diff --git a/arch/.gitignore b/arch/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3d589e9dce09bbc7838986d0341953c167d0f56e --- /dev/null +++ b/arch/.gitignore @@ -0,0 +1,22 @@ +.depend +Make.dep +*.o +*.a +*.d +*.i +*~ +.swp +.*.swp +core +.gdbinit +cscope.out +/Make.dep +/.depend +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/arch/Kconfig b/arch/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..fd61f2fbf55f96b6af107d6dc625c9454d389d94 --- /dev/null +++ b/arch/Kconfig @@ -0,0 +1,860 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +choice + prompt "CPU Architecture" + default ARCH_ARM + +config ARCH_ARM + bool "ARM" + select ARCH_HAVE_INTERRUPTSTACK + select ARCH_HAVE_TLS + select ARCH_HAVE_VFORK + select ARCH_HAVE_STACKCHECK + select ARCH_HAVE_CUSTOMOPT + ---help--- + The ARM architectures + +config ARCH_AVR + bool "AVR" + select ARCH_NOINTC + select ARCH_HAVE_INTERRUPTSTACK + select ARCH_HAVE_CUSTOMOPT + ---help--- + Atmel 8-bit bit AVR and 32-bit AVR32 architectures + +config ARCH_HC + bool "Freescale HC" + select ARCH_NOINTC + select ARCH_HAVE_INTERRUPTSTACK + ---help--- + Freescale HC architectures (M9S12) + +config ARCH_MIPS + bool "MIPS" + select ARCH_HAVE_INTERRUPTSTACK + select ARCH_HAVE_CUSTOMOPT + ---help--- + MIPS architectures (PIC32) + +config ARCH_RGMP + bool "RGMP" + ---help--- + RTOS and GPOS on Multi-Processor (RGMP) architecture. See + http://rgmp.sourceforge.net/wiki/index.php/Main_Page. + +config ARCH_SH + bool "Renesas" + select ARCH_NOINTC + select ARCH_HAVE_INTERRUPTSTACK + ---help--- + Renesas architectures (SH and M16C). + +config ARCH_SIM + bool "Simulation" + select ARCH_HAVE_MULTICPU + select ARCH_HAVE_TLS + select ARCH_HAVE_TICKLESS + select ARCH_HAVE_POWEROFF + ---help--- + Linux/Cywgin user-mode simulation. + +config ARCH_X86 + bool "x86" + ---help--- + Intel x86 architectures. + +config ARCH_Z16 + bool "ZNEO" + select ARCH_HAVE_HEAP2 + ---help--- + ZiLOG ZNEO 16-bit architectures (z16f). + +config ARCH_Z80 + bool "z80" + select ARCH_HAVE_HEAP2 + ---help--- + ZiLOG 8-bit architectures (z80, ez80, z8). + +endchoice + +config ARCH + string + default "arm" if ARCH_ARM + default "avr" if ARCH_AVR + default "hc" if ARCH_HC + default "mips" if ARCH_MIPS + default "rgmp" if ARCH_RGMP + default "sh" if ARCH_SH + default "sim" if ARCH_SIM + default "x86" if ARCH_X86 + default "z16" if ARCH_Z16 + default "z80" if ARCH_Z80 + +source arch/arm/Kconfig +source arch/avr/Kconfig +source arch/hc/Kconfig +source arch/mips/Kconfig +source arch/rgmp/Kconfig +source arch/sh/Kconfig +source arch/sim/Kconfig +source arch/x86/Kconfig +source arch/z16/Kconfig +source arch/z80/Kconfig + +comment "Architecture Options" + +config ARCH_NOINTC + bool + default n + +config ARCH_VECNOTIRQ + bool + default n + +config ARCH_DMA + bool + default n + +config ARCH_HAVE_IRQPRIO + bool + default n + +config ARCH_L2CACHE + bool + default n + +config ARCH_HAVE_COHERENT_DCACHE + bool + default n + +config ARCH_HAVE_ADDRENV + bool + default n + +config ARCH_NEED_ADDRENV_MAPPING + bool + default n + +config ARCH_HAVE_MULTICPU + bool + default n + +config ARCH_HAVE_VFORK + bool + default n + +config ARCH_HAVE_MMU + bool + default n + +config ARCH_HAVE_MPU + bool + default n + +config ARCH_NAND_HWECC + bool + default n + +config ARCH_HAVE_EXTCLK + bool + default n + +config ARCH_HAVE_POWEROFF + bool + default n + +config ARCH_HAVE_RESET + bool + default n + +config ARCH_USE_MMU + bool "Enable MMU" + default n + depends on ARCH_HAVE_MMU + ---help--- + The architecture supports supports an MMU. Enable this option in + order to enable use of the MMU. For most architectures, this is + not really an option: It is required to use the MMU. In those + cases, this selection will always be forced. + +config ARCH_USE_MPU + bool "Enable MPU" + default n + depends on ARCH_HAVE_MPU + ---help--- + The architecture supports supports an MPU. Enable this option in + order to enable use of the MPU. For most architectures, this option + is enabled by other, platform-specific logic. In those cases, this + selection will always be forced. + +menuconfig ARCH_ADDRENV + bool "Address environments" + default n + depends on ARCH_HAVE_ADDRENV + ---help--- + Support per-task address environments using the MMU... i.e., support + "processes" + +if ARCH_ADDRENV && ARCH_NEED_ADDRENV_MAPPING + +config ARCH_TEXT_VBASE + hex "Virtual .text base" + ---help--- + The virtual address of the beginning the .text region + +config ARCH_DATA_VBASE + hex "Virtual .bss/.data base" + ---help--- + The virtual address of the beginning of the .bss/.data region. + +config ARCH_HEAP_VBASE + hex "Virtual heap base" + ---help--- + The virtual address of the beginning of the heap region. + +config ARCH_SHM_VBASE + hex "Shared memory base" + depends on MM_SHM + ---help--- + The virtual address of the beginning of the shared memory region. + +config ARCH_TEXT_NPAGES + int "Max .text pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the .text region. + This, along with knowledge of the page size, determines the size of + the .text virtual address space. Default is 1. + +config ARCH_DATA_NPAGES + int "Max .bss/.data pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the .bss/.data + region. This, along with knowledge of the page size, determines the + size of the .bss/.data virtual address space. Default is 1. + +config ARCH_HEAP_NPAGES + int "Max heap pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the heap region. + This, along with knowledge of the page size, determines the size of + the heap virtual address space. Default is 1. + +if MM_SHM + +config ARCH_SHM_MAXREGIONS + int "Max shared memory regions" + default 1 + ---help--- + The maximum number of regions that can allocated for the shared + memory space. This hard-coded value permits static allocation of + the shared memory data structures and serves no other purpose. + Default is 1. + + The size of the virtual shared memory address space is then + determined by the product of the maximum number of regions, the + maximum number of pages per region, and the configured size of + each page. + +config ARCH_SHM_NPAGES + int "Max shared memory pages" + default 1 + ---help--- + The maximum number of pages that can allocated per region for the shared memory + region. Default is 1. + + The size of the virtual shared memory address space is then + determined by the product of the maximum number of regions, the + maximum number of pages per region, and the configured size of + each page. + +endif # MM_SHM + +config ARCH_STACK_DYNAMIC + bool "Dynamic user stack" + default n + depends on BUILD_KERNEL && EXPERIMENTAL + ---help--- + Select this option if the user process stack resides in its own + address space. The naming of this selection implies that dynamic + stack allocation is supported. Certainly this option must be set if + dynamic stack allocation is supported by a platform. But the more + general meaning of this configuration environment is simply that the + stack has its own address space. + + NOTE: This option not yet fully implemented in the code base. + Hence, it is marked EXPERIMENTAL: Do not enable it unless you plan + finish the implementation. + +if ARCH_STACK_DYNAMIC + +config ARCH_STACK_VBASE + hex "Virtual stack base" + ---help--- + The virtual address of the beginning the stack region + +config ARCH_STACK_NPAGES + int "Max. stack pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the stack region. + This, along with knowledge of the page size, determines the size of + the stack virtual address space. Default is 1. + +endif # ARCH_STACK_DYNAMIC + +config ARCH_KERNEL_STACK + bool "Kernel process stack" + default n if !LIBC_EXECFUNCS + default y if LIBC_EXECFUNCS + depends on BUILD_KERNEL + ---help--- + It this option is selected, then every user process will have two + stacks: A large, potentially dynamically sized user stack and small + kernel stack that is used during system call process. + + If this option is not selected, then kernel system calls will simply + use the caller's user stack. So, in most cases, this option is not + required. However, this option is *required* if both BUILD_KERNEL + and LIBC_EXECFUNCS are selected. Why? Because when we instantiate + and initialize the address environment of the new user process, we + will temporarily lose the address environment of the old user + process, including its stack contents. The kernel C logic will + crash immediately with no valid stack in place. + + When this option is selected, the smaller kernel stack stays in + place during system call processing event though the original user + stack may or may not be accessible. + +if ARCH_KERNEL_STACK + +config ARCH_KERNEL_STACKSIZE + int "Kernel stack size" + default 1568 + ---help--- + The common size of each process' kernel stack + +endif # ARCH_KERNEL_STACK + +config ARCH_PGPOOL_MAPPING + bool "Have page pool mapping" + default n + ---help--- + If there is a MMU mapping in place for the page pool memory, then + this mapping can be utilized to simplify some page table operations. + Otherwise, a temporary mapping will have to be established each time + it is necessary to modify the contents of a page. + +if ARCH_PGPOOL_MAPPING + +config ARCH_PGPOOL_PBASE + hex "Page pool physical address" + default 0x0 + ---help--- + The physical address of the start of the page pool memory. This + setting is probably equivalent to other platform specific definitions + but is required again in order to modularize the common address + environment logic. + +config ARCH_PGPOOL_VBASE + hex "Page pool virtual address" + default 0x0 + ---help--- + The virtual address of the start of the page pool memory. This + setting is probably equivalent to other platform specific definitions + but is required again in order to modularize the common address + environment logic. + +config ARCH_PGPOOL_SIZE + int "Page pool size (byes)" + default 0 + ---help--- + The size of the page pool memory in bytes. This setting is probably + equivalent to other platform specific definitions but is required again + in order to modularize the common address environment logic. + +endif # ARCH_PGPOOL_MAPPING +endif # ARCH_ADDRENV && ARCH_NEED_ADDRENV_MAPPING + +menuconfig PAGING + bool "On-demand paging" + default n + depends on ARCH_USE_MMU && !ARCH_ROMPGTABLE + ---help--- + If set =y in your configation file, this setting will enable the on-demand + paging feature as described in http://www.nuttx.org/NuttXDemandPaging.html. + +if PAGING + +config PAGING_PAGESIZE + int "Page size (bytes)" + default 4096 + ---help--- + The size of one managed page. This must be a value supported by the + processor's memory management unit + +config PAGING_NLOCKED + int "Number of locked pages" + default 48 + ---help--- + This is the number of locked pages in the memory map. + +config PAGING_CUSTOM_BASE + bool "Custom paging base address" + default n + ---help--- + By default, the page begins at RAM_START/VSTART. That base address + can be changed if this value is selected. + +if PAGING_CUSTOM_BASE + +config PAGING_LOCKED_PBASE + hex "Physical base address" + +config PAGING_LOCKED_VBASE + hex "Virtual base address" + +endif # PAGING_CUSTOM_BASE + +config PAGING_NPPAGED + int "Number of physical pages" + default 256 + ---help--- + This is the number of physical pages available to support the paged + text region. + +config PAGING_NVPAGED + int "Number of virtual pages" + default 1024 + ---help--- + This actual size of the virtual paged text region (in pages). This + is also the number of virtual pages required to span the entire + paged region. The on-demand paging feature is intended to support + only the case where the virtual paged text area is much larger the + available physical pages. Otherwise, why would you enable on-demand paging? + +config PAGING_NDATA + int "Number of data pages" + default 256 + ---help--- + This is the number of data pages in the memory map. The data region + will extend to the end of RAM unless overridden by a setting in the + configuration file. + + NOTE: In some architectures, it may be necessary to take some memory + from the end of RAM for page tables or other system usage. The + configuration settings and linker directives must be cognizant of + that: PAGING_NDATA should be defined to prevent the data region from + extending all the way to the end of memory. + +config PAGING_DEFPRIO + int "Page fill worker thread priority" + default 100 + ---help--- + The default, minimum priority of the page fill worker thread. The + priority of the page fill work thread will be boosted boosted + dynamically so that it matches the priority of the task on behalf + of which it performs the fill. This defines the minimum priority + that will be used. Default: 100. + +config PAGING_STACKSIZE + int "Page fill worker thread stack size" + default 1024 + ---help--- + Defines the size of the allocated stack for the page fill worker + thread. Default: 1024. + +config PAGING_BLOCKINGFILL + bool "Blocking fill" + default n + ---help--- + The architecture specific up_fillpage() function may be blocking + or non-blocking. If defined, this setting indicates that the + up_fillpage() implementation will block until the transfer is + completed. Default: Undefined (non-blocking). + +config PAGING_WORKPERIOD + int "Work period (usec)" + default 500000 + ---help--- + The page fill worker thread will wake periodically even if there + is no mapping to do. This selection controls that wake-up period + (in microseconds). This wake-up a failsafe that will handle any + cases where a single is lost (that would really be a bug and + shouldn't happen!) and also supports timeouts for case of non- + blocking, asynchronous fills (see CONFIG_PAGING_TIMEOUT_TICKS). + +config PAGING_TIMEOUT + bool "Paging timeout" + default n + ---help--- + If defined, the implementation will monitor the (asynchronous) page + fill logic. If the fill takes longer than than a timeout value, + then a fatal error will be declared. Default: No timeouts monitored + +config PAGING_TIMEOUT_TICKS + int "Paging timeout ticks" + default 10 + depends on PAGING_TIMEOUT + ---help--- + If PAGING_TIMEOUT is defined, then implementation will monitor the + (asynchronous) page fill logic. If the fill takes longer than this + number if microseconds, then a fatal error will be declared. + Default: No timeouts monitored + +endif # PAGING + +config ARCH_IRQPRIO + bool "Prioritized interrupt support" + default n + depends on ARCH_HAVE_IRQPRIO + ---help--- + Enable support for prioritized interrupts. + + NOTE: The use of interrupt priorities implies that you also have + support for nested interrupts. Most architectures do not support + nesting of interrupts or, if they do, they only supported nested + interrupts with certain configuration options. So this selection + should be used with caution. + +config ARCH_STACKDUMP + bool "Dump stack on assertions" + default n + ---help--- + Enable to do stack dumps after assertions + +config ARCH_USBDUMP + bool "Dump USB trace data" + default n + depends on USBDEV_TRACE + ---help--- + Enable to do USB trace after assertions + +config ENDIAN_BIG + bool "Big Endian Architecture" + default n + ---help--- + Select if architecture operates using big-endian byte ordering. + +config ARCH_IDLE_CUSTOM + bool "Custom IDLE loop" + default n + ---help--- + Each architecture provides a "default" IDLE loop that exits when the + MCU has nothing else to do. This default IDLE loop can be replaced + by a custom, board-specific IDLE loop by setting this option. Such + a custom IDLE loop may do things like a continuous built-in test or + perhaps or IDLE low power operations. + + NOTE: As of this writing, this capability is only supported by the + STM32. However, the implementation is trivial: If CONFIG_ARCH_IDLE_CUSTOM, + then the default IDLE loop file is not included in the MCU-specific + Make.defs file. + +config ARCH_CUSTOM_PMINIT + bool "Custom PM initialization" + default n + depends on PM + ---help--- + Each architecture provides default power management (PM) + initialization that is called automatically when the system is + started. This default PM initialization can be replaced by custom, + board-specific PM initialization by setting this option. Such a + custom initialization may do additional PM-related initialization + that is unique to the board power management requirements. + + NOTE: As of this writing, this capability is only supported by the + STM32. However, the implementation is trivial: If CONFIG_ARCH_CUSTOM_PMINIT, + then the default PM initialization is not included in the MCU-specific + Make.defs file. + +config ARCH_HAVE_RAMFUNCS + bool + default n + +config ARCH_RAMFUNCS + bool "Copy functions to RAM on startup" + default y + depends on ARCH_HAVE_RAMFUNCS + ---help--- + Copy some functions to RAM at boot time. This is done in some + architectures to improve performance. In other cases, it is done + so that FLASH can be reconfigured while the MCU executes out of + SRAM. + +config ARCH_HAVE_RAMVECTORS + bool + default n + +config ARCH_RAMVECTORS + bool "Support RAM interrupt vectors" + default n + depends on ARCH_HAVE_RAMVECTORS + ---help--- + If ARCH_RAMVECTORS is defined, then the architecture will support + modifiable vectors in a RAM-based vector table. + +comment "Board Settings" + +config BOARD_LOOPSPERMSEC + int "Delay loops per millisecond" + default 5000 + ---help--- + Simple delay loops are used by some logic, especially during boot-up, + driver initialization. These delay loops must be calibrated for each + board in order to assure accurate timing by the delay loops. + +config ARCH_CALIBRATION + bool "Calibrate delay loop" + default n + ---help--- + Enables some built in instrumentation that causes a 100 second delay + during boot-up. This 100 second delay serves no purpose other than it + allows you to calibrate BOARD_LOOPSPERMSEC. You simply use a stop + watch to measure the actual delay then adjust BOARD_LOOPSPERMSEC until + the actual delay is 100 seconds. + +comment "Interrupt options" + +config ARCH_HAVE_INTERRUPTSTACK + bool + default n + +config ARCH_INTERRUPTSTACK + int "Interrupt Stack Size" + depends on ARCH_HAVE_INTERRUPTSTACK + default 0 + ---help--- + This architecture supports an interrupt stack. If defined, this symbol + will be the size of the interrupt stack in bytes. If not defined (or + defined to be zero), the user task stacks will be used during interrupt + handling. + +config ARCH_HAVE_HIPRI_INTERRUPT + bool + default n + +config ARCH_HIPRI_INTERRUPT + bool "High priority interrupts" + default n + depends on ARCH_HAVE_HIPRI_INTERRUPT && ARCH_HAVE_IRQPRIO + select ARMV7M_USEBASEPRI + select ARCH_IRQPRIO + ---help--- + NOTE: This description is currently unique to the Cortex-M family + which is the only family that currently supports this feature. The + general feature is not conceptually unique to the Cortex-M but it + is extended to any other family, then this discussion will have to + be generalized. + + If ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so + that most interrupts will not have execution priority. SVCall must + have execution priority in all cases. + + In the normal cases, interrupts are not nest-able and all interrupts + run at an execution priority between NVIC_SYSH_PRIORITY_MIN and + NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for + SVCall). + + If, in addition, ARCH_HIPRI_INTERRUPT is defined, then special high + priority interrupts are supported. These are not "nested" in the + normal sense of the word. These high priority interrupts can + interrupt normal processing but execute outside of OS (although they + can "get back into the game" via a PendSV interrupt). + + How do you specify a high priority interrupt? You need to do two + things: + + 1) You need to change the address in the vector table so that + the high priority interrupt vectors to your special C + interrupt handler. There are two ways to do this: + + a) If you select CONFIG_ARCH_RAMVECTORS, then vectors will + be kept in RAM and the system will support the interface: + + int up_ramvec_attach(int irq, up_vector_t vector) + + that can be used to attach your C interrupt handler to the + vector at run time. + + b) Alternatively, you could keep your vectors in FLASH but in + order to this, you would have to develop your own custom + vector table. + + 2) Then set the priority of your interrupt to NVIC to + NVIC_SYSH_HIGH_PRIORITY using the standard interface: + + int up_prioritize_irq(int irq, int priority) + + NOTE: ARCH_INTERRUPTSTACK must be set in kernel mode (BUILD_KERNEL). + In kernel mode without an interrupt stack, the interrupt handler + will set the MSP to the stack pointer of the interrupted thread. If + the interrupted thread was a privileged thread, that will be the MSP + otherwise it will be the PSP. If the PSP is used, then the value of + the MSP will be invalid when the interrupt handler returns because + it will be a pointer to an old position in the unprivileged stack. + Then when the high priority interrupt occurs and uses this stale MSP, + there will most likely be a system failure. + + If the interrupt stack is selected, on the other hand, then the + interrupt handler will always set the the MSP to the interrupt + stack. So when the high priority interrupt occurs, it will either + use the MSP of the last privileged thread to run or, in the case of + the nested interrupt, the interrupt stack if no privileged task has + run + +config ARCH_INT_DISABLEALL + bool "Disable high priority interrupts" + default y + depends on ARCH_HIPRI_INTERRUPT && EXPERIMENTAL + ---help--- + If ARCH_HIPRI_INTERRUPT is defined, then special high priority + interrupts are supported. These are not "nested" in the normal + sense of the word. These high priority interrupts can interrupt + normal processing but execute outside of OS (although they can "get + back into the game" via a PendSV interrupt). + + In the normal course of things, interrupts must occasionally be + disabled using the up_irq_save() inline function to prevent contention + in use of resources that may be shared between interrupt level and + non-interrupt level logic. Now the question arises, if + ARCH_HIPRI_INTERRUPT, do we disable all interrupts (except SVCall), + or do we only disable the "normal" interrupts. Since the high + priority interrupts cannot interact with the OS, you may want to + permit the high priority interrupts even if interrupts are + disabled. The setting ARCH_INT_DISABLEALL can be used to select + either behavior: + + ----------------------------+--------------+---------------------------- + CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + ----------------------------+--------------+--------------+------------- + CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + ----------------------------+--------------+--------------+------------- + | | | SVCall + | SVCall | SVCall | HIGH + Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + | | MAXNORMAL | + ----------------------------+--------------+--------------+------------- + + NOTE: This does not work now because interrupts get disabled in the + standard interrupt handling, prohibiting nesting. Fix is simple: Need + to used more priority levels so that we can make a cleaner distinction + with the standard interrupt handler. + +comment "Boot options" + +choice + prompt "Boot Mode" + default BOOT_RUNFROMFLASH + +config BOOT_RUNFROMEXTSRAM + bool "Run from external SRAM" + ---help--- + Some configuration support booting and running from external SRAM. + +config BOOT_RUNFROMFLASH + bool "Boot and run from flash" + ---help--- + Most configurations support XIP operation from FLASH but must copy + initialized .data sections to RAM. (This is the default). + +config BOOT_RUNFROMISRAM + bool "Boot and run from internal SRAM" + ---help--- + Some configuration support booting and running from internal SRAM. + +config BOOT_RUNFROMSDRAM + bool "Boot and run from external SDRAM" + ---help--- + Some configuration support booting and running from external SDRAM. + +config BOOT_COPYTORAM + bool "Boot from FLASH but copy to ram" + ---help--- + Some configurations boot in FLASH but copy themselves entirely into + RAM for better performance. + +endchoice + +menu "Boot Memory Configuration" + +config RAM_START + hex "Primary RAM start address (physical)" + default 0x0 + help + The physical start address of primary installed RAM. "Primary" RAM + refers to the RAM that you link program code into. If program code + does not execute out of RAM but from FLASH, then you may designate + any block of RAM as "primary." + +config RAM_VSTART + hex "Primary RAM start address (virtual)" + default 0x0 + depends on ARCH_USE_MMU + help + The virtual start address of installed primary RAM. "Primary" RAM + refers to the RAM that you link program code into. If program code + does not execute out of RAM but from FLASH, then you may designate + any block of RAM as "primary." + +config RAM_SIZE + int "Primary RAM size" + default 0 + help + The size in bytes of the installed primary RAM. "Primary" RAM + refers to the RAM that you link program code into. If program code + does not execute out of RAM but from FLASH, then you may designate + any block of RAM as "primary." + +if BOOT_RUNFROMFLASH && ARCH_USE_MMU + +config FLASH_START + hex "Boot FLASH start address (physical)" + default 0x0 + help + The physical start address of installed boot FLASH. "Boot" FLASH + refers to the FLASH that you link program code into. + +config FLASH_VSTART + hex "Boot FLASH start address (virtual)" + default 0x0 + help + The virtual start address of installed boot FLASH. "Boot" FLASH + refers to the FLASH that you link program code into. + +config FLASH_SIZE + int "Boot FLASH size" + default 0 + help + The size in bytes of the installed boot FLASH. "Boot" FLASH + refers to the FLASH that you link program code into. + +endif # BOOT_RUNFROMFLASH && ARCH_USE_MMU + +config ARCH_HAVE_SDRAM + bool + default n + +config BOOT_SDRAM_DATA + bool "Data in SDRAM" + default n + depends on ARCH_HAVE_SDRAM && !BOOT_RUNFROMSDRAM + ---help--- + This selection should be set if data lies in SDRAM (vs. SRAM) and if + SDRAM was not previously initialized by a loader. Obviously, this + does not apply if we booting from SDRAM because SDRAM must have been + initialized priority to loading NuttX into SDRAM. + + In the case where SDRAM must be initialized by NuttX, the + initialization sequence is a little different: Normally, .data and + .bss must be initialized before starting the system. But in this + case SDRAM must be configured by board-specific logic before the + .data and .bss sections can be initialized. + +endmenu # Boot Memory Configuration diff --git a/arch/README.txt b/arch/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..df34133df9c310d0555b4c7a0c033cbe5946d062 --- /dev/null +++ b/arch/README.txt @@ -0,0 +1,339 @@ +Architecture-Specific Code +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Table of Contents +^^^^^^^^^^^^^^^^^ + + o Architecture-Specific Code + o Summary of Files + o Supported Architectures + o Configuring NuttX + +Architecture-Specific Code +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The NuttX configuration consists of: + +o Processor architecture specific files. These are the files contained + in the arch// directory discussed in this README. + +o Chip/SoC specific files. Each processor processor architecture + is embedded in chip or System-on-a-Chip (SoC) architecture. The + full chip architecture includes the processor architecture plus + chip-specific interrupt logic, general purpose I/O (GIO) logic, and + specialized, internal peripherals (such as UARTs, USB, etc.). + + These chip-specific files are contained within chip-specific + sub-directories in the arch// directory and are selected + via the CONFIG_ARCH_name selection + +o Board specific files. In order to be usable, the chip must be + contained in a board environment. The board configuration defines + additional properties of the board including such things as + peripheral LEDs, external peripherals (such as network, USB, etc.). + + These board-specific configuration files can be found in the + configs// sub-directories. + +This README will address the processor architecture specific files +that are contained in the arch// directory. The file +include/nuttx/arch.h identifies all of the APIs that must +be provided by this architecture specific logic. (It also includes +arch//arch.h as described below). + +Directory Structure +^^^^^^^^^^^^^^^^^^^ + +The arch directory contains architecture specific logic. The complete +board port in is defined by the architecture-specific code in this +directory (plus the board-specific configurations in the config/ +subdirectory). Each architecture must provide a subdirectory +under arch/ with the following characteristics: + + + / + |-- include/ + | |--/ + | | `-- (chip-specific header files) + | |--/ + | |-- arch.h + | |-- irq.h + | `-- types.h + `-- src/ + |--/ + | `-- (chip-specific source files) + |--/ + |-- Makefile + `-- (architecture-specific source files) + +Summary of Files +^^^^^^^^^^^^^^^^ + +include// + This sub-directory contains chip-specific header files. + +include/arch.h + This is a hook for any architecture specific definitions that may + be needed by the system. It is included by include/nuttx/arch.h + +include/types.h + This provides architecture/toolchain-specific definitions for + standard types. This file should typedef: + + _int8_t, _uint8_t, _int16_t, _uint16_t, _int32_t, _uint32_t + + and if the architecture supports 64-bit integers. + + _int24_t, _uint24_t, int64_t, uint64_t + + NOTE that these type names have a leading underscore character. This + file will be included(indirectly) by include/stdint.h and typedef'ed to + the final name without the underscore character. This roundabout way of + doings things allows the stdint.h to be removed from the include/ + directory in the event that the user prefers to use the definitions + provided by their toolchain header files + + irqstate_t + + Must be defined to the be the size required to hold the interrupt + enable/disable state. + + This file will be included by include/sys/types.h and be made + available to all files. + +include/irq.h + This file needs to define some architecture specific functions (usually + inline if the compiler supports inlining) and structure. These include: + + - struct xcptcontext. This structures represents the saved context + of a thread. + + - irqstate_t up_irq_save(void) -- Used to disable all interrupts. + + - void upirq_restore(irqstate_t flags) -- Used to restore interrupt + enables to the same state as before up_irq_save was called. + + NOTE: These interfaces are not available to application code but can + only be used withint the operating system code. And, in general, + these functions should *never* be called directly, not unless you + know absolutely well what you are doing. Rather you shoudl typically + use the wrapper functions enter_critical_section() and leave_critical_section() + as prototyped in include/nuttx/irq.h. + + This file must also define NR_IRQS, the total number of IRQs supported + by the board. + +src// + This sub-directory contains chip-specific source files. + +src/Makefile + This makefile will be executed to build the targets src/libup.a and + src/up_head.o. The up_head.o file holds the entry point into the system + (power-on reset entry point, for example). It will be used in + the final link with libup.a and other system archives to generate the + final executable. + +Supported Architectures +^^^^^^^^^^^^^^^^^^^^^^^ + +arch/sim - Linux/Cygwin simulation + A user-mode port of NuttX to the x86 Linux platform is available. + The purpose of this port is primarily to support OS feature development. + This port does not support interrupts or a real timer (and hence no + round robin scheduler) Otherwise, it is complete. + +arch/arm - ARM-based micro-controllers + This directory holds common ARM architectures. At present, this includes + the following subdirectories: + + arch/arm/include and arch/arm/src/common + Common ARM/Cortex-M3 logic. + + arch/arm/src/arm and arch/arm/include/arm + Common ARM-specific logic + + arch/arm/src/armv7-m and arch/arm/include/armv7-m + Common ARMv7-M logic (Cortex-M3 and Cortex-M4) + + arch/arm/include/c5471 and arch/arm/src/c5471 + TI TMS320C5471 (also called TMS320DM180 or just C5471). + NuttX operates on the ARM7 of this dual core processor. This port + complete, verified, and included in the NuttX release 0.1.1. + + arch/arm/include/calypso and arch/arm/src/calypso + TI "Calypso" MCU used in various cell phones (and, in particular, + by the Osmocom-bb project). Like the c5471, NuttX operates on the + ARM7 of this dual core processor. This port was contributed by + Denis Carilki and includes the work of Denis, Alan Carvalho de Assis, + and Stefan Richter. Calypso support first appeared in NuttX-6.17. + + arch/arm/include/dm320 and arch/arm/src/dm320 + TI TMS320DM320 (also called just DM320). + NuttX operates on the ARM9EJS of this dual core processor. This port + complete, verified, and included in the NuttX release 0.2.1. + + arch/arm/include/imx and arch/arm/src/imx + Freescale MC9328MX1 or i.MX1. This port uses the Freescale MX1ADS + development board with a GNU arm-elf toolchain* under either Linux or Cygwin. + STATUS: This port has stalled because of development tool issues. Coding + is complete on the basic port (timer, serial console, SPI). + + arch/arm/include/lm and arch/arm/src/lm + These directories contain support for the Luminary LM3S/4F family. The + initial, release of this port was included in NuttX version 0.4.6. The + current port includes timer, serial console, Ethernet, SSI, and microSD + support. There are working configurations the NuttX OS test, to run the + NuttShell (NSH), the NuttX networking test, and the uIP web server. + + arch/arm/include/lpc214x and arch/arm/src/lpc214x + These directories provide support for NXP LPC214x family of + ARM7TDMI processors. This port boots and passes the OS test (examples/ostest). + The port is complete and verifed. As of NuttX 0.3.17, the port includes: + timer interrupts, serial console, USB driver, and SPI-based MMC/SD card + support. A verifed NuttShell (NSH) configuration is also available. + + arch/arm/include/lpc2378 and arch/arm/src/lpc2378. + NXP LPC2378. Support is provided for the NXP LPC2378 MCU. This port was + contributed by Rommel Marcelo is was first released in NuttX-5.3. + STATUS: This port boots and passes the OS test (examples/ostest) and + includes a working implementation of the NuttShell (NSH). The port is + complete and verified. As of NuttX 5.3, the port includes only basic + timer interrupts and serial console support. + + arch/arm/include/lpc31xx and arch/arm/src/lpc31xx + These directories provide support for NXP LPC31xx family of + ARM926EJ-S processors. The port for the NXP LPC3131 was first + released in NuttX-5.1 (but was not functional until NuttX-5.2). + STATUS: The basic EA3131 port is complete and verified in NuttX-5.2 + This basic port includes basic boot-up, serial console, and timer + interrupts. This port was extended in NuttX 5.3 with a USB high + speed driver contributed by David Hewson. This port has been + verified using the NuttX OS test, USB serial and mass storage tests + and includes a working implementation of the NuttShell ((NSH)). + + This port was later extended to support additional members of the + LPC31xx family including, specifically, the LPC3152. + + arch/arm/include/sam3u and arch/arm/src/sam3u + Atmel AT91SAM3U. This port is for Atmel AT91SAM3U4E MCU. + STATUS: The basic AT91SAM3U port was released in NuttX version 5.1. + The basic port includes boot-up logic, interrupt driven serial + console, and system timer interrupts. That release passes the + NuttX OS test and is proven to have a valid OS implementation. A + onfiguration to support the NuttShell is also included. + + arch/arm/include/stm32 and arch/arm/src/stm32 + These directories contain support for the STMicro STM32 F1, F2, and + F4 families. + + STATUS: The basic STM32 F1 port was released in NuttX version 0.4.12. + and has continued to develop consistently over time. It now includes + support for the F2 and F4 families and a rich offering of peripheral + drivers. + + arch/arm/include/str71x and arch/arm/src/str71x + These directories provide support for the STMicro STR71x processors. + Coding is complete on the basic port (boot logic, system time, serial console), + but no testing has been performed due to some problems I am having with my + JTAG wiggler and OpenOCD on Linux. + +arch/avr + This directory is dedicated to ports to the Atmel AVR (8-bit) and AVR32 (32-bit) + MCU families. STATUS: Under development. + + arch/avr/include/avr and arch/avr/src/avr + Common support for all 8-bit AVR MCUs + + arch/avr/include/atmega and arch/avr/src/atmega + Support specifically for the AVR ATMega family (specifically only for + the ATMega128 at the moment). + + arch/avr/include/at90usb and arch/avr/src/at90usb + Support specifically for the AVR AT90USB646, 647, 1286, and 1287 family. + + arch/avr/include/avr32 and arch/avr/src/avr32 + Common support for all AVR32 MCUs + + arch/avr/include/at32uc3 and arch/avr/src/at32uc3 + Support specifically for the AT32UC3Bxxx family (specifically only for + the AT32UC3B0256 at the moment). + +arch/hc + This directory is dedicated to ports to the Freescale HC family. + + arch/arm/include/m9s12 and arch/arm/src/m9s12 + These directories provide support for the Freescale mc9s12x family. + STATUS: Fragments of this port were first released in nuttx-5.0 and + the port was "code-complete" as nuttx-5.18. However, the final + verification effort has been stalled because of higher priority tasks. + +arch/mips + This directory is dedicated to ports to the MIPS family. + + arch/mips/include/mips32 and arch/mips/src/mips32 + Common support for all MIPS32 architectures + + arch/mips/include/pic32mx and arch/mips/src/pic32mx + Support for all MicroChip PIC32MX architectures + +arch/rgmp + + RGMP stands for RTOS and GPOS on Multi-Processor. RGMP is a project + for running GPOS and RTOS simultaneously on multi-processor platforms. + You can port your favorite RTOS to RGMP together with an unmodified + Linux to form a hybrid operating system. This makes your application + able to use both RTOS and GPOS features. + + See http://rgmp.sourceforge.net/wiki/index.php/Main_Page for further + information about RGMP. + +arch/sh - SuperH and related Hitachi/Renesas microcontrollers + + arch/sh/include and arch/sh/src/common + Common SuperH logic. + + arch/sh/include/shs and arch/sh/src/sh1 + Support for the SH-1 processor. + +arch/x86 - Intel x86 architectures + This directory holds related, 32- and 64-bit architectures from Intel. + At present, this includes the following subdirectories: + + arch/x86/include and arch/x86/src/common + Common x86 logic. + + arch/x86/include/i486 and arch/x86/src/i486 + These directories hold definitions and logic appropriate for any + instantiation of the 32-bit i486 architecture. + + arch/x86/include/qemu and arch/x86/src/qemu + This is the implementation of NuttX on the QEMU x86 simulation. + +arch/z16 - ZiLOG 16-bit processors + This directory holds related, 16-bit architectures from ZiLOG. At + present, this includes the following subdirectories: + + arch/z16/include and arch/z16/src/common + Common microcontroller logic. + + arch/z16/include/z16f and arch/z16/src/z16f + ZiLOG z16f Microcontroller. + STATUS: Released in nuttx-0.3.7. Fully functional other than issues + addressed in ${TOPDIR}/TODO. + +arch/z80 - ZiLOG 8-bit microcontrollers + This directory holds related, 8-bit architectures from ZiLOG. At + present, this includes the following subdirectories: + + arch/z80/include and arch/z80/src/common + Common microcontroller logic. + + arch/z80/include/z80 and arch/z80/src/z80 + Classic ZiLOG z80 Microcontroller. + STATUS: Functional with no known defects. There are still several + OS features that have not yet been tested (e.g., networking). + + arch/z80/include/z8 and arch/z80/src/z8 + ZiLOG Z8Encore! Microcontroller + + arch/z80/include/ez80 and arch/z80/src/ez80 + ZiLOG ez80 Acclaim! Microcontroller diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..fd960282a1d78ec778f5a9823c032e8738f1c4f8 --- /dev/null +++ b/arch/arm/Kconfig @@ -0,0 +1,694 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_ARM +comment "ARM Options" + +choice + prompt "ARM chip selection" + default ARCH_CHIP_STM32 + +config ARCH_CHIP_A1X + bool "Allwinner A1X" + select ARCH_CORTEXA8 + select ARCH_HAVE_FPU + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_SDRAM + select BOOT_RUNFROMSDRAM + select ARCH_HAVE_ADDRENV + select ARCH_NEED_ADDRENV_MAPPING + ---help--- + Allwinner A1X family: A10, A10S (A12), A13 (ARM Cortex-A8) + +config ARCH_CHIP_C5471 + bool "TMS320 C5471" + select ARCH_ARM7TDMI + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_OTHER_UART + ---help--- + TI TMS320 C5471, A180, or DA180 (ARM7TDMI) + +config ARCH_CHIP_CALYPSO + bool "Calypso" + select ARCH_ARM7TDMI + select ARCH_HAVE_HEAP2 + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_OTHER_UART + select ARCH_HAVE_POWEROFF + ---help--- + TI Calypso-based cell phones (ARM7TDMI) + +config ARCH_CHIP_DM320 + bool "TMS320 DM320" + select ARCH_ARM926EJS + select ARCH_HAVE_LOWVECTORS + ---help--- + TI DMS320 DM320 (ARM926EJS) + +config ARCH_CHIP_EFM32 + bool "Energy Micro" + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + ---help--- + Energy Micro EFM32 microcontrollers (ARM Cortex-M). + +config ARCH_CHIP_IMX1 + bool "NXP/Freescale iMX.1" + select ARCH_ARM920T + select ARCH_HAVE_HEAP2 + select ARCH_HAVE_LOWVECTORS + ---help--- + Freescale iMX.1 architectures (ARM920T) + +config ARCH_CHIP_IMX6 + bool "NXP/Freescale iMX.6" + select ARCH_CORTEXA9 + select ARMV7A_HAVE_L2CC_PL310 + select ARCH_HAVE_FPU + select ARCH_HAVE_TRUSTZONE + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_SDRAM + select BOOT_RUNFROMSDRAM + select ARCH_HAVE_ADDRENV + select ARCH_NEED_ADDRENV_MAPPING + ---help--- + Freescale iMX.6 architectures (Cortex-A9) + +config ARCH_CHIP_KINETIS + bool "NXP/Freescale Kinetis" + select ARCH_CORTEXM4 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_FPU + select ARCH_HAVE_RAMFUNCS + ---help--- + Freescale Kinetis Architectures (ARM Cortex-M4) + +config ARCH_CHIP_KL + bool "NXP/Freescale Kinetis L" + select ARCH_CORTEXM0 + select ARCH_HAVE_CMNVECTOR + ---help--- + Freescale Kinetis L Architectures (ARM Cortex-M0+) + +config ARCH_CHIP_LM + bool "TI/Luminary Stellaris" + select ARCH_HAVE_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + ---help--- + TI/Luminary Stellaris LMS3 and LM4F architectures (ARM Cortex-M3/4) + +config ARCH_CHIP_TIVA + bool "TI Tiva" + select ARCH_HAVE_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_FPU + ---help--- + TI Tiva TM4C architectures (ARM Cortex-M4) + +config ARCH_CHIP_LPC11XX + bool "NXP LPC11xx" + select ARCH_CORTEXM0 + select ARCH_HAVE_CMNVECTOR + ---help--- + NXP LPC11xx architectures (ARM Cortex-M0) + +config ARCH_CHIP_LPC17XX + bool "NXP LPC17xx" + select ARCH_CORTEXM3 + select ARCH_HAVE_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + ---help--- + NXP LPC17xx architectures (ARM Cortex-M3) + +config ARCH_CHIP_LPC214X + bool "NXP LPC214x" + select ARCH_ARM7TDMI + select ARCH_HAVE_LOWVECTORS + ---help--- + NXP LPC2145x architectures (ARM7TDMI) + +config ARCH_CHIP_LPC2378 + bool "NXP LPC2378" + select ARCH_ARM7TDMI + select ARCH_HAVE_LOWVECTORS + ---help--- + NXP LPC2145x architectures (ARM7TDMI) + +config ARCH_CHIP_LPC31XX + bool "NXP LPC31XX" + select ARCH_ARM926EJS + select ARCH_HAVE_LOWVECTORS + ---help--- + NPX LPC31XX architectures (ARM926EJS). + +config ARCH_CHIP_LPC43XX + bool "NXP LPC43XX" + select ARCH_CORTEXM4 + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_FPU + ---help--- + NPX LPC43XX architectures (ARM Cortex-M4). + +config ARCH_CHIP_NUC1XX + bool "Nuvoton NUC100/120" + select ARCH_CORTEXM0 + select ARCH_HAVE_CMNVECTOR + ---help--- + NPX LPC43XX architectures (ARM Cortex-M4). + +config ARCH_CHIP_SAMA5 + bool "Atmel SAMA5" + select ARCH_CORTEXA5 + select ARCH_HAVE_FPU + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_TICKLESS + select ARCH_HAVE_ADDRENV + select ARCH_NEED_ADDRENV_MAPPING + ---help--- + Atmel SAMA5 (ARM Cortex-A5) + +config ARCH_CHIP_SAMD + bool "Atmel SAMD" + select ARCH_CORTEXM0 + select ARCH_HAVE_CMNVECTOR + ---help--- + Atmel SAMD (ARM Cortex-M0+) + +config ARCH_CHIP_SAML + bool "Atmel SAML" + select ARCH_CORTEXM0 + select ARCH_HAVE_CMNVECTOR + ---help--- + Atmel SAML (ARM Cortex-M0+) + +config ARCH_CHIP_SAM34 + bool "Atmel SAM3/SAM4" + select ARCH_HAVE_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_RAMFUNCS + select ARMV7M_HAVE_STACKCHECK + ---help--- + Atmel SAM3 (ARM Cortex-M3) and SAM4 (ARM Cortex-M4) architectures + +config ARCH_CHIP_SAMV7 + bool "Atmel SAMV7" + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + select ARCH_CORTEXM7 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_RAMFUNCS + select ARCH_HAVE_TICKLESS + select ARMV7M_HAVE_STACKCHECK + ---help--- + Atmel SAMV7 (ARM Cortex-M7) architectures + +config ARCH_CHIP_STM32 + bool "STMicro STM32 F1/F2/F3/F4" + select ARCH_HAVE_CMNVECTOR + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_HEAPCHECK + select ARMV7M_HAVE_STACKCHECK + ---help--- + STMicro STM32 architectures (ARM Cortex-M3/4). + +config ARCH_CHIP_STM32F7 + bool "STMicro STM32 F7" + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + select ARCH_CORTEXM7 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_HEAPCHECK + select ARMV7M_HAVE_STACKCHECK + ---help--- + STMicro STM32 architectures (ARM Cortex-M7). + +config ARCH_CHIP_STM32L4 + bool "STMicro STM32 L4" + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + select ARCH_CORTEXM4 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_HEAPCHECK + select ARMV7M_HAVE_STACKCHECK + ---help--- + STMicro STM32 architectures (ARM Cortex-M4). + +config ARCH_CHIP_STR71X + bool "STMicro STR71x" + select ARCH_ARM7TDMI + select ARCH_HAVE_LOWVECTORS + ---help--- + STMicro STR71x architectures (ARM7TDMI). + +config ARCH_CHIP_TMS570 + bool "TI TMS570" + select ENDIAN_BIG + select ARCH_HAVE_LOWVECTORS + select ARCH_HAVE_RAMFUNCS + select ARMV7R_MEMINIT + select ARMV7R_HAVE_DECODEFIQ + ---help--- + TI TMS570 family + +config ARCH_CHIP_MOXART + bool "MoxART" + select ARCH_ARM7TDMI + select ARCH_HAVE_RESET + select ARCH_HAVE_SERIAL_TERMIOS + ---help--- + MoxART family + +endchoice + +config ARCH_ARM7TDMI + bool + default n + +config ARCH_ARM926EJS + bool + default n + select ARCH_HAVE_MMU + select ARCH_USE_MMU + +config ARCH_ARM920T + bool + default n + select ARCH_HAVE_MMU + select ARCH_USE_MMU + +config ARCH_CORTEXM0 + bool + default n + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_RESET + +config ARCH_CORTEXM3 + bool + default n + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_RAMVECTORS + select ARCH_HAVE_HIPRI_INTERRUPT + select ARCH_HAVE_RESET + +config ARCH_CORTEXM4 + bool + default n + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_RAMVECTORS + select ARCH_HAVE_HIPRI_INTERRUPT + select ARCH_HAVE_RESET + +config ARCH_CORTEXM7 + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_IRQPRIO + select ARCH_HAVE_RAMVECTORS + select ARCH_HAVE_HIPRI_INTERRUPT + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXA5 + bool + default n + select ARCH_HAVE_MMU + select ARCH_USE_MMU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXA8 + bool + default n + select ARCH_HAVE_MMU + select ARCH_USE_MMU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXA9 + bool + default n + select ARCH_HAVE_MMU + select ARCH_USE_MMU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXR4 + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXR4F + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_FPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXR5 + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEX5F + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_FPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXR7 + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_CORTEXR7F + bool + default n + select ARCH_HAVE_MPU + select ARCH_HAVE_FPU + select ARCH_HAVE_COHERENT_DCACHE if ELF || MODULE + +config ARCH_FAMILY + string + default "arm" if ARCH_ARM7TDMI || ARCH_ARM926EJS || ARCH_ARM920T + default "armv6-m" if ARCH_CORTEXM0 + default "armv7-a" if ARCH_CORTEXA5 || ARCH_CORTEXA8 || ARCH_CORTEXA9 + default "armv7-m" if ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7 + default "armv7-r" if ARCH_CORTEXR4 || ARCH_CORTEXR4F || ARCH_CORTEXR5 || ARCH_CORTEXR5F || ARCH_CORTEX74 || ARCH_CORTEXR7F + +config ARCH_CHIP + string + default "a1x" if ARCH_CHIP_A1X + default "c5471" if ARCH_CHIP_C5471 + default "calypso" if ARCH_CHIP_CALYPSO + default "dm320" if ARCH_CHIP_DM320 + default "efm32" if ARCH_CHIP_EFM32 + default "imx1" if ARCH_CHIP_IMX1 + default "imx6" if ARCH_CHIP_IMX6 + default "kinetis" if ARCH_CHIP_KINETIS + default "kl" if ARCH_CHIP_KL + default "tiva" if ARCH_CHIP_LM || ARCH_CHIP_TIVA + default "lpc11xx" if ARCH_CHIP_LPC11XX + default "lpc17xx" if ARCH_CHIP_LPC17XX + default "lpc214x" if ARCH_CHIP_LPC214X + default "lpc2378" if ARCH_CHIP_LPC2378 + default "lpc31xx" if ARCH_CHIP_LPC31XX + default "lpc43xx" if ARCH_CHIP_LPC43XX + default "nuc1xx" if ARCH_CHIP_NUC1XX + default "sama5" if ARCH_CHIP_SAMA5 + default "samdl" if ARCH_CHIP_SAMD || ARCH_CHIP_SAML + default "sam34" if ARCH_CHIP_SAM34 + default "samv7" if ARCH_CHIP_SAMV7 + default "stm32" if ARCH_CHIP_STM32 + default "stm32f7" if ARCH_CHIP_STM32F7 + default "stm32l4" if ARCH_CHIP_STM32L4 + default "str71x" if ARCH_CHIP_STR71X + default "tms570" if ARCH_CHIP_TMS570 + default "moxart" if ARCH_CHIP_MOXART + +config ARM_TOOLCHAIN_IAR + bool + default n + +config ARM_TOOLCHAIN_GNU + bool + default n + +config ARMV7M_USEBASEPRI + bool "Use BASEPRI Register" + default n + depends on ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7 + ---help--- + Use the BASEPRI register to enable and disable interrupts. By + default, the PRIMASK register is used for this purpose. This + usually results in hardfaults when supervisor calls are made. + Though, these hardfaults are properly handled by the RTOS, the + hardfaults can confuse some debuggers. With the BASEPRI + register, these hardfaults, will be avoided. For more details see + http://www.nuttx.org/doku.php?id=wiki:nxinternal:svcall + +config ARCH_HAVE_CMNVECTOR + bool + +config ARMV7M_CMNVECTOR + bool "Use common ARMv7-M vectors" + default n + depends on ARCH_HAVE_CMNVECTOR + ---help--- + Some architectures use their own, built-in vector logic. Some use only + the common vector logic. Some can use either their own built-in vector + logic or the common vector logic. This applies only to ARMv7-M + architectures. + +config ARMV7M_LAZYFPU + bool "Lazy FPU storage" + default n + depends on ARCH_HAVE_CMNVECTOR + ---help--- + There are two forms of the common vector logic. There are pros and + cons to each option: + + 1) The standard common vector logic exploits features of the ARMv7-M + architecture to save the all of floating registers on entry into + each interrupt and then to restore the floating registers when + the interrupt returns. The primary advantage to this approach is + that floating point operations are available in interrupt + handling logic. Since the volatile registers are preserved, + operations on the floating point registers by interrupt handling + logic has no ill effect. The downside is, of course, that more + stack operations are required on each interrupt to save and store + the floating point registers. Because of the some special + features of the ARMv-M, this is not as much overhead as you might + expect, but overhead nonetheless. + + 2) The lazy FPU common vector logic does not save or restore + floating point registers on entry and exit from the interrupt + handler. Rather, the floating point registers are not restored + until it is absolutely necessary to do so when a context switch + occurs and the interrupt handler will be returning to a different + floating point context. Since floating point registers are not + protected, floating point operations must not be performed in + interrupt handling logic. Better interrupt performance is be + expected, however. + + By default, the "standard" common vector logic is build. This + option selects the alternate lazy FPU common vector logic. + +config ARCH_HAVE_FPU + bool + default n + +config ARCH_HAVE_DPFPU + bool + default n + +config ARCH_FPU + bool "FPU support" + default y + depends on ARCH_HAVE_FPU + ---help--- + Build in support for the ARM Cortex-M4 Floating Point Unit (FPU). + Check your chip specifications first; not all Cortex-M4 chips + support the FPU. + +config ARCH_DPFPU + bool "Double precision FPU support" + default y + depends on ARCH_FPU && ARCH_HAVE_DPFPU + ---help--- + Enable toolchain support for double precision (64-bit) floating + point if both the toolchain and the hardware support it. + +config ARCH_HAVE_TRUSTZONE + bool + default n + ---help--- + Automatically selected to indicate that the ARM CPU supports + TrustZone. + +choice + prompt "TrustZone Configuration" + default ARCH_TRUSTZONE_SECURE + depends on ARCH_HAVE_TRUSTZONE + +config ARCH_TRUSTZONE_SECURE + bool "All CPUs operate secure state" + +config ARCH_TRUSTZONE_NONSECURE + bool "All CPUs operate non-secure state" + depends on EXPERIMENTAL + +config ARCH_TRUSTZONE_BOTH + bool "CPUs operate in both secure and non-secure states" + depends on EXPERIMENTAL + +endchoice # TrustZone Configuration + +config ARM_HAVE_MPU_UNIFIED + bool + default n + ---help--- + Automatically selected to indicate that the CPU supports a + unified MPU for both instruction and data addresses. + +config ARM_MPU + bool "MPU support" + default n + depends on ARCH_HAVE_MPU + select ARCH_USE_MPU + ---help--- + Build in support for the ARM Cortex-M3/4 Memory Protection Unit (MPU). + Check your chip specifications first; not all Cortex-M3/4 chips + support the MPU. + +config ARM_MPU_NREGIONS + int "Number of MPU regions" + default 16 if ARCH_CORTEXM7 + default 8 if !ARCH_CORTEXM7 + depends on ARM_MPU + ---help--- + This is the number of protection regions supported by the MPU. + +config ARCH_HAVE_LOWVECTORS + bool + +config ARCH_LOWVECTORS + bool "Vectors in low memory" + default n + depends on ARCH_HAVE_LOWVECTORS + ---help--- + Support ARM vectors in low memory. + +config ARCH_ROMPGTABLE + bool "ROM page table" + default n + depends on ARCH_USE_MMU + ---help--- + Support a fixed memory mapping use a (read-only) page table in ROM/FLASH. + +config DEBUG_HARDFAULT + bool "Verbose Hard-Fault Debug" + default n + depends on DEBUG && (ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7) + ---help--- + Enables verbose debug output when a hard fault is occurs. This verbose + output is sometimes helpful when debugging difficult hard fault problems, + but may be more than you typcially want to see. + +if ARCH_CORTEXM0 +source arch/arm/src/armv6-m/Kconfig +endif +if ARCH_CORTEXA5 || ARCH_CORTEXA8 || ARCH_CORTEXA9 +source arch/arm/src/armv7-a/Kconfig +endif +if ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7 +source arch/arm/src/armv7-m/Kconfig +endif +if ARCH_CORTEXR4 || ARCH_CORTEXR4F || ARCH_CORTEXR5 || ARCH_CORTEXR5F || ARCH_CORTEX74 || ARCH_CORTEXR7F +source arch/arm/src/armv7-r/Kconfig +endif +if ARCH_ARM7TDMI || ARCH_ARM926EJS || ARCH_ARM920T +source arch/arm/src/arm/Kconfig +endif +if ARCH_CHIP_A1X +source arch/arm/src/a1x/Kconfig +endif +if ARCH_CHIP_C5471 +source arch/arm/src/c5471/Kconfig +endif +if ARCH_CHIP_CALYPSO +source arch/arm/src/calypso/Kconfig +endif +if ARCH_CHIP_DM320 +source arch/arm/src/dm320/Kconfig +endif +if ARCH_CHIP_EFM32 +source arch/arm/src/efm32/Kconfig +endif +if ARCH_CHIP_IMX1 +source arch/arm/src/imx1/Kconfig +endif +if ARCH_CHIP_IMX6 +source arch/arm/src/imx6/Kconfig +endif +if ARCH_CHIP_KINETIS +source arch/arm/src/kinetis/Kconfig +endif +if ARCH_CHIP_KL +source arch/arm/src/kl/Kconfig +endif +if ARCH_CHIP_LM || ARCH_CHIP_TIVA +source arch/arm/src/tiva/Kconfig +endif +if ARCH_CHIP_LPC11XX +source arch/arm/src/lpc11xx/Kconfig +endif +if ARCH_CHIP_LPC17XX +source arch/arm/src/lpc17xx/Kconfig +endif +if ARCH_CHIP_LPC214X +source arch/arm/src/lpc214x/Kconfig +endif +if ARCH_CHIP_LPC2378 +source arch/arm/src/lpc2378/Kconfig +endif +if ARCH_CHIP_LPC31XX +source arch/arm/src/lpc31xx/Kconfig +endif +if ARCH_CHIP_LPC43XX +source arch/arm/src/lpc43xx/Kconfig +endif +if ARCH_CHIP_NUC1XX +source arch/arm/src/nuc1xx/Kconfig +endif +if ARCH_CHIP_SAMA5 +source arch/arm/src/sama5/Kconfig +endif +if ARCH_CHIP_SAMD || ARCH_CHIP_SAML +source arch/arm/src/samdl/Kconfig +endif +if ARCH_CHIP_SAM34 +source arch/arm/src/sam34/Kconfig +endif +if ARCH_CHIP_SAMV7 +source arch/arm/src/samv7/Kconfig +endif +if ARCH_CHIP_STM32 +source arch/arm/src/stm32/Kconfig +endif +if ARCH_CHIP_STM32F7 +source arch/arm/src/stm32f7/Kconfig +endif +if ARCH_CHIP_STM32L4 +source arch/arm/src/stm32l4/Kconfig +endif +if ARCH_CHIP_STR71X +source arch/arm/src/str71x/Kconfig +endif +if ARCH_CHIP_TMS570 +source arch/arm/src/tms570/Kconfig +endif +if ARCH_CHIP_MOXART +source arch/arm/src/moxart/Kconfig +endif + +endif # ARCH_ARM diff --git a/arch/arm/include/.gitignore b/arch/arm/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6460c4a67846d5801c3600ce961277e3644f647 --- /dev/null +++ b/arch/arm/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/arm/include/a1x/a10_irq.h b/arch/arm/include/a1x/a10_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..82a40927438aff1fccc3ccff5f3988616a44a427 --- /dev/null +++ b/arch/arm/include/a1x/a10_irq.h @@ -0,0 +1,223 @@ +/**************************************************************************************** + * arch/arm/include/a1x/a10_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_A1X_A10_IRQ_H +#define __ARCH_ARM_INCLUDE_A1X_A10_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* External interrupts numbers */ + +#define A1X_IRQ_NMI 0 /* External Non-Mask Interrupt */ +# define A1X_IRQ_POWER 0 /* Power module */ +# define A1X_IRQ_BATTERY 0 /* Brownout detect */ +# define A1X_IRQ_BROWNOUT 0 /* Brownout */ +#define A1X_IRQ_UART0 1 /* UART 0 interrupt */ +#define A1X_IRQ_UART1 2 /* UART 1 interrupt */ +#define A1X_IRQ_UART2 3 /* UART 2 interrupt */ +#define A1X_IRQ_UART3 4 /* UART 3 interrupt */ +#define A1X_IRQ_IR0 5 /* IR 0 interrupt */ +#define A1X_IRQ_IR1 6 /* IR 1 interrupt */ +#define A1X_IRQ_TWI0 7 /* TWI 0 interrupt */ +#define A1X_IRQ_TWI1 8 /* TWI 1 interrupt */ +#define A1X_IRQ_TWI2 9 /* TWI 2 interrupt */ +#define A1X_IRQ_SPI0 10 /* SPI 0 interrupt */ +#define A1X_IRQ_SPI1 11 /* SPI 1 interrupt */ +#define A1X_IRQ_SPI2 12 /* SPI 2 interrupt */ +#define A1X_IRQ_NC 13 /* NC */ +#define A1X_IRQ_AC97 14 /* AC97 interrupt */ +#define A1X_IRQ_TS 15 /* TS interrupt */ +#define A1X_IRQ_IIS 16 /* Digital Audio Controller interrupt */ +#define A1X_IRQ_UART4 17 /* UART 4 interrupt */ +#define A1X_IRQ_UART5 18 /* UART 5 interrupt */ +#define A1X_IRQ_UART6 19 /* UART 6 interrupt */ +#define A1X_IRQ_UART7 20 /* UART 7 interrupt */ +#define A1X_IRQ_KEYPAD 21 /* Keypad interrupt */ +#define A1X_IRQ_TIMER0 22 /* Timer port 0 */ +#define A1X_IRQ_TIMER1 23 /* Timer port 1 */ +#define A1X_IRQ_TIMER2 24 /* Timer 2 */ +# define A1X_IRQ_ALARM 24 /* Alarm */ +# define A1X_IRQ_WD 24 /* Watchdog */ +#define A1X_IRQ_TIMER3 25 /* Timer 3 interrupt */ +#define A1X_IRQ_CAN 26 /* CAN Bus controller interrupt */ +#define A1X_IRQ_DMA 27 /* DMA channel interrupt */ +#define A1X_IRQ_PIO 28 /* PIO interrupt */ +#define A1X_IRQ_TOUCH 29 /* Touch Panel interrupt */ +#define A1X_IRQ_AUDIO 30 /* Analog Audio Codec interrupt */ +#define A1X_IRQ_LRADC 31 /* LRADC interrupt */ +#define A1X_IRQ_SDMMC0 32 /* SD/MMC Host Controller 0 interrupt */ +#define A1X_IRQ_SDMMC1 33 /* SD/MMC Host Controller 1 interrupt */ +#define A1X_IRQ_SDMMC2 34 /* SD/MMC Host Controller 2 interrupt */ +#define A1X_IRQ_SDMMC3 35 /* SD/MMC Host Controller 3 interrupt */ +#define A1X_IRQ_RESERVED36 36 +#define A1X_IRQ_NAND 37 /* NAND Flash Controller (NFC) interrupt */ +#define A1X_IRQ_USB0 38 /* USB 0 wakeup, connect, disconnect interrupt */ +#define A1X_IRQ_USB1 39 /* USB 1 wakeup, connect, disconnect interrupt */ +#define A1X_IRQ_USB2 40 /* USB 2 wakeup, connect, disconnect interrupt */ +#define A1X_IRQ_SCR 41 /* SCR interrupt */ +#define A1X_IRQ_CSI0 42 /* CSI 0 interrupt */ +#define A1X_IRQ_CSI1 43 /* CSI 1 interrupt */ +#define A1X_IRQ_LCDC0 44 /* LCD Controller 0 interrupt */ +#define A1X_IRQ_LCDC1 45 /* LCD Controller 1 interrupt */ +#define A1X_IRQ_MP 46 /* MP interrupt */ +#define A1X_IRQ_DEFE0 47 /* DE-FE0 interrupt */ +# define A1X_IRQ_DEBE0 47 /* DE-BE0 interrupt */ +#define A1X_IRQ_DEFE1 48 /* DE-FE1 interrupt */ +# define A1X_IRQ_DEBE1 48 /* DE-BE1 interrupt */ +#define A1X_IRQ_PMU 49 /* PMU interrupt */ +#define A1X_IRQ_SPI3 50 /* SPI3 interrupt */ +#define A1X_IRQ_TZASC 51 /* TZASC interrupt */ +#define A1X_IRQ_PATA 52 /* PATA interrupt */ +#define A1X_IRQ_VE 53 /* VE interrupt */ +#define A1X_IRQ_SS 54 /* Security System interrupt */ +#define A1X_IRQ_EMAC 55 /* EMAC interrupt */ +#define A1X_IRQ_RESERVED56 56 +#define A1X_IRQ_RESERVED57 57 +#define A1X_IRQ_HDMI 58 /* HDMI interrupt */ +#define A1X_IRQ_TVE 59 /* TV encoder 0/1 interrupt */ +#define A1X_IRQ_ACE 60 /* ACE interrupt */ +#define A1X_IRQ_TVD 61 /* TV decoder interrupt */ +#define A1X_IRQ_PS20 62 /* PS2-0 interrupt */ +#define A1X_IRQ_PS21 63 /* PS2-1 interrupt */ +#define A1X_IRQ_USB3 64 /* USB 3 wakeup, connect, disconnect interrupt */ +#define A1X_IRQ_USB4 65 /* USB 4 wakeup, connect, disconnect interrupt */ +#define A1X_IRQ_PLE 66 /* PLE interrupts */ +# define A1X_IRQ_PERFMU 66 /* Performance monitor interrupt */ +#define A1X_IRQ_TIMER4 67 /* Timer 4 interrupt */ +#define A1X_IRQ_TIMER5 68 /* Timer 5 interrupt */ +#define A1X_IRQ_GPU_GP 69 +#define A1X_IRQ_GPU_GPMMU 70 +#define A1X_IRQ_GPU_PP0 71 +#define A1X_IRQ_GPU_PPMMU0 72 +#define A1X_IRQ_GPU_PMU 73 +#define A1X_IRQ_GPU_RSV0 74 +#define A1X_IRQ_GPU_RSV1 75 +#define A1X_IRQ_GPU_RSV2 76 +#define A1X_IRQ_GPU_RSV3 77 +#define A1X_IRQ_GPU_RSV4 78 +#define A1X_IRQ_GPU_RSV5 79 +#define A1X_IRQ_GPU_RSV6 80 + +/* Total number of interrupts */ + +#define A1X_IRQ_NINT 81 + +/* Up to 32 external PIO interrupts */ + +#ifdef CONFIG_A1X_PIO_IRQ +# define A1X_PIO_EINT0 (A1X_IRQ_NINT+0) +# define A1X_PIO_EINT1 (A1X_IRQ_NINT+1) +# define A1X_PIO_EINT2 (A1X_IRQ_NINT+2) +# define A1X_PIO_EINT3 (A1X_IRQ_NINT+3) +# define A1X_PIO_EINT4 (A1X_IRQ_NINT+4) +# define A1X_PIO_EINT5 (A1X_IRQ_NINT+5) +# define A1X_PIO_EINT6 (A1X_IRQ_NINT+6) +# define A1X_PIO_EINT7 (A1X_IRQ_NINT+7) +# define A1X_PIO_EINT8 (A1X_IRQ_NINT+8) +# define A1X_PIO_EINT9 (A1X_IRQ_NINT+9) +# define A1X_PIO_EINT10 (A1X_IRQ_NINT+10) +# define A1X_PIO_EINT11 (A1X_IRQ_NINT+11) +# define A1X_PIO_EINT12 (A1X_IRQ_NINT+12) +# define A1X_PIO_EINT13 (A1X_IRQ_NINT+13) +# define A1X_PIO_EINT14 (A1X_IRQ_NINT+14) +# define A1X_PIO_EINT15 (A1X_IRQ_NINT+15) +# define A1X_PIO_EINT16 (A1X_IRQ_NINT+16) +# define A1X_PIO_EINT17 (A1X_IRQ_NINT+17) +# define A1X_PIO_EINT18 (A1X_IRQ_NINT+18) +# define A1X_PIO_EINT19 (A1X_IRQ_NINT+19) +# define A1X_PIO_EINT20 (A1X_IRQ_NINT+20) +# define A1X_PIO_EINT21 (A1X_IRQ_NINT+21) +# define A1X_PIO_EINT22 (A1X_IRQ_NINT+22) +# define A1X_PIO_EINT23 (A1X_IRQ_NINT+23) +# define A1X_PIO_EINT24 (A1X_IRQ_NINT+24) +# define A1X_PIO_EINT25 (A1X_IRQ_NINT+25) +# define A1X_PIO_EINT26 (A1X_IRQ_NINT+26) +# define A1X_PIO_EINT27 (A1X_IRQ_NINT+27) +# define A1X_PIO_EINT28 (A1X_IRQ_NINT+28) +# define A1X_PIO_EINT29 (A1X_IRQ_NINT+29) +# define A1X_PIO_EINT30 (A1X_IRQ_NINT+30) +# define A1X_PIO_EINT31 (A1X_IRQ_NINT+31) +# define A1X_PIO_NINT 32 +#else +# define A1X_PIO_NINT 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_IRQS (A1X_IRQ_NINT + A1X_PIO_NINT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_A1X_A10_IRQ_H */ + diff --git a/arch/arm/include/a1x/chip.h b/arch/arm/include/a1x/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..cca43bc037e2e26320a83c52195bbcd0efe689cc --- /dev/null +++ b/arch/arm/include/a1x/chip.h @@ -0,0 +1,68 @@ +/************************************************************************************ + * arch/arm/include/a1x/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_A1X_CHIP_H +#define __ARCH_ARM_INCLUDE_A1X_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* A1X Family */ + +#if defined(CONFIG_ARCH_CHIP_A10) +# define ALLWINNER_A1X 1 /* A1X family */ +#else +# error Unrecognized A1X chip +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_A1X_CHIP_H */ diff --git a/arch/arm/include/a1x/irq.h b/arch/arm/include/a1x/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..33fed49d240e6997a5739592cdaf6bfbfc5b3040 --- /dev/null +++ b/arch/arm/include/a1x/irq.h @@ -0,0 +1,91 @@ +/**************************************************************************************** + * arch/arm/include/a1x/irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_A1X_IRQ_H +#define __ARCH_ARM_INCLUDE_A1X_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* Chip-Specific External interrupts */ + +#if defined(CONFIG_ARCH_CHIP_A10) +# include +#else +# error Unrecognized A1X chip +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_A1X_IRQ_H */ + diff --git a/arch/arm/include/arch.h b/arch/arm/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..186b7cb653bdc8b8ee3128e066a3172138c03537 --- /dev/null +++ b/arch/arm/include/arch.h @@ -0,0 +1,210 @@ +/**************************************************************************** + * arch/arm/include/arch.h + * + * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARCH_H +#define __ARCH_ARM_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_PIC + +/* This identifies the register the is used by the processor as the PIC base + * register. It is usually r9 or r10 + */ + +#define PIC_REG r10 +#define PIC_REG_STRING "r10" + +/* Macros to get and set the PIC base register. picbase is assumed to be + * of type (void*) and that it will fit into a uint32_t. These must be + * inline so that they will be compatible with the ABIs rules for + * preserving the PIC register + */ + +#define up_getpicbase(ppicbase) \ +do { \ + uint32_t picbase; \ + __asm__ \ + ( \ + "\tmov %0, " PIC_REG_STRING "\n\t" \ + : "=r"(picbase) \ + ); \ + *ppicbase = (FAR void*)picbase; \ +} while (0) + +#define up_setpicbase(picbase) \ +do { \ + uint32_t _picbase = (uint32_t)picbase; \ + __asm__ \ + ( \ + "\tmov " PIC_REG_STRING ", %0\n\t" \ + : : "r"(_picbase) : PIC_REG_STRING \ + ); \ +} while (0) + +#endif /* CONFIG_PIC */ + +#ifdef CONFIG_ARCH_ADDRENV +#if CONFIG_MM_PGSIZE != 4096 +# error Only pages sizes of 4096 are currently supported (CONFIG_ARCH_ADDRENV) +#endif + +/* Convert 4KiB pages to 1MiB sections */ + +# define __PG2SECT_SHIFT (20 - MM_PGSHIFT) +# define __PG2SECT_MASK ((1 << __PG2SECT_SHIFT) - 1) + +# define ARCH_PG2SECT(p) (((p) + __PG2SECT_MASK) >> __PG2SECT_SHIFT) +# define ARCH_SECT2PG(s) ((s) << __PG2SECT_SHIFT) + +# define ARCH_TEXT_NSECTS ARCH_PG2SECT(CONFIG_ARCH_TEXT_NPAGES) +# define ARCH_DATA_NSECTS ARCH_PG2SECT(CONFIG_ARCH_DATA_NPAGES) +# define ARCH_HEAP_NSECTS ARCH_PG2SECT(CONFIG_ARCH_HEAP_NPAGES) + +# ifdef CONFIG_MM_SHM +# define ARCH_SHM_NSECTS ARCH_PG2SECT(ARCH_SHM_MAXPAGES) +# endif + +# ifdef CONFIG_ARCH_STACK_DYNAMIC +# define ARCH_STACK_NSECTS ARCH_PG2SECT(CONFIG_ARCH_STACK_NPAGES) +# endif +#endif /* CONFIG_ARCH_ADDRENV */ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef CONFIG_ARCH_ADDRENV +/* The task group resources are retained in a single structure, task_group_s + * that is defined in the header file nuttx/include/nuttx/sched.h. The type + * group_addrenv_t must be defined by platform specific logic in + * nuttx/arch//include/arch.h. + * + * These tables would hold the physical address of the level 2 page tables. + * All would be initially NULL and would not be backed up with physical memory + * until mappings in the level 2 page table are required. + */ + +struct group_addrenv_s +{ + /* Level 1 page table entries for each group section */ + + FAR uintptr_t *text[ARCH_TEXT_NSECTS]; + FAR uintptr_t *data[ARCH_DATA_NSECTS]; +#ifdef CONFIG_BUILD_KERNEL + FAR uintptr_t *heap[ARCH_HEAP_NSECTS]; +#ifdef CONFIG_MM_SHM + FAR uintptr_t *shm[ARCH_SHM_NSECTS]; +#endif + + /* Initial heap allocation (in bytes). This exists only provide an + * indirect path for passing the size of the initial heap to the heap + * initialization logic. These operations are separated in time and + * architecture. REVISIT: I would like a better way to do this. + */ + + size_t heapsize; +#endif +}; + +typedef struct group_addrenv_s group_addrenv_t; + +/* This type is used when the OS needs to temporarily instantiate a + * different address environment. Used in the implementation of + * + * int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv); + * int up_addrenv_restore(save_addrenv_t oldenv); + * + * In this case, the saved valued in the L1 page table are returned + */ + +struct save_addrenv_s +{ + FAR uint32_t text[ARCH_TEXT_NSECTS]; + FAR uint32_t data[ARCH_DATA_NSECTS]; +#ifdef CONFIG_BUILD_KERNEL + FAR uint32_t heap[ARCH_HEAP_NSECTS]; +#ifdef CONFIG_MM_SHM + FAR uint32_t shm[ARCH_SHM_NSECTS]; +#endif +#endif +}; + +typedef struct save_addrenv_s save_addrenv_t; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARCH_H */ diff --git a/arch/arm/include/arm/irq.h b/arch/arm/include/arm/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..37e5b93640c49622b9b41fc259a0111e20e0d869 --- /dev/null +++ b/arch/arm/include/arm/irq.h @@ -0,0 +1,240 @@ +/**************************************************************************** + * arch/arm/include/arm/irq.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARM_IRQ_H +#define __ARCH_ARM_INCLUDE_ARM_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ Stack Frame Format: + * + * Context is always saved/restored in the same way: + * + * (1) stmia rx, {r0-r14} + * (2) then the PC and CPSR + * + * This results in the following set of indices that + * can be used to access individual registers in the + * xcp.regs array: + */ + +#define REG_R0 (0) +#define REG_R1 (1) +#define REG_R2 (2) +#define REG_R3 (3) +#define REG_R4 (4) +#define REG_R5 (5) +#define REG_R6 (6) +#define REG_R7 (7) +#define REG_R8 (8) +#define REG_R9 (9) +#define REG_R10 (10) +#define REG_R11 (11) +#define REG_R12 (12) +#define REG_R13 (13) +#define REG_R14 (14) +#define REG_R15 (15) +#define REG_CPSR (16) + +#define XCPTCONTEXT_REGS (17) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This struct defines the way the registers are stored. We + * need to save: + * + * 1 CPSR + * 7 Static registers, v1-v7 (aka r4-r10) + * 1 Frame pointer, fp (aka r11) + * 1 Stack pointer, sp (aka r13) + * 1 Return address, lr (aka r14) + * --- + * 11 (XCPTCONTEXT_USER_REG) + * + * On interrupts, we also need to save: + * 4 Volatile registers, a1-a4 (aka r0-r3) + * 1 Scratch Register, ip (aka r12) + *--- + * 5 (XCPTCONTEXT_IRQ_REGS) + * + * For a total of 17 (XCPTCONTEXT_REGS) + */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR and CPSR used during + * signal processing. + */ + + uint32_t saved_pc; + uint32_t saved_cpsr; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; + + /* Extra fault address register saved for common paging logic. In the + * case of the prefetch abort, this value is the same as regs[REG_R15]; + * For the case of the data abort, this value is the value of the fault + * address register (FAR) at the time of data abort exception. + */ + +#ifdef CONFIG_PAGING + uintptr_t far; +#endif +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + + /* Save the current interrupt enable state & disable IRQs. */ + +static inline irqstate_t up_irq_save(void) +{ + unsigned int flags; + unsigned int temp; + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\torr %1, %0, #128\n" + "\tmsr cpsr_c, %1" + : "=r" (flags), "=r" (temp) + : + : "memory"); + return flags; +} + +/* Restore saved IRQ & FIQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + __asm__ __volatile__ + ( + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory"); +} +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARM_IRQ_H */ diff --git a/arch/arm/include/arm/syscall.h b/arch/arm/include/arm/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..18aa53f84e2fc01b8ebe517fc0fbd2db7c8169e5 --- /dev/null +++ b/arch/arm/include/arm/syscall.h @@ -0,0 +1,244 @@ +/**************************************************************************** + * arch/arm/include/arm/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARM_SYSCALL_H +#define __ARCH_ARM_INCLUDE_ARM_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x900001 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SWI with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0 __asm__("r0") = (long)(nbr); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5) + : "memory", "r14" + ); + + return reg0; +} + +/* SWI with SYS_ call number and six parameters */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg6 __asm__("r6") = (long)(parm6); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "swi %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6) + : "memory", "r14" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_ARM_SYSCALL_H */ + diff --git a/arch/arm/include/armv6-m/irq.h b/arch/arm/include/armv6-m/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..1d3da28e95ab4b3b57557079677a0721c09f39d3 --- /dev/null +++ b/arch/arm/include/armv6-m/irq.h @@ -0,0 +1,376 @@ +/**************************************************************************** + * arch/arm/include/armv6-m/irq.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If this is a kernel build, how many nested system calls should we support? */ + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +/* IRQ Stack Frame Format *************************************************** + * + * The following additional registers are stored by the interrupt handling + * logic. + */ + +#define REG_R13 (0) /* R13 = SP at time of interrupt */ +#define REG_PRIMASK (1) /* PRIMASK */ +#define REG_R4 (2) /* R4 */ +#define REG_R5 (3) /* R5 */ +#define REG_R6 (4) /* R6 */ +#define REG_R7 (5) /* R7 */ +#define REG_R8 (6) /* R8 */ +#define REG_R9 (7) /* R9 */ +#define REG_R10 (8) /* R10 */ +#define REG_R11 (9) /* R11 */ + +/* In the kernel build, we may return to either privileged or unprivileged + * modes. + */ + +#ifdef CONFIG_BUILD_PROTECTED +# define REG_EXC_RETURN (10) /* EXC_RETURN */ +# define SW_XCPT_REGS (11) +#else +# define SW_XCPT_REGS (10) +#endif + +/* The total number of registers saved by software */ + +#define SW_XCPT_SIZE (4 * SW_XCPT_REGS) + +/* On entry into an IRQ, the hardware automatically saves the following + * registers on the stack in this (address) order: + */ + +#define REG_R0 (SW_XCPT_REGS+0) /* R0 */ +#define REG_R1 (SW_XCPT_REGS+1) /* R1 */ +#define REG_R2 (SW_XCPT_REGS+2) /* R2 */ +#define REG_R3 (SW_XCPT_REGS+3) /* R3 */ +#define REG_R12 (SW_XCPT_REGS+4) /* R12 */ +#define REG_R14 (SW_XCPT_REGS+5) /* R14 = LR */ +#define REG_R15 (SW_XCPT_REGS+6) /* R15 = PC */ +#define REG_XPSR (SW_XCPT_REGS+7) /* xPSR */ + +#define HW_XCPT_REGS (8) +#define HW_XCPT_SIZE (4 * HW_XCPT_REGS) + +#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Alternate register names */ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ + uint32_t excreturn; /* The EXC_RETURN value */ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ +#ifndef CONFIG_DISABLE_SIGNALS + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR, PRIMASK, and xPSR used during + * signal processing. + */ + + uint32_t saved_pc; + uint32_t saved_primask; + uint32_t saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + uint32_t saved_lr; +#endif + +# ifdef CONFIG_BUILD_PROTECTED + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; + +# endif +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Get/set the PRIMASK register */ + +static inline uint8_t getprimask(void) inline_function; +static inline uint8_t getprimask(void) +{ + uint32_t primask; + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + : "=r" (primask) + : + : "memory"); + + return (uint8_t)primask; +} + +static inline void setprimask(uint32_t primask) inline_function; +static inline void setprimask(uint32_t primask) +{ + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (primask) + : "memory"); +} + +/* Disable IRQs */ + +static inline void up_irq_disable(void) inline_function; +static inline void up_irq_disable(void) +{ + __asm__ __volatile__ ("\tcpsid i\n"); +} + +/* Save the current primask state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) inline_function; +static inline irqstate_t up_irq_save(void) +{ + unsigned short primask; + + /* Return the current value of primask register and set + * bit 0 of the primask register to disable interrupts + */ + + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + "\tcpsid i\n" + : "=r" (primask) + : + : "memory"); + + return primask; +} + +/* Enable IRQs */ + +static inline void up_irq_enable(void) inline_function; +static inline void up_irq_enable(void) +{ + __asm__ __volatile__ ("\tcpsie i\n"); +} + +/* Restore saved primask state */ + +static inline void up_irq_restore(irqstate_t flags) inline_function; +static inline void up_irq_restore(irqstate_t flags) +{ + /* If bit 0 of the primask is 0, then we need to restore + * interrupts. + */ + + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (flags) + : "memory"); +} + +/* Get/set IPSR */ + +static inline uint32_t getipsr(void) inline_function; +static inline uint32_t getipsr(void) +{ + uint32_t ipsr; + __asm__ __volatile__ + ( + "\tmrs %0, ipsr\n" + : "=r" (ipsr) + : + : "memory"); + + return ipsr; +} + +/* Get/set CONTROL */ + +static inline uint32_t getcontrol(void) inline_function; +static inline uint32_t getcontrol(void) +{ + uint32_t control; + __asm__ __volatile__ + ( + "\tmrs %0, control\n" + : "=r" (control) + : + : "memory"); + + return control; +} + +static inline void setcontrol(uint32_t control) inline_function; +static inline void setcontrol(uint32_t control) +{ + __asm__ __volatile__ + ( + "\tmsr control, %0\n" + : + : "r" (control) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H */ + diff --git a/arch/arm/include/armv6-m/syscall.h b/arch/arm/include/armv6-m/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..de7c2a754b8ae8214c41684911b8d135d8e0b800 --- /dev/null +++ b/arch/arm/include/armv6-m/syscall.h @@ -0,0 +1,267 @@ +/**************************************************************************** + * arch/arm/include/armv6-m/syscall.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV6_M_SYSCALL_H +#define __ARCH_ARM_INCLUDE_ARMV6_M_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the value used as the argument to the SVC instruction. It is not + * used. + */ + +#define SYS_syscall 0x00 + +/* The SYS_signal_handler_return is executed here... its value is not always + * available in this context and so is assumed to be 7. + */ + +#ifndef SYS_signal_handler_return +# define SYS_signal_handler_return (7) +#elif SYS_signal_handler_return != 7 +# error "SYS_signal_handler_return was assumed to be 7" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SVC call with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0 __asm__("r0") = (long)(nbr); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and four parameters. + * + * NOTE the nonstandard parameter passing: parm4 is in R4 + */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and five parameters. + * + * NOTE the nonstandard parameter passing: parm4 and parm5 are in R4 and R5 + */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and six parameters. + * + * NOTE the nonstandard parameter passing: parm4-parm6 are in R4-R6 + */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg6 __asm__("r6") = (long)(parm6); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6) + : "memory" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_SYSCALL_H */ + diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f14785df930871161856811152f8a881d9bea166 --- /dev/null +++ b/arch/arm/include/armv7-a/irq.h @@ -0,0 +1,421 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/irq.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_A_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV7_A_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ Stack Frame Format: + * + * Context is always saved/restored in the same way: + * + * (1) stmia rx, {r0-r14} + * (2) then the PC and CPSR + * + * This results in the following set of indices that can be used to access + * individual registers in the xcp.regs array: + */ + +#define REG_R0 (0) +#define REG_R1 (1) +#define REG_R2 (2) +#define REG_R3 (3) +#define REG_R4 (4) +#define REG_R5 (5) +#define REG_R6 (6) +#define REG_R7 (7) +#define REG_R8 (8) +#define REG_R9 (9) +#define REG_R10 (10) +#define REG_R11 (11) +#define REG_R12 (12) +#define REG_R13 (13) +#define REG_R14 (14) +#define REG_R15 (15) +#define REG_CPSR (16) + +#define ARM_CONTEXT_REGS (17) + +/* If the MCU supports a floating point unit, then it will be necessary + * to save the state of the FPU status register and data registers on + * each context switch. These registers are not saved during interrupt + * level processing, however. So, as a consequence, floating point + * operations may NOT be performed in interrupt handlers. + * + * The FPU provides an extension register file containing 32 single- + * precision registers. These can be viewed as: + * + * - Sixteen 64-bit double word registers, D0-D15 + * - Thirty-two 32-bit single-word registers, S0-S31 + * S<2n> maps to the least significant half of D + * S<2n+1> maps to the most significant half of D. + */ + +#ifdef CONFIG_ARCH_FPU +# define REG_D0 (ARM_CONTEXT_REGS+0) /* D0 */ +# define REG_S0 (ARM_CONTEXT_REGS+0) /* S0 */ +# define REG_S1 (ARM_CONTEXT_REGS+1) /* S1 */ +# define REG_D1 (ARM_CONTEXT_REGS+2) /* D1 */ +# define REG_S2 (ARM_CONTEXT_REGS+2) /* S2 */ +# define REG_S3 (ARM_CONTEXT_REGS+3) /* S3 */ +# define REG_D2 (ARM_CONTEXT_REGS+4) /* D2 */ +# define REG_S4 (ARM_CONTEXT_REGS+4) /* S4 */ +# define REG_S5 (ARM_CONTEXT_REGS+5) /* S5 */ +# define REG_D3 (ARM_CONTEXT_REGS+6) /* D3 */ +# define REG_S6 (ARM_CONTEXT_REGS+6) /* S6 */ +# define REG_S7 (ARM_CONTEXT_REGS+7) /* S7 */ +# define REG_D4 (ARM_CONTEXT_REGS+8) /* D4 */ +# define REG_S8 (ARM_CONTEXT_REGS+8) /* S8 */ +# define REG_S9 (ARM_CONTEXT_REGS+9) /* S9 */ +# define REG_D5 (ARM_CONTEXT_REGS+10) /* D5 */ +# define REG_S10 (ARM_CONTEXT_REGS+10) /* S10 */ +# define REG_S11 (ARM_CONTEXT_REGS+11) /* S11 */ +# define REG_D6 (ARM_CONTEXT_REGS+12) /* D6 */ +# define REG_S12 (ARM_CONTEXT_REGS+12) /* S12 */ +# define REG_S13 (ARM_CONTEXT_REGS+13) /* S13 */ +# define REG_D7 (ARM_CONTEXT_REGS+14) /* D7 */ +# define REG_S14 (ARM_CONTEXT_REGS+14) /* S14 */ +# define REG_S15 (ARM_CONTEXT_REGS+15) /* S15 */ +# define REG_D8 (ARM_CONTEXT_REGS+16) /* D8 */ +# define REG_S16 (ARM_CONTEXT_REGS+16) /* S16 */ +# define REG_S17 (ARM_CONTEXT_REGS+17) /* S17 */ +# define REG_D9 (ARM_CONTEXT_REGS+18) /* D9 */ +# define REG_S18 (ARM_CONTEXT_REGS+18) /* S18 */ +# define REG_S19 (ARM_CONTEXT_REGS+19) /* S19 */ +# define REG_D10 (ARM_CONTEXT_REGS+20) /* D10 */ +# define REG_S20 (ARM_CONTEXT_REGS+20) /* S20 */ +# define REG_S21 (ARM_CONTEXT_REGS+21) /* S21 */ +# define REG_D11 (ARM_CONTEXT_REGS+22) /* D11 */ +# define REG_S22 (ARM_CONTEXT_REGS+22) /* S22 */ +# define REG_S23 (ARM_CONTEXT_REGS+23) /* S23 */ +# define REG_D12 (ARM_CONTEXT_REGS+24) /* D12 */ +# define REG_S24 (ARM_CONTEXT_REGS+24) /* S24 */ +# define REG_S25 (ARM_CONTEXT_REGS+25) /* S25 */ +# define REG_D13 (ARM_CONTEXT_REGS+26) /* D13 */ +# define REG_S26 (ARM_CONTEXT_REGS+26) /* S26 */ +# define REG_S27 (ARM_CONTEXT_REGS+27) /* S27 */ +# define REG_D14 (ARM_CONTEXT_REGS+28) /* D14 */ +# define REG_S28 (ARM_CONTEXT_REGS+28) /* S28 */ +# define REG_S29 (ARM_CONTEXT_REGS+29) /* S29 */ +# define REG_D15 (ARM_CONTEXT_REGS+30) /* D15 */ +# define REG_S30 (ARM_CONTEXT_REGS+30) /* S30 */ +# define REG_S31 (ARM_CONTEXT_REGS+31) /* S31 */ +# define REG_FPSCR (ARM_CONTEXT_REGS+32) /* Floating point status and control */ +# define FPU_CONTEXT_REGS (33) +#else +# define FPU_CONTEXT_REGS (0) +#endif + +/* The total number of registers saved by software */ + +#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Friendly register names */ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ +#ifdef CONFIG_BUILD_KERNEL + uint32_t cpsr; /* The CPSR value */ +#endif + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* This struct defines the way the registers are stored. We need to save: + * + * 1 CPSR + * 7 Static registers, v1-v7 (aka r4-r10) + * 1 Frame pointer, fp (aka r11) + * 1 Stack pointer, sp (aka r13) + * 1 Return address, lr (aka r14) + * --- + * 11 (XCPTCONTEXT_USER_REG) + * + * On interrupts, we also need to save: + * 4 Volatile registers, a1-a4 (aka r0-r3) + * 1 Scratch Register, ip (aka r12) + *--- + * 5 (XCPTCONTEXT_IRQ_REGS) + * + * For a total of 17 (XCPTCONTEXT_REGS) + */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR and CPSR used during signal processing. */ + + uint32_t saved_pc; + uint32_t saved_cpsr; + +# ifdef CONFIG_BUILD_KERNEL + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; + +# endif +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; + + /* Extra fault address register saved for common paging logic. In the + * case of the pre-fetch abort, this value is the same as regs[REG_R15]; + * For the case of the data abort, this value is the value of the fault + * address register (FAR) at the time of data abort exception. + */ + +#ifdef CONFIG_PAGING + uintptr_t far; +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; +#endif + +#ifdef CONFIG_ARCH_ADDRENV +#ifdef CONFIG_ARCH_STACK_DYNAMIC + /* This array holds the physical address of the level 2 page table used + * to map the thread's stack memory. This array will be initially of + * zeroed and would be back-up up with pages during page fault exception + * handling to support dynamically sized stacks for each thread. + */ + + FAR uintptr_t *ustack[ARCH_STACK_NSECTS]; +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* In this configuration, all syscalls execute from an internal kernel + * stack. Why? Because when we instantiate and initialize the address + * environment of the new user process, we will temporarily lose the + * address environment of the old user process, including its stack + * contents. The kernel C logic will crash immediately with no valid + * stack in place. + */ + + FAR uint32_t *ustkptr; /* Saved user stack pointer */ + FAR uint32_t *kstack; /* Allocate base of the (aligned) kernel stack */ +#ifndef CONFIG_DISABLE_SIGNALS + FAR uint32_t *kstkptr; /* Saved kernel stack pointer */ +#endif +#endif +#endif +}; +#endif + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Return the current IRQ state */ + +static inline irqstate_t irqstate(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Disable IRQs and return the previous IRQ state */ + +static inline irqstate_t up_irq_save(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsid i\n" +#if defined(CONFIG_ARMV7A_DECODEFIQ) + "\tcpsid f\n" +#endif + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Enable IRQs and return the previous IRQ state */ + +static inline irqstate_t up_irq_enable(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsie i\n" +#if defined(CONFIG_ARMV7A_DECODEFIQ) + "\tcpsie f\n" +#endif + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Restore saved IRQ & FIQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + __asm__ __volatile__ + ( + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_A_IRQ_H */ diff --git a/arch/arm/include/armv7-a/syscall.h b/arch/arm/include/armv7-a/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..9b86d064659137ad6cc2dbfbf2487c5e387be83f --- /dev/null +++ b/arch/arm/include/armv7-a/syscall.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/syscall.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_A_SYSCALL_H +#define __ARCH_ARM_INCLUDE_ARMV7_A_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x900001 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SVC with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0 __asm__("r0") = (long)(nbr); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and six parameters */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg6 __asm__("r6") = (long)(parm6); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6) + : "memory", "r14" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_ARMV7_A_SYSCALL_H */ diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f63fadbc490dff6b2c813cc1f11d3f7c27872031 --- /dev/null +++ b/arch/arm/include/armv7-m/irq.h @@ -0,0 +1,392 @@ +/**************************************************************************** + * arch/arm/include/armv7-m/irq.h + * + * Copyright (C) 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/* Included implementation-dependent register save structure layouts */ + +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) +# include +#else +# include +#endif + +#ifdef CONFIG_ARMV7M_USEBASEPRI +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If this is a kernel build, how many nested system calls should we support? */ + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +/* Alternate register names *************************************************/ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ + uint32_t excreturn; /* The EXC_RETURN value */ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ +#ifndef CONFIG_DISABLE_SIGNALS + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + + FAR void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR, PRIMASK, and xPSR used during + * signal processing. + */ + + uint32_t saved_pc; +#ifdef CONFIG_ARMV7M_USEBASEPRI + uint32_t saved_basepri; +#else + uint32_t saved_primask; +#endif + uint32_t saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + uint32_t saved_lr; +#endif + +# ifdef CONFIG_BUILD_PROTECTED + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; + +# endif +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; + +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Get/set the PRIMASK register */ + +static inline uint8_t getprimask(void) inline_function; +static inline uint8_t getprimask(void) +{ + uint32_t primask; + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + : "=r" (primask) + : + : "memory"); + + return (uint8_t)primask; +} + +static inline void setprimask(uint32_t primask) inline_function; +static inline void setprimask(uint32_t primask) +{ + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (primask) + : "memory"); +} + +/* Get/set the BASEPRI register. The BASEPRI register defines the minimum + * priority for exception processing. When BASEPRI is set to a nonzero + * value, it prevents the activation of all exceptions with the same or + * lower priority level as the BASEPRI value. + */ + +static inline uint8_t getbasepri(void) inline_function; +static inline uint8_t getbasepri(void) +{ + uint32_t basepri; + + __asm__ __volatile__ + ( + "\tmrs %0, basepri\n" + : "=r" (basepri) + : + : "memory"); + + return (uint8_t)basepri; +} + +static inline void setbasepri(uint32_t basepri) inline_function; +static inline void setbasepri(uint32_t basepri) +{ + __asm__ __volatile__ + ( + "\tmsr basepri, %0\n" + : + : "r" (basepri) + : "memory"); +} + +/* Disable IRQs */ + +static inline void up_irq_disable(void) inline_function; +static inline void up_irq_disable(void) +{ +#ifdef CONFIG_ARMV7M_USEBASEPRI + setbasepri(NVIC_SYSH_DISABLE_PRIORITY); +#else + __asm__ __volatile__ ("\tcpsid i\n"); +#endif +} + +/* Save the current primask state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) inline_function; +static inline irqstate_t up_irq_save(void) +{ +#ifdef CONFIG_ARMV7M_USEBASEPRI + + uint8_t basepri = getbasepri(); + setbasepri(NVIC_SYSH_DISABLE_PRIORITY); + return (irqstate_t)basepri; + +#else + + unsigned short primask; + + /* Return the current value of primask register and set + * bit 0 of the primask register to disable interrupts + */ + + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + "\tcpsid i\n" + : "=r" (primask) + : + : "memory"); + + return primask; +#endif +} + +/* Enable IRQs */ + +static inline void up_irq_enable(void) inline_function; +static inline void up_irq_enable(void) +{ + setbasepri(0); + __asm__ __volatile__ ("\tcpsie i\n"); +} + +/* Restore saved primask state */ + +static inline void up_irq_restore(irqstate_t flags) inline_function; +static inline void up_irq_restore(irqstate_t flags) +{ +#ifdef CONFIG_ARMV7M_USEBASEPRI + setbasepri((uint32_t)flags); +#else + /* If bit 0 of the primask is 0, then we need to restore + * interrupts. + */ + + __asm__ __volatile__ + ( + "\ttst %0, #1\n" + "\tbne.n 1f\n" + "\tcpsie i\n" + "1:\n" + : + : "r" (flags) + : "memory"); +#endif +} + +/* Get/set IPSR */ + +static inline uint32_t getipsr(void) inline_function; +static inline uint32_t getipsr(void) +{ + uint32_t ipsr; + __asm__ __volatile__ + ( + "\tmrs %0, ipsr\n" + : "=r" (ipsr) + : + : "memory"); + + return ipsr; +} + +/* Get/set CONTROL */ + +static inline uint32_t getcontrol(void) inline_function; +static inline uint32_t getcontrol(void) +{ + uint32_t control; + __asm__ __volatile__ + ( + "\tmrs %0, control\n" + : "=r" (control) + : + : "memory"); + + return control; +} + +static inline void setcontrol(uint32_t control) inline_function; +static inline void setcontrol(uint32_t control) +{ + __asm__ __volatile__ + ( + "\tmsr control, %0\n" + : + : "r" (control) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_H */ + diff --git a/arch/arm/include/armv7-m/irq_cmnvector.h b/arch/arm/include/armv7-m/irq_cmnvector.h new file mode 100644 index 0000000000000000000000000000000000000000..c07af9e632bf827592ad4a9a2277a15b9bb99e98 --- /dev/null +++ b/arch/arm/include/armv7-m/irq_cmnvector.h @@ -0,0 +1,168 @@ +/**************************************************************************** + * arch/arm/include/armv7-m/irq_cmnvector.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_CMNVECTOR_H +#define __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_CMNVECTOR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ Stack Frame Format: */ + +/* The following additional registers are stored by the interrupt handling + * logic. + */ + +#define REG_R13 (0) /* R13 = SP at time of interrupt */ +#ifdef CONFIG_ARMV7M_USEBASEPRI +# define REG_BASEPRI (1) /* BASEPRI */ +#else +# define REG_PRIMASK (1) /* PRIMASK */ +#endif +#define REG_R4 (2) /* R4 */ +#define REG_R5 (3) /* R5 */ +#define REG_R6 (4) /* R6 */ +#define REG_R7 (5) /* R7 */ +#define REG_R8 (6) /* R8 */ +#define REG_R9 (7) /* R9 */ +#define REG_R10 (8) /* R10 */ +#define REG_R11 (9) /* R11 */ +#define REG_EXC_RETURN (10) /* EXC_RETURN */ +#define SW_INT_REGS (11) + +#ifdef CONFIG_ARCH_FPU + +/* If the MCU supports a floating point unit, then it will be necessary + * to save the state of the non-volatile registers before calling code + * that may save and overwrite them. + */ + +# define REG_S16 (SW_INT_REGS+0) /* S16 */ +# define REG_S17 (SW_INT_REGS+1) /* S17 */ +# define REG_S18 (SW_INT_REGS+2) /* S18 */ +# define REG_S19 (SW_INT_REGS+3) /* S19 */ +# define REG_S20 (SW_INT_REGS+4) /* S20 */ +# define REG_S21 (SW_INT_REGS+5) /* S21 */ +# define REG_S22 (SW_INT_REGS+6) /* S22 */ +# define REG_S23 (SW_INT_REGS+7) /* S23 */ +# define REG_S24 (SW_INT_REGS+8) /* S24 */ +# define REG_S25 (SW_INT_REGS+9) /* S25 */ +# define REG_S26 (SW_INT_REGS+10) /* S26 */ +# define REG_S27 (SW_INT_REGS+11) /* S27 */ +# define REG_S28 (SW_INT_REGS+12) /* S28 */ +# define REG_S29 (SW_INT_REGS+13) /* S29 */ +# define REG_S30 (SW_INT_REGS+14) /* S30 */ +# define REG_S31 (SW_INT_REGS+15) /* S31 */ +# define SW_FPU_REGS (16) +#else +# define SW_FPU_REGS (0) +#endif + +/* The total number of registers saved by software */ + +#define SW_XCPT_REGS (SW_INT_REGS + SW_FPU_REGS) +#define SW_XCPT_SIZE (4 * SW_XCPT_REGS) + +/* On entry into an IRQ, the hardware automatically saves the following + * registers on the stack in this (address) order: + */ + +#define REG_R0 (SW_XCPT_REGS+0) /* R0 */ +#define REG_R1 (SW_XCPT_REGS+1) /* R1 */ +#define REG_R2 (SW_XCPT_REGS+2) /* R2 */ +#define REG_R3 (SW_XCPT_REGS+3) /* R3 */ +#define REG_R12 (SW_XCPT_REGS+4) /* R12 */ +#define REG_R14 (SW_XCPT_REGS+5) /* R14 = LR */ +#define REG_R15 (SW_XCPT_REGS+6) /* R15 = PC */ +#define REG_XPSR (SW_XCPT_REGS+7) /* xPSR */ +#define HW_INT_REGS (8) + +#ifdef CONFIG_ARCH_FPU + +/* If the FPU is enabled, the hardware also saves the volatile FP registers. + */ + +# define REG_S0 (SW_XCPT_REGS+8) /* S0 */ +# define REG_S1 (SW_XCPT_REGS+9) /* S1 */ +# define REG_S2 (SW_XCPT_REGS+10) /* S2 */ +# define REG_S3 (SW_XCPT_REGS+11) /* S3 */ +# define REG_S4 (SW_XCPT_REGS+12) /* S4 */ +# define REG_S5 (SW_XCPT_REGS+13) /* S5 */ +# define REG_S6 (SW_XCPT_REGS+14) /* S6 */ +# define REG_S7 (SW_XCPT_REGS+15) /* S7 */ +# define REG_S8 (SW_XCPT_REGS+16) /* S8 */ +# define REG_S9 (SW_XCPT_REGS+17) /* S9 */ +# define REG_S10 (SW_XCPT_REGS+18) /* S10 */ +# define REG_S11 (SW_XCPT_REGS+19) /* S11 */ +# define REG_S12 (SW_XCPT_REGS+20) /* S12 */ +# define REG_S13 (SW_XCPT_REGS+21) /* S13 */ +# define REG_S14 (SW_XCPT_REGS+22) /* S14 */ +# define REG_S15 (SW_XCPT_REGS+23) /* S15 */ +# define REG_FPSCR (SW_XCPT_REGS+24) /* FPSCR */ +# define REG_FPReserved (SW_XCPT_REGS+25) /* Reserved */ +# define HW_FPU_REGS (18) +#else +# define HW_FPU_REGS (0) +#endif + +#define HW_XCPT_REGS (HW_INT_REGS + HW_FPU_REGS) +#define HW_XCPT_SIZE (4 * HW_XCPT_REGS) + +#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_CMNVECTOR_H */ + diff --git a/arch/arm/include/armv7-m/irq_lazyfpu.h b/arch/arm/include/armv7-m/irq_lazyfpu.h new file mode 100644 index 0000000000000000000000000000000000000000..895d32befbadff91840b1b4247955fa77dd52c97 --- /dev/null +++ b/arch/arm/include/armv7-m/irq_lazyfpu.h @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/arm/include/armv7-m/irq_lazyfpu.h + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_LAZYFPU_H +#define __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_LAZYFPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ Stack Frame Format: */ + +/* The following additional registers are stored by the interrupt handling + * logic. + */ + +#define REG_R13 (0) /* R13 = SP at time of interrupt */ +#ifdef CONFIG_ARMV7M_USEBASEPRI +# define REG_BASEPRI (1) /* BASEPRI */ +#else +# define REG_PRIMASK (1) /* PRIMASK */ +#endif +#define REG_R4 (2) /* R4 */ +#define REG_R5 (3) /* R5 */ +#define REG_R6 (4) /* R6 */ +#define REG_R7 (5) /* R7 */ +#define REG_R8 (6) /* R8 */ +#define REG_R9 (7) /* R9 */ +#define REG_R10 (8) /* R10 */ +#define REG_R11 (9) /* R11 */ + +#ifdef CONFIG_BUILD_PROTECTED +# define REG_EXC_RETURN (10) /* EXC_RETURN */ +# define SW_INT_REGS (11) +#else +# define SW_INT_REGS (10) +#endif + +/* If the MCU supports a floating point unit, then it will be necessary + * to save the state of the FPU status register and data registers on + * each context switch. These registers are not saved during interrupt + * level processing, however. So, as a consequence, floating point + * operations may NOT be performed in interrupt handlers. + * + * The FPU provides an extension register file containing 32 single- + * precision registers. These can be viewed as: + * + * - Sixteen 64-bit doubleword registers, D0-D15 + * - Thirty-two 32-bit single-word registers, S0-S31 + * S<2n> maps to the least significant half of D + * S<2n+1> maps to the most significant half of D. + */ + +#ifdef CONFIG_ARCH_FPU +# define REG_D0 (SW_INT_REGS+0) /* D0 */ +# define REG_S0 (SW_INT_REGS+0) /* S0 */ +# define REG_S1 (SW_INT_REGS+1) /* S1 */ +# define REG_D1 (SW_INT_REGS+2) /* D1 */ +# define REG_S2 (SW_INT_REGS+2) /* S2 */ +# define REG_S3 (SW_INT_REGS+3) /* S3 */ +# define REG_D2 (SW_INT_REGS+4) /* D2 */ +# define REG_S4 (SW_INT_REGS+4) /* S4 */ +# define REG_S5 (SW_INT_REGS+5) /* S5 */ +# define REG_D3 (SW_INT_REGS+6) /* D3 */ +# define REG_S6 (SW_INT_REGS+6) /* S6 */ +# define REG_S7 (SW_INT_REGS+7) /* S7 */ +# define REG_D4 (SW_INT_REGS+8) /* D4 */ +# define REG_S8 (SW_INT_REGS+8) /* S8 */ +# define REG_S9 (SW_INT_REGS+9) /* S9 */ +# define REG_D5 (SW_INT_REGS+10) /* D5 */ +# define REG_S10 (SW_INT_REGS+10) /* S10 */ +# define REG_S11 (SW_INT_REGS+11) /* S11 */ +# define REG_D6 (SW_INT_REGS+12) /* D6 */ +# define REG_S12 (SW_INT_REGS+12) /* S12 */ +# define REG_S13 (SW_INT_REGS+13) /* S13 */ +# define REG_D7 (SW_INT_REGS+14) /* D7 */ +# define REG_S14 (SW_INT_REGS+14) /* S14 */ +# define REG_S15 (SW_INT_REGS+15) /* S15 */ +# define REG_D8 (SW_INT_REGS+16) /* D8 */ +# define REG_S16 (SW_INT_REGS+16) /* S16 */ +# define REG_S17 (SW_INT_REGS+17) /* S17 */ +# define REG_D9 (SW_INT_REGS+18) /* D9 */ +# define REG_S18 (SW_INT_REGS+18) /* S18 */ +# define REG_S19 (SW_INT_REGS+19) /* S19 */ +# define REG_D10 (SW_INT_REGS+20) /* D10 */ +# define REG_S20 (SW_INT_REGS+20) /* S20 */ +# define REG_S21 (SW_INT_REGS+21) /* S21 */ +# define REG_D11 (SW_INT_REGS+22) /* D11 */ +# define REG_S22 (SW_INT_REGS+22) /* S22 */ +# define REG_S23 (SW_INT_REGS+23) /* S23 */ +# define REG_D12 (SW_INT_REGS+24) /* D12 */ +# define REG_S24 (SW_INT_REGS+24) /* S24 */ +# define REG_S25 (SW_INT_REGS+25) /* S25 */ +# define REG_D13 (SW_INT_REGS+26) /* D13 */ +# define REG_S26 (SW_INT_REGS+26) /* S26 */ +# define REG_S27 (SW_INT_REGS+27) /* S27 */ +# define REG_D14 (SW_INT_REGS+28) /* D14 */ +# define REG_S28 (SW_INT_REGS+28) /* S28 */ +# define REG_S29 (SW_INT_REGS+29) /* S29 */ +# define REG_D15 (SW_INT_REGS+30) /* D15 */ +# define REG_S30 (SW_INT_REGS+30) /* S30 */ +# define REG_S31 (SW_INT_REGS+31) /* S31 */ +# define REG_FPSCR (SW_INT_REGS+32) /* Floating point status and control */ +# define SW_FPU_REGS (33) +#else +# define SW_FPU_REGS (0) +#endif + +/* The total number of registers saved by software */ + +#define SW_XCPT_REGS (SW_INT_REGS + SW_FPU_REGS) +#define SW_XCPT_SIZE (4 * SW_XCPT_REGS) + +/* On entry into an IRQ, the hardware automatically saves the following + * registers on the stack in this (address) order: + */ + +#define REG_R0 (SW_XCPT_REGS+0) /* R0 */ +#define REG_R1 (SW_XCPT_REGS+1) /* R1 */ +#define REG_R2 (SW_XCPT_REGS+2) /* R2 */ +#define REG_R3 (SW_XCPT_REGS+3) /* R3 */ +#define REG_R12 (SW_XCPT_REGS+4) /* R12 */ +#define REG_R14 (SW_XCPT_REGS+5) /* R14 = LR */ +#define REG_R15 (SW_XCPT_REGS+6) /* R15 = PC */ +#define REG_XPSR (SW_XCPT_REGS+7) /* xPSR */ + +#define HW_XCPT_REGS (8) +#define HW_XCPT_SIZE (4 * HW_XCPT_REGS) + +#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS) +#define XCPTCONTEXT_SIZE (HW_XCPT_SIZE + SW_XCPT_SIZE) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_IRQ_LAZYFPU_H */ + diff --git a/arch/arm/include/armv7-m/syscall.h b/arch/arm/include/armv7-m/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..dfef3ec3910d6077b14bb941c7fe83dc179dfbb7 --- /dev/null +++ b/arch/arm/include/armv7-m/syscall.h @@ -0,0 +1,267 @@ +/**************************************************************************** + * arch/arm/include/armv7-m/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_M_SYSCALL_H +#define __ARCH_ARM_INCLUDE_ARMV7_M_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the value used as the argument to the SVC instruction. It is not + * used. + */ + +#define SYS_syscall 0x00 + +/* The SYS_signal_handler_return is executed here... its value is not always + * available in this context and so is assumed to be 7. + */ + +#ifndef SYS_signal_handler_return +# define SYS_signal_handler_return (7) +#elif SYS_signal_handler_return != 7 +# error "SYS_signal_handler_return was assumed to be 7" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SVC call with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0 __asm__("r0") = (long)(nbr); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and four parameters. + * + * NOTE the nonstandard parameter passing: parm4 is in R4 + */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and five parameters. + * + * NOTE the nonstandard parameter passing: parm4 and parm5 are in R4 and R5 + */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5) + : "memory" + ); + + return reg0; +} + +/* SVC call with SYS_ call number and six parameters. + * + * NOTE the nonstandard parameter passing: parm4-parm6 are in R4-R6 + */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg6 __asm__("r6") = (long)(parm6); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6) + : "memory" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_SYSCALL_H */ + diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..5269ac6f6d0ff744fc28d6485e42a0677b52693f --- /dev/null +++ b/arch/arm/include/armv7-r/irq.h @@ -0,0 +1,421 @@ +/**************************************************************************** + * arch/arm/include/armv7-r/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ Stack Frame Format: + * + * Context is always saved/restored in the same way: + * + * (1) stmia rx, {r0-r14} + * (2) then the PC and CPSR + * + * This results in the following set of indices that can be used to access + * individual registers in the xcp.regs array: + */ + +#define REG_R0 (0) +#define REG_R1 (1) +#define REG_R2 (2) +#define REG_R3 (3) +#define REG_R4 (4) +#define REG_R5 (5) +#define REG_R6 (6) +#define REG_R7 (7) +#define REG_R8 (8) +#define REG_R9 (9) +#define REG_R10 (10) +#define REG_R11 (11) +#define REG_R12 (12) +#define REG_R13 (13) +#define REG_R14 (14) +#define REG_R15 (15) +#define REG_CPSR (16) + +#define ARM_CONTEXT_REGS (17) + +/* If the MCU supports a floating point unit, then it will be necessary + * to save the state of the FPU status register and data registers on + * each context switch. These registers are not saved during interrupt + * level processing, however. So, as a consequence, floating point + * operations may NOT be performed in interrupt handlers. + * + * The FPU provides an extension register file containing 32 single- + * precision registers. These can be viewed as: + * + * - Sixteen 64-bit double word registers, D0-D15 + * - Thirty-two 32-bit single-word registers, S0-S31 + * S<2n> maps to the least significant half of D + * S<2n+1> maps to the most significant half of D. + */ + +#ifdef CONFIG_ARCH_FPU +# define REG_D0 (ARM_CONTEXT_REGS+0) /* D0 */ +# define REG_S0 (ARM_CONTEXT_REGS+0) /* S0 */ +# define REG_S1 (ARM_CONTEXT_REGS+1) /* S1 */ +# define REG_D1 (ARM_CONTEXT_REGS+2) /* D1 */ +# define REG_S2 (ARM_CONTEXT_REGS+2) /* S2 */ +# define REG_S3 (ARM_CONTEXT_REGS+3) /* S3 */ +# define REG_D2 (ARM_CONTEXT_REGS+4) /* D2 */ +# define REG_S4 (ARM_CONTEXT_REGS+4) /* S4 */ +# define REG_S5 (ARM_CONTEXT_REGS+5) /* S5 */ +# define REG_D3 (ARM_CONTEXT_REGS+6) /* D3 */ +# define REG_S6 (ARM_CONTEXT_REGS+6) /* S6 */ +# define REG_S7 (ARM_CONTEXT_REGS+7) /* S7 */ +# define REG_D4 (ARM_CONTEXT_REGS+8) /* D4 */ +# define REG_S8 (ARM_CONTEXT_REGS+8) /* S8 */ +# define REG_S9 (ARM_CONTEXT_REGS+9) /* S9 */ +# define REG_D5 (ARM_CONTEXT_REGS+10) /* D5 */ +# define REG_S10 (ARM_CONTEXT_REGS+10) /* S10 */ +# define REG_S11 (ARM_CONTEXT_REGS+11) /* S11 */ +# define REG_D6 (ARM_CONTEXT_REGS+12) /* D6 */ +# define REG_S12 (ARM_CONTEXT_REGS+12) /* S12 */ +# define REG_S13 (ARM_CONTEXT_REGS+13) /* S13 */ +# define REG_D7 (ARM_CONTEXT_REGS+14) /* D7 */ +# define REG_S14 (ARM_CONTEXT_REGS+14) /* S14 */ +# define REG_S15 (ARM_CONTEXT_REGS+15) /* S15 */ +# define REG_D8 (ARM_CONTEXT_REGS+16) /* D8 */ +# define REG_S16 (ARM_CONTEXT_REGS+16) /* S16 */ +# define REG_S17 (ARM_CONTEXT_REGS+17) /* S17 */ +# define REG_D9 (ARM_CONTEXT_REGS+18) /* D9 */ +# define REG_S18 (ARM_CONTEXT_REGS+18) /* S18 */ +# define REG_S19 (ARM_CONTEXT_REGS+19) /* S19 */ +# define REG_D10 (ARM_CONTEXT_REGS+20) /* D10 */ +# define REG_S20 (ARM_CONTEXT_REGS+20) /* S20 */ +# define REG_S21 (ARM_CONTEXT_REGS+21) /* S21 */ +# define REG_D11 (ARM_CONTEXT_REGS+22) /* D11 */ +# define REG_S22 (ARM_CONTEXT_REGS+22) /* S22 */ +# define REG_S23 (ARM_CONTEXT_REGS+23) /* S23 */ +# define REG_D12 (ARM_CONTEXT_REGS+24) /* D12 */ +# define REG_S24 (ARM_CONTEXT_REGS+24) /* S24 */ +# define REG_S25 (ARM_CONTEXT_REGS+25) /* S25 */ +# define REG_D13 (ARM_CONTEXT_REGS+26) /* D13 */ +# define REG_S26 (ARM_CONTEXT_REGS+26) /* S26 */ +# define REG_S27 (ARM_CONTEXT_REGS+27) /* S27 */ +# define REG_D14 (ARM_CONTEXT_REGS+28) /* D14 */ +# define REG_S28 (ARM_CONTEXT_REGS+28) /* S28 */ +# define REG_S29 (ARM_CONTEXT_REGS+29) /* S29 */ +# define REG_D15 (ARM_CONTEXT_REGS+30) /* D15 */ +# define REG_S30 (ARM_CONTEXT_REGS+30) /* S30 */ +# define REG_S31 (ARM_CONTEXT_REGS+31) /* S31 */ +# define REG_FPSCR (ARM_CONTEXT_REGS+32) /* Floating point status and control */ +# define FPU_CONTEXT_REGS (33) +#else +# define FPU_CONTEXT_REGS (0) +#endif + +/* The total number of registers saved by software */ + +#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Friendly register names */ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ +#ifdef CONFIG_BUILD_KERNEL + uint32_t cpsr; /* The CPSR value */ +#endif + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* This struct defines the way the registers are stored. We need to save: + * + * 1 CPSR + * 7 Static registers, v1-v7 (aka r4-r10) + * 1 Frame pointer, fp (aka r11) + * 1 Stack pointer, sp (aka r13) + * 1 Return address, lr (aka r14) + * --- + * 11 (XCPTCONTEXT_USER_REG) + * + * On interrupts, we also need to save: + * 4 Volatile registers, a1-a4 (aka r0-r3) + * 1 Scratch Register, ip (aka r12) + *--- + * 5 (XCPTCONTEXT_IRQ_REGS) + * + * For a total of 17 (XCPTCONTEXT_REGS) + */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR and CPSR used during signal processing. */ + + uint32_t saved_pc; + uint32_t saved_cpsr; + +# ifdef CONFIG_BUILD_KERNEL + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; + +# endif +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; + + /* Extra fault address register saved for common paging logic. In the + * case of the pre-fetch abort, this value is the same as regs[REG_R15]; + * For the case of the data abort, this value is the value of the fault + * address register (FAR) at the time of data abort exception. + */ + +#ifdef CONFIG_PAGING + uintptr_t far; +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; +#endif + +#ifdef CONFIG_ARCH_ADDRENV +#ifdef CONFIG_ARCH_STACK_DYNAMIC + /* This array holds the physical address of the level 2 page table used + * to map the thread's stack memory. This array will be initially of + * zeroed and would be back-up up with pages during page fault exception + * handling to support dynamically sized stacks for each thread. + */ + + FAR uintptr_t *ustack[ARCH_STACK_NSECTS]; +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* In this configuration, all syscalls execute from an internal kernel + * stack. Why? Because when we instantiate and initialize the address + * environment of the new user process, we will temporarily lose the + * address environment of the old user process, including its stack + * contents. The kernel C logic will crash immediately with no valid + * stack in place. + */ + + FAR uint32_t *ustkptr; /* Saved user stack pointer */ + FAR uint32_t *kstack; /* Allocate base of the (aligned) kernel stack */ +#ifndef CONFIG_DISABLE_SIGNALS + FAR uint32_t *kstkptr; /* Saved kernel stack pointer */ +#endif +#endif +#endif +}; +#endif + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Return the current IRQ state */ + +static inline irqstate_t irqstate(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Disable IRQs and return the previous IRQ state */ + +static inline irqstate_t up_irq_save(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsid i\n" +#if defined(CONFIG_ARMV7A_DECODEFIQ) + "\tcpsid f\n" +#endif + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Enable IRQs and return the previous IRQ state */ + +static inline irqstate_t up_irq_enable(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsie i\n" +#if defined(CONFIG_ARMV7A_DECODEFIQ) + "\tcpsie f\n" +#endif + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Restore saved IRQ & FIQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + __asm__ __volatile__ + ( + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_R_IRQ_H */ diff --git a/arch/arm/include/armv7-r/syscall.h b/arch/arm/include/armv7-r/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..2c0cb7ca37d9dd162032379613cdc2e901724540 --- /dev/null +++ b/arch/arm/include/armv7-r/syscall.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/include/armv7-r/syscall.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV7_R_SYSCALL_H +#define __ARCH_ARM_INCLUDE_ARMV7_R_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x900001 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* SVC with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + register long reg0 __asm__("r0") = (long)(nbr); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5) + : "memory", "r14" + ); + + return reg0; +} + +/* SVC with SYS_ call number and six parameters */ + +static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6) +{ + register long reg0 __asm__("r0") = (long)(nbr); + register long reg6 __asm__("r6") = (long)(parm6); + register long reg5 __asm__("r5") = (long)(parm5); + register long reg4 __asm__("r4") = (long)(parm4); + register long reg3 __asm__("r3") = (long)(parm3); + register long reg2 __asm__("r2") = (long)(parm2); + register long reg1 __asm__("r1") = (long)(parm1); + + __asm__ __volatile__ + ( + "svc %1" + : "=r"(reg0) + : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), + "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6) + : "memory", "r14" + ); + + return reg0; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_ARMV7_R_SYSCALL_H */ diff --git a/arch/arm/include/c5471/irq.h b/arch/arm/include/c5471/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f2a79ef0b15f66640aed87a469778ececd1161b2 --- /dev/null +++ b/arch/arm/include/c5471/irq.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/arm/include/c5471/irq.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_C5471_IRQ_H +#define __ARCH_ARM_INCLUDE_C5471_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* C5471 Interrupts */ + +#define C5471_IRQ_TIMER0 0 +#define C5471_IRQ_TIMER1 1 +#define C5471_IRQ_TIMER2 2 +#define C5471_IRQ_GPIO0 3 +#define C5471_IRQ_ETHER 4 +#define C5471_IRQ_KBGPIO_0_7 5 +#define C5471_IRQ_UART 6 +#define C5471_IRQ_UART_IRDA 7 +#define C5471_IRQ_KBGPIO_8_15 8 +#define C5471_IRQ_GPIO3 9 +#define C5471_IRQ_GPIO2 10 +#define C5471_IRQ_I2C 11 +#define C5471_IRQ_GPIO1 12 +#define C5471_IRQ_SPI 13 +#define C5471_IRQ_GPIO_4_19 14 +#define C5471_IRQ_API 15 + +#define C5471_IRQ_WATCHDOG C5471_IRQ_TIMER0 +#define C5471_IRQ_SYSTIMER C5471_IRQ_TIMER2 +#define NR_IRQS (C5471_IRQ_API+1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_C5471_IRQ_H */ + diff --git a/arch/arm/include/calypso/armio.h b/arch/arm/include/calypso/armio.h new file mode 100644 index 0000000000000000000000000000000000000000..2f232beb22ade32761d28aed29498ff5ec51ac55 --- /dev/null +++ b/arch/arm/include/calypso/armio.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * Driver for Calypso ARMIO + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Prototypes for interrupt handling + ****************************************************************************/ + +inline int calypso_kbd_irq(int irq, uint32_t *regs); + +/**************************************************************************** + * Initialize device, add /dev/... nodes + ****************************************************************************/ + +void calypso_armio(void); diff --git a/arch/arm/include/calypso/clock.h b/arch/arm/include/calypso/clock.h new file mode 100644 index 0000000000000000000000000000000000000000..abcfde1d449d947a14904a36f100e5bfea0b95a8 --- /dev/null +++ b/arch/arm/include/calypso/clock.h @@ -0,0 +1,67 @@ +#ifndef _CALYPSO_CLK_H +#define _CALYPSO_CLK_H + +#include + +#define CALYPSO_PLL26_52_MHZ ((2 << 8) | 0) +#define CALYPSO_PLL26_86_7_MHZ ((10 << 8) | 2) +#define CALYPSO_PLL26_87_MHZ ((3 << 8) | 0) +#define CALYPSO_PLL13_104_MHZ ((8 << 8) | 0) + +enum mclk_div { + _ARM_MCLK_DIV_1 = 0, + ARM_MCLK_DIV_1 = 1, + ARM_MCLK_DIV_2 = 2, + ARM_MCLK_DIV_3 = 3, + ARM_MCLK_DIV_4 = 4, + ARM_MCLK_DIV_5 = 5, + ARM_MCLK_DIV_6 = 6, + ARM_MCLK_DIV_7 = 7, + ARM_MCLK_DIV_1_5 = 0x80 | 1, + ARM_MCLK_DIV_2_5 = 0x80 | 2, +}; + +void calypso_clock_set(uint8_t vtcxo_div2, uint16_t inp, enum mclk_div mclk_div); +void calypso_pll_set(uint16_t inp); +void calypso_clk_dump(void); + +/* CNTL_RST */ +enum calypso_rst { + RESET_DSP = (1 << 1), + RESET_EXT = (1 << 2), + RESET_WDOG = (1 << 3), +}; + +void calypso_reset_set(enum calypso_rst calypso_rst, int active); +int calypso_reset_get(enum calypso_rst); + +enum calypso_bank { + CALYPSO_nCS0 = 0, + CALYPSO_nCS1 = 2, + CALYPSO_nCS2 = 4, + CALYPSO_nCS3 = 6, + CALYPSO_nCS7 = 8, + CALYPSO_CS4 = 0xa, + CALYPSO_nCS6 = 0xc, +}; + +enum calypso_mem_width { + CALYPSO_MEM_8bit = 0, + CALYPSO_MEM_16bit = 1, + CALYPSO_MEM_32bit = 2, +}; + +void calypso_mem_cfg(enum calypso_bank bank, uint8_t ws, + enum calypso_mem_width width, int we); + +/* Enable or disable the internal bootrom mapped to 0x0000'0000 */ +void calypso_bootrom(int enable); + +/* Enable or disable the debug unit */ +void calypso_debugunit(int enable); + +/* configure the RHEA bus bridge[s] */ +void calypso_rhea_cfg(uint8_t fac0, uint8_t fac1, uint8_t timeout, + uint8_t ws_h, uint8_t ws_l, uint8_t w_en0, uint8_t w_en1); + +#endif /* _CALYPSO_CLK_H */ diff --git a/arch/arm/include/calypso/debug.h b/arch/arm/include/calypso/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..8c7b9aabfbdd132ae439b765f0d4318ec31c4144 --- /dev/null +++ b/arch/arm/include/calypso/debug.h @@ -0,0 +1,31 @@ +#ifndef _DEBUG_H +#define _DEBUG_H + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/* + * Check at compile time that something is of a particular type. + * Always evaluates to 1 so you may use it easily in comparisons. + */ +#define typecheck(type,x) \ +({ type __dummy; \ + typeof(x) __dummy2; \ + (void)(&__dummy == &__dummy2); \ + 1; \ +}) + +#ifdef DEBUG +#define dputchar(x) putchar(x) +#define dputs(x) puts(x) +#define dphex(x,y) phex(x,y) +#define printd(x, ...) printf(x, ##__VA_ARGS__) +#else +#define dputchar(x) +#define dputs(x) +#define dphex(x,y) +#define printd(x, args ...) +#endif + +#endif /* _DEBUG_H */ diff --git a/arch/arm/include/calypso/defines.h b/arch/arm/include/calypso/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..3c8732f92f8c086b825e70d7d51c980e41a79e40 --- /dev/null +++ b/arch/arm/include/calypso/defines.h @@ -0,0 +1,18 @@ + +#ifndef _DEFINES_H +#define _DEFINES_H + +#define __attribute_const__ __attribute__((__const__)) + +/* type properties */ +#define __packed __attribute__((packed)) +#define __aligned(alignment) __attribute__((aligned(alignment))) +#define __unused __attribute__((unused)) + +/* linkage */ +#define __section(name) __attribute__((section(name))) + +/* force placement in zero-waitstate memory */ +#define __ramtext __section(".ramtext") + +#endif /* !_DEFINES_H */ diff --git a/arch/arm/include/calypso/irq.h b/arch/arm/include/calypso/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..baea3de5a3f690f6b2a6411e6adfb12f03290325 --- /dev/null +++ b/arch/arm/include/calypso/irq.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arm/include/calypso/irq.h + * Driver for Calypso IRQ controller + * + * (C) 2010 by Harald Welte + * (C) 2011 by Stefan Richter + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_IRQ_H +#error "This file should never be included directly! Use " +#endif + +#ifndef _CALYPSO_IRQ_H +#define _CALYPSO_IRQ_H + +#ifndef __ASSEMBLY__ + +enum irq_nr { + IRQ_WATCHDOG = 0, + IRQ_TIMER1 = 1, + IRQ_TIMER2 = 2, + IRQ_TSP_RX = 3, + IRQ_TPU_FRAME = 4, + IRQ_TPU_PAGE = 5, + IRQ_SIMCARD = 6, + IRQ_UART_MODEM = 7, + IRQ_KEYPAD_GPIO = 8, + IRQ_RTC_TIMER = 9, + IRQ_RTC_ALARM_I2C = 10, + IRQ_ULPD_GAUGING = 11, + IRQ_EXTERNAL = 12, + IRQ_SPI = 13, + IRQ_DMA = 14, + IRQ_API = 15, + IRQ_SIM_DETECT = 16, + IRQ_EXTERNAL_FIQ = 17, + IRQ_UART_IRDA = 18, + IRQ_ULPD_GSM_TIMER = 19, + IRQ_GEA = 20, + _NR_IRQS +}; + +#endif /* __ASSEMBLY__ */ + +/* Don't use _NR_IRQS!!! Won't work in preprocessor... */ +#define NR_IRQS 21 + +#define IRQ_SYSTIMER IRQ_TIMER2 + +#endif /* _CALYPSO_IRQ_H */ diff --git a/arch/arm/include/calypso/memory.h b/arch/arm/include/calypso/memory.h new file mode 100644 index 0000000000000000000000000000000000000000..b0a0490cec1c3f8d44714ef9826fed115163be02 --- /dev/null +++ b/arch/arm/include/calypso/memory.h @@ -0,0 +1,28 @@ +#ifndef _MEMORY_H +#define _MEMORY_H + +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) + +#define writeb(v,a) __arch_putb(v,a) +#define writew(v,a) __arch_putw(v,a) +#define writel(v,a) __arch_putl(v,a) + +#define readb(a) __arch_getb(a) +#define readw(a) __arch_getw(a) +#define readl(a) __arch_getl(a) + +#endif /* _MEMORY_H */ diff --git a/arch/arm/include/calypso/timer.h b/arch/arm/include/calypso/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..694e4ebc92efb1d4031508354f4366f9079df243 --- /dev/null +++ b/arch/arm/include/calypso/timer.h @@ -0,0 +1,25 @@ +#ifndef _CAL_TIMER_H +#define _CAL_TIMER_H + +/* Enable or Disable a timer */ +void hwtimer_enable(int num, int on); + +/* Configure pre-scaler and if timer is auto-reload */ +void hwtimer_config(int num, uint8_t pre_scale, int auto_reload); + +/* Load a timer with the given value */ +void hwtimer_load(int num, uint16_t val); + +/* Read the current timer value */ +uint16_t hwtimer_read(int num); + +/* Enable or disable the watchdog */ +void wdog_enable(int on); + +/* Reset cpu using watchdog */ +void wdog_reset(void); + +/* power up the timers */ +void hwtimer_init(void); + +#endif /* _CAL_TIMER_H */ diff --git a/arch/arm/include/calypso/uwire.h b/arch/arm/include/calypso/uwire.h new file mode 100644 index 0000000000000000000000000000000000000000..19a277bccb5754cb938ce3593e8abe5492936068 --- /dev/null +++ b/arch/arm/include/calypso/uwire.h @@ -0,0 +1,6 @@ +#ifndef _CALYPSO_UWIRE_H +#define _CALYPSO_UWIRE_H +void uwire_init(void); +int uwire_xfer(int cs, int bitlen, const void *dout, void *din); +#endif + diff --git a/arch/arm/include/dm320/irq.h b/arch/arm/include/dm320/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..c48e58d1b7d364d3d5f44733e21e4b18916e31ac --- /dev/null +++ b/arch/arm/include/dm320/irq.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/include/dm320/irq.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_DM320_IRQ_H +#define __ARCH_ARM_INCLUDE_DM320_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* DM320 Interrupts */ + +#define DM320_IRQ_TMR0 0 /* IRQ0: Timer 0 Interrupt */ +#define DM320_IRQ_TMR1 1 /* IRQ1: Timer 1 Interrupt */ +#define DM320_IRQ_TMR2 2 /* IRQ2: Timer 2 Interrupt (CCD timer 0) */ +#define DM320_IRQ_TMR3 3 /* IRQ3: Timer 3 Interrupt (CCD timer 1) */ +#define DM320_IRQ_CCDVD0 4 /* IRQ4: CCD VD Interrupt #0 */ +#define DM320_IRQ_CCDVD1 5 /* IRQ5: CCD VD Interrupt #1 */ +#define DM320_IRQ_CCDWEN 6 /* IRQ6: CCD WEN Interrupt */ +#define DM320_IRQ_VENC 7 /* IRQ7: Video Encoder Interrupt */ +#define DM320_IRQ_SP0 8 /* IRQ8: Serial Port 0 Interrupt (with DMA) */ +#define DM320_IRQ_SP1 9 /* IRQ9: Serial Port 1 Interrupt */ +#define DM320_IRQ_EXTHOST 10 /* IRQ10: External host interrupt */ +#define DM320_IRQ_IMGBUF 11 /* IRQ11: Image Buffer */ +#define DM320_IRQ_UART0 12 /* IRQ12: UART0 Interrupt */ +#define DM320_IRQ_UART1 13 /* IRQ13: UART1 Interrupt */ +#define DM320_IRQ_USB0 14 /* IRQ14: USB 0 Interrupt (DMA) */ +#define DM320_IRQ_USB1 15 /* IRQ15: USB 1 Interrupt (Core) */ +#define DM320_IRQ_VLYNQ 16 /* IRQ16: VLYNQ Interrupt */ +#define DM320_IRQ_MTC0 17 /* IRQ17: Memory Traffic Controller 0 (DMA) */ +#define DM320_IRQ_MTC1 18 /* IRQ18: Memory Traffic Controller 1 (CFC_RDY) */ +#define DM320_IRQ_MMCSD0 19 /* IRQ19: MMC/SD or MS 0 Interrupt */ +#define DM320_IRQ_MMCSD1 20 /* IRQ20: MMC/SD or MS 1 Interrupt */ +#define DM320_IRQ_EXT0 21 /* IRQ21: External Interrupt #0 (GIO0) */ +#define DM320_IRQ_EXT1 22 /* IRQ22: External Interrupt #1 (GIO1) */ +#define DM320_IRQ_EXT2 23 /* IRQ23: External Interrupt #2 (GIO2) */ +#define DM320_IRQ_EXT3 24 /* IRQ24: External Interrupt #3 (GIO3) */ +#define DM320_IRQ_EXT4 25 /* IRQ25: External Interrupt #4 (GIO4) */ +#define DM320_IRQ_EXT5 26 /* IRQ26: External Interrupt #5 (GIO5) */ +#define DM320_IRQ_EXT6 27 /* IRQ27: External Interrupt #6 (GIO6) */ +#define DM320_IRQ_EXT7 28 /* IRQ28: External Interrupt #7 (GIO7) */ +#define DM320_IRQ_EXT8 29 /* IRQ29: External Interrupt #8 (GIO8) */ +#define DM320_IRQ_EXT9 30 /* IRQ30: External Interrupt #9 (GIO9) */ +#define DM320_IRQ_EXT10 31 /* IRQ31: External Interrupt #10 (GIO10) */ +#define DM320_IRQ_EXT11 32 /* IRQ32: External Interrupt #11 (GIO11) */ +#define DM320_IRQ_EXT12 33 /* IRQ33: External Interrupt #12 (GIO12) */ +#define DM320_IRQ_EXT13 34 /* IRQ34: External Interrupt #13 (GIO13) */ +#define DM320_IRQ_EXT14 35 /* IRQ35: External Interrupt #14 (GIO14) */ +#define DM320_IRQ_EXT15 36 /* IRQ36: External Interrupt #15 (GIO15) */ +#define DM320_IRQ_PREV0 37 /* IRQ37: Preview Engine 0 (Preview Over) */ +#define DM320_IRQ_PREV1 38 /* IRQ38: Preview Engine 1 (Preview Historgram Over) */ +#define DM320_IRQ_WDT 39 /* IRQ39: Watchdog Timer Interrupt */ +#define DM320_IRQ_I2C 40 /* IRQ40: I2C Interrupt */ +#define DM320_IRQ_CLKC 41 /* IRQ41: Clock controller Interrupt (wake up) */ +#define DM320_IRQ_E2ICE 42 /* IRQ42: Embedded ICE Interrupt */ +#define DM320_IRQ_ARMCOMRX 43 /* IRQ43: ARMCOMM Receive Interrupt */ +#define DM320_IRQ_ARMCOMTX 44 /* IRQ44: ARMCOMM Transmit Interrupt */ +#define DM320_IRQ_RSV 45 /* IRQ45: Reserved Interrupt */ + +#define DM320_IRQ_SYSTIMER DM320_IRQ_TMR0 +#define NR_IRQS (DM320_IRQ_RSV+1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_DM320_IRQ_H */ + diff --git a/arch/arm/include/efm32/chip.h b/arch/arm/include/efm32/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..2b73f7844fdc421f3890ebf7fd4b8c46e692b706 --- /dev/null +++ b/arch/arm/include/efm32/chip.h @@ -0,0 +1,129 @@ +/************************************************************************************ + * arch/arm/include/efm32/chip.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_EFM32_CHIP_H +#define __ARCH_ARM_INCLUDE_EFM32_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* EFM32 EnergyMicro ****************************************************************/ + +/* Tiny Gecko with 32KiB FLASH and 4KiB RAM in a QFN64 package */ + +#if defined(CONFIG_ARCH_CHIP_EFM32TG840F32) + +/* Gecko with 128KiB FLASH and 16KiB SRAM in LQFP100 (EFM32G880F128) or BGA112 + * (EFM32G890F128) package + */ + +#elif defined(CONFIG_ARCH_CHIP_EFM32G880F128) || \ + defined(CONFIG_ARCH_CHIP_EFM32G890F128) + +/* Giant Gecko with 1024KiB FLASH and 128KiB RAM in a QFP64 package + * (EFM32GG332F1024) or BGA112 (EFM32GG990F1024) package + */ + +#elif defined(CONFIG_ARCH_CHIP_EFM32GG332F1024) || \ + defined(CONFIG_ARCH_CHIP_EFM32GG990F1024) + +#else +# error "Unsupported EFM32 chip" +#endif + +/* NVIC priority levels *************************************************************/ + +#define NVIC_SYSH_PRIORITY_MIN 0xe0 /* Bits [7:5] set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Three bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_EFM32_CHIP_H */ diff --git a/arch/arm/include/efm32/efm32g_irq.h b/arch/arm/include/efm32/efm32g_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..fdd6062ba7bb231263cd7d8b97f47bde97c760c2 --- /dev/null +++ b/arch/arm/include/efm32/efm32g_irq.h @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/include/efm32s/efm32g_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_EFM32G_IRQ_H +#define __ARCH_ARM_INCLUDE_EFM32G_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in nuttx/arch/arm/include/efm32/irq.h + * + * External interrupts (vectors >= 16) + */ + /* IRQ# Source */ +#define EFM32_IRQ_DMA (EFM32_IRQ_INTERRUPTS+ 0) /* 0 DMA */ +#define EFM32_IRQ_GPIO_EVEN (EFM32_IRQ_INTERRUPTS+ 1) /* 1 GPIO_EVEN */ +#define EFM32_IRQ_TIMER0 (EFM32_IRQ_INTERRUPTS+ 2) /* 2 TIMER0 */ +#define EFM32_IRQ_USART0_RX (EFM32_IRQ_INTERRUPTS+ 3) /* 3 USART0_RX */ +#define EFM32_IRQ_USART0_TX (EFM32_IRQ_INTERRUPTS+ 4) /* 4 USART0_TX */ +#define EFM32_IRQ_ACMP (EFM32_IRQ_INTERRUPTS+ 5) /* 5 ACMP0/ACMP1 */ +#define EFM32_IRQ_ADC0 (EFM32_IRQ_INTERRUPTS+ 6) /* 6 ADC0 */ +#define EFM32_IRQ_DAC0 (EFM32_IRQ_INTERRUPTS+ 7) /* 7 DAC0 */ +#define EFM32_IRQ_I2C0 (EFM32_IRQ_INTERRUPTS+ 8) /* 8 I2C0 */ +#define EFM32_IRQ_GPIO_ODD (EFM32_IRQ_INTERRUPTS+ 9) /* 9 GPIO_ODD */ +#define EFM32_IRQ_TIMER1 (EFM32_IRQ_INTERRUPTS+10) /* 10 TIMER1 */ +#define EFM32_IRQ_TIMER2 (EFM32_IRQ_INTERRUPTS+11) /* 11 TIMER2 */ +#define EFM32_IRQ_USART1_RX (EFM32_IRQ_INTERRUPTS+12) /* 12 USART1_RX */ +#define EFM32_IRQ_USART1_TX (EFM32_IRQ_INTERRUPTS+13) /* 13 USART1_TX */ +#define EFM32_IRQ_USART2_RX (EFM32_IRQ_INTERRUPTS+14) /* 14 USART2_RX */ +#define EFM32_IRQ_USART2_TX (EFM32_IRQ_INTERRUPTS+15) /* 15 USART2_TX */ +#define EFM32_IRQ_UART0_RX (EFM32_IRQ_INTERRUPTS+16) /* 16 UART0_RX */ +#define EFM32_IRQ_UART0_TX (EFM32_IRQ_INTERRUPTS+17) /* 17 UART0_TX */ +#define EFM32_IRQ_LEUART0 (EFM32_IRQ_INTERRUPTS+18) /* 18 LEUART0 */ +#define EFM32_IRQ_LEUART1 (EFM32_IRQ_INTERRUPTS+19) /* 19 LEUART1 */ +#define EFM32_IRQ_LETIMER0 (EFM32_IRQ_INTERRUPTS+20) /* 20 LETIMER0 */ +#define EFM32_IRQ_PCNT0 (EFM32_IRQ_INTERRUPTS+21) /* 21 PCNT0 */ +#define EFM32_IRQ_PCNT1 (EFM32_IRQ_INTERRUPTS+22) /* 22 PCNT1 */ +#define EFM32_IRQ_PCNT2 (EFM32_IRQ_INTERRUPTS+23) /* 23 PCNT2 */ +#define EFM32_IRQ_RTC (EFM32_IRQ_INTERRUPTS+24) /* 24 RTC */ +#define EFM32_IRQ_CMU (EFM32_IRQ_INTERRUPTS+25) /* 25 CMU */ +#define EFM32_IRQ_VCMP (EFM32_IRQ_INTERRUPTS+26) /* 26 VCMP */ +#define EFM32_IRQ_LCD (EFM32_IRQ_INTERRUPTS+27) /* 27 LCD */ +#define EFM32_IRQ_MSC (EFM32_IRQ_INTERRUPTS+28) /* 28 MSC */ +#define EFM32_IRQ_AES (EFM32_IRQ_INTERRUPTS+29) /* 29 AES */ + +#define NR_VECTORS (EFM32_IRQ_INTERRUPTS+30) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_EFM32G_IRQ_H */ diff --git a/arch/arm/include/efm32/efm32gg_irq.h b/arch/arm/include/efm32/efm32gg_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ea501e7b1fa824ea15bcec18705179fd29df8378 --- /dev/null +++ b/arch/arm/include/efm32/efm32gg_irq.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/include/efm32s/efm32gg_irq.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_EFM32GG_IRQ_H +#define __ARCH_ARM_INCLUDE_EFM32GG_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in nuttx/arch/arm/include/efm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define EFM32_IRQ_DMA (EFM32_IRQ_INTERRUPTS+ 0) +#define EFM32_IRQ_GPIO_EVEN (EFM32_IRQ_INTERRUPTS+ 1) +#define EFM32_IRQ_TIMER0 (EFM32_IRQ_INTERRUPTS+ 2) +#define EFM32_IRQ_USART0_RX (EFM32_IRQ_INTERRUPTS+ 3) +#define EFM32_IRQ_USART0_TX (EFM32_IRQ_INTERRUPTS+ 4) +#define EFM32_IRQ_USB (EFM32_IRQ_INTERRUPTS+ 5) +#define EFM32_IRQ_ACMP (EFM32_IRQ_INTERRUPTS+ 6) +#define EFM32_IRQ_ADC0 (EFM32_IRQ_INTERRUPTS+ 7) +#define EFM32_IRQ_DAC0 (EFM32_IRQ_INTERRUPTS+ 8) +#define EFM32_IRQ_I2C0 (EFM32_IRQ_INTERRUPTS+ 9) +#define EFM32_IRQ_I2C1 (EFM32_IRQ_INTERRUPTS+10) +#define EFM32_IRQ_GPIO_ODD (EFM32_IRQ_INTERRUPTS+11) +#define EFM32_IRQ_TIMER1 (EFM32_IRQ_INTERRUPTS+12) +#define EFM32_IRQ_TIMER2 (EFM32_IRQ_INTERRUPTS+13) +#define EFM32_IRQ_TIMER3 (EFM32_IRQ_INTERRUPTS+14) +#define EFM32_IRQ_USART1_RX (EFM32_IRQ_INTERRUPTS+15) +#define EFM32_IRQ_USART1_TX (EFM32_IRQ_INTERRUPTS+16) +#define EFM32_IRQ_LESENSE (EFM32_IRQ_INTERRUPTS+17) +#define EFM32_IRQ_USART2_RX (EFM32_IRQ_INTERRUPTS+18) +#define EFM32_IRQ_USART2_TX (EFM32_IRQ_INTERRUPTS+19) +#define EFM32_IRQ_UART0_RX (EFM32_IRQ_INTERRUPTS+20) +#define EFM32_IRQ_UART0_TX (EFM32_IRQ_INTERRUPTS+21) +#define EFM32_IRQ_UART1_RX (EFM32_IRQ_INTERRUPTS+22) +#define EFM32_IRQ_UART1_TX (EFM32_IRQ_INTERRUPTS+23) +#define EFM32_IRQ_LEUART0 (EFM32_IRQ_INTERRUPTS+24) +#define EFM32_IRQ_LEUART1 (EFM32_IRQ_INTERRUPTS+25) +#define EFM32_IRQ_LETIMER0 (EFM32_IRQ_INTERRUPTS+26) +#define EFM32_IRQ_PCNT0 (EFM32_IRQ_INTERRUPTS+27) +#define EFM32_IRQ_PCNT1 (EFM32_IRQ_INTERRUPTS+28) +#define EFM32_IRQ_PCNT2 (EFM32_IRQ_INTERRUPTS+29) +#define EFM32_IRQ_RTC (EFM32_IRQ_INTERRUPTS+30) +#define EFM32_IRQ_BURTC (EFM32_IRQ_INTERRUPTS+31) +#define EFM32_IRQ_CMU (EFM32_IRQ_INTERRUPTS+32) +#define EFM32_IRQ_VCMP (EFM32_IRQ_INTERRUPTS+33) +#define EFM32_IRQ_LCD (EFM32_IRQ_INTERRUPTS+34) +#define EFM32_IRQ_MSC (EFM32_IRQ_INTERRUPTS+35) +#define EFM32_IRQ_AES (EFM32_IRQ_INTERRUPTS+36) +#define EFM32_IRQ_EBI (EFM32_IRQ_INTERRUPTS+37) +#define EFM32_IRQ_EMI (EFM32_IRQ_INTERRUPTS+38) + +#define NR_VECTORS (EFM32_IRQ_INTERRUPTS+39) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_EFM32GG_IRQ_H */ diff --git a/arch/arm/include/efm32/efm32tg_irq.h b/arch/arm/include/efm32/efm32tg_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..bbf64b108d5ea7f799be15db67ec593b6c9fc6ed --- /dev/null +++ b/arch/arm/include/efm32/efm32tg_irq.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/include/efm32s/efm32tg_irq.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_EFM32TG_IRQ_H +#define __ARCH_ARM_INCLUDE_EFM32TG_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in nuttx/arch/arm/include/efm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define EFM32_IRQ_DMA (EFM32_IRQ_INTERRUPTS+ 0) +#define EFM32_IRQ_GPIO_EVEN (EFM32_IRQ_INTERRUPTS+ 1) +#define EFM32_IRQ_TIMER0 (EFM32_IRQ_INTERRUPTS+ 2) +#define EFM32_IRQ_USART0_RX (EFM32_IRQ_INTERRUPTS+ 3) +#define EFM32_IRQ_USART0_TX (EFM32_IRQ_INTERRUPTS+ 4) +#define EFM32_IRQ_ACMP (EFM32_IRQ_INTERRUPTS+ 5) +#define EFM32_IRQ_ADC0 (EFM32_IRQ_INTERRUPTS+ 6) +#define EFM32_IRQ_DAC0 (EFM32_IRQ_INTERRUPTS+ 7) +#define EFM32_IRQ_I2C0 (EFM32_IRQ_INTERRUPTS+ 8) +#define EFM32_IRQ_GPIO_ODD (EFM32_IRQ_INTERRUPTS+ 9) +#define EFM32_IRQ_TIMER1 (EFM32_IRQ_INTERRUPTS+10) +#define EFM32_IRQ_USART1_RX (EFM32_IRQ_INTERRUPTS+11) +#define EFM32_IRQ_USART1_TX (EFM32_IRQ_INTERRUPTS+12) +#define EFM32_IRQ_LESENSE (EFM32_IRQ_INTERRUPTS+13) +#define EFM32_IRQ_LEUART0 (EFM32_IRQ_INTERRUPTS+14) +#define EFM32_IRQ_LETIMER0 (EFM32_IRQ_INTERRUPTS+15) +#define EFM32_IRQ_PCNT0 (EFM32_IRQ_INTERRUPTS+16) +#define EFM32_IRQ_RTC (EFM32_IRQ_INTERRUPTS+17) +#define EFM32_IRQ_CMU (EFM32_IRQ_INTERRUPTS+18) +#define EFM32_IRQ_VCMP (EFM32_IRQ_INTERRUPTS+19) +#define EFM32_IRQ_LCD (EFM32_IRQ_INTERRUPTS+20) +#define EFM32_IRQ_MSC (EFM32_IRQ_INTERRUPTS+21) +#define EFM32_IRQ_AES (EFM32_IRQ_INTERRUPTS+22) + +#define NR_VECTORS (EFM32_IRQ_INTERRUPTS+23) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_EFM32TG_IRQ_H */ diff --git a/arch/arm/include/efm32/irq.h b/arch/arm/include/efm32/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..7bd0449d621d225ad6408ea8d6422c28f71e4781 --- /dev/null +++ b/arch/arm/include/efm32/irq.h @@ -0,0 +1,147 @@ +/************************************************************************************ + * arch/arm/include/efm32s/irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_EFM32_IRQ_H +#define __ARCH_ARM_INCLUDE_EFM32_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define EFM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define EFM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define EFM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define EFM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define EFM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define EFM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define EFM32_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define EFM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define EFM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define EFM32_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define EFM32_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_EFM32_EFM32TG) +# include +#elif defined(CONFIG_EFM32_EFM32G) +# include +#elif defined(CONFIG_EFM32_EFM32GG) +# include +#else +# error "Unsupported EFM32 chip" +#endif + +#ifdef CONFIG_EFM32_GPIO_IRQ +/* If GPIO interrupt support is enabled then up to 16 additional GPIO interrupt + * sources are available. There are actually only two physical interrupt lines: + * GPIO_EVEN and GPIO_ODD. However, from the software point of view, there are + * 16-additional interrupts generated from a second level of decoding. + */ + +# define EFM32_IRQ_EXTI0 (NR_VECTORS+0) /* Port[n], pin0 external interrupt */ +# define EFM32_IRQ_EXTI1 (NR_VECTORS+1) /* Port[n], pin1 external interrupt */ +# define EFM32_IRQ_EXTI2 (NR_VECTORS+2) /* Port[n], pin2 external interrupt */ +# define EFM32_IRQ_EXTI3 (NR_VECTORS+3) /* Port[n], pin3 external interrupt */ +# define EFM32_IRQ_EXTI4 (NR_VECTORS+4) /* Port[n], pin4 external interrupt */ +# define EFM32_IRQ_EXTI5 (NR_VECTORS+5) /* Port[n], pin5 external interrupt */ +# define EFM32_IRQ_EXTI6 (NR_VECTORS+6) /* Port[n], pin6 external interrupt */ +# define EFM32_IRQ_EXTI7 (NR_VECTORS+7) /* Port[n], pin7 external interrupt */ +# define EFM32_IRQ_EXTI8 (NR_VECTORS+8) /* Port[n], pin8 external interrupt */ +# define EFM32_IRQ_EXTI9 (NR_VECTORS+9) /* Port[n], pin9 external interrupt */ +# define EFM32_IRQ_EXTI10 (NR_VECTORS+10) /* Port[n], pin10 external interrupt */ +# define EFM32_IRQ_EXTI11 (NR_VECTORS+11) /* Port[n], pin11 external interrupt */ +# define EFM32_IRQ_EXTI12 (NR_VECTORS+12) /* Port[n], pin12 external interrupt */ +# define EFM32_IRQ_EXTI13 (NR_VECTORS+13) /* Port[n], pin13 external interrupt */ +# define EFM32_IRQ_EXTI14 (NR_VECTORS+14) /* Port[n], pin14 external interrupt */ +# define EFM32_IRQ_EXTI15 (NR_VECTORS+15) /* Port[n], pin15 external interrupt */ + +# define NR_IRQS (NR_VECTORS+16) /* Total number of interrupts */ +#else +# define NR_IRQS NR_VECTORS /* Total number of interrupts */ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_EFM32_IRQ_H */ diff --git a/arch/arm/include/elf.h b/arch/arm/include/elf.h new file mode 100644 index 0000000000000000000000000000000000000000..9928a85a766fa4112ab9eadc757c90e4b386148c --- /dev/null +++ b/arch/arm/include/elf.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/include/syscall.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "ELF for the ARM® Architecture," ARM IHI 0044D, current through + * ABI release 2.08, October 28, 2009, ARM Limited. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_ELF_H +#define __ARCH_ARM_INCLUDE_ELF_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 4.3.1 ELF Identification. Should have: + * + * e_machine = EM_ARM + * e_ident[EI_CLASS] = ELFCLASS32 + * e_ident[EI_DATA] = ELFDATA2LSB (little endian) or ELFDATA2MSB (big endian) + */ + +#if 0 /* Defined in include/elf32.h */ +#define EM_ARM 40 +#endif + +/* Table 4-2, ARM-specific e_flags */ + +#define EF_ARM_EABI_MASK 0xff000000 +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 + +#define EF_ARM_BE8 0x00800000 + +/* Table 4-4, Processor specific section types */ + +#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table */ +#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map */ +#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes */ +#define SHT_ARM_DEBUGOVERLAY 0x70000004 +#define SHT_ARM_OVERLAYSECTION 0x70000005 + +/* 4.7.1 Relocation codes + * + * S (when used on its own) is the address of the symbol. + * A is the addend for the relocation. + * P is the address of the place being relocated (derived from r_offset). + * Pa is the adjusted address of the place being relocated, defined as (P & 0xFFFFFFFC). + * T is 1 if the target symbol S has type STT_FUNC and the symbol addresses a Thumb instruction; + * it is 0 otherwise. + * B(S) is the addressing origin of the output segment defining the symbol S. + * GOT_ORG is the addressing origin of the Global Offset Table + * GOT(S) is the address of the GOT entry for the symbol S. + */ + +#define R_ARM_NONE 0 /* No relocation */ +#define R_ARM_PC24 1 /* ARM ((S + A) | T) - P */ +#define R_ARM_ABS32 2 /* Data (S + A) | T */ +#define R_ARM_REL32 3 /* Data ((S + A) | T) - P */ +#define R_ARM_LDR_PC_G0 4 /* ARM S + A - P */ +#define R_ARM_ABS16 5 /* Data S + A */ +#define R_ARM_ABS12 6 /* ARM S + A */ +#define R_ARM_THM_ABS5 7 /* Thumb16 S + A */ +#define R_ARM_ABS8 8 /* Data S + A */ +#define R_ARM_SBREL32 9 /* Data ((S + A) | T) - B(S) */ +#define R_ARM_THM_CALL 10 /* Thumb32 ((S + A) | T) - P */ +#define R_ARM_THM_PC8 11 /* Thumb16 S + A - Pa */ +#define R_ARM_BREL_ADJ 12 /* Data ?B(S) + A */ +#define R_ARM_TLS_DESC 13 /* Data */ +#define R_ARM_THM_SWI8 14 /* Obsolete */ +#define R_ARM_XPC25 15 /* Obsolete */ +#define R_ARM_THM_XPC22 16 /* Obsolete */ +#define R_ARM_TLS_DTPMOD32 17 /* Data Module[S] */ +#define R_ARM_TLS_DTPOFF32 18 /* Data S + A - TLS */ +#define R_ARM_TLS_TPOFF32 19 /* Data S + A - tp */ +#define R_ARM_COPY 20 /* Miscellaneous */ +#define R_ARM_GLOB_DAT 21 /* Data (S + A) | T */ +#define R_ARM_JUMP_SLOT 22 /* Data (S + A) | T */ +#define R_ARM_RELATIVE 23 /* Data B(S) + A */ +#define R_ARM_GOTOFF32 24 /* Data ((S + A) | T) - GOT_ORG */ +#define R_ARM_BASE_PREL 25 /* Data B(S) + A - P */ +#define R_ARM_GOT_BREL 26 /* Data GOT(S) + A - GOT_ORG */ +#define R_ARM_PLT32 27 /* ARM ((S + A) | T) - P */ +#define R_ARM_CALL 28 /* ARM ((S + A) | T) - P */ +#define R_ARM_JUMP24 29 /* ARM ((S + A) | T) - P */ +#define R_ARM_THM_JUMP24 30 /* Thumb32 ((S + A) | T) - P */ +#define R_ARM_BASE_ABS 31 /* Data B(S) + A */ +#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete */ +#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete */ +#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete */ +#define R_ARM_LDR_SBREL_11_0_NC 35 /* ARM S + A - B(S) */ +#define R_ARM_ALU_SBREL_19_12_NC 36 /* ARM S + A - B(S) */ +#define R_ARM_ALU_SBREL_27_20_CK 37 /* ARM S + A - B(S) */ +#define R_ARM_TARGET1 38 /* Miscellaneous (S + A) | T or ((S + A) | T) - P */ +#define R_ARM_SBREL31 39 /* Data ((S + A) | T) - B(S) */ +#define R_ARM_V4BX 40 /* Miscellaneous */ +#define R_ARM_TARGET2 41 /* Miscellaneous */ +#define R_ARM_PREL31 42 /* Data ((S + A) | T) - P */ +#define R_ARM_MOVW_ABS_NC 43 /* ARM (S + A) | T */ +#define R_ARM_MOVT_ABS 44 /* ARM S + A */ +#define R_ARM_MOVW_PREL_NC 45 /* ARM ((S + A) | T) - P */ +#define R_ARM_MOVT_PREL 46 /* ARM S + A - P */ +#define R_ARM_THM_MOVW_ABS_NC 47 /* Thumb32 (S + A) | T */ +#define R_ARM_THM_MOVT_ABS 48 /* Thumb32 S + A */ +#define R_ARM_THM_MOVW_PREL_NC 49 /* Thumb32 ((S + A) | T) - P */ +#define R_ARM_THM_MOVT_PREL 50 /* Thumb32 S + A - P */ +#define R_ARM_THM_JUMP19 51 /* Thumb32 ((S + A) | T) - P */ +#define R_ARM_THM_JUMP6 52 /* Thumb16 S + A - P */ +#define R_ARM_THM_ALU_PREL_11_0 53 /* Thumb32 ((S + A) | T) - Pa */ +#define R_ARM_THM_PC12 54 /* Thumb32 S + A - Pa */ +#define R_ARM_ABS32_NOI 55 /* Data S + A */ +#define R_ARM_REL32_NOI 56 /* Data S + A - P */ +#define R_ARM_ALU_PC_G0_NC 57 /* ARM ((S + A) | T) - P */ +#define R_ARM_ALU_PC_G0 58 /* ARM ((S + A) | T) - P */ +#define R_ARM_ALU_PC_G1_NC 59 /* ARM ((S + A) | T) - P */ +#define R_ARM_ALU_PC_G1 60 /* ARM ((S + A) | T) - P */ +#define R_ARM_ALU_PC_G2 61 /* ARM ((S + A) | T) - P */ +#define R_ARM_LDR_PC_G1 62 /* ARM S + A - P */ +#define R_ARM_LDR_PC_G2 63 /* ARM S + A - P */ +#define R_ARM_LDRS_PC_G0 64 /* ARM S + A - P */ +#define R_ARM_LDRS_PC_G1 65 /* ARM S + A - P */ +#define R_ARM_LDRS_PC_G2 66 /* ARM S + A - P */ +#define R_ARM_LDC_PC_G0 67 /* ARM S + A - P */ +#define R_ARM_LDC_PC_G1 68 /* ARM S + A - P */ +#define R_ARM_LDC_PC_G2 69 /* ARM S + A - P */ +#define R_ARM_ALU_SB_G0_NC 70 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_ALU_SB_G0 71 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_ALU_SB_G1_NC 72 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_ALU_SB_G1 73 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_ALU_SB_G2 74 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_LDR_SB_G0 75 /* ARM S + A - B(S) */ +#define R_ARM_LDR_SB_G1 76 /* ARM S + A - B(S) */ +#define R_ARM_LDR_SB_G2 77 /* ARM S + A - B(S) */ +#define R_ARM_LDRS_SB_G0 78 /* ARM S + A - B(S) */ +#define R_ARM_LDRS_SB_G1 79 /* ARM S + A - B(S) */ +#define R_ARM_LDRS_SB_G2 80 /* ARM S + A - B(S) */ +#define R_ARM_LDC_SB_G0 81 /* ARM S + A - B(S) */ +#define R_ARM_LDC_SB_G1 82 /* ARM S + A - B(S) */ +#define R_ARM_LDC_SB_G2 83 /* ARM S + A - B(S) */ +#define R_ARM_MOVW_BREL_NC 84 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_MOVT_BREL 85 /* ARM S + A - B(S) */ +#define R_ARM_MOVW_BREL 86 /* ARM ((S + A) | T) - B(S) */ +#define R_ARM_THM_MOVW_BREL_NC 87 /* Thumb32 ((S + A) | T) - B(S) */ +#define R_ARM_THM_MOVT_BREL 88 /* Thumb32 S + A - B(S) */ +#define R_ARM_THM_MOVW_BREL 89 /* Thumb32 ((S + A) | T) - B(S) */ +#define R_ARM_TLS_GOTDESC 90 /* Data */ +#define R_ARM_TLS_CALL 91 /* ARM */ +#define R_ARM_TLS_DESCSEQ 92 /* ARM TLS relaxation */ +#define R_ARM_THM_TLS_CALL 93 /* Thumb32 */ +#define R_ARM_PLT32_ABS 94 /* Data PLT(S) + A */ +#define R_ARM_GOT_ABS 95 /* Data GOT(S) + A */ +#define R_ARM_GOT_PREL 96 /* Data GOT(S) + A - P */ +#define R_ARM_GOT_BREL12 97 /* ARM GOT(S) + A - GOT_ORG */ +#define R_ARM_GOTOFF12 98 /* ARM S + A - GOT_ORG */ +#define R_ARM_GOTRELAX 99 /* Miscellaneous */ +#define R_ARM_GNU_VTENTRY 100 /* Data */ +#define R_ARM_GNU_VTINHERIT 101 /* Data */ +#define R_ARM_THM_JUMP11 102 /* Thumb16 S + A - P */ +#define R_ARM_THM_JUMP8 103 /* Thumb16 S + A - P */ +#define R_ARM_TLS_GD32 104 /* Data GOT(S) + A - P */ +#define R_ARM_TLS_LDM32 105 /* Data GOT(S) + A - P */ +#define R_ARM_TLS_LDO32 106 /* Data S + A - TLS */ +#define R_ARM_TLS_IE32 107 /* Data GOT(S) + A - P */ +#define R_ARM_TLS_LE32 108 /* Data S + A - tp */ +#define R_ARM_TLS_LDO12 109 /* ARM S + A - TLS */ +#define R_ARM_TLS_LE12 110 /* ARM S + A - tp */ +#define R_ARM_TLS_IE12GP 111 /* ARM GOT(S) + A - GOT_ORG */ +#define R_ARM_ME_TOO 128 /* Obsolete */ +#define R_ARM_THM_TLS_DESCSEQ16 129 /* Thumb16 */ +#define R_ARM_THM_TLS_DESCSEQ32 130 /* Thumb32 */ + +/* 5.2.1 Platform architecture compatibility data */ + +#define PT_ARM_ARCHEXT_FMTMSK 0xff000000 +#define PT_ARM_ARCHEXT_PROFMSK 0x00ff0000 +#define PT_ARM_ARCHEXT_ARCHMSK 0x000000ff + +#define PT_ARM_ARCHEXT_FMT_OS 0x00000000 +#define PT_ARM_ARCHEXT_FMT_ABI 0x01000000 + +#define PT_ARM_ARCHEXT_PROF_NONE 0x00000000 +#define PT_ARM_ARCHEXT_PROF_ARM 0x00410000 +#define PT_ARM_ARCHEXT_PROF_RT 0x00520000 +#define PT_ARM_ARCHEXT_PROF_MC 0x004d0000 +#define PT_ARM_ARCHEXT_PROF_CLASSIC 0x00530000 + +#define PT_ARM_ARCHEXT_ARCH_UNKNOWN 0x00 +#define PT_ARM_ARCHEXT_ARCHv4 0x01 +#define PT_ARM_ARCHEXT_ARCHv4T 0x02 +#define PT_ARM_ARCHEXT_ARCHv5T 0x03 +#define PT_ARM_ARCHEXT_ARCHv5TE 0x04 +#define PT_ARM_ARCHEXT_ARCHv5TEJ 0x05 +#define PT_ARM_ARCHEXT_ARCHv6 0x06 +#define PT_ARM_ARCHEXT_ARCHv6KZ 0x07 +#define PT_ARM_ARCHEXT_ARCHv6T2 0x08 +#define PT_ARM_ARCHEXT_ARCHv6K 0x09 +#define PT_ARM_ARCHEXT_ARCHv7 0x0a +#define PT_ARM_ARCHEXT_ARCHv6M 0x0b +#define PT_ARM_ARCHEXT_ARCHv6SM 0x0c +#define PT_ARM_ARCHEXT_ARCHv7EM 0x0d + +/* Table 5-6, ARM-specific dynamic array tags */ + +#define DT_ARM_RESERVED1 0x70000000 +#define DT_ARM_SYMTABSZ 0x70000001 +#define DT_ARM_PREEMPTMAP 0x70000002 +#define DT_ARM_RESERVED2 0x70000003 + +#endif /* __ARCH_ARM_INCLUDE_ELF_H */ diff --git a/arch/arm/include/imx1/irq.h b/arch/arm/include/imx1/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..cb158c79f4eb6adc82064f635ef5984c3d84c588 --- /dev/null +++ b/arch/arm/include/imx1/irq.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/arm/include/imx1/irq.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_IMX1_IRQ_H +#define __ARCH_ARM_INCLUDE_IMX1_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* i.MX1 Interrupts */ + +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_UART3PFERR ( 0) +# define IMX_IRQ_UART3RTS ( 1) +# define IMX_IRQ_UART3DTR ( 2) +# define IMX_IRQ_UART3UARTC ( 3) +# define IMX_IRQ_UART3TX ( 4) +# define IMX_IRQ_PENUP ( 5) +#endif +#define IMX_IRQ_CSI ( 6) +#define IMX_IRQ_MMAMAC ( 7) +#define IMX_IRQ_MMA ( 8) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_COMP ( 9) +#endif +#define IMX_IRQ_MSHCXINT (10) +#define IMX_IRQ_GPIOPORTA (11) +#define IMX_IRQ_GPIOPORTB (12) +#define IMX_IRQ_GPIOPORTC (13) +#define IMX_IRQ_LCDC (14) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_SIM (15) +# define IMX_IRQ_SIMDATA (16) +#endif +#define IMX_IRQ_RTC (17) +#define IMX_IRQ_RTCSAMINT (18) +#define IMX_IRQ_UART2PFERR (19) +#define IMX_IRQ_UART2RTS (20) +#define IMX_IRQ_UART2DTR (21) +#define IMX_IRQ_UART2UARTC (22) +#define IMX_IRQ_UART2TX (23) +#define IMX_IRQ_UART2RX (24) +#define IMX_IRQ_UART1PFERR (25) +#define IMX_IRQ_UART1RTS (26) +#define IMX_IRQ_UART1DTR (27) +#define IMX_IRQ_UART1UARTC (28) +#define IMX_IRQ_UART1TX (29) +#define IMX_IRQ_UART1RX (30) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_PENDATA (33) +#endif +#define IMX_IRQ_PWM (34) +#define IMX_IRQ_MMCSD (35) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_SSI2TX (36) +# define IMX_IRQ_SSI2RX (37) +# define IMX_IRQ_SSI2ERR (38) +#endif +#define IMX_IRQ_I2C (39) +#define IMX_IRQ_CSPI2 (40) +#define IMX_IRQ_CSPI1 (41) +#define IMX_IRQ_SSITX (42) +#define IMX_IRQ_SSITXERR (43) +#define IMX_IRQ_SSIRX (44) +#define IMX_IRQ_SSIRXERR (45) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_TOUCH (46) +#endif +#define IMX_IRQ_USBD0 (47) +#define IMX_IRQ_USBD1 (48) +#define IMX_IRQ_USBD2 (49) +#define IMX_IRQ_USBD3 (50) +#define IMX_IRQ_USBD4 (51) +#define IMX_IRQ_USBD5 (52) +#define IMX_IRQ_USBD6 (53) +#ifndef CONFIG_ARCH_CHIP_IMXL +# define IMX_IRQ_UART3RX (54) +# define IMX_IRQ_BTSYS (55) +# define IMX_IRQ_BTTIM (56) +# define IMX_IRQ_BTWUI (57) +#endif +#define IMX_IRQ_TIMER2 (58) +#define IMX_IRQ_TIMER1 (59) +#define IMX_IRQ_DMAERR (60) +#define IMX_IRQ_DMA (61) +#define IMX_IRQ_GPIOPORTD (62) +#define IMX_IRQ_WDT (63) + +#define IMX_IRQ_SYSTIMER IMX_IRQ_TIMER1 +#define NR_IRQS (64) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_IMX1_IRQ_H */ + diff --git a/arch/arm/include/imx6/chip.h b/arch/arm/include/imx6/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..1c595c99a04b14a14cf5c3d3f02b9e701929d569 --- /dev/null +++ b/arch/arm/include/imx6/chip.h @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/arm/include/imx6/chip.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_IMX6_CHIP_H +#define __ARCH_ARM_INCLUDE_IMX6_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The i.MX6 6Quad and 6Dual/DualLite are the only support i.MX6 family + * members. Individual differences between members of the families are not + * accounted for. + */ + +#if defined(CONFIG_ARCH_CHIP_IMX6_6QUAD) +# define IMX_OCRAM_SIZE (256*1024) /* Size of the On-Chip RAM (OCRAM) */ +# define IMX_L2CACHE_SIZE (1024*1024) /* 1MB L2 Cache */ +# define IMX_NXCPUS 4 /* Four CPUs */ +# define IMX_NGPU3D 1 /* One 3D graphics engine */ +# define IMX_N32SHADERS 4 /* Four 3D shaders */ +# define IMX_NGPU2D 2 /* Two 2D graphics engines */ +# define IMX_HAVE_DDR64 1 /* 64-bit DDR3 */ +# undef IMX_HAVE_DDR32 /* 32-bit DDR3 */ +# define IMX_HAVE_DDR32x2 1 /* Two channel 32-bit DDR3 */ +# define IMX_HAVE_SATAII 1 /* Integrated SATA-II */ +# undef IMX_HAVE_EPD /* No interated EPD controller */ +#elif defined(CONFIG_ARCH_CHIP_IMX6_6DUAL) +# define IMX_OCRAM_SIZE (256*1024) /* Size of the On-Chip RAM (OCRAM) */ +# define IMX_L2CACHE_SIZE (1024*1024) /* 1MB L2 Cache */ +# define IMX_NXCPUS 2 /* Two CPUs */ +# define IMX_NGPU3D 1 /* One 3D graphics engine */ +# define IMX_N32SHADERS 4 /* Four 3D shaders */ +# define IMX_NGPU2D 2 /* Two 2D graphics engines */ +# define IMX_HAVE_DDR64 1 /* 64-bit DDR3 */ +# undef IMX_HAVE_DDR32 /* 32-bit DDR3 */ +# define IMX_HAVE_DDR32x2 1 /* Two channel 32-bit DDR3 */ +# define IMX_HAVE_SATAII 1 /* Integrated SATA-II */ +# undef IMX_HAVE_EPD /* No interated EPD controller */ +#elif defined(CONFIG_ARCH_CHIP_IMX6_6DUALLITE) +# define IMX_OCRAM_SIZE (256*1024) /* Size of the On-Chip RAM (OCRAM) */ +# define IMX_L2CACHE_SIZE (512*1024) /* 512KB L2 Cache */ +# define IMX_NXCPUS 2 /* Two CPUs */ +# define IMX_NGPU3D 1 /* One 3D graphics engine */ +# define IMX_N32SHADERS 1 /* One 3D shaders */ +# define IMX_NGPU2D 1 /* One 2D graphics engine */ +# define IMX_HAVE_DDR64 1 /* 64-bit DDR3 */ +# undef IMX_HAVE_DDR32 /* No 32-bit DDR3 */ +# define IMX_HAVE_DDR32x2 1 /* Two channel 32-bit DDR3 */ +# undef IMX_HAVE_SATAII /* No integrated SATA-II */ +# define IMX_HAVE_EPD 1 /* Interated EPD controller */ +#elif defined(CONFIG_ARCH_CHIP_IMX6_6SOLO) +# define IMX_OCRAM_SIZE (256*1024) /* Size of the On-Chip RAM (OCRAM) */ +# define IMX_L2CACHE_SIZE (512*1024) /* 512KB L2 Cache */ +# define IMX_NXCPUS 1 /* One CPU */ +# define IMX_NGPU3D 1 /* One 3D graphics engine */ +# define IMX_N32SHADERS 1 /* One 3D shaders */ +# define IMX_NGPU2D 1 /* One 2D graphics engine */ +# undef IMX_HAVE_DDR64 /* No 64-bit DDR3 */ +# define IMX_HAVE_DDR32 1 /* 32-bit DDR3 */ +# undef IMX_HAVE_DDR32x2 /* No two channel 32-bit DDR3 */ +# undef IMX_HAVE_SATAII /* No integrated SATA-II */ +# define IMX_HAVE_EPD 1 /* Interated EPD controller */ +#elif defined(CONFIG_ARCH_CHIP_IMX6_6SOLOLITE) +# define IMX_OCRAM_SIZE (256*1024) /* Size of the On-Chip RAM (OCRAM) */ +# define IMX_L2CACHE_SIZE (256*1024) /* 256KB L2 Cache */ +# define IMX_NXCPUS 1 /* One CPU */ +# undef IMX_NGPU3D /* No 3D graphics engine */ +# define IMX_N32SHADERS 0 /* No 3D shaders */ +# define IMX_NGPU2D 1 /* One 2D graphics engine */ +# undef IMX_HAVE_DDR64 /* No 64-bit DDR3 */ +# define IMX_HAVE_DDR32 1 /* 32-bit DDR3 */ +# undef IMX_HAVE_DDR32x2 /* No two channel 32-bit DDR3 */ +# undef IMX_HAVE_SATAII /* No integrated SATA-II */ +# define IMX_HAVE_EPD 1 /* Interated EPD controller */ +#else +# error Unspecified i.MX6 chip +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_IMX6_CHIP_H */ diff --git a/arch/arm/include/imx6/irq.h b/arch/arm/include/imx6/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..a99d4e6901918827e8cb6435cb73155a2fcf45b4 --- /dev/null +++ b/arch/arm/include/imx6/irq.h @@ -0,0 +1,261 @@ +/**************************************************************************** + * arch/arm/include/imx6/irq.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + & through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_IMX6_IRQ_H +#define __ARCH_ARM_INCLUDE_IMX6_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The Global Interrupt Controller (GIC) collects up to 128 interrupt + * requests from all i.MX 6Dual/6Quad sources and provides an interface to + * each of the CPU cores. + * + * The first 32 interrupts are used for interrupts that are private to the + * CPUs interface. interrupts besides the private CPU are also hooked up to + * the GIC in the same order. + * + * Each interrupt can be configured as a normal or a secure interrupt. + * Software force registers and software priority masking are also + * supported. The following table describes the ARM interrupt sources. + */ + +/* Private Peripheral Interrupts (PPI) **************************************/ +/* Each Cortex-A9 processor has private interrupts, ID0-ID15, that can only + * be triggered by software. These interrupts are aliased so that there is + * no requirement for a requesting Cortex-A9 processor to determine its own + * CPU ID when it deals with SGIs. The priority of an SGI depends on the + * value set by the receiving Cortex-A9 processor in the banked SGI priority + * registers, not the priority set by the sending Cortex-A9 processor. + */ + +#define IMX_IRQ_SGI0 0 /* Sofware Generated Interrupt (SGI) 0 */ +#define IMX_IRQ_SGI1 1 /* Sofware Generated Interrupt (SGI) 1 */ +#define IMX_IRQ_SGI2 2 /* Sofware Generated Interrupt (SGI) 2 */ +#define IMX_IRQ_SGI3 3 /* Sofware Generated Interrupt (SGI) 3 */ +#define IMX_IRQ_SGI4 4 /* Sofware Generated Interrupt (SGI) 4 */ +#define IMX_IRQ_SGI5 5 /* Sofware Generated Interrupt (SGI) 5 */ +#define IMX_IRQ_SGI6 6 /* Sofware Generated Interrupt (SGI) 6 */ +#define IMX_IRQ_SGI7 7 /* Sofware Generated Interrupt (SGI) 7 */ +#define IMX_IRQ_SGI8 8 /* Sofware Generated Interrupt (SGI) 8 */ +#define IMX_IRQ_SGI9 9 /* Sofware Generated Interrupt (SGI) 9 */ +#define IMX_IRQ_SGI10 10 /* Sofware Generated Interrupt (SGI) 10 */ +#define IMX_IRQ_SGI11 11 /* Sofware Generated Interrupt (SGI) 11 */ +#define IMX_IRQ_SGI12 12 /* Sofware Generated Interrupt (SGI) 12 */ +#define IMX_IRQ_SGI13 13 /* Sofware Generated Interrupt (SGI) 13 */ +#define IMX_IRQ_SGI14 14 /* Sofware Generated Interrupt (SGI) 14 */ +#define IMX_IRQ_SGI15 15 /* Sofware Generated Interrupt (SGI) 15 */ + +#define IMX_IRQ_GTM 27 /* Global Timer (GTM) PPI(0) */ +#define IMX_IRQ_FIQ 28 /* Fast Interrupt Request (nFIQ) PPI(1) */ +#define IMX_IRQ_PTM 29 /* Private Timer (PTM) PPI(2) */ +#define IMX_IRQ_WDT 30 /* Watchdog Timer (WDT) PPI(3) */ +#define IMX_IRQ_IRQ 31 /* Interrupt Request (nIRQ) PPI(4) */ + +/* Shared Peripheral Interrupts (SPI) ***************************************/ + +#define IMX_IRQ_IOMUXC 32 /* General Purpose Register 1 from IOMUXC */ +#define IMX_IRQ_DAP 33 /* Debug Access Port interrupt request */ +#define IMX_IRQ_SDMA 34 /* SDMA interrupt request from all channels */ +#define IMX_IRQ_VPU 35 /* JPEG codec interrupt request */ +#define IMX_IRQ_SNVS 36 /* PMIC power off request */ +#define IMX_IRQ_IPU 37 /* IPU error interrupt request */ +#define IMX_IRQ_IPU1 38 /* IPU1 sync interrupt request */ +#define IMX_IRQ_IPU2 39 /* IPU2 error interrupt request */ +#define IMX_IRQ_IPU2 40 /* IPU2 sync interrupt request */ +#define IMX_IRQ_GPU3D 41 /* GPU3D interrupt request */ +#define IMX_IRQ_R2D 42 /* GPU2D R2D GPU2D general interrupt request */ +#define IMX_IRQ_V2D 43 /* GPU2D V2D GPU2D(OpenVG) general interrupt request */ +#define IMX_IRQ_VPU 44 /* VPU interrupt request */ +#define IMX_IRQ_APBHDMA 45 /* APBH-Bridge-DMA channels 0-3 interrupts */ +#define IMX_IRQ_EIM 46 /* EIM interrupt request */ +#define IMX_IRQ_BCH 47 /* BCH operation complete interrupt */ +#define IMX_IRQ_GPMI 48 /* GPMI operation timeout error interrupt */ +#define IMX_IRQ_DTCP 49 /* DTCP interrupt request */ +#define IMX_IRQ_VDOA 50 /* VDOA interrupt requests */ +#define IMX_IRQ_SNVS 51 /* SRTC consolidated interrupt */ +#define IMX_IRQ_SNVS 52 /* SRTC security interrupt */ +#define IMX_IRQ_CSU 53 /* CSU interrupt request 1 */ +#define IMX_IRQ_USDHC1 54 /* uSDHC1 interrupt request */ +#define IMX_IRQ_USDHC2 55 /* uSDHC2 interrupt request */ +#define IMX_IRQ_USDHC3 56 /* uSDHC3 interrupt request */ +#define IMX_IRQ_USDHC4 57 /* uSDHC4 interrupt request */ +#define IMX_IRQ_UART1 58 /* UART1 interrupt request */ +#define IMX_IRQ_UART2 59 /* UART2 interrupt request */ +#define IMX_IRQ_UART3 60 /* UART3 interrupt request */ +#define IMX_IRQ_UART4 61 /* UART4 interrupt request */ +#define IMX_IRQ_UART5 62 /* UART5 interrupt request */ +#define IMX_IRQ_ECSPI1 63 /* eCSPI1 interrupt request */ +#define IMX_IRQ_ECSPI2 64 /* eCSPI2 interrupt request */ +#define IMX_IRQ_ECSPI3 65 /* eCSPI3 interrupt request */ +#define IMX_IRQ_ECSPI4 66 /* eCSPI4 interrupt request */ +#define IMX_IRQ_ECSPI5 67 /* eCSPI5 interrupt request */ +#define IMX_IRQ_I2C1 68 /* I2C1 interrupt request */ +#define IMX_IRQ_I2C2 69 /* I2C2 interrupt request */ +#define IMX_IRQ_I2C3 70 /* I2C3 interrupt request */ +#define IMX_IRQ_SATA 71 /* SATA interrupt request */ +#define IMX_IRQ_USBHOST1 72 /* USB Host 1 interrupt request */ +#define IMX_IRQ_USBHOST2 73 /* USB Host 2 interrupt request */ +#define IMX_IRQ_USBHOST3 74 /* USB Host 3 interrupt request */ +#define IMX_IRQ_USBOTG 75 /* USB OTG interrupt request */ +#define IMX_IRQ_USBPHY0 76 /* UTMI0 interrupt request */ +#define IMX_IRQ_USBPHY1 77 /* UTMI1 interrupt request */ +#define IMX_IRQ_SSI1 78 /* SSI1 interrupt request */ +#define IMX_IRQ_SSI2 79 /* SSI2 interrupt request */ +#define IMX_IRQ_SSI3 80 /* SSI3 interrupt request */ +#define IMX_IRQ_TEMP 81 /* Temperature Sensor interrupt request */ +#define IMX_IRQ_ASRC 82 /* ASRC interrupt request */ +#define IMX_IRQ_ESAI 83 /* ESAI interrupt request */ +#define IMX_IRQ_SPDIF 84 /* SPDIF interrupt */ +#define IMX_IRQ_MLB150ERR 85 /* MLB error interrupt request */ +#define IMX_IRQ_PMUANREG 86 /* Brown out of analog regulators occurred */ +#define IMX_IRQ_GPT 87 /* GPT interrupt lines */ +#define IMX_IRQ_EPIT1 88 /* EPIT1 output compare interrupt */ +#define IMX_IRQ_EPIT2 89 /* EPIT2 output compare interrupt */ +#define IMX_IRQ_GPIO1_INT7 90 /* INT7 interrupt request */ +#define IMX_IRQ_GPIO1_INT6 91 /* INT6 interrupt request */ +#define IMX_IRQ_GPIO1_INT5 92 /* INT5 interrupt request */ +#define IMX_IRQ_GPIO1_INT4 93 /* INT4 interrupt request */ +#define IMX_IRQ_GPIO1_INT3 94 /* INT3 interrupt request */ +#define IMX_IRQ_GPIO1_INT2 95 /* INT2 interrupt request */ +#define IMX_IRQ_GPIO1_INT1 96 /* INT1 interrupt request */ +#define IMX_IRQ_GPIO1_INT0 97 /* INT0 interrupt request */ +#define IMX_IRQ_GPIO1_INT_0_15 98 /* GPIO1 signals 0-15 */ +#define IMX_IRQ_GPIO1_INT_16_31 99 /* GPIO1 signals 16-31 */ +#define IMX_IRQ_GPIO2_INT_0_15 100 /* GPIO2 signals 0-15 */ +#define IMX_IRQ_GPIO2_INT_16_31 101 /* GPIO2 signals 16-31 */ +#define IMX_IRQ_GPIO3_INT_0_15 102 /* GPIO3 signals 0-15 */ +#define IMX_IRQ_GPIO3_INT_16_31 103 /* GPIO3 signals 16-31 */ +#define IMX_IRQ_GPIO4_INT_0_15 104 /* GPIO4 signals 0-15 */ +#define IMX_IRQ_GPIO4_INT_16_31 105 /* GPIO4 signals 16-31 */ +#define IMX_IRQ_GPIO5_INT_0_15 106 /* GPIO5 signals 0-15 */ +#define IMX_IRQ_GPIO5_INT_16_31 107 /* GPIO5 signals 16-31 */ +#define IMX_IRQ_GPIO6_INT_0_15 108 /* GPIO6 signals 0-15 */ +#define IMX_IRQ_GPIO6_INT_16_31 109 /* GPIO6 signals 16-31 */ +#define IMX_IRQ_GPIO7_INT_0_15 110 /* GPIO7 signals 0-15 */ +#define IMX_IRQ_GPIO7_INT_16_31 111 /* GPIO7 signals 16-31 */ +#define IMX_IRQ_WDOG1 112 /* WDOG1 timer reset interrupt request */ +#define IMX_IRQ_WDOG2 113 /* WDOG2 timer reset interrupt request */ +#define IMX_IRQ_KPP 114 /* Key Pad interrupt request */ +#define IMX_IRQ_PWM1 115 /* PWM1 interrupts */ +#define IMX_IRQ_PWM2 116 /* PWM2 interrupts */ +#define IMX_IRQ_PWM3 117 /* PWM3 interrupts */ +#define IMX_IRQ_PWM4 118 /* PWM4 interrupts */ +#define IMX_IRQ_CCM1 119 /* CCM interrupt request 1 */ +#define IMX_IRQ_CCM2 120 /* CCM interrupt request 2 */ +#define IMX_IRQ_GPC 121 /* GPC interrupt request 1 */ +#define IMX_IRQ_RESERVED122 122 /* Reserved */ +#define IMX_IRQ_SRC 123 /* SRC interrupt request */ +#define IMX_IRQ_CPUL2 124 /* L2 interrupt request */ +#define IMX_IRQ_CPUPAR 125 /* Parity Check error interrupt request */ +#define IMX_IRQ_CPUPERF 126 /* Performance Unit interrupt */ +#define IMX_IRQ_CPUCTI 127 /* CTI trigger outputs interrupt */ +#define IMX_IRQ_SRC 128 /* CPU wdog interrupts (4x) out of SRC */ +#define IMX_IRQ_RESERVED129 129 /* Reserved */ +#define IMX_IRQ_RESERVED130 130 /* Reserved */ +#define IMX_IRQ_RESERVED131 131 /* Reserved */ +#define IMX_IRQ_MIPICSI1 132 /* CSI interrupt request 1 */ +#define IMX_IRQ_MIPICSI2 133 /* CSI interrupt request 2 */ +#define IMX_IRQ_MIPIDSI 134 /* DSI interrupt request */ +#define IMX_IRQ_MIPIHSI 135 /* HSI interrupt request */ +#define IMX_IRQ_SJC 136 /* SJC interrupt from General Purpose register */ +#define IMX_IRQ_CAAM0 137 /* CAAM job ring 0 interrupt */ +#define IMX_IRQ_CAAM1 138 /* CAAM job ring 1 interrupt */ +#define IMX_IRQ_RESERVED139 139 /* Reserved */ +#define IMX_IRQ_ASC1 140 /* ASC1 interrupt request */ +#define IMX_IRQ_ASC2 141 /* ASC2 interrupt request */ +#define IMX_IRQ_FLEXCAN1 142 /* FLEXCAN1 interrupt request */ +#define IMX_IRQ_FLEXCAN2 143 /* FLEXCAN2 interrupt request */ +#define IMX_IRQ_RESERVED144 144 /* Reserved */ +#define IMX_IRQ_RESERVED145 145 /* Reserved */ +#define IMX_IRQ_RESERVED146 146 /* Reserved */ +#define IMX_IRQ_HDMIMSTR 147 /* HDMI master interrupt request */ +#define IMX_IRQ_HDMICEC 148 /* HDMI CEC engine dedicated wake-up interrupt */ +#define IMX_IRQ_MLB150_0_31 149 /* Channels [31:0] interrupt requests */ +#define IMX_IRQ_ENET0 150 /* MAC 0 IRQ */ +#define IMX_IRQ_ENET0TMR 151 /* MAC 0 1588 Timer interrupt request */ +#define IMX_IRQ_PCIE1 152 /* PCIe interrupt request 1 (intd/msi_ctrl_int) */ +#define IMX_IRQ_PCIE2 153 /* PCIe interrupt request 2 (intc) */ +#define IMX_IRQ_PCIE3 154 /* PCIe interrupt request 3 (intb) */ +#define IMX_IRQ_PCIE4 155 /* PCIe interrupt request 4 (inta) */ +#define IMX_IRQ_DCIC1 156 /* DCIC1 interrupt requests */ +#define IMX_IRQ_DCIC2 157 /* DCIC2 interrupt requests */ +#define IMX_IRQ_MLB150_32_63 158 /* Channel[63:32] interrupt requests */ +#define IMX_IRQ_PMUDIGREG 159 /* Brown out of digital regulators occurred */ + +#define NR_IRQS 160 /* Total number of interrupts */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_IMX6_IRQ_H */ + diff --git a/arch/arm/include/irq.h b/arch/arm/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ef3db14e78c33f46248d3bf95adeadb66ffd25b6 --- /dev/null +++ b/arch/arm/include/irq.h @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/arm/include/irq.h + * + * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_IRQ_H +#define __ARCH_ARM_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/* Include ARM architecture-specific IRQ definitions (including register + * save structure and up_irq_save()/up_irq_restore() functions) + */ + +#if defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXA9) +# include +#elif defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) +# include +#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ + defined(CONFIG_ARCH_CORTEXM7) +# include +#elif defined(CONFIG_ARCH_CORTEXM0) +# include +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_IRQ_H */ + diff --git a/arch/arm/include/kinetis/chip.h b/arch/arm/include/kinetis/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..dd8582e564fc8e78472ed6b53c9e4eaf200d10a1 --- /dev/null +++ b/arch/arm/include/kinetis/chip.h @@ -0,0 +1,1069 @@ +/************************************************************************************ + * arch/arm/include/kinetis/chip.h + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_KINETIS_CHIP_H +#define __ARCH_ARM_INCLUDE_KINETIS_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +/* MK20DX/DN---VLH5 + * + * ------------- ------ --- ------- ------ ------- ------ ----- ---- + * PART NUMBER CPU PIN PACKAGE TOTAL PROGRAM EEPROM SRAM GPIO + * FREQ CNT FLASH FLASH + * ------------- ------ --- ------- ------ ------- ------ ----- ---- + * MK20DN32VLH5 50 MHz 64 LQFP 32 KB 32 KB — 8 KB 40 + * MK20DX32VLH5 50 MHz 64 LQFP 64 KB 32 KB 2 KB 8 KB 40 + * MK20DN64VLH5 50 MHz 64 LQFP 64 KB 64 KB — 16 KB 40 + * MK20DX64VLH5 50 MHz 64 LQFP 96 KB 64 KB 2 KB 16 KB 40 + * MK20DN128VLH5 50 MHz 64 LQFP 128 KB 128 KB — 16 KB 40 + * MK20DX128VLH5 50 MHz 64 LQFP 160 KB 128 KB 2 KB 16 KB 40 + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DN32VLH5) || \ + defined(CONFIG_ARCH_CHIP_MK20DX32VLH5) || \ + defined(CONFIG_ARCH_CHIP_MK20DN64VLH5) || \ + defined(CONFIG_ARCH_CHIP_MK20DX64VLH5) || \ + defined(CONFIG_ARCH_CHIP_MK20DN128VLH5) || \ + defined(CONFIG_ARCH_CHIP_MK20DX128VLH5) + +# define KINETIS_K20 1 /* Kinetics K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ + +#if defined(CONFIG_ARCH_CHIP_MK20DN32VLH5) +# define KINETIS_FLASH_SIZE (64*1024) /* 32Kb */ +# define KINETIS_FLEXMEM_SIZE (0*1024) /* No FlexMEM */ +# define KINETIS_SRAM_SIZE (8*1024) /* 8Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DX32VLH5) +# define KINETIS_FLASH_SIZE (64*1024) /* 32Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (8*1024) /* 8Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DN64VLH5) +# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */ +# define KINETIS_FLEXMEM_SIZE (0*1024) /* No FlexMEM */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DX64VLH5) +# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DN128VLH5) +# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */ +# define KINETIS_FLEXMEM_SIZE (0*1024) /* No FlexMEM */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DX128VLH5) +# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +#endif + +# undef KINETIS_MPU /* No memory protection unit */ +# undef KINETIS_EXTBUS /* No external bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# undef KINETIS_NSDHC /* No SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 1 /* One I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 3 /* Three UARTs */ +# define KINETIS_NSPI 2 /* Two SPI modules */ +# undef KINETIS_NCAN /* No CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# undef KINETIS_NSLCD /* No segment LCD interface */ +# define KINETIS_NADC16 1 /* One 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 1 /* One Programmable Gain Amplifiers */ +# define KINETIS_NCMP 2 /* Two analog comparators */ +# define KINETIS_NDAC6 2 /* Two 6-bit DAC */ +# undef KINETIS_NDAC12 0 /* No 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS8 2 /* Two 2-8 channel FlexTimers */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# undef KINETIS_NRNG /* No random number generator */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* One CRC */ + +/* MK20DX---VLH7 + * + * ------------- ------ --- ------- ------ ------- ------ ----- ---- + * PART NUMBER CPU PIN PACKAGE TOTAL PROGRAM EEPROM SRAM GPIO + * FREQ CNT FLASH FLASH + * ------------- ------ --- ------- ------ ------- ------ ----- ---- + * MK20DX64VLH7 72 MHz 64 LQFP 96 KB 64 KB 2 KB 16 KB 40 + * MK20DX128VLH7 72 MHz 64 LQFP 160 KB 128 KB 2 KB 32 KB 40 + * MK20DX256VLH7 72 MHz 64 LQFP 288 KB 256 KB 2 KB 64 KB 40 + * ------------- ------ --- ------- ------ ------- ------ ----- ---- + */ + +#elif defined(CONFIG_ARCH_CHIP_MK20DX64VLH7) || \ + defined(CONFIG_ARCH_CHIP_MK20DX128VLH7) || \ + defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) + +# define KINETIS_K20 1 /* Kinetics K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX64VLH7) +# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +#elif defined(CONFIG_ARCH_CHIP_MK20DX128VLH7) +# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (32*1024) /* 32Kb */ +#else /* if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +#endif + +# undef KINETIS_MPU /* No memory protection unit */ +# undef KINETIS_EXTBUS /* No external bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# undef KINETIS_NSDHC /* No SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 3 /* Three UARTs */ +# define KINETIS_NSPI 1 /* One SPI module */ +# define KINETIS_NCAN 1 /* Two CAN controller */ +# define KINETIS_NI2S 1 /* One I2S module */ +# undef KINETIS_NSLCD /* No segment LCD interface */ +# define KINETIS_NADC16 2 /* Two 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 2 /* Two 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# undef KINETIS_NRNG /* No random number generator */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# undef KINETIS_NCRC /* No CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X64VFX50) || defined(CONFIG_ARCH_CHIP_MK40X64VLH50) || \ + defined(CONFIG_ARCH_CHIP_MK40X64VLK50) || defined(CONFIG_ARCH_CHIP_MK40X64VMB50) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */ +# undef KINETIS_MPU /* No memory protection unit */ +# undef KINETIS_EXTBUS /* No external bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# undef KINETIS_NSDHC /* No SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# if defined(CONFIG_ARCH_CHIP_MK40X64VLK50) || defined(CONFIG_ARCH_CHIP_MK40X64VMB50) +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# else +# undef KINETIS_NCAN /* No CAN in 64-pin chips */ +# endif +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 25x8/29x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# undef KINETIS_NRNG /* No random number generator */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VFX50) || defined(CONFIG_ARCH_CHIP_MK40X128VLH50) || \ + defined(CONFIG_ARCH_CHIP_MK40X128VLK50) || defined(CONFIG_ARCH_CHIP_MK40X128VMB50) || \ + defined(CONFIG_ARCH_CHIP_MK40X128VLL50) || defined(CONFIG_ARCH_CHIP_MK40X128VML50) || \ + defined(CONFIG_ARCH_CHIP_MK40X128VFX72) || defined(CONFIG_ARCH_CHIP_MK40X128VLH72) || \ + defined(CONFIG_ARCH_CHIP_MK40X128VLK72) || defined(CONFIG_ARCH_CHIP_MK40X128VMB72) || \ + defined(CONFIG_ARCH_CHIP_MK40X128VLL72) || defined(CONFIG_ARCH_CHIP_MK40X128VML72) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (32*1024) /* 32Kb */ +# undef KINETIS_MPU /* No memory protection unit */ +# undef KINETIS_EXTBUS /* No external bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# undef KINETIS_NSDHC /* No SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X256VLK72) || defined(CONFIG_ARCH_CHIP_MK40X256VMB72) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLL72) || defined(CONFIG_ARCH_CHIP_MK40X256VML72) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (32*1024) /* 64Kb */ +# undef KINETIS_MPU /* No memory protection unit */ +# undef KINETIS_EXTBUS /* No external bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# undef KINETIS_NSDHC /* No SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */ +# define KINETIS_FLEXMEM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_SRAM_SIZE (32*1024) /* 32Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* One SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 40x8/44x4)*/ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXMEM_SIZE (256*1024) /* 256Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 32Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* One SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 40x8/44x4)*/ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK40N512VLK100) || defined(CONFIG_ARCH_CHIP_MK40N512VMB100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLL100) || defined(CONFIG_ARCH_CHIP_MK40N512VML100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# define KINETIS_K40 1 /* Kinetics K40 family */ +# undef KINETIS_K60 /* Not Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */ +# undef KINETIS_FLEXMEM_SIZE /* No FlexMemory */ +# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# undef KINETIS_NENET /* No Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* One SD host controller */ +# undef KINETIS_NTOUCHIF /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 2 /* Two I2C modules */ +# undef KINETIS_NISO7816 /* No UART with ISO-786 */ +# define KINETIS_NUART 6 /* Six UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 1 /* One I2S module */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 40x8/44x4)*/ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 2 /* Two Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# define KINETIS_NDAC6 3 /* Three 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Two 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLL100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# define KINETIS_NADC13 1 /* No 13-channel ADC (ADC1) */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60X256VLL100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXRAM_SIZE (4*1024) /* 32Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# define KINETIS_NADC13 1 /* No 13-channel ADC (ADC1) */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N512VLL100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (512*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_ENET_HAS_DBSWAP /* MAC-NET supports DBSWP bit */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# define KINETIS_NADC13 1 /* No 13-channel ADC (ADC1) */ +# undef KINETIS_NADC15 /* No 15-channel ADC */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VML100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC1) */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60X256VML100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC1) */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N512VML100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (512*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 4 /* Four additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# define KINETIS_NADC12 1 /* One 12-channel ADC (ADC0)*/ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC1) */ +# undef KINETIS_NADC18 /* No 18-channel ADC */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 1 /* One 12-bit DAC */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60X256VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */ +# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */ +# define KINETIS_SRAM_SIZE (64*1024) /* 64Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N512VMD100) +# undef KINETIS_K20 /* Not Kinetis K20 family */ +# undef KINETIS_K40 /* Not Kinetics K40 family */ +# define KINETIS_K60 1 /* Kinetis K60 family */ +# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */ +# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */ +# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */ +# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */ +# define KINETIS_MPU 1 /* Memory protection unit */ +# define KINETIS_EXTBUS 1 /* External bus interface */ +# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */ +# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */ +# define KINETIS_NUSBHOST 1 /* One USB host controller */ +# define KINETIS_NUSBOTG 1 /* With USB OTG controller */ +# define KINETIS_NUSBDEV 1 /* One USB device controller */ +# define KINETIS_NSDHC 1 /* SD host controller */ +# define KINETIS_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KINETIS_NI2C 3 /* Three I2C modules */ +# define KINETIS_NISO7816 1 /* One UART with ISO-786 */ +# define KINETIS_NUART 5 /* Five additional UARTs */ +# define KINETIS_NSPI 3 /* Three SPI modules */ +# define KINETIS_NCAN 2 /* Two CAN controllers */ +# define KINETIS_NI2S 2 /* Two I2S modules */ +# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */ +# define KINETIS_NADC16 4 /* Four 16-bit ADC */ +# undef KINETIS_NADC12 /* No 12-channel ADC */ +# undef KINETIS_NADC13 /* No 13-channel ADC */ +# define KINETIS_NADC15 1 /* One 15-channel ADC (ADC0) */ +# define KINETIS_NADC18 1 /* One 18-channel ADC (ADC1) */ +# define KINETIS_NPGA 4 /* Four Programmable Gain Amplifiers */ +# define KINETIS_NCMP 3 /* Three analog comparators */ +# undef KINETIS_NDAC6 /* No 6-bit DAC */ +# define KINETIS_NDAC12 2 /* Twp 12-bit DACs */ +# define KINETIS_NVREF 1 /* Voltage reference */ +# undef KINETIS_NTIMERS12 /* No 12 channel timers */ +# define KINETIS_NTIMERS20 4 /* Four 20 channel timers */ +# define KINETIS_NTIMERS12 3 /* Three 12 channel timers */ +# undef KINETIS_NTIMERS20 /* No 20 channel timers */ +# define KINETIS_NRTC 1 /* Real time clock */ +# undef KINETIS_NRNG /* No random number generator */ +# undef KINETIS_NMMCAU /* No hardware encryption */ +# undef KINETIS_NTAMPER /* No tamper detect */ +# define KINETIS_NCRC 1 /* CRC */ + +#else +# error "Unsupported Kinetis chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-15. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:4] of each field, bits[3:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits[7:4] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Steps between supported priority values */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_KINETIS_CHIP_H */ diff --git a/arch/arm/include/kinetis/irq.h b/arch/arm/include/kinetis/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..3355f29b02cf2dcaa2570722632ddea9bd1c57a9 --- /dev/null +++ b/arch/arm/include/kinetis/irq.h @@ -0,0 +1,424 @@ +/************************************************************************************ + * arch/arm/include/kinetis/irq.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_KINETIS_IRQ_H +#define __ARCH_ARM_INCLUDE_KINETIS_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* IRQ numbers **********************************************************************/ +/* The IRQ numbers corresponds directly to vector numbers and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define KINETIS_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define KINETIS_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define KINETIS_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define KINETIS_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define KINETIS_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define KINETIS_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define KINETIS_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define KINETIS_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define KINETIS_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define KINETIS_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16) */ + +#define KINETIS_IRQ_EXTINT (16) + +/* K20 Family *********************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K20P64M72SF1RM + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) +# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */ +# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */ +# define KINETIS_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */ +# define KINETIS_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */ +# define KINETIS_IRQ_DMACH4 (20) /* Vector 20: DMA channel 4 transfer complete */ +# define KINETIS_IRQ_DMACH5 (21) /* Vector 21: DMA channel 5 transfer complete */ +# define KINETIS_IRQ_DMACH6 (22) /* Vector 22: DMA channel 6 transfer complete */ +# define KINETIS_IRQ_DMACH7 (23) /* Vector 23: DMA channel 7 transfer complete */ +# define KINETIS_IRQ_DMACH8 (24) /* Vector 24: DMA channel 8 transfer complete */ +# define KINETIS_IRQ_DMACH9 (25) /* Vector 25: DMA channel 9 transfer complete */ +# define KINETIS_IRQ_DMACH10 (26) /* Vector 26: DMA channel 10 transfer complete */ +# define KINETIS_IRQ_DMACH11 (27) /* Vector 27: DMA channel 11 transfer complete */ +# define KINETIS_IRQ_DMACH12 (28) /* Vector 28: DMA channel 12 transfer complete */ +# define KINETIS_IRQ_DMACH13 (29) /* Vector 29: DMA channel 13 transfer complete */ +# define KINETIS_IRQ_DMACH14 (30) /* Vector 30: DMA channel 14 transfer complete */ +# define KINETIS_IRQ_DMACH15 (31) /* Vector 31: DMA channel 15 transfer complete */ +# define KINETIS_IRQ_DMAERR (32) /* Vector 32: DMA error interrupt channels 0-15 */ +# define KINETIS_IRQ_FLASHCC (34) /* Vector 34: Flash memory command complete */ +# define KINETIS_IRQ_FLASHRC (35) /* Vector 35: Flash memory read collision */ +# define KINETIS_IRQ_SMCLVD (36) /* Vector 36: Mode Controller low-voltage + * detect, low-voltage warning */ +# define KINETIS_IRQ_LLWU (37) /* Vector 37: LLWU Normal Low Leakage Wakeup */ +# define KINETIS_IRQ_WDOG (38) /* Vector 38: Watchdog */ +# define KINETIS_IRQ_I2C0 (40) /* Vector 40: I2C0 */ +# define KINETIS_IRQ_I2C1 (41) /* Vector 41: I2C1 */ +# define KINETIS_IRQ_SPI0 (42) /* Vector 42: SPI0 all sources */ +# define KINETIS_IRQ_SPI1 (43) /* Vector 43: SPI1 all sources */ +# define KINETIS_IRQ_CAN0MB (45) /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ +# define KINETIS_IRQ_CAN0BO (46) /* Vector 46: CAN0 Bus Off */ +# define KINETIS_IRQ_CAN0ERR (47) /* Vector 47: CAN0 Error */ +# define KINETIS_IRQ_CAN0TW (48) /* Vector 48: CAN0 Transmit Warning */ +# define KINETIS_IRQ_CAN0RW (49) /* Vector 49: CAN0 Receive Warning */ +# define KINETIS_IRQ_CAN0WU (50) /* Vector 50: CAN0 Wake UP */ +//TODO UART0_LON +# define KINETIS_IRQ_UART0S (61) /* Vector 61: UART0 status */ +# define KINETIS_IRQ_UART0E (62) /* Vector 62: UART0 error */ +# define KINETIS_IRQ_UART1S (63) /* Vector 63: UART1 status */ +# define KINETIS_IRQ_UART1E (64) /* Vector 64: UART1 error */ +# define KINETIS_IRQ_UART2S (65) /* Vector 65: UART2 status */ +# define KINETIS_IRQ_UART2E (66) /* Vector 66: UART2 error */ +# define KINETIS_IRQ_ADC0 (73) /* Vector 73: ADC0 */ +# define KINETIS_IRQ_ADC1 (74) /* Vector 74: ADC1 */ +# define KINETIS_IRQ_CMP0 (75) /* Vector 75: CMP0 */ +# define KINETIS_IRQ_CMP1 (76) /* Vector 76: CMP1 */ +# define KINETIS_IRQ_CMP2 (77) /* Vector 77: CMP2 */ +# define KINETIS_IRQ_FTM0 (78) /* Vector 78: FTM0 all sources */ +# define KINETIS_IRQ_FTM1 (79) /* Vector 79: FTM1 all sources */ +# define KINETIS_IRQ_FTM2 (80) /* Vector 80: FTM2 all sources */ +# define KINETIS_IRQ_CMT (81) /* Vector 81: CMT */ +# define KINETIS_IRQ_RTC (82) /* Vector 82: RTC alarm interrupt */ +//TODO RTC_SECOND +# define KINETIS_IRQ_PITCH0 (84) /* Vector 84: PIT channel 0 */ +# define KINETIS_IRQ_PITCH1 (85) /* Vector 85: PIT channel 1 */ +# define KINETIS_IRQ_PITCH2 (86) /* Vector 86: PIT channel 2 */ +# define KINETIS_IRQ_PITCH3 (87) /* Vector 87: PIT channel 3 */ +# define KINETIS_IRQ_PDB (88) /* Vector 88: PDB */ +# define KINETIS_IRQ_USBOTG (89) /* Vector 88: USB OTG */ +# define KINETIS_IRQ_USBCD (90) /* Vector 90: USB charger detect */ +# define KINETIS_IRQ_DAC0 (97) /* Vector 97: DAC0 */ +# define KINETIS_IRQ_TSI (99) /* Vector 97: TSI all sources */ +# define KINETIS_IRQ_MCG (100) /* Vector 100: MCG */ +# define KINETIS_IRQ_LPT (101) /* Vector 101: Low power timer */ +# define KINETIS_IRQ_PORTA (103) /* Vector 103: Pin detect port A */ +# define KINETIS_IRQ_PORTB (104) /* Vector 104: Pin detect port B */ +# define KINETIS_IRQ_PORTC (105) /* Vector 105: Pin detect port C */ +# define KINETIS_IRQ_PORTD (106) /* Vector 106: Pin detect port D */ +# define KINETIS_IRQ_PORTE (107) /* Vector 107: Pin detect port E */ +# define KINETIS_IRQ_SWI (110) /* Vector 110: Software interrupt */ + +# define NR_VECTORS (111) /* 111 vectors */ +# define NR_IRQS (111) /* 94 interrupts but 111 IRQ numbers */ + +/* K40 Family *********************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) + +# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */ +# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */ +# define KINETIS_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */ +# define KINETIS_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */ +# define KINETIS_IRQ_DMACH4 (20) /* Vector 20: DMA channel 4 transfer complete */ +# define KINETIS_IRQ_DMACH5 (21) /* Vector 21: DMA channel 5 transfer complete */ +# define KINETIS_IRQ_DMACH6 (22) /* Vector 22: DMA channel 6 transfer complete */ +# define KINETIS_IRQ_DMACH7 (23) /* Vector 23: DMA channel 7 transfer complete */ +# define KINETIS_IRQ_DMACH8 (24) /* Vector 24: DMA channel 8 transfer complete */ +# define KINETIS_IRQ_DMACH9 (25) /* Vector 25: DMA channel 9 transfer complete */ +# define KINETIS_IRQ_DMACH10 (26) /* Vector 26: DMA channel 10 transfer complete */ +# define KINETIS_IRQ_DMACH11 (27) /* Vector 27: DMA channel 11 transfer complete */ +# define KINETIS_IRQ_DMACH12 (28) /* Vector 28: DMA channel 12 transfer complete */ +# define KINETIS_IRQ_DMACH13 (29) /* Vector 29: DMA channel 13 transfer complete */ +# define KINETIS_IRQ_DMACH14 (30) /* Vector 30: DMA channel 14 transfer complete */ +# define KINETIS_IRQ_DMACH15 (31) /* Vector 31: DMA channel 15 transfer complete */ +# define KINETIS_IRQ_DMAERR (32) /* Vector 32: DMA error interrupt channels 0-15 */ +# define KINETIS_IRQ_MCM (33) /* Vector 33: MCM Normal interrupt */ +# define KINETIS_IRQ_FLASHCC (34) /* Vector 34: Flash memory command complete */ +# define KINETIS_IRQ_FLASHRC (35) /* Vector 35: Flash memory read collision */ +# define KINETIS_IRQ_SMCLVD (36) /* Vector 36: Mode Controller low-voltage + * detect, low-voltage warning */ +# define KINETIS_IRQ_LLWU (37) /* Vector 37: LLWU Normal Low Leakage Wakeup */ +# define KINETIS_IRQ_WDOG (38) /* Vector 38: Watchdog */ + /* Vector 39: Reserved */ +# define KINETIS_IRQ_I2C0 (40) /* Vector 40: I2C0 */ +# define KINETIS_IRQ_I2C1 (41) /* Vector 41: I2C1 */ +# define KINETIS_IRQ_SPI0 (42) /* Vector 42: SPI0 all sources */ +# define KINETIS_IRQ_SPI1 (43) /* Vector 43: SPI1 all sources */ +# define KINETIS_IRQ_SPI2 (44) /* Vector 44: SPI2 all sources */ +# define KINETIS_IRQ_CAN0MB (45) /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ +# define KINETIS_IRQ_CAN0BO (46) /* Vector 46: CAN0 Bus Off */ +# define KINETIS_IRQ_CAN0ERR (47) /* Vector 47: CAN0 Error */ +# define KINETIS_IRQ_CAN0TW (48) /* Vector 48: CAN0 Transmit Warning */ +# define KINETIS_IRQ_CAN0RW (49) /* Vector 49: CAN0 Receive Warning */ +# define KINETIS_IRQ_CAN0WU (50) /* Vector 50: CAN0 Wake UP */ + /* Vectors 51-52: Reserved */ +# define KINETIS_IRQ_CAN1MB (53) /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ +# define KINETIS_IRQ_CAN1BO (54) /* Vector 54: CAN1 Bus Off */ +# define KINETIS_IRQ_CAN1ERR (55) /* Vector 55: CAN1 Error */ +# define KINETIS_IRQ_CAN1TW (56) /* Vector 56: CAN1 Transmit Warning */ +# define KINETIS_IRQ_CAN1RW (57) /* Vector 57: CAN1 Receive Warning */ +# define KINETIS_IRQ_CAN1WU (58) /* Vector 58: CAN1 Wake UP */ + /* Vectors 59-60: Reserved */ +# define KINETIS_IRQ_UART0S (61) /* Vector 61: UART0 status */ +# define KINETIS_IRQ_UART0E (62) /* Vector 62: UART0 error */ +# define KINETIS_IRQ_UART1S (63) /* Vector 63: UART1 status */ +# define KINETIS_IRQ_UART1E (64) /* Vector 64: UART1 error */ +# define KINETIS_IRQ_UART2S (65) /* Vector 65: UART2 status */ +# define KINETIS_IRQ_UART2E (66) /* Vector 66: UART2 error */ +# define KINETIS_IRQ_UART3S (67) /* Vector 67: UART3 status */ +# define KINETIS_IRQ_UART3E (68) /* Vector 68: UART3 error */ +# define KINETIS_IRQ_UART4S (69) /* Vector 69: UART4 status */ +# define KINETIS_IRQ_UART4E (70) /* Vector 70: UART4 error */ +# define KINETIS_IRQ_UART5S (71) /* Vector 71: UART5 status */ +# define KINETIS_IRQ_UART5E (72) /* Vector 72: UART5 error */ +# define KINETIS_IRQ_ADC0 (73) /* Vector 73: ADC0 */ +# define KINETIS_IRQ_ADC1 (74) /* Vector 74: ADC1 */ +# define KINETIS_IRQ_CMP0 (75) /* Vector 75: CMP0 */ +# define KINETIS_IRQ_CMP1 (76) /* Vector 76: CMP1 */ +# define KINETIS_IRQ_CMP2 (77) /* Vector 77: CMP2 */ +# define KINETIS_IRQ_FTM0 (78) /* Vector 78: FTM0 all sources */ +# define KINETIS_IRQ_FTM1 (79) /* Vector 79: FTM1 all sources */ +# define KINETIS_IRQ_FTM2 (80) /* Vector 80: FTM2 all sources */ +# define KINETIS_IRQ_CMT (81) /* Vector 81: CMT */ +# define KINETIS_IRQ_RTC (82) /* Vector 82: RTC alarm interrupt */ + /* Vector 83: Reserved */ +# define KINETIS_IRQ_PITCH0 (84) /* Vector 84: PIT channel 0 */ +# define KINETIS_IRQ_PITCH1 (85) /* Vector 85: PIT channel 1 */ +# define KINETIS_IRQ_PITCH2 (86) /* Vector 86: PIT channel 2 */ +# define KINETIS_IRQ_PITCH3 (87) /* Vector 87: PIT channel 3 */ +# define KINETIS_IRQ_PDB (88) /* Vector 88: PDB */ +# define KINETIS_IRQ_USBOTG (89) /* Vector 88: USB OTG */ +# define KINETIS_IRQ_USBCD (90) /* Vector 90: USB charger detect */ + /* Vectors 91-94: Reserved */ +# define KINETIS_IRQ_I2S0 (95) /* Vector 95: I2S0 */ +# define KINETIS_IRQ_SDHC (96) /* Vector 96: SDHC */ +# define KINETIS_IRQ_DAC0 (97) /* Vector 97: DAC0 */ +# define KINETIS_IRQ_DAC1 (98) /* Vector 98: DAC1 */ +# define KINETIS_IRQ_TSI (99) /* Vector 97: TSI all sources */ +# define KINETIS_IRQ_MCG (100) /* Vector 100: MCG */ +# define KINETIS_IRQ_LPT (101) /* Vector 101: Low power timer */ +# define KINETIS_IRQ_SLCD (102) /* Vector 102: Segment LCD all sources */ +# define KINETIS_IRQ_PORTA (103) /* Vector 103: Pin detect port A */ +# define KINETIS_IRQ_PORTB (104) /* Vector 104: Pin detect port B */ +# define KINETIS_IRQ_PORTC (105) /* Vector 105: Pin detect port C */ +# define KINETIS_IRQ_PORTD (106) /* Vector 106: Pin detect port D */ +# define KINETIS_IRQ_PORTE (107) /* Vector 107: Pin detect port E */ + /* Vectors 108-109: Reserved */ +# define KINETIS_IRQ_SWI (110) /* Vector 110: Software interrupt */ + +/* Note that the total number of IRQ numbers supported is equal to the number of + * valid interrupt vectors. This is wasteful in that certain tables are sized by + * this value. There are only 94 valid interrupts so, potentially the numver of + * IRQs to could be reduced to 94. However, equating IRQ numbers with vector numbers + * also simplifies operations on NVIC registers and (at least in my state of mind + * now) seems to justify the waste. + */ + +# define NR_VECTORS (111) /* 111 vectors */ +# define NR_IRQS (111) /* 94 interrupts but 111 IRQ numbers */ + +/* K60 Family *********************************************************************** + * + * The memory map for the following parts is defined in Freescale document + * K60P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLL100) + +# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */ +# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */ +# define KINETIS_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */ +# define KINETIS_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */ +# define KINETIS_IRQ_DMACH4 (20) /* Vector 20: DMA channel 4 transfer complete */ +# define KINETIS_IRQ_DMACH5 (21) /* Vector 21: DMA channel 5 transfer complete */ +# define KINETIS_IRQ_DMACH6 (22) /* Vector 22: DMA channel 6 transfer complete */ +# define KINETIS_IRQ_DMACH7 (23) /* Vector 23: DMA channel 7 transfer complete */ +# define KINETIS_IRQ_DMACH8 (24) /* Vector 24: DMA channel 8 transfer complete */ +# define KINETIS_IRQ_DMACH9 (25) /* Vector 25: DMA channel 9 transfer complete */ +# define KINETIS_IRQ_DMACH10 (26) /* Vector 26: DMA channel 10 transfer complete */ +# define KINETIS_IRQ_DMACH11 (27) /* Vector 27: DMA channel 11 transfer complete */ +# define KINETIS_IRQ_DMACH12 (28) /* Vector 28: DMA channel 12 transfer complete */ +# define KINETIS_IRQ_DMACH13 (29) /* Vector 29: DMA channel 13 transfer complete */ +# define KINETIS_IRQ_DMACH14 (30) /* Vector 30: DMA channel 14 transfer complete */ +# define KINETIS_IRQ_DMACH15 (31) /* Vector 31: DMA channel 15 transfer complete */ +# define KINETIS_IRQ_DMAERR (32) /* Vector 32: DMA error interrupt channels 0-15 */ +# define KINETIS_IRQ_MCM (33) /* Vector 33: MCM Normal interrupt */ +# define KINETIS_IRQ_FLASHCC (34) /* Vector 34: Flash memory command complete */ +# define KINETIS_IRQ_FLASHRC (35) /* Vector 35: Flash memory read collision */ +# define KINETIS_IRQ_SMCLVD (36) /* Vector 36: Mode Controller low-voltage + * detect, low-voltage warning */ +# define KINETIS_IRQ_LLWU (37) /* Vector 37: LLWU Normal Low Leakage Wakeup */ +# define KINETIS_IRQ_WDOG (38) /* Vector 38: Watchdog */ +# define KINETIS_IRQ_RNGB (39) /* Vector 39: Random number generator */ +# define KINETIS_IRQ_I2C0 (40) /* Vector 40: I2C0 */ +# define KINETIS_IRQ_I2C1 (41) /* Vector 41: I2C1 */ +# define KINETIS_IRQ_SPI0 (42) /* Vector 42: SPI0 all sources */ +# define KINETIS_IRQ_SPI1 (43) /* Vector 43: SPI1 all sources */ +# define KINETIS_IRQ_SPI2 (44) /* Vector 44: SPI2 all sources */ +# define KINETIS_IRQ_CAN0MB (45) /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ +# define KINETIS_IRQ_CAN0BO (46) /* Vector 46: CAN0 Bus Off */ +# define KINETIS_IRQ_CAN0ERR (47) /* Vector 47: CAN0 Error */ +# define KINETIS_IRQ_CAN0TW (48) /* Vector 48: CAN0 Transmit Warning */ +# define KINETIS_IRQ_CAN0RW (49) /* Vector 49: CAN0 Receive Warning */ +# define KINETIS_IRQ_CAN0WU (50) /* Vector 50: CAN0 Wake UP */ + /* Vectors 51-52: Reserved */ +# define KINETIS_IRQ_CAN1MB (53) /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ +# define KINETIS_IRQ_CAN1BO (54) /* Vector 54: CAN1 Bus Off */ +# define KINETIS_IRQ_CAN1ERR (55) /* Vector 55: CAN1 Error */ +# define KINETIS_IRQ_CAN1TW (56) /* Vector 56: CAN1 Transmit Warning */ +# define KINETIS_IRQ_CAN1RW (57) /* Vector 57: CAN1 Receive Warning */ +# define KINETIS_IRQ_CAN1WU (58) /* Vector 58: CAN1 Wake UP */ + /* Vectors 59-60: Reserved */ +# define KINETIS_IRQ_UART0S (61) /* Vector 61: UART0 status */ +# define KINETIS_IRQ_UART0E (62) /* Vector 62: UART0 error */ +# define KINETIS_IRQ_UART1S (63) /* Vector 63: UART1 status */ +# define KINETIS_IRQ_UART1E (64) /* Vector 64: UART1 error */ +# define KINETIS_IRQ_UART2S (65) /* Vector 65: UART2 status */ +# define KINETIS_IRQ_UART2E (66) /* Vector 66: UART2 error */ +# define KINETIS_IRQ_UART3S (67) /* Vector 67: UART3 status */ +# define KINETIS_IRQ_UART3E (68) /* Vector 68: UART3 error */ +# define KINETIS_IRQ_UART4S (69) /* Vector 69: UART4 status */ +# define KINETIS_IRQ_UART4E (70) /* Vector 70: UART4 error */ +# define KINETIS_IRQ_UART5S (71) /* Vector 71: UART5 status */ +# define KINETIS_IRQ_UART5E (72) /* Vector 72: UART5 error */ +# define KINETIS_IRQ_ADC0 (73) /* Vector 73: ADC0 */ +# define KINETIS_IRQ_ADC1 (74) /* Vector 74: ADC1 */ +# define KINETIS_IRQ_CMP0 (75) /* Vector 75: CMP0 */ +# define KINETIS_IRQ_CMP1 (76) /* Vector 76: CMP1 */ +# define KINETIS_IRQ_CMP2 (77) /* Vector 77: CMP2 */ +# define KINETIS_IRQ_FTM0 (78) /* Vector 78: FTM0 all sources */ +# define KINETIS_IRQ_FTM1 (79) /* Vector 79: FTM1 all sources */ +# define KINETIS_IRQ_FTM2 (80) /* Vector 80: FTM2 all sources */ +# define KINETIS_IRQ_CMT (81) /* Vector 81: CMT */ +# define KINETIS_IRQ_RTC (82) /* Vector 82: RTC alarm interrupt */ + /* Vector 83: Reserved */ +# define KINETIS_IRQ_PITCH0 (84) /* Vector 84: PIT channel 0 */ +# define KINETIS_IRQ_PITCH1 (85) /* Vector 85: PIT channel 1 */ +# define KINETIS_IRQ_PITCH2 (86) /* Vector 86: PIT channel 2 */ +# define KINETIS_IRQ_PITCH3 (87) /* Vector 87: PIT channel 3 */ +# define KINETIS_IRQ_PDB (88) /* Vector 88: PDB */ +# define KINETIS_IRQ_USBOTG (89) /* Vector 88: USB OTG */ +# define KINETIS_IRQ_USBCD (90) /* Vector 90: USB charger detect */ +# define KINETIS_IRQ_EMACTMR (91) /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */ +# define KINETIS_IRQ_EMACTX (92) /* Vector 92: Ethernet MAC transmit interrupt */ +# define KINETIS_IRQ_EMACRX (93) /* Vector 93: Ethernet MAC receive interrupt */ +# define KINETIS_IRQ_EMACMISC (94) /* Vector 94: Ethernet MAC error and misc interrupt */ +# define KINETIS_IRQ_I2S0 (95) /* Vector 95: I2S0 */ +# define KINETIS_IRQ_SDHC (96) /* Vector 96: SDHC */ +# define KINETIS_IRQ_DAC0 (97) /* Vector 97: DAC0 */ +# define KINETIS_IRQ_DAC1 (98) /* Vector 98: DAC1 */ +# define KINETIS_IRQ_TSI (99) /* Vector 97: TSI all sources */ +# define KINETIS_IRQ_MCG (100) /* Vector 100: MCG */ +# define KINETIS_IRQ_LPT (101) /* Vector 101: Low power timer */ + /* Vector 102: Reserved */ +# define KINETIS_IRQ_PORTA (103) /* Vector 103: Pin detect port A */ +# define KINETIS_IRQ_PORTB (104) /* Vector 104: Pin detect port B */ +# define KINETIS_IRQ_PORTC (105) /* Vector 105: Pin detect port C */ +# define KINETIS_IRQ_PORTD (106) /* Vector 106: Pin detect port D */ +# define KINETIS_IRQ_PORTE (107) /* Vector 107: Pin detect port E */ + /* Vectors 108-119: Reserved */ + +/* Note that the total number of IRQ numbers supported is equal to the number of + * valid interrupt vectors. This is wasteful in that certain tables are sized by + * this value. There are only 97 valid interrupts so, potentially the number of + * IRQs to could be reduced to 97. However, equating IRQ numbers with vector numbers + * also simplifies operations on NVIC registers and (at least in my state of mind + * now) seems to justify the waste. + */ + +# define NR_VECTORS (120) /* 120 vectors */ +# define NR_IRQS (108) /* 120 interrupts but 108 IRQ numbers */ + +#else + /* The interrupt vectors for other parts are defined in other documents and may or + * may not be the same as above (the family members are all very similar) This + * error just means that you have to look at the document and determine for yourself + * if the vectors are the same. + */ + +# error "No IRQ numbers for this Kinetis part" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_KINETIS_IRQ_H */ + diff --git a/arch/arm/include/kl/chip.h b/arch/arm/include/kl/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..df1029eecb4d5b47f64a3360b12d5791575ee033 --- /dev/null +++ b/arch/arm/include/kl/chip.h @@ -0,0 +1,193 @@ +/************************************************************************************ + * arch/arm/include/kinetis/chip.h + * + * Copyright (C) 2013, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_KL_CHIP_H +#define __ARCH_ARM_INCLUDE_KL_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +#if defined(CONFIG_ARCH_CHIP_MKL25Z64) + +# define KL_Z64 1 /* Kinetics KL25Z128 family */ +# define KL_FLASH_SIZE (64*1024) /* 64Kb */ +# define KL_SRAM_SIZE (8*1024) /* 8Kb */ +# undef KL_MPU /* No memory protection unit */ +# undef KL_EXTBUS /* No external bus interface */ +# define KL_NDMACH 4 /* Up to 4 DMA channels */ +# undef KL_NENET /* No Ethernet controller */ +# define KL_NUSBHOST 1 /* One USB host controller */ +# define KL_NUSBOTG 1 /* With USB OTG controller */ +# define KL_NUSBDEV 1 /* One USB device controller */ +# undef KL_NSDHC /* No SD host controller */ +# define KL_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KL_NI2C 2 /* Two I2C modules */ +# define KL_NUART 3 /* Three UARTs */ +# define KL_NSPI 2 /* Two SPI modules */ +# undef KL_NCAN /* No CAN in 64-pin chips */ +# define KL_NI2S 1 /* One I2S module */ +# undef KL_NSLCD /* One segment LCD interface (up to 25x8/29x4) */ +# define KL_NADC16 1 /* One 16-bit ADC */ +# undef KL_NADC12 /* No 12-channel ADC */ +# undef KL_NADC13 /* No 13-channel ADC */ +# undef KL_NADC15 /* No 15-channel ADC */ +# undef KL_NADC18 /* No 18-channel ADC */ +# undef KL_NPGA /* No Programmable Gain Amplifiers */ +# define KL_NCMP 1 /* One analog comparator */ +# define KL_NDAC6 1 /* Three 6-bit DAC */ +# define KL_NDAC12 1 /* Two 12-bit DAC */ +# define KL_NVREF 1 /* Voltage reference */ +# define KL_NTIMERS6 1 /* One 6 channel timer */ +# define KL_NTIMERS2 2 /* Two 2 channel timers */ +# undef KL_NRNG /* No random number generator */ +# define KL_NRTC 1 /* Real time clock */ +# undef KL_NMMCAU /* No hardware encryption */ +# undef KL_NTAMPER /* No tamper detect */ +# undef KL_NCRC /* No CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MKL25Z128) + +# define KL_Z128 1 /* Kinetics KL25Z128 family */ +# define KL_FLASH_SIZE (128*1024) /* 64Kb */ +# define KL_SRAM_SIZE (16*1024) /* 16Kb */ +# undef KL_MPU /* No memory protection unit */ +# undef KL_EXTBUS /* No external bus interface */ +# define KL_NDMACH 4 /* Up to 4 DMA channels */ +# undef KL_NENET /* No Ethernet controller */ +# define KL_NUSBHOST 1 /* One USB host controller */ +# define KL_NUSBOTG 1 /* With USB OTG controller */ +# define KL_NUSBDEV 1 /* One USB device controller */ +# undef KL_NSDHC /* No SD host controller */ +# define KL_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KL_NI2C 2 /* Two I2C modules */ +# define KL_NUART 3 /* Three UARTs */ +# define KL_NSPI 2 /* Two SPI modules */ +# undef KL_NCAN /* No CAN in 64-pin chips */ +# define KL_NI2S 1 /* One I2S module */ +# undef KL_NSLCD /* One segment LCD interface (up to 25x8/29x4) */ +# define KL_NADC16 1 /* One 16-bit ADC */ +# undef KL_NADC12 /* No 12-channel ADC */ +# undef KL_NADC13 /* No 13-channel ADC */ +# undef KL_NADC15 /* No 15-channel ADC */ +# undef KL_NADC18 /* No 18-channel ADC */ +# undef KL_NPGA /* No Programmable Gain Amplifiers */ +# define KL_NCMP 1 /* One analog comparator */ +# define KL_NDAC6 1 /* Three 6-bit DAC */ +# define KL_NDAC12 1 /* Two 12-bit DAC */ +# define KL_NVREF 1 /* Voltage reference */ +# define KL_NTIMERS8 1 /* One 8 channel timers */ +# undef KL_NTIMERS12 /* No 12 channel timers */ +# undef KL_NTIMERS20 /* No 20 channel timers */ +# undef KL_NRNG /* No random number generator */ +# define KL_NRTC 1 /* Real time clock */ +# undef KL_NMMCAU /* No hardware encryption */ +# undef KL_NTAMPER /* No tamper detect */ +# undef KL_NCRC /* No CRC */ + +#elif defined(CONFIG_ARCH_CHIP_MKL26Z128) + +# define KL_Z128 1 /* Kinetics KL25Z128 family */ +# define KL_FLASH_SIZE (128*1024) /* 64Kb */ +# define KL_SRAM_SIZE (16*1024) /* 16Kb */ +# undef KL_MPU /* No memory protection unit */ +# undef KL_EXTBUS /* No external bus interface */ +# define KL_NDMACH 4 /* Up to 4 DMA channels */ +# undef KL_NENET /* No Ethernet controller */ +# define KL_NUSBHOST 1 /* One USB host controller */ +# define KL_NUSBOTG 1 /* With USB OTG controller */ +# define KL_NUSBDEV 1 /* One USB device controller */ +# undef KL_NSDHC /* No SD host controller */ +# define KL_NTOUCHIF 1 /* Xtrinsic touch sensing interface */ +# define KL_NI2C 2 /* Two I2C modules */ +# define KL_NUART 3 /* Three UARTs */ +# define KL_NSPI 2 /* Two SPI modules */ +# undef KL_NCAN /* No CAN in 64-pin chips */ +# define KL_NI2S 1 /* One I2S module */ +# undef KL_NSLCD /* One segment LCD interface (up to 25x8/29x4) */ +# define KL_NADC16 1 /* One 16-bit ADC */ +# undef KL_NADC12 /* No 12-channel ADC */ +# undef KL_NADC13 /* No 13-channel ADC */ +# undef KL_NADC15 /* No 15-channel ADC */ +# undef KL_NADC18 /* No 18-channel ADC */ +# undef KL_NPGA /* No Programmable Gain Amplifiers */ +# define KL_NCMP 1 /* One analog comparator */ +# define KL_NDAC6 1 /* Three 6-bit DAC */ +# define KL_NDAC12 1 /* Two 12-bit DAC */ +# define KL_NVREF 1 /* Voltage reference */ +# define KL_NTIMERS8 1 /* One 8 channel timers */ +# undef KL_NTIMERS12 /* No 12 channel timers */ +# undef KL_NTIMERS20 /* No 20 channel timers */ +# undef KL_NRNG /* No random number generator */ +# define KL_NRTC 1 /* Real time clock */ +# undef KL_NMMCAU /* No hardware encryption */ +# undef KL_NTAMPER /* No tamper detect */ +# undef KL_NCRC /* No CRC */ + +#else +# error "Unsupported Kinetis chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-15. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:6] of each field, bits[5:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Steps between supported priority values */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +#endif /* __ARCH_ARM_INCLUDE_KL_CHIP_H */ diff --git a/arch/arm/include/kl/irq.h b/arch/arm/include/kl/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..27ba8575f52d023f7c9324244a967c05075b6d1c --- /dev/null +++ b/arch/arm/include/kl/irq.h @@ -0,0 +1,212 @@ +/************************************************************************************ + * arch/arm/include/kinetis/irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_KL_IRQ_H +#define __ARCH_ARM_INCLUDE_KL_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* IRQ numbers **********************************************************************/ +/* The IRQ numbers corresponds directly to vector numbers and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define KL_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define KL_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define KL_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + /* Vectors 4-10: Reserved */ +#define KL_IRQ_SVCALL (11) /* Vector 11: SVC call */ + /* Vector 12-13: Reserved */ +#define KL_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define KL_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16) */ + +#define KL_IRQ_EXTINT (16) + +/* K40 Family *********************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +#if defined(CONFIG_ARCH_CHIP_MKL25Z128) || defined(CONFIG_ARCH_CHIP_MKL25Z64) + +# define KL_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */ +# define KL_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */ +# define KL_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */ +# define KL_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */ + /* Vector 20: Reserved */ +# define KL_IRQ_FTFA (21) /* Vector 21: FTFA */ +# define KL_IRQ_LVDLVW (22) /* Vector 22: LVD_LVW */ +# define KL_IRQ_LLW (23) /* Vector 23: LLW */ +# define KL_IRQ_I2C0 (24) /* Vector 24: I2C0 */ +# define KL_IRQ_I2C1 (25) /* Vector 25: I2C1 */ +# define KL_IRQ_SPI0 (26) /* Vector 26: SPI0 */ +# define KL_IRQ_SPI1 (27) /* Vector 27: SPI1 */ +# define KL_IRQ_UART0 (28) /* Vector 28: UART0 */ +# define KL_IRQ_UART1 (29) /* Vector 29: UART1 */ +# define KL_IRQ_UART2 (30) /* Vector 30: UART2 */ +# define KL_IRQ_ADC0 (31) /* Vector 31: Analog Device Converter 0 */ +# define KL_IRQ_CMP0 (32) /* Vector 32: Comparator 0 */ +# define KL_IRQ_TPM0 (33) /* Vector 33: Timer/PWM Module 0 */ +# define KL_IRQ_TPM1 (34) /* Vector 34: Timer/PWM Module 1 */ +# define KL_IRQ_TPM2 (35) /* Vector 35: Timer/PWM Module 2 */ +# define KL_IRQ_RTC (36) /* Vector 36: Realtime Clock */ +# define KL_IRQ_RTCSEC (37) /* Vector 37: Realtime Clock, seconds interrupt */ +# define KL_IRQ_PIT (38) /* Vector 38: Programmable Interrupt Timer */ + /* Vector 39: Reserved */ +# define KL_IRQ_USB0 (40) /* Vector 40: USB0 */ +# define KL_IRQ_DAC0 (41) /* Vector 41: Digital Analog Converter 0 */ +# define KL_IRQ_TSI0 (42) /* Vector 42: TSI0 */ +# define KL_IRQ_MCG (43) /* Vector 43: MCG */ +# define KL_IRQ_LPTIMER (44) /* Vector 44: Low Power Timer */ + /* Vector 45: Reserved */ +# define KL_IRQ_PORTA (46) /* Vector 46: GPIO Port A */ +# define KL_IRQ_PORTD (47) /* Vector 47: GPIO Port D */ + +/* Note that the total number of IRQ numbers supported is equal to the number of + * valid interrupt vectors. This is wasteful in that certain tables are sized by + * this value. There are only 94 valid interrupts so, potentially the numver of + * IRQs to could be reduced to 94. However, equating IRQ numbers with vector numbers + * also simplifies operations on NVIC registers and (at least in my state of mind + * now) seems to justify the waste. + */ + +# define NR_VECTORS (64) /* 64 vectors */ +# define NR_IRQS (48) /* 64 interrupts but 48 IRQ numbers */ + +#elif defined(CONFIG_ARCH_CHIP_MKL26Z128) + +# define KL_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */ +# define KL_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */ +# define KL_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */ +# define KL_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */ + /* Vector 20: Reserved */ +# define KL_IRQ_FTFA (21) /* Vector 21: FTFA */ +# define KL_IRQ_LVDLVW (22) /* Vector 22: LVD_LVW */ +# define KL_IRQ_LLW (23) /* Vector 23: LLW */ +# define KL_IRQ_I2C0 (24) /* Vector 24: I2C0 */ +# define KL_IRQ_I2C1 (25) /* Vector 25: I2C1 */ +# define KL_IRQ_SPI0 (26) /* Vector 26: SPI0 */ +# define KL_IRQ_SPI1 (27) /* Vector 27: SPI1 */ +# define KL_IRQ_UART0 (28) /* Vector 28: UART0 */ +# define KL_IRQ_UART1 (29) /* Vector 29: UART1 */ +# define KL_IRQ_UART2 (30) /* Vector 30: UART2 */ +# define KL_IRQ_ADC0 (31) /* Vector 31: Analog Device Converter 0 */ +# define KL_IRQ_CMP0 (32) /* Vector 32: Comparator 0 */ +# define KL_IRQ_TPM0 (33) /* Vector 33: Timer/PWM Module 0 */ +# define KL_IRQ_TPM1 (34) /* Vector 34: Timer/PWM Module 1 */ +# define KL_IRQ_TPM2 (35) /* Vector 35: Timer/PWM Module 2 */ +# define KL_IRQ_RTC (36) /* Vector 36: Realtime Clock */ +# define KL_IRQ_RTCSEC (37) /* Vector 37: Realtime Clock, seconds interrupt */ +# define KL_IRQ_PIT (38) /* Vector 38: Programmable Interrupt Timer */ + /* Vector 39: Reserved */ +# define KL_IRQ_USB0 (40) /* Vector 40: USB0 */ +# define KL_IRQ_DAC0 (41) /* Vector 41: Digital Analog Converter 0 */ +# define KL_IRQ_TSI0 (42) /* Vector 42: TSI0 */ +# define KL_IRQ_MCG (43) /* Vector 43: MCG */ +# define KL_IRQ_LPTIMER (44) /* Vector 44: Low Power Timer */ + /* Vector 45: Reserved */ +# define KL_IRQ_PORTA (46) /* Vector 46: GPIO Port A */ +# define KL_IRQ_PORTD (47) /* Vector 47: GPIO Port D */ + +/* Note that the total number of IRQ numbers supported is equal to the number of + * valid interrupt vectors. This is wasteful in that certain tables are sized by + * this value. There are only 94 valid interrupts so, potentially the numver of + * IRQs to could be reduced to 94. However, equating IRQ numbers with vector numbers + * also simplifies operations on NVIC registers and (at least in my state of mind + * now) seems to justify the waste. + */ + +# define NR_VECTORS (64) /* 64 vectors */ +# define NR_IRQS (48) /* 64 interrupts but 48 IRQ numbers */ + +#else + /* The interrupt vectors for other parts are defined in other documents and may or + * may not be the same as above (the family members are all very similar) This + * error just means that you have to look at the document and determine for yourself + * if the vectors are the same. + */ + +# error "No IRQ numbers for this Kinetis L part" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_KL_IRQ_H */ + diff --git a/arch/arm/include/limits.h b/arch/arm/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..c291e33ed77bc6e82eeb11418a17c3f5046f1635 --- /dev/null +++ b/arch/arm/include/limits.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/include/limits.h + * + * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_LIMITS_H +#define __ARCH_ARM_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_ARM_INCLUDE_LIMITS_H */ diff --git a/arch/arm/include/lpc11xx/chip.h b/arch/arm/include/lpc11xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..1c381df7d9607814bd9fd072b67b7cfddccdfa41 --- /dev/null +++ b/arch/arm/include/lpc11xx/chip.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/include/lpc11xx/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_LPC11XX_CHIP_H +#define __ARCH_ARM_INCLUDE_LPC11XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +#if defined(CONFIG_ARCH_CHIP_LPC1115) +# define LPC111x 1 /* LPC111x family */ +# define LPC11_FLASH_SIZE (64*1024) /* 64Kb */ +# define LPC11_SRAM_SIZE (8*1024) /* 8Kb */ +# define LPC11_CPUSRAM_SIZE (8*1024) +# undef LPC11_HAVE_BANK0 /* No AHB SRAM bank 0 */ +# undef LPC11_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC11_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC11_NUSBHOST 0 /* No USB host controller */ +# define LPC11_NUSBOTG 0 /* No USB OTG controller */ +# define LPC11_NUSBDEV 1 /* One USB device controller */ +# define LPC11_NCAN 1 /* One CAN controller */ +# define LPC11_NI2S 0 /* No I2S modules */ +# define LPC11_NDAC 0 /* No DAC module */ +#else +# error "Unsupported LPC11xx chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-31. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:6] of each field, bits[5:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_LPC11XX_CHIP_H */ diff --git a/arch/arm/include/lpc11xx/irq.h b/arch/arm/include/lpc11xx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..caac7c3e170c1d858882bbf13a32ae10bb6741fd --- /dev/null +++ b/arch/arm/include/lpc11xx/irq.h @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/include/lpc11xxx/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC11XX_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC11XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* Common Processor Exceptions (vectors 0-15) */ + +#define LPC11_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define LPC11_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define LPC11_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + /* Vectors 4-10: Reserved */ +#define LPC11_IRQ_SVCALL (11) /* Vector 11: SVC call */ + /* Vector 12-13: Reserved */ +#define LPC11_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define LPC11_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16) */ + +#define LPC11_IRQ_EXTINT (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_LPC1115) +#define LPC11_IRQ_PIO0_0 (16) /* Vector 16: PIO0_0 */ +#define LPC11_IRQ_PIO0_1 (17) /* Vector 17: PIO0_1 */ +#define LPC11_IRQ_PIO0_2 (18) /* Vector 18: PIO0_2 */ +#define LPC11_IRQ_PIO0_3 (19) /* Vector 19: PIO0_3 */ +#define LPC11_IRQ_PIO0_4 (20) /* Vector 20: PIO0_4 */ +#define LPC11_IRQ_PIO0_5 (21) /* Vector 21: PIO0_5 */ +#define LPC11_IRQ_PIO0_6 (22) /* Vector 22: PIO0_6 */ +#define LPC11_IRQ_PIO0_7 (23) /* Vector 23: PIO0_7 */ +#define LPC11_IRQ_PIO0_8 (24) /* Vector 24: PIO0_8 */ +#define LPC11_IRQ_PIO0_9 (25) /* Vector 25: PIO0_9 */ +#define LPC11_IRQ_PIO0_10 (26) /* Vector 26: PIO0_10 */ +#define LPC11_IRQ_PIO0_11 (27) /* Vector 27: PIO0_11 */ +#define LPC11_IRQ_PIO1_0 (28) /* Vector 28: PIO1_0 */ +#define LPC11_IRQ_CCAN (29) /* Vector 29: C_CAN controller for LPC11Cxx */ +#define LPC11_IRQ_SSP1 (30) /* Vector 30: SPI1/SSP1 */ +#define LPC11_IRQ_I2C0 (31) /* Vector 31: I2C0 */ +#define LPC11_IRQ_CT16B0 (32) /* Vector 32: Clock/Timer0 16 bits */ +#define LPC11_IRQ_CT16B1 (33) /* Vector 33: Clock/Timer1 16 bits */ +#define LPC11_IRQ_CT32B0 (34) /* Vector 34: Clock/Timer0 32 bits */ +#define LPC11_IRQ_CT32B1 (35) /* Vector 35: Clock/Timer1 32 bits */ +#define LPC11_IRQ_SSP0 (36) /* Vector 36: SPI0/SSP0 */ +#define LPC11_IRQ_UART (37) /* Vector 37: UART */ + /* Vector 38: Reserved */ + /* Vector 39: Reserved */ +#define LPC11_IRQ_ADC (40) /* Vector 40: Analog/Digital Converter */ +#define LPC11_IRQ_WDT (41) /* Vector 41: Watchdog timer */ +#define LPC11_IRQ_BOD (42) /* Vector 42: Brownout Detection */ + /* Vector 43: Reserved */ +#define LPC11_IRQ_PIO3 (44) /* Vector 44: PIO3 */ +#define LPC11_IRQ_PIO2 (45) /* Vector 45: PIO2 */ +#define LPC11_IRQ_PIO1 (46) /* Vector 46: PIO1 */ +#define LPC11_IRQ_PIO0 (47) /* Vector 47: PIO0 */ +#endif + +#define NR_VECTORS (64) /* 64 vectors */ +#define NR_IRQS (48) /* 64 interrupts but 48 IRQ numbers */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_LPC11XX_IRQ_H */ diff --git a/arch/arm/include/lpc17xx/chip.h b/arch/arm/include/lpc17xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..5eebd0f7bf5c4864acbdc44d0d42412ba8a31796 --- /dev/null +++ b/arch/arm/include/lpc17xx/chip.h @@ -0,0 +1,437 @@ +/************************************************************************************ + * arch/arm/include/lpc17xx/chip.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * with LPC178x support from Rommel Marcelo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_LPC17XX_CHIP_H +#define __ARCH_ARM_INCLUDE_LPC17XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +#if defined(CONFIG_ARCH_CHIP_LPC1751) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (32*1024) /* 32Kb */ +# define LPC17_SRAM_SIZE (8*1024) /* 8Kb */ +# define LPC17_CPUSRAM_SIZE (8*1024) +# undef LPC17_HAVE_BANK0 /* No AHB SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 0 /* No USB host controller */ +# define LPC17_NUSBOTG 0 /* No USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 1 /* One CAN controller */ +# define LPC17_NI2S 0 /* No I2S modules */ +# define LPC17_NDAC 0 /* No DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1752) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (64*1024) /* 65Kb */ +# define LPC17_SRAM_SIZE (16*1024) /* 16Kb */ +# define LPC17_CPUSRAM_SIZE (16*1024) +# undef LPC17_HAVE_BANK0 /* No AHB SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 0 /* No USB host controller */ +# define LPC17_NUSBOTG 0 /* No USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 1 /* One CAN controller */ +# define LPC17_NI2S 0 /* No I2S modules */ +# define LPC17_NDAC 0 /* No DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1754) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (128*1024) /* 128Kb */ +# define LPC17_SRAM_SIZE (32*1024) /* 32Kb */ +# define LPC17_CPUSRAM_SIZE (16*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 1 /* One CAN controller */ +# define LPC17_NI2S 0 /* No I2S modules */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1756) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (32*1024) /* 32Kb */ +# define LPC17_CPUSRAM_SIZE (16*1024) +# define LPC17_HAVE_BANK0 1 /* No AHB SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1758) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1759) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1764) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (128*1024) /* 128Kb */ +# define LPC17_SRAM_SIZE (32*1024) /* 32Kb */ +# define LPC17_CPUSRAM_SIZE (16*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 0 /* No USB host controller */ +# define LPC17_NUSBOTG 0 /* No USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 0 /* No I2S modules */ +# define LPC17_NDAC 0 /* No DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1765) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1766) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1767) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 0 /* No USB host controller */ +# define LPC17_NUSBOTG 0 /* No USB OTG controller */ +# define LPC17_NUSBDEV 0 /* No USB device controller */ +# define LPC17_NCAN 0 /* No CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1769) || defined(CONFIG_ARCH_CHIP_LPC1768) +# define LPC176x 1 /* LPC175/6 family */ +# undef LPC178x /* Not LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (64*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have AHB SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have AHB SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_NCAN 2 /* Two CAN controllers */ +# define LPC17_NI2S 1 /* One I2S module */ +# define LPC17_NDAC 1 /* One DAC module */ +#elif defined(CONFIG_ARCH_CHIP_LPC1773) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (128*1024) /* 128Kb */ +# define LPC17_SRAM_SIZE (40*1024) /* 40Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* No Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# undef LPC17_NUSBHOST /* No USB host controller */ +# undef LPC17_NUSBOTG /* No USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# define LPC17_HAVE_SPIFI 1 /* Have SPIFI interface */ +# undef LPC17_HAVE_LCD /* No LCD controller */ +# undef LPC17_HAVE_QEI /* No QEI interface */ +# undef LPC17_HAVE_SD /* No SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1774) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (128*1024) /* 128Kb */ +# define LPC17_SRAM_SIZE (40*1024) /* 40Kb */ +# define LPC17_CPUSRAM_SIZE (32*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0*/ +# undef LPC17_HAVE_BANK1 /* Have Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# undef LPC17_NUSBHOST /* One USB host controller */ +# undef LPC17_NUSBOTG /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# undef LPC17_HAVE_LCD /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1776) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (80*1024) /* 80Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* Have Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# undef LPC17_HAVE_LCD /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1777) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (96*1024) /* 96Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have Peripheral SRAM bank 1 */ +# undef LPC17_NETHCONTROLLERS /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# undef LPC17_HAVE_LCD /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1778) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (96*1024) /* 64Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# undef LPC17_HAVE_LCD /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1785) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (80*1024) /* 80Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* Have Peripheral SRAM bank 1 */ +# undef LPC17_NETHCONTROLLERS /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# define LPC17_HAVE_LCD 1 /* One LCD controller */ +# undef LPC17_HAVE_QEI /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1786) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (256*1024) /* 256Kb */ +# define LPC17_SRAM_SIZE (80*1024) /* 80Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# undef LPC17_HAVE_BANK1 /* Have Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# define LPC17_HAVE_LCD 1 /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1787) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (96*1024) /* 96Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have Peripheral SRAM bank 1 */ +# undef LPC17_NETHCONTROLLERS /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# define LPC17_HAVE_LCD 1 /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#elif defined(CONFIG_ARCH_CHIP_LPC1788) +# undef LPC176x /* Not LPC175/6 family */ +# define LPC178x 1 /* LPC177/8 family */ +# define LPC17_FLASH_SIZE (512*1024) /* 512Kb */ +# define LPC17_SRAM_SIZE (96*1024) /* 96Kb */ +# define LPC17_CPUSRAM_SIZE (64*1024) +# define LPC17_HAVE_BANK0 1 /* Have Peripheral SRAM bank 0 */ +# define LPC17_HAVE_BANK1 1 /* Have Peripheral SRAM bank 1 */ +# define LPC17_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define LPC17_NUSBHOST 1 /* One USB host controller */ +# define LPC17_NUSBOTG 1 /* One USB OTG controller */ +# define LPC17_NUSBDEV 1 /* One USB device controller */ +# undef LPC17_HAVE_SPIFI /* Have SPIFI interface */ +# define LPC17_HAVE_LCD 1 /* One LCD controller */ +# define LPC17_HAVE_QEI 1 /* One QEI interface */ +# define LPC17_HAVE_SD 1 /* One SD controller */ +#else +# error "Unsupported LPC17xx chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-31. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:3] of each field, bits[2:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf8 /* All bits[7:3] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x08 /* Five bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_LPC17XX_CHIP_H */ diff --git a/arch/arm/include/lpc17xx/irq.h b/arch/arm/include/lpc17xx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..6af683225ca64dbcad3a639e1f64714018f68976 --- /dev/null +++ b/arch/arm/include/lpc17xx/irq.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/include/lpc17xxx/irq.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC17XX_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC17XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* Common Processor Exceptions (vectors 0-15) */ + +#define LPC17_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define LPC17_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define LPC17_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define LPC17_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define LPC17_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define LPC17_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define LPC17_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define LPC17_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define LPC17_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define LPC17_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16) */ + +#define LPC17_IRQ_EXTINT (16) /* Vector number of the first external interrupt */ + +/* Family Specfic Interrupts */ + +#if defined(LPC176x) /* LPC175/6 family */ +# include +#elif defined(LPC178x) /* LPC177/8 family */ +# include +#else +# error "Unknown LPC17xx family" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_LPC17XX_IRQ_H */ diff --git a/arch/arm/include/lpc17xx/lpc176x_irq.h b/arch/arm/include/lpc17xx/lpc176x_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..248c5c47d66070842bed5b0dda851ec236a2b7dd --- /dev/null +++ b/arch/arm/include/lpc17xx/lpc176x_irq.h @@ -0,0 +1,246 @@ +/**************************************************************************** + * arch/lpc17xx/lpc176x_irq.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC17XX_LPC176X_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC17XX_LPC176X_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define LPC17_IRQ_WDT (LPC17_IRQ_EXTINT+0) /* WDT Watchdog Interrupt (WDINT) */ +#define LPC17_IRQ_TMR0 (LPC17_IRQ_EXTINT+1) /* Timer 0 Match 0 - 1 (MR0, MR1) + * Capture 0 - 1 (CR0, CR1) */ +#define LPC17_IRQ_TMR1 (LPC17_IRQ_EXTINT+2) /* Timer 1 Match 0 - 2 (MR0, MR1, MR2) + * Capture 0 - 1 (CR0, CR1) */ +#define LPC17_IRQ_TMR2 (LPC17_IRQ_EXTINT+3) /* Timer 2 Match 0-3 + * Capture 0-1 */ +#define LPC17_IRQ_TMR3 (LPC17_IRQ_EXTINT+4) /* Timer 3 Match 0-3 + * Capture 0-1 */ +#define LPC17_IRQ_UART0 (LPC17_IRQ_EXTINT+5) /* UART 0 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART1 (LPC17_IRQ_EXTINT+6) /* UART 1 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * Modem Control Change + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART2 (LPC17_IRQ_EXTINT+7) /* UART 2 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART3 (LPC17_IRQ_EXTINT+8) /* UART 3 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_PWM1 (LPC17_IRQ_EXTINT+9) /* PWM1 Match 0 - 6 of PWM1 + * Capture 0-1 of PWM1 */ +#define LPC17_IRQ_I2C0 (LPC17_IRQ_EXTINT+10) /* I2C0 SI (state change) */ +#define LPC17_IRQ_I2C1 (LPC17_IRQ_EXTINT+11) /* I2C1 SI (state change) */ +#define LPC17_IRQ_I2C2 (LPC17_IRQ_EXTINT+12) /* I2C2 SI (state change) */ +#define LPC17_IRQ_SPIF (LPC17_IRQ_EXTINT+13) /* SPI SPI Interrupt Flag (SPIF) + * Mode Fault (MODF) */ +#define LPC17_IRQ_SSP0 (LPC17_IRQ_EXTINT+14) /* SSP0 Tx FIFO half empty of SSP0 + * Rx FIFO half full of SSP0 + * Rx Timeout of SSP0 + * Rx Overrun of SSP0 */ +#define LPC17_IRQ_SSP1 (LPC17_IRQ_EXTINT+15) /* SSP 1 Tx FIFO half empty + * Rx FIFO half full + * Rx Timeout + * Rx Overrun */ +#define LPC17_IRQ_PLL0 (LPC17_IRQ_EXTINT+16) /* PLL0 (Main PLL) PLL0 Lock (PLOCK0) */ +#define LPC17_IRQ_RTC (LPC17_IRQ_EXTINT+17) /* RTC Counter Increment (RTCCIF) + * Alarm (RTCALF) */ +#define LPC17_IRQ_EINT0 (LPC17_IRQ_EXTINT+18) /* External Interrupt 0 (EINT0) */ +#define LPC17_IRQ_EINT1 (LPC17_IRQ_EXTINT+19) /* External Interrupt 1 (EINT1) */ +#define LPC17_IRQ_EINT2 (LPC17_IRQ_EXTINT+20) /* External Interrupt 2 (EINT2) */ +#define LPC17_IRQ_EINT3 (LPC17_IRQ_EXTINT+21) /* External Interrupt 3 (EINT3) + * Note: EINT3 channel is shared with GPIO interrupts */ +#define LPC17_IRQ_ADC (LPC17_IRQ_EXTINT+22) /* ADC A/D Converter end of conversion */ +#define LPC17_IRQ_BOD (LPC17_IRQ_EXTINT+23) /* BOD Brown Out detect */ +#define LPC17_IRQ_USB (LPC17_IRQ_EXTINT+24) /* USB USB_INT_REQ_LP, USB_INT_REQ_HP, + * USB_INT_REQ_DMA */ +#define LPC17_IRQ_CAN (LPC17_IRQ_EXTINT+25) /* CAN CAN Common, CAN 0 Tx, CAN 0 Rx, + * CAN 1 Tx, CAN 1 Rx */ +#define LPC17_IRQ_GPDMA (LPC17_IRQ_EXTINT+26) /* GPDMA IntStatus of DMA channel 0, + * IntStatus of DMA channel 1 */ +#define LPC17_IRQ_I2S (LPC17_IRQ_EXTINT+27) /* I2S irq, dmareq1, dmareq2 */ +#define LPC17_IRQ_ETH (LPC17_IRQ_EXTINT+28) /* Ethernet WakeupInt, SoftInt, TxDoneInt, + * TxFinishedInt, TxErrorInt,* TxUnderrunInt, + * RxDoneInt, RxFinishedInt, RxErrorInt, + * RxOverrunInt */ +#define LPC17_IRQ_RITINT (LPC17_IRQ_EXTINT+29) /* Repetitive Interrupt Timer (RITINT) */ +#define LPC17_IRQ_MCPWM (LPC17_IRQ_EXTINT+30) /* Motor Control PWM IPER[2:0], IPW[2:0], + * ICAP[2:0], FES */ +#define LPC17_IRQ_QEI (LPC17_IRQ_EXTINT+31) /* Quadrature Encoder INX_Int, TIM_Int, VELC_Int, + * DIR_Int, ERR_Int, ENCLK_Int, POS0_Int, POS1_Int + * POS2_Int, REV_Int, POS0REV_Int, OS1REV_Int, + * POS2REV_Int */ +#define LPC17_IRQ_PLL1 (LPC17_IRQ_EXTINT+32) /* PLL1 (USB PLL) PLL1 Lock (PLOCK1) */ +#define LPC17_IRQ_USBACT (LPC17_IRQ_EXTINT+33) /* USB Activity Interrupt USB_NEED_CLK */ +#define LPC17_IRQ_CANACT (LPC17_IRQ_EXTINT+34) /* CAN Activity Interrupt CAN1WAKE, CAN2WAKE */ +#define LPC17_IRQ_NEXTINT (35) +#define LPC17_IRQ_NIRQS (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT) + +/* GPIO interrupts. The LPC17xx supports several interrupts on ports 0 and + * 2 (only). We go through some special efforts to keep the number of IRQs + * to a minimum in this sparse interrupt case. + * + * 28 interrupts on Port 0: p0.0 - p0.11, p0.15-p0.30 + * 14 interrupts on Port 2: p2.0 - p2.13 + * -- + * 42 + */ + +#ifdef CONFIG_GPIO_IRQ +# define LPC17_VALID_GPIOINT0 (0x7fff8ffful) /* GPIO port 0 interrupt set */ +# define LPC17_VALID_GPIOINT2 (0x00003ffful) /* GPIO port 2 interrupt set */ + + /* Set 1: 12 interrupts p0.0-p0.11 */ + +# define LPC17_VALID_GPIOINT0L (0x00000ffful) +# define LPC17_VALID_SHIFT0L (0) +# define LPC17_VALID_FIRST0L (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT) + +# define LPC17_IRQ_P0p0 (LPC17_VALID_FIRST0L+0) +# define LPC17_IRQ_P0p1 (LPC17_VALID_FIRST0L+1) +# define LPC17_IRQ_P0p2 (LPC17_VALID_FIRST0L+2) +# define LPC17_IRQ_P0p3 (LPC17_VALID_FIRST0L+3) +# define LPC17_IRQ_P0p4 (LPC17_VALID_FIRST0L+4) +# define LPC17_IRQ_P0p5 (LPC17_VALID_FIRST0L+5) +# define LPC17_IRQ_P0p6 (LPC17_VALID_FIRST0L+6) +# define LPC17_IRQ_P0p7 (LPC17_VALID_FIRST0L+7) +# define LPC17_IRQ_P0p8 (LPC17_VALID_FIRST0L+8) +# define LPC17_IRQ_P0p9 (LPC17_VALID_FIRST0L+9) +# define LPC17_IRQ_P0p10 (LPC17_VALID_FIRST0L+10) +# define LPC17_IRQ_P0p11 (LPC17_VALID_FIRST0L+11) +# define LPC17_VALID_NIRQS0L (12) + + /* Set 2: 16 interrupts p0.15-p0.30 */ + +# define LPC17_VALID_GPIOINT0H (0x7fff8000ull) +# define LPC17_VALID_SHIFT0H (15) +# define LPC17_VALID_FIRST0H (LPC17_VALID_FIRST0L+LPC17_VALID_NIRQS0L) + +# define LPC17_IRQ_P0p15 (LPC17_VALID_FIRST0H+0) +# define LPC17_IRQ_P0p16 (LPC17_VALID_FIRST0H+1) +# define LPC17_IRQ_P0p17 (LPC17_VALID_FIRST0H+2) +# define LPC17_IRQ_P0p18 (LPC17_VALID_FIRST0H+3) +# define LPC17_IRQ_P0p19 (LPC17_VALID_FIRST0H+4) +# define LPC17_IRQ_P0p20 (LPC17_VALID_FIRST0H+5) +# define LPC17_IRQ_P0p21 (LPC17_VALID_FIRST0H+6) +# define LPC17_IRQ_P0p22 (LPC17_VALID_FIRST0H+7) +# define LPC17_IRQ_P0p23 (LPC17_VALID_FIRST0H+8) +# define LPC17_IRQ_P0p24 (LPC17_VALID_FIRST0H+9) +# define LPC17_IRQ_P0p25 (LPC17_VALID_FIRST0H+10) +# define LPC17_IRQ_P0p26 (LPC17_VALID_FIRST0H+11) +# define LPC17_IRQ_P0p27 (LPC17_VALID_FIRST0H+12) +# define LPC17_IRQ_P0p28 (LPC17_VALID_FIRST0H+13) +# define LPC17_IRQ_P0p29 (LPC17_VALID_FIRST0H+14) +# define LPC17_IRQ_P0p30 (LPC17_VALID_FIRST0H+15) +# define LPC17_VALID_NIRQS0H (16) + + /* Set 3: 14 interrupts p2.0-p2.13 */ + +# define LPC17_VALID_GPIOINT2 (0x00003ffful) +# define LPC17_VALID_SHIFT2 (0) +# define LPC17_VALID_FIRST2 (LPC17_VALID_FIRST0H+LPC17_VALID_NIRQS0H) + +# define LPC17_IRQ_P2p0 (LPC17_VALID_FIRST2+0) +# define LPC17_IRQ_P2p1 (LPC17_VALID_FIRST2+1) +# define LPC17_IRQ_P2p2 (LPC17_VALID_FIRST2+2) +# define LPC17_IRQ_P2p3 (LPC17_VALID_FIRST2+3) +# define LPC17_IRQ_P2p4 (LPC17_VALID_FIRST2+4) +# define LPC17_IRQ_P2p5 (LPC17_VALID_FIRST2+5) +# define LPC17_IRQ_P2p6 (LPC17_VALID_FIRST2+6) +# define LPC17_IRQ_P2p7 (LPC17_VALID_FIRST2+7) +# define LPC17_IRQ_P2p8 (LPC17_VALID_FIRST2+8) +# define LPC17_IRQ_P2p9 (LPC17_VALID_FIRST2+9) +# define LPC17_IRQ_P2p10 (LPC17_VALID_FIRST2+10) +# define LPC17_IRQ_P2p11 (LPC17_VALID_FIRST2+11) +# define LPC17_IRQ_P2p12 (LPC17_VALID_FIRST2+12) +# define LPC17_IRQ_P2p13 (LPC17_VALID_FIRST2+13) +# define LPC17_VALID_NIRQS2 (14) +# define LPC17_NGPIOAIRQS (LPC17_VALID_NIRQS0L+LPC17_VALID_NIRQS0H+LPC17_VALID_NIRQS2) +#else +# define LPC17_NGPIOAIRQS (0) +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS LPC17_IRQ_NIRQS +#define NR_IRQS (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT+LPC17_NGPIOAIRQS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_LPC17XX_LPC176X_IRQ_H */ + diff --git a/arch/arm/include/lpc17xx/lpc178x_irq.h b/arch/arm/include/lpc17xx/lpc178x_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..76c749045282f80dac2bf2be47d93fee0f991c99 --- /dev/null +++ b/arch/arm/include/lpc17xx/lpc178x_irq.h @@ -0,0 +1,292 @@ +/**************************************************************************** + * arch/arm/include/lpc17xxx/lpc178x_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC17XX_LPC178X_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC17XX_LPC178X_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define LPC17_IRQ_WDT (LPC17_IRQ_EXTINT+0) /* WDT Watchdog Interrupt (WDINT) */ +#define LPC17_IRQ_TMR0 (LPC17_IRQ_EXTINT+1) /* Timer 0 Match 0 - 1 (MR0, MR1) + * Capture 0 - 1 (CR0, CR1) */ +#define LPC17_IRQ_TMR1 (LPC17_IRQ_EXTINT+2) /* Timer 1 Match 0 - 2 (MR0, MR1, MR2) + * Capture 0 - 1 (CR0, CR1) */ +#define LPC17_IRQ_TMR2 (LPC17_IRQ_EXTINT+3) /* Timer 2 Match 0-3 + * Capture 0-1 */ +#define LPC17_IRQ_TMR3 (LPC17_IRQ_EXTINT+4) /* Timer 3 Match 0-3 + * Capture 0-1 */ +#define LPC17_IRQ_UART0 (LPC17_IRQ_EXTINT+5) /* UART 0 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART1 (LPC17_IRQ_EXTINT+6) /* UART 1 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * Modem Control Change + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART2 (LPC17_IRQ_EXTINT+7) /* UART 2 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_UART3 (LPC17_IRQ_EXTINT+8) /* UART 3 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_PWM1 (LPC17_IRQ_EXTINT+9) /* PWM1 Match 0 - 6 of PWM1 + * Capture 0-1 of PWM1 */ +#define LPC17_IRQ_I2C0 (LPC17_IRQ_EXTINT+10) /* I2C0 SI (state change) */ +#define LPC17_IRQ_I2C1 (LPC17_IRQ_EXTINT+11) /* I2C1 SI (state change) */ +#define LPC17_IRQ_I2C2 (LPC17_IRQ_EXTINT+12) /* I2C2 SI (state change) */ +#define LPC17_IRQ_RESERVED29 (LPC17_IRQ_EXTINT+13) /* Unused */ +#define LPC17_IRQ_SSP0 (LPC17_IRQ_EXTINT+14) /* SSP0 Tx FIFO half empty of SSP0 + * Rx FIFO half full of SSP0 + * Rx Timeout of SSP0 + * Rx Overrun of SSP0 */ +#define LPC17_IRQ_SSP1 (LPC17_IRQ_EXTINT+15) /* SSP 1 Tx FIFO half empty + * Rx FIFO half full + * Rx Timeout + * Rx Overrun */ +#define LPC17_IRQ_PLL0 (LPC17_IRQ_EXTINT+16) /* PLL0 (Main PLL) PLL0 Lock (PLOCK0) */ +#define LPC17_IRQ_RTC (LPC17_IRQ_EXTINT+17) /* RTC Counter Increment (RTCCIF) + * Alarm (RTCALF) */ +#define LPC17_IRQ_EINT0 (LPC17_IRQ_EXTINT+18) /* External Interrupt 0 (EINT0) */ +#define LPC17_IRQ_EINT1 (LPC17_IRQ_EXTINT+19) /* External Interrupt 1 (EINT1) */ +#define LPC17_IRQ_EINT2 (LPC17_IRQ_EXTINT+20) /* External Interrupt 2 (EINT2) */ +#define LPC17_IRQ_EINT3 (LPC17_IRQ_EXTINT+21) /* External Interrupt 3 (EINT3) + * Note: EINT3 channel is shared with GPIO interrupts */ +#define LPC17_IRQ_ADC (LPC17_IRQ_EXTINT+22) /* ADC A/D Converter end of conversion */ +#define LPC17_IRQ_BOD (LPC17_IRQ_EXTINT+23) /* BOD Brown Out detect */ +#define LPC17_IRQ_USB (LPC17_IRQ_EXTINT+24) /* USB USB_INT_REQ_LP, USB_INT_REQ_HP, + * USB_INT_REQ_DMA */ +#define LPC17_IRQ_CAN (LPC17_IRQ_EXTINT+25) /* CAN CAN Common, CAN 0 Tx, CAN 0 Rx, + * CAN 1 Tx, CAN 1 Rx */ +#define LPC17_IRQ_GPDMA (LPC17_IRQ_EXTINT+26) /* GPDMA IntStatus of DMA channel 0, + * IntStatus of DMA channel 1 */ +#define LPC17_IRQ_I2S (LPC17_IRQ_EXTINT+27) /* I2S irq, dmareq1, dmareq2 */ +#define LPC17_IRQ_ETH (LPC17_IRQ_EXTINT+28) /* Ethernet WakeupInt, SoftInt, TxDoneInt, + * TxFinishedInt, TxErrorInt,* TxUnderrunInt, + * RxDoneInt, RxFinishedInt, RxErrorInt, + * RxOverrunInt */ +#define LPC17_IRQ_MCI (LPC17_IRQ_EXTINT+29) /* MCI SD Card Interface */ +#define LPC17_IRQ_MCPWM (LPC17_IRQ_EXTINT+30) /* Motor Control PWM IPER[2:0], IPW[2:0], + * ICAP[2:0], FES */ +#define LPC17_IRQ_QEI (LPC17_IRQ_EXTINT+31) /* Quadrature Encoder INX_Int, TIM_Int, VELC_Int, + * DIR_Int, ERR_Int, ENCLK_Int, POS0_Int, POS1_Int + * POS2_Int, REV_Int, POS0REV_Int, OS1REV_Int, + * POS2REV_Int */ +#define LPC17_IRQ_PLL1 (LPC17_IRQ_EXTINT+32) /* PLL1 (USB PLL) PLL1 Lock (PLOCK1) */ +#define LPC17_IRQ_USBACT (LPC17_IRQ_EXTINT+33) /* USB Activity Interrupt USB_NEED_CLK */ +#define LPC17_IRQ_CANACT (LPC17_IRQ_EXTINT+34) /* CAN Activity Interrupt CAN1WAKE, CAN2WAKE */ +#define LPC17_IRQ_UART4 (LPC17_IRQ_EXTINT+35) /* UART 4 Rx Line Status (RLS) + * Transmit Holding Register Empty (THRE) + * Rx Data Available (RDA) + * Character Time-out Indicator (CTI) + * End of Auto-Baud (ABEO) + * Auto-Baud Time-Out (ABTO) */ +#define LPC17_IRQ_SSP2 (LPC17_IRQ_EXTINT+36) /* SSP2 Tx FIFO half empty of SSP2 + * Rx FIFO half full of SSP2 + * Rx Timeout of SSP2 + * Rx Overrun of SSP2 */ +#define LPC17_IRQ_LCD (LPC17_IRQ_EXTINT+37) /* LCD interrupt + * BER, VCompI, LNBUI, FUFI, CrsrI */ +#define LPC17_IRQ_GPIO (LPC17_IRQ_EXTINT+38) /* GPIO Interrupt + * P0xREI, P2xREI, P0xFEI, P2xFEI */ +#define LPC17_IRQ_PWM0 (LPC17_IRQ_EXTINT+39) /* PWM0 Match 0 - 6 of PWM0 + * Capture 0-1 of PWM0 */ +#define LPC17_IRQ_EEPROM (LPC17_IRQ_EXTINT+40) /* EEPROM Interrupt + * EE_PROG_DONE, EE_RW_DONE */ +#define LPC17_IRQ_NEXTINT (40) +#define LPC17_IRQ_NIRQS (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT) + +/* GPIO interrupts. The LPC177x_8x supports several interrupts on ports 0 and + * 2 (only). We go through some special efforts to keep the number of IRQs + * to a minimum in this sparse interrupt case. + * + * 31 interrupts on Port 0: p0.0 - p0.30 + * 31 interrupts on Port 2: p2.0 - p2.30 + * -- + * 42 + */ + +#ifdef CONFIG_GPIO_IRQ +# define LPC17_VALID_GPIOINT0 (0xfffffffful) /* GPIO port 0 interrupt set */ +# define LPC17_VALID_GPIOINT2 (0xfffffffful) /* GPIO port 2 interrupt set */ + + /* Set 1: 16 interrupts p0.0-p0.15 */ + +# define LPC17_VALID_SHIFT0L (0) +# define LPC17_VALID_FIRST0L (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT) + +# define LPC17_IRQ_P0p0 (LPC17_VALID_FIRST0L+0) +# define LPC17_IRQ_P0p1 (LPC17_VALID_FIRST0L+1) +# define LPC17_IRQ_P0p2 (LPC17_VALID_FIRST0L+2) +# define LPC17_IRQ_P0p3 (LPC17_VALID_FIRST0L+3) +# define LPC17_IRQ_P0p4 (LPC17_VALID_FIRST0L+4) +# define LPC17_IRQ_P0p5 (LPC17_VALID_FIRST0L+5) +# define LPC17_IRQ_P0p6 (LPC17_VALID_FIRST0L+6) +# define LPC17_IRQ_P0p7 (LPC17_VALID_FIRST0L+7) +# define LPC17_IRQ_P0p8 (LPC17_VALID_FIRST0L+8) +# define LPC17_IRQ_P0p9 (LPC17_VALID_FIRST0L+9) +# define LPC17_IRQ_P0p10 (LPC17_VALID_FIRST0L+10) +# define LPC17_IRQ_P0p11 (LPC17_VALID_FIRST0L+11) +# define LPC17_IRQ_P0p12 (LPC17_VALID_FIRST0L+12) +# define LPC17_IRQ_P0p13 (LPC17_VALID_FIRST0L+13) +# define LPC17_IRQ_P0p14 (LPC17_VALID_FIRST0L+14) +# define LPC17_IRQ_P0p15 (LPC17_VALID_FIRST0L+15) +# define LPC17_VALID_NIRQS0L (16) + + /* Set 2: 16 interrupts p0.16-p0.31 */ + +# define LPC17_VALID_SHIFT0H (16) +# define LPC17_VALID_FIRST0H (LPC17_VALID_FIRST0L+LPC17_VALID_NIRQS0L) + +# define LPC17_IRQ_P0p16 (LPC17_VALID_FIRST0H+0) +# define LPC17_IRQ_P0p17 (LPC17_VALID_FIRST0H+1) +# define LPC17_IRQ_P0p18 (LPC17_VALID_FIRST0H+2) +# define LPC17_IRQ_P0p19 (LPC17_VALID_FIRST0H+3) +# define LPC17_IRQ_P0p20 (LPC17_VALID_FIRST0H+4) +# define LPC17_IRQ_P0p21 (LPC17_VALID_FIRST0H+5) +# define LPC17_IRQ_P0p22 (LPC17_VALID_FIRST0H+6) +# define LPC17_IRQ_P0p23 (LPC17_VALID_FIRST0H+7) +# define LPC17_IRQ_P0p24 (LPC17_VALID_FIRST0H+8) +# define LPC17_IRQ_P0p25 (LPC17_VALID_FIRST0H+9) +# define LPC17_IRQ_P0p26 (LPC17_VALID_FIRST0H+10) +# define LPC17_IRQ_P0p27 (LPC17_VALID_FIRST0H+11) +# define LPC17_IRQ_P0p28 (LPC17_VALID_FIRST0H+12) +# define LPC17_IRQ_P0p29 (LPC17_VALID_FIRST0H+13) +# define LPC17_IRQ_P0p30 (LPC17_VALID_FIRST0H+14) +# define LPC17_IRQ_P0p31 (LPC17_VALID_FIRST0H+15) +# define LPC17_VALID_NIRQS0H (16) + + /* Set 3: 16 interrupts p2.0-p2.15 */ + +# define LPC17_VALID_SHIFT2L (0) +# define LPC17_VALID_FIRST2L (LPC17_VALID_FIRST0H+LPC17_VALID_NIRQS0H) + +# define LPC17_IRQ_P2p0 (LPC17_VALID_FIRST2L+0) +# define LPC17_IRQ_P2p1 (LPC17_VALID_FIRST2L+1) +# define LPC17_IRQ_P2p2 (LPC17_VALID_FIRST2L+2) +# define LPC17_IRQ_P2p3 (LPC17_VALID_FIRST2L+3) +# define LPC17_IRQ_P2p4 (LPC17_VALID_FIRST2L+4) +# define LPC17_IRQ_P2p5 (LPC17_VALID_FIRST2L+5) +# define LPC17_IRQ_P2p6 (LPC17_VALID_FIRST2L+6) +# define LPC17_IRQ_P2p7 (LPC17_VALID_FIRST2L+7) +# define LPC17_IRQ_P2p8 (LPC17_VALID_FIRST2L+8) +# define LPC17_IRQ_P2p9 (LPC17_VALID_FIRST2L+9) +# define LPC17_IRQ_P2p10 (LPC17_VALID_FIRST2L+10) +# define LPC17_IRQ_P2p11 (LPC17_VALID_FIRST2L+11) +# define LPC17_IRQ_P2p12 (LPC17_VALID_FIRST2L+12) +# define LPC17_IRQ_P2p13 (LPC17_VALID_FIRST2L+13) +# define LPC17_IRQ_P2p14 (LPC17_VALID_FIRST2L+14) +# define LPC17_IRQ_P2p15 (LPC17_VALID_FIRST2L+15) +# define LPC17_VALID_NIRQS2L (16) + + /* Set 4: 16 interrupts p2.16 - p2.31 */ + +# define LPC17_VALID_SHIFT2H (16) +# define LPC17_VALID_FIRST2H (LPC17_VALID_FIRST2L+LPC17_VALID_NIRQS2L) + +# define LPC17_IRQ_P2p16 (LPC17_VALID_FIRST2H+0) +# define LPC17_IRQ_P2p17 (LPC17_VALID_FIRST2H+1) +# define LPC17_IRQ_P2p18 (LPC17_VALID_FIRST2H+2) +# define LPC17_IRQ_P2p19 (LPC17_VALID_FIRST2H+3) +# define LPC17_IRQ_P2p20 (LPC17_VALID_FIRST2H+4) +# define LPC17_IRQ_P2p21 (LPC17_VALID_FIRST2H+5) +# define LPC17_IRQ_P2p22 (LPC17_VALID_FIRST2H+6) +# define LPC17_IRQ_P2p23 (LPC17_VALID_FIRST2H+7) +# define LPC17_IRQ_P2p24 (LPC17_VALID_FIRST2H+8) +# define LPC17_IRQ_P2p25 (LPC17_VALID_FIRST2H+9) +# define LPC17_IRQ_P2p26 (LPC17_VALID_FIRST2H+10) +# define LPC17_IRQ_P2p27 (LPC17_VALID_FIRST2H+11) +# define LPC17_IRQ_P2p28 (LPC17_VALID_FIRST2H+12) +# define LPC17_IRQ_P2p29 (LPC17_VALID_FIRST2H+13) +# define LPC17_IRQ_P2p30 (LPC17_VALID_FIRST2H+14) +# define LPC17_IRQ_P2p31 (LPC17_VALID_FIRST2H+15) +# define LPC17_VALID_NIRQS2H (16) + +# define LPC17_NGPIOAIRQS (LPC17_VALID_NIRQS0L+LPC17_VALID_NIRQS0H+LPC17_VALID_NIRQS2L+LPC17_VALID_NIRQS2H) +#else +# define LPC17_NGPIOAIRQS (0) +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS LPC17_IRQ_NIRQS +#define NR_IRQS (LPC17_IRQ_EXTINT+LPC17_IRQ_NEXTINT+LPC17_NGPIOAIRQS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_LPC17XX_LPC178X_IRQ_H */ + diff --git a/arch/arm/include/lpc214x/irq.h b/arch/arm/include/lpc214x/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..a4737c38d4bade9651ecb5304accf205dd9ae6bf --- /dev/null +++ b/arch/arm/include/lpc214x/irq.h @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/lpc214x/irq.h + * + * Copyright (C) 2007, 2008, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_LPC214X_IRQ_H +#define __ARCH_LPC214X_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LPC214X Interrupts */ + +#define LPC214X_WDT_IRQ 0 /* Watchdog */ +#define LPC214X_RESERVED_IRQ 1 /* SWI only */ +#define LPC214X_DBGCOMMRX_IRQ 2 /* Embedded debug */ +#define LPC214X_DBGCOMMTX_IRQ 3 /* Embedded debug */ +#define LPC214X_TIMER0_IRQ 4 /* Timer 0 */ +#define LPC214X_TIMER1_IRQ 5 /* Timer 1 */ +#define LPC214X_UART0_IRQ 6 /* UART 0 */ +#define LPC214X_UART1_IRQ 7 /* UART 1 */ +#define LPC214X_PWM0_IRQ 8 /* PWM 0 */ +#define LPC214X_I2C0_IRQ 9 /* I2C 0 */ +#define LPC214X_SPI0_IRQ 10 /* SPI 0 */ +#define LPC214X_SPI1_IRQ 11 /* SPI 1 */ +#define LPC214X_PLL_IRQ 12 /* PLL Lock IRQ */ +#define LPC214X_RTC_IRQ 13 /* Real Time Clock */ +#define LPC214X_EINT0_IRQ 14 /* External interrupt 0 */ +#define LPC214X_EINT1_IRQ 15 /* External interrupt 1 */ +#define LPC214X_EINT2_IRQ 16 /* External interrupt 2 */ +#define LPC214X_EINT3_IRQ 17 /* External interrupt 3 */ +#define LPC214X_ADC0_IRQ 18 /* ADC 0 */ +#define LPC214X_I2C1_IRQ 19 /* I2C 1 */ +#define LPC214X_BOD_IRQ 20 /* Brown Out Detect */ +#define LPC214X_ADC1_IRQ 21 /* ADC 1 */ +#define LPC214X_USB_IRQ 22 /* USB */ + +#define LPC214X_IRQ_SYSTIMER LPC214X_TIMER0_IRQ +#define NR_IRQS 23 + +/* There are 16 vectored interrupts. If vectored interrupts are enabled, the + * following will be used by the system. + */ + +#define LPC214X_SYSTIMER_VEC 0 /* System timer */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_attach_vector(int irq, int vector, vic_vector_t handler); +void up_detach_vector(int vector); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_LPC214X_IRQ_H */ + diff --git a/arch/arm/include/lpc2378/irq.h b/arch/arm/include/lpc2378/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..18ef58604b737fa269dc9dbba6febcf9dab137ba --- /dev/null +++ b/arch/arm/include/lpc2378/irq.h @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/lpc2378/irq.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_LPC2378_IRQ_H +#define __ARCH_LPC2378_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LPC2378 Interrupts */ + +#define WDT_IRQ 0 /* Watchdog */ +#define RESERVED_IRQ 1 /* SWI only */ +#define DBGCOMMRX_IRQ 2 /* Embedded debug */ +#define DBGCOMMTX_IRQ 3 /* Embedded debug */ +#define TIMER0_IRQ 4 /* Timer 0 */ +#define TIMER1_IRQ 5 /* Timer 1 */ +#define UART0_IRQ 6 /* UART 0 */ +#define UART1_IRQ 7 /* UART 1 */ +#define PWM0_IRQ 8 /* PWM 0 */ +#define I2C0_IRQ 9 /* I2C 0 */ +#define SPI0_IRQ 10 /* SPI 0 */ +#define SSP0_IRQ 10 /* SSP 0 */ +#define SSP1_IRQ 11 /* SSP 1 */ +#define PLL_IRQ 12 /* PLL Lock IRQ */ +#define RTC_IRQ 13 /* Real Time Clock */ +#define EINT0_IRQ 14 /* External interrupt 0 */ +#define EINT1_IRQ 15 /* External interrupt 1 */ +#define EINT2_IRQ 16 /* External interrupt 2 */ +#define EINT3_IRQ 17 /* External interrupt 3 */ +#define ADC0_IRQ 18 /* ADC 0 */ +#define I2C1_IRQ 19 /* I2C 1 */ +#define BOD_IRQ 20 /* Brown Out Detect */ +#define EMAC_IRQ 21 /* Ethernet */ +#define USB_IRQ 22 /* USB */ +#define CAN_IRQ 23 /* CAN */ +#define MCI_IRQ 24 /* SD/MMC Interface */ +#define GPDMA_IRQ 25 /* General Purpose DMA */ +#define TIMER2_IRQ 26 /* Timer 2 */ +#define TIMER3_IRQ 27 /* Timer 3 */ +#define UART2_IRQ 28 /* Uart 2 */ +#define UART3_IRQ 29 /* Uart 3 */ +#define I2C2_IRQ 30 /* I2C 2 */ +#define I2S_IRQ 31 /* I2S */ + + +#define IRQ_SYSTIMER TIMER0_IRQ + +#define NR_IRQS 32 + +/* There are 32 vectored interrupts. If vectored interrupts are enabled, the + * following will be used by the system. + */ +#define SYSTIMER_VEC 0 /* System timer */ + +#define CLASS_IRQ 0 +#define CLASS_FIQ 1 +#define PRIORITY_LOWEST 15 +#define PRIORITY_HIGHEST 0 /* System timer */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_attach_vector(int irq, int priority, vic_vector_t handler); +void up_detach_vector(int vector); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_LPC2378_IRQ_H */ diff --git a/arch/arm/include/lpc31xx/irq.h b/arch/arm/include/lpc31xx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..c67c5b1274eaa36ca8e153614ddc85fcf32a1112 --- /dev/null +++ b/arch/arm/include/lpc31xx/irq.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/include/lpc31xx/irq.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC31XX_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC31XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LPC31XX Interrupts */ + + /* IRQ0: Reserved */ +#define LPC31_IRQ_IRQ0 0 /* IRQ1: Event router cascaded IRQ0 */ +#define LPC31_IRQ_IRQ1 1 /* IRQ2: Event router cascaded IRQ1 */ +#define LPC31_IRQ_IRQ2 2 /* IRQ3: Event router cascaded IRQ2 */ +#define LPC31_IRQ_IRQ3 3 /* IRQ4: Event router cascaded IRQ3 */ +#define LPC31_IRQ_TMR0 4 /* IRQ5: Timer 0 Interrupt */ +#define LPC31_IRQ_TMR1 5 /* IRQ6: Timer 1 Interrupt */ +#define LPC31_IRQ_TMR2 6 /* IRQ7: Timer 2 Interrupt */ +#define LPC31_IRQ_TMR3 7 /* IRQ8: Timer 3 Interrupt */ +#define LPC31_IRQ_ADC 8 /* IRQ9: ADC 10-bit */ +#define LPC31_IRQ_UART 9 /* IRQ10: UART */ +#define LPC31_IRQ_I2C0 10 /* IRQ11: I2C0 */ +#define LPC31_IRQ_I2C1 11 /* IRQ12: I2C1 */ +#define LPC31_IRQ_I2STX0 12 /* IRQ13: I2S0 Transmit */ +#define LPC31_IRQ_I2STX1 13 /* IRQ14: I2S1 Transmit */ +#define LPC31_IRQ_I2SRX0 14 /* IRQ15: I2S0 Receive */ +#define LPC31_IRQ_I2SRX1 15 /* IRQ16: I2S1 Receive */ + /* IRQ17: Reserved */ +#define LPC31_IRQ_LCD 17 /* IRQ18: LCD Interface */ +#define LPC31_IRQ_SPISMS 18 /* IRQ19: SPI SMS */ +#define LPC31_IRQ_SPITX 19 /* IRQ20: SPI Transmit */ +#define LPC31_IRQ_SPIRX 20 /* IRQ21: SPI Receive */ +#define LPC31_IRQ_SPIOVF 21 /* IRQ22: SPI Overflow */ +#define LPC31_IRQ_SPI 22 /* IRQ23: SPI */ +#define LPC31_IRQ_DMA 23 /* IRQ24: DMA */ +#define LPC31_IRQ_NAND 24 /* IRQ25: NAND FLASH Controller */ +#define LPC31_IRQ_MCI 25 /* IRQ26: MCI */ +#define LPC31_IRQ_USBOTG 26 /* IRQ27: USB OTG */ +#define LPC31_IRQ_ISRAM0 27 /* IRQ28: ISRAM0 MRC Finished */ +#define LPC31_IRQ_ISRAM1 28 /* IRQ29: ISRAM1 MRC Finished */ + +#define LPC31_IRQ_SYSTIMER LPC31_IRQ_TMR0 +#define NR_IRQS (LPC31_IRQ_ISRAM1+1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_LPC31XX_IRQ_H */ + diff --git a/arch/arm/include/lpc43xx/chip.h b/arch/arm/include/lpc43xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..56db629293791488a443b8cb61b27280cb74ec5b --- /dev/null +++ b/arch/arm/include/lpc43xx/chip.h @@ -0,0 +1,726 @@ +/************************************************************************************ + * arch/arm/include/lpc43xx/chip.h + * + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_LPC43XX_CHIP_H +#define __ARCH_ARM_INCLUDE_LPC43XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Per the data sheet: LPC4350/30/20/10 Rev. 3.2 — 4 June 2012 */ +/* Get customizations for each supported chip. + * + * SRAM Resources + * --------------------- -------- ------- ------- ------- + * Local SRAM LPC4310 LPC4320 LPC4330 LPC4350 + * --------------------- -------- ------- ------- ------- + * BANK 0 (0x1000 0000) 96Kb 128Kb 128Kb 128Kb + * BANK 1 (0x1008 0000) 40Kb 40Kb 72Kb 72Kb + * --------------------- -------- ------- ------- ------- + * SUBTOTAL 136Kb 168Kb 200Kb 200Kb + * --------------------- -------- ------- ------- ------- + * AHB SRAM LPC4310 LPC4320 LPC4330 LPC4350 + * --------------------- -------- ------- ------- ------- + * BANK 0 (0x2000 0000) 16Kb 48Kb 48Kb 48Kb + * BANK 1 (0x2000 8000) NOTE 1 NOTE 1 NOTE 1 + * BANK 2 (0x2000 c000) 16Kb 16Kb 16Kb 16Kb + * --------------------- -------- ------- ------- ------- + * SUBTOTAL 32Kb 32Kb 64Kb 64Kb + * --------------------- -------- ------- ------- ------- + * TOTAL 168Kb 200Kb 264Kb 264Kb + * --------------------- -------- ------- ------- ------- + * + * NOTE 1: The 64Kb of AHB of SRAM on the LPC4350/30/20 span all AHB SRAM + * banks but are treated as two banks of 48 an 16Kb by the NuttX memory + * manager. This gives some symmetry to all of the members of the family. + */ + +/* Per the user manual: UM10503, Rev. 1.2 — 8 June 2012 */ +/* Get customizations for each supported chip. + * + * SRAM Resources + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * Local SRAM LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 LPC4337 + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * BANK 0 (0x1000 0000) 96Kb 96Kb 128Kb 128Kb 32Kb 32Kb 32Kb + * BANK 1 (0x1008 0000) 40Kb 40Kb 72Kb 72Kb 40Kb 40Kb 40Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * SUBTOTAL 136Kb 136Kb 200Kb 200Kb 72Kb 72Kb 72Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * AHB SRAM LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 LPC4337 + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * BANK 0 (0x2000 0000) 16Kb 48Kb 48Kb 48Kb 48Kb 48Kb 48Kb + * BANK 1 (0x2000 8000) NOTE 1 NOTE 1 NOTE 1 NOTE 1 NOTE 1 NOTE 1 + * BANK 2 (0x2000 c000) 16Kb 16Kb 16Kb 16Kb 16Kb 16Kb 16Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * SUBTOTAL 32Kb 64Kb 64Kb 64Kb 64Kb 64Kb 64Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * TOTAL 168Kb 200Kb 264Kb 264Kb 136Kb 136Kb 136Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * FLASH LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 LPC4337 + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * BANK A (0x1a00 0000) 256Kb 512Kb 512Kb + * BANK B (0x1b00 8000) 256Kb 512Kb 512Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * TOTAL None None None None 512Kb 1024Kb 1024Kb + * --------------------- -------- ------- ------- ------- ------- ------- ------- + * + * NOTE 1: The 64Kb of AHB of SRAM on the LPC4350/30/20 span all AHB SRAM + * banks but are treated as two banks of 48 an 16Kb by the NuttX memory + * manager. This gives some symmetry to all of the members of the family. + */ + +#if defined(CONFIG_ARCH_CHIP_LPC4310FBD144) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (96*1024) /* 136Kb Local SRAM */ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (16*1024) /* 32Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# undef LPC43_ETHERNET /* No Ethernet controller */ +# undef LPC43_USB0 /* No USB0 (Host, Device, OTG) */ +# undef LPC43_USB1 /* No USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4310FET100) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (96*1024) /* 136Kb Local SRAM */ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (16*1024) /* 32Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# undef LPC43_ETHERNET /* No Ethernet controller */ +# undef LPC43_USB0 /* No USB0 (Host, Device, OTG) */ +# undef LPC43_USB1 /* No USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# undef LPC43_MCPWM /* No PWM capability */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (4) /* Four ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4320FBD144) +# warning "Data sheet and user manual are consistement for the LPC4320" +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 168Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (16*1024) /* 32Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# undef LPC43_ETHERNET /* No Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# undef LPC43_USB1 /* No USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4320FET100) +# warning "Data sheet and user manual are consistement for the LPC4320" +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 168Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (16*1024) /* 32Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# undef LPC43_ETHERNET /* No Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# undef LPC43_USB1 /* No USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# undef LPC43_MCPWM /* No PWM capability */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (4) /* Four ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4330FBD144) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET100) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# undef LPC43_MCPWM /* No PWM capability */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (4) /* Four ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET180) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET256) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4337JBD144) +# define LPC43_FLASH_BANKA_SIZE (512*1025) /* 1024Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (512*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (0) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (0) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (0) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4350FBD208) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# define LPC43_NLCD (1) /* One LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4350FET180) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# define LPC43_NLCD (1) /* One LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4350FET256) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# define LPC43_NLCD (1) /* One LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4353FBD208) +# define LPC43_FLASH_BANKA_SIZE (256*1025) /* 512Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (256*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4353FET180) +# define LPC43_FLASH_BANKA_SIZE (256*1025) /* 512Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (256*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4353FET256) +# define LPC43_FLASH_BANKA_SIZE (256*1025) /* 512Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (256*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4357FET180) +# define LPC43_FLASH_BANKA_SIZE (512*1025) /* 1024Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (512*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4357FBD208) +# define LPC43_FLASH_BANKA_SIZE (512*1025) /* 1024Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (512*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4357FET256) +# define LPC43_FLASH_BANKA_SIZE (512*1025) /* 1024Kb FLASH */ +# define LPC43_FLASH_BANKB_SIZE (512*1025) +# define LPC43_LOCSRAM_BANK0_SIZE (32*1024) /* 72Kb Local SRAM*/ +# define LPC43_LOCSRAM_BANK1_SIZE (40*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (48*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (0) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (16*1024) /* 16Kb EEPROM */ +# define LPC43_NLCD (1) /* Has LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels */ +# undef LPC43_NADC12 /* No 12-bit ADC controllers */ +#elif defined(CONFIG_ARCH_CHIP_LPC4370FET100) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM (plus 18Kb for Cortex-M0)*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (32*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (16*1024) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# undef LPC43_NLCD /* No LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# undef LPC43_USB1_ULPI /* No USB1 (Host, Device) with ULPI I/F */ +# undef LPC43_MCPWM /* No PWM capability */ +# undef LPC43_QEI /* No Quadrature Encoder capability */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two C-CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10 (2) /* Two 10-bit ADC controllers */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels (per ADC)*/ +# define LPC43_NADC12 (1) /* ONne 12-bit ADC controllers (ADCHS)*/ +#elif defined(CONFIG_ARCH_CHIP_LPC4370FET256) +# define LPC43_FLASH_BANKA_SIZE (0) /* Flashless */ +# define LPC43_FLASH_BANKB_SIZE (0) +# define LPC43_LOCSRAM_BANK0_SIZE (128*1024) /* 200Kb Local SRAM (plus 18Kb for Cortex-M0)*/ +# define LPC43_LOCSRAM_BANK1_SIZE (72*1024) +# define LPC43_AHBSRAM_BANK0_SIZE (32*1024) /* 64Kb AHB SRAM */ +# define LPC43_AHBSRAM_BANK1_SIZE (16*1024) +# define LPC43_AHBSRAM_BANK2_SIZE (16*1024) +# define LPC43_EEPROM_SIZE (0) /* No EEPROM */ +# define LPC43_NLCD (1) /* One LCD controller */ +# define LPC43_ETHERNET (1) /* One Ethernet controller */ +# define LPC43_USB0 (1) /* Have USB0 (Host, Device, OTG) */ +# define LPC43_USB1 (1) /* Have USB1 (Host, Device) */ +# define LPC43_USB1_ULPI (1) /* Have USB1 (Host, Device) with ULPI I/F */ +# define LPC43_MCPWM (1) /* One PWM interface */ +# define LPC43_QEI (1) /* One Quadrature Encoder interface */ +# define LPC43_NUSARTS (4) /* Three USARTs + 1 UART */ +# define LPC43_NSSP (2) /* Two SSP controllers */ +# define LPC43_NTIMERS (4) /* Four Timers */ +# define LPC43_NI2C (2) /* Two I2C controllers */ +# define LPC43_NI2S (2) /* Two I2S controllers */ +# define LPC43_NCAN (2) /* Two C-CAN controllers */ +# define LPC43_NDAC (1) /* One 10-bit DAC */ +# define LPC43_NADC10_CHANNELS (8) /* Eight ADC channels (per ADC)*/ +# define LPC43_NADC12 (1) /* ONne 12-bit ADC controllers (ADCHS)*/ +#else +# error "Unsupported LPC43xx chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-31. The lower the value, the greater + * the priority of the corresponding interrupt. + * + * The Cortex-M4 core supports up to 53 interrupts an 8 prgrammable interrupt + * priority levels; The Cortex-M0 core supports up to 32 interrupts with 4 + * programmable interrupt priorities. + */ + +#define LPC43M4_SYSH_PRIORITY_MIN 0xe0 /* All bits[7:5] set is minimum priority */ +#define LPC43M4_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define LPC43M4_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define LPC43M4_SYSH_PRIORITY_STEP 0x20 /* Steps between priorities */ + +#define LPC43M0_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define LPC43M0_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define LPC43M0_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define LPC43M0_SYSH_PRIORITY_STEP 0x40 /* Steps between priorities */ + +/* Only the Cortex-M4 is supported by Nuttx */ + +#define NVIC_SYSH_PRIORITY_MIN LPC43M4_SYSH_PRIORITY_MIN +#define NVIC_SYSH_PRIORITY_DEFAULT LPC43M4_SYSH_PRIORITY_DEFAULT +#define NVIC_SYSH_PRIORITY_MAX LPC43M4_SYSH_PRIORITY_MAX +#define NVIC_SYSH_PRIORITY_STEP LPC43M4_SYSH_PRIORITY_STEP + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_LPC43XX_CHIP_H */ diff --git a/arch/arm/include/lpc43xx/irq.h b/arch/arm/include/lpc43xx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..9b103e97185005d00d3e254fee0d6ca03ccf3fce --- /dev/null +++ b/arch/arm/include/lpc43xx/irq.h @@ -0,0 +1,227 @@ +/******************************************************************************************** + * arch/arm/include/lpc43xxx/irq.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_LPC43XX_IRQ_H +#define __ARCH_ARM_INCLUDE_LPC43XX_IRQ_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to bits in + * the NVIC. This does, however, waste several words of memory in the IRQ to handle mapping + * tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define LPC43_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define LPC43_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define LPC43_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define LPC43_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define LPC43_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define LPC43_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define LPC43_IRQ_SIGNVALUE (7) /* Vector 7: Sign value */ +#define LPC43_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define LPC43_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define LPC43_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define LPC43_IRQ_SYSTICK (15) /* Vector 15: System tick */ +#define LPC43_IRQ_EXTINT (16) /* Vector 16: Vector number of the first external interrupt */ + +/* Cortex-M4 External interrupts (vectors >= 16) */ + +#define LPC43M4_IRQ_DAC (LPC43_IRQ_EXTINT+0) /* D/A */ +#define LPC43M4_IRQ_M0CORE (LPC43_IRQ_EXTINT+1) /* M0 Core */ +#define LPC43M4_IRQ_DMA (LPC43_IRQ_EXTINT+2) /* DMA */ +#define LPC43M4_IRQ_FLASHEEPROM (LPC43_IRQ_EXTINT+4) /* EEPROM interrupts (BankA or BankB) */ +#define LPC43M4_IRQ_ETHERNET (LPC43_IRQ_EXTINT+5) /* Ethernet interrupt */ +#define LPC43M4_IRQ_SDIO (LPC43_IRQ_EXTINT+6) /* SD/MMC interrupt */ +#define LPC43M4_IRQ_LCD (LPC43_IRQ_EXTINT+7) /* LCD */ +#define LPC43M4_IRQ_USB0 (LPC43_IRQ_EXTINT+8) /* USB0 OTG interrupt */ +#define LPC43M4_IRQ_USB1 (LPC43_IRQ_EXTINT+9) /* USB1 interrupt */ +#define LPC43M4_IRQ_SCT (LPC43_IRQ_EXTINT+10) /* SCT combined interrupt */ +#define LPC43M4_IRQ_RITIMER (LPC43_IRQ_EXTINT+11) /* RITIMER interrupt */ +#define LPC43M4_IRQ_TIMER0 (LPC43_IRQ_EXTINT+12) /* TIMER0 interrupt */ +#define LPC43M4_IRQ_TIMER1 (LPC43_IRQ_EXTINT+13) /* TIMER1 interrupt */ +#define LPC43M4_IRQ_TIMER2 (LPC43_IRQ_EXTINT+14) /* TIMER2 interrupt */ +#define LPC43M4_IRQ_TIMER3 (LPC43_IRQ_EXTINT+15) /* TIMER3 interrupt */ +#define LPC43M4_IRQ_MCPWM (LPC43_IRQ_EXTINT+16) /* Motor control PWM interrupt */ +#define LPC43M4_IRQ_ADC0 (LPC43_IRQ_EXTINT+17) /* ADC0 interrupt */ +#define LPC43M4_IRQ_I2C0 (LPC43_IRQ_EXTINT+18) /* I2C0 interrupt */ +#define LPC43M4_IRQ_I2C1 (LPC43_IRQ_EXTINT+19) /* I2C1 interrupt */ +#define LPC43M4_IRQ_SPI (LPC43_IRQ_EXTINT+20) /* SPI interrupt */ +#define LPC43M4_IRQ_ADC1 (LPC43_IRQ_EXTINT+21) /* ADC1 interrupt */ +#define LPC43M4_IRQ_SSP0 (LPC43_IRQ_EXTINT+22) /* SSP0 interrupt */ +#define LPC43M4_IRQ_SSP1 (LPC43_IRQ_EXTINT+23) /* SSP1 interrupt */ +#define LPC43M4_IRQ_USART0 (LPC43_IRQ_EXTINT+24) /* USART0 interrupt */ +#define LPC43M4_IRQ_UART1 (LPC43_IRQ_EXTINT+25) /* UART1/Modem interrupt */ +#define LPC43M4_IRQ_USART2 (LPC43_IRQ_EXTINT+26) /* USART2 interrupt */ +#define LPC43M4_IRQ_USART3 (LPC43_IRQ_EXTINT+27) /* USART3/IrDA interrupt */ +#define LPC43M4_IRQ_I2S0 (LPC43_IRQ_EXTINT+28) /* I2S0 interrupt */ +#define LPC43M4_IRQ_I2S1 (LPC43_IRQ_EXTINT+29) /* I2S1 interrupt */ +#define LPC43M4_IRQ_SPIFI (LPC43_IRQ_EXTINT+30) /* SPIFI interrupt */ +#define LPC43M4_IRQ_SGPIO (LPC43_IRQ_EXTINT+31) /* SGPIO interrupt */ +#define LPC43M4_IRQ_PININT0 (LPC43_IRQ_EXTINT+32) /* GPIO pin interrupt 0 */ +#define LPC43M4_IRQ_PININT1 (LPC43_IRQ_EXTINT+33) /* GPIO pin interrupt 1 */ +#define LPC43M4_IRQ_PININT2 (LPC43_IRQ_EXTINT+34) /* GPIO pin interrupt 2 */ +#define LPC43M4_IRQ_PININT3 (LPC43_IRQ_EXTINT+35) /* GPIO pin interrupt 3 */ +#define LPC43M4_IRQ_PININT4 (LPC43_IRQ_EXTINT+36) /* GPIO pin interrupt 4 */ +#define LPC43M4_IRQ_PININT5 (LPC43_IRQ_EXTINT+37) /* GPIO pin interrupt 5 */ +#define LPC43M4_IRQ_PININT6 (LPC43_IRQ_EXTINT+38) /* GPIO pin interrupt 6 */ +#define LPC43M4_IRQ_PININT7 (LPC43_IRQ_EXTINT+39) /* GPIO pin interrupt 7 */ +#define LPC43M4_IRQ_GINT0 (LPC43_IRQ_EXTINT+40) /* GPIO group interrupt 0 */ +#define LPC43M4_IRQ_GINT1 (LPC43_IRQ_EXTINT+41) /* GPIO group interrupt 1 */ +#define LPC43M4_IRQ_EVENTROUTER (LPC43_IRQ_EXTINT+42) /* Event router interrupt */ +#define LPC43M4_IRQ_CAN1 (LPC43_IRQ_EXTINT+43) /* C_CAN1 interrupt */ +#define LPC43M4_IRQ_ATIMER (LPC43_IRQ_EXTINT+46) /* ATIMER Alarm timer interrupt */ +#define LPC43M4_IRQ_RTC (LPC43_IRQ_EXTINT+47) /* RTC interrupt */ +#define LPC43M4_IRQ_WWDT (LPC43_IRQ_EXTINT+49) /* WWDT interrupt */ +#define LPC43M4_IRQ_CAN0 (LPC43_IRQ_EXTINT+51) /* C_CAN0 interrupt */ +#define LPC43M4_IRQ_QEI (LPC43_IRQ_EXTINT+52) /* QEI interrupt */ + +#define LPC43M4_IRQ_NEXTINT (53) +#define LPC43M4_IRQ_NIRQS (LPC43_IRQ_EXTINT+LPC43M4_IRQ_NEXTINT) + +/* Total number of IRQ numbers (This will need to be revisited if/when the Cortex-M0 is + * supported) + */ + +#define NR_VECTORS LPC43M4_IRQ_NIRQS +#define NR_IRQS LPC43M4_IRQ_NIRQS + +/* Cortex-M0 External interrupts (vectors >= 16) */ + +#define LPC43M0_IRQ_RTC (LPC43_IRQ_EXTINT+0) /* RT interrupt */ +#define LPC43M0_IRQ_M4CORE (LPC43_IRQ_EXTINT+1) /* Interrupt from the M4 core */ +#define LPC43M0_IRQ_DMA (LPC43_IRQ_EXTINT+2) /* DMA interrupt */ +#define LPC43M0_IRQ_FLASHEEPROM (LPC43_IRQ_EXTINT+4) /* EEPROM (Bank A or B) | A Timer */ +#define LPC43M0_IRQ_ATIMER (LPC43_IRQ_EXTINT+4) /* EEPROM (Bank A or B) | A Timer */ +#define LPC43M0_IRQ_ETHERNET (LPC43_IRQ_EXTINT+5) /* Ethernet interrupt */ +#define LPC43M0_IRQ_SDIO (LPC43_IRQ_EXTINT+6) /* SDIO interrupt */ +#define LPC43M0_IRQ_LCD (LPC43_IRQ_EXTINT+7) /* LCD interrupt */ +#define LPC43M0_IRQ_USB0 (LPC43_IRQ_EXTINT+8) /* USB0 OTG interrupt */ +#define LPC43M0_IRQ_USB1 (LPC43_IRQ_EXTINT+9) /* USB1 interrupt */ +#define LPC43M0_IRQ_SCT (LPC43_IRQ_EXTINT+10) /* SCT combined interrupt */ +#define LPC43M0_IRQ_RITIMER (LPC43_IRQ_EXTINT+11) /* RI Timer | WWDT interrupt */ +#define LPC43M0_IRQ_WWDT (LPC43_IRQ_EXTINT+11) /* RI Timer | WWDT interrupt */ +#define LPC43M0_IRQ_TIMER0 (LPC43_IRQ_EXTINT+12) /* TIMER0 interrupt */ +#define LPC43M0_IRQ_GINT1 (LPC43_IRQ_EXTINT+13) /* GINT1 GPIO global interrupt 1 */ +#define LPC43M0_IRQ_PININT4 (LPC43_IRQ_EXTINT+14) /* GPIO pin interrupt 4 */ +#define LPC43M0_IRQ_TIMER3 (LPC43_IRQ_EXTINT+15) /* TIMER interrupt */ +#define LPC43M0_IRQ_MCPWM (LPC43_IRQ_EXTINT+16) /* Motor control PWM interrupt */ +#define LPC43M0_IRQ_ADC0 (LPC43_IRQ_EXTINT+17) /* ADC0 interrupt */ +#define LPC43M0_IRQ_I2C0 (LPC43_IRQ_EXTINT+18) /* I2C0 | I2C1 interrupt */ +#define LPC43M0_IRQ_I2C1 (LPC43_IRQ_EXTINT+18) /* I2C0 | I2C1 interrupt */ +#define LPC43M0_IRQ_SGPIO (LPC43_IRQ_EXTINT+19) /* SGPIO interrupt */ +#define LPC43M0_IRQ_SPI (LPC43_IRQ_EXTINT+20) /* SPI | DAC interrupt */ +#define LPC43M0_IRQ_DAC (LPC43_IRQ_EXTINT+20) /* SPI | DAC interrupt */ +#define LPC43M0_IRQ_ADC1 (LPC43_IRQ_EXTINT+21) /* ADC1 interrupt */ +#define LPC43M0_IRQ_SSP0 (LPC43_IRQ_EXTINT+22) /* SSP0 | SSP1 interrupt */ +#define LPC43M0_IRQ_SSP1 (LPC43_IRQ_EXTINT+22) /* SSP0 | SSP1 interrupt */ +#define LPC43M0_IRQ_EVENTROUTER (LPC43_IRQ_EXTINT+23) /* Event router interrupt */ +#define LPC43M0_IRQ_USART0 (LPC43_IRQ_EXTINT+24) /* USART0 interrupt */ +#define LPC43M0_IRQ_UART1 (LPC43_IRQ_EXTINT+25) /* UART1 Modem/UART1 interrupt */ +#define LPC43M0_IRQ_USART2 (LPC43_IRQ_EXTINT+26) /* USART2 | C_CAN1 interrupt */ +#define LPC43M0_IRQ_CAN1 (LPC43_IRQ_EXTINT+26) /* USART2 | C_CAN1 interrupt */ +#define LPC43M0_IRQ_USART3 (LPC43_IRQ_EXTINT+27) /* USART3 interrupt */ +#define LPC43M0_IRQ_I2S0 (LPC43_IRQ_EXTINT+28) /* I2S0 | I2S1 | QEI interrupt */ +#define LPC43M0_IRQ_I2S1 (LPC43_IRQ_EXTINT+28) /* I2S0 | I2S1 | QEI interrupt */ +#define LPC43M0_IRQ_QEI (LPC43_IRQ_EXTINT+28) /* I2S0 | I2S1 | QEI interrupt */ +#define LPC43M0_IRQ_CAN0 (LPC43_IRQ_EXTINT+29) /* C_CAN0 interrupt */ + +#define LPC43M0_IRQ_NEXTINT (30) +#define LPC43M0_IRQ_NIRQS (LPC43_IRQ_EXTINT+LPC43M0_IRQ_NEXTINT) + +/* Total number of IRQ numbers (This will need to be revisited if/when the Cortex-M0 is + * supported) + */ + +#if 0 +#define NR_VECTORS LPC43M0_IRQ_NIRQS +#define NR_IRQS LPC43M0_IRQ_NIRQS +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); +#endif + +/******************************************************************************************** + * Inline functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_LPC43XX_IRQ_H */ + diff --git a/arch/arm/include/moxart/irq.h b/arch/arm/include/moxart/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f9165cbaaa7ef7c840a9ea603599356e7849d820 --- /dev/null +++ b/arch/arm/include/moxart/irq.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/include/moxart/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_MOXART_IRQ_H +#define __ARCH_ARM_INCLUDE_MOXART_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#define IRQ_SYSTIMER 19 + +#define VIRQ_START 32 + +#define NR_IRQS (VIRQ_START+2) + +#endif /* __ARCH_ARM_INCLUDE_MOXART_IRQ_H */ diff --git a/arch/arm/include/nuc1xx/chip.h b/arch/arm/include/nuc1xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..0443f19a00225e3f8020292dac66c06c13a39bed --- /dev/null +++ b/arch/arm/include/nuc1xx/chip.h @@ -0,0 +1,677 @@ +/************************************************************************************ + * arch/arm/include/nuc1xx/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + + +#ifndef __ARCH_ARM_INCLUDE_NUC1XX_CHIP_H +#define __ARCH_ARM_INCLUDE_NUC1XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Chip capabilities ****************************************************************/ +/* NUC100 Advanced Line (Low Density) */ + +#if defined(CONFIG_ARCH_CHIP_NUC100LC1BN) /* Flash 32K SRAM 4K, LQFP48 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (32*1024) /* 32K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 35 /* (35) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100LD1BN) /* Flash 64K SRAM 4K, LQFP48 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 31 /* (35) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100LD2BN) /* Flash 64K SRAM 8K, LQFP48 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 8K SRAM */ +# define NUC_NIO 31 /* (35) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100RC1BN) /* Flash 32K SRAM 4K, LQFP64 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (32*1024) /* 32K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 49 /* (49) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Supports EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100RD1BN) /* Flash 64K SRAM 4K, LQFP64 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 49 /* (49) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Supports EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100RD2BN) /* Flash 64K SRAM 8K, LQFP64 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 4K SRAM */ +# define NUC_NIO 49 /* (49) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Supports EBI */ + +/* NUC100 Advanced Line (Medium Density) */ + +#elif defined(CONFIG_ARCH_CHIP_NUC100LD3AN) /* Flash 64K SRAM 16K, LQFP48 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 35 /* (35) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100LE3AN) /* Flash 128K SRAM 16K, LQFP48 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 35 /* (35) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100RD3AN) /* Flash 64K SRAM 16K, LQFP64 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 49 /* (49) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparator */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100RE3AN) /* Flash 128K SRAM 16K, LQFP64 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 128K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 49 /* (49) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparator */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100VD2AN) /* Flash 64K SRAM 8K, LQFP100 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 8K SRAM */ +# define NUC_NIO 80 /* (80) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparator */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100VD3AN) /* Flash 64K SRAM 16K, LQFP100 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 80 /* (80) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparator */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC100VE3AN) /* Flash 128K SRAM 8K, LQFP100 package */ +# define NUC100 1 /* NUC100 family */ +# undef NUC120 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 128K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 80 /* (80) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 0 /* No USB */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparator */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ + +/* NUC120 USB Line (Low Density) */ + +#elif defined(CONFIG_ARCH_CHIP_NUC120LC1BN) /* Flash 32K SRAM 4K, LQFP48 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (32*1024) /* 32K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 31 /* (31) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120LD1BN) /* Flash 64K SRAM 4K, LQFP48 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 31 /* (31) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120LD2BN) /* Flash 64K SRAM 8K, LQFP48 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 8K SRAM */ +# define NUC_NIO 31 /* (31) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120RC1BN) /* Flash 32K SRAM 4K, LQFP64 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (32*1024) /* 32K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 45 /* (45) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Have EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120RD1BN) /* Flash 64K SRAM 4K, LQFP64 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (4*1024) /* 4K SRAM */ +# define NUC_NIO 45 /* (45) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Have EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120RD2BN) /* Flash 64K SRAM 8K, LQFP64 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# define NUC_LOW 1 /* Low density part */ +# undef NUC_MEDIUM /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 8K SRAM */ +# define NUC_NIO 45 /* (45) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 1 /* 1 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# define NUC_EBI 1 /* Have EBI */ + +/* NUC120 USB Line (Medium Density) */ + +#elif defined(CONFIG_ARCH_CHIP_NUC120LD3AN) /* Flash 64K SRAM 16K, LQFP48 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 31 /* (31) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120LE3AN) /* Flash 128K SRAM 16K, LQFP48 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 128K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 31 /* (31) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 1 /* (1) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 1 /* (1) Analog Comparator */ +# define NUC_NPWM 4 /* (4) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120RD3AN) /* Flash 64K SRAM 16K, LQFP64 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 45 /* (45) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120RE3AN) /* Flash 128K SRAM 16K, LQFP64 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 128K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 45 /* (45) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 2 /* (2) UARTs */ +# define NUC_NSPI 2 /* (2) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 6 /* (6) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120VD2AN) /* Flash 64K SRAM 8K, LQFP100 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (8*1024) /* 8K SRAM */ +# define NUC_NIO 76 /* (76) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120VD3AN) /* Flash 64K SRAM 16K, LQFP100 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (64*1024) /* 64K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 76 /* (76) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ +#elif defined(CONFIG_ARCH_CHIP_NUC120VE3AN) /* Flash 128K SRAM 16K, LQFP100 package */ +# undef NUC100 /* NUC100 family */ +# define NUC120 1 /* NUC120 family */ +# undef NUC_LOW /* Low density part */ +# define NUC_MEDIUM 1 /* Medium density part */ +# define NUC_FLASH (128*1024) /* 128K FLASH */ +# define NUC_SRAM (16*1024) /* 16K SRAM */ +# define NUC_NIO 76 /* (76) GPIO */ +# define NUC_NTIMERS 4 /* 4x32-bit Timers */ +# define NUC_NPDMA 9 /* 9 PDMA channels */ +# define NUC_NUARTS 3 /* (3) UARTs */ +# define NUC_NSPI 4 /* (4) SPI */ +# define NUC_NI2C 2 /* (2) I2C */ +# define NUC_NUSB 1 /* (1) USB 2.0 full speed */ +# define NUC_NLIN 0 /* No LIN */ +# define NUC_NCAN 0 /* No CAN */ +# define NUC_NI2S 1 /* (1) I2S */ +# define NUC_NCOMP 2 /* (2) Analog Comparators */ +# define NUC_NPWM 8 /* (8) PWM */ +# define NUC_NADC 8 /* 8x12-bit ADC */ +# define NUC_RTC 1 /* RTC */ +# undef NUC_EBI /* No EBI */ + +#else +# error "Unrecognized NUC1XX chip" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-3. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:6] of each field, bits[5:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Five bits of interrupt priority used */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_NUC1XX_CHIP_H */ + diff --git a/arch/arm/include/nuc1xx/irq.h b/arch/arm/include/nuc1xx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..0db0379d1b4b4360b1ba4fe68491c546afcdf1d5 --- /dev/null +++ b/arch/arm/include/nuc1xx/irq.h @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/include/nuc1xx/irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_NUC1XX_IRQ_H +#define __ARCH_ARM_INCLUDE_NUC1XX_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define NUC_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define NUC_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define NUC_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + /* Vector 4-10: Reserved */ +#define NUC_IRQ_SVCALL (11) /* Vector 11: SVC call */ + /* Vector 12-13: Reserved */ +#define NUC_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define NUC_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define NUC_IRQ_INTERRUPT (16) + +#if defined(NUC120) +# include +#else +# error "Unrecognized/unsupported NUC chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_NUC1XX_IRQ_H */ + diff --git a/arch/arm/include/nuc1xx/nuc120_irq.h b/arch/arm/include/nuc1xx/nuc120_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..5310b2cd8ece82260b4c9db629d87bbfb6e7558b --- /dev/null +++ b/arch/arm/include/nuc1xx/nuc120_irq.h @@ -0,0 +1,116 @@ +/************************************************************************************ + * arch/arm/include/nuc1xx/nuc120_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_NUC1XX_NUC120_IRQ_H +#define __ARCH_ARM_INCLUDE_NUC1XX_NUC120_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* NUC120 IRQ numbers */ + +#define NUC_IRQ_BOD (16) /* Brown-out low voltage detected */ +#define NUC_IRQ_WDT (17) /* Watchdog Timer */ +#define NUC_IRQ_EINT0 (18) /* Eternal interrupt from PB.14 */ +#define NUC_IRQ_EINT1 (19) /* Eternal interrupt from PB.15 */ +#define NUC_IRQ_GPAB (20) /* Eternal interrupt from PA[15:0]/PB[13:0] */ +#define NUC_IRQ_GPCDE (21) /* Eternal interrupt from PC[15:0]/PD[15:0]/PE[15:0] */ +#define NUC_IRQ_PWMA (22) /* PWM0-3 */ +#define NUC_IRQ_PWMB (23) /* PWM4-7 */ +#define NUC_IRQ_TMR0 (24) /* Timer 0 */ +#define NUC_IRQ_TMR1 (25) /* Timer 1 */ +#define NUC_IRQ_TMR2 (26) /* Timer 2 */ +#define NUC_IRQ_TMR3 (27) /* Timer 3 */ +#define NUC_IRQ_UART02 (28) /* UART0-1 */ +#define NUC_IRQ_UART1 (29) /* UART1 */ +#define NUC_IRQ_SPI0 (30) /* SPI0 */ +#define NUC_IRQ_SPI1 (31) /* SPI1 */ +#define NUC_IRQ_SPI2 (32) /* SPI2 */ +#define NUC_IRQ_SPI3 (33) /* SPI3 */ +#define NUC_IRQ_I2C0 (34) /* I2C0 */ +#define NUC_IRQ_I2C1 (35) /* I2C1 */ + /* 36-38: Reserved */ +#define NUC_IRQ_USB (39) /* USB */ +#define NUC_IRQ_PS2 (40) /* PS/2 interrupt */ +#define NUC_IRQ_ACMP (41) /* Analog comparator interrupt for chip wake-up from + * power down state */ +#define NUC_IRQ_PDMA (42) /* PDMA */ +#define NUC_IRQ_I2S (43) /* I2S */ +#define NUC_IRQ_PWRWU (44) /* Clock controller interrupt for chip wake-up from + * power down state */ +#define NUC_IRQ_ADC (45) /* ADC */ + /* 46: Reserved */ +#define NUC_IRQ_RTC (47) /* Real time clock */ + +#define NR_IRQS (48) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_NUC1XX_NUC120_IRQ_H */ + diff --git a/arch/arm/include/sam34/chip.h b/arch/arm/include/sam34/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..3bd3b42d51e868e3a52c113302d244bef281e19c --- /dev/null +++ b/arch/arm/include/sam34/chip.h @@ -0,0 +1,949 @@ +/************************************************************************************ + * arch/arm/include/sam34/chip.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_CHIP_H +#define __ARCH_ARM_INCLUDE_SAM34_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +/* AT91SAM3U Family *****************************************************************/ +/* FEATURE SAM3U4E SAM3U2E SAM3U1E SAM3U4C SAM3U2C SAM3U1C + * ----------- -------- -------- -------- -------- -------- -------- + * Flash 2x128KB 128KB 64KB 2x128KB 128KB 64KB + * SRAM 32+16KB 16+16KB 16KB 32+16KB 16+16KB 16KB + * NFC Yes Yes Yes Yes Yes Yes + * NFC SRAM 4KB 4KB 4KB 4KB 4KB 4KB + * Package LQFP144 LQFP144 LQFP144 LQFP100 LQFP100 LQFP100 + * LFBGA144 LFBGA144 LFBGA144 LFBGA100 LFBGA100 LFBGA100 + * No. PIOs 96 96 96 57 57 57 + * SHDN Pin Yes Yes Yes No No No + * EMAC --- --- --- --- --- --- + * EBI Yes Yes Yes Yes Yes Yes + * EBI data 8/16 8/16 8/16 8 8 8 + * EBI ch 4 4 4 2 2 2 + * EBI addr 24 24 24 8 8 8 + * SDRAM --- --- --- --- --- --- + * DMA 4 4 4 4 4 4 + * 12-bit ADC 8ch 8ch 8ch 4ch 4ch 4ch + * 10-bit ADC 8ch 8ch 8ch 4ch 4ch 4ch + * 32-bit Timer 1 1 1 1 1 1 + * 16-bit Timer 3 3 3 3 3 3 + * PDC Channels 17 17 17 17 17 17 + * USART 4 4 4 3 3 3 + * UART 2 2 2 1 1 1 + * SPI 1 1 1 1 1 1 + * SSC 1 1 1 1 1 1 + * HSMCI 8 bit 8 bit 8 bit 4 bit 4 bit 4 bit + */ + +#if defined(CONFIG_ARCH_CHIP_ATSAM3U4E) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE (16*1024) /* 16KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3U2E) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAM34_SRAM1_SIZE (16*1024) /* 16KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3U1E) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (64*1024) /* 64KB */ +# define SAM34_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAM34_SRAM1_SIZE 0 /* No SRAM1 */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3U4C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE (16*1024) /* 16KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3U2C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAM34_SRAM1_SIZE (16*1024) /* 16KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3U1C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (64*1024) /* 64KB */ +# define SAM34_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAM34_SRAM1_SIZE 0 /* No SRAM1 */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +/* AT91SAM3X/3A Families ************************************************************/ +/* FEATURE SAM3X8E SAM3X8C SAM3X4E SAM3X4C SAM3A8C SAM3A4C + * ------------ -------- -------- -------- -------- -------- -------- + * Flash 2x256KB 2x256KB 2x128KB 2x128KB 2x256KB 2x128KB + * SRAM 64+32KB 64+32KB 32+32KB 32+32KB 64+32KB 32+32KB + * NFC Yes --- Yes --- --- --- + * NFC SRAM 4KB --- 4KB --- --- --- + * Package LQFP144 LQFP100 LQFP144 LQFP100 LQFP100 LQFP100 + * LFBGA144 LFBGA100 LFBGA144 LFBGA100 LFBGA100 LFBGA100 + * No. PIOs 103 63 103 63 63 63 + * SHDN Pin Yes No Yes No No No + * EMAC MII/RMII RMII MII/RMII RMII --- --- + * EBI Yes --- Yes --- --- --- + * SDRAM --- --- --- --- --- --- + * DMA 6 4 6 4 4 4 + * 12-bit ADC 16ch 16ch 16ch 16ch 16ch 16ch + * 12-bit DAC 2ch 2ch 2ch 2ch 2ch 2ch + * 32-bit Timer 9 9 9 9 9 9 + * PDC Channels 17 17 17 15 15 15 + * USART 3 3 3 3 3 3 + * UART 2 1 2 1 1 1 + * SPI 1/4+3 1/4+3 1/4+3 1/4+3 1/4+3 1/4+3 + * HSMCI 8 bit 4 bit 8 bit 4 bit 4 bit 4 bit + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3X8E) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (64*1024) /* 64KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 6 /* 6 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3X8C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (64*1024) /* 64KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE 0 /* No NFC SRAM */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3X4E) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE (4*1024) /* 4KB */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 6 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 17 /* 17 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3X4C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE 0 /* No NFC SRAM */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 15 /* 15 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3A8C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (64*1024) /* 64KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE 0 /* No NFC SRAM */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 15 /* 15 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM3A4C) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 64KB */ +# define SAM34_SRAM1_SIZE (32*1024) /* 32KB */ +# define SAM34_NFCSRAM_SIZE 0 /* No NFC SRAM */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMA Channels */ +# define SAM34_NPDCCHAN 15 /* 15 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 1 /* One USB high speed device */ +# define SAM34_NUHPHS 1 /* One USB high speed embedded host */ +# define SAM34_NUDPFS 0 /* No USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +/* AT91SAM4C Family *****************************************************************/ +/* FEATURE SAM4CMP16B + * ----------- --------- + * Flash 1024KB + * SRAM 128KB + * SMC Yes + * GMCC 2KB + * Package LQFP144 + * LFBGA144 + * No. PIOs 117 + * SHDN Pin No + * EMAC MII + * CAN 2 + * EBI Yes + * EBI data 8 + * EBI ch 4 + * EBI addr 24 + * SDRAM --- + * DMA 4 + * 16-bit ADC0 16ch + * 16-bit ADC1 8ch + * 12-bit DAC 2ch + * Timer 9 + * PDC Channels 24+9 + * USART 2 + * UART 2 + * SPI 1 + * HSMCI 4 bit + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4CMP16B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 21 /* 21 PDC Channels */ +# define SAM34_NMCI2 0 /* No memory card interface */ +# define SAM32_NSLCD 1 /* 1 segment LCD interface */ +# define SAM32_NAESA 1 /* 1 advanced encryption standard */ +# define SAM32_NUDPHS 0 /* No USB high speed device */ +# define SAM32_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM32_NUDPFS 0 /* No USB full speed device */ +# define SAM32_NUHPFS 0 /* No USB full speed embedded host */ + +/* AT91SAM4L Family *****************************************************************/ +/* Sub-family differences: + * + * FEATURE ATSAM4LCxx ATSAM4LSxx + * ----------------------- ------------- ------------- + * SEGMENT LCD Yes No + * AESA Yes No + * USB Device + Host Device Only + * + * Note: The SEGMENT LCD capability varies with packaging. + * + * FEATURE ATSAM4Lx2x ATSAM4Lx4x + * ----------------------- ------------- ------------- + * FLASH 256KB 128KB + * SRAM 32KB 32KB + * + * Packaging differences: + * + * FEATURE ATSAM4LxxC ATSAM4LxxB ATSAM4LxxA + * ----------------------- ---------- ---------- ---------- + * Number of Pins 100 64 48 + * Max Frequency 48MHz 48MHz 48MHz + * SEGMENT LCD 4x40 4x23 4x13 + * GPIO 75 43 27 + * High-drive pins 6 3 1 + * External Interrupts 8+NMI 8+NMI 8+NMI + * TWI Masters 2 2 1 + * TWI Master/Slave 2 2 1 + * USART 4 4 3 + * PICOUART 1 1 1 + * Peripheral DMA Channels 16 16 16 + * Peripheral Even System 1 1 1 + * SPI 1 1 1 + * Asynchronous Timers 1 1 1 + * Timer/Counter Channels 6 3 3 + * Parallel Capture Inputs 8 8 8 + * Frequency Meter 1 1 1 + * Watchdog Timer 1 1 1 + * Power Manager 1 1 1 + * Glue Logic LUT 2 2 1 + * ADC 15-channel 7-channel 3-channel + * DAC 1-channel 1-channel 1-channel + * Analog Comparators 4 2 1 + * CATB Sensors 32 32 26 + * Audio Bitstream DAC 1 1 1 + * IIS Controller 1 1 1 + * Packages TQFP/VFBGA TQFP/QFN TQFP/QFN + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4LC2C) || defined (CONFIG_ARCH_CHIP_ATSAM4LC2B) || \ + defined(CONFIG_ARCH_CHIP_ATSAM4LC2A) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 16 /* 16 PDC Channels */ +# define SAM34_NMCI2 0 /* No memory card interface */ +# define SAM34_NSLCD 1 /* 1 segment LCD interface */ +# define SAM34_NAESA 1 /* 1 advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 1 /* 1 USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4LC4C) || defined (CONFIG_ARCH_CHIP_ATSAM4LC4B) || \ + defined(CONFIG_ARCH_CHIP_ATSAM4LC4A) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 16 /* 16 PDC Channels */ +# define SAM34_NMCI2 0 /* No memory card interface */ +# define SAM34_NSLCD 1 /* 1 segment LCD interface */ +# define SAM34_NAESA 1 /* 1 advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 1 /* 1 USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4LS2C) || defined (CONFIG_ARCH_CHIP_ATSAM4LS2B) || \ + defined(CONFIG_ARCH_CHIP_ATSAM4LS2A) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 16 /* 16 PDC Channels */ +# define SAM34_NMCI2 0 /* No memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4LS4C) || defined (CONFIG_ARCH_CHIP_ATSAM4LS4B) || \ + defined(CONFIG_ARCH_CHIP_ATSAM4LS4A) + +/* Internal memory */ + +# define SAM34_FLASH_SIZE (256*1024) /* 256KB */ +# define SAM34_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 16 /* 16 PDC Channels */ +# define SAM34_NMCI2 0 /* No memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +/* AT91SAM4S Family *****************************************************************/ +/* + * FEATURE SAM4SD32C SAM4SD32B SAM4SD16C SAM4SD16B SAM4SA16C SAM4SA16B SAM4S16C SAM4S16B SAM4S8C SAM4S8B + * ------------- --------- --------- --------- --------- --------- --------- -------- -------- ------- ------- + * Flash 2x1MB 2x1MB 2x512KB 1x1MB 1x1MB 1x1MB 1x1MB 1x1MB 1x512KB 1x512KB + * SRAM 160KB 160KB 160KB 160KB 160KB 160KB 128KB 128KB 128KB 128KB + * HCACHE 2KB 2KB 2KB 2KB 2KB 2KB - - - - + * Pins 100 64 100 64 100 64 100 64 100 64 + * No. PIOs 79 47 79 47 79 47 79 47 79 47 + * Ext. BUS Yes No Yes No Yes No Yes No Yes No + * 12-bit ADC 16 ch 11 ch 16 ch 11 ch 16 ch 11 ch 16 ch 11 ch 16 ch 11 ch + * 12-bit DAC 2 ch 2 ch 2 ch 2 ch 2 ch 2 ch 2 ch 2 ch 2 ch 2 ch + * Timer Counter 6 ch 3 ch 6 ch 3 ch 6 ch 3 ch 6 ch 3 ch 6 ch 3 ch + * PDC 22 ch 22 ch 22 ch 22 ch 22 ch 22 ch 22 ch 22 ch 22 ch 22 ch + * USART 2 2 2 2 2 2 2 2 2 2 + * UART 2 2 2 2 2 2 2 2 2 2 + * HSMCI Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SD32C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (2*1024*1024) /* 2x1MB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SD32B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (2*1024*1024) /* 2x1MB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SD16C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 2x512KB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SD16B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 2x512KB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SA16C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1MB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4SA16B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1MB */ +# define SAM34_SRAM0_SIZE (160*1024) /* 160KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4S16C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1MB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4S16B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1MB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4S8C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4S8B) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 0 /* No DMAC Channels */ +# define SAM34_NPDCCHAN 22 /* 22 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +/* AT91SAM4E Family *****************************************************************/ +/* FEATURE SAM4E16E SAM4E8E SAM4E16C SAM4E8C + * ----------- --------- -------- -------- -------- + * Flash 1024KB 512KB 1024KB 512KB + * SRAM 128KB 128KB 128KB 128KB + * SMC Yes Yes Yes Yes + * GMCC 2KB 2KB 2KB 2KB + * Package LQFP144 LQFP144 LQFP100 LQFP100 + * LFBGA144 LFBGA144 TFBGA100 TFBGA100 + * No. PIOs 117 117 79 79 + * SHDN Pin No No No No + * EMAC MII MII MII MII + * CAN 2 2 1 1 + * EBI Yes Yes No No + * EBI data 8 8 --- --- + * EBI ch 4 4 --- --- + * EBI addr 24 24 --- --- + * SDRAM --- --- --- --- + * DMA 4 4 4 4 + * 16-bit ADC0 16ch 16ch 6ch 6ch + * 16-bit ADC1 8ch 8ch 4ch 4ch + * 12-bit DAC 2ch 2ch 2ch 2ch + * Timer 9 9 3 3 + * PDC Channels 24+9 24+9 21+9 21+9 + * USART 2 2 2 2 + * UART 2 2 2 2 + * SPI 1 1 1 1 + * HSMCI 4 bit 4 bit 4 bit 4 bit + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4E16E) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMAC Channels */ +# define SAM34_NPDCCHAN 24 /* 24 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4E8E) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMAC Channels */ +# define SAM34_NPDCCHAN 24 /* 24 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4E16C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMAC Channels */ +# define SAM34_NPDCCHAN 21 /* 21 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAM4E8C) +/* Internal memory */ + +# define SAM34_FLASH_SIZE (512*1024) /* 512KB */ +# define SAM34_SRAM0_SIZE (128*1024) /* 128KB */ +# define SAM34_SRAM1_SIZE 0 /* None */ +# define SAM34_NFCSRAM_SIZE 0 /* None */ + +/* Peripherals */ + +# define SAM34_NDMACHAN 4 /* 4 DMAC Channels */ +# define SAM34_NPDCCHAN 21 /* 21 PDC Channels */ +# define SAM34_NMCI2 1 /* 1 memory card interface */ +# define SAM34_NSLCD 0 /* No segment LCD interface */ +# define SAM34_NAESA 0 /* No advanced encryption standard */ +# define SAM34_NUDPHS 0 /* No USB high speed device */ +# define SAM34_NUHPHS 0 /* No USB high speed embedded host */ +# define SAM34_NUDPFS 1 /* 1 USB full speed device */ +# define SAM34_NUHPFS 0 /* No USB full speed embedded host */ + +#else +# error "Unknown SAM3/4 chip type" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-15. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:4] of each field, bits[3:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits[7:4] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_SAM34_CHIP_H */ diff --git a/arch/arm/include/sam34/irq.h b/arch/arm/include/sam34/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..521cd5a93cd71b10d8f5076fb8283a0bd4fbc423 --- /dev/null +++ b/arch/arm/include/sam34/irq.h @@ -0,0 +1,123 @@ +/**************************************************************************************** + * arch/arm/include/sam34/irq.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Common Processor Exceptions (vectors 0-15) */ + +#define SAM_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define SAM_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define SAM_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define SAM_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define SAM_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define SAM_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define SAM_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define SAM_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define SAM_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define SAM_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* Chip-Specific External interrupts */ + +#define SAM_IRQ_EXTINT (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include +#else +# error Unrecognized SAM architecture +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_IRQ_H */ diff --git a/arch/arm/include/sam34/sam3u_irq.h b/arch/arm/include/sam34/sam3u_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..8165519c01ba3cba1993f3616eb04acab5735ead --- /dev/null +++ b/arch/arm/include/sam34/sam3u_irq.h @@ -0,0 +1,277 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam3u_irq.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM3U_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM3U_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM3U Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_PID_EEFC1 (7) /* Enhanced Embedded Flash Controller 1 */ +#define SAM_PID_UART0 (8) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_SMC (9) /* Static Memory Controller */ +#define SAM_PID_PIOA (10) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (11) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (12) /* Parallel I/O Controller C */ +#define SAM_PID_USART0 (13) /* USART 0 */ +#define SAM_PID_USART1 (14) /* USART 1 */ +#define SAM_PID_USART2 (15) /* USART 2 */ +#define SAM_PID_USART3 (16) /* USART 3 */ +#define SAM_PID_HSMCI (17) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWI0 (18) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (19) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (20) /* Serial Peripheral Interface */ +#define SAM_PID_SSC (21) /* Synchronous Serial Controller */ +#define SAM_PID_TC0 (22) /* Timer Counter 0 */ +#define SAM_PID_TC1 (23) /* Timer Counter 1 */ +#define SAM_PID_TC2 (24) /* Timer Counter 2 */ +#define SAM_PID_PWM (25) /* Pulse Width Modulation Controller */ +#define SAM_PID_ADC12B (26) /* 12-bit ADC Controller */ +#define SAM_PID_ADC (27) /* 10-bit ADC Controller */ +#define SAM_PID_DMAC (28) /* DMA Controller */ +#define SAM_PID_UDPHS (29) /* USB Device High Speed */ +#define NR_PIDS (30) /* Number of peripheral identifiers */ + +/* External interrupts (vectors >= 16) */ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EEFC0) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_IRQ_EEFC1 (SAM_IRQ_EXTINT+SAM_PID_EEFC1) /* Enhanced Embedded Flash Controller 1 */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* Universal Asynchronous Receiver Transmitter */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* Static Memory Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* Parallel I/O Controller C */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* USART 1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+SAM_PID_USART2) /* USART 2 */ +#define SAM_IRQ_USART3 (SAM_IRQ_EXTINT+SAM_PID_USART3) /* USART 3 */ +#define SAM_IRQ_HSMCI (SAM_IRQ_EXTINT+SAM_PID_HSMCI) /* High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWI0 (SAM_IRQ_EXTINT+SAM_PID_TWI0) /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 (SAM_IRQ_EXTINT+SAM_PID_TWI1) /* Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* Serial Peripheral Interface */ +#define SAM_IRQ_SSC (SAM_IRQ_EXTINT+SAM_PID_SSC) /* Synchronous Serial Controller */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* Timer Counter 2 */ +#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* Pulse Width Modulation Controller */ +#define SAM_IRQ_ADC12B (SAM_IRQ_EXTINT+SAM_PID_ADC12B) /* 12-bit ADC Controller */ +#define SAM_IRQ_ADC (SAM_IRQ_EXTINT+SAM_PID_ADC) /* 10-bit ADC Controller */ +#define SAM_IRQ_DMAC (SAM_IRQ_EXTINT+SAM_PID_DMAC) /* DMA Controller */ +#define SAM_IRQ_UDPHS (SAM_IRQ_EXTINT+SAM_PID_UDPHS) /* USB Device High Speed */ +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C) */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM3U_IRQ_H */ + diff --git a/arch/arm/include/sam34/sam3x_irq.h b/arch/arm/include/sam34/sam3x_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f9de5513bee51264d390b4f7056469e4d8494995 --- /dev/null +++ b/arch/arm/include/sam34/sam3x_irq.h @@ -0,0 +1,432 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam3x_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM3X_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM3X_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM3X Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_PID_EEFC1 (7) /* Enhanced Embedded Flash Controller 1 */ +#define SAM_PID_UART0 (8) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_SMC (9) /* Static Memory Controller */ +#define SAM_PID_SDRAMC (10) /* Synchronous Dynamic RAM Controller */ +#define SAM_PID_PIOA (11) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (12) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (13) /* Parallel I/O Controller C */ +#define SAM_PID_PIOD (14) /* Parallel I/O Controller D */ +#define SAM_PID_PIOE (15) /* Parallel I/O Controller E */ +#define SAM_PID_PIOF (16) /* Parallel I/O Controller F */ +#define SAM_PID_USART0 (17) /* USART 0 */ +#define SAM_PID_USART1 (18) /* USART 1 */ +#define SAM_PID_USART2 (19) /* USART 2 */ +#define SAM_PID_USART3 (20) /* USART 3 */ +#define SAM_PID_HSMCI (21) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWI0 (22) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (23) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (24) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SPI1 (25) /* Serial Peripheral Interface 2 */ +#define SAM_PID_SSC (26) /* Synchronous Serial Controller */ +#define SAM_PID_TC0 (27) /* Timer Counter 0 */ +#define SAM_PID_TC1 (28) /* Timer Counter 1 */ +#define SAM_PID_TC2 (29) /* Timer Counter 2 */ +#define SAM_PID_TC3 (30) /* Timer Counter 3 */ +#define SAM_PID_TC4 (31) /* Timer Counter 4 */ +#define SAM_PID_TC5 (32) /* Timer Counter 5 */ +#define SAM_PID_TC6 (33) /* Timer Counter 6 */ +#define SAM_PID_TC7 (34) /* Timer Counter 7 */ +#define SAM_PID_TC8 (35) /* Timer Counter 8 */ +#define SAM_PID_PWM (36) /* Pulse Width Modulation Controller */ +#define SAM_PID_ADC (37) /* ADC Controller */ +#define SAM_PID_DACC (38) /* DAC Controller */ +#define SAM_PID_DMAC (39) /* DMA Controller */ +#define SAM_PID_UOTGHS (40) /* USB OTG High Speed */ +#define SAM_PID_TRNG (41) /* True Random Number Generator */ +#define SAM_PID_EMAC (42) /* Ethernet MAC */ +#define SAM_PID_CAN0 (43) /* CAN Controller 0 */ +#define SAM_PID_CAN1 (44) /* CAN Controller 1 */ + +#define NR_PIDS (45) /* Number of peripheral identifiers */ + +/* External interrupts (vectors >= 16) */ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EEFC0) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_IRQ_EEFC1 (SAM_IRQ_EXTINT+SAM_PID_EEFC1) /* Enhanced Embedded Flash Controller 1 */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* Universal Asynchronous Receiver Transmitter */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* Static Memory Controller */ +#define SAM_IRQ_SDRAMC (SAM_IRQ_EXTINT+SAM_PID_SDRAMC) /* Synchronous Dynamic RAM Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* Parallel I/O Controller C */ +#define SAM_IRQ_PIOD (SAM_IRQ_EXTINT+SAM_PID_PIOD) /* Parallel I/O Controller D */ +#define SAM_IRQ_PIOE (SAM_IRQ_EXTINT+SAM_PID_PIOE) /* Parallel I/O Controller E */ +#define SAM_IRQ_PIOF (SAM_IRQ_EXTINT+SAM_PID_PIOF) /* Parallel I/O Controller F */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* USART 1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+SAM_PID_USART2) /* USART 2 */ +#define SAM_IRQ_USART3 (SAM_IRQ_EXTINT+SAM_PID_USART3) /* USART 3 */ +#define SAM_IRQ_HSMCI (SAM_IRQ_EXTINT+SAM_PID_HSMCI) /* High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWI0 (SAM_IRQ_EXTINT+SAM_PID_TWI0) /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 (SAM_IRQ_EXTINT+SAM_PID_TWI1) /* Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SPI1 (SAM_IRQ_EXTINT+SAM_PID_SPI1) /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_SSC (SAM_IRQ_EXTINT+SAM_PID_SSC) /* Synchronous Serial Controller */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* Timer Counter 5 */ +#define SAM_IRQ_TC6 (SAM_IRQ_EXTINT+SAM_PID_TC6) /* Timer Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_EXTINT+SAM_PID_TC7) /* Timer Counter 7 */ +#define SAM_IRQ_TC8 (SAM_IRQ_EXTINT+SAM_PID_TC8) /* Timer Counter 8 */ +#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* Pulse Width Modulation Controller */ +#define SAM_IRQ_ADC (SAM_IRQ_EXTINT+SAM_PID_ADC) /* ADC Controller */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+SAM_PID_DACC) /* DAC Controller */ +#define SAM_IRQ_DMAC (SAM_IRQ_EXTINT+SAM_PID_DMAC) /* DMA Controller */ +#define SAM_IRQ_UOTGHS (SAM_IRQ_EXTINT+SAM_PID_UOTGHS) /* USB OTG High Speed */ +#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+SAM_PID_TRNG) /* True Random Number Generator */ +#define SAM_IRQ_EMAC (SAM_IRQ_EXTINT+SAM_PID_EMAC) /* Ethernet MAC */ +#define SAM_IRQ_CAN0 (SAM_IRQ_EXTINT+SAM_PID_CAN0) /* CAN Controller 0 */ +#define SAM_IRQ_CAN1 (SAM_IRQ_EXTINT+SAM_PID_CAN1) /* CAN Controller 1 */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Number of external interrupts */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C/D/E/F) */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOD_IRQ +# define SAM_IRQ_GPIOD_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_GPIOD_PINS+0) /* GPIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_GPIOD_PINS+1) /* GPIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_GPIOD_PINS+2) /* GPIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_GPIOD_PINS+3) /* GPIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_GPIOD_PINS+4) /* GPIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_GPIOD_PINS+5) /* GPIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_GPIOD_PINS+6) /* GPIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_GPIOD_PINS+7) /* GPIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_GPIOD_PINS+8) /* GPIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_GPIOD_PINS+9) /* GPIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_GPIOD_PINS+10) /* GPIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_GPIOD_PINS+11) /* GPIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_GPIOD_PINS+12) /* GPIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_GPIOD_PINS+13) /* GPIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_GPIOD_PINS+14) /* GPIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_GPIOD_PINS+15) /* GPIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_GPIOD_PINS+16) /* GPIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_GPIOD_PINS+17) /* GPIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_GPIOD_PINS+18) /* GPIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_GPIOD_PINS+19) /* GPIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_GPIOD_PINS+20) /* GPIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_GPIOD_PINS+21) /* GPIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_GPIOD_PINS+22) /* GPIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_GPIOD_PINS+23) /* GPIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_GPIOD_PINS+24) /* GPIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_GPIOD_PINS+25) /* GPIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_GPIOD_PINS+26) /* GPIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_GPIOD_PINS+27) /* GPIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_GPIOD_PINS+28) /* GPIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_GPIOD_PINS+29) /* GPIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_GPIOD_PINS+30) /* GPIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_GPIOD_PINS+31) /* GPIOD, PIN 31 */ +# define SAM_NGPIODIRQS 32 +#else +# define SAM_NGPIODIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOE_IRQ +# define SAM_IRQ_GPIOE_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + SAM_NGPIODIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_GPIOE_PINS+0) /* GPIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_GPIOE_PINS+1) /* GPIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_GPIOE_PINS+2) /* GPIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_GPIOE_PINS+3) /* GPIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_GPIOE_PINS+4) /* GPIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_GPIOE_PINS+5) /* GPIOE, PIN 5 */ +# define SAM_IRQ_PE6 (SAM_IRQ_GPIOE_PINS+6) /* GPIOE, PIN 6 */ +# define SAM_IRQ_PE7 (SAM_IRQ_GPIOE_PINS+7) /* GPIOE, PIN 7 */ +# define SAM_IRQ_PE8 (SAM_IRQ_GPIOE_PINS+8) /* GPIOE, PIN 8 */ +# define SAM_IRQ_PE9 (SAM_IRQ_GPIOE_PINS+9) /* GPIOE, PIN 9 */ +# define SAM_IRQ_PE10 (SAM_IRQ_GPIOE_PINS+10) /* GPIOE, PIN 10 */ +# define SAM_IRQ_PE11 (SAM_IRQ_GPIOE_PINS+11) /* GPIOE, PIN 11 */ +# define SAM_IRQ_PE12 (SAM_IRQ_GPIOE_PINS+12) /* GPIOE, PIN 12 */ +# define SAM_IRQ_PE13 (SAM_IRQ_GPIOE_PINS+13) /* GPIOE, PIN 13 */ +# define SAM_IRQ_PE14 (SAM_IRQ_GPIOE_PINS+14) /* GPIOE, PIN 14 */ +# define SAM_IRQ_PE15 (SAM_IRQ_GPIOE_PINS+15) /* GPIOE, PIN 15 */ +# define SAM_IRQ_PE16 (SAM_IRQ_GPIOE_PINS+16) /* GPIOE, PIN 16 */ +# define SAM_IRQ_PE17 (SAM_IRQ_GPIOE_PINS+17) /* GPIOE, PIN 17 */ +# define SAM_IRQ_PE18 (SAM_IRQ_GPIOE_PINS+18) /* GPIOE, PIN 18 */ +# define SAM_IRQ_PE19 (SAM_IRQ_GPIOE_PINS+19) /* GPIOE, PIN 19 */ +# define SAM_IRQ_PE20 (SAM_IRQ_GPIOE_PINS+20) /* GPIOE, PIN 20 */ +# define SAM_IRQ_PE21 (SAM_IRQ_GPIOE_PINS+21) /* GPIOE, PIN 21 */ +# define SAM_IRQ_PE22 (SAM_IRQ_GPIOE_PINS+22) /* GPIOE, PIN 22 */ +# define SAM_IRQ_PE23 (SAM_IRQ_GPIOE_PINS+23) /* GPIOE, PIN 23 */ +# define SAM_IRQ_PE24 (SAM_IRQ_GPIOE_PINS+24) /* GPIOE, PIN 24 */ +# define SAM_IRQ_PE25 (SAM_IRQ_GPIOE_PINS+25) /* GPIOE, PIN 25 */ +# define SAM_IRQ_PE26 (SAM_IRQ_GPIOE_PINS+26) /* GPIOE, PIN 26 */ +# define SAM_IRQ_PE27 (SAM_IRQ_GPIOE_PINS+27) /* GPIOE, PIN 27 */ +# define SAM_IRQ_PE28 (SAM_IRQ_GPIOE_PINS+28) /* GPIOE, PIN 28 */ +# define SAM_IRQ_PE29 (SAM_IRQ_GPIOE_PINS+29) /* GPIOE, PIN 29 */ +# define SAM_IRQ_PE30 (SAM_IRQ_GPIOE_PINS+30) /* GPIOE, PIN 30 */ +# define SAM_IRQ_PE31 (SAM_IRQ_GPIOE_PINS+31) /* GPIOE, PIN 31 */ +# define SAM_NGPIOEIRQS 32 +#else +# define SAM_NGPIOEIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOF_IRQ +# define SAM_IRQ_GPIOF_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + SAM_NGPIODIRQS + \ + SAM_NGPIOEIRQS) +# define SAM_IRQ_PF0 (SAM_IRQ_GPIOF_PINS+0) /* GPIOF, PIN 0 */ +# define SAM_IRQ_PF1 (SAM_IRQ_GPIOF_PINS+1) /* GPIOF, PIN 1 */ +# define SAM_IRQ_PF2 (SAM_IRQ_GPIOF_PINS+2) /* GPIOF, PIN 2 */ +# define SAM_IRQ_PF3 (SAM_IRQ_GPIOF_PINS+3) /* GPIOF, PIN 3 */ +# define SAM_IRQ_PF4 (SAM_IRQ_GPIOF_PINS+4) /* GPIOF, PIN 4 */ +# define SAM_IRQ_PF5 (SAM_IRQ_GPIOF_PINS+5) /* GPIOF, PIN 5 */ +# define SAM_IRQ_PF6 (SAM_IRQ_GPIOF_PINS+6) /* GPIOF, PIN 6 */ +# define SAM_IRQ_PF7 (SAM_IRQ_GPIOF_PINS+7) /* GPIOF, PIN 7 */ +# define SAM_IRQ_PF8 (SAM_IRQ_GPIOF_PINS+8) /* GPIOF, PIN 8 */ +# define SAM_IRQ_PF9 (SAM_IRQ_GPIOF_PINS+9) /* GPIOF, PIN 9 */ +# define SAM_IRQ_PF10 (SAM_IRQ_GPIOF_PINS+10) /* GPIOF, PIN 10 */ +# define SAM_IRQ_PF11 (SAM_IRQ_GPIOF_PINS+11) /* GPIOF, PIN 11 */ +# define SAM_IRQ_PF12 (SAM_IRQ_GPIOF_PINS+12) /* GPIOF, PIN 12 */ +# define SAM_IRQ_PF13 (SAM_IRQ_GPIOF_PINS+13) /* GPIOF, PIN 13 */ +# define SAM_IRQ_PF14 (SAM_IRQ_GPIOF_PINS+14) /* GPIOF, PIN 14 */ +# define SAM_IRQ_PF15 (SAM_IRQ_GPIOF_PINS+15) /* GPIOF, PIN 15 */ +# define SAM_IRQ_PF16 (SAM_IRQ_GPIOF_PINS+16) /* GPIOF, PIN 16 */ +# define SAM_IRQ_PF17 (SAM_IRQ_GPIOF_PINS+17) /* GPIOF, PIN 17 */ +# define SAM_IRQ_PF18 (SAM_IRQ_GPIOF_PINS+18) /* GPIOF, PIN 18 */ +# define SAM_IRQ_PF19 (SAM_IRQ_GPIOF_PINS+19) /* GPIOF, PIN 19 */ +# define SAM_IRQ_PF20 (SAM_IRQ_GPIOF_PINS+20) /* GPIOF, PIN 20 */ +# define SAM_IRQ_PF21 (SAM_IRQ_GPIOF_PINS+21) /* GPIOF, PIN 21 */ +# define SAM_IRQ_PF22 (SAM_IRQ_GPIOF_PINS+22) /* GPIOF, PIN 22 */ +# define SAM_IRQ_PF23 (SAM_IRQ_GPIOF_PINS+23) /* GPIOF, PIN 23 */ +# define SAM_IRQ_PF24 (SAM_IRQ_GPIOF_PINS+24) /* GPIOF, PIN 24 */ +# define SAM_IRQ_PF25 (SAM_IRQ_GPIOF_PINS+25) /* GPIOF, PIN 25 */ +# define SAM_IRQ_PF26 (SAM_IRQ_GPIOF_PINS+26) /* GPIOF, PIN 26 */ +# define SAM_IRQ_PF27 (SAM_IRQ_GPIOF_PINS+27) /* GPIOF, PIN 27 */ +# define SAM_IRQ_PF28 (SAM_IRQ_GPIOF_PINS+28) /* GPIOF, PIN 28 */ +# define SAM_IRQ_PF29 (SAM_IRQ_GPIOF_PINS+29) /* GPIOF, PIN 29 */ +# define SAM_IRQ_PF30 (SAM_IRQ_GPIOF_PINS+30) /* GPIOF, PIN 30 */ +# define SAM_IRQ_PF31 (SAM_IRQ_GPIOF_PINS+31) /* GPIOF, PIN 31 */ +# define SAM_NGPIOFIRQS 32 +#else +# define SAM_NGPIOFIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + \ + SAM_NGPIODIRQS + SAM_NGPIOEIRQS + SAM_NGPIOFIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM3X_IRQ_H */ + diff --git a/arch/arm/include/sam34/sam4cm_irq.h b/arch/arm/include/sam34/sam4cm_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..096d7357051c950b4c763903921854f76377af02 --- /dev/null +++ b/arch/arm/include/sam34/sam4cm_irq.h @@ -0,0 +1,305 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam4cm_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM4CM_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM4CM_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM4CM Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_PID_RESERVED_7 (7) /* Reserved */ +#define SAM_PID_UART0 (8) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_RESERVED_9 (9) /* Reserved */ +#define SAM_PID_SMC (10) /* Static Memory Controller */ +#define SAM_PID_PIOA (11) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (12) /* Parallel I/O Controller B */ +#define SAM_PID_RESERVED_13 (13) /* Reserved */ +#define SAM_PID_USART0 (14) /* USART 0 */ +#define SAM_PID_USART1 (15) /* USART 1 */ +#define SAM_PID_USART2 (16) /* USART 2 */ +#define SAM_PID_USART3 (17) /* USART 3 */ +#define SAM_PID_RESERVED_18 (18) /* Reserved */ +#define SAM_PID_TWI0 (19) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (20) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (21) /* Serial Peripheral Interface */ +#define SAM_PID_RESERVED_22 (22) /* Reserved */ +#define SAM_PID_TC0 (23) /* Timer Counter 0 */ +#define SAM_PID_TC1 (24) /* Timer Counter 1 */ +#define SAM_PID_TC2 (25) /* Timer Counter 2 */ +#define SAM_PID_TC3 (26) /* Timer Counter 3 */ +#define SAM_PID_TC4 (27) /* Timer Counter 4 */ +#define SAM_PID_TC5 (28) /* Timer Counter 5 */ +#define SAM_PID_ADC (29) /* Analog To Digital Converter */ +#define SAM_PID_ARM (30) /* FPU signals (only on CM4P1 core): FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ +#define SAM_PID_IPC0 (31) /* Interprocessor communication 0 */ +#define SAM_PID_SLCDC (32) /* Segment LCD Controller */ +#define SAM_PID_TRNG (33) /* True Random Generator */ +#define SAM_PID_ICM (34) /* Integrity Check Module */ +#define SAM_PID_CPKCC (35) /* Classical Public Key Cryptography Controller */ +#define SAM_PID_AES (36) /* Advanced Enhanced Standard */ +#define SAM_PID_PIOC (37) /* Parallel I/O Controller C */ +#define SAM_PID_UART1 (38) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_PID_IPC1 (39) /* Interprocessor communication 1 */ +#define SAM_PID_RESERVED_40 (40) /* Reserved */ +#define SAM_PID_PWM (41) /* Pulse Width Modulation */ +#define SAM_PID_SRAM (42) /* SRAM1 (I/D Code bus of CM4P1), SRAM2 (Systembus of CM4P1) */ +#define SAM_PID_SMC1 (43) /* Static Memory Controller 1 */ +#define NR_PIDS (44) /* Number of peripheral identifiers */ + +/* External interrupts (vectors >= 16) */ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* PID 0: Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* PID 1: Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* PID 2: Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* PID 3: Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* PID 4: Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* PID 5: Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EEFC0) /* PID 6: Enhanced Embedded Flash Controller 0 */ +#define SAM_IRQ_RESERVED_7 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_7) /* PID 7: Reserved */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* PID 8: Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_IRQ_RESERVED_9 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_9) /* PID 9: Reserved */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* PID 10: Static Memory Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* PID 11: Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* PID 12: Parallel I/O Controller B */ +#define SAM_IRQ_RESERVED_13 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_13) /* PID 13: Reserved */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* PID 14: USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* PID 15: USART 1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+SAM_PID_USART2) /* PID 16: USART 2 */ +#define SAM_IRQ_USART3 (SAM_IRQ_EXTINT+SAM_PID_USART3) /* PID 17: USART 3 */ +#define SAM_IRQ_RESERVED_18 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_18) /* PID 18: Reserved */ +#define SAM_IRQ_TWI0 (SAM_IRQ_EXTINT+SAM_PID_TWI0) /* PID 19: Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 (SAM_IRQ_EXTINT+SAM_PID_TWI1) /* PID 20: Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* PIC 21: Serial Peripheral Interface */ +#define SAM_IRQ_RESERVED_22 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_22) /* PID 22: Reserved */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* PID 23: Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* PID 24: Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* PID 25: Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* PID 26: Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* PID 27: Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* PID 28: Timer Counter 5 */ +#define SAM_IRQ_ADC (SAM_IRQ_EXTINT+SAM_PID_ADC) /* PID 29: Analog To Digital Converter */ +#define SAM_IRQ_ARM (SAM_IRQ_EXTINT+SAM_PID_ARM) /* PID 30: FPU signals (only on CM4P1 core): FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ +#define SAM_IRQ_IPC0 (SAM_IRQ_EXTINT+SAM_PID_IPC0) /* PID 31: Interprocessor communication 0 */ +#define SAM_IRQ_SLCDC (SAM_IRQ_EXTINT+SAM_PID_SLCDC) /* PID 32: Segment LCD Controller */ +#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+SAM_PID_TRNG) /* PID 33: True Random Generator */ +#define SAM_IRQ_ICM (SAM_IRQ_EXTINT+SAM_PID_ICM) /* PID 34: Integrity Check Module */ +#define SAM_IRQ_CPKCC (SAM_IRQ_EXTINT+SAM_PID_CPKCC) /* PID 35: Classical Public Key Cryptography Controller */ +#define SAM_IRQ_AES (SAM_IRQ_EXTINT+SAM_PID_AES) /* PID 36: Advanced Enhanced Standard */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* PID 37: Parallel I/O Controller C */ +#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* PID 38: Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_IRQ_IPC1 (SAM_IRQ_EXTINT+SAM_PID_IPC1) /* PID 39: Interprocessor communication 1 */ +#define SAM_IRQ_RESERVED_40 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_40) /* PID 40: Reserved */ +#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* PID 41: Pulse Width Modulation */ +#define SAM_IRQ_SRAM (SAM_IRQ_EXTINT+SAM_PID_SRAM) /* PID 42: SRAM1 (I/D Code bus of CM4P1), SRAM2 (Systembus of CM4P1) */ +#define SAM_IRQ_SMC1 (SAM_IRQ_EXTINT+SAM_PID_SMC1) /* PID 43: Static Memory Controller 1 */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT + NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C) */ + +#ifdef CONFIG_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM4CM_IRQ_H */ diff --git a/arch/arm/include/sam34/sam4e_irq.h b/arch/arm/include/sam34/sam4e_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..fd868899839bd8f6dd4f66cd9f769932473f1904 --- /dev/null +++ b/arch/arm/include/sam34/sam4e_irq.h @@ -0,0 +1,339 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam4e_irq.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM4E_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM4E_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM4E Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller */ +#define SAM_PID_UART0 (7) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_SMC (8) /* Static Memory Controller */ +#define SAM_PID_PIOA (9) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (10) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (11) /* Parallel I/O Controller C */ +#define SAM_PID_PIOD (12) /* Parallel I/O Controller D */ +#define SAM_PID_PIOE (13) /* Parallel I/O Controller E */ +#define SAM_PID_USART0 (14) /* USART 0 */ +#define SAM_PID_USART1 (15) /* USART 1 */ +#define SAM_PID_HSMCI (16) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWI0 (17) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (18) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (19) /* Serial Peripheral Interface */ +#define SAM_PID_DMAC (20) /* DMAC */ +#define SAM_PID_TC0 (21) /* Timer Counter 0 */ +#define SAM_PID_TC1 (22) /* Timer Counter 1 */ +#define SAM_PID_TC2 (23) /* Timer Counter 2 */ +#define SAM_PID_TC3 (24) /* Timer Counter 3 */ +#define SAM_PID_TC4 (25) /* Timer Counter 4 */ +#define SAM_PID_TC5 (26) /* Timer Counter 5 */ +#define SAM_PID_TC6 (27) /* Timer Counter 6 */ +#define SAM_PID_TC7 (28) /* Timer Counter 7 */ +#define SAM_PID_TC8 (29) /* Timer Counter 8 */ +#define SAM_PID_AFEC0 (30) /* Analog Front End 0 */ +#define SAM_PID_AFEC1 (31) /* Analog Front End 1 */ +#define SAM_PID_DACC (32) /* Digital to Analog Converter */ +#define SAM_PID_ACC (33) /* Analog Comparator */ +#define SAM_PID_ARM (34) /* FPU signals: FPIXC, FPOFC, FPUFC, FPIOC, FPDZC,FPIDC, FPIXC */ +#define SAM_PID_UDP (35) /* USB Device */ +#define SAM_PID_PWM (36) /* PWM */ +#define SAM_PID_CAN0 (37) /* CAN0 */ +#define SAM_PID_CAN1 (38) /* CAN1 */ +#define SAM_PID_AES (39) /* AES */ + /* 40-43: Reserved */ +#define SAM_PID_EMAC (44) /* EMAC */ +#define SAM_PID_UART1 (45) /* UART */ + /* 46: Reserved */ +#define NR_PIDS (47) /* Number of peripheral identifiers */ + +/* External interrupts (priority levels >= 256*/ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EEFC0) /* Enhanced Embedded Flash Controller */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* Parallel I/O Controller B */ + +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* Parallel I/O Controller C */ +#define SAM_IRQ_PIOD (SAM_IRQ_EXTINT+SAM_PID_PIOD) /* Parallel I/O Controller D */ +#define SAM_IRQ_PIOE (SAM_IRQ_EXTINT+SAM_PID_PIOE) /* Parallel I/O Controller E */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* USART 1 */ +#define SAM_IRQ_HSMCI (SAM_IRQ_EXTINT+SAM_PID_HSMCI) /* High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWI0 (SAM_IRQ_EXTINT+SAM_PID_TWI0) /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 (SAM_IRQ_EXTINT+SAM_PID_TWI1) /* Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* Serial Peripheral Interface */ +#define SAM_IRQ_DMAC (SAM_IRQ_EXTINT+SAM_PID_DMAC) /* DMAC */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* Timer Counter 5 */ +#define SAM_IRQ_TC6 (SAM_IRQ_EXTINT+SAM_PID_TC6) /* Timer Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_EXTINT+SAM_PID_TC7) /* Timer Counter 7 */ +#define SAM_IRQ_TC8 (SAM_IRQ_EXTINT+SAM_PID_TC8) /* Timer Counter 8 */ +#define SAM_IRQ_AFEC0 (SAM_IRQ_EXTINT+SAM_PID_AFEC0) /* Analog Front End 0 */ +#define SAM_IRQ_AFEC1 (SAM_IRQ_EXTINT+SAM_PID_AFEC1) /* Analog Front End 1 */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+SAM_PID_DACC) /* Digital to Analog Converter */ +#define SAM_IRQ_ACC (SAM_IRQ_EXTINT+SAM_PID_ACC) /* Analog Comparator */ +#define SAM_IRQ_ARM (SAM_IRQ_EXTINT+SAM_PID_ARM) /* FPU signals: FPIXC, FPOFC, FPUFC, FPIOC, FPDZC,FPIDC, FPIXC */ +#define SAM_IRQ_UDP (SAM_IRQ_EXTINT+SAM_PID_UDP) /* USB Device */ +#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* PWM */ +#define SAM_IRQ_CAN0 (SAM_IRQ_EXTINT+SAM_PID_CAN0) /* CAN0 */ +#define SAM_IRQ_CAN1 (SAM_IRQ_EXTINT+SAM_PID_CAN1) /* CAN1 */ +#define SAM_IRQ_AES (SAM_IRQ_EXTINT+SAM_PID_AES) /* AES */ +#define SAM_IRQ_EMAC (SAM_IRQ_EXTINT+SAM_PID_EMAC) /* EMAC */ +#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* UART1 */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C) */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_NGPIOBIRQS 15 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOD_IRQ +# define SAM_IRQ_GPIOD_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_GPIOD_PINS+0) /* GPIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_GPIOD_PINS+1) /* GPIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_GPIOD_PINS+2) /* GPIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_GPIOD_PINS+3) /* GPIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_GPIOD_PINS+4) /* GPIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_GPIOD_PINS+5) /* GPIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_GPIOD_PINS+6) /* GPIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_GPIOD_PINS+7) /* GPIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_GPIOD_PINS+8) /* GPIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_GPIOD_PINS+9) /* GPIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_GPIOD_PINS+10) /* GPIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_GPIOD_PINS+11) /* GPIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_GPIOD_PINS+12) /* GPIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_GPIOD_PINS+13) /* GPIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_GPIOD_PINS+14) /* GPIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_GPIOD_PINS+15) /* GPIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_GPIOD_PINS+16) /* GPIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_GPIOD_PINS+17) /* GPIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_GPIOD_PINS+18) /* GPIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_GPIOD_PINS+19) /* GPIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_GPIOD_PINS+20) /* GPIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_GPIOD_PINS+21) /* GPIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_GPIOD_PINS+22) /* GPIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_GPIOD_PINS+23) /* GPIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_GPIOD_PINS+24) /* GPIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_GPIOD_PINS+25) /* GPIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_GPIOD_PINS+26) /* GPIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_GPIOD_PINS+27) /* GPIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_GPIOD_PINS+28) /* GPIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_GPIOD_PINS+29) /* GPIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_GPIOD_PINS+30) /* GPIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_GPIOD_PINS+31) /* GPIOD, PIN 31 */ +# define SAM_NGPIODIRQS 32 +#else +# define SAM_NGPIODIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOE_IRQ +# define SAM_IRQ_GPIOE_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_GPIOE_PINS+0) /* GPIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_GPIOE_PINS+1) /* GPIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_GPIOE_PINS+2) /* GPIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_GPIOE_PINS+3) /* GPIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_GPIOE_PINS+4) /* GPIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_GPIOE_PINS+5) /* GPIOE, PIN 5 */ +# define SAM_NGPIOEIRQS 6 +#else +# define SAM_NGPIOEIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + \ + SAM_NGPIODIRQS + SAM_NGPIOEIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM4E_IRQ_H */ diff --git a/arch/arm/include/sam34/sam4l_irq.h b/arch/arm/include/sam34/sam4l_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..98441ab9da3be59fecc4f95b6176a3f11dadbeae --- /dev/null +++ b/arch/arm/include/sam34/sam4l_irq.h @@ -0,0 +1,338 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam4l_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM4L_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM4L_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM4L Peripheral Identifiers. NOTE: Interrupts are not tied to the DMA peripheral + * identifiers in the SAM4L as they were with the SAM3U. However, for consistency, those + * peripheral identifiers are defined in this file as well. + */ + +#define SAM_PID_USART0_RHR (0) /* DIR=RX REGISTER: USART0 RHR */ +#define SAM_PID_USART1_RHR (1) /* DIR=RX REGISTER: USART1 RHR */ +#define SAM_PID_USART2_RHR (2) /* DIR=RX REGISTER: USART2 RHR */ +#define SAM_PID_USART3_RHR (3) /* DIR=RX REGISTER: USART3 RHR */ +#define SAM_PID_SPI0_RDR (4) /* DIR=RX REGISTER: SPI RDR */ +#define SAM_PID_TWIM0_RHR (5) /* DIR=RX REGISTER: TWIM0 RHR */ +#define SAM_PID_TWIM1_RHR (6) /* DIR=RX REGISTER: TWIM1 RHR */ +#define SAM_PID_TWIM2_RHR (7) /* DIR=RX REGISTER: TWIM2 RHR */ +#define SAM_PID_TWIM3_RHR (8) /* DIR=RX REGISTER: TWIM3 RHR */ +#define SAM_PID_TWIS0_RHR (9) /* DIR=RX REGISTER: TWIS0 RHR */ +#define SAM_PID_TWIS1_RHR (10) /* DIR=RX REGISTER: TWIS1 RHR */ +#define SAM_PID_ADCIFE_LCV (11) /* DIR=RX REGISTER: ADCIFE LCV */ +#define SAM_PID_CATB_RX (12) /* DIR=RX REGISTER: CATB Multiple */ + /* 13: Reserved */ +#define SAM_PID_IISC0_RHR (14) /* DIR=RX REGISTER: IISC RHR (CH0) */ +#define SAM_PID_IISC1_RHR (15) /* DIR=RX REGISTER: IISC RHR (CH1) */ +#define SAM_PID_PARC_RHR (16) /* DIR=RX REGISTER: PARC RHR */ +#define SAM_PID_AESA_ODATA (17) /* DIR=RX REGISTER: AESA ODATA */ +#define SAM_PID_USART0_THR (18) /* DIR=TX REGISTER: USART0 THR */ +#define SAM_PID_USART1_THR (19) /* DIR=TX REGISTER: USART1 THR */ +#define SAM_PID_USART2_THR (20) /* DIR=TX REGISTER: USART2 THR */ +#define SAM_PID_USART3_THR (21) /* DIR=TX REGISTER: USART3 THR */ +#define SAM_PID_SPI0_TDR (22) /* DIR=TX REGISTER: SPI TDR */ +#define SAM_PID_TWIM0_THR (23) /* DIR=TX REGISTER: TWIM0 THR */ +#define SAM_PID_TWIM1_THR (24) /* DIR=TX REGISTER: TWIM1 THR */ +#define SAM_PID_TWIM2_THR (25) /* DIR=TX REGISTER: TWIM2 THR */ +#define SAM_PID_TWIM3_THR (26) /* DIR=TX REGISTER: TWIM3 THR */ +#define SAM_PID_TWIS0_THR (27) /* DIR=TX REGISTER: TWIS0 THR */ +#define SAM_PID_TWIS1_THR (28) /* DIR=TX REGISTER: TWIS1 THR */ +#define SAM_PID_ADCIFE_CDMA (29) /* DIR=TX REGISTER: ADCIFE CDMA */ +#define SAM_PID_CATB_TX (30) /* DIR=TX REGISTER: CATB Multiple */ +#define SAM_PID_ABDACB_SDR0 (31) /* DIR=TX REGISTER: ABDACB SDR0 */ +#define SAM_PID_ABDACB_SDR1 (32) /* DIR=TX REGISTER: ABDACB SDR1 */ +#define SAM_PID_IISC0_THR (33) /* DIR=TX REGISTER: IISC THR (CH0) */ +#define SAM_PID_IISC1_THR (34) /* DIR=TX REGISTER: IISC THR (CH1) */ +#define SAM_PID_DACC_CDR (35) /* DIR=TX REGISTER: DACC CDR */ +#define SAM_PID_AESA_IDATA (36) /* DIR=TX REGISTER: AESA IDATA */ +#define SAM_PID_LCDCA_ACMDR (37) /* DIR=TX REGISTER: LCDCA ACMDR */ +#define SAM_PID_LCDCA_ABMDR (38) /* DIR=TX REGISTER: LCDCA ABMDR */ + +/* External interrupts (vectors >= 16) */ + +#define SAM_IRQ_HFLASHC (SAM_IRQ_EXTINT+0) /* 0 Flash Controller */ +#define SAM_IRQ_PDCA0 (SAM_IRQ_EXTINT+1) /* 1 Peripheral DMA Controller 0 */ +#define SAM_IRQ_PDCA1 (SAM_IRQ_EXTINT+2) /* 2 Peripheral DMA Controller 1 */ +#define SAM_IRQ_PDCA2 (SAM_IRQ_EXTINT+3) /* 3 Peripheral DMA Controller 2 */ +#define SAM_IRQ_PDCA3 (SAM_IRQ_EXTINT+4) /* 4 Peripheral DMA Controller 3 */ +#define SAM_IRQ_PDCA4 (SAM_IRQ_EXTINT+5) /* 5 Peripheral DMA Controller 4 */ +#define SAM_IRQ_PDCA5 (SAM_IRQ_EXTINT+6) /* 6 Peripheral DMA Controller 5 */ +#define SAM_IRQ_PDCA6 (SAM_IRQ_EXTINT+7) /* 7 Peripheral DMA Controller 6 */ +#define SAM_IRQ_PDCA7 (SAM_IRQ_EXTINT+8) /* 8 Peripheral DMA Controller 7 */ +#define SAM_IRQ_PDCA8 (SAM_IRQ_EXTINT+9) /* 9 Peripheral DMA Controller 8 */ +#define SAM_IRQ_PDCA9 (SAM_IRQ_EXTINT+10) /* 10 Peripheral DMA Controller 9 */ +#define SAM_IRQ_PDCA10 (SAM_IRQ_EXTINT+11) /* 11 Peripheral DMA Controller 10 */ +#define SAM_IRQ_PDCA11 (SAM_IRQ_EXTINT+12) /* 12 Peripheral DMA Controller 11 */ +#define SAM_IRQ_PDCA12 (SAM_IRQ_EXTINT+13) /* 13 Peripheral DMA Controller 12 */ +#define SAM_IRQ_PDCA13 (SAM_IRQ_EXTINT+14) /* 14 Peripheral DMA Controller 13 */ +#define SAM_IRQ_PDCA14 (SAM_IRQ_EXTINT+15) /* 15 Peripheral DMA Controller 14 */ +#define SAM_IRQ_PDCA15 (SAM_IRQ_EXTINT+16) /* 16 Peripheral DMA Controller 15 */ +#define SAM_IRQ_CRCCU (SAM_IRQ_EXTINT+17) /* 17 CRC Calculation Unit */ +#define SAM_IRQ_USBC (SAM_IRQ_EXTINT+18) /* 18 USB 2.0 Interface */ +#define SAM_IRQ_PEVC_TR (SAM_IRQ_EXTINT+19) /* 19 Peripheral Event Controller TR */ +#define SAM_IRQ_PEVC_OV (SAM_IRQ_EXTINT+20) /* 20 Peripheral Event Controller OV */ +#define SAM_IRQ_AESA (SAM_IRQ_EXTINT+21) /* 21 Advanced Encryption Standard AESA */ +#define SAM_IRQ_PM (SAM_IRQ_EXTINT+22) /* 22 Power Manager */ +#define SAM_IRQ_SCIF (SAM_IRQ_EXTINT+23) /* 23 System Control Interface */ +#define SAM_IRQ_FREQM (SAM_IRQ_EXTINT+24) /* 24 Frequency Meter */ +#define SAM_IRQ_GPIO0 (SAM_IRQ_EXTINT+25) /* 25 General-Purpose Input/Output Controller 0 */ +#define SAM_IRQ_GPIO1 (SAM_IRQ_EXTINT+26) /* 26 General-Purpose Input/Output Controller 1 */ +#define SAM_IRQ_GPIO2 (SAM_IRQ_EXTINT+27) /* 27 General-Purpose Input/Output Controller 2 */ +#define SAM_IRQ_GPIO3 (SAM_IRQ_EXTINT+28) /* 28 General-Purpose Input/Output Controller 3 */ +#define SAM_IRQ_GPIO4 (SAM_IRQ_EXTINT+29) /* 29 General-Purpose Input/Output Controller 4 */ +#define SAM_IRQ_GPIO5 (SAM_IRQ_EXTINT+30) /* 30 General-Purpose Input/Output Controller 5 */ +#define SAM_IRQ_GPIO6 (SAM_IRQ_EXTINT+31) /* 31 General-Purpose Input/Output Controller 6 */ +#define SAM_IRQ_GPIO7 (SAM_IRQ_EXTINT+32) /* 32 General-Purpose Input/Output Controller 7 */ +#define SAM_IRQ_GPIO8 (SAM_IRQ_EXTINT+33) /* 33 General-Purpose Input/Output Controller 8 */ +#define SAM_IRQ_GPIO9 (SAM_IRQ_EXTINT+34) /* 34 General-Purpose Input/Output Controller 9 */ +#define SAM_IRQ_GPIO10 (SAM_IRQ_EXTINT+35) /* 35 General-Purpose Input/Output Controller 10 */ +#define SAM_IRQ_GPIO11 (SAM_IRQ_EXTINT+36) /* 36 General-Purpose Input/Output Controller 11 */ +#define SAM_IRQ_BPM (SAM_IRQ_EXTINT+37) /* 37 Backup Power Manager */ +#define SAM_IRQ_BSCIF (SAM_IRQ_EXTINT+38) /* 38 Backup System Control Interface */ +#define SAM_IRQ_AST_ALARM (SAM_IRQ_EXTINT+39) /* 39 Asynchronous Timer ALARM */ +#define SAM_IRQ_AST_PER (SAM_IRQ_EXTINT+40) /* 40 Asynchronous Timer PER */ +#define SAM_IRQ_AST_OVF (SAM_IRQ_EXTINT+41) /* 41 Asynchronous Timer OVF */ +#define SAM_IRQ_AST_READY (SAM_IRQ_EXTINT+42) /* 42 Asynchronous Timer READY */ +#define SAM_IRQ_AST_CLKREADY (SAM_IRQ_EXTINT+43) /* 43 Asynchronous Timer CLKREADY */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+44) /* 44 Watchdog Timer */ +#define SAM_IRQ_EIC1 (SAM_IRQ_EXTINT+45) /* 45 External Interrupt Controller 1 */ +#define SAM_IRQ_EIC2 (SAM_IRQ_EXTINT+46) /* 46 External Interrupt Controller 2 */ +#define SAM_IRQ_EIC3 (SAM_IRQ_EXTINT+47) /* 47 External Interrupt Controller 3 */ +#define SAM_IRQ_EIC4 (SAM_IRQ_EXTINT+48) /* 48 External Interrupt Controller 4 */ +#define SAM_IRQ_EIC5 (SAM_IRQ_EXTINT+49) /* 49 External Interrupt Controller 5 */ +#define SAM_IRQ_EIC6 (SAM_IRQ_EXTINT+50) /* 50 External Interrupt Controller 6 */ +#define SAM_IRQ_EIC7 (SAM_IRQ_EXTINT+51) /* 51 External Interrupt Controller 7 */ +#define SAM_IRQ_EIC8 (SAM_IRQ_EXTINT+52) /* 52 External Interrupt Controller 8 */ +#define SAM_IRQ_IISC (SAM_IRQ_EXTINT+53) /* 53 Inter-IC Sound (I2S) Controller */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+54) /* 54 Serial Peripheral Interface */ +#define SAM_IRQ_TC00 (SAM_IRQ_EXTINT+55) /* 55 Timer/Counter 0 */ +#define SAM_IRQ_TC01 (SAM_IRQ_EXTINT+56) /* 56 Timer/Counter 1 */ +#define SAM_IRQ_TC02 (SAM_IRQ_EXTINT+57) /* 57 Timer/Counter 2 */ +#define SAM_IRQ_TC10 (SAM_IRQ_EXTINT+58) /* 58 Timer/Counter 10 */ +#define SAM_IRQ_TC11 (SAM_IRQ_EXTINT+59) /* 59 Timer/Counter 11 */ +#define SAM_IRQ_TC12 (SAM_IRQ_EXTINT+60) /* 60 Timer/Counter 12 */ +#define SAM_IRQ_TWIM0 (SAM_IRQ_EXTINT+61) /* 61 Two-wire Master Interface TWIM0 */ +#define SAM_IRQ_TWIS0 (SAM_IRQ_EXTINT+62) /* 62 Two-wire Slave Interface TWIS0 */ +#define SAM_IRQ_TWIM1 (SAM_IRQ_EXTINT+63) /* 63 Two-wire Master Interface TWIM1 */ +#define SAM_IRQ_TWIS1 (SAM_IRQ_EXTINT+64) /* 64 Two-wire Slave Interface TWIS1 */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+65) /* 65 USART0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+66) /* 66 USART1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+67) /* 67 USART2 */ +#define SAM_IRQ_USART3 (SAM_IRQ_EXTINT+68) /* 68 USART3 */ +#define SAM_IRQ_ADCIFE (SAM_IRQ_EXTINT+69) /* 69 ADC controller interface */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+70) /* 70 DAC Controller */ +#define SAM_IRQ_ACIFC (SAM_IRQ_EXTINT+71) /* 71 Analog Comparator Interface */ +#define SAM_IRQ_ABDACB (SAM_IRQ_EXTINT+72) /* 72 Audio Bitstream DAC */ +#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+73) /* 73 True Random Number Generator */ +#define SAM_IRQ_PARC (SAM_IRQ_EXTINT+74) /* 74 Parallel Capture */ +#define SAM_IRQ_CATB (SAM_IRQ_EXTINT+75) /* 75 Capacitive Touch Module B */ +#define SAM_IRQ_TWIM2 (SAM_IRQ_EXTINT+77) /* 77 Two-wire Master Interface */ +#define SAM_IRQ_TWIM3 (SAM_IRQ_EXTINT+78) /* 78 Two-wire Master Interface */ +#define SAM_IRQ_LCDCA (SAM_IRQ_EXTINT+79) /* 79 LCD Controller A */ +#define SAM_IRQ_NEXTINT 80 /* Total number of external interrupt numbers */ + +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+SAM_IRQ_NEXTINT) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C) */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM4L_IRQ_H */ + diff --git a/arch/arm/include/sam34/sam4s_irq.h b/arch/arm/include/sam34/sam4s_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f46781d0d2ae8def5b4d2a990abcdcad6b1b7ec8 --- /dev/null +++ b/arch/arm/include/sam34/sam4s_irq.h @@ -0,0 +1,288 @@ +/**************************************************************************************** + * arch/arm/include/sam34/sam4s_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAM34_SAM4S_IRQ_H +#define __ARCH_ARM_INCLUDE_SAM34_SAM4S_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAM4S Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EEFC0 (6) /* Enhanced Embedded Flash Controller 0 */ +#define SAM_PID_EEFC1 (7) /* Enhanced Embedded Flash Controller 1 */ +#define SAM_PID_UART0 (8) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_UART1 (9) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_PID_SMC (10) /* Static Memory Controller */ +#define SAM_PID_PIOA (11) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (12) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (13) /* Parallel I/O Controller C */ +#define SAM_PID_USART0 (14) /* USART 0 */ +#define SAM_PID_USART1 (15) /* USART 1 */ +#define SAM_PID_RESERVED_16 (16) /* Reserved */ +#define SAM_PID_RESERVED_17 (17) /* Reserved */ +#define SAM_PID_HSMCI (18) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWI0 (19) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (20) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (21) /* Serial Peripheral Interface */ +#define SAM_PID_SSC (22) /* Synchronous Serial Controller */ +#define SAM_PID_TC0 (23) /* Timer Counter 0 */ +#define SAM_PID_TC1 (24) /* Timer Counter 1 */ +#define SAM_PID_TC2 (25) /* Timer Counter 2 */ +#define SAM_PID_TC3 (26) /* Timer Counter 3 */ +#define SAM_PID_TC4 (27) /* Timer Counter 4 */ +#define SAM_PID_TC5 (28) /* Timer Counter 5 */ +#define SAM_PID_ADC (29) /* Analog To Digital Converter */ +#define SAM_PID_DACC (30) /* Digital To Analog Converter */ +#define SAM_PID_PWM (31) /* Pulse Width Modulation */ +#define SAM_PID_CRCCU (32) /* CRC Calculation Unit */ +#define SAM_PID_ACC (33) /* Analog Comparator */ +#define SAM_PID_UDP (34) /* USB Device Port */ +#define NR_PIDS (35) /* Number of peripheral identifiers */ + +/* External interrupts (vectors >= 16) */ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* PID 0: Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* PID 1: Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* PID 2: Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* PID 3: Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* PID 4: Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* PID 5: Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EEFC0) /* PID 6: Enhanced Embedded Flash Controller 0 */ +#define SAM_IRQ_EEFC1 (SAM_IRQ_EXTINT+SAM_PID_EEFC1) /* PID 7: Enhanced Embedded Flash Controller 1 */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* PID 8: Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* PID 9: Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* PID 10: Static Memory Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* PID 11: Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* PID 12: Parallel I/O Controller B */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* PID 13: Parallel I/O Controller C */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* PID 14: USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* PID 15: USART 1 */ +#define SAM_IRQ_RESERVED_16 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_16) /* PID 16: Reserved */ +#define SAM_IRQ_RESERVED_17 (SAM_IRQ_EXTINT+SAM_PID_RESERVED_17) /* PID 17: Reserved */ +#define SAM_IRQ_HSMCI (SAM_IRQ_EXTINT+SAM_PID_HSMCI) /* PID 18: High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWI0 (SAM_IRQ_EXTINT+SAM_PID_TWI0) /* PID 19: Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 (SAM_IRQ_EXTINT+SAM_PID_TWI1) /* PID 20: Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* PIC 21: Serial Peripheral Interface */ +#define SAM_IRQ_SSC (SAM_IRQ_EXTINT+SAM_PID_SSC) /* PID 22: Synchronous Serial Controller */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* PID 23: Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* PID 24: Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* PID 25: Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* PID 26: Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* PID 27: Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* PID 28: Timer Counter 5 */ +#define SAM_IRQ_ADC (SAM_IRQ_EXTINT+SAM_PID_ADC) /* PID 29: Analog To Digital Converter */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+SAM_PID_DACC) /* PID 30: Digital To Analog Converter */ +#define SAM_IRQ_PWM (SAM_IRQ_EXTINT+SAM_PID_PWM) /* PID 31: Pulse Width Modulation */ +#define SAM_IRQ_CRCCU (SAM_IRQ_EXTINT+SAM_PID_CRCCU) /* PID 32: CRC Calculation Unit */ +#define SAM_IRQ_ACC (SAM_IRQ_EXTINT+SAM_PID_ACC) /* PID 33: Analog Comparator */ +#define SAM_IRQ_UDP (SAM_IRQ_EXTINT+SAM_PID_UDP) /* PID 34: USB Device Port */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT + NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA/B/C) */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAM34_SAM4S_IRQ_H */ + diff --git a/arch/arm/include/sama5/chip.h b/arch/arm/include/sama5/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..c2e6cf0932abb30b4e37353bc1c0e42e429a3a80 --- /dev/null +++ b/arch/arm/include/sama5/chip.h @@ -0,0 +1,219 @@ +/**************************************************************************************************** + * arch/arm/include/sama5/chip.h + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SAMA5_CHIP_H +#define __ARCH_ARM_INCLUDE_SAMA5_CHIP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* SAMA5D2 Family + * + * SAMA5D21 SAMA5D22 SAMA5D23 SAMA5D24 SAMA5D26 SAMA5D27 SAMA5D28 + * ------------------------- --------- --------- --------- --------- --------- --------- --------- + * Pin Count 196 196 196 256 289 289 289 + * Max. Operating Frequency 500 MHz 500 MHz 500 MHz 500 MHz 500 MHz 500 MHz 500 MHz + * CPU Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 + * Max I/O Pins 72 72 72 105 128 128 128 + * USB Transceiver 1 1 1 1 1 1 1 + * USB Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed + * USB Interface 2 2 2 3 3 3 3 + * SPI 6 6 6 7 7 7 7 + * QuadSPI 2 2 2 2 2 2 2 + * TWIHS (I2C) 6 6 6 7 7 7 7 + * UART 9 9 9 10 10 10 10 + * CAN - 1 1 - - 2 2 + * SDIO/SD/MMC 1 1 1 2 2 2 2 + * I2SC 2 2 2 2 2 2 2 + * SSC 2 2 2 2 2 2 2 + * Class D 1 1 1 2 2 2 2 + * PDMIC 1 1 1 2 2 2 2 + * Camera Interface 1 1 1 1 1 1 1 + * ADC Inputs 5 5 5 12 12 12 12 + * AESB - 1 1 1 - 1 1 + * SRAM (Kbytes) 128 128 128 128 128 128 128 + * DDR Bus 16-bit 16-bit 16-bit 16/32-bit 16/32-bit 16/32-bit 16/32-bit + * Timers 6 6 6 6 6 6 6 + * Tamper pins 6 6 6 2 8 8 8 + * Packages BGA196 BGA196 BGA196 BGA256 BGA289 BGA289 BGA289 + */ + +#if defined(CONFIG_ARCH_CHIP_ATSAMA5D21) || defined(CONFIG_ARCH_CHIP_ATSAMA5D22) || \ + defined(CONFIG_ARCH_CHIP_ATSAMA5D22) || defined(CONFIG_ARCH_CHIP_ATSAMA5D23) || \ + defined(CONFIG_ARCH_CHIP_ATSAMA5D24) || defined(CONFIG_ARCH_CHIP_ATSAMA5D26) || \ + defined(CONFIG_ARCH_CHIP_ATSAMA5D27) || defined(CONFIG_ARCH_CHIP_ATSAMA5D28) +# define ATSAMA5D2 1 /* SAMA5D2 family */ +# undef ATSAMA5D3 /* Not SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (128*1024) /* SRAM0: 128KB */ +#ifdef CONFIG_ARMV7A_L2CC_PL310 +# define SAM_ISRAM1_SIZE (0) /* (SRAM1 used for L2 cache )*/ +#else +# define SAM_ISRAM0_SIZE (64*1024) /* SRAM1: 128KB */ +#endif +# define SAM_NDMAC 2 /* (2) XDMA controllers */ +# define SAM_NDMACHAN 16 /* (16) DMA channels per XDMA controller */ + +/* SAMA5D3 Family + * + * ATSAMA5D31 ATSAMA5D33 ATSAMA5D34 ATSAMA5D35 ATSAMA5D36 + * ------------------------- ------------- ------------- ------------- ------------- ------------- + * Pin Count 324 324 324 324 324 + * Max. Operating Frequency 536 MHz 536 MHz 536 MHz 536 MHz 536 MHz + * CPU Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 Cortex-A5 + * Max I/O Pins 160 160 160 160 160 + * Ext Interrupts 160 160 160 160 160 + * USB Transceiver 3 3 3 3 3 + * USB Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed Hi-Speed + * USB Interface Host, Device Host, Device Host, Device Host, Device Host, Device + * SPI 6 6 6 6 6 + * TWI (I2C) 3 3 3 3 3 + * UART 7 5 5 7 7 + * CAN - - 2 2 2 + * LIN 4 4 4 4 4 + * SSC 2 2 2 2 2 + * Ethernet 1 1 1 2 2 + * SD / eMMC 3 2 3 2 3 + * Graphic LCD Yes Yes Yes - Yes + * Camera Interface Yes Yes Yes Yes Yes + * ADC channels 12 12 12 12 12 + * ADC Resolution (bits) 12 12 12 12 12 + * ADC Speed (ksps) 440 440 440 440 1000 + * Resistive Touch Screen Yes Yes Yes Yes Yes + * Crypto Engine AES/DES/ AES/DES/ AES/DES/ AES/DES/ AES/DES/ + * SHA/TRNG SHA/TRNG SHA/TRNG SHA/TRNG SHA/TRNG + * SRAM (Kbytes) 128 128 128 128 128 + * External Bus Interface 1 1 1 1 1 + * DRAM Memory DDR2/LPDDR, DDR2/LPDDR, DDR2/LPDDR, DDR2/LPDDR, DDR2/LPDDR, + * SDRAM/LPSDR SDRAM/LPSDR DDR2/LPDDR, DDR2/LPDDR, DDR2/LPDDR, + * NAND Interface Yes Yes Yes Yes Yes + * Temp. Range (deg C) -40 to 85 -40 to 85 -40 to 85 -40 to 85 -40 to 105 + * I/O Supply Class 1.8/3.3 1.8/3.3 1.8/3.3 1.8/3.3 1.8/3.3 + * Operating Voltage (Vcc) 1.08 to 1.32 1.08 to 1.32 1.08 to 1.32 1.08 to 1.322 1.08 to 1.32 + * FPU Yes Yes Yes Yes Yes + * MPU / MMU No/Yes No/Yes No/Yes No/Yes No/Yes + * Timers 5 5 5 6 6 + * Output Compare channels 6 6 6 6 6 + * Input Capture Channels 6 6 6 6 6 + * PWM Channels 4 4 4 4 4 + * 32kHz RTC Yes Yes Yes Yes Yes + * Packages LFBGA324_A LFBGA324_A LFBGA324_A LFBGA324_A LFBGA324_A + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D31) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) DMA controllers */ +# define SAM_NDMACHAN 8 /* (8) DMA channels per DMA controller */ +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D33) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) DMA controllers */ +# define SAM_NDMACHAN 8 /* (8) DMA channels per DMA controller */ +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D34) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) DMA controllers */ +# define SAM_NDMACHAN 8 /* (8) DMA channels per DMA controller */ +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D35) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) DMA controllers */ +# define SAM_NDMACHAN 8 /* (8) DMA channels per DMA controller */ +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D36) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# undef ATSAMA5D4 /* Not SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) DMA controllers */ +# define SAM_NDMACHAN 8 /* (8) DMA channels per DMA controller */ + +/* The SAMA5D4 series devices are similar to the SAMA5D3 family except that: + * + * - Some parts support a 32-bit DDR data path (SAMA5D42 and SAMA5D44) + * - Some parts support a Video Decoder (SAMA5D43 and SAMA5D44) + * - Includes an L2 data cache, NEON FPU, and TrustZone + * - New XDMAC DMA controller + * - There are few differences in the support peripherals. As examples: + * Gigbit Ethernet is not supported, for example; 10/100Base-T Ethernet + * is different. Additional instances of peripherals: USART4, TWI3, + * and SPI2. + */ + +#elif defined(CONFIG_ARCH_CHIP_ATSAMA5D41) || defined(CONFIG_ARCH_CHIP_ATSAMA5D42) || \ + defined(CONFIG_ARCH_CHIP_ATSAMA5D43) || defined(CONFIG_ARCH_CHIP_ATSAMA5D44) +# undef ATSAMA5D2 /* Not SAMA5D2 family */ +# undef ATSAMA5D3 /* Not SAMA5D3 family */ +# define ATSAMA5D4 1 /* SAMA5D4 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) +# define SAM_NDMAC 2 /* (2) XDMA controllers */ +# define SAM_NDMACHAN 16 /* (16) DMA channels per XDMA controller */ +#else +# error Unrecognized SAMAD5 chip +#endif + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_SAMA5_CHIP_H */ diff --git a/arch/arm/include/sama5/irq.h b/arch/arm/include/sama5/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..864f802d950aa9bb639ef8b982c40475f0289f68 --- /dev/null +++ b/arch/arm/include/sama5/irq.h @@ -0,0 +1,95 @@ +/**************************************************************************************** + * arch/arm/include/sama5/irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMA5_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMA5_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* Chip-Specific External interrupts */ + +#if defined(ATSAMA5D2) +# include +#elif defined(ATSAMA5D3) +# include +#elif defined(ATSAMA5D4) +# include +#else +# error Unrecognized SAMA5 family +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMA5_IRQ_H */ + diff --git a/arch/arm/include/sama5/sama5d2_irq.h b/arch/arm/include/sama5/sama5d2_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..0776ae0ce3249c34aae64b7cbd226837f545543f --- /dev/null +++ b/arch/arm/include/sama5/sama5d2_irq.h @@ -0,0 +1,424 @@ +/**************************************************************************************** + * arch/arm/include/sama5/sama5d2_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMA5_SAMA5D2_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMA5_SAMA5D2_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAMA5D3 Peripheral Identifiers */ + +#define SAM_PID_FIQ (0) /* Advanced Interrupt Controller FIQ */ + /* 2 Reserved */ +#define SAM_PID_ARM (2) /* Performance Monitor Unit */ +#define SAM_PID_PIT (3) /* Periodic Interval Timer Interrupt */ +#define SAM_PID_WDT (4) /* Watchdog timer Interrupt */ +#define SAM_PID_EMAC0 (5) /* Ethernet MAC 0 */ +#define SAM_PID_XDMAC0 (6) /* DMA Controller 0 */ +#define SAM_PID_XDMAC1 (7) /* DMA Controller 1 */ +#define SAM_PID_ICM (8) /* Integrity Check Monitor */ +#define SAM_PID_AES (9) /* Advanced Encryption Standard */ + +#define SAM_PID_AESB (10) /* AES bridge */ +#define SAM_PID_TDES (11) /* Triple Data Encryption Standard */ +#define SAM_PID_SHA (12) /* Secure Hash Algorithm */ +#define SAM_PID_MPDDRC (13) /* MPDDR controller */ +#define SAM_PID_MATRIX1 (14) /* H32MX, 32-bit AHB Matrix */ +#define SAM_PID_MATRIX0 (15) /* H64MX, 64-bit AHB Matrix */ +#define SAM_PID_SECUMOD (16) /* Secure Module */ +#define SAM_PID_HSMC (17) /* Multi-bit ECC Interrupt */ +#define SAM_PID_PIO (18) /* Parallel I/O Controller */ +#define SAM_PID_FLEXCOM0 (19) /* FLEXCOM 0 */ + +#define SAM_PID_FLEXCOM1 (20) /* FLEXCOM 1 */ +#define SAM_PID_FLEXCOM2 (21) /* FLEXCOM 2 */ +#define SAM_PID_FLEXCOM3 (22) /* FLEXCOM 3 */ +#define SAM_PID_FLEXCOM4 (23) /* FLEXCOM 4 */ +#define SAM_PID_UART0 (24) /* UART 0 */ +#define SAM_PID_UART1 (25) /* UART 1 */ +#define SAM_PID_UART2 (26) /* UART 2 */ +#define SAM_PID_UART3 (27) /* UART 3 */ +#define SAM_PID_UART4 (28) /* UART 4 */ +#define SAM_PID_TWI0 (29) /* Two-Wire Interface 0 */ + +#define SAM_PID_TWI1 (30) /* Two-Wire Interface 1 */ +#define SAM_PID_SDMMC0 (31) /* Secure Data Memory Card Controller 0 */ +#define SAM_PID_SDMMC1 (32) /* Secure Data Memory Card Controller 1 */ +#define SAM_PID_SPI0 (33) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SPI1 (34) /* Serial Peripheral Interface 1 */ +#define SAM_PID_TC0 (35) /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_PID_TC1 (36) /* Timer Counter 1 (ch. 3, 4, 5) */ + /* 37 Reserved */ +#define SAM_PID_PWM (38) /* Pulse Width Modulation Controller */ + /* 39 Reserved */ + +#define SAM_PID_ADC (40) /* Touch Screen ADC Controller */ +#define SAM_PID_UHPHS (41) /* USB Host High Speed */ +#define SAM_PID_UDPHS (42) /* USB Device High Speed */ +#define SAM_PID_SSC0 (43) /* Synchronous Serial Controller 0 */ +#define SAM_PID_SSC1 (44) /* Synchronous Serial Controller 1 */ +#define SAM_PID_LCDC (45) /* LCD Controller */ +#define SAM_PID_ISC (46) /* Image Sensor Controller */ +#define SAM_PID_TRNG (47) /* True Random Number Generator */ +#define SAM_PID_PDMIC (48) /* Pulse Density Modulation Interface Controller */ +#define SAM_PID_IRQID (49) /* IRQ Interrupt ID */ + +#define SAM_PID_SFC (50) /* Fuse Controller */ +#define SAM_PID_SECURAM (51) /* Secured RAM */ +#define SAM_PID_QSPI0 (52) /* QuadSPI 0 */ +#define SAM_PID_QSPI1 (53) /* QuadSPI 1 */ +#define SAM_PID_I2SC0 (54) /* Inter-IC Sound Controller 0 */ +#define SAM_PID_I2SC1 (55) /* Inter-IC Sound Controller 1 */ +#define SAM_PID_MCAN00 (56) /* MCAN controller 0, Interrupt 0 */ +#define SAM_PID_MCAN10 (57) /* MCAN controller 1, Interrupt 0 */ + /* 58 Reserved */ +#define SAM_PID_CLASSD (59) /* Audio Class D Amplifier */ + +#define SAM_PID_SFR (60) /* Special Function Register */ +#define SAM_PID_SAIC (61) /* Secured Advanced Interrupt Controller */ +#define SAM_PID_AIC (62) /* Advanced Interrupt Controller */ +#define SAM_PID_L2CC (63) /* L2 Cache Controller */ +#define SAM_PID_MCAN01 (64) /* MCAN controller 0, Interrupt 1 */ +#define SAM_PID_MCAN11 (65) /* MCAN controller 1, Interrupt 1 */ +#define SAM_PID_EMACQ1 (66) /* EMAC Queue 1 Interrupt */ +#define SAM_PID_EMACQ2 (67) /* EMAC Queue 2 Interrupt */ +#define SAM_PID_PIOB (68) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (69) /* Parallel I/O Controller C */ + +#define SAM_PID_PIOD (70) /* Parallel I/O Controller D */ +#define SAM_PID_SDMMC0T (71) /* Secure Data Memory Card Controller 0 */ +#define SAM_PID_SDMMC1T (72) /* Secure Data Memory Card Controller 1 */ + /* 73 Reserved */ +#define SAM_PID_SYS (74) /* System Controller Interrupt PMC, RTC, RSTC */ +#define SAM_PID_ACC (75) /* Analog Comparator */ +#define SAM_PID_RXLP (76) /* UART Low-Power */ +#define SAM_PID_SFRBU (77) /* Special Function Register BackUp */ +#define SAM_PID_CHIPID (78) /* Chip ID */ + +#define SAM_NPIDS (79) + +/* External interrupts vectors numbers (same as peripheral ID) */ + +#define SAM_IRQ_FIQ SAM_PID_FIQ /* Advanced Interrupt Controller FIQ */ +#define SAM_IRQ_ARM SAM_PID_ARM /* Performance Monitor Unit */ +#define SAM_IRQ_PIT SAM_PID_PIT /* Periodic Interval Timer Interrupt */ +#define SAM_IRQ_WDT SAM_PID_WDT /* Watchdog timer Interrupt */ +#define SAM_IRQ_EMAC0 SAM_PID_EMAC0 /* Ethernet MAC 0 */ +#define SAM_IRQ_XDMAC0 SAM_PID_XDMAC0 /* DMA Controller 0 */ +#define SAM_IRQ_XDMAC1 SAM_PID_XDMAC1 /* DMA Controller 1 */ +#define SAM_IRQ_ICM SAM_PID_ICM /* Integrity Check Monitor */ +#define SAM_IRQ_AES SAM_PID_AES /* Advanced Encryption Standard */ + +#define SAM_IRQ_AESB SAM_PID_AESB /* AES bridge */ +#define SAM_IRQ_TDES SAM_PID_TDES /* Triple Data Encryption Standard */ +#define SAM_IRQ_SHA SAM_PID_SHA /* Secure Hash Algorithm */ +#define SAM_IRQ_MPDDRC SAM_PID_MPDDRC /* MPDDR controller */ +#define SAM_IRQ_MATRIX1 SAM_PID_MATRIX1 /* H32MX, 32-bit AHB Matrix */ +#define SAM_IRQ_MATRIX0 SAM_PID_MATRIX0 /* H64MX, 64-bit AHB Matrix */ +#define SAM_IRQ_SECUMOD SAM_PID_SECUMOD /* Secure Module */ +#define SAM_IRQ_HSMC SAM_PID_HSMC /* Multi-bit ECC Interrupt */ +#define SAM_IRQ_PIO SAM_PID_PIO /* Parallel I/O Controller */ +#define SAM_IRQ_FLEXCOM0 SAM_PID_FLEXCOM0 /* FLEXCOM 0 */ + +#define SAM_IRQ_FLEXCOM1 SAM_PID_FLEXCOM1 /* FLEXCOM 1 */ +#define SAM_IRQ_FLEXCOM2 SAM_PID_FLEXCOM2 /* FLEXCOM 2 */ +#define SAM_IRQ_FLEXCOM3 SAM_PID_FLEXCOM3 /* FLEXCOM 3 */ +#define SAM_IRQ_FLEXCOM4 SAM_PID_FLEXCOM4 /* FLEXCOM 4 */ +#define SAM_IRQ_UART0 SAM_PID_UART0 /* UART 0 */ +#define SAM_IRQ_UART1 SAM_PID_UART1 /* UART 1 */ +#define SAM_IRQ_UART2 SAM_PID_UART2 /* UART 2 */ +#define SAM_IRQ_UART3 SAM_PID_UART3 /* UART 3 */ +#define SAM_IRQ_UART4 SAM_PID_UART4 /* UART 4 */ +#define SAM_IRQ_TWI0 SAM_PID_TWI0 /* Two-Wire Interface 0 */ + +#define SAM_IRQ_TWI1 SAM_PID_TWI1 /* Two-Wire Interface 1 */ +#define SAM_IRQ_SDMMC0 SAM_PID_SDMMC0 /* Secure Data Memory Card Controller 0 */ +#define SAM_IRQ_SDMMC1 SAM_PID_SDMMC1 /* Secure Data Memory Card Controller 1 */ +#define SAM_IRQ_SPI0 SAM_PID_SPI0 /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SPI1 SAM_PID_SPI1 /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_TC0 SAM_PID_TC0 /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_IRQ_TC1 SAM_PID_TC1 /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAM_IRQ_PWM SAM_PID_PWM /* Pulse Width Modulation Controller */ + +#define SAM_IRQ_ADC SAM_PID_ADC /* Touch Screen ADC Controller */ +#define SAM_IRQ_UHPHS SAM_PID_UHPHS /* USB Host High Speed */ +#define SAM_IRQ_UDPHS SAM_PID_UDPHS /* USB Device High Speed */ +#define SAM_IRQ_SSC0 SAM_PID_SSC0 /* Synchronous Serial Controller 0 */ +#define SAM_IRQ_SSC1 SAM_PID_SSC1 /* Synchronous Serial Controller 1 */ +#define SAM_IRQ_LCDC SAM_PID_LCDC /* LCD Controller */ +#define SAM_IRQ_ISC SAM_PID_ISC /* Image Sensor Controller */ +#define SAM_IRQ_TRNG SAM_PID_TRNG /* True Random Number Generator */ +#define SAM_IRQ_PDMIC SAM_PID_PDMIC /* Pulse Density Modulation Interface Controller */ +#define SAM_IRQ_IRQID SAM_PID_IRQID /* IRQ Interrupt ID */ + +#define SAM_IRQ_SFC SAM_PID_SFC /* Fuse Controller */ +#define SAM_IRQ_SECURAM SAM_PID_SECURAM /* Secured RAM */ +#define SAM_IRQ_QSPI0 SAM_PID_QSPI0 /* QuadSPI 0 */ +#define SAM_IRQ_QSPI1 SAM_PID_QSPI1 /* QuadSPI 1 */ +#define SAM_IRQ_I2SC0 SAM_PID_I2SC0 /* Inter-IC Sound Controller 0 */ +#define SAM_IRQ_I2SC1 SAM_PID_I2SC1 /* Inter-IC Sound Controller 1 */ +#define SAM_IRQ_MCAN00 SAM_PID_MCAN00 /* MCAN controller 0, Interrupt 0 */ +#define SAM_IRQ_MCAN10 SAM_PID_MCAN10 /* MCAN controller 1, Interrupt 0 */ +#define SAM_IRQ_CLASSD SAM_PID_CLASSD /* Audio Class D Amplifier */ + + /* Special Function Register (no interrupt) */ + /* Secured Advanced Interrupt Controller (no interrupt) */ + /* Advanced Interrupt Controller (no interrupt) */ +#define SAM_IRQ_L2CC SAM_PID_L2CC /* L2 Cache Controller */ +#define SAM_IRQ_MCAN01 SAM_PID_MCAN01 /* MCAN controller 0, Interrupt 1 */ +#define SAM_IRQ_MCAN11 SAM_PID_MCAN11 /* MCAN controller 1, Interrupt 1 */ +#define SAM_IRQ_EMACQ1 SAM_PID_EMACQ1 /* EMAC Queue 1 Interrupt */ +#define SAM_IRQ_EMACQ2 SAM_PID_EMACQ2 /* EMAC Queue 2 Interrupt */ +#define SAM_IRQ_PIOB SAM_PID_PIOB /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC SAM_PID_PIOC /* Parallel I/O Controller C */ + +#define SAM_IRQ_PIOD SAM_PID_PIOD /* Parallel I/O Controller D */ +#define SAM_IRQ_SDMMC0T SAM_PID_SDMMC0T /* Secure Data Memory Card Controller 0 */ +#define SAM_IRQ_SDMMC1T SAM_PID_SDMMC1T /* Secure Data Memory Card Controller 1 */ +#define SAM_IRQ_SYS SAM_PID_SYS /* System Controller Interrupt PMC, RTC, RSTC */ +#define SAM_IRQ_ACC SAM_PID_ACC /* Analog Comparator */ +#define SAM_IRQ_RXLP SAM_PID_RXLP /* UART Low-Power */ + /* Special Function Register BackUp (no interrupt) */ + /* Chip ID (no interrupt) */ + +#define SAM_IRQ_NINT (SAM_PID_RXLP + 1) + +/* PIO interrupts (derived from SAM_IRQ_PIOA/B/C/D/E/F) */ + +#ifdef CONFIG_SAMA5_PIOA_IRQ +# define SAM_IRQ_PIOA_PINS (SAM_IRQ_NINT) +# define SAM_IRQ_PA0 (SAM_IRQ_PIOA_PINS+0) /* PIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_PIOA_PINS+1) /* PIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_PIOA_PINS+2) /* PIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_PIOA_PINS+3) /* PIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_PIOA_PINS+4) /* PIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_PIOA_PINS+5) /* PIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_PIOA_PINS+6) /* PIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_PIOA_PINS+7) /* PIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_PIOA_PINS+8) /* PIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_PIOA_PINS+9) /* PIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_PIOA_PINS+10) /* PIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_PIOA_PINS+11) /* PIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_PIOA_PINS+12) /* PIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_PIOA_PINS+13) /* PIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_PIOA_PINS+14) /* PIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_PIOA_PINS+15) /* PIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_PIOA_PINS+16) /* PIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_PIOA_PINS+17) /* PIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_PIOA_PINS+18) /* PIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_PIOA_PINS+19) /* PIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_PIOA_PINS+20) /* PIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_PIOA_PINS+21) /* PIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_PIOA_PINS+22) /* PIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_PIOA_PINS+23) /* PIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_PIOA_PINS+24) /* PIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_PIOA_PINS+25) /* PIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_PIOA_PINS+26) /* PIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_PIOA_PINS+27) /* PIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_PIOA_PINS+28) /* PIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_PIOA_PINS+29) /* PIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_PIOA_PINS+30) /* PIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_PIOA_PINS+31) /* PIOA, PIN 31 */ +# define SAM_NPIOAIRQS 32 +#else +# define SAM_NPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOB_IRQ +# define SAM_IRQ_PIOB_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_PIOB_PINS+0) /* PIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_PIOB_PINS+1) /* PIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_PIOB_PINS+2) /* PIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_PIOB_PINS+3) /* PIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_PIOB_PINS+4) /* PIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_PIOB_PINS+5) /* PIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_PIOB_PINS+6) /* PIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_PIOB_PINS+7) /* PIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_PIOB_PINS+8) /* PIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_PIOB_PINS+9) /* PIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_PIOB_PINS+10) /* PIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_PIOB_PINS+11) /* PIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_PIOB_PINS+12) /* PIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_PIOB_PINS+13) /* PIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_PIOB_PINS+14) /* PIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_PIOB_PINS+15) /* PIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_PIOB_PINS+16) /* PIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_PIOB_PINS+17) /* PIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_PIOB_PINS+18) /* PIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_PIOB_PINS+19) /* PIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_PIOB_PINS+20) /* PIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_PIOB_PINS+21) /* PIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_PIOB_PINS+22) /* PIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_PIOB_PINS+23) /* PIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_PIOB_PINS+24) /* PIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_PIOB_PINS+25) /* PIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_PIOB_PINS+26) /* PIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_PIOB_PINS+27) /* PIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_PIOB_PINS+28) /* PIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_PIOB_PINS+29) /* PIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_PIOB_PINS+30) /* PIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_PIOB_PINS+31) /* PIOB, PIN 31 */ +# define SAM_NPIOBIRQS 32 +#else +# define SAM_NPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOC_IRQ +# define SAM_IRQ_PIOC_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_PIOC_PINS+0) /* PIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_PIOC_PINS+1) /* PIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_PIOC_PINS+2) /* PIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_PIOC_PINS+3) /* PIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_PIOC_PINS+4) /* PIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_PIOC_PINS+5) /* PIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_PIOC_PINS+6) /* PIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_PIOC_PINS+7) /* PIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_PIOC_PINS+8) /* PIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_PIOC_PINS+9) /* PIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_PIOC_PINS+10) /* PIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_PIOC_PINS+11) /* PIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_PIOC_PINS+12) /* PIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_PIOC_PINS+13) /* PIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_PIOC_PINS+14) /* PIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_PIOC_PINS+15) /* PIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_PIOC_PINS+16) /* PIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_PIOC_PINS+17) /* PIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_PIOC_PINS+18) /* PIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_PIOC_PINS+19) /* PIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_PIOC_PINS+20) /* PIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_PIOC_PINS+21) /* PIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_PIOC_PINS+22) /* PIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_PIOC_PINS+23) /* PIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_PIOC_PINS+24) /* PIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_PIOC_PINS+25) /* PIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_PIOC_PINS+26) /* PIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_PIOC_PINS+27) /* PIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_PIOC_PINS+28) /* PIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_PIOC_PINS+29) /* PIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_PIOC_PINS+30) /* PIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_PIOC_PINS+31) /* PIOC, PIN 31 */ +# define SAM_NPIOCIRQS 32 +#else +# define SAM_NPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOD_IRQ +# define SAM_IRQ_PIOD_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS + \ + SAM_NPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_PIOD_PINS+0) /* PIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_PIOD_PINS+1) /* PIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_PIOD_PINS+2) /* PIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_PIOD_PINS+3) /* PIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_PIOD_PINS+4) /* PIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_PIOD_PINS+5) /* PIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_PIOD_PINS+6) /* PIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_PIOD_PINS+7) /* PIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_PIOD_PINS+8) /* PIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_PIOD_PINS+9) /* PIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_PIOD_PINS+10) /* PIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_PIOD_PINS+11) /* PIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_PIOD_PINS+12) /* PIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_PIOD_PINS+13) /* PIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_PIOD_PINS+14) /* PIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_PIOD_PINS+15) /* PIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_PIOD_PINS+16) /* PIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_PIOD_PINS+17) /* PIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_PIOD_PINS+18) /* PIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_PIOD_PINS+19) /* PIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_PIOD_PINS+20) /* PIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_PIOD_PINS+21) /* PIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_PIOD_PINS+22) /* PIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_PIOD_PINS+23) /* PIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_PIOD_PINS+24) /* PIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_PIOD_PINS+25) /* PIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_PIOD_PINS+26) /* PIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_PIOD_PINS+27) /* PIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_PIOD_PINS+28) /* PIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_PIOD_PINS+29) /* PIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_PIOD_PINS+30) /* PIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_PIOD_PINS+31) /* PIOD, PIN 31 */ +# define SAM_NPIODIRQS 32 +#else +# define SAM_NPIODIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_IRQS (SAM_IRQ_NINT + \ + SAM_NPIOAIRQS + SAM_NPIOBIRQS + SAM_NPIOCIRQS + \ + SAM_NPIODIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMA5_SAMA5D2_IRQ_H */ diff --git a/arch/arm/include/sama5/sama5d3_irq.h b/arch/arm/include/sama5/sama5d3_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..21d3ef573c1f117ad911f5a5c18c1edf01fbea11 --- /dev/null +++ b/arch/arm/include/sama5/sama5d3_irq.h @@ -0,0 +1,396 @@ +/**************************************************************************************** + * arch/arm/include/sama5/sama5d3_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMA5_SAMA5D3_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMA5_SAMA5D3_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAMA5D3 Peripheral Identifiers */ + +#define SAM_PID_FIQ (0) /* Advanced Interrupt Controller FIQ */ +#define SAM_PID_SYS (1) /* System Controller Interrupt PMC */ +#define SAM_PID_DBGU (2) /* Debug Unit Interrupt */ +#define SAM_PID_PIT (3) /* Periodic Interval Timer Interrupt */ +#define SAM_PID_WDT (4) /* Watchdog timer Interrupt */ +#define SAM_PID_HSMC (5) /* Multi-bit ECC Interrupt */ +#define SAM_PID_PIOA (6) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (7) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (8) /* Parallel I/O Controller C */ +#define SAM_PID_PIOD (9) /* Parallel I/O Controller D */ +#define SAM_PID_PIOE (10) /* Parallel I/O Controller E */ +#define SAM_PID_SMD (11) /* SMD Soft Modem */ +#define SAM_PID_USART0 (12) /* USART 0 */ +#define SAM_PID_USART1 (13) /* USART 1 */ +#define SAM_PID_USART2 (14) /* USART 2 */ +#define SAM_PID_USART3 (15) /* USART 3 */ +#define SAM_PID_UART0 (16) /* UART 0 */ +#define SAM_PID_UART1 (17) /* UART 1 */ +#define SAM_PID_TWI0 (18) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (19) /* Two-Wire Interface 1 */ +#define SAM_PID_TWI2 (20) /* Two-Wire Interface 2 */ +#define SAM_PID_HSMCI0 (21) /* High Speed Multimedia Card Interface 0 */ +#define SAM_PID_HSMCI1 (22) /* High Speed Multimedia Card Interface 1 */ +#define SAM_PID_HSMCI2 (23) /* High Speed Multimedia Card Interface 2 */ +#define SAM_PID_SPI0 (24) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SPI1 (25) /* Serial Peripheral Interface 1 */ +#define SAM_PID_TC0 (26) /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_PID_TC1 (27) /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAM_PID_PWM (28) /* Pulse Width Modulation Controller */ +#define SAM_PID_ADC (29) /* Touch Screen ADC Controller */ +#define SAM_PID_DMAC0 (30) /* DMA Controller 0 */ +#define SAM_PID_DMAC1 (31) /* DMA Controller 1 */ +#define SAM_PID_UHPHS (32) /* USB Host High Speed */ +#define SAM_PID_UDPHS (33) /* USB Device High Speed */ +#define SAM_PID_GMAC (34) /* Gigabit Ethernet MAC */ +#define SAM_PID_EMAC (35) /* Ethernet MAC */ +#define SAM_PID_LCDC (36) /* LCD Controller */ +#define SAM_PID_ISI (37) /* Image Sensor Interface */ +#define SAM_PID_SSC0 (38) /* Synchronous Serial Controller 0 */ +#define SAM_PID_SSC1 (39) /* Synchronous Serial Controller 1 */ +#define SAM_PID_CAN0 (40) /* CAN controller 0 */ +#define SAM_PID_CAN1 (41) /* CAN controller 1 */ +#define SAM_PID_SHA (42) /* Secure Hash Algorithm */ +#define SAM_PID_AES (43) /* Advanced Encryption Standard */ +#define SAM_PID_TDES (44) /* Triple Data Encryption Standard */ +#define SAM_PID_TRNG (45) /* True Random Number Generator */ +#define SAM_PID_ARM (46) /* Performance Monitor Unit */ +#define SAM_PID_AIC (47) /* Advanced Interrupt Controller IRQ */ +#define SAM_PID_FUSE (48) /* Fuse Controller */ +#define SAM_PID_MPDDRC (49) /* MPDDR controller */ + /* 50-63 Reserved */ + +/* External interrupts vectors numbers (same as peripheral ID) */ + +#define SAM_IRQ_FIQ SAM_PID_FIQ /* Advanced Interrupt Controller FIQ */ +#define SAM_IRQ_SYS SAM_PID_SYS /* System Controller Interrupt PMC */ +#define SAM_IRQ_DBGU SAM_PID_DBGU /* Debug Unit Interrupt */ +#define SAM_IRQ_PIT SAM_PID_PIT /* Periodic Interval Timer Interrupt */ +#define SAM_IRQ_WDT SAM_PID_WDT /* Watchdog timer Interrupt */ +#define SAM_IRQ_HSMC SAM_PID_HSMC /* Multi-bit ECC Interrupt */ +#define SAM_IRQ_PIOA SAM_PID_PIOA /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB SAM_PID_PIOB /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC SAM_PID_PIOC /* Parallel I/O Controller C */ +#define SAM_IRQ_PIOD SAM_PID_PIOD /* Parallel I/O Controller D */ +#define SAM_IRQ_PIOE SAM_PID_PIOE /* Parallel I/O Controller E */ +#define SAM_IRQ_SMD SAM_PID_SMD /* SMD Soft Modem */ +#define SAM_IRQ_USART0 SAM_PID_USART0 /* USART 0 */ +#define SAM_IRQ_USART1 SAM_PID_USART1 /* USART 1 */ +#define SAM_IRQ_USART2 SAM_PID_USART2 /* USART 2 */ +#define SAM_IRQ_USART3 SAM_PID_USART3 /* USART 3 */ +#define SAM_IRQ_UART0 SAM_PID_UART0 /* UART 0 */ +#define SAM_IRQ_UART1 SAM_PID_UART1 /* UART 1 */ +#define SAM_IRQ_TWI0 SAM_PID_TWI0 /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 SAM_PID_TWI1 /* Two-Wire Interface 1 */ +#define SAM_IRQ_TWI2 SAM_PID_TWI2 /* Two-Wire Interface 2 */ +#define SAM_IRQ_HSMCI0 SAM_PID_HSMCI0 /* High Speed Multimedia Card Interface 0 */ +#define SAM_IRQ_HSMCI1 SAM_PID_HSMCI1 /* High Speed Multimedia Card Interface 1 */ +#define SAM_IRQ_HSMCI2 SAM_PID_HSMCI2 /* High Speed Multimedia Card Interface 2 */ +#define SAM_IRQ_SPI0 SAM_PID_SPI0 /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SPI1 SAM_PID_SPI1 /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_TC0 SAM_PID_TC0 /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_IRQ_TC1 SAM_PID_TC1 /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAM_IRQ_PWM SAM_PID_PWM /* Pulse Width Modulation Controller */ +#define SAM_IRQ_ADC SAM_PID_ADC /* Touch Screen ADC Controller */ +#define SAM_IRQ_DMAC0 SAM_PID_DMAC0 /* DMA Controller 0 */ +#define SAM_IRQ_DMAC1 SAM_PID_DMAC1 /* DMA Controller 1 */ +#define SAM_IRQ_UHPHS SAM_PID_UHPHS /* USB Host High Speed */ +#define SAM_IRQ_UDPHS SAM_PID_UDPHS /* USB Device High Speed */ +#define SAM_IRQ_GMAC SAM_PID_GMAC /* Gigabit Ethernet MAC */ +#define SAM_IRQ_EMAC SAM_PID_EMAC /* Ethernet MAC */ +#define SAM_IRQ_LCDC SAM_PID_LCDC /* LCD Controller */ +#define SAM_IRQ_ISI SAM_PID_ISI /* Image Sensor Interface */ +#define SAM_IRQ_SSC0 SAM_PID_SSC0 /* Synchronous Serial Controller 0 */ +#define SAM_IRQ_SSC1 SAM_PID_SSC1 /* Synchronous Serial Controller 1 */ +#define SAM_IRQ_CAN0 SAM_PID_CAN0 /* CAN controller 0 */ +#define SAM_IRQ_CAN1 SAM_PID_CAN1 /* CAN controller 1 */ +#define SAM_IRQ_SHA SAM_PID_SHA /* Secure Hash Algorithm */ +#define SAM_IRQ_AES SAM_PID_AES /* Advanced Encryption Standard */ +#define SAM_IRQ_TDES SAM_PID_TDES /* Triple Data Encryption Standard */ +#define SAM_IRQ_TRNG SAM_PID_TRNG /* True Random Number Generator */ +#define SAM_IRQ_ARM SAM_PID_ARM /* Performance Monitor Unit */ +#define SAM_IRQ_AIC SAM_PID_AIC /* Advanced Interrupt Controller IRQ */ +#define SAM_IRQ_FUSE SAM_PID_FUSE /* Fuse Controller */ +#define SAM_IRQ_MPDDRC SAM_PID_MPDDRC /* MPDDR controller */ + +#define SAM_IRQ_NINT (SAM_PID_MPDDRC + 1) + +/* PIO interrupts (derived from SAM_IRQ_PIOA/B/C/D/E/F) */ + +#ifdef CONFIG_SAMA5_PIOA_IRQ +# define SAM_IRQ_PIOA_PINS (SAM_IRQ_NINT) +# define SAM_IRQ_PA0 (SAM_IRQ_PIOA_PINS+0) /* PIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_PIOA_PINS+1) /* PIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_PIOA_PINS+2) /* PIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_PIOA_PINS+3) /* PIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_PIOA_PINS+4) /* PIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_PIOA_PINS+5) /* PIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_PIOA_PINS+6) /* PIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_PIOA_PINS+7) /* PIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_PIOA_PINS+8) /* PIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_PIOA_PINS+9) /* PIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_PIOA_PINS+10) /* PIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_PIOA_PINS+11) /* PIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_PIOA_PINS+12) /* PIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_PIOA_PINS+13) /* PIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_PIOA_PINS+14) /* PIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_PIOA_PINS+15) /* PIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_PIOA_PINS+16) /* PIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_PIOA_PINS+17) /* PIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_PIOA_PINS+18) /* PIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_PIOA_PINS+19) /* PIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_PIOA_PINS+20) /* PIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_PIOA_PINS+21) /* PIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_PIOA_PINS+22) /* PIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_PIOA_PINS+23) /* PIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_PIOA_PINS+24) /* PIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_PIOA_PINS+25) /* PIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_PIOA_PINS+26) /* PIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_PIOA_PINS+27) /* PIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_PIOA_PINS+28) /* PIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_PIOA_PINS+29) /* PIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_PIOA_PINS+30) /* PIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_PIOA_PINS+31) /* PIOA, PIN 31 */ +# define SAM_NPIOAIRQS 32 +#else +# define SAM_NPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOB_IRQ +# define SAM_IRQ_PIOB_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_PIOB_PINS+0) /* PIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_PIOB_PINS+1) /* PIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_PIOB_PINS+2) /* PIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_PIOB_PINS+3) /* PIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_PIOB_PINS+4) /* PIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_PIOB_PINS+5) /* PIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_PIOB_PINS+6) /* PIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_PIOB_PINS+7) /* PIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_PIOB_PINS+8) /* PIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_PIOB_PINS+9) /* PIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_PIOB_PINS+10) /* PIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_PIOB_PINS+11) /* PIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_PIOB_PINS+12) /* PIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_PIOB_PINS+13) /* PIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_PIOB_PINS+14) /* PIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_PIOB_PINS+15) /* PIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_PIOB_PINS+16) /* PIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_PIOB_PINS+17) /* PIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_PIOB_PINS+18) /* PIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_PIOB_PINS+19) /* PIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_PIOB_PINS+20) /* PIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_PIOB_PINS+21) /* PIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_PIOB_PINS+22) /* PIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_PIOB_PINS+23) /* PIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_PIOB_PINS+24) /* PIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_PIOB_PINS+25) /* PIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_PIOB_PINS+26) /* PIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_PIOB_PINS+27) /* PIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_PIOB_PINS+28) /* PIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_PIOB_PINS+29) /* PIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_PIOB_PINS+30) /* PIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_PIOB_PINS+31) /* PIOB, PIN 31 */ +# define SAM_NPIOBIRQS 32 +#else +# define SAM_NPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOC_IRQ +# define SAM_IRQ_PIOC_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_PIOC_PINS+0) /* PIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_PIOC_PINS+1) /* PIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_PIOC_PINS+2) /* PIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_PIOC_PINS+3) /* PIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_PIOC_PINS+4) /* PIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_PIOC_PINS+5) /* PIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_PIOC_PINS+6) /* PIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_PIOC_PINS+7) /* PIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_PIOC_PINS+8) /* PIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_PIOC_PINS+9) /* PIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_PIOC_PINS+10) /* PIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_PIOC_PINS+11) /* PIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_PIOC_PINS+12) /* PIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_PIOC_PINS+13) /* PIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_PIOC_PINS+14) /* PIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_PIOC_PINS+15) /* PIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_PIOC_PINS+16) /* PIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_PIOC_PINS+17) /* PIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_PIOC_PINS+18) /* PIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_PIOC_PINS+19) /* PIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_PIOC_PINS+20) /* PIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_PIOC_PINS+21) /* PIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_PIOC_PINS+22) /* PIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_PIOC_PINS+23) /* PIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_PIOC_PINS+24) /* PIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_PIOC_PINS+25) /* PIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_PIOC_PINS+26) /* PIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_PIOC_PINS+27) /* PIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_PIOC_PINS+28) /* PIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_PIOC_PINS+29) /* PIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_PIOC_PINS+30) /* PIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_PIOC_PINS+31) /* PIOC, PIN 31 */ +# define SAM_NPIOCIRQS 32 +#else +# define SAM_NPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOD_IRQ +# define SAM_IRQ_PIOD_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS + \ + SAM_NPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_PIOD_PINS+0) /* PIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_PIOD_PINS+1) /* PIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_PIOD_PINS+2) /* PIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_PIOD_PINS+3) /* PIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_PIOD_PINS+4) /* PIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_PIOD_PINS+5) /* PIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_PIOD_PINS+6) /* PIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_PIOD_PINS+7) /* PIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_PIOD_PINS+8) /* PIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_PIOD_PINS+9) /* PIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_PIOD_PINS+10) /* PIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_PIOD_PINS+11) /* PIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_PIOD_PINS+12) /* PIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_PIOD_PINS+13) /* PIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_PIOD_PINS+14) /* PIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_PIOD_PINS+15) /* PIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_PIOD_PINS+16) /* PIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_PIOD_PINS+17) /* PIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_PIOD_PINS+18) /* PIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_PIOD_PINS+19) /* PIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_PIOD_PINS+20) /* PIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_PIOD_PINS+21) /* PIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_PIOD_PINS+22) /* PIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_PIOD_PINS+23) /* PIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_PIOD_PINS+24) /* PIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_PIOD_PINS+25) /* PIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_PIOD_PINS+26) /* PIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_PIOD_PINS+27) /* PIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_PIOD_PINS+28) /* PIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_PIOD_PINS+29) /* PIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_PIOD_PINS+30) /* PIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_PIOD_PINS+31) /* PIOD, PIN 31 */ +# define SAM_NPIODIRQS 32 +#else +# define SAM_NPIODIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOE_IRQ +# define SAM_IRQ_PIOE_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + \ + SAM_NPIOBIRQS + SAM_NPIOCIRQS + SAM_NPIODIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_PIOE_PINS+0) /* PIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_PIOE_PINS+1) /* PIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_PIOE_PINS+2) /* PIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_PIOE_PINS+3) /* PIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_PIOE_PINS+4) /* PIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_PIOE_PINS+5) /* PIOE, PIN 5 */ +# define SAM_IRQ_PE6 (SAM_IRQ_PIOE_PINS+6) /* PIOE, PIN 6 */ +# define SAM_IRQ_PE7 (SAM_IRQ_PIOE_PINS+7) /* PIOE, PIN 7 */ +# define SAM_IRQ_PE8 (SAM_IRQ_PIOE_PINS+8) /* PIOE, PIN 8 */ +# define SAM_IRQ_PE9 (SAM_IRQ_PIOE_PINS+9) /* PIOE, PIN 9 */ +# define SAM_IRQ_PE10 (SAM_IRQ_PIOE_PINS+10) /* PIOE, PIN 10 */ +# define SAM_IRQ_PE11 (SAM_IRQ_PIOE_PINS+11) /* PIOE, PIN 11 */ +# define SAM_IRQ_PE12 (SAM_IRQ_PIOE_PINS+12) /* PIOE, PIN 12 */ +# define SAM_IRQ_PE13 (SAM_IRQ_PIOE_PINS+13) /* PIOE, PIN 13 */ +# define SAM_IRQ_PE14 (SAM_IRQ_PIOE_PINS+14) /* PIOE, PIN 14 */ +# define SAM_IRQ_PE15 (SAM_IRQ_PIOE_PINS+15) /* PIOE, PIN 15 */ +# define SAM_IRQ_PE16 (SAM_IRQ_PIOE_PINS+16) /* PIOE, PIN 16 */ +# define SAM_IRQ_PE17 (SAM_IRQ_PIOE_PINS+17) /* PIOE, PIN 17 */ +# define SAM_IRQ_PE18 (SAM_IRQ_PIOE_PINS+18) /* PIOE, PIN 18 */ +# define SAM_IRQ_PE19 (SAM_IRQ_PIOE_PINS+19) /* PIOE, PIN 19 */ +# define SAM_IRQ_PE20 (SAM_IRQ_PIOE_PINS+20) /* PIOE, PIN 20 */ +# define SAM_IRQ_PE21 (SAM_IRQ_PIOE_PINS+21) /* PIOE, PIN 21 */ +# define SAM_IRQ_PE22 (SAM_IRQ_PIOE_PINS+22) /* PIOE, PIN 22 */ +# define SAM_IRQ_PE23 (SAM_IRQ_PIOE_PINS+23) /* PIOE, PIN 23 */ +# define SAM_IRQ_PE24 (SAM_IRQ_PIOE_PINS+24) /* PIOE, PIN 24 */ +# define SAM_IRQ_PE25 (SAM_IRQ_PIOE_PINS+25) /* PIOE, PIN 25 */ +# define SAM_IRQ_PE26 (SAM_IRQ_PIOE_PINS+26) /* PIOE, PIN 26 */ +# define SAM_IRQ_PE27 (SAM_IRQ_PIOE_PINS+27) /* PIOE, PIN 27 */ +# define SAM_IRQ_PE28 (SAM_IRQ_PIOE_PINS+28) /* PIOE, PIN 28 */ +# define SAM_IRQ_PE29 (SAM_IRQ_PIOE_PINS+29) /* PIOE, PIN 29 */ +# define SAM_IRQ_PE30 (SAM_IRQ_PIOE_PINS+30) /* PIOE, PIN 30 */ +# define SAM_IRQ_PE31 (SAM_IRQ_PIOE_PINS+31) /* PIOE, PIN 31 */ +# define SAM_NPIOEIRQS 32 +#else +# define SAM_NPIOEIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_IRQS (SAM_IRQ_NINT + \ + SAM_NPIOAIRQS + SAM_NPIOBIRQS + SAM_NPIOCIRQS + \ + SAM_NPIODIRQS + SAM_NPIOEIRQS ) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMA5_SAMA5D3_IRQ_H */ diff --git a/arch/arm/include/sama5/sama5d4_irq.h b/arch/arm/include/sama5/sama5d4_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b27df9afa8f8d4bea13d82159f013ff01732f461 --- /dev/null +++ b/arch/arm/include/sama5/sama5d4_irq.h @@ -0,0 +1,439 @@ +/**************************************************************************************** + * arch/arm/include/sama5/sama5d4_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMA5_SAMA5D4_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMA5_SAMA5D4_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAMA5D3 Peripheral Identifiers */ + +#define SAM_PID_FIQ (0) /* Advanced Interrupt Controller FIQ */ +#define SAM_PID_SYS (1) /* System Controller Interrupt PMC */ +#define SAM_PID_ARM (2) /* Performance Monitor Unit */ +#define SAM_PID_PIT (3) /* Periodic Interval Timer Interrupt */ +#define SAM_PID_WDT (4) /* Watchdog timer Interrupt */ +#define SAM_PID_PIOD (5) /* Parallel I/O Controller D */ +#define SAM_PID_USART0 (6) /* USART 0 */ +#define SAM_PID_USART1 (7) /* USART 1 */ +#define SAM_PID_XDMAC0 (8) /* DMA Controller 0 */ +#define SAM_PID_ICM (9) /* Integrity Check Monitor */ + +#define SAM_PID_CPKCC (10) /* Classic Public Key Crypto Controller */ + /* 11 Undefined */ +#define SAM_PID_AES (12) /* Advanced Encryption Standard */ +#define SAM_PID_AESB (13) /* AES bridge */ +#define SAM_PID_TDES (14) /* Triple Data Encryption Standard */ +#define SAM_PID_SHA (15) /* Secure Hash Algorithm */ +#define SAM_PID_MPDDRC (16) /* MPDDR controller */ +#define SAM_PID_MATRIX1 (17) /* H32MX, 32-bit AHB Matrix */ +#define SAM_PID_MATRIX0 (18) /* H64MX, 64-bit AHB Matrix */ +#define SAM_PID_VDEC (19) /* Video Decoder */ + +#define SAM_PID_SBM (20) /* Secure Box Module */ + /* 21 Undefined */ +#define SAM_PID_HSMC (22) /* Multi-bit ECC Interrupt */ +#define SAM_PID_PIOA (23) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (24) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (25) /* Parallel I/O Controller C */ +#define SAM_PID_PIOE (26) /* Parallel I/O Controller E */ +#define SAM_PID_UART0 (27) /* UART 0 */ +#define SAM_PID_UART1 (28) /* UART 1 */ +#define SAM_PID_USART2 (29) /* USART 2 */ + +#define SAM_PID_USART3 (30) /* USART 3 */ +#define SAM_PID_USART4 (31) /* USART 4 */ +#define SAM_PID_TWI0 (32) /* Two-Wire Interface 0 */ +#define SAM_PID_TWI1 (33) /* Two-Wire Interface 1 */ +#define SAM_PID_TWI2 (34) /* Two-Wire Interface 2 */ +#define SAM_PID_HSMCI0 (35) /* High Speed Multimedia Card Interface 0 */ +#define SAM_PID_HSMCI1 (36) /* High Speed Multimedia Card Interface 1 */ +#define SAM_PID_SPI0 (37) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SPI1 (38) /* Serial Peripheral Interface 1 */ +#define SAM_PID_SPI2 (39) /* Serial Peripheral Interface 2 */ + +#define SAM_PID_TC0 (40) /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_PID_TC1 (41) /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAM_PID_TC2 (42) /* Timer Counter 2 (ch. 6, 7, 8) */ +#define SAM_PID_PWM (43) /* Pulse Width Modulation Controller */ +#define SAM_PID_ADC (44) /* Touch Screen ADC Controller */ +#define SAM_PID_DBGU (45) /* Debug Unit Interrupt */ +#define SAM_PID_UHPHS (46) /* USB Host High Speed */ +#define SAM_PID_UDPHS (47) /* USB Device High Speed */ +#define SAM_PID_SSC0 (48) /* Synchronous Serial Controller 0 */ +#define SAM_PID_SSC1 (49) /* Synchronous Serial Controller 1 */ + +#define SAM_PID_XDMAC1 (50) /* DMA Controller 1 */ +#define SAM_PID_LCDC (51) /* LCD Controller */ +#define SAM_PID_ISI (52) /* Image Sensor Interface */ +#define SAM_PID_TRNG (53) /* True Random Number Generator */ +#define SAM_PID_EMAC0 (54) /* Ethernet MAC 0 */ +#define SAM_PID_EMAC1 (55) /* Ethernet MAC 1 */ +#define SAM_PID_AICID (56) /* IRQ Interrupt ID */ +#define SAM_PID_SFC (57) /* Fuse Controller */ + /* 58 Reserved */ +#define SAM_PID_SECURAM (59) /* Secured RAM */ + + /* 60 Undefined */ +#define SAM_PID_SMD (61) /* SMD Soft Modem */ +#define SAM_PID_TWI3 (62) /* Two-Wire Interface 3 */ +#define SAM_PID_CATB (63) /* Capacitive Touch Module */ +#define SAM_PID_SFR (64) /* Special Function Register */ +#define SAM_PID_AIC (65) /* Advanced Interrupt Controller */ +#define SAM_PID_SAIC (66) /* Secured Advanced Interrupt Controller */ +#define SAM_PID_L2CC (67) /* L2 Cache Controller */ + +/* External interrupts vectors numbers (same as peripheral ID) */ + +#define SAM_IRQ_FIQ SAM_PID_FIQ /* Advanced Interrupt Controller FIQ */ +#define SAM_IRQ_SYS SAM_PID_SYS /* System Controller Interrupt PMC */ +#define SAM_IRQ_ARM SAM_PID_ARM /* Performance Monitor Unit */ +#define SAM_IRQ_PIT SAM_PID_PIT /* Periodic Interval Timer Interrupt */ +#define SAM_IRQ_WDT SAM_PID_WDT /* Watchdog timer Interrupt */ +#define SAM_IRQ_PIOD SAM_PID_PIOD /* Parallel I/O Controller D */ +#define SAM_IRQ_USART0 SAM_PID_USART0 /* USART 0 */ +#define SAM_IRQ_USART1 SAM_PID_USART1 /* USART 1 */ +#define SAM_IRQ_XDMAC0 SAM_PID_XDMAC0 /* DMA Controller 0 */ +#define SAM_IRQ_ICM SAM_PID_ICM /* Integrity Check Monitor */ + +#define SAM_IRQ_CPKCC SAM_PID_CPKCC /* Classic Public Key Crypto Controller */ +#define SAM_IRQ_AES SAM_PID_AES /* Advanced Encryption Standard */ +#define SAM_IRQ_AESB SAM_PID_AESB /* AES bridge */ +#define SAM_IRQ_TDES SAM_PID_TDES /* Triple Data Encryption Standard */ +#define SAM_IRQ_SHA SAM_PID_SHA /* Secure Hash Algorithm */ +#define SAM_IRQ_MPDDRC SAM_PID_MPDDRC /* MPDDR controller */ +#define SAM_IRQ_MATRIX1 SAM_PID_MATRIX1 /* H32MX, 32-bit AHB Matrix */ +#define SAM_IRQ_MATRIX0 SAM_PID_MATRIX0 /* H64MX, 64-bit AHB Matrix */ +#define SAM_IRQ_VDEC SAM_PID_VDEC /* Video Decoder */ + +#define SAM_IRQ_SBM SAM_PID_SBM /* Secure Box Module */ +#define SAM_IRQ_HSMC SAM_PID_HSMC /* Multi-bit ECC Interrupt */ +#define SAM_IRQ_PIOA SAM_PID_PIOA /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB SAM_PID_PIOB /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC SAM_PID_PIOC /* Parallel I/O Controller C */ +#define SAM_IRQ_PIOE SAM_PID_PIOE /* Parallel I/O Controller E */ +#define SAM_IRQ_UART0 SAM_PID_UART0 /* UART 0 */ +#define SAM_IRQ_UART1 SAM_PID_UART1 /* UART 1 */ +#define SAM_IRQ_USART2 SAM_PID_USART2 /* USART 2 */ + +#define SAM_IRQ_USART3 SAM_PID_USART3 /* USART 3 */ +#define SAM_IRQ_USART4 SAM_PID_USART4 /* USART 4 */ +#define SAM_IRQ_TWI0 SAM_PID_TWI0 /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWI1 SAM_PID_TWI1 /* Two-Wire Interface 1 */ +#define SAM_IRQ_TWI2 SAM_PID_TWI2 /* Two-Wire Interface 2 */ +#define SAM_IRQ_HSMCI0 SAM_PID_HSMCI0 /* High Speed Multimedia Card Interface 0 */ +#define SAM_IRQ_HSMCI1 SAM_PID_HSMCI1 /* High Speed Multimedia Card Interface 1 */ +#define SAM_IRQ_SPI0 SAM_PID_SPI0 /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SPI1 SAM_PID_SPI1 /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_SPI2 SAM_PID_SPI2 /* Serial Peripheral Interface 2 */ + +#define SAM_IRQ_TC0 SAM_PID_TC0 /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAM_IRQ_TC1 SAM_PID_TC1 /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAM_IRQ_TC2 SAM_PID_TC2 /* Timer Counter 2 (ch. 6, 7, 8) */ +#define SAM_IRQ_PWM SAM_PID_PWM /* Pulse Width Modulation Controller */ +#define SAM_IRQ_ADC SAM_PID_ADC /* Touch Screen ADC Controller */ +#define SAM_IRQ_DBGU SAM_PID_DBGU /* Debug Unit Interrupt */ +#define SAM_IRQ_UHPHS SAM_PID_UHPHS /* USB Host High Speed */ +#define SAM_IRQ_UDPHS SAM_PID_UDPHS /* USB Device High Speed */ +#define SAM_IRQ_SSC0 SAM_PID_SSC0 /* Synchronous Serial Controller 0 */ +#define SAM_IRQ_SSC1 SAM_PID_SSC1 /* Synchronous Serial Controller 1 */ + +#define SAM_IRQ_XDMAC1 SAM_PID_XDMAC1 /* DMA Controller 1 */ +#define SAM_IRQ_LCDC SAM_PID_LCDC /* LCD Controller */ +#define SAM_IRQ_ISI SAM_PID_ISI /* Image Sensor Interface */ +#define SAM_IRQ_TRNG SAM_PID_TRNG /* True Random Number Generator */ +#define SAM_IRQ_EMAC0 SAM_PID_EMAC0 /* Ethernet MAC 0 */ +#define SAM_IRQ_EMAC1 SAM_PID_EMAC1 /* Ethernet MAC 1 */ +#define SAM_IRQ_AICID SAM_PID_AICID /* IRQ Interrupt ID */ +#define SAM_IRQ_SFC SAM_PID_SFC /* Fuse Controller */ +#define SAM_IRQ_SECURAM SAM_PID_SECURAM /* Secured RAM */ + +#define SAM_IRQ_SMD SAM_PID_SMD /* SMD Soft Modem */ +#define SAM_IRQ_TWI3 SAM_PID_TWI3 /* Two-Wire Interface 3 */ +#define SAM_IRQ_CATB SAM_PID_CATB /* Capacitive Touch Module */ +#define SAM_IRQ_SFR SAM_PID_SFR /* Special Function Register */ +#define SAM_IRQ_AIC SAM_PID_AIC /* Advanced Interrupt Controller */ +#define SAM_IRQ_SAIC SAM_PID_SAIC /* Secured Advanced Interrupt Controller */ +#define SAM_IRQ_L2CC SAM_PID_L2CC /* L2 Cache Controller */ + +#define SAM_IRQ_NINT (SAM_PID_L2CC + 1) + +/* PIO interrupts (derived from SAM_IRQ_PIOA/B/C/D/E/F) */ + +#ifdef CONFIG_SAMA5_PIOA_IRQ +# define SAM_IRQ_PIOA_PINS (SAM_IRQ_NINT) +# define SAM_IRQ_PA0 (SAM_IRQ_PIOA_PINS+0) /* PIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_PIOA_PINS+1) /* PIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_PIOA_PINS+2) /* PIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_PIOA_PINS+3) /* PIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_PIOA_PINS+4) /* PIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_PIOA_PINS+5) /* PIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_PIOA_PINS+6) /* PIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_PIOA_PINS+7) /* PIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_PIOA_PINS+8) /* PIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_PIOA_PINS+9) /* PIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_PIOA_PINS+10) /* PIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_PIOA_PINS+11) /* PIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_PIOA_PINS+12) /* PIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_PIOA_PINS+13) /* PIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_PIOA_PINS+14) /* PIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_PIOA_PINS+15) /* PIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_PIOA_PINS+16) /* PIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_PIOA_PINS+17) /* PIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_PIOA_PINS+18) /* PIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_PIOA_PINS+19) /* PIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_PIOA_PINS+20) /* PIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_PIOA_PINS+21) /* PIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_PIOA_PINS+22) /* PIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_PIOA_PINS+23) /* PIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_PIOA_PINS+24) /* PIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_PIOA_PINS+25) /* PIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_PIOA_PINS+26) /* PIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_PIOA_PINS+27) /* PIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_PIOA_PINS+28) /* PIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_PIOA_PINS+29) /* PIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_PIOA_PINS+30) /* PIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_PIOA_PINS+31) /* PIOA, PIN 31 */ +# define SAM_NPIOAIRQS 32 +#else +# define SAM_NPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOB_IRQ +# define SAM_IRQ_PIOB_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_PIOB_PINS+0) /* PIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_PIOB_PINS+1) /* PIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_PIOB_PINS+2) /* PIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_PIOB_PINS+3) /* PIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_PIOB_PINS+4) /* PIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_PIOB_PINS+5) /* PIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_PIOB_PINS+6) /* PIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_PIOB_PINS+7) /* PIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_PIOB_PINS+8) /* PIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_PIOB_PINS+9) /* PIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_PIOB_PINS+10) /* PIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_PIOB_PINS+11) /* PIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_PIOB_PINS+12) /* PIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_PIOB_PINS+13) /* PIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_PIOB_PINS+14) /* PIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_PIOB_PINS+15) /* PIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_PIOB_PINS+16) /* PIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_PIOB_PINS+17) /* PIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_PIOB_PINS+18) /* PIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_PIOB_PINS+19) /* PIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_PIOB_PINS+20) /* PIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_PIOB_PINS+21) /* PIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_PIOB_PINS+22) /* PIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_PIOB_PINS+23) /* PIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_PIOB_PINS+24) /* PIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_PIOB_PINS+25) /* PIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_PIOB_PINS+26) /* PIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_PIOB_PINS+27) /* PIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_PIOB_PINS+28) /* PIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_PIOB_PINS+29) /* PIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_PIOB_PINS+30) /* PIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_PIOB_PINS+31) /* PIOB, PIN 31 */ +# define SAM_NPIOBIRQS 32 +#else +# define SAM_NPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOC_IRQ +# define SAM_IRQ_PIOC_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_PIOC_PINS+0) /* PIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_PIOC_PINS+1) /* PIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_PIOC_PINS+2) /* PIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_PIOC_PINS+3) /* PIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_PIOC_PINS+4) /* PIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_PIOC_PINS+5) /* PIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_PIOC_PINS+6) /* PIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_PIOC_PINS+7) /* PIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_PIOC_PINS+8) /* PIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_PIOC_PINS+9) /* PIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_PIOC_PINS+10) /* PIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_PIOC_PINS+11) /* PIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_PIOC_PINS+12) /* PIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_PIOC_PINS+13) /* PIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_PIOC_PINS+14) /* PIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_PIOC_PINS+15) /* PIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_PIOC_PINS+16) /* PIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_PIOC_PINS+17) /* PIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_PIOC_PINS+18) /* PIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_PIOC_PINS+19) /* PIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_PIOC_PINS+20) /* PIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_PIOC_PINS+21) /* PIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_PIOC_PINS+22) /* PIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_PIOC_PINS+23) /* PIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_PIOC_PINS+24) /* PIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_PIOC_PINS+25) /* PIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_PIOC_PINS+26) /* PIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_PIOC_PINS+27) /* PIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_PIOC_PINS+28) /* PIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_PIOC_PINS+29) /* PIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_PIOC_PINS+30) /* PIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_PIOC_PINS+31) /* PIOC, PIN 31 */ +# define SAM_NPIOCIRQS 32 +#else +# define SAM_NPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOD_IRQ +# define SAM_IRQ_PIOD_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + SAM_NPIOBIRQS + \ + SAM_NPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_PIOD_PINS+0) /* PIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_PIOD_PINS+1) /* PIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_PIOD_PINS+2) /* PIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_PIOD_PINS+3) /* PIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_PIOD_PINS+4) /* PIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_PIOD_PINS+5) /* PIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_PIOD_PINS+6) /* PIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_PIOD_PINS+7) /* PIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_PIOD_PINS+8) /* PIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_PIOD_PINS+9) /* PIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_PIOD_PINS+10) /* PIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_PIOD_PINS+11) /* PIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_PIOD_PINS+12) /* PIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_PIOD_PINS+13) /* PIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_PIOD_PINS+14) /* PIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_PIOD_PINS+15) /* PIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_PIOD_PINS+16) /* PIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_PIOD_PINS+17) /* PIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_PIOD_PINS+18) /* PIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_PIOD_PINS+19) /* PIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_PIOD_PINS+20) /* PIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_PIOD_PINS+21) /* PIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_PIOD_PINS+22) /* PIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_PIOD_PINS+23) /* PIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_PIOD_PINS+24) /* PIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_PIOD_PINS+25) /* PIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_PIOD_PINS+26) /* PIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_PIOD_PINS+27) /* PIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_PIOD_PINS+28) /* PIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_PIOD_PINS+29) /* PIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_PIOD_PINS+30) /* PIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_PIOD_PINS+31) /* PIOD, PIN 31 */ +# define SAM_NPIODIRQS 32 +#else +# define SAM_NPIODIRQS 0 +#endif + +#ifdef CONFIG_SAMA5_PIOE_IRQ +# define SAM_IRQ_PIOE_PINS (SAM_IRQ_NINT + SAM_NPIOAIRQS + \ + SAM_NPIOBIRQS + SAM_NPIOCIRQS + SAM_NPIODIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_PIOE_PINS+0) /* PIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_PIOE_PINS+1) /* PIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_PIOE_PINS+2) /* PIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_PIOE_PINS+3) /* PIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_PIOE_PINS+4) /* PIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_PIOE_PINS+5) /* PIOE, PIN 5 */ +# define SAM_IRQ_PE6 (SAM_IRQ_PIOE_PINS+6) /* PIOE, PIN 6 */ +# define SAM_IRQ_PE7 (SAM_IRQ_PIOE_PINS+7) /* PIOE, PIN 7 */ +# define SAM_IRQ_PE8 (SAM_IRQ_PIOE_PINS+8) /* PIOE, PIN 8 */ +# define SAM_IRQ_PE9 (SAM_IRQ_PIOE_PINS+9) /* PIOE, PIN 9 */ +# define SAM_IRQ_PE10 (SAM_IRQ_PIOE_PINS+10) /* PIOE, PIN 10 */ +# define SAM_IRQ_PE11 (SAM_IRQ_PIOE_PINS+11) /* PIOE, PIN 11 */ +# define SAM_IRQ_PE12 (SAM_IRQ_PIOE_PINS+12) /* PIOE, PIN 12 */ +# define SAM_IRQ_PE13 (SAM_IRQ_PIOE_PINS+13) /* PIOE, PIN 13 */ +# define SAM_IRQ_PE14 (SAM_IRQ_PIOE_PINS+14) /* PIOE, PIN 14 */ +# define SAM_IRQ_PE15 (SAM_IRQ_PIOE_PINS+15) /* PIOE, PIN 15 */ +# define SAM_IRQ_PE16 (SAM_IRQ_PIOE_PINS+16) /* PIOE, PIN 16 */ +# define SAM_IRQ_PE17 (SAM_IRQ_PIOE_PINS+17) /* PIOE, PIN 17 */ +# define SAM_IRQ_PE18 (SAM_IRQ_PIOE_PINS+18) /* PIOE, PIN 18 */ +# define SAM_IRQ_PE19 (SAM_IRQ_PIOE_PINS+19) /* PIOE, PIN 19 */ +# define SAM_IRQ_PE20 (SAM_IRQ_PIOE_PINS+20) /* PIOE, PIN 20 */ +# define SAM_IRQ_PE21 (SAM_IRQ_PIOE_PINS+21) /* PIOE, PIN 21 */ +# define SAM_IRQ_PE22 (SAM_IRQ_PIOE_PINS+22) /* PIOE, PIN 22 */ +# define SAM_IRQ_PE23 (SAM_IRQ_PIOE_PINS+23) /* PIOE, PIN 23 */ +# define SAM_IRQ_PE24 (SAM_IRQ_PIOE_PINS+24) /* PIOE, PIN 24 */ +# define SAM_IRQ_PE25 (SAM_IRQ_PIOE_PINS+25) /* PIOE, PIN 25 */ +# define SAM_IRQ_PE26 (SAM_IRQ_PIOE_PINS+26) /* PIOE, PIN 26 */ +# define SAM_IRQ_PE27 (SAM_IRQ_PIOE_PINS+27) /* PIOE, PIN 27 */ +# define SAM_IRQ_PE28 (SAM_IRQ_PIOE_PINS+28) /* PIOE, PIN 28 */ +# define SAM_IRQ_PE29 (SAM_IRQ_PIOE_PINS+29) /* PIOE, PIN 29 */ +# define SAM_IRQ_PE30 (SAM_IRQ_PIOE_PINS+30) /* PIOE, PIN 30 */ +# define SAM_IRQ_PE31 (SAM_IRQ_PIOE_PINS+31) /* PIOE, PIN 31 */ +# define SAM_NPIOEIRQS 32 +#else +# define SAM_NPIOEIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_IRQS (SAM_IRQ_NINT + \ + SAM_NPIOAIRQS + SAM_NPIOBIRQS + SAM_NPIOCIRQS + \ + SAM_NPIODIRQS + SAM_NPIOEIRQS ) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMA5_SAMA5D4_IRQ_H */ diff --git a/arch/arm/include/samdl/chip.h b/arch/arm/include/samdl/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..9e447057dec17e360da2dcd36bc7cd85dad0e5b5 --- /dev/null +++ b/arch/arm/include/samdl/chip.h @@ -0,0 +1,993 @@ +/************************************************************************************ + * arch/arm/include/samdl/chip.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SAMDL_CHIP_H +#define __ARCH_ARM_INCLUDE_SAMDL_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +/* SAMD20 Family ********************************************************************/ +/* FEATURE SAM D20J SAM D20G SAM D20E + * ------------------- ------------------ ------------------ -------- + * No. of pins 64 48 32 + * Flash 256/128/64/32/16KB 256/128/64/32/16KB 256/128/64/32/16KB + * SRAM 32/16/8/4/2KB 32/16/8/4/2KB 32/16/8/4/2KB + * Max. Freq. 48MHz 48MHz 48MHz + * Event channels 8 8 8 + * Timer/counters 8 6 6 + * TC output channels 2 2 2 + * SERCOM 6 6 4 + * ADC channels 20 14 10 + * Comparators 2 2 2 + * DAC channels 1 1 1 + * RTC Yes Yes Yes + * RTC alarms 1 1 1 + * RTC compare 1 32-bit/2 16-bit 1 32-bit/2 16-bit 1 32-bit/2 16-bit + * External interrupts 16 16 16 + * PTC X an Y 16x16 12x10 10x6 + * Packages QFN/TQFP QFN/TQFP QFN/TQFP + * Oscillators XOSC32, XOSC, OSC32K, OSCULP32K, OSC8M, and DFLL48M + * SW Debug interface Yes Yes Yes + * Watchdog timer Yes Yes Yes + */ + +#if defined(CONFIG_ARCH_CHIP_SAMD20E14) + +# define SAMD20 1 /* SAMD20 family */ +# define SAMD20E 1 /* SAMD20E */ +# undef SAMD20G +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ +# define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20E15) + +# define SAMD20 1 /* SAMD20 family */ +# define SAMD20E 1 /* SAMD20E */ +# undef SAMD20G +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20E16) + +# define SAMD20 1 /* SAMD20 family */ +# define SAMD20E 1 /* SAMD20E */ +# undef SAMD20G +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20E17) + +# define SAMD20 1 /* SAMD20 family */ +# define SAMD20E 1 /* SAMD20E */ +# undef SAMD20G +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20E18) + +# define SAMD20 1 /* SAMD20 family */ +# define SAMD20E 1 /* SAMD20E */ +# undef SAMD20G +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20G14) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# define SAMD20G 1 /* SAMD20G */ +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ +# define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20G15) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# define SAMD20G 1 /* SAMD20G */ +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20G16) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# define SAMD20G 1 /* SAMD20G */ +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20G17) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# define SAMD20G 1 /* SAMD20G */ +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20G18) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# define SAMD20G 1 /* SAMD20G */ +# undef SAMD20J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20J14) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# define SAMD20J 1 /* SAMD20J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ +# define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20J15) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# define SAMD20J 1 /* SAMD20J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20J16) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# define SAMD20J 1 /* SAMD20J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20J17) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# define SAMD20J 1 /* SAMD20J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD20J18) + +# define SAMD20 1 /* SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# define SAMD20J 1 /* SAMD20J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#else + +# undef SAMD20 /* Not SAMD20 family */ +# undef SAMD20E +# undef SAMD20G +# undef SAMD20J + +#endif + +/* SAMD20 Peripherals */ + +#if defined(SAMD20E) +# define SAMDL_NEVENTS 8 /* 8 event channels */ +# define SAMDL_NTC 6 /* 6 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 0 /* No TC control channels */ +# define SAMDL_NTCCOUT 0 /* No TCC output channels */ +# define SAMDL_NDMACHAN 0 /* No DMA channels */ +# define SAMDL_NUSBIF 0 /* No USB interface */ +# define SAMDL_NAES 0 /* No AES engine */ +# define SAMDL_NCCL 0 /* No Counfigurable Custom Logic */ +# define SAMDL_NTRNG 0 /* No True random number generator */ +# define SAMDL_NSERCOM 4 /* 4 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 10 /* 10 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 0 /* No OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 10 /* PTC X */ +# define SAMDL_NPTCY 6 /* PTC Y */ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAMD20G) +# define SAMDL_NEVENTS 8 /* 8 event channels */ +# define SAMDL_NTC 6 /* 6 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 0 /* No TC control channels */ +# define SAMDL_NTCCOUT 0 /* No TCC output channels */ +# define SAMDL_NDMACHAN 0 /* No DMA channels */ +# define SAMDL_NUSBIF 0 /* No USB interface */ +# define SAMDL_NAES 0 /* No AES engine */ +# define SAMDL_NCCL 0 /* No Counfigurable Custom Logic */ +# define SAMDL_NTRNG 0 /* No True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 15 /* 14 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 0 /* No OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 12 /* PTC X */ +# define SAMDL_NPTCY 10 /* PTC Y */ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAMD20J) +# define SAMDL_NEVENTS 8 /* 8 event channels */ +# define SAMDL_NTC 8 /* 8 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 0 /* No TC control channels */ +# define SAMDL_NTCCOUT 0 /* No TCC output channels */ +# define SAMDL_NDMACHAN 0 /* No DMA channels */ +# define SAMDL_NUSBIF 0 /* No USB interface */ +# define SAMDL_NAES 0 /* No AES engine */ +# define SAMDL_NCCL 0 /* No Counfigurable Custom Logic */ +# define SAMDL_NTRNG 0 /* No True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 20 /* 20 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 0 /* No OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 16 /* PTC X */ +# define SAMDL_NPTCY 16 /* PTC Y */ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#endif + +/* SAMD21 Family ********************************************************************/ +/* FEATURE SAM D21J SAM D21G SAM D21E + * ------------------- ------------------ ------------------ -------- + * No. of pins 64 48 32 + * Flash 256/128/64/32/16KB 256/128/64/32KB 256/128/64/32KB + * SRAM 32/16/8/4/2KB 32/16/8/4/2KB 32/16/8/4KB + * Max. Freq. 48MHz 48MHz 48MHz + * Event channels 12 12 12 + * Timer/counters 5 3 3 + * TC output channels 2 2 2 + * T/C Control 3 3 3 + * TCC output channels 2 2 2 + * TCC waveform output 8/4/2 8/4/2 6/4/2 + * DMA channels 12 12 12 + * USB interface 1 1 1 + * SERCOM 6 6 4 + * I2S 1 1 1 + * ADC channels 20 14 10 + * Comparators 2 2 2 + * DAC channels 1 1 1 + * RTC Yes Yes Yes + * RTC alarms 1 1 1 + * RTC compare 1 32-bit/2 16-bit 1 32-bit/2 16-bit 1 32-bit/2 16-bit + * External interrupts 16 16 16 + * PTC X an Y 16x16 12x10 10x6 + * Packages QFN/TQFP QFN/TQFP/WLCSP QFN/TQFP/UFBGA + * Oscillators XOSC32, XOSC, OSC32K, OSCULP32K, OSC8M, DFLL48M, and FDPLL96M + * SW Debug interface Yes Yes Yes + * Watchdog timer Yes Yes Yes + */ + +#if defined(CONFIG_ARCH_CHIP_SAMD21E15A) || defined(CONFIG_ARCH_CHIP_SAMD21E15B) + +# define SAMD21 1 /* SAMD21 family */ +# define SAMD21E 1 /* SAMD21E */ +# undef SAMD21G +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21E15A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (1*1024) /* 1KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21E16A) || defined(CONFIG_ARCH_CHIP_SAMD21E16B) + +# define SAMD21 1 /* SAMD21 family */ +# define SAMD21E 1 /* SAMD21E */ +# undef SAMD21G +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21E16A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21E17A) + +# define SAMD21 1 /* SAMD21 family */ +# define SAMD21E 1 /* SAMD21E */ +# undef SAMD21G +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD21E18A) + +# define SAMD21 1 /* SAMD21 family */ +# define SAMD21E 1 /* SAMD21E */ +# undef SAMD21G +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD21G15A) || defined(CONFIG_ARCH_CHIP_SAMD21G15B) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# define SAMD21G 1 /* SAMD21G */ +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21G15A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (1*1024) /* 1KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21G16A) || defined(CONFIG_ARCH_CHIP_SAMD21G16B) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# define SAMD21G 1 /* SAMD21G */ +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21G16A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21G17A) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# define SAMD21G 1 /* SAMD21G */ +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD21G18A) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# define SAMD21G 1 /* SAMD21G */ +# undef SAMD21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD21J15A) || defined(CONFIG_ARCH_CHIP_SAMD21J15B) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# undef SAMD21G +# define SAMD21J 1 /* SAMD21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21J15A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (1*1024) /* 1KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21J16A) || defined(CONFIG_ARCH_CHIP_SAMD21J16B) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# undef SAMD21G +# define SAMD21J 1 /* SAMD21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +# if defined(CONFIG_ARCH_CHIP_SAMD21J16A) +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# else +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# endif + +#elif defined(CONFIG_ARCH_CHIP_SAMD21J17A) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# undef SAMD21G +# define SAMD21J 1 /* SAMD21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#elif defined(CONFIG_ARCH_CHIP_SAMD21J18A) + +# define SAMD21 1 /* SAMD21 family */ +# undef SAMD21E +# undef SAMD21G +# define SAMD21J 1 /* SAMD21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (0*1024) /* None */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ + +#else + +# undef SAMD21 /* Not SAMD21 family */ +# undef SAMD21E +# undef SAMD21G +# undef SAMD21J + +#endif + +#if defined(SAMD21E) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 3 /* 3 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_TCC_NWAVEFORMS 8 /* Each TCC has a different number of outputs */ +# define SAMDL_NDMACHAN 12 /* 12 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 4 /* 4 SERCOM */ +# define SAMDL_NI2S 1 /* 1 I2S */ +# define SAMDL_NADC 10 /* 10 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 10 /* 10x6 */ +# define SAMDL_NPTCY 6 /* 10x6*/ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAMD21G) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 3 /* 3 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_TCC_NWAVEFORMS 8 /* Each TCC has a different number of outputs */ +# define SAMDL_NDMACHAN 12 /* 12 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 1 /* 1 I2S */ +# define SAMDL_NADC 14 /* 14 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 12 /* 12x10 */ +# define SAMDL_NPTCY 10 /* 12x10 */ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAMD21J) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 5 /* 5 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_TCC_NWAVEFORMS 8 /* Each TCC has a different number of outputs */ +# define SAMDL_NDMACHAN 12 /* 12 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 1 /* 1 I2S */ +# define SAMDL_NADC 20 /* 20 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 1 /* 1 DAC channel */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 16 /* 16x16 */ +# define SAMDL_NPTCY 16 /* 16x16*/ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#endif + +/* SAML21 Family ********************************************************************/ +/* FEATURE SAM L21J SAM L21G SAM L21E + * ------------------- ------------------ ------------------ -------- + * No. of pins 64 48 32 + * Flash 256/128/64KB 256/128/64KB 256/128/64/32KB + * Flash RWW 8/4/2KB 8/4/2KB 8/4/2/1KB + * SRAM 32/16/8KB 32/16/8KB 32/16/8/4KB + * Max. Freq. 48MHz 48MHz 48MHz + * Event channels 12 12 12 + * Timer/counters 5 3 3 + * TC output channels 2 2 2 + * T/C Control 3 3 3 + * TCC output channels 2 2 2 + * TCC waveform output 8/4/2 8/4/2 6/4/2 + * DMA channels 16 16 16 + * USB interface 1 1 1 + * AES engine 1 1 1 + * CCLs 4 4 4 + * TRNG 1 1 1 + * SERCOM 6 6 4 + * ADC channels 20 14 10 + * Comparators 2 2 2 + * DAC channels 2 2 2 + * OPAMP 3 3 3 + * RTC Yes Yes Yes + * RTC alarms 1 1 1 + * RTC compare 1 32-bit/2 16-bit 1 32-bit/2 16-bit 1 32-bit/2 16-bit + * External interrupts 16 16 16 + * PTC X an Y 12x16 8x12 6x10 + * 16x12 12x8 10x6 + * Packages QFN/TQFP QFN/TQFP QFN/TQFP + * Oscillators XOSC32, XOSC, OSC32K, OSCULP32K, OSC16M, DFLL48M, and FDPLL96M + * SW Debug interface Yes Yes Yes + * Watchdog timer Yes Yes Yes + */ + +#if defined(CONFIG_ARCH_CHIP_SAML21E15) + +# define SAML21 1 /* SAML21 family */ +# define SAML21E 1 /* SAML21E */ +# undef SAML21G +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ +# define SAMDL_FLASHRWW_SIZE (1*1024) /* 1KB */ +# define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (2*1024) /* 2KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 2 /* 2 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21E16) + +# define SAML21 1 /* SAML21 family */ +# define SAML21E 1 /* SAML21E */ +# undef SAML21G +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (4*1024) /* 4KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 2 /* 2 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21E17) + +# define SAML21 1 /* SAML21 family */ +# define SAML21E 1 /* SAML21E */ +# undef SAML21G +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 4 /* 4 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21E18) + +# define SAML21 1 /* SAML21 family */ +# define SAML21E 1 /* SAML21E */ +# undef SAML21G +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 6 /* 6 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21G16) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# define SAML21G 1 /* SAML21G */ +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (4*1024) /* 4KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 2 /* 2 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21G17) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# define SAML21G 1 /* SAML21G */ +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 4 /* 4 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21G18) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# define SAML21G 1 /* SAML21G */ +# undef SAML21J + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 8 /* 8 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21J16) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# undef SAML21G +# define SAML21J 1 /* SAML21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ +# define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ +# define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 4KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 2 /* 2 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21J17) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# undef SAML21G +# define SAML21J 1 /* SAML21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 4 /* 4 TCC waveform outputs */ + +#elif defined(CONFIG_ARCH_CHIP_SAML21J18) + +# define SAML21 1 /* SAML21 family */ +# undef SAML21E +# undef SAML21G +# define SAML21J 1 /* SAML21J */ + +/* Internal memory */ + +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ + +/* TCC waveform outputs */ + +# define SAMDL_TCC_NWAVEFORMS 8 /* 8 TCC waveform outputs */ + +#else + +# undef SAML21 /* Not SAML21 family */ +# undef SAML21E +# undef SAML21G +# undef SAML21J + +#endif + +#if defined(SAML21E) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 3 /* 3 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_NDMACHAN 16 /* 16 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 4 /* 4 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 10 /* 10 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 2 /* 2 DAC channels */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 10 /* PTC X 6 or 10 */ +# define SAMDL_NPTCY 10 /* PTC Y 6 or 10*/ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAML21G) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 3 /* 3 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_NDMACHAN 16 /* 16 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 14 /* 14 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 2 /* 2 DAC channels */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 12 /* PTC X 8 or 12 */ +# define SAMDL_NPTCY 12 /* PTC Y 8 or 12*/ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#elif defined(SAML21J) +# define SAMDL_NEVENTS 12 /* 12 event channels */ +# define SAMDL_NTC 5 /* 5 Timer/counters */ +# define SAMDL_NTCOUT 2 /* 2 TC output channels */ +# define SAMDL_NTCC 3 /* 3 TC control channels */ +# define SAMDL_NTCCOUT 2 /* 2 TCC output channels */ +# define SAMDL_NDMACHAN 16 /* 16 DMA channels */ +# define SAMDL_NUSBIF 1 /* 1 USB interface */ +# define SAMDL_NAES 1 /* 1 AES engine */ +# define SAMDL_NCCL 4 /* 4 Counfigurable Custom Logic */ +# define SAMDL_NTRNG 1 /* 1 True random number generator */ +# define SAMDL_NSERCOM 6 /* 6 SERCOM */ +# define SAMDL_NI2S 0 /* No I2S */ +# define SAMDL_NADC 20 /* 20 ADC channels */ +# define SAMDL_NCMP 2 /* 2 Comparators */ +# define SAMDL_NDAC 2 /* 2 DAC channels */ +# define SAMCL_NOPAMP 3 /* 3 OpAmps */ +# define SAMDL_RTC 1 /* Have RTC */ +# define SAMDL_NALARMS 1 /* 1 RTC alarm */ +# define SAMDL_NRTCMP 1 /* RTC compare: 1 32-bit/2 16-bit */ +# define SAMDL_NEXTINT 16 /* 16 External interrupts */ +# define SAMDL_NPTCX 16 /* PTC X 12 or 16 */ +# define SAMDL_NPTCY 16 /* PTC Y 12 or 16*/ +# define SAMDL_WDT 1 /* Have watchdog timer */ +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-3. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:6] of each field, bits[5:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Five bits of interrupt priority used */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_SAMDL_CHIP_H */ diff --git a/arch/arm/include/samdl/irq.h b/arch/arm/include/samdl/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..d74584fb298cc557b03dfe5dfb2804d0a811152c --- /dev/null +++ b/arch/arm/include/samdl/irq.h @@ -0,0 +1,116 @@ +/**************************************************************************************** + * arch/arm/include/samdl/irq.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMDL_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMDL_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define SAM_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define SAM_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define SAM_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + /* Vector 4-10: Reserved */ +#define SAM_IRQ_SVCALL (11) /* Vector 11: SVC call */ + /* Vector 12-13: Reserved */ +#define SAM_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define SAM_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define SAM_IRQ_INTERRUPT (16) /* Vector number of the first external interrupt */ + +/* Chip-Specific External interrupts */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# include +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# include +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMDL_IRQ_H */ diff --git a/arch/arm/include/samdl/samd20_irq.h b/arch/arm/include/samdl/samd20_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..01361e8e00e5b8d9d7e9574fbdacf5b13deca5ee --- /dev/null +++ b/arch/arm/include/samdl/samd20_irq.h @@ -0,0 +1,142 @@ +/**************************************************************************************** + * arch/arm/include/samd/samd20_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMDL_SAMD20_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMDL_SAMD20_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* External interrupts */ + +#define SAM_IRQ_PM (SAM_IRQ_INTERRUPT+0) /* Power Manager */ +#define SAM_IRQ_SYSCTRL (SAM_IRQ_INTERRUPT+1) /* System Controller */ +#define SAM_IRQ_WDT (SAM_IRQ_INTERRUPT+2) /* Watchdog Timer */ +#define SAM_IRQ_RTC (SAM_IRQ_INTERRUPT+3) /* Real Time Counter */ +#define SAM_IRQ_EIC (SAM_IRQ_INTERRUPT+4) /* External Interrupt Controller */ +#define SAM_IRQ_NVMCTRL (SAM_IRQ_INTERRUPT+5) /* Non-Volatile Memory Controller */ +#define SAM_IRQ_EVSYS (SAM_IRQ_INTERRUPT+6) /* Event System */ +#define SAM_IRQ_SERCOM0 (SAM_IRQ_INTERRUPT+7) /* Serial Communication Interface 0 */ +#define SAM_IRQ_SERCOM1 (SAM_IRQ_INTERRUPT+8) /* Serial Communication Interface 1 */ +#define SAM_IRQ_SERCOM2 (SAM_IRQ_INTERRUPT+9) /* Serial Communication Interface 2 */ +#define SAM_IRQ_SERCOM3 (SAM_IRQ_INTERRUPT+10) /* Serial Communication Interface 3 */ +#define SAM_IRQ_SERCOM4 (SAM_IRQ_INTERRUPT+11) /* Serial Communication Interface 4 */ +#define SAM_IRQ_SERCOM5 (SAM_IRQ_INTERRUPT+12) /* Serial Communication Interface 5 */ +#define SAM_IRQ_TC0 (SAM_IRQ_INTERRUPT+13) /* Timer/Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_INTERRUPT+14) /* Timer/Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_INTERRUPT+15) /* Timer/Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_INTERRUPT+16) /* Timer/Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_INTERRUPT+17) /* Timer/Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_INTERRUPT+18) /* Timer/Counter 5 */ +#define SAM_IRQ_TC6 (SAM_IRQ_INTERRUPT+19) /* Timer/Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_INTERRUPT+20) /* Timer/Counter 7 */ +#define SAM_IRQ_ADC (SAM_IRQ_INTERRUPT+21) /* Analog-to-Digital Converter */ +#define SAM_IRQ_AC (SAM_IRQ_INTERRUPT+22) /* Analog Comparator */ +#define SAM_IRQ_DAC (SAM_IRQ_INTERRUPT+23) /* Digital-to-Analog Converter */ +#define SAM_IRQ_PTC (SAM_IRQ_INTERRUPT+24) /* Peripheral Touch Controller*/ + +#define SAM_IRQ_NINTS (25) /* Total number of interrupts */ +#define SAM_IRQ_NIRQS (SAM_IRQ_INTERRUPT+25) /* The number of real interrupts */ + +/* GPIO interrupts. Up to 16 pins may be configured to support interrupts */ + +#ifdef CONFIG_GPIO_IRQ +# define SAM_IRQ_EXTINT0 (SAM_IRQ_NIRQS+0) /* External interrupt 0 */ +# define SAM_IRQ_EXTINT1 (SAM_IRQ_NIRQS+1) /* External interrupt 1 */ +# define SAM_IRQ_EXTINT2 (SAM_IRQ_NIRQS+2) /* External interrupt 2 */ +# define SAM_IRQ_EXTINT3 (SAM_IRQ_NIRQS+3) /* External interrupt 3 */ +# define SAM_IRQ_EXTINT4 (SAM_IRQ_NIRQS+4) /* External interrupt 4 */ +# define SAM_IRQ_EXTINT5 (SAM_IRQ_NIRQS+5) /* External interrupt 5 */ +# define SAM_IRQ_EXTINT6 (SAM_IRQ_NIRQS+6) /* External interrupt 6 */ +# define SAM_IRQ_EXTINT7 (SAM_IRQ_NIRQS+7) /* External interrupt 7 */ +# define SAM_IRQ_EXTINT8 (SAM_IRQ_NIRQS+8) /* External interrupt 8 */ +# define SAM_IRQ_EXTINT9 (SAM_IRQ_NIRQS+9) /* External interrupt 9 */ +# define SAM_IRQ_EXTINT10 (SAM_IRQ_NIRQS+10) /* External interrupt 10 */ +# define SAM_IRQ_EXTINT11 (SAM_IRQ_NIRQS+11) /* External interrupt 11 */ +# define SAM_IRQ_EXTINT12 (SAM_IRQ_NIRQS+12) /* External interrupt 12 */ +# define SAM_IRQ_EXTINT13 (SAM_IRQ_NIRQS+13) /* External interrupt 13 */ +# define SAM_IRQ_EXTINT14 (SAM_IRQ_NIRQS+14) /* External interrupt 14 */ +# define SAM_IRQ_EXTINT15 (SAM_IRQ_NIRQS+15) /* External interrupt 15 */ +# define SAM_IRQ_NEXTINTS 16 +#else +# define SAM_IRQ_NEXTINTS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS + SAM_IRQ_NEXTINTS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMDL_SAMD20_IRQ_H */ diff --git a/arch/arm/include/samdl/samd21_irq.h b/arch/arm/include/samdl/samd21_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..2ea4db825795737185aeda5fdea09c6c10357645 --- /dev/null +++ b/arch/arm/include/samdl/samd21_irq.h @@ -0,0 +1,149 @@ +/**************************************************************************************** + * arch/arm/include/samd/samd21_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMDL_SAMD21_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMDL_SAMD21_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* External interrupts */ + +#define SAM_IRQ_PM (SAM_IRQ_INTERRUPT+0) /* Power Manager */ +#define SAM_IRQ_SYSCTRL (SAM_IRQ_INTERRUPT+1) /* System Controller */ +#define SAM_IRQ_WDT (SAM_IRQ_INTERRUPT+2) /* Watchdog Timer */ +#define SAM_IRQ_RTC (SAM_IRQ_INTERRUPT+3) /* Real Time Counter */ +#define SAM_IRQ_EIC (SAM_IRQ_INTERRUPT+4) /* External Interrupt Controller */ +#define SAM_IRQ_NVMCTRL (SAM_IRQ_INTERRUPT+5) /* Non-Volatile Memory Controller */ +#define SAM_IRQ_DMAC (SAM_IRQ_INTERRUPT+6) /* Direct Memory Access Controller */ +#define SAM_IRQ_USB (SAM_IRQ_INTERRUPT+7) /* Universal Serial Bus */ +#define SAM_IRQ_EVSYS (SAM_IRQ_INTERRUPT+8) /* Event System */ +#define SAM_IRQ_SERCOM0 (SAM_IRQ_INTERRUPT+9) /* Serial Communication Interface 0 */ +#define SAM_IRQ_SERCOM1 (SAM_IRQ_INTERRUPT+10) /* Serial Communication Interface 1 */ +#define SAM_IRQ_SERCOM2 (SAM_IRQ_INTERRUPT+11) /* Serial Communication Interface 2 */ +#define SAM_IRQ_SERCOM3 (SAM_IRQ_INTERRUPT+12) /* Serial Communication Interface 3 */ +#define SAM_IRQ_SERCOM4 (SAM_IRQ_INTERRUPT+13) /* Serial Communication Interface 4 */ +#define SAM_IRQ_SERCOM5 (SAM_IRQ_INTERRUPT+14) /* Serial Communication Interface 5 */ +#define SAM_IRQ_TCC0 (SAM_IRQ_INTERRUPT+15) /* Timer/Counter for Control 0 */ +#define SAM_IRQ_TCC1 (SAM_IRQ_INTERRUPT+16) /* Timer/Counter for Control 1 */ +#define SAM_IRQ_TCC2 (SAM_IRQ_INTERRUPT+17) /* Timer/Counter for Control 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_INTERRUPT+18) /* Timer/Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_INTERRUPT+19) /* Timer/Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_INTERRUPT+20) /* Timer/Counter 5 */ +#define SAM_IRQ_TC6 (SAM_IRQ_INTERRUPT+21) /* Timer/Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_INTERRUPT+22) /* Timer/Counter 7 */ +#define SAM_IRQ_ADC (SAM_IRQ_INTERRUPT+23) /* Analog-to-Digital Converter */ +#define SAM_IRQ_AC (SAM_IRQ_INTERRUPT+24) /* Analog Comparator */ +#define SAM_IRQ_DAC (SAM_IRQ_INTERRUPT+25) /* Digital-to-Analog Converter */ +#define SAM_IRQ_PTC (SAM_IRQ_INTERRUPT+26) /* Peripheral Touch Controller */ +#define SAM_IRQ_I2S (SAM_IRQ_INTERRUPT+27) /* Inter IC Sound */ + +#define SAM_IRQ_NINTS (28) /* Total number of interrupts */ +#define SAM_IRQ_NIRQS (SAM_IRQ_INTERRUPT+28) /* The number of real interrupts */ + +/* GPIO interrupts. Up to 16 pins may be configured to support interrupts */ + +#ifdef CONFIG_GPIO_IRQ +# define SAM_IRQ_EXTINT0 (SAM_IRQ_NIRQS+0) /* External interrupt 0 */ +# define SAM_IRQ_EXTINT1 (SAM_IRQ_NIRQS+1) /* External interrupt 1 */ +# define SAM_IRQ_EXTINT2 (SAM_IRQ_NIRQS+2) /* External interrupt 2 */ +# define SAM_IRQ_EXTINT3 (SAM_IRQ_NIRQS+3) /* External interrupt 3 */ +# define SAM_IRQ_EXTINT4 (SAM_IRQ_NIRQS+4) /* External interrupt 4 */ +# define SAM_IRQ_EXTINT5 (SAM_IRQ_NIRQS+5) /* External interrupt 5 */ +# define SAM_IRQ_EXTINT6 (SAM_IRQ_NIRQS+6) /* External interrupt 6 */ +# define SAM_IRQ_EXTINT7 (SAM_IRQ_NIRQS+7) /* External interrupt 7 */ +# define SAM_IRQ_EXTINT8 (SAM_IRQ_NIRQS+8) /* External interrupt 8 */ +# define SAM_IRQ_EXTINT9 (SAM_IRQ_NIRQS+9) /* External interrupt 9 */ +# define SAM_IRQ_EXTINT10 (SAM_IRQ_NIRQS+10) /* External interrupt 10 */ +# define SAM_IRQ_EXTINT11 (SAM_IRQ_NIRQS+11) /* External interrupt 11 */ +# define SAM_IRQ_EXTINT12 (SAM_IRQ_NIRQS+12) /* External interrupt 12 */ +# define SAM_IRQ_EXTINT13 (SAM_IRQ_NIRQS+13) /* External interrupt 13 */ +# define SAM_IRQ_EXTINT14 (SAM_IRQ_NIRQS+14) /* External interrupt 14 */ +# define SAM_IRQ_EXTINT15 (SAM_IRQ_NIRQS+15) /* External interrupt 15 */ +# define SAM_IRQ_NEXTINTS 16 +#else +# define SAM_IRQ_NEXTINTS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS + SAM_IRQ_NEXTINTS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline Functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMDL_SAMD21_IRQ_H */ diff --git a/arch/arm/include/samdl/saml21_irq.h b/arch/arm/include/samdl/saml21_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..9622a0321523cc257ab1de0f09435cea89c86439 --- /dev/null +++ b/arch/arm/include/samdl/saml21_irq.h @@ -0,0 +1,150 @@ +/**************************************************************************************** + * arch/arm/include/samd/saml21_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMDL_SAML21_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMDL_SAML21_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* External interrupts */ + +#define SAM_IRQ_PM (SAM_IRQ_INTERRUPT+0) /* Power Manager */ +#define SAM_IRQ_MCLK (SAM_IRQ_INTERRUPT+0) /* Main Clock */ +#define SAM_IRQ_OSCCTRL (SAM_IRQ_INTERRUPT+0) /* Oscillators Controller */ +#define SAM_IRQ_OSC32KCTRL (SAM_IRQ_INTERRUPT+0) /* 32KHz scillators Controller */ +#define SAM_IRQ_SUPC (SAM_IRQ_INTERRUPT+0) /* Supply Controller */ +#define SAM_IRQ_PACC (SAM_IRQ_INTERRUPT+0) /* Protection Access Controller */ +#define SAM_IRQ_WDT (SAM_IRQ_INTERRUPT+1) /* Watchdog Timer */ +#define SAM_IRQ_RTC (SAM_IRQ_INTERRUPT+2) /* Real Time Counter */ +#define SAM_IRQ_EIC (SAM_IRQ_INTERRUPT+3) /* External Interrupt Controller */ +#define SAM_IRQ_NVMCTRL (SAM_IRQ_INTERRUPT+4) /* Non-Volatile Memory Controller */ +#define SAM_IRQ_DMAC (SAM_IRQ_INTERRUPT+5) /* Direct Memory Access Controller */ +#define SAM_IRQ_USB (SAM_IRQ_INTERRUPT+6) /* Universal Serial Bus */ +#define SAM_IRQ_EVSYS (SAM_IRQ_INTERRUPT+7) /* Event System */ +#define SAM_IRQ_SERCOM0 (SAM_IRQ_INTERRUPT+8) /* Serial Communication Interface 0 */ +#define SAM_IRQ_SERCOM1 (SAM_IRQ_INTERRUPT+9) /* Serial Communication Interface 1 */ +#define SAM_IRQ_SERCOM2 (SAM_IRQ_INTERRUPT+10) /* Serial Communication Interface 2 */ +#define SAM_IRQ_SERCOM3 (SAM_IRQ_INTERRUPT+11) /* Serial Communication Interface 3 */ +#define SAM_IRQ_SERCOM4 (SAM_IRQ_INTERRUPT+12) /* Serial Communication Interface 4 */ +#define SAM_IRQ_SERCOM5 (SAM_IRQ_INTERRUPT+13) /* Serial Communication Interface 5 */ +#define SAM_IRQ_TCC0 (SAM_IRQ_INTERRUPT+14) /* Timer/Counter for Control 0 */ +#define SAM_IRQ_TCC1 (SAM_IRQ_INTERRUPT+15) /* Timer/Counter for Control 1 */ +#define SAM_IRQ_TCC2 (SAM_IRQ_INTERRUPT+16) /* Timer/Counter for Control 2 */ +#define SAM_IRQ_TC0 (SAM_IRQ_INTERRUPT+17) /* Timer/Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_INTERRUPT+18) /* Timer/Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_INTERRUPT+19) /* Timer/Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_INTERRUPT+20) /* Timer/Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_INTERRUPT+21) /* Timer/Counter 4 */ +#define SAM_IRQ_ADC (SAM_IRQ_INTERRUPT+22) /* Analog-to-Digital Converter */ +#define SAM_IRQ_AC (SAM_IRQ_INTERRUPT+23) /* Analog Comparator */ +#define SAM_IRQ_DAC (SAM_IRQ_INTERRUPT+24) /* Digital-to-Analog Converter */ +#define SAM_IRQ_PTC (SAM_IRQ_INTERRUPT+25) /* Peripheral Touch Controller */ +#define SAM_IRQ_AES (SAM_IRQ_INTERRUPT+26) /* Advanced Encryption Standard Module */ +#define SAM_IRQ_TRNG (SAM_IRQ_INTERRUPT+27) /* True Random Number Generator */ + +#define SAM_IRQ_NINTS (28) /* Total number of interrupts */ +#define SAM_IRQ_NIRQS (SAM_IRQ_INTERRUPT+28) /* The number of real interrupts */ + +/* GPIO interrupts. Up to 16 pins may be configured to support interrupts */ + +#ifdef CONFIG_GPIO_IRQ +# define SAM_IRQ_EXTINT0 (SAM_IRQ_NIRQS+0) /* External interrupt 0 */ +# define SAM_IRQ_EXTINT1 (SAM_IRQ_NIRQS+1) /* External interrupt 1 */ +# define SAM_IRQ_EXTINT2 (SAM_IRQ_NIRQS+2) /* External interrupt 2 */ +# define SAM_IRQ_EXTINT3 (SAM_IRQ_NIRQS+3) /* External interrupt 3 */ +# define SAM_IRQ_EXTINT4 (SAM_IRQ_NIRQS+4) /* External interrupt 4 */ +# define SAM_IRQ_EXTINT5 (SAM_IRQ_NIRQS+5) /* External interrupt 5 */ +# define SAM_IRQ_EXTINT6 (SAM_IRQ_NIRQS+6) /* External interrupt 6 */ +# define SAM_IRQ_EXTINT7 (SAM_IRQ_NIRQS+7) /* External interrupt 7 */ +# define SAM_IRQ_EXTINT8 (SAM_IRQ_NIRQS+8) /* External interrupt 8 */ +# define SAM_IRQ_EXTINT9 (SAM_IRQ_NIRQS+9) /* External interrupt 9 */ +# define SAM_IRQ_EXTINT10 (SAM_IRQ_NIRQS+10) /* External interrupt 10 */ +# define SAM_IRQ_EXTINT11 (SAM_IRQ_NIRQS+11) /* External interrupt 11 */ +# define SAM_IRQ_EXTINT12 (SAM_IRQ_NIRQS+12) /* External interrupt 12 */ +# define SAM_IRQ_EXTINT13 (SAM_IRQ_NIRQS+13) /* External interrupt 13 */ +# define SAM_IRQ_EXTINT14 (SAM_IRQ_NIRQS+14) /* External interrupt 14 */ +# define SAM_IRQ_EXTINT15 (SAM_IRQ_NIRQS+15) /* External interrupt 15 */ +# define SAM_IRQ_NEXTINTS 16 +#else +# define SAM_IRQ_NEXTINTS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS + SAM_IRQ_NEXTINTS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline Functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMDL_SAML21_IRQ_H */ diff --git a/arch/arm/include/samv7/chip.h b/arch/arm/include/samv7/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..2d52b3de8a6d6220fef40d804b6657dd911cc45a --- /dev/null +++ b/arch/arm/include/samv7/chip.h @@ -0,0 +1,461 @@ +/************************************************************************************ + * arch/arm/include/samv7/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SAMV7_CHIP_H +#define __ARCH_ARM_INCLUDE_SAMV7_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +/* SAME70Q19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAME70Q20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAME70Q21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP144 and LFBGA144 packaging + */ + +#if defined(CONFIG_ARCH_CHIP_SAME70Q19) || defined(CONFIG_ARCH_CHIP_SAME70Q20) || \ + defined(CONFIG_ARCH_CHIP_SAME70Q21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAME70Q19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAME70Q20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAME70Q21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +# define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +/* Peripherals */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 1 /* Have External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 1 /* Have SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 0 /* No MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 24 /* 24 12-bit ADC channels */ +# define SAMV7_NDAC12 2 /* 2 12-bit DAC channels */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 36 /* 36 Timer/counter channels I/O */ +# define SAMV7_NUSART 3 /* 3 USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 1 /* 1 Quad SPI */ +# define SAMV7_NSPI 2 /* 2 SPI, SPI0-1 */ +# define SAMV7_NTWIHS 3 /* 3 TWIHS */ +# define SAMV7_NHSMCI4 1 /* 1 4-bit HSMCI port */ +# define SAMV7_NCAN 2 /* 2 CAN ports */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 1 /* 1 Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 1 /* 1 12-bit ISI interface */ +# define SAMV7_NISI8 0 /* No 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 1 /* 1 USB high speed device */ +# define SAMV7_NUHPHS 1 /* 1 USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 0 /* No USB full speed device */ +# define SAMV7_NUHPFS 0 /* No USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +/* SAME70N19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAME70N20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAME70N21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP100 and TFBGA100 packaging + */ + +#elif defined(CONFIG_ARCH_CHIP_SAME70N19) || defined(CONFIG_ARCH_CHIP_SAME70N20) || \ + defined(CONFIG_ARCH_CHIP_SAME70N21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAME70N19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAME70N20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAME70N21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +# define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +/* Peripherals */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 0 /* No External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 0 /* No SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 0 /* No MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 10 /* 10 12-bit ADC channels */ +# define SAMV7_NDAC12 2 /* 2 12-bit DAC channels */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 9 /* 9 Timer/counter channels I/O */ +# define SAMV7_NUSART 3 /* 3 USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 1 /* 1 Quad SPI */ +# define SAMV7_NSPI 1 /* 1 SPI, SPI0 only */ +# define SAMV7_NTWIHS 3 /* 3 TWIHS */ +# define SAMV7_NHSMCI4 1 /* 1 4-bit HSMCI port */ +# define SAMV7_NCAN 2 /* 2 CAN ports */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 1 /* 1 Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 1 /* 1 12-bit ISI interface */ +# define SAMV7_NISI8 0 /* No 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 1 /* 1 USB high speed device */ +# define SAMV7_NUHPHS 1 /* 1 USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 0 /* No USB full speed device */ +# define SAMV7_NUHPFS 0 /* No USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +/* SAME70J19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAME70J20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAME70J21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP64 and TFBGA64 packaging + */ + +#elif defined(CONFIG_ARCH_CHIP_SAME70J19) || defined(CONFIG_ARCH_CHIP_SAME70J20) || \ + defined(CONFIG_ARCH_CHIP_SAME70J21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAME70J19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAME70J20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAME70J21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +# define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 0 /* No External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 0 /* No SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 0 /* No MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 5 /* 5 12-bit ADC channels */ +# define SAMV7_NDAC12 1 /* 1 12-bit DAC channel */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 3 /* 3 Timer/counter channels I/O */ +# define SAMV7_NUSART 0 /* No USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 0 /* No Quad SPI */ +# define SAMV7_NSPI 1 /* No SPI, QSPI functions in SPI mode only */ +# define SAMV7_NTWIHS 2 /* 2 TWIHS */ +# define SAMV7_NHSMCI4 0 /* No 4-bit HSMCI port */ +# define SAMV7_NCAN 1 /* 1 CAN port */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 0 /* No Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 0 /* No 12-bit ISI interface */ +# define SAMV7_NISI8 1 /* 1 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 0 /* No USB high speed device */ +# define SAMV7_NUHPHS 0 /* No USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 1 /* 1 USB full speed device */ +# define SAMV7_NUHPFS 1 /* 1 USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +/* SAMV71Q19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAMV71Q20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAMV71Q21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP144 and LFBGA144 packaging + */ + +#elif defined(CONFIG_ARCH_CHIP_SAMV71Q19) || defined(CONFIG_ARCH_CHIP_SAMV71Q20) || \ + defined(CONFIG_ARCH_CHIP_SAMV71Q21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71Q19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAMV71Q20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAMV71Q21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +# define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +/* Peripherals */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 1 /* Have External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 1 /* Have SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 1 /* Have MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 24 /* 24 12-bit ADC channels */ +# define SAMV7_NDAC12 2 /* 2 12-bit DAC channels */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 36 /* 36 Timer/counter channels I/O */ +# define SAMV7_NUSART 3 /* 3 USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 1 /* 1 Quad SPI */ +# define SAMV7_NSPI 2 /* 2 SPI, SPI0-1 */ +# define SAMV7_NTWIHS 3 /* 3 TWIHS */ +# define SAMV7_NHSMCI4 1 /* 1 4-bit HSMCI port */ +# define SAMV7_NCAN 2 /* 2 CAN ports */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 1 /* 1 Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 1 /* 1 12-bit ISI interface */ +# define SAMV7_NISI8 0 /* No 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 1 /* 1 USB high speed device */ +# define SAMV7_NUHPHS 1 /* 1 USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 0 /* No USB full speed device */ +# define SAMV7_NUHPFS 0 /* No USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +/* SAMV71N19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAMV71N20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAMV71N21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP100 and TFBGA100 packaging + */ + +#elif defined(CONFIG_ARCH_CHIP_SAMV71N19) || defined(CONFIG_ARCH_CHIP_SAMV71N20) || \ + defined(CONFIG_ARCH_CHIP_SAMV71N21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71N19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAMV71N20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAMV71N21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +# define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +/* Peripherals */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 0 /* No External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 0 /* No SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 1 /* Have MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 10 /* 10 12-bit ADC channels */ +# define SAMV7_NDAC12 2 /* 2 12-bit DAC channels */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 9 /* 9 Timer/counter channels I/O */ +# define SAMV7_NUSART 3 /* 3 USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 1 /* 1 Quad SPI */ +# define SAMV7_NSPI 1 /* 1 SPI, SPI0 */ +# define SAMV7_NTWIHS 3 /* 3 TWIHS */ +# define SAMV7_NHSMCI4 1 /* 1 4-bit HSMCI port */ +# define SAMV7_NCAN 2 /* 2 CAN ports */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 1 /* 1 Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 1 /* 1 12-bit ISI interface */ +# define SAMV7_NISI8 0 /* No 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 1 /* 1 USB high speed device */ +# define SAMV7_NUHPHS 1 /* 1 USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 0 /* No USB full speed device */ +# define SAMV7_NUHPFS 0 /* No USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +/* SAMV71J19 - 512 Kbytes FLASH / 256 Kbytes SRAM + * SAMV71J20 - 1024 Kbytes FLASH / 384 Kbytes SRAM + * SAMV71J21 - 2048 Kbytes FLASH / 384 Kbytes SRAM + * + * LQFP64, TFBGA64, and QFN64 packaging + */ + +#elif defined(CONFIG_ARCH_CHIP_SAMV71J19) || defined(CONFIG_ARCH_CHIP_SAMV71J20) || \ + defined(CONFIG_ARCH_CHIP_SAMV71J21) + +/* Internal memory */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71J19) +# define SAMV7_FLASH_SIZE (512*1024) /* 512KB */ +# define SAMV7_SRAM_SIZE (256*1024) /* 256KB */ +#elif defined(CONFIG_ARCH_CHIP_SAMV71J20) +# define SAMV7_FLASH_SIZE (1024*1024) /* 1024KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#else /* if defined(CONFIG_ARCH_CHIP_SAMV71J21) */ +# define SAMV7_FLASH_SIZE (2048*1024) /* 2048KB */ +# define SAMV7_SRAM_SIZE (384*1024) /* 384KB */ +#endif + +#define SAMV7_BSRAM_SIZE (1*1024) /* 1KB Backup SRAM */ + +/* Peripherals */ + +# define SAMV7_NPIO 5 /* 5 PIO ports A-E */ +# define SAMV7_NEBI 0 /* No External Bus Interface (EBI) */ +# define SAMV7_NSDRAMC 0 /* No SDRAM controller (SDRAMC) */ +# define SAMV7_NMLB 1 /* Have MediaLB interface (MLB) */ +# define SAMV7_NDMACHAN 24 /* 24 Central DMA Channels */ +# define SAMV7_NADC12 5 /* 5 12-bit ADC channels */ +# define SAMV7_NDAC12 1 /* 1 12-bit DAC channels */ +# define SAMV7_NTCCH 12 /* 12 Timer/counter channels */ +# define SAMV7_NTCCHIO 3 /* 3 Timer/counter channels I/O */ +# define SAMV7_NUSART 0 /* No USARTs */ +# define SAMV7_NUART 5 /* 5 UARTs */ +# define SAMV7_NQSPI 0 /* No Quad SPI */ +# define SAMV7_NSPI 1 /* 1 SPI, QSPI functions in SPI mode only */ +# define SAMV7_NTWIHS 2 /* 2 TWIHS */ +# define SAMV7_NHSMCI4 0 /* No 4-bit HSMCI port */ +# define SAMV7_NCAN 1 /* 1 CAN port */ +# define SAMV7_NEMAC 1 /* 1 Ethernet MAC (GMAC) */ +# define SAMV7_NEMACMII 0 /* No Ethernet MAC MII interface */ +# define SAMV7_NEMACRMII 1 /* 1 Ethernet MAC RMII interface */ +# define SAMV7_NISI12 0 /* No 12-bit ISI interface */ +# define SAMV7_NISI8 1 /* 1 8-bit ISI interface */ +# define SAMV7_NSSC 1 /* 1 SSC */ +# define SAMV7_NUDPHS 0 /* No USB high speed device */ +# define SAMV7_NUHPHS 0 /* No USB high speed embedded Mini-Host */ +# define SAMV7_NUDPFS 1 /* 1 USB full speed device */ +# define SAMV7_NUHPFS 1 /* 1 USB full speed embedded host */ +# define SAMV7_NACC 1 /* 1 Analog comparator */ +# define SAMV7_NETM 1 /* 1 Embedded Trace Macrocell (ETM) */ + +#else +# error "Unknown SAMV7 chip type" +#endif + +/* NVIC priority levels *************************************************************/ +/* Each priority field holds a priority value, 0-15. The lower the value, the greater + * the priority of the corresponding interrupt. The processor implements only + * bits[7:6] of each field, bits[5:0] read as zero and ignore writes. + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_SAMV7_CHIP_H */ diff --git a/arch/arm/include/samv7/irq.h b/arch/arm/include/samv7/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..4c33f3dbec0bb4b61b846958c7226f274b549b84 --- /dev/null +++ b/arch/arm/include/samv7/irq.h @@ -0,0 +1,116 @@ +/**************************************************************************************** + * arch/arm/include/samv7/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMV7_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMV7_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Common Processor Exceptions (vectors 0-15) */ + +#define SAM_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define SAM_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define SAM_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define SAM_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define SAM_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define SAM_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define SAM_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define SAM_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define SAM_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define SAM_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* Chip-Specific External interrupts */ + +#define SAM_IRQ_EXTINT (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71) +# include +#elif defined(CONFIG_ARCH_CHIP_SAME70) +# include +#else +# error Unrecognized SAMV7 architecture +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMV7_IRQ_H */ diff --git a/arch/arm/include/samv7/same70_irq.h b/arch/arm/include/samv7/same70_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..579e4b3158ecb7be82281cdf031d97c8e057e3c9 --- /dev/null +++ b/arch/arm/include/samv7/same70_irq.h @@ -0,0 +1,438 @@ +/**************************************************************************************** + * arch/arm/include/samv7/same70_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMV7_SAME70_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMV7_SAME70_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAMV71 Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EFC (6) /* Embedded Flash Controller */ +#define SAM_PID_UART0 (7) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_UART1 (8) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_PID_SMC (9) /* Static Memory Controller */ +#define SAM_PID_PIOA (10) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (11) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (12) /* Parallel I/O Controller C */ +#define SAM_PID_USART0 (13) /* USART 0 */ +#define SAM_PID_USART1 (14) /* USART 1 */ +#define SAM_PID_USART2 (15) /* USART 2 */ +#define SAM_PID_PIOD (16) /* Parallel I/O Controller D */ +#define SAM_PID_PIOE (17) /* Parallel I/O Controller E */ +#define SAM_PID_HSMCI0 (18) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWIHS0 (19) /* Two-Wire Interface 0 */ +#define SAM_PID_TWIHS1 (20) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (21) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SSC0 (22) /* Synchronous Serial Controller */ +#define SAM_PID_TC0 (23) /* Timer Counter 0 */ +#define SAM_PID_TC1 (24) /* Timer Counter 1 */ +#define SAM_PID_TC2 (25) /* Timer Counter 2 */ +#define SAM_PID_TC3 (26) /* Timer Counter 3 */ +#define SAM_PID_TC4 (27) /* Timer Counter 4 */ +#define SAM_PID_TC5 (28) /* Timer Counter 5 */ +#define SAM_PID_AFEC0 (29) /* Analog Front End 0 */ +#define SAM_PID_DACC (30) /* Digital to Analog Converter */ +#define SAM_PID_PWM0 (31) /* Pulse Width Modulation Controller 0 */ +#define SAM_PID_ICM (32) /* Integrity Check Monitor */ +#define SAM_PID_ACC (33) /* Analog Comparator */ +#define SAM_PID_USBHS (34) /* USB Host / Device Controller */ +#define SAM_PID_MCAN00 (35) /* CAN0 IRQ line 0 */ +#define SAM_PID_MCAN01 (36) /* CAN0 IRQ line 1 */ +#define SAM_PID_MCAN10 (37) /* CAN1 IRQ line 0 */ +#define SAM_PID_MCAN11 (38) /* CAN1 IRQ line 1 */ +#define SAM_PID_EMAC0 (39) /* Ethernet MAC */ +#define SAM_PID_AFEC1 (40) /* Analog Front End 1 */ +#define SAM_PID_TWIHS2 (41) /* Two-Wire Interface 2 */ +#define SAM_PID_SPI1 (42) /* Serial Peripheral Interface 1 */ +#define SAM_PID_QSPI (43) /* Quad I/O Serial Peripheral Interface */ +#define SAM_PID_UART2 (44) /* Universal Asynchronous Receiver Transmitter 2 */ +#define SAM_PID_UART3 (45) /* Universal Asynchronous Receiver Transmitter 3 */ +#define SAM_PID_UART4 (46) /* Universal Asynchronous Receiver Transmitter 4 */ +#define SAM_PID_TC6 (47) /* Timer Counter 6 */ +#define SAM_PID_TC7 (48) /* Timer Counter 7 */ +#define SAM_PID_TC8 (49) /* Timer Counter 8 */ +#define SAM_PID_TC9 (50) /* Timer Counter 9 */ +#define SAM_PID_TC10 (51) /* Timer Counter 10 */ +#define SAM_PID_TC11 (52) /* Timer Counter 11 */ +#define SAM_PID_RESERVED53 (53) /* Reserved */ +#define SAM_PID_RESERVED54 (54) /* Reserved */ +#define SAM_PID_RESERVED55 (55) /* Reserved */ +#define SAM_PID_AES (56) /* Advanced Encryption Standard */ +#define SAM_PID_TRNG (57) /* True Random Number Generator */ +#define SAM_PID_XDMAC (58) /* Central DMA Controller */ +#define SAM_PID_ISI (59) /* Image Sensor Interface */ +#define SAM_PID_PWM1 (60) /* Pulse Width Modulation Controller 1 */ +#define SAM_PID_FPU (61) /* ARM Floating Point Unit interrupt */ +#define SAM_PID_SDRAMC (62) /* SDRAM Controller */ +#define SAM_PID_RSWDT (63) /* Reinforced Safety Watchdog Timer */ +#define SAM_PID_CCW (64) /* ARM Cache ECC Warning */ +#define SAM_PID_CCF (65) /* ARM Cache ECC Fault */ +#define SAM_PID_EMACQ1 (66) /* EMAC Queue 1 Interrupt */ +#define SAM_PID_EMACQ2 (67) /* EMAC Queue 2 Interrupt */ +#define SAM_PID_FPIXC (68) /* ARM Cache ECC Warning */ + +#define NR_PIDS (69) /* Number of peripheral identifiers */ + +/* External interrupts (priority levels >= 256*/ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* Watchdog Timer */ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EFC) /* Embedded Flash Controller */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* Static Memory Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* Parallel I/O Controller C */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* USART 1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+SAM_PID_USART2) /* USART 2 */ +#define SAM_IRQ_PIOD (SAM_IRQ_EXTINT+SAM_PID_PIOD) /* Parallel I/O Controller D */ +#define SAM_IRQ_PIOE (SAM_IRQ_EXTINT+SAM_PID_PIOE) /* Parallel I/O Controller E */ +#define SAM_IRQ_HSMCI0 (SAM_IRQ_EXTINT+SAM_PID_HSMCI0) /* High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWIHS0 (SAM_IRQ_EXTINT+SAM_PID_TWIHS0) /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWIHS1 (SAM_IRQ_EXTINT+SAM_PID_TWIHS1) /* Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SSC0 (SAM_IRQ_EXTINT+SAM_PID_SSC0) /* Synchronous Serial Controller */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* Timer Counter 5 */ +#define SAM_IRQ_AFEC0 (SAM_IRQ_EXTINT+SAM_PID_AFEC0) /* Analog Front End 0 */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+SAM_PID_DACC) /* Digital to Analog Converter */ +#define SAM_IRQ_PWM0 (SAM_IRQ_EXTINT+SAM_PID_PWM0) /* Pulse Width Modulation Controller 0 */ +#define SAM_IRQ_ICM (SAM_IRQ_EXTINT+SAM_PID_ICM) /* Integrity Check Monitor */ +#define SAM_IRQ_ACC (SAM_IRQ_EXTINT+SAM_PID_ACC) /* Analog Comparator */ +#define SAM_IRQ_USBHS (SAM_IRQ_EXTINT+SAM_PID_USBHS) /* USB Host / Device Controller */ +#define SAM_IRQ_MCAN00 (SAM_IRQ_EXTINT+SAM_PID_MCAN00) /* CAN0 IRQ line 0 */ +#define SAM_IRQ_MCAN01 (SAM_IRQ_EXTINT+SAM_PID_MCAN01) /* CAN0 IRQ line 1 */ +#define SAM_IRQ_MCAN10 (SAM_IRQ_EXTINT+SAM_PID_MCAN10) /* CAN1 IRQ line 0 */ +#define SAM_IRQ_MCAN11 (SAM_IRQ_EXTINT+SAM_PID_MCAN11) /* CAN1 IRQ line 1 */ +#define SAM_IRQ_EMAC0 (SAM_IRQ_EXTINT+SAM_PID_EMAC0) /* Ethernet MAC */ +#define SAM_IRQ_AFEC1 (SAM_IRQ_EXTINT+SAM_PID_AFEC1) /* Analog Front End 1 */ +#define SAM_IRQ_TWIHS2 (SAM_IRQ_EXTINT+SAM_PID_TWIHS2) /* Two-Wire Interface 2 */ +#define SAM_IRQ_SPI1 (SAM_IRQ_EXTINT+SAM_PID_SPI1) /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_QSPI (SAM_IRQ_EXTINT+SAM_PID_QSPI) /* Quad I/O Serial Peripheral Interface */ +#define SAM_IRQ_UART2 (SAM_IRQ_EXTINT+SAM_PID_UART2) /* Universal Asynchronous Receiver Transmitter 2 */ +#define SAM_IRQ_UART3 (SAM_IRQ_EXTINT+SAM_PID_UART3) /* Universal Asynchronous Receiver Transmitter 3 */ +#define SAM_IRQ_UART4 (SAM_IRQ_EXTINT+SAM_PID_UART4) /* Universal Asynchronous Receiver Transmitter 4 */ +#define SAM_IRQ_TC6 (SAM_IRQ_EXTINT+SAM_PID_TC6) /* Timer Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_EXTINT+SAM_PID_TC7) /* Timer Counter 7 */ +#define SAM_IRQ_TC8 (SAM_IRQ_EXTINT+SAM_PID_TC8) /* Timer Counter 8 */ +#define SAM_IRQ_TC9 (SAM_IRQ_EXTINT+SAM_PID_TC9) /* Timer Counter 9 */ +#define SAM_IRQ_TC10 (SAM_IRQ_EXTINT+SAM_PID_TC10) /* Timer Counter 10 */ +#define SAM_IRQ_TC11 (SAM_IRQ_EXTINT+SAM_PID_TC11) /* Timer Counter 11 */ +#define SAM_IRQ_RESERVED53 (SAM_IRQ_EXTINT+SAM_PID_RESERVED53) /* Reserved */ +#define SAM_IRQ_RESERVED54 (SAM_IRQ_EXTINT+SAM_PID_RESERVED54) /* Reserved */ +#define SAM_IRQ_RESERVED55 (SAM_IRQ_EXTINT+SAM_PID_RESERVED55) /* Reserved */ +#define SAM_IRQ_AES (SAM_IRQ_EXTINT+SAM_PID_AES) /* AES */ +#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+SAM_PID_TRNG) /* True Random Number Generator */ +#define SAM_IRQ_XDMAC (SAM_IRQ_EXTINT+SAM_PID_XDMAC) /* Central DMA Controller */ +#define SAM_IRQ_ISI (SAM_IRQ_EXTINT+SAM_PID_ISI) /* Image Sensor Interface */ +#define SAM_IRQ_PWM1 (SAM_IRQ_EXTINT+SAM_PID_PWM1) /* Pulse Width Modulation Controller 1 */ +#define SAM_IRQ_FPU (SAM_IRQ_EXTINT+SAM_PID_FPU) /* ARM Floating Point Unit interrupt */ +#define SAM_IRQ_SDRAMC (SAM_IRQ_EXTINT+SAM_PID_SDRAMC) /* SDRAM Controller */ +#define SAM_IRQ_RSWDT (SAM_IRQ_EXTINT+SAM_PID_RSWDT) /* Reinforced Safety Watchdog Timer */ +#define SAM_IRQ_CCW (SAM_IRQ_EXTINT+SAM_PID_CCW) /* ARM Cache ECC Warning */ +#define SAM_IRQ_CCF (SAM_IRQ_EXTINT+SAM_PID_CCF) /* ARM Cache ECC Fault */ +#define SAM_IRQ_EMACQ1 (SAM_IRQ_EXTINT+SAM_PID_EMACQ1) /* EMAC Queue 1 Interrupt */ +#define SAM_IRQ_EMACQ2 (SAM_IRQ_EXTINT+SAM_PID_EMACQ2) /* EMAC Queue 2 Interrupt */ +#define SAM_IRQ_FPIXC (SAM_IRQ_EXTINTSAM_PID_FPIXC+) /* ARM Cache ECC Warning */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA..E) */ + +#ifdef CONFIG_SAMV7_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOD_IRQ +# define SAM_IRQ_GPIOD_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_GPIOD_PINS+0) /* GPIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_GPIOD_PINS+1) /* GPIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_GPIOD_PINS+2) /* GPIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_GPIOD_PINS+3) /* GPIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_GPIOD_PINS+4) /* GPIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_GPIOD_PINS+5) /* GPIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_GPIOD_PINS+6) /* GPIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_GPIOD_PINS+7) /* GPIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_GPIOD_PINS+8) /* GPIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_GPIOD_PINS+9) /* GPIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_GPIOD_PINS+10) /* GPIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_GPIOD_PINS+11) /* GPIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_GPIOD_PINS+12) /* GPIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_GPIOD_PINS+13) /* GPIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_GPIOD_PINS+14) /* GPIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_GPIOD_PINS+15) /* GPIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_GPIOD_PINS+16) /* GPIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_GPIOD_PINS+17) /* GPIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_GPIOD_PINS+18) /* GPIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_GPIOD_PINS+19) /* GPIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_GPIOD_PINS+20) /* GPIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_GPIOD_PINS+21) /* GPIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_GPIOD_PINS+22) /* GPIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_GPIOD_PINS+23) /* GPIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_GPIOD_PINS+24) /* GPIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_GPIOD_PINS+25) /* GPIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_GPIOD_PINS+26) /* GPIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_GPIOD_PINS+27) /* GPIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_GPIOD_PINS+28) /* GPIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_GPIOD_PINS+29) /* GPIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_GPIOD_PINS+30) /* GPIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_GPIOD_PINS+31) /* GPIOD, PIN 31 */ +# define SAM_NGPIODIRQS 32 +#else +# define SAM_NGPIODIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOE_IRQ +# define SAM_IRQ_GPIOE_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + SAM_NGPIODIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_GPIOE_PINS+0) /* GPIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_GPIOE_PINS+1) /* GPIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_GPIOE_PINS+2) /* GPIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_GPIOE_PINS+3) /* GPIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_GPIOE_PINS+4) /* GPIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_GPIOE_PINS+5) /* GPIOE, PIN 5 */ +# define SAM_IRQ_PE6 (SAM_IRQ_GPIOE_PINS+6) /* GPIOE, PIN 6 */ +# define SAM_IRQ_PE7 (SAM_IRQ_GPIOE_PINS+7) /* GPIOE, PIN 7 */ +# define SAM_IRQ_PE8 (SAM_IRQ_GPIOE_PINS+8) /* GPIOE, PIN 8 */ +# define SAM_IRQ_PE9 (SAM_IRQ_GPIOE_PINS+9) /* GPIOE, PIN 9 */ +# define SAM_IRQ_PE10 (SAM_IRQ_GPIOE_PINS+10) /* GPIOE, PIN 10 */ +# define SAM_IRQ_PE11 (SAM_IRQ_GPIOE_PINS+11) /* GPIOE, PIN 11 */ +# define SAM_IRQ_PE12 (SAM_IRQ_GPIOE_PINS+12) /* GPIOE, PIN 12 */ +# define SAM_IRQ_PE13 (SAM_IRQ_GPIOE_PINS+13) /* GPIOE, PIN 13 */ +# define SAM_IRQ_PE14 (SAM_IRQ_GPIOE_PINS+14) /* GPIOE, PIN 14 */ +# define SAM_IRQ_PE15 (SAM_IRQ_GPIOE_PINS+15) /* GPIOE, PIN 15 */ +# define SAM_IRQ_PE16 (SAM_IRQ_GPIOE_PINS+16) /* GPIOE, PIN 16 */ +# define SAM_IRQ_PE17 (SAM_IRQ_GPIOE_PINS+17) /* GPIOE, PIN 17 */ +# define SAM_IRQ_PE18 (SAM_IRQ_GPIOE_PINS+18) /* GPIOE, PIN 18 */ +# define SAM_IRQ_PE19 (SAM_IRQ_GPIOE_PINS+19) /* GPIOE, PIN 19 */ +# define SAM_IRQ_PE20 (SAM_IRQ_GPIOE_PINS+20) /* GPIOE, PIN 20 */ +# define SAM_IRQ_PE21 (SAM_IRQ_GPIOE_PINS+21) /* GPIOE, PIN 21 */ +# define SAM_IRQ_PE22 (SAM_IRQ_GPIOE_PINS+22) /* GPIOE, PIN 22 */ +# define SAM_IRQ_PE23 (SAM_IRQ_GPIOE_PINS+23) /* GPIOE, PIN 23 */ +# define SAM_IRQ_PE24 (SAM_IRQ_GPIOE_PINS+24) /* GPIOE, PIN 24 */ +# define SAM_IRQ_PE25 (SAM_IRQ_GPIOE_PINS+25) /* GPIOE, PIN 25 */ +# define SAM_IRQ_PE26 (SAM_IRQ_GPIOE_PINS+26) /* GPIOE, PIN 26 */ +# define SAM_IRQ_PE27 (SAM_IRQ_GPIOE_PINS+27) /* GPIOE, PIN 27 */ +# define SAM_IRQ_PE28 (SAM_IRQ_GPIOE_PINS+28) /* GPIOE, PIN 28 */ +# define SAM_IRQ_PE29 (SAM_IRQ_GPIOE_PINS+29) /* GPIOE, PIN 29 */ +# define SAM_IRQ_PE30 (SAM_IRQ_GPIOE_PINS+30) /* GPIOE, PIN 30 */ +# define SAM_IRQ_PE31 (SAM_IRQ_GPIOE_PINS+31) /* GPIOE, PIN 31 */ +# define SAM_NGPIOEIRQS 32 +#else +# define SAM_NGPIOEIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + \ + SAM_NGPIODIRQS + SAM_NGPIOEIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMV7_SAME70_IRQ_H */ diff --git a/arch/arm/include/samv7/samv71_irq.h b/arch/arm/include/samv7/samv71_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..4077e6fdd1f998f4bb28335cf3db4bee5600fad7 --- /dev/null +++ b/arch/arm/include/samv7/samv71_irq.h @@ -0,0 +1,438 @@ +/**************************************************************************************** + * arch/arm/include/samv7/samv71_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SAMV7_SAMV71_IRQ_H +#define __ARCH_ARM_INCLUDE_SAMV7_SAMV71_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SAMV71 Peripheral Identifiers */ + +#define SAM_PID_SUPC (0) /* Supply Controller */ +#define SAM_PID_RSTC (1) /* Reset Controller */ +#define SAM_PID_RTC (2) /* Real Time Clock */ +#define SAM_PID_RTT (3) /* Real Time Timer */ +#define SAM_PID_WDT (4) /* Watchdog Timer */ +#define SAM_PID_PMC (5) /* Power Management Controller */ +#define SAM_PID_EFC (6) /* Embedded Flash Controller */ +#define SAM_PID_UART0 (7) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_PID_UART1 (8) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_PID_SMC (9) /* Static Memory Controller */ +#define SAM_PID_PIOA (10) /* Parallel I/O Controller A */ +#define SAM_PID_PIOB (11) /* Parallel I/O Controller B */ +#define SAM_PID_PIOC (12) /* Parallel I/O Controller C */ +#define SAM_PID_USART0 (13) /* USART 0 */ +#define SAM_PID_USART1 (14) /* USART 1 */ +#define SAM_PID_USART2 (15) /* USART 2 */ +#define SAM_PID_PIOD (16) /* Parallel I/O Controller D */ +#define SAM_PID_PIOE (17) /* Parallel I/O Controller E */ +#define SAM_PID_HSMCI0 (18) /* High Speed Multimedia Card Interface */ +#define SAM_PID_TWIHS0 (19) /* Two-Wire Interface 0 */ +#define SAM_PID_TWIHS1 (20) /* Two-Wire Interface 1 */ +#define SAM_PID_SPI0 (21) /* Serial Peripheral Interface 0 */ +#define SAM_PID_SSC0 (22) /* Synchronous Serial Controller */ +#define SAM_PID_TC0 (23) /* Timer Counter 0 */ +#define SAM_PID_TC1 (24) /* Timer Counter 1 */ +#define SAM_PID_TC2 (25) /* Timer Counter 2 */ +#define SAM_PID_TC3 (26) /* Timer Counter 3 */ +#define SAM_PID_TC4 (27) /* Timer Counter 4 */ +#define SAM_PID_TC5 (28) /* Timer Counter 5 */ +#define SAM_PID_AFEC0 (29) /* Analog Front End 0 */ +#define SAM_PID_DACC (30) /* Digital to Analog Converter */ +#define SAM_PID_PWM0 (31) /* Pulse Width Modulation Controller 0 */ +#define SAM_PID_ICM (32) /* Integrity Check Monitor */ +#define SAM_PID_ACC (33) /* Analog Comparator */ +#define SAM_PID_USBHS (34) /* USB Host / Device Controller */ +#define SAM_PID_MCAN00 (35) /* CAN0 IRQ line 0 */ +#define SAM_PID_MCAN01 (36) /* CAN0 IRQ line 1 */ +#define SAM_PID_MCAN10 (37) /* CAN1 IRQ line 0 */ +#define SAM_PID_MCAN11 (38) /* CAN1 IRQ line 1 */ +#define SAM_PID_EMAC0 (39) /* Ethernet MAC */ +#define SAM_PID_AFEC1 (40) /* Analog Front End 1 */ +#define SAM_PID_TWIHS2 (41) /* Two-Wire Interface 2 */ +#define SAM_PID_SPI1 (42) /* Serial Peripheral Interface 1 */ +#define SAM_PID_QSPI (43) /* Quad I/O Serial Peripheral Interface */ +#define SAM_PID_UART2 (44) /* Universal Asynchronous Receiver Transmitter 2 */ +#define SAM_PID_UART3 (45) /* Universal Asynchronous Receiver Transmitter 3 */ +#define SAM_PID_UART4 (46) /* Universal Asynchronous Receiver Transmitter 4 */ +#define SAM_PID_TC6 (47) /* Timer Counter 6 */ +#define SAM_PID_TC7 (48) /* Timer Counter 7 */ +#define SAM_PID_TC8 (49) /* Timer Counter 8 */ +#define SAM_PID_TC9 (50) /* Timer Counter 9 */ +#define SAM_PID_TC10 (51) /* Timer Counter 10 */ +#define SAM_PID_TC11 (52) /* Timer Counter 11 */ +#define SAM_PID_MLB0 (53) /* MediaLB IRQ 0 */ +#define SAM_PID_MLB1 (54) /* MediaLB IRQ 1 */ +#define SAM_PID_RESERVED55 (55) /* Reserved */ +#define SAM_PID_AES (56) /* Advanced Encryption Standard */ +#define SAM_PID_TRNG (57) /* True Random Number Generator */ +#define SAM_PID_XDMAC (58) /* Central DMA Controller */ +#define SAM_PID_ISI (59) /* Image Sensor Interface */ +#define SAM_PID_PWM1 (60) /* Pulse Width Modulation Controller 1 */ +#define SAM_PID_FPU (61) /* ARM Floating Point Unit interrupt */ +#define SAM_PID_SDRAMC (62) /* SDRAM Controller */ +#define SAM_PID_RSWDT (63) /* Reinforced Safetry Watchdog Timer */ +#define SAM_PID_CCW (64) /* ARM Cache ECC Warning */ +#define SAM_PID_CCF (65) /* ARM Cache ECC Fault */ +#define SAM_PID_EMACQ1 (66) /* EMAC Queue 1 Interrupt */ +#define SAM_PID_EMACQ2 (67) /* EMAC Queue 2 Interrupt */ +#define SAM_PID_FPIXC (68) /* ARM Cache ECC Warning */ + +#define NR_PIDS (69) /* Number of peripheral identifiers */ + +/* External interrupts (priority levels >= 256*/ + +#define SAM_IRQ_SUPC (SAM_IRQ_EXTINT+SAM_PID_SUPC) /* Supply Controller */ +#define SAM_IRQ_RSTC (SAM_IRQ_EXTINT+SAM_PID_RSTC) /* Reset Controller */ +#define SAM_IRQ_RTC (SAM_IRQ_EXTINT+SAM_PID_RTC) /* Real Time Clock */ +#define SAM_IRQ_RTT (SAM_IRQ_EXTINT+SAM_PID_RTT) /* Real Time Timer */ +#define SAM_IRQ_WDT (SAM_IRQ_EXTINT+SAM_PID_WDT) /* Watchdog Timer*/ +#define SAM_IRQ_PMC (SAM_IRQ_EXTINT+SAM_PID_PMC) /* Power Management Controller */ +#define SAM_IRQ_EEFC0 (SAM_IRQ_EXTINT+SAM_PID_EFC) /* Embedded Flash Controller */ +#define SAM_IRQ_UART0 (SAM_IRQ_EXTINT+SAM_PID_UART0) /* Universal Asynchronous Receiver Transmitter 0 */ +#define SAM_IRQ_UART1 (SAM_IRQ_EXTINT+SAM_PID_UART1) /* Universal Asynchronous Receiver Transmitter 1 */ +#define SAM_IRQ_SMC (SAM_IRQ_EXTINT+SAM_PID_SMC) /* Static Memory Controller */ +#define SAM_IRQ_PIOA (SAM_IRQ_EXTINT+SAM_PID_PIOA) /* Parallel I/O Controller A */ +#define SAM_IRQ_PIOB (SAM_IRQ_EXTINT+SAM_PID_PIOB) /* Parallel I/O Controller B */ +#define SAM_IRQ_PIOC (SAM_IRQ_EXTINT+SAM_PID_PIOC) /* Parallel I/O Controller C */ +#define SAM_IRQ_USART0 (SAM_IRQ_EXTINT+SAM_PID_USART0) /* USART 0 */ +#define SAM_IRQ_USART1 (SAM_IRQ_EXTINT+SAM_PID_USART1) /* USART 1 */ +#define SAM_IRQ_USART2 (SAM_IRQ_EXTINT+SAM_PID_USART2) /* USART 2 */ +#define SAM_IRQ_PIOD (SAM_IRQ_EXTINT+SAM_PID_PIOD) /* Parallel I/O Controller D */ +#define SAM_IRQ_PIOE (SAM_IRQ_EXTINT+SAM_PID_PIOE) /* Parallel I/O Controller E */ +#define SAM_IRQ_HSMCI0 (SAM_IRQ_EXTINT+SAM_PID_HSMCI0) /* High Speed Multimedia Card Interface */ +#define SAM_IRQ_TWIHS0 (SAM_IRQ_EXTINT+SAM_PID_TWIHS0) /* Two-Wire Interface 0 */ +#define SAM_IRQ_TWIHS1 (SAM_IRQ_EXTINT+SAM_PID_TWIHS1) /* Two-Wire Interface 1 */ +#define SAM_IRQ_SPI0 (SAM_IRQ_EXTINT+SAM_PID_SPI0) /* Serial Peripheral Interface 0 */ +#define SAM_IRQ_SSC0 (SAM_IRQ_EXTINT+SAM_PID_SSC0) /* Synchronous Serial Controller */ +#define SAM_IRQ_TC0 (SAM_IRQ_EXTINT+SAM_PID_TC0) /* Timer Counter 0 */ +#define SAM_IRQ_TC1 (SAM_IRQ_EXTINT+SAM_PID_TC1) /* Timer Counter 1 */ +#define SAM_IRQ_TC2 (SAM_IRQ_EXTINT+SAM_PID_TC2) /* Timer Counter 2 */ +#define SAM_IRQ_TC3 (SAM_IRQ_EXTINT+SAM_PID_TC3) /* Timer Counter 3 */ +#define SAM_IRQ_TC4 (SAM_IRQ_EXTINT+SAM_PID_TC4) /* Timer Counter 4 */ +#define SAM_IRQ_TC5 (SAM_IRQ_EXTINT+SAM_PID_TC5) /* Timer Counter 5 */ +#define SAM_IRQ_AFEC0 (SAM_IRQ_EXTINT+SAM_PID_AFEC0) /* Analog Front End 0 */ +#define SAM_IRQ_DACC (SAM_IRQ_EXTINT+SAM_PID_DACC) /* Digital to Analog Converter */ +#define SAM_IRQ_PWM0 (SAM_IRQ_EXTINT+SAM_PID_PWM0) /* Pulse Width Modulation Controller 0 */ +#define SAM_IRQ_ICM (SAM_IRQ_EXTINT+SAM_PID_ICM) /* Integrity Check Monitor */ +#define SAM_IRQ_ACC (SAM_IRQ_EXTINT+SAM_PID_ACC) /* Analog Comparator */ +#define SAM_IRQ_USBHS (SAM_IRQ_EXTINT+SAM_PID_USBHS) /* USB Host / Device Controller */ +#define SAM_IRQ_MCAN00 (SAM_IRQ_EXTINT+SAM_PID_MCAN00) /* CAN0 IRQ line 0 */ +#define SAM_IRQ_MCAN01 (SAM_IRQ_EXTINT+SAM_PID_MCAN01) /* CAN0 IRQ line 1 */ +#define SAM_IRQ_MCAN10 (SAM_IRQ_EXTINT+SAM_PID_MCAN10) /* CAN1 IRQ line 0 */ +#define SAM_IRQ_MCAN11 (SAM_IRQ_EXTINT+SAM_PID_MCAN11) /* CAN1 IRQ line 1 */ +#define SAM_IRQ_EMAC0 (SAM_IRQ_EXTINT+SAM_PID_EMAC0) /* Ethernet MAC */ +#define SAM_IRQ_AFEC1 (SAM_IRQ_EXTINT+SAM_PID_AFEC1) /* Analog Front End 1 */ +#define SAM_IRQ_TWIHS2 (SAM_IRQ_EXTINT+SAM_PID_TWIHS2) /* Two-Wire Interface 2 */ +#define SAM_IRQ_SPI1 (SAM_IRQ_EXTINT+SAM_PID_SPI1) /* Serial Peripheral Interface 1 */ +#define SAM_IRQ_QSPI (SAM_IRQ_EXTINT+SAM_PID_QSPI) /* Quad I/O Serial Peripheral Interface */ +#define SAM_IRQ_UART2 (SAM_IRQ_EXTINT+SAM_PID_UART2) /* Universal Asynchronous Receiver Transmitter 2 */ +#define SAM_IRQ_UART3 (SAM_IRQ_EXTINT+SAM_PID_UART3) /* Universal Asynchronous Receiver Transmitter 3 */ +#define SAM_IRQ_UART4 (SAM_IRQ_EXTINT+SAM_PID_UART4) /* Universal Asynchronous Receiver Transmitter 4 */ +#define SAM_IRQ_TC6 (SAM_IRQ_EXTINT+SAM_PID_TC6) /* Timer Counter 6 */ +#define SAM_IRQ_TC7 (SAM_IRQ_EXTINT+SAM_PID_TC7) /* Timer Counter 7 */ +#define SAM_IRQ_TC8 (SAM_IRQ_EXTINT+SAM_PID_TC8) /* Timer Counter 8 */ +#define SAM_IRQ_TC9 (SAM_IRQ_EXTINT+SAM_PID_TC9) /* Timer Counter 9 */ +#define SAM_IRQ_TC10 (SAM_IRQ_EXTINT+SAM_PID_TC10) /* Timer Counter 10 */ +#define SAM_IRQ_TC11 (SAM_IRQ_EXTINT+SAM_PID_TC11) /* Timer Counter 11 */ +#define SAM_IRQ_MLB0 (SAM_IRQ_EXTINT+SAM_PID_MLB0) /* MediaLB IRQ 0 */ +#define SAM_IRQ_MLB1 (SAM_IRQ_EXTINT+SAM_PID_MLB1) /* MediaLB IRQ 1 */ +#define SAM_IRQ_RESERVED55 (SAM_IRQ_EXTINT+SAM_PID_RESERVED55) /* Reserved */ +#define SAM_IRQ_AES (SAM_IRQ_EXTINT+SAM_PID_AES) /* AES */ +#define SAM_IRQ_TRNG (SAM_IRQ_EXTINT+SAM_PID_TRNG) /* True Random Number Generator */ +#define SAM_IRQ_XDMAC (SAM_IRQ_EXTINT+SAM_PID_XDMAC) /* Central DMA Controller */ +#define SAM_IRQ_ISI (SAM_IRQ_EXTINT+SAM_PID_ISI) /* Image Sensor Interface */ +#define SAM_IRQ_PWM1 (SAM_IRQ_EXTINT+SAM_PID_PWM1) /* Pulse Width Modulation Controller 1 */ +#define SAM_IRQ_FPU (SAM_IRQ_EXTINT+SAM_PID_FPU) /* ARM Floating Point Unit interrupt */ +#define SAM_IRQ_SDRAMC (SAM_IRQ_EXTINT+SAM_PID_SDRAMC) /* SDRAM Controller */ +#define SAM_IRQ_RSWDT (SAM_IRQ_EXTINT+SAM_PID_RSWDT) /* Reinforced Safety Watchdog Timer */ +#define SAM_IRQ_CCW (SAM_IRQ_EXTINT+SAM_PID_CCW) /* ARM Cache ECC Warning */ +#define SAM_IRQ_CCF (SAM_IRQ_EXTINT+SAM_PID_CCF) /* ARM Cache ECC Fault */ +#define SAM_IRQ_EMACQ1 (SAM_IRQ_EXTINT+SAM_PID_EMACQ1) /* EMAC Queue 1 Interrupt */ +#define SAM_IRQ_EMACQ2 (SAM_IRQ_EXTINT+SAM_PID_EMACQ2) /* EMAC Queue 2 Interrupt */ +#define SAM_IRQ_FPIXC (SAM_IRQ_EXTINTSAM_PID_FPIXC+) /* ARM Cache ECC Warning */ + +#define SAM_IRQ_NEXTINT NR_PIDS /* Total number of external interrupt numbers */ +#define SAM_IRQ_NIRQS (SAM_IRQ_EXTINT+NR_PIDS) /* The number of real IRQs */ + +/* GPIO interrupts (derived from SAM_IRQ_PIOA..E) */ + +#ifdef CONFIG_SAMV7_GPIOA_IRQ +# define SAM_IRQ_GPIOA_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT) +# define SAM_IRQ_PA0 (SAM_IRQ_GPIOA_PINS+0) /* GPIOA, PIN 0 */ +# define SAM_IRQ_PA1 (SAM_IRQ_GPIOA_PINS+1) /* GPIOA, PIN 1 */ +# define SAM_IRQ_PA2 (SAM_IRQ_GPIOA_PINS+2) /* GPIOA, PIN 2 */ +# define SAM_IRQ_PA3 (SAM_IRQ_GPIOA_PINS+3) /* GPIOA, PIN 3 */ +# define SAM_IRQ_PA4 (SAM_IRQ_GPIOA_PINS+4) /* GPIOA, PIN 4 */ +# define SAM_IRQ_PA5 (SAM_IRQ_GPIOA_PINS+5) /* GPIOA, PIN 5 */ +# define SAM_IRQ_PA6 (SAM_IRQ_GPIOA_PINS+6) /* GPIOA, PIN 6 */ +# define SAM_IRQ_PA7 (SAM_IRQ_GPIOA_PINS+7) /* GPIOA, PIN 7 */ +# define SAM_IRQ_PA8 (SAM_IRQ_GPIOA_PINS+8) /* GPIOA, PIN 8 */ +# define SAM_IRQ_PA9 (SAM_IRQ_GPIOA_PINS+9) /* GPIOA, PIN 9 */ +# define SAM_IRQ_PA10 (SAM_IRQ_GPIOA_PINS+10) /* GPIOA, PIN 10 */ +# define SAM_IRQ_PA11 (SAM_IRQ_GPIOA_PINS+11) /* GPIOA, PIN 11 */ +# define SAM_IRQ_PA12 (SAM_IRQ_GPIOA_PINS+12) /* GPIOA, PIN 12 */ +# define SAM_IRQ_PA13 (SAM_IRQ_GPIOA_PINS+13) /* GPIOA, PIN 13 */ +# define SAM_IRQ_PA14 (SAM_IRQ_GPIOA_PINS+14) /* GPIOA, PIN 14 */ +# define SAM_IRQ_PA15 (SAM_IRQ_GPIOA_PINS+15) /* GPIOA, PIN 15 */ +# define SAM_IRQ_PA16 (SAM_IRQ_GPIOA_PINS+16) /* GPIOA, PIN 16 */ +# define SAM_IRQ_PA17 (SAM_IRQ_GPIOA_PINS+17) /* GPIOA, PIN 17 */ +# define SAM_IRQ_PA18 (SAM_IRQ_GPIOA_PINS+18) /* GPIOA, PIN 18 */ +# define SAM_IRQ_PA19 (SAM_IRQ_GPIOA_PINS+19) /* GPIOA, PIN 19 */ +# define SAM_IRQ_PA20 (SAM_IRQ_GPIOA_PINS+20) /* GPIOA, PIN 20 */ +# define SAM_IRQ_PA21 (SAM_IRQ_GPIOA_PINS+21) /* GPIOA, PIN 21 */ +# define SAM_IRQ_PA22 (SAM_IRQ_GPIOA_PINS+22) /* GPIOA, PIN 22 */ +# define SAM_IRQ_PA23 (SAM_IRQ_GPIOA_PINS+23) /* GPIOA, PIN 23 */ +# define SAM_IRQ_PA24 (SAM_IRQ_GPIOA_PINS+24) /* GPIOA, PIN 24 */ +# define SAM_IRQ_PA25 (SAM_IRQ_GPIOA_PINS+25) /* GPIOA, PIN 25 */ +# define SAM_IRQ_PA26 (SAM_IRQ_GPIOA_PINS+26) /* GPIOA, PIN 26 */ +# define SAM_IRQ_PA27 (SAM_IRQ_GPIOA_PINS+27) /* GPIOA, PIN 27 */ +# define SAM_IRQ_PA28 (SAM_IRQ_GPIOA_PINS+28) /* GPIOA, PIN 28 */ +# define SAM_IRQ_PA29 (SAM_IRQ_GPIOA_PINS+29) /* GPIOA, PIN 29 */ +# define SAM_IRQ_PA30 (SAM_IRQ_GPIOA_PINS+30) /* GPIOA, PIN 30 */ +# define SAM_IRQ_PA31 (SAM_IRQ_GPIOA_PINS+31) /* GPIOA, PIN 31 */ +# define SAM_NGPIOAIRQS 32 +#else +# define SAM_NGPIOAIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOB_IRQ +# define SAM_IRQ_GPIOB_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS) +# define SAM_IRQ_PB0 (SAM_IRQ_GPIOB_PINS+0) /* GPIOB, PIN 0 */ +# define SAM_IRQ_PB1 (SAM_IRQ_GPIOB_PINS+1) /* GPIOB, PIN 1 */ +# define SAM_IRQ_PB2 (SAM_IRQ_GPIOB_PINS+2) /* GPIOB, PIN 2 */ +# define SAM_IRQ_PB3 (SAM_IRQ_GPIOB_PINS+3) /* GPIOB, PIN 3 */ +# define SAM_IRQ_PB4 (SAM_IRQ_GPIOB_PINS+4) /* GPIOB, PIN 4 */ +# define SAM_IRQ_PB5 (SAM_IRQ_GPIOB_PINS+5) /* GPIOB, PIN 5 */ +# define SAM_IRQ_PB6 (SAM_IRQ_GPIOB_PINS+6) /* GPIOB, PIN 6 */ +# define SAM_IRQ_PB7 (SAM_IRQ_GPIOB_PINS+7) /* GPIOB, PIN 7 */ +# define SAM_IRQ_PB8 (SAM_IRQ_GPIOB_PINS+8) /* GPIOB, PIN 8 */ +# define SAM_IRQ_PB9 (SAM_IRQ_GPIOB_PINS+9) /* GPIOB, PIN 9 */ +# define SAM_IRQ_PB10 (SAM_IRQ_GPIOB_PINS+10) /* GPIOB, PIN 10 */ +# define SAM_IRQ_PB11 (SAM_IRQ_GPIOB_PINS+11) /* GPIOB, PIN 11 */ +# define SAM_IRQ_PB12 (SAM_IRQ_GPIOB_PINS+12) /* GPIOB, PIN 12 */ +# define SAM_IRQ_PB13 (SAM_IRQ_GPIOB_PINS+13) /* GPIOB, PIN 13 */ +# define SAM_IRQ_PB14 (SAM_IRQ_GPIOB_PINS+14) /* GPIOB, PIN 14 */ +# define SAM_IRQ_PB15 (SAM_IRQ_GPIOB_PINS+15) /* GPIOB, PIN 15 */ +# define SAM_IRQ_PB16 (SAM_IRQ_GPIOB_PINS+16) /* GPIOB, PIN 16 */ +# define SAM_IRQ_PB17 (SAM_IRQ_GPIOB_PINS+17) /* GPIOB, PIN 17 */ +# define SAM_IRQ_PB18 (SAM_IRQ_GPIOB_PINS+18) /* GPIOB, PIN 18 */ +# define SAM_IRQ_PB19 (SAM_IRQ_GPIOB_PINS+19) /* GPIOB, PIN 19 */ +# define SAM_IRQ_PB20 (SAM_IRQ_GPIOB_PINS+20) /* GPIOB, PIN 20 */ +# define SAM_IRQ_PB21 (SAM_IRQ_GPIOB_PINS+21) /* GPIOB, PIN 21 */ +# define SAM_IRQ_PB22 (SAM_IRQ_GPIOB_PINS+22) /* GPIOB, PIN 22 */ +# define SAM_IRQ_PB23 (SAM_IRQ_GPIOB_PINS+23) /* GPIOB, PIN 23 */ +# define SAM_IRQ_PB24 (SAM_IRQ_GPIOB_PINS+24) /* GPIOB, PIN 24 */ +# define SAM_IRQ_PB25 (SAM_IRQ_GPIOB_PINS+25) /* GPIOB, PIN 25 */ +# define SAM_IRQ_PB26 (SAM_IRQ_GPIOB_PINS+26) /* GPIOB, PIN 26 */ +# define SAM_IRQ_PB27 (SAM_IRQ_GPIOB_PINS+27) /* GPIOB, PIN 27 */ +# define SAM_IRQ_PB28 (SAM_IRQ_GPIOB_PINS+28) /* GPIOB, PIN 28 */ +# define SAM_IRQ_PB29 (SAM_IRQ_GPIOB_PINS+29) /* GPIOB, PIN 29 */ +# define SAM_IRQ_PB30 (SAM_IRQ_GPIOB_PINS+30) /* GPIOB, PIN 30 */ +# define SAM_IRQ_PB31 (SAM_IRQ_GPIOB_PINS+31) /* GPIOB, PIN 31 */ +# define SAM_NGPIOBIRQS 32 +#else +# define SAM_NGPIOBIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOC_IRQ +# define SAM_IRQ_GPIOC_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS) +# define SAM_IRQ_PC0 (SAM_IRQ_GPIOC_PINS+0) /* GPIOC, PIN 0 */ +# define SAM_IRQ_PC1 (SAM_IRQ_GPIOC_PINS+1) /* GPIOC, PIN 1 */ +# define SAM_IRQ_PC2 (SAM_IRQ_GPIOC_PINS+2) /* GPIOC, PIN 2 */ +# define SAM_IRQ_PC3 (SAM_IRQ_GPIOC_PINS+3) /* GPIOC, PIN 3 */ +# define SAM_IRQ_PC4 (SAM_IRQ_GPIOC_PINS+4) /* GPIOC, PIN 4 */ +# define SAM_IRQ_PC5 (SAM_IRQ_GPIOC_PINS+5) /* GPIOC, PIN 5 */ +# define SAM_IRQ_PC6 (SAM_IRQ_GPIOC_PINS+6) /* GPIOC, PIN 6 */ +# define SAM_IRQ_PC7 (SAM_IRQ_GPIOC_PINS+7) /* GPIOC, PIN 7 */ +# define SAM_IRQ_PC8 (SAM_IRQ_GPIOC_PINS+8) /* GPIOC, PIN 8 */ +# define SAM_IRQ_PC9 (SAM_IRQ_GPIOC_PINS+9) /* GPIOC, PIN 9 */ +# define SAM_IRQ_PC10 (SAM_IRQ_GPIOC_PINS+10) /* GPIOC, PIN 10 */ +# define SAM_IRQ_PC11 (SAM_IRQ_GPIOC_PINS+11) /* GPIOC, PIN 11 */ +# define SAM_IRQ_PC12 (SAM_IRQ_GPIOC_PINS+12) /* GPIOC, PIN 12 */ +# define SAM_IRQ_PC13 (SAM_IRQ_GPIOC_PINS+13) /* GPIOC, PIN 13 */ +# define SAM_IRQ_PC14 (SAM_IRQ_GPIOC_PINS+14) /* GPIOC, PIN 14 */ +# define SAM_IRQ_PC15 (SAM_IRQ_GPIOC_PINS+15) /* GPIOC, PIN 15 */ +# define SAM_IRQ_PC16 (SAM_IRQ_GPIOC_PINS+16) /* GPIOC, PIN 16 */ +# define SAM_IRQ_PC17 (SAM_IRQ_GPIOC_PINS+17) /* GPIOC, PIN 17 */ +# define SAM_IRQ_PC18 (SAM_IRQ_GPIOC_PINS+18) /* GPIOC, PIN 18 */ +# define SAM_IRQ_PC19 (SAM_IRQ_GPIOC_PINS+19) /* GPIOC, PIN 19 */ +# define SAM_IRQ_PC20 (SAM_IRQ_GPIOC_PINS+20) /* GPIOC, PIN 20 */ +# define SAM_IRQ_PC21 (SAM_IRQ_GPIOC_PINS+21) /* GPIOC, PIN 21 */ +# define SAM_IRQ_PC22 (SAM_IRQ_GPIOC_PINS+22) /* GPIOC, PIN 22 */ +# define SAM_IRQ_PC23 (SAM_IRQ_GPIOC_PINS+23) /* GPIOC, PIN 23 */ +# define SAM_IRQ_PC24 (SAM_IRQ_GPIOC_PINS+24) /* GPIOC, PIN 24 */ +# define SAM_IRQ_PC25 (SAM_IRQ_GPIOC_PINS+25) /* GPIOC, PIN 25 */ +# define SAM_IRQ_PC26 (SAM_IRQ_GPIOC_PINS+26) /* GPIOC, PIN 26 */ +# define SAM_IRQ_PC27 (SAM_IRQ_GPIOC_PINS+27) /* GPIOC, PIN 27 */ +# define SAM_IRQ_PC28 (SAM_IRQ_GPIOC_PINS+28) /* GPIOC, PIN 28 */ +# define SAM_IRQ_PC29 (SAM_IRQ_GPIOC_PINS+29) /* GPIOC, PIN 29 */ +# define SAM_IRQ_PC30 (SAM_IRQ_GPIOC_PINS+30) /* GPIOC, PIN 30 */ +# define SAM_IRQ_PC31 (SAM_IRQ_GPIOC_PINS+31) /* GPIOC, PIN 31 */ +# define SAM_NGPIOCIRQS 32 +#else +# define SAM_NGPIOCIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOD_IRQ +# define SAM_IRQ_GPIOD_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS) +# define SAM_IRQ_PD0 (SAM_IRQ_GPIOD_PINS+0) /* GPIOD, PIN 0 */ +# define SAM_IRQ_PD1 (SAM_IRQ_GPIOD_PINS+1) /* GPIOD, PIN 1 */ +# define SAM_IRQ_PD2 (SAM_IRQ_GPIOD_PINS+2) /* GPIOD, PIN 2 */ +# define SAM_IRQ_PD3 (SAM_IRQ_GPIOD_PINS+3) /* GPIOD, PIN 3 */ +# define SAM_IRQ_PD4 (SAM_IRQ_GPIOD_PINS+4) /* GPIOD, PIN 4 */ +# define SAM_IRQ_PD5 (SAM_IRQ_GPIOD_PINS+5) /* GPIOD, PIN 5 */ +# define SAM_IRQ_PD6 (SAM_IRQ_GPIOD_PINS+6) /* GPIOD, PIN 6 */ +# define SAM_IRQ_PD7 (SAM_IRQ_GPIOD_PINS+7) /* GPIOD, PIN 7 */ +# define SAM_IRQ_PD8 (SAM_IRQ_GPIOD_PINS+8) /* GPIOD, PIN 8 */ +# define SAM_IRQ_PD9 (SAM_IRQ_GPIOD_PINS+9) /* GPIOD, PIN 9 */ +# define SAM_IRQ_PD10 (SAM_IRQ_GPIOD_PINS+10) /* GPIOD, PIN 10 */ +# define SAM_IRQ_PD11 (SAM_IRQ_GPIOD_PINS+11) /* GPIOD, PIN 11 */ +# define SAM_IRQ_PD12 (SAM_IRQ_GPIOD_PINS+12) /* GPIOD, PIN 12 */ +# define SAM_IRQ_PD13 (SAM_IRQ_GPIOD_PINS+13) /* GPIOD, PIN 13 */ +# define SAM_IRQ_PD14 (SAM_IRQ_GPIOD_PINS+14) /* GPIOD, PIN 14 */ +# define SAM_IRQ_PD15 (SAM_IRQ_GPIOD_PINS+15) /* GPIOD, PIN 15 */ +# define SAM_IRQ_PD16 (SAM_IRQ_GPIOD_PINS+16) /* GPIOD, PIN 16 */ +# define SAM_IRQ_PD17 (SAM_IRQ_GPIOD_PINS+17) /* GPIOD, PIN 17 */ +# define SAM_IRQ_PD18 (SAM_IRQ_GPIOD_PINS+18) /* GPIOD, PIN 18 */ +# define SAM_IRQ_PD19 (SAM_IRQ_GPIOD_PINS+19) /* GPIOD, PIN 19 */ +# define SAM_IRQ_PD20 (SAM_IRQ_GPIOD_PINS+20) /* GPIOD, PIN 20 */ +# define SAM_IRQ_PD21 (SAM_IRQ_GPIOD_PINS+21) /* GPIOD, PIN 21 */ +# define SAM_IRQ_PD22 (SAM_IRQ_GPIOD_PINS+22) /* GPIOD, PIN 22 */ +# define SAM_IRQ_PD23 (SAM_IRQ_GPIOD_PINS+23) /* GPIOD, PIN 23 */ +# define SAM_IRQ_PD24 (SAM_IRQ_GPIOD_PINS+24) /* GPIOD, PIN 24 */ +# define SAM_IRQ_PD25 (SAM_IRQ_GPIOD_PINS+25) /* GPIOD, PIN 25 */ +# define SAM_IRQ_PD26 (SAM_IRQ_GPIOD_PINS+26) /* GPIOD, PIN 26 */ +# define SAM_IRQ_PD27 (SAM_IRQ_GPIOD_PINS+27) /* GPIOD, PIN 27 */ +# define SAM_IRQ_PD28 (SAM_IRQ_GPIOD_PINS+28) /* GPIOD, PIN 28 */ +# define SAM_IRQ_PD29 (SAM_IRQ_GPIOD_PINS+29) /* GPIOD, PIN 29 */ +# define SAM_IRQ_PD30 (SAM_IRQ_GPIOD_PINS+30) /* GPIOD, PIN 30 */ +# define SAM_IRQ_PD31 (SAM_IRQ_GPIOD_PINS+31) /* GPIOD, PIN 31 */ +# define SAM_NGPIODIRQS 32 +#else +# define SAM_NGPIODIRQS 0 +#endif + +#ifdef CONFIG_SAMV7_GPIOE_IRQ +# define SAM_IRQ_GPIOE_PINS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + SAM_NGPIOAIRQS + \ + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + SAM_NGPIODIRQS) +# define SAM_IRQ_PE0 (SAM_IRQ_GPIOE_PINS+0) /* GPIOE, PIN 0 */ +# define SAM_IRQ_PE1 (SAM_IRQ_GPIOE_PINS+1) /* GPIOE, PIN 1 */ +# define SAM_IRQ_PE2 (SAM_IRQ_GPIOE_PINS+2) /* GPIOE, PIN 2 */ +# define SAM_IRQ_PE3 (SAM_IRQ_GPIOE_PINS+3) /* GPIOE, PIN 3 */ +# define SAM_IRQ_PE4 (SAM_IRQ_GPIOE_PINS+4) /* GPIOE, PIN 4 */ +# define SAM_IRQ_PE5 (SAM_IRQ_GPIOE_PINS+5) /* GPIOE, PIN 5 */ +# define SAM_IRQ_PE6 (SAM_IRQ_GPIOE_PINS+6) /* GPIOE, PIN 6 */ +# define SAM_IRQ_PE7 (SAM_IRQ_GPIOE_PINS+7) /* GPIOE, PIN 7 */ +# define SAM_IRQ_PE8 (SAM_IRQ_GPIOE_PINS+8) /* GPIOE, PIN 8 */ +# define SAM_IRQ_PE9 (SAM_IRQ_GPIOE_PINS+9) /* GPIOE, PIN 9 */ +# define SAM_IRQ_PE10 (SAM_IRQ_GPIOE_PINS+10) /* GPIOE, PIN 10 */ +# define SAM_IRQ_PE11 (SAM_IRQ_GPIOE_PINS+11) /* GPIOE, PIN 11 */ +# define SAM_IRQ_PE12 (SAM_IRQ_GPIOE_PINS+12) /* GPIOE, PIN 12 */ +# define SAM_IRQ_PE13 (SAM_IRQ_GPIOE_PINS+13) /* GPIOE, PIN 13 */ +# define SAM_IRQ_PE14 (SAM_IRQ_GPIOE_PINS+14) /* GPIOE, PIN 14 */ +# define SAM_IRQ_PE15 (SAM_IRQ_GPIOE_PINS+15) /* GPIOE, PIN 15 */ +# define SAM_IRQ_PE16 (SAM_IRQ_GPIOE_PINS+16) /* GPIOE, PIN 16 */ +# define SAM_IRQ_PE17 (SAM_IRQ_GPIOE_PINS+17) /* GPIOE, PIN 17 */ +# define SAM_IRQ_PE18 (SAM_IRQ_GPIOE_PINS+18) /* GPIOE, PIN 18 */ +# define SAM_IRQ_PE19 (SAM_IRQ_GPIOE_PINS+19) /* GPIOE, PIN 19 */ +# define SAM_IRQ_PE20 (SAM_IRQ_GPIOE_PINS+20) /* GPIOE, PIN 20 */ +# define SAM_IRQ_PE21 (SAM_IRQ_GPIOE_PINS+21) /* GPIOE, PIN 21 */ +# define SAM_IRQ_PE22 (SAM_IRQ_GPIOE_PINS+22) /* GPIOE, PIN 22 */ +# define SAM_IRQ_PE23 (SAM_IRQ_GPIOE_PINS+23) /* GPIOE, PIN 23 */ +# define SAM_IRQ_PE24 (SAM_IRQ_GPIOE_PINS+24) /* GPIOE, PIN 24 */ +# define SAM_IRQ_PE25 (SAM_IRQ_GPIOE_PINS+25) /* GPIOE, PIN 25 */ +# define SAM_IRQ_PE26 (SAM_IRQ_GPIOE_PINS+26) /* GPIOE, PIN 26 */ +# define SAM_IRQ_PE27 (SAM_IRQ_GPIOE_PINS+27) /* GPIOE, PIN 27 */ +# define SAM_IRQ_PE28 (SAM_IRQ_GPIOE_PINS+28) /* GPIOE, PIN 28 */ +# define SAM_IRQ_PE29 (SAM_IRQ_GPIOE_PINS+29) /* GPIOE, PIN 29 */ +# define SAM_IRQ_PE30 (SAM_IRQ_GPIOE_PINS+30) /* GPIOE, PIN 30 */ +# define SAM_IRQ_PE31 (SAM_IRQ_GPIOE_PINS+31) /* GPIOE, PIN 31 */ +# define SAM_NGPIOEIRQS 32 +#else +# define SAM_NGPIOEIRQS 0 +#endif + +/* Total number of IRQ numbers */ + +#define NR_VECTORS SAM_IRQ_NIRQS +#define NR_IRQS (SAM_IRQ_EXTINT + SAM_IRQ_NEXTINT + \ + SAM_NGPIOAIRQS + SAM_NGPIOBIRQS + SAM_NGPIOCIRQS + \ + SAM_NGPIODIRQS + SAM_NGPIOEIRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Inline functions + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SAMV7_SAMV71_IRQ_H */ diff --git a/arch/arm/include/serial.h b/arch/arm/include/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..5663a990ec0334a905be30f323dc553687ecdf02 --- /dev/null +++ b/arch/arm/include/serial.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/arm/include/serial.h + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SERIAL_H +#define __ARCH_ARM_INCLUDE_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_SERIAL_H */ diff --git a/arch/arm/include/spinlock.h b/arch/arm/include/spinlock.h new file mode 100644 index 0000000000000000000000000000000000000000..fbd0e424382e7aff2c0607abe48b3b71cd4e5ec0 --- /dev/null +++ b/arch/arm/include/spinlock.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm/include/spinlock.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_SPINLOCK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SP_UNLOCKED 0 /* The Un-locked state */ +#define SP_LOCKED 1 /* The Locked state */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* The Type of a spinlock. + * + * ARMv6 architecture introuced the concept of exclusive accesses to memory + * locations in the form of the Load-Exclusive (LDREX) and Store-Exclusive + * (STREX) instructions in ARM and Thumb instruction sets. ARMv6K extended + * this to included byte, halfword, and doubleword variants of LDREX and + * STREX. ARMv7-M supports byte and halfwor, but not the doudleword varient + * (ARMv6-M does not support exlusive access) + * + * ARM architectures prior to ARMv6 supported SWP and SWPB instructions that + * atomically swap a 32-bit word for byte value between a register and a + * memory location. From the ARMv6 architecture, ARM deprecates the use + * of SWP and SWPB. + */ + +typedef uint8_t spinlock_t; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + +/* See prototype in nuttx/include/nuttx/spinlock.h */ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_SPINLOCK_H */ diff --git a/arch/arm/include/stdarg.h b/arch/arm/include/stdarg.h new file mode 100644 index 0000000000000000000000000000000000000000..653d34a6ffafd1910d4dc8a74f208a4c170f8d0f --- /dev/null +++ b/arch/arm/include/stdarg.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/arm/include/stdarg.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STDARG_H +#define __ARCH_ARM_INCLUDE_STDARG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This should work with any modern gcc (newer than 3.4 or so) */ + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_copy(d,s) __builtin_va_copy(d,s) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef __builtin_va_list va_list; + +#endif /* __ARCH_ARM_INCLUDE_STDARG_H */ diff --git a/arch/arm/include/stm32/chip.h b/arch/arm/include/stm32/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..ae2c1b614c9fa9f74fc693250dfebf71df96e5d6 --- /dev/null +++ b/arch/arm/include/stm32/chip.h @@ -0,0 +1,2462 @@ +/************************************************************************************ + * arch/arm/include/stm32/chip.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip and provide alternate function pin-mapping + * + * NOTE: Each GPIO pin may serve either for general purpose I/O or for a special + * alternate function (such as USART, CAN, USB, SDIO, etc.). That particular + * pin-mapping will depend on the package and STM32 family. If you are incorporating + * a new STM32 chip into NuttX, you will need to add the pin-mapping to a header file + * and to include that header file below. The chip-specific pin-mapping is defined in + * the chip datasheet. + */ + +/* STM32L EnergyLite Line ************************************************************/ + +/* STM32L151XX -- No LCD + * STM32L152XX -- With LCD + * + * STM32L15XCX -- 48-pins + * STM32L15XRX -- 64-pins + * STM32L15XVX -- 100-pins + * + * STM32L15XX6 -- 32KB FLASH, 10KB SRAM, 4KB EEPROM + * STM32L15XX8 -- 64KB FLASH, 10KB SRAM, 4KB EEPROM + * STM32L15XXB -- 128KB FLASH, 16KB SRAM, 4KB EEPROM + * + * STM32L15XXC -- 256KB FLASH, 32KB SRAM, 8KB EEPROM (medium+ density) + */ + +#if defined(CONFIG_ARCH_CHIP_STM32L151C6) || defined(CONFIG_ARCH_CHIP_STM32L151C8) || \ + defined(CONFIG_ARCH_CHIP_STM32L151CB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 37 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 16-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 13 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L151R6) || defined(CONFIG_ARCH_CHIP_STM32L151R8) || \ + defined(CONFIG_ARCH_CHIP_STM32L151RB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 51 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 20-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L151V6) || defined(CONFIG_ARCH_CHIP_STM32L151V8) || \ + defined(CONFIG_ARCH_CHIP_STM32L151VB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 83 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 24-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L152C6) || defined(CONFIG_ARCH_CHIP_STM32L152C8) || \ + defined(CONFIG_ARCH_CHIP_STM32L152CB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 1 /* LCD 4x16 */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 37 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 16-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 13 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L152R6) || defined(CONFIG_ARCH_CHIP_STM32L152R8) || \ + defined(CONFIG_ARCH_CHIP_STM32L152RB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 1 /* LCD 4x32, 8x28 */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 51 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 20-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L152V6) || defined(CONFIG_ARCH_CHIP_STM32L152V8) || \ + defined(CONFIG_ARCH_CHIP_STM32L152VB) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 1 /* DMA1, 7-channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 1 /* LCD 4x44, 8x40*/ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 83 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 24-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L152RC) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite vamily */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# define CONFIG_STM32_MEDIUMPLUSDENSITY 1 /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 3 /* 16-bit general up/down timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */ +# define STM32_NDMA 2 /* DMA1, 7-channels, DMA2 (5 channels) */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2, overlapping with SPI2-3 */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 1 /* LCD 4x44, 8x40*/ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 83 /* GPIOA-E,H */ +# define STM32_NADC 1 /* ADC1, 24-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32L162ZD) +# define CONFIG_STM32_STM32L15XX 1 /* STM32L151xx and STM32L152xx family */ +# define CONFIG_STM32_ENERGYLITE 1 /* STM32L EnergyLite vamily */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes + * and STM32L15xxx */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes, STM32L16x w/ 48/384 Kbytes. */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 0 /* No advanced timers */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-4 with DMA + * 32-bit general timer TIM5 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 without DMA */ +# define STM32_NDMA 2 /* DMA1, 7-channels, DMA2 (5 channels) */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2, overlapping with SPI2-3 */ +# define STM32_NUSART 5 /* USART1-3, UART4-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 1 /* LCD 4x44, 8x40*/ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NGPIO 115 /* GPIOA-G,H */ +# define STM32_NADC 1 /* ADC1, 24-channels */ +# define STM32_NDAC 2 /* DAC 1-2, 2 channels */ + /* (2) Comparators */ +# define STM32_NCAPSENSE 20 /* Capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F100 Value Line ************************************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F100C8) || defined(CONFIG_ARCH_CHIP_STM32F100CB) \ + || defined(CONFIG_ARCH_CHIP_STM32F100R8) || defined(CONFIG_ARCH_CHIP_STM32F100RB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# define CONFIG_STM32_VALUELINE 1 /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 3 /* 16-bit general timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +// TODO: there are also 3 additional timers (15-17) that don't fit any existing category +# define STM32_NDMA 1 /* DMA1 */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 64 /* GPIOA-D */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 2 /* DAC 1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC1 */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F100V8) || defined(CONFIG_ARCH_CHIP_STM32F100VB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# define CONFIG_STM32_VALUELINE 1 /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 3 /* 16-bit general timers TIM2-4 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +// TODO: there are also 3 additional timers (15-17) that don't fit any existing category +# define STM32_NDMA 1 /* DMA1 */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 80 /* GPIOA-E */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 2 /* DAC 1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC1 */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F100 High-density value Line ************************************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F100RC) || defined(CONFIG_ARCH_CHIP_STM32F100RD) \ + || defined(CONFIG_ARCH_CHIP_STM32F100RE) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# define CONFIG_STM32_VALUELINE 1 /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +// TODO: there are also 6 additional timers (12-17) that don't fit any existing category +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 5 /* USART1-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 64 /* GPIOA-D */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 2 /* DAC 1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC1 */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F100VC) || defined(CONFIG_ARCH_CHIP_STM32F100VD) \ + || defined(CONFIG_ARCH_CHIP_STM32F100VE) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# define CONFIG_STM32_VALUELINE 1 /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +// TODO: there are also 6 additional timers (12-17) that don't fit any existing category +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 5 /* USART1-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 80 /* GPIOA-E */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 2 /* DAC 1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC1 */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F102x8/102xB Medium Density USB Access Family ***************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F102CB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite vamily */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_USBACCESSLINE 1 /* STM32F102xx */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 0 /* No advanced timer TIM1 */ +# define STM32_NGTIM 3 /* 16-bit general timers TIM2-4 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 1 /* DMA */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-D */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC1 */ +# define STM32_NETHERNET 0 /* No ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F103 Low Density Family *************************************************/ + +/* STM32F103C4 & STM32F103C6 */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103C4) +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# define CONFIG_STM32_LOWDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 2 /* General timers TIM2,3 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timer */ +# define STM32_NDMA 1 /* DMA1 */ +# define STM32_NSPI 1 /* SPI1 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 2 /* USART1-2 */ +# define STM32_NI2C 1 /* I2C1 */ +# define STM32_NCAN 1 /* bxCAN1 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-C */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F103 Medium Density Performance Line ***************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103T8) || defined(CONFIG_ARCH_CHIP_STM32F103TB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_PERFORMANCELINE 1 /* STM32F103x8 and STM32F103xB */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 3 /* General timers TIM2-4 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 1 /* DMA1, 7 channels */ +# define STM32_NSPI 1 /* SPI1 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 2 /* USART1-2 */ +# define STM32_NI2C 1 /* I2C1 */ +# define STM32_NCAN 1 /* bxCAN1 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 26 /* GPIOA-E */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103C8) || defined(CONFIG_ARCH_CHIP_STM32F103CB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_PERFORMANCELINE 1 /* STM32F103x8 and STM32F103xB */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 3 /* General timers TIM2-4 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 1 /* DMA1, 7 channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 1 /* bxCAN1 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-C */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103R8) || defined(CONFIG_ARCH_CHIP_STM32F103RB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_PERFORMANCELINE 1 /* STM32F103x8 and STM32F103xB */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 3 /* General timers TIM2-4 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 1 /* DMA1, 7 channels */ +# define STM32_NSPI 2 /* SPI1-2 */ +# define STM32_NI2S 0 /* No I2S */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 1 /* bxCAN1 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 51 /* GPIOA-E */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F103 High Density Family ***************************************************/ +/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and + * differ only in the available FLASH and SRAM. + */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103RC) || defined(CONFIG_ARCH_CHIP_STM32F103RD) || \ + defined(CONFIG_ARCH_CHIP_STM32F103RE) || defined(CONFIG_ARCH_CHIP_STM32F103RG) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and TIM8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* Two basic timers TIM6 and TIM7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 0 /* No I2S (?) */ +# define STM32_NUSART 5 /* USART1-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 1 /* CAN1 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 51 /* GPIOA-D */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 2 /* DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32F103VC, STM32F103VD, and STM32F103VE are all provided in 100 pin packages and differ + * only in the available FLASH and SRAM. + */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103VC) || defined(CONFIG_ARCH_CHIP_STM32F103VE) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and TIM8 */ +# define STM32_NGTIM 4 /* General timers TIM2-5 */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* Two basic timers TIM6 and TIM7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 0 /* No I2S (?) */ +# define STM32_NUSART 5 /* USART1-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 1 /* bxCAN1 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 80 /* GPIOA-E */ +# define STM32_NADC 3 /* ADC1-3 */ +# define STM32_NDAC 2 /* DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32F103ZC, STM32F103ZD, and STM32F103ZE are all provided in 144 pin packages and differ + * only in the available FLASH and SRAM. + */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F103ZE) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# define CONFIG_STM32_HIGHDENSITY 1 /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timer TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 0 /* No I2S (?) */ +# define STM32_NUSART 3 /* USART1-3 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 1 /* CAN1 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 112 /* GPIOA-G */ +# define STM32_NADC 1 /* ADC1 */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 0 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F105/F107 Connectivity Line *******************************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F105VB) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_CONNECTIVITYLINE 1 /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 5 /* USART1-3, UART 4-5 */ +# define STM32_NI2C 2 /* I2C1-2 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 80 /* GPIOA-E */ +# define STM32_NADC 2 /* ADC1-2 */ +# define STM32_NDAC 2 /* DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F107VC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# define CONFIG_STM32_CONNECTIVITYLINE 1 /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM2-5 with DMA */ +# define STM32_NGTIMNDMA 0 /* No 16-bit general timers without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 5 /* USART1-3, UART 4-5 */ +# define STM32_NI2C 1 /* I2C1 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 0 /* No SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 80 /* GPIOA-E */ +# define STM32_NADC 2 /* ADC1-2*/ +# define STM32_NDAC 2 /* DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* No random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +/* STM32 F2 Family ******************************************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F205RG) /* UFBGA-176 1024Kb FLASH 128Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# define CONFIG_STM32_STM32F20XX 1 /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 51 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F207IG) /* UFBGA-176 1024Kb FLASH 128Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# define CONFIG_STM32_STM32F20XX 1 /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 140 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F207ZE) /* LQFP-144 512Kb FLASH 128Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# define CONFIG_STM32_STM32F20XX 1 /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 114 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +/* STM23 F3 Family ******************************************************************/ +/* Part Numbering: STM32Fssscfxxx + * + * Where + * sss = 302/303 or 372/373 + * c = C (48pins) R (68 pins) V (100 pins) + * c = K (32 pins), C (48 pins), R (68 pins), V (100 pins) + * f = 6 (32KB FLASH), 8 (64KB FLASH), B (128KB FLASH), C (256KB FLASH) + * f = 8 (64KB FLASH), B (128KB FLASH), C (256KB FLASH) + * xxx = Package, temperature range, options (ignored here) + */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F302K6) || defined(CONFIG_ARCH_CHIP_STM32F302K8) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite vamily */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 (no TIM8) */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ + +# define STM32_NBTIM 1 /* (1) Basic timers: TIM6 (no TIM7) */ +# define STM32_NDMA 1 /* (1) DMA1 (7 channels) */ +# define STM32_NSPI 2 /* (3) SPI1-3 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 2 /* (2) USART1-2, no UARTs */ +# define STM32_NI2C 3 /* (3) I2C1-3 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 24 /* GPIOA-F */ +# define STM32_NADC 1 /* (1) 12-bit ADC1 */ +# define STM32_NDAC 1 /* (1) 12-bit DAC1 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F302CB) || defined(CONFIG_ARCH_CHIP_STM32F302CC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 (no TIM8) */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ + +# define STM32_NBTIM 1 /* (1) Basic timers: TIM6 (no TIM7) */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 3 /* (3) No UART1-3, no UARTs */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-F */ +# define STM32_NADC 2 /* (2) 12-bit ADC1-2 */ +# define STM32_NDAC 1 /* (1) 12-bit DAC1 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F302RB) || defined(CONFIG_ARCH_CHIP_STM32F302RC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 (no TIM8) */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ + +# define STM32_NBTIM 1 /* (1) Basic timers: TIM6 (no TIM7) */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 5 /* (5) USART1-3, UART4-5 */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 52 /* GPIOA-F */ +# define STM32_NADC 2 /* (2) 12-bit ADC1-2 */ +# define STM32_NDAC 1 /* (1) 12-bit DAC1 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F302VB) || defined(CONFIG_ARCH_CHIP_STM32F302VC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 (no TIM8) */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ + +# define STM32_NBTIM 1 /* (1) Basic timers: TIM6 (no TIM7) */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 5 /* (5) USART1-3, UART4-5 */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 87 /* GPIOA-F */ +# define STM32_NADC 2 /* (2) 12-bit ADC1-2 */ +# define STM32_NDAC 1 /* (1) 12-bit DAC1 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303K6) || defined(CONFIG_ARCH_CHIP_STM32F303K8) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 */ +# define STM32_NGTIM 5 /* (1) 16-bit general timers with DMA: TIM3 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 1 /* (1) DMA1 (7 channels) */ +# define STM32_NSPI 1 /* (1) SPI1 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 2 /* (2) USART1-2, no UARTs */ +# define STM32_NI2C 1 /* (1) I2C1 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 25 /* GPIOA-F */ +# define STM32_NADC 2 /* (2) 12-bit ADC1-2 */ +# define STM32_NDAC 3 /* (2) 12-bit DAC1-3 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303C6) || defined(CONFIG_ARCH_CHIP_STM32F303C8) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 1 /* (1) Advanced 16-bit timers with DMA: TIM1 */ +# define STM32_NGTIM 5 /* (1) 16-bit general timers with DMA: TIM3 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 1 /* (1) DMA1 (7 channels) */ +# define STM32_NSPI 1 /* (1) SPI1 */ +# define STM32_NI2S 0 /* (0) No I2S */ +# define STM32_NUSART 3 /* (3) USART1-3, no UARTs */ +# define STM32_NI2C 1 /* (1) I2C1 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-F */ +# define STM32_NADC 2 /* (2) 12-bit ADC1-2 */ +# define STM32_NDAC 3 /* (2) 12-bit DAC1-3 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303CB) || defined(CONFIG_ARCH_CHIP_STM32F303CC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 2 /* (2) Advanced 16-bit timers with DMA: TIM1 and TIM8 */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 2 /* (2) I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 3 /* (3) No UART1-3, no UARTs */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 37 /* GPIOA-F */ +# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */ +# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303RB) || defined(CONFIG_ARCH_CHIP_STM32F303RC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 2 /* (2) Advanced 16-bit timers with DMA: TIM1 and TIM8 */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 2 /* (2) I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 5 /* (5) USART1-3, UART4-5 */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 52 /* GPIOA-F */ +# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */ +# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303RD) || defined(CONFIG_ARCH_CHIP_STM32F303RE) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 2 /* (2) Advanced 16-bit timers with DMA: TIM1 and TIM8 */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 4 /* (4) SPI1-4 */ +# define STM32_NI2S 2 /* (2) I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 5 /* (5) USART1-3, UART4-5 */ +# define STM32_NI2C 3 /* (2) I2C1-3 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 51 /* GPIOA-F */ +# define STM32_NADC 4 /* (4) 12-bit ADC1-4 */ +# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F303VB) || defined(CONFIG_ARCH_CHIP_STM32F303VC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# define CONFIG_STM32_STM32F30XX 1 /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 2 /* (2) Advanced 16-bit timers with DMA: TIM1 and TIM8 */ +# define STM32_NGTIM 6 /* (2) 16-bit general timers with DMA: TIM3 and TIM4 + * (1) 32-bit general timers with DMA: TIM2 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 0 /* All timers have DMA */ +# define STM32_NBTIM 2 /* (2) Basic timers: TIM6 and TIM7 */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 2 /* (2) I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 5 /* (5) USART1-3, UART4-5 */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 87 /* GPIOA-F */ +# define STM32_NADC 3 /* (3) 12-bit ADC1-3 */ +# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F373C8) || defined(CONFIG_ARCH_CHIP_STM32F373CB) || defined(CONFIG_ARCH_CHIP_STM32F373CC) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite vamily */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# define CONFIG_STM32_STM32F37XX 1 /* STM32F37xxx family */ +# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ + +# define STM32_NATIM 0 /* (0) Advanced 16-bit timers with DMA: */ +# define STM32_NGTIM 8 /* (3) 16-bit general timers with DMA: TIM3, TIM4 and TIM19 + * (2) 32-bit general timers with DMA: TIM2 and TIM5 + * (3) 16-bit general timers count-up timers with DMA: TIM15-17 */ +# define STM32_NGTIMNDMA 3 /* (3) 16-bit general timers count-up timers without DMA: TIM12-14 */ +# define STM32_NBTIM 3 /* (3) Basic timers: TIM6, TIM7 and TIM18 */ +# define STM32_NDMA 2 /* (2) DMA1 (7 channels) and DMA2 (5 channels) */ +# define STM32_NSPI 3 /* (3) SPI1-3 */ +# define STM32_NI2S 3 /* (3) I2S1-2 (multiplexed with SPI1-3) */ +# define STM32_NUSART 3 /* (3) USART1-3 */ +# define STM32_NI2C 2 /* (2) I2C1-2 */ +# define STM32_NCAN 1 /* (1) CAN1 */ +# define STM32_NSDIO 0 /* (0) No SDIO */ +# define STM32_NLCD 0 /* (0) No LCD */ +# define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ +# define STM32_NGPIO 87 /* GPIOA-F */ +# define STM32_NADC 1 /* (3) 12-bit ADC1 */ +# define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ +# define STM32_NCRC 1 /* (1) CRC calculation unit */ +# define STM32_NETHERNET 0 /* (0) No Ethernet MAC */ +# define STM32_NRNG 0 /* (0) No random number generator (RNG) */ +# define STM32_NDCMI 0 /* (0) No digital camera interface (DCMI) */ + + + +/* STM23 F4 Family ******************************************************************/ + +#elif defined(CONFIG_ARCH_CHIP_STM32F401RE) /* LQFP64 package, 512Kb FLASH, 96KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 2 /* DMA1-2 with 8 streams each*/ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* Actually only 3: USART1, 2 and 6 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 1 /* One SDIO interface */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS (only) */ +# define STM32_NGPIO 50 /* GPIOA-H */ +# define STM32_NADC 1 /* One 12-bit ADC1, 16 channels */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F411RE) /* LQFP64 package, 512Kb FLASH, 128KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM9-11 without DMA */ +# define STM32_NBTIM 0 /* No basic timers */ +# define STM32_NDMA 2 /* DMA1-2 with 8 streams each*/ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* Actually only 3: USART1, 2 and 6 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 0 /* No CAN */ +# define STM32_NSDIO 1 /* One SDIO interface */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS (only) */ +# define STM32_NGPIO 50 /* GPIOA-H */ +# define STM32_NADC 1 /* One 12-bit ADC1, 16 channels */ +# define STM32_NDAC 0 /* No DAC */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* No CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F405RG) /* LQFP 64 10x10x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 0 /* No FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F405VG) /* LQFP 100 14x14x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F405ZG) /* LQFP 144 20x20x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407VE) /* LQFP-100 512Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407VG) /* LQFP-100 14x14x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407ZE) /* LQFP-144 512Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407ZG) /* LQFP 144 20x20x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407IE) /* LQFP 176 24x24x1.4 512Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 (?) */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F407IG) /* BGA 176; LQFP 176 24x24x1.4 1024Kb FLASH 192Kb SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx and STM32407xx */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F427I) /* BGA176; LQFP176 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F427Z) /* LQFP144 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F427V) /* LQFP100 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F429I) /* BGA176; LQFP176 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F429Z) /* LQFP144 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437/429/439 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F429V) /* LQFP100 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 139 /* GPIOA-I */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F446M) /* WLCSP81 256/512KiB flash 128KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 STM32F466 */ +# define STM32_NFSMC 0 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 114 /* GPIOA-I */ +# define STM32_NADC 2 /* 12-bit ADC1-3, 14 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F446R) /* LQFP64 256/512KiB flash 128KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 STM32F466 */ +# define STM32_NFSMC 0 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 114 /* GPIOA-I */ +# define STM32_NADC 2 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F446V) /* LQFP100 256/512KiB flash 128KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 STM32F466 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 114 /* GPIOA-I */ +# define STM32_NADC 2 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F446Z) /* LQFP144 UFBGA144 256/512KiB flash 128KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 STM32F466 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 4 /* SPI1-4 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 6 /* USART1-3 and 6, UART 4-5 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 114 /* GPIOA-I */ +# define STM32_NADC 2 /* 12-bit ADC1-3, 16 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 0 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 0 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F429N) /* TFBGA216 1024/2048KiB flash 256KiB SRAM */ +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 0 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# define STM32_NGPIO 168 /* GPIOA-K */ +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F469A) || \ + defined(CONFIG_ARCH_CHIP_STM32F469I) || \ + defined(CONFIG_ARCH_CHIP_STM32F469B) || \ + defined(CONFIG_ARCH_CHIP_STM32F469N) +# undef CONFIG_STM32_STM32L15XX /* STM32L151xx and STM32L152xx family */ +# undef CONFIG_STM32_ENERGYLITE /* STM32L EnergyLite family */ +# undef CONFIG_STM32_STM32F10XX /* STM32F10xxx family */ +# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */ +# undef CONFIG_STM32_MEDIUMDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */ +# undef CONFIG_STM32_MEDIUMPLUSDENSITY /* STM32L15xxC w/ 32/256 Kbytes */ +# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */ +# undef CONFIG_STM32_VALUELINE /* STM32F100x */ +# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */ +# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */ +# undef CONFIG_STM32_STM32F30XX /* STM32F30xxx family */ +# undef CONFIG_STM32_STM32F37XX /* STM32F37xxx family */ +# define CONFIG_STM32_STM32F40XX 1 /* STM32F405xx, STM32407xx and STM32F427/437 */ +# define STM32_NFSMC 1 /* FSMC */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM 4 /* 16-bit general timers TIM3 and 4 with DMA + * 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NSPI 6 /* SPI1-6 */ +# define STM32_NI2S 2 /* I2S1-2 (multiplexed with SPI2-3) */ +# define STM32_NUSART 8 /* USART1-3 and 6, UART 4-5 and 7-8 */ +# define STM32_NI2C 3 /* I2C1-3 */ +# define STM32_NCAN 2 /* CAN1-2 */ +# define STM32_NSDIO 1 /* SDIO */ +# define STM32_NLCD 1 /* No LCD */ +# define STM32_NUSBOTG 1 /* USB OTG FS/HS */ +# if defined(CONFIG_ARCH_CHIP_STM32F469A) +# define STM32_NGPIO 114 /* GPIOA-I */ +# elif defined(CONFIG_ARCH_CHIP_STM32F469I) +# define STM32_NGPIO 131 /* GPIOA-I */ +# elif defined(CONFIG_ARCH_CHIP_STM32F469B) || \ + defined(CONFIG_ARCH_CHIP_STM32F469N) +# define STM32_NGPIO 161 /* GPIOA-K */ +# endif +# define STM32_NADC 3 /* 12-bit ADC1-3, 24 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32_NCRC 1 /* CRC */ +# if defined(CONFIG_ARCH_CHIP_STM32F469A) +# define STM32_NETHERNET 0 /* No Ethernet MAC */ +# elif defined(CONFIG_ARCH_CHIP_STM32F469I) || \ +# defined(CONFIG_ARCH_CHIP_STM32F469B) || \ + defined(CONFIG_ARCH_CHIP_STM32F469N) +# define STM32_NETHERNET 1 /* 100/100 Ethernet MAC */ +# endif +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NDCMI 1 /* Digital camera interface (DCMI) */ + +#else +# error "Unsupported STM32 chip" +#endif + +/* NVIC priority levels *************************************************************/ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_CHIP_H */ diff --git a/arch/arm/include/stm32/dma2d.h b/arch/arm/include/stm32/dma2d.h new file mode 100644 index 0000000000000000000000000000000000000000..349944148f93158f1c2b80f11a6187693b2ffd6e --- /dev/null +++ b/arch/arm/include/stm32/dma2d.h @@ -0,0 +1,415 @@ +/**************************************************************************** + * arch/arm/src/include/stm32/dma2d.h + * + * Copyright (C) 2015 Marco Krahl. All rights reserved. + * Author: Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32_DMA2D_H +#define __ARCH_ARM_INCLUDE_STM32_DMA2D_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ltdc_area_s; /* see arch/chip/ltdc.h */ + +/* Blend mode definitions */ + +enum dma2d_blend_e +{ + DMA2D_BLEND_NONE = 0, /* Disable all blend operation */ + DMA2D_BLEND_ALPHA = 0x1, /* Enable alpha blending */ + DMA2D_BLEND_PIXELALPHA = 0x2, /* Enable alpha blending from pixel color */ +}; + +/* The layer is controlled through the following structure */ + +struct dma2d_layer_s +{ + /* Name: getvideoinfo + * + * Description: + * Get video information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * vinfo - Reference to the video info structure + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getvideoinfo)(FAR struct dma2d_layer_s *layer, + FAR struct fb_videoinfo_s *vinfo); + + /* Name: getplaneinfo + * + * Description: + * Get plane information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * planeno - Number of the plane + * pinfo - Reference to the plane info structure + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getplaneinfo)(FAR struct dma2d_layer_s *layer, int planeno, + FAR struct fb_planeinfo_s *pinfo); + + /* Name: getlid + * + * Description: + * Get a specific layer identifier. + * + * Parameter: + * layer - Reference to the layer structure + * lid - Reference to store the layer id + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getlid)(FAR struct dma2d_layer_s *layer, int *lid); + +#ifdef CONFIG_STM32_DMA2D_L8 + /* Name: setclut + * + * Description: + * Configure layer clut (color lookup table). + * Non clut is defined during initializing. + * + * Parameter: + * layer - Reference to the layer structure + * cmap - color lookup table with up the 256 entries + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*setclut)(FAR struct dma2d_layer_s *layer, + const FAR struct fb_cmap_s *cmap); + + /* Name: getclut + * + * Description: + * Get configured layer clut (color lookup table). + * + * Parameter: + * layer - Reference to the layer structure + * cmap - Reference to valid color lookup table accept up the 256 color + * entries + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getclut)(FAR struct dma2d_layer_s *layer, FAR struct fb_cmap_s *cmap); +#endif + + /* Name: setalpha + * + * Description: + * Configure layer alpha value factor into blend operation. + * During the layer blend operation the source alpha value is multiplied + * with this alpha value. If the source color format doesn't support alpha + * channel (e.g. non ARGB8888) this alpha value will be used as constant + * alpha value for blend operation. + * Default value during initializing: 0xff + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*setalpha)(FAR struct dma2d_layer_s *layer, uint8_t alpha); + + /* Name: getalpha + * + * Description: + * Get configured layer alpha value factor for blend operation. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Reference to store the alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getalpha)(FAR struct dma2d_layer_s *layer, uint8_t *alpha); + + /* Name: setblendmode + * + * Description: + * Configure blend mode of the layer. + * Default mode during initializing: DMA2D_BLEND_NONE + * Blendmode is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Blend mode (see DMA2D_BLEND_*) + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure information: + * DMA2D_BLEND_NONE: + * Informs the driver to disable all blend operation for the given layer. + * That means the layer is opaque. + * + * DMA2D_BLEND_ALPHA: + * Informs the driver to enable alpha blending for the given layer. + * + * DMA2D_BLEND_PIXELALPHA: + * Informs the driver to use the pixel alpha value of the layer instead + * the constant alpha value. This is only useful for ARGB8888 + * color format. + */ + + int (*setblendmode)(FAR struct dma2d_layer_s *layer, uint32_t mode); + + /* Name: getblendmode + * + * Description: + * Get configured blend mode of the layer. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Reference to store the blend mode + * + * Return: + * On success - OK + * On error - -EINVAL + */ + + int (*getblendmode)(FAR struct dma2d_layer_s *layer, uint32_t *mode); + + /* Name: blit + * + * Description: + * Copy selected area from a source layer to selected position of the + * destination layer. + * + * Parameter: + * dest - Reference to the destination layer + * destxpos - Selected x target position of the destination layer + * destypos - Selected y target position of the destination layer + * src - Reference to the source layer + * srcarea - Reference to the selected area of the source layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the + * selected source area outside the visible area of the + * destination layer. (The visible area usually represents the + * display size) + * -ECANCELED - Operation cancelled, something goes wrong. + */ + + int (*blit)(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea); + + /* Name: blend + * + * Description: + * Blends the selected area from a background layer with selected position + * of the foreground layer. Copies the result to the selected position of + * the destination layer. Note! The content of the foreground and background + * layer keeps unchanged as long destination layer is unequal to the + * foreground and background layer. + * + * Parameter: + * dest - Reference to the destination layer + * fore - Reference to the foreground layer + * forexpos - Selected x target position of the foreground layer + * foreypos - Selected y target position of the foreground layer + * back - Reference to the background layer + * backarea - Reference to the selected area of the background layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the + * selected source area outside the visible area of the + * destination layer. (The visible area usually represents the + * display size) + * -ECANCELED - Operation cancelled, something goes wrong. + */ + + int (*blend)(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea); + + /* Name: fillarea + * + * Description: + * Fill the selected area of the whole layer with a specific color. + * + * Parameter: + * layer - Reference to the layer structure + * area - Reference to the valid area structure select the area + * color - Color to fill the selected area. Color must be formatted + * according to the layer pixel format. + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the + * selected area outside the visible area of the layer. + * -ECANCELED - Operation cancelled, something goes wrong. + */ + + int (*fillarea)(FAR struct dma2d_layer_s *layer, + FAR const struct ltdc_area_s *area, + uint32_t color); +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dma2dgetlayer + * + * Description: + * Get a dma2d layer structure by the layer identifier + * + * Parameter: + * lid - Layer identifier + * + * Return: + * Reference to the dma2d layer control structure on success or Null if no + * related exist. + * + ****************************************************************************/ + +FAR struct dma2d_layer_s * up_dma2dgetlayer(int lid); + +/**************************************************************************** + * Name: up_dma2dcreatelayer + * + * Description: + * Create a new dma2d layer object to interact with the dma2d controller + * + * Parameter: + * width - Layer width + * height - Layer height + * fmt - Pixel format of the layer + * + * Return: + * On success - A valid dma2d layer reference + * On error - NULL and errno is set to + * -EINVAL if one of the parameter is invalid + * -ENOMEM if no memory available or exceeds + * CONFIG_STM32_DMA2D_NLAYERS + * + ****************************************************************************/ + +FAR struct dma2d_layer_s *up_dma2dcreatelayer(fb_coord_t width, + fb_coord_t height, + uint8_t fmt); + +/**************************************************************************** + * Name: up_dma2dremovelayer + * + * Description: + * Remove and deallocate the dma2d layer + * + * Parameter: + * layer - Reference to the layer to remove + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +int up_dma2dremovelayer(FAR struct dma2d_layer_s *layer); + +/**************************************************************************** + * Name: up_dma2dinitialize + * + * Description: + * Initialize the dma2d controller + * + * Return: + * OK - On success + * An error if initializing failed. + * + ****************************************************************************/ + +int up_dma2dinitialize(void); + +/**************************************************************************** + * Name: up_dma2duninitialize + * + * Description: + * Uninitialize the dma2d controller + * + ****************************************************************************/ + +void up_dma2duninitialize(void); + +#endif /* __ARCH_ARM_INCLUDE_STM32_DMA2D_H */ diff --git a/arch/arm/include/stm32/irq.h b/arch/arm/include/stm32/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..1d57bc3e500147c86db55809a6c4cad1aca92c5e --- /dev/null +++ b/arch/arm/include/stm32/irq.h @@ -0,0 +1,124 @@ +/************************************************************************************ + * arch/arm/include/stm32s/irq.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define STM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define STM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define STM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define STM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define STM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define STM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define STM32_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define STM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define STM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define STM32_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define STM32_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_STM32_STM32L15XX) +# include +#elif defined(CONFIG_STM32_STM32F10XX) +# include +#elif defined(CONFIG_STM32_STM32F20XX) +# include +#elif defined(CONFIG_STM32_STM32F30XX) +# include +#elif defined(CONFIG_STM32_STM32F37XX) +# include +#elif defined(CONFIG_STM32_STM32F40XX) +# include +#else +# error "Unsupported STM32 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_IRQ_H */ + diff --git a/arch/arm/include/stm32/ltdc.h b/arch/arm/include/stm32/ltdc.h new file mode 100644 index 0000000000000000000000000000000000000000..70f978058aa6fa13a6f791c99fb80b6781837272 --- /dev/null +++ b/arch/arm/include/stm32/ltdc.h @@ -0,0 +1,592 @@ +/**************************************************************************** + * arch/arm/src/include/stm32/ltdc.h + * + * Copyright (C) 2014-2015 Marco Krahl. All rights reserved. + * Author: Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32_LTDC_H +#define __ARCH_ARM_INCLUDE_STM32_LTDC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_STM32_LTDC +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct dma2d_layer_s; /* see arch/chip/dma2d.h */ + +/* Blend mode definitions */ + +enum ltdc_blend_e +{ + LTDC_BLEND_NONE = 0, /* Disable all blend operation */ + LTDC_BLEND_ALPHA = 0x1, /* Enable alpha blending */ + LTDC_BLEND_PIXELALPHA = 0x2, /* Enable alpha blending from pixel color */ + LTDC_BLEND_COLORKEY = 0x4, /* Enable colorkey */ + LTDC_BLEND_ALPHAINV = 0x8, /* Inverse alpha blending of source */ + LTDC_BLEND_PIXELALPHAINV = 0x10 /* Invers pixel alpha blending of source */ +}; + +/* layer control definitions */ + +enum ltdc_layer_e +{ + LTDC_LAYER_OWN = 0, /* The given layer */ + LTDC_LAYER_TOP = 0x1, /* The initialized top layer */ + LTDC_LAYER_BOTTOM = 0x2, /* the initialized bottom layer */ + LTDC_LAYER_ACTIVE = 0x4, /* The current visible flip layer */ + LTDC_LAYER_INACTIVE = 0x8 /* The current invisible flip layer */ +#ifdef CONFIG_STM32_DMA2D + ,LTDC_LAYER_DMA2D = 0x10 /* The dma2d interface layer id */ +#endif +}; + +/* Update operation flag */ + +enum ltdc_update_e +{ + LTDC_UPDATE_NONE = 0, /* Update given layer only */ + LTDC_UPDATE_SIM = 0x1, /* Update both layer simultaneous */ + LTDC_UPDATE_FLIP = 0x2, /* Perform flip operation */ + LTDC_UPDATE_ACTIVATE = 0x4 /* Set the given layer to the active layer */ +}; + +/* sync mode definitions */ + +enum ltdc_sync_e +{ + LTDC_SYNC_NONE = 0, /* Immediately */ + LTDC_SYNC_VBLANK = 0x100, /* Upon vertical sync */ + LTDC_SYNC_WAIT = 0x200 /* Waits upon vertical sync */ +}; + +/* Definition of the visible layer position and size */ + +struct ltdc_area_s +{ + fb_coord_t xpos; /* X position in pixel */ + fb_coord_t ypos; /* Y position in pixel */ + fb_coord_t xres; /* X resolution in pixel */ + fb_coord_t yres; /* Y resolution in pixel */ +}; + +/* The layer is controlled through the following structure */ + +struct ltdc_layer_s +{ + + /* + * Name: getvideoinfo + * + * Description: + * Get video information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * vinfo - Reference to the video info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getvideoinfo)(FAR struct ltdc_layer_s *layer, + FAR struct fb_videoinfo_s *vinfo); + + /* + * Name: getplaneinfo + * + * Description: + * Get plane information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * planeno - Number of the plane + * pinfo - Reference to the plane info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getplaneinfo)(FAR struct ltdc_layer_s *layer, int planeno, + FAR struct fb_planeinfo_s *pinfo); + + /* + * Name: getlid + * + * Description: + * Get a specific layer identifier. + * + * Parameter: + * layer - Reference to the layer structure + * lid - Reference to store the layer id + * flag - Operation flag describe the layer identifier + * e.g. get the current active or inactive layer. + * See LTDC_LAYER_* for possible values + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getlid)(FAR struct ltdc_layer_s *layer, int *lid, uint32_t flag); + +#ifdef CONFIG_FB_CMAP + /* + * Name: setclut + * + * Description: + * Configure layer clut (color lookup table). + * Non clut is defined during initializing. + * Clut is active during next vertical blank period. Do not need an update. + * + * Parameter: + * layer - Reference to the layer structure + * cmap - color lookup table with up the 256 entries + * enable - Enable or disable clut support (if false cmap is ignored and can + * be NULL) + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*setclut)(FAR struct ltdc_layer_s *layer, + const FAR struct fb_cmap_s *cmap); + + /* + * Name: getclut + * + * Description: + * Get configured layer clut (color lookup table). + * + * Parameter: + * layer - Reference to the layer structure + * cmap - Reference to valid color lookup table accept up the 256 color + * entries + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getclut)(FAR struct ltdc_layer_s *layer, FAR struct fb_cmap_s *cmap); +#endif + + /* + * Name: setcolor + * + * Description: + * Configure layer color for the non active layer area. + * Default value during initializing: 0x00000000 + * Color is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * argb - ARGB8888 color value + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*setcolor)(FAR struct ltdc_layer_s *layer, uint32_t argb); + + /* + * Name: getcolor + * + * Description: + * Get configured layer color for the non active layer area. + * + * Parameter: + * layer - Reference to the layer structure + * argb - Reference to store the ARGB8888 color value + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getcolor)(FAR struct ltdc_layer_s *layer, uint32_t *argb); + + /* + * Name: setcolorkey + * + * Description: + * Configure the layer color key (chromakey) for transparence. + * Default value during initializing: 0x00000000 + * Colorkey is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * rgb - RGB888 color key + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*setcolorkey)(FAR struct ltdc_layer_s *layer, uint32_t rgb); + + /* + * Name: getcolorkey + * + * Description: + * Get the configured layer color key (chromakey) for transparence. + * + * Parameter: + * layer - Reference to the layer structure + * rgb - Reference to store the RGB888 color key + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getcolorkey)(FAR struct ltdc_layer_s *layer, uint32_t *rgb); + + /* + * Name: setalpha + * + * Description: + * Configure layer alpha value factor into blend operation. + * During the layer blend operation the source alpha value is multiplied + * with this alpha value. If the source color format doesn't support alpha + * channel (e.g. non ARGB8888) this alpha value will be used as constant + * alpha value for blend operation. + * Default value during initializing: 0xff + * Alpha is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*setalpha)(FAR struct ltdc_layer_s *layer, uint8_t alpha); + + /* + * Name: getalpha + * + * Description: + * Get configured layer alpha value factor for blend operation. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Reference to store the alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getalpha)(FAR struct ltdc_layer_s *layer, uint8_t *alpha); + + /* + * Name: setblendmode + * + * Description: + * Configure blend mode of the layer. + * Default mode during initializing: LTDC_BLEND_NONE + * Blendmode is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Blend mode (see LTDC_BLEND_*) + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure information: + * LTDC_BLEND_NONE: + * Informs the driver to disable all blend operation for the given layer. + * That means the layer is opaque. Note this has no effect on the + * colorkey settings. + * + * LTDC_BLEND_ALPHA: + * Informs the driver to enable alpha blending for the given layer. + * + * LTDC_BLEND_COLORKEY: + * Informs the driver to enable colorkeying for the given layer. + * + * LTDC_BLEND_SRCPIXELALPHA: + * Informs the driver to use the pixel alpha value of the layer instead + * the constant alpha value. This is only useful for ARGB8888 + * color format. + * + * LTDC_BLEND_DESTPIXELALPHA: + * Informs the driver to use the pixel alpha value of the subjacent layer + * instead the constant alpha value. This is only useful for ARGB8888 + * color format. + * + */ + int (*setblendmode)(FAR struct ltdc_layer_s *layer, uint32_t mode); + + /* + * Name: getblendmode + * + * Description: + * Get configured blend mode of the layer. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Reference to store the blend mode + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getblendmode)(FAR struct ltdc_layer_s *layer, uint32_t *mode); + + /* + * Name: setarea + * + * Description: + * Configure visible layer area and the reference position of the first + * pixel of the whole layer which is the first visible top left pixel in + * the active area. + * Default value during initializing: + * xpos = 0 + * ypos = 0 + * xres = display x resolution + * yres = display y resolution + * + * Area is active after next update. + * + * Parameter: + * layer - Reference to the layer control structure + * area - Reference to the valid area structure for the new active area + * srcxpos - x position of the visible pixel of the whole layer + * srcypos - y position of the visible pixel of the whole layer + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure Information: + * If the srcxpos and srcypos unequal the the xpos and ypos of the coord + * structure this acts like moving the visible area to another position on + * the screen during the next update operation. + * + */ + int (*setarea)(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + fb_coord_t srcxpos, + fb_coord_t srcypos); + + /* + * Name: getarea + * + * Description: + * Get configured visible layer area. + * + * Parameter: + * layer - Reference to the layer control structure + * area - Reference to the area structure to store the active area + * srcxpos - Reference to store the referenced x position of the whole layer + * srcypos - Reference to store the reterenced y position of the whole layer + * + * Return: + * On success - OK + * On error - -EINVAL + * + */ + int (*getarea)(FAR struct ltdc_layer_s *layer, + FAR struct ltdc_area_s *area, + fb_coord_t *srcxpos, + fb_coord_t *srcypos); + + /* + * Name: update + * + * Description: + * Update current layer settings and make changes visible. + * + * Parameter: + * layer - Reference to the layer structure + * mode - operation mode (see LTDC_UPDATE_*) + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid + * -ECANCELED - Operation cancelled, something goes wrong + * + * Procedure information: + * LTDC_UPDATE_SIM: + * Informs the driver to update both ltdc layers simultaneously. Otherwise + * update the given layer only. + * + * LTDC_UPDATE_FLIP: + * Informs the driver to perform a flip operation. + * This only effects the ltdc layer 1 and 2 and can be useful for double + * buffering. Each flip operation changed the active layer ot the inactive + * and vice versa. In the context of the ltdc that means, the inactive layer + * is complete disabled. So the subjacent layer is the background layer + * (background color). To reactivate both layer and their settings perform + * an update without LTDC_UPDATE_FLIP flag. + * + * LTDC_UPDATE_ACTIVATE: + * Informs the driver that the given layer should be the active layer when + * the operation is complete. + * + * LTDC_SYNC_VBLANK: + * Informs the driver to update the layer upon vertical blank. Otherwise + * immediately. + * + */ + int (*update)(FAR struct ltdc_layer_s *layer, uint32_t mode); + +#ifdef CONFIG_STM32_DMA2D + /* + * Name: blit + * + * Description: + * Copy selected area from a source layer to selected position of the + * destination layer. + * + * Parameter: + * dest - Reference to the destination layer + * destxpos - Selected x position of the destination layer + * destypos - Selected y position of the destination layer + * src - Reference to the source layer + * srcarea - Reference to the selected area of the source layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * + */ + int (*blit)(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea); + /* + * + * Name: blend + * + * Description: + * Blends the selected area from a foreground layer with selected position + * of the background layer. Copy the result to the destination layer. Note! + * The content of the foreground and background layer is not changed. + * + * Parameter: + * dest - Reference to the destination layer + * destxpos - Selected x position of the destination layer + * destypos - Selected y position of the destination layer + * fore - Reference to the foreground layer + * forexpos - Selected x position of the foreground layer + * foreypos - Selected y position of the foreground layer + * back - Reference to the background layer + * backarea - Reference to the selected area of the background layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * + */ + int (*blend)(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea); + + /* + * Name: fillarea + * + * Description: + * Fill the selected area of the whole layer with a specific color. + * + * Parameter: + * layer - Reference to the layer structure + * area - Reference to the valid area structure select the area + * color - Color to fill the selected area. Color must be formatted + * according to the layer pixel format. + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * area outside the visible area of the layer. + * + */ + int (*fillarea)(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + uint32_t color); +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ltdcgetlayer + * + * Description: + * Get the ltdc layer structure to perform hardware layer operation + * + * Parameter: + * lid - Layer identifier + * + * Return: + * Reference to the layer control structure on success or Null if parameter + * invalid. + * + ****************************************************************************/ +FAR struct ltdc_layer_s *up_ltdcgetlayer(int lid); +#endif /* CONFIG_STM32_LTDC */ +#endif /* __ARCH_ARM_INCLUDE_STM32_LTDC_H */ diff --git a/arch/arm/include/stm32/stm32f10xxx_irq.h b/arch/arm/include/stm32/stm32f10xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..3c62e1e2ea3fe97433cf0562c56b74daa7c280e9 --- /dev/null +++ b/arch/arm/include/stm32/stm32f10xxx_irq.h @@ -0,0 +1,313 @@ +/************************************************************************************ + * arch/arm/include/stm32s/stm32f10xxx_irq.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32F10XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32F10XXX_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) + */ + + /* Value line devices */ + +#if defined(CONFIG_STM32_VALUELINE) +# define STM32_IRQ_WWDG (16) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (17) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (18) /* 2: Tamper interrupt */ +# define STM32_IRQ_RTC (19) /* 3: RTC Wakeup through EXTI line interrupt */ +# define STM32_IRQ_FLASH (20) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (21) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (22) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (23) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (24) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (25) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (26) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (27) /* 11: DMA1 Channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (28) /* 12: DMA1 Channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (29) /* 13: DMA1 Channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (30) /* 14: DMA1 Channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (31) /* 15: DMA1 Channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (32) /* 16: DMA1 Channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (33) /* 17: DMA1 Channel 7 global interrupt */ +# define STM32_IRQ_ADC1 (34) /* 18: ADC1 global interrupt */ +# define STM32_IRQ_RESERVED0 (35) /* 19: Reserved 0 */ +# define STM32_IRQ_RESERVED1 (36) /* 20: Reserved 1 */ +# define STM32_IRQ_RESERVED2 (37) /* 21: Reserved 2 */ +# define STM32_IRQ_RESERVED3 (38) /* 22: Reserved 3 */ +# define STM32_IRQ_EXTI95 (39) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_TIM1BRK (40) /* 24: TIM1 Break interrupt */ +# define STM32_IRQ_TIM15 (40) /* TIM15 global interrupt */ +# define STM32_IRQ_TIM1UP (41) /* 25: TIM1 Update interrupt */ +# define STM32_IRQ_TIM16 (41) /* TIM16 global interrupt */ +# define STM32_IRQ_TIM1TRGCOM (42) /* 26: TIM1 Trigger and Commutation interrupts */ +# define STM32_IRQ_TIM17 (42) /* TIM17 global interrupt */ +# define STM32_IRQ_TIM1CC (43) /* 27: TIM1 Capture Compare interrupt */ +# define STM32_IRQ_TIM2 (44) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (45) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (46) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (47) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (48) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (49) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (50) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (51) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (52) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (53) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (54) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (55) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (56) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALR (57) /* 41: RTC alarms (A and B) through EXTI line interrupt */ +# define STM32_IRQ_CEC (58) /* 42: CEC global interrupt */ +# define STM32_IRQ_TIM12 (59) /* 43: TIM12 global interrupt */ +# define STM32_IRQ_TIM13 (60) /* 44: TIM13 global interrupt */ +# define STM32_IRQ_TIM14 (61) /* 45: TIM14 global interrupt */ +# define STM32_IRQ_RESERVED4 (62) /* 46: Reserved 4 */ +# define STM32_IRQ_RESERVED5 (63) /* 47: Reserved 5 */ +# define STM32_IRQ_FSMC (64) /* 48: FSMC global interrupt */ +# define STM32_IRQ_RESERVED6 (65) /* 49: Reserved 6 */ +# define STM32_IRQ_TIM5 (66) /* 50: TIM5 global interrupt */ +# define STM32_IRQ_SPI3 (67) /* 51: SPI3 global interrupt */ +# define STM32_IRQ_UART4 (68) /* 52: USART2 global interrupt */ +# define STM32_IRQ_UART5 (69) /* 53: USART5 global interrupt */ +# define STM32_IRQ_TIM6 (70) /* 54: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (71) /* 55: TIM7 global interrupt */ +# define STM32_IRQ_DMA2CH1 (72) /* 56: DMA2 Channel 1 global interrupt */ +# define STM32_IRQ_DMA2CH2 (73) /* 57: DMA2 Channel 2 global interrupt */ +# define STM32_IRQ_DMA2CH3 (74) /* 58: DMA2 Channel 3 global interrupt */ +# define STM32_IRQ_DMA2CH45 (75) /* 59: DMA2 Channel 4 and 5 global interrupt */ +# define STM32_IRQ_DMA2CH5 (76) /* 60: DMA2 Channel 5 global interrupt */ + +# define NR_VECTORS (77) +# define NR_IRQS (77) + +/* Connectivity Line Devices */ + +#elif defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_IRQ_WWDG (16) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (17) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (18) /* 2: Tamper interrupt */ +# define STM32_IRQ_RTC (19) /* 3: RTC global interrupt */ +# define STM32_IRQ_FLASH (20) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (21) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (22) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (23) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (24) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (25) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (26) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (27) /* 11: DMA1 Channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (28) /* 12: DMA1 Channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (29) /* 13: DMA1 Channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (30) /* 14: DMA1 Channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (31) /* 15: DMA1 Channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (32) /* 16: DMA1 Channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (33) /* 17: DMA1 Channel 7 global interrupt */ +# define STM32_IRQ_ADC12 (34) /* 18: ADC1 and ADC2 global interrupt */ +# define STM32_IRQ_CAN1TX (35) /* 19: CAN1 TX interrupts */ +# define STM32_IRQ_CAN1RX0 (36) /* 20: CAN1 RX0 interrupts */ +# define STM32_IRQ_CAN1RX1 (37) /* 21: CAN1 RX1 interrupt */ +# define STM32_IRQ_CAN1SCE (38) /* 22: CAN1 SCE interrupt */ +# define STM32_IRQ_EXTI95 (39) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_TIM1BRK (40) /* 24: TIM1 Break interrupt */ +# define STM32_IRQ_TIM1UP (41) /* 25: TIM1 Update interrupt */ +# define STM32_IRQ_TIM1TRGCOM (42) /* 26: TIM1 Trigger and Commutation interrupts */ +# define STM32_IRQ_TIM1CC (43) /* 27: TIM1 Capture Compare interrupt */ +# define STM32_IRQ_TIM2 (44) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (45) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (46) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (47) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (48) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (49) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (50) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (51) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (52) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (53) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (54) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (55) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (56) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALRM (57) /* 41: RTC alarm through EXTI line interrupt */ +# define STM32_IRQ_OTGFSWKUP (58) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +# define STM32_IRQ_RESERVED0 (59) /* 43: Reserved 0 */ +# define STM32_IRQ_RESERVED1 (60) /* 44: Reserved 1 */ +# define STM32_IRQ_RESERVED2 (61) /* 45: Reserved 2 */ +# define STM32_IRQ_RESERVED3 (62) /* 46: Reserved 3 */ +# define STM32_IRQ_RESERVED4 (63) /* 47: Reserved 4 */ +# define STM32_IRQ_RESERVED5 (64) /* 48: Reserved 5 */ +# define STM32_IRQ_RESERVED6 (65) /* 49: Reserved 6 */ +# define STM32_IRQ_TIM5 (66) /* 50: TIM5 global interrupt */ +# define STM32_IRQ_SPI3 (67) /* 51: SPI3 global interrupt */ +# define STM32_IRQ_UART4 (68) /* 52: UART4 global interrupt */ +# define STM32_IRQ_UART5 (69) /* 53: UART5 global interrupt */ +# define STM32_IRQ_TIM6 (70) /* 54: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (71) /* 55: TIM7 global interrupt */ +# define STM32_IRQ_DMA2CH1 (72) /* 56: DMA2 Channel 1 global interrupt */ +# define STM32_IRQ_DMA2CH2 (73) /* 57: DMA2 Channel 2 global interrupt */ +# define STM32_IRQ_DMA2CH3 (74) /* 58: DMA2 Channel 3 global interrupt */ +# define STM32_IRQ_DMA2CH4 (75) /* 59: DMA2 Channel 4 global interrupt */ +# define STM32_IRQ_DMA2CH5 (76) /* 60: DMA2 Channel 5 global interrupt */ +# define STM32_IRQ_ETH (77) /* 61: Ethernet global interrupt */ +# define STM32_IRQ_ETHWKUP (78) /* 62: Ethernet Wakeup through EXTI line interrupt */ +# define STM32_IRQ_CAN2TX (79) /* 63: CAN2 TX interrupts */ +# define STM32_IRQ_CAN2RX0 (70) /* 64: CAN2 RX0 interrupts */ +# define STM32_IRQ_CAN2RX1 (81) /* 65: CAN2 RX1 interrupt */ +# define STM32_IRQ_CAN2SCE (82) /* 66: CAN2 SCE interrupt */ +# define STM32_IRQ_OTGFS (83) /* 67: USB On The Go FS global interrupt */ + +# define NR_VECTORS (84) +# define NR_IRQS (84) + +/* Medium and High Density Devices */ + +#else +# define STM32_IRQ_WWDG (16) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (17) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (18) /* 2: Tamper interrupt */ +# define STM32_IRQ_RTC (19) /* 3: RTC global interrupt */ +# define STM32_IRQ_FLASH (20) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (21) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (22) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (23) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (24) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (25) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (26) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (27) /* 11: DMA1 Channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (28) /* 12: DMA1 Channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (29) /* 13: DMA1 Channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (30) /* 14: DMA1 Channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (31) /* 15: DMA1 Channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (32) /* 16: DMA1 Channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (33) /* 17: DMA1 Channel 7 global interrupt */ +# define STM32_IRQ_ADC12 (34) /* 18: ADC1 and ADC2 global interrupt */ +# define STM32_IRQ_USBHPCANTX (35) /* 19: USB High Priority or CAN TX interrupts*/ +# define STM32_IRQ_USBLPCANRX0 (36) /* 20: USB Low Priority or CAN RX0 interrupts*/ +# define STM32_IRQ_CAN1RX1 (37) /* 21: CAN1 RX1 interrupt */ +# define STM32_IRQ_CAN1SCE (38) /* 22: CAN1 SCE interrupt */ +# define STM32_IRQ_EXTI95 (39) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_TIM1BRK (40) /* 24: TIM1 Break interrupt */ +# define STM32_IRQ_TIM1UP (41) /* 25: TIM1 Update interrupt */ +# define STM32_IRQ_TIM1TRGCOM (42) /* 26: TIM1 Trigger and Commutation interrupts */ +# define STM32_IRQ_TIM1CC (43) /* 27: TIM1 Capture Compare interrupt */ +# define STM32_IRQ_TIM2 (44) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (45) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (46) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (47) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (48) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (49) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (50) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (51) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (52) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (53) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (54) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (55) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (56) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALRM (57) /* 41: RTC alarm through EXTI line interrupt */ +# define STM32_IRQ_USBWKUP (58) /* 42: USB wakeup from suspend through EXTI line interrupt*/ +# define STM32_IRQ_TIM8BRK (59) /* 43: TIM8 Break interrupt */ +# define STM32_IRQ_TIM8UP (60) /* 44: TIM8 Update interrupt */ +# define STM32_IRQ_TIM8TRGCOM (61) /* 45: TIM8 Trigger and Commutation interrupts */ +# define STM32_IRQ_TIM8CC (62) /* 46: TIM8 Capture Compare interrupt */ +# define STM32_IRQ_ADC3 (63) /* 47: ADC3 global interrupt */ +# define STM32_IRQ_FSMC (64) /* 48: FSMC global interrupt */ +# define STM32_IRQ_SDIO (65) /* 49: SDIO global interrupt */ +# define STM32_IRQ_TIM5 (66) /* 50: TIM5 global interrupt */ +# define STM32_IRQ_SPI3 (67) /* 51: SPI3 global interrupt */ +# define STM32_IRQ_UART4 (68) /* 52: UART4 global interrupt */ +# define STM32_IRQ_UART5 (69) /* 53: UART5 global interrupt */ +# define STM32_IRQ_TIM6 (70) /* 54: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (71) /* 55: TIM7 global interrupt */ +# define STM32_IRQ_DMA2CH1 (72) /* 56: DMA2 Channel 1 global interrupt */ +# define STM32_IRQ_DMA2CH2 (73) /* 57: DMA2 Channel 2 global interrupt */ +# define STM32_IRQ_DMA2CH3 (74) /* 58: DMA2 Channel 3 global interrupt */ +# define STM32_IRQ_DMA2CH45 (75) /* 59: DMA2 Channel 4&5 global interrupt */ + +# define NR_VECTORS (76) +# define NR_IRQS (76) + +/* Convenience definitions for interrupts with multiple functions */ + +# define STM32_IRQ_USBHP STM32_IRQ_USBHPCANTX +# define STM32_IRQ_CAN1TX STM32_IRQ_USBHPCANTX +# define STM32_IRQ_USBLP STM32_IRQ_USBLPCANRX0 +# define STM32_IRQ_CAN1RX0 STM32_IRQ_USBLPCANRX0 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_STM32F10XXX_IRQ_H */ + diff --git a/arch/arm/include/stm32/stm32f20xxx_irq.h b/arch/arm/include/stm32/stm32f20xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..43a2e218eb9ca9c329692e457834dbbe45b88867 --- /dev/null +++ b/arch/arm/include/stm32/stm32f20xxx_irq.h @@ -0,0 +1,184 @@ +/**************************************************************************************************** + * arch/arm/include/stm32s/stm32f20xxx_irq.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32F20XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32F20XXX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32_IRQ_DMA1S0 (STM32_IRQ_FIRST+11) /* 11: DMA1 Stream 0 global interrupt */ +#define STM32_IRQ_DMA1S1 (STM32_IRQ_FIRST+12) /* 12: DMA1 Stream 1 global interrupt */ +#define STM32_IRQ_DMA1S2 (STM32_IRQ_FIRST+13) /* 13: DMA1 Stream 2 global interrupt */ +#define STM32_IRQ_DMA1S3 (STM32_IRQ_FIRST+14) /* 14: DMA1 Stream 3 global interrupt */ +#define STM32_IRQ_DMA1S4 (STM32_IRQ_FIRST+15) /* 15: DMA1 Stream 4 global interrupt */ +#define STM32_IRQ_DMA1S5 (STM32_IRQ_FIRST+16) /* 16: DMA1 Stream 5 global interrupt */ +#define STM32_IRQ_DMA1S6 (STM32_IRQ_FIRST+17) /* 17: DMA1 Stream 6 global interrupt */ +#define STM32_IRQ_ADC (STM32_IRQ_FIRST+18) /* 18: ADC1, ADC2, and ADC3 global interrupt */ +#define STM32_IRQ_CAN1TX (STM32_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32_IRQ_CAN1RX0 (STM32_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */ +#define STM32_IRQ_CAN1RX1 (STM32_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32_IRQ_CAN1SCE (STM32_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32_IRQ_TIM1BRK (STM32_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */ +#define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+24) /* 24: TIM9 global interrupt */ +#define STM32_IRQ_TIM1UP (STM32_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */ +#define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+25) /* 25: TIM10 global interrupt */ +#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+26) /* 26: TIM11 global interrupt */ +#define STM32_IRQ_TIM1CC (STM32_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32_IRQ_OTGFSWKUP (STM32_IRQ_FIRST+42) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +#define STM32_IRQ_TIM8BRK (STM32_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32_IRQ_TIM12 (STM32_IRQ_FIRST+43) /* 43: TIM12 global interrupt */ +#define STM32_IRQ_TIM8UP (STM32_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32_IRQ_TIM13 (STM32_IRQ_FIRST+44) /* 44: TIM13 global interrupt */ +#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM14 (STM32_IRQ_FIRST+45) /* 45: TIM14 global interrupt */ +#define STM32_IRQ_TIM8CC (STM32_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32_IRQ_DMA1S7 (STM32_IRQ_FIRST+47) /* 47: DMA1 Stream 7 global interrupt */ +#define STM32_IRQ_FSMC (STM32_IRQ_FIRST+48) /* 48: FSMC global interrupt */ +#define STM32_IRQ_SDIO (STM32_IRQ_FIRST+49) /* 49: SDIO global interrupt */ +#define STM32_IRQ_TIM5 (STM32_IRQ_FIRST+50) /* 50: TIM5 global interrupt */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST+52) /* 52: UART4 global interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST+53) /* 53: UART5 global interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+54) /* 54: TIM6 global interrupt */ +#define STM32_IRQ_DAC (STM32_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32_IRQ_DMA2S0 (STM32_IRQ_FIRST+56) /* 56: DMA2 Stream 0 global interrupt */ +#define STM32_IRQ_DMA2S1 (STM32_IRQ_FIRST+57) /* 57: DMA2 Stream 1 global interrupt */ +#define STM32_IRQ_DMA2S2 (STM32_IRQ_FIRST+58) /* 58: DMA2 Stream 2 global interrupt */ +#define STM32_IRQ_DMA2S3 (STM32_IRQ_FIRST+59) /* 59: DMA2 Stream 3 global interrupt */ +#define STM32_IRQ_DMA2S4 (STM32_IRQ_FIRST+60) /* 60: DMA2 Stream 4 global interrupt */ +#define STM32_IRQ_ETH (STM32_IRQ_FIRST+61) /* 61: Ethernet global interrupt */ +#define STM32_IRQ_ETHWKUP (STM32_IRQ_FIRST+62) /* 62: Ethernet Wakeup through EXTI line interrupt */ +#define STM32_IRQ_CAN2TX (STM32_IRQ_FIRST+63) /* 63: CAN2 TX interrupts */ +#define STM32_IRQ_CAN2RX0 (STM32_IRQ_FIRST+64) /* 64: CAN2 RX0 interrupts */ +#define STM32_IRQ_CAN2RX1 (STM32_IRQ_FIRST+65) /* 65: CAN2 RX1 interrupt */ +#define STM32_IRQ_CAN2SCE (STM32_IRQ_FIRST+66) /* 66: CAN2 SCE interrupt */ +#define STM32_IRQ_OTGFS (STM32_IRQ_FIRST+67) /* 67: USB On The Go FS global interrupt */ +#define STM32_IRQ_DMA2S5 (STM32_IRQ_FIRST+68) /* 68: DMA2 Stream 5 global interrupt */ +#define STM32_IRQ_DMA2S6 (STM32_IRQ_FIRST+69) /* 69: DMA2 Stream 6 global interrupt */ +#define STM32_IRQ_DMA2S7 (STM32_IRQ_FIRST+70) /* 70: DMA2 Stream 7 global interrupt */ +#define STM32_IRQ_USART6 (STM32_IRQ_FIRST+71) /* 71: USART6 global interrupt */ +#define STM32_IRQ_I2C3EV (STM32_IRQ_FIRST+72) /* 72: I2C3 event interrupt */ +#define STM32_IRQ_I2C3ER (STM32_IRQ_FIRST+73) /* 73: I2C3 error interrupt */ +#define STM32_IRQ_OTGHSEP1OUT (STM32_IRQ_FIRST+74) /* 74: USB On The Go HS End Point 1 Out global interrupt */ +#define STM32_IRQ_OTGHSEP1IN (STM32_IRQ_FIRST+75) /* 75: USB On The Go HS End Point 1 In global interrupt */ +#define STM32_IRQ_OTGHSWKUP (STM32_IRQ_FIRST+76) /* 76: USB On The Go HS Wakeup through EXTI interrupt */ +#define STM32_IRQ_OTGHS (STM32_IRQ_FIRST+77) /* 77: USB On The Go HS global interrupt */ +#define STM32_IRQ_DCMI (STM32_IRQ_FIRST+78) /* 78: DCMI global interrupt */ +#define STM32_IRQ_CRYP (STM32_IRQ_FIRST+79) /* 79: CRYP crypto global interrupt */ +#define STM32_IRQ_HASH (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ +#define STM32_IRQ_RNG (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ + +#define NR_VECTORS (STM32_IRQ_FIRST+81) +#define NR_IRQS (STM32_IRQ_FIRST+81) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data +****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_STM32F20XXX_IRQ_H */ + diff --git a/arch/arm/include/stm32/stm32f30xxx_irq.h b/arch/arm/include/stm32/stm32f30xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..74c8a279a65ecfad11406d4ee14b0b4b57ee416b --- /dev/null +++ b/arch/arm/include/stm32/stm32f30xxx_irq.h @@ -0,0 +1,195 @@ +/**************************************************************************************************** + * arch/arm/include/stm32s/stm32f30xxx_irq.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32F30XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32F30XXX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper interrupt, or */ +#define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Time stamp interrupt */ +#define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt, or */ +#define STM32_IRQ_TSC (STM32_IRQ_FIRST+8) /* 8: TSC interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32_IRQ_DMA1CH1 (STM32_IRQ_FIRST+11) /* 11: DMA1 channel 1 global interrupt */ +#define STM32_IRQ_DMA1CH2 (STM32_IRQ_FIRST+12) /* 12: DMA1 channel 2 global interrupt */ +#define STM32_IRQ_DMA1CH3 (STM32_IRQ_FIRST+13) /* 13: DMA1 channel 3 global interrupt */ +#define STM32_IRQ_DMA1CH4 (STM32_IRQ_FIRST+14) /* 14: DMA1 channel 4 global interrupt */ +#define STM32_IRQ_DMA1CH5 (STM32_IRQ_FIRST+15) /* 15: DMA1 channel 5 global interrupt */ +#define STM32_IRQ_DMA1CH6 (STM32_IRQ_FIRST+16) /* 16: DMA1 channel 6 global interrupt */ +#define STM32_IRQ_DMA1CH7 (STM32_IRQ_FIRST+17) /* 17: DMA1 channel 7 global interrupt */ +#define STM32_IRQ_ADC12 (STM32_IRQ_FIRST+18) /* 18: ADC1/ADC2 global interrupt */ +#define STM32_IRQ_USBHP_1 (STM32_IRQ_FIRST+19) /* 19: USB High Priority interrupts (not remapped) */ +#define STM32_IRQ_CAN1TX (STM32_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32_IRQ_USBLP_1 (STM32_IRQ_FIRST+20) /* 20: USB Low Priority interrupt (not remapped) */ +#define STM32_IRQ_CAN1RX0 (STM32_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts*/ +#define STM32_IRQ_CAN1RX1 (STM32_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32_IRQ_CAN1SCE (STM32_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32_IRQ_TIM1BRK (STM32_IRQ_FIRST+24) /* 24: TIM1 Break interrupt, or */ +#define STM32_IRQ_TIM15 (STM32_IRQ_FIRST+24) /* 24: TIM15 global interrupt */ +#define STM32_IRQ_TIM1UP (STM32_IRQ_FIRST+25) /* 25: TIM1 Update interrupt, or */ +#define STM32_IRQ_TIM16 (STM32_IRQ_FIRST+25) /* 25: TIM16 global interrupt */ +#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts, or */ +#define STM32_IRQ_TIM17 (STM32_IRQ_FIRST+26) /* 26: TIM17 global interrupt */ +#define STM32_IRQ_TIM1CC (STM32_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt, or */ +#define STM32_IRQ_EXTI23 (STM32_IRQ_FIRST+31) /* 31: EXTI Line23 interrupt */ +#define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt, or */ +#define STM32_IRQ_EXTI24 (STM32_IRQ_FIRST+33) /* 33: EXTI Line24 interrupt */ +#define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt, or */ +#define STM32_IRQ_EXTI25 (STM32_IRQ_FIRST+37) /* 37: EXTI Line 25 interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt, or */ +#define STM32_IRQ_EXTI26 (STM32_IRQ_FIRST+38) /* 38: EXTI Line 26 interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt, or */ +#define STM32_IRQ_EXTI28 (STM32_IRQ_FIRST+39) /* 39: EXTI Line 28 interrupt */ +#define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32_IRQ_USBWKUP_1 (STM32_IRQ_FIRST+42) /* 42: USB wakeup from suspend through EXTI line interrupt */ +#define STM32_IRQ_EXT18 (STM32_IRQ_FIRST+42) /* 42: EXTI Line 18 interrupt */ +#define STM32_IRQ_TIM8BRK (STM32_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32_IRQ_TIM8UP (STM32_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM8CC (STM32_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32_IRQ_ADC3 (STM32_IRQ_FIRST+47) /* 47: ADC3 global interrupt */ +#define STM32_IRQ_RESERVED48 (STM32_IRQ_FIRST+48) /* 48: Reserved */ +#define STM32_IRQ_RESERVED49 (STM32_IRQ_FIRST+49) /* 49: Reserved */ +#define STM32_IRQ_RESERVED50 (STM32_IRQ_FIRST+50) /* 50: Reserved */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST+52) /* 52: UART4 global interrupt, or */ +#define STM32_IRQ_EXTI34 (STM32_IRQ_FIRST+52) /* 52: EXTI Line 34 interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST+53) /* 53: UART5 global interrupt, or */ +#define STM32_IRQ_EXTI35 (STM32_IRQ_FIRST+53) /* 53: EXTI Line 35 interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+54) /* 54: TIM6 global interrupt, or */ +#define STM32_IRQ_DAC (STM32_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32_IRQ_DMA2CH1 (STM32_IRQ_FIRST+56) /* 56: DMA2 channel 1 global interrupt */ +#define STM32_IRQ_DMA2CH2 (STM32_IRQ_FIRST+57) /* 57: DMA2 channel 2 global interrupt */ +#define STM32_IRQ_DMA2CH3 (STM32_IRQ_FIRST+58) /* 58: DMA2 channel 3 global interrupt */ +#define STM32_IRQ_DMA2CH4 (STM32_IRQ_FIRST+59) /* 59: DMA2 channel 4 global interrupt */ +#define STM32_IRQ_DMA2CH5 (STM32_IRQ_FIRST+60) /* 60: DMA2 channel 5 global interrupt */ +#define STM32_IRQ_ADC4 (STM32_IRQ_FIRST+61) /* 61: ADC4 global interrupt */ +#define STM32_IRQ_RESERVED62 (STM32_IRQ_FIRST+62) /* 62: Reserved */ +#define STM32_IRQ_RESERVED63 (STM32_IRQ_FIRST+63) /* 63: Reserved */ +#define STM32_IRQ_COMP123 (STM32_IRQ_FIRST+64) /* 64: COMP1 & COMP2 & COMP3 interrupts, or */ +#define STM32_IRQ_EXTI2129 (STM32_IRQ_FIRST+64) /* 64: EXTI Lines 21, 22 and 29 interrupts */ +#define STM32_IRQ_COMP456 (STM32_IRQ_FIRST+65) /* 65: COMP4 & COMP5 & COMP6 interrupts, or */ +#define STM32_IRQ_EXTI3012 (STM32_IRQ_FIRST+65) /* 65: EXTI Lines 30, 31 and 32 interrupts */ +#define STM32_IRQ_COMP7 (STM32_IRQ_FIRST+66) /* 66: COMP7 interrupt, or */ +#define STM32_IRQ_EXTI33 (STM32_IRQ_FIRST+66) /* 66: EXTI Line 33 interrupt */ +#define STM32_IRQ_RESERVED67 (STM32_IRQ_FIRST+67) /* 67: Reserved */ +#define STM32_IRQ_RESERVED68 (STM32_IRQ_FIRST+68) /* 68: Reserved */ +#define STM32_IRQ_RESERVED69 (STM32_IRQ_FIRST+69) /* 69: Reserved */ +#define STM32_IRQ_RESERVED70 (STM32_IRQ_FIRST+70) /* 70: Reserved */ +#define STM32_IRQ_RESERVED71 (STM32_IRQ_FIRST+71) /* 71: Reserved */ +#define STM32_IRQ_RESERVED72 (STM32_IRQ_FIRST+72) /* 72: Reserved */ +#define STM32_IRQ_RESERVED73 (STM32_IRQ_FIRST+73) /* 73: Reserved */ +#define STM32_IRQ_USBHP_2 (STM32_IRQ_FIRST+74) /* 74: USB High priority interrupt (remapped) */ +#define STM32_IRQ_USBLP_2 (STM32_IRQ_FIRST+75) /* 75: USB Low priority interrupt remapped) */ +#define STM32_IRQ_USBWKUP_2 (STM32_IRQ_FIRST+76) /* 76: USB wakeup from suspend remapped) */ +#define STM32_IRQ_RESERVED77 (STM32_IRQ_FIRST+77) /* 77: Reserved */ +#define STM32_IRQ_RESERVED78 (STM32_IRQ_FIRST+78) /* 78: Reserved */ +#define STM32_IRQ_RESERVED79 (STM32_IRQ_FIRST+79) /* 79: Reserved */ +#define STM32_IRQ_RESERVED80 (STM32_IRQ_FIRST+80) /* 80: Reserved */ +#define STM32_IRQ_FPU (STM32_IRQ_FIRST+81) /* 81: FPU global interrupt */ + +#define NR_VECTORS (STM32_IRQ_FIRST+82) +#define NR_IRQS (STM32_IRQ_FIRST+82) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data +****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_STM32F30XXX_IRQ_H */ + diff --git a/arch/arm/include/stm32/stm32f37xxx_irq.h b/arch/arm/include/stm32/stm32f37xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..22456683bc3bcaae51a78028f9a0395f1d9a6946 --- /dev/null +++ b/arch/arm/include/stm32/stm32f37xxx_irq.h @@ -0,0 +1,181 @@ +/**************************************************************************************************** + * arch/arm/include/stm32s/stm32f37xxx_irq.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32F37XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32F37XXX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper interrupt, or */ +#define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Time stamp interrupt */ +#define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt, or */ +#define STM32_IRQ_TSC (STM32_IRQ_FIRST+8) /* 8: TSC interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32_IRQ_DMA1CH1 (STM32_IRQ_FIRST+11) /* 11: DMA1 channel 1 global interrupt */ +#define STM32_IRQ_DMA1CH2 (STM32_IRQ_FIRST+12) /* 12: DMA1 channel 2 global interrupt */ +#define STM32_IRQ_DMA1CH3 (STM32_IRQ_FIRST+13) /* 13: DMA1 channel 3 global interrupt */ +#define STM32_IRQ_DMA1CH4 (STM32_IRQ_FIRST+14) /* 14: DMA1 channel 4 global interrupt */ +#define STM32_IRQ_DMA1CH5 (STM32_IRQ_FIRST+15) /* 15: DMA1 channel 5 global interrupt */ +#define STM32_IRQ_DMA1CH6 (STM32_IRQ_FIRST+16) /* 16: DMA1 channel 6 global interrupt */ +#define STM32_IRQ_DMA1CH7 (STM32_IRQ_FIRST+17) /* 17: DMA1 channel 7 global interrupt */ +#define STM32_IRQ_ADC1 (STM32_IRQ_FIRST+18) /* 18: ADC1 global interrupt */ +#define STM32_IRQ_CAN1TX (STM32_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32_IRQ_CAN1RX0 (STM32_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts*/ +#define STM32_IRQ_CAN1RX1 (STM32_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32_IRQ_CAN1SCE (STM32_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32_IRQ_TIM15 (STM32_IRQ_FIRST+24) /* 24: TIM15 global interrupt */ +#define STM32_IRQ_TIM16 (STM32_IRQ_FIRST+25) /* 25: TIM16 global interrupt */ +#define STM32_IRQ_TIM17 (STM32_IRQ_FIRST+26) /* 26: TIM17 global interrupt */ +#define STM32_IRQ_TIM18 (STM32_IRQ_FIRST+27) /* 27: TIM18 global interrupt, or */ +#define STM32_IRQ_DAC2 (STM32_IRQ_FIRST+27) /* 27: DAC2 global interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32_IRQ_CEC (STM32_IRQ_FIRST+42) /* 42: CEC Interrupt */ +#define STM32_IRQ_TIM12 (STM32_IRQ_FIRST+43) /* 43: TIM12 global interrupt */ +#define STM32_IRQ_TIM13 (STM32_IRQ_FIRST+44) /* 44: TIM13 global interrupt */ +#define STM32_IRQ_TIM14 (STM32_IRQ_FIRST+45) /* 45: TIM14 global interrupt */ +#define STM32_IRQ_RESERVED46 (STM32_IRQ_FIRST+46) /* 46: Reserved */ +#define STM32_IRQ_RESERVED47 (STM32_IRQ_FIRST+47) /* 47: Reserved */ +#define STM32_IRQ_RESERVED48 (STM32_IRQ_FIRST+48) /* 48: Reserved */ +#define STM32_IRQ_RESERVED49 (STM32_IRQ_FIRST+49) /* 49: Reserved */ +#define STM32_IRQ_RESERVED50 (STM32_IRQ_FIRST+50) /* 50: Reserved */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32_IRQ_RESERVED52 (STM32_IRQ_FIRST+52) /* 52: Reserved */ +#define STM32_IRQ_RESERVED53 (STM32_IRQ_FIRST+53) /* 53: Reserved */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+54) /* 54: TIM6 global interrupt, or */ +#define STM32_IRQ_DAC1 (STM32_IRQ_FIRST+54) /* 54: DAC1 underrun error interrupts */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32_IRQ_DMA2CH1 (STM32_IRQ_FIRST+56) /* 56: DMA2 channel 1 global interrupt */ +#define STM32_IRQ_DMA2CH2 (STM32_IRQ_FIRST+57) /* 57: DMA2 channel 2 global interrupt */ +#define STM32_IRQ_DMA2CH3 (STM32_IRQ_FIRST+58) /* 58: DMA2 channel 3 global interrupt */ +#define STM32_IRQ_DMA2CH4 (STM32_IRQ_FIRST+59) /* 59: DMA2 channel 4 global interrupt */ +#define STM32_IRQ_DMA2CH5 (STM32_IRQ_FIRST+60) /* 60: DMA2 channel 5 global interrupt */ +#define STM32_IRQ_SDADC1 (STM32_IRQ_FIRST+61) /* 61: ADC Sigma Delta 1 global interrupt */ +#define STM32_IRQ_SDADC2 (STM32_IRQ_FIRST+62) /* 62: ADC Sigma Delta 2 global interrupt */ +#define STM32_IRQ_SDADC3 (STM32_IRQ_FIRST+63) /* 63: ADC Sigma Delta 3 global interrupt */ +#define STM32_IRQ_COMP12 (STM32_IRQ_FIRST+64) /* 64: COMP1 & COMP2 interrupts*/ +#define STM32_IRQ_RESERVED65 (STM32_IRQ_FIRST+65) /* 65: Reserved */ +#define STM32_IRQ_RESERVED66 (STM32_IRQ_FIRST+66) /* 66: Reserved */ +#define STM32_IRQ_RESERVED67 (STM32_IRQ_FIRST+67) /* 67: Reserved */ +#define STM32_IRQ_RESERVED68 (STM32_IRQ_FIRST+68) /* 68: Reserved */ +#define STM32_IRQ_RESERVED69 (STM32_IRQ_FIRST+69) /* 69: Reserved */ +#define STM32_IRQ_RESERVED70 (STM32_IRQ_FIRST+70) /* 70: Reserved */ +#define STM32_IRQ_RESERVED71 (STM32_IRQ_FIRST+71) /* 71: Reserved */ +#define STM32_IRQ_RESERVED72 (STM32_IRQ_FIRST+72) /* 72: Reserved */ +#define STM32_IRQ_RESERVED73 (STM32_IRQ_FIRST+73) /* 73: Reserved */ +#define STM32_IRQ_USBHP (STM32_IRQ_FIRST+74) /* 74: USB High priority interrupt */ +#define STM32_IRQ_USBLP (STM32_IRQ_FIRST+75) /* 75: USB Low priority interrupt */ +#define STM32_IRQ_USBWKUP (STM32_IRQ_FIRST+76) /* 76: USB wakeup from suspend */ +#define STM32_IRQ_RESERVED77 (STM32_IRQ_FIRST+77) /* 77: Reserved */ +#define STM32_IRQ_RESERVED78 (STM32_IRQ_FIRST+78) /* 78: Reserved */ +#define STM32_IRQ_RESERVED79 (STM32_IRQ_FIRST+79) /* 79: Reserved */ +#define STM32_IRQ_RESERVED80 (STM32_IRQ_FIRST+80) /* 80: Reserved */ +#define STM32_IRQ_FPU (STM32_IRQ_FIRST+81) /* 81: FPU global interrupt */ + +#define NR_VECTORS (STM32_IRQ_FIRST+82) +#define NR_IRQS (STM32_IRQ_FIRST+82) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data +****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32F30XXX_IRQ_H */ + diff --git a/arch/arm/include/stm32/stm32f40xxx_irq.h b/arch/arm/include/stm32/stm32f40xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b0499b6ba32bf3285545fb89bdc95e743345d0d6 --- /dev/null +++ b/arch/arm/include/stm32/stm32f40xxx_irq.h @@ -0,0 +1,260 @@ +/**************************************************************************************************** + * arch/arm/include/stm32s/stm32f40xxx_irq.h + * + * Copyright (C) 2009, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32F40XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32F40XXX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32_IRQ_DMA1S0 (STM32_IRQ_FIRST+11) /* 11: DMA1 Stream 0 global interrupt */ +#define STM32_IRQ_DMA1S1 (STM32_IRQ_FIRST+12) /* 12: DMA1 Stream 1 global interrupt */ +#define STM32_IRQ_DMA1S2 (STM32_IRQ_FIRST+13) /* 13: DMA1 Stream 2 global interrupt */ +#define STM32_IRQ_DMA1S3 (STM32_IRQ_FIRST+14) /* 14: DMA1 Stream 3 global interrupt */ +#define STM32_IRQ_DMA1S4 (STM32_IRQ_FIRST+15) /* 15: DMA1 Stream 4 global interrupt */ +#define STM32_IRQ_DMA1S5 (STM32_IRQ_FIRST+16) /* 16: DMA1 Stream 5 global interrupt */ +#define STM32_IRQ_DMA1S6 (STM32_IRQ_FIRST+17) /* 17: DMA1 Stream 6 global interrupt */ +#define STM32_IRQ_ADC (STM32_IRQ_FIRST+18) /* 18: ADC1, ADC2, and ADC3 global interrupt */ +#define STM32_IRQ_CAN1TX (STM32_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32_IRQ_CAN1RX0 (STM32_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */ +#define STM32_IRQ_CAN1RX1 (STM32_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32_IRQ_CAN1SCE (STM32_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32_IRQ_TIM1BRK (STM32_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */ +#define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+24) /* 24: TIM9 global interrupt */ +#define STM32_IRQ_TIM1UP (STM32_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */ +#define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+25) /* 25: TIM10 global interrupt */ +#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+26) /* 26: TIM11 global interrupt */ +#define STM32_IRQ_TIM1CC (STM32_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32_IRQ_OTGFSWKUP (STM32_IRQ_FIRST+42) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +#define STM32_IRQ_TIM8BRK (STM32_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32_IRQ_TIM12 (STM32_IRQ_FIRST+43) /* 43: TIM12 global interrupt */ +#define STM32_IRQ_TIM8UP (STM32_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32_IRQ_TIM13 (STM32_IRQ_FIRST+44) /* 44: TIM13 global interrupt */ +#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM14 (STM32_IRQ_FIRST+45) /* 45: TIM14 global interrupt */ +#define STM32_IRQ_TIM8CC (STM32_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32_IRQ_DMA1S7 (STM32_IRQ_FIRST+47) /* 47: DMA1 Stream 7 global interrupt */ +#define STM32_IRQ_FSMC (STM32_IRQ_FIRST+48) /* 48: FSMC global interrupt */ +#define STM32_IRQ_SDIO (STM32_IRQ_FIRST+49) /* 49: SDIO global interrupt */ +#define STM32_IRQ_TIM5 (STM32_IRQ_FIRST+50) /* 50: TIM5 global interrupt */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST+52) /* 52: UART4 global interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST+53) /* 53: UART5 global interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+54) /* 54: TIM6 global interrupt */ +#define STM32_IRQ_DAC (STM32_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32_IRQ_DMA2S0 (STM32_IRQ_FIRST+56) /* 56: DMA2 Stream 0 global interrupt */ +#define STM32_IRQ_DMA2S1 (STM32_IRQ_FIRST+57) /* 57: DMA2 Stream 1 global interrupt */ +#define STM32_IRQ_DMA2S2 (STM32_IRQ_FIRST+58) /* 58: DMA2 Stream 2 global interrupt */ +#define STM32_IRQ_DMA2S3 (STM32_IRQ_FIRST+59) /* 59: DMA2 Stream 3 global interrupt */ +#define STM32_IRQ_DMA2S4 (STM32_IRQ_FIRST+60) /* 60: DMA2 Stream 4 global interrupt */ +#if defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_RESERVED61 (STM32_IRQ_FIRST+61) /* 61: Reserved */ +# define STM32_IRQ_RESERVED62 (STM32_IRQ_FIRST+62) /* 62: Reserved */ +#else +# define STM32_IRQ_ETH (STM32_IRQ_FIRST+61) /* 61: Ethernet global interrupt */ +# define STM32_IRQ_ETHWKUP (STM32_IRQ_FIRST+62) /* 62: Ethernet Wakeup through EXTI line interrupt */ +#endif +#define STM32_IRQ_CAN2TX (STM32_IRQ_FIRST+63) /* 63: CAN2 TX interrupts */ +#define STM32_IRQ_CAN2RX0 (STM32_IRQ_FIRST+64) /* 64: CAN2 RX0 interrupts */ +#define STM32_IRQ_CAN2RX1 (STM32_IRQ_FIRST+65) /* 65: CAN2 RX1 interrupt */ +#define STM32_IRQ_CAN2SCE (STM32_IRQ_FIRST+66) /* 66: CAN2 SCE interrupt */ +#define STM32_IRQ_OTGFS (STM32_IRQ_FIRST+67) /* 67: USB On The Go FS global interrupt */ +#define STM32_IRQ_DMA2S5 (STM32_IRQ_FIRST+68) /* 68: DMA2 Stream 5 global interrupt */ +#define STM32_IRQ_DMA2S6 (STM32_IRQ_FIRST+69) /* 69: DMA2 Stream 6 global interrupt */ +#define STM32_IRQ_DMA2S7 (STM32_IRQ_FIRST+70) /* 70: DMA2 Stream 7 global interrupt */ +#define STM32_IRQ_USART6 (STM32_IRQ_FIRST+71) /* 71: USART6 global interrupt */ +#define STM32_IRQ_I2C3EV (STM32_IRQ_FIRST+72) /* 72: I2C3 event interrupt */ +#define STM32_IRQ_I2C3ER (STM32_IRQ_FIRST+73) /* 73: I2C3 error interrupt */ +#define STM32_IRQ_OTGHSEP1OUT (STM32_IRQ_FIRST+74) /* 74: USB On The Go HS End Point 1 Out global interrupt */ +#define STM32_IRQ_OTGHSEP1IN (STM32_IRQ_FIRST+75) /* 75: USB On The Go HS End Point 1 In global interrupt */ +#define STM32_IRQ_OTGHSWKUP (STM32_IRQ_FIRST+76) /* 76: USB On The Go HS Wakeup through EXTI interrupt */ +#define STM32_IRQ_OTGHS (STM32_IRQ_FIRST+77) /* 77: USB On The Go HS global interrupt */ +#define STM32_IRQ_DCMI (STM32_IRQ_FIRST+78) /* 78: DCMI global interrupt */ +#if defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_RESERVED79 (STM32_IRQ_FIRST+79) /* 79: Reserved */ +# define STM32_IRQ_RESERVED80 (STM32_IRQ_FIRST+80) /* 80: Reserved */ +#else +# define STM32_IRQ_CRYP (STM32_IRQ_FIRST+79) /* 79: CRYP crypto global interrupt */ +# define STM32_IRQ_HASH (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ +# define STM32_IRQ_RNG (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ +#endif +#define STM32_IRQ_FPU (STM32_IRQ_FIRST+81) /* 81: FPU global interrupt */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_UART7 (STM32_IRQ_FIRST+82) /* 82: UART7 interrupt */ +# define STM32_IRQ_UART8 (STM32_IRQ_FIRST+83) /* 83: UART8 interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_RESERVED82 (STM32_IRQ_FIRST+82) /* 82: Reserved */ +# define STM32_IRQ_RESERVED83 (STM32_IRQ_FIRST+83) /* 83: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_SPI4 (STM32_IRQ_FIRST+84) /* 84: SPI4 interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_SPI5 (STM32_IRQ_FIRST+85) /* 85: SPI5 interrupt */ +# define STM32_IRQ_SPI6 (STM32_IRQ_FIRST+86) /* 86: SPI6 interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_RESERVED85 (STM32_IRQ_FIRST+85) /* 85: Reserved */ +# define STM32_IRQ_RESERVED86 (STM32_IRQ_FIRST+86) /* 86: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F446) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_SAI1 (STM32_IRQ_FIRST+87) /* 87: SAI1 interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_LTDCINT (STM32_IRQ_FIRST+88) /* 88: LTDCINT interrupt */ +# define STM32_IRQ_LTDCERRINT (STM32_IRQ_FIRST+89) /* 89: LTDCERRINT interrupt */ +# define STM32_IRQ_DMA2D (STM32_IRQ_FIRST+90) /* 90: DMA2D interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_RESERVED88 (STM32_IRQ_FIRST+88) /* 88: Reserved */ +# define STM32_IRQ_RESERVED89 (STM32_IRQ_FIRST+89) /* 89: Reserved */ +# define STM32_IRQ_RESERVED90 (STM32_IRQ_FIRST+90) /* 90: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_SAI2 (STM32_IRQ_FIRST+91) /* 91: SAI2 Global interrupt */ +# define STM32_IRQ_QUADSPI (STM32_IRQ_FIRST+92) /* 92: QuadSPI Global interrupt */ +#elif defined(CONFIG_STM32_STM32F469) +# define STM32_IRQ_QUADSPI (STM32_IRQ_FIRST+91) /* 92: QuadSPI Global interrupt */ +# define STM32_IRQ_DSI (STM32_IRQ_FIRST+92) /* 91: DSI Global interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define STM32_IRQ_HDMICEC (STM32_IRQ_FIRST+93) /* 93: HDMI-CEC Global interrupt */ +# define STM32_IRQ_SPDIFRX (STM32_IRQ_FIRST+94) /* 94: SPDIF-Rx Global interrupt */ +# define STM32_IRQ_FMPI2C1 (STM32_IRQ_FIRST+95) /* 95: FMPI2C1 event interrupt */ +# define STM32_IRQ_FMPI2C1ERR (STM32_IRQ_FIRST+96) /* 96: FMPI2C1 Error event interrupt */ +#endif + +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) +# define NR_VECTORS (STM32_IRQ_FIRST+82) +# define NR_IRQS (STM32_IRQ_FIRST+82) +#elif defined(CONFIG_STM32_STM32F427) +# define NR_VECTORS (STM32_IRQ_FIRST+87) +# define NR_IRQS (STM32_IRQ_FIRST+87) +#elif defined(CONFIG_STM32_STM32F429) +# define NR_VECTORS (STM32_IRQ_FIRST+91) +# define NR_IRQS (STM32_IRQ_FIRST+91) +#elif defined(CONFIG_STM32_STM32F446) +# define NR_VECTORS (STM32_IRQ_FIRST+97) +# define NR_IRQS (STM32_IRQ_FIRST+97) +#elif defined(CONFIG_STM32_STM32F469) +# define NR_VECTORS (STM32_IRQ_FIRST+93) +# define NR_IRQS (STM32_IRQ_FIRST+93) +#endif + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_STM32F40XXX_IRQ_H */ diff --git a/arch/arm/include/stm32/stm32l15xxx_irq.h b/arch/arm/include/stm32/stm32l15xxx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ca692932f9be8e49f9be0bc23a7f844a3f4f0bba --- /dev/null +++ b/arch/arm/include/stm32/stm32l15xxx_irq.h @@ -0,0 +1,274 @@ +/**************************************************************************************************** + * arch/arm/include/stm32s/stm32l15xxx_irq.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32_STM32FL15XXX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32_STM32FL15XXX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in nuttx/arch/arm/include/stm32/irq.h + * + * External interrupts (vectors >= 16) for low and medium density devices + */ + +#if defined(CONFIG_STM32_LOWDENSITY) || defined(CONFIG_STM32_MEDIUMDENSITY) +# define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper through EXTI line interrupt, or */ +# define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Time stamp through EXTI line interrupt */ +# define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC Wakeup through EXTI line interrupt */ +# define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (STM32_IRQ_FIRST+11) /* 11: DMA1 channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (STM32_IRQ_FIRST+12) /* 12: DMA1 channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (STM32_IRQ_FIRST+13) /* 13: DMA1 channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (STM32_IRQ_FIRST+14) /* 14: DMA1 channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (STM32_IRQ_FIRST+15) /* 15: DMA1 channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (STM32_IRQ_FIRST+16) /* 16: DMA1 channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (STM32_IRQ_FIRST+17) /* 17: DMA1 channel 7 global interrupt */ +# define STM32_IRQ_ADC1 (STM32_IRQ_FIRST+18) /* 18: ADC1 global interrupt */ +# define STM32_IRQ_USBHP (STM32_IRQ_FIRST+19) /* 19: USB High Priority interrupts */ +# define STM32_IRQ_USBLP (STM32_IRQ_FIRST+20) /* 20: USB Low Priority interrupt */ +# define STM32_IRQ_DAC (STM32_IRQ_FIRST+21) /* 21: DAC interrupt */ +# define STM32_IRQ_COMP (STM32_IRQ_FIRST+22) /* 22: Comparator wakeup through EXTI interrupt */ +# define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_LDC (STM32_IRQ_FIRST+24) /* 24: LCD global interrupt */ +# define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+25) /* 25: TIM9 global interrupt */ +# define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+26) /* 26: TIM10 global interrupt */ +# define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+27) /* 27: TIM11 global interrupt */ +# define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +# define STM32_IRQ_USBWKUP (STM32_IRQ_FIRST+42) /* 42: USB wakeup from suspend through EXTI line interrupt */ +# define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+43) /* 43: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+44) /* 44: TIM7 global interrupt */ + +# define NR_VECTORS (STM32_IRQ_FIRST+45) +# define NR_IRQS (STM32_IRQ_FIRST+45) + +/* External interrupts (vectors >= 16) medium+ density devices */ + +#elif defined(CONFIG_STM32_MEDIUMPLUSDENSITY) +# define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper through EXTI line interrupt, or */ +# define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Time stamp through EXTI line interrupt */ +# define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC Wakeup through EXTI line interrupt */ +# define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (STM32_IRQ_FIRST+11) /* 11: DMA1 channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (STM32_IRQ_FIRST+12) /* 12: DMA1 channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (STM32_IRQ_FIRST+13) /* 13: DMA1 channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (STM32_IRQ_FIRST+14) /* 14: DMA1 channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (STM32_IRQ_FIRST+15) /* 15: DMA1 channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (STM32_IRQ_FIRST+16) /* 16: DMA1 channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (STM32_IRQ_FIRST+17) /* 17: DMA1 channel 7 global interrupt */ +# define STM32_IRQ_ADC1 (STM32_IRQ_FIRST+18) /* 18: ADC1 global interrupt */ +# define STM32_IRQ_USBHP (STM32_IRQ_FIRST+19) /* 19: USB High Priority interrupts */ +# define STM32_IRQ_USBLP (STM32_IRQ_FIRST+20) /* 20: USB Low Priority interrupt */ +# define STM32_IRQ_DAC (STM32_IRQ_FIRST+21) /* 21: DAC interrupt */ +# define STM32_IRQ_COMP (STM32_IRQ_FIRST+22) /* 22: Comparator wakeup through EXTI interrupt, or */ +# define STM32_IRQ_CA (STM32_IRQ_FIRST+22) /* 22: Channel acquisition interrupt */ +# define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_LDC (STM32_IRQ_FIRST+24) /* 24: LCD global interrupt */ +# define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+25) /* 25: TIM9 global interrupt */ +# define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+26) /* 26: TIM10 global interrupt */ +# define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+27) /* 27: TIM11 global interrupt */ +# define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +# define STM32_IRQ_USBWKUP (STM32_IRQ_FIRST+42) /* 42: USB wakeup from suspend through EXTI line interrupt */ +# define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+43) /* 43: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+44) /* 44: TIM7 global interrupt */ +# define STM32_IRQ_TIM5 (STM32_IRQ_FIRST+45) /* 45: TIM5 global interrupt */ +# define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+46) /* 46: SPI3 global interrupt */ +# define STM32_IRQ_DMA2CH1 (STM32_IRQ_FIRST+47) /* 47: DMA2 channel 1 global interrupt */ +# define STM32_IRQ_DMA2CH2 (STM32_IRQ_FIRST+48) /* 48: DMA2 channel 2 global interrupt */ +# define STM32_IRQ_DMA2CH3 (STM32_IRQ_FIRST+49) /* 49: DMA2 channel 3 global interrupt */ +# define STM32_IRQ_DMA2CH4 (STM32_IRQ_FIRST+50) /* 50: DMA2 channel 4 global interrupt */ +# define STM32_IRQ_DMA2CH5 (STM32_IRQ_FIRST+51) /* 51: DMA2 channel 5 global interrupt */ +# define STM32_IRQ_AES (STM32_IRQ_FIRST+52) /* 52: AES global interrupt */ +# define STM32_IRQ_COMPACQ (STM32_IRQ_FIRST+53) /* 53: Comparator Channel Acquisition Interrupt */ + +# define NR_VECTORS (STM32_IRQ_FIRST+54) +# define NR_IRQS (STM32_IRQ_FIRST+54) + +/* External interrupts (vectors >= 16) high density devices */ + +#elif defined(CONFIG_STM32_HIGHDENSITY) +# define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +# define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +# define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper through EXTI line interrupt, or */ +# define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Time stamp through EXTI line interrupt */ +# define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC Wakeup through EXTI line interrupt */ +# define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +# define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +# define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +# define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +# define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +# define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +# define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +# define STM32_IRQ_DMA1CH1 (STM32_IRQ_FIRST+11) /* 11: DMA1 channel 1 global interrupt */ +# define STM32_IRQ_DMA1CH2 (STM32_IRQ_FIRST+12) /* 12: DMA1 channel 2 global interrupt */ +# define STM32_IRQ_DMA1CH3 (STM32_IRQ_FIRST+13) /* 13: DMA1 channel 3 global interrupt */ +# define STM32_IRQ_DMA1CH4 (STM32_IRQ_FIRST+14) /* 14: DMA1 channel 4 global interrupt */ +# define STM32_IRQ_DMA1CH5 (STM32_IRQ_FIRST+15) /* 15: DMA1 channel 5 global interrupt */ +# define STM32_IRQ_DMA1CH6 (STM32_IRQ_FIRST+16) /* 16: DMA1 channel 6 global interrupt */ +# define STM32_IRQ_DMA1CH7 (STM32_IRQ_FIRST+17) /* 17: DMA1 channel 7 global interrupt */ +# define STM32_IRQ_ADC1 (STM32_IRQ_FIRST+18) /* 18: ADC1 global interrupt */ +# define STM32_IRQ_USBHP (STM32_IRQ_FIRST+19) /* 19: USB High Priority interrupts */ +# define STM32_IRQ_USBLP (STM32_IRQ_FIRST+20) /* 20: USB Low Priority interrupt */ +# define STM32_IRQ_DAC (STM32_IRQ_FIRST+21) /* 21: DAC interrupt */ +# define STM32_IRQ_COMP (STM32_IRQ_FIRST+22) /* 22: Comparator wakeup through EXTI interrupt, or */ +# define STM32_IRQ_CA (STM32_IRQ_FIRST+22) /* 22: Channel acquisition interrupt */ +# define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +# define STM32_IRQ_LDC (STM32_IRQ_FIRST+24) /* 24: LCD global interrupt */ +# define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+25) /* 25: TIM9 global interrupt */ +# define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+26) /* 26: TIM10 global interrupt */ +# define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+27) /* 27: TIM11 global interrupt */ +# define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +# define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +# define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +# define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +# define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +# define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +# define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +# define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +# define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +# define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +# define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +# define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +# define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +# define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +# define STM32_IRQ_USBWKUP (STM32_IRQ_FIRST+42) /* 42: USB wakeup from suspend through EXTI line interrupt */ +# define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+43) /* 43: TIM6 global interrupt */ +# define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+44) /* 44: TIM7 global interrupt */ +# define STM32_IRQ_SDIO (STM32_IRQ_FIRST+45) /* 45: SDIO Global interrupt */ +# define STM32_IRQ_TIM5 (STM32_IRQ_FIRST+46) /* 46: TIM5 global interrupt */ +# define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+47) /* 47: SPI3 global interrupt */ +# define STM32_IRQ_UART4 (STM32_IRQ_FIRST+48) /* 48: UART4 global interrupt */ +# define STM32_IRQ_UART5 (STM32_IRQ_FIRST+49) /* 49: UART5 global interrupt */ +# define STM32_IRQ_DMA2CH1 (STM32_IRQ_FIRST+50) /* 50: DMA2 channel 1 global interrupt */ +# define STM32_IRQ_DMA2CH2 (STM32_IRQ_FIRST+51) /* 51: DMA2 channel 2 global interrupt */ +# define STM32_IRQ_DMA2CH3 (STM32_IRQ_FIRST+52) /* 52: DMA2 channel 3 global interrupt */ +# define STM32_IRQ_DMA2CH4 (STM32_IRQ_FIRST+53) /* 53: DMA2 channel 4 global interrupt */ +# define STM32_IRQ_DMA2CH5 (STM32_IRQ_FIRST+54) /* 54: DMA2 channel 5 global interrupt */ +# define STM32_IRQ_AES (STM32_IRQ_FIRST+55) /* 55: AES global interrupt */ +# define STM32_IRQ_COMPACQ (STM32_IRQ_FIRST+56) /* 56: Comparator Channel Acquisition Interrupt */ + +# define NR_VECTORS (STM32_IRQ_FIRST+57) +# define NR_IRQS (STM32_IRQ_FIRST+57) +#else +# error "Unknown STM32L density" +#endif + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data +****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32_STM32FL15XXX_IRQ_H */ + diff --git a/arch/arm/include/stm32f7/chip.h b/arch/arm/include/stm32f7/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..372bd1143f4529271932312ce75e3bd89919a2f8 --- /dev/null +++ b/arch/arm/include/stm32f7/chip.h @@ -0,0 +1,200 @@ +/************************************************************************************ + * arch/arm/include/stm32f7/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32F7_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32F7_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* STM32F745xx, STM32F746xx, and STM32F56xx. Differences between family members: + * + * ----------- ---------------- ----- -------- ------------ -------- + * PART PACKAGE GPIOs SPI/I2S ADC CHANNELS LCD-TFT? + * ----------- ---------------- ----- -------- ------------ -------- + * STM32F745Vx LQFP100 82 4/3 16 No + * STM32F745Zx WLCSP143/LQFP144 114 6/3 24 No + * STM32F745Ix UFBGA176/LQFP176 140 6/3 24 No + * STM32F745Bx LQFP208 168 6/3 24 No + * STM32F745Nx TFBGA216 68 6/3 24 No + * + * STM32F746Vx LQFP100 82 4/3 16 Yes + * STM32F746Zx WLCSP143/LQFP144 114 6/3 24 Yes + * STM32F746Ix UFBGA176/LQFP176 140 6/3 24 Yes + * STM32F746Bx LQFP208 168 6/3 24 Yes + * STM32F746Nx TFBGA216 168 6/3 24 Yes + * + * STM32F756Vx LQFP100 82 4/3 16 Yes + * STM32F756Zx WLCSP143/LQFP144 114 6/3 24 Yes + * STM32F756Ix UFBGA176/LQFP176 140 6/3 24 Yes + * STM32F756Bx LQFP208 168 6/3 24 Yes + * STM32F756Nx TFBGA216 168 6/3 24 Yes + * ----------- ---------------- ----- -------- ------------ -------- + * + * Parts STM32F74xxE have 512Kb of FLASH + * Parts STM32F74xxG have 1024Kb of FLASH + * + * The correct FLASH size must be set with a CONFIG_STM32F7_FLASH_*KB + * selection. + */ + +#if defined(CONFIG_ARCH_CHIP_STM32F745) || defined(CONFIG_ARCH_CHIP_STM32F746) || \ + defined(CONFIG_ARCH_CHIP_STM32F756) + +#if defined(CONFIG_ARCH_CHIP_STM32F745) +# define STM32F7_STM32F745XX 1 /* STM32F745xx family */ +# undef STM32F7_STM32F746XX /* Not STM32F746xx family */ +# undef STM32F7_STM32F756XX /* Not STM32F756xx family */ + +# define STM32F7_NLCDTFT 0 /* No LCD-TFT */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F746) + +# undef STM32F7_STM32F745XX /* Not STM32F745xx family */ +# define STM32F7_STM32F746XX 1 /* STM32F746xx family */ +# undef STM32F7_STM32F756XX /* Not STM32F756xx family */ + +# define STM32F7_NLCDTFT 1 /* One LCD-TFT */ + +#else /* if defined(CONFIG_ARCH_CHIP_STM32F746) */ + +# undef STM32F7_STM32F745XX /* Not STM32F745xx family */ +# undef STM32F7_STM32F746XX /* Not STM32F746xx family */ +# define STM32F7_STM32F756XX 1 /* STM32F756xx family */ + +# define STM32F7_NLCDTFT 1 /* One LCD-TFT */ +#endif + +# define STM32F7_SRAM1_SIZE (240*1024) /* 240Kb SRAM1 on AHB bus Matrix */ +# define STM32F7_SRAM2_SIZE (16*1024) /* 16Kb SRAM2 on AHB bus Matrix */ +# define STM32F7_DTCM_SRAM_SIZE (64*1024) /* 64Kb DTCM SRAM on TCM inerface */ +# define STM32F7_ITCM_SRAM_SIZE (16*1024) /* 16Kb ITCM SRAM on TCM inerface */ + +# define STM32F7_NFSMC 1 /* Have FSMC memory controller */ +# define STM32F7_NETHERNET 1 /* 100/100 Ethernet MAC */ +# define STM32F7_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32F7_NGTIM32 2 /* 32-bit general timers TIM2 and 5 with DMA */ +# define STM32F7_NGTIM16 2 /* 16-bit general timers TIM3 and 4 with DMA */ +# define STM32F7_NGTIMNDMA 6 /* 16-bit general timers TIM9-14 without DMA */ +# define STM32F7_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32F7_NRNG 1 /* Random number generator (RNG) */ +# define STM32F7_NUART 4 /* UART 4-5 and 7-8 */ +# define STM32F7_NUSART 4 /* USART1-3 and 6 */ +# define STM32F7_NSPI 6 /* SPI1-6 (Except V series) */ +# define STM32F7_NI2S 3 /* I2S1-2 (multiplexed with SPI1-3) */ +# define STM32F7_NI2C 4 /* I2C1-4 */ +# define STM32F7_NUSBOTGFS 1 /* USB OTG FS */ +# define STM32F7_NUSBOTGHS 1 /* USB OTG HS */ +# define STM32F7_NCAN 2 /* CAN1-2 */ +# define STM32F7_NSAI 2 /* SAI1-2 */ +# define STM32F7_NSPDIFRX 4 /* 4 SPDIFRX inputs */ +# define STM32F7_NSDMMC 1 /* SDMMC interface */ +# define STM32F7_NDCMI 1 /* Digital camera interface (DCMI) */ +# define STM32F7_NDMA 2 /* DMA1-2 */ +# define STM32F7_NDMA2D 1 /* DChrom-ART Acceleratorâ„¢ (DMA2D) */ +# define STM32F7_NGPIO 11 /* 11 GPIO ports, GPIOA-K */ +# define STM32F7_NADC 3 /* 12-bit ADC1-3, 24 channels *except V series) */ +# define STM32F7_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32F7_NCAPSENSE 0 /* No capacitive sensing channels */ +# define STM32F7_NCRC 1 /* CRC */ + +#else +# error STM32 F7 chip not identified +#endif + +/* NVIC priority levels *************************************************************/ +/* 16 Programmable interrupt levels */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32F7_CHIP_H */ diff --git a/arch/arm/include/stm32f7/irq.h b/arch/arm/include/stm32f7/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..5a5c710803668cca2b371ceaca5c60d89b510c5a --- /dev/null +++ b/arch/arm/include/stm32f7/irq.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/include/stm32f7/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32F7_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32F7_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define STM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define STM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define STM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define STM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define STM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define STM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define STM32_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define STM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define STM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define STM32_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define STM32_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include +#else +# error "Unsupported STM32 F7 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32F7_IRQ_H */ + diff --git a/arch/arm/include/stm32f7/stm32f74xx75xx_irq.h b/arch/arm/include/stm32f7/stm32f74xx75xx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..24c792ee6a66f801a186bdb608c2818e4f4f0660 --- /dev/null +++ b/arch/arm/include/stm32f7/stm32f74xx75xx_irq.h @@ -0,0 +1,203 @@ +/**************************************************************************************************** + * arch/arm/include/stm32f7/stm32f74xx75xx_irq.h.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through arch/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32F7_STM32F74XX75XX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32F7_STM32F74XX75XX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to bits in the + * NVIC. This does, however, waste several words of memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found in the file + * nuttx/arch/arm/include/stm32f7/irq.h which includes this file + * + * External interrupts (vectors >= 16) + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD (STM32_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32_IRQ_TAMPER (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_TIMESTAMP (STM32_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32_IRQ_RTC_WKUP (STM32_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32_IRQ_DMA1S0 (STM32_IRQ_FIRST+11) /* 11: DMA1 Stream 0 global interrupt */ +#define STM32_IRQ_DMA1S1 (STM32_IRQ_FIRST+12) /* 12: DMA1 Stream 1 global interrupt */ +#define STM32_IRQ_DMA1S2 (STM32_IRQ_FIRST+13) /* 13: DMA1 Stream 2 global interrupt */ +#define STM32_IRQ_DMA1S3 (STM32_IRQ_FIRST+14) /* 14: DMA1 Stream 3 global interrupt */ +#define STM32_IRQ_DMA1S4 (STM32_IRQ_FIRST+15) /* 15: DMA1 Stream 4 global interrupt */ +#define STM32_IRQ_DMA1S5 (STM32_IRQ_FIRST+16) /* 16: DMA1 Stream 5 global interrupt */ +#define STM32_IRQ_DMA1S6 (STM32_IRQ_FIRST+17) /* 17: DMA1 Stream 6 global interrupt */ +#define STM32_IRQ_ADC (STM32_IRQ_FIRST+18) /* 18: ADC1, ADC2, and ADC3 global interrupt */ +#define STM32_IRQ_CAN1TX (STM32_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32_IRQ_CAN1RX0 (STM32_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */ +#define STM32_IRQ_CAN1RX1 (STM32_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32_IRQ_CAN1SCE (STM32_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32_IRQ_EXTI95 (STM32_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32_IRQ_TIM1BRK (STM32_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */ +#define STM32_IRQ_TIM9 (STM32_IRQ_FIRST+24) /* 24: TIM9 global interrupt */ +#define STM32_IRQ_TIM1UP (STM32_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */ +#define STM32_IRQ_TIM10 (STM32_IRQ_FIRST+25) /* 25: TIM10 global interrupt */ +#define STM32_IRQ_TIM1TRGCOM (STM32_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM11 (STM32_IRQ_FIRST+26) /* 26: TIM11 global interrupt */ +#define STM32_IRQ_TIM1CC (STM32_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32_IRQ_I2C1EV (STM32_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32_IRQ_I2C1ER (STM32_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32_IRQ_I2C2EV (STM32_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32_IRQ_I2C2ER (STM32_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32_IRQ_EXTI1510 (STM32_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32_IRQ_RTCALRM (STM32_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32_IRQ_OTGFSWKUP (STM32_IRQ_FIRST+42) /* 42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +#define STM32_IRQ_TIM8BRK (STM32_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32_IRQ_TIM12 (STM32_IRQ_FIRST+43) /* 43: TIM12 global interrupt */ +#define STM32_IRQ_TIM8UP (STM32_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32_IRQ_TIM13 (STM32_IRQ_FIRST+44) /* 44: TIM13 global interrupt */ +#define STM32_IRQ_TIM8TRGCOM (STM32_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32_IRQ_TIM14 (STM32_IRQ_FIRST+45) /* 45: TIM14 global interrupt */ +#define STM32_IRQ_TIM8CC (STM32_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32_IRQ_DMA1S7 (STM32_IRQ_FIRST+47) /* 47: DMA1 Stream 7 global interrupt */ +#define STM32_IRQ_FSMC (STM32_IRQ_FIRST+48) /* 48: FSMC global interrupt */ +#define STM32_IRQ_SDMMC1 (STM32_IRQ_FIRST+49) /* 49: SDMMC1 global interrupt */ +#define STM32_IRQ_TIM5 (STM32_IRQ_FIRST+50) /* 50: TIM5 global interrupt */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST+52) /* 52: UART4 global interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST+53) /* 53: UART5 global interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST+54) /* 54: TIM6 global interrupt */ +#define STM32_IRQ_DAC (STM32_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32_IRQ_DMA2S0 (STM32_IRQ_FIRST+56) /* 56: DMA2 Stream 0 global interrupt */ +#define STM32_IRQ_DMA2S1 (STM32_IRQ_FIRST+57) /* 57: DMA2 Stream 1 global interrupt */ +#define STM32_IRQ_DMA2S2 (STM32_IRQ_FIRST+58) /* 58: DMA2 Stream 2 global interrupt */ +#define STM32_IRQ_DMA2S3 (STM32_IRQ_FIRST+59) /* 59: DMA2 Stream 3 global interrupt */ +#define STM32_IRQ_DMA2S4 (STM32_IRQ_FIRST+60) /* 60: DMA2 Stream 4 global interrupt */ +#define STM32_IRQ_ETH (STM32_IRQ_FIRST+61) /* 61: Ethernet global interrupt */ +#define STM32_IRQ_ETHWKUP (STM32_IRQ_FIRST+62) /* 62: Ethernet Wakeup through EXTI line interrupt */ +#define STM32_IRQ_CAN2TX (STM32_IRQ_FIRST+63) /* 63: CAN2 TX interrupts */ +#define STM32_IRQ_CAN2RX0 (STM32_IRQ_FIRST+64) /* 64: CAN2 RX0 interrupts */ +#define STM32_IRQ_CAN2RX1 (STM32_IRQ_FIRST+65) /* 65: CAN2 RX1 interrupt */ +#define STM32_IRQ_CAN2SCE (STM32_IRQ_FIRST+66) /* 66: CAN2 SCE interrupt */ +#define STM32_IRQ_OTGFS (STM32_IRQ_FIRST+67) /* 67: USB On The Go FS global interrupt */ +#define STM32_IRQ_DMA2S5 (STM32_IRQ_FIRST+68) /* 68: DMA2 Stream 5 global interrupt */ +#define STM32_IRQ_DMA2S6 (STM32_IRQ_FIRST+69) /* 69: DMA2 Stream 6 global interrupt */ +#define STM32_IRQ_DMA2S7 (STM32_IRQ_FIRST+70) /* 70: DMA2 Stream 7 global interrupt */ +#define STM32_IRQ_USART6 (STM32_IRQ_FIRST+71) /* 71: USART6 global interrupt */ +#define STM32_IRQ_I2C3EV (STM32_IRQ_FIRST+72) /* 72: I2C3 event interrupt */ +#define STM32_IRQ_I2C3ER (STM32_IRQ_FIRST+73) /* 73: I2C3 error interrupt */ +#define STM32_IRQ_OTGHSEP1OUT (STM32_IRQ_FIRST+74) /* 74: USB On The Go HS End Point 1 Out global interrupt */ +#define STM32_IRQ_OTGHSEP1IN (STM32_IRQ_FIRST+75) /* 75: USB On The Go HS End Point 1 In global interrupt */ +#define STM32_IRQ_OTGHSWKUP (STM32_IRQ_FIRST+76) /* 76: USB On The Go HS Wakeup through EXTI interrupt */ +#define STM32_IRQ_OTGHS (STM32_IRQ_FIRST+77) /* 77: USB On The Go HS global interrupt */ +#define STM32_IRQ_DCMI (STM32_IRQ_FIRST+78) /* 78: DCMI global interrupt */ +#define STM32_IRQ_CRYP (STM32_IRQ_FIRST+79) /* 79: CRYP crypto global interrupt */ +#define STM32_IRQ_HASH (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ +#define STM32_IRQ_RNG (STM32_IRQ_FIRST+80) /* 80: Hash and Rng global interrupt */ +#define STM32_IRQ_FPU (STM32_IRQ_FIRST+81) /* 81: FPU global interrupt */ +#define STM32_IRQ_UART7 (STM32_IRQ_FIRST+82) /* 82: UART7 global interrupt */ +#define STM32_IRQ_UART8 (STM32_IRQ_FIRST+83) /* 83: UART8 global interrupt */ +#define STM32_IRQ_SPI4 (STM32_IRQ_FIRST+84) /* 84: SPI4 global interrupt */ +#define STM32_IRQ_SPI5 (STM32_IRQ_FIRST+85) /* 85: SPI5 global interrupt */ +#define STM32_IRQ_SPI6 (STM32_IRQ_FIRST+86) /* 86: SPI6 global interrupt */ +#define STM32_IRQ_SAI1 (STM32_IRQ_FIRST+87) /* 87: SAI1 global interrupt */ +#define STM32_IRQ_LTDCINT (STM32_IRQ_FIRST+88) /* 88: LCD-TFT global interrupt */ +#define STM32_IRQ_LTDCERRINT (STM32_IRQ_FIRST+89) /* 89: LCD-TFT global Error interrupt */ +#define STM32_IRQ_DMA2D (STM32_IRQ_FIRST+90) /* 90: DMA2D global interrupt */ +#define STM32_IRQ_SAI2 (STM32_IRQ_FIRST+91) /* 91: SAI2 global interrupt */ +#define STM32_IRQ_QUADSPI (STM32_IRQ_FIRST+92) /* 92: QuadSPI global interrupt */ +#define STM32_IRQ_LPTIMER1 (STM32_IRQ_FIRST+93) /* 93: LP Timer1 global interrupt */ +#define STM32_IRQ_HDMICEC (STM32_IRQ_FIRST+94) /* 94: HDMI-CEC global interrupt */ +#define STM32_IRQ_I2C4EV (STM32_IRQ_FIRST+95) /* 95: I2C4 event interrupt */ +#define STM32_IRQ_I2C4ER (STM32_IRQ_FIRST+96) /* 96: I2C4 Error interrupt */ +#define STM32_IRQ_SPDIFRX (STM32_IRQ_FIRST+97) /* 97: SPDIFRX global interrupt */ + +#define NR_INTERRUPTS 98 +#define NR_VECTORS (STM32_IRQ_FIRST+NR_INTERRUPTS) + +/* EXTI interrupts (Do not use IRQ numbers) */ + +#define NR_IRQS NR_VECTORS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32F7_STM32F74XX75XX_IRQ_H */ + diff --git a/arch/arm/include/stm32l4/chip.h b/arch/arm/include/stm32l4/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..12d718764060f81070e5897e5b8cd95a2e426531 --- /dev/null +++ b/arch/arm/include/stm32l4/chip.h @@ -0,0 +1,154 @@ +/************************************************************************************ + * arch/arm/include/stm32l4/chip.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32L4_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32L4_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* STM32F476, STM32F486. Differences between family members: 486 has AES. + * + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * PART PACKAGE GPIOs LCD Tamper FSMC CapS AdcCh + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * STM32L4x6Jx WLCSP72L 57 8x28 2 No 12 16 + * STM32L476Mx WLCSP81L 65 ? ? ? ? ? + * STM32L4x6Qx UFBGA132L 109 8x40 3 Yes 24 16 + * STM32L4x6Rx LQFP64 51 8x28 2 No 12 16 + * STM32L4x6Vx LQFP100 82 8x40 3 Yes 21 16 + * STM32L4x6Zx LQFP144 114 8x40 3 Yes 24 24 + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * + * Parts STM32L4x6xC have 256Kb of FLASH + * Parts STM32L4x6xE have 512Kb of FLASH + * Parts STM32L4x6xG have 1024Kb of FLASH + * + * The correct FLASH size must be set with a CONFIG_STM32L4_FLASH_*KB + * selection. + */ + +# define STM32L4_SRAM1_SIZE (96*1024) /* 96Kb SRAM1 on AHB bus Matrix */ +# define STM32L4_SRAM2_SIZE (32*1024) /* 32Kb SRAM2 on AHB bus Matrix */ + +# define STM32L4_NFSMC 1 /* Have FSMC memory controller */ +# define STM32L4_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32L4_NGTIM32 2 /* 32-bit general timers TIM2 and 5 with DMA */ +# define STM32L4_NGTIM16 2 /* 16-bit general timers TIM3 and 4 with DMA */ +# define STM32L4_NGTIMNDMA 3 /* 16-bit general timers TIM15-17 without DMA */ +# define STM32L4_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32L4_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */ +# define STM32L4_NRNG 1 /* Random number generator (RNG) */ +# define STM32L4_NUART 4 /* UART 4-5 */ +# define STM32L4_NUSART 3 /* USART 1-3 */ +# define STM32L4_NLPUART 1 /* LPUART 1 */ +# define STM32L4_NSPI 3 /* SPI1-3 */ +# define STM32L4_NI2C 3 /* I2C1-3 */ +# define STM32L4_NUSBOTGFS 1 /* USB OTG FS */ +# define STM32L4_NCAN 1 /* CAN1 */ +# define STM32L4_NSAI 2 /* SAI1-2 */ +# define STM32L4_NSDMMC 1 /* SDMMC interface */ +# define STM32L4_NDMA 2 /* DMA1-2 */ +# define STM32L4_NPORTS 8 /* 8 GPIO ports, GPIOA-H */ +# define STM32L4_NADC 3 /* 12-bit ADC1-3, 24 channels *except V series) */ +# define STM32L4_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32L4_NCRC 1 /* CRC */ +# define STM32L4_NCOMP 2 /* Comparators */ +# define STM32L4_NOPAMP 2 /* Operational Amplifiers */ + +/* NVIC priority levels *************************************************************/ +/* 16 Programmable interrupt levels */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the irqsave() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_CHIP_H */ diff --git a/arch/arm/include/stm32l4/irq.h b/arch/arm/include/stm32l4/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ebfb22667891d9084a91b3b87ee0afed7db0a55f --- /dev/null +++ b/arch/arm/include/stm32l4/irq.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/include/stm32l4/irq.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32L4_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32L4_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define STM32L4_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define STM32L4_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define STM32L4_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define STM32L4_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define STM32L4_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define STM32L4_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define STM32L4_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define STM32L4_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define STM32L4_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define STM32L4_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define STM32L4_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include +#else +# error "Unsupported STM32 L4 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_IRQ_H */ + diff --git a/arch/arm/include/stm32l4/stm32l4x6xx_irq.h b/arch/arm/include/stm32l4/stm32l4x6xx_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..c992ed942fad96b0706771550768ee2a5fc9a50d --- /dev/null +++ b/arch/arm/include/stm32l4/stm32l4x6xx_irq.h @@ -0,0 +1,183 @@ +/**************************************************************************************************** + * arch/arm/include/stm32l4/stm32l4x6xx_irq.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through arch/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to bits in the + * NVIC. This does, however, waste several words of memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found in the file + * nuttx/arch/arm/include/stm32f7/irq.h which includes this file + * + * External interrupts (vectors >= 16) + */ + +#define STM32L4_IRQ_WWDG (STM32L4_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32L4_IRQ_PVD (STM32L4_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32L4_IRQ_TAMPER (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32L4_IRQ_TIMESTAMP (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32L4_IRQ_RTC_WKUP (STM32L4_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32L4_IRQ_FLASH (STM32L4_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32L4_IRQ_RCC (STM32L4_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32L4_IRQ_EXTI0 (STM32L4_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32L4_IRQ_EXTI1 (STM32L4_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32L4_IRQ_EXTI2 (STM32L4_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +#define STM32L4_IRQ_EXTI3 (STM32L4_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32L4_IRQ_EXTI4 (STM32L4_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32L4_IRQ_DMA1CH1 (STM32L4_IRQ_FIRST+11) /* 12: DMA1 Channel 1 global interrupt */ +#define STM32L4_IRQ_DMA1CH2 (STM32L4_IRQ_FIRST+12) /* 13: DMA1 Channel 2 global interrupt */ +#define STM32L4_IRQ_DMA1CH3 (STM32L4_IRQ_FIRST+13) /* 14: DMA1 Channel 3 global interrupt */ +#define STM32L4_IRQ_DMA1CH4 (STM32L4_IRQ_FIRST+14) /* 15: DMA1 Channel 4 global interrupt */ +#define STM32L4_IRQ_DMA1CH5 (STM32L4_IRQ_FIRST+15) /* 16: DMA1 Channel 5 global interrupt */ +#define STM32L4_IRQ_DMA1CH6 (STM32L4_IRQ_FIRST+16) /* 17: DMA1 Channel 6 global interrupt */ +#define STM32L4_IRQ_DMA1CH7 (STM32L4_IRQ_FIRST+17) /* 17: DMA1 Channel 7 global interrupt */ +#define STM32L4_IRQ_ADC12 (STM32L4_IRQ_FIRST+18) /* 18: ADC1 and ADC2 global interrupt */ +#define STM32L4_IRQ_CAN1TX (STM32L4_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32L4_IRQ_CAN1RX0 (STM32L4_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */ +#define STM32L4_IRQ_CAN1RX1 (STM32L4_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32L4_IRQ_CAN1SCE (STM32L4_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32L4_IRQ_EXTI95 (STM32L4_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32L4_IRQ_TIM1BRK (STM32L4_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */ +#define STM32L4_IRQ_TIM15 (STM32L4_IRQ_FIRST+24) /* 24: TIM15 global interrupt */ +#define STM32L4_IRQ_TIM1UP (STM32L4_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */ +#define STM32L4_IRQ_TIM16 (STM32L4_IRQ_FIRST+25) /* 25: TIM16 global interrupt */ +#define STM32L4_IRQ_TIM1TRGCOM (STM32L4_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */ +#define STM32L4_IRQ_TIM17 (STM32L4_IRQ_FIRST+26) /* 26: TIM17 global interrupt */ +#define STM32L4_IRQ_TIM1CC (STM32L4_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32L4_IRQ_TIM2 (STM32L4_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32L4_IRQ_TIM3 (STM32L4_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32L4_IRQ_TIM4 (STM32L4_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32L4_IRQ_I2C1EV (STM32L4_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32L4_IRQ_I2C1ER (STM32L4_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32L4_IRQ_I2C2EV (STM32L4_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32L4_IRQ_I2C2ER (STM32L4_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32L4_IRQ_SPI1 (STM32L4_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32L4_IRQ_SPI2 (STM32L4_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32L4_IRQ_USART1 (STM32L4_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32L4_IRQ_USART2 (STM32L4_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32L4_IRQ_USART3 (STM32L4_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32L4_IRQ_EXTI1510 (STM32L4_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32L4_IRQ_RTCALRM (STM32L4_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32L4_IRQ_DFSDM3 (STM32L4_IRQ_FIRST+42) /* 42: Digital Filter / Sigma Delta Modulator interrupt */ +#define STM32L4_IRQ_TIM8BRK (STM32L4_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32L4_IRQ_TIM8UP (STM32L4_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32L4_IRQ_TIM8TRGCOM (STM32L4_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32L4_IRQ_TIM8CC (STM32L4_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32L4_IRQ_ADC3 (STM32L4_IRQ_FIRST+47) /* 47: ADC3 global interrupt */ +#define STM32L4_IRQ_FSMC (STM32L4_IRQ_FIRST+48) /* 48: FSMC global interrupt */ +#define STM32L4_IRQ_SDMMC1 (STM32L4_IRQ_FIRST+49) /* 49: SDMMC1 global interrupt */ +#define STM32L4_IRQ_TIM5 (STM32L4_IRQ_FIRST+50) /* 50: TIM5 global interrupt */ +#define STM32L4_IRQ_SPI3 (STM32L4_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32L4_IRQ_UART4 (STM32L4_IRQ_FIRST+52) /* 52: UART4 global interrupt */ +#define STM32L4_IRQ_UART5 (STM32L4_IRQ_FIRST+53) /* 53: UART5 global interrupt */ +#define STM32L4_IRQ_TIM6 (STM32L4_IRQ_FIRST+54) /* 54: TIM6 global interrupt */ +#define STM32L4_IRQ_DAC (STM32L4_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32L4_IRQ_TIM7 (STM32L4_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32L4_IRQ_DMA2CH1 (STM32L4_IRQ_FIRST+56) /* 56: DMA2 Channel 1 global interrupt */ +#define STM32L4_IRQ_DMA2CH2 (STM32L4_IRQ_FIRST+57) /* 57: DMA2 Channel 2 global interrupt */ +#define STM32L4_IRQ_DMA2CH3 (STM32L4_IRQ_FIRST+58) /* 58: DMA2 Channel 3 global interrupt */ +#define STM32L4_IRQ_DMA2CH4 (STM32L4_IRQ_FIRST+59) /* 59: DMA2 Channel 4 global interrupt */ +#define STM32L4_IRQ_DMA2CH5 (STM32L4_IRQ_FIRST+60) /* 60: DMA2 Channel 5 global interrupt */ +#define STM32L4_IRQ_DFSDM0 (STM32L4_IRQ_FIRST+61) /* 61: DFSDM0 global interrupt */ +#define STM32L4_IRQ_DFSDM1 (STM32L4_IRQ_FIRST+62) /* 62: DFSDM1 global interrupt*/ +#define STM32L4_IRQ_DFSDM2 (STM32L4_IRQ_FIRST+63) /* 63: DFSDM2 global interrupt */ +#define STM32L4_IRQ_COMP (STM32L4_IRQ_FIRST+64) /* 64: COMP1/COMP2 interrupts */ +#define STM32L4_IRQ_LPTIM1 (STM32L4_IRQ_FIRST+65) /* 65: LPTIM1 global interrupt */ +#define STM32L4_IRQ_LPTIM2 (STM32L4_IRQ_FIRST+66) /* 66: LPTIM2 global interrupt */ +#define STM32L4_IRQ_OTGFS (STM32L4_IRQ_FIRST+67) /* 67: USB On The Go FS global interrupt */ +#define STM32L4_IRQ_DMA2CH6 (STM32L4_IRQ_FIRST+68) /* 68: DMA2 Channel 6 global interrupt */ +#define STM32L4_IRQ_DMA2CH7 (STM32L4_IRQ_FIRST+69) /* 69: DMA2 Channel 7 global interrupt */ +#define STM32L4_IRQ_LPUART1 (STM32L4_IRQ_FIRST+70) /* 70: Low power UART 1 global interrupt */ +#define STM32L4_IRQ_QUADSPI (STM32L4_IRQ_FIRST+71) /* 71: QUADSPI global interrupt */ +#define STM32L4_IRQ_I2C3EV (STM32L4_IRQ_FIRST+72) /* 72: I2C3 event interrupt */ +#define STM32L4_IRQ_I2C3ER (STM32L4_IRQ_FIRST+73) /* 73: I2C3 error interrupt */ +#define STM32L4_IRQ_SAI1 (STM32L4_IRQ_FIRST+74) /* 74: SAI1 global interrupt */ +#define STM32L4_IRQ_SAI2 (STM32L4_IRQ_FIRST+75) /* 75: SAI2 global interrupt */ +#define STM32L4_IRQ_SWPMI1 (STM32L4_IRQ_FIRST+76) /* 76: SWPMI1 global interrupt */ +#define STM32L4_IRQ_TSC (STM32L4_IRQ_FIRST+77) /* 77: TSC global interrupt */ +#define STM32L4_IRQ_LCD (STM32L4_IRQ_FIRST+78) /* 78: LCD global interrupt */ +#define STM32L4_IRQ_AES (STM32L4_IRQ_FIRST+79) /* 79: AES crypto global interrupt */ +#define STM32L4_IRQ_RNG (STM32L4_IRQ_FIRST+80) /* 80: Rng global interrupt */ +#define STM32L4_IRQ_FPU (STM32L4_IRQ_FIRST+81) /* 81: FPU global interrupt */ + +#define NR_INTERRUPTS 82 +#define NR_VECTORS (STM32L4_IRQ_FIRST+NR_INTERRUPTS) + +/* EXTI interrupts (Do not use IRQ numbers) */ + +#define NR_IRQS NR_VECTORS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H */ diff --git a/arch/arm/include/str71x/irq.h b/arch/arm/include/str71x/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..08f64d4706dfcceb52073b3a8638aec66c51b49c --- /dev/null +++ b/arch/arm/include/str71x/irq.h @@ -0,0 +1,152 @@ +/************************************************************************************ + * arch/arm/include/str71x/irq.h + * + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STR71X_IRQ_H +#define __ARCH_ARM_INCLUDE_STR71X_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ channels */ + +#define STR71X_IRQ_T0TIMI (0) /* IRQ 0: T0.EFTI Timer 0 global interrupt */ +#define STR71X_IRQ_FLASH (1) /* IRQ 1: FLASH FLASH global interrupt */ +#define STR71X_IRQ_RCCU (2) /* IRQ 2: PRCCU PRCCU global interrupt */ +#define STR71X_IRQ_RTC (3) /* IRQ 3: RTC Real Time Clock global interrupt */ +#define STR71X_IRQ_WDG (4) /* IRQ 4: WDG.IRQ Watchdog timer interrupt */ +#define STR71X_IRQ_XTI (5) /* IRQ 5: XTI.IRQ XTI external interrupt */ +#define STR71X_IRQ_USBHP (6) /* IRQ 6: USB.HPIRQ USB high priority event interrupt */ +#define STR71X_IRQ_I2C0ITERR (7) /* IRQ 7: I2C0.ITERR I2C 0 error interrupt */ +#define STR71X_IRQ_I2C1ITERR (8) /* IRQ 8: I2C1.ITERR I2C 1 error interrupt */ +#define STR71X_IRQ_UART0 (9) /* IRQ 9: UART0.IRQ UART 0 global interrupt */ +#define STR71X_IRQ_UART1 (10) /* IRQ 10: UART1.IRQ UART 1 global interrupt */ +#define STR71X_IRQ_UART2 (11) /* IRQ 11: UART2.IRQ UART 2 global interrupt */ +#define STR71X_IRQ_UART3 (12) /* IRQ 12: UART3.IRQ UART 3 global interrupt */ +#define STR71X_IRQ_SPI0 (13) /* IRQ 13: BSPI0.IRQ BSPI 0 global interrupt */ +#define STR71X_IRQ_SPI1 (14) /* IRQ 14: BSPI1.IRQ BSPI 1 global interrupt */ +#define STR71X_IRQ_I2C0 (15) /* IRQ 15: I2C0.IRQ I2C 0 tx/rx interrupt */ +#define STR71X_IRQ_I2C1 (16) /* IRQ 16: I2C1.IRQ I2C 1 tx/rx interrupt */ +#define STR71X_IRQ_CAN (17) /* IRQ 17: CAN.IRQ CAN module global interrupt */ +#define STR71X_IRQ_ADC (18) /* IRQ 18: ADC.IRQ ADC sample ready interrupt */ +#define STR71X_IRQ_T1TIMI (19) /* IRQ 19: T1.GI Timer 1 global interrupt */ +#define STR71X_IRQ_T2TIMI (20) /* IRQ 20: T2.GI Timer 2 global interrupt */ +#define STR71X_IRQ_T3TIMI (21) /* IRQ 21: T3.GI Timer 3 global interrupt */ + /* IRQ 22-24: Reserved */ +#define STR71X_IRQ_HDLC (25) /* IRQ 25: HDLC.IRQ HDLC global interrupt */ +#define STR71X_IRQ_USBLP (26) /* IRQ 26: USB.LPIRQ USB low priority event interrupt */ + /* IRQ 27-28: Reserved */ +#define STR71X_IRQ_T0TOI (29) /* IRQ 29: T0.TOI Timer 0 Overflow interrupt */ +#define STR71X_IRQ_T0OC1 (30) /* IRQ 30: T0.OCMPA Timer 0 Output Compare A interrupt */ +#define STR71X_IRQ_T0OC2 (31) /* IRQ 31: T0.OCMPB Timer 0 Output Compare B interrupt */ + +#define STR71X_NBASEIRQS (32) + +#ifdef CONFIG_STR71X_XTI +# define STR71X_IRQ_FIRSTXTI (32) +# define STR71X_IRQ_SW (32) /* Line 0: SW interrupt - no HW connection */ +# define STR71X_IRQ_USBWKUP (33) /* Line 1: USB wake-up event: generated while exiting + * from suspend mode */ +# define STR71X_IRQ_PORT2p8 (34) /* Line 2: Port 2.8 - External Interrupt */ +# define STR71X_IRQ_PORT2p9 (35) /* Line 3: Port 2.9 - External Interrupt */ +# define STR71X_IRQ_PORT2p10 (36) /* Line 4: Port 2.10 - External Interrupt */ +# define STR71X_IRQ_PORT2p11 (37) /* Line 5: Port 2.11 - External Interrupt */ +# define STR71X_IRQ_PORT1p11 (38) /* Line 6: Port 1.11 - CAN module receive pin (CANRX). */ +# define STR71X_IRQ_PORT1p13 (39) /* Line 7: Port 1.13 - HDLC clock (HCLK) or I2C.0 Clock + * (I0.SCL) */ +# define STR71X_IRQ_PORT1p14 (40) /* Line 8: Port 1.14 - HDLC receive pin (HRXD) or I2C.0 + * Data (SDA) */ +# define STR71X_IRQ_PORT0p1 (41) /* Line 9: Port 0.1 - BSPI0 Slave Input data (S0.MOSI) + * or UART3 Receive Data Input (U3.Rx) */ +# define STR71X_IRQ_PORT0p2 (42) /* Line 10: Port 0.2 - BSPI0 Slave Input serial clock + * (S0.SCLK) or I2C.1 Clock (I1.SCL) */ +# define STR71X_IRQ_PORT0p6 (43) /* Line 11: Port 0.6 - BSPI1 Slave Input serial clock + * (S1.SCLK) */ +# define STR71X_IRQ_PORT0p8 (44) /* Line 12: Port 0.8 - UART0 Receive Data Input (U0.Rx) */ +# define STR71X_IRQ_PORT0p10 (45) /* Line 13: Port 0.10 - UART1 Receive Data Input (U1.Rx) */ +# define STR71X_IRQ_PORT0p13 (46) /* Line 14: Port 0.13 - UART2 Receive Data Input (U2.Rx) */ +# define STR71X_IRQ_PORT0p15 (47) /* Line 15: Port 0.15 - WAKEUP pin or RTC ALARM */ +# define NR_IRQS (48) +#else +# define NR_IRQS (32) +#endif + +#define STR71X_IRQ_SYSTIMER STR71X_IRQ_T0TIMI + +/* FIQ channels */ + +#define STR71X_FIQ_T0TIMI (0X00000001) +#define STR71X_FIQ_WDG (0X00000002) +#define STR71X_FIQ_WDGT0TIMIS (0X00000003) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_STR71X_IRQ_H */ + diff --git a/arch/arm/include/syscall.h b/arch/arm/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..c8aa0fe43ccf8f8c9ce86fd7a88bb575ed898ac3 --- /dev/null +++ b/arch/arm/include/syscall.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SYSCALL_H +#define __ARCH_ARM_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include ARM architecture-specific syscall macros */ + +#if defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) +# include +#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ + defined(CONFIG_ARCH_CORTEXM7) +# include +#elif defined(CONFIG_ARCH_CORTEXM0) +# include +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_SYSCALL_H */ + diff --git a/arch/arm/include/tiva/cc3200_irq.h b/arch/arm/include/tiva/cc3200_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..d55b89ab22b37233616a836bbb79908a23fec013 --- /dev/null +++ b/arch/arm/include/tiva/cc3200_irq.h @@ -0,0 +1,299 @@ +/************************************************************************************ + * arch/arm/include/tiva/cc3200_irq.h + * + * Copyright (C) 2014 Droidifi LLC. + * Author: Jim Ewing + * + * Adapted for the cc3200 from code: + * + * Copyright (C) 2011-2012 Gregory Nutt. + * Author: Gregory Nutt + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Droidifi 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_CC3200_IRQ_H +#define __ARCH_ARM_INCLUDE_TIVA_CC3200_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define TIVA_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_CC3200) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_RESERVED_20 (20) /* Vector 20: Reserved */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_RESERVED_23 (23) /* Vector 23: Reserved */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ + +# define TIVA_RESERVED_25 (25) /* Vector 25: Reserved */ +# define TIVA_RESERVED_26 (26) /* Vector 26: Reserved */ +# define TIVA_RESERVED_27 (27) /* Vector 27: Reserved */ +# define TIVA_RESERVED_28 (28) /* Vector 28: Reserved */ +# define TIVA_RESERVED_29 (29) /* Vector 29: Reserved */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ + +# define TIVA_RESERVED_41 (41) /* Vector 41: Reserved */ +# define TIVA_RESERVED_42 (42) /* Vector 42: Reserved */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ + +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ + +# define TIVA_RESERVED_46 (46) /* Vector 46: Reserved */ +# define TIVA_RESERVED_47 (47) /* Vector 47: Reserved */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_RESERVED_49 (49) /* Vector 49: Reserved */ +# define TIVA_RESERVED_50 (50) /* Vector 50: Reserved */ + +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ + +# define TIVA_RESERVED_53 (53) /* Vector 53: Reserved */ +# define TIVA_RESERVED_54 (54) /* Vector 54: Reserved */ +# define TIVA_RESERVED_55 (55) /* Vector 55: Reserved */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_RESERVED_58 (58) /* Vector 58: Reserved */ + +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_RESERVED_60 (60) /* Vector 60: Reserved */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ + +# define TIVA_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */ + +# define TIVA_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */ +# define TIVA_IRQ_I2S0 (68) /* Vector 68: I2S0 */ +# define TIVA_IRQ_EPI (69) /* Vector 69: EPI */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ +# define TIVA_RESERVED_71 (71) /* Vector 71: Reserved */ +# define TIVA_RESERVED_72 (72) /* Vector 72: Reserved */ +# define TIVA_RESERVED_73 (73) /* Vector 73: Reserved */ +# define TIVA_RESERVED_74 (74) /* Vector 74: Reserved */ +# define TIVA_RESERVED_75 (75) /* Vector 75: Reserved */ +# define TIVA_RESERVED_76 (76) /* Vector 76: Reserved */ +# define TIVA_RESERVED_77 (77) /* Vector 77: Reserved */ +# define TIVA_RESERVED_78 (78) /* Vector 78: Reserved */ +# define TIVA_RESERVED_79 (79) /* Vector 79: Reserved */ + +# define TIVA_RESERVED_80 (80) /* Vector 80: Reserved */ +# define TIVA_RESERVED_81 (81) /* Vector 81: Reserved */ +# define TIVA_RESERVED_82 (82) /* Vector 82: Reserved */ +# define TIVA_RESERVED_83 (83) /* Vector 83: Reserved */ +# define TIVA_RESERVED_84 (84) /* Vector 84: Reserved */ +# define TIVA_RESERVED_85 (85) /* Vector 85: Reserved */ +# define TIVA_RESERVED_86 (86) /* Vector 86: Reserved */ +# define TIVA_RESERVED_87 (87) /* Vector 87: Reserved */ +# define TIVA_RESERVED_88 (88) /* Vector 88: Reserved */ +# define TIVA_RESERVED_89 (89) /* Vector 89: Reserved */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_RESERVED_91 (91) /* Vector 91: Reserved */ +# define TIVA_RESERVED_92 (92) /* Vector 92: Reserved */ +# define TIVA_RESERVED_93 (93) /* Vector 93: Reserved */ +# define TIVA_RESERVED_94 (94) /* Vector 94: Reserved */ +# define TIVA_RESERVED_95 (95) /* Vector 95: Reserved */ +# define TIVA_RESERVED_96 (96) /* Vector 96: Reserved */ +# define TIVA_RESERVED_97 (97) /* Vector 97: Reserved */ +# define TIVA_RESERVED_98 (98) /* Vector 98: Reserved */ +# define TIVA_RESERVED_99 (99) /* Vector 99: Reserved */ + +# define TIVA_RESERVED_100 (100) /* Vector 100: Reserved */ +# define TIVA_RESERVED_101 (101) /* Vector 101: Reserved */ +# define TIVA_RESERVED_102 (102) /* Vector 102: Reserved */ +# define TIVA_RESERVED_103 (103) /* Vector 103: Reserved */ +# define TIVA_RESERVED_104 (104) /* Vector 104: Reserved */ +# define TIVA_RESERVED_105 (105) /* Vector 105: Reserved */ +# define TIVA_RESERVED_106 (106) /* Vector 106: Reserved */ +# define TIVA_RESERVED_107 (107) /* Vector 107: Reserved */ +# define TIVA_RESERVED_108 (108) /* Vector 108: Reserved */ +# define TIVA_RESERVED_109 (109) /* Vector 109: Reserved */ +# define TIVA_RESERVED_110 (110) /* Vector 110: Reserved */ +# define TIVA_RESERVED_111 (111) /* Vector 111: Reserved */ +# define TIVA_RESERVED_112 (112) /* Vector 112: Reserved */ +# define TIVA_RESERVED_113 (113) /* Vector 113: Reserved */ +# define TIVA_RESERVED_114 (114) /* Vector 114: Reserved */ +# define TIVA_RESERVED_115 (115) /* Vector 115: Reserved */ +# define TIVA_RESERVED_116 (116) /* Vector 116: Reserved */ +# define TIVA_RESERVED_117 (117) /* Vector 117: Reserved */ +# define TIVA_RESERVED_118 (118) /* Vector 118: Reserved */ +# define TIVA_RESERVED_119 (119) /* Vector 119: Reserved */ + +# define TIVA_RESERVED_120 (120) /* Vector 120: Reserved */ +# define TIVA_RESERVED_121 (121) /* Vector 121: Reserved */ +# define TIVA_IRQ_SYSTEM (122) /* Vector 122: System Exception (imprecise) */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_RESERVED_125 (125) /* Vector 125: Reserved */ +# define TIVA_RESERVED_126 (126) /* Vector 126: Reserved */ +# define TIVA_RESERVED_127 (127) /* Vector 127: Reserved */ +# define TIVA_RESERVED_128 (128) /* Vector 128: Reserved */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define TIVA_RESERVED_130 (130) /* Vector 130: Reserved */ +# define TIVA_RESERVED_131 (131) /* Vector 131: Reserved */ +# define TIVA_RESERVED_132 (132) /* Vector 132: Reserved */ +# define TIVA_RESERVED_133 (133) /* Vector 133: Reserved */ +# define TIVA_RESERVED_134 (134) /* Vector 134: Reserved */ +# define TIVA_RESERVED_135 (135) /* Vector 135: Reserved */ +# define TIVA_RESERVED_136 (136) /* Vector 136: Reserved */ +# define TIVA_RESERVED_137 (137) /* Vector 137: Reserved */ +# define TIVA_RESERVED_138 (138) /* Vector 138: Reserved */ +# define TIVA_RESERVED_139 (139) /* Vector 139: Reserved */ + +# define TIVA_RESERVED_140 (140) /* Vector 140: Reserved */ +# define TIVA_RESERVED_141 (141) /* Vector 141: Reserved */ +# define TIVA_RESERVED_142 (142) /* Vector 142: Reserved */ +# define TIVA_RESERVED_143 (143) /* Vector 143: Reserved */ +# define TIVA_RESERVED_144 (144) /* Vector 144: Reserved */ +# define TIVA_RESERVED_145 (145) /* Vector 145: Reserved */ +# define TIVA_RESERVED_146 (146) /* Vector 146: Reserved */ +# define TIVA_RESERVED_147 (147) /* Vector 147: Reserved */ +# define TIVA_RESERVED_148 (148) /* Vector 148: Reserved */ +# define TIVA_RESERVED_149 (149) /* Vector 149: Reserved */ + +# define TIVA_RESERVED_150 (150) /* Vector 150: Reserved */ +# define TIVA_RESERVED_151 (151) /* Vector 151: Reserved */ +# define TIVA_RESERVED_152 (152) /* Vector 152: Reserved */ +# define TIVA_RESERVED_153 (153) /* Vector 153: Reserved */ +# define TIVA_RESERVED_154 (154) /* Vector 154: Reserved */ +# define TIVA_RESERVED_155 (155) /* Vector 155: Reserved */ +# define TIVA_RESERVED_156 (156) /* Vector 156: Reserved */ +# define TIVA_RESERVED_157 (157) /* Vector 157: Reserved */ +# define TIVA_RESERVED_158 (158) /* Vector 158: Reserved */ +# define TIVA_RESERVED_159 (159) /* Vector 159: Reserved */ + +# define TIVA_RESERVED_160 (160) /* Vector 160: Reserved */ +# define TIVA_RESERVED_161 (161) /* Vector 161: Reserved */ +# define TIVA_RESERVED_162 (162) /* Vector 162: Reserved */ +# define TIVA_RESERVED_163 (163) /* Vector 162: Reserved */ +# define TIVA_IRQ_SHA (164) /* Vector 162: SHA HW */ +# define TIVA_RESERVED_165 (165) /* Vector 165: Reserved */ +# define TIVA_RESERVED_166 (166) /* Vector 166: Reserved */ +# define TIVA_IRQ_AES (167) /* Vector 167: AES HW */ +# define TIVA_RESERVED_168 (168) /* Vector 168: Reserved */ +# define TIVA_IRQ_DES (169) /* Vector 169: DES HW */ + +# define TIVA_RESERVED_170 (170) /* Vector 170: Reserved */ +# define TIVA_RESERVED_171 (171) /* Vector 171: Reserved */ +# define TIVA_RESERVED_172 (172) /* Vector 172: Reserved */ +# define TIVA_RESERVED_173 (173) /* Vector 173: Reserved */ +# define TIVA_RESERVED_174 (174) /* Vector 174: Reserved */ +# define TIVA_RESERVED_175 (175) /* Vector 175: Reserved */ +# define TIVA_RESERVED_176 (176) /* Vector 176: Reserved */ +# define TIVA_IRQ_MC_ASP_0 (177) /* Vector 177: McASP 0 */ +# define TIVA_RESERVED_178 (178) /* Vector 178: Reserved */ +# define TIVA_IRQ_CAM_0 (179) /* Vector 179: Camera A0 */ + +# define TIVA_RESERVED_180 (180) /* Vector 180: Reserved */ +# define TIVA_RESERVED_181 (181) /* Vector 181: Reserved */ +# define TIVA_RESERVED_182 (182) /* Vector 182: Reserved */ +# define TIVA_RESERVED_183 (183) /* Vector 183: Reserved */ +# define TIVA_IRQ_RAM_ERR (184) /* Vector 184: RAM Err */ +# define TIVA_RESERVED_185 (185) /* Vector 185: Reserved */ +# define TIVA_RESERVED_186 (186) /* Vector 186: Reserved */ +# define TIVA_IRQ_NWPIC (187) /* Vector 187: NWP IC interocessor comm */ +# define TIVA_IRQ_PRCM (188) /* Vector 188: Pwr, Rst, Clk */ +# define TIVA_IRQ_TOPDIE (189) /* Vector 189: From Top Die */ + +# define TIVA_RESERVED_190 (190) /* Vector 190: Reserved */ +# define TIVA_IRQ_MCSPI_S0 (191) /* Vector 191: SPI S0 */ +# define TIVA_IRQ_MCSPI_A1 (192) /* Vector 191: SPI A0 */ +# define TIVA_IRQ_MCSPI_A2 (193) /* Vector 191: SPI A1 */ +# define TIVA_RESERVED_194 (194) /* Vector 194: Reserved */ + +# define NR_IRQS (195) /* (Really fewer because of reserved vectors) */ + +#else +# error "IRQ Numbers not known for this Tiva chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TIVA_CC3200_IRQ_H */ diff --git a/arch/arm/include/tiva/chip.h b/arch/arm/include/tiva/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..8e3085307fba32654670ce60fe745798ec5221a9 --- /dev/null +++ b/arch/arm/include/tiva/chip.h @@ -0,0 +1,391 @@ +/************************************************************************************ + * arch/arm/include/tiva/chip.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Jose Pablo Carballo + * Jim Ewing + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_CHIP_H +#define __ARCH_ARM_INCLUDE_TIVA_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip (only the LM3S6918 and 65 right now) */ + +#if defined(CONFIG_ARCH_CHIP_LM3S6918) +# define LM3S 1 /* LM3S family */ +# undef LM4F /* Not LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 4 /* Four 16/32-bit timers */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 1 /* One watchdog timer */ +# define TIVA_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# undef TIVA_ETHTS /* No timestamp register */ +# define TIVA_NSSI 2 /* Two SSI modules */ +# define TIVA_NUARTS 2 /* Two UART modules */ +# define TIVA_NI2C 2 /* Two I2C modules */ +# define TIVA_NADC 1 /* One ADC module */ +# define TIVA_NPWM 0 /* No PWM generator modules */ +# define TIVA_NQEI 0 /* No quadrature encoders */ +# define TIVA_NPORTS 8 /* 8 Ports (GPIOA-H) 5-38 GPIOs */ +# define TIVA_NCANCONTROLLER 0 /* No CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_LM3S6432) +# define LM3S 1 /* LM3S family */ +# undef LM4F /* Not LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 3 /* Three 16/32-bit timers */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 1 /* One watchdog timer */ +# define TIVA_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# undef TIVA_ETHTS /* No timestamp register */ +# define TIVA_NSSI 1 /* One SSI module */ +# define TIVA_NUARTS 2 /* Two UART modules */ +# define TIVA_NI2C 1 /* Two I2C modules */ +# define TIVA_NADC 1 /* One ADC module */ +# define TIVA_NPWM 1 /* One PWM generator module */ +# define TIVA_NQEI 0 /* No quadrature encoders */ +# define TIVA_NPORTS 7 /* 7 Ports (GPIOA-G), 0-42 GPIOs */ +# define TIVA_NCANCONTROLLER 0 /* No CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_LM3S6965) +# define LM3S 1 /* LM3S family */ +# undef LM4F /* Not LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 4 /* Four 16/32-bit timers */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 1 /* One watchdog timer */ +# define TIVA_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# undef TIVA_ETHTS /* No timestamp register */ +# define TIVA_NSSI 1 /* One SSI module */ +# define TIVA_NUARTS 3 /* Three UART modules */ +# define TIVA_NI2C 2 /* Two I2C modules */ +# define TIVA_NADC 1 /* One ADC module */ +# define TIVA_NPWM 3 /* Three PWM generator modules */ +# define TIVA_NQEI 2 /* Two quadrature encoders */ +# define TIVA_NPORTS 7 /* 7 Ports (GPIOA-G), 0-42 GPIOs */ +# define TIVA_NCANCONTROLLER 0 /* No CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) +# define LM3S 1 /* LM3S family */ +# undef LM4F /* Not LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 4 /* Four 16/32-bit timers */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 1 /* One watchdog timer */ +# define TIVA_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# undef TIVA_ETHTS /* No timestamp register */ +# define TIVA_NSSI 2 /* Two SSI modules */ +# define TIVA_NUARTS 3 /* Three UART modules */ +# define TIVA_NI2C 2 /* Two I2C modules */ +# define TIVA_NADC 2 /* Two ADC module */ +# define TIVA_CAN 2 /* Two CAN module */ +# define TIVA_NPWM 4 /* Four PWM generator modules */ +# define TIVA_NQEI 2 /* Two quadrature encoders */ +# define TIVA_NPORTS 9 /* 9 Ports (GPIOA-H,J) 0-65 GPIOs */ +# define TIVA_NCANCONTROLLER 0 /* No CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_LM3S8962) +# define LM3S 1 /* LM3S family */ +# undef LM4F /* Not LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 6 /* Four 16/32-bit timers */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 1 /* One watchdog timer */ +# define TIVA_NETHCONTROLLERS 1 /* One Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# define TIVA_NSSI 1 /* One SSI module */ +# define TIVA_NUARTS 3 /* Two UART modules */ +# define TIVA_NI2C 2 /* One I2C module */ +# define TIVA_NADC 1 /* One ADC module */ +# define TIVA_NPWM 3 /* Three PWM generator modules */ +# define TIVA_NQEI 2 /* Two quadrature encoders */ +# define TIVA_NPORTS 7 /* 7 Ports (GPIOA-G), 5-42 GPIOs */ +# define TIVA_NCANCONTROLLER 1 /* One CAN controller */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_LM4F120) +# undef LM3S /* Not LM3S family */ +# define LM4F 1 /* LM4F family */ +# undef TM4C /* Not TM4C family */ +# define TIVA_NTIMERS 6 /* Six 16/32-bit timers */ +# define TIVA_NWIDETIMERS 6 /* Six 32/64-bit timers */ +# define TIVA_NWDT 2 /* Two watchdog timer timers */ +# define TIVA_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# define TIVA_NSSI 4 /* Four SSI module */ +# define TIVA_NUARTS 8 /* Eight UART modules */ +# define TIVA_NI2C 4 /* Four I2C modules */ +# define TIVA_NADC 2 /* Two ADC modules */ +# define TIVA_NPWM 0 /* No PWM generator modules */ +# define TIVA_NQEI 0 /* No quadrature encoders */ +# define TIVA_NPORTS 6 /* 6 Ports (GPIOA-F), 0-43 GPIOs */ +# define TIVA_NCANCONTROLLER 1 /* One CAN controller */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PGE) || defined(CONFIG_ARCH_CHIP_TM4C123GH6PZ) || \ + defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# undef LM3S /* Not LM3S family */ +# undef LM4F /* Not LM4F family */ +# define TM4C 1 /* TM4C family */ +# define TIVA_NTIMERS 6 /* Six 16/32-bit timers */ +# define TIVA_NWIDETIMERS 6 /* Six 32/64-bit timers */ +# define TIVA_NWDT 2 /* Two watchdog timers */ +# define TIVA_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# define TIVA_NSSI 4 /* Four SSI module */ +# define TIVA_NUARTS 8 /* Eight UART modules */ +# define TIVA_NI2C 6 /* Six I2C modules */ +# define TIVA_NADC 2 /* Two ADC modules */ +# define TIVA_NPWM 2 /* Two PWM generator modules */ +# define TIVA_NQEI 1 /* One quadrature encoders */ +# define TIVA_NPORTS 15 /* Fifteen Ports (GPIOA-H, J-N, P-Q) */ +# define TIVA_NCANCONTROLLER 2 /* Two CAN controllers */ +# define TIVA_NUSBOTGFS 1 /* One USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) +# undef LM3S /* Not LM3S family */ +# undef LM4F /* Not LM4F family */ +# define TM4C 1 /* TM4C family */ +# define TIVA_NTIMERS 6 /* Six 16/32-bit timers */ +# define TIVA_NWIDETIMERS 6 /* Six 32/64-bit timers */ +# define TIVA_NWDT 2 /* Two watchdog timers */ +# define TIVA_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# define TIVA_NSSI 4 /* Four SSI module */ +# define TIVA_NUARTS 8 /* Eight UART modules */ +# define TIVA_NI2C 4 /* Four I2C modules */ +# define TIVA_NADC 2 /* Two ADC modules */ +# define TIVA_NPWM 2 /* Two PWM generator modules */ +# define TIVA_NQEI 2 /* Two quadrature encoders */ +# define TIVA_NPORTS 6 /* Six Ports (GPIOA-F) */ +# define TIVA_NCANCONTROLLER 2 /* Two CAN controllers */ +# define TIVA_NUSBOTGFS 1 /* One USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 0 /* No USB 2.0 OTG HS */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_TM4C1294NC) +# undef LM3S /* Not LM3S family */ +# undef LM4F /* Not LM4F family */ +# define TM4C 1 /* TM4C family */ +# define TIVA_NTIMERS 8 /* Eight Dual 16/32-bit timers A/B */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 2 /* Two watchdog timers */ +# define TIVA_NETHCONTROLLERS 1 /* One 10/100Mbit Ethernet controller */ +# define TIVA_NLCD 1 /* One LCD controller */ +# define TIVA_NSSI 4 /* Four SSI modules */ +# define TIVA_NUARTS 8 /* Eight UART modules */ +# define TIVA_NI2C 10 /* Ten I2C modules */ +# define TIVA_NADC 2 /* Two ADC modules */ +# define TIVA_NPWM 4 /* Four PWM generator modules */ +# define TIVA_NQEI 1 /* One quadrature encoders */ +# define TIVA_NPORTS 15 /* Fifteen Ports (GPIOA-H, J-N, P-Q) */ +# define TIVA_NCANCONTROLLER 2 /* Two CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 1 /* One USB 2.0 OTG HS */ +# define TIVA_NCRC 1 /* One CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) +# undef LM3S /* Not LM3S family */ +# undef LM4F /* Not LM4F family */ +# define TM4C 1 /* TM4C family */ +# define TIVA_NTIMERS 8 /* Eight Dual 16/32-bit timers A/B */ +# define TIVA_NWIDETIMERS 0 /* No 32/64-bit timers */ +# define TIVA_NWDT 2 /* Two watchdog timers */ +# define TIVA_NETHCONTROLLERS 1 /* One 10/100Mbit Ethernet controller */ +# define TIVA_NLCD 1 /* One LCD controller */ +# define TIVA_NSSI 4 /* Four SSI modules */ +# define TIVA_NUARTS 8 /* Eight UART modules */ +# define TIVA_NI2C 10 /* Ten I2C modules */ +# define TIVA_NADC 2 /* Two ADC modules */ +# define TIVA_NPWM 4 /* Four PWM generator modules */ +# define TIVA_NQEI 1 /* One quadrature encoder module */ +# define TIVA_NPORTS 18 /* Eighteen Ports (GPIOA-H, J-N, P-T) */ +# define TIVA_NCANCONTROLLER 2 /* Two CAN controllers */ +# define TIVA_NUSBOTGFS 0 /* No USB 2.0 OTG FS */ +# define TIVA_NUSBOTGHS 1 /* One USB 2.0 OTG HS */ +# define TIVA_NCRC 1 /* One CRC module */ +# define TIVA_NAES 1 /* One AES module */ +# define TIVA_NDES 1 /* One DES module */ +# define TIVA_NHASH 1 /* One SHA1/MD5 hash module */ +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# undef LM3S /* Not LM3S family */ +# undef LM4F /* Not LM4F family */ +# define TM4C 1 /* TM4C family */ +# define TIVA_NTIMERS 4 /* Four 16/32-bit timers */ +# define TIVA_NWIDETIMERS 2 /* Two 32/64-bit timers */ +# define TIVA_NETHCONTROLLERS 0 /* No Ethernet controller */ +# define TIVA_NLCD 0 /* No LCD controller */ +# define TIVA_NSSI 0 /* No SSI module */ +# define TIVA_NUARTS 2 /* Two UART modules */ +# define TIVA_NI2C 2 /* Two I2C modules */ +# define TIVA_NADC 3 /* Three ADC modules */ +# define TIVA_NPWM 0 /* No PWM generator modules */ +# define TIVA_NQEI 0 /* No quadrature encoders */ +# define TIVA_NPORTS 4 /* 4 Ports (GPIOA-D), 0-31 GPIOs */ +# define TIVA_DES 1 /* 1 DES hw crypto */ +# define TIVA_AES 1 /* 1 AES hw crypto */ +# define TIVA_CRC 1 /* 1 CRC hw crypto */ +# define TIVA_SHA 1 /* 1 SHA/MD5 hw crypto */ +# define TIVA_SPI 2 /* Two SPI modules */ +# define TIVA_NCANCONTROLLER 0 /* No CAN controllers */ +# define TIVA_NCRC 0 /* No CRC module */ +# define TIVA_NAES 0 /* No AES module */ +# define TIVA_NDES 0 /* No DES module */ +# define TIVA_NHASH 0 /* No SHA1/MD5 hash module */ +#else +# error "Capabilities not specified for this TIVA/Stellaris chip" +#endif + +/* The TIVA/Stellaris only supports 8 priority levels. The hardware priority + * mechanism will only look at the upper N bits of the 8-bit priority level + * (where N is 3 for the Tiva/Stellaris family), so any prioritization must be + * performed in those bits. The default priority level is set to the middle + * value + */ + +#define NVIC_SYSH_PRIORITY_MIN 0xe0 /* Bits [7:5] set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Three bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_TIVA_CHIP_H */ diff --git a/arch/arm/include/tiva/irq.h b/arch/arm/include/tiva/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..17c73a254de4d8f121593187ba0b4c62fad42a41 --- /dev/null +++ b/arch/arm/include/tiva/irq.h @@ -0,0 +1,463 @@ +/************************************************************************************ + * arch/arm/include/tiva/irq.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_IRQ_H +#define __ARCH_ARM_INCLUDE_TIVA_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +#if defined(CONFIG_ARCH_CHIP_LM3S) || defined(CONFIG_ARCH_CHIP_LM4F) || \ + defined(CONFIG_ARCH_CHIP_CC3200) + + /* I don't believe that any of these families support interrupts on port J. Many + * do not support interrupts on port H either. + */ + +# undef CONFIG_TIVA_GPIOJ_IRQS + +#elif defined(CONFIG_ARCH_CHIP_TM4C) + +/* The TM4C123GH6PMI supports ports A-F of which any can support interrupts */ + +# if defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) +# undef CONFIG_TIVA_GPIOP_IRQS /* P-Q */ +# undef CONFIG_TIVA_GPIOQ_IRQS + +/* The TM4C123GH6PGE supports interrupts only on port P */ + +# elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PGE) +# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */ +# undef CONFIG_TIVA_GPIOB_IRQS +# undef CONFIG_TIVA_GPIOC_IRQS +# undef CONFIG_TIVA_GPIOD_IRQS +# undef CONFIG_TIVA_GPIOE_IRQS +# undef CONFIG_TIVA_GPIOF_IRQS + +# undef CONFIG_TIVA_GPIOQ_IRQS /* Q */ + +/* The TM4C123GH6ZRB and the TM4C129x support interrupts only on ports P and Q. */ + +# else +# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */ +# undef CONFIG_TIVA_GPIOB_IRQS +# undef CONFIG_TIVA_GPIOC_IRQS +# undef CONFIG_TIVA_GPIOD_IRQS +# undef CONFIG_TIVA_GPIOE_IRQS +# undef CONFIG_TIVA_GPIOF_IRQS + +# endif + +/* No supported architecture supports interrupts on ports G-N or R-T */ + +# undef CONFIG_TIVA_GPIOG_IRQS /* G-N */ +# undef CONFIG_TIVA_GPIOH_IRQS +# undef CONFIG_TIVA_GPIOJ_IRQS +# undef CONFIG_TIVA_GPIOK_IRQS +# undef CONFIG_TIVA_GPIOL_IRQS +# undef CONFIG_TIVA_GPIOM_IRQS +# undef CONFIG_TIVA_GPION_IRQS + +# undef CONFIG_TIVA_GPIOR_IRQS /* R-T */ +# undef CONFIG_TIVA_GPIOS_IRQS +# undef CONFIG_TIVA_GPIOT_IRQS + +#endif + + /* Mark GPIO interrupts as disabled for non-existent GPIO ports. */ + +#if TIVA_NPORTS < 1 +# undef CONFIG_TIVA_GPIOA_IRQS +#endif +#if TIVA_NPORTS < 2 +# undef CONFIG_TIVA_GPIOB_IRQS +#endif +#if TIVA_NPORTS < 3 +# undef CONFIG_TIVA_GPIOC_IRQS +#endif +#if TIVA_NPORTS < 4 +# undef CONFIG_TIVA_GPIOD_IRQS +#endif +#if TIVA_NPORTS < 5 +# undef CONFIG_TIVA_GPIOE_IRQS +#endif +#if TIVA_NPORTS < 6 +# undef CONFIG_TIVA_GPIOF_IRQS +#endif +#if TIVA_NPORTS < 7 +# undef CONFIG_TIVA_GPIOG_IRQS +#endif +#if TIVA_NPORTS < 8 +# undef CONFIG_TIVA_GPIOH_IRQS +#endif +#if TIVA_NPORTS < 9 +# undef CONFIG_TIVA_GPIOJ_IRQS +#endif +#if TIVA_NPORTS < 10 +# undef CONFIG_TIVA_GPIOK_IRQS +#endif +#if TIVA_NPORTS < 11 +# undef CONFIG_TIVA_GPIOL_IRQS +#endif +#if TIVA_NPORTS < 12 +# undef CONFIG_TIVA_GPIOM_IRQS +#endif +#if TIVA_NPORTS < 13 +# undef CONFIG_TIVA_GPION_IRQS +#endif +#if TIVA_NPORTS < 14 +# undef CONFIG_TIVA_GPIOP_IRQS +#endif +#if TIVA_NPORTS < 15 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 16 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 17 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 18 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif + +/* Processor Exceptions (vectors 0-15) */ + +#define TIVA_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define TIVA_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define TIVA_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define TIVA_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define TIVA_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define TIVA_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define TIVA_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define TIVA_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define TIVA_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define TIVA_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +#if defined(CONFIG_ARCH_CHIP_LM3S) +# include +#elif defined(CONFIG_ARCH_CHIP_LM4F) +# include +#elif defined(CONFIG_ARCH_CHIP_TM4C) +# include +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# include +#else +# error "Unsupported Stellaris IRQ file" +#endif + +#define NR_VECTORS (NR_IRQS - 16) + +/* GPIO IRQs -- Note that support for individual GPIO ports can + * be disabled in order to reduce the size of the implementation. + */ + +#if defined(CONFIG_TIVA_GPIOA_IRQS) +# define TIVA_IRQ_GPIOA_0 (NR_IRQS + 0) +# define TIVA_IRQ_GPIOA_1 (NR_IRQS + 1) +# define TIVA_IRQ_GPIOA_2 (NR_IRQS + 2) +# define TIVA_IRQ_GPIOA_3 (NR_IRQS + 3) +# define TIVA_IRQ_GPIOA_4 (NR_IRQS + 4) +# define TIVA_IRQ_GPIOA_5 (NR_IRQS + 5) +# define TIVA_IRQ_GPIOA_6 (NR_IRQS + 6) +# define TIVA_IRQ_GPIOA_7 (NR_IRQS + 7) +# define _NGPIOAIRQS (NR_IRQS + 8) +#else +# define _NGPIOAIRQS NR_IRQS +#endif + +#if defined(CONFIG_TIVA_GPIOB_IRQS) +# define TIVA_IRQ_GPIOB_0 (_NGPIOAIRQS + 0) +# define TIVA_IRQ_GPIOB_1 (_NGPIOAIRQS + 1) +# define TIVA_IRQ_GPIOB_2 (_NGPIOAIRQS + 2) +# define TIVA_IRQ_GPIOB_3 (_NGPIOAIRQS + 3) +# define TIVA_IRQ_GPIOB_4 (_NGPIOAIRQS + 4) +# define TIVA_IRQ_GPIOB_5 (_NGPIOAIRQS + 5) +# define TIVA_IRQ_GPIOB_6 (_NGPIOAIRQS + 6) +# define TIVA_IRQ_GPIOB_7 (_NGPIOAIRQS + 7) +# define _NGPIOBIRQS (_NGPIOAIRQS + 8) +#else +# define _NGPIOBIRQS _NGPIOAIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOC_IRQS) +# define TIVA_IRQ_GPIOC_0 (_NGPIOBIRQS + 0) +# define TIVA_IRQ_GPIOC_1 (_NGPIOBIRQS + 1) +# define TIVA_IRQ_GPIOC_2 (_NGPIOBIRQS + 2) +# define TIVA_IRQ_GPIOC_3 (_NGPIOBIRQS + 3) +# define TIVA_IRQ_GPIOC_4 (_NGPIOBIRQS + 4) +# define TIVA_IRQ_GPIOC_5 (_NGPIOBIRQS + 5) +# define TIVA_IRQ_GPIOC_6 (_NGPIOBIRQS + 6) +# define TIVA_IRQ_GPIOC_7 (_NGPIOBIRQS + 7) +# define _NGPIOCIRQS (_NGPIOBIRQS + 8) +#else +# define _NGPIOCIRQS _NGPIOBIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOD_IRQS) +# define TIVA_IRQ_GPIOD_0 (_NGPIOCIRQS + 0) +# define TIVA_IRQ_GPIOD_1 (_NGPIOCIRQS + 1) +# define TIVA_IRQ_GPIOD_2 (_NGPIOCIRQS + 2) +# define TIVA_IRQ_GPIOD_3 (_NGPIOCIRQS + 3) +# define TIVA_IRQ_GPIOD_4 (_NGPIOCIRQS + 4) +# define TIVA_IRQ_GPIOD_5 (_NGPIOCIRQS + 5) +# define TIVA_IRQ_GPIOD_6 (_NGPIOCIRQS + 6) +# define TIVA_IRQ_GPIOD_7 (_NGPIOCIRQS + 7) +# define _NGPIODIRQS (_NGPIOCIRQS + 8) +#else +# define _NGPIODIRQS _NGPIOCIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOE_IRQS) +# define TIVA_IRQ_GPIOE_0 (_NGPIODIRQS + 0) +# define TIVA_IRQ_GPIOE_1 (_NGPIODIRQS + 1) +# define TIVA_IRQ_GPIOE_2 (_NGPIODIRQS + 2) +# define TIVA_IRQ_GPIOE_3 (_NGPIODIRQS + 3) +# define TIVA_IRQ_GPIOE_4 (_NGPIODIRQS + 4) +# define TIVA_IRQ_GPIOE_5 (_NGPIODIRQS + 5) +# define TIVA_IRQ_GPIOE_6 (_NGPIODIRQS + 6) +# define TIVA_IRQ_GPIOE_7 (_NGPIODIRQS + 7) +# define _NGPIOEIRQS (_NGPIODIRQS + 8) +#else +# define _NGPIOEIRQS _NGPIODIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOF_IRQS) +# define TIVA_IRQ_GPIOF_0 (_NGPIOEIRQS + 0) +# define TIVA_IRQ_GPIOF_1 (_NGPIOEIRQS + 1) +# define TIVA_IRQ_GPIOF_2 (_NGPIOEIRQS + 2) +# define TIVA_IRQ_GPIOF_3 (_NGPIOEIRQS + 3) +# define TIVA_IRQ_GPIOF_4 (_NGPIOEIRQS + 4) +# define TIVA_IRQ_GPIOF_5 (_NGPIOEIRQS + 5) +# define TIVA_IRQ_GPIOF_6 (_NGPIOEIRQS + 6) +# define TIVA_IRQ_GPIOF_7 (_NGPIOEIRQS + 7) +# define _NGPIOFIRQS (_NGPIOEIRQS + 8) +#else +# define _NGPIOFIRQS _NGPIOEIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOG_IRQS) +# define TIVA_IRQ_GPIOG_0 (_NGPIOFIRQS + 0) +# define TIVA_IRQ_GPIOG_1 (_NGPIOFIRQS + 1) +# define TIVA_IRQ_GPIOG_2 (_NGPIOFIRQS + 2) +# define TIVA_IRQ_GPIOG_3 (_NGPIOFIRQS + 3) +# define TIVA_IRQ_GPIOG_4 (_NGPIOFIRQS + 4) +# define TIVA_IRQ_GPIOG_5 (_NGPIOFIRQS + 5) +# define TIVA_IRQ_GPIOG_6 (_NGPIOFIRQS + 6) +# define TIVA_IRQ_GPIOG_7 (_NGPIOFIRQS + 7) +# define _NGPIOGIRQS (_NGPIOFIRQS + 8) +#else +# define _NGPIOGIRQS _NGPIOFIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOH_IRQS) +# define TIVA_IRQ_GPIOH_0 (_NGPIOGIRQS + 0) +# define TIVA_IRQ_GPIOH_1 (_NGPIOGIRQS + 1) +# define TIVA_IRQ_GPIOH_2 (_NGPIOGIRQS + 2) +# define TIVA_IRQ_GPIOH_3 (_NGPIOGIRQS + 3) +# define TIVA_IRQ_GPIOH_4 (_NGPIOGIRQS + 4) +# define TIVA_IRQ_GPIOH_5 (_NGPIOGIRQS + 5) +# define TIVA_IRQ_GPIOH_6 (_NGPIOGIRQS + 6) +# define TIVA_IRQ_GPIOH_7 (_NGPIOGIRQS + 7) +# define _NGPIOHIRQS (_NGPIOGIRQS + 8) +#else +# define _NGPIOHIRQS _NGPIOGIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOJ_IRQS) +# define TIVA_IRQ_GPIOJ_0 (_NGPIOHIRQS + 0) +# define TIVA_IRQ_GPIOJ_1 (_NGPIOHIRQS + 1) +# define TIVA_IRQ_GPIOJ_2 (_NGPIOHIRQS + 2) +# define TIVA_IRQ_GPIOJ_3 (_NGPIOHIRQS + 3) +# define TIVA_IRQ_GPIOJ_4 (_NGPIOHIRQS + 4) +# define TIVA_IRQ_GPIOJ_5 (_NGPIOHIRQS + 5) +# define TIVA_IRQ_GPIOJ_6 (_NGPIOHIRQS + 6) +# define TIVA_IRQ_GPIOJ_7 (_NGPIOHIRQS + 7) +# define _NGPIOJIRQS (_NGPIOHIRQS + 8) +#else +# define _NGPIOJIRQS _NGPIOHIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOK_IRQS) +# define TIVA_IRQ_GPIOK_0 (_NGPIOJIRQS + 0) +# define TIVA_IRQ_GPIOK_1 (_NGPIOJIRQS + 1) +# define TIVA_IRQ_GPIOK_2 (_NGPIOJIRQS + 2) +# define TIVA_IRQ_GPIOK_3 (_NGPIOJIRQS + 3) +# define TIVA_IRQ_GPIOK_4 (_NGPIOJIRQS + 4) +# define TIVA_IRQ_GPIOK_5 (_NGPIOJIRQS + 5) +# define TIVA_IRQ_GPIOK_6 (_NGPIOJIRQS + 6) +# define TIVA_IRQ_GPIOK_7 (_NGPIOJIRQS + 7) +# define _NGPIOKIRQS (_NGPIOJIRQS + 8) +#else +# define _NGPIOKIRQS _NGPIOJIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOL_IRQS) +# define TIVA_IRQ_GPIOL_0 (_NGPIOKIRQS + 0) +# define TIVA_IRQ_GPIOL_1 (_NGPIOKIRQS + 1) +# define TIVA_IRQ_GPIOL_2 (_NGPIOKIRQS + 2) +# define TIVA_IRQ_GPIOL_3 (_NGPIOKIRQS + 3) +# define TIVA_IRQ_GPIOL_4 (_NGPIOKIRQS + 4) +# define TIVA_IRQ_GPIOL_5 (_NGPIOKIRQS + 5) +# define TIVA_IRQ_GPIOL_6 (_NGPIOKIRQS + 6) +# define TIVA_IRQ_GPIOL_7 (_NGPIOKIRQS + 7) +# define _NGPIOLIRQS (_NGPIOKIRQS + 8) +#else +# define _NGPIOLIRQS _NGPIOKIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOM_IRQS) +# define TIVA_IRQ_GPIOM_0 (_NGPIOLIRQS + 0) +# define TIVA_IRQ_GPIOM_1 (_NGPIOLIRQS + 1) +# define TIVA_IRQ_GPIOM_2 (_NGPIOLIRQS + 2) +# define TIVA_IRQ_GPIOM_3 (_NGPIOLIRQS + 3) +# define TIVA_IRQ_GPIOM_4 (_NGPIOLIRQS + 4) +# define TIVA_IRQ_GPIOM_5 (_NGPIOLIRQS + 5) +# define TIVA_IRQ_GPIOM_6 (_NGPIOLIRQS + 6) +# define TIVA_IRQ_GPIOM_7 (_NGPIOLIRQS + 7) +# define _NGPIOMIRQS (_NGPIOLIRQS + 8) +#else +# define _NGPIOMIRQS _NGPIOLIRQS +#endif + +#if defined(CONFIG_TIVA_GPION_IRQS) +# define TIVA_IRQ_GPION_0 (_NGPIOMIRQS + 0) +# define TIVA_IRQ_GPION_1 (_NGPIOMIRQS + 1) +# define TIVA_IRQ_GPION_2 (_NGPIOMIRQS + 2) +# define TIVA_IRQ_GPION_3 (_NGPIOMIRQS + 3) +# define TIVA_IRQ_GPION_4 (_NGPIOMIRQS + 4) +# define TIVA_IRQ_GPION_5 (_NGPIOMIRQS + 5) +# define TIVA_IRQ_GPION_6 (_NGPIOMIRQS + 6) +# define TIVA_IRQ_GPION_7 (_NGPIOMIRQS + 7) +# define _NGPIONIRQS (_NGPIOMIRQS + 8) +#else +# define _NGPIONIRQS _NGPIOMIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOP_IRQS) +# define TIVA_IRQ_GPIOP_0 (_NGPIONIRQS + 0) +# define TIVA_IRQ_GPIOP_1 (_NGPIONIRQS + 1) +# define TIVA_IRQ_GPIOP_2 (_NGPIONIRQS + 2) +# define TIVA_IRQ_GPIOP_3 (_NGPIONIRQS + 3) +# define TIVA_IRQ_GPIOP_4 (_NGPIONIRQS + 4) +# define TIVA_IRQ_GPIOP_5 (_NGPIONIRQS + 5) +# define TIVA_IRQ_GPIOP_6 (_NGPIONIRQS + 6) +# define TIVA_IRQ_GPIOP_7 (_NGPIONIRQS + 7) +# define _NGPIOPIRQS (_NGPIONIRQS + 8) +#else +# define _NGPIOPIRQS _NGPIONIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOQ_IRQS) +# define TIVA_IRQ_GPIOQ_0 (_NGPIOPIRQS + 0) +# define TIVA_IRQ_GPIOQ_1 (_NGPIOPIRQS + 1) +# define TIVA_IRQ_GPIOQ_2 (_NGPIOPIRQS + 2) +# define TIVA_IRQ_GPIOQ_3 (_NGPIOPIRQS + 3) +# define TIVA_IRQ_GPIOQ_4 (_NGPIOPIRQS + 4) +# define TIVA_IRQ_GPIOQ_5 (_NGPIOPIRQS + 5) +# define TIVA_IRQ_GPIOQ_6 (_NGPIOPIRQS + 6) +# define TIVA_IRQ_GPIOQ_7 (_NGPIOPIRQS + 7) +# define _NGPIOQIRQS (_NGPIOPIRQS + 8) +#else +# define _NGPIOQIRQS _NGPIOPIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOR_IRQS) +# define TIVA_IRQ_GPIOR_0 (_NGPIOQIRQS + 0) +# define TIVA_IRQ_GPIOR_1 (_NGPIOQIRQS + 1) +# define TIVA_IRQ_GPIOR_2 (_NGPIOQIRQS + 2) +# define TIVA_IRQ_GPIOR_3 (_NGPIOQIRQS + 3) +# define TIVA_IRQ_GPIOR_4 (_NGPIOQIRQS + 4) +# define TIVA_IRQ_GPIOR_5 (_NGPIOQIRQS + 5) +# define TIVA_IRQ_GPIOR_6 (_NGPIOQIRQS + 6) +# define TIVA_IRQ_GPIOR_7 (_NGPIOQIRQS + 7) +# define _NGPIORIRQS (_NGPIOQIRQS + 8) +#else +# define _NGPIORIRQS _NGPIOQIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOS_IRQS) +# define TIVA_IRQ_GPIOS_0 (_NGPIORIRQS + 0) +# define TIVA_IRQ_GPIOS_1 (_NGPIORIRQS + 1) +# define TIVA_IRQ_GPIOS_2 (_NGPIORIRQS + 2) +# define TIVA_IRQ_GPIOS_3 (_NGPIORIRQS + 3) +# define TIVA_IRQ_GPIOS_4 (_NGPIORIRQS + 4) +# define TIVA_IRQ_GPIOS_5 (_NGPIORIRQS + 5) +# define TIVA_IRQ_GPIOS_6 (_NGPIORIRQS + 6) +# define TIVA_IRQ_GPIOS_7 (_NGPIORIRQS + 7) +# define _NGPIOSIRQS (_NGPIORIRQS + 8) +#else +# define _NGPIOSIRQS _NGPIORIRQS +#endif + +#if defined(CONFIG_TIVA_GPIOT_IRQS) +# define TIVA_IRQ_GPIOT_0 (_NGPIOSIRQS + 0) +# define TIVA_IRQ_GPIOT_1 (_NGPIOSIRQS + 1) +# define TIVA_IRQ_GPIOT_2 (_NGPIOSIRQS + 2) +# define TIVA_IRQ_GPIOT_3 (_NGPIOSIRQS + 3) +# define TIVA_IRQ_GPIOT_4 (_NGPIOSIRQS + 4) +# define TIVA_IRQ_GPIOT_5 (_NGPIOSIRQS + 5) +# define TIVA_IRQ_GPIOT_6 (_NGPIOSIRQS + 6) +# define TIVA_IRQ_GPIOT_7 (_NGPIOSIRQS + 7) +# define _NGPIOTIRQS (_NGPIOSIRQS + 8) +#else +# define _NGPIOTIRQS _NGPIOSIRQS +#endif + +#define NR_GPIO_IRQS (_NGPIOTIRQS - NR_IRQS) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_TIVA_IRQ_H */ diff --git a/arch/arm/include/tiva/lm3s_irq.h b/arch/arm/include/tiva/lm3s_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..720cd06483d7ac6928301fe25a0f4a507f86ebf5 --- /dev/null +++ b/arch/arm/include/tiva/lm3s_irq.h @@ -0,0 +1,411 @@ +/************************************************************************************ + * arch/arm/include/tiva/lm3s_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_LM3S_IRQ_H +#define __ARCH_ARM_INCLUDE_TIVA_LM3S_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define TIVA_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */ +#if defined(CONFIG_ARCH_CHIP_LM3S6918) + +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_RESERVED_25 (25) /* Vector 25: Reserved */ +# define TIVA_RESERVED_26 (26) /* Vector 26: Reserved */ +# define TIVA_RESERVED_27 (27) /* Vector 27: Reserved */ +# define TIVA_RESERVED_28 (28) /* Vector 28: Reserved */ +# define TIVA_RESERVED_29 (29) /* Vector 29: Reserved */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */ +# define TIVA_RESERVED_49 (49) /* Vector 49: Reserved */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_RESERVED_54 (54) /* Vector 54: Reserved */ +# define TIVA_RESERVED_55 (55) /* Vector 55: Reserved */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_RESERVED_60 (60) /* Vector 60: Reserved */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ +# define TIVA_RESERVED_62 (62) /* Vector 62: Reserved */ +# define TIVA_RESERVED_63 (63) /* Vector 63: Reserved */ +# define TIVA_RESERVED_64 (64) /* Vector 64: Reserved */ +# define TIVA_RESERVED_65 (65) /* Vector 65: Reserved */ +# define TIVA_RESERVED_66 (66) /* Vector 66: Reserved */ +# define TIVA_RESERVED_67 (67) /* Vector 67: Reserved */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ + +# define NR_IRQS (71) /* (Really less because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S6432) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_RESERVED_25 (25) /* Vector 25: Reserved */ +# define TIVA_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */ +# define TIVA_RESERVED_27 (27) /* Vector 27: Reserved */ +# define TIVA_RESERVED_28 (28) /* Vector 28: Reserved */ +# define TIVA_RESERVED_29 (29) /* Vector 29: Reserved */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_RESERVED_49 (49) /* Vector 49: Reserved */ + +# define TIVA_RESERVED_50 (50) /* Vector 50: Reserved */ +# define TIVA_RESERVED_51 (51) /* Vector 51: Reserved */ +# define TIVA_RESERVED_52 (52) /* Vector 52: Reserved */ +# define TIVA_RESERVED_53 (53) /* Vector 53: Reserved */ +# define TIVA_RESERVED_54 (54) /* Vector 54: Reserved */ +# define TIVA_RESERVED_55 (55) /* Vector 55: Reserved */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */ +# define TIVA_RESERVED_59 (59) /* Vector 59: Reserved */ + +# define TIVA_RESERVED_60 (60) /* Vector 60: Reserved */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ +# define TIVA_RESERVED_62 (62) /* Vector 62: Reserved */ +# define TIVA_RESERVED_63 (63) /* Vector 63: Reserved */ +# define TIVA_RESERVED_64 (64) /* Vector 64: Reserved */ +# define TIVA_RESERVED_65 (65) /* Vector 65: Reserved */ +# define TIVA_RESERVED_66 (66) /* Vector 66: Reserved */ +# define TIVA_RESERVED_67 (67) /* Vector 67: Reserved */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ + +# define NR_IRQS (71) /* (Really less because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S6965) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ + +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */ +# define TIVA_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */ +# define TIVA_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */ +# define TIVA_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_RESERVED_50 (50) /* Vector 50: Reserved */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_QEI1 (54) /* Vector 54: QEI1 */ +# define TIVA_RESERVED_55 (55) /* Vector 55: Reserved */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_RESERVED_60 (60) /* Vector 60: Reserved */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ +# define TIVA_RESERVED_62 (62) /* Vector 62: Reserved */ +# define TIVA_RESERVED_63 (63) /* Vector 63: Reserved */ +# define TIVA_RESERVED_64 (64) /* Vector 64: Reserved */ +# define TIVA_RESERVED_65 (65) /* Vector 65: Reserved */ +# define TIVA_RESERVED_66 (66) /* Vector 66: Reserved */ +# define TIVA_RESERVED_67 (67) /* Vector 67: Reserved */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ + +# define NR_IRQS (71) /* (Really less because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */ +# define TIVA_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */ +# define TIVA_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */ +# define TIVA_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC0 Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC0 Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC0 Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC0 Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 3 */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_QEI1 (54) /* Vector 54: QEI1 */ +# define TIVA_IRQ_CAN0 (55) /* Vector 55: CAN 1 */ +# define TIVA_IRQ_CAN1 (56) /* Vector 56: CAN 2 */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */ +# define TIVA_RESERVED_59 (59) /* Vector 59: Reserved */ + +# define TIVA_IRQ_USB (60) /* Vector 60: USB */ +# define TIVA_IRQ_PWM3 (61) /* Vector 61: PWM Generator 3 */ +# define TIVA_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */ +# define TIVA_IRQ_I2S0 (68) /* Vector 68: I2S0 */ +# define TIVA_IRQ_EPI (69) /* Vector 69: EPI */ + +# define TIVA_IRQ_GPIOJ (70) /* Vector 70: GPIO Port J */ +# define TIVA_RESERVED_71 (71) /* Vector 71: Reserved */ + +# define NR_IRQS (72) /* (Really less because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S8962) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWMFAULT (25) /* Vector 25: PWM Fault */ +# define TIVA_IRQ_PWM0 (26) /* Vector 26: PWM Generator 0 */ +# define TIVA_IRQ_PWM1 (27) /* Vector 27: PWM Generator 1 */ +# define TIVA_IRQ_PWM2 (28) /* Vector 28: PWM Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timer */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_RESERVED_42 (42) /* Vector 42: Reserved */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_RESERVED_49 (49) /* Vector 49: Reserved */ + +# define TIVA_RESERVED_50 (50) /* Vector 50: Reserved */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_QEI1 (54) /* Vector 54: QEI1 */ +# define TIVA_IRQ_CAN0 (54) /* Vector 55: CAN0 */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_IRQ_ETHCON (58) /* Vector 58: Ethernet Controller */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_RESERVED_60 (60) /* Vector 60: Reserved */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ +# define TIVA_RESERVED_62 (62) /* Vector 62: Reserved */ +# define TIVA_RESERVED_63 (63) /* Vector 63: Reserved */ +# define TIVA_RESERVED_64 (64) /* Vector 64: Reserved */ +# define TIVA_RESERVED_65 (65) /* Vector 65: Reserved */ +# define TIVA_RESERVED_66 (66) /* Vector 66: Reserved */ +# define TIVA_RESERVED_67 (67) /* Vector 67: Reserved */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ + +# define NR_IRQS (71) /* (Really less because of reserved vectors) */ + +#else +# error "IRQ Numbers not specified for this Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TIVA_LM3S_IRQ_H */ diff --git a/arch/arm/include/tiva/lm4f_irq.h b/arch/arm/include/tiva/lm4f_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..c6d5d60107dbf9f271128b3c19eeb5778b30a2f9 --- /dev/null +++ b/arch/arm/include/tiva/lm4f_irq.h @@ -0,0 +1,244 @@ +/************************************************************************************ + * arch/arm/include/tiva/lm4f_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_LM4F_IRQ_H +#define __ARCH_ARM_INCLUDE_TIVA_LM4F_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define TIVA_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_LM4F120) + +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_RESERVED_25 (25) /* Vector 25: Reserved */ +# define TIVA_RESERVED_26 (26) /* Vector 26: Reserved */ +# define TIVA_RESERVED_27 (27) /* Vector 27: Reserved */ +# define TIVA_RESERVED_28 (28) /* Vector 28: Reserved */ +# define TIVA_RESERVED_29 (29) /* Vector 29: Reserved */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_RESERVED_43 (43) /* Vector 43: Reserved */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_RESERVED_47 (47) /* Vector 47: Reserved */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_RESERVED_54 (54) /* Vector 54: Reserved */ +# define TIVA_IRQ_CAN0 (55) /* Vector 55: CAN 0 */ +# define TIVA_RESERVED_56 (56) /* Vector 56: Reserved */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_RESERVED_58 (58) /* Vector 58: Reserved */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_IRQ_USB (60) /* Vector 60: USB */ +# define TIVA_RESERVED_61 (61) /* Vector 61: Reserved */ +# define TIVA_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ +# define TIVA_RESERVED_71 (71) /* Vector 71: Reserved */ +# define TIVA_RESERVED_72 (72) /* Vector 72: Reserved */ +# define TIVA_IRQ_SSI2 (73) /* Vector 73: SSI 2 */ +# define TIVA_IRQ_SSI3 (74) /* Vector 74: SSI 3 */ +# define TIVA_IRQ_UART3 (75) /* Vector 75: UART 3 */ +# define TIVA_IRQ_UART4 (76) /* Vector 76: UART 4 */ +# define TIVA_IRQ_UART5 (77) /* Vector 77: UART 5 */ +# define TIVA_IRQ_UART6 (78) /* Vector 78: UART 6 */ +# define TIVA_IRQ_UART7 (79) /* Vector 79: UART 7 */ + +# define TIVA_RESERVED_80 (80) /* Vector 80: Reserved */ +# define TIVA_RESERVED_81 (81) /* Vector 81: Reserved */ +# define TIVA_RESERVED_82 (82) /* Vector 82: Reserved */ +# define TIVA_RESERVED_83 (83) /* Vector 83: Reserved */ +# define TIVA_IRQ_I2C2 (84) /* Vector 84: I2C 2 */ +# define TIVA_IRQ_I2C3 (85) /* Vector 85: I2C 3 */ +# define TIVA_IRQ_TIMER4A (86) /* Vector 86: 16/32-Bit Timer 4 A */ +# define TIVA_IRQ_TIMER4B (87) /* Vector 87: 16/32-Bit Timer 4 B */ +# define TIVA_RESERVED_88 (88) /* Vector 88: Reserved */ +# define TIVA_RESERVED_89 (89) /* Vector 89: Reserved */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_RESERVED_91 (91) /* Vector 91: Reserved */ +# define TIVA_RESERVED_92 (92) /* Vector 92: Reserved */ +# define TIVA_RESERVED_93 (93) /* Vector 93: Reserved */ +# define TIVA_RESERVED_94 (94) /* Vector 94: Reserved */ +# define TIVA_RESERVED_95 (95) /* Vector 95: Reserved */ +# define TIVA_RESERVED_96 (96) /* Vector 96: Reserved */ +# define TIVA_RESERVED_97 (97) /* Vector 97: Reserved */ +# define TIVA_RESERVED_98 (98) /* Vector 98: Reserved */ +# define TIVA_RESERVED_99 (99) /* Vector 99: Reserved */ + +# define TIVA_RESERVED_100 (100) /* Vector 100: Reserved */ +# define TIVA_RESERVED_101 (101) /* Vector 101: Reserved */ +# define TIVA_RESERVED_102 (102) /* Vector 102: Reserved */ +# define TIVA_RESERVED_103 (103) /* Vector 103: Reserved */ +# define TIVA_RESERVED_104 (104) /* Vector 104: Reserved */ +# define TIVA_RESERVED_105 (105) /* Vector 105: Reserved */ +# define TIVA_RESERVED_106 (106) /* Vector 106: Reserved */ +# define TIVA_RESERVED_107 (107) /* Vector 107: Reserved */ +# define TIVA_IRQ_TIMER5A (108) /* Vector 108: 16/32-Bit Timer 5 A */ +# define TIVA_IRQ_TIMER5B (109) /* Vector 109: 16/32-Bit Timer 5 B */ + +# define TIVA_IRQ_WTIMER0A (110) /* Vector 110: 32/64-Bit Timer 0 A */ +# define TIVA_IRQ_WTIMER0B (111) /* Vector 111: 32/64-Bit Timer 0 B */ +# define TIVA_IRQ_WTIMER1A (112) /* Vector 112: 32/64-Bit Timer 1 A */ +# define TIVA_IRQ_WTIMER1B (113) /* Vector 113: 32/64-Bit Timer 1 B */ +# define TIVA_IRQ_WTIMER2A (114) /* Vector 114: 32/64-Bit Timer 2 A */ +# define TIVA_IRQ_WTIMER2B (115) /* Vector 115: 32/64-Bit Timer 2 B */ +# define TIVA_IRQ_WTIMER3A (116) /* Vector 116: 32/64-Bit Timer 3 A */ +# define TIVA_IRQ_WTIMER3B (117) /* Vector 117: 32/64-Bit Timer 3 B */ +# define TIVA_IRQ_WTIMER4A (118) /* Vector 118: 32/64-Bit Timer 4 A */ +# define TIVA_IRQ_WTIMER4B (119) /* Vector 119: 32/64-Bit Timer 4 B */ + +# define TIVA_IRQ_WTIMER5A (120) /* Vector 120: 32/64-Bit Timer 5 A */ +# define TIVA_IRQ_WTIMER5B (121) /* Vector 121: 32/64-Bit Timer 5 B */ +# define TIVA_IRQ_SYSTEM (122) /* Vector 122: System Exception (imprecise) */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_RESERVED_125 (125) /* Vector 125: Reserved */ +# define TIVA_RESERVED_126 (126) /* Vector 126: Reserved */ +# define TIVA_RESERVED_127 (127) /* Vector 127: Reserved */ +# define TIVA_RESERVED_128 (128) /* Vector 128: Reserved */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define TIVA_RESERVED_130 (130) /* Vector 130: Reserved */ +# define TIVA_RESERVED_131 (131) /* Vector 131: Reserved */ +# define TIVA_RESERVED_132 (132) /* Vector 132: Reserved */ +# define TIVA_RESERVED_133 (133) /* Vector 133: Reserved */ +# define TIVA_RESERVED_134 (134) /* Vector 134: Reserved */ +# define TIVA_RESERVED_135 (135) /* Vector 135: Reserved */ +# define TIVA_RESERVED_136 (136) /* Vector 136: Reserved */ +# define TIVA_RESERVED_137 (137) /* Vector 137: Reserved */ +# define TIVA_RESERVED_138 (138) /* Vector 138: Reserved */ +# define TIVA_RESERVED_139 (139) /* Vector 139: Reserved */ + +# define TIVA_RESERVED_140 (140) /* Vector 140: Reserved */ +# define TIVA_RESERVED_141 (141) /* Vector 141: Reserved */ +# define TIVA_RESERVED_142 (142) /* Vector 142: Reserved */ +# define TIVA_RESERVED_143 (143) /* Vector 143: Reserved */ +# define TIVA_RESERVED_144 (144) /* Vector 144: Reserved */ +# define TIVA_RESERVED_145 (145) /* Vector 145: Reserved */ +# define TIVA_RESERVED_146 (146) /* Vector 146: Reserved */ +# define TIVA_RESERVED_147 (147) /* Vector 147: Reserved */ +# define TIVA_RESERVED_148 (148) /* Vector 148: Reserved */ +# define TIVA_RESERVED_149 (149) /* Vector 149: Reserved */ + +# define TIVA_RESERVED_150 (150) /* Vector 150: Reserved */ +# define TIVA_RESERVED_151 (151) /* Vector 151: Reserved */ +# define TIVA_RESERVED_152 (152) /* Vector 152: Reserved */ +# define TIVA_RESERVED_153 (153) /* Vector 153: Reserved */ +# define TIVA_RESERVED_154 (154) /* Vector 154: Reserved */ + +# define NR_IRQS (155) /* (Really fewer because of reserved vectors) */ + +#else +# error "IRQ Numbers not known for this Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TIVA_LM4F_IRQ_H */ + diff --git a/arch/arm/include/tiva/tm4c_irq.h b/arch/arm/include/tiva/tm4c_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..77d8b0c9f7838bdde8d7a202b3c9242a39b4a8b4 --- /dev/null +++ b/arch/arm/include/tiva/tm4c_irq.h @@ -0,0 +1,659 @@ +/************************************************************************************ + * arch/arm/include/tiva/tm4c_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TIVA_TM4C_IRQ_H +#define __ARCH_ARM_INCLUDE_TIVA_TM4C_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* External interrupts (vectors >= 16) */ + +#define TIVA_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWM0_FAULT (25) /* Vector 25: PWM0 Fault */ +# define TIVA_IRQ_PWM0_GEN0 (26) /* Vector 26: PWM0 Generator 0 */ +# define TIVA_IRQ_PWM0_GEN1 (27) /* Vector 27: PWM0 Generator 1 */ +# define TIVA_IRQ_PWM0_GEN2 (28) /* Vector 28: PWM0 Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 2 */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_QEI1 (54) /* Vector 54: QEI1 */ +# define TIVA_IRQ_CAN0 (55) /* Vector 55: CAN 0 */ +# define TIVA_IRQ_CAN1 (56) /* Vector 56: CAN 1 */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_RESERVED_58 (58) /* Vector 58: Reserved */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_IRQ_USB (60) /* Vector 60: USB */ +# define TIVA_IRQ_PWM0_GEN3 (61) /* Vector 61: PWM0 Generator 3 */ +# define TIVA_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_IRQ_GPIOJ (70) /* Vector 70: GPIO Port J */ +# define TIVA_IRQ_GPIOK (71) /* Vector 71: GPIO Port K */ +# define TIVA_IRQ_GPIOL (72) /* Vector 72: GPIO Port L */ +# define TIVA_IRQ_SSI2 (73) /* Vector 73: SSI 2 */ +# define TIVA_IRQ_SSI3 (74) /* Vector 74: SSI 3 */ +# define TIVA_IRQ_UART3 (75) /* Vector 75: UART 3 */ +# define TIVA_IRQ_UART4 (76) /* Vector 76: UART 4 */ +# define TIVA_IRQ_UART5 (77) /* Vector 77: UART 5 */ +# define TIVA_IRQ_UART6 (78) /* Vector 78: UART 6 */ +# define TIVA_IRQ_UART7 (79) /* Vector 79: UART 7 */ + +# define TIVA_RESERVED_80 (80) /* Vector 80: Reserved */ +# define TIVA_RESERVED_81 (81) /* Vector 81: Reserved */ +# define TIVA_RESERVED_82 (82) /* Vector 82: Reserved */ +# define TIVA_RESERVED_83 (83) /* Vector 83: Reserved */ +# define TIVA_IRQ_I2C2 (84) /* Vector 84: I2C 2 */ +# define TIVA_IRQ_I2C3 (85) /* Vector 85: I2C 3 */ +# define TIVA_IRQ_TIMER4A (86) /* Vector 86: 16/32-Bit Timer 4 A */ +# define TIVA_IRQ_TIMER4B (87) /* Vector 87: 16/32-Bit Timer 4 B */ +# define TIVA_RESERVED_88 (88) /* Vector 88: Reserved */ +# define TIVA_RESERVED_89 (89) /* Vector 89: Reserved */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_RESERVED_91 (91) /* Vector 91: Reserved */ +# define TIVA_RESERVED_92 (92) /* Vector 92: Reserved */ +# define TIVA_RESERVED_93 (93) /* Vector 93: Reserved */ +# define TIVA_RESERVED_94 (94) /* Vector 94: Reserved */ +# define TIVA_RESERVED_95 (95) /* Vector 95: Reserved */ +# define TIVA_RESERVED_96 (96) /* Vector 96: Reserved */ +# define TIVA_RESERVED_97 (97) /* Vector 97: Reserved */ +# define TIVA_RESERVED_98 (98) /* Vector 98: Reserved */ +# define TIVA_RESERVED_99 (99) /* Vector 99: Reserved */ + +# define TIVA_RESERVED_100 (100) /* Vector 100: Reserved */ +# define TIVA_RESERVED_101 (101) /* Vector 101: Reserved */ +# define TIVA_RESERVED_102 (102) /* Vector 102: Reserved */ +# define TIVA_RESERVED_103 (103) /* Vector 103: Reserved */ +# define TIVA_RESERVED_104 (104) /* Vector 104: Reserved */ +# define TIVA_RESERVED_105 (105) /* Vector 105: Reserved */ +# define TIVA_RESERVED_106 (106) /* Vector 106: Reserved */ +# define TIVA_RESERVED_107 (107) /* Vector 107: Reserved */ +# define TIVA_IRQ_TIMER5A (108) /* Vector 108: 16/32-Bit Timer 5 A */ +# define TIVA_IRQ_TIMER5B (109) /* Vector 109: 16/32-Bit Timer 5 B */ + +# define TIVA_IRQ_WTIMER0A (110) /* Vector 110: 32/64-Bit Timer 0 A */ +# define TIVA_IRQ_WTIMER0B (111) /* Vector 111: 32/64-Bit Timer 0 B */ +# define TIVA_IRQ_WTIMER1A (112) /* Vector 112: 32/64-Bit Timer 1 A */ +# define TIVA_IRQ_WTIMER1B (113) /* Vector 113: 32/64-Bit Timer 1 B */ +# define TIVA_IRQ_WTIMER2A (114) /* Vector 114: 32/64-Bit Timer 2 A */ +# define TIVA_IRQ_WTIMER2B (115) /* Vector 115: 32/64-Bit Timer 2 B */ +# define TIVA_IRQ_WTIMER3A (116) /* Vector 116: 32/64-Bit Timer 3 A */ +# define TIVA_IRQ_WTIMER3B (117) /* Vector 117: 32/64-Bit Timer 3 B */ +# define TIVA_IRQ_WTIMER4A (118) /* Vector 118: 32/64-Bit Timer 4 A */ +# define TIVA_IRQ_WTIMER4B (119) /* Vector 119: 32/64-Bit Timer 4 B */ + +# define TIVA_IRQ_WTIMER5A (120) /* Vector 120: 32/64-Bit Timer 5 A */ +# define TIVA_IRQ_WTIMER5B (121) /* Vector 121: 32/64-Bit Timer 5 B */ +# define TIVA_IRQ_SYSTEM (122) /* Vector 122: System Exception (imprecise) */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_IRQ_I2C4 (125) /* Vector 125: I2C4 */ +# define TIVA_IRQ_I2C5 (126) /* Vector 126: I2C5 */ +# define TIVA_IRQ_GPIOM (127) /* Vector 127: GPIO Port M */ +# define TIVA_IRQ_GPION (128) /* Vector 128: GPIO Port N */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define TIVA_RESERVED_130 (130) /* Vector 130: Reserved */ +# define TIVA_RESERVED_131 (131) /* Vector 131: Reserved */ +# define TIVA_IRQ_GPIOP (132) /* Vector 132: GPIO Port P (Summary or P0) */ +# define TIVA_IRQ_GPIOP1 (133) /* Vector 133: GPIO Port P1 */ +# define TIVA_IRQ_GPIOP2 (134) /* Vector 134: GPIO Port P2 */ +# define TIVA_IRQ_GPIOP3 (135) /* Vector 135: GPIO Port P3 */ +# define TIVA_IRQ_GPIOP4 (136) /* Vector 136: GPIO Port P4 */ +# define TIVA_IRQ_GPIOP5 (137) /* Vector 137: GPIO Port P5 */ +# define TIVA_IRQ_GPIOP6 (138) /* Vector 138: GPIO Port P6 */ +# define TIVA_IRQ_GPIOP7 (139) /* Vector 139: GPIO Port P7 */ + +# define TIVA_IRQ_GPIOQ (140) /* Vector 140: GPIO Port Q (Summary or Q0) */ +# define TIVA_IRQ_GPIOQ1 (141) /* Vector 141: GPIO Port Q1 */ +# define TIVA_IRQ_GPIOQ2 (142) /* Vector 142: GPIO Port Q2 */ +# define TIVA_IRQ_GPIOQ3 (143) /* Vector 143: GPIO Port Q3 */ +# define TIVA_IRQ_GPIOQ4 (144) /* Vector 144: GPIO Port Q4 */ +# define TIVA_IRQ_GPIOQ5 (145) /* Vector 145: GPIO Port Q5 */ +# define TIVA_IRQ_GPIOQ6 (146) /* Vector 146: GPIO Port Q6 */ +# define TIVA_IRQ_GPIOQ7 (147) /* Vector 147: GPIO Port Q7 */ +# define TIVA_RESERVED_148 (148) /* Vector 148: Reserved */ +# define TIVA_RESERVED_149 (149) /* Vector 149: Reserved */ + +# define TIVA_IRQ_PWM1_GEN0 (150) /* Vector 150: PWM1 Generator 0 */ +# define TIVA_IRQ_PWM1_GEN1 (151) /* Vector 151: PWM1 Generator 1 */ +# define TIVA_IRQ_PWM1_GEN2 (152) /* Vector 152: PWM1 Generator 2 */ +# define TIVA_IRQ_PWM1_GEN3 (153) /* Vector 153: PWM1 Generator 3 */ +# define TIVA_IRQ_PWM1_FAULT (154) /* Vector 154: PWM1 Fault */ + +# define NR_IRQS (155) /* (Really fewer because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWM0_FAULT (25) /* Vector 25: PWM0 Fault */ +# define TIVA_IRQ_PWM0_GEN0 (26) /* Vector 26: PWM0 Generator 0 */ +# define TIVA_IRQ_PWM0_GEN1 (27) /* Vector 27: PWM0 Generator 1 */ +# define TIVA_IRQ_PWM0_GEN2 (28) /* Vector 28: PWM0 Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 2 */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_RESERVED_47 (47) /* Vector 47: Reserved */ +# define TIVA_RESERVED_48 (48) /* Vector 48: Reserved */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_QEI1 (54) /* Vector 54: QEI1 */ +# define TIVA_IRQ_CAN0 (55) /* Vector 55: CAN 0 */ +# define TIVA_IRQ_CAN1 (56) /* Vector 56: CAN 1 */ +# define TIVA_RESERVED_57 (57) /* Vector 57: Reserved */ +# define TIVA_RESERVED_58 (58) /* Vector 58: Reserved */ +# define TIVA_IRQ_HIBERNATE (59) /* Vector 59: Hibernation Module */ + +# define TIVA_IRQ_USB (60) /* Vector 60: USB */ +# define TIVA_IRQ_PWM0_GEN3 (61) /* Vector 61: PWM0 Generator 3 */ +# define TIVA_IRQ_UDMASOFT (62) /* Vector 62: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (63) /* Vector 63: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (64) /* Vector 64: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (65) /* Vector 65: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (66) /* Vector 66: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (67) /* Vector 67: ADC1 Sequence 3 */ +# define TIVA_RESERVED_68 (68) /* Vector 68: Reserved */ +# define TIVA_RESERVED_69 (69) /* Vector 69: Reserved */ + +# define TIVA_RESERVED_70 (70) /* Vector 70: Reserved */ +# define TIVA_RESERVED_71 (71) /* Vector 71: Reserved */ +# define TIVA_RESERVED_72 (72) /* Vector 72: Reserved */ +# define TIVA_IRQ_SSI2 (73) /* Vector 73: SSI 2 */ +# define TIVA_IRQ_SSI3 (74) /* Vector 74: SSI 3 */ +# define TIVA_IRQ_UART3 (75) /* Vector 75: UART 3 */ +# define TIVA_IRQ_UART4 (76) /* Vector 76: UART 4 */ +# define TIVA_IRQ_UART5 (77) /* Vector 77: UART 5 */ +# define TIVA_IRQ_UART6 (78) /* Vector 78: UART 6 */ +# define TIVA_IRQ_UART7 (79) /* Vector 79: UART 7 */ + +# define TIVA_RESERVED_80 (80) /* Vector 80: Reserved */ +# define TIVA_RESERVED_81 (81) /* Vector 81: Reserved */ +# define TIVA_RESERVED_82 (82) /* Vector 82: Reserved */ +# define TIVA_RESERVED_83 (83) /* Vector 83: Reserved */ +# define TIVA_IRQ_I2C2 (84) /* Vector 84: I2C 2 */ +# define TIVA_IRQ_I2C3 (85) /* Vector 85: I2C 3 */ +# define TIVA_IRQ_TIMER4A (86) /* Vector 86: 16/32-Bit Timer 4 A */ +# define TIVA_IRQ_TIMER4B (87) /* Vector 87: 16/32-Bit Timer 4 B */ +# define TIVA_RESERVED_88 (88) /* Vector 88: Reserved */ +# define TIVA_RESERVED_89 (89) /* Vector 89: Reserved */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_RESERVED_91 (91) /* Vector 91: Reserved */ +# define TIVA_RESERVED_92 (92) /* Vector 92: Reserved */ +# define TIVA_RESERVED_93 (93) /* Vector 93: Reserved */ +# define TIVA_RESERVED_94 (94) /* Vector 94: Reserved */ +# define TIVA_RESERVED_95 (95) /* Vector 95: Reserved */ +# define TIVA_RESERVED_96 (96) /* Vector 96: Reserved */ +# define TIVA_RESERVED_97 (97) /* Vector 97: Reserved */ +# define TIVA_RESERVED_98 (98) /* Vector 98: Reserved */ +# define TIVA_RESERVED_99 (99) /* Vector 99: Reserved */ + +# define TIVA_RESERVED_100 (100) /* Vector 100: Reserved */ +# define TIVA_RESERVED_101 (101) /* Vector 101: Reserved */ +# define TIVA_RESERVED_102 (102) /* Vector 102: Reserved */ +# define TIVA_RESERVED_103 (103) /* Vector 103: Reserved */ +# define TIVA_RESERVED_104 (104) /* Vector 104: Reserved */ +# define TIVA_RESERVED_105 (105) /* Vector 105: Reserved */ +# define TIVA_RESERVED_106 (106) /* Vector 106: Reserved */ +# define TIVA_RESERVED_107 (107) /* Vector 107: Reserved */ +# define TIVA_IRQ_TIMER5A (108) /* Vector 108: 16/32-Bit Timer 5 A */ +# define TIVA_IRQ_TIMER5B (109) /* Vector 109: 16/32-Bit Timer 5 B */ + +# define TIVA_IRQ_WTIMER0A (110) /* Vector 110: 32/64-Bit Timer 0 A */ +# define TIVA_IRQ_WTIMER0B (111) /* Vector 111: 32/64-Bit Timer 0 B */ +# define TIVA_IRQ_WTIMER1A (112) /* Vector 112: 32/64-Bit Timer 1 A */ +# define TIVA_IRQ_WTIMER1B (113) /* Vector 113: 32/64-Bit Timer 1 B */ +# define TIVA_IRQ_WTIMER2A (114) /* Vector 114: 32/64-Bit Timer 2 A */ +# define TIVA_IRQ_WTIMER2B (115) /* Vector 115: 32/64-Bit Timer 2 B */ +# define TIVA_IRQ_WTIMER3A (116) /* Vector 116: 32/64-Bit Timer 3 A */ +# define TIVA_IRQ_WTIMER3B (117) /* Vector 117: 32/64-Bit Timer 3 B */ +# define TIVA_IRQ_WTIMER4A (118) /* Vector 118: 32/64-Bit Timer 4 A */ +# define TIVA_IRQ_WTIMER4B (119) /* Vector 119: 32/64-Bit Timer 4 B */ + +# define TIVA_IRQ_WTIMER5A (120) /* Vector 120: 32/64-Bit Timer 5 A */ +# define TIVA_IRQ_WTIMER5B (121) /* Vector 121: 32/64-Bit Timer 5 B */ +# define TIVA_IRQ_SYSTEM (122) /* Vector 122: System Exception (imprecise) */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_RESERVED_125 (125) /* Vector 125: Reserved */ +# define TIVA_RESERVED_126 (126) /* Vector 126: Reserved */ +# define TIVA_RESERVED_127 (127) /* Vector 127: Reserved */ +# define TIVA_RESERVED_128 (128) /* Vector 128: Reserved */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define TIVA_RESERVED_130 (130) /* Vector 130: Reserved */ +# define TIVA_RESERVED_131 (131) /* Vector 131: Reserved */ +# define TIVA_RESERVED_132 (132) /* Vector 132: Reserved */ +# define TIVA_RESERVED_133 (133) /* Vector 133: Reserved */ +# define TIVA_RESERVED_134 (134) /* Vector 134: Reserved */ +# define TIVA_RESERVED_135 (135) /* Vector 135: Reserved */ +# define TIVA_RESERVED_136 (136) /* Vector 136: Reserved */ +# define TIVA_RESERVED_137 (137) /* Vector 137: Reserved */ +# define TIVA_RESERVED_138 (138) /* Vector 138: Reserved */ +# define TIVA_RESERVED_139 (139) /* Vector 139: Reserved */ + +# define TIVA_RESERVED_140 (140) /* Vector 140: Reserved */ +# define TIVA_RESERVED_141 (141) /* Vector 141: Reserved */ +# define TIVA_RESERVED_142 (142) /* Vector 142: Reserved */ +# define TIVA_RESERVED_143 (143) /* Vector 143: Reserved */ +# define TIVA_RESERVED_144 (144) /* Vector 144: Reserved */ +# define TIVA_RESERVED_145 (145) /* Vector 145: Reserved */ +# define TIVA_RESERVED_146 (146) /* Vector 146: Reserved */ +# define TIVA_RESERVED_147 (147) /* Vector 147: Reserved */ +# define TIVA_RESERVED_148 (148) /* Vector 148: Reserved */ +# define TIVA_RESERVED_149 (149) /* Vector 149: Reserved */ + +# define TIVA_IRQ_PWM1_GEN0 (150) /* Vector 150: PWM1 Generator 0 */ +# define TIVA_IRQ_PWM1_GEN1 (151) /* Vector 151: PWM1 Generator 1 */ +# define TIVA_IRQ_PWM1_GEN2 (152) /* Vector 152: PWM1 Generator 2 */ +# define TIVA_IRQ_PWM1_GEN3 (153) /* Vector 153: PWM1 Generator 3 */ +# define TIVA_IRQ_PWM1_FAULT (154) /* Vector 154: PWM1 Fault */ + +# define NR_IRQS (155) /* (Really fewer because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) + +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWM0_FAULT (25) /* Vector 25: PWM0 Fault */ +# define TIVA_IRQ_PWM0_GEN0 (26) /* Vector 26: PWM0 Generator 0 */ +# define TIVA_IRQ_PWM0_GEN1 (27) /* Vector 27: PWM0 Generator 1 */ +# define TIVA_IRQ_PWM0_GEN2 (28) /* Vector 28: PWM0 Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 2 */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_CAN0 (54) /* Vector 54: CAN 0 */ +# define TIVA_IRQ_CAN1 (55) /* Vector 55: CAN 1 */ +# define TIVA_IRQ_ETHCON (56) /* Vector 56: Ethernet MAC */ +# define TIVA_IRQ_HIBERNATE (57) /* Vector 57: Hibernation Module */ +# define TIVA_IRQ_USB (58) /* Vector 58: USB MAC */ +# define TIVA_IRQ_PWM0_GEN3 (59) /* Vector 59: PWM0 Generator 3 */ + +# define TIVA_IRQ_UDMASOFT (60) /* Vector 60: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (61) /* Vector 61: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (62) /* Vector 62: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (63) /* Vector 63: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (64) /* Vector 64: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (65) /* Vector 65: ADC1 Sequence 3 */ +# define TIVA_IRQ_EPI0 (66) /* Vector 66: EPI 0 */ +# define TIVA_IRQ_GPIOJ (67) /* Vector 67: GPIO Port J */ +# define TIVA_IRQ_GPIOK (68) /* Vector 68: GPIO Port K */ +# define TIVA_IRQ_GPIOL (69) /* Vector 69: GPIO Port L */ + +# define TIVA_IRQ_SSI2 (70) /* Vector 70: SSI 2 */ +# define TIVA_IRQ_SSI3 (71) /* Vector 71: SSI 3 */ +# define TIVA_IRQ_UART3 (72) /* Vector 72: UART 3 */ +# define TIVA_IRQ_UART4 (73) /* Vector 73: UART 4 */ +# define TIVA_IRQ_UART5 (74) /* Vector 74: UART 5 */ +# define TIVA_IRQ_UART6 (75) /* Vector 75: UART 6 */ +# define TIVA_IRQ_UART7 (76) /* Vector 76: UART 7 */ +# define TIVA_IRQ_I2C2 (77) /* Vector 77: I2C 2 */ +# define TIVA_IRQ_I2C3 (78) /* Vector 78: I2C 3 */ +# define TIVA_IRQ_TIMER4A (79) /* Vector 79: 16/32-Bit Timer 4 A */ + +# define TIVA_IRQ_TIMER4B (80) /* Vector 80: 16/32-Bit Timer 4 B */ +# define TIVA_IRQ_TIMER5A (81) /* Vector 81: 16/32-Bit Timer 5 A */ +# define TIVA_IRQ_TIMER5B (82) /* Vector 82: 16/32-Bit Timer 5 B */ +# define TIVA_IRQ_FLOAT (83) /* Vector 83: Floating point exception */ +# define TIVA_RESERVED_84 (84) /* Vector 84: Reserved */ +# define TIVA_RESERVED_85 (85) /* Vector 85: Reserved */ +# define TIVA_IRQ_I2C4 (86) /* Vector 86: I2C 4 */ +# define TIVA_IRQ_I2C5 (87) /* Vector 87: I2C 5 */ +# define TIVA_IRQ_GPIOM (88) /* Vector 88: GPIO Port M */ +# define TIVA_IRQ_GPION (89) /* Vector 89: GPIO Port N */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_IRQ_TAMPER (91) /* Vector 91: Tamper */ +# define TIVA_IRQ_GPIOP (92) /* Vector 92: GPIO Port P (Summary or P0) */ +# define TIVA_IRQ_GPIOP1 (93) /* Vector 93: GPIO Port P1 */ +# define TIVA_IRQ_GPIOP2 (94) /* Vector 94: GPIO Port P2 */ +# define TIVA_IRQ_GPIOP3 (95) /* Vector 95: GPIO Port P3 */ +# define TIVA_IRQ_GPIOP4 (96) /* Vector 96: GPIO Port P4 */ +# define TIVA_IRQ_GPIOP5 (97) /* Vector 97: GPIO Port P5 */ +# define TIVA_IRQ_GPIOP6 (98) /* Vector 98: GPIO Port P6 */ +# define TIVA_IRQ_GPIOP7 (99) /* Vector 99: GPIO Port P7 */ + +# define TIVA_IRQ_GPIOQ (100) /* Vector 100: GPIO Port Q (Summary or Q0) */ +# define TIVA_IRQ_GPIOQ1 (101) /* Vector 101: GPIO Port Q1 */ +# define TIVA_IRQ_GPIOQ2 (102) /* Vector 102: GPIO Port Q2 */ +# define TIVA_IRQ_GPIOQ3 (103) /* Vector 103: GPIO Port Q3 */ +# define TIVA_IRQ_GPIOQ4 (104) /* Vector 104: GPIO Port Q4 */ +# define TIVA_IRQ_GPIOQ5 (105) /* Vector 105: GPIO Port Q5 */ +# define TIVA_IRQ_GPIOQ6 (106) /* Vector 106: GPIO Port Q6 */ +# define TIVA_IRQ_GPIOQ7 (107) /* Vector 107: GPIO Port Q7 */ +# define TIVA_IRQ_GPIOR (108) /* Vector 108: GPIO Port R */ +# define TIVA_IRQ_GPIOS (109) /* Vector 109: GPIO Port S */ + +# define TIVA_IRQ_SHAMD5 (110) /* Vector 110: SHA/MD5 */ +# define TIVA_IRQ_AES (111) /* Vector 111: AES */ +# define TIVA_IRQ_DES (112) /* Vector 112: DES */ +# define TIVA_IRQ_LCD (113) /* Vector 113: LCD */ +# define TIVA_IRQ_TIMER6A (114) /* Vector 114: 16/32-Bit Timer 6 A */ +# define TIVA_IRQ_TIMER6B (115) /* Vector 115: 16/32-Bit Timer 6 B */ +# define TIVA_IRQ_TIMER7A (116) /* Vector 116: 16/32-Bit Timer 7 A */ +# define TIVA_IRQ_TIMER7B (117) /* Vector 117: 16/32-Bit Timer 7 B */ +# define TIVA_IRQ_I2C6 (118) /* Vector 118: I2C 6 */ +# define TIVA_IRQ_I2C7 (119) /* Vector 119: I2C 7 */ + +# define TIVA_RESERVED_120 (120) /* Vector 120: Reserved */ +# define TIVA_IRQ_1WIRE (121) /* Vector 121: 1-Wire */ +# define TIVA_RESERVED_122 (122) /* Vector 122: Reserved */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_IRQ_I2C8 (125) /* Vector 125: I2C 8 */ +# define TIVA_IRQ_I2C9 (126) /* Vector 126: I2C 9 */ +# define TIVA_IRQ_GPIOT (127) /* Vector 127: GPIO Port T */ +# define TIVA_RESERVED_128 (128) /* Vector 128: Reserved */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define NR_IRQS (130) /* (Really fewer because of reserved vectors) */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C1294NC) +# define TIVA_IRQ_GPIOA (16) /* Vector 16: GPIO Port A */ +# define TIVA_IRQ_GPIOB (17) /* Vector 17: GPIO Port B */ +# define TIVA_IRQ_GPIOC (18) /* Vector 18: GPIO Port C */ +# define TIVA_IRQ_GPIOD (19) /* Vector 19: GPIO Port D */ + +# define TIVA_IRQ_GPIOE (20) /* Vector 20: GPIO Port E */ +# define TIVA_IRQ_UART0 (21) /* Vector 21: UART 0 */ +# define TIVA_IRQ_UART1 (22) /* Vector 22: UART 1 */ +# define TIVA_IRQ_SSI0 (23) /* Vector 23: SSI 0 */ +# define TIVA_IRQ_I2C0 (24) /* Vector 24: I2C 0 */ +# define TIVA_IRQ_PWM0_FAULT (25) /* Vector 25: PWM0 Fault */ +# define TIVA_IRQ_PWM0_GEN0 (26) /* Vector 26: PWM0 Generator 0 */ +# define TIVA_IRQ_PWM0_GEN1 (27) /* Vector 27: PWM0 Generator 1 */ +# define TIVA_IRQ_PWM0_GEN2 (28) /* Vector 28: PWM0 Generator 2 */ +# define TIVA_IRQ_QEI0 (29) /* Vector 29: QEI0 */ + +# define TIVA_IRQ_ADC0 (30) /* Vector 30: ADC Sequence 0 */ +# define TIVA_IRQ_ADC1 (31) /* Vector 31: ADC Sequence 1 */ +# define TIVA_IRQ_ADC2 (32) /* Vector 32: ADC Sequence 2 */ +# define TIVA_IRQ_ADC3 (33) /* Vector 33: ADC Sequence 3 */ +# define TIVA_IRQ_WDOG (34) /* Vector 34: Watchdog Timers 0 and 1 */ +# define TIVA_IRQ_TIMER0A (35) /* Vector 35: 16/32-Bit Timer 0 A */ +# define TIVA_IRQ_TIMER0B (36) /* Vector 36: 16/32-Bit Timer 0 B */ +# define TIVA_IRQ_TIMER1A (37) /* Vector 37: 16/32-Bit Timer 1 A */ +# define TIVA_IRQ_TIMER1B (38) /* Vector 38: 16/32-Bit Timer 1 B */ +# define TIVA_IRQ_TIMER2A (39) /* Vector 39: 16/32-Bit Timer 2 A */ + +# define TIVA_IRQ_TIMER2B (40) /* Vector 40: 16/32-Bit Timer 2 B */ +# define TIVA_IRQ_COMPARE0 (41) /* Vector 41: Analog Comparator 0 */ +# define TIVA_IRQ_COMPARE1 (42) /* Vector 42: Analog Comparator 1 */ +# define TIVA_IRQ_COMPARE2 (43) /* Vector 43: Analog Comparator 2 */ +# define TIVA_IRQ_SYSCON (44) /* Vector 44: System Control */ +# define TIVA_IRQ_FLASHCON (45) /* Vector 45: FLASH and EEPROM Control */ +# define TIVA_IRQ_GPIOF (46) /* Vector 46: GPIO Port F */ +# define TIVA_IRQ_GPIOG (47) /* Vector 47: GPIO Port G */ +# define TIVA_IRQ_GPIOH (48) /* Vector 48: GPIO Port H */ +# define TIVA_IRQ_UART2 (49) /* Vector 49: UART 2 */ + +# define TIVA_IRQ_SSI1 (50) /* Vector 50: SSI 1 */ +# define TIVA_IRQ_TIMER3A (51) /* Vector 51: 16/32-Bit Timer 3 A */ +# define TIVA_IRQ_TIMER3B (52) /* Vector 52: 16/32-Bit Timer 3 B */ +# define TIVA_IRQ_I2C1 (53) /* Vector 53: I2C 1 */ +# define TIVA_IRQ_CAN0 (54) /* Vector 54: CAN 0 */ +# define TIVA_IRQ_CAN1 (55) /* Vector 55: CAN 1 */ +# define TIVA_IRQ_ETHCON (56) /* Vector 56: Ethernet MAC */ +# define TIVA_IRQ_HIBERNATE (57) /* Vector 57: Hibernation Module */ +# define TIVA_IRQ_USB (58) /* Vector 58: USB MAC */ +# define TIVA_IRQ_PWM0_GEN3 (59) /* Vector 59: PWM0 Generator 3 */ + +# define TIVA_IRQ_UDMASOFT (60) /* Vector 60: uDMA Software */ +# define TIVA_IRQ_UDMAERROR (61) /* Vector 61: uDMA Error */ +# define TIVA_IRQ_ADC1_0 (62) /* Vector 62: ADC1 Sequence 0 */ +# define TIVA_IRQ_ADC1_1 (63) /* Vector 63: ADC1 Sequence 1 */ +# define TIVA_IRQ_ADC1_2 (64) /* Vector 64: ADC1 Sequence 2 */ +# define TIVA_IRQ_ADC1_3 (65) /* Vector 65: ADC1 Sequence 3 */ +# define TIVA_IRQ_EPI0 (66) /* Vector 66: EPI 0 */ +# define TIVA_IRQ_GPIOJ (67) /* Vector 67: GPIO Port J */ +# define TIVA_IRQ_GPIOK (68) /* Vector 68: GPIO Port K */ +# define TIVA_IRQ_GPIOL (69) /* Vector 69: GPIO Port L */ + +# define TIVA_IRQ_SSI2 (70) /* Vector 70: SSI 2 */ +# define TIVA_IRQ_SSI3 (71) /* Vector 71: SSI 3 */ +# define TIVA_IRQ_UART3 (72) /* Vector 72: UART 3 */ +# define TIVA_IRQ_UART4 (73) /* Vector 73: UART 4 */ +# define TIVA_IRQ_UART5 (74) /* Vector 74: UART 5 */ +# define TIVA_IRQ_UART6 (75) /* Vector 75: UART 6 */ +# define TIVA_IRQ_UART7 (76) /* Vector 76: UART 7 */ +# define TIVA_IRQ_I2C2 (77) /* Vector 77: I2C 2 */ +# define TIVA_IRQ_I2C3 (78) /* Vector 78: I2C 3 */ +# define TIVA_IRQ_TIMER4A (79) /* Vector 79: 16/32-Bit Timer 4 A */ + +# define TIVA_IRQ_TIMER4B (80) /* Vector 80: 16/32-Bit Timer 4 B */ +# define TIVA_IRQ_TIMER5A (81) /* Vector 81: 16/32-Bit Timer 5 A */ +# define TIVA_IRQ_TIMER5B (82) /* Vector 82: 16/32-Bit Timer 5 B */ +# define TIVA_IRQ_FLOAT (83) /* Vector 83: Floating point exception */ +# define TIVA_RESERVED_84 (84) /* Vector 84: Reserved */ +# define TIVA_RESERVED_85 (85) /* Vector 85: Reserved */ +# define TIVA_IRQ_I2C4 (86) /* Vector 86: I2C 4 */ +# define TIVA_IRQ_I2C5 (87) /* Vector 87: I2C 5 */ +# define TIVA_IRQ_GPIOM (88) /* Vector 88: GPIO Port M */ +# define TIVA_IRQ_GPION (89) /* Vector 89: GPIO Port N */ + +# define TIVA_RESERVED_90 (90) /* Vector 90: Reserved */ +# define TIVA_IRQ_TAMPER (91) /* Vector 91: Tamper */ +# define TIVA_IRQ_GPIOP (92) /* Vector 92: GPIO Port P (Summary or P0) */ +# define TIVA_IRQ_GPIOP1 (93) /* Vector 93: GPIO Port P1 */ +# define TIVA_IRQ_GPIOP2 (94) /* Vector 94: GPIO Port P2 */ +# define TIVA_IRQ_GPIOP3 (95) /* Vector 95: GPIO Port P3 */ +# define TIVA_IRQ_GPIOP4 (96) /* Vector 96: GPIO Port P4 */ +# define TIVA_IRQ_GPIOP5 (97) /* Vector 97: GPIO Port P5 */ +# define TIVA_IRQ_GPIOP6 (98) /* Vector 98: GPIO Port P6 */ +# define TIVA_IRQ_GPIOP7 (99) /* Vector 99: GPIO Port P7 */ + +# define TIVA_IRQ_GPIOQ (100) /* Vector 100: GPIO Port Q (Summary or Q0) */ +# define TIVA_IRQ_GPIOQ1 (101) /* Vector 101: GPIO Port Q1 */ +# define TIVA_IRQ_GPIOQ2 (102) /* Vector 102: GPIO Port Q2 */ +# define TIVA_IRQ_GPIOQ3 (103) /* Vector 103: GPIO Port Q3 */ +# define TIVA_IRQ_GPIOQ4 (104) /* Vector 104: GPIO Port Q4 */ +# define TIVA_IRQ_GPIOQ5 (105) /* Vector 105: GPIO Port Q5 */ +# define TIVA_IRQ_GPIOQ6 (106) /* Vector 106: GPIO Port Q6 */ +# define TIVA_IRQ_GPIOQ7 (107) /* Vector 107: GPIO Port Q7 */ +# define TIVA_RESERVED_108 (108) /* Vector 108: Reserved */ +# define TIVA_RESERVED_109 (109) /* Vector 109: Reserved */ + +# define TIVA_RESERVED_110 (110) /* Vector 110: Reserved */ +# define TIVA_RESERVED_111 (111) /* Vector 111: Reserved */ +# define TIVA_RESERVED_112 (113) /* Vector 112: Reserved */ +# define TIVA_RESERVED_113 (113) /* Vector 113: Reserved */ +# define TIVA_IRQ_TIMER6A (114) /* Vector 114: 16/32-Bit Timer 6 A */ +# define TIVA_IRQ_TIMER6B (115) /* Vector 115: 16/32-Bit Timer 6 B */ +# define TIVA_IRQ_TIMER7A (116) /* Vector 116: 16/32-Bit Timer 7 A */ +# define TIVA_IRQ_TIMER7B (117) /* Vector 117: 16/32-Bit Timer 7 B */ +# define TIVA_IRQ_I2C6 (118) /* Vector 118: I2C 6 */ +# define TIVA_IRQ_I2C7 (119) /* Vector 119: I2C 7 */ + +# define TIVA_RESERVED_120 (120) /* Vector 120: Reserved */ +# define TIVA_RESERVED_121 (121) /* Vector 121: Reserved */ +# define TIVA_RESERVED_122 (122) /* Vector 122: Reserved */ +# define TIVA_RESERVED_123 (123) /* Vector 123: Reserved */ +# define TIVA_RESERVED_124 (124) /* Vector 124: Reserved */ +# define TIVA_IRQ_I2C8 (125) /* Vector 125: I2C 8 */ +# define TIVA_IRQ_I2C9 (126) /* Vector 126: I2C 9 */ +# define TIVA_RESERVED_127 (127) /* Vector 127: Reserved */ +# define TIVA_RESERVED_128 (128) /* Vector 128: Reserved */ +# define TIVA_RESERVED_129 (129) /* Vector 129: Reserved */ + +# define NR_IRQS (130) /* (Really fewer because of reserved vectors) */ + +#else +# error "IRQ Numbers not known for this Tiva chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TIVA_TM4C_IRQ_H */ + diff --git a/arch/arm/include/tls.h b/arch/arm/include/tls.h new file mode 100644 index 0000000000000000000000000000000000000000..0678647510feace2cc21b13446e4e45e62268511 --- /dev/null +++ b/arch/arm/include/tls.h @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/include/tls.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TLS_H +#define __ARCH_ARM_INCLUDE_TLS_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#ifdef CONFIG_TLS + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + + return sp; +} + +/**************************************************************************** + * Name: up_tls_info + * + * Description: + * Return the TLS information structure for the currently executing thread. + * When TLS is enabled, up_createstack() will align allocated stacks to + * the TLS_STACK_ALIGN value. An instance of the following structure will + * be implicitly positioned at the "lower" end of the stack. Assuming a + * "push down" stack, this is at the "far" end of the stack (and can be + * clobbered if the stack overflows). + * + * If an MCU has a "push up" then that TLS structure will lie at the top + * of the stack and stack allocation and initialization logic must take + * care to preserve this structure content. + * + * The stack memory is fully accessible to user mode threads. + * + * Input Parameters: + * None + * + * Returned Value: + * A pointer to TLS info structure at the beginning of the STACK memory + * allocation. This is essentially an application of the TLS_INFO(sp) + * macro and has a platform dependency only in the manner in which the + * stack pointer (sp) is obtained and interpreted. + * + ****************************************************************************/ + +static inline FAR struct tls_info_s *up_tls_info(void) +{ + DEBUGASSERT(!up_interrupt_context()); + return TLS_INFO((uintptr_t)up_getsp()); +} + +#endif /* CONFIG_TLS */ +#endif /* __ARCH_ARM_INCLUDE_TLS_H */ diff --git a/arch/arm/include/tms570/chip.h b/arch/arm/include/tms570/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..dcff36c2347fcace563546832218fd2b6505b434 --- /dev/null +++ b/arch/arm/include/tms570/chip.h @@ -0,0 +1,361 @@ +/**************************************************************************************************** + * arch/arm/include/tms570/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_TMS570_CHIP_H +#define __ARCH_ARM_INCLUDE_TMS570_CHIP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* TMS570LS0432PZ TMS570LS0332PZ TMS570LS0232PZ + * Package 100 QFP 100 QFP 100 QFP + * CPU ARM Cortex-R4 ARM Cortex-R4 ARM Cortex-R4 + * Frequency (MHz) 80 80 80 + * Flash (KB) 384 256 128 + * RAM (KB) 32 32 32 + * Data Flash (KB) 16 16 16 + * EMAC – – – + * FlexRay – – – + * CAN 2 2 2 + * MibADC (CH) 1 (16) 1 (16) 1 (16) + * N2HET (Ch) 1 (19) 1 (19) 1 (19) + * ePWM Channels – – – + * eCAP Channels 0 0 0 + * eQEP Channels 1 1 1 + * MibSPI (CS) 1 (4) 1 (4) 1 (4) + * SPI (CS) 2 2 2 + * SCI (LIN) 1 (1) 1 (1) 1 (1) + * I2C – – – + * GPIO (INT) 45 (8) 45 (9) 45 (8) + * EMIF – – – + * ETM (Trace) – – – + * RTP/DMM – – – + */ + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ) +# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */ +# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (128*2014) /* 128 KB Program FLASH */ +# define TMS570_SRAM (32*1024) /* 32 KB SRAM */ +# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 2 /* Two CAN */ +# define TMS570_NMIBADC 1 /* One MiBADC */ +# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */ +# define TMS570_NN2HET 1 /* One N2HET */ +# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */ +# define TMS570_EPWM_NCH 0 /* No ePWM channels */ +# define TMS570_ECAP_NCH 0 /* No eCAP channels */ +# define TMS570_EQEP_NCH 1 /* One eQEP channel */ +# define TMS570_NMIBSPI 1 /* One MibSPI */ +# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */ +# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */ +# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */ +# define TMS570_NSPI 2 /* Two SPI */ +# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */ +# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */ +# define TMS570_NSCI 1 /* One SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 0 /* No I2C */ +# define TMS570_NGPIOINT 8 /* 8 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) +# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */ +# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (256*2014) /* 256 KB Program FLASH */ +# define TMS570_SRAM (32*1024) /* 32 KB SRAM */ +# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 2 /* Two CAN */ +# define TMS570_NMIBADC 1 /* One MiBADC */ +# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */ +# define TMS570_NN2HET 1 /* One N2HET */ +# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */ +# define TMS570_EPWM_NCH 0 /* No ePWM channels */ +# define TMS570_ECAP_NCH 0 /* No eCAP channels */ +# define TMS570_EQEP_NCH 1 /* One eQEP channel */ +# define TMS570_NMIBSPI 1 /* One MibSPI */ +# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */ +# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */ +# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */ +# define TMS570_NSPI 2 /* Two SPI */ +# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */ +# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */ +# define TMS570_NSCI 1 /* One SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 0 /* No I2C */ +# define TMS570_NGPIOINT 9 /* 9 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) +# define TMS570_CORTEX_R4 1 /* Cortex-R4 family */ +# undef TMS570_CORTEX_R4F /* Not Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (384*2014) /* 384 KB Program FLASH */ +# define TMS570_SRAM (32*1024) /* 32 KB SRAM */ +# define TMS570_DFLASH (16*1024) /* 16 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 2 /* Two CAN */ +# define TMS570_NMIBADC 1 /* One MiBADC */ +# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */ +# define TMS570_NN2HET 1 /* One N2HET */ +# define TMS570_N2HET_NCH 19 /* 19 N2HET channels */ +# define TMS570_EPWM_NCH 0 /* No ePWM channels */ +# define TMS570_ECAP_NCH 0 /* No eCAP channels */ +# define TMS570_EQEP_NCH 1 /* One eQEP channel */ +# define TMS570_NMIBSPI 1 /* One MibSPI */ +# define TMS570_MIBSPI1_NCS 4 /* MibSPI1: 4 chip selects */ +# define TMS570_MIBSPI2_NCS 0 /* MibSPI2: No chip selects */ +# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */ +# define TMS570_NSPI 2 /* Two SPI */ +# define TMS570_SPI1_NCS 0 /* SPI1: No chip selects */ +# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */ +# define TMS570_NSCI 1 /* One SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 0 /* No I2C */ +# define TMS570_NGPIOINT 8 /* 8 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +/* TMS570LS1227ZWT TMS570LS0714ZWT TMS570LS0714PGE TMS570LS0714PZ + * Package 337 BGA 337 BGA 144 QFP 100 QFP + * CPU ARM Cortex-R4F ARM Cortex-R4F ARM Cortex-R4F ARM Cortex-R4F + * Frequency (MHz) 180 180 160 100 + * Flash (KB) 1280 768 768 768 + * RAM (KB) 192 128 128 128 + * Data Flash (KB) 64 64 64 64 + * EMAC 10/100 – – – + * FlexRay 2-ch – – – + * CAN 3 3 3 2 + * MibADC (CH) 2 (24) 2 (24) 2 (24) 2 (16) + * N2HET (Ch) 2 (44) 2 (44) 2 (40) 2 (21) + * ePWM Channels 14 14 14 8 + * eCAP Channels 6 6 6 4 + * eQEP Channels 2 2 2 1 + * MibSPI (CS) 3 (6+6+4) 3 (6+6+4) 3 (5+6+4) 2 (5+1) + * SPI (CS) 2 (2+1) 2 (2+1) 1 (1) 1 (1) + * SCI (LIN) 2 (1) 2 (1) 2 (1) 1 (1) + * I2C 1 1 1 – + * GPIO (INT) 101 (16) 101 (16) 64 (10) 45 (9) + * EMIF 16-bit data – – – + * ETM (Trace) – – – – + * RTP/DMM – – – – + */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ) +# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */ +# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */ +# define TMS570_SRAM (128*1024) /* 128 KB SRAM */ +# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 3 /* Three CAN */ +# define TMS570_NMIBADC 2 /* Two MiBADC */ +# define TMS570_MIBADC_NCH 16 /* 16 MibADC channels */ +# define TMS570_NN2HET 2 /* Two N2HET */ +# define TMS570_N2HET_NCH 21 /* 21 N2HET channels */ +# define TMS570_EPWM_NCH 8 /* 8 ePWM channels */ +# define TMS570_ECAP_NCH 4 /* 4 eCAP channels */ +# define TMS570_EQEP_NCH 1 /* 1 eQEP channels */ +# define TMS570_NMIBSPI 2 /* 2 MibSPI */ +# define TMS570_MIBSPI1_NCS 5 /* MibSPI1: 5 chip selects */ +# define TMS570_MIBSPI2_NCS 1 /* MibSPI2: 1 chip selects */ +# define TMS570_MIBSPI3_NCS 0 /* MibSPI3: No chip selects */ +# define TMS570_NSPI 1 /* One SPI */ +# define TMS570_SPI1_NCS 1 /* SPI1: One chip selects */ +# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */ +# define TMS570_NSCI 1 /* One SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 0 /* No I2C */ +# define TMS570_NGPIOINT 9 /* 9 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE) +# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */ +# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */ +# define TMS570_SRAM (128*1024) /* 128 KB SRAM */ +# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 3 /* Three CAN */ +# define TMS570_NMIBADC 2 /* Two MiBADC */ +# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */ +# define TMS570_NN2HET 2 /* Two N2HET */ +# define TMS570_N2HET_NCH 40 /* 40 N2HET channels */ +# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */ +# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */ +# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */ +# define TMS570_NMIBSPI 3 /* 3 MibSPI */ +# define TMS570_MIBSPI1_NCS 5 /* MibSPI1: 5 chip selects */ +# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */ +# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */ +# define TMS570_NSPI 1 /* One SPI */ +# define TMS570_SPI1_NCS 1 /* SPI1: One chip selects */ +# define TMS570_SPI2_NCS 0 /* SPI2: No chip selects */ +# define TMS570_NSCI 2 /* Two SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 1 /* One I2C */ +# define TMS570_NGPIOINT 10 /* 16 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT) +# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */ +# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (768*2014) /* 768 KB Program FLASH */ +# define TMS570_SRAM (128*1024) /* 128 KB SRAM */ +# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 0 /* No 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 0 /* No Flexray channels */ +# define TMS570_NCAN 3 /* Three CAN */ +# define TMS570_NMIBADC 2 /* Two MiBADC */ +# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */ +# define TMS570_NN2HET 2 /* Two N2HET */ +# define TMS570_N2HET_NCH 44 /* 44 N2HET channels */ +# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */ +# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */ +# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */ +# define TMS570_NMIBSPI 3 /* 3 MibSPI */ +# define TMS570_MIBSPI1_NCS 6 /* MibSPI1: 6 chip selects */ +# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */ +# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */ +# define TMS570_NSPI 2 /* Two SPI */ +# define TMS570_SPI1_NCS 2 /* SPI1: Two chip selects */ +# define TMS570_SPI2_NCS 1 /* SPI2: One chip selects */ +# define TMS570_NSCI 2 /* Two SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 1 /* One I2C */ +# define TMS570_NGPIOINT 16 /* 16 GPIO interrupts */ +# define TMS570_NEMIF16 0 /* No EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT) +# undef TMS570_CORTEX_R4 /* Not Cortex-R4 family */ +# define TMS570_CORTEX_R4F 1 /* Cortex-R4F family */ +# undef TMS570_CORTEX_R5 /* Not Cortex-R5 family */ +# undef TMS570_CORTEX_R5F /* Not Cortex-R5F family */ +# undef TMS570_CORTEX_R7 /* Not Cortex-R7 family */ +# undef TMS570_CORTEX_R7F /* Not Cortex-R7F family */ +# define TMS570_PFLASH (1280*2014) /* 1,280 KB Program FLASH */ +# define TMS570_SRAM (192*1024) /* 192 KB SRAM */ +# define TMS570_DFLASH (64*1024) /* 64 KB Data FLASH (EEPROM) */ +# define TMS570_NEMAC 1 /* One 10/100 Mbit EMAC */ +# define TMS570_FLEXRAY_NCH 2 /* Two Flexray channels */ +# define TMS570_NCAN 3 /* Three CAN */ +# define TMS570_NMIBADC 2 /* Two MiBADC */ +# define TMS570_MIBADC_NCH 24 /* 24 MibADC channels */ +# define TMS570_NN2HET 2 /* Two N2HET */ +# define TMS570_N2HET_NCH 44 /* 44 N2HET channels */ +# define TMS570_EPWM_NCH 14 /* 14 ePWM channels */ +# define TMS570_ECAP_NCH 6 /* 6 eCAP channels */ +# define TMS570_EQEP_NCH 2 /* 2 eQEP channels */ +# define TMS570_NMIBSPI 3 /* 3 MibSPI */ +# define TMS570_MIBSPI1_NCS 6 /* MibSPI1: 6 chip selects */ +# define TMS570_MIBSPI2_NCS 6 /* MibSPI2: 6 chip selects */ +# define TMS570_MIBSPI3_NCS 4 /* MibSPI3: 4 chip selects */ +# define TMS570_NSPI 2 /* Two SPI */ +# define TMS570_SPI1_NCS 2 /* SPI1: Two chip selects */ +# define TMS570_SPI2_NCS 1 /* SPI2: One chip selects */ +# define TMS570_NSCI 2 /* Two SCI */ +# define TMS570_SCI1_LIN 1 /* SCI1: LIN supported */ +# undef TMS570_SCI2_LIN /* SCI2: LIN not supported */ +# define TMS570_NI2C 1 /* One I2C */ +# define TMS570_NGPIOINT 16 /* 16 GPIO interrupts */ +# define TMS570_NEMIF16 1 /* One EMIF 16-bit data */ +# undef TMS570_ETM /* No ETM (trace) */ +# undef TMS570_RTP /* No RAM trace port (RTP) */ +# undef TMS570_DMM /* No DMM */ + +#else +# error Unrecognized TMS570 chip +#endif +#endif /* __ARCH_ARM_INCLUDE_TMS570_CHIP_H */ diff --git a/arch/arm/include/tms570/irq.h b/arch/arm/include/tms570/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f83fad69defb2b7b56acacfcf699c96102bd4966 --- /dev/null +++ b/arch/arm/include/tms570/irq.h @@ -0,0 +1,114 @@ +/**************************************************************************************** + * arch/arm/include/tms570/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_TMS570_IRQ_H +#define __ARCH_ARM_INCLUDE_TMS570_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* The interrupt vector table only has 96 entries, one phantom vector and 95 interrupt + * channels. Channel 95 does not have a dedicated vector and shall not be used. + */ + +#define TMS570_VECT_PHANTOM 0 /* The first is the "phantom" interrupt */ + +/* Default channel assignments are MCU-dependent */ + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ) +# error No IRQ definitions for the TMS570LS0232PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) +# include +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) +# include +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ) +# error No IRQ definitions for the TMS570LS0714PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE) +# error No IRQ definitions for the TMS570LS0714PGE +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT) +# error No IRQ definitions for the TMS570LS0714ZWT +#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT) +# error No IRQ definitions for the TMS570LS1227ZWT +#else +# error "Unrecognized Hercules chip" +#endif + +/* Total number of IRQ numbers. Includes all channels plus GIO second-level interrupts + * (if enabled). Excluds the phantom vector. Zero corresponds to channel 0, vector 1. + */ + +#define NR_IRQS (TMS570_IRQ_NCHANNELS + TMS570_NGIO_IRQS) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TMS570_IRQ_H */ + diff --git a/arch/arm/include/tms570/tms570ls04x03x_irq.h b/arch/arm/include/tms570/tms570ls04x03x_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..9a7543215cdb5d1abcb4088caf7d61c3f578173e --- /dev/null +++ b/arch/arm/include/tms570/tms570ls04x03x_irq.h @@ -0,0 +1,172 @@ +/**************************************************************************************** + * arch/arm/include/tms570/tms570ls04x03x_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through + * nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_TMS570_TMS570LS04X03X_IRQ_H +#define __ARCH_ARM_INCLUDE_TMS570_TMS570LS04X03X_IRQ_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* The interrupt vector table only has 96 entries, one phantom vector and 95 interrupt + * channels. Channel 95 does not have a dedicated vector and shall not be used. + */ + +#define TMS570_IRQ_NCHANNELS 95 /* The "phantom" vector is followed by 95 real + * interrupt channels */ + +/* Default request to channel assignments. Undefined requests are reserved */ + +#define TMS570_REQ_ESMHIGH 0 /* ESM High level interrupt (NMI) */ +#define TMS570_REQ_RTICMP0 2 /* RTI compare interrupt 0 */ +#define TMS570_REQ_RTICMP1 3 /* RTI compare interrupt 1 */ +#define TMS570_REQ_RTICMP2 4 /* RTI compare interrupt 2 */ +#define TMS570_REQ_RTICMP3 5 /* RTI compare interrupt 3 */ +#define TMS570_REQ_RTIOVF0 6 /* RTI overflow interrupt 0 */ +#define TMS570_REQ_RTIOVF1 7 /* RTI overflow interrupt 1 */ +#define TMS570_REQ_GIO_0 9 /* GIO level 0 interrupt */ +#define TMS570_REQ_N2HET_0 10 /* N2HET level 0 interrupt */ +#define TMS570_REQ_HTU_0 11 /* HTU level 0 interrupt */ +#define TMS570_REQ_MIBSPI1_0 12 /* MIBSPI1 level 0 interrupt */ +#define TMS570_REQ_SCI1_0 13 /* SCI1/LIN1 level 0 interrupt */ +#define TMS570_REQ_MIBADCEV 14 /* MIBADC event group interrupt */ +#define TMS570_REQ_MIBADSW1 15 /* MIBADC sw group 1 interrupt */ +#define TMS570_REQ_DCAN1_0 16 /* DCAN1 level 0 interrupt */ +#define TMS570_REQ_SPI2_0 17 /* SPI2 level 0 interrupt */ +#define TMS570_REQ_ESMLO 20 /* ESM Low level interrupt */ +#define TMS570_REQ_SYSTEM 21 /* Software interrupt (SSI) */ +#define TMS570_REQ_CPU 22 /* PMU interrupt */ +#define TMS570_REQ_GIO_1 23 /* GIO level 1 interrupt */ +#define TMS570_REQ_N2HET_1 24 /* N2HET level 1 interrupt */ +#define TMS570_REQ_HTU_1 25 /* HTU level 1 interrupt */ +#define TMS570_REQ_MIBSPI1_1 26 /* MIBSPI1 level 1 interrupt */ +#define TMS570_REQ_SCI1_1 27 /* SCI1/LIN1 level 1 interrupt */ +#define TMS570_REQ_MIBADCSW2 28 /* MIBADC sw group 2 interrupt */ +#define TMS570_REQ_DCAN1_1 29 /* DCAN1 level 1 interrupt */ +#define TMS570_REQ_SPI2_1 30 /* SPI2 level 1 interrupt */ +#define TMS570_REQ_MIBADCMC 31 /* MIBADC magnitude compare interrupt */ +#define TMS570_REQ_DCAN2_0 35 /* DCAN2 level 0 interrupt */ +#define TMS570_REQ_SPI3_0 37 /* SPI3 level 0 interrupt */ +#define TMS570_REQ_SPI3_1 38 /* SPI3 level 1 interrupt */ +#define TMS570_REQ_DCAN2_1 42 /* DCAN2 level 1 interrupt */ +#define TMS570_REQ_FMC 61 /* FSM_DONE interrupt */ +#define TMS570_REQ_HWAGH 80 /* WA_INT_REQ_H */ +#define TMS570_REQ_DCC 82 /* DCC done interrupt */ +#define TMS570_REQ_EQEP 84 /* eQEP Interrupt */ +#define TMS570_REQ_PBIST 85 /* PBIST Done Interrupt */ +#define TMS570_REQ_HWAGL 88 /* HWA_INT_REQ_L */ + +#ifdef CONFIG_TMS570_GIO_IRQ +# define TMS570_IRQ_GIOA0 (TMS570_IRQ_NCHANNELS+1) +# define TMS570_IRQ_GIOA1 (TMS570_IRQ_NCHANNELS+2) +# define TMS570_IRQ_GIOA2 (TMS570_IRQ_NCHANNELS+3) +# define TMS570_IRQ_GIOA3 (TMS570_IRQ_NCHANNELS+4) +# define TMS570_IRQ_GIOA4 (TMS570_IRQ_NCHANNELS+5) +# define TMS570_IRQ_GIOA5 (TMS570_IRQ_NCHANNELS+6) +# define TMS570_IRQ_GIOA6 (TMS570_IRQ_NCHANNELS+7) +# define TMS570_IRQ_GIOA7 (TMS570_IRQ_NCHANNELS+8) + +# define TMS570_IRQ_GIOB0 (TMS570_IRQ_NCHANNELS+9) +# define TMS570_IRQ_GIOB1 (TMS570_IRQ_NCHANNELS+10) +# define TMS570_IRQ_GIOB2 (TMS570_IRQ_NCHANNELS+11) +# define TMS570_IRQ_GIOB3 (TMS570_IRQ_NCHANNELS+12) +# define TMS570_IRQ_GIOB4 (TMS570_IRQ_NCHANNELS+13) +# define TMS570_IRQ_GIOB5 (TMS570_IRQ_NCHANNELS+14) +# define TMS570_IRQ_GIOB6 (TMS570_IRQ_NCHANNELS+15) +# define TMS570_IRQ_GIOB7 (TMS570_IRQ_NCHANNELS+16) + +# define TMS570_IRQ_GIOC0 (TMS570_IRQ_NCHANNELS+17) +# define TMS570_IRQ_GIOC1 (TMS570_IRQ_NCHANNELS+18) +# define TMS570_IRQ_GIOC2 (TMS570_IRQ_NCHANNELS+19) +# define TMS570_IRQ_GIOC3 (TMS570_IRQ_NCHANNELS+20) +# define TMS570_IRQ_GIOC4 (TMS570_IRQ_NCHANNELS+21) +# define TMS570_IRQ_GIOC5 (TMS570_IRQ_NCHANNELS+22) +# define TMS570_IRQ_GIOC6 (TMS570_IRQ_NCHANNELS+23) +# define TMS570_IRQ_GIOC7 (TMS570_IRQ_NCHANNELS+24) + +# define TMS570_IRQ_GIOD0 (TMS570_IRQ_NCHANNELS+25) +# define TMS570_IRQ_GIOD1 (TMS570_IRQ_NCHANNELS+26) +# define TMS570_IRQ_GIOD2 (TMS570_IRQ_NCHANNELS+27) +# define TMS570_IRQ_GIOD3 (TMS570_IRQ_NCHANNELS+28) +# define TMS570_IRQ_GIOD4 (TMS570_IRQ_NCHANNELS+29) +# define TMS570_IRQ_GIOD5 (TMS570_IRQ_NCHANNELS+30) +# define TMS570_IRQ_GIOD6 (TMS570_IRQ_NCHANNELS+31) +# define TMS570_IRQ_GIOD7 (TMS570_IRQ_NCHANNELS+32) + +# define TMS570_NGIO_IRQS 32 +#else +# define TMS570_NGIO_IRQS 0 +#endif + + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************** + * Public Function Prototypes + ****************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_TMS570_TMS570LS04X03X_IRQ_H */ + diff --git a/arch/arm/include/types.h b/arch/arm/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..ea0675d0e914367f583be176137ff319e74842b9 --- /dev/null +++ b/arch/arm/include/types.h @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/include/types.h + * + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_ARM_INCLUDE_TYPES_H +#define __ARCH_ARM_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). For + * ARM, a 32 register value is returned, for the thumb2, Cortex-M3, the 16-bit + * primask register value is returned, + */ + +#ifdef __thumb2__ +#if defined(CONFIG_ARMV7M_USEBASEPRI) || defined(CONFIG_ARCH_ARMV6M) +typedef unsigned char irqstate_t; +#else +typedef unsigned short irqstate_t; +#endif +#else /* __thumb2__ */ +typedef unsigned int irqstate_t; +#endif /* __thumb2__ */ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_TYPES_H */ diff --git a/arch/arm/include/watchdog.h b/arch/arm/include/watchdog.h new file mode 100644 index 0000000000000000000000000000000000000000..fdcd71807cfbf5a93669be9f3384bf6e34627fe0 --- /dev/null +++ b/arch/arm/include/watchdog.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/arm/include/watchdog.h + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_WATCHDOG_H +#define __ARCH_ARM_INCLUDE_WATCHDOG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_INCLUDE_WATCHDOG_H */ diff --git a/arch/arm/src/.gitignore b/arch/arm/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dfdfc935431ac8f4a525420ed96ee4f631196522 --- /dev/null +++ b/arch/arm/src/.gitignore @@ -0,0 +1,5 @@ +/.depend +/Make.dep +/locked.r +/board +/chip diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e74c0cfc28bd221748ddeda2f29653e5673df2fd --- /dev/null +++ b/arch/arm/src/Makefile @@ -0,0 +1,250 @@ +############################################################################ +# arch/arm/src/Makefile +# +# Copyright (C) 2007-2009, 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip$(DELIM)Make.defs + +ifeq ($(CONFIG_ARCH_CORTEXA5),y) # Cortex-A5 is ARMv7-A +ARCH_SUBDIR = armv7-a +else ifeq ($(CONFIG_ARCH_CORTEXA8),y) # Cortex-A8 is ARMv7-A +ARCH_SUBDIR = armv7-a +else ifeq ($(CONFIG_ARCH_CORTEXA9),y) # Cortex-A9 is ARMv7-A +ARCH_SUBDIR = armv7-a +else ifeq ($(CONFIG_ARCH_CORTEXR4),y) # Cortex-R4 is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXR4F),y) # Cortex-R4F is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXR5),y) # Cortex-R5 is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXR5F),y) # Cortex-R5F is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXR7),y) # Cortex-R7 is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXR7F),y) # Cortex-R7F is ARMv7-R +ARCH_SUBDIR = armv7-r +else ifeq ($(CONFIG_ARCH_CORTEXM3),y) # Cortex-M3 is ARMv7-M +ARCH_SUBDIR = armv7-m +else ifeq ($(CONFIG_ARCH_CORTEXM4),y) # Cortex-M4 is ARMv7E-M +ARCH_SUBDIR = armv7-m +else ifeq ($(CONFIG_ARCH_CORTEXM7),y) # Cortex-M4 is ARMv7E-M +ARCH_SUBDIR = armv7-m +else ifeq ($(CONFIG_ARCH_CORTEXM0),y) # Cortex-M0 is ARMv6-M +ARCH_SUBDIR = armv6-m +else # ARM9, ARM7TDMI +ARCH_SUBDIR = arm +endif + +CPPFLAGS += $(EXTRADEFINES) +CFLAGS += $(EXTRADEFINES) +CXXFLAGS += $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)" + CFLAGS += -I$(ARCH_SRCDIR)\chip + CFLAGS += -I$(ARCH_SRCDIR)\common + CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)\sched +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)" + CFLAGS += -I$(ARCH_SRCDIR)/chip + CFLAGS += -I$(ARCH_SRCDIR)/common + CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)/sched +endif +endif + +# The "head" object + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +# Flat build or kernel-mode objects + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# User-mode objects + +UASRCS = $(CHIP_UASRCS) $(CMN_UASRCS) +UAOBJS = $(UASRCS:.S=$(OBJEXT)) + +UCSRCS = $(CHIP_UCSRCS) $(CMN_UCSRCS) +UCOBJS = $(UCSRCS:.c=$(OBJEXT)) + +USRCS = $(UASRCS) $(UCSRCS) +UOBJS = $(UAOBJS) $(UCOBJS) + +KBIN = libkarch$(LIBEXT) +UBIN = libuarch$(LIBEXT) +BIN = libarch$(LIBEXT) + +LDFLAGS += $(ARCHSCRIPT) + +EXTRA_LIBS ?= +EXTRA_LIBPATHS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" +GCC_LIBDIR := ${shell dirname $(LIBGCC)} + +VPATH += chip +VPATH += common +VPATH += $(ARCH_SUBDIR) + +ifeq ($(CONFIG_ARM_TOOLCHAIN_IAR),y) + VPATH += chip$(DELIM)iar + VPATH += $(ARCH_SUBDIR)$(DELIM)iar +else # ifeq ($(CONFIG_ARM_TOOLCHAIN_GNU),y) + VPATH += chip$(DELIM)gnu + VPATH += $(ARCH_SUBDIR)$(DELIM)gnu +endif + +all: $(HEAD_OBJ) $(BIN) + +.PHONY: board$(DELIM)libboard$(LIBEXT) + +$(AOBJS) $(UAOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(UCOBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(BIN) $(KBIN): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +$(UBIN): $(UOBJS) + $(call ARCHIVE, $@, $(UOBJS)) + +board$(DELIM)libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) + $(Q) echo "LD: nuttx" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \ + -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)$(DELIM)System.map +endif + +# This is part of the top-level export target +# Note that there may not be a head object if layout is handled +# by the linker configuration. + +export_startup: board$(DELIM)libboard$(LIBEXT) $(STARTUP_OBJS) +ifneq ($(STARTUP_OBJS),) + $(Q) if [ -d "$(EXPORT_DIR)$(DELIM)startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)$(DELIM)startup$(DELIM)."; \ + else \ + echo "$(EXPORT_DIR)$(DELIM)startup does not exist"; \ + exit 1; \ + fi +endif + +# Dependencies + +.depend: Makefile chip$(DELIM)Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) $(patsubst %,--dep-path %,$(subst :, ,$(VPATH))) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, $(KBIN)) + $(call DELFILE, $(UBIN)) + $(call DELFILE, $(BIN)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/arm/src/a1x/Kconfig b/arch/arm/src/a1x/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..41414352212e507d3512df3f4a271452c997b5d7 --- /dev/null +++ b/arch/arm/src/a1x/Kconfig @@ -0,0 +1,391 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_A1X + +comment "A1x Configuration Options" + +choice + prompt "Allwinner A1X Chip Selection" + default ARCH_CHIP_A10 + +config ARCH_CHIP_A10 + bool "A10" + +endchoice + +menu "Allwinner A1X Peripheral Support" + +config A1X_UART0 + bool "UART 0" + default n + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART1 + bool "UART 1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART2 + bool "UART 2" + default n + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART3 + bool "UART 3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART4 + bool "UART 4" + default n + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART5 + bool "UART 5" + default n + select ARCH_HAVE_UART5 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART6 + bool "UART 6" + default n + select ARCH_HAVE_UART6 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_UART7 + bool "UART 7" + default n + select ARCH_HAVE_UART7 + select ARCH_HAVE_SERIAL_TERMIOS + +config A1X_IR0 + bool "IR 0" + default n + +config A1X_IR1 + bool "IR 1" + default n + +config A1X_TWI0 + bool "TWI 0" + default n + +config A1X_TWI1 + bool "TWI 1" + default n + +config A1X_TWI2 + bool "TWI 2" + default n + +config A1X_SPI0 + bool "SPI 0" + default n + +config A1X_SPI1 + bool "SPI 1" + default n + +config A1X_SPI2 + bool "SPI 2" + default n + +config A1X_SPI3 + bool "SPI3" + default n + +config A1X_NC + bool "NC" + default n + +config A1X_AC97 + bool "AC97" + default n + +config A1X_TS + bool "TS" + default n + +config A1X_IIS + bool "Digital Audio Controller" + default n + +config A1X_KEYPAD + bool "Keypad" + default n + +config A1X_TIMER1 + bool "Timer 1" + default n + +config A1X_TIMER2 + bool "Timer 2" + default n + +config A1X_TIMER3 + bool "Timer 3" + default n + +config A1X_TIMER4 + bool "Timer 4" + default n + +config A1X_TIMER5 + bool "Timer 5" + default n + +config A1X_IRQ_Alarm + bool "Alarm" + default n + +config A1X_IRQ_WD + bool "Watchdog" + default n + +config A1X_CAN + bool "CAN Bus controller" + default n + +config A1X_DMA + bool "DMA" + default n + +config A1X_PIO + bool "PIO" + default n + +config A1X_TOUCH + bool "Touch Panel" + default n + +config A1X_AUDIO + bool "Analog Audio Codec" + default n + +config A1X_LRADC + bool "LRADC" + default n + +config A1X_SDMMC0 + bool "SD/MMC Host Controller 0" + default n + +config A1X_SDMMC1 + bool "SD/MMC Host Controller 1" + default n + +config A1X_SDMMC2 + bool "SD/MMC Host Controller 2" + default n + +config A1X_SDMMC3 + bool "SD/MMC Host Controller 3" + default n + +config A1X_NAND + bool "NAND Flash Controller (NFC)" + default n + +config A1X_USB0 + bool "USB 0" + default n + +config A1X_USB1 + bool "USB 1" + default n + +config A1X_USB2 + bool "USB 2" + default n + +config A1X_USB3 + bool "USB 3" + default n + +config A1X_USB4 + bool "USB 4" + default n + +config A1X_SCR + bool "SCR" + default n + +config A1X_CSI0 + bool "CSI 0" + default n + +config A1X_CSI1 + bool "CSI 1" + default n + +config A1X_LCDC0 + bool "LCD Controller 0" + default n + +config A1X_LCDC1 + bool "LCD Controller 1" + default n + +config A1X_MP + bool "MP" + default n + +config A1X_DEFE0 + bool "DE-FE0" + default n + +config A1X_IRQ_DEBE0 + bool "DE-BE0" + default n + +config A1X_DEFE1 + bool "DE-FE1" + default n + +config A1X_IRQ_DEBE1 + bool "DE-BE1" + default n + +config A1X_PMU + bool "PMU" + default n + +config A1X_TZASC + bool "TZASC" + default n + +config A1X_PATA + bool "PATA" + default n + +config A1X_VE + bool "VE" + default n + +config A1X_SS + bool "Security System" + default n + +config A1X_EMAC + bool "EMAC" + default n + +config A1X_HDMI + bool "HDMI" + default n + +config A1X_TVE + bool "TV encoder 0/1" + default n + +config A1X_ACE + bool "ACE" + default n + +config A1X_TVD + bool "TV decoder" + default n + +config A1X_PS20 + bool "PS2-0" + default n + +config A1X_PS21 + bool "PS2-1" + default n + +config A1X_PLE + bool "PLE" + default n + +config A1X_IRQ_PERFMU + bool "Performance monitor" + default n + +config A1X_GPU + bool "GPU" + default n + +endmenu + +config A1X_PIO_IRQ + bool "External PIO interrupts" + default n + ---help--- + Select to enable support for 32 external PIO interrupts. These will + be handled through a second level of interrupt decoding and will + otherwise appear as any other interrupt. + +choice + prompt "Boot device" + default A1X_BOOT_SDCARD + +config A1X_BOOT_NAND + bool "NAND FLASH" + +config A1X_BOOT_SPINOR + bool "SPI NOR FLASH" + +config A1X_BOOT_SDCARD + bool "SD card" + +config A1X_BOOT_USB + bool "USB" + +endchoice # Boot device + +config A1X_DDR_MAPOFFSET + int "Installed SDRAM offset" + default 0 + ---help--- + The size of the installed SRAM memory is required in order to + properly configure memory mapping. The mapping will begin at the + start of SDRAM plus A1X_DDR_MAPOFFSET and extend for DDR_MAPSIZE + bytes. NOTE typically A1X_MAP_OFFSET is zero and A1X_DDR_MAPSIZE is + the full, installed size of the DRAM. But these values can be + modified to set aside memory at the beginning or end of SRAM that is + unmapped (or mapped differently). NOTE also that this value relates + closely to other settings: + + RAM_START and RAM_VSTART give this physical and virtual addresses + of the start of usable memory (begining with .text). NOTE that + this may not necessarily be the actual start of the mapped SDRAM + region. It will be larger if NuttX begins at an offset from + beginning of mapped SDRAM (which is the normal case). + + RAM_SIZE gives the size of the .text, .data, and .bss sections + plus the size of the available heap. NOTE that RAM_SIZE may not + include all of SDRAM up to the end of mapped region. + +config A1X_DDR_MAPSIZE + int "Installed SDRAM size" + default 1073741824 + ---help--- + The size of the installed SRAM memory is required in order to + properly configure memory mapping. The mapping will begin at the + start of SDRAM plus A1X_DDR_MAPOFFSET and extend for DDR_MAPSIZE + bytes. NOTE typically A1X_MAP_OFFSET is zero and A1X_DDR_MAPSIZE is + the full, installed size of the DRAM. But these values can be + modified to set aside memory at the beginning or end of SRAM that is + unmapped (or mapped differently). NOTE also that this value relates + closely to other settings: + + RAM_START and RAM_VSTART give this physical and virtual addresses + of the start of usable memory (begining with .text). NOTE that + this may not necessarily be the actual start of the mapped SDRAM + region. It will be larger if NuttX begins at an offset from + beginning of mapped SDRAM (which is the normal case). + + RAM_SIZE gives the size of the .text, .data, and .bss sections + plus the size of the available heap. NOTE that RAM_SIZE may not + include all of SDRAM up to the end of mapped region. + +endif # ARCH_CHIP_A1X diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..f823d5c4e6193f60741acdd0d698d83096dd93bb --- /dev/null +++ b/arch/arm/src/a1x/Make.defs @@ -0,0 +1,139 @@ +############################################################################ +# arch/arm/a1x/Make.defs +# +# Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The vector table is the "head" object, i.e., the one that must forced into +# the link in order to draw in all of the other components + +HEAD_ASRC = arm_vectortab.S + +ifeq ($(CONFIG_BUILD_KERNEL),y) +STARTUP_OBJS = crt0$(OBJEXT) +endif + +# Force the start-up logic to be at the beginning of the .text to simplify +# debug. + +ifeq ($(CONFIG_PAGING),y) +CMN_ASRCS = arm_pghead.S +else +CMN_ASRCS = arm_head.S +endif + +# Common assembly language files + +CMN_ASRCS += arm_vectors.S arm_fpuconfig.S arm_fullcontextrestore.S +CMN_ASRCS += arm_saveusercontext.S arm_vectoraddrexcptn.S arm_vfork.S +CMN_ASRCS += arm_testset.S +CMN_ASRCS += cp15_coherent_dcache.S cp15_invalidate_dcache.S +CMN_ASRCS += cp15_clean_dcache.S cp15_flush_dcache.S cp15_invalidate_dcache_all.S + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += arm_memcpy.S +endif + +# Common C source files + +CMN_CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_exit.c +CMN_CSRCS += up_createstack.c up_releasestack.c up_usestack.c up_vfork.c +CMN_CSRCS += up_puts.c up_mdelay.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c +CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_mmu.c arm_prefetchabort.c +CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c +CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c + +# Use common heap allocation for now (may need to be customized later) + +CMN_CSRCS += up_allocateheap.c + +# Configuration dependent C and assembly language files + +ifeq ($(CONFIG_PAGING),y) +CMN_CSRCS += arm_allocpage.c arm_checkmapping.c arm_pginitialize.c +CMN_CSRCS += arm_va2pte.c +endif + +ifeq ($(CONFIG_BUILD_KERNEL),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c arm_signal_dispatch.c +endif + +ifeq ($(CONFIG_ARCH_ADDRENV),y) +CMN_CSRCS += arm_addrenv.c arm_addrenv_utils.c arm_pgalloc.c +ifeq ($(CONFIG_ARCH_STACK_DYNAMIC),y) +CMN_CSRCS += arm_addrenv_ustack.c +endif +ifeq ($(CONFIG_ARCH_KERNEL_STACK),y) +CMN_CSRCS += arm_addrenv_kstack.c +endif +ifeq ($(CONFIG_MM_SHM),y) +CMN_CSRCS += arm_addrenv_shm.c +endif +endif + +ifeq ($(CONFIG_MM_PGALLOC),y) +CMN_CSRCS += arm_physpgaddr.c +ifeq ($(CONFIG_ARCH_PGPOOL_MAPPING),y) +CMN_CSRCS += arm_virtpgaddr.c +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_savefpu.S arm_restorefpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# A1x-specific assembly language files + +CHIP_ASRCS = + +# A1x-specific C source files + +CHIP_CSRCS = a1x_boot.c a1x_irq.c a1x_pio.c a1x_lowputc.c a1x_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += a1x_timerisr.c +endif diff --git a/arch/arm/src/a1x/a1x_boot.c b/arch/arm/src/a1x/a1x_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..c999ea6ef57e8620d122bc8a03b9e9f831747f5c --- /dev/null +++ b/arch/arm/src/a1x/a1x_boot.c @@ -0,0 +1,366 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_boot.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifdef CONFIG_PAGING +# include +#endif + +#include + +#include "chip.h" +#include "arm.h" +#include "mmu.h" +#include "fpu.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "a1x_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The vectors are, by default, positioned at the beginning of the text + * section. They will always have to be copied to the correct location. + * + * If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case, + * the vectors will lie at virtual address 0xffff:000 and we will need + * to a) copy the vectors to another location, and b) map the vectors + * to that address, and + * + * For the case of CONFIG_ARCH_LOWVECTORS=y, defined. Vectors will be + * copied to SRAM A1 at address 0x0000:0000 + */ + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE) +# error High vector remap cannot be performed if we are using a ROM page table +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical + * address space of the A1X. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static const struct section_mapping_s section_mapping[] = +{ + { A1X_INTMEM_PSECTION, A1X_INTMEM_VSECTION, /* Includes vectors and page table */ + A1X_INTMEM_MMUFLAGS, A1X_INTMEM_NSECTIONS + }, + { A1X_PERIPH_PSECTION, A1X_PERIPH_VSECTION, + A1X_PERIPH_MMUFLAGS, A1X_PERIPH_NSECTIONS + }, + { A1X_SRAMC_PSECTION, A1X_SRAMC_VSECTION, + A1X_SRAMC_MMUFLAGS, A1X_SRAMC_NSECTIONS + }, + { A1X_DE_PSECTION, A1X_DE_VSECTION, + A1X_DE_MMUFLAGS, A1X_DE_NSECTIONS + }, + { A1X_DDR_MAPPADDR, A1X_DDR_MAPVADDR, + A1X_DDR_MMUFLAGS, A1X_DDR_NSECTIONS + }, + { A1X_BROM_PSECTION, A1X_BROM_VSECTION, + A1X_BROM_MMUFLAGS, A1X_BROM_NSECTIONS + } +}; + +#define NMAPPINGS \ + (sizeof(section_mapping) / sizeof(struct section_mapping_s)) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: a1x_setupmappings + * + * Description + * Map all of the initial memory regions defined in section_mapping[] + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline void a1x_setupmappings(void) +{ + int i; + + /* Set up each group of section mappings */ + + for (i = 0; i < NMAPPINGS; i++) + { + mmu_l1_map_region(§ion_mapping[i]); + } +} +#endif + +/**************************************************************************** + * Name: a1x_vectorpermissions + * + * Description: + * Set permissions on the vector mapping. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \ + defined(CONFIG_PAGING) +static void a1x_vectorpermissions(uint32_t mmuflags) +{ + /* The PTE for the beginning of ISRAM is at the base of the L2 page table */ + + uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0); + + /* Mask out the old MMU flags from the page table entry. + * + * The pte might be zero the first time this function is called. + */ + + if (pte == 0) + { + pte = PG_VECT_PBASE; + } + else + { + pte &= PG_L1_PADDRMASK; + } + + /* Update the page table entry with the MMU flags and save */ + + mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags); +} +#endif + +/**************************************************************************** + * Name: a1x_vectormapping + * + * Description: + * Setup a special mapping for the interrupt vectors when (1) the + * interrupt vectors are not positioned in ROM, and when (2) the interrupt + * vectors are located at the high address, 0xffff0000. When the + * interrupt vectors are located in ROM, we just have to assume that they + * were set up correctly; When vectors are located in low memory, + * 0x00000000, the mapping for the ROM memory region will be suppressed. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS) +static void a1x_vectormapping(void) +{ + uint32_t vector_paddr = A1X_VECTOR_PADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_vaddr = A1X_VECTOR_VADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start; + uint32_t end_paddr = A1X_VECTOR_PADDR + vector_size; + + /* REVISIT: Cannot really assert in this context */ + + DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE); + + /* We want to keep our interrupt vectors and interrupt-related logic in + * zero-wait state internal SRAM (ISRAM). The A1X has 128Kb of ISRAM + * positioned at physical address 0x0300:0000; we need to map this to + * 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr, + MMU_L2_VECTORFLAGS); + vector_paddr += 4096; + vector_vaddr += 4096; + } + + /* Now set the level 1 descriptor to refer to the level 2 page table. */ + + mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, + A1X_VECTOR_VADDR & PMD_PTE_PADDR_MASK, + MMU_L1_VECTORFLAGS); +} +#else + /* No vector remap */ + +# define a1x_vectormapping() +#endif + +/**************************************************************************** + * Name: a1x_copyvectorblock + * + * Description: + * Copy the interrupt block to its final destination. Vectors are already + * positioned at the beginning of the text region and only need to be + * copied in the case where we are using high vectors. + * + ****************************************************************************/ + +static void a1x_copyvectorblock(void) +{ + uint32_t *src; + uint32_t *end; + uint32_t *dest; + + /* If we are using re-mapped vectors in an area that has been marked + * read only, then temparily mark the mapping write-able (non-buffered). + */ + +#ifdef CONFIG_PAGING + a1x_vectorpermissions(MMU_L2_VECTRWFLAGS); +#endif + + /* Copy the vectors into ISRAM at the address that will be mapped to the vector + * address: + * + * A1X_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * A1X_VECTOR_VSRAM - Virtual address of vector table in SRAM + * A1X_VECTOR_VADDR - Virtual address of vector table (0x00000000 or + * 0xffff0000) + */ + + src = (uint32_t *)&_vector_start; + end = (uint32_t *)&_vector_end; + dest = (uint32_t *)(A1X_VECTOR_VSRAM + VECTOR_TABLE_OFFSET); + + while (src < end) + { + *dest++ = *src++; + } + + /* Make the vectors read-only, cacheable again */ + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + a1x_vectorpermissions(MMU_L2_VECTORFLAGS); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * This logic will be executing in SDRAM. This boot logic was started by + * the A10 boot logic. At this point in time, clocking and SDRAM have + * already be initialized (they must be because we are executing out of + * SDRAM). So all that must be done here is to: + * + * 1) Refine the memory mapping, + * 2) Configure the serial console, and + * 3) Perform board-specific initializations. + * + ****************************************************************************/ + +void up_boot(void) +{ +#ifndef CONFIG_ARCH_ROMPGTABLE + /* __start provided the basic MMU mappings for SRAM. Now provide mappings + * for all IO regions (Including the vector region). + */ + + a1x_setupmappings(); + + /* Provide a special mapping for the IRAM interrupt vector positioned in + * high memory. + */ + + a1x_vectormapping(); + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* Setup up vector block. _vector_start and _vector_end are exported from + * arm_vector.S + */ + + a1x_copyvectorblock(); + +#ifdef CONFIG_ARCH_FPU + /* Initialize the FPU */ + + arm_fpuconfig(); +#endif + +#ifdef CONFIG_BOOT_SDRAM_DATA + /* This setting is inappropriate for the A1x because the code is *always* + * executing from SDRAM. If CONFIG_BOOT_SDRAM_DATA happens to be set, + * let's try to do the right thing and initialize the .data and .bss + * sections. + */ + + arm_data_initialize(); +#endif + + /* Perform common, low-level chip initialization (might do nothing) */ + + a1x_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization if we are going to use the serial + * driver. + */ + + up_earlyserialinit(); +#endif + + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (PIOs, LEDs, etc). + */ + + a1x_boardinitialize(); +} diff --git a/arch/arm/src/a1x/a1x_config.h b/arch/arm/src/a1x/a1x_config.h new file mode 100644 index 0000000000000000000000000000000000000000..120bc411b355b2444ae6157db220660de7188a9d --- /dev/null +++ b/arch/arm/src/a1x/a1x_config.h @@ -0,0 +1,175 @@ +/************************************************************************************ + * arch/arm/src/a1x/a1x_config.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_CONFIG_H +#define __ARCH_ARM_SRC_A1X_A1X_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_A1X_UART0) || defined(CONFIG_A1X_UART1) || \ + defined(CONFIG_A1X_UART2) || defined(CONFIG_A1X_UART3) || \ + defined(CONFIG_A1X_UART4) || defined(CONFIG_A1X_UART5) || \ + defined(CONFIG_A1X_UART6) || defined(CONFIG_A1X_UART7) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3,4,5 + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART4) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART5) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART6) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_A1X_UART7) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Check UART flow control (Not yet supported) */ + +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART2_FLOWCONTROL +# undef CONFIG_UART3_FLOWCONTROL +# undef CONFIG_UART4_FLOWCONTROL +# undef CONFIG_UART5_FLOWCONTROL +# undef CONFIG_UART6_FLOWCONTROL +# undef CONFIG_UART7_FLOWCONTROL + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_A1X_A1X_CONFIG_H */ diff --git a/arch/arm/src/a1x/a1x_irq.c b/arch/arm/src/a1x/a1x_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..65e18ffd73bb5b9e53291d548221da072f50368f --- /dev/null +++ b/arch/arm/src/a1x/a1x_irq.c @@ -0,0 +1,453 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_irq.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sctlr.h" + +#include "a1x_pio.h" +#include "a1x_irq.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: a1x_dumpintc + * + * Description: + * Dump some interesting INTC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void a1x_dumpintc(const char *msg, int irq) +{ + irqstate_t flags; + + /* Dump some relevant ARMv7 register contents */ + + flags = enter_critical_section(); + lldbg("ARMv7 (%s, irq=%d):\n", msg, irq); + lldbg(" CPSR: %08x SCTLR: %08x\n", flags, cp15_rdsctlr()); + + /* Dump all of the (readable) INTC register contents */ + + lldbg("INTC (%s, irq=%d):\n", msg, irq); + lldbg(" VECTOR: %08x BASE: %08x PROTECT: %08x NMICTRL: %08x\n", + getreg32(A1X_INTC_VECTOR), getreg32(A1X_INTC_BASEADDR), + getreg32(A1X_INTC_PROTECT), getreg32(A1X_INTC_NMICTRL)); + lldbg(" IRQ PEND: %08x %08x %08x\n", + getreg32(A1X_INTC_IRQ_PEND0), getreg32(A1X_INTC_IRQ_PEND1), + getreg32(A1X_INTC_IRQ_PEND2)); + lldbg(" FIQ PEND: %08x %08x %08x\n", + getreg32(A1X_INTC_FIQ_PEND0), getreg32(A1X_INTC_FIQ_PEND1), + getreg32(A1X_INTC_FIQ_PEND2)); + lldbg(" SEL: %08x %08x %08x\n", + getreg32(A1X_INTC_IRQ_SEL0), getreg32(A1X_INTC_IRQ_SEL1), + getreg32(A1X_INTC_IRQ_SEL2)); + lldbg(" EN: %08x %08x %08x\n", + getreg32(A1X_INTC_EN0), getreg32(A1X_INTC_EN1), + getreg32(A1X_INTC_EN2)); + lldbg(" MASK: %08x %08x %08x\n", + getreg32(A1X_INTC_MASK0), getreg32(A1X_INTC_MASK1), + getreg32(A1X_INTC_MASK2)); + lldbg(" RESP: %08x %08x %08x\n", + getreg32(A1X_INTC_RESP0), getreg32(A1X_INTC_RESP1), + getreg32(A1X_INTC_RESP2)); + lldbg(" FF: %08x %08x %08x\n", + getreg32(A1X_INTC_FF0), getreg32(A1X_INTC_FF1), + getreg32(A1X_INTC_FF2)); + lldbg(" PRIO: %08x %08x %08x %08x %08x\n", + getreg32(A1X_INTC_PRIO0), getreg32(A1X_INTC_PRIO1), + getreg32(A1X_INTC_PRIO2), getreg32(A1X_INTC_PRIO3), + getreg32(A1X_INTC_PRIO4)); + leave_critical_section(flags); +} +#else +# define a1x_dumpintc(msg, irq) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * This function is called by up_initialize() during the bring-up of the + * system. It is the responsibility of this function to but the interrupt + * subsystem into the working and ready state. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int i; + + /* The following operations need to be atomic, but since this function is + * called early in the initialization sequence, we expect to have exclusive + * access to the INTC. + */ + + /* Disable, mask, and clear all interrupts */ + + for (i = 0; i < A1X_IRQ_NINT; i += 32) + { + putreg32(0x00000000, A1X_INTC_EN(i)); /* 0 disables corresponding interrupt */ + putreg32(0xffffffff, A1X_INTC_MASK(i)); /* 1 masks corresponding interrupt */ + (void)getreg32(A1X_INTC_IRQ_PEND(i)); /* Reading status clears pending interrupts */ + } + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Set the interrupt base address to zero. We do not use the vectored + * interrupts. + */ + + putreg32(0, A1X_INTC_BASEADDR); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + +#ifndef CONFIG_SUPPRESS_INTERRUPTS +#ifdef CONFIG_A1X_PIO_IRQ + /* Initialize logic to support a second level of interrupt decoding for PIO pins. */ + + a1x_pio_irqinitialize(); +#endif + + /* And finally, enable interrupts */ + + (void)up_irq_enable(); +#endif + + a1x_dumpintc("initial", 0); +} + +/**************************************************************************** + * Name: arm_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *arm_decodeirq(uint32_t *regs) +{ + /* REVISIT: I think that if you want to have prioritized interrupts, you + * would have to get the highest priority pending interrupt from the VECTOR + * register. But, in that case, you would also need to clear the pending + * interrupt by reading the PEND register. However, won't that clear up + * to 32 pending interrupts? + */ + +#if 0 /* Use PEND registers instead */ + uint32_t regval; + + /* During initialization, the BASE address register was set to zero. + * Therefore, when we read the VECTOR address register, we get the IRQ number + * shifted left by two. + */ + + regval = getreg32(A1X_INTC_VECTOR); + + /* Dispatch the interrupt */ + + return arm_doirq((int)(regval >> 2), regs); +#else + uintptr_t regaddr; + uint32_t pending; + int startirq; + int lastirq; + int irq; + + /* Check each PEND register for pending interrupts. Since the unused + * interrupts are disabled, we do not have to be concerned about which + * are MASKed. + */ + + for (startirq = 0, regaddr = A1X_INTC_IRQ_PEND0; + startirq < A1X_IRQ_NINT; + startirq += 32, regaddr += 4) + { + /* Check this register for pending interrupts */ + + pending = getreg32(regaddr); + if (pending != 0) + { + /* The last interrupt in this register */ + + lastirq = startirq + 32; + if (lastirq > A1X_IRQ_NINT) + { + lastirq = A1X_IRQ_NINT; + } + + for (irq = startirq; irq < lastirq && pending != 0; ) + { + /* Check for pending interrupts in any of the lower 16-bits */ + + if ((pending & 0x0000ffff) == 0) + { + irq += 16; + pending >>= 16; + } + + /* Check for pending interrupts in any of the lower 16-bits */ + + else if ((pending & 0x000000ff) == 0) + { + irq += 8; + pending >>= 8; + } + + /* Check for pending interrupts in any of the lower 4-bits */ + + else if ((pending & 0x0000000f) == 0) + { + irq += 4; + pending >>= 4; + } + + /* Check for pending interrupts in any of the lower 2-bits */ + + else if ((pending & 0x00000003) == 0) + { + irq += 2; + pending >>= 2; + } + + /* Check for pending interrupts in any of the last bits */ + + else + { + if ((pending & 0x00000001) != 0) + { + /* Yes.. dispatch the interrupt */ + + regs = arm_doirq(irq, regs); + } + + irq++; + pending >>= 1; + } + } + } + } + + return regs; +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + + if (irq < A1X_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Make sure that the interrupt is disabled. */ + + regaddr = A1X_INTC_EN(irq); + regval = getreg32(regaddr); + regval &= ~INTC_EN(irq); + putreg32(regval, regaddr); + + /* Mask the interrupt by setting the bit in the mask register */ + + regaddr = A1X_INTC_MASK(irq); + regval = getreg32(regaddr); + regval |= INTC_MASK(irq); + putreg32(regval, regaddr); + + a1x_dumpintc("disable", irq); + leave_critical_section(flags); + } + +#ifdef CONFIG_A1X_PIO_IRQ + /* Perhaps this is a second level PIO interrupt */ + + else + { + a1x_pio_irqdisable(irq); + } +#endif +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + + if (irq < A1X_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Make sure that the interrupt is enabled. */ + + regaddr = A1X_INTC_EN(irq); + regval = getreg32(regaddr); + regval |= INTC_EN(irq); + putreg32(regval, regaddr); + + /* Un-mask the interrupt by clearing the bit in the mask register */ + + regaddr = A1X_INTC_MASK(irq); + regval = getreg32(regaddr); + regval &= ~INTC_MASK(irq); + putreg32(regval, regaddr); + + a1x_dumpintc("enable", irq); + leave_critical_section(flags); + } + +#ifdef CONFIG_A1X_PIO_IRQ + /* Perhaps this is a second level PIO interrupt */ + + else + { + a1x_pio_irqenable(irq); + } +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + + DEBUGASSERT(irq < A1X_IRQ_NINT && (unsigned)priority <= INTC_PRIO_MAX); + if (irq < A1X_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Set the new priority */ + + regaddr = A1X_INTC_PRIO_OFFSET(irq); + regval = getreg32(regaddr); + regval &= ~INTC_PRIO_MASK(irq); + regval |= INTC_PRIO(irq, priority); + putreg32(regval, regaddr); + + a1x_dumpintc("prioritize", irq); + leave_critical_section(flags); + return OK; + } + + return -EINVAL; +} +#endif diff --git a/arch/arm/src/a1x/a1x_irq.h b/arch/arm/src/a1x/a1x_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ad0925707c56ddb04e71132d759f0d8567032e86 --- /dev/null +++ b/arch/arm/src/a1x/a1x_irq.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_IRQ_H +#define __ARCH_ARM_SRC_A1X_A1X_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/a1x_intc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCRTYPE_NTYPES 6 +#define A1X_DEFAULT_PRIOR ((INTC_PRIO_MAX-INTC_PRIO_MIN+1) >> 1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_A1X_A1X_IRQ_H */ diff --git a/arch/arm/src/a1x/a1x_lowputc.c b/arch/arm/src/a1x/a1x_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..0018c8888197ae7d2901031137662983e7ce71d8 --- /dev/null +++ b/arch/arm/src/a1x/a1x_lowputc.c @@ -0,0 +1,292 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_lowputc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "a1x_config.h" +#include "chip/a1x_uart.h" +#include "a1x_pio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART0_VADDR +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART1_VADDR +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART2_VADDR +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +# define CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART3_VADDR +# define CONSOLE_BAUD CONFIG_UART3_BAUD +# define CONSOLE_BITS CONFIG_UART3_BITS +# define CONSOLE_PARITY CONFIG_UART3_PARITY +# define CONSOLE_2STOP CONFIG_UART3_2STOP +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART4_VADDR +# define CONSOLE_BAUD CONFIG_UART4_BAUD +# define CONSOLE_BITS CONFIG_UART4_BITS +# define CONSOLE_PARITY CONFIG_UART4_PARITY +# define CONSOLE_2STOP CONFIG_UART4_2STOP +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART5_VADDR +# define CONSOLE_BAUD CONFIG_UART5_BAUD +# define CONSOLE_BITS CONFIG_UART5_BITS +# define CONSOLE_PARITY CONFIG_UART5_PARITY +# define CONSOLE_2STOP CONFIG_UART5_2STOP +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART6_VADDR +# define CONSOLE_BAUD CONFIG_UART6_BAUD +# define CONSOLE_BITS CONFIG_UART6_BITS +# define CONSOLE_PARITY CONFIG_UART6_PARITY +# define CONSOLE_2STOP CONFIG_UART6_2STOP +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define CONSOLE_BASE A1X_UART7_VADDR +# define CONSOLE_BAUD CONFIG_UART7_BAUD +# define CONSOLE_BITS CONFIG_UART7_BITS +# define CONSOLE_PARITY CONFIG_UART7_PARITY +# define CONSOLE_2STOP CONFIG_UART7_2STOP +#elif defined(HAVE_SERIAL_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS == 5 +# define CONSOLE_LCR_DLS UART_LCR_DLS_5BITS +#elif CONSOLE_BITS == 6 +# define CONSOLE_LCR_DLS UART_LCR_DLS_6BITS +#elif CONSOLE_BITS == 7 +# define CONSOLE_LCR_DLS UART_LCR_DLS_7BITS +#elif CONSOLE_BITS == 8 +# define CONSOLE_LCR_DLS UART_LCR_DLS_8BITS +#elif defined(HAVE_SERIAL_CONSOLE) +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR UART_LCR_PEN +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PEN | UART_LCR_EPS) +#elif CONSOLE_PARITY == 3 +#elif defined(HAVE_SERIAL_CONSOLE) +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and UART0-3 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP UART_LCR_STOP +#else +# define CONSOLE_LCR_STOP 0 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_DLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) +#define CONSOLE_FCR_VALUE (UART_FCR_RT_HALF | UART_FCR_XFIFOR |\ + UART_FCR_RFIFOR | UART_FCR_FIFOE) + +/* SCLK is the UART input clock. + * + * Through experimentation, it has been found that the serial clock is + * OSC24M + */ + +#define A1X_SCLK 24000000 + +/* The output baud rate is equal to the serial clock (SCLK) frequency divided + * by sixteen times the value of the baud rate divisor, as follows: + * + * baud rate = Fsclk / (16 * divisor). + */ + +#define CONSOLE_DL (A1X_SCLK / (CONSOLE_BAUD << 4)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART_DEVICE && defined HAVE_SERIAL_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(CONSOLE_BASE+A1X_UART_LSR_OFFSET) & UART_LSR_THRE) == 0); + + /* Send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE+A1X_UART_THR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: a1x_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void a1x_lowsetup(void) +{ +#ifdef HAVE_UART_DEVICE + /* Enable power and clocking to the UART peripheral */ +#warning Missing logic + + /* Configure UART pins for the selected CONSOLE. If there are multiple + * pin options for a given UART, the the applicable option must be + * disambiguated in the board.h header file. + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART0_TX); + a1x_pio_config(PIO_UART0_RX); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART1_TX); + a1x_pio_config(PIO_UART1_RX); +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART2_TX); + a1x_pio_config(PIO_UART2_RX); +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART3_TX); + a1x_pio_config(PIO_UART3_RX); +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART4_TX); + a1x_pio_config(PIO_UART4_RX); +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART5_TX); + a1x_pio_config(PIO_UART5_RX); +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART6_TX); + a1x_pio_config(PIO_UART6_RX); +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) + a1x_pio_config(PIO_UART7_TX); + a1x_pio_config(PIO_UART7_RX); +#endif + + /* Configure the console (only) */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* Clear fifos */ + + putreg32(UART_FCR_RFIFOR | UART_FCR_XFIFOR, CONSOLE_BASE + A1X_UART_FCR_OFFSET); + + /* Set trigger */ + + putreg32(UART_FCR_FIFOE | UART_FCR_RT_HALF, CONSOLE_BASE + A1X_UART_FCR_OFFSET); + + /* Set up the LCR and set DLAB=1 */ + + putreg32(CONSOLE_LCR_VALUE | UART_LCR_DLAB, CONSOLE_BASE + A1X_UART_LCR_OFFSET); + + /* Set the BAUD divisor */ + + putreg32(CONSOLE_DL >> 8, CONSOLE_BASE+A1X_UART_DLH_OFFSET); + putreg32(CONSOLE_DL & 0xff, CONSOLE_BASE+A1X_UART_DLL_OFFSET); + + /* Clear DLAB */ + + putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE+A1X_UART_LCR_OFFSET); + + /* Configure the FIFOs */ + + putreg32(UART_FCR_RT_HALF | UART_FCR_XFIFOR | UART_FCR_RFIFOR | UART_FCR_FIFOE, + CONSOLE_BASE + A1X_UART_FCR_OFFSET); +#endif +#endif /* HAVE_UART_DEVICE */ +} diff --git a/arch/arm/src/a1x/a1x_lowputc.h b/arch/arm/src/a1x/a1x_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..720785d58158623be1db966323cdd1e592fdb896 --- /dev/null +++ b/arch/arm/src/a1x/a1x_lowputc.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_LOWPUTC_H +#define __ARCH_ARM_SRC_A1X_A1X_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: a1x_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void a1x_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_A1X_A1X_LOWPUTC_H */ diff --git a/arch/arm/src/a1x/a1x_pio.c b/arch/arm/src/a1x/a1x_pio.c new file mode 100644 index 0000000000000000000000000000000000000000..8016b0075942640e3725ec912e615852bf13eea6 --- /dev/null +++ b/arch/arm/src/a1x/a1x_pio.c @@ -0,0 +1,465 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_pio.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "a1x_pio.h" +#include "chip/a1x_pio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: a1x_pio_pin + * + * Description: + * Return the port number + * + ****************************************************************************/ + +static inline int a1x_pio_port(pio_pinset_t cfgset) +{ + return ((cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: a1x_pio_pin + * + * Description: + * Return the pin bit position + * + ****************************************************************************/ + +static inline int a1x_pio_pin(pio_pinset_t cfgset) +{ + return 1 << ((cfgset & PIO_PIN_MASK) >> PIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: a1x_pio_interrupt + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * PIO pins. + * + ****************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +static int a1x_pio_interrupt(int irq, void *context) +{ + uint32_t status; + uint32_t mask; + uint32_t pending; + int irq; + + /* Read the set of pending GPIO interrupts */ + + status = getreg32(A1X_PIO_INT_STA); + mask = getreg32(A1X_PIO_INT_CTL); + pending = status & mask; + + /* Re-dispatch all pending GPIO interrupts */ + + for (irq = A1X_PIO_EINT0; pending != 0 && irq <= A1X_PIO_EINT31; irq++) + { + /* Check for pending interrupts in any of the lower 16-bits */ + + if ((pending & 0x0000ffff) == 0) + { + irq += 16; + pending >>= 16; + } + + /* Check for pending interrupts in any of the lower 16-bits */ + + else if ((pending & 0x000000ff) == 0) + { + irq += 8; + pending >>= 8; + } + + /* Check for pending interrupts in any of the lower 4-bits */ + + else if ((pending & 0x0000000f) == 0) + { + irq += 4; + pending >>= 4; + } + + /* Check for pending interrupts in any of the lower 2-bits */ + + else if ((pending & 0x00000003) == 0) + { + irq += 2; + pending >>= 2; + } + + /* Check for pending interrupts in any of the last bits */ + + else + { + if ((pending & 0x00000001) == 0) + { + /* Yes.. dispatch the interrupt */ + + (void)arm_doirq(irq, regs); + } + + irq++; + pending >>= 1; + } + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: a1x_pio_irqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * PIO pins. + * + ****************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqinitialize(void) +{ + int ret; + + /* Disable all external PIO interrupts */ + + putreg32(0, A1X_PIO_INT_CTL); + + /* Attach the PIO interrupt handler */ + + ret = irq_attach(A1X_IRQ_PIO) + if (ret < 0) + { + return ret; + } + + /* And enable the PIO interrupt */ + + up_enable_irq(A1X_IRQ_PIO); +} +#endif + +/**************************************************************************** + * Name: a1x_pio_config + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int a1x_pio_config(pio_pinset_t cfgset) +{ + unsigned int port = a1x_pio_port(cfgset); + unsigned int pin = a1x_pio_pin(cfgset); + unsigned int shift; + unsigned int value; + uintptr_t cfgaddr; + uintptr_t puaddr; + uintptr_t drvaddr; + uintptr_t intaddr; + uintptr_t dataddr; + uint32_t regval; + irqstate_t flags; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Set the peripheral ID (0=input, 1=output) and interrupt mode */ + + switch (pin >> 3) + { + case 0: /* PIO 0-7 */ + cfgaddr = A1X_PIO_CFG0(port); + intaddr = A1X_PIO_INT_CFG0; + break; + + case 1: /* PIO 8-15 */ + cfgaddr = A1X_PIO_CFG1(port); + intaddr = A1X_PIO_INT_CFG1; + break; + + case 2: /* PIO 16-23 */ + cfgaddr = A1X_PIO_CFG2(port); + intaddr = A1X_PIO_INT_CFG2; + break; + + case 3: /* PIO 24-31 */ + cfgaddr = A1X_PIO_CFG3(port); + intaddr = A1X_PIO_INT_CFG3; + break; + + default: + return -EINVAL; + } + + value = (cfgset & PIO_MODE_MASK) >> PIO_MODE_SHIFT; + shift = (port & 7) << 4; + + regval = getreg32(cfgaddr); + regval &= ~(7 << shift); + regval |= (value << shift); + putreg32(regval, cfgaddr); + + /* Do not modify the INT MASK unless this pin is configured + * as an external PIO interrupt. + */ + + if ((cfgset & PIO_EINT_MASK) == PIO_EINT) + { + value = (cfgset & PIO_INT_MASK) >> PIO_INT_SHIFT; + + regval = getreg32(intaddr); + regval &= ~(7 << shift); + regval |= (value << shift); + putreg32(regval, intaddr); + } + + /* Set the pull-up/down and drive strength */ + + switch (pin >> 4) + { + case 0: /* PIO 0-15 */ + puaddr = A1X_PIO_PUL0(port); + drvaddr = A1X_PIO_DRV0(port); + break; + + case 1: /* PIO 16-31 */ + puaddr = A1X_PIO_PUL1(port); + drvaddr = A1X_PIO_DRV1(port); + break; + + default: + return -EINVAL; + } + + value = (cfgset & PIO_PULL_MASK) >> PIO_PULL_SHIFT; + shift = (port & 15) << 2; + + regval = getreg32(puaddr); + regval &= ~(3 << shift); + regval |= (value << shift); + putreg32(regval, puaddr); + + value = (cfgset & PIO_DRIVE_MASK) >> PIO_DRIVE_SHIFT; + + regval = getreg32(drvaddr); + regval &= ~(3 << shift); + regval |= (value << shift); + putreg32(regval, drvaddr); + + /* Set the output value (will have no effect on inputs) */ + + dataddr = A1X_PIO_DAT(port); + regval = getreg32(dataddr); + + if ((cfgset & PIO_OUTPUT_SET) != 0) + { + regval |= PIO_DAT(pin); + } + else + { + regval &= ~PIO_DAT(pin); + } + + putreg32(regval, dataddr); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: a1x_piowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ****************************************************************************/ + +void a1x_pio_write(pio_pinset_t pinset, bool value) +{ + unsigned int port = a1x_pio_port(pinset); + unsigned int pin = a1x_pio_pin(pinset); + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Set the output value (will have no effect on inputs */ + + regaddr = A1X_PIO_DAT(port); + regval = getreg32(regaddr); + + if (value) + { + regval |= PIO_DAT(pin); + } + else + { + regval &= ~PIO_DAT(pin); + } + + putreg32(regval, regaddr); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: a1x_pio_read + * + * Description: + * Read one or zero from the selected PIO pin + * + ****************************************************************************/ + +bool a1x_pio_read(pio_pinset_t pinset) +{ + unsigned int port = a1x_pio_port(pinset); + unsigned int pin = a1x_pio_pin(pinset); + uintptr_t regaddr; + uint32_t regval; + + /* Get the input value */ + + regaddr = A1X_PIO_DAT(port); + regval = getreg32(regaddr); + return ((regval & PIO_DAT(pin)) != 0); +} + +/************************************************************************************ + * Name: a1x_pio_irqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqenable(int irq) +{ + irqstate_t flags; + uint32_t regval; + int pin; + + if (irq >= A1X_PIO_EINT0 && irq <= A1X_PIO_EINT31) + { + /* Convert the IRQ number to a bit position */ + + pin = irq - A1X_PIO_EINT0 + + /* Un-mask the interrupt be setting the corresponding bit in the PIO INT CTL + * register. + */ + + flags = enter_critical_section(); + regval = getreg32(A1X_PIO_INT_CTL); + regval |= PIO_INT_CTL(irq); + leave_critical_section(flags); + } +} +#endif + +/************************************************************************************ + * Name: a1x_pio_irqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ +#ifdef CONFIG_A1X_PIO_IRQ + +void a1x_pio_irqdisable(int irq) +{ + irqstate_t flags; + uint32_t regval; + int pin; + + if (irq >= A1X_PIO_EINT0 && irq <= A1X_PIO_EINT31) + { + /* Convert the IRQ number to a bit position */ + + pin = irq - A1X_PIO_EINT0 + + /* Mask the interrupt be clearning the corresponding bit in the PIO INT CTL + * register. + */ + + flags = enter_critical_section(); + regval = getreg32(A1X_PIO_INT_CTL); + regval &= ~PIO_INT_CTL(irq); + leave_critical_section(flags); + } +} +#endif diff --git a/arch/arm/src/a1x/a1x_pio.h b/arch/arm/src/a1x/a1x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..de69d4c3e1b2cff9c250603e87774c5925e96b94 --- /dev/null +++ b/arch/arm/src/a1x/a1x_pio.h @@ -0,0 +1,324 @@ +/************************************************************************************ + * arch/arm/src/a1x/a1x_pio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_PIO_H +#define __ARCH_ARM_SRC_A1X_A1X_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip/a1x_pio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Bit-encoded input to a1x_pio_config() ********************************************/ + +/* 32-bit Encoding: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... MMMM PPDD IIIV ...P PPPB BBBB + */ + +/* Input/Output mode: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... MMMX .... .... .... .... .... + */ + +#define PIO_MODE_SHIFT (21) /* Bits 21-23: PIO mode */ +#define PIO_MODE_MASK (7 << PIO_MODE_SHIFT) +# define PIO_PERIPH0 (PIO_REG_CFG_INPUT << PIO_MODE_SHIFT) +# define PIO_PERIPH1 (PIO_REG_CFG_OUTPUT << PIO_MODE_SHIFT) +# define PIO_PERIPH2 (2 << PIO_MODE_SHIFT) +# define PIO_PERIPH3 (3 << PIO_MODE_SHIFT) +# define PIO_PERIPH4 (4 << PIO_MODE_SHIFT) +# define PIO_PERIPH5 (5 << PIO_MODE_SHIFT) +# define PIO_PERIPH6 (6 << PIO_MODE_SHIFT) +# define PIO_PERIPH7 (7 << PIO_MODE_SHIFT) + +# define PIO_INPUT PIO_PERIPH0 /* Input */ +# define PIO_OUTPUT PIO_PERIPH1 /* Output */ + +/* Bit 20 also specifies an external interrupt which must go with ID=6 */ + +#define PIO_EINT_BIT (1 << 20) /* Bit 20: External PIO interrupt */ +#define PIO_EINT_SHIFT (20) /* Bits 20-23: Extended PIO mode */ +#define PIO_EINT_MASK (15 << PIO_EINT_SHIFT) +# define PIO_EINT (PIO_EINT_BIT | PIO_PERIPH6) + +/* These bits set the pull-up/down configuration of the pin: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... PP.. .... .... .... .... + */ + +#define PIO_PULL_SHIFT (18) /* Bits 18-19: PIO configuration bits */ +#define PIO_PULL_MASK (3 << PIO_PULL_SHIFT) +# define PIO_PULL_NONE (PIO_REG_PULL_NONE << PIO_PULL_SHIFT) +# define PIO_PULL_PULLUP (PIO_REG_PULL_UP << PIO_PULL_SHIFT) +# define PIO_PULL_PULLDOWN (PIO_REG_PULL_DOWN << PIO_PULL_SHIFT) + +/* Drive (outputs only): + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... ..DD .... .... .... .... + */ + +#define PIO_DRIVE_SHIFT (16) /* Bits 16-17: Drive strength */ +#define PIO_DRIVE_MASK (3 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_NONE (0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_LOW (PIO_REG_DRV_LEVEL0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDLOW (PIO_REG_DRV_LEVEL1 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDHIGH (PIO_REG_DRV_LEVEL2 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_HIGH (PIO_REG_DRV_LEVEL3 << PIO_DRIVE_SHIFT) + +/* Interrupt modes (inputs only): + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... ... .... III. .... .... .... + */ + +#define PIO_INT_SHIFT (13) /* Bits 13-15: PIO interrupt bits */ +#define PIO_INT_MASK (7 << PIO_INT_SHIFT) +# define PIO_INT_NONE (0 << PIO_INT_SHIFT) +# define PIO_INT_RISING (PIO_REG_INT_POSEDGE << PIO_INT_SHIFT) +# define PIO_INT_FALLING (PIO_REG_INT_NEGEDGE << PIO_INT_SHIFT) +# define PIO_INT_HIGHLEVEL (PIO_REG_INT_HILEVEL << PIO_INT_SHIFT) +# define PIO_INT_LOWLEVEL (PIO_REG_INT_LOWLEVEL << PIO_INT_SHIFT) +# define PIO_INT_BOTHEDGES (PIO_REG_INT_BOTHEDGES << PIO_INT_SHIFT) + +/* If the pin is an PIO output, then this identifies the initial output value: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... ...V .... .... .... + * V + */ + +#define PIO_OUTPUT_SET (1 << 12) /* Bit 12: Initial value of output */ +#define PIO_OUTPUT_CLEAR (0) + +/* This identifies the PIO port: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... .... ...P PPP. .... + * PPPP + */ + +#define PIO_PORT_SHIFT (5) /* Bit 5-8: Port number */ +#define PIO_PORT_MASK (15 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOA (PIO_REG_PORTA << PIO_PORT_SHIFT) +# define PIO_PORT_PIOB (PIO_REG_PORTB << PIO_PORT_SHIFT) +# define PIO_PORT_PIOC (PIO_REG_PORTC << PIO_PORT_SHIFT) +# define PIO_PORT_PIOD (PIO_REG_PORTD << PIO_PORT_SHIFT) +# define PIO_PORT_PIOE (PIO_REG_PORTE << PIO_PORT_SHIFT) +# define PIO_PORT_PIOF (PIO_REG_PORTF << PIO_PORT_SHIFT) +# define PIO_PORT_PIOG (PIO_REG_PORTG << PIO_PORT_SHIFT) +# define PIO_PORT_PIOH (PIO_REG_PORTH << PIO_PORT_SHIFT) +# define PIO_PORT_PIOI (PIO_REG_PORTI << PIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... .... .... ...B BBBB + */ + +#define PIO_PIN_SHIFT (0) /* Bits 0-4: PIO number: 0-31 */ +#define PIO_PIN_MASK (31 << PIO_PIN_SHIFT) +#define PIO_PIN0 (0 << PIO_PIN_SHIFT) +#define PIO_PIN1 (1 << PIO_PIN_SHIFT) +#define PIO_PIN2 (2 << PIO_PIN_SHIFT) +#define PIO_PIN3 (3 << PIO_PIN_SHIFT) +#define PIO_PIN4 (4 << PIO_PIN_SHIFT) +#define PIO_PIN5 (5 << PIO_PIN_SHIFT) +#define PIO_PIN6 (6 << PIO_PIN_SHIFT) +#define PIO_PIN7 (7 << PIO_PIN_SHIFT) +#define PIO_PIN8 (8 << PIO_PIN_SHIFT) +#define PIO_PIN9 (9 << PIO_PIN_SHIFT) +#define PIO_PIN10 (10 << PIO_PIN_SHIFT) +#define PIO_PIN11 (11 << PIO_PIN_SHIFT) +#define PIO_PIN12 (12 << PIO_PIN_SHIFT) +#define PIO_PIN13 (13 << PIO_PIN_SHIFT) +#define PIO_PIN14 (14 << PIO_PIN_SHIFT) +#define PIO_PIN15 (15 << PIO_PIN_SHIFT) +#define PIO_PIN16 (16 << PIO_PIN_SHIFT) +#define PIO_PIN17 (17 << PIO_PIN_SHIFT) +#define PIO_PIN18 (18 << PIO_PIN_SHIFT) +#define PIO_PIN19 (19 << PIO_PIN_SHIFT) +#define PIO_PIN20 (20 << PIO_PIN_SHIFT) +#define PIO_PIN21 (21 << PIO_PIN_SHIFT) +#define PIO_PIN22 (22 << PIO_PIN_SHIFT) +#define PIO_PIN23 (23 << PIO_PIN_SHIFT) +#define PIO_PIN24 (24 << PIO_PIN_SHIFT) +#define PIO_PIN25 (25 << PIO_PIN_SHIFT) +#define PIO_PIN26 (26 << PIO_PIN_SHIFT) +#define PIO_PIN27 (27 << PIO_PIN_SHIFT) +#define PIO_PIN28 (28 << PIO_PIN_SHIFT) +#define PIO_PIN29 (29 << PIO_PIN_SHIFT) +#define PIO_PIN30 (30 << PIO_PIN_SHIFT) +#define PIO_PIN31 (31 << PIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t pio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: a1x_pio_irqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for PIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqinitialize(void); +#else +# define a1x_pio_irqinitialize() +#endif + +/************************************************************************************ + * Name: a1x_pio_config + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int a1x_pio_config(pio_pinset_t cfgset); + +/************************************************************************************ + * Name: a1x_pio_write + * + * Description: + * Write one or zero to the selected PIO pin + * + ************************************************************************************/ + +void a1x_pio_write(pio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: a1x_pio_read + * + * Description: + * Read one or zero from the selected PIO pin + * + ************************************************************************************/ + +bool a1x_pio_read(pio_pinset_t pinset); + +/************************************************************************************ + * Name: a1x_pio_irqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqenable(int irq); +#else +# define a1x_pio_irqenable(irq) +#endif + +/************************************************************************************ + * Name: a1x_pio_irqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqdisable(int irq); +#else +# define a1x_pio_irqdisable(irq) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_A1X_A1X_PIO_H */ diff --git a/arch/arm/src/a1x/a1x_serial.c b/arch/arm/src/a1x/a1x_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..b6e536fdc601ecc0f79ec321a8eeb0f09258f4d4 --- /dev/null +++ b/arch/arm/src/a1x/a1x_serial.c @@ -0,0 +1,1706 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_serial.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/a1x_uart.h" +#include "a1x_pio.h" +#include "a1x_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART_DEVICE) + +/* SCLK is the UART input clock. + * + * Through experimentation, it has been found that the serial clock is + * OSC24M + */ + +#define A1X_SCLK 24000000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + xcpt_t handler; /* UART interrupt handler */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int uart_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_A1X_UART0 +static int uart0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART1 +static int uart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART2 +static int uart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART3 +static int uart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART4 +static int uart4_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART5 +static int uart5_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART6 +static int uart6_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_A1X_UART7 +static int uart7_interrupt(int irq, void *context); +#endif +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_A1X_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART6 +static char g_uart6rxbuffer[CONFIG_UART6_RXBUFSIZE]; +static char g_uart6txbuffer[CONFIG_UART6_TXBUFSIZE]; +#endif + +#ifdef CONFIG_A1X_UART7 +static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; +static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; +#endif + +/* This describes the state of the A1X UART0 port. */ + +#ifdef CONFIG_A1X_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = A1X_UART0_VADDR, + .baud = CONFIG_UART0_BAUD, + .handler = uart0_interrupt, + .irq = A1X_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the A1X UART1 port. */ + +#ifdef CONFIG_A1X_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = A1X_UART1_VADDR, + .baud = CONFIG_UART1_BAUD, + .handler = uart1_interrupt, + .irq = A1X_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the A1X UART2 port. */ + +#ifdef CONFIG_A1X_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = A1X_UART2_VADDR, + .baud = CONFIG_UART2_BAUD, + .handler = uart2_interrupt, + .irq = A1X_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the A1X UART3 port. */ + +#ifdef CONFIG_A1X_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = A1X_UART3_VADDR, + .baud = CONFIG_UART3_BAUD, + .handler = uart3_interrupt, + .irq = A1X_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the A1X UART4 port. */ + +#ifdef CONFIG_A1X_UART4 +static struct up_dev_s g_uart4priv = +{ + .uartbase = A1X_UART4_VADDR, + .baud = CONFIG_UART4_BAUD, + .handler = uart4_interrupt, + .irq = A1X_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the A1X UART5 port. */ + +#ifdef CONFIG_A1X_UART5 +static struct up_dev_s g_uart5priv = +{ + .uartbase = A1X_UART5_VADDR, + .baud = CONFIG_UART5_BAUD, + .handler = uart5_interrupt, + .irq = A1X_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +}; + +static uart_dev_t g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +/* This describes the state of the A1X UART6 port. */ + +#ifdef CONFIG_A1X_UART6 +static struct up_dev_s g_uart6priv = +{ + .uartbase = A1X_UART6_VADDR, + .baud = CONFIG_UART6_BAUD, + .handler = uart6_interrupt, + .irq = A1X_IRQ_UART6, + .parity = CONFIG_UART6_PARITY, + .bits = CONFIG_UART6_BITS, + .stopbits2 = CONFIG_UART6_2STOP, +}; + +static uart_dev_t g_uart6port = +{ + .recv = + { + .size = CONFIG_UART6_RXBUFSIZE, + .buffer = g_uart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART6_TXBUFSIZE, + .buffer = g_uart6txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart6priv, +}; +#endif + +/* This describes the state of the A1X UART7 port. */ + +#ifdef CONFIG_A1X_UART7 +static struct up_dev_s g_uart7priv = +{ + .uartbase = A1X_UART7_VADDR, + .baud = CONFIG_UART7_BAUD, + .handler = uart7_interrupt, + .irq = A1X_IRQ_UART7, + .parity = CONFIG_UART7_PARITY, + .bits = CONFIG_UART7_BITS, + .stopbits2 = CONFIG_UART7_2STOP, +}; + +static uart_dev_t g_uart7port = +{ + .recv = + { + .size = CONFIG_UART7_RXBUFSIZE, + .buffer = g_uart7rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART7_TXBUFSIZE, + .buffer = g_uart7txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart7priv, +}; +#endif + +/* Which UART with be tty0/console and which tty1-7? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-7 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART5 is console */ +# define TTYS5_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart6port /* UART6 is console */ +# define TTYS5_DEV g_uart6port /* UART6 is ttyS0 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart7port /* UART7 is console */ +# define TTYS5_DEV g_uart7port /* UART7 is ttyS0 */ +# define UART7_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_A1X_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART5) +# define TTYS0_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART6) +# define TTYS0_DEV g_uart6port /* UART6 is ttyS0 */ +# define UART6_ASSIGNED 1 +# elif defined(CONFIG_A1X_UART7) +# define TTYS0_DEV g_uart7port /* UART7 is ttyS0 */ +# define UART7_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-7 excluding the console UART. */ + +#if defined(CONFIG_A1X_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS1_DEV g_uart6port /* UART6 is ttyS1 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS1_DEV g_uart7port /* UART7 is ttyS1 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-7. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-7 could also be the + * console. + */ + +#if defined(CONFIG_A1X_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS2_DEV g_uart6port /* UART6 is ttyS2 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS2_DEV g_uart7port /* UART7 is ttyS2 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-7. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-7 could also be the console. + */ + +#if defined(CONFIG_A1X_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS3_DEV g_uart6port /* UART6 is ttyS3 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS3_DEV g_uart7port /* UART7 is ttyS3 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART3-7. It can't be UART0-2 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 3-7 could also be the console. + */ + +#if defined(CONFIG_A1X_UART3) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart3port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS4_DEV g_uart6port /* UART6 is ttyS4 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS4_DEV g_uart7port /* UART7 is ttyS4 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART4-7. It can't be UART0-3 because + * those have already been assigned to ttsyS0, 1, 2, 3 or 4. One of + * UART 4-7 could also be the console. + */ + +#if defined(CONFIG_A1X_UART4) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS5_DEV g_uart5port /* UART5 is ttyS5 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS5_DEV g_uart6port /* UART6 is ttyS5 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS5_DEV g_uart7port /* UART7 is ttyS5 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys6. This could be one of UART5-7. It can't be UART0-4 because + * those have already been assigned to ttsyS0, 1, 2, 3, 4, or 5. One of + * UART 5-7 could also be the console. + */ + +#if defined(CONFIG_A1X_UART5) && !defined(UART5_ASSIGNED) +# define TTYS6_DEV g_uart5port /* UART5 is ttyS6 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS6_DEV g_uart6port /* UART6 is ttyS6 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS6_DEV g_uart7port /* UART7 is ttyS6 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys7. This could be one of UART6-7. It can't be UART0-5 because + * those have already been assigned to ttsyS0, 1, 2, 3, 4, 5, or 6. One of + * UART 6-7 could also be the console. + */ + +#if defined(CONFIG_A1X_UART6) && !defined(UART6_ASSIGNED) +# define TTYS7_DEV g_uart6port /* UART6 is ttyS7 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_A1X_UART7) && !defined(UART7_ASSIGNED) +# define TTYS7_DEV g_uart7port /* UART7 is ttyS7 */ +# define UART7_ASSIGNED 1 +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + up_serialout(priv, A1X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + up_serialout(priv, A1X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, A1X_UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BC; + } + else + { + lcr &= ~UART_LCR_BC; + } + + up_serialout(priv, A1X_UART_LCR_OFFSET, lcr); +} + +/************************************************************************************ + * Name: a1x_uart0config, uart1config, uart2config, ..., uart7config + * + * Descrption: + * Configure the UART + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_UART0 +static inline void a1x_uart0config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART0 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART0 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART0_TX); + a1x_pio_config(PIO_UART0_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART1 +static inline void a1x_uart1config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART1 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART1 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART1_TX); + a1x_pio_config(PIO_UART1_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART2 +static inline void a1x_uart2config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART2 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking on UART2 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART2_TX); + a1x_pio_config(PIO_UART2_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART3 +static inline void a1x_uart3config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART3 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART3 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART3_TX); + a1x_pio_config(PIO_UART3_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART4 +static inline void a1x_uart4config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART4 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART4 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART4_TX); + a1x_pio_config(PIO_UART4_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART5 +static inline void a1x_uart5config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART5 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART5 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART5_TX); + a1x_pio_config(PIO_UART5_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART6 +static inline void a1x_uart6config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART6 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART6 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART6_TX); + a1x_pio_config(PIO_UART6_RX); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_A1X_UART7 +static inline void a1x_uart7config(void) +{ + irqstate_t flags; + + /* Step 1: Enable power to UART7 */ + + flags = enter_critical_section(); +#warning Missing logic + + /* Step 2: Enable clocking to UART7 */ +#warning Missing logic + + /* Step 3: Configure I/O pins */ + + a1x_pio_config(PIO_UART7_TX); + a1x_pio_config(PIO_UART7_RX); + leave_critical_section(flags); +}; +#endif + +/************************************************************************************ + * Name: a1x_uartdl + * + * Descrption: + * Select a divider to produce the BAUD from the UART PCLK. + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + ************************************************************************************/ + +static inline uint32_t a1x_uartdl(uint32_t baud) +{ + return A1X_SCLK / (baud << 4); +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t dl; + uint32_t lcr; + + /* Clear fifos */ + + up_serialout(priv, A1X_UART_FCR_OFFSET, (UART_FCR_RFIFOR | UART_FCR_XFIFOR)); + + /* Set trigger */ + + up_serialout(priv, A1X_UART_FCR_OFFSET, (UART_FCR_FIFOE | UART_FCR_RT_HALF)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, A1X_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + switch (priv->bits) + { + case 5: + lcr |= UART_LCR_DLS_5BITS; + break; + + case 6: + lcr |= UART_LCR_DLS_6BITS; + break; + + case 7: + lcr |= UART_LCR_DLS_7BITS; + break; + + case 8: + default: + lcr |= UART_LCR_DLS_8BITS; + break; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STOP; + } + + if (priv->parity == 1) + { + lcr |= UART_LCR_PEN; + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + /* Enter DLAB=1 */ + + up_serialout(priv, A1X_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + dl = a1x_uartdl(priv->baud); + up_serialout(priv, A1X_UART_DLH_OFFSET, dl >> 8); + up_serialout(priv, A1X_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, A1X_UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, A1X_UART_FCR_OFFSET, + (UART_FCR_RT_HALF | UART_FCR_XFIFOR | UART_FCR_RFIFOR | + UART_FCR_FIFOE)); + + /* Enable Auto-Flow Control in the Modem Control Register */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) +# warning Missing logic +#endif + +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: uartN_interrupt and uart_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int uart_interrupt(struct uart_dev_s *dev) +{ + struct up_dev_s *priv; + uint32_t status; + int passes; + + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status */ + + status = up_serialin(priv, A1X_UART_IIR_OFFSET); + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_IID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_IID_RECV: + case UART_IIR_IID_TIMEOUT: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_IID_TXEMPTY: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts (UART1 only) */ + + case UART_IIR_IID_MODEM: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, A1X_UART_MSR_OFFSET); + vdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_IID_LINESTATUS: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, A1X_UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* Busy detect. Just ignore. Cleared by reading the status register */ + + case UART_IIR_IID_BUSY: + { + /* Read from the UART status register to clear the BUSY condition */ + + status = up_serialin(priv, A1X_UART_USR_OFFSET); + break; + } + + /* No further interrupts pending... return now */ + + case UART_IIR_IID_NONE: + { + return OK; + } + + /* Otherwise we have received an interrupt that we cannot handle */ + + default: + { + lldbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + + return OK; +} + +#ifdef CONFIG_A1X_UART0 +static int uart0_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart0port); +} +#endif + +#ifdef CONFIG_A1X_UART1 +static int uart1_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart1port); +} +#endif + +#ifdef CONFIG_A1X_UART2 +static int uart2_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart2port); +} +#endif + +#ifdef CONFIG_A1X_UART3 +static int uart3_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart3port); +} +#endif + +#ifdef CONFIG_A1X_UART4 +static int uart4_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart4port); +} +#endif + +#ifdef CONFIG_A1X_UART5 +static int uart5_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart5port); +} +#endif + +#ifdef CONFIG_A1X_UART6 +static int uart6_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart6port); +} +#endif + +#ifdef CONFIG_A1X_UART7 +static int uart7_interrupt(int irq, void *context) +{ + return uart_interrupt(&g_uart7port); +} +#endif + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + * Both cfset(i|o)speed() translate to cfsetspeed. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + uint32_t lcr; /* Holds current values of line control register */ + uint16_t dl; /* Divisor latch */ + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + /* Get the c_speed field in the termios struct */ + + priv->baud = cfgetispeed(termiosp); + + /* TODO: Re-calculate the optimal CCLK divisor for the new baud and + * and reset the divider in the CLKSEL0/1 register. + */ + + /* DLAB open latch */ + /* REVISIT: Shouldn't we just call up_setup() to do all of the following? */ + + lcr = getreg32(priv->uartbase + A1X_UART_LCR_OFFSET); + up_serialout(priv, A1X_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + dl = a1x_uartdl(priv->baud); + up_serialout(priv, A1X_UART_DLH_OFFSET, dl >> 8); + up_serialout(priv, A1X_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, A1X_UART_LCR_OFFSET, lcr); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, A1X_UART_LSR_OFFSET); + rbr = up_serialin(priv, A1X_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_ERBFI; +#endif + } + else + { + priv->ier &= ~UART_IER_ERBFI; + } + + up_serialout(priv, A1X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, A1X_UART_LSR_OFFSET) & UART_LSR_DR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, A1X_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_ETBEI; + up_serialout(priv, A1X_UART_IER_OFFSET, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_IER_ETBEI; + up_serialout(priv, A1X_UART_IER_OFFSET, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, A1X_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, A1X_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */ + +#ifdef CONFIG_A1X_UART0 +#ifndef CONFIG_UART0_SERIAL_CONSOLE + a1x_uart0config(); +#endif + up_disableuartint(&g_uart0priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART1 +#ifndef CONFIG_UART1_SERIAL_CONSOLE + a1x_uart1config(); +#else +#endif + up_disableuartint(&g_uart1priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART2 +#ifndef CONFIG_UART2_SERIAL_CONSOLE + a1x_uart2config(); +#endif + up_disableuartint(&g_uart2priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART3 +#ifndef CONFIG_UART3_SERIAL_CONSOLE + a1x_uart3config(); +#endif + up_disableuartint(&g_uart3priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART4 +#ifndef CONFIG_UART4_SERIAL_CONSOLE + a1x_uart4config(); +#endif + up_disableuartint(&g_uart4priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART5 +#ifndef CONFIG_UART5_SERIAL_CONSOLE + a1x_uart5config(); +#endif + up_disableuartint(&g_uart5priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART6 +#ifndef CONFIG_UART6_SERIAL_CONSOLE + a1x_uart6config(); +#endif + up_disableuartint(&g_uart6priv, NULL); +#endif + +#ifdef CONFIG_A1X_UART7 +#ifndef CONFIG_UART7_SERIAL_CONSOLE + a1x_uart7config(); +#endif + up_disableuartint(&g_uart7priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +#ifdef TTYS6_DEV + (void)uart_register("/dev/ttyS6", &TTYS6_DEV); +#endif +#ifdef TTYS7_DEV + (void)uart_register("/dev/ttyS7", &TTYS7_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#ifdef HAVE_SERIAL_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART_DEVICE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/a1x/a1x_serial.h b/arch/arm/src/a1x/a1x_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..47957ac12d456503c7c70ff4927ada83b17e622a --- /dev/null +++ b/arch/arm/src/a1x/a1x_serial.h @@ -0,0 +1,79 @@ +/************************************************************************************ + * arch/arm/src/a1x/a1x_serial.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_SERIAL_H +#define __ARCH_ARM_SRC_A1X_A1X_SERIAL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/a1x_uart.h" + +#include "a1x_config.h" +#include "a1x_pio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration *********************************************************************/ + +/* We cannot allow the DLM/DLL divisor to become to small or will will lose too + * much accuracy. This following is a "fudge factor" that represents the minimum + * value of the divisor that we will permit. + */ + +#define UART_MINDL 32 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_A1X_A1X_SERIAL_H */ diff --git a/arch/arm/src/a1x/a1x_timerisr.c b/arch/arm/src/a1x/a1x_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..d4e827b13d539f66d2abc929350c460d3dfb6739 --- /dev/null +++ b/arch/arm/src/a1x/a1x_timerisr.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_timerisr.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include +#include + +#include "up_arch.h" +#include "chip/a1x_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Timer 0 will run at the rate of OSC24M with no division */ + +#define TMR0_CLOCK (24000000) + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * Timer 0 counts down from the interval reload value to zero, generating + * an interrupt (and reload) when the counts decrements to zero. + */ + +#define TMR_INTERVAL ((TMR0_CLOCK + (CLK_TCK >> 1)) / CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Only a TIMER0 interrupt is expected here */ + + DEBUGASSERT((getreg32(A1X_TMR_IRQ_STA) & TMR_IRQ_TMR0) != 0); + + /* Clear the pending interrupt by writing a '1' to the status register */ + + putreg32(TMR_IRQ_TMR0, A1X_TMR_IRQ_STA); + + /* Process timer interrupt */ + + sched_process_timer(); + return OK; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the timer reload interval value */ + + putreg32(TMR_INTERVAL, A1X_TMR0_INTV_VALUE); + + /* Configure timer 0: + * + * ENABLE - Enable counting + * RELOAD - Reload timer interval value + * CLKSRC - OSC24M + * PRESCALER - No division + * MODE - Continuous mode + */ + + regval = (TMR_CTRL_EN | TMR_CTRL_RELOAD | TMR_CTRL_SRC_OSC24M | + TMR_CTRL_CLK_PRES_DIV1 | TMR_CTRL_MODE_CONTINUOUS); + putreg32(regval, A1X_TMR0_CTRL); + + /* Make sure that interrupts from the Timer 0 are disabled */ + + up_disable_irq(A1X_IRQ_TIMER0); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(A1X_IRQ_TIMER0, (xcpt_t)up_timerisr); + + /* Enable interrupts from the TIMER 0 port */ + + regval = getreg32(A1X_TMR_IRQ_EN); + regval |= TMR_IRQ_TMR0; + putreg32(regval, A1X_TMR_IRQ_EN); + + /* And enable the timer interrupt */ + + up_enable_irq(A1X_IRQ_TIMER0); +} diff --git a/arch/arm/src/a1x/chip.h b/arch/arm/src/a1x/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..c86af8e0c70f6513b60ea13084dbfcd5def11897 --- /dev/null +++ b/arch/arm/src/a1x/chip.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_H +#define __ARCH_ARM_SRC_A1X_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_H */ diff --git a/arch/arm/src/a1x/chip/a10_memorymap.h b/arch/arm/src/a1x/chip/a10_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..a4e5d669c9457c9f50c8a23e618a369e16ff00b6 --- /dev/null +++ b/arch/arm/src/a1x/chip/a10_memorymap.h @@ -0,0 +1,618 @@ +/************************************************************************************ + * arch/arm/src/a1x/a10_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H +#define __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + +/* A1X physical section base addresses (aligned to 1MB boundaries) */ + +#define A1X_INTMEM_PSECTION 0x00000000 /* Internal memory 0x0000:0000-0x0002:ffff */ +#define A1X_PERIPH_PSECTION 0x01c00000 /* Peripherals 0x01c0:0000-0x01c4:ffff */ +#define A1X_SRAMC_PSECTION 0x01d00000 /* SRAM C 0x01d0:0000-0x01df:ffff Module sram */ +#define A1X_DE_PSECTION 0x01e00000 /* DE, MP, AVG 0x01e0:0000-0x01eb:ffff */ +#define A1X_DDR_PSECTION 0x40000000 /* DDR-II/DDR-III 0x4000:0000-0xbfff:ffff 2G */ +#define A1X_BROM_PSECTION 0xfff00000 /* BROM 0xffff:0000—0xffff:7fff 32K */ + +/* A1X Offsets from the internal memory section base address */ + +#define A1X_SRAMA1_OFFSET 0x00000000 /* SRAM A1 0x0000:0000-0x0000:3fff 16K */ +#define A1X_SRAMA2_OFFSET 0x00004000 /* SRAM A2 0x0000:4000-0x0000:7fff 16K */ +#define A1X_SRAMA3_OFFSET 0x00008000 /* SRAM A3 0x0000:8000-0x0000:b3ff 13K */ +#define A1X_SRAMA4_OFFSET 0x0000b400 /* SRAM A4 0x0000:b400-0x0000:bfff 3K */ +#define A1X_SRAMNAND_OFFSET /* SRAM Nand 2K */ +#define A1X_SRAMD_OFFSET 0x00010000 /* SRAM D 0x0001:0000-0x0001:0fff 4K */ +#define A1X_SRAMDSEC_OFFSET 0x00020000 /* SRAM D(Secure) 0x0002:0000-0x0002:ffff 64K */ + +/* A1X offsets from the peripheral section base address */ + +#define A1X_SRAMC_OFFSET 0x00000000 /* SRAM Controller 0x01c0:0000-0x01c0:0fff 4K */ +#define A1X_DRAMC_OFFSET 0x00001000 /* DRAM Controller 0x01c0:1000-0x01c0:1fff 4K */ +#define A1X_DMA_OFFSET 0x00002000 /* DMA 0x01c0:2000-0x01c0:2fff 4K */ +#define A1X_NFC_OFFSET 0x00003000 /* NFC 0x01c0:3000-0x01c0:3fff 4K */ +#define A1X_TS_OFFSET 0x00004000 /* TS 0x01c0:4000-0x01c0:4fff 4K */ +#define A1X_SPI0_OFFSET 0x00005000 /* SPI 0 0x01c0:5000-0x01c0:5fff 4K */ +#define A1X_SPI1_OFFSET 0x00006000 /* SPI 1 0x01c0:6000-0x01c0:6fff 4K */ +#define A1X_MS_OFFSET 0x00007000 /* MS 0x01c0:7000-0x01c0:7fff 4K */ +#define A1X_TVD_OFFSET 0x00008000 /* TVD 0x01c0:8000-0x01c0:8fff 4K */ +#define A1X_CSI0_OFFSET 0x00009000 /* CSI 0 0x01c0:9000-0x01c0:9fff 4K */ +#define A1X_TVE0_OFFSET 0x0000a000 /* TVE 0 0x01c0:a000-0x01c0:afff 4K */ +#define A1X_EMAC_OFFSET 0x0000b000 /* EMAC 0x01c0:b000-0x01c0:bfff 4K */ +#define A1X_LCD0_OFFSET 0x0000c000 /* LCD 0 0x01c0:c000-0x01c0:cfff 4K */ +#define A1X_LCD1_OFFSET 0x0000d000 /* LCD 1 0x01c0:d000-0x01c0:dfff 4K */ +#define A1X_VE_OFFSET 0x0000e000 /* VE 0x01c0:e000-0x01c0:efff 4K */ +#define A1X_SDMMC0_OFFSET 0x0000f000 /* SD/MMC 0 0x01c0:f000-0x01c0:ffff 4K */ +#define A1X_SDMMC1_OFFSET 0x00010000 /* SD/MMC 1 0x01c1:0000-0x01c1:0fff 4K */ +#define A1X_SDMMC2_OFFSET 0x00011000 /* SD/MMC 2 0x01c1:1000-0x01c1:1fff 4K */ +#define A1X_SDMMC3_OFFSET 0x00012000 /* SD/MMC 3 0x01c1:2000-0x01c1:2fff 4K */ +#define A1X_USB0_OFFSET 0x00013000 /* USB 0 0x01c1:3000-0x01c1:3fff 4K */ +#define A1X_USB1_OFFSET 0x00014000 /* USB 1 0x01c1:4000-0x01c1:4fff 4K */ +#define A1X_SS_OFFSET 0x00015000 /* SS 0x01c1:5000-0x01c1:5fff 4K */ +#define A1X_HDMI_OFFSET 0x00016000 /* HDMI 0x01c1:6000-0x01c1:6fff 4K */ +#define A1X_SPI2_OFFSET 0x00017000 /* SPI 2 0x01c1:7000-0x01c1:7fff 4K */ +#define A1X_PATA_OFFSET 0x00019000 /* PATA 0x01c1:9000-0x01c1:9fff 4K */ +#define A1X_ACE_OFFSET 0x0001a000 /* ACE 0x01c1:A000-0x01c1:afff 4K */ +#define A1X_TVE1_OFFSET 0x0001b000 /* TVE 1 0x01c1:B000-0x01c1:bfff 4K */ +#define A1X_USB2_OFFSET 0x0001c000 /* USB 2 0x01c1:C000-0x01c1:cfff 4K */ +#define A1X_CSI1_OFFSET 0x0001d000 /* CSI 1 0x01c1:D000-0x01c1:dfff 4K */ +#define A1X_TZASC_OFFSET 0x0001e000 /* TZASC 0x01c1:E000-0x01c1:efff 4K */ +#define A1X_SPI3_OFFSET 0x0001f000 /* SPI3 0x01c1:F000-0x01c1:ffff 4K */ +#define A1X_CCM_OFFSET 0x00020000 /* CCM 0x01c2:0000-0x01c2:03ff 1K */ +#define A1X_INTC_OFFSET 0x00020400 /* INTC 0x01c2:0400-0x01c2:07ff 1K */ +#define A1X_PIO_OFFSET 0x00020800 /* PIO 0x01c2:0800-0x01c2:0bff 1K */ +#define A1X_TIMER_OFFSET 0x00020c00 /* Timer 0x01c2:0C00-0x01c2:0fff 1K */ +#define A1X_AC97_OFFSET 0x00021400 /* AC97 0x01c2:1400-0x01c2:17ff 1K */ +#define A1X_IR0_OFFSET 0x00021800 /* IR 0 0x01c2:1800-0x01c2:1bff 1K */ +#define A1X_IR1_OFFSET 0x00021c00 /* IR 1 0x01c2:1c00-0x01c2:1fff 1K */ +#define A1X_IIS_OFFSET 0x00022400 /* IIS 0x01c2:2400-0x01c2:27ff 1K */ +#define A1X_LRADC01_OFFSET 0x00022800 /* LRADC 0/1 0x01c2:2800-0x01c2:2bff 1K */ +#define A1X_ADDA_OFFSET 0x00022c00 /* AD/DA 0x01c2:2c00-0x01c2:2fff 1K */ +#define A1X_KEYPAD_OFFSET 0x00023000 /* KEYPAD 0x01c2:3000-0x01c2:33ff 1K */ +#define A1X_TZPC_OFFSET 0x00023400 /* TZPC 0x01c2:3400-0x01c2:37ff 1K */ +#define A1X_SID_OFFSET 0x00023800 /* SID 0x01c2:3800-0x01c2:3bff 1K */ +#define A1X_SJTAG_OFFSET 0x00023c00 /* SJTAG 0x01c2:3c00-0x01c2:3fff 1K */ +#define A1X_TP_OFFSET 0x00025000 /* TP 0x01c2:5000-0x01c2:53ff 1K */ +#define A1X_PMU_OFFSET 0x00025400 /* PMU 0x01c2:5400-0x01c2:57ff 1K */ +#define A1X_UART_OFFSET(n) (0x00028000 + ((uint32_t)(n) << 10)) +#define A1X_UART0_OFFSET 0x00028000 /* UART 0 0x01c2:8000-0x01c2:83ff 1K */ +#define A1X_UART1_OFFSET 0x00028400 /* UART 1 0x01c2:8400-0x01c2:87ff 1K */ +#define A1X_UART2_OFFSET 0x00028800 /* UART 2 0x01c2:8800-0x01c2:8bff 1K */ +#define A1X_UART3_OFFSET 0x00028c00 /* UART 3 0x01c2:8C00-0x01c2:8fff 1K */ +#define A1X_UART4_OFFSET 0x00029000 /* UART 4 0x01c2:9000-0x01c2:93ff 1K */ +#define A1X_UART5_OFFSET 0x00029400 /* UART 5 0x01c2:9400-0x01c2:97ff 1K */ +#define A1X_UART6_OFFSET 0x00029800 /* UART 6 0x01c2:9800-0x01c2:9bff 1K */ +#define A1X_UART7_OFFSET 0x00029c00 /* UART 7 0x01c2:9c00-0x01c2:9fff 1K */ +#define A1X_PS20_OFFSET 0x0002a000 /* PS2-0 0x01c2:a000-0x01c2:a3ff 1K */ +#define A1X_PS21_OFFSET 0x0002a400 /* PS2-1 0x01c2:a400-0x01c2:a7ff 1K */ +#define A1X_TWI0_OFFSET 0x0002ac00 /* TWI 0 0x01c2:ac00-0x01c2:afff 1K */ +#define A1X_TWI1_OFFSET 0x0002b000 /* TWI 1 0x01c2:b000-0x01c2:B3ff 1K */ +#define A1X_TWI2_OFFSET 0x0002b400 /* TWI 2 0x01c2:b400-0x01c2:b7ff 1K */ +#define A1X_CAN_OFFSET 0x0002bc00 /* CAN 0x01c2:bc00-0x01c2:bfff 1K */ +#define A1X_SCR_OFFSET 0x0002c400 /* SCR 0x01c2:c400-0x01c2:c7ff 1K */ +#define A1X_MALI400_OFFSET 0x00040000 /* Mali400 0x01c4:0000-0x01c4:ffff 64K */ + +/* A1X offsets from the DE section base address */ + +#define A1X_DEFE0_OFFSET 0x00000000 /* DE_FE0 0x01e0:0000-0x01e1:ffff 128K */ +#define A1X_DEFE1_OFFSET 0x00020000 /* DE_FE1 0x01e2:0000-0x01e3:ffff 128K */ +#define A1X_DEBE0_OFFSET 0x00060000 /* DE_BE0 0x01e6:0000-0x01e7:ffff 128K */ +#define A1X_DEBE1_OFFSET 0x00040000 /* DE_BE1 0x01e4:0000-0x01e5:ffff 128K */ +#define A1X_MP_OFFSET 0x00080000 /* MP 0x01e8:0000-0x01e9:ffff 128K */ +#define A1X_AVG_OFFSET 0x000a0000 /* AVG 0x01ea:0000-0x01eb:ffff 128K */ + +/* A1X offsets from the BRROM section base address */ + +#define A1X_BROM_OFFSET 0x000f0000 /* BROM 0xffff:0000—0xffff:7fff 32K */ + +/* A1X internal memory physical base addresses */ + +#define A1X_SRAMA1_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA1_OFFSET) +#define A1X_SRAMA2_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA2_OFFSET) +#define A1X_SRAMA3_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA3_OFFSET) +#define A1X_SRAMA4_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA4_OFFSET) +#define A1X_SRAMNAND_PADDR +#define A1X_SRAMD_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMD_OFFSET) +#define A1X_SRAMDSEC_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMDSEC_OFFSET) + +/* Peripheral physical base addresses */ + +#define A1X_SRAMC_PADDR (A1X_PERIPH_PSECTION+A1X_SRAMC_OFFSET) +#define A1X_DRAMC_PADDR (A1X_PERIPH_PSECTION+A1X_DRAMC_OFFSET) +#define A1X_DMA_PADDR (A1X_PERIPH_PSECTION+A1X_DMA_OFFSET) +#define A1X_NFC_PADDR (A1X_PERIPH_PSECTION+A1X_NFC_OFFSET) +#define A1X_TS_PADDR (A1X_PERIPH_PSECTION+A1X_TS_OFFSET) +#define A1X_SPI0_PADDR (A1X_PERIPH_PSECTION+A1X_SPI0_OFFSET) +#define A1X_SPI1_PADDR (A1X_PERIPH_PSECTION+A1X_SPI1_OFFSET) +#define A1X_MS_PADDR (A1X_PERIPH_PSECTION+A1X_MS_OFFSET) +#define A1X_TVD_PADDR (A1X_PERIPH_PSECTION+A1X_TVD_OFFSET) +#define A1X_CSI0_PADDR (A1X_PERIPH_PSECTION+A1X_CSI0_OFFSET) +#define A1X_TVE0_PADDR (A1X_PERIPH_PSECTION+A1X_TVE0_OFFSET) +#define A1X_EMAC_PADDR (A1X_PERIPH_PSECTION+A1X_EMAC_OFFSET) +#define A1X_LCD0_PADDR (A1X_PERIPH_PSECTION+A1X_LCD0_OFFSET) +#define A1X_LCD1_PADDR (A1X_PERIPH_PSECTION+A1X_LCD1_OFFSET) +#define A1X_VE_PADDR (A1X_PERIPH_PSECTION+A1X_VE_OFFSET) +#define A1X_SDMMC0_PADDR (A1X_PERIPH_PSECTION+A1X_SDMMC0_OFFSET) +#define A1X_SDMMC1_PADDR (A1X_PERIPH_PSECTION+A1X_SDMMC1_OFFSET) +#define A1X_SDMMC2_PADDR (A1X_PERIPH_PSECTION+A1X_SDMMC2_OFFSET) +#define A1X_SDMMC3_PADDR (A1X_PERIPH_PSECTION+A1X_SDMMC3_OFFSET) +#define A1X_USB0_PADDR (A1X_PERIPH_PSECTION+A1X_USB0_OFFSET) +#define A1X_USB1_PADDR (A1X_PERIPH_PSECTION+A1X_USB1_OFFSET) +#define A1X_SS_PADDR (A1X_PERIPH_PSECTION+A1X_SS_OFFSET) +#define A1X_HDMI_PADDR (A1X_PERIPH_PSECTION+A1X_HDMI_OFFSET) +#define A1X_SPI2_PADDR (A1X_PERIPH_PSECTION+A1X_SPI2_OFFSET) +#define A1X_PATA_PADDR (A1X_PERIPH_PSECTION+A1X_PATA_OFFSET) +#define A1X_ACE_PADDR (A1X_PERIPH_PSECTION+A1X_ACE_OFFSET) +#define A1X_TVE1_PADDR (A1X_PERIPH_PSECTION+A1X_TVE1_OFFSET) +#define A1X_USB2_PADDR (A1X_PERIPH_PSECTION+A1X_USB2_OFFSET) +#define A1X_CSI1_PADDR (A1X_PERIPH_PSECTION+A1X_CSI1_OFFSET) +#define A1X_TZASC_PADDR (A1X_PERIPH_PSECTION+A1X_TZASC_OFFSET) +#define A1X_SPI3_PADDR (A1X_PERIPH_PSECTION+A1X_SPI3_OFFSET) +#define A1X_CCM_PADDR (A1X_PERIPH_PSECTION+A1X_CCM_OFFSET) +#define A1X_INTC_PADDR (A1X_PERIPH_PSECTION+A1X_INTC_OFFSET) +#define A1X_PIO_PADDR (A1X_PERIPH_PSECTION+A1X_PIO_OFFSET) +#define A1X_TIMER_PADDR (A1X_PERIPH_PSECTION+A1X_TIMER_OFFSET) +#define A1X_AC97_PADDR (A1X_PERIPH_PSECTION+A1X_AC97_OFFSET) +#define A1X_IR0_PADDR (A1X_PERIPH_PSECTION+A1X_IR0_OFFSET) +#define A1X_IR1_PADDR (A1X_PERIPH_PSECTION+A1X_IR1_OFFSET) +#define A1X_IIS_PADDR (A1X_PERIPH_PSECTION+A1X_IIS_OFFSET) +#define A1X_LRADC01_PADDR (A1X_PERIPH_PSECTION+A1X_LRADC01_OFFSET) +#define A1X_ADDA_PADDR (A1X_PERIPH_PSECTION+A1X_ADDA_OFFSET) +#define A1X_KEYPAD_PADDR (A1X_PERIPH_PSECTION+A1X_KEYPAD_OFFSET) +#define A1X_TZPC_PADDR (A1X_PERIPH_PSECTION+A1X_TZPC_OFFSET) +#define A1X_SID_PADDR (A1X_PERIPH_PSECTION+A1X_SID_OFFSET) +#define A1X_SJTAG_PADDR (A1X_PERIPH_PSECTION+A1X_SJTAG_OFFSET) +#define A1X_TP_PADDR (A1X_PERIPH_PSECTION+A1X_TP_OFFSET) +#define A1X_PMU_PADDR (A1X_PERIPH_PSECTION+A1X_PMU_OFFSET) +#define A1X_UART_PADDR(n) (A1X_PERIPH_PSECTION+A1X_UART_OFFSET(n)) +#define A1X_UART0_PADDR (A1X_PERIPH_PSECTION+A1X_UART0_OFFSET) +#define A1X_UART1_PADDR (A1X_PERIPH_PSECTION+A1X_UART1_OFFSET) +#define A1X_UART2_PADDR (A1X_PERIPH_PSECTION+A1X_UART2_OFFSET) +#define A1X_UART3_PADDR (A1X_PERIPH_PSECTION+A1X_UART3_OFFSET) +#define A1X_UART4_PADDR (A1X_PERIPH_PSECTION+A1X_UART4_OFFSET) +#define A1X_UART5_PADDR (A1X_PERIPH_PSECTION+A1X_UART5_OFFSET) +#define A1X_UART6_PADDR (A1X_PERIPH_PSECTION+A1X_UART6_OFFSET) +#define A1X_UART7_PADDR (A1X_PERIPH_PSECTION+A1X_UART7_OFFSET) +#define A1X_PS20_PADDR (A1X_PERIPH_PSECTION+A1X_PS20_OFFSET) +#define A1X_PS21_PADDR (A1X_PERIPH_PSECTION+A1X_PS21_OFFSET) +#define A1X_TWI0_PADDR (A1X_PERIPH_PSECTION+A1X_TWI0_OFFSET) +#define A1X_TWI1_PADDR (A1X_PERIPH_PSECTION+A1X_TWI1_OFFSET) +#define A1X_TWI2_PADDR (A1X_PERIPH_PSECTION+A1X_TWI2_OFFSET) +#define A1X_CAN_PADDR (A1X_PERIPH_PSECTION+A1X_CAN_OFFSET) +#define A1X_SCR_PADDR (A1X_PERIPH_PSECTION+A1X_SCR_OFFSET) +#define A1X_MALI400_PADDR (A1X_PERIPH_PSECTION+A1X_MALI400_OFFSET) + +/* A1X DE section physical base addresses */ + +#define A1X_DEFE0_PADDR (A1X_DE_PSECTION+A1X_DEFE0_OFFSET) +#define A1X_DEFE1_PADDR (A1X_DE_PSECTION+A1X_DEFE1_OFFSET) +#define A1X_DEBE0_PADDR (A1X_DE_PSECTION+A1X_DEBE0_OFFSET) +#define A1X_DEBE1_PADDR (A1X_DE_PSECTION+A1X_DEBE1_OFFSET) +#define A1X_MP_PADDR (A1X_DE_PSECTION+A1X_MP_OFFSET) +#define A1X_AVG_PADDR (A1X_DE_PSECTION+A1X_AVG_OFFSET) + +/* A1X BRROM section physical base address */ + +#define A1X_BROM_PADDR (A1X_BROM_PSECTION+A1X_BROM_OFFSET) + +/* Sizes of memory regions in bytes. + * + * These sizes exclude the undefined addresses at the end of the memory + * region. The implemented sizes of the external memory regions are + * not known apriori and must be specified with configuration settings. + */ + +#define A1X_INTMEM_SIZE 0x00030000 /* Internal memory 0x0000:0000-0x0002:ffff */ +#define A1X_PERIPH_SIZE 0x00050000 /* Peripherals 0x01c0:0000-0x01c4:ffff */ +#define A1X_SRAMC_SIZE 0x00100000 /* SRAM C 0x01d0:0000-0x01df:ffff Module sram */ +#define A1X_DE_SIZE 0x000c0000 /* DE, MP, AVG 0x01e0:0000-0x01eb:ffff */ +#define A1X_BROM_SIZE 0x000f8000 /* BROM 0xfff0:0000—0xffff:7fff 32K */ + +/* Force configured sizes that might exceed 2GB to be unsigned long */ + +#define A1X_DDR_MAPOFFSET MKULONG(CONFIG_A1X_DDR_MAPOFFSET) +#define A1X_DDR_MAPSIZE MKULONG(CONFIG_A1X_DDR_MAPSIZE) +#define A1X_DDR_HEAP_OFFSET MKULONG(CONFIG_A1X_DDR_HEAP_OFFSET) +#define A1X_DDR_HEAP_SIZE MKULONG(CONFIG_A1X_DDR_HEAP_SIZE) + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of memory regions in sections. + * + * The boot logic in A1X_boot.c, will select 1Mb level 1 MMU mappings to + * span the entire physical address space. The definitions below specify + * the number of 1Mb entries that are required to span a particular address + * region. + * + * NOTE: the size of the mapped SDRAM region depends on the configured size + * of DRAM, not on the size of the address space assigned to DRAM. + */ + +#define A1X_INTMEM_NSECTIONS _NSECTIONS(A1X_INTMEM_SIZE) +#define A1X_PERIPH_NSECTIONS _NSECTIONS(A1X_PERIPH_SIZE) +#define A1X_SRAMC_NSECTIONS _NSECTIONS(A1X_SRAMC_SIZE) +#define A1X_DE_NSECTIONS _NSECTIONS(A1X_DE_SIZE) +#define A1X_DDR_NSECTIONS _NSECTIONS(A1X_DDR_MAPSIZE) +#define A1X_BROM_NSECTIONS _NSECTIONS(A1X_BROM_SIZE) + +/* Section MMU Flags */ + +#define A1X_INTMEM_MMUFLAGS MMU_MEMFLAGS +#define A1X_PERIPH_MMUFLAGS MMU_IOFLAGS +#define A1X_SRAMC_MMUFLAGS MMU_MEMFLAGS +#define A1X_DE_MMUFLAGS MMU_IOFLAGS +#define A1X_DDR_MMUFLAGS MMU_MEMFLAGS +#define A1X_BROM_MMUFLAGS MMU_ROMFLAGS + +/* A1X Virtual (mapped) Memory Map + * + * board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* A1X Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + +/* Notice that these mappings are a simple 1-to-1 mappings */ + +#define A1X_INTMEM_VSECTION 0x00000000 /* Internal memory 0x0000:0000-0x0002:ffff */ +#define A1X_PERIPH_VSECTION 0x01c00000 /* Peripherals 0x01c0:0000-0x01c4:ffff */ +#define A1X_SRAMC_VSECTION 0x01d00000 /* SRAM C 0x01d0:0000-0x01df:ffff Module sram */ +#define A1X_DE_VSECTION 0x01e00000 /* DE, MP, AVG 0x01e0:0000-0x01eb:ffff */ +#define A1X_DDR_VSECTION 0x40000000 /* DDR-II/DDR-III 0x4000:0000-0xbfff:ffff 2G */ +#define A1X_BROM_VSECTION 0xfff00000 /* BROM 0xffff:0000—0xffff:7fff 32K */ + +#endif + +/* A1X internal memory virtual base addresses */ + +#define A1X_SRAMA1_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA1_OFFSET) +#define A1X_SRAMA2_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA2_OFFSET) +#define A1X_SRAMA3_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA3_OFFSET) +#define A1X_SRAMA4_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA4_OFFSET) +#define A1X_SRAMNAND_VADDR +#define A1X_SRAMD_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMD_OFFSET) +#define A1X_SRAMDSEC_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMDSEC_OFFSET) + +/* Peripheral virtual base addresses */ + +#define A1X_SRAMC_VADDR (A1X_PERIPH_VSECTION+A1X_SRAMC_OFFSET) +#define A1X_DRAMC_VADDR (A1X_PERIPH_VSECTION+A1X_DRAMC_OFFSET) +#define A1X_DMA_VADDR (A1X_PERIPH_VSECTION+A1X_DMA_OFFSET) +#define A1X_NFC_VADDR (A1X_PERIPH_VSECTION+A1X_NFC_OFFSET) +#define A1X_TS_VADDR (A1X_PERIPH_VSECTION+A1X_TS_OFFSET) +#define A1X_SPI0_VADDR (A1X_PERIPH_VSECTION+A1X_SPI0_OFFSET) +#define A1X_SPI1_VADDR (A1X_PERIPH_VSECTION+A1X_SPI1_OFFSET) +#define A1X_MS_VADDR (A1X_PERIPH_VSECTION+A1X_MS_OFFSET) +#define A1X_TVD_VADDR (A1X_PERIPH_VSECTION+A1X_TVD_OFFSET) +#define A1X_CSI0_VADDR (A1X_PERIPH_VSECTION+A1X_CSI0_OFFSET) +#define A1X_TVE0_VADDR (A1X_PERIPH_VSECTION+A1X_TVE0_OFFSET) +#define A1X_EMAC_VADDR (A1X_PERIPH_VSECTION+A1X_EMAC_OFFSET) +#define A1X_LCD0_VADDR (A1X_PERIPH_VSECTION+A1X_LCD0_OFFSET) +#define A1X_LCD1_VADDR (A1X_PERIPH_VSECTION+A1X_LCD1_OFFSET) +#define A1X_VE_VADDR (A1X_PERIPH_VSECTION+A1X_VE_OFFSET) +#define A1X_SDMMC0_VADDR (A1X_PERIPH_VSECTION+A1X_SDMMC0_OFFSET) +#define A1X_SDMMC1_VADDR (A1X_PERIPH_VSECTION+A1X_SDMMC1_OFFSET) +#define A1X_SDMMC2_VADDR (A1X_PERIPH_VSECTION+A1X_SDMMC2_OFFSET) +#define A1X_SDMMC3_VADDR (A1X_PERIPH_VSECTION+A1X_SDMMC3_OFFSET) +#define A1X_USB0_VADDR (A1X_PERIPH_VSECTION+A1X_USB0_OFFSET) +#define A1X_USB1_VADDR (A1X_PERIPH_VSECTION+A1X_USB1_OFFSET) +#define A1X_SS_VADDR (A1X_PERIPH_VSECTION+A1X_SS_OFFSET) +#define A1X_HDMI_VADDR (A1X_PERIPH_VSECTION+A1X_HDMI_OFFSET) +#define A1X_SPI2_VADDR (A1X_PERIPH_VSECTION+A1X_SPI2_OFFSET) +#define A1X_PATA_VADDR (A1X_PERIPH_VSECTION+A1X_PATA_OFFSET) +#define A1X_ACE_VADDR (A1X_PERIPH_VSECTION+A1X_ACE_OFFSET) +#define A1X_TVE1_VADDR (A1X_PERIPH_VSECTION+A1X_TVE1_OFFSET) +#define A1X_USB2_VADDR (A1X_PERIPH_VSECTION+A1X_USB2_OFFSET) +#define A1X_CSI1_VADDR (A1X_PERIPH_VSECTION+A1X_CSI1_OFFSET) +#define A1X_TZASC_VADDR (A1X_PERIPH_VSECTION+A1X_TZASC_OFFSET) +#define A1X_SPI3_VADDR (A1X_PERIPH_VSECTION+A1X_SPI3_OFFSET) +#define A1X_CCM_VADDR (A1X_PERIPH_VSECTION+A1X_CCM_OFFSET) +#define A1X_INTC_VADDR (A1X_PERIPH_VSECTION+A1X_INTC_OFFSET) +#define A1X_PIO_VADDR (A1X_PERIPH_VSECTION+A1X_PIO_OFFSET) +#define A1X_TIMER_VADDR (A1X_PERIPH_VSECTION+A1X_TIMER_OFFSET) +#define A1X_AC97_VADDR (A1X_PERIPH_VSECTION+A1X_AC97_OFFSET) +#define A1X_IR0_VADDR (A1X_PERIPH_VSECTION+A1X_IR0_OFFSET) +#define A1X_IR1_VADDR (A1X_PERIPH_VSECTION+A1X_IR1_OFFSET) +#define A1X_IIS_VADDR (A1X_PERIPH_VSECTION+A1X_IIS_OFFSET) +#define A1X_LRADC01_VADDR (A1X_PERIPH_VSECTION+A1X_LRADC01_OFFSET) +#define A1X_ADDA_VADDR (A1X_PERIPH_VSECTION+A1X_ADDA_OFFSET) +#define A1X_KEYPAD_VADDR (A1X_PERIPH_VSECTION+A1X_KEYPAD_OFFSET) +#define A1X_TZPC_VADDR (A1X_PERIPH_VSECTION+A1X_TZPC_OFFSET) +#define A1X_SID_VADDR (A1X_PERIPH_VSECTION+A1X_SID_OFFSET) +#define A1X_SJTAG_VADDR (A1X_PERIPH_VSECTION+A1X_SJTAG_OFFSET) +#define A1X_TP_VADDR (A1X_PERIPH_VSECTION+A1X_TP_OFFSET) +#define A1X_PMU_VADDR (A1X_PERIPH_VSECTION+A1X_PMU_OFFSET) +#define A1X_UART_VADDR(n) (A1X_PERIPH_VSECTION+A1X_UART_OFFSET(n)) +#define A1X_UART0_VADDR (A1X_PERIPH_VSECTION+A1X_UART0_OFFSET) +#define A1X_UART1_VADDR (A1X_PERIPH_VSECTION+A1X_UART1_OFFSET) +#define A1X_UART2_VADDR (A1X_PERIPH_VSECTION+A1X_UART2_OFFSET) +#define A1X_UART3_VADDR (A1X_PERIPH_VSECTION+A1X_UART3_OFFSET) +#define A1X_UART4_VADDR (A1X_PERIPH_VSECTION+A1X_UART4_OFFSET) +#define A1X_UART5_VADDR (A1X_PERIPH_VSECTION+A1X_UART5_OFFSET) +#define A1X_UART6_VADDR (A1X_PERIPH_VSECTION+A1X_UART6_OFFSET) +#define A1X_UART7_VADDR (A1X_PERIPH_VSECTION+A1X_UART7_OFFSET) +#define A1X_PS20_VADDR (A1X_PERIPH_VSECTION+A1X_PS20_OFFSET) +#define A1X_PS21_VADDR (A1X_PERIPH_VSECTION+A1X_PS21_OFFSET) +#define A1X_TWI0_VADDR (A1X_PERIPH_VSECTION+A1X_TWI0_OFFSET) +#define A1X_TWI1_VADDR (A1X_PERIPH_VSECTION+A1X_TWI1_OFFSET) +#define A1X_TWI2_VADDR (A1X_PERIPH_VSECTION+A1X_TWI2_OFFSET) +#define A1X_CAN_VADDR (A1X_PERIPH_VSECTION+A1X_CAN_OFFSET) +#define A1X_SCR_VADDR (A1X_PERIPH_VSECTION+A1X_SCR_OFFSET) +#define A1X_MALI400_VADDR (A1X_PERIPH_VSECTION+A1X_MALI400_OFFSET) + +/* A1X DE section virtual base addresses */ + +#define A1X_DEFE0_VADDR (A1X_DE_VSECTION+A1X_DEFE0_OFFSET) +#define A1X_DEFE1_VADDR (A1X_DE_VSECTION+A1X_DEFE1_OFFSET) +#define A1X_DEBE0_VADDR (A1X_DE_VSECTION+A1X_DEBE0_OFFSET) +#define A1X_DEBE1_VADDR (A1X_DE_VSECTION+A1X_DEBE1_OFFSET) +#define A1X_MP_VADDR (A1X_DE_VSECTION+A1X_MP_OFFSET) +#define A1X_AVG_VADDR (A1X_DE_VSECTION+A1X_AVG_OFFSET) + +/* A1X BRROM section virtual base address */ + +#define A1X_BROM_VADDR (A1X_BROM_VSECTION+A1X_BROM_OFFSET) + +/* Offset SDRAM address */ + +#define A1X_DDR_MAPPADDR (A1X_DDR_PSECTION+A1X_DDR_MAPOFFSET) +#define A1X_DDR_MAPVADDR (A1X_DDR_VSECTION+A1X_DDR_MAPOFFSET) + +/* NuttX virtual base address + * + * The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX will be running from either + * internal SRAM or external SDRAM. + * + * Setup the RAM region as the NUTTX .txt, .bss, and .data region. + */ + +#define NUTTX_TEXT_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +#define NUTTX_TEXT_PADDR (CONFIG_RAM_START & 0xfff00000) +#define NUTTX_TEXT_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +#define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + +/* MMU Page Table + * + * Determine the address of the MMU page table. Regardless of the memory + * configuration, we will keep the page table in the A1X's internal SRAM. + */ + +#if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + +#else /* PGTABLE_BASE_PADDR || PGTABLE_BASE_VADDR */ + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. In that case PGTABLE_BASE_VADDR is defined + * in the file mmu.h + * + * We must declare the page table at the bottom or at the top of internal + * SRAM. We pick the bottom of internal SRAM *unless* there are vectors + * in the way at that position. + */ + +# if defined(CONFIG_ARCH_LOWVECTORS) + /* In this case, table must lie in SRAM A2 after the vectors in SRAM A1 */ + +# define PGTABLE_BASE_PADDR A1X_SRAMA2_PADDR +# define PGTABLE_BASE_VADDR A1X_SRAMA2_VADDR + +# else /* CONFIG_ARCH_LOWVECTORS */ + + /* Otherwise, the vectors lie at another location. The page table will + * then be positioned at the beginning of SRAM A1. + */ + +# define PGTABLE_BASE_PADDR A1X_SRAMA1_PADDR +# define PGTABLE_BASE_VADDR A1X_SRAMA1_VADDR + +# endif /* CONFIG_ARCH_LOWVECTORS */ + + /* Note that the page table does not lie in the same address space as does the + * mapped RAM in either case. So we will need to create a special mapping for + * the page table at boot time. + */ + +# define ARMV7A_PGTABLE_MAPPING 1 + +#endif /* PGTABLE_BASE_PADDR || PGTABLE_BASE_VADDR */ + +/* Level 2 Page table start addresses. + * + * 16Kb of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation). There are several large holes in the physical address + * space for which there will never be level 1 mappings: + * + * LI PAGE TABLE + * ADDRESS RANGE SIZE ENTRIES SECTIONS + * ----------------------- ------- -------------- --------- + * 0x0003:0000-0x01eb:ffff 275MB 0x0004-0x006c 26 + * *(none usable) 0 + * 0x01ec:0000-0x3fff:ffff 993MB 0x0078-0x0ffc 993 + * *0x0400-0x0ffc 767 + * + * And the largest is probably from the end of SDRAM through 0xfff0:0000. + * But the size of that region varies with the size of the installed SDRAM. + * It is at least: + * + * LI PAGE TABLE + * ADDRESS RANGE SIZE ENTRIES SECTIONS + * ----------------------- ------- -------------- --------- + * 0xc000:0000-0xffef:ffff 1022MB *0x3000-0x3ff8 1022 + * + * And probably much larger. + * + * * NOTE that the L2 page table entries must be aligned 1KB address + * boundaries. + * + * These two larger regions is where L2 page tables will positioned. Up to + * two L2 page tables may be used: + * + * 1) One mapping the vector table (only when CONFIG_ARCH_LOWVECTORS is not + * defined). + * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional + * L2 page table is needed. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS +/* Vector L2 page table offset/size */ + +# define VECTOR_L2_OFFSET 0x000000400 +# define VECTOR_L2_SIZE 0x000000bfc + +/* Vector L2 page table base addresses */ + +# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET) +# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET) + +/* Vector L2 page table end addresses */ + +# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE) +# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE) + +#endif /* !CONFIG_ARCH_LOWVECTORS */ + +/* Paging L2 page table offset/size */ + +#define PGTABLE_L2_START_PADDR (A1X_DDR_PSECTION+A1X_DDR_MAPOFFSET+A1X_DDR_MAPSIZE) +#define PGTABLE_BROM_OFFSET 0x3ffc + +#define PGTABLE_L2_OFFSET ((PGTABLE_L2_START_PADDR >> 18) & ~3) +#define PGTABLE_L2_SIZE (PGTABLE_BROM_OFFSET - PGTABLE_L2_OFFSET) + +/* Paging L2 page table base addresses + * + * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +/* Paging L2 page table end addresses */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE) + +/* Base address of the interrupt vector table. + * + * A1X_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * A1X_VECTOR_VSRAM - Virtual address of vector table in SRAM + * A1X_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + * + * NOTE: When using LOWVECTORS, the actual base of the vectors appears to be + * offset to address 0x0000:0040 + */ + +#define VECTOR_TABLE_SIZE 0x00010000 +#define VECTOR_TABLE_OFFSET 0x00000040 + +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + +# define A1X_VECTOR_PADDR A1X_SRAMA1_PADDR +# define A1X_VECTOR_VSRAM A1X_SRAMA1_VADDR +# define A1X_VECTOR_VADDR 0x00000000 + +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ + +# ifdef A1X_ISRAM1_SIZE >= VECTOR_TABLE_SIZE +# define A1X_VECTOR_PADDR (A1X_SRAMA1_PADDR+A1X_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# define A1X_VECTOR_VSRAM (A1X_SRAMA1_VADDR+A1X_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# else +# define A1X_VECTOR_PADDR (A1X_SRAMA1_PADDR+A1X_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# define A1X_VECTOR_VSRAM (A1X_SRAMA1_VADDR+A1X_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# endif +# define A1X_VECTOR_VADDR 0xffff0000 + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H */ diff --git a/arch/arm/src/a1x/chip/a10_piocfg.h b/arch/arm/src/a1x/chip/a10_piocfg.h new file mode 100644 index 0000000000000000000000000000000000000000..3ed6a652dbc603a0819ec9c963f0e940bf908c73 --- /dev/null +++ b/arch/arm/src/a1x/chip/a10_piocfg.h @@ -0,0 +1,612 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a10_piocfg.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H +#define __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* PIO pin definitions *************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific PIO options (such as pull-up or + * -down). Just the basics are defined for most pins in this file at the present + * time. + */ + +/* AC97 */ + +#define PIO_AC97_BCLK (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_AC97_DI (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_AC97_DO (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_AC97_MCLK (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_AC97_SYNC (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN7) + +/* ATA */ + +#define PIO_ATAA0 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN0) +#define PIO_ATAA1 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN1) +#define PIO_ATAA2 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN2) +#define PIO_ATACS0 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN23) +#define PIO_ATACS1 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN24) +#define PIO_ATAD0 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN4) +#define PIO_ATAD1 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN5) +#define PIO_ATAD2 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_ATAD3 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_ATAD4 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_ATAD5 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_ATAD6 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_ATAD7 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN11) +#define PIO_ATAD8 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN12) +#define PIO_ATAD9 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN13) +#define PIO_ATAD10 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_ATAD11 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN15) +#define PIO_ATAD12 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN16) +#define PIO_ATAD13 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_ATAD14 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_ATAD15 (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN19) +#define PIO_ATADACK (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN22) +#define PIO_ATADREQ (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN21) +#define PIO_ATAIOR (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN26) +#define PIO_ATAIORDY (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN25) +#define PIO_ATAIOW (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN27) +#define PIO_ATAIRQ (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN3) +#define PIO_ATAOE (PIO_PERIPH3 | PIO_PORT_PIOH | PIO_PIN20) + +/* CAN */ + +#define PIO_CAN_RX_1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_CAN_RX_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN21) +#define PIO_CAN_TX_1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_CAN_TX_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN20) + +/* Camera Sensor Interface (CSI) */ + +#define PIO_CSI0_CK (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN1) +#define PIO_CSI0_D0 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN4) +#define PIO_CSI0_D1 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN5) +#define PIO_CSI0_D2 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN6) +#define PIO_CSI0_D3 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN7) +#define PIO_CSI0_D4 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN8) +#define PIO_CSI0_D5 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN9) +#define PIO_CSI0_D6 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN10) +#define PIO_CSI0_D7 (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN11) +#define PIO_CSI0_D8 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN4) +#define PIO_CSI0_D9 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN5) +#define PIO_CSI0_D10 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN6) +#define PIO_CSI0_D11 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN7) +#define PIO_CSI0_D12 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN8) +#define PIO_CSI0_D13 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN9) +#define PIO_CSI0_D14 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN10) +#define PIO_CSI0_D15 (PIO_PERIPH5 | PIO_PORT_PIOG | PIO_PIN11) +#define PIO_CSI0_HSYNC (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN2) +#define PIO_CSI0_PCK (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_CSI0_VSYNC (PIO_PERIPH3 | PIO_PORT_PIOE | PIO_PIN3) + +#define PIO_CSI1_CK (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN1) +#define PIO_CSI1_D0_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN4) +#define PIO_CSI1_D0_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN0) +#define PIO_CSI1_D1_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN5) +#define PIO_CSI1_D1_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN1) +#define PIO_CSI1_D2_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN6) +#define PIO_CSI1_D2_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN2) +#define PIO_CSI1_D3_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN7) +#define PIO_CSI1_D3_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN3) +#define PIO_CSI1_D4_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN8) +#define PIO_CSI1_D4_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN4) +#define PIO_CSI1_D5_1 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN9) +#define PIO_CSI1_D5_2 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN5) +#define PIO_CSI1_D6_1 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_CSI1_D6_2 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN10) +#define PIO_CSI1_D7_1 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_CSI1_D7_2 (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN11) +#define PIO_CSI1_D8 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_CSI1_D9 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_CSI1_D10 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_CSI1_D11 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN11) +#define PIO_CSI1_D12 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN12) +#define PIO_CSI1_D13 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN13) +#define PIO_CSI1_D14 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_CSI1_D15 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN15) +#define PIO_CSI1_D16 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN16) +#define PIO_CSI1_D17 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_CSI1_D18 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_CSI1_D19 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN19) +#define PIO_CSI1_D20 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN20) +#define PIO_CSI1_D21 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN21) +#define PIO_CSI1_D22 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN22) +#define PIO_CSI1_D23 (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN23) +#define PIO_CSI1_FIELD (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN25) +#define PIO_CSI1_HSYNC (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN2) +#define PIO_CSI1_HSYNC (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN26) +#define PIO_CSI1_MCLK (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_CSI1_PCK (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN0) +#define PIO_CSI1_PCLK (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN24) +#define PIO_CSI1_VSYNC (PIO_PERIPH3 | PIO_PORT_PIOG | PIO_PIN3) +#define PIO_CSI1_VSYNC (PIO_PERIPH7 | PIO_PORT_PIOH | PIO_PIN27) + +/* Ethernet MAC */ + +#define PIO_ECOL (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_ECRS (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_EMDC (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_EMDIO (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_ERXCK (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_ERXD0 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_ERXD1 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_ERXD2 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_ERXD3 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_ERXDV (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_ERXERR (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_ETXCK (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_ETXD0 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_ETXD1 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_ETXD2 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_ETXD3 (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_ETXEN (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_ETXERR (PIO_PERIPH2 | PIO_PORT_PIOA | PIO_PIN16) + +/* External PIO interrupts */ + +#define PIO_EINT0 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN0) +#define PIO_EINT1 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN1) +#define PIO_EINT2 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN2) +#define PIO_EINT3 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN3) +#define PIO_EINT4 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN4) +#define PIO_EINT5 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN5) +#define PIO_EINT6 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_EINT7 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_EINT8 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_EINT9 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_EINT10 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_EINT11 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN11) +#define PIO_EINT12 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN12) +#define PIO_EINT13 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN13) +#define PIO_EINT14 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_EINT15 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN15) +#define PIO_EINT16 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN16) +#define PIO_EINT17 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_EINT18 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_EINT19 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN19) +#define PIO_EINT20 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN20) +#define PIO_EINT21 (PIO_EINT | PIO_PORT_PIOH | PIO_PIN21) +#define PIO_EINT22 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN10) +#define PIO_EINT23 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN11) +#define PIO_EINT24 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN12) +#define PIO_EINT25 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN13) +#define PIO_EINT26 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN14) +#define PIO_EINT27 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN15) +#define PIO_EINT28 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN16) +#define PIO_EINT29 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN17) +#define PIO_EINT30 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN18) +#define PIO_EINT31 (PIO_EINT | PIO_PORT_PIOI | PIO_PIN19) + +/* I2C */ + +#define PIO_HSCL (PIO_PERIPH4 | PIO_PORT_PIOI | PIO_PIN20) +#define PIO_HSDA (PIO_PERIPH4 | PIO_PORT_PIOI | PIO_PIN21) + +/* I2S */ + +#define PIO_I2S_BCLK (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_I2S_DI (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_I2S_DO0 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_I2S_DO1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_I2S_DO2 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_I2S_DO3 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_I2S_LRCK (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_I2S_MCLK (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN5) + +/* IR Interface */ + +#define PIO_IR0_RX (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_IR0_TX (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN3) + +#define PIO_IR1_RX (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_IR1_TX (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN22) + +/* JTAG */ + +#define PIO_JTAG_CK0 (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_JTAG_CK1 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN5) +#define PIO_JTAG_DI0 (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_JTAG_DI1 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN1) +#define PIO_JTAG_DO0 (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_JTAG_DO1 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN3) +#define PIO_JTAG_MS0 (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_JTAG_MS1 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN0) + +/* Keypad */ + +#define PIO_KP_IN0 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_KP_IN1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_KP_IN2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_KP_IN3 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN11) +#define PIO_KP_IN4 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_KP_IN5 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN15) +#define PIO_KP_IN6 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN16) +#define PIO_KP_IN7 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_KP_OUT0 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_KP_OUT1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN19) +#define PIO_KP_OUT2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN22) +#define PIO_KP_OUT3 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN23) +#define PIO_KP_OUT4 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN24) +#define PIO_KP_OUT5 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN25) +#define PIO_KP_OUT6 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN26) +#define PIO_KP_OUT7 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN27) + +/* LCD */ + +#define PIO_LCD0_CLK (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_LCD0_D0 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_LCD0_D1 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN1) +#define PIO_LCD0_D2 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN2) +#define PIO_LCD0_D3 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_LCD0_D4 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_LCD0_D5 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_LCD0_D6 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_LCD0_D7 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_LCD0_D8 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_LCD0_D9 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_LCD0_D10 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_LCD0_D11 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_LCD0_D12 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_LCD0_D13 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_LCD0_D14 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_LCD0_D15 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_LCD0_D16 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_LCD0_D17 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_LCD0_D18 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_LCD0_D19 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_LCD0_D20 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_LCD0_D21 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_LCD0_D22 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_LCD0_D23 (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_LCD0_DE (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN25) +#define PIO_LCD0_HSYNC (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_LCD0_VSYNC (PIO_PERIPH2 | PIO_PORT_PIOD | PIO_PIN27) + +#define PIO_LCD1_CLK (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN24) +#define PIO_LCD1_D0_1 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN0) +#define PIO_LCD1_D0_2 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN1) +#define PIO_LCD1_D2 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN2) +#define PIO_LCD1_D3 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN3) +#define PIO_LCD1_D4 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN4) +#define PIO_LCD1_D5 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN5) +#define PIO_LCD1_D6 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_LCD1_D7 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_LCD1_D8 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_LCD1_D9 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_LCD1_D10 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_LCD1_D11 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN11) +#define PIO_LCD1_D12 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN12) +#define PIO_LCD1_D13 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN13) +#define PIO_LCD1_D14 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_LCD1_D15 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN15) +#define PIO_LCD1_D16 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN16) +#define PIO_LCD1_D17 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_LCD1_D18 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_LCD1_D19 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN19) +#define PIO_LCD1_D20 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN20) +#define PIO_LCD1_D21 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN21) +#define PIO_LCD1_D22 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN22) +#define PIO_LCD1_D23 (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN23) +#define PIO_LCD1_DE (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN25) +#define PIO_LCD1_HSYNC (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN26) +#define PIO_LCD1_VSYNC (PIO_PERIPH2 | PIO_PORT_PIOH | PIO_PIN27) + +#define PIO_LVDS0_VM3 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_LVDS0_VN0 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN1) +#define PIO_LVDS0_VN1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_LVDS0_VN2 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_LVDS0_VNC (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_LVDS0_VP0 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_LVDS0_VP1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN2) +#define PIO_LVDS0_VP2 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_LVDS0_VP3 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_LVDS0_VPC (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN6) + +/* LCD/TV Timing Controller */ + +#define PIO_LVDS1_VN (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_LVDS1_VN0 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_LVDS1_VN2 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_LVDS1_VN3 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_LVDS1_VNC (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_LVDS1_VP0 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_LVDS1_VP1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_LVDS1_VP2 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_LVDS1_VP3 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_LVDS1_VPC (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN16) + +/* Memory Stick Controller (MSC) */ + +#define PIO_MS_BS (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_MS_CLK (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_MS_D0 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN8) +#define PIO_MS_D1 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN9) +#define PIO_MS_D2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN10) +#define PIO_MS_D3 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN11) + +/* NAND */ + +#define PIO_NALE (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_NC (PIO_PERIPH3 | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_NCE0 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_NCE1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_NCE2 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_NCE3 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_NCE4 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_NCE5 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_NCE6 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_NCE7 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_NCLE (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_NDQ0 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_NDQ1 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_NDQ2 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_NDQ3 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_NDQ4 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_NDQ5 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_NDQ6 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_NDQ7 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_NDQS (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_NRB0 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_NRB1 (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_NRE (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_NWE (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_NWP (PIO_PERIPH2 | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_PS2_SCK (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN20) + +/* PS2 */ + +#define PIO_PS2_SCK1_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN14) +#define PIO_PS2_SCK1_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN12) +#define PIO_PS2_SDA0 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN21) +#define PIO_PS2_SDA1_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN15) +#define PIO_PS2_SDA1_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN13) + +/* PWM */ + +#define PIO_PWM0 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_PWM1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN3) + +/* SD/MMC Card Interface */ + +#define PIO_SDC0_CLK (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN2) +#define PIO_SDC0_CMD (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN3) +#define PIO_SDC0_D0 (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN1) +#define PIO_SDC0_D1 (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN0) +#define PIO_SDC0_D2 (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN5) +#define PIO_SDC0_D3 (PIO_PERIPH2 | PIO_PORT_PIOF | PIO_PIN4) + +#define PIO_SDC1_CLK (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN1) +#define PIO_SDC1_CLK (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN23) +#define PIO_SDC1_CMD (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN0) +#define PIO_SDC1_CMD (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN22) +#define PIO_SDC1_D0_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN2) +#define PIO_SDC1_D0_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN24) +#define PIO_SDC1_D1_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN3) +#define PIO_SDC1_D1_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN25) +#define PIO_SDC1_D2_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN4) +#define PIO_SDC1_D2_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN26) +#define PIO_SDC1_D3_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN5) +#define PIO_SDC1_D3_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN27) + +#define PIO_SDC2_CLK (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_SDC2_CMD (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_SDC2_D0 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_SDC2_D1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_SDC2_D2 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_SDC2_D3 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN11) + +#define PIO_SDC3_CLK (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN5) +#define PIO_SDC3_CMD (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN4) +#define PIO_SDC3_D0 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN6) +#define PIO_SDC3_D1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN7) +#define PIO_SDC3_D2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN8) +#define PIO_SDC3_D3 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN9) + +/* SMC */ + +#define PIO_SMC_DET (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_SMC_RST_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN25) +#define PIO_SMC_RST_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN13) +#define PIO_SMC_SCK_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_SMC_SCK_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN18) +#define PIO_SMC_SDA_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN27) +#define PIO_SMC_SDA_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN19) + +#define PIO_SMC_VCCEN_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_SMC_VCCEN_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN17) +#define PIO_SMC_VPPEN_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_SMC_VPPEN_2 (PIO_PERIPH4 | PIO_PORT_PIOE | PIO_PIN5) +#define PIO_SMC_VPPEN_3 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN14) +#define PIO_SMC_VPPPP_1 (PIO_PERIPH3 | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_SMC_VPPPP_2 (PIO_PERIPH5 | PIO_PORT_PIOH | PIO_PIN15) + +/* SPI */ + +#define PIO_SPI0_CLK_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_SPI0_CLK_2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN11) +#define PIO_SPI0_CS0_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_SPI0_CS0_2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN10) +#define PIO_SPI0_CS1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN14) +#define PIO_SPI0_MISO_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_SPI0_MISO_2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN13) +#define PIO_SPI0_MOSI_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_SPI0_MOSI_2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN12) + +#define PIO_SPI1_CLK_1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN17) +#define PIO_SPI1_CLK_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_SPI1_CS0_1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN16) +#define PIO_SPI1_CS0_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_SPI1_CS1_1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_SPI1_CS1_2 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN15) +#define PIO_SPI1_MISO_1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN19) +#define PIO_SPI1_MISO_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_SPI1_MOSI_1 (PIO_PERIPH2 | PIO_PORT_PIOI | PIO_PIN18) +#define PIO_SPI1_MOSI_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN2) + +#define PIO_SPI2_CLK_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_SPI2_CLK_2 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_SPI2_CS0_1 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_SPI2_CS0_2 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_SPI2_CS1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_SPI2_MISO_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_SPI2_MISO_2 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_SPI2_MOSI_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_SPI2_MOSI_2 (PIO_PERIPH3 | PIO_PORT_PIOC | PIO_PIN21) + +#define PIO_SPI3_CLK (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_SPI3_CS0 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_SPI3_CS1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_SPI3_MISO (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_SPI3_MOSI (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN7) + +/* ? */ + +#define PIO_STANBYWFI (PIO_PERIPH4 | PIO_PORT_PIOB | PIO_PIN3) + +/* ? */ + +#define PIO_TCLKIN0 (PIO_PERIPH4 | PIO_PORT_PIOI | PIO_PIN14) +#define PIO_TCLKIN1 (PIO_PERIPH4 | PIO_PORT_PIOI | PIO_PIN15) + +/* Touchscreen */ + +#define PIO_TS0_CLK (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_TS0_D0 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN4) +#define PIO_TS0_D1 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN5) +#define PIO_TS0_D2 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN6) +#define PIO_TS0_D3 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN7) +#define PIO_TS0_D4 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN8) +#define PIO_TS0_D5 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN9) +#define PIO_TS0_D6 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN10) +#define PIO_TS0_D7 (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN11) +#define PIO_TS0_DVLD (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN3) +#define PIO_TS0_ERR (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN1) +#define PIO_TS0_SYNC (PIO_PERIPH2 | PIO_PORT_PIOE | PIO_PIN2) + +#define PIO_TS1_CLK (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN0) +#define PIO_TS1_D0 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN4) +#define PIO_TS1_D1 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN5) +#define PIO_TS1_D2 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN6) +#define PIO_TS1_D3 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN7) +#define PIO_TS1_D4 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN8) +#define PIO_TS1_D5 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN9) +#define PIO_TS1_D6 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN10) +#define PIO_TS1_D7 (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN11) +#define PIO_TS1_DVLD (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN3) +#define PIO_TS1_ERR (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN1) +#define PIO_TS1_SYNC (PIO_PERIPH2 | PIO_PORT_PIOG | PIO_PIN2) + +/* TWI */ + +#define PIO_TWI0_SCK_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_TWI0_SDA_2 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_TWI1_SCK_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_TWI1_SDA_2 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN19) + +#define PIO_TWI2_SCK (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_TWI2_SDA (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN21) + +/* UARTs */ + +#define PIO_UART0_RX_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_UART0_RX_2 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN4) +#define PIO_UART0_TX_1 (PIO_PERIPH2 | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_UART0_TX_2 (PIO_PERIPH4 | PIO_PORT_PIOF | PIO_PIN2) + +#define PIO_UART1_CTS (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_UART1_DCD (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_UART1_DSR (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_UART1_DTR (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_UART1_RING (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_UART1_RTS (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_UART1_RX (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_UART1_TX (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN10) + +#define PIO_UART2_CTS_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN17) +#define PIO_UART2_CTS_2 (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_UART2_RTS_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN16) +#define PIO_UART2_RTS_2 (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_UART2_RX_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN19) +#define PIO_UART2_RX_2 (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_UART2_TX_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN18) +#define PIO_UART2_TX_2 (PIO_PERIPH4 | PIO_PORT_PIOA | PIO_PIN2) + +#define PIO_UART3_CTS_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN9) +#define PIO_UART3_CTS_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN3) +#define PIO_UART3_RTS_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN8) +#define PIO_UART3_RTS_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN2) +#define PIO_UART3_RX_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN7) +#define PIO_UART3_RX_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN1) +#define PIO_UART3_TX_1 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN6) +#define PIO_UART3_TX_2 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN0) + +#define PIO_UART4_RX_1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN5) +#define PIO_UART4_RX_2 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN11) +#define PIO_UART4_TX_1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN4) +#define PIO_UART4_TX_2 (PIO_PERIPH4 | PIO_PORT_PIOG | PIO_PIN10) + +#define PIO_UART5_RX_1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN7) +#define PIO_UART5_RX_2 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN11) +#define PIO_UART5_TX_1 (PIO_PERIPH4 | PIO_PORT_PIOH | PIO_PIN6) +#define PIO_UART5_TX_2 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN10) + +#define PIO_UART6_RX_1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_UART6_RX_2 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN13) +#define PIO_UART6_TX_1 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_UART6_TX_2 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN12) + +#define PIO_UART7_RX_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN21) +#define PIO_UART7_RX_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_UART7_TX_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN20) +#define PIO_UART7_TX_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN14) + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H */ diff --git a/arch/arm/src/a1x/chip/a1x_intc.h b/arch/arm/src/a1x/chip/a1x_intc.h new file mode 100644 index 0000000000000000000000000000000000000000..86bdc911c88a77fe858b4e46ca27a0307b0216d1 --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_intc.h @@ -0,0 +1,206 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_intc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define A1X_INTC_VECTOR_OFFSET 0x0000 /* Interrupt Vector */ +#define A1X_INTC_BASEADDR_OFFSET 0x0004 /* Interrupt Base Address */ +#define A1X_INTC_PROTECT_OFFSET 0x0008 /* Interrupt Protection Register */ +#define A1X_INTC_NMICTRL_OFFSET 0x000c /* Interrupt Control */ + +#define A1X_INTC_IRQ_PEND_OFFSET(n) (0x0010 + (((n) >> 3) & ~3)) +#define A1X_INTC_IRQ_PEND0_OFFSET 0x0010 /* Interrupt IRQ Pending 0 Status */ +#define A1X_INTC_IRQ_PEND1_OFFSET 0x0014 /* Interrupt IRQ Pending 1 Status */ +#define A1X_INTC_IRQ_PEND2_OFFSET 0x0018 /* Interrupt IRQ Pending 2 Status */ + +#define A1X_INTC_FIQ_PEND_OFFSET(n) (0x0020 + (((n) >> 3) & ~3)) +#define A1X_INTC_FIQ_PEND0_OFFSET 0x0020 /* Interrupt FIQ Pending 0 Status */ +#define A1X_INTC_FIQ_PEND1_OFFSET 0x0024 /* Interrupt FIQ Pending 1 Status */ +#define A1X_INTC_FIQ_PEND2_OFFSET 0x0028 /* Interrupt FIQ Pending 2 Status */ + +#define A1X_INTC_FIRQ_SEL_OFFSET(n) (0x0030 + (((n) >> 3) & ~3)) +#define A1X_INTC_IRQ_SEL0_OFFSET 0x0030 /* Interrupt Select 0 */ +#define A1X_INTC_IRQ_SEL1_OFFSET 0x0034 /* Interrupt Select 1 */ +#define A1X_INTC_IRQ_SEL2_OFFSET 0x0038 /* Interrupt Select 2 */ + +#define A1X_INTC_EN_OFFSET(n) (0x0040 + (((n) >> 3) & ~3)) +#define A1X_INTC_EN0_OFFSET 0x0040 /* Interrupt Enable 0 */ +#define A1X_INTC_EN1_OFFSET 0x0044 /* Interrupt Enable 1 */ +#define A1X_INTC_EN2_OFFSET 0x0048 /* Interrupt Enable 2 */ + +#define A1X_INTC_MASK_OFFSET(n) (0x0050 + (((n) >> 3) & ~3)) +#define A1X_INTC_MASK0_OFFSET 0x0050 /* Interrupt Mask 0 */ +#define A1X_INTC_MASK1_OFFSET 0x0054 /* Interrupt Mask 1 */ +#define A1X_INTC_MASK2_OFFSET 0x0058 /* Interrupt Mask 2 */ + +#define A1X_INTC_RESP_OFFSET(n) (0x0060 + (((n) >> 3) & ~3)) +#define A1X_INTC_RESP0_OFFSET 0x0060 /* Interrupt Response 0 */ +#define A1X_INTC_RESP1_OFFSET 0x0064 /* Interrupt Response 1 */ +#define A1X_INTC_RESP2_OFFSET 0x0068 /* Interrupt Response 2 */ + +#define A1X_INTC_FF_OFFSET(n) (0x0070 + (((n) >> 3) & ~3)) +#define A1X_INTC_FF0_OFFSET 0x0070 /* Interrupt Fast Forcing 0 */ +#define A1X_INTC_FF1_OFFSET 0x0074 /* Interrupt Fast Forcing 1 */ +#define A1X_INTC_FF2_OFFSET 0x0078 /* Interrupt Fast Forcing 2 */ + +#define A1X_INTC_PRIO_OFFSET(n) (0x0080 + (((n) >> 2) & ~3)) +#define A1X_INTC_PRIO0_OFFSET 0x0080 /* Interrupt Source Priority 0 */ +#define A1X_INTC_PRIO1_OFFSET 0x0084 /* Interrupt Source Priority 1 */ +#define A1X_INTC_PRIO2_OFFSET 0x0088 /* Interrupt Source Priority 2 */ +#define A1X_INTC_PRIO3_OFFSET 0x008c /* Interrupt Source Priority 3 */ +#define A1X_INTC_PRIO4_OFFSET 0x0090 /* Interrupt Source Priority 4 */ + +/* Register virtual addresses *******************************************************/ + +#define A1X_INTC_VECTOR (A1X_INTC_VADDR+A1X_INTC_VECTOR_OFFSET) +#define A1X_INTC_BASEADDR (A1X_INTC_VADDR+A1X_INTC_BASEADDR_OFFSET) +#define A1X_INTC_PROTECT (A1X_INTC_VADDR+A1X_INTC_PROTECT_OFFSET) +#define A1X_INTC_NMICTRL (A1X_INTC_VADDR+A1X_INTC_NMICTRL_OFFSET) + +#define A1X_INTC_IRQ_PEND(n) (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND_OFFSET(n)) +#define A1X_INTC_IRQ_PEND0 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND0_OFFSET) +#define A1X_INTC_IRQ_PEND1 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND1_OFFSET) +#define A1X_INTC_IRQ_PEND2 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND2_OFFSET) + +#define A1X_INTC_FIQ_PEND(n) (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND_OFFSET(n)) +#define A1X_INTC_FIQ_PEND0 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND0_OFFSET) +#define A1X_INTC_FIQ_PEND1 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND1_OFFSET) +#define A1X_INTC_FIQ_PEND2 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND2_OFFSET) + +#define A1X_INTC_IRQ_SEL(n) (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL_OFFSET(n)) +#define A1X_INTC_IRQ_SEL0 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL0_OFFSET) +#define A1X_INTC_IRQ_SEL1 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL1_OFFSET) +#define A1X_INTC_IRQ_SEL2 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL2_OFFSET) + +#define A1X_INTC_EN(n) (A1X_INTC_VADDR+A1X_INTC_EN_OFFSET(n)) +#define A1X_INTC_EN0 (A1X_INTC_VADDR+A1X_INTC_EN0_OFFSET) +#define A1X_INTC_EN1 (A1X_INTC_VADDR+A1X_INTC_EN1_OFFSET) +#define A1X_INTC_EN2 (A1X_INTC_VADDR+A1X_INTC_EN2_OFFSET) + +#define A1X_INTC_MASK(n) (A1X_INTC_VADDR+A1X_INTC_MASK_OFFSET(n)) +#define A1X_INTC_MASK0 (A1X_INTC_VADDR+A1X_INTC_MASK0_OFFSET) +#define A1X_INTC_MASK1 (A1X_INTC_VADDR+A1X_INTC_MASK1_OFFSET) +#define A1X_INTC_MASK2 (A1X_INTC_VADDR+A1X_INTC_MASK2_OFFSET) + +#define A1X_INTC_RESP(n) (A1X_INTC_VADDR+A1X_INTC_RESP_OFFSET(n)) +#define A1X_INTC_RESP0 (A1X_INTC_VADDR+A1X_INTC_RESP0_OFFSET) +#define A1X_INTC_RESP1 (A1X_INTC_VADDR+A1X_INTC_RESP1_OFFSET) +#define A1X_INTC_RESP2 (A1X_INTC_VADDR+A1X_INTC_RESP2_OFFSET) + +#define A1X_INTC_FF(n) (A1X_INTC_VADDR+A1X_INTC_FF_OFFSET(n)) +#define A1X_INTC_FF0 (A1X_INTC_VADDR+A1X_INTC_FF0_OFFSET) +#define A1X_INTC_FF1 (A1X_INTC_VADDR+A1X_INTC_FF1_OFFSET) +#define A1X_INTC_FF2 (A1X_INTC_VADDR+A1X_INTC_FF2_OFFSET) + +#define A1X_INTC_PRIO(n) (A1X_INTC_VADDR+A1X_INTC_PRIO_OFFSET(n)) +#define A1X_INTC_PRIO0 (A1X_INTC_VADDR+A1X_INTC_PRIO0_OFFSET) +#define A1X_INTC_PRIO1 (A1X_INTC_VADDR+A1X_INTC_PRIO1_OFFSET) +#define A1X_INTC_PRIO2 (A1X_INTC_VADDR+A1X_INTC_PRIO2_OFFSET) +#define A1X_INTC_PRIO3 (A1X_INTC_VADDR+A1X_INTC_PRIO3_OFFSET) +#define A1X_INTC_PRIO4 (A1X_INTC_VADDR+A1X_INTC_PRIO4_OFFSET) + +/* Register bit field definitions ***************************************************/ + +/* Interrupt Vector */ + +#define INTC_VECTOR_MASK 0xfffffffc /* Bits 2-31: Vector address */ + +/* Interrupt Base Address */ + +#define INTC_BASEADDR_MASK 0xfffffffc /* Bits 2-31: Base address */ + +/* Interrupt Control */ + +#define INTC_PROTECT_PROTEN (1 << 0) /* Bit 0: Enabled protected register access */ + +/* Interrupt Control */ + +#define INTC_NMICTRL_SRCTYPE_SHIFT (0) /* Bits 0-1: External NMI Interrupt Source Type */ +#define INTC_NMICTRL_SRCTYPE_MASK (3 << INTC_NMICTRL_SRCTYPE_SHIFT) +# define INTC_NMICTRL_SRCTYPE_LOW (0 << INTC_NMICTRL_SRCTYPE_SHIFT) /* Low level sensitive */ +# define INTC_NMICTRL_SRCTYPE_NEDGE (1 << INTC_NMICTRL_SRCTYPE_SHIFT) /* Negative edge trigged */ + +/* Interrupt IRQ Pending 0-2 Status */ + +#define INTC_IRQ_PEND(n) (1 << ((n) & 0x1f)) /* n=0-95: Interrupt pending */ + +/* Interrupt FIQ Pending 0-2 Status */ + +#define INTC_FIQ_PEND(n) (1 << ((n) & 0x1f)) /* n=0-95: Interrupt pending */ + +/* Interrupt Select 0-2 */ + +#define INTC_IRQ_SEL(n) (1 << ((n) & 0x1f)) /* n=0-95: FIQ (vs IRQ) */ + +/* Interrupt Enable 0-2 */ + +#define INTC_EN(n) (1 << ((n) & 0x1f)) /* n=0-95: Interrupt enable */ + +/* Interrupt Mask 0-2 */ + +#define INTC_MASK(n) (1 << ((n) & 0x1f)) /* n=0-95: Interrupt mask */ + +/* Interrupt Response 0-2 */ + +#define INTC_RESP(n) (1 << ((n) & 0x1f)) /* n=0-95: Interrupt level mask */ + +/* Interrupt Fast Forcing 0-2 */ + +#define INTC_FF(n) (1 << ((n) & 0x1f)) /* n=0-95: Enable fast forcing feature */ + +/* Interrupt Source Priority 0-4 */ + +#define INTC_PRIO_MIN 0 +#define INTC_PRIO_MAX 3 + +#define INTC_PRIO_SHIFT(n) (((n) & 15) << 1) /* n=0-95: Priority level */ +#define INTC_PRIO_MASK(n) (3 << INTC_PRIO_SHIFT(n)) +# define INTC_PRIO(n,p) ((uint32_t)(p) << INTC_PRIO_SHIFT(n)) + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H */ diff --git a/arch/arm/src/a1x/chip/a1x_memorymap.h b/arch/arm/src/a1x/chip/a1x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..154a1641ba4e0b44bf2c2b3945763a6d76471c6f --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_memorymap.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_ARCH_CHIP_A10) +# include "chip/a10_memorymap.h" +#else +# error Unrecognized A1X architecture +#endif + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H */ diff --git a/arch/arm/src/a1x/chip/a1x_pio.h b/arch/arm/src/a1x/chip/a1x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..48cc2bd9d78154526fdd0f5f0bec5fa683b52daf --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_pio.h @@ -0,0 +1,220 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_pio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define PIO_REG_PORTA 0 +#define PIO_REG_PORTB 1 +#define PIO_REG_PORTC 2 +#define PIO_REG_PORTD 3 +#define PIO_REG_PORTE 4 +#define PIO_REG_PORTF 5 +#define PIO_REG_PORTG 6 +#define PIO_REG_PORTH 7 +#define PIO_REG_PORTI 8 +#define PIO_REG_PORTS 9 + +#define PIO_REG_CFG_INPUT 0 +#define PIO_REG_CFG_OUTPUT 1 + +#define PIO_REG_DRV_LEVEL0 0 +#define PIO_REG_DRV_LEVEL1 1 +#define PIO_REG_DRV_LEVEL2 2 +#define PIO_REG_DRV_LEVEL3 3 + +#define PIO_REG_PULL_NONE 0 +#define PIO_REG_PULL_UP 1 +#define PIO_REG_PULL_DOWN 2 + +#define PIO_REG_INT_POSEDGE 0 +#define PIO_REG_INT_NEGEDGE 1 +#define PIO_REG_INT_HILEVEL 2 +#define PIO_REG_INT_LOWLEVEL 3 +#define PIO_REG_INT_BOTHEDGES 4 + +/* Register offsets *****************************************************************/ + +#define A1X_PIO_CFG0_OFFSET(n) (0x0000 + (n)*0x24) /* Port Configure Register 0, n=0-9 */ +#define A1X_PIO_CFG1_OFFSET(n) (0x0004 + (n)*0x24) /* Port Configure Register 1, n=0-9 */ +#define A1X_PIO_CFG2_OFFSET(n) (0x0008 + (n)*0x24) /* Port Configure Register 2, n=0-9 */ +#define A1X_PIO_CFG3_OFFSET(n) (0x000c + (n)*0x24) /* Port Configure Register 3, n=0-9 */ +#define A1X_PIO_DAT_OFFSET(n) (0x0010 + (n)*0x24) /* Port Data Register, n=0-9 */ +#define A1X_PIO_DRV0_OFFSET(n) (0x0014 + (n)*0x24) /* Port Multi-Driving Register 0, n=0-9 */ +#define A1X_PIO_DRV1_OFFSET(n) (0x0018 + (n)*0x24) /* Port Multi-Driving Register 1, n=0-9 */ +#define A1X_PIO_PUL0_OFFSET(n) (0x001c + (n)*0x24) /* Port Pull Register 0, n=0-9 */ +#define A1X_PIO_PUL1_OFFSET(n) (0x0020 + (n)*0x24) /* Port Pull Register 1, n=0-9 */ +#define A1X_PIO_INT_CFG0_OFFSET 0x0200 /* PIO Interrupt Configure Register 0 */ +#define A1X_PIO_INT_CFG1_OFFSET 0x0204 /* PIO Interrupt Configure Register 1 */ +#define A1X_PIO_INT_CFG2_OFFSET 0x0208 /* PIO Interrupt Configure Register 2 */ +#define A1X_PIO_INT_CFG3_OFFSET 0x020c /* PIO Interrupt Configure Register 3 */ +#define A1X_PIO_INT_CTL_OFFSET 0x0210 /* PIO Interrupt Control Register */ +#define A1X_PIO_INT_STA_OFFSET 0x0214 /* PIO Interrupt Status Register */ +#define A1X_PIO_INT_DEB_OFFSET 0x0218 /* PIO Interrupt Debounce Register */ +#define A1X_SDR_PAD_DRV_OFFSET 0x0220 /* SDRAM Pad Multi-Driving Register */ +#define A1X_SDR_PAD_PUL_OFFSET 0x0224 /* SDRAM Pad Pull Register */ + +/* Register virtual addresses *******************************************************/ + +#define A1X_PIO_CFG0(n) (A1X_PIO_VADDR+A1X_PIO_CFG0_OFFSET(n)) +#define A1X_PIO_CFG1(n) (A1X_PIO_VADDR+A1X_PIO_CFG1_OFFSET(n)) +#define A1X_PIO_CFG2(n) (A1X_PIO_VADDR+A1X_PIO_CFG2_OFFSET(n)) +#define A1X_PIO_CFG3(n) (A1X_PIO_VADDR+A1X_PIO_CFG3_OFFSET(n)) +#define A1X_PIO_DAT(n) (A1X_PIO_VADDR+A1X_PIO_DAT_OFFSET(n)) +#define A1X_PIO_DRV0(n) (A1X_PIO_VADDR+A1X_PIO_DRV0_OFFSET(n)) +#define A1X_PIO_DRV1(n) (A1X_PIO_VADDR+A1X_PIO_DRV1_OFFSET(n)) +#define A1X_PIO_PUL0(n) (A1X_PIO_VADDR+A1X_PIO_PUL0_OFFSET(n)) +#define A1X_PIO_PUL1(n) (A1X_PIO_VADDR+A1X_PIO_PUL1_OFFSET(n)) +#define A1X_PIO_INT_CFG0 (A1X_PIO_VADDR+A1X_PIO_INT_CFG0_OFFSET) +#define A1X_PIO_INT_CFG1 (A1X_PIO_VADDR+A1X_PIO_INT_CFG1_OFFSET) +#define A1X_PIO_INT_CFG2 (A1X_PIO_VADDR+A1X_PIO_INT_CFG2_OFFSET) +#define A1X_PIO_INT_CFG3 (A1X_PIO_VADDR+A1X_PIO_INT_CFG3_OFFSET) +#define A1X_PIO_INT_CTL (A1X_PIO_VADDR+A1X_PIO_INT_CTL_OFFSET) +#define A1X_PIO_INT_STA (A1X_PIO_VADDR+A1X_PIO_INT_STA_OFFSET) +#define A1X_PIO_INT_DEB (A1X_PIO_VADDR+A1X_PIO_INT_DEB_OFFSET) +#define A1X_SDR_PAD_DRV (A1X_PIO_VADDR+A1X_SDR_PAD_DRV_OFFSET) +#define A1X_SDR_PAD_PUL (A1X_PIO_VADDR+A1X_SDR_PAD_PUL_OFFSET) + +/* Register bit field definitions ***************************************************/ + +/* Port Configure Register 0, n=0-7 */ + +#define PIO_CFG0_SHIFT(n) ((n) << 2) +#define PIO_CFG0_MASK(n)) (7 << PIO_CFG0_SHIFT(n)) +# define PIO_CFG0(m,v) ((uint32_t)(v) << PIO_CFG0_SHIFT(n)) + +/* Port Configure Register 1, n=8-15 */ + +#define PIO_CFG1_SHIFT(n) (((n) - 8) << 2) +#define PIO_CFG1_MASK(n)) (7 << PIO_CFG1_SHIFT(n)) +# define PIO_CFG1(m,v) ((uint32_t)(v) << PIO_CFG1_SHIFT(n)) + +/* Port Configure Register 2, n=16-23 */ + +#define PIO_CFG2_SHIFT(n) (((n) - 16) << 2) +#define PIO_CFG2_MASK(n)) (7 << PIO_CFG2_SHIFT(n)) +# define PIO_CFG2(m,v) ((uint32_t)(v) << PIO_CFG2_SHIFT(n)) + +/* Port Configure Register 3, n=24-31 */ + +#define PIO_CFG3_SHIFT(n) (((n) - 24) << 2) +#define PIO_CFG3_MASK(n)) (7 << PIO_CFG3_SHIFT(n)) +# define PIO_CFG3(m,v) ((uint32_t)(v) << PIO_CFG3_SHIFT(n)) + +/* Port n Data Register, n=0-9 */ + +#define PIO_DAT(n) (1 << (n)) /* PA data, n=0-31 */ + +/* Port n Multi-Driving Register 0, n=0-9 */ + +#define PIO_DRV0_SHIFT(n) ((n) << 1) /* PA DRV0, n=0-15 */ +#define PIO_DRV0_MASK(n) (3 << PIO_DRV0_SHIFT(n)) +# define PIO_DRV0(n,v) ((uint32_t)(v) << PIO_DRV0_SHIFT(n)) + +/* Port n Multi-Driving Register 1, n=0-9 */ + +#define PIO_DRV1_SHIFT(n) (((n) - 16) << 1) /* PA DRV1, n=16-31 */ +#define PIO_DRV1_MASK(n) (3 << PIO_DRV1_SHIFT(n)) +# define PIO_DRV1(n,v) ((uint32_t)(v) << PIO_DRV1_SHIFT(n)) + +/* Port n Pull Register 0, n=0-9 */ + +#define PIO_PUL0_SHIFT(n) ((n) << 1) /* PA PUL0, n=0-15 */ +#define PIO_PUL0_MASK(n) (3 << PIO_PUL0_SHIFT(n)) +# define PIO_PUL0(n,v) ((uint32_t)(v) << PIO_PUL0_SHIFT(n)) + +/* Port n Pull Register 1, n=0-9 */ + +#define PIO_PUL1_SHIFT(n) (((n) - 16) << 1) /* PA PUL1, n=16-31 */ +#define PIO_PUL1_MASK(n) (3 << PIO_PUL1_SHIFT(n)) +# define PIO_PUL1(n,v) ((uint32_t)(v) << PIO_PUL1_SHIFT(n)) + +/* PIO Interrupt Configure Register 0 */ + +#define PIO_INT_CFG0_SHIFT(n) ((n) << 2) +#define PIO_INT_CFG0_MASK(n)) (15 << PIO_INT_CFG0_SHIFT(n)) +# define PIO_INT_CFG0(m,v) ((uint32_t)(v) << PIO_INT_CFG0_SHIFT(n)) + +/* PIO Interrupt Configure Register 1 */ + +#define PIO_INT_CFG1_SHIFT(n) (((n) - 8) << 2) +#define PIO_INT_CFG1_MASK(n)) (15 << PIO_INT_CFG1_SHIFT(n)) +# define PIO_INT_CFG1(m,v) ((uint32_t)(v) << PIO_INT_CFG1_SHIFT(n)) + +/* PIO Interrupt Configure Register 2 */ + +#define PIO_INT_CFG2_SHIFT(n) (((n) - 16) << 2) +#define PIO_INT_CFG2_MASK(n)) (15 << PIO_INT_CFG2_SHIFT(n)) +# define PIO_INT_CFG2(m,v) ((uint32_t)(v) << PIO_INT_CFG2_SHIFT(n)) + +/* PIO Interrupt Configure Register 3 */ + +#define PIO_INT_CFG3_SHIFT(n) (((n) - 24) << 2) +#define PIO_INT_CFG3_MASK(n)) (15 << PIO_INT_CFG3_SHIFT(n)) +# define PIO_INT_CFG3(m,v) ((uint32_t)(v) << PIO_INT_CFG3_SHIFT(n)) + +/* PIO Interrupt Control Register */ + +#define PIO_INT_CTL(n) (1 << (n)) + +/* PIO Interrupt Status Register */ + +#define PIO_INT_STA(n) (1 << (n)) + +/* PIO Interrupt Debounce Register */ + +#define PIO_INT_DEB_CLKSEL (1 << 0) /* Bit 0: PIO Interrupt Clock Select */ +#define PIO_INT_DEB_CLKPRESC_SHIFT (4) /* Bit 4-6: Debounce Clock Pre-scale */ +#define PIO_INT_DEB_CLKPRESC_MASK (7 << PIO_INT_DEB_CLKPRESC_SHIFT) +# define PIO_INT_DEB_CLKPRESC(n) ((uint32_t)(n) << PIO_INT_DEB_CLKPRESC_SHIFT) + +/* SDRAM Pad Multi-Driving Register */ +/* REVISIT: Missing register bit definitions */ + +/* SDRAM Pad Pull Register */ +/* REVISIT: Missing register bit definitions */ + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H */ diff --git a/arch/arm/src/a1x/chip/a1x_piocfg.h b/arch/arm/src/a1x/chip/a1x_piocfg.h new file mode 100644 index 0000000000000000000000000000000000000000..019eebf778dbb98b3a04f4d3388673970cf413bb --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_piocfg.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_piocfg.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_ARCH_CHIP_A10) +# include "chip/a10_piocfg.h" +#else +# error Unrecognized A1X architecture +#endif + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H */ diff --git a/arch/arm/src/a1x/chip/a1x_timer.h b/arch/arm/src/a1x/chip/a1x_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..afe3603057dd45dee35054acb9d6756aa6491387 --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_timer.h @@ -0,0 +1,379 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_timer.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define A1X_TMR_IRQ_EN_OFFSET 0x0000 /* Timer IRQ Enable */ +#define A1X_TMR_IRQ_STA_OFFSET 0x0004 /* Timer Status */ + +#define A1X_TMR_OFFSET(n) (0x0010 + ((n) << 4)) +#define A1X_TMR_CTRL_OFFSET 0x0000 /* Timer Control */ +#define A1X_TMR_INTV_VALUE_OFFSET 0x0004 /* Timer Interval Value */ +#define A1X_TMR_CUR_VALUE_OFFSET 0x0008 /* Timer Current Value */ + +#define A1X_TMR0_CTRL_OFFSET 0x0010 /* Timer 0 Control */ +#define A1X_TMR0_INTV_VALUE_OFFSET 0x0014 /* Timer 0 Interval Value */ +#define A1X_TMR0_CUR_VALUE_OFFSET 0x0018 /* Timer 0 Current Value */ + +#define A1X_TMR1_CTRL_OFFSET 0x0020 /* Timer 1 Control */ +#define A1X_TMR1_INTV_VALUE_OFFSET 0x0024 /* Timer 1 Interval Value */ +#define A1X_TMR1_CUR_VALUE_OFFSET 0x0028 /* Timer 1 Current Value */ + +#define A1X_TMR2_CTRL_OFFSET 0x0030 /* Timer 2 Control */ +#define A1X_TMR2_INTV_VALUE_OFFSET 0x0034 /* Timer 2 Interval Value */ +#define A1X_TMR2_CUR_VALUE_OFFSET 0x0038 /* Timer 2 Current Value */ + +#define A1X_TMR3_CTRL_OFFSET 0x0040 /* Timer 3 Control */ +#define A1X_TMR3_INTV_VALUE_OFFSET 0x0044 /* Timer 3 Interval Value */ + +#define A1X_TMR4_CTRL_OFFSET 0x0050 /* Timer 4 Control */ +#define A1X_TMR4_INTV_VALUE_OFFSET 0x0054 /* Timer 4 Interval Value */ +#define A1X_TMR4_CUR_VALUE_OFFSET 0x0058 /* Timer 4 Current Value */ + +#define A1X_TMR5_CTRL_OFFSET 0x0060 /* Timer 5 Control */ +#define A1X_TMR5_INTV_VALUE_OFFSET 0x0064 /* Timer 5 Interval Value */ +#define A1X_TMR5_CUR_VALUE_OFFSET 0x0068 /* Timer 5 Current Value */ + +#define A1X_AVS_CNT_CTL_OFFSET 0x0080 /* AVS Control Register */ +#define A1X_AVS_CNT0_OFFSET 0x0084 /* AVS Counter 0 Register */ +#define A1X_AVS_CNT1_OFFSET 0x0088 /* AVS Counter 1 Register */ +#define A1X_AVS_CNT_DIV_OFFSET 0x008c /* AVS Divisor */ + +#define A1X_WDOG_CTRL_OFFSET 0x0090 /* Watchdog Control */ +#define A1X_WDOG_MODE_OFFSET 0x0094 /* Watchdog Mode */ + +#define A1X_CNT64_CTRL_OFFSET 0x00a0 /* 64-bit Counter control */ +#define A1X_CNT64_LO_OFFSET 0x00a4 /* 64-bit Counter low */ +#define A1X_CNT64_HI_OFFSET 0x00a8 /* 64-bit Counter high */ + +#define A1X_LOSC_CTRL_OFFSET 0x0100 /* Low Oscillator Control */ + +#define A1X_RTC_YMD_OFFSET 0x0104 /* RTC Year-Month-Day */ +#define A1X_RTC_HMS_OFFSET 0x0108 /* RTC Hour-Minute-Second */ +#define A1X_ALRAM_DD_HMS_OFFSET 0x010c /* Alarm Day-Hour-Minute-Second */ +#define A1X_ALARM_WK_HMS_OFFSET 0x0110 /* Alarm Week HMS */ +#define A1X_ALARM_EN_OFFSET 0x0114 /* Alarm Enable */ +#define A1X_ALARM_IRQ_EN_OFFSET 0x0118 /* Alarm IRQ Enable */ +#define A1X_ALARM_IRQ_STA_OFFSET 0x011c /* Alarm IRQ Status */ + +#define A1X_TMR_GP_DATA0_OFFSET 0x0120 /* Timer general purpose register 0 */ +#define A1X_TMR_GP_DATA1_OFFSET 0x0124 /* Timer general purpose register 1 */ +#define A1X_TMR_GP_DATA2_OFFSET 0x0128 /* Timer general purpose register 2 */ +#define A1X_TMR_GP_DATA3_OFFSET 0x012c /* Timer general purpose register 3 */ + +#define A1X_CPU_CFG_OFFSET 0x0140 /* CPU configuration register */ + +/* Register virtual addresses *******************************************************/ + +#define A1X_TMR_IRQ_EN (A1X_TIMER_VADDR+A1X_TMR_IRQ_EN_OFFSET) +#define A1X_TMR_IRQ_STA (A1X_TIMER_VADDR+A1X_TMR_IRQ_STA_OFFSET) + +#define A1X_TMR(n) (A1X_TIMER_VADDR+A1X_TMR_OFFSET(n)) +#define A1X_TMR_CTRL (A1X_TIMER_VADDR+A1X_TMR_CTRL_OFFSET) +#define A1X_TMR_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR_INTV_VALUE_OFFSET) +#define A1X_TMR_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR_CUR_VALUE_OFFSET) + +#define A1X_TMR0_CTRL (A1X_TIMER_VADDR+A1X_TMR0_CTRL_OFFSET) +#define A1X_TMR0_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR0_INTV_VALUE_OFFSET) +#define A1X_TMR0_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR0_CUR_VALUE_OFFSET) + +#define A1X_TMR1_CTRL (A1X_TIMER_VADDR+A1X_TMR1_CTRL_OFFSET) +#define A1X_TMR1_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR1_INTV_VALUE_OFFSET) +#define A1X_TMR1_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR1_CUR_VALUE_OFFSET) + +#define A1X_TMR2_CTRL (A1X_TIMER_VADDR+A1X_TMR2_CTRL_OFFSET) +#define A1X_TMR2_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR2_INTV_VALUE_OFFSET) +#define A1X_TMR2_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR2_CUR_VALUE_OFFSET) + +#define A1X_TMR3_CTRL (A1X_TIMER_VADDR+A1X_TMR3_CTRL_OFFSET) +#define A1X_TMR3_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR3_INTV_VALUE_OFFSET) + +#define A1X_TMR4_CTRL (A1X_TIMER_VADDR+A1X_TMR4_CTRL_OFFSET) +#define A1X_TMR4_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR4_INTV_VALUE_OFFSET) +#define A1X_TMR4_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR4_CUR_VALUE_OFFSET) + +#define A1X_TMR5_CTRL (A1X_TIMER_VADDR+A1X_TMR5_CTRL_OFFSET) +#define A1X_TMR5_INTV_VALUE (A1X_TIMER_VADDR+A1X_TMR5_INTV_VALUE_OFFSET) +#define A1X_TMR5_CUR_VALUE (A1X_TIMER_VADDR+A1X_TMR5_CUR_VALUE_OFFSET) + +#define A1X_AVS_CNT_CTL (A1X_TIMER_VADDR+A1X_AVS_CNT_CTL_OFFSET) +#define A1X_AVS_CNT0 (A1X_TIMER_VADDR+A1X_AVS_CNT0_OFFSET) +#define A1X_AVS_CNT1 (A1X_TIMER_VADDR+A1X_AVS_CNT1_OFFSET) +#define A1X_AVS_CNT_DIV (A1X_TIMER_VADDR+A1X_AVS_CNT_DIV_OFFSET) + +#define A1X_WDOG_CTRL (A1X_TIMER_VADDR+A1X_WDOG_CTRL_OFFSET) +#define A1X_WDOG_MODE (A1X_TIMER_VADDR+A1X_WDOG_MODE_OFFSET) + +#define A1X_CNT64_CTRL (A1X_TIMER_VADDR+A1X_CNT64_CTRL_OFFSET) +#define A1X_CNT64_LO (A1X_TIMER_VADDR+A1X_CNT64_LO_OFFSET) +#define A1X_CNT64_HI (A1X_TIMER_VADDR+A1X_CNT64_HI_OFFSET) + +#define A1X_LOSC_CTRL (A1X_TIMER_VADDR+A1X_LOSC_CTRL_OFFSET) + +#define A1X_RTC_YMD (A1X_TIMER_VADDR+A1X_RTC_YMD_OFFSET) +#define A1X_RTC_HMS (A1X_TIMER_VADDR+A1X_RTC_HMS_OFFSET) +#define A1X_ALRAM_DD_HMS (A1X_TIMER_VADDR+A1X_ALRAM_DD_HMS_OFFSET) +#define A1X_ALARM_WK_HMS (A1X_TIMER_VADDR+A1X_ALARM_WK_HMS_OFFSET) +#define A1X_ALARM_EN (A1X_TIMER_VADDR+A1X_ALARM_EN_OFFSET) +#define A1X_ALARM_IRQ_EN (A1X_TIMER_VADDR+A1X_ALARM_IRQ_EN_OFFSET) +#define A1X_ALARM_IRQ_STA (A1X_TIMER_VADDR+A1X_ALARM_IRQ_STA_OFFSET) + +#define A1X_TMR_GP_DATA0 (A1X_TIMER_VADDR+A1X_TMR_GP_DATA0_OFFSET) +#define A1X_TMR_GP_DATA1 (A1X_TIMER_VADDR+A1X_TMR_GP_DATA1_OFFSET) +#define A1X_TMR_GP_DATA2 (A1X_TIMER_VADDR+A1X_TMR_GP_DATA2_OFFSET) +#define A1X_TMR_GP_DATA3 (A1X_TIMER_VADDR+A1X_TMR_GP_DATA3_OFFSET) + +#define A1X_CPU_CFG (A1X_TIMER_VADDR+A1X_CPU_CFG_OFFSET) + +/* Register bit field definitions ***************************************************/ + +/* Timer IRQ Enable and Timer Status */ + +#define TMR_IRQ_TMR0 (1 << 0) /* Bit 0: Timer 0 Interrupt */ +#define TMR_IRQ_TMR1 (1 << 1) /* Bit 1: Timer 1 Interrupt */ +#define TMR_IRQ_TMR2 (1 << 2) /* Bit 2: Timer 2 Interrupt */ +#define TMR_IRQ_TMR3 (1 << 3) /* Bit 3: Timer 3 Interrupt */ +#define TMR_IRQ_TMR4 (1 << 4) /* Bit 4: Timer 4 Interrupt */ +#define TMR_IRQ_TMR5 (1 << 5) /* Bit 5: Timer 5 Interrupt */ +#define TMR_IRQ_WDOG (1 << 8) /* Bit 8: Watchdog Interrupt */ + +/* Timer 0-2,/4-5 Control */ + +#define TMR_CTRL_EN (1 << 0) /* Bit 0: Timer n Enable, n={0,1,2,3,4,5} */ +#define TMR_CTRL_RELOAD (1 << 1) /* Bit 1: Timer n Reload, n={0,1,2,4,5} */ +#define TMR_CTRL_SRC_SHIFT (2) /* Bits 2-3: Timer n Clock Source, n={0,1,2,4,5} */ +#define TMR_CTRL_SRC_MASK (3 << TMR_CTRL_SRC_SHIFT) +# define TMR_CTRL_SRC_LOSC (0 << TMR_CTRL_SRC_SHIFT) /* Low speed OSC */ +# define TMR_CTRL_SRC_OSC24M (1 << TMR_CTRL_SRC_SHIFT) /* OSC24M */ +# define TMR01_CTRL_SRC_PLL6DIV6 (2 << TMR_CTRL_SRC_SHIFT) /* PLL6/6 (Timers 0 and 1 only) */ +# define TMR4_CTRL_SRC_CLKIN0 (2 << TMR_CTRL_SRC_SHIFT) /* External CLKIN0 (Timer 4 only) */ +# define TMR5_CTRL_SRC_CLKIN1 (2 << TMR_CTRL_SRC_SHIFT) /* External CLKIN1 (Timer 5 only) */ +#define TMR_CTRL_CLK_PRES_SHIFT (4) /* Bits 4-6: Select the pre-scale of timer n clock source */ +#define TMR_CTRL_CLK_PRES_MASK (7 << TMR_CTRL_CLK_PRES_SHIFT) +# define TMR_CTRL_CLK_PRES_DIV1 (0 << TMR_CTRL_CLK_PRES_SHIFT) /* /1 */ +# define TMR_CTRL_CLK_PRES_DIV2 (1 << TMR_CTRL_CLK_PRES_SHIFT) /* /2 */ +# define TMR_CTRL_CLK_PRES_DIV4 (2 << TMR_CTRL_CLK_PRES_SHIFT) /* /4 */ +# define TMR_CTRL_CLK_PRES_DIV8 (3 << TMR_CTRL_CLK_PRES_SHIFT) /* /8 */ +# define TMR_CTRL_CLK_PRES_DIV16 (4 << TMR_CTRL_CLK_PRES_SHIFT) /* /16 (Not Timer 0) */ +# define TMR_CTRL_CLK_PRES_DIV32 (5 << TMR_CTRL_CLK_PRES_SHIFT) /* /32 (Not Timer 0) */ +# define TMR_CTRL_CLK_PRES_DIV64 (6 << TMR_CTRL_CLK_PRES_SHIFT) /* /64 (Not Timer 0) */ +# define TMR_CTRL_CLK_PRES_DIV128 (7 << TMR_CTRL_CLK_PRES_SHIFT) /* /128 (Not Timer 0) */ +#define TMR_CTRL_MODE (1 << 7) /* Bit 7: Timer n mode, n={0,1,2,4,5} */ +# define TMR_CTRL_MODE_SINGLE (1 << 7) /* 1=single mode */ +# define TMR_CTRL_MODE_CONTINUOUS (0 << 7) /* 0=continuous mode */ + +/* Timer 3 Control */ + +#define TMR3_CTRL_EN (1 << 0) /* Bit 0: Timer 3 Enable*/ +#define TMR3_CTRL_CLK_PRES_SHIFT (2) /* Bits 2-3: Select the pre-scale of timer 3 clock source (LOSC) */ +#define TMR3_CTRL_CLK_PRES_MASK (7 << TMR3_CTRL_CLK_PRES_SHIFT) +# define TMR3_CTRL_CLK_PRES_DIV16 (0 << TMR3_CTRL_CLK_PRES_SHIFT) /* /16 */ +# define TMR3_CTRL_CLK_PRES_DIV32 (1 << TMR3_CTRL_CLK_PRES_SHIFT) /* /32 */ +# define TMR3_CTRL_CLK_PRES_DIV64 (2 << TMR3_CTRL_CLK_PRES_SHIFT) /* /64 */ +#define TMR3_CTRL_MODE (1 << 4) /* Bit 4: Timer3 mode */ + +/* Timer Interval Value (32-bit value) */ +/* Timer Current Value (32-bit value) */ + +/* AVS Control Register */ + +#define AVS_CNT0_EN (1 << 0) /* Bit 0: Audio/Video Sync Counter 1 Enable/ Disable (OSC24M) */ +#define AVS_CNT1_EN (1 << 1) /* Bit 1: Audio/Video Sync Counter 1 Enable/ Disable (OSC24M) */ +#define AVS_CNT0_PS (1 << 8) /* Bit 8: Audio/Video Sync Counter 0 Pause Control */ +#define AVS_CNT1_PS (1 << 9) /* Bit 9: Audio/Video Sync Counter 1 Pause Control */ + +/* AVS Counter 0 Register (32-bit value) */ +/* AVS Counter 1 Register (32-bit value) */ + +/* AVS Divisor */ + +#define AVS_CNT0_D_SHIFT (0) /* Bits 0-11: Divisor N for AVS Counter 0 */ +#define AVS_CNT0_D_MASK (0xfff << AVS_CNT0_D_SHIFT) +# define AVS_CNT0_D(n) ((uint32_t)(n) << AVS_CNT0_D_SHIFT) +#define AVS_CNT1_D_SHIFT (16) /* Bits 16-27: Divisor N for AVS Counter 1 */ +#define AVS_CNT1_D_MASK (0xfff << AVS_CNT1_D_SHIFT) +# define AVS_CNT1_D(n) ((uint32_t)(n) << AVS_CNT1_D_SHIFT) + +/* Watchdog Control */ + +#define WDOG_CTRL_RSTART (1 << 0) /* Bit 0: Watch-Dog Restart */ + +/* Watchdog Mode */ + +#define WDOG_MODE_EN (1 << 0) /* Bit 0: Watch-Dog Enable */ +#define WDOG_MODE_RSTEN (1 << 1) /* Bit 1: Watch-Dog Reset Enable */ +#define WDOG_MODE_INTV_SHIFT (3) /* Bits 3-6: Watch-Dog Interval Value */ +#define WDOG_MODE_INTV_MASK (15 << WDOG_MODE_INTV_SHIFT) +# define WDOG_MODE_INTV_0p5SEC (0 << WDOG_MODE_INTV_SHIFT) /* 0.5 sec */ +# define WDOG_MODE_INTV_1SEc (1 << WDOG_MODE_INTV_SHIFT) /* 1 sec */ +# define WDOG_MODE_INTV_2SEC (2 << WDOG_MODE_INTV_SHIFT) /* 2 sec */ +# define WDOG_MODE_INTV_3SEC (3 << WDOG_MODE_INTV_SHIFT) /* 3 sec */ +# define WDOG_MODE_INTV_4SEC (4 << WDOG_MODE_INTV_SHIFT) /* 4 sec */ +# define WDOG_MODE_INTV_5SEC (5 << WDOG_MODE_INTV_SHIFT) /* 5 sec */ +# define WDOG_MODE_INTV_6SEC (6 << WDOG_MODE_INTV_SHIFT) /* 6 sec */ +# define WDOG_MODE_INTV_8SEC (7 << WDOG_MODE_INTV_SHIFT) /* 8 sec */ +# define WDOG_MODE_INTV_10SEC (8 << WDOG_MODE_INTV_SHIFT) /* 10 sec */ +# define WDOG_MODE_INTV_12SEC (9 << WDOG_MODE_INTV_SHIFT) /* 12 sec */ +# define WDOG_MODE_INTV_14SEC (10 << WDOG_MODE_INTV_SHIFT) /* 14 sec */ +# define WDOG_MODE_INTV_16SEC (11 << WDOG_MODE_INTV_SHIFT) /* 16 sec */ + +/* 64-bit Counter control */ + +#define CNT64_CTRL_CLREN (1 << 0) /* Bit 0: 64-bit Counter Clear Enable */ +#define CNT64_CTRL_RLEN (1 << 1) /* Bit 1: 64-bit Counter Read Latch Enable */ +#define CNT64_CTRL_SRCSEL_MASK (1 << 2) /* Bit 2: 64-bit Counter Clock Source Select */ +# define CNT64_CTRL_SRC_OSC24M (0 << 2) /* 0=OSC24M */ +# define CNT64_CTRL_SRC_PLL6DIV6 (1 << 2) /* 1=PLL6/6 */ + +/* 64-bit Counter low (32-bit value) */ +/* 64-bit Counter high (32-bit value) */ + +/* Low Oscillator Control */ + +#define LOSC_CTRL_OSC32K_SRCSEL (1 << 0) /* Bit 0: OSC32KHz Clock source Select */ +#define LOSC_CTRL_EXT_GSM_SHIFT (2) /* Bits 2-3: External 32768Hz Crystal GSM */ +#define LOSC_CTRL_EXT_GSM_MASK (3 << LOSC_CTRL_EXT_GSM_SHIFT) +# define LOSC_CTRL_EXT_GSM_LOW (0 << LOSC_CTRL_EXT_GSM_SHIFT) +# define LOSC_CTRL_EXT_GSM_MEDLOW (1 << LOSC_CTRL_EXT_GSM_SHIFT) +# define LOSC_CTRL_EXT_GSM_MEDHI (2 << LOSC_CTRL_EXT_GSM_SHIFT) +# define LOSC_CTRL_EXT_GSM_HIGH (3 << LOSC_CTRL_EXT_GSM_SHIFT) +#define LOSC_CTRL_RTC_YMD_ACCE (1 << 7) /* Bit 7: RTC YY-MM-DD access */ +#define LOSC_CTRL_RTC_HMS_ACCE (1 << 8) /* Bit 8: RTC HH-MM-SS access */ +#define LOSC_CTRL_ALM_DHMS_ACCE (1 << 9) /* Bit 9: ALARM DD-HH-MM-SS access */ +#define LOSC_CTRL_CLK32K_AUTOSWE (1 << 14) /* Bit 14: CLK32K auto switch enable */ +#define LOSC_CTRL_CLK32K_AUTOSWP (1 << 15) /* Bit 15: CLK32K auto switch pending */ + +/* RTC Year-Month-Day */ + +#define RTC_YMD_DAY_SHIFT (0) /* Bits 0-4: Day (1-31) */ +#define RTC_YMD_DAY_MASK (0x1f << RTC_YMD_DAY_SHIFT) +# define RTC_YMD_DAY(n) ((uint32_t)(n) << RTC_YMD_DAY_SHIFT) +#define RTC_YMD_MONTH_SHIFT (8) /* Bit 8-11: Month (1-12) */ +#define RTC_YMD_MONTH_MASK (15 << RTC_YMD_MONTH_SHIFT) +# define RTC_YMD_MONTH(n) ((uint32_t)(n) << RTC_YMD_MONTH_SHIFT) +#define RTC_YMD_YEAR_SHIFT (16) /* Bit 16-21: Year (0-63) */ +#define RTC_YMD_YEAR_MASK (0x3f << RTC_YMD_YEAR_SHIFT) +# define RTC_YMD_YEAR(n) ((uint32_t)(n) << RTC_YMD_YEAR_SHIFT) +#define RTC_YMD_LEAP (1 << 22) /* Bit 22: Leap Year */ +#define RTC_YMD_SIMCTRL (1 << 30) /* Bit 30: RTC Simulation Control bit */ +#define RTC_YMD_TESTMODECTRL (1 << 31) /* Bit 31: RTC TEST Mode Control bit */ + +/* RTC Hour-Minute-Second */ + +#define RTC_HMS_SECOND_SHIFT (0) /* Bits 0-5: Second (0-59) */ +#define RTC_HMS_SECOND_MASK (0x3f << RTC_HMS_SECOND_SHIFT) +# define RTC_HMS_SECOND(n) ((uint32_t)(n) << RTC_HMS_SECOND_SHIFT) +#define RTC_HMS_MINUTE_SHIFT (8) /* Bits 8-13: Minute (0-59) */ +#define RTC_HMS_MINUTE_MASK (0x3f << RTC_HMS_MINUTE_SHIFT) +# define RTC_HMS_MINUTE(n) ((uint32_t)(n) << RTC_HMS_MINUTE_SHIFT) +#define RTC_HMS_HOUR_SHIFT (16) /* Bits 16-20: Hour (0-23) */ +#define RTC_HMS_HOUR_MASK (0x1f << RTC_HMS_HOUR_SHIFT) +# define RTC_HMS_HOUR(n) ((uint32_t)(n) << RTC_HMS_HOUR_SHIFT) +#define RTC_HMS_WKNO_SHIFT (29) /* Bits 29-31: Week number */ +#define RTC_HMS_WKNO_MASK (7 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO(n) ((uint32_t)(n) << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_MONDAY (0 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_TUESDAY (1 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_WEDNESDAY (2 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_THURSDAY (3 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_FRIDAY (4 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_SATURDAY (5 << RTC_HMS_WKNO_SHIFT) +# define RTC_HMS_WKNO_SUNDAY (6 << RTC_HMS_WKNO_SHIFT) + +/* Alarm Day-Hour-Minute-Second */ + +#define ALRAM_DD_HMS_SECOND_SHIFT (0) /* Bits 8-13: Second (0-59) */ +#define ALRAM_DD_HMS_SECOND_MASK (0x3f << ALRAM_DD_HMS_SECOND_SHIFT) +# define ALRAM_DD_HMS_SECOND(n) ((uint32_t)(n) << ALRAM_DD_HMS_SECOND_SHIFT) +#define ALRAM_DD_HMS_MINUTE_SHIFT (8) /* Bits 8-13: Minute (0-59) */ +#define ALRAM_DD_HMS_MINUTE_MASK (0x3f << ALRAM_DD_HMS_MINUTE_SHIFT) +# define ALRAM_DD_HMS_MINUTE(n) ((uint32_t)(n) << ALRAM_DD_HMS_MINUTE_SHIFT) +#define ALRAM_DD_HMS_HOUR_SHIFT (16) /* Bits 16-20: Hour (0-23) */ +#define ALRAM_DD_HMS_HOUR_MASK (0x1f << ALRAM_DD_HMS_HOUR_SHIFT) +# define ALRAM_DD_HMS_HOUR(n) ((uint32_t)(n) << ALRAM_DD_HMS_HOUR_SHIFT) +#define ALRAM_DD_HMS_DAY_SHIFT (24) /* Bits 24-31: Day (0-255) */ +#define ALRAM_DD_HMS_DAY_MASK (0xff << ALRAM_DD_HMS_DAY_SHIFT) +# define ALRAM_DD_HMS_DAY(n) ((uint32_t)(n) << ALRAM_DD_HMS_DAY_SHIFT) + +/* Alarm Week HMS */ + +#define ALARM_WK_HMS_SECOND_SHIFT (0) /* Bits 0-5: Seconds (0-59) */ +#define ALARM_WK_HMS_SECOND_MASK (0x3f << ALARM_WK_HMS_SECOND_SHIFT) +# define ALARM_WK_HMS_SECOND(n) ((uint32_t)(n) << ALARM_WK_HMS_SECOND_SHIFT) +#define ALARM_WK_HMS_MINUTE_SHIFT (8) /* Bits 8-13: Minutes (0-59) */ +#define ALARM_WK_HMS_MINUTE_MASK (0x3f << ALARM_WK_HMS_MINUTE_SHIFT) +# define ALARM_WK_HMS_MINUTE(n) ((uint32_t)(n) << ALARM_WK_HMS_MINUTE_SHIFT) +#define ALARM_WK_HMS_HOUR_SHIFT (16) /* Bits 16-20: Hours (0-23) */ +#define ALARM_WK_HMS_HOUR_MASK (0x1f << ALARM_WK_HMS_HOUR_SHIFT) +# define ALARM_WK_HMS_HOUR(n) ((uint32_t)(n) << ALARM_WK_HMS_HOUR_SHIFT) + +/* Alarm Enable */ + +#define ALARM_EN_WK0EN (1 << 0) /* Bit 0: Week 0(Monday) Alarm Enable */ +#define ALARM_EN_WK1EN (1 << 1) /* Bit 1: Week 1(Tuesday) Alarm Enable */ +#define ALARM_EN_WK2EN (1 << 2) /* Bit 2: Week 2(Wednesday) Alarm Enable */ +#define ALARM_EN_WK3EN (1 << 3) /* Bit 3: Week 3(Thursday) Alarm Enable */ +#define ALARM_EN_WK4EN (1 << 4) /* Bit 4: Week 4(Friday) Alarm Enable */ +#define ALARM_EN_WK5EN (1 << 5) /* Bit 5: Week 5(Saturday) Alarm Enable */ +#define ALARM_EN_WK6EN (1 << 6) /* Bit 6: Week 6(Sunday) Alarm Enable */ +#define ALARM_EN_CNTEN (1 << 8) /* Bit 8: Alarm Counter Enable */ + +/* Alarm IRQ Enable and Alarm IRQ Status*/ + +#define ALARM_IRQ_CNT (1 << 0) /* Bit 0: Alarm Counter IRQ */ +#define ALARM_IRQ_WK (1 << 1) /* Bit 1: Alarm Week IRQ */ + +/* Timer general purpose register 0-3 (32-bit values) */ + +/* CPU configuration register */ + +#define CPU_CFG_L2DCACHE_INVEN (1 << 0) /* Bit 0: Enable L2 data cache invalidation at reset */ +#define CPU_CFG_L1DCACHE_INVAEN (1 << 1) /* Bit 1: Enable L1 data cache invalidation at reset */ + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H */ diff --git a/arch/arm/src/a1x/chip/a1x_uart.h b/arch/arm/src/a1x/chip/a1x_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..96f53a250567890aca38d4f024f9dee82070b664 --- /dev/null +++ b/arch/arm/src/a1x/chip/a1x_uart.h @@ -0,0 +1,360 @@ +/************************************************************************************ + * arch/arm/src/a1x/chip/a1x_uart.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H +#define __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/a1x_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define A1X_UART_RBR_OFFSET 0x0000 /* UART Receive Buffer Register */ +#define A1X_UART_THR_OFFSET 0x0000 /* UART Transmit Holding Register */ +#define A1X_UART_DLL_OFFSET 0x0000 /* UART Divisor Latch Low Register */ +#define A1X_UART_DLH_OFFSET 0x0004 /* UART Divisor Latch High Register */ +#define A1X_UART_IER_OFFSET 0x0004 /* UART Interrupt Enable Register */ +#define A1X_UART_IIR_OFFSET 0x0008 /* UART Interrupt Identity Register */ +#define A1X_UART_FCR_OFFSET 0x0008 /* UART FIFO Control Register */ +#define A1X_UART_LCR_OFFSET 0x000c /* UART Line Control Register */ +#define A1X_UART_MCR_OFFSET 0x0010 /* UART Modem Control Register */ +#define A1X_UART_LSR_OFFSET 0x0014 /* UART Line Status Register */ +#define A1X_UART_MSR_OFFSET 0x0018 /* UART Modem Status Register */ +#define A1X_UART_SCH_OFFSET 0x001c /* UART Scratch Register */ +#define A1X_UART_USR_OFFSET 0x007c /* UART Status Register */ +#define A1X_UART_TFL_OFFSET 0x0080 /* UART Transmit FIFO Level */ +#define A1X_UART_RFL_OFFSET 0x0084 /* UART Receive FIFO Level */ +#define A1X_UART_HALT_OFFSET 0x00a4 /* UART Halt TX Register */ + +/* Register virtual addresses *******************************************************/ + +#define A1X_UART_RBR(n) (A1X_UART_VADDR(n)+A1X_UART_RBR_OFFSET) +#define A1X_UART_THR(n) (A1X_UART_VADDR(n)+A1X_UART_THR_OFFSET) +#define A1X_UART_DLL(n) (A1X_UART_VADDR(n)+A1X_UART_DLL_OFFSET) +#define A1X_UART_DLH(n) (A1X_UART_VADDR(n)+A1X_UART_DLH_OFFSET) +#define A1X_UART_IER(n) (A1X_UART_VADDR(n)+A1X_UART_IER_OFFSET) +#define A1X_UART_IIR(n) (A1X_UART_VADDR(n)+A1X_UART_IIR_OFFSET) +#define A1X_UART_FCR(n) (A1X_UART_VADDR(n)+A1X_UART_FCR_OFFSET) +#define A1X_UART_LCR(n) (A1X_UART_VADDR(n)+A1X_UART_LCR_OFFSET) +#define A1X_UART_MCR(n) (A1X_UART_VADDR(n)+A1X_UART_MCR_OFFSET) +#define A1X_UART_LSR(n) (A1X_UART_VADDR(n)+A1X_UART_LSR_OFFSET) +#define A1X_UART_MSR(n) (A1X_UART_VADDR(n)+A1X_UART_MSR_OFFSET) +#define A1X_UART_SCH(n) (A1X_UART_VADDR(n)+A1X_UART_SCH_OFFSET) +#define A1X_UART_USR(n) (A1X_UART_VADDR(n)+A1X_UART_USR_OFFSET) +#define A1X_UART_TFL(n) (A1X_UART_VADDR(n)+A1X_UART_TFL_OFFSET) +#define A1X_UART_RFL(n) (A1X_UART_VADDR(n)+A1X_UART_RFL_OFFSET) +#define A1X_UART_HALT(n) (A1X_UART_VADDR(n)+A1X_UART_HALT_OFFSET) + +#define A1X_UART0_RBR (A1X_UART0_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART0_THR (A1X_UART0_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART0_DLL (A1X_UART0_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART0_DLH (A1X_UART0_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART0_IER (A1X_UART0_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART0_IIR (A1X_UART0_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART0_FCR (A1X_UART0_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART0_LCR (A1X_UART0_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART0_MCR (A1X_UART0_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART0_LSR (A1X_UART0_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART0_MSR (A1X_UART0_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART0_SCH (A1X_UART0_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART0_USR (A1X_UART0_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART0_TFL (A1X_UART0_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART0_RFL (A1X_UART0_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART0_HALT (A1X_UART0_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART1_RBR (A1X_UART1_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART1_THR (A1X_UART1_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART1_DLL (A1X_UART1_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART1_DLH (A1X_UART1_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART1_IER (A1X_UART1_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART1_IIR (A1X_UART1_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART1_FCR (A1X_UART1_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART1_LCR (A1X_UART1_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART1_MCR (A1X_UART1_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART1_LSR (A1X_UART1_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART1_MSR (A1X_UART1_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART1_SCH (A1X_UART1_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART1_USR (A1X_UART1_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART1_TFL (A1X_UART1_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART1_RFL (A1X_UART1_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART1_HALT (A1X_UART1_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART2_RBR (A1X_UART2_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART2_THR (A1X_UART2_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART2_DLL (A1X_UART2_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART2_DLH (A1X_UART2_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART2_IER (A1X_UART2_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART2_IIR (A1X_UART2_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART2_FCR (A1X_UART2_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART2_LCR (A1X_UART2_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART2_MCR (A1X_UART2_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART2_LSR (A1X_UART2_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART2_MSR (A1X_UART2_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART2_SCH (A1X_UART2_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART2_USR (A1X_UART2_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART2_TFL (A1X_UART2_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART2_RFL (A1X_UART2_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART2_HALT (A1X_UART2_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART3_RBR (A1X_UART3_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART3_THR (A1X_UART3_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART3_DLL (A1X_UART3_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART3_DLH (A1X_UART3_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART3_IER (A1X_UART3_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART3_IIR (A1X_UART3_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART3_FCR (A1X_UART3_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART3_LCR (A1X_UART3_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART3_MCR (A1X_UART3_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART3_LSR (A1X_UART3_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART3_MSR (A1X_UART3_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART3_SCH (A1X_UART3_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART3_USR (A1X_UART3_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART3_TFL (A1X_UART3_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART3_RFL (A1X_UART3_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART3_HALT (A1X_UART3_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART4_RBR (A1X_UART4_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART4_THR (A1X_UART4_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART4_DLL (A1X_UART4_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART4_DLH (A1X_UART4_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART4_IER (A1X_UART4_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART4_IIR (A1X_UART4_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART4_FCR (A1X_UART4_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART4_LCR (A1X_UART4_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART4_MCR (A1X_UART4_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART4_LSR (A1X_UART4_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART4_MSR (A1X_UART4_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART4_SCH (A1X_UART4_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART4_USR (A1X_UART4_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART4_TFL (A1X_UART4_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART4_RFL (A1X_UART4_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART4_HALT (A1X_UART4_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART5_RBR (A1X_UART5_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART5_THR (A1X_UART5_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART5_DLL (A1X_UART5_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART5_DLH (A1X_UART5_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART5_IER (A1X_UART5_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART5_IIR (A1X_UART5_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART5_FCR (A1X_UART5_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART5_LCR (A1X_UART5_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART5_MCR (A1X_UART5_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART5_LSR (A1X_UART5_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART5_MSR (A1X_UART5_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART5_SCH (A1X_UART5_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART5_USR (A1X_UART5_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART5_TFL (A1X_UART5_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART5_RFL (A1X_UART5_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART5_HALT (A1X_UART5_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART6_RBR (A1X_UART6_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART6_THR (A1X_UART6_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART6_DLL (A1X_UART6_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART6_DLH (A1X_UART6_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART6_IER (A1X_UART6_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART6_IIR (A1X_UART6_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART6_FCR (A1X_UART6_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART6_LCR (A1X_UART6_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART6_MCR (A1X_UART6_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART6_LSR (A1X_UART6_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART6_MSR (A1X_UART6_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART6_SCH (A1X_UART6_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART6_USR (A1X_UART6_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART6_TFL (A1X_UART6_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART6_RFL (A1X_UART6_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART6_HALT (A1X_UART6_VADDR+A1X_UART_HALT_OFFSET) + +#define A1X_UART7_RBR (A1X_UART7_VADDR+A1X_UART_RBR_OFFSET) +#define A1X_UART7_THR (A1X_UART7_VADDR+A1X_UART_THR_OFFSET) +#define A1X_UART7_DLL (A1X_UART7_VADDR+A1X_UART_DLL_OFFSET) +#define A1X_UART7_DLH (A1X_UART7_VADDR+A1X_UART_DLH_OFFSET) +#define A1X_UART7_IER (A1X_UART7_VADDR+A1X_UART_IER_OFFSET) +#define A1X_UART7_IIR (A1X_UART7_VADDR+A1X_UART_IIR_OFFSET) +#define A1X_UART7_FCR (A1X_UART7_VADDR+A1X_UART_FCR_OFFSET) +#define A1X_UART7_LCR (A1X_UART7_VADDR+A1X_UART_LCR_OFFSET) +#define A1X_UART7_MCR (A1X_UART7_VADDR+A1X_UART_MCR_OFFSET) +#define A1X_UART7_LSR (A1X_UART7_VADDR+A1X_UART_LSR_OFFSET) +#define A1X_UART7_MSR (A1X_UART7_VADDR+A1X_UART_MSR_OFFSET) +#define A1X_UART7_SCH (A1X_UART7_VADDR+A1X_UART_SCH_OFFSET) +#define A1X_UART7_USR (A1X_UART7_VADDR+A1X_UART_USR_OFFSET) +#define A1X_UART7_TFL (A1X_UART7_VADDR+A1X_UART_TFL_OFFSET) +#define A1X_UART7_RFL (A1X_UART7_VADDR+A1X_UART_RFL_OFFSET) +#define A1X_UART7_HALT (A1X_UART7_VADDR+A1X_UART_HALT_OFFSET) + +/* Register bit field definitions ***************************************************/ + +/* UART Receive Buffer Register */ + +#define UART_RBR_MASK 0x000000ff + +/* UART Transmit Holding Register */ + +#define UART_THR_MASK 0x000000ff + +/* UART Divisor Latch Low Register */ + +#define UART_DLL_MASK 0x000000ff + +/* UART Divisor Latch High Register */ + +#define UART_DLH_MASK 0x000000ff + +/* UART Interrupt Enable Register */ + +#define UART_IER_ERBFI (1 << 0) /* Bit 0: Enable Received Data Available Interrupt */ +#define UART_IER_ETBEI (1 << 1) /* Bit 1: Enable Transmit Holding Register Empty Interrupt */ +#define UART_IER_ELSI (1 << 2) /* Bit 2: Enable Receiver Line Status Interrupt */ +#define UART_IER_EDSSI (1 << 3) /* Bit 3: Enable Modem Status Interrupt */ +#define UART_IER_PTIME (1 << 7) /* Bit 7: Programmable THRE Interrupt Mode Enable */ +#define UART_IER_ALLIE 0x0000008f + +/* UART Interrupt Identity Register */ + +#define UART_IIR_IID_SHIFT (0) /* Bits: 0-3: Interrupt ID */ +#define UART_IIR_IID_MASK (15 << UART_IIR_IID_SHIFT) +# define UART_IIR_IID_MODEM (0 << UART_IIR_IID_SHIFT) /* Modem status */ +# define UART_IIR_IID_NONE (1 << UART_IIR_IID_SHIFT) /* No interrupt pending */ +# define UART_IIR_IID_TXEMPTY (2 << UART_IIR_IID_SHIFT) /* THR empty */ +# define UART_IIR_IID_RECV (4 << UART_IIR_IID_SHIFT) /* Received data available */ +# define UART_IIR_IID_LINESTATUS (6 << UART_IIR_IID_SHIFT) /* Receiver line status */ +# define UART_IIR_IID_BUSY (7 << UART_IIR_IID_SHIFT) /* Busy detect */ +# define UART_IIR_IID_TIMEOUT (12 << UART_IIR_IID_SHIFT) /* Character timeout */ +#define UART_IIR_FEFLAG_SHIFT (6) /* Bits 6-7: FIFOs Enable Flag */ +#define UART_IIR_FEFLAG_MASK (3 << UART_IIR_FEFLAG_SHIFT) +# define UART_IIR_FEFLAG_DISABLE (0 << UART_IIR_FEFLAG_SHIFT) +# define UART_IIR_FEFLAG_ENABLE (3 << UART_IIR_FEFLAG_SHIFT) + +/* UART FIFO Control Register */ + +#define UART_FCR_FIFOE (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RFIFOR (1 << 1) /* Bit 1: RCVR FIFO Reset */ +#define UART_FCR_XFIFOR (1 << 2) /* Bit 2: XMIT FIFO reset */ +#define UART_FCR_DMAM (1 << 3) /* Bit 3: DMA mode */ +#define UART_FCR_TFT_SHIFT (4) /* Bits 4-5: TX Empty Trigger */ +#define UART_FCR_TFT_MASK (3 << UART_FCR_TFT_SHIFT) +# define UART_FCR_TFT_EMPTY (0 << UART_FCR_TFT_SHIFT) /* FIFO empty */ +# define UART_FCR_TFT_TWO (1 << UART_FCR_TFT_SHIFT) /* 2 characters in the FIFO */ +# define UART_FCR_TFT_QUARTER (2 << UART_FCR_TFT_SHIFT) /* FIFO 1/4 full */ +# define UART_FCR_TFT_HALF (3 << UART_FCR_TFT_SHIFT) /* FIFO 1/2 full */ +#define UART_FCR_RT_SHIFT (6) /* Bits 6-7: RCVR Trigger */ +#define UART_FCR_RT_MASK (3 << UART_FCR_RT_SHIFT) +# define UART_FCR_RT_ONE (0 << UART_FCR_RT_SHIFT) /* 1 character in the FIFO */ +# define UART_FCR_RT_QUARTER (1 << UART_FCR_RT_SHIFT) /* FIFO 1/4 full */ +# define UART_FCR_RT_HALF (2 << UART_FCR_RT_SHIFT) /* FIFO 1/2 full */ +# define UART_FCR_RT_MINUS2 (3 << UART_FCR_RT_SHIFT) /* FIFO-2 less than full */ + +/* UART Line Control Register */ + +#define UART_LCR_DLS_SHIFT (0) /* Bits 0-1: Data Length Select */ +#define UART_LCR_DLS_MASK (3 << UART_LCR_DLS_SHIFT) +# define UART_LCR_DLS_5BITS (0 << UART_LCR_DLS_SHIFT) /* 5 bits */ +# define UART_LCR_DLS_6BITS (1 << UART_LCR_DLS_SHIFT) /* 6 bits */ +# define UART_LCR_DLS_7BITS (2 << UART_LCR_DLS_SHIFT) /* 7 bits */ +# define UART_LCR_DLS_8BITS (3 << UART_LCR_DLS_SHIFT) /* 8 bits */ +#define UART_LCR_STOP (1 << 2) /* Bit 2: Number of stop bits */ +#define UART_LCR_PEN (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_EPS (1 << 4) /* Bit 4: Even Parity Select */ +#define UART_LCR_BC (1 << 6) /* Bit 6: Break Control Bit */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit */ + +/* UART Modem Control Register */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: Data Terminal Ready */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Request to Send */ +#define UART_MCR_LOOP (1 << 4) /* Bit 4: Loop Back Mode */ +#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */ +#define UART_MCR_SIRE (1 << 6) /* Bit 6: SIR Mode Enable */ + +/* UART Line Status Register */ + +#define UART_LSR_DR (1 << 0) /* Bit 0: Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: TX Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_FIFOERR (1 << 7) /* Bit 7: RX Data Error in FIFO */ + +/* UART Modem Status Register */ + +#define UART_MSR_DCTS (1 << 0) /* Bit 0: Delta Clear to Send */ +#define UART_MSR_DDSR (1 << 1) /* Bit 1: Delta Data Set Ready */ +#define UART_MSR_TERI (1 << 2) /* Bit 2: Trailing Edge Ring Indicator */ +#define UART_MSR_DDCD (1 << 3) /* Bit 3: Delta Data Carrier Detect */ +#define UART_MSR_CTS (1 << 4) /* Bit 4: Line State of Clear To Send */ +#define UART_MSR_DSR (1 << 5) /* Bit 5: Line State of Data Set Ready */ +#define UART_MSR_RI (1 << 6) /* Bit 6: Line State of Ring Indicator */ +#define UART_MSR_DCD (1 << 7) /* Bit 7: Line State of Data Carrier Detect */ + +/* UART Scratch Register */ + +#define UART_SCH_MASK 0x000000ff + +/* UART Status Register */ + +#define UART_USR_BUSY (1 << 0) /* Bit 0: UART Busy Bit */ +#define UART_USR_TFNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define UART_USR_TFE (1 << 2) /* Bit 2: Transmit FIFO Empty */ +#define UART_USR_RFNE (1 << 3) /* Bit 3: Receive FIFO Not Empty */ +#define UART_USR_RFF (1 << 4) /* Bit 4: Receive FIFO Full */ + +/* UART Transmit FIFO Level */ + +#define UART_TFL_SHIFT (0) /* Bits 0-6: Transmit FIFO Level */ +#define UART_TFL_MASK (0x7f << UART_TFL_SHIFT) +# define UART_TFL(n) ((uint32_t)(n) << UART_TFL_SHIFT) + +/* UART Receive FIFO Level */ + +#define UART_RFL_SHIFT (0) /* Bits 0-6: Receive FIFO Level */ +#define UART_RFL_MASK (0x7f << UART_RFL_SHIFT) +# define UART_RFL(n) ((uint32_t)(n) << UART_RFL_SHIFT) + +/* UART Halt TX Register */ + +#define UART_HALT_HALT_TX (1 << 0) /* Bit 0: Halt TX */ +#define UART_HALT_SIR_TX_INVERT (1 << 4) /* Bit 4: SIR Transmit Pulse Polarity Invert */ +#define UART_HALT_SIR_RX_INVERT (1 << 5) /* Bit 5: SIR Receiver Pulse Polarity Invert */ + +#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H */ diff --git a/arch/arm/src/arm/Kconfig b/arch/arm/src/arm/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..53f0958b2e2fd339c6e8097b1a026599c69090c6 --- /dev/null +++ b/arch/arm/src/arm/Kconfig @@ -0,0 +1,58 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "ARM Configuration Options" + +choice + prompt "Toolchain Selection" + default ARM_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS + default ARM_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS + +config ARM_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + +config ARM_TOOLCHAIN_CODESOURCERYL + bool "CodeSourcery GNU toolchain under Linux" + depends on HOST_LINUX + ---help--- + For use with the GNU toolchain built with the NuttX buildroot package. + This tools may be arm-nuttx-eabi- or, if ARM_OABI_TOOLCHAIN is set, + arm-nuttx-elf-. + +config ARM_TOOLCHAIN_CODESOURCERYW + bool "CodeSourcery GNU toolchain under Windows" + depends on HOST_WINDOWS + +config ARM_TOOLCHAIN_DEVKITARM + bool "devkitARM GNU toolchain" + depends on HOST_WINDOWS + +config ARM_TOOLCHAIN_GNU_EABIL + bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARM_TOOLCHAIN_GNU_EABIW + bool "Generic GNU EABI toolchain under Windows" + depends on HOST_WINDOWS + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARM_TOOLCHAIN_GNU_OABI + bool "Generic GNU OABI toolchain" + ---help--- + This option should work for any GNU toolchain configured for arm-elf-. + +endchoice + +config ARM_OABI_TOOLCHAIN + bool "OABI (vs EABI)" + default n + depends on ARM_TOOLCHAIN_BUILDROOT + ---help--- + Most of the older buildroot toolchains are OABI and are named arm-nuttx-elf- vs. arm-nuttx-eabi- diff --git a/arch/arm/src/arm/Toolchain.defs b/arch/arm/src/arm/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..d713e92e5da94043d916cb3c598d4918467ebca0 --- /dev/null +++ b/arch/arm/src/arm/Toolchain.defs @@ -0,0 +1,162 @@ +############################################################################ +# arch/arm/src/armv/Toolchain.defs +# +# Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Handle old-style chip-specific toolchain names in the absence of +# a new-style toolchain specification, force the selection of a single +# toolchain and allow the selected toolchain to be overridden by a +# command-line selection. +# + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_BUILDROOT) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_CODESOURCERYL) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= CODESOURCERYL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_CODESOURCERYW) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= CODESOURCERYW +endif + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_DEVKITARM) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= DEVKITARM +endif + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_GNU_EABIL) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= GNU_EABIL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARM_TOOLCHAIN_GNU_EABIW) \ + ),y) + CONFIG_ARM_TOOLCHAIN ?= GNU_EABIW +endif + +# +# Supported toolchains +# +# TODO - It's likely that all of these toolchains now support the +# CortexM4. Since they are all GCC-based, we could almost +# certainly simplify this further. +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_ARM_TOOLCHAIN),BUILDROOT) +ifeq ($(CONFIG_ARM_OABI_TOOLCHAIN),y) + CROSSDEV ?= arm-nuttx-elf- + ARCROSSDEV ?= arm-nuttx-elf- +else + CROSSDEV ?= arm-nuttx-eabi- + ARCROSSDEV ?= arm-nuttx-eabi- +endif + MAXOPTIMIZATION ?= -Os +endif + +# CodeSourcery under Linux + +ifeq ($(CONFIG_ARM_TOOLCHAIN),CODESOURCERYL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -O2 +endif + +# CodeSourcery under Windows + +ifeq ($(CONFIG_ARM_TOOLCHAIN),CODESOURCERYW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -O2 + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# devkitARM under Windows + +ifeq ($(CONFIG_ARM_TOOLCHAIN),DEVKITARM) + CROSSDEV ?= arm-eabi- + ARCROSSDEV ?= arm-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_ARM_TOOLCHAIN),GNU_EABIL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os +endif + +# Generic GNU EABI toolchain under Windows + +ifeq ($(CONFIG_ARM_TOOLCHAIN),GNU_EABIW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif diff --git a/arch/arm/src/arm/arm.h b/arch/arm/src/arm/arm.h new file mode 100644 index 0000000000000000000000000000000000000000..81fe724be3067e01910d183be465fe70bd103a89 --- /dev/null +++ b/arch/arm/src/arm/arm.h @@ -0,0 +1,452 @@ +/************************************************************************************ + * arch/arm/src/arm/arm.h + * + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARM_H +#define __ARCH_ARM_SRC_COMMON_ARM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#undef CONFIG_ALIGNMENT_TRAP +#undef CONFIG_DCACHE_WRITETHROUGH +#undef CONFIG_CACHE_ROUND_ROBIN +#undef CONFIG_DCACHE_DISABLE +#undef CONFIG_ICACHE_DISABLE + +/* ARM9EJS **************************************************************************/ + +/* PSR bits */ + +#define MODE_MASK 0x0000001f /* Bits 0-4: Mode bits */ +# define USR26_MODE 0x00000000 /* 26-bit User mode */ +# define FIQ26_MODE 0x00000001 /* 26-bit FIQ mode */ +# define IRQ26_MODE 0x00000002 /* 26-bit IRQ mode */ +# define SVC26_MODE 0x00000003 /* 26-bit Supervisor mode */ +# define MODE32_BIT 0x00000010 /* Bit 4: 32-bit mode */ +# define USR_MODE 0x00000010 /* 32-bit User mode */ +# define FIQ_MODE 0x00000011 /* 32-bit FIQ mode */ +# define IRQ_MODE 0x00000012 /* 32-bit IRQ mode */ +# define SVC_MODE 0x00000013 /* 32-bit Supervisor mode */ +# define ABT_MODE 0x00000017 /* 32-bit Abort mode */ +# define UND_MODE 0x0000001b /* 32-bit Undefined mode */ +# define SYSTEM_MODE 0x0000001f /* 32-bit System mode */ +#define PSR_T_BIT 0x00000020 /* Bit 5: Thumb state */ +#define PSR_F_BIT 0x00000040 /* Bit 6: FIQ disable */ +#define PSR_I_BIT 0x00000080 /* Bit 7: IRQ disable */ + /* Bits 8-23: Reserved */ +#define PSR_J_BIT 0x01000000 /* Bit 24: Jazelle state bit */ + /* Bits 25-26: Reserved */ +#define PSR_Q_BIT 0x08000000 /* Bit 27: Sticky overflow */ +#define PSR_V_BIT 0x10000000 /* Bit 28: Overflow */ +#define PSR_C_BIT 0x20000000 /* Bit 29: Carry/Borrow/Extend */ +#define PSR_Z_BIT 0x40000000 /* Bit 30: Zero */ +#define PSR_N_BIT 0x80000000 /* Bit 31: Negative/Less than */ + +/* CR1 bits (CP#15 CR1) */ + +#define CR_M 0x00000001 /* MMU enable */ +#define CR_A 0x00000002 /* Alignment abort enable */ +#define CR_C 0x00000004 /* Dcache enable */ +#define CR_W 0x00000008 /* Write buffer enable */ +#define CR_P 0x00000010 /* 32-bit exception handler */ +#define CR_D 0x00000020 /* 32-bit data address range */ +#define CR_L 0x00000040 /* Implementation defined */ +#define CR_B 0x00000080 /* Big endian */ +#define CR_S 0x00000100 /* System MMU protection */ +#define CR_R 0x00000200 /* ROM MMU protection */ +#define CR_F 0x00000400 /* Implementation defined */ +#define CR_Z 0x00000800 /* Implementation defined */ +#define CR_I 0x00001000 /* Icache enable */ +#define CR_V 0x00002000 /* Vectors relocated to 0xffff0000 */ +#define CR_RR 0x00004000 /* Round Robin cache replacement */ +#define CR_L4 0x00008000 /* LDR pc can set T bit */ +#define CR_DT 0x00010000 +#define CR_IT 0x00040000 +#define CR_ST 0x00080000 +#define CR_FI 0x00200000 /* Fast interrupt (lower latency mode) */ +#define CR_U 0x00400000 /* Unaligned access operation */ +#define CR_XP 0x00800000 /* Extended page tables */ +#define CR_VE 0x01000000 /* Vectored interrupts */ + +/* The lowest 4-bits of the FSR register indicates the fault generated by + * the MMU. + */ + +#define FSR_MASK 15 /* Bits 0-3: Type of fault */ +#define FSR_VECTOR 0 /* Vector exception */ +#define FSR_ALIGN1 1 /* Alignment fault */ +#define FSR_TERMINAL 2 /* Terminal exception */ +#define FSR_ALIGN2 3 /* Alignment fault */ +#define FSR_LINESECT 4 /* External abort on linefetch for section translation */ +#define FSR_SECT 5 /* Section translation fault (unmapped virtual address) */ +#define FSR_LINEPAGE 6 /* External abort on linefetch for page translation */ +#define FSR_PAGE 7 /* Page translation fault (unmapped virtual address) */ +#define FSR_NLINESECT 8 /* External abort on non-linefetch for section translation */ +#define FSR_DOMSECT 9 /* Domain fault on section translation (i.e. accessing invalid domain) */ +#define FSR_NLINEPAGE 10 /* External abort on non-linefetch for page translation */ +#define FSR_DOMPAGE 11 /* Domain fault on page translation (i.e. accessing invalid domain) */ +#define FSR_EXTERN1 12 /* External abort on first level translation */ +#define FSR_PERMSECT 13 /* Permission fault on section (i.e. no permission to access virtual address) */ +#define FSR_EXTERN2 14 /* External abort on second level translation */ +#define FSR_PERMPAGE 15 /* Permission fault on page (i.e. no permission to access virtual address) */ + +#define FSR_DOM_SHIFT 4 /* Bits 4-7: Domain */ +#define FSR_DOM_MASK (15 << FSR_DOM_SHIFT) + +/* Hardware page table definitions. + * + * Level 1 Descriptor (PMD) + * + * Common definitions. + */ + +#define PMD_TYPE_MASK 0x00000003 /* Bits 1:0: Type of descriptor */ +#define PMD_TYPE_FAULT 0x00000000 +#define PMD_TYPE_COARSE 0x00000001 +#define PMD_TYPE_SECT 0x00000002 +#define PMD_TYPE_FINE 0x00000003 + /* Bits 3:2: Depends on descriptor */ +#define PMD_BIT4 0x00000010 /* Bit 4: Must be one */ +#define PMD_DOMAIN_MASK 0x000001e0 /* Bits 8:5: Domain control bits */ +#define PMD_DOMAIN(x) ((x) << 5) +#define PMD_PROTECTION 0x00000200 /* Bit 9: v5 only */ + /* Bits 31:10: Depend on descriptor */ + +/* Level 1 Section Descriptor. Section descriptors allow fast, single + * level mapping between 1Mb address regions. + */ + /* Bits 1:0: Type of mapping */ +#define PMD_SECT_BUFFERABLE 0x00000004 /* Bit 2: 1=bufferable */ +#define PMD_SECT_CACHEABLE 0x00000008 /* Bit 3: 1=cacheable */ + /* Bit 4: Common, must be one */ + /* Bits 8:5: Common domain control */ + /* Bit 9: Common protection */ +#define PMD_SECT_AP_MASK 0x00000c00 /* Bits 11:10: Access permission */ +#define PMD_SECT_AP_WRITE 0x00000400 +#define PMD_SECT_AP_READ 0x00000800 + /* Bits 19:20: Should be zero */ +#define PMD_SECT_TEX_MASK 0xfff00000 /* Bits 31:20: v5, Physical page */ +#define PMD_SECT_APX 0x00008000 /* Bit 15: v6 only */ +#define PMD_SECT_S 0x00010000 /* Bit 16: v6 only */ +#define PMD_SECT_nG 0x00020000 /* Bit 17: v6 only */ + +#define PMD_SECT_UNCACHED (0) +#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE) +#define PMD_SECT_WT (PMD_SECT_CACHEABLE) +#define PMD_SECT_WB (PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE) +#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1)|PMD_SECT_CACHEABLE) +#define PMD_SECT_WBWA (PMD_SECT_TEX(1)|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE) + +/* Level 1 Coarse Table Descriptor. Coarse Table Descriptors support + * two level mapping between 16Kb memory regions. + */ + /* Bits 1:0: Type of mapping */ + /* Bits 3:2: Should be zero */ + /* Bit 4: Common, must be one */ + /* Bits 8:5: Common domain control */ + /* Bits 9: Should be zero */ +#define PMD_COARSE_TEX_MASK 0xfffffc00 /* Bits 31:10: v5, Physical page */ + +/* Level 1 Fine Table Descriptor. Coarse Table Descriptors support + * two level mapping between 4Kb memory regions. + */ + + /* Bits 1:0: Type of mapping */ + /* Bits 3:2: Should be zero */ + /* Bit 4: Common, must be one */ + /* Bits 8:5: Common domain control */ + /* Bits 11:9: Should be zero */ +#define PMD_FINE_TEX_MASK 0xfffff000 /* Bits 31:12: v5, Physical page */ + +/* Level 2 Table Descriptor (PTE). A section descriptor provides the base address + * of a 1MB block of memory. The page table descriptors provide the base address of + * a page table that contains second-level descriptors. There are two sizes of page + * table: + * - Coarse page tables have 256 entries, splitting the 1MB that the table + * describes into 4KB blocks + * - Fine/tiny page tables have 1024 entries, splitting the 1MB that the table + * describes into 1KB blocks. + * + * The following definitions apply to all L2 tables: + */ + +#define PTE_TYPE_MASK (3 << 0) /* Bits: 1:0: Type of mapping */ +#define PTE_TYPE_FAULT (0 << 0) /* None */ +#define PTE_TYPE_LARGE (1 << 0) /* 64Kb of memory */ +#define PTE_TYPE_SMALL (2 << 0) /* 4Kb of memory */ +#define PTE_TYPE_TINY (3 << 0) /* 1Kb of memory (v5)*/ +#define PTE_BUFFERABLE (1 << 2) /* Bit 2: 1=bufferable */ +#define PTE_CACHEABLE (1 << 3) /* Bit 3: 1=cacheable */ + /* Bits 31:4: Depend on type */ + +/* Large page -- 64Kb */ + /* Bits: 1:0: Type of mapping */ + /* Bits: 3:2: Bufferable/cacheable */ +#define PTE_LARGE_AP_MASK (0xff << 4) /* Bits 11:4 Access permissions */ +#define PTE_LARGE_AP_UNO_SRO (0x00 << 4) +#define PTE_LARGE_AP_UNO_SRW (0x55 << 4) +#define PTE_LARGE_AP_URO_SRW (0xaa << 4) +#define PTE_LARGE_AP_URW_SRW (0xff << 4) + /* Bits 15:12: Should be zero */ +#define PTE_LARGE_TEX_MASK 0xffff0000 /* Bits 31:16: v5, Physical page */ + +/* Small page -- 4Kb */ + + /* Bits: 1:0: Type of mapping */ + /* Bits: 3:2: Bufferable/cacheable */ +#define PTE_SMALL_AP_MASK (0xff << 4) /* Bits: 11:4: Access permissions */ +#define PTE_SMALL_AP_UNO_SRO (0x00 << 4) +#define PTE_SMALL_AP_UNO_SRW (0x55 << 4) +#define PTE_SMALL_AP_URO_SRW (0xaa << 4) +#define PTE_SMALL_AP_URW_SRW (0xff << 4) +#define PTE_SMALL_TEX_MASK 0xfffff000 /* Bits: 31:12: Physical page */ + +#define PTE_SMALL_NPAGES 256 /* 256 Coarse PTE's per section */ + +/* Fine/Tiny page -- 1Kb */ + + /* Bits: 1:0: Type of mapping */ + /* Bits: 3:2: Bufferable/cacheable */ +#define PTE_EXT_AP_MASK (3 << 4) /* Bits: 5:4: Access persions */ +#define PTE_EXT_AP_UNO_SRO (0 << 4) +#define PTE_EXT_AP_UNO_SRW (1 << 4) +#define PTE_EXT_AP_URO_SRW (2 << 4) +#define PTE_EXT_AP_URW_SRW (3 << 4) + /* Bits: 9:6: Should be zero */ +#define PTE_TINY_TEX_MASK 0xfffffc00 /* Bits: 31:10: Physical page */ + +#define PTE_TINY_NPAGES 1024 /* 1024 Tiny PTE's per section */ + +/* Default MMU flags for RAM memory, IO, vector region */ + +#define MMU_ROMFLAGS \ + (PMD_TYPE_SECT|PMD_BIT4|PMD_SECT_AP_READ) + +#define MMU_MEMFLAGS \ + (PMD_TYPE_SECT|PMD_SECT_WB|PMD_BIT4|PMD_SECT_AP_WRITE|PMD_SECT_AP_READ) + +#define MMU_IOFLAGS \ + (PMD_TYPE_SECT|PMD_BIT4|PMD_SECT_AP_WRITE|PMD_SECT_AP_READ) + +#define MMU_L1_VECTORFLAGS (PMD_TYPE_COARSE|PMD_BIT4) +#define MMU_L2_VECTORFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) + +/* Mapped section size */ + +#define SECTION_SIZE (1 << 20) /* 1Mb */ + +/* CP15 register c2 contains a pointer to the base address of a paged table in + * physical memory. Only bits 14-31 of the page table address is retained there; + * The full 30-bit address is formed by ORing in bits 2-13 or the virtual address + * (MVA). As a consequence, the page table must be aligned to a 16Kb address in + * physical memory and could require up to 16Kb of memory. + */ + +#define PGTABLE_SIZE 0x00004000 + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Get the current value of the CP15 C1 control register */ + +static inline unsigned int get_cp15c1(void) +{ + unsigned int retval; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0" + : "=r" (retval) + : + : "memory"); + return retval; +} + +/* Get the current value of the CP15 C2 page table pointer register */ + +static inline unsigned int get_cp15c2(void) +{ + unsigned int retval; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c2, c0" + : "=r" (retval) + : + : "memory"); + return retval; +} +/* Get the current value of the CP15 C3 domain access register */ + +static inline unsigned int get_cp15c3(void) +{ + unsigned int retval; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c3, c0" + : "=r" (retval) + : + : "memory"); + return retval; +} + +/* ARMv4/ARMv5 operation: Invalidate TLB + * ARM926EJ-S operation: Invalidate set-associative + * Data: Should be zero + */ + +static inline void tlb_invalidate(void) +{ + unsigned int sbz = 0; + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c8, c7, 0" + : + : "r" (sbz) + : "memory"); +} + +/* ARMv4/ARMv5 operation: Invalidate TLB single entry (MVA) + * ARM926EJ-S operation: Invalidate single entry + * Data: MVA + */ + +static inline void tlb_invalidate_single(unsigned int mva) +{ + mva &= 0xfffffc00; + __asm__ __volatile__ + ( + "mcr p15, 0, %0, c8, c7, 1" + : + : "r" (mva) + : "memory"); +} + +/* ARMv4/ARMv5 operation: Invalidate instruction TLB + * ARM926EJ-S operation: Invalidate set-associative TLB + * Data: Should be zero + */ + +static inline void tlb_instr_invalidate(void) +{ + unsigned int sbz = 0; + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c8, c5, 0" + : + : "r" (sbz) + : "memory"); +} + +/* ARMv4/ARMv5 operation: Invalidate instruction TLB single entry (MVA) + * ARM926EJ-S operation: Invalidate single entry + * Data: MVA + */ + +static inline void tlb_inst_invalidate_single(unsigned int mva) +{ + mva &= 0xfffffc00; + __asm__ __volatile__ + ( + "mcr p15, 0, %0, c8, c5, 1" + : + : "r" (mva) + : "memory"); +} + +/* ARMv4/ARMv5 operation: Invalidate data TLB + * ARM926EJ-S operation: Invalidate set-associative TLB + * Data: Should be zero + */ + +static inline void tlb_data_invalidate(void) +{ + unsigned int sbz = 0; + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c8, c6, 0" + : + : "r" (sbz) + : "memory"); +} + +/* ARMv4/ARMv5 operation: Invalidate data TLB single entry (MVA) + * ARM926EJ-S operation: Invalidate single entry + * Data: MVA + */ + +static inline void tlb_data_invalidate_single(unsigned int mva) +{ + mva &= 0xfffffc00; + __asm__ __volatile__ + ( + "mcr p15, 0, %0, c8, c6, 1" + : + : "r" (mva) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_COMMON_ARM_H */ diff --git a/arch/arm/src/arm/cache.h b/arch/arm/src/arm/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..a463490bc70b040effabf0dcd017dc4791e3995d --- /dev/null +++ b/arch/arm/src/arm/cache.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/arm/cache.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Several of these cache operations come from Atmel sample code with + * modifications for better integration with NuttX. The Atmel sample code + * has a BSD compatibile license that requires this copyright notice: + * + * Copyright (c) 2008, Atmel Corporation + * + * [Actually, I think that all of the Atmel functions are commented out now] + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARM_CACHE_H +#define __ARCH_ARM_SRC_ARM_CACHE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Defintiions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void cp15_flush_idcache(uint32_t start, uint32_t end); +#if 0 /* Not used */ +void cp15_invalidate_idcache(void); +void cp15_invalidate_icache(void); +#endif +void cp15_invalidate_dcache(uint32_t start, uint32_t end); +#if 0 /* Not used */ +void cp15_invalidate_dcache_all(void); +void cp15_prefetch_icacheline(unsigned int value); +void cp15_testcleaninvalidate_dcache(void); +void cp15_drain_writebuffer(void); + +unsigned int cp15_read_dcachelockdown(void); +void cp15_write_dcachelockdown(unsigned int value); +unsigned int cp15_read_icachelockdown(void); +void cp15_write_icachelockdown(unsigned int value); +#endif + +#endif /* __ARCH_ARM_SRC_ARM_CACHE_H */ + diff --git a/arch/arm/src/arm/pg_macros.h b/arch/arm/src/arm/pg_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..47616b426ae20f77dfe1dc346c85a8f6acc7afed --- /dev/null +++ b/arch/arm/src/arm/pg_macros.h @@ -0,0 +1,522 @@ +/**************************************************************************** + * arch/arm/src/arm/pg_macros.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Do not change this macro definition without making corresponding name + * changes in other files. This macro name is used in various places to + * assure that some file inclusion ordering dependencies are enforced. + */ + +#ifndef __ARCH_ARM_SRC_ARM_PG_MACROS_H +#define __ARCH_ARM_SRC_ARM_PG_MACROS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifdef CONFIG_PAGING + +/* Sanity check -- we cannot be using a ROM page table and supporting on- + * demand paging. + */ + +#ifdef CONFIG_ARCH_ROMPGTABLE +# error "Cannot support both CONFIG_PAGING and CONFIG_ARCH_ROMPGTABLE" +#endif + +/* Virtual Page Table Location **********************************************/ + +/* Check if the virtual address of the page table has been defined. It should + * not be defined: architecture specific logic should suppress defining + * PGTABLE_BASE_VADDR unless: (1) it is defined in the NuttX configuration + * file, or (2) the page table is position in low memory (because the vectors + * are in high memory). + */ + +#ifndef PGTABLE_BASE_VADDR +# define PGTABLE_BASE_VADDR (PG_LOCKED_VBASE + PG_TEXT_VSIZE + PG_DATA_SIZE) + + /* Virtual base of the address of the L2 page tables need to recalculates + * using this new virtual base address of the L2 page table. + */ + +# undef PGTABLE_L2_FINE_VBASE +# define PGTABLE_L2_FINE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_FINE_OFFSET) + +# undef PGTABLE_L2_COARSE_VBASE +# define PGTABLE_L2_COARSE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_COARSE_OFFSET) +#endif + +/* Page Size Selections *****************************************************/ + +/* Create some friendly definitions to handle some differences between + * small and tiny pages. + */ + +#if CONFIG_PAGING_PAGESIZE == 1024 + + /* Base of the L2 page table (aligned to 4Kb byte boundaries) */ + +# define PGTABLE_L2_BASE_PADDR PGTABLE_L2_FINE_PBASE +# define PGTABLE_L2_BASE_VADDR PGTABLE_L2_FINE_VBASE + + /* Number of pages in an L2 table per L1 entry */ + +# define PTE_NPAGES PTE_TINY_NPAGES + + /* Mask to get the page table physical address from an L1 entry */ + +# define PG_L1_PADDRMASK PMD_FINE_TEX_MASK + + /* MMU Flags for each memory region */ + +# define MMU_L1_TEXTFLAGS (PMD_TYPE_FINE|PMD_BIT4) +# define MMU_L2_TEXTFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRO|PTE_CACHEABLE) +# define MMU_L1_DATAFLAGS (PMD_TYPE_FINE|PMD_BIT4) +# define MMU_L2_DATAFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRW|PTE_CACHEABLE|PTE_BUFFERABLE) +# define MMU_L2_ALLOCFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRW) +# define MMU_L1_PGTABFLAGS (PMD_TYPE_FINE|PMD_BIT4) +# define MMU_L2_PGTABFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRW) + +# define MMU_L2_VECTRWFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRW) +# define MMU_L2_VECTROFLAGS (PTE_TYPE_TINY|PTE_EXT_AP_UNO_SRO|PTE_CACHEABLE) + +#elif CONFIG_PAGING_PAGESIZE == 4096 + + /* Base of the L2 page table (aligned to 1Kb byte boundaries) */ + +# define PGTABLE_L2_BASE_PADDR PGTABLE_L2_COARSE_PBASE +# define PGTABLE_L2_BASE_VADDR PGTABLE_L2_COARSE_VBASE + + /* Number of pages in an L2 table per L1 entry */ + +# define PTE_NPAGES PTE_SMALL_NPAGES + + /* Mask to get the page table physical address from an L1 entry */ + +# define PG_L1_PADDRMASK PMD_COARSE_TEX_MASK + + /* MMU Flags for each memory region. */ + +# define MMU_L1_TEXTFLAGS (PMD_TYPE_COARSE|PMD_BIT4) +# define MMU_L2_TEXTFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRO|PTE_CACHEABLE) +# define MMU_L1_DATAFLAGS (PMD_TYPE_COARSE|PMD_BIT4) +# define MMU_L2_DATAFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW|PTE_CACHEABLE|PTE_BUFFERABLE) +# define MMU_L2_ALLOCFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) +# define MMU_L1_PGTABFLAGS (PMD_TYPE_COARSE|PMD_BIT4) +# define MMU_L2_PGTABFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) + +# define MMU_L2_VECTRWFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) +# define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRO|PTE_CACHEABLE) + +#else +# error "Need extended definitions for CONFIG_PAGING_PAGESIZE" +#endif + +#define PT_SIZE (4*PTE_NPAGES) + +/* Addresses of Memory Regions **********************************************/ + +/* We position the locked region PTEs at an offset into the first + * L2 page table. The L1 entry points to an 1Mb aligned virtual + * address. The actual L2 entry will be offset into the aligned + * L2 table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * OFFSET=(((a) & 0x000fffff) >> 12) << 2) + * Fine: PG_L1_PADDRMASK=0xfffff000 + * OFFSET=(((a) & 0x000fffff) >> 10) << 2) + */ + +#define PG_L1_LOCKED_PADDR (PGTABLE_BASE_PADDR + ((PG_LOCKED_VBASE >> 20) << 2)) +#define PG_L1_LOCKED_VADDR (PGTABLE_BASE_VADDR + ((PG_LOCKED_VBASE >> 20) << 2)) + +#define PG_L2_LOCKED_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +#define PG_L2_LOCKED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_SIZE (4*CONFIG_PAGING_NLOCKED) + +/* We position the paged region PTEs immediately after the locked + * region PTEs. NOTE that the size of the paged regions is much + * larger than the size of the physical paged region. That is the + * core of what the On-Demanding Paging feature provides. + */ + +#define PG_L1_PAGED_PADDR (PGTABLE_BASE_PADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_L1_PAGED_VADDR (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) + +#define PG_L2_PAGED_PADDR (PG_L2_LOCKED_PADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_VADDR (PG_L2_LOCKED_VADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_SIZE (4*CONFIG_PAGING_NVPAGED) + +/* This describes the overall text region */ + +#define PG_L1_TEXT_PADDR PG_L1_LOCKED_PADDR +#define PG_L1_TEXT_VADDR PG_L1_LOCKED_VADDR + +#define PG_L2_TEXT_PADDR PG_L2_LOCKED_PADDR +#define PG_L2_TEXT_VADDR PG_L2_LOCKED_VADDR +#define PG_L2_TEXT_SIZE (PG_L2_LOCKED_SIZE + PG_L2_PAGED_SIZE) + +/* We position the data section PTEs just after the text region PTE's */ + +#define PG_L1_DATA_PADDR (PGTABLE_BASE_PADDR + ((PG_DATA_VBASE >> 20) << 2)) +#define PG_L1_DATA_VADDR (PGTABLE_BASE_VADDR + ((PG_DATA_VBASE >> 20) << 2)) + +#define PG_L2_DATA_PADDR (PG_L2_LOCKED_PADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_VADDR (PG_L2_LOCKED_VADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_SIZE (4*PG_DATA_NPAGES) + +/* Page Table Info **********************************************************/ + +/* The number of pages in the in the page table (PG_PGTABLE_NPAGES). We + * position the pagetable PTEs just after the data section PTEs. + */ + +#define PG_PGTABLE_NPAGES (PGTABLE_SIZE >> PAGESHIFT) +#define PG_L1_PGTABLE_PADDR (PGTABLE_BASE_PADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) +#define PG_L1_PGTABLE_VADDR (PGTABLE_BASE_VADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) + +#define PG_L2_PGTABLE_PADDR (PG_L2_DATA_PADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_VADDR (PG_L2_DATA_VADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_SIZE (4*PG_DATA_NPAGES) + +/* Vector Mapping ***********************************************************/ + +/* One page is required to map the vector table. The vector table could lie + * at virtual address zero (or at the start of RAM which is aliased to address + * zero on the ea3131) or at virtual address 0xfff00000. We only have logic + * here to support the former case. + * + * NOTE: If the vectors are at address zero, the page table will be + * forced to the highest RAM addresses. If the vectors are at 0xfff0000, + * then the page table is forced to the beginning of RAM. + * + * When the vectors are at the beginning of RAM, they will probably overlap + * the first page of the locked text region. In any other case, the + * configuration must set CONFIG_PAGING_VECPPAGE to provide the physical + * address of the page to use for the vectors. + * + * When the vectors overlap the first page of the locked text region (the + * only case in use so far), then the text page will be temporarily be made + * writable in order to copy the vectors. + * + * PG_VECT_PBASE - This the physical address of the page in memory to be + * mapped to the vector address. + * PG_L2_VECT_PADDR - This is the physical address of the L2 page table + * entry to use for the vector mapping. + * PG_L2_VECT_VADDR - This is the virtual address of the L2 page table + * entry to use for the vector mapping. + */ + +/* Case 1: The configuration tells us everything */ + +#if defined(CONFIG_PAGING_VECPPAGE) +# define PG_VECT_PBASE CONFIG_PAGING_VECPPAGE +# define PG_L2_VECT_PADDR CONFIG_PAGING_VECL2PADDR +# define PG_L2_VECT_VADDR CONFIG_PAGING_VECL2VADDR + +/* Case 2: Vectors are in low memory and the locked text region starts at + * the beginning of SRAM (which will be aliased to address 0x00000000). + * However, the beginning of SRAM may not be aligned to the beginning + * of the L2 page table (because the beginning of RAM is offset into + * the table. + */ + +#elif defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_PAGING_LOCKED_PBASE) +# define PG_VECT_PBASE PG_LOCKED_PBASE +# define PG_L2_VECT_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +# define PG_L2_VECT_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_VECT_OFFSET) +# define PG_L2_VECT_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_VECT_OFFSET) + +/* Case 3: High vectors or the locked region is not at the beginning or SRAM */ + +#else +# error "Logic missing for high vectors in this case" +#endif + +/* Page Usage ***************************************************************/ + +/* This is the total number of pages used in the text/data mapping: */ + +#define PG_TOTAL_NPPAGES (PG_TEXT_NPPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_NVPAGES (PG_TEXT_NVPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_PSIZE (PG_TOTAL_NPPAGES << PAGESHIFT) +#define PG_TOTAL_VSIZE (PG_TOTAL_NVPAGES << PAGESHIFT) + +/* Sanity check: */ + +#if PG_TOTAL_NPPAGES > PG_RAM_PAGES +# error "Total pages required exceeds RAM size" +#endif + +/* Page Management **********************************************************/ + +/* For page managment purposes, the following summarize the "heap" of + * free pages, operations on free pages and the L2 page table. + * + * PG_POOL_VA2L1OFFSET(va) - Given a virtual address, return the L1 table + * offset (in bytes). + * PG_POOL_VA2L1VADDR(va) - Given a virtual address, return the virtual + * address of the L1 table entry + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the physical address of the start of the L2 + * page table + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the virtual address of the start of the L2 + * page table. + * + * PG_POOL_L1VBASE - The virtual address of the start of the L1 + * page table range corresponding to the first + * virtual address of the paged text region. + * PG_POOL_L1VEND - The virtual address of the end+1 of the L1 + * page table range corresponding to the last + * virtual address+1 of the paged text region. + * + * PG_POOL_VA2L2NDX(va) - Converts a virtual address within the paged + * text region to the most compact possible + * representation. Each PAGESIZE of address + * corresponds to 1 index in the L2 page table; + * Index 0 corresponds to the first L2 page table + * entry for the first page in the virtual paged + * text address space. + * PG_POOL_NDX2VA(ndx) - Performs the opposite conversion.. convests + * an index into a virtual address in the paged + * text region (the address at the beginning of + * the page). + * PG_POOL_MAXL2NDX - This is the maximum value+1 of such an index. + * + * PG_POOL_PGPADDR(ndx) - Converts an page index into the corresponding + * (physical) address of the backing page memory. + * PG_POOL_PGVADDR(ndx) - Converts an page index into the corresponding + * (virtual)address of the backing page memory. + * + * These are used as follows: If a miss occurs at some virtual address, va, + * A new page index, ndx, is allocated. PG_POOL_PGPADDR(i) converts the index + * into the physical address of the page memory; PG_POOL_L2VADDR(va) converts + * the virtual address in the L2 page table there the new mapping will be + * written. + */ + +#define PG_POOL_VA2L1OFFSET(va) (((va) >> 20) << 2) +#define PG_POOL_VA2L1VADDR(va) (PGTABLE_BASE_VADDR + PG_POOL_VA2L1OFFSET(va)) +#define PG_POOL_L12PPTABLE(L1) ((L1) & PG_L1_PADDRMASK) +#define PG_POOL_L12VPTABLE(L1) (PG_POOL_L12PPTABLE(L1) - PGTABLE_BASE_PADDR + PGTABLE_BASE_VADDR) + +#define PG_POOL_L1VBASE (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_POOL_L1VEND (PG_POOL_L1VBASE + (CONFIG_PAGING_NVPAGED << 2)) + +#define PG_POOL_VA2L2NDX(va) (((va) - PG_PAGED_VBASE) >> PAGESHIFT) +#define PG_POOL_NDX2VA(ndx) (((ndx) << PAGESHIFT) + PG_PAGED_VBASE) +#define PG_POOL_MAXL2NDX PG_POOL_VA2L2NDX(PG_PAGED_VEND) + +#define PG_POOL_PGPADDR(ndx) (PG_PAGED_PBASE + ((ndx) << PAGESHIFT)) +#define PG_POOL_PGVADDR(ndx) (PG_PAGED_VBASE + ((ndx) << PAGESHIFT)) + +#endif /* CONFIG_PAGING */ + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +#ifdef __ASSEMBLY__ + +/**************************************************************************** + * Name: pg_l2map + * + * Description: + * Write several, contiguous L2 page table entries. npages entries will be + * written. This macro is used when CONFIG_PAGING is enable. This case, + * it is used as follows: + * + * ldr r0, =PGTABLE_L2_BASE_PADDR <-- Address in L2 table + * ldr r1, =PG_LOCKED_PBASE <-- Physical page memory address + * ldr r2, =CONFIG_PAGING_NLOCKED <-- number of pages + * ldr r3, =MMUFLAGS <-- L2 MMU flags + * pg_l2map r0, r1, r2, r3, r4 + * + * Inputs: + * l2 - Physical or virtual start address in the L2 page table, depending + * upon the context. (modified) + * ppage - The physical address of the start of the region to span. Must + * be aligned to 1Mb section boundaries (modified) + * npages - Number of pages to write in the section (modified) + * mmuflags - L2 MMU FLAGS + * + * Scratch registers (modified): tmp + * l2 - Next address in the L2 page table. + * ppage - Start of next physical page + * npages - Loop counter + * tmp - scratch + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * - pg_l1span has been called to initialize the L1 table. + * + ****************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l2map, l2, ppage, npages, mmuflags, tmp + b 2f +1: + /* Write the one L2 entries. First, get tmp = (ppage | mmuflags), + * the value to write into the L2 PTE + */ + + orr \tmp, \ppage, \mmuflags + + /* Write value into table at the current table address + * (and increment the L2 page table address by 4) + */ + + str \tmp, [\l2], #4 + + /* Update the physical address that will correspond to the next + * table entry. + */ + + add \ppage, \ppage, #CONFIG_PAGING_PAGESIZE + + /* Decrement the number of pages written */ + + sub \npages, \npages, #1 +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next PTE. + */ + cmp \npages, #0 + bgt 1b + .endm +#endif /* CONFIG_PAGING */ + +/**************************************************************************** + * Name: pg_l1span + * + * Description: + * Write several, contiguous unmapped coarse L1 page table entries. As + * many entries will be written as many as needed to span npages. This + * macro is used when CONFIG_PAGING is enable. This case, it is used as + * follows: + * + * ldr r0, =PG_L1_PGTABLE_PADDR <-- Address in the L1 table + * ldr r1, =PG_L2_PGTABLE_PADDR <-- Physical address of L2 page table + * ldr r2, =PG_PGTABLE_NPAGES <-- Total number of pages + * ldr r3, =PG_PGTABLE_NPAGE1 <-- Number of pages in the first PTE + * ldr r4, =MMU_L1_PGTABFLAGS <-- L1 MMU flags + * pg_l1span r0, r1, r2, r3, r4, r4 + * + * Inputs (unmodified unless noted): + * l1 - Physical or virtual address in the L1 table to begin writing (modified) + * l2 - Physical start address in the L2 page table (modified) + * npages - Number of pages to required to span that memory region (modified) + * ppage - The number of pages in page 1 (modified) + * mmuflags - L1 MMU flags to use + * + * Scratch registers (modified): l1, l2, npages, tmp + * l1 - Next L1 table address + * l2 - Physical start address of the next L2 page table + * npages - Loop counter + * ppage - After the first page, this will be the full number of pages. + * tmp - scratch + * + * Return: + * Nothing of interest. + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * + ****************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l1span, l1, l2, npages, ppage, mmuflags, tmp + b 2f +1: + /* Write the L1 table entry that refers to this (unmapped) coarse page + * table. + * + * tmp = (l2table | mmuflags), the value to write into the page table + */ + + orr \tmp, \l2, \mmuflags + + /* Write the value into the L1 table at the correct offset. + * (and increment the L1 table address by 4) + */ + + str \tmp, [\l1], #4 + + /* Update the L2 page table address for the next L1 table entry. */ + + add \l2, \l2, #PT_SIZE /* Next L2 page table start address */ + + /* Update the number of pages that we have account for (with + * non-mappings). NOTE that the first page may have fewer than + * the maximum entries per page table. + */ + + sub \npages, \npages, \ppage + mov \ppage, #PTE_NPAGES +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next L1 entry. + */ + + cmp \npages, #0 + bgt 1b + .endm + +#endif /* CONFIG_PAGING */ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_ARM_PG_MACROS_H */ diff --git a/arch/arm/src/arm/up_allocpage.c b/arch/arm/src/arm/up_allocpage.c new file mode 100644 index 0000000000000000000000000000000000000000..90bbfe2de136fa999ed2f56f31a4a515dfde9712 --- /dev/null +++ b/arch/arm/src/arm/up_allocpage.c @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/src/arm/up_allocpage.c + * Allocate a new page and map it to the fault address of a task. + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PAGING + +#include + +#include "pg_macros.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#if CONFIG_PAGING_NPPAGED < 256 +typedef uint8_t pgndx_t; +#elif CONFIG_PAGING_NPPAGED < 65536 +typedef uint16_t pgndx_t; +#else +typedef uint32_t pgndx_t; +#endif + +#if PG_POOL_MAXL1NDX < 256 +typedef uint8_t L1ndx_t; +#elif PG_POOL_MAXL1NDX < 65536 +typedef uint16_t L1ndx_t; +#else +typedef uint32_t L1ndx_t; +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Free pages in memory are managed by indices ranging from up to + * CONFIG_PAGING_NPAGED. Initially all pages are free so the page can be + * simply allocated in order: 0, 1, 2, ... . After all CONFIG_PAGING_NPAGED + * pages have be filled, then they are blindly freed and re-used in the + * same order 0, 1, 2, ... because we don't know any better. No smart "least + * recently used" kind of logic is supported. + */ + +static pgndx_t g_pgndx; + +/* After CONFIG_PAGING_NPAGED have been allocated, the pages will be re-used. + * In order to re-used the page, we will have un-map the page from its previous + * mapping. In order to that, we need to be able to map a physical address to + * to an index into the PTE where it was mapped. The following table supports + * this backward lookup - it is indexed by the page number index, and holds + * another index to the mapped virtual page. + */ + +static L1ndx_t g_ptemap[CONFIG_PAGING_NPPAGED]; + +/* The contents of g_ptemap[] are not valid until g_pgndx has wrapped at + * least one time. + */ + +static bool g_pgwrap; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocpage() + * + * Description: + * This architecture-specific function will set aside page in memory and map + * the page to its correct virtual address. Architecture-specific context + * information saved within the TCB will provide the function with the + * information needed to identify the virtual miss address. + * + * This function will return the allocated physical page address in vpage. + * The size of the underlying physical page is determined by the + * configuration setting CONFIG_PAGING_PAGESIZE. + * + * NOTE 1: This function must always return a page allocation. If all + * available pages are in-use (the typical case), then this function will + * select a page in-use, un-map it, and make it available. + * + * NOTE 2: If an in-use page is un-mapped, it may be necessary to flush the + * instruction cache in some architectures. + * + * NOTE 3: Allocating and filling a page is a two step process. up_allocpage() + * allocates the page, and up_fillpage() fills it with data from some non- + * volatile storage device. This distinction is made because up_allocpage() + * can probably be implemented in board-independent logic whereas up_fillpage() + * probably must be implemented as board-specific logic. + * + * NOTE 4: The initial mapping of vpage should be read-able and write- + * able (but not cached). No special actions will be required of + * up_fillpage() in order to write into this allocated page. + * + * Input Parameters: + * tcb - A reference to the task control block of the task that needs to + * have a page fill. Architecture-specific logic can retrieve page + * fault information from the architecture-specific context + * information in this TCB to perform the mapping. + * + * Returned Value: + * This function will return zero (OK) if the allocation was successful. + * A negated errno value may be returned if an error occurs. All errors, + * however, are fatal. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) +{ + uintptr_t vaddr; + uintptr_t paddr; + uint32_t *pte; + unsigned int pgndx; + + /* Since interrupts are disabled, we don't need to anything special. */ + + DEBUGASSERT(tcb && vpage); + + /* Get the virtual address that caused the fault */ + + vaddr = tcb->xcp.far; + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Allocate page memory to back up the mapping. Start by getting the + * index of the next page that we are going to allocate. + */ + + pgndx = g_pgndx++; + if (g_pgndx >= CONFIG_PAGING) + { + g_pgndx = 0; + g_pgwrap = true; + } + + /* Was this physical page previously mapped? If so, then we need to un-map + * it. + */ + + if (g_pgwrap) + { + /* Yes.. Get a pointer to the L2 entry corresponding to the previous + * mapping -- then zero it! + */ + + uintptr_t oldvaddr = PG_POOL_NDX2VA(g_ptemap[pgndx]); + pte = up_va2pte(oldvaddr); + *pte = 0; + + /* Invalidate the instruction TLB corresponding to the virtual address */ + + tlb_inst_invalidate_single(oldvaddr); + + /* I do not believe that it is necessary to flush the I-Cache in this + * case: The I-Cache uses a virtual address index and, hence, since the + * NuttX address space is flat, the cached instruction value should be + * correct even if the page mapping is no longer in place. + */ + } + + /* Then convert the index to a (physical) page address. */ + + paddr = PG_POOL_PGPADDR(pgndx); + + /* Now setup up the new mapping. Get a pointer to the L2 entry + * corresponding to the new mapping. Then set it map to the newly + * allocated page address. The inital mapping is read/write but + * non-cached (MMU_L2_ALLOCFLAGS) + */ + + pte = up_va2pte(vaddr); + *pte = (paddr | MMU_L2_ALLOCFLAGS); + + /* And save the new L1 index */ + + g_ptemap[pgndx] = PG_POOL_VA2L2NDX(vaddr); + + /* Finally, return the virtual address of allocated page */ + + *vpage = (void *)(vaddr & ~PAGEMASK); + return OK; +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/arm/up_assert.c b/arch/arm/src/arm/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..336a76c8613862c4bcea2c7b559eb727c947360e --- /dev/null +++ b/arch/arm/src/arm/up_assert.c @@ -0,0 +1,363 @@ +/**************************************************************************** + * arch/arm/src/arm/up_assert.c + * + * Copyright (C) 2007-2010, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump(sp,stack_base) +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (CURRENT_REGS) + { + int regs; + + /* Yes.. dump the interrupt registers */ + + for (regs = REG_R0; regs <= REG_R15; regs += 8) + { + uint32_t *ptr = (uint32_t *)&CURRENT_REGS[regs]; + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } + + lldbg("CPSR: %08x\n", CURRENT_REGS[REG_CPSR]); + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("sp: %08x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg("stack used: %08x\n", up_check_tcbstack(rtcb)); +#endif +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + up_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + up_registerdump(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (CURRENT_REGS || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/arm/src/arm/up_blocktask.c b/arch/arm/src/arm/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..716966714561b7eae8a8e399edaa6f471d440f3a --- /dev/null +++ b/arch/arm/src/arm/up_blocktask.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/arm/up_blocktask.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/arm/up_cache.S b/arch/arm/src/arm/up_cache.S new file mode 100644 index 0000000000000000000000000000000000000000..e03099ce04fc38676b3557295c37bbefe7da81d3 --- /dev/null +++ b/arch/arm/src/arm/up_cache.S @@ -0,0 +1,302 @@ +/**************************************************************************** + * arch/arm/src/arm/up_cache.S + * + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Several of these cache operations come from Atmel sample code with + * modifications for better integration with NuttX. The Atmel sample code + * has a BSD compatibile license that requires this copyright notice: + * + * Copyright (c) 2008, Atmel Corporation + * + * [Actually, I think that all of the Atmel functions are commented out now] + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .file "up_cp15.S" + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CACHE_DLINESIZE 32 + +/**************************************************************************** + * Cache Operations + ****************************************************************************/ + + .text + +/* Control functions caches and the write buffer c7 + * Register c7 controls the caches and the write buffer. The function of each cache + * operation is selected by the Opcode_2 and CRm fields in the MCR instruction used to + * write to CP15 c7. Writing other Opcode_2 or CRm values is Unpredictable. + * Reading from CP15 c7 is Unpredictable, with the exception of the two test and clean + * operations (see Table 2-18 on page 2-21 and Test and clean operations on page 2-23). + * You can use the following instruction to write to c7: + * MCR p15, , , , , + * + * Invalidate Icache and Dcache MCR p15, 0, , c7, c7, 0 + * Invalidate Icache MCR p15, 0, , c7, c5, 0 + * Invalidate Icache single entry (MVA) MVA MCR p15, 0, , c7, c5, 1 + * Invalidate Icache single entry (Set/Way) Set/Way MCR p15, 0, , c7, c5, 2 + * Prefetch Icache line (MVA) MVA MCR p15, 0, , c7, c13, 1 + * Invalidate Dcache MCR p15, 0, , c7, c6, 0 + * Invalidate Dcache single entry (MVA) MVA MCR p15, 0, , c7, c6, 1 + * Invalidate Dcache single entry (Set/Way) Set/Way MCR p15, 0, , c7, c6, 2 + * Clean Dcache single entry (MVA) MVA MCR p15, 0, , c7, c10, 1 + * Clean Dcache single entry (Set/Way) Set/Way MCR p15, 0, , c7, c10, 2 + * Test and clean Dcache - MRC p15, 0, , c7, c10, 3 + * Clean and invalidate Dcache entry (MVA) MVA MCR p15, 0, , c7, c14, 1 + * Clean and invalidate Dcache entry (Set/Way) Set/Way MCR p15, 0, , c7, c14, 2 + * Test, clean, and invalidate Dcache - MRC p15, 0, , c7, c14, 3 + * Drain write buffer SBZ MCR p15, 0, , c7, c10, 4 + * Wait for interrupt SBZ MCR p15, 0, , c7, c0, 4 + */ + +/* Esure coherency between the Icache and the Dcache in the region described + * by r0=start and r1=end. Cleans the corresponding D-cache lines and invalidates + * the corresponding I-Cache lines. + */ + + .globl cp15_flush_idcache + .type cp15_flush_idcache, function + +cp15_flush_idcache: + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 /* Clean D entry */ + mcr p15, 0, r0, c7, c5, 1 /* Invalidate I entry */ + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 /* Drain WB */ + mov pc, lr + .size cp15_flush_idcache, .-cp15_flush_idcache + +#if 0 /* Not used */ +/* Invalidate all of Icache and Dcache */ + + .globl cp15_invalidate_idcache + .type cp15_invalidate_idcache, function + +cp15_invalidate_idcache: + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 + nop + nop + nop + nop + nop + nop + nop + nop + bx lr + .size cp15_invalidate_idcache, . - cp15_invalidate_idcache + +/* Invalidate all of Icache */ + + .globl cp15_invalidate_icache + .type cp15_invalidate_icache, function + +cp15_invalidate_icache: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 + nop + nop + nop + nop + nop + nop + nop + nop + bx lr + .size cp15_invalidate_icache, . - cp15_invalidate_icache +#endif /* Not used */ + +/* Invalidate D-Cache in the region described by r0=start and r1=end. */ + + .globl cp15_invalidate_dcache + .type cp15_invalidate_dcache, function + +cp15_invalidate_dcache: + bic r0, r0, #CACHE_DLINESIZE - 1 + mcr p15, 0, r0, c7, c6, 1 /* Invalidate D entry */ + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov pc, lr + .size cp15_flush_idcache, .-cp15_flush_idcache + +#if 0 /* Not used */ +/* Invalidate Dcache */ + + .globl cp15_invalidate_dcache_all + .type cp15_invalidate_dcache_all, function + +cp15_invalidate_dcache_all: + mov r0, #0 + mcr p15, 0, r0, c7, c6, 0 + nop + nop + nop + nop + nop + nop + nop + nop + bx lr + .size cp15_invalidate_dcache_all, . - cp15_invalidate_dcache_all + +/* CP15 Prefetch Icache line c7 + * Performs an Icache lookup of the specified modified virtual address. + * If the cache misses, and the region is cacheable, a linefill is performed. + * Prefetch Icache line (MVA): MCR p15, 0, , c7, c13, 1 + */ + + .globl cp15_prefetch_icacheline + .type cp15_prefetch_icacheline, function + +cp15_prefetch_icacheline: + mcr p15, 0, r0, c7, c13, 1 + bx lr + .size cp15_prefetch_icacheline, . - cp15_prefetch_icacheline + +/* CP15 Test, clean, and invalidate Dcache c7 + * As for test and clean, except that when the entire cache has + * been tested and cleaned, it is invalidated. + */ + + .globl cp15_testcleaninvalidate_dcache + .type cp15_testcleaninvalidate_dcache, function + +cp15_testcleaninvalidate_dcache: + mrc p15, 0, r0, c7, c14, 3 + bne cp15_testcleaninvalidate_dcache + bx lr + .size cp15_testcleaninvalidate_dcache, . - cp15_testcleaninvalidate_dcache + +/* CP15 Drain write buffer c7 + * This instruction acts as an explicit memory barrier. It drains + * the contents of the write buffers of all memory stores + * occurring in program order before this instruction is + * completed. No instructions occurring in program order + * after this instruction are executed until it completes. This + * can be used when timing of specific stores to the level two + * memory system has to be controlled (for example, when a + * store to an interrupt acknowledge location has to complete + * before interrupts are enabled). + */ + + .globl cp15_drain_writebuffer + .type cp15_drain_writebuffer, function + +cp15_drain_writebuffer: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 + bx lr + .size cp15_drain_writebuffer, . - cp15_drain_writebuffer + +/**************************************************************************** + * Cache Lockdown + ****************************************************************************/ + +/* Cache Lockdown Register c9 + * The Cache Lockdown Register uses a cache-way-based locking scheme (Format C) that + * enables you to control each cache way independently. + * These registers enable you to control which cache ways of the four-way cache are used + * for the allocation on a linefill. When the registers are defined, subsequent linefills are + * only placed in the specified target cache way. This gives you some control over the + * cache pollution caused by particular applications, and provides a traditional lockdown + * operation for locking critical code into the cache. + * + * Read Dcache Lockdown Register MRC p15,0,,c9,c0,0 + * Write Dcache Lockdown Register MCR p15,0,,c9,c0,0 + * Read Icache Lockdown Register MRC p15,0,,c9,c0,1 + * Write Icache Lockdown Register MCR p15,0,,c9,c0,1 + */ + + .globl cp15_read_dcachelockdown + .type cp15_read_dcachelockdown, function + +cp15_read_dcachelockdown: + mov r0, #0 + mrc p15, 0, r0, c9, c0, 0 + bx lr + .size cp15_read_dcachelockdown, . - cp15_read_dcachelockdown + + .globl cp15_write_dcachelockdown + .type cp15_write_dcachelockdown, function + +cp15_write_dcachelockdown: + mcr p15, 0, r0, c9, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + bx lr + .size cp15_write_dcachelockdown, . - cp15_write_dcachelockdown + + .globl cp15_read_icachelockdown + .type cp15_read_icachelockdown, function + +cp15_read_icachelockdown: + mov r0, #0 + mrc p15, 0, r0, c9, c0, 1 + bx lr + .size cp15_read_icachelockdown, . - cp15_read_icachelockdown + + .globl cp15_write_icachelockdown + .type cp15_write_icachelockdown, function + +cp15_write_icachelockdown: + mcr p15, 0, r0, c9, c0, 1 + nop + nop + nop + nop + nop + nop + nop + nop + bx lr + .size cp15_write_icachelockdown, . - cp15_write_icachelockdown +#endif /* Not used */ + .end diff --git a/arch/arm/src/arm/up_checkmapping.c b/arch/arm/src/arm/up_checkmapping.c new file mode 100644 index 0000000000000000000000000000000000000000..f86b6de7558204c6f67197b5103a906e921464d1 --- /dev/null +++ b/arch/arm/src/arm/up_checkmapping.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/arm/up_checkmapping.c + * Check if the current task's fault address has been mapped into the virtual + * address space. + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkmapping() + * + * Description: + * The function up_checkmapping() returns an indication if the page fill + * still needs to performed or not. In certain conditions, the page fault + * may occur on several threads and be queued multiple times. This function + * will prevent the same page from be filled multiple times. + * + * Input Parameters: + * tcb - A reference to the task control block of the task that we believe + * needs to have a page fill. Architecture-specific logic can + * retrieve page fault information from the architecture-specific + * context information in this TCB and can consult processor resources + * (page tables or TLBs or ???) to determine if the fill still needs + * to be performed or not. + * + * Returned Value: + * This function will return true if the mapping is in place and false + * if the mapping is still needed. Errors encountered should be + * interpreted as fatal. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +bool up_checkmapping(FAR struct tcb_s *tcb) +{ + uintptr_t vaddr; + uint32_t *pte; + + /* Since interrupts are disabled, we don't need to anything special. */ + + DEBUGASSERT(tcb); + + /* Get the virtual address that caused the fault */ + + vaddr = tcb->xcp.far; + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Get the PTE associated with this virtual address */ + + pte = up_va2pte(vaddr); + + /* Return true if this virtual address is mapped. */ + + return (*pte != 0); +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/arm/up_copyfullstate.c b/arch/arm/src/arm/up_copyfullstate.c new file mode 100644 index 0000000000000000000000000000000000000000..5a60f7a1a67b48f75b22de4e557dfb6b62d90821 --- /dev/null +++ b/arch/arm/src/arm/up_copyfullstate.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/arm/up_copyfullstate.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyfullstate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copyfullstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the current ARM model, the state is always copied to and from the + * stack and TCB. + */ + + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/arm/src/arm/up_dataabort.c b/arch/arm/src/arm/up_dataabort.c new file mode 100644 index 0000000000000000000000000000000000000000..2ab00b15c9403b3e349288ef734b3c48f68a37f9 --- /dev/null +++ b/arch/arm/src/arm/up_dataabort.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/arm/src/arm/up_dataabort.c + * + * Copyright (C) 2007-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING +# include +# include "arm.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dataabort + * + * Input parameters: + * regs - The standard, ARM register save array. + * + * If CONFIG_PAGING is selected in the NuttX configuration file, then these + * additional input values are expected: + * + * far - Fault address register. On a data abort, the ARM MMU places the + * miss virtual address (MVA) into the FAR register. This is the address + * of the data which, when accessed, caused the fault. + * fsr - Fault status register. On a data a abort, the ARM MMU places an + * encoded four-bit value, the fault status, along with the four-bit + * encoded domain number, in the data FSR + * + * Description: + * This is the data abort exception handler. The ARM data abort exception + * occurs when a memory fault is detected during a data transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_PAGING +void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) +{ + struct tcb_s *tcb = this_task(); +#ifdef CONFIG_PAGING + uint32_t *savestate; + + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + + savestate = (uint32_t *)CURRENT_REGS; +#endif + CURRENT_REGS = regs; + +#ifdef CONFIG_PAGING + /* In the NuttX on-demand paging implementation, only the read-only, .text + * section is paged. However, the ARM compiler generated PC-relative data + * fetches from within the .text sections. Also, it is customary to locate + * read-only data (.rodata) within the same section as .text so that it + * does not require copying to RAM. Misses in either of these case should + * cause a data abort. + * + * We are only interested in data aborts due to page translations faults. + * Sections should already be in place and permissions should already be + * be set correctly (to read-only) so any other data abort reason is a + * fatal error. + */ + + pglldbg("FSR: %08x FAR: %08x\n", fsr, far); + if ((fsr & FSR_MASK) != FSR_PAGE) + { + goto segfault; + } + + /* Check the (virtual) address of data that caused the data abort. When + * the exception occurred, this address was provided in the FAR register. + * (It has not yet been saved in the register context save area). + */ + + pgllvdbg("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND); + if (far < PG_PAGED_VBASE || far >= PG_PAGED_VEND) + { + goto segfault; + } + + /* Save the offending data address as the fault address in the TCB of + * the currently task. This fault address is also used by the prefetch + * abort handling; this will allow common paging logic for both + * prefetch and data aborts. + */ + + tcb->xcp.far = regs[REG_R15]; + + /* Call pg_miss() to schedule the page fill. A consequences of this + * call are: + * + * (1) The currently executing task will be blocked and saved on + * on the g_waitingforfill task list. + * (2) An interrupt-level context switch will occur so that when + * this function returns, it will return to a different task, + * most likely the page fill worker thread. + * (3) The page fill worker task has been signalled and should + * execute immediately when we return from this exception. + */ + + pg_miss(); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + return; + +segfault: +#endif + lldbg("Data abort. PC: %08x FAR: %08x FSR: %08x\n", regs[REG_PC], far, fsr); + PANIC(); +} + +#else /* CONFIG_PAGING */ + +void up_dataabort(uint32_t *regs) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = regs; + + /* Crash -- possibly showing diagnost debug information. */ + + lldbg("Data abort. PC: %08x\n", regs[REG_PC]); + PANIC(); +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/arm/up_doirq.c b/arch/arm/src/arm/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..d13b04c19f25cf199f7b185c27f62d1b8b2be7c5 --- /dev/null +++ b/arch/arm/src/arm/up_doirq.c @@ -0,0 +1,134 @@ +/**************************************************************************** + * arch/arm/src/arm/up_doirq.c + * + * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Nested interrupts are not supported */ + + DEBUGASSERT(CURRENT_REGS == NULL); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + CURRENT_REGS = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + CURRENT_REGS = NULL; +#endif + board_autoled_off(LED_INIRQ); +} diff --git a/arch/arm/src/arm/up_elf.c b/arch/arm/src/arm/up_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..07eba7341d9a85a59703fbc936ad87510eb586c4 --- /dev/null +++ b/arch/arm/src/arm/up_elf.c @@ -0,0 +1,271 @@ +/**************************************************************************** + * arch/arm/src/arm/up_elf.c + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *ehdr) +{ + /* Make sure it's an ARM executable */ + + if (ehdr->e_machine != EM_ARM) + { + bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine); + return -ENOEXEC; + } + + /* Make sure that 32-bit objects are supported */ + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + { + bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]); + return -ENOEXEC; + } + + /* Verify endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG + if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) +#else + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) +#endif + { + bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]); + return -ENOEXEC; + } + + /* Make sure the entry point address is properly aligned */ + + if ((ehdr->e_entry & 3) != 0) + { + bdbg("Entry point is not properly aligned: %08x\n", ehdr->e_entry); + return -ENOEXEC + } + + /* TODO: Check ABI here. */ + return OK; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + int32_t offset; + unsigned int relotype; + + /* All relocations depend upon having valid symbol information */ + + relotype = ELF32_R_TYPE(rel->r_info); + if (sym == NULL && relotype != R_ARM_NONE) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (relotype) + { + case R_ARM_NONE: + { + /* No relocation */ + } + break; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + { + bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = (*(uint32_t *)addr & 0x00ffffff) << 2; + if (offset & 0x02000000) + { + offset -= 0x04000000; + } + + offset += sym->st_value - addr; + if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000) + { + bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + offset >>= 2; + + *(uint32_t *)addr &= 0xff000000; + *(uint32_t *)addr |= offset & 0x00ffffff; + } + break; + + case R_ARM_ABS32: + case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ + { + bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value; + } + break; + + case R_ARM_V4BX: + { + bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n", + (long)addr, (long)(*(uint32_t *)addr)); + + /* Preserve only Rm and the condition code */ + + *(uint32_t *)addr &= 0xf000000f; + + /* Change instruction to 'mov pc, Rm' */ + + *(uint32_t *)addr |= 0x01a0f000; + } + break; + + case R_ARM_PREL31: + { + bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + offset = *(uint32_t *)addr + sym->st_value - addr; + *(uint32_t *)addr = offset & 0x7fffffff; + } + break; + + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = *(uint32_t *)addr; + offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); + offset = (offset ^ 0x8000) - 0x8000; + + offset += sym->st_value; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + { + offset >>= 16; + } + + *(uint32_t *)addr &= 0xfff0f000; + *(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff); + } + break; + + default: + bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info)); + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("RELA relocation not supported\n"); + return -ENOSYS; +} diff --git a/arch/arm/src/arm/up_fullcontextrestore.S b/arch/arm/src/arm/up_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..50fdd745dd3578dea9da5a6c02af0783acf78fc2 --- /dev/null +++ b/arch/arm/src/arm/up_fullcontextrestore.S @@ -0,0 +1,118 @@ +/************************************************************************** + * arch/arm/src/arm/up_fullcontextrestore.S + * + * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_fullcontextrestore + **************************************************************************/ + + .globl up_fullcontextrestore + .type up_fullcontextrestore, function +up_fullcontextrestore: + + /* On entry, a1 (r0) holds address of the register save area */ + + /* Recover all registers except for r0, r1, R15, and CPSR */ + + add r1, r0, #(4*REG_R2) /* Offset to REG_R2 storage */ + ldmia r1, {r2-r14} /* Recover registers */ + + /* Create a stack frame to hold the PC */ + + sub sp, sp, #(3*4) /* Frame for three registers */ + ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */ + str r1, [sp] /* Save it at the top of the stack */ + ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */ + str r1, [sp, #4] /* Save it in the stack */ + ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */ + str r1, [sp, #8] /* Save it at the bottom of the frame */ + + /* Now we can restore the CPSR. We wait until we are completely + * finished with the context save data to do this. Restore the CPSR + * may re-enable and interrupts and we could be in a context + * where the save structure is only protected by interrupts being + * disabled. + */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ + msr cpsr, r1 /* Set the CPSR */ + + /* Now recover r0 and r1 */ + + ldr r0, [sp] + ldr r1, [sp, #4] + add sp, sp, #(2*4) + + /* Then return to the address at the stop of the stack, + * destroying the stack frame + */ + + ldr pc, [sp], #4 + .size up_fullcontextrestore, . - up_fullcontextrestore + diff --git a/arch/arm/src/arm/up_head.S b/arch/arm/src/arm/up_head.S new file mode 100644 index 0000000000000000000000000000000000000000..296c30656fde3f976221c76202a09d51da7e199a --- /dev/null +++ b/arch/arm/src/arm/up_head.S @@ -0,0 +1,705 @@ +/**************************************************************************** + * arch/arm/src/arm/up_head.S + * + * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm.h" +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifdef CONFIG_PAGING +# include +# include "pg_macros.h" +#endif + +/********************************************************************************** + * Configuration + **********************************************************************************/ + +#undef ALIGNMENT_TRAP +#undef CPU_DCACHE_WRITETHROUGH +#undef CPU_CACHE_ROUND_ROBIN +#undef CPU_DCACHE_DISABLE +#undef CPU_ICACHE_DISABLE + +/* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Initialize the .data section in RAM, and + * - Clear .bss section + */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH +# error "Configuration not implemented" +# define CONFIG_SDRAM 1 + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 2. We boot in FLASH but copy ourselves to DRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Copy ourself to DRAM (after mapping it), and + * - Clear .bss section + * + * In this case, we assume that the logic within this file executes from FLASH. + */ + +#elif defined(CONFIG_BOOT_COPYTORAM) +# error "configuration not implemented +# define CONFIG_SDRAM 1 + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning) + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM + * was initialized by the boot loader, and this boot logic must: + * + * - Clear .bss section + */ + +#else + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of RAM is the same as the physical + * beginning of RAM. + */ + +# if !defined(CONFIG_RAM_START) || !defined(CONFIG_RAM_VSTART) +# error "CONFIG_RAM_START or CONFIG_RAM_VSTART is not defined" +# endif + +# if CONFIG_RAM_START == CONFIG_RAM_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +#endif + +/* For each page table offset, the following provide (1) the physical address of + * the start of the page table and (2) the number of page table entries in the + * first page table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * NPAGE1=(256 -((a) & 0x000003ff) >> 2) NPAGE1=1-256 + * Fine: PG_L1_PADDRMASK=0xfffff000 + * NPAGE1=(1024 -((a) & 0x00000fff) >> 2) NPAGE1=1-1024 + */ + +#ifdef CONFIG_PAGING +# define PG_L2_TEXT_PBASE (PG_L2_TEXT_PADDR & PG_L1_PADDRMASK) +# define PG_L2_TEXT_NPAGE1 (PTE_NPAGES - ((PG_L2_TEXT_PADDR & ~PG_L1_PADDRMASK) >> 2)) +# define PG_L2_PGTABLE_PBASE (PG_L2_PGTABLE_PADDR & PG_L1_PADDRMASK) +# define PG_L2_PGTABLE_NPAGE1 (PTE_NPAGES - ((PG_L2_PGTABLE_PADDR & ~PG_L1_PADDRMASK) >> 2)) +# define PG_L2_DATA_PBASE (PG_L2_DATA_PADDR & PG_L1_PADDRMASK) +# define PG_L2_DATA_NPAGE1 (PTE_NPAGES - ((PG_L2_DATA_PADDR & ~PG_L1_PADDRMASK) >> 2)) +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RX_NSECTIONS determines the number of 1Mb sections to map for the + * Read/eXecute address region. This is based on CONFIG_RAM_SIZE. For most + * ARM9 architectures, CONFIG_RAM_SIZE describes the size of installed SDRAM. + * But for other architectures, this might refer to the size of FLASH or + * SRAM regions. (bad choice of naming). + */ + +#define RX_NSECTIONS ((CONFIG_RAM_SIZE+0x000fffff) >> 20) + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/* The ARM9 L1 page table can be placed at the beginning or at the end of + * the RAM space. This decision is based on the placement of the vector + * area: If the vectors are place in low memory at address 0x0000 0000, then + * the page table is placed in high memory; if the vectors are placed in + * high memory at address 0xfff0 0000, then the page table is locating at + * the beginning of RAM. + * + * For the special case where (1) the program executes out of RAM, and (2) + * the page is located at the beginning of RAM (i.e., the high vector case), + * then the following macro can easily find the physical address of the + * section that includes the first part of the text region: Since the page + * table is closely related to the NuttX base address in this case, we can + * convert the page table base address to the base address of the section + * containing both. + */ + +/* REVISIT: This works now of the low vector case only because the RAM + * sizes that we have been dealing with are less then 1MB so that both the + * page table and the vector table are in the same 1MB RAM block. But + * this will certainly break later. Hence, the annoying warning. + */ + +#ifdef CONFIG_ARCH_LOWVECTORS +# warning "REVISIT" +#endif + +//#ifndef CONFIG_ARCH_LOWVECTORS + .macro mksection, section, pgtable + bic \section, \pgtable, #0x000ff000 + .endm +//#endif + +/* This macro will modify r0, r1, r2 and r14 */ + +#ifdef CONFIG_DEBUG + .macro showprogress, code + mov r0, #\code + bl up_lowputc + .endm +#else + .macro showprogress, code + .endm +#endif + +/**************************************************************************** + * Name: __start + ****************************************************************************/ + +/* We assume the bootloader has already initialized most of the h/w for us + * and that only leaves us having to do some os specific things below. + */ + .text + .global __start + .type __start, #function +__start: + /* Make sure that we are in SVC mode with all IRQs disabled */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, r0 + + /* Initialize DRAM using a macro provided by board-specific logic */ + +#ifdef CONFIG_SDRAM + config_sdram +#endif + /* Clear the 16K level 1 page table */ + + ldr r4, .LCppgtable /* r4=phys. page table */ +#ifndef CONFIG_ARCH_ROMPGTABLE + mov r0, r4 + mov r1, #0 + add r2, r0, #PGTABLE_SIZE +.Lpgtableclear: + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + teq r0, r2 + bne .Lpgtableclear + + /* Create identity mapping for first MB of the .text section to support + * this startup logic executing out of the physical address space. This + * identity mapping will be removed by .Lvstart (see below). Of course, + * we would only do this if the physical-virtual mapping is not already + * the identity mapping. + */ + +#ifndef CONFIG_IDENTITY_TEXTMAP + mksection r0, r4 /* r0=phys. base section */ + ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */ + add r3, r1, r0 /* r3=flags + base */ + str r3, [r4, r0, lsr #18] /* identity mapping */ +#endif + +#ifdef CONFIG_PAGING + + /* Map the read-only .text region in place. This must be done + * before the MMU is enabled and the virtual addressing takes + * effect. First populate the L1 table for the locked and paged + * text regions. + * + * We could probably make the pg_l1span and pg_l2map macros into + * call-able subroutines, but we would have to be carefully during + * this phase while we are operating in a physical address space. + * + * NOTE: That the value of r5 (L1 table base address) must be + * preserved through the following. + */ + + adr r0, .Ltxtspan + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 + + /* Then populate the L2 table for the locked text region only. */ + + adr r0, .Ltxtmap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r5 + + /* Make sure that the page table is itself mapped and and read/write-able. + * First, populate the L1 table: + */ + + adr r0, .Lptabspan + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 + + /* Then populate the L2 table. */ + + adr r0, .Lptabmap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r5 + +#else /* CONFIG_PAGING */ + +#ifdef CONFIG_IDENTITY_TEXTMAP + mksection r0, r4 /* r0=phys. base section */ + ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */ + add r3, r1, r0 /* r3=flags + base */ +#endif + + /* Create a virtual single section mapping for the first MB of the .text + * address space. Now, we have the first 1MB mapping to both physical and + * virtual addresses. The rest of the .text mapping will be completed in + * .Lvstart once we have moved the physical mapping out of the way. + * + * Here we expect to have: + * r4 = Address of the base of the L1 table + */ + + ldr r2, .LCvpgtable /* r2=virt. page table */ + mksection r0, r2 /* r0=virt. base section */ + str r3, [r4, r0, lsr #18] /* identity mapping */ + + /* NOTE: No .data/.bss access should be attempted. This temporary mapping + * can only be assumed to cover the initial .text region. + */ + +#endif /* CONFIG_PAGING */ +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* The following logic will set up the ARM920/ARM926 for normal operation. + * + * Here we expect to have: + * r4 = Address of the base of the L1 table + */ + + mov r0, #0 + mcr p15, 0, r0, c7, c7 /* Invalidate I,D caches */ + mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ + mcr p15, 0, r0, c8, c7 /* Invalidate I,D TLBs */ + mcr p15, 0, r4, c2, c0 /* Load page table pointer */ + +#ifdef CPU_DCACHE_WRITETHROUGH + mov r0, #4 /* Disable write-back on caches explicitly */ + mcr p15, 7, r0, c15, c0, 0 +#endif + + /* Enable the MMU and caches + * lr = Resume at .Lvstart with the MMU enabled + */ + + ldr lr, .LCvstart /* Abs. virtual address */ + + mov r0, #0x1f /* Domains 0, 1 = client */ + mcr p15, 0, r0, c3, c0 /* Load domain access register */ + mrc p15, 0, r0, c1, c0 /* Get control register */ + + /* Clear bits (see arm.h) + * + * CR_R - ROM MMU protection + * CR_F - Implementation defined + * CR_Z - Implementation defined + * + * CR_A - Alignment abort enable + * CR_C - Dcache enable + * CR_W - Write buffer enable + * + * CR_I - Icache enable + */ + + bic r0, r0, #(CR_R|CR_F|CR_Z) + bic r0, r0, #(CR_A|CR_C|CR_W) + bic r0, r0, #(CR_I) + + /* Set bits (see arm.h) + * + * CR_M - MMU enable + * CR_P - 32-bit exception handler + * CR_D - 32-bit data address range + */ + + orr r0, r0, #(CR_M|CR_P|CR_D) + + /* In most architectures, vectors are relocated to 0xffff0000. + * -- but not all + * + * CR_S - System MMU protection + * CR_V - Vectors relocated to 0xffff0000 + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + orr r0, r0, #(CR_S|CR_V) +#else + orr r0, r0, #(CR_S) +#endif + /* CR_RR - Round Robin cache replacement */ + +#ifdef CPU_CACHE_ROUND_ROBIN + orr r0, r0, #(CR_RR) +#endif + /* CR_C - Dcache enable */ + +#ifndef CPU_DCACHE_DISABLE + orr r0, r0, #(CR_C) +#endif + /* CR_C - Dcache enable */ + +#ifndef CPU_ICACHE_DISABLE + orr r0, r0, #(CR_I) +#endif + /* CR_A - Alignment abort enable */ + +#ifdef ALIGNMENT_TRAP + orr r0, r0, #(CR_A) +#endif + mcr p15, 0, r0, c1, c0, 0 /* write control reg */ + + /* Get TMP=2 Processor ID register */ + + mrc p15, 0, r1, c0, c0, 0 /* read id reg */ + mov r1,r1 /* Null-avoiding nop */ + mov r1,r1 /* Null-avoiding nop */ + + /* And "jump" to .Lvstart */ + + mov pc, lr + +/**************************************************************************** + * PC_Relative Data + ****************************************************************************/ + + /* Most addresses are all virtual address */ + + .type .LCvstart, %object +.LCvstart: + .long .Lvstart + +#ifndef CONFIG_ARCH_ROMPGTABLE + .type .LCmmuflags, %object +.LCmmuflags: + .long MMU_MEMFLAGS /* MMU flags for memory sections */ +#endif + + .type .LCppgtable, %object +.LCppgtable: + .long PGTABLE_BASE_PADDR /* Physical start of page table */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + .type .LCvpgtable, %object +.LCvpgtable: + .long PGTABLE_BASE_VADDR /* Virtual start of page table */ +#endif + +#ifdef CONFIG_PAGING + +.Ltxtspan: + .long PG_L1_TEXT_PADDR /* Physical address in the L1 table */ + .long PG_L2_TEXT_PBASE /* Physical address of the start of the L2 page table */ + .long PG_TEXT_NVPAGES /* Total (virtual) text pages to be mapped */ + .long PG_L2_TEXT_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_TEXTFLAGS /* L1 MMU flags to use */ + +.Ltxtmap: + .long PG_L2_LOCKED_PADDR /* Physical address in the L2 table */ + .long PG_LOCKED_PBASE /* Physical address of locked base memory */ + .long CONFIG_PAGING_NLOCKED /* Number of pages in the locked region */ + .long MMU_L2_TEXTFLAGS /* L2 MMU flags to use */ + +.Lptabspan: + .long PG_L1_PGTABLE_PADDR /* Physical address in the L1 table */ + .long PG_L2_PGTABLE_PBASE /* Physical address of the start of the L2 page table */ + .long PG_PGTABLE_NPAGES /* Total mapped page table pages */ + .long PG_L2_PGTABLE_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_PGTABFLAGS /* L1 MMU flags to use */ + +.Lptabmap: + .long PG_L2_PGTABLE_PADDR /* Physical address in the L2 table */ + .long PGTABLE_BASE_PADDR /* Physical address of the page table memory */ + .long PG_PGTABLE_NPAGES /* Total mapped page table pages */ + .long MMU_L2_PGTABFLAGS /* L2 MMU flags to use */ + +#endif /* CONFIG_PAGING */ + .size __start, .-__start + +/**************************************************************************** + * Name: .Lvstart + ***************************************************************************/ + +/* The following is executed after the MMU has been enabled. This uses + * absolute addresses; this is not position independent. + */ + .align 5 + .local .Lvstart + .type .Lvstart, %function +.Lvstart: + + /* Remove the temporary mapping (if one was made). The following assumes + * that the total RAM size is > 1Mb and extends that initial mapping to + * cover additional RAM sections. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +#ifndef CONFIG_IDENTITY_TEXTMAP + ldr r4, .LCvpgtable /* r4=virtual page table */ + ldr r1, .LCppgtable /* r1=phys. page table */ + mksection r3, r1 /* r2=phys. base addr */ + mov r0, #0 /* flags + base = 0 */ + str r0, [r4, r3, lsr #18] /* Undo identity mapping */ +#endif + +#if defined(CONFIG_PAGING) + /* Populate the L1 table for the data region */ + + adr r0, .Ldataspan + ldmia r0, {r0, r1, r2, r3, r4} + pg_l1span r0, r1, r2, r3, r4, r5 + + /* Populate the L2 table for the data region */ + + adr r0, .Ldatamap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r4 + +#elif defined(CONFIG_BOOT_RUNFROMFLASH) +# error "Logic not implemented" +#else + /* Get the following value (if we did not already do so above): + * + * R4 = Virtual address of the page table + * R3 = Physical address of the NuttX execution space (aligned to a + * one megabyte addres boundary + */ + +#ifdef CONFIG_IDENTITY_TEXTMAP + ldr r4, .LCvpgtable /* r4=virtual page table */ +#endif + ldr r3, .LCnuttxpaddr /* r3=Aligned Nuttx start address (physical) */ + + /* Now setup the page tables for our normal mapped execution region. + * We round NUTTX_START_VADDR down to the nearest megabyte boundary. + */ + + ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */ + add r3, r3, r1 /* r3=flags + base */ + + add r0, r4, #(NUTTX_START_VADDR & 0xfff00000) >> 18 + str r3, [r0], #4 + + /* Now map the remaining RX_NSECTIONS-1 sections of the executable + * memory region. + */ + + .rept RX_NSECTIONS-1 + add r3, r3, #SECTION_SIZE + str r3, [r0], #4 + .endr + + /* If we are executing from RAM with a fixed page configuration, then + * we can assume that the above contiguous mapping included all of the + * .text, .data, .bss, heap, etc. But if we are executing from FLASH, + * then the RAM area is probably in a separate physical address region + * and will require a separate mapping. Or, if we are supporting on-demand + * paging of the .text region, then the RAM-based .data/.bss/heap section + * will still probably be located in a separate (virtual) address region. + */ + +#endif /* CONFIG_PAGING */ +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* Zero BSS and set up the stack pointer */ + + adr r0, .Linitparms + ldmia r0, {r0, r1, sp} + + /* Clear the frame pointer and .bss */ + + mov fp, #0 + +.Lbssinit: + cmp r0, r1 /* Clear up to _bss_end_ */ + strcc fp, [r0],#4 + bcc .Lbssinit + + /* If the .data section is in a separate, unitialized address space, + * then we will also need to copy the initial values of of the .data + * section from the .text region into that .data region. This would + * be the case if we are executing from FLASH and the .data section + * lies in a different physical address region OR if we are support + * on-demand paging and the .data section lies in a different virtual + * address region. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) || defined(CONFIG_PAGING) + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +1: ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 1b +#endif + + /* Perform early C-level, platform-specific initialization */ + + bl up_boot + +#ifdef CONFIG_STACK_COLORATION + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +2: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 2b /* Bottom of the loop */ + +#endif + + /* Finally branch to the OS entry point */ + + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ + + /* Text-section constants: + * + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * + * The idle task stack starts at the end of BSS and is of size + * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + +.Linitparms: + .long _sbss + .long _ebss + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +#if !defined(CONFIG_PAGING) && !defined(CONFIG_BOOT_RUNFROMFLASH) + +.LCnuttxpaddr: + .long NUTTX_START_PADDR & 0xfff00000 + +#endif + +#ifdef CONFIG_PAGING + +.Ldataspan: + .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ + .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ + +.Ldatamap: + .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ + .long PG_DATA_PBASE /* Physical address of data memory */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ + +#endif /* CONFIG_PAGING */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) || defined(CONFIG_PAGING) +.Ldatainit: + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata +#endif + +#ifdef CONFIG_STACK_COLORATION + .type .Lstkinit, %object +.Lstkinit: + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif + .size .Lvstart, .-.Lvstart + + /* Data section variables */ + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to .Linitparms + * above. + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/arm/src/arm/up_initialstate.c b/arch/arm/src/arm/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..2ff8cedbf37fd415a08777048c00dcf8d903d4d4 --- /dev/null +++ b/arch/arm/src/arm/up_initialstate.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * arch/arm/src/arm/up_initialstate.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + uint32_t cpsr; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC + if (tcb->dspace != NULL) + { + /* Set the PIC base register (probably R10) to the address of the + * alloacated D-Space region. + */ + + xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; + } +#endif + + /* Set supervisor- or user-mode, depending on how NuttX is configured and + * what kind of thread is being started. Disable FIQs in any event + */ + +#ifdef CONFIG_BUILD_KERNEL + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) + { + /* It is a kernel thread.. set supervisor mode */ + + cpsr = SVC_MODE | PSR_F_BIT; + } + else + { + /* It is a normal task or a pthread. Set user mode */ + + cpsr = USR_MODE | PSR_F_BIT; + } +#else + /* If the kernel build is not selected, then all threads run in + * supervisor-mode. + */ + + cpsr = SVC_MODE | PSR_F_BIT; +#endif + + /* Enable or disable interrupts, based on user configuration */ + +# ifdef CONFIG_SUPPRESS_INTERRUPTS + cpsr |= PSR_I_BIT; +# endif + + xcp->regs[REG_CPSR] = cpsr; +} + diff --git a/arch/arm/src/arm/up_nommuhead.S b/arch/arm/src/arm/up_nommuhead.S new file mode 100644 index 0000000000000000000000000000000000000000..04c5205efe057ee58a52286f961e40e3a65624ad --- /dev/null +++ b/arch/arm/src/arm/up_nommuhead.S @@ -0,0 +1,196 @@ +/**************************************************************************** + * arch/arm/src/arm/up_nommuhead.S + * + * Copyright (C) 2007, 2009-2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Macros + ****************************************************************************/ + + /* This macro will modify r0, r1, r2 and r14 */ + +#ifdef CONFIG_DEBUG + .macro showprogress, code + mov r0, #\code + bl up_lowputc + .endm +#else + .macro showprogress, code + .endm +#endif + +/**************************************************************************** + * OS Entry Point + ****************************************************************************/ + +/* We assume the bootloader has already initialized most of the h/w for + * us and that only leaves us having to do some os specific things + * below. + */ + .text + .global __start + .type __start, #function +__start: + + /* First, setup initial processor mode */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT ) + msr cpsr, r0 + + showprogress 'A' + + /* Setup system stack (and get the BSS range) */ + + adr r0, .Lbssinit + ldmia r0, {r4, r5, sp} + + /* Clear system BSS section */ + + mov r0, #0 +1: cmp r4, r5 + strcc r0, [r4], #4 + bcc 1b + + showprogress 'B' + + /* Copy system .data sections to new home in RAM. */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +1: ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 1b + +#endif + + /* Perform early serial initialization */ + + mov fp, #0 + +#ifdef USE_EARLYSERIALINIT + bl up_earlyserialinit +#endif + +#ifdef CONFIG_DEBUG + mov r0, #'C' + bl up_putc + mov r0, #'\n' + bl up_putc +#endif + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + bl board_autoled_initialize +#endif + +#ifdef CONFIG_STACK_COLORATION + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +2: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 2b /* Bottom of the loop */ + +#endif + + /* Finally branch to the OS entry point */ + + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ + + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_IDLETHREAD_STACKSIZE. The heap continues + * from there until the end of memory. See g_idle_topstack + * below. + */ + +.Lbssinit: + .long _sbss + .long _ebss + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +#ifdef CONFIG_BOOT_RUNFROMFLASH +.Ldatainit: + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata +#endif + +#ifdef CONFIG_STACK_COLORATION + .type .Lstkinit, %object +.Lstkinit: + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif + .size __start, .-__start + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to LCO + * above. + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/arm/up_pginitialize.c b/arch/arm/src/arm/up_pginitialize.c new file mode 100644 index 0000000000000000000000000000000000000000..5470f73e3548182a37f07dc9fc806d7631300b21 --- /dev/null +++ b/arch/arm/src/arm/up_pginitialize.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/arm/up_pginitialize.c + * Initialize the MMU for on-demand paging support. + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_pginitialize() + * + * Description: + * Initialize the MMU for on-demand paging support.. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. This function will crash if any errors are detected during MMU + * initialization + * + * Assumptions: + * - Called early in the platform initialization sequence so that no special + * concurrency protection is required. + * + ****************************************************************************/ + +void up_pginitialize(void) +{ + /* None needed at present. This file is just retained in case the need + * arises in the future. Nothing calls up_pginitialize() now. If needed, + * if should be called early in up_boot.c to assure that all paging is + * ready. + */ +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/arm/up_prefetchabort.c b/arch/arm/src/arm/up_prefetchabort.c new file mode 100644 index 0000000000000000000000000000000000000000..ed2bfb1bf9db8035dfb43915edf2ca23ad37051a --- /dev/null +++ b/arch/arm/src/arm/up_prefetchabort.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/arm/up_prefetchabort.c + * + * Copyright (C) 2007-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include +#ifdef CONFIG_PAGING +# include +#endif + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_prefetchabort + * + * Description; + * This is the prefetch abort exception handler. The ARM prefetch abort + * exception occurs when a memory fault is detected during an an + * instruction fetch. + * + ****************************************************************************/ + +void up_prefetchabort(uint32_t *regs) +{ +#ifdef CONFIG_PAGING + uint32_t *savestate; + + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + savestate = (uint32_t *)CURRENT_REGS; +#endif + CURRENT_REGS = regs; + +#ifdef CONFIG_PAGING + /* Get the (virtual) address of instruction that caused the prefetch abort. + * When the exception occurred, this address was provided in the lr register + * and this value was saved in the context save area as the PC at the + * REG_R15 index. + * + * Check to see if this miss address is within the configured range of + * virtual addresses. + */ + + pglldbg("VADDR: %08x VBASE: %08x VEND: %08x\n", + regs[REG_PC], PG_PAGED_VBASE, PG_PAGED_VEND); + + if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND) + { + /* Save the offending PC as the fault address in the TCB of the currently + * executing task. This value is, of course, already known in regs[REG_R15], + * but saving it in this location will allow common paging logic for both + * prefetch and data aborts. + */ + + struct tcb_s *tcb = this_task(); + tcb->xcp.far = regs[REG_R15]; + + /* Call pg_miss() to schedule the page fill. A consequences of this + * call are: + * + * (1) The currently executing task will be blocked and saved on + * on the g_waitingforfill task list. + * (2) An interrupt-level context switch will occur so that when + * this function returns, it will return to a different task, + * most likely the page fill worker thread. + * (3) The page fill worker task has been signalled and should + * execute immediately when we return from this exception. + */ + + pg_miss(); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + } + else +#endif + { + lldbg("Prefetch abort. PC: %08x\n", regs[REG_PC]); + PANIC(); + } +} diff --git a/arch/arm/src/arm/up_releasepending.c b/arch/arm/src/arm/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..4defb895e00e0398df6d95c135f521300e313211 --- /dev/null +++ b/arch/arm/src/arm/up_releasepending.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/src/arm/up_releasepending.c + * + * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/arm/up_reprioritizertr.c b/arch/arm/src/arm/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..8f6b739d08dc5cb7265c9234dcc93cb9b1faebe1 --- /dev/null +++ b/arch/arm/src/arm/up_reprioritizertr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/arm/src/arm/up_reprioritizertr.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/arm/src/arm/up_saveusercontext.S b/arch/arm/src/arm/up_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..bb812e53a216cd9a3757c44aa168daa1cbdc6320 --- /dev/null +++ b/arch/arm/src/arm/up_saveusercontext.S @@ -0,0 +1,119 @@ +/************************************************************************** + * arch/arm/src/arm/up_saveusercontext.S + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_saveusercontext + **************************************************************************/ + + .text + .globl up_saveusercontext + .type up_saveusercontext, function +up_saveusercontext: + /* On entry, a1 (r0) holds address of struct xcptcontext. + * Offset to the user region. + */ + + /* Make sure that the return value will be non-zero (the + * value of the other volatile registers don't matter -- + * r1-r3, ip). This function is called throught the + * noraml C calling conventions and the values of these + * registers cannot be assumed at the point of setjmp + * return. + */ + + mov ip, #1 + str ip, [r0, #(4*REG_R0)] + + /* Save the volatile registers (plus r12 which really + * doesn't need to be saved) + */ + + add r1, r0, #(4*REG_R4) + stmia r1, {r4-r14} + + /* Save the current cpsr */ + + mrs r2, cpsr /* R3 = CPSR value */ + add r1, r0, #(4*REG_CPSR) + str r2, [r1] + + /* Finally save the return address as the PC so that we + * return to the exit from this function. + */ + + add r1, r0, #(4*REG_PC) + str lr, [r1] + + /* Return 0 */ + + mov r0, #0 /* Return value == 0 */ + mov pc, lr /* Return */ + .size up_saveusercontext, . - up_saveusercontext + diff --git a/arch/arm/src/arm/up_schedulesigaction.c b/arch/arm/src/arm/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..3972b7792120a9ebe55b3ae569862e5b259c90cd --- /dev/null +++ b/arch/arm/src/arm/up_schedulesigaction.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/arm/up_schedulesigaction.c + * + * Copyright (C) 2007-2010, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm.h" +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!CURRENT_REGS) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * CURRENT_REGS does not refer to the thread of this_task()! + */ + + else + { + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = CURRENT_REGS[REG_PC]; + tcb->xcp.saved_cpsr = CURRENT_REGS[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver; + CURRENT_REGS[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/arm/up_sigdeliver.c b/arch/arm/src/arm/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..c03511d4df485c2648ae567bcbdb43656196e8d7 --- /dev/null +++ b/arch/arm/src/arm/up_sigdeliver.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/arm/up_sigdeliver.c + * + * Copyright (C) 2007-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copyfullstate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_CPSR] = rtcb->xcp.saved_cpsr; + + /* Get a local copy of the sigdeliver function pointer. we do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_CPSR]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/arm/src/arm/up_syscall.c b/arch/arm/src/arm/up_syscall.c new file mode 100644 index 0000000000000000000000000000000000000000..07d8ac26d229a90eff58544e4349008ffde9a7d4 --- /dev/null +++ b/arch/arm/src/arm/up_syscall.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/arm/up_syscall.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * vectors + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_syscall + * + * Description: + * SWI interrupts will vection here with insn=the SWI + * instruction and xcp=the interrupt context + * + * The handler may get the SWI number be de-referencing + * the return address saved in the xcp and decoding + * the SWI instruction + * + ****************************************************************************/ + +void up_syscall(uint32_t *regs) +{ + lldbg("Syscall from 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); +} diff --git a/arch/arm/src/arm/up_unblocktask.c b/arch/arm/src/arm/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..12cb984d831bb31fc86a9d26052d0ae87972b139 --- /dev/null +++ b/arch/arm/src/arm/up_unblocktask.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/arm/src/arm/up_unblocktask.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/arm/up_undefinedinsn.c b/arch/arm/src/arm/up_undefinedinsn.c new file mode 100644 index 0000000000000000000000000000000000000000..99b1e3fc66b1bca83ed545f1f9e6442f24d65ad2 --- /dev/null +++ b/arch/arm/src/arm/up_undefinedinsn.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/arm/up_undefinedinsn.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_undefinedinsn + ****************************************************************************/ + +void up_undefinedinsn(uint32_t *regs) +{ + lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); +} diff --git a/arch/arm/src/arm/up_va2pte.c b/arch/arm/src/arm/up_va2pte.c new file mode 100644 index 0000000000000000000000000000000000000000..16230f82850bd286999b19bb4bf481a0153eb460 --- /dev/null +++ b/arch/arm/src/arm/up_va2pte.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/arm/up_va2pte.c + * Utility to map a virtual address to a L2 page table entry. + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "pg_macros.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_va2pte() + * + * Description: + * Convert a virtual address within the paged text region into a pointer to + * the corresponding page table entry. + * + * Input Parameters: + * vaddr - The virtual address within the paged text region. + * + * Returned Value: + * A pointer to the corresponding page table entry. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +uint32_t *up_va2pte(uintptr_t vaddr) +{ + uint32_t L1; + uint32_t *L2; + unsigned int ndx; + + /* The virtual address is expected to lie in the paged text region */ + + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Get the L1 table entry associated with this virtual address */ + + L1 = *(uint32_t *)PG_POOL_VA2L1VADDR(vaddr); + + /* Get the address of the L2 page table from the L1 entry */ + + L2 = (uint32_t *)PG_POOL_L12VPTABLE(L1); + + /* Get the index into the L2 page table. Each L1 entry maps + * 256 x 4Kb or 1024 x 1Kb pages. + */ + + ndx = (vaddr & 0x000fffff) >> PAGESHIFT; + + /* Return true if this virtual address is mapped. */ + + return &L2[ndx]; +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/arm/up_vectoraddrexcptn.S b/arch/arm/src/arm/up_vectoraddrexcptn.S new file mode 100644 index 0000000000000000000000000000000000000000..6348cd626df5d79cf8530ad03dc32c7a5200a779 --- /dev/null +++ b/arch/arm/src/arm/up_vectoraddrexcptn.S @@ -0,0 +1,83 @@ +/************************************************************************************ + * arch/arm/src/arm/up_vectoraddrexceptn.S + * + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "up_arch.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Assembly Macros + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_vectoraddrexcption + * + * Description: + * Shouldn't happen. This exception handler is in a separate file from other + * vector handlers because some processors (e.g., lpc2148) do not support the + * the Address Exception vector. + * + ************************************************************************************/ + + .globl up_vectoraddrexcptn + .type up_vectoraddrexcptn, %function +up_vectoraddrexcptn: + b up_vectoraddrexcptn + .size up_vectoraddrexcptn, . - up_vectoraddrexcptn + .end diff --git a/arch/arm/src/arm/up_vectors.S b/arch/arm/src/arm/up_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..ff3bb56e5c0fafefff19281af5d62dca09dc364b --- /dev/null +++ b/arch/arm/src/arm/up_vectors.S @@ -0,0 +1,447 @@ +/************************************************************************************ + * arch/arm/src/arm/up_vectors.S + * + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "arm.h" +#include "up_arch.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + + .data +g_irqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_undeftmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_aborttmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ + +/************************************************************************************ + * Assembly Macros + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_vectorirq + * + * Description: + * Interrupt excetpion. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl up_vectorirq + .type up_vectorirq, %function +up_vectorirq: + /* On entry, we are in IRQ mode. We are free to use + * the IRQ mode r13 and r14. + */ + + ldr r13, .Lirqtmp + sub lr, lr, #4 + str lr, [r13] @ save lr_IRQ + mrs lr, spsr + str lr, [r13, #4] @ save spsr_IRQ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lirqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the IRQ handler with interrupts disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lirqstackbase /* SP = interrupt stack base */ + str r0, [sp] /* Save the user stack pointer */ + bl up_decodeirq /* Call the handler */ + ldr sp, [sp] /* Restore the user stack pointer */ +#else + bl up_decodeirq /* Call the handler */ +#endif + + /* Restore the CPSR, SVC mode registers and return */ +.Lnoirqset: + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lirqtmp: + .word g_irqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lirqstackbase: + .word g_intstackbase +#endif + .size up_vectorirq, . - up_vectorirq + .align 5 + +/************************************************************************************ + * Function: up_vectorswi + * + * Description: + * SWI interrupt. We enter the SWI in SVC mode. + * + ************************************************************************************/ + + .globl up_vectorswi + .type up_vectorswi, %function +up_vectorswi: + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp), r14(lr), r15(pc) + * and CPSR in r1-r4 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 /* R14 is altered on return from SWI */ + mov r3, r14 /* Save r14 as the PC as well */ + mrs r4, spsr /* Get the saved CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the SWI handler with interrupts disabled. + * void up_syscall(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_syscall /* Call the handler */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r0 + ldmia sp, {r0-r15}^ /* Return */ + .size up_vectorswi, . - up_vectorswi + + .align 5 + +/************************************************************************************ + * Name: up_vectordata + * + * Description: + * This is the data abort exception dispatcher. The ARM data abort exception occurs + * when a memory fault is detected during a data transfer. This handler saves the + * current processor state and gives control to data abort handler. This function + * is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl up_vectordata + .type up_vectordata, %function +up_vectordata: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Ldaborttmp /* Points to temp storage */ + sub lr, lr, #8 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Ldaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the data abort handler with interrupts disabled. + * void up_dataabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ +#ifdef CONFIG_PAGING + mrc p15, 0, r2, c5, c0, 0 /* Get r2=FSR */ + mrc p15, 0, r1, c6, c0, 0 /* Get R1=FAR */ +#endif + bl up_dataabort /* Call the handler */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Ldaborttmp: + .word g_aborttmp + .size up_vectordata, . - up_vectordata + + .align 5 + +/************************************************************************************ + * Name: up_vectorprefetch + * + * Description: + * This is the prefetch abort exception dispatcher. The ARM prefetch abort exception + * occurs when a memory fault is detected during an an instruction fetch. This + * handler saves the current processor state and gives control to prefetch abort + * handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC. + * + ************************************************************************************/ + + .globl up_vectorprefetch + .type up_vectorprefetch, %function +up_vectorprefetch: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Lpaborttmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lpaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the prefetch abort handler with interrupts disabled. + * void up_prefetchabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_prefetchabort /* Call the handler */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lpaborttmp: + .word g_aborttmp + .size up_vectorprefetch, . - up_vectorprefetch + + .align 5 + +/************************************************************************************ + * Name: up_vectorundefinsn + * + * Description: + * Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR, + * lr = SVC PC + * + ************************************************************************************/ + + .globl up_vectorundefinsn + .type up_vectorundefinsn, %function +up_vectorundefinsn: + /* On entry we are free to use the UND mode registers + * r13 and r14 + */ + + ldr r13, .Lundeftmp /* Points to temp storage */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lundeftmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the undef insn handler with interrupts disabled. + * void up_undefinedinsn(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_undefinedinsn /* Call the handler */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lundeftmp: + .word g_undeftmp + .size up_vectorundefinsn, . - up_vectorundefinsn + + .align 5 + +/************************************************************************************ + * Name: up_vectorfiq + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + + .globl up_vectorfiq + .type up_vectorfiq, %function +up_vectorfiq: + subs pc, lr, #4 + .size up_vectorfiq, . - up_vectorfiq + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + .globl g_intstackalloc + .type g_intstackalloc, object + .globl g_intstackbase + .type g_intstackbase, object +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) +g_intstackbase: + .skip 4 + .size g_intstackbase, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) +#endif + .end diff --git a/arch/arm/src/arm/up_vectortab.S b/arch/arm/src/arm/up_vectortab.S new file mode 100644 index 0000000000000000000000000000000000000000..026180e1d89372402cce42081c7692189b060e23 --- /dev/null +++ b/arch/arm/src/arm/up_vectortab.S @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm/src/arm/up_vectortab.S + * + * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Name: _vector_start + * + * Description: + * Vector initialization block + ****************************************************************************/ + + .globl _vector_start + +/* These will be relocated to VECTOR_BASE. */ + +_vector_start: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lswihandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + ldr pc, .Laddrexcptnhandler /* 0x14: Address exception */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl up_vectorundefinsn + .globl up_vectorswi + .globl up_vectorprefetch + .globl up_vectordata + .globl up_vectoraddrexcptn + .globl up_vectorirq + .globl up_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long up_vectorundefinsn +.Lswihandler: + .long up_vectorswi +.Lprefetchaborthandler: + .long up_vectorprefetch +.Ldataaborthandler: + .long up_vectordata +.Laddrexcptnhandler: + .long up_vectoraddrexcptn +.Lirqhandler: + .long up_vectorirq +.Lfiqhandler: + .long up_vectorfiq + + .globl _vector_end +_vector_end: + .end diff --git a/arch/arm/src/arm/vfork.S b/arch/arm/src/arm/vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..161315466fe81dd18b3bea6b31dd026500ec1244 --- /dev/null +++ b/arch/arm/src/arm/vfork.S @@ -0,0 +1,138 @@ +/************************************************************************************ + * arch/arm/src/arm/vfork.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_vfork.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .file "vfork.S" + .globl up_vfork + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the behavior is + * undefined if the process created by vfork() either modifies any data other than + * a variable of type pid_t used to store the return value from vfork(), or returns + * from the function in which vfork() was called, or calls any other function before + * successfully calling _exit() or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the vfork() + * context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and returns + * the process ID of the child process to the parent process. Otherwise, -1 is + * returned to the parent, no child process is created, and errno is set to + * indicate the error. + * + ************************************************************************************/ + + .globl vfork + .type vfork, function +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + str r4, [sp, #VFORK_R4_OFFSET] + str r5, [sp, #VFORK_R5_OFFSET] + str r6, [sp, #VFORK_R6_OFFSET] + str r7, [sp, #VFORK_R7_OFFSET] + str r8, [sp, #VFORK_R8_OFFSET] + str r9, [sp, #VFORK_R9_OFFSET] + str r10, [sp, #VFORK_R10_OFFSET] + + /* Save the frame pointer, stack pointer, and return address */ + + str fp, [sp, #VFORK_FP_OFFSET] + str r0, [sp, #VFORK_SP_OFFSET] + str lr, [sp, #VFORK_LR_OFFSET] + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Release the stack data and return the value returned by up_vfork */ + + ldr lr, [sp, #VFORK_LR_OFFSET] + add sp, sp, #VFORK_SIZEOF + mov pc, lr + .size vfork, .-vfork + .end diff --git a/arch/arm/src/armv6-m/Kconfig b/arch/arm/src/armv6-m/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ed8b54a8e1a06c89ed5864f86e1be46649e2df06 --- /dev/null +++ b/arch/arm/src/armv6-m/Kconfig @@ -0,0 +1,54 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "ARMV6M Configuration Options" + +choice + prompt "Toolchain Selection" + default ARMV6M_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS + default ARMV6M_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS + +config ARMV6M_TOOLCHAIN_ATOLLIC + bool "Atollic Lite/Pro for Windows" + depends on HOST_WINDOWS + +config ARMV6M_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + +config ARMV6M_TOOLCHAIN_CODEREDL + bool "CodeRed for Linux" + depends on HOST_LINUX + +config ARMV6M_TOOLCHAIN_CODEREDW + bool "CodeRed for Windows" + depends on HOST_WINDOWS + +config ARMV6M_TOOLCHAIN_CODESOURCERYL + bool "CodeSourcery GNU toolchain under Linux" + depends on HOST_LINUX + +config ARMV6M_TOOLCHAIN_CODESOURCERYW + bool "CodeSourcery GNU toolchain under Windows" + depends on HOST_WINDOWS + +config ARMV6M_TOOLCHAIN_DEVKITARM + bool "devkitARM GNU toolchain" + depends on HOST_WINDOWS + +config ARMV6M_TOOLCHAIN_GNU_EABIL + bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi. + +config ARMV6M_TOOLCHAIN_GNU_EABIW + bool "Generic GNU EABI toolchain under Windows" + depends on HOST_WINDOWS + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi. + +endchoice diff --git a/arch/arm/src/armv6-m/Toolchain.defs b/arch/arm/src/armv6-m/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..dfe5b9c9fdbabb0087508b6495ac4be38650b63f --- /dev/null +++ b/arch/arm/src/armv6-m/Toolchain.defs @@ -0,0 +1,191 @@ +############################################################################ +# arch/arm/src/armv6-m/Toolchain.defs +# +# Copyright (C) 2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Handle old-style chip-specific toolchain names in the absence of +# a new-style toolchain specification, force the selection of a single +# toolchain and allow the selected toolchain to be overridden by a +# command-line selection. +# + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_ATOLLIC)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= ATOLLIC +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_BUILDROOT)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_CODEREDL)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= CODEREDL +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_CODEREDW)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= CODEREDW +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_CODESOURCERYL)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= CODESOURCERYL +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_CODESOURCERYW)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= CODESOURCERYW +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_DEVKITARM)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= DEVKITARM +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_GNU_EABIL)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= GNU_EABIL +endif + +ifeq ($(filter y, $(CONFIG_ARMV6M_TOOLCHAIN_GNU_EABIW)),y) + CONFIG_ARMV6M_TOOLCHAIN ?= GNU_EABIW +endif + +# +# Supported toolchains +# +# TODO - It's likely that all of these toolchains now support the +# CortexM0. Since they are all GCC-based, we could almost +# certainly simplify this further. +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# Atollic toolchain under Windows + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),ATOLLIC) + CROSSDEV ?= arm-atollic-eabi- + ARCROSSDEV ?= arm-atollic-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),BUILDROOT) + CROSSDEV ?= arm-nuttx-eabi- + ARCROSSDEV ?= arm-nuttx-eabi- + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# Code Red RedSuite under Linux + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),CODEREDL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# Code Red RedSuite under Windows + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),CODEREDW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# CodeSourcery under Linux + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),CODESOURCERYL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# CodeSourcery under Windows + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),CODESOURCERYW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# devkitARM under Windows + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),DEVKITARM) + CROSSDEV ?= arm-eabi- + ARCROSSDEV ?= arm-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),GNU_EABIL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +ifeq ($(CONFIG_ARMV6M_TOOLCHAIN),GNU_EABIW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft +endif + +# Individual tools may limit the optimizatin level but, by default, the +# optimization level will be set to to -Os + +MAXOPTIMIZATION ?= -Os diff --git a/arch/arm/src/armv6-m/exc_return.h b/arch/arm/src/armv6-m/exc_return.h new file mode 100644 index 0000000000000000000000000000000000000000..4a782942832ec2f3399ab0429aa7ffb0fd5ef2ec --- /dev/null +++ b/arch/arm/src/armv6-m/exc_return.h @@ -0,0 +1,104 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/exc_return.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV6_M_EXC_RETURN_H +#define __ARCH_ARM_SRC_ARMV6_M_EXC_RETURN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* The processor saves an EXC_RETURN value to the LR on exception entry. The + * exception mechanism relies on this value to detect when the processor has + * completed an exception handler. + * + * Bits [31:4] of an EXC_RETURN value are always 1. When the processor loads a + * value matching this pattern to the PC it detects that the operation is a not + * a normal branch operation and instead, that the exception is complete. + * Therefore, it starts the exception return sequence. + * + * Bits[3:0] of the EXC_RETURN value indicate the required return stack and eventual + * processor mode. The remaining bits of the EXC_RETURN value should be set to 1. + */ + +/* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */ + +#define EXC_RETURN_BASE 0xfffffff1 + +/* EXC_RETURN_PROCESS_STACK: The exception saved (and will restore) the hardware + * context using the process stack pointer (if not set, the context was saved + * using the main stack pointer) + */ + +#define EXC_RETURN_PROCESS_BITNO (2) +#define EXC_RETURN_PROCESS_STACK (1 << EXC_RETURN_PROCESS_BITNO) + +/* EXC_RETURN_THREAD_MODE: The exception will return to thread mode (if not set, + * return stays in handler mode). + */ + +#define EXC_RETURN_THREAD_BITNO (3) +#define EXC_RETURN_THREAD_MODE (1 << EXC_RETURN_THREAD_BITNO) + +/* EXC_RETURN_HANDLER: Return to handler mode. Exception return gets state from + * the main stack. Execution uses MSP after return. + */ + +#define EXC_RETURN_HANDLER 0xfffffff1 + +/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return gets + * state from the main stack. Execution uses MSP after return. + */ + +#define EXC_RETURN_PRIVTHR 0xfffffff9 + +/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return gets + * state from the process stack. Execution uses PSP after return. + */ + +#define EXC_RETURN_UNPRIVTHR 0xfffffffd + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_ARMV6_M_EXC_RETURN_H */ + diff --git a/arch/arm/src/armv6-m/nvic.h b/arch/arm/src/armv6-m/nvic.h new file mode 100644 index 0000000000000000000000000000000000000000..945d5c4338f27eddd05964437a3989e5459fbce5 --- /dev/null +++ b/arch/arm/src/armv6-m/nvic.h @@ -0,0 +1,400 @@ +/**************************************************************************************************** + * arch/arm/src/armv6-m/nvic.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARMV6_M_NVIC_H +#define __ARCH_ARM_SRC_COMMON_ARMV6_M_NVIC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Base addresses ***********************************************************************************/ + +#define ARMV6M_SYSCON1_BASE 0xe000e008 /* 0xe000e008-0xe000e00f System Control Block */ + /* 0xe000e010-0xe000e01f Reserved */ +#define ARMV6M_SYSTICK_BASE 0xe000e010 /* 0xe000e010-0xe000e01f SysTick system timer */ +#define ARMV6M_NVIC1_BASE 0xe000e100 /* 0xe000e100-0xe000e4ef Nested Vectored Interrupt Controller */ +#define ARMV6M_SYSCON2_BASE 0xe000ed00 /* 0xe000ed00-0xe000ed3f System Control Block */ +#define ARMV6M_NVIC2_BASE 0xe000ef00 /* 0xe000ef00-0xe000ef03 Nested Vectored Interrupt Controller */ + +/* NVIC register offsets ****************************************************************************/ +/* NVIC register offsets (all relative to ARMV6M_NVIC1_BASE) */ + +#define ARMV6M_NVIC_ISER_OFFSET 0x0000 /* Interrupt set-enable register */ +#define ARMV6M_NVIC_ICER_OFFSET 0x0080 /* Interrupt clear-enable register */ +#define ARMV6M_NVIC_ISPR_OFFSET 0x0100 /* Interrupt set-pending register */ +#define ARMV6M_NVIC_ICPR_OFFSET 0x0180 /* Interrupt clear-pending register */ +#define ARMV6M_NVIC_IPR_OFFSET(n) (0x0300 + ((n) << 2)) +# define ARMV6M_NVIC_IPR0_OFFSET 0x0300 /* Interrupt priority register 0 */ +# define ARMV6M_NVIC_IPR1_OFFSET 0x0304 /* Interrupt priority register 1 */ +# define ARMV6M_NVIC_IPR2_OFFSET 0x0308 /* Interrupt priority register 2 */ +# define ARMV6M_NVIC_IPR3_OFFSET 0x030c /* Interrupt priority register 3 */ +# define ARMV6M_NVIC_IPR4_OFFSET 0x0310 /* Interrupt priority register 4 */ +# define ARMV6M_NVIC_IPR5_OFFSET 0x0314 /* Interrupt priority register 5 */ +# define ARMV6M_NVIC_IPR6_OFFSET 0x0318 /* Interrupt priority register 6 */ +# define ARMV6M_NVIC_IPR7_OFFSET 0x031c /* Interrupt priority register 7 */ + +/* System control register offsets (all relative to ARMV6M_SYSCON2_BASE) */ + +#define ARMV6M_SYSCON_CPUID_OFFSET 0x0000 /* CPUID Register */ +#define ARMV6M_SYSCON_ICSR_OFFSET 0x0004 /* Interrupt control and state register */ +#define ARMV6M_SYSCON_AIRCR_OFFSET 0x000c /* Application interrupt and reset control register */ +#define ARMV6M_SYSCON_SCR_OFFSET 0x0010 /* System control register */ +#define ARMV6M_SYSCON_CCR_OFFSET 0x0014 /* Configuration and control register */ +#define ARMV6M_SYSCON_SHPR2_OFFSET 0x001c /* System handler priority register 2 */ +#define ARMV6M_SYSCON_SHPR3_OFFSET 0x0020 /* System handler priority register 3 */ + +/* SYSTICK register offsets (all relatvive to ARMV6M_SYSTICK_BASE) */ + +#define ARMV6M_SYSTICK_CSR_OFFSET 0x0000 /* SysTick control and status register */ +#define ARMV6M_SYSTICK_RVR_OFFSET 0x0004 /* SysTick reload value register */ +#define ARMV6M_SYSTICK_CVR_OFFSET 0x0008 /* SysTick current value register */ +#define ARMV6M_SYSTICK_CALIB_OFFSET 0x000c /* SysTick calibration value register */ + +/* Register addresses *******************************************************************************/ +/* NVIC register addresses */ + +#define ARMV6M_NVIC_ISER (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_ISER_OFFSET) +#define ARMV6M_NVIC_ICER (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_ICER_OFFSET) +#define ARMV6M_NVIC_ISPR (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_ISPR_OFFSET) +#define ARMV6M_NVIC_ICPR (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_ICPR_OFFSET) +#define ARMV6M_NVIC_IPR(n) (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR_OFFSET(n)) +# define ARMV6M_NVIC_IPR0 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR0_OFFSET) +# define ARMV6M_NVIC_IPR1 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR1_OFFSET) +# define ARMV6M_NVIC_IPR2 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR2_OFFSET) +# define ARMV6M_NVIC_IPR3 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR3_OFFSET) +# define ARMV6M_NVIC_IPR4 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR4_OFFSET) +# define ARMV6M_NVIC_IPR5 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR5_OFFSET) +# define ARMV6M_NVIC_IPR6 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR6_OFFSET) +# define ARMV6M_NVIC_IPR7 (ARMV6M_NVIC1_BASE+ARMV6M_NVIC_IPR7_OFFSET) + +/* System control register addresses */ + +#define ARMV6M_SYSCON_CPUID (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_CPUID_OFFSET) +#define ARMV6M_SYSCON_ICSR (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_ICSR_OFFSET) +#define ARMV6M_SYSCON_AIRCR (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_AIRCR_OFFSET) +#define ARMV6M_SYSCON_SCR (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_SCR_OFFSET) +#define ARMV6M_SYSCON_CCR (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_CCR_OFFSET) +#define ARMV6M_SYSCON_SHPR2 (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_SHPR2_OFFSET) +#define ARMV6M_SYSCON_SHPR3 (ARMV6M_SYSCON2_BASE+ARMV6M_SYSCON_SHPR3_OFFSET) + +/* SYSTICK register addresses */ + +#define ARMV6M_SYSTICK_CSR (ARMV6M_SYSTICK_BASE+ARMV6M_SYSTICK_CSR_OFFSET) +#define ARMV6M_SYSTICK_RVR (ARMV6M_SYSTICK_BASE+ARMV6M_SYSTICK_RVR_OFFSET) +#define ARMV6M_SYSTICK_CVR (ARMV6M_SYSTICK_BASE+ARMV6M_SYSTICK_CVR_OFFSET) +#define ARMV6M_SYSTICK_CALIB (ARMV6M_SYSTICK_BASE+ARMV6M_SYSTICK_CALIB_OFFSET) + +/* Register bit definitions *************************************************************************/ + +/* Interrupt set-enable register */ + +#define NVIC_ISER(n) (1 << (n)) /* n=0..31 */ + +/* Interrupt clear-enable register */ + +#define NVIC_ICER(n) (1 << (n)) /* n=0..31 */ + +/* Interrupt set-pending register */ + +#define NVIC_ISPR(n) (1 << (n)) /* n=0..31 */ + +/* Interrupt clear-pending register */ + +#define NVIC_ICPR(n) (1 << (n)) /* n=0..31 */ + +/* Interrupt priority registers 0-7 */ + +#define NVIC_IPR_0_SHIFT (0) /* Bits 0-7: PRI_(4n) */ +#define NVIC_IPR_0_MASK (0xff << NVIC_IPR_0_SHIFT) +# define NVIC_IPR_0(p) ((p) << NVIC_IPR_0_SHIFT) +#define NVIC_IPR_1_SHIFT (8) /* Bits 8-15: PRI_(4n+1) */ +#define NVIC_IPR_1_MASK (0xff << NVIC_IPR_1_SHIFT) +# define NVIC_IPR_1(p) ((p) << NVIC_IPR_1_SHIFT) +#define NVIC_IPR_2_SHIFT (16) /* Bits 16-23: PRI_(4n+2) */ +#define NVIC_IPR_2_MASK (0xff << NVIC_IPR_2_SHIFT) +# define NVIC_IPR_2(p) ((p) << NVIC_IPR_2_SHIFT) +#define NVIC_IPR_3_SHIFT (24) /* Bits 24-31: PRI_(4n+3) */ +#define NVIC_IPR_3_MASK (0xff << NVIC_IPR_3_SHIFT) +# define NVIC_IPR_3(p) ((p) << NVIC_IPR_3_SHIFT) + +#define NVIC_IPR0_0_SHIFT (0) /* Bits 0-7: PRI_0 */ +#define NVIC_IPR0_0_MASK (0xff << NVIC_IPR0_0_SHIFT) +# define NVIC_IPR0_0(p) ((p) << NVIC_IPR0_0_SHIFT) +#define NVIC_IPR0_1_SHIFT (8) /* Bits 8-15: PRI_1 */ +#define NVIC_IPR0_1_MASK (0xff << NVIC_IPR0_1_SHIFT) +# define NVIC_IPR0_1(p) ((p) << NVIC_IPR0_1_SHIFT) +#define NVIC_IPR0_2_SHIFT (16) /* Bits 16-23: PRI_2 */ +#define NVIC_IPR0_2_MASK (0xff << NVIC_IPR0_2_SHIFT) +# define NVIC_IPR0_2(p) ((p) << NVIC_IPR0_2_SHIFT) +#define NVIC_IPR0_3_SHIFT (24) /* Bits 24-31: PRI_3 */ +#define NVIC_IPR0_3_MASK (0xff << NVIC_IPR0_3_SHIFT) +# define NVIC_IPR0_3(p) ((p) << NVIC_IPR0_3_SHIFT) + +#define NVIC_IPR1_4_SHIFT (0) /* Bits 0-7: PRI_4 */ +#define NVIC_IPR1_4_MASK (0xff << NVIC_IPR1_4_SHIFT) +# define NVIC_IPR1_4(p) ((p) << NVIC_IPR1_4_SHIFT) +#define NVIC_IPR1_5_SHIFT (8) /* Bits 8-15: PRI_5 */ +#define NVIC_IPR1_5_MASK (0xff << NVIC_IPR1_5_SHIFT) +# define NVIC_IPR1_5(p) ((p) << NVIC_IPR1_5_SHIFT) +#define NVIC_IPR1_6_SHIFT (16) /* Bits 16-23: PRI_6 */ +#define NVIC_IPR1_6_MASK (0xff << NVIC_IPR1_6_SHIFT) +# define NVIC_IPR1_6(p) ((p) << NVIC_IPR1_6_SHIFT) +#define NVIC_IPR1_7_SHIFT (24) /* Bits 24-31: PRI_7 */ +#define NVIC_IPR1_7_MASK (0xff << NVIC_IPR1_7_SHIFT) +# define NVIC_IPR1_7(p) ((p) << NVIC_IPR1_7_SHIFT) + +#define NVIC_IPR2_8_SHIFT (0) /* Bits 0-7: PRI_8 */ +#define NVIC_IPR2_8_MASK (0xff << NVIC_IPR2_8_SHIFT) +# define NVIC_IPR2_8(p) ((p) << NVIC_IPR2_8_SHIFT) +#define NVIC_IPR2_9_SHIFT (8) /* Bits 8-15: PRI_9 */ +#define NVIC_IPR2_9_MASK (0xff << NVIC_IPR2_9_SHIFT) +# define NVIC_IPR2_9(p) ((p) << NVIC_IPR2_9_SHIFT) +#define NVIC_IPR2_10_SHIFT (16) /* Bits 16-23: PRI_10 */ +#define NVIC_IPR2_10_MASK (0xff << NVIC_IPR2_10_SHIFT) +# define NVIC_IPR2_10(p) ((p) << NVIC_IPR2_10_SHIFT) +#define NVIC_IPR2_11_SHIFT (24) /* Bits 24-31: PRI_11 */ +#define NVIC_IPR2_11_MASK (0xff << NVIC_IPR2_11_SHIFT) +# define NVIC_IPR2_11(p) ((p) << NVIC_IPR2_11_SHIFT) + +#define NVIC_IPR3_12_SHIFT (0) /* Bits 0-7: PRI_12 */ +#define NVIC_IPR3_12_MASK (0xff << NVIC_IPR3_12_SHIFT) +# define NVIC_IPR3_12(p) ((p) << NVIC_IPR3_12_SHIFT) +#define NVIC_IPR3_13_SHIFT (8) /* Bits 8-15: PRI_13 */ +#define NVIC_IPR3_13_MASK (0xff << NVIC_IPR3_13_SHIFT) +# define NVIC_IPR3_13(p) ((p) << NVIC_IPR3_13_SHIFT) +#define NVIC_IPR3_14_SHIFT (16) /* Bits 16-23: PRI_14 */ +#define NVIC_IPR3_14_MASK (0xff << NVIC_IPR3_14_SHIFT) +# define NVIC_IPR3_14(p) ((p) << NVIC_IPR3_14_SHIFT) +#define NVIC_IPR3_15_SHIFT (24) /* Bits 24-31: PRI_15 */ +#define NVIC_IPR3_15_MASK (0xff << NVIC_IPR3_15_SHIFT) +# define NVIC_IPR3_15(p) ((p) << NVIC_IPR3_15_SHIFT) + +#define NVIC_IPR4_16_SHIFT (0) /* Bits 0-7: PRI_16 */ +#define NVIC_IPR4_16_MASK (0xff << NVIC_IPR4_16_SHIFT) +# define NVIC_IPR4_16(p) ((p) << NVIC_IPR4_16_SHIFT) +#define NVIC_IPR4_17_SHIFT (8) /* Bits 8-15: PRI_17 */ +#define NVIC_IPR4_17_MASK (0xff << NVIC_IPR4_17_SHIFT) +# define NVIC_IPR4_17(p) ((p) << NVIC_IPR4_17_SHIFT) +#define NVIC_IPR4_18_SHIFT (16) /* Bits 16-23: PRI_18 */ +#define NVIC_IPR4_18_MASK (0xff << NVIC_IPR4_18_SHIFT) +# define NVIC_IPR4_18(p) ((p) << NVIC_IPR4_18_SHIFT) +#define NVIC_IPR4_19_SHIFT (24) /* Bits 24-31: PRI_19 */ +#define NVIC_IPR4_19_MASK (0xff << NVIC_IPR4_19_SHIFT) +# define NVIC_IPR4_19(p) ((p) << NVIC_IPR4_19_SHIFT) + +#define NVIC_IPR5_20_SHIFT (0) /* Bits 0-7: PRI_20 */ +#define NVIC_IPR5_20_MASK (0xff << NVIC_IPR5_20_SHIFT) +# define NVIC_IPR5_20(p) ((p) << NVIC_IPR5_20_SHIFT) +#define NVIC_IPR5_21_SHIFT (8) /* Bits 8-15: PRI_21 */ +#define NVIC_IPR5_21_MASK (0xff << NVIC_IPR5_21_SHIFT) +# define NVIC_IPR5_21(p) ((p) << NVIC_IPR5_21_SHIFT) +#define NVIC_IPR5_22_SHIFT (16) /* Bits 16-23: PRI_22 */ +#define NVIC_IPR5_22_MASK (0xff << NVIC_IPR5_22_SHIFT) +# define NVIC_IPR5_22(p) ((p) << NVIC_IPR5_22_SHIFT) +#define NVIC_IPR5_23_SHIFT (24) /* Bits 24-31: PRI_23 */ +#define NVIC_IPR5_23_MASK (0xff << NVIC_IPR5_23_SHIFT) +# define NVIC_IPR5_23(p) ((p) << NVIC_IPR5_23_SHIFT) + +#define NVIC_IPR6_24_SHIFT (0) /* Bits 0-7: PRI_24 */ +#define NVIC_IPR6_24_MASK (0xff << NVIC_IPR6_24_SHIFT) +# define NVIC_IPR6_24(p) ((p) << NVIC_IPR6_24_SHIFT) +#define NVIC_IPR6_25_SHIFT (8) /* Bits 8-15: PRI_25 */ +#define NVIC_IPR6_25_MASK (0xff << NVIC_IPR6_25_SHIFT) +# define NVIC_IPR6_25(p) ((p) << NVIC_IPR6_25_SHIFT) +#define NVIC_IPR6_26_SHIFT (16) /* Bits 16-23: PRI_26 */ +#define NVIC_IPR6_26_MASK (0xff << NVIC_IPR6_26_SHIFT) +# define NVIC_IPR6_26(p) ((p) << NVIC_IPR6_26_SHIFT) +#define NVIC_IPR6_27_SHIFT (24) /* Bits 24-31: PRI_27 */ +#define NVIC_IPR6_27_MASK (0xff << NVIC_IPR6_27_SHIFT) +# define NVIC_IPR6_27(p) ((p) << NVIC_IPR6_27_SHIFT) + +#define NVIC_IPR7_28_SHIFT (0) /* Bits 0-7: PRI_28 */ +#define NVIC_IPR7_28_MASK (0xff << NVIC_IPR7_28_SHIFT) +# define NVIC_IPR7_28(p) ((p) << NVIC_IPR7_28_SHIFT) +#define NVIC_IPR7_29_SHIFT (8) /* Bits 8-15: PRI_29 */ +#define NVIC_IPR7_29_MASK (0xff << NVIC_IPR7_29_SHIFT) +# define NVIC_IPR7_29(p) ((p) << NVIC_IPR7_29_SHIFT) +#define NVIC_IPR7_30_SHIFT (16) /* Bits 16-23: PRI_30 */ +#define NVIC_IPR7_30_MASK (0xff << NVIC_IPR7_30_SHIFT) +# define NVIC_IPR7_30(p) ((p) << NVIC_IPR7_30_SHIFT) +#define NVIC_IPR7_31_SHIFT (24) /* Bits 24-31: PRI_31 */ +#define NVIC_IPR7_31_MASK (0xff << NVIC_IPR7_31_SHIFT) +# define NVIC_IPR7_31(p) ((p) << NVIC_IPR7_31_SHIFT) + +/* System control register addresses */ + +/* CPUID Register */ + +#define SYSCON_CPUID_REVISION_SHIFT (0) /* Bits 0-3: Revision number */ +#define SYSCON_CPUID_REVISION_MASK (15 << SYSCON_CPUID_REVISION_SHIFT) +#define SYSCON_CPUID_PARTNO_SHIFT (4) /* Bits 4-15: Part number of the processor */ +#define SYSCON_CPUID_PARTNO_MASK (0x0fff << SYSCON_CPUID_PARTNO_SHIFT) +# define SYSCON_CPUID_PARTNO_CORTEXM0 (0x0c20 << SYSCON_CPUID_PARTNO_SHIFT) +#define SYSCON_CPUID_CONSTANT_SHIFT (16) /* Bits 16-19: Constant that defines the architecture + * of the processor */ +#define SYSCON_CPUID_CONSTANT_MASK (15 << SYSCON_CPUID_CONSTANT_SHIFT) +# define SYSCON_CPUID_CONSTANT_ARMV6M (12 << SYSCON_CPUID_PARTNO_SHIFT) +#define SYSCON_CPUID_VARIANT_SHIFT (20) /* Bits 20-23: Variant number, the r value in the + * rnpn product revision identifier */ +#define SYSCON_CPUID_VARIANT_MASK (15 << SYSCON_CPUID_VARIANT_SHIFT) +#define SYSCON_CPUID_IMPLEMENTER_SHIFT (24) /* Bits 24-31: Implementer code */ +#define SYSCON_CPUID_IMPLEMENTER_MASK (0xff << SYSCON_CPUID_IMPLEMENTER_SHIFT) +# define SYSCON_CPUID_IMPLEMENTER_ARM (0x41 << SYSCON_CPUID_IMPLEMENTER_SHIFT) + +/* Interrupt control and state register */ + +#define SYSCON_ICSR_VECTACTIVE_SHIFT (0) /* Bits 0-5: Contains the active exception number */ +#define SYSCON_ICSR_VECTACTIVE_MASK (63 << SYSCON_ICSR_VECTACTIVE_SHIFT) +#define SYSCON_ICSR_VECTPENDING_SHIFT (12) /* Bits 12-17: Indicates the exception number of + * the highest priority pending enabled + * exception */ +#define SYSCON_ICSR_VECTPENDING_MASK (63 << SYSCON_ICSR_VECTPENDING_SHIFT) +#define SYSCON_ICSR_ISRPENDING (1 << 22) /* Bit 22: Interrupt pending flag, excluding NMI + * and Faults */ +#define SYSCON_ICSR_PENDSTCLR (1 << 25) /* Bit 25: SysTick exception clear-pending bit */ +#define SYSCON_ICSR_PENDSTSET (1 << 26) /* Bit 26: SysTick exception set-pending bit */ +#define SYSCON_ICSR_PENDSVCLR (1 << 27) /* Bit 27: PendSV clear-pending bit */ +#define SYSCON_ICSR_PENDSVSET (1 << 28) /* Bit 28: PendSV set-pending bit */ +#define SYSCON_ICSR_NMIPENDSET (1 << 31) /* Bit 31: NMI set-pending bit */ + +/* Application interrupt and reset control register */ + +#define SYSCON_AIRCR_VECTCLRACTIVE (1 << 1) /* Bit 1: Reserved for debug use */ +#define SYSCON_AIRCR_SYSRESETREQ (1 << 2) /* Bit 2: System reset request */ +#define SYSCON_AIRCR_ENDIANESS (1 << 15) /* Bit 15: Data endianness implemented */ +#define SYSCON_AIRCR_VECTKEY_SHIFT (16) /* Bits 16-31: Register key */ +#define SYSCON_AIRCR_VECTKEY_MASK (0xffff << SYSCON_AIRCR_VECTKEY_SHIFT) +# define SYSCON_AIRCR_VECTKEY(n) ((n) << SYSCON_AIRCR_VECTKEY_SHIFT) + +/* System control register */ + +#define SYSCON_SCR_SLEEPONEXIT (1 << 1) /* Bit 1: Sleep-on-exit when returning from handler + * to thread mode */ +#define SYSCON_SCR_SLEEPDEEP (1 << 2) /* Bit 2: Use deep sleep as the low power mode */ +#define SYSCON_SCR_SEVONPEND (1 << 4) /* Bit 4: Send event on pending bit */ + +/* Configuration and control register */ + +#define SYSCON_CCR_UNALIGN_TRP (1 << 3) /* Bit 3: Unaligned accesses generate a hardfault */ +#define SYSCON_CCR_STKALIGN (1 << 9) /* Bit 9: 8-byte stack alignment on exception entry */ + +/* System handler priority register 2 */ + +#define SYSCON_SHPR2_PRI_11_SHIFT (24) /* Bits 24-31: Priority of system handler 11, + * SVCall */ +#define SYSCON_SHPR2_PRI_11_MASK (0xff << SYSCON_SHPR2_PRI_11_SHIFT) + +/* System handler priority register 3 */ + +#define SYSCON_SHPR3_PRI_14_SHIFT (16) /* Bits 16-23: Priority of system handler 14, + * PendSV */ +#define SYSCON_SHPR3_PRI_14_MASK (0xff << SYSCON_SHPR3_PRI_14_SHIFT) +#define SYSCON_SHPR3_PRI_15_SHIFT (24) /* Bits 24-31: Priority of system handler 15, + * SysTick exception */ +#define SYSCON_SHPR3_PRI_15_MASK (0xff << SYSCON_SHPR3_PRI_15_SHIFT) + +/* SYSTICK register addresses */ + +/* SysTick control and status register */ + +#define SYSTICK_CSR_ENABLE (1 << 0) /* Bit 0: Enables the counter */ +#define SYSTICK_CSR_TICKINT (1 << 1) /* Bit 1: Enables SysTick exception request */ +#define SYSTICK_CSR_CLKSOURCE (1 << 2) /* Bit 2: Selects the SysTick timer clock source */ +#define SYSTICK_CSR_COUNTFLAG (1 << 16) /* Bit 16: Returns 1 if timer counted to 0 since + * the last read of this register */ +/* SysTick reload value register */ + +#define SYSTICK_RVR_MASK (0x0fffffff) /* Bits 0-23 */ + +/* SysTick current value register */ + +#define SYSTICK_CVR_MASK (0x0fffffff) /* Bits 0-23 */ + +/* SysTick calibration value register */ + +#define SYSTICK_CALIB_TENMS_SHIFT (0) /* Bits 0-23: Reload value for 10ms (100Hz) timing */ +#define SYSTICK_CALIB_TENMS_MASK (0x0fffffff << SYSTICK_CALIB_TENMS_SHIFT) +#define SYSTICK_CALIB_SKEW (1 << 30) /* Bit 30: TENMS value is exact */ +#define SYSTICK_CALIB_NOREF (1 << 31) /* Bit 31: Device provides a reference clock */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +/**************************************************************************************************** + * Function: up_dumpnvic + * + * Description: + * Dump all NVIC and SYSCON registers along with a user message. + * + ****************************************************************************************************/ + +#ifdef CONFIG_DEBUG +void up_dumpnvic(FAR const char *msg); +#else +# define up_dumpnvic(m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_COMMON_ARMV6_M_NVIC_H */ diff --git a/arch/arm/src/armv6-m/psr.h b/arch/arm/src/armv6-m/psr.h new file mode 100644 index 0000000000000000000000000000000000000000..eeb541a005ddf58385e9eb91297b63a5cd7e4aa3 --- /dev/null +++ b/arch/arm/src/armv6-m/psr.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/psr.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARMV6_M_PSR_H +#define __ARCH_ARM_SRC_COMMON_ARMV6_M_PSR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Application Program Status Register (APSR) */ + +#define ARMV6M_APSR_V (1 << 28) /* Bit 28: Overflow flag */ +#define ARMV6M_APSR_C (1 << 29) /* Bit 29: Carry/borrow flag */ +#define ARMV6M_APSR_Z (1 << 30) /* Bit 30: Zero flag */ +#define ARMV6M_APSR_N (1 << 31) /* Bit 31: Negative, less than flag */ + +/* Interrupt Program Status Register (IPSR) */ + +#define ARMV6M_IPSR_ISR_SHIFT 0 /* Bits 5-0: ISR number */ +#define ARMV6M_IPSR_ISR_MASK (31 << ARMV6M_IPSR_ISR_SHIFT) + +/* Execution PSR Register (EPSR) */ + +#define ARMV6M_EPSR_T (1 << 24) /* Bit 24: T-bit */ + +/* Save xPSR bits */ + +#define ARMV6M_XPSR_ISR_SHIFT ARMV6M_IPSR_ISR_SHIFT +#define ARMV6M_XPSR_ISR_MASK ARMV6M_IPSR_ISR_MASK +#define ARMV6M_XPSR_T ARMV6M_EPSR_T +#define ARMV6M_XPSR_V ARMV6M_APSR_V +#define ARMV6M_XPSR_C ARMV6M_APSR_C +#define ARMV6M_XPSR_Z ARMV6M_APSR_Z +#define ARMV6M_XPSR_N ARMV6M_APSR_N + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_COMMON_ARMV6_M_PSR_H */ diff --git a/arch/arm/src/armv6-m/svcall.h b/arch/arm/src/armv6-m/svcall.h new file mode 100644 index 0000000000000000000000000000000000000000..c3e849394e0af587c3a02fcef26f8c73c1a40996 --- /dev/null +++ b/arch/arm/src/armv6-m/svcall.h @@ -0,0 +1,146 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/svcall.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV6_M_SVCALL_H +#define __ARCH_ARM_SRC_ARMV6_M_SVCALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ +/* This logic uses three system calls {0,1,2} for context switching and one for the + * syscall return. So a minimum of four syscall values must be reserved. If + * CONFIG_BUILD_PROTECTED is defined, then four more syscall values must be reserved. + */ + +#ifdef CONFIG_LIB_SYSCALL +# ifdef CONFIG_BUILD_PROTECTED +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 8" +# elif CONFIG_SYS_RESERVED != 8 +# error "CONFIG_SYS_RESERVED must have the value 8" +# endif +# else +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 4" +# elif CONFIG_SYS_RESERVED != 4 +# error "CONFIG_SYS_RESERVED must have the value 4" +# endif +# endif +#endif + +/* Cortex M0 system calls ***********************************************************/ + +/* SYS call 0: + * + * int up_saveusercontext(uint32_t *saveregs); + */ + +#define SYS_save_context (0) + +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) + +/* SYS call 2: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) + +#ifdef CONFIG_LIB_SYSCALL +/* SYS call 3: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (3) + +#ifdef CONFIG_BUILD_PROTECTED +/* SYS call 4: + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) + * noreturn_function; + */ + +#define SYS_task_start (4) + +/* SYS call 5: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +/* SYS call 6: + * + * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, + * FAR void *ucontext); + */ + +#define SYS_signal_handler (6) + +/* SYS call 7: + * + * void signal_handler_return(void); + */ + +#define SYS_signal_handler_return (7) + +#endif /* CONFIG_BUILD_PROTECTED */ +#endif /* CONFIG_LIB_SYSCALL */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_ARMV6_M_SVCALL_H */ + diff --git a/arch/arm/src/armv6-m/up_assert.c b/arch/arm/src/armv6-m/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..dcb71392696ac255d524318c661bc8d5c0b136df --- /dev/null +++ b/arch/arm/src/armv6-m/up_assert.c @@ -0,0 +1,418 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_assert.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump(sp,stack_base) +#endif + +/**************************************************************************** + * Name: up_taskdump + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg) +{ + /* Dump interesting properties of this task */ + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("%s: PID=%d Stack Used=%lu of %lu\n", + tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#else + lldbg("PID: %d Stack Used=%lu of %lu\n", + tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#endif +} +#endif + +/**************************************************************************** + * Name: up_showtasks + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static inline void up_showtasks(void) +{ + /* Dump interesting properties of each task in the crash environment */ + + sched_foreach(up_taskdump, NULL); +} +#else +# define up_showtasks() +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (CURRENT_REGS) + { + /* Yes.. dump the interrupt registers */ + + lldbg("R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R0], CURRENT_REGS[REG_R1], + CURRENT_REGS[REG_R2], CURRENT_REGS[REG_R3], + CURRENT_REGS[REG_R4], CURRENT_REGS[REG_R5], + CURRENT_REGS[REG_R6], CURRENT_REGS[REG_R7]); + lldbg("R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R8], CURRENT_REGS[REG_R9], + CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11], + CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13], + CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]); +#ifdef CONFIG_BUILD_PROTECTED + lldbg("xPSR: %08x PRIMASK: %08x EXEC_RETURN: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK], + CURRENT_REGS[REG_EXC_RETURN]); +#else + lldbg("xPSR: %08x PRIMASK: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]); +#endif + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + } + + /* Extract the user stack pointer if we are in an interrupt handler. + * If we are not in an interrupt handler. Then sp is the user stack + * pointer (and the above range check should have failed). + */ + + if (CURRENT_REGS) + { + sp = CURRENT_REGS[REG_R13]; + lldbg("sp: %08x\n", sp); + } + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp <= ustackbase && sp > ustackbase - ustacksize) + { + up_stackdump(sp, ustackbase); + } + +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg("stack used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { + lldbg("ERROR: Stack pointer is not within allocated stack\n"); + } + else + { + up_stackdump(sp, ustackbase); + } +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); + + /* Dump the state of all tasks (if available) */ + + up_showtasks(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (CURRENT_REGS || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/arm/src/armv6-m/up_blocktask.c b/arch/arm/src/armv6-m/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..2a95163cca220e9fedaf323a7f0ebc88d02771d2 --- /dev/null +++ b/arch/arm/src/armv6-m/up_blocktask.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_blocktask.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of the ready to run list must + * be stopped. Save its context and move it to the inactive list specified + * by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally the task at + * the head of the list). It most be stopped, its context saved and + * moved into one of the waiting task lists. It it was the task at the + * head of the ready-to-run list, then a context to the new ready to run + * task must be performed. + * task_state: Specifies which waiting task list should be hold the + * blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv6-m/up_copyfullstate.c b/arch/arm/src/armv6-m/up_copyfullstate.c new file mode 100644 index 0000000000000000000000000000000000000000..0699462d8b0a1f9805b74d0634fa1d8ef6b5e411 --- /dev/null +++ b/arch/arm/src/armv6-m/up_copyfullstate.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_copyfullstate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyfullstate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copyfullstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the Cortex-M0 model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + diff --git a/arch/arm/src/armv6-m/up_doirq.c b/arch/arm/src/armv6-m/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..ac688ba3066855e761713f9c8f6729be2e796cac --- /dev/null +++ b/arch/arm/src/armv6-m/up_doirq.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_doirq.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + uint32_t *savestate; + + /* Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to (1) change the way that + * CURRENT_REGS is handled and (2) the design associated with + * CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* If a context switch occurred while processing the interrupt then + * CURRENT_REGS may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)CURRENT_REGS; + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; +#endif + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/arm/src/armv6-m/up_dumpnvic.c b/arch/arm/src/armv6-m/up_dumpnvic.c new file mode 100644 index 0000000000000000000000000000000000000000..36c2fdf21682cf9e24b417aa83da5bcd60ae845c --- /dev/null +++ b/arch/arm/src/armv6-m/up_dumpnvic.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_dumpnvic.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" + +#include "nvic.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_dumpnvic + * + * Description: + * Dump all NVIC and SYSCON registers along with a user message. + * + ****************************************************************************/ + +void up_dumpnvic(FAR const char *msg) +{ + irqstate_t flags; + int i; + + /* The following requires exclusive access to the NVIC/SYSCON registers */ + + flags = enter_critical_section(); + + lldbg("NVIC: %s\n", msg); + lldbg(" ISER: %08x ICER: %08x ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER), + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + + for (i = 0 ; i < 8; i += 4) + { + lldbg(" IPR%d: %08x IPR%d: %08x IPR%d: %08x IPR%d: %08x\n", + i, getreg32(ARMV6M_NVIC_IPR(i)), + i+1, getreg32(ARMV6M_NVIC_IPR(i+1)), + i+2, getreg32(ARMV6M_NVIC_IPR(i+2)), + i+3, getreg32(ARMV6M_NVIC_IPR(i+3))); + } + + lldbg("SYSCON:\n"); + lldbg(" CPUID: %08x ICSR: %08x AIRCR: %08x SCR: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID), getreg32(ARMV6M_SYSCON_ICSR), + getreg32(ARMV6M_SYSCON_AIRCR), getreg32(ARMV6M_SYSCON_SCR)); + lldbg(" CCR: %08x SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_CCR), getreg32(ARMV6M_SYSCON_SHPR2), + getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/armv6-m/up_elf.c b/arch/arm/src/armv6-m/up_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..dbe002cbb1a97419821aa7b3d2821a12e029ae97 --- /dev/null +++ b/arch/arm/src/armv6-m/up_elf.c @@ -0,0 +1,466 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_elf.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *ehdr) +{ + /* Make sure it's an ARM executable */ + + if (ehdr->e_machine != EM_ARM) + { + bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine); + return -ENOEXEC; + } + + /* Make sure that 32-bit objects are supported */ + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + { + bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]); + return -ENOEXEC; + } + + /* Verify endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG + if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) +#else + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) +#endif + { + bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]); + return -ENOEXEC; + } + + /* TODO: Check ABI here. */ + return OK; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + int32_t offset; + uint32_t upper_insn; + uint32_t lower_insn; + unsigned int relotype; + + /* All relocations except R_ARM_V4BX depend upon having valid symbol + * information. + */ + + relotype = ELF32_R_TYPE(rel->r_info); + if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (relotype) + { + case R_ARM_NONE: + { + /* No relocation */ + } + break; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + { + bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = (*(uint32_t *)addr & 0x00ffffff) << 2; + if (offset & 0x02000000) + { + offset -= 0x04000000; + } + + offset += sym->st_value - addr; + if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000) + { + bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + offset >>= 2; + + *(uint32_t *)addr &= 0xff000000; + *(uint32_t *)addr |= offset & 0x00ffffff; + } + break; + + case R_ARM_ABS32: + case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ + { + bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value; + } + break; + + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + { + uint32_t S; + uint32_t J1; + uint32_t J2; + + /* Thumb BL and B.W instructions. Encoding: + * + * upper_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +----------+---+-------------------------------+--------------+ + * |1 1 1 |OP1| OP2 | | 32-Bit Instructions + * +----------+---+--+-----+----------------------+--------------+ + * |1 1 1 | 1 0| S | imm10 | BL Instruction + * +----------+------+-----+-------------------------------------+ + * + * lower_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +---+---------------------------------------------------------+ + * |OP | | 32-Bit Instructions + * +---+--+---+---+---+------------------------------------------+ + * |1 1 |J1 | 1 |J2 | imm11 | BL Instruction + * +------+---+---+---+------------------------------------------+ + * + * The branch target is encoded in these bits: + * + * S = upper_insn[10] + * imm10 = upper_insn[0:9] + * imm11 = lower_insn[0:10] + * J1 = lower_insn[13] + * J2 = lower_insn[11] + */ + + upper_insn = (uint32_t)(*(uint16_t *)addr); + lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); + + bvdbg("Performing THM_JUMP24 [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, + sym, (long)sym->st_value); + + /* Extract the 25-bit offset from the 32-bit instruction: + * + * offset[24] = S + * offset[23] = ~(J1 ^ S) + * offset[22] = ~(J2 ^ S)] + * offset[12:21] = imm10 + * offset[1:11] = imm11 + * offset[0] = 0 + */ + + S = (upper_insn >> 10) & 1; + J1 = (lower_insn >> 13) & 1; + J2 = (lower_insn >> 11) & 1; + + offset = (S << 24) | /* S - > offset[24] */ + ((~(J1 ^ S) & 1) << 23) | /* J1 -> offset[23] */ + ((~(J2 ^ S) & 1) << 22) | /* J2 -> offset[22] */ + ((upper_insn & 0x03ff) << 12) | /* imm10 -> offset[12:21] */ + ((lower_insn & 0x07ff) << 1); /* imm11 -> offset[1:11] */ + /* 0 -> offset[0] */ + + /* Sign extend */ + + if (offset & 0x01000000) + { + offset -= 0x02000000; + } + + /* And perform the relocation */ + + bvdbg(" S=%d J1=%d J2=%d offset=%08lx branch target=%08lx\n", + S, J1, J2, (long)offset, offset + sym->st_value - addr); + + offset += sym->st_value - addr; + + /* Is this a function symbol? If so, then the branch target must be + * an odd Thumb address + */ + + if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && (offset & 1) == 0) + { + bdbg(" ERROR: JUMP24 [%d] requires odd offset, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + /* Check the range of the offset */ + + if (offset <= (int32_t)0xff000000 || offset >= (int32_t)0x01000000) + { + bdbg(" ERROR: JUMP24 [%d] relocation out of range, branch taget=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + /* Now, reconstruct the 32-bit instruction using the new, relocated + * branch target. + */ + + S = (offset >> 24) & 1; + J1 = S ^ (~(offset >> 23) & 1); + J2 = S ^ (~(offset >> 22) & 1); + + upper_insn = ((upper_insn & 0xf800) | (S << 10) | ((offset >> 12) & 0x03ff)); + *(uint16_t *)addr = (uint16_t)upper_insn; + + lower_insn = ((lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | ((offset >> 1) & 0x07ff)); + *(uint16_t *)(addr + 2) = (uint16_t)lower_insn; + + bvdbg(" S=%d J1=%d J2=%d insn [%04x %04x]\n", + S, J1, J2, (int)upper_insn, (int)lower_insn); + } + break; + + case R_ARM_V4BX: + { + bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n", + (long)addr, (long)(*(uint32_t *)addr)); + + /* Preserve only Rm and the condition code */ + + *(uint32_t *)addr &= 0xf000000f; + + /* Change instruction to 'mov pc, Rm' */ + + *(uint32_t *)addr |= 0x01a0f000; + } + break; + + case R_ARM_PREL31: + { + bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + offset = *(uint32_t *)addr + sym->st_value - addr; + *(uint32_t *)addr = offset & 0x7fffffff; + } + break; + + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = *(uint32_t *)addr; + offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); + offset = (offset ^ 0x8000) - 0x8000; + + offset += sym->st_value; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + { + offset >>= 16; + } + + *(uint32_t *)addr &= 0xfff0f000; + *(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff); + } + break; + + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + { + /* Thumb BL and B.W instructions. Encoding: + * + * upper_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +----------+---+-------------------------------+--------------+ + * |1 1 1 |OP1| OP2 | | 32-Bit Instructions + * +----------+---+--+-----+----------------------+--------------+ + * |1 1 1 | 1 0| i | 1 0 1 1 0 0 | imm4 | MOVT Instruction + * +----------+------+-----+----------------------+--------------+ + * + * lower_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +---+---------------------------------------------------------+ + * |OP | | 32-Bit Instructions + * +---+----------+--------------+-------------------------------+ + * |0 | imm3 | Rd | imm8 | MOVT Instruction + * +---+----------+--------------+-------------------------------+ + * + * The 16-bit immediate value is encoded in these bits: + * + * i = imm16[11] = upper_insn[10] + * imm4 = imm16[12:15] = upper_insn[3:0] + * imm3 = imm16[8:10] = lower_insn[14:12] + * imm8 = imm16[0:7] = lower_insn[7:0] + */ + + upper_insn = (uint32_t)(*(uint16_t *)addr); + lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); + + bvdbg("Performing THM_MOVx [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, + sym, (long)sym->st_value); + + /* Extract the 16-bit offset from the 32-bit instruction */ + + offset = ((upper_insn & 0x000f) << 12) | /* imm4 -> imm16[8:10] */ + ((upper_insn & 0x0400) << 1) | /* i -> imm16[11] */ + ((lower_insn & 0x7000) >> 4) | /* imm3 -> imm16[8:10] */ + (lower_insn & 0x00ff); /* imm8 -> imm16[0:7] */ + + /* Sign extend */ + + offset = (offset ^ 0x8000) - 0x8000; + + /* And perform the relocation */ + + bvdbg(" offset=%08lx branch target=%08lx\n", + (long)offset, offset + sym->st_value); + + offset += sym->st_value; + + /* Update the immediate value in the instruction. For MOVW we want the bottom + * 16-bits; for MOVT we want the top 16-bits. + */ + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) + { + offset >>= 16; + } + + upper_insn = ((upper_insn & 0xfbf0) | ((offset & 0xf000) >> 12) | ((offset & 0x0800) >> 1)); + *(uint16_t *)addr = (uint16_t)upper_insn; + + lower_insn = ((lower_insn & 0x8f00) | ((offset & 0x0700) << 4) | (offset & 0x00ff)); + *(uint16_t *)(addr + 2) = (uint16_t)lower_insn; + + bvdbg(" insn [%04x %04x]\n", + (int)upper_insn, (int)lower_insn); + } + break; + + default: + bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info)); + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("RELA relocation not supported\n"); + return -ENOSYS; +} diff --git a/arch/arm/src/armv6-m/up_exception.S b/arch/arm/src/armv6-m/up_exception.S new file mode 100644 index 0000000000000000000000000000000000000000..5a9d5d8a6829b71bb6814b10497afcc08e290e41 --- /dev/null +++ b/arch/arm/src/armv6-m/up_exception.S @@ -0,0 +1,281 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/up_exception.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file was leveraged from the ARMv7-M version which has, in addition: + * + * Copyright (C) 2012 Michael Smith. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "exc_return.h" + +#include "chip.h" + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl exception_common + + .cpu cortex-m0 + .file "up_exception.S" + +/************************************************************************************ + * .text + ************************************************************************************/ + +/* Common exception handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * IPSR contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .text + .align 2 + .code 16 + .thumb_func + .type exception_common, function +exception_common: + + /* Complete the context save */ + + /* Get the current stack pointer. The EXC_RETURN value tells us whether + * the context is on the MSP or PSP. + */ + +#ifdef CONFIG_BUILD_PROTECTED + mov r0, r14 /* Copy high register to low register */ + lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ + bmi 1f /* Test bit 31 */ + mrs r1, msp /* R1=The main stack pointer */ + b 2f + +1: + mrs r1, psp /* R1=The process stack pointer */ +#else + mrs r1, msp /* R1=The main stack pointer */ +#endif + + /* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack + * when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the + * stack pointer before the interrupt. The total size of the context save + * area is XCPTCONTEXT_SIZE = SW_XCPT_SIZE + HW_XCPT_SIZE so (R1)-SW_XCPT_SIZE + * is the address of the beginning of the context save area. + */ + +2: + /* Save SP, PRIMASK, and R4-R7 in the context array */ + + sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */ + mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */ + add r2, r1 /* R2=MSP/PSP before the interrupt was taken */ + /* (ignoring the xPSR[9] alignment bit) */ + mrs r3, primask /* R3=Current PRIMASK setting */ + mov r0, r1 /* Copy the context array pointer */ + stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */ + + /* Save R8-R11 and the EXEC_RETURN value in the context array */ + + mov r2, r8 /* Copy high registers to low */ + mov r3, r9 + mov r4, r10 + mov r5, r11 +#ifdef CONFIG_BUILD_PROTECTED + mov r6, r14 + stmia r0!, {r2-r6} /* Save the high registers r8-r11 and r14 */ +#else + stmia r0!, {r2-r5} /* Save the high registers r8-r11 */ +#endif + + /* Get the exception number in R0=IRQ, R1=register save area on stack */ + + mrs r0, ipsr /* R0=exception number */ + + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will use a special interrupt + * stack pointer. The way that this is done here prohibits nested interrupts! + * Otherwise, we will use the stack that was current when the interrupt was taken. + */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr r7, =g_intstackbase /* R7=Base of the interrupt stack */ + mov sp, r7 /* Set the new stack point */ + push {r1} /* Save the MSP on the interrupt stack */ + bl up_doirq /* R0=IRQ, R1=register save area on stack */ + pop {r1} /* Recover R1=main stack pointer */ +#else + msr msp, r1 /* We are using the main stack pointer */ + bl up_doirq /* R0=IRQ, R1=register save area on stack */ + mrs r1, msp /* Recover R1=main stack pointer */ +#endif + + /* On return from up_doirq, r0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 3f /* Branch if no context switch */ + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie on the + * stack but, rather within a TCB structure. We'll have to copy some + * values to the stack. + */ + + /* Copy the hardware-saved context to the new stack */ + + mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */ + add r1, r0, r2 /* R1=Address of HW save area in reg array */ + ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */ + sub r2, #HW_XCPT_SIZE /* R2=Address of HW save area on the return stack */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + + /* Restore the register contents */ + + mov r1, r0 + +3: + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created at entry. + */ + + /* Recover R8-R11 and EXEC_RETURN (5 registers) */ + + mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */ + add r0, r1, r2 /* R0=Address of R8 storage */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/ + mov r8, r2 /* Move to position in high registers */ + mov r9, r3 + mov r10, r4 + mov r11, r5 + mov r14, r6 /* EXEC_RETURN */ +#else + ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/ + mov r8, r2 /* Move to position in high registers */ + mov r9, r3 + mov r10, r4 + mov r11, r5 +#endif + + /* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of + * the stack pointer as it was on entry to the exception handler. + */ + + ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */ + mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */ + sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */ + + /* Restore the stack pointer. The EXC_RETURN value tells us whether the + * context is on the MSP or PSP. + */ + +#ifdef CONFIG_BUILD_PROTECTED + mov r0, r14 /* Copy high register to low register */ + lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ + bmi 5f /* Test bit 31 */ + msr msp, r1 /* R1=The main stack pointer */ + b 6f + +5: + msr psp, r1 /* R1=The process stack pointer */ + +6: +#else + msr msp, r1 /* R1=The main stack pointer */ + ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */ + mov r14, r0 /* R14=EXC_RETURN to privileged mode */ +#endif + + /* Restore the interrupt state */ + + msr primask, r3 /* Restore interrupts priority masking*/ + cpsie i /* Re-enable interrupts */ + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) select the correct stack. + */ + + bx r14 /* And return */ + + .size exception_common, .-exception_common + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 4 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif + + .end + diff --git a/arch/arm/src/armv6-m/up_fullcontextrestore.S b/arch/arm/src/armv6-m/up_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..048c468749d44feff5c0c0eb6deaf4a23f38fbea --- /dev/null +++ b/arch/arm/src/armv6-m/up_fullcontextrestore.S @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/up_fullcontextrestore.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .cpu cortex-m0 + .file "up_fullcontextrestore.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Restore the current thread context. Full prototype is: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * Return: + * None + * + ************************************************************************************/ + + .align 2 + .code 16 + .thumb_func + .globl up_fullcontextrestore + .type up_fullcontextrestore, function +up_fullcontextrestore: + + /* Perform the System call with R0=1 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_restore_context /* R0: restore context */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + .size up_fullcontextrestore, .-up_fullcontextrestore + .end + diff --git a/arch/arm/src/armv6-m/up_hardfault.c b/arch/arm/src/armv6-m/up_hardfault.c new file mode 100644 index 0000000000000000000000000000000000000000..edd1bab6a23606f93397d4c85bd62494de83cf90 --- /dev/null +++ b/arch/arm/src/armv6-m/up_hardfault.c @@ -0,0 +1,155 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_hardfault.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "nvic.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_HARDFAULT +# define hfdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define hfdbg(x...) +#endif + +#define INSN_SVC0 0xdf00 /* insn: svc 0 */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_hardfault + * + * Description: + * This is Hard Fault exception handler. It also catches SVC call + * exceptions that are performed in bad contexts. + * + ****************************************************************************/ + +int up_hardfault(int irq, FAR void *context) +{ + uint32_t *regs = (uint32_t *)context; + + /* Get the value of the program counter where the fault occurred */ + + uint16_t *pc = (uint16_t *)regs[REG_PC] - 1; + + /* Check if the pc lies in known FLASH memory. + * REVISIT: What if the PC lies in "unknown" external memory? + */ + +#ifdef CONFIG_BUILD_PROTECTED + /* In the kernel build, SVCalls are expected in either the base, kernel + * FLASH region or in the user FLASH region. + */ + + if (((uintptr_t)pc >= (uintptr_t)&_stext && + (uintptr_t)pc < (uintptr_t)&_etext) || + ((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart && + (uintptr_t)pc < (uintptr_t)USERSPACE->us_textend)) +#else + /* SVCalls are expected only from the base, kernel FLASH region */ + + if ((uintptr_t)pc >= (uintptr_t)&_stext && + (uintptr_t)pc < (uintptr_t)&_etext) +#endif + { + /* Fetch the instruction that caused the Hard fault */ + + uint16_t insn = *pc; + hfdbg(" PC: %p INSN: %04x\n", pc, insn); + + /* If this was the instruction 'svc 0', then forward processing + * to the SVCall handler + */ + + if (insn == INSN_SVC0) + { + hfdbg("Forward SVCall\n"); + return up_svcall(irq, context); + } + } + +#if defined(CONFIG_DEBUG_HARDFAULT) + /* Dump some hard fault info */ + + hfdbg("\nHard Fault:\n"); + hfdbg(" IRQ: %d regs: %p\n", irq, regs); + hfdbg(" PRIMASK: %08x IPSR: %08x\n", + getprimask(), getipsr()); + hfdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + hfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]); +#endif + + (void)up_irq_save(); + lldbg("PANIC!!! Hard fault\n"); + PANIC(); + return OK; /* Won't get here */ +} diff --git a/arch/arm/src/armv6-m/up_initialstate.c b/arch/arm/src/armv6-m/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..1ee31309514ea1be58be87fa0b4f3bca45e0500a --- /dev/null +++ b/arch/arm/src/armv6-m/up_initialstate.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_initialstate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "psr.h" +#include "exc_return.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point (stripping off the thumb bit) */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start & ~1; + + /* Specify thumb mode */ + + xcp->regs[REG_XPSR] = ARMV6M_XPSR_T; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC + if (tcb->dspace != NULL) + { + /* Set the PIC base register (probably R10) to the address of the + * alloacated D-Space region. + */ + + xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; + } + +#ifdef CONFIG_NXFLAT + /* Make certain that bit 0 is set in the main entry address. This is + * only an issue when NXFLAT is enabled. NXFLAT doesn't know anything + * about thumb; the addresses that NXFLAT sets are based on file header + * info and won't have bit 0 set. + */ + + tcb->entry.main = (main_t)((uint32_t)tcb->entry.main | 1); +#endif +#endif /* CONFIG_PIC */ + +#ifdef CONFIG_BUILD_PROTECTED + /* All tasks start via a stub function in kernel space. So all + * tasks must start in privileged thread mode. If CONFIG_BUILD_PROTECTED + * is defined, then that stub function will switch to unprivileged + * mode before transferring control to the user task. + */ + + xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; +#endif + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_PRIMASK] = 1; +#endif /* CONFIG_SUPPRESS_INTERRUPTS */ +} diff --git a/arch/arm/src/armv6-m/up_releasepending.c b/arch/arm/src/armv6-m/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..c3e2d02ea70c64ed4323136e48f3dff423627322 --- /dev/null +++ b/arch/arm/src/armv6-m/up_releasepending.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_releasepending.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to + * switch contexts. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. Just copy the + * CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv6-m/up_reprioritizertr.c b/arch/arm/src/armv6-m/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..bd50b88b70c2d8c05e5f29b410eeff6af135ac88 --- /dev/null +++ b/arch/arm/src/armv6-m/up_reprioritizertr.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_reprioritizertr.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just removed the head + * of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the ready-to-run task list. sched_addreadytorun + * will return true if the task was added to the head of ready-to-run + * list. We will need to perform a context switch only if the + * EXCLUSIVE or of the two calls is non-zero (i.e., one and only one + * the calls changes the head of the ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed (i.e. if the head + * of the ready-to-run list is no longer the same). + */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/arm/src/armv6-m/up_saveusercontext.S b/arch/arm/src/armv6-m/up_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..bfc9a70ea884a35f1a6cfb71df9a72e53f60bd16 --- /dev/null +++ b/arch/arm/src/armv6-m/up_saveusercontext.S @@ -0,0 +1,106 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/up_saveusercontext.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .cpu cortex-m0 + .file "up_saveusercontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_saveusercontext + * + * Description: + * Save the current thread context. Full prototype is: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * Return: + * 0: Normal return + * 1: Context switch return + * + ************************************************************************************/ + + .text + .align 2 + .code 16 + .thumb_func + .globl up_saveusercontext + .type up_saveusercontext, function +up_saveusercontext: + + /* Perform the System call with R0=0 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_save_context /* R0: save context (also return value) */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* There are two return conditions. On the first return, R0 (the + * return value will be zero. On the second return we need to + * force R0 to be 1. + */ + + mov r3, #(4*REG_R0) /* R3=Offset to R0 storage */ + add r2, r1, r3 /* R2=Address of R0 storage */ + mov r3, #1 /* R3=Return value of one */ + str r3, [r2, #0] /* Save return value */ + bx lr /* "normal" return with r0=0 or + * context switch with r0=1 */ + .size up_saveusercontext, .-up_saveusercontext + .end + diff --git a/arch/arm/src/armv6-m/up_schedulesigaction.c b/arch/arm/src/armv6-m/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..be9505a9c2c9ae74404f0cf8edd4d215b42cc432 --- /dev/null +++ b/arch/arm/src/armv6-m/up_schedulesigaction.c @@ -0,0 +1,215 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_schedulesigaction.c + * + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "psr.h" +#include "exc_return.h" +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + sdbg("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!CURRENT_REGS) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted + * task is the same as the one that must receive the signal, then + * we will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Save the return PC, CPSR, and PRIMASK registers (and + * perhaps the LR). These will be restored by the signal + * trampoline after the signal has been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = CURRENT_REGS[REG_PC]; + tcb->xcp.saved_primask = CURRENT_REGS[REG_PRIMASK]; + tcb->xcp.saved_xpsr = CURRENT_REGS[REG_XPSR]; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.saved_lr = CURRENT_REGS[REG_LR]; +#endif + /* Then set up to vector to the trampoline with interrupts + * disabled. The kernel-space trampoline must run in + * privileged thread mode. + */ + + CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver; + CURRENT_REGS[REG_PRIMASK] = 1; + CURRENT_REGS[REG_XPSR] = ARMV6M_XPSR_T; +#ifdef CONFIG_BUILD_PROTECTED + CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR; +#endif + /* And make sure that the saved context in the TCB is the same + * as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signalling a task is not running from an + * interrupt handler or (2) we are not in an interrupt handler and the + * running task is signalling some non-running task. + */ + + else + { + /* Save the return PS, CPSR and PRIMASK register (a perhaps also + * the LR). These will be restored by the signal trampoline after + * the signal has been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_primask = tcb->xcp.regs[REG_PRIMASK]; + tcb->xcp.saved_xpsr = tcb->xcp.regs[REG_XPSR]; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.saved_lr = tcb->xcp.regs[REG_LR]; +#endif + + /* Then set up to vector to the trampoline with interrupts + * disabled. We must already be in privileged thread mode to be + * here. + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_PRIMASK] = 1; + tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR; +#endif + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv6-m/up_sigdeliver.c b/arch/arm/src/armv6-m/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..84b89542a207aff8cceb519d51bd8e0ac47ce0ff --- /dev/null +++ b/arch/arm/src/armv6-m/up_sigdeliver.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_sigdeliver.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + /* NOTE the "magic" guard space added to regs. This is a little kludge + * because up_fullcontextrestore (called below) will do a stack-to-stack + * copy an may overwrite the regs[] array contents. Sorry. + */ + + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS + 4]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copyfullstate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_PRIMASK] = rtcb->xcp.saved_primask; + regs[REG_XPSR] = rtcb->xcp.saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + regs[REG_LR] = rtcb->xcp.saved_lr; +#endif + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore((uint8_t)regs[REG_PRIMASK]); + + /* Deliver the signal */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv6-m/up_signal_dispatch.c b/arch/arm/src/armv6-m/up_signal_dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..fa3cea62224a18debaf5079b8cc5b89c285a155f --- /dev/null +++ b/arch/arm/src/armv6-m/up_signal_dispatch.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_signal_dispatch.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "svcall.h" +#include "up_internal.h" + +#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ + defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_dispatch + * + * Description: + * In this kernel mode build, this function will be called to execute a + * a signal handler in user-space. When the signal is delivered, a + * kernel-mode stub will first run to perform some housekeeping functions. + * This kernel-mode stub will then be called transfer control to the user + * mode signal handler by calling this function. + * + * Normally the a user-mode signalling handling stub will also execute + * before the ultimate signal handler is called. See + * arch/arm/src/armv[6\7]/up_signal_handler. This function is the + * user-space, signal handler trampoline function. It is called from + * up_signal_dispatch() in user-mode. + * + * Inputs: + * sighand - The address user-space signal handling function + * signo, info, and ucontext - Standard arguments to be passed to the + * signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via an architecture specific system call made by up_signal_handler(). + * However, this will look like a normal return by the caller of + * up_signal_dispatch. + * + ****************************************************************************/ + +void up_signal_dispatch(_sa_sigaction_t sighand, int signo, + FAR siginfo_t *info, FAR void *ucontext) +{ + /* Let sys_call4() do all of the work */ + + (void)sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo, + (uintptr_t)info, (uintptr_t)ucontext); +} + +#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */ diff --git a/arch/arm/src/armv6-m/up_signal_handler.S b/arch/arm/src/armv6-m/up_signal_handler.S new file mode 100644 index 0000000000000000000000000000000000000000..f294db9fc805872e268044ddd079a4791fd9e32d --- /dev/null +++ b/arch/arm/src/armv6-m/up_signal_handler.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/srcm/armv6-m/up_signal_handler.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * File info + ****************************************************************************/ + + .cpu cortex-m0 + .file "up_signal_handler.S" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_handler + * + * Description: + * This function is the user-space, signal handler trampoline function. It + * is called from up_signal_dispatch() in user-mode. + * + * Inputs: + * R0 = sighand + * The address user-space signal handling function + * R1-R3 = signo, info, and ucontext + * Standard arguments to be passed to the signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via the SYS_signal_handler_return (see svcall.h) + * + ****************************************************************************/ + + .text + .align 2 + .code 16 + .thumb_func + .globl up_signal_handler + .type up_signal_handler, function +up_signal_handler: + + /* Save some register */ + + push {r4, r5 /* Save R4 and R5 on the stack */ + mov r5, lr /* Save LR in R5 */ + + /* Call the signal handler */ + + mov r4, r0 /* R4=sighand */ + mov r0, r1 /* R0=signo */ + mov r1, r2 /* R1=info */ + mov r2, r3 /* R2=ucontext */ + blx r4 /* Call the signal handler */ + + /* Restore the registers */ + + mov lr, r5 /* Restore LR */ + pop {r4, r5} /* Restore R4 and R5 */ + + /* Execute the SYS_signal_handler_return SVCall (will not return) */ + + mov r0, #SYS_signal_handler_return + svc 0 + nop + + .size up_signal_handler, .-up_signal_handler + .end + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/arch/arm/src/armv6-m/up_svcall.c b/arch/arm/src/armv6-m/up_svcall.c new file mode 100644 index 0000000000000000000000000000000000000000..b5cec07937933cdc12a47165f980057554c8b0e2 --- /dev/null +++ b/arch/arm/src/armv6-m/up_svcall.c @@ -0,0 +1,518 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_svcall.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +#include "svcall.h" +#include "exc_return.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Debug ********************************************************************/ +/* Debug output from this file may interfere with context switching! To get + * debug output you must enabled the following in your NuttX configuration: + * + * - CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL (shows only syscalls) + * - CONFIG_DEBUG and CONFIG_DEBUG_SVCALL (shows everything) + */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# define svcdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define svcdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: + * + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 + * + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ + __asm__ __volatile__ + ( + " push {r4, r5}\n" /* Save R4 and R5 */ + " sub sp, sp, #12\n" /* Create a stack frame to hold 3 parms */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ + " mov r5, lr\n" /* Save lr in R5 */ + " ldr r4, =g_stublookup\n" /* R4=The base of the stub lookup table */ + " lsl r0, r0, #2\n" /* R0=Offset of the stub for this syscall */ + " ldr r4, [r4, r0]\n" /* R4=Address of the stub for this syscall */ + " blx r5\n" /* Call the stub (modifies lr) */ + " mov lr, r5\n" /* Restore lr */ + " add sp, sp, #12\n" /* Destroy the stack frame */ + " pop {r4, r5}\n" /* Recover R4 and R5 */ + " mov r2, r0\n" /* R2=Save return value in R2 */ + " mov r0, #3\n" /* R0=SYS_syscall_return */ + " svc 0" /* Return from the syscall */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_svcall + * + * Description: + * This is SVCall exception handler that performs context switching + * + ****************************************************************************/ + +int up_svcall(int irq, FAR void *context) +{ + uint32_t *regs = (uint32_t *)context; + uint32_t cmd; + + DEBUGASSERT(regs && regs == CURRENT_REGS); + cmd = regs[REG_R0]; + + /* The SVCall software interrupt is called with R0 = system call command + * and R1..R7 = variable number of arguments depending on the system call. + */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# endif + { + svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); +# ifdef CONFIG_BUILD_PROTECTED + svcdbg(" PSR: %08x PRIMASK: %08x EXC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_PRIMASK], regs[REG_EXC_RETURN]); +# else + svcdbg(" PSR: %08x PRIMASK: %08x\n", + regs[REG_XPSR], regs[REG_PRIMASK]); +# endif + } +#endif + + /* Handle the SVCall according to the command in R0 */ + + switch (cmd) + { + /* R0=SYS_save_context: This is a save context command: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_save_context + * R1 = saveregs + * + * In this case, we simply need to copy the current regsters to the + * save register space references in the saved R1 and return. + */ + + case SYS_save_context: + { + DEBUGASSERT(regs[REG_R1] != 0); + memcpy((uint32_t *)regs[REG_R1], regs, XCPTCONTEXT_SIZE); + } + break; + + /* R0=SYS_restore_context: This a restore context command: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_restore_context + * R1 = restoreregs + * + * In this case, we simply need to set CURRENT_REGS to restore register + * area referenced in the saved R1. context == CURRENT_REGS is the normal + * exception return. By setting CURRENT_REGS = context[R1], we force + * the return to the saved context referenced in R1. + */ + + case SYS_restore_context: + { + DEBUGASSERT(regs[REG_R1] != 0); + CURRENT_REGS = (uint32_t *)regs[REG_R1]; + } + break; + + /* R0=SYS_switch_context: This a switch context command: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_switch_context + * R1 = saveregs + * R2 = restoreregs + * + * In this case, we do both: We save the context registers to the save + * register area reference by the saved contents of R1 and then set + * CURRENT_REGS to to the save register area referenced by the saved + * contents of R2. + */ + + case SYS_switch_context: + { + DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0); + memcpy((uint32_t *)regs[REG_R1], regs, XCPTCONTEXT_SIZE); + CURRENT_REGS = (uint32_t *)regs[REG_R2]; + } + break; + + /* R0=SYS_syscall_return: This a syscall return command: + * + * void up_syscall_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + +#ifdef CONFIG_LIB_SYSCALL + case SYS_syscall_return: + { + struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved syscall return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved syscall return address in + * the original mode. + */ + + regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn; + regs[REG_EXC_RETURN] = rtcb->xcp.syscall[index].excreturn; + rtcb->xcp.nsyscalls = index; + + /* The return value must be in R0-R1. dispatch_syscall() temporarily + * moved the value for R0 into R2. + */ + + regs[REG_R0] = regs[REG_R2]; + } + break; +#endif + + /* R0=SYS_task_start: This a user task start + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_task_start + * R1 = taskentry + * R2 = argc + * R3 = argv + */ + +#ifdef CONFIG_BUILD_PROTECTED + case SYS_task_start: + { + /* Set up to return to the user-space task start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->task_startup; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s task_startup: + */ + + regs[REG_R0] = regs[REG_R1]; /* Task entry */ + regs[REG_R1] = regs[REG_R2]; /* argc */ + regs[REG_R2] = regs[REG_R3]; /* argv */ + } + break; +#endif + + /* R0=SYS_pthread_start: This a user pthread start + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_pthread_start + * R1 = entrypt + * R2 = arg + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) + case SYS_pthread_start: + { + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->pthread_startup; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s pthread_startup: + */ + + regs[REG_R0] = regs[REG_R1]; /* pthread entry */ + regs[REG_R1] = regs[REG_R2]; /* arg */ + } + break; +#endif + + /* R0=SYS_signal_handler: This a user signal handler callback + * + * void signal_handler(_sa_sigaction_t sighand, int signo, + * FAR siginfo_t *info, FAR void *ucontext); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler + * R1 = sighand + * R2 = signo + * R3 = info + * ucontext (on the stack) + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + case SYS_signal_handler: + { + struct tcb_s *rtcb = sched_self(); + + /* Remember the caller's return address */ + + DEBUGASSERT(rtcb->xcp.sigreturn == 0); + rtcb->xcp.sigreturn = regs[REG_PC]; + + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->signal_handler; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s signal_handler. + */ + + regs[REG_R0] = regs[REG_R1]; /* sighand */ + regs[REG_R1] = regs[REG_R2]; /* signal */ + regs[REG_R2] = regs[REG_R3]; /* info */ + + /* The last parameter, ucontext, is trickier. The ucontext + * parameter will reside at an offset of 4 from the stack pointer. + */ + + regs[REG_R3] = *(uint32_t *)(regs[REG_SP]+4); + } + break; +#endif + + /* R0=SYS_signal_handler_return: This a user signal handler callback + * + * void signal_handler_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler_return + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + case SYS_signal_handler_return: + { + struct tcb_s *rtcb = sched_self(); + + /* Set up to return to the kernel-mode signal dispatching logic. */ + + DEBUGASSERT(rtcb->xcp.sigreturn != 0); + + regs[REG_PC] = rtcb->xcp.sigreturn; + regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + rtcb->xcp.sigreturn = 0; + } + break; +#endif + + /* This is not an architecture-specific system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_LIB_SYSCALL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall); + + /* Make sure that there is a no saved syscall return address. We + * cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcp.syscall[index].sysreturn = regs[REG_PC]; + rtcb->xcp.syscall[index].excreturn = regs[REG_EXC_RETURN]; + rtcb->xcp.nsyscalls = index + 1; + + regs[REG_PC] = (uint32_t)dispatch_syscall; + regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + + /* Offset R0 to account for the reserved values */ + + regs[REG_R0] -= CONFIG_SYS_RESERVED; +#else + slldbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]); +#endif + } + break; + } + + /* Report what happened. That might difficult in the case of a context switch */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# else + if (regs != CURRENT_REGS) +# endif + { + svcdbg("SVCall Return:\n"); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R0], CURRENT_REGS[REG_R1], + CURRENT_REGS[REG_R2], CURRENT_REGS[REG_R3], + CURRENT_REGS[REG_R4], CURRENT_REGS[REG_R5], + CURRENT_REGS[REG_R6], CURRENT_REGS[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R8], CURRENT_REGS[REG_R9], + CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11], + CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13], + CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]); +#ifdef CONFIG_BUILD_PROTECTED + svcdbg(" PSR: %08x PRIMASK: %08x EXC_RETURN: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK], + CURRENT_REGS[REG_EXC_RETURN]); +#else + svcdbg(" PSR: %08x PRIMASK: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]); +#endif + } +# ifdef CONFIG_DEBUG_SVCALL + else + { + svcdbg("SVCall Return: %d\n", regs[REG_R0]); + } +# endif +#endif + + return OK; +} diff --git a/arch/arm/src/armv6-m/up_switchcontext.S b/arch/arm/src/armv6-m/up_switchcontext.S new file mode 100644 index 0000000000000000000000000000000000000000..c24f501fc2e6958d588a6e54cc7ad33d5e759a61 --- /dev/null +++ b/arch/arm/src/armv6-m/up_switchcontext.S @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/up_switchcontext.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .cpu cortex-m0 + .file "up_switchcontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. + * Full prototype is: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * Return: + * None + * + ************************************************************************************/ + + .align 2 + .code 16 + .thumb_func + .globl up_switchcontext + .type up_switchcontext, function +up_switchcontext: + + /* Perform the System call with R0=1, R1=saveregs, R2=restoreregs */ + + mov r2, r1 /* R2: restoreregs */ + mov r1, r0 /* R1: saveregs */ + mov r0, #SYS_switch_context /* R0: context switch */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* We will get here only after the rerturn from the context switch */ + + bx lr + .size up_switchcontext, .-up_switchcontext + .end + diff --git a/arch/arm/src/armv6-m/up_systemreset.c b/arch/arm/src/armv6-m/up_systemreset.c new file mode 100644 index 0000000000000000000000000000000000000000..c5cafd9b8166da0898a7bcd44ddffd13aa5fd212 --- /dev/null +++ b/arch/arm/src/armv6-m/up_systemreset.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_systemreset.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Darcy Gong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" +#include "nvic.h" + +/**************************************************************************** + * Public functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_systemreset + * + * Description: + * Internal, Cortex-M0 reset logic. + * + ****************************************************************************/ + +void up_systemreset(void) +{ + uint32_t regval; + + /* Set up for the system reset, retaining the priority group from the + * the AIRCR register. + */ + + regval = ((0x5fa << SYSCON_AIRCR_VECTKEY_SHIFT) | SYSCON_AIRCR_SYSRESETREQ); + putreg32(regval, ARMV6M_SYSCON_AIRCR); + + /* Ensure completion of memory accesses */ + + __asm volatile ("dsb"); + + /* Wait for the reset */ + + for (; ; ); +} + + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. This function may or may not be supported by a + * particular board architecture. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not used by + * a board, the value zero may be provided in calls to board_reset. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_RESET +int board_reset(int status) +{ + up_systemreset(); + return 0; +} +#endif + diff --git a/arch/arm/src/armv6-m/up_unblocktask.c b/arch/arm/src/armv6-m/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..62ec07d90a31c2688a5283d50d78c2e1de8672d1 --- /dev/null +++ b/arch/arm/src/armv6-m/up_unblocktask.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_unblocktask.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list but has been prepped to + * execute. Move the TCB to the ready-to-run list, restore its context, + * and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is in one of the + * waiting tasks lists. It must be moved to the ready-to-run list and, + * if it is the highest priority ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv6-m/up_vectors.c b/arch/arm/src/armv6-m/up_vectors.c new file mode 100644 index 0000000000000000000000000000000000000000..b40d6c2887048b12232b2db0f99d45a7e3ffeb15 --- /dev/null +++ b/arch/arm/src/armv6-m/up_vectors.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/up_vectors.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Cloned from the ARMv7-M version: + * + * Copyright (C) 2012 Michael Smith. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define IDLE_STACK ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) + +#ifndef ARMV6M_PERIPHERAL_INTERRUPTS +# error ARMV6M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Chip-specific entrypoint */ + +extern void __start(void); + +/* Common exception entrypoint */ + +extern void exception_common(void); + +/************************************************************************************ + * Public data + ************************************************************************************/ + +/* Provided by the linker script to indicate the end of the BSS */ + +extern char _ebss; + +/* The v7m vector table consists of an array of function pointers, with the first + * slot (vector zero) used to hold the initial stack pointer. + * + * As all exceptions (interrupts) are routed via exception_common, we just need to + * fill this array with pointers to it. + * + * Note that the [ ... ] desginated initialiser is a GCC extension. + */ + +unsigned _vectors[] __attribute__((section(".vectors"))) = +{ + /* Initial stack */ + + IDLE_STACK, + + /* Reset exception handler */ + + (unsigned)&__start, + + /* Vectors 2 - n point directly at the generic handler */ + + [2 ... (15 + ARMV6M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common +}; diff --git a/arch/arm/src/armv6-m/vfork.S b/arch/arm/src/armv6-m/vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..20c003d3ea9fbb7b8d7dd22789810c28b31d5192 --- /dev/null +++ b/arch/arm/src/armv6-m/vfork.S @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/armv6-m/vfork.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_vfork.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .cpu cortex-m0 + .file "vfork.S" + .globl up_vfork + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the behavior is + * undefined if the process created by vfork() either modifies any data other than + * a variable of type pid_t used to store the return value from vfork(), or returns + * from the function in which vfork() was called, or calls any other function before + * successfully calling _exit() or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the vfork() + * context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and returns + * the process ID of the child process to the parent process. Otherwise, -1 is + * returned to the parent, no child process is created, and errno is set to + * indicate the error. + * + ************************************************************************************/ + + .align 2 + .code 16 + .thumb_func + .globl vfork + .type vfork, function +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + mov r1, sp + stmia r1!, {r4-r7} /* Save r4-r7 in the structure */ + mov r4, r8 /* Copy high registers to low registers */ + mov r5, r9 + mov r6, r10 + mov r7, fp + stmia r1!, {r4-r7} /* Save r8-r10 and fp in the structure */ + mov r5, lr /* Copy lr to a low register */ + stmia r1!, {r0,r5} /* Save sp and lr in the structure */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Recover r4-r7 that were destroyed before up_vfork was called */ + + mov r1, sp + ldmia r1!, {r4-r7} + + /* Release the stack data and return the value returned by up_vfork */ + + ldr r1, [sp, #VFORK_LR_OFFSET] + mov r14, r1 + add sp, sp, #VFORK_SIZEOF + bx lr + .size vfork, .-vfork + .end + diff --git a/arch/arm/src/armv7-a/Kconfig b/arch/arm/src/armv7-a/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..85ad10bbee0c202068ccec5d04ae73a1af94596c --- /dev/null +++ b/arch/arm/src/armv7-a/Kconfig @@ -0,0 +1,188 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "ARMv7-A Configuration Options" + +config ARMV7A_HAVE_GICv2 + bool + default n + ---help--- + Selected by the configuration tool if the architecture supports the + Generic Interrupt Controller (GIC) + +config ARMV7A_HAVE_GTM + bool + default n + ---help--- + Selected by the configuration tool if the architecture supports the + Global Timer (GTM) + +config ARMV7A_HAVE_PTM + bool + default n + ---help--- + Selected by the configuration tool if the architecture supports the + per-processor Private Timers (PTMs) + +config ARMV7A_HAVE_L2CC + bool + default n + ---help--- + Selected by the configuration tool if the architecture supports any + kind of L2 cache. + +config ARMV7A_HAVE_L2CC_PL310 + bool + default n + select ARMV7A_HAVE_L2CC + ---help--- + Set by architecture-specific code if the hardware supports a PL310 + r3p2 L2 cache (only version r3p2 is supported). + +if ARMV7A_HAVE_L2CC + +menu "L2 Cache Configuration" + +config ARMV7A_L2CC_PL310 + bool "ARMv7-A L2CC P310 Support" + default n + depends on ARMV7A_HAVE_L2CC_PL310 && EXPERIMENTAL + select ARCH_L2CACHE + ---help--- + Enable the 2 Cache Controller (L2CC) is based on the L2CC-PL310 ARM + multi-way cache macrocell, version r3p2. The addition of an on-chip + secondary cache, also referred to as a Level 2 or L2 cache, is a + method of improving the system performance when significant memory + traffic is generated by the processor. + +if ARCH_L2CACHE +if ARMV7A_L2CC_PL310 + +config PL310_LOCKDOWN_BY_MASTER + bool "PL310 Lockdown by Master" + default n + +config PL310_LOCKDOWN_BY_LINE + bool "PL310 Lockdown by Line" + default n + +config PL310_ADDRESS_FILTERING + bool "PL310 Address Filtering by Line" + default n + +endif # ARMV7A_L2CC_PL310 + +choice + prompt "L2 Cache Associativity" + default ARMV7A_ASSOCIATIVITY_8WAY + depends on ARCH_L2CACHE + ---help--- + This choice specifies the associativity of L2 cache in terms of the + number of ways. This value could be obtained by querying cache + configuration registers. However, by defining a configuration + setting instead, we can avoid using RAM memory to hold information + about properties of the memory. + +config ARMV7A_ASSOCIATIVITY_8WAY + bool "8-Way Associativity" + +config ARMV7A_ASSOCIATIVITY_16WAY + bool "16-Way Associativity" + +endchoice # L2 Cache Associativity + +choice + prompt "L2 Cache Way Size" + default ARMV7A_WAYSIZE_16KB + depends on ARCH_L2CACHE + ---help--- + This choice specifies size of each way. This value can be obtained + by querying cache configuration registers. However, by defining a + configuration setting instead, we can avoid using RAM memory to hold + information + +config ARMV7A_WAYSIZE_16KB + bool "16 KiB" + +config ARMV7A_WAYSIZE_32KB + bool "32 KiB" + +config ARMV7A_WAYSIZE_64KB + bool "64 KiB" + +config ARMV7A_WAYSIZE_128KB + bool "128 KiB" + +config ARMV7A_WAYSIZE_256KB + bool "256 KiB" + +config ARMV7A_WAYSIZE_512KB + bool "512 KiB" + +endchoice # L2 Cache Associativity +endif # ARCH_L2CACHE +endmenu # L2 Cache Configuration +endif # ARMV7A_HAVE_L2CC + +choice + prompt "Toolchain Selection" + default ARMV7A_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS + default ARMV7A_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS + +config ARMV7A_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + +config ARMV7A_TOOLCHAIN_CODESOURCERYL + bool "CodeSourcery GNU toolchain under Linux" + depends on HOST_LINUX + ---help--- + For use with the GNU toolchain built with the NuttX buildroot package. + This tools may be arm-nuttx-eabi- or, if ARMV7A_OABI_TOOLCHAIN is set, + arm-nuttx-elf-. + +config ARMV7A_TOOLCHAIN_CODESOURCERYW + bool "CodeSourcery GNU toolchain under Windows" + depends on HOST_WINDOWS + +config ARMV7A_TOOLCHAIN_DEVKITARM + bool "devkitARM GNU toolchain" + depends on HOST_WINDOWS + +config ARMV7A_TOOLCHAIN_GNU_EABIL + bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARMV7A_TOOLCHAIN_GNU_EABIW + bool "Generic GNU EABI toolchain under Windows" + depends on HOST_WINDOWS + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARMV7A_TOOLCHAIN_GNU_OABI + bool "Generic GNU OABI toolchain" + ---help--- + This option should work for any GNU toolchain configured for arm-elf-. + +endchoice # ARMV7A_HAVE_L2CC + +config ARMV7A_OABI_TOOLCHAIN + bool "OABI (vs EABI)" + default n + depends on ARMV7A_TOOLCHAIN_BUILDROOT + ---help--- + Most of the older buildroot toolchains are OABI and are named + arm-nuttx-elf- vs. arm-nuttx-eabi- + +config ARMV7A_DECODEFIQ + bool "FIQ Handler" + default n + ---help--- + Select this option if your platform supports the function + arm_decodefiq(). This is used primarily to support secure TrustZone + interrupts received on the FIQ vector. diff --git a/arch/arm/src/armv7-a/Toolchain.defs b/arch/arm/src/armv7-a/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..8ee6efdf2ad15f5604396f59a98c6230aeaa4ae5 --- /dev/null +++ b/arch/arm/src/armv7-a/Toolchain.defs @@ -0,0 +1,162 @@ +############################################################################ +# arch/arm/src/armv7-a/Toolchain.defs +# +# Copyright (C) 2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Select and allow the selected toolchain to be overridden by a command-line +#selection. +# + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_BUILDROOT) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_CODESOURCERYL) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= CODESOURCERYL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_CODESOURCERYW) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= CODESOURCERYW +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_DEVKITARM) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= DEVKITARM +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIL) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= GNU_EABIL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIW) \ + ),y) + CONFIG_ARMV7A_TOOLCHAIN ?= GNU_EABIW +endif + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +ifeq ($(CONFIG_ENDIAN_BIG),y) + TARGET_ARCH := armeb +else + TARGET_ARCH := arm +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),BUILDROOT) +ifeq ($(CONFIG_ARMV7A_OABI_TOOLCHAIN),y) + CROSSDEV ?= $(TARGET_ARCH)-nuttx-elf- + ARCROSSDEV ?= $(TARGET_ARCH)-nuttx-elf- +else + CROSSDEV ?= $(TARGET_ARCH)-nuttx-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-nuttx-eabi- +endif + MAXOPTIMIZATION ?= -Os +endif + +# CodeSourcery under Linux + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),CODESOURCERYL) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -O2 +endif + +# CodeSourcery under Windows + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),CODESOURCERYW) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -O2 + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# devkitARM under Windows + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),DEVKITARM) + CROSSDEV ?= $(TARGET_ARCH)-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),GNU_EABIL) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -Os +endif + +# Generic GNU EABI toolchain under Windows + +ifeq ($(CONFIG_ARMV7A_TOOLCHAIN),GNU_EABIW) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -Os + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif diff --git a/arch/arm/src/armv7-a/addrenv.h b/arch/arm/src/armv7-a/addrenv.h new file mode 100644 index 0000000000000000000000000000000000000000..653be5e26955ed9f61024c6b9e8b21e5d325f769 --- /dev/null +++ b/arch/arm/src/armv7-a/addrenv.h @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/addrenv.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_ADDRENV_H +#define __ARCH_ARM_SRC_ARMV7_A_ADDRENV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifdef CONFIG_ARCH_ADDRENV + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Aligned size of the kernel stack */ + +#ifdef CONFIG_ARCH_KERNEL_STACK +# define ARCH_KERNEL_STACKSIZE ((CONFIG_ARCH_KERNEL_STACKSIZE + 7) & ~7) +#endif + +/* Using a 4KiB page size, each 1MiB section maps to a PTE containing + * 256*2KiB entries + */ + +#define ENTRIES_PER_L2TABLE 256 + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_addrenv_create_region + * + * Description: + * Create one memory region. + * + * Returned Value: + * On success, the number of pages allocated is returned. Otherwise, a + * negated errno value is returned. + * + ****************************************************************************/ + +int arm_addrenv_create_region(FAR uintptr_t **list, unsigned int listlen, + uintptr_t vaddr, size_t regionsize, + uint32_t mmuflags); + +/**************************************************************************** + * Name: arm_addrenv_destroy_region + * + * Description: + * Destroy one memory region. + * + ****************************************************************************/ + +void arm_addrenv_destroy_region(FAR uintptr_t **list, unsigned int listlen, + uintptr_t vaddr, bool keep); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_ARCH_ADDRENV */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_ADDRENV_H */ diff --git a/arch/arm/src/armv7-a/arm.h b/arch/arm/src/armv7-a/arm.h new file mode 100644 index 0000000000000000000000000000000000000000..5d8d582289caa59687e1c48d08bc454376e3bbce --- /dev/null +++ b/arch/arm/src/armv7-a/arm.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm.h + * Non-CP15 Registers + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. + * ARM DDI 0406C.b (ID072512) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_ARM_H +#define __ARCH_ARM_SRC_ARMV7_A_ARM_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ARMv7-A ******************************************************************/ + +/* PSR bits */ + +#define PSR_MODE_SHIFT (0) /* Bits 0-4: Mode fields */ +#define PSR_MODE_MASK (31 << PSR_MODE_SHIFT) +# define PSR_MODE_USR (16 << PSR_MODE_SHIFT) /* User mode */ +# define PSR_MODE_FIQ (17 << PSR_MODE_SHIFT) /* FIQ mode */ +# define PSR_MODE_IRQ (18 << PSR_MODE_SHIFT) /* IRQ mode */ +# define PSR_MODE_SVC (19 << PSR_MODE_SHIFT) /* Supervisor mode */ +# define PSR_MODE_MON (22 << PSR_MODE_SHIFT) /* Monitor mode */ +# define PSR_MODE_ABT (23 << PSR_MODE_SHIFT) /* Abort mode */ +# define PSR_MODE_HYP (26 << PSR_MODE_SHIFT) /* Hyp mode */ +# define PSR_MODE_UND (27 << PSR_MODE_SHIFT) /* Undefined mode */ +# define PSR_MODE_SYS (31 << PSR_MODE_SHIFT) /* System mode */ +#define PSR_T_BIT (1 << 5) /* Bit 5: Thumb execution state bit */ +#define PSR_MASK_SHIFT (6) /* Bits 6-8: Mask Bits */ +#define PSR_MASK_MASK (7 << PSR_GE_SHIFT) +# define PSR_F_BIT (1 << 6) /* Bit 6: FIQ mask bit */ +# define PSR_I_BIT (1 << 7) /* Bit 7: IRQ mask bit */ +# define PSR_A_BIT (1 << 8) /* Bit 8: Asynchronous abort mask */ +#define PSR_E_BIT (1 << 9) /* Bit 9: Endianness execution state bit */ +#define PSR_GE_SHIFT (16) /* Bits 16-19: Greater than or Equal flags */ +#define PSR_GE_MASK (15 << PSR_GE_SHIFT) + /* Bits 20-23: Reserved. RAZ/SBZP */ +#define PSR_J_BIT (1 << 24) /* Bit 24: Jazelle state bit */ +#define PSR_IT01_SHIFT (25) /* Bits 25-26: If-Then execution state bits IT[0:1] */ +#define PSR_IT01_MASK (3 << PSR_IT01_SHIFT) +#define PSR_Q_BIT (1 << 27) /* Bit 27: Cumulative saturation bit */ +#define PSR_V_BIT (1 << 28) /* Bit 28: Overflow condition flag */ +#define PSR_C_BIT (1 << 29) /* Bit 29: Carry condition flag */ +#define PSR_Z_BIT (1 << 30) /* Bit 30: Zero condition flag */ +#define PSR_N_BIT (1 << 31) /* Bit 31: Negative condition flag */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: arm_data_initialize + * + * Description: + * Clear all of .bss to zero; set .data to the correct initial values + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_data_initialize(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_ARM_H */ diff --git a/arch/arm/src/armv7-a/arm_addrenv.c b/arch/arm/src/armv7-a/arm_addrenv.c new file mode 100644 index 0000000000000000000000000000000000000000..56d4d05ceea828193442f8513f1819e170621ccf --- /dev/null +++ b/arch/arm/src/armv7-a/arm_addrenv.c @@ -0,0 +1,831 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_addrenv.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Address Environment Interfaces + * + * Low-level interfaces used in binfmt/ to instantiate tasks with address + * environments. These interfaces all operate on type group_addrenv_t which + * is an abstract representation of a task group's address environment and + * must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined. + * + * up_addrenv_create - Create an address environment + * up_addrenv_destroy - Destroy an address environment. + * up_addrenv_vtext - Returns the virtual base address of the .text + * address environment + * up_addrenv_vdata - Returns the virtual base address of the .bss/.data + * address environment + * up_addrenv_heapsize - Returns the size of the initial heap allocation. + * up_addrenv_select - Instantiate an address environment + * up_addrenv_restore - Restore an address environment + * up_addrenv_clone - Copy an address environment from one location to + * another. + * + * Higher-level interfaces used by the tasking logic. These interfaces are + * used by the functions in sched/ and all operate on the thread which whose + * group been assigned an address environment by up_addrenv_clone(). + * + * up_addrenv_attach - Clone the address environment assigned to one TCB + * to another. This operation is done when a pthread + * is created that share's the same group address + * environment. + * up_addrenv_detach - Release the thread's reference to an address + * environment when a task/thread exits. + * + * CONFIG_ARCH_STACK_DYNAMIC=y indicates that the user process stack resides + * in its own address space. This options is also *required* if + * CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? + * Because the caller's stack must be preserved in its own address space + * when we instantiate the environment of the new process in order to + * initialize it. + * + * NOTE: The naming of the CONFIG_ARCH_STACK_DYNAMIC selection implies that + * dynamic stack allocation is supported. Certainly this option must be set + * if dynamic stack allocation is supported by a platform. But the more + * general meaning of this configuration environment is simply that the + * stack has its own address space. + * + * If CONFIG_ARCH_STACK_DYNAMIC=y is selected then the platform specific + * code must export these additional interfaces: + * + * up_addrenv_ustackalloc - Create a stack address environment + * up_addrenv_ustackfree - Destroy a stack address environment. + * up_addrenv_vustack - Returns the virtual base address of the stack + * up_addrenv_ustackselect - Instantiate a stack address environment + * + * If CONFIG_ARCH_KERNEL_STACK is selected, then each user process will have + * two stacks: (1) a large (and possibly dynamic) user stack and (2) a + * smaller kernel stack. However, this option is *required* if both + * CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? Because + * when we instantiate and initialize the address environment of the new + * user process, we will temporarily lose the address environment of the old + * user process, including its stack contents. The kernel C logic will crash + * immediately with no valid stack in place. + * + * If CONFIG_ARCH_KERNEL_STACK=y is selected then the platform specific + * code must export these additional interfaces: + * + * up_addrenv_kstackalloc - Create a stack in the kernel address environment + * up_addrenv_kstackfree - Destroy the kernel stack. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "pgalloc.h" +#include "cache.h" +#include "mmu.h" +#include "addrenv.h" + +#ifdef CONFIG_ARCH_ADDRENV + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration */ + +#if (CONFIG_ARCH_TEXT_VBASE & SECTION_MASK) != 0 +# error CONFIG_ARCH_TEXT_VBASE not aligned to section boundary +#endif + +#if (CONFIG_ARCH_DATA_VBASE & SECTION_MASK) != 0 +# error CONFIG_ARCH_DATA_VBASE not aligned to section boundary +#endif + +#if (CONFIG_ARCH_HEAP_VBASE & SECTION_MASK) != 0 +# error CONFIG_ARCH_HEAP_VBASE not aligned to section boundary +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addrenv_initdata + * + * Description: + * Initialize the region of memory at the the beginning of the .bss/.data + * region that is shared between the user process and the kernel. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +static int up_addrenv_initdata(uintptr_t l2table) +{ + irqstate_t flags; + FAR uint32_t *virtptr; + uintptr_t paddr; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + + DEBUGASSERT(l2table); + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page table address */ + + virtptr = (FAR uint32_t *)arm_pgvaddr(l2table); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(l2table & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + virtptr = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (l2table & SECTION_MASK)); +#endif + + /* Invalidate D-Cache so that we read from the physical memory */ + + arch_invalidate_dcache((uintptr_t)virtptr, + (uintptr_t)virtptr + sizeof(uint32_t)); + + /* Get the physical address of the first page of of .bss/.data */ + + paddr = (uintptr_t)(*virtptr) & PTE_SMALL_PADDR_MASK; + DEBUGASSERT(paddr); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page address */ + + virtptr = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + virtptr = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Finally, after of all of that, we can initialize the tiny region at + * the beginning of .bss/.data by setting it to zero. + */ + + memset(virtptr, 0, ARCH_DATA_RESERVE_SIZE); + + /* Make sure that the initialized data is flushed to physical memory. */ + + arch_flush_dcache((uintptr_t)virtptr, + (uintptr_t)virtptr + ARCH_DATA_RESERVE_SIZE); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + return OK; +} +#endif /* CONFIG_BUILD_KERNEL */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addrenv_create + * + * Description: + * This function is called when a new task is created in order to + * instantiate an address environment for the new task group. + * up_addrenv_create() is essentially the allocator of the physical + * memory for the new task. + * + * Input Parameters: + * textsize - The size (in bytes) of the .text address environment needed + * by the task. This region may be read/execute only. + * datasize - The size (in bytes) of the .data/.bss address environment + * needed by the task. This region may be read/write only. NOTE: The + * actual size of the data region that is allocated will include a + * OS private reserved region at the beginning. The size of the + * private, reserved region is give by ARCH_DATA_RESERVE_SIZE. + * heapsize - The initial size (in bytes) of the heap address environment + * needed by the task. This region may be read/write only. + * addrenv - The location to return the representation of the task address + * environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize, + FAR group_addrenv_t *addrenv) +{ + int ret; + + bvdbg("addrenv=%p textsize=%lu datasize=%lu\n", + addrenv, (unsigned long)textsize, (unsigned long)datasize); + + DEBUGASSERT(addrenv); + + /* Initialize the address environment structure to all zeroes */ + + memset(addrenv, 0, sizeof(group_addrenv_t)); + + /* Back the allocation up with physical pages and set up the level 2 mapping + * (which of course does nothing until the L2 page table is hooked into + * the L1 page table). + */ + + /* Allocate .text space pages */ + + ret = arm_addrenv_create_region(addrenv->text, ARCH_TEXT_NSECTS, + CONFIG_ARCH_TEXT_VBASE, textsize, + MMU_L2_UTEXTFLAGS); + if (ret < 0) + { + bdbg("ERROR: Failed to create .text region: %d\n", ret); + goto errout; + } + + /* Allocate .bss/.data space pages. NOTE that a configurable offset is + * added to the allocted size. This is matched by the offset that is + * used when reporting the virtual data address in up_addrenv_vdata(). + */ + + ret = arm_addrenv_create_region(addrenv->data, ARCH_DATA_NSECTS, + CONFIG_ARCH_DATA_VBASE, + datasize + ARCH_DATA_RESERVE_SIZE, + MMU_L2_UDATAFLAGS); + if (ret < 0) + { + bdbg("ERROR: Failed to create .bss/.data region: %d\n", ret); + goto errout; + } + +#ifdef CONFIG_BUILD_KERNEL + /* Initialize the shared data are at the beginning of the .bss/.data + * region. + */ + + ret = up_addrenv_initdata((uintptr_t)addrenv->data[0] & PMD_PTE_PADDR_MASK); + if (ret < 0) + { + bdbg("ERROR: Failed to initialize .bss/.data region: %d\n", ret); + goto errout; + } +#endif + +#ifdef CONFIG_BUILD_KERNEL + /* Allocate heap space pages */ + + ret = arm_addrenv_create_region(addrenv->heap, ARCH_HEAP_NSECTS, + CONFIG_ARCH_HEAP_VBASE, heapsize, + MMU_L2_UDATAFLAGS); + if (ret < 0) + { + bdbg("ERROR: Failed to create heap region: %d\n", ret); + goto errout; + } + + /* Save the initial heap size allocated. This will be needed when + * the heap data structures are initialized. + */ + + addrenv->heapsize = (size_t)ret << MM_PGSHIFT; +#endif + return OK; + +errout: + up_addrenv_destroy(addrenv); + return ret; +} + +/**************************************************************************** + * Name: up_addrenv_destroy + * + * Description: + * This function is called when a final thread leaves the task group and + * the task group is destroyed. This function then destroys the defunct + * address environment, releasing the underlying physical memory. + * + * Input Parameters: + * addrenv - The address environment to be destroyed. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_destroy(FAR group_addrenv_t *addrenv) +{ + bvdbg("addrenv=%p\n", addrenv); + DEBUGASSERT(addrenv); + + /* Destroy the .text region */ + + arm_addrenv_destroy_region(addrenv->text, ARCH_TEXT_NSECTS, + CONFIG_ARCH_TEXT_VBASE, false); + + /* Destroy the .bss/.data region */ + + arm_addrenv_destroy_region(addrenv->data, ARCH_DATA_NSECTS, + CONFIG_ARCH_DATA_VBASE, false); + +#ifdef CONFIG_BUILD_KERNEL + /* Destroy the heap region */ + + arm_addrenv_destroy_region(addrenv->heap, ARCH_HEAP_NSECTS, + CONFIG_ARCH_HEAP_VBASE, false); +#ifdef CONFIG_MM_SHM + /* Destroy the shared memory region (without freeing the physical page + * data). + */ + + arm_addrenv_destroy_region(addrenv->heap, ARCH_SHM_NSECTS, + CONFIG_ARCH_SHM_VBASE, true); +#endif +#endif + + memset(addrenv, 0, sizeof(group_addrenv_t)); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_vtext + * + * Description: + * Return the virtual address associated with the newly create .text + * address environment. This function is used by the binary loaders in + * order get an address that can be used to initialize the new task. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * vtext - The location to return the virtual address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_vtext(FAR group_addrenv_t *addrenv, FAR void **vtext) +{ + bvdbg("return=%p\n", (FAR void *)CONFIG_ARCH_TEXT_VBASE); + + /* Not much to do in this case */ + + DEBUGASSERT(addrenv && vtext); + *vtext = (FAR void *)CONFIG_ARCH_TEXT_VBASE; + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_vdata + * + * Description: + * Return the virtual address associated with the newly create .text + * address environment. This function is used by the binary loaders in + * order get an address that can be used to initialize the new task. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * textsize - For some implementations, the text and data will be saved + * in the same memory region (read/write/execute) and, in this case, + * the virtual address of the data just lies at this offset into the + * common region. + * vdata - The location to return the virtual address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize, + FAR void **vdata) +{ + bvdbg("return=%p\n", + (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE)); + + /* Not much to do in this case */ + + DEBUGASSERT(addrenv && vdata); + *vdata = (FAR void *)(CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_heapsize + * + * Description: + * Return the initial heap allocation size. That is the amount of memory + * allocated by up_addrenv_create() when the heap memory region was first + * created. This may or may not differ from the heapsize parameter that + * was passed to up_addrenv_create() + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * + * Returned Value: + * The initial heap size allocated is returned on success; a negated + * errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv) +{ + DEBUGASSERT(addrenv); + return (ssize_t)addrenv->heapsize; +} +#endif + +/**************************************************************************** + * Name: up_addrenv_select + * + * Description: + * After an address environment has been established for a task group (via + * up_addrenv_create(). This function may be called to to instantiate + * that address environment in the virtual address space. this might be + * necessary, for example, to load the code for the task group from a file or + * to access address environment private data. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * oldenv + * The address environment that was in place before up_addrenv_select(). + * This may be used with up_addrenv_restore() to restore the original + * address environment that was in place before up_addrenv_select() was + * called. Note that this may be a task agnostic, platform-specific + * representation that may or may not be different from group_addrenv_t. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_select(FAR const group_addrenv_t *addrenv, + FAR save_addrenv_t *oldenv) +{ + uintptr_t vaddr; + uintptr_t paddr; + int i; + + DEBUGASSERT(addrenv); + + for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0; + i < ARCH_TEXT_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Save the old L1 page table entry */ + + if (oldenv) + { + oldenv->text[i] = mmu_l1_getentry(vaddr); + } + + /* Set (or clear) the new page table entry */ + + paddr = (uintptr_t)addrenv->text[i]; + if (paddr) + { + mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); + } + else + { + mmu_l1_clrentry(vaddr); + } + } + + for (vaddr = CONFIG_ARCH_DATA_VBASE, i = 0; + i < ARCH_DATA_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Save the old L1 page table entry */ + + if (oldenv) + { + oldenv->data[i] = mmu_l1_getentry(vaddr); + } + + /* Set (or clear) the new page table entry */ + + paddr = (uintptr_t)addrenv->data[i]; + if (paddr) + { + mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); + } + else + { + mmu_l1_clrentry(vaddr); + } + } + +#ifdef CONFIG_BUILD_KERNEL + for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0; + i < ARCH_HEAP_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Save the old L1 page table entry */ + + if (oldenv) + { + oldenv->heap[i] = mmu_l1_getentry(vaddr); + } + + /* Set (or clear) the new page table entry */ + + paddr = (uintptr_t)addrenv->heap[i]; + if (paddr) + { + mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); + } + else + { + mmu_l1_clrentry(vaddr); + } + } + +#ifdef CONFIG_MM_SHM + for (vaddr = CONFIG_ARCH_SHM_VBASE, i = 0; + i < ARCH_SHM_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Save the old L1 page table entry */ + + if (oldenv) + { + oldenv->shm[i] = mmu_l1_getentry(vaddr); + } + + /* Set (or clear) the new page table entry */ + + paddr = (uintptr_t)addrenv->shm[i]; + if (paddr) + { + mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); + } + else + { + mmu_l1_clrentry(vaddr); + } + } + +#endif +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_restore + * + * Description: + * After an address environment has been temporarily instantiated by + * up_addrenv_select(), this function may be called to to restore the + * original address environment. + * + * Input Parameters: + * oldenv - The platform-specific representation of the address environment + * previously returned by up_addrenv_select. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_restore(FAR const save_addrenv_t *oldenv) +{ + uintptr_t vaddr; + int i; + + bvdbg("oldenv=%p\n", oldenv); + DEBUGASSERT(oldenv); + + for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0; + i < ARCH_TEXT_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Restore the L1 page table entry */ + + mmu_l1_restore(vaddr, oldenv->text[i]); + } + + for (vaddr = CONFIG_ARCH_DATA_VBASE, i = 0; + i < ARCH_DATA_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Restore the L1 page table entry */ + + mmu_l1_restore(vaddr, oldenv->data[i]); + } + +#ifdef CONFIG_BUILD_KERNEL + for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0; + i < ARCH_HEAP_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Restore the L1 page table entry */ + + mmu_l1_restore(vaddr, oldenv->heap[i]); + } + +#ifdef CONFIG_MM_SHM + for (vaddr = CONFIG_ARCH_SHM_VBASE, i = 0; + i < ARCH_SHM_NSECTS; + vaddr += SECTION_SIZE, i++) + { + /* Restore the L1 page table entry */ + + mmu_l1_restore(vaddr, oldenv->shm[i]); + } + +#endif +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_coherent + * + * Description: + * Flush D-Cache and invalidate I-Cache in preparation for a change in + * address environments. This should immediately precede a call to + * up_addrenv_select(); + * + * Input Parameters: + * addrenv - Describes the address environment to be made coherent. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_coherent(FAR const group_addrenv_t *addrenv) +{ + DEBUGASSERT(addrenv); + + /* Invalidate I-Cache */ + + cp15_invalidate_icache(); + + /* Clean D-Cache in each region. + * REVISIT: Cause crashes when trying to clean unmapped memory. In order + * for this to work, we need to know the exact size of each region (as we + * do now for the heap region). + */ + +#warning REVISIT... causes crashes +#if 0 + arch_clean_dcache(CONFIG_ARCH_TEXT_VBASE, + CONFIG_ARCH_TEXT_VBASE + + CONFIG_ARCH_TEXT_NPAGES * MM_PGSIZE - 1); + + arch_clean_dcache(CONFIG_ARCH_DATA_VBASE, + CONFIG_ARCH_DATA_VBASE + + CONFIG_ARCH_DATA_NPAGES * MM_PGSIZE - 1); +#endif + +#ifdef CONFIG_BUILD_KERNEL + arch_clean_dcache(CONFIG_ARCH_HEAP_VBASE, + CONFIG_ARCH_HEAP_VBASE + addrenv->heapsize); +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_clone + * + * Description: + * Duplicate an address environment. This does not copy the underlying + * memory, only the representation that can be used to instantiate that + * memory as an address environment. + * + * Input Parameters: + * src - The address environment to be copied. + * dest - The location to receive the copied address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_clone(FAR const group_addrenv_t *src, + FAR group_addrenv_t *dest) +{ + bvdbg("src=%p dest=%p\n", src, dest); + DEBUGASSERT(src && dest); + + /* Just copy the address environment from the source to the destination */ + + memcpy(dest, src, sizeof(group_addrenv_t)); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_attach + * + * Description: + * This function is called from the core scheduler logic when a thread + * is created that needs to share the address environment of its task + * group. + * + * NOTE: In some platforms, nothing will need to be done in this case. + * Simply being a member of the group that has the address environment + * may be sufficient. + * + * Input Parameters: + * group - The task group to which the new thread belongs. + * tcb - The TCB of the thread needing the address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb) +{ + bvdbg("group=%p tcb=%p\n", group, tcb); + + /* Nothing needs to be done in this implementation */ + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_detach + * + * Description: + * This function is called when a task or thread exits in order to release + * its reference to an address environment. The address environment, + * however, should persist until up_addrenv_destroy() is called when the + * task group is itself destroyed. Any resources unique to this thread + * may be destroyed now. + * + * NOTE: In some platforms, nothing will need to be done in this case. + * Simply being a member of the group that has the address environment + * may be sufficient. + * + * Input Parameters: + * group - The group to which the thread belonged. + * tcb - The TCB of the task or thread whose the address environment will + * be released. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb) +{ + bvdbg("group=%p tcb=%p\n", group, tcb); + + /* Nothing needs to be done in this implementation */ + + return OK; +} + +#endif /* CONFIG_ARCH_ADDRENV */ diff --git a/arch/arm/src/armv7-a/arm_addrenv_kstack.c b/arch/arm/src/armv7-a/arm_addrenv_kstack.c new file mode 100644 index 0000000000000000000000000000000000000000..852b03620b9bbcd7453ca014cebfb8d430b9ddcd --- /dev/null +++ b/arch/arm/src/armv7-a/arm_addrenv_kstack.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_addrenv_kstack.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Address Environment Interfaces + * + * Low-level interfaces used in binfmt/ to instantiate tasks with address + * environments. These interfaces all operate on type group_addrenv_t which + * is an abstract representation of a task group's address environment and + * must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined. + * + * up_addrenv_create - Create an address environment + * up_addrenv_destroy - Destroy an address environment. + * up_addrenv_vtext - Returns the virtual base address of the .text + * address environment + * up_addrenv_vdata - Returns the virtual base address of the .bss/.data + * address environment + * up_addrenv_heapsize - Returns the size of the initial heap allocation. + * up_addrenv_select - Instantiate an address environment + * up_addrenv_restore - Restore an address environment + * up_addrenv_clone - Copy an address environment from one location to + * another. + * + * Higher-level interfaces used by the tasking logic. These interfaces are + * used by the functions in sched/ and all operate on the thread which whose + * group been assigned an address environment by up_addrenv_clone(). + * + * up_addrenv_attach - Clone the address environment assigned to one TCB + * to another. This operation is done when a pthread + * is created that share's the same group address + * environment. + * up_addrenv_detach - Release the thread's reference to an address + * environment when a task/thread exits. + * + * CONFIG_ARCH_STACK_DYNAMIC=y indicates that the user process stack resides + * in its own address space. This options is also *required* if + * CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? + * Because the caller's stack must be preserved in its own address space + * when we instantiate the environment of the new process in order to + * initialize it. + * + * NOTE: The naming of the CONFIG_ARCH_STACK_DYNAMIC selection implies that + * dynamic stack allocation is supported. Certainly this option must be set + * if dynamic stack allocation is supported by a platform. But the more + * general meaning of this configuration environment is simply that the + * stack has its own address space. + * + * If CONFIG_ARCH_STACK_DYNAMIC=y is selected then the platform specific + * code must export these additional interfaces: + * + * up_addrenv_ustackalloc - Create a stack address environment + * up_addrenv_ustackfree - Destroy a stack address environment. + * up_addrenv_vustack - Returns the virtual base address of the stack + * up_addrenv_ustackselect - Instantiate a stack address environment + * + * If CONFIG_ARCH_KERNEL_STACK is selected, then each user process will have + * two stacks: (1) a large (and possibly dynamic) user stack and (2) a + * smaller kernel stack. However, this option is *required* if both + * CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? Because + * when we instantiate and initialize the address environment of the new + * user process, we will temporarily lose the address environment of the old + * user process, including its stack contents. The kernel C logic will crash + * immediately with no valid stack in place. + * + * If CONFIG_ARCH_KERNEL_STACK=y is selected then the platform specific + * code must export these additional interfaces: + * + * up_addrenv_kstackalloc - Create a stack in the kernel address environment + * up_addrenv_kstackfree - Destroy the kernel stack. + * up_addrenv_vkstack - Return the base address of the kernel stack + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "addrenv.h" + +#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_KERNEL_STACK) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addrenv_kstackalloc + * + * Description: + * This function is called when a new thread is created to allocate + * the new thread's kernel stack. This function may be called for certain + * terminating threads which have no kernel stack. It must be tolerant of + * that case. + * + * Input Parameters: + * tcb - The TCB of the thread that requires the kernel stack. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_kstackalloc(FAR struct tcb_s *tcb) +{ + bvdbg("tcb=%p stacksize=%u\n", tcb, ARCH_KERNEL_STACKSIZE); + + DEBUGASSERT(tcb && tcb->xcp.kstack == 0); + + /* Allocate the kernel stack */ + + tcb->xcp.kstack = (FAR uint32_t *)kmm_memalign(8, ARCH_KERNEL_STACKSIZE); + if (!tcb->xcp.kstack) + { + bdbg("ERROR: Failed to allocate the kernel stack\n"); + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_kstackfree + * + * Description: + * This function is called when any thread exits. This function frees + * the kernel stack. + * + * Input Parameters: + * tcb - The TCB of the thread that no longer requires the kernel stack. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_kstackfree(FAR struct tcb_s *tcb) +{ + bvdbg("tcb=%p\n", tcb); + DEBUGASSERT(tcb); + + /* Does the exiting thread have a kernel stack? */ + + if (tcb->xcp.kstack) + { + /* Yes.. Free the kernel stack */ + + kmm_free(tcb->xcp.kstack); + tcb->xcp.kstack = NULL; + } + + return OK; +} + +#endif /* CONFIG_ARCH_ADDRENV && CONFIG_ARCH_KERNEL_STACK */ diff --git a/arch/arm/src/armv7-a/arm_addrenv_shm.c b/arch/arm/src/armv7-a/arm_addrenv_shm.c new file mode 100644 index 0000000000000000000000000000000000000000..3bd2715350aad3ffb93e74d860367e42cf29b8cb --- /dev/null +++ b/arch/arm/src/armv7-a/arm_addrenv_shm.c @@ -0,0 +1,343 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_addrenv_shm.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "mmu.h" +#include "cache.h" +#include "addrenv.h" +#include "pgalloc.h" + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_shmat + * + * Description: + * Attach, i.e, map, on shared memory region to a user virtual address + * + * Input Parameters: + * pages - A pointer to the first element in a array of physical address, + * each corresponding to one page of memory. + * npages - The number of pages in the list of physical pages to be mapped. + * vaddr - The virtual address corresponding to the beginning of the + * (contiguous) virtual address region. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int up_shmat(FAR uintptr_t *pages, unsigned int npages, uintptr_t vaddr) +{ + FAR struct tcb_s *tcb = sched_self(); + FAR struct task_group_s *group; + FAR uintptr_t *l1entry; + FAR uint32_t *l2table; + irqstate_t flags; + uintptr_t paddr; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + unsigned int nmapped; + unsigned int shmndx; + + shmvdbg("pages=%p npages=%d vaddr=%08lx\n", + pages, npages, (unsigned long)vaddr); + + /* Sanity checks */ + + DEBUGASSERT(pages && npages > 0 && tcb && tcb->group); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(MM_ISALIGNED(vaddr)); + + group = tcb->group; + + /* Loop until all pages have been mapped into the caller's address space. */ + + for (nmapped = 0; nmapped < npages; ) + { + /* Get the shm[] index associated with the virtual address */ + + shmndx = (vaddr - CONFIG_ARCH_SHM_VBASE) >> SECTION_SHIFT; + + /* Has a level 1 page table entry been created for this virtual address */ + + l1entry = group->tg_addrenv.shm[shmndx]; + if (l1entry == NULL) + { + /* No.. Allocate one physical page for the L2 page table */ + + paddr = mm_pgalloc(1); + if (!paddr) + { + return -ENOMEM; + } + + DEBUGASSERT(MM_ISALIGNED(paddr)); + + /* We need to be more careful after we begin modifying + * global resources. + */ + + flags = enter_critical_section(); + group->tg_addrenv.shm[shmndx] = (FAR uintptr_t *)paddr; + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page + * address. + */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, + MMU_MEMFLAGS); + l2table = (FAR uint32_t *) + (ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Initialize the page table */ + + memset(l2table, 0, ENTRIES_PER_L2TABLE * sizeof(uint32_t)); + } + else + { + /* Get the physical address of the L2 page table from the L1 page + * table entry. + */ + + paddr = (uintptr_t)l1entry & ~SECTION_MASK; + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page\ + * address. + */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, + MMU_MEMFLAGS); + l2table = (FAR uint32_t *) + (ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + } + + /* Map the virtual address to this physical address */ + + DEBUGASSERT(get_l2_entry(l2table, vaddr) == 0); + + paddr = *pages++; + set_l2_entry(l2table, paddr, vaddr, MMU_MEMFLAGS); + nmapped++; + vaddr += MM_PGSIZE; + + /* Make sure that the initialized L2 table is flushed to physical + * memory. + * + * REVISIT: We could be smarter in doing this. Currently, we may + * flush the entire L2 page table numerous times. + */ + + arch_flush_dcache((uintptr_t)l2table, + (uintptr_t)l2table + + ENTRIES_PER_L2TABLE * sizeof(uint32_t)); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + } + + return OK; +} + +/**************************************************************************** + * Name: up_shmdt + * + * Description: + * Detach, i.e, unmap, on shared memory region from a user virtual address + * + * Input Parameters: + * vaddr - The virtual address corresponding to the beginning of the + * (contiguous) virtual address region. + * npages - The number of pages to be unmapped + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int up_shmdt(uintptr_t vaddr, unsigned int npages) +{ + FAR struct tcb_s *tcb = sched_self(); + FAR struct task_group_s *group; + FAR uintptr_t *l1entry; + FAR uint32_t *l2table; + irqstate_t flags; + uintptr_t paddr; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + unsigned int nunmapped; + unsigned int shmndx; + + shmvdbg("npages=%d vaddr=%08lx\n", npages, (unsigned long)vaddr); + + /* Sanity checks */ + + DEBUGASSERT(npages > 0 && tcb && tcb->group); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(MM_ISALIGNED(vaddr)); + + group = tcb->group; + + /* Loop until all pages have been unmapped from the caller's address + * space. + */ + + for (nunmapped = 0; nunmapped < npages; ) + { + /* Get the shm[] index associated with the virtual address */ + + shmndx = (vaddr - CONFIG_ARCH_SHM_VBASE) >> SECTION_SHIFT; + + /* Get the level 1 page table entry for this virtual address */ + + l1entry = group->tg_addrenv.shm[shmndx]; + DEBUGASSERT(l1entry != NULL); + + /* Get the physical address of the L2 page table from the L1 page + * table entry. + */ + + paddr = (uintptr_t)l1entry & ~SECTION_MASK; + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page + * address. + */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, + MMU_MEMFLAGS); + l2table = (FAR uint32_t *) + (ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Unmap this virtual page address. + * + * REVISIT: Note that the page allocated for the level 2 page table + * is not freed nor is the level 1 page table entry ever cleared. + * This means that the 4KiB page is still allocated to the process + * even though it may not contain any mappings and that the it will + * persist until the process terminates. That is not all bad because + * it means that we will be able to re-instantiate the shared memory + * mapping very quickly. + */ + + DEBUGASSERT(get_l2_entry(l2table, vaddr) != 0); + + clr_l2_entry(l2table, vaddr); + nunmapped++; + vaddr += MM_PGSIZE; + + /* Make sure that the modified L2 table is flushed to physical + * memory. + * + * REVISIT: We could be smarter in doing this. Currently, we may + * flush the entire L2 page table numerous times. + */ + + arch_flush_dcache((uintptr_t)l2table, + (uintptr_t)l2table + + ENTRIES_PER_L2TABLE * sizeof(uint32_t)); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + } + + return OK; +} + +#endif /* CONFIG_BUILD_KERNEL && CONFIG_MM_SHM */ diff --git a/arch/arm/src/armv7-a/arm_addrenv_ustack.c b/arch/arm/src/armv7-a/arm_addrenv_ustack.c new file mode 100644 index 0000000000000000000000000000000000000000..97da35992ff5016c8c6e78c7775992c0fb1dbd30 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_addrenv_ustack.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_addrenv_ustack.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Address Environment Interfaces + * + * Low-level interfaces used in binfmt/ to instantiate tasks with address + * environments. These interfaces all operate on type group_addrenv_t which + * is an abstract representation of a task group's address environment and + * must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined. + * + * up_addrenv_create - Create an address environment + * up_addrenv_destroy - Destroy an address environment. + * up_addrenv_vtext - Returns the virtual base address of the .text + * address environment + * up_addrenv_vdata - Returns the virtual base address of the .bss/.data + * address environment + * up_addrenv_heapsize - Returns the size of the initial heap allocation. + * up_addrenv_select - Instantiate an address environment + * up_addrenv_restore - Restore an address environment + * up_addrenv_clone - Copy an address environment from one location to + * another. + * + * Higher-level interfaces used by the tasking logic. These interfaces are + * used by the functions in sched/ and all operate on the thread which whose + * group been assigned an address environment by up_addrenv_clone(). + * + * up_addrenv_attach - Clone the address environment assigned to one TCB + * to another. This operation is done when a pthread + * is created that share's the same address + * environment. + * up_addrenv_detach - Release the threads reference to an address + * environment when a task/thread exits. + * + * CONFIG_ARCH_STACK_DYNAMIC=y indicates that the user process stack resides + * in its own address space. This options is also *required* if + * CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? + * Because the caller's stack must be preserved in its own address space + * when we instantiate the environment of the new process in order to + * initialize it. + * + * NOTE: The naming of the CONFIG_ARCH_STACK_DYNAMIC selection implies that + * dynamic stack allocation is supported. Certainly this option must be set + * if dynamic stack allocation is supported by a platform. But the more + * general meaning of this configuration environment is simply that the + * stack has its own address space. + * + * If CONFIG_ARCH_KERNEL_STACK=y is selected then the platform specific + * code must export these additional interfaces: + * + * up_addrenv_ustackalloc - Create a stack address environment + * up_addrenv_ustackfree - Destroy a stack address environment. + * up_addrenv_vustack - Returns the virtual base address of the stack + * up_addrenv_ustackselect - Instantiate a stack address environment + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "mmu.h" +#include "addrenv.h" + +#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration */ + +#if (CONFIG_ARCH_STACK_VBASE & SECTION_MASK) != 0 +# error CONFIG_ARCH_STACK_VBASE not aligned to section boundary +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addrenv_ustackalloc + * + * Description: + * This function is called when a new thread is created in order to + * instantiate an address environment for the new thread's stack. + * up_addrenv_ustackalloc() is essentially the allocator of the physical + * memory for the new task's stack. + * + * Input Parameters: + * tcb - The TCB of the thread that requires the stack address environment. + * stacksize - The size (in bytes) of the initial stack address + * environment needed by the task. This region may be read/write only. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_ustackalloc(FAR struct tcb_s *tcb, size_t stacksize) +{ + int ret; + + bvdbg("tcb=%p stacksize=%lu\n", tcb, (unsigned long)stacksize); + + DEBUGASSERT(tcb); + + /* Initialize the address environment list to all zeroes */ + + memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); + + /* Back the allocation up with physical pages and set up the level 2 mapping + * (which of course does nothing until the L2 page table is hooked into + * the L1 page table). + */ + + /* Allocate .text space pages */ + + ret = arm_addrenv_create_region(tcb->xcp.ustack, ARCH_STACK_NSECTS, + CONFIG_ARCH_STACK_VBASE, stacksize, + MMU_L2_UDATAFLAGS); + if (ret < 0) + { + bdbg("ERROR: Failed to create stack region: %d\n", ret); + up_addrenv_ustackfree(tcb); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_ustackfree + * + * Description: + * This function is called when any thread exits. This function then + * destroys the defunct address environment for the thread's stack, + * releasing the underlying physical memory. + * + * Input Parameters: + * tcb - The TCB of the thread that no longer requires the stack address + * environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_ustackfree(FAR struct tcb_s *tcb) +{ + bvdbg("tcb=%p\n", tcb); + DEBUGASSERT(tcb); + + /* Destroy the stack region */ + + arm_addrenv_destroy_region(tcb->xcp.ustack, ARCH_STACK_NSECTS, + CONFIG_ARCH_STACK_VBASE, false); + + memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_vustack + * + * Description: + * Return the virtual address associated with the newly created stack + * address environment. + * + * Input Parameters: + * tcb - The TCB of the thread with the stack address environment of + * interest. + * vstack - The location to return the stack virtual base address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_vustack(FAR const struct tcb_s *tcb, FAR void **vstack) +{ + bvdbg("Return=%p\n", (FAR void *)CONFIG_ARCH_STACK_VBASE); + + /* Not much to do in this case */ + + DEBUGASSERT(tcb); + *vstack = (FAR void *)CONFIG_ARCH_STACK_VBASE; + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_ustackselect + * + * Description: + * After an address environment has been established for a task's stack + * (via up_addrenv_ustackalloc(). This function may be called to instantiate + * that address environment in the virtual address space. This is a + * necessary step before each context switch to the newly created thread + * (including the initial thread startup). + * + * Input Parameters: + * tcb - The TCB of the thread with the stack address environment to be + * instantiated. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_ustackselect(FAR const struct tcb_s *tcb) +{ + uintptr_t vaddr; + uintptr_t paddr; + int i; + + DEBUGASSERT(tcb); + + for (vaddr = CONFIG_ARCH_STACK_VBASE, i = 0; + i < ARCH_TEXT_NSECTS; + vaddr += ARCH_STACK_NSECTS, i++) + { + /* Set (or clear) the new page table entry */ + + paddr = (uintptr_t)tcb->xcp.ustack[i]; + if (paddr) + { + mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); + } + else + { + mmu_l1_clrentry(vaddr); + } + } + + return OK; +} + +#endif /* CONFIG_ARCH_ADDRENV && CONFIG_ARCH_STACK_DYNAMIC */ diff --git a/arch/arm/src/armv7-a/arm_addrenv_utils.c b/arch/arm/src/armv7-a/arm_addrenv_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..fc62c9b12619fde6aa21db72119023a8a077dfa5 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_addrenv_utils.c @@ -0,0 +1,277 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_addrenv.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include + +#include "cache.h" +#include "mmu.h" +#include "pgalloc.h" +#include "addrenv.h" + +#ifdef CONFIG_ARCH_ADDRENV + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_addrenv_create_region + * + * Description: + * Create one memory region. + * + * Returned Value: + * On success, the number of pages allocated is returned. Otherwise, a + * negated errno value is returned. + * + ****************************************************************************/ + +int arm_addrenv_create_region(FAR uintptr_t **list, unsigned int listlen, + uintptr_t vaddr, size_t regionsize, + uint32_t mmuflags) +{ + irqstate_t flags; + uintptr_t paddr; + FAR uint32_t *l2table; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + size_t nmapped; + unsigned int npages; + unsigned int i; + unsigned int j; + + bvdbg("listlen=%d vaddr=%08lx regionsize=%ld, mmuflags=%08x\n", + listlen, (unsigned long)vaddr, (unsigned long)regionsize, + (unsigned int)mmuflags); + + /* Verify that we are configured with enough virtual address space to + * support this memory region. + * + * npages pages corresponds to (npages << MM_PGSHIFT) bytes + * listlen sections corresponds to (listlen << 20) bytes + */ + + npages = MM_NPAGES(regionsize); + if (npages > (listlen << (20 - MM_PGSHIFT))) + { + bdbg("ERROR: npages=%u listlen=%u\n", npages, listlen); + return -E2BIG; + } + + /* Back the allocation up with physical pages and set up the level mapping + * (which of course does nothing until the L2 page table is hooked into + * the L1 page table). + */ + + nmapped = 0; + for (i = 0; i < npages; i += ENTRIES_PER_L2TABLE) + { + /* Allocate one physical page for the L2 page table */ + + paddr = mm_pgalloc(1); + if (!paddr) + { + return -ENOMEM; + } + + DEBUGASSERT(MM_ISALIGNED(paddr)); + list[i] = (FAR uintptr_t *)paddr; + + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page address */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + l2table = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Initialize the page table */ + + memset(l2table, 0, ENTRIES_PER_L2TABLE * sizeof(uint32_t)); + + /* Back up L2 entries with physical memory */ + + for (j = 0; j < ENTRIES_PER_L2TABLE && nmapped < regionsize; j++) + { + /* Allocate one physical page for region data */ + + paddr = mm_pgalloc(1); + if (!paddr) + { +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + return -ENOMEM; + } + + /* Map the virtual address to this physical address */ + + set_l2_entry(l2table, paddr, vaddr, mmuflags); + nmapped += MM_PGSIZE; + vaddr += MM_PGSIZE; + } + + /* Make sure that the initialized L2 table is flushed to physical + * memory. + */ + + arch_flush_dcache((uintptr_t)l2table, + (uintptr_t)l2table + + ENTRIES_PER_L2TABLE * sizeof(uint32_t)); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + } + + return npages; +} + +/**************************************************************************** + * Name: arm_addrenv_destroy_region + * + * Description: + * Destroy one memory region. + * + ****************************************************************************/ + +void arm_addrenv_destroy_region(FAR uintptr_t **list, unsigned int listlen, + uintptr_t vaddr, bool keep) +{ + irqstate_t flags; + uintptr_t paddr; + FAR uint32_t *l2table; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + int i; + int j; + + bvdbg("listlen=%d vaddr=%08lx\n", listlen, (unsigned long)vaddr); + + for (i = 0; i < listlen; vaddr += SECTION_SIZE, list++, i++) + { + /* Unhook the L2 page table from the L1 page table */ + + mmu_l1_clrentry(vaddr); + + /* Has this page table been allocated? */ + + paddr = (uintptr_t)list[i]; + if (paddr != 0) + { + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page address */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + l2table = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Return the allocated pages to the page allocator unless we were + * asked to keep the page data. We keep the page data only for + * the case of shared memory. In that case, we need to tear down + * the mapping and page table entries, but keep the raw page data + * will still may be mapped by other user processes. + */ + + if (!keep) + { + for (j = 0; j < ENTRIES_PER_L2TABLE; j++) + { + paddr = *l2table++; + if (paddr != 0) + { + paddr &= PTE_SMALL_PADDR_MASK; + mm_pgfree(paddr, 1); + } + } + } + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + + /* And free the L2 page table itself */ + + mm_pgfree((uintptr_t)list[i], 1); + } + } +} + +#endif /* CONFIG_ARCH_ADDRENV */ diff --git a/arch/arm/src/armv7-a/arm_allocpage.c b/arch/arm/src/armv7-a/arm_allocpage.c new file mode 100644 index 0000000000000000000000000000000000000000..39ffea6e21e2d39e2db74093f5326dce8ffcf608 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_allocpage.c @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_allocpage.c + * Allocate a new page and map it to the fault address of a task. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PAGING + +#include + +#include "pg_macros.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#if CONFIG_PAGING_NPPAGED < 256 +typedef uint8_t pgndx_t; +#elif CONFIG_PAGING_NPPAGED < 65536 +typedef uint16_t pgndx_t; +#else +typedef uint32_t pgndx_t; +#endif + +#if PG_POOL_MAXL1NDX < 256 +typedef uint8_t L1ndx_t; +#elif PG_POOL_MAXL1NDX < 65536 +typedef uint16_t L1ndx_t; +#else +typedef uint32_t L1ndx_t; +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Free pages in memory are managed by indices ranging from up to + * CONFIG_PAGING_NPAGED. Initially all pages are free so the page can be + * simply allocated in order: 0, 1, 2, ... . After all CONFIG_PAGING_NPAGED + * pages have be filled, then they are blindly freed and re-used in the + * same order 0, 1, 2, ... because we don't know any better. No smart "least + * recently used" kind of logic is supported. + */ + +static pgndx_t g_pgndx; + +/* After CONFIG_PAGING_NPAGED have been allocated, the pages will be re-used. + * In order to re-used the page, we will have un-map the page from its previous + * mapping. In order to that, we need to be able to map a physical address to + * to an index into the PTE where it was mapped. The following table supports + * this backward lookup - it is indexed by the page number index, and holds + * another index to the mapped virtual page. + */ + +static L1ndx_t g_ptemap[CONFIG_PAGING_NPPAGED]; + +/* The contents of g_ptemap[] are not valid until g_pgndx has wrapped at + * least one time. + */ + +static bool g_pgwrap; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_allocpage() + * + * Description: + * This architecture-specific function will set aside page in memory and map + * the page to its correct virtual address. Architecture-specific context + * information saved within the TCB will provide the function with the + * information needed to identify the virtual miss address. + * + * This function will return the allocated physical page address in vpage. + * The size of the underlying physical page is determined by the + * configuration setting CONFIG_PAGING_PAGESIZE. + * + * NOTE 1: This function must always return a page allocation. If all + * available pages are in-use (the typical case), then this function will + * select a page in-use, un-map it, and make it available. + * + * NOTE 2: If an in-use page is un-mapped, it may be necessary to flush the + * instruction cache in some architectures. + * + * NOTE 3: Allocating and filling a page is a two step process. arm_allocpage() + * allocates the page, and up_fillpage() fills it with data from some non- + * volatile storage device. This distinction is made because arm_allocpage() + * can probably be implemented in board-independent logic whereas up_fillpage() + * probably must be implemented as board-specific logic. + * + * NOTE 4: The initial mapping of vpage should be read-able and write- + * able (but not cached). No special actions will be required of + * up_fillpage() in order to write into this allocated page. + * + * Input Parameters: + * tcb - A reference to the task control block of the task that needs to + * have a page fill. Architecture-specific logic can retrieve page + * fault information from the architecture-specific context + * information in this TCB to perform the mapping. + * + * Returned Value: + * This function will return zero (OK) if the allocation was successful. + * A negated errno value may be returned if an error occurs. All errors, + * however, are fatal. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +int arm_allocpage(FAR struct tcb_s *tcb, FAR void **vpage) +{ + uintptr_t vaddr; + uintptr_t paddr; + uint32_t *pte; + unsigned int pgndx; + + /* Since interrupts are disabled, we don't need to anything special. */ + + DEBUGASSERT(tcb && vpage); + + /* Get the virtual address that caused the fault */ + + vaddr = tcb->xcp.far; + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Allocate page memory to back up the mapping. Start by getting the + * index of the next page that we are going to allocate. + */ + + pgndx = g_pgndx++; + if (g_pgndx >= CONFIG_PAGING) + { + g_pgndx = 0; + g_pgwrap = true; + } + + /* Was this physical page previously mapped? If so, then we need to un-map + * it. + */ + + if (g_pgwrap) + { + /* Yes.. Get a pointer to the L2 entry corresponding to the previous + * mapping -- then zero it! + */ + + uintptr_t oldvaddr = PG_POOL_NDX2VA(g_ptemap[pgndx]); + pte = arm_va2pte(oldvaddr); + *pte = 0; + + /* Invalidate the instruction TLB corresponding to the virtual address */ + + tlb_inst_invalidate_single(oldvaddr); + + /* I do not believe that it is necessary to flush the I-Cache in this + * case: The I-Cache uses a virtual address index and, hence, since the + * NuttX address space is flat, the cached instruction value should be + * correct even if the page mapping is no longer in place. + */ + } + + /* Then convert the index to a (physical) page address. */ + + paddr = PG_POOL_PGPADDR(pgndx); + + /* Now setup up the new mapping. Get a pointer to the L2 entry + * corresponding to the new mapping. Then set it map to the newly + * allocated page address. The inital mapping is read/write but + * non-cached (MMU_L2_ALLOCFLAGS) + */ + + pte = arm_va2pte(vaddr); + *pte = (paddr | MMU_L2_ALLOCFLAGS); + + /* And save the new L1 index */ + + g_ptemap[pgndx] = PG_POOL_VA2L2NDX(vaddr); + + /* Finally, return the virtual address of allocated page */ + + *vpage = (void *)(vaddr & ~PAGEMASK); + return OK; +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..00c730919c7474455e853ce84e6ca4414fb52998 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_assert.c @@ -0,0 +1,412 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_assert.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump(sp,stack_base) +#endif + +/**************************************************************************** + * Name: up_taskdump + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg) +{ + /* Dump interesting properties of this task */ + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("%s: PID=%d Stack Used=%lu of %lu\n", + tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#else + lldbg("PID: %d Stack Used=%lu of %lu\n", + tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#endif +} +#endif + +/**************************************************************************** + * Name: up_showtasks + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static inline void up_showtasks(void) +{ + /* Dump interesting properties of each task in the crash environment */ + + sched_foreach(up_taskdump, NULL); +} +#else +# define up_showtasks() +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (CURRENT_REGS) + { + int regs; + + /* Yes.. dump the interrupt registers */ + + for (regs = REG_R0; regs <= REG_R15; regs += 8) + { + uint32_t *ptr = (uint32_t *)&CURRENT_REGS[regs]; + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } + + lldbg("CPSR: %08x\n", CURRENT_REGS[REG_CPSR]); + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif +#ifdef CONFIG_ARCH_KERNEL_STACK + uint32_t kstackbase = 0; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + lldbg("Current sp: %08x\n", sp); + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Get the limits on the interrupt stack memory */ + + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + + /* Show interrupt stack info */ + + lldbg("Interrupt stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif +#endif + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* This this thread have a kernel stack allocated? */ + + if (rtcb->xcp.kstack) + { + kstackbase = (uint32_t)rtcb->xcp.kstack + CONFIG_ARCH_KERNEL_STACKSIZE - 4; + + lldbg("Kernel stack:\n"); + lldbg(" base: %08x\n", kstackbase); + lldbg(" size: %08x\n", CONFIG_ARCH_KERNEL_STACKSIZE); + } +#endif + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Does the current stack pointer lie within the interrupt stack? */ + + if (sp > istackbase - istacksize && sp < istackbase) + { + /* Yes.. dump the interrupt stack */ + + lldbg("Interrupt Stack\n", sp); + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("User sp: %08x\n", sp); + } +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase - ustacksize && sp < ustackbase) + { + lldbg("User Stack\n", sp); + up_stackdump(sp, ustackbase); + } + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* Dump the user stack if the stack pointer lies within the allocated + * kernel stack memory. + */ + + if (sp >= (uint32_t)rtcb->xcp.kstack && sp < kstackbase) + { + lldbg("Kernel Stack\n", sp); + up_stackdump(sp, kstackbase); + } +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); + + /* Dump the state of all tasks (if available) */ + + up_showtasks(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (CURRENT_REGS || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/arm/src/armv7-a/arm_blocktask.c b/arch/arm/src/armv7-a/arm_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..3f02e46b362b80cc8e1e00311b4c57d6acac62bb --- /dev/null +++ b/arch/arm/src/armv7-a/arm_blocktask.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/up_blocktask.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-a/arm_checkmapping.c b/arch/arm/src/armv7-a/arm_checkmapping.c new file mode 100644 index 0000000000000000000000000000000000000000..4f20d22053267a0d7c3205e27a9649d2e761a19e --- /dev/null +++ b/arch/arm/src/armv7-a/arm_checkmapping.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_checkmapping.c + * Check if the current task's fault address has been mapped into the virtual + * address space. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_checkmapping() + * + * Description: + * The function arm_checkmapping() returns an indication if the page fill + * still needs to performed or not. In certain conditions, the page fault + * may occur on several threads and be queued multiple times. This function + * will prevent the same page from be filled multiple times. + * + * Input Parameters: + * tcb - A reference to the task control block of the task that we believe + * needs to have a page fill. Architecture-specific logic can + * retrieve page fault information from the architecture-specific + * context information in this TCB and can consult processor resources + * (page tables or TLBs or ???) to determine if the fill still needs + * to be performed or not. + * + * Returned Value: + * This function will return true if the mapping is in place and false + * if the mapping is still needed. Errors encountered should be + * interpreted as fatal. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +bool arm_checkmapping(FAR struct tcb_s *tcb) +{ + uintptr_t vaddr; + uint32_t *pte; + + /* Since interrupts are disabled, we don't need to anything special. */ + + DEBUGASSERT(tcb); + + /* Get the virtual address that caused the fault */ + + vaddr = tcb->xcp.far; + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Get the PTE associated with this virtual address */ + + pte = arm_va2pte(vaddr); + + /* Return true if this virtual address is mapped. */ + + return (*pte != 0); +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_coherent_dcache.c b/arch/arm/src/armv7-a/arm_coherent_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..363e88f8046af491c3d1e63d9e7bc81b3b7e8cf4 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_coherent_dcache.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/up_coherent_dcache.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "cp15_cacheops.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * addr - virtual start address of region + * len - Size of the address region in bytes + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_coherent_dcache(uintptr_t addr, size_t len) +{ + if (len > 0) + { + /* Perform the operation on the L1 cache */ + + cp15_coherent_dcache(addr, addr + len - 1); + +#ifdef CONFIG_ARCH_L2CACHE + /* If we have an L2 cache, then there more things that need to done */ + +# warning This is insufficient +#endif + } +} diff --git a/arch/arm/src/armv7-a/arm_copyarmstate.c b/arch/arm/src/armv7-a/arm_copyarmstate.c new file mode 100644 index 0000000000000000000000000000000000000000..56848737662e987883b13d028a3667112c47ebc5 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_copyarmstate.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_copyarmstate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" + +#ifdef CONFIG_ARCH_FPU + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyarmstate + * + * Description: + * Copy the ARM portion of the register save area (omitting the floating + * point registers) and save the floating pointer register directly. + * + ****************************************************************************/ + +void up_copyarmstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the Cortex-A model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + /* Save the floating point registers: This will initialize the floating + * registers at indices ARM_CONTEXT_REGS through (XCPTCONTEXT_REGS-1) + */ + + up_savefpu(dest); + + /* Then copy all of the ARM registers (omitting the floating point + * registers). Indices: 0 through (ARM_CONTEXT_REGS-1). + */ + + for (i = 0; i < ARM_CONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + +#endif /* CONFIG_ARCH_FPU */ diff --git a/arch/arm/src/armv7-a/arm_copyfullstate.c b/arch/arm/src/armv7-a/arm_copyfullstate.c new file mode 100644 index 0000000000000000000000000000000000000000..b41b3f2ebb5c935ef6ac0410a012a45c3d2855ec --- /dev/null +++ b/arch/arm/src/armv7-a/arm_copyfullstate.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_copyfullstate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyfullstate + * + * Description: + * Copy the entire register save area (including the floating point + * registers if applicable). This is a little faster than most memcpy's + * since it does 32-bit transfers. + * + ****************************************************************************/ + +void up_copyfullstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the current ARM model, the state is always copied to and from the + * stack and TCB. + */ + + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} diff --git a/arch/arm/src/armv7-a/arm_cpuindex.c b/arch/arm/src/armv7-a/arm_cpuindex.c new file mode 100644 index 0000000000000000000000000000000000000000..662b8fe0ad74d5925d7e448cd6d19eac6da593c3 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_cpuindex.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_cpuindex.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "cp15.h" +#include "sctlr.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_index + * + * Description: + * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + * If TLS is enabled, then the RTOS can get this information from the TLS + * info structure. Otherwise, the MCU-specific logic must provide some + * mechanism to provide the CPU index. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +int up_cpu_index(void) +{ + /* Read the Multiprocessor Affinity Register (MPIDR) */ + + uint32_t mpidr = cp15_rdmpidr(); + + /* And return the CPU ID field */ + + return (mpidr & MPIDR_CPUID_MASK) >> MPIDR_CPUID_SHIFT; +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/armv7-a/arm_cpupause.c b/arch/arm/src/armv7-a/arm_cpupause.c new file mode 100644 index 0000000000000000000000000000000000000000..585d574b06c5f6f97c42bac4a46b28b90e9b3277 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_cpupause.c @@ -0,0 +1,225 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_cpupause.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "up_internal.h" +#include "gic.h" +#include "sched/sched.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; +static spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_pause_handler + * + * Description: + * This is the handler for SGI2. It performs the following operations: + * + * 1. It saves the current task state at the head of the current assigned + * task list. + * 2. It waits on a spinlock, then + * 3. Returns from interrupt, restoring the state of the new task at the + * head of the ready to run list. + * + * Input Parameters: + * Standard interrupt handling + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int arm_pause_handler(int irq, FAR void *context) +{ + FAR struct tcb_s *tcb = this_task(); + int cpu = up_cpu_index(); + + /* Update scheduler parameters */ + + sched_suspend_scheduler(tcb); + + /* Save the current context at CURRENT_REGS into the TCB at the head of the + * assigned task list for this CPU. + */ + + up_savestate(tcb->xcp.regs); + + /* Wait for the spinlock to be released */ + + spin_unlock(&g_cpu_paused[cpu]); + spin_lock(&g_cpu_wait[cpu]); + + /* Restore the exception context of the tcb at the (new) head of the + * assigned task list. + */ + + tcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(tcb); + + /* Then switch contexts. Any necessary address environment changes will + * be made when the interrupt returns. + */ + + up_restorestate(tcb->xcp.regs); + spin_unlock(&g_cpu_wait[cpu]); + return OK; +} + +/**************************************************************************** + * Name: up_cpu_pause + * + * Description: + * Save the state of the current task at the head of the + * g_assignedtasks[cpu] task list and then pause task execution on the + * CPU. + * + * This function is called by the OS when the logic executing on one CPU + * needs to modify the state of the g_assignedtasks[cpu] list for another + * CPU. + * + * Input Parameters: + * cpu - The index of the CPU to be stopped/ + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_pause(int cpu) +{ + int ret; + + DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu()); + + /* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2 + * handler from returning until up_cpu_resume() is called; g_cpu_paused + * is a handshake that will prefent this function from returning until + * the CPU is actually paused. + */ + + DEBUGASSERT(!spin_islocked(&g_cpu_wait[cpu]) && + !spin_islocked(&g_cpu_paused[cpu])); + + spin_lock(&g_cpu_wait[cpu]); + spin_lock(&g_cpu_paused[cpu]); + + /* Execute SGI2 */ + + ret = arm_cpu_sgi(GIC_IRQ_SGI2, (1 << cpu)); + if (ret < 0) + { + /* What happened? Unlock the g_cpu_wait spinlock */ + + spin_unlock(&g_cpu_wait[cpu]); + } + else + { + /* Wait for the other CPU to unlock g_cpu_paused meaning that + * it is fully paused and ready for up_cpu_resume(); + */ + + spin_lock(&g_cpu_paused[cpu]); + } + + spin_unlock(&g_cpu_paused[cpu]); + + /* On successful return g_cpu_wait will be locked, the other CPU will be + * spinninf on g_cpu_wait and will not continue until g_cpu_resume() is + * called. g_cpu_paused will be unlocked in any case. + */ + + return ret; +} + +/**************************************************************************** + * Name: up_cpu_resume + * + * Description: + * Restart the cpu after it was paused via up_cpu_pause(), restoring the + * state of the task at the head of the g_assignedtasks[cpu] list, and + * resume normal tasking. + * + * This function is called after up_cpu_pause in order resume operation of + * the CPU after modifying its g_assignedtasks[cpu] list. + * + * Input Parameters: + * cpu - The index of the CPU being re-started. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_resume(int cpu) +{ + DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu()); + + /* Release the spinlock. Releasing the spinlock will cause the SGI2 + * handler on 'cpu' to continue and return from interrupt to the newly + * established thread. + */ + + DEBUGASSERT(spin_islocked(&g_cpu_wait[cpu]) && + !spin_islocked(&g_cpu_paused[cpu])); + + spin_unlock(&g_cpu_wait[cpu]); + return OK; +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/armv7-a/arm_cpustart.c b/arch/arm/src/armv7-a/arm_cpustart.c new file mode 100644 index 0000000000000000000000000000000000000000..d5d0fe99bc6e5ad8f4eadf1120fbde8ddda432f6 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_cpustart.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_cpustart.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "gic.h" +#include "sched/sched.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_start_handler + * + * Description: + * This is the handler for SGI1. This handler simply returns from the + * interrupt, restoring the state of the new task at the head of the ready + * to run list. + * + * Input Parameters: + * Standard interrupt handling + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int arm_start_handler(int irq, FAR void *context) +{ + FAR struct tcb_s *tcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(tcb); + + /* Then switch contexts. This instantiates the exception context of the + * tcb at the head of the assigned task list. In this case, this should + * be the CPUs NULL task. + */ + + up_restorestate(tcb->xcp.regs); + return OK; +} + +/**************************************************************************** + * Name: up_cpu_start + * + * Description: + * In an SMP configution, only one CPU is initially active (CPU 0). System + * initialization occurs on that single thread. At the completion of the + * initialization of the OS, just before beginning normal multitasking, + * the additional CPUs would be started by calling this function. + * + * Each CPU is provided the entry point to is IDLE task when started. A + * TCB for each CPU's IDLE task has been initialized and placed in the + * CPU's g_assignedtasks[cpu] list. Not stack has been alloced or + * initialized. + * + * The OS initialization logic calls this function repeatedly until each + * CPU has been started, 1 through (CONFIG_SMP_NCPUS-1). + * + * Input Parameters: + * cpu - The index of the CPU being started. This will be a numeric + * value in the range of from one to (CONFIG_SMP_NCPUS-1). (CPU + * 0 is already active) + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_start(int cpu) +{ + DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu()); + + /* Execute SGI1 */ + + return arm_cpu_sgi(GIC_IRQ_SGI1, (1 << cpu)); +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/armv7-a/arm_dataabort.c b/arch/arm/src/armv7-a/arm_dataabort.c new file mode 100644 index 0000000000000000000000000000000000000000..818557c552abc99c82e0acde220c62afeb9ff910 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_dataabort.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_dataabort.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING +# include +# include "arm.h" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_dataabort + * + * Input parameters: + * regs - The standard, ARM register save array. + * + * If CONFIG_PAGING is selected in the NuttX configuration file, then these + * additional input values are expected: + * + * dfar - Fault address register. On a data abort, the ARM MMU places the + * miss virtual address (MVA) into the DFAR register. This is the address + * of the data which, when accessed, caused the fault. + * dfsr - Fault status register. On a data a abort, the ARM MMU places an + * encoded four-bit value, the fault status, along with the four-bit + * encoded domain number, in the data DFSR + * + * Description: + * This is the data abort exception handler. The ARM data abort exception + * occurs when a memory fault is detected during a data transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_PAGING +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) +{ + struct tcb_s *tcb = this_task(); + uint32_t *savestate; + + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* In the NuttX on-demand paging implementation, only the read-only, .text + * section is paged. However, the ARM compiler generated PC-relative data + * fetches from within the .text sections. Also, it is customary to locate + * read-only data (.rodata) within the same section as .text so that it + * does not require copying to RAM. Misses in either of these case should + * cause a data abort. + * + * We are only interested in data aborts due to page translations faults. + * Sections should already be in place and permissions should already be + * be set correctly (to read-only) so any other data abort reason is a + * fatal error. + */ + + pglldbg("DFSR: %08x DFAR: %08x\n", dfsr, dfar); + if ((dfsr & FSR_MASK) != FSR_PAGE) + { + goto segfault; + } + + /* Check the (virtual) address of data that caused the data abort. When + * the exception occurred, this address was provided in the DFAR register. + * (It has not yet been saved in the register context save area). + */ + + pgllvdbg("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND); + if (dfar < PG_PAGED_VBASE || dfar >= PG_PAGED_VEND) + { + goto segfault; + } + + /* Save the offending data address as the fault address in the TCB of + * the currently task. This fault address is also used by the prefetch + * abort handling; this will allow common paging logic for both + * prefetch and data aborts. + */ + + tcb->xcp.dfar = regs[REG_R15]; + + /* Call pg_miss() to schedule the page fill. A consequences of this + * call are: + * + * (1) The currently executing task will be blocked and saved on + * on the g_waitingforfill task list. + * (2) An interrupt-level context switch will occur so that when + * this function returns, it will return to a different task, + * most likely the page fill worker thread. + * (3) The page fill worker task has been signalled and should + * execute immediately when we return from this exception. + */ + + pg_miss(); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + return regs; + +segfault: + lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n", + regs[REG_PC], dfar, dfsr); + PANIC(); + return regs; /* To keep the compiler happy */ +} + +#else /* CONFIG_PAGING */ + +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = regs; + + /* Crash -- possibly showing diagnostic debug information. */ + + lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n", + regs[REG_PC], dfar, dfsr); + PANIC(); + return regs; /* To keep the compiler happy */ +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_doirq.c b/arch/arm/src/armv7-a/arm_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..4980111d582db5861521b084518257a64016b520 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_doirq.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_doirq.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *arm_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Nested interrupts are not supported */ + + DEBUGASSERT(CURRENT_REGS == NULL); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + regs = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = NULL; +#endif + + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/arm/src/armv7-a/arm_elf.c b/arch/arm/src/armv7-a/arm_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..3f076908c4dfa7cde185d55da3ea1a98964430b9 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_elf.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/arm/src/armv-7a/arm_elf.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *ehdr) +{ + /* Make sure it's an ARM executable */ + + if (ehdr->e_machine != EM_ARM) + { + bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine); + return -ENOEXEC; + } + + /* Make sure that 32-bit objects are supported */ + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + { + bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]); + return -ENOEXEC; + } + + /* Verify endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG + if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) +#else + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) +#endif + { + bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]); + return -ENOEXEC; + } + + /* Make sure the entry point address is properly aligned */ + + if ((ehdr->e_entry & 3) != 0) + { + bdbg("Entry point is not properly aligned: %08x\n", ehdr->e_entry); + return -ENOEXEC; + } + + /* TODO: Check ABI here. */ + return OK; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + int32_t offset; + unsigned int relotype; + + /* All relocations except R_ARM_V4BX depend upon having valid symbol + * information. + */ + + relotype = ELF32_R_TYPE(rel->r_info); + if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (relotype) + { + case R_ARM_NONE: + { + /* No relocation */ + } + break; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + { + bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = (*(uint32_t *)addr & 0x00ffffff) << 2; + if (offset & 0x02000000) + { + offset -= 0x04000000; + } + + offset += sym->st_value - addr; + if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000) + { + bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + offset >>= 2; + + *(uint32_t *)addr &= 0xff000000; + *(uint32_t *)addr |= offset & 0x00ffffff; + } + break; + + case R_ARM_ABS32: + case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ + { + bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value; + } + break; + + case R_ARM_V4BX: + { + bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n", + (long)addr, (long)(*(uint32_t *)addr)); + + /* Preserve only Rm and the condition code */ + + *(uint32_t *)addr &= 0xf000000f; + + /* Change instruction to 'mov pc, Rm' */ + + *(uint32_t *)addr |= 0x01a0f000; + } + break; + + case R_ARM_PREL31: + { + bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + offset = *(uint32_t *)addr + sym->st_value - addr; + *(uint32_t *)addr = offset & 0x7fffffff; + } + break; + + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = *(uint32_t *)addr; + offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); + offset = (offset ^ 0x8000) - 0x8000; + + offset += sym->st_value; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + { + offset >>= 16; + } + + *(uint32_t *)addr &= 0xfff0f000; + *(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff); + } + break; + + default: + bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info)); + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("RELA relocation not supported\n"); + return -ENOSYS; +} diff --git a/arch/arm/src/armv7-a/arm_fpuconfig.S b/arch/arm/src/armv7-a/arm_fpuconfig.S new file mode 100644 index 0000000000000000000000000000000000000000..9ae1c66fd4494de3a651c82e2decc969729f906a --- /dev/null +++ b/arch/arm/src/armv7-a/arm_fpuconfig.S @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_fpuconfig.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "cp15.h" + + .file "arm_fpuconfig.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl arm_fpuconfig + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + + .globl arm_fpuconfig + .type arm_fpuconfig, %function + +arm_fpuconfig: + + /* Enable access to CP10 and CP11 in CP15.CACR */ + + mrc CP15_CPACR(r0) + orr r0, r0, #0xf00000 + mcr CP15_CPACR(r0) + + /* Enable access to CP10 and CP11 in CP15.NSACR */ + /* REVISIT: Do we need to do this? */ + + /* Set FPEXC.EN (B30) */ + + fmrx r0, fpexc + orr r0, r0, #0x40000000 + fmxr fpexc, r0 + bx lr + .size arm_fpuconfig, . - arm_fpuconfig + .end diff --git a/arch/arm/src/armv7-a/arm_fullcontextrestore.S b/arch/arm/src/armv7-a/arm_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..88fce91dba654cb137051667240048c810521419 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_fullcontextrestore.S @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_fullcontextrestore.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "up_internal.h" +#include "svcall.h" + + .file "arm_fullcontextrestore.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_fullcontextrestore + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fullcontextrestore + * + * Description: + * Restore the specified task context. Full prototype is: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * Return: + * None + * + ****************************************************************************/ + + .globl up_fullcontextrestore + .type up_fullcontextrestore, function + +up_fullcontextrestore: + + /* On entry, a1 (r0) holds address of the register save area. All other + * registers are available for use. + */ + +#ifdef CONFIG_ARCH_FPU + /* First, restore the floating point registers. Lets do this before we + * restore the ARM registers so that we have plenty of registers to + * work with. + */ + + add r1, r0, #(4*REG_S0) /* r1=Address of FP register storage */ + + /* Load all floating point registers. Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + + vldmia r1!, {s0-s31} /* Restore the full FP context */ + + /* Load the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + vmsr fpscr, r2 /* Restore the FPCSR */ +#endif + +#ifdef CONFIG_BUILD_KERNEL + /* For the kernel build, we need to be able to transition gracefully + * between kernel- and user-mode tasks. Here we do that with a system + * call; the system call will execute in kernel mode and but can return + * to either user or kernel mode. + */ + + /* Perform the System call with R0=SYS_context_restore, R1=restoreregs */ + + mov r1, r0 /* R1: restoreregs */ + mov r0, #SYS_context_restore /* R0: SYS_context_restore syscall */ + svc #0x900001 /* Perform the system call */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + +#else + /* For a flat build, we can do all of this here... Just think of this as + * a longjmp() all on steriods. + */ + + /* Recover all registers except for r0, r1, R15, and CPSR */ + + add r1, r0, #(4*REG_R2) /* Offset to REG_R2 storage */ + ldmia r1, {r2-r14} /* Recover registers */ + + /* Create a stack frame to hold the some registers */ + + sub sp, sp, #(3*4) /* Frame for three registers */ + ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */ + str r1, [sp] /* Save it at the top of the stack */ + ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */ + str r1, [sp, #4] /* Save it in the stack */ + ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */ + str r1, [sp, #8] /* Save it at the bottom of the frame */ + + /* Now we can restore the CPSR. We wait until we are completely + * finished with the context save data to do this. Restore the CPSR + * may re-enable and interrupts and we could be in a context + * where the save structure is only protected by interrupts being + * disabled. + */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ + msr cpsr, r1 /* Set the CPSR */ + + /* Now recover r0 and r1 */ + + ldr r0, [sp] + ldr r1, [sp, #4] + add sp, sp, #(2*4) + + /* Then return to the address at the stop of the stack, + * destroying the stack frame + */ + + ldr pc, [sp], #4 + +#endif + + .size up_fullcontextrestore, . - up_fullcontextrestore diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c new file mode 100644 index 0000000000000000000000000000000000000000..c03ef01c7a56960dd321c3b2a97d817ddb1831d0 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -0,0 +1,501 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_gicv2.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "gic.h" + +#ifdef CONFIG_ARMV7A_HAVE_GICv2 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_gic0_initialize + * + * Description: + * Perform common, one-time GIC initialization on CPU0 only. Both + * arm_gic0_initialize() must be called on CPU0; arm_gic_initialize() must + * be called for all CPUs. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_gic0_initialize(void) +{ + unsigned int nlines = arm_gic_nlines(); + unsigned int irq; + + arm_gic_dump("Entry arm_gic0_initialize", true, 0); + + /* Initialize SPIs. The following should be done only by CPU0. */ + + /* A processor in Secure State sets: + * + * 1. Which interrupts are non-secure (ICDISR). All set to zero (group + * 0). + * 2. Trigger mode of the SPI (ICDICFR). All fields set to 0b01->Level + * sensitive, 1-N model. + * 3. Interrupt Clear-Enable (ICDICER) + * 3. Priority of the SPI using the priority set register (ICDIPR). + * Priority values are 8-bit unsigned binary. A GIC supports a + * minimum of 16 and a maximum of 256 priority levels. Here all + * are set to the middle priority 128 (0x80). + * 4. Target that receives the SPI interrupt (ICDIPTR). Set all to + * CPU0. + */ + + /* Registers with 1-bit per interrupt */ + + for (irq = GIC_IRQ_SPI; irq < nlines; irq += 32) + { + putreg32(0x00000000, GIC_ICDISR(irq)); /* SPIs group 0 */ + putreg32(0xffffffff, GIC_ICDICER(irq)); /* SPIs disabled */ + } + + /* Registers with 2-bits per interrupt */ + + for (irq = GIC_IRQ_SPI; irq < nlines; irq += 16) + { + //putreg32(0xffffffff, GIC_ICDICFR(irq)); /* SPIs edge sensitive */ + putreg32(0x55555555, GIC_ICDICFR(irq)); /* SPIs level sensitive */ + } + + /* Registers with 8-bits per interrupt */ + + for (irq = GIC_IRQ_SPI; irq < nlines; irq += 4) + { + putreg32(0x80808080, GIC_ICDIPR(irq)); /* SPI priority */ + putreg32(0x01010101, GIC_ICDIPTR(irq)); /* SPI on CPU0 */ + } + +#ifdef CONFIG_SMP + /* Attach SGI interrupt handlers */ + + DEBUGVERIFY(irq_attach(GIC_IRQ_SGI1, arm_start_handler)); + DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm_pause_handler)); +#endif + + arm_gic_dump("Exit arm_gic0_initialize", true, 0); +} + +/**************************************************************************** + * Name: arm_gic_initialize + * + * Description: + * Perform common GIC initialization for the current CPU (all CPUs) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_gic_initialize(void) +{ + uint32_t iccicr; + uint32_t icddcr; + + arm_gic_dump("Entry arm_gic_initialize", true, 0); + + /* Initialize PPIs. The following steps need to be done by all CPUs */ + + /* Initialize SGIs and PPIs. NOTE: A processor in non-secure state cannot + * program its interrupt security registers and must get a secure processor + * to program the registers. + */ + + /* Registers with 1-bit per interrupt */ + + putreg32(0x00000000, GIC_ICDISR(0)); /* SGIs and PPIs secure */ + putreg32(0xf8000000, GIC_ICDICER(0)); /* PPIs disabled */ + + /* Registers with 8-bits per interrupt */ + + putreg32(0x80808080, GIC_ICDIPR(0)); /* SGI[3:0] priority */ + putreg32(0x80808080, GIC_ICDIPR(4)); /* SGI[4:7] priority */ + putreg32(0x80808080, GIC_ICDIPR(8)); /* SGI[8:11] priority */ + putreg32(0x80808080, GIC_ICDIPR(12)); /* SGI[12:15] priority */ + putreg32(0x80000000, GIC_ICDIPR(24)); /* PPI[0] priority */ + putreg32(0x80808080, GIC_ICDIPR(28)); /* PPI[1:4] priority */ + + /* Set the binary point register. + * + * Priority values are 8-bit unsigned binary. The binary point is a 3-bit + * field; the value n (n=0-6) specifies that bits (n+1) through bit 7 are + * used in the comparison for interrupt pre-emption. A GIC supports a + * minimum of 16 and a maximum of 256 priority levels so not all binary + * point settings may be meaningul. The special value n=7 (GIC_ICCBPR_NOPREMPT) + * disables pre-emption. We disable all pre-emption here to prevent nesting + * of interrupt handling. + */ + + putreg32(GIC_ICCBPR_NOPREMPT, GIC_ICCBPR); + + /* Program the idle priority in the PMR */ + + putreg32(GIC_ICCPMR_MASK, GIC_ICCPMR); + + /* Configure the CPU Interface Control Register */ + + iccicr = getreg32(GIC_ICCICR); + +#if defined(CONFIG_ARCH_TRUSTZONE_SECURE) || defined(CONFIG_ARCH_TRUSTZONE_BOTH) + /* Clear secure state ICCICR bits to be configured below */ + + iccicr &= ~(GIC_ICCICRS_FIQEN | GIC_ICCICRS_ACKTCTL | GIC_ICCICRS_CBPR | + GIC_ICCICRS_EOIMODES | GIC_ICCICRS_EOIMODENS | + GIC_ICCICRS_ENABLEGRP0 | GIC_ICCICRS_ENABLEGRP1 | + GIC_ICCICRS_FIQBYPDISGRP0 | GIC_ICCICRS_IRQBYPDISGRP0 | + GIC_ICCICRS_FIQBYPDISGRP1 | GIC_ICCICRS_IRQBYPDISGRP1); + +#elif defined(CONFIG_ARCH_TRUSTZONE_NONSECURE) + /* Clear non-secure state ICCICR bits to be configured below */ + + iccicr &= ~(GIC_ICCICRS_EOIMODENS | GIC_ICCICRU_ENABLEGRP1 | + GIC_ICCICRU_FIQBYPDISGRP1 |GIC_ICCICRU_IRQBYPDISGRP1); + +#endif + +#if defined(CONFIG_ARCH_TRUSTZONE_SECURE) || defined(CONFIG_ARCH_TRUSTZONE_BOTH) + /* Set FIQn=1 if secure interrupts are to signal using nfiq_c. + * + * NOTE: Only for processors that operate in secure state. + * REVISIT: Do I need to do this? + */ + + iccicr |= GIC_ICCICRS_FIQEN; +#endif + +#if defined(ONFIG_ARCH_TRUSTZONE_BOTH) + /* Program the AckCtl bit to select the required interrupt acknowledge + * behavior. + * + * NOTE: Only for processors that operate in both secure and non-secure + * state. + * REVISIT: I don't yet fully understand this setting. + */ + + // iccicr |= GIC_ICCICRS_ACKTCTL; + + /* Program the SBPR bit to select the required binary pointer behavior. + * + * NOTE: Only for processors that operate in both secure and non-secure + * state. + * REVISIT: I don't yet fully understand this setting. + */ + + // iccicr |= GIC_ICCICRS_CBPR; +#endif + +#if defined(CONFIG_ARCH_TRUSTZONE_SECURE) || defined(CONFIG_ARCH_TRUSTZONE_BOTH) + /* Set EnableS=1 to enable CPU interface to signal secure interrupts. + * + * NOTE: Only for processors that operate in secure state. + */ + + iccicr |= GIC_ICCICRS_EOIMODES; +#endif + +#if defined(CONFIG_ARCH_TRUSTZONE_NONSECURE) + /* Set EnableNS=1 to enable the CPU to signal non-secure interrupts. + * + * NOTE: Only for processors that operate in non-secure state. + */ + + iccicr |= GIC_ICCICRS_EOIMODENS; + +#elif defined(CONFIG_ARCH_TRUSTZONE_BOTH) + /* Set EnableNS=1 to enable the CPU to signal non-secure interrupts. + * + * NOTE: Only for processors that operate in non-secure state. + */ + + iccicr |= GIC_ICCICRU_EOIMODENS; +#endif + + #ifdef CONFIG_ARCH_TRUSTZONE_BOTH + /* If the processor operates in both security states and SBPR=0, then it + * must switch to the other security state and repeat the programming of + * the binary point register so that the binary point will be programmed + * for interrupts in both security states. + */ + +# warning Missing logic +#endif + +#if !defined(CONFIG_ARCH_HAVE_TRUSTZONE) + /* Enable the distributor by setting the the Enable bit in the enable + * register (no security extensions). + */ + + iccicr |= GIC_ICCICR_ENABLE; + icddcr = GIC_ICDDCR_ENABLE; + +#elif defined(CONFIG_ARCH_TRUSTZONE_SECURE) + /* Enable the Group 0 interrupts, FIQEn and disable Group 0/1 + * bypass. + */ + + iccicr |= (GIC_ICCICRS_ENABLEGRP0 | GIC_ICCICRS_FIQBYPDISGRP0 | + GIC_ICCICRS_IRQBYPDISGRP0 | GIC_ICCICRS_FIQBYPDISGRP1 | + GIC_ICCICRS_IRQBYPDISGRP1); + icddcr = GIC_ICDDCR_ENABLEGRP0; + +#elif defined(CONFIG_ARCH_TRUSTZONE_BOTH) + /* Enable the Group 0/1 interrupts, FIQEn and disable Group 0/1 + * bypass. + */ + + iccicr |= (GIC_ICCICRS_ENABLEGRP0 | GIC_ICCICRS_ENABLEGRP1 | + GIC_ICCICRS_FIQBYPDISGRP0 | GIC_ICCICRS_IRQBYPDISGRP0 | + GIC_ICCICRS_FIQBYPDISGRP1 | GIC_ICCICRS_IRQBYPDISGRP1); + icddcr = (GIC_ICDDCR_ENABLEGRP0 | GIC_ICDDCR_ENABLEGRP1); + +#else /* defined(CONFIG_ARCH_TRUSTZONE_NONSECURE) */ + /* Enable the Group 1 interrupts and disable Group 1 bypass. */ + + iccicr |= (GIC_ICCICRU_ENABLEGRP1 | GIC_ICCICRU_FIQBYPDISGRP1 | + GIC_ICCICRU_IRQBYPDISGRP1); + icddcr = GIC_ICDDCR_ENABLEGRP1; + +#endif + + /* Write the final ICCICR value to enable the GIC. */ + + putreg32(iccicr, GIC_ICCICR); + +#ifdef CONFIG_ARCH_TRUSTZONE_BOTH + /* A processor in the secure state must then switch to the non-secure + * a repeat setting of the enable bit in the enable register. This + * enables distributor to respond to interrupt in both security states. + * REVISIT: Initial implementation operates only in secure state. + */ + +# warning Missing logic +#endif + + /* Write the ICDDCR value to enable the forwarding of interrupt by the + * distributor. + */ + + putreg32(icddcr, GIC_ICDDCR); + arm_gic_dump("Exit arm_gic_initialize", true, 0); +} + +/**************************************************************************** + * Name: arm_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *arm_decodeirq(uint32_t *regs) +{ + uint32_t regval; + int irq; + + /* Read the interrupt acknowledge register and get the interrupt ID */ + + regval = getreg32(GIC_ICCIAR); + irq = (regval & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT; + + gicllvdbg("irq=%d\n", irq); + + /* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending + * interrupt. + */ + + DEBUGASSERT(irq < NR_IRQS || irq == 1023); + if (irq < NR_IRQS) + { + /* Dispatch the interrupt */ + + regs = arm_doirq(irq, regs); + } + + /* Write to the end-of-interrupt register */ + + putreg32(regval, GIC_ICCEOIR); + return regs; +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * On many architectures, there are three levels of interrupt enabling: (1) + * at the global level, (2) at the level of the interrupt controller, + * and (3) at the device level. In order to receive interrupts, they + * must be enabled at all three levels. + * + * This function implements enabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_restore() supports the global level, the device level is hardware + * specific). + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* Ignore invalid interrupt IDs. Also, in the Cortex-A9 MPCore, SGIs are + * always enabled. The corresponding bits in the ICDISERn are read as + * one, write ignored. + */ + + if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + { + uintptr_t regaddr; + + /* Write '1' to the corresponding bit in the distributor Interrupt + * Set-Enable Register (ICDISER) + */ + + regaddr = GIC_ICDISER(irq); + putreg32(GIC_ICDISER_INT(irq), regaddr); + + arm_gic_dump("Exit up_enable_irq", false, irq); + } +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * This function implements disabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* Ignore invalid interrupt IDs. Also, in the Cortex-A9 MPCore, SGIs are + * always enabled. The corresponding bits in the ICDISERn are read as + * one, write ignored. + */ + + if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + { + uintptr_t regaddr; + + /* Write '1' to the corresponding bit in the distributor Interrupt + * Clear-Enable Register (ICDISER) + */ + + regaddr = GIC_ICDICER(irq); + putreg32(GIC_ICDICER_INT(irq), regaddr); + + arm_gic_dump("Exit up_disable_irq", false, irq); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +int up_prioritize_irq(int irq, int priority) +{ + DEBUGASSERT(irq >= 0 && irq < NR_IRQS && priority >= 0 && priority <= 255); + + /* Ignore invalid interrupt IDs */ + + if (irq >= 0 && irq < NR_IRQS) + { + uintptr_t regaddr; + uint32_t regval; + + /* Write the new priority to the corresponding field in the in the + * distributor Interrupt Priority Register (GIC_ICDIPR). + */ + + regaddr = GIC_ICDIPR(irq); + regval = getreg32(regaddr); + regval &= ~GIC_ICDIPR_ID_MASK(irq); + regval |= GIC_ICDIPR_ID(irq, priority); + putreg32(regval, regaddr); + + arm_gic_dump("Exit up_prioritize_irq", false, irq); + return OK; + } + + return -EINVAL; +} + +#endif /* CONFIG_ARMV7A_HAVE_GICv2 */ diff --git a/arch/arm/src/armv7-a/arm_gicv2_dump.c b/arch/arm/src/armv7-a/arm_gicv2_dump.c new file mode 100644 index 0000000000000000000000000000000000000000..9e4dfa340f1f97b25cdf3c55dce81d9f1610012e --- /dev/null +++ b/arch/arm/src/armv7-a/arm_gicv2_dump.c @@ -0,0 +1,309 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_gicv2_dump.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_arch.h" +#include "gic.h" + +#if defined(CONFIG_ARMV7A_HAVE_GICv2) && defined(CONFIG_DEBUG_IRQ) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_gic_dump_cpu + * + * Description: + * Dump CPU interface registers. + * + * Input Parameters: + * all - True: Dump all IRQs; False: Dump only registers for this IRQ + * irq - if all == false, then dump only this IRQ. + * nlines - Number of interrupts to dump if all == true; + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump_cpu(bool all, int irq, int nlines) +{ + lowsyslog(LOG_INFO, " CPU Interface Registers:\n"); + lowsyslog(LOG_INFO, " ICR: %08x PMR: %08x BPR: %08x IAR: %08x\n", + getreg32(GIC_ICCICR), getreg32(GIC_ICCPMR), + getreg32(GIC_ICCBPR), getreg32(GIC_ICCIAR)); + lowsyslog(LOG_INFO, " RPR: %08x HPIR: %08x ABPR: %08x\n", + getreg32(GIC_ICCRPR), getreg32(GIC_ICCHPIR), + getreg32(GIC_ICCABPR)); + lowsyslog(LOG_INFO, " AIAR: %08x AHPIR: %08x IDR: %08x\n", + getreg32(GIC_ICCAIAR), getreg32(GIC_ICCAHPIR), + getreg32(GIC_ICCIDR)); + lowsyslog(LOG_INFO, " APR1: %08x APR2: %08x APR3: %08x APR4: %08x\n", + getreg32(GIC_ICCAPR1), getreg32(GIC_ICCAPR2), + getreg32(GIC_ICCAPR3), getreg32(GIC_ICCAPR4)); + lowsyslog(LOG_INFO, " NSAPR1: %08x NSAPR2: %08x NSAPR3: %08x NSAPR4: %08x\n", + getreg32(GIC_ICCNSAPR1), getreg32(GIC_ICCNSAPR2), + getreg32(GIC_ICCNSAPR3), getreg32(GIC_ICCNSAPR4)); +} + +/**************************************************************************** + * Name: arm_gic_dumpregs + * + * Description: + * Dump registers with 4x8-bit per interrupt + * + * Input Parameters: + * regaddr - First register address + * nlines - Number of interrupt lines + * incr - IRQs per 32-bit word + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void arm_gic_dumpregs(uintptr_t regaddr, int nlines, int incr) +{ + unsigned int i; + + incr <<= 2; + for (i = 0; i < nlines; i += incr, regaddr += 16) + { + lowsyslog(LOG_INFO, " %08x %08x %08x %08x\n", + getreg32(regaddr), getreg32(regaddr + 4), + getreg32(regaddr + 8), getreg32(regaddr + 12)); + } +} + +/**************************************************************************** + * Name: arm_gic_dump4 + * + * Description: + * Dump registers with 4x8-bit per interrupt + * + * Input Parameters: + * name - Register name + * regaddr - First register address + * nlines - Number of interrupt lines + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump4(const char *name, uintptr_t regaddr, + int nlines) +{ + lowsyslog(LOG_INFO, " %s[%08lx]\n", name, (unsigned long)regaddr); + arm_gic_dumpregs(regaddr, nlines, 4); +} + +/**************************************************************************** + * Name: arm_gic_dump8 + * + * Description: + * Dump registers with 8x4-bit per interrupt + * + * Input Parameters: + * name - Register name + * regaddr - First register address + * nlines - Number of interrupt lines + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump8(const char *name, uintptr_t regaddr, + int nlines) +{ + lowsyslog(LOG_INFO, " %s[%08lx]\n", name, (unsigned long)regaddr); + arm_gic_dumpregs(regaddr, nlines, 8); +} + +/**************************************************************************** + * Name: arm_gic_dump16 + * + * Description: + * Dump registers with 16 x 2-bit per interrupt + * + * Input Parameters: + * name - Register name + * regaddr - First register address + * nlines - Number of interrupt lines + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump16(const char *name, uintptr_t regaddr, + int nlines) +{ + lowsyslog(LOG_INFO, " %s[%08lx]\n", name, (unsigned long)regaddr); + arm_gic_dumpregs(regaddr, nlines, 16); +} + +/**************************************************************************** + * Name: arm_gic_dump32 + * + * Description: + * Dump registers with 32 x 1-bit per interrupt + * + * Input Parameters: + * name - Register name + * regaddr - First register address + * nlines - Number of interrupt lines + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump32(const char *name, uintptr_t regaddr, + int nlines) +{ + lowsyslog(LOG_INFO, " %s[%08lx]\n", name, (unsigned long)regaddr); + arm_gic_dumpregs(regaddr, nlines, 32); +} + +/**************************************************************************** + * Name: arm_gic_dump_distributor + * + * Description: + * Dump distributor interface registers. + * + * Input Parameters: + * all - True: Dump all IRQs; False: Dump only registers for this IRQ + * irq - if all == false, then dump only this IRQ. + * nlines - Number of interrupts to dump if all == true; + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void arm_gic_dump_distributor(bool all, int irq, int nlines) +{ + lowsyslog(LOG_INFO, " Distributor Registers:\n"); + lowsyslog(LOG_INFO, " DCR: %08x ICTR: %08x IIDR: %08x\n", + getreg32(GIC_ICDDCR), getreg32(GIC_ICDICTR), + getreg32(GIC_ICDIIDR)); + + if (all) + { + arm_gic_dump32("ISR", GIC_ICDISR(0), nlines); + arm_gic_dump32("ISER/ICER", GIC_ICDISER(0), nlines); + arm_gic_dump32("ISPR/ICPR", GIC_ICDISPR(0), nlines); + arm_gic_dump32("SAR/CAR", GIC_ICDSAR(0), nlines); + arm_gic_dump4("IPR", GIC_ICDIPR(0), nlines); + arm_gic_dump4("IPTR", GIC_ICDIPTR(0), nlines); + arm_gic_dump16("ICFR", GIC_ICDICFR(0), nlines); + arm_gic_dump32("PPSIR/SPISR", GIC_ICDPPISR, nlines); + arm_gic_dump32("NSACR", GIC_ICDNSACR(0), nlines); + arm_gic_dump8("SCPR/SSPR", GIC_ICDSCPR(0), nlines); + } + else + { + lowsyslog(LOG_INFO, " ISR: %08x ISER: %08x ISPR: %08x SAR: %08x\n", + getreg32(GIC_ICDISR(irq)), getreg32(GIC_ICDISER(irq)), + getreg32(GIC_ICDISPR(irq)), getreg32(GIC_ICDSAR(irq))); + lowsyslog(LOG_INFO, " IPR: %08x IPTR: %08x ICFR: %08x SPISR: %08x\n", + getreg32(GIC_ICDIPR(irq)), getreg32(GIC_ICDIPTR(irq)), + getreg32(GIC_ICDICFR(irq)), getreg32(GIC_ICDSPISR(irq))); + lowsyslog(LOG_INFO, " NSACR: %08x SCPR: %08x\n", + getreg32(GIC_ICDNSACR(irq)), getreg32(GIC_ICDSCPR(irq))); + } + + lowsyslog(LOG_INFO, " PIDR[%08lx]:\n", (unsigned long)GIC_ICDPIDR(0)); + lowsyslog(LOG_INFO, " %08x %08x %08x %08x\n", + getreg32(GIC_ICDPIDR(0)), getreg32(GIC_ICDPIDR(1)), + getreg32(GIC_ICDPIDR(2)), getreg32(GIC_ICDPIDR(3))); + lowsyslog(LOG_INFO, " %08x %08x %08x %08x\n", + getreg32(GIC_ICDPIDR(4)), getreg32(GIC_ICDPIDR(5)), + getreg32(GIC_ICDPIDR(6))); + lowsyslog(LOG_INFO, " CIDR[%08lx]:\n", (unsigned long)GIC_ICDCIDR(0)); + lowsyslog(LOG_INFO, " %08x %08x %08x %08x\n", + getreg32(GIC_ICDCIDR(0)), getreg32(GIC_ICDCIDR(1)), + getreg32(GIC_ICDCIDR(2)), getreg32(GIC_ICDCIDR(3))); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_gic_dump + * + * Description: + * Dump GIC registers to the SYSLOG device + * + * Input Parameters: + * msg - Message to print with the register data + * all - True: Dump all IRQs; False: Dump only registers for this IRQ + * irq - if all == false, then dump only this IRQ. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void arm_gic_dump(const char *msg, bool all, int irq) +{ + unsigned int nlines = arm_gic_nlines(); + + if (all) + { + lowsyslog(LOG_INFO, "GIC: %s NLINES=%u\n", msg, nlines); + } + else + { + lowsyslog(LOG_INFO, "GIC: %s IRQ=%d\n", msg, irq); + } + + arm_gic_dump_cpu(all, irq, nlines); + arm_gic_dump_distributor(all, irq, nlines); +} + +#endif /* CONFIG_ARMV7A_HAVE_GICv2 && CONFIG_DEBUG_IRQ */ diff --git a/arch/arm/src/armv7-a/arm_head.S b/arch/arm/src/armv7-a/arm_head.S new file mode 100644 index 0000000000000000000000000000000000000000..5af4f17ddf720b1e7e0b2afc9230b267cbe5db8a --- /dev/null +++ b/arch/arm/src/armv7-a/arm_head.S @@ -0,0 +1,798 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_head.S + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm.h" +#include "cp15.h" +#include "sctlr.h" +#include "mmu.h" +#include "chip.h" +#include "up_internal.h" + + .file "arm_head.S" + +/********************************************************************************** + * Configuration + **********************************************************************************/ + +/* Hard-coded options */ + +#undef CPU_ALIGNMENT_TRAP +#undef CPU_CACHE_ROUND_ROBIN +#undef CPU_DCACHE_DISABLE +#undef CPU_ICACHE_DISABLE +#undef CPU_AFE_ENABLE + +/* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Initialize the .data section in RAM, and + * - Clear .bss section + */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 2. We boot in FLASH but copy ourselves to DRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Copy ourself to DRAM (after mapping it), and + * - Clear .bss section + * + * In this case, we assume that the logic within this file executes from FLASH. + */ + +#elif defined(CONFIG_BOOT_COPYTORAM) +# error "configuration not implemented + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning) + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM + * was initialized by the boot loader, and this boot logic must: + * + * - Clear .bss section + */ + +#else + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of RAM is the same as the physical + * beginning of RAM. + */ + +# if !defined(CONFIG_RAM_START) || !defined(CONFIG_RAM_VSTART) +# error "CONFIG_RAM_START or CONFIG_RAM_VSTART is not defined" +# endif + +# if CONFIG_RAM_START == CONFIG_RAM_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RX_NSECTIONS determines the number of 1Mb sections to map for the + * Read/eXecute address region. This is based on NUTTX_TEXT_SIZE. + */ + +#define WR_NSECTIONS ((NUTTX_RAM_SIZE+0x000fffff) >> 20) + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/* The ARMv7-A L1 page table can be placed at the beginning or at the end of + * the RAM space. This decision is based on the placement of the vector + * area: If the vectors are place in low memory at address 0x0000 0000, then + * the page table is placed in high memory; if the vectors are placed in + * high memory at address 0xfff0 0000, then the page table is locating at + * the beginning of RAM. + * + * For the special case where (1) the program executes out of RAM, and (2) + * the page is located at the beginning of RAM (i.e., the high vector case), + * then the following macro can easily find the physical address of the + * section that includes the first part of the text region: Since the page + * table is closely related to the NuttX base address in this case, we can + * convert the page table base address to the base address of the section + * containing both. + */ + +/* This macro will modify r0, r1, r2 and r14 */ + +#ifdef CONFIG_DEBUG + .macro showprogress, code + mov r0, #\code + bl up_lowputc + .endm +#else + .macro showprogress, code + .endm +#endif + +/**************************************************************************** + * Name: __start + ****************************************************************************/ + + .text + .global __start + .type __start, #function + +__start: + /* Make sure that we are in SVC mode with IRQs and FIQs disabled */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, r0 + + /* The MMU and caches should be disabled */ + + mrc CP15_SCTLR(r0) + bic r0, r0, #(SCTLR_M | SCTLR_C) + bic r0, r0, #(SCTLR_I) + mcr CP15_SCTLR(r0) + + /* Clear the 16K level 1 page table */ + + ldr r5, .LCppgtable /* r5=phys. page table */ +#ifndef CONFIG_ARCH_ROMPGTABLE + mov r0, r5 + mov r1, #0 + add r2, r0, #PGTABLE_SIZE +.Lpgtableclear: + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + teq r0, r2 + bne .Lpgtableclear + +#ifdef ARMV7A_PGTABLE_MAPPING + /* If the page table does not lie in the same address space as does the + * mapped RAM in either case. So we will need to create a special + * mapping for the page table. + * + * Load information needed to map the page table. After the ldmia, we + * will have + * + * R1 = The aligned, physical base address of the page table + * R2 = The aligned, virtual base address of the page table + * R3 = The MMU flags to use with the .text space mapping + * R5 = The physical address of the L1 page table (from above) + * + * The value in R1 could have been obtained by simply masking R5. + */ + + adr r0, .LCptinfo /* Address of page table description */ + ldmia r0, {r1, r2, r3} /* Load the page table description */ + + /* A single page is sufficient to map the page table */ + + orr r0, r1, r3 /* OR MMU flags into physical address */ + str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */ +#endif + + /* Load information needed to map the .text region. After the ldmia, we + * will have: + * + * R1 = Aligned, physical address of the start of the .text region + * R2 = Aligned, virtual address of the start of the .text region + * R3 = MMU flags associated with the .txt region + * R4 = The number of 1MB sections in the mapping + * R5 = The physical address of the L1 page table (from above) + */ + + adr r0, .LCtextinfo /* Address of text info */ + ldmia r0, {r1, r2, r3, r4} /* Load the text description */ + +#ifndef CONFIG_IDENTITY_TEXTMAP + /* Create identity mapping for first MB of the .text section to support + * this start-up logic executing out of the physical address space. This + * identity mapping will be removed by .Lvstart (see below). Of course, + * we would only do this if the physical-virtual mapping is not already + * the identity mapping. + */ + + orr r0, r1, r3 /* OR MMU flags into physical address */ + str r0, [r5, r1, lsr #18] /* Identity mapping */ +#endif + + /* Map the entire .text region. We do this before enabling caches so + * we know that the data will be in place in the data cache. We map the + * entire text region because we don't know which parts are needed for + * start-up. + * + * The page table base address is in R5. Each 32-bit page table entry + * maps 1 MB of address space and is indexed by the lower 20 bits of + * the virtual address in R2 + */ + + add r2, r5, r2, lsr #18 /* R2=Offset page table address */ + + /* Now loop until each page table entry has been written for the .text + * region. + */ + +.Lpgtextloop: + orr r0, r1, r3 /* R0: OR MMU flags into physical address */ + subs r4, r4, #1 /* R4: Decrement the section count */ + str r0, [r2], #4 /* Save page table entry, increment page table address */ + add r1, r1, #(1024*1024) /* R1: Increment the physical address */ + bne .Lpgtextloop /* Loop while R4 is non-zero */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) && !defined(CONFIG_BOOT_SDRAM_DATA) + /* If we are executing from FLASH, then we will need additional mappings for + * the primary RAM region that holds the .data, .bss, stack, and heap memory. + * + * Here we expect to have: + * r5 = Address of the base of the L1 table + * + * Load information needed to map the .text region. After the ldmia, we + * will have: + * + * R1 = Aligned, physical address of the start of the .text region + * R2 = Aligned, virtual address of the start of the .text region + * R3 = MMU flags associated with the .txt region + * R4 = The number of 1MB sections in the mapping + * R5 = The physical address of the L1 page table (from above) + */ + + adr r0, .LCraminfo /* Address of primary RAM info */ + ldmia r0, {r1, r2, r3, r4} /* Load the primary RAM description */ + add r2, r5, r2, lsr #18 /* R2=Offset page table addres */ + + /* Loop until each page table entry has been written for the primary RAM + * region. + */ + +.Lpgramloop: + orr r0, r1, r3 /* R0: OR MMU flags into physical address */ + subs r4, r4, #1 /* R4: Decrement the section count */ + str r0, [r2], #4 /* Save page table entry, increment page table address */ + add r1, r1, #(1024*1024) /* R1: Increment the physical address */ + bne .Lpgramloop /* Loop while R4 is non-zero */ + +#endif /* CONFIG_BOOT_RUNFROMFLASH && !CONFIG_BOOT_SDRAM_DATA */ +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* The following logic will set up the ARMv7-A for normal operation. + * + * Here we expect to have: + * r5 = Address of the base of the L1 table + */ + + /* Invalidate caches and TLBs. + * + * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not + * support a CP15 operation to invalidate the entire data cache. ... + * In normal usage the only time the entire data cache has to be + * invalidated is on reset." + * + * The instruction cache is virtually indexed and physically tagged but + * the data cache is physically indexed and physically tagged. So it + * should not be an issue if the system comes up with a dirty Dcache; + * the ICache, however, must be invalidated. + */ + + mov r0, #0 + mcr CP15_TLBIALL(r0,c7) /* Invalidate the entire unified TLB */ + mcr CP15_TLBIALL(r0,c6) + mcr CP15_TLBIALL(r0,c5) + mcr CP15_BPIALL(r0) /* Invalidate entire branch prediction array */ + mcr CP15_ICIALLU(r0) /* Invalidate I-cache */ + + /* Load the page table address. + * + * NOTES: + * - Here we assume that the page table address is aligned to at least + * least a 16KB boundary (bits 0-13 are zero). No masking is provided + * to protect against an unaligned page table address. + * - The ARMv7-A has two page table address registers, TTBR0 and 1. + * Only TTBR0 is used in this implementation but both are initialized. + * + * Here we expect to have: + * r0 = Zero + * r5 = Address of the base of the L1 table + */ + + orr r1, r5, #(TTBR0_RGN_WBWA | TTBR0_IRGN0) /* Select cache properties */ + mcr CP15_TTBR0(r1) + mcr CP15_TTBR1(r1) + + /* Set the TTB control register (TTBCR) to indicate that we are using + * TTBR0. r0 still holds the value of zero. + * + * N : 0=Selects TTBR0 and 16KB page table size indexed by VA[31:20] + * PD0 : 0=Perform translation table walks using TTBR0 + * PD1 : 0=Perform translation table walks using TTBR1 (but it is disabled) + * EAE : 0=Use 32-bit translation system + */ + + mcr CP15_TTBCR(r0) + + /* Enable the MMU and caches + * lr = Resume at .Lvstart with the MMU enabled + */ + + ldr lr, .LCvstart /* Abs. virtual address */ + + /* Configure the domain access register (see mmu.h). Only domain 0 is + * supported and it uses the permissions in the TLB. + */ + + mov r0, #DACR_CLIENT(0) + mcr CP15_DACR(r0) /* Set domain access register */ + + /* Configure the system control register (see sctrl.h) */ + + mrc CP15_SCTLR(r0) /* Get control register */ + + /* Clear bits to reset values. This is only necessary in situations like, for + * example, we get here via a bootloader and the control register is in some + * unknown state. + * + * SCTLR_M Bit 0: Enable the MMU + * SCTLR_A Bit 1: Strict alignment disabled (reset value) + * SCTLR_C Bit 2: DCache disabled (reset value) + * + * SCTLR_SW Bit 10: SWP/SWPB not enabled (reset value) + * SCTLR_I Bit 12: ICache disabled (reset value) + * SCTLR_V Bit 13: Assume low vectors (reset value) + * SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random + * replacement strategy. + * SCTLR_HA Bit 17: Not supported by A5 + * + * SCTLR_EE Bit 25: 0=Little endian (reset value). + * SCTLR_TRE Bit 28: No memory region remapping (reset value) + * SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value). + * SCTLR_TE Bit 30: All exceptions handled in ARM state (reset value). + */ + + bic r0, r0, #(SCTLR_A | SCTLR_C) + bic r0, r0, #(SCTLR_SW | SCTLR_I | SCTLR_V | SCTLR_RR | SCTLR_HA) + bic r0, r0, #(SCTLR_EE | SCTLR_TRE | SCTLR_AFE | SCTLR_TE) + + /* Set bits to enable the MMU + * + * SCTLR_M Bit 0: Enable the MMU + * SCTLR_Z Bit 11: Program flow prediction control always enabled on A5 + */ + + orr r0, r0, #(SCTLR_M) +#ifndef CONFIG_ARCH_CORTEXA5 + orr r0, r0, #(SCTLR_Z) +#endif + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Position vectors to 0xffff0000 if so configured. + * + * SCTLR_V Bit 13: High vectors + */ + + orr r0, r0, #(SCTLR_V) +#endif + +#if defined(CPU_CACHE_ROUND_ROBIN) && !defined(CONFIG_ARCH_CORTEXA5) + /* Round Robin cache replacement + * + * SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random + * replacement strategy. + */ + + orr r0, r0, #(SCTLR_RR) +#endif + +#ifndef CPU_DCACHE_DISABLE + /* Dcache enable + * + * SCTLR_C Bit 2: DCache enable + */ + + orr r0, r0, #(SCTLR_C) +#endif + +#ifndef CPU_ICACHE_DISABLE + /* Icache enable + * + * SCTLR_I Bit 12: ICache enable + */ + + orr r0, r0, #(SCTLR_I) +#endif + +#ifdef CPU_ALIGNMENT_TRAP + /* Alignment abort enable + * + * SCTLR_A Bit 1: Strict alignment enabled + */ + + orr r0, r0, #(SCTLR_A) +#endif + +#ifdef CONFIG_ENDIAN_BIG + /* Big endian mode + * + * SCTLR_EE Bit 25: 1=Big endian. + */ + + orr r0, r0, #(SCTLR_EE) +#endif + +#ifdef CPU_AFE_ENABLE + /* AP[0:2] Permissions model + * + * SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value). + * + * When AFE=1, the page table AP[0] is used as an access flag and AP[2:1] + * control. When AFE=0, AP[2:0] control access permissions. + */ + + orr r0, r0, #(SCTLR_AFE) +#endif + + /* Then write the configured control register */ + + mcr CP15_SCTLR(r0) /* Write control reg */ + .rept 12 /* Cortex A8 wants lots of NOPs here */ + nop + .endr + + /* And "jump" to .Lvstart in the newly mapped virtual address space */ + + mov pc, lr + +/**************************************************************************** + * PC_Relative Data + ****************************************************************************/ + + /* The physical base address of the page table */ + + .type .LCppgtable, %object +.LCppgtable: + .long PGTABLE_BASE_PADDR /* Physical start of page table */ + .size .LCppgtable, . -.LCppgtable + +#ifdef ARMV7A_PGTABLE_MAPPING + /* Page table region description. The order of these fields must not + * change because the values are loaded using ldmia: + * + * 1) The aligned, physical base address of the page table + * 2) The aligned, virtual base address of the page table + * 3) The MMU flags to use with the .text space mapping + */ + + .type .LCptinfo, %object +.LCptinfo: + .long (PGTABLE_BASE_PADDR & 0xfff00000) /* Physical base address */ + .long (PGTABLE_BASE_VADDR & 0xfff00000) /* Virtual base address */ + .long MMU_MEMFLAGS /* MMU flags for text section in RAM */ + .size .LCptinfo, . -.LCptinfo +#endif + +#ifndef CONFIG_ARCH_ROMPGTABLE + /* Text region description. The order of these fields must not change + * because the values are loaded using ldmia: + * + * 1) The aligned, physical base address of the .text section + * 2) The aligned, virtual base address of the .text section + * 3) The MMU flags to use with the .text space mapping + * 4) The number of 1MB sections in the .text region + * + * Values provided for NUTTX_TEXT_* must all be properly aligned to 1MB + * address boundaries + */ + + .type .LCtextinfo, %object +.LCtextinfo: +.LCptextbase: + .long NUTTX_TEXT_PADDR /* Physical base address */ + .long NUTTX_TEXT_VADDR /* Virtual base address */ +.LCtextflags: +#ifdef CONFIG_BOOT_RUNFROMFLASH + .long MMU_ROMFLAGS /* MMU flags text section in FLASH/ROM */ +#else + .long MMU_MEMFLAGS /* MMU flags for text section in RAM */ +#endif + .long (NUTTX_TEXT_SIZE >> 20) /* Number of 1MB read-execute sections */ + .size .LCtextinfo, . -.LCtextinfo + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Primary RAM region description. The order of these fields must not change + * because the values are loaded using ldmia: + * + * 1) The aligned, physical base address of the primary RAM section + * 2) The aligned, virtual base address of the primary RAM section + * 3) The MMU flags to use with the primary RAM space mapping + * 4) The number of 1MB sections in the primary RAM region + * + * Values provided for NUTTX_RAM_* must all be properly aligned to 1MB + * address boundaries + */ + + .type .LCraminfo, %object +.LCraminfo: + .long NUTTX_RAM_PADDR /* Physical base address */ + .long NUTTX_RAM_VADDR /* Virtual base address */ + .long MMU_MEMFLAGS /* MMU flags for primary RAM section */ + .long (NUTTX_RAM_SIZE >> 20) /* Number of 1MB read-execute sections */ + .size .LCraminfo, . -.LCraminfo + +#endif /* CONFIG_BOOT_RUNFROMFLASH */ +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* The virtual start address of the second phase boot logic */ + + .type .LCvstart, %object +.LCvstart: + .long .Lvstart + .size .LCvstart, . -.LCvstart + + .size __start, .-__start + +/**************************************************************************** + * Name: .Lvstart + ***************************************************************************/ + +/* The following is executed after the MMU has been enabled. This uses + * absolute addresses; this is not position independent. + */ + .align 5 + .local .Lvstart + .type .Lvstart, %function + +.Lvstart: + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_IDENTITY_TEXTMAP) + /* Remove the temporary mapping (if one was made). The following assumes + * that the total RAM size is > 1Mb and extends that initial mapping to + * cover additional RAM sections. + */ + + ldr r5, .LCvpgtable /* r5=Virtual page table base address */ + ldr r3, .LCptextbase /* r0=Physical base address of .text section */ + mov r0, #0 /* flags + base = 0 */ + str r3, [r5, r3, lsr #18] /* identity mapping */ +#endif /* !CONFIG_ARCH_ROMPGTABLE && !CONFIG_IDENTITY_TEXTMAP */ + + /* Set up the stack pointer and clear the frame pointer */ + + ldr sp, .Lstackpointer + mov fp, #0 + +#ifndef CONFIG_BOOT_SDRAM_DATA + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. + */ + + bl arm_data_initialize +#endif + + /* Perform early C-level, platform-specific initialization. Logic + * within up_boot() must configure SDRAM and call arm_ram_initailize. + */ + + bl up_boot + +#ifdef CONFIG_STACK_COLORATION + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +1: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 1b /* Bottom of the loop */ +#endif + + /* Finally branch to the OS entry point */ + + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ + .size .Lvstart, .-.Lvstart + +/*************************************************************************** + * Name: arm_data_initialize + ***************************************************************************/ + + .global arm_data_initialize + .type arm_data_initialize, #function + +arm_data_initialize: + + /* Zero BSS */ + + adr r0, .Linitparms + ldmia r0, {r0, r1} + + mov r2, #0 +1: + cmp r0, r1 /* Clear up to _bss_end_ */ + strcc r2, [r0], #4 + bcc 1b + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* If the .data section is in a separate, uninitialized address space, + * then we will also need to copy the initial values of of the .data + * section from the .text region into that .data region. This would + * be the case if we are executing from FLASH and the .data section + * lies in a different physical address region OR if we are support + * on-demand paging and the .data section lies in a different virtual + * address region. + */ + + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +2: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt 2b +#endif + + /* And return to the caller */ + + bx lr + .size arm_data_initialize, . - arm_data_initialize + +/*************************************************************************** + * Text-section constants + ***************************************************************************/ + + /* Text-section constants: + * + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS region (see ld.script) + * + * The idle task stack usually starts at the end of BSS and is of size + * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the + * end of memory. See g_idle_topstack below. + * + * In the case where CONFIG_BOOT_SDRAM_DATA is defined, the IDLE stack is + * in ISRAM, but the heap is in SDRAM beginning at _ebss and extending + * to the end of SDRAM. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + /* The virtual base address of the page table */ + + .type .LCvpgtable, %object +.LCvpgtable: + .long PGTABLE_BASE_VADDR /* Virtual start of page table */ + .size .LCvpgtable, . -.LCvpgtable + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + .type .Linitparms, %object +.Linitparms: + .long _sbss + .long _ebss + .size .Linitparms, . -.Linitparms + +.Lstackpointer: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE-4 +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +#endif + .size .Lstackpointer, . -.Lstackpointer + +#ifdef CONFIG_BOOT_RUNFROMFLASH + .type .Ldatainit, %object +.Ldatainit: + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata + .size .Ldatainit, . -.Ldatainit +#endif + +#ifdef CONFIG_STACK_COLORATION + .type .Lstkinit, %object +.Lstkinit: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */ +#else + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ +#endif + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif + +/*************************************************************************** + * Data section variables + ***************************************************************************/ + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to .Linitparms + * above. + */ + + .section .rodata, "a" + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object + +g_idle_topstack: + +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE +#endif + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/arm/src/armv7-a/arm_initialstate.c b/arch/arm/src/armv7-a/arm_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..c43e12d67eba2c98ccf59afd0da051ee6c2434c9 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_initialstate.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_initialstate.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of + * the new TCB. + * + * This function must setup the initial architecture registers and/or + * stack so that execution will begin at tcb->start on the next context + * switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + uint32_t cpsr; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC + if (tcb->dspace != NULL) + { + /* Set the PIC base register (probably R10) to the address of the + * alloacated D-Space region. + */ + + xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; + } +#endif + + /* Set supervisor-mode and disable FIQs, regardless of how NuttX is + * configured and of what kind of thread is being started. That is + * because all threads, even user-mode threads will start in kernel + * trampoline at task_start() or pthread_start(). The thread's + * privileges will be dropped before transitioning to user code. + */ + + cpsr = PSR_MODE_SVC; + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + /* Disable interrupts (both IRQs and FIQs) */ + + cpsr |= (PSR_I_BIT | PSR_F_BIT); + +#else /* CONFIG_SUPPRESS_INTERRUPTS */ + /* Leave IRQs enabled (Also FIQs if CONFIG_ARMV7A_DECODEFIQ is selected) */ + +#ifndef CONFIG_ARMV7A_DECODEFIQ + + cpsr |= PSR_F_BIT; + +#endif /* !CONFIG_ARMV7A_DECODEFIQ */ +#endif /* CONFIG_SUPPRESS_INTERRUPTS */ + + xcp->regs[REG_CPSR] = cpsr; +} diff --git a/arch/arm/src/armv7-a/arm_l2cc_pl310.c b/arch/arm/src/armv7-a/arm_l2cc_pl310.c new file mode 100644 index 0000000000000000000000000000000000000000..64aeaf3b8bc61cbec7dc990fee8011650c961de3 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_l2cc_pl310.c @@ -0,0 +1,874 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/chip/arm-l2cc_pl310.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2, + * Technical Reference Manual, ARM DDI 0246F (ID011711), ARM + * + * NOTE: This logic is incompatible with older versions of the PL310! + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "l2cc.h" +#include "l2cc_pl310.h" + +#ifdef CONFIG_ARMV7A_L2CC_PL310 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***********************************************************/ +/* Number of ways depends on ARM configuration */ + +#if defined(CONFIG_ARMV7A_ASSOCIATIVITY_8WAY) +# define PL310_NWAYS 8 +# define PL310_WAY_MASK 0x000000ff +#elif defined(CONFIG_ARMV7A_ASSOCIATIVITY_8WAY) +# define PL310_NWAYS 16 +# define PL310_WAY_MASK 0x0000ffff +#else +# error "Number of ways not selected" +#endif + +/* The size of one depends on ARM configuration */ + +#if defined(CONFIG_ARMV7A_WAYSIZE_16KB) +# define PL310_WAYSIZE (16 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_32KB) +# define PL310_WAYSIZE (32 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_64KB) +# define PL310_WAYSIZE (64 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_128KB) +# define PL310_WAYSIZE (128 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_256KB) +# define PL310_WAYSIZE (256 * 1024) +#elif defined(CONFIG_ARMV7A_WAYSIZE_512KB) +# define PL310_WAYSIZE (512 * 1024) +#else +# error "Way size not selected" +#endif + +/* The size of the cache is then the product of the number of ways times + * the size of each way. + */ + +#define PL310_CACHE_SIZE (PL310_NWAYS * PL310_WAYSIZE) + +/* Use for aligning addresses to a cache line boundary */ + +#define PL310_CACHE_LINE_MASK (PL310_CACHE_LINE_SIZE - 1) + +/* Configurable options + * + * REVISIT: Currently there are not configuration options. All values + * are just set to the default. + */ + +/* Bit 0: Full line zero enable + * + * Default: 0=Full line of write zero behavior disabled + */ + +#define L2CC_ACR_FLZE_CONFIG (0) /* 0=Full line of write zero behavior disabled */ + +/* Bit 10: High Priority for SO and Dev Reads Enable + * + * Default: 0=Strongly Ordered and Device reads have lower priority than + * cacheable accesses + */ + +#define L2CC_ACR_HPSO_CONFIG (0) /* 0=Have lower priority than cache */ + +/* Bit 11: Store Buffer Device Limitation Enable + * + * Default: 0=Store buffer device limitation disabled + */ + +#define L2CC_ACR_SBDLE_CONFIG (0) /* 0=Store buffer device limitation disabled */ + +/* Bit 12: Exclusive Cache Configuration + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EXCC_CONFIG (0) /* 0=Disabled */ + +/* Bit 13: Shared Attribute Invalidate Enable + * + * Default: 0=Shared invalidate behavior disabled + */ + +#define L2CC_ACR_SAIE_CONFIG (0) /* 0=Shared invalidate behavior disabled */ + +/* Bit 20: Event Monitor Bus Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EMBEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 21: Parity Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_PEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 22: Shared Attribute Override Enable + * + * Default: 0=Treats shared accesses as specified in the TRM + */ + +#define L2CC_ACR_SAOEN_CONFIG (0) /* 0=As specified in the TRM */ + +/* Bits 23-24: Force Write Allocate + * + * Default: 0=Use AWCACHE attributes for WA + */ + +#define L2CC_ACR_FWA_CONFIG L2CC_ACR_FWA_AWCACHE /* Use AWCACHE attributes for WA */ + +/* Bit 25: Cache Replacement Policy + * + * Default: 1=Round robin replacement policy + */ + +#define L2CC_ACR_CRPOL_CONFIG L2CC_ACR_CRPOL /* 1=Round robin replacement policy */ + +/* Bit 26: Non-Secure Lockdown Enable + * + * Default: 0=Lockdown registers cannot be modified using non-secure acceses + */ + +#define L2CC_ACR_NSLEN_CONFIG (0) /* 0=Secure access only */ + +/* Bit 27: Non-Secure Interrupt Access Control + * + * Default: 0=Interrupt Clear and Mask can only be modified or read with + * secure accesses + */ + +#define L2CC_ACR_NSIAC_CONFIG (0) /* 0=Secure access only */ + +/* Bit 28: Data Prefetch Enable + * + * Default: 0=Data prefetching disabled + */ + +#define L2CC_ACR_DPEN_CONFIG (0) /* 0=Data prefetching disabled */ + +/* Bit 29: Instruction Prefetch Enable + * + * Default: 0=Instruction prefetching disabled + */ + +#define L2CC_ACR_IPEN_CONFIG (0) /* 0=Instruction prefetching disabled */ + +/* Bit 30: Early BRESP enable + * + * Default: 0=Early BRESP disabled + */ + +#define L2CC_ACR_EBRESP_CONFIG (0) /* 0=Early BRESP disabled */ + +#define L2CC_ACR_CONFIG \ + (L2CC_ACR_FLZE_CONFIG | L2CC_ACR_HPSO_CONFIG | L2CC_ACR_SBDLE_CONFIG | \ + L2CC_ACR_EXCC_CONFIG | L2CC_ACR_SAIE_CONFIG | L2CC_ACR_EMBEN_CONFIG | \ + L2CC_ACR_PEN_CONFIG | L2CC_ACR_SAOEN_CONFIG | L2CC_ACR_FWA_CONFIG | \ + L2CC_ACR_CRPOL_CONFIG | L2CC_ACR_NSLEN_CONFIG | L2CC_ACR_NSIAC_CONFIG | \ + L2CC_ACR_DPEN_CONFIG | L2CC_ACR_IPEN_CONFIG | L2CC_ACR_EBRESP_CONFIG) + +#define L2CC_ACR_ALLCONFIGS (0x7f303c01) +#define L2CC_ACR_CONFIGMASK (L2CC_ACR_SBZ | L2CC_ACR_ALLCONFIGS) + +/* Filter end address */ + +#define CONFIG_PL310_FLEND (CONFIG_PL310_FLSTRT + CONFIG_PL310_FLSIZE) + +/* Block size. Used to break up long operations so that interrupts are not + * disabled for a long time. + */ + +#define PL310_GULP_SIZE 4096 + +/* Misc commoly defined and re-defined things */ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef OK +# define OK 0 +#endif + +/* Data synchronization barrier */ + +#define dsb(a) __asm__ __volatile__ ("dsb " #a : : : "memory") + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pl310_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pl310_flush_all(void) +{ + /* Flush all ways by writing the set of ways to be cleaned to the Clean + * Invalidate Way Register (CIWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_CIWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CIWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_l2ccinitialize(void) +{ + uint32_t regval; + int i; + + /* Make sure that this is a PL310 cache, version r3p2. + * + * REVISIT: The SAMA5D4 is supposed to report its ID as 0x410000C8 which is + * r3p2, but the chip that I have actually* reports 0x410000C9 which is some + * later revision. + */ + + //DEBUGASSERT((getreg32(L2CC_IDR) & L2CC_IDR_REV_MASK) == L2CC_IDR_REV_R3P2); + + /* Make sure that actual cache configuration agrees with the configured + * cache configuration. + */ + + +#if defined(CONFIG_ARMV7A_ASSOCIATIVITY_8WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 0); +#elif defined(CONFIG_ARMV7A_ASSOCIATIVITY_16WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 1); +#else +# error No associativity selected +#endif + +#if defined(CONFIG_ARMV7A_WAYSIZE_16KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_16KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_32KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_32KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_64KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_64KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_128KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_128KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_256KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_256KB); +#elif defined(CONFIG_ARMV7A_WAYSIZE_512KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_512KB); +#else +# error No way size selected +#endif + + /* L2 configuration can only be changed if the cache is disabled, + * + * NOTE: This register access will fail if we are not in secure more. + */ + + if ((getreg32(L2CC_CR) & L2CC_CR_L2CEN) == 0) + { +#if defined(CONFIG_PL310_TRCR_TSETLAT) && defined(CONFIG_PL310_TRCR_TRDLAT) && \ + defined(CONFIG_PL310_TRCR_TWRLAT) + /* Configure Tag RAM control */ + + regval = ((CONFIG_PL310_TRCR_TSETLAT - 1) << L2CC_TRCR_TSETLAT_SHIFT) + ((CONFIG_PL310_TRCR_TRDLAT - 1) << L2CC_TRCR_TRDLAT_SHIFT) | + ((CONFIG_PL310_TRCR_TWRLAT - 1) << L2CC_TRCR_TWRLAT_SHIFT); + putreg32(regval, L2CC_TRCR); +#endif + +#if defined(CONFIG_PL310_DRCR_DSETLAT) && defined(CONFIG_PL310_DRCR_DRDLAT) && \ + defined(CONFIG_PL310_DRCR_DWRLAT) + /* Configure Data RAM control */ + + regval = ((CONFIG_PL310_DRCR_DSETLAT - 1) << L2CC_DRCR_DSETLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DRDLAT - 1) << L2CC_DRCR_DRDLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DWRLAT - 1) << L2CC_DRCR_DWRLAT_SHIFT); + putreg32(regval, L2CC_DRCR); +#endif + +#ifdef PL310_ADDRESS_FILTERING +#if defined(CONFIG_PL310_FLSTRT) && defined(CONFIG_PL310_FLSIZE) + /* Configure the address filter */ + + regval = (CONFIG_PL310_FLEND + ~L2CC_FLEND_MASK) & L2CC_FLEND_MASK; + putreg32(regval, L2CC_FLEND); + + regval = (CONFIG_PL310_FLSTRT & L2CC_FLSTRT_MASK) | L2CC_FLSTRT_ENABLE; + putreg32(regval | L2X0_ADDR_FILTER_EN, L2CC_FLSTRT); +#endif +#endif + + /* Make sure that the memory is not locked down */ + + for (i = 0; i < PL310_NLOCKREGS; i++) + { + putreg32(0, L2CC_DLKR(i)); + putreg32(0, L2CC_ILKR(i)); + } + + /* Configure the cache properties */ + + regval = getreg32(L2CC_ACR); + regval &= ~L2CC_ACR_CONFIGMASK; + regval |= L2CC_ACR_CONFIG; + putreg32(regval, L2CC_ACR); + + /* Invalidate and enable the cache */ + + l2cc_invalidate_all(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + } + + lldbg("(%d ways) * (%d bytes/way) = %d bytes\n", + PL310_NWAYS, PL310_WAYSIZE, PL310_CACHE_SIZE); +} + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_enable(void) +{ + irqstate_t flags; + + /* Invalidate and enable the cache (must be disabled to do this!) */ + + flags = enter_critical_section(); + l2cc_invalidate_all(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_disable(void) +{ + irqstate_t flags; + + /* Flush all ways using the Clean Invalidate Way Register (CIWR). */ + + flags = enter_critical_section(); + pl310_flush_all(); + + /* Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) */ + + putreg32(0, L2CC_CR); + dsb(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_sync(void) +{ + irqstate_t flags; + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate all ways using the Invalidate Way Register (IWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate_all(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Invalidate all ways */ + + flags = enter_critical_section(); + + /* Disable the L2 cache while we invalidate it */ + + regval = getreg32(L2CC_CR); + l2cc_disable(); + + /* Invalidate all ways by writing the bit mask of ways to be invalidated + * the Invalidate Way Register (IWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_IWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_IWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + + /* Then re-enable the L2 cache if it was enabled before */ + + putreg32(regval, L2CC_CR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses by writing to the Invalidate Physical + * Address Line Register (IPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t invalsize; + uintptr_t gulpend; + irqstate_t flags; + + /* Check if the start address is aligned with a cacheline */ + + flags = enter_critical_section(); + if ((startaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush the cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(startaddr, L2CC_CIPALR); + + /* Then start invalidating at the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Check if the end address is aligned with a cache line */ + + if ((endaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + endaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(endaddr, L2CC_CIPALR); + } + + leave_critical_section(flags); + + /* Loop, invalidated the address range by cache line. Interrupts are re- + * enabled momentarily every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to invalidate. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + invalsize = endaddr - startaddr; + gulpend = startaddr + MIN(invalsize, PL310_GULP_SIZE); + + /* Disable interrupts and invalidate the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Invalidate the cache line by writing the address to the + * Invalidate Physical Address Line Register (IPALR). + */ + + putreg32(startaddr, L2CC_IPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean all ways by using the Clean Ways Register (CWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean_all(void) +{ + irqstate_t flags; + + /* Clean all ways by writing the set of ways to be cleaned to the Clean + * Ways Register (CWR). + */ + + flags = enter_critical_section(); + putreg32(PL310_WAY_MASK, L2CC_CWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean the cache line over a range of addresses uing the Clean Physical + * Address Line Register (CPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t cleansize; + uintptr_t gulpend; + irqstate_t flags; + + /* If the range of addresses to clean is as large or larger the L2 cache, + * then just clean the whole thing. + */ + + cleansize = endaddr - startaddr; + if (cleansize >= PL310_CACHE_SIZE) + { + l2cc_clean_all(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Clean the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + cleansize = endaddr - startaddr; + gulpend = startaddr + MIN(cleansize, PL310_GULP_SIZE); + + /* Disable interrupts and clean the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Clean the cache line by writing the address to the Clean + * Physical Address Line Register (CPALR). + */ + + putreg32(startaddr, L2CC_CPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush_all(void) +{ + irqstate_t flags; + + /* Flush all ways using the Clean Invalidate Way Register (CIWR). */ + + flags = enter_critical_section(); + pl310_flush_all(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address by using the Clean Invalidate Physical Address + * Line Register (CIPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush(uint32_t startaddr, uint32_t endaddr) +{ + uintptr_t flushsize; + uintptr_t gulpend; + irqstate_t flags; + + /* If the range of addresses to flush is as large or larger the L2 cache, + * then just flush the whole thing. + */ + + flushsize = endaddr - startaddr; + if (flushsize >= PL310_CACHE_SIZE) + { + l2cc_flush_all(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Flush the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + flushsize = endaddr - startaddr; + gulpend = startaddr + MIN(flushsize, PL310_GULP_SIZE); + + /* Disable interrupts and flush the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Flush the cache line by writing the address to the Clean + * Invalidate Physical Address Line Register (CIPALR). + */ + + putreg32(startaddr, L2CC_CIPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +#endif /* CONFIG_ARMV7A_L2CC_PL310 */ diff --git a/arch/arm/src/armv7-a/arm_memcpy.S b/arch/arm/src/armv7-a/arm_memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..48e1294986b1a92468b36270949839cfaa0204ab --- /dev/null +++ b/arch/arm/src/armv7-a/arm_memcpy.S @@ -0,0 +1,429 @@ +/************************************************************************************ + * nuttx/arch/arm/src/armv7-a/arm_memcpy.S + * + * ARMv7-A optimised memcpy, based on the ARMv7-M version contributed by Mike Smith. + * Apparently in the public domain and is re-released here under the modified BSD + * license: + * + * Obtained via a posting on the Stellaris forum: + * http://e2e.ti.com/support/microcontrollers/\ + * stellaris_arm_cortex-m3_microcontroller/f/473/t/44360.aspx + * + * Posted by rocksoft on Jul 24, 2008 10:19 AM + * + * Hi, + * + * I recently finished a "memcpy" replacement and thought it might be useful for + * others... + * + * I've put some instructions and the code here: + * + * http://www.rock-software.net/downloads/memcpy/ + * + * Hope it works for you as well as it did for me. + * + * Liam. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .global memcpy + + .syntax unified + + .file "arm_memcpy.S" + +/************************************************************************************ + * .text + ************************************************************************************/ + + .text + +/************************************************************************************ + * Private Constant Data + ************************************************************************************/ + +/* We have 16 possible alignment combinations of src and dst, this jump table + * directs the copy operation + * + * Bits: Src=00, Dst=00 - Long to Long copy + * Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=10 - Long to Half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + * Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=01 - Byte before half word to byte before half word - + * Same alignment + * Bits: Src=01, Dst=10 - Byte before half word to half word + * Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * Bits: Src=10, Dst=00 - Half word to long word + * Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * Bits: Src=10, Dst=11 - Half word to byte before long word + * Bits: Src=11, Dst=00 - Byte before long word to long word + * Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - + * Same alignment + */ + +MEM_DataCopyTable: + .byte (MEM_DataCopy0 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy1 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy2 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy3 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy4 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy5 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy6 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy7 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy8 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy9 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy10 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy11 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy12 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy13 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy14 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy15 - MEM_DataCopyJump) >> 1 + + .align 2 + +MEM_LongCopyTable: + .byte (MEM_LongCopyEnd - MEM_LongCopyJump) >> 1 /* 0 bytes left */ + .byte 0 /* 4 bytes left */ + .byte (1 * 10) >> 1 /* 8 bytes left */ + .byte (2 * 10) >> 1 /* 12 bytes left */ + .byte (3 * 10) >> 1 /* 16 bytes left */ + .byte (4 * 10) >> 1 /* 20 bytes left */ + .byte (5 * 10) >> 1 /* 24 bytes left */ + .byte (6 * 10) >> 1 /* 28 bytes left */ + .byte (7 * 10) >> 1 /* 32 bytes left */ + .byte (8 * 10) >> 1 /* 36 bytes left */ + + .align 2 + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/************************************************************************************ + * Name: memcpy + * + * Description: + * Optimised "general" copy routine + * + * Input Parameters: + * r0 = destination, r1 = source, r2 = length + * + * Returned Value: + * r0 = destination r1-r3 burned + * + ************************************************************************************/ + + .align 4 + +memcpy: + push {r14} + push {r0} + bl _do_memcpy + pop {r0} + pop {pc} + + .align 4 + +_do_memcpy: + push {r14} + + /* This allows the inner workings to "assume" a minimum amount of bytes */ + /* Quickly check for very short copies */ + + cmp r2, #4 + blt.n MEM_DataCopyBytes + + and r14, r0, #3 /* Get destination alignment bits */ + bfi r14, r1, #2, #2 /* Get source alignment bits */ + ldr r3, =MEM_DataCopyTable /* Jump table base */ + tbb [r3, r14] /* Perform jump on src/dst alignment bits */ +MEM_DataCopyJump: + + .align 4 + +/* Bits: Src=01, Dst=01 - Byte before half word to byte before half word - Same alignment + * 3 bytes to read for long word aligning + */ + +MEM_DataCopy5: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * 2 bytes to read for long word aligning + */ + +MEM_DataCopy10: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - Same alignment + * 1 bytes to read for long word aligning + */ + +MEM_DataCopy15: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=00 - Long to Long copy */ + +MEM_DataCopy0: + /* Save regs that may be used by memcpy */ + + push {r4-r12} + + /* Check for short word-aligned copy */ + + cmp r2, #0x28 + blt.n MEM_DataCopy0_2 + + /* Bulk copy loop */ + +MEM_DataCopy0_1: + ldmia r1!, {r3-r12} + stmia r0!, {r3-r12} + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy0_1 + + /* Copy remaining long words */ + +MEM_DataCopy0_2: + /* Copy remaining long words */ + + ldr r14, =MEM_LongCopyTable + lsr r11, r2, #0x02 + tbb [r14, r11] + + /* longword copy branch table anchor */ + +MEM_LongCopyJump: + ldr.w r3, [r1], #0x04 /* 4 bytes remain */ + str.w r3, [r0], #0x04 + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r4} /* 8 bytes remain */ + stmia.w r0!, {r3-r4} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r5} /* 12 bytes remain */ + stmia.w r0!, {r3-r5} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r6} /* 16 bytes remain */ + stmia.w r0!, {r3-r6} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r7} /* 20 bytes remain */ + stmia.w r0!, {r3-r7} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r8} /* 24 bytes remain */ + stmia.w r0!, {r3-r8} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r9} /* 28 bytes remain */ + stmia.w r0!, {r3-r9} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r10} /* 32 bytes remain */ + stmia.w r0!, {r3-r10} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r11} /* 36 bytes remain */ + stmia.w r0!, {r3-r11} + +MEM_LongCopyEnd: + pop {r4-r12} + and r2, r2, #0x03 /* All the longs have been copied */ + + /* Deal with up to 3 remaining bytes */ + +MEM_DataCopyBytes: + /* Deal with up to 3 remaining bytes */ + + cmp r2, #0x00 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + pop {pc} + + .align 4 + +/* Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy7: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=00 - Half word to long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy8: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy13: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=10 - Long to Half word */ + +MEM_DataCopy2: + cmp r2, #0x28 + blt.n MEM_DataCopy2_1 + + /* Save regs */ + + push {r4-r12} + + /* Bulk copy loop */ + +MEM_DataCopy2_2: + ldmia r1!, {r3-r12} + + strh r3, [r0], #0x02 + + lsr r3, r3, #0x10 + bfi r3, r4, #0x10, #0x10 + lsr r4, r4, #0x10 + bfi r4, r5, #0x10, #0x10 + lsr r5, r5, #0x10 + bfi r5, r6, #0x10, #0x10 + lsr r6, r6, #0x10 + bfi r6, r7, #0x10, #0x10 + lsr r7, r7, #0x10 + bfi r7, r8, #0x10, #0x10 + lsr r8, r8, #0x10 + bfi r8, r9, #0x10, #0x10 + lsr r9, r9, #0x10 + bfi r9, r10, #0x10, #0x10 + lsr r10, r10, #0x10 + bfi r10, r11, #0x10, #0x10 + lsr r11, r11, #0x10 + bfi r11, r12, #0x10, #0x10 + stmia r0!, {r3-r11} + lsr r12, r12, #0x10 + strh r12, [r0], #0x02 + + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy2_2 + pop {r4-r12} + +MEM_DataCopy2_1: /* Read longs and write 2 x half words */ + cmp r2, #4 + blt.n MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strh r3, [r0], #0x02 + sub r2, r2, #0x04 + b.n MEM_DataCopy2 + +/* Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=10 - Byte before half word to half word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy4: +MEM_DataCopy6: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=11 - Half word to byte before long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy9: +MEM_DataCopy11: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=00 -chm Byte before long word to long word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy12: +MEM_DataCopy14: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + */ + +MEM_DataCopy1: /* Read longs, write B->H->B */ +MEM_DataCopy3: + cmp r2, #4 + blt MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strb r3, [r0], #0x01 + lsr r3, r3, #0x08 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strb r3, [r0], #0x01 + sub r2, r2, #0x04 + b.n MEM_DataCopy3 + + .size memcpy, .-memcpy + .end diff --git a/arch/arm/src/armv7-a/arm_mmu.c b/arch/arm/src/armv7-a/arm_mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..19c609e5b0f6be357b797008273ea87eb8ce1fe2 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_mmu.c @@ -0,0 +1,240 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_mmu.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "cache.h" +#include "mmu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mmu_l1_setentry + * + * Description: + * Set a one level 1 translation table entry. Only a single L1 page table + * is supported. + * + * Input Parameters: + * paddr - The physical address to be mapped. Must be aligned to a 1MB + * address boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 1MB + * address boundary + * mmuflags - The MMU flags to use in the mapping. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *l1table = (uint32_t *)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + l1table[index] = (paddr | mmuflags); + + /* Flush the data cache entry. Make sure that the modified contents + * of the page table are flushed into physical memory. + */ + + cp15_clean_dcache_bymva((uint32_t)&l1table[index]); + + /* Invalidate the TLB cache associated with virtual address range */ + + mmu_invalidate_region(vaddr, 1024*1024); +} +#endif + +/**************************************************************************** + * Name: mmu_l1_restore + * + * Description: + * Restore one L1 table entry previously returned by mmu_l1_getentry() (or + * any other encoded L1 page table value). + * + * Input Parameters: + * vaddr - A virtual address to be mapped + * l1entry - The value to write into the page table entry + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_ADDRENV) +void mmu_l1_restore(uintptr_t vaddr, uint32_t l1entry) +{ + uint32_t *l1table = (uint32_t *)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Set the encoded page table entry */ + + l1table[index] = l1entry; + + /* Flush the data cache entry. Make sure that the modified contents + * of the page table are flushed into physical memory. + */ + + cp15_clean_dcache_bymva((uint32_t)&l1table[index]); + + /* Invalidate the TLB cache associated with virtual address range */ + + mmu_invalidate_region(vaddr & PMD_PTE_PADDR_MASK, 1024*1024); +} +#endif + +/**************************************************************************** + * Name: mmu_l2_setentry + * + * Description: + * Set one small (4096B) entry in a level2 translation table. + * + * Input Parameters: + * l2vaddr - the virtual address of the beginning of the L2 translation + * table. + * paddr - The physical address to be mapped. Must be aligned to a 4KB + * address boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 4KB + * address boundary + * mmuflags - The MMU flags to use in the mapping. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l2_setentry(uint32_t l2vaddr, uint32_t paddr, uint32_t vaddr, + uint32_t mmuflags) +{ + uint32_t *l2table = (uint32_t *)l2vaddr; + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the table entry */ + + l2table[index] = (paddr | mmuflags); + + /* Flush the data cache entry. Make sure that the modified contents + * of the page table are flushed into physical memory. + */ + + cp15_clean_dcache_bymva((uint32_t)&l2table[index]); + + /* Invalidate the TLB cache associated with virtual address range */ + + cp15_invalidate_tlb_bymva(vaddr); +} +#endif + +/**************************************************************************** + * Name: mmu_l1_map_region + * + * Description: + * Set multiple level 1 translation table entries in order to map a + * region of memory. + * + * Input Parameters: + * mapping - Describes the mapping to be performed. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_map_region(const struct section_mapping_s *mapping) +{ + uint32_t paddr = mapping->physbase; + uint32_t vaddr = mapping->virtbase; + uint32_t mmuflags = mapping->mmuflags; + int i; + + /* Loop, writing each mapping into the L1 page table */ + + for (i = 0; i < mapping->nsections; i++) + { + mmu_l1_setentry(paddr, vaddr, mmuflags); + paddr += SECTION_SIZE; + vaddr += SECTION_SIZE; + } +} +#endif + +/**************************************************************************** + * Name: mmu_invalidate_region + * + * Description: + * Invalidate TLBs for a range of addresses (all 4KB aligned). + * + * Input Parameters: + * vaddr - The beginning of the region to invalidate. + * size - The size of the region in bytes to be invalidated. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_invalidate_region(uint32_t vstart, size_t size) +{ + uint32_t vaddr = vstart & 0xfffff000; + uint32_t vend = vaddr + size; + + /* Loop, invalidating regions */ + + while (vaddr < vend) + { + cp15_invalidate_tlb_bymva(vaddr); + vaddr += 4096; + } +} +#endif diff --git a/arch/arm/src/armv7-a/arm_pgalloc.c b/arch/arm/src/armv7-a/arm_pgalloc.c new file mode 100644 index 0000000000000000000000000000000000000000..d430f8b68b3fe809970df126dbfb2766d5a033a0 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_pgalloc.c @@ -0,0 +1,321 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_pgalloc.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "cache.h" +#include "mmu.h" +#include "pgalloc.h" + +#ifdef CONFIG_BUILD_KERNEL + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: alloc_pgtable + * + * Description: + * Add one page table to a memory region. + * + ****************************************************************************/ + +static uintptr_t alloc_pgtable(void) +{ + irqstate_t flags; + uintptr_t paddr; + FAR uint32_t *l2table; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + + /* Allocate one physical page for the L2 page table */ + + paddr = mm_pgalloc(1); + if (paddr) + { + DEBUGASSERT(MM_ISALIGNED(paddr)); + + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page address */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + l2table = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Initialize the page table */ + + memset(l2table, 0, MM_PGSIZE); + + /* Make sure that the initialized L2 table is flushed to physical + * memory. + */ + + arch_flush_dcache((uintptr_t)l2table, + (uintptr_t)l2table + MM_PGSIZE); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + } + + return paddr; +} + +/**************************************************************************** + * Name: get_pgtable + * + * Description: + * Return the physical address of the L2 page table corresponding to + * 'vaddr' + * + ****************************************************************************/ + +static int get_pgtable(FAR group_addrenv_t *addrenv, uintptr_t vaddr) +{ + uint32_t l1entry; + uintptr_t paddr; + unsigned int hpoffset; + unsigned int hpndx; + + /* The current implementation only supports extending the user heap + * region as part of the implementation of user sbrk(). + */ + + DEBUGASSERT(vaddr >= CONFIG_ARCH_HEAP_VBASE && vaddr < ARCH_HEAP_VEND); + + /* Get the current level 1 entry corresponding to this vaddr */ + + hpoffset = vaddr - CONFIG_ARCH_HEAP_VBASE; + if (hpoffset >= ARCH_HEAP_SIZE) + { + return 0; + } + + hpndx = hpoffset >> 20; + l1entry = (uintptr_t)addrenv->heap[hpndx]; + if (l1entry == 0) + { + /* No page table has been allocated... allocate one now */ + + paddr = alloc_pgtable(); + if (paddr != 0) + { + /* Set the new level 1 page table entry in the address environment. */ + + l1entry = paddr | MMU_L1_PGTABFLAGS; + addrenv->heap[hpndx] = (FAR uintptr_t *)l1entry; + + /* And instantiate the modified environment */ + + (void)up_addrenv_select(addrenv, NULL); + } + } + + return l1entry & ~SECTION_MASK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pgalloc + * + * Description: + * If there is a page allocator in the configuration and if and MMU is + * available to map physical addresses to virtual address, then function + * must be provided by the platform-specific code. This is part of the + * implementation of sbrk(). This function will allocate the requested + * number of pages using the page allocator and map them into consecutive + * virtual addresses beginning with 'brkaddr' + * + * NOTE: This function does not use the up_ naming standard because it + * is indirectly callable from user-space code via a system trap. + * Therefore, it is a system interface and follows a different naming + * convention. + * + * Input Parameters: + * brkaddr - The heap break address. The next page will be allocated and + * mapped to this address. Must be page aligned. If the memory manager + * has not yet been initialized and this is the first block requested for + * the heap, then brkaddr should be zero. pgalloc will then assigned the + * well-known virtual address of the beginning of the heap. + * npages - The number of pages to allocate and map. Mapping of pages + * will be contiguous beginning beginning at 'brkaddr' + * + * Returned Value: + * The (virtual) base address of the mapped page will returned on success. + * Normally this will be the same as the 'brkaddr' input. However, if + * the 'brkaddr' input was zero, this will be the virtual address of the + * beginning of the heap. Zero is returned on any failure. + * + ****************************************************************************/ + +uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages) +{ + FAR struct tcb_s *tcb = sched_self(); + FAR struct task_group_s *group; + FAR uint32_t *l2table; + irqstate_t flags; + uintptr_t paddr; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + unsigned int index; + + DEBUGASSERT(tcb && tcb->group); + group = tcb->group; + + /* The current implementation only supports extending the user heap + * region as part of the implementation of user sbrk(). This function + * needs to be expanded to also handle (1) extending the user stack + * space and (2) extending the kernel memory regions as well. + */ + + DEBUGASSERT((group->tg_flags & GROUP_FLAG_ADDRENV) != 0); + + /* brkaddr = 0 means that no heap has yet been allocated */ + + if (brkaddr == 0) + { + brkaddr = CONFIG_ARCH_HEAP_VBASE; + } + + DEBUGASSERT(brkaddr >= CONFIG_ARCH_HEAP_VBASE && brkaddr < ARCH_HEAP_VEND); + DEBUGASSERT(MM_ISALIGNED(brkaddr)); + + for (; npages > 0; npages--) + { + /* Get the physical address of the level 2 page table */ + + paddr = get_pgtable(&group->tg_addrenv, brkaddr); + if (paddr == 0) + { + return 0; + } + + flags = enter_critical_section(); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address corresponding to the physical page address */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the level 2 page table into the "scratch" virtual + * address space + */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + l2table = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + + /* Back up L2 entry with physical memory */ + + paddr = mm_pgalloc(1); + if (paddr == 0) + { +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + return 0; + } + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (brkaddr & 0x000ff000) >> 12; + + /* Map the .text region virtual address to this physical address */ + + DEBUGASSERT(l2table[index] == 0); + l2table[index] = paddr | MMU_L2_UDATAFLAGS; + brkaddr += MM_PGSIZE; + + /* Make sure that the modified L2 table is flushed to physical + * memory. + */ + + arch_flush_dcache((uintptr_t)&l2table[index], + (uintptr_t)&l2table[index] + sizeof(uint32_t)); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + leave_critical_section(flags); + } + + return brkaddr; +} + +#endif /* CONFIG_BUILD_KERNEL */ diff --git a/arch/arm/src/armv7-a/arm_pghead.S b/arch/arm/src/armv7-a/arm_pghead.S new file mode 100644 index 0000000000000000000000000000000000000000..e785360dfec0fa6a7eec7a29e07bc85bb599c46f --- /dev/null +++ b/arch/arm/src/armv7-a/arm_pghead.S @@ -0,0 +1,835 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_pghead.S + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "arm.h" +#include "cp15.h" +#include "sctlr.h" +#include "mmu.h" +#include "pg_macros.h" + +#include "chip.h" +#include "up_internal.h" + + .file "arm_pghead.S" + +/********************************************************************************** + * Configuration + **********************************************************************************/ +/* Assume these are not needed */ + +#undef ALIGNMENT_TRAP +#undef CPU_CACHE_ROUND_ROBIN +#undef CPU_DCACHE_DISABLE +#undef CPU_ICACHE_DISABLE + +/* The page table cannot be in ROM if we are going to do pagin! */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +# error CONFIG_PAGING and CONFIG_ARCH_ROMPGTABLE are incompatible options +#endif + +/* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Initialize the .data section in RAM, and + * - Clear .bss section + */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 2. We boot in FLASH but copy ourselves to DRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case + * the boot logic must: + * + * - Configure SDRAM, + * - Copy ourself to DRAM (after mapping it), and + * - Clear .bss section + * + * In this case, we assume that the logic within this file executes from FLASH. + */ + +#elif defined(CONFIG_BOOT_COPYTORAM) +# error "configuration not implemented + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of FLASH is the same as the physical + * beginning of FLASH. + */ + +# if !defined(CONFIG_FLASH_START) || !defined(CONFIG_FLASH_VSTART) +# error "CONFIG_FLASH_START or CONFIG_FLASH_VSTART is not defined" +# endif + +# if CONFIG_FLASH_START == CONFIG_FLASH_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning) + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM + * was initialized by the boot loader, and this boot logic must: + * + * - Clear .bss section + */ + +#else + + /* Check for the identity mapping: For this configuration, this would be + * the case where the virtual beginning of RAM is the same as the physical + * beginning of RAM. + */ + +# if !defined(CONFIG_RAM_START) || !defined(CONFIG_RAM_VSTART) +# error "CONFIG_RAM_START or CONFIG_RAM_VSTART is not defined" +# endif + +# if CONFIG_RAM_START == CONFIG_RAM_VSTART +# define CONFIG_IDENTITY_TEXTMAP 1 +# endif + +#endif + +/* For each page table offset, the following provide (1) the physical address of + * the start of the page table and (2) the number of page table entries in the + * first page table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * NPAGE1=(256 -((a) & 0x000003ff) >> 2) NPAGE1=1-256 + * Fine: PG_L1_PADDRMASK=0xfffff000 + * NPAGE1=(1024 -((a) & 0x00000fff) >> 2) NPAGE1=1-1024 + */ + +#define PG_L2_TEXT_PBASE (PG_L2_TEXT_PADDR & PG_L1_PADDRMASK) +#define PG_L2_TEXT_NPAGE1 (PTE_NPAGES - ((PG_L2_TEXT_PADDR & ~PG_L1_PADDRMASK) >> 2)) +#define PG_L2_PGTABLE_PBASE (PG_L2_PGTABLE_PADDR & PG_L1_PADDRMASK) +#define PG_L2_PGTABLE_NPAGE1 (PTE_NPAGES - ((PG_L2_PGTABLE_PADDR & ~PG_L1_PADDRMASK) >> 2)) +#define PG_L2_DATA_PBASE (PG_L2_DATA_PADDR & PG_L1_PADDRMASK) +#define PG_L2_DATA_NPAGE1 (PTE_NPAGES - ((PG_L2_DATA_PADDR & ~PG_L1_PADDRMASK) >> 2)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RX_NSECTIONS determines the number of 1Mb sections to map for the + * Read/eXecute address region. This is based on NUTTX_TEXT_SIZE. + */ + +#define RX_NSECTIONS ((NUTTX_TEXT_SIZE+0x000fffff) >> 20) +#define WR_NSECTIONS ((NUTTX_RAM_SIZE+0x000fffff) >> 20) + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/* The ARMv7-A L1 page table can be placed at the beginning or at the end of + * the RAM space. This decision is based on the placement of the vector + * area: If the vectors are place in low memory at address 0x0000 0000, then + * the page table is placed in high memory; if the vectors are placed in + * high memory at address 0xfff0 0000, then the page table is locating at + * the beginning of RAM. + * + * For the special case where (1) the program executes out of RAM, and (2) + * the page is located at the beginning of RAM (i.e., the high vector case), + * then the following macro can easily find the physical address of the + * section that includes the first part of the text region: Since the page + * table is closely related to the NuttX base address in this case, we can + * convert the page table base address to the base address of the section + * containing both. + */ + +/* This macro will modify r0, r1, r2 and r14 */ + +#ifdef CONFIG_DEBUG + .macro showprogress, code + mov r0, #\code + bl up_lowputc + .endm +#else + .macro showprogress, code + .endm +#endif + +/**************************************************************************** + * Name: __start + ****************************************************************************/ + + .text + .global __start + .type __start, #function + +__start: + /* Make sure that we are in SVC mode with IRQs and FIQs disabled */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, r0 + + /* Clear the 16K level 1 page table */ + + ldr r4, .LCppgtable /* r4=phys. page table */ + mov r0, r4 + mov r1, #0 + add r2, r0, #PGTABLE_SIZE +.Lpgtableclear: + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + str r1, [r0], #4 + teq r0, r2 + bne .Lpgtableclear + +#ifdef ARMV7A_PGTABLE_MAPPING + /* If the page table does not lie in the same address space as does the + * mapped RAM in either case. So we will need to create a special + * mapping for the page table. + * + * Load information needed to map the page table. After the ldmia, we + * will have + * + * R1 = The aligned, physical base address of the page table + * R2 = The aligned, virtual base address of the page table + * R3 = The MMU flags to use with the .text space mapping + * R5 = The physical address of the L1 page table (from above) + * + * The value in R1 could have been obtained by simply masking R5. + */ + + adr r0, .LCptinfo /* Address of page table description */ + ldmia r0, {r1, r2, r3} /* Load the page table description */ + + /* A single page is sufficient to map the page table */ + + orr r0, r1, r3 /* OR MMU flags into physical address */ + str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */ +#endif + +#ifndef CONFIG_IDENTITY_TEXTMAP + /* Create identity mapping for first MB of the .text section to support + * this start-up logic executing out of the physical address space. This + * identity mapping will be removed by .Lvstart (see below). Of course, + * we would only do this if the physical-virtual mapping is not already + * the identity mapping. + */ + + ldr r0, .LCptextbase /* r0=phys. base address of .text section */ + ldr r1, .LCtextflags /* R1=.text section MMU flags */ + orr r3, r1, r0 /* r3=flags + base */ + str r3, [r4, r0, lsr #18] /* identity mapping */ +#endif + + /* Map the read-only .text region in place. This must be done + * before the MMU is enabled and the virtual addressing takes + * effect. First populate the L1 table for the locked and paged + * text regions. + * + * We could probably make the pg_l1span and pg_l2map macros into + * call-able subroutines, but we would have to be carefully during + * this phase while we are operating in a physical address space. + * + * NOTE: That the value of r5 (L1 table base address) must be + * preserved through the following. + */ + + adr r0, .Ltxtspan + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 + + /* Then populate the L2 table for the locked text region only. */ + + adr r0, .Ltxtmap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r5 + + /* Make sure that the page table is itself mapped and and read/write-able. + * First, populate the L1 table: + */ + + adr r0, .Lptabspan + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 + + /* Then populate the L2 table. */ + + adr r0, .Lptabmap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r5 + + /* The following logic will set up the ARMv7-A for normal operation. + * + * Here we expect to have: + * r4 = Address of the base of the L1 table + */ + + /* Invalidate caches and TLBs. + * + * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not + * support a CP15 operation to invalidate the entire data cache. ... + * In normal usage the only time the entire data cache has to be + * invalidated is on reset." + * + * The instruction cache is virtually indexed and physically tagged but + * the data cache is physically indexed and physically tagged. So it + * should not be an issue if the system comes up with a dirty Dcache; + * the ICache, however, must be invalidated. + */ + + mov r0, #0 + mcr CP15_TLBIALL(r0,c7) /* Invalidate the entire unified TLB */ + mcr CP15_TLBIALL(r0,c6) + mcr CP15_TLBIALL(r0,c5) + mcr CP15_BPIALL(r0) /* Invalidate entire branch prediction array */ + mcr CP15_ICIALLU(r0) /* Invalidate I-cache */ + + /* Load the page table address. + * + * NOTES: + * - Here we assume that the page table address is aligned to at least + * least a 16KB boundary (bits 0-13 are zero). No masking is provided + * to protect against an unaligned page table address. + * - The Cortex-A5 has two page table address registers, TTBR0 and 1. + * Only TTBR0 is used in this implementation but both are initialized. + * + * Here we expect to have: + * r0 = Zero + * r4 = Address of the base of the L1 table + */ + + orr r1, r4, #0x48 + mcr CP15_TTBR0(r1) + mcr CP15_TTBR1(r1) + + /* Set the TTB control register (TTBCR) to indicate that we are using + * TTBR0. r0 still holds the value of zero. + * + * N : 0=Selects TTBR0 and 16KB page table size indexed by VA[31:20] + * PD0 : 0=Perform translation table walks using TTBR0 + * PD1 : 0=Perform translation table walks using TTBR1 (but it is disabled) + * EAE : 0=Use 32-bit translation system + */ + + mcr CP15_TTBCR(r0) + + /* Enable the MMU and caches + * lr = Resume at .Lvstart with the MMU enabled + */ + + ldr lr, .LCvstart /* Abs. virtual address */ + + /* Configure the domain access register (see mmu.h). Only domain 0 is + * supported and it uses the permissions in the TLB. + */ + + mov r0, #DACR_CLIENT(0) + mcr CP15_DACR(r0) /* Set domain access register */ + + /* Configure the system control register (see sctrl.h) */ + + mrc CP15_SCTLR(r0) /* Get control register */ + + /* Clear bits to reset values. This is only necessary in situations like, for + * example, we get here via a bootloader and the control register is in some + * unknown state. + * + * SCTLR_A Bit 1: Strict alignment disabled (reset value) + * SCTLR_C Bit 2: DCache disabled (reset value) + * + * SCTLR_SW Bit 10: SWP/SWPB not enabled (reset value) + * SCTLR_I Bit 12: ICache disabled (reset value) + * SCTLR_V Bit 13: Assume low vectors (reset value) + * SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random + * replacement strategy. + * SCTLR_HA Bit 17: Not supported by A5 + * + * SCTLR_EE Bit 25: Little endian (reset value). + * SCTLR_TRE Bit 28: No memory region remapping (reset value) + * SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value). + * SCTLR_TE Bit 30: All exceptions handled in ARM state (reset value). + */ + + bic r0, r0, #(SCTLR_A | SCTLR_C) + bic r0, r0, #(SCTLR_SW | SCTLR_I | SCTLR_V | SCTLR_RR | SCTLR_HA) + bic r0, r0, #(SCTLR_EE | SCTLR_TRE | SCTLR_AFE | SCTLR_TE) + + /* Set bits to enable the MMU + * + * SCTLR_M Bit 0: Enable the MMU + * SCTLR_Z Bit 11: Program flow prediction control always enabled on A5 + */ + + orr r0, r0, #(SCTLR_M) +#ifndef CONFIG_ARCH_CORTEXA5 + orr r0, r0, #(SCTLR_Z) +#endif + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Position vectors to 0xffff0000 if so configured. + * + * SCTLR_V Bit 13: High vectors + */ + + orr r0, r0, #(SCTLR_V) +#endif + +#if defined(CPU_CACHE_ROUND_ROBIN) && !defined(CONFIG_ARCH_CORTEXA5) + /* Round Robin cache replacement + * + * SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random + * replacement strategy. + */ + + orr r0, r0, #(SCTLR_RR) +#endif + +#ifndef CPU_DCACHE_DISABLE + /* Dcache enable + * + * SCTLR_C Bit 2: DCache enable + */ + + orr r0, r0, #(SCTLR_C) +#endif + +#ifndef CPU_ICACHE_DISABLE + /* Icache enable + * + * SCTLR_I Bit 12: ICache enable + */ + + orr r0, r0, #(SCTLR_I) +#endif + +#ifdef ALIGNMENT_TRAP + /* Alignment abort enable + * + * SCTLR_A Bit 1: Strict alignment enabled + */ + + orr r0, r0, #(SCTLR_A) +#endif + +#ifdef CPU_AFE_ENABLE + /* AP[0:2] Permissions model + * + * SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value). + * + * When AFE=1, the page table AP[0] is used as an access flag and AP[2:1] + * control. When AFE=0, AP[2:0] control access permissions. + */ + + orr r0, r0, #(SCTLR_AFE) +#endif + + /* Then write the configured control register */ + + mcr CP15_SCTLR(r0) /* Write control reg */ + .rept 12 /* Cortex A8 wants lots of NOPs here */ + nop + .endr + + /* And "jump" to .Lvstart in the newly mapped virtual address space */ + + mov pc, lr + +/**************************************************************************** + * PC_Relative Data + ****************************************************************************/ + + /* The virtual start address of the second phase boot logic */ + + .type .LCvstart, %object +.LCvstart: + .long .Lvstart + .size .LCvstart, . -.LCvstart + +#ifdef ARMV7A_PGTABLE_MAPPING + /* Page table region description. The order of these fields must not + * change because the values are loaded using ldmia: + * + * 1) The aligned, physical base address of the page table + * 2) The aligned, virtual base address of the page table + * 3) The MMU flags to use with the .text space mapping + */ + + .type .LCptinfo, %object +.LCptinfo: + .long (PGTABLE_BASE_PADDR & 0xfff00000) /* Physical base address */ + .long (PGTABLE_BASE_VADDR & 0xfff00000) /* Virtual base address */ + .long MMU_MEMFLAGS /* MMU flags for text section in RAM */ + .size .LCptinfo, . -.LCptinfo +#endif + + /* The aligned, physical base address of the .text section */ + + .type .LCptextbase, %object +.LCptextbase: + .long NUTTX_TEXT_PADDR & 0xfff00000 + .size .LCptextbase, . -.LCptextbase + + /* The aligned, virtual base address of the .text section */ + + .type .LCvtextbase, %object +.LCvtextbase: + .long NUTTX_TEXT_VADDR & 0xfff00000 + .size .LCvtextbase, . -.LCvtextbase + + /* The MMU flags used with the .text mapping */ + + .type .LCtextflags, %object +.LCtextflags: +#ifdef CONFIG_BOOT_RUNFROMFLASH + .long MMU_ROMFLAGS /* MMU flags text section in FLASH/ROM */ +#else + .long MMU_MEMFLAGS /* MMU flags for text section in RAM */ +#endif + .size .LCtextflags, . -.LCtextflags + + /* The physical base address of the page table */ + + .type .LCppgtable, %object +.LCppgtable: + .long PGTABLE_BASE_PADDR /* Physical start of page table */ + .size .LCppgtable, . -.LCppgtable + + /* The virtual base address of the page table */ + + .type .LCvpgtable, %object +.LCvpgtable: + .long PGTABLE_BASE_VADDR /* Virtual start of page table */ + .size .LCvpgtable, . -.LCvpgtable + + .type .Ltxtspan, %object +.Ltxtspan: + .long PG_L1_TEXT_PADDR /* Physical address in the L1 table */ + .long PG_L2_TEXT_PBASE /* Physical address of the start of the L2 page table */ + .long PG_TEXT_NVPAGES /* Total (virtual) text pages to be mapped */ + .long PG_L2_TEXT_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_TEXTFLAGS /* L1 MMU flags to use */ + .size .Ltxtspan, . -.Ltxtspan + + .type .Ltxtmap, %object +.Ltxtmap: + .long PG_L2_LOCKED_PADDR /* Physical address in the L2 table */ + .long PG_LOCKED_PBASE /* Physical address of locked base memory */ + .long CONFIG_PAGING_NLOCKED /* Number of pages in the locked region */ + .long MMU_L2_TEXTFLAGS /* L2 MMU flags to use */ + .size .Ltxtmap, . -.Ltxtmap + + .type .Lptabspan, %object +.Lptabspan: + .long PG_L1_PGTABLE_PADDR /* Physical address in the L1 table */ + .long PG_L2_PGTABLE_PBASE /* Physical address of the start of the L2 page table */ + .long PG_PGTABLE_NPAGES /* Total mapped page table pages */ + .long PG_L2_PGTABLE_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_PGTABFLAGS /* L1 MMU flags to use */ + .size .Lptabspan, . -.Lptabspan + + .type .Lptabmap, %object +.Lptabmap: + .long PG_L2_PGTABLE_PADDR /* Physical address in the L2 table */ + .long PGTABLE_BASE_PADDR /* Physical address of the page table memory */ + .long PG_PGTABLE_NPAGES /* Total mapped page table pages */ + .long MMU_L2_PGTABFLAGS /* L2 MMU flags to use */ + .size .Lptabmap, . -.Lptabmap + + .size __start, .-__start + +/**************************************************************************** + * Name: .Lvstart + ***************************************************************************/ + +/* The following is executed after the MMU has been enabled. This uses + * absolute addresses; this is not position independent. + */ + .align 5 + .local .Lvstart + .type .Lvstart, %function + +.Lvstart: + +#ifndef CONFIG_IDENTITY_TEXTMAP + /* Remove the temporary mapping (if one was made). The following assumes + * that the total RAM size is > 1Mb and extends that initial mapping to + * cover additional RAM sections. + */ + + ldr r4, .LCvpgtable /* r4=virtual page table base address */ + ldr r3, .LCvtextbase /* r0=virtual base address of .text section */ + mov r0, #0 /* flags + base = 0 */ + str r3, [r4, r3, lsr #18] /* identity mapping */ +#endif + + /* Populate the L1 table for the data region */ + + adr r0, .Ldataspan + ldmia r0, {r0, r1, r2, r3, r4} + pg_l1span r0, r1, r2, r3, r4, r5 + + /* Populate the L2 table for the data region */ + + adr r0, .Ldatamap + ldmia r0, {r0, r1, r2, r3} + pg_l2map r0, r1, r2, r3, r4 + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Get R3 = Value of RAM L1 page table entry */ + + ldr r3, .LCprambase /* r3=Aligned Nuttx RAM address (physical) */ + ldr r1, .LCramflags /* R1=.bss/.data section MMU flags */ + add r3, r3, r1 /* r3=flags + base */ + + /* Now setup the page tables for our normal mapped RAM region. + * We round NUTTX_RAM_VADDR down to the nearest megabyte boundary. + */ + + add r0, r4, #(NUTTX_RAM_VADDR & 0xfff00000) >> 18 + str r3, [r0], #4 + + /* Now map the remaining WR_NSECTIONS-1 sections of the RAM memory + * region. + */ + + .rept WR_NSECTIONS-1 + add r3, r3, #SECTION_SIZE + str r3, [r0], #4 + .endr +#endif /* CONFIG_BOOT_RUNFROMFLASH */ + + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. + */ + + /* Set up the stack pointer and clear the frame pointer */ + + ldr sp, .Lstackpointer + mov fp, #0 + +#ifndef CONFIG_BOOT_SDRAM_DATA + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. + */ + + bl arm_data_initialize +#endif + + /* Perform early C-level, platform-specific initialization. Logic + * within up_boot() must configure SDRAM and call arm_ram_initailize. + */ + + bl up_boot + +#ifdef CONFIG_STACK_COLORATION + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +1: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 1b /* Bottom of the loop */ +#endif + + /* Finally branch to the OS entry point */ + + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ + .size .Lvstart, .-.Lvstart + +/*************************************************************************** + * Name: arm_data_initialize + ***************************************************************************/ + + .global arm_data_initialize + .type arm_data_initialize, #function + +arm_data_initialize: + + /* Zero BSS */ + + adr r0, .Linitparms + ldmia r0, {r0, r1} + + mov r2, #0 +1: + cmp r0, r1 /* Clear up to _bss_end_ */ + strcc r2, [r0],#4 + bcc 1b + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* If the .data section is in a separate, uninitialized address space, + * then we will also need to copy the initial values of of the .data + * section from the .text region into that .data region. This would + * be the case if we are executing from FLASH and the .data section + * lies in a different physical address region OR if we are support + * on-demand paging and the .data section lies in a different virtual + * address region. + */ + + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +2: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt 2b +#endif + + /* And return to the caller */ + + bx lr + .size arm_data_initialize, . - arm_data_initialize + +/*************************************************************************** + * Text-section constants + ***************************************************************************/ + + /* Text-section constants: + * + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * + * The idle task stack usually starts at the end of BSS and is of size + * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the + * end of memory. See g_idle_topstack below. + * + * In the case where CONFIG_BOOT_SDRAM_DATA is defined, the IDLE stack is + * in ISRAM, but the heap is in SDRAM beginning at _ebss and extending + * to the end of SDRAM. + */ + + .type .Linitparms, %object +.Linitparms: + .long _sbss + .long _ebss + .size .Linitparms, . -.Linitparms + +.Lstackpointer: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE-4 +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +#endif + .size .Lstackpointer, . -.Lstackpointer + + .type .Ldataspan, %object +.Ldataspan: + .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ + .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ + .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ + .size .Ldataspan, . -.Ldataspan + + .type .Ldatamap, %object +.Ldatamap: + .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ + .long PG_DATA_PBASE /* Physical address of data memory */ + .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */ + .size .Ldatamap, . -.Ldatamap + + .type .Ldatainit, %object +.Ldatainit: + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata + .size .Ldatainit, . -.Ldatainit + +#ifdef CONFIG_STACK_COLORATION + .type .Lstkinit, %object +.Lstkinit: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */ +#else + .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ +#endif + .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) + .long STACK_COLOR /* Stack coloration word */ + .size .Lstkinit, . -.Lstkinit +#endif + +/*************************************************************************** + * Data section variables + ***************************************************************************/ + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to .Linitparms + * above. + */ + + .section .rodata, "a" + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object + +g_idle_topstack: + +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE +#endif + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/arm/src/armv7-a/arm_pginitialize.c b/arch/arm/src/armv7-a/arm_pginitialize.c new file mode 100644 index 0000000000000000000000000000000000000000..f419a28ba4c0f3c6f56d988c558a0657129d4e30 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_pginitialize.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_pginitialize.c + * Initialize the MMU for on-demand paging support. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_pginitialize() + * + * Description: + * Initialize the MMU for on-demand paging support.. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. This function will crash if any errors are detected during MMU + * initialization + * + * Assumptions: + * - Called early in the platform initialization sequence so that no special + * concurrency protection is required. + * + ****************************************************************************/ + +void up_pginitialize(void) +{ + /* None needed at present. This file is just retained in case the need + * arises in the future. Nothing calls up_pginitialize() now. If needed, + * if should be called early in up_boot.c to assure that all paging is + * ready. + */ +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_physpgaddr.c b/arch/arm/src/armv7-a/arm_physpgaddr.c new file mode 100644 index 0000000000000000000000000000000000000000..d3fecd1fc11c2a1e827bb7295b9927e1b82ad5d7 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_physpgaddr.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_phypgaddr.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "mmu.h" +#include "cache.h" + +#include "pgalloc.h" + +#ifdef CONFIG_MM_PGALLOC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_physpgaddr + * + * Description: + * Check if the virtual address lies in the user data area and, if so + * get the mapping to the physical address in the page pool. + * + ****************************************************************************/ + +uintptr_t arm_physpgaddr(uintptr_t vaddr) +{ + FAR uint32_t *l2table; + uintptr_t paddr; + uint32_t l1entry; +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + uint32_t l1save; +#endif + int index; + + /* Check if this address is within the range of one of the virtualized user + * address regions. + */ + + if (arm_uservaddr(vaddr)) + { + /* Yes.. Get Level 1 page table entry corresponding to this virtual + * address. + */ + + l1entry = mmu_l1_getentry(vaddr); + if ((l1entry & PMD_TYPE_MASK) == PMD_TYPE_PTE) + { + /* Get the physical address of the level 2 page table from the + * level 1 page table entry. + */ + + paddr = ((uintptr_t)l1entry & PMD_PTE_PADDR_MASK); + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING + /* Get the virtual address of the base of level 2 page table */ + + l2table = (FAR uint32_t *)arm_pgvaddr(paddr); +#else + /* Temporarily map the page into the virtual address space */ + + l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + l2table = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +#endif + if (l2table) + { + /* Invalidate D-Cache line containing this virtual address so that + * we re-read from physical memory + */ + + index = (vaddr & SECTION_MASK) >> MM_PGSHIFT; + arch_invalidate_dcache((uintptr_t)&l2table[index], + (uintptr_t)&l2table[index] + sizeof(uint32_t)); + + /* Get the Level 2 page table entry corresponding to this virtual + * address. Extract the physical address of the page containing + * the mapping of the virtual address. + */ + + paddr = ((uintptr_t)l2table[index] & PTE_SMALL_PADDR_MASK); + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING + /* Restore the scratch section L1 page table entry */ + + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +#endif + + /* Add the correct offset and return the physical address + * corresponding to the virtual address. + */ + + return paddr + (vaddr & MM_PGMASK); + } + } + } + + /* No mapping available */ + + return 0; +} + +#endif /* CONFIG_MM_PGALLOC */ diff --git a/arch/arm/src/armv7-a/arm_prefetchabort.c b/arch/arm/src/armv7-a/arm_prefetchabort.c new file mode 100644 index 0000000000000000000000000000000000000000..7d2b4cf2df2456e37792ce126986ed99cdc238b8 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_prefetchabort.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_prefetchabort.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include +#ifdef CONFIG_PAGING +# include +#endif + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_prefetchabort + * + * Description; + * This is the prefetch abort exception handler. The ARM prefetch abort + * exception occurs when a memory fault is detected during an an + * instruction fetch. + * + ****************************************************************************/ + +#ifdef CONFIG_PAGING + +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) +{ + uint32_t *savestate; + + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Get the (virtual) address of instruction that caused the prefetch abort. + * When the exception occurred, this address was provided in the lr register + * and this value was saved in the context save area as the PC at the + * REG_R15 index. + * + * Check to see if this miss address is within the configured range of + * virtual addresses. + */ + + pglldbg("VADDR: %08x VBASE: %08x VEND: %08x\n", + regs[REG_PC], PG_PAGED_VBASE, PG_PAGED_VEND); + + if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND) + { + /* Save the offending PC as the fault address in the TCB of the currently + * executing task. This value is, of course, already known in regs[REG_R15], + * but saving it in this location will allow common paging logic for both + * prefetch and data aborts. + */ + + struct tcb_s *tcb = this_task(); + tcb->xcp.far = regs[REG_R15]; + + /* Call pg_miss() to schedule the page fill. A consequences of this + * call are: + * + * (1) The currently executing task will be blocked and saved on + * on the g_waitingforfill task list. + * (2) An interrupt-level context switch will occur so that when + * this function returns, it will return to a different task, + * most likely the page fill worker thread. + * (3) The page fill worker task has been signalled and should + * execute immediately when we return from this exception. + */ + + pg_miss(); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + } + else + { + lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n", + regs[REG_PC], ifar, ifsr); + PANIC(); + } + + return regs; +} + +#else /* CONFIG_PAGING */ + +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = regs; + + /* Crash -- possibly showing diagnostic debug information. */ + + lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n", + regs[REG_PC], ifar, ifsr); + PANIC(); + return regs; /* To keep the compiler happy */ +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_releasepending.c b/arch/arm/src/armv7-a/arm_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..9696e931c0bdb7643535b0aa3e795eb237cb9c8c --- /dev/null +++ b/arch/arm/src/armv7-a/arm_releasepending.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_releasepending.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to + * switch contexts. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-a/arm_reprioritizertr.c b/arch/arm/src/armv7-a/arm_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..d4b2699f6dd01f2a3cc0c3be38038f1961c18c6e --- /dev/null +++ b/arch/arm/src/armv7-a/arm_reprioritizertr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_reprioritizertr.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/arm/src/armv7-a/arm_restorefpu.S b/arch/arm/src/armv7-a/arm_restorefpu.S new file mode 100644 index 0000000000000000000000000000000000000000..6633e6dc514f52b6369282cf79d84c60620aa18b --- /dev/null +++ b/arch/arm/src/armv7-a/arm_restorefpu.S @@ -0,0 +1,108 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/arm_restorefpu.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_FPU + + .file "arm_restorefpu.S" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_restorefpu + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_restorefpu + * + * Description: + * Given the pointer to a register save area (in R0), restore the state of the + * floating point registers. + * + * C Function Prototype: + * void up_restorefpu(const uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area containing the floating point + * registers. + * + * Returned Value: + * This function does not return anything explicitly. However, it is called from + * interrupt level assembly logic that assumes that r0 is preserved. + * + ************************************************************************************/ + + .globl up_restorefpu + .type up_restorefpu, function + +up_restorefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Load all floating point registers. Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + + vldmia r1!, {s0-s31} /* Restore the full FP context */ + + /* Load the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + vmsr fpscr, r2 /* Restore the FPCSR */ + bx lr + + .size up_restorefpu, .-up_restorefpu +#endif /* CONFIG_ARCH_FPU */ + .end + diff --git a/arch/arm/src/armv7-a/arm_savefpu.S b/arch/arm/src/armv7-a/arm_savefpu.S new file mode 100644 index 0000000000000000000000000000000000000000..b753046d9f292a22414d19fa3cea7809c3a73336 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_savefpu.S @@ -0,0 +1,106 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/arm_savefpu.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_FPU + + .file "arm_savefpu.S" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_savefpu + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_savefpu + * + * Description: + * Given the pointer to a register save area (in R0), save the state of the + * floating point registers. + * + * C Function Prototype: + * void up_savefpu(uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area in which to save the floating point + * registers + * + * Returned Value: + * None + * + ************************************************************************************/ + + .globl up_savefpu + .type up_savefpu, function + +up_savefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Store all floating point registers. Registers are stored in numeric order, + * s0, s1, ... in increasing address order. + */ + + vstmia r1!, {s0-s31} /* Save the full FP context */ + + /* Store the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + vmrs r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ + bx lr + + .size up_savefpu, .-up_savefpu +#endif /* CONFIG_ARCH_FPU */ + .end diff --git a/arch/arm/src/armv7-a/arm_saveusercontext.S b/arch/arm/src/armv7-a/arm_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..67b0ccdcb30694c9de07af49acef45a7690b68ab --- /dev/null +++ b/arch/arm/src/armv7-a/arm_saveusercontext.S @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_saveusercontext.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "up_internal.h" + + .file "arm_saveusercontext.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_saveusercontext + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: up_saveusercontext + ****************************************************************************/ + + .globl up_saveusercontext + .type up_saveusercontext, function + +up_saveusercontext: + + /* On entry, a1 (r0) holds address of struct xcptcontext */ + + /* Make sure that the return value will be non-zero (the value of the + * other volatile registers don't matter -- r1-r3, ip). This function + * is called through the normal C calling conventions and the values of + * these registers cannot be assumed at the point of setjmp return. + */ + + mov ip, #1 + str ip, [r0, #(4*REG_R0)] + + /* Save the volatile registers (plus r12 which really + * doesn't need to be saved) + */ + + add r1, r0, #(4*REG_R4) + stmia r1, {r4-r14} + + /* Save the current cpsr */ + + mrs r2, cpsr /* R3 = CPSR value */ + add r1, r0, #(4*REG_CPSR) + str r2, [r1] + + /* Save the return address as the PC so that we return to the exit from + * this function. + */ + + add r1, r0, #(4*REG_PC) + str lr, [r1] + + /* Save the floating point registers. + * REVISIT: Not all of the floating point registers need to be saved. + * Some are volatile and need not be preserved across functions calls. + * But right now, I can't find the definitive list of the volatile + * floating point registers. + */ + +#ifdef CONFIG_ARCH_FPU + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Store all floating point registers. Registers are stored in numeric order, + * s0, s1, ... in increasing address order. + */ + + vstmia r1!, {s0-s31} /* Save the full FP context */ + + /* Store the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + vmrs r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ +#endif + + /* Return 0 now indicating that this return is not a context switch */ + + mov r0, #0 /* Return value == 0 */ + mov pc, lr /* Return */ + .size up_saveusercontext, . - up_saveusercontext + .end diff --git a/arch/arm/src/armv7-a/arm_schedulesigaction.c b/arch/arm/src/armv7-a/arm_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..e8db2d35f45693bfa6287dbbedacbe0c44f8c4ca --- /dev/null +++ b/arch/arm/src/armv7-a/arm_schedulesigaction.c @@ -0,0 +1,204 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_schedulesigaction.c + * + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm.h" +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'sigdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + sdbg("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!CURRENT_REGS) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted + * task is the same as the one that must receive the signal, then + * we will have to modify the return state as well as the state + * in the TCB. + * + * Hmmm... there looks like a latent bug here: The following logic + * would fail in the strange case where we are in an interrupt + * handler, the thread is signalling itself, but a context switch + * to another task has occurred so that CURRENT_REGS does not + * refer to the thread of this_task()! + */ + + else + { + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = CURRENT_REGS[REG_PC]; + tcb->xcp.saved_cpsr = CURRENT_REGS[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver; + CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT); + + /* And make sure that the saved context in the TCB is the same + * as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an + * interrupt handler or (2) we are not in an interrupt handler and the + * running task is signalling some non-running task. + */ + + else + { + /* Save the return lr and cpsr and one scratch register. These + * will be restored by the signal trampoline after the signals + * have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-a/arm_sigdeliver.c b/arch/arm/src/armv7-a/arm_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..32f1e0b40d1219f98a282c6ca98fa5c7070bcc6a --- /dev/null +++ b/arch/arm/src/armv7-a/arm_sigdeliver.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_sigdeliver.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copyfullstate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_CPSR] = rtcb->xcp.saved_cpsr; + + /* Get a local copy of the sigdeliver function pointer. we do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_CPSR]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-a/arm_signal_dispatch.c b/arch/arm/src/armv7-a/arm_signal_dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..3e4f90b6e9b54f7b76f8249aac3b11c17f755c48 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_signal_dispatch.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_signal_dispatch.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "svcall.h" +#include "pgalloc.h" +#include "up_internal.h" + +#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ + defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_dispatch + * + * Description: + * In this kernel mode build, this function will be called to execute a + * a signal handler in user-space. When the signal is delivered, a + * kernel-mode stub will first run to perform some housekeeping functions. + * This kernel-mode stub will then be called transfer control to the user + * mode signal handler by calling this function. + * + * Normally the a user-mode signalling handling stub will also execute + * before the ultimate signal handler is called. See + * arch/arm/src/armv[6\7]/up_signal_handler. This function is the + * user-space, signal handler trampoline function. It is called from + * up_signal_dispatch() in user-mode. + * + * Inputs: + * sighand - The address user-space signal handling function + * signo, info, and ucontext - Standard arguments to be passed to the + * signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via an architecture specific system call made by up_signal_handler(). + * However, this will look like a normal return by the caller of + * up_signal_dispatch. + * + ****************************************************************************/ + +void up_signal_dispatch(_sa_sigaction_t sighand, int signo, + FAR siginfo_t *info, FAR void *ucontext) +{ + /* We are signalling a user group, but does the signal handler lie in the + * user address space? Or the kernel address space? The OS does + * intercept some signals for its own purpose (such as the death-of-child + * signal. + */ + + if (arm_uservaddr((uintptr_t)sighand)) + { + /* Yes.. Let sys_call4() do all of the work to get us into user space */ + + (void)sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo, + (uintptr_t)info, (uintptr_t)ucontext); + } + else + { + /* No.. we are already in kernel mode so just call the handler */ + + sighand(signo, info, ucontext); + } +} + +#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c new file mode 100644 index 0000000000000000000000000000000000000000..4b73c1e5e38cb3908ec7073ba705184ce27ecfb2 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -0,0 +1,534 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_syscall.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm.h" +#include "svcall.h" +#include "addrenv.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ + +#if defined(CONFIG_DEBUG_SYSCALL) +# define svcdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define svcdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: + * + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 + * + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * WARNING: There are hard-coded values in this logic! + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ + __asm__ __volatile__ + ( + " sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ + " str lr, [sp, #12]\n" /* Save lr in the stack frame */ + " ldr ip, =g_stublookup\n" /* R12=The base of the stub lookup table */ + " ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this SYSCALL */ + " blx ip\n" /* Call the stub (modifies lr) */ + " ldr lr, [sp, #12]\n" /* Restore lr */ + " add sp, sp, #16\n" /* Destroy the stack frame */ + " mov r2, r0\n" /* R2=Save return value in R2 */ + " mov r0, #0\n" /* R0=SYS_syscall_return */ + " svc #0x900001\n" /* Return from the SYSCALL */ + ); +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_syscall + * + * Description: + * SVC interrupts will vector here with insn=the SVC instruction and + * xcp=the interrupt context + * + * The handler may get the SVC number be de-referencing the return + * address saved in the xcp and decoding the SVC instruction + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +uint32_t *arm_syscall(uint32_t *regs) +{ + uint32_t cmd; +#ifdef CONFIG_BUILD_KERNEL + uint32_t cpsr; +#endif + + /* Nested interrupts are not supported */ + + DEBUGASSERT(regs); + + /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ + + cmd = regs[REG_R0]; + + /* The SVCall software interrupt is called with R0 = system call command + * and R1..R7 = variable number of arguments depending on the system call. + */ + +#if defined(CONFIG_DEBUG_SYSCALL) + svcdbg("SYSCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + svcdbg("CPSR: %08x\n", regs[REG_CPSR]); +#endif + + /* Handle the SVCall according to the command in R0 */ + + switch (cmd) + { + /* R0=SYS_syscall_return: This a SYSCALL return command: + * + * void up_syscall_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + + case SYS_syscall_return: + { + FAR struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved SYSCALL return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved SYSCALL return address in + * the original mode. + */ + + regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn; +#ifdef CONFIG_BUILD_KERNEL + regs[REG_CPSR] = rtcb->xcp.syscall[index].cpsr; +#endif + /* The return value must be in R0-R1. dispatch_syscall() temporarily + * moved the value for R0 into R2. + */ + + regs[REG_R0] = regs[REG_R2]; + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If this is the outermost SYSCALL and if there is a saved user stack + * pointer, then restore the user stack pointer on this final return to + * user code. + */ + + if (index == 0 && rtcb->xcp.ustkptr != NULL) + { + regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr; + rtcb->xcp.ustkptr = NULL; + } +#endif + /* Save the new SYSCALL nesting level */ + + rtcb->xcp.nsyscalls = index; + } + break; + + /* R0=SYS_context_restore: Restore task context + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_context_restore + * R1 = restoreregs + */ + +#ifdef CONFIG_BUILD_KERNEL + case SYS_context_restore: + { + /* Replace 'regs' with the pointer to the register set in + * regs[REG_R1]. On return from the system call, that register + * set will determine the restored context. + */ + + regs = (uint32_t *)regs[REG_R1]; + DEBUGASSERT(regs); + } + break; +#endif + + /* R0=SYS_task_start: This a user task start + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_task_start + * R1 = taskentry + * R2 = argc + * R3 = argv + */ + +#ifdef CONFIG_BUILD_KERNEL + case SYS_task_start: + { + /* Set up to return to the user-space _start function in + * unprivileged mode. We need: + * + * R0 = argc + * R1 = argv + * PC = taskentry + * CSPR = user mode + */ + + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; + regs[REG_R1] = regs[REG_R3]; + + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + } + break; +#endif + + /* R0=SYS_pthread_start: This a user pthread start + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_pthread_start + * R1 = entrypt + * R2 = arg + */ + +#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_PTHREAD) + case SYS_pthread_start: + { + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. We need: + * + * R0 = arg + * PC = entrypt + * CSPR = user mode + */ + + + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; + + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + } + break; +#endif + +#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS) + /* R0=SYS_signal_handler: This a user signal handler callback + * + * void signal_handler(_sa_sigaction_t sighand, int signo, + * FAR siginfo_t *info, FAR void *ucontext); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler + * R1 = sighand + * R2 = signo + * R3 = info + * ucontext (on the stack) + */ + + case SYS_signal_handler: + { + FAR struct tcb_s *rtcb = sched_self(); + /* Remember the caller's return address */ + + DEBUGASSERT(rtcb->xcp.sigreturn == 0); + rtcb->xcp.sigreturn = regs[REG_PC]; + + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)ARCH_DATA_RESERVE->ar_sigtramp; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s signal_handler. + */ + + regs[REG_R0] = regs[REG_R1]; /* sighand */ + regs[REG_R1] = regs[REG_R2]; /* signal */ + regs[REG_R2] = regs[REG_R3]; /* info */ + + /* The last parameter, ucontext, is trickier. The ucontext + * parameter will reside at an offset of 4 from the stack pointer. + */ + + regs[REG_R3] = *(uint32_t *)(regs[REG_SP]+4); + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If we are signalling a user process, then we must be operating + * on the kernel stack now. We need to switch back to the user + * stack before dispatching the signal handler to the user code. + * The existence of an allocated kernel stack is sufficient + * information to make this decision. + */ + + if (rtcb->xcp.kstack != NULL) + { + DEBUGASSERT(rtcb->xcp.kstkptr == NULL && rtcb->xcp.ustkptr != NULL); + + rtcb->xcp.kstkptr = (FAR uint32_t *)regs[REG_SP]; + regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr; + } +#endif + } + break; +#endif + +#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS) + /* R0=SYS_signal_handler_return: This a user signal handler callback + * + * void signal_handler_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler_return + */ + + case SYS_signal_handler_return: + { + FAR struct tcb_s *rtcb = sched_self(); + + /* Set up to return to the kernel-mode signal dispatching logic. */ + + DEBUGASSERT(rtcb->xcp.sigreturn != 0); + + regs[REG_PC] = rtcb->xcp.sigreturn; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; + rtcb->xcp.sigreturn = 0; + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* We must enter here be using the user stack. We need to switch + * to back to the kernel user stack before returning to the kernel + * mode signal trampoline. + */ + + if (rtcb->xcp.kstack != NULL) + { + DEBUGASSERT(rtcb->xcp.kstkptr != NULL && + (uint32_t)rtcb->xcp.ustkptr == regs[REG_SP]); + + regs[REG_SP] = (uint32_t)rtcb->xcp.kstkptr; + rtcb->xcp.kstkptr = NULL; + } +#endif + } + break; +#endif + + /* This is not an architecture-specific system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_LIB_SYSCALL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall); + + /* Make sure that there is a no saved SYSCALL return address. We + * cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcp.syscall[index].sysreturn = regs[REG_PC]; +#ifdef CONFIG_BUILD_KERNEL + rtcb->xcp.syscall[index].cpsr = regs[REG_CPSR]; +#endif + + regs[REG_PC] = (uint32_t)dispatch_syscall; +#ifdef CONFIG_BUILD_KERNEL + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; +#endif + /* Offset R0 to account for the reserved values */ + + regs[REG_R0] -= CONFIG_SYS_RESERVED; +#else + svcdbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]); +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If this is the first SYSCALL and if there is an allocated + * kernel stack, then switch to the kernel stack. + */ + + if (index == 0 && rtcb->xcp.kstack != NULL) + { + rtcb->xcp.ustkptr = (FAR uint32_t *)regs[REG_SP]; + regs[REG_SP] = (uint32_t)rtcb->xcp.kstack + ARCH_KERNEL_STACKSIZE; + } +#endif + /* Save the new SYSCALL nesting level */ + + rtcb->xcp.nsyscalls = index + 1; + } + break; + } + +#if defined(CONFIG_DEBUG_SYSCALL) + /* Report what happened */ + + svcdbg("SYSCALL Exit: regs: %p\n", regs); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + svcdbg("CPSR: %08x\n", regs[REG_CPSR]); +#endif + + /* Return the last value of curent_regs. This supports context switches + * on return from the exception. That capability is only used with the + * SYS_context_switch system call. + */ + + return regs; +} + +#else + +uint32_t *arm_syscall(uint32_t *regs) +{ + lldbg("SYSCALL from 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); +} + +#endif diff --git a/arch/arm/src/armv7-a/arm_testset.S b/arch/arm/src/armv7-a/arm_testset.S new file mode 100644 index 0000000000000000000000000000000000000000..6d6cdcd4acb78859f48730a62024408df1df53de --- /dev/null +++ b/arch/arm/src/armv7-a/arm_testset.S @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_testset.S + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + + .file "arm_testset.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_testset + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + + .globl up_testset + .type up_testset, %function + +up_testset: + + mov r1, #SP_LOCKED + + /* Test if the spinlock is locked or not */ + +1: + ldrexb r2, [r0] /* Test if spinlock is locked or not */ + cmp r2, r1 /* Already locked? */ + beq 2f /* If alrady locked, return SP_LOCKED */ + + /* Not locked ... attempt to lock it */ + + strexb r2, r1, [r0] /* Attempt to set the locked state */ + cmp r2, r1 /* r2 will be 1 is strexb failed */ + beq 1b /* Failed to lock... try again */ + + /* Lock acquired -- return SP_UNLOCKED */ + + dmb /* Required before accessing protected resource */ + mov r0, #SP_UNLOCKED + bx lr + + /* Lock not acquired -- return SP_LOCKED */ + +2: + mov r0, #SP_LOCKED + bx lr + .size up_testset, . - up_testset + .end diff --git a/arch/arm/src/armv7-a/arm_unblocktask.c b/arch/arm/src/armv7-a/arm_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..173ca913222711daacfd09cc57cb8b6fa050c7f2 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_unblocktask.c @@ -0,0 +1,171 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_unblocktask.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-a/arm_undefinedinsn.c b/arch/arm/src/armv7-a/arm_undefinedinsn.c new file mode 100644 index 0000000000000000000000000000000000000000..bc08375594cba59d9ccbd480b501a57cf08dcbd9 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_undefinedinsn.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_undefinedinsn.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_undefinedinsn + ****************************************************************************/ + +uint32_t *arm_undefinedinsn(uint32_t *regs) +{ + lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); + return regs; /* To keep the compiler happy */ +} diff --git a/arch/arm/src/armv7-a/arm_va2pte.c b/arch/arm/src/armv7-a/arm_va2pte.c new file mode 100644 index 0000000000000000000000000000000000000000..ded054187e3e817c688ba48cfdcbaa67f4ab8777 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_va2pte.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_va2pte.c + * Utility to map a virtual address to a L2 page table entry. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "pg_macros.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_va2pte + * + * Description: + * Convert a virtual address within the paged text region into a pointer to + * the corresponding page table entry. + * + * Input Parameters: + * vaddr - The virtual address within the paged text region. + * + * Returned Value: + * A pointer to the corresponding page table entry. + * + * Assumptions: + * - This function is called from the normal tasking context (but with + * interrupts disabled). The implementation must take whatever actions + * are necessary to assure that the operation is safe within this + * context. + * + ****************************************************************************/ + +uint32_t *arm_va2pte(uintptr_t vaddr) +{ + uint32_t L1; + uint32_t *L2; + unsigned int ndx; + + /* The virtual address is expected to lie in the paged text region */ + + DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND); + + /* Get the L1 table entry associated with this virtual address */ + + L1 = *(uint32_t *)PG_POOL_VA2L1VADDR(vaddr); + + /* Get the address of the L2 page table from the L1 entry */ + + L2 = (uint32_t *)PG_POOL_L12VPTABLE(L1); + + /* Get the index into the L2 page table. Each L1 entry maps + * 256 x 4Kb or 1024 x 1Kb pages. + */ + + ndx = (vaddr & 0x000fffff) >> PAGESHIFT; + + /* Return true if this virtual address is mapped. */ + + return &L2[ndx]; +} + +#endif /* CONFIG_PAGING */ diff --git a/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S b/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S new file mode 100644 index 0000000000000000000000000000000000000000..14a42908192a686653494aff8972ea77df4bceca --- /dev/null +++ b/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_vectoraddrexceptn.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "up_arch.h" + + .file "arm_vectoraddrexcptn.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl arm_vectoraddrexcption + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: arm_vectoraddrexcption + * + * Description: + * Shouldn't happen. This exception handler is in a separate file from + * other vector handlers because some processors (e.g., Cortex-A5) do not + * support the Address Exception vector. + * + ****************************************************************************/ + + .globl arm_vectoraddrexcptn + .type arm_vectoraddrexcptn, %function +arm_vectoraddrexcptn: + b arm_vectoraddrexcptn + .size arm_vectoraddrexcptn, . - arm_vectoraddrexcptn + .end diff --git a/arch/arm/src/armv7-a/arm_vectors.S b/arch/arm/src/armv7-a/arm_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..5699a449fdaddd60bd424425d0ba78f8936c5ba8 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_vectors.S @@ -0,0 +1,977 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/arm_vectors.S + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "arm.h" +#include "cp15.h" + + .file "arm_vectors.S" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + + .data +g_irqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_undeftmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_aborttmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +#ifdef CONFIG_ARMV7A_DECODEFIQ +g_fiqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +#endif + +/************************************************************************************ + * Assembly Macros + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: arm_vectorirq + * + * Description: + * Interrupt exception. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl arm_decodeirq + .globl arm_vectorirq + .type arm_vectorirq, %function + +arm_vectorirq: + /* On entry, we are in IRQ mode. We are free to use the IRQ mode r13 + * and r14. + */ + + ldr r13, .Lirqtmp + sub lr, lr, #4 + str lr, [r13] /* Save lr_IRQ */ + mrs lr, spsr + str lr, [r13, #4] /* Save spsr_IRQ */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ +#ifdef CONFIG_ARMV7A_DECODEFIQ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) +#else + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT) +#endif + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lirqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lirqentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lirqcontinue + +.Lirqentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lirqcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the IRQ handler with interrupts disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lirqstackbase /* SP = interrupt stack base */ + str r0, [sp] /* Save the user stack pointer */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodeirq /* Call the handler */ + ldr sp, [r4] /* Restore the user stack pointer */ +#else + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodeirq /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ +#endif + + /* Upon return from arm_decodeirq, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_decodeirq: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lirqleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lirqleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lirqtmp: + .word g_irqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lirqstackbase: + .word g_intstackbase +#endif + .size arm_vectorirq, . - arm_vectorirq + .align 5 + +/************************************************************************************ + * Function: arm_vectorsvc + * + * Description: + * SVC interrupt. We enter the SVC in SVC mode. + * + ************************************************************************************/ + + .globl arm_syscall + .globl arm_vectorsvc + .type arm_vectorsvc, %function + +arm_vectorsvc: + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + mov r3, r14 /* Save r14 as the PC as well */ + mrs r4, spsr /* Get the saved CPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lsvcentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lsvccontinue + +.Lsvcentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lsvccontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the SVC handler with interrupts disabled. + * void arm_syscall(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_syscall /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_syscall, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_syscall: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lleavesvcsvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lleavesvcsvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + + .size arm_vectorsvc, . - arm_vectorsvc + + .align 5 + +/************************************************************************************ + * Name: arm_vectordata + * + * Description: + * This is the data abort exception dispatcher. The ARM data abort exception occurs + * when a memory fault is detected during a data transfer. This handler saves the + * current processor state and gives control to data abort handler. This function + * is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl arm_dataabort + .globl arm_vectordata + .type arm_vectordata, %function + +arm_vectordata: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Ldaborttmp /* Points to temp storage */ + sub lr, lr, #8 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Ldaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Ldabtentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Ldabtcontinue + +.Ldabtentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Ldabtcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the data abort handler with interrupts disabled. + * void arm_dataabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mrc CP15_DFAR(r1) /* Get R1=DFAR */ + mrc CP15_DFSR(r2) /* Get r2=DFSR */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_dataabort /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_dataabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_dataabort: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Ldabtleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Ldabtleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r1-r15}^ /* Return */ + +.Ldaborttmp: + .word g_aborttmp + .size arm_vectordata, . - arm_vectordata + + .align 5 + +/************************************************************************************ + * Name: arm_vectorprefetch + * + * Description: + * This is the prefetch abort exception dispatcher. The ARM prefetch abort exception + * occurs when a memory fault is detected during an an instruction fetch. This + * handler saves the current processor state and gives control to prefetch abort + * handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC. + * + ************************************************************************************/ + + .globl arm_prefetchabort + .globl arm_vectorprefetch + .type arm_vectorprefetch, %function + +arm_vectorprefetch: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Lpaborttmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lpaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lpabtentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lpabtcontinue + +.Lpabtentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lpabtcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the prefetch abort handler with interrupts disabled. + * void arm_prefetchabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mrc CP15_IFAR(r1) /* Get R1=IFAR */ + mrc CP15_IFSR(r2) /* Get r2=IFSR */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_prefetchabort /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_prefetchabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_prefetchabort: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lpabtleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lpabtleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lpaborttmp: + .word g_aborttmp + .size arm_vectorprefetch, . - arm_vectorprefetch + + .align 5 + +/************************************************************************************ + * Name: arm_vectorundefinsn + * + * Description: + * Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR, + * lr = SVC PC + * + ************************************************************************************/ + + .globl arm_undefinedinsn + .globl arm_vectorundefinsn + .type arm_vectorundefinsn, %function + +arm_vectorundefinsn: + /* On entry we are free to use the UND mode registers + * r13 and r14 + */ + + ldr r13, .Lundeftmp /* Points to temp storage */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lundeftmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_UND, r4=spsr_UND */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lundefentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lundefcontinue + +.Lundefentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lundefcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the undef insn handler with interrupts disabled. + * void arm_undefinedinsn(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_undefinedinsn /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_undefinedinsn, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_undefinedinsn: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lundefleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lundefleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lundeftmp: + .word g_undeftmp + .size arm_vectorundefinsn, . - arm_vectorundefinsn + + .align 5 + +/************************************************************************************ + * Name: arm_vectorfiq + * + * Description: + * Shouldn't happen unless a arm_decodefiq() is provided. FIQ is primarily used + * with the TrustZone feature in order to handle secure interrupts. + * + ************************************************************************************/ + +#ifdef CONFIG_ARMV7A_DECODEFIQ + .globl arm_decodefiq +#endif + .globl arm_vectorfiq + .type arm_vectorfiq, %function + +arm_vectorfiq: +#ifdef CONFIG_ARMV7A_DECODEFIQ + /* On entry we are free to use the FIQ mode registers r8 through r14 */ + + ldr r13, .Lfiqtmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR_fiq */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lfiqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_SVC, r4=spsr_SVC */ + +#ifdef CONFIG_BUILD_KERNEL + /* Did we enter from user mode? If so then we need get the values of + * USER mode rr13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lfiqentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lfiqcontinue + +.Lfiqentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lfiqcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the FIQ handler with interrupts disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lfiqstackbase /* SP = interrupt stack base */ + str r0, [sp] /* Save the user stack pointer */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodefiq /* Call the handler */ + ldr sp, [r4] /* Restore the user stack pointer */ +#else + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodefiq /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ +#endif + + /* Upon return from arm_decodefiq, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_decodefiq: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_KERNEL + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lfiqleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lfiqleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lfiqtmp: + .word g_fiqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lfiqstackbase: + .word g_intstackbase +#endif + +#else + subs pc, lr, #4 +#endif + .size arm_vectorfiq, . - arm_vectorfiq + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + + .globl g_intstackalloc + .type g_intstackalloc, object + .globl g_intstackbase + .type g_intstackbase, object + +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) +g_intstackbase: + .skip 4 + .size g_intstackbase, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) + +#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */ + .end diff --git a/arch/arm/src/armv7-a/arm_vectortab.S b/arch/arm/src/armv7-a/arm_vectortab.S new file mode 100644 index 0000000000000000000000000000000000000000..5f3c54754b7871cb758c7f98eb2c1c237f9a9cc7 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_vectortab.S @@ -0,0 +1,110 @@ +/**************************************************************************** + * arch/arm/src/arm7-a/arm_vectortab.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + + .file "arm_vectortab.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl _vector_start + .globl _vector_end + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Name: _vector_start + * + * Description: + * Vector initialization block + ****************************************************************************/ + + .section .vectors, "ax" + .globl _vector_start + +/* These will be relocated to VECTOR_BASE. */ + +_vector_start: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lsvchandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl arm_vectorundefinsn + .globl arm_vectorsvc + .globl arm_vectorprefetch + .globl arm_vectordata + .globl arm_vectoraddrexcptn + .globl arm_vectorirq + .globl arm_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long arm_vectorundefinsn +.Lsvchandler: + .long arm_vectorsvc +.Lprefetchaborthandler: + .long arm_vectorprefetch +.Ldataaborthandler: + .long arm_vectordata +.Laddrexcptnhandler: + .long arm_vectoraddrexcptn +.Lirqhandler: + .long arm_vectorirq +.Lfiqhandler: + .long arm_vectorfiq + + .globl _vector_end +_vector_end: + .size _vector_start, . - _vector_start + .end diff --git a/arch/arm/src/armv7-a/arm_vfork.S b/arch/arm/src/armv7-a/arm_vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..b7abc1c0f22a306161c9b7fa3f133510370e5857 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_vfork.S @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_vfork.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_vfork.h" + + .file "vfork.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_vfork + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the + * behavior is undefined if the process created by vfork() either modifies + * any data other than a variable of type pid_t used to store the return + * value from vfork(), or returns from the function in which vfork() was + * called, or calls any other function before successfully calling _exit() + * or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the + * vfork() context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. + * This consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and + * returns the process ID of the child process to the parent process. + * Otherwise, -1 is returned to the parent, no child process is created, + * and errno is set to indicate the error. + * + ****************************************************************************/ + + .globl vfork + .type vfork, function +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + str r4, [sp, #VFORK_R4_OFFSET] + str r5, [sp, #VFORK_R5_OFFSET] + str r6, [sp, #VFORK_R6_OFFSET] + str r7, [sp, #VFORK_R7_OFFSET] + str r8, [sp, #VFORK_R8_OFFSET] + str r9, [sp, #VFORK_R9_OFFSET] + str r10, [sp, #VFORK_R10_OFFSET] + + /* Save the frame pointer, stack pointer, and return address */ + + str fp, [sp, #VFORK_FP_OFFSET] + str r0, [sp, #VFORK_SP_OFFSET] + str lr, [sp, #VFORK_LR_OFFSET] + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Release the stack data and return the value returned by up_vfork */ + + ldr lr, [sp, #VFORK_LR_OFFSET] + add sp, sp, #VFORK_SIZEOF + mov pc, lr + .size vfork, .-vfork + .end diff --git a/arch/arm/src/armv7-a/arm_virtpgaddr.c b/arch/arm/src/armv7-a/arm_virtpgaddr.c new file mode 100644 index 0000000000000000000000000000000000000000..741bf8d122747577e3cff99670ba78dbd81f3e10 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_virtpgaddr.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_virtpgaddr.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pgalloc.h" + +#if defined(CONFIG_MM_PGALLOC) && defined(CONFIG_ARCH_PGPOOL_MAPPING) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_virtpgaddr + * + * Description: + * Check if the physical address lies in the page pool and, if so + * get the mapping to the virtual address in the user data area. + * + ****************************************************************************/ + +uintptr_t arm_virtpgaddr(uintptr_t paddr) +{ + /* REVISIT: Not implemented correctly. The reverse lookup from physical + * to virtual. This will return a kernel accessible virtual address, but + * not an address usable by the user code. + * + * The correct solutions is complex and, perhaps, will never be needed. + */ + + if (paddr >= CONFIG_ARCH_PGPOOL_PBASE && paddr < CONFIG_ARCH_PGPOOL_PEND) + { + return paddr - CONFIG_ARCH_PGPOOL_PBASE + CONFIG_ARCH_PGPOOL_VBASE; + } + + return 0; +} + +#endif /* CONFIG_MM_PGALLOC && CONFIG_ARCH_PGPOOL_MAPPING */ diff --git a/arch/arm/src/armv7-a/cache.h b/arch/arm/src/armv7-a/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..dda36271e2d865a5e2533e9201feea5952fc9845 --- /dev/null +++ b/arch/arm/src/armv7-a/cache.h @@ -0,0 +1,208 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/cache.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_CACHE_H +#define __ARCH_ARM_SRC_ARMV7_A_CACHE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "cp15_cacheops.h" +#include "l2cc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + + /************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: arch_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_invalidate_dcache(uintptr_t start, uintptr_t end) +{ + cp15_invalidate_dcache(start, end); + l2cc_invalidate(start, end); +} + +/**************************************************************************** + * Name: arch_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * NOTE: This function forces L1 and L2 cache operations to be atomic + * by disabling interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_invalidate_dcache_all(void) +{ +#ifdef CONFIG_ARCH_L2CACHE + irqstate_t flags = enter_critical_section(); + cp15_invalidate_dcache_all(); + l2cc_invalidate_all(); + leave_critical_section(flags); +#else + cp15_invalidate_dcache_all(); +#endif +} + +/************************************************************************************ + * Name: arch_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#define arch_invalidate_icache() cp15_invalidate_icache() + +/**************************************************************************** + * Name: arch_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_clean_dcache(uintptr_t start, uintptr_t end) +{ + cp15_clean_dcache(start, end); + l2cc_clean(start, end); +} + +/**************************************************************************** + * Name: arch_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_flush_dcache(uintptr_t start, uintptr_t end) +{ + cp15_flush_dcache(start, end); + l2cc_flush(start, end); +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_CACHE_H */ diff --git a/arch/arm/src/armv7-a/cp15.h b/arch/arm/src/armv7-a/cp15.h new file mode 100644 index 0000000000000000000000000000000000000000..8da017b419b7531b821f6301681cd60e166f4e31 --- /dev/null +++ b/arch/arm/src/armv7-a/cp15.h @@ -0,0 +1,215 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/cp15.h + * CP15 register access + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 + * ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_CP15_H +#define __ARCH_ARM_SRC_ARMV7_A_CP15_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* System control register descriptions. + * + * CP15 registers are accessed with MRC and MCR instructions as follows: + * + * MRC p15, , , , , ; Read CP15 Register + * MCR p15, , , , , ; Write CP15 Register + * + * Where + * + * is the Opcode_1 value for the register + * is a general purpose register + * is the register number within CP15 + * is the operational register + * is the Opcode_2 value for the register. + * + * Reference: Cortex-A5™ MPCore, Technical Reference Manual, Paragraph 4.2. + */ + +#define _CP15(op1,rd,crn,crm,op2) p15, op1, rd, crn, crm, op2 + +#define CP15_MIDR(r) _CP15(0, r, c0, c0, 0) /* Main ID Register */ +#define CP15_CTR(r) _CP15(0, r, c0, c0, 1) /* Cache Type Register */ +#define CP15_TCMTR(r) _CP15(0, r, c0, c0, 2) /* TCM Type Register */ +#define CP15_TLBTR(r) _CP15(0, r, c0, c0, 3) /* TLB Type Register */ +#define CP15_MPIDR(r) _CP15(0, r, c0, c0, 5) /* Multiprocessor Affinity Register */ +#define CP15_REVIDR(r) _CP15(0, r, c0, c0, 6) /* Revision ID register (Cortex-A9) */ +#define CP15_MID_PFR0(r) _CP15(0, r, c0, c1, 0) /* Processor Feature Register 0 */ +#define CP15_MID_PFR1(r) _CP15(0, r, c0, c1, 1) /* Processor Feature Register 1 */ +#define CP15_MID_DFR0(r) _CP15(0, r, c0, c1, 2) /* Debug Feature Register 0 */ +#define CP15_MID_AFR0(r) _CP15(0, r, c0, c1, 3) /* Auxiliary Feature Register 0 (Cortex-A9) */ +#define CP15_MID_MMFR0(r) _CP15(0, r, c0, c1, 4) /* Memory Model Features Register 0 */ +#define CP15_MID_MMFR1(r) _CP15(0, r, c0, c1, 5) /* Memory Model Features Register 1 */ +#define CP15_MID_MMFR2(r) _CP15(0, r, c0, c1, 6) /* Memory Model Features Register 2 */ +#define CP15_MID_MMFR3(r) _CP15(0, r, c0, c1, 7) /* Memory Model Features Register 3 */ +#define CP15_ID_ISAR0(r) _CP15(0, r, c0, c2, 0) /* Instruction Set Attributes Register 0 */ +#define CP15_ID_ISAR1(r) _CP15(0, r, c0, c2, 1) /* Instruction Set Attributes Register 1 */ +#define CP15_ID_ISAR2(r) _CP15(0, r, c0, c2, 2) /* Instruction Set Attributes Register 2 */ +#define CP15_ID_ISAR3(r) _CP15(0, r, c0, c2, 3) /* Instruction Set Attributes Register 3 */ +#define CP15_ID_ISAR4(r) _CP15(0, r, c0, c2, 4) /* Instruction Set Attributes Register 4 */ +#define CP15_ID_ISAR5(r) _CP15(0, r, c0, c2, 5) /* Instruction Set Attributes Register 5 (Cortex-A5) */ +#define CP15_CCSIDR(r) _CP15(1, r, c0, c0, 0) /* Cache Size Identification Register */ +#define CP15_CLIDR(r) _CP15(1, r, c0, c0, 1) /* Cache Level ID Register */ +#define CP15_AIDR(r) _CP15(1, r, c0, c0, 7) /* Auxiliary ID Register */ +#define CP15_CSSELR(r) _CP15(2, r, c0, c0, 0) /* Cache Size Selection Register */ + +#define CP15_SCTLR(r) _CP15(0, r, c1, c0, 0) /* System Control Register */ +#define CP15_ACTLR(r) _CP15(0, r, c1, c0, 1) /* Auxiliary Control Register */ +#define CP15_CPACR(r) _CP15(0, r, c1, c0, 2) /* Coprocessor Access Control Register */ +#define CP15_SCR(r) _CP15(0, r, c1, c1, 0) /* Secure Configuration Register */ +#define CP15_SDER(r) _CP15(0, r, c1, c1, 1) /* Secure Debug Enable Register */ +#define CP15_NSACR(r) _CP15(0, r, c1, c1, 2) /* Non-secure Access Control Register */ +#define CP15_VCR(r) _CP15(0, r, c1, c1, 3) /* Virtualization Control Register */ + +#define CP15_TTBR0(r) _CP15(0, r, c2, c0, 0) /* Translation Table Base Register 0 */ +#define CP15_TTBR1(r) _CP15(0, r, c2, c0, 1) /* Translation Table Base Register 1 */ +#define CP15_TTBCR(r) _CP15(0, r, c2, c0, 2) /* Translation Table Base Control Register */ + +#define CP15_DACR(r) _CP15(0, r, c3, c0, 0) /* Domain Access Control Register */ + +#define CP15_DFSR(r) _CP15(0, r, c5, c0, 0) /* Data Fault Status Register */ +#define CP15_IFSR(r) _CP15(0, r, c5, c0, 1) /* Instruction Fault Status Register */ +#define CP15_ADFSR(r) _CP15(0, r, c5, c1, 0) /* Auxiliary Data Fault Status Register */ +#define CP15_AIFSR(r) _CP15(0, r, c5, c1, 1) /* Auxiliary Instruction Fault Status Register */ + +#define CP15_DFAR(r) _CP15(0, r, c6, c0, 0) /* Data Fault Address Register */ +#define CP15_IFAR(r) _CP15(0, r, c6, c0, 2) /* Instruction Fault Address Register */ + +#define CP15_NOP(r) _CP15(0, r, c7, c0, 4) +#define CP15_ICIALLUIS(r) _CP15(0, r, c7, c1, 0) /* Cache Operations Registers */ +#define CP15_BPIALLIS(r) _CP15(0, r, c7, c1, 6) +#define CP15_PAR(r) _CP15(0, r, c7, c4, 0) /* Physical Address Register */ +#define CP15_ICIALLU(r) _CP15(0, r, c7, c5, 0) /* Cache Operations Registers */ +#define CP15_ICIMVAU(r) _CP15(0, r, c7, c5, 1) +#define CP15_ISB(r) _CP15(0, r, c7, c5, 4) +#define CP15_BPIALL(r) _CP15(0, r, c7, c5, 6) /* Cache Operations Registers */ +#define CP15_BPIMVA(r) _CP15(0, r, c7, c5, 7) /* Cortex-A5 */ +#define CP15_DCIMVAC(r) _CP15(0, r, c7, c6, 1) +#define CP15_DCISW(r) _CP15(0, r, c7, c6, 2) +#define CP15_V2PCWPR(r,n) _CP15(0, r, c7, c8, (n)) /* VA to PA operations, n=0-3 */ +# define CP15_V2PCWPR0(r) _CP15(0, r, c7, c8, 0) +# define CP15_V2PCWPR1(r) _CP15(0, r, c7, c8, 1) +# define CP15_V2PCWPR2(r) _CP15(0, r, c7, c8, 2) +# define CP15_V2PCWPR3(r) _CP15(0, r, c7, c8, 3) +#define CP15_V2POWPR(r,n) _CP15(0, r, c7, c8, ((n)+4)) /* n=0-3 */ +# define CP15_V2POWPR0(r) _CP15(0, r, c7, c8, 4) +# define CP15_V2POWPR1(r) _CP15(0, r, c7, c8, 5) +# define CP15_V2POWPR2(r) _CP15(0, r, c7, c8, 6) +# define CP15_V2POWPR3(r) _CP15(0, r, c7, c8, 7) +#define CP15_DCCMVAC(r) _CP15(0, r, c7, c10, 1) /* Cache Operations Registers (aka DCCVAC) */ +#define CP15_DCCSW(r) _CP15(0, r, c7, c10, 2) +#define CP15_DSB(r) _CP15(0, r, c7, c10, 4) +#define CP15_DMB(r) _CP15(0, r, c7, c10, 5) +#define CP15_DCCMVAU(r) _CP15(0, r, c7, c11, 1) /* Cache Operations Registers */ +#define CP15_DCCIMVAC(r) _CP15(0, r, c7, c14, 1) +#define CP15_DCCISW(r) _CP15(0, r, c7, c14, 2) + +#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* Invalidate entire unified TLB Inner Shareable */ +#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1) /* Invalidate unified TLB entry by MVA and ASID, Inner Shareable */ +#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2) /* Invalidate unified TLB by ASID match Inner Shareable */ +#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3) /* Invalidate unified TLB entry by MVA all ASID Inner Shareable */ +#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* Invalidate entire instruction TLB. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* Invalidate instruction TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ +#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* Invalidate data TLB by ASID match. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* Invalidate unified TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ + +#define CP15_PMCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */ +#define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */ +#define CP15_PMCNTENCLR(r) _CP15(0, r, c9, c12, 2) /* Count Enable Clear Register */ +#define CP15_PMOVSR(r) _CP15(0, r, c9, c12, 3) /* Overflow Flag Status Register */ +#define CP15_PMSWINC(r) _CP15(0, r, c9, c12, 4) /* Software Increment Register */ +#define CP15_PMSELR(r) _CP15(0, r, c9, c12, 5) /* Event Counter Selection Register */ +#define CP15_PMCEID0(r) _CP15(0, r, c9, c12, 6) /* Common Event Identification Registers (Cortex-A5) */ +#define CP15_PMCEID1(r) _CP15(0, r, c9, c12, 7) +#define CP15_PMCCNTR(r) _CP15(0, r, c9, c13, 0) /* Cycle Count Register */ +#define CP15_PMXEVTYPER(r) _CP15(0, r, c9, c13, 1) /* Event Type Select Register */ +#define CP15_PMCCFILTR(r) _CP15(0, r, c9, c13, 1) /* Cycle Count Filter Control Register */ +#define CP15_PMXEVCNTR(r) _CP15(0, r, c9, c13, 2) /* Event Count Registers (Cortex-A5) */ +#define CP15_PMUSERENR(r) _CP15(0, r, c9, c14, 0) /* User Enable Register */ +#define CP15_PMINTENSET(r) _CP15(0, r, c9, c14, 1) /* Interrupt Enable Set Register */ +#define CP15_PMINTENCLR(r) _CP15(0, r, c9, c14, 2) /* Interrupt Enable Clear Register */ + +#define CP15_TLBLCKDOWN(r) _CP15(0, r, c10, c0, 0) /* TLB Lockdown register (Cortex-A9) */ +#define CP15_PPRRR(r) _CP15(0, r, c10, c2, 0) /* Primary Region Remap Register */ +#define CP15_NMRR(r) _CP15(0, r, c10, c2, 1) /* Normal Memory Remap Register */ + +#define CP15_PLEIDR(r) _CP15(0, r, c11, c0, 0) /* PLE ID Register (Cortex-A9) */ +#define CP15_PLEASR(r) _CP15(0, r, c11, c0, 2) /* PLE Activity Status Register (Cortex-A9) */ +#define CP15_PLEFSR(r) _CP15(0, r, c11, c0, 4) /* PLE FIFO Status Register (Cortex-A9) */ +#define CP15_PLEUAR(r) _CP15(0, r, c11, c1, 0) /* Preload Engine User Accessibility Register (Cortex-A9) */ +#define CP15_PLEPCR(r) _CP15(0, r, c11, c1, 1) /* Preload Engine Parameters Control Register (Cortex-A9) */ + +#define CP15_VBAR(r) _CP15(0, r, c12, c0, 0) /* Vector Base Address Register */ +#define CP15_MVBAR(r) _CP15(0, r, c12, c0, 1) /* Monitor Vector Base Address Register */ +#define CP15_ISR(r) _CP15(0, r, c12, c1, 0) /* Interrupt Status Register */ +#define CP15_VIR(r) _CP15(0, r, c12, c1, 1) /* Virtualization Interrupt Register */ + +#define CP15_FCSEIDR(r) _CP15(0, r, c13, c0, 0) /* Fast Context Switch Extension (FCSE) not implemented */ +#define CP15_CONTEXTIDR(r) _CP15(0, r, c13, c0, 1) /* Context ID Register */ +#define CP15_TPIDRURW(r) _CP15(0, r, c13, c0, 2) /* Software Thread ID Registers */ +#define CP15_TPIDRURO(r) _CP15(0, r, c13, c0, 3) +#define CP15_TPIDRPRW(r) _CP15(0, r, c13, c0, 4) + +#define CP15_PWRCTRL(r) _CP15(0, r, c15, c0, 0) /* Power Control Register (Cortex-A9) */ +#define CP15_NEONBUSY(r) _CP15(0, r, c15, c1, 1) /* NEON Busy Register (Cortex-A9) */ +#define CP15_DR0(r) _CP15(3, r, c15, c0, 0) /* Data Register (Cortex-A5) */ +#define CP15_DR1(r) _CP15(3, r, c15, c0, 1) /* Data Register (Cortex-A5) */ +#define CP15_DTAGR(r) _CP15(3, r, c15, c2, 0) /* Data Cache Tag Read Operation Register (Cortex-A5) */ +#define CP15_ITAGR(r) _CP15(3, r, c15, c2, 1) /* Instruction Cache Tag Read Operation Register (Cortex-A5) */ +#define CP15_DDATAR(r) _CP15(3, r, c15, c4, 0) /* Data Cache Data Read Operation Register (Cortex-A5) */ +#define CP15_IDATAR(r) _CP15(3, r, c15, c4, 1) /* Instruction Cache Data Read Operation Register (Cortex-A5) */ +#define CP15_TLBR(r) _CP15(3, r, c15, c4, 2) /* TLB Data Read Operation Register (Cortex-A5) */ +#define CP15_CBADDR(r) _CP15(4, r, c15, c0, 0) /* Configuration Base Address Register */ +#define CP15_TLBHITMAP(r) _CP15(5, r, c15, c0, 0) /* TLB access and attributes (Cortex-A5) */ +#define CP15_RTLBLCKDWN(r) _CP15(5, r, c15, c4, 2) /* Select Lockdown TLB Entry for read (Cortex-A9) */ +#define CP15_WTLBLCKDWN(r) _CP15(5, r, c15, c4, 4) /* Select Lockdown TLB Entry for write (Cortex-A9) */ +#define CP15_MAINTLBVA(r) _CP15(5, r, c15, c5, 2) /* Main TLB VA register (Cortex-A9) */ +#define CP15_MAINTLBPA(r) _CP15(5, r, c15, c6, 2) /* Main TLB PA register (Cortex-A9) */ +#define CP15_MAINTLBAT(r) _CP15(5, r, c15, c7, 2) /* Main TLB Attribute register (Cortex-A9) */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_CP15_H */ diff --git a/arch/arm/src/armv7-a/cp15_cacheops.h b/arch/arm/src/armv7-a/cp15_cacheops.h new file mode 100644 index 0000000000000000000000000000000000000000..ce38540793984f4d0c831a63b397a25f648437bc --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_cacheops.h @@ -0,0 +1,991 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/cp15_cacheops.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 + * ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H +#define __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Cache definitions ****************************************************************/ +/* L1 Memory */ + +#define CP15_L1_LINESIZE 32 + +/* CP15 Registers *******************************************************************/ +/* Reference: Cortex-A5™ MPCore Paragraph 4.1.5, "Cache Operations Registers." + * + * Terms: + * 1) Point of coherency (PoC) + * The PoC is the point at which all agents that can access memory are guaranteed + * to see the same copy of a memory location + * 2) Point of unification (PoU) + * The PoU is the point by which the instruction and data caches and the + * translation table walks of the processor are guaranteed to see the same copy + * of a memory location. + * + * Cache Operations: + * + * CP15 Register: ICIALLUIS + * Description: Invalidate entire instruction cache Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 0 + * CP15 Register: BPIALLIS + * Description: Invalidate entire branch predictor array Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 6 + * CP15 Register: ICIALLU + * Description: Invalidate all instruction caches to PoU. Also flushes branch + * target cache. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 0 + * CP15 Register: ICIMVAU + * Description: Invalidate instruction cache by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c5, 1 + * CP15 Register: BPIALL + * Description: Invalidate entire branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 6 + * CP15 Register: BPIMVA + * Description: Invalidate VA from branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 7 + * CP15 Register: DCIMVAC + * Description: Invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c6, 1 + * CP15 Register: DCISW + * Description: Invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c6, 2 + * CP15 Register: DCCMVAC + * Description: Clean data cache line to PoC by VA. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c10, 1 + * CP15 Register: DCCSW + * Description: Clean data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c10, 2 + * CP15 Register: DCCMVAU + * Description: Clean data or unified cache line by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c11, 1 + * CP15 Register: DCCIMVAC + * Description: Clean and invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c14, 1 + * CP15 Register: DCCISW + * Description: Clean and invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c14, 2 + */ + +/* Set/way format */ + +#define CACHE_WAY_SHIFT (3) /* Bits 30-31: Way in set being accessed */ +#define CACHE_WAY_MASK (3 << CACHE_WAY_SHIFT) +#define CACHE_SET_SHIFT (5) /* Bits 5-(S+4): Way in set being accessed */ + /* For 4KB cache size: S=5 */ +#define CACHE_SET4KB_MASK (0x1f << CACHE_SET_SHIFT) + /* Bits 10-29: Reserved */ + /* For 8KB cache size: S=6 */ +#define CACHE_SET8KB_MASK (0x3f << CACHE_SET_SHIFT) + /* Bits 11-29: Reserved */ + /* For 16KB cache size: S=7 */ +#define CACHE_SET16KB_MASK (0x7f << CACHE_SET_SHIFT) + /* Bits 12-29: Reserved */ + /* For 32KB cache size: S=8 */ +#define CACHE_SET32KB_MASK (0xff << CACHE_SET_SHIFT) + /* Bits 13-29: Reserved */ + /* For 64KB cache size: S=9 */ +#define CACHE_SET64KB_MASK (0x1fff << CACHE_SET_SHIFT) + /* Bits 14-29: Reserved */ + +/* VA and SBZ format */ + +#define CACHE_SBZ_SHIFT (4) /* Bits 0-4: Should be zero (SBZ) */ +#define CACHE_SBZ_MASK (31 << TLB_SBZ_SHIFT) +#define CACHE_VA_MASK (0xfffffffe0) /* Bits 5-31: Virtual address */ + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ +/* cp15_cache Cache Operations + * + * Usage + * + * They are performed as MCR instructions and only operate on a level 1 cache + * associated with ARM v7 processor. + * + * The supported operations are: + * + * 1. Any of these operations can be applied to any data cache or any + * unified cache. + * 2. Invalidate by MVA. Performs an invalidate of a data or unified cache + * line + * based on the address it contains. + * 3. Invalidate by set/way. Performs an invalidate of a data or unified + * cache line based on its location in the cache hierarchy. + * 4. Clean by MVA. Performs a clean of a data or unified cache line based + * on the address it contains. + * 5. Clean by set/way. Performs a clean of a data or unified cache line + * based on its location in the cache hierarchy. + * 6. Clean and Invalidate by MVA. Performs a clean and invalidate of a + * data or unified cache line based on the address it contains. + * 7. Clean and Invalidate by set/way. Performs a clean and invalidate of + * a data or unified cache line based on its location in the cache + * hierarchy. + * + * NOTE: Many of these operations are implemented as assembly language + * macros or as C inline functions in the file cache.h. The larger functions + * are implemented here as C-callable functions. + */ + +#ifdef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_disable_dcache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ + .endm + +/************************************************************************************ + * Name: cp15_disable_caches + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_disable_caches, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 12) /* Disable I cache */ + bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 0 /* ICIALLUIS */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_btb_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 6 /* BPIALLIS */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 0 /* ICIALLU */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache_bymva, va + mrc p15, 0, \va, c7, c5, 1 /* ICIMVAU */ + .endm + +/************************************************************************************ + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_flush_btb, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 6 /* BPIALL */ + .endm + +/************************************************************************************ + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_flush_btb_bymva, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 7 /* BPIMVA */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c6, 1 /* DCIMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_dcacheline_bysetway, setway + mrc p15, 0, \setway, c7, c6, 2 /* DCISW */ + .endm + +/************************************************************************************ + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_dcache_bymva, va + mrc p15, 0, \va, c7, c10, 1 /* DCCMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_dcache_bysetway, setway + mrc p15, 0, \setway, c7, c10, 2 /* DCCSW */ + .endm + +/************************************************************************************ + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_ucache_bymva, setway + mrc p15, 0, \setway, c7, c11, 1 /* DCCMVAU */ + .endm + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_cleaninvalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c14, 1 /* DCCIMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_cleaninvalidate_dcacheline, setway + mrc p15, 0, \setway, c7, c14, 2 /* DCCISW */ + .endm + +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_disable_dcache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_disable_caches + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_disable_caches(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 12)\n" /* Disable I cache */ + "\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 0\n" /* ICIALLUIS */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_btb_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 6\n" /* BPIALLIS */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 0\n" /* ICIALLU */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c5, 1\n" /* ICIMVAU */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_flush_btb(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 6\n" /* BPIALL */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_flush_btb_bymva(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 7\n" /* BPIMVA */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Invalidate data cache line by VA to PoC */ + +static inline void cp15_invalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 1\n" /* DCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Invalidate data cache line by set/way */ + +static inline void cp15_invalidate_dcacheline_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 2\n" /* DCISW */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Clean data cache line by MVA */ + +static inline void cp15_clean_dcache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 1\n" /* DCCMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_clean_dcache_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 2\n" /* DCCSW */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_clean_ucache_bymva(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c11, 1\n" /* DCCMVAU */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, r0, c7, c14, 1\n" /* DCCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c14, 2\n" /* DCCISW */ + : + : "r" (setway) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: cp15_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache). This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_coherent_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_invalidate_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_invalidate_dcache_all(void); + +/**************************************************************************** + * Name: cp15_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_clean_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_flush_dcache(uintptr_t start, uintptr_t end); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_CP15_CACHEOPS_H */ diff --git a/arch/arm/src/armv7-a/cp15_clean_dcache.S b/arch/arm/src/armv7-a/cp15_clean_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..0f2f8e39eb8aba3b7a22642850122cdcd4a5cfe6 --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_clean_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_clean_dcache.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_clean_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_clean_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_clean_dcache + .type cp15_clean_dcache, function + +cp15_clean_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r0, r0, r3 /* R0=aligned start address */ + + /* Loop, cleaning each cache line by writing its contents to memory */ + +1: + mcr CP15_DCCMVAC(r0) /* Clean data cache line to PoC by VA */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + bx lr + .size cp15_clean_dcache, . - cp15_clean_dcache + .end diff --git a/arch/arm/src/armv7-a/cp15_coherent_dcache.S b/arch/arm/src/armv7-a/cp15_coherent_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..8f3ee3196b7f616dd3f45ceacb6cf4401ca15efe --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_coherent_dcache.S @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_coherent_dcache.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_coherent_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_coherent_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_coherent_dcache + .type cp15_coherent_dcache, function + +cp15_coherent_dcache: + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, flushing each D cache line to memory */ +1: + mcr CP15_DCCMVAU(r12) /* Clean data or unified cache line by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + and r3, r3, #0xf /* Isolate the IminLine field */ + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, invalidating each I cache line to memory */ +1: + mcr CP15_ICIMVAU(r12) /* Invalidate instruction cache by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been invalidated */ + blo 1b + + mov r0, #0 + mcr CP15_BPIALLIS(r0) /* Invalidate entire branch predictor array Inner Shareable */ + mcr CP15_BPIALL(r0) /* Invalidate entire branch predictor array Inner Shareable */ + + dsb + isb + bx lr + .size cp15_coherent_dcache, . - cp15_coherent_dcache + .end diff --git a/arch/arm/src/armv7-a/cp15_flush_dcache.S b/arch/arm/src/armv7-a/cp15_flush_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..ca43fa1adffbedf6fc6d9dc03e3025bd7ce022aa --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_flush_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_flush_dcache.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_flush_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_flush_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_flush_dcache + .type cp15_flush_dcache, function + +cp15_flush_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r0, r0, r3 /* R0=aligned start address */ + + /* Loop, cleaning and invaliding each D cache line in the address range */ + +1: + mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + bx lr + .size cp15_flush_dcache, . - cp15_flush_dcache + .end diff --git a/arch/arm/src/armv7-a/cp15_invalidate_dcache.S b/arch/arm/src/armv7-a/cp15_invalidate_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..56ff8837bfb2814fd594f1df34abdde83e6bb0a8 --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_invalidate_dcache.S @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_invalidate_dcache.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_invalidate_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_invalidate_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_invalidate_dcache + .type cp15_invalidate_dcache, function + +cp15_invalidate_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + tst r0, r3 + bic r0, r0, r3 /* R0=aligned start address */ + + mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */ + + tst r1, r3 + bic r1, r1, r3 /* R0=aligned end address */ + mcrne CP15_DCCIMVAC(r1) /* Clean and invalidate data cache line by VA to PoC */ + + /* Loop, invalidating each D cache line */ +1: + mcr CP15_DCIMVAC(r0) /* Invalidate data cache line by VA to PoC */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been invalidate */ + blo 1b + + dsb + bx lr + .size cp15_invalidate_dcache, . - cp15_invalidate_dcache + .end diff --git a/arch/arm/src/armv7-a/cp15_invalidate_dcache_all.S b/arch/arm/src/armv7-a/cp15_invalidate_dcache_all.S new file mode 100644 index 0000000000000000000000000000000000000000..747c190f7da1505dc595b893f2190ca5915eabb0 --- /dev/null +++ b/arch/arm/src/armv7-a/cp15_invalidate_dcache_all.S @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/cp15_invalidate_dcache_all.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_invalidate_dcache_all.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_invalidate_dcache_all + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_invalidate_dcache_all + .type cp15_invalidate_dcache_all, function + +cp15_invalidate_dcache_all: + + mrc CP15_CCSIDR(r0) /* Read the Cache Size Identification Register */ + ldr r3, =0xffff /* Isolate the NumSets field (bits 13-27) */ + and r0, r3, r0, lsr #13 /* r0=NumSets (number of sets - 1) */ + + mov r1, #0 /* r1 = way loop counter */ +way_loop: + + mov r3, #0 /* r3 = set loop counter */ +set_loop: + mov r2, r1, lsl #30 /* r2 = way loop counter << 30 */ + orr r2, r3, lsl #5 /* r2 = set/way cache operation format */ + mcr CP15_DCISW(r2) /* Data Cache Invalidate by Set/Way */ + add r3, r3, #1 /* Increment set counter */ + cmp r0, r3 /* Last set? */ + bne set_loop /* Keep looping if not */ + + add r1, r1, #1 /* Increment the way counter */ + cmp r1, #4 /* Last way? (four ways assumed) */ + bne way_loop /* Keep looping if not */ + + dsb + bx lr + .size cp15_invalidate_dcache_all, . - cp15_invalidate_dcache_all + .end diff --git a/arch/arm/src/armv7-a/crt0.c b/arch/arm/src/armv7-a/crt0.c new file mode 100644 index 0000000000000000000000000000000000000000..cfa00e7b1c4bfbb9111322565955ae66d5951c6c --- /dev/null +++ b/arch/arm/src/armv7-a/crt0.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/crt0.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_BUILD_KERNEL + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int main(int argc, char *argv[]); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_handler + * + * Description: + * This function is the user-space, signal handler trampoline function. It + * is called from up_signal_dispatch() in user-mode. + * + * R0-R3, R11 - volatile registers need not be preserved. + * R4-R10 - static registers must be preserved + * R12-R14 - LR and SP must be preserved + * + * Inputs: + * R0 = sighand + * The address user-space signal handling function + * R1-R3 = signo, info, and ucontext + * Standard arguments to be passed to the signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via the SYS_signal_handler_return (see svcall.h) + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_SIGNALS +static void sig_trampoline(void) naked_function; +static void sig_trampoline(void) +{ + __asm__ __volatile__ + ( + " push {lr}\n" /* Save LR on the stack */ + " mov ip, r0\n" /* IP=sighand */ + " mov r0, r1\n" /* R0=signo */ + " mov r1, r2\n" /* R1=info */ + " mov r2, r3\n" /* R2=ucontext */ + " blx ip\n" /* Call the signal handler */ + " pop {r2}\n" /* Recover LR in R2 */ + " mov lr, r2\n" /* Restore LR */ + " mov r0, #5\n" /* SYS_signal_handler_return */ + " svc #0x900001\n" /* Return from the signal handler */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This function is the low level entry point into the main thread of + * execution of a task. It receives initial control when the task is + * started and calls main entry point of the newly started task. + * + * Input Parameters: + * argc - The number of parameters being passed. + * argv - The parameters being passed. These lie in kernel-space memory + * and will have to be reallocated in user-space memory. + * + * Returned Value: + * This function should not return. It should call the user-mode start-up + * main() function. If that function returns, this function will call + * exit. + * + ****************************************************************************/ + +void _start(int argc, FAR char *argv[]) +{ + int ret; + +#ifndef CONFIG_DISABLE_SIGNALS + /* Initialize the reserved area at the beginning of the .bss/.data region + * that is visible to the RTOS. + */ + + ARCH_DATA_RESERVE->ar_sigtramp = (addrenv_sigtramp_t)sig_trampoline; +#endif + + /* Call C++ constructors */ + /* Setup so that C++ destructors called on task exit */ + /* REVISIT: Missing logic */ + + /* Call the main() entry point passing argc and argv. */ + + ret = main(argc, argv); + + /* Call exit() if/when the main() returns */ + + exit(ret); +} + +#endif /* CONFIG_BUILD_KERNEL */ diff --git a/arch/arm/src/armv7-a/fpu.h b/arch/arm/src/armv7-a/fpu.h new file mode 100644 index 0000000000000000000000000000000000000000..075ade1cff592888adf64d73ff7f0359bde549af --- /dev/null +++ b/arch/arm/src/armv7-a/fpu.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/fpu.h + * Non-CP15 Registers + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_FPU_H +#define __ARCH_ARM_SRC_ARMV7_A_FPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +void arm_fpuconfig(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_FPU_H */ diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h new file mode 100644 index 0000000000000000000000000000000000000000..45f8a606cbed8df68ec30ab53d06634ecc61f06c --- /dev/null +++ b/arch/arm/src/armv7-a/gic.h @@ -0,0 +1,813 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/gic.h + * Generic Interrupt Controller Version 2 Definitions + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * Cortexâ„¢-A9 MPCore, Revision: r4p1, Technical Reference Manual, ARM DDI + * 0407I (ID091612). + * + * Includes some removed registers from the r2p2 version as well. ARM DDI + * 0407F (ID050110) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_GIC_H +#define __ARCH_ARM_SRC_ARMV7_A_GIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "nuttx/config.h" + +#include +#include + +#include "mpcore.h" +#include "up_arch.h" + +#ifdef CONFIG_ARMV7A_HAVE_GICv2 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Generic indexing helpers *************************************************/ +/* 1x32 bit field per register */ + +#define GIC_INDEX1(n) (n) /* 1 field per word */ +#define GIC_OFFSET1(n) (GIC_INDEX1(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT1(n) (0) /* No shift */ +#define GIC_MASK1(n) (0xffffffff) /* Whole word */ + +/* 2x16 bit field per register */ + +#define GIC_INDEX2(n) (n >> 1) /* 2 fields per word */ +#define GIC_OFFSET2(n) (GIC_INDEX2(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT2(n) (((n) & 1) << 4) /* Shift 16-bits per field */ +#define GIC_MASK2(n) (0xffff << GIC_SHIFT2(n)) /* 16-bit mask */ + +/* 4x8 bit field per register */ + +#define GIC_INDEX4(n) (n >> 2) /* 4 fields per word */ +#define GIC_OFFSET4(n) (GIC_INDEX4(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT4(n) (((n) & 3) << 3) /* Shift 8-bits per field */ +#define GIC_MASK4(n) (0xff << GIC_SHIFT4(n)) /* 8-bit mask */ + +/* 8x4 bit field per register */ + +#define GIC_INDEX8(n) (n >> 3) /* 8 fields per word */ +#define GIC_OFFSET8(n) (GIC_INDEX8(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT8(n) (((n) & 7) << 2) /* Shift 4-bits per field */ +#define GIC_MASK8(n) (15 << GIC_SHIFT8(n)) /* 4-bit mask */ + +/* 16x2 bit field per register */ + +#define GIC_INDEX16(n) (n >> 4) /* 16 fields per word */ +#define GIC_OFFSET16(n) (GIC_INDEX16(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT16(n) (((n) & 15) << 1) /* Shift 2-bits per field */ +#define GIC_MASK16(n) (3 << GIC_SHIFT16(n)) /* 2-bit mask */ + +/* 32x1 bit field per register */ + +#define GIC_INDEX32(n) (n >> 5) /* 32 fields per word */ +#define GIC_OFFSET32(n) (GIC_INDEX32(n) << 2) /* 32-bit word offset */ +#define GIC_SHIFT32(n) ((n) & 31) /* Shift 1-bit per field */ +#define GIC_MASK32(n) (1 << GIC_SHIFT32(n)) /* 1-bit mask */ + +/* GIC Register Offsets *****************************************************/ +/* CPU Interface registers */ + +#define GIC_ICCICR_OFFSET 0x0000 /* CPU Interface Control Register */ +#define GIC_ICCPMR_OFFSET 0x0004 /* Interrupt Priority Mask Register */ +#define GIC_ICCBPR_OFFSET 0x0008 /* Binary point Register */ +#define GIC_ICCIAR_OFFSET 0x000c /* Interrupt Acknowledge */ +#define GIC_ICCEOIR_OFFSET 0x0010 /* End of interrupt */ +#define GIC_ICCRPR_OFFSET 0x0014 /* Running interrupt */ +#define GIC_ICCHPIR_OFFSET 0x0018 /* Highest pending interrupt */ +#define GIC_ICCABPR_OFFSET 0x001c /* Aliased Non-secure Binary Point Register */ +#define GIC_ICCAIAR_OFFSET 0x0020 /* Aliased Interrupt Acknowledge Register */ +#define GIC_ICCAEOIR_OFFSET 0x0024 /* Aliased End of Interrupt Register */ +#define GIC_ICCAHPIR_OFFSET 0x0028 /* Aliased Highest Priority Pending Interrupt Register */ + /* 0x002c-0x003c: Reserved */ + /* 0x0040-0x00cf: Implementation defined */ +#define GIC_ICCAPR1_OFFSET 0x00d0 /* Active Priorities Register 1 */ +#define GIC_ICCAPR2_OFFSET 0x00d4 /* Active Priorities Register 2 */ +#define GIC_ICCAPR3_OFFSET 0x00d8 /* Active Priorities Register 3 */ +#define GIC_ICCAPR4_OFFSET 0x00dc /* Active Priorities Register 4 */ +#define GIC_ICCNSAPR1_OFFSET 0x00e0 /* Non-secure Active Priorities Register 1 */ +#define GIC_ICCNSAPR2_OFFSET 0x00e4 /* Non-secure Active Priorities Register 2 */ +#define GIC_ICCNSAPR3_OFFSET 0x00e8 /* Non-secure Active Priorities Register 3 */ +#define GIC_ICCNSAPR4_OFFSET 0x00ec /* Non-secure Active Priorities Register 4 */ + /* 0x00ed-0x00f8: Reserved */ +#define GIC_ICCIDR_OFFSET 0x00fc /* CPU Interface Implementer ID Register */ +#define GIC_ICCDIR_OFFSET 0x1000 /* Deactivate Interrupt Register */ + +/* Distributor Registers */ + +#define GIC_ICDDCR_OFFSET 0x0000 /* Distributor Control Register */ +#define GIC_ICDICTR_OFFSET 0x0004 /* Interrupt Controller Type Register */ +#define GIC_ICDIIDR_OFFSET 0x0008 /* Distributor Implementer ID Register */ + /* 0x000c-0x001c: Reserved */ + /* 0x0020-0x003c: Implementation defined */ + /* 0x0040-0x007c: Reserved */ +/* Interrupt Security Registers: 0x0080-0x009c */ + +#define GIC_ICDISR_OFFSET(n) (0x0080 + GIC_OFFSET32(n)) + +/* Interrupt Set-Enable Registers: 0x0100-0x011c */ + +#define GIC_ICDISER_OFFSET(n) (0x0100 + GIC_OFFSET32(n)) + +/* Interrupt Clear-Enable Registers: 0x0180-0x019c */ + +#define GIC_ICDICER_OFFSET(n) (0x0180 + GIC_OFFSET32(n)) + +/* Interrupt Set-Pending Registers: 0x0200-0x027c */ + +#define GIC_ICDISPR_OFFSET(n) (0x0200 + GIC_OFFSET32(n)) + +/* Interrupt Clear-Pending Registers: 0x0280-0x02fc */ + +#define GIC_ICDICPR_OFFSET(n) (0x0280 + GIC_OFFSET32(n)) + +/* GICv2 Interrupt Set-Active Registers: 0x0300-0x31c */ + +#define GIC_ICDSAR_OFFSET(n) (0x0300 + GIC_OFFSET32(n)) + +/* Interrupt Clear-Active Registers: 0x380-0x3fc */ + +#define GIC_ICDCAR_OFFSET(n) (0x0380 + GIC_OFFSET32(n)) + +/* Interrupt Priority Registers: 0x0400-0x04fc */ + +#define GIC_ICDIPR_OFFSET(n) (0x0400 + GIC_OFFSET4(n)) + +/* 0x0500-0x07fc: Reserved */ +/* Interrupt Processor Target Registers: 0x0800-0x08fc */ + +#define GIC_ICDIPTR_OFFSET(n) (0x0800 + GIC_OFFSET4(n)) + +/* 0x0900-0x0bfc: Reserved */ +/* Interrupt Configuration Registers: 0x0c00-0x0c3c */ + +#define GIC_ICDICFR_OFFSET(n) (0x0c00 + GIC_OFFSET16(n)) + +/* 0x0d00-0x0dfc: Implementation defined */ +/* PPI Status Register: 0x0d00 */ +/* SPI Status Registers: 0x0d04-0x0d1c */ + +#define GIC_ICDPPISR_OFFSET 0x0d00 /* PPI Status Register */ +#define GIC_ICDSPISR_OFFSET(n) (0x0d00 + GIC_OFFSET32(n)) + +/* 0x0d80-0x0dfc: Reserved */ +/* Non-secure Access Control Registers, optional: 00xe00-0x0efc */ + +#define GIC_ICDNSACR_OFFSET(n) (0x0e00 + GIC_OFFSET32(n)) + +/* Software Generated Interrupt Register: 0x0f00 */ + +#define GIC_ICDSGIR_OFFSET 0x0f00 /* Software Generated Interrupt Register */ + +/* 0x0f0c-0x0f0c: Reserved */ +/* Peripheral Identification Registers: 0x0fd0-0xfe8 */ + +#define GIC_ICDPIDR_OFFSET(n) (0x0fd0 + ((n) << 2)) + +/* SGI Clear-Pending Registers: 0x0f10-0x0f1c */ + +#define GIC_ICDSCPR_OFFSET(n) (0x0f10 + GIC_OFFSET8(n)) + +/* SGI Set-Pending Registers: 0x0f20-0x0f2c */ + +#define GIC_ICDSSPR_OFFSET(n) (0x0f20 + GIC_OFFSET8(n)) + +/* 0x0f30-0x0fcc: Reserved */ +/* 0x0fd0-0x0ffc: Implementation defined */ +/* Component Identification Registers: 0x0ff0-0x0ffc */ + +#define GIC_ICDCIDR_OFFSET(n) (0x0ff0 + ((n) << 2)) + +/* 0x0f04-0x0ffc: Reserved */ + +/* GIC Register Addresses ***************************************************/ +/* The Interrupt Controller is a single functional unit that is located in a + * Cortex-A9 MPCore design. There is one interrupt interface per Cortex-A9 + * processor. Registers are memory mapped and accessed through a chip- + * specific private memory spaced (see mpcore.h). + */ + +/* CPU Interface registers */ + +#define GIC_ICCICR (MPCORE_ICC_VBASE+GIC_ICCICR_OFFSET) +#define GIC_ICCPMR (MPCORE_ICC_VBASE+GIC_ICCPMR_OFFSET) +#define GIC_ICCBPR (MPCORE_ICC_VBASE+GIC_ICCBPR_OFFSET) +#define GIC_ICCIAR (MPCORE_ICC_VBASE+GIC_ICCIAR_OFFSET) +#define GIC_ICCEOIR (MPCORE_ICC_VBASE+GIC_ICCEOIR_OFFSET) +#define GIC_ICCRPR (MPCORE_ICC_VBASE+GIC_ICCRPR_OFFSET) +#define GIC_ICCHPIR (MPCORE_ICC_VBASE+GIC_ICCHPIR_OFFSET) +#define GIC_ICCABPR (MPCORE_ICC_VBASE+GIC_ICCABPR_OFFSET) +#define GIC_ICCAIAR (MPCORE_ICC_VBASE+GIC_ICCAIAR_OFFSET) +#define GIC_ICCAEOIR (MPCORE_ICC_VBASE+GIC_ICCAEOIR_OFFSET) +#define GIC_ICCAHPIR (MPCORE_ICC_VBASE+GIC_ICCAHPIR_OFFSET) +#define GIC_ICCAPR1 (MPCORE_ICC_VBASE+GIC_ICCAPR1_OFFSET) +#define GIC_ICCAPR2 (MPCORE_ICC_VBASE+GIC_ICCAPR2_OFFSET) +#define GIC_ICCAPR3 (MPCORE_ICC_VBASE+GIC_ICCAPR3_OFFSET) +#define GIC_ICCAPR4 (MPCORE_ICC_VBASE+GIC_ICCAPR4_OFFSET) +#define GIC_ICCNSAPR1 (MPCORE_ICC_VBASE+GIC_ICCNSAPR1_OFFSET) +#define GIC_ICCNSAPR2 (MPCORE_ICC_VBASE+GIC_ICCNSAPR2_OFFSET) +#define GIC_ICCNSAPR3 (MPCORE_ICC_VBASE+GIC_ICCNSAPR3_OFFSET) +#define GIC_ICCNSAPR4 (MPCORE_ICC_VBASE+GIC_ICCNSAPR4_OFFSET) +#define GIC_ICCIDR (MPCORE_ICC_VBASE+GIC_ICCIDR_OFFSET) +#define GIC_ICCDIR (MPCORE_ICC_VBASE+GIC_ICCDIR_OFFSET) + +/* Distributor Registers */ + +#define GIC_ICDDCR (MPCORE_ICD_VBASE+GIC_ICDDCR_OFFSET) +#define GIC_ICDICTR (MPCORE_ICD_VBASE+GIC_ICDICTR_OFFSET) +#define GIC_ICDIIDR (MPCORE_ICD_VBASE+GIC_ICDIIDR_OFFSET) +#define GIC_ICDISR(n) (MPCORE_ICD_VBASE+GIC_ICDISR_OFFSET(n)) +#define GIC_ICDISER(n) (MPCORE_ICD_VBASE+GIC_ICDISER_OFFSET(n)) +#define GIC_ICDICER(n) (MPCORE_ICD_VBASE+GIC_ICDICER_OFFSET(n)) +#define GIC_ICDISPR(n) (MPCORE_ICD_VBASE+GIC_ICDISPR_OFFSET(n)) +#define GIC_ICDICPR(n) (MPCORE_ICD_VBASE+GIC_ICDICPR_OFFSET(n)) +#define GIC_ICDSAR(n) (MPCORE_ICD_VBASE+GIC_ICDSAR_OFFSET(n)) +#define GIC_ICDCAR(n) (MPCORE_ICD_VBASE+GIC_ICDCAR_OFFSET(n)) +#define GIC_ICDIPR(n) (MPCORE_ICD_VBASE+GIC_ICDIPR_OFFSET(n)) +#define GIC_ICDIPTR(n) (MPCORE_ICD_VBASE+GIC_ICDIPTR_OFFSET(n)) +#define GIC_ICDICFR(n) (MPCORE_ICD_VBASE+GIC_ICDICFR_OFFSET(n)) +#define GIC_ICDPPISR (MPCORE_ICD_VBASE+GIC_ICDPPISR_OFFSET) +#define GIC_ICDSPISR(n) (MPCORE_ICD_VBASE+GIC_ICDSPISR_OFFSET(n)) +#define GIC_ICDNSACR(n) (MPCORE_ICD_VBASE+GIC_ICDNSACR_OFFSET(n)) +#define GIC_ICDSGIR (MPCORE_ICD_VBASE+GIC_ICDSGIR_OFFSET) +#define GIC_ICDPIDR(n) (MPCORE_ICD_VBASE+GIC_ICDPIDR_OFFSET(n)) +#define GIC_ICDSCPR(n) (MPCORE_ICD_VBASE+GIC_ICDSCPR_OFFSET(n)) +#define GIC_ICDSSPR(n) (MPCORE_ICD_VBASE+GIC_ICDSSPR_OFFSET(n)) +#define GIC_ICDCIDR(n) (MPCORE_ICD_VBASE+GIC_ICDCIDR_OFFSET(n)) + +/* GIC Register Bit Definitions *********************************************/ + +/* CPU Interface registers */ +/* CPU Interface Control Register -- without security extensions */ + +#define GIC_ICCICR_ENABLE (1 << 0) /* Bit 0: Enable the CPU interface for this GIC */ + /* Bits 1-31: Reserved */ +/* CPU Interface Control Register -- with security extensions, non-secure copy */ + +#define GIC_ICCICRU_ENABLEGRP1 (1 << 0) /* Bit 0: Enable Group 1 interrupts for the CPU */ + /* Bits 1-4: Reserved */ +#define GIC_ICCICRU_FIQBYPDISGRP1 (1 << 5) /* Bit 5: FIQ disabled for CPU Group 1*/ +#define GIC_ICCICRU_IRQBYPDISGRP1 (1 << 6) /* Bit 6: IRQ disabled for CPU Group 1*/ + /* Bits 7-8: Reserved */ +#define GIC_ICCICRU_EOIMODENS (1 << 9) /* Bit 9: Control EIOIR access (non-secure) */ + /* Bits 10-31: Reserved */ +/* CPU Interface Control Register -- with security extensions, secure copy */ + +#define GIC_ICCICRS_ENABLEGRP0 (1 << 0) /* Bit 0: Enable Group 0 interrupts for the CPU */ +#define GIC_ICCICRS_ENABLEGRP1 (1 << 1) /* Bit 1: Enable Group 1 interrupts for the CPU */ +#define GIC_ICCICRS_ACKTCTL (1 << 2) /* Bit 2: Group 1 interrupt activation control */ +#define GIC_ICCICRS_FIQEN (1 << 3) /* Bit 3: Signal Group 0 via FIQ */ +#define GIC_ICCICRS_CBPR (1 << 4) /* Bit 4: Control Group 0/1 Pre-emption */ +#define GIC_ICCICRS_FIQBYPDISGRP0 (1 << 5) /* Bit 5: FIQ disabled for CPU Group 0 */ +#define GIC_ICCICRS_IRQBYPDISGRP0 (1 << 6) /* Bit 6: IRQ disabled for CPU Group 0 */ +#define GIC_ICCICRS_FIQBYPDISGRP1 (1 << 7) /* Bit 5: FIQ disabled for CPU Group 1 */ +#define GIC_ICCICRS_IRQBYPDISGRP1 (1 << 8) /* Bit 6: IRQ disabled for CPU Group 1 */ +#define GIC_ICCICRS_EOIMODES (1 << 9) /* Bit 6: Control EIOIR access (secure) */ +#define GIC_ICCICRS_EOIMODENS (1 << 10) /* Bit 10: Control EIOIR access (non-secure) */ + /* Bits 11-31: Reserved */ +/* Interrupt Priority Mask Register. Priority values are 8-bit unsigned + * binary. A GIC supports a minimum of 16 and a maximum of 256 priority + * levels. As a result, PMR settings make sense. + */ + +#define GIC_ICCPMR_SHIFT (0) /* Bits 0-7: Priority mask */ +#define GIC_ICCPMR_MASK (0xff << GIC_ICCPMR_SHIFT) +# define GIC_ICCPMR_VALUE(n) ((uint32_t)(n) << GIC_ICCPMR_SHIFT) + /* Bits 8-31: Reserved */ +/* Binary point Register and Aliased Non-secure Binary Point Register. + * Priority values are 8-bit unsigned binary. A GIC supports a minimum of + * 16 and a maximum of 256 priority levels. As a result, not all binary + * point settings make sense. + */ + +#define GIC_ICCBPR_SHIFT (0) /* Bits 0-2: Binary point */ +#define GIC_ICCBPR_MASK (7 << GIC_ICCBPR_SHIFT) +# define GIC_ICCBPR_1_7 (0 << GIC_ICCBPR_SHIFT) /* Priority bits [7:1] compared for pre-emption */ +# define GIC_ICCBPR_2_7 (1 << GIC_ICCBPR_SHIFT) /* Priority bits [7:2] compared for pre-emption */ +# define GIC_ICCBPR_3_7 (2 << GIC_ICCBPR_SHIFT) /* Priority bits [7:2] compared for pre-emption */ +# define GIC_ICCBPR_4_7 (3 << GIC_ICCBPR_SHIFT) /* Priority bits [7:2] compared for pre-emption */ +# define GIC_ICCBPR_5_7 (4 << GIC_ICCBPR_SHIFT) /* Priority bits [7:5] compared for pre-emption */ +# define GIC_ICCBPR_6_7 (5 << GIC_ICCBPR_SHIFT) /* Priority bits [7:6] compared for pre-emption */ +# define GIC_ICCBPR_7_7 (6 << GIC_ICCBPR_SHIFT) /* Priority bit [7] compared for pre-emption */ +# define GIC_ICCBPR_NOPREMPT (7 << GIC_ICCBPR_SHIFT) /* No pre-emption is performed */ + /* Bits 3-31: Reserved */ +/* Interrupt Acknowledge Register */ + +#define GIC_ICCIAR_INTID_SHIFT (0) /* Bits 0-9: Interrupt ID */ +#define GIC_ICCIAR_INTID_MASK (0x3ff << GIC_ICCIAR_INTID_SHIFT) +# define GIC_ICCIAR_INTID(n) ((uint32_t)(n) << GIC_ICCIAR_INTID_SHIFT) +#define GIC_ICCIAR_CPUSRC_SHIFT (10) /* Bits 10-12: CPU source ID */ +#define GIC_ICCIAR_CPUSRC_MASK (7 << GIC_ICCIAR_CPUSRC_SHIFT) +# define GIC_ICCIAR_CPUSRC(n) ((uint32_t)(n) << GIC_ICCIAR_CPUSRC_SHIFT) + /* Bits 13-31: Reserved */ +/* End of Interrupt Register */ + +#define GIC_ICCEOIR_SPURIOUS (0x3ff) + +#define GIC_ICCEOIR_INTID_SHIFT (0) /* Bits 0-9: Interrupt ID */ +#define GIC_ICCEOIR_INTID_MASK (0x3ff << GIC_ICCEOIR_INTID_SHIFT) +# define GIC_ICCEOIR_INTID(n) ((uint32_t)(n) << GIC_ICCEOIR_INTID_SHIFT) +#define GIC_ICCEOIR_CPUSRC_SHIFT (10) /* Bits 10-12: CPU source ID */ +#define GIC_ICCEOIR_CPUSRC_MASK (7 << GIC_ICCEOIR_CPUSRC_SHIFT) +# define GIC_ICCEOIR_CPUSRC(n) ((uint32_t)(n) << GIC_ICCEOIR_CPUSRC_SHIFT) + /* Bits 13-31: Reserved */ +/* Running Interrupt Register */ + + /* Bits 0-3: Reserved */ +#define GIC_ICCRPR_PRIO_SHIFT (4) /* Bits 4-7: Priority mask */ +#define GIC_ICCRPR_PRIO_MASK (15 << GIC_ICCRPR_PRIO_SHIFT) +# define GIC_ICCRPR_PRIO_VALUE(n) ((uint32_t)(n) << GIC_ICCRPR_PRIO_SHIFT) + /* Bits 8-31: Reserved */ +/* Highest Pending Interrupt Register */ + +#define GIC_ICCHPIR_INTID_SHIFT (0) /* Bits 0-9: Interrupt ID */ +#define GIC_ICCHPIR_INTID_MASK (0x3ff << GIC_ICCHPIR_INTID_SHIFT) +# define GIC_ICCHPIR_INTID(n) ((uint32_t)(n) << GIC_ICCHPIR_INTID_SHIFT) +#define GIC_ICCHPIR_CPUSRC_SHIFT (10) /* Bits 10-12: CPU source ID */ +#define GIC_ICCHPIR_CPUSRC_MASK (7 << GIC_ICCHPIR_CPUSRC_SHIFT) +# define GIC_ICCHPIR_CPUSRC(n) ((uint32_t)(n) << GIC_ICCHPIR_CPUSRC_SHIFT) + /* Bits 13-31: Reserved */ + +/* Aliased Interrupt Acknowledge Register */ +#define GIC_ICCAIAR_ +/* Aliased End of Interrupt Register */ +#define GIC_ICCAEOIR_ +/* Aliased Highest Priority Pending Interrupt Register */ +#define GIC_ICCAHPIR_ +/* Active Priorities Register 1 */ +#define GIC_ICCAPR1_ +/* Active Priorities Register 2 */ +#define GIC_ICCAPR2_ +/* Active Priorities Register 3 */ +#define GIC_ICCAPR3_ +/* Active Priorities Register 4 */ +#define GIC_ICCAPR4_ +/* Non-secure Active Priorities Register 1 */ +#define GIC_ICCNSAPR1_ +/* Non-secure Active Priorities Register 2 */ +#define GIC_ICCNSAPR2_ +/* Non-secure Active Priorities Register 3 */ +#define GIC_ICCNSAPR3_ +/* Non-secure Active Priorities Register 4 */ +#define GIC_ICCNSAPR4_ + +/* CPU Interface Implementer ID Register */ + +#define GIC_ICCIDR_IMPL_SHIFT (0) /* Bits 0-11: Implementer */ +#define GIC_ICCIDR_IMPL_MASK (0xfff << GIC_ICCIDR_IMPL_SHIFT) +#define GIC_ICCIDR_REVISION_SHIFT (12) /* Bits 12-15: Revision number */ +#define GIC_ICCIDR_REVISION_MASK (15 << GIC_ICCIDR_REVISION_SHIFT) +#define GIC_ICCIDR_ARCHNO_SHIFT (16) /* Bits 16-19: Architecture number */ +#define GIC_ICCIDR_ARCHNO_MASK (15 << GIC_ICCIDR_ARCHNO_SHIFT) +#define GIC_ICCIDR_PARTNO_SHIFT (20) /* Bits 20-31: Part number */ +#define GIC_ICCIDR_PARTNO_MASK (0xfff << GIC_ICCIDR_PARTNO_SHIFT) + +/* Deactivate Interrupt Register */ +#define GIC_ICCDIR_ + +/* Distributor Registers */ +/* Distributor Control Register -- without security extensions */ + +#define GIC_ICDDCR_ENABLE (1 << 0) /* Bit 0: Enable forwarding of interrupts */ + /* Bits 1-31: Reserved */ +/* Distributor Control Register -- with security extensions */ + +#define GIC_ICDDCR_ENABLEGRP0 (1 << 0) /* Bit 0: Enable forwarding of Group 0 interrupts */ +#define GIC_ICDDCR_ENABLEGRP1 (1 << 1) /* Bit 1: Enable forwarding of Group 1 interrupts */ + /* Bits 2-31: Reserved */ +/* Interrupt Controller Type Register */ + +#define GIC_ICDICTR_ITLINES_SHIFT (0) /* Bits 0-4: It lines number */ +#define GIC_ICDICTR_ITLINES_MASK (0x1f << GIC_ICDICTR_ITLINES_SHIFT) +#define GIC_ICDICTR_CPUNO_SHIFT (5) /* Bits 5-7: CPU number */ +#define GIC_ICDICTR_CPUNO_MASK (7 << GIC_ICDICTR_CPUNO_SHIFT) + /* Bits 8-9: Reserved */ +#define GIC_ICDICTR_SECEXTNS (1 << 10) /* Bit 10: Number of security domains */ +#define GIC_ICDICTR_LSPI_SHIFT (11) /* Bits 11-15: Number of Lockable Shared Peripheral Interrupts */ +#define GIC_ICDICTR_LSPI_MASK (0x1f << GIC_ICDICTR_LSPI_SHIFT) + /* Bits 16-31: Reserved */ +/* Distributor Implementer ID Register */ + +#define GIC_ICDIIDR_IMPL_SHIFT (0) /* Bits 0-11: Implementer */ +#define GIC_ICDIIDR_IMPL_MASK (0xfff << GIC_ICDIIDR_IMPL_SHIFT) +#define GIC_ICDIIDR_REVISION_SHIFT (12) /* Bits 12-23: Revision number */ +#define GIC_ICDIIDR_REVISION_MASK (0xfff << GIC_ICDIIDR_REVISION_SHIFT) +#define GIC_ICDIIDR_VERSION_SHIFT (24) /* Bits 24-31: Iimplementer version */ +#define GIC_ICDIIDR_VERSION_MASK (0xff << GIC_ICDIIDR_VERSION_SHIFT) + +/* Interrupt Security Registers: 0x0080-0x009c */ + +#define GIC_ICDISR_INT(n) GIC_MASK32(n) + +/* Interrupt Set-Enable. + * + * NOTE: In the Cortex-A9 MPCore, SGIs are always enabled. The corresponding bits + * in the ICDISERn are read as one, write ignored + */ + +#define GIC_ICDISER_INT(n) GIC_MASK32(n) + +/* Interrupt Clear-Enable. + * + * NOTE: In the Cortex-A9 MPCore, SGIs are always enabled. The corresponding bits + * in the ICDICERn are read as one, write ignored + */ + +#define GIC_ICDICER_INT(n) GIC_MASK32(n) + +/* Interrupt Set-Pending */ + +#define GIC_ICDISPR_INT(n) GIC_MASK32(n) + +/* Interrupt Clear-Pending */ + +#define GIC_ICDICPR_INT(n) GIC_MASK32(n) + +/* GICv2 Interrupt Set-Active Registers */ + +#define GIC_ICDSAR_INT(n) GIC_MASK32(n) + +/* Interrupt Clear-Active Registers */ + +#define GIC_ICDCAR_INT(n) GIC_MASK32(n) + +/* Interrupt Priority Registers */ + +#define GIC_ICDIPR_ID_SHIFT(n) GIC_SHIFT4(n) +#define GIC_ICDIPR_ID_MASK(n) GIC_MASK4(n) +# define GIC_ICDIPR_ID(n,p) ((uint32_t)(p) << GIC_SHIFT4(n)) + +/* Interrupt Processor Target Registers */ + +#define CPU0_TARGET (1 << 0) +#define CPU1_TARGET (1 << 1) +#define CPU2_TARGET (1 << 2) +#define CPU3_TARGET (1 << 3) + +#define GIC_ICDIPTR_ID_SHIFT(n) GIC_SHIFT4(n) +#define GIC_ICDIPTR_ID_MASK(n) GIC_MASK4(n) +# define GIC_ICDIPTR_ID(n,t) ((uint32_t)(t) <> GIC_ICDICTR_ITLINES_SHIFT; + return (field + 1) << 5; +} + +/**************************************************************************** + * Name: arm_cpu_sgi + * + * Description: + * Perform a Software Generated Interrupt (SGI). If CONFIG_SMP is + * selected, then the SGI is sent to all CPUs specified in the CPU set. + * That set may include the current CPU. + * + * If CONFIG_SMP is not selected, the cpuset is ignored and SGI is sent + * only to the current CPU. + * + * Input Paramters + * sgi - The SGI interrupt ID (0-15) + * cpuset - The set of CPUs to receive the SGI + * + * Returned Value: + * OK is always returned at present. + * + ****************************************************************************/ + +static inline int arm_cpu_sgi(int sgi, unsigned int cpuset) +{ + uint32_t regval; + +#ifdef CONFIG_SMP + regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(cpuset) | + GIC_ICDSGIR_TGTFILTER_LIST; +#else + regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(0) | + GIC_ICDSGIR_TGTFILTER_THIS; +#endif + + putreg32(regval, GIC_ICDSGIR); + return OK; +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +/**************************************************************************** + * Name: arm_gic0_initialize + * + * Description: + * Perform common, one-time GIC initialization on CPU0 only. Both + * arm_gic0_initialize() must be called on CPU0; arm_gic_initialize() must + * be called for all CPUs. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_gic0_initialize(void); + +/**************************************************************************** + * Name: arm_gic_initialize + * + * Description: + * Perform common GIC initialization for the current CPU (all CPUs) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_gic_initialize(void); + +/**************************************************************************** + * Name: arm_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *arm_decodeirq(uint32_t *regs); + +/**************************************************************************** + * Name: arm_start_handler + * + * Description: + * This is the handler for SGI1. This handler simply returns from the + * interrupt, restoring the state of the new task at the head of the ready + * to run list. + * + * Input Parameters: + * Standard interrupt handling + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int arm_start_handler(int irq, FAR void *context); +#endif + +/**************************************************************************** + * Name: arm_pause_handler + * + * Description: + * This is the handler for SGI2. It performs the following operations: + * + * 1. It saves the current task state at the head of the current assigned + * task list. + * 2. It waits on a spinlock, then + * 3. Returns from interrupt, restoring the state of the new task at the + * head of the ready to run list. + * + * Input Parameters: + * Standard interrupt handling + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int arm_pause_handler(int irq, FAR void *context); +#endif + +/**************************************************************************** + * Name: arm_gic_dump + * + * Description: + * Dump GIC registers to the SYSLOG device + * + * Input Parameters: + * msg - Message to print with the register data + * all - True: Dump all IRQs; False: Dump only registers for this IRQ + * irq - if all == false, then dump only this IRQ. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_IRQ +void arm_gic_dump(const char *msg, bool all, int irq); +#else +# define arm_gic_dump(m,a,i) +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_ARMV7A_HAVE_GICv2 */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_GIC_H */ diff --git a/arch/arm/src/armv7-a/gtm.h b/arch/arm/src/armv7-a/gtm.h new file mode 100644 index 0000000000000000000000000000000000000000..054d37f1784e263a3c451a97cf91fb97fe02aa0b --- /dev/null +++ b/arch/arm/src/armv7-a/gtm.h @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/gtm.h + * Global Timer Definitions + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * Cortexâ„¢-A9 MPCore, Revision: r4p1, Technical Reference Manual, ARM DDI + * 0407I (ID091612). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_GTM_H +#define __ARCH_ARM_SRC_ARMV7_A_GTM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "nuttx/config.h" +#include +#include "mpcore.h" + +#ifdef CONFIG_ARMV7A_HAVE_GTM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* GTM Register Offsets *****************************************************/ + +#define GTM_COUNT0_OFFSET 0x0000 /* Global Timer Counter Register 0 */ +#define GTM_COUNT1_OFFSET 0x0004 /* Global Timer Counter Register 1 */ +#define GTM_CTRL_OFFSET 0x0008 /* Global Timer Control Register */ +#define GTM_STA_OFFSET 0x000c /* Global Timer Interrupt Status Register */ +#define GTM_COMP0_OFFSET 0x0010 /* Comparator Value Register 0 */ +#define GTM_COMP1_OFFSET 0x0014 /* Comparator Value Register 1 */ +#define GTM_AUTO_OFFSET 0x0018 /* Auto-increment Register */ + +/* GTM Register Addresses ***************************************************/ + +#define GTM_COUNT0 (MPCORE_GTM_VBASE+GTM_COUNT0_OFFSET) +#define GTM_COUNT1 (MPCORE_GTM_VBASE+GTM_COUNT1_OFFSET) +#define GTM_CTRL (MPCORE_GTM_VBASE+GTM_CTRL_OFFSET) +#define GTM_STA (MPCORE_GTM_VBASE+GTM_STA_OFFSET) +#define GTM_COMP0 (MPCORE_GTM_VBASE+GTM_COMP0_OFFSET) +#define GTM_COMP1 (MPCORE_GTM_VBASE+COMPARE1_OFFSET) +#define GTM_AUTO (MPCORE_GTM_VBASE+AUTO_OFFSET) + +/* GTM Register Bit Definitions *********************************************/ + +/* Global Timer Counter Register 0/1 -- 64-bit timer counter value */ + +/* Global Timer Control Register */ + +#define GTM_CTRL_TIMEN (1 << 0) /* Bit 0: Timer comparator */ +#define GTM_CTRL_CMPEN (1 << 1) /* Bit 1: Enable comparator */ +#define GTM_CTRL_INTEN (1 << 2) /* Bit 2: Enable timer interrupt ID 27 */ +#define GTM_CTRL_AUTO (1 << 3) /* Bit 3: Auto-increment comparator register */ + /* Bits 4-7: Reserved */ +#define GTM_CTRL_PRESC_SHIFT (8) /* Bits 8-15: PERIPHCLK prescaler */ +#define GTM_CTRL_PRESC_MASK (0xff << GTM_CTRL_PRESC_SHIFT) +# define GTM_CTRL_PRESC(n) ((uint32_t)(n) << GTM_CTRL_PRESC_SHIFT) + /* Bits 16-31: Reserved */ + +/* Global Timer Interrupt Status Register */ + +#define GTM_STA_EVENT (1 << 0) /* Timer event flag */ + /* Bits 1-31: Reserved */ + +/* Comparator Value Register 0/1 -- 64-bit timer compare value */ +/* Auto-increment Register -- 32-bit auto-increment value */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +/* Clocking: + * CLK - This is the main clock of the Cortex-A9 processor. All Cortex-A9 + * processors in the Cortex-A9 MPCore processor and the SCU are clocked + * with a distributed version of CLK. + * PERIPHCLK - The Interrupt Controller, global timer, private timers, and + * watchdogs are clocked with PERIPHCLK. PERIPHCLK must be synchronous + * with CLK, and the PERIPHCLK clock period, N, must be configured as a + * multiple of the CLK clock period. This multiple N must be equal to, + * or greater than two. + */ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_ARMV7A_HAVE_GTM */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_GTM_H */ diff --git a/arch/arm/src/armv7-a/l2cc.h b/arch/arm/src/armv7-a/l2cc.h new file mode 100644 index 0000000000000000000000000000000000000000..f43ae9b65351f68043f039d50632d51653adc0ce --- /dev/null +++ b/arch/arm/src/armv7-a/l2cc.h @@ -0,0 +1,258 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/l2cc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_L2CC_H +#define __ARCH_ARM_SRC_ARMV7_A_L2CC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ARCH_L2CACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if 0 /* Prototyped in up_internal.h */ +void up_l2ccinitialize(void); +#endif + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_enable(void); + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2 cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_disable(void); + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_sync(void); + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate_all(void); + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses in the L2 cache + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean_all(void); + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush_all(void); + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush(uint32_t startaddr, uint32_t endaddr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_ARCH_L2CACHE */ + /* Provide simple definitions to concentrate the inline conditional + * compilation in one place. + */ + +# define l2cc_enable() +# define l2cc_disable() +# define l2cc_sync() +# define l2cc_invalidate_all() +# define l2cc_invalidate(s,e) +# define l2cc_clean_all() +# define l2cc_clean(s,e) +# define l2cc_flush_all() +# define l2cc_flush(s,e) + +#endif /* CONFIG_ARCH_L2CACHE */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_L2CC_H */ diff --git a/arch/arm/src/armv7-a/l2cc_pl310.h b/arch/arm/src/armv7-a/l2cc_pl310.h new file mode 100644 index 0000000000000000000000000000000000000000..16d8f723cb4b93f7854fc11c54118ee767f29a39 --- /dev/null +++ b/arch/arm/src/armv7-a/l2cc_pl310.h @@ -0,0 +1,497 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/chip/l2cc_pl310.h + * + * Register definitions for the L2 Cache Controller (L2CC) is based on the + * L2CC-PL310 ARM multi-way cache macrocell, version r3p2. + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2, + * Technical Reference Manual, ARM DDI 0246F (ID011711), ARM + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H +#define __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* The base address of the L2CC implementation must be provided in the chip.h + * header file as L2CC_VBASE. + */ + +#include "chip/chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* General Definitions **************************************************************/ + +#define PL310_CACHE_LINE_SIZE 32 + +#ifdef CONFIG_PL310_LOCKDOWN_BY_MASTER +# define PL310_NLOCKREGS 8 +#else +# define PL310_NLOCKREGS 1 +#endif + +/* L2CC Register Offsets ************************************************************/ + +#define L2CC_IDR_OFFSET 0x0000 /* Cache ID Register */ +#define L2CC_TYPR_OFFSET 0x0004 /* Cache Type Register */ +#define L2CC_CR_OFFSET 0x0100 /* Control Register */ +#define L2CC_ACR_OFFSET 0x0104 /* Auxiliary Control Register */ +#define L2CC_TRCR_OFFSET 0x0108 /* Tag RAM Control Register */ +#define L2CC_DRCR_OFFSET 0x010c /* Data RAM Control Register */ + /* 0x0110-0x01fc Reserved */ +#define L2CC_ECR_OFFSET 0x0200 /* Event Counter Control Register */ +#define L2CC_ECFGR1_OFFSET 0x0204 /* Event Counter 1 Configuration Register */ +#define L2CC_ECFGR0_OFFSET 0x0208 /* Event Counter 0 Configuration Register */ +#define L2CC_EVR1_OFFSET 0x020c /* Event Counter 1 Value Register */ +#define L2CC_EVR0_OFFSET 0x0210 /* Event Counter 0 Value Register */ +#define L2CC_IMR_OFFSET 0x0214 /* Interrupt Mask Register */ +#define L2CC_MISR_OFFSET 0x0218 /* Masked Interrupt Status Register */ +#define L2CC_RISR_OFFSET 0x021c /* Raw Interrupt Status Register */ +#define L2CC_ICR_OFFSET 0x0220 /* Interrupt Clear Register */ + /* 0x0224-0x072c Reserved */ +#define L2CC_CSR_OFFSET 0x0730 /* Cache Synchronization Register */ + /* 0x0734-0x076c Reserved */ +#define L2CC_IPALR_OFFSET 0x0770 /* Invalidate Physical Address Line Register */ + /* 0x0774-0x0778 Reserved */ +#define L2CC_IWR_OFFSET 0x077c /* Invalidate Way Register */ + /* 0x0780-0x07af Reserved */ +#define L2CC_CPALR_OFFSET 0x07b0 /* Clean Physical Address Line Register */ + /* 0x07b4 Reserved */ +#define L2CC_CIR_OFFSET 0x07b8 /* Clean Index Register */ +#define L2CC_CWR_OFFSET 0x07bc /* Clean Way Register */ + /* 0x07c0-0x07ec Reserved */ +#define L2CC_CIPALR_OFFSET 0x07f0 /* Clean Invalidate Physical Address Line Register */ + /* 0x07f4 Reserved */ +#define L2CC_CIIR_OFFSET 0x07f8 /* Clean Invalidate Index Register */ +#define L2CC_CIWR_OFFSET 0x07fc /* Clean Invalidate Way Register */ + /* 0x0800-0x08fc Reserved */ + +/* Data and Instruction Lockdown registers where n=0-7. The registers for n > 0 are + * implemented if the option pl310_LOCKDOWN_BY_MASTER is enabled. Otherwise, they are + * unused + */ + +#define L2CC_DLKR_OFFSET(n) (0x0900 + ((n) << 3)) /* Data Lockdown Register */ +#define L2CC_ILKR_OFFSET(n) (0x0904 + ((n) << 3)) /* Instruction Lockdown Register */ + /* 0x0940-0x0f4c Reserved */ +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_OFFSET 0x0950 /* Lock Line Enable Register */ +# define L2CC_UNLKW_OFFSET 0x0954 /* Unlock Way Register */ +#endif + /* 0x0958-0x0bfc Reserved */ +#define L2CC_FLSTRT_OFFSET 0x0c00 /* Address filter start */ +#define L2CC_FLEND_OFFSET 0x0c04 /* Address filter end */ + /* 0x0c08-0x0f3c Reserved */ +#define L2CC_DCR_OFFSET 0x0f40 /* Debug Control Register */ + /* 0x0f44-0x0f5c Reserved */ +#define L2CC_PCR_OFFSET 0x0f60 /* Prefetch Control Register */ + /* 0x0f64-0x0f7c Reserved */ +#define L2CC_POWCR_OFFSET 0x0f80 /* Power Control Register */ + +/* L2CC Register Addresses **********************************************************/ + +#define L2CC_IDR (L2CC_VBASE+L2CC_IDR_OFFSET) +#define L2CC_TYPR (L2CC_VBASE+L2CC_TYPR_OFFSET) +#define L2CC_CR (L2CC_VBASE+L2CC_CR_OFFSET) +#define L2CC_ACR (L2CC_VBASE+L2CC_ACR_OFFSET) +#define L2CC_TRCR (L2CC_VBASE+L2CC_TRCR_OFFSET) +#define L2CC_DRCR (L2CC_VBASE+L2CC_DRCR_OFFSET) +#define L2CC_ECR (L2CC_VBASE+L2CC_ECR_OFFSET) +#define L2CC_ECFGR1 (L2CC_VBASE+L2CC_ECFGR1_OFFSET) +#define L2CC_ECFGR0 (L2CC_VBASE+L2CC_ECFGR0_OFFSET) +#define L2CC_EVR1 (L2CC_VBASE+L2CC_EVR1_OFFSET) +#define L2CC_EVR0 (L2CC_VBASE+L2CC_EVR0_OFFSET) +#define L2CC_IMR (L2CC_VBASE+L2CC_IMR_OFFSET) +#define L2CC_MISR (L2CC_VBASE+L2CC_MISR_OFFSET) +#define L2CC_RISR (L2CC_VBASE+L2CC_RISR_OFFSET) +#define L2CC_ICR (L2CC_VBASE+L2CC_ICR_OFFSET) +#define L2CC_CSR (L2CC_VBASE+L2CC_CSR_OFFSET) +#define L2CC_IPALR (L2CC_VBASE+L2CC_IPALR_OFFSET) +#define L2CC_IWR (L2CC_VBASE+L2CC_IWR_OFFSET) +#define L2CC_CPALR (L2CC_VBASE+L2CC_CPALR_OFFSET) +#define L2CC_CIR (L2CC_VBASE+L2CC_CIR_OFFSET) +#define L2CC_CWR (L2CC_VBASE+L2CC_CWR_OFFSET) +#define L2CC_CIPALR (L2CC_VBASE+L2CC_CIPALR_OFFSET) +#define L2CC_CIIR (L2CC_VBASE+L2CC_CIIR_OFFSET) +#define L2CC_CIWR (L2CC_VBASE+L2CC_CIWR_OFFSET) +#define L2CC_DLKR(n) (L2CC_VBASE+L2CC_DLKR_OFFSET(n)) +#define L2CC_ILKR(n) (L2CC_VBASE+L2CC_ILKR_OFFSET(n)) + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN (L2CC_VBASE+L2CC_LKLN_OFFSET) +# define L2CC_UNLKW (L2CC_VBASE+L2CC_UNLKW_OFFSET) +#endif + +#define L2CC_FLSTRT (L2CC_VBASE+L2CC_FLSTRT_OFFSET) +#define L2CC_FLEND (L2CC_VBASE+L2CC_FLEND_OFFSET) +#define L2CC_DCR (L2CC_VBASE+L2CC_DCR_OFFSET) +#define L2CC_PCR (L2CC_VBASE+L2CC_PCR_OFFSET) +#define L2CC_POWCR (L2CC_VBASE+L2CC_POWCR_OFFSET) + +/* L2CC Register Bit Definitions ****************************************************/ + +/* Cache ID Register (32-bit ID) */ + +#define L2CC_IDR_REV_MASK 0x0000003f +# define L2CC_IDR_REV_R0P0 0x00000000 +# define L2CC_IDR_REV_R1P0 0x00000002 +# define L2CC_IDR_REV_R2P0 0x00000004 +# define L2CC_IDR_REV_R3P0 0x00000005 +# define L2CC_IDR_REV_R3P1 0x00000006 +# define L2CC_IDR_REV_R3P2 0x00000008 + +/* Cache Type Register */ + +#define L2CC_TYPR_IL2ASS (1 << 6) /* Bit 6: Instruction L2 Cache Associativity */ +#define L2CC_TYPR_IL2WSIZE_SHIFT (8) /* Bits 8-10: Instruction L2 Cache Way Size */ +#define L2CC_TYPR_IL2WSIZE_MASK (7 << L2CC_TYPR_IL2WSIZE_SHIFT) +# define L2CC_TYPR_IL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_IL2WSIZE_SHIFT) +#define L2CC_TYPR_DL2ASS (1 << 18) /* Bit 18: Data L2 Cache Associativity */ +#define L2CC_TYPR_DL2WSIZE_SHIFT (20) /* Bits 20-22: Data L2 Cache Way Size */ +#define L2CC_TYPR_DL2WSIZE_MASK (7 << L2CC_TYPR_DL2WSIZE_SHIFT) +# define L2CC_TYPR_DL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_DL2WSIZE_SHIFT) + +/* Control Register */ + +#define L2CC_CR_L2CEN (1 << 0) /* Bit 0: L2 Cache Enable */ + +/* Auxiliary Control Register */ + +#define L2CC_ACR_FLZE (1 << 0) /* Bit 0: Full line zero enable */ +#define L2CC_ACR_HPSO (1 << 10) /* Bit 10: High Priority for SO and Dev Reads Enable */ +#define L2CC_ACR_SBDLE (1 << 11) /* Bit 11: Store Buffer Device Limitation Enable */ +#define L2CC_ACR_EXCC (1 << 12) /* Bit 12: Exclusive Cache Configuration */ +#define L2CC_ACR_SAIE (1 << 13) /* Bit 13: Shared Attribute Invalidate Enable */ +#define L2CC_ACR_ASS (1 << 16) /* Bit 16: Associativity */ +#define L2CC_ACR_WAYSIZE_SHIFT (17) /* Bits 17-19: Way Size */ +#define L2CC_ACR_WAYSIZE_MASK (7 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_16KB (1 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_32KB (2 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_64KB (3 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_128KB (4 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_256KB (5 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_512KB (6 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_EMBEN (1 << 20) /* Bit 20: Event Monitor Bus Enable */ +#define L2CC_ACR_PEN (1 << 21) /* Bit 21: Parity Enable */ +#define L2CC_ACR_SAOEN (1 << 22) /* Bit 22: Shared Attribute Override Enable */ +#define L2CC_ACR_FWA_SHIFT (23) /* Bits 23-24: Force Write Allocate */ +#define L2CC_ACR_FWA_MASK (3 << L2CC_ACR_FWA_SHIFT) +# define L2CC_ACR_FWA_AWCACHE (0 << L2CC_ACR_FWA_SHIFT) /* Use AWCACHE attributes for WA */ +# define L2CC_ACR_FWA_NOALLOC (1 << L2CC_ACR_FWA_SHIFT) /* No allocate */ +# define L2CC_ACR_FWA_OVERRIDE (2 << L2CC_ACR_FWA_SHIFT) /* Override AWCACHE attributes */ +# define L2CC_ACR_FWA_MAPPED (3 << L2CC_ACR_FWA_SHIFT) /* Internally mapped to 00 */ +#define L2CC_ACR_CRPOL (1 << 25) /* Bit 25: Cache Replacement Policy */ +#define L2CC_ACR_NSLEN (1 << 26) /* Bit 26: Non-Secure Lockdown Enable */ +#define L2CC_ACR_NSIAC (1 << 27) /* Bit 27: Non-Secure Interrupt Access Control */ +#define L2CC_ACR_DPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_ACR_IPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_ACR_EBRESP (1 << 30) /* Bit 30: Early BRESP enable */ + +#define L2CC_ACR_SBZ (0x8000c1fe) + +/* Tag RAM Control Register */ + +#define L2CC_TRCR_TSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_TRCR_TSETLAT_MASK (7 << L2CC_TRCR_TSETLAT_SHIFT) +# define L2CC_TRCR_TSETLAT(n) ((uint32_t)(n) << L2CC_TRCR_TSETLAT_SHIFT) +#define L2CC_TRCR_TRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_TRCR_TRDLAT_MASK (7 << L2CC_TRCR_TRDLAT_SHIFT) +# define L2CC_TRCR_TRDLAT(n) ((uint32_t)(n) << L2CC_TRCR_TRDLAT_SHIFT) +#define L2CC_TRCR_TWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_TRCR_TWRLAT_MASK (7 << L2CC_TRCR_TWRLAT_SHIFT) +# define L2CC_TRCR_TWRLAT(n) ((uint32_t)(n) << L2CC_TRCR_TWRLAT_SHIFT) + +/* Data RAM Control Register */ + +#define L2CC_DRCR_DSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_DRCR_DSETLAT_MASK (7 << L2CC_DRCR_DSETLAT_SHIFT) +# define L2CC_DRCR_DSETLAT(n) ((uint32_t)(n) << L2CC_DRCR_DSETLAT_SHIFT) +#define L2CC_DRCR_DRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_DRCR_DRDLAT_MASK (7 << L2CC_DRCR_DRDLAT_SHIFT) +# define L2CC_DRCR_DRDLAT(n) ((uint32_t)(n) << L2CC_DRCR_DRDLAT_SHIFT) +#define L2CC_DRCR_DWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_DRCR_DWRLAT_MASK (7 << L2CC_DRCR_DWRLAT_SHIFT) +# define L2CC_DRCR_DWRLAT(n) ((uint32_t)(n) << L2CC_DRCR_DWRLAT_SHIFT) + +/* Event Counter Control Register */ + +#define L2CC_ECR_EVCEN (1 << 0) /* Bit 0: Event Counter Enable */ +#define L2CC_ECR_EVC0RST (1 << 1) /* Bit 1: Event Counter 0 Reset */ +#define L2CC_ECR_EVC1RST (1 << 2) /* Bit 2: Event Counter 1 Reset */ + +/* Event Counter 1 Configuration Register */ + + +#define L2CC_ECFGR1_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR1_EIGEN_MASK (3 << L2CC_ECFGR1_EIGEN_SHIFT) +# define L2CC_ECFGR1_EIGEN_INTDIS (0 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables (default) */ +# define L2CC_ECFGR1_EIGEN_INTENINCR (1 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Increment condition */ +# define L2CC_ECFGR1_EIGEN_INTENOVER (2 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Overflow condition */ +# define L2CC_ECFGR1_EIGEN_INTGENDIS (3 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR1_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR1_ESRC_MASK (15 << L2CC_ECFGR1_ESRC_SHIFT) +# define L2CC_ECFGR1_ESRC_CNTDIS (0 << L2CC_ECFGR1_ESRC_SHIFT) /* Counter Disabled */ +# define L2CC_ECFGR1_ESRC_CO (1 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is CO */ +# define L2CC_ECFGR1_ESRC_DRHIT (2 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRHIT */ +# define L2CC_ECFGR1_ESRC_DRREQ (3 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRREQ */ +# define L2CC_ECFGR1_ESRC_DWHIT (4 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWHIT */ +# define L2CC_ECFGR1_ESRC_DWREQ (5 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWREQ */ +# define L2CC_ECFGR1_ESRC_DWTREQ (6 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWTREQ */ +# define L2CC_ECFGR1_ESRC_IRHIT (7 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRHIT */ +# define L2CC_ECFGR1_ESRC_IRREQ (8 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRREQ */ +# define L2CC_ECFGR1_ESRC_WA (9 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is WA */ +# define L2CC_ECFGR1_ESRC_IPFALLOC (10 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IPFALLOC */ +# define L2CC_ECFGR1_ESRC_EPFHIT (11 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFHIT */ +# define L2CC_ECFGR1_ESRC_EPFALLOC (12 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFALLOC */ +# define L2CC_ECFGR1_ESRC_SRRCVD (13 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRRCVD */ +# define L2CC_ECFGR1_ESRC_SRCONF (14 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRCONF */ +# define L2CC_ECFGR1_ESRC_EPFRCVD (15 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 0 Configuration Register */ + +#define L2CC_ECFGR0_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR0_EIGEN_MASK (3 << L2CC_ECFGR0_EIGEN_SHIFT) +# define L2CC_ECFGR0_EIGEN_INTDIS (0 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables (default) */ +# define L2CC_ECFGR0_EIGEN_INTENINCR (1 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Increment condition */ +# define L2CC_ECFGR0_EIGEN_INTENOVER (2 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Overflow condition */ +# define L2CC_ECFGR0_EIGEN_INTGENDIS (3 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR0_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR0_ESRC_MASK (15 << L2CC_ECFGR0_ESRC_SHIFT) +# define L2CC_ECFGR0_ESRC_CNTDIS (0 << L2CC_ECFGR0_ESRC_SHIFT) /* Counter Disabled */ +# define L2CC_ECFGR0_ESRC_CO (1 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is CO */ +# define L2CC_ECFGR0_ESRC_DRHIT (2 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRHIT */ +# define L2CC_ECFGR0_ESRC_DRREQ (3 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRREQ */ +# define L2CC_ECFGR0_ESRC_DWHIT (4 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWHIT */ +# define L2CC_ECFGR0_ESRC_DWREQ (5 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWREQ */ +# define L2CC_ECFGR0_ESRC_DWTREQ (6 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWTREQ */ +# define L2CC_ECFGR0_ESRC_IRHIT (7 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRHIT */ +# define L2CC_ECFGR0_ESRC_IRREQ (8 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRREQ */ +# define L2CC_ECFGR0_ESRC_WA (9 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is WA */ +# define L2CC_ECFGR0_ESRC_IPFALLOC (10 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IPFALLOC */ +# define L2CC_ECFGR0_ESRC_EPFHIT (11 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFHIT */ +# define L2CC_ECFGR0_ESRC_EPFALLOC (12 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFALLOC */ +# define L2CC_ECFGR0_ESRC_SRRCVD (13 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRRCVD */ +# define L2CC_ECFGR0_ESRC_SRCONF (14 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRCONF */ +# define L2CC_ECFGR0_ESRC_EPFRCVD (15 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 1 Value Register (32-bit value) */ +/* Event Counter 0 Value Register (32-bit value) */ + +/* Interrupt Mask Register, Masked Interrupt Status Register, Raw Interrupt Status + * Register, and Interrupt Clear Register. + */ + +#define L2CC_INT_ECNTR (1 << 0) /* Bit 0: Event Counter 1/0 Overflow Increment */ +#define L2CC_INT_PARRT (1 << 1) /* Bit 1: Parity Error on L2 Tag RAM, Read */ +#define L2CC_INT_PARRD (1 << 2) /* Bit 2: Parity Error on L2 Data RAM, Read */ +#define L2CC_INT_ERRWT (1 << 3) /* Bit 3: Error on L2 Tag RAM, Write */ +#define L2CC_INT_ERRWD (1 << 4) /* Bit 4: Error on L2 Data RAM, Write */ +#define L2CC_INT_ERRRT (1 << 5) /* Bit 5: Error on L2 Tag RAM, Read */ +#define L2CC_INT_ERRRD (1 << 6) /* Bit 6: Error on L2 Data RAM, Read */ +#define L2CC_INT_SLVERR (1 << 7) /* Bit 7: SLVERR from L3 Memory */ +#define L2CC_INT_DECERR (1 << 8) /* Bit 8: DECERR from L3 Memory */ + +/* Cache Synchronization Register */ + +#define L2CC_CSR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ + +/* Invalidate Physical Address Line Register */ + +#define L2CC_IPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_IPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_IPALR_IDX_MASK (0x1ff << L2CC_IPALR_IDX_SHIFT) +# define L2CC_IPALR_IDX(n) ((uint32_t)(n) << L2CC_IPALR_IDX_SHIFT) +#define L2CC_IPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_IPALR_TAG_MASK (0x3ffff << L2CC_IPALR_TAG_SHIFT) +# define L2CC_IPALR_TAG(n) ((uint32_t)(n) << L2CC_IPALR_TAG_SHIFT) + +/* Invalidate Way Register */ + +#define L2CC_IWR_WAY(n) (1 << (n)) /* Bist 0-7: Invalidate Way Number n, n=0..7 */ +# define L2CC_IWR_WAY0 (1 << 0) /* Bit 0: Invalidate Way Number 0 */ +# define L2CC_IWR_WAY1 (1 << 1) /* Bit 1: Invalidate Way Number 1 */ +# define L2CC_IWR_WAY2 (1 << 2) /* Bit 2: Invalidate Way Number 2 */ +# define L2CC_IWR_WAY3 (1 << 3) /* Bit 3: Invalidate Way Number 3 */ +# define L2CC_IWR_WAY4 (1 << 4) /* Bit 4: Invalidate Way Number 4 */ +# define L2CC_IWR_WAY5 (1 << 5) /* Bit 5: Invalidate Way Number 5 */ +# define L2CC_IWR_WAY6 (1 << 6) /* Bit 6: Invalidate Way Number 6 */ +# define L2CC_IWR_WAY7 (1 << 7) /* Bit 7: Invalidate Way Number 7 */ + +/* Clean Physical Address Line Register */ + +#define L2CC_CPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CPALR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CPALR_IDX_MASK (0x1ff << L2CC_CPALR_IDX_SHIFT) +# define L2CC_CPALR_IDX(n) ((uint32_t)(n) << L2CC_CPALR_IDX_SHIFT) +#define L2CC_CPALR_TAG_SHIFT (14) /* Bits 14-31: Tag number */ +#define L2CC_CPALR_TAG_MASK (0x3ffff << L2CC_CPALR_TAG_SHIFT) +# define L2CC_CPALR_TAG(n) ((uint32_t)(n) << L2CC_CPALR_TAG_SHIFT) + +/* Clean Index Register */ + +#define L2CC_CIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CIR_IDX_MASK (0x1ff << L2CC_CIR_IDX_SHIFT) +# define L2CC_CIR_IDX(n) ((uint32_t)(n) << L2CC_CIR_IDX_SHIFT) +#define L2CC_CIR_WAY_SHIFT (28) /* Bits 28-30: Way number */ +#define L2CC_CIR_WAY_MASK (7 << L2CC_CIR_WAY_SHIFT) +# define L2CC_CIR_WAY(n) ((uint32_t)(n) << L2CC_CIR_WAY_SHIFT) + +/* Clean Way Register */ + +#define L2CC_CWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Way Number n, n=0..7 */ +# define L2CC_CWR_WAY0 (1 << 0) /* Bit 0: Clean Way Number 0 */ +# define L2CC_CWR_WAY1 (1 << 1) /* Bit 1: Clean Way Number 1 */ +# define L2CC_CWR_WAY2 (1 << 2) /* Bit 2: Clean Way Number 2 */ +# define L2CC_CWR_WAY3 (1 << 3) /* Bit 3: Clean Way Number 3 */ +# define L2CC_CWR_WAY4 (1 << 4) /* Bit 4: Clean Way Number 4 */ +# define L2CC_CWR_WAY5 (1 << 5) /* Bit 5: Clean Way Number 5 */ +# define L2CC_CWR_WAY6 (1 << 6) /* Bit 6: Clean Way Number 6 */ +# define L2CC_CWR_WAY7 (1 << 7) /* Bit 7: Clean Way Number 7 */ + +/* Clean Invalidate Physical Address Line Register */ + +#define L2CC_CIPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIPALR_IDX_MASK (0x1ff << L2CC_CIPALR_IDX_SHIFT) +# define L2CC_CIPALR_IDX(n) ((uint32_t)(n) << L2CC_CIPALR_IDX_SHIFT) +#define L2CC_CIPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_CIPALR_TAG_MASK (0x3ffff << L2CC_CIPALR_TAG_SHIFT) +# define L2CC_CIPALR_TAG(n) ((uint32_t)(n) << L2CC_CIPALR_TAG_SHIFT) + +/* Clean Invalidate Index Register */ + +#define L2CC_CIIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIIR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIIR_IDX_MASK (0x1ff << L2CC_CIIR_IDX_SHIFT) +# define L2CC_CIIR_IDX(n) ((uint32_t)(n) << L2CC_CIIR_IDX_SHIFT) +#define L2CC_CIIR_WAY_SHIFT (28) /* Bits 28-30: Way Number */ +#define L2CC_CIIR_WAY_MASK (7 << L2CC_CIIR_WAY_SHIFT) +# define L2CC_CIIR_WAY(n) ((uint32_t)(n) << L2CC_CIIR_WAY_SHIFT) + +/* Clean Invalidate Way Register */ + +#define L2CC_CIWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Invalidate Way Number n, n=1..7 */ +# define L2CC_CIWR_WAY0 (1 << 0) /* Bit 0: Clean Invalidate Way Number 0 */ +# define L2CC_CIWR_WAY1 (1 << 1) /* Bit 1: Clean Invalidate Way Number 1 */ +# define L2CC_CIWR_WAY2 (1 << 2) /* Bit 2: Clean Invalidate Way Number 2 */ +# define L2CC_CIWR_WAY3 (1 << 3) /* Bit 3: Clean Invalidate Way Number 3 */ +# define L2CC_CIWR_WAY4 (1 << 4) /* Bit 4: Clean Invalidate Way Number 4 */ +# define L2CC_CIWR_WAY5 (1 << 5) /* Bit 5: Clean Invalidate Way Number 5 */ +# define L2CC_CIWR_WAY6 (1 << 6) /* Bit 6: Clean Invalidate Way Number 6 */ +# define L2CC_CIWR_WAY7 (1 << 7) /* Bit 7: Clean Invalidate Way Number 7 */ + +/* Data Lockdown Register */ + +#define L2CC_DLKR_DLK(n) (1 << (n)) /* Bits 0-7: Data Lockdown in Way Number n, n=0..7 */ +# define L2CC_DLKR_DLK0 (1 << 0) /* Bit 0: Data Lockdown in Way Number 0 */ +# define L2CC_DLKR_DLK1 (1 << 1) /* Bit 1: Data Lockdown in Way Number 1 */ +# define L2CC_DLKR_DLK2 (1 << 2) /* Bit 2: Data Lockdown in Way Number 2 */ +# define L2CC_DLKR_DLK3 (1 << 3) /* Bit 3: Data Lockdown in Way Number 3 */ +# define L2CC_DLKR_DLK4 (1 << 4) /* Bit 4: Data Lockdown in Way Number 4 */ +# define L2CC_DLKR_DLK5 (1 << 5) /* Bit 5: Data Lockdown in Way Number 5 */ +# define L2CC_DLKR_DLK6 (1 << 6) /* Bit 6: Data Lockdown in Way Number 6 */ +# define L2CC_DLKR_DLK7 (1 << 7) /* Bit 7: Data Lockdown in Way Number 7 */ + +/* Instruction Lockdown Register */ + +#define L2CC_ILKR_ILK(n) (1 << (n)) /* Bits 0-7: Instruction Lockdown in Way Number n, n=0..7 */ +# define L2CC_ILKR_ILK0 (1 << 0) /* Bit 0: Instruction Lockdown in Way Number 0 */ +# define L2CC_ILKR_ILK1 (1 << 1) /* Bit 1: Instruction Lockdown in Way Number 1 */ +# define L2CC_ILKR_ILK2 (1 << 2) /* Bit 2: Instruction Lockdown in Way Number 2 */ +# define L2CC_ILKR_ILK3 (1 << 3) /* Bit 3: Instruction Lockdown in Way Number 3 */ +# define L2CC_ILKR_ILK4 (1 << 4) /* Bit 4: Instruction Lockdown in Way Number 4 */ +# define L2CC_ILKR_ILK5 (1 << 5) /* Bit 5: Instruction Lockdown in Way Number 5 */ +# define L2CC_ILKR_ILK6 (1 << 6) /* Bit 6: Instruction Lockdown in Way Number 6 */ +# define L2CC_ILKR_ILK7 (1 << 7) /* Bit 7: Instruction Lockdown in Way Number 7 */ + +/* Lock Line Enable Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_ENABLE (1 << 0) /* Bit 0: Lockdown by line enable */ +#endif + +/* Unlock Way Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_UNLKW_WAY_SHIFT (0) /* Bits 0-15: Unlock line for corresponding way */ +# define L2CC_UNLKW_WAY_MASK (0xffff << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_SET(n) ((uint32_t)(n) << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_BIT(n) ((1 << (n)) << L2CC_UNLKW_WAY_SHIFT) +#endif + +/* Address filter start */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLSTRT_ENABLE (1 << 0) /* Bit 0: Address filter enable */ +# define L2CC_FLSTRT_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Address filter end */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLEND_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Debug Control Register */ + +#define L2CC_DCR_DCL (1 << 0) /* Bit 0: Disable Cache Linefill */ +#define L2CC_DCR_DWB (1 << 1) /* Bit 1: Disable Write-back, Force Write-through */ +#define L2CC_DCR_SPNIDEN (1 << 2) /* Bit 2: SPNIDEN Value */ + +/* Prefetch Control Register */ + +#define L2CC_PCR_SHIFT (0) /* Bits 0-4: Prefetch Offset */ +#define L2CC_PCR_MASK (31 << L2CC_PCR_SHIFT) +# define L2CC_PCR_PREFETCH(n) ((uint32_t)(n) << L2CC_PCR_SHIFT) +#define L2CC_PCR_NSIDEN (1 << 21) /* Bit 21: Not Same ID on Exclusive Sequence Enable */ +#define L2CC_PCR_IDLEN (1 << 23) /* Bit 23: INCR Double Linefill Enable */ +#define L2CC_PCR_PDEN (1 << 24) /* Bit 24: Prefetch Drop Enable */ +#define L2CC_PCR_DLFWRDIS (1 << 27) /* Bit 27: Double Linefill on WRAP Read Disable */ +#define L2CC_PCR_DATPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_PCR_INSPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_PCR_DLEN (1 << 30) /* Bit 30: Double Linefill Enable */ + +/* Power Control Register */ + +#define L2CC_POWCR_STBYEN (1 << 0) /* Bit 0: Standby Mode Enable */ +#define L2CC_POWCR_DCKGATEN (1 << 1) /* Bit 1: Dynamic Clock Gating Enable */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_L2CC_PL310_H */ diff --git a/arch/arm/src/armv7-a/mmu.h b/arch/arm/src/armv7-a/mmu.h new file mode 100644 index 0000000000000000000000000000000000000000..9ce8280b73232ba793c8a0d11ed0e958f41aeb77 --- /dev/null +++ b/arch/arm/src/armv7-a/mmu.h @@ -0,0 +1,1465 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/mmu.h + * CP15 MMU register definitions + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © + * 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_MMU_H +#define __ARCH_ARM_SRC_ARMV7_A_MMU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include "chip.h" +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_PAGING) || defined(CONFIG_ARCH_ADDRENV) + +/* Sanity check -- we cannot be using a ROM page table and supporting on- + * demand paging. + */ + +#ifdef CONFIG_ARCH_ROMPGTABLE +# error "Cannot support both CONFIG_PAGING/CONFIG_ARCH_ADDRENV and CONFIG_ARCH_ROMPGTABLE" +#endif +#endif /* CONFIG_PAGING */ + +/* MMU CP15 Register Bit Definitions ************************************************/ +/* Reference: Cortex-A5™ MPCore Paragraph 6.7, "MMU software accessible registers." */ + +/* TLB Type Register TLB Type Register + * + * The Translation Lookaside Buffer (TLB) Type Register, TLBTR, returns the number of + * lockable entries for the TLB. The Cortex-A5 MPCore processor does not implement + * this feature, so this register always RAZ. + */ + +/* System Control Register (SCTLR). see cstlr.h */ +/* Non-secure Access Control Register (NSACR). See cstlr.h */ + +/* Translation Table Base Register 0 (TTBR0)*/ + +#define TTBR0_IRGN1 (1 << 0) /* Bit 0: Inner cacheability IRGN[1] (MP extensions) */ +#define TTBR0_C (1 << 0) /* Bit 0: Inner cacheability for table walk */ +#define TTBR0_S (1 << 1) /* Bit 1: Translation table walk */ + /* Bit 2: Reserved */ +#define TTBR0_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ +#define TTBR0_RGN_MASK (3 << TTBR0_RGN_SHIFT) +# define TTBR0_RGN_NONE (0 << TTBR0_RGN_SHIFT) /* Non-cacheable */ +# define TTBR0_RGN_WBWA (1 << TTBR0_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ +# define TTBR0_RGN_WT (2 << TTBR0_RGN_SHIFT) /* Write-Through */ +# define TTBR0_RGN_WB (3 << TTBR0_RGN_SHIFT) /* Write-Back */ +#define TTBR0_NOS (1 << 5) /* Bit 5: Not Outer Shareable bit */ +#define TTBR0_IRGN0 (1 << 6) /* Bit 6: Inner cacheability IRGN[0] (MP extensions) */ + /* Bits 7-n: Reserved, n=7-13 */ +#define _TTBR0_LOWER(n) (0xffffffff << (n)) + /* Bits (n+1)-31: Translation table base 0 */ +#define TTBR0_BASE_MASK(n) (~_TTBR0_LOWER(n)) + +/* Translation Table Base Register 1 (TTBR1) */ + +#define TTBR1_IRGN1 (1 << 0) /* Bit 0: Inner cacheability IRGN[1] (MP extensions) */ +#define TTBR1_C (1 << 0) /* Bit 0: Inner cacheability for table walk */ +#define TTBR1_S (1 << 1) /* Bit 1: Translation table walk */ + /* Bit 2: Reserved */ +#define TTBR1_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ +#define TTBR1_RGN_MASK (3 << TTBR1_RGN_SHIFT) +# define TTBR1_RGN_NONE (0 << TTBR1_RGN_SHIFT) /* Non-cacheable */ +# define TTBR1_RGN_WBWA (1 << TTBR1_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ +# define TTBR1_RGN_WT (2 << TTBR1_RGN_SHIFT) /* Write-Through */ +# define TTBR1_RGN_WB (3 << TTBR1_RGN_SHIFT) /* Write-Back */ +#define TTBR1_NOS (1 << 5) /* Bit 5: Not Outer Shareable bit */ +#define TTBR1_IRGN0 (1 << 6) /* Bit 6: Inner cacheability IRGN[0] (MP extensions) */ + /* Bits 7-13: Reserved */ +#define TTBR1_BASE_SHIFT (14) /* Bits 14-31: Translation table base 1 */ +#define TTBR1_BASE_MASK (0xffffc000) + +/* Translation Table Base Control Register (TTBCR) */ + +#define TTBCR_N_SHIFT (0) /* Bits 0-2: Boundary size of TTBR0 */ +#define TTBCR_N_MASK (7 << TTBCR_N_SHIFT) +# define TTBCR_N_16KB (0 << TTBCR_N_SHIFT) /* Reset value */ +# define TTBCR_N_8KB (1 << TTBCR_N_SHIFT) +# define TTBCR_N_4KB (2 << TTBCR_N_SHIFT) +# define TTBCR_N_2KB (3 << TTBCR_N_SHIFT) +# define TTBCR_N_1KB (4 << TTBCR_N_SHIFT) +# define TTBCR_N_512B (5 << TTBCR_N_SHIFT) +# define TTBCR_N_256B (6 << TTBCR_N_SHIFT) +# define TTBCR_N_128B (7 << TTBCR_N_SHIFT) + /* Bit 3: Reserved */ +#define TTBCR_PD0 (1 << 4) /* Bit 4: Translation table walk on a TLB miss w/TTBR0 */ +#define TTBCR_PD1 (1 << 5) /* Bit 5: Translation table walk on a TLB miss w/TTBR1 */ + /* Bits 6-31: Reserved */ + +/* Domain Access Control Register (DACR) */ + +#define DACR_SHIFT(n) ((n) << 1) /* Domain n, n=0-15 */ +#define DACR_MASK(n) (3 << DACR_SHIFT(n)) +# define DACR_NONE(n) (0 << DACR_SHIFT(n)) /* Any access generates a domain fault */ +# define DACR_CLIENT(n) (1 << DACR_SHIFT(n)) /* Accesses checked against permissions TLB */ +# define DACR_MANAGER(n) (3 << DACR_SHIFT(n)) /* Accesses are not checked */ + +/* Data Fault Status Register (DFSR) */ + +#define DFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of exception generated (w/EXT and FS) */ +#define DFSR_STATUS_MASK (15 << DFSR_STATUS_SHIFT) +#define DFSR_DOMAIN_SHIFT (4) /* Bits 4-7: Domain accessed when a data fault occurred */ +#define DFSR_DOMAIN_MASK (15 << DFSR_STATUS_MASK) + /* Bits 8-9: Reserved */ +#define DFSR_FS (1 << 10) /* Bit 10: Part of the STATUS field */ +#define DFSR_WNR (1 << 11) /* Bit 11: Not read and write */ +#define DFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ + /* Bits 13-31: Reserved */ + +/* Instruction Fault Status Register (IFSR) */ + +#define IFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of fault generated (w/EXT and FS) */ +#define IFSR_STATUS_MASK (15 << IFSR_STATUS_SHIFT) + /* Bits 4-9: Reserved */ +#define IFSR_S (1 << 10) /* Bit 10: Part of the STATUS field */ + /* Bits 11: Reserved */ +#define IFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ + /* Bits 13-31: Reserved */ + +/* Data Fault Address Register(DFAR). Holds the MVA of the faulting address when a + * synchronous fault occurs + * + * Instruction Fault Address Register(IFAR). Holds the MVA of the faulting address + * of the instruction that caused a prefetch abort. + */ + +/* TLB operations. + * + * CP15 Register: TLBIALLIS + * Description: Invalidate entire Unified TLB Inner Shareable + * Register Format: SBZ + * Instruction: MCR p15, 0, , c8, c3, 0 + * CP15 Register: TLBIMVAIS + * Description: Invalidate Unified TLB entry by VA Inner Shareable + * Register Format: VA/ASID + * Instruction: MCR p15, 0, , c8, c3, 1 + * CP15 Register: TLBIASIDIS + * Description: Invalidate Unified TLB entry by ASID match Inner + * Shareable + * Register Format: ASID + * Instruction: MCR p15, 0, , c8, c3, 2 + * CP15 Register: TLBIMVAAIS + * Description: Invalidate Unified TLB entry by VA all ASID Inner + * Shareable + * Register Format: VA + * Instruction: MCR p15, 0, , c8, c3, 3 + * CP15 Register: TLBIALL + * Description: Invalidate entire Unified TLB + * Register Format: Ignored + * Instruction: MCR p15, 0, , c8, c7, 0 + * CP15 Register: TLBIMVA + * Description: Invalidate Unified TLB by VA + * Register Format: VA/ASID + * Instruction: MCR p15, 0, , c8, c7, 1 + * CP15 Register: TLBIASID + * Description: Invalidate TLB entries by ASID Match + * Register Format: ASID + * MCR p15, 0, , c8, c7, 2 + * CP15 Register: TLBIMVAA + * Description: Invalidate TLB entries by VA All ASID + * Register Format: VA + * Instruction: MCR p15, 0, , c8, c7, 3 + */ + +#define TLB_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ +#define TLB_ASID_MASK (0xff << TLB_ASID_SHIFT) +#define TLB_SBZ_SHIFT (8) /* Bits 8-11: SBZ */ +#define TLB_SBZ_MASK (15 << TLB_SBZ_SHIFT) +#define TLB_VA_MASK (0xfffff000) /* Bits 12-31: Virtual address */ + +/* Primary Region Remap Register (PRRR) */ +/* Normal Memory Remap Register (NMRR) */ + +/* TLB Hitmap Register (TLBHR) */ + +#define TLBHR_4KB (1 << 0) /* Bit 0: 4KB pages are present in the TLB */ +#define TLBHR_16KB (1 << 1) /* Bit 1: 16KB pages are present in the TLB */ +#define TLBHR_1MB (1 << 2) /* Bit 2: 1MB sections are present in the TLB */ +#define TLBHR_16MB (1 << 3) /* Bit 3: 16MB supersections are present in the TLB */ + /* Bits 4-31: Reserved */ + +/* Context ID Register (CONTEXTIDR). See cstlr.h */ + +/* Translation Table Definitions ****************************************************/ +/* Hardware translation table definitions. Only the "short descriptor format" is + * supported. + * + * Level 1 Descriptor (PMD) + * + * Common definitions that apply to all L1 table entry types + */ + +#define PMD_TYPE_SHIFT (0) /* Bits: 1:0: Type of mapping */ +#define PMD_TYPE_MASK (3 << PMD_TYPE_SHIFT) +# define PMD_TYPE_FAULT (0 << PMD_TYPE_SHIFT) /* None */ +# define PMD_TYPE_PTE (1 << PMD_TYPE_SHIFT) /* Page table */ +# define PMD_TYPE_SECT (2 << PMD_TYPE_SHIFT) /* Section or supersection */ +# define PMD_TYPE_PXN (3 << PMD_TYPE_SHIFT) /* PXN Section or supersection */ + /* Bits 2-31: Depend on the mapping type */ + +/* Level 1 Fault Translation Table Format. + * + * Invalid or fault entry. "The associated VA is unmapped, and any attempt to + * access it generates a Translation fault. Software can use bits[31:2] of the + * descriptor for its own purposes, because the hardware ignores + * these bits." + */ + +/* Level 1 Page Table Translation Table Format. + * + * Page table. "The descriptor gives the address of a second-level translation + * table, that specifies the mapping of the associated 1MByte VA range." + */ + + /* Bits 0-1: Type of mapping */ +#define PMD_PTE_PXN (1 << 2) /* Bit 2: Privileged execute-never bit */ +#define PMD_PTE_NS (1 << 3) /* Bit 3: Non-secure bit */ + /* Bit 4: Should be zero (SBZ) */ +#define PMD_PTE_DOM_SHIFT (5) /* Bits 5-8: Domain */ +#define PMD_PTE_DOM_MASK (15 << PMD_PTE_DOM_SHIFT) +# define PMD_PTE_DOM(n) ((n) << PMD_PTE_DOM_SHIFT) + /* Bit 9: Not implemented */ +#define PMD_PTE_PADDR_MASK (0xfffffc00) /* Bits 10-31: Page table base address */ + +/* Level 1 Section/Supersection Descriptor. + * + * Section or Supersection. "The descriptor gives the base address of the + * Section or Supersection. Bit[18] determines whether the entry describes a + * Section or a Supersection. If the implementation supports the PXN + * attribute, this encoding also defines the PXN bit as 0. Section descriptors + * allow fast, single level mapping between 1Mb address regions." + + * PXN Section or Supersection. "If an implementation supports the PXN attribute, + * this encoding is identical..., except that it defines the PXN bit as 1. + * + * "If the implementation does not support the PXN attribute, an attempt to access + * the associated VA generates a Translation fault. On an implementation that + * does not support the PXN attribute, this encoding must not be used." + */ + +/* Section */ + +#define PMD_SECT_PXN (1 << 0) /* Bit 0: Privileged execute-never bit */ + /* Bits 0-1: Type of mapping */ +#define PMD_SECT_B (1 << 2) /* Bit 2: Bufferable bit */ +#define PMD_SECT_C (1 << 3) /* Bit 3: Cacheable bit */ +#define PMD_SECT_XN (1 << 4) /* Bit 4: Execute-never bit */ +#define PMD_SECT_DOM_SHIFT (5) /* Bits 5-8: Domain */ +#define PMD_SECT_DOM_MASK (15 << PMD_SECT_DOM_SHIFT) +# define PMD_SECT_DOM(n) ((n) << PMD_SECT_DOM_SHIFT) + /* Bit 9: Implementation defined */ +#define PMD_SECT_AP_SHIFT (10) /* Bits 10-11: Access Permissions bits AP[0:1] */ +#define PMD_SECT_AP_MASK (3 << PMD_SECT_AP_SHIFT) +# define PMD_SECT_AP0 (1 << PMD_SECT_AP_SHIFT) /* AP[0]: Access permission bit 0 */ +# define PMD_SECT_AP1 (2 << PMD_SECT_AP_SHIFT) /* AP[1]: Access permission bit 1 */ +#define PMD_SECT_TEX_SHIFT (12) /* Bits 12-14: Memory region attribute bits */ +#define PMD_SECT_TEX_MASK (7 << PMD_SECT_TEX_SHIFT) +#define PMD_SECT_AP2 (1 << 15) /* Bit 15: AP[2]: Access permission bit 2 */ +#define PMD_SECT_S (1 << 16) /* Bit 16: Shareable bit */ +#define PMD_SECT_NG (1 << 17) /* Bit 17: Not global bit. */ +#define PMD_SECT_PADDR_MASK (0xfff00000) /* Bits 20-31: Section base address, PA[31:20] */ + +/* Super Section (differences only) */ + +#define PMD_SSECT_XBA3_SHIFT (5) /* Bits 24-31: Extended base address, PA[39:36] */ +#define PMD_SSECT_XBA3_MASK (15 << PMD_SSECT_XBA3_SHIFT) +#define PMD_SSECT_XBA2_SHIFT (5) /* Bits 20-23: Extended base address, PA[35:32] */ +#define PMD_SSECT_XBA2_MASK (15 << PMD_SSECT_XBA2_SHIFT) +#define PMD_SSECT_XBA1_SHIFT (5) /* Bits 24-31: Extended base address, PA[31:24] */ +#define PMD_SSECT_XBA1_MASK (15 << PMD_SSECT_XBA1_SHIFT) + +/* Level 1 Section/Supersection Access Permissions. + * + * Paragraph B3.7.1, Access permissions: "If address translation is using + * the Short-descriptor translation table format, it must set SCTLR.AFE to + * 1 to enable use of the Access flag.... Setting this bit to 1 redefines + * the AP[0] bit in the translation table descriptors as an Access flag, and + * limits the access permissions information in the translation table + * descriptors to AP[2:1]... + * + * Key: + * + * WR - Read/write address allowed + * R - Read-only access allowed + * 0,1,2 - At PL0, PL1, and/or PL2 + * + * PL0 - User privilege level + * PL1 - Privileged mode + * PL2 - Software executing in Hyp mode + */ + +#ifdef CPU_AFE_ENABLE +/* AP[2:1] access permissions model. AP[0] is used as an access flag: + * + * AP[2] AP[1] PL1 PL0 Description + * ----- ----- ----------- ---------- -------------------------------- + * 0 0 Read/write No access Access only at PL1 + * 0 1 Read/write Read/write Full access + * 1 0 Read-only No access Read-only for PL1 + * 1 1 Read-only Read-only Read-only at any privilege level + */ + +# define PMD_SECT_AP_RW1 (0) +# define PMD_SECT_AP_RW01 (PMD_SECT_AP1) +# define PMD_SECT_AP_R1 (PMD_SECT_AP2) +# define PMD_SECT_AP_R01 (PMD_SECT_AP1 | PMD_SECT_AP2) + +#else +/* AP[2:0] access permissions control, Short-descriptor format only: + * + * AP[2] AP[1] AP[0] PL1/2 PL0 Description + * ----- ----- ----- ----------- ---------- -------------------------------- + * 0 0 0 No access No access All accesses generate faults + * 0 0 1 Read/write No access Access only at PL1 and higher + * 0 1 0 Read/write Read-only Writes at PL0 generate faults + * 0 1 1 Read/write Read/write Full access + * 1 0 0 ---- --- Reserved + * 1 0 1 Read-only No access Read-only for PL1 and higher + * 1 1 0 Read-only Read-only (deprecated) + * 1 1 1 Read-only Read-only Read-only at any privilege level + */ + +# define PMD_SECT_AP_NONE (0) +# define PMD_SECT_AP_RW12 (PMD_SECT_AP0) +# define PMD_SECT_AP_RW12_R0 (PMD_SECT_AP1) +# define PMD_SECT_AP_RW012 (PMD_SECT_AP0 | PMD_SECT_AP1) +# define PMD_SECT_AP_R12 (PMD_SECT_AP0 | PMD_SECT_AP2) +# define PMD_SECT_AP_R012 (PMD_SECT_AP0 | PMD_SECT_AP1 | PMD_SECT_AP2) + +/* Some mode-independent aliases */ + +# define PMD_SECT_AP_RW1 PMD_SECT_AP_RW12 +# define PMD_SECT_AP_RW01 PMD_SECT_AP_RW012 +# define PMD_SECT_AP_R1 PMD_SECT_AP_R12 +# define PMD_SECT_AP_R01 PMD_SECT_AP_R012 + +#endif + +/* Short-descriptor translation table second-level descriptor formats + * + * A PMD_TYPE_PTE level-one table entry provides the base address of the beginning + * of a second-level page table. There are two types of page table entries: + * + * - Large page table entries support mapping of 64KB memory regions. + * - Small page table entries support mapping of 4KB memory regions. + * + * The following definitions apply to all L2 tables: + */ + +#define PTE_TYPE_SHIFT (0) /* Bits: 1:0: Type of mapping */ +#define PTE_TYPE_MASK (3 << PTE_TYPE_SHIFT) +# define PTE_TYPE_FAULT (0 << PTE_TYPE_SHIFT) /* None */ +# define PTE_TYPE_LARGE (1 << PTE_TYPE_SHIFT) /* 64Kb of memory */ +# define PTE_TYPE_SMALL (2 << PTE_TYPE_SHIFT) /* 4Kb of memory */ +#define PTE_B (1 << 2) /* Bit 2: Bufferable bit */ +#define PTE_C (1 << 3) /* Bit 3: Cacheable bit */ +#define PTE_AP_SHIFT (4) /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_AP_MASK (3 << PTE_AP_SHIFT) +# define PTE_AP0 (1 << PTE_AP_SHIFT) /* AP[0]: Access permission bit 0 */ +# define PTE_AP1 (2 << PTE_AP_SHIFT) /* AP[1]: Access permission bit 1 */ + /* Bits 6-8: Depend on entry type */ +#define PTE_AP2 (1 << 9) /* Bit 9: AP[2]: Access permission bit 2 */ +#define PTE_S (1 << 10) /* Bit 10: Shareable bit */ +#define PTE_NG (1 << 11) /* Bit 11: Not global bit. */ + /* Bits 12-31:Depend on entry type */ + +/* Large page -- 64Kb */ + /* Bits: 1:0: Type of mapping */ + /* Bit 2: Bufferable bit */ + /* Bit 3: Cacheable bit */ + /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_LARGE_TEX_SHIFT (12) /* Bits 12-14: Memory region attribute bits */ +#define PTE_LARGE_TEX_MASK (7 << PTE_LARGE_TEX_SHIFT) +#define PTE_LARGE_XN (1 << 15) /* Bit 15: Execute-never bit */ +#define PTE_LARGE_FLAG_MASK (0x0000f03f) /* Bits 0-15: MMU flags (mostly) */ +#define PTE_LARGE_PADDR_MASK (0xffff0000) /* Bits 16-31: Large page base address, PA[31:16] */ + +/* Small page -- 4Kb */ + + /* Bits: 1:0: Type of mapping */ + /* Bit 2: Bufferable bit */ + /* Bit 3: Cacheable bit */ + /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_SMALL_FLAG_MASK (0x0000003f) /* Bits 0-11: MMU flags (mostly) */ +#define PTE_SMALL_PADDR_MASK (0xfffff000) /* Bits 12-31: Small page base address, PA[31:12] */ + +/* Level 2 Translation Table Access Permissions: + * + * WR - Read/write access allowed + * R - Read-only access allowed + * 0,1,2 - At PL0, PL1, and/or PL2 + * + * PL0 - User privilege level + * PL1 - Privileged mode + * PL2 - Software executing in Hyp mode + */ + +#ifdef CONFIG_AFE_ENABLE +/* AP[2:1] access permissions model. AP[0] is used as an access flag: + * + * AP[2] AP[1] PL1 PL0 Description + * ----- ----- ----------- ---------- -------------------------------- + * 0 0 Read/write No access Access only at PL1 + * 0 1 Read/write Read/write Full access + * 1 0 Read-only No access Read-only for PL1 + * 1 1 Read-only Read-only Read-only at any privilege level + */ + +# define PTE_AP_RW1 (0) +# define PTE_AP_RW01 (PTE_AP1) +# define PTE_AP_R1 (PTE_AP2) +# define PTE_AP_R01 (PTE_AP1 | PTE_AP2) + +#else +/* AP[2:0] access permissions control, Short-descriptor format only: + * + * AP[2] AP[1] AP[0] PL1/2 PL0 Description + * ----- ----- ----- ----------- ---------- -------------------------------- + * 0 0 0 No access No access All accesses generate faults + * 0 0 1 Read/write No access Access only at PL1 and higher + * 0 1 0 Read/write Read-only Writes at PL0 generate faults + * 0 1 1 Read/write Read/write Full access + * 1 0 0 ---- --- Reserved + * 1 0 1 Read-only No access Read-only for PL1 and higher + * 1 1 0 Read-only Read-only (deprecated) + * 1 1 1 Read-only Read-only Read-only at any privilege level + */ + +# define PTE_AP_NONE (0) +# define PTE_AP_RW12 (PTE_AP0) +# define PTE_AP_RW12_R0 (PTE_AP1) +# define PTE_AP_RW012 (PTE_AP0 | PTE_AP1) +# define PTE_AP_R12 (PTE_AP0 | PTE_AP2) +# define PTE_AP_R012 (PTE_AP0 | PTE_AP1 | PTE_AP2) + +/* Some mode-independent aliases */ + +# define PTE_AP_RW1 PTE_AP_RW12 +# define PTE_AP_RW01 PTE_AP_RW012 +# define PTE_AP_R1 PTE_AP_R12 +# define PTE_AP_R01 PTE_AP_R012 + +#endif + +/* Memory types + * + * When TEX[2] == 1, the memory region is cacheable memory, and TEX[1:0] + * describe inner and outer cache attributes. In this implementation, + * however, TEX[2:0] are always zero. In this case, the cacheability is + * described simply as: + * + * C B Memory Type + * - - --------------------------------------------------------------- + * 0 0 Strongly-ordered. Strongly-ordered Shareable + * 0 1 Shareable Device. Device Shareable + * 1 0 Outer and Inner Write-Through, no Write-Allocate. Normal S bit + * 1 1 Outer and Inner Write-Back, no Write-Allocate. Normal S bit + * + * The memory type is actually controlled by the contents of the PRRR and + * NMRR registers. For the simple case where TEX[2:0] = 0b000, the control + * is as follows: + * + * + * MEMORY INNER OUTER OUTER SHAREABLE + * C B TYPE CACHEABILITY CACHEABILITY ATTRIBUTE + * - - ---------- ------------- ------------ ----------------- + * 0 0 PRRR[1:0] NMRR[1:0] NMRR[17:16] NOT(PRRR[24]) + * 0 1 PRRR[3:2] NMRR[3:2] NMRR[19:18] NOT(PRRR[25]) + * 1 0 PRRR[5:4] NMRR[5:4] NMRR[21:20] NOT(PRRR[26]) + * 1 1 PRRR[7:6] NMRR[7:6] NMRR[23:22] NOT(PRRR[27]) + * + * But on reset I see the following in PRRR: + * + * PRRR[1:0] = 0b00, Strongly ordered memory + * PRRR[3:2] = 0b01, Device memory + * PRRR[5:4] = 0b10, Normal memory + * PRRR[7:6] = 0b10, Normal memory + * PRRR[14:27] = 0b10, Outer shareable + * + * And the following in NMRR: + * + * NMRR[1:0] = 0b00, Region is Non-cacheable + * NMRR[3:2] = 0b00, Region is Non-cacheable + * NMRR[5:4] = 0b10, Region is Write-Through, no Write-Allocate + * NMRR[7:6] = 0b11, Region is Write-Back, no Write-Allocate + * NMRR[17:16] = 0b00, Region is Non-cacheable + * NMRR[19:18] = 0b00, Region is Non-cacheable + * NMRR[21:20] = 0b10, Region is Write-Through, no Write-Allocate + * NMRR[23:22] = 0b11, Region is Write-Back, no Write-Allocate + * + * Interpretation of Cacheable (C) and Bufferable (B) Bits: + * + * Write-Through Write-Back Write-Through/Write-Back + * C B Cache Only Cache Cache + * --- --- -------------- ------------- ------------------------- + * 0 0 Uncached/ Uncached/ Uncached/ + * Unbuffered Unbuffered Unbuffered + * 0 1 Uncached/ Uncached/ Uncached/ + * Buffered Buffered Buffered + * 1 0 Cached/ UNPREDICTABLE Write-Through cached + * Unbuffered Buffered + * 1 1 Cached/ Cached/ Write-Back cached + * Buffered Buffered Buffered + */ + +#define PMD_STRONGLY_ORDERED (0) +#define PMD_DEVICE (PMD_SECT_B) +#define PMD_CACHEABLE (PMD_SECT_B | PMD_SECT_C) + +#define PTE_STRONGLY_ORDER (0) +#define PTE_DEVICE (PTE_B) +#define PTE_WRITE_THROUGH (PTE_C) +#define PTE_WRITE_BACK (PTE_B | PTE_C) + +/* Default MMU flags for RAM memory, IO, vector sections (level 1) + * + * REVISIT: Here we expect all threads to be running at PL1 + */ + +#define MMU_ROMFLAGS (PMD_TYPE_SECT | PMD_SECT_AP_R1 | PMD_CACHEABLE | \ + PMD_SECT_DOM(0)) +#define MMU_MEMFLAGS (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | PMD_CACHEABLE | \ + PMD_SECT_DOM(0)) +#define MMU_IOFLAGS (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | PMD_DEVICE | \ + PMD_SECT_DOM(0) | PMD_SECT_XN) +#define MMU_STRONGLY_ORDERED (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | \ + PMD_STRONGLY_ORDERED | PMD_SECT_DOM(0) | \ + PMD_SECT_XN) + +/* MMU Flags for each type memory region (level 1 and 2) */ + +#define MMU_L1_TEXTFLAGS (PMD_TYPE_PTE | PMD_PTE_DOM(0)) + +#define MMU_L2_KTEXTFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_R1) +#ifdef CONFIG_AFE_ENABLE +# define MMU_L2_UTEXTFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW01) +#else +# define MMU_L2_UTEXTFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW12_R0) +#endif + +#define MMU_L1_DATAFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0)) +#define MMU_L2_UDATAFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW01) +#define MMU_L2_KDATAFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW1) +#define MMU_L2_UALLOCFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW01) +#define MMU_L2_KALLOCFLAGS (PTE_TYPE_SMALL | PTE_WRITE_BACK | PTE_AP_RW1) + +#define MMU_L1_PGTABFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PTE_WRITE_THROUGH | \ + PMD_PTE_DOM(0)) +#define MMU_L2_PGTABFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1) + +#define MMU_L1_VECTORFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0)) + +#define MMU_L2_VECTRWFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1) +#define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_R1) +#define MMU_L2_VECTORFLAGS MMU_L2_VECTRWFLAGS + +/* Mapped section size */ + +#define SECTION_SHIFT (20) +#define SECTION_SIZE (1 << SECTION_SHIFT) /* 1Mb */ +#define SECTION_MASK (SECTION_SIZE - 1) + +/* The Cortex-A5 supports two translation table base address registers. In + * this, implementation, only Translation Table Base Register 0 (TTBR0) is + * used. The TTBR0 contains the upper bits of the address a a page table in + * physical memory. If 4KB page sizes are used, then TTBR0 registers holds + * bits 14-31 of the page table address; A full 30-bit address is formed by + * ORing in bits 2-13 or the virtual address (MVA). As a consequence, the + * page table must be aligned to a 16Kb address in physical memory and could + * require up to 16Kb of memory. + */ + +#define PGTABLE_SIZE 0x00004000 + +/* Virtual Page Table Location ******************************************************/ + +#ifdef CONFIG_PAGING +/* Check if the virtual address of the page table has been defined. It + * should not be defined: architecture specific logic should suppress + * defining PGTABLE_BASE_VADDR unless: (1) it is defined in the NuttX + * configuration file, or (2) the page table is position in low memory + * (because the vectors are in high memory). + */ + +#ifndef PGTABLE_BASE_VADDR +# define PGTABLE_BASE_VADDR (PG_LOCKED_VBASE + PG_TEXT_VSIZE + PG_DATA_SIZE) + + /* Virtual base of the address of the L2 page tables need to recalculates + * using this new virtual base address of the L2 page table. + */ + +# undef PGTABLE_L2_VBASE +# define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +#endif /* PGTABLE_BASE_VADDR */ + +/* MMU flags ************************************************************************/ + +/* Create some friendly definitions to handle page table entries */ + +#if CONFIG_PAGING_PAGESIZE != 4096 +# error "Unsupported value for CONFIG_PAGING_PAGESIZE" +#endif + +/* Base of the L2 page table (aligned to 1Kb byte boundaries) */ + +#define PGTABLE_L2_BASE_PADDR PGTABLE_L2_PBASE +#define PGTABLE_L2_BASE_VADDR PGTABLE_L2_VBASE + +/* Number of pages in an L2 table per L1 entry */ + +#define PTE_NPAGES PTE_SMALL_NPAGES +#define PT_SIZE (4*PTE_NPAGES) + +/* Mask to get the page table physical address from an L1 entry */ + +#define PG_L1_PADDRMASK PMD_SECT_PADDR_MASK + +/* Addresses of Memory Regions ******************************************************/ + +/* We position the locked region PTEs at an offset into the first + * L2 page table. The L1 entry points to an 1Mb aligned virtual + * address. The actual L2 entry will be offset into the aligned + * L2 table. For 4KB, "small" pages: + * + * PG_L1_PADDRMASK=0xfffff000 + * OFFSET=(((a) & 0x000fffff) >> 10) << 2) + */ + +#define PG_L1_LOCKED_PADDR (PGTABLE_BASE_PADDR + ((PG_LOCKED_VBASE >> 20) << 2)) +#define PG_L1_LOCKED_VADDR (PGTABLE_BASE_VADDR + ((PG_LOCKED_VBASE >> 20) << 2)) + +#define PG_L2_LOCKED_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +#define PG_L2_LOCKED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_SIZE (4*CONFIG_PAGING_NLOCKED) + +/* We position the paged region PTEs immediately after the locked + * region PTEs. NOTE that the size of the paged regions is much + * larger than the size of the physical paged region. That is the + * core of what the On-Demanding Paging feature provides. + */ + +#define PG_L1_PAGED_PADDR (PGTABLE_BASE_PADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_L1_PAGED_VADDR (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) + +#define PG_L2_PAGED_PADDR (PG_L2_LOCKED_PADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_VADDR (PG_L2_LOCKED_VADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_SIZE (4*CONFIG_PAGING_NVPAGED) + +/* This describes the overall text region */ + +#define PG_L1_TEXT_PADDR PG_L1_LOCKED_PADDR +#define PG_L1_TEXT_VADDR PG_L1_LOCKED_VADDR + +#define PG_L2_TEXT_PADDR PG_L2_LOCKED_PADDR +#define PG_L2_TEXT_VADDR PG_L2_LOCKED_VADDR +#define PG_L2_TEXT_SIZE (PG_L2_LOCKED_SIZE + PG_L2_PAGED_SIZE) + +/* We position the data section PTEs just after the text region PTE's */ + +#define PG_L1_DATA_PADDR (PGTABLE_BASE_PADDR + ((PG_DATA_VBASE >> 20) << 2)) +#define PG_L1_DATA_VADDR (PGTABLE_BASE_VADDR + ((PG_DATA_VBASE >> 20) << 2)) + +#define PG_L2_DATA_PADDR (PG_L2_LOCKED_PADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_VADDR (PG_L2_LOCKED_VADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_SIZE (4*PG_DATA_NPAGES) + +/* Page Table Info ******************************************************************/ + +/* The number of pages in the in the page table (PG_PGTABLE_NPAGES). We + * position the page table PTEs just after the data section PTEs. + */ + +#define PG_PGTABLE_NPAGES (PGTABLE_SIZE >> PAGESHIFT) +#define PG_L1_PGTABLE_PADDR (PGTABLE_BASE_PADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) +#define PG_L1_PGTABLE_VADDR (PGTABLE_BASE_VADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) + +#define PG_L2_PGTABLE_PADDR (PG_L2_DATA_PADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_VADDR (PG_L2_DATA_VADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_SIZE (4*PG_DATA_NPAGES) + +/* Vector Mapping *******************************************************************/ + +/* One page is required to map the vector table. The vector table could lie + * at virtual address zero (or at the start of RAM which is aliased to address + * zero on the ea3131) or at virtual address 0xfff00000. We only have logic + * here to support the former case. + * + * NOTE: If the vectors are at address zero, the page table will be + * forced to the highest RAM addresses. If the vectors are at 0xfff0000, + * then the page table is forced to the beginning of RAM. + * + * When the vectors are at the beginning of RAM, they will probably overlap + * the first page of the locked text region. In any other case, the + * configuration must set CONFIG_PAGING_VECPPAGE to provide the physical + * address of the page to use for the vectors. + * + * When the vectors overlap the first page of the locked text region (the + * only case in use so far), then the text page will be temporarily be made + * writable in order to copy the vectors. + * + * PG_VECT_PBASE - This the physical address of the page in memory to be + * mapped to the vector address. + * PG_L2_VECT_PADDR - This is the physical address of the L2 page table + * entry to use for the vector mapping. + * PG_L2_VECT_VADDR - This is the virtual address of the L2 page table + * entry to use for the vector mapping. + */ + +/* Case 1: The configuration tells us everything */ + +#if defined(CONFIG_PAGING_VECPPAGE) +# define PG_VECT_PBASE CONFIG_PAGING_VECPPAGE +# define PG_L2_VECT_PADDR CONFIG_PAGING_VECL2PADDR +# define PG_L2_VECT_VADDR CONFIG_PAGING_VECL2VADDR + +/* Case 2: Vectors are in low memory and the locked text region starts at + * the beginning of SRAM (which will be aliased to address 0x00000000). + * However, the beginning of SRAM may not be aligned to the beginning + * of the L2 page table (because the beginning of RAM is offset into + * the table. + */ + +#elif defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_PAGING_LOCKED_PBASE) +# define PG_VECT_PBASE PG_LOCKED_PBASE +# define PG_L2_VECT_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +# define PG_L2_VECT_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_VECT_OFFSET) +# define PG_L2_VECT_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_VECT_OFFSET) + +/* Case 3: High vectors or the locked region is not at the beginning or SRAM */ + +#else +# error "Logic missing for high vectors in this case" +#endif + +/* Page Usage ***********************************************************************/ + +/* This is the total number of pages used in the text/data mapping: */ + +#define PG_TOTAL_NPPAGES (PG_TEXT_NPPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_NVPAGES (PG_TEXT_NVPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_PSIZE (PG_TOTAL_NPPAGES << PAGESHIFT) +#define PG_TOTAL_VSIZE (PG_TOTAL_NVPAGES << PAGESHIFT) + +/* Sanity check: */ + +#if PG_TOTAL_NPPAGES > PG_RAM_PAGES +# error "Total pages required exceeds RAM size" +#endif + +/* Page Management ******************************************************************/ + +/* For page management purposes, the following summarize the "heap" of + * free pages, operations on free pages and the L2 page table. + * + * PG_POOL_VA2L1OFFSET(va) - Given a virtual address, return the L1 table + * offset (in bytes). + * PG_POOL_VA2L1VADDR(va) - Given a virtual address, return the virtual + * address of the L1 table entry + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the physical address of the start of the L2 + * page table + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the virtual address of the start of the L2 + * page table. + * + * PG_POOL_L1VBASE - The virtual address of the start of the L1 + * page table range corresponding to the first + * virtual address of the paged text region. + * PG_POOL_L1VEND - The virtual address of the end+1 of the L1 + * page table range corresponding to the last + * virtual address+1 of the paged text region. + * + * PG_POOL_VA2L2NDX(va) - Converts a virtual address within the paged + * text region to the most compact possible + * representation. Each PAGESIZE of address + * corresponds to 1 index in the L2 page table; + * Index 0 corresponds to the first L2 page table + * entry for the first page in the virtual paged + * text address space. + * PG_POOL_NDX2VA(ndx) - Performs the opposite conversion.. converts + * an index into a virtual address in the paged + * text region (the address at the beginning of + * the page). + * PG_POOL_MAXL2NDX - This is the maximum value+1 of such an index. + * + * PG_POOL_PGPADDR(ndx) - Converts an page index into the corresponding + * (physical) address of the backing page memory. + * PG_POOL_PGVADDR(ndx) - Converts an page index into the corresponding + * (virtual)address of the backing page memory. + * + * These are used as follows: If a miss occurs at some virtual address, va, + * A new page index, ndx, is allocated. PG_POOL_PGPADDR(i) converts the index + * into the physical address of the page memory; PG_POOL_L2VADDR(va) converts + * the virtual address in the L2 page table there the new mapping will be + * written. + */ + +#define PG_POOL_VA2L1OFFSET(va) (((va) >> 20) << 2) +#define PG_POOL_VA2L1VADDR(va) (PGTABLE_BASE_VADDR + PG_POOL_VA2L1OFFSET(va)) +#define PG_POOL_L12PPTABLE(L1) ((L1) & PG_L1_PADDRMASK) +#define PG_POOL_L12VPTABLE(L1) (PG_POOL_L12PPTABLE(L1) - PGTABLE_BASE_PADDR + PGTABLE_BASE_VADDR) + +#define PG_POOL_L1VBASE (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_POOL_L1VEND (PG_POOL_L1VBASE + (CONFIG_PAGING_NVPAGED << 2)) + +#define PG_POOL_VA2L2NDX(va) (((va) - PG_PAGED_VBASE) >> PAGESHIFT) +#define PG_POOL_NDX2VA(ndx) (((ndx) << PAGESHIFT) + PG_PAGED_VBASE) +#define PG_POOL_MAXL2NDX PG_POOL_VA2L2NDX(PG_PAGED_VEND) + +#define PG_POOL_PGPADDR(ndx) (PG_PAGED_PBASE + ((ndx) << PAGESHIFT)) +#define PG_POOL_PGVADDR(ndx) (PG_PAGED_VBASE + ((ndx) << PAGESHIFT)) + +#endif /* CONFIG_PAGING */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* struct section_mapping_s describes the L1 mapping of a large region of memory + * consisting of one or more 1MB sections (nsections). + * + * All addresses must be aligned to 1MB address boundaries. + */ + +struct section_mapping_s +{ + uint32_t physbase; /* Physical address of the region to be mapped */ + uint32_t virtbase; /* Virtual address of the region to be mapped */ + uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ + uint32_t nsections; /* Number of mappings in the region */ +}; +#endif + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ + +#ifdef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_mmu + * + * Description: + * Disable the MMU + * + * Inputs: + * None + * + ************************************************************************************/ + + .macro cp15_disable_mmu, scratch + mrc p15, 0, \scratch, c1, c0, 0 + bic \scratch, \scratch, #1 + mcr p15, 0, \scratch, c1, c0, 0 + .endm + +/************************************************************************************ + * Name: cp15_invalidate_tlbs + * + * Description: + * Invalidate entire unified TLB + * + * The Invalidate entire TLB operations invalidate all unlocked entries in the + * TLB. The operation ignores the value in the register Rt specified by the MCR + * instruction that performs the operation. Software does not have to write a + * value to the register before issuing the MCR instruction. + * + * Inputs: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_tlbs, scratch + mcr p15, 0, \scratch, c8, c7, 0 /* TLBIALL */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_tlb_bymva + * + * Description: + * Invalidate unified TLB entry by MVA all ASID Inner Shareable + * + * Inputs: + * vaddr - The virtual address to be invalidated + * + ************************************************************************************/ + + .macro cp15_invalidate_tlb_bymva, vaddr + dsb + mcr p15, 0, \vaddr, c8, c3, 3 /* TLBIMVAAIS */ + dsb + isb + .endm + +/************************************************************************************ + * Name: cp15_wrdacr + * + * Description: + * Write the Domain Access Control Register (DACR) + * + * Inputs: + * dacr - The new value of the DACR + * + ************************************************************************************/ + + .macro cp15_wrdacr, dacr + mcr p15, 0, \dacr, c3, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + .endm + +/************************************************************************************ + * Name: cp14_wrttb + * + * Description: + * The ARMv7-aA architecture supports two translation tables. This + * implementation, however, uses only translation table 0. This + * function writes the address of the page table to the Translation + * Table Base Register 0 (TTBR0). Then it clears the TTB control + * register (TTBCR), indicating that we are using TTBR0. + * + * Inputs: + * ttb - The new value of the TTBR0 register + * + ************************************************************************************/ + + .macro cp14_wrttb, ttb, scratch + mcr p15, 0, \ttb, c2, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + mov \scratch, #0x0 + mcr p15, 0, \scratch, c2, c0, 2 + .endm + +/************************************************************************************ + * Name: pg_l2map + * + * Description: + * Write several, contiguous L2 page table entries. npages entries will be + * written. This macro is used when CONFIG_PAGING is enable. This case, + * it is used as follows: + * + * ldr r0, =PGTABLE_L2_BASE_PADDR <-- Address in L2 table + * ldr r1, =PG_LOCKED_PBASE <-- Physical page memory address + * ldr r2, =CONFIG_PAGING_NLOCKED <-- number of pages + * ldr r3, =MMUFLAGS <-- L2 MMU flags + * pg_l2map r0, r1, r2, r3, r4 + * + * Inputs: + * l2 - Physical or virtual start address in the L2 page table, depending + * upon the context. (modified) + * ppage - The physical address of the start of the region to span. Must + * be aligned to 1Mb section boundaries (modified) + * npages - Number of pages to write in the section (modified) + * mmuflags - L2 MMU FLAGS + * + * Scratch registers (modified): tmp + * l2 - Next address in the L2 page table. + * ppage - Start of next physical page + * npages - Loop counter + * tmp - scratch + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * - pg_l1span has been called to initialize the L1 table. + * + ************************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l2map, l2, ppage, npages, mmuflags, tmp + b 2f +1: + /* Write the one L2 entries. First, get tmp = (ppage | mmuflags), + * the value to write into the L2 PTE + */ + + orr \tmp, \ppage, \mmuflags + + /* Write value into table at the current table address + * (and increment the L2 page table address by 4) + */ + + str \tmp, [\l2], #4 + + /* Update the physical address that will correspond to the next + * table entry. + */ + + add \ppage, \ppage, #CONFIG_PAGING_PAGESIZE + + /* Decrement the number of pages written */ + + sub \npages, \npages, #1 +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next PTE. + */ + + cmp \npages, #0 + bgt 1b + .endm +#endif /* CONFIG_PAGING */ + +/************************************************************************************ + * Name: pg_l1span + * + * Description: + * Write several, contiguous, unmapped, small L1 page table entries. As many + * entries will be written as many as needed to span npages. This macro is + * used when CONFIG_PAGING is enable. In this case, it is used as follows: + * + * ldr r0, =PG_L1_PGTABLE_PADDR <-- Address in the L1 table + * ldr r1, =PG_L2_PGTABLE_PADDR <-- Physical address of L2 page table + * ldr r2, =PG_PGTABLE_NPAGES <-- Total number of pages + * ldr r3, =PG_PGTABLE_NPAGE1 <-- Number of pages in the first PTE + * ldr r4, =MMU_L1_PGTABFLAGS <-- L1 MMU flags + * pg_l1span r0, r1, r2, r3, r4, r4 + * + * Inputs (unmodified unless noted): + * l1 - Physical or virtual address in the L1 table to begin writing (modified) + * l2 - Physical start address in the L2 page table (modified) + * npages - Number of pages to required to span that memory region (modified) + * ppage - The number of pages in page 1 (modified) + * mmuflags - L1 MMU flags to use + * + * Scratch registers (modified): l1, l2, npages, tmp + * l1 - Next L1 table address + * l2 - Physical start address of the next L2 page table + * npages - Loop counter + * ppage - After the first page, this will be the full number of pages. + * tmp - scratch + * + * Return: + * Nothing of interest. + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * + ************************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l1span, l1, l2, npages, ppage, mmuflags, tmp + b 2f +1: + /* Write the L1 table entry that refers to this (unmapped) small page + * table. + * + * tmp = (l2table | mmuflags), the value to write into the page table + */ + + orr \tmp, \l2, \mmuflags + + /* Write the value into the L1 table at the correct offset. + * (and increment the L1 table address by 4) + */ + + str \tmp, [\l1], #4 + + /* Update the L2 page table address for the next L1 table entry. */ + + add \l2, \l2, #PT_SIZE /* Next L2 page table start address */ + + /* Update the number of pages that we have account for (with + * non-mappings). NOTE that the first page may have fewer than + * the maximum entries per page table. + */ + + sub \npages, \npages, \ppage + mov \ppage, #PTE_NPAGES +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next L1 entry. + */ + + cmp \npages, #0 + bgt 1b + .endm + +#endif /* CONFIG_PAGING */ +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_mmu + * + * Description: + * Disable the MMU + * + * Inputs: + * None + * + ************************************************************************************/ + +static inline void cp15_disable_mmu(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" + "\tbic r0, r0, #1\n" + "\tmcr p15, 0, r0, c1, c0, 0\n" + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_tlbs + * + * Description: + * Invalidate entire unified TLB + * + * The Invalidate entire TLB operations invalidate all unlocked entries in the + * TLB. The operation ignores the value in the register Rt specified by the MCR + * instruction that performs the operation. Software does not have to write a + * value to the register before issuing the MCR instruction. + * + * Inputs: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_tlbs(void) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, r0, c8, c7, 0\n" /* TLBIALL */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_tlb_bymva + * + * Description: + * Invalidate unified TLB entry by MVA all ASID Inner Shareable + * + * Inputs: + * vaddr - The virtual address to be invalidated + * + ************************************************************************************/ + +static inline void cp15_invalidate_tlb_bymva(uint32_t vaddr) +{ + __asm__ __volatile__ + ( + "\tdsb\n" + "\tmcr p15, 0, %0, c8, c3, 3\n" /* TLBIMVAAIS */ + "\tdsb\n" + "\tisb\n" + : + : "r" (vaddr) + : "r1", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_wrdacr + * + * Description: + * Write the Domain Access Control Register (DACR) + * + * Inputs: + * dacr - The new value of the DACR + * + ************************************************************************************/ + +static inline void cp15_wrdacr(unsigned int dacr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0,0, c3, c0, 0\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + : + : "r" (dacr) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp14_wrttb + * + * Description: + * The ARMv7-aA architecture supports two translation tables. This + * implementation, however, uses only translation table 0. This + * function writes the address of the page table to the Translation + * Table Base Register 0 (TTBR0). Then it clears the TTB control + * register (TTBCR), indicating that we are using TTBR0. + * + * Inputs: + * ttb - The new value of the TTBR0 register + * + ************************************************************************************/ + +static inline void cp14_wrttb(unsigned int ttb) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0,0, c2, c0, 0\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tmov r1, #0\n" + "\tmcr p15, 0, r1, c2, c0, 2\n" + : + : "r" (ttb) + : "r1", "memory" + ); +} + +/************************************************************************************* + * Name: mmu_l1_getentry + * + * Description: + * Given a virtual address, return the value of the corresponding L1 table entry. + * + * Input Parameters: + * vaddr - The virtual address to be mapped. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline uint32_t mmu_l1_getentry(uint32_t vaddr) +{ + uint32_t *l1table = (uint32_t*)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Return the address of the page table entry */ + + return l1table[index]; +} +#endif + +/************************************************************************************* + * Name: mmu_l2_getentry + * + * Description: + * Given a address of the beginning of an L2 page table and a virtual address, + * return the value of the corresponding L2 page table entry. + * + * Input Parameters: + * l2vaddr - The virtual address of the beginning of the L2 page table + * vaddr - The virtual address to be mapped. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline uint32_t mmu_l2_getentry(uint32_t l2vaddr, uint32_t vaddr) +{ + uint32_t *l2table = (uint32_t*)l2vaddr; + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Return the address of the page table entry */ + + return l2table[index]; +} +#endif + +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: mmu_l1_setentry + * + * Description: + * Set a one level 1 translation table entry. Only a single L1 page table is + * supported. + * + * Input Parameters: + * paddr - The physical address to be mapped. Must be aligned to a 1MB address + * boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 1MB address + * boundary + * mmuflags - The MMU flags to use in the mapping. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags); +#endif + +/**************************************************************************** + * Name: mmu_l1_restore + * + * Description: + * Restore one L1 table entry previously returned by mmu_l1_getentry() (or + * any other encoded L1 page table value). + * + * Input Parameters: + * vaddr - A virtual address to be mapped + * l1entry - The value to write into the page table entry + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_ADDRENV) +void mmu_l1_restore(uintptr_t vaddr, uint32_t l1entry); +#endif + +/************************************************************************************ + * Name: mmu_l1_clrentry + * + * Description: + * Unmap one L1 region by writing zero into the L1 page table entry and by + * flushing caches and TLBs appropriately. + * + * Input Parameters: + * vaddr - A virtual address within the L1 address region to be unmapped. + * + ************************************************************************************/ + +#if !defined (CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_ADDRENV) +# define mmu_l1_clrentry(v) mmu_l1_restore(v,0) +#endif + +/************************************************************************************ + * Name: mmu_l1_map_region + * + * Description: + * Set multiple level 1 translation table entries in order to map a region of + * memory. + * + * Input Parameters: + * mapping - Describes the mapping to be performed. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_map_region(const struct section_mapping_s *mapping); +#endif + +/**************************************************************************** + * Name: mmu_invalidate_region + * + * Description: + * Invalidate TLBs for a range of addresses (all 4KB aligned). + * + * Input Parameters: + * vaddr - The beginning of the region to invalidate. + * size - The size of the region in bytes to be invalidated. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_invalidate_region(uint32_t vstart, size_t size); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_MMU_H */ diff --git a/arch/arm/src/armv7-a/mpcore.h b/arch/arm/src/armv7-a/mpcore.h new file mode 100644 index 0000000000000000000000000000000000000000..962f127620a0d093dc59b4bde8eece1197de8b7d --- /dev/null +++ b/arch/arm/src/armv7-a/mpcore.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/mpcore.h + * Generic Interrupt Controller Definitions + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * Cortexâ„¢-A9 MPCore, Revision: r4p1, Technical Reference Manual, ARM DDI + * 0407I (ID091612). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_MPCORE_H +#define __ARCH_ARM_SRC_ARMV7_A_MPCORE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "chip.h" /* For CHIP_MPCORE_VBASE */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MPCore registers are memory mapped and accessed through a processor + * specific private address space via the SCU. The Cortex-A9 MCU chip.h + * header file must provide the definition CHIP_MPCORE_VBASE to access this + * the registers in this memory region. + */ + +/* Peripheral Base Offsets **************************************************/ + +#define MPCORE_SCU_OFFSET 0x0000 /* 0x0000-0x00fc SCU registers */ +#define MPCORE_ICC_OFFSET 0x0100 /* 0x0000-0x00FC Interrupt conroller interface */ +#define MPCORE_GTM_OFFSET 0x0200 /* 0x0200-0x02ff Global timer */ + /* 0x0300-0x05ff Reserved */ +#define MPCORE_PTM_OFFSET 0x0600 /* 0x0600-0x06ff Private timers and watchdogs */ + /* 0x0700-0x07ff Reserved */ +#define MPCORE_ICD_OFFSET 0x1000 /* 0x1000-0x1fff Interrupt Distributor */ + +/* Peripheral Base Addresses ************************************************/ + +#define MPCORE_SCU_VBASE (CHIP_MPCORE_VBASE+MPCORE_SCU_OFFSET) +#define MPCORE_ICC_VBASE (CHIP_MPCORE_VBASE+MPCORE_ICC_OFFSET) +#define MPCORE_GTM_VBASE (CHIP_MPCORE_VBASE+MPCORE_GTM_OFFSET) +#define MPCORE_PTM_VBASE (CHIP_MPCORE_VBASE+MPCORE_PTM_OFFSET) +#define MPCORE_ICD_VBASE (CHIP_MPCORE_VBASE+MPCORE_ICD_OFFSET) + +#endif /* __ARCH_ARM_SRC_ARMV7_A_MPCORE_H */ diff --git a/arch/arm/src/armv7-a/pgalloc.h b/arch/arm/src/armv7-a/pgalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..32436cf362ef809e64aa21418ab4287b8c2a2931 --- /dev/null +++ b/arch/arm/src/armv7-a/pgalloc.h @@ -0,0 +1,251 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/pgalloc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_PGALLOC_H +#define __ARCH_ARM_SRC_ARMV7_A_PGALLOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "mmu.h" + +#ifdef CONFIG_MM_PGALLOC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_pgmap + * + * Description: + * Map one page to a temporary, scratch virtual memory address + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_PGPOOL_MAPPING) && defined(CONFIG_ARCH_USE_MMU) +static inline uintptr_t arm_tmpmap(uintptr_t paddr, FAR uint32_t *l1save) +{ + *l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE); + mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS); + return ((uintptr_t)ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK)); +} +#endif + +/**************************************************************************** + * Name: arm_pgrestore + * + * Description: + * Restore any previous L1 page table mapping that was in place when + * arm_tmpmap() was called + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_PGPOOL_MAPPING) && defined(CONFIG_ARCH_USE_MMU) +static inline void arm_tmprestore(uint32_t l1save) +{ + mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save); +} +#endif + +/**************************************************************************** + * Name: arm_pgvaddr + * + * Description: + * If the page memory pool is statically mapped, then we do not have to + * go through the the temporary mapping. We simply have to perform a + * physical to virtual memory address mapping. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING +static inline uintptr_t arm_pgvaddr(uintptr_t paddr) +{ + DEBUGASSERT(paddr >= CONFIG_ARCH_PGPOOL_PBASE && + paddr < CONFIG_ARCH_PGPOOL_PEND); + + return paddr - CONFIG_ARCH_PGPOOL_PBASE + CONFIG_ARCH_PGPOOL_VBASE; +} +#endif + +/**************************************************************************** + * Name: arm_uservaddr + * + * Description: + * Return true if the virtual address, vaddr, lies in the user address + * space. + * + ****************************************************************************/ + +static inline bool arm_uservaddr(uintptr_t vaddr) +{ + /* Check if this address is within the range of the virtualized .bss/.data, + * heap, or stack regions. + */ + + return ((vaddr >= CONFIG_ARCH_TEXT_VBASE && vaddr < ARCH_TEXT_VEND) || + (vaddr >= CONFIG_ARCH_DATA_VBASE && vaddr < ARCH_DATA_VEND) || + (vaddr >= CONFIG_ARCH_HEAP_VBASE && vaddr < ARCH_HEAP_VEND) +#ifdef CONFIG_ARCH_STACK_DYNAMIC + || (vaddr >= CONFIG_ARCH_STACK_VBASE && vaddr < ARCH_STACK_VEND) +#endif +#ifdef CONFIG_MM_SHM + || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND) +#endif + ); +} + +/**************************************************************************** + * Name: set_l2_entry + * + * Description: + * Set the L2 table entry as part of the initialization of the L2 Page + * table. + * + ****************************************************************************/ + +static inline void set_l2_entry(FAR uint32_t *l2table, uintptr_t paddr, + uintptr_t vaddr, uint32_t mmuflags) +{ + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the level 2 page table entry */ + + l2table[index] = (paddr | mmuflags); +} + +/**************************************************************************** + * Name: clr_l2_entry + * + * Description: + * Claear the L2 table entry. + * + ****************************************************************************/ + +static inline void clr_l2_entry(FAR uint32_t *l2table, uintptr_t vaddr) +{ + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the level 2 page table entry */ + + l2table[index] = 0; +} + +/**************************************************************************** + * Name: get_l2_entry + * + * Description: + * Set the L2 table entry as part of the initialization of the L2 Page + * table. + * + ****************************************************************************/ + +static inline uintptr_t get_l2_entry(FAR uint32_t *l2table, uintptr_t vaddr) +{ + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Return the level 2 page table entry */ + + return l2table[index]; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_physpgaddr + * + * Description: + * Check if the virtual address lies in the user data area and, if so + * get the mapping to the physical address in the page pool. + * + ****************************************************************************/ + +uintptr_t arm_physpgaddr(uintptr_t vaddr); + +/**************************************************************************** + * Name: arm_virtpgaddr + * + * Description: + * Check if the physical address lies in the page pool and, if so + * get the mapping to the virtual address in the user data area. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING +uintptr_t arm_virtpgaddr(uintptr_t paddr); +#endif + +#endif /* CONFIG_MM_PGALLOC */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_PGALLOC_H */ diff --git a/arch/arm/src/armv7-a/sctlr.h b/arch/arm/src/armv7-a/sctlr.h new file mode 100644 index 0000000000000000000000000000000000000000..10511156a4b72e0ed594297d66b09ce17bd3d410 --- /dev/null +++ b/arch/arm/src/armv7-a/sctlr.h @@ -0,0 +1,407 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/sctlr.h + * CP15 System Control Registers + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 + * ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_SCTLR_H +#define __ARCH_ARM_SRC_ARMV7_A_SCTLR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Reference: Cortex-A5™ MPCore Paragraph 4.2, "Register summary." */ + +/* Main ID Register (MIDR) */ +/* TODO: To be provided */ + +/* Cache Type Register (CTR) */ +/* TODO: To be provided */ + +/* TCM Type Register + * + * The Cortex-A5 MPCore processor does not implement instruction or data Tightly + * Coupled Memory (TCM), so this register always Reads-As-Zero (RAZ). + * + * TLB Type Register + * + * The Cortex-A5 MPCore processor does not implement instruction or data Tightly + * CoupledMemory (TCM), so this register always Reads-As-Zero (RAZ). + */ + +/* Multiprocessor Affinity Register (MPIDR) */ + +#define MPIDR_CPUID_SHIFT (0) /* Bits 0-1: CPU ID */ +#define MPIDR_CPUID_MASK (3 << MPIDR_CPUID_SHIFT) +# define MPIDR_CPUID_CPU0 (0 << MPIDR_CPUID_SHIFT) +# define MPIDR_CPUID_CPU1 (1 << MPIDR_CPUID_SHIFT) +# define MPIDR_CPUID_CPU2 (2 << MPIDR_CPUID_SHIFT) +# define MPIDR_CPUID_CPU3 (3 << MPIDR_CPUID_SHIFT) + /* Bits 2-7: Reserved */ +#define MPIDR_CLUSTID_SHIFT (8) /* Bits 8-11: Cluster ID value */ +#define MPIDR_CLUSTID_MASK (15 << MPIDR_CLUSTID_SHIFT) + /* Bits 12-29: Reserved */ +#define MPIDR_U (1 << 30) /* Bit 30: Multiprocessing Extensions. */ + +/* Processor Feature Register 0 (ID_PFR0) */ +/* TODO: To be provided */ + +/* Processor Feature Register 1 (ID_PFR1) */ +/* TODO: To be provided */ + +/* Debug Feature Register 0 (ID_DFR0) */ +/* TODO: To be provided */ + +/* Auxiliary Feature Register 0 (ID_AFR0) */ +/* TODO: To be provided */ + +/* Memory Model Features Register 0 (ID_MMFR0) */ +/* Memory Model Features Register 1 (ID_MMFR1) */ +/* Memory Model Features Register 2 (ID_MMFR2) */ +/* Memory Model Features Register 3 (ID_MMFR3) */ +/* TODO: To be provided */ + +/* Instruction Set Attributes Register 0 (ID_ISAR0) */ +/* Instruction Set Attributes Register 1 (ID_ISAR1) */ +/* Instruction Set Attributes Register 2 (ID_ISAR2) */ +/* Instruction Set Attributes Register 3 (ID_ISAR3) */ +/* Instruction Set Attributes Register 4 (ID_ISAR4) */ +/* Instruction Set Attributes Register 5 (ID_ISAR5) */ +/* Instruction Set Attributes Register 6-7 (ID_ISAR6-7). Reserved. */ +/* TODO: Others to be provided */ + +/* Cache Size Identification Register (CCSIDR) */ +/* TODO: To be provided */ + +/* Cache Level ID Register (CLIDR) */ +/* TODO: To be provided */ + +/* Auxiliary ID Register (AIDR) */ +/* TODO: To be provided */ + +/* Cache Size Selection Register (CSSELR) */ +/* TODO: To be provided */ + +/* System Control Register (SCTLR) + * + * NOTES: + * (1) Always enabled on A5 + * (2) Not available on A5 + */ + +#define SCTLR_M (1 << 0) /* Bit 0: Enables the MMU */ +#define SCTLR_A (1 << 1) /* Bit 1: Enables strict alignment of data */ +#define SCTLR_C (1 << 2) /* Bit 2: Determines if data can be cached */ + /* Bits 3-9: Reserved */ +#define SCTLR_SW (1 << 10) /* Bit 10: SWP/SWPB Enable bit */ +#define SCTLR_Z (1 << 11) /* Bit 11: Program flow prediction control (1) */ +#define SCTLR_I (1 << 12) /* Bit 12: Determines if instructions can be cached */ +#define SCTLR_V (1 << 13) /* Bit 13: Vectors bit */ +#define SCTLR_RR (1 << 14) /* Bit 14: Cache replacement strategy (2) */ + /* Bits 15-16: Reserved */ +#define SCTLR_HA (1 << 17) /* Bit 17: Hardware management access disabled (2) */ + /* Bits 18-24: Reserved */ +#define SCTLR_EE (1 << 25) /* Bit 25: Determines the value the CPSR.E */ + /* Bit 26: Reserved */ +#define SCTLR_NMFI (1 << 27) /* Bit 27: Non-maskable FIQ support (Cortex-A9) */ +#define SCTLR_TRE (1 << 28) /* Bit 28: TEX remap */ +#define SCTLR_AFE (1 << 29) /* Bit 29: Access Flag Enable bit */ +#define SCTLR_TE (1 << 30) /* Bit 30: Thumb exception enable */ + /* Bit 31: Reserved */ + +/* Auxiliary Control Register (ACTLR) */ + +#define ACTLR_FW (1 << 0) /* Bit 0: Enable Cache/TLB maintenance broadcase */ +#define ACTLR_L2_PREFECTH (1 << 1) /* Bit 1: L2 pre-fetch hint enable */ +#define ACTLR_L1_PREFETCH (1 << 2) /* Bit 2: L1 Dside pre-fetch enable */ +#define ACTLR_LINE_ZERO (1 << 3) /* Bit 3: Enable write full line zero mode */ + /* Bits 4-5: Reserved */ +#define ACTLR_SMP (1 << 6) /* Bit 6: Cortex-A9 taking part in coherency */ +#define ACTLR_EXCL (1 << 7) /* Bit 7: Exclusive cache bit */ +#define ACTLR_ALLOC_1WAY (1 << 8) /* Bit 8: Allocation in 1-way cache only */ +#define ACTLR_PARITY (1 << 9) /* Bit 9: Parity ON */ + /* Bits 10-31: Reserved */ + +/* Coprocessor Access Control Register (CPACR) */ +/* TODO: To be provided */ + +/* Secure Configuration Register (SCR) */ +/* TODO: To be provided */ + +/* Secure Debug Enable Register (SDER) */ +/* TODO: To be provided */ + +/* Non-secure Access Control Register (NSACR) */ + + /* Bits 0-9: Reserved */ +#define NSACR_CP10 (1 << 10) /* Bit 10: Permission to access coprocessor 10 */ +#define NSACR_CP11 (1 << 11) /* Bit 11: Permission to access coprocessor 11 */ + /* Bits 12-13: Reserved */ +#define NSACR_NSD32DIS (1 << 14) /* Bit 14: Disable the Non-secure use of VFP D16-D31 */ +#define NSACR_NSASEDIS (1 << 15) /* Bit 15: Disable Non-secure Advanced SIMD Extension */ + /* Bits 16-17: Reserved */ +#define NSACR_NSSMP (1 << 18) /* Bit 18: ACR SMP bit writable */ + /* Bits 19-31: Reserved */ + +/* Virtualization Control Register (VCR) */ +/* TODO: To be provided */ + +/* Translation Table Base Register 0 (TTBR0). See mmu.h */ +/* Translation Table Base Register 1 (TTBR1). See mmu.h */ +/* Translation Table Base Control Register (TTBCR). See mmu.h */ +/* Domain Access Control Register (DACR). See mmu.h */ +/* Data Fault Status Register (DFSR). See mmu.h */ +/* Instruction Fault Status Register (IFSR). See mmu.h */ + +/* Auxiliary Data Fault Status Register (ADFSR). Not used in this implementation. */ + +/* Data Fault Address Register(DFAR) + * + * Holds the MVA of the faulting address when a synchronous fault occurs + * + * Instruction Fault Address Register(IFAR) + * + * Holds the MVA of the faulting address of the instruction that caused a prefetch + * abort. + * + * NOP Register + * + * The use of this register is optional and deprecated. Use the NOP instruction + * instead. + * + * Physical Address Register (PAR) + * + * Holds: + * - the PA after a successful translation + * - the source of the abort for an unsuccessful translation + * + * Instruction Synchronization Barrier + * + * The use of ISB is optional and deprecated. Use the instruction ISB instead. + * + * Data Memory Barrier + * The use of DMB is deprecated and, on Cortex-A5 MPCore, behaves as NOP. Use the + * instruction DMB instead. + */ + +/* Vector Base Address Register (VBAR) */ + +#define VBAR_MASK (0xffffffe0) + +/* Monitor Vector Base Address Register (MVBAR) */ +/* TODO: To be provided */ + +/* Interrupt Status Register (ISR) */ +/* TODO: To be provided */ + +/* Virtualization Interrupt Register (VIR) */ +/* TODO: To be provided */ + +/* Context ID Register (CONTEXTIDR) */ + +#define CONTEXTIDR_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ +#define CONTEXTIDR_ASID_MASK (0xff << CONTEXTIDR_ASID_SHIFT) +#define CONTEXTIDR_PROCID_SHIFT (8) /* Bits 8-31: Process Identifier */ +#define CONTEXTIDR_PROCID_MASK (0x00ffffff << CONTEXTIDR_PROCID_SHIFT) + +/* Configuration Base Address Register (CBAR) */ +/* TODO: To be provided */ + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ + +#ifdef __ASSEMBLY__ + +/* Get the device ID */ + + .macro cp15_rdid, id + mrc p15, 0, \id, c0, c0, 0 + .endm + +/* Read/write the system control register (SCTLR) */ + + .macro cp15_rdsctlr, sctlr + mrc p15, 0, \sctlr, c1, c0, 0 + .endm + + .macro cp15_wrsctlr, sctlr + mcr p15, 0, \sctlr, c1, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + .endm +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Get the device ID register */ + +static inline unsigned int cp15_rdid(void) +{ + unsigned int id; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c0, c0, 0\n" + : "=r" (id) + : + : "memory" + ); + + return id; +} + +/* Get the Multiprocessor Affinity Register (MPIDR) */ + +static inline unsigned int cp15_rdmpidr(void) +{ + unsigned int mpidr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c0, c0, 5\n" + : "=r" (mpidr) + : + : "memory" + ); + + return mpidr; +} + +/* Read/write the system control register (SCTLR) */ + +static inline unsigned int cp15_rdsctlr(void) +{ + unsigned int sctlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0, 0\n" + : "=r" (sctlr) + : + : "memory" + ); + + return sctlr; +} + +static inline void cp15_wrsctlr(unsigned int sctlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c1, c0, 0\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + : + : "r" (sctlr) + : "memory" + ); +} + +/* Read/write the vector base address register (VBAR) */ + +static inline unsigned int cp15_rdvbar(void) +{ + unsigned int sctlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c12, c0, 0\n" + : "=r" (sctlr) + : + : "memory" + ); + + return sctlr; +} + +static inline void cp15_wrvbar(unsigned int sctlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c12, c0, 0\n" + : + : "r" (sctlr) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_SCTLR_H */ diff --git a/arch/arm/src/armv7-a/svcall.h b/arch/arm/src/armv7-a/svcall.h new file mode 100644 index 0000000000000000000000000000000000000000..9e3c679e899d07417ca041448c0f7c7f5c51bd2a --- /dev/null +++ b/arch/arm/src/armv7-a/svcall.h @@ -0,0 +1,130 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/svcall.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_SVCALL_H +#define __ARCH_ARM_SRC_ARMV7_A_SVCALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +#ifdef CONFIG_LIB_SYSCALL + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ +/* This logic uses one system call for the syscall return. So a minimum of one + * syscall values must be reserved. If CONFIG_BUILD_KERNEL is defined, then four + * more syscall values must be reserved. + */ + +#ifdef CONFIG_BUILD_KERNEL +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 6" +# elif CONFIG_SYS_RESERVED != 6 +# error "CONFIG_SYS_RESERVED must have the value 6" +# endif +#else +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 1" +# elif CONFIG_SYS_RESERVED != 1 +# error "CONFIG_SYS_RESERVED must have the value 1" +# endif +#endif + +/* Cortex-A system calls ************************************************************/ + +/* SYS call 0: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (0) + +#ifdef CONFIG_BUILD_KERNEL +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_context_restore (1) + +/* SYS call 2: + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) + * noreturn_function; + */ + +#define SYS_task_start (2) + +/* SYS call 3: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (3) + +/* SYS call 4: + * + * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, + * FAR void *ucontext); + */ + +#define SYS_signal_handler (4) + +/* SYS call 5: + * + * void signal_handler_return(void); + */ + +#define SYS_signal_handler_return (5) + +#endif /* CONFIG_BUILD_KERNEL */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* CONFIG_LIB_SYSCALL */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_SVCALL_H */ diff --git a/arch/arm/src/armv7-m/Kconfig b/arch/arm/src/armv7-m/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..406e2e46624be926494b130312a91d539bc3c02b --- /dev/null +++ b/arch/arm/src/armv7-m/Kconfig @@ -0,0 +1,181 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "ARMV7M Configuration Options" + +config ARMV7M_HAVE_ICACHE + bool + default n + +config ARMV7M_HAVE_DCACHE + bool + default n + +config ARMV7M_ICACHE + bool "Use I-Cache" + default n + depends on ARMV7M_HAVE_ICACHE + +config ARMV7M_DCACHE + bool "Use D-Cache" + default n + depends on ARMV7M_HAVE_DCACHE + +config ARMV7M_DCACHE_WRITETHROUGH + bool "D-Cache Write-Through" + default n + depends on ARMV7M_DCACHE + +config ARMV7M_HAVE_ITCM + bool + default n + +config ARMV7M_HAVE_DTCM + bool + default n + +config ARMV7M_ITCM + bool "Use ITCM" + default n + depends on ARMV7M_HAVE_ITCM + +config ARMV7M_DTCM + bool "Use DTCM" + default n + depends on ARMV7M_HAVE_DTCM + +choice + prompt "Toolchain Selection" + default ARMV7M_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS + default ARMV7M_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS + +config ARMV7M_TOOLCHAIN_IARW + bool "IAR for Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_IAR + +config ARMV7M_TOOLCHAIN_IARL + bool "IAR for Linux" + depends on HOST_LINUX + select ARM_TOOLCHAIN_IAR + +config ARMV7M_TOOLCHAIN_ATOLLIC + bool "Atollic Lite/Pro for Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_CODEREDL + bool "CodeRed for Linux" + depends on HOST_LINUX + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_CODEREDW + bool "CodeRed for Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_CODESOURCERYL + bool "CodeSourcery GNU toolchain under Linux" + depends on HOST_LINUX + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_CODESOURCERYW + bool "CodeSourcery GNU toolchain under Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_DEVKITARM + bool "devkitARM GNU toolchain" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + +config ARMV7M_TOOLCHAIN_GNU_EABIL + bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)" + depends on !WINDOWS_NATIVE + select ARM_TOOLCHAIN_GNU + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi. + +config ARMV7M_TOOLCHAIN_GNU_EABIW + bool "Generic GNU EABI toolchain under Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi. + +config ARMV7M_TOOLCHAIN_RAISONANCE + bool "STMicro Raisonance for Windows" + depends on HOST_WINDOWS + select ARM_TOOLCHAIN_GNU + +endchoice + +config ARMV7M_OABI_TOOLCHAIN + bool "OABI (vs EABI)" + default n + depends on ARMV7M_TOOLCHAIN_BUILDROOT + ---help--- + Most of the older buildroot toolchains are OABI and are named + arm-nuttx-elf- vs. arm-nuttx-eabi- + +config ARMV7M_TARGET2_PREL + bool "R_ARM_TARGET2 is PC relative" + default n if !UCLIBCXX_EXCEPTION + default y if UCLIBCXX_EXCEPTION + depends on ELF + ---help--- + Perform a PC relative relocation for relocation type R_ARM_TARGET2 + +config ARMV7M_HAVE_STACKCHECK + bool + default n + +config ARMV7M_STACKCHECK + bool "Check for stack overflow on each function call" + default n + depends on ARMV7M_HAVE_STACKCHECK + ---help--- + This check uses R10 to check for a stack overflow within each + function call. This has performances and code size impacts, but it + will be able to catch hard to find stack overflows. + + Currently only available only for the STM32, SAM3/4 and SAMA5D + architectures. The changes are not complex and patches for + other architectures will be accepted. + + This option requires that you are using a GCC toolchain and that + you also include -finstrument-functions in your CFLAGS when you + compile. This addition to your CFLAGS should probably be added + to the definition of the CFFLAGS in your board Make.defs file. + +config ARMV7M_ITMSYSLOG + bool "ITM SYSLOG support" + default n + select SYSLOG + ---help--- + Enable hooks to support ITM syslog output. This requires additional + MCU support in order to be used. See arch/arm/src/armv7-m/itm_syslog.h + for additional initialization information. + +if ARMV7M_ITMSYSLOG + +config ARMV7M_ITMSYSLOG_PORT + int "ITM SYSLOG Port" + default 0 + range 0 31 + +config ARMV7M_ITMSYSLOG_SWODIV + int "ITM SYSLOG SWO divider" + default 15 + range 1 8192 + +endif # ARMV7M_ITMSYSLOG diff --git a/arch/arm/src/armv7-m/Toolchain.defs b/arch/arm/src/armv7-m/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..8cfcaa3e1d4e6405c9ec2ad8c5396970fd1e5b43 --- /dev/null +++ b/arch/arm/src/armv7-m/Toolchain.defs @@ -0,0 +1,271 @@ +############################################################################ +# arch/arm/src/armv7-m/Toolchain.defs +# +# Copyright (C) 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Handle old-style chip-specific toolchain names in the absence of +# a new-style toolchain specification, force the selection of a single +# toolchain and allow the selected toolchain to be overridden by a +# command-line selection. +# + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= ATOLLIC +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_CODEREDL) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= CODEREDL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_CODEREDW) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= CODEREDW +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= CODESOURCERYL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYW) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= CODESOURCERYW +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_DEVKITARM) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= DEVKITARM +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_RAISONANCE) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= RAISONANCE +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= GNU_EABIL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW) \ + ),y) + CONFIG_ARMV7M_TOOLCHAIN ?= GNU_EABIW +endif + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# Parametrization for ARCHCPUFLAGS + +ifeq ($(CONFIG_ARCH_CORTEXM4),y) + TOOLCHAIN_ARM7EM := y + TOOLCHAIN_MCPU := -mcpu=cortex-m4 + TOOLCHAIN_MTUNE := -mtune=cortex-m4 + TOOLCHAIN_MARCH := -march=armv7e-m + ifeq ($(CONFIG_ARCH_FPU),y) + ifeq ($(CONFIG_ARCH_DPFPU),y) + TOOLCHAIN_MFLOAT := -mfpu=fpv4-sp -mfloat-abi=hard + else + TOOLCHAIN_MFLOAT := -mfpu=fpv4-sp-d16 -mfloat-abi=hard + endif + else + TOOLCHAIN_MFLOAT := -mfloat-abi=soft + endif +else ifeq ($(CONFIG_ARCH_CORTEXM7),y) + TOOLCHAIN_ARM7EM := y + TOOLCHAIN_MCPU := -mcpu=cortex-m7 + TOOLCHAIN_MTUNE := -mtune=cortex-m7 + TOOLCHAIN_MARCH := -march=armv7e-m + ifeq ($(CONFIG_ARCH_FPU),y) + ifeq ($(CONFIG_ARCH_DPFPU),y) + TOOLCHAIN_MFLOAT := -mfpu=fpv5-d16 -mfloat-abi=hard + else + TOOLCHAIN_MFLOAT := -mfpu=fpv5-sp-d16 -mfloat-abi=hard + endif + else + TOOLCHAIN_MFLOAT := -mfloat-abi=soft + endif +else # ifeq ($(CONFIG_ARCH_CORTEXM3),y) + TOOLCHAIN_ARM7EM := n + TOOLCHAIN_MCPU := -mcpu=cortex-m3 + TOOLCHAIN_MTUNE := -mtune=cortex-m3 + TOOLCHAIN_MARCH := -march=armv7-m + TOOLCHAIN_MFLOAT := -mfloat-abi=soft +endif + +# Atollic toolchain under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),ATOLLIC) + CROSSDEV ?= arm-atollic-eabi- + ARCROSSDEV ?= arm-atollic-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),BUILDROOT) +ifeq ($(CONFIG_ARMV7M_OABI_TOOLCHAIN),y) + CROSSDEV ?= arm-nuttx-elf- + ARCROSSDEV ?= arm-nuttx-elf- + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) $(TOOLCHAIN_MFLOAT) +else + CROSSDEV ?= arm-nuttx-eabi- + ARCROSSDEV ?= arm-nuttx-eabi- + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif + MAXOPTIMIZATION ?= -Os +endif + +# Code Red RedSuite under Linux + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODEREDL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif + +# Code Red RedSuite under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODEREDW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# CodeSourcery under Linux + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODESOURCERYL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif + +# CodeSourcery under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODESOURCERYW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# devkitARM under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),DEVKITARM) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif + +# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),GNU_EABIL) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif + +# Generic GNU EABI toolchain under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),GNU_EABIW) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + MAXOPTIMIZATION ?= -Os + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# Raisonance RIDE7 under Windows + +ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),RAISONANCE) + CROSSDEV ?= arm-none-eabi- + ARCROSSDEV ?= arm-none-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + ARCHCPUFLAGS = $(TOOLCHAIN_MCPU) -mthumb $(TOOLCHAIN_MFLOAT) +endif diff --git a/arch/arm/src/armv7-m/arch_clean_dcache.c b/arch/arm/src/armv7-m/arch_clean_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..735623b4cda1783a47194aaf03f7317b50b9762d --- /dev/null +++ b/arch/arm/src/armv7-m/arch_clean_dcache.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_clean_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +void arch_clean_dcache(uintptr_t start, uintptr_t end) +{ + uint32_t ccsidr; + uint32_t smask; + uint32_t sshift; + uint32_t ways; + uint32_t wshift; + uint32_t ssize; + uint32_t set; + uint32_t sw; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + smask = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCCSW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + /* Clean the D-Cache over the range of addresses */ + + ssize = (1 << sshift); + start &= ~(ssize - 1); + ARM_DSB(); + + do + { + int32_t tmpways = ways; + + /* Isolate the cache line associated with this address. For example + * if the cache line size is 32 bytes and the cache size is 16KB, then + * + * sshift = 5 : Offset to the beginning of the set field + * smask = 0x007f : Mask of the set field + */ + + set = ((uint32_t)start >> sshift) & smask; + + /* Clean and invalidate each way for this cacheline */ + + do + { + sw = ((tmpways << wshift) | (set << sshift)); + putreg32(sw, NVIC_DCCSW); + } + while (tmpways--); + + /* Increment the address by the size of one cache line. */ + + start += ssize; + } + while (start < end); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */ diff --git a/arch/arm/src/armv7-m/arch_clean_dcache_all.c b/arch/arm/src/armv7-m/arch_clean_dcache_all.c new file mode 100644 index 0000000000000000000000000000000000000000..296780bee5d377cb8ff2d457c2f6caca117a2147 --- /dev/null +++ b/arch/arm/src/armv7-m/arch_clean_dcache_all.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_clean_dcache_all.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_clean_dcache_all + * + * Description: + * Clean the entire data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +void arch_clean_dcache_all(void) +{ + uint32_t ccsidr; + uint32_t sshift; + uint32_t wshift; + uint32_t sw; + uint32_t sets; + uint32_t ways; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCCSW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + ARM_DSB(); + + /* Clean the entire D-Cache */ + + do + { + int32_t tmpways = ways; + + do + { + sw = ((tmpways << wshift) | (sets << sshift)); + putreg32(sw, NVIC_DCCSW); + } + while (tmpways--); + } + while (sets--); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */ diff --git a/arch/arm/src/armv7-m/arch_disable_dcache.c b/arch/arm/src/armv7-m/arch_disable_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..c21c8cb8f76427581fb7590c88d7d95e3dea650a --- /dev/null +++ b/arch/arm/src/armv7-m/arch_disable_dcache.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_disable_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#ifdef CONFIG_ARMV7M_DCACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_disable_dcache + * + * Description: + * Disable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arch_disable_dcache(void) +{ + uint32_t ccsidr; + uint32_t ccr; + uint32_t sshift; + uint32_t wshift; + uint32_t sw; + uint32_t sets; + uint32_t ways; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + ARM_DSB(); + + /* Disable the D-Cache */ + + ccr = getreg32(NVIC_CFGCON); + ccr &= ~NVIC_CFGCON_DC; + putreg32(ccr, NVIC_CFGCON); + + /* Clean and invalidate the entire D-Cache */ + + do + { + int32_t tmpways = ways; + + do + { + sw = ((tmpways << wshift) | (sets << sshift)); + putreg32(sw, NVIC_DCCISW); + } + while (tmpways--); + } + while (sets--); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE */ diff --git a/arch/arm/src/armv7-m/arch_enable_dcache.c b/arch/arm/src/armv7-m/arch_enable_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..9c1abe47c69bda0cc1a0469cf89b415e1652f5e1 --- /dev/null +++ b/arch/arm/src/armv7-m/arch_enable_dcache.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_enable_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#ifdef CONFIG_ARMV7M_DCACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_enable_dcache + * + * Description: + * Enable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arch_enable_dcache(void) +{ + uint32_t ccsidr; + uint32_t ccr; + uint32_t sshift; + uint32_t wshift; + uint32_t sw; + uint32_t sets; + uint32_t ways; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + /* Invalidate the entire D-Cache */ + + ARM_DSB(); + do + { + int32_t tmpways = ways; + + do + { + sw = ((tmpways << wshift) | (sets << sshift)); + putreg32(sw, NVIC_DCISW); + } + while (tmpways--); + } + while (sets--); + + ARM_DSB(); + + /* Enable the D-Cache */ + + ccr = getreg32(NVIC_CFGCON); + ccr |= NVIC_CFGCON_DC; + putreg32(ccr, NVIC_CFGCON); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE */ diff --git a/arch/arm/src/armv7-m/arch_flush_dcache.c b/arch/arm/src/armv7-m/arch_flush_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..c884eec041e354080283c6a237fc141ac33c51e8 --- /dev/null +++ b/arch/arm/src/armv7-m/arch_flush_dcache.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_flush_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +void arch_flush_dcache(uintptr_t start, uintptr_t end) +{ + uint32_t ccsidr; + uint32_t smask; + uint32_t sshift; + uint32_t ways; + uint32_t wshift; + uint32_t ssize; + uint32_t set; + uint32_t sw; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + smask = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + /* Clean and invalidate the D-Cache over the range of addresses */ + + ssize = (1 << sshift); + start &= ~(ssize - 1); + ARM_DSB(); + + do + { + int32_t tmpways = ways; + + /* Isolate the cache line associated with this address. For example + * if the cache line size is 32 bytes and the cache size is 16KB, then + * + * sshift = 5 : Offset to the beginning of the set field + * smask = 0x007f : Mask of the set field + */ + + set = ((uint32_t)start >> sshift) & smask; + + /* Clean and invalidate each way for this cacheline */ + + do + { + sw = ((tmpways << wshift) | (set << sshift)); + putreg32(sw, NVIC_DCCISW); + } + while (tmpways--); + + /* Increment the address by the size of one cache line. */ + + start += ssize; + } + while (start < end); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */ diff --git a/arch/arm/src/armv7-m/arch_flush_dcache_all.c b/arch/arm/src/armv7-m/arch_flush_dcache_all.c new file mode 100644 index 0000000000000000000000000000000000000000..33f80b85ba8a919d956793ff5cf8794a42c4b3c0 --- /dev/null +++ b/arch/arm/src/armv7-m/arch_flush_dcache_all.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_flush_dcache_all.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_flush_dcache_all + * + * Description: + * Flush the entire data cache by cleaning and invalidating the D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +void arch_flush_dcache_all(void) +{ + uint32_t ccsidr; + uint32_t sshift; + uint32_t wshift; + uint32_t sw; + uint32_t sets; + uint32_t ways; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + ARM_DSB(); + + /* Clean and invalidate the entire D-Cache */ + + do + { + int32_t tmpways = ways; + + do + { + sw = ((tmpways << wshift) | (sets << sshift)); + putreg32(sw, NVIC_DCCISW); + } + while (tmpways--); + } + while (sets--); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */ diff --git a/arch/arm/src/armv7-m/arch_invalidate_dcache.c b/arch/arm/src/armv7-m/arch_invalidate_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..899252cde7f543889008ad3b8110b7b99ac2c27e --- /dev/null +++ b/arch/arm/src/armv7-m/arch_invalidate_dcache.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_invalidate_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#ifdef CONFIG_ARMV7M_DCACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +void arch_invalidate_dcache(uintptr_t start, uintptr_t end) +{ + uint32_t ccsidr; + uint32_t smask; + uint32_t sshift; + uint32_t ways; + uint32_t wshift; + uint32_t ssize; + uint32_t set; + uint32_t sw; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + smask = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + /* Invalidate the D-Cache over the range of addresses */ + + ssize = (1 << sshift); + start &= ~(ssize - 1); + ARM_DSB(); + + do + { + int32_t tmpways = ways; + + /* Isolate the cache line associated with this address. For example + * if the cache line size is 32 bytes and the cache size is 16KB, then + * + * sshift = 5 : Offset to the beginning of the set field + * smask = 0x007f : Mask of the set field + */ + + set = ((uint32_t)start >> sshift) & smask; + + /* Clean and invalidate each way for this cacheline */ + + do + { + sw = ((tmpways << wshift) | (set << sshift)); + putreg32(sw, NVIC_DCISW); + } + while (tmpways--); + + /* Increment the address by the size of one cache line. */ + + start += ssize; + } + while (start < end); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE */ diff --git a/arch/arm/src/armv7-m/arch_invalidate_dcache_all.c b/arch/arm/src/armv7-m/arch_invalidate_dcache_all.c new file mode 100644 index 0000000000000000000000000000000000000000..380d7d5015b34d8b46417b62693b4c9da0073880 --- /dev/null +++ b/arch/arm/src/armv7-m/arch_invalidate_dcache_all.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arch_invalidate_dcache_all.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cache.h" + +#ifdef CONFIG_ARMV7M_DCACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arch_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arch_invalidate_dcache_all(void) +{ + uint32_t ccsidr; + uint32_t sshift; + uint32_t wshift; + uint32_t sw; + uint32_t sets; + uint32_t ways; + + /* Get the characteristics of the D-Cache */ + + ccsidr = getreg32(NVIC_CCSIDR); + sets = CCSIDR_SETS(ccsidr); /* (Number of sets) - 1 */ + sshift = CCSIDR_LSSHIFT(ccsidr) + 4; /* log2(cache-line-size-in-bytes) */ + ways = CCSIDR_WAYS(ccsidr); /* (Number of ways) - 1 */ + + /* Calculate the bit offset for the way field in the DCISW register by + * counting the number of leading zeroes. For example: + * + * Number of Value of ways Field + * Ways 'ways' Offset + * 2 1 31 + * 4 3 30 + * 8 7 29 + * ... + */ + + wshift = arm_clz(ways) & 0x1f; + + ARM_DSB(); + + /* Invalidate the entire D-Cache */ + + do + { + int32_t tmpways = ways; + + do + { + sw = ((tmpways << wshift) | (sets << sshift)); + putreg32(sw, NVIC_DCISW); + } + while (tmpways--); + } + while (sets--); + + ARM_DSB(); + ARM_ISB(); +} + +#endif /* CONFIG_ARMV7M_DCACHE */ diff --git a/arch/arm/src/armv7-m/cache.h b/arch/arm/src/armv7-m/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b40b30a11d5087fde62a3111c7886ccb5f7fc5 --- /dev/null +++ b/arch/arm/src/armv7-m/cache.h @@ -0,0 +1,476 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/cache.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this header file derives from the ARM CMSIS core_cm7.h + * header file which has a compatible 3-clause BSD license: + * + * Copyright (c) 2009 - 2014 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name ARM, NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_CACHE_H +#define __ARCH_ARM_SRC_ARMV7_M_CACHE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" +#include "nvic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Cache Size ID (CCSIDR) register macros used by inline functions + * Given the value of the CCSIDR reginer (n): + * + * CCSIDR_WAYS - Returns the (number of ways) - 1 + * CCSIDR_SETS - Returns the (number of sets) - 1 + * CCSIDR_LSSHIFT - Returns log2(cache line size in words) - 2 + * Eg. 0 -> 4 words + * 1 -> 8 words + * ... + */ + +#define CCSIDR_WAYS(n) \ + (((n) & NVIC_CCSIDR_ASSOCIATIVITY_MASK) >> NVIC_CCSIDR_ASSOCIATIVITY_SHIFT) +#define CCSIDR_SETS(n) \ + (((n) & NVIC_CCSIDR_NUMSETS_MASK) >> NVIC_CCSIDR_NUMSETS_SHIFT) +#define CCSIDR_LSSHIFT(n) \ + (((n) & NVIC_CCSIDR_LINESIZE_MASK) >> NVIC_CCSIDR_LINESIZE_SHIFT) + +/* intrinsics are used in these inline functions */ + +#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory") +#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory") +#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory") + +#define ARM_DSB() arm_dsb(15) +#define ARM_ISB() arm_isb(15) +#define ARM_DMB() arm_dmb(15) + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: arm_clz + * + * Description: + * Access to CLZ instructions + * + * Input Parameters: + * value - The value to perform the CLZ operation on + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t arm_clz(unsigned int value) +{ + uint32_t ret; + + __asm__ __volatile__ ("clz %0, %1" : "=r"(ret) : "r"(value)); + return ret; +} + +/**************************************************************************** + * Name: arch_enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_enable_icache(void) +{ +#ifdef CONFIG_ARMV7M_ICACHE + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Invalidate the entire I-Cache */ + + putreg32(0, NVIC_ICIALLU); + + /* Enable the I-Cache */ + + regval = getreg32(NVIC_CFGCON); + regval |= NVIC_CFGCON_IC; + putreg32(regval, NVIC_CFGCON); + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** + * Name: arch_disable_icache + * + * Description: + * Disable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_disable_icache(void) +{ +#ifdef CONFIG_ARMV7M_ICACHE + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Disable the I-Cache */ + + regval = getreg32(NVIC_CFGCON); + regval &= ~NVIC_CFGCON_IC; + putreg32(regval, NVIC_CFGCON); + + /* Invalidate the entire I-Cache */ + + putreg32(0, NVIC_ICIALLU); + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** + * Name: arch_invalidate_icache_all + * + * Description: + * Invalidate the entire contents of I cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_invalidate_icache_all(void) +{ +#ifdef CONFIG_ARMV7M_ICACHE + ARM_DSB(); + ARM_ISB(); + + /* Invalidate the entire I-Cache */ + + putreg32(0, NVIC_ICIALLU); + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** + * Name: arch_dcache_writethrough + * + * Description: + * Configure the D-Cache for Write-Through operation. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_ARMV7M_DCACHE) && defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) +static inline void arch_dcache_writethrough(void) +{ + uint32_t regval = getreg32(NVIC_CACR); + regval |= NVIC_CACR_FORCEWT; + putreg32(regval, NVIC_CACR); +} +#else +# define arch_dcache_writethrough() +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + + /**************************************************************************** + * Name: arch_enable_dcache + * + * Description: + * Enable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +void arch_enable_dcache(void); +#else +# define arch_enable_dcache() +#endif + +/**************************************************************************** + * Name: arch_disable_dcache + * + * Description: + * Disable the D-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +void arch_disable_dcache(void); +#else +# define arch_disable_dcache() +#endif + +/**************************************************************************** + * Name: arch_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +void arch_invalidate_dcache(uintptr_t start, uintptr_t end); +#else +# define arch_invalidate_dcache(s,e) +#endif + +/**************************************************************************** + * Name: arch_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +void arch_invalidate_dcache_all(void); +#else +# define arch_invalidate_dcache_all() +#endif + +/**************************************************************************** + * Name: arch_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * NOTE: This operation is un-necessary if the DCACHE is configured in + * write-through mode. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) +void arch_clean_dcache(uintptr_t start, uintptr_t end); +#else +# define arch_clean_dcache(s,e) +#endif + +/**************************************************************************** + * Name: arch_clean_dcache_all + * + * Description: + * Clean the entire data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * NOTE: This operation is un-necessary if the DCACHE is configured in + * write-through mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) +void arch_clean_dcache_all(void); +#else +# define arch_clean_dcache_all() +#endif + +/**************************************************************************** + * Name: arch_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * NOTE: If DCACHE write-through is configured, then this operation is the + * same as arch_invalidate_cache(). + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +#ifdef CONFIG_ARMV7M_DCACHE_WRITETHROUGH +# define arch_flush_dcache(s,e) arch_invalidate_dcache(s,e) +#else +void arch_flush_dcache(uintptr_t start, uintptr_t end); +#endif +#else +# define arch_flush_dcache(s,e) +#endif + +/**************************************************************************** + * Name: arch_flush_dcache_all + * + * Description: + * Flush the entire data cache by cleaning and invalidating the D cache. + * + * NOTE: If DCACHE write-through is configured, then this operation is the + * same as arch_invalidate_cache_all(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_DCACHE +#ifdef CONFIG_ARMV7M_DCACHE_WRITETHROUGH +# define arch_flush_dcache_all() arch_invalidate_dcache_all() +#else +void arch_flush_dcache_all(void); +#endif +#else +# define arch_flush_dcache_all() +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_CACHE_H */ diff --git a/arch/arm/src/armv7-m/dwt.h b/arch/arm/src/armv7-m/dwt.h new file mode 100644 index 0000000000000000000000000000000000000000..6cd66c9594dcf22827a6e9da03b363c1689ce5e2 --- /dev/null +++ b/arch/arm/src/armv7-m/dwt.h @@ -0,0 +1,173 @@ +/*********************************************************************************************** + * arch/arm/src/armv7-m/dwt.h + * + * 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. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_DWT_H +#define __ARCH_ARM_SRC_ARMV7_M_DWT_H + +/*********************************************************************************************** + * Pre-processor Definitions + ***********************************************************************************************/ + +/* Data Watchpoint and Trace Register (DWT) Definitions ****************************************/ +/* DWT Register Base Address *******************************************************************/ + +#define DWT_BASE (0xe0001000ul) + +/* DWT Register Addresses **********************************************************************/ + +#define DWT_CTRL (DWT_BASE+0x0000) /* Control Register */ +#define DWT_CYCCNT (DWT_BASE+0x0004) /* Cycle Count Register */ +#define DWT_CPICNT (DWT_BASE+0x0008) /* CPI Count Register */ +#define DWT_EXCCNT (DWT_BASE+0x000c) /* Exception Overhead Count Register */ +#define DWT_SLEEPCNT (DWT_BASE+0x0010) /* Sleep Count Register */ +#define DWT_LSUCNT (DWT_BASE+0x0014) /* LSU Count Register */ +#define DWT_FOLDCNT (DWT_BASE+0x0018) /* Folded-instruction Count Register */ +#define DWT_PCSR (DWT_BASE+0x001c) /* Program Counter Sample Register */ +#define DWT_COMP0 (DWT_BASE+0x0020) /* Comparator Register 0 */ +#define DWT_MASK0 (DWT_BASE+0x0024) /* Mask Register 0 */ +#define DWT_FUNCTION0 (DWT_BASE+0x0028) /* Function Register 0 */ +#define DWT_COMP1 (DWT_BASE+0x0030) /* Comparator Register 1 */ +#define DWT_MASK1 (DWT_BASE+0x0034) /* Mask Register 1 */ +#define DWT_FUNCTION1 (DWT_BASE+0x0038) /* Function Register 1 */ +#define DWT_COMP2 (DWT_BASE+0x0040) /* Comparator Register 2 */ +#define DWT_MASK2 (DWT_BASE+0x0044) /* Mask Register 2 */ +#define DWT_FUNCTION2 (DWT_BASE+0x0048) /* Function Register 2 */ +#define DWT_COMP3 (DWT_BASE+0x0050) /* Comparator Register 3 */ +#define DWT_MASK3 (DWT_BASE+0x0054) /* Mask Register 3 */ +#define DWT_FUNCTION3 (DWT_BASE+0x0058) /* Function Register 3 */ + +/* DWT Register Bit Field 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 */ + +#define DWT_CPICNT_CPICNT_Pos 0 /* DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xfful << DWT_CPICNT_CPICNT_Pos) /* DWT CPICNT: CPICNT Mask */ + +#define DWT_EXCCNT_EXCCNT_Pos 0 /* DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xfful << DWT_EXCCNT_EXCCNT_Pos) /* DWT EXCCNT: EXCCNT Mask */ + +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /* DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xfful << DWT_SLEEPCNT_SLEEPCNT_Pos) /* DWT SLEEPCNT: SLEEPCNT Mask */ + +#define DWT_LSUCNT_LSUCNT_Pos 0 /* DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xfful << DWT_LSUCNT_LSUCNT_Pos) /* DWT LSUCNT: LSUCNT Mask */ + +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /* DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xfful << DWT_FOLDCNT_FOLDCNT_Pos) /* DWT FOLDCNT: FOLDCNT Mask */ + +#define DWT_MASK_MASK_Pos 0 /* DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1ful << DWT_MASK_MASK_Pos) /* DWT MASK: MASK Mask */ + +#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 */ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_DWT_H */ diff --git a/arch/arm/src/armv7-m/etm.h b/arch/arm/src/armv7-m/etm.h new file mode 100644 index 0000000000000000000000000000000000000000..eef1ba85d04888639a3f0437bacf093f23454e9c --- /dev/null +++ b/arch/arm/src/armv7-m/etm.h @@ -0,0 +1,916 @@ +/******************************************************************************************************************************* + * arch/arm/src/armv7-m/etm.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_ETM_H +#define __ARCH_ARM_SRC_ARMV7_M_ETM_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* ETM Register Base Address ***************************************************************************************************/ + +#define ETM_BASE (0xe0041000ul) + +/* ETM Register Offsets ********************************************************************************************************/ + +#define ETM_ETMCR_OFFSET 0x0000 /* Main Control Register */ +#define ETM_ETMCCR_OFFSET 0x0004 /* Configuration Code Register */ +#define ETM_ETMTRIGGER_OFFSET 0x0008 /* ETM Trigger Event Register */ +#define ETM_ETMSR_OFFSET 0x0010 /* ETM Status Register */ +#define ETM_ETMSCR_OFFSET 0x0014 /* ETM System Configuration Register */ +#define ETM_ETMTEEVR_OFFSET 0x0020 /* ETM TraceEnable Event Register */ +#define ETM_ETMTECR1_OFFSET 0x0024 /* ETM Trace control Register */ +#define ETM_ETMFFLR_OFFSET 0x002c /* ETM Fifo Full Level Register */ +#define ETM_ETMCNTRLDVR1_OFFSET 0x0140 /* Counter Reload Value */ +#define ETM_ETMSYNCFR_OFFSET 0x01e0 /* Synchronisation Frequency Register */ +#define ETM_ETMIDR_OFFSET 0x01e4 /* ID Register */ +#define ETM_ETMCCER_OFFSET 0x01e8 /* Configuration Code Extension Register */ +#define ETM_ETMTESSEICR_OFFSET 0x01f0 /* TraceEnable Start/Stop EmbeddedICE Control Register */ +#define ETM_ETMTSEVR_OFFSET 0x01f8 /* Timestamp Event Register */ +#define ETM_ETMTRACEIDR_OFFSET 0x0200 /* CoreSight Trace ID Register */ +#define ETM_ETMIDR2_OFFSET 0x0208 /* ETM ID Register 2 */ +#define ETM_ETMPDSR_OFFSET 0x0314 /* Device Power-down Status Register */ +#define ETM_ETMISCIN_OFFSET 0x0ee0 /* Integration Test Miscellaneous Inputs Register */ +#define ETM_ITTRIGOUT_OFFSET 0x0ee8 /* Integration Test Trigger Out Register */ +#define ETM_ETMITATBCTR2_OFFSET 0x0ef0 /* ETM Integration Test ATB Control 2 Register */ +#define ETM_ETMITATBCTR0_OFFSET 0x0ef8 /* ETM Integration Test ATB Control 0 Register */ +#define ETM_ETMITCTRL_OFFSET 0x0f00 /* ETM Integration Control Register */ +#define ETM_ETMCLAIMSET_OFFSET 0x0fa0 /* ETM Claim Tag Set Register */ +#define ETM_ETMCLAIMCLR_OFFSET 0x0fa4 /* ETM Claim Tag Clear Register */ +#define ETM_ETMLAR_OFFSET 0x0fb0 /* ETM Lock Access Register */ +#define ETM_ETMLSR_OFFSET 0x0fb4 /* Lock Status Register */ +#define ETM_ETMAUTHSTATUS_OFFSET 0x0fb8 /* ETM Authentication Status Register */ +#define ETM_ETMDEVTYPE_OFFSET 0x0fcc /* CoreSight Device Type Register */ +#define ETM_ETMPIDR4_OFFSET 0x0fd0 /* Peripheral ID4 Register */ +#define ETM_ETMPIDR5_OFFSET 0x0fd4 /* Peripheral ID5 Register */ +#define ETM_ETMPIDR6_OFFSET 0x0fd8 /* Peripheral ID6 Register */ +#define ETM_ETMPIDR7_OFFSET 0x0fdc /* Peripheral ID7 Register */ +#define ETM_ETMPIDR0_OFFSET 0x0fe0 /* Peripheral ID0 Register */ +#define ETM_ETMPIDR1_OFFSET 0x0fe4 /* Peripheral ID1 Register */ +#define ETM_ETMPIDR2_OFFSET 0x0fe8 /* Peripheral ID2 Register */ +#define ETM_ETMPIDR3_OFFSET 0x0fec /* Peripheral ID3 Register */ +#define ETM_ETMCIDR0_OFFSET 0x0ff0 /* Component ID0 Register */ +#define ETM_ETMCIDR1_OFFSET 0x0ff4 /* Component ID1 Register */ +#define ETM_ETMCIDR2_OFFSET 0x0ff8 /* Component ID2 Register */ +#define ETM_ETMCIDR3_OFFSET 0x0ffc /* Component ID3 Register */ + +/* ETM Register Addresses ******************************************************************************************************/ + +#define ETM_ETMCR (ETM_BASE+ETM_ETMCR_OFFSET) +#define ETM_ETMCCR (ETM_BASE+ETM_ETMCCR_OFFSET) +#define ETM_ETMTRIGGER (ETM_BASE+ETM_ETMTRIGGER_OFFSET) +#define ETM_ETMSR (ETM_BASE+ETM_ETMSR_OFFSET) +#define ETM_ETMSCR (ETM_BASE+ETM_ETMSCR_OFFSET) +#define ETM_ETMTEEVR (ETM_BASE+ETM_ETMTEEVR_OFFSET) +#define ETM_ETMTECR1 (ETM_BASE+ETM_ETMTECR1_OFFSET) +#define ETM_ETMFFLR (ETM_BASE+ETM_ETMFFLR_OFFSET) +#define ETM_ETMCNTRLDVR1 (ETM_BASE+ETM_ETMCNTRLDVR1_OFFSET) +#define ETM_ETMSYNCFR (ETM_BASE+ETM_ETMSYNCFR_OFFSET) +#define ETM_ETMIDR (ETM_BASE+ETM_ETMIDR_OFFSET) +#define ETM_ETMCCER (ETM_BASE+ETM_ETMCCER_OFFSET) +#define ETM_ETMTESSEICR (ETM_BASE+ETM_ETMTESSEICR_OFFSET) +#define ETM_ETMTSEVR (ETM_BASE+ETM_ETMTSEVR_OFFSET) +#define ETM_ETMTRACEIDR (ETM_BASE+ETM_ETMTRACEIDR_OFFSET) +#define ETM_ETMIDR2 (ETM_BASE+ETM_ETMIDR2_OFFSET) +#define ETM_ETMPDSR (ETM_BASE+ETM_ETMPDSR_OFFSET) +#define ETM_ETMISCIN (ETM_BASE+ETM_ETMISCIN_OFFSET) +#define ETM_ITTRIGOUT (ETM_BASE+ETM_ITTRIGOUT_OFFSET) +#define ETM_ETMITATBCTR2 (ETM_BASE+ETM_ETMITATBCTR2_OFFSET) +#define ETM_ETMITATBCTR0 (ETM_BASE+ETM_ETMITATBCTR0_OFFSET) +#define ETM_ETMITCTRL (ETM_BASE+ETM_ETMITCTRL_OFFSET) +#define ETM_ETMCLAIMSET (ETM_BASE+ETM_ETMCLAIMSET_OFFSET) +#define ETM_ETMCLAIMCLR (ETM_BASE+ETM_ETMCLAIMCLR_OFFSET) +#define ETM_ETMLAR (ETM_BASE+ETM_ETMLAR_OFFSET) +#define ETM_ETMLSR (ETM_BASE+ETM_ETMLSR_OFFSET) +#define ETM_ETMAUTHSTATUS (ETM_BASE+ETM_ETMAUTHSTATUS_OFFSET) +#define ETM_ETMDEVTYPE (ETM_BASE+ETM_ETMDEVTYPE_OFFSET) +#define ETM_ETMPIDR4 (ETM_BASE+ETM_ETMPIDR4_OFFSET) +#define ETM_ETMPIDR5 (ETM_BASE+ETM_ETMPIDR5_OFFSET) +#define ETM_ETMPIDR6 (ETM_BASE+ETM_ETMPIDR6_OFFSET) +#define ETM_ETMPIDR7 (ETM_BASE+ETM_ETMPIDR7_OFFSET) +#define ETM_ETMPIDR0 (ETM_BASE+ETM_ETMPIDR0_OFFSET) +#define ETM_ETMPIDR1 (ETM_BASE+ETM_ETMPIDR1_OFFSET) +#define ETM_ETMPIDR2 (ETM_BASE+ETM_ETMPIDR2_OFFSET) +#define ETM_ETMPIDR3 (ETM_BASE+ETM_ETMPIDR3_OFFSET) +#define ETM_ETMCIDR0 (ETM_BASE+ETM_ETMCIDR0_OFFSET) +#define ETM_ETMCIDR1 (ETM_BASE+ETM_ETMCIDR1_OFFSET) +#define ETM_ETMCIDR2 (ETM_BASE+ETM_ETMCIDR2_OFFSET) +#define ETM_ETMCIDR3 (ETM_BASE+ETM_ETMCIDR3_OFFSET) + +/* ETM Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for ETM ETMCR */ + +#define _ETM_ETMCR_RESETVALUE 0x00000411UL /* Default value for ETM_ETMCR */ +#define _ETM_ETMCR_MASK 0x10632FF1UL /* Mask for ETM_ETMCR */ + +#define ETM_ETMCR_POWERDWN (0x1UL << 0) /* ETM Control in low power mode */ +#define _ETM_ETMCR_POWERDWN_SHIFT 0 /* Shift value for ETM_POWERDWN */ +#define _ETM_ETMCR_POWERDWN_MASK 0x1UL /* Bit mask for ETM_POWERDWN */ +#define _ETM_ETMCR_POWERDWN_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_POWERDWN_DEFAULT (_ETM_ETMCR_POWERDWN_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define _ETM_ETMCR_PORTSIZE_SHIFT 4 /* Shift value for ETM_PORTSIZE */ +#define _ETM_ETMCR_PORTSIZE_MASK 0x70UL /* Bit mask for ETM_PORTSIZE */ +#define _ETM_ETMCR_PORTSIZE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_PORTSIZE_DEFAULT (_ETM_ETMCR_PORTSIZE_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_STALL (0x1UL << 7) /* Stall Processor */ +#define _ETM_ETMCR_STALL_SHIFT 7 /* Shift value for ETM_STALL */ +#define _ETM_ETMCR_STALL_MASK 0x80UL /* Bit mask for ETM_STALL */ +#define _ETM_ETMCR_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_STALL_DEFAULT (_ETM_ETMCR_STALL_DEFAULT << 7) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_BRANCHOUTPUT (0x1UL << 8) /* Branch Output */ +#define _ETM_ETMCR_BRANCHOUTPUT_SHIFT 8 /* Shift value for ETM_BRANCHOUTPUT */ +#define _ETM_ETMCR_BRANCHOUTPUT_MASK 0x100UL /* Bit mask for ETM_BRANCHOUTPUT */ +#define _ETM_ETMCR_BRANCHOUTPUT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_BRANCHOUTPUT_DEFAULT (_ETM_ETMCR_BRANCHOUTPUT_DEFAULT << 8) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_DBGREQCTRL (0x1UL << 9) /* Debug Request Control */ +#define _ETM_ETMCR_DBGREQCTRL_SHIFT 9 /* Shift value for ETM_DBGREQCTRL */ +#define _ETM_ETMCR_DBGREQCTRL_MASK 0x200UL /* Bit mask for ETM_DBGREQCTRL */ +#define _ETM_ETMCR_DBGREQCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_DBGREQCTRL_DEFAULT (_ETM_ETMCR_DBGREQCTRL_DEFAULT << 9) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_ETMPROG (0x1UL << 10) /* ETM Programming */ +#define _ETM_ETMCR_ETMPROG_SHIFT 10 /* Shift value for ETM_ETMPROG */ +#define _ETM_ETMCR_ETMPROG_MASK 0x400UL /* Bit mask for ETM_ETMPROG */ +#define _ETM_ETMCR_ETMPROG_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_ETMPROG_DEFAULT (_ETM_ETMCR_ETMPROG_DEFAULT << 10) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_ETMPORTSEL (0x1UL << 11) /* ETM Port Selection */ +#define _ETM_ETMCR_ETMPORTSEL_SHIFT 11 /* Shift value for ETM_ETMPORTSEL */ +#define _ETM_ETMCR_ETMPORTSEL_MASK 0x800UL /* Bit mask for ETM_ETMPORTSEL */ +#define _ETM_ETMCR_ETMPORTSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define _ETM_ETMCR_ETMPORTSEL_ETMLOW 0x00000000UL /* Mode ETMLOW for ETM_ETMCR */ +#define _ETM_ETMCR_ETMPORTSEL_ETMHIGH 0x00000001UL /* Mode ETMHIGH for ETM_ETMCR */ +#define ETM_ETMCR_ETMPORTSEL_DEFAULT (_ETM_ETMCR_ETMPORTSEL_DEFAULT << 11) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_ETMPORTSEL_ETMLOW (_ETM_ETMCR_ETMPORTSEL_ETMLOW << 11) /* Shifted mode ETMLOW for ETM_ETMCR */ +#define ETM_ETMCR_ETMPORTSEL_ETMHIGH (_ETM_ETMCR_ETMPORTSEL_ETMHIGH << 11) /* Shifted mode ETMHIGH for ETM_ETMCR */ +#define ETM_ETMCR_PORTMODE2 (0x1UL << 13) /* Port Mode[2] */ +#define _ETM_ETMCR_PORTMODE2_SHIFT 13 /* Shift value for ETM_PORTMODE2 */ +#define _ETM_ETMCR_PORTMODE2_MASK 0x2000UL /* Bit mask for ETM_PORTMODE2 */ +#define _ETM_ETMCR_PORTMODE2_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_PORTMODE2_DEFAULT (_ETM_ETMCR_PORTMODE2_DEFAULT << 13) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define _ETM_ETMCR_PORTMODE_SHIFT 16 /* Shift value for ETM_PORTMODE */ +#define _ETM_ETMCR_PORTMODE_MASK 0x30000UL /* Bit mask for ETM_PORTMODE */ +#define _ETM_ETMCR_PORTMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_PORTMODE_DEFAULT (_ETM_ETMCR_PORTMODE_DEFAULT << 16) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define _ETM_ETMCR_EPORTSIZE_SHIFT 21 /* Shift value for ETM_EPORTSIZE */ +#define _ETM_ETMCR_EPORTSIZE_MASK 0x600000UL /* Bit mask for ETM_EPORTSIZE */ +#define _ETM_ETMCR_EPORTSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_EPORTSIZE_DEFAULT (_ETM_ETMCR_EPORTSIZE_DEFAULT << 21) /* Shifted mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_TSTAMPEN (0x1UL << 28) /* Time Stamp Enable */ +#define _ETM_ETMCR_TSTAMPEN_SHIFT 28 /* Shift value for ETM_TSTAMPEN */ +#define _ETM_ETMCR_TSTAMPEN_MASK 0x10000000UL /* Bit mask for ETM_TSTAMPEN */ +#define _ETM_ETMCR_TSTAMPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCR */ +#define ETM_ETMCR_TSTAMPEN_DEFAULT (_ETM_ETMCR_TSTAMPEN_DEFAULT << 28) /* Shifted mode DEFAULT for ETM_ETMCR */ + +/* Bit fields for ETM ETMCCR */ + +#define _ETM_ETMCCR_RESETVALUE 0x8C802000UL /* Default value for ETM_ETMCCR */ +#define _ETM_ETMCCR_MASK 0x8FFFFFFFUL /* Mask for ETM_ETMCCR */ + +#define _ETM_ETMCCR_ADRCMPPAIR_SHIFT 0 /* Shift value for ETM_ADRCMPPAIR */ +#define _ETM_ETMCCR_ADRCMPPAIR_MASK 0xFUL /* Bit mask for ETM_ADRCMPPAIR */ +#define _ETM_ETMCCR_ADRCMPPAIR_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_ADRCMPPAIR_DEFAULT (_ETM_ETMCCR_ADRCMPPAIR_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_DATACMPNUM_SHIFT 4 /* Shift value for ETM_DATACMPNUM */ +#define _ETM_ETMCCR_DATACMPNUM_MASK 0xF0UL /* Bit mask for ETM_DATACMPNUM */ +#define _ETM_ETMCCR_DATACMPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_DATACMPNUM_DEFAULT (_ETM_ETMCCR_DATACMPNUM_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_MMDECCNT_SHIFT 8 /* Shift value for ETM_MMDECCNT */ +#define _ETM_ETMCCR_MMDECCNT_MASK 0x1F00UL /* Bit mask for ETM_MMDECCNT */ +#define _ETM_ETMCCR_MMDECCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_MMDECCNT_DEFAULT (_ETM_ETMCCR_MMDECCNT_DEFAULT << 8) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_COUNTNUM_SHIFT 13 /* Shift value for ETM_COUNTNUM */ +#define _ETM_ETMCCR_COUNTNUM_MASK 0xE000UL /* Bit mask for ETM_COUNTNUM */ +#define _ETM_ETMCCR_COUNTNUM_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_COUNTNUM_DEFAULT (_ETM_ETMCCR_COUNTNUM_DEFAULT << 13) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_SEQPRES (0x1UL << 16) /* Sequencer Present */ +#define _ETM_ETMCCR_SEQPRES_SHIFT 16 /* Shift value for ETM_SEQPRES */ +#define _ETM_ETMCCR_SEQPRES_MASK 0x10000UL /* Bit mask for ETM_SEQPRES */ +#define _ETM_ETMCCR_SEQPRES_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_SEQPRES_DEFAULT (_ETM_ETMCCR_SEQPRES_DEFAULT << 16) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_EXTINPNUM_SHIFT 17 /* Shift value for ETM_EXTINPNUM */ +#define _ETM_ETMCCR_EXTINPNUM_MASK 0xE0000UL /* Bit mask for ETM_EXTINPNUM */ +#define _ETM_ETMCCR_EXTINPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_EXTINPNUM_ZERO 0x00000000UL /* Mode ZERO for ETM_ETMCCR */ +#define _ETM_ETMCCR_EXTINPNUM_ONE 0x00000001UL /* Mode ONE for ETM_ETMCCR */ +#define _ETM_ETMCCR_EXTINPNUM_TWO 0x00000002UL /* Mode TWO for ETM_ETMCCR */ +#define ETM_ETMCCR_EXTINPNUM_DEFAULT (_ETM_ETMCCR_EXTINPNUM_DEFAULT << 17) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_EXTINPNUM_ZERO (_ETM_ETMCCR_EXTINPNUM_ZERO << 17) /* Shifted mode ZERO for ETM_ETMCCR */ +#define ETM_ETMCCR_EXTINPNUM_ONE (_ETM_ETMCCR_EXTINPNUM_ONE << 17) /* Shifted mode ONE for ETM_ETMCCR */ +#define ETM_ETMCCR_EXTINPNUM_TWO (_ETM_ETMCCR_EXTINPNUM_TWO << 17) /* Shifted mode TWO for ETM_ETMCCR */ +#define _ETM_ETMCCR_EXTOUTNUM_SHIFT 20 /* Shift value for ETM_EXTOUTNUM */ +#define _ETM_ETMCCR_EXTOUTNUM_MASK 0x700000UL /* Bit mask for ETM_EXTOUTNUM */ +#define _ETM_ETMCCR_EXTOUTNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_EXTOUTNUM_DEFAULT (_ETM_ETMCCR_EXTOUTNUM_DEFAULT << 20) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_FIFOFULLPRES (0x1UL << 23) /* FIFIO FULL present */ +#define _ETM_ETMCCR_FIFOFULLPRES_SHIFT 23 /* Shift value for ETM_FIFOFULLPRES */ +#define _ETM_ETMCCR_FIFOFULLPRES_MASK 0x800000UL /* Bit mask for ETM_FIFOFULLPRES */ +#define _ETM_ETMCCR_FIFOFULLPRES_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_FIFOFULLPRES_DEFAULT (_ETM_ETMCCR_FIFOFULLPRES_DEFAULT << 23) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define _ETM_ETMCCR_IDCOMPNUM_SHIFT 24 /* Shift value for ETM_IDCOMPNUM */ +#define _ETM_ETMCCR_IDCOMPNUM_MASK 0x3000000UL /* Bit mask for ETM_IDCOMPNUM */ +#define _ETM_ETMCCR_IDCOMPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_IDCOMPNUM_DEFAULT (_ETM_ETMCCR_IDCOMPNUM_DEFAULT << 24) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_TRACESS (0x1UL << 26) /* Trace Start/Stop Block Present */ +#define _ETM_ETMCCR_TRACESS_SHIFT 26 /* Shift value for ETM_TRACESS */ +#define _ETM_ETMCCR_TRACESS_MASK 0x4000000UL /* Bit mask for ETM_TRACESS */ +#define _ETM_ETMCCR_TRACESS_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_TRACESS_DEFAULT (_ETM_ETMCCR_TRACESS_DEFAULT << 26) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_MMACCESS (0x1UL << 27) /* Coprocessor and Memeory Access */ +#define _ETM_ETMCCR_MMACCESS_SHIFT 27 /* Shift value for ETM_MMACCESS */ +#define _ETM_ETMCCR_MMACCESS_MASK 0x8000000UL /* Bit mask for ETM_MMACCESS */ +#define _ETM_ETMCCR_MMACCESS_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_MMACCESS_DEFAULT (_ETM_ETMCCR_MMACCESS_DEFAULT << 27) /* Shifted mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_ETMID (0x1UL << 31) /* ETM ID Register Present */ +#define _ETM_ETMCCR_ETMID_SHIFT 31 /* Shift value for ETM_ETMID */ +#define _ETM_ETMCCR_ETMID_MASK 0x80000000UL /* Bit mask for ETM_ETMID */ +#define _ETM_ETMCCR_ETMID_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCR */ +#define ETM_ETMCCR_ETMID_DEFAULT (_ETM_ETMCCR_ETMID_DEFAULT << 31) /* Shifted mode DEFAULT for ETM_ETMCCR */ + +/* Bit fields for ETM ETMTRIGGER */ + +#define _ETM_ETMTRIGGER_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTRIGGER */ +#define _ETM_ETMTRIGGER_MASK 0x0001FFFFUL /* Mask for ETM_ETMTRIGGER */ + +#define _ETM_ETMTRIGGER_RESA_SHIFT 0 /* Shift value for ETM_RESA */ +#define _ETM_ETMTRIGGER_RESA_MASK 0x7FUL /* Bit mask for ETM_RESA */ +#define _ETM_ETMTRIGGER_RESA_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTRIGGER */ +#define ETM_ETMTRIGGER_RESA_DEFAULT (_ETM_ETMTRIGGER_RESA_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTRIGGER */ +#define _ETM_ETMTRIGGER_RESB_SHIFT 7 /* Shift value for ETM_RESB */ +#define _ETM_ETMTRIGGER_RESB_MASK 0x3F80UL /* Bit mask for ETM_RESB */ +#define _ETM_ETMTRIGGER_RESB_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTRIGGER */ +#define ETM_ETMTRIGGER_RESB_DEFAULT (_ETM_ETMTRIGGER_RESB_DEFAULT << 7) /* Shifted mode DEFAULT for ETM_ETMTRIGGER */ +#define _ETM_ETMTRIGGER_ETMFCN_SHIFT 14 /* Shift value for ETM_ETMFCN */ +#define _ETM_ETMTRIGGER_ETMFCN_MASK 0x1C000UL /* Bit mask for ETM_ETMFCN */ +#define _ETM_ETMTRIGGER_ETMFCN_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTRIGGER */ +#define ETM_ETMTRIGGER_ETMFCN_DEFAULT (_ETM_ETMTRIGGER_ETMFCN_DEFAULT << 14) /* Shifted mode DEFAULT for ETM_ETMTRIGGER */ + +/* Bit fields for ETM ETMSR */ + +#define _ETM_ETMSR_RESETVALUE 0x00000002UL /* Default value for ETM_ETMSR */ +#define _ETM_ETMSR_MASK 0x0000000FUL /* Mask for ETM_ETMSR */ + +#define ETM_ETMSR_ETHOF (0x1UL << 0) /* ETM Overflow */ +#define _ETM_ETMSR_ETHOF_SHIFT 0 /* Shift value for ETM_ETHOF */ +#define _ETM_ETMSR_ETHOF_MASK 0x1UL /* Bit mask for ETM_ETHOF */ +#define _ETM_ETMSR_ETHOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_ETHOF_DEFAULT (_ETM_ETMSR_ETHOF_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_ETMPROGBIT (0x1UL << 1) /* ETM Programming Bit Status */ +#define _ETM_ETMSR_ETMPROGBIT_SHIFT 1 /* Shift value for ETM_ETMPROGBIT */ +#define _ETM_ETMSR_ETMPROGBIT_MASK 0x2UL /* Bit mask for ETM_ETMPROGBIT */ +#define _ETM_ETMSR_ETMPROGBIT_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_ETMPROGBIT_DEFAULT (_ETM_ETMSR_ETMPROGBIT_DEFAULT << 1) /* Shifted mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_TRACESTAT (0x1UL << 2) /* Trace Start/Stop Status */ +#define _ETM_ETMSR_TRACESTAT_SHIFT 2 /* Shift value for ETM_TRACESTAT */ +#define _ETM_ETMSR_TRACESTAT_MASK 0x4UL /* Bit mask for ETM_TRACESTAT */ +#define _ETM_ETMSR_TRACESTAT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_TRACESTAT_DEFAULT (_ETM_ETMSR_TRACESTAT_DEFAULT << 2) /* Shifted mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_TRIGBIT (0x1UL << 3) /* Trigger Bit */ +#define _ETM_ETMSR_TRIGBIT_SHIFT 3 /* Shift value for ETM_TRIGBIT */ +#define _ETM_ETMSR_TRIGBIT_MASK 0x8UL /* Bit mask for ETM_TRIGBIT */ +#define _ETM_ETMSR_TRIGBIT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMSR */ +#define ETM_ETMSR_TRIGBIT_DEFAULT (_ETM_ETMSR_TRIGBIT_DEFAULT << 3) /* Shifted mode DEFAULT for ETM_ETMSR */ + +/* Bit fields for ETM ETMSCR */ + +#define _ETM_ETMSCR_RESETVALUE 0x00020D09UL /* Default value for ETM_ETMSCR */ +#define _ETM_ETMSCR_MASK 0x00027F0FUL /* Mask for ETM_ETMSCR */ + +#define _ETM_ETMSCR_MAXPORTSIZE_SHIFT 0 /* Shift value for ETM_MAXPORTSIZE */ +#define _ETM_ETMSCR_MAXPORTSIZE_MASK 0x7UL /* Bit mask for ETM_MAXPORTSIZE */ +#define _ETM_ETMSCR_MAXPORTSIZE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_MAXPORTSIZE_DEFAULT (_ETM_ETMSCR_MAXPORTSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_Reserved (0x1UL << 3) /* Reserved */ +#define _ETM_ETMSCR_Reserved_SHIFT 3 /* Shift value for ETM_Reserved */ +#define _ETM_ETMSCR_Reserved_MASK 0x8UL /* Bit mask for ETM_Reserved */ +#define _ETM_ETMSCR_Reserved_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_Reserved_DEFAULT (_ETM_ETMSCR_Reserved_DEFAULT << 3) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_FIFOFULL (0x1UL << 8) /* FIFO FULL Supported */ +#define _ETM_ETMSCR_FIFOFULL_SHIFT 8 /* Shift value for ETM_FIFOFULL */ +#define _ETM_ETMSCR_FIFOFULL_MASK 0x100UL /* Bit mask for ETM_FIFOFULL */ +#define _ETM_ETMSCR_FIFOFULL_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_FIFOFULL_DEFAULT (_ETM_ETMSCR_FIFOFULL_DEFAULT << 8) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_MAXPORTSIZE3 (0x1UL << 9) /* Max Port Size[3] */ +#define _ETM_ETMSCR_MAXPORTSIZE3_SHIFT 9 /* Shift value for ETM_MAXPORTSIZE3 */ +#define _ETM_ETMSCR_MAXPORTSIZE3_MASK 0x200UL /* Bit mask for ETM_MAXPORTSIZE3 */ +#define _ETM_ETMSCR_MAXPORTSIZE3_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_MAXPORTSIZE3_DEFAULT (_ETM_ETMSCR_MAXPORTSIZE3_DEFAULT << 9) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_PORTSIZE (0x1UL << 10) /* Port Size Supported */ +#define _ETM_ETMSCR_PORTSIZE_SHIFT 10 /* Shift value for ETM_PORTSIZE */ +#define _ETM_ETMSCR_PORTSIZE_MASK 0x400UL /* Bit mask for ETM_PORTSIZE */ +#define _ETM_ETMSCR_PORTSIZE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_PORTSIZE_DEFAULT (_ETM_ETMSCR_PORTSIZE_DEFAULT << 10) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_PORTMODE (0x1UL << 11) /* Port Mode Supported */ +#define _ETM_ETMSCR_PORTMODE_SHIFT 11 /* Shift value for ETM_PORTMODE */ +#define _ETM_ETMSCR_PORTMODE_MASK 0x800UL /* Bit mask for ETM_PORTMODE */ +#define _ETM_ETMSCR_PORTMODE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_PORTMODE_DEFAULT (_ETM_ETMSCR_PORTMODE_DEFAULT << 11) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define _ETM_ETMSCR_PROCNUM_SHIFT 12 /* Shift value for ETM_PROCNUM */ +#define _ETM_ETMSCR_PROCNUM_MASK 0x7000UL /* Bit mask for ETM_PROCNUM */ +#define _ETM_ETMSCR_PROCNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_PROCNUM_DEFAULT (_ETM_ETMSCR_PROCNUM_DEFAULT << 12) /* Shifted mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_NOFETCHCOMP (0x1UL << 17) /* No Fetch Comparison */ +#define _ETM_ETMSCR_NOFETCHCOMP_SHIFT 17 /* Shift value for ETM_NOFETCHCOMP */ +#define _ETM_ETMSCR_NOFETCHCOMP_MASK 0x20000UL /* Bit mask for ETM_NOFETCHCOMP */ +#define _ETM_ETMSCR_NOFETCHCOMP_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMSCR */ +#define ETM_ETMSCR_NOFETCHCOMP_DEFAULT (_ETM_ETMSCR_NOFETCHCOMP_DEFAULT << 17) /* Shifted mode DEFAULT for ETM_ETMSCR */ + +/* Bit fields for ETM ETMTEEVR */ + +#define _ETM_ETMTEEVR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTEEVR */ +#define _ETM_ETMTEEVR_MASK 0x0001FFFFUL /* Mask for ETM_ETMTEEVR */ + +#define _ETM_ETMTEEVR_RESA_SHIFT 0 /* Shift value for ETM_RESA */ +#define _ETM_ETMTEEVR_RESA_MASK 0x7FUL /* Bit mask for ETM_RESA */ +#define _ETM_ETMTEEVR_RESA_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTEEVR */ +#define ETM_ETMTEEVR_RESA_DEFAULT (_ETM_ETMTEEVR_RESA_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTEEVR */ +#define _ETM_ETMTEEVR_RESB_SHIFT 7 /* Shift value for ETM_RESB */ +#define _ETM_ETMTEEVR_RESB_MASK 0x3F80UL /* Bit mask for ETM_RESB */ +#define _ETM_ETMTEEVR_RESB_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTEEVR */ +#define ETM_ETMTEEVR_RESB_DEFAULT (_ETM_ETMTEEVR_RESB_DEFAULT << 7) /* Shifted mode DEFAULT for ETM_ETMTEEVR */ +#define _ETM_ETMTEEVR_ETMFCNEN_SHIFT 14 /* Shift value for ETM_ETMFCNEN */ +#define _ETM_ETMTEEVR_ETMFCNEN_MASK 0x1C000UL /* Bit mask for ETM_ETMFCNEN */ +#define _ETM_ETMTEEVR_ETMFCNEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTEEVR */ +#define ETM_ETMTEEVR_ETMFCNEN_DEFAULT (_ETM_ETMTEEVR_ETMFCNEN_DEFAULT << 14) /* Shifted mode DEFAULT for ETM_ETMTEEVR */ + +/* Bit fields for ETM ETMTECR1 */ + +#define _ETM_ETMTECR1_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_MASK 0x03FFFFFFUL /* Mask for ETM_ETMTECR1 */ + +#define _ETM_ETMTECR1_ADRCMP_SHIFT 0 /* Shift value for ETM_ADRCMP */ +#define _ETM_ETMTECR1_ADRCMP_MASK 0xFFUL /* Bit mask for ETM_ADRCMP */ +#define _ETM_ETMTECR1_ADRCMP_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_ADRCMP_DEFAULT (_ETM_ETMTECR1_ADRCMP_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_MEMMAP_SHIFT 8 /* Shift value for ETM_MEMMAP */ +#define _ETM_ETMTECR1_MEMMAP_MASK 0xFFFF00UL /* Bit mask for ETM_MEMMAP */ +#define _ETM_ETMTECR1_MEMMAP_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_MEMMAP_DEFAULT (_ETM_ETMTECR1_MEMMAP_DEFAULT << 8) /* Shifted mode DEFAULT for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_INCEXCTL (0x1UL << 24) /* Trace Include/Exclude Flag */ +#define _ETM_ETMTECR1_INCEXCTL_SHIFT 24 /* Shift value for ETM_INCEXCTL */ +#define _ETM_ETMTECR1_INCEXCTL_MASK 0x1000000UL /* Bit mask for ETM_INCEXCTL */ +#define _ETM_ETMTECR1_INCEXCTL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_INCEXCTL_INC 0x00000000UL /* Mode INC for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_INCEXCTL_EXC 0x00000001UL /* Mode EXC for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_INCEXCTL_DEFAULT (_ETM_ETMTECR1_INCEXCTL_DEFAULT << 24) /* Shifted mode DEFAULT for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_INCEXCTL_INC (_ETM_ETMTECR1_INCEXCTL_INC << 24) /* Shifted mode INC for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_INCEXCTL_EXC (_ETM_ETMTECR1_INCEXCTL_EXC << 24) /* Shifted mode EXC for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_TCE (0x1UL << 25) /* Trace Control Enable */ +#define _ETM_ETMTECR1_TCE_SHIFT 25 /* Shift value for ETM_TCE */ +#define _ETM_ETMTECR1_TCE_MASK 0x2000000UL /* Bit mask for ETM_TCE */ +#define _ETM_ETMTECR1_TCE_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_TCE_EN 0x00000000UL /* Mode EN for ETM_ETMTECR1 */ +#define _ETM_ETMTECR1_TCE_DIS 0x00000001UL /* Mode DIS for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_TCE_DEFAULT (_ETM_ETMTECR1_TCE_DEFAULT << 25) /* Shifted mode DEFAULT for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_TCE_EN (_ETM_ETMTECR1_TCE_EN << 25) /* Shifted mode EN for ETM_ETMTECR1 */ +#define ETM_ETMTECR1_TCE_DIS (_ETM_ETMTECR1_TCE_DIS << 25) /* Shifted mode DIS for ETM_ETMTECR1 */ + +/* Bit fields for ETM ETMFFLR */ + +#define _ETM_ETMFFLR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMFFLR */ +#define _ETM_ETMFFLR_MASK 0x000000FFUL /* Mask for ETM_ETMFFLR */ + +#define _ETM_ETMFFLR_BYTENUM_SHIFT 0 /* Shift value for ETM_BYTENUM */ +#define _ETM_ETMFFLR_BYTENUM_MASK 0xFFUL /* Bit mask for ETM_BYTENUM */ +#define _ETM_ETMFFLR_BYTENUM_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMFFLR */ +#define ETM_ETMFFLR_BYTENUM_DEFAULT (_ETM_ETMFFLR_BYTENUM_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMFFLR */ + +/* Bit fields for ETM ETMCNTRLDVR1 */ + +#define _ETM_ETMCNTRLDVR1_RESETVALUE 0x00000000UL /* Default value for ETM_ETMCNTRLDVR1 */ +#define _ETM_ETMCNTRLDVR1_MASK 0x0000FFFFUL /* Mask for ETM_ETMCNTRLDVR1 */ + +#define _ETM_ETMCNTRLDVR1_COUNT_SHIFT 0 /* Shift value for ETM_COUNT */ +#define _ETM_ETMCNTRLDVR1_COUNT_MASK 0xFFFFUL /* Bit mask for ETM_COUNT */ +#define _ETM_ETMCNTRLDVR1_COUNT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCNTRLDVR1 */ +#define ETM_ETMCNTRLDVR1_COUNT_DEFAULT (_ETM_ETMCNTRLDVR1_COUNT_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCNTRLDVR1 */ + +/* Bit fields for ETM ETMSYNCFR */ + +#define _ETM_ETMSYNCFR_RESETVALUE 0x00000400UL /* Default value for ETM_ETMSYNCFR */ +#define _ETM_ETMSYNCFR_MASK 0x00000FFFUL /* Mask for ETM_ETMSYNCFR */ + +#define _ETM_ETMSYNCFR_FREQ_SHIFT 0 /* Shift value for ETM_FREQ */ +#define _ETM_ETMSYNCFR_FREQ_MASK 0xFFFUL /* Bit mask for ETM_FREQ */ +#define _ETM_ETMSYNCFR_FREQ_DEFAULT 0x00000400UL /* Mode DEFAULT for ETM_ETMSYNCFR */ +#define ETM_ETMSYNCFR_FREQ_DEFAULT (_ETM_ETMSYNCFR_FREQ_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMSYNCFR */ + +/* Bit fields for ETM ETMIDR */ + +#define _ETM_ETMIDR_RESETVALUE 0x4114F253UL /* Default value for ETM_ETMIDR */ +#define _ETM_ETMIDR_MASK 0xFF1DFFFFUL /* Mask for ETM_ETMIDR */ + +#define _ETM_ETMIDR_IMPVER_SHIFT 0 /* Shift value for ETM_IMPVER */ +#define _ETM_ETMIDR_IMPVER_MASK 0xFUL /* Bit mask for ETM_IMPVER */ +#define _ETM_ETMIDR_IMPVER_DEFAULT 0x00000003UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_IMPVER_DEFAULT (_ETM_ETMIDR_IMPVER_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define _ETM_ETMIDR_ETMMINVER_SHIFT 4 /* Shift value for ETM_ETMMINVER */ +#define _ETM_ETMIDR_ETMMINVER_MASK 0xF0UL /* Bit mask for ETM_ETMMINVER */ +#define _ETM_ETMIDR_ETMMINVER_DEFAULT 0x00000005UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_ETMMINVER_DEFAULT (_ETM_ETMIDR_ETMMINVER_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define _ETM_ETMIDR_ETMMAJVER_SHIFT 8 /* Shift value for ETM_ETMMAJVER */ +#define _ETM_ETMIDR_ETMMAJVER_MASK 0xF00UL /* Bit mask for ETM_ETMMAJVER */ +#define _ETM_ETMIDR_ETMMAJVER_DEFAULT 0x00000002UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_ETMMAJVER_DEFAULT (_ETM_ETMIDR_ETMMAJVER_DEFAULT << 8) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define _ETM_ETMIDR_PROCFAM_SHIFT 12 /* Shift value for ETM_PROCFAM */ +#define _ETM_ETMIDR_PROCFAM_MASK 0xF000UL /* Bit mask for ETM_PROCFAM */ +#define _ETM_ETMIDR_PROCFAM_DEFAULT 0x0000000FUL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_PROCFAM_DEFAULT (_ETM_ETMIDR_PROCFAM_DEFAULT << 12) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_LPCF (0x1UL << 16) /* Load PC First */ +#define _ETM_ETMIDR_LPCF_SHIFT 16 /* Shift value for ETM_LPCF */ +#define _ETM_ETMIDR_LPCF_MASK 0x10000UL /* Bit mask for ETM_LPCF */ +#define _ETM_ETMIDR_LPCF_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_LPCF_DEFAULT (_ETM_ETMIDR_LPCF_DEFAULT << 16) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_THUMBT (0x1UL << 18) /* 32-bit Thumb Instruction Tracing */ +#define _ETM_ETMIDR_THUMBT_SHIFT 18 /* Shift value for ETM_THUMBT */ +#define _ETM_ETMIDR_THUMBT_MASK 0x40000UL /* Bit mask for ETM_THUMBT */ +#define _ETM_ETMIDR_THUMBT_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_THUMBT_DEFAULT (_ETM_ETMIDR_THUMBT_DEFAULT << 18) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_SECEXT (0x1UL << 19) /* Security Extension Support */ +#define _ETM_ETMIDR_SECEXT_SHIFT 19 /* Shift value for ETM_SECEXT */ +#define _ETM_ETMIDR_SECEXT_MASK 0x80000UL /* Bit mask for ETM_SECEXT */ +#define _ETM_ETMIDR_SECEXT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_SECEXT_DEFAULT (_ETM_ETMIDR_SECEXT_DEFAULT << 19) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_BPE (0x1UL << 20) /* Branch Packet Encoding */ +#define _ETM_ETMIDR_BPE_SHIFT 20 /* Shift value for ETM_BPE */ +#define _ETM_ETMIDR_BPE_MASK 0x100000UL /* Bit mask for ETM_BPE */ +#define _ETM_ETMIDR_BPE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_BPE_DEFAULT (_ETM_ETMIDR_BPE_DEFAULT << 20) /* Shifted mode DEFAULT for ETM_ETMIDR */ +#define _ETM_ETMIDR_IMPCODE_SHIFT 24 /* Shift value for ETM_IMPCODE */ +#define _ETM_ETMIDR_IMPCODE_MASK 0xFF000000UL /* Bit mask for ETM_IMPCODE */ +#define _ETM_ETMIDR_IMPCODE_DEFAULT 0x00000041UL /* Mode DEFAULT for ETM_ETMIDR */ +#define ETM_ETMIDR_IMPCODE_DEFAULT (_ETM_ETMIDR_IMPCODE_DEFAULT << 24) /* Shifted mode DEFAULT for ETM_ETMIDR */ + +/* Bit fields for ETM ETMCCER */ + +#define _ETM_ETMCCER_RESETVALUE 0x18541800UL /* Default value for ETM_ETMCCER */ +#define _ETM_ETMCCER_MASK 0x387FFFFBUL /* Mask for ETM_ETMCCER */ + +#define _ETM_ETMCCER_EXTINPSEL_SHIFT 0 /* Shift value for ETM_EXTINPSEL */ +#define _ETM_ETMCCER_EXTINPSEL_MASK 0x3UL /* Bit mask for ETM_EXTINPSEL */ +#define _ETM_ETMCCER_EXTINPSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_EXTINPSEL_DEFAULT (_ETM_ETMCCER_EXTINPSEL_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define _ETM_ETMCCER_EXTINPBUS_SHIFT 3 /* Shift value for ETM_EXTINPBUS */ +#define _ETM_ETMCCER_EXTINPBUS_MASK 0x7F8UL /* Bit mask for ETM_EXTINPBUS */ +#define _ETM_ETMCCER_EXTINPBUS_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_EXTINPBUS_DEFAULT (_ETM_ETMCCER_EXTINPBUS_DEFAULT << 3) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_READREGS (0x1UL << 11) /* Readable Registers */ +#define _ETM_ETMCCER_READREGS_SHIFT 11 /* Shift value for ETM_READREGS */ +#define _ETM_ETMCCER_READREGS_MASK 0x800UL /* Bit mask for ETM_READREGS */ +#define _ETM_ETMCCER_READREGS_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_READREGS_DEFAULT (_ETM_ETMCCER_READREGS_DEFAULT << 11) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_DADDRCMP (0x1UL << 12) /* Data Address comparisons */ +#define _ETM_ETMCCER_DADDRCMP_SHIFT 12 /* Shift value for ETM_DADDRCMP */ +#define _ETM_ETMCCER_DADDRCMP_MASK 0x1000UL /* Bit mask for ETM_DADDRCMP */ +#define _ETM_ETMCCER_DADDRCMP_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_DADDRCMP_DEFAULT (_ETM_ETMCCER_DADDRCMP_DEFAULT << 12) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define _ETM_ETMCCER_INSTRES_SHIFT 13 /* Shift value for ETM_INSTRES */ +#define _ETM_ETMCCER_INSTRES_MASK 0xE000UL /* Bit mask for ETM_INSTRES */ +#define _ETM_ETMCCER_INSTRES_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_INSTRES_DEFAULT (_ETM_ETMCCER_INSTRES_DEFAULT << 13) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define _ETM_ETMCCER_EICEWPNT_SHIFT 16 /* Shift value for ETM_EICEWPNT */ +#define _ETM_ETMCCER_EICEWPNT_MASK 0xF0000UL /* Bit mask for ETM_EICEWPNT */ +#define _ETM_ETMCCER_EICEWPNT_DEFAULT 0x00000004UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_EICEWPNT_DEFAULT (_ETM_ETMCCER_EICEWPNT_DEFAULT << 16) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TEICEWPNT (0x1UL << 20) /* Trace Sart/Stop Block Uses EmbeddedICE watchpoint inputs */ +#define _ETM_ETMCCER_TEICEWPNT_SHIFT 20 /* Shift value for ETM_TEICEWPNT */ +#define _ETM_ETMCCER_TEICEWPNT_MASK 0x100000UL /* Bit mask for ETM_TEICEWPNT */ +#define _ETM_ETMCCER_TEICEWPNT_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TEICEWPNT_DEFAULT (_ETM_ETMCCER_TEICEWPNT_DEFAULT << 20) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_EICEIMP (0x1UL << 21) /* EmbeddedICE Behavior control Implemented */ +#define _ETM_ETMCCER_EICEIMP_SHIFT 21 /* Shift value for ETM_EICEIMP */ +#define _ETM_ETMCCER_EICEIMP_MASK 0x200000UL /* Bit mask for ETM_EICEIMP */ +#define _ETM_ETMCCER_EICEIMP_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_EICEIMP_DEFAULT (_ETM_ETMCCER_EICEIMP_DEFAULT << 21) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TIMP (0x1UL << 22) /* Timestamping Implemented */ +#define _ETM_ETMCCER_TIMP_SHIFT 22 /* Shift value for ETM_TIMP */ +#define _ETM_ETMCCER_TIMP_MASK 0x400000UL /* Bit mask for ETM_TIMP */ +#define _ETM_ETMCCER_TIMP_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TIMP_DEFAULT (_ETM_ETMCCER_TIMP_DEFAULT << 22) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_RFCNT (0x1UL << 27) /* Reduced Function Counter */ +#define _ETM_ETMCCER_RFCNT_SHIFT 27 /* Shift value for ETM_RFCNT */ +#define _ETM_ETMCCER_RFCNT_MASK 0x8000000UL /* Bit mask for ETM_RFCNT */ +#define _ETM_ETMCCER_RFCNT_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_RFCNT_DEFAULT (_ETM_ETMCCER_RFCNT_DEFAULT << 27) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TENC (0x1UL << 28) /* Timestamp Encoding */ +#define _ETM_ETMCCER_TENC_SHIFT 28 /* Shift value for ETM_TENC */ +#define _ETM_ETMCCER_TENC_MASK 0x10000000UL /* Bit mask for ETM_TENC */ +#define _ETM_ETMCCER_TENC_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TENC_DEFAULT (_ETM_ETMCCER_TENC_DEFAULT << 28) /* Shifted mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TSIZE (0x1UL << 29) /* Timestamp Size */ +#define _ETM_ETMCCER_TSIZE_SHIFT 29 /* Shift value for ETM_TSIZE */ +#define _ETM_ETMCCER_TSIZE_MASK 0x20000000UL /* Bit mask for ETM_TSIZE */ +#define _ETM_ETMCCER_TSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCCER */ +#define ETM_ETMCCER_TSIZE_DEFAULT (_ETM_ETMCCER_TSIZE_DEFAULT << 29) /* Shifted mode DEFAULT for ETM_ETMCCER */ + +/* Bit fields for ETM ETMTESSEICR */ + +#define _ETM_ETMTESSEICR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTESSEICR */ +#define _ETM_ETMTESSEICR_MASK 0x000F000FUL /* Mask for ETM_ETMTESSEICR */ + +#define _ETM_ETMTESSEICR_STARTRSEL_SHIFT 0 /* Shift value for ETM_STARTRSEL */ +#define _ETM_ETMTESSEICR_STARTRSEL_MASK 0xFUL /* Bit mask for ETM_STARTRSEL */ +#define _ETM_ETMTESSEICR_STARTRSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTESSEICR */ +#define ETM_ETMTESSEICR_STARTRSEL_DEFAULT (_ETM_ETMTESSEICR_STARTRSEL_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTESSEICR */ +#define _ETM_ETMTESSEICR_STOPRSEL_SHIFT 16 /* Shift value for ETM_STOPRSEL */ +#define _ETM_ETMTESSEICR_STOPRSEL_MASK 0xF0000UL /* Bit mask for ETM_STOPRSEL */ +#define _ETM_ETMTESSEICR_STOPRSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTESSEICR */ +#define ETM_ETMTESSEICR_STOPRSEL_DEFAULT (_ETM_ETMTESSEICR_STOPRSEL_DEFAULT << 16) /* Shifted mode DEFAULT for ETM_ETMTESSEICR */ + +/* Bit fields for ETM ETMTSEVR */ + +#define _ETM_ETMTSEVR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTSEVR */ +#define _ETM_ETMTSEVR_MASK 0x0001FFFFUL /* Mask for ETM_ETMTSEVR */ + +#define _ETM_ETMTSEVR_RESAEVT_SHIFT 0 /* Shift value for ETM_RESAEVT */ +#define _ETM_ETMTSEVR_RESAEVT_MASK 0x7FUL /* Bit mask for ETM_RESAEVT */ +#define _ETM_ETMTSEVR_RESAEVT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTSEVR */ +#define ETM_ETMTSEVR_RESAEVT_DEFAULT (_ETM_ETMTSEVR_RESAEVT_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTSEVR */ +#define _ETM_ETMTSEVR_RESBEVT_SHIFT 7 /* Shift value for ETM_RESBEVT */ +#define _ETM_ETMTSEVR_RESBEVT_MASK 0x3F80UL /* Bit mask for ETM_RESBEVT */ +#define _ETM_ETMTSEVR_RESBEVT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTSEVR */ +#define ETM_ETMTSEVR_RESBEVT_DEFAULT (_ETM_ETMTSEVR_RESBEVT_DEFAULT << 7) /* Shifted mode DEFAULT for ETM_ETMTSEVR */ +#define _ETM_ETMTSEVR_ETMFCNEVT_SHIFT 14 /* Shift value for ETM_ETMFCNEVT */ +#define _ETM_ETMTSEVR_ETMFCNEVT_MASK 0x1C000UL /* Bit mask for ETM_ETMFCNEVT */ +#define _ETM_ETMTSEVR_ETMFCNEVT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTSEVR */ +#define ETM_ETMTSEVR_ETMFCNEVT_DEFAULT (_ETM_ETMTSEVR_ETMFCNEVT_DEFAULT << 14) /* Shifted mode DEFAULT for ETM_ETMTSEVR */ + +/* Bit fields for ETM ETMTRACEIDR */ + +#define _ETM_ETMTRACEIDR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMTRACEIDR */ +#define _ETM_ETMTRACEIDR_MASK 0x0000007FUL /* Mask for ETM_ETMTRACEIDR */ + +#define _ETM_ETMTRACEIDR_TRACEID_SHIFT 0 /* Shift value for ETM_TRACEID */ +#define _ETM_ETMTRACEIDR_TRACEID_MASK 0x7FUL /* Bit mask for ETM_TRACEID */ +#define _ETM_ETMTRACEIDR_TRACEID_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMTRACEIDR */ +#define ETM_ETMTRACEIDR_TRACEID_DEFAULT (_ETM_ETMTRACEIDR_TRACEID_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMTRACEIDR */ + +/* Bit fields for ETM ETMIDR2 */ + +#define _ETM_ETMIDR2_RESETVALUE 0x00000000UL /* Default value for ETM_ETMIDR2 */ +#define _ETM_ETMIDR2_MASK 0x00000003UL /* Mask for ETM_ETMIDR2 */ + +#define ETM_ETMIDR2_RFE (0x1UL << 0) /* RFE Transfer Order */ +#define _ETM_ETMIDR2_RFE_SHIFT 0 /* Shift value for ETM_RFE */ +#define _ETM_ETMIDR2_RFE_MASK 0x1UL /* Bit mask for ETM_RFE */ +#define _ETM_ETMIDR2_RFE_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMIDR2 */ +#define _ETM_ETMIDR2_RFE_PC 0x00000000UL /* Mode PC for ETM_ETMIDR2 */ +#define _ETM_ETMIDR2_RFE_CPSR 0x00000001UL /* Mode CPSR for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_RFE_DEFAULT (_ETM_ETMIDR2_RFE_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_RFE_PC (_ETM_ETMIDR2_RFE_PC << 0) /* Shifted mode PC for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_RFE_CPSR (_ETM_ETMIDR2_RFE_CPSR << 0) /* Shifted mode CPSR for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_SWP (0x1UL << 1) /* SWP Transfer Order */ +#define _ETM_ETMIDR2_SWP_SHIFT 1 /* Shift value for ETM_SWP */ +#define _ETM_ETMIDR2_SWP_MASK 0x2UL /* Bit mask for ETM_SWP */ +#define _ETM_ETMIDR2_SWP_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMIDR2 */ +#define _ETM_ETMIDR2_SWP_LOAD 0x00000000UL /* Mode LOAD for ETM_ETMIDR2 */ +#define _ETM_ETMIDR2_SWP_STORE 0x00000001UL /* Mode STORE for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_SWP_DEFAULT (_ETM_ETMIDR2_SWP_DEFAULT << 1) /* Shifted mode DEFAULT for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_SWP_LOAD (_ETM_ETMIDR2_SWP_LOAD << 1) /* Shifted mode LOAD for ETM_ETMIDR2 */ +#define ETM_ETMIDR2_SWP_STORE (_ETM_ETMIDR2_SWP_STORE << 1) /* Shifted mode STORE for ETM_ETMIDR2 */ + +/* Bit fields for ETM ETMPDSR */ + +#define _ETM_ETMPDSR_RESETVALUE 0x00000001UL /* Default value for ETM_ETMPDSR */ +#define _ETM_ETMPDSR_MASK 0x00000001UL /* Mask for ETM_ETMPDSR */ + +#define ETM_ETMPDSR_ETMUP (0x1UL << 0) /* ETM Powered Up */ +#define _ETM_ETMPDSR_ETMUP_SHIFT 0 /* Shift value for ETM_ETMUP */ +#define _ETM_ETMPDSR_ETMUP_MASK 0x1UL /* Bit mask for ETM_ETMUP */ +#define _ETM_ETMPDSR_ETMUP_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMPDSR */ +#define ETM_ETMPDSR_ETMUP_DEFAULT (_ETM_ETMPDSR_ETMUP_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPDSR */ + +/* Bit fields for ETM ETMISCIN */ + +#define _ETM_ETMISCIN_RESETVALUE 0x00000000UL /* Default value for ETM_ETMISCIN */ +#define _ETM_ETMISCIN_MASK 0x00000013UL /* Mask for ETM_ETMISCIN */ + +#define _ETM_ETMISCIN_EXTIN_SHIFT 0 /* Shift value for ETM_EXTIN */ +#define _ETM_ETMISCIN_EXTIN_MASK 0x3UL /* Bit mask for ETM_EXTIN */ +#define _ETM_ETMISCIN_EXTIN_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMISCIN */ +#define ETM_ETMISCIN_EXTIN_DEFAULT (_ETM_ETMISCIN_EXTIN_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMISCIN */ +#define ETM_ETMISCIN_COREHALT (0x1UL << 4) /* Core Halt */ +#define _ETM_ETMISCIN_COREHALT_SHIFT 4 /* Shift value for ETM_COREHALT */ +#define _ETM_ETMISCIN_COREHALT_MASK 0x10UL /* Bit mask for ETM_COREHALT */ +#define _ETM_ETMISCIN_COREHALT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMISCIN */ +#define ETM_ETMISCIN_COREHALT_DEFAULT (_ETM_ETMISCIN_COREHALT_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMISCIN */ + +/* Bit fields for ETM ITTRIGOUT */ + +#define _ETM_ITTRIGOUT_RESETVALUE 0x00000000UL /* Default value for ETM_ITTRIGOUT */ +#define _ETM_ITTRIGOUT_MASK 0x00000001UL /* Mask for ETM_ITTRIGOUT */ + +#define ETM_ITTRIGOUT_TRIGGEROUT (0x1UL << 0) /* Trigger output value */ +#define _ETM_ITTRIGOUT_TRIGGEROUT_SHIFT 0 /* Shift value for ETM_TRIGGEROUT */ +#define _ETM_ITTRIGOUT_TRIGGEROUT_MASK 0x1UL /* Bit mask for ETM_TRIGGEROUT */ +#define _ETM_ITTRIGOUT_TRIGGEROUT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ITTRIGOUT */ +#define ETM_ITTRIGOUT_TRIGGEROUT_DEFAULT (_ETM_ITTRIGOUT_TRIGGEROUT_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ITTRIGOUT */ + +/* Bit fields for ETM ETMITATBCTR2 */ + +#define _ETM_ETMITATBCTR2_RESETVALUE 0x00000001UL /* Default value for ETM_ETMITATBCTR2 */ +#define _ETM_ETMITATBCTR2_MASK 0x00000001UL /* Mask for ETM_ETMITATBCTR2 */ + +#define ETM_ETMITATBCTR2_ATREADY (0x1UL << 0) /* ATREADY Input Value */ +#define _ETM_ETMITATBCTR2_ATREADY_SHIFT 0 /* Shift value for ETM_ATREADY */ +#define _ETM_ETMITATBCTR2_ATREADY_MASK 0x1UL /* Bit mask for ETM_ATREADY */ +#define _ETM_ETMITATBCTR2_ATREADY_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMITATBCTR2 */ +#define ETM_ETMITATBCTR2_ATREADY_DEFAULT (_ETM_ETMITATBCTR2_ATREADY_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMITATBCTR2 */ + +/* Bit fields for ETM ETMITATBCTR0 */ + +#define _ETM_ETMITATBCTR0_RESETVALUE 0x00000000UL /* Default value for ETM_ETMITATBCTR0 */ +#define _ETM_ETMITATBCTR0_MASK 0x00000001UL /* Mask for ETM_ETMITATBCTR0 */ + +#define ETM_ETMITATBCTR0_ATVALID (0x1UL << 0) /* ATVALID Output Value */ +#define _ETM_ETMITATBCTR0_ATVALID_SHIFT 0 /* Shift value for ETM_ATVALID */ +#define _ETM_ETMITATBCTR0_ATVALID_MASK 0x1UL /* Bit mask for ETM_ATVALID */ +#define _ETM_ETMITATBCTR0_ATVALID_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMITATBCTR0 */ +#define ETM_ETMITATBCTR0_ATVALID_DEFAULT (_ETM_ETMITATBCTR0_ATVALID_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMITATBCTR0 */ + +/* Bit fields for ETM ETMITCTRL */ + +#define _ETM_ETMITCTRL_RESETVALUE 0x00000000UL /* Default value for ETM_ETMITCTRL */ +#define _ETM_ETMITCTRL_MASK 0x00000001UL /* Mask for ETM_ETMITCTRL */ + +#define ETM_ETMITCTRL_ITEN (0x1UL << 0) /* Integration Mode Enable */ +#define _ETM_ETMITCTRL_ITEN_SHIFT 0 /* Shift value for ETM_ITEN */ +#define _ETM_ETMITCTRL_ITEN_MASK 0x1UL /* Bit mask for ETM_ITEN */ +#define _ETM_ETMITCTRL_ITEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMITCTRL */ +#define ETM_ETMITCTRL_ITEN_DEFAULT (_ETM_ETMITCTRL_ITEN_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMITCTRL */ + +/* Bit fields for ETM ETMCLAIMSET */ + +#define _ETM_ETMCLAIMSET_RESETVALUE 0x0000000FUL /* Default value for ETM_ETMCLAIMSET */ +#define _ETM_ETMCLAIMSET_MASK 0x000000FFUL /* Mask for ETM_ETMCLAIMSET */ + +#define _ETM_ETMCLAIMSET_SETTAG_SHIFT 0 /* Shift value for ETM_SETTAG */ +#define _ETM_ETMCLAIMSET_SETTAG_MASK 0xFFUL /* Bit mask for ETM_SETTAG */ +#define _ETM_ETMCLAIMSET_SETTAG_DEFAULT 0x0000000FUL /* Mode DEFAULT for ETM_ETMCLAIMSET */ +#define ETM_ETMCLAIMSET_SETTAG_DEFAULT (_ETM_ETMCLAIMSET_SETTAG_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCLAIMSET */ + +/* Bit fields for ETM ETMCLAIMCLR */ + +#define _ETM_ETMCLAIMCLR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMCLAIMCLR */ +#define _ETM_ETMCLAIMCLR_MASK 0x00000001UL /* Mask for ETM_ETMCLAIMCLR */ + +#define ETM_ETMCLAIMCLR_CLRTAG (0x1UL << 0) /* Tag Bits */ +#define _ETM_ETMCLAIMCLR_CLRTAG_SHIFT 0 /* Shift value for ETM_CLRTAG */ +#define _ETM_ETMCLAIMCLR_CLRTAG_MASK 0x1UL /* Bit mask for ETM_CLRTAG */ +#define _ETM_ETMCLAIMCLR_CLRTAG_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMCLAIMCLR */ +#define ETM_ETMCLAIMCLR_CLRTAG_DEFAULT (_ETM_ETMCLAIMCLR_CLRTAG_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCLAIMCLR */ + +/* Bit fields for ETM ETMLAR */ + +#define _ETM_ETMLAR_RESETVALUE 0x00000000UL /* Default value for ETM_ETMLAR */ +#define _ETM_ETMLAR_MASK 0x00000001UL /* Mask for ETM_ETMLAR */ + +#define ETM_ETMLAR_KEY (0x1UL << 0) /* Key Value */ +#define _ETM_ETMLAR_KEY_SHIFT 0 /* Shift value for ETM_KEY */ +#define _ETM_ETMLAR_KEY_MASK 0x1UL /* Bit mask for ETM_KEY */ +#define _ETM_ETMLAR_KEY_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMLAR */ +#define ETM_ETMLAR_KEY_DEFAULT (_ETM_ETMLAR_KEY_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMLAR */ + +/* Bit fields for ETM ETMLSR */ + +#define _ETM_ETMLSR_RESETVALUE 0x00000003UL /* Default value for ETM_ETMLSR */ +#define _ETM_ETMLSR_MASK 0x00000003UL /* Mask for ETM_ETMLSR */ + +#define ETM_ETMLSR_LOCKIMP (0x1UL << 0) /* ETM Locking Implemented */ +#define _ETM_ETMLSR_LOCKIMP_SHIFT 0 /* Shift value for ETM_LOCKIMP */ +#define _ETM_ETMLSR_LOCKIMP_MASK 0x1UL /* Bit mask for ETM_LOCKIMP */ +#define _ETM_ETMLSR_LOCKIMP_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMLSR */ +#define ETM_ETMLSR_LOCKIMP_DEFAULT (_ETM_ETMLSR_LOCKIMP_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMLSR */ +#define ETM_ETMLSR_LOCKED (0x1UL << 1) /* ETM locked */ +#define _ETM_ETMLSR_LOCKED_SHIFT 1 /* Shift value for ETM_LOCKED */ +#define _ETM_ETMLSR_LOCKED_MASK 0x2UL /* Bit mask for ETM_LOCKED */ +#define _ETM_ETMLSR_LOCKED_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMLSR */ +#define ETM_ETMLSR_LOCKED_DEFAULT (_ETM_ETMLSR_LOCKED_DEFAULT << 1) /* Shifted mode DEFAULT for ETM_ETMLSR */ + +/* Bit fields for ETM ETMAUTHSTATUS */ + +#define _ETM_ETMAUTHSTATUS_RESETVALUE 0x000000C0UL /* Default value for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_MASK 0x000000FFUL /* Mask for ETM_ETMAUTHSTATUS */ + +#define _ETM_ETMAUTHSTATUS_NONSECINVDBG_SHIFT 0 /* Shift value for ETM_NONSECINVDBG */ +#define _ETM_ETMAUTHSTATUS_NONSECINVDBG_MASK 0x3UL /* Bit mask for ETM_NONSECINVDBG */ +#define _ETM_ETMAUTHSTATUS_NONSECINVDBG_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_NONSECINVDBG_DEFAULT (_ETM_ETMAUTHSTATUS_NONSECINVDBG_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_NONSECNONINVDBG_SHIFT 2 /* Shift value for ETM_NONSECNONINVDBG */ +#define _ETM_ETMAUTHSTATUS_NONSECNONINVDBG_MASK 0xCUL /* Bit mask for ETM_NONSECNONINVDBG */ +#define _ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DISABLE 0x00000002UL /* Mode DISABLE for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_NONSECNONINVDBG_ENABLE 0x00000003UL /* Mode ENABLE for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DEFAULT (_ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DEFAULT << 2) /* Shifted mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DISABLE (_ETM_ETMAUTHSTATUS_NONSECNONINVDBG_DISABLE << 2) /* Shifted mode DISABLE for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_NONSECNONINVDBG_ENABLE (_ETM_ETMAUTHSTATUS_NONSECNONINVDBG_ENABLE << 2) /* Shifted mode ENABLE for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_SECINVDBG_SHIFT 4 /* Shift value for ETM_SECINVDBG */ +#define _ETM_ETMAUTHSTATUS_SECINVDBG_MASK 0x30UL /* Bit mask for ETM_SECINVDBG */ +#define _ETM_ETMAUTHSTATUS_SECINVDBG_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_SECINVDBG_DEFAULT (_ETM_ETMAUTHSTATUS_SECINVDBG_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define _ETM_ETMAUTHSTATUS_SECNONINVDBG_SHIFT 6 /* Shift value for ETM_SECNONINVDBG */ +#define _ETM_ETMAUTHSTATUS_SECNONINVDBG_MASK 0xC0UL /* Bit mask for ETM_SECNONINVDBG */ +#define _ETM_ETMAUTHSTATUS_SECNONINVDBG_DEFAULT 0x00000003UL /* Mode DEFAULT for ETM_ETMAUTHSTATUS */ +#define ETM_ETMAUTHSTATUS_SECNONINVDBG_DEFAULT (_ETM_ETMAUTHSTATUS_SECNONINVDBG_DEFAULT << 6) /* Shifted mode DEFAULT for ETM_ETMAUTHSTATUS */ + +/* Bit fields for ETM ETMDEVTYPE */ + +#define _ETM_ETMDEVTYPE_RESETVALUE 0x00000013UL /* Default value for ETM_ETMDEVTYPE */ +#define _ETM_ETMDEVTYPE_MASK 0x000000FFUL /* Mask for ETM_ETMDEVTYPE */ + +#define _ETM_ETMDEVTYPE_TRACESRC_SHIFT 0 /* Shift value for ETM_TRACESRC */ +#define _ETM_ETMDEVTYPE_TRACESRC_MASK 0xFUL /* Bit mask for ETM_TRACESRC */ +#define _ETM_ETMDEVTYPE_TRACESRC_DEFAULT 0x00000003UL /* Mode DEFAULT for ETM_ETMDEVTYPE */ +#define ETM_ETMDEVTYPE_TRACESRC_DEFAULT (_ETM_ETMDEVTYPE_TRACESRC_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMDEVTYPE */ +#define _ETM_ETMDEVTYPE_PROCTRACE_SHIFT 4 /* Shift value for ETM_PROCTRACE */ +#define _ETM_ETMDEVTYPE_PROCTRACE_MASK 0xF0UL /* Bit mask for ETM_PROCTRACE */ +#define _ETM_ETMDEVTYPE_PROCTRACE_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMDEVTYPE */ +#define ETM_ETMDEVTYPE_PROCTRACE_DEFAULT (_ETM_ETMDEVTYPE_PROCTRACE_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMDEVTYPE */ + +/* Bit fields for ETM ETMPIDR4 */ + +#define _ETM_ETMPIDR4_RESETVALUE 0x00000004UL /* Default value for ETM_ETMPIDR4 */ +#define _ETM_ETMPIDR4_MASK 0x000000FFUL /* Mask for ETM_ETMPIDR4 */ + +#define _ETM_ETMPIDR4_CONTCODE_SHIFT 0 /* Shift value for ETM_CONTCODE */ +#define _ETM_ETMPIDR4_CONTCODE_MASK 0xFUL /* Bit mask for ETM_CONTCODE */ +#define _ETM_ETMPIDR4_CONTCODE_DEFAULT 0x00000004UL /* Mode DEFAULT for ETM_ETMPIDR4 */ +#define ETM_ETMPIDR4_CONTCODE_DEFAULT (_ETM_ETMPIDR4_CONTCODE_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPIDR4 */ +#define _ETM_ETMPIDR4_COUNT_SHIFT 4 /* Shift value for ETM_COUNT */ +#define _ETM_ETMPIDR4_COUNT_MASK 0xF0UL /* Bit mask for ETM_COUNT */ +#define _ETM_ETMPIDR4_COUNT_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMPIDR4 */ +#define ETM_ETMPIDR4_COUNT_DEFAULT (_ETM_ETMPIDR4_COUNT_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMPIDR4 */ + +/* Bit fields for ETM ETMPIDR5 */ + +#define _ETM_ETMPIDR5_RESETVALUE 0x00000000UL /* Default value for ETM_ETMPIDR5 */ +#define _ETM_ETMPIDR5_MASK 0x00000000UL /* Mask for ETM_ETMPIDR5 */ + +/* Bit fields for ETM ETMPIDR6 */ + +#define _ETM_ETMPIDR6_RESETVALUE 0x00000000UL /* Default value for ETM_ETMPIDR6 */ +#define _ETM_ETMPIDR6_MASK 0x00000000UL /* Mask for ETM_ETMPIDR6 */ + +/* Bit fields for ETM ETMPIDR7 */ + +#define _ETM_ETMPIDR7_RESETVALUE 0x00000000UL /* Default value for ETM_ETMPIDR7 */ +#define _ETM_ETMPIDR7_MASK 0x00000000UL /* Mask for ETM_ETMPIDR7 */ + +/* Bit fields for ETM ETMPIDR0 */ + +#define _ETM_ETMPIDR0_RESETVALUE 0x00000024UL /* Default value for ETM_ETMPIDR0 */ +#define _ETM_ETMPIDR0_MASK 0x000000FFUL /* Mask for ETM_ETMPIDR0 */ + +#define _ETM_ETMPIDR0_PARTNUM_SHIFT 0 /* Shift value for ETM_PARTNUM */ +#define _ETM_ETMPIDR0_PARTNUM_MASK 0xFFUL /* Bit mask for ETM_PARTNUM */ +#define _ETM_ETMPIDR0_PARTNUM_DEFAULT 0x00000024UL /* Mode DEFAULT for ETM_ETMPIDR0 */ +#define ETM_ETMPIDR0_PARTNUM_DEFAULT (_ETM_ETMPIDR0_PARTNUM_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPIDR0 */ + +/* Bit fields for ETM ETMPIDR1 */ + +#define _ETM_ETMPIDR1_RESETVALUE 0x000000B9UL /* Default value for ETM_ETMPIDR1 */ +#define _ETM_ETMPIDR1_MASK 0x000000FFUL /* Mask for ETM_ETMPIDR1 */ + +#define _ETM_ETMPIDR1_PARTNUM_SHIFT 0 /* Shift value for ETM_PARTNUM */ +#define _ETM_ETMPIDR1_PARTNUM_MASK 0xFUL /* Bit mask for ETM_PARTNUM */ +#define _ETM_ETMPIDR1_PARTNUM_DEFAULT 0x00000009UL /* Mode DEFAULT for ETM_ETMPIDR1 */ +#define ETM_ETMPIDR1_PARTNUM_DEFAULT (_ETM_ETMPIDR1_PARTNUM_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPIDR1 */ +#define _ETM_ETMPIDR1_IDCODE_SHIFT 4 /* Shift value for ETM_IDCODE */ +#define _ETM_ETMPIDR1_IDCODE_MASK 0xF0UL /* Bit mask for ETM_IDCODE */ +#define _ETM_ETMPIDR1_IDCODE_DEFAULT 0x0000000BUL /* Mode DEFAULT for ETM_ETMPIDR1 */ +#define ETM_ETMPIDR1_IDCODE_DEFAULT (_ETM_ETMPIDR1_IDCODE_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMPIDR1 */ + +/* Bit fields for ETM ETMPIDR2 */ + +#define _ETM_ETMPIDR2_RESETVALUE 0x0000003BUL /* Default value for ETM_ETMPIDR2 */ +#define _ETM_ETMPIDR2_MASK 0x000000FFUL /* Mask for ETM_ETMPIDR2 */ + +#define _ETM_ETMPIDR2_IDCODE_SHIFT 0 /* Shift value for ETM_IDCODE */ +#define _ETM_ETMPIDR2_IDCODE_MASK 0x7UL /* Bit mask for ETM_IDCODE */ +#define _ETM_ETMPIDR2_IDCODE_DEFAULT 0x00000003UL /* Mode DEFAULT for ETM_ETMPIDR2 */ +#define ETM_ETMPIDR2_IDCODE_DEFAULT (_ETM_ETMPIDR2_IDCODE_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPIDR2 */ +#define ETM_ETMPIDR2_ALWAYS1 (0x1UL << 3) /* Always 1 */ +#define _ETM_ETMPIDR2_ALWAYS1_SHIFT 3 /* Shift value for ETM_ALWAYS1 */ +#define _ETM_ETMPIDR2_ALWAYS1_MASK 0x8UL /* Bit mask for ETM_ALWAYS1 */ +#define _ETM_ETMPIDR2_ALWAYS1_DEFAULT 0x00000001UL /* Mode DEFAULT for ETM_ETMPIDR2 */ +#define ETM_ETMPIDR2_ALWAYS1_DEFAULT (_ETM_ETMPIDR2_ALWAYS1_DEFAULT << 3) /* Shifted mode DEFAULT for ETM_ETMPIDR2 */ +#define _ETM_ETMPIDR2_REV_SHIFT 4 /* Shift value for ETM_REV */ +#define _ETM_ETMPIDR2_REV_MASK 0xF0UL /* Bit mask for ETM_REV */ +#define _ETM_ETMPIDR2_REV_DEFAULT 0x00000003UL /* Mode DEFAULT for ETM_ETMPIDR2 */ +#define ETM_ETMPIDR2_REV_DEFAULT (_ETM_ETMPIDR2_REV_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMPIDR2 */ + +/* Bit fields for ETM ETMPIDR3 */ + +#define _ETM_ETMPIDR3_RESETVALUE 0x00000000UL /* Default value for ETM_ETMPIDR3 */ +#define _ETM_ETMPIDR3_MASK 0x000000FFUL /* Mask for ETM_ETMPIDR3 */ + +#define _ETM_ETMPIDR3_CUSTMOD_SHIFT 0 /* Shift value for ETM_CUSTMOD */ +#define _ETM_ETMPIDR3_CUSTMOD_MASK 0xFUL /* Bit mask for ETM_CUSTMOD */ +#define _ETM_ETMPIDR3_CUSTMOD_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMPIDR3 */ +#define ETM_ETMPIDR3_CUSTMOD_DEFAULT (_ETM_ETMPIDR3_CUSTMOD_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMPIDR3 */ +#define _ETM_ETMPIDR3_REVAND_SHIFT 4 /* Shift value for ETM_REVAND */ +#define _ETM_ETMPIDR3_REVAND_MASK 0xF0UL /* Bit mask for ETM_REVAND */ +#define _ETM_ETMPIDR3_REVAND_DEFAULT 0x00000000UL /* Mode DEFAULT for ETM_ETMPIDR3 */ +#define ETM_ETMPIDR3_REVAND_DEFAULT (_ETM_ETMPIDR3_REVAND_DEFAULT << 4) /* Shifted mode DEFAULT for ETM_ETMPIDR3 */ + +/* Bit fields for ETM ETMCIDR0 */ + +#define _ETM_ETMCIDR0_RESETVALUE 0x0000000DUL /* Default value for ETM_ETMCIDR0 */ +#define _ETM_ETMCIDR0_MASK 0x000000FFUL /* Mask for ETM_ETMCIDR0 */ + +#define _ETM_ETMCIDR0_PREAMB_SHIFT 0 /* Shift value for ETM_PREAMB */ +#define _ETM_ETMCIDR0_PREAMB_MASK 0xFFUL /* Bit mask for ETM_PREAMB */ +#define _ETM_ETMCIDR0_PREAMB_DEFAULT 0x0000000DUL /* Mode DEFAULT for ETM_ETMCIDR0 */ +#define ETM_ETMCIDR0_PREAMB_DEFAULT (_ETM_ETMCIDR0_PREAMB_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCIDR0 */ + +/* Bit fields for ETM ETMCIDR1 */ + +#define _ETM_ETMCIDR1_RESETVALUE 0x00000090UL /* Default value for ETM_ETMCIDR1 */ +#define _ETM_ETMCIDR1_MASK 0x000000FFUL /* Mask for ETM_ETMCIDR1 */ + +#define _ETM_ETMCIDR1_PREAMB_SHIFT 0 /* Shift value for ETM_PREAMB */ +#define _ETM_ETMCIDR1_PREAMB_MASK 0xFFUL /* Bit mask for ETM_PREAMB */ +#define _ETM_ETMCIDR1_PREAMB_DEFAULT 0x00000090UL /* Mode DEFAULT for ETM_ETMCIDR1 */ +#define ETM_ETMCIDR1_PREAMB_DEFAULT (_ETM_ETMCIDR1_PREAMB_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCIDR1 */ + +/* Bit fields for ETM ETMCIDR2 */ + +#define _ETM_ETMCIDR2_RESETVALUE 0x00000005UL /* Default value for ETM_ETMCIDR2 */ +#define _ETM_ETMCIDR2_MASK 0x000000FFUL /* Mask for ETM_ETMCIDR2 */ + +#define _ETM_ETMCIDR2_PREAMB_SHIFT 0 /* Shift value for ETM_PREAMB */ +#define _ETM_ETMCIDR2_PREAMB_MASK 0xFFUL /* Bit mask for ETM_PREAMB */ +#define _ETM_ETMCIDR2_PREAMB_DEFAULT 0x00000005UL /* Mode DEFAULT for ETM_ETMCIDR2 */ +#define ETM_ETMCIDR2_PREAMB_DEFAULT (_ETM_ETMCIDR2_PREAMB_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCIDR2 */ + +/* Bit fields for ETM ETMCIDR3 */ + +#define _ETM_ETMCIDR3_RESETVALUE 0x000000B1UL /* Default value for ETM_ETMCIDR3 */ +#define _ETM_ETMCIDR3_MASK 0x000000FFUL /* Mask for ETM_ETMCIDR3 */ + +#define _ETM_ETMCIDR3_PREAMB_SHIFT 0 /* Shift value for ETM_PREAMB */ +#define _ETM_ETMCIDR3_PREAMB_MASK 0xFFUL /* Bit mask for ETM_PREAMB */ +#define _ETM_ETMCIDR3_PREAMB_DEFAULT 0x000000B1UL /* Mode DEFAULT for ETM_ETMCIDR3 */ +#define ETM_ETMCIDR3_PREAMB_DEFAULT (_ETM_ETMCIDR3_PREAMB_DEFAULT << 0) /* Shifted mode DEFAULT for ETM_ETMCIDR3 */ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_ETM_H */ diff --git a/arch/arm/src/armv7-m/exc_return.h b/arch/arm/src/armv7-m/exc_return.h new file mode 100644 index 0000000000000000000000000000000000000000..928e2a97c991a635ab16e1bff384217a099dde05 --- /dev/null +++ b/arch/arm/src/armv7-m/exc_return.h @@ -0,0 +1,120 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/exc_return.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_EXC_RETURN_H +#define __ARCH_ARM_SRC_ARMV7_M_EXC_RETURN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* The processor saves an EXC_RETURN value to the LR on exception entry. The + * exception mechanism relies on this value to detect when the processor has + * completed an exception handler. + * + * Bits [31:28] of an EXC_RETURN value are always 1. When the processor loads a + * value matching this pattern to the PC it detects that the operation is a not + * a normal branch operation and instead, that the exception is complete. + * Therefore, it starts the exception return sequence. + * + * Bits[4:0] of the EXC_RETURN value indicate the required return stack and eventual + * processor mode. The remaining bits of the EXC_RETURN value should be set to 1. + */ + +/* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */ + +#define EXC_RETURN_BASE 0xffffffe1 + +/* EXC_RETURN_PROCESS_STACK: The exception saved (and will restore) the hardware + * context using the process stack pointer (if not set, the context was saved + * using the main stack pointer) + */ + +#define EXC_RETURN_PROCESS_STACK (1 << 2) + +/* EXC_RETURN_THREAD_MODE: The exception will return to thread mode (if not set, + * return stays in handler mode) + */ + +#define EXC_RETURN_THREAD_MODE (1 << 3) + +/* EXC_RETURN_STD_CONTEXT: The state saved on the stack does not include the + * volatile FP registers and FPSCR. If this bit is clear, the state does include + * these registers. + */ + +#define EXC_RETURN_STD_CONTEXT (1 << 4) + +/* EXC_RETURN_HANDLER: Return to handler mode. Exception return gets state from + * the main stack. Execution uses MSP after return. + */ + +#define EXC_RETURN_HANDLER 0xfffffff1 + +/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return gets + * state from the main stack. Execution uses MSP after return. + */ + +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) && defined(CONFIG_ARCH_FPU) +# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE) +#else +# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \ + EXC_RETURN_THREAD_MODE) +#endif + +/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return gets + * state from the process stack. Execution uses PSP after return. + */ + +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) && defined(CONFIG_ARCH_FPU) +# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE | \ + EXC_RETURN_PROCESS_STACK) +#else +# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \ + EXC_RETURN_THREAD_MODE | EXC_RETURN_PROCESS_STACK) +#endif + +/************************Th************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_EXC_RETURN_H */ + diff --git a/arch/arm/src/armv7-m/gnu/up_exception.S b/arch/arm/src/armv7-m/gnu/up_exception.S new file mode 100644 index 0000000000000000000000000000000000000000..0010136b0357a0f2424c4b99148921d1fb4f35db --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_exception.S @@ -0,0 +1,332 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_exception.S + * + * Copyright (C) 2009-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2012 Michael Smith. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "exc_return.h" + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the + * MSP to the stack pointer of the interrupted thread. If the interrupted thread + * was a privileged thread, that will be the MSP otherwise it will be the PSP. If + * the PSP is used, then the value of the MSP will be invalid when the interrupt + * handler returns because it will be a pointer to an old position in the + * unprivileged stack. Then when the high priority interrupt occurs and uses this + * stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt + * handler will always set the the MSP to the interrupt stack. So when the high + * priority interrupt occurs, it will either use the MSP of the last privileged + * thread to run or, in the case of the nested interrupt, the interrupt stack if + * no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl exception_common + + .syntax unified + .thumb + .file "up_exception.S" + +/************************************************************************************ + * .text + ************************************************************************************/ + +/* Common exception handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * IPSR contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + * + * If CONFIG_ARCH_FPU is defined, the volatile FP registers and FPSCR are on the + * return stack immediately above REG_XPSR. + */ + + .text + .type exception_common, function + .thumb_func +exception_common: + + mrs r0, ipsr /* R0=exception number */ + + /* Complete the context save */ + + /* The EXC_RETURN value tells us whether the context is on the MSP or PSP */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ + /* (ignoring the xPSR[9] alignment bit) */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + + /* Save the non-volatile FP registers here. + * + * This routine is the only point where we can save these registers; either before + * or after calling up_doirq. The compiler is free to use them at any time as long + * as they are restored before returning, so we can't assume that we can get at the + * true values of these registers in any routine called from here. + * + * REVISIT: we could do all this saving lazily on the context switch side if we knew + * where to put the registers. + */ + + vstmdb sp!, {s16-s31} /* Save the non-volatile FP context */ + +#endif + + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */ + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie on the + * stack but, rather within a TCB structure. We'll have to copy some + * values to the stack. + */ + + /* Copy the hardware-saved context to the stack, and restore the software + * saved context directly. + * + * XXX In the normal case, it appears that this entire operation is unnecessary; + * context switch time would be improved if we could work out when the stack + * is dirty and avoid the work... + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */ +#ifdef CONFIG_ARCH_FPU + vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */ + ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */ +#endif + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ +#ifdef CONFIG_ARCH_FPU + stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */ + vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */ +#endif + stmdb r1!, {r4-r11} /* Store eight registers on the return stack */ + ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#ifdef CONFIG_ARCH_FPU + vldmia r0, {s16-s31} /* Recover S16-S31 */ +#endif + + b 3f /* Re-join common logic */ + +2: + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created at entry. + */ + + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#ifdef CONFIG_ARCH_FPU + vldmia r1!, {s16-s31} /* Recover S16-S31 */ +#endif + +3: + /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP + */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + ite eq /* next two instructions conditional */ + msreq msp, r1 /* R1=The main stack pointer */ + msrne psp, r1 /* R1=The process stack pointer */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) select the correct stack. + */ + + bx r14 /* And return */ + + .size exception_common, .-exception_common + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif + + .end + diff --git a/arch/arm/src/armv7-m/gnu/up_fpu.S b/arch/arm/src/armv7-m/gnu/up_fpu.S new file mode 100644 index 0000000000000000000000000000000000000000..6c9dd28fba14c02f45aed04de34161fe6ab8bc53 --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_fpu.S @@ -0,0 +1,286 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_fpu.S + * + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +/* + * When this file is assembled, it will require the following GCC options: + * + * -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfp -meabi=5 -mthumb + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_FPU + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_savefpu + .globl up_restorefpu + + .syntax unified + .thumb + .file "up_fpu.S" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_savefpu + * + * Description: + * Given the pointer to a register save area (in R0), save the state of the + * floating point registers. + * + * C Function Prototype: + * void up_savefpu(uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area in which to save the floating point + * registers + * + * Returned Value: + * None + * + ************************************************************************************/ + + .thumb_func + .type up_savefpu, function +up_savefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Some older GNU assemblers don't support all the newer UAL mnemonics. */ + +#if 1 /* Use UAL mnemonics */ + /* Store all floating point registers. Registers are stored in numeric order, + * s0, s1, ... in increasing address order. + */ + + vstmia r1!, {s0-s31} /* Save the full FP context */ + + /* Store the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + vmrs r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ +#else + /* Store all floating point registers */ + +#if 1 /* Use store multiple */ + fstmias r1!, {s0-s31} /* Save the full FP context */ +#else + vmov r2, r3, d0 /* r2, r3 = d0 */ + str r2, [r1], #4 /* Save S0 and S1 values */ + str r3, [r1], #4 + vmov r2, r3, d1 /* r2, r3 = d1 */ + str r2, [r1], #4 /* Save S2 and S3 values */ + str r3, [r1], #4 + vmov r2, r3, d2 /* r2, r3 = d2 */ + str r2, [r1], #4 /* Save S4 and S5 values */ + str r3, [r1], #4 + vmov r2, r3, d3 /* r2, r3 = d3 */ + str r2, [r1], #4 /* Save S6 and S7 values */ + str r3, [r1], #4 + vmov r2, r3, d4 /* r2, r3 = d4 */ + str r2, [r1], #4 /* Save S8 and S9 values */ + str r3, [r1], #4 + vmov r2, r3, d5 /* r2, r3 = d5 */ + str r2, [r1], #4 /* Save S10 and S11 values */ + str r3, [r1], #4 + vmov r2, r3, d6 /* r2, r3 = d6 */ + str r2, [r1], #4 /* Save S12 and S13 values */ + str r3, [r1], #4 + vmov r2, r3, d7 /* r2, r3 = d7 */ + str r2, [r1], #4 /* Save S14 and S15 values */ + str r3, [r1], #4 + vmov r2, r3, d8 /* r2, r3 = d8 */ + str r2, [r1], #4 /* Save S16 and S17 values */ + str r3, [r1], #4 + vmov r2, r3, d9 /* r2, r3 = d9 */ + str r2, [r1], #4 /* Save S18 and S19 values */ + str r3, [r1], #4 + vmov r2, r3, d10 /* r2, r3 = d10 */ + str r2, [r1], #4 /* Save S20 and S21 values */ + str r3, [r1], #4 + vmov r2, r3, d11 /* r2, r3 = d11 */ + str r2, [r1], #4 /* Save S22 and S23 values */ + str r3, [r1], #4 + vmov r2, r3, d12 /* r2, r3 = d12 */ + str r2, [r1], #4 /* Save S24 and S25 values */ + str r3, [r1], #4 + vmov r2, r3, d13 /* r2, r3 = d13 */ + str r2, [r1], #4 /* Save S26 and S27 values */ + str r3, [r1], #4 + vmov r2, r3, d14 /* r2, r3 = d14 */ + str r2, [r1], #4 /* Save S28 and S29 values */ + str r3, [r1], #4 + vmov r2, r3, d15 /* r2, r3 = d15 */ + str r2, [r1], #4 /* Save S30 and S31 values */ + str r3, [r1], #4 +#endif + + /* Store the floating point control and status register */ + + fmrx r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ +#endif + bx lr + + .size up_savefpu, .-up_savefpu + +/************************************************************************************ + * Name: up_restorefpu + * + * Description: + * Given the pointer to a register save area (in R0), restore the state of the + * floating point registers. + * + * C Function Prototype: + * void up_restorefpu(const uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area containing the floating point + * registers. + * + * Returned Value: + * This function does not return anything explicitly. However, it is called from + * interrupt level assembly logic that assumes that r0 is preserved. + * + ************************************************************************************/ + + .thumb_func + .type up_restorefpu, function +up_restorefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Some older GNU assemblers don't support all the newer UAL mnemonics. */ + +#if 1 /* Use UAL mnemonics */ + /* Load all floating point registers. Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + + vldmia r1!, {s0-s31} /* Restore the full FP context */ + + /* Load the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + vmsr fpscr, r2 /* Restore the FPCSR */ +#else + /* Load all floating point registers Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + +#if 1 /* Use load multiple */ + fldmias r1!, {s0-s31} /* Restore the full FP context */ +#else + ldr r2, [r1], #4 /* Fetch S0 and S1 values */ + ldr r3, [r1], #4 + vmov d0, r2, r3 /* Save as d0 */ + ldr r2, [r1], #4 /* Fetch S2 and S3 values */ + ldr r3, [r1], #4 + vmov d1, r2, r3 /* Save as d1 */ + ldr r2, [r1], #4 /* Fetch S4 and S5 values */ + ldr r3, [r1], #4 + vmov d2, r2, r3 /* Save as d2 */ + ldr r2, [r1], #4 /* Fetch S6 and S7 values */ + ldr r3, [r1], #4 + vmov d3, r2, r3 /* Save as d3 */ + ldr r2, [r1], #4 /* Fetch S8 and S9 values */ + ldr r3, [r1], #4 + vmov d4, r2, r3 /* Save as d4 */ + ldr r2, [r1], #4 /* Fetch S10 and S11 values */ + ldr r3, [r1], #4 + vmov d5, r2, r3 /* Save as d5 */ + ldr r2, [r1], #4 /* Fetch S12 and S13 values */ + ldr r3, [r1], #4 + vmov d6, r2, r3 /* Save as d6 */ + ldr r2, [r1], #4 /* Fetch S14 and S15 values */ + ldr r3, [r1], #4 + vmov d7, r2, r3 /* Save as d7 */ + ldr r2, [r1], #4 /* Fetch S16 and S17 values */ + ldr r3, [r1], #4 + vmov d8, r2, r3 /* Save as d8 */ + ldr r2, [r1], #4 /* Fetch S18 and S19 values */ + ldr r3, [r1], #4 + vmov d9, r2, r3 /* Save as d9 */ + ldr r2, [r1], #4 /* Fetch S20 and S21 values */ + ldr r3, [r1], #4 + vmov d10, r2, r3 /* Save as d10 */ + ldr r2, [r1], #4 /* Fetch S22 and S23 values */ + ldr r3, [r1], #4 + vmov d11, r2, r3 /* Save as d11 */ + ldr r2, [r1], #4 /* Fetch S24 and S25 values */ + ldr r3, [r1], #4 + vmov d12, r2, r3 /* Save as d12 */ + ldr r2, [r1], #4 /* Fetch S26 and S27 values */ + ldr r3, [r1], #4 + vmov d13, r2, r3 /* Save as d13 */ + ldr r2, [r1], #4 /* Fetch S28 and S29 values */ + ldr r3, [r1], #4 + vmov d14, r2, r3 /* Save as d14 */ + ldr r2, [r1], #4 /* Fetch S30 and S31 values */ + ldr r3, [r1], #4 + vmov d15, r2, r3 /* Save as d15 */ +#endif + + /* Load the floating point control and status register. r1 points t + * the address of the FPCSR register. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + fmxr fpscr, r2 /* Restore the FPCSR */ +#endif + bx lr + + .size up_restorefpu, .-up_restorefpu +#endif /* CONFIG_ARCH_FPU */ + .end + diff --git a/arch/arm/src/armv7-m/gnu/up_fullcontextrestore.S b/arch/arm/src/armv7-m/gnu/up_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..a9ccb0d572c0b9208e25fb3365382d0e1b4436fd --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_fullcontextrestore.S @@ -0,0 +1,95 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_fullcontextrestore.S + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_fullcontextrestore.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Restore the current thread context. Full prototype is: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * Return: + * None + * + ************************************************************************************/ + + .thumb_func + .globl up_fullcontextrestore + .type up_fullcontextrestore, function +up_fullcontextrestore: + + /* Perform the System call with R0=1 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_restore_context /* R0: restore context */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + .size up_fullcontextrestore, .-up_fullcontextrestore + .end + diff --git a/arch/arm/src/armv7-m/gnu/up_lazyexception.S b/arch/arm/src/armv7-m/gnu/up_lazyexception.S new file mode 100644 index 0000000000000000000000000000000000000000..08ce8be75cca0f0755b27753ecc6972c6faf165b --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_lazyexception.S @@ -0,0 +1,363 @@ +/************************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_lazyexcption.S + * + * Copyright (C) 2009-2010, 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include +#include "exc_return.h" + +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* Configuration ********************************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the + * stack pointer of the interrupted thread. If the interrupted thread was a privileged + * thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the + * value of the MSP will be invalid when the interrupt handler returns because it will be a + * pointer to an old position in the unprivileged stack. Then when the high priority + * interrupt occurs and uses this stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt handler will + * always set the the MSP to the interrupt stack. So when the high priority interrupt occurs, + * it will either use the MSP of the last privileged thread to run or, in the case of the + * nested interrupt, the interrupt stack if no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/************************************************************************************************ + * Public Symbols + ************************************************************************************************/ + + .globl exception_common + + .syntax unified + .thumb + .file "up_lazyexception.S" + +/************************************************************************************************ + * .text + ************************************************************************************************/ + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * IPSR contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .text + .type exception_common, function + +exception_common: + + /* Get the IRQ number from the IPSR */ + + mrs r0, ipsr /* R0=exception number */ + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size exception_common, .-exception_common + +/************************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif + + .end diff --git a/arch/arm/src/armv7-m/gnu/up_memcpy.S b/arch/arm/src/armv7-m/gnu/up_memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..cf34648d0125500e48a93a89b4583f6eb6a22934 --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_memcpy.S @@ -0,0 +1,431 @@ +/************************************************************************************ + * nuttx/arch/arm/src/armv7-m/gnu/up_memcpy.S + * + * armv7m-optimised memcpy, contributed by Mike Smith. Apparently in the public + * domain and is re-released here under the modified BSD license: + * + * Obtained via a posting on the Stellaris forum: + * http://e2e.ti.com/support/microcontrollers/\ + * stellaris_arm_cortex-m3_microcontroller/f/473/t/44360.aspx + * + * Posted by rocksoft on Jul 24, 2008 10:19 AM + * + * Hi, + * + * I recently finished a "memcpy" replacement and thought it might be useful for + * others... + * + * I've put some instructions and the code here: + * + * http://www.rock-software.net/downloads/memcpy/ + * + * Hope it works for you as well as it did for me. + * + * Liam. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .global memcpy + + .syntax unified + .thumb + .cpu cortex-m3 + .file "up_memcpy.S" + +/************************************************************************************ + * .text + ************************************************************************************/ + + .text + +/************************************************************************************ + * Private Constant Data + ************************************************************************************/ + +/* We have 16 possible alignment combinations of src and dst, this jump table + * directs the copy operation + * + * Bits: Src=00, Dst=00 - Long to Long copy + * Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=10 - Long to Half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + * Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=01 - Byte before half word to byte before half word - + * Same alignment + * Bits: Src=01, Dst=10 - Byte before half word to half word + * Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * Bits: Src=10, Dst=00 - Half word to long word + * Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * Bits: Src=10, Dst=11 - Half word to byte before long word + * Bits: Src=11, Dst=00 - Byte before long word to long word + * Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - + * Same alignment + */ + +MEM_DataCopyTable: + .byte (MEM_DataCopy0 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy1 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy2 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy3 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy4 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy5 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy6 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy7 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy8 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy9 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy10 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy11 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy12 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy13 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy14 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy15 - MEM_DataCopyJump) >> 1 + + .align 2 + +MEM_LongCopyTable: + .byte (MEM_LongCopyEnd - MEM_LongCopyJump) >> 1 /* 0 bytes left */ + .byte 0 /* 4 bytes left */ + .byte (1 * 10) >> 1 /* 8 bytes left */ + .byte (2 * 10) >> 1 /* 12 bytes left */ + .byte (3 * 10) >> 1 /* 16 bytes left */ + .byte (4 * 10) >> 1 /* 20 bytes left */ + .byte (5 * 10) >> 1 /* 24 bytes left */ + .byte (6 * 10) >> 1 /* 28 bytes left */ + .byte (7 * 10) >> 1 /* 32 bytes left */ + .byte (8 * 10) >> 1 /* 36 bytes left */ + + .align 2 + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/************************************************************************************ + * Name: memcpy + * + * Description: + * Optimised "general" copy routine + * + * Input Parameters: + * r0 = destination, r1 = source, r2 = length + * + * Returned Value: + * r0 = destination r1-r3 burned + * + ************************************************************************************/ + + .align 4 + .thumb_func + +memcpy: + push {r14} + push {r0} + bl _do_memcpy + pop {r0} + pop {pc} + + .align 4 + + .thumb_func +_do_memcpy: + push {r14} + + /* This allows the inner workings to "assume" a minimum amount of bytes */ + /* Quickly check for very short copies */ + + cmp r2, #4 + blt.n MEM_DataCopyBytes + + and r14, r0, #3 /* Get destination alignment bits */ + bfi r14, r1, #2, #2 /* Get source alignment bits */ + ldr r3, =MEM_DataCopyTable /* Jump table base */ + tbb [r3, r14] /* Perform jump on src/dst alignment bits */ +MEM_DataCopyJump: + + .align 4 + +/* Bits: Src=01, Dst=01 - Byte before half word to byte before half word - Same alignment + * 3 bytes to read for long word aligning + */ + +MEM_DataCopy5: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * 2 bytes to read for long word aligning + */ + +MEM_DataCopy10: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - Same alignment + * 1 bytes to read for long word aligning + */ + +MEM_DataCopy15: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=00 - Long to Long copy */ + +MEM_DataCopy0: + /* Save regs that may be used by memcpy */ + + push {r4-r12} + + /* Check for short word-aligned copy */ + + cmp r2, #0x28 + blt.n MEM_DataCopy0_2 + + /* Bulk copy loop */ + +MEM_DataCopy0_1: + ldmia r1!, {r3-r12} + stmia r0!, {r3-r12} + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy0_1 + + /* Copy remaining long words */ + +MEM_DataCopy0_2: + /* Copy remaining long words */ + + ldr r14, =MEM_LongCopyTable + lsr r11, r2, #0x02 + tbb [r14, r11] + + /* longword copy branch table anchor */ + +MEM_LongCopyJump: + ldr.w r3, [r1], #0x04 /* 4 bytes remain */ + str.w r3, [r0], #0x04 + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r4} /* 8 bytes remain */ + stmia.w r0!, {r3-r4} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r5} /* 12 bytes remain */ + stmia.w r0!, {r3-r5} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r6} /* 16 bytes remain */ + stmia.w r0!, {r3-r6} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r7} /* 20 bytes remain */ + stmia.w r0!, {r3-r7} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r8} /* 24 bytes remain */ + stmia.w r0!, {r3-r8} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r9} /* 28 bytes remain */ + stmia.w r0!, {r3-r9} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r10} /* 32 bytes remain */ + stmia.w r0!, {r3-r10} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r11} /* 36 bytes remain */ + stmia.w r0!, {r3-r11} + +MEM_LongCopyEnd: + pop {r4-r12} + and r2, r2, #0x03 /* All the longs have been copied */ + + /* Deal with up to 3 remaining bytes */ + +MEM_DataCopyBytes: + /* Deal with up to 3 remaining bytes */ + + cmp r2, #0x00 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + pop {pc} + + .align 4 + +/* Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy7: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=00 - Half word to long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy8: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy13: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=10 - Long to Half word */ + +MEM_DataCopy2: + cmp r2, #0x28 + blt.n MEM_DataCopy2_1 + + /* Save regs */ + + push {r4-r12} + + /* Bulk copy loop */ + +MEM_DataCopy2_2: + ldmia r1!, {r3-r12} + + strh r3, [r0], #0x02 + + lsr r3, r3, #0x10 + bfi r3, r4, #0x10, #0x10 + lsr r4, r4, #0x10 + bfi r4, r5, #0x10, #0x10 + lsr r5, r5, #0x10 + bfi r5, r6, #0x10, #0x10 + lsr r6, r6, #0x10 + bfi r6, r7, #0x10, #0x10 + lsr r7, r7, #0x10 + bfi r7, r8, #0x10, #0x10 + lsr r8, r8, #0x10 + bfi r8, r9, #0x10, #0x10 + lsr r9, r9, #0x10 + bfi r9, r10, #0x10, #0x10 + lsr r10, r10, #0x10 + bfi r10, r11, #0x10, #0x10 + lsr r11, r11, #0x10 + bfi r11, r12, #0x10, #0x10 + stmia r0!, {r3-r11} + lsr r12, r12, #0x10 + strh r12, [r0], #0x02 + + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy2_2 + pop {r4-r12} + +MEM_DataCopy2_1: /* Read longs and write 2 x half words */ + cmp r2, #4 + blt.n MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strh r3, [r0], #0x02 + sub r2, r2, #0x04 + b.n MEM_DataCopy2 + +/* Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=10 - Byte before half word to half word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy4: +MEM_DataCopy6: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=11 - Half word to byte before long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy9: +MEM_DataCopy11: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=00 -chm Byte before long word to long word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy12: +MEM_DataCopy14: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + */ + +MEM_DataCopy1: /* Read longs, write B->H->B */ +MEM_DataCopy3: + cmp r2, #4 + blt MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strb r3, [r0], #0x01 + lsr r3, r3, #0x08 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strb r3, [r0], #0x01 + sub r2, r2, #0x04 + b.n MEM_DataCopy3 + + .size memcpy, .-memcpy + .end diff --git a/arch/arm/src/armv7-m/gnu/up_saveusercontext.S b/arch/arm/src/armv7-m/gnu/up_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..7ebd2e4836a79d94b77c5cbfcd73e86fa444377f --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_saveusercontext.S @@ -0,0 +1,103 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_saveusercontext.S + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_saveusercontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_saveusercontext + * + * Description: + * Save the current thread context. Full prototype is: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * Return: + * 0: Normal return + * 1: Context switch return + * + ************************************************************************************/ + + .text + .thumb_func + .globl up_saveusercontext + .type up_saveusercontext, function +up_saveusercontext: + + /* Perform the System call with R0=0 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_save_context /* R0: save context (also return value) */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* There are two return conditions. On the first return, R0 (the + * return value will be zero. On the second return we need to + * force R0 to be 1. + */ + + add r2, r1, #(4*REG_R0) + mov r3, #1 + str r3, [r2, #0] + bx lr /* "normal" return with r0=0 or + * context switch with r0=1 */ + .size up_saveusercontext, .-up_saveusercontext + .end diff --git a/arch/arm/src/armv7-m/gnu/up_signal_handler.S b/arch/arm/src/armv7-m/gnu/up_signal_handler.S new file mode 100644 index 0000000000000000000000000000000000000000..2cc31da4d19fe67be41c4caf0ce4a97d16e6b098 --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_signal_handler.S @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/gnu/up_signal_handler.S + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * File info + ****************************************************************************/ + + .syntax unified + .thumb + .cpu cortex-m3 + .file "up_signal_handler.S" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_handler + * + * Description: + * This function is the user-space, signal handler trampoline function. It + * is called from up_signal_dispatch() in user-mode. + * + * R0-R3, R11 - volatile registers need not be preserved. + * R4-R10 - static registers must be preserved + * R12-R14 - LR and SP must be preserved + * + * Inputs: + * R0 = sighand + * The address user-space signal handling function + * R1-R3 = signo, info, and ucontext + * Standard arguments to be passed to the signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via the SYS_signal_handler_return (see svcall.h) + * + ****************************************************************************/ + + .text + .thumb_func + .globl up_signal_handler + .type up_signal_handler, function +up_signal_handler: + + /* Save some register */ + + push {lr} /* Save LR on the stack */ + + /* Call the signal handler */ + + mov ip, r0 /* IP=sighand */ + mov r0, r1 /* R0=signo */ + mov r1, r2 /* R1=info */ + mov r2, r3 /* R2=ucontext */ + blx ip /* Call the signal handler */ + + /* Restore the registers */ + + pop {r2} /* Recover LR in R2 */ + mov lr, r2 /* Restore LR */ + + /* Execute the SYS_signal_handler_return SVCall (will not return) */ + + mov r0, #SYS_signal_handler_return + svc 0 + nop + + .size up_signal_handler, .-up_signal_handler + .end + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/arch/arm/src/armv7-m/gnu/up_switchcontext.S b/arch/arm/src/armv7-m/gnu/up_switchcontext.S new file mode 100644 index 0000000000000000000000000000000000000000..c0ddf151627c485681cdbfc39ee167b908a02c51 --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_switchcontext.S @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/up_switchcontext.S + * + * Copyright (C) 2009-2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_switchcontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. + * Full prototype is: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * Return: + * None + * + ************************************************************************************/ + + .thumb_func + .globl up_switchcontext + .type up_switchcontext, function +up_switchcontext: + + /* Perform the System call with R0=1, R1=saveregs, R2=restoreregs */ + + mov r2, r1 /* R2: restoreregs */ + mov r1, r0 /* R1: saveregs */ + mov r0, #SYS_switch_context /* R0: context switch */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* We will get here only after the rerturn from the context switch */ + + bx lr + .size up_switchcontext, .-up_switchcontext + .end + diff --git a/arch/arm/src/armv7-m/gnu/up_testset.S b/arch/arm/src/armv7-m/gnu/up_testset.S new file mode 100644 index 0000000000000000000000000000000000000000..7dd45eee4dbef257817c6ac0095450811b371d80 --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/up_testset.S @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/gnu/up_testset.S + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + + .syntax unified + .thumb + .file "up_testset.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_testset + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + + .globl up_testset + .type up_testset, %function + +up_testset: + + mov r1, #SP_LOCKED + + /* Test if the spinlock is locked or not */ + +1: + ldrexb r2, [r0] /* Test if spinlock is locked or not */ + cmp r2, r1 /* Already locked? */ + beq 2f /* If already locked, return SP_LOCKED */ + + /* Not locked ... attempt to lock it */ + + strexb r2, r1, [r0] /* Attempt to set the locked state */ + cmp r2, r1 /* r2 will be 1 is strexb failed */ + beq 1b /* Failed to lock... try again */ + + /* Lock acquired -- return SP_UNLOCKED */ + + dmb /* Required before accessing protected resource */ + mov r0, #SP_UNLOCKED + bx lr + + /* Lock not acquired -- return SP_LOCKED */ + +2: + mov r0, #SP_LOCKED + bx lr + .size up_testset, . - up_testset + .end diff --git a/arch/arm/src/armv7-m/gnu/vfork.S b/arch/arm/src/armv7-m/gnu/vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..784ab83ce7b065113b69dd7a3dd48c780ff2644b --- /dev/null +++ b/arch/arm/src/armv7-m/gnu/vfork.S @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/gnu/vfork.S + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_vfork.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "vfork.S" + .globl up_vfork + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the behavior is + * undefined if the process created by vfork() either modifies any data other than + * a variable of type pid_t used to store the return value from vfork(), or returns + * from the function in which vfork() was called, or calls any other function before + * successfully calling _exit() or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the vfork() + * context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and returns + * the process ID of the child process to the parent process. Otherwise, -1 is + * returned to the parent, no child process is created, and errno is set to + * indicate the error. + * + ************************************************************************************/ + + .thumb_func + .globl vfork + .type vfork, function +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + str r4, [sp, #VFORK_R4_OFFSET] + str r5, [sp, #VFORK_R5_OFFSET] + str r6, [sp, #VFORK_R6_OFFSET] + str r7, [sp, #VFORK_R7_OFFSET] + str r8, [sp, #VFORK_R8_OFFSET] + str r9, [sp, #VFORK_R9_OFFSET] + str r10, [sp, #VFORK_R10_OFFSET] + + /* Save the frame pointer, stack pointer, and return address */ + + str fp, [sp, #VFORK_FP_OFFSET] + str r0, [sp, #VFORK_SP_OFFSET] + str lr, [sp, #VFORK_LR_OFFSET] + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Release the stack data and return the value returned by up_vfork */ + + ldr lr, [sp, #VFORK_LR_OFFSET] + add sp, sp, #VFORK_SIZEOF + bx lr + .size vfork, .-vfork + .end + diff --git a/arch/arm/src/armv7-m/iar/up_fullcontextrestore.S b/arch/arm/src/armv7-m/iar/up_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..9a50acb2064d59604b0de4e9761f03d972b89203 --- /dev/null +++ b/arch/arm/src/armv7-m/iar/up_fullcontextrestore.S @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/iar/up_fullcontextrestore.S + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + + MODULE up_fullcontextrestore + SECTION .text:CODE:NOROOT(2) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + PUBLIC up_fullcontextrestore + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Restore the current thread context. Full prototype is: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * Return: + * None + * + ************************************************************************************/ + + THUMB + +up_fullcontextrestore: + + /* Perform the System call with R0=1 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_restore_context /* R0: restore context */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + + END diff --git a/arch/arm/src/armv7-m/iar/up_saveusercontext.S b/arch/arm/src/armv7-m/iar/up_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..b8f27a7772cbac54ea11701e5337a2c2f3e439e3 --- /dev/null +++ b/arch/arm/src/armv7-m/iar/up_saveusercontext.S @@ -0,0 +1,101 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/iar/up_saveusercontext.S + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + + MODULE up_saveusercontext + SECTION .text:CODE:NOROOT(2) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + PUBLIC up_saveusercontext + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_saveusercontext + * + * Description: + * Save the current thread context. Full prototype is: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * Return: + * 0: Normal return + * 1: Context switch return + * + ************************************************************************************/ + + THUMB + +up_saveusercontext: + + /* Perform the System call with R0=0 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #SYS_save_context /* R0: save context (also return value) */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* There are two return conditions. On the first return, R0 (the + * return value will be zero. On the second return we need to + * force R0 to be 1. + */ + + add r2, r1, #(4*REG_R0) + mov r3, #1 + str r3, [r2, #0] + bx lr /* "normal" return with r0=0 or + * context switch with r0=1 */ + END diff --git a/arch/arm/src/armv7-m/iar/up_switchcontext.S b/arch/arm/src/armv7-m/iar/up_switchcontext.S new file mode 100644 index 0000000000000000000000000000000000000000..5936503d73fe27c3ce9516f4fa2bd209de95c945 --- /dev/null +++ b/arch/arm/src/armv7-m/iar/up_switchcontext.S @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/iar/up_switchcontext.S + * + * Copyright (C) 2009-2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "nvic.h" +#include "svcall.h" + + MODULE up_switchcontext + SECTION .text:CODE:NOROOT(2) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + PUBLIC up_switchcontext + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. + * Full prototype is: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * Return: + * None + * + ************************************************************************************/ + + THUMB + +up_switchcontext: + + /* Perform the System call with R0=1, R1=saveregs, R2=restoreregs */ + + mov r2, r1 /* R2: restoreregs */ + mov r1, r0 /* R1: saveregs */ + mov r0, #SYS_switch_context /* R0: context switch */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* We will get here only after the rerturn from the context switch */ + + bx lr + + END diff --git a/arch/arm/src/armv7-m/iar/vfork.S b/arch/arm/src/armv7-m/iar/vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..6018a28a00a7bda8d1f6177d865f9a234cbd6fd9 --- /dev/null +++ b/arch/arm/src/armv7-m/iar/vfork.S @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/iar/vfork.S + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_vfork.h" + + MODULE vfork + SECTION .text:CODE:NOROOT(2) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + PUBLIC vfork + EXTERN up_vfork + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the behavior is + * undefined if the process created by vfork() either modifies any data other than + * a variable of type pid_t used to store the return value from vfork(), or returns + * from the function in which vfork() was called, or calls any other function before + * successfully calling _exit() or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the vfork() + * context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and returns + * the process ID of the child process to the parent process. Otherwise, -1 is + * returned to the parent, no child process is created, and errno is set to + * indicate the error. + * + ************************************************************************************/ + + THUMB + +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + str r4, [sp, #VFORK_R4_OFFSET] + str r5, [sp, #VFORK_R5_OFFSET] + str r6, [sp, #VFORK_R6_OFFSET] + str r7, [sp, #VFORK_R7_OFFSET] + str r8, [sp, #VFORK_R8_OFFSET] + str r9, [sp, #VFORK_R9_OFFSET] + str r10, [sp, #VFORK_R10_OFFSET] + + /* Save the frame pointer, stack pointer, and return address */ + + str r11, [sp, #VFORK_FP_OFFSET] /* fp not defined. use r11 */ + str r0, [sp, #VFORK_SP_OFFSET] + str lr, [sp, #VFORK_LR_OFFSET] + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Release the stack data and return the value returned by up_vfork */ + + ldr lr, [sp, #VFORK_LR_OFFSET] + add sp, sp, #VFORK_SIZEOF + bx lr + + END diff --git a/arch/arm/src/armv7-m/itm.h b/arch/arm/src/armv7-m/itm.h new file mode 100644 index 0000000000000000000000000000000000000000..9bafa0c70307a35a7b8dd79f0bfdaf1a46f8238c --- /dev/null +++ b/arch/arm/src/armv7-m/itm.h @@ -0,0 +1,169 @@ +/*********************************************************************************************** + * arch/arm/src/armv7-m/itm.h + * + * 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. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_ITM_H +#define __ARCH_ARM_SRC_ARMV7_M_ITM_H + +/*********************************************************************************************** + * Included Files + ***********************************************************************************************/ + +#include + +/*********************************************************************************************** + * Pre-processor Definitions + ***********************************************************************************************/ + +/* Instrumentation Trace Macrocell Register (ITM) Definitions **********************************/ +/* ITM Register Base Address *******************************************************************/ + +#define ITM_BASE (0xe0000000ul) + +/* ITM Register Addresses **********************************************************************/ + +#define ITM_PORT(i) (ITM_BASE+(i*4)) /* Stimulus Port 32-bit */ +#define ITM_TER (ITM_BASE+0x0e00) /* Trace Enable Register */ +#define ITM_TPR (ITM_BASE+0x0e40) /* Trace Privilege Register */ +#define ITM_TCR (ITM_BASE+0x0e80) /* Trace Control Register */ +#define ITM_IWR (ITM_BASE+0x0ef8) /* Integration Write Register */ +#define ITM_IRR (ITM_BASE+0x0efc) /* Integration Read Register */ +#define ITM_IMCR (ITM_BASE+0x0f00) /* Integration Mode Control Register */ +#define ITM_LAR (ITM_BASE+0x0fb0) /* Lock Access Register */ +#define ITM_LSR (ITM_BASE+0x0fb4) /* Lock Status Register */ +#define ITM_PID4 (ITM_BASE+0x0fd0) /* Peripheral Identification Register #4 */ +#define ITM_PID5 (ITM_BASE+0x0fd4) /* Peripheral Identification Register #5 */ +#define ITM_PID6 (ITM_BASE+0x0fd8) /* Peripheral Identification Register #6 */ +#define ITM_PID7 (ITM_BASE+0x0fdc) /* Peripheral Identification Register #7 */ +#define ITM_PID0 (ITM_BASE+0x0fe0) /* Peripheral Identification Register #0 */ +#define ITM_PID1 (ITM_BASE+0x0fe4) /* Peripheral Identification Register #1 */ +#define ITM_PID2 (ITM_BASE+0x0fe8) /* Peripheral Identification Register #2 */ +#define ITM_PID3 (ITM_BASE+0x0fec) /* Peripheral Identification Register #3 */ +#define ITM_CID0 (ITM_BASE+0x0ff0) /* Component Identification Register #0 */ +#define ITM_CID1 (ITM_BASE+0x0ff4) /* Component Identification Register #1 */ +#define ITM_CID2 (ITM_BASE+0x0ff8) /* Component Identification Register #2 */ +#define ITM_CID3 (ITM_BASE+0x0ffc) /* Component Identification Register #3 */ + +/* ITM Register Bit Field 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 */ + +#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 */ + +#define ITM_IWR_ATVALIDM_Pos 0 /* ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /* ITM IWR: ATVALIDM Mask */ + +#define ITM_IRR_ATREADYM_Pos 0 /* ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /* ITM IRR: ATREADYM Mask */ + +#define ITM_IMCR_INTEGRATION_Pos 0 /* ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /* ITM IMCR: INTEGRATION Mask */ + +#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 */ + +#define ITM_RXBUFFER_EMPTY 0x5aa55aa5 /* Value identifying g_itm_rxbuffer is ready for next character. */ + +/*********************************************************************************************** + * Public Data + ***********************************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern volatile int32_t g_itm_rxbuffer; /* External variable to receive characters. */ + +/*********************************************************************************************** + * Public Function Prototypes + ***********************************************************************************************/ + +uint32_t itm_sendchar(uint32_t ch); +int32_t itm_receivechar(void); +int32_t itm_checkchar(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARM_SRC_ARMV7_M_ITM_H */ diff --git a/arch/arm/src/armv7-m/itm_syslog.h b/arch/arm/src/armv7-m/itm_syslog.h new file mode 100644 index 0000000000000000000000000000000000000000..1b42be2ea8e442ee412ebf9169103b7c8fa9f289 --- /dev/null +++ b/arch/arm/src/armv7-m/itm_syslog.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/itm_syslog.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_ITM_SYSLOG_H +#define __ARCH_ARM_SRC_ARMV7_M_ITM_SYSLOG_H + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: itm_syslog_initialize + * + * Description: + * Performs ARM-specific initialize for the ITM SYSLOG functions. + * Additional, board specific logic may be required to: + * + * - Enable/configured serial wire output pins + * - Enable debug clocking. + * + * Those operations must be performed by MCU-specific logic before this + * function is called. + * + ****************************************************************************/ + +#if defined(CONFIG_SYSLOG) || defined(CONFIG_ARMV7M_ITMSYSLOG) +void itm_syslog_initialize(void); +#else +# define itm_syslog_initialize() +#endif + +#endif /* __ARCH_ARM_SRC_ARMV7_M_ITM_SYSLOG_H */ diff --git a/arch/arm/src/armv7-m/mpu.h b/arch/arm/src/armv7-m/mpu.h new file mode 100644 index 0000000000000000000000000000000000000000..310c21a90912303363435c59a6dbf1f348386ca2 --- /dev/null +++ b/arch/arm/src/armv7-m/mpu.h @@ -0,0 +1,586 @@ +/***************************************************************************** + * arch/arm/src/armv7-m/mpu.h + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7M_MPU_H +#define __ARCH_ARM_SRC_ARMV7M_MPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +# include +# include + +# include "up_arch.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MPU Register Addresses */ + +#define MPU_TYPE 0xe000ed90 /* MPU Type Register */ +#define MPU_CTRL 0xe000ed94 /* MPU Control Register */ +#define MPU_RNR 0xe000ed98 /* MPU Region Number Register */ +#define MPU_RBAR 0xe000ed9c /* MPU Region Base Address Register */ +#define MPU_RASR 0xe000eda0 /* MPU Region Attribute and Size Register */ + +#define MPU_RBAR_A1 0xe000eda4 /* MPU alias registers */ +#define MPU_RASR_A1 0xe000eda8 +#define MPU_RBAR_A2 0xe000edac +#define MPU_RASR_A2 0xe000edb0 +#define MPU_RBAR_A3 0xe000edb4 +#define MPU_RASR_A3 0xe000edb8 + +/* MPU Type Register Bit Definitions */ + +#define MPU_TYPE_SEPARATE (1 << 0) /* Bit 0: 0:unified or 1:separate memory maps */ +#define MPU_TYPE_DREGION_SHIFT (8) /* Bits 8-15: Number MPU data regions */ +#define MPU_TYPE_DREGION_MASK (0xff << MPU_TYPE_DREGION_SHIFT) +#define MPU_TYPE_IREGION_SHIFT (16) /* Bits 16-23: Number MPU instruction regions */ +#define MPU_TYPE_IREGION_MASK (0xff << MPU_TYPE_IREGION_SHIFT) + +/* MPU Control Register Bit Definitions */ + +#define MPU_CTRL_ENABLE (1 << 0) /* Bit 0: Enable the MPU */ +#define MPU_CTRL_HFNMIENA (1 << 1) /* Bit 1: Enable MPU during hard fault, NMI, and FAULTMAS */ +#define MPU_CTRL_PRIVDEFENA (1 << 2) /* Bit 2: Enable privileged access to default memory map */ + +/* MPU Region Number Register Bit Definitions */ + +#if defined(CONFIG_ARM_MPU_NREGIONS) +# if CONFIG_ARM_MPU_NREGIONS <= 8 +# define MPU_RNR_MASK (0x00000007) +# elif CONFIG_ARM_MPU_NREGIONS <= 16 +# define MPU_RNR_MASK (0x0000000f) +# elif CONFIG_ARM_MPU_NREGIONS <= 32 +# define MPU_RNR_MASK (0x0000001f) +# else +# error "FIXME: Unsupported number of MPU regions" +# endif +#endif + +/* MPU Region Base Address Register Bit Definitions */ + +#define MPU_RBAR_REGION_SHIFT (0) /* Bits 0-3: MPU region */ +#define MPU_RBAR_REGION_MASK (15 << MPU_RBAR_REGION_SHIFT) +#define MPU_RBAR_VALID (1 << 4) /* Bit 4: MPU Region Number valid */ +#define MPU_RBAR_ADDR_MASK 0xffffffe0 /* Bits N-31: Region base addrese */ + +/* MPU Region Attributes and Size Register Bit Definitions */ + +#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */ +#define MPU_RASR_SIZE_SHIFT (1) /* Bits 1-5: Size of the MPU protection region */ +#define MPU_RASR_SIZE_MASK (31 << MPU_RASR_SIZE_SHIFT) +# define MPU_RASR_SIZE_LOG2(n) ((n-1) << MPU_RASR_SIZE_SHIFT) +#define MPU_RASR_SRD_SHIFT (8) /* Bits 8-15: Subregion disable */ +#define MPU_RASR_SRD_MASK (0xff << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_0 (0x01 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_1 (0x02 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_2 (0x04 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_3 (0x08 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_4 (0x10 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_5 (0x20 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_6 (0x40 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_7 (0x80 << MPU_RASR_SRD_SHIFT) +#define MPU_RASR_ATTR_SHIFT (16) /* Bits 16-31: MPU Region Attribute field */ +#define MPU_RASR_ATTR_MASK (0xffff << MPU_RASR_ATTR_SHIFT) +# define MPU_RASR_B (1 << 16) /* Bit 16: Bufferable */ +# define MPU_RASR_C (1 << 17) /* Bit 17: Cacheable */ +# define MPU_RASR_S (1 << 18) /* Bit 18: Shareable */ +# define MPU_RASR_TEX_SHIFT (19) /* Bits 19-21: TEX Address Permisson */ +# define MPU_RASR_TEX_MASK (7 << MPU_RASR_TEX_SHIFT) +# define MPU_RASR_AP_SHIFT (24) /* Bits 24-26: Access permission */ +# define MPU_RASR_AP_MASK (7 << MPU_RASR_AP_SHIFT) +# define MPU_RASR_AP_NONO (0 << MPU_RASR_AP_SHIFT) /* P:None U:None */ +# define MPU_RASR_AP_RWNO (1 << MPU_RASR_AP_SHIFT) /* P:RW U:None */ +# define MPU_RASR_AP_RWRO (2 << MPU_RASR_AP_SHIFT) /* P:RW U:RO */ +# define MPU_RASR_AP_RWRW (3 << MPU_RASR_AP_SHIFT) /* P:RW U:RW */ +# define MPU_RASR_AP_RONO (5 << MPU_RASR_AP_SHIFT) /* P:RO U:None */ +# define MPU_RASR_AP_RORO (6 << MPU_RASR_AP_SHIFT) /* P:RO U:RO */ +# define MPU_RASR_XN (1 << 28) /* Bit 28: Instruction access disable */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mpu_allocregion + * + * Description: + * Allocate the next region + * + ****************************************************************************/ + +unsigned int mpu_allocregion(void); + +/**************************************************************************** + * Name: mpu_log2regionceil + * + * Description: + * Determine the smallest value of l2size (log base 2 size) such that the + * following is true: + * + * size <= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionceil(size_t size); + +/**************************************************************************** + * Name: mpu_log2regionfloor + * + * Description: + * Determine the largest value of l2size (log base 2 size) such that the + * following is true: + * + * size >= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionfloor(size_t size); + +/**************************************************************************** + * Name: mpu_subregion + * + * Description: + * Given (1) the offset to the beginning of valid data, (2) the size of the + * memory to be mapped and (2) the log2 size of the mapping to use, determine + * the minimal sub-region set to span that memory region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size); + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_showtype + * + * Description: + * Show the characteristics of the MPU + * + ****************************************************************************/ + +static inline void mpu_showtype(void) +{ +#ifdef CONFIG_DEBUG + uint32_t regval = getreg32(MPU_TYPE); + dbg("%s MPU Regions: data=%d instr=%d\n", + (regval & MPU_TYPE_SEPARATE) != 0 ? "Separate" : "Unified", + (regval & MPU_TYPE_DREGION_MASK) >> MPU_TYPE_DREGION_SHIFT, + (regval & MPU_TYPE_IREGION_MASK) >> MPU_TYPE_IREGION_SHIFT); +#endif +} + +/**************************************************************************** + * Name: mpu_control + * + * Description: + * Configure and enable (or disable) the MPU + * + ****************************************************************************/ + +static inline void mpu_control(bool enable, bool hfnmiena, bool privdefena) +{ + uint32_t regval = 0; + + if (enable) + { + regval |= MPU_CTRL_ENABLE; /* Enable the MPU */ + + if (hfnmiena) + { + regval |= MPU_CTRL_HFNMIENA; /* Enable MPU during hard fault, NMI, and FAULTMAS */ + } + + if (privdefena) + { + regval |= MPU_CTRL_PRIVDEFENA; /* Enable privileged access to default memory map */ + } + } + + putreg32(regval, MPU_CTRL); +} + + +/**************************************************************************** + * Name: mpu_priv_stronglyordered + * + * Description: + * Configure a region for privileged, strongly ordered memory + * + ****************************************************************************/ + +#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE) +static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + /* Not Cacheable */ + /* Not Bufferable */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_AP_RWNO; /* P:RW U:None */ + putreg32(regval, MPU_RASR); +} +#endif + +/**************************************************************************** + * Name: mpu_user_flash + * + * Description: + * Configure a region for user program flash + * + ****************************************************************************/ + +static inline void mpu_user_flash(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_AP_RORO; /* P:RO U:RO */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_priv_flash + * + * Description: + * Configure a region for privileged program flash + * + ****************************************************************************/ + +static inline void mpu_priv_flash(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(mpu_allocregion(), MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_AP_RONO; /* P:RO U:None */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_user_intsram + * + * Description: + * Configure a region as user internal SRAM + * + ****************************************************************************/ + +static inline void mpu_user_intsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_AP_RWRW; /* P:RW U:RW */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_priv_intsram + * + * Description: + * Configure a region as privileged internal SRAM + * + ****************************************************************************/ + +static inline void mpu_priv_intsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_AP_RWNO; /* P:RW U:None */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_user_extsram + * + * Description: + * Configure a region as user external SRAM + * + ****************************************************************************/ + +static inline void mpu_user_extsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_B | /* Bufferable */ + MPU_RASR_AP_RWRW; /* P:RW U:RW */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_priv_extsram + * + * Description: + * Configure a region as privileged external SRAM + * + ****************************************************************************/ + +static inline void mpu_priv_extsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_C | /* Cacheable */ + MPU_RASR_B | /* Bufferable */ + MPU_RASR_AP_RWNO; /* P:RW U:None */ + putreg32(regval, MPU_RASR); +} + +/**************************************************************************** + * Name: mpu_peripheral + * + * Description: + * Configure a region as privileged periperal address space + * + ****************************************************************************/ + +static inline void mpu_peripheral(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + putreg32(region, MPU_RNR); + + /* Select the region base address */ + + putreg32((base & MPU_RBAR_ADDR_MASK) | region, MPU_RBAR); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* Then configure the region */ + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_SIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT) | /* Sub-regions */ + MPU_RASR_S | /* Shareable */ + MPU_RASR_B | /* Bufferable */ + MPU_RASR_AP_RWNO | /* P:RW U:None */ + MPU_RASR_XN; /* Instruction access disable */ + + putreg32(regval, MPU_RASR); +} + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_ARMV7M_MPU_H */ + diff --git a/arch/arm/src/armv7-m/nvic.h b/arch/arm/src/armv7-m/nvic.h new file mode 100644 index 0000000000000000000000000000000000000000..3b5ca6007dc14e09502d81d7b8f3c5d043752a8d --- /dev/null +++ b/arch/arm/src/armv7-m/nvic.h @@ -0,0 +1,694 @@ +/******************************************************************************************** + * arch/arm/src/armv7-m/nvic.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARMV7_M_NVIC_H +#define __ARCH_ARM_SRC_COMMON_ARMV7_M_NVIC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* NVIC base address ************************************************************************/ + +#define ARMV7M_NVIC_BASE 0xe000e000 + +/* NVIC register offsets ********************************************************************/ + +#define NVIC_ICTR_OFFSET 0x0004 /* Interrupt controller type register */ +#define NVIC_SYSTICK_CTRL_OFFSET 0x0010 /* SysTick control and status register */ +#define NVIC_SYSTICK_RELOAD_OFFSET 0x0014 /* SysTick reload value register */ +#define NVIC_SYSTICK_CURRENT_OFFSET 0x0018 /* SysTick current value register */ +#define NVIC_SYSTICK_CALIB_OFFSET 0x001c /* SysTick calibration value register */ + +#define NVIC_IRQ_ENABLE_OFFSET(n) (0x0100 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_ENABLE_OFFSET 0x0100 /* IRQ 0-31 set enable register */ +#define NVIC_IRQ32_63_ENABLE_OFFSET 0x0104 /* IRQ 32-63 set enable register */ +#define NVIC_IRQ64_95_ENABLE_OFFSET 0x0108 /* IRQ 64-95 set enable register */ +#define NVIC_IRQ96_127_ENABLE_OFFSET 0x010c /* IRQ 96-127 set enable register */ +#define NVIC_IRQ128_159_ENABLE_OFFSET 0x0110 /* IRQ 128-159 set enable register */ +#define NVIC_IRQ160_191_ENABLE_OFFSET 0x0114 /* IRQ 160-191 set enable register */ +#define NVIC_IRQ192_223_ENABLE_OFFSET 0x0118 /* IRQ 192-223 set enable register */ +#define NVIC_IRQ224_239_ENABLE_OFFSET 0x011c /* IRQ 224-239 set enable register */ + +#define NVIC_IRQ_CLEAR_OFFSET(n) (0x0180 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_CLEAR_OFFSET 0x0180 /* IRQ 0-31 clear enable register */ +#define NVIC_IRQ32_63_CLEAR_OFFSET 0x0184 /* IRQ 32-63 clear enable register */ +#define NVIC_IRQ64_95_CLEAR_OFFSET 0x0188 /* IRQ 64-95 clear enable register */ +#define NVIC_IRQ96_127_CLEAR_OFFSET 0x018c /* IRQ 96-127 clear enable register */ +#define NVIC_IRQ128_159_CLEAR_OFFSET 0x0190 /* IRQ 128-159 clear enable register */ +#define NVIC_IRQ160_191_CLEAR_OFFSET 0x0194 /* IRQ 160-191 clear enable register */ +#define NVIC_IRQ192_223_CLEAR_OFFSET 0x0198 /* IRQ 192-223 clear enable register */ +#define NVIC_IRQ224_239_CLEAR_OFFSET 0x019c /* IRQ 224-2391 clear enable register */ + +#define NVIC_IRQ_PEND_OFFSET(n) (0x0200 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_PEND_OFFSET 0x0200 /* IRQ 0-31 set pending register */ +#define NVIC_IRQ32_63_PEND_OFFSET 0x0204 /* IRQ 32-63 set pending register */ +#define NVIC_IRQ64_95_PEND_OFFSET 0x0208 /* IRQ 64-95 set pending register */ +#define NVIC_IRQ96_127_PEND_OFFSET 0x020c /* IRQ 96-127 set pending register */ +#define NVIC_IRQ128_159_PEND_OFFSET 0x0210 /* IRQ 128-159 set pending register */ +#define NVIC_IRQ160_191_PEND_OFFSET 0x0214 /* IRQ 160-191 set pending register */ +#define NVIC_IRQ192_223_PEND_OFFSET 0x0218 /* IRQ 192-2231 set pending register */ +#define NVIC_IRQ224_239_PEND_OFFSET 0x021c /* IRQ 224-2391 set pending register */ + +#define NVIC_IRQ_CLRPEND_OFFSET(n) (0x0280 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_CLRPEND_OFFSET 0x0280 /* IRQ 0-31 clear pending register */ +#define NVIC_IRQ32_63_CLRPEND_OFFSET 0x0284 /* IRQ 32-63 clear pending register */ +#define NVIC_IRQ64_95_CLRPEND_OFFSET 0x0288 /* IRQ 64-95 clear pending register */ +#define NVIC_IRQ96_127_CLRPEND_OFFSET 0x028c /* IRQ 96-127 clear pending register */ +#define NVIC_IRQ128_159_CLRPEND_OFFSET 0x0290 /* IRQ 128-159 clear pending register */ +#define NVIC_IRQ160_191_CLRPEND_OFFSET 0x0294 /* IRQ 160-191 clear pending register */ +#define NVIC_IRQ192_223_CLRPEND_OFFSET 0x0298 /* IRQ 192-223 clear pending register */ +#define NVIC_IRQ224_239_CLRPEND_OFFSET 0x029c /* IRQ 224-239 clear pending register */ + +#define NVIC_IRQ_ACTIVE_OFFSET(n) (0x0300 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_ACTIVE_OFFSET 0x0300 /* IRQ 0-31 active bit register */ +#define NVIC_IRQ32_63_ACTIVE_OFFSET 0x0304 /* IRQ 32-63 active bit register */ +#define NVIC_IRQ64_95_ACTIVE_OFFSET 0x0308 /* IRQ 64-95 active bit register */ +#define NVIC_IRQ96_127_ACTIVE_OFFSET 0x030c /* IRQ 96-127 active bit register */ +#define NVIC_IRQ128_159_ACTIVE_OFFSET 0x0310 /* IRQ 128-159 active bit register */ +#define NVIC_IRQ160_191_ACTIVE_OFFSET 0x0314 /* IRQ 160-191 active bit register */ +#define NVIC_IRQ192_223_ACTIVE_OFFSET 0x0318 /* IRQ 192-223 active bit register */ +#define NVIC_IRQ224_239_ACTIVE_OFFSET 0x031c /* IRQ 224-239 active bit register */ + +#define NVIC_IRQ_PRIORITY_OFFSET(n) (0x0400 + 4*((n) >> 2)) +#define NVIC_IRQ0_3_PRIORITY_OFFSET 0x0400 /* IRQ 0-3 priority register */ +#define NVIC_IRQ4_7_PRIORITY_OFFSET 0x0404 /* IRQ 4-7 priority register */ +#define NVIC_IRQ8_11_PRIORITY_OFFSET 0x0408 /* IRQ 8-11 priority register */ +#define NVIC_IRQ12_15_PRIORITY_OFFSET 0x040c /* IRQ 12-15 priority register */ +#define NVIC_IRQ16_19_PRIORITY_OFFSET 0x0410 /* IRQ 16-19 priority register */ +#define NVIC_IRQ20_23_PRIORITY_OFFSET 0x0414 /* IRQ 20-23 priority register */ +#define NVIC_IRQ24_27_PRIORITY_OFFSET 0x0418 /* IRQ 24-29 priority register */ +#define NVIC_IRQ28_31_PRIORITY_OFFSET 0x041c /* IRQ 28-31 priority register */ +#define NVIC_IRQ32_35_PRIORITY_OFFSET 0x0420 /* IRQ 32-35 priority register */ +#define NVIC_IRQ36_39_PRIORITY_OFFSET 0x0424 /* IRQ 36-39 priority register */ +#define NVIC_IRQ40_43_PRIORITY_OFFSET 0x0428 /* IRQ 40-43 priority register */ +#define NVIC_IRQ44_47_PRIORITY_OFFSET 0x042c /* IRQ 44-47 priority register */ +#define NVIC_IRQ48_51_PRIORITY_OFFSET 0x0430 /* IRQ 48-51 priority register */ +#define NVIC_IRQ52_55_PRIORITY_OFFSET 0x0434 /* IRQ 52-55 priority register */ +#define NVIC_IRQ56_59_PRIORITY_OFFSET 0x0438 /* IRQ 56-59 priority register */ +#define NVIC_IRQ60_63_PRIORITY_OFFSET 0x043c /* IRQ 60-63 priority register */ +#define NVIC_IRQ64_67_PRIORITY_OFFSET 0x0440 /* IRQ 64-67 priority register */ +#define NVIC_IRQ68_71_PRIORITY_OFFSET 0x0444 /* IRQ 68-71 priority register */ +#define NVIC_IRQ72_75_PRIORITY_OFFSET 0x0448 /* IRQ 72-75 priority register */ +#define NVIC_IRQ76_79_PRIORITY_OFFSET 0x044c /* IRQ 76-79 priority register */ +#define NVIC_IRQ80_83_PRIORITY_OFFSET 0x0450 /* IRQ 80-83 priority register */ +#define NVIC_IRQ84_87_PRIORITY_OFFSET 0x0454 /* IRQ 84-87 priority register */ +#define NVIC_IRQ88_91_PRIORITY_OFFSET 0x0458 /* IRQ 88-91 priority register */ +#define NVIC_IRQ92_95_PRIORITY_OFFSET 0x045c /* IRQ 92-95 priority register */ +#define NVIC_IRQ96_99_PRIORITY_OFFSET 0x0460 /* IRQ 96-99 priority register */ +#define NVIC_IRQ100_103_PRIORITY_OFFSET 0x0464 /* IRQ 100-103 priority register */ +#define NVIC_IRQ104_107_PRIORITY_OFFSET 0x0468 /* IRQ 104-107 priority register */ +#define NVIC_IRQ108_111_PRIORITY_OFFSET 0x046c /* IRQ 108-111 priority register */ +#define NVIC_IRQ112_115_PRIORITY_OFFSET 0x0470 /* IRQ 112-115 priority register */ +#define NVIC_IRQ116_119_PRIORITY_OFFSET 0x0474 /* IRQ 116-119 priority register */ +#define NVIC_IRQ120_123_PRIORITY_OFFSET 0x0478 /* IRQ 120-123 priority register */ +#define NVIC_IRQ124_127_PRIORITY_OFFSET 0x047c /* IRQ 124-127 priority register */ +#define NVIC_IRQ128_131_PRIORITY_OFFSET 0x0480 /* IRQ 128-131 priority register */ +#define NVIC_IRQ132_135_PRIORITY_OFFSET 0x0484 /* IRQ 132-135 priority register */ +#define NVIC_IRQ136_139_PRIORITY_OFFSET 0x0488 /* IRQ 136-139 priority register */ +#define NVIC_IRQ140_143_PRIORITY_OFFSET 0x048c /* IRQ 140-143 priority register */ +#define NVIC_IRQ144_147_PRIORITY_OFFSET 0x0490 /* IRQ 144-147 priority register */ +#define NVIC_IRQ148_151_PRIORITY_OFFSET 0x0494 /* IRQ 148-151 priority register */ +#define NVIC_IRQ152_155_PRIORITY_OFFSET 0x0498 /* IRQ 152-155 priority register */ +#define NVIC_IRQ156_159_PRIORITY_OFFSET 0x049c /* IRQ 156-159 priority register */ +#define NVIC_IRQ160_163_PRIORITY_OFFSET 0x04a0 /* IRQ 160-163 priority register */ +#define NVIC_IRQ164_167_PRIORITY_OFFSET 0x04a4 /* IRQ 164-167 priority register */ +#define NVIC_IRQ168_171_PRIORITY_OFFSET 0x04a8 /* IRQ 168-171 priority register */ +#define NVIC_IRQ172_175_PRIORITY_OFFSET 0x04ac /* IRQ 172-175 priority register */ +#define NVIC_IRQ176_179_PRIORITY_OFFSET 0x04b0 /* IRQ 176-179 priority register */ +#define NVIC_IRQ180_183_PRIORITY_OFFSET 0x04b4 /* IRQ 180-183 priority register */ +#define NVIC_IRQ184_187_PRIORITY_OFFSET 0x04b8 /* IRQ 184-187 priority register */ +#define NVIC_IRQ188_191_PRIORITY_OFFSET 0x04bc /* IRQ 188-191 priority register */ +#define NVIC_IRQ192_195_PRIORITY_OFFSET 0x04c0 /* IRQ 192-195 priority register */ +#define NVIC_IRQ196_199_PRIORITY_OFFSET 0x04c4 /* IRQ 196-199 priority register */ +#define NVIC_IRQ200_203_PRIORITY_OFFSET 0x04c8 /* IRQ 200-203 priority register */ +#define NVIC_IRQ204_207_PRIORITY_OFFSET 0x04cc /* IRQ 204-207 priority register */ +#define NVIC_IRQ208_211_PRIORITY_OFFSET 0x04d0 /* IRQ 208-211 priority register */ +#define NVIC_IRQ212_215_PRIORITY_OFFSET 0x04d4 /* IRQ 212-215 priority register */ +#define NVIC_IRQ216_219_PRIORITY_OFFSET 0x04d8 /* IRQ 216-219 priority register */ +#define NVIC_IRQ220_223_PRIORITY_OFFSET 0x04dc /* IRQ 220-223 priority register */ +#define NVIC_IRQ224_227_PRIORITY_OFFSET 0x04e0 /* IRQ 224-227 priority register */ +#define NVIC_IRQ228_231_PRIORITY_OFFSET 0x04e4 /* IRQ 228-231 priority register */ +#define NVIC_IRQ232_235_PRIORITY_OFFSET 0x04e8 /* IRQ 232-235 priority register */ +#define NVIC_IRQ236_239_PRIORITY_OFFSET 0x04ec /* IRQ 236-239 priority register */ + +/* System Control Block (SCB) */ + +#define NVIC_CPUID_BASE_OFFSET 0x0d00 /* CPUID base register */ +#define NVIC_INTCTRL_OFFSET 0x0d04 /* Interrupt control state register */ +#define NVIC_VECTAB_OFFSET 0x0d08 /* Vector table offset register */ +#define NVIC_AIRCR_OFFSET 0x0d0c /* Application interrupt/reset contol registr */ +#define NVIC_SYSCON_OFFSET 0x0d10 /* System control register */ +#define NVIC_CFGCON_OFFSET 0x0d14 /* Configuration control register */ +#define NVIC_SYSH_PRIORITY_OFFSET(n) (0x0d14 + 4*((n) >> 2)) +#define NVIC_SYSH4_7_PRIORITY_OFFSET 0x0d18 /* System handlers 4-7 priority register */ +#define NVIC_SYSH8_11_PRIORITY_OFFSET 0x0d1c /* System handler 8-11 priority register */ +#define NVIC_SYSH12_15_PRIORITY_OFFSET 0x0d20 /* System handler 12-15 priority register */ +#define NVIC_SYSHCON_OFFSET 0x0d24 /* System handler control and state register */ +#define NVIC_CFAULTS_OFFSET 0x0d28 /* Configurable fault status register */ +#define NVIC_HFAULTS_OFFSET 0x0d2c /* Hard fault status register */ +#define NVIC_DFAULTS_OFFSET 0x0d30 /* Debug fault status register */ +#define NVIC_MEMMANAGE_ADDR_OFFSET 0x0d34 /* Mem manage address register */ +#define NVIC_BFAULT_ADDR_OFFSET 0x0d38 /* Bus fault address register */ +#define NVIC_AFAULTS_OFFSET 0x0d3c /* Auxiliary fault status register */ +#define NVIC_PFR0_OFFSET 0x0d40 /* Processor feature register 0 */ +#define NVIC_PFR1_OFFSET 0x0d44 /* Processor feature register 1 */ +#define NVIC_DFR0_OFFSET 0x0d48 /* Debug feature register 0 */ +#define NVIC_AFR0_OFFSET 0x0d4c /* Auxiliary feature register 0 */ +#define NVIC_MMFR0_OFFSET 0x0d50 /* Memory model feature register 0 */ +#define NVIC_MMFR1_OFFSET 0x0d54 /* Memory model feature register 1 */ +#define NVIC_MMFR2_OFFSET 0x0d58 /* Memory model feature register 2 */ +#define NVIC_MMFR3_OFFSET 0x0d5c /* Memory model feature register 3 */ +#define NVIC_ISAR0_OFFSET 0x0d60 /* ISA feature register 0 */ +#define NVIC_ISAR1_OFFSET 0x0d64 /* ISA feature register 1 */ +#define NVIC_ISAR2_OFFSET 0x0d68 /* ISA feature register 2 */ +#define NVIC_ISAR3_OFFSET 0x0d6c /* ISA feature register 3 */ +#define NVIC_ISAR4_OFFSET 0x0d70 /* ISA feature register 4 */ +#define NVIC_CLIDR_OFFSET 0x0d78 /* Cache Level ID register (Cortex-M7) */ +#define NVIC_CTR_OFFSET 0x0d7c /* Cache Type register (Cortex-M7) */ +#define NVIC_CCSIDR_OFFSET 0x0d80 /* Cache Size ID Register (Cortex-M7) */ +#define NVIC_CSSELR_OFFSET 0x0d84 /* Cache Size Selection Register (Cortex-M7) */ +#define NVIC_CPACR_OFFSET 0x0d88 /* Coprocessor Access Control Register */ +#define NVIC_DHCSR_OFFSET 0x0df0 /* Debug Halting Control and Status Register */ +#define NVIC_DCRSR_OFFSET 0x0df4 /* Debug Core Register Selector Register */ +#define NVIC_DCRDR_OFFSET 0x0df8 /* Debug Core Register Data Register */ +#define NVIC_DEMCR_OFFSET 0x0dfc /* Debug Exception and Monitor Control Register */ +#define NVIC_STIR_OFFSET 0x0f00 /* Software trigger interrupt register */ +#define NVIC_FPCCR_OFFSET 0x0f34 /* Floating-point Context Control Register */ +#define NVIC_FPCAR_OFFSET 0x0f38 /* Floating-point Context Address Register */ +#define NVIC_FPDSCR_OFFSET 0x0f3c /* Floating-point Default Status Control Register */ +#define NVIC_MVFR0_OFFSET 0x0f40 /* Media and VFP Feature Register 0 */ +#define NVIC_MVFR1_OFFSET 0x0f44 /* Media and VFP Feature Register 1 */ +#define NVIC_MVFR2_OFFSET 0x0f48 /* Media and VFP Feature Register 2 */ +#define NVIC_ICIALLU_OFFSET 0x0f50 /* I-Cache Invalidate All to PoU (Cortex-M7) */ +#define NVIC_ICIMVAU_OFFSET 0x0f58 /* I-Cache Invalidate by MVA to PoU (Cortex-M7) */ +#define NVIC_DCIMVAU_OFFSET 0x0f5c /* D-Cache Invalidate by MVA to PoC (Cortex-M7) */ +#define NVIC_DCISW_OFFSET 0x0f60 /* D-Cache Invalidate by Set-way (Cortex-M7) */ +#define NVIC_DCCMVAU_OFFSET 0x0f64 /* D-Cache Clean by MVA to PoU (Cortex-M7) */ +#define NVIC_DCCMVAC_OFFSET 0x0f68 /* D-Cache Clean by MVA to PoC (Cortex-M7) */ +#define NVIC_DCCSW_OFFSET 0x0f6c /* D-Cache Clean by Set-way (Cortex-M7) */ +#define NVIC_DCCIMVAC_OFFSET 0x0f70 /* D-Cache Clean and Invalidate by MVA to PoC (Cortex-M7) */ +#define NVIC_DCCISW_OFFSET 0x0f74 /* D-Cache Clean and Invalidate by Set-way (Cortex-M7) */ +#define NVIC_ITCMCR_OFFSET 0x0f90 /* Instruction Tightly-Coupled Memory Control Register */ +#define NVIC_DTCMCR_OFFSET 0x0f94 /* Data Tightly-Coupled Memory Control Registers */ +#define NVIC_AHBPCR_OFFSET 0x0f98 /* AHBP Control Register */ +#define NVIC_CACR_OFFSET 0x0f9c /* L1 Cache Control Register */ +#define NVIC_AHBSCR_OFFSET 0x0fa0 /* AHB Slave Control Register */ +#define NVIC_ABFSR_OFFSET 0x0fa8 /* Auxiliary Bus Fault Status */ +#define NVIC_PID4_OFFSET 0x0fd0 /* Peripheral identification register (PID4) */ +#define NVIC_PID5_OFFSET 0x0fd4 /* Peripheral identification register (PID5) */ +#define NVIC_PID6_OFFSET 0x0fd8 /* Peripheral identification register (PID6) */ +#define NVIC_PID7_OFFSET 0x0fdc /* Peripheral identification register (PID7) */ +#define NVIC_PID0_OFFSET 0x0fe0 /* Peripheral identification register bits 7:0 (PID0) */ +#define NVIC_PID1_OFFSET 0x0fe4 /* Peripheral identification register bits 15:8 (PID1) */ +#define NVIC_PID2_OFFSET 0x0fe8 /* Peripheral identification register bits 23:16 (PID2) */ +#define NVIC_PID3_OFFSET 0x0fec /* Peripheral identification register bits 23:16 (PID3) */ +#define NVIC_CID0_OFFSET 0x0ff0 /* Component identification register bits 7:0 (CID0) */ +#define NVIC_CID1_OFFSET 0x0ff4 /* Component identification register bits 15:8 (CID0) */ +#define NVIC_CID2_OFFSET 0x0ff8 /* Component identification register bits 23:16 (CID0) */ +#define NVIC_CID3_OFFSET 0x0ffc /* Component identification register bits 23:16 (CID0) */ + +/* NVIC register addresses ******************************************************************/ + +#define NVIC_ICTR (ARMV7M_NVIC_BASE + NVIC_ICTR_OFFSET) +#define NVIC_SYSTICK_CTRL (ARMV7M_NVIC_BASE + NVIC_SYSTICK_CTRL_OFFSET) +#define NVIC_SYSTICK_RELOAD (ARMV7M_NVIC_BASE + NVIC_SYSTICK_RELOAD_OFFSET) +#define NVIC_SYSTICK_CURRENT (ARMV7M_NVIC_BASE + NVIC_SYSTICK_CURRENT_OFFSET) +#define NVIC_SYSTICK_CALIB (ARMV7M_NVIC_BASE + NVIC_SYSTICK_CALIB_OFFSET) + +#define NVIC_IRQ_ENABLE(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_ENABLE_OFFSET(n)) +#define NVIC_IRQ0_31_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ0_31_ENABLE_OFFSET) +#define NVIC_IRQ32_63_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ32_63_ENABLE_OFFSET) +#define NVIC_IRQ64_95_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ64_95_ENABLE_OFFSET) +#define NVIC_IRQ96_127_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ96_127_ENABLE_OFFSET) +#define NVIC_IRQ128_159_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ128_159_ENABLE_OFFSET) +#define NVIC_IRQ160_191_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ160_191_ENABLE_OFFSET) +#define NVIC_IRQ192_223_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ192_223_ENABLE_OFFSET) +#define NVIC_IRQ224_239_ENABLE (ARMV7M_NVIC_BASE + NVIC_IRQ224_239_ENABLE_OFFSET) + +#define NVIC_IRQ_CLEAR(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_CLEAR_OFFSET(n)) +#define NVIC_IRQ0_31_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ0_31_CLEAR_OFFSET) +#define NVIC_IRQ32_63_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ32_63_CLEAR_OFFSET) +#define NVIC_IRQ64_95_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ64_95_CLEAR_OFFSET) +#define NVIC_IRQ96_127_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ96_127_CLEAR_OFFSET) +#define NVIC_IRQ128_159_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ128_159_CLEAR_OFFSET) +#define NVIC_IRQ160_191_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ160_191_CLEAR_OFFSET) +#define NVIC_IRQ192_223_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ192_223_CLEAR_OFFSET) +#define NVIC_IRQ224_239_CLEAR (ARMV7M_NVIC_BASE + NVIC_IRQ224_239_CLEAR_OFFSET) + +#define NVIC_IRQ_PEND(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_PEND_OFFSET(n)) +#define NVIC_IRQ0_31_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ0_31_PEND_OFFSET) +#define NVIC_IRQ32_63_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ32_63_PEND_OFFSET) +#define NVIC_IRQ64_95_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ64_95_PEND_OFFSET) +#define NVIC_IRQ96_127_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ96_127_PEND_OFFSET) +#define NVIC_IRQ128_159_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ128_159_PEND_OFFSET) +#define NVIC_IRQ160_191_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ160_191_PEND_OFFSET) +#define NVIC_IRQ192_223_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ192_223_PEND_OFFSET) +#define NVIC_IRQ224_239_PEND (ARMV7M_NVIC_BASE + NVIC_IRQ224_239_PEND_OFFSET) + +#define NVIC_IRQ_CLRPEND(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_CLRPEND_OFFSET(n)) +#define NVIC_IRQ0_31_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ0_31_CLRPEND_OFFSET) +#define NVIC_IRQ32_63_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ32_63_CLRPEND_OFFSET) +#define NVIC_IRQ64_95_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ64_95_CLRPEND_OFFSET) +#define NVIC_IRQ96_127_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ96_127_CLRPEND_OFFSET) +#define NVIC_IRQ128_159_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ128_159_CLRPEND_OFFSET) +#define NVIC_IRQ160_191_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ160_191_CLRPEND_OFFSET) +#define NVIC_IRQ192_223_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ192_223_CLRPEND_OFFSET) +#define NVIC_IRQ224_239_CLRPEND (ARMV7M_NVIC_BASE + NVIC_IRQ224_239_CLRPEND_OFFSET) + +#define NVIC_IRQ_ACTIVE(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_ACTIVE_OFFSET(n)) +#define NVIC_IRQ0_31_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ0_31_ACTIVE_OFFSET) +#define NVIC_IRQ32_63_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ32_63_ACTIVE_OFFSET) +#define NVIC_IRQ64_95_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ64_95_ACTIVE_OFFSET) +#define NVIC_IRQ96_127_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ96_127_ACTIVE_OFFSET) +#define NVIC_IRQ128_159_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ128_159_ACTIVE_OFFSET) +#define NVIC_IRQ160_191_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ160_191_ACTIVE_OFFSET) +#define NVIC_IRQ192_223_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ192_223_ACTIVE_OFFSET) +#define NVIC_IRQ224_239_ACTIVE (ARMV7M_NVIC_BASE + NVIC_IRQ224_239_ACTIVE_OFFSET) + +#define NVIC_IRQ_PRIORITY(n) (ARMV7M_NVIC_BASE + NVIC_IRQ_PRIORITY_OFFSET(n)) +#define NVIC_IRQ0_3_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ0_3_PRIORITY_OFFSET) +#define NVIC_IRQ4_7_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ4_7_PRIORITY_OFFSET) +#define NVIC_IRQ8_11_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ8_11_PRIORITY_OFFSET) +#define NVIC_IRQ12_15_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ12_15_PRIORITY_OFFSET) +#define NVIC_IRQ16_19_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ16_19_PRIORITY_OFFSET) +#define NVIC_IRQ20_23_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ20_23_PRIORITY_OFFSET) +#define NVIC_IRQ24_27_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ24_27_PRIORITY_OFFSET) +#define NVIC_IRQ28_31_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ28_31_PRIORITY_OFFSET) +#define NVIC_IRQ32_35_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ32_35_PRIORITY_OFFSET) +#define NVIC_IRQ36_39_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ36_39_PRIORITY_OFFSET) +#define NVIC_IRQ40_43_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ40_43_PRIORITY_OFFSET) +#define NVIC_IRQ44_47_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ44_47_PRIORITY_OFFSET) +#define NVIC_IRQ48_51_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ48_51_PRIORITY_OFFSET) +#define NVIC_IRQ52_55_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ52_55_PRIORITY_OFFSET) +#define NVIC_IRQ56_59_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ56_59_PRIORITY_OFFSET) +#define NVIC_IRQ60_63_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ60_63_PRIORITY_OFFSET) +#define NVIC_IRQ64_67_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ64_67_PRIORITY_OFFSET) +#define NVIC_IRQ68_71_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ68_71_PRIORITY_OFFSET) +#define NVIC_IRQ72_75_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ72_75_PRIORITY_OFFSET) +#define NVIC_IRQ76_79_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ76_79_PRIORITY_OFFSET) +#define NVIC_IRQ80_83_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ80_83_PRIORITY_OFFSET) +#define NVIC_IRQ84_87_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ84_87_PRIORITY_OFFSET) +#define NVIC_IRQ88_91_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ88_91_PRIORITY_OFFSET) +#define NVIC_IRQ92_95_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ92_95_PRIORITY_OFFSET) +#define NVIC_IRQ96_99_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ96_99_PRIORITY_OFFSET) +#define NVIC_IRQ100_103_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ100_103_PRIORITY_OFFSET) +#define NVIC_IRQ104_107_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ104_107_PRIORITY_OFFSET) +#define NVIC_IRQ108_111_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ108_111_PRIORITY_OFFSET) +#define NVIC_IRQ112_115_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ112_115_PRIORITY_OFFSET) +#define NVIC_IRQ116_119_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ116_119_PRIORITY_OFFSET) +#define NVIC_IRQ120_123_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ120_123_PRIORITY_OFFSET) +#define NVIC_IRQ124_127_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ124_127_PRIORITY_OFFSET) +#define NVIC_IRQ128_131_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ128_131_PRIORITY_OFFSET) +#define NVIC_IRQ132_135_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ132_135_PRIORITY_OFFSET) +#define NVIC_IRQ136_139_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ136_139_PRIORITY_OFFSET) +#define NVIC_IRQ140_143_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ140_143_PRIORITY_OFFSET) +#define NVIC_IRQ144_147_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ144_147_PRIORITY_OFFSET) +#define NVIC_IRQ148_151_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ148_151_PRIORITY_OFFSET) +#define NVIC_IRQ152_155_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ152_155_PRIORITY_OFFSET) +#define NVIC_IRQ156_159_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ156_159_PRIORITY_OFFSET) +#define NVIC_IRQ160_163_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ160_163_PRIORITY_OFFSET) +#define NVIC_IRQ164_167_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ164_167_PRIORITY_OFFSET) +#define NVIC_IRQ168_171_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ168_171_PRIORITY_OFFSET) +#define NVIC_IRQ172_175_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ172_175_PRIORITY_OFFSET) +#define NVIC_IRQ176_179_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ176_179_PRIORITY_OFFSET) +#define NVIC_IRQ180_183_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ180_183_PRIORITY_OFFSET) +#define NVIC_IRQ184_187_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ184_187_PRIORITY_OFFSET) +#define NVIC_IRQ188_191_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ188_191_PRIORITY_OFFSET) +#define NVIC_IRQ192_195_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ192_195_PRIORITY_OFFSET) +#define NVIC_IRQ196_199_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ196_199_PRIORITY_OFFSET) +#define NVIC_IRQ200_203_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ200_203_PRIORITY_OFFSET) +#define NVIC_IRQ204_207_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ204_207_PRIORITY_OFFSET) +#define NVIC_IRQ208_211_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ208_211_PRIORITY_OFFSET) +#define NVIC_IRQ212_215_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ212_215_PRIORITY_OFFSET) +#define NVIC_IRQ216_219_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ216_219_PRIORITY_OFFSET) +#define NVIC_IRQ220_223_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ220_223_PRIORITY_OFFSET) +#define NVIC_IRQ224_227_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ224_227_PRIORITY_OFFSET) +#define NVIC_IRQ228_231_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ228_231_PRIORITY_OFFSET) +#define NVIC_IRQ232_235_PRIORITY (ARMV7M_NVIC_BASE + NVIC_IRQ232_235_PRIORITY_OFFSET) + +#define NVIC_CPUID_BASE (ARMV7M_NVIC_BASE + NVIC_CPUID_BASE_OFFSET) +#define NVIC_INTCTRL (ARMV7M_NVIC_BASE + NVIC_INTCTRL_OFFSET) +#define NVIC_VECTAB (ARMV7M_NVIC_BASE + NVIC_VECTAB_OFFSET) +#define NVIC_AIRCR (ARMV7M_NVIC_BASE + NVIC_AIRCR_OFFSET) +#define NVIC_SYSCON (ARMV7M_NVIC_BASE + NVIC_SYSCON_OFFSET) +#define NVIC_CFGCON (ARMV7M_NVIC_BASE + NVIC_CFGCON_OFFSET) +#define NVIC_SYSH_PRIORITY(n) (ARMV7M_NVIC_BASE + NVIC_SYSH_PRIORITY_OFFSET(n)) +#define NVIC_SYSH4_7_PRIORITY (ARMV7M_NVIC_BASE + NVIC_SYSH4_7_PRIORITY_OFFSET) +#define NVIC_SYSH8_11_PRIORITY (ARMV7M_NVIC_BASE + NVIC_SYSH8_11_PRIORITY_OFFSET) +#define NVIC_SYSH12_15_PRIORITY (ARMV7M_NVIC_BASE + NVIC_SYSH12_15_PRIORITY_OFFSET) +#define NVIC_SYSHCON (ARMV7M_NVIC_BASE + NVIC_SYSHCON_OFFSET) +#define NVIC_CFAULTS (ARMV7M_NVIC_BASE + NVIC_CFAULTS_OFFSET) +#define NVIC_HFAULTS (ARMV7M_NVIC_BASE + NVIC_HFAULTS_OFFSET) +#define NVIC_DFAULTS (ARMV7M_NVIC_BASE + NVIC_DFAULTS_OFFSET) +#define NVIC_MEMMANAGE_ADDR (ARMV7M_NVIC_BASE + NVIC_MEMMANAGE_ADDR_OFFSET) +#define NVIC_BFAULT_ADDR (ARMV7M_NVIC_BASE + NVIC_BFAULT_ADDR_OFFSET) +#define NVIC_AFAULTS (ARMV7M_NVIC_BASE + NVIC_AFAULTS_OFFSET) +#define NVIC_PFR0 (ARMV7M_NVIC_BASE + NVIC_PFR0_OFFSET) +#define NVIC_PFR1 (ARMV7M_NVIC_BASE + NVIC_PFR1_OFFSET) +#define NVIC_DFR0 (ARMV7M_NVIC_BASE + NVIC_DFR0_OFFSET) +#define NVIC_AFR0 (ARMV7M_NVIC_BASE + NVIC_AFR0_OFFSET) +#define NVIC_MMFR0 (ARMV7M_NVIC_BASE + NVIC_MMFR0_OFFSET) +#define NVIC_MMFR1 (ARMV7M_NVIC_BASE + NVIC_MMFR1_OFFSET) +#define NVIC_MMFR2 (ARMV7M_NVIC_BASE + NVIC_MMFR2_OFFSET) +#define NVIC_MMFR3 (ARMV7M_NVIC_BASE + NVIC_MMFR3_OFFSET) +#define NVIC_ISAR0 (ARMV7M_NVIC_BASE + NVIC_ISAR0_OFFSET) +#define NVIC_ISAR1 (ARMV7M_NVIC_BASE + NVIC_ISAR1_OFFSET) +#define NVIC_ISAR2 (ARMV7M_NVIC_BASE + NVIC_ISAR2_OFFSET) +#define NVIC_ISAR3 (ARMV7M_NVIC_BASE + NVIC_ISAR3_OFFSET) +#define NVIC_ISAR4 (ARMV7M_NVIC_BASE + NVIC_ISAR4_OFFSET) +#define NVIC_CLIDR (ARMV7M_NVIC_BASE + NVIC_CLIDR_OFFSET) +#define NVIC_CTR (ARMV7M_NVIC_BASE + NVIC_CTR_OFFSET) +#define NVIC_CCSIDR (ARMV7M_NVIC_BASE + NVIC_CCSIDR_OFFSET) +#define NVIC_CSSELR (ARMV7M_NVIC_BASE + NVIC_CSSELR_OFFSET) +#define NVIC_CPACR (ARMV7M_NVIC_BASE + NVIC_CPACR_OFFSET) +#define NVIC_DHCSR (ARMV7M_NVIC_BASE + NVIC_DHCSR_OFFSET) +#define NVIC_DCRSR (ARMV7M_NVIC_BASE + NVIC_DCRSR_OFFSET) +#define NVIC_DCRDR (ARMV7M_NVIC_BASE + NVIC_DCRDR_OFFSET) +#define NVIC_DEMCR (ARMV7M_NVIC_BASE + NVIC_DEMCR_OFFSET) +#define NVIC_STIR (ARMV7M_NVIC_BASE + NVIC_STIR_OFFSET) +#define NVIC_FPCCR (ARMV7M_NVIC_BASE + NVIC_FPCCR_OFFSET) +#define NVIC_ICIALLU (ARMV7M_NVIC_BASE + NVIC_ICIALLU_OFFSET) +#define NVIC_ICIMVAU (ARMV7M_NVIC_BASE + NVIC_ICIMVAU_OFFSET) +#define NVIC_DCIMVAU (ARMV7M_NVIC_BASE + NVIC_DCIMVAU_OFFSET) +#define NVIC_DCISW (ARMV7M_NVIC_BASE + NVIC_DCISW_OFFSET) +#define NVIC_DCCMVAU (ARMV7M_NVIC_BASE + NVIC_DCCMVAU_OFFSET) +#define NVIC_DCCMVAC (ARMV7M_NVIC_BASE + NVIC_DCCMVAC_OFFSET) +#define NVIC_DCCSW (ARMV7M_NVIC_BASE + NVIC_DCCSW_OFFSET) +#define NVIC_DCCIMVAC (ARMV7M_NVIC_BASE + NVIC_DCCIMVAC_OFFSET) +#define NVIC_DCCISW (ARMV7M_NVIC_BASE + NVIC_DCCISW_OFFSET) +#define NVIC_ITCMCR (ARMV7M_NVIC_BASE + NVIC_ITCMCR_OFFSET) +#define NVIC_DTCMCR (ARMV7M_NVIC_BASE + NVIC_DTCMCR_OFFSET) +#define NVIC_AHBPCR (ARMV7M_NVIC_BASE + NVIC_AHBPCR_OFFSET) +#define NVIC_CACR (ARMV7M_NVIC_BASE + NVIC_CACR_OFFSET) +#define NVIC_AHBSCR (ARMV7M_NVIC_BASE + NVIC_AHBSCR_OFFSET) +#define NVIC_ABFSR (ARMV7M_NVIC_BASE + NVIC_ABFSR_OFFSET) +#define NVIC_PID4 (ARMV7M_NVIC_BASE + NVIC_PID4_OFFSET) +#define NVIC_PID5 (ARMV7M_NVIC_BASE + NVIC_PID5_OFFSET) +#define NVIC_PID6 (ARMV7M_NVIC_BASE + NVIC_PID6_OFFSET) +#define NVIC_PID7 (ARMV7M_NVIC_BASE + NVIC_PID7_OFFSET) +#define NVIC_PID0 (ARMV7M_NVIC_BASE + NVIC_PID0_OFFSET) +#define NVIC_PID1 (ARMV7M_NVIC_BASE + NVIC_PID1_OFFSET) +#define NVIC_PID2 (ARMV7M_NVIC_BASE + NVIC_PID2_OFFSET) +#define NVIC_PID3 (ARMV7M_NVIC_BASE + NVIC_PID3_OFFSET) +#define NVIC_CID0 (ARMV7M_NVIC_BASE + NVIC_CID0_OFFSET) +#define NVIC_CID1 (ARMV7M_NVIC_BASE + NVIC_CID1_OFFSET) +#define NVIC_CID2 (ARMV7M_NVIC_BASE + NVIC_CID2_OFFSET) +#define NVIC_CID3 (ARMV7M_NVIC_BASE + NVIC_CID3_OFFSET) + +/* NVIC register bit definitions ************************************************************/ + +/* Interrrupt controller type (INCTCTL_TYPE) */ + +#define NVIC_ICTR_INTLINESNUM_SHIFT 0 /* Bits 0-3: Number of interrupt inputs / 32 - 1 */ +#define NVIC_ICTR_INTLINESNUM_MASK (15 << NVIC_ICTR_INTLINESNUM_SHIFT) + +/* SysTick control and status register (SYSTICK_CTRL) */ + +#define NVIC_SYSTICK_CTRL_ENABLE (1 << 0) /* Bit 0: Enable */ +#define NVIC_SYSTICK_CTRL_TICKINT (1 << 1) /* Bit 1: Tick interrupt */ +#define NVIC_SYSTICK_CTRL_CLKSOURCE (1 << 2) /* Bit 2: Clock source */ +#define NVIC_SYSTICK_CTRL_COUNTFLAG (1 << 16) /* Bit 16: Count Flag */ + +/* SysTick reload value register (SYSTICK_RELOAD) */ + +#define NVIC_SYSTICK_RELOAD_SHIFT 0 /* Bits 23-0: Timer reload value */ +#define NVIC_SYSTICK_RELOAD_MASK (0x00ffffff << NVIC_SYSTICK_RELOAD_SHIFT) + +/* SysTick current value register (SYSTICK_CURRENT) */ + +#define NVIC_SYSTICK_CURRENT_SHIFT 0 /* Bits 23-0: Timer current value */ +#define NVIC_SYSTICK_CURRENT_MASK (0x00ffffff << NVIC_SYSTICK_RELOAD_SHIFT) + +/* SysTick calibration value register (SYSTICK_CALIB) */ + +#define NVIC_SYSTICK_CALIB_TENMS_SHIFT 0 /* Bits 23-0: Calibration value */ +#define NVIC_SYSTICK_CALIB_TENMS_MASK (0x00ffffff << NVIC_SYSTICK_CALIB_TENMS_SHIFT) +#define NVIC_SYSTICK_CALIB_SKEW (1 << 30) /* Bit 30: Calibration value inexact */ +#define NVIC_SYSTICK_CALIB_NOREF (1 << 31) /* Bit 31: No external reference clock */ + +/* Interrupt control state register (INTCTRL) */ + +#define NVIC_INTCTRL_NMIPENDSET (1 << 31) /* Bit 31: Set pending NMI bit */ +#define NVIC_INTCTRL_PENDSVSET (1 << 28) /* Bit 28: Set pending PendSV bit */ +#define NVIC_INTCTRL_PENDSVCLR (1 << 27) /* Bit 27: Clear pending PendSV bit */ +#define NVIC_INTCTRL_PENDSTSET (1 << 26) /* Bit 26: Set pending SysTick bit */ +#define NVIC_INTCTRL_PENDSTCLR (1 << 25) /* Bit 25: Clear pending SysTick bit */ +#define NVIC_INTCTRL_ISPREEMPOT (1 << 23) /* Bit 23: Pending active next cycle */ +#define NVIC_INTCTRL_ISRPENDING (1 << 22) /* Bit 22: Interrupt pending flag */ +#define NVIC_INTCTRL_VECTPENDING_SHIFT 12 /* Bits 21-12: Pending ISR number field */ +#define NVIC_INTCTRL_VECTPENDING_MASK (0x3ff << NVIC_INTCTRL_VECTPENDING_SHIFT) +#define NVIC_INTCTRL_RETTOBASE (1 << 11) /* Bit 11: no other exceptions pending */ +#define NVIC_INTCTRL_VECTACTIVE_SHIFT 0 /* Bits 8-0: Active ISR number */ +#define NVIC_INTCTRL_VECTACTIVE_MASK (0x1ff << NVIC_INTCTRL_VECTACTIVE_SHIFT) + +/* System control register (SYSCON) */ + /* Bit 0: Reserved */ +#define NVIC_SYSCON_SLEEPONEXIT (1 << 1) /* Bit 1: Sleep-on-exit (returning from Handler to Thread mode) */ +#define NVIC_SYSCON_SLEEPDEEP (1 << 2) /* Bit 2: Use deep sleep in low power mode */ + /* Bit 3: Reserved */ +#define NVIC_SYSCON_SEVONPEND (1 << 4) /* Bit 4: Send Event on Pending bit */ + /* Bits 5-31: Reserved */ + +/* Configuration control register (CFGCON) */ + +#define NVIC_CFGCON_NONBASETHRDENA (1 << 0) /* Bit 0: How processor enters thread mode */ +#define NVIC_CFGCON_USERSETMPEND (1 << 1) /* Bit 1: Enables unprivileged access to STIR */ +#define NVIC_CFGCON_UNALIGNTRP (1 << 3) /* Bit 3: Enables unaligned access traps */ +#define NVIC_CFGCON_DIV0TRP (1 << 4) /* Bit 4: Enables fault on divide-by-zero */ +#define NVIC_CFGCON_BFHFNMIGN (1 << 8) /* Bit 8: Disables data bus faults */ +#define NVIC_CFGCON_STKALIGN (1 << 9) /* Bit 9: Indicates stack alignment on exeption */ + /* Cortex-M7: */ +#define NVIC_CFGCON_DC (1 << 16) /* Bit 16: Data cache enable */ +#define NVIC_CFGCON_IC (1 << 17) /* Bit 17: Instruction cache enable */ +#define NVIC_CFGCON_BP (1 << 18) /* Bit 18: Branch prediction enable */ + +/* System handler 4-7 priority register */ + +#define NVIC_SYSH_PRIORITY_PR4_SHIFT 0 +#define NVIC_SYSH_PRIORITY_PR4_MASK (0xff << NVIC_SYSH_PRIORITY_PR4_SHIFT) +#define NVIC_SYSH_PRIORITY_PR5_SHIFT 8 +#define NVIC_SYSH_PRIORITY_PR5_MASK (0xff << NVIC_SYSH_PRIORITY_PR5_SHIFT) +#define NVIC_SYSH_PRIORITY_PR6_SHIFT 16 +#define NVIC_SYSH_PRIORITY_PR6_MASK (0xff << NVIC_SYSH_PRIORITY_PR6_SHIFT) +#define NVIC_SYSH_PRIORITY_PR7_SHIFT 24 +#define NVIC_SYSH_PRIORITY_PR7_MASK (0xff << NVIC_SYSH_PRIORITY_PR7_SHIFT) + +/* System handler 8-11 priority register */ + +#define NVIC_SYSH_PRIORITY_PR8_SHIFT 0 +#define NVIC_SYSH_PRIORITY_PR8_MASK (0xff << NVIC_SYSH_PRIORITY_PR8_SHIFT) +#define NVIC_SYSH_PRIORITY_PR9_SHIFT 8 +#define NVIC_SYSH_PRIORITY_PR9_MASK (0xff << NVIC_SYSH_PRIORITY_PR9_SHIFT) +#define NVIC_SYSH_PRIORITY_PR10_SHIFT 16 +#define NVIC_SYSH_PRIORITY_PR10_MASK (0xff << NVIC_SYSH_PRIORITY_PR10_SHIFT) +#define NVIC_SYSH_PRIORITY_PR11_SHIFT 24 +#define NVIC_SYSH_PRIORITY_PR11_MASK (0xff << NVIC_SYSH_PRIORITY_PR11_SHIFT) + +/* System handler 12-15 priority register */ + +#define NVIC_SYSH_PRIORITY_PR12_SHIFT 0 +#define NVIC_SYSH_PRIORITY_PR12_MASK (0xff << NVIC_SYSH_PRIORITY_PR12_SHIFT) +#define NVIC_SYSH_PRIORITY_PR13_SHIFT 8 +#define NVIC_SYSH_PRIORITY_PR13_MASK (0xff << NVIC_SYSH_PRIORITY_PR13_SHIFT) +#define NVIC_SYSH_PRIORITY_PR14_SHIFT 16 +#define NVIC_SYSH_PRIORITY_PR14_MASK (0xff << NVIC_SYSH_PRIORITY_PR14_SHIFT) +#define NVIC_SYSH_PRIORITY_PR15_SHIFT 24 +#define NVIC_SYSH_PRIORITY_PR15_MASK (0xff << NVIC_SYSH_PRIORITY_PR15_SHIFT) + +/* Vector Table Offset Register (VECTAB). This mask seems to vary among + * ARMv7-M implementations. It may need to be redefined in some + * architecture-specific header file. + */ + +#define NVIC_VECTAB_TBLOFF_MASK (0xffffff80) + +/* Application Interrupt and Reset Control Register (AIRCR) */ + +#define NVIC_AIRCR_VECTRESET (1 << 0) /* Bit 0: VECTRESET */ +#define NVIC_AIRCR_VECTCLRACTIVE (1 << 1) /* Bit 1: Reserved for debug use */ +#define NVIC_AIRCR_SYSRESETREQ (1 << 2) /* Bit 2: System reset */ + /* Bits 2-7: Reserved */ +#define NVIC_AIRCR_PRIGROUP_SHIFT (8) /* Bits 8-14: PRIGROUP */ +#define NVIC_AIRCR_PRIGROUP_MASK (7 << NVIC_AIRCR_PRIGROUP_SHIFT) +#define NVIC_AIRCR_ENDIANNESS (1 << 15) /* Bit 15: 1=Big endian */ +#define NVIC_AIRCR_VECTKEY_SHIFT (16) /* Bits 16-31: VECTKEY */ +#define NVIC_AIRCR_VECTKEY_MASK (0xffff << NVIC_AIRCR_VECTKEY_SHIFT) +#define NVIC_AIRCR_VECTKEYSTAT_SHIFT (16) /* Bits 16-31: VECTKEYSTAT */ +#define NVIC_AIRCR_VECTKEYSTAT_MASK (0xffff << NVIC_AIRCR_VECTKEYSTAT_SHIFT) + +/* System handler control and state register (SYSHCON) */ + +#define NVIC_SYSHCON_MEMFAULTACT (1 << 0) /* Bit 0: MemManage is active */ +#define NVIC_SYSHCON_BUSFAULTACT (1 << 1) /* Bit 1: BusFault is active */ +#define NVIC_SYSHCON_USGFAULTACT (1 << 3) /* Bit 3: UsageFault is active */ +#define NVIC_SYSHCON_SVCALLACT (1 << 7) /* Bit 7: SVCall is active */ +#define NVIC_SYSHCON_MONITORACT (1 << 8) /* Bit 8: Monitor is active */ +#define NVIC_SYSHCON_PENDSVACT (1 << 10) /* Bit 10: PendSV is active */ +#define NVIC_SYSHCON_SYSTICKACT (1 << 11) /* Bit 11: SysTick is active */ +#define NVIC_SYSHCON_USGFAULTPENDED (1 << 12) /* Bit 12: Usage fault is pended */ +#define NVIC_SYSHCON_MEMFAULTPENDED (1 << 13) /* Bit 13: MemManage is pended */ +#define NVIC_SYSHCON_BUSFAULTPENDED (1 << 14) /* Bit 14: BusFault is pended */ +#define NVIC_SYSHCON_SVCALLPENDED (1 << 15) /* Bit 15: SVCall is pended */ +#define NVIC_SYSHCON_MEMFAULTENA (1 << 16) /* Bit 16: MemFault enabled */ +#define NVIC_SYSHCON_BUSFAULTENA (1 << 17) /* Bit 17: BusFault enabled */ +#define NVIC_SYSHCON_USGFAULTENA (1 << 18) /* Bit 18: UsageFault enabled */ + +/* Cache Level ID register (Cortex-M7) */ + +#define NVIC_CLIDR_L1CT_SHIFT (0) /* Bits 0-2: Level 1 cache type */ +#define NVIC_CLIDR_L1CT_MASK (7 << NVIC_CLIDR_L1CT_SHIFT) +# define NVIC_CLIDR_L1CT_ICACHE (1 << NVIC_CLIDR_LOC_SHIFT) +# define NVIC_CLIDR_L1CT_DCACHE (2 << NVIC_CLIDR_LOC_SHIFT) +#define NVIC_CLIDR_LOC_SHIFT (24) /* Bits 24-26: Level of Coherency */ +#define NVIC_CLIDR_LOC_MASK (7 << NVIC_CLIDR_LOC_SHIFT) +# define NVIC_CLIDR_LOC_IMPLEMENTED (1 << NVIC_CLIDR_LOC_SHIFT) +# define NVIC_CLIDR_LOC_UNIMPLEMENTED (0 << NVIC_CLIDR_LOC_SHIFT) +#define NVIC_CLIDR_LOUU_SHIFT (27) /* Bits 27-29: Level of Unification Uniprocessor */ +#define NVIC_CLIDR_LOUU_MASK (7 << NVIC_CLIDR_LOUU_SHIFT) +# define NVIC_CLIDR_LOUU_IMPLEMENTED (1 << NVIC_CLIDR_LOUU_SHIFT) +# define NVIC_CLIDR_LOUU_UNIMPLEMENTED (0 << NVIC_CLIDR_LOUU_SHIFT) + +/* Cache Type register (Cortex-M7) */ + +#define NVIC_CTR_IMINLINE_SHIFT (0) /* Bits 0-3: ImInLine */ +#define NVIC_CTR_IMINLINE_MASK (15 << NVIC_CTR_IMINLINE_SHIFT) +#define NVIC_CTR_DMINLINE_SHIFT (16) /* Bits 16-19: DmInLine */ +#define NVIC_CTR_DMINLINE_MASK (15 << NVIC_CTR_DMINLINE_SHIFT) +#define NVIC_CTR_ERG_SHIFT (20) /* Bits 20-23: ERG */ +#define NVIC_CTR_ERG_MASK (15 << NVIC_CTR_ERG_SHIFT) +#define NVIC_CTR_CWG_SHIFT (24) /* Bits 24-27: ERG */ +#define NVIC_CTR_CWG_MASK (15 << NVIC_CTR_CWG_SHIFT) +#define NVIC_CTR_FORMAT_SHIFT (29) /* Bits 29-31: Format */ +#define NVIC_CTR_FORMAT_MASK (7 << NVIC_CTR_FORMAT_SHIFT) + +/* Cache Size ID Register (Cortex-M7) */ + +#define NVIC_CCSIDR_LINESIZE_SHIFT (0) /* Bits 0-2: Number of words in each cache line */ +#define NVIC_CCSIDR_LINESIZE_MASK (7 << NVIC_CCSIDR_LINESIZE_SHIFT) +#define NVIC_CCSIDR_ASSOCIATIVITY_SHIFT (3) /* Bits 3-12: Number of ways - 1 */ +#define NVIC_CCSIDR_ASSOCIATIVITY_MASK (0x3ff << NVIC_CCSIDR_ASSOCIATIVITY_SHIFT) +#define NVIC_CCSIDR_NUMSETS_SHIFT (13) /* Bits 13-27: Number of sets - 1 */ +#define NVIC_CCSIDR_NUMSETS_MASK (0x7fff << NVIC_CCSIDR_NUMSETS_SHIFT) +#define NVIC_CCSIDR_WA_SHIFT (1 << 28) /* Bits 28: Write Allocation support */ +#define NVIC_CCSIDR_RA_SHIFT (1 << 29) /* Bits 29: Read Allocation support */ +#define NVIC_CCSIDR_WB_SHIFT (1 << 30) /* Bits 30: Write-Back support */ +#define NVIC_CCSIDR_WT_SHIFT (1 << 31) /* Bits 31: Write-Through support */ + +/* Cache Size Selection Register (Cortex-M7) */ + +#define NVIC_CSSELR_IND (1 << 0) /* Bit 0: Selects either instruction or data cache */ +# define NVIC_CSSELR_IND_ICACHE (0 << 0) /* 0=Instruction Cache */ +# define NVIC_CSSELR_IND_DCACHE (1 << 0) /* 1=Data Cache */ + +#define NVIC_CSSELR_LEVEL_SHIFT (1) /* Bit 1-3: Selects cache level */ +#define NVIC_CSSELR_LEVEL_MASK (7 << NVIC_CSSELR_LEVEL_SHIFT) + #define NVIC_CSSELR_LEVEL_1 (0 << NVIC_CSSELR_LEVEL_SHIFT) + +/* Debug Exception and Monitor Control Register (DEMCR) */ + +#define NVIC_DEMCR_VCCORERESET (1 << 0) /* Bit 0: Reset Vector Catch */ +#define NVIC_DEMCR_VCMMERR (1 << 4) /* Bit 4: Debug trap on Memory Management faults */ +#define NVIC_DEMCR_VCNOCPERR (1 << 5) /* Bit 5: Debug trap on Usage Fault access to non-present coprocessor */ +#define NVIC_DEMCR_VCCHKERR (1 << 6) /* Bit 6: Debug trap on Usage Fault enabled checking errors */ +#define NVIC_DEMCR_VCSTATERR (1 << 7) /* Bit 7: Debug trap on Usage Fault state error */ +#define NVIC_DEMCR_VCBUSERR (1 << 8) /* Bit 8: Debug Trap on normal Bus error */ +#define NVIC_DEMCR_VCINTERR (1 << 9) /* Bit 9: Debug Trap on interrupt/exception service errors */ +#define NVIC_DEMCR_VCHARDERR (1 << 10) /* Bit 10: Debug trap on Hard Fault */ +#define NVIC_DEMCR_MONEN (1 << 16) /* Bit 16: Enable the debug monitor */ +#define NVIC_DEMCR_MONPEND (1 << 17) /* Bit 17: Pend the monitor to activate when priority permits */ +#define NVIC_DEMCR_MONSTEP (1 << 18) /* Bit 18: Steps the core */ +#define NVIC_DEMCR_MONREQ (1 << 19) /* Bit 19: Monitor wake-up mode */ +#define NVIC_DEMCR_TRCENA (1 << 24) /* Bit 24: Enable trace and debug blocks */ + +/* Instruction Tightly-Coupled Memory Control Register (ITCMCR) */ +/* Data Tightly-Coupled Memory Control Registers (DTCMCR */ + +#define NVIC_TCMCR_EN (1 << 0) /* Bit 9: TCM enable */ +#define NVIC_TCMCR_RMW (1 << 1) /* Bit 1: Read-Modify-Write (RMW) enable */ +#define NVIC_TCMCR_RETEN (1 << 2) /* Bit 2: Retry phase enable */ +#define NVIC_TCMCR_SZ_SHIFT (3) /* Bits 3-6: Size of the TCM */ +#define NVIC_TCMCR_SZ_MASK (15 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_NONE (0 << NVIC_TCMCR_SZ_SHIFT) /* No TCM implemented */ +# define NVIC_TCMCR_SZ_4KB (3 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_8KB (4 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_16KB (5 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_32KB (6 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_64KB (7 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_128KB (8 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_256KB (9 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_512KB (10 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_1MB (11 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_2MB (12 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_4MB (13 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_8MB (14 << NVIC_TCMCR_SZ_SHIFT) +# define NVIC_TCMCR_SZ_16MB (15 << NVIC_TCMCR_SZ_SHIFT) + +/* AHBP Control Register (AHBPCR, Cortex-M7) */ + +#define NVIC_AHBPCR_EN (1 << 0) /* Bit 0: AHBP enable */ +#define NVIC_AHBPCR_SZ_SHIFT (1) /* Bits 1-3: AHBP size */ +#define NVIC_AHBPCR_SZ_MASK (7 << NVIC_AHBPCR_SZ_SHIFT) +# define NVIC_AHBPCR_SZ_DISABLED (0 << NVIC_AHBPCR_SZ_SHIFT) +# define NVIC_AHBPCR_SZ_64MB (1 << NVIC_AHBPCR_SZ_SHIFT) +# define NVIC_AHBPCR_SZ_128MB (2 << NVIC_AHBPCR_SZ_SHIFT) +# define NVIC_AHBPCR_SZ_256MB (3 << NVIC_AHBPCR_SZ_SHIFT) +# define NVIC_AHBPCR_SZ_512MB (4 << NVIC_AHBPCR_SZ_SHIFT) + +/* L1 Cache Control Register (CACR, Cortex-M7) */ + +#define NVIC_CACR_SIWT (1 << 0) /* Bit 0: Shared cacheable-is-WT for data cache */ +#define NVIC_CACR_ECCDIS (1 << 1) /* Bit 1: Enables ECC in the instruction and data cache */ +#define NVIC_CACR_FORCEWT (1 << 2) /* Bit 2: Enables Force Write-Through in the data cache */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_COMMON_ARMV7_M_NVIC_H */ diff --git a/arch/arm/src/armv7-m/psr.h b/arch/arm/src/armv7-m/psr.h new file mode 100644 index 0000000000000000000000000000000000000000..b8b33c80f6e5170f51ca5b147459148990ea55c4 --- /dev/null +++ b/arch/arm/src/armv7-m/psr.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/psr.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARMV7_M_PSR_H +#define __ARCH_ARM_SRC_COMMON_ARMV7_M_PSR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Application Program Status Register (APSR) */ + +#define ARMV7M_APSR_Q (1 << 27) /* Bit 27: Sticky saturation flag */ +#define ARMV7M_APSR_V (1 << 28) /* Bit 28: Overflow flag */ +#define ARMV7M_APSR_C (1 << 29) /* Bit 29: Carry/borrow flag */ +#define ARMV7M_APSR_Z (1 << 30) /* Bit 30: Zero flag */ +#define ARMV7M_APSR_N (1 << 31) /* Bit 31: Negative, less than flag */ + +/* Interrupt Program Status Register (IPSR) */ + +#define ARMV7M_IPSR_ISR_SHIFT 0 /* Bits 8-0: ISR number */ +#define ARMV7M_IPSR_ISR_MASK (0x1ff << ARMV7M_IPSR_ISR_SHIFT) + +/* Execution PSR Register (EPSR) */ + +#define ARMV7M_EPSR_ICIIT1_SHIFT 10 /* Bits 15-10: Interrupt-Continuable-Instruction/If-Then bits */ +#define ARMV7M_EPSR_ICIIT1_MASK (3 << ARMV7M_EPSR_ICIIT1_SHIFT) +#define ARMV7M_EPSR_T (1 << 24) /* Bit 24: T-bit */ +#define ARMV7M_EPSR_ICIIT2_SHIFT 25 /* Bits 26-25: Interrupt-Continuable-Instruction/If-Then bits */ +#define ARMV7M_EPSR_ICIIT2_MASK (3 << ARMV7M_EPSR_ICIIT2_SHIFT) + +/* Save xPSR bits */ + +#define ARMV7M_XPSR_ISR_SHIFT ARMV7M_IPSR_ISR_SHIFT +#define ARMV7M_XPSR_ISR_MASK ARMV7M_IPSR_ISR_MASK +#define ARMV7M_XPSR_ICIIT1_SHIFT ARMV7M_EPSR_ICIIT1_SHIFT/ +#define ARMV7M_XPSR_ICIIT1_MASK ARMV7M_EPSR_ICIIT1_MASK +#define ARMV7M_XPSR_T ARMV7M_EPSR_T +#define ARMV7M_XPSR_ICIIT2_SHIFT ARMV7M_EPSR_ICIIT2_SHIFT +#define ARMV7M_XPSR_ICIIT2_MASK ARMV7M_EPSR_ICIIT2_MASK +#define ARMV7M_XPSR_Q ARMV7M_APSR_Q +#define ARMV7M_XPSR_V ARMV7M_APSR_V +#define ARMV7M_XPSR_C ARMV7M_APSR_C +#define ARMV7M_XPSR_Z ARMV7M_APSR_Z +#define ARMV7M_XPSR_N ARMV7M_APSR_N + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_COMMON_ARMV7_M_PSR_H */ diff --git a/arch/arm/src/armv7-m/ram_vectors.h b/arch/arm/src/armv7-m/ram_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..0306655f8dc9ede553a1698ce721c47b790f8343 --- /dev/null +++ b/arch/arm/src/armv7-m/ram_vectors.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/ram_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_ARMV7_M_RAM_VECTORS_H +#define __ARCH_ARM_SRC_COMMON_ARMV7_M_RAM_VECTORS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_ARCH_RAMVECTORS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the size of the vector table (in 4-byte entries). This size + * includes the (1) the peripheral interrupts, (2) space for 15 Cortex-M + * exceptions, and (3) IDLE stack pointer which lies at the beginning of the + * table. + */ + +#define ARMV7M_VECTAB_SIZE (NR_VECTORS + 16) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide + * ARM-specific implementations of irq_initialize(), irq_attach(), and + * irq_dispatch. In this case, it is also assumed that the ARM vector + * table resides in RAM, has the name up_ram_vectors, and has been + * properly positioned and aligned in memory by the linker script. + * + * REVISIT: Can this alignment requirement vary from core-to-core? Yes, it + * depends on the number of vectors supported by the MCU. The safest thing + * to do is to put the vector table at the beginning of RAM in order toforce + * the highest alignment possible. + */ + +extern up_vector_t g_ram_vectors[ARMV7M_VECTAB_SIZE] + __attribute__ ((section (".ram_vectors"), aligned (128))); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ramvec_initialize + * + * Description: + * Copy vectors to RAM an configure the NVIC to use the RAM vectors. + * + ****************************************************************************/ + +void up_ramvec_initialize(void); + +/**************************************************************************** + * Name: exception_common + * + * Description: + * This is the default, common vector handling entrypoint. + * + ****************************************************************************/ + +void exception_common(void); + +/**************************************************************************** + * Name: up_ramvec_attach + * + * Description: + * Configure the ram vector table so that IRQ number 'irq' will be + * dipatched by hardware to 'vector' + * + ****************************************************************************/ + +int up_ramvec_attach(int irq, up_vector_t vector); + +#endif /* CONFIG_ARCH_RAMVECTORS */ +#endif /* __ARCH_ARM_SRC_COMMON_ARMV7_M_RAM_VECTORS_H */ diff --git a/arch/arm/src/armv7-m/svcall.h b/arch/arm/src/armv7-m/svcall.h new file mode 100644 index 0000000000000000000000000000000000000000..cc2b2716b2e13f1b443d5dfd001da40670c562a3 --- /dev/null +++ b/arch/arm/src/armv7-m/svcall.h @@ -0,0 +1,145 @@ +/************************************************************************************ + * arch/arm/src/armv7-m/svcall.h + * + * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_SVCALL_H +#define __ARCH_ARM_SRC_ARMV7_M_SVCALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ +/* This logic uses three system calls {0,1,2} for context switching and one for the + * syscall return. So a minimum of four syscall values must be reserved. If + * CONFIG_BUILD_PROTECTED is defined, then four more syscall values must be reserved. + */ + +#ifdef CONFIG_LIB_SYSCALL +# ifdef CONFIG_BUILD_PROTECTED +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 8" +# elif CONFIG_SYS_RESERVED != 8 +# error "CONFIG_SYS_RESERVED must have the value 8" +# endif +# else +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 4" +# elif CONFIG_SYS_RESERVED != 4 +# error "CONFIG_SYS_RESERVED must have the value 4" +# endif +# endif +#endif + +/* Cortex-M system calls ************************************************************/ + +/* SYS call 0: + * + * int up_saveusercontext(uint32_t *saveregs); + */ + +#define SYS_save_context (0) + +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) + +/* SYS call 2: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) + +#ifdef CONFIG_LIB_SYSCALL +/* SYS call 3: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (3) + +#ifdef CONFIG_BUILD_PROTECTED +/* SYS call 4: + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) + * noreturn_function; + */ + +#define SYS_task_start (4) + +/* SYS call 5: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +/* SYS call 6: + * + * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, + * FAR void *ucontext); + */ + +#define SYS_signal_handler (6) + +/* SYS call 7: + * + * void signal_handler_return(void); + */ + +#define SYS_signal_handler_return (7) + +#endif /* CONFIG_BUILD_PROTECTED */ +#endif /* CONFIG_LIB_SYSCALL */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_SVCALL_H */ diff --git a/arch/arm/src/armv7-m/tpi.h b/arch/arm/src/armv7-m/tpi.h new file mode 100644 index 0000000000000000000000000000000000000000..3993667f9ea16d962bf925c29ee8f5235f83d171 --- /dev/null +++ b/arch/arm/src/armv7-m/tpi.h @@ -0,0 +1,176 @@ +/*********************************************************************************************** + * arch/arm/src/armv7-m/tpi.h + * + * 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. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_M_TPI_H +#define __ARCH_ARM_SRC_ARMV7_M_TPI_H + +/*********************************************************************************************** + * Pre-processor Definitions + ***********************************************************************************************/ + +/* Trace Port Interface Register (TPI) Definitions *********************************************/ +/* TPI Register Base Address *******************************************************************/ + +#define TPI_BASE (0xe0040000ul) + +/* TPI Register Addresses **********************************************************************/ + +#define TPI_SSPSR (TPI_BASE+0x0000) /* Supported Parallel Port Size Register */ +#define TPI_CSPSR (TPI_BASE+0x0004) /* Current Parallel Port Size Register */ +#define TPI_ACPR (TPI_BASE+0x0010) /* Asynchronous Clock Prescaler Register */ +#define TPI_SPPR (TPI_BASE+0x00f0) /* Selected Pin Protocol Register */ +#define TPI_FFSR (TPI_BASE+0x0300) /* Formatter and Flush Status Register */ +#define TPI_FFCR (TPI_BASE+0x0304) /* Formatter and Flush Control Register */ +#define TPI_FSCR (TPI_BASE+0x0308) /* Formatter Synchronization Counter Register */ +#define TPI_TRIGGER (TPI_BASE+0x0ee8) /* TRIGGER */ +#define TPI_FIFO0 (TPI_BASE+0x0eec) /* Integration ETM Data */ +#define TPI_ITATBCTR2 (TPI_BASE+0x0ef0) /* ITATBCTR2 */ +#define TPI_ITATBCTR0 (TPI_BASE+0x0ef8) /* ITATBCTR0 */ +#define TPI_FIFO1 (TPI_BASE+0x0efc) /* Integration ITM Data */ +#define TPI_ITCTRL (TPI_BASE+0x0f00) /* Integration Mode Control */ +#define TPI_CLAIMSET (TPI_BASE+0x0fa0) /* Claim tag set */ +#define TPI_CLAIMCLR (TPI_BASE+0x0fa4) /* Claim tag clear */ +#define TPI_DEVID (TPI_BASE+0x0fc8) /* TPIU_DEVID */ +#define TPI_DEVTYPE (TPI_BASE+0x0fcc) /* TPIU_DEVTYPE */ + +/* TPI Register Bit Field 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 */ + +#define TPI_SPPR_TXMODE_Pos 0 /* TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3ul << TPI_SPPR_TXMODE_Pos) /* TPI SPPR: TXMODE Mask */ + +#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 */ + +#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 */ + +#define TPI_TRIGGER_TRIGGER_Pos 0 /* TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1ul << TPI_TRIGGER_TRIGGER_Pos) /* TPI TRIGGER: TRIGGER Mask */ + +#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 */ + +#define TPI_ITATBCTR2_ATREADY_Pos 0 /* TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1ul << TPI_ITATBCTR2_ATREADY_Pos) /* TPI ITATBCTR2: ATREADY Mask */ + +#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 */ + +#define TPI_ITATBCTR0_ATREADY_Pos 0 /* TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1ul << TPI_ITATBCTR0_ATREADY_Pos) /* TPI ITATBCTR0: ATREADY Mask */ + +#define TPI_ITCTRL_Mode_Pos 0 /* TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1ul << TPI_ITCTRL_Mode_Pos) /* TPI ITCTRL: Mode Mask */ + +#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 */ + +#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 */ + +#endif /* __ARCH_ARM_SRC_ARMV7_M_TPI_H */ diff --git a/arch/arm/src/armv7-m/up_assert.c b/arch/arm/src/armv7-m/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..0f6fa00d219488401220dc6d35a5d469786f66d8 --- /dev/null +++ b/arch/arm/src/armv7-m/up_assert.c @@ -0,0 +1,427 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_assert.c + * + * Copyright (C) 2009-2010, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump(sp,stack_base) +#endif + +/**************************************************************************** + * Name: up_taskdump + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg) +{ + /* Dump interesting properties of this task */ + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("%s: PID=%d Stack Used=%lu of %lu\n", + tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#else + lldbg("PID: %d Stack Used=%lu of %lu\n", + tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#endif +} +#endif + +/**************************************************************************** + * Name: up_showtasks + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static inline void up_showtasks(void) +{ + /* Dump interesting properties of each task in the crash environment */ + + sched_foreach(up_taskdump, NULL); +} +#else +# define up_showtasks() +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (CURRENT_REGS) + { + /* Yes.. dump the interrupt registers */ + + lldbg("R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R0], CURRENT_REGS[REG_R1], + CURRENT_REGS[REG_R2], CURRENT_REGS[REG_R3], + CURRENT_REGS[REG_R4], CURRENT_REGS[REG_R5], + CURRENT_REGS[REG_R6], CURRENT_REGS[REG_R7]); + lldbg("R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R8], CURRENT_REGS[REG_R9], + CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11], + CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13], + CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]); + +#ifdef CONFIG_ARMV7M_USEBASEPRI + lldbg("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_BASEPRI], + getcontrol()); +#else + lldbg("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK], + getcontrol()); +#endif + +#ifdef REG_EXC_RETURN + lldbg("EXC_RETURN: %08x\n", CURRENT_REGS[REG_EXC_RETURN]); +#endif + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Get the limits on the interrupt stack memory */ + + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + } + + /* Extract the user stack pointer if we are in an interrupt handler. + * If we are not in an interrupt handler. Then sp is the user stack + * pointer (and the above range check should have failed). + */ + + if (CURRENT_REGS) + { + sp = CURRENT_REGS[REG_R13]; + lldbg("sp: %08x\n", sp); + } + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp <= ustackbase && sp > ustackbase - ustacksize) + { + up_stackdump(sp, ustackbase); + } + +#else + + /* Show user stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg("stack used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { + lldbg("ERROR: Stack pointer is not within the allocated stack\n"); + } + else + { + up_stackdump(sp, ustackbase); + } + +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); + + /* Dump the state of all tasks (if available) */ + + up_showtasks(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (CURRENT_REGS || (this_task())->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/arm/src/armv7-m/up_blocktask.c b/arch/arm/src/armv7-m/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..5e62e0fb9fc3c4d9e021e4087560d84ad1efbed1 --- /dev/null +++ b/arch/arm/src/armv7-m/up_blocktask.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_blocktask.c + * + * Copyright (C) 2007-2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv7-m/up_coherent_dcache.c b/arch/arm/src/armv7-m/up_coherent_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..019205f46bc8f74e50e92a124a4a067a41a0a560 --- /dev/null +++ b/arch/arm/src/armv7-m/up_coherent_dcache.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_coherent_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "cache.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * addr - virtual start address of region + * len - Size of the address region in bytes + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_coherent_dcache(uintptr_t addr, size_t len) +{ + uintptr_t end; + + if (len > 0) + { + /* Flush any dirtcy D-Cache lines to memory */ + + end = addr + len; + arch_clean_dcache(addr, end); + UNUSED(end); + + /* Invalidate the entire I-Cache */ + + arch_invalidate_icache_all(); + } +} diff --git a/arch/arm/src/armv7-m/up_copyarmstate.c b/arch/arm/src/armv7-m/up_copyarmstate.c new file mode 100644 index 0000000000000000000000000000000000000000..13fec55422aa731c510d0c807e52d77c1098e4db --- /dev/null +++ b/arch/arm/src/armv7-m/up_copyarmstate.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_copyarmstate.c + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" + +#if defined(CONFIG_ARCH_FPU) && \ + (!defined(CONFIG_ARMV7M_CMNVECTOR) || defined(CONFIG_ARMV7M_LAZYFPU)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyarmstate + * + * Description: + * Copy the ARM portion of the register save area (omitting the floating + * point registers) and save the floating pointer register directly. + * + ****************************************************************************/ + +void up_copyarmstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the Cortex-M3 model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + /* Save the floating point registers: This will initialize the floating + * registers at indices SW_INT_REGS through (SW_INT_REGS+SW_FPU_REGS-1) + */ + + up_savefpu(dest); + + /* Save the block of ARM registers that were saved by the interrupt + * handling logic. Indices: 0 through (SW_INT_REGS-1). + */ + + for (i = 0; i < SW_INT_REGS; i++) + { + *dest++ = *src++; + } + + /* Skip over the floating point registers and save the block of ARM + * registers that were saved by the hardware when the interrupt was + * taken. Indices: (SW_INT_REGS+SW_FPU_REGS) through + * (XCPTCONTEXT_REGS-1) + */ + + src += SW_FPU_REGS; + dest += SW_FPU_REGS; + + for (i = 0; i < HW_XCPT_REGS; i++) + { + *dest++ = *src++; + } + } +} + +#endif /* CONFIG_ARCH_FPU && (!CONFIG_ARMV7M_CMNVECTOR || CONFIG_ARMV7M_LAZYFPU) */ diff --git a/arch/arm/src/armv7-m/up_copyfullstate.c b/arch/arm/src/armv7-m/up_copyfullstate.c new file mode 100644 index 0000000000000000000000000000000000000000..e3618d486238c6ac0c14b2a79bce17c6506ab855 --- /dev/null +++ b/arch/arm/src/armv7-m/up_copyfullstate.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_copyfullstate.c + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyfullstate + * + * Description: + * Copy the entire register save area (including the floating point + * registers if applicable). This is a little faster than most memcpy's + * since it does 32-bit transfers. + * + ****************************************************************************/ + +void up_copyfullstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the Cortex-M3 model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} diff --git a/arch/arm/src/armv7-m/up_doirq.c b/arch/arm/src/armv7-m/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..b51c10e55823bf3ca9861292e97258244519c3cd --- /dev/null +++ b/arch/arm/src/armv7-m/up_doirq.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_doirq.c + * + * Copyright (C) 2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + uint32_t *savestate; + + /* Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to (1) change the way that + * CURRENT_REGS is handled and (2) the design associated with + * CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* If a context switch occurred while processing the interrupt then + * CURRENT_REGS may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)CURRENT_REGS; + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; +#endif + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/arm/src/armv7-m/up_elf.c b/arch/arm/src/armv7-m/up_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..bf492f1acaa5ac25ac8a7c1a0aec6fd73f49866f --- /dev/null +++ b/arch/arm/src/armv7-m/up_elf.c @@ -0,0 +1,486 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_elf.c + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_UCLIBCXX_EXCEPTION +extern void init_unwind_exidx(Elf32_Addr start, Elf32_Addr end); +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *ehdr) +{ + /* Make sure it's an ARM executable */ + + if (ehdr->e_machine != EM_ARM) + { + bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine); + return -ENOEXEC; + } + + /* Make sure that 32-bit objects are supported */ + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + { + bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]); + return -ENOEXEC; + } + + /* Verify endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG + if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) +#else + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) +#endif + { + bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]); + return -ENOEXEC; + } + + /* TODO: Check ABI here. */ + return OK; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + int32_t offset; + uint32_t upper_insn; + uint32_t lower_insn; + unsigned int relotype; + + /* All relocations except R_ARM_V4BX depend upon having valid symbol + * information. + */ + + relotype = ELF32_R_TYPE(rel->r_info); + if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (relotype) + { + case R_ARM_NONE: + { + /* No relocation */ + } + break; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + { + bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = (*(uint32_t *)addr & 0x00ffffff) << 2; + if (offset & 0x02000000) + { + offset -= 0x04000000; + } + + offset += sym->st_value - addr; + if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000) + { + bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + offset >>= 2; + + *(uint32_t *)addr &= 0xff000000; + *(uint32_t *)addr |= offset & 0x00ffffff; + } + break; + + case R_ARM_ABS32: + case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ + { + bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value; + } + break; + +#ifdef CONFIG_ARMV7M_TARGET2_PREL + case R_ARM_TARGET2: /* TARGET2 is a platform-specific relocation: gcc-arm-none-eabi + * performs a self relocation */ + { + bvdbg("Performing TARGET2 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value - addr; + } + break; +#endif + + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + { + uint32_t S; + uint32_t J1; + uint32_t J2; + + /* Thumb BL and B.W instructions. Encoding: + * + * upper_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +----------+---+-------------------------------+--------------+ + * |1 1 1 |OP1| OP2 | | 32-Bit Instructions + * +----------+---+--+-----+----------------------+--------------+ + * |1 1 1 | 1 0| S | imm10 | BL Instruction + * +----------+------+-----+-------------------------------------+ + * + * lower_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +---+---------------------------------------------------------+ + * |OP | | 32-Bit Instructions + * +---+--+---+---+---+------------------------------------------+ + * |1 1 |J1 | 1 |J2 | imm11 | BL Instruction + * +------+---+---+---+------------------------------------------+ + * + * The branch target is encoded in these bits: + * + * S = upper_insn[10] + * imm10 = upper_insn[0:9] + * imm11 = lower_insn[0:10] + * J1 = lower_insn[13] + * J2 = lower_insn[11] + */ + + upper_insn = (uint32_t)(*(uint16_t *)addr); + lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); + + bvdbg("Performing THM_JUMP24 [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, + sym, (long)sym->st_value); + + /* Extract the 25-bit offset from the 32-bit instruction: + * + * offset[24] = S + * offset[23] = ~(J1 ^ S) + * offset[22] = ~(J2 ^ S)] + * offset[12:21] = imm10 + * offset[1:11] = imm11 + * offset[0] = 0 + */ + + S = (upper_insn >> 10) & 1; + J1 = (lower_insn >> 13) & 1; + J2 = (lower_insn >> 11) & 1; + + offset = (S << 24) | /* S - > offset[24] */ + ((~(J1 ^ S) & 1) << 23) | /* J1 -> offset[23] */ + ((~(J2 ^ S) & 1) << 22) | /* J2 -> offset[22] */ + ((upper_insn & 0x03ff) << 12) | /* imm10 -> offset[12:21] */ + ((lower_insn & 0x07ff) << 1); /* imm11 -> offset[1:11] */ + /* 0 -> offset[0] */ + + /* Sign extend */ + + if (offset & 0x01000000) + { + offset -= 0x02000000; + } + + /* And perform the relocation */ + + bvdbg(" S=%d J1=%d J2=%d offset=%08lx branch target=%08lx\n", + S, J1, J2, (long)offset, offset + sym->st_value - addr); + + offset += sym->st_value - addr; + + /* Is this a function symbol? If so, then the branch target must be + * an odd Thumb address + */ + + if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && (offset & 1) == 0) + { + bdbg(" ERROR: JUMP24 [%d] requires odd offset, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + /* Check the range of the offset */ + + if (offset <= (int32_t)0xff000000 || offset >= (int32_t)0x01000000) + { + bdbg(" ERROR: JUMP24 [%d] relocation out of range, branch taget=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + /* Now, reconstruct the 32-bit instruction using the new, relocated + * branch target. + */ + + S = (offset >> 24) & 1; + J1 = S ^ (~(offset >> 23) & 1); + J2 = S ^ (~(offset >> 22) & 1); + + upper_insn = ((upper_insn & 0xf800) | (S << 10) | ((offset >> 12) & 0x03ff)); + *(uint16_t *)addr = (uint16_t)upper_insn; + + lower_insn = ((lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | ((offset >> 1) & 0x07ff)); + *(uint16_t *)(addr + 2) = (uint16_t)lower_insn; + + bvdbg(" S=%d J1=%d J2=%d insn [%04x %04x]\n", + S, J1, J2, (int)upper_insn, (int)lower_insn); + } + break; + + case R_ARM_V4BX: + { + bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n", + (long)addr, (long)(*(uint32_t *)addr)); + + /* Preserve only Rm and the condition code */ + + *(uint32_t *)addr &= 0xf000000f; + + /* Change instruction to 'mov pc, Rm' */ + + *(uint32_t *)addr |= 0x01a0f000; + } + break; + + case R_ARM_PREL31: + { + bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + offset = *(uint32_t *)addr + sym->st_value - addr; + *(uint32_t *)addr = offset & 0x7fffffff; + } + break; + + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = *(uint32_t *)addr; + offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); + offset = (offset ^ 0x8000) - 0x8000; + + offset += sym->st_value; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + { + offset >>= 16; + } + + *(uint32_t *)addr &= 0xfff0f000; + *(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff); + } + break; + + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + { + /* Thumb BL and B.W instructions. Encoding: + * + * upper_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +----------+---+-------------------------------+--------------+ + * |1 1 1 |OP1| OP2 | | 32-Bit Instructions + * +----------+---+--+-----+----------------------+--------------+ + * |1 1 1 | 1 0| i | 1 0 1 1 0 0 | imm4 | MOVT Instruction + * +----------+------+-----+----------------------+--------------+ + * + * lower_insn: + * + * 1 1 1 1 1 1 + * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +---+---------------------------------------------------------+ + * |OP | | 32-Bit Instructions + * +---+----------+--------------+-------------------------------+ + * |0 | imm3 | Rd | imm8 | MOVT Instruction + * +---+----------+--------------+-------------------------------+ + * + * The 16-bit immediate value is encoded in these bits: + * + * i = imm16[11] = upper_insn[10] + * imm4 = imm16[12:15] = upper_insn[3:0] + * imm3 = imm16[8:10] = lower_insn[14:12] + * imm8 = imm16[0:7] = lower_insn[7:0] + */ + + upper_insn = (uint32_t)(*(uint16_t *)addr); + lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); + + bvdbg("Performing THM_MOVx [%d] link at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (int)upper_insn, (int)lower_insn, + sym, (long)sym->st_value); + + /* Extract the 16-bit offset from the 32-bit instruction */ + + offset = ((upper_insn & 0x000f) << 12) | /* imm4 -> imm16[8:10] */ + ((upper_insn & 0x0400) << 1) | /* i -> imm16[11] */ + ((lower_insn & 0x7000) >> 4) | /* imm3 -> imm16[8:10] */ + (lower_insn & 0x00ff); /* imm8 -> imm16[0:7] */ + + /* Sign extend */ + + offset = (offset ^ 0x8000) - 0x8000; + + /* And perform the relocation */ + + bvdbg(" offset=%08lx branch target=%08lx\n", + (long)offset, offset + sym->st_value); + + offset += sym->st_value; + + /* Update the immediate value in the instruction. For MOVW we want the bottom + * 16-bits; for MOVT we want the top 16-bits. + */ + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) + { + offset >>= 16; + } + + upper_insn = ((upper_insn & 0xfbf0) | ((offset & 0xf000) >> 12) | + ((offset & 0x0800) >> 1)); + *(uint16_t *)addr = (uint16_t)upper_insn; + + lower_insn = ((lower_insn & 0x8f00) | ((offset & 0x0700) << 4) | + (offset & 0x00ff)); + *(uint16_t *)(addr + 2) = (uint16_t)lower_insn; + + bvdbg(" insn [%04x %04x]\n", + (int)upper_insn, (int)lower_insn); + } + break; + + default: + bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info)); + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("RELA relocation not supported\n"); + return -ENOSYS; +} + +#ifdef CONFIG_UCLIBCXX_EXCEPTION +int up_init_exidx(Elf32_Addr address, Elf32_Word size) +{ + init_unwind_exidx(address, size); + + return OK; +} +#endif + diff --git a/arch/arm/src/armv7-m/up_hardfault.c b/arch/arm/src/armv7-m/up_hardfault.c new file mode 100644 index 0000000000000000000000000000000000000000..807d45cc43922595c1dbb7a3c92a0235acbf76e9 --- /dev/null +++ b/arch/arm/src/armv7-m/up_hardfault.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_hardfault.c + * + * Copyright (C) 2009, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "nvic.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If CONFIG_ARMV7M_USEBASEPRI=n, then debug output from this file may + * interfere with context switching! + */ + +#ifdef CONFIG_DEBUG_HARDFAULT +# define hfdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define hfdbg(x...) +#endif + +#define INSN_SVC0 0xdf00 /* insn: svc 0 */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_hardfault + * + * Description: + * This is Hard Fault exception handler. It also catches SVC call + * exceptions that are performed in bad contexts. + * + ****************************************************************************/ + +int up_hardfault(int irq, FAR void *context) +{ +#if defined(CONFIG_DEBUG_HARDFAULT) || !defined(CONFIG_ARMV7M_USEBASEPRI) + uint32_t *regs = (uint32_t *)context; +#endif + + /* Get the value of the program counter where the fault occurred */ + +#ifndef CONFIG_ARMV7M_USEBASEPRI + uint16_t *pc = (uint16_t *)regs[REG_PC] - 1; + + /* Check if the pc lies in known FLASH memory. + * REVISIT: What if the PC lies in "unknown" external memory? Best + * use the BASEPRI register if you have external memory. + */ + +#ifdef CONFIG_BUILD_PROTECTED + /* In the kernel build, SVCalls are expected in either the base, kernel + * FLASH region or in the user FLASH region. + */ + + if (((uintptr_t)pc >= (uintptr_t)_START_TEXT && + (uintptr_t)pc < (uintptr_t)_END_TEXT) || + ((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart && + (uintptr_t)pc < (uintptr_t)USERSPACE->us_textend)) +#else + /* SVCalls are expected only from the base, kernel FLASH region */ + + if ((uintptr_t)pc >= (uintptr_t)_START_TEXT && + (uintptr_t)pc < (uintptr_t)_END_TEXT) +#endif + { + /* Fetch the instruction that caused the Hard fault */ + + uint16_t insn = *pc; + hfdbg(" PC: %p INSN: %04x\n", pc, insn); + + /* If this was the instruction 'svc 0', then forward processing + * to the SVCall handler + */ + + if (insn == INSN_SVC0) + { + hfdbg("Forward SVCall\n"); + return up_svcall(irq, context); + } + } +#endif + + /* Dump some hard fault info */ + + hfdbg("Hard Fault:\n"); + hfdbg(" IRQ: %d regs: %p\n", irq, regs); + hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + hfdbg(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x AFAULTS: %08x\n", + getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS), + getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR), + getreg32(NVIC_AFAULTS)); + hfdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + hfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + +#ifdef CONFIG_ARMV7M_USEBASEPRI +# ifdef REG_EXC_RETURN + hfdbg(" xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_BASEPRI], + CURRENT_REGS[REG_EXC_RETURN]); +# else + hfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_BASEPRI]); +# endif +#else +# ifdef REG_EXC_RETURN + hfdbg(" xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK], + CURRENT_REGS[REG_EXC_RETURN]); +# else + hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]); +# endif +#endif + + (void)up_irq_save(); + lldbg("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS)); + PANIC(); + return OK; +} diff --git a/arch/arm/src/armv7-m/up_initialstate.c b/arch/arm/src/armv7-m/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..7cf6816c21820e75a684e276469410c04f5fd1ae --- /dev/null +++ b/arch/arm/src/armv7-m/up_initialstate.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_initialstate.c + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "psr.h" +#include "exc_return.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit value */ + + xcp->regs[REG_R10] = (uint32_t)tcb->stack_alloc_ptr + 64; +#endif + + /* Save the task entry point (stripping off the thumb bit) */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start & ~1; + + /* Specify thumb mode */ + + xcp->regs[REG_XPSR] = ARMV7M_XPSR_T; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC + if (tcb->dspace != NULL) + { + /* Set the PIC base register (probably R10) to the address of the + * alloacated D-Space region. + */ + + xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; + } + +#ifdef CONFIG_NXFLAT + /* Make certain that bit 0 is set in the main entry address. This + * is only an issue when NXFLAT is enabled. NXFLAT doesn't know + * anything about thumb; the addresses that NXFLAT sets are based + * on file header info and won't have bit 0 set. + */ + + tcb->entry.main = (main_t)((uint32_t)tcb->entry.main | 1); +#endif +#endif /* CONFIG_PIC */ + +#if (defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU)) || \ + defined(CONFIG_BUILD_PROTECTED) + /* All tasks start via a stub function in kernel space. So all + * tasks must start in privileged thread mode. If CONFIG_BUILD_PROTECTED + * is defined, then that stub function will switch to unprivileged + * mode before transferring control to the user task. + */ + + xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + +#endif /* (CONFIG_ARMV7M_CMNVECTOR && !CONFIG_ARMV7M_LAZYFPU) || CONFIG_BUILD_PROTECTED */ + +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) && \ + defined(CONFIG_ARCH_FPU) + + xcp->regs[REG_FPSCR] = 0; /* REVISIT: Initial FPSCR should be configurable */ + xcp->regs[REG_FPReserved] = 0; + +#endif /* CONFIG_ARMV7M_CMNVECTOR && !CONFIG_ARMV7M_LAZYFPU && CONFIG_ARCH_FPU */ + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + +#ifdef CONFIG_ARMV7M_USEBASEPRI + xcp->regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY; +#else + xcp->regs[REG_PRIMASK] = 1; +#endif + +#else /* CONFIG_SUPPRESS_INTERRUPTS */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + xcp->regs[REG_BASEPRI] = NVIC_SYSH_PRIORITY_MIN; +#endif + +#endif /* CONFIG_SUPPRESS_INTERRUPTS */ +} diff --git a/arch/arm/src/armv7-m/up_itm.c b/arch/arm/src/armv7-m/up_itm.c new file mode 100644 index 0000000000000000000000000000000000000000..695360a1e703169204324bb5cb71a560c75aa925 --- /dev/null +++ b/arch/arm/src/armv7-m/up_itm.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_itm.c + * + * 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. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "itm.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: itm_sendchar + * + * Description: + * The function transmits a character via the ITM channel 0, and + * - Just returns when no debugger is connected that has booked the output. + * - Is blocking when a debugger is connected, but the previous character + * sent has not been transmitted. + * + * Input Parameters: + * ch - Character to transmit. + * + * Returned Value: + * Character to transmit. + * + ****************************************************************************/ + +uint32_t itm_sendchar(uint32_t ch) +{ + if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (getreg32(ITM_TER) & (1UL << 0))) /* ITM Port #0 enabled */ + { + while (getreg32(ITM_PORT(0)) == 0); + putreg8((uint8_t)ch, ITM_PORT(0)); + } + + return ch; +} + +/**************************************************************************** + * Name: itm_receivechar + * + * Description: + * + * Input Parameters: + * The function inputs a character via the external variable g_itm_rxbuffer. + * + * Returned Value: + * Received character or -1 No character pending. + * + ****************************************************************************/ + +int32_t itm_receivechar(void) +{ + int32_t ch = -1; /* Assume no character available */ + + if (g_itm_rxbuffer != ITM_RXBUFFER_EMPTY) + { + ch = g_itm_rxbuffer; + g_itm_rxbuffer = ITM_RXBUFFER_EMPTY; /* Ready for next character */ + } + + return ch; +} + +/**************************************************************************** + * Name: itm_checkchar + * + * Description: + * + * Input Parameters: + * The function checks whether a character is pending for reading in the + * variable g_itm_rxbuffer. + * + * Returned Value: + * 0 No character available. + * 1 Character available. + * + ****************************************************************************/ + +int32_t itm_checkchar (void) +{ + return (g_itm_rxbuffer != ITM_RXBUFFER_EMPTY); +} diff --git a/arch/arm/src/armv7-m/up_itm_syslog.c b/arch/arm/src/armv7-m/up_itm_syslog.c new file mode 100644 index 0000000000000000000000000000000000000000..94b499879a79b9111a9225f50f6990a66e6059fb --- /dev/null +++ b/arch/arm/src/armv7-m/up_itm_syslog.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_itm_syslog.c + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nvic.h" +#include "itm.h" +#include "tpi.h" +#include "dwt.h" +#include "up_arch.h" +#include "itm_syslog.h" + +#if defined(CONFIG_SYSLOG) || defined(CONFIG_ARMV7M_ITMSYSLOG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ARMV7M_ITMSYSLOG_SWODIV +# define CONFIG_ARMV7M_ITMSYSLOG_SWODIV 15 +#endif + +#if CONFIG_ARMV7M_ITMSYSLOG_SWODIV < 0 +# error CONFIG_ARMV7M_ITMSYSLOG_SWODIV should be at least equal to 1 +#endif + +/* Use Port #0 at default */ + +#ifndef CONFIG_ARMV7M_ITMSYSLOG_PORT +# define CONFIG_ARMV7M_ITMSYSLOG_PORT 0 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: itm_syslog_initialize + * + * Description: + * Performs ARM-specific initialize for the ITM SYSLOG functions. + * Additional, board specific logic may be required to: + * + * - Enable/configured serial wire output pins + * - Enable debug clocking. + * + * Those operations must be performed by MCU-specific logic before this + * function is called. + * + ****************************************************************************/ + +void itm_syslog_initialize(void) +{ + uint32_t regval; + + /* Enable trace in core debug */ + + regval = getreg32(NVIC_DEMCR); + regval |= NVIC_DEMCR_TRCENA; + putreg32(regval, NVIC_DEMCR); + + putreg32(0xc5acce55, ITM_LAR); + putreg32(0, ITM_TER); + putreg32(0, ITM_TCR); + putreg32(2, TPI_SPPR); /* Pin protocol: 2=> Manchester (USART) */ + + /* Default 880kbps */ + + regval = CONFIG_ARMV7M_ITMSYSLOG_SWODIV - 1; + putreg32(regval, TPI_ACPR); /* TRACECLKIN/(ACPR+1) SWO speed */ + + putreg32(0, ITM_TPR); + putreg32(0x400003fe, DWT_CTRL); + putreg32(0x0001000d, ITM_TCR); + putreg32(0x00000100, TPI_FFCR); + putreg32(0xffffffff, ITM_TER); /* Enable 32 Ports */ +} + +/**************************************************************************** + * Name: syslog_putc + * + * Description: + * This is the low-level system logging interface. The debugging/syslogging + * interfaces are syslog() and lowsyslog(). The difference is that + * the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses + * a lower level interface that works from interrupt handlers. This + * function is the low-level interface used to implement lowsyslog(). + * + ****************************************************************************/ + +int syslog_putc(int ch) +{ + /* ITM enabled */ + + if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_Msk) == 0) + { + return EOF; + } + + /* ITM Port "CONFIG_ARMV7M_ITMSYSLOG_PORT" enabled */ + + if (getreg32(ITM_TER) & (1 << CONFIG_ARMV7M_ITMSYSLOG_PORT)) + { + while (getreg32(ITM_PORT(CONFIG_ARMV7M_ITMSYSLOG_PORT)) == 0); + putreg8((uint8_t)ch, ITM_PORT(CONFIG_ARMV7M_ITMSYSLOG_PORT)); + } + + return ch; +} + +#endif /* CONFIG_SYSLOG && CONFIG_ARMV7M_ITMSYSLOG */ diff --git a/arch/arm/src/armv7-m/up_memfault.c b/arch/arm/src/armv7-m/up_memfault.c new file mode 100644 index 0000000000000000000000000000000000000000..145dba531d0d788fc61d212c3f9ec860f0e2da35 --- /dev/null +++ b/arch/arm/src/armv7-m/up_memfault.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_memfault.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "nvic.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef DEBUG_MEMFAULTS /* Define to debug memory management faults */ + +#ifdef DEBUG_MEMFAULTS +# define mfdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define mfdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_memfault + * + * Description: + * This is Memory Management Fault exception handler. Normally we get here + * when the Cortex M3 MPU is enabled and an MPU fault is detected. However, + * I understand that there are other error conditions that can also generate + * memory management faults. + * + ****************************************************************************/ + +int up_memfault(int irq, FAR void *context) +{ + /* Dump some memory management fault info */ + + (void)up_irq_save(); + lldbg("PANIC!!! Memory Management Fault:\n"); + mfdbg(" IRQ: %d context: %p\n", irq, regs); + lldbg(" CFAULTS: %08x MMFAR: %08x\n", + getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR)); + mfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + mfdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + mfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + +#ifdef CONFIG_ARMV7M_USEBASEPRI +# ifdef REG_EXC_RETURN + mfdbg(" xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_BASEPRI], + CURRENT_REGS[REG_EXC_RETURN]); +# else + mfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_BASEPRI]); +# endif +#else +# ifdef REG_EXC_RETURN + mfdbg(" xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK], + CURRENT_REGS[REG_EXC_RETURN]); +# else + mfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]); +# endif +#endif + + PANIC(); + return OK; /* Won't get here */ +} diff --git a/arch/arm/src/armv7-m/up_mpu.c b/arch/arm/src/armv7-m/up_mpu.c new file mode 100644 index 0000000000000000000000000000000000000000..05aadda4b6b21076621c23ee8e24ae10f3743d47 --- /dev/null +++ b/arch/arm/src/armv7-m/up_mpu.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_mpu.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "mpu.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ARM_MPU_NREGIONS +# define CONFIG_ARM_MPU_NREGIONS 8 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These sets represent the set of disabled memory sub-regions. A bit set + * corresponds to a disabled sub-region; the LS bit corresponds to the first + * region. + * + * The g_ms_regionmask array is indexed by the number of subregions at the + * end of the region: 0 means no sub-regions are available(0xff) and 8 means + * all subregions are available (0x00). + */ + +static const uint8_t g_ms_regionmask[9] = +{ + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 +}; + +/* The g_ls_regionmask array is indexed by the number of subregions at the + * beginning of the region: 0 means no sub-regions need be disabled (0x00) + * and 8 means all subregions must be disabled (0xff). + */ + +static const uint8_t g_ls_regionmask[9] = +{ + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff +}; + +/* The next available region number */ + +static uint8_t g_region; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_subregion_ms + * + * Description: + * Given (1) the size of the memory to be mapped and (2) the log2 size + * of the mapping to use, determine the minimal sub-region set at the + * to be disabled at the higher end of the region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t asize; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Size Mask Size Shift Sub-Regions Bitset + * 0x1000 0x01ff 0x1000 9 8 0x00 + * 0x0c00 0x01ff 0x0c00 9 6 0xc0 + * 0x0c40 0x01ff 0x0e00 9 7 0x80 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + asize = (size + mask) & ~mask; /* Adjusted size */ + nsrs = asize >> (l2size-3); /* Number of subregions */ + return g_ms_regionmask[nsrs]; +} + +/**************************************************************************** + * Name: mpu_subregion_ls + * + * Description: + * Given (1) the offset to the beginning of data in the region and (2) the + * log2 size of the mapping to use, determine the minimal sub-region set + * to span that memory region sub-region set at the to be disabled at the + * higher end of the region + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t aoffset; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Offset Mask Offset Shift Sub-Regions Bitset + * 0x0000 0x01ff 0x0000 9 8 0x00 + * 0x0400 0x01ff 0x0400 9 6 0x03 + * 0x02c0 0x01ff 0x0200 9 7 0x01 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + aoffset = offset & ~mask; /* Adjusted offset */ + nsrs = aoffset >> (l2size-3); /* Number of subregions */ + return g_ls_regionmask[nsrs]; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_allocregion + * + * Description: + * Allocate the next region + * + * Assumptions: + * - Regions are never deallocated + * - Regions are only allocated early in initialization, so no special + * protection against re-entrancy is required; + * + ****************************************************************************/ + +unsigned int mpu_allocregion(void) +{ + DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS); + return (unsigned int)g_region++; +} + +/**************************************************************************** + * Name: mpu_log2regionceil + * + * Description: + * Determine the smallest value of l2size (log base 2 size) such that the + * following is true: + * + * size <= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionceil(size_t size) +{ + uint8_t l2size; + + /* The minimum permitted region size is 32 bytes (log2(32) = 5. */ + + for (l2size = 5; l2size < 32 && size > (1 << l2size); l2size++); + return l2size; +} + +/**************************************************************************** + * Name: mpu_log2regionfloor + * + * Description: + * Determine the largest value of l2size (log base 2 size) such that the + * following is true: + * + * size >= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionfloor(size_t size) +{ + uint8_t l2size = mpu_log2regionceil(size); + + if (l2size > 4 && size < (1 << l2size)) + { + l2size--; + } + + return l2size; +} + +/**************************************************************************** + * Name: mpu_subregion + * + * Description: + * Given the size of the (1) memory to be mapped and (2) the log2 size + * of the mapping to use, determine the minimal sub-region set to span + * that memory region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size) +{ + uint32_t mask; + size_t offset; + uint32_t ret; + + /* Eight subregions are supported. The representation is as an 8-bit + * value with the LS bit corresponding to subregion 0. A bit is set + * to disable the sub-region. + * + * l2size: Log2 of the actual region size is <= (1 << l2size); + */ + + DEBUGASSERT(l2size > 4 && size <= (1 << l2size)); + + /* For region sizes of 32, 64, and 128 bytes, the effect of setting + * one or more bits of the SRD field to 1 is UNPREDICTABLE. + */ + + if (l2size < 8) + { + return 0; + } + + /* Calculate the offset of the base address into the aligned region. */ + + mask = (1 << l2size) - 1; + offset = base & mask; + + /* Calculate the mask need to handle disabled subregions at the end of the + * region + */ + + ret = mpu_subregion_ms(size + offset, l2size); + + /* Then OR in the mask need to handle disabled subregions at the beginning + * of the region. + */ + + ret |= mpu_subregion_ls(offset, l2size); + return ret; +} diff --git a/arch/arm/src/armv7-m/up_ramvec_attach.c b/arch/arm/src/armv7-m/up_ramvec_attach.c new file mode 100644 index 0000000000000000000000000000000000000000..3700cdb00bc1542ff0b44e29585e3363475cded5 --- /dev/null +++ b/arch/arm/src/armv7-m/up_ramvec_attach.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/arm/irq/up_ramvec_attach.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "ram_vectors.h" + +#ifdef CONFIG_ARCH_RAMVECTORS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the interrupt + * config. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_IRQ +# define intdbg lldbg +# define intvdbg llvdbg +#else +# define intdbg(x...) +# define intvdbg(x...) +#endif + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Common exception entrypoint */ + +void exception_common(void); + +/**************************************************************************** + * Name: up_ramvec_attach + * + * Description: + * Configure the ram vector table so that IRQ number 'irq' will be + * dispatched by hardware to 'vector' + * + ****************************************************************************/ + +int up_ramvec_attach(int irq, up_vector_t vector) +{ + int ret = -EINVAL; + + intvdbg("%s IRQ%d\n", vector ? "Attaching" : "Detaching", irq); + + if ((unsigned)irq < NR_VECTORS) + { + irqstate_t flags; + + /* If the new vector is NULL, then the vector is being detached. In + * this case, disable the itnerrupt and direct any interrupts to the + * common exception handler. + */ + + flags = enter_critical_section(); + if (vector == NULL) + { + /* Disable the interrupt if we can before detaching it. We might + * not be able to do this for all interrupts. + */ + + up_disable_irq(irq); + + /* Detaching the vector really means re-attaching it to the + * common exception handler. + */ + + vector = exception_common; + } + + /* Save the new vector in the vector table */ + + g_ram_vectors[irq] = vector; + leave_critical_section(flags); + ret = OK; + } + + return ret; +} + +#endif /* !CONFIG_ARCH_RAMVECTORS */ diff --git a/arch/arm/src/armv7-m/up_ramvec_initialize.c b/arch/arm/src/armv7-m/up_ramvec_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..80b176d67403d0eaf8d14cb880ac1b3e99946bc7 --- /dev/null +++ b/arch/arm/src/armv7-m/up_ramvec_initialize.c @@ -0,0 +1,170 @@ +/**************************************************************************** + * arm/arm/src/armv7-m/up_ramvec_initialize.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" + +#include "chip.h" /* May redefine VECTAB fields */ +#include "up_arch.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_RAMVECTORS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Alignment ****************************************************************/ +/* Per the ARMv7M Architecture reference manual, the NVIC vector table + * requires 7-bit address alignment (i.e, bits 0-6 of the address of the + * vector table must be zero). In this case alignment to a 128 byte address + * boundary is sufficient. + * + * Some parts, such as the LPC17xx family, require alignment to a 256 byte + * address boundary. Any other unusual alignment requirements for the vector + * can be specified for a given architecture be redefining + * NVIC_VECTAB_TBLOFF_MASK in the chip-specific chip.h header file for the + * appropriate mask. + */ + +#define RAMVEC_ALIGN ((~NVIC_VECTAB_TBLOFF_MASK & 0xffff) + 1) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the interrupt + * config. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_IRQ +# define intdbg lldbg +# define intvdbg llvdbg +#else +# define intdbg(x...) +# define intvdbg(x...) +#endif + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* If CONFIG_ARCH_RAMVECTORS is defined, then the ARM logic must provide + * ARM-specific implementations of up_ramvec_initialize(), irq_attach(), and + * irq_dispatch. In this case, it is also assumed that the ARM vector + * table resides in RAM, has the name up_ram_vectors, and has been + * properly positioned and aligned in memory by the linker script. + * + * REVISIT: Can this alignment requirement vary from core-to-core? Yes, it + * depends on the number of vectors supported by the MCU. The safest thing + * to do is to put the vector table at the beginning of RAM in order toforce + * the highest alignment possible. + */ + +up_vector_t g_ram_vectors[ARMV7M_VECTAB_SIZE] + __attribute__ ((section (".ram_vectors"), aligned (RAMVEC_ALIGN))); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ramvec_initialize + * + * Description: + * Copy vectors to RAM an configure the NVIC to use the RAM vectors. + * + ****************************************************************************/ + +void up_ramvec_initialize(void) +{ + const up_vector_t *src; + up_vector_t *dest; + int i; + + /* The vector table must be aligned */ + + DEBUGASSERT(((uint32_t)g_ram_vectors & ~NVIC_VECTAB_TBLOFF_MASK) == 0); + + /* Copy the ROM vector table at address zero to RAM vector table. + * + * This must be done BEFORE the MPU is enable if the MPU is being used to + * protect against NULL pointer references. + */ + + src = (const CODE up_vector_t *)getreg32(NVIC_VECTAB); + dest = g_ram_vectors; + + intvdbg("src=%p dest=%p\n", src, dest); + + for (i = 0; i < ARMV7M_VECTAB_SIZE; i++) + { + *dest++ = *src++; + } + + /* Now configure the NVIC to use the new vector table. */ + + putreg32((uint32_t)g_ram_vectors, NVIC_VECTAB); + + /* The number bits required to align the RAM vector table seem to vary + * from part-to-part. The following assertion will catch the case where + * the table alignment is insufficient. + */ + + intvdbg("NVIC_VECTAB=%08x\n", getreg32(NVIC_VECTAB)); + DEBUGASSERT(getreg32(NVIC_VECTAB) == (uint32_t)g_ram_vectors); +} + +#endif /* !CONFIG_ARCH_RAMVECTORS */ diff --git a/arch/arm/src/armv7-m/up_releasepending.c b/arch/arm/src/armv7-m/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..e9f4cceb33cdf2181f3273caa7bc473d0ea4201d --- /dev/null +++ b/arch/arm/src/armv7-m/up_releasepending.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_releasepending.c + * + * Copyright (C) 2007-2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. Just copy the + * CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv7-m/up_reprioritizertr.c b/arch/arm/src/armv7-m/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..d3415e77414246695490bb00e54bb912dbb6dac7 --- /dev/null +++ b/arch/arm/src/armv7-m/up_reprioritizertr.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_reprioritizertr.c + * + * Copyright (C) 2007-2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just removed the head + * of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the ready-to-run task list. sched_addreadytorun + * will return true if the task was added to the head of ready-to-run + * list. We will need to perform a context switch only if the + * EXCLUSIVE or of the two calls is non-zero (i.e., one and only one + * the calls changes the head of the ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed (i.e. if the head + * of the ready-to-run list is no longer the same). + */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/arm/src/armv7-m/up_schedulesigaction.c b/arch/arm/src/armv7-m/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..c44298c14ece181a4a7033324d600a2258b752c8 --- /dev/null +++ b/arch/arm/src/armv7-m/up_schedulesigaction.c @@ -0,0 +1,220 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_schedulesigaction.c + * + * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "psr.h" +#include "exc_return.h" +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'sigdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + DEBUGASSERT(tcb != NULL && sigdeliver != NULL); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + sdbg("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!CURRENT_REGS) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted + * task is the same as the one that must receive the signal, then + * we will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Save the return PC, CPSR and either the BASEPRI or PRIMASK + * registers (and perhaps also the LR). These will be + * restored by the signal trampoline after the signal has been + * delivered. + */ + + tcb->xcp.sigdeliver = (FAR void *)sigdeliver; + tcb->xcp.saved_pc = CURRENT_REGS[REG_PC]; +#ifdef CONFIG_ARMV7M_USEBASEPRI + tcb->xcp.saved_basepri = CURRENT_REGS[REG_BASEPRI]; +#else + tcb->xcp.saved_primask = CURRENT_REGS[REG_PRIMASK]; +#endif + tcb->xcp.saved_xpsr = CURRENT_REGS[REG_XPSR]; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.saved_lr = CURRENT_REGS[REG_LR]; +#endif + /* Then set up to vector to the trampoline with interrupts + * disabled. The kernel-space trampoline must run in + * privileged thread mode. + */ + + CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver; +#ifdef CONFIG_ARMV7M_USEBASEPRI + CURRENT_REGS[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY; +#else + CURRENT_REGS[REG_PRIMASK] = 1; +#endif + CURRENT_REGS[REG_XPSR] = ARMV7M_XPSR_T; +#ifdef CONFIG_BUILD_PROTECTED + CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR; +#endif + /* And make sure that the saved context in the TCB is the same + * as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signalling a task is not running from an + * interrupt handler or (2) we are not in an interrupt handler and the + * running task is signalling* some non-running task. + */ + + else + { + /* Save the return PC, CPSR and either the BASEPRI or PRIMASK + * registers (and perhaps also the LR). These will be restored + * by the signal trampoline after the signal has been delivered. + */ + + tcb->xcp.sigdeliver = (FAR void *)sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; +#ifdef CONFIG_ARMV7M_USEBASEPRI + tcb->xcp.saved_basepri = tcb->xcp.regs[REG_BASEPRI]; +#else + tcb->xcp.saved_primask = tcb->xcp.regs[REG_PRIMASK]; +#endif + tcb->xcp.saved_xpsr = tcb->xcp.regs[REG_XPSR]; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.saved_lr = tcb->xcp.regs[REG_LR]; +#endif + /* Then set up to vector to the trampoline with interrupts + * disabled. We must already be in privileged thread mode to be + * here. + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; +#ifdef CONFIG_ARMV7M_USEBASEPRI + tcb->xcp.regs[REG_BASEPRI] = NVIC_SYSH_DISABLE_PRIORITY; +#else + tcb->xcp.regs[REG_PRIMASK] = 1; +#endif + tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T; +#ifdef CONFIG_BUILD_PROTECTED + tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR; +#endif + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-m/up_sigdeliver.c b/arch/arm/src/armv7-m/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..bfa672aa7acf3d154b2169869a9c9166149ea4bc --- /dev/null +++ b/arch/arm/src/armv7-m/up_sigdeliver.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_sigdeliver.c + * + * Copyright (C) 2009-2010, 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copyfullstate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; +#ifdef CONFIG_ARMV7M_USEBASEPRI + regs[REG_BASEPRI] = rtcb->xcp.saved_basepri; +#else + regs[REG_PRIMASK] = rtcb->xcp.saved_primask; +#endif + regs[REG_XPSR] = rtcb->xcp.saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + regs[REG_LR] = rtcb->xcp.saved_lr; +#endif + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + up_irq_restore((uint8_t)regs[REG_BASEPRI]); +#else + up_irq_restore((uint16_t)regs[REG_PRIMASK]); +#endif + + /* Deliver the signal */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-m/up_signal_dispatch.c b/arch/arm/src/armv7-m/up_signal_dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..4a03a26b213e7d39ceedd7086c6c10162d4d6051 --- /dev/null +++ b/arch/arm/src/armv7-m/up_signal_dispatch.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_signal_dispatch.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "svcall.h" +#include "up_internal.h" + +#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ + defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_dispatch + * + * Description: + * In this kernel mode build, this function will be called to execute a + * a signal handler in user-space. When the signal is delivered, a + * kernel-mode stub will first run to perform some housekeeping functions. + * This kernel-mode stub will then be called transfer control to the user + * mode signal handler by calling this function. + * + * Normally the a user-mode signalling handling stub will also execute + * before the ultimate signal handler is called. See + * arch/arm/src/armv[6\7]/up_signal_handler. This function is the + * user-space, signal handler trampoline function. It is called from + * up_signal_dispatch() in user-mode. + * + * Inputs: + * sighand - The address user-space signal handling function + * signo, info, and ucontext - Standard arguments to be passed to the + * signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via an architecture specific system call made by up_signal_handler(). + * However, this will look like a normal return by the caller of + * up_signal_dispatch. + * + ****************************************************************************/ + +void up_signal_dispatch(_sa_sigaction_t sighand, int signo, + FAR siginfo_t *info, FAR void *ucontext) +{ + /* Let sys_call4() do all of the work */ + + (void)sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo, + (uintptr_t)info, (uintptr_t)ucontext); +} + +#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */ diff --git a/arch/arm/src/armv7-m/up_stackcheck.c b/arch/arm/src/armv7-m/up_stackcheck.c new file mode 100644 index 0000000000000000000000000000000000000000..1b465d233ff59a068211e6d17d6196d4d801af72 --- /dev/null +++ b/arch/arm/src/armv7-m/up_stackcheck.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_stackcheck.c + * + * Copyright (c) 2013, 2014 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ARMV7M_STACKCHECK + +/* Support per function call stack checking. + * This code uses R10 to check for a stack overflow within function calls. + * This has a performance impact, but will be able to catch hard to find + * stack overflows. + */ + +#include + +#include "up_arch.h" +#include "nvic.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +void __cyg_profile_func_enter(void *func, void *caller) __attribute__((naked, no_instrument_function)); +void __cyg_profile_func_exit(void *func, void *caller) __attribute__((naked, no_instrument_function)); +void __stack_overflow_trap(void) __attribute__((naked, no_instrument_function)); + +/**************************************************************************** + * Name: __stack_overflow_trap + ****************************************************************************/ + +void __stack_overflow_trap(void) +{ + /* if we get here, the stack has overflowed */ + + uint32_t regval; + + /* force hard fault */ + regval = getreg32(NVIC_INTCTRL); + regval |= NVIC_INTCTRL_NMIPENDSET; + putreg32(regval, NVIC_INTCTRL); + + /* XXX no need to trap it here, the fault handler gets to it */ +} + +/**************************************************************************** + * Name: __cyg_profile_func_enter + ****************************************************************************/ + +void __cyg_profile_func_enter(void *func, void *caller) +{ + asm volatile ( + " mrs r2, ipsr \n" /* Check whether we are in interrupt mode */ + " cmp r2, #0 \n" /* since we don't switch r10 on interrupt entry, we */ + " bne 2f \n" /* can't detect overflow of the interrupt stack. */ + " \n" + " sub r2, sp, #68 \n" /* compute stack pointer as though we just stacked a full frame */ + " mrs r1, control \n" /* Test CONTROL.FPCA to see whether we also need room for the FP */ + " tst r1, #4 \n" /* context. */ + " beq 1f \n" + " sub r2, r2, #136 \n" /* subtract FP context frame size */ + "1: \n" + " cmp r2, r10 \n" /* compare stack with limit */ + " bgt 2f \n" /* stack is above limit and thus OK */ + " b __stack_overflow_trap\n" + "2: \n" + " bx lr \n" + ); +} + +/**************************************************************************** + * Name: __cyg_profile_func_exit + ****************************************************************************/ + +void __cyg_profile_func_exit(void *func, void *caller) +{ + asm volatile("bx lr"); +} +#endif diff --git a/arch/arm/src/armv7-m/up_svcall.c b/arch/arm/src/armv7-m/up_svcall.c new file mode 100644 index 0000000000000000000000000000000000000000..4d28224fd7eba41837ef4b49a91a4381733c4af4 --- /dev/null +++ b/arch/arm/src/armv7-m/up_svcall.c @@ -0,0 +1,518 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_svcall.c + * + * Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +#include "svcall.h" +#include "exc_return.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Debug ********************************************************************/ +/* Debug output from this file may interfere with context switching! To get + * debug output you must enabled the following in your NuttX configuration: + * + * - CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL (shows only syscalls) + * - CONFIG_DEBUG and CONFIG_DEBUG_SVCALL (shows everything) + */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# define svcdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define svcdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: + * + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 + * + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ + __asm__ __volatile__ + ( + " sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ + " str lr, [sp, #12]\n" /* Save lr in the stack frame */ + " ldr ip, =g_stublookup\n" /* R12=The base of the stub lookup table */ + " ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this syscall */ + " blx ip\n" /* Call the stub (modifies lr) */ + " ldr lr, [sp, #12]\n" /* Restore lr */ + " add sp, sp, #16\n" /* Destroy the stack frame */ + " mov r2, r0\n" /* R2=Save return value in R2 */ + " mov r0, #3\n" /* R0=SYS_syscall_return */ + " svc 0" /* Return from the syscall */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_svcall + * + * Description: + * This is SVCall exception handler that performs context switching + * + ****************************************************************************/ + +int up_svcall(int irq, FAR void *context) +{ + uint32_t *regs = (uint32_t *)context; + uint32_t cmd; + + DEBUGASSERT(regs && regs == CURRENT_REGS); + cmd = regs[REG_R0]; + + /* The SVCall software interrupt is called with R0 = system call command + * and R1..R7 = variable number of arguments depending on the system call. + */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# endif + { + svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); +# ifdef REG_EXC_RETURN + svcdbg(" PSR: %08x EXC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_EXC_RETURN]); +# else + svcdbg(" PSR: %08x\n", regs[REG_XPSR]); +# endif + } +#endif + + /* Handle the SVCall according to the command in R0 */ + + switch (cmd) + { + /* R0=SYS_save_context: This is a save context command: + * + * int up_saveusercontext(uint32_t *saveregs); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_save_context + * R1 = saveregs + * + * In this case, we simply need to copy the current regsters to the + * save register space references in the saved R1 and return. + */ + + case SYS_save_context: + { + DEBUGASSERT(regs[REG_R1] != 0); + memcpy((uint32_t *)regs[REG_R1], regs, XCPTCONTEXT_SIZE); +#if defined(CONFIG_ARCH_FPU) && \ + (!defined(CONFIG_ARMV7M_CMNVECTOR) || defined(CONFIG_ARMV7M_LAZYFPU)) + up_savefpu((uint32_t *)regs[REG_R1]); +#endif + } + break; + + /* R0=SYS_restore_context: This a restore context command: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_restore_context + * R1 = restoreregs + * + * In this case, we simply need to set CURRENT_REGS to restore register + * area referenced in the saved R1. context == CURRENT_REGS is the normal + * exception return. By setting CURRENT_REGS = context[R1], we force + * the return to the saved context referenced in R1. + */ + + case SYS_restore_context: + { + DEBUGASSERT(regs[REG_R1] != 0); + CURRENT_REGS = (uint32_t *)regs[REG_R1]; + } + break; + + /* R0=SYS_switch_context: This a switch context command: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_switch_context + * R1 = saveregs + * R2 = restoreregs + * + * In this case, we do both: We save the context registers to the save + * register area reference by the saved contents of R1 and then set + * CURRENT_REGS to to the save register area referenced by the saved + * contents of R2. + */ + + case SYS_switch_context: + { + DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0); + memcpy((uint32_t *)regs[REG_R1], regs, XCPTCONTEXT_SIZE); +#if defined(CONFIG_ARCH_FPU) && \ + (!defined(CONFIG_ARMV7M_CMNVECTOR) || defined(CONFIG_ARMV7M_LAZYFPU)) + up_savefpu((uint32_t *)regs[REG_R1]); +#endif + CURRENT_REGS = (uint32_t *)regs[REG_R2]; + } + break; + + /* R0=SYS_syscall_return: This a syscall return command: + * + * void up_syscall_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + +#ifdef CONFIG_LIB_SYSCALL + case SYS_syscall_return: + { + struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved syscall return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved syscall return address in + * the original mode. + */ + + regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn; + regs[REG_EXC_RETURN] = rtcb->xcp.syscall[index].excreturn; + rtcb->xcp.nsyscalls = index; + + /* The return value must be in R0-R1. dispatch_syscall() temporarily + * moved the value for R0 into R2. + */ + + regs[REG_R0] = regs[REG_R2]; + } + break; +#endif + + /* R0=SYS_task_start: This a user task start + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_task_start + * R1 = taskentry + * R2 = argc + * R3 = argv + */ + +#ifdef CONFIG_BUILD_PROTECTED + case SYS_task_start: + { + /* Set up to return to the user-space task start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->task_startup; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s task_startup: + */ + + regs[REG_R0] = regs[REG_R1]; /* Task entry */ + regs[REG_R1] = regs[REG_R2]; /* argc */ + regs[REG_R2] = regs[REG_R3]; /* argv */ + } + break; +#endif + + /* R0=SYS_pthread_start: This a user pthread start + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_pthread_start + * R1 = entrypt + * R2 = arg + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) + case SYS_pthread_start: + { + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->pthread_startup; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s pthread_startup: + */ + + regs[REG_R0] = regs[REG_R1]; /* pthread entry */ + regs[REG_R1] = regs[REG_R2]; /* arg */ + } + break; +#endif + + /* R0=SYS_signal_handler: This a user signal handler callback + * + * void signal_handler(_sa_sigaction_t sighand, int signo, + * FAR siginfo_t *info, FAR void *ucontext); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler + * R1 = sighand + * R2 = signo + * R3 = info + * ucontext (on the stack) + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + case SYS_signal_handler: + { + struct tcb_s *rtcb = sched_self(); + + /* Remember the caller's return address */ + + DEBUGASSERT(rtcb->xcp.sigreturn == 0); + rtcb->xcp.sigreturn = regs[REG_PC]; + + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)USERSPACE->signal_handler; + regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s signal_handler. + */ + + regs[REG_R0] = regs[REG_R1]; /* sighand */ + regs[REG_R1] = regs[REG_R2]; /* signal */ + regs[REG_R2] = regs[REG_R3]; /* info */ + + /* The last parameter, ucontext, is trickier. The ucontext + * parameter will reside at an offset of 4 from the stack pointer. + */ + + regs[REG_R3] = *(uint32_t *)(regs[REG_SP]+4); + } + break; +#endif + + /* R0=SYS_signal_handler_return: This a user signal handler callback + * + * void signal_handler_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler_return + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + case SYS_signal_handler_return: + { + struct tcb_s *rtcb = sched_self(); + + /* Set up to return to the kernel-mode signal dispatching logic. */ + + DEBUGASSERT(rtcb->xcp.sigreturn != 0); + + regs[REG_PC] = rtcb->xcp.sigreturn; + regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + rtcb->xcp.sigreturn = 0; + } + break; +#endif + + /* This is not an architecture-specific system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_LIB_SYSCALL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall); + + /* Make sure that there is a no saved syscall return address. We + * cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcp.syscall[index].sysreturn = regs[REG_PC]; + rtcb->xcp.syscall[index].excreturn = regs[REG_EXC_RETURN]; + rtcb->xcp.nsyscalls = index + 1; + + regs[REG_PC] = (uint32_t)dispatch_syscall; + regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + + /* Offset R0 to account for the reserved values */ + + regs[REG_R0] -= CONFIG_SYS_RESERVED; +#else + slldbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]); +#endif + } + break; + } + + /* Report what happened. That might difficult in the case of a context switch */ + +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# else + if (regs != CURRENT_REGS) +# endif + { + svcdbg("SVCall Return:\n"); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R0], CURRENT_REGS[REG_R1], + CURRENT_REGS[REG_R2], CURRENT_REGS[REG_R3], + CURRENT_REGS[REG_R4], CURRENT_REGS[REG_R5], + CURRENT_REGS[REG_R6], CURRENT_REGS[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + CURRENT_REGS[REG_R8], CURRENT_REGS[REG_R9], + CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11], + CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13], + CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]); +# ifdef REG_EXC_RETURN + svcdbg(" PSR: %08x EXC_RETURN: %08x\n", + CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_EXC_RETURN]); +# else + svcdbg(" PSR: %08x\n", CURRENT_REGS[REG_XPSR]); +# endif + } +# ifdef CONFIG_DEBUG_SVCALL + else + { + svcdbg("SVCall Return: %d\n", regs[REG_R0]); + } +# endif +#endif + + return OK; +} diff --git a/arch/arm/src/armv7-m/up_systemreset.c b/arch/arm/src/armv7-m/up_systemreset.c new file mode 100644 index 0000000000000000000000000000000000000000..509f7707afee42a0b95963a545045add7f058fb4 --- /dev/null +++ b/arch/arm/src/armv7-m/up_systemreset.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_systemreset.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Darcy Gong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" +#include "nvic.h" + +/**************************************************************************** + * Public functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_systemreset + * + * Description: + * Internal, Cortex-M0 reset logic. + * + ****************************************************************************/ + +void up_systemreset(void) +{ + uint32_t regval; + + /* Set up for the system reset, retaining the priority group from the + * the AIRCR register. + */ + + regval = getreg32(NVIC_AIRCR) & NVIC_AIRCR_PRIGROUP_MASK; + regval |= ((0x5fa << NVIC_AIRCR_VECTKEY_SHIFT) | NVIC_AIRCR_SYSRESETREQ); + putreg32(regval, NVIC_AIRCR); + + /* Ensure completion of memory accesses */ + + __asm volatile ("dsb"); + + /* Wait for the reset */ + + for (; ; ); +} + + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. This function may or may not be supported by a + * particular board architecture. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not used by + * a board, the value zero may be provided in calls to board_reset. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_RESET +int board_reset(int status) +{ + up_systemreset(); + return 0; +} +#endif diff --git a/arch/arm/src/armv7-m/up_unblocktask.c b/arch/arm/src/armv7-m/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..3c9ae8df14780afc49037b67f6666882c72dcffc --- /dev/null +++ b/arch/arm/src/armv7-m/up_unblocktask.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_unblocktask.c + * + * Copyright (C) 2007-2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/armv7-m/up_vectors.c b/arch/arm/src/armv7-m/up_vectors.c new file mode 100644 index 0000000000000000000000000000000000000000..ada819c3315673f162c24b96104e5aae1209538f --- /dev/null +++ b/arch/arm/src/armv7-m/up_vectors.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_vectors.c + * + * Copyright (C) 2012 Michael Smith. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define IDLE_STACK ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) + +#ifndef ARMV7M_PERIPHERAL_INTERRUPTS +# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Chip-specific entrypoint */ + +extern void __start(void); + +/* Common exception entrypoint */ + +extern void exception_common(void); + +/************************************************************************************ + * Public data + ************************************************************************************/ + +/* Provided by the linker script to indicate the end of the BSS */ + +extern char _ebss; + +/* The v7m vector table consists of an array of function pointers, with the first + * slot (vector zero) used to hold the initial stack pointer. + * + * As all exceptions (interrupts) are routed via exception_common, we just need to + * fill this array with pointers to it. + * + * Note that the [ ... ] designated initialiser is a GCC extension. + */ + +unsigned _vectors[] __attribute__((section(".vectors"))) = +{ + /* Initial stack */ + + IDLE_STACK, + + /* Reset exception handler */ + + (unsigned)&__start, + + /* Vectors 2 - n point directly at the generic handler */ + + [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common +}; diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..0582a4fee3361af32e82c9d368bddce074040244 --- /dev/null +++ b/arch/arm/src/armv7-r/Kconfig @@ -0,0 +1,185 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "ARMv7-A Configuration Options" + +config ARMV7R_MEMINIT + bool + default y if BOOT_SDRAM_DATA + default n if !BOOT_SDRAM_DATA + ---help--- + If this configuration *not* selected, then it is assumed that all + memory resources are initialized via arm_data_initialize() and + available at power-up reset time. Other memories, such as SDRAM or + some ECC SRAM memories, require some platform-specific + initialization first. In that case, this option should be selected + and the platform-specific implementation of arm_boot() must perform + the memory initialization first, then explicitly call + arm_data_initialize(). + +config ARMV7R_HAVE_L2CC + bool + default n + ---help--- + Selected by the configuration tool if the architecutre supports any + kind of L2 cache. + +config ARMV7R_HAVE_L2CC_PL310 + bool + default n + select ARMV7R_HAVE_L2CC + ---help--- + Set by architecture-specific code if the hardware supports a PL310 + r3p2 L2 cache (only version r3p2 is supported). + +if ARMV7R_HAVE_L2CC + +menu "L2 Cache Configuration" + +config ARMV7R_L2CC_PL310 + bool "ARMv7-A L2CC P310 Support" + default n + depends on ARMV7R_HAVE_L2CC_PL310 && EXPERIMENTAL + select ARCH_L2CACHE + ---help--- + Enable the 2 Cache Controller (L2CC) is based on the L2CC-PL310 ARM + multi-way cache macrocell, version r3p2. The addition of an on-chip + secondary cache, also referred to as a Level 2 or L2 cache, is a + method of improving the system performance when significant memory + traffic is generated by the processor. + +if ARCH_L2CACHE +if ARMV7R_L2CC_PL310 + +config PL310_LOCKDOWN_BY_MASTER + bool "PL310 Lockdown by Master" + default n + +config PL310_LOCKDOWN_BY_LINE + bool "PL310 Lockdown by Line" + default n + +config PL310_ADDRESS_FILTERING + bool "PL310 Address Filtering by Line" + default n + +endif # ARMV7R_L2CC_PL310 + +choice + prompt "L2 Cache Associativity" + default ARMV7R_ASSOCIATIVITY_8WAY + depends on ARCH_L2CACHE + ---help--- + This choice specifies the associativity of L2 cache in terms of the + number of ways. This value could be obtained by querying cache + configuration registers. However, by defining a configuration + setting instead, we can avoid using RAM memory to hold information + about properties of the memory. + +config ARMV7R_ASSOCIATIVITY_8WAY + bool "8-Way Associativity" + +config ARMV7R_ASSOCIATIVITY_16WAY + bool "16-Way Associativity" + +endchoice # L2 Cache Associativity + +choice + prompt "L2 Cache Way Size" + default ARMV7R_WAYSIZE_16KB + depends on ARCH_L2CACHE + ---help--- + This choice specifies size of each way. This value can be obtained + by querying cache configuration registers. However, by defining a + configuration setting instead, we can avoid using RAM memory to hold + information + +config ARMV7R_WAYSIZE_16KB + bool "16 KiB" + +config ARMV7R_WAYSIZE_32KB + bool "32 KiB" + +config ARMV7R_WAYSIZE_64KB + bool "64 KiB" + +config ARMV7R_WAYSIZE_128KB + bool "128 KiB" + +config ARMV7R_WAYSIZE_256KB + bool "256 KiB" + +config ARMV7R_WAYSIZE_512KB + bool "512 KiB" + +endchoice # L2 Cache Associativity +endif # ARCH_L2CACHE +endmenu # L2 Cache Configuration +endif # ARMV7R_HAVE_L2CC + +choice + prompt "Toolchain Selection" + default ARMV7R_TOOLCHAIN_GNU_EABIW if HOST_WINDOWS + default ARMV7R_TOOLCHAIN_GNU_EABIL if !HOST_WINDOWS + +config ARMV7R_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + +config ARMV7R_TOOLCHAIN_CODESOURCERYL + bool "CodeSourcery GNU toolchain under Linux" + depends on HOST_LINUX + ---help--- + For use with the GNU toolchain built with the NuttX buildroot package. + This tools may be arm-nuttx-eabi- or, if ARMV7R_OABI_TOOLCHAIN is set, + arm-nuttx-elf-. + +config ARMV7R_TOOLCHAIN_CODESOURCERYW + bool "CodeSourcery GNU toolchain under Windows" + depends on HOST_WINDOWS + +config ARMV7R_TOOLCHAIN_DEVKITARM + bool "devkitARM GNU toolchain" + depends on HOST_WINDOWS + +config ARMV7R_TOOLCHAIN_GNU_EABIL + bool "Generic GNU EABI toolchain under Linux (or other POSIX environment)" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARMV7R_TOOLCHAIN_GNU_EABIW + bool "Generic GNU EABI toolchain under Windows" + depends on HOST_WINDOWS + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for arm-none-eabi-. + +config ARMV7R_TOOLCHAIN_GNU_OABI + bool "Generic GNU OABI toolchain" + ---help--- + This option should work for any GNU toolchain configured for arm-elf-. + +endchoice # ARMV7R_HAVE_L2CC + +config ARMV7R_OABI_TOOLCHAIN + bool "OABI (vs EABI)" + default n + depends on ARMV7R_TOOLCHAIN_BUILDROOT + ---help--- + Most of the older buildroot toolchains are OABI and are named + arm-nuttx-elf- vs. arm-nuttx-eabi- + +config ARMV7R_HAVE_DECODEFIQ + bool + default n + +config ARMV7R_DECODEFIQ + bool "FIQ Handler" + default n + depends on ARMV7R_HAVE_DECODEFIQ + ---help--- + Select this option if your platform supports the function + arm_decodefiq(). diff --git a/arch/arm/src/armv7-r/Toolchain.defs b/arch/arm/src/armv7-r/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..f1eb9db8170e74c3aecd97c13ab649f356e4418f --- /dev/null +++ b/arch/arm/src/armv7-r/Toolchain.defs @@ -0,0 +1,162 @@ +############################################################################ +# arch/arm/src/armv7-r/Toolchain.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Select and allow the selected toolchain to be overridden by a command-line +#selection. +# + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_BUILDROOT) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYL) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= CODESOURCERYL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYW) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= CODESOURCERYW +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_DEVKITARM) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= DEVKITARM +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIL) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= GNU_EABIL +endif + +ifeq ($(filter y, \ + $(CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIW) \ + ),y) + CONFIG_ARMV7R_TOOLCHAIN ?= GNU_EABIW +endif + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +ifeq ($(CONFIG_ENDIAN_BIG),y) + TARGET_ARCH := armeb +else + TARGET_ARCH := arm +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),BUILDROOT) +ifeq ($(CONFIG_ARMV7R_OABI_TOOLCHAIN),y) + CROSSDEV ?= $(TARGET_ARCH)-nuttx-elf- + ARCROSSDEV ?= $(TARGET_ARCH)-nuttx-elf- +else + CROSSDEV ?= $(TARGET_ARCH)-nuttx-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-nuttx-eabi- +endif + MAXOPTIMIZATION ?= -Os +endif + +# CodeSourcery under Linux + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),CODESOURCERYL) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -O2 +endif + +# CodeSourcery under Windows + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),CODESOURCERYW) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -O2 + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# devkitARM under Windows + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),DEVKITARM) + CROSSDEV ?= $(TARGET_ARCH)-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-eabi- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + +# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),GNU_EABIL) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -Os +endif + +# Generic GNU EABI toolchain under Windows + +ifeq ($(CONFIG_ARMV7R_TOOLCHAIN),GNU_EABIW) + CROSSDEV ?= $(TARGET_ARCH)-none-eabi- + ARCROSSDEV ?= $(TARGET_ARCH)-none-eabi- + MAXOPTIMIZATION ?= -Os + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif diff --git a/arch/arm/src/armv7-r/arm.h b/arch/arm/src/armv7-r/arm.h new file mode 100644 index 0000000000000000000000000000000000000000..a2d64dc50fc10dd88f86cc4f71a5a4d7775291b5 --- /dev/null +++ b/arch/arm/src/armv7-r/arm.h @@ -0,0 +1,170 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm.h + * Non-CP15 Registers + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_CPSR_H +#define __ARCH_ARM_SRC_ARMV7_R_CPSR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ARMv7-R ******************************************************************/ + +/* PSR bits */ + +#define PSR_MODE_SHIFT (0) /* Bits 0-4: Mode fields */ +#define PSR_MODE_MASK (31 << PSR_MODE_SHIFT) +# define PSR_MODE_USR (16 << PSR_MODE_SHIFT) /* User mode */ +# define PSR_MODE_FIQ (17 << PSR_MODE_SHIFT) /* FIQ mode */ +# define PSR_MODE_IRQ (18 << PSR_MODE_SHIFT) /* IRQ mode */ +# define PSR_MODE_SVC (19 << PSR_MODE_SHIFT) /* Supervisor mode */ +# define PSR_MODE_ABT (23 << PSR_MODE_SHIFT) /* Abort mode */ +# define PSR_MODE_UND (27 << PSR_MODE_SHIFT) /* Undefined mode */ +# define PSR_MODE_SYS (31 << PSR_MODE_SHIFT) /* System mode */ +#define PSR_T_BIT (1 << 5) /* Bit 5: Thumb execution state bit */ +#define PSR_MASK_SHIFT (6) /* Bits 6-8: Mask Bits */ +#define PSR_MASK_MASK (7 << PSR_GE_SHIFT) +# define PSR_F_BIT (1 << 6) /* Bit 6: FIQ mask bit */ +# define PSR_I_BIT (1 << 7) /* Bit 7: IRQ mask bit */ +# define PSR_A_BIT (1 << 8) /* Bit 8: Asynchronous abort mask */ +#define PSR_E_BIT (1 << 9) /* Bit 9: Endianness execution state bit */ +#define PSR_IT27_SHIFT (10) /* Bits 10-15: If-Then execution state bits IT[2:7] */ +#define PSR_IT27_MASK (0x3f << PSR_IT27_SHIFT) +#define PSR_GE_SHIFT (16) /* Bits 16-19: Greater than or Equal flags */ +#define PSR_GE_MASK (15 << PSR_GE_SHIFT) + /* Bits 20-23: Reserved. RAZ/SBZP */ +#define PSR_J_BIT (1 << 24) /* Bit 24: Jazelle state bit */ +#define PSR_IT01_SHIFT (25) /* Bits 25-26: If-Then execution state bits IT[0:1] */ +#define PSR_IT01_MASK (3 << PSR_IT01_SHIFT) +#define PSR_Q_BIT (1 << 27) /* Bit 27: Cumulative saturation bit */ +#define PSR_V_BIT (1 << 28) /* Bit 28: Overflow condition flag */ +#define PSR_C_BIT (1 << 29) /* Bit 29: Carry condition flag */ +#define PSR_Z_BIT (1 << 30) /* Bit 30: Zero condition flag */ +#define PSR_N_BIT (1 << 31) /* Bit 31: Negative condition flag */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: arm_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * Boot Sequence + * + * 1. The __start entry point in armv7-r/arm_head.S is invoked upon power- + * on reset. + * 2. __start prepares CPU for code execution. + * 3a. If CONFIG_ARMV7R_MEMINIT is not defined, then __start will prepare + * memory resources by calling arm_data_initialize() and will then + * branch to this function. + * 3b. Otherwise, this function will be called without having initialized + * memory resources! We need to be very careful in this case. This + * function will perform MCU- and board-specific initialization which, + * among other things, must initialize memories. After initializatino + ( of the memories, this function will call arm_data_initialize() to + * initialize the memory resources + * 4. This function will then branch to os_start() to start the operating + * system. + * + ****************************************************************************/ + +void arm_boot(void) noreturn_function; + +/**************************************************************************** + * Name: arm_data_initialize + * + * Description: + * Clear all of .bss to zero; set .data to the correct initial values. + * This function is called automatically from ARMv7-R boot code *UNLESS* + * executing with data in some memory that requires platform-specific + * initialization (such as SDRAM). That latter case is indicated with + * CONFIG_ARMV7R_MEMINIT=y. In that case, early platform-specific logic + * must first initialize then memory then call this function. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_data_initialize(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_CPSR_H */ diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..11dd9fad09be9e339bb896a1767a819ff7e0583a --- /dev/null +++ b/arch/arm/src/armv7-r/arm_assert.c @@ -0,0 +1,412 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_assert.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump(sp,stack_base) +#endif + +/**************************************************************************** + * Name: up_taskdump + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg) +{ + /* Dump interesting properties of this task */ + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("%s: PID=%d Stack Used=%lu of %lu\n", + tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#else + lldbg("PID: %d Stack Used=%lu of %lu\n", + tcb->pid, (unsigned long)up_check_tcbstack(tcb), + (unsigned long)tcb->adj_stack_size); +#endif +} +#endif + +/**************************************************************************** + * Name: up_showtasks + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static inline void up_showtasks(void) +{ + /* Dump interesting properties of each task in the crash environment */ + + sched_foreach(up_taskdump, NULL); +} +#else +# define up_showtasks() +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (CURRENT_REGS) + { + int regs; + + /* Yes.. dump the interrupt registers */ + + for (regs = REG_R0; regs <= REG_R15; regs += 8) + { + uint32_t *ptr = (uint32_t *)&CURRENT_REGS[regs]; + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } + + lldbg("CPSR: %08x\n", CURRENT_REGS[REG_CPSR]); + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif +#ifdef CONFIG_ARCH_KERNEL_STACK + uint32_t kstackbase = 0; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + lldbg("Current sp: %08x\n", sp); + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Get the limits on the interrupt stack memory */ + + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + + /* Show interrupt stack info */ + + lldbg("Interrupt stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif +#endif + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* This this thread have a kernel stack allocated? */ + + if (rtcb->xcp.kstack) + { + kstackbase = (uint32_t)rtcb->xcp.kstack + CONFIG_ARCH_KERNEL_STACKSIZE - 4; + + lldbg("Kernel stack:\n"); + lldbg(" base: %08x\n", kstackbase); + lldbg(" size: %08x\n", CONFIG_ARCH_KERNEL_STACKSIZE); + } +#endif + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Does the current stack pointer lie within the interrupt stack? */ + + if (sp > istackbase - istacksize && sp < istackbase) + { + /* Yes.. dump the interrupt stack */ + + lldbg("Interrupt Stack\n", sp); + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("User sp: %08x\n", sp); + } +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase - ustacksize && sp < ustackbase) + { + lldbg("User Stack\n", sp); + up_stackdump(sp, ustackbase); + } + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* Dump the user stack if the stack pointer lies within the allocated + * kernel stack memory. + */ + + if (sp >= (uint32_t)rtcb->xcp.kstack && sp < kstackbase) + { + lldbg("Kernel Stack\n", sp); + up_stackdump(sp, kstackbase); + } +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); + + /* Dump the state of all tasks (if available) */ + + up_showtasks(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (CURRENT_REGS || (this_task())->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/arm/src/armv7-r/arm_blocktask.c b/arch/arm/src/armv7-r/arm_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..58cefee3cfe8a4e88fcf9b61b05dddcdc1e0fc1d --- /dev/null +++ b/arch/arm/src/armv7-r/arm_blocktask.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/up_blocktask.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_coherent_dcache.c b/arch/arm/src/armv7-r/arm_coherent_dcache.c new file mode 100644 index 0000000000000000000000000000000000000000..3be6b8df5c8f0a770f9d7ff8fb8614ffdaca3850 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_coherent_dcache.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/up_coherent_dcache.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "cp15_cacheops.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * addr - virtual start address of region + * len - Size of the address region in bytes + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_coherent_dcache(uintptr_t addr, size_t len) +{ + if (len > 0) + { + /* Perform the operation on the L1 cache */ + + cp15_coherent_dcache(addr, addr + len - 1); + +#ifdef CONFIG_ARCH_L2CACHE + /* If we have an L2 cache, then there more things that need to done */ + +# warning This is insufficient +#endif + } +} diff --git a/arch/arm/src/armv7-r/arm_copyarmstate.c b/arch/arm/src/armv7-r/arm_copyarmstate.c new file mode 100644 index 0000000000000000000000000000000000000000..601e074e1d23d993218befe1d0daa276509ac16d --- /dev/null +++ b/arch/arm/src/armv7-r/arm_copyarmstate.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_copyarmstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" + +#ifdef CONFIG_ARCH_FPU + +/**************************************************************************** + * Name: up_copyarmstate + * + * Description: + * Copy the ARM portion of the register save area (omitting the floating + * point registers) and save the floating pointer register directly. + * + ****************************************************************************/ + +void up_copyarmstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the Cortex-R model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + /* Save the floating point registers: This will initialize the floating + * registers at indices ARM_CONTEXT_REGS through (XCPTCONTEXT_REGS-1) + */ + + up_savefpu(dest); + + /* Then copy all of the ARM registers (omitting the floating point + * registers). Indices: 0 through (ARM_CONTEXT_REGS-1). + */ + + for (i = 0; i < ARM_CONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + +#endif /* CONFIG_ARCH_FPU */ diff --git a/arch/arm/src/armv7-r/arm_copyfullstate.c b/arch/arm/src/armv7-r/arm_copyfullstate.c new file mode 100644 index 0000000000000000000000000000000000000000..35c0805af2ea67192a7d8171eee73fb2696f3673 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_copyfullstate.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_copyfullstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copyfullstate + * + * Description: + * Copy the entire register save area (including the floating point + * registers if applicable). This is a little faster than most memcpy's + * since it does 32-bit transfers. + * + ****************************************************************************/ + +void up_copyfullstate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the current ARM model, the state is always copied to and from the + * stack and TCB. + */ + + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} diff --git a/arch/arm/src/armv7-r/arm_dataabort.c b/arch/arm/src/armv7-r/arm_dataabort.c new file mode 100644 index 0000000000000000000000000000000000000000..789fb0f5adae6e62bc6be4e1b919da3f9b56abcc --- /dev/null +++ b/arch/arm/src/armv7-r/arm_dataabort.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_dataabort.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_dataabort + * + * Input parameters: + * regs - The standard, ARM register save array. + * dfar - Fault address register. + * dfsr - Fault status register. + * + * Description: + * This is the data abort exception handler. The ARM data abort exception + * occurs when a memory fault is detected during a data transfer. + * + ****************************************************************************/ + +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = regs; + + /* Crash -- possibly showing diagnostic debug information. */ + + lldbg("Data abort. PC: %08x DFAR: %08x DFSR: %08x\n", + regs[REG_PC], dfar, dfsr); + PANIC(); + return regs; /* To keep the compiler happy */ +} diff --git a/arch/arm/src/armv7-r/arm_doirq.c b/arch/arm/src/armv7-r/arm_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..fdf392d3384d5ceab1b845f49c83b511221c0032 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_doirq.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_doirq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *arm_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Nested interrupts are not supported */ + + DEBUGASSERT(CURRENT_REGS == NULL); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#ifdef CONFIG_ARCH_FPU + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); + } +#endif + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + regs = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = NULL; + + board_autoled_off(LED_INIRQ); +#endif + return regs; +} diff --git a/arch/arm/src/armv7-r/arm_elf.c b/arch/arm/src/armv7-r/arm_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..698ecd0084fc3c80ebf5ab99b927d3a810ee4762 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_elf.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_elf.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *ehdr) +{ + /* Make sure it's an ARM executable */ + + if (ehdr->e_machine != EM_ARM) + { + bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine); + return -ENOEXEC; + } + + /* Make sure that 32-bit objects are supported */ + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + { + bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]); + return -ENOEXEC; + } + + /* Verify endian-ness */ + +#ifdef CONFIG_ENDIAN_BIG + if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) +#else + if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) +#endif + { + bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]); + return -ENOEXEC; + } + + /* Make sure the entry point address is properly aligned */ + + if ((ehdr->e_entry & 3) != 0) + { + bdbg("Entry point is not properly aligned: %08x\n", ehdr->e_entry); + return -ENOEXEC; + } + + /* TODO: Check ABI here. */ + return OK; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + int32_t offset; + unsigned int relotype; + + /* All relocations except R_ARM_V4BX depend upon having valid symbol + * information. + */ + + relotype = ELF32_R_TYPE(rel->r_info); + if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (relotype) + { + case R_ARM_NONE: + { + /* No relocation */ + } + break; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + { + bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = (*(uint32_t *)addr & 0x00ffffff) << 2; + if (offset & 0x02000000) + { + offset -= 0x04000000; + } + + offset += sym->st_value - addr; + if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000) + { + bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n", + ELF32_R_TYPE(rel->r_info), offset); + + return -EINVAL; + } + + offset >>= 2; + + *(uint32_t *)addr &= 0xff000000; + *(uint32_t *)addr |= offset & 0x00ffffff; + } + break; + + case R_ARM_ABS32: + case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ + { + bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + *(uint32_t *)addr += sym->st_value; + } + break; + + case R_ARM_V4BX: + { + bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n", + (long)addr, (long)(*(uint32_t *)addr)); + + /* Preserve only Rm and the condition code */ + + *(uint32_t *)addr &= 0xf000000f; + + /* Change instruction to 'mov pc, Rm' */ + + *(uint32_t *)addr |= 0x01a0f000; + } + break; + + case R_ARM_PREL31: + { + bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + (long)addr, (long)(*(uint32_t *)addr), sym, (long)sym->st_value); + + offset = *(uint32_t *)addr + sym->st_value - addr; + *(uint32_t *)addr = offset & 0x7fffffff; + } + break; + + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", + ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t *)addr), + sym, (long)sym->st_value); + + offset = *(uint32_t *)addr; + offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); + offset = (offset ^ 0x8000) - 0x8000; + + offset += sym->st_value; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + { + offset >>= 16; + } + + *(uint32_t *)addr &= 0xfff0f000; + *(uint32_t *)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff); + } + break; + + default: + bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info)); + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("RELA relocation not supported\n"); + return -ENOSYS; +} diff --git a/arch/arm/src/armv7-r/arm_fpuconfig.S b/arch/arm/src/armv7-r/arm_fpuconfig.S new file mode 100644 index 0000000000000000000000000000000000000000..7f81415ad46263e2e12036b207511978837d7dba --- /dev/null +++ b/arch/arm/src/armv7-r/arm_fpuconfig.S @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_fpuconfig.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "cp15.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl arm_fpuconfig + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_fpuconfig.S" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: sam_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + + .globl arm_fpuconfig + .type arm_fpuconfig, %function + +arm_fpuconfig: + + /* Enable access to CP10 and CP11 in CP15.CACR */ + + mrc CP15_CPACR(r0) + orr r0, r0, #0xf00000 + mcr CP15_CPACR(r0) + + /* Enable access to CP10 and CP11 in CP15.NSACR */ + /* REVISIT: Do we need to do this? */ + + /* Set FPEXC.EN (B30) */ + + fmrx r0, fpexc + orr r0, r0, #0x40000000 + fmxr fpexc, r0 + bx lr + .size arm_fpuconfig, . - arm_fpuconfig + .end diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..9f197063b27de976981cef4065527029a2b2d1cb --- /dev/null +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -0,0 +1,176 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_fullcontextrestore.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "up_internal.h" +#include "svcall.h" + + .file "arm_fullcontextrestore.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_fullcontextrestore + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_fullcontextrestore.S" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: up_fullcontextrestore + * + * Description: + * Restore the specified task context. Full prototype is: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * Return: + * None + * + ****************************************************************************/ + + .globl up_fullcontextrestore + .type up_fullcontextrestore, function + +up_fullcontextrestore: + + /* On entry, a1 (r0) holds address of the register save area. All other + * registers are available for use. + */ + +#ifdef CONFIG_ARCH_FPU + /* First, restore the floating point registers. Lets do this before we + * restore the ARM registers so that we have plenty of registers to + * work with. + */ + + add r1, r0, #(4*REG_S0) /* r1=Address of FP register storage */ + + /* Load all floating point registers. Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + + vldmia r1!, {s0-s31} /* Restore the full FP context */ + + /* Load the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + vmsr fpscr, r2 /* Restore the FPCSR */ +#endif + +#ifdef CONFIG_BUILD_PROTECTED + /* For the protected build, we need to be able to transition gracefully + * between kernel- and user-mode tasks. Here we do that with a system + * call; the system call will execute in kernel mode and but can return + * to either user or kernel mode. + */ + + /* Perform the System call with R0=SYS_context_restore, R1=restoreregs */ + + mov r1, r0 /* R1: restoreregs */ + mov r0, #SYS_context_restore /* R0: SYS_context_restore syscall */ + svc #0x900001 /* Perform the system call */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + +#else + /* For a flat build, we can do all of this here... Just think of this as + * a longjmp() all on steriods. + */ + + /* Recover all registers except for r0, r1, R15, and CPSR */ + + add r1, r0, #(4*REG_R2) /* Offset to REG_R2 storage */ + ldmia r1, {r2-r14} /* Recover registers */ + + /* Create a stack frame to hold the some registers */ + + sub sp, sp, #(3*4) /* Frame for three registers */ + ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */ + str r1, [sp] /* Save it at the top of the stack */ + ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */ + str r1, [sp, #4] /* Save it in the stack */ + ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */ + str r1, [sp, #8] /* Save it at the bottom of the frame */ + + /* Now we can restore the CPSR. We wait until we are completely + * finished with the context save data to do this. Restore the CPSR + * may re-enable and interrupts and we could be in a context + * where the save structure is only protected by interrupts being + * disabled. + */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ + msr cpsr, r1 /* Set the CPSR */ + + /* Now recover r0 and r1 */ + + ldr r0, [sp] + ldr r1, [sp, #4] + add sp, sp, #(2*4) + + /* Then return to the address at the stop of the stack, + * destroying the stack frame + */ + + ldr pc, [sp], #4 + +#endif + + .size up_fullcontextrestore, . - up_fullcontextrestore diff --git a/arch/arm/src/armv7-r/arm_head.S b/arch/arm/src/armv7-r/arm_head.S new file mode 100644 index 0000000000000000000000000000000000000000..a081d230b63adfbfc13082fbc07562175989652d --- /dev/null +++ b/arch/arm/src/armv7-r/arm_head.S @@ -0,0 +1,532 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_head.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm.h" +#include "cp15.h" +#include "sctlr.h" + +#include "up_internal.h" +#include "up_arch.h" + +#include + +/********************************************************************************** + * Configuration + **********************************************************************************/ + +/* Hard-coded options */ + +#undef CPU_ALIGNMENT_TRAP +#undef CPU_CACHE_ROUND_ROBIN +#undef CPU_DCACHE_DISABLE +#undef CPU_ICACHE_DISABLE +#define CPU_SCTLR_CCP15BEN 1 +#define CPU_BACKGROUND_REGION 1 +#undef CPU_DIV0_FAULT +#undef CPU_FAST_INTERRUPT +#undef CPU_IMPL_VECTORS +#undef CPU_NONMASKABLE_FIQ + +/* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case + * the boot logic must: + * + * - Configure SDRAM (if present), + * - Initialize the .data section in RAM, and + * - Clear .bss section + * + * 2. We boot in FLASH but copy ourselves to SDRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case + * the boot logic must: + * + * - Configure SDRAM (if present), + * - Copy ourself to RAM, and + * - Clear .bss section (data should be fully initialized) + * + * In this case, we assume that the logic within this file executes from FLASH. + * + * 3. There is bootloader that copies us to SDRAM (CONFIG_BOOT_RUNFROMFLASH=n && + * CONFIG_BOOT_COPYTORAM=n). In this case SDRAM was initialized by the boot + * loader, and this boot logic must: + * + * - Clear .bss section (data should be fully initialized) + */ + +/* Beginning (BOTTOM/BASE) and End+1 (TOP) of the IDLE stack. + * + * The IDLE stack is the stack that is used during intialization and, + * eventually, becomes the stack of the IDLE task when initialization + * is complete. + * + * REVISIT: There are issues here in some configurations. The stack + * pointer is initialized very early in the boot sequence. But in some + * architectures the memory supporting the stack may not yet be + * initialized (SDRAM, for example, would not be ready yet). In that + * case, ideally the IDLE stack should be in some other memory that does + * not require initialization (such as internal SRAM) + */ + +#ifndef IDLE_STACK_BASE +# define IDLE_STACK_BASE _ebss +#endif + +#define IDLE_STACK_TOP IDLE_STACK_BASE+CONFIG_IDLETHREAD_STACKSIZE + +/**************************************************************************** + * Global Symbols + ****************************************************************************/ + +/* Imported symbols */ + + .global arm_boot /* Branch to continue initialization in C */ + + .global _sbss /* Start of .bss in RAM */ + .global _ebss /* End+1 of .bss in RAM */ +#ifdef CONFIG_BOOT_RUNFROMFLASH + .global _eronly /* Where .data defaults are stored in FLASH */ + .global _sdata /* Where .data needs to reside in SDRAM */ + .global _edata +#endif +#ifdef CONFIG_ARCH_RAMFUNCS + .global _framfuncs /* Where RAM functions are stored in FLASH */ + .global _sramfuncs /* Where RAM functions needs to reside in RAM */ + .global _eramfuncs +#endif + +/* Exported symbols */ + + .global __start /* Power-up/Reset entry point */ + .global arm_data_initialize /* Perform C data initialization */ + .global g_idle_topstack /* Top of the initial/IDLE stack */ + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_head.S" + +/*************************************************************************** + * .text + ***************************************************************************/ + + .text + +/**************************************************************************** + * OS Entry Point + ****************************************************************************/ + +/* We assume the bootloader has already initialized most of the h/w for + * us and that only leaves us having to do some os specific things + * below. + */ + + .type __start, #function +__start: + + /* Make sure that we are in SVC mode with IRQs and FIQs disabled */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, r0 + + /* Set up the stack pointer and clear the frame pointer. */ + + ldr sp, .Lstackpointer + mov fp, #0 + + /* Invalidate caches and TLBs. + * + * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not + * support a CP15 operation to invalidate the entire data cache. ... + * In normal usage the only time the entire data cache has to be + * invalidated is on reset." + * + * The instruction cache is virtually indexed and physically tagged but + * the data cache is physically indexed and physically tagged. So it + * should not be an issue if the system comes up with a dirty Dcache; + * the ICache, however, must be invalidated. + */ + + mov r0, #0 + mcr CP15_BPIALL(r0) /* Invalidate entire branch prediction array */ + mcr CP15_ICIALLU(r0) /* Invalidate I-cache */ + + /* Configure the system control register (see sctrl.h) */ + + mrc CP15_SCTLR(r0) /* Get control register */ + + /* Clear bits to reset values. This is only necessary in situations like, for + * example, we get here via a bootloader and the control register is in some + * unknown state. + * + * SCTLR_M Bit 0: MPU enable bit + * SCTLR_A Bit 1: Strict alignment disabled + * SCTLR_C Bit 2: DCache disabled + * SCTLR_CCP15BEN Bit 5: CP15 barrier enable + * SCTLR_B Bit 7: Should be zero on ARMv7R + * + * SCTLR_SW Bit 10: SWP/SWPB not enabled + * SCTLR_I Bit 12: ICache disabled + * SCTLR_V Bit 13: Assume low vectors + * SCTLR_RR Bit 14: Round-robin replacement strategy. + * + * SCTLR_BR Bit 17: Background Region bit + * SCTLR_DZ Bit 19: Divide by Zero fault enable bit + * SCTLR_FI Bit 21: Fast interrupts configuration enable bit + * SCTLR_U Bit 22: Unaligned access model (always one) + * + * SCTLR_VE Bit 24: Interrupt Vectors Enable bit + * SCTLR_EE Bit 25: 0=Little endian. + * SCTLR_NMFI Bit 27: Non-maskable FIQ (NMFI) support + * SCTLR_TE Bit 30: All exceptions handled in ARM state. + * SCTLR_IE Bit 31: Instruction endian-ness. + */ + + /* Clear all configurable bits */ + + bic r0, r0, #(SCTLR_M | SCTLR_A | SCTLR_C | SCTLR_CCP15BEN | SCTLR_B) + bic r0, r0, #(SCTLR_SW | SCTLR_I | SCTLR_V | SCTLR_RR) + bic r0, r0, #(SCTLR_BR | SCTLR_DZ | SCTLR_FI | SCTLR_U) + bic r0, r0, #(SCTLR_VE | SCTLR_EE | SCTLR_NMFI | SCTLR_TE | SCTLR_IE) + + /* Set configured bits */ + +#ifdef CPU_ALIGNMENT_TRAP + /* Alignment abort enable + * + * SCTLR_A Bit 1: Strict alignment enabled + */ + + orr r0, r0, #(SCTLR_A) +#endif + +#ifndef CPU_DCACHE_DISABLE + /* Dcache enable + * + * SCTLR_C Bit 2: DCache enable + */ + + orr r0, r0, #(SCTLR_C) +#endif + +#ifdef CPU_SCTLR_CCP15BEN + /* Enable memory barriers + * + * SCTLR_CCP15BEN Bit 5: CP15 barrier enable + */ + + orr r0, r0, #(SCTLR_CCP15BEN) +#endif + +#ifndef CPU_ICACHE_DISABLE + /* Icache enable + * + * SCTLR_I Bit 12: ICache enable + */ + + orr r0, r0, #(SCTLR_I) +#endif + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Position vectors to 0xffff0000 if so configured. + * + * SCTLR_V Bit 13: High vectors + */ + + orr r0, r0, #(SCTLR_V) +#endif + +#ifdef CPU_CACHE_ROUND_ROBIN + /* Round Robin cache replacement + * + * SCTLR_RR Bit 14: Round-robin replacement strategy. + */ + + orr r0, r0, #(SCTLR_RR) +#endif + +#ifdef CPU_BACKGROUND_REGION + /* Allow PL1 access to back region when MPU is enabled + * + * SCTLR_BR Bit 17: Background Region bit + */ + + orr r0, r0, #(SCTLR_BR) +#endif + +#ifdef CPU_DIV0_FAULT + /* Enable divide by zero faults + * + * SCTLR_DZ Bit 19: Divide by Zero fault enable bit + */ + + orr r0, r0, #(SCTLR_DZ) +#endif + +#ifdef CPU_FAST_INTERRUPT + /* Fast interrupts configuration enable bit + * + * SCTLR_FI Bit 21: Fast interrupts configuration enable bit + */ + + orr r0, r0, #(SCTLR_FI) +#endif + +#ifdef CPU_IMPL_VECTORS + /* Implementation defined interrupt vectors + * + * SCTLR_VE Bit 24: Interrupt Vectors Enable bit + */ + + orr r0, r0, #(SCTLR_VE) +#endif + +#ifdef CONFIG_ENDIAN_BIG + /* Big endian mode + * + * SCTLR_EE Bit 25: 1=Big endian. + */ + + orr r0, r0, #(SCTLR_EE) +#endif + +#ifdef CPU_NONMASKABLE_FIQ + /* Non-maskable FIQ support + * + * SCTLR_NMFI Bit 27: Non-maskable FIQ (NMFI) support + */ + + orr r0, r0, #(SCTLR_NMFI) +#endif + + /* Then write the configured control register */ + + mcr CP15_SCTLR(r0) /* Write control reg */ + .rept 12 /* Some CPUs want want lots of NOPs here */ + nop + .endr + +#if 0 + /* Cortex-R/RF Errata Work-Around + * + * Errata 754269: Register corruption during a load-multiple instruction + * at an exception vector. + * Workaround: To workaround this erratum, set bit [7] of the + * Auxiliary Control Register to disable out-of-order + * completion for divide instructions. Code performance + * may be reduced depending on how often divide + * operations are used. + * NOTE: The ARMv7-A/R Architecture reference many lists the bits + * bits of the ACTLR as "implementation defined" + * + * REVISIT: I do not think this is needed because the NuttX vectors do not + * begin with an LDM instruction. + */ + + mrc CP15_ACTLR(r0) /* Read Auxiliary Control register */ + orr r0, r0, #(1 << 7) /* Disable out-of-order completion */ + mcr CP15_ACTLR(r0) /* Write Auxiliary Control register */ +#endif + +#ifndef CONFIG_ARMV7R_MEMINIT + /* Initialize .bss and .data ONLY if .bss and .data lie in RAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. arm_boot() will perform that memory initialization and + * .bss and .data can be initialized by arm_boot() by calling this + * arm_data_initialize() later. + */ + + bl arm_data_initialize +#endif + + /* Perform early C-level, platform-specific initialization. Logic + * within arm_boot() must configure SDRAM and call arm_data_initialize() + * if CONFIG_ARMV7R_MEMINIT=y. + * + * This function does not return. It must give control to os_start() + * at the completion of its initialization. + * + * Why not just call arm_boot() and branch to os_start() when it returns? + * If the stack pointer initialized above lies in SDRAM, then that may + * not be possible. Also, in the special case of the TMS570, it may + * perform a destructive test, losing the pushed content of the stack. + */ + + b arm_boot + + /* .text Data */ + +.Lstackpointer: + .long IDLE_STACK_TOP + .size __start, .-__start + +/*************************************************************************** + * Name: arm_data_initialize + ***************************************************************************/ + + .global arm_data_initialize + .type arm_data_initialize, #function + +arm_data_initialize: + + /* Zero BSS */ + + adr r0, .Linitparms + ldmia r0, {r0, r1} + + mov r2, #0 +1: + cmp r0, r1 /* Clear up to _bss_end_ */ + strcc r2, [r0], #4 + bcc 1b + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* If the .data section is in a separate, uninitialized address space, + * then we will also need to copy the initial values of of the .data + * section from the .text region into that .data region. This would + * be the case if we are executing from FLASH and the .data section + * lies in a different physical address region OR if we are support + * on-demand paging and the .data section lies in a different virtual + * address region. + */ + + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +2: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt 2b +#endif + +#ifdef CONFIG_ARCH_RAMFUNCS + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs + */ + + adr r3, .Lfuncinit + ldmia r3, {r0, r1, r2} + +3: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt 3b + +#ifndef CPU_DCACHE_DISABLE + /* Flush the copied RAM functions into physical RAM so that will + * be available when fetched into the I-Cache. + * + * Note that this is a branch, not a call and so will return + * directly to the caller without returning here. + */ + + adr r3, ..Lramfunc + ldmia r3, {r0, r1} + ldr r3, =arch_clean_dcache + b r3 +#else + /* Otherwise return to the caller */ + + bx lr +#endif +#else + /* Return to the caller */ + + bx lr +#endif + + /* .text Data: + * + * _sbss is the start of the BSS region (see linker script) + * _ebss is the end of the BSS regsion (see linker script) + * + * Typical Configuration: + * The idle task stack starts at the end of BSS and is of size + * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there + * until the end of memory. See g_idle_topstack below. + */ + + .type .Linitparms, %object +.Linitparms: + .long _sbss + .long _ebss + +#ifdef CONFIG_BOOT_RUNFROMFLASH + .type .Ldatainit, %object +.Ldatainit: + .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata +#endif + +#ifdef CONFIG_ARCH_RAMFUNCS + .type .Lfuncinit, %object +.Lfuncinit: + .long _framfuncs /* Where RAM functions are stored in FLASH */ +.Lramfuncs: + .long _sramfuncs /* Where RAM functions needs to reside in RAM */ + .long _eramfuncs +#endif + .size arm_data_initialize, . - arm_data_initialize + +/*************************************************************************** + * .rodata + ***************************************************************************/ + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to .Lstackpointer + * above. + */ + + .section .rodata, "a" + .align 4 + .type g_idle_topstack, object +g_idle_topstack: + .long IDLE_STACK_TOP + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/armv7-r/arm_initialstate.c b/arch/arm/src/armv7-r/arm_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..2150020510e05a194964fb309d895cca340ce08c --- /dev/null +++ b/arch/arm/src/armv7-r/arm_initialstate.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_initialstate.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of + * the new TCB. + * + * This function must setup the initial architecture registers and/or + * stack so that execution will begin at tcb->start on the next context + * switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + uint32_t cpsr; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC + if (tcb->dspace != NULL) + { + /* Set the PIC base register (probably R10) to the address of the + * alloacated D-Space region. + */ + + xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; + } +#endif + + /* Set supervisor-mode and disable FIQs, regardless of how NuttX is + * configured and of what kind of thread is being started. That is + * because all threads, even user-mode threads will start in kernel + * trampoline at task_start() or pthread_start(). The thread's + * privileges will be dropped before transitioning to user code. + */ + + cpsr = PSR_MODE_SVC; + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + /* Disable interrupts (both IRQs and FIQs) */ + + cpsr |= (PSR_I_BIT | PSR_F_BIT); + +#else /* CONFIG_SUPPRESS_INTERRUPTS */ + /* Leave IRQs enabled (Also FIQs if CONFIG_ARMV7R_DECODEFIQ is selected) */ + +#ifndef CONFIG_ARMV7R_DECODEFIQ + + cpsr |= PSR_F_BIT; + +#endif /* !CONFIG_ARMV7R_DECODEFIQ */ +#endif /* CONFIG_SUPPRESS_INTERRUPTS */ + + xcp->regs[REG_CPSR] = cpsr; +} diff --git a/arch/arm/src/armv7-r/arm_l2cc_pl310.c b/arch/arm/src/armv7-r/arm_l2cc_pl310.c new file mode 100644 index 0000000000000000000000000000000000000000..e019e70e95f2e95d4a1581da09d3f350585c29d1 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_l2cc_pl310.c @@ -0,0 +1,874 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/chip/arm-l2cc_pl310.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2, + * Technical Reference Manual, ARM DDI 0246F (ID011711), ARM + * + * NOTE: This logic is incompatible with older versions of the PL310! + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "l2cc.h" +#include "l2cc_pl310.h" + +#ifdef CONFIG_ARMV7R_L2CC_PL310 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***********************************************************/ +/* Number of ways depends on ARM configuration */ + +#if defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY) +# define PL310_NWAYS 8 +# define PL310_WAY_MASK 0x000000ff +#elif defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY) +# define PL310_NWAYS 16 +# define PL310_WAY_MASK 0x0000ffff +#else +# error "Number of ways not selected" +#endif + +/* The size of one depends on ARM configuration */ + +#if defined(CONFIG_ARMV7R_WAYSIZE_16KB) +# define PL310_WAYSIZE (16 * 1024) +#elif defined(CONFIG_ARMV7R_WAYSIZE_32KB) +# define PL310_WAYSIZE (32 * 1024) +#elif defined(CONFIG_ARMV7R_WAYSIZE_64KB) +# define PL310_WAYSIZE (64 * 1024) +#elif defined(CONFIG_ARMV7R_WAYSIZE_128KB) +# define PL310_WAYSIZE (128 * 1024) +#elif defined(CONFIG_ARMV7R_WAYSIZE_256KB) +# define PL310_WAYSIZE (256 * 1024) +#elif defined(CONFIG_ARMV7R_WAYSIZE_512KB) +# define PL310_WAYSIZE (512 * 1024) +#else +# error "Way size not selected" +#endif + +/* The size of the cache is then the product of the number of ways times + * the size of each way. + */ + +#define PL310_CACHE_SIZE (PL310_NWAYS * PL310_WAYSIZE) + +/* Use for aligning addresses to a cache line boundary */ + +#define PL310_CACHE_LINE_MASK (PL310_CACHE_LINE_SIZE - 1) + +/* Configurable options + * + * REVISIT: Currently there are not configuration options. All values + * are just set to the default. + */ + +/* Bit 0: Full line zero enable + * + * Default: 0=Full line of write zero behavior disabled + */ + +#define L2CC_ACR_FLZE_CONFIG (0) /* 0=Full line of write zero behavior disabled */ + +/* Bit 10: High Priority for SO and Dev Reads Enable + * + * Default: 0=Strongly Ordered and Device reads have lower priority than + * cacheable accesses + */ + +#define L2CC_ACR_HPSO_CONFIG (0) /* 0=Have lower priority than cache */ + +/* Bit 11: Store Buffer Device Limitation Enable + * + * Default: 0=Store buffer device limitation disabled + */ + +#define L2CC_ACR_SBDLE_CONFIG (0) /* 0=Store buffer device limitation disabled */ + +/* Bit 12: Exclusive Cache Configuration + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EXCC_CONFIG (0) /* 0=Disabled */ + +/* Bit 13: Shared Attribute Invalidate Enable + * + * Default: 0=Shared invalidate behavior disabled + */ + +#define L2CC_ACR_SAIE_CONFIG (0) /* 0=Shared invalidate behavior disabled */ + +/* Bit 20: Event Monitor Bus Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_EMBEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 21: Parity Enable + * + * Default: 0=Disabled + */ + +#define L2CC_ACR_PEN_CONFIG (0) /* 0=Disabled */ + +/* Bit 22: Shared Attribute Override Enable + * + * Default: 0=Treats shared accesses as specified in the TRM + */ + +#define L2CC_ACR_SAOEN_CONFIG (0) /* 0=As specified in the TRM */ + +/* Bits 23-24: Force Write Allocate + * + * Default: 0=Use AWCACHE attributes for WA + */ + +#define L2CC_ACR_FWA_CONFIG L2CC_ACR_FWA_AWCACHE /* Use AWCACHE attributes for WA */ + +/* Bit 25: Cache Replacement Policy + * + * Default: 1=Round robin replacement policy + */ + +#define L2CC_ACR_CRPOL_CONFIG L2CC_ACR_CRPOL /* 1=Round robin replacement policy */ + +/* Bit 26: Non-Secure Lockdown Enable + * + * Default: 0=Lockdown registers cannot be modified using non-secure acceses + */ + +#define L2CC_ACR_NSLEN_CONFIG (0) /* 0=Secure access only */ + +/* Bit 27: Non-Secure Interrupt Access Control + * + * Default: 0=Interrupt Clear and Mask can only be modified or read with + * secure accesses + */ + +#define L2CC_ACR_NSIAC_CONFIG (0) /* 0=Secure access only */ + +/* Bit 28: Data Prefetch Enable + * + * Default: 0=Data prefetching disabled + */ + +#define L2CC_ACR_DPEN_CONFIG (0) /* 0=Data prefetching disabled */ + +/* Bit 29: Instruction Prefetch Enable + * + * Default: 0=Instruction prefetching disabled + */ + +#define L2CC_ACR_IPEN_CONFIG (0) /* 0=Instruction prefetching disabled */ + +/* Bit 30: Early BRESP enable + * + * Default: 0=Early BRESP disabled + */ + +#define L2CC_ACR_EBRESP_CONFIG (0) /* 0=Early BRESP disabled */ + +#define L2CC_ACR_CONFIG \ + (L2CC_ACR_FLZE_CONFIG | L2CC_ACR_HPSO_CONFIG | L2CC_ACR_SBDLE_CONFIG | \ + L2CC_ACR_EXCC_CONFIG | L2CC_ACR_SAIE_CONFIG | L2CC_ACR_EMBEN_CONFIG | \ + L2CC_ACR_PEN_CONFIG | L2CC_ACR_SAOEN_CONFIG | L2CC_ACR_FWA_CONFIG | \ + L2CC_ACR_CRPOL_CONFIG | L2CC_ACR_NSLEN_CONFIG | L2CC_ACR_NSIAC_CONFIG | \ + L2CC_ACR_DPEN_CONFIG | L2CC_ACR_IPEN_CONFIG | L2CC_ACR_EBRESP_CONFIG) + +#define L2CC_ACR_ALLCONFIGS (0x7f303c01) +#define L2CC_ACR_CONFIGMASK (L2CC_ACR_SBZ | L2CC_ACR_ALLCONFIGS) + +/* Filter end address */ + +#define CONFIG_PL310_FLEND (CONFIG_PL310_FLSTRT + CONFIG_PL310_FLSIZE) + +/* Block size. Used to break up long operations so that interrupts are not + * disabled for a long time. + */ + +#define PL310_GULP_SIZE 4096 + +/* Misc commoly defined and re-defined things */ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef OK +# define OK 0 +#endif + +/* Data synchronization barrier */ + +#define dsb(a) __asm__ __volatile__ ("dsb " #a : : : "memory") + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pl310_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pl310_flush_all(void) +{ + /* Flush all ways by writing the set of ways to be cleaned to the Clean + * Invalidate Way Register (CIWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_CIWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CIWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_l2ccinitialize(void) +{ + uint32_t regval; + int i; + + /* Make sure that this is a PL310 cache, version r3p2. + * + * REVISIT: The SAMA5D4 is supposed to report its ID as 0x410000C8 which is + * r3p2, but the chip that I have actually* reports 0x410000C9 which is some + * later revision. + */ + + //DEBUGASSERT((getreg32(L2CC_IDR) & L2CC_IDR_REV_MASK) == L2CC_IDR_REV_R3P2); + + /* Make sure that actual cache configuration agrees with the configured + * cache configuration. + */ + + +#if defined(CONFIG_ARMV7R_ASSOCIATIVITY_8WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 0); +#elif defined(CONFIG_ARMV7R_ASSOCIATIVITY_16WAY) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_ASS) == 1); +#else +# error No associativity selected +#endif + +#if defined(CONFIG_ARMV7R_WAYSIZE_16KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_16KB); +#elif defined(CONFIG_ARMV7R_WAYSIZE_32KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_32KB); +#elif defined(CONFIG_ARMV7R_WAYSIZE_64KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_64KB); +#elif defined(CONFIG_ARMV7R_WAYSIZE_128KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_128KB); +#elif defined(CONFIG_ARMV7R_WAYSIZE_256KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_256KB); +#elif defined(CONFIG_ARMV7R_WAYSIZE_512KB) + DEBUGASSERT((getreg32(L2CC_ACR) & L2CC_ACR_WAYSIZE_MASK) == L2CC_ACR_WAYSIZE_512KB); +#else +# error No way size selected +#endif + + /* L2 configuration can only be changed if the cache is disabled, + * + * NOTE: This register access will fail if we are not in secure more. + */ + + if ((getreg32(L2CC_CR) & L2CC_CR_L2CEN) == 0) + { +#if defined(CONFIG_PL310_TRCR_TSETLAT) && defined(CONFIG_PL310_TRCR_TRDLAT) && \ + defined(CONFIG_PL310_TRCR_TWRLAT) + /* Configure Tag RAM control */ + + regval = ((CONFIG_PL310_TRCR_TSETLAT - 1) << L2CC_TRCR_TSETLAT_SHIFT) + ((CONFIG_PL310_TRCR_TRDLAT - 1) << L2CC_TRCR_TRDLAT_SHIFT) | + ((CONFIG_PL310_TRCR_TWRLAT - 1) << L2CC_TRCR_TWRLAT_SHIFT); + putreg32(regval, L2CC_TRCR); +#endif + +#if defined(CONFIG_PL310_DRCR_DSETLAT) && defined(CONFIG_PL310_DRCR_DRDLAT) && \ + defined(CONFIG_PL310_DRCR_DWRLAT) + /* Configure Data RAM control */ + + regval = ((CONFIG_PL310_DRCR_DSETLAT - 1) << L2CC_DRCR_DSETLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DRDLAT - 1) << L2CC_DRCR_DRDLAT_SHIFT) | + ((CONFIG_PL310_DRCR_DWRLAT - 1) << L2CC_DRCR_DWRLAT_SHIFT); + putreg32(regval, L2CC_DRCR); +#endif + +#ifdef PL310_ADDRESS_FILTERING +#if defined(CONFIG_PL310_FLSTRT) && defined(CONFIG_PL310_FLSIZE) + /* Configure the address filter */ + + regval = (CONFIG_PL310_FLEND + ~L2CC_FLEND_MASK) & L2CC_FLEND_MASK; + putreg32(regval, L2CC_FLEND); + + regval = (CONFIG_PL310_FLSTRT & L2CC_FLSTRT_MASK) | L2CC_FLSTRT_ENABLE; + putreg32(regval | L2X0_ADDR_FILTER_EN, L2CC_FLSTRT); +#endif +#endif + + /* Make sure that the memory is not locked down */ + + for (i = 0; i < PL310_NLOCKREGS; i++) + { + putreg32(0, L2CC_DLKR(i)); + putreg32(0, L2CC_ILKR(i)); + } + + /* Configure the cache properties */ + + regval = getreg32(L2CC_ACR); + regval &= ~L2CC_ACR_CONFIGMASK; + regval |= L2CC_ACR_CONFIG; + putreg32(regval, L2CC_ACR); + + /* Invalidate and enable the cache */ + + l2cc_invalidate_all(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + } + + lldbg("(%d ways) * (%d bytes/way) = %d bytes\n", + PL310_NWAYS, PL310_WAYSIZE, PL310_CACHE_SIZE); +} + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_enable(void) +{ + irqstate_t flags; + + /* Invalidate and enable the cache (must be disabled to do this!) */ + + flags = enter_critical_section(); + l2cc_invalidate_all(); + putreg32(L2CC_CR_L2CEN, L2CC_CR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_disable(void) +{ + irqstate_t flags; + + /* Flush all ways using the Clean Invalidate Way Register (CIWR). */ + + flags = enter_critical_section(); + pl310_flush_all(); + + /* Disable the L2CC-P310 L2 cache by clearing the Control Register (CR) */ + + putreg32(0, L2CC_CR); + dsb(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_sync(void) +{ + irqstate_t flags; + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate all ways using the Invalidate Way Register (IWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate_all(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Invalidate all ways */ + + flags = enter_critical_section(); + + /* Disable the L2 cache while we invalidate it */ + + regval = getreg32(L2CC_CR); + l2cc_disable(); + + /* Invalidate all ways by writing the bit mask of ways to be invalidated + * the Invalidate Way Register (IWR). + */ + + putreg32(PL310_WAY_MASK, L2CC_IWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_IWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + + /* Then re-enable the L2 cache if it was enabled before */ + + putreg32(regval, L2CC_CR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses by writing to the Invalidate Physical + * Address Line Register (IPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t invalsize; + uintptr_t gulpend; + irqstate_t flags; + + /* Check if the start address is aligned with a cacheline */ + + flags = enter_critical_section(); + if ((startaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush the cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(startaddr, L2CC_CIPALR); + + /* Then start invalidating at the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Check if the end address is aligned with a cache line */ + + if ((endaddr & PL310_CACHE_LINE_MASK) != 0) + { + /* No.. align down and flush cache line by writing the address to + * the Clean Invalidate Physical Address Line Register (CIPALR). + */ + + endaddr &= ~PL310_CACHE_LINE_MASK; + putreg32(endaddr, L2CC_CIPALR); + } + + leave_critical_section(flags); + + /* Loop, invalidated the address range by cache line. Interrupts are re- + * enabled momentarily every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to invalidate. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + invalsize = endaddr - startaddr; + gulpend = startaddr + MIN(invalsize, PL310_GULP_SIZE); + + /* Disable interrupts and invalidate the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Invalidate the cache line by writing the address to the + * Invalidate Physical Address Line Register (IPALR). + */ + + putreg32(startaddr, L2CC_IPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean all ways by using the Clean Ways Register (CWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean_all(void) +{ + irqstate_t flags; + + /* Clean all ways by writing the set of ways to be cleaned to the Clean + * Ways Register (CWR). + */ + + flags = enter_critical_section(); + putreg32(PL310_WAY_MASK, L2CC_CWR); + + /* Wait for cache operation by way to complete */ + + while ((getreg32(L2CC_CWR) & PL310_WAY_MASK) != 0); + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean the cache line over a range of addresses uing the Clean Physical + * Address Line Register (CPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr) +{ + uintptr_t cleansize; + uintptr_t gulpend; + irqstate_t flags; + + /* If the range of addresses to clean is as large or larger the L2 cache, + * then just clean the whole thing. + */ + + cleansize = endaddr - startaddr; + if (cleansize >= PL310_CACHE_SIZE) + { + l2cc_clean_all(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Clean the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + cleansize = endaddr - startaddr; + gulpend = startaddr + MIN(cleansize, PL310_GULP_SIZE); + + /* Disable interrupts and clean the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Clean the cache line by writing the address to the Clean + * Physical Address Line Register (CPALR). + */ + + putreg32(startaddr, L2CC_CPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush all ways using the Clean Invalidate Way Register (CIWR). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush_all(void) +{ + irqstate_t flags; + + /* Flush all ways using the Clean Invalidate Way Register (CIWR). */ + + flags = enter_critical_section(); + pl310_flush_all(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address by using the Clean Invalidate Physical Address + * Line Register (CIPALR) repeatedly. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush(uint32_t startaddr, uint32_t endaddr) +{ + uintptr_t flushsize; + uintptr_t gulpend; + irqstate_t flags; + + /* If the range of addresses to flush is as large or larger the L2 cache, + * then just flush the whole thing. + */ + + flushsize = endaddr - startaddr; + if (flushsize >= PL310_CACHE_SIZE) + { + l2cc_flush_all(); + return; + } + + /* Align the starting address to a cache line boundary */ + + startaddr &= ~PL310_CACHE_LINE_MASK; + + /* Flush the L2 cache by cache line, enabling interrupts momentarily + * every PL310_GULP_SIZE bytes. + */ + + while (startaddr < endaddr) + { + /* Get the size of the next gulp of cache lines to flush. We do + * this in small chunks so that we do not have to keep interrupts + * disabled throughout the whole flush. + */ + + flushsize = endaddr - startaddr; + gulpend = startaddr + MIN(flushsize, PL310_GULP_SIZE); + + /* Disable interrupts and flush the gulp */ + + flags = enter_critical_section(); + while (startaddr < gulpend) + { + /* Flush the cache line by writing the address to the Clean + * Invalidate Physical Address Line Register (CIPALR). + */ + + putreg32(startaddr, L2CC_CIPALR); + + /* Start of the next cache line */ + + startaddr += PL310_CACHE_LINE_SIZE; + } + + /* Enable interrupts momentarily */ + + leave_critical_section(flags); + } + + /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and + * EB, are empty. + */ + + flags = enter_critical_section(); + putreg32(0, L2CC_CSR); + leave_critical_section(flags); +} + +#endif /* CONFIG_ARMV7R_L2CC_PL310 */ diff --git a/arch/arm/src/armv7-r/arm_memcpy.S b/arch/arm/src/armv7-r/arm_memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..b88a0e086912fe08316aa0ac641e20c8ecc0f797 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_memcpy.S @@ -0,0 +1,433 @@ +/************************************************************************************ + * nuttx/arch/arm/src/armv7-r/arm_memcpy.S + * + * ARMv7-R optimised memcpy, based on the ARMv7-M version contributed by Mike Smith. + * Apparently in the public domain and is re-released here under the modified BSD + * license: + * + * Obtained via a posting on the Stellaris forum: + * http://e2e.ti.com/support/microcontrollers/\ + * stellaris_arm_cortex-m3_microcontroller/f/473/t/44360.aspx + * + * Posted by rocksoft on Jul 24, 2008 10:19 AM + * + * Hi, + * + * I recently finished a "memcpy" replacement and thought it might be useful for + * others... + * + * I've put some instructions and the code here: + * + * http://www.rock-software.net/downloads/memcpy/ + * + * Hope it works for you as well as it did for me. + * + * Liam. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .global memcpy + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_memcpy.S" + +/************************************************************************************ + * .text + ************************************************************************************/ + + .text + +/************************************************************************************ + * Private Constant Data + ************************************************************************************/ + +/* We have 16 possible alignment combinations of src and dst, this jump table + * directs the copy operation + * + * Bits: Src=00, Dst=00 - Long to Long copy + * Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=10 - Long to Half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + * Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=01 - Byte before half word to byte before half word - + * Same alignment + * Bits: Src=01, Dst=10 - Byte before half word to half word + * Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * Bits: Src=10, Dst=00 - Half word to long word + * Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * Bits: Src=10, Dst=11 - Half word to byte before long word + * Bits: Src=11, Dst=00 - Byte before long word to long word + * Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - + * Same alignment + */ + +MEM_DataCopyTable: + .byte (MEM_DataCopy0 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy1 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy2 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy3 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy4 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy5 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy6 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy7 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy8 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy9 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy10 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy11 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy12 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy13 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy14 - MEM_DataCopyJump) >> 1 + .byte (MEM_DataCopy15 - MEM_DataCopyJump) >> 1 + + .align 2 + +MEM_LongCopyTable: + .byte (MEM_LongCopyEnd - MEM_LongCopyJump) >> 1 /* 0 bytes left */ + .byte 0 /* 4 bytes left */ + .byte (1 * 10) >> 1 /* 8 bytes left */ + .byte (2 * 10) >> 1 /* 12 bytes left */ + .byte (3 * 10) >> 1 /* 16 bytes left */ + .byte (4 * 10) >> 1 /* 20 bytes left */ + .byte (5 * 10) >> 1 /* 24 bytes left */ + .byte (6 * 10) >> 1 /* 28 bytes left */ + .byte (7 * 10) >> 1 /* 32 bytes left */ + .byte (8 * 10) >> 1 /* 36 bytes left */ + + .align 2 + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/************************************************************************************ + * Name: memcpy + * + * Description: + * Optimised "general" copy routine + * + * Input Parameters: + * r0 = destination, r1 = source, r2 = length + * + * Returned Value: + * r0 = destination r1-r3 burned + * + ************************************************************************************/ + + .align 4 + +memcpy: + push {r14} + push {r0} + bl _do_memcpy + pop {r0} + pop {pc} + + .align 4 + +_do_memcpy: + push {r14} + + /* This allows the inner workings to "assume" a minimum amount of bytes */ + /* Quickly check for very short copies */ + + cmp r2, #4 + blt.n MEM_DataCopyBytes + + and r14, r0, #3 /* Get destination alignment bits */ + bfi r14, r1, #2, #2 /* Get source alignment bits */ + ldr r3, =MEM_DataCopyTable /* Jump table base */ + tbb [r3, r14] /* Perform jump on src/dst alignment bits */ +MEM_DataCopyJump: + + .align 4 + +/* Bits: Src=01, Dst=01 - Byte before half word to byte before half word - Same alignment + * 3 bytes to read for long word aligning + */ + +MEM_DataCopy5: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=10 - Half word to half word - Same Alignment + * 2 bytes to read for long word aligning + */ + +MEM_DataCopy10: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=11 - Byte before long word to Byte before long word - Same alignment + * 1 bytes to read for long word aligning + */ + +MEM_DataCopy15: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=00 - Long to Long copy */ + +MEM_DataCopy0: + /* Save regs that may be used by memcpy */ + + push {r4-r12} + + /* Check for short word-aligned copy */ + + cmp r2, #0x28 + blt.n MEM_DataCopy0_2 + + /* Bulk copy loop */ + +MEM_DataCopy0_1: + ldmia r1!, {r3-r12} + stmia r0!, {r3-r12} + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy0_1 + + /* Copy remaining long words */ + +MEM_DataCopy0_2: + /* Copy remaining long words */ + + ldr r14, =MEM_LongCopyTable + lsr r11, r2, #0x02 + tbb [r14, r11] + + /* longword copy branch table anchor */ + +MEM_LongCopyJump: + ldr.w r3, [r1], #0x04 /* 4 bytes remain */ + str.w r3, [r0], #0x04 + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r4} /* 8 bytes remain */ + stmia.w r0!, {r3-r4} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r5} /* 12 bytes remain */ + stmia.w r0!, {r3-r5} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r6} /* 16 bytes remain */ + stmia.w r0!, {r3-r6} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r7} /* 20 bytes remain */ + stmia.w r0!, {r3-r7} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r8} /* 24 bytes remain */ + stmia.w r0!, {r3-r8} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r9} /* 28 bytes remain */ + stmia.w r0!, {r3-r9} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r10} /* 32 bytes remain */ + stmia.w r0!, {r3-r10} + b.n MEM_LongCopyEnd + ldmia.w r1!, {r3-r11} /* 36 bytes remain */ + stmia.w r0!, {r3-r11} + +MEM_LongCopyEnd: + pop {r4-r12} + and r2, r2, #0x03 /* All the longs have been copied */ + + /* Deal with up to 3 remaining bytes */ + +MEM_DataCopyBytes: + /* Deal with up to 3 remaining bytes */ + + cmp r2, #0x00 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + subs r2, r2, #0x01 + it eq + popeq {pc} + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + pop {pc} + + .align 4 + +/* Bits: Src=01, Dst=11 - Byte before half word to byte before long word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy7: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=00 - Half word to long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy8: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=01 - Byte before long word to byte before half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy13: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=10 - Long to Half word */ + +MEM_DataCopy2: + cmp r2, #0x28 + blt.n MEM_DataCopy2_1 + + /* Save regs */ + + push {r4-r12} + + /* Bulk copy loop */ + +MEM_DataCopy2_2: + ldmia r1!, {r3-r12} + + strh r3, [r0], #0x02 + + lsr r3, r3, #0x10 + bfi r3, r4, #0x10, #0x10 + lsr r4, r4, #0x10 + bfi r4, r5, #0x10, #0x10 + lsr r5, r5, #0x10 + bfi r5, r6, #0x10, #0x10 + lsr r6, r6, #0x10 + bfi r6, r7, #0x10, #0x10 + lsr r7, r7, #0x10 + bfi r7, r8, #0x10, #0x10 + lsr r8, r8, #0x10 + bfi r8, r9, #0x10, #0x10 + lsr r9, r9, #0x10 + bfi r9, r10, #0x10, #0x10 + lsr r10, r10, #0x10 + bfi r10, r11, #0x10, #0x10 + lsr r11, r11, #0x10 + bfi r11, r12, #0x10, #0x10 + stmia r0!, {r3-r11} + lsr r12, r12, #0x10 + strh r12, [r0], #0x02 + + sub r2, r2, #0x28 + cmp r2, #0x28 + bge.n MEM_DataCopy2_2 + pop {r4-r12} + +MEM_DataCopy2_1: /* Read longs and write 2 x half words */ + cmp r2, #4 + blt.n MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strh r3, [r0], #0x02 + sub r2, r2, #0x04 + b.n MEM_DataCopy2 + +/* Bits: Src=01, Dst=00 - Byte before half word to long + * Bits: Src=01, Dst=10 - Byte before half word to half word + * 3 bytes to read for long word aligning the source + */ + +MEM_DataCopy4: +MEM_DataCopy6: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=10, Dst=01 - Half word to byte before half word + * Bits: Src=10, Dst=11 - Half word to byte before long word + * 2 bytes to read for long word aligning the source + */ + +MEM_DataCopy9: +MEM_DataCopy11: + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=11, Dst=00 -chm Byte before long word to long word + * Bits: Src=11, Dst=11 - Byte before long word to half word + * 1 byte to read for long word aligning the source + */ + +MEM_DataCopy12: +MEM_DataCopy14: + /* Read B and write B */ + + ldrb r3, [r1], #0x01 + strb r3, [r0], #0x01 + sub r2, r2, #0x01 + +/* Bits: Src=00, Dst=01 - Long to Byte before half word + * Bits: Src=00, Dst=11 - Long to Byte before long word + */ + +MEM_DataCopy1: /* Read longs, write B->H->B */ +MEM_DataCopy3: + cmp r2, #4 + blt MEM_DataCopyBytes + ldr r3, [r1], #0x04 + strb r3, [r0], #0x01 + lsr r3, r3, #0x08 + strh r3, [r0], #0x02 + lsr r3, r3, #0x10 + strb r3, [r0], #0x01 + sub r2, r2, #0x04 + b.n MEM_DataCopy3 + + .size memcpy, .-memcpy + .end diff --git a/arch/arm/src/armv7-r/arm_mpu.c b/arch/arm/src/armv7-r/arm_mpu.c new file mode 100644 index 0000000000000000000000000000000000000000..93bda13385025c94fff8d97b5f5197d7d6fd04ab --- /dev/null +++ b/arch/arm/src/armv7-r/arm_mpu.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_mpu.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "mpu.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ARM_MPU_NREGIONS +# define CONFIG_ARM_MPU_NREGIONS 8 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These sets represent the set of disabled memory sub-regions. A bit set + * corresponds to a disabled sub-region; the LS bit corresponds to the first + * region. + * + * The g_ms_regionmask array is indexed by the number of subregions at the + * end of the region: 0 means no sub-regions are available(0xff) and 8 means + * all subregions are available (0x00). + */ + +static const uint8_t g_ms_regionmask[9] = +{ + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 +}; + +/* The g_ls_regionmask array is indexed by the number of subregions at the + * beginning of the region: 0 means no sub-regions need be disabled (0x00) + * and 8 means all subregions must be disabled (0xff). + */ + +static const uint8_t g_ls_regionmask[9] = +{ + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff +}; + +/* The next available region number */ + +static uint8_t g_region; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_subregion_ms + * + * Description: + * Given (1) the size of the memory to be mapped and (2) the log2 size + * of the mapping to use, determine the minimal sub-region set at the + * to be disabled at the higher end of the region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t asize; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Size Mask Size Shift Sub-Regions Bitset + * 0x1000 0x01ff 0x1000 9 8 0x00 + * 0x0c00 0x01ff 0x0c00 9 6 0xc0 + * 0x0c40 0x01ff 0x0e00 9 7 0x80 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + asize = (size + mask) & ~mask; /* Adjusted size */ + nsrs = asize >> (l2size-3); /* Number of subregions */ + return g_ms_regionmask[nsrs]; +} + +/**************************************************************************** + * Name: mpu_subregion_ls + * + * Description: + * Given (1) the offset to the beginning of data in the region and (2) the + * log2 size of the mapping to use, determine the minimal sub-region set + * to span that memory region sub-region set at the to be disabled at the + * higher end of the region + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t aoffset; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Offset Mask Offset Shift Sub-Regions Bitset + * 0x0000 0x01ff 0x0000 9 8 0x00 + * 0x0400 0x01ff 0x0400 9 6 0x03 + * 0x02c0 0x01ff 0x0200 9 7 0x01 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + aoffset = offset & ~mask; /* Adjusted offset */ + nsrs = aoffset >> (l2size-3); /* Number of subregions */ + return g_ls_regionmask[nsrs]; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_allocregion + * + * Description: + * Allocate the next region + * + * Assumptions: + * - Regions are never deallocated + * - Regions are only allocated early in initialization, so no special + * protection against re-entrancy is required; + * + ****************************************************************************/ + +unsigned int mpu_allocregion(void) +{ + DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS); + return (unsigned int)g_region++; +} + +/**************************************************************************** + * Name: mpu_log2regionceil + * + * Description: + * Determine the smallest value of l2size (log base 2 size) such that the + * following is true: + * + * size <= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionceil(size_t size) +{ + uint8_t l2size; + + /* The minimum permitted region size is 32 bytes (log2(32) = 5. */ + + for (l2size = 5; l2size < 32 && size > (1 << l2size); l2size++); + return l2size; +} + +/**************************************************************************** + * Name: mpu_log2regionfloor + * + * Description: + * Determine the largest value of l2size (log base 2 size) such that the + * following is true: + * + * size >= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionfloor(size_t size) +{ + uint8_t l2size = mpu_log2regionceil(size); + + if (l2size > 4 && size < (1 << l2size)) + { + l2size--; + } + + return l2size; +} + +/**************************************************************************** + * Name: mpu_subregion + * + * Description: + * Given the size of the (1) memory to be mapped and (2) the log2 size + * of the mapping to use, determine the minimal sub-region set to span + * that memory region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size) +{ + uint32_t mask; + size_t offset; + uint32_t ret; + + /* Eight subregions are supported. The representation is as an 8-bit + * value with the LS bit corresponding to subregion 0. A bit is set + * to disable the sub-region. + * + * l2size: Log2 of the actual region size is <= (1 << l2size); + */ + + DEBUGASSERT(l2size > 4 && size <= (1 << l2size)); + + /* For region sizes of 32, 64, and 128 bytes, the effect of setting + * one or more bits of the SRD field to 1 is UNPREDICTABLE. + */ + + if (l2size < 8) + { + return 0; + } + + /* Calculate the offset of the base address into the aligned region. */ + + mask = (1 << l2size) - 1; + offset = base & mask; + + /* Calculate the mask need to handle disabled subregions at the end of the + * region + */ + + ret = mpu_subregion_ms(size + offset, l2size); + + /* Then OR in the mask need to handle disabled subregions at the beginning + * of the region. + */ + + ret |= mpu_subregion_ls(offset, l2size); + return ret; +} diff --git a/arch/arm/src/armv7-r/arm_prefetchabort.c b/arch/arm/src/armv7-r/arm_prefetchabort.c new file mode 100644 index 0000000000000000000000000000000000000000..bf16d194676ce28f4402db9c4330a28c73c90c6a --- /dev/null +++ b/arch/arm/src/armv7-r/arm_prefetchabort.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_prefetchabort.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_prefetchabort + * + * Description; + * This is the prefetch abort exception handler. The ARM prefetch abort + * exception occurs when a memory fault is detected during an an + * instruction fetch. + * + ****************************************************************************/ + +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = regs; + + /* Crash -- possibly showing diagnostic debug information. */ + + lldbg("Prefetch abort. PC: %08x IFAR: %08x IFSR: %08x\n", + regs[REG_PC], ifar, ifsr); + PANIC(); + return regs; /* To keep the compiler happy */ +} diff --git a/arch/arm/src/armv7-r/arm_releasepending.c b/arch/arm/src/armv7-r/arm_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..89827085907498d7edaab83db8dd1fab47e3c817 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_releasepending.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_releasepending.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to + * switch contexts. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_reprioritizertr.c b/arch/arm/src/armv7-r/arm_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..4fed13e8f272ca7b43fd90e1e65109e3bc18ae63 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_reprioritizertr.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_reprioritizertr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/arm/src/armv7-r/arm_restorefpu.S b/arch/arm/src/armv7-r/arm_restorefpu.S new file mode 100644 index 0000000000000000000000000000000000000000..1557986e5561bba5d37947652380fe5d77bf2f72 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_restorefpu.S @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_restorefpu.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_FPU + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_restorefpu + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_restorefpu.S" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_restorefpu + * + * Description: + * Given the pointer to a register save area (in R0), restore the state of the + * floating point registers. + * + * C Function Prototype: + * void up_restorefpu(const uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area containing the floating point + * registers. + * + * Returned Value: + * This function does not return anything explicitly. However, it is called from + * interrupt level assembly logic that assumes that r0 is preserved. + * + ************************************************************************************/ + + .globl up_restorefpu + .type up_restorefpu, function + +up_restorefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Load all floating point registers. Registers are loaded in numeric order, + * s0, s1, ... in increasing address order. + */ + + vldmia r1!, {s0-s31} /* Restore the full FP context */ + + /* Load the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + ldr r2, [r1], #4 /* Fetch the floating point control and status register */ + vmsr fpscr, r2 /* Restore the FPCSR */ + bx lr + + .size up_restorefpu, .-up_restorefpu +#endif /* CONFIG_ARCH_FPU */ + .end + diff --git a/arch/arm/src/armv7-r/arm_savefpu.S b/arch/arm/src/armv7-r/arm_savefpu.S new file mode 100644 index 0000000000000000000000000000000000000000..af637ada9fcdd499a30f26468c4d4f5d24286197 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_savefpu.S @@ -0,0 +1,106 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_savefpu.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_FPU + + .file "arm_savefpu.S" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl up_savefpu + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_savefpu + * + * Description: + * Given the pointer to a register save area (in R0), save the state of the + * floating point registers. + * + * C Function Prototype: + * void up_savefpu(uint32_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area in which to save the floating point + * registers + * + * Returned Value: + * None + * + ************************************************************************************/ + + .globl up_savefpu + .type up_savefpu, function + +up_savefpu: + + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Store all floating point registers. Registers are stored in numeric order, + * s0, s1, ... in increasing address order. + */ + + vstmia r1!, {s0-s31} /* Save the full FP context */ + + /* Store the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + vmrs r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ + bx lr + + .size up_savefpu, .-up_savefpu +#endif /* CONFIG_ARCH_FPU */ + .end diff --git a/arch/arm/src/armv7-r/arm_saveusercontext.S b/arch/arm/src/armv7-r/arm_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..19b198077c4cb0e8b80e087f20b1279bad32c7d2 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_saveusercontext.S @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_saveusercontext.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "up_internal.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_saveusercontext + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_saveusercontext.S" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: up_saveusercontext + ****************************************************************************/ + + .globl up_saveusercontext + .type up_saveusercontext, function + +up_saveusercontext: + + /* On entry, a1 (r0) holds address of struct xcptcontext */ + + /* Make sure that the return value will be non-zero (the value of the + * other volatile registers don't matter -- r1-r3, ip). This function + * is called through the normal C calling conventions and the values of + * these registers cannot be assumed at the point of setjmp return. + */ + + mov ip, #1 + str ip, [r0, #(4*REG_R0)] + + /* Save the volatile registers (plus r12 which really + * doesn't need to be saved) + */ + + add r1, r0, #(4*REG_R4) + stmia r1, {r4-r14} + + /* Save the current cpsr */ + + mrs r2, cpsr /* R3 = CPSR value */ + add r1, r0, #(4*REG_CPSR) + str r2, [r1] + + /* Save the return address as the PC so that we return to the exit from + * this function. + */ + + add r1, r0, #(4*REG_PC) + str lr, [r1] + + /* Save the floating point registers. + * REVISIT: Not all of the floating point registers need to be saved. + * Some are volatile and need not be preserved across functions calls. + * But right now, I can't find the definitive list of the volatile + * floating point registers. + */ + +#ifdef CONFIG_ARCH_FPU + add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */ + + /* Store all floating point registers. Registers are stored in numeric order, + * s0, s1, ... in increasing address order. + */ + + vstmia r1!, {s0-s31} /* Save the full FP context */ + + /* Store the floating point control and status register. At the end of the + * vstmia, r1 will point to the FPCSR storage location. + */ + + vmrs r2, fpscr /* Fetch the FPCSR */ + str r2, [r1], #4 /* Save the floating point control and status register */ +#endif + + /* Return 0 now indicating that this return is not a context switch */ + + mov r0, #0 /* Return value == 0 */ + mov pc, lr /* Return */ + .size up_saveusercontext, . - up_saveusercontext + .end diff --git a/arch/arm/src/armv7-r/arm_schedulesigaction.c b/arch/arm/src/armv7-r/arm_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..692debff2f0590db39b0d6d12d8c716cdf210c9f --- /dev/null +++ b/arch/arm/src/armv7-r/arm_schedulesigaction.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_schedulesigaction.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm.h" +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'sigdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + sdbg("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!CURRENT_REGS) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted + * task is the same as the one that must receive the signal, then + * we will have to modify the return state as well as the state + * in the TCB. + * + * Hmmm... there looks like a latent bug here: The following logic + * would fail in the strange case where we are in an interrupt + * handler, the thread is signalling itself, but a context switch + * to another task has occurred so that CURRENT_REGS does not + * refer to the thread of this_task()! + */ + + else + { + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = CURRENT_REGS[REG_PC]; + tcb->xcp.saved_cpsr = CURRENT_REGS[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver; + CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT); + + /* And make sure that the saved context in the TCB is the same + * as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an + * interrupt handler or (2) we are not in an interrupt handler and the + * running task is signalling some non-running task. + */ + + else + { + /* Save the return lr and cpsr and one scratch register. These + * will be restored by the signal trampoline after the signals + * have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-r/arm_sigdeliver.c b/arch/arm/src/armv7-r/arm_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..f638b35bfd64aec670f86dca54c1a23ebe4ad4c3 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_sigdeliver.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_sigdeliver.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copyfullstate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_CPSR] = rtcb->xcp.saved_cpsr; + + /* Get a local copy of the sigdeliver function pointer. we do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_CPSR]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-r/arm_signal_dispatch.c b/arch/arm/src/armv7-r/arm_signal_dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..5fa1b3a647769ae46991415dd56ee175ac3576a3 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_signal_dispatch.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_signal_dispatch.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "svcall.h" +#include "pgalloc.h" +#include "up_internal.h" + +#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ + defined(CONFIG_BUILD_PROTECTED)) && !defined(CONFIG_DISABLE_SIGNALS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_signal_dispatch + * + * Description: + * In the protected mode build, this function will be called to execute a + * a signal handler in user-space. When the signal is delivered, a + * kernel-mode stub will first run to perform some housekeeping functions. + * This kernel-mode stub will then be called transfer control to the user + * mode signal handler by calling this function. + * + * Normally the a user-mode signalling handling stub will also execute + * before the ultimate signal handler is called. See + * arch/arm/src/armv[6\7]/up_signal_handler. This function is the + * user-space, signal handler trampoline function. It is called from + * up_signal_dispatch() in user-mode. + * + * Inputs: + * sighand - The address user-space signal handling function + * signo, info, and ucontext - Standard arguments to be passed to the + * signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via an architecture specific system call made by up_signal_handler(). + * However, this will look like a normal return by the caller of + * up_signal_dispatch. + * + ****************************************************************************/ + +void up_signal_dispatch(_sa_sigaction_t sighand, int signo, + FAR siginfo_t *info, FAR void *ucontext) +{ + /* We are signalling a user group, but does the signal handler lie in the + * user address space? Or the kernel address space? The OS does + * intercept some signals for its own purpose (such as the death-of-child + * signal. + */ + + if (arm_uservaddr((uintptr_t)sighand)) + { + /* Yes.. Let sys_call4() do all of the work to get us into user space */ + + (void)sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo, + (uintptr_t)info, (uintptr_t)ucontext); + } + else + { + /* No.. we are already in kernel mode so just call the handler */ + + sighand(signo, info, ucontext); + } +} + +#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_PROTECTED) && !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/arm/src/armv7-r/arm_signal_handler.S b/arch/arm/src/armv7-r/arm_signal_handler.S new file mode 100644 index 0000000000000000000000000000000000000000..43f629a3ba9254f8e84ab949648e2bdb28ae7296 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_signal_handler.S @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_signal_handler.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * File info + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU + .cpu cortex-r4 +#else + .cpu cortex-r4f +#endif + .syntax unified + .file "arm_signal_handler.S" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: up_signal_handler + * + * Description: + * This function is the user-space, signal handler trampoline function. It + * is called from up_signal_dispatch() in user-mode. + * + * R0-R3, R11 - volatile registers need not be preserved. + * R4-R10 - static registers must be preserved + * R12-R14 - LR and SP must be preserved + * + * Inputs: + * R0 = sighand + * The address user-space signal handling function + * R1-R3 = signo, info, and ucontext + * Standard arguments to be passed to the signal handling function. + * + * Return: + * None. This function does not return in the normal sense. It returns + * via the SYS_signal_handler_return (see svcall.h) + * + ****************************************************************************/ + + .globl up_signal_handler + .type up_signal_handler, function +up_signal_handler: + + /* Save some register */ + + push {lr} /* Save LR on the stack */ + + /* Call the signal handler */ + + mov ip, r0 /* IP=sighand */ + mov r0, r1 /* R0=signo */ + mov r1, r2 /* R1=info */ + mov r2, r3 /* R2=ucontext */ + blx ip /* Call the signal handler */ + + /* Restore the registers */ + + pop {r2} /* Recover LR in R2 */ + mov lr, r2 /* Restore LR */ + + /* Execute the SYS_signal_handler_return SVCall (will not return) */ + + mov r0, #SYS_signal_handler_return + svc 0 + nop + + .size up_signal_handler, .-up_signal_handler + .end + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c new file mode 100644 index 0000000000000000000000000000000000000000..3e41a3484344f1dafbbfa8258f892f3986c125b8 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -0,0 +1,532 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_syscall.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "arm.h" +#include "svcall.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ + +#if defined(CONFIG_DEBUG_SYSCALL) +# define svcdbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define svcdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: + * + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 + * + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * WARNING: There are hard-coded values in this logic! + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ + __asm__ __volatile__ + ( + " sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ + " str lr, [sp, #12]\n" /* Save lr in the stack frame */ + " ldr ip, =g_stublookup\n" /* R12=The base of the stub lookup table */ + " ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this SYSCALL */ + " blx ip\n" /* Call the stub (modifies lr) */ + " ldr lr, [sp, #12]\n" /* Restore lr */ + " add sp, sp, #16\n" /* Destroy the stack frame */ + " mov r2, r0\n" /* R2=Save return value in R2 */ + " mov r0, #0\n" /* R0=SYS_syscall_return */ + " svc #0x900001\n" /* Return from the SYSCALL */ + ); +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_syscall + * + * Description: + * SVC interrupts will vector here with insn=the SVC instruction and + * xcp=the interrupt context + * + * The handler may get the SVC number be de-referencing the return + * address saved in the xcp and decoding the SVC instruction + * + ****************************************************************************/ + +#ifdef CONFIG_LIB_SYSCALL +uint32_t *arm_syscall(uint32_t *regs) +{ + uint32_t cmd; +#ifdef CONFIG_BUILD_PROTECTED + uint32_t cpsr; +#endif + + /* Nested interrupts are not supported */ + + DEBUGASSERT(regs); + + /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ + + cmd = regs[REG_R0]; + + /* The SVCall software interrupt is called with R0 = system call command + * and R1..R7 = variable number of arguments depending on the system call. + */ + +#if defined(CONFIG_DEBUG_SYSCALL) + svcdbg("SYSCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + svcdbg("CPSR: %08x\n", regs[REG_CPSR]); +#endif + + /* Handle the SVCall according to the command in R0 */ + + switch (cmd) + { + /* R0=SYS_syscall_return: This a SYSCALL return command: + * + * void up_syscall_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + + case SYS_syscall_return: + { + FAR struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved SYSCALL return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved SYSCALL return address in + * the original mode. + */ + + regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn; +#ifdef CONFIG_BUILD_PROTECTED + regs[REG_CPSR] = rtcb->xcp.syscall[index].cpsr; +#endif + /* The return value must be in R0-R1. dispatch_syscall() temporarily + * moved the value for R0 into R2. + */ + + regs[REG_R0] = regs[REG_R2]; + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If this is the outermost SYSCALL and if there is a saved user stack + * pointer, then restore the user stack pointer on this final return to + * user code. + */ + + if (index == 0 && rtcb->xcp.ustkptr != NULL) + { + regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr; + rtcb->xcp.ustkptr = NULL; + } +#endif + /* Save the new SYSCALL nesting level */ + + rtcb->xcp.nsyscalls = index; + } + break; + + /* R0=SYS_context_restore: Restore task context + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_context_restore + * R1 = restoreregs + */ + +#ifdef CONFIG_BUILD_PROTECTED + case SYS_context_restore: + { + /* Replace 'regs' with the pointer to the register set in + * regs[REG_R1]. On return from the system call, that register + * set will determine the restored context. + */ + + regs = (uint32_t *)regs[REG_R1]; + DEBUGASSERT(regs); + } + break; +#endif + + /* R0=SYS_task_start: This a user task start + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_task_start + * R1 = taskentry + * R2 = argc + * R3 = argv + */ + +#ifdef CONFIG_BUILD_PROTECTED + case SYS_task_start: + { + /* Set up to return to the user-space _start function in + * unprivileged mode. We need: + * + * R0 = argc + * R1 = argv + * PC = taskentry + * CSPR = user mode + */ + + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; + regs[REG_R1] = regs[REG_R3]; + + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + } + break; +#endif + + /* R0=SYS_pthread_start: This a user pthread start + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R0 = SYS_pthread_start + * R1 = entrypt + * R2 = arg + */ + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) + case SYS_pthread_start: + { + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. We need: + * + * R0 = arg + * PC = entrypt + * CSPR = user mode + */ + + + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; + + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + } + break; +#endif + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + /* R0=SYS_signal_handler: This a user signal handler callback + * + * void signal_handler(_sa_sigaction_t sighand, int signo, + * FAR siginfo_t *info, FAR void *ucontext); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler + * R1 = sighand + * R2 = signo + * R3 = info + * ucontext (on the stack) + */ + + case SYS_signal_handler: + { + FAR struct tcb_s *rtcb = sched_self(); + /* Remember the caller's return address */ + + DEBUGASSERT(rtcb->xcp.sigreturn == 0); + rtcb->xcp.sigreturn = regs[REG_PC]; + + /* Set up to return to the user-space pthread start-up function in + * unprivileged mode. + */ + + regs[REG_PC] = (uint32_t)ARCH_DATA_RESERVE->ar_sigtramp; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; + + /* Change the parameter ordering to match the expectation of struct + * userpace_s signal_handler. + */ + + regs[REG_R0] = regs[REG_R1]; /* sighand */ + regs[REG_R1] = regs[REG_R2]; /* signal */ + regs[REG_R2] = regs[REG_R3]; /* info */ + + /* The last parameter, ucontext, is trickier. The ucontext + * parameter will reside at an offset of 4 from the stack pointer. + */ + + regs[REG_R3] = *(uint32_t *)(regs[REG_SP]+4); + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If we are signalling a user process, then we must be operating + * on the kernel stack now. We need to switch back to the user + * stack before dispatching the signal handler to the user code. + * The existence of an allocated kernel stack is sufficient + * information to make this decision. + */ + + if (rtcb->xcp.kstack != NULL) + { + DEBUGASSERT(rtcb->xcp.kstkptr == NULL && rtcb->xcp.ustkptr != NULL); + + rtcb->xcp.kstkptr = (FAR uint32_t *)regs[REG_SP]; + regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr; + } +#endif + } + break; +#endif + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS) + /* R0=SYS_signal_handler_return: This a user signal handler callback + * + * void signal_handler_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_signal_handler_return + */ + + case SYS_signal_handler_return: + { + FAR struct tcb_s *rtcb = sched_self(); + + /* Set up to return to the kernel-mode signal dispatching logic. */ + + DEBUGASSERT(rtcb->xcp.sigreturn != 0); + + regs[REG_PC] = rtcb->xcp.sigreturn; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; + rtcb->xcp.sigreturn = 0; + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* We must enter here be using the user stack. We need to switch + * to back to the kernel user stack before returning to the kernel + * mode signal trampoline. + */ + + if (rtcb->xcp.kstack != NULL) + { + DEBUGASSERT(rtcb->xcp.kstkptr != NULL && + (uint32_t)rtcb->xcp.ustkptr == regs[REG_SP]); + + regs[REG_SP] = (uint32_t)rtcb->xcp.kstkptr; + rtcb->xcp.kstkptr = NULL; + } +#endif + } + break; +#endif + + /* This is not an architecture-specific system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_LIB_SYSCALL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall); + + /* Make sure that there is a no saved SYSCALL return address. We + * cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcp.syscall[index].sysreturn = regs[REG_PC]; +#ifdef CONFIG_BUILD_PROTECTED + rtcb->xcp.syscall[index].cpsr = regs[REG_CPSR]; +#endif + + regs[REG_PC] = (uint32_t)dispatch_syscall; +#ifdef CONFIG_BUILD_PROTECTED + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; +#endif + /* Offset R0 to account for the reserved values */ + + regs[REG_R0] -= CONFIG_SYS_RESERVED; +#else + svcdbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]); +#endif + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* If this is the first SYSCALL and if there is an allocated + * kernel stack, then switch to the kernel stack. + */ + + if (index == 0 && rtcb->xcp.kstack != NULL) + { + rtcb->xcp.ustkptr = (FAR uint32_t *)regs[REG_SP]; + regs[REG_SP] = (uint32_t)rtcb->xcp.kstack + ARCH_KERNEL_STACKSIZE; + } +#endif + /* Save the new SYSCALL nesting level */ + + rtcb->xcp.nsyscalls = index + 1; + } + break; + } + +#if defined(CONFIG_DEBUG_SYSCALL) + /* Report what happened */ + + svcdbg("SYSCALL Exit: regs: %p\n", regs); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + svcdbg("CPSR: %08x\n", regs[REG_CPSR]); +#endif + + /* Return the last value of curent_regs. This supports context switches + * on return from the exception. That capability is only used with the + * SYS_context_switch system call. + */ + + return regs; +} + +#else + +uint32_t *arm_syscall(uint32_t *regs) +{ + lldbg("SYSCALL from 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); +} + +#endif diff --git a/arch/arm/src/armv7-r/arm_testset.S b/arch/arm/src/armv7-r/arm_testset.S new file mode 100644 index 0000000000000000000000000000000000000000..7cd741fed734dfe86cd9b803306c74fc09973435 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_testset.S @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_testset.S + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + + .file "arm_testset.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_testset + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + + .globl up_testset + .type up_testset, %function + +up_testset: + + mov r1, #SP_LOCKED + + /* Test if the spinlock is locked or not */ + +1: + ldrexb r2, [r0] /* Test if spinlock is locked or not */ + cmp r2, r1 /* Already locked? */ + beq 2f /* If already locked, return SP_LOCKED */ + + /* Not locked ... attempt to lock it */ + + strexb r2, r1, [r0] /* Attempt to set the locked state */ + cmp r2, r1 /* r2 will be 1 is strexb failed */ + beq 1b /* Failed to lock... try again */ + + /* Lock acquired -- return SP_UNLOCKED */ + + dmb /* Required before accessing protected resource */ + mov r0, #SP_UNLOCKED + bx lr + + /* Lock not acquired -- return SP_LOCKED */ + +2: + mov r0, #SP_LOCKED + bx lr + .size up_testset, . - up_testset + .end diff --git a/arch/arm/src/armv7-r/arm_unblocktask.c b/arch/arm/src/armv7-r/arm_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..0361c1cc816f19903bb5c95e52796c25bca5c547 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_unblocktask.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_unblocktask.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (CURRENT_REGS) + { + /* Yes, then we have to do things differently. + * Just copy the CURRENT_REGS into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/arm/src/armv7-r/arm_undefinedinsn.c b/arch/arm/src/armv7-r/arm_undefinedinsn.c new file mode 100644 index 0000000000000000000000000000000000000000..b1db4f88686c6f35d98ef625c8e3a50a1b4af2dc --- /dev/null +++ b/arch/arm/src/armv7-r/arm_undefinedinsn.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_undefinedinsn.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_undefinedinsn + ****************************************************************************/ + +uint32_t *arm_undefinedinsn(uint32_t *regs) +{ + lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]); + CURRENT_REGS = regs; + PANIC(); + return regs; /* To keep the compiler happy */ +} diff --git a/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S b/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S new file mode 100644 index 0000000000000000000000000000000000000000..42775bd3b57d26ad3f8e6d3ecff59146d3ef4289 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectoraddrexcptn.S @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_vectoraddrexceptn.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "up_arch.h" + + .file "arm_vectoraddrexcptn.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl arm_vectoraddrexcption + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: arm_vectoraddrexcption + * + * Description: + * Shouldn't happen. This exception handler is in a separate file from + * other vector handlers because some processors do not support the + * Address Exception vector. + * + ****************************************************************************/ + + .globl arm_vectoraddrexcptn + .type arm_vectoraddrexcptn, %function +arm_vectoraddrexcptn: + b arm_vectoraddrexcptn + .size arm_vectoraddrexcptn, . - arm_vectoraddrexcptn + .end diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..216633e3a36f47d7c16ca8ae23af25aec2bd5bd8 --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -0,0 +1,977 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/arm_vectors.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "arm.h" +#include "cp15.h" + + .file "arm_vectors.S" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + + .data +g_irqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_undeftmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_aborttmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +#ifdef CONFIG_ARMV7R_DECODEFIQ +g_fiqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +#endif + +/************************************************************************************ + * Assembly Macros + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: arm_vectorirq + * + * Description: + * Interrupt exception. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl arm_decodeirq + .globl arm_vectorirq + .type arm_vectorirq, %function + +arm_vectorirq: + /* On entry, we are in IRQ mode. We are free to use the IRQ mode r13 + * and r14. + */ + + ldr r13, .Lirqtmp + sub lr, lr, #4 + str lr, [r13] /* Save lr_IRQ */ + mrs lr, spsr + str lr, [r13, #4] /* Save spsr_IRQ */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ +#ifdef CONFIG_ARMV7R_DECODEFIQ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) +#else + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT) +#endif + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lirqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lirqentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lirqcontinue + +.Lirqentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lirqcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the IRQ handler with interrupts disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lirqstackbase /* SP = interrupt stack base */ + str r0, [sp] /* Save the user stack pointer */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodeirq /* Call the handler */ + ldr sp, [r4] /* Restore the user stack pointer */ +#else + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodeirq /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ +#endif + + /* Upon return from arm_decodeirq, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_decodeirq: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lirqleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lirqleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lirqtmp: + .word g_irqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lirqstackbase: + .word g_intstackbase +#endif + .size arm_vectorirq, . - arm_vectorirq + .align 5 + +/************************************************************************************ + * Function: arm_vectorsvc + * + * Description: + * SVC interrupt. We enter the SVC in SVC mode. + * + ************************************************************************************/ + + .globl arm_syscall + .globl arm_vectorsvc + .type arm_vectorsvc, %function + +arm_vectorsvc: + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + mov r3, r14 /* Save r14 as the PC as well */ + mrs r4, spsr /* Get the saved CPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lsvcentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lsvccontinue + +.Lsvcentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lsvccontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the SVC handler with interrupts disabled. + * void arm_syscall(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_syscall /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_syscall, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_syscall: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lleavesvcsvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lleavesvcsvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + + .size arm_vectorsvc, . - arm_vectorsvc + + .align 5 + +/************************************************************************************ + * Name: arm_vectordata + * + * Description: + * This is the data abort exception dispatcher. The ARM data abort exception occurs + * when a memory fault is detected during a data transfer. This handler saves the + * current processor state and gives control to data abort handler. This function + * is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl arm_dataabort + .globl arm_vectordata + .type arm_vectordata, %function + +arm_vectordata: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Ldaborttmp /* Points to temp storage */ + sub lr, lr, #8 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Ldaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Ldabtentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Ldabtcontinue + +.Ldabtentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Ldabtcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the data abort handler with interrupts disabled. + * void arm_dataabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mrc CP15_DFAR(r1) /* Get R1=DFAR */ + mrc CP15_DFSR(r2) /* Get r2=DFSR */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_dataabort /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_dataabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_dataabort: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Ldabtleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Ldabtleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r1-r15}^ /* Return */ + +.Ldaborttmp: + .word g_aborttmp + .size arm_vectordata, . - arm_vectordata + + .align 5 + +/************************************************************************************ + * Name: arm_vectorprefetch + * + * Description: + * This is the prefetch abort exception dispatcher. The ARM prefetch abort exception + * occurs when a memory fault is detected during an an instruction fetch. This + * handler saves the current processor state and gives control to prefetch abort + * handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC. + * + ************************************************************************************/ + + .globl arm_prefetchabort + .globl arm_vectorprefetch + .type arm_vectorprefetch, %function + +arm_vectorprefetch: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Lpaborttmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lpaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_ABT, r4=spsr_ABT */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lpabtentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lpabtcontinue + +.Lpabtentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lpabtcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the prefetch abort handler with interrupts disabled. + * void arm_prefetchabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mrc CP15_IFAR(r1) /* Get R1=IFAR */ + mrc CP15_IFSR(r2) /* Get r2=IFSR */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_prefetchabort /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_prefetchabort, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_prefetchabort: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lpabtleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lpabtleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lpaborttmp: + .word g_aborttmp + .size arm_vectorprefetch, . - arm_vectorprefetch + + .align 5 + +/************************************************************************************ + * Name: arm_vectorundefinsn + * + * Description: + * Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR, + * lr = SVC PC + * + ************************************************************************************/ + + .globl arm_undefinedinsn + .globl arm_vectorundefinsn + .type arm_vectorundefinsn, %function + +arm_vectorundefinsn: + /* On entry we are free to use the UND mode registers + * r13 and r14 + */ + + ldr r13, .Lundeftmp /* Points to temp storage */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lundeftmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_UND, r4=spsr_UND */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode r13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lundefentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lundefcontinue + +.Lundefentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lundefcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the undef insn handler with interrupts disabled. + * void arm_undefinedinsn(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_undefinedinsn /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ + + /* Upon return from arm_undefinedinsn, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_undefinedinsn: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lundefleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lundefleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lundeftmp: + .word g_undeftmp + .size arm_vectorundefinsn, . - arm_vectorundefinsn + + .align 5 + +/************************************************************************************ + * Name: arm_vectorfiq + * + * Description: + * Shouldn't happen unless a arm_decodefiq() is provided. FIQ is primarily used + * with the TrustZone feature in order to handle secure interrupts. + * + ************************************************************************************/ + +#ifdef CONFIG_ARMV7R_DECODEFIQ + .globl arm_decodefiq +#endif + .globl arm_vectorfiq + .type arm_vectorfiq, %function + +arm_vectorfiq: +#ifdef CONFIG_ARMV7R_DECODEFIQ + /* On entry we are free to use the FIQ mode registers r8 through r14 */ + + ldr r13, .Lfiqtmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR_fiq */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lfiqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r3=lr_SVC, r4=spsr_SVC */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Did we enter from user mode? If so then we need get the values of + * USER mode rr13(sp) and r14(lr). + */ + + and r1, r4, #PSR_MODE_MASK /* Interrupted mode */ + cmp r1, #PSR_MODE_USR /* User mode? */ + bne .Lfiqentersvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */ + stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */ + add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */ + stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */ + b .Lfiqcontinue + +.Lfiqentersvc: + /* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1 + * and r2. + */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + +.Lfiqcontinue: + +#else + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Save r13(sp), r14(lr), r15(pc), and the CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} +#endif + + /* Then call the FIQ handler with interrupts disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lfiqstackbase /* SP = interrupt stack base */ + str r0, [sp] /* Save the user stack pointer */ + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodefiq /* Call the handler */ + ldr sp, [r4] /* Restore the user stack pointer */ +#else + mov r4, sp /* Save the SP in a preserved register */ + bic sp, sp, #7 /* Force 8-byte alignment */ + bl arm_decodefiq /* Call the handler */ + mov sp, r4 /* Restore the possibly unaligned stack pointer */ +#endif + + /* Upon return from arm_decodefiq, r0 holds the pointer to the register + * state save area to use to restore the registers. This may or may not + * be the same value that was passed to arm_decodefiq: It will differ if a + * context switch is required. + */ + + /* Restore the CPSR, SVC mode registers and return */ + + ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r1 /* Set the return mode SPSR */ + +#ifdef CONFIG_BUILD_PROTECTED + /* Are we leaving in user mode? If so then we need to restore the + * values of USER mode r13(sp) and r14(lr). + */ + + and r2, r1, #PSR_MODE_MASK /* Interrupted mode */ + cmp r2, #PSR_MODE_USR /* User mode? */ + bne .Lfiqleavesvc /* Branch if not user mode */ + + /* ldmia with ^ will return the user mode registers (provided that r15 + * is not in the register list). + */ + + mov r13, r0 /* (SVC) R13=Register storage area */ + ldmia r13, {r0-R12} /* Restore common R0-R12 */ + add r14, r13, #(4*REG_R13) /* (SVC) R14=address of R13/R14 storage */ + ldmia r14, {r13, r14}^ /* Restore user mode R13/R14 */ + add r14, r13, #(4*REG_R15) /* (SVC) R14=address of R15 storage */ + ldmia r14, {r15}^ /* Return */ + +.Lfiqleavesvc: +#endif + /* Life is simple when everything is SVC mode */ + + ldmia r0, {r0-r15}^ /* Return */ + +.Lfiqtmp: + .word g_fiqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lfiqstackbase: + .word g_intstackbase +#endif + +#else + subs pc, lr, #4 +#endif + .size arm_vectorfiq, . - arm_vectorfiq + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + + .globl g_intstackalloc + .type g_intstackalloc, object + .globl g_intstackbase + .type g_intstackbase, object + +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) +g_intstackbase: + .skip 4 + .size g_intstackbase, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) + +#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */ + .end diff --git a/arch/arm/src/armv7-r/arm_vectortab.S b/arch/arm/src/armv7-r/arm_vectortab.S new file mode 100644 index 0000000000000000000000000000000000000000..6c8f99447571e3dcd46cf1910e7a62a48a3a8e3a --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vectortab.S @@ -0,0 +1,110 @@ +/**************************************************************************** + * arch/arm/src/arm7-r/arm_vectortab.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + + .file "arm_vectortab.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl _vector_start + .globl _vector_end + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Name: _vector_start + * + * Description: + * Vector initialization block + ****************************************************************************/ + + .section .vectors, "ax" + .globl _vector_start + +/* These will be relocated to VECTOR_BASE. */ + +_vector_start: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lsvchandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl arm_vectorundefinsn + .globl arm_vectorsvc + .globl arm_vectorprefetch + .globl arm_vectordata + .globl arm_vectoraddrexcptn + .globl arm_vectorirq + .globl arm_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long arm_vectorundefinsn +.Lsvchandler: + .long arm_vectorsvc +.Lprefetchaborthandler: + .long arm_vectorprefetch +.Ldataaborthandler: + .long arm_vectordata +.Laddrexcptnhandler: + .long arm_vectoraddrexcptn +.Lirqhandler: + .long arm_vectorirq +.Lfiqhandler: + .long arm_vectorfiq + + .globl _vector_end +_vector_end: + .size _vector_start, . - _vector_start + .end diff --git a/arch/arm/src/armv7-r/arm_vfork.S b/arch/arm/src/armv7-r/arm_vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..635a5759c461a41c2688408c8f1d16c66b68c5ab --- /dev/null +++ b/arch/arm/src/armv7-r/arm_vfork.S @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_vfork.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_vfork.h" + + .file "vfork.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl up_vfork + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the + * behavior is undefined if the process created by vfork() either modifies + * any data other than a variable of type pid_t used to store the return + * value from vfork(), or returns from the function in which vfork() was + * called, or calls any other function before successfully calling _exit() + * or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the + * vfork() context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. + * This consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and + * returns the process ID of the child process to the parent process. + * Otherwise, -1 is returned to the parent, no child process is created, + * and errno is set to indicate the error. + * + ****************************************************************************/ + + .globl vfork + .type vfork, function +vfork: + /* Create a stack frame */ + + mov r0, sp /* Save the value of the stack on entry */ + sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the volatile registers */ + + str r4, [sp, #VFORK_R4_OFFSET] + str r5, [sp, #VFORK_R5_OFFSET] + str r6, [sp, #VFORK_R6_OFFSET] + str r7, [sp, #VFORK_R7_OFFSET] + str r8, [sp, #VFORK_R8_OFFSET] + str r9, [sp, #VFORK_R9_OFFSET] + str r10, [sp, #VFORK_R10_OFFSET] + + /* Save the frame pointer, stack pointer, and return address */ + + str fp, [sp, #VFORK_FP_OFFSET] + str r0, [sp, #VFORK_SP_OFFSET] + str lr, [sp, #VFORK_LR_OFFSET] + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + mov r0, sp + bl up_vfork + + /* Release the stack data and return the value returned by up_vfork */ + + ldr lr, [sp, #VFORK_LR_OFFSET] + add sp, sp, #VFORK_SIZEOF + mov pc, lr + .size vfork, .-vfork + .end diff --git a/arch/arm/src/armv7-r/cache.h b/arch/arm/src/armv7-r/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..2c60fe2c3d62d266e01506c6473f4473609efb42 --- /dev/null +++ b/arch/arm/src/armv7-r/cache.h @@ -0,0 +1,208 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/cache.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_CACHE_H +#define __ARCH_ARM_SRC_ARMV7_R_CACHE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "cp15_cacheops.h" +#include "l2cc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + + /************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: arch_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_invalidate_dcache(uintptr_t start, uintptr_t end) +{ + cp15_invalidate_dcache(start, end); + l2cc_invalidate(start, end); +} + +/**************************************************************************** + * Name: arch_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * NOTE: This function forces L1 and L2 cache operations to be atomic + * by disabling interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_invalidate_dcache_all(void) +{ +#ifdef CONFIG_ARCH_L2CACHE + irqstate_t flags = enter_critical_section(); + cp15_invalidate_dcache_all(); + l2cc_invalidate_all(); + leave_critical_section(flags); +#else + cp15_invalidate_dcache_all(); +#endif +} + +/************************************************************************************ + * Name: arch_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#define arch_invalidate_icache() cp15_invalidate_icache() + +/**************************************************************************** + * Name: arch_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_clean_dcache(uintptr_t start, uintptr_t end) +{ + cp15_clean_dcache(start, end); + l2cc_clean(start, end); +} + +/**************************************************************************** + * Name: arch_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + * Assumptions: + * This operation is not atomic. This function assumes that the caller + * has exclusive access to the address range so that no harm is done if + * the operation is pre-empted. + * + ****************************************************************************/ + +static inline void arch_flush_dcache(uintptr_t start, uintptr_t end) +{ + cp15_flush_dcache(start, end); + l2cc_flush(start, end); +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_CACHE_H */ diff --git a/arch/arm/src/armv7-r/cp15.h b/arch/arm/src/armv7-r/cp15.h new file mode 100644 index 0000000000000000000000000000000000000000..99a841ffc54a08007996d80be2a648a598762b7a --- /dev/null +++ b/arch/arm/src/armv7-r/cp15.h @@ -0,0 +1,169 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/cp15.h + * CP15 register access + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * References: + * + * "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_CP15_H +#define __ARCH_ARM_SRC_ARMV7_R_CP15_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* System control register descriptions. + * + * CP15 registers are accessed with MRC and MCR instructions as follows: + * + * MRC p15, , , , , ; Read CP15 Register + * MCR p15, , , , , ; Write CP15 Register + * + * Where + * + * is the Opcode_1 value for the register + * is a general purpose register + * is the register number within CP15 + * is the operational register + * is the Opcode_2 value for the register. + * + * Reference: Cortex-A5™ MPCore, Technical Reference Manual, Paragraph 4.2. + */ + +#define _CP15(op1,rd,crn,crm,op2) p15, op1, rd, crn, crm, op2 + +#define CP15_MIDR(r) _CP15(0, r, c0, c0, 0) /* Main ID Register */ +#define CP15_CTR(r) _CP15(0, r, c0, c0, 1) /* Cache Type Register */ +#define CP15_TCMTR(r) _CP15(0, r, c0, c0, 2) /* TCM Type Register */ +#define CP15_MPUIR(r) _CP15(0, r, c0, c0, 4) /* MPU Type Register */ +#define CP15_MPIDR(r) _CP15(0, r, c0, c0, 5) /* Multiprocessor Affinity Register */ +#define CP15_REVIDR(r) _CP15(0, r, c0, c0, 6) /* Revision ID register (Cortex-A9) */ +#define CP15_MID_PFR0(r) _CP15(0, r, c0, c1, 0) /* Processor Feature Register 0 */ +#define CP15_MID_PFR1(r) _CP15(0, r, c0, c1, 1) /* Processor Feature Register 1 */ +#define CP15_MID_DFR0(r) _CP15(0, r, c0, c1, 2) /* Debug Feature Register 0 */ +#define CP15_MID_AFR0(r) _CP15(0, r, c0, c1, 3) /* Auxiliary Feature Register 0 (Cortex-A9) */ +#define CP15_MID_MMFR0(r) _CP15(0, r, c0, c1, 4) /* Memory Model Features Register 0 */ +#define CP15_MID_MMFR1(r) _CP15(0, r, c0, c1, 5) /* Memory Model Features Register 1 */ +#define CP15_MID_MMFR2(r) _CP15(0, r, c0, c1, 6) /* Memory Model Features Register 2 */ +#define CP15_MID_MMFR3(r) _CP15(0, r, c0, c1, 7) /* Memory Model Features Register 3 */ +#define CP15_ID_ISAR0(r) _CP15(0, r, c0, c2, 0) /* Instruction Set Attributes Register 0 */ +#define CP15_ID_ISAR1(r) _CP15(0, r, c0, c2, 1) /* Instruction Set Attributes Register 1 */ +#define CP15_ID_ISAR2(r) _CP15(0, r, c0, c2, 2) /* Instruction Set Attributes Register 2 */ +#define CP15_ID_ISAR3(r) _CP15(0, r, c0, c2, 3) /* Instruction Set Attributes Register 3 */ +#define CP15_ID_ISAR4(r) _CP15(0, r, c0, c2, 4) /* Instruction Set Attributes Register 4 */ +#define CP15_ID_ISAR5(r) _CP15(0, r, c0, c2, 5) /* Instruction Set Attributes Register 5 (Cortex-A5) */ +#define CP15_CCSIDR(r) _CP15(1, r, c0, c0, 0) /* Cache Size Identification Register */ +#define CP15_CLIDR(r) _CP15(1, r, c0, c0, 1) /* Cache Level ID Register */ +#define CP15_AIDR(r) _CP15(1, r, c0, c0, 7) /* Auxiliary ID Register */ +#define CP15_CSSELR(r) _CP15(2, r, c0, c0, 0) /* Cache Size Selection Register */ + +#define CP15_SCTLR(r) _CP15(0, r, c1, c0, 0) /* System Control Register */ +#define CP15_ACTLR(r) _CP15(0, r, c1, c0, 1) /* Auxiliary Control Register */ +#define CP15_CPACR(r) _CP15(0, r, c1, c0, 2) /* Coprocessor Access Control Register */ + +#define CP15_DFSR(r) _CP15(0, r, c5, c0, 0) /* Data Fault Status Register */ +#define CP15_IFSR(r) _CP15(0, r, c5, c0, 1) /* Instruction Fault Status Register */ +#define CP15_ADFSR(r) _CP15(0, r, c5, c1, 0) /* Auxiliary Data Fault Status Register */ +#define CP15_AIFSR(r) _CP15(0, r, c5, c1, 1) /* Auxiliary Instruction Fault Status Register */ + +#define CP15_DFAR(r) _CP15(0, r, c6, c0, 0) /* Data Fault Address Register */ +#define CP15_IFAR(r) _CP15(0, r, c6, c0, 2) /* Instruction Fault Address Register */ +#define CP15_DRBAR(r) _CP15(0, r, c6, c1, 0) /* Data Region Base Address Register */ +#define CP15_DRSR(r) _CP15(0, r, c6, c1, 2) /* Data Region Size and Enable Register */ +#define CP15_DRACR(r) _CP15(0, r, c6, c1, 4) /* Data Region Access Control Register */ +#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED +# define CP15_IRBAR(r) _CP15(0, r, c6, c1, 1) /* Instruction Region Base Address Register */ +# define CP15_IRSR(r) _CP15(0, r, c6, c1, 3) /* Instruction Region Size and Enable Register */ +# define CP15_IRACR(r) _CP15(0, r, c6, c1, 5) /* Instruction Region Access Control Register */ +#endif +#define CP15_RGNR(r) _CP15(0, r, c6, c2, 0) /* MPU Region Number Register */ + +#define CP15_ICIALLUIS(r) _CP15(0, r, c7, c1, 0) /* Cache Operations Registers */ +#define CP15_BPIALLIS(r) _CP15(0, r, c7, c1, 6) + +#define CP15_ICIALLU(r) _CP15(0, r, c7, c5, 0) /* Cache Operations Registers */ +#define CP15_ICIMVAU(r) _CP15(0, r, c7, c5, 1) +#define CP15_CP15ISB(r) _CP15(0, r, c7, c5, 4) /* CP15 Instruction Synchronization Barrier operation */ +#define CP15_BPIALL(r) _CP15(0, r, c7, c5, 6) /* Cache Operations Registers */ +#define CP15_BPIMVA(r) _CP15(0, r, c7, c5, 7) /* Cortex-A5 */ +#define CP15_DCIMVAC(r) _CP15(0, r, c7, c6, 1) +#define CP15_DCISW(r) _CP15(0, r, c7, c6, 2) +#define CP15_DCCMVAC(r) _CP15(0, r, c7, c10, 1) /* Data Cache Clean by MVA to PoC */ +#define CP15_DCCSW(r) _CP15(0, r, c7, c10, 2) /* Data Cache Clean by Set/Way */ +#define CP15_CP15DSB(r) _CP15(0, r, c7, c10, 4) /* CP15 Data Synchronization Barrier operation */ +#define CP15_CP15DMB(r) _CP15(0, r, c7, c10, 5) /* CP15 Instruction Synchronization Barrier operation */ +#define CP15_DCCMVAU(r) _CP15(0, r, c7, c11, 1) /* Cache Operations Registers */ +#define CP15_DCCIMVAC(r) _CP15(0, r, c7, c14, 1) +#define CP15_DCCISW(r) _CP15(0, r, c7, c14, 2) + +#define CP15_PMCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */ +#define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */ +#define CP15_PMCNTENCLR(r) _CP15(0, r, c9, c12, 2) /* Count Enable Clear Register */ +#define CP15_PMOVSR(r) _CP15(0, r, c9, c12, 3) /* Overflow Flag Status Register */ +#define CP15_PMSWINC(r) _CP15(0, r, c9, c12, 4) /* Software Increment Register */ +#define CP15_PMSELR(r) _CP15(0, r, c9, c12, 5) /* Event Counter Selection Register */ +#define CP15_PMCEID0(r) _CP15(0, r, c9, c12, 6) /* Common Event Identification Registers (Cortex-A5) */ +#define CP15_PMCEID1(r) _CP15(0, r, c9, c12, 7) +#define CP15_PMCCNTR(r) _CP15(0, r, c9, c13, 0) /* Cycle Count Register */ +#define CP15_PMXEVTYPER(r) _CP15(0, r, c9, c13, 1) /* Event Type Select Register */ +#define CP15_PMXEVCNTR(r) _CP15(0, r, c9, c13, 2) /* Event Count Registers (Cortex-A5) */ +#define CP15_PMUSERENR(r) _CP15(0, r, c9, c14, 0) /* User Enable Register */ +#define CP15_PMINTENSET(r) _CP15(0, r, c9, c14, 1) /* Interrupt Enable Set Register */ +#define CP15_PMINTENCLR(r) _CP15(0, r, c9, c14, 2) /* Interrupt Enable Clear Register */ + +#define CP15_CONTEXTIDR(r) _CP15(0, r, c13, c0, 1) /* Context ID Register */ +#define CP15_TPIDRURW(r) _CP15(0, r, c13, c0, 2) /* Software Thread ID Registers */ +#define CP15_TPIDRURO(r) _CP15(0, r, c13, c0, 3) +#define CP15_TPIDRPRW(r) _CP15(0, r, c13, c0, 4) + +#define CP15_CNTFRQ(r) _CP15(0, r, c14, c0, 0) /* Counter Frequency register */ +#define CP15_CNTKCTL(r) _CP15(0, r, c14, c1, 0) /* Timer PL1 Control register */ +#define CP15_CNTP_TVAL(r) _CP15(0, r, c14, c2, 0) /* PL1 Physical TimerValue register */ +#define CP15_CNTP_CTL(r) _CP15(0, r, c14, c2, 0) /* PL1 Physical Timer Control register */ +#define CP15_CNTV_TVAL(r) _CP15(0, r, c14, c3, 0) /* Virtual TimerValue register */ +#define CP15_CNTV_CTL(r) _CP15(0, r, c14, c3, 0) /* Virtual Timer Control register */ +#define CP15_CNTPCT(r,n) _CP15(0, r, c14, c14, n) /* 64-bit Physical Count register */ +#define CP15_CNTVCT(r,n) _CP15(1, r, c14, c14, n) /* Virtual Count register */ +#define CP15_CNTP_CVAL(r,n) _CP15(2, r, c14, c14, n) /* PL1 Physical Timer CompareValue register */ +#define CP15_CNTV_CVAL(r,n) _CP15(3, r, c14, c14, n) /* Virtual Timer CompareValue register */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_CP15_H */ diff --git a/arch/arm/src/armv7-r/cp15_cacheops.h b/arch/arm/src/armv7-r/cp15_cacheops.h new file mode 100644 index 0000000000000000000000000000000000000000..aa0dee9906c9d8bfe68dba6a43b9ed38f0e8050a --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_cacheops.h @@ -0,0 +1,999 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/cp15_cacheops.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_CP15_CACHEOPS_H +#define __ARCH_ARM_SRC_ARMV7_R_CP15_CACHEOPS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Cache definitions ****************************************************************/ +/* L1 Memory */ + +#define CP15_L1_LINESIZE 32 + +/* CP15 Registers *******************************************************************/ +/* Terms: + * 1) Point of coherency (PoC) + * The PoC is the point at which all agents that can access memory are guaranteed + * to see the same copy of a memory location + * 2) Point of unification (PoU) + * The PoU is the point by which the instruction and data caches and the + * translation table walks of the processor are guaranteed to see the same copy + * of a memory location. + * + * Cache Operations: + * + * CP15 Register: ICIALLUIS + * Description: Invalidate entire instruction cache Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 0 + * CP15 Register: BPIALLIS + * Description: Invalidate entire branch predictor array Inner Shareable. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c1, 6 + * CP15 Register: ICIALLU + * Description: Invalidate all instruction caches to PoU. Also flushes branch + * target cache. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 0 + * CP15 Register: ICIMVAU + * Description: Invalidate instruction cache by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c5, 1 + * CP15 Register: CP15ISB + * Description: Instruction Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c5, 4 + * CP15 Register: BPIALL + * Description: Invalidate entire branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 6 + * CP15 Register: BPIMVA + * Description: Invalidate VA from branch predictor array. + * Register Format: Should be zero (SBZ) + * Instruction: MCR p15, 0, , c7, c5, 7 + * CP15 Register: DCIMVAC + * Description: Invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c6, 1 + * CP15 Register: DCISW + * Description: Invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c6, 2 + * CP15 Register: DCCMVAC + * Description: Clean data cache line to PoC by VA. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c10, 1 + * CP15 Register: DCCSW + * Description: Clean data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c10, 2 + * CP15 Register: CP15DSB + * Description: Data Synchronization Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 4 + * CP15 Register: CP15DMB + * Description: Data Memory Barrier operation + * NOTE: Deprecated and no longer documented + * Instruction: MCR p15, 0, , c7, c10, 5 + * CP15 Register: DCCMVAU + * Description: Clean data or unified cache line by VA to PoU. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c11, 1 + * CP15 Register: DCCIMVAC + * Description: Clean and invalidate data cache line by VA to PoC. + * Register Format: VA + * Instruction: MCR p15, 0, , c7, c14, 1 + * CP15 Register: DCCISW + * Description: Clean and invalidate data cache line by Set/Way. + * Register Format: Set/Way + * Instruction: MCR p15, 0, , c7, c14, 2 + */ + +/* Set/way format */ + +#define CACHE_WAY_SHIFT (3) /* Bits 30-31: Way in set being accessed */ +#define CACHE_WAY_MASK (3 << CACHE_WAY_SHIFT) +#define CACHE_SET_SHIFT (5) /* Bits 5-(S+4): Way in set being accessed */ + /* For 4KB cache size: S=5 */ +#define CACHE_SET4KB_MASK (0x1f << CACHE_SET_SHIFT) + /* Bits 10-29: Reserved */ + /* For 8KB cache size: S=6 */ +#define CACHE_SET8KB_MASK (0x3f << CACHE_SET_SHIFT) + /* Bits 11-29: Reserved */ + /* For 16KB cache size: S=7 */ +#define CACHE_SET16KB_MASK (0x7f << CACHE_SET_SHIFT) + /* Bits 12-29: Reserved */ + /* For 32KB cache size: S=8 */ +#define CACHE_SET32KB_MASK (0xff << CACHE_SET_SHIFT) + /* Bits 13-29: Reserved */ + /* For 64KB cache size: S=9 */ +#define CACHE_SET64KB_MASK (0x1fff << CACHE_SET_SHIFT) + /* Bits 14-29: Reserved */ + +/* VA and SBZ format */ + +#define CACHE_SBZ_SHIFT (4) /* Bits 0-4: Should be zero (SBZ) */ +#define CACHE_SBZ_MASK (31 << TLB_SBZ_SHIFT) +#define CACHE_VA_MASK (0xfffffffe0) /* Bits 5-31: Virtual address */ + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ +/* cp15_cache Cache Operations + * + * Usage + * + * They are performed as MCR instructions and only operate on a level 1 cache + * associated with ARM v7 processor. + * + * The supported operations are: + * + * 1. Any of these operations can be applied to any data cache or any + * unified cache. + * 2. Invalidate by MVA. Performs an invalidate of a data or unified cache + * line + * based on the address it contains. + * 3. Invalidate by set/way. Performs an invalidate of a data or unified + * cache line based on its location in the cache hierarchy. + * 4. Clean by MVA. Performs a clean of a data or unified cache line based + * on the address it contains. + * 5. Clean by set/way. Performs a clean of a data or unified cache line + * based on its location in the cache hierarchy. + * 6. Clean and Invalidate by MVA. Performs a clean and invalidate of a + * data or unified cache line based on the address it contains. + * 7. Clean and Invalidate by set/way. Performs a clean and invalidate of + * a data or unified cache line based on its location in the cache + * hierarchy. + * + * NOTE: Many of these operations are implemented as assembly language + * macros or as C inline functions in the file cache.h. The larger functions + * are implemented here as C-callable functions. + */ + +#ifdef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 D Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_disable_dcache, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ + .endm + +/************************************************************************************ + * Name: cp15_disable_caches + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_disable_caches, tmp + mrc p15, 0, \tmp, c1, c0, 0 /* Read SCTLR */ + bic \tmp, \tmp, #(0x1 << 12) /* Disable I cache */ + bic \tmp, \tmp, #(0x1 << 2) /* Disable D cache */ + mcr p15, 0, \tmp, c1, c0, 0 /* Update the SCTLR */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 0 /* ICIALLUIS */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_btb_inner_sharable, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c1, 6 /* BPIALLIS */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 0 /* ICIALLU */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_icache_bymva, va + mrc p15, 0, \va, c7, c5, 1 /* ICIMVAU */ + .endm + +/************************************************************************************ + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_flush_btb, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 6 /* BPIALL */ + .endm + +/************************************************************************************ + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_flush_btb_bymva, tmp + mov \tmp, #0 + mrc p15, 0, \tmp, c7, c5, 7 /* BPIMVA */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c6, 1 /* DCIMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_invalidate_dcacheline_bysetway, setway + mrc p15, 0, \setway, c7, c6, 2 /* DCISW */ + .endm + +/************************************************************************************ + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_dcache_bymva, va + mrc p15, 0, \va, c7, c10, 1 /* DCCMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_dcache_bysetway, setway + mrc p15, 0, \setway, c7, c10, 2 /* DCCSW */ + .endm + +/************************************************************************************ + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_clean_ucache_bymva, setway + mrc p15, 0, \setway, c7, c11, 1 /* DCCMVAU */ + .endm + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - Register with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_cleaninvalidate_dcacheline_bymva, va + mrc p15, 0, \va, c7, c14, 1 /* DCCIMVAC */ + .endm + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - Register with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + + .macro cp15_cleaninvalidate_dcacheline, setway + mrc p15, 0, \setway, c7, c14, 2 /* DCCISW */ + .endm + +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_disable_dcache + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_disable_dcache(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_disable_caches + * + * Description: + * Disable L1 Caches + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_disable_caches(void) +{ + __asm__ __volatile__ + ( + "\tmrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */ + "\tbic r0, r0, #(1 << 12)\n" /* Disable I cache */ + "\tbic r0, r0, #(1 << 2)\n" /* Disable D cache */ + "\tmcr p15, 0, r0, c1, c0, 0\n" /* Update the SCTLR */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache_inner_sharable + * + * Description: + * Invalidate I cache predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 0\n" /* ICIALLUIS */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_btb_inner_sharable + * + * Description: + * Invalidate entire branch predictor array inner sharable + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_btb_inner_sharable(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c1, 6\n" /* BPIALLIS */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache + * + * Description: + * Invalidate all instruction caches to PoU, also flushes branch target cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 0\n" /* ICIALLU */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_icache_bymva + * + * Description: + * Invalidate instruction caches by VA to PoU + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_invalidate_icache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c5, 1\n" /* ICIMVAU */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_flush_btb + * + * Description: + * Invalidate entire branch predictor array + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_flush_btb(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 6\n" /* BPIALL */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_flush_btb_bymva + * + * Description: + * Invalidate branch predictor array entry by MVA + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_flush_btb_bymva(void) +{ + __asm__ __volatile__ + ( + "\tmov r0, #0\n" + "\tmcr p15, 0, r0, c7, c5, 7\n" /* BPIMVA */ + : + : + : "r0", "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bymva + * + * Description: + * Invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Invalidate data cache line by VA to PoC */ + +static inline void cp15_invalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 1\n" /* DCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_invalidate_dcacheline_bysetway + * + * Description: + * Invalidate data cache line by set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Invalidate data cache line by set/way */ + +static inline void cp15_invalidate_dcacheline_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c6, 2\n" /* DCISW */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_dcache_bymva + * + * Description: + * Clean data cache line by MVA + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +/* Clean data cache line by MVA */ + +static inline void cp15_clean_dcache_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 1\n" /* DCCMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_dcache_bysetway + * + * Description: + * Clean data cache line by Set/way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_clean_dcache_bysetway(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c10, 2\n" /* DCCSW */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_clean_ucache_bymva + * + * Description: + * Clean unified cache line by MVA + * + * Input Parameters: + * setway - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_clean_ucache_bymva(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c11, 1\n" /* DCCMVAU */ + : + : "r" (setway) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline_bymva + * + * Description: + * Clean and invalidate data cache line by VA to PoC + * + * Input Parameters: + * va - 32-bit value with VA format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline_bymva(unsigned int va) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, r0, c7, c14, 1\n" /* DCCIMVAC */ + : + : "r" (va) + : "memory" + ); +} + +/************************************************************************************ + * Name: cp15_cleaninvalidate_dcacheline + * + * Description: + * Clean and Incalidate data cache line by Set/Way + * + * Input Parameters: + * setway - 32-bit value with Set/Way format + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void cp15_cleaninvalidate_dcacheline(unsigned int setway) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c7, c14, 2\n" /* DCCISW */ + : + : "r" (setway) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: cp15_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache). This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_coherent_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_invalidate_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_invalidate_dcache_all(void); + +/**************************************************************************** + * Name: cp15_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_clean_dcache(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: cp15_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + +void cp15_flush_dcache(uintptr_t start, uintptr_t end); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_CP15_CACHEOPS_H */ diff --git a/arch/arm/src/armv7-r/cp15_clean_dcache.S b/arch/arm/src/armv7-r/cp15_clean_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..f4739c02d393a7dbb3bb5d4496f245622be15a70 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_clean_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_clean_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_clean_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_clean_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_clean_dcache + * + * Description: + * Clean the data cache within the specified region by flushing the + * contents of the data cache to memory. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_clean_dcache + .type cp15_clean_dcache, function + +cp15_clean_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r0, r0, r3 /* R0=aligned start address */ + + /* Loop, cleaning each cache line by writing its contents to memory */ + +1: + mcr CP15_DCCMVAC(r0) /* Clean data cache line to PoC by VA */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + bx lr + .size cp15_clean_dcache, . - cp15_clean_dcache + .end diff --git a/arch/arm/src/armv7-r/cp15_coherent_dcache.S b/arch/arm/src/armv7-r/cp15_coherent_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..fa8b728f28713a874fa8858e7fb5f183d134103d --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_coherent_dcache.S @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_coherent_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_coherent_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_coherent_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_coherent_dcache + .type cp15_coherent_dcache, function + +cp15_coherent_dcache: + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, flushing each D cache line to memory */ +1: + mcr CP15_DCCMVAU(r12) /* Clean data or unified cache line by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + and r3, r3, #0xf /* Isolate the IminLine field */ + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r12, r0, r3 /* R12=aligned start address */ + + /* Loop, invalidating each I cache line to memory */ +1: + mcr CP15_ICIMVAU(r12) /* Invalidate instruction cache by VA to PoU */ + add r12, r12, r2 /* R12=Next cache line */ + cmp r12, r1 /* Loop until all cache lines have been invalidated */ + blo 1b + + mov r0, #0 + mcr CP15_BPIALLIS(r0) /* Invalidate entire branch predictor array Inner Shareable */ + mcr CP15_BPIALL(r0) /* Invalidate entire branch predictor array Inner Shareable */ + + dsb + isb + bx lr + .size cp15_coherent_dcache, . - cp15_coherent_dcache + .end diff --git a/arch/arm/src/armv7-r/cp15_flush_dcache.S b/arch/arm/src/armv7-r/cp15_flush_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..d7d1fe278edee14c8eb1f870d5de9e2b16c82142 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_flush_dcache.S @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_flush_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_flush_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_flush_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_flush_dcache + * + * Description: + * Flush the data cache within the specified region by cleaning and + * invalidating the D cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_flush_dcache + .type cp15_flush_dcache, function + +cp15_flush_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + bic r0, r0, r3 /* R0=aligned start address */ + + /* Loop, cleaning and invaliding each D cache line in the address range */ + +1: + mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been cleaned */ + blo 1b + + dsb + bx lr + .size cp15_flush_dcache, . - cp15_flush_dcache + .end diff --git a/arch/arm/src/armv7-r/cp15_invalidate_dcache.S b/arch/arm/src/armv7-r/cp15_invalidate_dcache.S new file mode 100644 index 0000000000000000000000000000000000000000..2dc6ab0ce61df8f91e01e9cb27301be0c197c9c5 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_invalidate_dcache.S @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_invalidate_dcache.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_invalidate_dcache.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_invalidate_dcache + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_invalidate_dcache + * + * Description: + * Invalidate the data cache within the specified region; we will be + * performing a DMA operation in this region and we want to purge old data + * in the cache. + * + * Input Parameters: + * start - virtual start address of region + * end - virtual end address of region + 1 + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_invalidate_dcache + .type cp15_invalidate_dcache, function + +cp15_invalidate_dcache: + + mrc CP15_CTR(r3) /* Read the Cache Type Register */ + lsr r3, r3, #16 /* Isolate the DMinLine field */ + and r3, r3, #0xf + mov r2, #4 + mov r2, r2, lsl r3 /* Get the cache line size in bytes */ + + sub r3, r2, #1 /* R3=Cache line size mask */ + tst r0, r3 + bic r0, r0, r3 /* R0=aligned start address */ + + mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */ + + tst r1, r3 + bic r1, r1, r3 /* R0=aligned end address */ + mcrne CP15_DCCIMVAC(r1) /* Clean and invalidate data cache line by VA to PoC */ + + /* Loop, invalidating each D cache line */ +1: + mcr CP15_DCIMVAC(r0) /* Invalidate data cache line by VA to PoC */ + add r0, r0, r2 /* R12=Next cache line */ + cmp r0, r1 /* Loop until all cache lines have been invalidate */ + blo 1b + + dsb + bx lr + .size cp15_invalidate_dcache, . - cp15_invalidate_dcache + .end diff --git a/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S b/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S new file mode 100644 index 0000000000000000000000000000000000000000..da32c8c9ad53bf5b48746e6271da1b6766b286a3 --- /dev/null +++ b/arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/cp15_invalidate_dcache_all.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) + * + * Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5 + * which also has a modified BSD-style license: + * + * Copyright (c) 2012, Atmel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor Atmel nor the names of the 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "cp15.h" + + .file "cp15_invalidate_dcache_all.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl cp15_invalidate_dcache_all + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: cp15_invalidate_dcache_all + * + * Description: + * Invalidate the entire contents of D cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + + .globl cp15_invalidate_dcache_all + .type cp15_invalidate_dcache_all, function + +cp15_invalidate_dcache_all: + + mrc CP15_CCSIDR(r0) /* Read the Cache Size Identification Register */ + ldr r3, =0xffff /* Isolate the NumSets field (bits 13-27) */ + and r0, r3, r0, lsr #13 /* r0=NumSets (number of sets - 1) */ + + mov r1, #0 /* r1 = way loop counter */ +way_loop: + + mov r3, #0 /* r3 = set loop counter */ +set_loop: + mov r2, r1, lsl #30 /* r2 = way loop counter << 30 */ + orr r2, r3, lsl #5 /* r2 = set/way cache operation format */ + mcr CP15_DCISW(r2) /* Data Cache Invalidate by Set/Way */ + add r3, r3, #1 /* Increment set counter */ + cmp r0, r3 /* Last set? */ + bne set_loop /* Keep looping if not */ + + add r1, r1, #1 /* Increment the way counter */ + cmp r1, #4 /* Last way? (four ways assumed) */ + bne way_loop /* Keep looping if not */ + + dsb + bx lr + .size cp15_invalidate_dcache_all, . - cp15_invalidate_dcache_all + .end diff --git a/arch/arm/src/armv7-r/fpu.h b/arch/arm/src/armv7-r/fpu.h new file mode 100644 index 0000000000000000000000000000000000000000..1f8fdfdba1699ed6c6a173ea6faa925f01c833f9 --- /dev/null +++ b/arch/arm/src/armv7-r/fpu.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/fpu.h + * Non-CP15 Registers + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_FPU_H +#define __ARCH_ARM_SRC_ARMV7_R_FPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +void arm_fpuconfig(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_FPU_H */ diff --git a/arch/arm/src/armv7-r/l2cc.h b/arch/arm/src/armv7-r/l2cc.h new file mode 100644 index 0000000000000000000000000000000000000000..05a69ab94dc461df9425e8122e98179b32b8aecb --- /dev/null +++ b/arch/arm/src/armv7-r/l2cc.h @@ -0,0 +1,258 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/l2cc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_L2CC_H +#define __ARCH_ARM_SRC_ARMV7_R_L2CC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ARCH_L2CACHE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_l2ccinitialize + * + * Description: + * One time configuration of the L2 cache. The L2 cache will be enabled + * upon return. + * + * Input Parameters: + * None. The L2 cache configuration is controlled by configuration + * settings. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if 0 /* Prototyped in up_internal.h */ +void up_l2ccinitialize(void); +#endif + +/**************************************************************************** + * Name: l2cc_enable + * + * Description: + * Re-enable the L2CC-P310 L2 cache by setting the enable bit in the + * Control Register (CR) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_enable(void); + +/**************************************************************************** + * Name: l2cc_disable + * + * Description: + * Disable the L2 cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_disable(void); + +/**************************************************************************** + * Name: l2cc_sync + * + * Description: + * Drain the L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_sync(void); + +/**************************************************************************** + * Name: l2cc_invalidate_all + * + * Description: + * Invalidate the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate_all(void); + +/**************************************************************************** + * Name: l2cc_invalidate + * + * Description: + * Invalidate a range of addresses in the L2 cache + * + * Input Parameters: + * startaddr - The first address to be invalidated + * endaddr - The last address to be invalidated + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_invalidate(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_clean_all + * + * Description: + * Clean the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean_all(void); + +/**************************************************************************** + * Name: l2cc_clean + * + * Description: + * Clean a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be cleaned + * endaddr - The last address to be cleaned + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_clean(uintptr_t startaddr, uintptr_t endaddr); + +/**************************************************************************** + * Name: l2cc_flush_all + * + * Description: + * Flush the entire L2 cache. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush_all(void); + +/**************************************************************************** + * Name: l2cc_flush + * + * Description: + * Flush a range of address within the L2 cache. + * + * Input Parameters: + * startaddr - The first address to be flushed + * endaddr - The last address to be flushed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void l2cc_flush(uint32_t startaddr, uint32_t endaddr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_ARCH_L2CACHE */ + /* Provide simple definitions to concentrate the inline conditional + * compilation in one place. + */ + +# define l2cc_enable() +# define l2cc_disable() +# define l2cc_sync() +# define l2cc_invalidate_all() +# define l2cc_invalidate(s,e) +# define l2cc_clean_all() +# define l2cc_clean(s,e) +# define l2cc_flush_all() +# define l2cc_flush(s,e) + +#endif /* CONFIG_ARCH_L2CACHE */ +#endif /* __ARCH_ARM_SRC_ARMV7_R_L2CC_H */ diff --git a/arch/arm/src/armv7-r/l2cc_pl310.h b/arch/arm/src/armv7-r/l2cc_pl310.h new file mode 100644 index 0000000000000000000000000000000000000000..51410b1923127d349b585af803bb537dffcfc7a5 --- /dev/null +++ b/arch/arm/src/armv7-r/l2cc_pl310.h @@ -0,0 +1,497 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/chip/l2cc_pl310.h + * + * Register definitions for the L2 Cache Controller (L2CC) is based on the + * L2CC-PL310 ARM multi-way cache macrocell, version r3p2. + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "CoreLink™ Level 2 Cache Controller L2C-310", Revision r3p2, + * Technical Reference Manual, ARM DDI 0246F (ID011711), ARM + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_L2CC_PL310_H +#define __ARCH_ARM_SRC_ARMV7_R_L2CC_PL310_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* The base address of the L2CC implementation must be provided in the chip.h + * header file as L2CC_BASE. + */ + +#include "chip/chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* General Definitions **************************************************************/ + +#define PL310_CACHE_LINE_SIZE 32 + +#ifdef CONFIG_PL310_LOCKDOWN_BY_MASTER +# define PL310_NLOCKREGS 8 +#else +# define PL310_NLOCKREGS 1 +#endif + +/* L2CC Register Offsets ************************************************************/ + +#define L2CC_IDR_OFFSET 0x0000 /* Cache ID Register */ +#define L2CC_TYPR_OFFSET 0x0004 /* Cache Type Register */ +#define L2CC_CR_OFFSET 0x0100 /* Control Register */ +#define L2CC_ACR_OFFSET 0x0104 /* Auxiliary Control Register */ +#define L2CC_TRCR_OFFSET 0x0108 /* Tag RAM Control Register */ +#define L2CC_DRCR_OFFSET 0x010c /* Data RAM Control Register */ + /* 0x0110-0x01fc Reserved */ +#define L2CC_ECR_OFFSET 0x0200 /* Event Counter Control Register */ +#define L2CC_ECFGR1_OFFSET 0x0204 /* Event Counter 1 Configuration Register */ +#define L2CC_ECFGR0_OFFSET 0x0208 /* Event Counter 0 Configuration Register */ +#define L2CC_EVR1_OFFSET 0x020c /* Event Counter 1 Value Register */ +#define L2CC_EVR0_OFFSET 0x0210 /* Event Counter 0 Value Register */ +#define L2CC_IMR_OFFSET 0x0214 /* Interrupt Mask Register */ +#define L2CC_MISR_OFFSET 0x0218 /* Masked Interrupt Status Register */ +#define L2CC_RISR_OFFSET 0x021c /* Raw Interrupt Status Register */ +#define L2CC_ICR_OFFSET 0x0220 /* Interrupt Clear Register */ + /* 0x0224-0x072c Reserved */ +#define L2CC_CSR_OFFSET 0x0730 /* Cache Synchronization Register */ + /* 0x0734-0x076c Reserved */ +#define L2CC_IPALR_OFFSET 0x0770 /* Invalidate Physical Address Line Register */ + /* 0x0774-0x0778 Reserved */ +#define L2CC_IWR_OFFSET 0x077c /* Invalidate Way Register */ + /* 0x0780-0x07af Reserved */ +#define L2CC_CPALR_OFFSET 0x07b0 /* Clean Physical Address Line Register */ + /* 0x07b4 Reserved */ +#define L2CC_CIR_OFFSET 0x07b8 /* Clean Index Register */ +#define L2CC_CWR_OFFSET 0x07bc /* Clean Way Register */ + /* 0x07c0-0x07ec Reserved */ +#define L2CC_CIPALR_OFFSET 0x07f0 /* Clean Invalidate Physical Address Line Register */ + /* 0x07f4 Reserved */ +#define L2CC_CIIR_OFFSET 0x07f8 /* Clean Invalidate Index Register */ +#define L2CC_CIWR_OFFSET 0x07fc /* Clean Invalidate Way Register */ + /* 0x0800-0x08fc Reserved */ + +/* Data and Instruction Lockdown registers where n=0-7. The registers for n > 0 are + * implemented if the option pl310_LOCKDOWN_BY_MASTER is enabled. Otherwise, they are + * unused + */ + +#define L2CC_DLKR_OFFSET(n) (0x0900 + ((n) << 3)) /* Data Lockdown Register */ +#define L2CC_ILKR_OFFSET(n) (0x0904 + ((n) << 3)) /* Instruction Lockdown Register */ + /* 0x0940-0x0f4c Reserved */ +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_OFFSET 0x0950 /* Lock Line Enable Register */ +# define L2CC_UNLKW_OFFSET 0x0954 /* Unlock Way Register */ +#endif + /* 0x0958-0x0bfc Reserved */ +#define L2CC_FLSTRT_OFFSET 0x0c00 /* Address filter start */ +#define L2CC_FLEND_OFFSET 0x0c04 /* Address filter end */ + /* 0x0c08-0x0f3c Reserved */ +#define L2CC_DCR_OFFSET 0x0f40 /* Debug Control Register */ + /* 0x0f44-0x0f5c Reserved */ +#define L2CC_PCR_OFFSET 0x0f60 /* Prefetch Control Register */ + /* 0x0f64-0x0f7c Reserved */ +#define L2CC_POWCR_OFFSET 0x0f80 /* Power Control Register */ + +/* L2CC Register Addresses **********************************************************/ + +#define L2CC_IDR (L2CC_BASE+L2CC_IDR_OFFSET) +#define L2CC_TYPR (L2CC_BASE+L2CC_TYPR_OFFSET) +#define L2CC_CR (L2CC_BASE+L2CC_CR_OFFSET) +#define L2CC_ACR (L2CC_BASE+L2CC_ACR_OFFSET) +#define L2CC_TRCR (L2CC_BASE+L2CC_TRCR_OFFSET) +#define L2CC_DRCR (L2CC_BASE+L2CC_DRCR_OFFSET) +#define L2CC_ECR (L2CC_BASE+L2CC_ECR_OFFSET) +#define L2CC_ECFGR1 (L2CC_BASE+L2CC_ECFGR1_OFFSET) +#define L2CC_ECFGR0 (L2CC_BASE+L2CC_ECFGR0_OFFSET) +#define L2CC_EVR1 (L2CC_BASE+L2CC_EVR1_OFFSET) +#define L2CC_EVR0 (L2CC_BASE+L2CC_EVR0_OFFSET) +#define L2CC_IMR (L2CC_BASE+L2CC_IMR_OFFSET) +#define L2CC_MISR (L2CC_BASE+L2CC_MISR_OFFSET) +#define L2CC_RISR (L2CC_BASE+L2CC_RISR_OFFSET) +#define L2CC_ICR (L2CC_BASE+L2CC_ICR_OFFSET) +#define L2CC_CSR (L2CC_BASE+L2CC_CSR_OFFSET) +#define L2CC_IPALR (L2CC_BASE+L2CC_IPALR_OFFSET) +#define L2CC_IWR (L2CC_BASE+L2CC_IWR_OFFSET) +#define L2CC_CPALR (L2CC_BASE+L2CC_CPALR_OFFSET) +#define L2CC_CIR (L2CC_BASE+L2CC_CIR_OFFSET) +#define L2CC_CWR (L2CC_BASE+L2CC_CWR_OFFSET) +#define L2CC_CIPALR (L2CC_BASE+L2CC_CIPALR_OFFSET) +#define L2CC_CIIR (L2CC_BASE+L2CC_CIIR_OFFSET) +#define L2CC_CIWR (L2CC_BASE+L2CC_CIWR_OFFSET) +#define L2CC_DLKR(n) (L2CC_BASE+L2CC_DLKR_OFFSET(n)) +#define L2CC_ILKR(n) (L2CC_BASE+L2CC_ILKR_OFFSET(n)) + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN (L2CC_BASE+L2CC_LKLN_OFFSET) +# define L2CC_UNLKW (L2CC_BASE+L2CC_UNLKW_OFFSET) +#endif + +#define L2CC_FLSTRT (L2CC_BASE+L2CC_FLSTRT_OFFSET) +#define L2CC_FLEND (L2CC_BASE+L2CC_FLEND_OFFSET) +#define L2CC_DCR (L2CC_BASE+L2CC_DCR_OFFSET) +#define L2CC_PCR (L2CC_BASE+L2CC_PCR_OFFSET) +#define L2CC_POWCR (L2CC_BASE+L2CC_POWCR_OFFSET) + +/* L2CC Register Bit Definitions ****************************************************/ + +/* Cache ID Register (32-bit ID) */ + +#define L2CC_IDR_REV_MASK 0x0000003f +# define L2CC_IDR_REV_R0P0 0x00000000 +# define L2CC_IDR_REV_R1P0 0x00000002 +# define L2CC_IDR_REV_R2P0 0x00000004 +# define L2CC_IDR_REV_R3P0 0x00000005 +# define L2CC_IDR_REV_R3P1 0x00000006 +# define L2CC_IDR_REV_R3P2 0x00000008 + +/* Cache Type Register */ + +#define L2CC_TYPR_IL2ASS (1 << 6) /* Bit 6: Instruction L2 Cache Associativity */ +#define L2CC_TYPR_IL2WSIZE_SHIFT (8) /* Bits 8-10: Instruction L2 Cache Way Size */ +#define L2CC_TYPR_IL2WSIZE_MASK (7 << L2CC_TYPR_IL2WSIZE_SHIFT) +# define L2CC_TYPR_IL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_IL2WSIZE_SHIFT) +#define L2CC_TYPR_DL2ASS (1 << 18) /* Bit 18: Data L2 Cache Associativity */ +#define L2CC_TYPR_DL2WSIZE_SHIFT (20) /* Bits 20-22: Data L2 Cache Way Size */ +#define L2CC_TYPR_DL2WSIZE_MASK (7 << L2CC_TYPR_DL2WSIZE_SHIFT) +# define L2CC_TYPR_DL2WSIZE(n) ((uint32_t)(n) << L2CC_TYPR_DL2WSIZE_SHIFT) + +/* Control Register */ + +#define L2CC_CR_L2CEN (1 << 0) /* Bit 0: L2 Cache Enable */ + +/* Auxiliary Control Register */ + +#define L2CC_ACR_FLZE (1 << 0) /* Bit 0: Full line zero enable */ +#define L2CC_ACR_HPSO (1 << 10) /* Bit 10: High Priority for SO and Dev Reads Enable */ +#define L2CC_ACR_SBDLE (1 << 11) /* Bit 11: Store Buffer Device Limitation Enable */ +#define L2CC_ACR_EXCC (1 << 12) /* Bit 12: Exclusive Cache Configuration */ +#define L2CC_ACR_SAIE (1 << 13) /* Bit 13: Shared Attribute Invalidate Enable */ +#define L2CC_ACR_ASS (1 << 16) /* Bit 16: Associativity */ +#define L2CC_ACR_WAYSIZE_SHIFT (17) /* Bits 17-19: Way Size */ +#define L2CC_ACR_WAYSIZE_MASK (7 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_16KB (1 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_32KB (2 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_64KB (3 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_128KB (4 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_256KB (5 << L2CC_ACR_WAYSIZE_SHIFT) +# define L2CC_ACR_WAYSIZE_512KB (6 << L2CC_ACR_WAYSIZE_SHIFT) +#define L2CC_ACR_EMBEN (1 << 20) /* Bit 20: Event Monitor Bus Enable */ +#define L2CC_ACR_PEN (1 << 21) /* Bit 21: Parity Enable */ +#define L2CC_ACR_SAOEN (1 << 22) /* Bit 22: Shared Attribute Override Enable */ +#define L2CC_ACR_FWA_SHIFT (23) /* Bits 23-24: Force Write Allocate */ +#define L2CC_ACR_FWA_MASK (3 << L2CC_ACR_FWA_SHIFT) +# define L2CC_ACR_FWA_AWCACHE (0 << L2CC_ACR_FWA_SHIFT) /* Use AWCACHE attributes for WA */ +# define L2CC_ACR_FWA_NOALLOC (1 << L2CC_ACR_FWA_SHIFT) /* No allocate */ +# define L2CC_ACR_FWA_OVERRIDE (2 << L2CC_ACR_FWA_SHIFT) /* Override AWCACHE attributes */ +# define L2CC_ACR_FWA_MAPPED (3 << L2CC_ACR_FWA_SHIFT) /* Internally mapped to 00 */ +#define L2CC_ACR_CRPOL (1 << 25) /* Bit 25: Cache Replacement Policy */ +#define L2CC_ACR_NSLEN (1 << 26) /* Bit 26: Non-Secure Lockdown Enable */ +#define L2CC_ACR_NSIAC (1 << 27) /* Bit 27: Non-Secure Interrupt Access Control */ +#define L2CC_ACR_DPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_ACR_IPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_ACR_EBRESP (1 << 30) /* Bit 30: Early BRESP enable */ + +#define L2CC_ACR_SBZ (0x8000c1fe) + +/* Tag RAM Control Register */ + +#define L2CC_TRCR_TSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_TRCR_TSETLAT_MASK (7 << L2CC_TRCR_TSETLAT_SHIFT) +# define L2CC_TRCR_TSETLAT(n) ((uint32_t)(n) << L2CC_TRCR_TSETLAT_SHIFT) +#define L2CC_TRCR_TRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_TRCR_TRDLAT_MASK (7 << L2CC_TRCR_TRDLAT_SHIFT) +# define L2CC_TRCR_TRDLAT(n) ((uint32_t)(n) << L2CC_TRCR_TRDLAT_SHIFT) +#define L2CC_TRCR_TWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_TRCR_TWRLAT_MASK (7 << L2CC_TRCR_TWRLAT_SHIFT) +# define L2CC_TRCR_TWRLAT(n) ((uint32_t)(n) << L2CC_TRCR_TWRLAT_SHIFT) + +/* Data RAM Control Register */ + +#define L2CC_DRCR_DSETLAT_SHIFT (0) /* Bits 0-2: Setup Latency */ +#define L2CC_DRCR_DSETLAT_MASK (7 << L2CC_DRCR_DSETLAT_SHIFT) +# define L2CC_DRCR_DSETLAT(n) ((uint32_t)(n) << L2CC_DRCR_DSETLAT_SHIFT) +#define L2CC_DRCR_DRDLAT_SHIFT (4) /* Bits 4-6: Read Access Latency */ +#define L2CC_DRCR_DRDLAT_MASK (7 << L2CC_DRCR_DRDLAT_SHIFT) +# define L2CC_DRCR_DRDLAT(n) ((uint32_t)(n) << L2CC_DRCR_DRDLAT_SHIFT) +#define L2CC_DRCR_DWRLAT_SHIFT (8) /* Bits 8-10: Write Access Latency */ +#define L2CC_DRCR_DWRLAT_MASK (7 << L2CC_DRCR_DWRLAT_SHIFT) +# define L2CC_DRCR_DWRLAT(n) ((uint32_t)(n) << L2CC_DRCR_DWRLAT_SHIFT) + +/* Event Counter Control Register */ + +#define L2CC_ECR_EVCEN (1 << 0) /* Bit 0: Event Counter Enable */ +#define L2CC_ECR_EVC0RST (1 << 1) /* Bit 1: Event Counter 0 Reset */ +#define L2CC_ECR_EVC1RST (1 << 2) /* Bit 2: Event Counter 1 Reset */ + +/* Event Counter 1 Configuration Register */ + + +#define L2CC_ECFGR1_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR1_EIGEN_MASK (3 << L2CC_ECFGR1_EIGEN_SHIFT) +# define L2CC_ECFGR1_EIGEN_INTDIS (0 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables (default) */ +# define L2CC_ECFGR1_EIGEN_INTENINCR (1 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Increment condition */ +# define L2CC_ECFGR1_EIGEN_INTENOVER (2 << L2CC_ECFGR1_EIGEN_SHIFT) /* Enables with Overflow condition */ +# define L2CC_ECFGR1_EIGEN_INTGENDIS (3 << L2CC_ECFGR1_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR1_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR1_ESRC_MASK (15 << L2CC_ECFGR1_ESRC_SHIFT) +# define L2CC_ECFGR1_ESRC_CNTDIS (0 << L2CC_ECFGR1_ESRC_SHIFT) /* Counter Disabled */ +# define L2CC_ECFGR1_ESRC_CO (1 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is CO */ +# define L2CC_ECFGR1_ESRC_DRHIT (2 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRHIT */ +# define L2CC_ECFGR1_ESRC_DRREQ (3 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DRREQ */ +# define L2CC_ECFGR1_ESRC_DWHIT (4 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWHIT */ +# define L2CC_ECFGR1_ESRC_DWREQ (5 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWREQ */ +# define L2CC_ECFGR1_ESRC_DWTREQ (6 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is DWTREQ */ +# define L2CC_ECFGR1_ESRC_IRHIT (7 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRHIT */ +# define L2CC_ECFGR1_ESRC_IRREQ (8 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IRREQ */ +# define L2CC_ECFGR1_ESRC_WA (9 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is WA */ +# define L2CC_ECFGR1_ESRC_IPFALLOC (10 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is IPFALLOC */ +# define L2CC_ECFGR1_ESRC_EPFHIT (11 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFHIT */ +# define L2CC_ECFGR1_ESRC_EPFALLOC (12 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFALLOC */ +# define L2CC_ECFGR1_ESRC_SRRCVD (13 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRRCVD */ +# define L2CC_ECFGR1_ESRC_SRCONF (14 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is SRCONF */ +# define L2CC_ECFGR1_ESRC_EPFRCVD (15 << L2CC_ECFGR1_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 0 Configuration Register */ + +#define L2CC_ECFGR0_EIGEN_SHIFT (0) /* Bits 0-1: Event Counter Interrupt Generation */ +#define L2CC_ECFGR0_EIGEN_MASK (3 << L2CC_ECFGR0_EIGEN_SHIFT) +# define L2CC_ECFGR0_EIGEN_INTDIS (0 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables (default) */ +# define L2CC_ECFGR0_EIGEN_INTENINCR (1 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Increment condition */ +# define L2CC_ECFGR0_EIGEN_INTENOVER (2 << L2CC_ECFGR0_EIGEN_SHIFT) /* Enables with Overflow condition */ +# define L2CC_ECFGR0_EIGEN_INTGENDIS (3 << L2CC_ECFGR0_EIGEN_SHIFT) /* Disables Interrupt generation */ +#define L2CC_ECFGR0_ESRC_SHIFT (2) /* Bits 2-5: Event Counter Source */ +#define L2CC_ECFGR0_ESRC_MASK (15 << L2CC_ECFGR0_ESRC_SHIFT) +# define L2CC_ECFGR0_ESRC_CNTDIS (0 << L2CC_ECFGR0_ESRC_SHIFT) /* Counter Disabled */ +# define L2CC_ECFGR0_ESRC_CO (1 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is CO */ +# define L2CC_ECFGR0_ESRC_DRHIT (2 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRHIT */ +# define L2CC_ECFGR0_ESRC_DRREQ (3 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DRREQ */ +# define L2CC_ECFGR0_ESRC_DWHIT (4 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWHIT */ +# define L2CC_ECFGR0_ESRC_DWREQ (5 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWREQ */ +# define L2CC_ECFGR0_ESRC_DWTREQ (6 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is DWTREQ */ +# define L2CC_ECFGR0_ESRC_IRHIT (7 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRHIT */ +# define L2CC_ECFGR0_ESRC_IRREQ (8 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IRREQ */ +# define L2CC_ECFGR0_ESRC_WA (9 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is WA */ +# define L2CC_ECFGR0_ESRC_IPFALLOC (10 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is IPFALLOC */ +# define L2CC_ECFGR0_ESRC_EPFHIT (11 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFHIT */ +# define L2CC_ECFGR0_ESRC_EPFALLOC (12 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFALLOC */ +# define L2CC_ECFGR0_ESRC_SRRCVD (13 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRRCVD */ +# define L2CC_ECFGR0_ESRC_SRCONF (14 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is SRCONF */ +# define L2CC_ECFGR0_ESRC_EPFRCVD (15 << L2CC_ECFGR0_ESRC_SHIFT) /* Source is EPFRCVD */ + +/* Event Counter 1 Value Register (32-bit value) */ +/* Event Counter 0 Value Register (32-bit value) */ + +/* Interrupt Mask Register, Masked Interrupt Status Register, Raw Interrupt Status + * Register, and Interrupt Clear Register. + */ + +#define L2CC_INT_ECNTR (1 << 0) /* Bit 0: Event Counter 1/0 Overflow Increment */ +#define L2CC_INT_PARRT (1 << 1) /* Bit 1: Parity Error on L2 Tag RAM, Read */ +#define L2CC_INT_PARRD (1 << 2) /* Bit 2: Parity Error on L2 Data RAM, Read */ +#define L2CC_INT_ERRWT (1 << 3) /* Bit 3: Error on L2 Tag RAM, Write */ +#define L2CC_INT_ERRWD (1 << 4) /* Bit 4: Error on L2 Data RAM, Write */ +#define L2CC_INT_ERRRT (1 << 5) /* Bit 5: Error on L2 Tag RAM, Read */ +#define L2CC_INT_ERRRD (1 << 6) /* Bit 6: Error on L2 Data RAM, Read */ +#define L2CC_INT_SLVERR (1 << 7) /* Bit 7: SLVERR from L3 Memory */ +#define L2CC_INT_DECERR (1 << 8) /* Bit 8: DECERR from L3 Memory */ + +/* Cache Synchronization Register */ + +#define L2CC_CSR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ + +/* Invalidate Physical Address Line Register */ + +#define L2CC_IPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_IPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_IPALR_IDX_MASK (0x1ff << L2CC_IPALR_IDX_SHIFT) +# define L2CC_IPALR_IDX(n) ((uint32_t)(n) << L2CC_IPALR_IDX_SHIFT) +#define L2CC_IPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_IPALR_TAG_MASK (0x3ffff << L2CC_IPALR_TAG_SHIFT) +# define L2CC_IPALR_TAG(n) ((uint32_t)(n) << L2CC_IPALR_TAG_SHIFT) + +/* Invalidate Way Register */ + +#define L2CC_IWR_WAY(n) (1 << (n)) /* Bist 0-7: Invalidate Way Number n, n=0..7 */ +# define L2CC_IWR_WAY0 (1 << 0) /* Bit 0: Invalidate Way Number 0 */ +# define L2CC_IWR_WAY1 (1 << 1) /* Bit 1: Invalidate Way Number 1 */ +# define L2CC_IWR_WAY2 (1 << 2) /* Bit 2: Invalidate Way Number 2 */ +# define L2CC_IWR_WAY3 (1 << 3) /* Bit 3: Invalidate Way Number 3 */ +# define L2CC_IWR_WAY4 (1 << 4) /* Bit 4: Invalidate Way Number 4 */ +# define L2CC_IWR_WAY5 (1 << 5) /* Bit 5: Invalidate Way Number 5 */ +# define L2CC_IWR_WAY6 (1 << 6) /* Bit 6: Invalidate Way Number 6 */ +# define L2CC_IWR_WAY7 (1 << 7) /* Bit 7: Invalidate Way Number 7 */ + +/* Clean Physical Address Line Register */ + +#define L2CC_CPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CPALR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CPALR_IDX_MASK (0x1ff << L2CC_CPALR_IDX_SHIFT) +# define L2CC_CPALR_IDX(n) ((uint32_t)(n) << L2CC_CPALR_IDX_SHIFT) +#define L2CC_CPALR_TAG_SHIFT (14) /* Bits 14-31: Tag number */ +#define L2CC_CPALR_TAG_MASK (0x3ffff << L2CC_CPALR_TAG_SHIFT) +# define L2CC_CPALR_TAG(n) ((uint32_t)(n) << L2CC_CPALR_TAG_SHIFT) + +/* Clean Index Register */ + +#define L2CC_CIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIR_IDX_SHIFT (5) /* Bits 5-13: Index number */ +#define L2CC_CIR_IDX_MASK (0x1ff << L2CC_CIR_IDX_SHIFT) +# define L2CC_CIR_IDX(n) ((uint32_t)(n) << L2CC_CIR_IDX_SHIFT) +#define L2CC_CIR_WAY_SHIFT (28) /* Bits 28-30: Way number */ +#define L2CC_CIR_WAY_MASK (7 << L2CC_CIR_WAY_SHIFT) +# define L2CC_CIR_WAY(n) ((uint32_t)(n) << L2CC_CIR_WAY_SHIFT) + +/* Clean Way Register */ + +#define L2CC_CWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Way Number n, n=0..7 */ +# define L2CC_CWR_WAY0 (1 << 0) /* Bit 0: Clean Way Number 0 */ +# define L2CC_CWR_WAY1 (1 << 1) /* Bit 1: Clean Way Number 1 */ +# define L2CC_CWR_WAY2 (1 << 2) /* Bit 2: Clean Way Number 2 */ +# define L2CC_CWR_WAY3 (1 << 3) /* Bit 3: Clean Way Number 3 */ +# define L2CC_CWR_WAY4 (1 << 4) /* Bit 4: Clean Way Number 4 */ +# define L2CC_CWR_WAY5 (1 << 5) /* Bit 5: Clean Way Number 5 */ +# define L2CC_CWR_WAY6 (1 << 6) /* Bit 6: Clean Way Number 6 */ +# define L2CC_CWR_WAY7 (1 << 7) /* Bit 7: Clean Way Number 7 */ + +/* Clean Invalidate Physical Address Line Register */ + +#define L2CC_CIPALR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIPALR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIPALR_IDX_MASK (0x1ff << L2CC_CIPALR_IDX_SHIFT) +# define L2CC_CIPALR_IDX(n) ((uint32_t)(n) << L2CC_CIPALR_IDX_SHIFT) +#define L2CC_CIPALR_TAG_SHIFT (14) /* Bits 14-31: Tag Number */ +#define L2CC_CIPALR_TAG_MASK (0x3ffff << L2CC_CIPALR_TAG_SHIFT) +# define L2CC_CIPALR_TAG(n) ((uint32_t)(n) << L2CC_CIPALR_TAG_SHIFT) + +/* Clean Invalidate Index Register */ + +#define L2CC_CIIR_C (1 << 0) /* Bit 0: Cache Synchronization Status */ +#define L2CC_CIIR_IDX_SHIFT (5) /* Bits 5-13: Index Number */ +#define L2CC_CIIR_IDX_MASK (0x1ff << L2CC_CIIR_IDX_SHIFT) +# define L2CC_CIIR_IDX(n) ((uint32_t)(n) << L2CC_CIIR_IDX_SHIFT) +#define L2CC_CIIR_WAY_SHIFT (28) /* Bits 28-30: Way Number */ +#define L2CC_CIIR_WAY_MASK (7 << L2CC_CIIR_WAY_SHIFT) +# define L2CC_CIIR_WAY(n) ((uint32_t)(n) << L2CC_CIIR_WAY_SHIFT) + +/* Clean Invalidate Way Register */ + +#define L2CC_CIWR_WAY(n) (1 << (n)) /* Bits 0-7: Clean Invalidate Way Number n, n=1..7 */ +# define L2CC_CIWR_WAY0 (1 << 0) /* Bit 0: Clean Invalidate Way Number 0 */ +# define L2CC_CIWR_WAY1 (1 << 1) /* Bit 1: Clean Invalidate Way Number 1 */ +# define L2CC_CIWR_WAY2 (1 << 2) /* Bit 2: Clean Invalidate Way Number 2 */ +# define L2CC_CIWR_WAY3 (1 << 3) /* Bit 3: Clean Invalidate Way Number 3 */ +# define L2CC_CIWR_WAY4 (1 << 4) /* Bit 4: Clean Invalidate Way Number 4 */ +# define L2CC_CIWR_WAY5 (1 << 5) /* Bit 5: Clean Invalidate Way Number 5 */ +# define L2CC_CIWR_WAY6 (1 << 6) /* Bit 6: Clean Invalidate Way Number 6 */ +# define L2CC_CIWR_WAY7 (1 << 7) /* Bit 7: Clean Invalidate Way Number 7 */ + +/* Data Lockdown Register */ + +#define L2CC_DLKR_DLK(n) (1 << (n)) /* Bits 0-7: Data Lockdown in Way Number n, n=0..7 */ +# define L2CC_DLKR_DLK0 (1 << 0) /* Bit 0: Data Lockdown in Way Number 0 */ +# define L2CC_DLKR_DLK1 (1 << 1) /* Bit 1: Data Lockdown in Way Number 1 */ +# define L2CC_DLKR_DLK2 (1 << 2) /* Bit 2: Data Lockdown in Way Number 2 */ +# define L2CC_DLKR_DLK3 (1 << 3) /* Bit 3: Data Lockdown in Way Number 3 */ +# define L2CC_DLKR_DLK4 (1 << 4) /* Bit 4: Data Lockdown in Way Number 4 */ +# define L2CC_DLKR_DLK5 (1 << 5) /* Bit 5: Data Lockdown in Way Number 5 */ +# define L2CC_DLKR_DLK6 (1 << 6) /* Bit 6: Data Lockdown in Way Number 6 */ +# define L2CC_DLKR_DLK7 (1 << 7) /* Bit 7: Data Lockdown in Way Number 7 */ + +/* Instruction Lockdown Register */ + +#define L2CC_ILKR_ILK(n) (1 << (n)) /* Bits 0-7: Instruction Lockdown in Way Number n, n=0..7 */ +# define L2CC_ILKR_ILK0 (1 << 0) /* Bit 0: Instruction Lockdown in Way Number 0 */ +# define L2CC_ILKR_ILK1 (1 << 1) /* Bit 1: Instruction Lockdown in Way Number 1 */ +# define L2CC_ILKR_ILK2 (1 << 2) /* Bit 2: Instruction Lockdown in Way Number 2 */ +# define L2CC_ILKR_ILK3 (1 << 3) /* Bit 3: Instruction Lockdown in Way Number 3 */ +# define L2CC_ILKR_ILK4 (1 << 4) /* Bit 4: Instruction Lockdown in Way Number 4 */ +# define L2CC_ILKR_ILK5 (1 << 5) /* Bit 5: Instruction Lockdown in Way Number 5 */ +# define L2CC_ILKR_ILK6 (1 << 6) /* Bit 6: Instruction Lockdown in Way Number 6 */ +# define L2CC_ILKR_ILK7 (1 << 7) /* Bit 7: Instruction Lockdown in Way Number 7 */ + +/* Lock Line Enable Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_LKLN_ENABLE (1 << 0) /* Bit 0: Lockdown by line enable */ +#endif + +/* Unlock Way Register */ + +#ifdef CONFIG_PL310_LOCKDOWN_BY_LINE +# define L2CC_UNLKW_WAY_SHIFT (0) /* Bits 0-15: Unlock line for corresponding way */ +# define L2CC_UNLKW_WAY_MASK (0xffff << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_SET(n) ((uint32_t)(n) << L2CC_UNLKW_WAY_SHIFT) +# define L2CC_UNLKW_WAY_BIT(n) ((1 << (n)) << L2CC_UNLKW_WAY_SHIFT) +#endif + +/* Address filter start */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLSTRT_ENABLE (1 << 0) /* Bit 0: Address filter enable */ +# define L2CC_FLSTRT_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Address filter end */ + +#ifdef PL310_ADDRESS_FILTERING +# define L2CC_FLEND_MASK (0xfff00000) /* Bits 20-31: Bits 20-31 of address mask */ +#endif + +/* Debug Control Register */ + +#define L2CC_DCR_DCL (1 << 0) /* Bit 0: Disable Cache Linefill */ +#define L2CC_DCR_DWB (1 << 1) /* Bit 1: Disable Write-back, Force Write-through */ +#define L2CC_DCR_SPNIDEN (1 << 2) /* Bit 2: SPNIDEN Value */ + +/* Prefetch Control Register */ + +#define L2CC_PCR_SHIFT (0) /* Bits 0-4: Prefetch Offset */ +#define L2CC_PCR_MASK (31 << L2CC_PCR_SHIFT) +# define L2CC_PCR_PREFETCH(n) ((uint32_t)(n) << L2CC_PCR_SHIFT) +#define L2CC_PCR_NSIDEN (1 << 21) /* Bit 21: Not Same ID on Exclusive Sequence Enable */ +#define L2CC_PCR_IDLEN (1 << 23) /* Bit 23: INCR Double Linefill Enable */ +#define L2CC_PCR_PDEN (1 << 24) /* Bit 24: Prefetch Drop Enable */ +#define L2CC_PCR_DLFWRDIS (1 << 27) /* Bit 27: Double Linefill on WRAP Read Disable */ +#define L2CC_PCR_DATPEN (1 << 28) /* Bit 28: Data Prefetch Enable */ +#define L2CC_PCR_INSPEN (1 << 29) /* Bit 29: Instruction Prefetch Enable */ +#define L2CC_PCR_DLEN (1 << 30) /* Bit 30: Double Linefill Enable */ + +/* Power Control Register */ + +#define L2CC_POWCR_STBYEN (1 << 0) /* Bit 0: Standby Mode Enable */ +#define L2CC_POWCR_DCKGATEN (1 << 1) /* Bit 1: Dynamic Clock Gating Enable */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_L2CC_PL310_H */ diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h new file mode 100644 index 0000000000000000000000000000000000000000..67aeb2e94a240db6b6f00282643b4590dca98065 --- /dev/null +++ b/arch/arm/src/armv7-r/mpu.h @@ -0,0 +1,742 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/mpu.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7R_MPU_H +#define __ARCH_ARM_SRC_ARMV7R_MPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +# include + +# include "up_arch.h" +# include "cp15.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MPU Type Register Bit Definitions */ + +#define MPUIR_SEPARATE (1 << 0) /* Bit 0: 0:unified or 1:separate memory maps */ +#define MPUIR_DREGION_SHIFT (8) /* Bits 8-15: Number MPU data regions */ +#define MPUIR_DREGION_MASK (0xff << MPUIR_DREGION_SHIFT) +#define MPUIR_IREGION_SHIFT (16) /* Bits 16-23: Number MPU instruction regions */ +#define MPUIR_IREGION_MASK (0xff << MPUIR_IREGION_SHIFT) + +/* Region Base Address Register Definitions */ + +#define MPU_RBAR_MASK 0xfffffffc + +/* Region Size and Enable Register */ + +#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */ +#define MPU_RASR_RSIZE_SHIFT (1) /* Bits 1-5: Size of the MPU protection region */ +#define MPU_RASR_RSIZE_MASK (31 << MPU_RASR_RSIZE_SHIFT) +# define MPU_RASR_RSIZE_LOG2(n) ((n-1) << MPU_RASR_RSIZE_SHIFT) + +#define MPU_RASR_SRD_SHIFT (8) /* Bits 8-15: Subregion disable */ +#define MPU_RASR_SRD_MASK (0xff << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_0 (0x01 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_1 (0x02 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_2 (0x04 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_3 (0x08 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_4 (0x10 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_5 (0x20 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_6 (0x40 << MPU_RASR_SRD_SHIFT) +# define MPU_RASR_SRD_7 (0x80 << MPU_RASR_SRD_SHIFT) + +/* Region Access Control Register */ + +#define MPU_RACR_B (1 << 0) /* Bit 0: Bufferable */ +#define MPU_RACR_C (1 << 1) /* Bit 1: Cacheable */ +#define MPU_RACR_S (1 << 2) /* Bit 2: Shareable */ +#define MPU_RACR_TEX_SHIFT (8) /* Bits 0-2: Memory attributes (with C and B) */ +#define MPU_RACR_TEX_MASK (7 << MPU_RACR_TEX_SHIFT) +# define MPU_RACR_TEX(n) ((uint32_t)(n) << MPU_RACR_TEX_SHIFT) +#define MPU_RACR_AP_SHIFT (8) /* Bits 8-10: Access permission */ +#define MPU_RACR_AP_MASK (7 << MPU_RACR_AP_SHIFT) +# define MPU_RACR_AP_NONO (0 << MPU_RACR_AP_SHIFT) /* PL0:None PL1:None */ +# define MPU_RACR_AP_RWNO (1 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:None */ +# define MPU_RACR_AP_RWRO (2 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:RO */ +# define MPU_RACR_AP_RWRW (3 << MPU_RACR_AP_SHIFT) /* PL0:RW PL1:RW */ +# define MPU_RACR_AP_RONO (5 << MPU_RACR_AP_SHIFT) /* PL0:RO PL1:None */ +# define MPU_RACR_AP_RORO (6 << MPU_RACR_AP_SHIFT) /* PL0:RO PL1:RO */ +#define MPU_RACR_XN (1 << 12) /* Bit 12: Instruction access disable */ + +/* MPU Region Number Register */ + +#if defined(CONFIG_ARM_MPU_NREGIONS) +# if CONFIG_ARM_MPU_NREGIONS <= 8 +# define MPU_RGNR_MASK (0x00000007) +# elif CONFIG_ARM_MPU_NREGIONS <= 16 +# define MPU_RGNR_MASK (0x0000000f) +# elif CONFIG_ARM_MPU_NREGIONS <= 32 +# define MPU_RGNR_MASK (0x0000001f) +# else +# error "FIXME: Unsupported number of MPU regions" +# endif +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mpu_allocregion + * + * Description: + * Allocate the next region + * + ****************************************************************************/ + +unsigned int mpu_allocregion(void); + +/**************************************************************************** + * Name: mpu_log2regionceil + * + * Description: + * Determine the smallest value of l2size (log base 2 size) such that the + * following is true: + * + * size <= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionceil(size_t size); + +/**************************************************************************** + * Name: mpu_log2regionfloor + * + * Description: + * Determine the largest value of l2size (log base 2 size) such that the + * following is true: + * + * size >= (1 << l2size) + * + ****************************************************************************/ + +uint8_t mpu_log2regionfloor(size_t size); + +/**************************************************************************** + * Name: mpu_subregion + * + * Description: + * Given (1) the offset to the beginning of valid data, (2) the size of the + * memory to be mapped and (2) the log2 size of the mapping to use, determine + * the minimal sub-region set to span that memory region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size); + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpu_get_mpuir + * + * Description: + * Read the MPUIR register the characteristics of the MPU + * + ****************************************************************************/ + +static inline unsigned int mpu_get_mpuir(void) +{ + unsigned int mpuir; + __asm__ __volatile__ + ( + "\tmrc " CP15_MPUIR(%0) + : "=r" (mpuir) + : + : "memory" + ); + + return mpuir; +} + +/**************************************************************************** + * Name: mpu_set_drbar + * + * Description: + * Wrtie to the DRBAR register + * + ****************************************************************************/ + +static inline void mpu_set_drbar(unsigned int drbar) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_DRBAR(%0) + : + : "r" (drbar) + : "memory" + ); +} + +/**************************************************************************** + * Name: mpu_set_drsr + * + * Description: + * Wrtie to the DRSR register + * + ****************************************************************************/ + +static inline void mpu_set_drsr(unsigned int drsr) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_DRSR(%0) + : + : "r" (drsr) + : "memory" + ); +} + +/**************************************************************************** + * Name: mpu_set_dracr + * + * Description: + * Wrtie to the DRACR register + * + ****************************************************************************/ + +static inline void mpu_set_dracr(unsigned int dracr) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_DRACR(%0) + : + : "r" (dracr) + : "memory" + ); +} + +/**************************************************************************** + * Name: mpu_set_irbar + * + * Description: + * Wrtie to the IRBAR register + * + ****************************************************************************/ + +#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED +static inline void mpu_set_irbar(unsigned int irbar) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_IRBAR(%0) + : + : "r" (irbar) + : "memory" + ); +} +#endif + +/**************************************************************************** + * Name: mpu_set_irsr + * + * Description: + * Wrtie to the IRSR register + * + ****************************************************************************/ + +#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED +static inline void mpu_set_irsr(unsigned int irsr) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_IRSR(%0) + : + : "r" (irsr) + : "memory" + ); +} +#endif + +/**************************************************************************** + * Name: mpu_set_iracr + * + * Description: + * Wrtie to the IRCR register + * + ****************************************************************************/ + +#ifndef CONFIG_ARM_HAVE_MPU_UNIFIED +static inline void mpu_set_iracr(unsigned int iracr) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_IRACR(%0) + : + : "r" (iracr) + : "memory" + ); +} +#endif + +/**************************************************************************** + * Name: mpu_set_rgnr + * + * Description: + * Wrtie to the IRCR register + * + ****************************************************************************/ + +static inline void mpu_set_rgnr(unsigned int rgnr) +{ + __asm__ __volatile__ + ( + "\tmcr " CP15_RGNR(%0) + : + : "r" (rgnr) + : "memory" + ); +} + +/**************************************************************************** + * Name: mpu_showtype + * + * Description: + * Show the characteristics of the MPU + * + ****************************************************************************/ + +static inline void mpu_showtype(void) +{ +#ifdef CONFIG_DEBUG + uint32_t regval = mpu_get_mpuir(); + dbg("%s MPU Regions: data=%d instr=%d\n", + (regval & MPUIR_SEPARATE) != 0 ? "Separate" : "Unified", + (regval & MPUIR_DREGION_MASK) >> MPUIR_DREGION_SHIFT, + (regval & MPUIR_IREGION_MASK) >> MPUIR_IREGION_SHIFT); +#endif +} + +/**************************************************************************** + * Name: mpu_control + * + * Description: + * Enable (or disable) the MPU + * + ****************************************************************************/ + +static inline void mpu_control(bool enable) +{ + uint32_t regval; + + /* Set/clear the following bits in the SCTLR: + * + * SCTLR_M Bit 0: MPU enable bit + * SCTLR_BR Bit 17: Background Region bit (not cleared) + */ + + regval = cp15_rdsctlr(); + if (enable) + { + regval |= (SCTLR_M | SCTLR_BR); + cp15_wrsctlr(regval); + } + else + { + regval &= ~SCTLR_M; + } + + cp15_wrsctlr(regval); +} + +/**************************************************************************** + * Name: mpu_priv_stronglyordered + * + * Description: + * Configure a region for privileged, strongly ordered memory + * + ****************************************************************************/ + +#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE) +static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = /* Not Cacheable */ + /* Not Bufferable */ + MPU_RACR_S | /* Shareable */ + MPU_RACR_AP_RWNO; /* P:RW U:None */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} +#endif + +/**************************************************************************** + * Name: mpu_user_flash + * + * Description: + * Configure a region for user program flash + * + ****************************************************************************/ + +static inline void mpu_user_flash(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = /* Not Cacheable */ + MPU_RACR_C | /* Cacheable */ + MPU_RACR_AP_RORO; /* P:RO U:RO */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_priv_flash + * + * Description: + * Configure a region for privileged program flash + * + ****************************************************************************/ + +static inline void mpu_priv_flash(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RACR_C | /* Cacheable */ + MPU_RACR_AP_RONO; /* P:RO U:None */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_user_intsram + * + * Description: + * Configure a region as user internal SRAM + * + ****************************************************************************/ + +static inline void mpu_user_intsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RACR_S | /* Shareable */ + MPU_RACR_C | /* Cacheable */ + MPU_RACR_AP_RWRW; /* P:RW U:RW */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_priv_intsram + * + * Description: + * Configure a region as privileged internal SRAM + * + ****************************************************************************/ + +static inline void mpu_priv_intsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RACR_S | /* Shareable */ + MPU_RACR_C | /* Cacheable */ + MPU_RACR_AP_RWNO; /* P:RW U:None */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_user_extsram + * + * Description: + * Configure a region as user external SRAM + * + ****************************************************************************/ + +static inline void mpu_user_extsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RACR_S | /* Shareable */ + MPU_RACR_C | /* Cacheable */ + MPU_RACR_B | /* Bufferable */ + MPU_RACR_AP_RWRW; /* P:RW U:RW */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_priv_extsram + * + * Description: + * Configure a region as privileged external SRAM + * + ****************************************************************************/ + +static inline void mpu_priv_extsram(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* The configure the region */ + + regval = MPU_RACR_S | /* Shareable */ + MPU_RACR_C | /* Cacheable */ + MPU_RACR_B | /* Bufferable */ + MPU_RACR_AP_RWNO; /* P:RW U:None */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +/**************************************************************************** + * Name: mpu_peripheral + * + * Description: + * Configure a region as privileged periperal address space + * + ****************************************************************************/ + +static inline void mpu_peripheral(uintptr_t base, size_t size) +{ + unsigned int region = mpu_allocregion(); + uint32_t regval; + uint8_t l2size; + uint8_t subregions; + + /* Select the region */ + + mpu_set_rgnr(region); + + /* Select the region base address */ + + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + + /* Select the region size and the sub-region map */ + + l2size = mpu_log2regionceil(size); + subregions = mpu_subregion(base, size, l2size); + + /* Then configure the region */ + + regval = MPU_RACR_S | /* Shareable */ + MPU_RACR_B | /* Bufferable */ + MPU_RACR_AP_RWNO | /* P:RW U:None */ + MPU_RACR_XN; /* Instruction access disable */ + mpu_set_dracr(regval); + + regval = MPU_RASR_ENABLE | /* Enable region */ + MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */ + ((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */ + mpu_set_drsr(regval); +} + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_ARMV7R_MPU_H */ diff --git a/arch/arm/src/armv7-r/sctlr.h b/arch/arm/src/armv7-r/sctlr.h new file mode 100644 index 0000000000000000000000000000000000000000..76ab8081df1ef26fe2ee33c37fa6128ff3028fda --- /dev/null +++ b/arch/arm/src/armv7-r/sctlr.h @@ -0,0 +1,545 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/sctlr.h + * CP15 System Control Registers + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.c (ID051414) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_SCTLR_H +#define __ARCH_ARM_SRC_ARMV7_R_SCTLR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* CP15 c0 Registers ****************************************************************/ + +/* Main ID Register (MIDR): CRn=c0, opc1=0, CRm=c0, opc2=0 + * TODO: To be provided + */ + +/* Cache Type Register (CTR): CRn=c0, opc1=0, CRm=c0, opc2=1 + * TODO: To be provided + */ + +/* TCM Type Register (TCMTR): CRn=c0, opc1=0, CRm=c0, opc2=2 + * Details implementation defined. + */ + +/* Aliases of Main ID register (MIDR): CRn=c0, opc1=0, CRm=c0, opc2=3,7 + * TODO: To be provided + */ + +/* MPU Type Register (MPUIR): CRn=c0, opc1=0, CRm=c0, opc2=4 + * TODO: To be provided + */ + +/* Multiprocessor Affinity Register (MPIDR): CRn=c0, opc1=0, CRm=c0, opc2=5 + * TODO: To be provided + */ + +/* Revision ID Register (REVIDR): CRn=c0, opc1=0, CRm=c0, opc2=6 + * TODO: To be provided + */ + +/* Processor Feature Register 0 (ID_PFR0): CRn=c0, opc1=0, CRm=c1, opc2=0 + * Processor Feature Register 1 (ID_PFR1): CRn=c0, opc1=0, CRm=c1, opc2=1 + * TODO: To be provided + */ + +/* Debug Feature Register 0 (ID_DFR0): CRn=c0, opc1=0, CRm=c1, opc2=2 + * TODO: To be provided + */ + +/* Auxiliary Feature Register 0 (ID_AFR0): CRn=c0, opc1=0, CRm=c1, opc2=3 + * TODO: To be provided + */ + +/* Memory Model Features Register 0 (ID_MMFR0): CRn=c0, opc1=0, CRm=c1, opc2=4 + * Memory Model Features Register 1 (ID_MMFR1): CRn=c0, opc1=0, CRm=c1, opc2=5 + * Memory Model Features Register 2 (ID_MMFR2): CRn=c0, opc1=0, CRm=c1, opc2=6 + * Memory Model Features Register 3 (ID_MMFR3): CRn=c0, opc1=0, CRm=c1, opc2=7 + * TODO: To be provided + */ + +/* Instruction Set Attributes Register 0 (ID_ISAR0): CRn=c0, opc1=0, CRm=c2, opc2=0 + * Instruction Set Attributes Register 1 (ID_ISAR1): CRn=c0, opc1=0, CRm=c2, opc2=1 + * Instruction Set Attributes Register 2 (ID_ISAR2): CRn=c0, opc1=0, CRm=c2, opc2=2 + * Instruction Set Attributes Register 3 (ID_ISAR3): CRn=c0, opc1=0, CRm=c2, opc2=3 + * Instruction Set Attributes Register 4 (ID_ISAR4): CRn=c0, opc1=0, CRm=c2, opc2=4 + * Instruction Set Attributes Register 5 (ID_ISAR5): CRn=c0, opc1=0, CRm=c2, opc2=5 + * Instruction Set Attributes Register 6-7 (ID_ISAR6-7). Reserved. + * TODO: Others to be provided + */ + +/* Reserved: CRn=c0, opc1=0, CRm=c3-c7, opc2=* */ + +/* Cache Size Identification Register (CCSIDR): CRn=c0, opc1=1, CRm=c0, opc2=0 + * TODO: To be provided + */ + +/* Cache Level ID Register (CLIDR): CRn=c0, opc1=1, CRm=c0, opc2=1 + * TODO: To be provided + */ + +/* Auxiliary ID Register (AIDR): CRn=c0, opc1=1, CRm=c0, opc2=7 + * TODO: To be provided + */ + +/* Cache Size Selection Register (CSSELR): CRn=c0, opc1=2, CRm=c0, opc2=0 + * TODO: To be provided + */ + +/* CP15 c1 Registers ****************************************************************/ +/* System Control Register (SCTLR): CRn=c1, opc1=0, CRm=c0, opc2=0 + */ + +#define SCTLR_M (1 << 0) /* Bit 0: MPU enable bit */ +#define SCTLR_A (1 << 1) /* Bit 1: Enables strict alignment of data */ +#define SCTLR_C (1 << 2) /* Bit 2: Determines if data can be cached */ + /* Bits 3-4: Reserved */ +#define SCTLR_CCP15BEN (1 << 5) /* Bit 5: CP15 barrier enable */ + /* Bit 6: Reserved */ +#define SCTLR_B (1 << 7) /* Bit 7: Should be zero on ARMv7-R */ + /* Bits 8-9: Reserved */ +#define SCTLR_SW (1 << 10) /* Bit 10: SWP/SWPB Enable bit */ +#define SCTLR_Z (1 << 11) /* Bit 11: Program flow prediction control */ +#define SCTLR_I (1 << 12) /* Bit 12: Determines if instructions can be cached */ +#define SCTLR_V (1 << 13) /* Bit 13: Vectors bit */ +#define SCTLR_RR (1 << 14) /* Bit 14: Cache replacement strategy */ + /* Bits 15-16: Reserved */ +#define SCTLR_BR (1 << 17) /* Bit 17: Background Region bit */ + /* Bit 18: Reserved */ +#define SCTLR_DZ (1 << 19) /* Bit 19: Divide by Zero fault enable bit */ + /* Bit 20: Reserved */ +#define SCTLR_FI (1 << 21) /* Bit 21: Fast interrupts configuration enable bit */ +#define SCTLR_U (1 << 22) /* Bit 22: Unaligned access model (always one) */ +#define SCTLR_VE (1 << 24) /* Bit 24: Interrupt Vectors Enable bit */ +#define SCTLR_EE (1 << 25) /* Bit 25: Determines the value the CPSR.E */ +#define SCTLR_NMFI (1 << 27) /* Bit 27: Non-maskable FIQ (NMFI) support */ + /* Bits 28-29: Reserved */ +#define SCTLR_TE (1 << 30) /* Bit 30: Thumb exception enable */ +#define SCTLR_IE (1 << 31) /* Bit 31: Instruction endian-ness */ + +/* Auxiliary Control Register (ACTLR): CRn=c1, opc1=0, CRm=c0, opc2=1 + * Implementation defined + */ + +/* Coprocessor Access Control Register (CPACR): CRn=c1, opc1=0, CRm=c0, opc2=2 + * TODO: To be provided + */ + +/* CP15 c2-c4 Registers *************************************************************/ +/* Not used on ARMv7-R */ + +/* CP15 c5 Registers ****************************************************************/ +/* Data Fault Status Register (DFSR): CRn=c5, opc1=0, CRm=c0, opc2=0 + * TODO: To be provided + */ + +/* Instruction Fault Status Register (IFSR): CRn=c5, opc1=0, CRm=c0, opc2=1 + * TODO: To be provided + */ + +/* Auxiliary DFSR (ADFSR): CRn=c5, opc1=0, CRm=c1, opc2=0 + * TODO: To be provided + */ + +/* Auxiliary IFSR (AIFSR): CRn=c5, opc1=0, CRm=c1, opc2=1 + * TODO: To be provided + */ + +/* CP15 c6 Registers ****************************************************************/ + +/* Data Fault Address Register(DFAR): CRn=c6, opc1=0, CRm=c0, opc2=0 + * + * Holds the MVA of the faulting address when a synchronous fault occurs + */ + +/* Instruction Fault Address Register(IFAR): CRn=c6, opc1=0, CRm=c0, opc2=1 + * + * Holds the MVA of the faulting address of the instruction that caused a prefetch + * abort. + */ + +/* Data Region Base Address Register (DRBAR): CRn=c6, opc1=0, CRm=c1, opc2=0 + * TODO: To be provided + */ + +/* Instruction Region Base Address Register (IRBAR): CRn=c6, opc1=0, CRm=c1, opc2=1 + * TODO: To be provided + */ + +/* Data Region Size and Enable Register (DRSR): CRn=c6, opc1=0, CRm=c1, opc2=2 + * TODO: To be provided + */ + +/* Instruction Region Size and Enable Register (IRSR): CRn=c6, opc1=0, CRm=c1, opc2=3 + * TODO: To be provided + */ + +/* Data Region Access Control Register (DRACR): CRn=c6, opc1=0, CRm=c1, opc2=4 + * TODO: To be provided + */ + +/* Instruction Region Access Control Register (IRACR): CRn=c6, opc1=0, CRm=c1, opc2=5 + * TODO: To be provided + */ + +/* MPU Region Number Register (RGNR): CRn=c6, opc1=0, CRm=c2, opc2=0 + * TODO: To be provided + */ + +/* CP15 c7 Registers ****************************************************************/ +/* See cp15_cacheops.h */ + +/* CP15 c8 Registers ****************************************************************/ +/* Not used on ARMv7-R */ + +/* CP15 c9 Registers ****************************************************************/ +/* 32-bit Performance Monitors Control Register (PMCR): CRn=c9, opc1=0, CRm=c12, opc2=0 + * TODO: To be provided + */ + +#define PCMR_E (1 << 0) /* Enable all counters */ +#define PCMR_P (1 << 1) /* Reset all counter eventts (except PMCCNTR) */ +#define PCMR_C (1 << 2) /* Reset cycle counter (PMCCNTR) to zero */ +#define PCMR_D (1 << 3) /* Enable cycle counter clock (PMCCNTR) divider */ +#define PCMR_X (1 << 4) /* Export of events is enabled */ +#define PCMR_DP (1 << 5) /* Disable PMCCNTR if event counting is prohibited */ +#define PCMR_N_SHIFT (11) /* Bits 11-15: Number of event counters */ +#define PCMR_N_MASK (0x1f << PCMR_N_SHIFT) +#define PCMR_IDCODE_SHIFT (16) /* Bits 16-23: Identification code */ +#define PCMR_IDCODE_MASK (0xff << PCMR_IDCODE_SHIFT) +#define PCMR_IMP_SHIFT (24) /* Bits 24-31: Implementer code */ +#define PCMR_IMP_MASK (0xff << PCMR_IMP_SHIFT) + +/* 32-bit Performance Monitors Count Enable Set register (PMCNTENSET): CRn=c9, opc1=0, CRm=c12, opc2=1 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Count Enable Clear register (PMCNTENCLR): CRn=c9, opc1=0, CRm=c12, opc2=2 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Overflow Flag Status Register (PMOVSR): CRn=c9, opc1=0, CRm=c12, opc2=3 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Software Increment register (PMSWINC): CRn=c9, opc1=0, CRm=c12, opc2=4 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Event Counter Selection Register (PMSELR): CRn=c9, opc1=0, CRm=c12, opc2=5 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Common Event Identification (PMCEID0): CRn=c9, opc1=0, CRm=c12, opc2=6 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Common Event Identification (PMCEID1): CRn=c9, opc1=0, CRm=c12, opc2=7 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Cycle Count Register (PMCCNTR): CRn=c9, opc1=0, CRm=c13, opc2=0 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Event Type Select Register (PMXEVTYPER): CRn=c9, opc1=0, CRm=c13, opc2=1 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Event Count Register (PMXEVCNTR): CRn=c9, opc1=0, CRm=c13, opc2=2 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors User Enable Register (PMUSERENR): CRn=c9, opc1=0, CRm=c14, opc2=0 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Interrupt Enable Set register (PMINTENSET): CRn=c9, opc1=0, CRm=c14, opc2=1 + * TODO: To be provided + */ + +/* 32-bit Performance Monitors Interrupt Enable Clear register (PMINTENCLR): CRn=c9, opc1=0, CRm=c14, opc2=2 + * TODO: To be provided + */ + +/* CP15 c10 Registers ***************************************************************/ +/* Not used on ARMv7-R */ + +/* CP15 c11 Registers ***************************************************************/ +/* Reserved for implementation defined DMA functions */ + +/* CP15 c12 Registers ***************************************************************/ +/* Not used on ARMv7-R */ + +/* CP15 c13 Registers ***************************************************************/ + +/* Context ID Register (CONTEXTIDR): CRn=c13, opc1=0, CRm=c0, opc2=1 + * 32-Bit ContextID value. + */ + +/* User Read/Write (TPIDRURW): CRn=c13, opc1=0, CRm=c0, opc2=2 + * TODO: To be provided + */ + +/* User Read Only (TPIDRURO): CRn=c13, opc1=0, CRm=c0, opc2=3 + * TODO: To be provided + */ + +/* PL1 only (TPIDRPRW): CRn=c13, opc1=0, CRm=c0, opc2=4 + * TODO: To be provided + */ + +/* CP15 c14 Registers ***************************************************************/ + +/* Counter Frequency register (CNTFRQ): CRn=c14, opc1=0, CRm=c0, opc2=0 + * TODO: To be provided + */ + +/* Timer PL1 Control register (CNTKCTL): CRn=c14, opc1=0, CRm=c1, opc2=0 + * TODO: To be provided + */ + +/* PL1 Physical TimerValue register (CNTP_TVAL): CRn=c14, opc1=0, CRm=c2, opc2=0 + * TODO: To be provided + */ + +/* PL1 Physical Timer Control register (CNTP_CTL): CRn=c14, opc1=0, CRm=c2, opc2=0 + * TODO: To be provided + */ + +/* Virtual TimerValue register (CNTV_TVAL): CRn=c14, opc1=0, CRm=c3, opc2=0 + * TODO: To be provided + */ + +/* Virtual Timer Control register (CNTV_CTL): CRn=c14, opc1=0, CRm=c3, opc2=0 + * TODO: To be provided + */ + +/* 64-bit Physical Count register (CNTPCT): CRn=c14, opc1=0, CRm=c14, opc2=n + * TODO: To be provided + */ + +/* Virtual Count register (CNTVCT): CRn=c14, opc1=1, CRm=c14, opc2=n + * TODO: To be provided + */ + +/* PL1 Physical Timer CompareValue register (CNTP_CVAL): CRn=c14, opc1=2, CRm=c14, opc2=n + * TODO: To be provided + */ + +/* Virtual Timer CompareValue register (CNTV_CVAL): CRn=c14, opc1=3, CRm=c14, opc2=n + * TODO: To be provided + */ + +/* CP15 c15 Registers ***************************************************************/ +/* Implementation defined */ + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ + +#ifdef __ASSEMBLY__ + +/* Get the device ID */ + + .macro cp15_rdid, id + mrc p15, 0, \id, c0, c0, 0 + .endm + +/* Read/write the system control register (SCTLR) */ + + .macro cp15_rdsctlr, sctlr + mrc p15, 0, \sctlr, c1, c0, 0 + .endm + + .macro cp15_wrsctlr, sctlr + mcr p15, 0, \sctlr, c1, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + .endm +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Get the device ID */ + +static inline unsigned int cp15_rdid(void) +{ + unsigned int id; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c0, c0, 0" + : "=r" (id) + : + : "memory" + ); + + return id; +} + +/* Read/write the system control register (SCTLR) */ + +static inline unsigned int cp15_rdsctlr(void) +{ + unsigned int sctlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0, 0\n" + : "=r" (sctlr) + : + : "memory" + ); + + return sctlr; +} + +static inline void cp15_wrsctlr(unsigned int sctlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c1, c0, 0\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + : + : "r" (sctlr) + : "memory" + ); +} + +/* Read/write the implementation defined Auxiliary Control Regster (ACTLR) */ + +static inline unsigned int cp15_rdactlr(void) +{ + unsigned int actlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0, 1\n" + : "=r" (actlr) + : + : "memory" + ); + + return actlr; +} + +static inline void cp15_wractlr(unsigned int actlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c1, c0, 1\n" + : + : "r" (actlr) + : "memory" + ); +} + +/* Read/write the Performance Monitor Control Register (PMCR) */ + +static inline unsigned int cp15_rdpmcr(void) +{ + unsigned int pmcr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c9, c12, 0\n" + : "=r" (pmcr) + : + : "memory" + ); + + return pmcr; +} + +static inline void cp15_wrpmcr(unsigned int pmcr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, %0, c9, c12, 0\n" + : + : "r" (pmcr) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_R_SCTLR_H */ diff --git a/arch/arm/src/armv7-r/svcall.h b/arch/arm/src/armv7-r/svcall.h new file mode 100644 index 0000000000000000000000000000000000000000..8ee1ec2730c2912c70dbb1f8b3508f856905fc06 --- /dev/null +++ b/arch/arm/src/armv7-r/svcall.h @@ -0,0 +1,130 @@ +/************************************************************************************ + * arch/arm/src/armv7-r/svcall.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_R_SVCALL_H +#define __ARCH_ARM_SRC_ARMV7_R_SVCALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifdef CONFIG_LIB_SYSCALL +# include +#endif + +#ifdef CONFIG_LIB_SYSCALL + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ +/* This logic uses one system call for the syscall return. So a minimum of one + * syscall values must be reserved. If CONFIG_BUILD_PROTECTED is defined, then four + * more syscall values must be reserved. + */ + +#ifdef CONFIG_BUILD_PROTECTED +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 6" +# elif CONFIG_SYS_RESERVED != 6 +# error "CONFIG_SYS_RESERVED must have the value 6" +# endif +#else +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to have the value 1" +# elif CONFIG_SYS_RESERVED != 1 +# error "CONFIG_SYS_RESERVED must have the value 1" +# endif +#endif + +/* Cortex-R system calls ************************************************************/ + +/* SYS call 0: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (0) + +#ifdef CONFIG_BUILD_PROTECTED +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_context_restore (1) + +/* SYS call 2: + * + * void up_task_start(main_t taskentry, int argc, FAR char *argv[]) + * noreturn_function; + */ + +#define SYS_task_start (2) + +/* SYS call 3: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (3) + +/* SYS call 4: + * + * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, + * FAR void *ucontext); + */ + +#define SYS_signal_handler (4) + +/* SYS call 5: + * + * void signal_handler_return(void); + */ + +#define SYS_signal_handler_return (5) + +#endif /* CONFIG_BUILD_PROTECTED */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* CONFIG_LIB_SYSCALL */ +#endif /* __ARCH_ARM_SRC_ARMV7_R_SVCALL_H */ diff --git a/arch/arm/src/c5471/Kconfig b/arch/arm/src/c5471/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..17b615a0973de6b10fe31faaecf11b7afd0054fc --- /dev/null +++ b/arch/arm/src/c5471/Kconfig @@ -0,0 +1,112 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "C5471 Configuration Options" + +menu "IrDA UART Configuration" + +config UART_IRDA_BAUD + int "IrDA UART BAUD" + default 115200 + +config UART_IRDA_PARITY + int "IrDA UART parity" + default 0 + ---help--- + IrDA UART parity. 0=None, 1=Odd, 2=Even. Default: None + +config UART_IRDA_BITS + int "IrDA UART number of bits" + default 8 + ---help--- + IrDA UART number of bits. Default: 8 + +config UART_IRDA_2STOP + int "IrDA UART two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config UART_IRDA_RXBUFSIZE + int "IrDA UART Rx buffer size" + default 256 + ---help--- + IrDA UART Rx buffer size. Default: 256 + +config UART_IRDA_TXBUFSIZE + int "IrDA UART Tx buffer size" + default 256 + ---help--- + IrDA UART Tx buffer size. Default: 256 + +endmenu # IrDA UART Configuration + +menu "Modem UART Configuration" + +config UART_MODEM_BAUD + int "IrDA UART BAUD" + default 115200 + +config UART_MODEM_PARITY + int "IrDA UART parity" + default 0 + ---help--- + IrDA UART parity. 0=None, 1=Odd, 2=Even. Default: None + +config UART_MODEM_BITS + int "IrDA UART number of bits" + default 8 + ---help--- + IrDA UART number of bits. Default: 8 + +config UART_MODEM_2STOP + int "IrDA UART two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config UART_MODEM_RXBUFSIZE + int "IrDA UART Rx buffer size" + default 256 + ---help--- + IrDA UART Rx buffer size. Default: 256 + +config UART_MODEM_TXBUFSIZE + int "IrDA UART Tx buffer size" + default 256 + ---help--- + IrDA UART Tx buffer size. Default: 256 + +endmenu # Modem UART Configuration + +choice + prompt "Ethernet PHY" + default C5471_PHY_LU3X31T_T64 + +config C5471_PHY_NONE + bool "None" + +config C5471_PHY_AC101L + bool "AC101L" + +config C5471_PHY_LU3X31T_T64 + bool "LU3X31T T64" + +endchoice + +choice + prompt "PHY mode" + default C5471_AUTONEGOTIATION + +config C5471_AUTONEGOTIATION + bool "Autonegotiation" + +config C5471_BASET100 + bool "100BaseT FullDuplex" + +config C5471_BASET10 + bool "10BaseT FullDuplex" + +endchoice diff --git a/arch/arm/src/c5471/Make.defs b/arch/arm/src/c5471/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..92320e5d480af0fc2b7d5d84672d5c1b59e62daa --- /dev/null +++ b/arch/arm/src/c5471/Make.defs @@ -0,0 +1,63 @@ +############################################################################ +# c5471/Make.defs +# +# Copyright (C) 2007, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = up_nommuhead.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c up_doirq.c +CMN_CSRCS += up_exit.c up_idle.c up_initialize.c up_initialstate.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = c5471_lowputc.S c5471_vectors.S +CHIP_CSRCS = c5471_irq.c c5471_serial.c c5471_watchdog.c c5471_ethernet.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += c5471_timerisr.c +endif diff --git a/arch/arm/src/c5471/c5471_ethernet.c b/arch/arm/src/c5471/c5471_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..11c157f35f41c7f5d401235a16308c4b3d9d0d7b --- /dev/null +++ b/arch/arm/src/c5471/c5471_ethernet.c @@ -0,0 +1,2270 @@ +/**************************************************************************** + * arch/arm/src/c5471/c5471_ethernet.c + * + * Copyright (C) 2007, 2009-2010, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based one a C5471 Linux driver and released under this BSD license with + * special permission from the copyright holder of the Linux driver: + * Todd Fischer, Cadenux, LLC. Other references: "TMS320VC547x CPU and + * Peripherals Reference Guide," TI document spru038.pdf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* CONFIG_C5471_NET_NINTERFACES determines the number of physical interfaces + * that will be supported. + */ + +#ifndef CONFIG_C5471_NET_NINTERFACES +# define CONFIG_C5471_NET_NINTERFACES 1 +#endif + +/* CONFIG_C5471_NET_STATS will enabled collection of driver statistics. + * Default is disabled. + */ + +/* Mode of operation defaults to AUTONEGOTIATION */ + +#if defined(CONFIG_C5471_AUTONEGOTIATION) +# undef CONFIG_C5471_BASET100 +# undef CONFIG_C5471_BASET10 +#elif defined(CONFIG_C5471_BASET100) +# undef CONFIG_C5471_AUTONEGOTIATION +# undef CONFIG_C5471_BASET10 +#elif defined(CONFIG_C5471_BASET10) +# undef CONFIG_C5471_AUTONEGOTIATION +# undef CONFIG_C5471_BASET100 +#else +# define CONFIG_C5471_AUTONEGOTIATION 1 +# undef CONFIG_C5471_BASET100 +# undef CONFIG_C5471_BASET10 +#endif + +/* This should be disabled unless you are performing very low level debug */ + +#undef CONFIG_C5471_NET_DUMPBUFFER +//#define CONFIG_C5471_NET_DUMPBUFFER 1 + +/* Timing values ************************************************************/ +/* TX poll deley = 1 seconds. CLK_TCK=number of clock ticks per second */ + +#define C5471_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define C5471_TXTIMEOUT (60*CLK_TCK) + +/* Ethernet GPIO bit settings ***********************************************/ + +#define GPIO_CIO_MDIO 0x00004000 +#define GPIO_IO_MDCLK 0x00008000 + +/* Ethernet interface bit settings ******************************************/ + +/* TX descriptor, word #0 */ + +#define EIM_TXDESC_OWN_HOST 0x80000000 /* Bit 15: Ownership bit */ +#define EIM_TXDESC_OWN_ENET 0x00000000 +#define EIM_TXDESC_WRAP_NEXT 0x40000000 /* Bit 14: Descriptor chain wrap */ +#define EIM_TXDESC_WRAP_FIRST 0x00000000 +#define EIM_TXDESC_FIF 0x20000000 /* Bit 13: First in frame */ +#define EIM_TXDESC_LIF 0x10000000 /* Bit 12: Last in frame */ + /* Bits 8-11: Retry count status */ +#define EIM_TXDESC_INTRE 0x00800000 /* Bit 7: TX_IRQ int enable */ +#define EIM_TXDESC_STATUSMASK 0x007f0000 /* Bits 0-6: Status */ +#define EIM_TXDESC_RETRYERROR 0x00400000 /* Exceed retry error */ +#define EIM_TXDESC_HEARTBEAT 0x00200000 /* Heartbeat (SQE) */ +#define EIM_TXDESC_LCOLLISON 0x00100000 /* Late collision error */ +#define EIM_TXDESC_COLLISION 0x00080000 /* Collision */ +#define EIM_TXDESC_CRCERROR 0x00040000 /* CRC error */ +#define EIM_TXDESC_UNDERRUN 0x00020000 /* Underrun error */ +#define EIM_TXDESC_LOC 0x00010000 /* Loss of carrier */ + +/* Packet bytes value used for both TX and RX descriptors */ + +#define EIM_PACKET_BYTES 0x00000040 + +/* Count of descriptors */ + +#define NUM_DESC_TX 32 +#define NUM_DESC_RX 64 + +/* TX descriptor, word #1 */ + /* Bit 15: reserved */ +#define EIM_TXDESC_PADCRC 0x00004000 /* Bit 14: Enable padding small frames */ + /* Bits 11-13: reserved */ +#define EIM_TXDESC_BYTEMASK 0x000007ff /* Bits 0-10: Descriptor byte count */ + +/* RX descriptor, word #0 */ + +#define EIM_RXDESC_OWN_HOST 0x80000000 /* Bit 15: Ownership bit */ +#define EIM_RXDESC_OWN_ENET 0x00000000 +#define EIM_RXDESC_WRAP_NEXT 0x40000000 /* Bit 14: Descriptor chain wrap */ +#define EIM_RXDESC_WRAP_FIRST 0x00000000 +#define EIM_RXDESC_FIF 0x20000000 /* Bit 13: First in frame */ +#define EIM_RXDESC_LIF 0x10000000 /* Bit 12: Last in frame */ + /* Bits 8-11: reserved */ +#define EIM_RXDESC_INTRE 0x00800000 /* Bit 7: RX_IRQ int enable */ +#define EIM_RXDESC_STATUSMASK 0x007f0000 /* Bits 0-6: Status */ +#define EIM_RXDESC_MISS 0x00400000 /* Miss */ +#define EIM_RXDESC_VLAN 0x00200000 /* VLAN */ +#define EIM_RXDESC_LFRAME 0x00100000 /* Long frame error */ +#define EIM_RXDESC_SFRAME 0x00080000 /* Short frame error */ +#define EIM_RXDESC_CRCERROR 0x00040000 /* CRC error */ +#define EIM_RXDESC_OVERRUN 0x00020000 /* Overrun error */ +#define EIM_RXDESC_ALIGN 0x00010000 /* Non-octect align error */ + +#define EIM_RXDESC_PADCRC 0x00004000 /* Enable padding for small frames */ + +/* RX descriptor, word #1 */ + /* Bits 11-15: reserved */ +#define EIM_RXDESC_BYTEMASK 0x000007ff /* Bits 0-10: Descriptor byte count */ + +/* EIM_CPU_FILTER bit settings */ + /* Bits 5-31: reserved */ +#define EIM_FILTER_MACLA 0x00000010 /* Bit 4: Enable logical address+multicast filtering */ +#define EIM_FILTER_LOGICAL 0x00000008 /* Bit 3: Enable ENET logical filtering */ +#define EIM_FILTER_MULTICAST 0x00000004 /* Bit 2: Enable multicast filtering */ +#define EIM_FILTER_BROADCAST 0x00000002 /* Bit 1: Enable broadcast matching */ +#define EIM_FILTER_UNICAST 0x00000001 /* Bit 0: Enable dest CPU address matching */ + +/* EIM_CTRL bit settings */ + /* Bits 16-31: Reserved */ +#define EIM_CTRL_ESM_EN 0x00008000 /* Bit 15: Ethernet state machine enable */ + /* Bits 9-14: reserved */ +#define EIM_CTRL_ENET0_EN 0x00000100 /* Bit 8: Enable routing of RX packets CPU->ENET0 */ + /* Bit 7: reserved */ +#define EIM_CTRL_ENET0_FLW 0x00000040 /* Bit 6: Enable ENET0 flow control RX threshold */ +#define EIM_CTRL_RXENET0_EN 0x00000020 /* Bit 5: Enable processing of ENET0 RX queue */ +#define EIM_CTRL_TXENET0_EN 0x00000010 /* Bit 4: Enable processing of ENET0 TX queue */ + /* Bits 2-3: reserved */ +#define EIM_CTRL_RXCPU_EN 0x00000002 /* Bit 1: Enable processing of CPU RX queue */ +#define EIM_CTRL_TXCPU_EN 0x00000001 /* Bit 0: Enable processing of CPU TX queue */ + +/* EIM_STATUS bit settings */ + /* Bits 10-31: reserved */ +#define EIM_STATUS_CPU_TXLIF 0x00000200 /* Bit 9: Last descriptor of TX packet filled */ +#define EIM_STATUS_CPU_RXLIF 0x00000100 /* Bit 8: Last descriptor of RX queue processed */ +#define EIM_STATUS_CPU_TX 0x00000080 /* Bit 7: Descriptor filled in TX queue */ +#define EIM_STATUS_CPU_RX 0x00000040 /* Bit 6: Descriptor filled in RX queue */ + /* Bits 3-5: reserved */ +#define EIM_STATUS_ENET0_ERR 0x00000004 /* Bit 2: ENET0 error interrupt */ +#define EIM_STATUS_ENET0_TX 0x00000002 /* Bit 1: ENET0 TX interrupt */ +#define EIM_STATUS_ENET0_RX 0x00000001 /* Bit 0" ENET0 RX interrupt */ + +/* EIM_INTEN bit settings */ + +#define EIM_INTEN_CPU_TXLIF 0x00000200 /* Bit 9: Last descriptor of TX packet filled */ +#define EIM_INTEN_CPU_RXLIF 0x00000100 /* Bit 8: Last descriptor of RX queue processed */ +#define EIM_INTEN_CPU_TX 0x00000080 /* Bit 7: Descriptor filled in TX queue */ +#define EIM_INTEN_CPU_RX 0x00000040 /* Bit 6: Descriptor filled in RX queue */ + /* Bits 3-5: reserved */ +#define EIM_INTEN_ENET0_ERR 0x00000004 /* Bit 2: ENET0 error interrupt */ +#define EIM_INTEN_ENET0_TX 0x00000002 /* Bit 1: ENET0 TX interrupt */ +#define EIM_INTEN_ENET0_RX 0x00000001 /* Bit 0: ENET0 RX interrupt */ + +/* ENET0_ADRMODE_EN bit settings */ + +#define ENET_ADR_PROMISCUOUS 0x00000008 /* Bit 3: Enable snoop address comparison */ +#define ENET_ADR_BROADCAST 0x00000004 /* Bit 2: Enable broadcast address comparison */ +#define ENET_ADDR_LCOMPARE 0x00000002 /* Bit 1: Enable logical address comparison */ +#define ENET_ADDR_PCOMPARE 0x00000001 /* Bit 0: Enable physical address comparison */ + +/* ENET0_MODE bit settings */ + /* Bits 16-31: reserved */ +#define ENET_MODO_FIFO_EN 0x00008000 /* Bit 15: Fifo enable */ + /* Bits 8-14: reserved */ +#define ENET_MODE_RJCT_SFE 0x00000080 /* Bit 7: Reject short frames durig receive */ +#define ENET_MODE_DPNET 0x00000040 /* Bit 6: Demand priority networkd vs CSMA/CD */ +#define ENET_MODE_MWIDTH 0x00000020 /* Bit 5: Select nibble mode MII port */ +#define ENET_MODE_WRAP 0x00000010 /* Bit 4: Internal MAC loopback */ +#define ENET_MODE_FDWRAP 0x00000008 /* Bit 3: Full duplex wrap */ +#define ENET_MODE_FULLDUPLEX 0x00000004 /* Bit 2: 1:Full duplex */ +#define ENET_MODE_HALFDUPLEX 0x00000000 /* 0:Half duplex */ + /* Bit 1: reserved */ +#define ENET_MODE_ENABLE 0x00000001 /* Bit 0: Port enable */ + +/* PHY registers */ + +#define MD_PHY_CONTROL_REG 0x00 +#define MD_PHY_MSB_REG 0x02 +#define MD_PHY_LSB_REG 0x03 +#define MD_PHY_CTRL_STAT_REG 0x17 + +/* Lucent LU3X31T-T64 transeiver ID */ + +#define LU3X31_T64_PHYID 0x00437421 + +/* PHY control register bit settings */ + +#define MODE_AUTONEG 0x1000 +#define MODE_10MBIT_HALFDUP 0x0000 +#define MODE_10MBIT_FULLDUP 0x0100 +#define MODE_100MBIT_FULLDUP 0x2100 +#define MODE_100MBIT_HALFDUP 0x2000 + +/* Inserts an ARM "nop" instruction */ + +#define nop() asm(" nop"); + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)c5471->c_dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The c5471_driver_s encapsulates all state information for a single c5471 + * hardware interface + */ + +struct c5471_driver_s +{ + bool c_bifup; /* true:ifup false:ifdown */ + WDOG_ID c_txpoll; /* TX poll timer */ + WDOG_ID c_txtimeout; /* TX timeout timer */ + + /* Note: According to the C547x documentation: "The software has to maintain + * two pointers to the current RX-CPU and TX-CPU descriptors. At init time, + * they have to be set to the first descriptors of each queue, and they have + * to be incremented each time a descriptor ownership is give to the SWITCH". + */ + + volatile uint32_t c_txcpudesc; + volatile uint32_t c_rxcpudesc; + + /* Last TX descriptor saved for error handling */ + + uint32_t c_lastdescstart; + uint32_t c_lastdescend; + + /* Shadowed registers */ + + uint32_t c_eimstatus; + +#ifdef CONFIG_C5471_NET_STATS + /* TX statistics */ + + uint32_t c_txpackets; /* Number of packets sent */ + uint32_t c_txmiss; /* Miss */ + uint32_t c_txvlan; /* VLAN */ + uint32_t c_txlframe; /* Long frame errors */ + uint32_t c_txsframe; /* Short frame errors */ + uint32_t c_txcrc; /* CRC errors */ + uint32_t c_txoverrun; /* Overrun errors */ + uint32_t c_txalign; /* Non-octect align errors */ + uint32_t c_txtimeouts; /* TX timeouts */ + + uint32_t c_rxpackets; /* Number of packets received */ + uint32_t c_rxretries; /* Exceed retry errors */ + uint32_t c_rxheartbeat; /* Heartbeat (SQE) */ + uint32_t c_rxlcollision; /* Late collision errors */ + uint32_t c_rxcollision; /* Collision */ + uint32_t c_rxcrc; /* CRC errors */ + uint32_t c_rxunderrun; /* Underrun errors */ + uint32_t c_rxloc; /* Loss of carrier */ + uint32_t c_rxdropped; /* Packets dropped because of size */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s c_dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct c5471_driver_s g_c5471[CONFIG_C5471_NET_NINTERFACES]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Transceiver interface */ + +static void c5471_mdtxbit (int bit_state); +static int c5471_mdrxbit (void); +static void c5471_mdwrite (int adr, int reg, int data); +static int c5471_mdread (int adr, int reg); +static int c5471_phyinit (void); + +/* Support logic */ + +static inline void c5471_inctxcpu(struct c5471_driver_s *c5471); +static inline void c5471_incrxcpu(struct c5471_driver_s *c5471); + +/* Common TX logic */ + +static int c5471_transmit(struct c5471_driver_s *c5471); +static int c5471_txpoll(struct net_driver_s *dev); + +/* Interrupt handling */ + +#ifdef CONFIG_C5471_NET_STATS +static void c5471_rxstatus(struct c5471_driver_s *c5471); +#endif +static void c5471_receive(struct c5471_driver_s *c5471); +#ifdef CONFIG_C5471_NET_STATS +static void c5471_txstatus(struct c5471_driver_s *c5471); +#endif +static void c5471_txdone(struct c5471_driver_s *c5471); +static int c5471_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static void c5471_polltimer(int argc, uint32_t arg, ...); +static void c5471_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int c5471_ifup(struct net_driver_s *dev); +static int c5471_ifdown(struct net_driver_s *dev); +static int c5471_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int c5471_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int c5471_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif + +/* Initialization functions */ + +static void c5471_eimreset (struct c5471_driver_s *c5471); +static void c5471_eimconfig(struct c5471_driver_s *c5471); +static void c5471_reset(struct c5471_driver_s *c5471); +static void c5471_macassign(struct c5471_driver_s *c5471); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: c5471_dumpbuffer + * + * Description + * Debug only + * + ****************************************************************************/ + +#ifdef CONFIG_C5471_NET_DUMPBUFFER +static inline void c5471_dumpbuffer(const char *msg, const uint8_t *buffer, unsigned int nbytes) +{ + /* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_NET have to be + * defined or the following does nothing. + */ + + nvdbgdumpbuffer(msg, buffer, nbytes); +} +#else +# define c5471_dumpbuffer(msg, buffer,nbytes) +#endif + +/**************************************************************************** + * Name: c5471_mdtxbit + * + * Description + * A helper routine used when serially communicating with the c547X's + * external ethernet transeiver device. GPIO pins are connected to the + * transeiver's MDCLK and MDIO pins and are used to accomplish the serial + * comm. + * + * protocol: + * ___________ + * MDCLK ________/ \_ + * ________:____ + * MDIO <________:____>-------- + * : + * ^ + * Pin state internalized + * + ****************************************************************************/ + +static void c5471_mdtxbit (int bit_state) +{ + /* Note: any non-zero "bit_state" supplied by the caller means we should clk a "1" + * out the MDIO pin. + */ + + /* Config MDIO as output pin. */ + + putreg32((getreg32(GPIO_CIO) & ~GPIO_CIO_MDIO), GPIO_CIO); + + /* Select the bit output state */ + + if (bit_state) + { + /* set MDIO state high. */ + + putreg32((getreg32(GPIO_IO) | GPIO_CIO_MDIO), GPIO_IO); + } + else + { + /* set MDIO state low. */ + + putreg32((getreg32(GPIO_IO) & ~GPIO_CIO_MDIO), GPIO_IO); + } + + nop(); + nop(); + nop(); + nop(); + + /* MDCLK rising edge */ + + putreg32((getreg32(GPIO_IO) | GPIO_IO_MDCLK), GPIO_IO); + nop(); + nop(); + + /* release MDIO */ + + putreg32((getreg32(GPIO_CIO) | GPIO_CIO_MDIO), GPIO_CIO); + nop(); + nop(); + + /* MDCLK falling edge. */ + + putreg32((getreg32(GPIO_IO) & ~GPIO_IO_MDCLK), GPIO_IO); +} + +/**************************************************************************** + * Name: c5471_mdrxbit + * + * Description + * A helper routine used when serially communicating with the c547X's + * external ethernet transeiver device. GPIO pins are connected to the + * transeiver's MDCLK and MDIO pins and are used to accomplish the serial + * comm. + * + * protocol: + * ___________ + * MDCLK ________/ \_ + * _______:_____ + * MDIO _______:_____>-------- + * : + * ^ + * pin state sample point + * + ****************************************************************************/ + +static int c5471_mdrxbit (void) +{ + register volatile uint32_t bit_state; + + /* config MDIO as input pin. */ + + putreg32((getreg32(GPIO_CIO) | GPIO_CIO_MDIO), GPIO_CIO); + + /* Make sure the MDCLK is low */ + + putreg32((getreg32(GPIO_IO) & ~GPIO_IO_MDCLK), GPIO_IO); + nop(); + nop(); + nop(); + nop(); + + /* Sample MDIO */ + + bit_state = getreg32(GPIO_IO) & GPIO_CIO_MDIO; + + /* MDCLK rising edge */ + + putreg32((getreg32(GPIO_IO) | GPIO_IO_MDCLK), GPIO_IO); + nop(); + nop(); + nop(); + nop(); + + /* MDCLK falling edge. */ + + putreg32((getreg32(GPIO_IO) & ~GPIO_IO_MDCLK), GPIO_IO); /* MDCLK falling edge */ + if (bit_state) + { + return 1; + } + else + { + return OK; + } +} + +/**************************************************************************** + * Name: c5471_mdwrite + * + * Description + * A helper routine used when serially communicating with the c547X's + * external ethernet transeiver device. GPIO pins are connected to the + * transeiver's MDCLK and MDIO pins and are used to accomplish the serial + * comm. + * + ****************************************************************************/ + +static void c5471_mdwrite (int adr, int reg, int data) +{ + int i; + + /* preamble: 11111111111111111111111111111111 */ + + for (i = 0; i < 32; i++) + { + c5471_mdtxbit(1); + } + + /* start of frame: 01 */ + + c5471_mdtxbit(0); + c5471_mdtxbit(1); + + /* operation code: 01 - write */ + + c5471_mdtxbit(0); + c5471_mdtxbit(1); + + /* PHY device address: AAAAA, msb first */ + + for (i = 0; i < 5; i++) + { + c5471_mdtxbit(adr & 0x10); + adr = adr << 1; + } + + /* MII register address: RRRRR, msb first */ + + for (i = 0; i < 5; i++) + { + c5471_mdtxbit(reg & 0x10); + reg = reg << 1; + } + + /* Turnaround time: ZZ */ + + c5471_mdtxbit(1); + c5471_mdtxbit(0); + + /* data: DDDDDDDDDDDDDDDD, msb first */ + + for (i = 0; i < 16; i++) + { + c5471_mdtxbit(data & 0x8000); + data = data << 1; + } +} + +/**************************************************************************** + * Name: c5471_mdread + * + * Description + * A helper routine used when serially communicating with the c547X's + * external ethernet transeiver device. GPIO pins are connected to the + * transeiver's MDCLK and MDIO pins and are used to accomplish the serial + * comm. + * + ****************************************************************************/ + +static int c5471_mdread (int adr, int reg) +{ + int i; + int data = 0; + + /* preamble: 11111111111111111111111111111111 */ + + for (i = 0; i < 32; i++) + { + c5471_mdtxbit(1); + } + + /* start of frame: 01 */ + + c5471_mdtxbit(0); + c5471_mdtxbit(1); + + /* operation code: 10 - read */ + + c5471_mdtxbit(1); + c5471_mdtxbit(0); + + /* PHY device address: AAAAA, msb first */ + + for (i = 0; i < 5; i++) + { + c5471_mdtxbit(adr & 0x10); + adr = adr << 1; + } + + /* MII register address: RRRRR, msb first */ + + for (i = 0; i < 5; i++) + { + c5471_mdtxbit(reg & 0x10); + reg = reg << 1; + } + + /* turnaround time: ZZ */ + + c5471_mdrxbit(); + c5471_mdrxbit(); /* PHY should drive a 0 */ + + /* data: DDDDDDDDDDDDDDDD, msb first */ + + for (i = 0; i < 16; i++) + { + data = data << 1; + data |= c5471_mdrxbit(); + } + + return data; +} + +/**************************************************************************** + * Name: c5471_phyinit + * + * Description + * The c547X EVM board uses a Lucent LU3X31T-T64 transeiver device to + * handle the physical layer (PHY). It's a h/w block that on the one end + * offers a Media Independent Interface (MII) which is connected to the + * Ethernet Interface Module (EIM) internal to the C547x and on the other + * end offers either the 10baseT or 100baseT electrical interface connecting + * to an RJ45 onboard network connector. The PHY transeiver has several + * internal registers allowing host configuration and status access. These + * internal registers are accessable by clocking serial data in/out of the + * MDIO pin of the LU3X31T-T64 chip. For c547X, the MDC and the MDIO pins + * are connected to the C547x GPIO15 and GPIO14 pins respectivley. Host + * software twiddles the GPIO pins appropriately to get data serially into + * and out of the chip. This is typically a one time operation at boot and + * normal operation of the transeiver involves EIM/Transeiver interaction at + * the other pins of the transeiver chip and doesn't require host intervention + * at the MDC and MDIO pins. + * + ****************************************************************************/ + +#if defined(CONFIG_C5471_PHY_LU3X31T_T64) +static int c5471_phyinit (void) +{ + int phyid; + int status; + + /* Next, Setup GPIO pins to talk serially to the Lucent transeiver chip */ + + /* enable gpio bits 15,14 */ + + putreg32((getreg32(GPIO_EN) | 0x0000C000), GPIO_EN); + + /* config gpio(15); out -> MDCLK */ + + putreg32((getreg32(GPIO_CIO) & ~0x00008000), GPIO_CIO); + + /* config gpio(14); in <- MDIO */ + + putreg32((getreg32(GPIO_CIO) | 0x00004000), GPIO_CIO); + + /* initial pin state; MDCLK = 0 */ + + putreg32((getreg32(GPIO_IO) & 0x000F3FFF), GPIO_IO); + + /* Next, request a chip reset */ + + c5471_mdwrite(0, MD_PHY_CONTROL_REG, 0x8000); + while (c5471_mdread(0, MD_PHY_CONTROL_REG) & 0x8000) + { + /* wait for chip reset to complete */ + } + + /* Next, Read out the chip ID */ + + phyid = (c5471_mdread(0, MD_PHY_MSB_REG) << 16) | c5471_mdread(0, MD_PHY_LSB_REG); + if (phyid != LU3X31_T64_PHYID) + { + ndbg("Unrecognized PHY ID: %08x\n", phyid); + return ERROR; + } + + /* Next, Set desired network rate, 10BaseT, 100BaseT, or auto. */ + +#ifdef CONFIG_C5471_AUTONEGOTIATION + ndbg("Setting PHY Transceiver for Autonegotiation\n"); + c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_AUTONEG); +#endif +#ifdef CONFIG_C5471_BASET100 + ndbg("Setting PHY Transceiver for 100BaseT FullDuplex\n"); + c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_100MBIT_FULLDUP); +#endif +#ifdef CONFIG_C5471_BASET10 + ndbg("Setting PHY Transceiver for 10BaseT FullDuplex\n"); + c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_10MBIT_FULLDUP); +#endif + + status = c5471_mdread(0, MD_PHY_CTRL_STAT_REG); + return status; +} + +#elif defined(CONFIG_C5471_PHY_AC101L) + +static int c5471_phyinit (void) +{ + int phyid; + int status; + + /* Next, Setup GPIO pins to talk serially to the Lucent transeiver chip */ + + putreg32((getreg32(GPIO_EN) | 0x0000C000), GPIO_EN); /* enable gpio bits 15,14 */ + putreg32((getreg32(GPIO_CIO) & ~0x00008000), GPIO_CIO); /* config gpio(15); out -> MDCLK */ + putreg32((getreg32(GPIO_CIO) | 0x00004000), GPIO_CIO); /* config gpio(14); in <- MDIO */ + putreg32((getreg32(GPIO_IO) & 0x000F3FFF), GPIO_IO); /* initial pin state; MDCLK = 0 */ + + return 1; +} + +#else +# define c5471_phyinit() +# warning "Assuming no PHY" +#endif + +/**************************************************************************** + * Name: c5471_inctxcpu + * + * Description + * + ****************************************************************************/ + +static inline void c5471_inctxcpu(struct c5471_driver_s *c5471) +{ + if (EIM_TXDESC_WRAP_NEXT & getreg32(c5471->c_txcpudesc)) + { + /* Loop back around to base of descriptor queue */ + + c5471->c_txcpudesc = getreg32(EIM_CPU_TXBA) + EIM_RAM_START; + } + else + { + c5471->c_txcpudesc += 2*sizeof(uint32_t); + } + + nvdbg("TX CPU desc: %08x\n", c5471->c_txcpudesc); +} + +/**************************************************************************** + * Name: c5471_incrxcpu + * + * Description + * + ****************************************************************************/ + +static inline void c5471_incrxcpu(struct c5471_driver_s *c5471) +{ + if (EIM_RXDESC_WRAP_NEXT & getreg32(c5471->c_rxcpudesc)) + { + /* Loop back around to base of descriptor queue */ + + c5471->c_rxcpudesc = getreg32(EIM_CPU_RXBA) + EIM_RAM_START; + } + else + { + c5471->c_rxcpudesc += 2*sizeof(uint32_t); + } + + nvdbg("RX CPU desc: %08x\n", c5471->c_rxcpudesc); +} + +/**************************************************************************** + * Function: c5471_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * c5471 - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int c5471_transmit(struct c5471_driver_s *c5471) +{ + struct net_driver_s *dev = &c5471->c_dev; + volatile uint16_t *packetmem; + uint16_t framelen; + bool bfirstframe; + int nbytes; + int nshorts; + unsigned int i; + unsigned int j; + + nbytes = (dev->d_len + 1) & ~1; + j = 0; + bfirstframe = true; + c5471->c_lastdescstart = c5471->c_rxcpudesc; + + nvdbg("Packet size: %d RX CPU desc: %08x\n", nbytes, c5471->c_rxcpudesc); + c5471_dumpbuffer("Transmit packet", dev->d_buf, dev->d_len); + + while (nbytes) + { + /* Verify that the hardware is ready to send another packet */ + /* Words #0 and #1 of descriptor */ + + while (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) + { + /* Loop until the SWITCH lets go of the descriptor giving us access + * rights to submit our new ether frame to it. + */ + } + + if (bfirstframe) + { + putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_FIF), c5471->c_rxcpudesc); + } + else + { + putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_FIF), c5471->c_rxcpudesc); + } + + putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_PADCRC), c5471->c_rxcpudesc); + + if (bfirstframe) + { + putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_PADCRC), c5471->c_rxcpudesc); + } + + if (nbytes >= EIM_PACKET_BYTES) + { + framelen = EIM_PACKET_BYTES; + } + else + { + framelen = nbytes; + } + + /* Submit ether frame bytes to the C5472 Ether Module packet memory space. */ + /* Get the number of 16-bit values to transfer by dividing by 2 with round up. */ + + nshorts = (framelen + 1) >> 1; + + /* Words #2 and #3 of descriptor */ + + packetmem = (uint16_t *)getreg32(c5471->c_rxcpudesc + sizeof(uint32_t)); + for (i = 0; i < nshorts; i++, j++) + { + /* 16-bits at a time. */ + + packetmem[i] = htons(((uint16_t *)dev->d_buf)[j]); + } + + putreg32(((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_BYTEMASK) | framelen), c5471->c_rxcpudesc); + nbytes -= framelen; + nvdbg("Wrote framelen: %d nbytes: %d nshorts: %d\n", framelen, nbytes, nshorts); + + if (0 == nbytes) + { + putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_LIF), c5471->c_rxcpudesc); + } + else + { + putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_LIF), c5471->c_rxcpudesc); + } + + /* We're done with that descriptor; give access rights back to h/w */ + + putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_OWN_HOST), c5471->c_rxcpudesc); + + /* Next, tell Ether Module that those submitted bytes are ready for the wire */ + + putreg32(0x00000001, EIM_CPU_RXREADY); + c5471->c_lastdescend = c5471->c_rxcpudesc; + + /* Advance to the next free descriptor */ + + c5471_incrxcpu(c5471); + bfirstframe = false; + } + + /* Packet transferred .. Update statistics */ + +#ifdef CONFIG_C5471_NET_STATS + c5471->c_txpackets++; +#endif + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(c5471->c_txtimeout, C5471_TXTIMEOUT, c5471_txtimeout, 1, (uint32_t)c5471); + return OK; +} + +/**************************************************************************** + * Function: c5471_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int c5471_txpoll(struct net_driver_s *dev) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (c5471->c_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(c5471->c_dev.d_flags)) +#endif + { + arp_out(&c5471->c_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&c5471->c_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + c5471_transmit(c5471); + + /* Check if the ESM has let go of the RX descriptor giving us access + * rights to submit another Ethernet frame. + */ + + if ((EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) != 0) + { + /* No, then return non-zero to terminate the poll */ + + return 1; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: c5471_rxstatus + * + * Description: + * An interrupt was received indicating that the last RX packet(s) is done + * + * Parameters: + * c5471 - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_C5471_NET_STATS +static void c5471_rxstatus(struct c5471_driver_s *c5471) +{ + uint32_t desc = c5471->c_txcpudesc; + uint32_t rxstatus; + + /* Walk that last packet we just received to collect xmit status bits. */ + + rxstatus = 0; + for (; ; ) + { + if (EIM_TXDESC_OWN_HOST & getreg32(desc)) + { + /* The incoming packet queue is empty. */ + + break; + } + + rxstatus |= (getreg32(desc) & EIM_TXDESC_STATUSMASK); + + if ((getreg32(desc) & EIM_TXDESC_LIF) != 0) + { + break; + } + + /* This packet is made up of several descriptors, find next one in chain. */ + + if (EIM_TXDESC_WRAP_NEXT & getreg32(desc)) + { + /* Loop back around to base of descriptor queue. */ + + desc = getreg32(EIM_CPU_TXBA) + EIM_RAM_START; + } + else + { + desc += 2 * sizeof(uint32_t); + } + } + + if (rxstatus != 0) + { + if ((rxstatus & EIM_TXDESC_RETRYERROR) != 0) + { + c5471->c_rxretries++; + nvdbg("c_rxretries: %d\n", c5471->c_rxretries); + } + + if ((rxstatus & EIM_TXDESC_HEARTBEAT) != 0) + { + c5471->c_rxheartbeat++; + nvdbg("c_rxheartbeat: %d\n", c5471->c_rxheartbeat); + } + + if ((rxstatus & EIM_TXDESC_LCOLLISON) != 0) + { + c5471->c_rxlcollision++; + nvdbg("c_rxlcollision: %d\n", c5471->c_rxlcollision); + } + + if ((rxstatus & EIM_TXDESC_COLLISION) != 0) + { + c5471->c_rxcollision++; + nvdbg("c_rxcollision: %d\n", c5471->c_rxcollision); + } + + if ((rxstatus & EIM_TXDESC_CRCERROR) != 0) + { + c5471->c_rxcrc++; + nvdbg("c_rxcrc: %d\n", c5471->c_rxcrc); + } + + if ((rxstatus & EIM_TXDESC_UNDERRUN) != 0) + { + c5471->c_rxunderrun++; + nvdbg("c_rxunderrun: %d\n", c5471->c_rxunderrun); + } + + if ((rxstatus & EIM_TXDESC_LOC) != 0) + { + c5471->c_rxloc++; + nvdbg("c_rxloc: %d\n", c5471->c_rxloc); + } + } +} +#endif + +/**************************************************************************** + * Function: c5471_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * c5471 - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void c5471_receive(struct c5471_driver_s *c5471) +{ + struct net_driver_s *dev = &c5471->c_dev; + uint16_t *packetmem; + bool bmore = true; + int packetlen = 0; + int framelen; + int nshorts; + int i; + int j = 0; + + /* Walk the newly received packet contained within the EIM and transfer + * its contents to the uIP buffer. This frees up the memory contained within + * the EIM for additional packets that might be received later from the network. + */ + + nvdbg("Reading TX CPU desc: %08x\n", c5471->c_txcpudesc); + while (bmore) + { + /* Words #0 and #1 of descriptor */ + + if (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_txcpudesc)) + { + /* No further packets to receive. */ + + break; + } + + /* Get the size of the frame from words #0 and #1 of the descriptor + * and update the accumulated packet size + */ + + framelen = (getreg32(c5471->c_txcpudesc) & EIM_TXDESC_BYTEMASK); + packetlen += framelen; + + /* Check if the received packet will fit within the uIP packet buffer */ + + if (packetlen < (CONFIG_NET_ETH_MTU + 4)) + { + /* Get the packet memory from words #2 and #3 of descriptor */ + + packetmem = (uint16_t *)getreg32(c5471->c_txcpudesc + sizeof(uint32_t)); + + /* Divide by 2 with round up to get the number of 16-bit words. */ + + nshorts = (framelen + 1) >> 1; + nvdbg("Reading framelen: %d packetlen: %d nshorts: %d packetmen: %p\n", + framelen, packetlen, nshorts, packetmem); + + for (i = 0 ; i < nshorts; i++, j++) + { + /* Copy the data data from the hardware to c5471->c_dev.d_buf 16-bits at + * a time. + */ + + ((uint16_t *)dev->d_buf)[j] = htons(packetmem[i]); + } + } + else + { + nvdbg("Discarding framelen: %d packetlen\n", framelen, packetlen); + } + + if (getreg32(c5471->c_txcpudesc) & EIM_TXDESC_LIF) + { + bmore = false; + } + + /* Next, Clear all bits of words0/1 of the emptied descriptor except preserve + * the settings of a select few. Can leave descriptor words 2/3 alone. + */ + + putreg32((getreg32(c5471->c_txcpudesc) & (EIM_TXDESC_WRAP_NEXT | EIM_TXDESC_INTRE)), + c5471->c_txcpudesc); + + /* Next, Give ownership of now emptied descriptor back to the Ether Module's SWITCH */ + + putreg32((getreg32(c5471->c_txcpudesc) | EIM_TXDESC_OWN_HOST), c5471->c_txcpudesc); + + /* Advance to the next data buffer */ + + c5471_inctxcpu(c5471); + } + + /* Adjust the packet length to remove the CRC bytes that uIP doesn't care about. */ + + packetlen -= 4; + +#ifdef CONFIG_C5471_NET_STATS + /* Increment the count of received packets */ + + c5471->c_rxpackets++; +#endif + + /* If we successfully transferred the data into the uIP buffer, then pass it on + * to uIP for processing. + */ + + if (packetlen > 0 && packetlen < CONFIG_NET_ETH_MTU) + { + /* Set amount of data in c5471->c_dev.d_len. */ + + dev->d_len = packetlen; + nvdbg("Received packet, packetlen: %d type: %02x\n", packetlen, ntohs(BUF->type)); + c5471_dumpbuffer("Received packet", dev->d_buf, dev->d_len); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(dev); + ipv4_input(dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + * Send that data now if ESM has let go of the RX descriptor giving us + * access rights to submit another Ethernet frame. + */ + + if (dev->d_len > 0 && + (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) == 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(dev->d_flags)) +#endif + { + arp_out(dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(dev); + } +#endif + + /* And send the packet */ + + c5471_transmit(c5471); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + * Send that data now if ESM has let go of the RX descriptor giving us + * access rights to submit another Ethernet frame. + */ + + if (dev->d_len > 0 && + (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) == 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(dev->d_flags)) + { + arp_out(dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(dev); + } +#endif + + /* And send the packet */ + + c5471_transmit(c5471); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == HTONS(ETHTYPE_ARP)) + { + arp_arpin(dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + * Send that data now if ESM has let go of the RX descriptor giving us + * access rights to submit another Ethernet frame. + */ + + if (dev->d_len > 0 && + (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) == 0) + { + c5471_transmit(c5471); + } + } +#endif + } +#ifdef CONFIG_C5471_NET_STATS + else + { + /* Increment the count of dropped packets */ + + ndbg("Too big! packetlen: %d\n", packetlen); + c5471->c_rxdropped++; + } +#endif +} + +/**************************************************************************** + * Function: c5471_txstatus + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * c5471 - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_C5471_NET_STATS +static void c5471_txstatus(struct c5471_driver_s *c5471) +{ + uint32_t desc = c5471->c_lastdescstart; + uint32_t txstatus; + + /* Walk that last packet we just sent to collect xmit status bits. */ + + txstatus = 0; + if (c5471->c_lastdescstart && c5471->c_lastdescend) + { + for (; ; ) + { + txstatus |= (getreg32(desc) & EIM_RXDESC_STATUSMASK); + if (desc == c5471->c_lastdescend) + { + break; + } + + /* This packet is made up of several descriptors, find next one in chain. */ + + if (EIM_RXDESC_WRAP_NEXT & getreg32(c5471->c_rxcpudesc)) + { + /* Loop back around to base of descriptor queue. */ + + desc = getreg32(EIM_CPU_RXBA) + EIM_RAM_START; + } + else + { + desc += 2 * sizeof(uint32_t); + } + } + } + + if (txstatus) + { + if ((txstatus & EIM_RXDESC_MISS) != 0) + { + c5471->c_txmiss++; + nvdbg("c_txmiss: %d\n", c5471->c_txmiss); + } + + if ((txstatus & EIM_RXDESC_VLAN) != 0) + { + c5471->c_txvlan++; + nvdbg("c_txvlan: %d\n", c5471->c_txvlan); + } + + if ((txstatus & EIM_RXDESC_LFRAME) != 0) + { + c5471->c_txlframe++; + nvdbg("c_txlframe: %d\n", c5471->c_txlframe); + } + + if ((txstatus & EIM_RXDESC_SFRAME) != 0) + { + c5471->c_txsframe++; + nvdbg("c_txsframe: %d\n", c5471->c_txsframe); + } + + if ((txstatus & EIM_RXDESC_CRCERROR) != 0) + { + c5471->c_txcrc++; + nvdbg("c_txcrc: %d\n", c5471->c_txcrc); + } + + if ((txstatus & EIM_RXDESC_OVERRUN) != 0) + { + c5471->c_txoverrun++; + nvdbg("c_txoverrun: %d\n", c5471->c_txoverrun); + } + + if ((txstatus & EIM_RXDESC_OVERRUN) != 0) + { + c5471->c_txalign++; + nvdbg("c_txalign: %d\n", c5471->c_txalign); + } + } +} +#endif + +/**************************************************************************** + * Function: c5471_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * c5471 - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void c5471_txdone(struct c5471_driver_s *c5471) +{ + /* If no further xmits are pending, then cancel the TX timeout */ + + wd_cancel(c5471->c_txtimeout); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&c5471->c_dev, c5471_txpoll); +} + +/**************************************************************************** + * Function: c5471_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int c5471_interrupt(int irq, FAR void *context) +{ +#if CONFIG_C5471_NET_NINTERFACES == 1 + register struct c5471_driver_s *c5471 = &g_c5471[0]; +#else +# error "Additional logic needed to support multiple interfaces" +#endif + + /* Get and clear interrupt status bits */ + + c5471->c_eimstatus = getreg32(EIM_STATUS); + + /* Handle interrupts according to status bit settings */ + /* Check if we received an incoming packet, if so, call c5471_receive() */ + + if ((EIM_STATUS_CPU_TX & c5471->c_eimstatus) != 0) + { + /* An incoming packet has been received by the EIM from the network and + * the interrupt associated with EIM's CPU TX queue has been asserted. It + * is the EIM's CPU TX queue that we need to read from to get those + * packets. We use this terminology to stay consistent with the Orion + * documentation. + */ + +#ifdef CONFIG_C5471_NET_STATS + /* Check for RX errors */ + + c5471_rxstatus(c5471); +#endif + + /* Process the received packet */ + + c5471_receive(c5471); + } + + /* Check is a packet transmission just completed. If so, call c5471_txdone */ + + if ((EIM_STATUS_CPU_RX & c5471->c_eimstatus) != 0) + { + /* An outgoing packet has been processed by the EIM and the interrupt + * associated with EIM's CPU RX que has been asserted. It is the EIM's + * CPU RX queue that we put packets on to send them *out*. TWe use this + * terminology to stay consistent with the Orion documentation. + */ + +#ifdef CONFIG_C5471_NET_STATS + /* Check for TX errors */ + + c5471_txstatus(c5471); +#endif + + /* Handle the transmission done event */ + + c5471_txdone(c5471); + } + + /* Enable Ethernet interrupts (perhaps excluding the TX done interrupt if + * there are no pending transmissions. + */ + + return OK; +} + +/**************************************************************************** + * Function: c5471_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void c5471_txtimeout(int argc, uint32_t arg, ...) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)arg; + + /* Increment statistics */ + +#ifdef CONFIG_C5471_NET_STATS + c5471->c_txtimeouts++; + nvdbg("c_txtimeouts: %d\n", c5471->c_txtimeouts); +#endif + + /* Then try to restart the hardware */ + + c5471_ifdown(&c5471->c_dev); + c5471_ifup(&c5471->c_dev); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&c5471->c_dev, c5471_txpoll); +} + +/**************************************************************************** + * Function: c5471_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void c5471_polltimer(int argc, uint32_t arg, ...) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)arg; + + /* Check if the ESM has let go of the RX descriptor giving us access rights + * to submit another Ethernet frame. + */ + + if ((EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) == 0) + { + /* If so, update TCP timing states and poll uIP for new XMIT data */ + + (void)devif_timer(&c5471->c_dev, c5471_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(c5471->c_txpoll, C5471_WDDELAY, c5471_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: c5471_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * The user has assigned a MAC to the driver + * + ****************************************************************************/ + +static int c5471_ifup(struct net_driver_s *dev) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private; + volatile uint32_t clearbits; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Initilize Ethernet interface */ + + c5471_reset(c5471); + + /* Assign the MAC to the device */ + + c5471_macassign(c5471); + + /* Clear pending interrupts by reading the EIM status register */ + + clearbits = getreg32(EIM_STATUS); + UNUSED(clearbits); + + /* Enable interrupts going from EIM Module to Interrupt Module. */ + + putreg32(((getreg32(EIM_INTEN) | EIM_INTEN_CPU_TX | EIM_INTEN_CPU_RX)), + EIM_INTEN); + + /* Next, go on-line. According to the C547X documentation the enables have to + * occur in this order to insure proper operation; ESM first then the ENET. + */ + + putreg32((getreg32(EIM_CTRL) | EIM_CTRL_ESM_EN), EIM_CTRL); /* enable ESM */ + putreg32((getreg32(ENET0_MODE) | ENET_MODE_ENABLE), ENET0_MODE); /* enable ENET */ + up_mdelay(100); + + /* Set and activate a timer process */ + + (void)wd_start(c5471->c_txpoll, C5471_WDDELAY, c5471_polltimer, 1, (uint32_t)c5471); + + /* Enable the Ethernet interrupt */ + + c5471->c_bifup = true; + up_enable_irq(C5471_IRQ_ETHER); + return OK; +} + +/**************************************************************************** + * Function: c5471_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int c5471_ifdown(struct net_driver_s *dev) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private; + irqstate_t flags; + + ndbg("Stopping\n"); + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(C5471_IRQ_ETHER); + + /* Disable interrupts going from EIM Module to Interrupt Module. */ + + putreg32((getreg32(EIM_INTEN) & ~(EIM_INTEN_CPU_TX | EIM_INTEN_CPU_RX)), + EIM_INTEN); + + /* Disable ENET */ + + putreg32((getreg32(ENET0_MODE) & ~ENET_MODE_ENABLE), ENET0_MODE); /* disable ENET */ + + /* Disable ESM */ + + putreg32((getreg32(EIM_CTRL) & ~EIM_CTRL_ESM_EN), EIM_CTRL); /* disable ESM */ + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(c5471->c_txpoll); + wd_cancel(c5471->c_txtimeout); + + /* Reset the device */ + + c5471->c_bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: c5471_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int c5471_txavail(struct net_driver_s *dev) +{ + struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private; + irqstate_t flags; + + ndbg("Polling\n"); + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (c5471->c_bifup) + { + /* Check if the ESM has let go of the RX descriptor giving us access + * rights to submit another Ethernet frame. + */ + + if ((EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) == 0) + { + /* If so, then poll uIP for new XMIT data */ + + (void)devif_poll(&c5471->c_dev, c5471_txpoll); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: c5471_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int c5471_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Multicast MAC support not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Function: c5471_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int c5471_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Multicast MAC support not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Name: c5471_eimreset + * + * Description + * The C547x docs states that a module should generally be reset according + * to the following algorithm: + * + * 1. Put the module in reset. + * 2. Switch on the module clock. + * 3. Wait for eight clock cycles. + * 4. Release the reset. + * + ****************************************************************************/ + +static void c5471_eimreset (struct c5471_driver_s *c5471) +{ + /* Stop the EIM module clock */ + + putreg32((getreg32(CLKM) | CLKM_EIM_CLK_STOP), CLKM); + + /* Put EIM module in reset */ + + putreg32((getreg32(CLKM_RESET) & ~CLKM_RESET_EIM), CLKM_RESET); + + /* Start the EIM module clock */ + + putreg32((getreg32(CLKM) & ~CLKM_EIM_CLK_STOP), CLKM); + + /* Assert nRESET to reset the board's PHY0/1 chips */ + + putreg32((CLKM_CTL_RST_EXT_RESET | CLKM_CTL_RST_LEAD_RESET), + CLKM_CTL_RST); + up_mdelay(2); + + /* Release the peripheral nRESET signal */ + + putreg32(CLKM_CTL_RST_LEAD_RESET, CLKM_CTL_RST); + + /* Release EIM module reset */ + + putreg32((getreg32(CLKM_RESET) | CLKM_RESET_EIM), CLKM_RESET); + + /* All EIM register should now be in there power-up default states */ + + c5471->c_lastdescstart = 0; + c5471->c_lastdescend = 0; +} + +/**************************************************************************** + * Name: c5471_eimconfig + * + * Description + * Assumes that all registers are currently in the power-up reset state. + * This routine then modifies that state to provide our specific ethernet + * configuration. + * + ****************************************************************************/ + +static void c5471_eimconfig(struct c5471_driver_s *c5471) +{ + volatile uint32_t pbuf; + volatile uint32_t desc; + volatile uint32_t val; + int i; + + desc = EIM_RAM_START; + pbuf = EIM_RAM_START + 0x6C0; + + /* TX ENET 0 */ + + ndbg("TX ENET0 desc: %08x pbuf: %08x\n", desc, pbuf); + putreg32((desc & 0x0000ffff), ENET0_TDBA); /* 16-bit offset address */ + for (i = NUM_DESC_TX-1; i >= 0; i--) + { + if (i == 0) + val = EIM_TXDESC_WRAP_NEXT; + else + val = EIM_TXDESC_WRAP_FIRST; + + val |= EIM_TXDESC_OWN_HOST | EIM_TXDESC_INTRE | EIM_TXDESC_PADCRC | + EIM_PACKET_BYTES; + + putreg32(val, desc); + desc += sizeof(uint32_t); + + putreg32(pbuf, desc); + desc += sizeof(uint32_t); + + putreg32(0, pbuf); + pbuf += EIM_PACKET_BYTES; + + putreg32(0, pbuf); + pbuf += sizeof(uint32_t); /* Ether Module's "Buffer Usage Word" */ + } + + /* RX ENET 0 */ + + ndbg("RX ENET0 desc: %08x pbuf: %08x\n", desc, pbuf); + putreg32((desc & 0x0000ffff), ENET0_RDBA); /* 16-bit offset address */ + for (i = NUM_DESC_RX-1; i >= 0; i--) + { + if (i == 0) + val = EIM_RXDESC_WRAP_NEXT; + else + val = EIM_RXDESC_WRAP_FIRST; + + val |= EIM_RXDESC_OWN_ENET | EIM_RXDESC_INTRE | EIM_RXDESC_PADCRC | + EIM_PACKET_BYTES; + + putreg32(val, desc); + desc += sizeof(uint32_t); + + putreg32(pbuf, desc); + desc += sizeof(uint32_t); + + putreg32(0, pbuf); + pbuf += EIM_PACKET_BYTES; + + putreg32(0, pbuf); + pbuf += sizeof(uint32_t); /* Ether Module's "Buffer Usage Word" */ + } + + /* TX CPU */ + + ndbg("TX CPU desc: %08x pbuf: %08x\n", desc, pbuf); + c5471->c_txcpudesc = desc; + putreg32((desc & 0x0000ffff), EIM_CPU_TXBA); /* 16-bit offset address */ + for (i = NUM_DESC_TX-1; i >= 0; i--) + { + /* Set words 1+2 of the TXDESC */ + + if (i == 0) + val = EIM_TXDESC_WRAP_NEXT; + else + val = EIM_TXDESC_WRAP_FIRST; + + val |= EIM_TXDESC_OWN_HOST | EIM_TXDESC_INTRE | EIM_TXDESC_PADCRC | + EIM_PACKET_BYTES; + + putreg32(val, desc); + desc += sizeof(uint32_t); + + putreg32(pbuf, desc); + desc += sizeof(uint32_t); + + putreg32(0, pbuf); + pbuf += EIM_PACKET_BYTES; + + putreg32(0, pbuf); + pbuf += sizeof(uint32_t); /* Ether Module's "Buffer Usage Word" */ + } + + /* RX CPU */ + + ndbg("RX CPU desc: %08x pbuf: %08x\n", desc, pbuf); + c5471->c_rxcpudesc = desc; + putreg32((desc & 0x0000ffff), EIM_CPU_RXBA); /* 16-bit offset address */ + for (i = NUM_DESC_RX-1; i >= 0; i--) + { + /* Set words 1+2 of the RXDESC */ + + if (i == 0) + val = EIM_RXDESC_WRAP_NEXT; + else + val = EIM_RXDESC_WRAP_FIRST; + + val |= EIM_RXDESC_OWN_ENET | EIM_RXDESC_INTRE | EIM_RXDESC_PADCRC | + EIM_PACKET_BYTES; + + putreg32(val, desc); + desc += sizeof(uint32_t); + + putreg32(pbuf, desc); + desc += sizeof(uint32_t); + + putreg32(0, pbuf); + pbuf += EIM_PACKET_BYTES; + + putreg32(0, pbuf); + pbuf += sizeof(uint32_t); /* Ether Module's "Buffer Usage Word" */ + } + + ndbg("END desc: %08x pbuf: %08x\n", desc, pbuf); + + /* Save the descriptor packet size */ + + putreg32(EIM_PACKET_BYTES, EIM_BUFSIZE); + + /* Set the filter mode */ + +#if 0 + putreg32(EIM_FILTER_UNICAST, EIM_CPU_FILTER); +#else +// putreg32(EIM_FILTER_LOGICAL | EIM_FILTER_UNICAST | EIM_FILTER_MULTICAST | +// EIM_FILTER_BROADCAST, EIM_CPU_FILTER); + putreg32(EIM_FILTER_UNICAST | EIM_FILTER_MULTICAST | EIM_FILTER_BROADCAST, + EIM_CPU_FILTER); +#endif + + /* Disable all Ethernet interrupts */ + + putreg32(0x00000000, EIM_INTEN); + + /* Setup the EIM control register */ + +#if 1 + putreg32(EIM_CTRL_ENET0_EN | EIM_CTRL_RXENET0_EN | EIM_CTRL_TXENET0_EN | + EIM_CTRL_RXCPU_EN | EIM_CTRL_TXCPU_EN, EIM_CTRL); +#else + putreg32(EIM_CTRL_ENET0_EN | EIM_CTRL_ENET0_FLW | EIM_CTRL_RXENET0_EN | + EIM_CTRL_TXENET0_EN | EIM_CTRL_RXCPU_EN | EIM_CTRL_TXCPU_EN, + EIM_CTRL); +#endif + +#if 1 + putreg32(0x00000000, EIM_MFVHI); +#else + putreg32(0x0000ff00, EIM_MFVHI); +#endif + + putreg32(0x00000000, EIM_MFVLO); + putreg32(0x00000000, EIM_MFMHI); + putreg32(0x00000000, EIM_MFMLO); + putreg32(0x00000018, EIM_RXTH); + putreg32(0x00000000, EIM_CPU_RXREADY); + + /* Setup the ENET0 mode register */ + +#if 1 + putreg32(ENET_MODE_RJCT_SFE | ENET_MODE_MWIDTH | ENET_MODE_FULLDUPLEX, + ENET0_MODE); +#else + putreg32(ENET_MODE_RJCT_SFE | ENET_MODE_MWIDTH | ENET_MODE_HALFDUPLEX, + ENET0_MODE); +#endif + + putreg32(0x00000000, ENET0_BOFFSEED); + putreg32(0x00000000, ENET0_FLWPAUSE); + putreg32(0x00000000, ENET0_FLWCONTROL); + putreg32(0x00000000, ENET0_VTYPE); + +#if 0 + putreg32(ENET_ADR_BROADCAST | ENET_ADR_PROMISCUOUS, ENET0_ADRMODE_EN); +#else + /* The CPU port is not PROMISCUOUS, it wants a no-promiscuous address + * match yet the SWITCH receives packets from the PROMISCUOUS ENET0 + * which routes all packets for filter matching at the CPU port which + * then allows the s/w to see the new incoming packetes that passed + * the filter. Here we are setting the main SWITCH closest the ether + * wire. + */ + + putreg32(ENET_ADR_PROMISCUOUS, ENET0_ADRMODE_EN); +#endif + + putreg32(0x00000000, ENET0_DRP); + up_mdelay(500); +} + +/**************************************************************************** + * Name: c5471_reset + * + * Description + * + ****************************************************************************/ + +static void c5471_reset(struct c5471_driver_s *c5471) +{ +#if defined(CONFIG_C5471_PHY_LU3X31T_T64) + ndbg("EIM reset\n"); + c5471_eimreset(c5471); +#endif + ndbg("PHY init\n"); + c5471_phyinit(); + + ndbg("EIM config\n"); + c5471_eimconfig(c5471); +} + +/**************************************************************************** + * Name: c5471_macassign + * + * Description + * Set the mac address of our CPU ether port so that when the SWITCH + * receives packets from the PROMISCUOUS ENET0 it will switch them to the + * CPU port and cause a packet arrival event on the Switch's CPU TX queue + * when an address match occurs. The CPU port is not PROMISCUOUS and wants + * to see only packets specifically addressed to this device. + * + ****************************************************************************/ + +static void c5471_macassign(struct c5471_driver_s *c5471) +{ + struct net_driver_s *dev = &c5471->c_dev; + uint8_t *mptr = dev->d_mac.ether_addr_octet; + register uint32_t tmp; + + ndbg("MAC: %0x:%0x:%0x:%0x:%0x:%0x\n", + mptr[0], mptr[1], mptr[2], mptr[3], mptr[4], mptr[5]); + + /* Set CPU port MAC address. S/W will only see incoming packets that match + * this destination address. + */ + + tmp = (((uint32_t)mptr[0]) << 8) | ((uint32_t)mptr[1]); + putreg32(tmp, EIM_CPU_DAHI); + + tmp = (((uint32_t)mptr[2]) << 24) | (((uint32_t)mptr[3]) << 16) | + (((uint32_t)mptr[4]) << 8) | ((uint32_t)mptr[5]); + putreg32(tmp, EIM_CPU_DALO); + +#if 0 + /* Set the ENET MAC address */ + + putreg32(getreg32(EIM_CPU_DAHI), ENET0_PARHI); + putreg32(getreg32(EIM_CPU_DALO), ENET0_PARLO); + putreg32(getreg32(EIM_CPU_DAHI), ENET0_LARHI); + putreg32(getreg32(EIM_CPU_DALO), ENET0_LARLO); + +#else + /* ENET MAC assignment not needed for its PROMISCUOUS mode */ + + putreg32(0x00000000, ENET0_PARHI); + putreg32(0x00000000, ENET0_PARLO); + putreg32(0x00000000, ENET0_LARHI); + putreg32(0x00000000, ENET0_LARLO); + +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: c5471_initialize + * + * Description: + * Initialize the Ethernet driver + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +/* Initialize the DM90x0 chip and driver */ + +void up_netinitialize(void) +{ + /* Attach the IRQ to the driver */ + + if (irq_attach(C5471_IRQ_ETHER, c5471_interrupt)) + { + /* We could not attach the ISR to the ISR */ + + nlldbg("irq_attach() failed\n"); + return; + } + + /* Initialize the driver structure */ + + memset(g_c5471, 0, CONFIG_C5471_NET_NINTERFACES*sizeof(struct c5471_driver_s)); + g_c5471[0].c_dev.d_ifup = c5471_ifup; /* I/F down callback */ + g_c5471[0].c_dev.d_ifdown = c5471_ifdown; /* I/F up (new IP address) callback */ + g_c5471[0].c_dev.d_txavail = c5471_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + g_c5471[0].c_dev.d_addmac = c5471_addmac; /* Add multicast MAC address */ + g_c5471[0].c_dev.d_rmmac = c5471_rmmac; /* Remove multicast MAC address */ +#endif + g_c5471[0].c_dev.d_private = (void *)g_c5471; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + g_c5471[0].c_txpoll = wd_create(); /* Create periodic poll timer */ + g_c5471[0].c_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&g_c5471[0].c_dev, NET_LL_ETHERNET); +} + +#endif /* CONFIG_NET */ diff --git a/arch/arm/src/c5471/c5471_irq.c b/arch/arm/src/c5471/c5471_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..8156ae5269e9663089bd7bf17c2559395f6e368b --- /dev/null +++ b/arch/arm/src/c5471/c5471_irq.c @@ -0,0 +1,244 @@ +/**************************************************************************** + * arch/arm/src/c5471/c5471_irq.c + * + * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ILR_EDGESENSITIVE 0x00000020 +#define ILR_PRIORITY 0x0000001E + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The value of _svectors is defined in ld.script. It could be hard-coded + * because we know that correct IRAM area is 0xffc00000. + */ + +extern int _svectors; /* Type does not matter */ + +/* The C5471 has FLASH at the low end of memory. The rrload bootloaer will + * catch all interrupts and re-vector them to vectors stored in IRAM. The + * following table is used to initialize those vectors. + */ + +static up_vector_t g_vectorinittab[] = +{ + (up_vector_t)NULL, + up_vectorundefinsn, + up_vectorswi, + up_vectorprefetch, + up_vectordata, + up_vectoraddrexcptn, + up_vectorirq, + up_vectorfiq +}; +#define NVECTORS ((sizeof(g_vectorinittab)) / sizeof(up_vector_t)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ackirq + * + * Description: + * Acknowlede the IRQ.Bit 0 of the Interrupt Control + * Register == New IRQ agreement (NEW_IRQ_AGR). Reset IRQ + * output. Clear source IRQ register. Enables a new IRQ + * generation. Reset by internal logic. + * + ****************************************************************************/ + +static inline void up_ackirq(unsigned int irq) +{ + uint32_t reg; + reg = getreg32(SRC_IRQ_REG); /* Insure appropriate IT_REG bit clears */ + putreg32(reg | 0x00000001, INT_CTRL_REG); /* write the NEW_IRQ_AGR bit. */ +} + +/**************************************************************************** + * Name: up_ackfiq + * + * Description: + * Acknowledge the FIQ. Bit 1 of the Interrupt Control + * Register == New FIQ agreement (NEW_FIQ_AGR). Reset FIQ + * output. Clear source FIQ register. Enables a new FIQ + * generation. Reset by internal logic. + * + ****************************************************************************/ + +static inline void up_ackfiq(unsigned int irq) +{ + uint32_t reg; + reg = getreg32(SRC_FIQ_REG); /* Insure appropriate IT_REG bit clears */ + putreg32(reg | 0x00000002, INT_CTRL_REG); /* write the NEW_FIQ_AGR bit. */ +} + +/**************************************************************************** + * Name: up_vectorinitialize + ****************************************************************************/ + +static inline void up_vectorinitialize(void) +{ + up_vector_t *src = g_vectorinittab; + up_vector_t *dest = (up_vector_t *)&_svectors; + int i; + + for (i = 0; i < NVECTORS; i++) + { + *dest++ = *src++; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Disable all interrupts. */ + + putreg32(0x0000ffff, MASK_IT_REG); + + /* Clear any pending interrupts */ + + up_ackirq(0); + up_ackfiq(0); + putreg32(0x00000000, IT_REG); + + /* Override hardware defaults */ + + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ2_REG); + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ4_REG); + putreg32(ILR_PRIORITY, ILR_IRQ6_REG); + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ15_REG); + + /* Initialize hardware interrupt vectors */ + + up_vectorinitialize(); + CURRENT_REGS = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + uint32_t reg = getreg32(MASK_IT_REG); + putreg32(reg | (1 << irq), MASK_IT_REG); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + uint32_t reg = getreg32(MASK_IT_REG); + putreg32(reg & ~(1 << irq), MASK_IT_REG); + } +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + uint32_t reg; + + /* Set the NEW_IRQ_AGR bit. This clears the IRQ src register + * enables generation of a new IRQ. + */ + + reg = getreg32(INT_CTRL_REG); + putreg32(reg | 0x00000001, INT_CTRL_REG); /* write the NEW_IRQ_AGR bit. */ +} diff --git a/arch/arm/src/c5471/c5471_lowputc.S b/arch/arm/src/c5471/c5471_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..29453f10813ce06a51e284b28f9a8a610210acbb --- /dev/null +++ b/arch/arm/src/c5471/c5471_lowputc.S @@ -0,0 +1,129 @@ +/************************************************************************** + * c5471/c5471_lowputc.S + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + +#ifdef CONFIG_SERIAL_IRDA_CONSOLE + ldr r2, =UART_IRDA_BASE /* r2=IRDA UART base */ +#else + ldr r2, =UART_MODEM_BASE /* r2=Modem UART base */ +#endif + + /* Poll bit 0 of the UART_SSR register. When the bit + * is clear, the TX FIFO is no longer full + */ + +1: ldr r1, [r2, #UART_SSR_OFFS] + tst r1, #UART_SSR_TXFULL + bne 1b + + /* Send the character by writing it into the UART_THR + * register. + */ + + str r0, [r2, #UART_THR_OFFS] + + /* Wait for the tranmsit holding regiser (THR) to be + * emptied. This is detemined when bit 6 of the LSR + * is set. + */ + +2: ldr r1, [r2, #UART_LSR_OFFS] + tst r1, #0x00000020 + beq 2b + + /* If the character that we just sent was a linefeed, + * then send a carriage return as well. + */ + + teq r0, #'\n' + moveq r0, #'\r' + beq 1b + + /* And return */ + + mov pc, lr + diff --git a/arch/arm/src/c5471/c5471_serial.c b/arch/arm/src/c5471/c5471_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..935bc46871de9100e78b1c337d3a7f9f2b754f9c --- /dev/null +++ b/arch/arm/src/c5471/c5471_serial.c @@ -0,0 +1,874 @@ +/**************************************************************************** + * c5471/c5471_serial.c + * + * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BASE_BAUD 115200 + +#if defined(CONFIG_UART_IRDA_HWFLOWCONTROL) || defined(CONFIG_UART_MODEM_HWFLOWCONTROL) +# define CONFIG_UART_HWFLOWCONTROL +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct uart_regs_s +{ + uint32_t ier; + uint32_t lcr; + uint32_t fcr; +#ifdef CONFIG_UART_HWFLOWCONTROL + uint32_t efr; + uint32_t tcr; +#endif +}; + +struct up_dev_s +{ + unsigned int uartbase; /* Base address of UART registers */ + unsigned int baud_base; /* Base baud for conversions */ + unsigned int baud; /* Configured baud */ + uint8_t xmit_fifo_size; /* Size of transmit FIFO */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ +#ifdef CONFIG_UART_HWFLOWCONTROL + bool flowcontrol; /* true: Hardware flow control + * is enabled. */ +#endif + bool stopbits2; /* true: Configure with 2 + * stop bits instead of 1 */ + struct uart_regs_s regs; /* Shadow copy of readonly regs */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_irdarxbuffer[CONFIG_UART_IRDA_RXBUFSIZE]; +static char g_irdatxbuffer[CONFIG_UART_IRDA_TXBUFSIZE]; +static char g_modemrxbuffer[CONFIG_UART_MODEM_RXBUFSIZE]; +static char g_modemtxbuffer[CONFIG_UART_MODEM_TXBUFSIZE]; + +/* This describes the state of the C5471 serial IRDA port. */ + +static struct up_dev_s g_irdapriv = +{ + .xmit_fifo_size = UART_IRDA_XMIT_FIFO_SIZE, + .baud_base = BASE_BAUD, + .uartbase = UART_IRDA_BASE, + .baud = CONFIG_UART_IRDA_BAUD, + .irq = C5471_IRQ_UART_IRDA, + .parity = CONFIG_UART_IRDA_PARITY, + .bits = CONFIG_UART_IRDA_BITS, +#ifdef CONFIG_UART_IRDA_HWFLOWCONTROL + .flowcontrol = true, +#endif + .stopbits2 = CONFIG_UART_IRDA_2STOP, +}; + +static uart_dev_t g_irdaport = +{ + .recv = + { + .size = CONFIG_UART_IRDA_RXBUFSIZE, + .buffer = g_irdarxbuffer, + }, + .xmit = + { + .size = CONFIG_UART_IRDA_TXBUFSIZE, + .buffer = g_irdatxbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_irdapriv, +}; + +/* This describes the state of the C5471 serial Modem port. */ + +static struct up_dev_s g_modempriv = +{ + .xmit_fifo_size = UART_XMIT_FIFO_SIZE, + .baud_base = BASE_BAUD, + .uartbase = UART_MODEM_BASE, + .baud = CONFIG_UART_MODEM_BAUD, + .irq = C5471_IRQ_UART, + .parity = CONFIG_UART_MODEM_PARITY, + .bits = CONFIG_UART_MODEM_BITS, +#ifdef CONFIG_UART_MODEM_HWFLOWCONTROL + .flowcontrol = true, +#endif + .stopbits2 = CONFIG_UART_MODEM_2STOP, +}; + +static uart_dev_t g_modemport = +{ + .recv = + { + .size = CONFIG_UART_MODEM_RXBUFSIZE, + .buffer = g_modemrxbuffer, + }, + .xmit = + { + .size = CONFIG_UART_MODEM_TXBUFSIZE, + .buffer = g_modemtxbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_modempriv, +}; + +/* Now, which one with be tty0/console and which tty1? */ + +#ifdef CONFIG_SERIAL_IRDA_CONSOLE +# define CONSOLE_DEV g_irdaport +# define TTYS0_DEV g_irdaport +# define TTYS1_DEV g_modemport +#else +# define CONSOLE_DEV g_modemport +# define TTYS0_DEV g_modemport +# define TTYS1_DEV g_irdaport +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_inserial + ****************************************************************************/ + +static inline uint32_t up_inserial(struct up_dev_s *priv, uint32_t offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier) +{ + if (ier) + { + *ier = priv->regs.ier & UART_IER_INTMASK; + } + priv->regs.ier &= ~UART_IER_INTMASK; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier) +{ + priv->regs.ier |= ier & (UART_IER_RECVINT | UART_IER_XMITINT); + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0) + { + break; + } + } +} +/**************************************************************************** + * Name: up_disablebreaks + ****************************************************************************/ + +static inline void up_disablebreaks(struct up_dev_s *priv) +{ + priv->regs.lcr &= ~UART_LCR_BOC; + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv) +{ + priv->regs.lcr |= UART_LCR_BOC; + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); +} + +/**************************************************************************** + * Name: up_setrate + ****************************************************************************/ + +static inline void up_setrate(struct up_dev_s *priv, unsigned int rate) +{ + uint32_t div_bit_rate; + + switch (rate) + { + case 115200: + div_bit_rate = BAUD_115200; + break; + case 57600: + div_bit_rate = BAUD_57600; + break; + case 38400: + div_bit_rate = BAUD_38400; + break; + case 19200: + div_bit_rate = BAUD_19200; + break; + case 4800: + div_bit_rate = BAUD_4800; + break; + case 2400: + div_bit_rate = BAUD_2400; + break; + case 1200: + div_bit_rate = BAUD_1200; + break; + case 9600: + default: + div_bit_rate = BAUD_9600; + break; + } + + up_serialout(priv, UART_DIV_BIT_RATE_OFFS, div_bit_rate); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = dev->priv; + unsigned int cval; + + if (priv->bits == 7) + { + cval = UART_LCR_7BITS; + } + else + { + cval = UART_LCR_8BITS; + } + + if (priv->stopbits2) + { + cval |= UART_LCR_2STOP; + } + + if (priv->parity == 1) /* Odd parity */ + { + cval |= (UART_LCR_PAREN | UART_LCR_PARODD); + } + else if (priv->parity == 2) /* Even parity */ + { + cval |= (UART_LCR_PAREN | UART_LCR_PAREVEN); + } + + /* Both the IrDA and MODEM UARTs support RESET and UART mode. */ + + up_serialout(priv, UART_MDR_OFFS, MDR_RESET_MODE); + up_mdelay(5); + up_serialout(priv, UART_MDR_OFFS, MDR_UART_MODE); + up_mdelay(5); + + priv->regs.ier = up_inserial(priv, UART_IER_OFFS); + priv->regs.lcr = up_inserial(priv, UART_LCR_OFFS); +#ifdef CONFIG_UART_HWFLOWCONTROL + if (priv->flowcontrol) + { + priv->regs.efr = up_inserial(priv, UART_EFR_OFFS); + priv->regs.tcr = up_inserial(priv, UART_TCR_OFFS); + } +#endif + + up_disableuartint(priv, NULL); + + up_serialout(priv, UART_EFR_OFFS, 0x0010); /* Enable fifo control */ + up_serialout(priv, UART_TFCR_OFFS, 0); /* Reset to 0 */ + up_serialout(priv, UART_RFCR_OFFS, UART_FCR_RX_CLR); /* Clear RX fifo */ + up_serialout(priv, UART_TFCR_OFFS, UART_FCR_TX_CLR); /* Clear TX fifo */ + up_serialout(priv, UART_TFCR_OFFS, UART_FCR_FIFO_EN); /* Enable RX/TX fifos */ + + up_disablebreaks(priv); + + /* Set the RX and TX trigger levels to the minimum */ + + priv->regs.fcr = (priv->regs.fcr & 0xffffffcf) | UART_FCR_FTL; + up_serialout(priv, UART_RFCR_OFFS, priv->regs.fcr); + + priv->regs.fcr = (priv->regs.fcr & 0xffffff3f) | UART_FCR_FTL; + up_serialout(priv, UART_RFCR_OFFS, priv->regs.fcr); + + up_setrate(priv, priv->baud); + + priv->regs.lcr &= 0xffffffe0; /* clear original field, and... */ + priv->regs.lcr |= (uint32_t)cval; /* Set new bits in that field. */ + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); + +#ifdef CONFIG_UART_HWFLOWCONTROL + if (priv->flowcontrol) + { + /* Set the FIFO level triggers for flow control + * Halt = 48 bytes, resume = 12 bytes + */ + + priv->regs.tcr = (priv->regs.tcr & 0xffffff00) | 0x0000003c; + up_serialout(priv, UART_TCR_OFFS, priv->regs.tcr); + + /* Enable RTS/CTS flow control */ + + priv->regs.efr |= 0x000000c0; + up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); + } + else + { + /* Disable RTS/CTS flow control */ + + priv->regs.efr &= 0xffffff3f; + up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); + } +#endif +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + volatile uint32_t cause; + + if (g_irdapriv.irq == irq) + { + dev = &g_irdaport; + } + else if (g_modempriv.irq == irq) + { + dev = &g_modemport; + } + else + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + cause = up_inserial(priv, UART_ISR_OFFS) & 0x0000003f; + + if ((cause & 0x0000000c) == 0x0000000c) + { + uint32_t ier_val = 0; + + /* Is this an interrupt from the IrDA UART? */ + + if (irq == C5471_IRQ_UART_IRDA) + { + /* Save the currently enabled IrDA UART interrupts + * so that we can restore the IrDA interrupt state + * below. + */ + + ier_val = up_inserial(priv, UART_IER_OFFS); + + /* Then disable all IrDA UART interrupts */ + + up_serialout(priv, UART_IER_OFFS, 0); + } + + /* Receive characters from the RX fifo */ + + uart_recvchars(dev); + + /* read UART_RHR to clear int condition + * toss = up_inserialchar(priv,&status); + */ + + /* Is this an interrupt from the IrDA UART? */ + + if (irq == C5471_IRQ_UART_IRDA) + { + /* Restore the IrDA UART interrupt enables */ + + up_serialout(priv, UART_IER_OFFS, ier_val); + } + } + else if ((cause & 0x0000000c) == 0x00000004) + { + uart_recvchars(dev); + } + + if ((cause & 0x00000002) != 0) + { + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_disablebreaks(priv); + leave_critical_section(flags); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rhr; + uint32_t lsr; + + /* Construct a 16bit status word that uses the high byte to + * hold the status bits associated with framing,parity,break + * and a low byte that holds error bits of LSR for + * conditions such as overflow, etc. + */ + + rhr = up_inserial(priv, UART_RHR_OFFS); + lsr = up_inserial(priv, UART_LSR_OFFS); + + *status = (unsigned int)((rhr & 0x0000ff00) | (lsr & 0x000000ff)); + + return rhr & 0x000000ff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->regs.ier |= UART_IER_RECVINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +#endif + } + else + { + priv->regs.ier &= ~UART_IER_RECVINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return up_inserial(priv, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_THR_OFFS, (uint8_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->regs.ier |= UART_IER_XMITINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +#endif + } + else + { + priv->regs.ier &= ~UART_IER_XMITINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); + } +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return (up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return (up_inserial(priv, UART_LSR_OFFS) & UART_LSR_TREF) != 0; +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + up_disableuartint(TTYS0_DEV.priv, NULL); + up_disableuartint(TTYS1_DEV.priv, NULL); + + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint16_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFS, (uint8_t)ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFS, '\r'); + } + + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + diff --git a/arch/arm/src/c5471/c5471_timerisr.c b/arch/arm/src/c5471/c5471_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..6f1ca3da87b808f69a558e28e4cb23b2cd9814e8 --- /dev/null +++ b/arch/arm/src/c5471/c5471_timerisr.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * c5471/c5471_timerisr.c + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* We want the general purpose timer running at the rate + * USEC_PER_TICK. The C5471 clock is 47.5MHz and we're using + * a timer PTV value of 3 (3 == divide incoming frequency by + * 16) which then yields a 16 bitCLKS_PER_INT value + * of 29687. + * + * 47500000 / 16 = 2968750 clocks/sec + * 2968750 / 100 = 29687 clocks/ 100Hz interrupt + * + */ + +#define CLKS_PER_INT 29687 +#define CLKS_PER_INT_SHIFT 5 +#define AR 0x00000010 +#define ST 0x00000008 +#define PTV 0x00000003 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for + * various portions of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t val; + + up_disable_irq(C5471_IRQ_SYSTIMER); + + /* Start the general purpose timer running in auto-reload mode + * so that an interrupt is generated at the rate USEC_PER_TICK. + */ + + val = ((CLKS_PER_INT-1) << CLKS_PER_INT_SHIFT) | AR | ST | PTV; + putreg32(val, C5471_TIMER2_CTRL); + + /* Attach and enable the timer interrupt */ + + irq_attach(C5471_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(C5471_IRQ_SYSTIMER); +} diff --git a/arch/arm/src/c5471/c5471_vectors.S b/arch/arm/src/c5471/c5471_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..443e12cad7ce7523439cdeb3b43d0b893dc34b8e --- /dev/null +++ b/arch/arm/src/c5471/c5471_vectors.S @@ -0,0 +1,486 @@ +/************************************************************************************ + * arch/arm/src/c5471/c5471_vectors.S + * + * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_arch.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + + .data +g_irqtmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_undeftmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ +g_aborttmp: + .word 0 /* Saved lr */ + .word 0 /* Saved spsr */ + +/************************************************************************************ + * Assembly Macros + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + + .text + +/************************************************************************************ + * Name: up_vectorirq + * + * Description: + * Interrupt excetpion. Entered in IRQ mode with spsr = SVC + * CPSR, lr = SVC PC + ************************************************************************************/ + + .globl up_vectorirq + .type up_vectorirq, %function +up_vectorirq: + /* On entry, we are in IRQ mode. We are free to use + * the IRQ mode r13 and r14. + * + */ + + ldr r13, .Lirqtmp + sub lr, lr, #4 + str lr, [r13] @ save lr_IRQ + mrs lr, spsr + str lr, [r13, #4] @ save spsr_IRQ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lirqtmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Now decode the interrupt */ + +#if 0 + ldr lr, =SRC_IRQ_BIN_REG /* Fetch encoded IRQ */ + ldr r0, [lr] + and r0, r0, #0x0f /* Valid range is 0..15 */ + + /* Problems here... cannot read SRC_IRQ_BIN_REQ (and/or + * SRC_IRQ_REQ because this will clear edge triggered + * interrupts. Plus, no way to validate spurious + * interrupt. + */ +#else + ldr r6, =SRC_IRQ_REG + ldr r6, [r6] /* Get source IRQ reg */ + mov r0, #0 /* Assume IRQ0_IRQ set */ +.Lmorebits: + tst r6, #1 /* Is IRQ set? */ + bne .Lhaveirq /* Yes... we have the IRQ */ + add r0, r0, #1 /* Setup next IRQ */ + mov r6, r6, lsr #1 /* Shift right one */ + cmp r0, #16 /* Only 16 valid bits */ + bcc .Lmorebits /* Keep until we have looked + * at all bits */ + b .Lnoirqset /* If we get here, there is + * no pending interrupt */ +.Lhaveirq: +#endif + /* Then call the IRQ handler with interrupt disabled. */ + + mov fp, #0 /* Init frame pointer */ + mov r1, sp /* Get r1=xcp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + ldr sp, .Lirqstackbase /* SP = interrupt stack base */ + str r1, [sp] /* Save the user stack pointer */ + bl up_doirq /* Call the handler */ + ldr sp, [sp] /* Restore the user stack pointer */ +#else + bl up_doirq /* Call the handler */ +#endif + + /* Restore the CPSR, SVC modr registers and return */ +.Lnoirqset: + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lirqtmp: + .word g_irqtmp +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lirqstackbase: + .word g_intstackbase +#endif + .align 5 + +/************************************************************************************ + * Function: up_vectorswi + * + * Description: + * SWI interrupt. We enter the SWI in SVC mode + ************************************************************************************/ + + .globl up_vectorswi + .type up_vectorswi, %function +up_vectorswi: + + /* The c547x rrload bootloader intemediates all + * interrupts. For the* case of the SWI, it mucked + * with the stack to create some temporary registers. + * We'll have to recover from this mucking here. + */ + + ldr r14, [sp,#-0x4] /* rrload workaround */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp), r14(lr), r15(pc) + * and CPSR in r1-r4 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 /* R14 is altered on return from SWI */ + mov r3, r14 /* Save r14 as the PC as well */ + mrs r4, spsr /* Get the saved CPSR */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the SWI handler with interrupt disabled. + * void up_syscall(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_syscall /* Call the handler */ + + /* Restore the CPSR, SVC modr registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr, r0 + ldmia sp, {r0-r15}^ /* Return */ + + .align 5 + +/************************************************************************************ + * Name: up_vectordata + * + * Description: + * Data abort Exception dispatcher. Give control to data + * abort handler. This function is entered in ABORT mode + * with spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl up_vectordata + .type up_vectordata, %function +up_vectordata: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Ldaborttmp /* Points to temp storage */ + sub lr, lr, #8 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Ldaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the data abort handler with interrupt disabled. + * void up_dataabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_dataabort /* Call the handler */ + + /* Restore the CPSR, SVC modr registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Ldaborttmp: + .word g_aborttmp + + .align 5 + +/************************************************************************************ + * Name: up_vectorprefetch + * + * Description: + * Prefetch abort exception. Entered in ABT mode with + * spsr = SVC CPSR, lr = SVC PC + ************************************************************************************/ + + .globl up_vectorprefetch + .type up_vectorprefetch, %function +up_vectorprefetch: + /* On entry we are free to use the ABORT mode registers + * r13 and r14 + */ + + ldr r13, .Lpaborttmp /* Points to temp storage */ + sub lr, lr, #4 /* Fixup return */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lpaborttmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the prefetch abort handler with interrupt disabled. + * void up_prefetchabort(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_prefetchabort /* Call the handler */ + + /* Restore the CPSR, SVC modr registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lpaborttmp: + .word g_aborttmp + + .align 5 + +/************************************************************************************ + * Name: up_vectorundefinsn + * + * Description: + * Undefined instruction entry exception. Entered in + * UND mode, spsr = SVC CPSR, lr = SVC PC + * + ************************************************************************************/ + + .globl up_vectorundefinsn + .type up_vectorundefinsn, %function +up_vectorundefinsn: + /* On entry we are free to use the UND mode registers + * r13 and r14 + */ + + ldr r13, .Lundeftmp /* Points to temp storage */ + str lr, [r13] /* Save in temp storage */ + mrs lr, spsr /* Get SPSR */ + str lr, [r13, #4] /* Save in temp storage */ + + /* Then switch back to SVC mode */ + + bic lr, lr, #MODE_MASK /* Keep F and T bits */ + orr lr, lr, #(SVC_MODE | PSR_I_BIT) + msr cpsr_c, lr /* Switch to SVC mode */ + + /* Create a context structure. First set aside a stack frame + * and store r0-r12 into the frame. + */ + + sub sp, sp, #XCPTCONTEXT_SIZE + stmia sp, {r0-r12} /* Save the SVC mode regs */ + + /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + + add r1, sp, #XCPTCONTEXT_SIZE + mov r2, r14 + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + ldr r0, .Lundeftmp /* Points to temp storage */ + ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */ + + add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */ + stmia r0, {r1-r4} + + /* Then call the undef insn handler with interrupt disabled. + * void up_undefinedinsn(struct xcptcontext *xcp) + */ + + mov fp, #0 /* Init frame pointer */ + mov r0, sp /* Get r0=xcp */ + bl up_undefinedinsn /* Call the handler */ + + /* Restore the CPSR, SVC modr registers and return */ + + ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ + msr spsr_cxsf, r0 + ldmia sp, {r0-r15}^ /* Return */ + +.Lundeftmp: + .word g_undeftmp + + .align 5 + +/************************************************************************************ + * Name: up_vectorfiq + * + * Description: + * Shouldn't happen + ************************************************************************************/ + + .globl up_vectorfiq + .type up_vectorfiq, %function +up_vectorfiq: + subs pc, lr, #4 + +/************************************************************************************ + * Name: up_vectoraddrexcption + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + + .globl up_vectoraddrexcptn + .type up_vectoraddrexcptn, %function +up_vectoraddrexcptn: + b up_vectoraddrexcptn + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + .global g_intstackalloc + .global g_intstackbase + .type g_intstackalloc, object + .type g_intstackbase, object +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) +g_intstackbase: + .skip 4 + .size g_intstackbase, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) +#endif + .end diff --git a/arch/arm/src/c5471/c5471_watchdog.c b/arch/arm/src/c5471/c5471_watchdog.c new file mode 100644 index 0000000000000000000000000000000000000000..2143246d6e7597754d6716eb259808b946a17af4 --- /dev/null +++ b/arch/arm/src/c5471/c5471_watchdog.c @@ -0,0 +1,398 @@ +/**************************************************************************** + * arch/arm/src/c5471/c5471_watchdog.c + * + * Copyright (C) 2007, 2009, 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef CONFIG_SOFTWARE_TEST +#undef CONFIG_SOFTWARE_REBOOT +#undef CONFIG_WATCHDOG_STRICT + +#define MAX_WDT_USEC 353200 +#define MAX_PRESCALER 256 +#define C5471_TIMER_STOP 0 + +#define C5471_TIMER_PRESCALER 0x07 /* Bits 0-2: Prescale value */ +#define C5471_TIMER_STARTBIT (1 << 3) /* Bit 3: Start timer bit */ +#define C5471_TIMER_AUTORELOAD (1 << 4) /* Bit 4: Auto-reload timer */ +#define C5471_TIMER_LOADTIM (0xffff << 5) /* Bits 20-5: Load timer value */ +#define C5471_TIMER_MODE (1 << 21) /* Bit 21: Timer mode */ +#define C5471_DISABLE_VALUE1 (0xf5 << 22) /* Bits 29-22: WD disable */ +#define C5471_DISABLE_VALUE2 (0xa0 << 22) + +#define CLOCK_KHZ 47500 +#define CLOCK_MHZx2 95 + +/* Macros to manage access to to watchdog timer macros */ + +#define c5471_wdt_cntl (*(volatile uint32_t*)C5471_TIMER0_CTRL) +#define c5471_wdt_count (*(volatile uint32_t*)C5471_TIMER0_CNT) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Local implementation of timer interface */ + +static inline unsigned int wdt_prescaletoptv(unsigned int prescale); + +static int wdt_setusec(uint32_t usec); +static int wdt_interrupt(int irq, void *context); + +static int wdt_open(struct file *filep); +static int wdt_close(struct file *filep); +static ssize_t wdt_read(struct file *filep, char *buffer, size_t buflen); +static ssize_t wdt_write(struct file *filep, const char *buffer, size_t buflen); +static int wdt_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool g_wdtopen; + +static const struct file_operations g_wdtops = +{ + .open = wdt_open, + .close = wdt_close, + .read = wdt_read, + .write = wdt_write, + .ioctl = wdt_ioctl, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wdt_prescaletoptv + ****************************************************************************/ + +static inline unsigned int wdt_prescaletoptv(unsigned int prescale) +{ + unsigned int ptv = 0; + + if (prescale > 255) + { + ptv = 7; + } + else + { + unsigned int value = prescale >> 1; + + /* 0: 0-2 + * 1: 3-4 + * 2: 5-8 + * 3: 9-16 + * 4: 17-32 + * 5: 33-64 + * 6: 65-128 + * 7: 129- + */ + + while (value > 1) + { + value >>= 1; + ptv++; + } + } + + dbg("prescale=%d -> ptv=%d\n", prescale, ptv); + return ptv; +} + +/**************************************************************************** + * Name: wdt_setusec + ****************************************************************************/ + +static int wdt_setusec(uint32_t usec) +{ + /* prescaler: clock / prescaler = #clock ticks per counter in ptv + * divisor: #counts until the interrupt comes. + */ + + uint32_t prescaler = MAX_PRESCALER; + uint32_t divisor = 1; + uint32_t mode; + + dbg("usec=%d\n", usec); + + /* Calculate a value of prescaler and divisor that will be able + * to count to the usec. It may not be exact or the best + * possible set, but it's a quick and simple algorithm. + * + * divisor max = 0x10000 + * prescaler max = MAX_PRESCALER + */ + + do + { + divisor = (CLOCK_MHZx2 * usec) / (prescaler * 2); + dbg("divisor=0x%x prescaler=0x%x\n", divisor, prescaler); + + if (divisor >= 0x10000) + { + if (prescaler == MAX_PRESCALER) + { + /* This is the max possible ~2.5 seconds. */ + + dbg("prescaler=0x%x too big!\n", prescaler); + return ERROR; + } + + prescaler <<= 1; + if (prescaler > MAX_PRESCALER) + { + prescaler = MAX_PRESCALER; + } + } + } + while (divisor >= 0x10000); + + dbg("prescaler=0x%x divisor=0x%x\n", prescaler, divisor); + + mode = wdt_prescaletoptv(prescaler); + mode &= ~C5471_TIMER_AUTORELOAD; /* One shot mode. */ + mode |= divisor << 5; + dbg("mode=0x%x\n", mode); + + c5471_wdt_cntl = mode; + + /* Now start the watchdog */ + + c5471_wdt_cntl |= C5471_TIMER_STARTBIT; + dbg("cntl_timer=0x%x\n", c5471_wdt_cntl); + + return 0; +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wdt_interrupt + ****************************************************************************/ + +static int wdt_interrupt(int irq, void *context) +{ + dbg("expired\n"); + +#if defined(CONFIG_SOFTWARE_REBOOT) +# if defined(CONFIG_SOFTWARE_TEST) + dbg(" Test only\n"); +# else + dbg(" Re-booting\n"); +# warning "Add logic to reset CPU here" +# endif +#else + dbg(" No reboot\n"); +#endif + return OK; +} + +/**************************************************************************** + * Name: wdt_read + ****************************************************************************/ + +static ssize_t wdt_read(struct file *filep, char *buffer, size_t buflen) +{ + /* We are going to return "NNNNNNNN NNNNNNNN." The followig logic will + * not work if the user provides a buffer smaller than 18 bytes. + */ + + dbg("buflen=%d\n", buflen); + if (buflen >= 18) + { + sprintf(buffer, "%08x %08x\n", c5471_wdt_cntl, c5471_wdt_count); + return 18; + } + return 0; +} + +/**************************************************************************** + * Name: wdt_write + ****************************************************************************/ + +static ssize_t wdt_write(struct file *filep, const char *buffer, size_t buflen) +{ + dbg("buflen=%d\n", buflen); + if (buflen) + { + /* Reset the timer to the maximum delay */ + + wdt_setusec(MAX_WDT_USEC); + return 1; + } + + return 0; +} + +/**************************************************************************** + * Name: wdt_ioctl + ****************************************************************************/ + +static int wdt_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + dbg("ioctl Call: cmd=0x%x arg=0x%x", cmd, arg); + + /* Process the IOCTL command (see arch/watchdog.h) */ + + switch (cmd) + { + case WDIOC_KEEPALIVE: + wdt_setusec(MAX_WDT_USEC); + break; + + default: + return -ENOTTY; + } + + return OK; +} + +/**************************************************************************** + * Name: wdt_open + ****************************************************************************/ + +static int wdt_open(struct file *filep) +{ + dbg(""); + + if (g_wdtopen) + { + return -EBUSY; + } + + /* This will automatically load the timer with its max + * count and start it running. + */ + + c5471_wdt_cntl = C5471_DISABLE_VALUE1; + c5471_wdt_cntl = C5471_DISABLE_VALUE2; + + g_wdtopen = true; + return OK; +} + +/**************************************************************************** + * Name: wdt_close + ****************************************************************************/ + +static int wdt_close(struct file *filep) +{ + dbg(""); + + /* The task controlling the watchdog has terminated. Take the timer + * the + * watchdog in interrupt mode -- we are going to reset unless the + * reopened again soon. + */ + +#ifndef CONFIG_WATCHDOG_STRICT + c5471_wdt_cntl = C5471_TIMER_MODE; +#endif + + g_wdtopen = false; + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdtinit + ****************************************************************************/ + +int up_wdtinit(void) +{ + int ret; + + dbg("C547x Watchdog Driver\n"); + + /* Register as /dev/wdt */ + + ret = register_driver("/dev/wdt", &g_wdtops, 0666, NULL); + if (ret) + { + return ERROR; + } + + /* Register for an interrupt level callback through wdt_interrupt */ + + dbg("Attach to IRQ=%d\n", C5471_IRQ_WATCHDOG); + + /* Make sure that the timer is stopped */ + + c5471_wdt_cntl = C5471_TIMER_STOP; + + /* Request the interrupt. */ + + ret = irq_attach(C5471_IRQ_WATCHDOG, wdt_interrupt); + if (ret) + { + unregister_driver("/dev/wdt"); + return ERROR; + } + + return OK; +} diff --git a/arch/arm/src/c5471/chip.h b/arch/arm/src/c5471/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..580ae075dcd6a8fef32e505b78ef45e2cd249253 --- /dev/null +++ b/arch/arm/src/c5471/chip.h @@ -0,0 +1,371 @@ +/**************************************************************************** + * c5471/chip.h + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __C5471_CHIP_H +#define __C5471_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EIM_RAM_START 0xffd00000 + +/* Ethernet Interface Module (EIM) ******************************************/ + +#define EIM_CTRL 0xffff0000 /* ESM control register */ +#define EIM_STATUS 0xffff0004 /* ESM status register */ +#define EIM_CPU_TXBA 0xffff0008 /* CPU TX descriptors base address */ +#define EIM_CPU_RXBA 0xffff000c /* CPU RX descriptors base address */ +#define EIM_BUFSIZE 0xffff0010 /* Packet buffer size register */ +#define EIM_CPU_FILTER 0xffff0014 /* CPU filtering contol registers */ +#define EIM_CPU_DAHI 0xffff0018 /* CPU destination address (HI) */ +#define EIM_CPU_DALO 0xffff001c /* CPU destination address (LO) */ +#define EIM_MFVHI 0xffff0020 /* Multicast filter valid (HI) */ +#define EIM_MFVLO 0xffff0024 /* Multicast filter valid (LO) */ +#define EIM_MFMHI 0xffff0028 /* Multicast filter mask (HI) */ +#define EIM_MFMLO 0xffff002c /* Multicast filter mask (LO) */ +#define EIM_RXTH 0xffff0030 /* RX threshold register */ +#define EIM_CPU_RXREADY 0xffff0034 /* CPU RX ready register */ +#define EIM_INTEN 0xffff0038 /* ESM interrupt enable register */ +#define EIM_ENET0_TXDESC 0xffff0040 /* ENET0 TX Queue pointer */ +#define EIM_ENET0_RXDESC 0xffff0044 /* ENET0 RX Queue pointer */ +#define EIM_CPU_TXDESC 0xffff0050 /* CPU TX Queue pointer */ +#define EIM_CPU_RXDESC 0xffff0054 /* CPU RX Queue pointer */ + +#define ENET0_MODE 0xffff0100 /* Mode register */ +#define ENET0_BOFFSEED 0xffff0104 /* Backoff seed register */ +#define ENET0_BCOUNT 0xffff0108 /* Backoff count register */ +#define ENET0_FLWPAUSE 0xffff010c /* TX flow pause count register */ +#define ENET0_FLWCONTROL 0xffff0110 /* Flow control register */ +#define ENET0_VTYPE 0xffff0114 /* VTYPE tag register */ +#define ENET0_SEISR 0xffff0118 /* System error int status register */ +#define ENET0_TXBUFRDY 0xffff011c /* TX descripter buffer ready */ +#define ENET0_TDBA 0xffff0120 /* TX descriptor base address */ +#define ENET0_RDBA 0xffff0124 /* RX descriptor base address */ +#define ENET0_PARHI 0xffff0128 /* Dest phys address match (HI) */ +#define ENET0_PARLO 0xffff012c /* Dest phys address match (LO) */ +#define ENET0_LARHI 0xffff0130 /* Log address hash filter (HI) */ +#define ENET0_LARLO 0xffff0134 /* Log address hash filter (LO) */ +#define ENET0_ADRMODE_EN 0xffff0138 /* Address mode enable register */ +#define ENET0_DRP 0xffff013c /* Desc ring poll interval count */ + +/* UARTs ********************************************************************/ + +#define UART_IRDA_BASE 0xffff0800 +#define UART_MODEM_BASE 0xffff1000 +#define UARTn_IO_RANGE 0x00000800 + +/* Common UART Registers. Expressed as offsets from the BASE address */ + +#define UART_RHR_OFFS 0x00000000 /* Rcv Holding Register */ +#define UART_THR_OFFS 0x00000004 /* Xmit Holding Register */ +#define UART_FCR_OFFS 0x00000008 /* FIFO Control Register */ +#define UART_RFCR_OFFS 0x00000008 /* Rcv FIFO Control Register */ +#define UART_TFCR_OFFS 0x00000008 /* Xmit FIFO Control Register */ +#define UART_SCR_OFFS 0x0000000c /* Status Control Register */ +#define UART_LCR_OFFS 0x00000010 /* Line Control Register */ +#define UART_LSR_OFFS 0x00000014 /* Line Status Register */ +#define UART_SSR_OFFS 0x00000018 /* Supplementary Status Register */ +#define UART_MCR_OFFS 0x0000001c /* Modem Control Register */ +#define UART_MSR_OFFS 0x00000020 /* Modem Status Register */ +#define UART_IER_OFFS 0x00000024 /* Interrupt Enable Register */ +#define UART_ISR_OFFS 0x00000028 /* Interrupt Status Register */ +#define UART_EFR_OFFS 0x0000002c /* Enhanced Feature Register */ +#define UART_XON1_OFFS 0x00000030 /* XON1 Character Register */ +#define UART_XON2_OFFS 0x00000034 /* XON2 Character Register */ +#define UART_XOFF1_OFFS 0x00000038 /* XOFF1 Character Register */ +#define UART_XOFF2_OFFS 0x0000003c /* XOFF2 Character Register */ +#define UART_SPR_OFFS 0x00000040 /* Scratch-pad Register */ +#define UART_DIV_115K_OFFS 0x00000044 /* Divisor for baud generation */ +#define UART_DIV_BIT_RATE_OFFS 0x00000048 /* For baud rate generation */ +#define UART_TCR_OFFS 0x0000004c /* Transmission Control Register */ +#define UART_TLR_OFFS 0x00000050 /* Trigger Level Register */ +#define UART_MDR_OFFS 0x00000054 /* Mode Definition Register */ + +/* Registers available only for the IrDA UART (absolute address). */ + +#define UART_IRDA_MDR1 0xffff0854 /* Mode Definition Register 1 */ +#define UART_IRDA_MDR2 0xffff0858 /* Mode Definition Register 2 */ +#define UART_IRDA_TXFLL 0xffff085c /* LS Xmit Frame Length Register */ +#define UART_IRDA_TXFLH 0xffff0860 /* MS Xmit Frame Length Register */ +#define UART_IRDA_RXFLL 0xffff0864 /* LS Rcvd Frame Length Register */ +#define UART_IRDA_RXFLH 0xffff0868 /* MS Rcvd Frame Length Register */ +#define UART_IRDA_SFLSR 0xffff086c /* Status FIFO Line Status Reg */ +#define UART_IRDA_SFREGL 0xffff0870 /* LS Status FIFO Register */ +#define UART_IRDA_SFREGH 0xffff0874 /* MS Status FIFO Register */ +#define UART_IRDA_BLR 0xffff0878 /* Begin of File Length Register */ +#define UART_IRDA_PULSE_WIDTH 0xffff087c /* Pulse Width Register */ +#define UART_IRDA_ACREG 0xffff0880 /* Auxiliary Control Register */ +#define UART_IRDA_PULSE_START 0xffff0884 /* Start time of pulse */ +#define UART_IRDA_RX_W_PTR 0xffff0888 /* RX FIFO write pointer */ +#define UART_IRDA_RX_R_PTR 0xffff088c /* RX FIFO read pointer */ +#define UART_IRDA_TX_W_PTR 0xffff0890 /* TX FIFO write pointer */ +#define UART_IRDA_TX_R_PTR 0xffff0894 /* TX FIFO read pointer */ +#define UART_IRDA_STATUS_W_PTR 0xffff0898 /* Write pointer of status FIFO */ +#define UART_IRDA_STATUS_R_PTR 0xffff089c /* Read pointer of status FIFO */ +#define UART_IRDA_RESUME 0xffff08a0 /* Resume register */ +#define UART_IRDA_MUX 0xffff08a4 /* Selects UART_IRDA output mux */ + +/* Registers available for the Modem UART (absolute addresses) */ + +#define UART_MODEM_MDR 0xffff1054 /* Mode Definition Register */ +#define UART_MODEM_UASR 0xffff1058 /* UART Auto-baud Status Register */ +#define UART_MODEM_RDPTR_URX 0xffff105c /* RX FIFO Read Pointer Register */ +#define UART_MODEM_WRPTR_URX 0xffff1060 /* RX FIFO Write Pointer Register */ +#define UART_MODEM_RDPTR_UTX 0xffff1064 /* TX FIFO Read Pointer Register */ +#define UART_MODEM_WRPTR_UTX 0xffff1068 /* TX FIFO Write Pointer Register */ + +/* UART Settings ************************************************************/ + +/* Miscellaneous UART settings. */ + +#define UART_RX_FIFO_NOEMPTY 0x00000001 +#define UART_SSR_TXFULL 0x00000001 +#define UART_LSR_TREF 0x00000020 + +#define UART_XMIT_FIFO_SIZE 64 +#define UART_IRDA_XMIT_FIFO_SIZE 64 + +/* UART_LCR Register */ + /* Bits 31-7: Reserved */ +#define UART_LCR_BOC 0x00000040 /* Bit 6: Break Control */ + /* Bit 5: Parity Type 2 */ +#define UART_LCR_PAREVEN 0x00000010 /* Bit 4: Parity Type 1 */ +#define UART_LCR_PARODD 0x00000000 +#define UART_LCR_PAREN 0x00000008 /* Bit 3: Paity Enable */ +#define UART_LCR_PARDIS 0x00000000 +#define UART_LCR_2STOP 0x00000004 /* Bit 2: Number of stop bits */ +#define UART_LCR_1STOP 0x00000000 +#define UART_LCR_5BITS 0x00000000 /* Bits 0-1: Word-length */ +#define UART_LCR_6BITS 0x00000001 +#define UART_LCR_7BITS 0x00000002 +#define UART_LCR_8BITS 0x00000003 + +#define UART_FCR_FTL 0x00000000 +#define UART_FCR_FIFO_EN 0x00000001 +#define UART_FCR_TX_CLR 0x00000002 +#define UART_FCR_RX_CLR 0x00000004 + +#define UART_IER_RECVINT 0x00000001 +#define UART_IER_XMITINT 0x00000002 +#define UART_IER_LINESTSINT 0x00000004 +#define UART_IER_MODEMSTSINT 0x00000008 /* IrDA UART only */ +#define UART_IER_XOFFINT 0x00000020 +#define UART_IER_RTSINT 0x00000040 /* IrDA UART only */ +#define UART_IER_CTSINT 0x00000080 /* IrDA UART only */ +#define UART_IER_INTMASK 0x000000ff + +#define BAUD_115200 0x00000001 +#define BAUD_57600 0x00000002 +#define BAUD_38400 0x00000003 +#define BAUD_19200 0x00000006 +#define BAUD_9600 0x0000000C +#define BAUD_4800 0x00000018 +#define BAUD_2400 0x00000030 +#define BAUD_1200 0x00000060 + +#define MDR_UART_MODE 0x00000000 /* Both IrDA and Modem UARTs */ +#define MDR_SIR_MODE 0x00000001 /* IrDA UART only */ +#define MDR_AUTOBAUDING_MODE 0x00000002 /* Modem UART only */ +#define MDR_RESET_MODE 0x00000007 /* Both IrDA and Modem UARTs */ + +/* SPI **********************************************************************/ + +#define MAX_SPI 3 + +#define SPI_REGISTER_BASE 0xffff2000 + +/* GIO **********************************************************************/ + +#define MAX_GIO (35) + +#define GIO_REGISTER_BASE 0xffff2800 + +#define GPIO_IO 0xffff2800 /* Writeable when I/O is configured + * as an output; reads value on I/O + * pin when I/O is configured as an + * input */ +#define GPIO_CIO 0xffff2804 /* GPIO configuration register */ +#define GPIO_IRQA 0xffff2808 /* In conjunction with GPIO_IRQB + * determines the behavior when GPIO + * pins configured as input IRQ */ +#define GPIO_IRQB 0xffff280c /* Determines the behavior when GPIO + * pins configured as input IRQ */ +#define GPIO_DDIO 0xffff2810 /* Delta Detect Register + * (detects changes in the I/O pins) */ +#define GPIO_EN 0xffff2814 /* Selects register for muxed GPIOs */ + +#define KGIO_REGISTER_BASE 0xffff2900 + +#define KBGPIO_IO 0xffff2900 /* Keyboard I/O bits: Writeable + * when KBGPIO is configured as an + * output; reads value on I/O pin + * when KBGPIO is configured as an + * input */ +#define KBGPIO_CIO 0xffff2904 /* KBGPIO configuration register */ +#define KBGPIO_IRQA 0xffff2908 /* In conjunction with KBGPIO_IRQB + * determines the behavior when + * KBGPIO pins configured as input + * IRQ */ +#define KBGPIO_IRQB 0xffff290c /* In conjunction with KBGPIO_IRQA + * determines the behavior when + * KBGPIO pins configured as input + * IRQ */ +#define KBGPIO_DDIO 0xffff2910 /* Delta Detect Register (detects + * changes in the KBGPIO pins) */ +#define KBGPIO_EN 0xffff2914 /* Selects register for muxed + * KBGPIOs */ + +/* Timers *******************************************************************/ + +#define C5471_TIMER0_CTRL 0xffff2a00 +#define C5471_TIMER0_CNT 0xffff2a04 +#define C5471_TIMER1_CTRL 0xffff2b00 +#define C5471_TIMER1_CNT 0xffff2b04 +#define C5471_TIMER2_CTRL 0xffff2c00 + +#define C5471_TIMER2_CNT 0xffff2c04 + +/* Interrupts */ + +#define HAVE_SRC_IRQ_BIN_REG 0 + +#define INT_FIRST_IO 0xffff2d00 +#define INT_IO_RANGE 0x5C + +#define IT_REG 0xffff2d00 +#define MASK_IT_REG 0xffff2d04 +#define SRC_IRQ_REG 0xffff2d08 +#define SRC_FIQ_REG 0xffff2d0c +#define SRC_IRQ_BIN_REG 0xffff2d10 +#define INT_CTRL_REG 0xffff2d18 + +#define ILR_IRQ0_REG 0xffff2d1C /* 0-Timer 0 */ +#define ILR_IRQ1_REG 0xffff2d20 /* 1-Timer 1 */ +#define ILR_IRQ2_REG 0xffff2d24 /* 2-Timer 2 */ +#define ILR_IRQ3_REG 0xffff2d28 /* 3-GPIO0 */ +#define ILR_IRQ4_REG 0xffff2d2c /* 4-Ethernet */ +#define ILR_IRQ5_REG 0xffff2d30 /* 5-KBGPIO[7:0] */ +#define ILR_IRQ6_REG 0xffff2d34 /* 6-Uart serial */ +#define ILR_IRQ7_REG 0xffff2d38 /* 7-Uart IRDA */ +#define ILR_IRQ8_REG 0xffff2d3c /* 8-KBGPIO[15:8] */ +#define ILR_IRQ9_REG 0xffff2d40 /* 9-GPIO3 */ +#define ILR_IRQ10_REG 0xffff2d44 /* 10-GPIO2 */ +#define ILR_IRQ11_REG 0xffff2d48 /* 11-I2C */ +#define ILR_IRQ12_REG 0xffff2d4c /* 12-GPIO1 */ +#define ILR_IRQ13_REG 0xffff2d50 /* 13-SPI */ +#define ILR_IRQ14_REG 0xffff2d54 /* 14-GPIO[19:4] */ +#define ILR_IRQ15_REG 0xffff2d58 /* 15-API */ + +/* CLKM *********************************************************************/ + +#define CLKM 0xffff2f00 +#define CLKM_CTL_RST 0xffff2f10 +#define CLKM_RESET 0xffff2f18 + +#define CLKM_RESET_EIM 0x00000008 +#define CLKM_EIM_CLK_STOP 0x00000010 +#define CLKM_CTL_RST_LEAD_RESET 0x00000000 +#define CLKM_CTL_RST_EXT_RESET 0x00000002 + +/* I2C **********************************************************************/ + +#define MAX_I2C 1 + +/* API **********************************************************************/ + +#define DSPRAM_BASE 0xffe00000 /* DSPRAM base address */ +#define DSPRAM_END 0xffe03fff + +/* This is the API address range in the DSP address space. */ + +#define DSPMEM_DSP_START 0x2000 +#define DSPMEM_DSP_END 0x3fff + +/* This is the API address range in the ARM address space. */ + +#define DSPMEM_ARM_START DSPRAM_BASE /* Defined in hardware.h */ +#define DSPMEM_ARM_END DSPRAM_END + +/* DSPMEM_IN_RANGE is a generic macro to test is a value is within + * a range of values. + */ + +#define DSPMEM_IN_RANGE(addr, start, end) \ + ((((__u32)(addr)) >= (start)) && (((__u32)(addr)) <= (end))) + +/* DSPMEM_ADDR_ALIGNED verifies that a potential DSP address is + * properly word aligned. + */ + +#define DSPMEM_ADDR_ALIGNED(addr, cpu) ((((__u32)(addr)) & 1) == 0) + +/* DSPMEM_DSP_ADDR checks if a DSP address lies in within the + * DSP's API address range. + */ + +#define DSPMEM_DSP_ADDR(addr, cpu) \ + DSPMEM_IN_RANGE(addr, DSPMEM_DSP_START, DSPMEM_DSP_END) + +/* DSPMEM_ARM_ADDR checks if a ARM address lies in within the + * ARM's API address range. + */ + +#define DSPMEM_ARM_ADDR(addr) \ + DSPMEM_IN_RANGE(addr, DSPMEM_ARM_START, DSPMEM_ARM_END) + +/* DSPMEM_DSP_TO_ARM maps a DSP API address into an ARM API address */ + +#define DSPMEM_DSP_TO_ARM(addr, cpu) \ + ((((__u32)(addr) - DSPMEM_DSP_START) << 1) + DSPMEM_ARM_START) + +/* DSPMEM_ARM_TO_DSP maps an ARM API address into a DSP API address */ + +#define DSPMEM_ARM_TO_DSP(addr) \ + ((((__u32)(addr) - DSPMEM_ARM_START) >> 1) + DSPMEM_DSP_START) + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __C5471_CHIP_H */ diff --git a/arch/arm/src/calypso/Kconfig b/arch/arm/src/calypso/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..e044280f6269506a88aea11e65cf644a639a958c --- /dev/null +++ b/arch/arm/src/calypso/Kconfig @@ -0,0 +1,115 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Calypso Configuration Options" + +menu "Modem UART Configuration" + +config UART_MODEM_BAUD + int "Modem UART BAUD" + default 115200 + +config UART_MODEM_PARITY + int "Modem UART parity" + default 0 + ---help--- + Modem UART parity. 0=None, 1=Odd, 2=Even. Default: None + +config UART_MODEM_BITS + int "Modem UART number of bits" + default 8 + ---help--- + Modem UART number of bits. Default: 8 + +config UART_MODEM_2STOP + int "Modem UART two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config UART_MODEM_RXBUFSIZE + int "Modem UART Rx buffer size" + default 256 + ---help--- + Modem UART Rx buffer size. Default: 256 + +config UART_MODEM_TXBUFSIZE + int "Modem UART Tx buffer size" + default 256 + ---help--- + Modem UART Tx buffer size. Default: 256 + +config UART_MODEM_HWFLOWCONTROL + bool "Hardware flow control" + default n + ---help--- + Enabled Modem UART hardware flow control. Default: n + +endmenu + +menu "IrDA UART Configuration" + +config UART_IRDA_BAUD + int "IrDA UART BAUD" + default 115200 + +config UART_IRDA_PARITY + int "IrDA UART parity" + default 0 + ---help--- + IrDA UART parity. 0=None, 1=Odd, 2=Even. Default: None + +config UART_IRDA_BITS + int "IrDA UART number of bits" + default 8 + ---help--- + IrDA UART number of bits. Default: 8 + +config UART_IRDA_2STOP + int "IrDA UART two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config UART_IRDA_RXBUFSIZE + int "IrDA UART Rx buffer size" + default 256 + ---help--- + IrDA UART Rx buffer size. Default: 256 + +config UART_IRDA_TXBUFSIZE + int "IrDA UART Tx buffer size" + default 256 + ---help--- + IrDA UART Tx buffer size. Default: 256 + +config UART_IRDA_HWFLOWCONTROL + bool "Hardware flow control" + default n + ---help--- + Enabled IrDA UART hardware flow control. Default: n + +endmenu + +choice + prompt "Serial Console Selection" + default SERIAL_CONSOLE_NONE + depends on DEV_CONSOLE + +# See drivers/Kconfig +config USE_SERCOMM_CONSOLE + bool "SERCOMM console" + select SERCOMM_CONSOLE + +config SERIAL_MODEM_CONSOLE + bool "Serial console on modem UART" + +config SERIAL_IRDA_CONSOLE + bool "Serial console on IrDA UART" + +config SERIAL_CONSOLE_NONE + bool "No serial console" + +endchoice diff --git a/arch/arm/src/calypso/Make.defs b/arch/arm/src/calypso/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..c3d6b6b0bb53d4c625c3e08aefc5c8445bc6dc01 --- /dev/null +++ b/arch/arm/src/calypso/Make.defs @@ -0,0 +1,71 @@ +############################################################################ +# calypso/Make.defs +# +# Copyright (C) 2007, 2013-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Copyright (C) 2011 Stefan Richter. All rights reserved. +# Author: Stefan Richter +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = calypso_head.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S +CMN_ASRCS += up_nommuhead.S vfork.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c +CMN_CSRCS += up_doirq.c up_exit.c up_idle.c up_initialstate.c up_initialize.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c calypso_power.c up_vfork.c + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = calypso_lowputc.S +CHIP_CSRCS = calypso_irq.c calypso_heap.c calypso_serial.c clock.c +CHIP_CSRCS += calypso_uwire.c calypso_armio.c calypso_keypad.c + +ifeq ($(CONFIG_SPI),y) +CHIP_CSRCS += calypso_spi.c +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += calypso_timer.c +endif diff --git a/arch/arm/src/calypso/calypso_armio.c b/arch/arm/src/calypso/calypso_armio.c new file mode 100644 index 0000000000000000000000000000000000000000..c210fa34dce0e2b030308775ad9a30056e5f5d04 --- /dev/null +++ b/arch/arm/src/calypso/calypso_armio.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * Driver for shared features of ARMIO modules + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * HW access + ****************************************************************************/ + +#define BASE_ADDR_ARMIO 0xfffe4800 +#define ARMIO_REG(x) (BASE_ADDR_ARMIO + (x)) + +enum armio_reg { + LATCH_IN = 0x00, + LATCH_OUT = 0x02, + IO_CNTL = 0x04, + CNTL_REG = 0x06, + LOAD_TIM = 0x08, + KBR_LATCH_REG = 0x0a, + KBC_REG = 0x0c, + BUZZ_LIGHT_REG = 0x0e, + LIGHT_LEVEL = 0x10, + BUZZER_LEVEL = 0x12, + GPIO_EVENT_MODE = 0x14, + KBD_GPIO_INT = 0x16, + KBD_GPIO_MASKIT = 0x18, + GPIO_DEBOUNCING = 0x1a, + GPIO_LATCH = 0x1c, +}; + +#define KBD_INT (1 << 0) +#define GPIO_INT (1 << 1) + +/**************************************************************************** + * ARMIO interrupt handler + * forward keypad events + * forward GPIO events + ****************************************************************************/ + +static int kbd_gpio_irq(int irq, uint32_t *regs) +{ + return calypso_kbd_irq(irq, regs); +} + +/**************************************************************************** + * Initialize ARMIO + ****************************************************************************/ + +void calypso_armio(void) +{ + /* Enable ARMIO clock */ + + putreg16(1 << 5, ARMIO_REG(CNTL_REG)); + + /* Mask GPIO interrupt and keypad interrupt */ + + putreg16(KBD_INT | GPIO_INT, ARMIO_REG(KBD_GPIO_MASKIT)); + + /* Attach and enable the interrupt */ + + irq_attach(IRQ_KEYPAD_GPIO, (xcpt_t)kbd_gpio_irq); + up_enable_irq(IRQ_KEYPAD_GPIO); +} diff --git a/arch/arm/src/calypso/calypso_head.S b/arch/arm/src/calypso/calypso_head.S new file mode 100644 index 0000000000000000000000000000000000000000..eb83b68516f261043edeb713474cb864fda7b5d2 --- /dev/null +++ b/arch/arm/src/calypso/calypso_head.S @@ -0,0 +1,23 @@ +/* Place a branch to the real head at the entry point */ +.section .text.start + b __start + + +/* Exception Vectors like they are needed for the exception vector + indirection of the internal boot ROM. The following section must + be liked to appear at 0x80001c */ +.section .text.exceptions +_undef_instr: + b up_vectorundefinsn +_sw_interr: + b up_vectorswi +_prefetch_abort: + b up_vectorprefetch +_data_abort: + b up_vectordata +_reserved: + b _reserved +_irq: + b up_vectorirq +_fiq: + b up_vectorfiq diff --git a/arch/arm/src/calypso/calypso_heap.c b/arch/arm/src/calypso/calypso_heap.c new file mode 100644 index 0000000000000000000000000000000000000000..697e05a8f5e39e1ac8b8f5f9ce9f074464e2e242 --- /dev/null +++ b/arch/arm/src/calypso/calypso_heap.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_heap.c + * Initialize memory interfaces of Calypso MCU + * + * (C) 2010 by Harald Welte + * (C) 2011 Stefan Richter + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * This function is called right after basics are initialized and right + * before IRQ system setup. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#ifdef CONFIG_ARCH_BOARD_COMPALE99 + /* Disable watchdog in first non-common function */ + wdog_enable(0); +#endif + /* XXX: change to initialization of extern memory with save defaults */ + /* Configure memory interface */ + calypso_mem_cfg(CALYPSO_nCS0, 3, CALYPSO_MEM_16bit, 1); + calypso_mem_cfg(CALYPSO_nCS1, 3, CALYPSO_MEM_16bit, 1); + calypso_mem_cfg(CALYPSO_nCS2, 5, CALYPSO_MEM_16bit, 1); + calypso_mem_cfg(CALYPSO_nCS3, 5, CALYPSO_MEM_16bit, 1); + calypso_mem_cfg(CALYPSO_CS4, 0, CALYPSO_MEM_8bit, 1); + calypso_mem_cfg(CALYPSO_nCS6, 0, CALYPSO_MEM_32bit, 1); + calypso_mem_cfg(CALYPSO_nCS7, 0, CALYPSO_MEM_32bit, 0); + + /* Set VTCXO_DIV2 = 1, configure PLL for 104 MHz and give ARM half of that */ + calypso_clock_set(2, CALYPSO_PLL13_104_MHZ, ARM_MCLK_DIV_2); + + /* Configure the RHEA bridge with some sane default values */ + calypso_rhea_cfg(0, 0, 0xff, 0, 1, 0, 0); + + kmm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +} +#endif diff --git a/arch/arm/src/calypso/calypso_irq.c b/arch/arm/src/calypso/calypso_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..85f4f084589bb7ac4e68b25f5761191a3bdcfdd3 --- /dev/null +++ b/arch/arm/src/calypso/calypso_irq.c @@ -0,0 +1,357 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_irq.c + * Driver for Calypso IRQ controller + * + * (C) 2010 by Harald Welte + * (C) 2011 by Stefan Richter + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BASE_ADDR_IRQ 0xfffffa00 +#define BASE_ADDR_IBOOT_EXC 0x0080001C + +enum irq_reg +{ + IT_REG1 = 0x00, + IT_REG2 = 0x02, + MASK_IT_REG1 = 0x08, + MASK_IT_REG2 = 0x0a, + IRQ_NUM = 0x10, + FIQ_NUM = 0x12, + IRQ_CTRL = 0x14, +}; + +#define ILR_IRQ(x) (0x20 + (x*2)) +#define IRQ_REG(x) (BASE_ADDR_IRQ + (x)) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; +extern uint32_t _exceptions; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t default_irq_prio[] = +{ + [IRQ_WATCHDOG] = 0xff, + [IRQ_TIMER1] = 0xff, + [IRQ_TIMER2] = 0xff, + [IRQ_TSP_RX] = 0, + [IRQ_TPU_FRAME] = 3, + [IRQ_TPU_PAGE] = 0xff, + [IRQ_SIMCARD] = 0xff, + [IRQ_UART_MODEM] = 8, + [IRQ_KEYPAD_GPIO] = 4, + [IRQ_RTC_TIMER] = 9, + [IRQ_RTC_ALARM_I2C] = 10, + [IRQ_ULPD_GAUGING] = 2, + [IRQ_EXTERNAL] = 12, + [IRQ_SPI] = 0xff, + [IRQ_DMA] = 0xff, + [IRQ_API] = 0xff, + [IRQ_SIM_DETECT] = 0, + [IRQ_EXTERNAL_FIQ] = 7, + [IRQ_UART_IRDA] = 2, + [IRQ_ULPD_GSM_TIMER] = 1, + [IRQ_GEA] = 0xff, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void _irq_enable(enum irq_nr nr, int enable) +{ + uintptr_t reg = IRQ_REG(MASK_IT_REG1); + uint16_t val; + + if (nr > 15) + { + reg = IRQ_REG(MASK_IT_REG2); + nr -= 16; + } + + val = getreg16(reg); + if (enable) + { + val &= ~(1 << nr); + } + else + { + val |= (1 << nr); + } + + putreg16(val, reg); +} + +static void set_default_priorities(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) + { + uint16_t val; + uint8_t prio = default_irq_prio[i]; + + if (prio > 31) + { + prio = 31; + } + + val = getreg16(IRQ_REG(ILR_IRQ(i))); + val &= ~(0x1f << 2); + val |= prio << 2; + + /* Make edge mode default. Hopefully causes less trouble */ + + val |= 0x02; + + putreg16(val, IRQ_REG(ILR_IRQ(i))); + } +} + +/* Install the exception handlers to where the ROM loader jumps */ + +static void calypso_exceptions_install(void) +{ + uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC; + uint32_t *exceptions_src = &_exceptions; + int i; + + for (i = 0; i < 7; i++) + { + *exceptions_dst++ = *exceptions_src++; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Setup the IRQ and FIQ controllers + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Prepare hardware */ + + calypso_exceptions_install(); + CURRENT_REGS = NULL; + + /* Switch to internal ROM */ + + calypso_bootrom(1); + + /* Set default priorities */ + + set_default_priorities(); + + /* Mask all interrupts off */ + + putreg16(0xffff, IRQ_REG(MASK_IT_REG1)); + putreg16(0xffff, IRQ_REG(MASK_IT_REG2)); + + /* clear all pending interrupts */ + putreg16(0, IRQ_REG(IT_REG1)); + putreg16(0, IRQ_REG(IT_REG2)); + + /* Enable interrupts globally to the ARM core */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + _irq_enable(irq, 0); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + _irq_enable(irq, 1); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int nr, int prio) +{ + uint16_t val; + + if (prio == -1) + { + prio = default_irq_prio[nr]; + } + + if (prio > 31) + { + prio = 31; + } + + val = prio << 2; + putreg16(val, IRQ_REG(ILR_IRQ(nr))); + + return 0; +} +#endif + +/**************************************************************************** + * Entry point for interrupts + ****************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ + uint8_t num, tmp; + uint32_t *saved_regs; + + /* XXX: What is this??? + * Passed to but ignored in IRQ handlers + * Only valid meaning is apparently non-NULL == IRQ context */ + + saved_regs = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Detect & deliver the IRQ */ + + num = getreg8(IRQ_REG(IRQ_NUM)) & 0x1f; + irq_dispatch(num, regs); + + /* Start new IRQ agreement */ + + tmp = getreg8(IRQ_REG(IRQ_CTRL)); + tmp |= 0x01; + putreg8(tmp, IRQ_REG(IRQ_CTRL)); + + CURRENT_REGS = saved_regs; +} + +/**************************************************************************** + * Entry point for FIQs + ****************************************************************************/ + +void calypso_fiq(void) +{ + uint8_t num, tmp; + uint32_t *regs; + + /* XXX: What is this??? + * Passed to but ignored in IRQ handlers + * Only valid meaning is apparently non-NULL == IRQ context */ + + regs = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = (uint32_t *)# + + /* Detect & deliver like an IRQ but we are in FIQ context */ + + num = getreg8(IRQ_REG(FIQ_NUM)) & 0x1f; + irq_dispatch(num, regs); + + /* Start new FIQ agreement */ + + tmp = getreg8(IRQ_REG(IRQ_CTRL)); + tmp |= 0x02; + putreg8(tmp, IRQ_REG(IRQ_CTRL)); + + CURRENT_REGS = regs; +} diff --git a/arch/arm/src/calypso/calypso_keypad.c b/arch/arm/src/calypso/calypso_keypad.c new file mode 100644 index 0000000000000000000000000000000000000000..2430667ca553012fdcec47709e6576c4ec6d3eb0 --- /dev/null +++ b/arch/arm/src/calypso/calypso_keypad.c @@ -0,0 +1,380 @@ +/**************************************************************************** + * Driver for Calypso keypad hardware + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/**************************************************************************** + * HW access + ****************************************************************************/ + +#define BASE_ADDR_ARMIO 0xfffe4800 +#define ARMIO_REG(x) ((void *)BASE_ADDR_ARMIO + (x)) + +enum armio_reg +{ + LATCH_IN = 0x00, + LATCH_OUT = 0x02, + IO_CNTL = 0x04, + CNTL_REG = 0x06, + LOAD_TIM = 0x08, + KBR_LATCH_REG = 0x0a, + KBC_REG = 0x0c, + BUZZ_LIGHT_REG = 0x0e, + LIGHT_LEVEL = 0x10, + BUZZER_LEVEL = 0x12, + GPIO_EVENT_MODE = 0x14, + KBD_GPIO_INT = 0x16, + KBD_GPIO_MASKIT = 0x18, + GPIO_DEBOUNCING = 0x1a, + GPIO_LATCH = 0x1c, +}; + +#define KBD_INT (1 << 0) +#define GPIO_INT (1 << 1) + +/**************************************************************************** + * Decoder functions for matrix and power button + ****************************************************************************/ + +static int btn_dec(uint32_t * btn_state, uint8_t col, uint8_t reg, + char *buf, size_t buflen, size_t * len) +{ + uint8_t diff = (*btn_state ^ reg) & 0x1f; + + while (diff) + { + uint8_t val = diff & ~(diff - 1); + uint8_t sc = val >> 1; + sc |= sc << 2; + sc += col; + sc += (sc & 0x20) ? 0x26 : 0x3f; + + if (reg & val) + { + sc |= 0x20; + } + + /* Check for space in buffer and dispatch */ + + if (*len < buflen) + { + buf[(*len)++] = sc; + } + else + { + break; + } + + /* Only change diff if dispatched/buffer not full */ + + diff ^= val; + } + + /* Store new state of the buttons (but only if they where dispatch) */ + + *btn_state >>= 5; +#ifdef INCLUDE_ALL_COLS + *btn_state |= (reg ^ diff) << 20; +#else + *btn_state |= (reg ^ diff) << 15; +#endif + return diff; +} + +static int pwr_btn_dec(uint32_t * state, uint8_t reg, char *buf, size_t * len) +{ + if (reg) + { + /* Check for pressed power button. If pressed, ignore other + * buttons since it collides with an entire row. + */ + + if (~*state & 0x80000000) + { + buf[0] = 'z'; + *len = 1; + *state |= 0x80000000; + } + + return 1; /* break loop in caller */ + } + else + { + /* Check for released power button. */ + + if (*state & 0x80000000) + { + buf[0] = 'Z'; + *len = 1; + + *state &= 0x7fffffff; + + /* Don't scan others when released; might trigger + * false keystrokes otherwise + */ + + return 1; + } + } + + return 0; /* Continue with other columns */ +} + +/**************************************************************************** + * Keypad: Fileops Prototypes and Structures + ****************************************************************************/ + +typedef FAR struct file file_t; + +static int keypad_open(file_t * filep); +static int keypad_close(file_t * filep); +static ssize_t keypad_read(file_t * filep, FAR char *buffer, size_t buflen); +#ifndef CONFIG_DISABLE_POLL +static int keypad_poll(file_t * filep, FAR struct pollfd *fds, bool setup); +#endif + +static const struct file_operations keypad_ops = +{ + keypad_open, /* open */ + keypad_close, /* close */ + keypad_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + keypad_poll /* poll */ +#endif +}; + +static sem_t kbdsem; + +/**************************************************************************** + * Keypad: Fileops + ****************************************************************************/ + +static int keypad_open(file_t * filep) +{ + register uint16_t reg; + + /* Unmask keypad interrupt */ + + reg = readw(ARMIO_REG(KBD_GPIO_MASKIT)); + writew(reg & ~KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT)); + + return OK; +} + +static int keypad_close(file_t * filep) +{ + register uint16_t reg; + + /* Mask keypad interrupt */ + + reg = readw(ARMIO_REG(KBD_GPIO_MASKIT)); + writew(reg | KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT)); + + return OK; +} + +static ssize_t keypad_read(file_t * filep, FAR char *buf, size_t buflen) +{ + static uint32_t btn_state = 0; + register uint16_t reg; + uint16_t col, col_mask; + size_t len = 0; + + if (buf == NULL || buflen < 1) + { + /* Well... nothing to do */ + + return -EINVAL; + } + +retry: + col = 1; + col_mask = 0x1e; + + if (!btn_state) + { + /* Drive all cols low such that all buttons cause events */ + + writew(0, ARMIO_REG(KBC_REG)); + + /* No button currently pressed, use IRQ */ + + reg = readw(ARMIO_REG(KBD_GPIO_MASKIT)); + writew(reg & ~KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT)); + sem_wait(&kbdsem); + } + else + { + writew(0x1f, ARMIO_REG(KBC_REG)); + usleep(80000); + } + + /* Scan columns */ + +#ifdef INCLUDE_ALL_COLS + while (col <= 6) + { +#else + while (col <= 5) + { +#endif + /* Read keypad latch and immediately set new column since + * synchronization takes about 5usec. For the 1st round, the + * interrupt has prepared this and the context switch takes + * long enough to serve as a delay. + */ + + reg = readw(ARMIO_REG(KBR_LATCH_REG)); + writew(col_mask, ARMIO_REG(KBC_REG)); + + /* Turn pressed buttons into 1s */ + + reg = 0x1f & ~reg; + + if (col == 1) + { + /* Power/End switch */ + + if (pwr_btn_dec(&btn_state, reg, buf, &len)) + { + break; + } + } + else + { + /* Non-power switches */ + + if (btn_dec(&btn_state, col, reg, buf, buflen, &len)) + { + break; + } + } + + /* Select next column and respective mask */ + + col_mask = 0x1f & ~(1 << col++); + + /* We have to wait for synchronization of the inputs. The + * processing is too fast if no/few buttons are processed. + */ + + usleep(5); + + /* XXX: usleep seems to suffer hugh overhead. Better this!? + * If nothing else can be done, it's overhead still wastes + * time 'usefully'. + */ + /* sched_yield(); up_udelay(2); */ + } + + /* If we don't have anything to return, retry to avoid EOF */ + + if (!len) + { + goto retry; + } + + return len; +} + +/**************************************************************************** + * Keypad interrupt handler + * mask interrupts + * prepare column drivers for scan + * posts keypad semaphore + ****************************************************************************/ + +int calypso_kbd_irq(int irq, uint32_t * regs) +{ + register uint16_t reg; + + /* Mask keypad interrupt */ + + reg = readw(ARMIO_REG(KBD_GPIO_MASKIT)); + writew(reg | KBD_INT, ARMIO_REG(KBD_GPIO_MASKIT)); + + /* Turn off column drivers */ + + writew(0x1f, ARMIO_REG(KBC_REG)); + + /* Let the userspace know */ + + sem_post(&kbdsem); + + return 0; +} + +/**************************************************************************** + * Initialize device, add /dev/... nodes + ****************************************************************************/ + +void up_keypad(void) +{ + /* Semaphore; helps leaving IRQ ctx as soon as possible */ + + sem_init(&kbdsem, 0, 0); + + /* Drive cols low in idle state such that all buttons cause events */ + + writew(0, ARMIO_REG(KBC_REG)); + + (void)register_driver("/dev/keypad", &keypad_ops, 0444, NULL); +} + +int keypad_kbdinit(void) +{ + calypso_armio(); + up_keypad(); + + return OK; +} diff --git a/arch/arm/src/calypso/calypso_lowputc.S b/arch/arm/src/calypso/calypso_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..5556b3baca956f135b3d956f10c43c62c9933b59 --- /dev/null +++ b/arch/arm/src/calypso/calypso_lowputc.S @@ -0,0 +1,133 @@ +/************************************************************************** + * calypso/calypso_lowputc.S + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * based on: c5471/c5471_lowputc.S + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + +#ifdef CONFIG_SERIAL_IRDA_CONSOLE + ldr r2, =UART_IRDA_BASE /* r2=IRDA UART base */ +#else + ldr r2, =UART_MODEM_BASE /* r2=Modem UART base */ +#endif + + /* Poll bit 0 of the UART_SSR register. When the bit + * is clear, the TX FIFO is no longer full + */ + +1: ldrb r1, [r2, #UART_SSR_OFFS] + tst r1, #UART_SSR_TXFULL + bne 1b + + /* Send the character by writing it into the UART_THR + * register. + */ + + strb r0, [r2, #UART_THR_OFFS] + + /* Wait for the tranmsit holding regiser (THR) to be + * emptied. This is detemined when bit 6 of the LSR + * is set. + */ + +2: ldrb r1, [r2, #UART_LSR_OFFS] + tst r1, #0x00000020 + beq 2b + + /* If the character that we just sent was a linefeed, + * then send a carriage return as well. + */ + + teq r0, #'\n' + moveq r0, #'\r' + beq 1b + + /* And return */ + + mov pc, lr + diff --git a/arch/arm/src/calypso/calypso_power.c b/arch/arm/src/calypso/calypso_power.c new file mode 100644 index 0000000000000000000000000000000000000000..11b51a629bf63315435e70725a0df8bd4f47ed56 --- /dev/null +++ b/arch/arm/src/calypso/calypso_power.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "calypso_spi.h" + +/**************************************************************************** + * Name: board_power_off + * + * Description: + * Power off the board. + * + * If this function returns, then it was not possible to power-off the + * board due to some other constraints. + * + * Input Parameters: + * status - Status information provided with the power off event. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_POWEROFF +int board_power_off(int status) +{ + struct spi_dev_s *spi = calypso_spibus_initialize(0); + uint16_t tx; + + SPI_SETBITS(spi, 16); + (void)SPI_HWFEATURES(spi, 0); + + tx = (1 << 6) | (1 << 1); + SPI_SNDBLOCK(spi, &tx, 1); + + tx = (1 << 6) | (30 << 1); + SPI_SNDBLOCK(spi, &tx, 1); + + return 0; +} +#endif diff --git a/arch/arm/src/calypso/calypso_serial.c b/arch/arm/src/calypso/calypso_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..0c4a44c0c14d90c08489ed35ac9e388a12c10aab --- /dev/null +++ b/arch/arm/src/calypso/calypso_serial.c @@ -0,0 +1,968 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_serial.c + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * based on c5471/c5471_serial.c + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BASE_BAUD 115200 + +#if defined(CONFIG_UART_IRDA_HWFLOWCONTROL) || defined(CONFIG_UART_MODEM_HWFLOWCONTROL) +# define CONFIG_UART_HWFLOWCONTROL +#endif + +#if UART_FCR_OFFS == UART_EFR_OFFS +# define UART_MULTIPLEX_REGS + +/* HW flow control not supported yet */ + +# undef CONFIG_UART_HWFLOWCONTROL +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct uart_regs_s +{ + uint32_t ier; + uint32_t lcr; + uint32_t fcr; +#ifdef CONFIG_UART_HWFLOWCONTROL + uint32_t efr; + uint32_t tcr; +#endif +}; + +struct up_dev_s +{ + unsigned int uartbase; /* Base address of UART registers */ + unsigned int baud_base; /* Base baud for conversions */ + unsigned int baud; /* Configured baud */ + uint8_t xmit_fifo_size; /* Size of transmit FIFO */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ +#ifdef CONFIG_UART_HWFLOWCONTROL + bool flowcontrol; /* true: Hardware flow control + * is enabled. */ +#endif + bool stopbits2; /* true: Configure with 2 + * stop bits instead of 1 */ + struct uart_regs_s regs; /* Shadow copy of readonly regs */ + +#ifdef CONFIG_SERCOMM_CONSOLE + bool sercomm; /* Call sercomm in interrupt if true */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_irdarxbuffer[CONFIG_UART_IRDA_RXBUFSIZE]; +static char g_irdatxbuffer[CONFIG_UART_IRDA_TXBUFSIZE]; +static char g_modemrxbuffer[CONFIG_UART_MODEM_RXBUFSIZE]; +static char g_modemtxbuffer[CONFIG_UART_MODEM_TXBUFSIZE]; + +/* This describes the state of the C5471 serial IRDA port. */ + +static struct up_dev_s g_irdapriv = +{ + .xmit_fifo_size = UART_IRDA_XMIT_FIFO_SIZE, + .baud_base = BASE_BAUD, + .uartbase = UART_IRDA_BASE, + .baud = CONFIG_UART_IRDA_BAUD, + .irq = UART_IRQ_IRDA, + .parity = CONFIG_UART_IRDA_PARITY, + .bits = CONFIG_UART_IRDA_BITS, +#ifdef CONFIG_UART_IRDA_HWFLOWCONTROL + .flowcontrol = true, +#endif + .stopbits2 = CONFIG_UART_IRDA_2STOP, + +#ifdef CONFIG_SERCOMM_CONSOLE + .sercomm = false, +#endif +}; + +static uart_dev_t g_irdaport = +{ + .recv = + { + .size = CONFIG_UART_IRDA_RXBUFSIZE, + .buffer = g_irdarxbuffer, + }, + .xmit = + { + .size = CONFIG_UART_IRDA_TXBUFSIZE, + .buffer = g_irdatxbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_irdapriv, +}; + +/* This describes the state of the C5471 serial Modem port. */ + +static struct up_dev_s g_modempriv = +{ + .xmit_fifo_size = UART_XMIT_FIFO_SIZE, + .baud_base = BASE_BAUD, + .uartbase = UART_MODEM_BASE, + .baud = CONFIG_UART_MODEM_BAUD, + .irq = UART_IRQ_MODEM, + .parity = CONFIG_UART_MODEM_PARITY, + .bits = CONFIG_UART_MODEM_BITS, +#ifdef CONFIG_UART_MODEM_HWFLOWCONTROL + .flowcontrol = true, +#endif + .stopbits2 = CONFIG_UART_MODEM_2STOP, + +#ifdef CONFIG_SERCOMM_CONSOLE + .sercomm = false, +#endif +}; + +static uart_dev_t g_modemport = +{ + .recv = + { + .size = CONFIG_UART_MODEM_RXBUFSIZE, + .buffer = g_modemrxbuffer, + }, + .xmit = + { + .size = CONFIG_UART_MODEM_TXBUFSIZE, + .buffer = g_modemtxbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_modempriv, +}; + +/* Now, which one with be tty0/console and which tty1? */ + +#ifdef CONFIG_SERIAL_IRDA_CONSOLE +# define CONSOLE_DEV g_irdaport +# define TTYS0_DEV g_irdaport +# define TTYS1_DEV g_modemport +#else +# define CONSOLE_DEV g_modemport +# define TTYS0_DEV g_modemport +# define TTYS1_DEV g_irdaport +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_inserial + ****************************************************************************/ + +static inline uint32_t up_inserial(struct up_dev_s *priv, uint32_t offset) +{ +#if UART_REGISTER_BITS == 8 + return getreg8(priv->uartbase + offset); +#elif UART_REGISTER_BITS == 32 + return getreg32(priv->uartbase + offset); +#else +#error Unsupported number of bits set in UART_REGISTER_BITS +#endif +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value) +{ +#if UART_REGISTER_BITS == 8 + putreg8(value & 0xff, priv->uartbase + offset); +#elif UART_REGISTER_BITS == 32 + putreg32(value, priv->uartbase + offset); +#endif +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier) +{ + if (ier) + { + *ier = priv->regs.ier & UART_IER_INTMASK; + } + priv->regs.ier &= ~UART_IER_INTMASK; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier) +{ + priv->regs.ier |= ier & (UART_IER_RECVINT | UART_IER_XMITINT); + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0) + { + break; + } + } +} +/**************************************************************************** + * Name: up_disablebreaks + ****************************************************************************/ + +static inline void up_disablebreaks(struct up_dev_s *priv) +{ + priv->regs.lcr &= ~UART_LCR_BOC; + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv) +{ + priv->regs.lcr |= UART_LCR_BOC; + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); +} + +/**************************************************************************** + * Name: up_setrate + ****************************************************************************/ + +static inline void up_setrate(struct up_dev_s *priv, unsigned int rate) +{ + uint32_t div_bit_rate; + + switch (rate) + { + case 115200: + div_bit_rate = BAUD_115200; + break; + case 57600: + div_bit_rate = BAUD_57600; + break; + case 38400: + div_bit_rate = BAUD_38400; + break; + case 19200: + div_bit_rate = BAUD_19200; + break; + case 4800: + div_bit_rate = BAUD_4800; + break; + case 2400: + div_bit_rate = BAUD_2400; + break; + case 1200: + div_bit_rate = BAUD_1200; + break; + case 9600: + default: + div_bit_rate = BAUD_9600; + break; + } + +#ifdef UART_DIV_BIT_RATE_OFFS + up_serialout(priv, UART_DIV_BIT_RATE_OFFS, div_bit_rate); +#else + up_serialout(priv, UART_DIV_LOW_OFFS, div_bit_rate); + up_serialout(priv, UART_DIV_HIGH_OFFS, div_bit_rate >> 8); +#endif +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ +#include +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = dev->priv; + unsigned int cval; + + if (priv->bits == 7) + { + cval = UART_LCR_7BITS; + } + else + { + cval = UART_LCR_8BITS; + } + + if (priv->stopbits2) + { + cval |= UART_LCR_2STOP; + } + + if (priv->parity == 1) /* Odd parity */ + { + cval |= (UART_LCR_PAREN | UART_LCR_PARODD); + } + else if (priv->parity == 2) /* Even parity */ + { + cval |= (UART_LCR_PAREN | UART_LCR_PAREVEN); + } + + /* Both the IrDA and MODEM UARTs support RESET and UART mode. */ + + up_serialout(priv, UART_MDR_OFFS, MDR_RESET_MODE); + up_serialout(priv, UART_LCR_OFFS, 0xbf); + up_serialout(priv, UART_XON1_OFFS, 0x00); + up_serialout(priv, UART_XON2_OFFS, 0x00); + up_serialout(priv, UART_XOFF1_OFFS, 0x00); + up_serialout(priv, UART_XOFF2_OFFS, 0x00); + up_serialout(priv, UART_EFR_OFFS, 0x00); + up_serialout(priv, UART_LCR_OFFS, 0x00); + up_mdelay(5); + + up_serialout(priv, UART_MDR_OFFS, MDR_UART_MODE); + up_mdelay(5); + + priv->regs.ier = up_inserial(priv, UART_IER_OFFS); + priv->regs.lcr = up_inserial(priv, UART_LCR_OFFS); +#ifdef CONFIG_UART_HWFLOWCONTROL + if (priv->flowcontrol) + { + priv->regs.efr = up_inserial(priv, UART_EFR_OFFS); + priv->regs.tcr = up_inserial(priv, UART_TCR_OFFS); + } +#endif + + up_disableuartint(priv, NULL); + +#ifdef UART_MULTIPLEX_REGS + up_serialout(priv, UART_LCR_OFFS, 0x00bf); +#endif + + up_serialout(priv, UART_EFR_OFFS, 0x0010); /* Unprotect enhanced control */ + +#ifdef UART_MULTIPLEX_REGS + priv->regs.lcr = 0x80; + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); + //up_serialout(priv, UART_MCR_OFFS, 1 << 4); /* loopback */ +#endif + + up_serialout(priv, UART_TFCR_OFFS, 0); /* Reset to 0 */ + up_serialout(priv, UART_RFCR_OFFS, UART_FCR_RX_CLR); /* Clear RX fifo */ + up_serialout(priv, UART_TFCR_OFFS, UART_FCR_TX_CLR); /* Clear TX fifo */ + priv->regs.fcr = UART_FCR_FIFO_EN; + up_serialout(priv, UART_TFCR_OFFS, priv->regs.fcr); /* Enable RX/TX fifos */ + + up_disablebreaks(priv); + + /* Set the RX and TX trigger levels to the minimum */ + + priv->regs.fcr = (priv->regs.fcr & 0xffffff0f) | UART_FCR_FTL; + up_serialout(priv, UART_RFCR_OFFS, priv->regs.fcr); + + up_setrate(priv, priv->baud); + +#ifdef UART_MULTIPLEX_REGS + up_serialout(priv, UART_SCR_OFFS, 1); /* Disable DMA */ + priv->regs.lcr = (uint32_t)cval; /* Configure mode, return to THR/RHR */ +#else + priv->regs.lcr &= 0xffffffe0; /* clear original field, and... */ + priv->regs.lcr |= (uint32_t)cval; /* Set new bits in that field. */ +#endif + up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr); + +#ifdef CONFIG_UART_HWFLOWCONTROL + if (priv->flowcontrol) + { + /* Set the FIFO level triggers for flow control + * Halt = 48 bytes, resume = 12 bytes + */ + + priv->regs.tcr = (priv->regs.tcr & 0xffffff00) | 0x0000003c; + up_serialout(priv, UART_TCR_OFFS, priv->regs.tcr); + + /* Enable RTS/CTS flow control */ + + priv->regs.efr |= 0x000000c0; + up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); + } + else + { + /* Disable RTS/CTS flow control */ + + priv->regs.efr &= 0xffffff3f; + up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); + } +#endif +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + volatile uint32_t cause; + + if (g_irdapriv.irq == irq) + { + dev = &g_irdaport; + } + else if (g_modempriv.irq == irq) + { + dev = &g_modemport; + } + else + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + cause = up_inserial(priv, UART_ISR_OFFS) & 0x0000003f; + + if ((cause & 0x0000000c) == 0x0000000c) + { + uint32_t ier_val = 0; + + /* Is this an interrupt from the IrDA UART? */ + + if (irq == UART_IRQ_IRDA) + { + /* Save the currently enabled IrDA UART interrupts + * so that we can restore the IrDA interrupt state + * below. + */ + + ier_val = up_inserial(priv, UART_IER_OFFS); + + /* Then disable all IrDA UART interrupts */ + + up_serialout(priv, UART_IER_OFFS, 0); + } + + /* Receive characters from the RX fifo */ + +#ifdef CONFIG_SERCOMM_CONSOLE + if (priv->sercomm) + { + sercomm_recvchars(dev); + } + else +#endif + { + uart_recvchars(dev); + } + + /* read UART_RHR to clear int condition + * toss = up_inserialchar(priv,&status); + */ + + /* Is this an interrupt from the IrDA UART? */ + + if (irq == UART_IRQ_IRDA) + { + /* Restore the IrDA UART interrupt enables */ + + up_serialout(priv, UART_IER_OFFS, ier_val); + } + } + else if ((cause & 0x0000000c) == 0x00000004) + { +#ifdef CONFIG_SERCOMM_CONSOLE + if (priv->sercomm) + { + sercomm_recvchars(dev); + } + else +#endif + { + uart_recvchars(dev); + } + } + + if ((cause & 0x00000002) != 0) + { +#ifdef CONFIG_SERCOMM_CONSOLE + if (priv->sercomm) + { + sercomm_xmitchars(dev); + } + else +#endif + { + uart_xmitchars(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_disablebreaks(priv); + leave_critical_section(flags); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rhr; + uint32_t lsr; + + /* Construct a 16bit status word that uses the high byte to + * hold the status bits associated with framing,parity,break + * and a low byte that holds error bits of LSR for + * conditions such as overflow, etc. + */ + + rhr = up_inserial(priv, UART_RHR_OFFS); + lsr = up_inserial(priv, UART_LSR_OFFS); + + *status = (unsigned int)((rhr & 0x0000ff00) | (lsr & 0x000000ff)); + + return rhr & 0x000000ff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->regs.ier |= UART_IER_RECVINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +#endif + } + else + { + priv->regs.ier &= ~UART_IER_RECVINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return up_inserial(priv, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_THR_OFFS, (uint8_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->regs.ier |= UART_IER_XMITINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); +#endif + } + else + { + priv->regs.ier &= ~UART_IER_XMITINT; + up_serialout(priv, UART_IER_OFFS, priv->regs.ier); + } +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return (up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return (up_inserial(priv, UART_LSR_OFFS) & UART_LSR_TREF) != 0; +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + up_disableuartint(TTYS0_DEV.priv, NULL); + up_disableuartint(TTYS1_DEV.priv, NULL); + + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONFIG_SERCOMM_CONSOLE + ((struct up_dev_s *)TTYS0_DEV.priv)->sercomm = true; + (void)sercomm_register("/dev/console", &TTYS0_DEV); + (void)uart_register("/dev/ttyS0", &TTYS1_DEV); +#else + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint16_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFS, (uint8_t)ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFS, '\r'); + } + + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + diff --git a/arch/arm/src/calypso/calypso_spi.c b/arch/arm/src/calypso/calypso_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..e3b063a559d671f504750e3bf711c16c479be0ec --- /dev/null +++ b/arch/arm/src/calypso/calypso_spi.c @@ -0,0 +1,314 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_spi.c + * SPI driver for TI Calypso + * + * Copyright (C) 2010 Harald Welte + * Copyright (C) 2011 Stefan Richter + * + * Part of this source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "calypso_spi.h" + +#warning "MOST OF SPI API IS INCOMPLETE! (Wrapper around Osmocom driver)" +extern void spi_init(void); +extern int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din); + +#ifndef CONFIG_SPI_EXCHANGE +#error "Calypso HW only supports exchange. Enable CONFIG_SPI_EXCHANGE!" +#endif + +struct calypso_spidev_s +{ + struct spi_dev_s spidev; /* External driver interface */ + int nbits; /* Number of transfered bits */ + sem_t exclsem; /* Supports mutually exclusive access */ +}; + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + struct calypso_spidev_s *priv = (struct calypso_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/* STUBS! */ + +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ +} + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + return frequency; +} + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ +} + +/* Osmocom wrapper */ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + ((FAR struct calypso_spidev_s *)dev)->nbits = nbits; +} + +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct calypso_spidev_s *priv = (FAR struct calypso_spidev_s *)dev; + size_t i; + + for (i = 0; i < nwords; i++) + { + spi_xfer(0, priv->nbits, txbuffer + i, rxbuffer + i); + } +} + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + uint16_t buf = wd; + spi_exchange(dev, &buf, &buf, 1); + return buf; +} + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, +#endif + .status = 0, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = 0, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, +}; + +static struct calypso_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, + .nbits = 0, + .exclsem = SEM_INITIALIZER(1) +}; + +void spi_init(void) +{ + putreg16(SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | SPI_SET1_RDWR_IRQ_DIS, + SPI_REG(REG_SET1)); + + putreg16(0x0001, SPI_REG(REG_SET2)); +} + +int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din) +{ + uint8_t bytes_per_xfer; + uint8_t reg_status, reg_ctrl = 0; + uint32_t tmp; + + if (bitlen == 0) + { + return 0; + } + + if (bitlen > 32) + { + return -1; + } + + if (dev_idx > 4) + { + return -1; + } + + bytes_per_xfer = bitlen / 8; + if (bitlen % 8) + { + bytes_per_xfer ++; + } + + reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT; + reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT; + + if (bitlen <= 8) + { + tmp = *(uint8_t *)dout; + tmp <<= 24 + (8-bitlen); /* align to MSB */ + } + else if (bitlen <= 16) + { + tmp = *(uint16_t *)dout; + tmp <<= 16 + (16-bitlen); /* align to MSB */ + } + else + { + tmp = *(uint32_t *)dout; + tmp <<= (32-bitlen); /* align to MSB */ + } + + dbg("spi_xfer(dev_idx=%u, bitlen=%u, data_out=0x%08x): ", + dev_idx, bitlen, tmp); + + /* fill transmit registers */ + + putreg16(tmp >> 16, SPI_REG(REG_TX_MSB)); + putreg16(tmp & 0xffff, SPI_REG(REG_TX_LSB)); + + /* initiate transfer */ + + if (din) + { + reg_ctrl |= SPI_CTRL_RDWR; + } + else + { + reg_ctrl |= SPI_CTRL_WR; + } + + putreg16(reg_ctrl, SPI_REG(REG_CTRL)); + dbg("reg_ctrl=0x%04x ", reg_ctrl); + + /* wait until the transfer is complete */ + + while (1) + { + reg_status = getreg16(SPI_REG(REG_STATUS)); + dbg("status=0x%04x ", reg_status); + if (din && (reg_status & SPI_STATUS_RE)) + { + break; + } + else if (reg_status & SPI_STATUS_WE) + { + break; + } + } + + /* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */ + + usleep(1000); + + if (din) + { + tmp = getreg16(SPI_REG(REG_RX_MSB)) << 16; + tmp |= getreg16(SPI_REG(REG_RX_LSB)); + dbg("data_in=0x%08x ", tmp); + + if (bitlen <= 8) + { + *(uint8_t *)din = tmp & 0xff; + } + else if (bitlen <= 16) + { + *(uint16_t *)din = tmp & 0xffff; + } + else + { + *(uint32_t *)din = tmp; + } + } + + dbg("\n"); + + return 0; +} + +/**************************************************************************** + * Name: calypso_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *calypso_spibus_initialize(int port) +{ + switch (port) + { + case 0: /* SPI master device */ + spi_init(); + return (FAR struct spi_dev_s *)&g_spidev; + + case 1: /* uWire device */ + return NULL; + + default: + return NULL; + } +} diff --git a/arch/arm/src/calypso/calypso_spi.h b/arch/arm/src/calypso/calypso_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..70ca2ad9d0a826788a96d1af5d70865b142801b3 --- /dev/null +++ b/arch/arm/src/calypso/calypso_spi.h @@ -0,0 +1,59 @@ +#ifndef ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H +#define ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BASE_ADDR_SPI 0xfffe3000 +#define SPI_REG(n) (BASE_ADDR_SPI+(n)) + +#define SPI_SET1_EN_CLK (1 << 0) +#define SPI_SET1_WR_IRQ_DIS (1 << 4) +#define SPI_SET1_RDWR_IRQ_DIS (1 << 5) + +#define SPI_CTRL_RDWR (1 << 0) +#define SPI_CTRL_WR (1 << 1) +#define SPI_CTRL_NB_SHIFT 2 +#define SPI_CTRL_AD_SHIFT 7 + +#define SPI_STATUS_RE (1 << 0) /* Read End */ +#define SPI_STATUS_WE (1 << 1) /* Write End */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum spi_regs +{ + REG_SET1 = 0x00, + REG_SET2 = 0x02, + REG_CTRL = 0x04, + REG_STATUS = 0x06, + REG_TX_LSB = 0x08, + REG_TX_MSB = 0x0a, + REG_RX_LSB = 0x0c, + REG_RX_MSB = 0x0e, +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: calypso_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *calypso_spibus_initialize(int port); + +#endif /* ___ARCH_ARM_SRC_CALYPSO_CALYPSO_SPI_H */ diff --git a/arch/arm/src/calypso/calypso_timer.c b/arch/arm/src/calypso/calypso_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..86626c5de64944b6b6c854b9445965517e0e4c95 --- /dev/null +++ b/arch/arm/src/calypso/calypso_timer.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_timer.c + * Calypso DBB internal Timer Driver + * + * (C) 2010 by Harald Welte + * (C) 2011 by Stefan Richter + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#define BASE_ADDR_TIMER 0xfffe3800 +#define TIMER2_OFFSET 0x3000 + +#define TIMER_REG(n, m) (((n)-1) ? (BASE_ADDR_TIMER + TIMER2_OFFSET + (m)) : (BASE_ADDR_TIMER + (m))) + +enum timer_reg +{ + CNTL_TIMER = 0x00, + LOAD_TIMER = 0x02, + READ_TIMER = 0x04, +}; + +enum timer_ctl +{ + CNTL_START = (1 << 0), + CNTL_AUTO_RELOAD = (1 << 1), + CNTL_CLOCK_ENABLE = (1 << 5), +}; + +/* Regular Timers (1 and 2) */ + +void hwtimer_enable(int num, int on) +{ + uint8_t ctl; + + if (num < 1 || num > 2) + { + printf("Unknown timer %d\n", num); + return; + } + + ctl = getreg8(TIMER_REG(num, CNTL_TIMER)); + if (on) + { + ctl |= CNTL_START | CNTL_CLOCK_ENABLE; + } + else + { + ctl &= ~CNTL_START; + } + + putreg8(ctl, TIMER_REG(num, CNTL_TIMER)); +} + +void hwtimer_config(int num, uint8_t pre_scale, int auto_reload) +{ + uint8_t ctl; + + ctl = (pre_scale & 0x7) << 2; + if (auto_reload) + ctl |= CNTL_AUTO_RELOAD; + + putreg8(ctl, TIMER_REG(num, CNTL_TIMER)); +} + +void hwtimer_load(int num, uint16_t val) +{ + putreg16(val, TIMER_REG(num, LOAD_TIMER)); +} + +uint16_t hwtimer_read(int num) +{ + uint8_t ctl = getreg8(TIMER_REG(num, CNTL_TIMER)); + + /* Somehow a read results in an abort */ + + if ((ctl & (CNTL_START | CNTL_CLOCK_ENABLE)) != (CNTL_START | CNTL_CLOCK_ENABLE)) + { + return 0xffff; + } + + return getreg16(TIMER_REG(num, READ_TIMER)); +} + +/**************************************************************************** + * Watchdog Timer + ****************************************************************************/ + +#define BASE_ADDR_WDOG 0xfffff800 +#define WDOG_REG(m) (BASE_ADDR_WDOG + m) + +enum wdog_reg +{ + WD_CNTL_TIMER = CNTL_TIMER, + WD_LOAD_TIMER = LOAD_TIMER, + WD_READ_TIMER = 0x02, + WD_MODE = 0x04, +}; + +enum wdog_ctl +{ + WD_CTL_START = (1 << 7), + WD_CTL_AUTO_RELOAD = (1 << 8) +}; + +enum wdog_mode +{ + WD_MODE_DIS_ARM = 0xF5, + WD_MODE_DIS_CONFIRM = 0xA0, + WD_MODE_ENABLE = (1 << 15) +}; + +#define WD_CTL_PRESCALE(value) (((value)&0x07) << 9) + +static void wdog_irq(__unused enum irq_nr nr) +{ + puts("=> WATCHDOG\n"); +} + +void wdog_enable(int on) +{ + if (!on) + { + putreg16(WD_MODE_DIS_ARM, WDOG_REG(WD_MODE)); + putreg16(WD_MODE_DIS_CONFIRM, WDOG_REG(WD_MODE)); + } +} + +void wdog_reset(void) +{ + /* Enable watchdog */ + + putreg16(WD_MODE_ENABLE, WDOG_REG(WD_MODE)); + + /* Force expiration */ + + putreg16(0x0000, WDOG_REG(WD_LOAD_TIMER)); + putreg16(0x0000, WDOG_REG(WD_LOAD_TIMER)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for + * various portions of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * Setup Calypso HW timer 2 to cause system ticks. + * + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + up_disable_irq(IRQ_SYSTIMER); + + /* The timer runs at 13MHz / 32, i.e. 406.25kHz */ + /* 4062 ticks until expiry yields 100Hz interrupt */ + + hwtimer_load(2, 4062); + hwtimer_config(2, 0, 1); + hwtimer_enable(2, 1); + + /* Attach and enable the timer interrupt */ + + irq_attach(IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(IRQ_SYSTIMER); +} diff --git a/arch/arm/src/calypso/calypso_uwire.c b/arch/arm/src/calypso/calypso_uwire.c new file mode 100644 index 0000000000000000000000000000000000000000..d837a7abdc249ac67c300fcfe566aa575c28f6ac --- /dev/null +++ b/arch/arm/src/calypso/calypso_uwire.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_uwire.c + * Driver for Calypso uWire Master Controller + * + * (C) 2010 by Sylvain Munaut + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "up_arch.h" + +#define BASE_ADDR_UWIRE 0xfffe4000 +#define UWIRE_REG(n) (BASE_ADDR_UWIRE+(n)) + +enum uwire_regs +{ + REG_DATA = 0x00, + REG_CSR = 0x02, + REG_SR1 = 0x04, + REG_SR2 = 0x06, + REG_SR3 = 0x08, +}; + +#define UWIRE_CSR_BITS_RD(n) (((n) & 0x1f) << 0) +#define UWIRE_CSR_BITS_WR(n) (((n) & 0x1f) << 5) +#define UWIRE_CSR_IDX(n) (((n) & 3) << 10) +#define UWIRE_CSR_CS_CMD (1 << 12) +#define UWIRE_CSR_START (1 << 13) +#define UWIRE_CSR_CSRB (1 << 14) +#define UWIRE_CSR_RDRB (1 << 15) + +#define UWIRE_CSn_EDGE_RD (1 << 0) /* 1=falling 0=rising */ +#define UWIRE_CSn_EDGE_WR (1 << 1) /* 1=falling 0=rising */ +#define UWIRE_CSn_CS_LVL (1 << 2) +#define UWIRE_CSn_FRQ_DIV2 (0 << 3) +#define UWIRE_CSn_FRQ_DIV4 (1 << 3) +#define UWIRE_CSn_FRQ_DIV8 (2 << 3) +#define UWIRE_CSn_CKH + +#define UWIRE_CSn_SHIFT(n) (((n) & 1) ? 6 : 0) +#define UWIRE_CSn_REG(n) (((n) & 2) ? REG_SR2 : REG_SR1) + +#define UWIRE_SR3_CLK_EN (1 << 0) +#define UWIRE_SR3_CLK_DIV2 (0 << 1) +#define UWIRE_SR3_CLK_DIV4 (1 << 1) +#define UWIRE_SR3_CLK_DIV7 (2 << 1) +#define UWIRE_SR3_CLK_DIV10 (3 << 1) + +static inline void _uwire_wait(int mask, int val) +{ + while ((getreg16(UWIRE_REG(REG_CSR)) & mask) != val); +} + +void uwire_init(void) +{ + putreg16(UWIRE_SR3_CLK_EN | UWIRE_SR3_CLK_DIV2, UWIRE_REG(REG_SR3)); + + /* FIXME only init CS0 for now */ + + putreg16(((UWIRE_CSn_CS_LVL | UWIRE_CSn_FRQ_DIV2) << UWIRE_CSn_SHIFT(0)), + UWIRE_REG(UWIRE_CSn_REG(0))); + putreg16(UWIRE_CSR_IDX(0) | UWIRE_CSR_CS_CMD, UWIRE_REG(REG_CSR)); + _uwire_wait(UWIRE_CSR_CSRB, 0); +} + +int uwire_xfer(int cs, int bitlen, const void *dout, void *din) +{ + uint16_t tmp = 0; + + if (bitlen <= 0 || bitlen > 16) + return -1; + + if (cs < 0 || cs > 4) + return -1; + + /* FIXME uwire_init always selects CS0 for now */ + + dbg("uwire_xfer(dev_idx=%u, bitlen=%u\n", cs, bitlen); + + /* select the chip */ + + putreg16(UWIRE_CSR_IDX(0) | UWIRE_CSR_CS_CMD, UWIRE_REG(REG_CSR)); + _uwire_wait(UWIRE_CSR_CSRB, 0); + + if (dout) + { + if (bitlen <= 8) + tmp = *(uint8_t *)dout; + else if (bitlen <= 16) + tmp = *(uint16_t *)dout; + + tmp <<= 16 - bitlen; /* align to MSB */ + putreg16(tmp, UWIRE_REG(REG_DATA)); + dbg(", data_out=0x%04hx", tmp); + } + + tmp = (dout ? UWIRE_CSR_BITS_WR(bitlen) : 0) | + (din ? UWIRE_CSR_BITS_RD(bitlen) : 0) | + UWIRE_CSR_START; + putreg16(tmp, UWIRE_REG(REG_CSR)); + _uwire_wait(UWIRE_CSR_CSRB, 0); + + if (din) + { + _uwire_wait(UWIRE_CSR_RDRB, UWIRE_CSR_RDRB); + + tmp = getreg16(UWIRE_REG(REG_DATA)); + dbg(", data_in=0x%08x", tmp); + + if (bitlen <= 8) + *(uint8_t *)din = tmp & 0xff; + else if (bitlen <= 16) + *(uint16_t *)din = tmp & 0xffff; + } + + /* unselect the chip */ + + putreg16(UWIRE_CSR_IDX(0) | 0, UWIRE_REG(REG_CSR)); + _uwire_wait(UWIRE_CSR_CSRB, 0); + + dbg(")\n"); + + return 0; +} diff --git a/arch/arm/src/calypso/chip.h b/arch/arm/src/calypso/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..824fdce8935f609f55780cba31853a8859373972 --- /dev/null +++ b/arch/arm/src/calypso/chip.h @@ -0,0 +1,211 @@ +/**************************************************************************** + * calypso/chip.h + * + * Copyright (C) 2011 Stefan Richter. All rights reserved. + * Author: Stefan Richter + * + * based on: c5471/chip.h + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __CALYPSO_CHIP_H +#define __CALYPSO_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* UARTs ********************************************************************/ + +#define UART_IRDA_BASE 0xffff5000 +#define UART_MODEM_BASE 0xffff5800 +#define UART_UIR 0xffff6000 +#define UARTn_IO_RANGE 0x00000800 + +/* Common UART Registers. Expressed as offsets from the BASE address */ + +#define UART_RHR_OFFS 0x00000000 /* Rcv Holding Register */ +#define UART_THR_OFFS 0x00000000 /* Xmit Holding Register */ +#define UART_FCR_OFFS 0x00000002 /* FIFO Control Register */ +#define UART_RFCR_OFFS 0x00000002 /* Rcv FIFO Control Register */ +#define UART_TFCR_OFFS 0x00000002 /* Xmit FIFO Control Register */ +#define UART_SCR_OFFS 0x00000010 /* Status Control Register */ +#define UART_LCR_OFFS 0x00000003 /* Line Control Register */ +#define UART_LSR_OFFS 0x00000005 /* Line Status Register */ +#define UART_SSR_OFFS 0x00000011 /* Supplementary Status Register */ +#define UART_MCR_OFFS 0x00000004 /* Modem Control Register */ +#define UART_MSR_OFFS 0x00000006 /* Modem Status Register */ +#define UART_IER_OFFS 0x00000001 /* Interrupt Enable Register */ +#define UART_ISR_OFFS 0x00000002 /* Interrupt Status Register */ +#define UART_EFR_OFFS 0x00000002 /* Enhanced Feature Register */ +#define UART_XON1_OFFS 0x00000004 /* XON1 Character Register */ +#define UART_XON2_OFFS 0x00000005 /* XON2 Character Register */ +#define UART_XOFF1_OFFS 0x00000006 /* XOFF1 Character Register */ +#define UART_XOFF2_OFFS 0x00000007 /* XOFF2 Character Register */ +#define UART_SPR_OFFS 0x00000007 /* Scratch-pad Register */ +#define UART_DIV_LOW_OFFS 0x00000000 /* Divisor for baud generation */ +#define UART_DIV_HIGH_OFFS 0x00000001 +#define UART_TCR_OFFS 0x00000006 /* Transmission Control Register */ +#define UART_TLR_OFFS 0x00000007 /* Trigger Level Register */ +#define UART_MDR_OFFS 0x00000008 /* Mode Definition Register */ + +/* UART Settings ************************************************************/ + +/* Miscellaneous UART settings. */ + +#define UART_REGISTER_BITS 8 +#define UART_IRQ_MODEM IRQ_UART_MODEM +#define UART_IRQ_IRDA IRQ_UART_IRDA + +#define UART_RX_FIFO_NOEMPTY 0x00000001 +#define UART_SSR_TXFULL 0x00000001 +#define UART_LSR_TREF 0x00000020 + +#define UART_XMIT_FIFO_SIZE 64 +#define UART_IRDA_XMIT_FIFO_SIZE 64 + +/* UART_LCR Register */ + /* Bits 31-7: Reserved */ +#define UART_LCR_BOC 0x00000040 /* Bit 6: Break Control */ + /* Bit 5: Parity Type 2 */ +#define UART_LCR_PAREVEN 0x00000010 /* Bit 4: Parity Type 1 */ +#define UART_LCR_PARODD 0x00000000 +#define UART_LCR_PARMARK 0x00000010 +#define UART_LCR_PARSPACE 0x00000011 +#define UART_LCR_PAREN 0x00000008 /* Bit 3: Paity Enable */ +#define UART_LCR_PARDIS 0x00000000 +#define UART_LCR_2STOP 0x00000004 /* Bit 2: Number of stop bits */ +#define UART_LCR_1STOP 0x00000000 +#define UART_LCR_5BITS 0x00000000 /* Bits 0-1: Word-length */ +#define UART_LCR_6BITS 0x00000001 +#define UART_LCR_7BITS 0x00000002 +#define UART_LCR_8BITS 0x00000003 + +#define UART_FCR_FTL 0x000000f0 +#define UART_FCR_FIFO_EN 0x00000001 +#define UART_FCR_TX_CLR 0x00000002 +#define UART_FCR_RX_CLR 0x00000004 + +#define UART_IER_RECVINT 0x00000001 +#define UART_IER_XMITINT 0x00000002 +#define UART_IER_LINESTSINT 0x00000004 +#define UART_IER_MODEMSTSINT 0x00000008 /* IrDA UART only */ +#define UART_IER_XOFFINT 0x00000020 +#define UART_IER_RTSINT 0x00000040 /* IrDA UART only */ +#define UART_IER_CTSINT 0x00000080 /* IrDA UART only */ +#define UART_IER_INTMASK 0x000000ff + +#define BAUD_115200 0x00000007 +#define BAUD_57600 0x00000014 +#define BAUD_38400 0x00000021 +#define BAUD_19200 0x00000006 +#define BAUD_9600 0x0000000C +#define BAUD_4800 0x00000018 +#define BAUD_2400 0x00000030 +#define BAUD_1200 0x00000060 + +#define MDR_UART_MODE 0x00000000 /* Both IrDA and Modem UARTs */ +#define MDR_SIR_MODE 0x00000001 /* IrDA UART only */ +#define MDR_AUTOBAUDING_MODE 0x00000002 /* Modem UART only */ +#define MDR_RESET_MODE 0x00000007 /* Both IrDA and Modem UARTs */ + +/* SPI **********************************************************************/ + +#define MAX_SPI 3 + +#define SPI_REGISTER_BASE 0xffff2000 + +/* ARMIO ********************************************************************/ +/* Timers / Watchdog ********************************************************/ + +#define C5471_TIMER0_CTRL 0xffff2a00 +#define C5471_TIMER0_CNT 0xffff2a04 +#define C5471_TIMER1_CTRL 0xffff2b00 +#define C5471_TIMER1_CNT 0xffff2b04 +#define C5471_TIMER2_CTRL 0xffff2c00 +#define C5471_TIMER2_CNT 0xffff2c04 + +/* Interrupts ***************************************************************/ + +#define HAVE_SRC_IRQ_BIN_REG 0 + +#define INT_FIRST_IO 0xffff2d00 +#define INT_IO_RANGE 0x5C + +#define IT_REG 0xffff2d00 +#define MASK_IT_REG 0xffff2d04 +#define SRC_IRQ_REG 0xffff2d08 +#define SRC_FIQ_REG 0xffff2d0c +#define SRC_IRQ_BIN_REG 0xffff2d10 +#define INT_CTRL_REG 0xffff2d18 + +#define ILR_IRQ0_REG 0xffff2d1C /* 0-Timer 0 */ +#define ILR_IRQ1_REG 0xffff2d20 /* 1-Timer 1 */ +#define ILR_IRQ2_REG 0xffff2d24 /* 2-Timer 2 */ +#define ILR_IRQ3_REG 0xffff2d28 /* 3-GPIO0 */ +#define ILR_IRQ4_REG 0xffff2d2c /* 4-Ethernet */ +#define ILR_IRQ5_REG 0xffff2d30 /* 5-KBGPIO[7:0] */ +#define ILR_IRQ6_REG 0xffff2d34 /* 6-Uart serial */ +#define ILR_IRQ7_REG 0xffff2d38 /* 7-Uart IRDA */ +#define ILR_IRQ8_REG 0xffff2d3c /* 8-KBGPIO[15:8] */ +#define ILR_IRQ9_REG 0xffff2d40 /* 9-GPIO3 */ +#define ILR_IRQ10_REG 0xffff2d44 /* 10-GPIO2 */ +#define ILR_IRQ11_REG 0xffff2d48 /* 11-I2C */ +#define ILR_IRQ12_REG 0xffff2d4c /* 12-GPIO1 */ +#define ILR_IRQ13_REG 0xffff2d50 /* 13-SPI */ +#define ILR_IRQ14_REG 0xffff2d54 /* 14-GPIO[19:4] */ +#define ILR_IRQ15_REG 0xffff2d58 /* 15-API */ + +/* CLKM *********************************************************************/ + +#define CLKM 0xffff2f00 +#define CLKM_CTL_RST 0xffff2f10 +#define CLKM_RESET 0xffff2f18 + +#define CLKM_RESET_EIM 0x00000008 +#define CLKM_EIM_CLK_STOP 0x00000010 +#define CLKM_CTL_RST_LEAD_RESET 0x00000000 +#define CLKM_CTL_RST_EXT_RESET 0x00000002 + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __CALYPSO_CHIP_H */ diff --git a/arch/arm/src/calypso/clock.c b/arch/arm/src/calypso/clock.c new file mode 100644 index 0000000000000000000000000000000000000000..29dc2f8273ad66a264a3eccac1ada2c809c5b1ac --- /dev/null +++ b/arch/arm/src/calypso/clock.c @@ -0,0 +1,230 @@ +/**************************************************************************** + * arch/arm/src/calypso/clock.c + * Driver for Calypso clock management + * + * (C) 2010 by Harald Welte + * + * This source code is derivated from Osmocom-BB project and was + * relicensed as BSD with permission from original authors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include +#include + +//#define DEBUG +#include + +#include +#include + +#include "up_arch.h" + +#define REG_DPLL 0xffff9800 +#define DPLL_LOCK (1 << 0) +#define DPLL_BREAKLN (1 << 1) +#define DPLL_BYPASS_DIV_SHIFT 2 /* 2 bits */ +#define DPLL_PLL_ENABLE (1 << 4) +#define DPLL_PLL_DIV_SHIFT 5 /* 2 bits */ +#define DPLL_PLL_MULT_SHIFT 7 /* 5 bits */ +#define DPLL_TEST (1 << 12) +#define DPLL_IOB (1 << 13) /* Initialize on break */ +#define DPLL_IAI (1 << 14) /* Initialize after Idle */ + +#define BASE_ADDR_CLKM 0xfffffd00 +#define CLKM_REG(m) (BASE_ADDR_CLKM+(m)) + +enum clkm_reg +{ + CNTL_ARM_CLK = 0, + CNTL_CLK = 2, + CNTL_RST = 4, + CNTL_ARM_DIV = 8, +}; + +/* CNTL_ARM_CLK */ + +#define ARM_CLK_BIG_SLEEP (1 << 0) /* MCU Master Clock enabled? */ +#define ARM_CLK_CLKIN_SEL0 (1 << 1) /* MCU source clock (0 = DPLL output, 1 = VTCXO or CLKIN */ +#define ARM_CLK_CLKIN_SEL (1 << 2) /* 0 = VTCXO or 1 = CLKIN */ +#define ARM_CLK_MCLK_DIV5 (1 << 3) /* enable 1.5 or 2.5 division factor */ +#define ARM_CLK_MCLK_DIV_SHIFT 4 /* 3 bits */ +#define ARM_CLK_DEEP_POWER_SHIFT 8 +#define ARM_CLK_DEEP_SLEEP 12 + +/* CNTL_CLK */ +#define CLK_IRQ_CLK_DIS (1 << 0) /* IRQ clock control (0 always, 1 according ARM_MCLK_EN) */ +#define CLK_BRIDGE_CLK_DIS (1 << 1) +#define CLK_TIMER_CLK_DIS (1 << 2) +#define CLK_DPLL_DIS (1 << 3) /* 0: DPLL is not stopped during SLEEP */ +#define CLK_CLKOUT_EN (1 << 4) /* Enable CLKOUT output pins */ +#define CLK_EN_IDLE3_FLG (1 << 5) /* DSP idle flag control (1 = + * SAM/HOM register forced to HOM when DSP IDLE3) */ +#define CLK_VCLKOUT_DIV2 (1 << 6) /* 1: VCLKOUT-FR is divided by 2 */ +#define CLK_VTCXO_DIV2 (1 << 7) /* 1: VTCXO is dividied by 2 */ + +#define BASE_ADDR_MEMIF 0xfffffb00 +#define MEMIF_REG(x) (BASE_ADDR_MEMIF+(x)) + +enum memif_reg +{ + API_RHEA_CTL = 0x0e, + EXTRA_CONF = 0x10, +}; + +static void dump_reg16(uint32_t addr, char *name) +{ + printf("%s=0x%04x\n", name, getreg16(addr)); +} + +void calypso_clk_dump(void) +{ + dump_reg16(REG_DPLL, "REG_DPLL"); + dump_reg16(CLKM_REG(CNTL_ARM_CLK), "CNTL_ARM_CLK"); + dump_reg16(CLKM_REG(CNTL_CLK), "CNTL_CLK"); + dump_reg16(CLKM_REG(CNTL_RST), "CNTL_RST"); + dump_reg16(CLKM_REG(CNTL_ARM_DIV), "CNTL_ARM_DIV"); +} + +void calypso_pll_set(uint16_t inp) +{ + uint8_t mult = inp >> 8; + uint8_t div = inp & 0xff; + uint16_t reg = getreg16(REG_DPLL); + + reg &= ~0x0fe0; + reg |= (div & 0x3) << DPLL_PLL_DIV_SHIFT; + reg |= (mult & 0x1f) << DPLL_PLL_MULT_SHIFT; + reg |= DPLL_PLL_ENABLE; + + putreg16(reg, REG_DPLL); +} + +void calypso_reset_set(enum calypso_rst calypso_rst, int active) +{ + uint8_t reg = getreg8(CLKM_REG(CNTL_RST)); + + if (active) + reg |= calypso_rst; + else + reg &= ~calypso_rst; + + putreg8(reg, CLKM_REG(CNTL_RST)); +} + +int calypso_reset_get(enum calypso_rst calypso_rst) +{ + uint8_t reg = getreg8(CLKM_REG(CNTL_RST)); + + if (reg & calypso_rst) + return 1; + else + return 0; +} + +void calypso_clock_set(uint8_t vtcxo_div2, uint16_t inp, enum mclk_div mclk_div) +{ + uint16_t cntl_clock = getreg16(CLKM_REG(CNTL_CLK)); + uint16_t cntl_arm_clk = getreg16(CLKM_REG(CNTL_ARM_CLK)); + + /* First set the vtcxo_div2 */ + + cntl_clock &= ~CLK_VCLKOUT_DIV2; + if (vtcxo_div2) + cntl_clock |= CLK_VTCXO_DIV2; + else + cntl_clock &= ~CLK_VTCXO_DIV2; + + putreg16(cntl_clock, CLKM_REG(CNTL_CLK)); + + /* Then configure the MCLK divider */ + + cntl_arm_clk &= ~ARM_CLK_CLKIN_SEL0; + if (mclk_div & 0x80) + { + mclk_div &= ~0x80; + cntl_arm_clk |= ARM_CLK_MCLK_DIV5; + } + else + cntl_arm_clk &= ~ARM_CLK_MCLK_DIV5; + + cntl_arm_clk &= ~(0x7 << ARM_CLK_MCLK_DIV_SHIFT); + cntl_arm_clk |= (mclk_div << ARM_CLK_MCLK_DIV_SHIFT); + putreg16(cntl_arm_clk, CLKM_REG(CNTL_ARM_CLK)); + + /* Then finally set the PLL */ + + calypso_pll_set(inp); +} + +void calypso_mem_cfg(enum calypso_bank bank, uint8_t ws, + enum calypso_mem_width width, int we) +{ + putreg16((ws & 0x1f) | ((width & 3) << 5) | ((we & 1) << 7), + BASE_ADDR_MEMIF + bank); +} + +void calypso_bootrom(int enable) +{ + uint16_t conf = getreg16(MEMIF_REG(EXTRA_CONF)); + + conf |= (3 << 8); + + if (enable) + conf &= ~(1 << 9); + + putreg16(conf, MEMIF_REG(EXTRA_CONF)); +} + +void calypso_debugunit(int enable) +{ + uint16_t conf = getreg16(MEMIF_REG(EXTRA_CONF)); + + if (enable) + conf &= ~(1 << 11); + else + conf |= (1 << 11); + + putreg16(conf, MEMIF_REG(EXTRA_CONF)); +} + +#define REG_RHEA_CNTL 0xfffff900 +#define REG_API_CNTL 0xfffff902 +#define REG_ARM_RHEA 0xfffff904 + +void calypso_rhea_cfg(uint8_t fac0, uint8_t fac1, uint8_t timeout, + uint8_t ws_h, uint8_t ws_l, uint8_t w_en0, uint8_t w_en1) +{ + putreg16(fac0 | (fac1 << 4) | (timeout << 8), REG_RHEA_CNTL); + putreg16(ws_h | (ws_l << 5), REG_API_CNTL); + putreg16(w_en0 | (w_en1 << 1), REG_ARM_RHEA); +} diff --git a/arch/arm/src/common/arm-elf.h b/arch/arm/src/common/arm-elf.h new file mode 100644 index 0000000000000000000000000000000000000000..fac387b110169dfbf838f29ef29475ad5e71489a --- /dev/null +++ b/arch/arm/src/common/arm-elf.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/arm/src/common/arm-elf.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARM_ELF_H +#define __ARCH_ARM_SRC_ARM_ELF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_ARM_ELF_H */ diff --git a/arch/arm/src/common/up_allocateheap.c b/arch/arm/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..b4aa3d05d000bd2999f9e8550f2eb742309c9d82 --- /dev/null +++ b/arch/arm/src/common/up_allocateheap.c @@ -0,0 +1,187 @@ +/**************************************************************************** + * arch/arm/src/common/up_allocateheap.c + * + * Copyright (C) 2007, 2008, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Terminology. In the flat build (CONFIG_BUILD_FLAT=y), there is only a + * single heap access with the standard allocations (malloc/free). This + * heap is referred to as the user heap. In the protected build + * (CONFIG_BUILD_PROTECTED=y) where an MPU is used to protect a region of + * otherwise flat memory, there will be two allocators: One that allocates + * protected (kernel) memory and one that allocates unprotected (user) + * memory. These are referred to as the kernel and user heaps, + * respectively. + * + * The ARMv7 has no MPU but does have an MMU. With this MMU, it can support + * the kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there + * is one kernel heap but multiple user heaps: One per task group. However, + * in this case, we need only be concerned about initializing the single + * kernel heap here. + */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap/up_allocate_kheap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * - For the normal "flat" build, this function returns the size of the + * single heap. + * - For the protected build (CONFIG_BUILD_PROTECTED=y) with both kernel- + * and user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function + * provides the size of the unprotected, user-space heap. + * - For the kernel build (CONFIG_BUILD_KERNEL=y), this function provides + * the size of the protected, kernel-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated by an analogous up_allocate_kheap(). A custom version of this + * file is needed if memory protection of the kernel heap is required. + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +#else +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +#endif +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED/KERNEL=y) with both kernel- + * and user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * the kernel-space heap. A custom version of this function is needed if + * memory protection of the kernel heap is required. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif diff --git a/arch/arm/src/common/up_arch.h b/arch/arm/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..fc6981efb6ff5636a094bf0572ffb1a28e8e4126 --- /dev/null +++ b/arch/arm/src/common/up_arch.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/arm/src/common/up_arch.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_ARM_SRC_COMMON_UP_ARCH_H +#define ___ARCH_ARM_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(a) (*(volatile uint8_t *)(a)) +# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +# define getreg32(a) (*(volatile uint32_t *)(a)) +# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +/* Some compiler options will convert short loads and stores into byte loads + * and stores. We don't want this to happen for IO reads and writes! + */ + +/* # define getreg16(a) (*(volatile uint16_t *)(a)) */ +static inline uint16_t getreg16(unsigned int addr) +{ + uint16_t retval; + __asm__ __volatile__("\tldrh %0, [%1]\n\t" : "=r"(retval) : "r"(addr)); + return retval; +} + +/* define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) */ +static inline void putreg16(uint16_t val, unsigned int addr) +{ + __asm__ __volatile__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr)); +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Atomic modification of registers */ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* ___ARCH_ARM_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/arm/src/common/up_checkstack.c b/arch/arm/src/common/up_checkstack.c new file mode 100644 index 0000000000000000000000000000000000000000..55f89388e3ee983d72ce5ccabdf23acb71677733 --- /dev/null +++ b/arch/arm/src/common/up_checkstack.c @@ -0,0 +1,207 @@ +/**************************************************************************** + * arch/arm/src/common/up_checkstack.c + * + * Copyright (C) 2011, 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_STACK_COLORATION + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static size_t do_stackcheck(uintptr_t alloc, size_t size); + +/**************************************************************************** + * Name: do_stackcheck + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * alloc - Allocation base address of the stack + * size - The size of the stack in bytes + * + * Returned value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +static size_t do_stackcheck(uintptr_t alloc, size_t size) +{ + FAR uintptr_t start; + FAR uintptr_t end; + FAR uint32_t *ptr; + size_t mark; + + /* Get aligned addresses of the top and bottom of the stack */ +#ifdef CONFIG_TLS + /* Skip over the TLS data structure at the bottom of the stack */ + + DEBUGASSERT((alloc & TLS_STACK_MASK) == 0); + start = alloc + sizeof(struct tls_info_s); +#else + start = alloc & ~3; +#endif + end = (alloc + size + 3) & ~3; + + /* Get the adjusted size based on the top and bottom of the stack */ + + size = end - start; + + /* The ARM uses a push-down stack: the stack grows toward lower addresses + * in memory. We need to start at the lowest address in the stack memory + * allocation and search to higher addresses. The first word we encounter + * that does not have the magic value is the high water mark. + */ + + for (ptr = (FAR uint32_t *)start, mark = (size >> 2); + *ptr == STACK_COLOR && mark > 0; + ptr++, mark--); + + /* If the stack is completely used, then this might mean that the stack + * overflowed from above (meaning that the stack is too small), or may + * have been overwritten from below meaning that some other stack or data + * structure overflowed. + * + * If you see returned values saying that the entire stack is being used + * then enable the following logic to see it there are unused areas in the + * middle of the stack. + */ + +#if 0 + if (mark + 16 > nwords) + { + int i, j; + + ptr = (FAR uint32_t *)start; + for (i = 0; i < size; i += 4*64) + { + for (j = 0; j < 64; j++) + { + int ch; + if (*ptr++ == STACK_COLOR) + { + ch = '.'; + } + else + { + ch = 'X'; + } + + up_putc(ch); + } + + up_putc('\n'); + } + } +#endif + + /* Return our guess about how much stack space was used */ + + return mark << 2; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_check_stack and friends + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * None + * + * Returned value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +size_t up_check_tcbstack(FAR struct tcb_s *tcb) +{ + return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size); +} + +ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) +{ + return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); +} + +size_t up_check_stack(void) +{ + return up_check_tcbstack(this_task()); +} + +ssize_t up_check_stack_remain(void) +{ + return up_check_tcbstack_remain(this_task()); +} + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +size_t up_check_intstack(void) +{ + return do_stackcheck((uintptr_t)&g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)); +} + +size_t up_check_intstack_remain(void) +{ + return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack(); +} +#endif + +#endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/arm/src/common/up_createstack.c b/arch/arm/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..12d4575e3dd818a6cdfce2116d31d0a0a05eefc1 --- /dev/null +++ b/arch/arm/src/common/up_createstack.c @@ -0,0 +1,315 @@ +/**************************************************************************** + * arch/arm/src/common/up_createstack.c + * + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ +/* Configuration */ + +#undef HAVE_KERNEL_HEAP +#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ + defined(CONFIG_MM_KERNEL_HEAP) +# define HAVE_KERNEL_HEAP 1 +#endif + +/* ARM requires at least a 4-byte stack alignment. For use with EABI and + * floating point, the stack must be aligned to 8-byte addresses. + */ + +#ifndef CONFIG_STACK_ALIGNMENT + +/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you + * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly! + */ + +# ifdef __ARM_EABI__ +# define CONFIG_STACK_ALIGNMENT 8 +# else +# define CONFIG_STACK_ALIGNMENT 4 +# endif +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If either CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are defined, + * then this thread type may affect how the stack is allocated. For + * example, kernel thread stacks should be allocated from protected + * kernel memory. Stacks for user tasks and threads must come from + * memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif + + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + * If TLS is enabled, then we must allocate aligned stacks. + */ + +#ifdef CONFIG_TLS +#ifdef HAVE_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS */ +#ifdef HAVE_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } +#endif /* CONFIG_TLS */ + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { +#if defined(CONFIG_TLS) && defined(CONFIG_STACK_COLORATION) + uinptr_t stack_base; +#endif + size_t top_of_stack; + size_t size_of_stack; + + /* The ARM uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to + * the lowest, valid work address (the "top" of the stack). Items + * on the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The ARM stack must be aligned; 4 byte alignment for OABI and + * 8-byte alignment for EABI. If necessary top_of_stack must be + * rounded down to the next boundary + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + + /* The size of the stack in bytes is then the difference between + * the top and the bottom of the stack (+4 because if the top + * is the same as the bottom, then the size is one 32-bit element). + * The size need not be aligned. + */ + + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); + +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + stackbase = (uintptr_t)tcb->stack_alloc_ptr + sizeof(struct tls_info_s); + stack_size = tcb->adj_stack_size - sizeof(struct tls_info_s); + up_stack_color((FAR void *)stack_base, stack_size); + +#endif /* CONFIG_STACK_COLORATION */ +#else /* CONFIG_TLS */ +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size); + +#endif /* CONFIG_STACK_COLORATION */ +#endif /* CONFIG_TLS */ + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} + +/**************************************************************************** + * Name: up_stack_color + * + * Description: + * Write a well know value into the stack + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +void up_stack_color(FAR void *stackbase, size_t nbytes) +{ + /* Take extra care that we do not write outsize the stack boundaries */ + + uint32_t *stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); + uintptr_t stkend = (((uintptr_t)stackbase + nbytes) & ~3); + size_t nwords = (stkend - (uintptr_t)stackbase) >> 2; + + /* Set the entire stack to the coloration value */ + + while (nwords-- > 0) + { + *stkptr++ = STACK_COLOR; + } +} +#endif diff --git a/arch/arm/src/common/up_etherstub.c b/arch/arm/src/common/up_etherstub.c new file mode 100644 index 0000000000000000000000000000000000000000..e0fd1800cfcf303546538b7b08a114f4b0c617c3 --- /dev/null +++ b/arch/arm/src/common/up_etherstub.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/common/up_etherstub.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_netinitialize (stub) + * + * Description: + * This is a stub version os up_netinitialize. Normally, up_netinitialize + * is defined in board/xyz_network.c for board-specific Ethernet + * implementations, or chip/xyx_ethernet.c for chip-specific Ethernet + * implementations. The stub version here is used in the corner case where + * the network is enable yet there is no Ethernet driver to be initialized. + * In this case, up_initialize will still try to call up_netinitialize() + * when one does not exist. This corner case would occur if, for example, + * only a USB network interface is being used or perhaps if a SLIP is + * being used). + * + * Use of this stub is deprecated. The preferred mechanism is to use + * CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in + * up_initialize(). Then this stub would not be needed. + * + ****************************************************************************/ + +void up_netinitialize(void) +{ +} diff --git a/arch/arm/src/common/up_exit.c b/arch/arm/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..57137a60def127946b8ed5079c442e2433bd85d6 --- /dev/null +++ b/arch/arm/src/common/up_exit.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * common/up_exit.c + * + * Copyright (C) 2007-2009, 201-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s *tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} + diff --git a/arch/arm/src/common/up_idle.c b/arch/arm/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..c6725a98d6307aa29bb809c3fe3b053ca03c49d8 --- /dev/null +++ b/arch/arm/src/common/up_idle.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/common/up_idle.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Sleep until an interrupt occurs to save power */ + +#if 0 + asm("WFI"); /* For example */ +#endif +#endif +} + diff --git a/arch/arm/src/common/up_initialize.c b/arch/arm/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..511138e4f51640de6328d0d1019d6241ca2c2898 --- /dev/null +++ b/arch/arm/src/common/up_initialize.c @@ -0,0 +1,290 @@ +/**************************************************************************** + * arch/arm/src/common/up_initialize.c + * + * Copyright (C) 2007-2010, 2012-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Name: up_color_intstack + * + * Description: + * Set the interrupt stack to a value so that later we can determine how + * much stack space was used by interrupt handling logic + * + ****************************************************************************/ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 +static inline void up_color_intstack(void) +{ + uint32_t *ptr = (uint32_t *)&g_intstackalloc; + ssize_t size; + + for (size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + size > 0; + size -= sizeof(uint32_t)) + { + *ptr++ = INTSTACK_COLOR; + } +} +#else +# define up_color_intstack() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + CURRENT_REGS = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Colorize the interrupt stack */ + + up_color_intstack(); + + /* Add any extra memory fragments to the memory manager */ + + up_addregion(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the power management subsystem. This MCU-specific function + * must be called *very* early in the initialization sequence *before* any + * other device drivers are initialized (since they may attempt to register + * with the power management subsystem). + */ + +#ifdef CONFIG_PM + up_pminitialize(); +#endif + + /* Initialize the DMA subsystem if the weak function up_dmainitialize has been + * brought into the build + */ + +#ifdef CONFIG_ARCH_DMA +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_dmainitialize) +#endif + { + up_dmainitialize(); + } +#endif + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) && \ + !defined(CONFIG_SYSTEMTICK_EXTCLK) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the HW crypto and /dev/crypto */ + +#if defined(CONFIG_CRYPTO) + up_cryptoinitialize(); +#endif + +#if CONFIG_NFILE_DESCRIPTORS > 0 +#if defined(CONFIG_CRYPTO_CRYPTODEV) + devcrypto_register(); +#endif +#endif + + /* Initialize the Random Number Generator (RNG) */ + +#ifdef CONFIG_DEV_RANDOM + up_rnginitialize(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB -- device and/or host */ + + up_usbinitialize(); + + /* Initialize the L2 cache if present and selected */ + + up_l2ccinitialize(); + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..0e8650c76cd86f451c9c043320e1a9780d0cee72 --- /dev/null +++ b/arch/arm/src/common/up_internal.h @@ -0,0 +1,568 @@ +/**************************************************************************** + * common/up_internal.h + * + * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_COMMON_UP_INTERNAL_H +#define __ARCH_ARM_SRC_COMMON_UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS == 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/* Macros to handle saving and restoring interrupt state. In the current ARM + * model, the state is always copied to and from the stack and TCB. In the + * Cortex-M0/3 model, the state is copied from the stack to the TCB, but only + * a referenced is passed to get the state from the TCB. Cortex-M4 is the + * same, but may have additional complexity for floating point support in + * some configurations. + */ + +#if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \ + defined(CONFIG_ARCH_CORTEXM4) || defined(CONFIG_ARCH_CORTEXM7) + + /* If the floating point unit is present and enabled, then save the + * floating point registers as well as normal ARM registers. This only + * applies if "lazy" floating point register save/restore is used + * (i.e., not CONFIG_ARMV7M_CMNVECTOR=y with CONFIG_ARMV7M_LAZYFPU=n). + */ + +# if defined(CONFIG_ARCH_FPU) && (!defined(CONFIG_ARMV7M_CMNVECTOR) || \ + defined(CONFIG_ARMV7M_LAZYFPU)) +# define up_savestate(regs) up_copyarmstate(regs, (uint32_t*)CURRENT_REGS) +# else +# define up_savestate(regs) up_copyfullstate(regs, (uint32_t*)CURRENT_REGS) +# endif +# define up_restorestate(regs) (CURRENT_REGS = regs) + +/* The Cortex-A and Cortex-R supports the same mechanism, but only lazy + * floating point register save/restore. + */ + +#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXA9) || \ + defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) + + /* If the floating point unit is present and enabled, then save the + * floating point registers as well as normal ARM registers. + */ + +# if defined(CONFIG_ARCH_FPU) +# define up_savestate(regs) up_copyarmstate(regs, (uint32_t*)CURRENT_REGS) +# else +# define up_savestate(regs) up_copyfullstate(regs, (uint32_t*)CURRENT_REGS) +# endif +# define up_restorestate(regs) (CURRENT_REGS = regs) + +/* Otherwise, for the ARM7 and ARM9. The state is copied in full from stack + * to stack. This is not very efficient and should be fixed to match Cortex-A5. + */ + +#else + + /* If the floating point unit is present and enabled, then save the + * floating point registers as well as normal ARM registers. Only "lazy" + * floating point save/restore is supported. + */ + +# if defined(CONFIG_ARCH_FPU) +# define up_savestate(regs) up_copyarmstate(regs, (uint32_t*)CURRENT_REGS) +# else +# define up_savestate(regs) up_copyfullstate(regs, (uint32_t*)CURRENT_REGS) +# endif +# define up_restorestate(regs) up_copyfullstate((uint32_t*)CURRENT_REGS, regs) + +#endif + +/* Toolchain dependent, linker defined section addresses */ + +#if defined(__ICCARM__) +# define _START_TEXT __sfb(".text") +# define _END_TEXT __sfe(".text") +# define _START_BSS __sfb(".bss") +# define _END_BSS __sfe(".bss") +# define _DATA_INIT __sfb(".data_init") +# define _START_DATA __sfb(".data") +# define _END_DATA __sfe(".data") +#else +# define _START_TEXT &_stext +# define _END_TEXT &_etext +# define _START_BSS &_sbss +# define _END_BSS &_ebss +# define _DATA_INIT &_eronly +# define _START_DATA &_sdata +# define _END_DATA &_edata +#endif + +/* This is the value used to mark the stack for subsequent stack monitoring + * logic. + */ + +#define STACK_COLOR 0xdeadbeef +#define INTSTACK_COLOR 0xdeadbeef +#define HEAP_COLOR 'h' + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +#ifdef CONFIG_SMP +/* For the case of architectures with multiple CPUs, then there must be one + * such value for each processor that can receive an interrupt. + */ + +int up_cpu_index(void); /* See include/nuttx/arch.h */ +EXTERN volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +# define CURRENT_REGS (g_current_regs[up_cpu_index()]) + +#else + +EXTERN volatile uint32_t *g_current_regs[1]; +# define CURRENT_REGS (g_current_regs[0]) + +#endif + +/* This is the beginning of heap as provided from up_head.S. + * This is the first address in DRAM after the loaded + * program+bss+idle stack. The end of the heap is + * CONFIG_RAM_END + */ + +EXTERN const uint32_t g_idle_topstack; + +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +EXTERN uint32_t g_intstackalloc; /* Allocated stack base */ +EXTERN uint32_t g_intstackbase; /* Initial top of interrupt stack */ +#endif + +/* These 'addresses' of these values are setup by the linker script. They are + * not actual uint32_t storage locations! They are only used meaningfully in the + * following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declareion extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data (it is + * not!). + * - We can recoved the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +EXTERN uint32_t _stext; /* Start of .text */ +EXTERN uint32_t _etext; /* End_1 of .text + .rodata */ +EXTERN const uint32_t _eronly; /* End+1 of read only section (.text + .rodata) */ +EXTERN uint32_t _sdata; /* Start of .data */ +EXTERN uint32_t _edata; /* End+1 of .data */ +EXTERN uint32_t _sbss; /* Start of .bss */ +EXTERN uint32_t _ebss; /* End+1 of .bss */ + +/* Sometimes, functions must be executed from RAM. In this case, the following + * macro may be used (with GCC!) to specify a function that will execute from + * RAM. For example, + * + * int __ramfunc__ foo (void); + * int __ramfunc__ foo (void) { return bar; } + * + * will create a function named foo that will execute from RAM. + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + +# define __ramfunc__ __attribute__ ((section(".ramfunc"),long_call,noinline)) + +/* Functions declared in the .ramfunc section will be packaged together + * by the linker script and stored in FLASH. During boot-up, the start + * logic must include logic to copy the RAM functions from their storage + * location in FLASH to their correct destination in SRAM. The following + * following linker-defined values provide the information to copy the + * functions from flash to RAM. + */ + +EXTERN const uint32_t _framfuncs; /* Copy source address in FLASH */ +EXTERN uint32_t _sramfuncs; /* Copy destination start address in RAM */ +EXTERN uint32_t _eramfuncs; /* Copy destination end address in RAM */ + +#else /* CONFIG_ARCH_RAMFUNCS */ + +/* Otherwise, a null definition is provided so that condition compilation is + * not necessary in code that may operate with or without RAM functions. + */ + +# define __ramfunc__ + +#endif /* CONFIG_ARCH_RAMFUNCS */ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Low level initialization provided by board-level logic ******************/ + +void up_boot(void); + +/* Context switching */ + +void up_copyfullstate(uint32_t *dest, uint32_t *src); +#ifdef CONFIG_ARCH_FPU +void up_copyarmstate(uint32_t *dest, uint32_t *src); +#endif +void up_decodeirq(uint32_t *regs); +int up_saveusercontext(uint32_t *saveregs); +void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; +void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + +/* Signal handling **********************************************************/ + +void up_sigdeliver(void); + +/* Power management *********************************************************/ + +#ifdef CONFIG_PM +void up_pminitialize(void); +#else +# define up_pminitialize() +#endif + +#if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \ + defined(CONFIG_ARCH_CORTEXM4) || defined(CONFIG_ARCH_CORTEXM7) +void up_systemreset(void) noreturn_function; +#endif + +/* Interrupt handling *******************************************************/ + +void up_irqinitialize(void); + +/* Exception handling logic unique to the Cortex-M family */ + +#if defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM3) || \ + defined(CONFIG_ARCH_CORTEXM4) || defined(CONFIG_ARCH_CORTEXM7) + +/* Interrupt acknowledge and dispatch */ + +void up_ack_irq(int irq); +uint32_t *up_doirq(int irq, uint32_t *regs); + +/* Exception Handlers */ + +int up_svcall(int irq, FAR void *context); +int up_hardfault(int irq, FAR void *context); + +# if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ + defined(CONFIG_ARCH_CORTEXM7) + +int up_memfault(int irq, FAR void *context); + +# endif /* CONFIG_ARCH_CORTEXM3,4,7 */ + +/* Exception handling logic unique to the Cortex-A and Cortex-R families +* (but should be back-ported to the ARM7 and ARM9 families). + */ + +#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXA9) || \ + defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) + +/* Interrupt acknowledge and dispatch */ + +uint32_t *arm_doirq(int irq, uint32_t *regs); + +/* Paging support */ + +#ifdef CONFIG_PAGING +void arm_pginitialize(void); +uint32_t *arm_va2pte(uintptr_t vaddr); +#else /* CONFIG_PAGING */ +# define up_pginitialize() +#endif /* CONFIG_PAGING */ + +/* Exception Handlers */ + +uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr); +uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr); +uint32_t *arm_syscall(uint32_t *regs); +uint32_t *arm_undefinedinsn(uint32_t *regs); + +/* Exception handling logic common to other ARM7 and ARM9 family. */ + +#else /* ARM7 | ARM9 */ + +/* Interrupt acknowledge and dispatch */ + +void up_ack_irq(int irq); +void up_doirq(int irq, uint32_t *regs); + +/* Paging support (and exception handlers) */ + +#ifdef CONFIG_PAGING +void up_pginitialize(void); +uint32_t *up_va2pte(uintptr_t vaddr); +void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr); +#else /* CONFIG_PAGING */ +# define up_pginitialize() +void up_dataabort(uint32_t *regs); +#endif /* CONFIG_PAGING */ + +/* Exception handlers */ + +void up_prefetchabort(uint32_t *regs); +void up_syscall(uint32_t *regs); +void up_undefinedinsn(uint32_t *regs); + +#endif /* CONFIG_ARCH_CORTEXM0,3,4,7 */ + +void up_vectorundefinsn(void); +void up_vectorswi(void); +void up_vectorprefetch(void); +void up_vectordata(void); +void up_vectoraddrexcptn(void); +void up_vectorirq(void); +void up_vectorfiq(void); + +/* Floating point unit ******************************************************/ + +#ifdef CONFIG_ARCH_FPU +void up_savefpu(uint32_t *regs); +void up_restorefpu(const uint32_t *regs); +#else +# define up_savefpu(regs) +# define up_restorefpu(regs) +#endif + +/* System timer *************************************************************/ + +void up_timer_initialize(void); +int up_timerisr(int irq, uint32_t *regs); + +/* Low level serial output **************************************************/ + +void up_lowputc(char ch); +void up_puts(const char *str); +void up_lowputs(const char *str); + +#ifdef USE_SERIALDRIVER +void up_serialinit(void); +#else +# define up_serialinit() +#endif + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void); +#else +# define up_earlyserialinit() +#endif + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* DMA **********************************************************************/ + +#ifdef CONFIG_ARCH_DMA +void weak_function up_dmainitialize(void); +#endif + +/* Cache control ************************************************************/ + +#ifdef CONFIG_ARCH_L2CACHE +void up_l2ccinitialize(void); +#else +# define up_l2ccinitialize() +#endif + +/* Memory management ********************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#else +# define up_addregion() +#endif + +/* Watchdog timer ***********************************************************/ + +void up_wdtinit(void); + +/* Networking ***************************************************************/ + +/* Defined in board/xyz_network.c for board-specific Ethernet implementations, + * or chip/xyx_ethernet.c for chip-specific Ethernet implementations, or + * common/up_etherstub.c for a corner case where the network is enabled yet + * there is no Ethernet driver to be initialized. + * + * Use of common/up_etherstub.c is deprecated. The preferred mechanism is to + * use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in + * up_initialize(). Then this stub would not be needed. + */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +/* USB **********************************************************************/ + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +/* Random Number Generator (RNG) ********************************************/ + +#ifdef CONFIG_DEV_RANDOM +void up_rnginitialize(void); +#endif + +/* Debug ********************************************************************/ +#ifdef CONFIG_STACK_COLORATION +void up_stack_color(FAR void *stackbase, size_t nbytes); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/arm/src/common/up_interruptcontext.c b/arch/arm/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..09fd58fa5aea98c70fce207883d5f701f67d92fc --- /dev/null +++ b/arch/arm/src/common/up_interruptcontext.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/arm/src/common/up_interruptcontext.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return CURRENT_REGS != NULL; +} diff --git a/arch/arm/src/common/up_lowputs.c b/arch/arm/src/common/up_lowputs.c new file mode 100644 index 0000000000000000000000000000000000000000..fde555e46a7910904a5d7482de9ed906954f99d2 --- /dev/null +++ b/arch/arm/src/common/up_lowputs.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/arm/src/common/up_lowputs.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} diff --git a/arch/arm/src/common/up_mdelay.c b/arch/arm/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..94285ea3ac627cc3a16505d2010addcbab4da0d2 --- /dev/null +++ b/arch/arm/src/common/up_mdelay.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/common/up_mdelay.c + * + * Copyright (C) 2007, 2008, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile unsigned int i; + volatile unsigned int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/arm/src/common/up_modifyreg16.c b/arch/arm/src/common/up_modifyreg16.c new file mode 100644 index 0000000000000000000000000000000000000000..8871d7f60c0581a2ca8db6a14053df14ac1aa0b0 --- /dev/null +++ b/arch/arm/src/common/up_modifyreg16.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/arm/src/common/up_modifyreg16.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16(addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/arm/src/common/up_modifyreg32.c b/arch/arm/src/common/up_modifyreg32.c new file mode 100644 index 0000000000000000000000000000000000000000..0a1619592b5953dee261b1bdda91cd53f1ad3ec1 --- /dev/null +++ b/arch/arm/src/common/up_modifyreg32.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/arm/src/common/up_modifyreg32.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32(addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/arm/src/common/up_modifyreg8.c b/arch/arm/src/common/up_modifyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..abc4b60885c29a58f58f4df382f4469c821aed32 --- /dev/null +++ b/arch/arm/src/common/up_modifyreg8.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/arm/src/common/up_modifyreg8.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8(addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/arm/src/common/up_pthread_start.c b/arch/arm/src/common/up_pthread_start.c new file mode 100644 index 0000000000000000000000000000000000000000..4b325557a4fc5e70f6c0726a97b40ca70faa0185 --- /dev/null +++ b/arch/arm/src/common/up_pthread_start.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/common/up_pthread_start.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "svcall.h" +#include "up_internal.h" + +#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ + defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_PTHREAD) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_pthread_start + * + * Description: + * In this kernel mode build, this function will be called to execute a + * pthread in user-space. When the pthread is first started, a kernel-mode + * stub will first run to perform some housekeeping functions. This + * kernel-mode stub will then be called transfer control to the user-mode + * pthread. + * + * Normally the a user-mode start-up stub will also execute before the + * pthread actually starts. See libc/pthread/pthread_startup.c + * + * Input Parameters: + * entrypt - The user-space address of the pthread entry point + * arg - Standard argument for the pthread entry point + * + * Returned Value: + * This function should not return. It should call the user-mode start-up + * stub and that stub should call pthread_exit if/when the user pthread + * terminates. + * + ****************************************************************************/ + +void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) +{ + /* Let sys_call2() do all of the work */ + + sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg); +} + +#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */ diff --git a/arch/arm/src/common/up_puts.c b/arch/arm/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..35dc603de086c604f94dfb8b1c27fccd4c8bc5d0 --- /dev/null +++ b/arch/arm/src/common/up_puts.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/common/up_puts.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} + diff --git a/arch/arm/src/common/up_releasestack.c b/arch/arm/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..9be9740a5b5b6f91cbafc41fb596a2a6a7f0fc13 --- /dev/null +++ b/arch/arm/src/common/up_releasestack.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/arm/src/common/up_releasestack.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration */ + +#undef HAVE_KERNEL_HEAP +#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ + defined(CONFIG_MM_KERNEL_HEAP) +# define HAVE_KERNEL_HEAP 1 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If either CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are defined, + * then this thread type may affect how the stack is freed. For example, + * kernel thread stacks may have been allocated from protected kernel + * memory. Stacks for user tasks and threads must have come from memory + * that is accessible to user code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#ifdef HAVE_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/arm/src/common/up_stackframe.c b/arch/arm/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..b5712b2a291494d18d3e128a31fdc1432392e131 --- /dev/null +++ b/arch/arm/src/common/up_stackframe.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * arch/arm/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* ARM requires at least a 4-byte stack alignment. For use with EABI and + * floating point, the stack must be aligned to 8-byte addresses. + */ + +#ifndef CONFIG_STACK_ALIGNMENT + +/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you + * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly! + */ + +# ifdef __ARM_EABI__ +# define CONFIG_STACK_ALIGNMENT 8 +# else +# define CONFIG_STACK_ALIGNMENT 4 +# endif +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} diff --git a/arch/arm/src/common/up_task_start.c b/arch/arm/src/common/up_task_start.c new file mode 100644 index 0000000000000000000000000000000000000000..9c4e7fdf601bf8834f5769aff543c8020ceda936 --- /dev/null +++ b/arch/arm/src/common/up_task_start.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/common/up_task_start.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "svcall.h" +#include "up_internal.h" + +#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_task_start + * + * Description: + * In this kernel mode build, this function will be called to execute a + * task in user-space. When the task is first started, a kernel-mode + * stub will first run to perform some housekeeping functions. This + * kernel-mode stub will then be called transfer control to the user-mode + * task. + * + * Normally the a user-mode start-up stub will also execute before the + * task actually starts. See libc/sched/task_startup.c + * + * Input Parameters: + * taskentry - The user-space entry point of the task. + * argc - The number of parameters being passed. + * argv - The parameters being passed. These lie in kernel-space memory + * and will have to be reallocated in user-space memory. + * + * Returned Value: + * This function should not return. It should call the user-mode start-up + * stub and that stub should call exit if/when the user task terminates. + * + ****************************************************************************/ + +void up_task_start(main_t taskentry, int argc, FAR char *argv[]) +{ + /* Let sys_call3() do all of the work */ + + sys_call3(SYS_task_start, (uintptr_t)taskentry, (uintptr_t)argc, + (uintptr_t)argv); +} + +#endif /* CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL */ diff --git a/arch/arm/src/common/up_udelay.c b/arch/arm/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..e1a19445f041a1cd419c725dce42c7690ff915aa --- /dev/null +++ b/arch/arm/src/common/up_udelay.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/common/up_udelay.c + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + + microseconds--; + } +} diff --git a/arch/arm/src/common/up_usestack.c b/arch/arm/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..5dea96be4e91ea6ed9f680448c8b0e0ed36cefa0 --- /dev/null +++ b/arch/arm/src/common/up_usestack.c @@ -0,0 +1,181 @@ +/**************************************************************************** + * arch/arm/src/common/up_usestack.c + * + * Copyright (C) 2007-2009, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* ARM requires at least a 4-byte stack alignment. For use with EABI and + * floating point, the stack must be aligned to 8-byte addresses. + */ + +#ifndef CONFIG_STACK_ALIGNMENT + +/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you + * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly! + */ + +# ifdef __ARM_EABI__ +# define CONFIG_STACK_ALIGNMENT 8 +# else +# define CONFIG_STACK_ALIGNMENT 4 +# endif +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + +#ifdef CONFIG_TLS + /* Make certain that the user provided stack is properly aligned */ + + DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); +#endif + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes... Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The ARM uses a push-down stack: the stack grows toward lower addresses + * in memory. The stack pointer register, points to the lowest, valid + * work address (the "top" of the stack). Items on the stack are + * referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The ARM stack must be aligned; 4 byte alignment for OABI and 8-byte + * alignment for EABI. If necessary top_of_stack must be rounded down + * to the next boundary + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + + /* The size of the stack in bytes is then the difference between + * the top and the bottom of the stack (+4 because if the top + * is the same as the bottom, then the size is one 32-bit element). + * The size need not be aligned. + */ + + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a recognizable + * value that we can use later to test for high water marks. + */ + +# warning Missing logic +#endif + + return OK; +} diff --git a/arch/arm/src/common/up_vfork.c b/arch/arm/src/common/up_vfork.c new file mode 100644 index 0000000000000000000000000000000000000000..b902ccba7b9f93dcbd8e6f22181f472bd97a5f26 --- /dev/null +++ b/arch/arm/src/common/up_vfork.c @@ -0,0 +1,278 @@ +/**************************************************************************** + * arch/arm/src/common/up_vfork.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_vfork.h" +#include "sched/sched.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ARM requires at least a 4-byte stack alignment. For use with EABI and + * floating point, the stack must be aligned to 8-byte addresses. + */ + +#ifndef CONFIG_STACK_ALIGNMENT + +/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you + * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly! + */ + +# ifdef __ARM_EABI__ +# define CONFIG_STACK_ALIGNMENT 8 +# else +# define CONFIG_STACK_ALIGNMENT 4 +# endif +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the + * behavior is undefined if the process created by vfork() either modifies + * any data other than a variable of type pid_t used to store the return + * value from vfork(), or returns from the function in which vfork() was + * called, or calls any other function before successfully calling _exit() + * or one of the exec family of functions. + * + * The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * task_vforkabort() may be called if an error occurs between steps 3 and 6. + * + * Input Parameters: + * context - Caller context information saved by vfork() + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and + * returns the process ID of the child process to the parent process. + * Otherwise, -1 is returned to the parent, no child process is created, + * and errno is set to indicate the error. + * + ****************************************************************************/ + +pid_t up_vfork(const struct vfork_s *context) +{ + struct tcb_s *parent = this_task(); + struct task_tcb_s *child; + size_t stacksize; + uint32_t newsp; + uint32_t newfp; + uint32_t stackutil; + int ret; + + svdbg("vfork context [%p]:\n", context); + svdbg(" r4:%08x r5:%08x r6:%08x r7:%08x\n", + context->r4, context->r5, context->r6, context->r7); + svdbg(" r8:%08x r9:%08x r10:%08x\n", + context->r8, context->r9, context->r10); + svdbg(" fp:%08x sp:%08x lr:%08x\n", + context->fp, context->sp, context->lr); + + /* Allocate and initialize a TCB for the child task. */ + + child = task_vforksetup((start_t)(context->lr & ~1)); + if (!child) + { + sdbg("ERROR: task_vforksetup failed\n"); + return (pid_t)ERROR; + } + + svdbg("TCBs: Parent=%p Child=%p\n", parent, child); + + /* Get the size of the parent task's stack. Due to alignment operations, + * the adjusted stack size may be smaller than the stack size originally + * requested. + */ + + stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1; + + /* Allocate the stack for the TCB */ + + ret = up_create_stack((FAR struct tcb_s *)child, stacksize, + parent->flags & TCB_FLAG_TTYPE_MASK); + if (ret != OK) + { + sdbg("ERROR: up_create_stack failed: %d\n", ret); + task_vforkabort(child, -ret); + return (pid_t)ERROR; + } + + /* How much of the parent's stack was utilized? The ARM uses + * a push-down stack so that the current stack pointer should + * be lower than the initial, adjusted stack pointer. The + * stack usage should be the difference between those two. + */ + + DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); + stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; + + svdbg("Parent: stacksize:%d stackutil:%d\n", stacksize, stackutil); + + /* Make some feeble effort to preserve the stack contents. This is + * feeble because the stack surely contains invalid pointers and other + * content that will not work in the child context. However, if the + * user follows all of the caveats of vfork() usage, even this feeble + * effort is overkill. + */ + + newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; + memcpy((void *)newsp, (const void *)context->sp, stackutil); + + /* Was there a frame pointer in place before? */ + + if (context->fp <= (uint32_t)parent->adj_stack_ptr && + context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) + { + uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; + newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; + } + else + { + newfp = context->fp; + } + + svdbg("Parent: stack base:%08x SP:%08x FP:%08x\n", + parent->adj_stack_ptr, context->sp, context->fp); + svdbg("Child: stack base:%08x SP:%08x FP:%08x\n", + child->cmn.adj_stack_ptr, newsp, newfp); + + /* Update the stack pointer, frame pointer, and volatile registers. When + * the child TCB was initialized, all of the values were set to zero. + * up_initial_state() altered a few values, but the return value in R0 + * should be cleared to zero, providing the indication to the newly started + * child thread. + */ + + child->cmn.xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */ + child->cmn.xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */ + child->cmn.xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */ + child->cmn.xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */ + child->cmn.xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */ + child->cmn.xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */ + child->cmn.xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */ + child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ + child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ + +#ifdef CONFIG_LIB_SYSCALL + /* If we got here via a syscall, then we are going to have to setup some + * syscall return information as well. + */ + + if (parent->xcp.nsyscalls > 0) + { + int index; + for (index = 0; index < parent->xcp.nsyscalls; index++) + { + child->cmn.xcp.syscall[index].sysreturn = + parent->xcp.syscall[index].sysreturn; + + /* REVISIT: This logic is *not* common. */ + +#if defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXA9) +# ifdef CONFIG_BUILD_KERNEL + + child->cmn.xcp.syscall[index].cpsr = + parent->xcp.syscall[index].cpsr; + +# endif + +#elif defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) +# ifdef CONFIG_BUILD_PROTECTED + + child->cmn.xcp.syscall[index].cpsr = + parent->xcp.syscall[index].cpsr; + +# endif +#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ + defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM7) + + child->cmn.xcp.syscall[index].excreturn = + parent->xcp.syscall[index].excreturn; +#else +# error Missing logic +#endif + } + + child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls; + } +#endif + + /* And, finally, start the child task. On a failure, task_vforkstart() + * will discard the TCB by calling task_vforkabort(). + */ + + return task_vforkstart(child); +} diff --git a/arch/arm/src/common/up_vfork.h b/arch/arm/src/common/up_vfork.h new file mode 100644 index 0000000000000000000000000000000000000000..97edf9aaa5cffb6445b7def2d223530114b15da1 --- /dev/null +++ b/arch/arm/src/common/up_vfork.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/src/common/up_vfork.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARM_VFORK_H +#define __ARCH_ARM_SRC_ARM_VFORK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VFORK_R4_OFFSET (0*4) /* Volatile register r4 */ +#define VFORK_R5_OFFSET (1*4) /* Volatile register r5 */ +#define VFORK_R6_OFFSET (2*4) /* Volatile register r6 */ +#define VFORK_R7_OFFSET (3*4) /* Volatile register r7 */ +#define VFORK_R8_OFFSET (4*4) /* Volatile register r8 */ +#define VFORK_R9_OFFSET (5*4) /* Volatile register r9 */ +#define VFORK_R10_OFFSET (6*4) /* Volatile register r10 */ + +#define VFORK_FP_OFFSET (7*4) /* Frame pointer */ +#define VFORK_SP_OFFSET (8*4) /* Stack pointer*/ +#define VFORK_LR_OFFSET (9*4) /* Return address*/ + +#define VFORK_SIZEOF (10*4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +struct vfork_s +{ + /* CPU registers */ + + uint32_t r4; /* Volatile register r4 */ + uint32_t r5; /* Volatile register r5 */ + uint32_t r6; /* Volatile register r6 */ + uint32_t r7; /* Volatile register r7 */ + uint32_t r8; /* Volatile register r8 */ + uint32_t r9; /* Volatile register r9 */ + uint32_t r10; /* Volatile register r10 */ + + uint32_t fp; /* Frame pointer */ + uint32_t sp; /* Stack pointer*/ + uint32_t lr; /* Return address*/ + + /* Floating point registers (not yet) */ +}; +#endif + +#endif /* __ARCH_ARM_SRC_ARM_VFORK_H */ diff --git a/arch/arm/src/dm320/Kconfig b/arch/arm/src/dm320/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..cc0de49494c2ea01ba32e4c26464a62a1c189295 --- /dev/null +++ b/arch/arm/src/dm320/Kconfig @@ -0,0 +1,22 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_DM320 +comment "DM320 Configuration Options" + +menu "DM320 Peripheral Selections" + +config DM320_UART0 + bool + default y + select ARCH_HAVE_UART0 + +config DM320_UART1 + bool + default y + select ARCH_HAVE_UART1 + +endmenu # DM320 Peripheral Selections +endif # ARCH_CHIP_DM320 diff --git a/arch/arm/src/dm320/Make.defs b/arch/arm/src/dm320/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..ab9b2afa638eb4d521023ce9b2bf12f88679468b --- /dev/null +++ b/arch/arm/src/dm320/Make.defs @@ -0,0 +1,70 @@ +############################################################################ +# dm320/Make.defs +# +# Copyright (C) 2007, 2010, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = up_head.S + +CMN_ASRCS = up_cache.S up_fullcontextrestore.S up_saveusercontext.S +CMN_ASRCS += up_vectors.S up_vectoraddrexcptn.S up_vectortab.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_prefetchabort.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = dm320_lowputc.S dm320_restart.S + +CHIP_CSRCS = dm320_allocateheap.c dm320_boot.c dm320_decodeirq.c +CHIP_CSRCS += dm320_irq.c dm320_serial.c dm320_framebuffer.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += dm320_timerisr.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += dm320_usbdev.c +endif diff --git a/arch/arm/src/dm320/chip.h b/arch/arm/src/dm320/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..73e53b68317bc91e2cac994345a12ced92f3d117 --- /dev/null +++ b/arch/arm/src/dm320/chip.h @@ -0,0 +1,61 @@ +/************************************************************************************ + * arch/arm/src/dm320/chip.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_CHIP_H +#define __DM320_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "dm320_memorymap.h" +#include "dm320_clkc.h" +#include "dm320_ahb.h" +#include "dm320_busc.h" +#include "dm320_uart.h" +#include "dm320_timer.h" +#include "dm320_intc.h" +#include "dm320_gio.h" +#include "dm320_usb.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __DM320_CHIP_H */ diff --git a/arch/arm/src/dm320/dm320_ahb.h b/arch/arm/src/dm320/dm320_ahb.h new file mode 100644 index 0000000000000000000000000000000000000000..6a3654666ba993d82672693b681e442ce72b32a0 --- /dev/null +++ b/arch/arm/src/dm320/dm320_ahb.h @@ -0,0 +1,59 @@ +/************************************************************************************ + * dm320/dm320_uart.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_DM320_DM320_AHB_H +#define __ARCH_ARM_SRC_DM320_DM320_AHB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* AHB Bus Controller (AHBBUSC) Registers *******************************************/ + +#define DM320_AHB_SDRAMSA (DM320_AHB_VADDR+0x0f00) /* SDRAM start address */ +#define DM320_AHB_SDRAMEA (DM320_AHB_VADDR+0x0f04) /* SDRAM end address */ +#define DM320_AHB_BUSCONTROL (DM320_AHB_VADDR+0x0f08) /* Bus endianess control */ +#define DM320_AHB_RSV1 (DM320_AHB_VADDR+0x0f0c) /* Reserved */ +#define DM320_AHB_USBCTL (DM320_AHB_VADDR+0x0f10) /* USB control register (ES1.1) */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_DM320_DM320_AHB_H */ diff --git a/arch/arm/src/dm320/dm320_allocateheap.c b/arch/arm/src/dm320/dm320_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..d1a96f8020ac854b8f0506574b49fc200f9c9ec8 --- /dev/null +++ b/arch/arm/src/dm320/dm320_allocateheap.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * dm320/dm320_allocateheap.c + * + * Copyright (C) 2007, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside + * the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both + * kernel- and user-space heaps (CONFIG_MM_KERNEL_HEAP=y), + * this function provides the size of the unprotected, + * user-space heap. + * + * If a protected kernel-space heap is provided, the kernel + * heap must be allocated (and protected) by an analogous + * up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = (DM320_SDRAM_VADDR + CONFIG_RAM_SIZE) - g_idle_topstack; +} diff --git a/arch/arm/src/dm320/dm320_boot.c b/arch/arm/src/dm320/dm320_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..4ba55ac1726a473f4c0acdcc384111b450852299 --- /dev/null +++ b/arch/arm/src/dm320/dm320_boot.c @@ -0,0 +1,236 @@ +/************************************************************************************ + * arch/arm/src/dm320/dm320_boot.c + * + * Copyright (C) 2007, 2009-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +#include + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct section_mapping_s +{ + uint32_t physbase; /* Physical address of the region to be mapped */ + uint32_t virtbase; /* Virtual address of the region to be mapped */ + uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ + uint32_t nsections; /* Number of mappings in the region */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static const struct section_mapping_s section_mapping[] = +{ + { DM320_PERIPHERALS_PSECTION, DM320_PERIPHERALS_VSECTION, + DM320_PERIPHERALS_MMUFLAGS, DM320_PERIPHERALS_NSECTIONS}, + { DM320_FLASH_PSECTION, DM320_FLASH_VSECTION, + DM320_FLASH_MMUFLAGS, DM320_FLASH_NSECTIONS}, + { DM320_CFI_PSECTION, DM320_CFI_VSECTION, + DM320_CFI_MMUFLAGS, DM320_CFI_NSECTIONS}, + { DM320_SSFDC_PSECTION, DM320_SSFDC_VSECTION, + DM320_SSFDC_MMUFLAGS, DM320_SSFDC_NSECTIONS}, + { DM320_CE1_PSECTION, DM320_CE1_VSECTION, + DM320_CE1_MMUFLAGS, DM320_CE1_NSECTIONS}, + { DM320_CE2_PSECTION, DM320_CE2_VSECTION, + DM320_CE2_MMUFLAGS, DM320_CE2_NSECTIONS}, + { DM320_VLYNQ_PSECTION, DM320_VLYNQ_VSECTION, + DM320_VLYNQ_MMUFLAGS, DM320_VLYNQ_NSECTIONS}, + { DM320_USBOTG_PSECTION, DM320_USBOTG_VSECTION, + DM320_USBOTG_MMUFLAGS, DM320_USBOTG_NSECTIONS} +}; +#define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s)) + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_setlevel1entry + ************************************************************************************/ + +static inline void up_setlevel1entry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *pgtable = (uint32_t *)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + pgtable[index] = (paddr | mmuflags); +} + +/************************************************************************************ + * Name: up_setlevel2coarseentry + ************************************************************************************/ + +static inline void up_setlevel2coarseentry(uint32_t ctabvaddr, uint32_t paddr, + uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *ctable = (uint32_t *)ctabvaddr; + uint32_t index; + + /* The coarse table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The coarse page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the coarse table entry */ + + ctable[index] = (paddr | mmuflags); +} + +/************************************************************************************ + * Name: up_setupmappings + ************************************************************************************/ + +static void up_setupmappings(void) +{ + int i, j; + + for (i = 0; i < NMAPPINGS; i++) + { + uint32_t sect_paddr = section_mapping[i].physbase; + uint32_t sect_vaddr = section_mapping[i].virtbase; + uint32_t mmuflags = section_mapping[i].mmuflags; + + for (j = 0; j < section_mapping[i].nsections; j++) + { + up_setlevel1entry(sect_paddr, sect_vaddr, mmuflags); + sect_paddr += SECTION_SIZE; + sect_vaddr += SECTION_SIZE; + } + } +} + +/************************************************************************************ + * Name: up_vectormapping + ************************************************************************************/ + +static void up_vectormapping(void) +{ + uint32_t vector_paddr = DM320_IRAM_PADDR; + uint32_t vector_vaddr = DM320_VECTOR_VADDR; + uint32_t end_paddr = vector_paddr + DM320_IRAM_SIZE; + + /* We want to keep our interrupt vectors and interrupt-related logic in zero-wait + * state internal RAM (IRAM). The DM320 has 16Kb of IRAM positioned at physical + * address 0x0000:0000; we need to map this to 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + up_setlevel2coarseentry(PGTABLE_L2_COARSE_VBASE, vector_paddr, vector_vaddr, + MMU_L2_VECTORFLAGS); + vector_paddr += 4096; + vector_vaddr += 4096; + } + + /* Now set the level 1 descriptor to refer to the level 2 coarse page table. */ + + up_setlevel1entry(PGTABLE_L2_COARSE_PBASE, DM320_VECTOR_VCOARSE, MMU_L1_VECTORFLAGS); +} + +/************************************************************************************ + * Name: up_copyvectorblock + ************************************************************************************/ + +static void up_copyvectorblock(void) +{ + uint32_t *src = (uint32_t *)&_vector_start; + uint32_t *end = (uint32_t *)&_vector_end; + uint32_t *dest = (uint32_t *)VECTOR_BASE; + + while (src < end) + { + *dest++ = *src++; + } +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void up_boot(void) +{ + /* __start provided the basic MMU mappings for SDRAM. Now provide mappings for all + * IO regions (Including the vector region). + */ + + up_setupmappings(); + + /* Provide a special mapping for the IRAM interrupt vector positioned in high + * memory. + */ + + up_vectormapping(); + + /* Setup up vector block. _vector_start and _vector_end are exported from + * up_vector.S + */ + + up_copyvectorblock(); + + /* Set up the board-specific LEDs */ + +#ifdef CONFIG_ARCH_LEDS + board_autoled_initialize(); +#endif + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif +} diff --git a/arch/arm/src/dm320/dm320_busc.h b/arch/arm/src/dm320/dm320_busc.h new file mode 100644 index 0000000000000000000000000000000000000000..8c359094678aaac83d872155901f7ad03d5fe9d6 --- /dev/null +++ b/arch/arm/src/dm320/dm320_busc.h @@ -0,0 +1,58 @@ +/************************************************************************************ + * dm320/dm320_busc.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_DM320_DM320_BUSC_H +#define __ARCH_ARM_SRC_DM320_DM320_BUSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bus Controller Register Map (BUSC) ***********************************************/ + +#define DM320_BUSC_ECR (DM320_BUSC_REGISTER_BASE+0x0000) /* Endian Conversion Register */ +#define DM320_BUSC_EBYTER (DM320_BUSC_REGISTER_BASE+0x0002) /* Endian Byte Reverse Register */ +#define DM320_BUSC_EBITR (DM320_BUSC_REGISTER_BASE+0x0004) /* Endian Bit Reverse Register */ +#define DM320_BUSC_REVR (DM320_BUSC_REGISTER_BASE+0x0006) /* Device Revision Register */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_DM320_DM320_BUSC_H */ diff --git a/arch/arm/src/dm320/dm320_clkc.h b/arch/arm/src/dm320/dm320_clkc.h new file mode 100644 index 0000000000000000000000000000000000000000..7019b11dcee83e63fa292e69b556941f4c37a05b --- /dev/null +++ b/arch/arm/src/dm320/dm320_clkc.h @@ -0,0 +1,81 @@ +/************************************************************************************ + * dm320/dm320_clkc.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_DM320_DM320_CLKC_H +#define __ARCH_ARM_SRC_DM320_DM320_CLKC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clock Controller Register Map (CLKC) *********************************************/ + +#define DM320_CLKC_PLLA (DM320_CLKC_REGISTER_BASE+0x0000) /* PLLA Configuration */ +#define DM320_CLKC_PLLB (DM320_CLKC_REGISTER_BASE+0x0002) /* PLLB Configuration */ +#define DM320_CLKC_SEL0 (DM320_CLKC_REGISTER_BASE+0x0004) /* Input Clock Source Selection #0 */ +#define DM320_CLKC_SEL1 (DM320_CLKC_REGISTER_BASE+0x0006) /* Input Slock Source Selection #1 */ +#define DM320_CLKC_SEL2 (DM320_CLKC_REGISTER_BASE+0x0008) /* Input Clock Source Selection #2 */ +#define DM320_CLKC_DIV0 (DM320_CLKC_REGISTER_BASE+0x000a) /* Clock Divisor Settings #0 */ +#define DM320_CLKC_DIV1 (DM320_CLKC_REGISTER_BASE+0x000c) /* Clock Divisor Settings #1 */ +#define DM320_CLKC_DIV2 (DM320_CLKC_REGISTER_BASE+0x000e) /* Clock Divisor Settings #2 */ +#define DM320_CLKC_DIV3 (DM320_CLKC_REGISTER_BASE+0x0010) /* Clock Divisor Settings #3 */ +#define DM320_CLKC_DIV4 (DM320_CLKC_REGISTER_BASE+0x0012) /* Clock Divisor Settings #4 */ +#define DM320_CLKC_BYP (DM320_CLKC_REGISTER_BASE+0x0014) /* Bypass Control */ +#define DM320_CLKC_INV (DM320_CLKC_REGISTER_BASE+0x0016) /* Inverse Control */ +#define DM320_CLKC_MOD0 (DM320_CLKC_REGISTER_BASE+0x0018) /* Module Clock Enables #0 */ +#define DM320_CLKC_MOD1 (DM320_CLKC_REGISTER_BASE+0x001a) /* Module ClockEnables #1 */ +#define DM320_CLKC_MOD2 (DM320_CLKC_REGISTER_BASE+0x001c) /* Module ClockEnables #1 */ +#define DM320_CLKC_LPCTL0 (DM320_CLKC_REGISTER_BASE+0x001e) /* Low Power Control #0 */ +#define DM320_CLKC_LPCTL1 (DM320_CLKC_REGISTER_BASE+0x0020) /* Low Power Control #1 */ +#define DM320_CLKC_OSEL (DM320_CLKC_REGISTER_BASE+0x0022) /* Output Clock Selector */ +#define DM320_CLKC_O0DIV (DM320_CLKC_REGISTER_BASE+0x0024) /* Output Clock #0 Divider */ +#define DM320_CLKC_O1DIV (DM320_CLKC_REGISTER_BASE+0x0026) /* Output Clock #1 Divider */ +#define DM320_CLKC_O2DIV (DM320_CLKC_REGISTER_BASE+0x0028) /* Output Clock #2 Divider */ +#define DM320_CLKC_PWM0C (DM320_CLKC_REGISTER_BASE+0x002a) /* PWM #0 Cycle Count */ +#define DM320_CLKC_PWM0H (DM320_CLKC_REGISTER_BASE+0x002c) /* PWM #0 High Period */ +#define DM320_CLKC_PWM1C (DM320_CLKC_REGISTER_BASE+0x002e) /* PWM #1 Cycle Count */ +#define DM320_CLKC_PWM1H (DM320_CLKC_REGISTER_BASE+0x0030) /* PWM #1 Cycle Period */ +#define DM320_CLKC_TEST0 (DM320_CLKC_REGISTER_BASE+0x08FE) /* Test #0 */ +#define DM320_CLKC_TEST1 (DM320_CLKC_REGISTER_BASE+0x08FE) /* Test #1 */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_DM320_DM320_CLKC_H */ diff --git a/arch/arm/src/dm320/dm320_decodeirq.c b/arch/arm/src/dm320/dm320_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..5d36a6bdc65685f41bc4bdb50e6710b3d82b6071 --- /dev/null +++ b/arch/arm/src/dm320/dm320_decodeirq.c @@ -0,0 +1,150 @@ +/******************************************************************************** + * arch/arm/src/dm320/dm320_decodeirq.c + * + * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + /* Decode the interrupt. First, fetch the interrupt id register. */ + + uint16_t irqentry = getreg16(DM320_INTC_IRQENTRY0); + + /* The irqentry value is an offset into a table. Zero means no interrupt. */ + + if (irqentry != 0) + { + /* If non-zero, then we can map the table offset into an IRQ number */ + + int irq = (irqentry >> 2) - 1; + + /* Verify that the resulting IRQ number is valid */ + + if ((unsigned)irq < NR_IRQS) + { + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(CURRENT_REGS == NULL); + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. + * If an interrupt level context switch has occurred, then restore + * the floating point state and the establish the correct address + * environment before returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in + * an interrupt handler. + */ + + CURRENT_REGS = NULL; + } + } +#endif +} diff --git a/arch/arm/src/dm320/dm320_emif.h b/arch/arm/src/dm320/dm320_emif.h new file mode 100644 index 0000000000000000000000000000000000000000..653e20fe0d5532f4970971a19b48e8e653e0630f --- /dev/null +++ b/arch/arm/src/dm320/dm320_emif.h @@ -0,0 +1,108 @@ +/************************************************************************************ + * dm320/dm320_emif.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_DM320_EMIF_H +#define __DM320_DM320_EMIF_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* External Memory Interface (EMIF) Registers */ + +#define DM320_EMIF_CS0CTRL1 (DM320_PERIPHERALS_VADDR + 0x0A00) /* CS0 Control Register #1 */ +#define DM320_EMIF_CS0CTRL2 (DM320_PERIPHERALS_VADDR + 0x0A02) /* CS0 Control Register #2 */ +#define DM320_EMIF_CS0CTRL3 (DM320_PERIPHERALS_VADDR + 0x0A04) /* CS0 Control Register #3 */ +#define DM320_EMIF_CS1CTRL1A (DM320_PERIPHERALS_VADDR + 0x0A06) /* CS1 Control Register #1A */ +#define DM320_EMIF_CS1CTRL1B (DM320_PERIPHERALS_VADDR + 0x0A08) /* CS1 Control Register #1B */ +#define DM320_EMIF_CS2CTRL2 (DM320_PERIPHERALS_VADDR + 0x0A0A) /* CS1 Control Register #2 */ +#define DM320_EMIF_CS2CTRL1 (DM320_PERIPHERALS_VADDR + 0x0A0C) /* CS2 Control Register #1 */ +#define DM320_EMIF_CS1CTRL2 (DM320_PERIPHERALS_VADDR + 0x0A0E) /* CS2 Control Register #2 */ +#define DM320_EMIF_CS3CTRL1 (DM320_PERIPHERALS_VADDR + 0x0A10) /* CS3 Control Register #1 */ +#define DM320_EMIF_CS3CTRL2 (DM320_PERIPHERALS_VADDR + 0x0A12) /* CS3 Control Register #2 */ +#define DM320_EMIF_CS4CTRL1 (DM320_PERIPHERALS_VADDR + 0x0A14) /* CS4 Control Register #1 */ +#define DM320_EMIF_CS4CTRL2 (DM320_PERIPHERALS_VADDR + 0x0A16) /* CS4 Control Register #2 */ +#define DM320_EMIF_BUSCTRL (DM320_PERIPHERALS_VADDR + 0x0A18) /* Bus Control Register */ +#define DM320_EMIF_BUSRLS (DM320_PERIPHERALS_VADDR + 0x0A1A) /* Bus Release Control Register */ +#define DM320_EMIF_CFCTRL1 (DM320_PERIPHERALS_VADDR + 0x0A1C) /* CFC ControlRegister #1 */ +#define DM320_EMIF_CFCTRL2 (DM320_PERIPHERALS_VADDR + 0x0A1E) /* CFC ControlRegister#2 */ +#define DM320_EMIF_SMCTRL (DM320_PERIPHERALS_VADDR + 0x0A20) /* SmartMedia Control Register */ +#define DM320_EMIF_BUSINTEN (DM320_PERIPHERALS_VADDR + 0x0A22) /* Bus Interrupt Enable Register */ +#define DM320_EMIF_BUSSTS (DM320_PERIPHERALS_VADDR + 0x0A24) /* Bus Status Register */ +#define DM320_EMIF_BUSWAITMD (DM320_PERIPHERALS_VADDR + 0x0A26) /* Bus Wait Mode Register */ +#define DM320_EMIF_ECC1CP (DM320_PERIPHERALS_VADDR + 0x0A28) /* ECC Area 1 CP Register */ +#define DM320_EMIF_ECC1LP (DM320_PERIPHERALS_VADDR + 0x0A2A) /* ECC Area 1 LP Register */ +#define DM320_EMIF_ECC2CP (DM320_PERIPHERALS_VADDR + 0x0A2C) /* ECC Area 2 CP Register */ +#define DM320_EMIF_ECC2LP (DM320_PERIPHERALS_VADDR + 0x0A2E) /* ECC Area 2 LP Register */ +#define DM320_EMIF_ECC3CP (DM320_PERIPHERALS_VADDR + 0x0A30) /* ECC Area 3 CP Register */ +#define DM320_EMIF_ECC3LP (DM320_PERIPHERALS_VADDR + 0x0A32) /* ECC Area 3 LP Register */ +#define DM320_EMIF_ECC4CP (DM320_PERIPHERALS_VADDR + 0x0A34) /* ECC Area 4 CP Register */ +#define DM320_EMIF_ECC4LP (DM320_PERIPHERALS_VADDR + 0x0A36) /* ECC Area 4 LP Register */ +#define DM320_EMIF_ECC5CP (DM320_PERIPHERALS_VADDR + 0x0A38) /* ECC Area 5 CP Register */ +#define DM320_EMIF_ECC5LP (DM320_PERIPHERALS_VADDR + 0x0A3A) /* ECC Area 5 LP Register */ +#define DM320_EMIF_ECC6CP (DM320_PERIPHERALS_VADDR + 0x0A3C) /* ECC Area 6 CP Register */ +#define DM320_EMIF_ECC6LP (DM320_PERIPHERALS_VADDR + 0x0A3E) /* ECC Area 6 LP Register */ +#define DM320_EMIF_ECC7CP (DM320_PERIPHERALS_VADDR + 0x0A40) /* ECC Area 7 CP Register */ +#define DM320_EMIF_ECC7LP (DM320_PERIPHERALS_VADDR + 0x0A42) /* ECC Area 7 LP Register */ +#define DM320_EMIF_ECC8CP (DM320_PERIPHERALS_VADDR + 0x0A44) /* ECC Area 8 CP Register */ +#define DM320_EMIF_ECC8LP (DM320_PERIPHERALS_VADDR + 0x0A46) /* ECC Area 8 LP Register */ +#define DM320_EMIF_ECCCLR (DM320_PERIPHERALS_VADDR + 0x0A48) /* ECC Clear Register */ +#define DM320_EMIF_PAGESZ (DM320_PERIPHERALS_VADDR + 0x0A4A) /* SmartMedia Page Size Register */ +#define DM320_EMIF_PRIORCTL (DM320_PERIPHERALS_VADDR + 0x0A4C) /* Priority control for DMA */ +#define DM320_EMIF_IMGDSPDEST (DM320_PERIPHERALS_VADDR + 0x0A4E) /* DSP/IMGBUF DMA destination */ +#define DM320_EMIF_IMGDSPADDH (DM320_PERIPHERALS_VADDR + 0x0A50) /* DSP/IMGBUF high address */ +#define DM320_EMIF_IMGDSPADDL (DM320_PERIPHERALS_VADDR + 0x0A52) /* DSP/IMGBUG low address */ +#define DM320_EMIF_AHBADDH (DM320_PERIPHERALS_VADDR + 0x0A54) /* AHB high address */ +#define DM320_EMIF_AHBADDL (DM320_PERIPHERALS_VADDR + 0x0A56) /* AHB low address */ +#define DM320_EMIF_MTCADDH (DM320_PERIPHERALS_VADDR + 0x0A58) /* MTC high address */ +#define DM320_EMIF_MTCADDL (DM320_PERIPHERALS_VADDR + 0x0A5A) /* MTC low address */ +#define DM320_EMIF_DMASIZE (DM320_PERIPHERALS_VADDR + 0x0A5C) /* DMA Transfer Size Register */ +#define DM320_EMIF_DMAMTCSEL (DM320_PERIPHERALS_VADDR + 0x0A5E) /* DMA Device Select Register */ +#define DM320_EMIF_DMACTL (DM320_PERIPHERALS_VADDR + 0x0A60) /* DMA Control Register */ +#define DM320_EMIF_TEST (DM320_PERIPHERALS_VADDR + 0x0A62) /* Test Register.Do not use */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif + +#endif /* __DM320_DM320_EMIF_H */ diff --git a/arch/arm/src/dm320/dm320_framebuffer.c b/arch/arm/src/dm320/dm320_framebuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..6a7f44e819a19dd96796194d68b4e0df37b21eef --- /dev/null +++ b/arch/arm/src/dm320/dm320_framebuffer.c @@ -0,0 +1,1440 @@ +/**************************************************************************** + * arch/arm/src/dm320/dm320_framebuffer.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "dm320_memorymap.h" +#include "dm320_osd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ********************************************************/ + +/* Video (X,Y) base offset */ + +#ifndef CONFIG_DM320_BASEX +# define CONFIG_DM320_BASEX 0x090 +#endif + +#ifndef CONFIG_DM320_BASEY +# define CONFIG_DM320_BASEY 0x010 +#endif + +/* Background color */ + +#ifndef CONFIG_DM320_BKGDCLUT +# define CONFIG_DM320_BKGDCLUT 0x00ff +#endif + +#ifdef CONFIG_FB_HWCURSORIMAGE +# error "Cursor image not supported" +#endif + +/* Window selections */ + +#if defined(CONFIG_DM320_OSD0_RGB16) && defined(CONFIG_DM320_OSD1_RGB16) +# error "Both CONFIG_DM320_OSD0_RGB16 and CONFIG_DM320_OSD1_RGB16 defined" +#endif + +#if defined(CONFIG_DM320_VID0_DISABLE) && defined(CONFIG_DM320_VID1_DISABLE) && \ + defined(CONFIG_DM320_OSD0_DISABLE) && defined(CONFIG_DM320_OSD1_DISABLE) +# error "All windows are disabled, at least one window must be enabled" +#endif + +#undef CONFIG_DM320_DISABLE_PINGPONG +#define CONFIG_DM320_DISABLE_PINGPONG 1 /* Not supported by interface */ + +/* Window positions and sizes */ + +#define MAX_XRES 640 +#define MAX_YRES 480 + +#ifndef CONFIG_DM320_VID0_DISABLE +# ifndef CONFIG_DM320_VID0_XRES +# define CONFIG_DM320_VID0_XRES MAX_XRES +# elif CONFIG_DM320_VID0_XRES > MAX_XRES +# error "VID0 XRES out of range" +# endif +# ifndef CONFIG_DM320_VID0_XPOS +# define CONFIG_DM320_VID0_XPOS 0 +# elif CONFIG_DM320_VID0_XPOS + CONFIG_DM320_VID0_XRES > MAX_XRES +# error "VID0 XPOS out of range" +# endif +# ifndef CONFIG_DM320_VID0_YRES +# define CONFIG_DM320_VID0_YRES MAX_YRES +# elif CONFIG_DM320_VID0_YRES > MAX_YRES +# error "VID0 YRES out of range" +# endif +# ifndef CONFIG_DM320_VID0_YPOS +# define CONFIG_DM320_VID0_YPOS 0 +# elif CONFIG_DM320_VID0_YPOS + CONFIG_DM320_VID0_YRES > MAX_YRES +# error "VID0 YPOS out of range" +# endif +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE +# ifndef CONFIG_DM320_VID1_XRES +# define CONFIG_DM320_VID1_XRES MAX_XRES +# elif CONFIG_DM320_VID1_XRES > MAX_XRES +# error "VID1 XRES out of range" +# endif +# ifndef CONFIG_DM320_VID1_XPOS +# define CONFIG_DM320_VID1_XPOS 0 +# elif CONFIG_DM320_VID1_XPOS + CONFIG_DM320_VID1_XRES > MAX_XRES +# error "VID0 XPOS out of range" +# endif +# ifndef CONFIG_DM320_VID1_YRES +# define CONFIG_DM320_VID1_YRES MAX_YRES +# elif CONFIG_DM320_VID1_YRES > MAX_YRES +# error "VID1 YRES out of range" +# endif +# ifndef CONFIG_DM320_VID1_YPOS +# define CONFIG_DM320_VID1_YPOS 0 +# elif CONFIG_DM320_VID1_YPOS + CONFIG_DM320_VID1_YRES > MAX_YRES +# error "VID1 YPOS out of range" +# endif +#endif + +#ifndef CONFIG_DM320_OSD0_DISABLE +# ifndef CONFIG_DM320_OSD0_XRES +# define CONFIG_DM320_OSD0_XRES MAX_XRES +# elif CONFIG_DM320_OSD0_XRES > MAX_XRES +# error "OSD0 XRES out of range" +# endif +# ifndef CONFIG_DM320_OSD0_XPOS +# define CONFIG_DM320_OSD0_XPOS 0 +# elif CONFIG_DM320_OSD0_XPOS + CONFIG_DM320_OSD0_XRES > MAX_XRES +# error "OSD0 XPOS out of range" +# endif +# ifndef CONFIG_DM320_OSD0_YRES +# define CONFIG_DM320_OSD0_YRES MAX_YRES +# elif CONFIG_DM320_OSD0_YRES > MAX_YRES +# error "OSD0 YRES out of range" +# endif +# ifndef CONFIG_DM320_OSD0_YPOS +# define CONFIG_DM320_OSD0_YPOS 0 +# elif CONFIG_DM320_OSD0_YPOS + CONFIG_DM320_OSD0_YRES > MAX_YRES +# error "OSD0 YPOS out of range" +# endif +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE +# ifndef CONFIG_DM320_OSD1_XRES +# define CONFIG_DM320_OSD1_XRES MAX_XRES +# elif CONFIG_DM320_OSD1_XRES > MAX_XRES +# error "OSD1 XRES out of range" +# endif +# ifndef CONFIG_DM320_OSD1_XPOS +# define CONFIG_DM320_OSD1_XPOS 0 +# elif CONFIG_DM320_OSD1_XPOS + CONFIG_DM320_OSD1_XRES > MAX_XRES +# error "OSD1 XPOS out of range" +# endif +# ifndef CONFIG_DM320_OSD1_YRES +# define CONFIG_DM320_OSD1_YRES MAX_YRES +# elif CONFIG_DM320_OSD0_YRES > MAX_YRES +# error "OSD0 YRES out of range" +# endif +# ifndef CONFIG_DM320_OSD1_YPOS +# define CONFIG_DM320_OSD1_YPOS 0 +# elif CONFIG_DM320_OSD1_YPOS + CONFIG_DM320_OSD1_YRES > MAX_YRES +# error "OSD1 YPOS out of range" +# endif +#endif + +/* Cursor selections */ + +#ifdef CONFIG_FB_HWCURSOR +# ifndef CONFIG_DM320_CURSORCLUT +# define CONFIG_DM320_CURSORCLUT 0x00 +# endif +# ifndef CONFIG_DM320_CURSORLINEWIDTH +# define CONFIG_DM320_CURSORLINEWIDTH 1 +# endif +# if CONFIG_DM320_CURSORLINEWIDTH > 7 +# error "Rectangular cursor width is out of range" +# endif +# ifndef CONFIG_DM320_CURSORLINEHEIGHT +# define CONFIG_DM320_CURSORLINEHEIGHT 1 +# endif +# if CONFIG_DM320_CURSORLINEHEIGHT > 7 +# error "Rectangular cursor height is out of range" +# endif +# ifndef CONFIG_DM320_RECTCURSOR_WIDTH +# define CONFIG_DM320_RECTCURSOR_WIDTH MAX_XRES +# elif CONFIG_DM320_RECTCURSOR_WIDTH > MAX_XRES +# error "Cursor width out of range" +# endif +# ifndef CONFIG_DM320_RECTCURSOR_HEIGHT +# define CONFIG_DM320_RECTCURSOR_HEIGHT MAX_YRES +# elif CONFIG_DM320_RECTCURSOR_HEIGHT > MAX_YRES +# error "Cursor width out of range" +# endif +#endif + +/* DM320 ****************************************************************/ + +/* Video planes. This long messy conditional compilation results in + * consecutive plane numbers assigned for enable planes and the total + * number of planes + */ + +#ifndef CONFIG_DM320_VID0_DISABLE +# define DM320_VIDWIN0 (0) /* Have VID0 */ +# ifndef CONFIG_DM320_VID1_DISABLE +# define DM320_VIDWIN1 (1) /* Have VID0+VID1 */ +# ifndef CONFIG_DM320_OSD0_DISABLE +# define DM320_OSDWIN0 (2) /* Have VID0+VID1+OSD0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (3) /* Have VID0+VID1+OSD0+OSD1 */ +# define DM320_NFRAMES (4) +# else +# define DM320_NFRAMES (3) /* Have VID0+VID1+OSD0 but not OSD1 */ +# endif +# else /* Have VID0+VID1 but not OSD0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (2) /* Have VID0+VID1+OSD1 but not OSD0 */ +# define DM320_NFRAMES (3) +# else +# define DM320_NFRAMES (2) /* Have VID0+VID1 but not OSD0 or OSD1 */ +# endif +# endif +# else /* Have VID0 but not VID1 */ +# ifndef CONFIG_DM320_OSD0_DISABLE +# define DM320_OSDWIN0 (1) /* Have VID0+OSD0 but not VID1 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (2) /* Have VID0+OSD0+OSD1 but not VID1 */ +# define DM320_NFRAMES (3) +# else +# define DM320_NFRAMES (2) /* Have VID0+OSD0 but not VID1 or OSD1 */ +# endif +# else /* Have VID0 but not VID1 or OSD0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (1) /* Have VID0+OSD1 but not VID1 or OSD0 */ +# define DM320_NFRAMES (3) +# else +# define DM320_NFRAMES (2) /* Have VID0 but not VID1, OSD0, or OSD1 */ +# endif +# endif +# endif +#else /* Don't have VID0 */ +# ifndef CONFIG_DM320_VID1_DISABLE +# define DM320_VIDWIN1 (0) /* Have VID1 but not VID0 */ +# ifndef CONFIG_DM320_OSD0_DISABLE +# define DM320_OSDWIN0 (1) /* Have VID1+OSD0 not VID0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (2) /* Have VID1+OSD0+OSD1 not VID0 */ +# define DM320_NFRAMES (3) +# else +# define DM320_NFRAMES (2) /* Have VID1+OSD0 but not VID0 or OSD1 */ +# endif +# else /* Have VID1 but not VID0 or OSD0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (1) /* Have VID1+OSD1 but not VID0 or OSD0 */ +# define DM320_NFRAMES (2) +# else +# define DM320_NFRAMES (2) /* Have VID1 but not VID0, OSD0 or OSD1 */ +# endif +# endif +# else /* Don't have VID0 or VID1 */ +# ifndef CONFIG_DM320_OSD0_DISABLE +# define DM320_OSDWIN0 (0) /* Have OSD0 but not VID0 or VID1 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (1) /* Have OSD0+OSD1 but not VID0 or VID1 */ +# define DM320_NFRAMES (2) +# else +# define DM320_NFRAMES (1) /* Have OSD0 but VID0, VID, or OSD1 */ +# endif +# else /* Don't have VID0, VID1, or OSD0 */ +# ifndef CONFIG_DM320_OSD1_DISABLE +# define DM320_OSDWIN1 (0) /* Have OSD1 but not VID0, VID1, or OSD0 */ +# define DM320_NFRAMES (1) +# else +# error "No video planes enabled" +# endif +# endif +# endif +#endif + +/* Bits per pixel */ + +#define DM320_VID0_BPP (16) +#define DM320_VID1_BPP (16) +#ifdef CONFIG_DM320_OSD0_RGB16 +# define DM320_OSD0_BPP (16) +#else +# define DM320_OSD0_BPP (8) +#endif +#ifdef CONFIG_DM320_OSD1_RGB16 +# define DM320_OSD1_BPP (16) +#else +# define DM320_OSD1_BPP (8) +#endif + +/* These are DM320-specific ranges for the BASEPX/Y registers */ + +#define DM320_MIN_BASEPX (24) +#define DM320_MAX_BASEPX (1023) +#define DM320_MIN_BASEPY (1) +#define DM320_MAX_BASEPY (511) + +#if (CONFIG_DM320_BASEX < DM320_MIN_BASEPX || CONFIG_DM320_BASEX > DM320_MAX_BASEPX) +# error "CONFIG_DM320_BASEX is out of range" +#endif + +#if (CONFIG_DM320_BASEY < DM320_MIN_BASEPY || CONFIG_DM320_BASEY > DM320_MAX_BASEPY) +# error "CONFIG_DM320_BASEY is out of range" +#endif + +/* The width of a line in bytes */ + +#define DM320_VID0_STRIDE (CONFIG_DM320_VID0_XRES * DM320_VID0_BPP / 8) +#define DM320_VID1_STRIDE (CONFIG_DM320_VID1_XRES * DM320_VID1_BPP / 8) +#define DM320_OSD0_STRIDE (CONFIG_DM320_OSD0_XRES * DM320_OSD0_BPP / 8) +#define DM320_OSD1_STRIDE (CONFIG_DM320_OSD1_XRES * DM320_OSD1_BPP / 8) + +/* The area of the screen in bytes */ + +#define DM320_VID0_FBLEN (DM320_VID0_STRIDE * CONFIG_DM320_VID0_YRES) +#define DM320_VID1_FBLEN (DM320_VID1_STRIDE * CONFIG_DM320_VID1_YRES) +#define DM320_OSD0_FBLEN (DM320_OSD0_STRIDE * CONFIG_DM320_OSD0_YRES) +#define DM320_OSD1_FBLEN (DM320_OSD1_STRIDE * CONFIG_DM320_OSD1_YRES) + +/* Video/OSD modes */ + +#ifndef CONFIG_DM320_VID0_DISABLE +# ifdef CONFIG_DM320_VID0_FRAMEMODE +# define DM320_VID0MODE 0x0003 +# else +# define DM320_VID0MODE 0x0001 +# endif +#else +# define DM320_VID0MODE 0x0000 +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE +# ifdef CONFIG_DM320_VID1_FRAMEMODE +# define DM320_VID1MODE 0x0300 +# else +# define DM320_VID1MODE 0x0100 +# endif +#else +# define DM320_VID1MODE 0x0000 +#endif + +#define DM320_VIDMODE (DM320_VID0MODE|DM320_VID1MODE) + +#ifndef CONFIG_DM320_OSD0_DISABLE +# ifdef CONFIG_DM320_OSD0_FRAMEMODE +# define OSD0MODE_FRAME 0x0002 +# else +# define OSD0_FRAMEMODE 0x0000 +# endif + +# ifdef CONFIG_DM320_OSD0_TRANSPMODE +# ifdef CONFIG_DM320_OSD0_BLEND8THS +# if CONFIG_DM320_OSD0_BLEND8THS == 8 +# define OSD0MODE_TRANSPMODE 0x0004 +# elif CONFIG_DM320_OSD0_BLEND8THS == 7 +# define OSD0MODE_TRANSPMODE 0x000c +# elif CONFIG_DM320_OSD0_BLEND8THS == 6 +# define OSD0MODE_TRANSPMODE 0x0014 +# elif CONFIG_DM320_OSD0_BLEND8THS == 5 +# define OSD0MODE_TRANSPMODE 0x001c +# elif CONFIG_DM320_OSD0_BLEND8THS == 4 +# define OSD0MODE_TRANSPMODE 0x0024 +# elif CONFIG_DM320_OSD0_BLEND8THS == 3 +# define OSD0MODE_TRANSPMODE 0x002c +# elif CONFIG_DM320_OSD0_BLEND8THS == 2 +# define OSD0MODE_TRANSPMODE 0x0034 +# elif CONFIG_DM320_OSD0_BLEND8THS == 0 +# define OSD0MODE_TRANSPMODE 0x003c +# else +# error "Invalid OSD0 transparency selection" +# endif +# else +# define OSD0MODE_TRANSPMODE 0x0004 +# endif +# else +# define OSD0MODE_TRANSPMODE 0x0000 +# endif + +# ifdef CONFIG_DM320_OSD0_RGB16 +# define OSD0MODE_RGB16 0x2000 +# else +# define OSD0MODE_RGB16 0x0000 +# endif + +# define INITIAL_OSD0MODE (0x00c1|OSD0MODE_TRANSPMODE|OSD0_FRAMEMODE|OSD0MODE_RGB16) +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE +# ifdef CONFIG_DM320_OSD1_FRAMEMODE +# define OSD1MODE_FRAME 0x0002 +# else +# define OSD1MODE_FRAME 0x0000 +# endif + +# ifdef CONFIG_DM320_OSD1_TRANSPMODE +# ifdef CONFIG_DM320_OSD1_BLEND8THS +# if CONFIG_DM320_OSD1_BLEND8THS == 8 +# define OSD1MODE_TRANSPMODE 0x0004 +# elif CONFIG_DM320_OSD1_BLEND8THS == 7 +# define OSD1MODE_TRANSPMODE 0x000c +# elif CONFIG_DM320_OSD1_BLEND8THS == 6 +# define OSD1MODE_TRANSPMODE 0x0014 +# elif CONFIG_DM320_OSD1_BLEND8THS == 5 +# define OSD1MODE_TRANSPMODE 0x001c +# elif CONFIG_DM320_OSD1_BLEND8THS == 4 +# define OSD1MODE_TRANSPMODE 0x0024 +# elif CONFIG_DM320_OSD1_BLEND8THS == 3 +# define OSD1MODE_TRANSPMODE 0x002c +# elif CONFIG_DM320_OSD1_BLEND8THS == 2 +# define OSD1MODE_TRANSPMODE 0x0034 +# elif CONFIG_DM320_OSD1_BLEND8THS == 0 +# define OSD1MODE_TRANSPMODE 0x003c +# else +# error "Invalid OSD1 transparency selection" +# endif +# else +# define OSD1MODE_TRANSPMODE 0x0004 +# endif +# else +# define OSD1MODE_TRANSPMODE 0x0000 +# endif + +# ifdef CONFIG_DM320_OSD1_RGB16 +# define OSD1MODE_RGB16 0x2000 +# else +# define OSD1MODE_RGB16 0x0000 +# endif + +# ifdef CONFIG_DM32_OSD1_ATTRIB +# define OSD1MODE_ATTRIB 0x8000 +# else +# define OSD1MODE_ATTRIB 0x0000 +# endif + +# define INITIAL_OSD1MODE (0x00c1|OSD1MODE_TRANSPMODE|OSD1MODE_FRAME|OSD1MODE_RGB16|OSD1MODE_ATTRIB) +#endif + +/* Rectangular cursor mode */ + +#ifdef CONFIG_FB_HWCURSOR +# define DM320_RECTCURSOR_SETUP \ + ((CONFIG_DM320_CURSORLINEHEIGHT << 1) | \ + (CONFIG_DM320_CURSORLINEWIDTH << 4) | \ + (CONFIG_DM320_CURSORCLUT << 8)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Initialization */ + +static int dm320_allocvideomemory(void); +static void dm320_freevideomemory(void); +static void dm320_hwinitialize(void); + +/* Framebuffer interface methods */ + +#ifndef CONFIG_DM320_VID0_DISABLE +static int dm320_getvid0videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo); +static int dm320_getvid0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo); +#endif +#ifndef CONFIG_DM320_VID1_DISABLE +static int dm320_getvid1videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo); +static int dm320_getvid1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo); +#endif +#ifndef CONFIG_DM320_OSD0_DISABLE +static int dm320_getosd0videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo); +static int dm320_getosd0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo); +#endif +#ifndef CONFIG_DM320_OSD1_DISABLE +static int dm320_getosd1videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo); +static int dm320_getosd1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo); +#endif +#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE)) +static int dm320_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap); +static int dm320_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap); +#endif +#ifdef CONFIG_FB_HWCURSOR +static int dm320_getcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_cursorattrib_s *attrib); +static int dm320_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_s *setttings); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These are the addresses of allocated framebuffer memory regions */ + +#ifndef CONFIG_DM320_VID0_DISABLE +static FAR void *g_vid0base = 0; +#ifndef CONFIG_DM320_DISABLE_PINGPONG +static FAR void *g_vid0ppbase = 0; +#endif + +static struct fb_vtable_s g_vid0vtable = +{ + .getvideoinfo = dm320_getvid0videoinfo, + .getplaneinfo = dm320_getvid0planeinfo, +#ifdef CONFIG_FB_HWCURSOR + .getcursor = dm320_getcursor, + .setcursor = dm320_setcursor, +#endif +}; + +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE +static FAR void *g_vid1base = 0; + +static struct fb_vtable_s g_vid1vtable = +{ + .getvideoinfo = dm320_getvid1videoinfo, + .getplaneinfo = dm320_getvid1planeinfo, +#ifdef CONFIG_FB_HWCURSOR + .getcursor = dm320_getcursor, + .setcursor = dm320_setcursor, +#endif +}; +#endif + +#ifndef CONFIG_DM320_OSD0_DISABLE +static FAR void *g_osd0base = 0; +static struct fb_vtable_s g_osd0vtable = +{ + .getvideoinfo = dm320_getosd0videoinfo, + .getplaneinfo = dm320_getosd0planeinfo, +#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE)) + .getcmap = dm320_getcmap, + .putcmap = dm320_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + .getcursor = dm320_getcursor, + .setcursor = dm320_setcursor, +#endif +}; + +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE +static FAR void *g_osd1base = 0; +static struct fb_vtable_s g_osd1vtable = +{ + .getvideoinfo = dm320_getosd1videoinfo, + .getplaneinfo = dm320_getosd1planeinfo, +#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE)) + .getcmap = dm320_getcmap, + .putcmap = dm320_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + .getcursor = dm320_getcursor, + .setcursor = dm320_setcursor, +#endif +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void dm320_blankscreen(uint8_t *buffer, int len) +{ + memset(buffer, 0xff, len); +} + +static inline uint32_t dm320_physaddr(FAR void *fb_vaddr) +{ + return (uint32_t)fb_vaddr - DM320_SDRAM_VADDR; +} + +#ifndef CONFIG_DM320_VID0_DISABLE +static inline uint32_t dm320_vid0upperoffset(void) +{ + return (((dm320_physaddr(g_vid0base) / 32) >> 16) & 0xff); +} + +static inline uint32_t dm320_vid0loweroffset(void) +{ + return ((dm320_physaddr(g_vid0base) / 32) & 0xffff); +} + +#ifndef CONFIG_DM320_DISABLE_PINGPONG +static inline uint32_t dm320_vid0ppupperoffset(void) +{ + return (((dm320_physaddr(g_vid0ppbase) / 32) >> 16) & 0xff); +} + +static inline uint32_t dm320_vid0pploweroffset(void) +{ + return ((dm320_physaddr(g_vid0ppbase) / 32) & 0xffff); +} +#endif +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE +static inline uint32_t dm320_vid1upperoffset(void) +{ + return (((dm320_physaddr(g_vid1base) / 32) >> 16) & 0xff); +} + +static inline uint32_t dm320_vid1loweroffset(void) +{ + return ((dm320_physaddr(g_vid1base) / 32) & 0xffff); +} +#endif + +#ifndef CONFIG_DM320_OSD0_DISABLE +static inline uint32_t dm320_osd0upperoffset(void) +{ + return (((dm320_physaddr(g_osd0base) / 32) >> 16) & 0xff); +} + +static inline uint32_t dm320_osd0loweroffset(void) +{ + return ((dm320_physaddr(g_osd0base) / 32) & 0xffff); +} +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE +static inline uint32_t dm320_osd1upperoffset(void) +{ + return (((dm320_physaddr(g_osd1base) / 32) >> 16) & 0xff); +} + +static inline uint32_t dm320_osd1loweroffset(void) +{ + return ((dm320_physaddr(g_osd1base) / 32) & 0xffff); +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * dm320_allocvideomemory + ****************************************************************************/ + +static int dm320_allocvideomemory(void) +{ +#ifndef CONFIG_DM320_VID0_DISABLE +#ifndef CONFIG_DM320_DISABLE_PINGPONG + g_vid0base = (FAR void *)kmm_malloc(2 * DM320_VID0_FBLEN); + g_vid0ppbase = (FAR char *)g_vid0base + DM320_VID0_FBLEN; +#else + g_vid0base = (FAR void *)kmm_malloc(DM320_VID0_FBLEN); +#endif + if (!g_vid0base) + { + goto errout; + } +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE + g_vid1base = (FAR void *)kmm_malloc(DM320_VID1_FBLEN); + if (!g_vid1base) + { + goto errout; + } +#endif + +#ifndef CONFIG_DM320_OSD0_DISABLE + g_osd0base = (FAR void *)kmm_malloc(DM320_OSD0_FBLEN); + if (!g_osd0base) + { + goto errout; + } +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE + g_osd1base = (FAR void *)kmm_malloc(DM320_OSD1_FBLEN); + if (!g_osd1base) + { + goto errout; + } +#endif + + return OK; + +errout: + dm320_freevideomemory(); + return -ENOMEM; +} + +/**************************************************************************** + * Name: dm320_freevideomemory + ****************************************************************************/ + +static void dm320_freevideomemory(void) +{ +#ifndef CONFIG_DM320_VID0_DISABLE + if (g_vid0base) + { + kmm_free(g_vid0base); + g_vid0base = NULL; +#ifndef CONFIG_DM320_DISABLE_PINGPONG + g_vid0ppbase = NULL; +#endif + } +#endif + +#ifndef CONFIG_DM320_VID1_DISABLE + if (g_vid1base != 0) + { + kmm_free(g_vid1base); + g_vid1base = NULL; + } +#endif + +#ifndef CONFIG_DM320_OSD0_DISABLE + if (g_osd0base != 0) + { + kmm_free(g_osd0base); + g_osd0base = NULL; + } +#endif + +#ifndef CONFIG_DM320_OSD1_DISABLE + if (g_osd1base != 0) + { + kmm_free(g_osd1base); + g_osd1base = NULL; + } +#endif +} + +/**************************************************************************** + * Name: dm320_disable + ****************************************************************************/ + +static void dm320_disable(void) +{ + /* Disable all planes */ + + gvdbg("Inactivate OSD:\n"); + + putreg16(0, DM320_OSD_OSDWIN0MD); /* Win0 mode = 0 (1:active) */ + putreg16(0, DM320_OSD_OSDWIN1MD); /* Win1 mode = 0 (1:active) */ + putreg16(0, DM320_OSD_RECTCUR); /* Rectangular cursor mode = 0 (1:active) */ + + gvdbg("DM320_OSD_OSDWIN0MD: %04x\n", getreg16(DM320_OSD_OSDWIN0MD)); + gvdbg("DM320_OSD_OSDWIN1MD: %04x\n", getreg16(DM320_OSD_OSDWIN1MD)); + gvdbg("DM320_OSD_RECTCUR: %04x\n", getreg16(DM320_OSD_RECTCUR)); +} + +/**************************************************************************** + * Name: dm320_hwinitialize + ****************************************************************************/ + +static void dm320_hwinitialize(void) +{ + /* Disable all planes */ + + dm320_disable(); + + /* Initialize the main video to correct the origin */ + + gvdbg("Setup main video origin:\n"); + + putreg16(CONFIG_DM320_BASEX, DM320_OSD_BASEPX); + putreg16(CONFIG_DM320_BASEY, DM320_OSD_BASEPY); + + gvdbg("DM320_OSD_BASEPX: %04x\n", getreg16(DM320_OSD_BASEPX)); + gvdbg("DM320_OSD_BASEPY: %04x\n", getreg16(DM320_OSD_BASEPY)); + + /* Set up the frame buffer address registers */ + + gvdbg("Setup framebuffer addresses:\n"); + + + putreg16(((dm320_osd1upperoffset() << 8) | + dm320_osd0upperoffset()), DM320_OSD_OSDWINADH); + putreg16(dm320_osd0loweroffset(), DM320_OSD_OSDWIN0ADL); + putreg16(dm320_osd1loweroffset(), DM320_OSD_OSDWIN1ADL); + + gvdbg("DM320_OSD_OSDWINADH: %04x\n", getreg16(DM320_OSD_OSDWINADH)); + gvdbg("DM320_OSD_OSDWIN0ADL: %04x\n", getreg16(DM320_OSD_OSDWIN0ADL)); + gvdbg("DM320_OSD_OSDWIN1ADL: %04x\n", getreg16(DM320_OSD_OSDWIN1ADL)); + + /* Set up VID WIN0 */ + +#if defined(CONFIG_DM320_VID0_DISABLE) || defined(CONFIG_DM320_VID1_DISABLE) + putreg16(((dm320_vid1upperoffset() << 8) | dm320_vid0upperoffset()), DM320_OSD_VIDWINADH); +#endif + +#ifndef CONFIG_DM320_VID0_DISABLE + gvdbg("Initialize video win0:\n"); + putreg16(dm320_vid0loweroffset(), DM320_OSD_VIDWIN0ADL); + + gvdbg("DM320_OSD_VIDWINADH: %04x\n", getreg16(DM320_OSD_VIDWINADH)); + gvdbg("DM320_OSD_VIDWIN0ADL: %04x\n", getreg16(DM320_OSD_VIDWIN0ADL)); + dm320_blankscreen((uint8_t *)g_vid0base, DM320_VID0_FBLEN); + +#ifndef CONFIG_DM320_DISABLE_PINGPONG + putreg16(dm320_vid0ppupperoffset(), DM320_OSD_PPVWIN0ADH); + putreg16(dm320_vid0pploweroffset(), DM320_OSD_PPVWIN0ADL); + + gvdbg("DM320_OSD_PPVWIN0ADH: %04x\n", getreg16(DM320_OSD_PPVWIN0ADH)); + gvdbg("DM320_OSD_PPVWIN0ADL: %04x\n", getreg16(DM320_OSD_PPVWIN0ADL)); + dm320_blankscreen((uint8_t *)g_vid0ppbase, DM320_VID0_FBLEN); +#endif + + putreg16(CONFIG_DM320_VID0_XPOS, DM320_OSD_VIDWIN0XP); + putreg16(CONFIG_DM320_VID0_YPOS, DM320_OSD_VIDWIN0YP); + putreg16((CONFIG_DM320_VID0_XRES >> 4), DM320_OSD_VIDWIN0OFST); + putreg16(CONFIG_DM320_VID0_XRES, DM320_OSD_VIDWIN0XL); + putreg16(CONFIG_DM320_VID0_YRES, DM320_OSD_VIDWIN0YL); + + gvdbg("DM320_OSD_VIDWIN0XP: %04x\n", getreg16(DM320_OSD_VIDWIN0XP)); + gvdbg("DM320_OSD_VIDWIN0YP: %04x\n", getreg16(DM320_OSD_VIDWIN0YP)); + gvdbg("DM320_OSD_VIDWIN0OFST: %04x\n", getreg16(DM320_OSD_VIDWIN0OFST)); + gvdbg("DM320_OSD_VIDWIN0XL: %04x\n", getreg16(DM320_OSD_VIDWIN0XL)); + gvdbg("DM320_OSD_VIDWIN0YL: %04x\n", getreg16(DM320_OSD_VIDWIN0YL)); +#endif + + /* Set up VID WIN1 */ + +#ifndef CONFIG_DM320_VID1_DISABLE + gvdbg("Initialize video win1:\n"); + putreg16(dm320_vid1loweroffset(), DM320_OSD_VIDWIN1ADL); + + gvdbg("DM320_OSD_VIDWINADH: %04x\n", getreg16(DM320_OSD_VIDWINADH)); + gvdbg("DM320_OSD_VIDWIN1ADL: %04x\n", getreg16(DM320_OSD_VIDWIN1ADL)); + dm320_blankscreen((uint8_t *)g_vid1base, DM320_VID1_FBLEN); + + putreg16(CONFIG_DM320_VID1_XPOS, DM320_OSD_VIDWIN1XP); + putreg16(CONFIG_DM320_VID1_XPOS, DM320_OSD_VIDWIN1YP); + putreg16((CONFIG_DM320_VID1_XRES >> 4), DM320_OSD_VIDWIN1OFST); + putreg16(CONFIG_DM320_VID1_XRES, DM320_OSD_VIDWIN1XL); + putreg16(CONFIG_DM320_VID1_YRES, DM320_OSD_VIDWIN1YL); + + gvdbg("DM320_OSD_VIDWIN1XP: %04x\n", getreg16(DM320_OSD_VIDWIN1XP)); + gvdbg("DM320_OSD_VIDWIN1YP: %04x\n", getreg16(DM320_OSD_VIDWIN1YP)); + gvdbg("DM320_OSD_VIDWIN1OFST: %04x\n", getreg16(DM320_OSD_VIDWIN1OFST)); + gvdbg("DM320_OSD_VIDWIN1XL: %04x\n", getreg16(DM320_OSD_VIDWIN1XL)); + gvdbg("DM320_OSD_VIDWIN1YL: %04x\n", getreg16(DM320_OSD_VIDWIN1YL)); +#endif + + putreg16(DM320_VIDMODE, DM320_OSD_VIDWINMD); + gvdbg("DM320_OSD_VIDWINMD: %04x\n", getreg16(DM320_OSD_VIDWINMD)); + + /* Set up OSD WIN0 */ + +#ifndef CONFIG_DM320_OSD0_DISABLE + gvdbg("Initialize OSD win0:\n"); + dm320_blankscreen((uint8_t *)g_osd0base, DM320_OSD0_FBLEN); + + putreg16(CONFIG_DM320_OSD0_XPOS, DM320_OSD_OSDWIN0XP); + putreg16(CONFIG_DM320_OSD0_YPOS, DM320_OSD_OSDWIN0YP); +#ifdef CONFIG_DM320_OSD1_RGB16 + putreg16((CONFIG_DM320_OSD0_XRES >> 4), DM320_OSD_OSDWIN0OFST); +#else + putreg16((CONFIG_DM320_OSD0_XRES >> 5), DM320_OSD_OSDWIN0OFST); +#endif + putreg16(CONFIG_DM320_OSD0_XRES, DM320_OSD_OSDWIN0XL); + putreg16(CONFIG_DM320_OSD0_YRES, DM320_OSD_OSDWIN0YL); + putreg16(INITIAL_OSD0MODE, DM320_OSD_OSDWIN0MD); + + gvdbg("DM320_OSD_OSDWIN0XP: %04x\n", getreg16(DM320_OSD_OSDWIN0XP)); + gvdbg("DM320_OSD_OSDWIN0YP: %04x\n", getreg16(DM320_OSD_OSDWIN0YP)); + gvdbg("DM320_OSD_OSDWIN0OFST: %04x\n", getreg16(DM320_OSD_OSDWIN0OFST)); + gvdbg("DM320_OSD_OSDWIN0XL: %04x\n", getreg16(DM320_OSD_OSDWIN0XL)); + gvdbg("DM320_OSD_OSDWIN0YL: %04x\n", getreg16(DM320_OSD_OSDWIN0YL)); + gvdbg("DM320_OSD_OSDWIN0MD: %04x\n", getreg16(DM320_OSD_OSDWIN0MD)); +#endif + + /* Set up OSD WIN1 */ + +#ifndef CONFIG_DM320_OSD1_DISABLE + gvdbg("Initialize OSD win1\n"); + dm320_blankscreen((uint8_t *)g_osd1base, DM320_OSD1_FBLEN); + + putreg16(CONFIG_DM320_OSD1_XPOS, DM320_OSD_OSDWIN1XP); + putreg16(CONFIG_DM320_OSD1_YPOS, DM320_OSD_OSDWIN1YP); +#ifdef CONFIG_DM320_OSD1_RGB16 + putreg16((CONFIG_DM320_OSD1_XRES >> 4), DM320_OSD_OSDWIN1OFST); +#else + putreg16((CONFIG_DM320_OSD1_XRES >> 5), DM320_OSD_OSDWIN1OFST); +#endif + putreg16(CONFIG_DM320_OSD1_XRES, DM320_OSD_OSDWIN1XL); + putreg16(CONFIG_DM320_OSD1_YRES, DM320_OSD_OSDWIN1YL); + putreg16(INITIAL_OSD1MODE, DM320_OSD_OSDWIN1MD); + + gvdbg("DM320_OSD_OSDWIN1XP: %04x\n", getreg16(DM320_OSD_OSDWIN1XP)); + gvdbg("DM320_OSD_OSDWIN1YP: %04x\n", getreg16(DM320_OSD_OSDWIN1YP)); + gvdbg("DM320_OSD_OSDWIN1OFST: %04x\n", getreg16(DM320_OSD_OSDWIN1OFST)); + gvdbg("DM320_OSD_OSDWIN1XL: %04x\n", getreg16(DM320_OSD_OSDWIN1XL)); + gvdbg("DM320_OSD_OSDWIN1YL: %04x\n", getreg16(DM320_OSD_OSDWIN1YL)); + gvdbg("DM320_OSD_OSDWIN1MD: %04x\n", getreg16(DM320_OSD_OSDWIN1MD)); +#endif + + /* Set up the rectangular cursor with defaults */ + +#ifdef CONFIG_FB_HWCURSOR + gdbg("Initialize rectangular cursor\n"); + + putreg16(0, DM320_OSD_CURXP); + putreg16(0, DM320_OSD_CURYP); + putreg16(CONFIG_DM320_RECTCURSOR_WIDTH, DM320_OSD_CURXL); + putreg16(CONFIG_DM320_RECTCURSOR_HEIGHT, DM320_OSD_CURYL); + + /* DM320_RECTCURSOR_SETUP: + * + * Bit 0: 0=rectangular cursor inactive 1=on 0 + * Bits 113: Vertical line height: {1,2,4,6,8,10,12,14} CONFIG_DM320_CURSORLINEHEIGHT + * 4:6: Horizontal line width: {1,4,8,16,20,24,28} CONFIG_DM320_CURSORLINEWIDTH + * 7: 0=ROM lookup table, 1=RAM lookup table 0 + * 8:15: Rectangular cursor color pallette address CONFIG_DM320_CURSORCLUT + */ + + putreg16(DM320_RECTCURSOR_SETUP, DM320_OSD_RECTCUR); + + gvdbg("DM320_OSD_CURXP: %04x\n", getreg16(DM320_OSD_CURXP)); + gvdbg("DM320_OSD_CURYP: %04x\n", getreg16(DM320_OSD_CURYP)); + gvdbg("DM320_OSD_CURXL: %04x\n", getreg16(DM320_OSD_CURXL)); + gvdbg("DM320_OSD_CURYL: %04x\n", getreg16(DM320_OSD_CURYL)); + gvdbg("DM320_OSD_RECTCUR: %04x\n", getreg16(DM320_OSD_RECTCUR)); +#endif + + /* Set main window to the hardware default state. That initial + * state is: + * + * FIELD SETTING + * Bits 0-7: background color clut CONFIG_DM320_BKGDCLUT + * Bit 8: background clut 0=ROM 1=RAM 0 + * Bit 9: field signal 0=normal 1=inverted 0 + * Bit 10: vid window H expansion: 1=x9/8 0 + * Bit 11: vid window V expansion: 1=x6/5 0 + * Bit 12: expansion filter 0=off 1=on 0 + * Bit 13: osd window H expansion: 1=x9/8 0 + * Bit 14: osd window V expansion: 1=x6/5 0 + * Bit 1515: 0=offset binary, 1=complement of 2 0 + */ + + putreg16(CONFIG_DM320_BKGDCLUT, DM320_OSD_OSDMODE); + gvdbg("DM320_OSD_OSDMODE: %04x\n", getreg16(DM320_OSD_OSDMODE)); +} + +/**************************************************************************** + * Name: dm320_getvid0videoinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_VID0_DISABLE +static int dm320_getvid0videoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !vinfo) + { + return -EINVAL; + } +#endif + + vinfo->fmt = FB_FMT_UYVY; + vinfo->xres = CONFIG_DM320_VID0_XRES; + vinfo->yres = CONFIG_DM320_VID0_YRES; + vinfo->nplanes = 1; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getvid0planeinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_VID0_DISABLE +static int dm320_getvid0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !pinfo) + { + return -EINVAL; + } +#endif + + pinfo->fbmem = g_vid0base; + pinfo->fblen = DM320_VID0_FBLEN; + pinfo->stride = DM320_VID0_STRIDE; + pinfo->bpp = DM320_VID0_BPP; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getvid1videoinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_VID1_DISABLE +static int dm320_getvid1videoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !vinfo) + { + return -EINVAL; + } +#endif + + vinfo->fmt = FB_FMT_UYVY; + vinfo->xres = CONFIG_DM320_VID1_XRES; + vinfo->yres = CONFIG_DM320_VID1_YRES; + vinfo->nplanes = 1; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getvid1planeinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_VID1_DISABLE +static int dm320_getvid1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !pinfo) + { + return -EINVAL; + } +#endif + + pinfo->fbmem = g_vid1base; + pinfo->fblen = DM320_VID1_FBLEN; + pinfo->stride = DM320_VID1_STRIDE; + pinfo->bpp = DM320_VID1_BPP; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getosd0osdeoinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_OSD0_DISABLE +static int dm320_getosd0videoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !vinfo) + { + return -EINVAL; + } +#endif + +#ifdef CONFIG_DM320_OSD0_RGB16 + vinfo->fmt = FB_FMT_RGB16_565; +#else + vinfo->fmt = FB_FMT_RGB8; +#endif + vinfo->xres = CONFIG_DM320_OSD0_XRES; + vinfo->yres = CONFIG_DM320_OSD0_YRES; + vinfo->nplanes = 1; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getosd0planeinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_OSD0_DISABLE +static int dm320_getosd0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !pinfo) + { + return -EINVAL; + } +#endif + + pinfo->fbmem = g_osd0base; + pinfo->fblen = DM320_OSD0_FBLEN; + pinfo->stride = DM320_OSD0_STRIDE; + pinfo->bpp = DM320_OSD0_BPP; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getosd1osdeoinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_OSD1_DISABLE +static int dm320_getosd1videoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !vinfo) + { + return -EINVAL; + } +#endif + +#ifdef CONFIG_DM320_OSD1_RGB16 + vinfo->fmt = FB_FMT_RGB16_565; +#else + vinfo->fmt = FB_FMT_RGB8; +#endif + vinfo->xres = CONFIG_DM320_OSD1_XRES; + vinfo->yres = CONFIG_DM320_OSD1_YRES; + vinfo->nplanes = 1; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getosd1planeinfo + ****************************************************************************/ + +#ifndef CONFIG_DM320_OSD1_DISABLE +static int dm320_getosd1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ +#ifdef CONFIG_DEBUG + if (!vtable || !pinfo) + { + return -EINVAL; + } +#endif + + pinfo->fbmem = g_osd1base; + pinfo->fblen = DM320_OSD1_FBLEN; + pinfo->stride = DM320_OSD1_STRIDE; + pinfo->bpp = DM320_OSD1_BPP; + return OK; +} +#endif + +/**************************************************************************** + * Name: dm320_getcmap + ****************************************************************************/ + +#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE)) +static int dm320_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap) +{ + /* I don't think the RAM clut is readable */ + + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: dm320_putcmap + ****************************************************************************/ + +#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE)) +static int dm320_putcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap) +{ + irqstate_t flags; + uint16_t regval; + uint8_t y; + uint8_t u; + uint8_t v; + int len + int i; + +#ifdef CONFIG_DEBUG + if (!vtable || !cmap || !cmap->read || !cmap->green || !cmap->blue) + { + return -EINVAL; + } +#endif + + flags = enter_critical_section(); + for (i = cmap.first, len = 0; i < 256 && len < cmap.len, i++, len++) + { + /* Convert the RGB to YUV */ + + nxgl_rgb2yuv(cmap->red[i], cmap->green[i], cmap->blue[i], &y, &u, &v); + + /* Program the CLUT */ + + while (getreg16(DM320_OSD_MISCCTL) & 0x8); + putreg16(((uint16_t)y) << 8 | uint16_t(u)), DM320_OSD_CLUTRAMYCB); + putreg16(((uint16_t)v << 8 | i), DM320_OSD_CLUTRAMCR); + } + + /* Select RAM clut */ + +#if !defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD0_RGB16) + regval = getreg16(DM320_OSD_OSDWIN0MD); + regval |= 0x1000; + putreg16(regval, DM320_OSD_OSDWIN0MD); +#endif + +#if !defined(CONFIG_DM320_OSD1_DISABLE) && !defined(CONFIG_DM320_OSD1_RGB16) + regval = getreg16(DM320_OSD_OSDWIN1MD); + regval |= 0x1000; + putreg16(regval, DM320_OSD_OSDWIN1MD); +#endif + + leave_critical_section(flags); + return 0; +} +#endif + +/**************************************************************************** + * Name: dm320_getcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int dm320_getcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_cursorattrib_s *attrib) +{ + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!vtable || !attrib) + { + return -EINVAL; + } +#endif + + flags = enter_critical_section(); + attrib->pos.x = getreg16(DM320_OSD_CURXP); + attrib->pos.y = getreg16(DM320_OSD_CURYP); + +#ifdef CONFIG_FB_HWCURSORSIZE + attrib->size.w = getreg16(DM320_OSD_CURXL); + attrib->size.h = getreg16(DM320_OSD_CURYL); +#endif + leave_critical_section(flags); + + attrib->mxsize.w = MAX_XRES; + attrib->mxsize.h = MAX_YRES; + + gvdbg("DM320_OSD_CURXP: %04x\n", attrib->pos.x); + gvdbg("DM320_OSD_CURYP: %04x\n", attrib->pos.y); +#ifdef CONFIG_FB_HWCURSORSIZE + gvdbg("DM320_OSD_CURXL: %04x\n", attrib->size.w); + gvdbg("DM320_OSD_CURYL: %04x\n", attrib->size.h); +#else + gvdbg("DM320_OSD_CURXL: %04x\n", getreg16(DM320_OSD_CURXL)); + gvdbg("DM320_OSD_CURYL: %04x\n", getreg16(DM320_OSD_CURYL)); +#endif + gvdbg("DM320_OSD_RECTCUR: %04x\n", getreg16(DM320_OSD_RECTCUR)); +} +#endif + +/**************************************************************************** + * Name: dm320_setcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int dm320_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_s *settings) +{ + irqstate_t flags; + uint16_t regval; + +#ifdef CONFIG_DEBUG + if (!vtable || !settings) + { + return -EINVAL; + } +#endif + + /* Set cursor position */ + + flags = enter_critical_section(); + if ((settings->flags & FB_CUR_SETPOSITION) != 0) + { + gvdbg("x=%d y=%d\n", settings->pos.x, settings->pos.y); + + if (settings->pos.x > MAX_YRES) + { + settings->pos.x = MAX_YRES; + } + + if (settings->pos.y > MAX_YRES) + { + settings->pos.y = MAX_YRES; + } + + putreg16(settings->pos.x, DM320_OSD_CURXP); + putreg16(settings->pos.y, DM320_OSD_CURYP); + } + +#ifdef CONFIG_FB_HWCURSORSIZE + if ((settings->flags & FB_CUR_SETSIZE) != 0) + { + gvdbg("h=%d w=%d\n", settings->size.h, settings->size.w); + + if (settings->size.w > MAX_YRES) + { + settings->size.w = MAX_YRES; + } + + if (settings->size.h > MAX_YRES) + { + settings->size.h = MAX_YRES; + } + + putreg16(settings->size.w, DM320_OSD_CURXL); + putreg16(settings->size.h, DM320_OSD_CURYL); + } +#endif + + regval = getreg16(DM320_OSD_RECTCUR); + if ((settings->flags & FB_CUR_ENABLE) != 0) + { + regval |= 1; + } + else + { + regval &= ~1; + } + + putreg16(regval, DM320_OSD_RECTCUR); + leave_critical_section(flags); + + gvdbg("DM320_OSD_CURXP: %04x\n", getreg16(DM320_OSD_CURXP)); + gvdbg("DM320_OSD_CURYP: %04x\n", getreg16(DM320_OSD_CURYP)); + gvdbg("DM320_OSD_CURXL: %04x\n", getreg16(DM320_OSD_CURXL)); + gvdbg("DM320_OSD_CURYL: %04x\n", getreg16(DM320_OSD_CURYL)); + gvdbg("DM320_OSD_RECTCUR: %04x\n", getreg16(DM320_OSD_RECTCUR)); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fbinitialize + * + * Description: + * Initialize the video hardware + * + ****************************************************************************/ + +int up_fbinitialize(void) +{ + int ret; + + gvdbg("Allocating framebuffers\n"); + ret = dm320_allocvideomemory(); + if (ret != 0) + { + gdbg("Failed to allocate video buffers\n"); + return ret; + } + + /* Initialize the hardware */ + + gvdbg("Initializing hardware\n"); + dm320_hwinitialize(); + return 0; +} + +/**************************************************************************** + * Name: up_fbgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video plane. + * + * Input parameters: + * None + * + * Returned value: + * Reference to the framebuffer object (NULL on failure) + * + ****************************************************************************/ + +FAR struct fb_vtable_s *up_fbgetvplane(int vplane) +{ + switch (vplane) + { +#ifndef CONFIG_DM320_VID0_DISABLE + case DM320_VIDWIN0: /* VID0 window */ + return &g_vid0vtable; +#endif +#ifndef CONFIG_DM320_VID1_DISABLE + case DM320_VIDWIN1: /* VID1 window */ + return &g_vid1vtable; +#endif +#ifndef CONFIG_DM320_OSD0_DISABLE + case DM320_OSDWIN0: /* OSD2 window */ + return &g_osd0vtable; +#endif +#ifndef CONFIG_DM320_OSD1_DISABLE + case DM320_OSDWIN1: /* OSD2 window */ + return &g_osd1vtable; +#endif + default: + break; + } + return NULL; +} + +/**************************************************************************** + * Name: up_fbteardown + ****************************************************************************/ + +void fb_teardown(void) +{ + /* Disable the hardware */ + + dm320_disable(); + + /* Free the video buffers */ + + dm320_freevideomemory(); +} diff --git a/arch/arm/src/dm320/dm320_gio.h b/arch/arm/src/dm320/dm320_gio.h new file mode 100644 index 0000000000000000000000000000000000000000..136e96118ce096717dda1ae61ba41fe3dbecd496 --- /dev/null +++ b/arch/arm/src/dm320/dm320_gio.h @@ -0,0 +1,176 @@ +/************************************************************************************ + * dm320/dm320_gio.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_DM320GIO_H +#define __DM320_DM320GIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include "up_arch.h" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* General I/O Registers */ + +#define DM320_GIO_DIR0 (DM320_PERIPHERALS_VADDR + 0x0580) /* GIO Direction Register 0 */ +#define DM320_GIO_DIR1 (DM320_PERIPHERALS_VADDR + 0x0582) /* GIO Direction Register 1 */ +#define DM320_GIO_DIR2 (DM320_PERIPHERALS_VADDR + 0x0584) /* GIO Direction Register 2 */ +#define DM320_GIO_INV0 (DM320_PERIPHERALS_VADDR + 0x0586) /* GIO Inversion Register 0 */ +#define DM320_GIO_INV1 (DM320_PERIPHERALS_VADDR + 0x0588) /* GIO Inversion Register 1 */ +#define DM320_GIO_INV2 (DM320_PERIPHERALS_VADDR + 0x058A) /* GIO Inversion Register 2 */ +#define DM320_GIO_BITSET0 (DM320_PERIPHERALS_VADDR + 0x058C) /* GIO Bit Set Register 0 */ +#define DM320_GIO_BITSET1 (DM320_PERIPHERALS_VADDR + 0x058E) /* GIO Bit Set Register 1 */ +#define DM320_GIO_BITSET2 (DM320_PERIPHERALS_VADDR + 0x0590) /* GIO Bit Set Register 2 */ +#define DM320_GIO_BITCLR0 (DM320_PERIPHERALS_VADDR + 0x0592) /* GIO Bit Clear Register 0 */ +#define DM320_GIO_BITCLR1 (DM320_PERIPHERALS_VADDR + 0x0594) /* GIO Bit Clear Register 1 */ +#define DM320_GIO_BITCLR2 (DM320_PERIPHERALS_VADDR + 0x0596) /* GIO Bit Clear Register 2 */ +#define DM320_GIO_IRQPORT (DM320_PERIPHERALS_VADDR + 0x0598) /* GIO IRQ Port Setting Register */ +#define DM320_GIO_IRQEDGE (DM320_PERIPHERALS_VADDR + 0x059A) /* GIO IRQ Edge Setting Register */ +#define DM320_GIO_CHAT0 (DM320_PERIPHERALS_VADDR + 0x059C) /* GIO Chatter Setting Register 0 */ +#define DM320_GIO_CHAT1 (DM320_PERIPHERALS_VADDR + 0x059E) /* GIO Chatter Setting Register 1 */ +#define DM320_GIO_CHAT2 (DM320_PERIPHERALS_VADDR + 0x05A0) /* GIO Chatter Setting Register 2 */ +#define DM320_GIO_NCHAT (DM320_PERIPHERALS_VADDR + 0x05A2) /* GIO Chatter Value Register */ +#define DM320_GIO_FSEL0 (DM320_PERIPHERALS_VADDR + 0x05A4) /* GIO Function Select Register 0 */ +#define DM320_GIO_FSEL1 (DM320_PERIPHERALS_VADDR + 0x05A6) /* GIO Function Select Register 1 */ +#define DM320_GIO_FSEL2 (DM320_PERIPHERALS_VADDR + 0x05A8) /* GIO Function Select Register 2 */ +#define DM320_GIO_FSEL3 (DM320_PERIPHERALS_VADDR + 0x05AA) /* GIO Function Select Register 3 */ + +/* Macros for GIO access */ + +#define _GIO_READ_REG(pin, reg0, reg1, reg2, bval) \ + do { \ + register uint32_t _reg; register int _pin; \ + if ((pin) < 16) { _reg = (reg0); _pin = (pin); } \ + else if ((pin) < 32) { _reg = (reg1); _pin = ((pin) - 16); } \ + else { _reg = (reg2); _pin = ((pin) - 32); } \ + bval = ((getreg16(_reg) & (1<<_pin)) != 0); \ + } + +#define _GIO_SET_REG(pin, reg0, reg1, reg2) \ + do { \ + register uint32_t _reg; register int _pin; \ + if ((pin) < 16) { _reg = (reg0); _pin = (pin); } \ + else if ((pin) < 32) { _reg = (reg1); _pin = ((pin) - 16); } \ + else { _reg = (reg2); _pin = ((pin) - 32); } \ + putreg16((getreg16(_reg) | (1 << _pin)), _reg); \ + } while (0) + +#define _GIO_CLEAR_REG(pin, reg0, reg1, reg2) \ + do { \ + register uint32_t _reg; register int _pin; \ + if ((pin) < 16) { _reg = (reg0); _pin = (pin); } \ + else if ((pin) < 32) { _reg = (reg1); _pin = ((pin) - 16); } \ + else { _reg = (reg2); _pin = ((pin) - 32); } \ + putreg16((getreg16(_reg) & ~(1 << _pin)), _reg); \ + } while (0) + +/* Select GIO input or output */ + +#define GIO_INPUT(pin) \ + _GIO_SET_REG((pin), DM320_GIO_DIR0, DM320_GIO_DIR1, DM320_GIO_DIR2) +#define GIO_OUTPUT(pin) \ + _GIO_CLEAR_REG((pin), DM320_GIO_DIR0, DM320_GIO_DIR1, DM320_GIO_DIR2) + +/* Select inverted or non-inverted GIO */ + +#define GIO_INVERTED(pin) \ + _GIO_SET_REG((pin), DM320_GIO_INV0, DM320_GIO_INV1, DM320_GIO_INV2) +#define GIO_NONINVERTED(pin) \ + _GIO_CLEAR_REG((pin), DM320_GIO_INV0, DM320_GIO_INV1, DM320_GIO_INV2) + +/* Set and clear outputs */ + +#define GIO_SET_OUTPUT(pin) \ + _GIO_SET_REG((pin), DM320_GIO_BITSET0, DM320_GIO_BITSET1, DM320_GIO_BITSET2) +#define GIO_CLEAR_OUTPUT(pin) \ + _GIO_SET_REG((pin), DM320_GIO_BITCLR0, DM320_GIO_BITCLR1, DM320_GIO_BITCLR2) + +/* Read input */ + +#define GIO_READ_INPUT(pin, bval) \ + _GIO_READ_REG((pin), DM320_GIO_BITSET0, DM320_GIO_BITSET1, DM320_GIO_BITSET2, (bval)) + +/* Configure GIO pins */ + +#define _GIO_SET_CONFIG(reg, sh, val) \ + putreg16(((getreg16(reg) & ~(3 << sh)) | (val << sh)), (reg)) + +#define GIO_CONFIGURE(pin, val) \ + do {\ + if ((pin) < 10) _GIO_SET_CONFIG(DM320_GIO_FSEL0, 0, (val)); \ + else if ((pin) < 17) _GIO_SET_CONFIG(DM320_GIO_FSEL0, 2*((pin)-9), (val)); \ + else if ((pin) < 25) _GIO_SET_CONFIG(DM320_GIO_FSEL1, 2*((pin)-17), (val)); \ + else if ((pin) < 33) _GIO_SET_CONFIG(DM320_GIO_FSEL2, 2*((pin)-25), (val)); \ + else _GIO_SET_CONFIG(DM320_GIO_FSEL3, 2*((pin)-33), (val)); \ + } + +/* Configure GIO interrupts (pins 1-15) */ + +#define GIO_INTERRUPT(pin) \ + if (pin < 16) putreg16((getreg16(DM320_GIO_IRQPORT) | (1<<(pin))), DM320_GIO_IRQPORT) +#define GIO_NONINTERRUPT(pin) \ + if (pin < 16) putreg16((getreg16(DM320_GIO_IRQPORT) & ~(1<<(pin))), DM320_GIO_IRQPORT) +#define GIO_FALLINGEDGE(pin) \ + if (pin < 16) { \ + putreg16((getreg16(DM320_GIO_IRQEDGE) & ~(1<<(pin))), DM320_GIO_IRQEDGE) \ + putreg16((getreg16(DM320_GIO_INV0) & ~(1<<(pin))), DM320_GIO_INV0); \ + } +#define GIO_RISINGEDGE(pin) \ + if (pin < 16) { \ + putreg16((getreg16(DM320_GIO_IRQEDGE) & ~(1<<(pin))), DM320_GIO_IRQEDGE); \ + putreg16((getreg16(DM320_GIO_INV0) | (1<<(pin))), DM320_GIO_INV0); \ + } +#define GIO_BOTHEDGES(pin) \ + if (pin < 16) { \ + putreg16((getreg16(DM320_GIO_IRQEDGE) | (1<<(pin))), DM320_GIO_IRQEDGE); \ + putreg16((getreg16(DM320_GIO_INV0) & ~(1<<(pin))), DM320_GIO_INV0); \ + } + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif + +#endif /* __DM320_DM320_GIO_H */ diff --git a/arch/arm/src/dm320/dm320_intc.h b/arch/arm/src/dm320/dm320_intc.h new file mode 100644 index 0000000000000000000000000000000000000000..f05febb2f953ac5a118f0e6e5f23da64700cf27c --- /dev/null +++ b/arch/arm/src/dm320/dm320_intc.h @@ -0,0 +1,101 @@ +/************************************************************************************ + * dm320/dm320_intc.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_DM320_INTC_H +#define __DM320_DM320_INTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Interrupt Controller Registers */ + +#define DM320_INTC_FIQ0 (DM320_PERIPHERALS_VADDR + 0x0500) /* FIQ Interrupt Flag Register #0 */ +#define DM320_INTC_FIQ1 (DM320_PERIPHERALS_VADDR + 0x0502) /* FIQ Interrupt Flag Register #1 */ +#define DM320_INTC_FIQ2 (DM320_PERIPHERALS_VADDR + 0x0504) /* FIQ Interrupt Flag Register #2 */ +#define DM320_INTC_IRQ0 (DM320_PERIPHERALS_VADDR + 0x0508) /* IRQ Interrupt Flag Register #0 */ +#define DM320_INTC_IRQ1 (DM320_PERIPHERALS_VADDR + 0x050A) /* IRQ Interrupt Flag Register #1 */ +#define DM320_INTC_IRQ2 (DM320_PERIPHERALS_VADDR + 0x050C) /* IRQ Interrupt Flag Register #2 */ +#define DM320_INTC_FIQENTRY0 (DM320_PERIPHERALS_VADDR + 0x0510) /* FIQ Entry Address Register #0 */ +#define DM320_INTC_FIQENTRY1 (DM320_PERIPHERALS_VADDR + 0x0512) /* FIQ Entry Address Register #1 */ +#define DM320_INTC_FIQENTLCK0 (DM320_PERIPHERALS_VADDR + 0x0514) /* FIQ Lock Entry Address Register #1 */ +#define DM320_INTC_FIQENTLCK1 (DM320_PERIPHERALS_VADDR + 0x0516) /* FIQ Lock Entry Address Register #1 */ +#define DM320_INTC_IRQENTRY0 (DM320_PERIPHERALS_VADDR + 0x0518) /* IRQ Entry Address Register #0 */ +#define DM320_INTC_IRQENTRY1 (DM320_PERIPHERALS_VADDR + 0x051A) /* IRQ Entry Address Register #1 */ +#define DM320_INTC_IRQENTLCK0 (DM320_PERIPHERALS_VADDR + 0x051C) /* IRQ Lock Entry Address Register #1 */ +#define DM320_INTC_IRQENTLCK1 (DM320_PERIPHERALS_VADDR + 0x051E) /* Lock Entry Address Register #1 */ +#define DM320_INTC_FISEL0 (DM320_PERIPHERALS_VADDR + 0x0520) /* FIQ select register #0 */ +#define DM320_INTC_FISEL1 (DM320_PERIPHERALS_VADDR + 0x0522) /* FIQ select register #1 */ +#define DM320_INTC_FISEL2 (DM320_PERIPHERALS_VADDR + 0x0524) /* FIQ select register #2 */ +#define DM320_INTC_EINT0 (DM320_PERIPHERALS_VADDR + 0x0528) /* Interrupt Enable Register #0 */ +#define DM320_INTC_EINT1 (DM320_PERIPHERALS_VADDR + 0x052A) /* Interrupt Enable Register #1 */ +#define DM320_INTC_EINT2 (DM320_PERIPHERALS_VADDR + 0x052C) /* Interrupt Enable Register #2 */ +#define DM320_INTC_INTRAW (DM320_PERIPHERALS_VADDR + 0x0530) /* Interrupt Raw Register */ +#define DM320_INTC_EABASE0 (DM320_PERIPHERALS_VADDR + 0x0538) /* Entry Table Base Address Register #0 */ +#define DM320_INTC_EABASE1 (DM320_PERIPHERALS_VADDR + 0x053A) /* Entry Table Base Address Register #1 */ +#define DM320_INTC_INTPRI00 (DM320_PERIPHERALS_VADDR + 0x0540) /* Interrupt Priority Register #0 */ +#define DM320_INTC_INTPRI01 (DM320_PERIPHERALS_VADDR + 0x0542) /* Interrupt Priority Register #1 */ +#define DM320_INTC_INTPRI02 (DM320_PERIPHERALS_VADDR + 0x0544) /* Interrupt Priority Register #2 */ +#define DM320_INTC_INTPRI03 (DM320_PERIPHERALS_VADDR + 0x0546) /* Interrupt Priority Register #3 */ +#define DM320_INTC_INTPRI04 (DM320_PERIPHERALS_VADDR + 0x0548) /* Interrupt Priority Register #4 */ +#define DM320_INTC_INTPRI05 (DM320_PERIPHERALS_VADDR + 0x054A) /* Interrupt Priority Register #5 */ +#define DM320_INTC_INTPRI06 (DM320_PERIPHERALS_VADDR + 0x054C) /* Interrupt Priority Register #6 */ +#define DM320_INTC_INTPRI07 (DM320_PERIPHERALS_VADDR + 0x054E) /* Interrupt Priority Register #7 */ +#define DM320_INTC_INTPRI08 (DM320_PERIPHERALS_VADDR + 0x0550) /* Interrupt Priority Register #8 */ +#define DM320_INTC_INTPRI09 (DM320_PERIPHERALS_VADDR + 0x0552) /* Interrupt Priority Register #9 */ +#define DM320_INTC_INTPRI10 (DM320_PERIPHERALS_VADDR + 0x0554) /* Interrupt Priority Register #10 */ +#define DM320_INTC_INTPRI11 (DM320_PERIPHERALS_VADDR + 0x0556) /* Interrupt Priority Register #11 */ +#define DM320_INTC_INTPRI12 (DM320_PERIPHERALS_VADDR + 0x0558) /* Interrupt Priority Register #12 */ +#define DM320_INTC_INTPRI13 (DM320_PERIPHERALS_VADDR + 0x055A) /* Interrupt Priority Register #13 */ +#define DM320_INTC_INTPRI14 (DM320_PERIPHERALS_VADDR + 0x055C) /* Interrupt Priority Register #14 */ +#define DM320_INTC_INTPRI15 (DM320_PERIPHERALS_VADDR + 0x055E) /* Interrupt Priority Register #15 */ +#define DM320_INTC_INTPRI16 (DM320_PERIPHERALS_VADDR + 0x0560) /* Interrupt Priority Register #16 */ +#define DM320_INTC_INTPRI17 (DM320_PERIPHERALS_VADDR + 0x0562) /* Interrupt Priority Register #17 */ +#define DM320_INTC_INTPRI18 (DM320_PERIPHERALS_VADDR + 0x0564) /* Interrupt Priority Register #18 */ +#define DM320_INTC_INTPRI19 (DM320_PERIPHERALS_VADDR + 0x0566) /* Interrupt Priority Register #19 */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif + +#endif /* __DM320_DM320_INTC_H */ diff --git a/arch/arm/src/dm320/dm320_irq.c b/arch/arm/src/dm320/dm320_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..e7bfff04bbc91cce76996779271cb7684640a5bd --- /dev/null +++ b/arch/arm/src/dm320/dm320_irq.c @@ -0,0 +1,241 @@ +/**************************************************************************** + * arch/arm/src/dm320/dm320_irq.c + * + * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "arm.h" +#include "chip.h" + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The value of _svectors is defined in ld.script. It could be hard- + * coded because we know that correct IRAM area is 0xffc00000. + */ + +extern int _svectors; /* Type does not matter */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Clear, disable and configure all interrupts. */ + + putreg16(0, DM320_INTC_EINT0); /* Mask all IRQs/FIQs */ + putreg16(0, DM320_INTC_EINT1); + putreg16(0, DM320_INTC_EINT2); + + putreg16(0, DM320_INTC_INTRAW); /* No masked interrupts in status */ + + putreg16(0, DM320_INTC_FISEL0); /* No FIQs */ + putreg16(0, DM320_INTC_FISEL1); + putreg16(0, DM320_INTC_FISEL2); + + putreg16(0xffff, DM320_INTC_FIQ0); /* Clear all pending FIQs */ + putreg16(0xffff, DM320_INTC_FIQ1); + putreg16(0xffff, DM320_INTC_FIQ2); + + putreg16(0xffff, DM320_INTC_IRQ0); /* Clear all pending IRQs */ + putreg16(0xffff, DM320_INTC_IRQ1); + putreg16(0xffff, DM320_INTC_IRQ2); + + /* Make sure that the base addresses are zero and that + * the table increment is 4 bytes. + */ + + putreg16(0, DM320_INTC_EABASE0); + putreg16(0, DM320_INTC_EABASE1); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* Disable the interrupt by clearing the corresponding bit in + * the IRQ enable register. + */ + + if (irq < 16) + { + /* IRQs0-15 are controlled by the IRQ0 enable register + * Clear the associated bit to disable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT0) & ~(1 << irq)), DM320_INTC_EINT0); + } + else if (irq < 32) + { + /* IRQs16-31 are controlled by the IRQ1 enable register + * Clear the associated bit to disable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT1) & ~(1 << (irq-16))), DM320_INTC_EINT1); + } + else + { + /* IRQs32- are controlled by the IRQ2 enable register + * Clear the associated bit to disable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT2) & ~(1 << (irq-32))), DM320_INTC_EINT2); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* Enable the interrupt by setting the corresponding bit in + * the IRQ enable register. + */ + + if (irq < 16) + { + /* IRQs0-15 are controlled by the IRQ0 enable register + * Set the associated bit to enable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT0) | (1 << irq)), DM320_INTC_EINT0); + } + else if (irq < 32) + { + /* IRQs16-31 are controlled by the IRQ1 enable register + * Set the associated bit to enable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT1) | (1 << (irq-16))), DM320_INTC_EINT1); + } + else + { + /* IRQs32- are controlled by the IRQ2 enable register + * Set the associated bit to enable the interrupt + */ + + putreg16((getreg16(DM320_INTC_EINT2) | (1 << (irq-32))), DM320_INTC_EINT2); + } +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + /* Acknowlege the interrupt by setting the corresponding bit in the + * IRQ status register. + */ + + if (irq < 16) + { + /* Set the associated status bit to clear the interrupt */ + + putreg16((1 << irq), DM320_INTC_IRQ0); + } + else if (irq < 32) + { + /* Set the associated status bit to clear the interrupt */ + + putreg16((1 << (irq-16)), DM320_INTC_IRQ1); + } + else + { + /* Set the associated status bit to clear the interrupt */ + + putreg16((1 << (irq-32)), DM320_INTC_IRQ2); + } +} diff --git a/arch/arm/src/dm320/dm320_lowputc.S b/arch/arm/src/dm320/dm320_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..8df578bb3314b1d97dab4bea0e2418f708121905 --- /dev/null +++ b/arch/arm/src/dm320/dm320_lowputc.S @@ -0,0 +1,130 @@ +/************************************************************************** + * arch/arm/src/dm320/dm320_lowputc.S + * arch/arm/src/chip/dm320_lowputc.S + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + ldr r2, =DM320_UART1_REGISTER_BASE /* r2=UART1 base */ +#else + ldr r2, =DM320_UART0_REGISTER_BASE /* r2=UART0 base */ +#endif + + /* Poll the TX fifo trigger level bit of the UART_SSR + * register. When the bit is non-zero, the TX FIFO is no + * longer full + */ + +1: ldrh r1, [r2, #UART_SR] + tst r1, #UART_SR_TFTI + beq 1b + + /* Send the character by writing it into the UART_DTRR + * register. + */ + + strh r0, [r2, #UART_DTRR] + + /* Wait for the tranmsit regiser to be emptied. This is + * detemined when TX register empty bit of the SR is zero. + */ + +2: ldrh r1, [r2, #UART_SR] + tst r1, #UART_SR_TREF + bne 2b + + /* If the character that we just sent was a linefeed, + * then send a carriage return as well. + */ + + teq r0, #'\n' + moveq r0, #'\r' + beq 1b + + /* And return */ + + mov pc, lr + diff --git a/arch/arm/src/dm320/dm320_memorymap.h b/arch/arm/src/dm320/dm320_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..67923b1507403702bb105d53b86f023431882150 --- /dev/null +++ b/arch/arm/src/dm320/dm320_memorymap.h @@ -0,0 +1,264 @@ +/************************************************************************************ + * dm320/dm320_memorymap.h + * + * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_MEMORYMAP_H +#define __DM320_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "arm.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Mapped base of all registers *****************************************************/ + +/* DM320 Physical Memory Map, where: + * + * CW = cachable with write buffering + * -W = Write buffering only + * -- = Neither + * + * NOTE: + * 1. Most DM320 memory sections can be programmed to lie at different locations in + * the memory map. Therefore, much of the DM320 physical memory map is really + * board-specific and, as such, really belongs in the configs//include/board.h + * file rather than here. + * + * To handle all cases, this file defines a "default" physical memory map, but + * section address for most regions can be overriden if the same setting is + * defined in the board.h file (These defaults correspond to the product Neuros + * OSD memory configuration). + * + * 2. The DM320 only has a single control line for external peripherals. To support + * more than one peripheral, most hardware will use external memory decode logic, + * so that physical memory regions is in the board-specific files. + */ + +/* Section/Region Name Phys Address Size TLB Enty CW */ +#define DM320_PERIPHERALS_PSECTION 0x00000000 /* 1Mb 1 section -- */ +#define DM320_IRAM_PADDR 0x00000000 /* 16Kb 1 large page CW */ +#define DM320_PERIPHERALS_PADDR 0x00030000 /* 4Kb 1 small pages -- */ +#define DM320_DSP_ONCHIP_RAM_PADDR 0x00040000 /* 128Kb 1 large page -- */ +#define DM320_AHB_PADDR 0x00060000 /* 4Kb 1 small page -- */ +#define DM320_COPRO_SUB_PADDR 0x00080000 /* 128Kb -- */ + +#ifndef DM320_FLASH_PSECTION +# define DM320_FLASH_PSECTION 0x00100000 /* 16Mb many sections -- */ +# define DM320_EXT_MEM_PADDR 0x00100000 /* 16Mb flash -- */ +#endif +#ifndef DM320_FLASH_PSECTION +# define DM320_SDRAM_PSECTION 0x01100000 /* 496Mb many section -- */ +# define DM320_SDRAM_PADDR 0x01100000 /* 496Mb many sections CW */ +#endif +#ifndef DM320_CFI_PSECTION +# define DM320_CFI_PSECTION 0x40000000 /* 16Mb 16 sections -- */ +# define DM320_CFI_PADDR 0x40000000 /* 16Mb 16 sections -- */ +#endif +#ifndef DM320_SSFDC_PSECTION +# define DM320_SSFDC_PSECTION 0x48000000 /* 16Mb 16 sections -- */ +# define DM320_SSFDC_PADDR 0x48000000 /* 16Mb 16 sections -- */ +#endif +#ifndef DM320_CE1_PSECTION +# define DM320_CE1_PSECTION 0x50000000 /* 16Mb 16 sections -- */ +# define DM320_CE1_PADDR 0x50000000 /* 16Mb 16 sections -- */ +#endif +#ifndef DM320_CE2_PSECTION +# define DM320_CE2_PSECTION 0x60000000 /* 16Mb 16 sections -- */ +# define DM320_CE2_PADDR 0x60000000 /* 16Mb 16 sections -- */ +#endif + +#define DM320_VLYNQ_PSECTION 0x70000000 /* 64MB 64 sections -- */ +#define DM320_VLYNQ_PADDR 0x70000000 /* 64MB 64 sections -- */ +#define DM320_USBOTG_PSECTION 0x80000000 /* 1Mb 1 section -- */ +#define DM320_USBOTG_PADDR 0x80000000 /* 1Kb 1 small page -- */ + +/* Sizes of sections/regions */ + +/* Section / Region Name Size */ +#define DM320_PERIPHERALS_NSECTIONS 1 /* 1Mb 1 section -- */ +#define DM320_IRAM_SIZE (16*1024) +#define DM320_PERIPHERALS_SIZE (4*1024) +#define DM320_DSP_ONCHIP_RAM_SIZE (128*1024) +#define DM320_AHB_SIZE (4*1024) +#define DM320_COPRO_SUB_SIZE (128*1024) +#define DM320_FLASH_NSECTIONS 16 /* 16Mb 16 sections -- */ +#define DM320_EXT_MEM_SIZE (16*1024*1024) +#define DM320_CFI_NSECTIONS 16 /* 16Mb 16 sections -- */ +#define DM320_CFI_SIZE (16*1024*1024) +#define DM320_SSFDC_NSECTIONS 16 /* 16Mb 16 sections -- */ +#define DM320_SSFDC_SIZE (16*1024*1024) +#define DM320_CE1_NSECTIONS 16 /* 16Mb 16 sections -- */ +#define DM320_CE1_SIZE (16*1024*1024) +#define DM320_CE2_NSECTIONS 16 /* 16Mb 16 sections -- */ +#define DM320_CE2_SIZE (16*1024*1024) +#define DM320_VLYNQ_NSECTIONS 64 /* 64MB 64 sections -- */ +#define DM320_VLYNQ_SIZE (64*1024*1024) +#define DM320_USBOTG_NSECTIONS 1 /* 1Mb 1 section -- */ +#define DM320_USBOTG_SIZE (1024) + +/* DM320 Virtual Memory Map */ + +#if CONFIG_RAM_VSTART != 0x00000000 +# error "Invalid setting for CONFIG_RAM_VSTART" +#endif + +/* Section/Region Name Virt Address End Size CW */ +#define DM320_SDRAM_VSECTION 0x00000000 /* 0x1effffff 496Mb CW */ +#define DM320_SDRAM_VADDR 0x00000000 /* 0x1effffff 496Mb CW */ + /* 0x1f000000 0xdfffffff UNMAPPED */ +#define DM320_FLASH_VSECTION 0xc0000000 /* 0xc0ffffff 16Mb -- */ +#define DM320_EXT_MEM_VADDR 0xc0000000 /* 0xc0ffffff 16Mb -- */ +#define DM320_CFI_VSECTION 0xc4000000 /* 0xc4ffffff 16Mb -- */ +#define DM320_CFI_VADDR 0xc4000000 /* 0xc4ffffff 16Mb -- */ +#define DM320_SSFDC_VSECTION 0xc8000000 /* 0xc8ffffff 16Mb -- */ +#define DM320_SSFDC_VADDR 0xc8000000 /* 0xc8ffffff 16Mb -- */ +#define DM320_CE1_VSECTION 0xcc000000 /* 0xccffffff 16Mb -- */ +#define DM320_CE1_VADDR 0xcc000000 /* 0xccffffff 16Mb -- */ +#define DM320_CE2_VSECTION 0xd0000000 /* 0xd0ffffff 16Mb -- */ +#define DM320_CE2_VADDR 0xd0000000 /* 0xd0ffffff 16Mb -- */ +#define DM320_USBOTG_VSECTION 0xd4000000 /* 0xd40fffff 1Mb -- */ +#define DM320_USBOTG_VADDR 0xd4000000 /* 0xd40003ff 1Kb -- */ +#define DM320_VLYNQ_VSECTION 0xe0000000 /* 0xefffffff 64Mb -- */ +#define DM320_VLYNQ_VADDR 0xe0000000 /* 0xefffffff 64Mb -- */ +#define DM320_PERIPHERALS_VSECTION 0xf0000000 /* 0xf00fffff 1Mb -- */ +#define DM320_IRAM_VADDR 0xf0000000 /* 0xf0003fff 16Kb -- */ +#define DM320_PERIPHERALS_VADDR 0xf0030000 /* 0xf0030fff 4Kb -- */ +#define DM320_DSP_ONCHIP_RAM_VADDR 0xf0040000 /* 0xf005ffff 128Kb -- */ +#define DM320_AHB_VADDR 0xf0060000 /* 0xf0060fff 4Kb -- */ +#define DM320_COPRO_SUB_VADDR 0xf0080000 /* 0xf009ffff 128Kb -- */ + /* 0xf0100000 0xffefffff UNMAPPED */ +#define DM320_VECTOR_VCOARSE 0xfff00000 /* 0xffffffff 1Mb -- */ + /* 0xfff00000 0xfffeffff UNMAPPED */ +#define DM320_VECTOR_VADDR 0xffff0000 /* 0xffff3fff 16Kb -- */ + /* 0xffff4000 0xffffffff UNMAPPED */ + +/* The NuttX entry point starts at an offset from the virtual beginning of DRAM. + * This offset reserves space for the MMU page cache. + */ + +#define NUTTX_START_VADDR (DM320_SDRAM_VADDR+PGTABLE_SIZE) +#define NUTTX_START_PADDR (DM320_SDRAM_PADDR+PGTABLE_SIZE) + +/* Section MMU Flags Flags CW */ +#define DM320_FLASH_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_CFI_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_SSFDC_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_CE1_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_CE2_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_VLYNQ_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_USBOTG_MMUFLAGS MMU_IOFLAGS /* -- */ +#define DM320_PERIPHERALS_MMUFLAGS MMU_IOFLAGS /* -- */ + +/* 16Kb of memory is reserved at the beginning of SDRAM to hold the + * page table for the virtual mappings. A portion of this table is + * not accessible in the virtual address space (for normal operation). + * We will reuse this memory for coarse page tables as follows: + * FIXME! Where does that 0x00000800 come from. I can't remember + * and it does not feel right! + */ + +#define PGTABLE_BASE_PADDR DM320_SDRAM_PADDR +#define PGTABLE_SDRAM_PADDR PGTABLE_BASE_PADDR +#define PGTABLE_L2_COARSE_PBASE (PGTABLE_BASE_PADDR+0x00000800) +#define PGTABLE_L2_FINE_PBASE (PGTABLE_BASE_PADDR+0x00001000) +#define PGTABLE_L2_END_PADDR (PGTABLE_BASE_PADDR+PGTABLE_SIZE) + +#define PGTABLE_BASE_VADDR DM320_SDRAM_VADDR +#define PGTABLE_SDRAM_VADDR PGTABLE_BASE_VADDR +#define PGTABLE_L2_COARSE_VBASE (PGTABLE_BASE_VADDR+0x00000800) +#define PGTABLE_L2_FINE_VBASE (PGTABLE_BASE_VADDR+0x00001000) +#define PGTABLE_L2_END_VADDR (PGTABLE_BASE_VADDR+PGTABLE_SIZE) + +/* Page table sizes */ + +#define PGTABLE_L2_COARSE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_COARSE_VBASE) +#define PGTABLE_COARSE_TABLE_SIZE (4*256) +#define PGTABLE_NCOARSE_TABLES (PGTABLE_L2_COARSE_ALLOC / PGTABLE_COARSE_TABLE_SIZE) + +#define PGTABLE_L2_FINE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_FINE_VBASE) +#define PGTABLE_FINE_TABLE_SIZE (4*1024) +#define PGTABLE_NFINE_TABLES (PGTABLE_L2_FINE_ALLOC / PGTABLE_FINE_TABLE_SIZE) + +/* This is the base address of the interrupt vectors on the ARM926 */ + +#define VECTOR_BASE DM320_VECTOR_VADDR + +/* DM320 Peripheral Registers */ + +#define DM320_TIMER0_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0000) /* Timer 0 */ +#define DM320_TIMER1_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0080) /* Timer 1 */ +#define DM320_TIMER2_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0100) /* Timer 2 */ +#define DM320_TIMER3_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0180) /* Timer 3 */ +#define DM320_SERIAL0_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0200) /* Serial port 0 */ +#define DM320_SERIAL1_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0280) /* Serial port 1 */ +#define DM320_UART0_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0300) /* UART 0 */ +#define DM320_UART1_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0380) /* UART 1 */ +#define DM320_WDT_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0400) /* Watchdog timer */ +#define DM320_MMCSD_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0480) /* MMC/SD */ +#define DM320_INTC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0500) /* Interrupt controller */ +#define DM320_GIO_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0580) /* GIO */ +#define DM320_DSPC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0600) /* DSP controller */ +#define DM320_OSD_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0680) /* OSD */ +#define DM320_CCDC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0700) /* CCD controller */ +#define DM320_VENC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0800) /* Video encoder */ +#define DM320_CLKC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0880) /* Clock controller */ +#define DM320_BUSC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0900) /* Bus controller */ +#define DM320_SDRAMC_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0980) /* SDRAM controller */ +#define DM320_EMIF_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0A00) /* External memory interface */ +#define DM320_PREV_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0A80) /* Preview engine */ +#define DM320_AF_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0B80) /* Hardware 3A (AF/AE/AWB) */ +#define DM320_MSTICK_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0C80) /* Memory stick */ +#define DM320_I2C_REGISTER_BASE (DM320_PERIPHERALS_VADDR + 0x0D80) /* I2C */ +#define DM320_USB_REGISTER_BASE (DM320_USBOTG_VADDR + 0x0000) /* USB full speed OTG */ +#define DM320_USBDMA_REGISTER_BASE (DM320_USBOTG_VADDR + 0x0200) /* USB DMA */ +#define DM320_VLYNQ_REGISTER_BASE (DM320_AHB_VADDR + 0x0300) /* VLYNQ */ +#define DM320_AHBBUSC_REGISTER_BASE (DM320_AHB_VADDR + 0x0F00) /* AHBBUSC */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif + +#endif /* __DM320_MEMORYMAP_H */ diff --git a/arch/arm/src/dm320/dm320_osd.h b/arch/arm/src/dm320/dm320_osd.h new file mode 100644 index 0000000000000000000000000000000000000000..199651e6929b51f1def9280ccad5d8a139dafc8d --- /dev/null +++ b/arch/arm/src/dm320/dm320_osd.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * dm320/dm320_osd.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_DM320_DM320_OSD_H +#define __ARCH_ARM_SRC_DM320_DM320_OSD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* On Screen Display Register Map (OSD) *********************************************/ + +#define DM320_OSD_OSDMODE (DM320_OSD_REGISTER_BASE+0x0000) /* OSD Mode Setup */ +#define DM320_OSD_VIDWINMD (DM320_OSD_REGISTER_BASE+0x0002) /* Video Window Mode Setup */ +#define DM320_OSD_OSDWIN0MD (DM320_OSD_REGISTER_BASE+0x0004) /* OSD Window 0 Mode Setup */ +#define DM320_OSD_OSDWIN1MD (DM320_OSD_REGISTER_BASE+0x0006) /* OSD Window 1 Mode Setup */ +#define DM320_OSD_OSDATRMD (DM320_OSD_REGISTER_BASE+0x0006) /* OSD Attribute Window Mode Setup */ +#define DM320_OSD_RECTCUR (DM320_OSD_REGISTER_BASE+0x0008) /* Rectangular Cursor Setup */ +#define DM320_OSD_VIDWIN0OFST (DM320_OSD_REGISTER_BASE+0x000c) /* Video Window 0 Offset */ +#define DM320_OSD_VIDWIN1OFST (DM320_OSD_REGISTER_BASE+0x000e) /* Video Window 1 Offset */ +#define DM320_OSD_OSDWIN0OFST (DM320_OSD_REGISTER_BASE+0x0010) /* OSD Window 0 Offset */ +#define DM320_OSD_OSDWIN1OFST (DM320_OSD_REGISTER_BASE+0x0012) /* OSD Window 1 Offset */ +#define DM320_OSD_VIDWINADH (DM320_OSD_REGISTER_BASE+0x0014) /* Video Window 0/1 Address - High */ +#define DM320_OSD_VIDWIN0ADL (DM320_OSD_REGISTER_BASE+0x0016) /* Video Window 0 Address - Low */ +#define DM320_OSD_VIDWIN1ADL (DM320_OSD_REGISTER_BASE+0x0018) /* Video Window 1 Address - Low */ +#define DM320_OSD_OSDWINADH (DM320_OSD_REGISTER_BASE+0x001a) /* OSD Window 0/1 Address - High */ +#define DM320_OSD_OSDWIN0ADL (DM320_OSD_REGISTER_BASE+0x001c) /* OSD Window 0 Address - Low */ +#define DM320_OSD_OSDWIN1ADL (DM320_OSD_REGISTER_BASE+0x001e) /* OSD Window 1 Address - Low */ +#define DM320_OSD_BASEPX (DM320_OSD_REGISTER_BASE+0x0020) /* Base Pixel X */ +#define DM320_OSD_BASEPY (DM320_OSD_REGISTER_BASE+0x0022) /* Base Pixel Y */ +#define DM320_OSD_VIDWIN0XP (DM320_OSD_REGISTER_BASE+0x0024) /* Video Window 0 X-Position */ +#define DM320_OSD_VIDWIN0YP (DM320_OSD_REGISTER_BASE+0x0026) /* Video Window 0 Y-Position */ +#define DM320_OSD_VIDWIN0XL (DM320_OSD_REGISTER_BASE+0x0028) /* Video Window 0 X-Size */ +#define DM320_OSD_VIDWIN0YL (DM320_OSD_REGISTER_BASE+0x002a) /* Video Window 0 Y-Size */ +#define DM320_OSD_VIDWIN1XP (DM320_OSD_REGISTER_BASE+0x002c) /* Video Window 1 X-Position */ +#define DM320_OSD_VIDWIN1YP (DM320_OSD_REGISTER_BASE+0x002e) /* Video Window 1 Y-Position */ +#define DM320_OSD_VIDWIN1XL (DM320_OSD_REGISTER_BASE+0x0030) /* Video Window 1 X-Size */ +#define DM320_OSD_VIDWIN1YL (DM320_OSD_REGISTER_BASE+0x0032) /* Video Window 1 Y-Size */ +#define DM320_OSD_OSDWIN0XP (DM320_OSD_REGISTER_BASE+0x0034) /* OSD Bitmap Window 0 X-Position */ +#define DM320_OSD_OSDWIN0YP (DM320_OSD_REGISTER_BASE+0x0036) /* OSD Bitmap Window 0 Y-Position */ +#define DM320_OSD_OSDWIN0XL (DM320_OSD_REGISTER_BASE+0x0038) /* OSD Bitmap Window 0 X-Size */ +#define DM320_OSD_OSDWIN0YL (DM320_OSD_REGISTER_BASE+0x003a) /* OSD Bitmap Window 0 Y-Size */ +#define DM320_OSD_OSDWIN1XP (DM320_OSD_REGISTER_BASE+0x003c) /* OSD Bitmap Window 1 X-Position */ +#define DM320_OSD_OSDWIN1YP (DM320_OSD_REGISTER_BASE+0x003e) /* OSD Bitmap Window 1 Y-Position */ +#define DM320_OSD_OSDWIN1XL (DM320_OSD_REGISTER_BASE+0x0040) /* OSD Bitmap Window 1 X-Size */ +#define DM320_OSD_OSDWIN1YL (DM320_OSD_REGISTER_BASE+0x0042) /* OSD Bitmap Window 1 Y-Size */ +#define DM320_OSD_CURXP (DM320_OSD_REGISTER_BASE+0x0044) /* Rectangular Cursor Window X-Position */ +#define DM320_OSD_CURYP (DM320_OSD_REGISTER_BASE+0x0046) /* Rectangular Cursor Window Y-Position */ +#define DM320_OSD_CURXL (DM320_OSD_REGISTER_BASE+0x0048) /* Rectangular Cursor Window X-Size */ +#define DM320_OSD_CURYL (DM320_OSD_REGISTER_BASE+0x004a) /* Rectangular Cursor Window Y-Size */ +#define DM320_OSD_W0BMP01 (DM320_OSD_REGISTER_BASE+0x0050) /* Window 0 Bitmap Value to Palette Map 0/1 */ +#define DM320_OSD_W0BMP23 (DM320_OSD_REGISTER_BASE+0x0052) /* Window 0 Bitmap Value to Palette Map 2/3 */ +#define DM320_OSD_W0BMP45 (DM320_OSD_REGISTER_BASE+0x0054) /* Window 0 Bitmap Value to Palette Map 4/5 */ +#define DM320_OSD_W0BMP67 (DM320_OSD_REGISTER_BASE+0x0056) /* Window 0 Bitmap Value to Palette Map 6/7 */ +#define DM320_OSD_W0BMP89 (DM320_OSD_REGISTER_BASE+0x0058) /* Window 0 Bitmap Value to Palette Map 8/9 */ +#define DM320_OSD_W0BMPAB (DM320_OSD_REGISTER_BASE+0x005a) /* Window 0 Bitmap Value to Palette Map A/B */ +#define DM320_OSD_W0BMPCD (DM320_OSD_REGISTER_BASE+0x005c) /* Window 0 Bitmap Value to Palette Map C/D */ +#define DM320_OSD_W0BMPEF (DM320_OSD_REGISTER_BASE+0x005e) /* Window 0 Bitmap Value to Palette Map E/F */ +#define DM320_OSD_W1BMP01 (DM320_OSD_REGISTER_BASE+0x0060) /* Window 1 Bitmap Value to Palette Map 0/1 */ +#define DM320_OSD_W1BMP23 (DM320_OSD_REGISTER_BASE+0x0062) /* Window 1 Bitmap Value to Palette Map 2/3 */ +#define DM320_OSD_W1BMP45 (DM320_OSD_REGISTER_BASE+0x0064) /* Window 1 Bitmap Value to Palette Map 4/5 */ +#define DM320_OSD_W1BMP67 (DM320_OSD_REGISTER_BASE+0x0066) /* Window 1 Bitmap Value to Palette Map 6/7 */ +#define DM320_OSD_W1BMP89 (DM320_OSD_REGISTER_BASE+0x0068) /* Window 1 Bitmap Value to Palette Map 8/9 */ +#define DM320_OSD_W1BMPAB (DM320_OSD_REGISTER_BASE+0x006a) /* Window 1 Bitmap Value to Palette Map A/B */ +#define DM320_OSD_W1BMPCD (DM320_OSD_REGISTER_BASE+0x006c) /* Window 1 Bitmap Value to Palette Map C/D */ +#define DM320_OSD_W1BMPEF (DM320_OSD_REGISTER_BASE+0x006e) /* Window 1 Bitmap Value to Palette Map E/F */ +#define DM320_OSD_MISCCTL (DM320_OSD_REGISTER_BASE+0x0074) /* Miscellaneous Control */ +#define DM320_OSD_CLUTRAMYCB (DM320_OSD_REGISTER_BASE+0x0076) /* CLUT RAM Y/Cb Setup */ +#define DM320_OSD_CLUTRAMCR (DM320_OSD_REGISTER_BASE+0x0078) /* CLUT RAM Cr/Mapping Setup */ +#define DM320_OSD_RSV5 (DM320_OSD_REGISTER_BASE+0x007a) /* CLUT RAM Cr/Mapping Setup */ +#define DM320_OSD_PPVWIN0ADH (DM320_OSD_REGISTER_BASE+0x007c) /* Ping-Pong Video Window 0 Address (High) */ +#define DM320_OSD_PPVWIN0ADL (DM320_OSD_REGISTER_BASE+0x007e) /* Ping-Pong Video Window 0 Address (Low) */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_DM320_DM320_OSD_H */ diff --git a/arch/arm/src/dm320/dm320_restart.S b/arch/arm/src/dm320/dm320_restart.S new file mode 100644 index 0000000000000000000000000000000000000000..a24fab80105a4992655c635cffa991e891a32f2c --- /dev/null +++ b/arch/arm/src/dm320/dm320_restart.S @@ -0,0 +1,138 @@ +/******************************************************************** + * arch/arm/src/dm320/dm320_restart.S + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************/ + +/******************************************************************** + * Included Files + ********************************************************************/ + +#include + +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +/******************************************************************** + * Pre-processor Definitions + ********************************************************************/ + +/******************************************************************** + * Assembly Macros + ********************************************************************/ + +/* Since the page table is closely related to the NuttX base + * address, we can convert the page table base address to the + * base address of the section containing both. + */ + + .macro mksection, section, pgtable + bic \section, \pgtable, #0x000ff000 + .endm + +/************************************************************************** + * Name: up_restart + **************************************************************************/ + + .text + .globl up_restart + .type up_restart, %function +up_restart: + /* Make sure that we are in SVC mode with all IRQs disabled */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) + msr cpsr_c, r0 + + /* Create identity mapping for first MB section to support + * this re-start logic executing out of the physical address + * space. + */ + + mksection r0, r4 /* r0=phys. base section */ + ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */ + add r3, r1, r0 /* r3=flags + base */ + str r3, [r4, r0, lsr #18] /* identity mapping */ + + /* Jump into the physical address space */ + + ldr pc, .LCphysrestart + nop + nop + + /* We are now executing at our physical address, with the + * MMU disabled. + */ + +up_phyrestart: + + mov r0, #0 + mcr p15, 0, r0, c7, c7 /* Invalidate I,D caches */ + mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ + mcr p15, 0, r0, c8, c7 /* Invalidate I,D TLBs */ + + /* Clear bits in control register (see start.h): Disable, + * MMU, Data cache, alignment traps, write buffer, Instruction + * cache, exceptions at 0xffff0000, round robin) + */ + + mrc p15, 0, r0, c1, c0 /* Get control register */ + bic r0, r0, #(CR_M|CR_C|CR_A|CR_W) + bic r0, r0, #(CR_S|CR_I|CR_V|CR_RR) + mcr p15, 0, r0, c1, c0, 0 /* Write control reg */ + + /* We know that the bootloader entry point is at the + * beginning of flash. + */ +#if 1 + ldr pc, .LCbtldrentry /* Restart bootloader */ +#else + b __start /* Restart Nuttx */ +#endif + + .type .LCphysrestart, %object +.LCphysrestart: + .long (up_phyrestart - CONFIG_RAM_VSTART - CONFIG_RAM_START) +.LCbtldrentry: + .long DM320_EXT_MEM_PADDR + +/************************************************************************** + * PC_Relative Data + **************************************************************************/ + + .type .LCmmuflags, %object +.LCmmuflags: + .long MMU_MEMFLAGS + .size up_restart, .-up_restart + + .end + diff --git a/arch/arm/src/dm320/dm320_serial.c b/arch/arm/src/dm320/dm320_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..dcceafb28a29c47ef6d3e617ae94de4ca28c316f --- /dev/null +++ b/arch/arm/src/dm320/dm320_serial.c @@ -0,0 +1,843 @@ +/**************************************************************************** + * arch/arm/src/dm320/dm320_serial.c + * arch/arm/src/chip/dm320_serial.c + * + * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint16_t msr; /* Saved MSR value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 + * stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; + +/* This describes the state of the DM320 uart0 port. */ + +static struct up_dev_s g_uart0priv = +{ + .uartbase = DM320_UART0_REGISTER_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = DM320_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; + +/* This describes the state of the DM320 uart1 port. */ + +static struct up_dev_s g_uart1priv = +{ + .uartbase = DM320_UART1_REGISTER_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = DM320_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; + +/* Now, which one with be tty0/console and which tty1? */ + +#ifdef CONFIG_SERIAL_IRDA_CONSOLE +# define CONSOLE_DEV g_uart1port +# define TTYS0_DEV g_uart1port +# define TTYS1_DEV g_uart0port +#else +# define CONSOLE_DEV g_uart0port +# define TTYS0_DEV g_uart0port +# define TTYS1_DEV g_uart1port +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint16_t up_serialin(struct up_dev_s *priv, uint32_t offset) +{ + return getreg16(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint16_t value) +{ + putreg16(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *msr) +{ + if (msr) + { + *msr = priv->msr & UART_MSR_ALLIE; + } + + priv->msr &= ~UART_MSR_ALLIE; + up_serialout(priv, UART_MSR, priv->msr); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t msr) +{ + priv->msr |= msr & UART_MSR_ALLIE; + up_serialout(priv, UART_MSR, priv->msr); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((up_serialin(priv, UART_SR) & UART_SR_TFTI) != 0) + { + break; + } + } +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint16_t lcr = up_serialin(priv, UART_LCR); + if (enable) + { + lcr |= UART_LCR_BOC; + } + else + { + lcr &= ~UART_LCR_BOC; + } + up_serialout(priv, UART_LCR, lcr); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t brsr; + + /* Clear fifos */ + + up_serialout(priv, UART_RFCR, 0x8000); + up_serialout(priv, UART_TFCR, 0x8000); + + /* Set rx and tx triggers */ + + up_serialout(priv, UART_RFCR, UART_RFCR_RTL_1); + up_serialout(priv, UART_TFCR, UART_TFCR_TTL_16); + + /* Set up the MSR */ + + priv->msr = up_serialin(priv, UART_MSR); + if (priv->bits == 7) + { + priv->msr |= UART_DATABIT_7; + } + else + { + priv->msr &= ~UART_MSR_CLS; + } + + if (priv->stopbits2) + { + priv->msr |= UART_STOPBIT_2; + } + else + { + priv->msr &= ~UART_MSR_SBLS; + } + + if (priv->parity == 1) + { + priv->msr |= UART_ODDPARITY; + } + else if (priv->parity == 2) + { + priv->msr |= UART_EVENPARITY; + } + else + { + priv->msr &= ~(UART_MSR_PSB | UART_MSR_PEB); + } + + /* Set up the BRSR */ + + switch (priv->baud) + { + case 2400: + brsr = UART_BAUD_2400; + break; + case 4800: + brsr = UART_BAUD_4800; + break; + default: + case 9600: + brsr = UART_BAUD_9600; + break; + case 14400: + brsr = UART_BAUD_14400; + break; + case 19200: + brsr = UART_BAUD_19200; + break; + case 28800: + brsr = UART_BAUD_28800; + break; + case 3840: + brsr = UART_BAUD_38400; + break; + case 57600: + brsr = UART_BAUD_57600; + break; + case 115200: + brsr = UART_BAUD_115200; + break; + case 230400: + brsr = UART_BAUD_230400; + break; + case 460800: + brsr = UART_BAUD_460800; + break; + case 921600: + brsr = UART_BAUD_921600; + break; + } + + /* Setup the new UART configuration */ + + up_serialout(priv, UART_MSR, priv->msr); + up_serialout(priv, UART_BRSR, brsr); + up_enablebreaks(priv, false); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint16_t status; + int passes = 0; + + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (; ; ) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, UART_SR); + status &= (UART_SR_RFTI | UART_SR_TFTI); + + if (status == 0 || passes > 256) + { + return OK; + } + + /* Handline incoming, receive bytes */ + + if (status & UART_SR_RFTI) + { + uart_recvchars(dev); + } + + /* Handle outgoing, transmit bytes */ + + if (status & UART_SR_TFTI) + { + uart_xmitchars(dev); + } + + /* Keep track of how many times we do this in case there + * is some hardware failure condition. + */ + + passes++; + } +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t dtrr; + + dtrr = up_serialin(priv, UART_DTRR); + *status = dtrr; + return dtrr & UART_DTRR_DTR_MASK; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->msr |= UART_MSR_RFTIE; +#endif + } + else + { + priv->msr &= ~UART_MSR_RFTIE; + } + up_serialout(priv, UART_MSR, priv->msr); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_SR) & UART_SR_RFNEF) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_DTRR, (uint16_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->msr |= UART_MSR_TFTIE; +#endif + } + else + { + priv->msr &= ~UART_MSR_TFTIE; + } + up_serialout(priv, UART_MSR, priv->msr); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_SR) & UART_SR_TFTI) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_SR) & UART_SR_TREF) == 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + up_disableuartint(TTYS0_DEV.priv, NULL); + up_disableuartint(TTYS1_DEV.priv, NULL); + + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint16_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + up_serialout(priv, UART_DTRR, (uint16_t)ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, UART_DTRR, '\r'); + } + + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +# ifdef CONFIG_UART1_SERIAL_CONSOLE +# define DM320_REGISTER_BASE DM320_UART1_REGISTER_BASE +# else +# define DM320_REGISTER_BASE DM320_UART0_REGISTER_BASE +# endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void up_waittxready(void) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + + if ((getreg16(DM320_REGISTER_BASE + UART_SR) & UART_SR_TFTI) != 0) + { + break; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int up_putc(int ch) +{ + up_waittxready(); + putreg16((uint16_t)ch, DM320_REGISTER_BASE + UART_DTRR); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(); + putreg16((uint16_t)'\r', DM320_REGISTER_BASE + UART_DTRR); + } + + up_waittxready(); + return ch; +} + +#endif /* USE_SERIALDRIVER */ + + diff --git a/arch/arm/src/dm320/dm320_timer.h b/arch/arm/src/dm320/dm320_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..2ef40790673b0e4e2a90cc2f6bf2641973d14c5e --- /dev/null +++ b/arch/arm/src/dm320/dm320_timer.h @@ -0,0 +1,108 @@ +/************************************************************************************ + * dm320/dm320_timer.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_TIMER_H +#define __DM320_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Timer Registers */ + +#define DM320_TIMER0_TMMD (DM320_PERIPHERALS_VADDR + 0x0000) /* Timer 0 Mode */ +#define DM320_TIMER0_TMPRSCL (DM320_PERIPHERALS_VADDR + 0x0004) /* Timer 0 Prescalar */ +#define DM320_TIMER0_TMDIV (DM320_PERIPHERALS_VADDR + 0x0006) /* Timer 0 Divisor (count) */ +#define DM320_TIMER0_TMTRG (DM320_PERIPHERALS_VADDR + 0x0008) /* Timer 0 One-Shot Trigger */ +#define DM320_TIMER0_TMCNT (DM320_PERIPHERALS_VADDR + 0x000A) /* Timer 0 Count */ + +#define DM320_TIMER1_TMMD (DM320_PERIPHERALS_VADDR + 0x0080) /* Timer 1 Mode */ +#define DM320_TIMER1_TMPRSCL (DM320_PERIPHERALS_VADDR + 0x0084) /* Timer 1 Prescalar */ +#define DM320_TIMER1_TMDIV (DM320_PERIPHERALS_VADDR + 0x0086) /* Timer 1 Divisor (count) */ +#define DM320_TIMER1_TMTRG (DM320_PERIPHERALS_VADDR + 0x0088) /* Timer 1 One-Shot Trigger */ +#define DM320_TIMER1_TMCNT (DM320_PERIPHERALS_VADDR + 0x008A) /* Timer 1 Count */ + +#define DM320_TIMER2_TMMD (DM320_PERIPHERALS_VADDR + 0x0100) /* Timer 2 Mode */ +#define DM320_TIMER2_TMPRSCL (DM320_PERIPHERALS_VADDR + 0x0104) /* Timer 2 Prescalar */ +#define DM320_TIMER2_TMDIV (DM320_PERIPHERALS_VADDR + 0x0106) /* Timer 2 Divisor (count) */ +#define DM320_TIMER2_TMTRG (DM320_PERIPHERALS_VADDR + 0x0108) /* Timer 2 One-Shot Trigger */ +#define DM320_TIMER2_TMCNT (DM320_PERIPHERALS_VADDR + 0x010A) /* Timer 2 Count */ + +#define DM320_TIMER3_TMMD (DM320_PERIPHERALS_VADDR + 0x0180) /* Timer 2 Mode */ +#define DM320_TIMER3_TMPRSCL (DM320_PERIPHERALS_VADDR + 0x0184) /* Timer 2 Prescalar */ +#define DM320_TIMER3_TMDIV (DM320_PERIPHERALS_VADDR + 0x0186) /* Timer 2 Divisor (count) */ +#define DM320_TIMER3_TMTRG (DM320_PERIPHERALS_VADDR + 0x0188) /* Timer 2 One-Shot Trigger */ +#define DM320_TIMER3_TMCNT (DM320_PERIPHERALS_VADDR + 0x018A) /* Timer 2 Count */ + +/* Timer 0,1,2,3 Mode Register Bits: */ + +#define DM320_TMR_MODE_TEST_MASK 0x00fc /* Bits 7:2=Test */ +#define DM320_TMR_MODE_MODE_MASK 0x0003 /* Bits 1:0=timer mode */ + +# define DM320_TMR_MODE_STOP 0x0000 /* Stop Timer */ +# define DM320_TMR_MODE_ONESHOT 0x0001 /* Start one-shot timer */ +# define DM320_TMR_MODE_FREERUN 0x0002 /* Start free-running timer */ + +/* Timer 0,1,2,3 Clock Select Register Bits: */ + +#define DM320_TMR_PRSCL_MASK 0x03ff /* Bits 0:9=Timer prescale value */ + +/* Timer 0,1,2,3 Clock Divisor (Count) Register Bits: */ + +#define DM320_TMR_DIV_MASK 0xffff /* Bits 0:15=Timer divisor value */ + +/* Timer 0,1,2,3 Timer One-Short Trigger Register Bits: */ + +#define DM320_TMR_TMTRG_MASK 0x0001 /* Bit 0=One short trigger */ + +# define DM320_TMR_TMTRG_START 0x0001 /* 1 starts one shot timer */ + +/* Timer 0,1,2,3 Timer Counter Register Bits: */ + +#define DM320_TMR_COUNT_MASK 0xffff /* Bits 0:15=Current counter value */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif + +#endif /* __DM320_TIMER_H */ diff --git a/arch/arm/src/dm320/dm320_timerisr.c b/arch/arm/src/dm320/dm320_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..e88cac0630c4f1875ffb66b2bb3ff65bfc891ef0 --- /dev/null +++ b/arch/arm/src/dm320/dm320_timerisr.c @@ -0,0 +1,157 @@ +/**************************************************************************** + * arch/arm/src/dm320/dm320_timerisr.c + * arch/arm/src/chip/dm320_timerisr.c + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* DM320 Timers + * + * Each of the general-purpose timers can run in one of two modes: one- + * shot mode and free-run mode. In one-shot mode, an interrupt only + * occurs once and then the timer must be explicitly reset to begin the + * timing operation again. In free-run mode, when the timer generates an + * interrupt, the timer counter is automatically reloaded to start the count + * operation again. Use the bit field MODE in TMMDx to configure the + * timer for one-shot more or free-run mode. The bit field MODE in TMMDx + * also allows you to stop the timer. + * + * Either the ARM clock divided by 2 (CLK_ARM/2) or an external clock + * connected to the M27XI pin can be selected as the clock source of the + * timer. + * + * The actual clock frequency used in the timer count operation is the input + * clock divided by: 1 plus the value set in the bit field PRSCL of the + * register TMPRSCLx (10 bits). The timer expires when it reaches the + * value set in the bit field DIV of the register TMDIVx (16 bits) plus 1. + * PRSCL+1 is the source clock frequency divide factor and DIV+1 is the + * timer count value. The frequency of a timer interrupt is given by the + * following equation: + * + * Interrupt Frequency = (Source Clock Frequency) / (PRSCL+1) / (DIV+1) + */ + +/* System Timer + * + * Timer0 is dedicated as the system timer. The rate of system timer + * interrupts is assumed to to 10MS per tick / 100Hz. The following + * register settings are used for timer 0 + * + * System clock formula: + * Interrupt Frequency = (Source Clock Frequency) / (PRSCL+1) / (DIV+1) + * Source Clock Frequency = 27MHz (PLL clock) + * DIV = 26,999 (Yields 1Khz timer clock) + * PRSCL = 9 (Produces 100Hz interrupts) + */ + +#define DM320_TMR0_MODE DM320_TMR_MODE_FREERUN /* Free running */ +#define DM320_TMR0_DIV 26999 /* (see above) */ +#define DM320_TMR0_PRSCL 9 /* (see above) */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + up_disable_irq(DM320_IRQ_SYSTIMER); + + /* Start timer0 running so that an interrupt is generated at + * the rate USEC_PER_TICK. + */ + + putreg16(DM320_TMR0_PRSCL, DM320_TIMER0_TMPRSCL); /* Timer 0 Prescalar */ + putreg16(DM320_TMR0_DIV, DM320_TIMER0_TMDIV); /* Timer 0 Divisor (count) */ + + /* Start the timer */ + + putreg16(DM320_TMR0_MODE, DM320_TIMER0_TMMD); /* Timer 0 Mode */ + + /* Attach and enable the timer interrupt */ + + irq_attach(DM320_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(DM320_IRQ_SYSTIMER); +} + diff --git a/arch/arm/src/dm320/dm320_uart.h b/arch/arm/src/dm320/dm320_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..d668489412075518199c52a170475331f8e97dfd --- /dev/null +++ b/arch/arm/src/dm320/dm320_uart.h @@ -0,0 +1,176 @@ +/************************************************************************************ + * dm320/dm320_uart.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __DM320_UART_H +#define __DM320_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* UART definitions *****************************************************************/ + +/* UART Registers (offsets from the register base) */ + +#define UART_DTRR 0 /* Data Transmission/Reception Register */ +#define UART_BRSR 2 /* Bit Rate Set Register */ +#define UART_MSR 4 /* Mode Set Register */ +#define UART_RFCR 6 /* Reception FIFO Control Register */ +#define UART_TFCR 8 /* Transmission FIFO Control Register */ +#define UART_LCR 10 /* Line Control Register */ +#define UART_SR 12 /* Status Register */ + +/* UART DTRR register bit definitions */ + +#define UART_DTRR_RVF 0x1000 /* Receive word valid flag */ +#define UART_DTRR_BF 0x0800 /* Break flag */ +#define UART_DTRR_FE 0x0400 /* Framing error */ +#define UART_DTRR_ORF 0x0200 /* Overrun flag */ +#define UART_DTRR_PEF 0x0100 /* Parity error */ +#define UART_DTRR_DTR_MASK 0x00ff /* Data transmit/receive */ + +/* UART BRSR register bit definitions */ +/* The UART module is clocked by either the AHB clock or PLLIN / 16 */ + +#ifdef CONFIG_DM320_UARTPPLIN +# define UART_REFCLK (27000000 / 16) +#else +# define UART_REFCLK (DM320_AHB_CLOCK / 16) +#endif + +/* And baud = UART_REFCLK / (brsr+1) */ + +#define UART_BAUD_2400 ((uint16_t)((UART_REFCLK / 2400 ) - 1)) +#define UART_BAUD_4800 ((uint16_t)((UART_REFCLK / 4800 ) - 1)) +#define UART_BAUD_9600 ((uint16_t)((UART_REFCLK / 9600 ) - 1)) +#define UART_BAUD_14400 ((uint16_t)((UART_REFCLK / 14400 ) - 1)) +#define UART_BAUD_19200 ((uint16_t)((UART_REFCLK / 19200 ) - 1)) +#define UART_BAUD_28800 ((uint16_t)((UART_REFCLK / 28800 ) - 1)) +#define UART_BAUD_38400 ((uint16_t)((UART_REFCLK / 38400 ) - 1)) +#define UART_BAUD_57600 ((uint16_t)((UART_REFCLK / 57600 ) - 1)) +#define UART_BAUD_115200 ((uint16_t)((UART_REFCLK / 115200) - 1)) +#define UART_BAUD_230400 ((uint16_t)((UART_REFCLK / 230400) - 1)) +#define UART_BAUD_460800 ((uint16_t)((UART_REFCLK / 460800) - 1)) +#define UART_BAUD_921600 ((uint16_t)((UART_REFCLK / 921600) - 1)) + +/* UART MSR register bit definitions */ + +#define UART_MSR_MODE_BITS 0x001f /* Aata length, stop, & parity */ +#define UART_MSR_CLS 0x0001 /* Char length (1=7bit, 0=8bit) */ +#define UART_DATABIT_7 0x0001 /* Data bit = 7bit */ +#define UART_DATABIT_8 0x0000 /* Data bit = 8bit */ +#define UART_MSR_SBLS 0x0004 /* Stop bit length selection */ +#define UART_STOPBIT_1 0x0000 /* Stop bit = 1bit */ +#define UART_STOPBIT_2 0x0004 /* Stop bit = 2bit */ +#define UART_MSR_PSB 0x0008 /* Parity selection bit */ +#define UART_MSR_PEB 0x0010 /* Parity enable bit */ +#define UART_NOPARITY 0x0000 /* No-parity */ +#define UART_ODDPARITY 0x0018 /* Odd parity */ +#define UART_EVENPARITY 0x0010 /* Even parity */ +#define UART_MSR_RTSC 0x0020 /* RTS receive FIFO control */ +#define UART_MSR_CSTC 0x0040 /* CTS send control */ +#define UART_MSR_TOIC_MASK 0x0c00 /* Timeout interrupt control */ +#define UART_MSR_TOIC_DIS 0x0000 /* Disabled */ +#define UART_MSR_TOIC_3 0x0400 /* 3 bytes */ +#define UART_MSR_TOIC_7 0x0800 /* 7 bytes */ +#define UART_MSR_TOIC_15 0x0c00 /* 15 bytes */ +#define UART_MSR_ALLIE 0xfc00 /* All interrupt bits */ +#define UART_MSR_LSIE 0x1000 /* Line status change int. enable */ +#define UART_MSR_REIE 0x2000 /* Receive error interrupt enable */ +#define UART_MSR_TFTIE 0x4000 /* Transmit FIFO trigger int. enable */ +#define UART_MSR_RFTIE 0x8000 /* Receive FIFO trigger int. enable */ + +#define UART_MSR_INIT (UART_NOPARITY | UART_STOPBIT_1 | UART_DATABIT_8) + +/* UART RFCR register bit definitions */ + +#define UART_RFCR_RWC_MASK 0x003f /* Receive byte count */ +#define UART_RFCR_RTL_MASK 0x0700 /* Receive trigger level */ +#define UART_RFCR_RTL_1 0x0000 /* 1 byte */ +#define UART_RFCR_RTL_4 0x0100 /* 4 bytes */ +#define UART_RFCR_RTL_8 0x0200 /* 8 bytes */ +#define UART_RFCR_RTL_16 0x0300 /* 16 bytes */ +#define UART_RFCR_RTL_24 0x0400 /* 24 bytes */ +#define UART_RFCR_RTL_32 0x0500 /* 32 bytes */ +#define UART_RFCR_RDEF 0x4000 /* Receive data error flag */ +#define UART_RFCR_RFCB 0x8000 /* Receive FIFO clear bit */ + +/* UART TFCR register bit definitions */ + +#define UART_TFCR_TWC_MASK 0x003f /* Transmit byte count */ +#define UART_TFCR_TTL_MASK 0x0700 /* Transmit trigger level */ +#define UART_TFCR_TTL_1 0x0000 /* 1 byte */ +#define UART_TFCR_TTL_4 0x0100 /* 4 bytes */ +#define UART_TFCR_TTL_8 0x0200 /* 8 bytes */ +#define UART_TFCR_TTL_16 0x0300 /* 16 bytes */ +#define UART_TFCR_TTL_24 0x0400 /* 24 bytes */ +#define UART_TFCR_TTL_32 0x0500 /* 32 bytes */ +#define UART_TFCR_TFCB 0x8000 /* Transmit FIFO clear bit */ + +/* UART LCR register bit definitions */ + +#define UART_LCR_RTS 0x0004 /* Current RTS value */ +#define UART_LCR_CTS 0x0010 /* Current CTS value */ +#define UART_LCR_DSR 0x0080 /* Current DSR value */ +#define UART_LCR_BOC 0x0100 /* Break output control */ +#define UART_LCR_UTST 0x4000 /* Test mode setting */ + +#define UART_LCR_INIT 0x0000 + +/* UART SR register bit definitions */ + +#define UART_SR_TREF 0x0001 /* Transmit register empty flag */ +#define UART_SR_TFEF 0x0002 /* Transmit FIFO empty flag */ +#define UART_SR_RFNEF 0x0004 /* Receive FIFO not empty flag */ +#define UART_SR_TOIF 0x0100 /* Timeout Interrupt flag */ +#define UART_SR_RFER 0x0200 /* Receive data error flag */ +#define UART_SR_TFTI 0x0400 /* Transmit FIFO trigger level */ +#define UART_SR_RFTI 0x0800 /* Receive FIFO trigger level */ +#define UART_SR_CTSS 0x1000 /* CTS status */ +#define UART_SR_DSRS 0x8000 /* DSR status */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __DM320_UART_H */ diff --git a/arch/arm/src/dm320/dm320_usb.h b/arch/arm/src/dm320/dm320_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..6db7aef3d6a800e455610e9318eec0125e48cf08 --- /dev/null +++ b/arch/arm/src/dm320/dm320_usb.h @@ -0,0 +1,249 @@ +/************************************************************************************ + * dm320/dm320_uart.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_DM320_DM320_USB_H +#define __ARCH_ARM_SRC_DM320_DM320_USB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* USB Controller Registers *********************************************************/ + +#define DM320_USB_FADDR (DM320_USBOTG_VADDR+0x0000) /* Peripheral Address */ +#define DM320_USB_POWER (DM320_USBOTG_VADDR+0x0001) /* Power Control */ +#define DM320_USB_INTRTX1 (DM320_USBOTG_VADDR+0x0002) /* Transmit EP Interrupt Status #1 */ +#define DM320_USB_RSV1 (DM320_USBOTG_VADDR+0x0003) /* Reserved */ +#define DM320_USB_INTRRX1 (DM320_USBOTG_VADDR+0x0004) /* Receive EP Interrupt Status #1 */ +#define DM320_USB_RSV2 (DM320_USBOTG_VADDR+0x0005) /* Reserved */ +#define DM320_USB_INTRUSB (DM320_USBOTG_VADDR+0x0006) /* USB Interrupt Status */ +#define DM320_USB_INTRTX1E (DM320_USBOTG_VADDR+0x0007) /* Transmit EP Interrupt Enable #1 */ +#define DM320_USB_RSV3 (DM320_USBOTG_VADDR+0x0008) /* Reserved */ +#define DM320_USB_INTRRX1E (DM320_USBOTG_VADDR+0x0009) /* Receive EP Interrupt Enable #1 */ +#define DM320_USB_RSV4 (DM320_USBOTG_VADDR+0x000a) /* Reserved */ +#define DM320_USB_INTRUSBE (DM320_USBOTG_VADDR+0x000b) /* USB Interrupt Enable */ +#define DM320_USB_FRAME1 (DM320_USBOTG_VADDR+0x000c) /* Lower Frame Number */ +#define DM320_USB_FRAME2 (DM320_USBOTG_VADDR+0x000d) /* Upper Frame Number */ +#define DM320_USB_INDEX (DM320_USBOTG_VADDR+0x000e) /* Endpoint Index */ +#define DM320_USB_DEVCTL (DM320_USBOTG_VADDR+0x000f) /* Device Control */ +#define DM320_USB_TXMAXP (DM320_USBOTG_VADDR+0x0010) /* Transmit Maximum Packet Size */ +#define DM320_USB_PERCSR0 (DM320_USBOTG_VADDR+0x0011) /* Peripheral EP0 Control */ +#define DM320_USB_PERTXCSR1 (DM320_USBOTG_VADDR+0x0011) /* Peripheral Tx EP Control #1 */ +#define DM320_USB_CSR2 (DM320_USBOTG_VADDR+0x0012) /* EP0 Control #2 */ +#define DM320_USB_TXCSR2 (DM320_USBOTG_VADDR+0x0012) /* Tx EP Control #2 */ +#define DM320_USB_RXMAXP (DM320_USBOTG_VADDR+0x0013) /* Receive Maximum Packet Size */ +#define DM320_USB_PERRXCSR1 (DM320_USBOTG_VADDR+0x0014) /* Peripheral Rx EP Control #1 */ +#define DM320_USB_PERRXCSR2 (DM320_USBOTG_VADDR+0x0015) /* Peripheral Rx EP Control #2 */ +#define DM320_USB_COUNT0 (DM320_USBOTG_VADDR+0x0016) /* Count EP0 Data Bytes */ +#define DM320_USB_RXCOUNT1 (DM320_USBOTG_VADDR+0x0016) /* Count EP Data bytes #1 */ +#define DM320_USB_RXCOUNT2 (DM320_USBOTG_VADDR+0x0017) /* Count EP Data bytes #2 */ +#define DM320_USB_TXTYPE (DM320_USBOTG_VADDR+0x0018) /* EP Transmit Type */ +#define DM320_USB_NAKLMT0 (DM320_USBOTG_VADDR+0x0019) /* EP0 NAK Limit */ +#define DM320_USB_TXINTVL (DM320_USBOTG_VADDR+0x0019) /* EP Transmit Interval */ +#define DM320_USB_RXTYPE (DM320_USBOTG_VADDR+0x001a) /* EP Receive Type */ +#define DM320_USB_RXINTVL (DM320_USBOTG_VADDR+0x001b) /* EP Receive Interval */ +#define DM320_USB_TXFIFO1 (DM320_USBOTG_VADDR+0x001c) /* EP Transmit FIFO Address #1 */ +#define DM320_USB_TXFIFO2 (DM320_USBOTG_VADDR+0x001d) /* EP Transmit FIFO Address #2 */ +#define DM320_USB_RXFIFO1 (DM320_USBOTG_VADDR+0x001e) /* EP Receive FIFO Address #1 */ +#define DM320_USB_RXFIFO2 (DM320_USBOTG_VADDR+0x001f) /* EP Receive FIFO Address #2 */ +#define DM320_USB_HST_CSR0 (DM320_USBOTG_VADDR+0x0011) /* Host EP0 Control */ +#define DM320_USB_HSTTXCSR (DM320_USBOTG_VADDR+0x0011) /* Host Tx EP Control #1 */ +#define DM320_USB_HSTRXCSR1 (DM320_USBOTG_VADDR+0x0014) /* Host Rx EP Control #1 */ +#define DM320_USB_HSTRXCSR2 (DM320_USBOTG_VADDR+0x0015) /* Host Rx EP Control #2 */ +#define DM320_USB_FIFO0 (DM320_USBOTG_VADDR+0x0020) /* EP0 FIFO Access */ +#define DM320_USB_FIFO1 (DM320_USBOTG_VADDR+0x0024) /* EP1 FIFO Access */ +#define DM320_USB_FIFO2 (DM320_USBOTG_VADDR+0x0028) /* EP2 FIFO Access */ +#define DM320_USB_FIFO3 (DM320_USBOTG_VADDR+0x002c) /* EP3 FIFO Access */ +#define DM320_USB_FIFO4 (DM320_USBOTG_VADDR+0x0030) /* EP4 FIFO Access */ +#define DM320_USB_DMAINTR (DM320_USBOTG_VADDR+0x0200) /* Interrupt Status */ +#define DM320_USB_DMACNTL1 (DM320_USBOTG_VADDR+0x0204) /* DMA Channel1 Control */ +#define DM320_USB_DMAADDR1 (DM320_USBOTG_VADDR+0x0208) /* DMA Channel1 Address */ +#define DM320_USB_DMACOUNT1 (DM320_USBOTG_VADDR+0x020c) /* DMA Channel1 Byte Count */ +#define DM320_USB_DMACNTL2 (DM320_USBOTG_VADDR+0x0214) /* DMA Channel2 Control */ +#define DM320_USB_DMAADDR2 (DM320_USBOTG_VADDR+0x0218) /* DMA Channel2 Address */ +#define DM320_USB_DMACOUNT2 (DM320_USBOTG_VADDR+0x021c) /* DMA Channel2 Byte Count */ +#define DM320_USB_DMACNTL3 (DM320_USBOTG_VADDR+0x0224) /* DMA Channel3 Control */ +#define DM320_USB_DMAADDR3 (DM320_USBOTG_VADDR+0x0228) /* DMA Channel3 Address */ +#define DM320_USB_DMACOUNT3 (DM320_USBOTG_VADDR+0x022c) /* DMA Channel3 Byte Count */ +#define DM320_USB_DMACNTL4 (DM320_USBOTG_VADDR+0x0234) /* DMA Channel4 Control */ +#define DM320_USB_DMAADDR4 (DM320_USBOTG_VADDR+0x0238) /* DMA Channel4 Address */ +#define DM320_USB_DMACOUNT4 (DM320_USBOTG_VADDR+0x023c) /* DMA Channel4 Byte Count */ + +/* POWER register bit settings ******************************************************/ + +#define USB_POWER_ENSUS (0x00000001) +#define USB_POWER_SUSPEND (0x00000002) +#define USB_POWER_RESUME (0x00000004) +#define USB_POWER_RESET (0x00000008) +#define USB_POWER_VBUSLO (0x00000010) +#define USB_POWER_VBUSSESS (0x00000020) +#define USB_POWER_VBUSVAL (0x00000040) +#define USB_POWER_ISO (0x00000080) + +/* USB interrupt bits **************************************************************/ + +#define USB_INT_NOINTERRUPT (0x00000000) +#define USB_INT_SUSPEND (0x00000001) +#define USB_INT_RESUME (0x00000002) +#define USB_INT_RESET (0x00000004) +#define USB_INT_SOF (0x00000008) +#define USB_INT_CONNECTED (0x00000010) +#define USB_INT_DISCONNECTED (0x00000020) +#define USB_INT_SESSRQ (0x00000040) +#define USB_INT_VBUSERR (0x00000080) +#define USB_INT_RXFIFO (0x00000f00) +#define USB_INT_RXFIFO1 (0x00000100) +#define USB_INT_RXFIFO2 (0x00000200) +#define USB_INT_RXFIFO3 (0x00000400) +#define USB_INT_RXFIFO4 (0x00000800) +#define USB_INT_CONTROL (0x00001000) +#define USB_INT_TXFIFO (0x0001e000) +#define USB_INT_TXFIFO1 (0x00002000) +#define USB_INT_TXFIFO2 (0x00004000) +#define USB_INT_TXFIFO3 (0x00008000) +#define USB_INT_TXFIFO4 (0x00010000) + +#define USB_EP4_TX (0x10) +#define USB_EP3_TX (0x08) +#define USB_EP2_TX (0x04) +#define USB_EP1_TX (0x02) +#define USB_EP0 (0x01) + +#define USB_EP4_RX (0x10) +#define USB_EP3_RX (0x08) +#define USB_EP2_RX (0x04) +#define USB_EP1_RX (0x02) + +/* Endpoint control register index *************************************************/ + +#define USB_EP0_SELECT (0x00) + +/* DEVCTL register bit settings ****************************************************/ + +#define USB_DEVCTL_CID (0x80) +#define USB_DEVCTL_FSDEV (0x40) +#define USB_DEVCTL_LSDEV (0x20) +#define USB_DEVCTL_PUCON (0x10) +#define USB_DEVCTL_PDCON (0x08) +#define USB_DEVCTL_MODE (0x04) +#define USB_DEVCTL_HOSTREQ (0x02) +#define USB_DEVCTL_SESSREQ (0x01) + +/* PERCSR0 register bit settings ***************************************************/ + +#define USB_PERCSR0_CLRSETEND (0x80) +#define USB_PERCSR0_CLRRXRDY (0x40) +#define USB_PERCSR0_SENDST (0x20) +#define USB_PERCSR0_SETEND (0x10) +#define USB_PERCSR0_DATAEND (0x08) +#define USB_PERCSR0_SENTST (0x04) +#define USB_PERCSR0_TXPKTRDY (0x02) +#define USB_PERCSR0_RXPKTRDY (0x01) + +/* TXCSR1 register bit settings ****************************************************/ + +#define USB_TXCSR1_CLRDATTOG (0x40) +#define USB_TXCSR1_SENTST (0x20) +#define USB_TXCSR1_SENDST (0x10) +#define USB_TXCSR1_FLFIFO (0x08) +#define USB_TXCSR1_UNDERRUN (0x04) +#define USB_TXCSR1_FIFOEMP (0x02) +#define USB_TXCSR1_TXPKTRDY (0x01) + +/* CSR2 register bit settings ******************************************************/ + +#define USB_CSR2_FLFIFO (0x01) + +/* TXCSR2 register bit settings ****************************************************/ + +#define USB_TXCSR2_AUTOSET (0x80) +#define USB_TXCSR2_ISO (0x40) +#define USB_TXCSR2_MODE_TX (0x20) +#define USB_TXCSR2_DMAEN (0x10) +#define USB_TXCSR2_FRDATTOG (0x08) +#define USB_TXCSR2_DMAMODE1 (0x04) + +/* PERRXCSR1 register bit settings *************************************************/ + +#define USB_PERRXCSR1_CLRDATTOG (0x80) +#define USB_PERRXCSR1_SENTST (0x40) +#define USB_PERRXCSR1_SENDST (0x20) +#define USB_PERRXCSR1_FLFIFO (0x10) +#define USB_PERRXCSR1_DATERR (0x08) +#define USB_PERRXCSR1_OVERRUN (0x04) +#define USB_PERRXCSR1_FIFOFUL (0x02) +#define USB_PERRXCSR1_RXPKTRDY (0x01) + +/* PERRXCSR2 register bit settings *************************************************/ + +#define USB_PERPXCSR2_AUTOCLR (0x80) +#define USB_PERPXCSR2_ISO (0x40) +#define USB_PERPXCSR2_DMAEN (0x20) +#define USB_PERPXCSR2_DMAMODE1 (0x10) + +/* TXFIFO2 register bit settings **************************************************/ + +#define USB_TXFIF02_SZMASK (0xe0) +#define USB_TXFIFO2_SZ_8 (0x00) +#define USB_TXFIFO2_SZ_16 (0x20) +#define USB_TXFIFO2_SZ_32 (0x40) +#define USB_TXFIFO2_SZ_64 (0x60) +#define USB_TXFIFO2_SZ_128 (0x80) +#define USB_TXFIFO2_SZ_256 (0xa0) +#define USB_TXFIFO2_SZ_512 (0xc0) +#define USB_TXFIFO2_SZ_1024 (0xe0) +#define USB_TXFIFO2_SINGLE_BUF (0x00) +#define USB_TXFIFO2_DOUBLE_BUF (0x10) + +/* RXFIFO2 register bit settings **************************************************/ + +#define USB_RXFIF02_DPB (0x10) + +/* USBDMA control register bit settings ********************************************/ + +#define USBDMA_CNTL_DMAEN (0x01) +#define USBDMA_CNTL_DIR_IN (0x02) +#define USBDMA_CNTL_DMAMODE1 (0x04) +#define USBDMA_CNTL_INTREN (0x08) + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_DM320_DM320_USB_H */ diff --git a/arch/arm/src/dm320/dm320_usbdev.c b/arch/arm/src/dm320/dm320_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..f0f87b7f584c88cbe5ca18d1eac7ebf1bc4b2102 --- /dev/null +++ b/arch/arm/src/dm320/dm320_usbdev.c @@ -0,0 +1,2628 @@ +/**************************************************************************** + * arch/arm/src/dm320/dm320_usbdev.c + * + * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "dm320_usb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* Verify the selected USB attach interrupt GIO line */ + +#if CONFIG_DM320_GIO_USBATTACH < 0 || CONFIG_DM320_GIO_USBATTACH > 15 +# error "CONFIG_DM320_GIO_USBATTACH invalid" +#endif + +/* Calculate the IRQ number associated with this GIO */ + +#define IRQ_USBATTACH (DM320_IRQ_EXT0+CONFIG_DM320_GIO_USBATTACH) + +/* Vendor ID & Product ID of the USB device */ + +#ifndef CONFIG_DM320_VENDORID +# define CONFIG_DM320_VENDORID 0xd320 +#endif + +#ifndef CONFIG_DM320_PRODUCTID +# define CONFIG_DM320_PRODUCTID 0x3211 +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#undef CONFIG_DM320_USBDEV_REGDEBUG + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define DM320_TRACEERR_ALLOCFAIL 0x0001 +#define DM320_TRACEERR_ATTACHIRQREG 0x0002 +#define DM320_TRACEERR_BINDFAILED 0x0003 +#define DM320_TRACEERR_COREIRQREG 0x0004 +#define DM320_TRACEERR_DRIVER 0x0005 +#define DM320_TRACEERR_DRIVERREGISTERED 0x0006 +#define DM320_TRACEERR_EPREAD 0x0007 +#define DM320_TRACEERR_EWRITE 0x0008 +#define DM320_TRACEERR_INVALIDPARMS 0x0009 +#define DM320_TRACEERR_NOEP 0x000a +#define DM320_TRACEERR_NOTCONFIGURED 0x000b +#define DM320_TRACEERR_NULLPACKET 0x000c +#define DM320_TRACEERR_NULLREQUEST 0x000d +#define DM320_TRACEERR_REQABORTED 0x000e +#define DM320_TRACEERR_STALLEDCLRFEATURE 0x000f +#define DM320_TRACEERR_STALLEDISPATCH 0x0010 +#define DM320_TRACEERR_STALLEDGETST 0x0011 +#define DM320_TRACEERR_STALLEDGETSTEP 0x0012 +#define DM320_TRACEERR_STALLEDGETSTRECIP 0x0013 +#define DM320_TRACEERR_STALLEDREQUEST 0x0014 +#define DM320_TRACEERR_STALLEDSETFEATURE 0x0015 + +/* Trace interrupt codes */ + +#define DM320_TRACEINTID_ATTACHED 0x0001 +#define DM320_TRACEINTID_ATTACH 0x0002 +#define DM320_TRACEINTID_CLEARFEATURE 0x0003 +#define DM320_TRACEINTID_CONNECTED 0x0004 +#define DM320_TRACEINTID_CONTROL 0x0005 +#define DM320_TRACEINTID_DETACHED 0x0006 +#define DM320_TRACEINTID_DISCONNECTED 0x0007 +#define DM320_TRACEINTID_DISPATCH 0x0008 +#define DM320_TRACEINTID_GETENDPOINT 0x0009 +#define DM320_TRACEINTID_GETIFDEV 0x000a +#define DM320_TRACEINTID_GETSETDESC 0x000b +#define DM320_TRACEINTID_GETSETIFCONFIG 0x000c +#define DM320_TRACEINTID_GETSTATUS 0x000d +#define DM320_TRACEINTID_RESET 0x000e +#define DM320_TRACEINTID_RESUME 0x000f +#define DM320_TRACEINTID_RXFIFO 0x0010 +#define DM320_TRACEINTID_RXPKTRDY 0x0011 +#define DM320_TRACEINTID_SESSRQ 0x0012 +#define DM320_TRACEINTID_SETADDRESS 0x0013 +#define DM320_TRACEINTID_SETFEATURE 0x0014 +#define DM320_TRACEINTID_SOF 0x0015 +#define DM320_TRACEINTID_SUSPEND 0x0016 +#define DM320_TRACEINTID_SYNCHFRAME 0x0017 +#define DM320_TRACEINTID_TESTMODE 0x0018 +#define DM320_TRACEINTID_TXFIFO 0x0019 +#define DM320_TRACEINTID_TXFIFOSETEND 0x001a +#define DM320_TRACEINTID_TXFIFOSTALL 0x001b +#define DM320_TRACEINTID_TXPKTRDY 0x001c +#define DM320_TRACEINTID_UNKNOWN 0x001d +#define DM320_TRACEINTID_USBCTLR 0x001d +#define DM320_TRACEINTID_VBUSERR 0x001f + +/* Hardware interface **********************************************************/ + +/* The DM320 hardware supports 8 configurable endpoints EP1-4, IN and OUT + * (in addition to EP0 IN and OUT). This driver, however, does not exploit + * the full configuratability of the hardware at this time but, instead, + * supports the one interrupt IN, one bulk IN and one bulk OUT endpoint. + */ + +/* Hardware dependent sizes and numbers */ + +#define DM320_EP0MAXPACKET 64 /* EP0 max packet size */ +#define DM320_BULKMAXPACKET 64 /* Bulk endpoint max packet */ +#define DM320_INTRMAXPACKET 64 /* Interrupt endpoint max packet */ +#define DM320_NENDPOINTS 4 /* Includes EP0 */ + +/* Endpoint numbers */ + +#define DM320_EP0 0 /* Control endpoint */ +#define DM320_EPBULKIN 1 /* Bulk EP for send to host */ +#define DM320_EPBULKOUT 2 /* Bulk EP for recv to host */ +#define DM320_EPINTRIN 3 /* Intr EP for host poll */ + +/* Request queue operations ****************************************************/ + +#define dm320_rqempty(ep) ((ep)->head == NULL) +#define dm320_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request make be retained in a list */ + +struct dm320_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct dm320_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct dm320_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct dm320_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* DM320-specific fields */ + + struct dm320_usbdev_s *dev; /* Reference to private driver data */ + struct dm320_req_s *head; /* Request list for this endpoint */ + struct dm320_req_s *tail; + uint8_t epphy; /* Physical EP address/index */ + uint8_t stalled:1; /* Endpoint is halted */ + uint8_t in:1; /* Endpoint is IN only */ + uint8_t halted:1; /* Endpoint feature halted */ + uint8_t txnullpkt:1; /* Null packet needed at end of transfer */ +}; + +/* This structure encapsulates the overall driver state */ + +struct dm320_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct dm320_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* DM320-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t rxpending:1; /* 1: RX pending */ + uint8_t paddr; /* Peripheral address */ + + /* The endpoint list */ + + struct dm320_ep_s eplist[DM320_NENDPOINTS]; +}; + +/* For maintaining tables of endpoint info */ + +struct dm320_epinfo_s +{ + uint8_t addr; /* Logical endpoint address */ + uint8_t attr; /* Endpoint attributes */ + uint8_t fifo; /* FIFO mx pkt size + dual buffer bits */ +#ifdef CONFIG_USBDEV_HIGHSPEED + uint16_t maxpacket; /* Max packet size */ +#else + uint8_t maxpacket; /* Max packet size */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations */ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t dm320_getreg8(uint32_t addr); +static uint32_t dm320_getreg16(uint32_t addr); +static uint32_t dm320_getreg32(uint32_t addr); +static void dm320_putreg8(uint8_t val, uint32_t addr); +static void dm320_putreg16(uint16_t val, uint32_t addr); +static void dm320_putreg32(uint32_t val, uint32_t addr); +#else +# define dm320_getreg8(addr) getreg8(addr) +# define dm320_getreg16(addr) getreg16(addr) +# define dm320_getreg32(addr) getreg32(addr) +# define dm320_putreg8(val,addr) putreg8(val,addr) +# define dm320_putreg16(val,addr) putreg16(val,addr) +# define dm320_putreg32(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations ****************************************************/ + +static FAR struct dm320_req_s *dm320_rqdequeue(FAR struct dm320_ep_s *privep); +static void dm320_rqenqueue(FAR struct dm320_ep_s *privep, FAR struct dm320_req_s *req); + +/* Low level data transfers and request operations */ + +static int dm320_ep0write(uint8_t *buf, uint16_t nbytes); +static int dm320_epwrite(uint8_t epphy, uint8_t *buf, uint16_t nbytes); +static int dm320_epread(uint8_t epphy, uint8_t *buf, uint16_t nbytes); +static inline void dm320_abortrequest(struct dm320_ep_s *privep, + struct dm320_req_s *privreq, int16_t result); +static void dm320_reqcomplete(struct dm320_ep_s *privep, int16_t result); +static int dm320_wrrequest(struct dm320_ep_s *privep); +static int dm320_rdrequest(struct dm320_ep_s *privep); +static void dm320_cancelrequests(struct dm320_ep_s *privep); + +/* Interrupt handling */ + +static struct dm320_ep_s *dm320_epfindbyaddr(struct dm320_usbdev_s *priv, + uint16_t eplog); +static void dm320_dispatchrequest(struct dm320_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static inline void dm320_ep0setup(struct dm320_usbdev_s *priv); +static inline uint32_t dm320_highestpriinterrupt(int intstatus); +static int dm320_ctlrinterrupt(int irq, FAR void *context); +static int dm320_attachinterrupt(int irq, FAR void *context); + +/* Initialization operations */ + +static void dm320_epreset(unsigned int index); +static inline void dm320_epinitialize(struct dm320_usbdev_s *priv); +static void dm320_ctrlinitialize(struct dm320_usbdev_s *priv); + +/* Endpoint methods */ + +static int dm320_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int dm320_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *dm320_epallocreq(FAR struct usbdev_ep_s *ep); +static void dm320_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); +#ifdef CONFIG_USBDEV_DMA +static FAR void *dm320_epallocbuffer(FAR struct usbdev_ep_s *ep, uint16_t nbytes); +static void dm320_epfreebuffer(FAR struct usbdev_ep_s *ep, void *buf); +#endif +static int dm320_epsubmit(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *privreq); +static int dm320_epcancel(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *privreq); + +/* USB device controller methods */ + +static FAR struct usbdev_ep_s *dm320_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void dm320_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int dm320_getframe(struct usbdev_s *dev); +static int dm320_wakeup(struct usbdev_s *dev); +static int dm320_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int dm320_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Endpoint methods */ + +static const struct usbdev_epops_s g_epops = +{ + .configure = dm320_epconfigure, + .disable = dm320_epdisable, + .allocreq = dm320_epallocreq, + .freereq = dm320_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = dm320_epallocbuffer, + .freebuffer = dm320_epfreebuffer, +#endif + .submit = dm320_epsubmit, + .cancel = dm320_epcancel, +}; + +/* USB controller device methods */ + +static const struct usbdev_ops_s g_devops = +{ + .allocep = dm320_allocep, + .freeep = dm320_freeep, + .getframe = dm320_getframe, + .wakeup = dm320_wakeup, + .selfpowered = dm320_selfpowered, +#ifdef CONFIG_DM320_GIO_USBDPPULLUP + .pullup = dm320_pullup, +#endif +}; + +/* There is only one, single, pre-allocated instance of the driver structure */ + +static struct dm320_usbdev_s g_usbdev; + +/* Summarizes information about all DM320 endpoints */ + +static const struct dm320_epinfo_s g_epinfo[DM320_NENDPOINTS] = +{ + { + 0, /* EP0 */ + USB_EP_ATTR_XFER_CONTROL, /* Type: Control IN/OUT */ + USB_TXFIFO2_SZ_64 | USB_TXFIFO2_SINGLE_BUF, /* Bits for TX/RXFIFO2 */ + DM320_EP0MAXPACKET /* Max packet size */ + }, + { + DM320_EPBULKIN | USB_DIR_IN, /* Logical endpoint number: 1 IN */ + USB_EP_ATTR_XFER_BULK, /* Type: Bulk */ + USB_TXFIFO2_SZ_64 | USB_TXFIFO2_SINGLE_BUF, /* Bits for TX/RXFIFO2 */ + DM320_BULKMAXPACKET, /* Max packet size */ + }, + { + DM320_EPBULKOUT | USB_DIR_OUT, /* Logical endpoint number: 2 OUT */ + USB_EP_ATTR_XFER_BULK, /* Type: Bulk */ + USB_TXFIFO2_SZ_64 | USB_TXFIFO2_SINGLE_BUF, /* Bits for TX/RXFIFO2 */ + DM320_BULKMAXPACKET /* Max packet size */ + }, + { + DM320_EPINTRIN | USB_DIR_IN, /* Logical endpoint number: 3 IN */ + USB_EP_ATTR_XFER_INT, /* Type: Interrupt */ + USB_TXFIFO2_SZ_64 | USB_TXFIFO2_SINGLE_BUF, /* Bits for TX/RXFIFO2 */ + DM320_INTRMAXPACKET /* Max packet size */ + } +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dm320_getreg8 + * + * Description: + * Get the contents of an DM320 8-bit register + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint8_t dm320_getreg8(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint8_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint8_t val = getreg8(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr || val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%02x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: dm320_getreg16 + * + * Description: + * Get the contents of an DM320 16-bit register + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t dm320_getreg16(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint16_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint16_t val = getreg16(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr || val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%04x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: dm320_getreg32 + * + * Description: + * Get the contents of an DM320 32-bit register + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t dm320_getreg32(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr || val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: dm320_putreg8 + * + * Description: + * Set the contents of an DM320 8-bit register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void dm320_putreg8(uint8_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%02x\n", addr, val); + + /* Write the value */ + + putreg8(val, addr); +} +#endif + +/**************************************************************************** + * Name: dm320_putreg16 + * + * Description: + * Set the contents of an DM320 16-bit register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void dm320_putreg16(uint16_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%04x\n", addr, val); + + /* Write the value */ + + putreg16(val, addr); +} +#endif + +/**************************************************************************** + * Name: dm320_putreg32 + * + * Description: + * Set the contents of an DM320 32-bit register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_DM320_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void dm320_putreg32(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: dm320_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct dm320_req_s *dm320_rqdequeue(FAR struct dm320_ep_s *privep) +{ + FAR struct dm320_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: dm320_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static void dm320_rqenqueue(FAR struct dm320_ep_s *privep, + FAR struct dm320_req_s *req) +{ + req->flink = NULL; + if (!privep->head) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } +} + +/**************************************************************************** + * Name: dm320_ep0write + * + * Description: + * Control endpoint write (IN) + * + ****************************************************************************/ + +static int dm320_ep0write(uint8_t *buf, uint16_t nbytes) +{ + uint8_t csr0 = USB_PERCSR0_TXPKTRDY; /* XMT packet ready bit */ + uint16_t bytesleft; + uint16_t nwritten; + + if (nbytes <= DM320_EP0MAXPACKET) + { + bytesleft = nbytes; + csr0 |= USB_PERCSR0_DATAEND; /* Transaction end bit */ + } + else + { + bytesleft = DM320_EP0MAXPACKET; + } + + nwritten = bytesleft; + while (bytesleft > 0) + { + dm320_putreg8(*buf++, DM320_USB_FIFO0); + bytesleft--; + } + + dm320_putreg8(csr0, DM320_USB_PERCSR0); + return nwritten; +} + +/**************************************************************************** + * Name: dm320_epwrite + * + * Description: + * Endpoint write (IN) + * + ****************************************************************************/ + +static int dm320_epwrite(uint8_t epphy, uint8_t *buf, uint16_t nbytes) +{ + volatile uint8_t *fifo; + uint16_t bytesleft; + int ret = ERROR; + + if (/* epphy < USB_EP0_SELECT || */ epphy >= DM320_NENDPOINTS) + { + return ret; + } + dm320_putreg8(epphy, DM320_USB_INDEX); + + if (epphy == USB_EP0_SELECT) + { + return dm320_ep0write(buf, nbytes); + } + + bytesleft = DM320_BULKMAXPACKET; + if (bytesleft > nbytes) + { + bytesleft = nbytes; + } + + ret = bytesleft; + fifo = (volatile uint8_t *)DM320_USB_FIFO0; + fifo = fifo + (epphy << 2); + + if (dm320_getreg8(DM320_USB_PERTXCSR1) & USB_TXCSR1_FIFOEMP) + { + dm320_putreg8(dm320_getreg8(DM320_USB_PERTXCSR1) | USB_TXCSR1_TXPKTRDY, DM320_USB_PERTXCSR1); + while (dm320_getreg8(DM320_USB_PERTXCSR1) & USB_TXCSR1_TXPKTRDY); + dm320_putreg8((dm320_getreg8(DM320_USB_PERTXCSR1) | USB_TXCSR1_FLFIFO), DM320_USB_PERTXCSR1); + } + + while (bytesleft > 0) + { + *fifo = *buf++; + bytesleft--; + } + dm320_putreg8(dm320_getreg8(DM320_USB_PERTXCSR1) | USB_TXCSR1_TXPKTRDY, DM320_USB_PERTXCSR1); + return ret; +} + +/**************************************************************************** + * Name: dm320_epread + * + * Description: + * Endpoint read (OUT) + * + ****************************************************************************/ + +static int dm320_epread(uint8_t epphy, uint8_t *buf, uint16_t nbytes) +{ + volatile uint8_t *fifo; + int bytesleft; + int ret = ERROR; + + if (/* epphy < USB_EP0_SELECT || */ epphy >= DM320_NENDPOINTS) + { + return ret; + } + dm320_putreg8(epphy, DM320_USB_INDEX); + + if (epphy == USB_EP0_SELECT) + { + bytesleft = dm320_getreg8(DM320_USB_COUNT0); + if (bytesleft > nbytes) + { + bytesleft = nbytes; + } + } + else + { + bytesleft = dm320_getreg8(DM320_USB_RXCOUNT2); + bytesleft = (bytesleft << 8) + dm320_getreg8(DM320_USB_RXCOUNT1); + if (bytesleft > nbytes) + { + bytesleft = nbytes; + } + } + + ret = bytesleft; + fifo = (uint8_t *)DM320_USB_FIFO0; + fifo = fifo + (epphy << 2); + + while (bytesleft > 0) + { + *buf++ = *fifo; + bytesleft--; + } + + /* Clear RXPKTRDY bit in PER_RXCSR1 */ + + dm320_putreg8(dm320_getreg8(DM320_USB_PERRXCSR1) & ~(USB_PERRXCSR1_RXPKTRDY), DM320_USB_PERRXCSR1); + return ret; +} + +/**************************************************************************** + * Name: dm320_abortrequest + * + * Description: + * Discard a request + * + ****************************************************************************/ + +static inline void dm320_abortrequest(struct dm320_ep_s *privep, + struct dm320_req_s *privreq, + int16_t result) +{ + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_REQABORTED), (uint16_t)privep->epphy); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: dm320_reqcomplete + * + * Description: + * Handle termination of a request. + * + ****************************************************************************/ + +static void dm320_reqcomplete(struct dm320_ep_s *privep, int16_t result) +{ + struct dm320_req_s *privreq; + int stalled = privep->stalled; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = dm320_rqdequeue(privep); + leave_critical_section(flags); + + if (privreq) + { + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + if (privep->epphy == 0) + { + if (privep->dev->stalled) + { + privep->stalled = 1; + } + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; + } +} + +/**************************************************************************** + * Name: dm320_wrrequest + * + * Description: + * Send from the next queued write request + * + * Returned Value: + * 0:not finished; 1:completed; <0:error + * + ****************************************************************************/ + +static int dm320_wrrequest(struct dm320_ep_s *privep) +{ + struct dm320_req_s *privreq; + uint8_t *buf; + int nbytes; + int bytesleft; + int nbyteswritten; + + /* Check the request from the head of the endpoint request queue */ + + privreq = dm320_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_NULLREQUEST), 0); + return OK; + } + + /* Otherwise send the data in the packet (in the DMA on case, we + * may be resuming transfer already in progress. + */ + + for (; ; ) + { + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + + /* Send the next packet if (1) there are more bytes to be sent, or + * (2) the last packet sent was exactly maxpacketsize (bytesleft == 0) + */ + + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + if (bytesleft > 0 || privep->txnullpkt) + { + /* Try to send maxpacketsize -- unless we don't have that many + * bytes to send. + */ + + privep->txnullpkt = 0; + if (bytesleft > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + else + { + nbytes = bytesleft; + if ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + privep->txnullpkt = (bytesleft == privep->ep.maxpacket); + } + } + + /* Send the largest number of bytes that we can in this packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + nbyteswritten = dm320_epwrite(privep->epphy, buf, nbytes); + if (nbyteswritten < 0 || nbyteswritten != nbytes) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_EWRITE), nbyteswritten); + return ERROR; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* If all of the bytes were sent (including any final null packet) + * then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->txnullpkt) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + privep->txnullpkt = 0; + dm320_reqcomplete(privep, OK); + return OK; + } + } + + return OK; /* Won't get here */ +} + +/**************************************************************************** + * Name: dm320_rdrequest + * + * Description: + * Receive to the next queued read request + * + ****************************************************************************/ + +static int dm320_rdrequest(struct dm320_ep_s *privep) +{ + struct dm320_req_s *privreq; + uint8_t *buf; + int nbytesread; + + /* Check the request from the head of the endpoint request queue */ + + privreq = dm320_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_NULLREQUEST), 0); + return OK; + } + + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + + /* Receive the next packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + nbytesread = dm320_epread(privep->epphy, buf, privep->ep.maxpacket); + if (nbytesread < 0) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_EPREAD), nbytesread); + return ERROR; + } + + /* If the receive buffer is full or if the last packet was not full + * then we are finished with the transfer. + */ + + privreq->req.xfrd += nbytesread; + if (privreq->req.len < privreq->req.xfrd || nbytesread < privep->ep.maxpacket) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + dm320_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: dm320_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void dm320_cancelrequests(struct dm320_ep_s *privep) +{ + while (!dm320_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (dm320_rqpeek(privep))->req.xfrd); + dm320_reqcomplete(privep, -ESHUTDOWN); + } +} + +/**************************************************************************** + * Name: dm320_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct dm320_ep_s *dm320_epfindbyaddr(struct dm320_usbdev_s *priv, + uint16_t eplog) +{ + struct dm320_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < DM320_NENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: dm320_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver + * + ****************************************************************************/ + +static void dm320_dispatchrequest(struct dm320_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret; + + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDISPATCH), ctrl->req); + priv->stalled = 1; + } + } +} + +/**************************************************************************** + * Name: dm320_ep0setup + * + * Description: + * USB Ctrl EP Setup Event + * + ****************************************************************************/ + +static inline void dm320_ep0setup(struct dm320_usbdev_s *priv) +{ + struct dm320_ep_s *ep0 = &priv->eplist[DM320_EP0]; + struct dm320_req_s *privreq = dm320_rqpeek(ep0); + struct dm320_ep_s *privep; + struct usb_ctrlreq_s ctrl; + uint16_t index; + uint16_t value; + uint16_t len; + int ret; + + /* Starting a control request? */ + + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + } + + /* Terminate any pending requests */ + + while (!dm320_rqempty(ep0)) + { + int16_t result = OK; + if (privreq->req.xfrd != privreq->req.len) + { + result = -EPROTO; + } + + usbtrace(TRACE_COMPLETE(ep0->epphy), privreq->req.xfrd); + dm320_reqcomplete(ep0, result); + } + + /* Assume NOT stalled */ + + ep0->stalled = 0; + priv->stalled = 0; + + /* Read EP0 data */ + + ret = dm320_epread(USB_EP0_SELECT, (uint8_t *)&ctrl, USB_SIZEOF_CTRLREQ); + if (ret <= 0) + { + return; + } + + index = GETUINT16(ctrl.index); + value = GETUINT16(ctrl.value); + len = GETUINT16(ctrl.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl.type, ctrl.req, value, index, len); + + /* Dispatch any non-standard requests */ + + ep0->in = (ctrl.type & USB_DIR_IN) != 0; + if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + dm320_putreg8(USB_PERCSR0_CLRRXRDY, DM320_USB_PERCSR0); + dm320_dispatchrequest(priv, &ctrl); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_GETSTATUS), 0); + + if (len != 2 || (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDGETST), ctrl.req); + priv->stalled = 1; + } + else + { + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_GETENDPOINT), 0); + privep = dm320_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDGETSTEP), ctrl.type); + priv->stalled = 1; + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + case USB_REQ_RECIPIENT_INTERFACE: + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_GETIFDEV), 0); + break; + + default: + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDGETSTRECIP), ctrl.type); + priv->stalled = 1; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_CLEARFEATURE), (uint16_t)ctrl.req); + if (ctrl.type != USB_REQ_RECIPIENT_ENDPOINT) + { + dm320_dispatchrequest(priv, &ctrl); + } + else if (value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = dm320_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 0; + + /* Restart the write queue */ + + (void)dm320_wrrequest(privep); + } + else + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDCLRFEATURE), ctrl.type); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_SETFEATURE), 0); + if (ctrl.type == USB_REQ_RECIPIENT_DEVICE && value == USB_FEATURE_TESTMODE) + { + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_TESTMODE), index); + } + else if (ctrl.type != USB_REQ_RECIPIENT_ENDPOINT) + { + dm320_dispatchrequest(priv, &ctrl); + } + else if (value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = dm320_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 1; + } + else + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDSETFEATURE), ctrl.type); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, + DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_SETADDRESS), 0); + priv->paddr = value & 0xff; + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + { + dm320_putreg8(USB_PERCSR0_CLRRXRDY, DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_GETSETDESC), 0); + dm320_dispatchrequest(priv, &ctrl); + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, + DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_GETSETIFCONFIG), 0); + dm320_dispatchrequest(priv, &ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + { + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_SENDST, + DM320_USB_PERCSR0); + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_SENDST, + DM320_USB_PERCSR0); + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_STALLEDREQUEST), ctrl.req); + priv->stalled = 1; + } + break; + } +} + +/**************************************************************************** + * Name: dm320_highestpriinterrupt + * + * Description: + * Part of the USB core controller interrupt handling logic + * + ****************************************************************************/ + +static inline uint32_t dm320_highestpriinterrupt(int intstatus) +{ + if ((intstatus & USB_INT_CONNECTED) != 0) + { + return USB_INT_CONNECTED; + } + + if ((intstatus & USB_INT_DISCONNECTED) != 0) + { + return USB_INT_DISCONNECTED; + } + + if ((intstatus & USB_INT_RESET) != 0) + { + return USB_INT_RESET; + } + + if ((intstatus & USB_INT_RESUME) != 0) + { + return USB_INT_RESUME; + } + + if ((intstatus & USB_INT_SESSRQ) != 0) + { + return USB_INT_SESSRQ; + } + + if ((intstatus & USB_INT_VBUSERR) != 0) + { + return USB_INT_VBUSERR; + } + + if ((intstatus & USB_INT_SOF) != 0) + { + return USB_INT_SOF; + } + + if ((intstatus & USB_INT_SUSPEND) != 0) + { + return USB_INT_SUSPEND; + } + + if ((intstatus & USB_INT_CONTROL) != 0) + { + return USB_INT_CONTROL; + } + + if ((intstatus & USB_INT_RXFIFO) != 0) + { + return USB_INT_RXFIFO; + } + + if ((intstatus & USB_INT_TXFIFO) != 0) + { + return USB_INT_TXFIFO; + } + + return USB_INT_NOINTERRUPT; +} + +/**************************************************************************** + * Name: dm320_ctlrinterrupt + * + * Description: + * Handle USB controller core interrupts + * + ****************************************************************************/ + +static int dm320_ctlrinterrupt(int irq, FAR void *context) +{ + struct dm320_usbdev_s *priv = &g_usbdev; + struct dm320_ep_s *privep ; + uint32_t intstatus; + uint32_t priorityint; + uint8_t csr0; + + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_USBCTLR), 0); + + /* Combine interretup registers into one interrupt status value */ + + intstatus = ((uint32_t)dm320_getreg8(DM320_USB_INTRTX1) << 12) | + (((uint32_t)dm320_getreg8(DM320_USB_INTRRX1) >> 1) << 8) | + (uint32_t)dm320_getreg8(DM320_USB_INTRUSB); + /* Then process each interrupt source, highest priority first */ + + do + { + priorityint = dm320_highestpriinterrupt(intstatus); + switch (priorityint) + { + case USB_INT_RESET: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_RESET), 0); + priv->paddrset = 0; + break; + + case USB_INT_SESSRQ: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_SESSRQ), 0); + break; + + case USB_INT_VBUSERR: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_VBUSERR), 0); + break; + + case USB_INT_CONNECTED: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_CONNECTED), 0); + break; + + case USB_INT_RESUME: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_RESUME), 0); + break; + + case USB_INT_CONTROL: + { + /* Select EP0 */ + + dm320_putreg8(USB_EP0_SELECT, DM320_USB_INDEX); + + /* Check for a response complete interrupt */ + + csr0 = dm320_getreg8(DM320_USB_PERCSR0); + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_CONTROL), csr0); + if (csr0 == 0x00) + { + /* Check if we need to set the peripheral address */ + + if (!priv->paddrset && priv->paddr != 0) + { + dm320_putreg8(priv->paddr, DM320_USB_FADDR); + priv->paddrset = 1; + break; + } + } + + if ((csr0 & USB_PERCSR0_RXPKTRDY) != 0) + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_RXPKTRDY), csr0); + (void)dm320_getreg8(DM320_USB_COUNT0); + dm320_ep0setup(priv); + } + else if ((csr0 & USB_PERCSR0_SENTST) != 0) + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_TXFIFOSTALL), csr0); + dm320_putreg8(0, DM320_USB_PERCSR0); + } + else if ((csr0 & USB_PERCSR0_SETEND) != 0) + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_TXFIFOSETEND), csr0); + dm320_putreg8(USB_PERCSR0_CLRSETEND, DM320_USB_PERCSR0); + } + else if ((csr0 & USB_PERCSR0_TXPKTRDY) != 0) + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_TXPKTRDY), csr0); + } + else + { + /* Now ignore these unknown interrupts */ + + dm320_putreg8(USB_PERCSR0_CLRRXRDY | USB_PERCSR0_DATAEND, DM320_USB_PERCSR0); + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_UNKNOWN), csr0); + } + } + break; + + case USB_INT_RXFIFO: + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_RXFIFO), 0); + privep = &priv->eplist[DM320_EPBULKOUT]; + if (!dm320_rqempty(privep)) + { + dm320_rdrequest(privep); + } + else + { + ullvdbg("Pending data on OUT endpoint\n"); + priv->rxpending = 1; + } + } + break; + + case USB_INT_TXFIFO: + { + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_TXFIFO), 0); +#ifdef PIPE_STALL + dm320_putreg8(DM320_EPBULKIN, DM320_USB_INDEX); + if (dm320_getreg8(DM320_USB_PERTXCSR1) & USB_TXCSR1_SENTST) + { + dm320_putreg8(dm320_getreg8(DM320_USB_PERTXCSR1) & ~USB_TXCSR1_SENTST, DM320_USB_PERTXCSR1); + dm320_putreg8(dm320_getreg8(DM320_USB_PERTXCSR1) & ~USB_TXCSR1_SENDST, DM320_USB_PERTXCSR1); + } +#endif + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + } + privep = &priv->eplist[DM320_EPBULKIN]; + + if (!dm320_rqempty(privep)) + { + (void)dm320_wrrequest(privep); + } + } + break; + + case USB_INT_SOF: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_SOF), 0); + break; + + case USB_INT_DISCONNECTED: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_DISCONNECTED), 0); + break; + + case USB_INT_SUSPEND: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_SUSPEND), 0); + break; + + default: + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_UNKNOWN), 0); + break; + } + + intstatus = intstatus & ~priorityint; + + } + while (intstatus != USB_INT_NOINTERRUPT); + return OK; +} + +/**************************************************************************** + * Name: dm320_attachinterrupt + * + * Description: + * Attach GIO interrtup handler + * + ****************************************************************************/ + +static int dm320_attachinterrupt(int irq, FAR void *context) +{ + struct dm320_usbdev_s *priv = &g_usbdev; + uint16_t gio; + + /* Check if the USB device was connected to or disconnected from a host */ + + gio = dm320_getreg16(DM320_GIO_BITSET0); + usbtrace(TRACE_INTENTRY(DM320_TRACEINTID_ATTACH), gio); + if ((gio & (1 << CONFIG_DM320_GIO_USBATTACH)) == 0) + { + /* The host is disconnected */ + + if (priv->attached) + { + /* We have detected a transition from attached to detached */ + + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_DETACHED), 0); + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + priv->attached = 0; + + dm320_putreg16(dm320_getreg16(DM320_CLKC_LPCTL1) | 0x0010, DM320_CLKC_LPCTL1); + if ((dm320_getreg8(DM320_USB_PERTXCSR1) & USB_TXCSR1_FIFOEMP)) + { + dm320_putreg8(USB_TXCSR1_FLFIFO, DM320_USB_PERTXCSR1); + up_mdelay(5); + } + } + } + else if (!priv->attached) + { + /* We have a transition from unattached to attached */ + + usbtrace(TRACE_INTDECODE(DM320_TRACEINTID_ATTACHED), 0); + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + dm320_ctrlinitialize(priv); + + dm320_putreg16(dm320_getreg16(DM320_INTC_FISEL0) & 0x7f, DM320_INTC_FISEL0); + dm320_putreg16(dm320_getreg16(DM320_INTC_EINT0) | 0x80, DM320_INTC_EINT0); + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + priv->paddrset = 0; + priv->paddr = 0; + priv->attached = 1; + } + return OK; +} + +/**************************************************************************** + * Name: dm320_epreset + ****************************************************************************/ + +static void dm320_epreset(unsigned int index) +{ + dm320_putreg8(index, DM320_USB_INDEX); + dm320_putreg8(USB_PERCSR0_CLRSETEND | USB_PERCSR0_CLRRXRDY, DM320_USB_PERCSR0); + dm320_putreg8(USB_CSR2_FLFIFO, DM320_USB_CSR2); + dm320_putreg8(USB_CSR2_FLFIFO, DM320_USB_CSR2); +} + +/**************************************************************************** + * Name: dm320_epinitialize + * + * Description: + * Initialize endpoints. This is logically a part of dm320_ctrlinitialize + * + ****************************************************************************/ + +static inline void dm320_epinitialize(struct dm320_usbdev_s *priv) +{ + uint16_t offset; /* Full USB buffer offset */ + uint8_t addrhi; /* MS bytes of ofset */ + uint8_t addrlo; /* LS bytes of offset */ + int i; + + /* Initialize endpoint 0 */ + + dm320_putreg8(USB_EP0_SELECT, DM320_USB_INDEX); + dm320_putreg8(USB_PERCSR0_CLRSETEND | USB_PERCSR0_CLRRXRDY, + DM320_USB_PERCSR0); + dm320_putreg8(USB_CSR2_FLFIFO, DM320_USB_CSR2); + dm320_putreg8(USB_CSR2_FLFIFO, DM320_USB_CSR2); + + /* EP0 Fifo size/address (ofset == 0) */ + + dm320_putreg8(0x00, DM320_USB_TXFIFO1); + dm320_putreg8(0x00, DM320_USB_RXFIFO1); + dm320_putreg8(g_epinfo[0].fifo, DM320_USB_TXFIFO2); + dm320_putreg8(USB_TXFIFO2_SZ_64, DM320_USB_RXFIFO2); + + /* EP0 max packet size */ + + dm320_putreg8(g_epinfo[0].maxpacket >> 3, DM320_USB_TXMAXP); + dm320_putreg8(g_epinfo[0].maxpacket >> 3, DM320_USB_RXMAXP); + + /* Setup bulk-in, bulk-out, iso-in, iso-out, and intr endpoints using the + * g_epinfo[] array. + */ + + offset = DM320_EP0MAXPACKET; /* move to next buffer position */ + for (i = 1; i < DM320_NENDPOINTS; i++) + { + dm320_putreg8(g_epinfo[i].addr & 0x0f, DM320_USB_INDEX); + + addrlo = (offset >> 8) & 0xff; + addrhi = (offset >= 2048) ? 1 : 0; + + /* Configure IN endpoints (device-to-host) */ + + if (USB_EPIN(g_epinfo[i].addr)) + { + /* Initialize TX endpoint */ + + dm320_putreg8(USB_TXCSR1_CLRDATTOG | USB_TXCSR1_FLFIFO | + USB_TXCSR1_UNDERRUN, + DM320_USB_PERTXCSR1); + dm320_putreg8(USB_TXCSR1_FLFIFO, DM320_USB_PERTXCSR1); + dm320_putreg8(USB_TXCSR2_FRDATTOG | USB_TXCSR2_MODE_TX, + DM320_USB_TXCSR2); + + /* FIFO address, max packet size, dual/single buffered */ + + dm320_putreg8(addrlo, DM320_USB_TXFIFO1); + dm320_putreg8(addrhi | g_epinfo[i].fifo, DM320_USB_TXFIFO2); + + /* TX endpoint max packet size */ + + dm320_putreg8(g_epinfo[i].maxpacket >> 3, DM320_USB_TXMAXP); + } + + /* Configure OUT endpoints (host-to-device) */ + + else + { + /* Initialize RX endpoint */ + + dm320_putreg8(USB_PERRXCSR1_CLRDATTOG | USB_PERRXCSR1_FLFIFO, + DM320_USB_PERRXCSR1); + dm320_putreg8(USB_PERRXCSR1_FLFIFO, DM320_USB_PERRXCSR1); + dm320_putreg8(0x00, DM320_USB_PERRXCSR2); + + /* FIFO address, max packet size, dual/single buffered */ + + dm320_putreg8(addrhi, DM320_USB_RXFIFO1); + dm320_putreg8(addrhi | g_epinfo[i].fifo | USB_RXFIF02_DPB, DM320_USB_RXFIFO2); + + /* RX endpoint max packet size */ + + dm320_putreg8(g_epinfo[i].maxpacket >> 3, DM320_USB_RXMAXP); + } + offset += g_epinfo[i].maxpacket; + } +} + +/**************************************************************************** + * Name: dm320_ctrlinitialize + * + * Description: + * Initialize the DM320 USB controller for peripheral mode operation . + * + ****************************************************************************/ + +static void dm320_ctrlinitialize(FAR struct dm320_usbdev_s *priv) +{ + /* Setup the USB controller for operation as a periperhal *******************/ + /* Enable USB clock */ + + dm320_putreg16(dm320_getreg16(DM320_CLKC_MOD2) | 0x0060, DM320_CLKC_MOD2); + + /* Disable USB Power down mode */ + + dm320_putreg16(dm320_getreg16(DM320_CLKC_LPCTL1) & 0xFFEF, DM320_CLKC_LPCTL1); + + /* Put USB controller in peripheral mode */ + + dm320_putreg32(0x00000000, DM320_AHB_USBCTL); + dm320_putreg8(USB_DEVCTL_SESSREQ, DM320_USB_DEVCTL); + + /* Reset USB controller registers */ + + dm320_putreg8(0x00, DM320_USB_FADDR); /* Reset peripheral address register */ + dm320_putreg8(0x00, DM320_USB_POWER); /* Reset power control register */ + + /* Initialize interrupts *****************************************************/ + + up_ack_irq(DM320_IRQ_USB0); /* Clear USB controller interrupt */ + up_ack_irq(DM320_IRQ_USB1); /* Clear USB DMA interrupt flag */ + + dm320_getreg8(DM320_USB_INTRTX1); /* Clear TX interrupt */ + dm320_getreg8(DM320_USB_INTRRX1); /* Clear RX interrupt */ + dm320_getreg8(DM320_USB_INTRUSB); /* Clear control interrupt */ + dm320_getreg8(DM320_USB_DMAINTR); + + /* Enable USB interrupts */ + + dm320_putreg8((DM320_EPBULKIN << 1), DM320_USB_INTRRX1E); + dm320_putreg8((DM320_EPBULKOUT << 1) | USB_EP0, DM320_USB_INTRTX1E); + dm320_putreg8(USB_INT_RESET | USB_INT_RESUME | USB_INT_SUSPEND | + USB_INT_SESSRQ | USB_INT_SOF, + DM320_USB_INTRUSBE); + + /* Initialize endpoints ******************************************************/ + + dm320_epinitialize(priv); + + /* Peripheral address has not yet been set */ + + priv->paddr = 0; + dm320_putreg8(0, DM320_USB_FADDR); + + /* Finished -- set default endpoint as EP0 */ + + dm320_putreg8(USB_EP0_SELECT, DM320_USB_INDEX); +} + +/**************************************************************************** + * Endpoint Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: dm320_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int dm320_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct dm320_ep_s *privep = (FAR struct dm320_ep_s *)ep; + + /* Retain what we need from the descriptor */ + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + UNUSED(privep); + DEBUGASSERT(desc->addr == ep->eplog); + return OK; +} + +/**************************************************************************** + * Name: dm320_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int dm320_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct dm320_ep_s *privep = (FAR struct dm320_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Cancel any ongoing activity and reset the endpoint */ + + flags = enter_critical_section(); + dm320_cancelrequests(privep); + dm320_epreset(privep->epphy); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: dm320_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *dm320_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct dm320_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct dm320_ep_s *)ep)->epphy); + + privreq = (FAR struct dm320_req_s *)kmm_malloc(sizeof(struct dm320_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct dm320_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: dm320_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void dm320_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct dm320_req_s *privreq = (FAR struct dm320_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct dm320_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: dm320_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *dm320_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: dm320_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void dm320_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: dm320_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int dm320_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct dm320_req_s *privreq = (FAR struct dm320_req_s *)req; + FAR struct dm320_ep_s *privep = (FAR struct dm320_ep_s *)ep; + FAR struct dm320_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_NOTCONFIGURED), 0); + return -ESHUTDOWN; + } + + req->result = -EINPROGRESS; + req->xfrd = 0; + flags = enter_critical_section(); + + /* Check for NULL packet */ + + if (req->len == 0 && (privep->in || privep->epphy == 3)) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_NULLPACKET), 0); + dm320_putreg8(dm320_getreg8(DM320_USB_PERTXCSR1) | USB_TXCSR1_TXPKTRDY, DM320_USB_PERTXCSR1); + dm320_abortrequest(privep, privreq, OK); + } + + /* If we are stalled, then drop all requests on the floor */ + + else if (privep->stalled) + { + dm320_abortrequest(privep, privreq, -EBUSY); + ret = -EBUSY; + } + + /* Handle zero-length transfers on EP0 */ + + else if (privep->epphy == 0 && req->len == 0) + { + /* Nothing to transfer -- exit success, with zero bytes transferred */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + dm320_abortrequest(privep, privreq, OK); + } + + /* Handle IN (device-to-host) requests */ + + else if ((privep->in) || privep->epphy == 3) + { + /* Add the new request to the request queue for the IN endpoint */ + + dm320_rqenqueue(privep, privreq); + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + ret = dm320_wrrequest(privep); + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + privep->txnullpkt = 0; + dm320_rqenqueue(privep, privreq); + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + + /* This there a incoming data pending the availability of a request? */ + + if (priv->rxpending) + { + ret = dm320_rdrequest(privep); + priv->rxpending = 0; + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: dm320_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int dm320_epcancel(struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct dm320_ep_s *privep = (FAR struct dm320_ep_s *)ep; + FAR struct dm320_usbdev_s *priv; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + priv = privep->dev; + + flags = enter_critical_section(); + dm320_cancelrequests(privep); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: dm320_allocep + * + * Description: + * Allocate an endpoint matching the parameters + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *dm320_allocep(FAR struct usbdev_s *dev, uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct dm320_usbdev_s *priv = (FAR struct dm320_usbdev_s *)dev; + int ndx; + + usbtrace(TRACE_DEVALLOCEP, 0); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* Check all endpoints (except EP0) */ + + for (ndx = 1; ndx < DM320_NENDPOINTS; ndx++) + { + /* Does this match the endpoint number (if one was provided?) */ + + if (eplog != 0 && eplog != USB_EPNO(priv->eplist[ndx].ep.eplog)) + { + continue; + } + + /* Does the direction match */ + + if (in) + { + if (!USB_EPIN(g_epinfo[ndx].addr)) + { + continue; + } + } + else + { + if (!USB_EPOUT(g_epinfo[ndx].addr)) + { + continue; + } + } + + /* Does the type match? */ + + if (g_epinfo[ndx].attr == eptype) + { + /* Success! */ + + return &priv->eplist[ndx].ep; + } + } + + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_NOEP), 0); + return NULL; +} + +/**************************************************************************** + * Name: dm320_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void dm320_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct dm320_ep_s *privep = (FAR struct dm320_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + UNUSED(privep); + + /* Nothing needs to be done */ +} + +/**************************************************************************** + * Name: dm320_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int dm320_getframe(struct usbdev_s *dev) +{ + irqstate_t flags; + int ret; + + usbtrace(TRACE_DEVGETFRAME, 0); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + /* Return the contents of the frame register. Interrupts must be disabled + * because the operation is not atomic. + */ + + flags = enter_critical_section(); + ret = dm320_getreg8(DM320_USB_FRAME2) << 8; + ret |= dm320_getreg8(DM320_USB_FRAME1); + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: dm320_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int dm320_wakeup(struct usbdev_s *dev) +{ + irqstate_t flags; + usbtrace(TRACE_DEVWAKEUP, 0); + + flags = enter_critical_section(); + dm320_putreg8(USB_POWER_RESUME, DM320_USB_POWER); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: dm320_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int dm320_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct dm320_usbdev_s *priv = &g_usbdev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: dm320_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +#ifdef CONFIG_DM320_GIO_USBDPPULLUP +static int dm320_pullup(struct usbdev_s *dev, bool enable) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + flags = enter_critical_section(); + if (enable) + { + GIO_SET_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); /* Set D+ pullup */ + } + else + { + GIO_CLEAR_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); /* Clear D+ pullup */ + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + struct dm320_usbdev_s *priv = &g_usbdev; + struct dm320_ep_s *privep; +#ifdef CONFIG_DEBUG_USB + uint16_t chiprev; +#endif + int i; + + usbtrace(TRACE_DEVINIT, 0); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct dm320_usbdev_s)); + priv->usbdev.ops = &g_devops; + +#ifdef CONFIG_DEBUG_USB + chiprev = dm320_getreg16(DM320_BUSC_REVR); + ulldbg("DM320 revision : %d.%d\n", chiprev >> 4, chiprev & 0x0f); +#endif + + /* Enable USB clock & GIO clock */ + + dm320_putreg16(dm320_getreg16(DM320_CLKC_MOD2) | 0x0060, DM320_CLKC_MOD2); + dm320_putreg16(dm320_getreg16(DM320_CLKC_DIV4) | (((4) - 1) << 8) | ((1) - 1), DM320_CLKC_DIV4); + + /* Initialize D+ pullup control GIO */ + + GIO_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); + GIO_SET_OUTPUT(CONFIG_DM320_GIO_USBDPPULLUP); + + /* Initilialize USB attach GIO */ + + GIO_INTERRUPT(CONFIG_DM320_GIO_USBATTACH); + GIO_BOTHEDGES(CONFIG_DM320_GIO_USBATTACH); + dm320_putreg16(dm320_getreg16(DM320_GIO_CHAT0) | (1 << CONFIG_DM320_GIO_USBATTACH), DM320_GIO_CHAT0); + + /* Attach host attach GIO interrupt */ + + if (irq_attach(IRQ_USBATTACH, dm320_attachinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_ATTACHIRQREG), 0); + goto errout; + } + + /* Attach USB controller core interrupt handler -- interrupts will be + * enabled when the driver is bound + */ + + if (irq_attach(DM320_IRQ_USB1, dm320_ctlrinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_COREIRQREG), 0); + goto errout; + } + + /* Initialize the DM320 USB controller for peripheral mode operation. */ + + dm320_ctrlinitialize(priv); + + /* Perform endpoint initialization */ + + for (i = 0; i < DM320_NENDPOINTS; i++) + { + /* Set up the standard stuff */ + + privep = &priv->eplist[i]; + memset(privep, 0, sizeof(struct dm320_ep_s)); + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = g_epinfo[i].addr; + + /* Setup the endpoint-specific stuff */ + + priv->eplist[i].ep.maxpacket = g_epinfo[i].maxpacket; + if (USB_EPIN(g_epinfo[i].addr)) + { + priv->eplist[i].in = 1; + } + + /* Reset the endpoint */ + + dm320_epreset(privep->epphy); + } + + /* Expose only the standard EP0 */ + + priv->usbdev.ep0 = &priv->eplist[0].ep; + + /* For 'B' device initiate session request protocol */ + + dm320_putreg8(USB_DEVCTL_SESSREQ, DM320_USB_DEVCTL); + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct dm320_usbdev_s *priv = &g_usbdev; + + usbtrace(TRACE_DEVUNINIT, 0); + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + dm320_putreg16(dm320_getreg16(DM320_CLKC_LPCTL1) | 0x0010, DM320_CLKC_LPCTL1); + + /* Disable and detach IRQs */ + + up_disable_irq(IRQ_USBATTACH); + up_disable_irq(DM320_IRQ_USB1); + + irq_detach(IRQ_USBATTACH); + irq_detach(DM320_IRQ_USB1); +} + +/************************************************************************************ + * Name: usbdevclass_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ************************************************************************************/ + +int usbdev_register(FAR struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || (driver->speed != USB_SPEED_FULL) || !driver->ops->bind || + !driver->ops->unbind || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* Hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + return ret; + } + + /* Enable host detection and ep0 RX/TX */ + + dm320_epreset(0); + dm320_putreg8(USB_EP0, DM320_USB_INTRTX1E); + dm320_putreg8(USB_INT_RESET | USB_INT_RESUME | USB_INT_SUSPEND | + USB_INT_SESSRQ | USB_INT_SOF, + DM320_USB_INTRUSBE); + + /* Enable interrupts */ + + up_enable_irq(IRQ_USBATTACH); + up_enable_irq(DM320_IRQ_USB1); + return OK; +} + +/************************************************************************************ + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ************************************************************************************/ + +int usbdev_unregister(FAR struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(DM320_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable IRQs */ + + up_disable_irq(IRQ_USBATTACH); + up_disable_irq(DM320_IRQ_USB1); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} + + diff --git a/arch/arm/src/efm32/Kconfig b/arch/arm/src/efm32/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..0b90826e5edd5bda31e5e9b09f9e6a9c307b267b --- /dev/null +++ b/arch/arm/src/efm32/Kconfig @@ -0,0 +1,610 @@ +# +# arch/arm/src/efm32/Kconfig +# + +if ARCH_CHIP_EFM32 + +comment "EFM32 Configuration Options" + +choice + prompt "EFM32 Chip Selection" + default ARCH_CHIP_EFM32TG840F32 + +config ARCH_CHIP_EFM32TG840F32 + bool "EFM32TG840F32" + select EFM32_EFM32TG + select ARCH_CORTEXM3 + ---help--- + This chip is a Tiny Gecko with 32 KB flash and 4 KB RAM in a QFN64 + package + +config ARCH_CHIP_EFM32G880F128 + bool "EFM32G880F128" + select EFM32_EFM32G + select ARCH_CORTEXM3 + ---help--- + This chip is a Gecko with 128KiB flash and 16KiB RAM in a LQFP100 + package + +config ARCH_CHIP_EFM32G890F128 + bool "EFM32G890F128" + select EFM32_EFM32G + select ARCH_CORTEXM3 + ---help--- + This chip is a Gecko with 128KiB flash and 16KiB RAM in a BGA112 + package + +config ARCH_CHIP_EFM32GG332F1024 + bool "EFM32GG332F1024" + select EFM32_EFM32GG + select ARCH_CORTEXM3 + ---help--- + This chip is a Giant Gecko with 1024KiB flash and 128KiB RAM in a + QFP64 package. + +config ARCH_CHIP_EFM32GG990F1024 + bool "EFM32GG990F1024" + select EFM32_EFM32GG + select ARCH_CORTEXM3 + ---help--- + This chip is a Giant Gecko with 1024KiB flash and 128KiB RAM in a + BGA112 package. + +endchoice + +# These hidden selections represent automatically selected MCU families and, +# in turn, select general capabilities of the MCU family + +config EFM32_EFM32TG + bool + default n + +config EFM32_EFM32G + bool + default n + select EFM32_HAVE_USART2 + select EFM32_HAVE_UART0 + select EFM32_HAVE_LEUART1 + +config EFM32_EFM32GG + bool + default n + select EFM32_HAVE_USART2 + select EFM32_HAVE_UART0 + select EFM32_HAVE_UART1 + select EFM32_HAVE_LEUART1 + select EFM32_HAVE_OTGFS + +menu "EFM32 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for +# the selection MCU + +config EFM32_HAVE_USART2 + bool + default n + +config EFM32_HAVE_UART0 + bool + default n + +config EFM32_HAVE_UART1 + bool + default n + +config EFM32_HAVE_LEUART1 + bool + default n + +config EFM32_HAVE_OTGFS + bool + default n + +# When there are multiple instances of a device, these "hidden" settings +# will automatically be selected and will represent the 'OR' of the +# instances selected. + +config EFM32_USART_ISUART + bool + default n + +config EFM32_USART_ISSPI + bool + default n + +config EFM32_UART + bool + default n + +config EFM32_LEUART + bool + default n + select MCU_SERIAL + +# Then, these are the actual, selectable peripheral options + +config EFM32_DMA + bool "DMA" + default n + select ARCH_DMA + +config EFM32_RMU + bool "Reset Management Unit (RMU) " + default n + +config EFM32_FLASHPROG + bool "Enable Erase/Write flash function (MSC) " + default n + select ARCH_HAVE_RAMFUNCS + +config EFM32_RMU_DEBUG + bool "Reset Management Unit (RMU) DEBUG " + default n + depends on EFM32_RMU && DEBUG + +config EFM32_I2C0 + bool "I2C0" + default n + +config EFM32_I2C1 + bool "I2C1" + default n + +config EFM32_BITBAND + bool "BITBAND" + default n + +config EFM32_USART0 + bool "USART0" + default n + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config EFM32_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config EFM32_USART2 + bool "USART2" + default n + depends on EFM32_HAVE_USART2 + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config EFM32_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + select EFM32_UART + +config EFM32_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select EFM32_UART + +config EFM32_LEUART0 + bool "Low energy UART0" + default n + select ARCH_HAVE_OTHER_UART + select EFM32_LEUART + +config EFM32_LEUART1 + bool "Low energy UART1" + default n + depends on EFM32_HAVE_LEUART1 + select ARCH_HAVE_OTHER_UART + select EFM32_LEUART + +config EFM32_OTGFS + bool "USB Full-Speed OTG" + default n + depends on EFM32_HAVE_OTGFS && EXPERIMENTAL + select USBHOST_HAVE_ASYNCH if USBHOST + +config EFM32_TIMER0 + bool "TIMER0" + default n + select ARCH_HAVE_TIMER0 + select EFM32_TIMER + +config EFM32_TIMER1 + bool "TIMER1" + default n + select ARCH_HAVE_TIMER1 + select EFM32_TIMER + +config EFM32_TIMER2 + bool "TIMER2" + default n + select ARCH_HAVE_TIMER2 + select EFM32_TIMER + +config EFM32_TIMER3 + bool "TIMER3" + default n + select ARCH_HAVE_TIMER3 + select EFM32_TIMER + +endmenu # EFM32 Peripheral Support + +config EFM32_GPIO_IRQ + bool "GPIO pin interrupts" + ---help--- + Enable support for interrupting GPIO pins + +config EFM32_LECLOCK + bool "Enable LE clocking (unconditionally)" + default n + ---help--- + Even you don't use core clock LE as source for LFA or LFB, to read + are write any register not clocked by HFPERCLK or HFCORECLK, + HFCORECLKLE should be enabled. + +if EFM32_DMA + +config EFM32_DMA_ALTDSEC + int "Enable alternate descriptors" + default 8 + depends on EXPERIMENTAL + ---help--- + Enable support for alternate descriptors. Not fully implemented. + +endif + +choice + prompt "USART0 Mode" + default EFM32_USART0_ISUART + depends on EFM32_USART0 + +config EFM32_USART0_ISUART + bool "USART0 is a UART" + select USART0_ISUART + select EFM32_USART_ISUART + +config EFM32_USART0_ISSPI + bool "USART0 is SPI" + select EFM32_USART_ISSPI + +endchoice # USART0 Mode + +choice + prompt "USART1 Mode" + default EFM32_USART1_ISUART + depends on EFM32_USART1 + +config EFM32_USART1_ISUART + bool "USART1 is a UART" + select USART1_ISUART + select EFM32_USART_ISUART + +config EFM32_USART1_ISSPI + bool "USART1 is SPI" + select EFM32_USART_ISSPI + +endchoice # USART1 Mode + +choice + prompt "USART2 Mode" + default EFM32_USART2_ISUART + depends on EFM32_USART2 + +config EFM32_USART2_ISUART + bool "USART2 is a UART" + select USART2_ISUART + select EFM32_USART_ISUART + +config EFM32_USART2_ISSPI + bool "USART2 is SPI" + select EFM32_USART_ISSPI + +endchoice # USART2 Mode + +choice + prompt "LEUART Serial Console" + default NO_LEUART_SERIAL_CONSOLE + depends on DEV_CONSOLE && EFM32_LEUART + +config LEUART0_SERIAL_CONSOLE + bool "Use LEUART0 as the serial console" + depends on EFM32_LEUART0 + select OTHER_SERIAL_CONSOLE + ---help--- + Use the LEUART0 device as the serial console + +config LEUART1_SERIAL_CONSOLE + bool "Use LEUART1 as the serial console" + depends on EFM32_LEUART1 + select OTHER_SERIAL_CONSOLE + ---help--- + Use the LEUART0 device as the serial console + +config NO_LEUART_SERIAL_CONSOLE + bool "No LEUART serial console" + ---help--- + No serial console OR some other serial device provides the serial console + +endchoice # LEUART Serial Console + +menu "LEUART0 Configuration" + depends on EFM32_LEUART0 + +config LEUART0_RXBUFSIZE + int "Receive buffer size" + default 64 + ---help--- + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config LEUART0_TXBUFSIZE + int "Transmit buffer size" + default 64 + ---help--- + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config LEUART0_BAUD + int "BAUD rate" + default 2400 + ---help--- + The configured BAUD of the UART. + +config LEUART0_BITS + int "Character size" + default 8 + range 8 9 + ---help--- + The number of bits. Must be either 8 or 9. + +config LEUART0_PARITY + int "Parity setting" + range 0 2 + default 0 + ---help--- + 0=no parity, 1=odd parity, 2=even parity + +config LEUART0_2STOP + int "use 2 stop bits" + default 0 + range 0 1 + ---help--- + 1=Two stop bits + +endmenu # LEUART0 Configuration + +menu "LEUART1 Configuration" + depends on EFM32_LEUART1 + +config LEUART1_RXBUFSIZE + int "Receive buffer size" + default 64 + ---help--- + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config LEUART1_TXBUFSIZE + int "Transmit buffer size" + default 64 + ---help--- + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config LEUART1_BAUD + int "BAUD rate" + default 2400 + ---help--- + The configured BAUD of the UART. + +config LEUART1_BITS + int "Character size" + default 8 + range 8 9 + ---help--- + The number of bits. Must be either 8 or 9. + +config LEUART1_PARITY + int "Parity setting" + range 0 2 + default 0 + ---help--- + 0=no parity, 1=odd parity, 2=even parity + +config LEUART1_2STOP + int "use 2 stop bits" + default 0 + range 0 1 + ---help--- + 1=Two stop bits + +endmenu # LEUART1 Configuration + +if EFM32_USART_ISSPI +menu "SPI Configuration" + +config EFM32_SPI_DMA + bool "SPI DMA support" + default n + depends on EFM32_DMA + ---help--- + Select to enable DMA SPI transfers + +if EFM32_SPI_DMA + +config EFM32_SPI_DMA_TIMEO_NSEC + int "Per word timeout (nsec)" + default 500 + ---help--- + A timeout will be be used to detect hung DMA transfers. The timeout + will vary as a function of the number of words transferred. This + value provides the per-word timeout value in nanoseconds. + +config EFM32_SPI_DMA_MINSIZE + int "Minimum DMA size" + default 16 + ---help--- + DMA is particularly helpful for the case of large SPI transfers. + Smaller SPI transfer may be more efficiently performed without DMA. + This option determines a threshold: For transfers of this size and + below, DMA will not be used. A value of zero will force all DMA- + based transfers. + +endif # EFM32_SPI_DMA +endmenu # SPI Configuration +endif # EFM32_USART_ISSPI + +menu "USB FS Host Configuration" + depends on USBHOST && EFM32_OTGFS + +config EFM32_OTGFS_RXFIFO_SIZE + int "Rx Packet Size" + default 128 + ---help--- + Size of the RX FIFO in 32-bit words. Default 128 (512 bytes) + +config EFM32_OTGFS_NPTXFIFO_SIZE + int "Non-periodic Tx FIFO Size" + default 96 + ---help--- + Size of the non-periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config EFM32_OTGFS_PTXFIFO_SIZE + int "Periodic Tx FIFO size" + default 128 + ---help--- + Size of the periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config EFM32_OTGFS_DESCSIZE + int "Descriptor Size" + default 128 + ---help--- + Maximum size to allocate for descriptor memory descriptor. Default: 128 + +config EFM32_OTGFS_SOFINTR + bool "Enable SOF interrupts" + default n + ---help--- + Enable SOF interrupts. Why would you ever want to do that? + +endmenu + +config EFM32_TIMER0 + bool "TIMER0" + default n + depends on EFM32_HAVE_TIMER0 + +config EFM32_TIMER0_PWM + bool "TIMER0 PWM" + default n + depends on EFM32_TIMER0 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 0 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. + If EFM32_TIMER0 is defined then THIS following may also be defined + to indicate that the timer is intended to be used for pulsed output + modulation. + +config EFM32_TIMER0_CHANNEL + int "TIMER0 PWM Output Channel" + default 0 + range 0 2 + depends on EFM32_TIMER0_PWM + ---help--- + If TIMER0 is enabled for PWM usage, you also need specifies the timer output + channel {0,1,2} + +config EFM32_TIMER1 + bool "TIMER1" + default n + depends on EFM32_HAVE_TIMER1 + +config EFM32_TIMER1_PWM + bool "TIMER1 PWM" + default n + depends on EFM32_TIMER1 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 0 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. + If EFM32_TIMER1 is defined then THIS following may also be defined + to indicate that the timer is intended to be used for pulsed output + modulation. + +config EFM32_TIMER1_CHANNEL + int "TIMER1 PWM Output Channel" + default 0 + range 0 2 + depends on EFM32_TIMER1_PWM + ---help--- + If TIMER1 is enabled for PWM usage, you also need specifies the timer output + channel {0,1,2} + +config EFM32_TIMER2 + bool "TIMER2" + default n + depends on EFM32_HAVE_TIMER2 + +config EFM32_TIMER2_PWM + bool "TIMER2 PWM" + default n + depends on EFM32_TIMER2 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 0 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. + If EFM32_TIMER2 is defined then THIS following may also be defined + to indicate that the timer is intended to be used for pulsed output + modulation. + +config EFM32_TIMER2_CHANNEL + int "TIMER2 PWM Output Channel" + default 0 + range 0 2 + depends on EFM32_TIMER2_PWM + ---help--- + If TIMER2 is enabled for PWM usage, you also need specifies the timer output + channel {0,1,2} + +config EFM32_TIMER3 + bool "TIMER3" + default n + depends on EFM32_HAVE_TIMER3 + +config EFM32_TIMER3_PWM + bool "TIMER3 PWM" + default n + depends on EFM32_TIMER3 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 0 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. + If EFM32_TIMER3 is defined then THIS following may also be defined + to indicate that the timer is intended to be used for pulsed output + modulation. + +config EFM32_TIMER3_CHANNEL + int "TIMER3 PWM Output Channel" + default 0 + range 0 2 + depends on EFM32_TIMER3_PWM + ---help--- + If TIMER3 is enabled for PWM usage, you also need specifies the timer output + channel {0,1,2} + +config EFM32_RTC_BURTC + bool "Use BURTC as RTC" + default n + ---help--- + Enable RTC with EFM32 BURTC + +endif # ARCH_CHIP_EFM32 diff --git a/arch/arm/src/efm32/Make.defs b/arch/arm/src/efm32/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..623941031bb7e1ed505e2d9c6ec5f165485e2bc4 --- /dev/null +++ b/arch/arm/src/efm32/Make.defs @@ -0,0 +1,165 @@ +############################################################################ +# arch/arm/src/efm32/Make.defs +# +# Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_hardfault.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_itm.c up_mdelay.c up_memfault.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_svcall.c up_systemreset.c +CMN_CSRCS += up_udelay.c up_unblocktask.c up_usestack.c up_vfork.c + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y) +CMN_CSRCS += up_itm_syslog.c +endif + +CHIP_ASRCS = + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CHIP_ASRCS += efm32_vectors.S +endif + +CHIP_CSRCS = efm32_start.c efm32_clockconfig.c efm32_irq.c efm32_timerisr.c +CHIP_CSRCS += efm32_gpio.c efm32_lowputc.c efm32_timer.c efm32_i2c.c + +ifeq ($(CONFIG_EFM32_FLASHPROG),y) +CHIP_CSRCS += efm32_flash.c +endif + +ifeq ($(CONFIG_EFM32_BITBAND),y) +CHIP_CSRCS += efm32_bitband.c +endif + +ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += efm32_idle.c +endif + +ifeq ($(CONFIG_EFM32_USART_ISUART),y) +CHIP_CSRCS += efm32_serial.c +else +ifeq ($(CONFIG_EFM32_UART),y) +CHIP_CSRCS += efm32_serial.c +endif +endif + +ifeq ($(CONFIG_EFM32_RMU),y) +CHIP_CSRCS += efm32_rmu.c +endif + +ifeq ($(CONFIG_EFM32_USART_ISSPI),y) +CHIP_CSRCS += efm32_spi.c +endif + +ifeq ($(CONFIG_EFM32_LEUART),y) +CHIP_CSRCS += efm32_leserial.c +endif + +ifeq ($(CONFIG_EFM32_GPIO_IRQ),y) +CHIP_CSRCS += efm32_gpioirq.c +endif + +ifeq ($(CONFIG_EFM32_DMA),y) +CHIP_CSRCS += efm32_dma.c +endif + +ifeq ($(CONFIG_EFM32_RTC_BURTC),y) +CHIP_CSRCS += efm32_rtc_burtc.c +endif + +ifeq ($(CONFIG_EFM32_OTGFS),y) +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += efm32_usbdev.c +endif +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += efm32_usbhost.c +endif +endif + +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += efm32_pwm.c +endif diff --git a/arch/arm/src/efm32/chip.h b/arch/arm/src/efm32/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..207ffa17c137e7066ec0c170bcbd98684770db69 --- /dev/null +++ b/arch/arm/src/efm32/chip.h @@ -0,0 +1,69 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Gregory Nutt + * Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* Include the chip pin configuration file */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR +# if defined(CONFIG_EFM32_EFM32TG) +# include "chip/efm32tg_vectors.h" +# elif defined(CONFIG_EFM32_EFM32G) +# include "chip/efm32g_vectors.h" +# elif defined(CONFIG_EFM32_EFM32GG) +# include "chip/efm32gg_vectors.h" +# else +# error "No vector file for this EFM32 family" +# endif +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_H */ diff --git a/arch/arm/src/efm32/chip/efm32_acmp.h b/arch/arm/src/efm32/chip/efm32_acmp.h new file mode 100644 index 0000000000000000000000000000000000000000..e9956ba8e486f96662a8f97772e8d9cc812774a2 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_acmp.h @@ -0,0 +1,402 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_acmp.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ACMP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ACMP_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* ACMP Register Offsets *******************************************************************************************************/ + +#define EFM32_ACMP_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_ACMP_INPUTSEL_OFFSET 0x0004 /* Input Selection Register */ +#define EFM32_ACMP_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_ACMP_IEN_OFFSET 0x000c /* Interrupt Enable Register */ +#define EFM32_ACMP_IF_OFFSET 0x0010 /* Interrupt Flag Register */ +#define EFM32_ACMP_IFS_OFFSET 0x0014 /* Interrupt Flag Set Register */ +#define EFM32_ACMP_IFC_OFFSET 0x0018 /* Interrupt Flag Clear Register */ +#define EFM32_ACMP_ROUTE_OFFSET 0x001c /* I/O Routing Register */ + +/* ACMP Register Addresses *****************************************************************************************************/ + +#define EFM32_ACMP0_CTRL (EFM32_ACMP0_BASE+EFM32_ACMP_CTRL_OFFSET) +#define EFM32_ACMP0_INPUTSEL (EFM32_ACMP0_BASE+EFM32_ACMP_INPUTSEL_OFFSET) +#define EFM32_ACMP0_STATUS (EFM32_ACMP0_BASE+EFM32_ACMP_STATUS_OFFSET) +#define EFM32_ACMP0_IEN (EFM32_ACMP0_BASE+EFM32_ACMP_IEN_OFFSET) +#define EFM32_ACMP0_IF (EFM32_ACMP0_BASE+EFM32_ACMP_IF_OFFSET) +#define EFM32_ACMP0_IFS (EFM32_ACMP0_BASE+EFM32_ACMP_IFS_OFFSET) +#define EFM32_ACMP0_IFC (EFM32_ACMP0_BASE+EFM32_ACMP_IFC_OFFSET) +#define EFM32_ACMP0_ROUTE (EFM32_ACMP0_BASE+EFM32_ACMP_ROUTE_OFFSET) + +#define EFM32_ACMP1_CTRL (EFM32_ACMP1_BASE+EFM32_ACMP_CTRL_OFFSET) +#define EFM32_ACMP1_INPUTSEL (EFM32_ACMP1_BASE+EFM32_ACMP_INPUTSEL_OFFSET) +#define EFM32_ACMP1_STATUS (EFM32_ACMP1_BASE+EFM32_ACMP_STATUS_OFFSET) +#define EFM32_ACMP1_IEN (EFM32_ACMP1_BASE+EFM32_ACMP_IEN_OFFSET) +#define EFM32_ACMP1_IF (EFM32_ACMP1_BASE+EFM32_ACMP_IF_OFFSET) +#define EFM32_ACMP1_IFS (EFM32_ACMP1_BASE+EFM32_ACMP_IFS_OFFSET) +#define EFM32_ACMP1_IFC (EFM32_ACMP1_BASE+EFM32_ACMP_IFC_OFFSET) +#define EFM32_ACMP1_ROUTE (EFM32_ACMP1_BASE+EFM32_ACMP_ROUTE_OFFSET) + +/* ACMP Register Bit Field Definitions *****************************************************************************************/ + +/* Bit fields for ACMP CTRL */ + +#define _ACMP_CTRL_RESETVALUE 0x47000000UL /* Default value for ACMP_CTRL */ +#define _ACMP_CTRL_MASK 0xCF03077FUL /* Mask for ACMP_CTRL */ + +#define ACMP_CTRL_EN (0x1UL << 0) /* Analog Comparator Enable */ +#define _ACMP_CTRL_EN_SHIFT 0 /* Shift value for ACMP_EN */ +#define _ACMP_CTRL_EN_MASK 0x1UL /* Bit mask for ACMP_EN */ +#define _ACMP_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_EN_DEFAULT (_ACMP_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_MUXEN (0x1UL << 1) /* Input Mux Enable */ +#define _ACMP_CTRL_MUXEN_SHIFT 1 /* Shift value for ACMP_MUXEN */ +#define _ACMP_CTRL_MUXEN_MASK 0x2UL /* Bit mask for ACMP_MUXEN */ +#define _ACMP_CTRL_MUXEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_MUXEN_DEFAULT (_ACMP_CTRL_MUXEN_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_INACTVAL (0x1UL << 2) /* Inactive Value */ +#define _ACMP_CTRL_INACTVAL_SHIFT 2 /* Shift value for ACMP_INACTVAL */ +#define _ACMP_CTRL_INACTVAL_MASK 0x4UL /* Bit mask for ACMP_INACTVAL */ +#define _ACMP_CTRL_INACTVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_INACTVAL_LOW 0x00000000UL /* Mode LOW for ACMP_CTRL */ +#define _ACMP_CTRL_INACTVAL_HIGH 0x00000001UL /* Mode HIGH for ACMP_CTRL */ +#define ACMP_CTRL_INACTVAL_DEFAULT (_ACMP_CTRL_INACTVAL_DEFAULT << 2) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_INACTVAL_LOW (_ACMP_CTRL_INACTVAL_LOW << 2) /* Shifted mode LOW for ACMP_CTRL */ +#define ACMP_CTRL_INACTVAL_HIGH (_ACMP_CTRL_INACTVAL_HIGH << 2) /* Shifted mode HIGH for ACMP_CTRL */ +#define ACMP_CTRL_GPIOINV (0x1UL << 3) /* Comparator GPIO Output Invert */ +#define _ACMP_CTRL_GPIOINV_SHIFT 3 /* Shift value for ACMP_GPIOINV */ +#define _ACMP_CTRL_GPIOINV_MASK 0x8UL /* Bit mask for ACMP_GPIOINV */ +#define _ACMP_CTRL_GPIOINV_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_GPIOINV_NOTINV 0x00000000UL /* Mode NOTINV for ACMP_CTRL */ +#define _ACMP_CTRL_GPIOINV_INV 0x00000001UL /* Mode INV for ACMP_CTRL */ +#define ACMP_CTRL_GPIOINV_DEFAULT (_ACMP_CTRL_GPIOINV_DEFAULT << 3) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_GPIOINV_NOTINV (_ACMP_CTRL_GPIOINV_NOTINV << 3) /* Shifted mode NOTINV for ACMP_CTRL */ +#define ACMP_CTRL_GPIOINV_INV (_ACMP_CTRL_GPIOINV_INV << 3) /* Shifted mode INV for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_SHIFT 4 /* Shift value for ACMP_HYSTSEL */ +#define _ACMP_CTRL_HYSTSEL_MASK 0x70UL /* Bit mask for ACMP_HYSTSEL */ +#define _ACMP_CTRL_HYSTSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST0 0x00000000UL /* Mode HYST0 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST1 0x00000001UL /* Mode HYST1 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST2 0x00000002UL /* Mode HYST2 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST3 0x00000003UL /* Mode HYST3 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST4 0x00000004UL /* Mode HYST4 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST5 0x00000005UL /* Mode HYST5 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST6 0x00000006UL /* Mode HYST6 for ACMP_CTRL */ +#define _ACMP_CTRL_HYSTSEL_HYST7 0x00000007UL /* Mode HYST7 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_DEFAULT (_ACMP_CTRL_HYSTSEL_DEFAULT << 4) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST0 (_ACMP_CTRL_HYSTSEL_HYST0 << 4) /* Shifted mode HYST0 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST1 (_ACMP_CTRL_HYSTSEL_HYST1 << 4) /* Shifted mode HYST1 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST2 (_ACMP_CTRL_HYSTSEL_HYST2 << 4) /* Shifted mode HYST2 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST3 (_ACMP_CTRL_HYSTSEL_HYST3 << 4) /* Shifted mode HYST3 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST4 (_ACMP_CTRL_HYSTSEL_HYST4 << 4) /* Shifted mode HYST4 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST5 (_ACMP_CTRL_HYSTSEL_HYST5 << 4) /* Shifted mode HYST5 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST6 (_ACMP_CTRL_HYSTSEL_HYST6 << 4) /* Shifted mode HYST6 for ACMP_CTRL */ +#define ACMP_CTRL_HYSTSEL_HYST7 (_ACMP_CTRL_HYSTSEL_HYST7 << 4) /* Shifted mode HYST7 for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_SHIFT 8 /* Shift value for ACMP_WARMTIME */ +#define _ACMP_CTRL_WARMTIME_MASK 0x700UL /* Bit mask for ACMP_WARMTIME */ +#define _ACMP_CTRL_WARMTIME_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_4CYCLES 0x00000000UL /* Mode 4CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_8CYCLES 0x00000001UL /* Mode 8CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_16CYCLES 0x00000002UL /* Mode 16CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_32CYCLES 0x00000003UL /* Mode 32CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_64CYCLES 0x00000004UL /* Mode 64CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_128CYCLES 0x00000005UL /* Mode 128CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_256CYCLES 0x00000006UL /* Mode 256CYCLES for ACMP_CTRL */ +#define _ACMP_CTRL_WARMTIME_512CYCLES 0x00000007UL /* Mode 512CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_DEFAULT (_ACMP_CTRL_WARMTIME_DEFAULT << 8) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_4CYCLES (_ACMP_CTRL_WARMTIME_4CYCLES << 8) /* Shifted mode 4CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_8CYCLES (_ACMP_CTRL_WARMTIME_8CYCLES << 8) /* Shifted mode 8CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_16CYCLES (_ACMP_CTRL_WARMTIME_16CYCLES << 8) /* Shifted mode 16CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_32CYCLES (_ACMP_CTRL_WARMTIME_32CYCLES << 8) /* Shifted mode 32CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_64CYCLES (_ACMP_CTRL_WARMTIME_64CYCLES << 8) /* Shifted mode 64CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_128CYCLES (_ACMP_CTRL_WARMTIME_128CYCLES << 8) /* Shifted mode 128CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_256CYCLES (_ACMP_CTRL_WARMTIME_256CYCLES << 8) /* Shifted mode 256CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_WARMTIME_512CYCLES (_ACMP_CTRL_WARMTIME_512CYCLES << 8) /* Shifted mode 512CYCLES for ACMP_CTRL */ +#define ACMP_CTRL_IRISE (0x1UL << 16) /* Rising Edge Interrupt Sense */ +#define _ACMP_CTRL_IRISE_SHIFT 16 /* Shift value for ACMP_IRISE */ +#define _ACMP_CTRL_IRISE_MASK 0x10000UL /* Bit mask for ACMP_IRISE */ +#define _ACMP_CTRL_IRISE_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_IRISE_DISABLED 0x00000000UL /* Mode DISABLED for ACMP_CTRL */ +#define _ACMP_CTRL_IRISE_ENABLED 0x00000001UL /* Mode ENABLED for ACMP_CTRL */ +#define ACMP_CTRL_IRISE_DEFAULT (_ACMP_CTRL_IRISE_DEFAULT << 16) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_IRISE_DISABLED (_ACMP_CTRL_IRISE_DISABLED << 16) /* Shifted mode DISABLED for ACMP_CTRL */ +#define ACMP_CTRL_IRISE_ENABLED (_ACMP_CTRL_IRISE_ENABLED << 16) /* Shifted mode ENABLED for ACMP_CTRL */ +#define ACMP_CTRL_IFALL (0x1UL << 17) /* Falling Edge Interrupt Sense */ +#define _ACMP_CTRL_IFALL_SHIFT 17 /* Shift value for ACMP_IFALL */ +#define _ACMP_CTRL_IFALL_MASK 0x20000UL /* Bit mask for ACMP_IFALL */ +#define _ACMP_CTRL_IFALL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define _ACMP_CTRL_IFALL_DISABLED 0x00000000UL /* Mode DISABLED for ACMP_CTRL */ +#define _ACMP_CTRL_IFALL_ENABLED 0x00000001UL /* Mode ENABLED for ACMP_CTRL */ +#define ACMP_CTRL_IFALL_DEFAULT (_ACMP_CTRL_IFALL_DEFAULT << 17) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_IFALL_DISABLED (_ACMP_CTRL_IFALL_DISABLED << 17) /* Shifted mode DISABLED for ACMP_CTRL */ +#define ACMP_CTRL_IFALL_ENABLED (_ACMP_CTRL_IFALL_ENABLED << 17) /* Shifted mode ENABLED for ACMP_CTRL */ +#define _ACMP_CTRL_BIASPROG_SHIFT 24 /* Shift value for ACMP_BIASPROG */ +#define _ACMP_CTRL_BIASPROG_MASK 0xF000000UL /* Bit mask for ACMP_BIASPROG */ +#define _ACMP_CTRL_BIASPROG_DEFAULT 0x00000007UL /* Mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_BIASPROG_DEFAULT (_ACMP_CTRL_BIASPROG_DEFAULT << 24) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_HALFBIAS (0x1UL << 30) /* Half Bias Current */ +#define _ACMP_CTRL_HALFBIAS_SHIFT 30 /* Shift value for ACMP_HALFBIAS */ +#define _ACMP_CTRL_HALFBIAS_MASK 0x40000000UL /* Bit mask for ACMP_HALFBIAS */ +#define _ACMP_CTRL_HALFBIAS_DEFAULT 0x00000001UL /* Mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_HALFBIAS_DEFAULT (_ACMP_CTRL_HALFBIAS_DEFAULT << 30) /* Shifted mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_FULLBIAS (0x1UL << 31) /* Full Bias Current */ +#define _ACMP_CTRL_FULLBIAS_SHIFT 31 /* Shift value for ACMP_FULLBIAS */ +#define _ACMP_CTRL_FULLBIAS_MASK 0x80000000UL /* Bit mask for ACMP_FULLBIAS */ +#define _ACMP_CTRL_FULLBIAS_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_CTRL */ +#define ACMP_CTRL_FULLBIAS_DEFAULT (_ACMP_CTRL_FULLBIAS_DEFAULT << 31) /* Shifted mode DEFAULT for ACMP_CTRL */ + +/* Bit fields for ACMP INPUTSEL */ + +#define _ACMP_INPUTSEL_RESETVALUE 0x00010080UL /* Default value for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_MASK 0x31013FF7UL /* Mask for ACMP_INPUTSEL */ + +#define _ACMP_INPUTSEL_POSSEL_SHIFT 0 /* Shift value for ACMP_POSSEL */ +#define _ACMP_INPUTSEL_POSSEL_MASK 0x7UL /* Bit mask for ACMP_POSSEL */ +#define _ACMP_INPUTSEL_POSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH0 0x00000000UL /* Mode CH0 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH1 0x00000001UL /* Mode CH1 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH2 0x00000002UL /* Mode CH2 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH3 0x00000003UL /* Mode CH3 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH4 0x00000004UL /* Mode CH4 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH5 0x00000005UL /* Mode CH5 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH6 0x00000006UL /* Mode CH6 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_POSSEL_CH7 0x00000007UL /* Mode CH7 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_DEFAULT (_ACMP_INPUTSEL_POSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH0 (_ACMP_INPUTSEL_POSSEL_CH0 << 0) /* Shifted mode CH0 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH1 (_ACMP_INPUTSEL_POSSEL_CH1 << 0) /* Shifted mode CH1 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH2 (_ACMP_INPUTSEL_POSSEL_CH2 << 0) /* Shifted mode CH2 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH3 (_ACMP_INPUTSEL_POSSEL_CH3 << 0) /* Shifted mode CH3 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH4 (_ACMP_INPUTSEL_POSSEL_CH4 << 0) /* Shifted mode CH4 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH5 (_ACMP_INPUTSEL_POSSEL_CH5 << 0) /* Shifted mode CH5 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH6 (_ACMP_INPUTSEL_POSSEL_CH6 << 0) /* Shifted mode CH6 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_POSSEL_CH7 (_ACMP_INPUTSEL_POSSEL_CH7 << 0) /* Shifted mode CH7 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_SHIFT 4 /* Shift value for ACMP_NEGSEL */ +#define _ACMP_INPUTSEL_NEGSEL_MASK 0xF0UL /* Bit mask for ACMP_NEGSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH0 0x00000000UL /* Mode CH0 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH1 0x00000001UL /* Mode CH1 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH2 0x00000002UL /* Mode CH2 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH3 0x00000003UL /* Mode CH3 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH4 0x00000004UL /* Mode CH4 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH5 0x00000005UL /* Mode CH5 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH6 0x00000006UL /* Mode CH6 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CH7 0x00000007UL /* Mode CH7 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_DEFAULT 0x00000008UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_1V25 0x00000008UL /* Mode 1V25 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_2V5 0x00000009UL /* Mode 2V5 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_VDD 0x0000000AUL /* Mode VDD for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_CAPSENSE 0x0000000BUL /* Mode CAPSENSE for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_DAC0CH0 0x0000000CUL /* Mode DAC0CH0 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_NEGSEL_DAC0CH1 0x0000000DUL /* Mode DAC0CH1 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH0 (_ACMP_INPUTSEL_NEGSEL_CH0 << 4) /* Shifted mode CH0 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH1 (_ACMP_INPUTSEL_NEGSEL_CH1 << 4) /* Shifted mode CH1 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH2 (_ACMP_INPUTSEL_NEGSEL_CH2 << 4) /* Shifted mode CH2 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH3 (_ACMP_INPUTSEL_NEGSEL_CH3 << 4) /* Shifted mode CH3 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH4 (_ACMP_INPUTSEL_NEGSEL_CH4 << 4) /* Shifted mode CH4 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH5 (_ACMP_INPUTSEL_NEGSEL_CH5 << 4) /* Shifted mode CH5 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH6 (_ACMP_INPUTSEL_NEGSEL_CH6 << 4) /* Shifted mode CH6 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CH7 (_ACMP_INPUTSEL_NEGSEL_CH7 << 4) /* Shifted mode CH7 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_DEFAULT (_ACMP_INPUTSEL_NEGSEL_DEFAULT << 4) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_1V25 (_ACMP_INPUTSEL_NEGSEL_1V25 << 4) /* Shifted mode 1V25 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_2V5 (_ACMP_INPUTSEL_NEGSEL_2V5 << 4) /* Shifted mode 2V5 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_VDD (_ACMP_INPUTSEL_NEGSEL_VDD << 4) /* Shifted mode VDD for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_CAPSENSE (_ACMP_INPUTSEL_NEGSEL_CAPSENSE << 4) /* Shifted mode CAPSENSE for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_DAC0CH0 (_ACMP_INPUTSEL_NEGSEL_DAC0CH0 << 4) /* Shifted mode DAC0CH0 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_NEGSEL_DAC0CH1 (_ACMP_INPUTSEL_NEGSEL_DAC0CH1 << 4) /* Shifted mode DAC0CH1 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_VDDLEVEL_SHIFT 8 /* Shift value for ACMP_VDDLEVEL */ +#define _ACMP_INPUTSEL_VDDLEVEL_MASK 0x3F00UL /* Bit mask for ACMP_VDDLEVEL */ +#define _ACMP_INPUTSEL_VDDLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_VDDLEVEL_DEFAULT (_ACMP_INPUTSEL_VDDLEVEL_DEFAULT << 8) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_LPREF (0x1UL << 16) /* Low Power Reference Mode */ +#define _ACMP_INPUTSEL_LPREF_SHIFT 16 /* Shift value for ACMP_LPREF */ +#define _ACMP_INPUTSEL_LPREF_MASK 0x10000UL /* Bit mask for ACMP_LPREF */ +#define _ACMP_INPUTSEL_LPREF_DEFAULT 0x00000001UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_LPREF_DEFAULT (_ACMP_INPUTSEL_LPREF_DEFAULT << 16) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESEN (0x1UL << 24) /* Capacitive Sense Mode Internal Resistor Enable */ +#define _ACMP_INPUTSEL_CSRESEN_SHIFT 24 /* Shift value for ACMP_CSRESEN */ +#define _ACMP_INPUTSEL_CSRESEN_MASK 0x1000000UL /* Bit mask for ACMP_CSRESEN */ +#define _ACMP_INPUTSEL_CSRESEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESEN_DEFAULT (_ACMP_INPUTSEL_CSRESEN_DEFAULT << 24) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_SHIFT 28 /* Shift value for ACMP_CSRESSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_MASK 0x30000000UL /* Bit mask for ACMP_CSRESSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_RES0 0x00000000UL /* Mode RES0 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_RES1 0x00000001UL /* Mode RES1 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_RES2 0x00000002UL /* Mode RES2 for ACMP_INPUTSEL */ +#define _ACMP_INPUTSEL_CSRESSEL_RES3 0x00000003UL /* Mode RES3 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_DEFAULT (_ACMP_INPUTSEL_CSRESSEL_DEFAULT << 28) /* Shifted mode DEFAULT for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_RES0 (_ACMP_INPUTSEL_CSRESSEL_RES0 << 28) /* Shifted mode RES0 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_RES1 (_ACMP_INPUTSEL_CSRESSEL_RES1 << 28) /* Shifted mode RES1 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_RES2 (_ACMP_INPUTSEL_CSRESSEL_RES2 << 28) /* Shifted mode RES2 for ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_RES3 (_ACMP_INPUTSEL_CSRESSEL_RES3 << 28) /* Shifted mode RES3 for ACMP_INPUTSEL */ + +/* Bit fields for ACMP STATUS */ + +#define _ACMP_STATUS_RESETVALUE 0x00000000UL /* Default value for ACMP_STATUS */ +#define _ACMP_STATUS_MASK 0x00000003UL /* Mask for ACMP_STATUS */ + +#define ACMP_STATUS_ACMPACT (0x1UL << 0) /* Analog Comparator Active */ +#define _ACMP_STATUS_ACMPACT_SHIFT 0 /* Shift value for ACMP_ACMPACT */ +#define _ACMP_STATUS_ACMPACT_MASK 0x1UL /* Bit mask for ACMP_ACMPACT */ +#define _ACMP_STATUS_ACMPACT_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_STATUS */ +#define ACMP_STATUS_ACMPACT_DEFAULT (_ACMP_STATUS_ACMPACT_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_STATUS */ +#define ACMP_STATUS_ACMPOUT (0x1UL << 1) /* Analog Comparator Output */ +#define _ACMP_STATUS_ACMPOUT_SHIFT 1 /* Shift value for ACMP_ACMPOUT */ +#define _ACMP_STATUS_ACMPOUT_MASK 0x2UL /* Bit mask for ACMP_ACMPOUT */ +#define _ACMP_STATUS_ACMPOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_STATUS */ +#define ACMP_STATUS_ACMPOUT_DEFAULT (_ACMP_STATUS_ACMPOUT_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_STATUS */ + +/* Bit fields for ACMP IEN */ + +#define _ACMP_IEN_RESETVALUE 0x00000000UL /* Default value for ACMP_IEN */ +#define _ACMP_IEN_MASK 0x00000003UL /* Mask for ACMP_IEN */ + +#define ACMP_IEN_EDGE (0x1UL << 0) /* Edge Trigger Interrupt Enable */ +#define _ACMP_IEN_EDGE_SHIFT 0 /* Shift value for ACMP_EDGE */ +#define _ACMP_IEN_EDGE_MASK 0x1UL /* Bit mask for ACMP_EDGE */ +#define _ACMP_IEN_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IEN */ +#define ACMP_IEN_EDGE_DEFAULT (_ACMP_IEN_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_IEN */ +#define ACMP_IEN_WARMUP (0x1UL << 1) /* Warm-up Interrupt Enable */ +#define _ACMP_IEN_WARMUP_SHIFT 1 /* Shift value for ACMP_WARMUP */ +#define _ACMP_IEN_WARMUP_MASK 0x2UL /* Bit mask for ACMP_WARMUP */ +#define _ACMP_IEN_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IEN */ +#define ACMP_IEN_WARMUP_DEFAULT (_ACMP_IEN_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_IEN */ + +/* Bit fields for ACMP IF */ + +#define _ACMP_IF_RESETVALUE 0x00000000UL /* Default value for ACMP_IF */ +#define _ACMP_IF_MASK 0x00000003UL /* Mask for ACMP_IF */ + +#define ACMP_IF_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag */ +#define _ACMP_IF_EDGE_SHIFT 0 /* Shift value for ACMP_EDGE */ +#define _ACMP_IF_EDGE_MASK 0x1UL /* Bit mask for ACMP_EDGE */ +#define _ACMP_IF_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IF */ +#define ACMP_IF_EDGE_DEFAULT (_ACMP_IF_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_IF */ +#define ACMP_IF_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag */ +#define _ACMP_IF_WARMUP_SHIFT 1 /* Shift value for ACMP_WARMUP */ +#define _ACMP_IF_WARMUP_MASK 0x2UL /* Bit mask for ACMP_WARMUP */ +#define _ACMP_IF_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IF */ +#define ACMP_IF_WARMUP_DEFAULT (_ACMP_IF_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_IF */ + +/* Bit fields for ACMP IFS */ + +#define _ACMP_IFS_RESETVALUE 0x00000000UL /* Default value for ACMP_IFS */ +#define _ACMP_IFS_MASK 0x00000003UL /* Mask for ACMP_IFS */ + +#define ACMP_IFS_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag Set */ +#define _ACMP_IFS_EDGE_SHIFT 0 /* Shift value for ACMP_EDGE */ +#define _ACMP_IFS_EDGE_MASK 0x1UL /* Bit mask for ACMP_EDGE */ +#define _ACMP_IFS_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IFS */ +#define ACMP_IFS_EDGE_DEFAULT (_ACMP_IFS_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_IFS */ +#define ACMP_IFS_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag Set */ +#define _ACMP_IFS_WARMUP_SHIFT 1 /* Shift value for ACMP_WARMUP */ +#define _ACMP_IFS_WARMUP_MASK 0x2UL /* Bit mask for ACMP_WARMUP */ +#define _ACMP_IFS_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IFS */ +#define ACMP_IFS_WARMUP_DEFAULT (_ACMP_IFS_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_IFS */ + +/* Bit fields for ACMP IFC */ + +#define _ACMP_IFC_RESETVALUE 0x00000000UL /* Default value for ACMP_IFC */ +#define _ACMP_IFC_MASK 0x00000003UL /* Mask for ACMP_IFC */ + +#define ACMP_IFC_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag Clear */ +#define _ACMP_IFC_EDGE_SHIFT 0 /* Shift value for ACMP_EDGE */ +#define _ACMP_IFC_EDGE_MASK 0x1UL /* Bit mask for ACMP_EDGE */ +#define _ACMP_IFC_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IFC */ +#define ACMP_IFC_EDGE_DEFAULT (_ACMP_IFC_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_IFC */ +#define ACMP_IFC_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag Clear */ +#define _ACMP_IFC_WARMUP_SHIFT 1 /* Shift value for ACMP_WARMUP */ +#define _ACMP_IFC_WARMUP_MASK 0x2UL /* Bit mask for ACMP_WARMUP */ +#define _ACMP_IFC_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_IFC */ +#define ACMP_IFC_WARMUP_DEFAULT (_ACMP_IFC_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for ACMP_IFC */ + +/* Bit fields for ACMP ROUTE */ + +#define _ACMP_ROUTE_RESETVALUE 0x00000000UL /* Default value for ACMP_ROUTE */ +#define _ACMP_ROUTE_MASK 0x00000701UL /* Mask for ACMP_ROUTE */ + +#define ACMP_ROUTE_ACMPPEN (0x1UL << 0) /* ACMP Output Pin Enable */ +#define _ACMP_ROUTE_ACMPPEN_SHIFT 0 /* Shift value for ACMP_ACMPPEN */ +#define _ACMP_ROUTE_ACMPPEN_MASK 0x1UL /* Bit mask for ACMP_ACMPPEN */ +#define _ACMP_ROUTE_ACMPPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_ROUTE */ +#define ACMP_ROUTE_ACMPPEN_DEFAULT (_ACMP_ROUTE_ACMPPEN_DEFAULT << 0) /* Shifted mode DEFAULT for ACMP_ROUTE */ +#define _ACMP_ROUTE_LOCATION_SHIFT 8 /* Shift value for ACMP_LOCATION */ +#define _ACMP_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for ACMP_LOCATION */ +#define _ACMP_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for ACMP_ROUTE */ +#define _ACMP_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for ACMP_ROUTE */ +#define _ACMP_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for ACMP_ROUTE */ +#define _ACMP_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for ACMP_ROUTE */ +#define ACMP_ROUTE_LOCATION_LOC0 (_ACMP_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for ACMP_ROUTE */ +#define ACMP_ROUTE_LOCATION_DEFAULT (_ACMP_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for ACMP_ROUTE */ +#define ACMP_ROUTE_LOCATION_LOC1 (_ACMP_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for ACMP_ROUTE */ +#define ACMP_ROUTE_LOCATION_LOC2 (_ACMP_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for ACMP_ROUTE */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ACMP_H */ diff --git a/arch/arm/src/efm32/chip/efm32_adc.h b/arch/arm/src/efm32/chip/efm32_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..8245acffab8cff57967194aba5241cba4476ab91 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_adc.h @@ -0,0 +1,751 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_adc.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ADC_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ADC_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* ADC Register Offsets ********************************************************************************************************/ + +#define EFM32_ADC_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_ADC_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_ADC_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_ADC_SINGLECTRL_OFFSET 0x000c /* Single Sample Control Register */ +#define EFM32_ADC_SCANCTRL_OFFSET 0x0010 /* Scan Control Register */ +#define EFM32_ADC_IEN_OFFSET 0x0014 /* Interrupt Enable Register */ +#define EFM32_ADC_IF_OFFSET 0x0018 /* Interrupt Flag Register */ +#define EFM32_ADC_IFS_OFFSET 0x001c /* Interrupt Flag Set Register */ +#define EFM32_ADC_IFC_OFFSET 0x0020 /* Interrupt Flag Clear Register */ +#define EFM32_ADC_SINGLEDATA_OFFSET 0x0024 /* Single Conversion Result Data */ +#define EFM32_ADC_SCANDATA_OFFSET 0x0028 /* Scan Conversion Result Data */ +#define EFM32_ADC_SINGLEDATAP_OFFSET 0x002c /* Single Conversion Result Data Peek Register */ +#define EFM32_ADC_SCANDATAP_OFFSET 0x0030 /* Scan Sequence Result Data Peek Register */ +#define EFM32_ADC_CAL_OFFSET 0x0034 /* Calibration Register */ +#define EFM32_ADC_BIASPROG_OFFSET 0x003c /* Bias Programming Register */ + +/* ADC Register Addresses ******************************************************************************************************/ + +#define EFM32_ADC0_CTRL (EFM32_ADC0_BASE+EFM32_ADC_CTRL_OFFSET) +#define EFM32_ADC0_CMD (EFM32_ADC0_BASE+EFM32_ADC_CMD_OFFSET) +#define EFM32_ADC0_STATUS (EFM32_ADC0_BASE+EFM32_ADC_STATUS_OFFSET) +#define EFM32_ADC0_SINGLECTRL (EFM32_ADC0_BASE+EFM32_ADC_SINGLECTRL_OFFSET) +#define EFM32_ADC0_SCANCTRL (EFM32_ADC0_BASE+EFM32_ADC_SCANCTRL_OFFSET) +#define EFM32_ADC0_IEN (EFM32_ADC0_BASE+EFM32_ADC_IEN_OFFSET) +#define EFM32_ADC0_IF (EFM32_ADC0_BASE+EFM32_ADC_IF_OFFSET) +#define EFM32_ADC0_IFS (EFM32_ADC0_BASE+EFM32_ADC_IFS_OFFSET) +#define EFM32_ADC0_IFC (EFM32_ADC0_BASE+EFM32_ADC_IFC_OFFSET) +#define EFM32_ADC0_SINGLEDATA (EFM32_ADC0_BASE+EFM32_ADC_SINGLEDATA_OFFSET) +#define EFM32_ADC0_SCANDATA (EFM32_ADC0_BASE+EFM32_ADC_SCANDATA_OFFSET) +#define EFM32_ADC0_SINGLEDATAP (EFM32_ADC0_BASE+EFM32_ADC_SINGLEDATAP_OFFSET) +#define EFM32_ADC0_SCANDATAP (EFM32_ADC0_BASE+EFM32_ADC_SCANDATAP_OFFSET) +#define EFM32_ADC0_CAL (EFM32_ADC0_BASE+EFM32_ADC_CAL_OFFSET) +#define EFM32_ADC0_BIASPROG (EFM32_ADC0_BASE+EFM32_ADC_BIASPROG_OFFSET) + +/* ADC Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for ADC CTRL */ + +#define _ADC_CTRL_RESETVALUE 0x001F0000UL /* Default value for ADC_CTRL */ +#define _ADC_CTRL_MASK 0x0F1F7F3BUL /* Mask for ADC_CTRL */ + +#define _ADC_CTRL_WARMUPMODE_SHIFT 0 /* Shift value for ADC_WARMUPMODE */ +#define _ADC_CTRL_WARMUPMODE_MASK 0x3UL /* Bit mask for ADC_WARMUPMODE */ +#define _ADC_CTRL_WARMUPMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_WARMUPMODE_NORMAL 0x00000000UL /* Mode NORMAL for ADC_CTRL */ +#define _ADC_CTRL_WARMUPMODE_FASTBG 0x00000001UL /* Mode FASTBG for ADC_CTRL */ +#define _ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM 0x00000002UL /* Mode KEEPSCANREFWARM for ADC_CTRL */ +#define _ADC_CTRL_WARMUPMODE_KEEPADCWARM 0x00000003UL /* Mode KEEPADCWARM for ADC_CTRL */ +#define ADC_CTRL_WARMUPMODE_DEFAULT (_ADC_CTRL_WARMUPMODE_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_WARMUPMODE_NORMAL (_ADC_CTRL_WARMUPMODE_NORMAL << 0) /* Shifted mode NORMAL for ADC_CTRL */ +#define ADC_CTRL_WARMUPMODE_FASTBG (_ADC_CTRL_WARMUPMODE_FASTBG << 0) /* Shifted mode FASTBG for ADC_CTRL */ +#define ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM (_ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM << 0) /* Shifted mode KEEPSCANREFWARM for ADC_CTRL */ +#define ADC_CTRL_WARMUPMODE_KEEPADCWARM (_ADC_CTRL_WARMUPMODE_KEEPADCWARM << 0) /* Shifted mode KEEPADCWARM for ADC_CTRL */ +#define ADC_CTRL_TAILGATE (0x1UL << 3) /* Conversion Tailgating */ +#define _ADC_CTRL_TAILGATE_SHIFT 3 /* Shift value for ADC_TAILGATE */ +#define _ADC_CTRL_TAILGATE_MASK 0x8UL /* Bit mask for ADC_TAILGATE */ +#define _ADC_CTRL_TAILGATE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_TAILGATE_DEFAULT (_ADC_CTRL_TAILGATE_DEFAULT << 3) /* Shifted mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_LPFMODE_SHIFT 4 /* Shift value for ADC_LPFMODE */ +#define _ADC_CTRL_LPFMODE_MASK 0x30UL /* Bit mask for ADC_LPFMODE */ +#define _ADC_CTRL_LPFMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_LPFMODE_BYPASS 0x00000000UL /* Mode BYPASS for ADC_CTRL */ +#define _ADC_CTRL_LPFMODE_DECAP 0x00000001UL /* Mode DECAP for ADC_CTRL */ +#define _ADC_CTRL_LPFMODE_RCFILT 0x00000002UL /* Mode RCFILT for ADC_CTRL */ +#define ADC_CTRL_LPFMODE_DEFAULT (_ADC_CTRL_LPFMODE_DEFAULT << 4) /* Shifted mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_LPFMODE_BYPASS (_ADC_CTRL_LPFMODE_BYPASS << 4) /* Shifted mode BYPASS for ADC_CTRL */ +#define ADC_CTRL_LPFMODE_DECAP (_ADC_CTRL_LPFMODE_DECAP << 4) /* Shifted mode DECAP for ADC_CTRL */ +#define ADC_CTRL_LPFMODE_RCFILT (_ADC_CTRL_LPFMODE_RCFILT << 4) /* Shifted mode RCFILT for ADC_CTRL */ +#define _ADC_CTRL_PRESC_SHIFT 8 /* Shift value for ADC_PRESC */ +#define _ADC_CTRL_PRESC_MASK 0x7F00UL /* Bit mask for ADC_PRESC */ +#define _ADC_CTRL_PRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_PRESC_NODIVISION 0x00000000UL /* Mode NODIVISION for ADC_CTRL */ +#define ADC_CTRL_PRESC_DEFAULT (_ADC_CTRL_PRESC_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_PRESC_NODIVISION (_ADC_CTRL_PRESC_NODIVISION << 8) /* Shifted mode NODIVISION for ADC_CTRL */ +#define _ADC_CTRL_TIMEBASE_SHIFT 16 /* Shift value for ADC_TIMEBASE */ +#define _ADC_CTRL_TIMEBASE_MASK 0x1F0000UL /* Bit mask for ADC_TIMEBASE */ +#define _ADC_CTRL_TIMEBASE_DEFAULT 0x0000001FUL /* Mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_TIMEBASE_DEFAULT (_ADC_CTRL_TIMEBASE_DEFAULT << 16) /* Shifted mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_SHIFT 24 /* Shift value for ADC_OVSRSEL */ +#define _ADC_CTRL_OVSRSEL_MASK 0xF000000UL /* Bit mask for ADC_OVSRSEL */ +#define _ADC_CTRL_OVSRSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X2 0x00000000UL /* Mode X2 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X4 0x00000001UL /* Mode X4 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X8 0x00000002UL /* Mode X8 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X16 0x00000003UL /* Mode X16 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X32 0x00000004UL /* Mode X32 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X64 0x00000005UL /* Mode X64 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X128 0x00000006UL /* Mode X128 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X256 0x00000007UL /* Mode X256 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X512 0x00000008UL /* Mode X512 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X1024 0x00000009UL /* Mode X1024 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X2048 0x0000000AUL /* Mode X2048 for ADC_CTRL */ +#define _ADC_CTRL_OVSRSEL_X4096 0x0000000BUL /* Mode X4096 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_DEFAULT (_ADC_CTRL_OVSRSEL_DEFAULT << 24) /* Shifted mode DEFAULT for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X2 (_ADC_CTRL_OVSRSEL_X2 << 24) /* Shifted mode X2 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X4 (_ADC_CTRL_OVSRSEL_X4 << 24) /* Shifted mode X4 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X8 (_ADC_CTRL_OVSRSEL_X8 << 24) /* Shifted mode X8 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X16 (_ADC_CTRL_OVSRSEL_X16 << 24) /* Shifted mode X16 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X32 (_ADC_CTRL_OVSRSEL_X32 << 24) /* Shifted mode X32 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X64 (_ADC_CTRL_OVSRSEL_X64 << 24) /* Shifted mode X64 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X128 (_ADC_CTRL_OVSRSEL_X128 << 24) /* Shifted mode X128 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X256 (_ADC_CTRL_OVSRSEL_X256 << 24) /* Shifted mode X256 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X512 (_ADC_CTRL_OVSRSEL_X512 << 24) /* Shifted mode X512 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X1024 (_ADC_CTRL_OVSRSEL_X1024 << 24) /* Shifted mode X1024 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X2048 (_ADC_CTRL_OVSRSEL_X2048 << 24) /* Shifted mode X2048 for ADC_CTRL */ +#define ADC_CTRL_OVSRSEL_X4096 (_ADC_CTRL_OVSRSEL_X4096 << 24) /* Shifted mode X4096 for ADC_CTRL */ + +/* Bit fields for ADC CMD */ + +#define _ADC_CMD_RESETVALUE 0x00000000UL /* Default value for ADC_CMD */ +#define _ADC_CMD_MASK 0x0000000FUL /* Mask for ADC_CMD */ + +#define ADC_CMD_SINGLESTART (0x1UL << 0) /* Single Conversion Start */ +#define _ADC_CMD_SINGLESTART_SHIFT 0 /* Shift value for ADC_SINGLESTART */ +#define _ADC_CMD_SINGLESTART_MASK 0x1UL /* Bit mask for ADC_SINGLESTART */ +#define _ADC_CMD_SINGLESTART_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SINGLESTART_DEFAULT (_ADC_CMD_SINGLESTART_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SINGLESTOP (0x1UL << 1) /* Single Conversion Stop */ +#define _ADC_CMD_SINGLESTOP_SHIFT 1 /* Shift value for ADC_SINGLESTOP */ +#define _ADC_CMD_SINGLESTOP_MASK 0x2UL /* Bit mask for ADC_SINGLESTOP */ +#define _ADC_CMD_SINGLESTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SINGLESTOP_DEFAULT (_ADC_CMD_SINGLESTOP_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SCANSTART (0x1UL << 2) /* Scan Sequence Start */ +#define _ADC_CMD_SCANSTART_SHIFT 2 /* Shift value for ADC_SCANSTART */ +#define _ADC_CMD_SCANSTART_MASK 0x4UL /* Bit mask for ADC_SCANSTART */ +#define _ADC_CMD_SCANSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SCANSTART_DEFAULT (_ADC_CMD_SCANSTART_DEFAULT << 2) /* Shifted mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SCANSTOP (0x1UL << 3) /* Scan Sequence Stop */ +#define _ADC_CMD_SCANSTOP_SHIFT 3 /* Shift value for ADC_SCANSTOP */ +#define _ADC_CMD_SCANSTOP_MASK 0x8UL /* Bit mask for ADC_SCANSTOP */ +#define _ADC_CMD_SCANSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CMD */ +#define ADC_CMD_SCANSTOP_DEFAULT (_ADC_CMD_SCANSTOP_DEFAULT << 3) /* Shifted mode DEFAULT for ADC_CMD */ + +/* Bit fields for ADC STATUS */ + +#define _ADC_STATUS_RESETVALUE 0x00000000UL /* Default value for ADC_STATUS */ +#define _ADC_STATUS_MASK 0x07031303UL /* Mask for ADC_STATUS */ + +#define ADC_STATUS_SINGLEACT (0x1UL << 0) /* Single Conversion Active */ +#define _ADC_STATUS_SINGLEACT_SHIFT 0 /* Shift value for ADC_SINGLEACT */ +#define _ADC_STATUS_SINGLEACT_MASK 0x1UL /* Bit mask for ADC_SINGLEACT */ +#define _ADC_STATUS_SINGLEACT_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SINGLEACT_DEFAULT (_ADC_STATUS_SINGLEACT_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANACT (0x1UL << 1) /* Scan Conversion Active */ +#define _ADC_STATUS_SCANACT_SHIFT 1 /* Shift value for ADC_SCANACT */ +#define _ADC_STATUS_SCANACT_MASK 0x2UL /* Bit mask for ADC_SCANACT */ +#define _ADC_STATUS_SCANACT_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANACT_DEFAULT (_ADC_STATUS_SCANACT_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SINGLEREFWARM (0x1UL << 8) /* Single Reference Warmed Up */ +#define _ADC_STATUS_SINGLEREFWARM_SHIFT 8 /* Shift value for ADC_SINGLEREFWARM */ +#define _ADC_STATUS_SINGLEREFWARM_MASK 0x100UL /* Bit mask for ADC_SINGLEREFWARM */ +#define _ADC_STATUS_SINGLEREFWARM_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SINGLEREFWARM_DEFAULT (_ADC_STATUS_SINGLEREFWARM_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANREFWARM (0x1UL << 9) /* Scan Reference Warmed Up */ +#define _ADC_STATUS_SCANREFWARM_SHIFT 9 /* Shift value for ADC_SCANREFWARM */ +#define _ADC_STATUS_SCANREFWARM_MASK 0x200UL /* Bit mask for ADC_SCANREFWARM */ +#define _ADC_STATUS_SCANREFWARM_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANREFWARM_DEFAULT (_ADC_STATUS_SCANREFWARM_DEFAULT << 9) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_WARM (0x1UL << 12) /* ADC Warmed Up */ +#define _ADC_STATUS_WARM_SHIFT 12 /* Shift value for ADC_WARM */ +#define _ADC_STATUS_WARM_MASK 0x1000UL /* Bit mask for ADC_WARM */ +#define _ADC_STATUS_WARM_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_WARM_DEFAULT (_ADC_STATUS_WARM_DEFAULT << 12) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SINGLEDV (0x1UL << 16) /* Single Sample Data Valid */ +#define _ADC_STATUS_SINGLEDV_SHIFT 16 /* Shift value for ADC_SINGLEDV */ +#define _ADC_STATUS_SINGLEDV_MASK 0x10000UL /* Bit mask for ADC_SINGLEDV */ +#define _ADC_STATUS_SINGLEDV_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SINGLEDV_DEFAULT (_ADC_STATUS_SINGLEDV_DEFAULT << 16) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANDV (0x1UL << 17) /* Scan Data Valid */ +#define _ADC_STATUS_SCANDV_SHIFT 17 /* Shift value for ADC_SCANDV */ +#define _ADC_STATUS_SCANDV_MASK 0x20000UL /* Bit mask for ADC_SCANDV */ +#define _ADC_STATUS_SCANDV_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANDV_DEFAULT (_ADC_STATUS_SCANDV_DEFAULT << 17) /* Shifted mode DEFAULT for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_SHIFT 24 /* Shift value for ADC_SCANDATASRC */ +#define _ADC_STATUS_SCANDATASRC_MASK 0x7000000UL /* Bit mask for ADC_SCANDATASRC */ +#define _ADC_STATUS_SCANDATASRC_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH0 0x00000000UL /* Mode CH0 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH1 0x00000001UL /* Mode CH1 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH2 0x00000002UL /* Mode CH2 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH3 0x00000003UL /* Mode CH3 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH4 0x00000004UL /* Mode CH4 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH5 0x00000005UL /* Mode CH5 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH6 0x00000006UL /* Mode CH6 for ADC_STATUS */ +#define _ADC_STATUS_SCANDATASRC_CH7 0x00000007UL /* Mode CH7 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_DEFAULT (_ADC_STATUS_SCANDATASRC_DEFAULT << 24) /* Shifted mode DEFAULT for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH0 (_ADC_STATUS_SCANDATASRC_CH0 << 24) /* Shifted mode CH0 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH1 (_ADC_STATUS_SCANDATASRC_CH1 << 24) /* Shifted mode CH1 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH2 (_ADC_STATUS_SCANDATASRC_CH2 << 24) /* Shifted mode CH2 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH3 (_ADC_STATUS_SCANDATASRC_CH3 << 24) /* Shifted mode CH3 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH4 (_ADC_STATUS_SCANDATASRC_CH4 << 24) /* Shifted mode CH4 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH5 (_ADC_STATUS_SCANDATASRC_CH5 << 24) /* Shifted mode CH5 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH6 (_ADC_STATUS_SCANDATASRC_CH6 << 24) /* Shifted mode CH6 for ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_CH7 (_ADC_STATUS_SCANDATASRC_CH7 << 24) /* Shifted mode CH7 for ADC_STATUS */ + +/* Bit fields for ADC SINGLECTRL */ + +#define _ADC_SINGLECTRL_RESETVALUE 0x00000000UL /* Default value for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_MASK 0xF1F70F37UL /* Mask for ADC_SINGLECTRL */ + +#define ADC_SINGLECTRL_REP (0x1UL << 0) /* Single Sample Repetitive Mode */ +#define _ADC_SINGLECTRL_REP_SHIFT 0 /* Shift value for ADC_REP */ +#define _ADC_SINGLECTRL_REP_MASK 0x1UL /* Bit mask for ADC_REP */ +#define _ADC_SINGLECTRL_REP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REP_DEFAULT (_ADC_SINGLECTRL_REP_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_DIFF (0x1UL << 1) /* Single Sample Differential Mode */ +#define _ADC_SINGLECTRL_DIFF_SHIFT 1 /* Shift value for ADC_DIFF */ +#define _ADC_SINGLECTRL_DIFF_MASK 0x2UL /* Bit mask for ADC_DIFF */ +#define _ADC_SINGLECTRL_DIFF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_DIFF_DEFAULT (_ADC_SINGLECTRL_DIFF_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_ADJ (0x1UL << 2) /* Single Sample Result Adjustment */ +#define _ADC_SINGLECTRL_ADJ_SHIFT 2 /* Shift value for ADC_ADJ */ +#define _ADC_SINGLECTRL_ADJ_MASK 0x4UL /* Bit mask for ADC_ADJ */ +#define _ADC_SINGLECTRL_ADJ_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_ADJ_RIGHT 0x00000000UL /* Mode RIGHT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_ADJ_LEFT 0x00000001UL /* Mode LEFT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_ADJ_DEFAULT (_ADC_SINGLECTRL_ADJ_DEFAULT << 2) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_ADJ_RIGHT (_ADC_SINGLECTRL_ADJ_RIGHT << 2) /* Shifted mode RIGHT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_ADJ_LEFT (_ADC_SINGLECTRL_ADJ_LEFT << 2) /* Shifted mode LEFT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_RES_SHIFT 4 /* Shift value for ADC_RES */ +#define _ADC_SINGLECTRL_RES_MASK 0x30UL /* Bit mask for ADC_RES */ +#define _ADC_SINGLECTRL_RES_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_RES_12BIT 0x00000000UL /* Mode 12BIT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_RES_8BIT 0x00000001UL /* Mode 8BIT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_RES_6BIT 0x00000002UL /* Mode 6BIT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_RES_OVS 0x00000003UL /* Mode OVS for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_RES_DEFAULT (_ADC_SINGLECTRL_RES_DEFAULT << 4) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_RES_12BIT (_ADC_SINGLECTRL_RES_12BIT << 4) /* Shifted mode 12BIT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_RES_8BIT (_ADC_SINGLECTRL_RES_8BIT << 4) /* Shifted mode 8BIT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_RES_6BIT (_ADC_SINGLECTRL_RES_6BIT << 4) /* Shifted mode 6BIT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_RES_OVS (_ADC_SINGLECTRL_RES_OVS << 4) /* Shifted mode OVS for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_SHIFT 8 /* Shift value for ADC_INPUTSEL */ +#define _ADC_SINGLECTRL_INPUTSEL_MASK 0xF00UL /* Bit mask for ADC_INPUTSEL */ +#define _ADC_SINGLECTRL_INPUTSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH0 0x00000000UL /* Mode CH0 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH0CH1 0x00000000UL /* Mode CH0CH1 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH1 0x00000001UL /* Mode CH1 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH2CH3 0x00000001UL /* Mode CH2CH3 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH2 0x00000002UL /* Mode CH2 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH4CH5 0x00000002UL /* Mode CH4CH5 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH6CH7 0x00000003UL /* Mode CH6CH7 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH3 0x00000003UL /* Mode CH3 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH4 0x00000004UL /* Mode CH4 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_DIFF0 0x00000004UL /* Mode DIFF0 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH5 0x00000005UL /* Mode CH5 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH6 0x00000006UL /* Mode CH6 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_CH7 0x00000007UL /* Mode CH7 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_TEMP 0x00000008UL /* Mode TEMP for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_VDDDIV3 0x00000009UL /* Mode VDDDIV3 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_VDD 0x0000000AUL /* Mode VDD for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_VSS 0x0000000BUL /* Mode VSS for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_VREFDIV2 0x0000000CUL /* Mode VREFDIV2 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_DAC0OUT0 0x0000000DUL /* Mode DAC0OUT0 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_INPUTSEL_DAC0OUT1 0x0000000EUL /* Mode DAC0OUT1 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_DEFAULT (_ADC_SINGLECTRL_INPUTSEL_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH0 (_ADC_SINGLECTRL_INPUTSEL_CH0 << 8) /* Shifted mode CH0 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH0CH1 (_ADC_SINGLECTRL_INPUTSEL_CH0CH1 << 8) /* Shifted mode CH0CH1 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH1 (_ADC_SINGLECTRL_INPUTSEL_CH1 << 8) /* Shifted mode CH1 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH2CH3 (_ADC_SINGLECTRL_INPUTSEL_CH2CH3 << 8) /* Shifted mode CH2CH3 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH2 (_ADC_SINGLECTRL_INPUTSEL_CH2 << 8) /* Shifted mode CH2 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH4CH5 (_ADC_SINGLECTRL_INPUTSEL_CH4CH5 << 8) /* Shifted mode CH4CH5 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH6CH7 (_ADC_SINGLECTRL_INPUTSEL_CH6CH7 << 8) /* Shifted mode CH6CH7 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH3 (_ADC_SINGLECTRL_INPUTSEL_CH3 << 8) /* Shifted mode CH3 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH4 (_ADC_SINGLECTRL_INPUTSEL_CH4 << 8) /* Shifted mode CH4 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_DIFF0 (_ADC_SINGLECTRL_INPUTSEL_DIFF0 << 8) /* Shifted mode DIFF0 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH5 (_ADC_SINGLECTRL_INPUTSEL_CH5 << 8) /* Shifted mode CH5 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH6 (_ADC_SINGLECTRL_INPUTSEL_CH6 << 8) /* Shifted mode CH6 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_CH7 (_ADC_SINGLECTRL_INPUTSEL_CH7 << 8) /* Shifted mode CH7 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_TEMP (_ADC_SINGLECTRL_INPUTSEL_TEMP << 8) /* Shifted mode TEMP for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_VDDDIV3 (_ADC_SINGLECTRL_INPUTSEL_VDDDIV3 << 8) /* Shifted mode VDDDIV3 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_VDD (_ADC_SINGLECTRL_INPUTSEL_VDD << 8) /* Shifted mode VDD for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_VSS (_ADC_SINGLECTRL_INPUTSEL_VSS << 8) /* Shifted mode VSS for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_VREFDIV2 (_ADC_SINGLECTRL_INPUTSEL_VREFDIV2 << 8) /* Shifted mode VREFDIV2 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_DAC0OUT0 (_ADC_SINGLECTRL_INPUTSEL_DAC0OUT0 << 8) /* Shifted mode DAC0OUT0 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_INPUTSEL_DAC0OUT1 (_ADC_SINGLECTRL_INPUTSEL_DAC0OUT1 << 8) /* Shifted mode DAC0OUT1 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_SHIFT 16 /* Shift value for ADC_REF */ +#define _ADC_SINGLECTRL_REF_MASK 0x70000UL /* Bit mask for ADC_REF */ +#define _ADC_SINGLECTRL_REF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_1V25 0x00000000UL /* Mode 1V25 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_2V5 0x00000001UL /* Mode 2V5 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_VDD 0x00000002UL /* Mode VDD for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_5VDIFF 0x00000003UL /* Mode 5VDIFF for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_EXTSINGLE 0x00000004UL /* Mode EXTSINGLE for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_2XEXTDIFF 0x00000005UL /* Mode 2XEXTDIFF for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_REF_2XVDD 0x00000006UL /* Mode 2XVDD for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_DEFAULT (_ADC_SINGLECTRL_REF_DEFAULT << 16) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_1V25 (_ADC_SINGLECTRL_REF_1V25 << 16) /* Shifted mode 1V25 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_2V5 (_ADC_SINGLECTRL_REF_2V5 << 16) /* Shifted mode 2V5 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_VDD (_ADC_SINGLECTRL_REF_VDD << 16) /* Shifted mode VDD for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_5VDIFF (_ADC_SINGLECTRL_REF_5VDIFF << 16) /* Shifted mode 5VDIFF for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_EXTSINGLE (_ADC_SINGLECTRL_REF_EXTSINGLE << 16) /* Shifted mode EXTSINGLE for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_2XEXTDIFF (_ADC_SINGLECTRL_REF_2XEXTDIFF << 16) /* Shifted mode 2XEXTDIFF for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_REF_2XVDD (_ADC_SINGLECTRL_REF_2XVDD << 16) /* Shifted mode 2XVDD for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_SHIFT 20 /* Shift value for ADC_AT */ +#define _ADC_SINGLECTRL_AT_MASK 0xF00000UL /* Bit mask for ADC_AT */ +#define _ADC_SINGLECTRL_AT_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_1CYCLE 0x00000000UL /* Mode 1CYCLE for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_2CYCLES 0x00000001UL /* Mode 2CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_4CYCLES 0x00000002UL /* Mode 4CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_8CYCLES 0x00000003UL /* Mode 8CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_16CYCLES 0x00000004UL /* Mode 16CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_32CYCLES 0x00000005UL /* Mode 32CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_64CYCLES 0x00000006UL /* Mode 64CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_128CYCLES 0x00000007UL /* Mode 128CYCLES for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_AT_256CYCLES 0x00000008UL /* Mode 256CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_DEFAULT (_ADC_SINGLECTRL_AT_DEFAULT << 20) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_1CYCLE (_ADC_SINGLECTRL_AT_1CYCLE << 20) /* Shifted mode 1CYCLE for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_2CYCLES (_ADC_SINGLECTRL_AT_2CYCLES << 20) /* Shifted mode 2CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_4CYCLES (_ADC_SINGLECTRL_AT_4CYCLES << 20) /* Shifted mode 4CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_8CYCLES (_ADC_SINGLECTRL_AT_8CYCLES << 20) /* Shifted mode 8CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_16CYCLES (_ADC_SINGLECTRL_AT_16CYCLES << 20) /* Shifted mode 16CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_32CYCLES (_ADC_SINGLECTRL_AT_32CYCLES << 20) /* Shifted mode 32CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_64CYCLES (_ADC_SINGLECTRL_AT_64CYCLES << 20) /* Shifted mode 64CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_128CYCLES (_ADC_SINGLECTRL_AT_128CYCLES << 20) /* Shifted mode 128CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_AT_256CYCLES (_ADC_SINGLECTRL_AT_256CYCLES << 20) /* Shifted mode 256CYCLES for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSEN (0x1UL << 24) /* Single Sample PRS Trigger Enable */ +#define _ADC_SINGLECTRL_PRSEN_SHIFT 24 /* Shift value for ADC_PRSEN */ +#define _ADC_SINGLECTRL_PRSEN_MASK 0x1000000UL /* Bit mask for ADC_PRSEN */ +#define _ADC_SINGLECTRL_PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSEN_DEFAULT (_ADC_SINGLECTRL_PRSEN_DEFAULT << 24) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_SHIFT 28 /* Shift value for ADC_PRSSEL */ +#define _ADC_SINGLECTRL_PRSSEL_MASK 0xF0000000UL /* Bit mask for ADC_PRSSEL */ +#define _ADC_SINGLECTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for ADC_SINGLECTRL */ +#define _ADC_SINGLECTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_DEFAULT (_ADC_SINGLECTRL_PRSSEL_DEFAULT << 28) /* Shifted mode DEFAULT for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH0 (_ADC_SINGLECTRL_PRSSEL_PRSCH0 << 28) /* Shifted mode PRSCH0 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH1 (_ADC_SINGLECTRL_PRSSEL_PRSCH1 << 28) /* Shifted mode PRSCH1 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH2 (_ADC_SINGLECTRL_PRSSEL_PRSCH2 << 28) /* Shifted mode PRSCH2 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH3 (_ADC_SINGLECTRL_PRSSEL_PRSCH3 << 28) /* Shifted mode PRSCH3 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH4 (_ADC_SINGLECTRL_PRSSEL_PRSCH4 << 28) /* Shifted mode PRSCH4 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH5 (_ADC_SINGLECTRL_PRSSEL_PRSCH5 << 28) /* Shifted mode PRSCH5 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH6 (_ADC_SINGLECTRL_PRSSEL_PRSCH6 << 28) /* Shifted mode PRSCH6 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH7 (_ADC_SINGLECTRL_PRSSEL_PRSCH7 << 28) /* Shifted mode PRSCH7 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH8 (_ADC_SINGLECTRL_PRSSEL_PRSCH8 << 28) /* Shifted mode PRSCH8 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH9 (_ADC_SINGLECTRL_PRSSEL_PRSCH9 << 28) /* Shifted mode PRSCH9 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH10 (_ADC_SINGLECTRL_PRSSEL_PRSCH10 << 28) /* Shifted mode PRSCH10 for ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_PRSCH11 (_ADC_SINGLECTRL_PRSSEL_PRSCH11 << 28) /* Shifted mode PRSCH11 for ADC_SINGLECTRL */ + +/* Bit fields for ADC SCANCTRL */ + +#define _ADC_SCANCTRL_RESETVALUE 0x00000000UL /* Default value for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_MASK 0xF1F7FF37UL /* Mask for ADC_SCANCTRL */ + +#define ADC_SCANCTRL_REP (0x1UL << 0) /* Scan Sequence Repetitive Mode */ +#define _ADC_SCANCTRL_REP_SHIFT 0 /* Shift value for ADC_REP */ +#define _ADC_SCANCTRL_REP_MASK 0x1UL /* Bit mask for ADC_REP */ +#define _ADC_SCANCTRL_REP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REP_DEFAULT (_ADC_SCANCTRL_REP_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_DIFF (0x1UL << 1) /* Scan Sequence Differential Mode */ +#define _ADC_SCANCTRL_DIFF_SHIFT 1 /* Shift value for ADC_DIFF */ +#define _ADC_SCANCTRL_DIFF_MASK 0x2UL /* Bit mask for ADC_DIFF */ +#define _ADC_SCANCTRL_DIFF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_DIFF_DEFAULT (_ADC_SCANCTRL_DIFF_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_ADJ (0x1UL << 2) /* Scan Sequence Result Adjustment */ +#define _ADC_SCANCTRL_ADJ_SHIFT 2 /* Shift value for ADC_ADJ */ +#define _ADC_SCANCTRL_ADJ_MASK 0x4UL /* Bit mask for ADC_ADJ */ +#define _ADC_SCANCTRL_ADJ_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_ADJ_RIGHT 0x00000000UL /* Mode RIGHT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_ADJ_LEFT 0x00000001UL /* Mode LEFT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_ADJ_DEFAULT (_ADC_SCANCTRL_ADJ_DEFAULT << 2) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_ADJ_RIGHT (_ADC_SCANCTRL_ADJ_RIGHT << 2) /* Shifted mode RIGHT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_ADJ_LEFT (_ADC_SCANCTRL_ADJ_LEFT << 2) /* Shifted mode LEFT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_RES_SHIFT 4 /* Shift value for ADC_RES */ +#define _ADC_SCANCTRL_RES_MASK 0x30UL /* Bit mask for ADC_RES */ +#define _ADC_SCANCTRL_RES_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_RES_12BIT 0x00000000UL /* Mode 12BIT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_RES_8BIT 0x00000001UL /* Mode 8BIT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_RES_6BIT 0x00000002UL /* Mode 6BIT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_RES_OVS 0x00000003UL /* Mode OVS for ADC_SCANCTRL */ +#define ADC_SCANCTRL_RES_DEFAULT (_ADC_SCANCTRL_RES_DEFAULT << 4) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_RES_12BIT (_ADC_SCANCTRL_RES_12BIT << 4) /* Shifted mode 12BIT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_RES_8BIT (_ADC_SCANCTRL_RES_8BIT << 4) /* Shifted mode 8BIT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_RES_6BIT (_ADC_SCANCTRL_RES_6BIT << 4) /* Shifted mode 6BIT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_RES_OVS (_ADC_SCANCTRL_RES_OVS << 4) /* Shifted mode OVS for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_SHIFT 8 /* Shift value for ADC_INPUTMASK */ +#define _ADC_SCANCTRL_INPUTMASK_MASK 0xFF00UL /* Bit mask for ADC_INPUTMASK */ +#define _ADC_SCANCTRL_INPUTMASK_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH0 0x00000001UL /* Mode CH0 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH0CH1 0x00000001UL /* Mode CH0CH1 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH1 0x00000002UL /* Mode CH1 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH2CH3 0x00000002UL /* Mode CH2CH3 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH2 0x00000004UL /* Mode CH2 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH4CH5 0x00000004UL /* Mode CH4CH5 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH6CH7 0x00000008UL /* Mode CH6CH7 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH3 0x00000008UL /* Mode CH3 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH4 0x00000010UL /* Mode CH4 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH5 0x00000020UL /* Mode CH5 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH6 0x00000040UL /* Mode CH6 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_INPUTMASK_CH7 0x00000080UL /* Mode CH7 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_DEFAULT (_ADC_SCANCTRL_INPUTMASK_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH0 (_ADC_SCANCTRL_INPUTMASK_CH0 << 8) /* Shifted mode CH0 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH0CH1 (_ADC_SCANCTRL_INPUTMASK_CH0CH1 << 8) /* Shifted mode CH0CH1 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH1 (_ADC_SCANCTRL_INPUTMASK_CH1 << 8) /* Shifted mode CH1 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH2CH3 (_ADC_SCANCTRL_INPUTMASK_CH2CH3 << 8) /* Shifted mode CH2CH3 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH2 (_ADC_SCANCTRL_INPUTMASK_CH2 << 8) /* Shifted mode CH2 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH4CH5 (_ADC_SCANCTRL_INPUTMASK_CH4CH5 << 8) /* Shifted mode CH4CH5 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH6CH7 (_ADC_SCANCTRL_INPUTMASK_CH6CH7 << 8) /* Shifted mode CH6CH7 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH3 (_ADC_SCANCTRL_INPUTMASK_CH3 << 8) /* Shifted mode CH3 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH4 (_ADC_SCANCTRL_INPUTMASK_CH4 << 8) /* Shifted mode CH4 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH5 (_ADC_SCANCTRL_INPUTMASK_CH5 << 8) /* Shifted mode CH5 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH6 (_ADC_SCANCTRL_INPUTMASK_CH6 << 8) /* Shifted mode CH6 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_INPUTMASK_CH7 (_ADC_SCANCTRL_INPUTMASK_CH7 << 8) /* Shifted mode CH7 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_SHIFT 16 /* Shift value for ADC_REF */ +#define _ADC_SCANCTRL_REF_MASK 0x70000UL /* Bit mask for ADC_REF */ +#define _ADC_SCANCTRL_REF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_1V25 0x00000000UL /* Mode 1V25 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_2V5 0x00000001UL /* Mode 2V5 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_VDD 0x00000002UL /* Mode VDD for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_5VDIFF 0x00000003UL /* Mode 5VDIFF for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_EXTSINGLE 0x00000004UL /* Mode EXTSINGLE for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_2XEXTDIFF 0x00000005UL /* Mode 2XEXTDIFF for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_REF_2XVDD 0x00000006UL /* Mode 2XVDD for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_DEFAULT (_ADC_SCANCTRL_REF_DEFAULT << 16) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_1V25 (_ADC_SCANCTRL_REF_1V25 << 16) /* Shifted mode 1V25 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_2V5 (_ADC_SCANCTRL_REF_2V5 << 16) /* Shifted mode 2V5 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_VDD (_ADC_SCANCTRL_REF_VDD << 16) /* Shifted mode VDD for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_5VDIFF (_ADC_SCANCTRL_REF_5VDIFF << 16) /* Shifted mode 5VDIFF for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_EXTSINGLE (_ADC_SCANCTRL_REF_EXTSINGLE << 16) /* Shifted mode EXTSINGLE for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_2XEXTDIFF (_ADC_SCANCTRL_REF_2XEXTDIFF << 16) /* Shifted mode 2XEXTDIFF for ADC_SCANCTRL */ +#define ADC_SCANCTRL_REF_2XVDD (_ADC_SCANCTRL_REF_2XVDD << 16) /* Shifted mode 2XVDD for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_SHIFT 20 /* Shift value for ADC_AT */ +#define _ADC_SCANCTRL_AT_MASK 0xF00000UL /* Bit mask for ADC_AT */ +#define _ADC_SCANCTRL_AT_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_1CYCLE 0x00000000UL /* Mode 1CYCLE for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_2CYCLES 0x00000001UL /* Mode 2CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_4CYCLES 0x00000002UL /* Mode 4CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_8CYCLES 0x00000003UL /* Mode 8CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_16CYCLES 0x00000004UL /* Mode 16CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_32CYCLES 0x00000005UL /* Mode 32CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_64CYCLES 0x00000006UL /* Mode 64CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_128CYCLES 0x00000007UL /* Mode 128CYCLES for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_AT_256CYCLES 0x00000008UL /* Mode 256CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_DEFAULT (_ADC_SCANCTRL_AT_DEFAULT << 20) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_1CYCLE (_ADC_SCANCTRL_AT_1CYCLE << 20) /* Shifted mode 1CYCLE for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_2CYCLES (_ADC_SCANCTRL_AT_2CYCLES << 20) /* Shifted mode 2CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_4CYCLES (_ADC_SCANCTRL_AT_4CYCLES << 20) /* Shifted mode 4CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_8CYCLES (_ADC_SCANCTRL_AT_8CYCLES << 20) /* Shifted mode 8CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_16CYCLES (_ADC_SCANCTRL_AT_16CYCLES << 20) /* Shifted mode 16CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_32CYCLES (_ADC_SCANCTRL_AT_32CYCLES << 20) /* Shifted mode 32CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_64CYCLES (_ADC_SCANCTRL_AT_64CYCLES << 20) /* Shifted mode 64CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_128CYCLES (_ADC_SCANCTRL_AT_128CYCLES << 20) /* Shifted mode 128CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_AT_256CYCLES (_ADC_SCANCTRL_AT_256CYCLES << 20) /* Shifted mode 256CYCLES for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSEN (0x1UL << 24) /* Scan Sequence PRS Trigger Enable */ +#define _ADC_SCANCTRL_PRSEN_SHIFT 24 /* Shift value for ADC_PRSEN */ +#define _ADC_SCANCTRL_PRSEN_MASK 0x1000000UL /* Bit mask for ADC_PRSEN */ +#define _ADC_SCANCTRL_PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSEN_DEFAULT (_ADC_SCANCTRL_PRSEN_DEFAULT << 24) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_SHIFT 28 /* Shift value for ADC_PRSSEL */ +#define _ADC_SCANCTRL_PRSSEL_MASK 0xF0000000UL /* Bit mask for ADC_PRSSEL */ +#define _ADC_SCANCTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for ADC_SCANCTRL */ +#define _ADC_SCANCTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_DEFAULT (_ADC_SCANCTRL_PRSSEL_DEFAULT << 28) /* Shifted mode DEFAULT for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH0 (_ADC_SCANCTRL_PRSSEL_PRSCH0 << 28) /* Shifted mode PRSCH0 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH1 (_ADC_SCANCTRL_PRSSEL_PRSCH1 << 28) /* Shifted mode PRSCH1 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH2 (_ADC_SCANCTRL_PRSSEL_PRSCH2 << 28) /* Shifted mode PRSCH2 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH3 (_ADC_SCANCTRL_PRSSEL_PRSCH3 << 28) /* Shifted mode PRSCH3 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH4 (_ADC_SCANCTRL_PRSSEL_PRSCH4 << 28) /* Shifted mode PRSCH4 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH5 (_ADC_SCANCTRL_PRSSEL_PRSCH5 << 28) /* Shifted mode PRSCH5 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH6 (_ADC_SCANCTRL_PRSSEL_PRSCH6 << 28) /* Shifted mode PRSCH6 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH7 (_ADC_SCANCTRL_PRSSEL_PRSCH7 << 28) /* Shifted mode PRSCH7 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH8 (_ADC_SCANCTRL_PRSSEL_PRSCH8 << 28) /* Shifted mode PRSCH8 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH9 (_ADC_SCANCTRL_PRSSEL_PRSCH9 << 28) /* Shifted mode PRSCH9 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH10 (_ADC_SCANCTRL_PRSSEL_PRSCH10 << 28) /* Shifted mode PRSCH10 for ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_PRSCH11 (_ADC_SCANCTRL_PRSSEL_PRSCH11 << 28) /* Shifted mode PRSCH11 for ADC_SCANCTRL */ + +/* Bit fields for ADC IEN */ + +#define _ADC_IEN_RESETVALUE 0x00000000UL /* Default value for ADC_IEN */ +#define _ADC_IEN_MASK 0x00000303UL /* Mask for ADC_IEN */ + +#define ADC_IEN_SINGLE (0x1UL << 0) /* Single Conversion Complete Interrupt Enable */ +#define _ADC_IEN_SINGLE_SHIFT 0 /* Shift value for ADC_SINGLE */ +#define _ADC_IEN_SINGLE_MASK 0x1UL /* Bit mask for ADC_SINGLE */ +#define _ADC_IEN_SINGLE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SINGLE_DEFAULT (_ADC_IEN_SINGLE_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SCAN (0x1UL << 1) /* Scan Conversion Complete Interrupt Enable */ +#define _ADC_IEN_SCAN_SHIFT 1 /* Shift value for ADC_SCAN */ +#define _ADC_IEN_SCAN_MASK 0x2UL /* Bit mask for ADC_SCAN */ +#define _ADC_IEN_SCAN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SCAN_DEFAULT (_ADC_IEN_SCAN_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SINGLEOF (0x1UL << 8) /* Single Result Overflow Interrupt Enable */ +#define _ADC_IEN_SINGLEOF_SHIFT 8 /* Shift value for ADC_SINGLEOF */ +#define _ADC_IEN_SINGLEOF_MASK 0x100UL /* Bit mask for ADC_SINGLEOF */ +#define _ADC_IEN_SINGLEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SINGLEOF_DEFAULT (_ADC_IEN_SINGLEOF_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SCANOF (0x1UL << 9) /* Scan Result Overflow Interrupt Enable */ +#define _ADC_IEN_SCANOF_SHIFT 9 /* Shift value for ADC_SCANOF */ +#define _ADC_IEN_SCANOF_MASK 0x200UL /* Bit mask for ADC_SCANOF */ +#define _ADC_IEN_SCANOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IEN */ +#define ADC_IEN_SCANOF_DEFAULT (_ADC_IEN_SCANOF_DEFAULT << 9) /* Shifted mode DEFAULT for ADC_IEN */ + +/* Bit fields for ADC IF */ + +#define _ADC_IF_RESETVALUE 0x00000000UL /* Default value for ADC_IF */ +#define _ADC_IF_MASK 0x00000303UL /* Mask for ADC_IF */ + +#define ADC_IF_SINGLE (0x1UL << 0) /* Single Conversion Complete Interrupt Flag */ +#define _ADC_IF_SINGLE_SHIFT 0 /* Shift value for ADC_SINGLE */ +#define _ADC_IF_SINGLE_MASK 0x1UL /* Bit mask for ADC_SINGLE */ +#define _ADC_IF_SINGLE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IF */ +#define ADC_IF_SINGLE_DEFAULT (_ADC_IF_SINGLE_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_IF */ +#define ADC_IF_SCAN (0x1UL << 1) /* Scan Conversion Complete Interrupt Flag */ +#define _ADC_IF_SCAN_SHIFT 1 /* Shift value for ADC_SCAN */ +#define _ADC_IF_SCAN_MASK 0x2UL /* Bit mask for ADC_SCAN */ +#define _ADC_IF_SCAN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IF */ +#define ADC_IF_SCAN_DEFAULT (_ADC_IF_SCAN_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_IF */ +#define ADC_IF_SINGLEOF (0x1UL << 8) /* Single Result Overflow Interrupt Flag */ +#define _ADC_IF_SINGLEOF_SHIFT 8 /* Shift value for ADC_SINGLEOF */ +#define _ADC_IF_SINGLEOF_MASK 0x100UL /* Bit mask for ADC_SINGLEOF */ +#define _ADC_IF_SINGLEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IF */ +#define ADC_IF_SINGLEOF_DEFAULT (_ADC_IF_SINGLEOF_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_IF */ +#define ADC_IF_SCANOF (0x1UL << 9) /* Scan Result Overflow Interrupt Flag */ +#define _ADC_IF_SCANOF_SHIFT 9 /* Shift value for ADC_SCANOF */ +#define _ADC_IF_SCANOF_MASK 0x200UL /* Bit mask for ADC_SCANOF */ +#define _ADC_IF_SCANOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IF */ +#define ADC_IF_SCANOF_DEFAULT (_ADC_IF_SCANOF_DEFAULT << 9) /* Shifted mode DEFAULT for ADC_IF */ + +/* Bit fields for ADC IFS */ + +#define _ADC_IFS_RESETVALUE 0x00000000UL /* Default value for ADC_IFS */ +#define _ADC_IFS_MASK 0x00000303UL /* Mask for ADC_IFS */ + +#define ADC_IFS_SINGLE (0x1UL << 0) /* Single Conversion Complete Interrupt Flag Set */ +#define _ADC_IFS_SINGLE_SHIFT 0 /* Shift value for ADC_SINGLE */ +#define _ADC_IFS_SINGLE_MASK 0x1UL /* Bit mask for ADC_SINGLE */ +#define _ADC_IFS_SINGLE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SINGLE_DEFAULT (_ADC_IFS_SINGLE_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SCAN (0x1UL << 1) /* Scan Conversion Complete Interrupt Flag Set */ +#define _ADC_IFS_SCAN_SHIFT 1 /* Shift value for ADC_SCAN */ +#define _ADC_IFS_SCAN_MASK 0x2UL /* Bit mask for ADC_SCAN */ +#define _ADC_IFS_SCAN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SCAN_DEFAULT (_ADC_IFS_SCAN_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SINGLEOF (0x1UL << 8) /* Single Result Overflow Interrupt Flag Set */ +#define _ADC_IFS_SINGLEOF_SHIFT 8 /* Shift value for ADC_SINGLEOF */ +#define _ADC_IFS_SINGLEOF_MASK 0x100UL /* Bit mask for ADC_SINGLEOF */ +#define _ADC_IFS_SINGLEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SINGLEOF_DEFAULT (_ADC_IFS_SINGLEOF_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SCANOF (0x1UL << 9) /* Scan Result Overflow Interrupt Flag Set */ +#define _ADC_IFS_SCANOF_SHIFT 9 /* Shift value for ADC_SCANOF */ +#define _ADC_IFS_SCANOF_MASK 0x200UL /* Bit mask for ADC_SCANOF */ +#define _ADC_IFS_SCANOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFS */ +#define ADC_IFS_SCANOF_DEFAULT (_ADC_IFS_SCANOF_DEFAULT << 9) /* Shifted mode DEFAULT for ADC_IFS */ + +/* Bit fields for ADC IFC */ + +#define _ADC_IFC_RESETVALUE 0x00000000UL /* Default value for ADC_IFC */ +#define _ADC_IFC_MASK 0x00000303UL /* Mask for ADC_IFC */ + +#define ADC_IFC_SINGLE (0x1UL << 0) /* Single Conversion Complete Interrupt Flag Clear */ +#define _ADC_IFC_SINGLE_SHIFT 0 /* Shift value for ADC_SINGLE */ +#define _ADC_IFC_SINGLE_MASK 0x1UL /* Bit mask for ADC_SINGLE */ +#define _ADC_IFC_SINGLE_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SINGLE_DEFAULT (_ADC_IFC_SINGLE_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SCAN (0x1UL << 1) /* Scan Conversion Complete Interrupt Flag Clear */ +#define _ADC_IFC_SCAN_SHIFT 1 /* Shift value for ADC_SCAN */ +#define _ADC_IFC_SCAN_MASK 0x2UL /* Bit mask for ADC_SCAN */ +#define _ADC_IFC_SCAN_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SCAN_DEFAULT (_ADC_IFC_SCAN_DEFAULT << 1) /* Shifted mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SINGLEOF (0x1UL << 8) /* Single Result Overflow Interrupt Flag Clear */ +#define _ADC_IFC_SINGLEOF_SHIFT 8 /* Shift value for ADC_SINGLEOF */ +#define _ADC_IFC_SINGLEOF_MASK 0x100UL /* Bit mask for ADC_SINGLEOF */ +#define _ADC_IFC_SINGLEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SINGLEOF_DEFAULT (_ADC_IFC_SINGLEOF_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SCANOF (0x1UL << 9) /* Scan Result Overflow Interrupt Flag Clear */ +#define _ADC_IFC_SCANOF_SHIFT 9 /* Shift value for ADC_SCANOF */ +#define _ADC_IFC_SCANOF_MASK 0x200UL /* Bit mask for ADC_SCANOF */ +#define _ADC_IFC_SCANOF_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_IFC */ +#define ADC_IFC_SCANOF_DEFAULT (_ADC_IFC_SCANOF_DEFAULT << 9) /* Shifted mode DEFAULT for ADC_IFC */ + +/* Bit fields for ADC SINGLEDATA */ + +#define _ADC_SINGLEDATA_RESETVALUE 0x00000000UL /* Default value for ADC_SINGLEDATA */ +#define _ADC_SINGLEDATA_MASK 0xFFFFFFFFUL /* Mask for ADC_SINGLEDATA */ + +#define _ADC_SINGLEDATA_DATA_SHIFT 0 /* Shift value for ADC_DATA */ +#define _ADC_SINGLEDATA_DATA_MASK 0xFFFFFFFFUL /* Bit mask for ADC_DATA */ +#define _ADC_SINGLEDATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLEDATA */ +#define ADC_SINGLEDATA_DATA_DEFAULT (_ADC_SINGLEDATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SINGLEDATA */ + +/* Bit fields for ADC SCANDATA */ + +#define _ADC_SCANDATA_RESETVALUE 0x00000000UL /* Default value for ADC_SCANDATA */ +#define _ADC_SCANDATA_MASK 0xFFFFFFFFUL /* Mask for ADC_SCANDATA */ + +#define _ADC_SCANDATA_DATA_SHIFT 0 /* Shift value for ADC_DATA */ +#define _ADC_SCANDATA_DATA_MASK 0xFFFFFFFFUL /* Bit mask for ADC_DATA */ +#define _ADC_SCANDATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANDATA */ +#define ADC_SCANDATA_DATA_DEFAULT (_ADC_SCANDATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SCANDATA */ + +/* Bit fields for ADC SINGLEDATAP */ + +#define _ADC_SINGLEDATAP_RESETVALUE 0x00000000UL /* Default value for ADC_SINGLEDATAP */ +#define _ADC_SINGLEDATAP_MASK 0xFFFFFFFFUL /* Mask for ADC_SINGLEDATAP */ + +#define _ADC_SINGLEDATAP_DATAP_SHIFT 0 /* Shift value for ADC_DATAP */ +#define _ADC_SINGLEDATAP_DATAP_MASK 0xFFFFFFFFUL /* Bit mask for ADC_DATAP */ +#define _ADC_SINGLEDATAP_DATAP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SINGLEDATAP */ +#define ADC_SINGLEDATAP_DATAP_DEFAULT (_ADC_SINGLEDATAP_DATAP_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SINGLEDATAP */ + +/* Bit fields for ADC SCANDATAP */ + +#define _ADC_SCANDATAP_RESETVALUE 0x00000000UL /* Default value for ADC_SCANDATAP */ +#define _ADC_SCANDATAP_MASK 0xFFFFFFFFUL /* Mask for ADC_SCANDATAP */ + +#define _ADC_SCANDATAP_DATAP_SHIFT 0 /* Shift value for ADC_DATAP */ +#define _ADC_SCANDATAP_DATAP_MASK 0xFFFFFFFFUL /* Bit mask for ADC_DATAP */ +#define _ADC_SCANDATAP_DATAP_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_SCANDATAP */ +#define ADC_SCANDATAP_DATAP_DEFAULT (_ADC_SCANDATAP_DATAP_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_SCANDATAP */ + +/* Bit fields for ADC CAL */ + +#define _ADC_CAL_RESETVALUE 0x3F003F00UL /* Default value for ADC_CAL */ +#define _ADC_CAL_MASK 0x7F7F7F7FUL /* Mask for ADC_CAL */ + +#define _ADC_CAL_SINGLEOFFSET_SHIFT 0 /* Shift value for ADC_SINGLEOFFSET */ +#define _ADC_CAL_SINGLEOFFSET_MASK 0x7FUL /* Bit mask for ADC_SINGLEOFFSET */ +#define _ADC_CAL_SINGLEOFFSET_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CAL */ +#define ADC_CAL_SINGLEOFFSET_DEFAULT (_ADC_CAL_SINGLEOFFSET_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_CAL */ +#define _ADC_CAL_SINGLEGAIN_SHIFT 8 /* Shift value for ADC_SINGLEGAIN */ +#define _ADC_CAL_SINGLEGAIN_MASK 0x7F00UL /* Bit mask for ADC_SINGLEGAIN */ +#define _ADC_CAL_SINGLEGAIN_DEFAULT 0x0000003FUL /* Mode DEFAULT for ADC_CAL */ +#define ADC_CAL_SINGLEGAIN_DEFAULT (_ADC_CAL_SINGLEGAIN_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_CAL */ +#define _ADC_CAL_SCANOFFSET_SHIFT 16 /* Shift value for ADC_SCANOFFSET */ +#define _ADC_CAL_SCANOFFSET_MASK 0x7F0000UL /* Bit mask for ADC_SCANOFFSET */ +#define _ADC_CAL_SCANOFFSET_DEFAULT 0x00000000UL /* Mode DEFAULT for ADC_CAL */ +#define ADC_CAL_SCANOFFSET_DEFAULT (_ADC_CAL_SCANOFFSET_DEFAULT << 16) /* Shifted mode DEFAULT for ADC_CAL */ +#define _ADC_CAL_SCANGAIN_SHIFT 24 /* Shift value for ADC_SCANGAIN */ +#define _ADC_CAL_SCANGAIN_MASK 0x7F000000UL /* Bit mask for ADC_SCANGAIN */ +#define _ADC_CAL_SCANGAIN_DEFAULT 0x0000003FUL /* Mode DEFAULT for ADC_CAL */ +#define ADC_CAL_SCANGAIN_DEFAULT (_ADC_CAL_SCANGAIN_DEFAULT << 24) /* Shifted mode DEFAULT for ADC_CAL */ + +/* Bit fields for ADC BIASPROG */ + +#define _ADC_BIASPROG_RESETVALUE 0x00000747UL /* Default value for ADC_BIASPROG */ +#define _ADC_BIASPROG_MASK 0x00000F4FUL /* Mask for ADC_BIASPROG */ + +#define _ADC_BIASPROG_BIASPROG_SHIFT 0 /* Shift value for ADC_BIASPROG */ +#define _ADC_BIASPROG_BIASPROG_MASK 0xFUL /* Bit mask for ADC_BIASPROG */ +#define _ADC_BIASPROG_BIASPROG_DEFAULT 0x00000007UL /* Mode DEFAULT for ADC_BIASPROG */ +#define ADC_BIASPROG_BIASPROG_DEFAULT (_ADC_BIASPROG_BIASPROG_DEFAULT << 0) /* Shifted mode DEFAULT for ADC_BIASPROG */ +#define ADC_BIASPROG_HALFBIAS (0x1UL << 6) /* Half Bias Current */ +#define _ADC_BIASPROG_HALFBIAS_SHIFT 6 /* Shift value for ADC_HALFBIAS */ +#define _ADC_BIASPROG_HALFBIAS_MASK 0x40UL /* Bit mask for ADC_HALFBIAS */ +#define _ADC_BIASPROG_HALFBIAS_DEFAULT 0x00000001UL /* Mode DEFAULT for ADC_BIASPROG */ +#define ADC_BIASPROG_HALFBIAS_DEFAULT (_ADC_BIASPROG_HALFBIAS_DEFAULT << 6) /* Shifted mode DEFAULT for ADC_BIASPROG */ +#define _ADC_BIASPROG_COMPBIAS_SHIFT 8 /* Shift value for ADC_COMPBIAS */ +#define _ADC_BIASPROG_COMPBIAS_MASK 0xF00UL /* Bit mask for ADC_COMPBIAS */ +#define _ADC_BIASPROG_COMPBIAS_DEFAULT 0x00000007UL /* Mode DEFAULT for ADC_BIASPROG */ +#define ADC_BIASPROG_COMPBIAS_DEFAULT (_ADC_BIASPROG_COMPBIAS_DEFAULT << 8) /* Shifted mode DEFAULT for ADC_BIASPROG */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ADC_H */ diff --git a/arch/arm/src/efm32/chip/efm32_aes.h b/arch/arm/src/efm32/chip/efm32_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..3376edaec317116b6a305981b6963eb689dd7173 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_aes.h @@ -0,0 +1,327 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_aes.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_AES_H_ +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_AES_H_ + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* AES Register Offsets ********************************************************************************************************/ + +#define EFM32_AES_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_AES_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_AES_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_AES_IEN_OFFSET 0x000c /* Interrupt Enable Register */ +#define EFM32_AES_IF_OFFSET 0x0010 /* Interrupt Flag Register */ +#define EFM32_AES_IFS_OFFSET 0x0014 /* Interrupt Flag Set Register */ +#define EFM32_AES_IFC_OFFSET 0x0018 /* Interrupt Flag Clear Register */ +#define EFM32_AES_DATA_OFFSET 0x001c /* DATA Register */ +#define EFM32_AES_XORDATA_OFFSET 0x0020 /* XORDATA Register */ +#define EFM32_AES_KEYLA_OFFSET 0x0030 /* KEY Low Register */ +#define EFM32_AES_KEYLB_OFFSET 0x0034 /* KEY Low Register */ +#define EFM32_AES_KEYLC_OFFSET 0x0038 /* KEY Low Register */ +#define EFM32_AES_KEYLD_OFFSET 0x003c /* KEY Low Register */ +#define EFM32_AES_KEYHA_OFFSET 0x0040 /* KEY High Register */ +#define EFM32_AES_KEYHB_OFFSET 0x0044 /* KEY High Register */ +#define EFM32_AES_KEYHC_OFFSET 0x0048 /* KEY High Register */ +#define EFM32_AES_KEYHD_OFFSET 0x004c /* KEY High Register */ + +/* AES Register Addresses ******************************************************************************************************/ + +#define EFM32_AES_CTRL (EFM32_AES_BASE+EFM32_AES_CTRL_OFFSET) +#define EFM32_AES_CMD (EFM32_AES_BASE+EFM32_AES_CMD_OFFSET) +#define EFM32_AES_STATUS (EFM32_AES_BASE+EFM32_AES_STATUS_OFFSET) +#define EFM32_AES_IEN (EFM32_AES_BASE+EFM32_AES_IEN_OFFSET) +#define EFM32_AES_IF (EFM32_AES_BASE+EFM32_AES_IF_OFFSET) +#define EFM32_AES_IFS (EFM32_AES_BASE+EFM32_AES_IFS_OFFSET) +#define EFM32_AES_IFC (EFM32_AES_BASE+EFM32_AES_IFC_OFFSET) +#define EFM32_AES_DATA (EFM32_AES_BASE+EFM32_AES_DATA_OFFSET) +#define EFM32_AES_XORDATA (EFM32_AES_BASE+EFM32_AES_XORDATA_OFFSET) +#define EFM32_AES_KEYLA (EFM32_AES_BASE+EFM32_AES_KEYLA_OFFSET) +#define EFM32_AES_KEYLB (EFM32_AES_BASE+EFM32_AES_KEYLB_OFFSET) +#define EFM32_AES_KEYLC (EFM32_AES_BASE+EFM32_AES_KEYLC_OFFSET) +#define EFM32_AES_KEYLD (EFM32_AES_BASE+EFM32_AES_KEYLD_OFFSET) +#define EFM32_AES_KEYHA (EFM32_AES_BASE+EFM32_AES_KEYHA_OFFSET) +#define EFM32_AES_KEYHB (EFM32_AES_BASE+EFM32_AES_KEYHB_OFFSET) +#define EFM32_AES_KEYHC (EFM32_AES_BASE+EFM32_AES_KEYHC_OFFSET) +#define EFM32_AES_KEYHD (EFM32_AES_BASE+EFM32_AES_KEYHD_OFFSET) + +/* AES Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for AES CTRL */ + +#define _AES_CTRL_RESETVALUE 0x00000000UL /* Default value for AES_CTRL */ +#define _AES_CTRL_MASK 0x00000077UL /* Mask for AES_CTRL */ + +#define AES_CTRL_DECRYPT (0x1UL << 0) /* Decryption/Encryption Mode */ +#define _AES_CTRL_DECRYPT_SHIFT 0 /* Shift value for AES_DECRYPT */ +#define _AES_CTRL_DECRYPT_MASK 0x1UL /* Bit mask for AES_DECRYPT */ +#define _AES_CTRL_DECRYPT_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_DECRYPT_DEFAULT (_AES_CTRL_DECRYPT_DEFAULT << 0) /* Shifted mode DEFAULT for AES_CTRL */ +#define AES_CTRL_AES256 (0x1UL << 1) /* AES-256 Mode */ +#define _AES_CTRL_AES256_SHIFT 1 /* Shift value for AES_AES256 */ +#define _AES_CTRL_AES256_MASK 0x2UL /* Bit mask for AES_AES256 */ +#define _AES_CTRL_AES256_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_AES256_DEFAULT (_AES_CTRL_AES256_DEFAULT << 1) /* Shifted mode DEFAULT for AES_CTRL */ +#define AES_CTRL_KEYBUFEN (0x1UL << 2) /* Key Buffer Enable */ +#define _AES_CTRL_KEYBUFEN_SHIFT 2 /* Shift value for AES_KEYBUFEN */ +#define _AES_CTRL_KEYBUFEN_MASK 0x4UL /* Bit mask for AES_KEYBUFEN */ +#define _AES_CTRL_KEYBUFEN_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_KEYBUFEN_DEFAULT (_AES_CTRL_KEYBUFEN_DEFAULT << 2) /* Shifted mode DEFAULT for AES_CTRL */ +#define AES_CTRL_DATASTART (0x1UL << 4) /* AES_DATA Write Start */ +#define _AES_CTRL_DATASTART_SHIFT 4 /* Shift value for AES_DATASTART */ +#define _AES_CTRL_DATASTART_MASK 0x10UL /* Bit mask for AES_DATASTART */ +#define _AES_CTRL_DATASTART_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_DATASTART_DEFAULT (_AES_CTRL_DATASTART_DEFAULT << 4) /* Shifted mode DEFAULT for AES_CTRL */ +#define AES_CTRL_XORSTART (0x1UL << 5) /* AES_XORDATA Write Start */ +#define _AES_CTRL_XORSTART_SHIFT 5 /* Shift value for AES_XORSTART */ +#define _AES_CTRL_XORSTART_MASK 0x20UL /* Bit mask for AES_XORSTART */ +#define _AES_CTRL_XORSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_XORSTART_DEFAULT (_AES_CTRL_XORSTART_DEFAULT << 5) /* Shifted mode DEFAULT for AES_CTRL */ +#define AES_CTRL_BYTEORDER (0x1UL << 6) /* Configure byte order in data and key registers */ +#define _AES_CTRL_BYTEORDER_SHIFT 6 /* Shift value for AES_BYTEORDER */ +#define _AES_CTRL_BYTEORDER_MASK 0x40UL /* Bit mask for AES_BYTEORDER */ +#define _AES_CTRL_BYTEORDER_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CTRL */ +#define AES_CTRL_BYTEORDER_DEFAULT (_AES_CTRL_BYTEORDER_DEFAULT << 6) /* Shifted mode DEFAULT for AES_CTRL */ + +/* Bit fields for AES CMD */ + +#define _AES_CMD_RESETVALUE 0x00000000UL /* Default value for AES_CMD */ +#define _AES_CMD_MASK 0x00000003UL /* Mask for AES_CMD */ + +#define AES_CMD_START (0x1UL << 0) /* Encryption/Decryption Start */ +#define _AES_CMD_START_SHIFT 0 /* Shift value for AES_START */ +#define _AES_CMD_START_MASK 0x1UL /* Bit mask for AES_START */ +#define _AES_CMD_START_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CMD */ +#define AES_CMD_START_DEFAULT (_AES_CMD_START_DEFAULT << 0) /* Shifted mode DEFAULT for AES_CMD */ +#define AES_CMD_STOP (0x1UL << 1) /* Encryption/Decryption Stop */ +#define _AES_CMD_STOP_SHIFT 1 /* Shift value for AES_STOP */ +#define _AES_CMD_STOP_MASK 0x2UL /* Bit mask for AES_STOP */ +#define _AES_CMD_STOP_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_CMD */ +#define AES_CMD_STOP_DEFAULT (_AES_CMD_STOP_DEFAULT << 1) /* Shifted mode DEFAULT for AES_CMD */ + +/* Bit fields for AES STATUS */ + +#define _AES_STATUS_RESETVALUE 0x00000000UL /* Default value for AES_STATUS */ +#define _AES_STATUS_MASK 0x00000001UL /* Mask for AES_STATUS */ + +#define AES_STATUS_RUNNING (0x1UL << 0) /* AES Running */ +#define _AES_STATUS_RUNNING_SHIFT 0 /* Shift value for AES_RUNNING */ +#define _AES_STATUS_RUNNING_MASK 0x1UL /* Bit mask for AES_RUNNING */ +#define _AES_STATUS_RUNNING_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_STATUS */ +#define AES_STATUS_RUNNING_DEFAULT (_AES_STATUS_RUNNING_DEFAULT << 0) /* Shifted mode DEFAULT for AES_STATUS */ + +/* Bit fields for AES IEN */ + +#define _AES_IEN_RESETVALUE 0x00000000UL /* Default value for AES_IEN */ +#define _AES_IEN_MASK 0x00000001UL /* Mask for AES_IEN */ + +#define AES_IEN_DONE (0x1UL << 0) /* Encryption/Decryption Done Interrupt Enable */ +#define _AES_IEN_DONE_SHIFT 0 /* Shift value for AES_DONE */ +#define _AES_IEN_DONE_MASK 0x1UL /* Bit mask for AES_DONE */ +#define _AES_IEN_DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_IEN */ +#define AES_IEN_DONE_DEFAULT (_AES_IEN_DONE_DEFAULT << 0) /* Shifted mode DEFAULT for AES_IEN */ + +/* Bit fields for AES IF */ + +#define _AES_IF_RESETVALUE 0x00000000UL /* Default value for AES_IF */ +#define _AES_IF_MASK 0x00000001UL /* Mask for AES_IF */ + +#define AES_IF_DONE (0x1UL << 0) /* Encryption/Decryption Done Interrupt Flag */ +#define _AES_IF_DONE_SHIFT 0 /* Shift value for AES_DONE */ +#define _AES_IF_DONE_MASK 0x1UL /* Bit mask for AES_DONE */ +#define _AES_IF_DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_IF */ +#define AES_IF_DONE_DEFAULT (_AES_IF_DONE_DEFAULT << 0) /* Shifted mode DEFAULT for AES_IF */ + +/* Bit fields for AES IFS */ + +#define _AES_IFS_RESETVALUE 0x00000000UL /* Default value for AES_IFS */ +#define _AES_IFS_MASK 0x00000001UL /* Mask for AES_IFS */ + +#define AES_IFS_DONE (0x1UL << 0) /* Encryption/Decryption Done Interrupt Flag Set */ +#define _AES_IFS_DONE_SHIFT 0 /* Shift value for AES_DONE */ +#define _AES_IFS_DONE_MASK 0x1UL /* Bit mask for AES_DONE */ +#define _AES_IFS_DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_IFS */ +#define AES_IFS_DONE_DEFAULT (_AES_IFS_DONE_DEFAULT << 0) /* Shifted mode DEFAULT for AES_IFS */ + +/* Bit fields for AES IFC */ + +#define _AES_IFC_RESETVALUE 0x00000000UL /* Default value for AES_IFC */ +#define _AES_IFC_MASK 0x00000001UL /* Mask for AES_IFC */ + +#define AES_IFC_DONE (0x1UL << 0) /* Encryption/Decryption Done Interrupt Flag Clear */ +#define _AES_IFC_DONE_SHIFT 0 /* Shift value for AES_DONE */ +#define _AES_IFC_DONE_MASK 0x1UL /* Bit mask for AES_DONE */ +#define _AES_IFC_DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_IFC */ +#define AES_IFC_DONE_DEFAULT (_AES_IFC_DONE_DEFAULT << 0) /* Shifted mode DEFAULT for AES_IFC */ + +/* Bit fields for AES DATA */ + +#define _AES_DATA_RESETVALUE 0x00000000UL /* Default value for AES_DATA */ +#define _AES_DATA_MASK 0xFFFFFFFFUL /* Mask for AES_DATA */ + +#define _AES_DATA_DATA_SHIFT 0 /* Shift value for AES_DATA */ +#define _AES_DATA_DATA_MASK 0xFFFFFFFFUL /* Bit mask for AES_DATA */ +#define _AES_DATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_DATA */ +#define AES_DATA_DATA_DEFAULT (_AES_DATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for AES_DATA */ + +/* Bit fields for AES XORDATA */ + +#define _AES_XORDATA_RESETVALUE 0x00000000UL /* Default value for AES_XORDATA */ +#define _AES_XORDATA_MASK 0xFFFFFFFFUL /* Mask for AES_XORDATA */ + +#define _AES_XORDATA_XORDATA_SHIFT 0 /* Shift value for AES_XORDATA */ +#define _AES_XORDATA_XORDATA_MASK 0xFFFFFFFFUL /* Bit mask for AES_XORDATA */ +#define _AES_XORDATA_XORDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_XORDATA */ +#define AES_XORDATA_XORDATA_DEFAULT (_AES_XORDATA_XORDATA_DEFAULT << 0) /* Shifted mode DEFAULT for AES_XORDATA */ + +/* Bit fields for AES KEYLA */ + +#define _AES_KEYLA_RESETVALUE 0x00000000UL /* Default value for AES_KEYLA */ +#define _AES_KEYLA_MASK 0xFFFFFFFFUL /* Mask for AES_KEYLA */ + +#define _AES_KEYLA_KEYLA_SHIFT 0 /* Shift value for AES_KEYLA */ +#define _AES_KEYLA_KEYLA_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYLA */ +#define _AES_KEYLA_KEYLA_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYLA */ +#define AES_KEYLA_KEYLA_DEFAULT (_AES_KEYLA_KEYLA_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYLA */ + +/* Bit fields for AES KEYLB */ + +#define _AES_KEYLB_RESETVALUE 0x00000000UL /* Default value for AES_KEYLB */ +#define _AES_KEYLB_MASK 0xFFFFFFFFUL /* Mask for AES_KEYLB */ + +#define _AES_KEYLB_KEYLB_SHIFT 0 /* Shift value for AES_KEYLB */ +#define _AES_KEYLB_KEYLB_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYLB */ +#define _AES_KEYLB_KEYLB_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYLB */ +#define AES_KEYLB_KEYLB_DEFAULT (_AES_KEYLB_KEYLB_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYLB */ + +/* Bit fields for AES KEYLC */ + +#define _AES_KEYLC_RESETVALUE 0x00000000UL /* Default value for AES_KEYLC */ +#define _AES_KEYLC_MASK 0xFFFFFFFFUL /* Mask for AES_KEYLC */ + +#define _AES_KEYLC_KEYLC_SHIFT 0 /* Shift value for AES_KEYLC */ +#define _AES_KEYLC_KEYLC_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYLC */ +#define _AES_KEYLC_KEYLC_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYLC */ +#define AES_KEYLC_KEYLC_DEFAULT (_AES_KEYLC_KEYLC_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYLC */ + +/* Bit fields for AES KEYLD */ + +#define _AES_KEYLD_RESETVALUE 0x00000000UL /* Default value for AES_KEYLD */ +#define _AES_KEYLD_MASK 0xFFFFFFFFUL /* Mask for AES_KEYLD */ + +#define _AES_KEYLD_KEYLD_SHIFT 0 /* Shift value for AES_KEYLD */ +#define _AES_KEYLD_KEYLD_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYLD */ +#define _AES_KEYLD_KEYLD_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYLD */ +#define AES_KEYLD_KEYLD_DEFAULT (_AES_KEYLD_KEYLD_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYLD */ + +/* Bit fields for AES KEYHA */ + +#define _AES_KEYHA_RESETVALUE 0x00000000UL /* Default value for AES_KEYHA */ +#define _AES_KEYHA_MASK 0xFFFFFFFFUL /* Mask for AES_KEYHA */ + +#define _AES_KEYHA_KEYHA_SHIFT 0 /* Shift value for AES_KEYHA */ +#define _AES_KEYHA_KEYHA_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYHA */ +#define _AES_KEYHA_KEYHA_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYHA */ +#define AES_KEYHA_KEYHA_DEFAULT (_AES_KEYHA_KEYHA_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYHA */ + +/* Bit fields for AES KEYHB */ + +#define _AES_KEYHB_RESETVALUE 0x00000000UL /* Default value for AES_KEYHB */ +#define _AES_KEYHB_MASK 0xFFFFFFFFUL /* Mask for AES_KEYHB */ + +#define _AES_KEYHB_KEYHB_SHIFT 0 /* Shift value for AES_KEYHB */ +#define _AES_KEYHB_KEYHB_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYHB */ +#define _AES_KEYHB_KEYHB_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYHB */ +#define AES_KEYHB_KEYHB_DEFAULT (_AES_KEYHB_KEYHB_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYHB */ + +/* Bit fields for AES KEYHC */ + +#define _AES_KEYHC_RESETVALUE 0x00000000UL /* Default value for AES_KEYHC */ +#define _AES_KEYHC_MASK 0xFFFFFFFFUL /* Mask for AES_KEYHC */ + +#define _AES_KEYHC_KEYHC_SHIFT 0 /* Shift value for AES_KEYHC */ +#define _AES_KEYHC_KEYHC_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYHC */ +#define _AES_KEYHC_KEYHC_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYHC */ +#define AES_KEYHC_KEYHC_DEFAULT (_AES_KEYHC_KEYHC_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYHC */ + +/* Bit fields for AES KEYHD */ + +#define _AES_KEYHD_RESETVALUE 0x00000000UL /* Default value for AES_KEYHD */ +#define _AES_KEYHD_MASK 0xFFFFFFFFUL /* Mask for AES_KEYHD */ + +#define _AES_KEYHD_KEYHD_SHIFT 0 /* Shift value for AES_KEYHD */ +#define _AES_KEYHD_KEYHD_MASK 0xFFFFFFFFUL /* Bit mask for AES_KEYHD */ +#define _AES_KEYHD_KEYHD_DEFAULT 0x00000000UL /* Mode DEFAULT for AES_KEYHD */ +#define AES_KEYHD_KEYHD_DEFAULT (_AES_KEYHD_KEYHD_DEFAULT << 0) /* Shifted mode DEFAULT for AES_KEYHD */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_AES_H_ */ diff --git a/arch/arm/src/efm32/chip/efm32_burtc.h b/arch/arm/src/efm32/chip/efm32_burtc.h new file mode 100644 index 0000000000000000000000000000000000000000..7cdc5cd347a688302a6dd486c5d29a8481856643 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_burtc.h @@ -0,0 +1,471 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_burtc.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_BURTC_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_BURTC_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +#define EFM32_BURTC_NREGS 128 /* Number of backup retention registers */ + +/* BURTC Register Offsets ******************************************************************************************************/ + +#define EFM32_BURTC_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_BURTC_LPMODE_OFFSET 0x0004 /* Low power mode configuration */ +#define EFM32_BURTC_CNT_OFFSET 0x0008 /* Counter Value Register */ +#define EFM32_BURTC_COMP0_OFFSET 0x000c /* Counter Compare Value */ +#define EFM32_BURTC_TIMESTAMP_OFFSET 0x0010 /* Backup mode timestamp */ +#define EFM32_BURTC_LFXOFDET_OFFSET 0x0014 /* LFXO */ +#define EFM32_BURTC_STATUS_OFFSET 0x0018 /* Backup domain status */ +#define EFM32_BURTC_CMD_OFFSET 0x001c /* Command Register */ +#define EFM32_BURTC_POWERDOWN_OFFSET 0x0020 /* Retention RAM power-down resgister */ +#define EFM32_BURTC_LOCK_OFFSET 0x0024 /* Configuration Lock Register */ +#define EFM32_BURTC_IF_OFFSET 0x0028 /* Interrupt Flag Register */ +#define EFM32_BURTC_IFS_OFFSET 0x002c /* Interrupt Flag Set Register */ +#define EFM32_BURTC_IFC_OFFSET 0x0030 /* Interrupt Flag Clear Register */ +#define EFM32_BURTC_IEN_OFFSET 0x0034 /* Interrupt Enable Register */ +#define EFM32_BURTC_FREEZE_OFFSET 0x0038 /* Freeze Register */ +#define EFM32_BURTC_SYNCBUSY_OFFSET 0x003c /* Synchronization Busy Register */ + +/* Backup retention register */ + +#define EFM32_BURTC_RET_REG_OFFSET(n) (0x0100 + ((n) << 2)) + +/* BURTC Register Addresses ****************************************************************************************************/ + +#define EFM32_BURTC_CTRL (EFM32_BCKRTC_BASE+EFM32_BURTC_CTRL_OFFSET) +#define EFM32_BURTC_LPMODE (EFM32_BCKRTC_BASE+EFM32_BURTC_LPMODE_OFFSET) +#define EFM32_BURTC_CNT (EFM32_BCKRTC_BASE+EFM32_BURTC_CNT_OFFSET) +#define EFM32_BURTC_COMP0 (EFM32_BCKRTC_BASE+EFM32_BURTC_COMP0_OFFSET) +#define EFM32_BURTC_TIMESTAMP (EFM32_BCKRTC_BASE+EFM32_BURTC_TIMESTAMP_OFFSET) +#define EFM32_BURTC_LFXOFDET (EFM32_BCKRTC_BASE+EFM32_BURTC_LFXOFDET_OFFSET) +#define EFM32_BURTC_STATUS (EFM32_BCKRTC_BASE+EFM32_BURTC_STATUS_OFFSET) +#define EFM32_BURTC_CMD (EFM32_BCKRTC_BASE+EFM32_BURTC_CMD_OFFSET) +#define EFM32_BURTC_POWERDOWN (EFM32_BCKRTC_BASE+EFM32_BURTC_POWERDOWN_OFFSET) +#define EFM32_BURTC_LOCK (EFM32_BCKRTC_BASE+EFM32_BURTC_LOCK_OFFSET) +#define EFM32_BURTC_IF (EFM32_BCKRTC_BASE+EFM32_BURTC_IF_OFFSET) +#define EFM32_BURTC_IFS (EFM32_BCKRTC_BASE+EFM32_BURTC_IFS_OFFSET) +#define EFM32_BURTC_IFC (EFM32_BCKRTC_BASE+EFM32_BURTC_IFC_OFFSET) +#define EFM32_BURTC_IEN (EFM32_BCKRTC_BASE+EFM32_BURTC_IEN_OFFSET) +#define EFM32_BURTC_FREEZE (EFM32_BCKRTC_BASE+EFM32_BURTC_FREEZE_OFFSET) +#define EFM32_BURTC_SYNCBUSY (EFM32_BCKRTC_BASE+EFM32_BURTC_SYNCBUSY_OFFSET) + +/* Backup retention register */ + +#define EFM32_BURTC_RET_REG(n) (EFM32_BCKRTC_BASE+EFM32_BURTC_RET_REG_OFFSET(n)) + +/* BURTC Register Bit Field Definitions ****************************************************************************************/ + +/* Bit fields for BURTC CTRL */ + +#define _BURTC_CTRL_RESETVALUE 0x00000008UL /* Default value for BURTC_CTRL */ +#define _BURTC_CTRL_MASK 0x000077FFUL /* Mask for BURTC_CTRL */ + +#define _BURTC_CTRL_MODE_SHIFT 0 /* Shift value for BURTC_MODE */ +#define _BURTC_CTRL_MODE_MASK 0x3UL /* Bit mask for BURTC_MODE */ +#define _BURTC_CTRL_MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define _BURTC_CTRL_MODE_DISABLE 0x00000000UL /* Mode DISABLE for BURTC_CTRL */ +#define _BURTC_CTRL_MODE_EM2EN 0x00000001UL /* Mode EM2EN for BURTC_CTRL */ +#define _BURTC_CTRL_MODE_EM3EN 0x00000002UL /* Mode EM3EN for BURTC_CTRL */ +#define _BURTC_CTRL_MODE_EM4EN 0x00000003UL /* Mode EM4EN for BURTC_CTRL */ +#define BURTC_CTRL_MODE_DEFAULT (_BURTC_CTRL_MODE_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_MODE_DISABLE (_BURTC_CTRL_MODE_DISABLE << 0) /* Shifted mode DISABLE for BURTC_CTRL */ +#define BURTC_CTRL_MODE_EM2EN (_BURTC_CTRL_MODE_EM2EN << 0) /* Shifted mode EM2EN for BURTC_CTRL */ +#define BURTC_CTRL_MODE_EM3EN (_BURTC_CTRL_MODE_EM3EN << 0) /* Shifted mode EM3EN for BURTC_CTRL */ +#define BURTC_CTRL_MODE_EM4EN (_BURTC_CTRL_MODE_EM4EN << 0) /* Shifted mode EM4EN for BURTC_CTRL */ +#define BURTC_CTRL_DEBUGRUN (0x1UL << 2) /* Debug Mode Run Enable */ +#define _BURTC_CTRL_DEBUGRUN_SHIFT 2 /* Shift value for BURTC_DEBUGRUN */ +#define _BURTC_CTRL_DEBUGRUN_MASK 0x4UL /* Bit mask for BURTC_DEBUGRUN */ +#define _BURTC_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_DEBUGRUN_DEFAULT (_BURTC_CTRL_DEBUGRUN_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_RSTEN (0x1UL << 3) /* Enable BURTC reset */ +#define _BURTC_CTRL_RSTEN_SHIFT 3 /* Shift value for BURTC_RSTEN */ +#define _BURTC_CTRL_RSTEN_MASK 0x8UL /* Bit mask for BURTC_RSTEN */ +#define _BURTC_CTRL_RSTEN_DEFAULT 0x00000001UL /* Mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_RSTEN_DEFAULT (_BURTC_CTRL_RSTEN_DEFAULT << 3) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_COMP0TOP (0x1UL << 4) /* Compare clear enable */ +#define _BURTC_CTRL_COMP0TOP_SHIFT 4 /* Shift value for BURTC_COMP0TOP */ +#define _BURTC_CTRL_COMP0TOP_MASK 0x10UL /* Bit mask for BURTC_COMP0TOP */ +#define _BURTC_CTRL_COMP0TOP_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_COMP0TOP_DEFAULT (_BURTC_CTRL_COMP0TOP_DEFAULT << 4) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_SHIFT 5 /* Shift value for BURTC_LPCOMP */ +#define _BURTC_CTRL_LPCOMP_MASK 0xE0UL /* Bit mask for BURTC_LPCOMP */ +#define _BURTC_CTRL_LPCOMP_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN0LSB 0x00000000UL /* Mode IGN0LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN1LSB 0x00000001UL /* Mode IGN1LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN2LSB 0x00000002UL /* Mode IGN2LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN3LSB 0x00000003UL /* Mode IGN3LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN4LSB 0x00000004UL /* Mode IGN4LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN5LSB 0x00000005UL /* Mode IGN5LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN6LSB 0x00000006UL /* Mode IGN6LSB for BURTC_CTRL */ +#define _BURTC_CTRL_LPCOMP_IGN7LSB 0x00000007UL /* Mode IGN7LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_DEFAULT (_BURTC_CTRL_LPCOMP_DEFAULT << 5) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN0LSB (_BURTC_CTRL_LPCOMP_IGN0LSB << 5) /* Shifted mode IGN0LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN1LSB (_BURTC_CTRL_LPCOMP_IGN1LSB << 5) /* Shifted mode IGN1LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN2LSB (_BURTC_CTRL_LPCOMP_IGN2LSB << 5) /* Shifted mode IGN2LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN3LSB (_BURTC_CTRL_LPCOMP_IGN3LSB << 5) /* Shifted mode IGN3LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN4LSB (_BURTC_CTRL_LPCOMP_IGN4LSB << 5) /* Shifted mode IGN4LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN5LSB (_BURTC_CTRL_LPCOMP_IGN5LSB << 5) /* Shifted mode IGN5LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN6LSB (_BURTC_CTRL_LPCOMP_IGN6LSB << 5) /* Shifted mode IGN6LSB for BURTC_CTRL */ +#define BURTC_CTRL_LPCOMP_IGN7LSB (_BURTC_CTRL_LPCOMP_IGN7LSB << 5) /* Shifted mode IGN7LSB for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_SHIFT 8 /* Shift value for BURTC_PRESC */ +#define _BURTC_CTRL_PRESC_MASK 0x700UL /* Bit mask for BURTC_PRESC */ +#define _BURTC_CTRL_PRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV1 0x00000000UL /* Mode DIV1 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV2 0x00000001UL /* Mode DIV2 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV4 0x00000002UL /* Mode DIV4 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV8 0x00000003UL /* Mode DIV8 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV16 0x00000004UL /* Mode DIV16 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV32 0x00000005UL /* Mode DIV32 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV64 0x00000006UL /* Mode DIV64 for BURTC_CTRL */ +#define _BURTC_CTRL_PRESC_DIV128 0x00000007UL /* Mode DIV128 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DEFAULT (_BURTC_CTRL_PRESC_DEFAULT << 8) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV1 (_BURTC_CTRL_PRESC_DIV1 << 8) /* Shifted mode DIV1 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV2 (_BURTC_CTRL_PRESC_DIV2 << 8) /* Shifted mode DIV2 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV4 (_BURTC_CTRL_PRESC_DIV4 << 8) /* Shifted mode DIV4 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV8 (_BURTC_CTRL_PRESC_DIV8 << 8) /* Shifted mode DIV8 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV16 (_BURTC_CTRL_PRESC_DIV16 << 8) /* Shifted mode DIV16 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV32 (_BURTC_CTRL_PRESC_DIV32 << 8) /* Shifted mode DIV32 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV64 (_BURTC_CTRL_PRESC_DIV64 << 8) /* Shifted mode DIV64 for BURTC_CTRL */ +#define BURTC_CTRL_PRESC_DIV128 (_BURTC_CTRL_PRESC_DIV128 << 8) /* Shifted mode DIV128 for BURTC_CTRL */ +#define _BURTC_CTRL_CLKSEL_SHIFT 12 /* Shift value for BURTC_CLKSEL */ +#define _BURTC_CTRL_CLKSEL_MASK 0x3000UL /* Bit mask for BURTC_CLKSEL */ +#define _BURTC_CTRL_CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define _BURTC_CTRL_CLKSEL_NONE 0x00000000UL /* Mode NONE for BURTC_CTRL */ +#define _BURTC_CTRL_CLKSEL_LFRCO 0x00000001UL /* Mode LFRCO for BURTC_CTRL */ +#define _BURTC_CTRL_CLKSEL_LFXO 0x00000002UL /* Mode LFXO for BURTC_CTRL */ +#define _BURTC_CTRL_CLKSEL_ULFRCO 0x00000003UL /* Mode ULFRCO for BURTC_CTRL */ +#define BURTC_CTRL_CLKSEL_DEFAULT (_BURTC_CTRL_CLKSEL_DEFAULT << 12) /* Shifted mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_CLKSEL_NONE (_BURTC_CTRL_CLKSEL_NONE << 12) /* Shifted mode NONE for BURTC_CTRL */ +#define BURTC_CTRL_CLKSEL_LFRCO (_BURTC_CTRL_CLKSEL_LFRCO << 12) /* Shifted mode LFRCO for BURTC_CTRL */ +#define BURTC_CTRL_CLKSEL_LFXO (_BURTC_CTRL_CLKSEL_LFXO << 12) /* Shifted mode LFXO for BURTC_CTRL */ +#define BURTC_CTRL_CLKSEL_ULFRCO (_BURTC_CTRL_CLKSEL_ULFRCO << 12) /* Shifted mode ULFRCO for BURTC_CTRL */ +#define BURTC_CTRL_BUMODETSEN (0x1UL << 14) /* Backup mode timestamp enable */ +#define _BURTC_CTRL_BUMODETSEN_SHIFT 14 /* Shift value for BURTC_BUMODETSEN */ +#define _BURTC_CTRL_BUMODETSEN_MASK 0x4000UL /* Bit mask for BURTC_BUMODETSEN */ +#define _BURTC_CTRL_BUMODETSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CTRL */ +#define BURTC_CTRL_BUMODETSEN_DEFAULT (_BURTC_CTRL_BUMODETSEN_DEFAULT << 14) /* Shifted mode DEFAULT for BURTC_CTRL */ + +/* Bit fields for BURTC LPMODE */ + +#define _BURTC_LPMODE_RESETVALUE 0x00000000UL /* Default value for BURTC_LPMODE */ +#define _BURTC_LPMODE_MASK 0x00000003UL /* Mask for BURTC_LPMODE */ + +#define _BURTC_LPMODE_LPMODE_SHIFT 0 /* Shift value for BURTC_LPMODE */ +#define _BURTC_LPMODE_LPMODE_MASK 0x3UL /* Bit mask for BURTC_LPMODE */ +#define _BURTC_LPMODE_LPMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_LPMODE */ +#define _BURTC_LPMODE_LPMODE_DISABLE 0x00000000UL /* Mode DISABLE for BURTC_LPMODE */ +#define _BURTC_LPMODE_LPMODE_ENABLE 0x00000001UL /* Mode ENABLE for BURTC_LPMODE */ +#define _BURTC_LPMODE_LPMODE_BUEN 0x00000002UL /* Mode BUEN for BURTC_LPMODE */ +#define BURTC_LPMODE_LPMODE_DEFAULT (_BURTC_LPMODE_LPMODE_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_LPMODE */ +#define BURTC_LPMODE_LPMODE_DISABLE (_BURTC_LPMODE_LPMODE_DISABLE << 0) /* Shifted mode DISABLE for BURTC_LPMODE */ +#define BURTC_LPMODE_LPMODE_ENABLE (_BURTC_LPMODE_LPMODE_ENABLE << 0) /* Shifted mode ENABLE for BURTC_LPMODE */ +#define BURTC_LPMODE_LPMODE_BUEN (_BURTC_LPMODE_LPMODE_BUEN << 0) /* Shifted mode BUEN for BURTC_LPMODE */ + +/* Bit fields for BURTC CNT */ + +#define _BURTC_CNT_RESETVALUE 0x00000000UL /* Default value for BURTC_CNT */ +#define _BURTC_CNT_MASK 0xFFFFFFFFUL /* Mask for BURTC_CNT */ + +#define _BURTC_CNT_CNT_SHIFT 0 /* Shift value for BURTC_CNT */ +#define _BURTC_CNT_CNT_MASK 0xFFFFFFFFUL /* Bit mask for BURTC_CNT */ +#define _BURTC_CNT_CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CNT */ +#define BURTC_CNT_CNT_DEFAULT (_BURTC_CNT_CNT_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_CNT */ + +/* Bit fields for BURTC COMP0 */ + +#define _BURTC_COMP0_RESETVALUE 0x00000000UL /* Default value for BURTC_COMP0 */ +#define _BURTC_COMP0_MASK 0xFFFFFFFFUL /* Mask for BURTC_COMP0 */ + +#define _BURTC_COMP0_COMP0_SHIFT 0 /* Shift value for BURTC_COMP0 */ +#define _BURTC_COMP0_COMP0_MASK 0xFFFFFFFFUL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_COMP0_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_COMP0 */ +#define BURTC_COMP0_COMP0_DEFAULT (_BURTC_COMP0_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_COMP0 */ + +/* Bit fields for BURTC TIMESTAMP */ + +#define _BURTC_TIMESTAMP_RESETVALUE 0x00000000UL /* Default value for BURTC_TIMESTAMP */ +#define _BURTC_TIMESTAMP_MASK 0xFFFFFFFFUL /* Mask for BURTC_TIMESTAMP */ + +#define _BURTC_TIMESTAMP_TIMESTAMP_SHIFT 0 /* Shift value for BURTC_TIMESTAMP */ +#define _BURTC_TIMESTAMP_TIMESTAMP_MASK 0xFFFFFFFFUL /* Bit mask for BURTC_TIMESTAMP */ +#define _BURTC_TIMESTAMP_TIMESTAMP_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_TIMESTAMP */ +#define BURTC_TIMESTAMP_TIMESTAMP_DEFAULT (_BURTC_TIMESTAMP_TIMESTAMP_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_TIMESTAMP */ + +/* Bit fields for BURTC LFXOFDET */ + +#define _BURTC_LFXOFDET_RESETVALUE 0x00000000UL /* Default value for BURTC_LFXOFDET */ +#define _BURTC_LFXOFDET_MASK 0x000001F3UL /* Mask for BURTC_LFXOFDET */ + +#define _BURTC_LFXOFDET_OSC_SHIFT 0 /* Shift value for BURTC_OSC */ +#define _BURTC_LFXOFDET_OSC_MASK 0x3UL /* Bit mask for BURTC_OSC */ +#define _BURTC_LFXOFDET_OSC_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_LFXOFDET */ +#define _BURTC_LFXOFDET_OSC_DISABLE 0x00000000UL /* Mode DISABLE for BURTC_LFXOFDET */ +#define _BURTC_LFXOFDET_OSC_LFRCO 0x00000001UL /* Mode LFRCO for BURTC_LFXOFDET */ +#define _BURTC_LFXOFDET_OSC_ULFRCO 0x00000002UL /* Mode ULFRCO for BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_OSC_DEFAULT (_BURTC_LFXOFDET_OSC_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_OSC_DISABLE (_BURTC_LFXOFDET_OSC_DISABLE << 0) /* Shifted mode DISABLE for BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_OSC_LFRCO (_BURTC_LFXOFDET_OSC_LFRCO << 0) /* Shifted mode LFRCO for BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_OSC_ULFRCO (_BURTC_LFXOFDET_OSC_ULFRCO << 0) /* Shifted mode ULFRCO for BURTC_LFXOFDET */ +#define _BURTC_LFXOFDET_TOP_SHIFT 4 /* Shift value for BURTC_TOP */ +#define _BURTC_LFXOFDET_TOP_MASK 0x1F0UL /* Bit mask for BURTC_TOP */ +#define _BURTC_LFXOFDET_TOP_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_TOP_DEFAULT (_BURTC_LFXOFDET_TOP_DEFAULT << 4) /* Shifted mode DEFAULT for BURTC_LFXOFDET */ + +/* Bit fields for BURTC STATUS */ + +#define _BURTC_STATUS_RESETVALUE 0x00000000UL /* Default value for BURTC_STATUS */ +#define _BURTC_STATUS_MASK 0x00000007UL /* Mask for BURTC_STATUS */ + +#define BURTC_STATUS_LPMODEACT (0x1UL << 0) /* Low power mode active */ +#define _BURTC_STATUS_LPMODEACT_SHIFT 0 /* Shift value for BURTC_LPMODEACT */ +#define _BURTC_STATUS_LPMODEACT_MASK 0x1UL /* Bit mask for BURTC_LPMODEACT */ +#define _BURTC_STATUS_LPMODEACT_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_STATUS */ +#define BURTC_STATUS_LPMODEACT_DEFAULT (_BURTC_STATUS_LPMODEACT_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_STATUS */ +#define BURTC_STATUS_BUMODETS (0x1UL << 1) /* Timestamp for backup mode entry stored. */ +#define _BURTC_STATUS_BUMODETS_SHIFT 1 /* Shift value for BURTC_BUMODETS */ +#define _BURTC_STATUS_BUMODETS_MASK 0x2UL /* Bit mask for BURTC_BUMODETS */ +#define _BURTC_STATUS_BUMODETS_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_STATUS */ +#define BURTC_STATUS_BUMODETS_DEFAULT (_BURTC_STATUS_BUMODETS_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_STATUS */ +#define BURTC_STATUS_RAMWERR (0x1UL << 2) /* RAM write error. */ +#define _BURTC_STATUS_RAMWERR_SHIFT 2 /* Shift value for BURTC_RAMWERR */ +#define _BURTC_STATUS_RAMWERR_MASK 0x4UL /* Bit mask for BURTC_RAMWERR */ +#define _BURTC_STATUS_RAMWERR_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_STATUS */ +#define BURTC_STATUS_RAMWERR_DEFAULT (_BURTC_STATUS_RAMWERR_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_STATUS */ + +/* Bit fields for BURTC CMD */ + +#define _BURTC_CMD_RESETVALUE 0x00000000UL /* Default value for BURTC_CMD */ +#define _BURTC_CMD_MASK 0x00000001UL /* Mask for BURTC_CMD */ + +#define BURTC_CMD_CLRSTATUS (0x1UL << 0) /* Clear BURTC_STATUS register. */ +#define _BURTC_CMD_CLRSTATUS_SHIFT 0 /* Shift value for BURTC_CLRSTATUS */ +#define _BURTC_CMD_CLRSTATUS_MASK 0x1UL /* Bit mask for BURTC_CLRSTATUS */ +#define _BURTC_CMD_CLRSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_CMD */ +#define BURTC_CMD_CLRSTATUS_DEFAULT (_BURTC_CMD_CLRSTATUS_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_CMD */ + +/* Bit fields for BURTC POWERDOWN */ + +#define _BURTC_POWERDOWN_RESETVALUE 0x00000000UL /* Default value for BURTC_POWERDOWN */ +#define _BURTC_POWERDOWN_MASK 0x00000001UL /* Mask for BURTC_POWERDOWN */ + +#define BURTC_POWERDOWN_RAM (0x1UL << 0) /* Retention RAM power-down */ +#define _BURTC_POWERDOWN_RAM_SHIFT 0 /* Shift value for BURTC_RAM */ +#define _BURTC_POWERDOWN_RAM_MASK 0x1UL /* Bit mask for BURTC_RAM */ +#define _BURTC_POWERDOWN_RAM_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_POWERDOWN */ +#define BURTC_POWERDOWN_RAM_DEFAULT (_BURTC_POWERDOWN_RAM_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_POWERDOWN */ + +/* Bit fields for BURTC LOCK */ + +#define _BURTC_LOCK_RESETVALUE 0x00000000UL /* Default value for BURTC_LOCK */ +#define _BURTC_LOCK_MASK 0x0000FFFFUL /* Mask for BURTC_LOCK */ + +#define _BURTC_LOCK_LOCKKEY_SHIFT 0 /* Shift value for BURTC_LOCKKEY */ +#define _BURTC_LOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for BURTC_LOCKKEY */ +#define _BURTC_LOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_LOCK */ +#define _BURTC_LOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for BURTC_LOCK */ +#define _BURTC_LOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for BURTC_LOCK */ +#define _BURTC_LOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for BURTC_LOCK */ +#define _BURTC_LOCK_LOCKKEY_UNLOCK 0x0000AEE8UL /* Mode UNLOCK for BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_DEFAULT (_BURTC_LOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_LOCK (_BURTC_LOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_UNLOCKED (_BURTC_LOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_LOCKED (_BURTC_LOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_UNLOCK (_BURTC_LOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for BURTC_LOCK */ + +/* Bit fields for BURTC IF */ + +#define _BURTC_IF_RESETVALUE 0x00000000UL /* Default value for BURTC_IF */ +#define _BURTC_IF_MASK 0x00000007UL /* Mask for BURTC_IF */ + +#define BURTC_IF_OF (0x1UL << 0) /* Overflow Interrupt Flag */ +#define _BURTC_IF_OF_SHIFT 0 /* Shift value for BURTC_OF */ +#define _BURTC_IF_OF_MASK 0x1UL /* Bit mask for BURTC_OF */ +#define _BURTC_IF_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IF */ +#define BURTC_IF_OF_DEFAULT (_BURTC_IF_OF_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_IF */ +#define BURTC_IF_COMP0 (0x1UL << 1) /* Compare match Interrupt Flag */ +#define _BURTC_IF_COMP0_SHIFT 1 /* Shift value for BURTC_COMP0 */ +#define _BURTC_IF_COMP0_MASK 0x2UL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_IF_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IF */ +#define BURTC_IF_COMP0_DEFAULT (_BURTC_IF_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_IF */ +#define BURTC_IF_LFXOFAIL (0x1UL << 2) /* LFXO failure Interrupt Flag */ +#define _BURTC_IF_LFXOFAIL_SHIFT 2 /* Shift value for BURTC_LFXOFAIL */ +#define _BURTC_IF_LFXOFAIL_MASK 0x4UL /* Bit mask for BURTC_LFXOFAIL */ +#define _BURTC_IF_LFXOFAIL_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IF */ +#define BURTC_IF_LFXOFAIL_DEFAULT (_BURTC_IF_LFXOFAIL_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_IF */ + +/* Bit fields for BURTC IFS */ + +#define _BURTC_IFS_RESETVALUE 0x00000000UL /* Default value for BURTC_IFS */ +#define _BURTC_IFS_MASK 0x00000007UL /* Mask for BURTC_IFS */ + +#define BURTC_IFS_OF (0x1UL << 0) /* Set Overflow Interrupt Flag */ +#define _BURTC_IFS_OF_SHIFT 0 /* Shift value for BURTC_OF */ +#define _BURTC_IFS_OF_MASK 0x1UL /* Bit mask for BURTC_OF */ +#define _BURTC_IFS_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFS */ +#define BURTC_IFS_OF_DEFAULT (_BURTC_IFS_OF_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_IFS */ +#define BURTC_IFS_COMP0 (0x1UL << 1) /* Set compare match Interrupt Flag */ +#define _BURTC_IFS_COMP0_SHIFT 1 /* Shift value for BURTC_COMP0 */ +#define _BURTC_IFS_COMP0_MASK 0x2UL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_IFS_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFS */ +#define BURTC_IFS_COMP0_DEFAULT (_BURTC_IFS_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_IFS */ +#define BURTC_IFS_LFXOFAIL (0x1UL << 2) /* Set LFXO fail Interrupt Flag */ +#define _BURTC_IFS_LFXOFAIL_SHIFT 2 /* Shift value for BURTC_LFXOFAIL */ +#define _BURTC_IFS_LFXOFAIL_MASK 0x4UL /* Bit mask for BURTC_LFXOFAIL */ +#define _BURTC_IFS_LFXOFAIL_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFS */ +#define BURTC_IFS_LFXOFAIL_DEFAULT (_BURTC_IFS_LFXOFAIL_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_IFS */ + +/* Bit fields for BURTC IFC */ + +#define _BURTC_IFC_RESETVALUE 0x00000000UL /* Default value for BURTC_IFC */ +#define _BURTC_IFC_MASK 0x00000007UL /* Mask for BURTC_IFC */ + +#define BURTC_IFC_OF (0x1UL << 0) /* Clear Overflow Interrupt Flag */ +#define _BURTC_IFC_OF_SHIFT 0 /* Shift value for BURTC_OF */ +#define _BURTC_IFC_OF_MASK 0x1UL /* Bit mask for BURTC_OF */ +#define _BURTC_IFC_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFC */ +#define BURTC_IFC_OF_DEFAULT (_BURTC_IFC_OF_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_IFC */ +#define BURTC_IFC_COMP0 (0x1UL << 1) /* Clear compare match Interrupt Flag */ +#define _BURTC_IFC_COMP0_SHIFT 1 /* Shift value for BURTC_COMP0 */ +#define _BURTC_IFC_COMP0_MASK 0x2UL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_IFC_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFC */ +#define BURTC_IFC_COMP0_DEFAULT (_BURTC_IFC_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_IFC */ +#define BURTC_IFC_LFXOFAIL (0x1UL << 2) /* Clear LFXO failure Interrupt Flag */ +#define _BURTC_IFC_LFXOFAIL_SHIFT 2 /* Shift value for BURTC_LFXOFAIL */ +#define _BURTC_IFC_LFXOFAIL_MASK 0x4UL /* Bit mask for BURTC_LFXOFAIL */ +#define _BURTC_IFC_LFXOFAIL_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IFC */ +#define BURTC_IFC_LFXOFAIL_DEFAULT (_BURTC_IFC_LFXOFAIL_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_IFC */ + +/* Bit fields for BURTC IEN */ + +#define _BURTC_IEN_RESETVALUE 0x00000000UL /* Default value for BURTC_IEN */ +#define _BURTC_IEN_MASK 0x00000007UL /* Mask for BURTC_IEN */ + +#define BURTC_IEN_OF (0x1UL << 0) /* Overflow Interrupt Enable */ +#define _BURTC_IEN_OF_SHIFT 0 /* Shift value for BURTC_OF */ +#define _BURTC_IEN_OF_MASK 0x1UL /* Bit mask for BURTC_OF */ +#define _BURTC_IEN_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IEN */ +#define BURTC_IEN_OF_DEFAULT (_BURTC_IEN_OF_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_IEN */ +#define BURTC_IEN_COMP0 (0x1UL << 1) /* Compare match Interrupt Enable */ +#define _BURTC_IEN_COMP0_SHIFT 1 /* Shift value for BURTC_COMP0 */ +#define _BURTC_IEN_COMP0_MASK 0x2UL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_IEN_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IEN */ +#define BURTC_IEN_COMP0_DEFAULT (_BURTC_IEN_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_IEN */ +#define BURTC_IEN_LFXOFAIL (0x1UL << 2) /* LFXO failure Interrupt Enable */ +#define _BURTC_IEN_LFXOFAIL_SHIFT 2 /* Shift value for BURTC_LFXOFAIL */ +#define _BURTC_IEN_LFXOFAIL_MASK 0x4UL /* Bit mask for BURTC_LFXOFAIL */ +#define _BURTC_IEN_LFXOFAIL_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_IEN */ +#define BURTC_IEN_LFXOFAIL_DEFAULT (_BURTC_IEN_LFXOFAIL_DEFAULT << 2) /* Shifted mode DEFAULT for BURTC_IEN */ + +/* Bit fields for BURTC FREEZE */ + +#define _BURTC_FREEZE_RESETVALUE 0x00000000UL /* Default value for BURTC_FREEZE */ +#define _BURTC_FREEZE_MASK 0x00000001UL /* Mask for BURTC_FREEZE */ + +#define BURTC_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _BURTC_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for BURTC_REGFREEZE */ +#define _BURTC_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for BURTC_REGFREEZE */ +#define _BURTC_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_FREEZE */ +#define _BURTC_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for BURTC_FREEZE */ +#define _BURTC_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for BURTC_FREEZE */ +#define BURTC_FREEZE_REGFREEZE_DEFAULT (_BURTC_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_FREEZE */ +#define BURTC_FREEZE_REGFREEZE_UPDATE (_BURTC_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for BURTC_FREEZE */ +#define BURTC_FREEZE_REGFREEZE_FREEZE (_BURTC_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for BURTC_FREEZE */ + +/* Bit fields for BURTC SYNCBUSY */ + +#define _BURTC_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for BURTC_SYNCBUSY */ +#define _BURTC_SYNCBUSY_MASK 0x00000003UL /* Mask for BURTC_SYNCBUSY */ + +#define BURTC_SYNCBUSY_LPMODE (0x1UL << 0) /* LPMODE Register Busy */ +#define _BURTC_SYNCBUSY_LPMODE_SHIFT 0 /* Shift value for BURTC_LPMODE */ +#define _BURTC_SYNCBUSY_LPMODE_MASK 0x1UL /* Bit mask for BURTC_LPMODE */ +#define _BURTC_SYNCBUSY_LPMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_SYNCBUSY */ +#define BURTC_SYNCBUSY_LPMODE_DEFAULT (_BURTC_SYNCBUSY_LPMODE_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_SYNCBUSY */ +#define BURTC_SYNCBUSY_COMP0 (0x1UL << 1) /* COMP0 Register Busy */ +#define _BURTC_SYNCBUSY_COMP0_SHIFT 1 /* Shift value for BURTC_COMP0 */ +#define _BURTC_SYNCBUSY_COMP0_MASK 0x2UL /* Bit mask for BURTC_COMP0 */ +#define _BURTC_SYNCBUSY_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_SYNCBUSY */ +#define BURTC_SYNCBUSY_COMP0_DEFAULT (_BURTC_SYNCBUSY_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for BURTC_SYNCBUSY */ + +/* Bit fields for BURTC RET_REG */ + +#define _BURTC_RET_REG_RESETVALUE 0x00000000UL /* Default value for BURTC_RET_REG */ +#define _BURTC_RET_REG_MASK 0xFFFFFFFFUL /* Mask for BURTC_RET_REG */ + +#define _BURTC_RET_REG_REG_SHIFT 0 /* Shift value for REG */ +#define _BURTC_RET_REG_REG_MASK 0xFFFFFFFFUL /* Bit mask for REG */ +#define _BURTC_RET_REG_REG_DEFAULT 0x00000000UL /* Mode DEFAULT for BURTC_RET_REG */ +#define BURTC_RET_REG_REG_DEFAULT (_BURTC_RET_REG_REG_DEFAULT << 0) /* Shifted mode DEFAULT for BURTC_RET_REG */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_BURTC_H */ diff --git a/arch/arm/src/efm32/chip/efm32_calibrate.h b/arch/arm/src/efm32/chip/efm32_calibrate.h new file mode 100644 index 0000000000000000000000000000000000000000..7fb84d1e3105bb047125f27305dd950d4b85e243 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_calibrate.h @@ -0,0 +1,93 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_calibrate.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CALIBRATE_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CALIBRATE_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +#define CALIBRATE_MAX_REGISTERS 50 /* Max number of address/value pairs for calibration */ + +#define CALIBRATE ((const struct efm32_calibrate_s *)EFM32_CALIBRATE_BASE) + +/******************************************************************************************************************************* + * Public Type Definitions + *******************************************************************************************************************************/ + +struct efm32_calibrate_s +{ + const uint32_t address; /* Address of calibration register */ + const uint32_t value; /* Default value for calibration register */ +}; + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CALIBRATE_H */ diff --git a/arch/arm/src/efm32/chip/efm32_cmu.h b/arch/arm/src/efm32/chip/efm32_cmu.h new file mode 100644 index 0000000000000000000000000000000000000000..ffefddd6939fe2e8ed9ba435221620ddbeda3243 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_cmu.h @@ -0,0 +1,1653 @@ +/******************************************************************************************************************************** + * arch/arm/src/efm32/chip/efm32_cmu.h + * + * (C) Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CMU_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CMU_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) && !defined(CONFIG_EFM32_EFM32G) +# warning This is the EFM32GG/G header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* Maximum allowed core frequency when using 0 wait states on flash access */ + +#define CMU_MAX_FREQ_0WS 16000000 + +/* Maximum allowed core frequency when using 1 wait states on flash access */ + +#define CMU_MAX_FREQ_1WS 32000000 + +/* Maximum allowed core frequency when using 1 wait states on flash access */ + +#define CMU_MAX_FREQ_2WS 48000000 + +/* Maximum frequency that HFLE needs to be enabled on Giant, Leopard and Wonder parts. */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_MAX_FREQ_HFLE 32000000 +#endif + +/* CMU Register Offsets ********************************************************************************************************/ + +#define EFM32_CMU_CTRL_OFFSET 0x0000 /* CMU Control Register */ +#define EFM32_CMU_HFCORECLKDIV_OFFSET 0x0004 /* High Frequency Core Clock Division Register */ +#define EFM32_CMU_HFPERCLKDIV_OFFSET 0x0008 /* High Frequency Peripheral Clock Division Register */ +#define EFM32_CMU_HFRCOCTRL_OFFSET 0x000c /* HFRCO Control Register */ +#define EFM32_CMU_LFRCOCTRL_OFFSET 0x0010 /* LFRCO Control Register */ +#define EFM32_CMU_AUXHFRCOCTRL_OFFSET 0x0014 /* AUXHFRCO Control Register */ +#define EFM32_CMU_CALCTRL_OFFSET 0x0018 /* Calibration Control Register */ +#define EFM32_CMU_CALCNT_OFFSET 0x001c /* Calibration Counter Register */ +#define EFM32_CMU_OSCENCMD_OFFSET 0x0020 /* Oscillator Enable/Disable Command Register */ +#define EFM32_CMU_CMD_OFFSET 0x0024 /* Command Register */ +#define EFM32_CMU_LFCLKSEL_OFFSET 0x0028 /* Low Frequency Clock Select Register */ +#define EFM32_CMU_STATUS_OFFSET 0x002c /* Status Register */ +#define EFM32_CMU_IF_OFFSET 0x0030 /* Interrupt Flag Register */ +#define EFM32_CMU_IFS_OFFSET 0x0034 /* Interrupt Flag Set Register */ +#define EFM32_CMU_IFC_OFFSET 0x0038 /* Interrupt Flag Clear Register */ +#define EFM32_CMU_IEN_OFFSET 0x003c /* Interrupt Enable Register */ +#define EFM32_CMU_HFCORECLKEN0_OFFSET 0x0040 /* High Frequency Core Clock Enable Register 0 */ +#define EFM32_CMU_HFPERCLKEN0_OFFSET 0x0044 /* High Frequency Peripheral Clock Enable Register 0 */ +#define EFM32_CMU_SYNCBUSY_OFFSET 0x0050 /* Synchronization Busy Register */ +#define EFM32_CMU_FREEZE_OFFSET 0x0054 /* Freeze Register */ +#define EFM32_CMU_LFACLKEN0_OFFSET 0x0058 /* Low Frequency A Clock Enable Register 0 (Async Reg) */ +#define EFM32_CMU_LFBCLKEN0_OFFSET 0x0060 /* Low Frequency B Clock Enable Register 0 (Async Reg) */ +#define EFM32_CMU_LFAPRESC0_OFFSET 0x0068 /* Low Frequency A Prescaler Register 0 (Async Reg) */ +#define EFM32_CMU_LFBPRESC0_OFFSET 0x0070 /* Low Frequency B Prescaler Register 0 (Async Reg) */ +#define EFM32_CMU_PCNTCTRL_OFFSET 0x0078 /* PCNT Control Register */ +#define EFM32_CMU_LCDCTRL_OFFSET 0x007c /* LCD Control Register */ +#define EFM32_CMU_ROUTE_OFFSET 0x0080 /* I/O Routing Register */ +#define EFM32_CMU_LOCK_OFFSET 0x0084 /* Configuration Lock Register */ + +/* CMU Register Addresses ******************************************************************************************************/ + +#define EFM32_CMU_CTRL (EFM32_CMU_BASE+EFM32_CMU_CTRL_OFFSET) +#define EFM32_CMU_HFCORECLKDIV (EFM32_CMU_BASE+EFM32_CMU_HFCORECLKDIV_OFFSET) +#define EFM32_CMU_HFPERCLKDIV (EFM32_CMU_BASE+EFM32_CMU_HFPERCLKDIV_OFFSET) +#define EFM32_CMU_HFRCOCTRL (EFM32_CMU_BASE+EFM32_CMU_HFRCOCTRL_OFFSET) +#define EFM32_CMU_LFRCOCTRL (EFM32_CMU_BASE+EFM32_CMU_LFRCOCTRL_OFFSET) +#define EFM32_CMU_AUXHFRCOCTRL (EFM32_CMU_BASE+EFM32_CMU_AUXHFRCOCTRL_OFFSET) +#define EFM32_CMU_CALCTRL (EFM32_CMU_BASE+EFM32_CMU_CALCTRL_OFFSET) +#define EFM32_CMU_CALCNT (EFM32_CMU_BASE+EFM32_CMU_CALCNT_OFFSET) +#define EFM32_CMU_OSCENCMD (EFM32_CMU_BASE+EFM32_CMU_OSCENCMD_OFFSET) +#define EFM32_CMU_CMD (EFM32_CMU_BASE+EFM32_CMU_CMD_OFFSET) +#define EFM32_CMU_LFCLKSEL (EFM32_CMU_BASE+EFM32_CMU_LFCLKSEL_OFFSET) +#define EFM32_CMU_STATUS (EFM32_CMU_BASE+EFM32_CMU_STATUS_OFFSET) +#define EFM32_CMU_IF (EFM32_CMU_BASE+EFM32_CMU_IF_OFFSET) +#define EFM32_CMU_IFS (EFM32_CMU_BASE+EFM32_CMU_IFS_OFFSET) +#define EFM32_CMU_IFC (EFM32_CMU_BASE+EFM32_CMU_IFC_OFFSET) +#define EFM32_CMU_IEN (EFM32_CMU_BASE+EFM32_CMU_IEN_OFFSET) +#define EFM32_CMU_HFCORECLKEN0 (EFM32_CMU_BASE+EFM32_CMU_HFCORECLKEN0_OFFSET) +#define EFM32_CMU_HFPERCLKEN0 (EFM32_CMU_BASE+EFM32_CMU_HFPERCLKEN0_OFFSET) +#define EFM32_CMU_SYNCBUSY (EFM32_CMU_BASE+EFM32_CMU_SYNCBUSY_OFFSET) +#define EFM32_CMU_FREEZE (EFM32_CMU_BASE+EFM32_CMU_FREEZE_OFFSET) +#define EFM32_CMU_LFACLKEN0 (EFM32_CMU_BASE+EFM32_CMU_LFACLKEN0_OFFSET) +#define EFM32_CMU_LFBCLKEN0 (EFM32_CMU_BASE+EFM32_CMU_LFBCLKEN0_OFFSET) +#define EFM32_CMU_LFAPRESC0 (EFM32_CMU_BASE+EFM32_CMU_LFAPRESC0_OFFSET) +#define EFM32_CMU_LFBPRESC0 (EFM32_CMU_BASE+EFM32_CMU_LFBPRESC0_OFFSET) +#define EFM32_CMU_PCNTCTRL (EFM32_CMU_BASE+EFM32_CMU_PCNTCTRL_OFFSET) +#define EFM32_CMU_LCDCTRL (EFM32_CMU_BASE+EFM32_CMU_LCDCTRL_OFFSET) +#define EFM32_CMU_ROUTE (EFM32_CMU_BASE+EFM32_CMU_ROUTE_OFFSET) +#define EFM32_CMU_LOCK (EFM32_CMU_BASE+EFM32_CMU_LOCK_OFFSET) + +/* CMU Register Bit Definitions ************************************************************************************************/ + +/* Bit fields for CMU CTRL */ + +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_CTRL_RESETVALUE 0x000C262CUL /* Default value for CMU_CTRL */ +# define _CMU_CTRL_MASK 0x13FE3EEFUL /* Mask for CMU_CTRL */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_CTRL_RESETVALUE 0x000C062CUL /* Default value for CMU_CTRL */ +# define _CMU_CTRL_MASK 0x53FFFEEFUL /* Mask for CMU_CTRL */ +#endif + +#define _CMU_CTRL_HFXOMODE_SHIFT 0 /* Shift value for CMU_HFXOMODE */ +#define _CMU_CTRL_HFXOMODE_MASK 0x3UL /* Bit mask for CMU_HFXOMODE */ +#define _CMU_CTRL_HFXOMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_HFXOMODE_XTAL 0x00000000UL /* Mode XTAL for CMU_CTRL */ +#define _CMU_CTRL_HFXOMODE_BUFEXTCLK 0x00000001UL /* Mode BUFEXTCLK for CMU_CTRL */ +#define _CMU_CTRL_HFXOMODE_DIGEXTCLK 0x00000002UL /* Mode DIGEXTCLK for CMU_CTRL */ +#define CMU_CTRL_HFXOMODE_DEFAULT (_CMU_CTRL_HFXOMODE_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_HFXOMODE_XTAL (_CMU_CTRL_HFXOMODE_XTAL << 0) /* Shifted mode XTAL for CMU_CTRL */ +#define CMU_CTRL_HFXOMODE_BUFEXTCLK (_CMU_CTRL_HFXOMODE_BUFEXTCLK << 0) /* Shifted mode BUFEXTCLK for CMU_CTRL */ +#define CMU_CTRL_HFXOMODE_DIGEXTCLK (_CMU_CTRL_HFXOMODE_DIGEXTCLK << 0) /* Shifted mode DIGEXTCLK for CMU_CTRL */ +#define _CMU_CTRL_HFXOBOOST_SHIFT 2 /* Shift value for CMU_HFXOBOOST */ +#define _CMU_CTRL_HFXOBOOST_MASK 0xCUL /* Bit mask for CMU_HFXOBOOST */ +#define _CMU_CTRL_HFXOBOOST_50PCENT 0x00000000UL /* Mode 50PCENT for CMU_CTRL */ +#define _CMU_CTRL_HFXOBOOST_70PCENT 0x00000001UL /* Mode 70PCENT for CMU_CTRL */ +#define _CMU_CTRL_HFXOBOOST_80PCENT 0x00000002UL /* Mode 80PCENT for CMU_CTRL */ +#define _CMU_CTRL_HFXOBOOST_DEFAULT 0x00000003UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_HFXOBOOST_100PCENT 0x00000003UL /* Mode 100PCENT for CMU_CTRL */ +#define CMU_CTRL_HFXOBOOST_50PCENT (_CMU_CTRL_HFXOBOOST_50PCENT << 2) /* Shifted mode 50PCENT for CMU_CTRL */ +#define CMU_CTRL_HFXOBOOST_70PCENT (_CMU_CTRL_HFXOBOOST_70PCENT << 2) /* Shifted mode 70PCENT for CMU_CTRL */ +#define CMU_CTRL_HFXOBOOST_80PCENT (_CMU_CTRL_HFXOBOOST_80PCENT << 2) /* Shifted mode 80PCENT for CMU_CTRL */ +#define CMU_CTRL_HFXOBOOST_DEFAULT (_CMU_CTRL_HFXOBOOST_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_HFXOBOOST_100PCENT (_CMU_CTRL_HFXOBOOST_100PCENT << 2) /* Shifted mode 100PCENT for CMU_CTRL */ +#define _CMU_CTRL_HFXOBUFCUR_SHIFT 5 /* Shift value for CMU_HFXOBUFCUR */ +#define _CMU_CTRL_HFXOBUFCUR_MASK 0x60UL /* Bit mask for CMU_HFXOBUFCUR */ +#define _CMU_CTRL_HFXOBUFCUR_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_CTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define _CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ 0x00000001UL /* Mode BOOSTUPTO32MHZ for CMU_CTRL */ +# define _CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ 0x00000003UL /* Mode BOOSTABOVE32MHZ for CMU_CTRL */ +#endif +#define CMU_CTRL_HFXOBUFCUR_DEFAULT (_CMU_CTRL_HFXOBUFCUR_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_CTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ (_CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ << 5) /* Shifted mode BOOSTUPTO32MHZ for CMU_CTRL */ +# define CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ (_CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ << 5) /* Shifted mode BOOSTABOVE32MHZ for CMU_CTRL */ +#endif +#define CMU_CTRL_HFXOGLITCHDETEN (0x1UL << 7) /* HFXO Glitch Detector Enable */ +#define _CMU_CTRL_HFXOGLITCHDETEN_SHIFT 7 /* Shift value for CMU_HFXOGLITCHDETEN */ +#define _CMU_CTRL_HFXOGLITCHDETEN_MASK 0x80UL /* Bit mask for CMU_HFXOGLITCHDETEN */ +#define _CMU_CTRL_HFXOGLITCHDETEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_HFXOGLITCHDETEN_DEFAULT (_CMU_CTRL_HFXOGLITCHDETEN_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_HFXOTIMEOUT_SHIFT 9 /* Shift value for CMU_HFXOTIMEOUT */ +#define _CMU_CTRL_HFXOTIMEOUT_MASK 0x600UL /* Bit mask for CMU_HFXOTIMEOUT */ +#define _CMU_CTRL_HFXOTIMEOUT_8CYCLES 0x00000000UL /* Mode 8CYCLES for CMU_CTRL */ +#define _CMU_CTRL_HFXOTIMEOUT_256CYCLES 0x00000001UL /* Mode 256CYCLES for CMU_CTRL */ +#define _CMU_CTRL_HFXOTIMEOUT_1KCYCLES 0x00000002UL /* Mode 1KCYCLES for CMU_CTRL */ +#define _CMU_CTRL_HFXOTIMEOUT_DEFAULT 0x00000003UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_HFXOTIMEOUT_16KCYCLES 0x00000003UL /* Mode 16KCYCLES for CMU_CTRL */ +#define CMU_CTRL_HFXOTIMEOUT_8CYCLES (_CMU_CTRL_HFXOTIMEOUT_8CYCLES << 9) /* Shifted mode 8CYCLES for CMU_CTRL */ +#define CMU_CTRL_HFXOTIMEOUT_256CYCLES (_CMU_CTRL_HFXOTIMEOUT_256CYCLES << 9) /* Shifted mode 256CYCLES for CMU_CTRL */ +#define CMU_CTRL_HFXOTIMEOUT_1KCYCLES (_CMU_CTRL_HFXOTIMEOUT_1KCYCLES << 9) /* Shifted mode 1KCYCLES for CMU_CTRL */ +#define CMU_CTRL_HFXOTIMEOUT_DEFAULT (_CMU_CTRL_HFXOTIMEOUT_DEFAULT << 9) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_HFXOTIMEOUT_16KCYCLES (_CMU_CTRL_HFXOTIMEOUT_16KCYCLES << 9) /* Shifted mode 16KCYCLES for CMU_CTRL */ +#define _CMU_CTRL_LFXOMODE_SHIFT 11 /* Shift value for CMU_LFXOMODE */ +#define _CMU_CTRL_LFXOMODE_MASK 0x1800UL /* Bit mask for CMU_LFXOMODE */ +#define _CMU_CTRL_LFXOMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_LFXOMODE_XTAL 0x00000000UL /* Mode XTAL for CMU_CTRL */ +#define _CMU_CTRL_LFXOMODE_BUFEXTCLK 0x00000001UL /* Mode BUFEXTCLK for CMU_CTRL */ +#define _CMU_CTRL_LFXOMODE_DIGEXTCLK 0x00000002UL /* Mode DIGEXTCLK for CMU_CTRL */ +#define CMU_CTRL_LFXOMODE_DEFAULT (_CMU_CTRL_LFXOMODE_DEFAULT << 11) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_LFXOMODE_XTAL (_CMU_CTRL_LFXOMODE_XTAL << 11) /* Shifted mode XTAL for CMU_CTRL */ +#define CMU_CTRL_LFXOMODE_BUFEXTCLK (_CMU_CTRL_LFXOMODE_BUFEXTCLK << 11) /* Shifted mode BUFEXTCLK for CMU_CTRL */ +#define CMU_CTRL_LFXOMODE_DIGEXTCLK (_CMU_CTRL_LFXOMODE_DIGEXTCLK << 11) /* Shifted mode DIGEXTCLK for CMU_CTRL */ +#define CMU_CTRL_LFXOBOOST (0x1UL << 13) /* LFXO Start-up Boost Current */ +#define _CMU_CTRL_LFXOBOOST_SHIFT 13 /* Shift value for CMU_LFXOBOOST */ +#define _CMU_CTRL_LFXOBOOST_MASK 0x2000UL /* Bit mask for CMU_LFXOBOOST */ +#define _CMU_CTRL_LFXOBOOST_70PCENT 0x00000000UL /* Mode 70PCENT for CMU_CTRL */ +#define _CMU_CTRL_LFXOBOOST_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_LFXOBOOST_100PCENT 0x00000001UL /* Mode 100PCENT for CMU_CTRL */ +#define CMU_CTRL_LFXOBOOST_70PCENT (_CMU_CTRL_LFXOBOOST_70PCENT << 13) /* Shifted mode 70PCENT for CMU_CTRL */ +#define CMU_CTRL_LFXOBOOST_DEFAULT (_CMU_CTRL_LFXOBOOST_DEFAULT << 13) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_LFXOBOOST_100PCENT (_CMU_CTRL_LFXOBOOST_100PCENT << 13) /* Shifted mode 100PCENT for CMU_CTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define _CMU_CTRL_HFCLKDIV_SHIFT 14 /* Shift value for CMU_HFCLKDIV */ +# define _CMU_CTRL_HFCLKDIV_MASK 0x1C000UL /* Bit mask for CMU_HFCLKDIV */ +# define _CMU_CTRL_HFCLKDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +# define CMU_CTRL_HFCLKDIV_DEFAULT (_CMU_CTRL_HFCLKDIV_DEFAULT << 14) /* Shifted mode DEFAULT for CMU_CTRL */ +#endif +#define CMU_CTRL_LFXOBUFCUR (0x1UL << 17) /* LFXO Boost Buffer Current */ +#define _CMU_CTRL_LFXOBUFCUR_SHIFT 17 /* Shift value for CMU_LFXOBUFCUR */ +#define _CMU_CTRL_LFXOBUFCUR_MASK 0x20000UL /* Bit mask for CMU_LFXOBUFCUR */ +#define _CMU_CTRL_LFXOBUFCUR_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_LFXOBUFCUR_DEFAULT (_CMU_CTRL_LFXOBUFCUR_DEFAULT << 17) /* Shifted mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_LFXOTIMEOUT_SHIFT 18 /* Shift value for CMU_LFXOTIMEOUT */ +#define _CMU_CTRL_LFXOTIMEOUT_MASK 0xC0000UL /* Bit mask for CMU_LFXOTIMEOUT */ +#define _CMU_CTRL_LFXOTIMEOUT_8CYCLES 0x00000000UL /* Mode 8CYCLES for CMU_CTRL */ +#define _CMU_CTRL_LFXOTIMEOUT_1KCYCLES 0x00000001UL /* Mode 1KCYCLES for CMU_CTRL */ +#define _CMU_CTRL_LFXOTIMEOUT_16KCYCLES 0x00000002UL /* Mode 16KCYCLES for CMU_CTRL */ +#define _CMU_CTRL_LFXOTIMEOUT_DEFAULT 0x00000003UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_LFXOTIMEOUT_32KCYCLES 0x00000003UL /* Mode 32KCYCLES for CMU_CTRL */ +#define CMU_CTRL_LFXOTIMEOUT_8CYCLES (_CMU_CTRL_LFXOTIMEOUT_8CYCLES << 18) /* Shifted mode 8CYCLES for CMU_CTRL */ +#define CMU_CTRL_LFXOTIMEOUT_1KCYCLES (_CMU_CTRL_LFXOTIMEOUT_1KCYCLES << 18) /* Shifted mode 1KCYCLES for CMU_CTRL */ +#define CMU_CTRL_LFXOTIMEOUT_16KCYCLES (_CMU_CTRL_LFXOTIMEOUT_16KCYCLES << 18) /* Shifted mode 16KCYCLES for CMU_CTRL */ +#define CMU_CTRL_LFXOTIMEOUT_DEFAULT (_CMU_CTRL_LFXOTIMEOUT_DEFAULT << 18) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_LFXOTIMEOUT_32KCYCLES (_CMU_CTRL_LFXOTIMEOUT_32KCYCLES << 18) /* Shifted mode 32KCYCLES for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_SHIFT 20 /* Shift value for CMU_CLKOUTSEL0 */ +#define _CMU_CTRL_CLKOUTSEL0_MASK 0x700000UL /* Bit mask for CMU_CLKOUTSEL0 */ +#define _CMU_CTRL_CLKOUTSEL0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFRCO 0x00000000UL /* Mode HFRCO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFXO 0x00000001UL /* Mode HFXO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFCLK2 0x00000002UL /* Mode HFCLK2 for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFCLK4 0x00000003UL /* Mode HFCLK4 for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFCLK8 0x00000004UL /* Mode HFCLK8 for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_HFCLK16 0x00000005UL /* Mode HFCLK16 for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_ULFRCO 0x00000006UL /* Mode ULFRCO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL0_AUXHFRCO 0x00000007UL /* Mode AUXHFRCO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_DEFAULT (_CMU_CTRL_CLKOUTSEL0_DEFAULT << 20) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFRCO (_CMU_CTRL_CLKOUTSEL0_HFRCO << 20) /* Shifted mode HFRCO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFXO (_CMU_CTRL_CLKOUTSEL0_HFXO << 20) /* Shifted mode HFXO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFCLK2 (_CMU_CTRL_CLKOUTSEL0_HFCLK2 << 20) /* Shifted mode HFCLK2 for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFCLK4 (_CMU_CTRL_CLKOUTSEL0_HFCLK4 << 20) /* Shifted mode HFCLK4 for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFCLK8 (_CMU_CTRL_CLKOUTSEL0_HFCLK8 << 20) /* Shifted mode HFCLK8 for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_HFCLK16 (_CMU_CTRL_CLKOUTSEL0_HFCLK16 << 20) /* Shifted mode HFCLK16 for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_ULFRCO (_CMU_CTRL_CLKOUTSEL0_ULFRCO << 20) /* Shifted mode ULFRCO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL0_AUXHFRCO (_CMU_CTRL_CLKOUTSEL0_AUXHFRCO << 20) /* Shifted mode AUXHFRCO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_SHIFT 23 /* Shift value for CMU_CLKOUTSEL1 */ +#define _CMU_CTRL_CLKOUTSEL1_MASK 0x3800000UL /* Bit mask for CMU_CLKOUTSEL1 */ +#define _CMU_CTRL_CLKOUTSEL1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_LFRCO 0x00000000UL /* Mode LFRCO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_LFXO 0x00000001UL /* Mode LFXO for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_HFCLK 0x00000002UL /* Mode HFCLK for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_LFXOQ 0x00000003UL /* Mode LFXOQ for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_HFXOQ 0x00000004UL /* Mode HFXOQ for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_LFRCOQ 0x00000005UL /* Mode LFRCOQ for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_HFRCOQ 0x00000006UL /* Mode HFRCOQ for CMU_CTRL */ +#define _CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ 0x00000007UL /* Mode AUXHFRCOQ for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_DEFAULT (_CMU_CTRL_CLKOUTSEL1_DEFAULT << 23) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_LFRCO (_CMU_CTRL_CLKOUTSEL1_LFRCO << 23) /* Shifted mode LFRCO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_LFXO (_CMU_CTRL_CLKOUTSEL1_LFXO << 23) /* Shifted mode LFXO for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_HFCLK (_CMU_CTRL_CLKOUTSEL1_HFCLK << 23) /* Shifted mode HFCLK for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_LFXOQ (_CMU_CTRL_CLKOUTSEL1_LFXOQ << 23) /* Shifted mode LFXOQ for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_HFXOQ (_CMU_CTRL_CLKOUTSEL1_HFXOQ << 23) /* Shifted mode HFXOQ for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_LFRCOQ (_CMU_CTRL_CLKOUTSEL1_LFRCOQ << 23) /* Shifted mode LFRCOQ for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_HFRCOQ (_CMU_CTRL_CLKOUTSEL1_HFRCOQ << 23) /* Shifted mode HFRCOQ for CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ (_CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ << 23) /* Shifted mode AUXHFRCOQ for CMU_CTRL */ +#define CMU_CTRL_DBGCLK (0x1UL << 28) /* Debug Clock */ +#define _CMU_CTRL_DBGCLK_SHIFT 28 /* Shift value for CMU_DBGCLK */ +#define _CMU_CTRL_DBGCLK_MASK 0x10000000UL /* Bit mask for CMU_DBGCLK */ +#define _CMU_CTRL_DBGCLK_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +#define _CMU_CTRL_DBGCLK_AUXHFRCO 0x00000000UL /* Mode AUXHFRCO for CMU_CTRL */ +#define _CMU_CTRL_DBGCLK_HFCLK 0x00000001UL /* Mode HFCLK for CMU_CTRL */ +#define CMU_CTRL_DBGCLK_DEFAULT (_CMU_CTRL_DBGCLK_DEFAULT << 28) /* Shifted mode DEFAULT for CMU_CTRL */ +#define CMU_CTRL_DBGCLK_AUXHFRCO (_CMU_CTRL_DBGCLK_AUXHFRCO << 28) /* Shifted mode AUXHFRCO for CMU_CTRL */ +#define CMU_CTRL_DBGCLK_HFCLK (_CMU_CTRL_DBGCLK_HFCLK << 28) /* Shifted mode HFCLK for CMU_CTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_CTRL_HFLE (0x1UL << 30) /* High-Frequency LE Interface */ +# define _CMU_CTRL_HFLE_SHIFT 30 /* Shift value for CMU_HFLE */ +# define _CMU_CTRL_HFLE_MASK 0x40000000UL /* Bit mask for CMU_HFLE */ +# define _CMU_CTRL_HFLE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CTRL */ +# define CMU_CTRL_HFLE_DEFAULT (_CMU_CTRL_HFLE_DEFAULT << 30) /* Shifted mode DEFAULT for CMU_CTRL */ +#endif + +/* Bit fields for CMU HFCORECLKDIV */ + +#define _CMU_HFCORECLKDIV_RESETVALUE 0x00000000UL /* Default value for CMU_HFCORECLKDIV */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_HFCORECLKDIV_MASK 0x0000000FUL /* Mask for CMU_HFCORECLKDIV */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_HFCORECLKDIV_MASK 0x0000010FUL /* Mask for CMU_HFCORECLKDIV */ +#endif + +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT 0 /* Shift value for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK 0xFUL /* Bit mask for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK 0x00000000UL /* Mode HFCLK for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 0x00000001UL /* Mode HFCLK2 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 0x00000002UL /* Mode HFCLK4 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 0x00000003UL /* Mode HFCLK8 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 0x00000004UL /* Mode HFCLK16 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 0x00000005UL /* Mode HFCLK32 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 0x00000006UL /* Mode HFCLK64 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 0x00000007UL /* Mode HFCLK128 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 0x00000008UL /* Mode HFCLK256 for CMU_HFCORECLKDIV */ +#define _CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 0x00000009UL /* Mode HFCLK512 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DEFAULT (_CMU_HFCORECLKDIV_HFCORECLKDIV_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK << 0) /* Shifted mode HFCLK for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 << 0) /* Shifted mode HFCLK2 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 << 0) /* Shifted mode HFCLK4 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 << 0) /* Shifted mode HFCLK8 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 << 0) /* Shifted mode HFCLK16 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 << 0) /* Shifted mode HFCLK32 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 << 0) /* Shifted mode HFCLK64 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 << 0) /* Shifted mode HFCLK128 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 << 0) /* Shifted mode HFCLK256 for CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 (_CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 << 0) /* Shifted mode HFCLK512 for CMU_HFCORECLKDIV */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_HFCORECLKDIV_HFCORECLKLEDIV (0x1UL << 8) /* Additional Division Factor For HFCORECLKLE */ +# define _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT 8 /* Shift value for CMU_HFCORECLKLEDIV */ +# define _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK 0x100UL /* Bit mask for CMU_HFCORECLKLEDIV */ +# define _CMU_HFCORECLKDIV_HFCORECLKLEDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKDIV */ +# define _CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV2 0x00000000UL /* Mode DIV2 for CMU_HFCORECLKDIV */ +# define _CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4 0x00000001UL /* Mode DIV4 for CMU_HFCORECLKDIV */ +# define CMU_HFCORECLKDIV_HFCORECLKLEDIV_DEFAULT (_CMU_HFCORECLKDIV_HFCORECLKLEDIV_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFCORECLKDIV */ +# define CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV2 (_CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV2 << 8) /* Shifted mode DIV2 for CMU_HFCORECLKDIV */ +# define CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4 (_CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4 << 8) /* Shifted mode DIV4 for CMU_HFCORECLKDIV */ +#endif + +/* Bit fields for CMU HFPERCLKDIV */ + +#define _CMU_HFPERCLKDIV_RESETVALUE 0x00000100UL /* Default value for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_MASK 0x0000010FUL /* Mask for CMU_HFPERCLKDIV */ + +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT 0 /* Shift value for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK 0xFUL /* Bit mask for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK 0x00000000UL /* Mode HFCLK for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 0x00000001UL /* Mode HFCLK2 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 0x00000002UL /* Mode HFCLK4 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 0x00000003UL /* Mode HFCLK8 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 0x00000004UL /* Mode HFCLK16 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 0x00000005UL /* Mode HFCLK32 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 0x00000006UL /* Mode HFCLK64 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 0x00000007UL /* Mode HFCLK128 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 0x00000008UL /* Mode HFCLK256 for CMU_HFPERCLKDIV */ +#define _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 0x00000009UL /* Mode HFCLK512 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DEFAULT (_CMU_HFPERCLKDIV_HFPERCLKDIV_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK << 0) /* Shifted mode HFCLK for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 << 0) /* Shifted mode HFCLK2 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 << 0) /* Shifted mode HFCLK4 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 << 0) /* Shifted mode HFCLK8 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 << 0) /* Shifted mode HFCLK16 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 << 0) /* Shifted mode HFCLK32 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 << 0) /* Shifted mode HFCLK64 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 << 0) /* Shifted mode HFCLK128 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 << 0) /* Shifted mode HFCLK256 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 (_CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 << 0) /* Shifted mode HFCLK512 for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKEN (0x1UL << 8) /* HFPERCLK Enable */ +#define _CMU_HFPERCLKDIV_HFPERCLKEN_SHIFT 8 /* Shift value for CMU_HFPERCLKEN */ +#define _CMU_HFPERCLKDIV_HFPERCLKEN_MASK 0x100UL /* Bit mask for CMU_HFPERCLKEN */ +#define _CMU_HFPERCLKDIV_HFPERCLKEN_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKEN_DEFAULT (_CMU_HFPERCLKDIV_HFPERCLKEN_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFPERCLKDIV */ + +/* Bit fields for CMU HFRCOCTRL */ + +#define _CMU_HFRCOCTRL_RESETVALUE 0x00000380UL /* Default value for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_MASK 0x0001F7FFUL /* Mask for CMU_HFRCOCTRL */ + +#define _CMU_HFRCOCTRL_TUNING_SHIFT 0 /* Shift value for CMU_TUNING */ +#define _CMU_HFRCOCTRL_TUNING_MASK 0xFFUL /* Bit mask for CMU_TUNING */ +#define _CMU_HFRCOCTRL_TUNING_DEFAULT 0x00000080UL /* Mode DEFAULT for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_TUNING_DEFAULT (_CMU_HFRCOCTRL_TUNING_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_SHIFT 8 /* Shift value for CMU_BAND */ +#define _CMU_HFRCOCTRL_BAND_MASK 0x700UL /* Bit mask for CMU_BAND */ +#define _CMU_HFRCOCTRL_BAND_1MHZ 0x00000000UL /* Mode 1MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_7MHZ 0x00000001UL /* Mode 7MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_11MHZ 0x00000002UL /* Mode 11MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_DEFAULT 0x00000003UL /* Mode DEFAULT for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_14MHZ 0x00000003UL /* Mode 14MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_21MHZ 0x00000004UL /* Mode 21MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_BAND_28MHZ 0x00000005UL /* Mode 28MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_1MHZ (_CMU_HFRCOCTRL_BAND_1MHZ << 8) /* Shifted mode 1MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_7MHZ (_CMU_HFRCOCTRL_BAND_7MHZ << 8) /* Shifted mode 7MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_11MHZ (_CMU_HFRCOCTRL_BAND_11MHZ << 8) /* Shifted mode 11MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_DEFAULT (_CMU_HFRCOCTRL_BAND_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_14MHZ (_CMU_HFRCOCTRL_BAND_14MHZ << 8) /* Shifted mode 14MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_21MHZ (_CMU_HFRCOCTRL_BAND_21MHZ << 8) /* Shifted mode 21MHZ for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_BAND_28MHZ (_CMU_HFRCOCTRL_BAND_28MHZ << 8) /* Shifted mode 28MHZ for CMU_HFRCOCTRL */ +#define _CMU_HFRCOCTRL_SUDELAY_SHIFT 12 /* Shift value for CMU_SUDELAY */ +#define _CMU_HFRCOCTRL_SUDELAY_MASK 0x1F000UL /* Bit mask for CMU_SUDELAY */ +#define _CMU_HFRCOCTRL_SUDELAY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_SUDELAY_DEFAULT (_CMU_HFRCOCTRL_SUDELAY_DEFAULT << 12) /* Shifted mode DEFAULT for CMU_HFRCOCTRL */ + +/* Bit fields for CMU LFRCOCTRL */ + +#define _CMU_LFRCOCTRL_RESETVALUE 0x00000040UL /* Default value for CMU_LFRCOCTRL */ +#define _CMU_LFRCOCTRL_MASK 0x0000007FUL /* Mask for CMU_LFRCOCTRL */ + +#define _CMU_LFRCOCTRL_TUNING_SHIFT 0 /* Shift value for CMU_TUNING */ +#define _CMU_LFRCOCTRL_TUNING_MASK 0x7FUL /* Bit mask for CMU_TUNING */ +#define _CMU_LFRCOCTRL_TUNING_DEFAULT 0x00000040UL /* Mode DEFAULT for CMU_LFRCOCTRL */ +#define CMU_LFRCOCTRL_TUNING_DEFAULT (_CMU_LFRCOCTRL_TUNING_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LFRCOCTRL */ + +/* Bit fields for CMU AUXHFRCOCTRL */ + +#define _CMU_AUXHFRCOCTRL_RESETVALUE 0x00000080UL /* Default value for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_MASK 0x000007FFUL /* Mask for CMU_AUXHFRCOCTRL */ + +#define _CMU_AUXHFRCOCTRL_TUNING_SHIFT 0 /* Shift value for CMU_TUNING */ +#define _CMU_AUXHFRCOCTRL_TUNING_MASK 0xFFUL /* Bit mask for CMU_TUNING */ +#define _CMU_AUXHFRCOCTRL_TUNING_DEFAULT 0x00000080UL /* Mode DEFAULT for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_TUNING_DEFAULT (_CMU_AUXHFRCOCTRL_TUNING_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_SHIFT 8 /* Shift value for CMU_BAND */ +#define _CMU_AUXHFRCOCTRL_BAND_MASK 0x700UL /* Bit mask for CMU_BAND */ +#define _CMU_AUXHFRCOCTRL_BAND_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_14MHZ 0x00000000UL /* Mode 14MHZ for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_11MHZ 0x00000001UL /* Mode 11MHZ for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_7MHZ 0x00000002UL /* Mode 7MHZ for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_1MHZ 0x00000003UL /* Mode 1MHZ for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_28MHZ 0x00000006UL /* Mode 28MHZ for CMU_AUXHFRCOCTRL */ +#define _CMU_AUXHFRCOCTRL_BAND_21MHZ 0x00000007UL /* Mode 21MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_DEFAULT (_CMU_AUXHFRCOCTRL_BAND_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_14MHZ (_CMU_AUXHFRCOCTRL_BAND_14MHZ << 8) /* Shifted mode 14MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_11MHZ (_CMU_AUXHFRCOCTRL_BAND_11MHZ << 8) /* Shifted mode 11MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_7MHZ (_CMU_AUXHFRCOCTRL_BAND_7MHZ << 8) /* Shifted mode 7MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_1MHZ (_CMU_AUXHFRCOCTRL_BAND_1MHZ << 8) /* Shifted mode 1MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_28MHZ (_CMU_AUXHFRCOCTRL_BAND_28MHZ << 8) /* Shifted mode 28MHZ for CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_21MHZ (_CMU_AUXHFRCOCTRL_BAND_21MHZ << 8) /* Shifted mode 21MHZ for CMU_AUXHFRCOCTRL */ + +/* Bit fields for CMU CALCTRL */ + +#define _CMU_CALCTRL_RESETVALUE 0x00000000UL /* Default value for CMU_CALCTRL */ +#define _CMU_CALCTRL_MASK 0x0000007FUL /* Mask for CMU_CALCTRL */ + +#define _CMU_CALCTRL_UPSEL_SHIFT 0 /* Shift value for CMU_UPSEL */ +#define _CMU_CALCTRL_UPSEL_MASK 0x7UL /* Bit mask for CMU_UPSEL */ +#define _CMU_CALCTRL_UPSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CALCTRL */ +#define _CMU_CALCTRL_UPSEL_HFXO 0x00000000UL /* Mode HFXO for CMU_CALCTRL */ +#define _CMU_CALCTRL_UPSEL_LFXO 0x00000001UL /* Mode LFXO for CMU_CALCTRL */ +#define _CMU_CALCTRL_UPSEL_HFRCO 0x00000002UL /* Mode HFRCO for CMU_CALCTRL */ +#define _CMU_CALCTRL_UPSEL_LFRCO 0x00000003UL /* Mode LFRCO for CMU_CALCTRL */ +#define _CMU_CALCTRL_UPSEL_AUXHFRCO 0x00000004UL /* Mode AUXHFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_DEFAULT (_CMU_CALCTRL_UPSEL_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_HFXO (_CMU_CALCTRL_UPSEL_HFXO << 0) /* Shifted mode HFXO for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_LFXO (_CMU_CALCTRL_UPSEL_LFXO << 0) /* Shifted mode LFXO for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_HFRCO (_CMU_CALCTRL_UPSEL_HFRCO << 0) /* Shifted mode HFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_LFRCO (_CMU_CALCTRL_UPSEL_LFRCO << 0) /* Shifted mode LFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_UPSEL_AUXHFRCO (_CMU_CALCTRL_UPSEL_AUXHFRCO << 0) /* Shifted mode AUXHFRCO for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_SHIFT 3 /* Shift value for CMU_DOWNSEL */ +#define _CMU_CALCTRL_DOWNSEL_MASK 0x38UL /* Bit mask for CMU_DOWNSEL */ +#define _CMU_CALCTRL_DOWNSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_HFCLK 0x00000000UL /* Mode HFCLK for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_HFXO 0x00000001UL /* Mode HFXO for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_LFXO 0x00000002UL /* Mode LFXO for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_HFRCO 0x00000003UL /* Mode HFRCO for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_LFRCO 0x00000004UL /* Mode LFRCO for CMU_CALCTRL */ +#define _CMU_CALCTRL_DOWNSEL_AUXHFRCO 0x00000005UL /* Mode AUXHFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_DEFAULT (_CMU_CALCTRL_DOWNSEL_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_HFCLK (_CMU_CALCTRL_DOWNSEL_HFCLK << 3) /* Shifted mode HFCLK for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_HFXO (_CMU_CALCTRL_DOWNSEL_HFXO << 3) /* Shifted mode HFXO for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_LFXO (_CMU_CALCTRL_DOWNSEL_LFXO << 3) /* Shifted mode LFXO for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_HFRCO (_CMU_CALCTRL_DOWNSEL_HFRCO << 3) /* Shifted mode HFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_LFRCO (_CMU_CALCTRL_DOWNSEL_LFRCO << 3) /* Shifted mode LFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_DOWNSEL_AUXHFRCO (_CMU_CALCTRL_DOWNSEL_AUXHFRCO << 3) /* Shifted mode AUXHFRCO for CMU_CALCTRL */ +#define CMU_CALCTRL_CONT (0x1UL << 6) /* Continuous Calibration */ +#define _CMU_CALCTRL_CONT_SHIFT 6 /* Shift value for CMU_CONT */ +#define _CMU_CALCTRL_CONT_MASK 0x40UL /* Bit mask for CMU_CONT */ +#define _CMU_CALCTRL_CONT_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CALCTRL */ +#define CMU_CALCTRL_CONT_DEFAULT (_CMU_CALCTRL_CONT_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_CALCTRL */ + +/* Bit fields for CMU CALCNT */ + +#define _CMU_CALCNT_RESETVALUE 0x00000000UL /* Default value for CMU_CALCNT */ +#define _CMU_CALCNT_MASK 0x000FFFFFUL /* Mask for CMU_CALCNT */ + +#define _CMU_CALCNT_CALCNT_SHIFT 0 /* Shift value for CMU_CALCNT */ +#define _CMU_CALCNT_CALCNT_MASK 0xFFFFFUL /* Bit mask for CMU_CALCNT */ +#define _CMU_CALCNT_CALCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CALCNT */ +#define CMU_CALCNT_CALCNT_DEFAULT (_CMU_CALCNT_CALCNT_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_CALCNT */ + +/* Bit fields for CMU OSCENCMD */ + +#define _CMU_OSCENCMD_RESETVALUE 0x00000000UL /* Default value for CMU_OSCENCMD */ +#define _CMU_OSCENCMD_MASK 0x000003FFUL /* Mask for CMU_OSCENCMD */ + +#define CMU_OSCENCMD_HFRCOEN (0x1UL << 0) /* HFRCO Enable */ +#define _CMU_OSCENCMD_HFRCOEN_SHIFT 0 /* Shift value for CMU_HFRCOEN */ +#define _CMU_OSCENCMD_HFRCOEN_MASK 0x1UL /* Bit mask for CMU_HFRCOEN */ +#define _CMU_OSCENCMD_HFRCOEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFRCOEN_DEFAULT (_CMU_OSCENCMD_HFRCOEN_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFRCODIS (0x1UL << 1) /* HFRCO Disable */ +#define _CMU_OSCENCMD_HFRCODIS_SHIFT 1 /* Shift value for CMU_HFRCODIS */ +#define _CMU_OSCENCMD_HFRCODIS_MASK 0x2UL /* Bit mask for CMU_HFRCODIS */ +#define _CMU_OSCENCMD_HFRCODIS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFRCODIS_DEFAULT (_CMU_OSCENCMD_HFRCODIS_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFXOEN (0x1UL << 2) /* HFXO Enable */ +#define _CMU_OSCENCMD_HFXOEN_SHIFT 2 /* Shift value for CMU_HFXOEN */ +#define _CMU_OSCENCMD_HFXOEN_MASK 0x4UL /* Bit mask for CMU_HFXOEN */ +#define _CMU_OSCENCMD_HFXOEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFXOEN_DEFAULT (_CMU_OSCENCMD_HFXOEN_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFXODIS (0x1UL << 3) /* HFXO Disable */ +#define _CMU_OSCENCMD_HFXODIS_SHIFT 3 /* Shift value for CMU_HFXODIS */ +#define _CMU_OSCENCMD_HFXODIS_MASK 0x8UL /* Bit mask for CMU_HFXODIS */ +#define _CMU_OSCENCMD_HFXODIS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_HFXODIS_DEFAULT (_CMU_OSCENCMD_HFXODIS_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_AUXHFRCOEN (0x1UL << 4) /* AUXHFRCO Enable */ +#define _CMU_OSCENCMD_AUXHFRCOEN_SHIFT 4 /* Shift value for CMU_AUXHFRCOEN */ +#define _CMU_OSCENCMD_AUXHFRCOEN_MASK 0x10UL /* Bit mask for CMU_AUXHFRCOEN */ +#define _CMU_OSCENCMD_AUXHFRCOEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_AUXHFRCOEN_DEFAULT (_CMU_OSCENCMD_AUXHFRCOEN_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_AUXHFRCODIS (0x1UL << 5) /* AUXHFRCO Disable */ +#define _CMU_OSCENCMD_AUXHFRCODIS_SHIFT 5 /* Shift value for CMU_AUXHFRCODIS */ +#define _CMU_OSCENCMD_AUXHFRCODIS_MASK 0x20UL /* Bit mask for CMU_AUXHFRCODIS */ +#define _CMU_OSCENCMD_AUXHFRCODIS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_AUXHFRCODIS_DEFAULT (_CMU_OSCENCMD_AUXHFRCODIS_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFRCOEN (0x1UL << 6) /* LFRCO Enable */ +#define _CMU_OSCENCMD_LFRCOEN_SHIFT 6 /* Shift value for CMU_LFRCOEN */ +#define _CMU_OSCENCMD_LFRCOEN_MASK 0x40UL /* Bit mask for CMU_LFRCOEN */ +#define _CMU_OSCENCMD_LFRCOEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFRCOEN_DEFAULT (_CMU_OSCENCMD_LFRCOEN_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFRCODIS (0x1UL << 7) /* LFRCO Disable */ +#define _CMU_OSCENCMD_LFRCODIS_SHIFT 7 /* Shift value for CMU_LFRCODIS */ +#define _CMU_OSCENCMD_LFRCODIS_MASK 0x80UL /* Bit mask for CMU_LFRCODIS */ +#define _CMU_OSCENCMD_LFRCODIS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFRCODIS_DEFAULT (_CMU_OSCENCMD_LFRCODIS_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFXOEN (0x1UL << 8) /* LFXO Enable */ +#define _CMU_OSCENCMD_LFXOEN_SHIFT 8 /* Shift value for CMU_LFXOEN */ +#define _CMU_OSCENCMD_LFXOEN_MASK 0x100UL /* Bit mask for CMU_LFXOEN */ +#define _CMU_OSCENCMD_LFXOEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFXOEN_DEFAULT (_CMU_OSCENCMD_LFXOEN_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFXODIS (0x1UL << 9) /* LFXO Disable */ +#define _CMU_OSCENCMD_LFXODIS_SHIFT 9 /* Shift value for CMU_LFXODIS */ +#define _CMU_OSCENCMD_LFXODIS_MASK 0x200UL /* Bit mask for CMU_LFXODIS */ +#define _CMU_OSCENCMD_LFXODIS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFXODIS_DEFAULT (_CMU_OSCENCMD_LFXODIS_DEFAULT << 9) /* Shifted mode DEFAULT for CMU_OSCENCMD */ + +/* Bit fields for CMU CMD */ + +#define _CMU_CMD_RESETVALUE 0x00000000UL /* Default value for CMU_CMD */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_CMD_MASK 0x0000001FUL /* Mask for CMU_CMD */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_CMD_MASK 0x0000007FUL /* Mask for CMU_CMD */ +#endif + +#define _CMU_CMD_HFCLKSEL_SHIFT 0 /* Shift value for CMU_HFCLKSEL */ +#define _CMU_CMD_HFCLKSEL_MASK 0x7UL /* Bit mask for CMU_HFCLKSEL */ +#define _CMU_CMD_HFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CMD */ +#define _CMU_CMD_HFCLKSEL_HFRCO 0x00000001UL /* Mode HFRCO for CMU_CMD */ +#define _CMU_CMD_HFCLKSEL_HFXO 0x00000002UL /* Mode HFXO for CMU_CMD */ +#define _CMU_CMD_HFCLKSEL_LFRCO 0x00000003UL /* Mode LFRCO for CMU_CMD */ +#define _CMU_CMD_HFCLKSEL_LFXO 0x00000004UL /* Mode LFXO for CMU_CMD */ +#define CMU_CMD_HFCLKSEL_DEFAULT (_CMU_CMD_HFCLKSEL_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_CMD */ +#define CMU_CMD_HFCLKSEL_HFRCO (_CMU_CMD_HFCLKSEL_HFRCO << 0) /* Shifted mode HFRCO for CMU_CMD */ +#define CMU_CMD_HFCLKSEL_HFXO (_CMU_CMD_HFCLKSEL_HFXO << 0) /* Shifted mode HFXO for CMU_CMD */ +#define CMU_CMD_HFCLKSEL_LFRCO (_CMU_CMD_HFCLKSEL_LFRCO << 0) /* Shifted mode LFRCO for CMU_CMD */ +#define CMU_CMD_HFCLKSEL_LFXO (_CMU_CMD_HFCLKSEL_LFXO << 0) /* Shifted mode LFXO for CMU_CMD */ +#define CMU_CMD_CALSTART (0x1UL << 3) /* Calibration Start */ +#define _CMU_CMD_CALSTART_SHIFT 3 /* Shift value for CMU_CALSTART */ +#define _CMU_CMD_CALSTART_MASK 0x8UL /* Bit mask for CMU_CALSTART */ +#define _CMU_CMD_CALSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CMD */ +#define CMU_CMD_CALSTART_DEFAULT (_CMU_CMD_CALSTART_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_CMD */ +#define CMU_CMD_CALSTOP (0x1UL << 4) /* Calibration Stop */ +#define _CMU_CMD_CALSTOP_SHIFT 4 /* Shift value for CMU_CALSTOP */ +#define _CMU_CMD_CALSTOP_MASK 0x10UL /* Bit mask for CMU_CALSTOP */ +#define _CMU_CMD_CALSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CMD */ +#define CMU_CMD_CALSTOP_DEFAULT (_CMU_CMD_CALSTOP_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_CMD */ +#if defined(CONFIG_EFM32_EFM32GG) +# define _CMU_CMD_USBCCLKSEL_SHIFT 5 /* Shift value for CMU_USBCCLKSEL */ +# define _CMU_CMD_USBCCLKSEL_MASK 0x60UL /* Bit mask for CMU_USBCCLKSEL */ +# define _CMU_CMD_USBCCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_CMD */ +# define _CMU_CMD_USBCCLKSEL_HFCLKNODIV 0x00000001UL /* Mode HFCLKNODIV for CMU_CMD */ +# define _CMU_CMD_USBCCLKSEL_LFXO 0x00000002UL /* Mode LFXO for CMU_CMD */ +# define _CMU_CMD_USBCCLKSEL_LFRCO 0x00000003UL /* Mode LFRCO for CMU_CMD */ +# define CMU_CMD_USBCCLKSEL_DEFAULT (_CMU_CMD_USBCCLKSEL_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_CMD */ +# define CMU_CMD_USBCCLKSEL_HFCLKNODIV (_CMU_CMD_USBCCLKSEL_HFCLKNODIV << 5) /* Shifted mode HFCLKNODIV for CMU_CMD */ +# define CMU_CMD_USBCCLKSEL_LFXO (_CMU_CMD_USBCCLKSEL_LFXO << 5) /* Shifted mode LFXO for CMU_CMD */ +# define CMU_CMD_USBCCLKSEL_LFRCO (_CMU_CMD_USBCCLKSEL_LFRCO << 5) /* Shifted mode LFRCO for CMU_CMD */ +#endif + +/* Bit fields for CMU LFCLKSEL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _CMU_LFCLKSEL_RESETVALUE 0x00000005UL /* Default value for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_MASK 0x0011000FUL /* Mask for CMU_LFCLKSEL */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _CMU_LFCLKSEL_RESETVALUE 0x00000005UL /* Default value for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_MASK 0x0011000FUL /* Mask for CMU_LFCLKSEL */ +#endif + +#define _CMU_LFCLKSEL_LFA_SHIFT 0 /* Shift value for CMU_LFA */ +#define _CMU_LFCLKSEL_LFA_MASK 0x3UL /* Bit mask for CMU_LFA */ +#define _CMU_LFCLKSEL_LFA_DISABLED 0x00000000UL /* Mode DISABLED for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFA_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFA_LFRCO 0x00000001UL /* Mode LFRCO for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFA_LFXO 0x00000002UL /* Mode LFXO for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 0x00000003UL /* Mode HFCORECLKLEDIV2 for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFA_DISABLED (_CMU_LFCLKSEL_LFA_DISABLED << 0) /* Shifted mode DISABLED for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFA_DEFAULT (_CMU_LFCLKSEL_LFA_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFA_LFRCO (_CMU_LFCLKSEL_LFA_LFRCO << 0) /* Shifted mode LFRCO for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFA_LFXO (_CMU_LFCLKSEL_LFA_LFXO << 0) /* Shifted mode LFXO for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 (_CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 << 0) /* Shifted mode HFCORECLKLEDIV2 for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFB_SHIFT 2 /* Shift value for CMU_LFB */ +#define _CMU_LFCLKSEL_LFB_MASK 0xCUL /* Bit mask for CMU_LFB */ +#define _CMU_LFCLKSEL_LFB_DISABLED 0x00000000UL /* Mode DISABLED for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFB_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFB_LFRCO 0x00000001UL /* Mode LFRCO for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFB_LFXO 0x00000002UL /* Mode LFXO for CMU_LFCLKSEL */ +#define _CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 0x00000003UL /* Mode HFCORECLKLEDIV2 for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFB_DISABLED (_CMU_LFCLKSEL_LFB_DISABLED << 2) /* Shifted mode DISABLED for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFB_DEFAULT (_CMU_LFCLKSEL_LFB_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFB_LFRCO (_CMU_LFCLKSEL_LFB_LFRCO << 2) /* Shifted mode LFRCO for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFB_LFXO (_CMU_LFCLKSEL_LFB_LFXO << 2) /* Shifted mode LFXO for CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 (_CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 << 2) /* Shifted mode HFCORECLKLEDIV2 for CMU_LFCLKSEL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_LFCLKSEL_LFAE (0x1UL << 16) /* Clock Select for LFA Extended */ +# define _CMU_LFCLKSEL_LFAE_SHIFT 16 /* Shift value for CMU_LFAE */ +# define _CMU_LFCLKSEL_LFAE_MASK 0x10000UL /* Bit mask for CMU_LFAE */ +# define _CMU_LFCLKSEL_LFAE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_LFAE_DISABLED 0x00000000UL /* Mode DISABLED for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_LFAE_ULFRCO 0x00000001UL /* Mode ULFRCO for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFAE_DEFAULT (_CMU_LFCLKSEL_LFAE_DEFAULT << 16) /* Shifted mode DEFAULT for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFAE_DISABLED (_CMU_LFCLKSEL_LFAE_DISABLED << 16) /* Shifted mode DISABLED for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFAE_ULFRCO (_CMU_LFCLKSEL_LFAE_ULFRCO << 16) /* Shifted mode ULFRCO for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFBE (0x1UL << 20) /* Clock Select for LFB Extended */ +# define _CMU_LFCLKSEL_LFBE_SHIFT 20 /* Shift value for CMU_LFBE */ +# define _CMU_LFCLKSEL_LFBE_MASK 0x100000UL /* Bit mask for CMU_LFBE */ +# define _CMU_LFCLKSEL_LFBE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_LFBE_DISABLED 0x00000000UL /* Mode DISABLED for CMU_LFCLKSEL */ +# define _CMU_LFCLKSEL_LFBE_ULFRCO 0x00000001UL /* Mode ULFRCO for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFBE_DEFAULT (_CMU_LFCLKSEL_LFBE_DEFAULT << 20) /* Shifted mode DEFAULT for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFBE_DISABLED (_CMU_LFCLKSEL_LFBE_DISABLED << 20) /* Shifted mode DISABLED for CMU_LFCLKSEL */ +# define CMU_LFCLKSEL_LFBE_ULFRCO (_CMU_LFCLKSEL_LFBE_ULFRCO << 20) /* Shifted mode ULFRCO for CMU_LFCLKSEL */ +#endif + +/* Bit fields for CMU STATUS */ + +#define _CMU_STATUS_RESETVALUE 0x00000403UL /* Default value for CMU_STATUS */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_STATUS_MASK 0x00007FFFUL /* Mask for CMU_STATUS */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_STATUS_MASK 0x0003FFFFUL /* Mask for CMU_STATUS */ +#endif + +#define CMU_STATUS_HFRCOENS (0x1UL << 0) /* HFRCO Enable Status */ +#define _CMU_STATUS_HFRCOENS_SHIFT 0 /* Shift value for CMU_HFRCOENS */ +#define _CMU_STATUS_HFRCOENS_MASK 0x1UL /* Bit mask for CMU_HFRCOENS */ +#define _CMU_STATUS_HFRCOENS_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFRCOENS_DEFAULT (_CMU_STATUS_HFRCOENS_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFRCORDY (0x1UL << 1) /* HFRCO Ready */ +#define _CMU_STATUS_HFRCORDY_SHIFT 1 /* Shift value for CMU_HFRCORDY */ +#define _CMU_STATUS_HFRCORDY_MASK 0x2UL /* Bit mask for CMU_HFRCORDY */ +#define _CMU_STATUS_HFRCORDY_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFRCORDY_DEFAULT (_CMU_STATUS_HFRCORDY_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXOENS (0x1UL << 2) /* HFXO Enable Status */ +#define _CMU_STATUS_HFXOENS_SHIFT 2 /* Shift value for CMU_HFXOENS */ +#define _CMU_STATUS_HFXOENS_MASK 0x4UL /* Bit mask for CMU_HFXOENS */ +#define _CMU_STATUS_HFXOENS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXOENS_DEFAULT (_CMU_STATUS_HFXOENS_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXORDY (0x1UL << 3) /* HFXO Ready */ +#define _CMU_STATUS_HFXORDY_SHIFT 3 /* Shift value for CMU_HFXORDY */ +#define _CMU_STATUS_HFXORDY_MASK 0x8UL /* Bit mask for CMU_HFXORDY */ +#define _CMU_STATUS_HFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXORDY_DEFAULT (_CMU_STATUS_HFXORDY_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_AUXHFRCOENS (0x1UL << 4) /* AUXHFRCO Enable Status */ +#define _CMU_STATUS_AUXHFRCOENS_SHIFT 4 /* Shift value for CMU_AUXHFRCOENS */ +#define _CMU_STATUS_AUXHFRCOENS_MASK 0x10UL /* Bit mask for CMU_AUXHFRCOENS */ +#define _CMU_STATUS_AUXHFRCOENS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_AUXHFRCOENS_DEFAULT (_CMU_STATUS_AUXHFRCOENS_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_AUXHFRCORDY (0x1UL << 5) /* AUXHFRCO Ready */ +#define _CMU_STATUS_AUXHFRCORDY_SHIFT 5 /* Shift value for CMU_AUXHFRCORDY */ +#define _CMU_STATUS_AUXHFRCORDY_MASK 0x20UL /* Bit mask for CMU_AUXHFRCORDY */ +#define _CMU_STATUS_AUXHFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_AUXHFRCORDY_DEFAULT (_CMU_STATUS_AUXHFRCORDY_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCOENS (0x1UL << 6) /* LFRCO Enable Status */ +#define _CMU_STATUS_LFRCOENS_SHIFT 6 /* Shift value for CMU_LFRCOENS */ +#define _CMU_STATUS_LFRCOENS_MASK 0x40UL /* Bit mask for CMU_LFRCOENS */ +#define _CMU_STATUS_LFRCOENS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCOENS_DEFAULT (_CMU_STATUS_LFRCOENS_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCORDY (0x1UL << 7) /* LFRCO Ready */ +#define _CMU_STATUS_LFRCORDY_SHIFT 7 /* Shift value for CMU_LFRCORDY */ +#define _CMU_STATUS_LFRCORDY_MASK 0x80UL /* Bit mask for CMU_LFRCORDY */ +#define _CMU_STATUS_LFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCORDY_DEFAULT (_CMU_STATUS_LFRCORDY_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXOENS (0x1UL << 8) /* LFXO Enable Status */ +#define _CMU_STATUS_LFXOENS_SHIFT 8 /* Shift value for CMU_LFXOENS */ +#define _CMU_STATUS_LFXOENS_MASK 0x100UL /* Bit mask for CMU_LFXOENS */ +#define _CMU_STATUS_LFXOENS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXOENS_DEFAULT (_CMU_STATUS_LFXOENS_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXORDY (0x1UL << 9) /* LFXO Ready */ +#define _CMU_STATUS_LFXORDY_SHIFT 9 /* Shift value for CMU_LFXORDY */ +#define _CMU_STATUS_LFXORDY_MASK 0x200UL /* Bit mask for CMU_LFXORDY */ +#define _CMU_STATUS_LFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXORDY_DEFAULT (_CMU_STATUS_LFXORDY_DEFAULT << 9) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFRCOSEL (0x1UL << 10) /* HFRCO Selected */ +#define _CMU_STATUS_HFRCOSEL_SHIFT 10 /* Shift value for CMU_HFRCOSEL */ +#define _CMU_STATUS_HFRCOSEL_MASK 0x400UL /* Bit mask for CMU_HFRCOSEL */ +#define _CMU_STATUS_HFRCOSEL_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFRCOSEL_DEFAULT (_CMU_STATUS_HFRCOSEL_DEFAULT << 10) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXOSEL (0x1UL << 11) /* HFXO Selected */ +#define _CMU_STATUS_HFXOSEL_SHIFT 11 /* Shift value for CMU_HFXOSEL */ +#define _CMU_STATUS_HFXOSEL_MASK 0x800UL /* Bit mask for CMU_HFXOSEL */ +#define _CMU_STATUS_HFXOSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_HFXOSEL_DEFAULT (_CMU_STATUS_HFXOSEL_DEFAULT << 11) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCOSEL (0x1UL << 12) /* LFRCO Selected */ +#define _CMU_STATUS_LFRCOSEL_SHIFT 12 /* Shift value for CMU_LFRCOSEL */ +#define _CMU_STATUS_LFRCOSEL_MASK 0x1000UL /* Bit mask for CMU_LFRCOSEL */ +#define _CMU_STATUS_LFRCOSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFRCOSEL_DEFAULT (_CMU_STATUS_LFRCOSEL_DEFAULT << 12) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXOSEL (0x1UL << 13) /* LFXO Selected */ +#define _CMU_STATUS_LFXOSEL_SHIFT 13 /* Shift value for CMU_LFXOSEL */ +#define _CMU_STATUS_LFXOSEL_MASK 0x2000UL /* Bit mask for CMU_LFXOSEL */ +#define _CMU_STATUS_LFXOSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_LFXOSEL_DEFAULT (_CMU_STATUS_LFXOSEL_DEFAULT << 13) /* Shifted mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_CALBSY (0x1UL << 14) /* Calibration Busy */ +#define _CMU_STATUS_CALBSY_SHIFT 14 /* Shift value for CMU_CALBSY */ +#define _CMU_STATUS_CALBSY_MASK 0x4000UL /* Bit mask for CMU_CALBSY */ +#define _CMU_STATUS_CALBSY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +#define CMU_STATUS_CALBSY_DEFAULT (_CMU_STATUS_CALBSY_DEFAULT << 14) /* Shifted mode DEFAULT for CMU_STATUS */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_STATUS_USBCHFCLKSEL (0x1UL << 15) /* USBC HFCLK Selected */ +# define _CMU_STATUS_USBCHFCLKSEL_SHIFT 15 /* Shift value for CMU_USBCHFCLKSEL */ +# define _CMU_STATUS_USBCHFCLKSEL_MASK 0x8000UL /* Bit mask for CMU_USBCHFCLKSEL */ +# define _CMU_STATUS_USBCHFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +# define CMU_STATUS_USBCHFCLKSEL_DEFAULT (_CMU_STATUS_USBCHFCLKSEL_DEFAULT << 15) /* Shifted mode DEFAULT for CMU_STATUS */ +# define CMU_STATUS_USBCLFXOSEL (0x1UL << 16) /* USBC LFXO Selected */ +# define _CMU_STATUS_USBCLFXOSEL_SHIFT 16 /* Shift value for CMU_USBCLFXOSEL */ +# define _CMU_STATUS_USBCLFXOSEL_MASK 0x10000UL /* Bit mask for CMU_USBCLFXOSEL */ +# define _CMU_STATUS_USBCLFXOSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +# define CMU_STATUS_USBCLFXOSEL_DEFAULT (_CMU_STATUS_USBCLFXOSEL_DEFAULT << 16) /* Shifted mode DEFAULT for CMU_STATUS */ +# define CMU_STATUS_USBCLFRCOSEL (0x1UL << 17) /* USBC LFRCO Selected */ +# define _CMU_STATUS_USBCLFRCOSEL_SHIFT 17 /* Shift value for CMU_USBCLFRCOSEL */ +# define _CMU_STATUS_USBCLFRCOSEL_MASK 0x20000UL /* Bit mask for CMU_USBCLFRCOSEL */ +# define _CMU_STATUS_USBCLFRCOSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_STATUS */ +# define CMU_STATUS_USBCLFRCOSEL_DEFAULT (_CMU_STATUS_USBCLFRCOSEL_DEFAULT << 17) /* Shifted mode DEFAULT for CMU_STATUS */ +#endif + +/* Bit fields for CMU IF */ + +#define _CMU_IF_RESETVALUE 0x00000001UL /* Default value for CMU_IF */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_IF_MASK 0x0000007FUL /* Mask for CMU_IF */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_IF_MASK 0x000000FFUL /* Mask for CMU_IF */ +#endif + +#define CMU_IF_HFRCORDY (0x1UL << 0) /* HFRCO Ready Interrupt Flag */ +#define _CMU_IF_HFRCORDY_SHIFT 0 /* Shift value for CMU_HFRCORDY */ +#define _CMU_IF_HFRCORDY_MASK 0x1UL /* Bit mask for CMU_HFRCORDY */ +#define _CMU_IF_HFRCORDY_DEFAULT 0x00000001UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_HFRCORDY_DEFAULT (_CMU_IF_HFRCORDY_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_HFXORDY (0x1UL << 1) /* HFXO Ready Interrupt Flag */ +#define _CMU_IF_HFXORDY_SHIFT 1 /* Shift value for CMU_HFXORDY */ +#define _CMU_IF_HFXORDY_MASK 0x2UL /* Bit mask for CMU_HFXORDY */ +#define _CMU_IF_HFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_HFXORDY_DEFAULT (_CMU_IF_HFXORDY_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_LFRCORDY (0x1UL << 2) /* LFRCO Ready Interrupt Flag */ +#define _CMU_IF_LFRCORDY_SHIFT 2 /* Shift value for CMU_LFRCORDY */ +#define _CMU_IF_LFRCORDY_MASK 0x4UL /* Bit mask for CMU_LFRCORDY */ +#define _CMU_IF_LFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_LFRCORDY_DEFAULT (_CMU_IF_LFRCORDY_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_LFXORDY (0x1UL << 3) /* LFXO Ready Interrupt Flag */ +#define _CMU_IF_LFXORDY_SHIFT 3 /* Shift value for CMU_LFXORDY */ +#define _CMU_IF_LFXORDY_MASK 0x8UL /* Bit mask for CMU_LFXORDY */ +#define _CMU_IF_LFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_LFXORDY_DEFAULT (_CMU_IF_LFXORDY_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_AUXHFRCORDY (0x1UL << 4) /* AUXHFRCO Ready Interrupt Flag */ +#define _CMU_IF_AUXHFRCORDY_SHIFT 4 /* Shift value for CMU_AUXHFRCORDY */ +#define _CMU_IF_AUXHFRCORDY_MASK 0x10UL /* Bit mask for CMU_AUXHFRCORDY */ +#define _CMU_IF_AUXHFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_AUXHFRCORDY_DEFAULT (_CMU_IF_AUXHFRCORDY_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_CALRDY (0x1UL << 5) /* Calibration Ready Interrupt Flag */ +#define _CMU_IF_CALRDY_SHIFT 5 /* Shift value for CMU_CALRDY */ +#define _CMU_IF_CALRDY_MASK 0x20UL /* Bit mask for CMU_CALRDY */ +#define _CMU_IF_CALRDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_CALRDY_DEFAULT (_CMU_IF_CALRDY_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_IF */ +#define CMU_IF_CALOF (0x1UL << 6) /* Calibration Overflow Interrupt Flag */ +#define _CMU_IF_CALOF_SHIFT 6 /* Shift value for CMU_CALOF */ +#define _CMU_IF_CALOF_MASK 0x40UL /* Bit mask for CMU_CALOF */ +#define _CMU_IF_CALOF_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +#define CMU_IF_CALOF_DEFAULT (_CMU_IF_CALOF_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_IF */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_IF_USBCHFCLKSEL (0x1UL << 7) /* USBC HFCLK Selected Interrupt Flag */ +# define _CMU_IF_USBCHFCLKSEL_SHIFT 7 /* Shift value for CMU_USBCHFCLKSEL */ +# define _CMU_IF_USBCHFCLKSEL_MASK 0x80UL /* Bit mask for CMU_USBCHFCLKSEL */ +# define _CMU_IF_USBCHFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IF */ +# define CMU_IF_USBCHFCLKSEL_DEFAULT (_CMU_IF_USBCHFCLKSEL_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_IF */ +#endif + +/* Bit fields for CMU IFS */ + +#define _CMU_IFS_RESETVALUE 0x00000000UL /* Default value for CMU_IFS */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_IFS_MASK 0x0000007FUL /* Mask for CMU_IFS */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_IFS_MASK 0x000000FFUL /* Mask for CMU_IFS */ +#endif + +#define CMU_IFS_HFRCORDY (0x1UL << 0) /* HFRCO Ready Interrupt Flag Set */ +#define _CMU_IFS_HFRCORDY_SHIFT 0 /* Shift value for CMU_HFRCORDY */ +#define _CMU_IFS_HFRCORDY_MASK 0x1UL /* Bit mask for CMU_HFRCORDY */ +#define _CMU_IFS_HFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_HFRCORDY_DEFAULT (_CMU_IFS_HFRCORDY_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_HFXORDY (0x1UL << 1) /* HFXO Ready Interrupt Flag Set */ +#define _CMU_IFS_HFXORDY_SHIFT 1 /* Shift value for CMU_HFXORDY */ +#define _CMU_IFS_HFXORDY_MASK 0x2UL /* Bit mask for CMU_HFXORDY */ +#define _CMU_IFS_HFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_HFXORDY_DEFAULT (_CMU_IFS_HFXORDY_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_LFRCORDY (0x1UL << 2) /* LFRCO Ready Interrupt Flag Set */ +#define _CMU_IFS_LFRCORDY_SHIFT 2 /* Shift value for CMU_LFRCORDY */ +#define _CMU_IFS_LFRCORDY_MASK 0x4UL /* Bit mask for CMU_LFRCORDY */ +#define _CMU_IFS_LFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_LFRCORDY_DEFAULT (_CMU_IFS_LFRCORDY_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_LFXORDY (0x1UL << 3) /* LFXO Ready Interrupt Flag Set */ +#define _CMU_IFS_LFXORDY_SHIFT 3 /* Shift value for CMU_LFXORDY */ +#define _CMU_IFS_LFXORDY_MASK 0x8UL /* Bit mask for CMU_LFXORDY */ +#define _CMU_IFS_LFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_LFXORDY_DEFAULT (_CMU_IFS_LFXORDY_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_AUXHFRCORDY (0x1UL << 4) /* AUXHFRCO Ready Interrupt Flag Set */ +#define _CMU_IFS_AUXHFRCORDY_SHIFT 4 /* Shift value for CMU_AUXHFRCORDY */ +#define _CMU_IFS_AUXHFRCORDY_MASK 0x10UL /* Bit mask for CMU_AUXHFRCORDY */ +#define _CMU_IFS_AUXHFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_AUXHFRCORDY_DEFAULT (_CMU_IFS_AUXHFRCORDY_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_CALRDY (0x1UL << 5) /* Calibration Ready Interrupt Flag Set */ +#define _CMU_IFS_CALRDY_SHIFT 5 /* Shift value for CMU_CALRDY */ +#define _CMU_IFS_CALRDY_MASK 0x20UL /* Bit mask for CMU_CALRDY */ +#define _CMU_IFS_CALRDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_CALRDY_DEFAULT (_CMU_IFS_CALRDY_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_IFS */ +#define CMU_IFS_CALOF (0x1UL << 6) /* Calibration Overflow Interrupt Flag Set */ +#define _CMU_IFS_CALOF_SHIFT 6 /* Shift value for CMU_CALOF */ +#define _CMU_IFS_CALOF_MASK 0x40UL /* Bit mask for CMU_CALOF */ +#define _CMU_IFS_CALOF_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +#define CMU_IFS_CALOF_DEFAULT (_CMU_IFS_CALOF_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_IFS */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_IFS_USBCHFCLKSEL (0x1UL << 7) /* USBC HFCLK Selected Interrupt Flag Set */ +# define _CMU_IFS_USBCHFCLKSEL_SHIFT 7 /* Shift value for CMU_USBCHFCLKSEL */ +# define _CMU_IFS_USBCHFCLKSEL_MASK 0x80UL /* Bit mask for CMU_USBCHFCLKSEL */ +# define _CMU_IFS_USBCHFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFS */ +# define CMU_IFS_USBCHFCLKSEL_DEFAULT (_CMU_IFS_USBCHFCLKSEL_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_IFS */ +#endif + +/* Bit fields for CMU IFC */ + +#define _CMU_IFC_RESETVALUE 0x00000000UL /* Default value for CMU_IFC */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_IFC_MASK 0x0000007FUL /* Mask for CMU_IFC */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_IFC_MASK 0x000000FFUL /* Mask for CMU_IFC */ +#endif + +#define CMU_IFC_HFRCORDY (0x1UL << 0) /* HFRCO Ready Interrupt Flag Clear */ +#define _CMU_IFC_HFRCORDY_SHIFT 0 /* Shift value for CMU_HFRCORDY */ +#define _CMU_IFC_HFRCORDY_MASK 0x1UL /* Bit mask for CMU_HFRCORDY */ +#define _CMU_IFC_HFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_HFRCORDY_DEFAULT (_CMU_IFC_HFRCORDY_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_HFXORDY (0x1UL << 1) /* HFXO Ready Interrupt Flag Clear */ +#define _CMU_IFC_HFXORDY_SHIFT 1 /* Shift value for CMU_HFXORDY */ +#define _CMU_IFC_HFXORDY_MASK 0x2UL /* Bit mask for CMU_HFXORDY */ +#define _CMU_IFC_HFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_HFXORDY_DEFAULT (_CMU_IFC_HFXORDY_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_LFRCORDY (0x1UL << 2) /* LFRCO Ready Interrupt Flag Clear */ +#define _CMU_IFC_LFRCORDY_SHIFT 2 /* Shift value for CMU_LFRCORDY */ +#define _CMU_IFC_LFRCORDY_MASK 0x4UL /* Bit mask for CMU_LFRCORDY */ +#define _CMU_IFC_LFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_LFRCORDY_DEFAULT (_CMU_IFC_LFRCORDY_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_LFXORDY (0x1UL << 3) /* LFXO Ready Interrupt Flag Clear */ +#define _CMU_IFC_LFXORDY_SHIFT 3 /* Shift value for CMU_LFXORDY */ +#define _CMU_IFC_LFXORDY_MASK 0x8UL /* Bit mask for CMU_LFXORDY */ +#define _CMU_IFC_LFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_LFXORDY_DEFAULT (_CMU_IFC_LFXORDY_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_AUXHFRCORDY (0x1UL << 4) /* AUXHFRCO Ready Interrupt Flag Clear */ +#define _CMU_IFC_AUXHFRCORDY_SHIFT 4 /* Shift value for CMU_AUXHFRCORDY */ +#define _CMU_IFC_AUXHFRCORDY_MASK 0x10UL /* Bit mask for CMU_AUXHFRCORDY */ +#define _CMU_IFC_AUXHFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_AUXHFRCORDY_DEFAULT (_CMU_IFC_AUXHFRCORDY_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_CALRDY (0x1UL << 5) /* Calibration Ready Interrupt Flag Clear */ +#define _CMU_IFC_CALRDY_SHIFT 5 /* Shift value for CMU_CALRDY */ +#define _CMU_IFC_CALRDY_MASK 0x20UL /* Bit mask for CMU_CALRDY */ +#define _CMU_IFC_CALRDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_CALRDY_DEFAULT (_CMU_IFC_CALRDY_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_IFC */ +#define CMU_IFC_CALOF (0x1UL << 6) /* Calibration Overflow Interrupt Flag Clear */ +#define _CMU_IFC_CALOF_SHIFT 6 /* Shift value for CMU_CALOF */ +#define _CMU_IFC_CALOF_MASK 0x40UL /* Bit mask for CMU_CALOF */ +#define _CMU_IFC_CALOF_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +#define CMU_IFC_CALOF_DEFAULT (_CMU_IFC_CALOF_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_IFC */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_IFC_USBCHFCLKSEL (0x1UL << 7) /* USBC HFCLK Selected Interrupt Flag Clear */ +# define _CMU_IFC_USBCHFCLKSEL_SHIFT 7 /* Shift value for CMU_USBCHFCLKSEL */ +# define _CMU_IFC_USBCHFCLKSEL_MASK 0x80UL /* Bit mask for CMU_USBCHFCLKSEL */ +# define _CMU_IFC_USBCHFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IFC */ +# define CMU_IFC_USBCHFCLKSEL_DEFAULT (_CMU_IFC_USBCHFCLKSEL_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_IFC */ +#endif + +/* Bit fields for CMU IEN */ + +#define _CMU_IEN_RESETVALUE 0x00000000UL /* Default value for CMU_IEN */ +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _CMU_IEN_MASK 0x0000007FUL /* Mask for CMU_IEN */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_IEN_MASK 0x000000FFUL /* Mask for CMU_IEN */ +#endif + +#define CMU_IEN_HFRCORDY (0x1UL << 0) /* HFRCO Ready Interrupt Enable */ +#define _CMU_IEN_HFRCORDY_SHIFT 0 /* Shift value for CMU_HFRCORDY */ +#define _CMU_IEN_HFRCORDY_MASK 0x1UL /* Bit mask for CMU_HFRCORDY */ +#define _CMU_IEN_HFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_HFRCORDY_DEFAULT (_CMU_IEN_HFRCORDY_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_HFXORDY (0x1UL << 1) /* HFXO Ready Interrupt Enable */ +#define _CMU_IEN_HFXORDY_SHIFT 1 /* Shift value for CMU_HFXORDY */ +#define _CMU_IEN_HFXORDY_MASK 0x2UL /* Bit mask for CMU_HFXORDY */ +#define _CMU_IEN_HFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_HFXORDY_DEFAULT (_CMU_IEN_HFXORDY_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_LFRCORDY (0x1UL << 2) /* LFRCO Ready Interrupt Enable */ +#define _CMU_IEN_LFRCORDY_SHIFT 2 /* Shift value for CMU_LFRCORDY */ +#define _CMU_IEN_LFRCORDY_MASK 0x4UL /* Bit mask for CMU_LFRCORDY */ +#define _CMU_IEN_LFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_LFRCORDY_DEFAULT (_CMU_IEN_LFRCORDY_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_LFXORDY (0x1UL << 3) /* LFXO Ready Interrupt Enable */ +#define _CMU_IEN_LFXORDY_SHIFT 3 /* Shift value for CMU_LFXORDY */ +#define _CMU_IEN_LFXORDY_MASK 0x8UL /* Bit mask for CMU_LFXORDY */ +#define _CMU_IEN_LFXORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_LFXORDY_DEFAULT (_CMU_IEN_LFXORDY_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_AUXHFRCORDY (0x1UL << 4) /* AUXHFRCO Ready Interrupt Enable */ +#define _CMU_IEN_AUXHFRCORDY_SHIFT 4 /* Shift value for CMU_AUXHFRCORDY */ +#define _CMU_IEN_AUXHFRCORDY_MASK 0x10UL /* Bit mask for CMU_AUXHFRCORDY */ +#define _CMU_IEN_AUXHFRCORDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_AUXHFRCORDY_DEFAULT (_CMU_IEN_AUXHFRCORDY_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_CALRDY (0x1UL << 5) /* Calibration Ready Interrupt Enable */ +#define _CMU_IEN_CALRDY_SHIFT 5 /* Shift value for CMU_CALRDY */ +#define _CMU_IEN_CALRDY_MASK 0x20UL /* Bit mask for CMU_CALRDY */ +#define _CMU_IEN_CALRDY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_CALRDY_DEFAULT (_CMU_IEN_CALRDY_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_IEN */ +#define CMU_IEN_CALOF (0x1UL << 6) /* Calibration Overflow Interrupt Enable */ +#define _CMU_IEN_CALOF_SHIFT 6 /* Shift value for CMU_CALOF */ +#define _CMU_IEN_CALOF_MASK 0x40UL /* Bit mask for CMU_CALOF */ +#define _CMU_IEN_CALOF_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +#define CMU_IEN_CALOF_DEFAULT (_CMU_IEN_CALOF_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_IEN */ +#if defined(CONFIG_EFM32_EFM32GG) +# define CMU_IEN_USBCHFCLKSEL (0x1UL << 7) /* USBC HFCLK Selected Interrupt Enable */ +# define _CMU_IEN_USBCHFCLKSEL_SHIFT 7 /* Shift value for CMU_USBCHFCLKSEL */ +# define _CMU_IEN_USBCHFCLKSEL_MASK 0x80UL /* Bit mask for CMU_USBCHFCLKSEL */ +# define _CMU_IEN_USBCHFCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_IEN */ +# define CMU_IEN_USBCHFCLKSEL_DEFAULT (_CMU_IEN_USBCHFCLKSEL_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_IEN */ +#endif + +/* Bit fields for CMU HFCORECLKEN0 */ + +#if defined(CONFIG_EFM32_EFM32TG) +# define _CMU_HFCORECLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFCORECLKEN0 */ +# define _CMU_HFCORECLKEN0_MASK 0x00000007UL /* Mask for CMU_HFCORECLKEN0 */ + +# define CMU_HFCORECLKEN0_AES (0x1UL << 0) /* Advanced Encryption Standard Accelerator Clock Enable */ +# define _CMU_HFCORECLKEN0_AES_SHIFT 0 /* Shift value for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_MASK 0x1UL /* Bit mask for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_AES_DEFAULT (_CMU_HFCORECLKEN0_AES_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_DMA (0x1UL << 1) /* Direct Memory Access Controller Clock Enable */ +# define _CMU_HFCORECLKEN0_DMA_SHIFT 1 /* Shift value for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_MASK 0x2UL /* Bit mask for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_DMA_DEFAULT (_CMU_HFCORECLKEN0_DMA_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE (0x1UL << 2) /* Low Energy Peripheral Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_LE_SHIFT 2 /* Shift value for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_MASK 0x4UL /* Bit mask for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE_DEFAULT (_CMU_HFCORECLKEN0_LE_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _CMU_HFCORECLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFCORECLKEN0 */ +# define _CMU_HFCORECLKEN0_MASK 0x00000007UL /* Mask for CMU_HFCORECLKEN0 */ + +# define CMU_HFCORECLKEN0_AES (0x1UL << 0) /* Advanced Encryption Standard Accelerator Clock Enable */ +# define _CMU_HFCORECLKEN0_AES_SHIFT 0 /* Shift value for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_MASK 0x1UL /* Bit mask for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_AES_DEFAULT (_CMU_HFCORECLKEN0_AES_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_DMA (0x1UL << 1) /* Direct Memory Access Controller Clock Enable */ +# define _CMU_HFCORECLKEN0_DMA_SHIFT 1 /* Shift value for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_MASK 0x2UL /* Bit mask for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_DMA_DEFAULT (_CMU_HFCORECLKEN0_DMA_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE (0x1UL << 2) /* Low Energy Peripheral Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_LE_SHIFT 2 /* Shift value for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_MASK 0x4UL /* Bit mask for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE_DEFAULT (_CMU_HFCORECLKEN0_LE_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_EBI (0x1UL << 3) /* External Bus Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_EBI_SHIFT 3 /* Shift value for CMU_EBI */ +# define _CMU_HFCORECLKEN0_EBI_MASK 0x8UL /* Bit mask for CMU_EBI */ +# define _CMU_HFCORECLKEN0_EBI_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_EBI_DEFAULT (_CMU_HFCORECLKEN0_EBI_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_HFCORECLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFCORECLKEN0 */ +# define _CMU_HFCORECLKEN0_MASK 0x0000003FUL /* Mask for CMU_HFCORECLKEN0 */ + +# define CMU_HFCORECLKEN0_DMA (0x1UL << 0) /* Direct Memory Access Controller Clock Enable */ +# define _CMU_HFCORECLKEN0_DMA_SHIFT 0 /* Shift value for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_MASK 0x1UL /* Bit mask for CMU_DMA */ +# define _CMU_HFCORECLKEN0_DMA_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_DMA_DEFAULT (_CMU_HFCORECLKEN0_DMA_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_AES (0x1UL << 1) /* Advanced Encryption Standard Accelerator Clock Enable */ +# define _CMU_HFCORECLKEN0_AES_SHIFT 1 /* Shift value for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_MASK 0x2UL /* Bit mask for CMU_AES */ +# define _CMU_HFCORECLKEN0_AES_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_AES_DEFAULT (_CMU_HFCORECLKEN0_AES_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_USBC (0x1UL << 2) /* Universal Serial Bus Interface Core Clock Enable */ +# define _CMU_HFCORECLKEN0_USBC_SHIFT 2 /* Shift value for CMU_USBC */ +# define _CMU_HFCORECLKEN0_USBC_MASK 0x4UL /* Bit mask for CMU_USBC */ +# define _CMU_HFCORECLKEN0_USBC_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_USBC_DEFAULT (_CMU_HFCORECLKEN0_USBC_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_USB (0x1UL << 3) /* Universal Serial Bus Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_USB_SHIFT 3 /* Shift value for CMU_USB */ +# define _CMU_HFCORECLKEN0_USB_MASK 0x8UL /* Bit mask for CMU_USB */ +# define _CMU_HFCORECLKEN0_USB_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_USB_DEFAULT (_CMU_HFCORECLKEN0_USB_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE (0x1UL << 4) /* Low Energy Peripheral Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_LE_SHIFT 4 /* Shift value for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_MASK 0x10UL /* Bit mask for CMU_LE */ +# define _CMU_HFCORECLKEN0_LE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_LE_DEFAULT (_CMU_HFCORECLKEN0_LE_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_EBI (0x1UL << 5) /* External Bus Interface Clock Enable */ +# define _CMU_HFCORECLKEN0_EBI_SHIFT 5 /* Shift value for CMU_EBI */ +# define _CMU_HFCORECLKEN0_EBI_MASK 0x20UL /* Bit mask for CMU_EBI */ +# define _CMU_HFCORECLKEN0_EBI_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFCORECLKEN0 */ +# define CMU_HFCORECLKEN0_EBI_DEFAULT (_CMU_HFCORECLKEN0_EBI_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_HFCORECLKEN0 */ +#endif + +/* Bit fields for CMU HFPERCLKEN0 */ + +#if defined(CONFIG_EFM32_EFM32TG) +# define _CMU_HFPERCLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFPERCLKEN0 */ +# define _CMU_HFPERCLKEN0_MASK 0x00000FFFUL /* Mask for CMU_HFPERCLKEN0 */ + +# define CMU_HFPERCLKEN0_ACMP0 (0x1UL << 0) /* Analog Comparator 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP0_SHIFT 0 /* Shift value for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_MASK 0x1UL /* Bit mask for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP0_DEFAULT (_CMU_HFPERCLKEN0_ACMP0_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1 (0x1UL << 1) /* Analog Comparator 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP1_SHIFT 1 /* Shift value for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_MASK 0x2UL /* Bit mask for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1_DEFAULT (_CMU_HFPERCLKEN0_ACMP1_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART0 (0x1UL << 2) /* Universal Synchronous/Asynchronous Receiver/Transmitter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART0_SHIFT 2 /* Shift value for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_MASK 0x4UL /* Bit mask for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART0_DEFAULT (_CMU_HFPERCLKEN0_USART0_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1 (0x1UL << 3) /* Universal Synchronous/Asynchronous Receiver/Transmitter 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART1_SHIFT 3 /* Shift value for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_MASK 0x8UL /* Bit mask for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1_DEFAULT (_CMU_HFPERCLKEN0_USART1_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0 (0x1UL << 4) /* Timer 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER0_SHIFT 4 /* Shift value for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_MASK 0x10UL /* Bit mask for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0_DEFAULT (_CMU_HFPERCLKEN0_TIMER0_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1 (0x1UL << 5) /* Timer 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER1_SHIFT 5 /* Shift value for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_MASK 0x20UL /* Bit mask for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1_DEFAULT (_CMU_HFPERCLKEN0_TIMER1_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO (0x1UL << 6) /* General purpose Input/Output Clock Enable */ +# define _CMU_HFPERCLKEN0_GPIO_SHIFT 6 /* Shift value for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_MASK 0x40UL /* Bit mask for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO_DEFAULT (_CMU_HFPERCLKEN0_GPIO_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP (0x1UL << 7) /* Voltage Comparator Clock Enable */ +# define _CMU_HFPERCLKEN0_VCMP_SHIFT 7 /* Shift value for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_MASK 0x80UL /* Bit mask for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP_DEFAULT (_CMU_HFPERCLKEN0_VCMP_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS (0x1UL << 8) /* Peripheral Reflex System Clock Enable */ +# define _CMU_HFPERCLKEN0_PRS_SHIFT 8 /* Shift value for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_MASK 0x100UL /* Bit mask for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS_DEFAULT (_CMU_HFPERCLKEN0_PRS_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0 (0x1UL << 9) /* Analog to Digital Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ADC0_SHIFT 9 /* Shift value for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_MASK 0x200UL /* Bit mask for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0_DEFAULT (_CMU_HFPERCLKEN0_ADC0_DEFAULT << 9) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0 (0x1UL << 10) /* Digital to Analog Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_DAC0_SHIFT 10 /* Shift value for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_MASK 0x400UL /* Bit mask for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0_DEFAULT (_CMU_HFPERCLKEN0_DAC0_DEFAULT << 10) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0 (0x1UL << 11) /* I2C 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_I2C0_SHIFT 11 /* Shift value for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_MASK 0x800UL /* Bit mask for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0_DEFAULT (_CMU_HFPERCLKEN0_I2C0_DEFAULT << 11) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _CMU_HFPERCLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFPERCLKEN0 */ +# define _CMU_HFPERCLKEN0_MASK 0x0000FDFFUL /* Mask for CMU_HFPERCLKEN0 */ + +# define CMU_HFPERCLKEN0_USART0 (0x1UL << 0) /* Universal Synchronous/Asynchronous Receiver/Transmitter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART0_SHIFT 0 /* Shift value for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_MASK 0x1UL /* Bit mask for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART0_DEFAULT (_CMU_HFPERCLKEN0_USART0_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1 (0x1UL << 1) /* Universal Synchronous/Asynchronous Receiver/Transmitter 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART1_SHIFT 1 /* Shift value for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_MASK 0x2UL /* Bit mask for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1_DEFAULT (_CMU_HFPERCLKEN0_USART1_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART2 (0x1UL << 2) /* Universal Synchronous/Asynchronous Receiver/Transmitter 2 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART2_SHIFT 2 /* Shift value for CMU_USART2 */ +# define _CMU_HFPERCLKEN0_USART2_MASK 0x4UL /* Bit mask for CMU_USART2 */ +# define _CMU_HFPERCLKEN0_USART2_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART2_DEFAULT (_CMU_HFPERCLKEN0_USART2_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART0 (0x1UL << 3) /* Universal Asynchronous Receiver/Transmitter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_UART0_SHIFT 3 /* Shift value for CMU_UART0 */ +# define _CMU_HFPERCLKEN0_UART0_MASK 0x8UL /* Bit mask for CMU_UART0 */ +# define _CMU_HFPERCLKEN0_UART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART0_DEFAULT (_CMU_HFPERCLKEN0_UART0_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0 (0x1UL << 4) /* Timer 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER0_SHIFT 4 /* Shift value for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_MASK 0x10UL /* Bit mask for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0_DEFAULT (_CMU_HFPERCLKEN0_TIMER0_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1 (0x1UL << 5) /* Timer 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER1_SHIFT 5 /* Shift value for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_MASK 0x20UL /* Bit mask for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1_DEFAULT (_CMU_HFPERCLKEN0_TIMER1_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER2 (0x1UL << 6) /* Timer 2 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER2_SHIFT 6 /* Shift value for CMU_TIMER2 */ +# define _CMU_HFPERCLKEN0_TIMER2_MASK 0x40UL /* Bit mask for CMU_TIMER2 */ +# define _CMU_HFPERCLKEN0_TIMER2_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER2_DEFAULT (_CMU_HFPERCLKEN0_TIMER2_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP0 (0x1UL << 7) /* Analog Comparator 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP0_SHIFT 7 /* Shift value for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_MASK 0x80UL /* Bit mask for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP0_DEFAULT (_CMU_HFPERCLKEN0_ACMP0_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1 (0x1UL << 8) /* Analog Comparator 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP1_SHIFT 8 /* Shift value for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_MASK 0x100UL /* Bit mask for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1_DEFAULT (_CMU_HFPERCLKEN0_ACMP1_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS (0x1UL << 10) /* Peripheral Reflex System Clock Enable */ +# define _CMU_HFPERCLKEN0_PRS_SHIFT 10 /* Shift value for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_MASK 0x400UL /* Bit mask for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS_DEFAULT (_CMU_HFPERCLKEN0_PRS_DEFAULT << 10) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0 (0x1UL << 11) /* Digital to Analog Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_DAC0_SHIFT 11 /* Shift value for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_MASK 0x800UL /* Bit mask for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0_DEFAULT (_CMU_HFPERCLKEN0_DAC0_DEFAULT << 11) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO (0x1UL << 12) /* General purpose Input/Output Clock Enable */ +# define _CMU_HFPERCLKEN0_GPIO_SHIFT 12 /* Shift value for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_MASK 0x1000UL /* Bit mask for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO_DEFAULT (_CMU_HFPERCLKEN0_GPIO_DEFAULT << 12) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP (0x1UL << 13) /* Voltage Comparator Clock Enable */ +# define _CMU_HFPERCLKEN0_VCMP_SHIFT 13 /* Shift value for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_MASK 0x2000UL /* Bit mask for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP_DEFAULT (_CMU_HFPERCLKEN0_VCMP_DEFAULT << 13) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0 (0x1UL << 14) /* Analog to Digital Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ADC0_SHIFT 14 /* Shift value for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_MASK 0x40000UL /* Bit mask for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0_DEFAULT (_CMU_HFPERCLKEN0_ADC0_DEFAULT << 14) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0 (0x1UL << 15) /* I2C 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_I2C0_SHIFT 15 /* Shift value for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_MASK 0x8000UL /* Bit mask for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0_DEFAULT (_CMU_HFPERCLKEN0_I2C0_DEFAULT << 15) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _CMU_HFPERCLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_HFPERCLKEN0 */ +# define _CMU_HFPERCLKEN0_MASK 0x0003FFFFUL /* Mask for CMU_HFPERCLKEN0 */ + +# define CMU_HFPERCLKEN0_USART0 (0x1UL << 0) /* Universal Synchronous/Asynchronous Receiver/Transmitter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART0_SHIFT 0 /* Shift value for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_MASK 0x1UL /* Bit mask for CMU_USART0 */ +# define _CMU_HFPERCLKEN0_USART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART0_DEFAULT (_CMU_HFPERCLKEN0_USART0_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1 (0x1UL << 1) /* Universal Synchronous/Asynchronous Receiver/Transmitter 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART1_SHIFT 1 /* Shift value for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_MASK 0x2UL /* Bit mask for CMU_USART1 */ +# define _CMU_HFPERCLKEN0_USART1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART1_DEFAULT (_CMU_HFPERCLKEN0_USART1_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART2 (0x1UL << 2) /* Universal Synchronous/Asynchronous Receiver/Transmitter 2 Clock Enable */ +# define _CMU_HFPERCLKEN0_USART2_SHIFT 2 /* Shift value for CMU_USART2 */ +# define _CMU_HFPERCLKEN0_USART2_MASK 0x4UL /* Bit mask for CMU_USART2 */ +# define _CMU_HFPERCLKEN0_USART2_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_USART2_DEFAULT (_CMU_HFPERCLKEN0_USART2_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART0 (0x1UL << 3) /* Universal Asynchronous Receiver/Transmitter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_UART0_SHIFT 3 /* Shift value for CMU_UART0 */ +# define _CMU_HFPERCLKEN0_UART0_MASK 0x8UL /* Bit mask for CMU_UART0 */ +# define _CMU_HFPERCLKEN0_UART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART0_DEFAULT (_CMU_HFPERCLKEN0_UART0_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART1 (0x1UL << 4) /* Universal Asynchronous Receiver/Transmitter 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_UART1_SHIFT 4 /* Shift value for CMU_UART1 */ +# define _CMU_HFPERCLKEN0_UART1_MASK 0x10UL /* Bit mask for CMU_UART1 */ +# define _CMU_HFPERCLKEN0_UART1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_UART1_DEFAULT (_CMU_HFPERCLKEN0_UART1_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0 (0x1UL << 5) /* Timer 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER0_SHIFT 5 /* Shift value for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_MASK 0x20UL /* Bit mask for CMU_TIMER0 */ +# define _CMU_HFPERCLKEN0_TIMER0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER0_DEFAULT (_CMU_HFPERCLKEN0_TIMER0_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1 (0x1UL << 6) /* Timer 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER1_SHIFT 6 /* Shift value for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_MASK 0x40UL /* Bit mask for CMU_TIMER1 */ +# define _CMU_HFPERCLKEN0_TIMER1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER1_DEFAULT (_CMU_HFPERCLKEN0_TIMER1_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER2 (0x1UL << 7) /* Timer 2 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER2_SHIFT 7 /* Shift value for CMU_TIMER2 */ +# define _CMU_HFPERCLKEN0_TIMER2_MASK 0x80UL /* Bit mask for CMU_TIMER2 */ +# define _CMU_HFPERCLKEN0_TIMER2_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER2_DEFAULT (_CMU_HFPERCLKEN0_TIMER2_DEFAULT << 7) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER3 (0x1UL << 8) /* Timer 3 Clock Enable */ +# define _CMU_HFPERCLKEN0_TIMER3_SHIFT 8 /* Shift value for CMU_TIMER3 */ +# define _CMU_HFPERCLKEN0_TIMER3_MASK 0x100UL /* Bit mask for CMU_TIMER3 */ +# define _CMU_HFPERCLKEN0_TIMER3_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_TIMER3_DEFAULT (_CMU_HFPERCLKEN0_TIMER3_DEFAULT << 8) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP0 (0x1UL << 9) /* Analog Comparator 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP0_SHIFT 9 /* Shift value for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_MASK 0x200UL /* Bit mask for CMU_ACMP0 */ +# define _CMU_HFPERCLKEN0_ACMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP0_DEFAULT (_CMU_HFPERCLKEN0_ACMP0_DEFAULT << 9) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1 (0x1UL << 10) /* Analog Comparator 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_ACMP1_SHIFT 10 /* Shift value for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_MASK 0x400UL /* Bit mask for CMU_ACMP1 */ +# define _CMU_HFPERCLKEN0_ACMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ACMP1_DEFAULT (_CMU_HFPERCLKEN0_ACMP1_DEFAULT << 10) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0 (0x1UL << 11) /* I2C 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_I2C0_SHIFT 11 /* Shift value for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_MASK 0x800UL /* Bit mask for CMU_I2C0 */ +# define _CMU_HFPERCLKEN0_I2C0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C0_DEFAULT (_CMU_HFPERCLKEN0_I2C0_DEFAULT << 11) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C1 (0x1UL << 12) /* I2C 1 Clock Enable */ +# define _CMU_HFPERCLKEN0_I2C1_SHIFT 12 /* Shift value for CMU_I2C1 */ +# define _CMU_HFPERCLKEN0_I2C1_MASK 0x1000UL /* Bit mask for CMU_I2C1 */ +# define _CMU_HFPERCLKEN0_I2C1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_I2C1_DEFAULT (_CMU_HFPERCLKEN0_I2C1_DEFAULT << 12) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO (0x1UL << 13) /* General purpose Input/Output Clock Enable */ +# define _CMU_HFPERCLKEN0_GPIO_SHIFT 13 /* Shift value for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_MASK 0x2000UL /* Bit mask for CMU_GPIO */ +# define _CMU_HFPERCLKEN0_GPIO_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_GPIO_DEFAULT (_CMU_HFPERCLKEN0_GPIO_DEFAULT << 13) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP (0x1UL << 14) /* Voltage Comparator Clock Enable */ +# define _CMU_HFPERCLKEN0_VCMP_SHIFT 14 /* Shift value for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_MASK 0x4000UL /* Bit mask for CMU_VCMP */ +# define _CMU_HFPERCLKEN0_VCMP_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_VCMP_DEFAULT (_CMU_HFPERCLKEN0_VCMP_DEFAULT << 14) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS (0x1UL << 15) /* Peripheral Reflex System Clock Enable */ +# define _CMU_HFPERCLKEN0_PRS_SHIFT 15 /* Shift value for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_MASK 0x8000UL /* Bit mask for CMU_PRS */ +# define _CMU_HFPERCLKEN0_PRS_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_PRS_DEFAULT (_CMU_HFPERCLKEN0_PRS_DEFAULT << 15) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0 (0x1UL << 16) /* Analog to Digital Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_ADC0_SHIFT 16 /* Shift value for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_MASK 0x10000UL /* Bit mask for CMU_ADC0 */ +# define _CMU_HFPERCLKEN0_ADC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_ADC0_DEFAULT (_CMU_HFPERCLKEN0_ADC0_DEFAULT << 16) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0 (0x1UL << 17) /* Digital to Analog Converter 0 Clock Enable */ +# define _CMU_HFPERCLKEN0_DAC0_SHIFT 17 /* Shift value for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_MASK 0x20000UL /* Bit mask for CMU_DAC0 */ +# define _CMU_HFPERCLKEN0_DAC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_HFPERCLKEN0 */ +# define CMU_HFPERCLKEN0_DAC0_DEFAULT (_CMU_HFPERCLKEN0_DAC0_DEFAULT << 17) /* Shifted mode DEFAULT for CMU_HFPERCLKEN0 */ +#endif + +/* Bit fields for CMU SYNCBUSY */ + +#define _CMU_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for CMU_SYNCBUSY */ +#define _CMU_SYNCBUSY_MASK 0x00000055UL /* Mask for CMU_SYNCBUSY */ + +#define CMU_SYNCBUSY_LFACLKEN0 (0x1UL << 0) /* Low Frequency A Clock Enable 0 Busy */ +#define _CMU_SYNCBUSY_LFACLKEN0_SHIFT 0 /* Shift value for CMU_LFACLKEN0 */ +#define _CMU_SYNCBUSY_LFACLKEN0_MASK 0x1UL /* Bit mask for CMU_LFACLKEN0 */ +#define _CMU_SYNCBUSY_LFACLKEN0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFACLKEN0_DEFAULT (_CMU_SYNCBUSY_LFACLKEN0_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFAPRESC0 (0x1UL << 2) /* Low Frequency A Prescaler 0 Busy */ +#define _CMU_SYNCBUSY_LFAPRESC0_SHIFT 2 /* Shift value for CMU_LFAPRESC0 */ +#define _CMU_SYNCBUSY_LFAPRESC0_MASK 0x4UL /* Bit mask for CMU_LFAPRESC0 */ +#define _CMU_SYNCBUSY_LFAPRESC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFAPRESC0_DEFAULT (_CMU_SYNCBUSY_LFAPRESC0_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFBCLKEN0 (0x1UL << 4) /* Low Frequency B Clock Enable 0 Busy */ +#define _CMU_SYNCBUSY_LFBCLKEN0_SHIFT 4 /* Shift value for CMU_LFBCLKEN0 */ +#define _CMU_SYNCBUSY_LFBCLKEN0_MASK 0x10UL /* Bit mask for CMU_LFBCLKEN0 */ +#define _CMU_SYNCBUSY_LFBCLKEN0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFBCLKEN0_DEFAULT (_CMU_SYNCBUSY_LFBCLKEN0_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFBPRESC0 (0x1UL << 6) /* Low Frequency B Prescaler 0 Busy */ +#define _CMU_SYNCBUSY_LFBPRESC0_SHIFT 6 /* Shift value for CMU_LFBPRESC0 */ +#define _CMU_SYNCBUSY_LFBPRESC0_MASK 0x40UL /* Bit mask for CMU_LFBPRESC0 */ +#define _CMU_SYNCBUSY_LFBPRESC0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFBPRESC0_DEFAULT (_CMU_SYNCBUSY_LFBPRESC0_DEFAULT << 6) /* Shifted mode DEFAULT for CMU_SYNCBUSY */ + +/* Bit fields for CMU FREEZE */ + +#define _CMU_FREEZE_RESETVALUE 0x00000000UL /* Default value for CMU_FREEZE */ +#define _CMU_FREEZE_MASK 0x00000001UL /* Mask for CMU_FREEZE */ + +#define CMU_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _CMU_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for CMU_REGFREEZE */ +#define _CMU_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for CMU_REGFREEZE */ +#define _CMU_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_FREEZE */ +#define _CMU_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for CMU_FREEZE */ +#define _CMU_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for CMU_FREEZE */ +#define CMU_FREEZE_REGFREEZE_DEFAULT (_CMU_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_FREEZE */ +#define CMU_FREEZE_REGFREEZE_UPDATE (_CMU_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for CMU_FREEZE */ +#define CMU_FREEZE_REGFREEZE_FREEZE (_CMU_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for CMU_FREEZE */ + +/* Bit fields for CMU LFACLKEN0 */ + +#define _CMU_LFACLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_LFACLKEN0 */ +#define _CMU_LFACLKEN0_MASK 0x0000000FUL /* Mask for CMU_LFACLKEN0 */ + +#define CMU_LFACLKEN0_LESENSE (0x1UL << 0) /* Low Energy Sensor Interface Clock Enable */ +#define _CMU_LFACLKEN0_LESENSE_SHIFT 0 /* Shift value for CMU_LESENSE */ +#define _CMU_LFACLKEN0_LESENSE_MASK 0x1UL /* Bit mask for CMU_LESENSE */ +#define _CMU_LFACLKEN0_LESENSE_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LESENSE_DEFAULT (_CMU_LFACLKEN0_LESENSE_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_RTC (0x1UL << 1) /* Real-Time Counter Clock Enable */ +#define _CMU_LFACLKEN0_RTC_SHIFT 1 /* Shift value for CMU_RTC */ +#define _CMU_LFACLKEN0_RTC_MASK 0x2UL /* Bit mask for CMU_RTC */ +#define _CMU_LFACLKEN0_RTC_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_RTC_DEFAULT (_CMU_LFACLKEN0_RTC_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LETIMER0 (0x1UL << 2) /* Low Energy Timer 0 Clock Enable */ +#define _CMU_LFACLKEN0_LETIMER0_SHIFT 2 /* Shift value for CMU_LETIMER0 */ +#define _CMU_LFACLKEN0_LETIMER0_MASK 0x4UL /* Bit mask for CMU_LETIMER0 */ +#define _CMU_LFACLKEN0_LETIMER0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LETIMER0_DEFAULT (_CMU_LFACLKEN0_LETIMER0_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LCD (0x1UL << 3) /* Liquid Crystal Display Controller Clock Enable */ +#define _CMU_LFACLKEN0_LCD_SHIFT 3 /* Shift value for CMU_LCD */ +#define _CMU_LFACLKEN0_LCD_MASK 0x8UL /* Bit mask for CMU_LCD */ +#define _CMU_LFACLKEN0_LCD_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LCD_DEFAULT (_CMU_LFACLKEN0_LCD_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_LFACLKEN0 */ + +/* Bit fields for CMU LFBCLKEN0 */ + +#define _CMU_LFBCLKEN0_RESETVALUE 0x00000000UL /* Default value for CMU_LFBCLKEN0 */ +#if defined(CONFIG_EFM32_EFM32TG) +# define _CMU_LFBCLKEN0_MASK 0x00000001UL /* Mask for CMU_LFBCLKEN0 */ +#elif defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define _CMU_LFBCLKEN0_MASK 0x00000003UL /* Mask for CMU_LFBCLKEN0 */ +#endif + +#define CMU_LFBCLKEN0_LEUART0 (0x1UL << 0) /* Low Energy UART 0 Clock Enable */ +#define _CMU_LFBCLKEN0_LEUART0_SHIFT 0 /* Shift value for CMU_LEUART0 */ +#define _CMU_LFBCLKEN0_LEUART0_MASK 0x1UL /* Bit mask for CMU_LEUART0 */ +#define _CMU_LFBCLKEN0_LEUART0_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFBCLKEN0 */ +#define CMU_LFBCLKEN0_LEUART0_DEFAULT (_CMU_LFBCLKEN0_LEUART0_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LFBCLKEN0 */ +#if defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define CMU_LFBCLKEN0_LEUART1 (0x1UL << 1) /* Low Energy UART 1 Clock Enable */ +# define _CMU_LFBCLKEN0_LEUART1_SHIFT 1 /* Shift value for CMU_LEUART1 */ +# define _CMU_LFBCLKEN0_LEUART1_MASK 0x2UL /* Bit mask for CMU_LEUART1 */ +# define _CMU_LFBCLKEN0_LEUART1_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LFBCLKEN0 */ +# define CMU_LFBCLKEN0_LEUART1_DEFAULT (_CMU_LFBCLKEN0_LEUART1_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_LFBCLKEN0 */ +#endif + +/* Bit fields for CMU LFAPRESC0 */ + +#define _CMU_LFAPRESC0_RESETVALUE 0x00000000UL /* Default value for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_MASK 0x00003FF3UL /* Mask for CMU_LFAPRESC0 */ + +#define _CMU_LFAPRESC0_LESENSE_SHIFT 0 /* Shift value for CMU_LESENSE */ +#define _CMU_LFAPRESC0_LESENSE_MASK 0x3UL /* Bit mask for CMU_LESENSE */ +#define _CMU_LFAPRESC0_LESENSE_DIV1 0x00000000UL /* Mode DIV1 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LESENSE_DIV2 0x00000001UL /* Mode DIV2 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LESENSE_DIV4 0x00000002UL /* Mode DIV4 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LESENSE_DIV8 0x00000003UL /* Mode DIV8 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LESENSE_DIV1 (_CMU_LFAPRESC0_LESENSE_DIV1 << 0) /* Shifted mode DIV1 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LESENSE_DIV2 (_CMU_LFAPRESC0_LESENSE_DIV2 << 0) /* Shifted mode DIV2 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LESENSE_DIV4 (_CMU_LFAPRESC0_LESENSE_DIV4 << 0) /* Shifted mode DIV4 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LESENSE_DIV8 (_CMU_LFAPRESC0_LESENSE_DIV8 << 0) /* Shifted mode DIV8 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_SHIFT 4 /* Shift value for CMU_RTC */ +#define _CMU_LFAPRESC0_RTC_MASK 0xF0UL /* Bit mask for CMU_RTC */ +#define _CMU_LFAPRESC0_RTC_DIV1 0x00000000UL /* Mode DIV1 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV2 0x00000001UL /* Mode DIV2 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV4 0x00000002UL /* Mode DIV4 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV8 0x00000003UL /* Mode DIV8 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV16 0x00000004UL /* Mode DIV16 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV32 0x00000005UL /* Mode DIV32 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV64 0x00000006UL /* Mode DIV64 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV128 0x00000007UL /* Mode DIV128 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV256 0x00000008UL /* Mode DIV256 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV512 0x00000009UL /* Mode DIV512 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV1024 0x0000000AUL /* Mode DIV1024 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV2048 0x0000000BUL /* Mode DIV2048 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV4096 0x0000000CUL /* Mode DIV4096 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV8192 0x0000000DUL /* Mode DIV8192 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV16384 0x0000000EUL /* Mode DIV16384 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_RTC_DIV32768 0x0000000FUL /* Mode DIV32768 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV1 (_CMU_LFAPRESC0_RTC_DIV1 << 4) /* Shifted mode DIV1 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV2 (_CMU_LFAPRESC0_RTC_DIV2 << 4) /* Shifted mode DIV2 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV4 (_CMU_LFAPRESC0_RTC_DIV4 << 4) /* Shifted mode DIV4 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV8 (_CMU_LFAPRESC0_RTC_DIV8 << 4) /* Shifted mode DIV8 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV16 (_CMU_LFAPRESC0_RTC_DIV16 << 4) /* Shifted mode DIV16 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV32 (_CMU_LFAPRESC0_RTC_DIV32 << 4) /* Shifted mode DIV32 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV64 (_CMU_LFAPRESC0_RTC_DIV64 << 4) /* Shifted mode DIV64 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV128 (_CMU_LFAPRESC0_RTC_DIV128 << 4) /* Shifted mode DIV128 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV256 (_CMU_LFAPRESC0_RTC_DIV256 << 4) /* Shifted mode DIV256 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV512 (_CMU_LFAPRESC0_RTC_DIV512 << 4) /* Shifted mode DIV512 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV1024 (_CMU_LFAPRESC0_RTC_DIV1024 << 4) /* Shifted mode DIV1024 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV2048 (_CMU_LFAPRESC0_RTC_DIV2048 << 4) /* Shifted mode DIV2048 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV4096 (_CMU_LFAPRESC0_RTC_DIV4096 << 4) /* Shifted mode DIV4096 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV8192 (_CMU_LFAPRESC0_RTC_DIV8192 << 4) /* Shifted mode DIV8192 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV16384 (_CMU_LFAPRESC0_RTC_DIV16384 << 4) /* Shifted mode DIV16384 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_DIV32768 (_CMU_LFAPRESC0_RTC_DIV32768 << 4) /* Shifted mode DIV32768 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_SHIFT 8 /* Shift value for CMU_LETIMER0 */ +#define _CMU_LFAPRESC0_LETIMER0_MASK 0xF00UL /* Bit mask for CMU_LETIMER0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV1 0x00000000UL /* Mode DIV1 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV2 0x00000001UL /* Mode DIV2 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV4 0x00000002UL /* Mode DIV4 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV8 0x00000003UL /* Mode DIV8 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV16 0x00000004UL /* Mode DIV16 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV32 0x00000005UL /* Mode DIV32 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV64 0x00000006UL /* Mode DIV64 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV128 0x00000007UL /* Mode DIV128 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV256 0x00000008UL /* Mode DIV256 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV512 0x00000009UL /* Mode DIV512 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV1024 0x0000000AUL /* Mode DIV1024 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV2048 0x0000000BUL /* Mode DIV2048 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV4096 0x0000000CUL /* Mode DIV4096 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV8192 0x0000000DUL /* Mode DIV8192 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV16384 0x0000000EUL /* Mode DIV16384 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LETIMER0_DIV32768 0x0000000FUL /* Mode DIV32768 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV1 (_CMU_LFAPRESC0_LETIMER0_DIV1 << 8) /* Shifted mode DIV1 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV2 (_CMU_LFAPRESC0_LETIMER0_DIV2 << 8) /* Shifted mode DIV2 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV4 (_CMU_LFAPRESC0_LETIMER0_DIV4 << 8) /* Shifted mode DIV4 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV8 (_CMU_LFAPRESC0_LETIMER0_DIV8 << 8) /* Shifted mode DIV8 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV16 (_CMU_LFAPRESC0_LETIMER0_DIV16 << 8) /* Shifted mode DIV16 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV32 (_CMU_LFAPRESC0_LETIMER0_DIV32 << 8) /* Shifted mode DIV32 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV64 (_CMU_LFAPRESC0_LETIMER0_DIV64 << 8) /* Shifted mode DIV64 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV128 (_CMU_LFAPRESC0_LETIMER0_DIV128 << 8) /* Shifted mode DIV128 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV256 (_CMU_LFAPRESC0_LETIMER0_DIV256 << 8) /* Shifted mode DIV256 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV512 (_CMU_LFAPRESC0_LETIMER0_DIV512 << 8) /* Shifted mode DIV512 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV1024 (_CMU_LFAPRESC0_LETIMER0_DIV1024 << 8) /* Shifted mode DIV1024 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV2048 (_CMU_LFAPRESC0_LETIMER0_DIV2048 << 8) /* Shifted mode DIV2048 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV4096 (_CMU_LFAPRESC0_LETIMER0_DIV4096 << 8) /* Shifted mode DIV4096 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV8192 (_CMU_LFAPRESC0_LETIMER0_DIV8192 << 8) /* Shifted mode DIV8192 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV16384 (_CMU_LFAPRESC0_LETIMER0_DIV16384 << 8) /* Shifted mode DIV16384 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LETIMER0_DIV32768 (_CMU_LFAPRESC0_LETIMER0_DIV32768 << 8) /* Shifted mode DIV32768 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LCD_SHIFT 12 /* Shift value for CMU_LCD */ +#define _CMU_LFAPRESC0_LCD_MASK 0x3000UL /* Bit mask for CMU_LCD */ +#define _CMU_LFAPRESC0_LCD_DIV16 0x00000000UL /* Mode DIV16 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LCD_DIV32 0x00000001UL /* Mode DIV32 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LCD_DIV64 0x00000002UL /* Mode DIV64 for CMU_LFAPRESC0 */ +#define _CMU_LFAPRESC0_LCD_DIV128 0x00000003UL /* Mode DIV128 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LCD_DIV16 (_CMU_LFAPRESC0_LCD_DIV16 << 12) /* Shifted mode DIV16 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LCD_DIV32 (_CMU_LFAPRESC0_LCD_DIV32 << 12) /* Shifted mode DIV32 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LCD_DIV64 (_CMU_LFAPRESC0_LCD_DIV64 << 12) /* Shifted mode DIV64 for CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LCD_DIV128 (_CMU_LFAPRESC0_LCD_DIV128 << 12) /* Shifted mode DIV128 for CMU_LFAPRESC0 */ + +/* Bit fields for CMU LFBPRESC0 */ + +#define _CMU_LFBPRESC0_RESETVALUE 0x00000000UL /* Default value for CMU_LFBPRESC0 */ +#if defined(CONFIG_EFM32_EFM32TG) +# define _CMU_LFBPRESC0_MASK 0x00000003UL /* Mask for CMU_LFBPRESC0 */ +#elif defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define _CMU_LFBPRESC0_MASK 0x00000033UL /* Mask for CMU_LFBPRESC0 */ +#endif + +#define _CMU_LFBPRESC0_LEUART0_SHIFT 0 /* Shift value for CMU_LEUART0 */ +#define _CMU_LFBPRESC0_LEUART0_MASK 0x3UL /* Bit mask for CMU_LEUART0 */ +#define _CMU_LFBPRESC0_LEUART0_DIV1 0x00000000UL /* Mode DIV1 for CMU_LFBPRESC0 */ +#define _CMU_LFBPRESC0_LEUART0_DIV2 0x00000001UL /* Mode DIV2 for CMU_LFBPRESC0 */ +#define _CMU_LFBPRESC0_LEUART0_DIV4 0x00000002UL /* Mode DIV4 for CMU_LFBPRESC0 */ +#define _CMU_LFBPRESC0_LEUART0_DIV8 0x00000003UL /* Mode DIV8 for CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART0_DIV1 (_CMU_LFBPRESC0_LEUART0_DIV1 << 0) /* Shifted mode DIV1 for CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART0_DIV2 (_CMU_LFBPRESC0_LEUART0_DIV2 << 0) /* Shifted mode DIV2 for CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART0_DIV4 (_CMU_LFBPRESC0_LEUART0_DIV4 << 0) /* Shifted mode DIV4 for CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART0_DIV8 (_CMU_LFBPRESC0_LEUART0_DIV8 << 0) /* Shifted mode DIV8 for CMU_LFBPRESC0 */ +#if defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define _CMU_LFBPRESC0_LEUART1_SHIFT 4 /* Shift value for CMU_LEUART1 */ +# define _CMU_LFBPRESC0_LEUART1_MASK 0x30UL /* Bit mask for CMU_LEUART1 */ +# define _CMU_LFBPRESC0_LEUART1_DIV1 0x00000000UL /* Mode DIV1 for CMU_LFBPRESC0 */ +# define _CMU_LFBPRESC0_LEUART1_DIV2 0x00000001UL /* Mode DIV2 for CMU_LFBPRESC0 */ +# define _CMU_LFBPRESC0_LEUART1_DIV4 0x00000002UL /* Mode DIV4 for CMU_LFBPRESC0 */ +# define _CMU_LFBPRESC0_LEUART1_DIV8 0x00000003UL /* Mode DIV8 for CMU_LFBPRESC0 */ +# define CMU_LFBPRESC0_LEUART1_DIV1 (_CMU_LFBPRESC0_LEUART1_DIV1 << 4) /* Shifted mode DIV1 for CMU_LFBPRESC0 */ +# define CMU_LFBPRESC0_LEUART1_DIV2 (_CMU_LFBPRESC0_LEUART1_DIV2 << 4) /* Shifted mode DIV2 for CMU_LFBPRESC0 */ +# define CMU_LFBPRESC0_LEUART1_DIV4 (_CMU_LFBPRESC0_LEUART1_DIV4 << 4) /* Shifted mode DIV4 for CMU_LFBPRESC0 */ +# define CMU_LFBPRESC0_LEUART1_DIV8 (_CMU_LFBPRESC0_LEUART1_DIV8 << 4) /* Shifted mode DIV8 for CMU_LFBPRESC0 */ +#endif + +/* Bit fields for CMU PCNTCTRL */ + +#define _CMU_PCNTCTRL_RESETVALUE 0x00000000UL /* Default value for CMU_PCNTCTRL */ +#if defined(CONFIG_EFM32_EFM32TG) +# define _CMU_PCNTCTRL_MASK 0x00000003UL /* Mask for CMU_PCNTCTRL */ +#elif defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define _CMU_PCNTCTRL_MASK 0x0000003FUL /* Mask for CMU_PCNTCTRL */ +#endif + +#define CMU_PCNTCTRL_PCNT0CLKEN (0x1UL << 0) /* PCNT0 Clock Enable */ +#define _CMU_PCNTCTRL_PCNT0CLKEN_SHIFT 0 /* Shift value for CMU_PCNT0CLKEN */ +#define _CMU_PCNTCTRL_PCNT0CLKEN_MASK 0x1UL /* Bit mask for CMU_PCNT0CLKEN */ +#define _CMU_PCNTCTRL_PCNT0CLKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKEN_DEFAULT (_CMU_PCNTCTRL_PCNT0CLKEN_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKSEL (0x1UL << 1) /* PCNT0 Clock Select */ +#define _CMU_PCNTCTRL_PCNT0CLKSEL_SHIFT 1 /* Shift value for CMU_PCNT0CLKSEL */ +#define _CMU_PCNTCTRL_PCNT0CLKSEL_MASK 0x2UL /* Bit mask for CMU_PCNT0CLKSEL */ +#define _CMU_PCNTCTRL_PCNT0CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +#define _CMU_PCNTCTRL_PCNT0CLKSEL_LFACLK 0x00000000UL /* Mode LFACLK for CMU_PCNTCTRL */ +#define _CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0 0x00000001UL /* Mode PCNT0S0 for CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKSEL_DEFAULT (_CMU_PCNTCTRL_PCNT0CLKSEL_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKSEL_LFACLK (_CMU_PCNTCTRL_PCNT0CLKSEL_LFACLK << 1) /* Shifted mode LFACLK for CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0 (_CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0 << 1) /* Shifted mode PCNT0S0 for CMU_PCNTCTRL */ +#if defined(CONFIG_EFM32_EFM32G) || defined(CONFIG_EFM32_EFM32GG) +# define CMU_PCNTCTRL_PCNT1CLKEN (0x1UL << 2) /* PCNT1 Clock Enable */ +# define _CMU_PCNTCTRL_PCNT1CLKEN_SHIFT 2 /* Shift value for CMU_PCNT1CLKEN */ +# define _CMU_PCNTCTRL_PCNT1CLKEN_MASK 0x4UL /* Bit mask for CMU_PCNT1CLKEN */ +# define _CMU_PCNTCTRL_PCNT1CLKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT1CLKEN_DEFAULT (_CMU_PCNTCTRL_PCNT1CLKEN_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT1CLKSEL (0x1UL << 3) /* PCNT1 Clock Select */ +# define _CMU_PCNTCTRL_PCNT1CLKSEL_SHIFT 3 /* Shift value for CMU_PCNT1CLKSEL */ +# define _CMU_PCNTCTRL_PCNT1CLKSEL_MASK 0x8UL /* Bit mask for CMU_PCNT1CLKSEL */ +# define _CMU_PCNTCTRL_PCNT1CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +# define _CMU_PCNTCTRL_PCNT1CLKSEL_LFACLK 0x00000000UL /* Mode LFACLK for CMU_PCNTCTRL */ +# define _CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0 0x00000001UL /* Mode PCNT1S0 for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT1CLKSEL_DEFAULT (_CMU_PCNTCTRL_PCNT1CLKSEL_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT1CLKSEL_LFACLK (_CMU_PCNTCTRL_PCNT1CLKSEL_LFACLK << 3) /* Shifted mode LFACLK for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0 (_CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0 << 3) /* Shifted mode PCNT1S0 for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKEN (0x1UL << 4) /* PCNT2 Clock Enable */ +# define _CMU_PCNTCTRL_PCNT2CLKEN_SHIFT 4 /* Shift value for CMU_PCNT2CLKEN */ +# define _CMU_PCNTCTRL_PCNT2CLKEN_MASK 0x10UL /* Bit mask for CMU_PCNT2CLKEN */ +# define _CMU_PCNTCTRL_PCNT2CLKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKEN_DEFAULT (_CMU_PCNTCTRL_PCNT2CLKEN_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKSEL (0x1UL << 5) /* PCNT2 Clock Select */ +# define _CMU_PCNTCTRL_PCNT2CLKSEL_SHIFT 5 /* Shift value for CMU_PCNT2CLKSEL */ +# define _CMU_PCNTCTRL_PCNT2CLKSEL_MASK 0x20UL /* Bit mask for CMU_PCNT2CLKSEL */ +# define _CMU_PCNTCTRL_PCNT2CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_PCNTCTRL */ +# define _CMU_PCNTCTRL_PCNT2CLKSEL_LFACLK 0x00000000UL /* Mode LFACLK for CMU_PCNTCTRL */ +# define _CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0 0x00000001UL /* Mode PCNT2S0 for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKSEL_DEFAULT (_CMU_PCNTCTRL_PCNT2CLKSEL_DEFAULT << 5) /* Shifted mode DEFAULT for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKSEL_LFACLK (_CMU_PCNTCTRL_PCNT2CLKSEL_LFACLK << 5) /* Shifted mode LFACLK for CMU_PCNTCTRL */ +# define CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0 (_CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0 << 5) /* Shifted mode PCNT2S0 for CMU_PCNTCTRL */ +#endif + +/* Bit fields for CMU LCDCTRL */ + +#define _CMU_LCDCTRL_RESETVALUE 0x00000020UL /* Default value for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_MASK 0x0000007FUL /* Mask for CMU_LCDCTRL */ + +#define _CMU_LCDCTRL_FDIV_SHIFT 0 /* Shift value for CMU_FDIV */ +#define _CMU_LCDCTRL_FDIV_MASK 0x7UL /* Bit mask for CMU_FDIV */ +#define _CMU_LCDCTRL_FDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LCDCTRL */ +#define CMU_LCDCTRL_FDIV_DEFAULT (_CMU_LCDCTRL_FDIV_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBOOSTEN (0x1UL << 3) /* Voltage Boost Enable */ +#define _CMU_LCDCTRL_VBOOSTEN_SHIFT 3 /* Shift value for CMU_VBOOSTEN */ +#define _CMU_LCDCTRL_VBOOSTEN_MASK 0x8UL /* Bit mask for CMU_VBOOSTEN */ +#define _CMU_LCDCTRL_VBOOSTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBOOSTEN_DEFAULT (_CMU_LCDCTRL_VBOOSTEN_DEFAULT << 3) /* Shifted mode DEFAULT for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_SHIFT 4 /* Shift value for CMU_VBFDIV */ +#define _CMU_LCDCTRL_VBFDIV_MASK 0x70UL /* Bit mask for CMU_VBFDIV */ +#define _CMU_LCDCTRL_VBFDIV_DIV1 0x00000000UL /* Mode DIV1 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV2 0x00000001UL /* Mode DIV2 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DEFAULT 0x00000002UL /* Mode DEFAULT for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV4 0x00000002UL /* Mode DIV4 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV8 0x00000003UL /* Mode DIV8 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV16 0x00000004UL /* Mode DIV16 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV32 0x00000005UL /* Mode DIV32 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV64 0x00000006UL /* Mode DIV64 for CMU_LCDCTRL */ +#define _CMU_LCDCTRL_VBFDIV_DIV128 0x00000007UL /* Mode DIV128 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV1 (_CMU_LCDCTRL_VBFDIV_DIV1 << 4) /* Shifted mode DIV1 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV2 (_CMU_LCDCTRL_VBFDIV_DIV2 << 4) /* Shifted mode DIV2 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DEFAULT (_CMU_LCDCTRL_VBFDIV_DEFAULT << 4) /* Shifted mode DEFAULT for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV4 (_CMU_LCDCTRL_VBFDIV_DIV4 << 4) /* Shifted mode DIV4 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV8 (_CMU_LCDCTRL_VBFDIV_DIV8 << 4) /* Shifted mode DIV8 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV16 (_CMU_LCDCTRL_VBFDIV_DIV16 << 4) /* Shifted mode DIV16 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV32 (_CMU_LCDCTRL_VBFDIV_DIV32 << 4) /* Shifted mode DIV32 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV64 (_CMU_LCDCTRL_VBFDIV_DIV64 << 4) /* Shifted mode DIV64 for CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_DIV128 (_CMU_LCDCTRL_VBFDIV_DIV128 << 4) /* Shifted mode DIV128 for CMU_LCDCTRL */ + +/* Bit fields for CMU ROUTE */ + +#define _CMU_ROUTE_RESETVALUE 0x00000000UL /* Default value for CMU_ROUTE */ +#define _CMU_ROUTE_MASK 0x0000001FUL /* Mask for CMU_ROUTE */ + +#define CMU_ROUTE_CLKOUT0PEN (0x1UL << 0) /* CLKOUT0 Pin Enable */ +#define _CMU_ROUTE_CLKOUT0PEN_SHIFT 0 /* Shift value for CMU_CLKOUT0PEN */ +#define _CMU_ROUTE_CLKOUT0PEN_MASK 0x1UL /* Bit mask for CMU_CLKOUT0PEN */ +#define _CMU_ROUTE_CLKOUT0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_ROUTE */ +#define CMU_ROUTE_CLKOUT0PEN_DEFAULT (_CMU_ROUTE_CLKOUT0PEN_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_ROUTE */ +#define CMU_ROUTE_CLKOUT1PEN (0x1UL << 1) /* CLKOUT1 Pin Enable */ +#define _CMU_ROUTE_CLKOUT1PEN_SHIFT 1 /* Shift value for CMU_CLKOUT1PEN */ +#define _CMU_ROUTE_CLKOUT1PEN_MASK 0x2UL /* Bit mask for CMU_CLKOUT1PEN */ +#define _CMU_ROUTE_CLKOUT1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_ROUTE */ +#define CMU_ROUTE_CLKOUT1PEN_DEFAULT (_CMU_ROUTE_CLKOUT1PEN_DEFAULT << 1) /* Shifted mode DEFAULT for CMU_ROUTE */ +#define _CMU_ROUTE_LOCATION_SHIFT 2 /* Shift value for CMU_LOCATION */ +#define _CMU_ROUTE_LOCATION_MASK 0x1CUL /* Bit mask for CMU_LOCATION */ +#define _CMU_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for CMU_ROUTE */ +#define _CMU_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_ROUTE */ +#define _CMU_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for CMU_ROUTE */ +#define _CMU_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_LOC0 (_CMU_ROUTE_LOCATION_LOC0 << 2) /* Shifted mode LOC0 for CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_DEFAULT (_CMU_ROUTE_LOCATION_DEFAULT << 2) /* Shifted mode DEFAULT for CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_LOC1 (_CMU_ROUTE_LOCATION_LOC1 << 2) /* Shifted mode LOC1 for CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_LOC2 (_CMU_ROUTE_LOCATION_LOC2 << 2) /* Shifted mode LOC2 for CMU_ROUTE */ + +/* Bit fields for CMU LOCK */ + +#define _CMU_LOCK_RESETVALUE 0x00000000UL /* Default value for CMU_LOCK */ +#define _CMU_LOCK_MASK 0x0000FFFFUL /* Mask for CMU_LOCK */ + +#define _CMU_LOCK_LOCKKEY_SHIFT 0 /* Shift value for CMU_LOCKKEY */ +#define _CMU_LOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for CMU_LOCKKEY */ +#define _CMU_LOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for CMU_LOCK */ +#define _CMU_LOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for CMU_LOCK */ +#define _CMU_LOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for CMU_LOCK */ +#define _CMU_LOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for CMU_LOCK */ +#define _CMU_LOCK_LOCKKEY_UNLOCK 0x0000580EUL /* Mode UNLOCK for CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_DEFAULT (_CMU_LOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_LOCK (_CMU_LOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_UNLOCKED (_CMU_LOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_LOCKED (_CMU_LOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_UNLOCK (_CMU_LOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for CMU_LOCK */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_CMU_H */ diff --git a/arch/arm/src/efm32/chip/efm32_dac.h b/arch/arm/src/efm32/chip/efm32_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..58aec484dc08837ba7ce118aa4f99a82da690c7e --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_dac.h @@ -0,0 +1,883 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_dac.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DAC_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DAC_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* DAC Register Offsets ********************************************************************************************************/ + +#define EFM32_DAC_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_DAC_STATUS_OFFSET 0x0004 /* Status Register */ +#define EFM32_DAC_CH0CTRL_OFFSET 0x0008 /* Channel 0 Control Register */ +#define EFM32_DAC_CH1CTRL_OFFSET 0x000c /* Channel 1 Control Register */ +#define EFM32_DAC_IEN_OFFSET 0x0010 /* Interrupt Enable Register */ +#define EFM32_DAC_IF_OFFSET 0x0014 /* Interrupt Flag Register */ +#define EFM32_DAC_IFS_OFFSET 0x0018 /* Interrupt Flag Set Register */ +#define EFM32_DAC_IFC_OFFSET 0x001c /* Interrupt Flag Clear Register */ +#define EFM32_DAC_CH0DATA_OFFSET 0x0020 /* Channel 0 Data Register */ +#define EFM32_DAC_CH1DATA_OFFSET 0x0024 /* Channel 1 Data Register */ +#define EFM32_DAC_COMBDATA_OFFSET 0x0028 /* Combined Data Register */ +#define EFM32_DAC_CAL_OFFSET 0x002c /* Calibration Register */ +#define EFM32_DAC_BIASPROG_OFFSET 0x0030 /* Bias Programming Register */ +#define EFM32_DAC_OPACTRL_OFFSET 0x0054 /* Operational Amplifier Control Register */ +#define EFM32_DAC_OPAOFFSET_OFFSET 0x0058 /* Operational Amplifier Offset Register */ +#define EFM32_DAC_OPA0MUX_OFFSET 0x005c /* Operational Amplifier Mux Configuration Register */ +#define EFM32_DAC_OPA1MUX_OFFSET 0x0060 /* Operational Amplifier Mux Configuration Register */ +#define EFM32_DAC_OPA2MUX_OFFSET 0x0064 /* Operational Amplifier Mux Configuration Register */ + +/* DAC Register Addresses ******************************************************************************************************/ + +#define EFM32_DAC0_CTRL (EFM32_DAC0_BASE+EFM32_DAC_CTRL_OFFSET) +#define EFM32_DAC0_STATUS (EFM32_DAC0_BASE+EFM32_DAC_STATUS_OFFSET) +#define EFM32_DAC0_CH0CTRL (EFM32_DAC0_BASE+EFM32_DAC_CH0CTRL_OFFSET) +#define EFM32_DAC0_CH1CTRL (EFM32_DAC0_BASE+EFM32_DAC_CH1CTRL_OFFSET) +#define EFM32_DAC0_IEN (EFM32_DAC0_BASE+EFM32_DAC_IEN_OFFSET) +#define EFM32_DAC0_IF (EFM32_DAC0_BASE+EFM32_DAC_IF_OFFSET) +#define EFM32_DAC0_IFS (EFM32_DAC0_BASE+EFM32_DAC_IFS_OFFSET) +#define EFM32_DAC0_IFC (EFM32_DAC0_BASE+EFM32_DAC_IFC_OFFSET) +#define EFM32_DAC0_CH0DATA (EFM32_DAC0_BASE+EFM32_DAC_CH0DATA_OFFSET) +#define EFM32_DAC0_CH1DATA (EFM32_DAC0_BASE+EFM32_DAC_CH1DATA_OFFSET) +#define EFM32_DAC0_COMBDATA (EFM32_DAC0_BASE+EFM32_DAC_COMBDATA_OFFSET) +#define EFM32_DAC0_CAL (EFM32_DAC0_BASE+EFM32_DAC_CAL_OFFSET) +#define EFM32_DAC0_BIASPROG (EFM32_DAC0_BASE+EFM32_DAC_BIASPROG_OFFSET) +#define EFM32_DAC0_OPACTRL (EFM32_DAC0_BASE+EFM32_DAC_OPACTRL_OFFSET) +#define EFM32_DAC0_OPAOFFSET (EFM32_DAC0_BASE+EFM32_DAC_OPAOFFSET_OFFSET) +#define EFM32_DAC0_OPA0MUX (EFM32_DAC0_BASE+EFM32_DAC_OPA0MUX_OFFSET) +#define EFM32_DAC0_OPA1MUX (EFM32_DAC0_BASE+EFM32_DAC_OPA1MUX_OFFSET) +#define EFM32_DAC0_OPA2MUX (EFM32_DAC0_BASE+EFM32_DAC_OPA2MUX_OFFSET) + +/* DAC Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for DAC CTRL */ + +#define _DAC_CTRL_RESETVALUE 0x00000010UL /* Default value for DAC_CTRL */ +#define _DAC_CTRL_MASK 0x003703FFUL /* Mask for DAC_CTRL */ + +#define DAC_CTRL_DIFF (0x1UL << 0) /* Differential Mode */ +#define _DAC_CTRL_DIFF_SHIFT 0 /* Shift value for DAC_DIFF */ +#define _DAC_CTRL_DIFF_MASK 0x1UL /* Bit mask for DAC_DIFF */ +#define _DAC_CTRL_DIFF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_DIFF_DEFAULT (_DAC_CTRL_DIFF_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_SINEMODE (0x1UL << 1) /* Sine Mode */ +#define _DAC_CTRL_SINEMODE_SHIFT 1 /* Shift value for DAC_SINEMODE */ +#define _DAC_CTRL_SINEMODE_MASK 0x2UL /* Bit mask for DAC_SINEMODE */ +#define _DAC_CTRL_SINEMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_SINEMODE_DEFAULT (_DAC_CTRL_SINEMODE_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_CONVMODE_SHIFT 2 /* Shift value for DAC_CONVMODE */ +#define _DAC_CTRL_CONVMODE_MASK 0xCUL /* Bit mask for DAC_CONVMODE */ +#define _DAC_CTRL_CONVMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_CONVMODE_CONTINUOUS 0x00000000UL /* Mode CONTINUOUS for DAC_CTRL */ +#define _DAC_CTRL_CONVMODE_SAMPLEHOLD 0x00000001UL /* Mode SAMPLEHOLD for DAC_CTRL */ +#define _DAC_CTRL_CONVMODE_SAMPLEOFF 0x00000002UL /* Mode SAMPLEOFF for DAC_CTRL */ +#define DAC_CTRL_CONVMODE_DEFAULT (_DAC_CTRL_CONVMODE_DEFAULT << 2) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_CONVMODE_CONTINUOUS (_DAC_CTRL_CONVMODE_CONTINUOUS << 2) /* Shifted mode CONTINUOUS for DAC_CTRL */ +#define DAC_CTRL_CONVMODE_SAMPLEHOLD (_DAC_CTRL_CONVMODE_SAMPLEHOLD << 2) /* Shifted mode SAMPLEHOLD for DAC_CTRL */ +#define DAC_CTRL_CONVMODE_SAMPLEOFF (_DAC_CTRL_CONVMODE_SAMPLEOFF << 2) /* Shifted mode SAMPLEOFF for DAC_CTRL */ +#define _DAC_CTRL_OUTMODE_SHIFT 4 /* Shift value for DAC_OUTMODE */ +#define _DAC_CTRL_OUTMODE_MASK 0x30UL /* Bit mask for DAC_OUTMODE */ +#define _DAC_CTRL_OUTMODE_DISABLE 0x00000000UL /* Mode DISABLE for DAC_CTRL */ +#define _DAC_CTRL_OUTMODE_DEFAULT 0x00000001UL /* Mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_OUTMODE_PIN 0x00000001UL /* Mode PIN for DAC_CTRL */ +#define _DAC_CTRL_OUTMODE_ADC 0x00000002UL /* Mode ADC for DAC_CTRL */ +#define _DAC_CTRL_OUTMODE_PINADC 0x00000003UL /* Mode PINADC for DAC_CTRL */ +#define DAC_CTRL_OUTMODE_DISABLE (_DAC_CTRL_OUTMODE_DISABLE << 4) /* Shifted mode DISABLE for DAC_CTRL */ +#define DAC_CTRL_OUTMODE_DEFAULT (_DAC_CTRL_OUTMODE_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_OUTMODE_PIN (_DAC_CTRL_OUTMODE_PIN << 4) /* Shifted mode PIN for DAC_CTRL */ +#define DAC_CTRL_OUTMODE_ADC (_DAC_CTRL_OUTMODE_ADC << 4) /* Shifted mode ADC for DAC_CTRL */ +#define DAC_CTRL_OUTMODE_PINADC (_DAC_CTRL_OUTMODE_PINADC << 4) /* Shifted mode PINADC for DAC_CTRL */ +#define DAC_CTRL_OUTENPRS (0x1UL << 6) /* PRS Controlled Output Enable */ +#define _DAC_CTRL_OUTENPRS_SHIFT 6 /* Shift value for DAC_OUTENPRS */ +#define _DAC_CTRL_OUTENPRS_MASK 0x40UL /* Bit mask for DAC_OUTENPRS */ +#define _DAC_CTRL_OUTENPRS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_OUTENPRS_DEFAULT (_DAC_CTRL_OUTENPRS_DEFAULT << 6) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_CH0PRESCRST (0x1UL << 7) /* Channel 0 Start Reset Prescaler */ +#define _DAC_CTRL_CH0PRESCRST_SHIFT 7 /* Shift value for DAC_CH0PRESCRST */ +#define _DAC_CTRL_CH0PRESCRST_MASK 0x80UL /* Bit mask for DAC_CH0PRESCRST */ +#define _DAC_CTRL_CH0PRESCRST_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_CH0PRESCRST_DEFAULT (_DAC_CTRL_CH0PRESCRST_DEFAULT << 7) /* Shifted mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_REFSEL_SHIFT 8 /* Shift value for DAC_REFSEL */ +#define _DAC_CTRL_REFSEL_MASK 0x300UL /* Bit mask for DAC_REFSEL */ +#define _DAC_CTRL_REFSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_REFSEL_1V25 0x00000000UL /* Mode 1V25 for DAC_CTRL */ +#define _DAC_CTRL_REFSEL_2V5 0x00000001UL /* Mode 2V5 for DAC_CTRL */ +#define _DAC_CTRL_REFSEL_VDD 0x00000002UL /* Mode VDD for DAC_CTRL */ +#define DAC_CTRL_REFSEL_DEFAULT (_DAC_CTRL_REFSEL_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_REFSEL_1V25 (_DAC_CTRL_REFSEL_1V25 << 8) /* Shifted mode 1V25 for DAC_CTRL */ +#define DAC_CTRL_REFSEL_2V5 (_DAC_CTRL_REFSEL_2V5 << 8) /* Shifted mode 2V5 for DAC_CTRL */ +#define DAC_CTRL_REFSEL_VDD (_DAC_CTRL_REFSEL_VDD << 8) /* Shifted mode VDD for DAC_CTRL */ +#define _DAC_CTRL_PRESC_SHIFT 16 /* Shift value for DAC_PRESC */ +#define _DAC_CTRL_PRESC_MASK 0x70000UL /* Bit mask for DAC_PRESC */ +#define _DAC_CTRL_PRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_PRESC_NODIVISION 0x00000000UL /* Mode NODIVISION for DAC_CTRL */ +#define DAC_CTRL_PRESC_DEFAULT (_DAC_CTRL_PRESC_DEFAULT << 16) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_PRESC_NODIVISION (_DAC_CTRL_PRESC_NODIVISION << 16) /* Shifted mode NODIVISION for DAC_CTRL */ +#define _DAC_CTRL_REFRSEL_SHIFT 20 /* Shift value for DAC_REFRSEL */ +#define _DAC_CTRL_REFRSEL_MASK 0x300000UL /* Bit mask for DAC_REFRSEL */ +#define _DAC_CTRL_REFRSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CTRL */ +#define _DAC_CTRL_REFRSEL_8CYCLES 0x00000000UL /* Mode 8CYCLES for DAC_CTRL */ +#define _DAC_CTRL_REFRSEL_16CYCLES 0x00000001UL /* Mode 16CYCLES for DAC_CTRL */ +#define _DAC_CTRL_REFRSEL_32CYCLES 0x00000002UL /* Mode 32CYCLES for DAC_CTRL */ +#define _DAC_CTRL_REFRSEL_64CYCLES 0x00000003UL /* Mode 64CYCLES for DAC_CTRL */ +#define DAC_CTRL_REFRSEL_DEFAULT (_DAC_CTRL_REFRSEL_DEFAULT << 20) /* Shifted mode DEFAULT for DAC_CTRL */ +#define DAC_CTRL_REFRSEL_8CYCLES (_DAC_CTRL_REFRSEL_8CYCLES << 20) /* Shifted mode 8CYCLES for DAC_CTRL */ +#define DAC_CTRL_REFRSEL_16CYCLES (_DAC_CTRL_REFRSEL_16CYCLES << 20) /* Shifted mode 16CYCLES for DAC_CTRL */ +#define DAC_CTRL_REFRSEL_32CYCLES (_DAC_CTRL_REFRSEL_32CYCLES << 20) /* Shifted mode 32CYCLES for DAC_CTRL */ +#define DAC_CTRL_REFRSEL_64CYCLES (_DAC_CTRL_REFRSEL_64CYCLES << 20) /* Shifted mode 64CYCLES for DAC_CTRL */ + +/* Bit fields for DAC STATUS */ + +#define _DAC_STATUS_RESETVALUE 0x00000000UL /* Default value for DAC_STATUS */ +#define _DAC_STATUS_MASK 0x00000003UL /* Mask for DAC_STATUS */ + +#define DAC_STATUS_CH0DV (0x1UL << 0) /* Channel 0 Data Valid */ +#define _DAC_STATUS_CH0DV_SHIFT 0 /* Shift value for DAC_CH0DV */ +#define _DAC_STATUS_CH0DV_MASK 0x1UL /* Bit mask for DAC_CH0DV */ +#define _DAC_STATUS_CH0DV_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_STATUS */ +#define DAC_STATUS_CH0DV_DEFAULT (_DAC_STATUS_CH0DV_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_STATUS */ +#define DAC_STATUS_CH1DV (0x1UL << 1) /* Channel 1 Data Valid */ +#define _DAC_STATUS_CH1DV_SHIFT 1 /* Shift value for DAC_CH1DV */ +#define _DAC_STATUS_CH1DV_MASK 0x2UL /* Bit mask for DAC_CH1DV */ +#define _DAC_STATUS_CH1DV_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_STATUS */ +#define DAC_STATUS_CH1DV_DEFAULT (_DAC_STATUS_CH1DV_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_STATUS */ + +/* Bit fields for DAC CH0CTRL */ + +#define _DAC_CH0CTRL_RESETVALUE 0x00000000UL /* Default value for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_MASK 0x000000F7UL /* Mask for DAC_CH0CTRL */ + +#define DAC_CH0CTRL_EN (0x1UL << 0) /* Channel 0 Enable */ +#define _DAC_CH0CTRL_EN_SHIFT 0 /* Shift value for DAC_EN */ +#define _DAC_CH0CTRL_EN_MASK 0x1UL /* Bit mask for DAC_EN */ +#define _DAC_CH0CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_EN_DEFAULT (_DAC_CH0CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_REFREN (0x1UL << 1) /* Channel 0 Automatic Refresh Enable */ +#define _DAC_CH0CTRL_REFREN_SHIFT 1 /* Shift value for DAC_REFREN */ +#define _DAC_CH0CTRL_REFREN_MASK 0x2UL /* Bit mask for DAC_REFREN */ +#define _DAC_CH0CTRL_REFREN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_REFREN_DEFAULT (_DAC_CH0CTRL_REFREN_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSEN (0x1UL << 2) /* Channel 0 PRS Trigger Enable */ +#define _DAC_CH0CTRL_PRSEN_SHIFT 2 /* Shift value for DAC_PRSEN */ +#define _DAC_CH0CTRL_PRSEN_MASK 0x4UL /* Bit mask for DAC_PRSEN */ +#define _DAC_CH0CTRL_PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSEN_DEFAULT (_DAC_CH0CTRL_PRSEN_DEFAULT << 2) /* Shifted mode DEFAULT for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_SHIFT 4 /* Shift value for DAC_PRSSEL */ +#define _DAC_CH0CTRL_PRSSEL_MASK 0xF0UL /* Bit mask for DAC_PRSSEL */ +#define _DAC_CH0CTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for DAC_CH0CTRL */ +#define _DAC_CH0CTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_DEFAULT (_DAC_CH0CTRL_PRSSEL_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH0 (_DAC_CH0CTRL_PRSSEL_PRSCH0 << 4) /* Shifted mode PRSCH0 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH1 (_DAC_CH0CTRL_PRSSEL_PRSCH1 << 4) /* Shifted mode PRSCH1 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH2 (_DAC_CH0CTRL_PRSSEL_PRSCH2 << 4) /* Shifted mode PRSCH2 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH3 (_DAC_CH0CTRL_PRSSEL_PRSCH3 << 4) /* Shifted mode PRSCH3 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH4 (_DAC_CH0CTRL_PRSSEL_PRSCH4 << 4) /* Shifted mode PRSCH4 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH5 (_DAC_CH0CTRL_PRSSEL_PRSCH5 << 4) /* Shifted mode PRSCH5 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH6 (_DAC_CH0CTRL_PRSSEL_PRSCH6 << 4) /* Shifted mode PRSCH6 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH7 (_DAC_CH0CTRL_PRSSEL_PRSCH7 << 4) /* Shifted mode PRSCH7 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH8 (_DAC_CH0CTRL_PRSSEL_PRSCH8 << 4) /* Shifted mode PRSCH8 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH9 (_DAC_CH0CTRL_PRSSEL_PRSCH9 << 4) /* Shifted mode PRSCH9 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH10 (_DAC_CH0CTRL_PRSSEL_PRSCH10 << 4) /* Shifted mode PRSCH10 for DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_PRSCH11 (_DAC_CH0CTRL_PRSSEL_PRSCH11 << 4) /* Shifted mode PRSCH11 for DAC_CH0CTRL */ + +/* Bit fields for DAC CH1CTRL */ + +#define _DAC_CH1CTRL_RESETVALUE 0x00000000UL /* Default value for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_MASK 0x000000F7UL /* Mask for DAC_CH1CTRL */ + +#define DAC_CH1CTRL_EN (0x1UL << 0) /* Channel 1 Enable */ +#define _DAC_CH1CTRL_EN_SHIFT 0 /* Shift value for DAC_EN */ +#define _DAC_CH1CTRL_EN_MASK 0x1UL /* Bit mask for DAC_EN */ +#define _DAC_CH1CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_EN_DEFAULT (_DAC_CH1CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_REFREN (0x1UL << 1) /* Channel 1 Automatic Refresh Enable */ +#define _DAC_CH1CTRL_REFREN_SHIFT 1 /* Shift value for DAC_REFREN */ +#define _DAC_CH1CTRL_REFREN_MASK 0x2UL /* Bit mask for DAC_REFREN */ +#define _DAC_CH1CTRL_REFREN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_REFREN_DEFAULT (_DAC_CH1CTRL_REFREN_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSEN (0x1UL << 2) /* Channel 1 PRS Trigger Enable */ +#define _DAC_CH1CTRL_PRSEN_SHIFT 2 /* Shift value for DAC_PRSEN */ +#define _DAC_CH1CTRL_PRSEN_MASK 0x4UL /* Bit mask for DAC_PRSEN */ +#define _DAC_CH1CTRL_PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSEN_DEFAULT (_DAC_CH1CTRL_PRSEN_DEFAULT << 2) /* Shifted mode DEFAULT for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_SHIFT 4 /* Shift value for DAC_PRSSEL */ +#define _DAC_CH1CTRL_PRSSEL_MASK 0xF0UL /* Bit mask for DAC_PRSSEL */ +#define _DAC_CH1CTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for DAC_CH1CTRL */ +#define _DAC_CH1CTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_DEFAULT (_DAC_CH1CTRL_PRSSEL_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH0 (_DAC_CH1CTRL_PRSSEL_PRSCH0 << 4) /* Shifted mode PRSCH0 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH1 (_DAC_CH1CTRL_PRSSEL_PRSCH1 << 4) /* Shifted mode PRSCH1 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH2 (_DAC_CH1CTRL_PRSSEL_PRSCH2 << 4) /* Shifted mode PRSCH2 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH3 (_DAC_CH1CTRL_PRSSEL_PRSCH3 << 4) /* Shifted mode PRSCH3 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH4 (_DAC_CH1CTRL_PRSSEL_PRSCH4 << 4) /* Shifted mode PRSCH4 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH5 (_DAC_CH1CTRL_PRSSEL_PRSCH5 << 4) /* Shifted mode PRSCH5 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH6 (_DAC_CH1CTRL_PRSSEL_PRSCH6 << 4) /* Shifted mode PRSCH6 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH7 (_DAC_CH1CTRL_PRSSEL_PRSCH7 << 4) /* Shifted mode PRSCH7 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH8 (_DAC_CH1CTRL_PRSSEL_PRSCH8 << 4) /* Shifted mode PRSCH8 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH9 (_DAC_CH1CTRL_PRSSEL_PRSCH9 << 4) /* Shifted mode PRSCH9 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH10 (_DAC_CH1CTRL_PRSSEL_PRSCH10 << 4) /* Shifted mode PRSCH10 for DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_PRSCH11 (_DAC_CH1CTRL_PRSSEL_PRSCH11 << 4) /* Shifted mode PRSCH11 for DAC_CH1CTRL */ + +/* Bit fields for DAC IEN */ + +#define _DAC_IEN_RESETVALUE 0x00000000UL /* Default value for DAC_IEN */ +#define _DAC_IEN_MASK 0x00000033UL /* Mask for DAC_IEN */ + +#define DAC_IEN_CH0 (0x1UL << 0) /* Channel 0 Conversion Complete Interrupt Enable */ +#define _DAC_IEN_CH0_SHIFT 0 /* Shift value for DAC_CH0 */ +#define _DAC_IEN_CH0_MASK 0x1UL /* Bit mask for DAC_CH0 */ +#define _DAC_IEN_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH0_DEFAULT (_DAC_IEN_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH1 (0x1UL << 1) /* Channel 1 Conversion Complete Interrupt Enable */ +#define _DAC_IEN_CH1_SHIFT 1 /* Shift value for DAC_CH1 */ +#define _DAC_IEN_CH1_MASK 0x2UL /* Bit mask for DAC_CH1 */ +#define _DAC_IEN_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH1_DEFAULT (_DAC_IEN_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH0UF (0x1UL << 4) /* Channel 0 Conversion Data Underflow Interrupt Enable */ +#define _DAC_IEN_CH0UF_SHIFT 4 /* Shift value for DAC_CH0UF */ +#define _DAC_IEN_CH0UF_MASK 0x10UL /* Bit mask for DAC_CH0UF */ +#define _DAC_IEN_CH0UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH0UF_DEFAULT (_DAC_IEN_CH0UF_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH1UF (0x1UL << 5) /* Channel 1 Conversion Data Underflow Interrupt Enable */ +#define _DAC_IEN_CH1UF_SHIFT 5 /* Shift value for DAC_CH1UF */ +#define _DAC_IEN_CH1UF_MASK 0x20UL /* Bit mask for DAC_CH1UF */ +#define _DAC_IEN_CH1UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IEN */ +#define DAC_IEN_CH1UF_DEFAULT (_DAC_IEN_CH1UF_DEFAULT << 5) /* Shifted mode DEFAULT for DAC_IEN */ + +/* Bit fields for DAC IF */ + +#define _DAC_IF_RESETVALUE 0x00000000UL /* Default value for DAC_IF */ +#define _DAC_IF_MASK 0x00000033UL /* Mask for DAC_IF */ + +#define DAC_IF_CH0 (0x1UL << 0) /* Channel 0 Conversion Complete Interrupt Flag */ +#define _DAC_IF_CH0_SHIFT 0 /* Shift value for DAC_CH0 */ +#define _DAC_IF_CH0_MASK 0x1UL /* Bit mask for DAC_CH0 */ +#define _DAC_IF_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IF */ +#define DAC_IF_CH0_DEFAULT (_DAC_IF_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_IF */ +#define DAC_IF_CH1 (0x1UL << 1) /* Channel 1 Conversion Complete Interrupt Flag */ +#define _DAC_IF_CH1_SHIFT 1 /* Shift value for DAC_CH1 */ +#define _DAC_IF_CH1_MASK 0x2UL /* Bit mask for DAC_CH1 */ +#define _DAC_IF_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IF */ +#define DAC_IF_CH1_DEFAULT (_DAC_IF_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_IF */ +#define DAC_IF_CH0UF (0x1UL << 4) /* Channel 0 Data Underflow Interrupt Flag */ +#define _DAC_IF_CH0UF_SHIFT 4 /* Shift value for DAC_CH0UF */ +#define _DAC_IF_CH0UF_MASK 0x10UL /* Bit mask for DAC_CH0UF */ +#define _DAC_IF_CH0UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IF */ +#define DAC_IF_CH0UF_DEFAULT (_DAC_IF_CH0UF_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_IF */ +#define DAC_IF_CH1UF (0x1UL << 5) /* Channel 1 Data Underflow Interrupt Flag */ +#define _DAC_IF_CH1UF_SHIFT 5 /* Shift value for DAC_CH1UF */ +#define _DAC_IF_CH1UF_MASK 0x20UL /* Bit mask for DAC_CH1UF */ +#define _DAC_IF_CH1UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IF */ +#define DAC_IF_CH1UF_DEFAULT (_DAC_IF_CH1UF_DEFAULT << 5) /* Shifted mode DEFAULT for DAC_IF */ + +/* Bit fields for DAC IFS */ + +#define _DAC_IFS_RESETVALUE 0x00000000UL /* Default value for DAC_IFS */ +#define _DAC_IFS_MASK 0x00000033UL /* Mask for DAC_IFS */ + +#define DAC_IFS_CH0 (0x1UL << 0) /* Channel 0 Conversion Complete Interrupt Flag Set */ +#define _DAC_IFS_CH0_SHIFT 0 /* Shift value for DAC_CH0 */ +#define _DAC_IFS_CH0_MASK 0x1UL /* Bit mask for DAC_CH0 */ +#define _DAC_IFS_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH0_DEFAULT (_DAC_IFS_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH1 (0x1UL << 1) /* Channel 1 Conversion Complete Interrupt Flag Set */ +#define _DAC_IFS_CH1_SHIFT 1 /* Shift value for DAC_CH1 */ +#define _DAC_IFS_CH1_MASK 0x2UL /* Bit mask for DAC_CH1 */ +#define _DAC_IFS_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH1_DEFAULT (_DAC_IFS_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH0UF (0x1UL << 4) /* Channel 0 Data Underflow Interrupt Flag Set */ +#define _DAC_IFS_CH0UF_SHIFT 4 /* Shift value for DAC_CH0UF */ +#define _DAC_IFS_CH0UF_MASK 0x10UL /* Bit mask for DAC_CH0UF */ +#define _DAC_IFS_CH0UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH0UF_DEFAULT (_DAC_IFS_CH0UF_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH1UF (0x1UL << 5) /* Channel 1 Data Underflow Interrupt Flag Set */ +#define _DAC_IFS_CH1UF_SHIFT 5 /* Shift value for DAC_CH1UF */ +#define _DAC_IFS_CH1UF_MASK 0x20UL /* Bit mask for DAC_CH1UF */ +#define _DAC_IFS_CH1UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFS */ +#define DAC_IFS_CH1UF_DEFAULT (_DAC_IFS_CH1UF_DEFAULT << 5) /* Shifted mode DEFAULT for DAC_IFS */ + +/* Bit fields for DAC IFC */ + +#define _DAC_IFC_RESETVALUE 0x00000000UL /* Default value for DAC_IFC */ +#define _DAC_IFC_MASK 0x00000033UL /* Mask for DAC_IFC */ + +#define DAC_IFC_CH0 (0x1UL << 0) /* Channel 0 Conversion Complete Interrupt Flag Clear */ +#define _DAC_IFC_CH0_SHIFT 0 /* Shift value for DAC_CH0 */ +#define _DAC_IFC_CH0_MASK 0x1UL /* Bit mask for DAC_CH0 */ +#define _DAC_IFC_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH0_DEFAULT (_DAC_IFC_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH1 (0x1UL << 1) /* Channel 1 Conversion Complete Interrupt Flag Clear */ +#define _DAC_IFC_CH1_SHIFT 1 /* Shift value for DAC_CH1 */ +#define _DAC_IFC_CH1_MASK 0x2UL /* Bit mask for DAC_CH1 */ +#define _DAC_IFC_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH1_DEFAULT (_DAC_IFC_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH0UF (0x1UL << 4) /* Channel 0 Data Underflow Interrupt Flag Clear */ +#define _DAC_IFC_CH0UF_SHIFT 4 /* Shift value for DAC_CH0UF */ +#define _DAC_IFC_CH0UF_MASK 0x10UL /* Bit mask for DAC_CH0UF */ +#define _DAC_IFC_CH0UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH0UF_DEFAULT (_DAC_IFC_CH0UF_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH1UF (0x1UL << 5) /* Channel 1 Data Underflow Interrupt Flag Clear */ +#define _DAC_IFC_CH1UF_SHIFT 5 /* Shift value for DAC_CH1UF */ +#define _DAC_IFC_CH1UF_MASK 0x20UL /* Bit mask for DAC_CH1UF */ +#define _DAC_IFC_CH1UF_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_IFC */ +#define DAC_IFC_CH1UF_DEFAULT (_DAC_IFC_CH1UF_DEFAULT << 5) /* Shifted mode DEFAULT for DAC_IFC */ + +/* Bit fields for DAC CH0DATA */ + +#define _DAC_CH0DATA_RESETVALUE 0x00000000UL /* Default value for DAC_CH0DATA */ +#define _DAC_CH0DATA_MASK 0x00000FFFUL /* Mask for DAC_CH0DATA */ + +#define _DAC_CH0DATA_DATA_SHIFT 0 /* Shift value for DAC_DATA */ +#define _DAC_CH0DATA_DATA_MASK 0xFFFUL /* Bit mask for DAC_DATA */ +#define _DAC_CH0DATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH0DATA */ +#define DAC_CH0DATA_DATA_DEFAULT (_DAC_CH0DATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CH0DATA */ + +/* Bit fields for DAC CH1DATA */ + +#define _DAC_CH1DATA_RESETVALUE 0x00000000UL /* Default value for DAC_CH1DATA */ +#define _DAC_CH1DATA_MASK 0x00000FFFUL /* Mask for DAC_CH1DATA */ + +#define _DAC_CH1DATA_DATA_SHIFT 0 /* Shift value for DAC_DATA */ +#define _DAC_CH1DATA_DATA_MASK 0xFFFUL /* Bit mask for DAC_DATA */ +#define _DAC_CH1DATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CH1DATA */ +#define DAC_CH1DATA_DATA_DEFAULT (_DAC_CH1DATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CH1DATA */ + +/* Bit fields for DAC COMBDATA */ + +#define _DAC_COMBDATA_RESETVALUE 0x00000000UL /* Default value for DAC_COMBDATA */ +#define _DAC_COMBDATA_MASK 0x0FFF0FFFUL /* Mask for DAC_COMBDATA */ + +#define _DAC_COMBDATA_CH0DATA_SHIFT 0 /* Shift value for DAC_CH0DATA */ +#define _DAC_COMBDATA_CH0DATA_MASK 0xFFFUL /* Bit mask for DAC_CH0DATA */ +#define _DAC_COMBDATA_CH0DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_COMBDATA */ +#define DAC_COMBDATA_CH0DATA_DEFAULT (_DAC_COMBDATA_CH0DATA_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_COMBDATA */ +#define _DAC_COMBDATA_CH1DATA_SHIFT 16 /* Shift value for DAC_CH1DATA */ +#define _DAC_COMBDATA_CH1DATA_MASK 0xFFF0000UL /* Bit mask for DAC_CH1DATA */ +#define _DAC_COMBDATA_CH1DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_COMBDATA */ +#define DAC_COMBDATA_CH1DATA_DEFAULT (_DAC_COMBDATA_CH1DATA_DEFAULT << 16) /* Shifted mode DEFAULT for DAC_COMBDATA */ + +/* Bit fields for DAC CAL */ + +#define _DAC_CAL_RESETVALUE 0x00400000UL /* Default value for DAC_CAL */ +#define _DAC_CAL_MASK 0x007F3F3FUL /* Mask for DAC_CAL */ + +#define _DAC_CAL_CH0OFFSET_SHIFT 0 /* Shift value for DAC_CH0OFFSET */ +#define _DAC_CAL_CH0OFFSET_MASK 0x3FUL /* Bit mask for DAC_CH0OFFSET */ +#define _DAC_CAL_CH0OFFSET_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CAL */ +#define DAC_CAL_CH0OFFSET_DEFAULT (_DAC_CAL_CH0OFFSET_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_CAL */ +#define _DAC_CAL_CH1OFFSET_SHIFT 8 /* Shift value for DAC_CH1OFFSET */ +#define _DAC_CAL_CH1OFFSET_MASK 0x3F00UL /* Bit mask for DAC_CH1OFFSET */ +#define _DAC_CAL_CH1OFFSET_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_CAL */ +#define DAC_CAL_CH1OFFSET_DEFAULT (_DAC_CAL_CH1OFFSET_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_CAL */ +#define _DAC_CAL_GAIN_SHIFT 16 /* Shift value for DAC_GAIN */ +#define _DAC_CAL_GAIN_MASK 0x7F0000UL /* Bit mask for DAC_GAIN */ +#define _DAC_CAL_GAIN_DEFAULT 0x00000040UL /* Mode DEFAULT for DAC_CAL */ +#define DAC_CAL_GAIN_DEFAULT (_DAC_CAL_GAIN_DEFAULT << 16) /* Shifted mode DEFAULT for DAC_CAL */ + +/* Bit fields for DAC BIASPROG */ + +#define _DAC_BIASPROG_RESETVALUE 0x00004747UL /* Default value for DAC_BIASPROG */ +#define _DAC_BIASPROG_MASK 0x00004F4FUL /* Mask for DAC_BIASPROG */ + +#define _DAC_BIASPROG_BIASPROG_SHIFT 0 /* Shift value for DAC_BIASPROG */ +#define _DAC_BIASPROG_BIASPROG_MASK 0xFUL /* Bit mask for DAC_BIASPROG */ +#define _DAC_BIASPROG_BIASPROG_DEFAULT 0x00000007UL /* Mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_BIASPROG_DEFAULT (_DAC_BIASPROG_BIASPROG_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_HALFBIAS (0x1UL << 6) /* Half Bias Current */ +#define _DAC_BIASPROG_HALFBIAS_SHIFT 6 /* Shift value for DAC_HALFBIAS */ +#define _DAC_BIASPROG_HALFBIAS_MASK 0x40UL /* Bit mask for DAC_HALFBIAS */ +#define _DAC_BIASPROG_HALFBIAS_DEFAULT 0x00000001UL /* Mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_HALFBIAS_DEFAULT (_DAC_BIASPROG_HALFBIAS_DEFAULT << 6) /* Shifted mode DEFAULT for DAC_BIASPROG */ +#define _DAC_BIASPROG_OPA2BIASPROG_SHIFT 8 /* Shift value for DAC_OPA2BIASPROG */ +#define _DAC_BIASPROG_OPA2BIASPROG_MASK 0xF00UL /* Bit mask for DAC_OPA2BIASPROG */ +#define _DAC_BIASPROG_OPA2BIASPROG_DEFAULT 0x00000007UL /* Mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_OPA2BIASPROG_DEFAULT (_DAC_BIASPROG_OPA2BIASPROG_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_OPA2HALFBIAS (0x1UL << 14) /* Half Bias Current */ +#define _DAC_BIASPROG_OPA2HALFBIAS_SHIFT 14 /* Shift value for DAC_OPA2HALFBIAS */ +#define _DAC_BIASPROG_OPA2HALFBIAS_MASK 0x4000UL /* Bit mask for DAC_OPA2HALFBIAS */ +#define _DAC_BIASPROG_OPA2HALFBIAS_DEFAULT 0x00000001UL /* Mode DEFAULT for DAC_BIASPROG */ +#define DAC_BIASPROG_OPA2HALFBIAS_DEFAULT (_DAC_BIASPROG_OPA2HALFBIAS_DEFAULT << 14) /* Shifted mode DEFAULT for DAC_BIASPROG */ + +/* Bit fields for DAC OPACTRL */ + +#define _DAC_OPACTRL_RESETVALUE 0x00000000UL /* Default value for DAC_OPACTRL */ +#define _DAC_OPACTRL_MASK 0x01C3F1C7UL /* Mask for DAC_OPACTRL */ + +#define DAC_OPACTRL_OPA0EN (0x1UL << 0) /* OPA0 Enable */ +#define _DAC_OPACTRL_OPA0EN_SHIFT 0 /* Shift value for DAC_OPA0EN */ +#define _DAC_OPACTRL_OPA0EN_MASK 0x1UL /* Bit mask for DAC_OPA0EN */ +#define _DAC_OPACTRL_OPA0EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0EN_DEFAULT (_DAC_OPACTRL_OPA0EN_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1EN (0x1UL << 1) /* OPA1 Enable */ +#define _DAC_OPACTRL_OPA1EN_SHIFT 1 /* Shift value for DAC_OPA1EN */ +#define _DAC_OPACTRL_OPA1EN_MASK 0x2UL /* Bit mask for DAC_OPA1EN */ +#define _DAC_OPACTRL_OPA1EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1EN_DEFAULT (_DAC_OPACTRL_OPA1EN_DEFAULT << 1) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2EN (0x1UL << 2) /* OPA2 Enable */ +#define _DAC_OPACTRL_OPA2EN_SHIFT 2 /* Shift value for DAC_OPA2EN */ +#define _DAC_OPACTRL_OPA2EN_MASK 0x4UL /* Bit mask for DAC_OPA2EN */ +#define _DAC_OPACTRL_OPA2EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2EN_DEFAULT (_DAC_OPACTRL_OPA2EN_DEFAULT << 2) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0HCMDIS (0x1UL << 6) /* High Common Mode Disable. */ +#define _DAC_OPACTRL_OPA0HCMDIS_SHIFT 6 /* Shift value for DAC_OPA0HCMDIS */ +#define _DAC_OPACTRL_OPA0HCMDIS_MASK 0x40UL /* Bit mask for DAC_OPA0HCMDIS */ +#define _DAC_OPACTRL_OPA0HCMDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0HCMDIS_DEFAULT (_DAC_OPACTRL_OPA0HCMDIS_DEFAULT << 6) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1HCMDIS (0x1UL << 7) /* High Common Mode Disable. */ +#define _DAC_OPACTRL_OPA1HCMDIS_SHIFT 7 /* Shift value for DAC_OPA1HCMDIS */ +#define _DAC_OPACTRL_OPA1HCMDIS_MASK 0x80UL /* Bit mask for DAC_OPA1HCMDIS */ +#define _DAC_OPACTRL_OPA1HCMDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1HCMDIS_DEFAULT (_DAC_OPACTRL_OPA1HCMDIS_DEFAULT << 7) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2HCMDIS (0x1UL << 8) /* High Common Mode Disable. */ +#define _DAC_OPACTRL_OPA2HCMDIS_SHIFT 8 /* Shift value for DAC_OPA2HCMDIS */ +#define _DAC_OPACTRL_OPA2HCMDIS_MASK 0x100UL /* Bit mask for DAC_OPA2HCMDIS */ +#define _DAC_OPACTRL_OPA2HCMDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2HCMDIS_DEFAULT (_DAC_OPACTRL_OPA2HCMDIS_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA0LPFDIS_SHIFT 12 /* Shift value for DAC_OPA0LPFDIS */ +#define _DAC_OPACTRL_OPA0LPFDIS_MASK 0x3000UL /* Bit mask for DAC_OPA0LPFDIS */ +#define _DAC_OPACTRL_OPA0LPFDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA0LPFDIS_PLPFDIS 0x00000001UL /* Mode PLPFDIS for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA0LPFDIS_NLPFDIS 0x00000002UL /* Mode NLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0LPFDIS_DEFAULT (_DAC_OPACTRL_OPA0LPFDIS_DEFAULT << 12) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0LPFDIS_PLPFDIS (_DAC_OPACTRL_OPA0LPFDIS_PLPFDIS << 12) /* Shifted mode PLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0LPFDIS_NLPFDIS (_DAC_OPACTRL_OPA0LPFDIS_NLPFDIS << 12) /* Shifted mode NLPFDIS for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA1LPFDIS_SHIFT 14 /* Shift value for DAC_OPA1LPFDIS */ +#define _DAC_OPACTRL_OPA1LPFDIS_MASK 0xC000UL /* Bit mask for DAC_OPA1LPFDIS */ +#define _DAC_OPACTRL_OPA1LPFDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA1LPFDIS_PLPFDIS 0x00000001UL /* Mode PLPFDIS for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA1LPFDIS_NLPFDIS 0x00000002UL /* Mode NLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1LPFDIS_DEFAULT (_DAC_OPACTRL_OPA1LPFDIS_DEFAULT << 14) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1LPFDIS_PLPFDIS (_DAC_OPACTRL_OPA1LPFDIS_PLPFDIS << 14) /* Shifted mode PLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1LPFDIS_NLPFDIS (_DAC_OPACTRL_OPA1LPFDIS_NLPFDIS << 14) /* Shifted mode NLPFDIS for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA2LPFDIS_SHIFT 16 /* Shift value for DAC_OPA2LPFDIS */ +#define _DAC_OPACTRL_OPA2LPFDIS_MASK 0x30000UL /* Bit mask for DAC_OPA2LPFDIS */ +#define _DAC_OPACTRL_OPA2LPFDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA2LPFDIS_PLPFDIS 0x00000001UL /* Mode PLPFDIS for DAC_OPACTRL */ +#define _DAC_OPACTRL_OPA2LPFDIS_NLPFDIS 0x00000002UL /* Mode NLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2LPFDIS_DEFAULT (_DAC_OPACTRL_OPA2LPFDIS_DEFAULT << 16) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2LPFDIS_PLPFDIS (_DAC_OPACTRL_OPA2LPFDIS_PLPFDIS << 16) /* Shifted mode PLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2LPFDIS_NLPFDIS (_DAC_OPACTRL_OPA2LPFDIS_NLPFDIS << 16) /* Shifted mode NLPFDIS for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0SHORT (0x1UL << 22) /* Short the non-inverting and inverting input. */ +#define _DAC_OPACTRL_OPA0SHORT_SHIFT 22 /* Shift value for DAC_OPA0SHORT */ +#define _DAC_OPACTRL_OPA0SHORT_MASK 0x400000UL /* Bit mask for DAC_OPA0SHORT */ +#define _DAC_OPACTRL_OPA0SHORT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA0SHORT_DEFAULT (_DAC_OPACTRL_OPA0SHORT_DEFAULT << 22) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1SHORT (0x1UL << 23) /* Short the non-inverting and inverting input. */ +#define _DAC_OPACTRL_OPA1SHORT_SHIFT 23 /* Shift value for DAC_OPA1SHORT */ +#define _DAC_OPACTRL_OPA1SHORT_MASK 0x800000UL /* Bit mask for DAC_OPA1SHORT */ +#define _DAC_OPACTRL_OPA1SHORT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA1SHORT_DEFAULT (_DAC_OPACTRL_OPA1SHORT_DEFAULT << 23) /* Shifted mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2SHORT (0x1UL << 24) /* Short the non-inverting and inverting input. */ +#define _DAC_OPACTRL_OPA2SHORT_SHIFT 24 /* Shift value for DAC_OPA2SHORT */ +#define _DAC_OPACTRL_OPA2SHORT_MASK 0x1000000UL /* Bit mask for DAC_OPA2SHORT */ +#define _DAC_OPACTRL_OPA2SHORT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2SHORT_DEFAULT (_DAC_OPACTRL_OPA2SHORT_DEFAULT << 24) /* Shifted mode DEFAULT for DAC_OPACTRL */ + +/* Bit fields for DAC OPAOFFSET */ + +#define _DAC_OPAOFFSET_RESETVALUE 0x00000020UL /* Default value for DAC_OPAOFFSET */ +#define _DAC_OPAOFFSET_MASK 0x0000003FUL /* Mask for DAC_OPAOFFSET */ + +#define _DAC_OPAOFFSET_OPA2OFFSET_SHIFT 0 /* Shift value for DAC_OPA2OFFSET */ +#define _DAC_OPAOFFSET_OPA2OFFSET_MASK 0x3FUL /* Bit mask for DAC_OPA2OFFSET */ +#define _DAC_OPAOFFSET_OPA2OFFSET_DEFAULT 0x00000020UL /* Mode DEFAULT for DAC_OPAOFFSET */ +#define DAC_OPAOFFSET_OPA2OFFSET_DEFAULT (_DAC_OPAOFFSET_OPA2OFFSET_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_OPAOFFSET */ + +/* Bit fields for DAC OPA0MUX */ + +#define _DAC_OPA0MUX_RESETVALUE 0x00400000UL /* Default value for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_MASK 0x74C7F737UL /* Mask for DAC_OPA0MUX */ + +#define _DAC_OPA0MUX_POSSEL_SHIFT 0 /* Shift value for DAC_POSSEL */ +#define _DAC_OPA0MUX_POSSEL_MASK 0x7UL /* Bit mask for DAC_POSSEL */ +#define _DAC_OPA0MUX_POSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_POSSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_POSSEL_DAC 0x00000001UL /* Mode DAC for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_POSSEL_POSPAD 0x00000002UL /* Mode POSPAD for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_POSSEL_OPA0INP 0x00000003UL /* Mode OPA0INP for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_POSSEL_OPATAP 0x00000004UL /* Mode OPATAP for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_DEFAULT (_DAC_OPA0MUX_POSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_DISABLE (_DAC_OPA0MUX_POSSEL_DISABLE << 0) /* Shifted mode DISABLE for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_DAC (_DAC_OPA0MUX_POSSEL_DAC << 0) /* Shifted mode DAC for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_POSPAD (_DAC_OPA0MUX_POSSEL_POSPAD << 0) /* Shifted mode POSPAD for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_OPA0INP (_DAC_OPA0MUX_POSSEL_OPA0INP << 0) /* Shifted mode OPA0INP for DAC_OPA0MUX */ +#define DAC_OPA0MUX_POSSEL_OPATAP (_DAC_OPA0MUX_POSSEL_OPATAP << 0) /* Shifted mode OPATAP for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_NEGSEL_SHIFT 4 /* Shift value for DAC_NEGSEL */ +#define _DAC_OPA0MUX_NEGSEL_MASK 0x30UL /* Bit mask for DAC_NEGSEL */ +#define _DAC_OPA0MUX_NEGSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_NEGSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_NEGSEL_UG 0x00000001UL /* Mode UG for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_NEGSEL_OPATAP 0x00000002UL /* Mode OPATAP for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_NEGSEL_NEGPAD 0x00000003UL /* Mode NEGPAD for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEGSEL_DEFAULT (_DAC_OPA0MUX_NEGSEL_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEGSEL_DISABLE (_DAC_OPA0MUX_NEGSEL_DISABLE << 4) /* Shifted mode DISABLE for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEGSEL_UG (_DAC_OPA0MUX_NEGSEL_UG << 4) /* Shifted mode UG for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEGSEL_OPATAP (_DAC_OPA0MUX_NEGSEL_OPATAP << 4) /* Shifted mode OPATAP for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEGSEL_NEGPAD (_DAC_OPA0MUX_NEGSEL_NEGPAD << 4) /* Shifted mode NEGPAD for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_SHIFT 8 /* Shift value for DAC_RESINMUX */ +#define _DAC_OPA0MUX_RESINMUX_MASK 0x700UL /* Bit mask for DAC_RESINMUX */ +#define _DAC_OPA0MUX_RESINMUX_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_OPA0INP 0x00000001UL /* Mode OPA0INP for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_NEGPAD 0x00000002UL /* Mode NEGPAD for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_POSPAD 0x00000003UL /* Mode POSPAD for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESINMUX_VSS 0x00000004UL /* Mode VSS for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_DEFAULT (_DAC_OPA0MUX_RESINMUX_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_DISABLE (_DAC_OPA0MUX_RESINMUX_DISABLE << 8) /* Shifted mode DISABLE for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_OPA0INP (_DAC_OPA0MUX_RESINMUX_OPA0INP << 8) /* Shifted mode OPA0INP for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_NEGPAD (_DAC_OPA0MUX_RESINMUX_NEGPAD << 8) /* Shifted mode NEGPAD for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_POSPAD (_DAC_OPA0MUX_RESINMUX_POSPAD << 8) /* Shifted mode POSPAD for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESINMUX_VSS (_DAC_OPA0MUX_RESINMUX_VSS << 8) /* Shifted mode VSS for DAC_OPA0MUX */ +#define DAC_OPA0MUX_PPEN (0x1UL << 12) /* OPA0 Positive Pad Input Enable */ +#define _DAC_OPA0MUX_PPEN_SHIFT 12 /* Shift value for DAC_PPEN */ +#define _DAC_OPA0MUX_PPEN_MASK 0x1000UL /* Bit mask for DAC_PPEN */ +#define _DAC_OPA0MUX_PPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_PPEN_DEFAULT (_DAC_OPA0MUX_PPEN_DEFAULT << 12) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NPEN (0x1UL << 13) /* OPA0 Negative Pad Input Enable */ +#define _DAC_OPA0MUX_NPEN_SHIFT 13 /* Shift value for DAC_NPEN */ +#define _DAC_OPA0MUX_NPEN_MASK 0x2000UL /* Bit mask for DAC_NPEN */ +#define _DAC_OPA0MUX_NPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NPEN_DEFAULT (_DAC_OPA0MUX_NPEN_DEFAULT << 13) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_SHIFT 14 /* Shift value for DAC_OUTPEN */ +#define _DAC_OPA0MUX_OUTPEN_MASK 0x7C000UL /* Bit mask for DAC_OUTPEN */ +#define _DAC_OPA0MUX_OUTPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_OUT0 0x00000001UL /* Mode OUT0 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_OUT1 0x00000002UL /* Mode OUT1 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_OUT2 0x00000004UL /* Mode OUT2 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_OUT3 0x00000008UL /* Mode OUT3 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTPEN_OUT4 0x00000010UL /* Mode OUT4 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_DEFAULT (_DAC_OPA0MUX_OUTPEN_DEFAULT << 14) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_OUT0 (_DAC_OPA0MUX_OUTPEN_OUT0 << 14) /* Shifted mode OUT0 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_OUT1 (_DAC_OPA0MUX_OUTPEN_OUT1 << 14) /* Shifted mode OUT1 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_OUT2 (_DAC_OPA0MUX_OUTPEN_OUT2 << 14) /* Shifted mode OUT2 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_OUT3 (_DAC_OPA0MUX_OUTPEN_OUT3 << 14) /* Shifted mode OUT3 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTPEN_OUT4 (_DAC_OPA0MUX_OUTPEN_OUT4 << 14) /* Shifted mode OUT4 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTMODE_SHIFT 22 /* Shift value for DAC_OUTMODE */ +#define _DAC_OPA0MUX_OUTMODE_MASK 0xC00000UL /* Bit mask for DAC_OUTMODE */ +#define _DAC_OPA0MUX_OUTMODE_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTMODE_DEFAULT 0x00000001UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTMODE_MAIN 0x00000001UL /* Mode MAIN for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTMODE_ALT 0x00000002UL /* Mode ALT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_OUTMODE_ALL 0x00000003UL /* Mode ALL for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTMODE_DISABLE (_DAC_OPA0MUX_OUTMODE_DISABLE << 22) /* Shifted mode DISABLE for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTMODE_DEFAULT (_DAC_OPA0MUX_OUTMODE_DEFAULT << 22) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTMODE_MAIN (_DAC_OPA0MUX_OUTMODE_MAIN << 22) /* Shifted mode MAIN for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTMODE_ALT (_DAC_OPA0MUX_OUTMODE_ALT << 22) /* Shifted mode ALT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_OUTMODE_ALL (_DAC_OPA0MUX_OUTMODE_ALL << 22) /* Shifted mode ALL for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEXTOUT (0x1UL << 26) /* OPA0 Next Enable */ +#define _DAC_OPA0MUX_NEXTOUT_SHIFT 26 /* Shift value for DAC_NEXTOUT */ +#define _DAC_OPA0MUX_NEXTOUT_MASK 0x4000000UL /* Bit mask for DAC_NEXTOUT */ +#define _DAC_OPA0MUX_NEXTOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_NEXTOUT_DEFAULT (_DAC_OPA0MUX_NEXTOUT_DEFAULT << 26) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_SHIFT 28 /* Shift value for DAC_RESSEL */ +#define _DAC_OPA0MUX_RESSEL_MASK 0x70000000UL /* Bit mask for DAC_RESSEL */ +#define _DAC_OPA0MUX_RESSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES0 0x00000000UL /* Mode RES0 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES1 0x00000001UL /* Mode RES1 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES2 0x00000002UL /* Mode RES2 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES3 0x00000003UL /* Mode RES3 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES4 0x00000004UL /* Mode RES4 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES5 0x00000005UL /* Mode RES5 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES6 0x00000006UL /* Mode RES6 for DAC_OPA0MUX */ +#define _DAC_OPA0MUX_RESSEL_RES7 0x00000007UL /* Mode RES7 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_DEFAULT (_DAC_OPA0MUX_RESSEL_DEFAULT << 28) /* Shifted mode DEFAULT for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES0 (_DAC_OPA0MUX_RESSEL_RES0 << 28) /* Shifted mode RES0 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES1 (_DAC_OPA0MUX_RESSEL_RES1 << 28) /* Shifted mode RES1 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES2 (_DAC_OPA0MUX_RESSEL_RES2 << 28) /* Shifted mode RES2 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES3 (_DAC_OPA0MUX_RESSEL_RES3 << 28) /* Shifted mode RES3 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES4 (_DAC_OPA0MUX_RESSEL_RES4 << 28) /* Shifted mode RES4 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES5 (_DAC_OPA0MUX_RESSEL_RES5 << 28) /* Shifted mode RES5 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES6 (_DAC_OPA0MUX_RESSEL_RES6 << 28) /* Shifted mode RES6 for DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_RES7 (_DAC_OPA0MUX_RESSEL_RES7 << 28) /* Shifted mode RES7 for DAC_OPA0MUX */ + +/* Bit fields for DAC OPA1MUX */ + +#define _DAC_OPA1MUX_RESETVALUE 0x00000000UL /* Default value for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_MASK 0x74C7F737UL /* Mask for DAC_OPA1MUX */ + +#define _DAC_OPA1MUX_POSSEL_SHIFT 0 /* Shift value for DAC_POSSEL */ +#define _DAC_OPA1MUX_POSSEL_MASK 0x7UL /* Bit mask for DAC_POSSEL */ +#define _DAC_OPA1MUX_POSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_POSSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_POSSEL_DAC 0x00000001UL /* Mode DAC for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_POSSEL_POSPAD 0x00000002UL /* Mode POSPAD for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_POSSEL_OPA0INP 0x00000003UL /* Mode OPA0INP for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_POSSEL_OPATAP 0x00000004UL /* Mode OPATAP for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_DEFAULT (_DAC_OPA1MUX_POSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_DISABLE (_DAC_OPA1MUX_POSSEL_DISABLE << 0) /* Shifted mode DISABLE for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_DAC (_DAC_OPA1MUX_POSSEL_DAC << 0) /* Shifted mode DAC for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_POSPAD (_DAC_OPA1MUX_POSSEL_POSPAD << 0) /* Shifted mode POSPAD for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_OPA0INP (_DAC_OPA1MUX_POSSEL_OPA0INP << 0) /* Shifted mode OPA0INP for DAC_OPA1MUX */ +#define DAC_OPA1MUX_POSSEL_OPATAP (_DAC_OPA1MUX_POSSEL_OPATAP << 0) /* Shifted mode OPATAP for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_NEGSEL_SHIFT 4 /* Shift value for DAC_NEGSEL */ +#define _DAC_OPA1MUX_NEGSEL_MASK 0x30UL /* Bit mask for DAC_NEGSEL */ +#define _DAC_OPA1MUX_NEGSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_NEGSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_NEGSEL_UG 0x00000001UL /* Mode UG for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_NEGSEL_OPATAP 0x00000002UL /* Mode OPATAP for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_NEGSEL_NEGPAD 0x00000003UL /* Mode NEGPAD for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEGSEL_DEFAULT (_DAC_OPA1MUX_NEGSEL_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEGSEL_DISABLE (_DAC_OPA1MUX_NEGSEL_DISABLE << 4) /* Shifted mode DISABLE for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEGSEL_UG (_DAC_OPA1MUX_NEGSEL_UG << 4) /* Shifted mode UG for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEGSEL_OPATAP (_DAC_OPA1MUX_NEGSEL_OPATAP << 4) /* Shifted mode OPATAP for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEGSEL_NEGPAD (_DAC_OPA1MUX_NEGSEL_NEGPAD << 4) /* Shifted mode NEGPAD for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_SHIFT 8 /* Shift value for DAC_RESINMUX */ +#define _DAC_OPA1MUX_RESINMUX_MASK 0x700UL /* Bit mask for DAC_RESINMUX */ +#define _DAC_OPA1MUX_RESINMUX_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_OPA0INP 0x00000001UL /* Mode OPA0INP for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_NEGPAD 0x00000002UL /* Mode NEGPAD for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_POSPAD 0x00000003UL /* Mode POSPAD for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESINMUX_VSS 0x00000004UL /* Mode VSS for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_DEFAULT (_DAC_OPA1MUX_RESINMUX_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_DISABLE (_DAC_OPA1MUX_RESINMUX_DISABLE << 8) /* Shifted mode DISABLE for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_OPA0INP (_DAC_OPA1MUX_RESINMUX_OPA0INP << 8) /* Shifted mode OPA0INP for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_NEGPAD (_DAC_OPA1MUX_RESINMUX_NEGPAD << 8) /* Shifted mode NEGPAD for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_POSPAD (_DAC_OPA1MUX_RESINMUX_POSPAD << 8) /* Shifted mode POSPAD for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESINMUX_VSS (_DAC_OPA1MUX_RESINMUX_VSS << 8) /* Shifted mode VSS for DAC_OPA1MUX */ +#define DAC_OPA1MUX_PPEN (0x1UL << 12) /* OPA1 Positive Pad Input Enable */ +#define _DAC_OPA1MUX_PPEN_SHIFT 12 /* Shift value for DAC_PPEN */ +#define _DAC_OPA1MUX_PPEN_MASK 0x1000UL /* Bit mask for DAC_PPEN */ +#define _DAC_OPA1MUX_PPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_PPEN_DEFAULT (_DAC_OPA1MUX_PPEN_DEFAULT << 12) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NPEN (0x1UL << 13) /* OPA1 Negative Pad Input Enable */ +#define _DAC_OPA1MUX_NPEN_SHIFT 13 /* Shift value for DAC_NPEN */ +#define _DAC_OPA1MUX_NPEN_MASK 0x2000UL /* Bit mask for DAC_NPEN */ +#define _DAC_OPA1MUX_NPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NPEN_DEFAULT (_DAC_OPA1MUX_NPEN_DEFAULT << 13) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_SHIFT 14 /* Shift value for DAC_OUTPEN */ +#define _DAC_OPA1MUX_OUTPEN_MASK 0x7C000UL /* Bit mask for DAC_OUTPEN */ +#define _DAC_OPA1MUX_OUTPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_OUT0 0x00000001UL /* Mode OUT0 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_OUT1 0x00000002UL /* Mode OUT1 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_OUT2 0x00000004UL /* Mode OUT2 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_OUT3 0x00000008UL /* Mode OUT3 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTPEN_OUT4 0x00000010UL /* Mode OUT4 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_DEFAULT (_DAC_OPA1MUX_OUTPEN_DEFAULT << 14) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_OUT0 (_DAC_OPA1MUX_OUTPEN_OUT0 << 14) /* Shifted mode OUT0 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_OUT1 (_DAC_OPA1MUX_OUTPEN_OUT1 << 14) /* Shifted mode OUT1 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_OUT2 (_DAC_OPA1MUX_OUTPEN_OUT2 << 14) /* Shifted mode OUT2 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_OUT3 (_DAC_OPA1MUX_OUTPEN_OUT3 << 14) /* Shifted mode OUT3 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTPEN_OUT4 (_DAC_OPA1MUX_OUTPEN_OUT4 << 14) /* Shifted mode OUT4 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTMODE_SHIFT 22 /* Shift value for DAC_OUTMODE */ +#define _DAC_OPA1MUX_OUTMODE_MASK 0xC00000UL /* Bit mask for DAC_OUTMODE */ +#define _DAC_OPA1MUX_OUTMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTMODE_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTMODE_MAIN 0x00000001UL /* Mode MAIN for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTMODE_ALT 0x00000002UL /* Mode ALT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_OUTMODE_ALL 0x00000003UL /* Mode ALL for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTMODE_DEFAULT (_DAC_OPA1MUX_OUTMODE_DEFAULT << 22) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTMODE_DISABLE (_DAC_OPA1MUX_OUTMODE_DISABLE << 22) /* Shifted mode DISABLE for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTMODE_MAIN (_DAC_OPA1MUX_OUTMODE_MAIN << 22) /* Shifted mode MAIN for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTMODE_ALT (_DAC_OPA1MUX_OUTMODE_ALT << 22) /* Shifted mode ALT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_OUTMODE_ALL (_DAC_OPA1MUX_OUTMODE_ALL << 22) /* Shifted mode ALL for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEXTOUT (0x1UL << 26) /* OPA1 Next Enable */ +#define _DAC_OPA1MUX_NEXTOUT_SHIFT 26 /* Shift value for DAC_NEXTOUT */ +#define _DAC_OPA1MUX_NEXTOUT_MASK 0x4000000UL /* Bit mask for DAC_NEXTOUT */ +#define _DAC_OPA1MUX_NEXTOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_NEXTOUT_DEFAULT (_DAC_OPA1MUX_NEXTOUT_DEFAULT << 26) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_SHIFT 28 /* Shift value for DAC_RESSEL */ +#define _DAC_OPA1MUX_RESSEL_MASK 0x70000000UL /* Bit mask for DAC_RESSEL */ +#define _DAC_OPA1MUX_RESSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES0 0x00000000UL /* Mode RES0 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES1 0x00000001UL /* Mode RES1 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES2 0x00000002UL /* Mode RES2 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES3 0x00000003UL /* Mode RES3 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES4 0x00000004UL /* Mode RES4 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES5 0x00000005UL /* Mode RES5 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES6 0x00000006UL /* Mode RES6 for DAC_OPA1MUX */ +#define _DAC_OPA1MUX_RESSEL_RES7 0x00000007UL /* Mode RES7 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_DEFAULT (_DAC_OPA1MUX_RESSEL_DEFAULT << 28) /* Shifted mode DEFAULT for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES0 (_DAC_OPA1MUX_RESSEL_RES0 << 28) /* Shifted mode RES0 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES1 (_DAC_OPA1MUX_RESSEL_RES1 << 28) /* Shifted mode RES1 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES2 (_DAC_OPA1MUX_RESSEL_RES2 << 28) /* Shifted mode RES2 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES3 (_DAC_OPA1MUX_RESSEL_RES3 << 28) /* Shifted mode RES3 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES4 (_DAC_OPA1MUX_RESSEL_RES4 << 28) /* Shifted mode RES4 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES5 (_DAC_OPA1MUX_RESSEL_RES5 << 28) /* Shifted mode RES5 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES6 (_DAC_OPA1MUX_RESSEL_RES6 << 28) /* Shifted mode RES6 for DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_RES7 (_DAC_OPA1MUX_RESSEL_RES7 << 28) /* Shifted mode RES7 for DAC_OPA1MUX */ + +/* Bit fields for DAC OPA2MUX */ + +#define _DAC_OPA2MUX_RESETVALUE 0x00000000UL /* Default value for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_MASK 0x7440F737UL /* Mask for DAC_OPA2MUX */ + +#define _DAC_OPA2MUX_POSSEL_SHIFT 0 /* Shift value for DAC_POSSEL */ +#define _DAC_OPA2MUX_POSSEL_MASK 0x7UL /* Bit mask for DAC_POSSEL */ +#define _DAC_OPA2MUX_POSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_POSSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_POSSEL_POSPAD 0x00000002UL /* Mode POSPAD for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_POSSEL_OPA1INP 0x00000003UL /* Mode OPA1INP for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_POSSEL_OPATAP 0x00000004UL /* Mode OPATAP for DAC_OPA2MUX */ +#define DAC_OPA2MUX_POSSEL_DEFAULT (_DAC_OPA2MUX_POSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_POSSEL_DISABLE (_DAC_OPA2MUX_POSSEL_DISABLE << 0) /* Shifted mode DISABLE for DAC_OPA2MUX */ +#define DAC_OPA2MUX_POSSEL_POSPAD (_DAC_OPA2MUX_POSSEL_POSPAD << 0) /* Shifted mode POSPAD for DAC_OPA2MUX */ +#define DAC_OPA2MUX_POSSEL_OPA1INP (_DAC_OPA2MUX_POSSEL_OPA1INP << 0) /* Shifted mode OPA1INP for DAC_OPA2MUX */ +#define DAC_OPA2MUX_POSSEL_OPATAP (_DAC_OPA2MUX_POSSEL_OPATAP << 0) /* Shifted mode OPATAP for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_NEGSEL_SHIFT 4 /* Shift value for DAC_NEGSEL */ +#define _DAC_OPA2MUX_NEGSEL_MASK 0x30UL /* Bit mask for DAC_NEGSEL */ +#define _DAC_OPA2MUX_NEGSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_NEGSEL_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_NEGSEL_UG 0x00000001UL /* Mode UG for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_NEGSEL_OPATAP 0x00000002UL /* Mode OPATAP for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_NEGSEL_NEGPAD 0x00000003UL /* Mode NEGPAD for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEGSEL_DEFAULT (_DAC_OPA2MUX_NEGSEL_DEFAULT << 4) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEGSEL_DISABLE (_DAC_OPA2MUX_NEGSEL_DISABLE << 4) /* Shifted mode DISABLE for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEGSEL_UG (_DAC_OPA2MUX_NEGSEL_UG << 4) /* Shifted mode UG for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEGSEL_OPATAP (_DAC_OPA2MUX_NEGSEL_OPATAP << 4) /* Shifted mode OPATAP for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEGSEL_NEGPAD (_DAC_OPA2MUX_NEGSEL_NEGPAD << 4) /* Shifted mode NEGPAD for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_SHIFT 8 /* Shift value for DAC_RESINMUX */ +#define _DAC_OPA2MUX_RESINMUX_MASK 0x700UL /* Bit mask for DAC_RESINMUX */ +#define _DAC_OPA2MUX_RESINMUX_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_DISABLE 0x00000000UL /* Mode DISABLE for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_OPA1INP 0x00000001UL /* Mode OPA1INP for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_NEGPAD 0x00000002UL /* Mode NEGPAD for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_POSPAD 0x00000003UL /* Mode POSPAD for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESINMUX_VSS 0x00000004UL /* Mode VSS for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_DEFAULT (_DAC_OPA2MUX_RESINMUX_DEFAULT << 8) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_DISABLE (_DAC_OPA2MUX_RESINMUX_DISABLE << 8) /* Shifted mode DISABLE for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_OPA1INP (_DAC_OPA2MUX_RESINMUX_OPA1INP << 8) /* Shifted mode OPA1INP for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_NEGPAD (_DAC_OPA2MUX_RESINMUX_NEGPAD << 8) /* Shifted mode NEGPAD for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_POSPAD (_DAC_OPA2MUX_RESINMUX_POSPAD << 8) /* Shifted mode POSPAD for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESINMUX_VSS (_DAC_OPA2MUX_RESINMUX_VSS << 8) /* Shifted mode VSS for DAC_OPA2MUX */ +#define DAC_OPA2MUX_PPEN (0x1UL << 12) /* OPA2 Positive Pad Input Enable */ +#define _DAC_OPA2MUX_PPEN_SHIFT 12 /* Shift value for DAC_PPEN */ +#define _DAC_OPA2MUX_PPEN_MASK 0x1000UL /* Bit mask for DAC_PPEN */ +#define _DAC_OPA2MUX_PPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_PPEN_DEFAULT (_DAC_OPA2MUX_PPEN_DEFAULT << 12) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NPEN (0x1UL << 13) /* OPA2 Negative Pad Input Enable */ +#define _DAC_OPA2MUX_NPEN_SHIFT 13 /* Shift value for DAC_NPEN */ +#define _DAC_OPA2MUX_NPEN_MASK 0x2000UL /* Bit mask for DAC_NPEN */ +#define _DAC_OPA2MUX_NPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NPEN_DEFAULT (_DAC_OPA2MUX_NPEN_DEFAULT << 13) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_OUTPEN_SHIFT 14 /* Shift value for DAC_OUTPEN */ +#define _DAC_OPA2MUX_OUTPEN_MASK 0xC000UL /* Bit mask for DAC_OUTPEN */ +#define _DAC_OPA2MUX_OUTPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_OUTPEN_OUT0 0x00000001UL /* Mode OUT0 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_OUTPEN_OUT1 0x00000002UL /* Mode OUT1 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_OUTPEN_DEFAULT (_DAC_OPA2MUX_OUTPEN_DEFAULT << 14) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_OUTPEN_OUT0 (_DAC_OPA2MUX_OUTPEN_OUT0 << 14) /* Shifted mode OUT0 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_OUTPEN_OUT1 (_DAC_OPA2MUX_OUTPEN_OUT1 << 14) /* Shifted mode OUT1 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_OUTMODE (0x1UL << 22) /* Output Select */ +#define _DAC_OPA2MUX_OUTMODE_SHIFT 22 /* Shift value for DAC_OUTMODE */ +#define _DAC_OPA2MUX_OUTMODE_MASK 0x400000UL /* Bit mask for DAC_OUTMODE */ +#define _DAC_OPA2MUX_OUTMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_OUTMODE_DEFAULT (_DAC_OPA2MUX_OUTMODE_DEFAULT << 22) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEXTOUT (0x1UL << 26) /* OPA2 Next Enable */ +#define _DAC_OPA2MUX_NEXTOUT_SHIFT 26 /* Shift value for DAC_NEXTOUT */ +#define _DAC_OPA2MUX_NEXTOUT_MASK 0x4000000UL /* Bit mask for DAC_NEXTOUT */ +#define _DAC_OPA2MUX_NEXTOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_NEXTOUT_DEFAULT (_DAC_OPA2MUX_NEXTOUT_DEFAULT << 26) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_SHIFT 28 /* Shift value for DAC_RESSEL */ +#define _DAC_OPA2MUX_RESSEL_MASK 0x70000000UL /* Bit mask for DAC_RESSEL */ +#define _DAC_OPA2MUX_RESSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES0 0x00000000UL /* Mode RES0 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES1 0x00000001UL /* Mode RES1 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES2 0x00000002UL /* Mode RES2 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES3 0x00000003UL /* Mode RES3 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES4 0x00000004UL /* Mode RES4 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES5 0x00000005UL /* Mode RES5 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES6 0x00000006UL /* Mode RES6 for DAC_OPA2MUX */ +#define _DAC_OPA2MUX_RESSEL_RES7 0x00000007UL /* Mode RES7 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_DEFAULT (_DAC_OPA2MUX_RESSEL_DEFAULT << 28) /* Shifted mode DEFAULT for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES0 (_DAC_OPA2MUX_RESSEL_RES0 << 28) /* Shifted mode RES0 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES1 (_DAC_OPA2MUX_RESSEL_RES1 << 28) /* Shifted mode RES1 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES2 (_DAC_OPA2MUX_RESSEL_RES2 << 28) /* Shifted mode RES2 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES3 (_DAC_OPA2MUX_RESSEL_RES3 << 28) /* Shifted mode RES3 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES4 (_DAC_OPA2MUX_RESSEL_RES4 << 28) /* Shifted mode RES4 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES5 (_DAC_OPA2MUX_RESSEL_RES5 << 28) /* Shifted mode RES5 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES6 (_DAC_OPA2MUX_RESSEL_RES6 << 28) /* Shifted mode RES6 for DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_RES7 (_DAC_OPA2MUX_RESSEL_RES7 << 28) /* Shifted mode RES7 for DAC_OPA2MUX */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DAC_H */ diff --git a/arch/arm/src/efm32/chip/efm32_devinfo.h b/arch/arm/src/efm32/chip/efm32_devinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..501e34741ccc759f236a152cfa906d0b1c30f613 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_devinfo.h @@ -0,0 +1,229 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_devinfo.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DEVINFO_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DEVINFO_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + + +/* MSC Register Offsets ********************************************************************************************************/ + +#define EFM32_DEVINFO_CAL_OFFSET 0x0000 +#define EFM32_DEVINFO_ADC0CALn_OFFSET(n) (0x0004+(n)*4) +#define EFM32_DEVINFO_DAC0CALn_OFFSET(n) (0x0018+(n)*4) +#define EFM32_DEVINFO_AUXHFRCOCALn_OFFSET(n) (0x0024+(n)*4) +#define EFM32_DEVINFO_HFRCOCALn_OFFSET(n) (0x002c+(n)*4) +#define EFM32_DEVINFO_MEMINFO_PAGE_SIZE_OFFSET 0x0034 +#define EFM32_DEVINFO_UNIQUEL_OFFSET 0x0040 +#define EFM32_DEVINFO_UNIQUEH_OFFSET 0x0044 +#define EFM32_DEVINFO_MEMINFO_SIZE_OFFSET 0x0048 +#define EFM32_DEVINFO_PART_OFFSET 0x004c + +/* MSC Register Addresses ******************************************************************************************************/ + +#define EFM32_DEVINFO_CAL (EFM32_DEVINFO_BASE+EFM32_DEVINFO_CAL_OFFSET) + +#define EFM32_DEVINFO_ADC0CALn(n) (EFM32_DEVINFO_BASE+EFM32_DEVINFO_ADC0CALn_OFFSET(n)) +#define EFM32_DEVINFO_ADC0CAL0 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_ADC0CALn_OFFSET(0)) +#define EFM32_DEVINFO_ADC0CAL1 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_ADC0CALn_OFFSET(1)) +#define EFM32_DEVINFO_ADC0CAL2 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_ADC0CALn_OFFSET(2)) + +#define EFM32_DEVINFO_DAC0CALn(n) (EFM32_DEVINFO_BASE+EFM32_DEVINFO_DAC0CALn_OFFSET(n)) +#define EFM32_DEVINFO_DAC0CAL0 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_DAC0CALn_OFFSET(0)) +#define EFM32_DEVINFO_DAC0CAL1 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_DAC0CALn_OFFSET(1)) +#define EFM32_DEVINFO_DAC0CAL2 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_DAC0CALn_OFFSET(2)) +#define EFM32_DEVINFO_AUXHFRCOCALn(n) (EFM32_DEVINFO_BASE+EFM32_DEVINFO_AUXHFRCOCALn_OFFSET(n)) +#define EFM32_DEVINFO_AUXHFRCOCAL0 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_AUXHFRCOCALn_OFFSET(0)) +#define EFM32_DEVINFO_AUXHFRCOCAL1 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_AUXHFRCOCALn_OFFSET(1)) +#define EFM32_DEVINFO_HFRCOCALn(n) (EFM32_DEVINFO_BASE+EFM32_DEVINFO_HFRCOCALn_OFFSET(n)) +#define EFM32_DEVINFO_HFRCOCAL0 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_HFRCOCALn_OFFSET(0)) +#define EFM32_DEVINFO_HFRCOCAL1 (EFM32_DEVINFO_BASE+EFM32_DEVINFO_HFRCOCALn_OFFSET(1)) +#define EFM32_DEVINFO_MEMINFO_PAGE_SIZE (EFM32_DEVINFO_BASE+EFM32_DEVINFO_MEMINFO_PAGE_SIZE_OFFSET) +#define EFM32_DEVINFO_UNIQUEL (EFM32_DEVINFO_BASE+EFM32_DEVINFO_UNIQUEL_OFFSET) +#define EFM32_DEVINFO_UNIQUEH (EFM32_DEVINFO_BASE+EFM32_DEVINFO_UNIQUEH_OFFSET) +#define EFM32_DEVINFO_MEMINFO_SIZE (EFM32_DEVINFO_BASE+EFM32_DEVINFO_MEMINFO_SIZE_OFFSET) +#define EFM32_DEVINFO_PART (EFM32_DEVINFO_BASE+EFM32_DEVINFO_PART_OFFSET) + +/* Bit fields for struct efm32_devinfo_s */ + +#define _DEVINFO_CAL_CRC_MASK 0x0000FFFFUL /* Integrity CRC checksum mask */ +#define _DEVINFO_CAL_CRC_SHIFT 0 /* Integrity CRC checksum shift */ +#define _DEVINFO_CAL_TEMP_MASK 0x00FF0000UL /* Calibration temperature, DegC, mask */ +#define _DEVINFO_CAL_TEMP_SHIFT 16 /* Calibration temperature shift */ + +#define _DEVINFO_ADC0CAL0_1V25_GAIN_MASK 0x00007F00UL /* Gain for 1V25 reference, mask */ +#define _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT 8 /* Gain for 1V25 reference, shift */ +#define _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK 0x0000007FUL /* Offset for 1V25 reference, mask */ +#define _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT 0 /* Offset for 1V25 reference, shift */ +#define _DEVINFO_ADC0CAL0_2V5_GAIN_MASK 0x7F000000UL /* Gain for 2V5 reference, mask */ +#define _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT 24 /* Gain for 2V5 reference, shift */ +#define _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK 0x007F0000UL /* Offset for 2V5 reference, mask */ +#define _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT 16 /* Offset for 2V5 reference, shift */ + +#define _DEVINFO_ADC0CAL1_VDD_GAIN_MASK 0x00007F00UL /* Gain for VDD reference, mask */ +#define _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT 8 /* Gain for VDD reference, shift */ +#define _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK 0x0000007FUL /* Offset for VDD reference, mask */ +#define _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT 0 /* Offset for VDD reference, shift */ +#define _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK 0x7F000000UL /* Gain 5VDIFF for 5VDIFF reference, mask */ +#define _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT 24 /* Gain for 5VDIFF reference, mask */ +#define _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK 0x007F0000UL /* Offset for 5VDIFF reference, mask */ +#define _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT 16 /* Offset for 5VDIFF reference, shift */ + +#define _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK 0x0000007FUL /* Offset for 2XVDDVSS reference, mask */ +#define _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT 0 /* Offset for 2XVDDVSS reference, shift */ +#define _DEVINFO_ADC0CAL2_TEMP1V25_MASK 0xFFF00000UL /* Temperature reading at 1V25 reference, mask */ +#define _DEVINFO_ADC0CAL2_TEMP1V25_SHIFT 20 /* Temperature reading at 1V25 reference, DegC */ + +#define _DEVINFO_DAC0CAL0_1V25_GAIN_MASK 0x007F0000UL /* Gain for 1V25 reference, mask */ +#define _DEVINFO_DAC0CAL0_1V25_GAIN_SHIFT 16 /* Gain for 1V25 reference, shift */ +#define _DEVINFO_DAC0CAL0_1V25_CH1_OFFSET_MASK 0x00003F00UL /* Channel 1 offset for 1V25 reference, mask */ +#define _DEVINFO_DAC0CAL0_1V25_CH1_OFFSET_SHIFT 8 /* Channel 1 offset for 1V25 reference, shift */ +#define _DEVINFO_DAC0CAL0_1V25_CH0_OFFSET_MASK 0x0000003FUL /* Channel 0 offset for 1V25 reference, mask */ +#define _DEVINFO_DAC0CAL0_1V25_CH0_OFFSET_SHIFT 0 /* Channel 0 offset for 1V25 reference, shift */ + +#define _DEVINFO_DAC0CAL1_2V5_GAIN_MASK 0x007F0000UL /* Gain for 2V5 reference, mask */ +#define _DEVINFO_DAC0CAL1_2V5_GAIN_SHIFT 16 /* Gain for 2V5 reference, shift */ +#define _DEVINFO_DAC0CAL1_2V5_CH1_OFFSET_MASK 0x00003F00UL /* Channel 1 offset for 2V5 reference, mask */ +#define _DEVINFO_DAC0CAL1_2V5_CH1_OFFSET_SHIFT 8 /* Channel 1 offset for 2V5 reference, shift */ +#define _DEVINFO_DAC0CAL1_2V5_CH0_OFFSET_MASK 0x0000003FUL /* Channel 0 offset for 2V5 reference, mask */ +#define _DEVINFO_DAC0CAL1_2V5_CH0_OFFSET_SHIFT 0 /* Channel 0 offset for 2V5 reference, shift */ + +#define _DEVINFO_DAC0CAL2_VDD_GAIN_MASK 0x007F0000UL /* Gain for VDD reference, mask */ +#define _DEVINFO_DAC0CAL2_VDD_GAIN_SHIFT 16 /* Gain for VDD reference, shift */ +#define _DEVINFO_DAC0CAL2_VDD_CH1_OFFSET_MASK 0x00003F00UL /* Channel 1 offset for VDD reference, mask */ +#define _DEVINFO_DAC0CAL2_VDD_CH1_OFFSET_SHIFT 8 /* Channel 1 offset for VDD reference, shift */ +#define _DEVINFO_DAC0CAL2_VDD_CH0_OFFSET_MASK 0x0000003FUL /* Channel 0 offset for VDD reference, mask */ +#define _DEVINFO_DAC0CAL2_VDD_CH0_OFFSET_SHIFT 0 /* Channel 0 offset for VDD reference, shift*/ + +#define _DEVINFO_AUXHFRCOCAL0_BAND1_MASK 0x000000FFUL /* 1MHz tuning value for AUXHFRCO, mask */ +#define _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT 0 /* 1MHz tuning value for AUXHFRCO, shift */ +#define _DEVINFO_AUXHFRCOCAL0_BAND7_MASK 0x0000FF00UL /* 7MHz tuning value for AUXHFRCO, mask */ +#define _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT 8 /* 7MHz tuning value for AUXHFRCO, shift */ +#define _DEVINFO_AUXHFRCOCAL0_BAND11_MASK 0x00FF0000UL /* 11MHz tuning value for AUXHFRCO, mask */ +#define _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT 16 /* 11MHz tuning value for AUXHFRCO, shift */ +#define _DEVINFO_AUXHFRCOCAL0_BAND14_MASK 0xFF000000UL /* 14MHz tuning value for AUXHFRCO, mask */ +#define _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT 24 /* 14MHz tuning value for AUXHFRCO, shift */ + +#define _DEVINFO_AUXHFRCOCAL1_BAND21_MASK 0x000000FFUL /* 21MHz tuning value for AUXHFRCO, mask */ +#define _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT 0 /* 21MHz tuning value for AUXHFRCO, shift */ +#define _DEVINFO_AUXHFRCOCAL1_BAND28_MASK 0x0000FF00UL /* 28MHz tuning value for AUXHFRCO, shift */ +#define _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT 8 /* 28MHz tuning value for AUXHFRCO, mask */ + +#define _DEVINFO_HFRCOCAL0_BAND1_MASK 0x000000FFUL /* 1MHz tuning value for HFRCO, mask */ +#define _DEVINFO_HFRCOCAL0_BAND1_SHIFT 0 /* 1MHz tuning value for HFRCO, shift */ +#define _DEVINFO_HFRCOCAL0_BAND7_MASK 0x0000FF00UL /* 7MHz tuning value for HFRCO, mask */ +#define _DEVINFO_HFRCOCAL0_BAND7_SHIFT 8 /* 7MHz tuning value for HFRCO, shift */ +#define _DEVINFO_HFRCOCAL0_BAND11_MASK 0x00FF0000UL /* 11MHz tuning value for HFRCO, mask */ +#define _DEVINFO_HFRCOCAL0_BAND11_SHIFT 16 /* 11MHz tuning value for HFRCO, shift */ +#define _DEVINFO_HFRCOCAL0_BAND14_MASK 0xFF000000UL /* 14MHz tuning value for HFRCO, mask */ +#define _DEVINFO_HFRCOCAL0_BAND14_SHIFT 24 /* 14MHz tuning value for HFRCO, shift */ + +#define _DEVINFO_HFRCOCAL1_BAND21_MASK 0x000000FFUL /* 21MHz tuning value for HFRCO, mask */ +#define _DEVINFO_HFRCOCAL1_BAND21_SHIFT 0 /* 21MHz tuning value for HFRCO, shift */ +#define _DEVINFO_HFRCOCAL1_BAND28_MASK 0x0000FF00UL /* 28MHz tuning value for HFRCO, shift */ +#define _DEVINFO_HFRCOCAL1_BAND28_SHIFT 8 /* 28MHz tuning value for HFRCO, mask */ + +#define _DEVINFO_MEMINFO_FLASH_PAGE_SIZE_MASK 0xFF000000UL /* Flash page size (refer to ref.man for encoding) mask */ +#define _DEVINFO_MEMINFO_FLASH_PAGE_SIZE_SHIFT 24 /* Flash page size shift */ + +#define _DEVINFO_UNIQUEL_MASK 0xFFFFFFFFUL /* Lower part of 64-bit device unique number */ +#define _DEVINFO_UNIQUEL_SHIFT 0 /* Unique Low 32-bit shift */ + +#define _DEVINFO_UNIQUEH_MASK 0xFFFFFFFFUL /* High part of 64-bit device unique number */ +#define _DEVINFO_UNIQUEH_SHIFT 0 /* Unique High 32-bit shift */ + +#define _DEVINFO_MEMINFO_SIZE_SRAM_MASK 0xFFFF0000UL /* Flash size in kilobytes */ +#define _DEVINFO_MEMINFO_SIZE_SRAM_SHIFT 16 /* Bit position for flash size */ +#define _DEVINFO_MEMINFO_SIZE_FLASH_MASK 0x0000FFFFUL /* SRAM size in kilobytes */ +#define _DEVINFO_MEMINFO_SIZE_FLASH_SHIFT 0 /* Bit position for SRAM size */ + +#define _DEVINFO_PART_PROD_REV_MASK 0xFF000000UL /* Production revision */ +#define _DEVINFO_PART_PROD_REV_SHIFT 24 /* Bit position for production revision */ +#define _DEVINFO_PART_DEVICE_FAMILY_MASK 0x00FF0000UL /* Device Family, 0x47 for Gecko */ +#define _DEVINFO_PART_DEVICE_FAMILY_SHIFT 16 /* Bit position for device family */ +#define _DEVINFO_PART_DEVICE_FAMILY_G 71 /* Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_FAMILY_GG 72 /* Giant Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_FAMILY_TG 73 /* Tiny Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_FAMILY_LG 74 /* Leopard Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_FAMILY_WG 75 /* Wonder Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_FAMILY_ZG 76 /* Zero Gecko Device Family */ +#define _DEVINFO_PART_DEVICE_NUMBER_MASK 0x0000FFFFUL /* Device number */ +#define _DEVINFO_PART_DEVICE_NUMBER_SHIFT 0 /* Bit position for device number */ + +/******************************************************************************************************************************* + * Public Type Definitions + *******************************************************************************************************************************/ + + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DEVINFO_H */ diff --git a/arch/arm/src/efm32/chip/efm32_dma.h b/arch/arm/src/efm32/chip/efm32_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..d7ef85e3112405f450fc4ea90106fd5147ee871f --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_dma.h @@ -0,0 +1,2287 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_dma.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DMA_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DMA_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) && !defined(CONFIG_EFM32_EFM32G) +# warning This is the EFM32GG/G header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_DMA_NCHANNELS 12 +#elif defined(CONFIG_EFM32_EFM32G) +# define EFM32_DMA_NCHANNELS 8 +#endif + +/* DMA Register Offsets ********************************************************************************************************/ + +#define EFM32_DMA_STATUS_OFFSET 0x0000 /* DMA Status Registers */ +#define EFM32_DMA_CONFIG_OFFSET 0x0004 /* DMA Configuration Register */ +#define EFM32_DMA_CTRLBASE_OFFSET 0x0008 /* Channel Control Data Base Pointer Register */ +#define EFM32_DMA_ALTCTRLBASE_OFFSET 0x000c /* Channel Alternate Control Data Base Pointer Register */ +#define EFM32_DMA_CHWAITSTATUS_OFFSET 0x0010 /* Channel Wait on Request Status Register */ +#define EFM32_DMA_CHSWREQ_OFFSET 0x0014 /* Channel Software Request Register */ +#define EFM32_DMA_CHUSEBURSTS_OFFSET 0x0018 /* Channel Useburst Set Register */ +#define EFM32_DMA_CHUSEBURSTC_OFFSET 0x001c /* Channel Useburst Clear Register */ +#define EFM32_DMA_CHREQMASKS_OFFSET 0x0020 /* Channel Request Mask Set Register */ +#define EFM32_DMA_CHREQMASKC_OFFSET 0x0024 /* Channel Request Mask Clear Register */ +#define EFM32_DMA_CHENS_OFFSET 0x0028 /* Channel Enable Set Register */ +#define EFM32_DMA_CHENC_OFFSET 0x002c /* Channel Enable Clear Register */ +#define EFM32_DMA_CHALTS_OFFSET 0x0030 /* Channel Alternate Set Register */ +#define EFM32_DMA_CHALTC_OFFSET 0x0034 /* Channel Alternate Clear Register */ +#define EFM32_DMA_CHPRIS_OFFSET 0x0038 /* Channel Priority Set Register */ +#define EFM32_DMA_CHPRIC_OFFSET 0x003c /* Channel Priority Clear Register */ +#define EFM32_DMA_ERRORC_OFFSET 0x004c /* Bus Error Clear Register */ +#define EFM32_DMA_CHREQSTATUS_OFFSET 0x0e10 /* Channel Request Status */ +#define EFM32_DMA_CHSREQSTATUS_OFFSET 0x0e18 /* Channel Single Request Status */ +#define EFM32_DMA_IF_OFFSET 0x1000 /* Interrupt Flag Register */ +#define EFM32_DMA_IFS_OFFSET 0x1004 /* Interrupt Flag Set Register */ +#define EFM32_DMA_IFC_OFFSET 0x1008 /* Interrupt Flag Clear Register */ +#define EFM32_DMA_IEN_OFFSET 0x100c /* Interrupt Enable register */ +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_DMA_CTRL_OFFSET 0x1010 /* DMA Control Register */ +# define EFM32_DMA_RDS_OFFSET 0x1014 /* DMA Retain Descriptor State */ +# define EFM32_DMA_LOOP0_OFFSET 0x1020 /* Channel 0 Loop Register */ +# define EFM32_DMA_LOOP1_OFFSET 0x1024 /* Channel 1 Loop Register */ +# define EFM32_DMA_RECT0_OFFSET 0x1060 /* Channel 0 Rectangle Register */ +#endif + +#define EFM32_DMA_CHn_CTRL_OFFSET(n) (0x1100+((n)<<2)) /* Channel n Control Register */ +#define EFM32_DMA_CH0_CTRL_OFFSET 0x1100 /* Channel 0 Control Register */ +#define EFM32_DMA_CH1_CTRL_OFFSET 0x1104 /* Channel 1 Control Register */ +#define EFM32_DMA_CH2_CTRL_OFFSET 0x1108 /* Channel 2 Control Register */ +#define EFM32_DMA_CH3_CTRL_OFFSET 0x110c /* Channel 3 Control Register */ +#define EFM32_DMA_CH4_CTRL_OFFSET 0x1110 /* Channel 4 Control Register */ +#define EFM32_DMA_CH5_CTRL_OFFSET 0x1114 /* Channel 5 Control Register */ +#define EFM32_DMA_CH6_CTRL_OFFSET 0x1118 /* Channel 6 Control Register */ +#define EFM32_DMA_CH7_CTRL_OFFSET 0x111c /* Channel 7 Control Register */ +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_DMA_CH8_CTRL_OFFSET 0x1120 /* Channel 8 Control Register */ +# define EFM32_DMA_CH9_CTRL_OFFSET 0x1124 /* Channel 9 Control Register */ +# define EFM32_DMA_CH10_CTRL_OFFSET 0x1128 /* Channel 10 Control Register */ +# define EFM32_DMA_CH11_CTRL_OFFSET 0x112c /* Channel 11 Control Register */ +#endif + +/* DMA Register Addresses ******************************************************************************************************/ + +#define EFM32_DMA_STATUS (EFM32_DMA_BASE+EFM32_DMA_STATUS_OFFSET) +#define EFM32_DMA_CONFIG (EFM32_DMA_BASE+EFM32_DMA_CONFIG_OFFSET) +#define EFM32_DMA_CTRLBASE (EFM32_DMA_BASE+EFM32_DMA_CTRLBASE_OFFSET) +#define EFM32_DMA_ALTCTRLBASE (EFM32_DMA_BASE+EFM32_DMA_ALTCTRLBASE_OFFSET) +#define EFM32_DMA_CHWAITSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHWAITSTATUS_OFFSET) +#define EFM32_DMA_CHSWREQ (EFM32_DMA_BASE+EFM32_DMA_CHSWREQ_OFFSET) +#define EFM32_DMA_CHUSEBURSTS (EFM32_DMA_BASE+EFM32_DMA_CHUSEBURSTS_OFFSET) +#define EFM32_DMA_CHUSEBURSTC (EFM32_DMA_BASE+EFM32_DMA_CHUSEBURSTC_OFFSET) +#define EFM32_DMA_CHREQMASKS (EFM32_DMA_BASE+EFM32_DMA_CHREQMASKS_OFFSET) +#define EFM32_DMA_CHREQMASKC (EFM32_DMA_BASE+EFM32_DMA_CHREQMASKC_OFFSET) +#define EFM32_DMA_CHENS (EFM32_DMA_BASE+EFM32_DMA_CHENS_OFFSET) +#define EFM32_DMA_CHENC (EFM32_DMA_BASE+EFM32_DMA_CHENC_OFFSET) +#define EFM32_DMA_CHALTS (EFM32_DMA_BASE+EFM32_DMA_CHALTS_OFFSET) +#define EFM32_DMA_CHALTC (EFM32_DMA_BASE+EFM32_DMA_CHALTC_OFFSET) +#define EFM32_DMA_CHPRIS (EFM32_DMA_BASE+EFM32_DMA_CHPRIS_OFFSET) +#define EFM32_DMA_CHPRIC (EFM32_DMA_BASE+EFM32_DMA_CHPRIC_OFFSET) +#define EFM32_DMA_ERRORC (EFM32_DMA_BASE+EFM32_DMA_ERRORC_OFFSET) +#define EFM32_DMA_CHREQSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHREQSTATUS_OFFSET) +#define EFM32_DMA_CHSREQSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHSREQSTATUS_OFFSET) +#define EFM32_DMA_IF (EFM32_DMA_BASE+EFM32_DMA_IF_OFFSET) +#define EFM32_DMA_IFS (EFM32_DMA_BASE+EFM32_DMA_IFS_OFFSET) +#define EFM32_DMA_IFC (EFM32_DMA_BASE+EFM32_DMA_IFC_OFFSET) +#define EFM32_DMA_IEN (EFM32_DMA_BASE+EFM32_DMA_IEN_OFFSET) +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_DMA_CTRL (EFM32_DMA_BASE+EFM32_DMA_CTRL_OFFSET) +# define EFM32_DMA_RDS (EFM32_DMA_BASE+EFM32_DMA_RDS_OFFSET) +# define EFM32_DMA_LOOP0 (EFM32_DMA_BASE+EFM32_DMA_LOOP0_OFFSET) +# define EFM32_DMA_LOOP1 (EFM32_DMA_BASE+EFM32_DMA_LOOP1_OFFSET) +# define EFM32_DMA_RECT0 (EFM32_DMA_BASE+EFM32_DMA_RECT0_OFFSET) +#endif + +#define EFM32_DMA_CHn_CTRL(n) (EFM32_DMA_BASE+EFM32_DMA_CHn_CTRL_OFFSET(n)) +#define EFM32_DMA_CH0_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH0_CTRL_OFFSET) +#define EFM32_DMA_CH1_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH1_CTRL_OFFSET) +#define EFM32_DMA_CH2_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH2_CTRL_OFFSET) +#define EFM32_DMA_CH3_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH3_CTRL_OFFSET) +#define EFM32_DMA_CH4_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH4_CTRL_OFFSET) +#define EFM32_DMA_CH5_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH5_CTRL_OFFSET) +#define EFM32_DMA_CH6_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH6_CTRL_OFFSET) +#define EFM32_DMA_CH7_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH7_CTRL_OFFSET) +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_DMA_CH8_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH8_CTRL_OFFSET) +# define EFM32_DMA_CH9_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH9_CTRL_OFFSET) +# define EFM32_DMA_CH10_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH10_CTRL_OFFSET) +# define EFM32_DMA_CH11_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH11_CTRL_OFFSET) +#endif + +/* DMA Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for DMA STATUS */ + +#define _DMA_STATUS_RESETVALUE 0x100B0000UL /* Default value for DMA_STATUS */ +#define _DMA_STATUS_MASK 0x001F00F1UL /* Mask for DMA_STATUS */ + +#define DMA_STATUS_EN (0x1UL << 0) /* DMA Enable Status */ +#define _DMA_STATUS_EN_SHIFT 0 /* Shift value for DMA_EN */ +#define _DMA_STATUS_EN_MASK 0x1UL /* Bit mask for DMA_EN */ +#define _DMA_STATUS_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_STATUS */ +#define DMA_STATUS_EN_DEFAULT (_DMA_STATUS_EN_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_STATUS */ +#define _DMA_STATUS_STATE_SHIFT 4 /* Shift value for DMA_STATE */ +#define _DMA_STATUS_STATE_MASK 0xF0UL /* Bit mask for DMA_STATE */ +#define _DMA_STATUS_STATE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_STATUS */ +#define _DMA_STATUS_STATE_IDLE 0x00000000UL /* Mode IDLE for DMA_STATUS */ +#define _DMA_STATUS_STATE_RDCHCTRLDATA 0x00000001UL /* Mode RDCHCTRLDATA for DMA_STATUS */ +#define _DMA_STATUS_STATE_RDSRCENDPTR 0x00000002UL /* Mode RDSRCENDPTR for DMA_STATUS */ +#define _DMA_STATUS_STATE_RDDSTENDPTR 0x00000003UL /* Mode RDDSTENDPTR for DMA_STATUS */ +#define _DMA_STATUS_STATE_RDSRCDATA 0x00000004UL /* Mode RDSRCDATA for DMA_STATUS */ +#define _DMA_STATUS_STATE_WRDSTDATA 0x00000005UL /* Mode WRDSTDATA for DMA_STATUS */ +#define _DMA_STATUS_STATE_WAITREQCLR 0x00000006UL /* Mode WAITREQCLR for DMA_STATUS */ +#define _DMA_STATUS_STATE_WRCHCTRLDATA 0x00000007UL /* Mode WRCHCTRLDATA for DMA_STATUS */ +#define _DMA_STATUS_STATE_STALLED 0x00000008UL /* Mode STALLED for DMA_STATUS */ +#define _DMA_STATUS_STATE_DONE 0x00000009UL /* Mode DONE for DMA_STATUS */ +#define _DMA_STATUS_STATE_PERSCATTRANS 0x0000000AUL /* Mode PERSCATTRANS for DMA_STATUS */ +#define DMA_STATUS_STATE_DEFAULT (_DMA_STATUS_STATE_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_STATUS */ +#define DMA_STATUS_STATE_IDLE (_DMA_STATUS_STATE_IDLE << 4) /* Shifted mode IDLE for DMA_STATUS */ +#define DMA_STATUS_STATE_RDCHCTRLDATA (_DMA_STATUS_STATE_RDCHCTRLDATA << 4) /* Shifted mode RDCHCTRLDATA for DMA_STATUS */ +#define DMA_STATUS_STATE_RDSRCENDPTR (_DMA_STATUS_STATE_RDSRCENDPTR << 4) /* Shifted mode RDSRCENDPTR for DMA_STATUS */ +#define DMA_STATUS_STATE_RDDSTENDPTR (_DMA_STATUS_STATE_RDDSTENDPTR << 4) /* Shifted mode RDDSTENDPTR for DMA_STATUS */ +#define DMA_STATUS_STATE_RDSRCDATA (_DMA_STATUS_STATE_RDSRCDATA << 4) /* Shifted mode RDSRCDATA for DMA_STATUS */ +#define DMA_STATUS_STATE_WRDSTDATA (_DMA_STATUS_STATE_WRDSTDATA << 4) /* Shifted mode WRDSTDATA for DMA_STATUS */ +#define DMA_STATUS_STATE_WAITREQCLR (_DMA_STATUS_STATE_WAITREQCLR << 4) /* Shifted mode WAITREQCLR for DMA_STATUS */ +#define DMA_STATUS_STATE_WRCHCTRLDATA (_DMA_STATUS_STATE_WRCHCTRLDATA << 4) /* Shifted mode WRCHCTRLDATA for DMA_STATUS */ +#define DMA_STATUS_STATE_STALLED (_DMA_STATUS_STATE_STALLED << 4) /* Shifted mode STALLED for DMA_STATUS */ +#define DMA_STATUS_STATE_DONE (_DMA_STATUS_STATE_DONE << 4) /* Shifted mode DONE for DMA_STATUS */ +#define DMA_STATUS_STATE_PERSCATTRANS (_DMA_STATUS_STATE_PERSCATTRANS << 4) /* Shifted mode PERSCATTRANS for DMA_STATUS */ +#define _DMA_STATUS_CHNUM_SHIFT 16 /* Shift value for DMA_CHNUM */ +#define _DMA_STATUS_CHNUM_MASK 0x1F0000UL /* Bit mask for DMA_CHNUM */ +#define _DMA_STATUS_CHNUM_DEFAULT 0x0000000BUL /* Mode DEFAULT for DMA_STATUS */ +#define DMA_STATUS_CHNUM_DEFAULT (_DMA_STATUS_CHNUM_DEFAULT << 16) /* Shifted mode DEFAULT for DMA_STATUS */ + +/* Bit fields for DMA CONFIG */ + +#define _DMA_CONFIG_RESETVALUE 0x00000000UL /* Default value for DMA_CONFIG */ +#define _DMA_CONFIG_MASK 0x00000021UL /* Mask for DMA_CONFIG */ + +#define DMA_CONFIG_EN (0x1UL << 0) /* Enable DMA */ +#define _DMA_CONFIG_EN_SHIFT 0 /* Shift value for DMA_EN */ +#define _DMA_CONFIG_EN_MASK 0x1UL /* Bit mask for DMA_EN */ +#define _DMA_CONFIG_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CONFIG */ +#define DMA_CONFIG_EN_DEFAULT (_DMA_CONFIG_EN_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CONFIG */ +#define DMA_CONFIG_CHPROT (0x1UL << 5) /* Channel Protection Control */ +#define _DMA_CONFIG_CHPROT_SHIFT 5 /* Shift value for DMA_CHPROT */ +#define _DMA_CONFIG_CHPROT_MASK 0x20UL /* Bit mask for DMA_CHPROT */ +#define _DMA_CONFIG_CHPROT_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CONFIG */ +#define DMA_CONFIG_CHPROT_DEFAULT (_DMA_CONFIG_CHPROT_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CONFIG */ + +/* Bit fields for DMA CTRLBASE */ + +#define _DMA_CTRLBASE_RESETVALUE 0x00000000UL /* Default value for DMA_CTRLBASE */ +#define _DMA_CTRLBASE_MASK 0xFFFFFFFFUL /* Mask for DMA_CTRLBASE */ + +#define _DMA_CTRLBASE_CTRLBASE_SHIFT 0 /* Shift value for DMA_CTRLBASE */ +#define _DMA_CTRLBASE_CTRLBASE_MASK 0xFFFFFFFFUL /* Bit mask for DMA_CTRLBASE */ +#define _DMA_CTRLBASE_CTRLBASE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CTRLBASE */ +#define DMA_CTRLBASE_CTRLBASE_DEFAULT (_DMA_CTRLBASE_CTRLBASE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CTRLBASE */ + +/* Bit fields for DMA ALTCTRLBASE */ + +#define _DMA_ALTCTRLBASE_RESETVALUE 0x00000100UL /* Default value for DMA_ALTCTRLBASE */ +#define _DMA_ALTCTRLBASE_MASK 0xFFFFFFFFUL /* Mask for DMA_ALTCTRLBASE */ + +#define _DMA_ALTCTRLBASE_ALTCTRLBASE_SHIFT 0 /* Shift value for DMA_ALTCTRLBASE */ +#define _DMA_ALTCTRLBASE_ALTCTRLBASE_MASK 0xFFFFFFFFUL /* Bit mask for DMA_ALTCTRLBASE */ +#define _DMA_ALTCTRLBASE_ALTCTRLBASE_DEFAULT 0x00000100UL /* Mode DEFAULT for DMA_ALTCTRLBASE */ +#define DMA_ALTCTRLBASE_ALTCTRLBASE_DEFAULT (_DMA_ALTCTRLBASE_ALTCTRLBASE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_ALTCTRLBASE */ + +/* Bit fields for DMA CHWAITSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHWAITSTATUS_RESETVALUE 0x00000FFFUL /* Default value for DMA_CHWAITSTATUS */ +# define _DMA_CHWAITSTATUS_MASK 0x00000FFFUL /* Mask for DMA_CHWAITSTATUS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHWAITSTATUS_RESETVALUE 0x000000FFUL /* Default value for DMA_CHWAITSTATUS */ +# define _DMA_CHWAITSTATUS_MASK 0x000000FFUL /* Mask for DMA_CHWAITSTATUS */ +#endif + +#define DMA_CHWAITSTATUS_CH0WAITSTATUS (0x1UL << 0) /* Channel 0 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH0WAITSTATUS_SHIFT 0 /* Shift value for DMA_CH0WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH0WAITSTATUS_MASK 0x1UL /* Bit mask for DMA_CH0WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH0WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH0WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH0WAITSTATUS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH1WAITSTATUS (0x1UL << 1) /* Channel 1 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH1WAITSTATUS_SHIFT 1 /* Shift value for DMA_CH1WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH1WAITSTATUS_MASK 0x2UL /* Bit mask for DMA_CH1WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH1WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH1WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH1WAITSTATUS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH2WAITSTATUS (0x1UL << 2) /* Channel 2 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH2WAITSTATUS_SHIFT 2 /* Shift value for DMA_CH2WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH2WAITSTATUS_MASK 0x4UL /* Bit mask for DMA_CH2WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH2WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH2WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH2WAITSTATUS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH3WAITSTATUS (0x1UL << 3) /* Channel 3 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH3WAITSTATUS_SHIFT 3 /* Shift value for DMA_CH3WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH3WAITSTATUS_MASK 0x8UL /* Bit mask for DMA_CH3WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH3WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH3WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH3WAITSTATUS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH4WAITSTATUS (0x1UL << 4) /* Channel 4 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH4WAITSTATUS_SHIFT 4 /* Shift value for DMA_CH4WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH4WAITSTATUS_MASK 0x10UL /* Bit mask for DMA_CH4WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH4WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH4WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH4WAITSTATUS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH5WAITSTATUS (0x1UL << 5) /* Channel 5 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH5WAITSTATUS_SHIFT 5 /* Shift value for DMA_CH5WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH5WAITSTATUS_MASK 0x20UL /* Bit mask for DMA_CH5WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH5WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH5WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH5WAITSTATUS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH6WAITSTATUS (0x1UL << 6) /* Channel 6 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH6WAITSTATUS_SHIFT 6 /* Shift value for DMA_CH6WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH6WAITSTATUS_MASK 0x40UL /* Bit mask for DMA_CH6WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH6WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH6WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH6WAITSTATUS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH7WAITSTATUS (0x1UL << 7) /* Channel 7 Wait on Request Status */ +#define _DMA_CHWAITSTATUS_CH7WAITSTATUS_SHIFT 7 /* Shift value for DMA_CH7WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH7WAITSTATUS_MASK 0x80UL /* Bit mask for DMA_CH7WAITSTATUS */ +#define _DMA_CHWAITSTATUS_CH7WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CH7WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH7WAITSTATUS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHWAITSTATUS_CH8WAITSTATUS (0x1UL << 8) /* Channel 8 Wait on Request Status */ +# define _DMA_CHWAITSTATUS_CH8WAITSTATUS_SHIFT 8 /* Shift value for DMA_CH8WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH8WAITSTATUS_MASK 0x100UL /* Bit mask for DMA_CH8WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH8WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH8WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH8WAITSTATUS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH9WAITSTATUS (0x1UL << 9) /* Channel 9 Wait on Request Status */ +# define _DMA_CHWAITSTATUS_CH9WAITSTATUS_SHIFT 9 /* Shift value for DMA_CH9WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH9WAITSTATUS_MASK 0x200UL /* Bit mask for DMA_CH9WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH9WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH9WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH9WAITSTATUS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH10WAITSTATUS (0x1UL << 10) /* Channel 10 Wait on Request Status */ +# define _DMA_CHWAITSTATUS_CH10WAITSTATUS_SHIFT 10 /* Shift value for DMA_CH10WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH10WAITSTATUS_MASK 0x400UL /* Bit mask for DMA_CH10WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH10WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH10WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH10WAITSTATUS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH11WAITSTATUS (0x1UL << 11) /* Channel 11 Wait on Request Status */ +# define _DMA_CHWAITSTATUS_CH11WAITSTATUS_SHIFT 11 /* Shift value for DMA_CH11WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH11WAITSTATUS_MASK 0x800UL /* Bit mask for DMA_CH11WAITSTATUS */ +# define _DMA_CHWAITSTATUS_CH11WAITSTATUS_DEFAULT 0x00000001UL /* Mode DEFAULT for DMA_CHWAITSTATUS */ +# define DMA_CHWAITSTATUS_CH11WAITSTATUS_DEFAULT (_DMA_CHWAITSTATUS_CH11WAITSTATUS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHWAITSTATUS */ +#endif + +/* Bit fields for DMA CHSWREQ */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHSWREQ_RESETVALUE 0x00000000UL /* Default value for DMA_CHSWREQ */ +# define _DMA_CHSWREQ_MASK 0x00000FFFUL /* Mask for DMA_CHSWREQ */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHSWREQ_RESETVALUE 0x00000000UL /* Default value for DMA_CHSWREQ */ +# define _DMA_CHSWREQ_MASK 0x000000FFUL /* Mask for DMA_CHSWREQ */ +#endif + +#define DMA_CHSWREQ_CH0SWREQ (0x1UL << 0) /* Channel 0 Software Request */ +#define _DMA_CHSWREQ_CH0SWREQ_SHIFT 0 /* Shift value for DMA_CH0SWREQ */ +#define _DMA_CHSWREQ_CH0SWREQ_MASK 0x1UL /* Bit mask for DMA_CH0SWREQ */ +#define _DMA_CHSWREQ_CH0SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH0SWREQ_DEFAULT (_DMA_CHSWREQ_CH0SWREQ_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH1SWREQ (0x1UL << 1) /* Channel 1 Software Request */ +#define _DMA_CHSWREQ_CH1SWREQ_SHIFT 1 /* Shift value for DMA_CH1SWREQ */ +#define _DMA_CHSWREQ_CH1SWREQ_MASK 0x2UL /* Bit mask for DMA_CH1SWREQ */ +#define _DMA_CHSWREQ_CH1SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH1SWREQ_DEFAULT (_DMA_CHSWREQ_CH1SWREQ_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH2SWREQ (0x1UL << 2) /* Channel 2 Software Request */ +#define _DMA_CHSWREQ_CH2SWREQ_SHIFT 2 /* Shift value for DMA_CH2SWREQ */ +#define _DMA_CHSWREQ_CH2SWREQ_MASK 0x4UL /* Bit mask for DMA_CH2SWREQ */ +#define _DMA_CHSWREQ_CH2SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH2SWREQ_DEFAULT (_DMA_CHSWREQ_CH2SWREQ_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH3SWREQ (0x1UL << 3) /* Channel 3 Software Request */ +#define _DMA_CHSWREQ_CH3SWREQ_SHIFT 3 /* Shift value for DMA_CH3SWREQ */ +#define _DMA_CHSWREQ_CH3SWREQ_MASK 0x8UL /* Bit mask for DMA_CH3SWREQ */ +#define _DMA_CHSWREQ_CH3SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH3SWREQ_DEFAULT (_DMA_CHSWREQ_CH3SWREQ_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH4SWREQ (0x1UL << 4) /* Channel 4 Software Request */ +#define _DMA_CHSWREQ_CH4SWREQ_SHIFT 4 /* Shift value for DMA_CH4SWREQ */ +#define _DMA_CHSWREQ_CH4SWREQ_MASK 0x10UL /* Bit mask for DMA_CH4SWREQ */ +#define _DMA_CHSWREQ_CH4SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH4SWREQ_DEFAULT (_DMA_CHSWREQ_CH4SWREQ_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH5SWREQ (0x1UL << 5) /* Channel 5 Software Request */ +#define _DMA_CHSWREQ_CH5SWREQ_SHIFT 5 /* Shift value for DMA_CH5SWREQ */ +#define _DMA_CHSWREQ_CH5SWREQ_MASK 0x20UL /* Bit mask for DMA_CH5SWREQ */ +#define _DMA_CHSWREQ_CH5SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH5SWREQ_DEFAULT (_DMA_CHSWREQ_CH5SWREQ_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH6SWREQ (0x1UL << 6) /* Channel 6 Software Request */ +#define _DMA_CHSWREQ_CH6SWREQ_SHIFT 6 /* Shift value for DMA_CH6SWREQ */ +#define _DMA_CHSWREQ_CH6SWREQ_MASK 0x40UL /* Bit mask for DMA_CH6SWREQ */ +#define _DMA_CHSWREQ_CH6SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH6SWREQ_DEFAULT (_DMA_CHSWREQ_CH6SWREQ_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH7SWREQ (0x1UL << 7) /* Channel 7 Software Request */ +#define _DMA_CHSWREQ_CH7SWREQ_SHIFT 7 /* Shift value for DMA_CH7SWREQ */ +#define _DMA_CHSWREQ_CH7SWREQ_MASK 0x80UL /* Bit mask for DMA_CH7SWREQ */ +#define _DMA_CHSWREQ_CH7SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +#define DMA_CHSWREQ_CH7SWREQ_DEFAULT (_DMA_CHSWREQ_CH7SWREQ_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHSWREQ */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHSWREQ_CH8SWREQ (0x1UL << 8) /* Channel 8 Software Request */ +# define _DMA_CHSWREQ_CH8SWREQ_SHIFT 8 /* Shift value for DMA_CH8SWREQ */ +# define _DMA_CHSWREQ_CH8SWREQ_MASK 0x100UL /* Bit mask for DMA_CH8SWREQ */ +# define _DMA_CHSWREQ_CH8SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH8SWREQ_DEFAULT (_DMA_CHSWREQ_CH8SWREQ_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH9SWREQ (0x1UL << 9) /* Channel 9 Software Request */ +# define _DMA_CHSWREQ_CH9SWREQ_SHIFT 9 /* Shift value for DMA_CH9SWREQ */ +# define _DMA_CHSWREQ_CH9SWREQ_MASK 0x200UL /* Bit mask for DMA_CH9SWREQ */ +# define _DMA_CHSWREQ_CH9SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH9SWREQ_DEFAULT (_DMA_CHSWREQ_CH9SWREQ_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH10SWREQ (0x1UL << 10) /* Channel 10 Software Request */ +# define _DMA_CHSWREQ_CH10SWREQ_SHIFT 10 /* Shift value for DMA_CH10SWREQ */ +# define _DMA_CHSWREQ_CH10SWREQ_MASK 0x400UL /* Bit mask for DMA_CH10SWREQ */ +# define _DMA_CHSWREQ_CH10SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH10SWREQ_DEFAULT (_DMA_CHSWREQ_CH10SWREQ_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH11SWREQ (0x1UL << 11) /* Channel 11 Software Request */ +# define _DMA_CHSWREQ_CH11SWREQ_SHIFT 11 /* Shift value for DMA_CH11SWREQ */ +# define _DMA_CHSWREQ_CH11SWREQ_MASK 0x800UL /* Bit mask for DMA_CH11SWREQ */ +# define _DMA_CHSWREQ_CH11SWREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSWREQ */ +# define DMA_CHSWREQ_CH11SWREQ_DEFAULT (_DMA_CHSWREQ_CH11SWREQ_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHSWREQ */ +#endif + +/* Bit fields for DMA CHUSEBURSTS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHUSEBURSTS_RESETVALUE 0x00000000UL /* Default value for DMA_CHUSEBURSTS */ +# define _DMA_CHUSEBURSTS_MASK 0x00000FFFUL /* Mask for DMA_CHUSEBURSTS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHUSEBURSTS_RESETVALUE 0x00000000UL /* Default value for DMA_CHUSEBURSTS */ +# define _DMA_CHUSEBURSTS_MASK 0x000000FFUL /* Mask for DMA_CHUSEBURSTS */ +#endif + +#define DMA_CHUSEBURSTS_CH0USEBURSTS (0x1UL << 0) /* Channel 0 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH0USEBURSTS_SHIFT 0 /* Shift value for DMA_CH0USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH0USEBURSTS_MASK 0x1UL /* Bit mask for DMA_CH0USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH0USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define _DMA_CHUSEBURSTS_CH0USEBURSTS_SINGLEANDBURST 0x00000000UL /* Mode SINGLEANDBURST for DMA_CHUSEBURSTS */ +#define _DMA_CHUSEBURSTS_CH0USEBURSTS_BURSTONLY 0x00000001UL /* Mode BURSTONLY for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH0USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH0USEBURSTS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH0USEBURSTS_SINGLEANDBURST (_DMA_CHUSEBURSTS_CH0USEBURSTS_SINGLEANDBURST << 0) /* Shifted mode SINGLEANDBURST for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH0USEBURSTS_BURSTONLY (_DMA_CHUSEBURSTS_CH0USEBURSTS_BURSTONLY << 0) /* Shifted mode BURSTONLY for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH1USEBURSTS (0x1UL << 1) /* Channel 1 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH1USEBURSTS_SHIFT 1 /* Shift value for DMA_CH1USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH1USEBURSTS_MASK 0x2UL /* Bit mask for DMA_CH1USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH1USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH1USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH1USEBURSTS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH2USEBURSTS (0x1UL << 2) /* Channel 2 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH2USEBURSTS_SHIFT 2 /* Shift value for DMA_CH2USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH2USEBURSTS_MASK 0x4UL /* Bit mask for DMA_CH2USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH2USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH2USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH2USEBURSTS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH3USEBURSTS (0x1UL << 3) /* Channel 3 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH3USEBURSTS_SHIFT 3 /* Shift value for DMA_CH3USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH3USEBURSTS_MASK 0x8UL /* Bit mask for DMA_CH3USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH3USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH3USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH3USEBURSTS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH4USEBURSTS (0x1UL << 4) /* Channel 4 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH4USEBURSTS_SHIFT 4 /* Shift value for DMA_CH4USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH4USEBURSTS_MASK 0x10UL /* Bit mask for DMA_CH4USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH4USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH4USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH4USEBURSTS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH5USEBURSTS (0x1UL << 5) /* Channel 5 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH5USEBURSTS_SHIFT 5 /* Shift value for DMA_CH5USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH5USEBURSTS_MASK 0x20UL /* Bit mask for DMA_CH5USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH5USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH5USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH5USEBURSTS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH6USEBURSTS (0x1UL << 6) /* Channel 6 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH6USEBURSTS_SHIFT 6 /* Shift value for DMA_CH6USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH6USEBURSTS_MASK 0x40UL /* Bit mask for DMA_CH6USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH6USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH6USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH6USEBURSTS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH7USEBURSTS (0x1UL << 7) /* Channel 7 Useburst Set */ +#define _DMA_CHUSEBURSTS_CH7USEBURSTS_SHIFT 7 /* Shift value for DMA_CH7USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH7USEBURSTS_MASK 0x80UL /* Bit mask for DMA_CH7USEBURSTS */ +#define _DMA_CHUSEBURSTS_CH7USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CH7USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH7USEBURSTS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHUSEBURSTS_CH8USEBURSTS (0x1UL << 8) /* Channel 8 Useburst Set */ +# define _DMA_CHUSEBURSTS_CH8USEBURSTS_SHIFT 8 /* Shift value for DMA_CH8USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH8USEBURSTS_MASK 0x100UL /* Bit mask for DMA_CH8USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH8USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH8USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH8USEBURSTS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH9USEBURSTS (0x1UL << 9) /* Channel 9 Useburst Set */ +# define _DMA_CHUSEBURSTS_CH9USEBURSTS_SHIFT 9 /* Shift value for DMA_CH9USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH9USEBURSTS_MASK 0x200UL /* Bit mask for DMA_CH9USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH9USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH9USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH9USEBURSTS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH10USEBURSTS (0x1UL << 10) /* Channel 10 Useburst Set */ +# define _DMA_CHUSEBURSTS_CH10USEBURSTS_SHIFT 10 /* Shift value for DMA_CH10USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH10USEBURSTS_MASK 0x400UL /* Bit mask for DMA_CH10USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH10USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH10USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH10USEBURSTS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH11USEBURSTS (0x1UL << 11) /* Channel 11 Useburst Set */ +# define _DMA_CHUSEBURSTS_CH11USEBURSTS_SHIFT 11 /* Shift value for DMA_CH11USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH11USEBURSTS_MASK 0x800UL /* Bit mask for DMA_CH11USEBURSTS */ +# define _DMA_CHUSEBURSTS_CH11USEBURSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTS */ +# define DMA_CHUSEBURSTS_CH11USEBURSTS_DEFAULT (_DMA_CHUSEBURSTS_CH11USEBURSTS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHUSEBURSTS */ +#endif + +/* Bit fields for DMA CHUSEBURSTC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHUSEBURSTC_RESETVALUE 0x00000000UL /* Default value for DMA_CHUSEBURSTC */ +# define _DMA_CHUSEBURSTC_MASK 0x00000FFFUL /* Mask for DMA_CHUSEBURSTC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHUSEBURSTC_RESETVALUE 0x00000000UL /* Default value for DMA_CHUSEBURSTC */ +# define _DMA_CHUSEBURSTC_MASK 0x000000FFUL /* Mask for DMA_CHUSEBURSTC */ +#endif + +#define DMA_CHUSEBURSTC_CH0USEBURSTC (0x1UL << 0) /* Channel 0 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH0USEBURSTC_SHIFT 0 /* Shift value for DMA_CH0USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH0USEBURSTC_MASK 0x1UL /* Bit mask for DMA_CH0USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH0USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH0USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH0USEBURSTC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH1USEBURSTC (0x1UL << 1) /* Channel 1 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH1USEBURSTC_SHIFT 1 /* Shift value for DMA_CH1USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH1USEBURSTC_MASK 0x2UL /* Bit mask for DMA_CH1USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH1USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH1USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH1USEBURSTC_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH2USEBURSTC (0x1UL << 2) /* Channel 2 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH2USEBURSTC_SHIFT 2 /* Shift value for DMA_CH2USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH2USEBURSTC_MASK 0x4UL /* Bit mask for DMA_CH2USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH2USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH2USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH2USEBURSTC_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH3USEBURSTC (0x1UL << 3) /* Channel 3 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH3USEBURSTC_SHIFT 3 /* Shift value for DMA_CH3USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH3USEBURSTC_MASK 0x8UL /* Bit mask for DMA_CH3USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH3USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH3USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH3USEBURSTC_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH4USEBURSTC (0x1UL << 4) /* Channel 4 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH4USEBURSTC_SHIFT 4 /* Shift value for DMA_CH4USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH4USEBURSTC_MASK 0x10UL /* Bit mask for DMA_CH4USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH4USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH4USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH4USEBURSTC_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH5USEBURSTC (0x1UL << 5) /* Channel 5 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH5USEBURSTC_SHIFT 5 /* Shift value for DMA_CH5USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH5USEBURSTC_MASK 0x20UL /* Bit mask for DMA_CH5USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH5USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH5USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH5USEBURSTC_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH6USEBURSTC (0x1UL << 6) /* Channel 6 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH6USEBURSTC_SHIFT 6 /* Shift value for DMA_CH6USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH6USEBURSTC_MASK 0x40UL /* Bit mask for DMA_CH6USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH6USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH6USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH6USEBURSTC_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH7USEBURSTC (0x1UL << 7) /* Channel 7 Useburst Clear */ +#define _DMA_CHUSEBURSTC_CH7USEBURSTC_SHIFT 7 /* Shift value for DMA_CH7USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH7USEBURSTC_MASK 0x80UL /* Bit mask for DMA_CH7USEBURSTC */ +#define _DMA_CHUSEBURSTC_CH7USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CH7USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH7USEBURSTC_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHUSEBURSTC_CH08USEBURSTC (0x1UL << 8) /* Channel 8 Useburst Clear */ +# define _DMA_CHUSEBURSTC_CH08USEBURSTC_SHIFT 8 /* Shift value for DMA_CH08USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH08USEBURSTC_MASK 0x100UL /* Bit mask for DMA_CH08USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH08USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH08USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH08USEBURSTC_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH9USEBURSTC (0x1UL << 9) /* Channel 9 Useburst Clear */ +# define _DMA_CHUSEBURSTC_CH9USEBURSTC_SHIFT 9 /* Shift value for DMA_CH9USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH9USEBURSTC_MASK 0x200UL /* Bit mask for DMA_CH9USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH9USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH9USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH9USEBURSTC_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH10USEBURSTC (0x1UL << 10) /* Channel 10 Useburst Clear */ +# define _DMA_CHUSEBURSTC_CH10USEBURSTC_SHIFT 10 /* Shift value for DMA_CH10USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH10USEBURSTC_MASK 0x400UL /* Bit mask for DMA_CH10USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH10USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH10USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH10USEBURSTC_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH11USEBURSTC (0x1UL << 11) /* Channel 11 Useburst Clear */ +# define _DMA_CHUSEBURSTC_CH11USEBURSTC_SHIFT 11 /* Shift value for DMA_CH11USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH11USEBURSTC_MASK 0x800UL /* Bit mask for DMA_CH11USEBURSTC */ +# define _DMA_CHUSEBURSTC_CH11USEBURSTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHUSEBURSTC */ +# define DMA_CHUSEBURSTC_CH11USEBURSTC_DEFAULT (_DMA_CHUSEBURSTC_CH11USEBURSTC_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHUSEBURSTC */ +#endif + +/* Bit fields for DMA CHREQMASKS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHREQMASKS_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQMASKS */ +# define _DMA_CHREQMASKS_MASK 0x00000FFFUL /* Mask for DMA_CHREQMASKS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHREQMASKS_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQMASKS */ +# define _DMA_CHREQMASKS_MASK 0x000000FFUL /* Mask for DMA_CHREQMASKS */ +#endif + +#define DMA_CHREQMASKS_CH0REQMASKS (0x1UL << 0) /* Channel 0 Request Mask Set */ +#define _DMA_CHREQMASKS_CH0REQMASKS_SHIFT 0 /* Shift value for DMA_CH0REQMASKS */ +#define _DMA_CHREQMASKS_CH0REQMASKS_MASK 0x1UL /* Bit mask for DMA_CH0REQMASKS */ +#define _DMA_CHREQMASKS_CH0REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH0REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH0REQMASKS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH1REQMASKS (0x1UL << 1) /* Channel 1 Request Mask Set */ +#define _DMA_CHREQMASKS_CH1REQMASKS_SHIFT 1 /* Shift value for DMA_CH1REQMASKS */ +#define _DMA_CHREQMASKS_CH1REQMASKS_MASK 0x2UL /* Bit mask for DMA_CH1REQMASKS */ +#define _DMA_CHREQMASKS_CH1REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH1REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH1REQMASKS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH2REQMASKS (0x1UL << 2) /* Channel 2 Request Mask Set */ +#define _DMA_CHREQMASKS_CH2REQMASKS_SHIFT 2 /* Shift value for DMA_CH2REQMASKS */ +#define _DMA_CHREQMASKS_CH2REQMASKS_MASK 0x4UL /* Bit mask for DMA_CH2REQMASKS */ +#define _DMA_CHREQMASKS_CH2REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH2REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH2REQMASKS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH3REQMASKS (0x1UL << 3) /* Channel 3 Request Mask Set */ +#define _DMA_CHREQMASKS_CH3REQMASKS_SHIFT 3 /* Shift value for DMA_CH3REQMASKS */ +#define _DMA_CHREQMASKS_CH3REQMASKS_MASK 0x8UL /* Bit mask for DMA_CH3REQMASKS */ +#define _DMA_CHREQMASKS_CH3REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH3REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH3REQMASKS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH4REQMASKS (0x1UL << 4) /* Channel 4 Request Mask Set */ +#define _DMA_CHREQMASKS_CH4REQMASKS_SHIFT 4 /* Shift value for DMA_CH4REQMASKS */ +#define _DMA_CHREQMASKS_CH4REQMASKS_MASK 0x10UL /* Bit mask for DMA_CH4REQMASKS */ +#define _DMA_CHREQMASKS_CH4REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH4REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH4REQMASKS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH5REQMASKS (0x1UL << 5) /* Channel 5 Request Mask Set */ +#define _DMA_CHREQMASKS_CH5REQMASKS_SHIFT 5 /* Shift value for DMA_CH5REQMASKS */ +#define _DMA_CHREQMASKS_CH5REQMASKS_MASK 0x20UL /* Bit mask for DMA_CH5REQMASKS */ +#define _DMA_CHREQMASKS_CH5REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH5REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH5REQMASKS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH6REQMASKS (0x1UL << 6) /* Channel 6 Request Mask Set */ +#define _DMA_CHREQMASKS_CH6REQMASKS_SHIFT 6 /* Shift value for DMA_CH6REQMASKS */ +#define _DMA_CHREQMASKS_CH6REQMASKS_MASK 0x40UL /* Bit mask for DMA_CH6REQMASKS */ +#define _DMA_CHREQMASKS_CH6REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH6REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH6REQMASKS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH7REQMASKS (0x1UL << 7) /* Channel 7 Request Mask Set */ +#define _DMA_CHREQMASKS_CH7REQMASKS_SHIFT 7 /* Shift value for DMA_CH7REQMASKS */ +#define _DMA_CHREQMASKS_CH7REQMASKS_MASK 0x80UL /* Bit mask for DMA_CH7REQMASKS */ +#define _DMA_CHREQMASKS_CH7REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CH7REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH7REQMASKS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHREQMASKS_CH8REQMASKS (0x1UL << 8) /* Channel 8 Request Mask Set */ +# define _DMA_CHREQMASKS_CH8REQMASKS_SHIFT 8 /* Shift value for DMA_CH8REQMASKS */ +# define _DMA_CHREQMASKS_CH8REQMASKS_MASK 0x100UL /* Bit mask for DMA_CH8REQMASKS */ +# define _DMA_CHREQMASKS_CH8REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH8REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH8REQMASKS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH9REQMASKS (0x1UL << 9) /* Channel 9 Request Mask Set */ +# define _DMA_CHREQMASKS_CH9REQMASKS_SHIFT 9 /* Shift value for DMA_CH9REQMASKS */ +# define _DMA_CHREQMASKS_CH9REQMASKS_MASK 0x200UL /* Bit mask for DMA_CH9REQMASKS */ +# define _DMA_CHREQMASKS_CH9REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH9REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH9REQMASKS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH10REQMASKS (0x1UL << 10) /* Channel 10 Request Mask Set */ +# define _DMA_CHREQMASKS_CH10REQMASKS_SHIFT 10 /* Shift value for DMA_CH10REQMASKS */ +# define _DMA_CHREQMASKS_CH10REQMASKS_MASK 0x400UL /* Bit mask for DMA_CH10REQMASKS */ +# define _DMA_CHREQMASKS_CH10REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH10REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH10REQMASKS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH11REQMASKS (0x1UL << 11) /* Channel 11 Request Mask Set */ +# define _DMA_CHREQMASKS_CH11REQMASKS_SHIFT 11 /* Shift value for DMA_CH11REQMASKS */ +# define _DMA_CHREQMASKS_CH11REQMASKS_MASK 0x800UL /* Bit mask for DMA_CH11REQMASKS */ +# define _DMA_CHREQMASKS_CH11REQMASKS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKS */ +# define DMA_CHREQMASKS_CH11REQMASKS_DEFAULT (_DMA_CHREQMASKS_CH11REQMASKS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHREQMASKS */ +#endif + +/* Bit fields for DMA CHREQMASKC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHREQMASKC_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQMASKC */ +# define _DMA_CHREQMASKC_MASK 0x00000FFFUL /* Mask for DMA_CHREQMASKC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHREQMASKC_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQMASKC */ +# define _DMA_CHREQMASKC_MASK 0x000000FFUL /* Mask for DMA_CHREQMASKC */ +#endif + +#define DMA_CHREQMASKC_CH0REQMASKC (0x1UL << 0) /* Channel 0 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH0REQMASKC_SHIFT 0 /* Shift value for DMA_CH0REQMASKC */ +#define _DMA_CHREQMASKC_CH0REQMASKC_MASK 0x1UL /* Bit mask for DMA_CH0REQMASKC */ +#define _DMA_CHREQMASKC_CH0REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH0REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH0REQMASKC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH1REQMASKC (0x1UL << 1) /* Channel 1 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH1REQMASKC_SHIFT 1 /* Shift value for DMA_CH1REQMASKC */ +#define _DMA_CHREQMASKC_CH1REQMASKC_MASK 0x2UL /* Bit mask for DMA_CH1REQMASKC */ +#define _DMA_CHREQMASKC_CH1REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH1REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH1REQMASKC_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH2REQMASKC (0x1UL << 2) /* Channel 2 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH2REQMASKC_SHIFT 2 /* Shift value for DMA_CH2REQMASKC */ +#define _DMA_CHREQMASKC_CH2REQMASKC_MASK 0x4UL /* Bit mask for DMA_CH2REQMASKC */ +#define _DMA_CHREQMASKC_CH2REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH2REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH2REQMASKC_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH3REQMASKC (0x1UL << 3) /* Channel 3 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH3REQMASKC_SHIFT 3 /* Shift value for DMA_CH3REQMASKC */ +#define _DMA_CHREQMASKC_CH3REQMASKC_MASK 0x8UL /* Bit mask for DMA_CH3REQMASKC */ +#define _DMA_CHREQMASKC_CH3REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH3REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH3REQMASKC_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH4REQMASKC (0x1UL << 4) /* Channel 4 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH4REQMASKC_SHIFT 4 /* Shift value for DMA_CH4REQMASKC */ +#define _DMA_CHREQMASKC_CH4REQMASKC_MASK 0x10UL /* Bit mask for DMA_CH4REQMASKC */ +#define _DMA_CHREQMASKC_CH4REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH4REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH4REQMASKC_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH5REQMASKC (0x1UL << 5) /* Channel 5 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH5REQMASKC_SHIFT 5 /* Shift value for DMA_CH5REQMASKC */ +#define _DMA_CHREQMASKC_CH5REQMASKC_MASK 0x20UL /* Bit mask for DMA_CH5REQMASKC */ +#define _DMA_CHREQMASKC_CH5REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH5REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH5REQMASKC_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH6REQMASKC (0x1UL << 6) /* Channel 6 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH6REQMASKC_SHIFT 6 /* Shift value for DMA_CH6REQMASKC */ +#define _DMA_CHREQMASKC_CH6REQMASKC_MASK 0x40UL /* Bit mask for DMA_CH6REQMASKC */ +#define _DMA_CHREQMASKC_CH6REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH6REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH6REQMASKC_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH7REQMASKC (0x1UL << 7) /* Channel 7 Request Mask Clear */ +#define _DMA_CHREQMASKC_CH7REQMASKC_SHIFT 7 /* Shift value for DMA_CH7REQMASKC */ +#define _DMA_CHREQMASKC_CH7REQMASKC_MASK 0x80UL /* Bit mask for DMA_CH7REQMASKC */ +#define _DMA_CHREQMASKC_CH7REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CH7REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH7REQMASKC_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHREQMASKC_CH8REQMASKC (0x1UL << 8) /* Channel 8 Request Mask Clear */ +# define _DMA_CHREQMASKC_CH8REQMASKC_SHIFT 8 /* Shift value for DMA_CH8REQMASKC */ +# define _DMA_CHREQMASKC_CH8REQMASKC_MASK 0x100UL /* Bit mask for DMA_CH8REQMASKC */ +# define _DMA_CHREQMASKC_CH8REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH8REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH8REQMASKC_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH9REQMASKC (0x1UL << 9) /* Channel 9 Request Mask Clear */ +# define _DMA_CHREQMASKC_CH9REQMASKC_SHIFT 9 /* Shift value for DMA_CH9REQMASKC */ +# define _DMA_CHREQMASKC_CH9REQMASKC_MASK 0x200UL /* Bit mask for DMA_CH9REQMASKC */ +# define _DMA_CHREQMASKC_CH9REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH9REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH9REQMASKC_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH10REQMASKC (0x1UL << 10) /* Channel 10 Request Mask Clear */ +# define _DMA_CHREQMASKC_CH10REQMASKC_SHIFT 10 /* Shift value for DMA_CH10REQMASKC */ +# define _DMA_CHREQMASKC_CH10REQMASKC_MASK 0x400UL /* Bit mask for DMA_CH10REQMASKC */ +# define _DMA_CHREQMASKC_CH10REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH10REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH10REQMASKC_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH11REQMASKC (0x1UL << 11) /* Channel 11 Request Mask Clear */ +# define _DMA_CHREQMASKC_CH11REQMASKC_SHIFT 11 /* Shift value for DMA_CH11REQMASKC */ +# define _DMA_CHREQMASKC_CH11REQMASKC_MASK 0x800UL /* Bit mask for DMA_CH11REQMASKC */ +# define _DMA_CHREQMASKC_CH11REQMASKC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQMASKC */ +# define DMA_CHREQMASKC_CH11REQMASKC_DEFAULT (_DMA_CHREQMASKC_CH11REQMASKC_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHREQMASKC */ +#endif + +/* Bit fields for DMA CHENS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHENS_RESETVALUE 0x00000000UL /* Default value for DMA_CHENS */ +# define _DMA_CHENS_MASK 0x00000FFFUL /* Mask for DMA_CHENS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHENS_RESETVALUE 0x00000000UL /* Default value for DMA_CHENS */ +# define _DMA_CHENS_MASK 0x000000FFUL /* Mask for DMA_CHENS */ +#endif + +#define DMA_CHENS_CH0ENS (0x1UL << 0) /* Channel 0 Enable Set */ +#define _DMA_CHENS_CH0ENS_SHIFT 0 /* Shift value for DMA_CH0ENS */ +#define _DMA_CHENS_CH0ENS_MASK 0x1UL /* Bit mask for DMA_CH0ENS */ +#define _DMA_CHENS_CH0ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH0ENS_DEFAULT (_DMA_CHENS_CH0ENS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH1ENS (0x1UL << 1) /* Channel 1 Enable Set */ +#define _DMA_CHENS_CH1ENS_SHIFT 1 /* Shift value for DMA_CH1ENS */ +#define _DMA_CHENS_CH1ENS_MASK 0x2UL /* Bit mask for DMA_CH1ENS */ +#define _DMA_CHENS_CH1ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH1ENS_DEFAULT (_DMA_CHENS_CH1ENS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH2ENS (0x1UL << 2) /* Channel 2 Enable Set */ +#define _DMA_CHENS_CH2ENS_SHIFT 2 /* Shift value for DMA_CH2ENS */ +#define _DMA_CHENS_CH2ENS_MASK 0x4UL /* Bit mask for DMA_CH2ENS */ +#define _DMA_CHENS_CH2ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH2ENS_DEFAULT (_DMA_CHENS_CH2ENS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH3ENS (0x1UL << 3) /* Channel 3 Enable Set */ +#define _DMA_CHENS_CH3ENS_SHIFT 3 /* Shift value for DMA_CH3ENS */ +#define _DMA_CHENS_CH3ENS_MASK 0x8UL /* Bit mask for DMA_CH3ENS */ +#define _DMA_CHENS_CH3ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH3ENS_DEFAULT (_DMA_CHENS_CH3ENS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH4ENS (0x1UL << 4) /* Channel 4 Enable Set */ +#define _DMA_CHENS_CH4ENS_SHIFT 4 /* Shift value for DMA_CH4ENS */ +#define _DMA_CHENS_CH4ENS_MASK 0x10UL /* Bit mask for DMA_CH4ENS */ +#define _DMA_CHENS_CH4ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH4ENS_DEFAULT (_DMA_CHENS_CH4ENS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH5ENS (0x1UL << 5) /* Channel 5 Enable Set */ +#define _DMA_CHENS_CH5ENS_SHIFT 5 /* Shift value for DMA_CH5ENS */ +#define _DMA_CHENS_CH5ENS_MASK 0x20UL /* Bit mask for DMA_CH5ENS */ +#define _DMA_CHENS_CH5ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH5ENS_DEFAULT (_DMA_CHENS_CH5ENS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH6ENS (0x1UL << 6) /* Channel 6 Enable Set */ +#define _DMA_CHENS_CH6ENS_SHIFT 6 /* Shift value for DMA_CH6ENS */ +#define _DMA_CHENS_CH6ENS_MASK 0x40UL /* Bit mask for DMA_CH6ENS */ +#define _DMA_CHENS_CH6ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH6ENS_DEFAULT (_DMA_CHENS_CH6ENS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH7ENS (0x1UL << 7) /* Channel 7 Enable Set */ +#define _DMA_CHENS_CH7ENS_SHIFT 7 /* Shift value for DMA_CH7ENS */ +#define _DMA_CHENS_CH7ENS_MASK 0x80UL /* Bit mask for DMA_CH7ENS */ +#define _DMA_CHENS_CH7ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +#define DMA_CHENS_CH7ENS_DEFAULT (_DMA_CHENS_CH7ENS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHENS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHENS_CH8ENS (0x1UL << 8) /* Channel 8 Enable Set */ +# define _DMA_CHENS_CH8ENS_SHIFT 8 /* Shift value for DMA_CH8ENS */ +# define _DMA_CHENS_CH8ENS_MASK 0x100UL /* Bit mask for DMA_CH8ENS */ +# define _DMA_CHENS_CH8ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH8ENS_DEFAULT (_DMA_CHENS_CH8ENS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH9ENS (0x1UL << 9) /* Channel 9 Enable Set */ +# define _DMA_CHENS_CH9ENS_SHIFT 9 /* Shift value for DMA_CH9ENS */ +# define _DMA_CHENS_CH9ENS_MASK 0x200UL /* Bit mask for DMA_CH9ENS */ +# define _DMA_CHENS_CH9ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH9ENS_DEFAULT (_DMA_CHENS_CH9ENS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH10ENS (0x1UL << 10) /* Channel 10 Enable Set */ +# define _DMA_CHENS_CH10ENS_SHIFT 10 /* Shift value for DMA_CH10ENS */ +# define _DMA_CHENS_CH10ENS_MASK 0x400UL /* Bit mask for DMA_CH10ENS */ +# define _DMA_CHENS_CH10ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH10ENS_DEFAULT (_DMA_CHENS_CH10ENS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH11ENS (0x1UL << 11) /* Channel 11 Enable Set */ +# define _DMA_CHENS_CH11ENS_SHIFT 11 /* Shift value for DMA_CH11ENS */ +# define _DMA_CHENS_CH11ENS_MASK 0x800UL /* Bit mask for DMA_CH11ENS */ +# define _DMA_CHENS_CH11ENS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENS */ +# define DMA_CHENS_CH11ENS_DEFAULT (_DMA_CHENS_CH11ENS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHENS */ +#endif + +/* Bit fields for DMA CHENC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHENC_RESETVALUE 0x00000000UL /* Default value for DMA_CHENC */ +# define _DMA_CHENC_MASK 0x00000FFFUL /* Mask for DMA_CHENC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHENC_RESETVALUE 0x00000000UL /* Default value for DMA_CHENC */ +# define _DMA_CHENC_MASK 0x000000FFUL /* Mask for DMA_CHENC */ +#endif + +#define DMA_CHENC_CH0ENC (0x1UL << 0) /* Channel 0 Enable Clear */ +#define _DMA_CHENC_CH0ENC_SHIFT 0 /* Shift value for DMA_CH0ENC */ +#define _DMA_CHENC_CH0ENC_MASK 0x1UL /* Bit mask for DMA_CH0ENC */ +#define _DMA_CHENC_CH0ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH0ENC_DEFAULT (_DMA_CHENC_CH0ENC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH1ENC (0x1UL << 1) /* Channel 1 Enable Clear */ +#define _DMA_CHENC_CH1ENC_SHIFT 1 /* Shift value for DMA_CH1ENC */ +#define _DMA_CHENC_CH1ENC_MASK 0x2UL /* Bit mask for DMA_CH1ENC */ +#define _DMA_CHENC_CH1ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH1ENC_DEFAULT (_DMA_CHENC_CH1ENC_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH2ENC (0x1UL << 2) /* Channel 2 Enable Clear */ +#define _DMA_CHENC_CH2ENC_SHIFT 2 /* Shift value for DMA_CH2ENC */ +#define _DMA_CHENC_CH2ENC_MASK 0x4UL /* Bit mask for DMA_CH2ENC */ +#define _DMA_CHENC_CH2ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH2ENC_DEFAULT (_DMA_CHENC_CH2ENC_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH3ENC (0x1UL << 3) /* Channel 3 Enable Clear */ +#define _DMA_CHENC_CH3ENC_SHIFT 3 /* Shift value for DMA_CH3ENC */ +#define _DMA_CHENC_CH3ENC_MASK 0x8UL /* Bit mask for DMA_CH3ENC */ +#define _DMA_CHENC_CH3ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH3ENC_DEFAULT (_DMA_CHENC_CH3ENC_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH4ENC (0x1UL << 4) /* Channel 4 Enable Clear */ +#define _DMA_CHENC_CH4ENC_SHIFT 4 /* Shift value for DMA_CH4ENC */ +#define _DMA_CHENC_CH4ENC_MASK 0x10UL /* Bit mask for DMA_CH4ENC */ +#define _DMA_CHENC_CH4ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH4ENC_DEFAULT (_DMA_CHENC_CH4ENC_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH5ENC (0x1UL << 5) /* Channel 5 Enable Clear */ +#define _DMA_CHENC_CH5ENC_SHIFT 5 /* Shift value for DMA_CH5ENC */ +#define _DMA_CHENC_CH5ENC_MASK 0x20UL /* Bit mask for DMA_CH5ENC */ +#define _DMA_CHENC_CH5ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH5ENC_DEFAULT (_DMA_CHENC_CH5ENC_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH6ENC (0x1UL << 6) /* Channel 6 Enable Clear */ +#define _DMA_CHENC_CH6ENC_SHIFT 6 /* Shift value for DMA_CH6ENC */ +#define _DMA_CHENC_CH6ENC_MASK 0x40UL /* Bit mask for DMA_CH6ENC */ +#define _DMA_CHENC_CH6ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH6ENC_DEFAULT (_DMA_CHENC_CH6ENC_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH7ENC (0x1UL << 7) /* Channel 7 Enable Clear */ +#define _DMA_CHENC_CH7ENC_SHIFT 7 /* Shift value for DMA_CH7ENC */ +#define _DMA_CHENC_CH7ENC_MASK 0x80UL /* Bit mask for DMA_CH7ENC */ +#define _DMA_CHENC_CH7ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +#define DMA_CHENC_CH7ENC_DEFAULT (_DMA_CHENC_CH7ENC_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHENC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHENC_CH8ENC (0x1UL << 8) /* Channel 8 Enable Clear */ +# define _DMA_CHENC_CH8ENC_SHIFT 8 /* Shift value for DMA_CH8ENC */ +# define _DMA_CHENC_CH8ENC_MASK 0x100UL /* Bit mask for DMA_CH8ENC */ +# define _DMA_CHENC_CH8ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH8ENC_DEFAULT (_DMA_CHENC_CH8ENC_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH9ENC (0x1UL << 9) /* Channel 9 Enable Clear */ +# define _DMA_CHENC_CH9ENC_SHIFT 9 /* Shift value for DMA_CH9ENC */ +# define _DMA_CHENC_CH9ENC_MASK 0x200UL /* Bit mask for DMA_CH9ENC */ +# define _DMA_CHENC_CH9ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH9ENC_DEFAULT (_DMA_CHENC_CH9ENC_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH10ENC (0x1UL << 10) /* Channel 10 Enable Clear */ +# define _DMA_CHENC_CH10ENC_SHIFT 10 /* Shift value for DMA_CH10ENC */ +# define _DMA_CHENC_CH10ENC_MASK 0x400UL /* Bit mask for DMA_CH10ENC */ +# define _DMA_CHENC_CH10ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH10ENC_DEFAULT (_DMA_CHENC_CH10ENC_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH11ENC (0x1UL << 11) /* Channel 11 Enable Clear */ +# define _DMA_CHENC_CH11ENC_SHIFT 11 /* Shift value for DMA_CH11ENC */ +# define _DMA_CHENC_CH11ENC_MASK 0x800UL /* Bit mask for DMA_CH11ENC */ +# define _DMA_CHENC_CH11ENC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHENC */ +# define DMA_CHENC_CH11ENC_DEFAULT (_DMA_CHENC_CH11ENC_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHENC */ +#endif + +/* Bit fields for DMA CHALTS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHALTS_RESETVALUE 0x00000000UL /* Default value for DMA_CHALTS */ +# define _DMA_CHALTS_MASK 0x00000FFFUL /* Mask for DMA_CHALTS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHALTS_RESETVALUE 0x00000000UL /* Default value for DMA_CHALTS */ +# define _DMA_CHALTS_MASK 0x000000FFUL /* Mask for DMA_CHALTS */ +#endif + +#define DMA_CHALTS_CH0ALTS (0x1UL << 0) /* Channel 0 Alternate Structure Set */ +#define _DMA_CHALTS_CH0ALTS_SHIFT 0 /* Shift value for DMA_CH0ALTS */ +#define _DMA_CHALTS_CH0ALTS_MASK 0x1UL /* Bit mask for DMA_CH0ALTS */ +#define _DMA_CHALTS_CH0ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH0ALTS_DEFAULT (_DMA_CHALTS_CH0ALTS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH1ALTS (0x1UL << 1) /* Channel 1 Alternate Structure Set */ +#define _DMA_CHALTS_CH1ALTS_SHIFT 1 /* Shift value for DMA_CH1ALTS */ +#define _DMA_CHALTS_CH1ALTS_MASK 0x2UL /* Bit mask for DMA_CH1ALTS */ +#define _DMA_CHALTS_CH1ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH1ALTS_DEFAULT (_DMA_CHALTS_CH1ALTS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH2ALTS (0x1UL << 2) /* Channel 2 Alternate Structure Set */ +#define _DMA_CHALTS_CH2ALTS_SHIFT 2 /* Shift value for DMA_CH2ALTS */ +#define _DMA_CHALTS_CH2ALTS_MASK 0x4UL /* Bit mask for DMA_CH2ALTS */ +#define _DMA_CHALTS_CH2ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH2ALTS_DEFAULT (_DMA_CHALTS_CH2ALTS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH3ALTS (0x1UL << 3) /* Channel 3 Alternate Structure Set */ +#define _DMA_CHALTS_CH3ALTS_SHIFT 3 /* Shift value for DMA_CH3ALTS */ +#define _DMA_CHALTS_CH3ALTS_MASK 0x8UL /* Bit mask for DMA_CH3ALTS */ +#define _DMA_CHALTS_CH3ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH3ALTS_DEFAULT (_DMA_CHALTS_CH3ALTS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH4ALTS (0x1UL << 4) /* Channel 4 Alternate Structure Set */ +#define _DMA_CHALTS_CH4ALTS_SHIFT 4 /* Shift value for DMA_CH4ALTS */ +#define _DMA_CHALTS_CH4ALTS_MASK 0x10UL /* Bit mask for DMA_CH4ALTS */ +#define _DMA_CHALTS_CH4ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH4ALTS_DEFAULT (_DMA_CHALTS_CH4ALTS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH5ALTS (0x1UL << 5) /* Channel 5 Alternate Structure Set */ +#define _DMA_CHALTS_CH5ALTS_SHIFT 5 /* Shift value for DMA_CH5ALTS */ +#define _DMA_CHALTS_CH5ALTS_MASK 0x20UL /* Bit mask for DMA_CH5ALTS */ +#define _DMA_CHALTS_CH5ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH5ALTS_DEFAULT (_DMA_CHALTS_CH5ALTS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH6ALTS (0x1UL << 6) /* Channel 6 Alternate Structure Set */ +#define _DMA_CHALTS_CH6ALTS_SHIFT 6 /* Shift value for DMA_CH6ALTS */ +#define _DMA_CHALTS_CH6ALTS_MASK 0x40UL /* Bit mask for DMA_CH6ALTS */ +#define _DMA_CHALTS_CH6ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH6ALTS_DEFAULT (_DMA_CHALTS_CH6ALTS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH7ALTS (0x1UL << 7) /* Channel 7 Alternate Structure Set */ +#define _DMA_CHALTS_CH7ALTS_SHIFT 7 /* Shift value for DMA_CH7ALTS */ +#define _DMA_CHALTS_CH7ALTS_MASK 0x80UL /* Bit mask for DMA_CH7ALTS */ +#define _DMA_CHALTS_CH7ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +#define DMA_CHALTS_CH7ALTS_DEFAULT (_DMA_CHALTS_CH7ALTS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHALTS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHALTS_CH8ALTS (0x1UL << 8) /* Channel 8 Alternate Structure Set */ +# define _DMA_CHALTS_CH8ALTS_SHIFT 8 /* Shift value for DMA_CH8ALTS */ +# define _DMA_CHALTS_CH8ALTS_MASK 0x100UL /* Bit mask for DMA_CH8ALTS */ +# define _DMA_CHALTS_CH8ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH8ALTS_DEFAULT (_DMA_CHALTS_CH8ALTS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH9ALTS (0x1UL << 9) /* Channel 9 Alternate Structure Set */ +# define _DMA_CHALTS_CH9ALTS_SHIFT 9 /* Shift value for DMA_CH9ALTS */ +# define _DMA_CHALTS_CH9ALTS_MASK 0x200UL /* Bit mask for DMA_CH9ALTS */ +# define _DMA_CHALTS_CH9ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH9ALTS_DEFAULT (_DMA_CHALTS_CH9ALTS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH10ALTS (0x1UL << 10) /* Channel 10 Alternate Structure Set */ +# define _DMA_CHALTS_CH10ALTS_SHIFT 10 /* Shift value for DMA_CH10ALTS */ +# define _DMA_CHALTS_CH10ALTS_MASK 0x400UL /* Bit mask for DMA_CH10ALTS */ +# define _DMA_CHALTS_CH10ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH10ALTS_DEFAULT (_DMA_CHALTS_CH10ALTS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH11ALTS (0x1UL << 11) /* Channel 11 Alternate Structure Set */ +# define _DMA_CHALTS_CH11ALTS_SHIFT 11 /* Shift value for DMA_CH11ALTS */ +# define _DMA_CHALTS_CH11ALTS_MASK 0x800UL /* Bit mask for DMA_CH11ALTS */ +# define _DMA_CHALTS_CH11ALTS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTS */ +# define DMA_CHALTS_CH11ALTS_DEFAULT (_DMA_CHALTS_CH11ALTS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHALTS */ +#endif + +/* Bit fields for DMA CHALTC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHALTC_RESETVALUE 0x00000000UL /* Default value for DMA_CHALTC */ +# define _DMA_CHALTC_MASK 0x00000FFFUL /* Mask for DMA_CHALTC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHALTC_RESETVALUE 0x00000000UL /* Default value for DMA_CHALTC */ +# define _DMA_CHALTC_MASK 0x000000FFUL /* Mask for DMA_CHALTC */ +#endif + +#define DMA_CHALTC_CH0ALTC (0x1UL << 0) /* Channel 0 Alternate Clear */ +#define _DMA_CHALTC_CH0ALTC_SHIFT 0 /* Shift value for DMA_CH0ALTC */ +#define _DMA_CHALTC_CH0ALTC_MASK 0x1UL /* Bit mask for DMA_CH0ALTC */ +#define _DMA_CHALTC_CH0ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH0ALTC_DEFAULT (_DMA_CHALTC_CH0ALTC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH1ALTC (0x1UL << 1) /* Channel 1 Alternate Clear */ +#define _DMA_CHALTC_CH1ALTC_SHIFT 1 /* Shift value for DMA_CH1ALTC */ +#define _DMA_CHALTC_CH1ALTC_MASK 0x2UL /* Bit mask for DMA_CH1ALTC */ +#define _DMA_CHALTC_CH1ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH1ALTC_DEFAULT (_DMA_CHALTC_CH1ALTC_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH2ALTC (0x1UL << 2) /* Channel 2 Alternate Clear */ +#define _DMA_CHALTC_CH2ALTC_SHIFT 2 /* Shift value for DMA_CH2ALTC */ +#define _DMA_CHALTC_CH2ALTC_MASK 0x4UL /* Bit mask for DMA_CH2ALTC */ +#define _DMA_CHALTC_CH2ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH2ALTC_DEFAULT (_DMA_CHALTC_CH2ALTC_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH3ALTC (0x1UL << 3) /* Channel 3 Alternate Clear */ +#define _DMA_CHALTC_CH3ALTC_SHIFT 3 /* Shift value for DMA_CH3ALTC */ +#define _DMA_CHALTC_CH3ALTC_MASK 0x8UL /* Bit mask for DMA_CH3ALTC */ +#define _DMA_CHALTC_CH3ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH3ALTC_DEFAULT (_DMA_CHALTC_CH3ALTC_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH4ALTC (0x1UL << 4) /* Channel 4 Alternate Clear */ +#define _DMA_CHALTC_CH4ALTC_SHIFT 4 /* Shift value for DMA_CH4ALTC */ +#define _DMA_CHALTC_CH4ALTC_MASK 0x10UL /* Bit mask for DMA_CH4ALTC */ +#define _DMA_CHALTC_CH4ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH4ALTC_DEFAULT (_DMA_CHALTC_CH4ALTC_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH5ALTC (0x1UL << 5) /* Channel 5 Alternate Clear */ +#define _DMA_CHALTC_CH5ALTC_SHIFT 5 /* Shift value for DMA_CH5ALTC */ +#define _DMA_CHALTC_CH5ALTC_MASK 0x20UL /* Bit mask for DMA_CH5ALTC */ +#define _DMA_CHALTC_CH5ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH5ALTC_DEFAULT (_DMA_CHALTC_CH5ALTC_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH6ALTC (0x1UL << 6) /* Channel 6 Alternate Clear */ +#define _DMA_CHALTC_CH6ALTC_SHIFT 6 /* Shift value for DMA_CH6ALTC */ +#define _DMA_CHALTC_CH6ALTC_MASK 0x40UL /* Bit mask for DMA_CH6ALTC */ +#define _DMA_CHALTC_CH6ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH6ALTC_DEFAULT (_DMA_CHALTC_CH6ALTC_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH7ALTC (0x1UL << 7) /* Channel 7 Alternate Clear */ +#define _DMA_CHALTC_CH7ALTC_SHIFT 7 /* Shift value for DMA_CH7ALTC */ +#define _DMA_CHALTC_CH7ALTC_MASK 0x80UL /* Bit mask for DMA_CH7ALTC */ +#define _DMA_CHALTC_CH7ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +#define DMA_CHALTC_CH7ALTC_DEFAULT (_DMA_CHALTC_CH7ALTC_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHALTC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHALTC_CH8ALTC (0x1UL << 8) /* Channel 8 Alternate Clear */ +# define _DMA_CHALTC_CH8ALTC_SHIFT 8 /* Shift value for DMA_CH8ALTC */ +# define _DMA_CHALTC_CH8ALTC_MASK 0x100UL /* Bit mask for DMA_CH8ALTC */ +# define _DMA_CHALTC_CH8ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH8ALTC_DEFAULT (_DMA_CHALTC_CH8ALTC_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH9ALTC (0x1UL << 9) /* Channel 9 Alternate Clear */ +# define _DMA_CHALTC_CH9ALTC_SHIFT 9 /* Shift value for DMA_CH9ALTC */ +# define _DMA_CHALTC_CH9ALTC_MASK 0x200UL /* Bit mask for DMA_CH9ALTC */ +# define _DMA_CHALTC_CH9ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH9ALTC_DEFAULT (_DMA_CHALTC_CH9ALTC_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH10ALTC (0x1UL << 10) /* Channel 10 Alternate Clear */ +# define _DMA_CHALTC_CH10ALTC_SHIFT 10 /* Shift value for DMA_CH10ALTC */ +# define _DMA_CHALTC_CH10ALTC_MASK 0x400UL /* Bit mask for DMA_CH10ALTC */ +# define _DMA_CHALTC_CH10ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH10ALTC_DEFAULT (_DMA_CHALTC_CH10ALTC_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH11ALTC (0x1UL << 11) /* Channel 11 Alternate Clear */ +# define _DMA_CHALTC_CH11ALTC_SHIFT 11 /* Shift value for DMA_CH11ALTC */ +# define _DMA_CHALTC_CH11ALTC_MASK 0x800UL /* Bit mask for DMA_CH11ALTC */ +# define _DMA_CHALTC_CH11ALTC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHALTC */ +# define DMA_CHALTC_CH11ALTC_DEFAULT (_DMA_CHALTC_CH11ALTC_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHALTC */ +#endif + +/* Bit fields for DMA CHPRIS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHPRIS_RESETVALUE 0x00000000UL /* Default value for DMA_CHPRIS */ +# define _DMA_CHPRIS_MASK 0x00000FFFUL /* Mask for DMA_CHPRIS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHPRIS_RESETVALUE 0x00000000UL /* Default value for DMA_CHPRIS */ +# define _DMA_CHPRIS_MASK 0x000000FFUL /* Mask for DMA_CHPRIS */ +#endif + +#define DMA_CHPRIS_CH0PRIS (0x1UL << 0) /* Channel 0 High Priority Set */ +#define _DMA_CHPRIS_CH0PRIS_SHIFT 0 /* Shift value for DMA_CH0PRIS */ +#define _DMA_CHPRIS_CH0PRIS_MASK 0x1UL /* Bit mask for DMA_CH0PRIS */ +#define _DMA_CHPRIS_CH0PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH0PRIS_DEFAULT (_DMA_CHPRIS_CH0PRIS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH1PRIS (0x1UL << 1) /* Channel 1 High Priority Set */ +#define _DMA_CHPRIS_CH1PRIS_SHIFT 1 /* Shift value for DMA_CH1PRIS */ +#define _DMA_CHPRIS_CH1PRIS_MASK 0x2UL /* Bit mask for DMA_CH1PRIS */ +#define _DMA_CHPRIS_CH1PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH1PRIS_DEFAULT (_DMA_CHPRIS_CH1PRIS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH2PRIS (0x1UL << 2) /* Channel 2 High Priority Set */ +#define _DMA_CHPRIS_CH2PRIS_SHIFT 2 /* Shift value for DMA_CH2PRIS */ +#define _DMA_CHPRIS_CH2PRIS_MASK 0x4UL /* Bit mask for DMA_CH2PRIS */ +#define _DMA_CHPRIS_CH2PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH2PRIS_DEFAULT (_DMA_CHPRIS_CH2PRIS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH3PRIS (0x1UL << 3) /* Channel 3 High Priority Set */ +#define _DMA_CHPRIS_CH3PRIS_SHIFT 3 /* Shift value for DMA_CH3PRIS */ +#define _DMA_CHPRIS_CH3PRIS_MASK 0x8UL /* Bit mask for DMA_CH3PRIS */ +#define _DMA_CHPRIS_CH3PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH3PRIS_DEFAULT (_DMA_CHPRIS_CH3PRIS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH4PRIS (0x1UL << 4) /* Channel 4 High Priority Set */ +#define _DMA_CHPRIS_CH4PRIS_SHIFT 4 /* Shift value for DMA_CH4PRIS */ +#define _DMA_CHPRIS_CH4PRIS_MASK 0x10UL /* Bit mask for DMA_CH4PRIS */ +#define _DMA_CHPRIS_CH4PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH4PRIS_DEFAULT (_DMA_CHPRIS_CH4PRIS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH5PRIS (0x1UL << 5) /* Channel 5 High Priority Set */ +#define _DMA_CHPRIS_CH5PRIS_SHIFT 5 /* Shift value for DMA_CH5PRIS */ +#define _DMA_CHPRIS_CH5PRIS_MASK 0x20UL /* Bit mask for DMA_CH5PRIS */ +#define _DMA_CHPRIS_CH5PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH5PRIS_DEFAULT (_DMA_CHPRIS_CH5PRIS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH6PRIS (0x1UL << 6) /* Channel 6 High Priority Set */ +#define _DMA_CHPRIS_CH6PRIS_SHIFT 6 /* Shift value for DMA_CH6PRIS */ +#define _DMA_CHPRIS_CH6PRIS_MASK 0x40UL /* Bit mask for DMA_CH6PRIS */ +#define _DMA_CHPRIS_CH6PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH6PRIS_DEFAULT (_DMA_CHPRIS_CH6PRIS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH7PRIS (0x1UL << 7) /* Channel 7 High Priority Set */ +#define _DMA_CHPRIS_CH7PRIS_SHIFT 7 /* Shift value for DMA_CH7PRIS */ +#define _DMA_CHPRIS_CH7PRIS_MASK 0x80UL /* Bit mask for DMA_CH7PRIS */ +#define _DMA_CHPRIS_CH7PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +#define DMA_CHPRIS_CH7PRIS_DEFAULT (_DMA_CHPRIS_CH7PRIS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHPRIS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHPRIS_CH8PRIS (0x1UL << 8) /* Channel 8 High Priority Set */ +# define _DMA_CHPRIS_CH8PRIS_SHIFT 8 /* Shift value for DMA_CH8PRIS */ +# define _DMA_CHPRIS_CH8PRIS_MASK 0x100UL /* Bit mask for DMA_CH8PRIS */ +# define _DMA_CHPRIS_CH8PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH8PRIS_DEFAULT (_DMA_CHPRIS_CH8PRIS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH9PRIS (0x1UL << 9) /* Channel 9 High Priority Set */ +# define _DMA_CHPRIS_CH9PRIS_SHIFT 9 /* Shift value for DMA_CH9PRIS */ +# define _DMA_CHPRIS_CH9PRIS_MASK 0x200UL /* Bit mask for DMA_CH9PRIS */ +# define _DMA_CHPRIS_CH9PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH9PRIS_DEFAULT (_DMA_CHPRIS_CH9PRIS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH10PRIS (0x1UL << 10) /* Channel 10 High Priority Set */ +# define _DMA_CHPRIS_CH10PRIS_SHIFT 10 /* Shift value for DMA_CH10PRIS */ +# define _DMA_CHPRIS_CH10PRIS_MASK 0x400UL /* Bit mask for DMA_CH10PRIS */ +# define _DMA_CHPRIS_CH10PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH10PRIS_DEFAULT (_DMA_CHPRIS_CH10PRIS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH11PRIS (0x1UL << 11) /* Channel 11 High Priority Set */ +# define _DMA_CHPRIS_CH11PRIS_SHIFT 11 /* Shift value for DMA_CH11PRIS */ +# define _DMA_CHPRIS_CH11PRIS_MASK 0x800UL /* Bit mask for DMA_CH11PRIS */ +# define _DMA_CHPRIS_CH11PRIS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIS */ +# define DMA_CHPRIS_CH11PRIS_DEFAULT (_DMA_CHPRIS_CH11PRIS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHPRIS */ +#endif + +/* Bit fields for DMA CHPRIC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHPRIC_RESETVALUE 0x00000000UL /* Default value for DMA_CHPRIC */ +# define _DMA_CHPRIC_MASK 0x00000FFFUL /* Mask for DMA_CHPRIC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHPRIC_RESETVALUE 0x00000000UL /* Default value for DMA_CHPRIC */ +# define _DMA_CHPRIC_MASK 0x000000FFUL /* Mask for DMA_CHPRIC */ +#endif + +#define DMA_CHPRIC_CH0PRIC (0x1UL << 0) /* Channel 0 High Priority Clear */ +#define _DMA_CHPRIC_CH0PRIC_SHIFT 0 /* Shift value for DMA_CH0PRIC */ +#define _DMA_CHPRIC_CH0PRIC_MASK 0x1UL /* Bit mask for DMA_CH0PRIC */ +#define _DMA_CHPRIC_CH0PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH0PRIC_DEFAULT (_DMA_CHPRIC_CH0PRIC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH1PRIC (0x1UL << 1) /* Channel 1 High Priority Clear */ +#define _DMA_CHPRIC_CH1PRIC_SHIFT 1 /* Shift value for DMA_CH1PRIC */ +#define _DMA_CHPRIC_CH1PRIC_MASK 0x2UL /* Bit mask for DMA_CH1PRIC */ +#define _DMA_CHPRIC_CH1PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH1PRIC_DEFAULT (_DMA_CHPRIC_CH1PRIC_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH2PRIC (0x1UL << 2) /* Channel 2 High Priority Clear */ +#define _DMA_CHPRIC_CH2PRIC_SHIFT 2 /* Shift value for DMA_CH2PRIC */ +#define _DMA_CHPRIC_CH2PRIC_MASK 0x4UL /* Bit mask for DMA_CH2PRIC */ +#define _DMA_CHPRIC_CH2PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH2PRIC_DEFAULT (_DMA_CHPRIC_CH2PRIC_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH3PRIC (0x1UL << 3) /* Channel 3 High Priority Clear */ +#define _DMA_CHPRIC_CH3PRIC_SHIFT 3 /* Shift value for DMA_CH3PRIC */ +#define _DMA_CHPRIC_CH3PRIC_MASK 0x8UL /* Bit mask for DMA_CH3PRIC */ +#define _DMA_CHPRIC_CH3PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH3PRIC_DEFAULT (_DMA_CHPRIC_CH3PRIC_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH4PRIC (0x1UL << 4) /* Channel 4 High Priority Clear */ +#define _DMA_CHPRIC_CH4PRIC_SHIFT 4 /* Shift value for DMA_CH4PRIC */ +#define _DMA_CHPRIC_CH4PRIC_MASK 0x10UL /* Bit mask for DMA_CH4PRIC */ +#define _DMA_CHPRIC_CH4PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH4PRIC_DEFAULT (_DMA_CHPRIC_CH4PRIC_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH5PRIC (0x1UL << 5) /* Channel 5 High Priority Clear */ +#define _DMA_CHPRIC_CH5PRIC_SHIFT 5 /* Shift value for DMA_CH5PRIC */ +#define _DMA_CHPRIC_CH5PRIC_MASK 0x20UL /* Bit mask for DMA_CH5PRIC */ +#define _DMA_CHPRIC_CH5PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH5PRIC_DEFAULT (_DMA_CHPRIC_CH5PRIC_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH6PRIC (0x1UL << 6) /* Channel 6 High Priority Clear */ +#define _DMA_CHPRIC_CH6PRIC_SHIFT 6 /* Shift value for DMA_CH6PRIC */ +#define _DMA_CHPRIC_CH6PRIC_MASK 0x40UL /* Bit mask for DMA_CH6PRIC */ +#define _DMA_CHPRIC_CH6PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH6PRIC_DEFAULT (_DMA_CHPRIC_CH6PRIC_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH7PRIC (0x1UL << 7) /* Channel 7 High Priority Clear */ +#define _DMA_CHPRIC_CH7PRIC_SHIFT 7 /* Shift value for DMA_CH7PRIC */ +#define _DMA_CHPRIC_CH7PRIC_MASK 0x80UL /* Bit mask for DMA_CH7PRIC */ +#define _DMA_CHPRIC_CH7PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +#define DMA_CHPRIC_CH7PRIC_DEFAULT (_DMA_CHPRIC_CH7PRIC_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHPRIC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHPRIC_CH8PRIC (0x1UL << 8) /* Channel 8 High Priority Clear */ +# define _DMA_CHPRIC_CH8PRIC_SHIFT 8 /* Shift value for DMA_CH8PRIC */ +# define _DMA_CHPRIC_CH8PRIC_MASK 0x100UL /* Bit mask for DMA_CH8PRIC */ +# define _DMA_CHPRIC_CH8PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH8PRIC_DEFAULT (_DMA_CHPRIC_CH8PRIC_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH9PRIC (0x1UL << 9) /* Channel 9 High Priority Clear */ +# define _DMA_CHPRIC_CH9PRIC_SHIFT 9 /* Shift value for DMA_CH9PRIC */ +# define _DMA_CHPRIC_CH9PRIC_MASK 0x200UL /* Bit mask for DMA_CH9PRIC */ +# define _DMA_CHPRIC_CH9PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH9PRIC_DEFAULT (_DMA_CHPRIC_CH9PRIC_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH10PRIC (0x1UL << 10) /* Channel 10 High Priority Clear */ +# define _DMA_CHPRIC_CH10PRIC_SHIFT 10 /* Shift value for DMA_CH10PRIC */ +# define _DMA_CHPRIC_CH10PRIC_MASK 0x400UL /* Bit mask for DMA_CH10PRIC */ +# define _DMA_CHPRIC_CH10PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH10PRIC_DEFAULT (_DMA_CHPRIC_CH10PRIC_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH11PRIC (0x1UL << 11) /* Channel 11 High Priority Clear */ +# define _DMA_CHPRIC_CH11PRIC_SHIFT 11 /* Shift value for DMA_CH11PRIC */ +# define _DMA_CHPRIC_CH11PRIC_MASK 0x800UL /* Bit mask for DMA_CH11PRIC */ +# define _DMA_CHPRIC_CH11PRIC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHPRIC */ +# define DMA_CHPRIC_CH11PRIC_DEFAULT (_DMA_CHPRIC_CH11PRIC_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHPRIC */ +#endif + +/* Bit fields for DMA ERRORC */ + +#define _DMA_ERRORC_RESETVALUE 0x00000000UL /* Default value for DMA_ERRORC */ +#define _DMA_ERRORC_MASK 0x00000001UL /* Mask for DMA_ERRORC */ + +#define DMA_ERRORC_ERRORC (0x1UL << 0) /* Bus Error Clear */ +#define _DMA_ERRORC_ERRORC_SHIFT 0 /* Shift value for DMA_ERRORC */ +#define _DMA_ERRORC_ERRORC_MASK 0x1UL /* Bit mask for DMA_ERRORC */ +#define _DMA_ERRORC_ERRORC_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_ERRORC */ +#define DMA_ERRORC_ERRORC_DEFAULT (_DMA_ERRORC_ERRORC_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_ERRORC */ + +/* Bit fields for DMA CHREQSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHREQSTATUS_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQSTATUS */ +# define _DMA_CHREQSTATUS_MASK 0x00000FFFUL /* Mask for DMA_CHREQSTATUS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHREQSTATUS_RESETVALUE 0x00000000UL /* Default value for DMA_CHREQSTATUS */ +# define _DMA_CHREQSTATUS_MASK 0x000000FFUL /* Mask for DMA_CHREQSTATUS */ +#endif + +#define DMA_CHREQSTATUS_CH0REQSTATUS (0x1UL << 0) /* Channel 0 Request Status */ +#define _DMA_CHREQSTATUS_CH0REQSTATUS_SHIFT 0 /* Shift value for DMA_CH0REQSTATUS */ +#define _DMA_CHREQSTATUS_CH0REQSTATUS_MASK 0x1UL /* Bit mask for DMA_CH0REQSTATUS */ +#define _DMA_CHREQSTATUS_CH0REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH0REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH0REQSTATUS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH1REQSTATUS (0x1UL << 1) /* Channel 1 Request Status */ +#define _DMA_CHREQSTATUS_CH1REQSTATUS_SHIFT 1 /* Shift value for DMA_CH1REQSTATUS */ +#define _DMA_CHREQSTATUS_CH1REQSTATUS_MASK 0x2UL /* Bit mask for DMA_CH1REQSTATUS */ +#define _DMA_CHREQSTATUS_CH1REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH1REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH1REQSTATUS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH2REQSTATUS (0x1UL << 2) /* Channel 2 Request Status */ +#define _DMA_CHREQSTATUS_CH2REQSTATUS_SHIFT 2 /* Shift value for DMA_CH2REQSTATUS */ +#define _DMA_CHREQSTATUS_CH2REQSTATUS_MASK 0x4UL /* Bit mask for DMA_CH2REQSTATUS */ +#define _DMA_CHREQSTATUS_CH2REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH2REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH2REQSTATUS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH3REQSTATUS (0x1UL << 3) /* Channel 3 Request Status */ +#define _DMA_CHREQSTATUS_CH3REQSTATUS_SHIFT 3 /* Shift value for DMA_CH3REQSTATUS */ +#define _DMA_CHREQSTATUS_CH3REQSTATUS_MASK 0x8UL /* Bit mask for DMA_CH3REQSTATUS */ +#define _DMA_CHREQSTATUS_CH3REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH3REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH3REQSTATUS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH4REQSTATUS (0x1UL << 4) /* Channel 4 Request Status */ +#define _DMA_CHREQSTATUS_CH4REQSTATUS_SHIFT 4 /* Shift value for DMA_CH4REQSTATUS */ +#define _DMA_CHREQSTATUS_CH4REQSTATUS_MASK 0x10UL /* Bit mask for DMA_CH4REQSTATUS */ +#define _DMA_CHREQSTATUS_CH4REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH4REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH4REQSTATUS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH5REQSTATUS (0x1UL << 5) /* Channel 5 Request Status */ +#define _DMA_CHREQSTATUS_CH5REQSTATUS_SHIFT 5 /* Shift value for DMA_CH5REQSTATUS */ +#define _DMA_CHREQSTATUS_CH5REQSTATUS_MASK 0x20UL /* Bit mask for DMA_CH5REQSTATUS */ +#define _DMA_CHREQSTATUS_CH5REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH5REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH5REQSTATUS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH6REQSTATUS (0x1UL << 6) /* Channel 6 Request Status */ +#define _DMA_CHREQSTATUS_CH6REQSTATUS_SHIFT 6 /* Shift value for DMA_CH6REQSTATUS */ +#define _DMA_CHREQSTATUS_CH6REQSTATUS_MASK 0x40UL /* Bit mask for DMA_CH6REQSTATUS */ +#define _DMA_CHREQSTATUS_CH6REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH6REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH6REQSTATUS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH7REQSTATUS (0x1UL << 7) /* Channel 7 Request Status */ +#define _DMA_CHREQSTATUS_CH7REQSTATUS_SHIFT 7 /* Shift value for DMA_CH7REQSTATUS */ +#define _DMA_CHREQSTATUS_CH7REQSTATUS_MASK 0x80UL /* Bit mask for DMA_CH7REQSTATUS */ +#define _DMA_CHREQSTATUS_CH7REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CH7REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH7REQSTATUS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHREQSTATUS_CH8REQSTATUS (0x1UL << 8) /* Channel 8 Request Status */ +# define _DMA_CHREQSTATUS_CH8REQSTATUS_SHIFT 8 /* Shift value for DMA_CH8REQSTATUS */ +# define _DMA_CHREQSTATUS_CH8REQSTATUS_MASK 0x100UL /* Bit mask for DMA_CH8REQSTATUS */ +# define _DMA_CHREQSTATUS_CH8REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH8REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH8REQSTATUS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH9REQSTATUS (0x1UL << 9) /* Channel 9 Request Status */ +# define _DMA_CHREQSTATUS_CH9REQSTATUS_SHIFT 9 /* Shift value for DMA_CH9REQSTATUS */ +# define _DMA_CHREQSTATUS_CH9REQSTATUS_MASK 0x200UL /* Bit mask for DMA_CH9REQSTATUS */ +# define _DMA_CHREQSTATUS_CH9REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH9REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH9REQSTATUS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH10REQSTATUS (0x1UL << 10) /* Channel 10 Request Status */ +# define _DMA_CHREQSTATUS_CH10REQSTATUS_SHIFT 10 /* Shift value for DMA_CH10REQSTATUS */ +# define _DMA_CHREQSTATUS_CH10REQSTATUS_MASK 0x400UL /* Bit mask for DMA_CH10REQSTATUS */ +# define _DMA_CHREQSTATUS_CH10REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH10REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH10REQSTATUS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH11REQSTATUS (0x1UL << 11) /* Channel 11 Request Status */ +# define _DMA_CHREQSTATUS_CH11REQSTATUS_SHIFT 11 /* Shift value for DMA_CH11REQSTATUS */ +# define _DMA_CHREQSTATUS_CH11REQSTATUS_MASK 0x800UL /* Bit mask for DMA_CH11REQSTATUS */ +# define _DMA_CHREQSTATUS_CH11REQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHREQSTATUS */ +# define DMA_CHREQSTATUS_CH11REQSTATUS_DEFAULT (_DMA_CHREQSTATUS_CH11REQSTATUS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHREQSTATUS */ +#endif + +/* Bit fields for DMA CHSREQSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CHSREQSTATUS_RESETVALUE 0x00000000UL /* Default value for DMA_CHSREQSTATUS */ +# define _DMA_CHSREQSTATUS_MASK 0x00000FFFUL /* Mask for DMA_CHSREQSTATUS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_CHSREQSTATUS_RESETVALUE 0x00000000UL /* Default value for DMA_CHSREQSTATUS */ +# define _DMA_CHSREQSTATUS_MASK 0x000000FFUL /* Mask for DMA_CHSREQSTATUS */ +#endif + +#define DMA_CHSREQSTATUS_CH0SREQSTATUS (0x1UL << 0) /* Channel 0 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH0SREQSTATUS_SHIFT 0 /* Shift value for DMA_CH0SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH0SREQSTATUS_MASK 0x1UL /* Bit mask for DMA_CH0SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH0SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH0SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH0SREQSTATUS_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH1SREQSTATUS (0x1UL << 1) /* Channel 1 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH1SREQSTATUS_SHIFT 1 /* Shift value for DMA_CH1SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH1SREQSTATUS_MASK 0x2UL /* Bit mask for DMA_CH1SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH1SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH1SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH1SREQSTATUS_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH2SREQSTATUS (0x1UL << 2) /* Channel 2 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH2SREQSTATUS_SHIFT 2 /* Shift value for DMA_CH2SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH2SREQSTATUS_MASK 0x4UL /* Bit mask for DMA_CH2SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH2SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH2SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH2SREQSTATUS_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH3SREQSTATUS (0x1UL << 3) /* Channel 3 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH3SREQSTATUS_SHIFT 3 /* Shift value for DMA_CH3SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH3SREQSTATUS_MASK 0x8UL /* Bit mask for DMA_CH3SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH3SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH3SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH3SREQSTATUS_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH4SREQSTATUS (0x1UL << 4) /* Channel 4 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH4SREQSTATUS_SHIFT 4 /* Shift value for DMA_CH4SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH4SREQSTATUS_MASK 0x10UL /* Bit mask for DMA_CH4SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH4SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH4SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH4SREQSTATUS_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH5SREQSTATUS (0x1UL << 5) /* Channel 5 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH5SREQSTATUS_SHIFT 5 /* Shift value for DMA_CH5SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH5SREQSTATUS_MASK 0x20UL /* Bit mask for DMA_CH5SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH5SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH5SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH5SREQSTATUS_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH6SREQSTATUS (0x1UL << 6) /* Channel 6 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH6SREQSTATUS_SHIFT 6 /* Shift value for DMA_CH6SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH6SREQSTATUS_MASK 0x40UL /* Bit mask for DMA_CH6SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH6SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH6SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH6SREQSTATUS_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH7SREQSTATUS (0x1UL << 7) /* Channel 7 Single Request Status */ +#define _DMA_CHSREQSTATUS_CH7SREQSTATUS_SHIFT 7 /* Shift value for DMA_CH7SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH7SREQSTATUS_MASK 0x80UL /* Bit mask for DMA_CH7SREQSTATUS */ +#define _DMA_CHSREQSTATUS_CH7SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CH7SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH7SREQSTATUS_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_CHSREQSTATUS_CH8SREQSTATUS (0x1UL << 8) /* Channel 8 Single Request Status */ +# define _DMA_CHSREQSTATUS_CH8SREQSTATUS_SHIFT 8 /* Shift value for DMA_CH8SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH8SREQSTATUS_MASK 0x100UL /* Bit mask for DMA_CH8SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH8SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH8SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH8SREQSTATUS_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH9SREQSTATUS (0x1UL << 9) /* Channel 9 Single Request Status */ +# define _DMA_CHSREQSTATUS_CH9SREQSTATUS_SHIFT 9 /* Shift value for DMA_CH9SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH9SREQSTATUS_MASK 0x200UL /* Bit mask for DMA_CH9SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH9SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH9SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH9SREQSTATUS_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH10SREQSTATUS (0x1UL << 10) /* Channel 10 Single Request Status */ +# define _DMA_CHSREQSTATUS_CH10SREQSTATUS_SHIFT 10 /* Shift value for DMA_CH10SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH10SREQSTATUS_MASK 0x400UL /* Bit mask for DMA_CH10SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH10SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH10SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH10SREQSTATUS_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH11SREQSTATUS (0x1UL << 11) /* Channel 11 Single Request Status */ +# define _DMA_CHSREQSTATUS_CH11SREQSTATUS_SHIFT 11 /* Shift value for DMA_CH11SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH11SREQSTATUS_MASK 0x800UL /* Bit mask for DMA_CH11SREQSTATUS */ +# define _DMA_CHSREQSTATUS_CH11SREQSTATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CHSREQSTATUS */ +# define DMA_CHSREQSTATUS_CH11SREQSTATUS_DEFAULT (_DMA_CHSREQSTATUS_CH11SREQSTATUS_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_CHSREQSTATUS */ +#endif + +/* Bit fields for DMA IF */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_IF_RESETVALUE 0x00000000UL /* Default value for DMA_IF */ +# define _DMA_IF_MASK 0x80000FFFUL /* Mask for DMA_IF */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_IF_RESETVALUE 0x00000000UL /* Default value for DMA_IF */ +# define _DMA_IF_MASK 0x800000FFUL /* Mask for DMA_IF */ +#endif + +#define DMA_IF_CH0DONE (0x1UL << 0) /* DMA Channel 0 Complete Interrupt Flag */ +#define _DMA_IF_CH0DONE_SHIFT 0 /* Shift value for DMA_CH0DONE */ +#define _DMA_IF_CH0DONE_MASK 0x1UL /* Bit mask for DMA_CH0DONE */ +#define _DMA_IF_CH0DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH0DONE_DEFAULT (_DMA_IF_CH0DONE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH1DONE (0x1UL << 1) /* DMA Channel 1 Complete Interrupt Flag */ +#define _DMA_IF_CH1DONE_SHIFT 1 /* Shift value for DMA_CH1DONE */ +#define _DMA_IF_CH1DONE_MASK 0x2UL /* Bit mask for DMA_CH1DONE */ +#define _DMA_IF_CH1DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH1DONE_DEFAULT (_DMA_IF_CH1DONE_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH2DONE (0x1UL << 2) /* DMA Channel 2 Complete Interrupt Flag */ +#define _DMA_IF_CH2DONE_SHIFT 2 /* Shift value for DMA_CH2DONE */ +#define _DMA_IF_CH2DONE_MASK 0x4UL /* Bit mask for DMA_CH2DONE */ +#define _DMA_IF_CH2DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH2DONE_DEFAULT (_DMA_IF_CH2DONE_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH3DONE (0x1UL << 3) /* DMA Channel 3 Complete Interrupt Flag */ +#define _DMA_IF_CH3DONE_SHIFT 3 /* Shift value for DMA_CH3DONE */ +#define _DMA_IF_CH3DONE_MASK 0x8UL /* Bit mask for DMA_CH3DONE */ +#define _DMA_IF_CH3DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH3DONE_DEFAULT (_DMA_IF_CH3DONE_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH4DONE (0x1UL << 4) /* DMA Channel 4 Complete Interrupt Flag */ +#define _DMA_IF_CH4DONE_SHIFT 4 /* Shift value for DMA_CH4DONE */ +#define _DMA_IF_CH4DONE_MASK 0x10UL /* Bit mask for DMA_CH4DONE */ +#define _DMA_IF_CH4DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH4DONE_DEFAULT (_DMA_IF_CH4DONE_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH5DONE (0x1UL << 5) /* DMA Channel 5 Complete Interrupt Flag */ +#define _DMA_IF_CH5DONE_SHIFT 5 /* Shift value for DMA_CH5DONE */ +#define _DMA_IF_CH5DONE_MASK 0x20UL /* Bit mask for DMA_CH5DONE */ +#define _DMA_IF_CH5DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH5DONE_DEFAULT (_DMA_IF_CH5DONE_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH6DONE (0x1UL << 6) /* DMA Channel 6 Complete Interrupt Flag */ +#define _DMA_IF_CH6DONE_SHIFT 6 /* Shift value for DMA_CH6DONE */ +#define _DMA_IF_CH6DONE_MASK 0x40UL /* Bit mask for DMA_CH6DONE */ +#define _DMA_IF_CH6DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH6DONE_DEFAULT (_DMA_IF_CH6DONE_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_IF */ +#define DMA_IF_CH7DONE (0x1UL << 7) /* DMA Channel 7 Complete Interrupt Flag */ +#define _DMA_IF_CH7DONE_SHIFT 7 /* Shift value for DMA_CH7DONE */ +#define _DMA_IF_CH7DONE_MASK 0x80UL /* Bit mask for DMA_CH7DONE */ +#define _DMA_IF_CH7DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +#define DMA_IF_CH7DONE_DEFAULT (_DMA_IF_CH7DONE_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_IF */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_IF_CH8DONE (0x1UL << 8) /* DMA Channel 8 Complete Interrupt Flag */ +# define _DMA_IF_CH8DONE_SHIFT 8 /* Shift value for DMA_CH8DONE */ +# define _DMA_IF_CH8DONE_MASK 0x100UL /* Bit mask for DMA_CH8DONE */ +# define _DMA_IF_CH8DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +# define DMA_IF_CH8DONE_DEFAULT (_DMA_IF_CH8DONE_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_IF */ +# define DMA_IF_CH9DONE (0x1UL << 9) /* DMA Channel 9 Complete Interrupt Flag */ +# define _DMA_IF_CH9DONE_SHIFT 9 /* Shift value for DMA_CH9DONE */ +# define _DMA_IF_CH9DONE_MASK 0x200UL /* Bit mask for DMA_CH9DONE */ +# define _DMA_IF_CH9DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +# define DMA_IF_CH9DONE_DEFAULT (_DMA_IF_CH9DONE_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_IF */ +# define DMA_IF_CH10DONE (0x1UL << 10) /* DMA Channel 10 Complete Interrupt Flag */ +# define _DMA_IF_CH10DONE_SHIFT 10 /* Shift value for DMA_CH10DONE */ +# define _DMA_IF_CH10DONE_MASK 0x400UL /* Bit mask for DMA_CH10DONE */ +# define _DMA_IF_CH10DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +# define DMA_IF_CH10DONE_DEFAULT (_DMA_IF_CH10DONE_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_IF */ +# define DMA_IF_CH11DONE (0x1UL << 11) /* DMA Channel 11 Complete Interrupt Flag */ +# define _DMA_IF_CH11DONE_SHIFT 11 /* Shift value for DMA_CH11DONE */ +# define _DMA_IF_CH11DONE_MASK 0x800UL /* Bit mask for DMA_CH11DONE */ +# define _DMA_IF_CH11DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +# define DMA_IF_CH11DONE_DEFAULT (_DMA_IF_CH11DONE_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_IF */ +# define DMA_IF_ERR (0x1UL << 31) /* DMA Error Interrupt Flag */ +# define _DMA_IF_ERR_SHIFT 31 /* Shift value for DMA_ERR */ +# define _DMA_IF_ERR_MASK 0x80000000UL /* Bit mask for DMA_ERR */ +# define _DMA_IF_ERR_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IF */ +# define DMA_IF_ERR_DEFAULT (_DMA_IF_ERR_DEFAULT << 31) /* Shifted mode DEFAULT for DMA_IF */ +#endif + +/* Bit fields for DMA IFS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_IFS_RESETVALUE 0x00000000UL /* Default value for DMA_IFS */ +# define _DMA_IFS_MASK 0x80000FFFUL /* Mask for DMA_IFS */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_IFS_RESETVALUE 0x00000000UL /* Default value for DMA_IFS */ +# define _DMA_IFS_MASK 0x800000FFUL /* Mask for DMA_IFS */ +#endif + +#define DMA_IFS_CH0DONE (0x1UL << 0) /* DMA Channel 0 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH0DONE_SHIFT 0 /* Shift value for DMA_CH0DONE */ +#define _DMA_IFS_CH0DONE_MASK 0x1UL /* Bit mask for DMA_CH0DONE */ +#define _DMA_IFS_CH0DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH0DONE_DEFAULT (_DMA_IFS_CH0DONE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH1DONE (0x1UL << 1) /* DMA Channel 1 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH1DONE_SHIFT 1 /* Shift value for DMA_CH1DONE */ +#define _DMA_IFS_CH1DONE_MASK 0x2UL /* Bit mask for DMA_CH1DONE */ +#define _DMA_IFS_CH1DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH1DONE_DEFAULT (_DMA_IFS_CH1DONE_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH2DONE (0x1UL << 2) /* DMA Channel 2 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH2DONE_SHIFT 2 /* Shift value for DMA_CH2DONE */ +#define _DMA_IFS_CH2DONE_MASK 0x4UL /* Bit mask for DMA_CH2DONE */ +#define _DMA_IFS_CH2DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH2DONE_DEFAULT (_DMA_IFS_CH2DONE_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH3DONE (0x1UL << 3) /* DMA Channel 3 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH3DONE_SHIFT 3 /* Shift value for DMA_CH3DONE */ +#define _DMA_IFS_CH3DONE_MASK 0x8UL /* Bit mask for DMA_CH3DONE */ +#define _DMA_IFS_CH3DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH3DONE_DEFAULT (_DMA_IFS_CH3DONE_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH4DONE (0x1UL << 4) /* DMA Channel 4 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH4DONE_SHIFT 4 /* Shift value for DMA_CH4DONE */ +#define _DMA_IFS_CH4DONE_MASK 0x10UL /* Bit mask for DMA_CH4DONE */ +#define _DMA_IFS_CH4DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH4DONE_DEFAULT (_DMA_IFS_CH4DONE_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH5DONE (0x1UL << 5) /* DMA Channel 5 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH5DONE_SHIFT 5 /* Shift value for DMA_CH5DONE */ +#define _DMA_IFS_CH5DONE_MASK 0x20UL /* Bit mask for DMA_CH5DONE */ +#define _DMA_IFS_CH5DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH5DONE_DEFAULT (_DMA_IFS_CH5DONE_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH6DONE (0x1UL << 6) /* DMA Channel 6 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH6DONE_SHIFT 6 /* Shift value for DMA_CH6DONE */ +#define _DMA_IFS_CH6DONE_MASK 0x40UL /* Bit mask for DMA_CH6DONE */ +#define _DMA_IFS_CH6DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH6DONE_DEFAULT (_DMA_IFS_CH6DONE_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH7DONE (0x1UL << 7) /* DMA Channel 7 Complete Interrupt Flag Set */ +#define _DMA_IFS_CH7DONE_SHIFT 7 /* Shift value for DMA_CH7DONE */ +#define _DMA_IFS_CH7DONE_MASK 0x80UL /* Bit mask for DMA_CH7DONE */ +#define _DMA_IFS_CH7DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +#define DMA_IFS_CH7DONE_DEFAULT (_DMA_IFS_CH7DONE_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_IFS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_IFS_CH8DONE (0x1UL << 8) /* DMA Channel 8 Complete Interrupt Flag Set */ +# define _DMA_IFS_CH8DONE_SHIFT 8 /* Shift value for DMA_CH8DONE */ +# define _DMA_IFS_CH8DONE_MASK 0x100UL /* Bit mask for DMA_CH8DONE */ +# define _DMA_IFS_CH8DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH8DONE_DEFAULT (_DMA_IFS_CH8DONE_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH9DONE (0x1UL << 9) /* DMA Channel 9 Complete Interrupt Flag Set */ +# define _DMA_IFS_CH9DONE_SHIFT 9 /* Shift value for DMA_CH9DONE */ +# define _DMA_IFS_CH9DONE_MASK 0x200UL /* Bit mask for DMA_CH9DONE */ +# define _DMA_IFS_CH9DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH9DONE_DEFAULT (_DMA_IFS_CH9DONE_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH10DONE (0x1UL << 10) /* DMA Channel 10 Complete Interrupt Flag Set */ +# define _DMA_IFS_CH10DONE_SHIFT 10 /* Shift value for DMA_CH10DONE */ +# define _DMA_IFS_CH10DONE_MASK 0x400UL /* Bit mask for DMA_CH10DONE */ +# define _DMA_IFS_CH10DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH10DONE_DEFAULT (_DMA_IFS_CH10DONE_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH11DONE (0x1UL << 11) /* DMA Channel 11 Complete Interrupt Flag Set */ +# define _DMA_IFS_CH11DONE_SHIFT 11 /* Shift value for DMA_CH11DONE */ +# define _DMA_IFS_CH11DONE_MASK 0x800UL /* Bit mask for DMA_CH11DONE */ +# define _DMA_IFS_CH11DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +# define DMA_IFS_CH11DONE_DEFAULT (_DMA_IFS_CH11DONE_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_IFS */ +# define DMA_IFS_ERR (0x1UL << 31) /* DMA Error Interrupt Flag Set */ +# define _DMA_IFS_ERR_SHIFT 31 /* Shift value for DMA_ERR */ +# define _DMA_IFS_ERR_MASK 0x80000000UL /* Bit mask for DMA_ERR */ +# define _DMA_IFS_ERR_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFS */ +# define DMA_IFS_ERR_DEFAULT (_DMA_IFS_ERR_DEFAULT << 31) /* Shifted mode DEFAULT for DMA_IFS */ +#endif + +/* Bit fields for DMA IFC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_IFC_RESETVALUE 0x00000000UL /* Default value for DMA_IFC */ +# define _DMA_IFC_MASK 0x80000FFFUL /* Mask for DMA_IFC */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_IFC_RESETVALUE 0x00000000UL /* Default value for DMA_IFC */ +# define _DMA_IFC_MASK 0x800000FFUL /* Mask for DMA_IFC */ +#endif + +#define DMA_IFC_CH0DONE (0x1UL << 0) /* DMA Channel 0 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH0DONE_SHIFT 0 /* Shift value for DMA_CH0DONE */ +#define _DMA_IFC_CH0DONE_MASK 0x1UL /* Bit mask for DMA_CH0DONE */ +#define _DMA_IFC_CH0DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH0DONE_DEFAULT (_DMA_IFC_CH0DONE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH1DONE (0x1UL << 1) /* DMA Channel 1 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH1DONE_SHIFT 1 /* Shift value for DMA_CH1DONE */ +#define _DMA_IFC_CH1DONE_MASK 0x2UL /* Bit mask for DMA_CH1DONE */ +#define _DMA_IFC_CH1DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH1DONE_DEFAULT (_DMA_IFC_CH1DONE_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH2DONE (0x1UL << 2) /* DMA Channel 2 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH2DONE_SHIFT 2 /* Shift value for DMA_CH2DONE */ +#define _DMA_IFC_CH2DONE_MASK 0x4UL /* Bit mask for DMA_CH2DONE */ +#define _DMA_IFC_CH2DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH2DONE_DEFAULT (_DMA_IFC_CH2DONE_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH3DONE (0x1UL << 3) /* DMA Channel 3 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH3DONE_SHIFT 3 /* Shift value for DMA_CH3DONE */ +#define _DMA_IFC_CH3DONE_MASK 0x8UL /* Bit mask for DMA_CH3DONE */ +#define _DMA_IFC_CH3DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH3DONE_DEFAULT (_DMA_IFC_CH3DONE_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH4DONE (0x1UL << 4) /* DMA Channel 4 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH4DONE_SHIFT 4 /* Shift value for DMA_CH4DONE */ +#define _DMA_IFC_CH4DONE_MASK 0x10UL /* Bit mask for DMA_CH4DONE */ +#define _DMA_IFC_CH4DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH4DONE_DEFAULT (_DMA_IFC_CH4DONE_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH5DONE (0x1UL << 5) /* DMA Channel 5 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH5DONE_SHIFT 5 /* Shift value for DMA_CH5DONE */ +#define _DMA_IFC_CH5DONE_MASK 0x20UL /* Bit mask for DMA_CH5DONE */ +#define _DMA_IFC_CH5DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH5DONE_DEFAULT (_DMA_IFC_CH5DONE_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH6DONE (0x1UL << 6) /* DMA Channel 6 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH6DONE_SHIFT 6 /* Shift value for DMA_CH6DONE */ +#define _DMA_IFC_CH6DONE_MASK 0x40UL /* Bit mask for DMA_CH6DONE */ +#define _DMA_IFC_CH6DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH6DONE_DEFAULT (_DMA_IFC_CH6DONE_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH7DONE (0x1UL << 7) /* DMA Channel 7 Complete Interrupt Flag Clear */ +#define _DMA_IFC_CH7DONE_SHIFT 7 /* Shift value for DMA_CH7DONE */ +#define _DMA_IFC_CH7DONE_MASK 0x80UL /* Bit mask for DMA_CH7DONE */ +#define _DMA_IFC_CH7DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +#define DMA_IFC_CH7DONE_DEFAULT (_DMA_IFC_CH7DONE_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_IFC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_IFC_CH8DONE (0x1UL << 8) /* DMA Channel 8 Complete Interrupt Flag Clear */ +# define _DMA_IFC_CH8DONE_SHIFT 8 /* Shift value for DMA_CH8DONE */ +# define _DMA_IFC_CH8DONE_MASK 0x100UL /* Bit mask for DMA_CH8DONE */ +# define _DMA_IFC_CH8DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH8DONE_DEFAULT (_DMA_IFC_CH8DONE_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH9DONE (0x1UL << 9) /* DMA Channel 9 Complete Interrupt Flag Clear */ +# define _DMA_IFC_CH9DONE_SHIFT 9 /* Shift value for DMA_CH9DONE */ +# define _DMA_IFC_CH9DONE_MASK 0x200UL /* Bit mask for DMA_CH9DONE */ +# define _DMA_IFC_CH9DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH9DONE_DEFAULT (_DMA_IFC_CH9DONE_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH10DONE (0x1UL << 10) /* DMA Channel 10 Complete Interrupt Flag Clear */ +# define _DMA_IFC_CH10DONE_SHIFT 10 /* Shift value for DMA_CH10DONE */ +# define _DMA_IFC_CH10DONE_MASK 0x400UL /* Bit mask for DMA_CH10DONE */ +# define _DMA_IFC_CH10DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH10DONE_DEFAULT (_DMA_IFC_CH10DONE_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH11DONE (0x1UL << 11) /* DMA Channel 11 Complete Interrupt Flag Clear */ +# define _DMA_IFC_CH11DONE_SHIFT 11 /* Shift value for DMA_CH11DONE */ +# define _DMA_IFC_CH11DONE_MASK 0x800UL /* Bit mask for DMA_CH11DONE */ +# define _DMA_IFC_CH11DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +# define DMA_IFC_CH11DONE_DEFAULT (_DMA_IFC_CH11DONE_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_IFC */ +# define DMA_IFC_ERR (0x1UL << 31) /* DMA Error Interrupt Flag Clear */ +# define _DMA_IFC_ERR_SHIFT 31 /* Shift value for DMA_ERR */ +# define _DMA_IFC_ERR_MASK 0x80000000UL /* Bit mask for DMA_ERR */ +# define _DMA_IFC_ERR_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IFC */ +# define DMA_IFC_ERR_DEFAULT (_DMA_IFC_ERR_DEFAULT << 31) /* Shifted mode DEFAULT for DMA_IFC */ +#endif + +/* Bit fields for DMA IEN */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_IEN_RESETVALUE 0x00000000UL /* Default value for DMA_IEN */ +# define _DMA_IEN_MASK 0x80000FFFUL /* Mask for DMA_IEN */ +#elif defined(CONFIG_EFM32_EFM32G) +# define _DMA_IEN_RESETVALUE 0x00000000UL /* Default value for DMA_IEN */ +# define _DMA_IEN_MASK 0x800000FFUL /* Mask for DMA_IEN */ +#endif + +#define DMA_IEN_CH0DONE (0x1UL << 0) /* DMA Channel 0 Complete Interrupt Enable */ +#define _DMA_IEN_CH0DONE_SHIFT 0 /* Shift value for DMA_CH0DONE */ +#define _DMA_IEN_CH0DONE_MASK 0x1UL /* Bit mask for DMA_CH0DONE */ +#define _DMA_IEN_CH0DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH0DONE_DEFAULT (_DMA_IEN_CH0DONE_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH1DONE (0x1UL << 1) /* DMA Channel 1 Complete Interrupt Enable */ +#define _DMA_IEN_CH1DONE_SHIFT 1 /* Shift value for DMA_CH1DONE */ +#define _DMA_IEN_CH1DONE_MASK 0x2UL /* Bit mask for DMA_CH1DONE */ +#define _DMA_IEN_CH1DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH1DONE_DEFAULT (_DMA_IEN_CH1DONE_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH2DONE (0x1UL << 2) /* DMA Channel 2 Complete Interrupt Enable */ +#define _DMA_IEN_CH2DONE_SHIFT 2 /* Shift value for DMA_CH2DONE */ +#define _DMA_IEN_CH2DONE_MASK 0x4UL /* Bit mask for DMA_CH2DONE */ +#define _DMA_IEN_CH2DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH2DONE_DEFAULT (_DMA_IEN_CH2DONE_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH3DONE (0x1UL << 3) /* DMA Channel 3 Complete Interrupt Enable */ +#define _DMA_IEN_CH3DONE_SHIFT 3 /* Shift value for DMA_CH3DONE */ +#define _DMA_IEN_CH3DONE_MASK 0x8UL /* Bit mask for DMA_CH3DONE */ +#define _DMA_IEN_CH3DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH3DONE_DEFAULT (_DMA_IEN_CH3DONE_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH4DONE (0x1UL << 4) /* DMA Channel 4 Complete Interrupt Enable */ +#define _DMA_IEN_CH4DONE_SHIFT 4 /* Shift value for DMA_CH4DONE */ +#define _DMA_IEN_CH4DONE_MASK 0x10UL /* Bit mask for DMA_CH4DONE */ +#define _DMA_IEN_CH4DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH4DONE_DEFAULT (_DMA_IEN_CH4DONE_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH5DONE (0x1UL << 5) /* DMA Channel 5 Complete Interrupt Enable */ +#define _DMA_IEN_CH5DONE_SHIFT 5 /* Shift value for DMA_CH5DONE */ +#define _DMA_IEN_CH5DONE_MASK 0x20UL /* Bit mask for DMA_CH5DONE */ +#define _DMA_IEN_CH5DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH5DONE_DEFAULT (_DMA_IEN_CH5DONE_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH6DONE (0x1UL << 6) /* DMA Channel 6 Complete Interrupt Enable */ +#define _DMA_IEN_CH6DONE_SHIFT 6 /* Shift value for DMA_CH6DONE */ +#define _DMA_IEN_CH6DONE_MASK 0x40UL /* Bit mask for DMA_CH6DONE */ +#define _DMA_IEN_CH6DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH6DONE_DEFAULT (_DMA_IEN_CH6DONE_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH7DONE (0x1UL << 7) /* DMA Channel 7 Complete Interrupt Enable */ +#define _DMA_IEN_CH7DONE_SHIFT 7 /* Shift value for DMA_CH7DONE */ +#define _DMA_IEN_CH7DONE_MASK 0x80UL /* Bit mask for DMA_CH7DONE */ +#define _DMA_IEN_CH7DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +#define DMA_IEN_CH7DONE_DEFAULT (_DMA_IEN_CH7DONE_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_IEN */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMA_IEN_CH8DONE (0x1UL << 8) /* DMA Channel 8 Complete Interrupt Enable */ +# define _DMA_IEN_CH8DONE_SHIFT 8 /* Shift value for DMA_CH8DONE */ +# define _DMA_IEN_CH8DONE_MASK 0x100UL /* Bit mask for DMA_CH8DONE */ +# define _DMA_IEN_CH8DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH8DONE_DEFAULT (_DMA_IEN_CH8DONE_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH9DONE (0x1UL << 9) /* DMA Channel 9 Complete Interrupt Enable */ +# define _DMA_IEN_CH9DONE_SHIFT 9 /* Shift value for DMA_CH9DONE */ +# define _DMA_IEN_CH9DONE_MASK 0x200UL /* Bit mask for DMA_CH9DONE */ +# define _DMA_IEN_CH9DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH9DONE_DEFAULT (_DMA_IEN_CH9DONE_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH10DONE (0x1UL << 10) /* DMA Channel 10 Complete Interrupt Enable */ +# define _DMA_IEN_CH10DONE_SHIFT 10 /* Shift value for DMA_CH10DONE */ +# define _DMA_IEN_CH10DONE_MASK 0x400UL /* Bit mask for DMA_CH10DONE */ +# define _DMA_IEN_CH10DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH10DONE_DEFAULT (_DMA_IEN_CH10DONE_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH11DONE (0x1UL << 11) /* DMA Channel 11 Complete Interrupt Enable */ +# define _DMA_IEN_CH11DONE_SHIFT 11 /* Shift value for DMA_CH11DONE */ +# define _DMA_IEN_CH11DONE_MASK 0x800UL /* Bit mask for DMA_CH11DONE */ +# define _DMA_IEN_CH11DONE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +# define DMA_IEN_CH11DONE_DEFAULT (_DMA_IEN_CH11DONE_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_IEN */ +# define DMA_IEN_ERR (0x1UL << 31) /* DMA Error Interrupt Flag Enable */ +# define _DMA_IEN_ERR_SHIFT 31 /* Shift value for DMA_ERR */ +# define _DMA_IEN_ERR_MASK 0x80000000UL /* Bit mask for DMA_ERR */ +# define _DMA_IEN_ERR_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_IEN */ +# define DMA_IEN_ERR_DEFAULT (_DMA_IEN_ERR_DEFAULT << 31) /* Shifted mode DEFAULT for DMA_IEN */ +#endif + +/* Bit fields for DMA CTRL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_CTRL_RESETVALUE 0x00000000UL /* Default value for DMA_CTRL */ +# define _DMA_CTRL_MASK 0x00000003UL /* Mask for DMA_CTRL */ + +# define DMA_CTRL_DESCRECT (0x1UL << 0) /* Descriptor Specifies Rectangle */ +# define _DMA_CTRL_DESCRECT_SHIFT 0 /* Shift value for DMA_DESCRECT */ +# define _DMA_CTRL_DESCRECT_MASK 0x1UL /* Bit mask for DMA_DESCRECT */ +# define _DMA_CTRL_DESCRECT_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CTRL */ +# define DMA_CTRL_DESCRECT_DEFAULT (_DMA_CTRL_DESCRECT_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_CTRL */ +# define DMA_CTRL_PRDU (0x1UL << 1) /* Prevent Rect Descriptor Update */ +# define _DMA_CTRL_PRDU_SHIFT 1 /* Shift value for DMA_PRDU */ +# define _DMA_CTRL_PRDU_MASK 0x2UL /* Bit mask for DMA_PRDU */ +# define _DMA_CTRL_PRDU_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_CTRL */ +# define DMA_CTRL_PRDU_DEFAULT (_DMA_CTRL_PRDU_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_CTRL */ +#endif + +/* Bit fields for DMA RDS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_RDS_RESETVALUE 0x00000000UL /* Default value for DMA_RDS */ +# define _DMA_RDS_MASK 0x00000FFFUL /* Mask for DMA_RDS */ + +# define DMA_RDS_RDSCH0 (0x1UL << 0) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH0_SHIFT 0 /* Shift value for DMA_RDSCH0 */ +# define _DMA_RDS_RDSCH0_MASK 0x1UL /* Bit mask for DMA_RDSCH0 */ +# define _DMA_RDS_RDSCH0_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH0_DEFAULT (_DMA_RDS_RDSCH0_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH1 (0x1UL << 1) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH1_SHIFT 1 /* Shift value for DMA_RDSCH1 */ +# define _DMA_RDS_RDSCH1_MASK 0x2UL /* Bit mask for DMA_RDSCH1 */ +# define _DMA_RDS_RDSCH1_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH1_DEFAULT (_DMA_RDS_RDSCH1_DEFAULT << 1) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH2 (0x1UL << 2) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH2_SHIFT 2 /* Shift value for DMA_RDSCH2 */ +# define _DMA_RDS_RDSCH2_MASK 0x4UL /* Bit mask for DMA_RDSCH2 */ +# define _DMA_RDS_RDSCH2_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH2_DEFAULT (_DMA_RDS_RDSCH2_DEFAULT << 2) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH3 (0x1UL << 3) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH3_SHIFT 3 /* Shift value for DMA_RDSCH3 */ +# define _DMA_RDS_RDSCH3_MASK 0x8UL /* Bit mask for DMA_RDSCH3 */ +# define _DMA_RDS_RDSCH3_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH3_DEFAULT (_DMA_RDS_RDSCH3_DEFAULT << 3) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH4 (0x1UL << 4) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH4_SHIFT 4 /* Shift value for DMA_RDSCH4 */ +# define _DMA_RDS_RDSCH4_MASK 0x10UL /* Bit mask for DMA_RDSCH4 */ +# define _DMA_RDS_RDSCH4_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH4_DEFAULT (_DMA_RDS_RDSCH4_DEFAULT << 4) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH5 (0x1UL << 5) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH5_SHIFT 5 /* Shift value for DMA_RDSCH5 */ +# define _DMA_RDS_RDSCH5_MASK 0x20UL /* Bit mask for DMA_RDSCH5 */ +# define _DMA_RDS_RDSCH5_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH5_DEFAULT (_DMA_RDS_RDSCH5_DEFAULT << 5) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH6 (0x1UL << 6) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH6_SHIFT 6 /* Shift value for DMA_RDSCH6 */ +# define _DMA_RDS_RDSCH6_MASK 0x40UL /* Bit mask for DMA_RDSCH6 */ +# define _DMA_RDS_RDSCH6_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH6_DEFAULT (_DMA_RDS_RDSCH6_DEFAULT << 6) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH7 (0x1UL << 7) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH7_SHIFT 7 /* Shift value for DMA_RDSCH7 */ +# define _DMA_RDS_RDSCH7_MASK 0x80UL /* Bit mask for DMA_RDSCH7 */ +# define _DMA_RDS_RDSCH7_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH7_DEFAULT (_DMA_RDS_RDSCH7_DEFAULT << 7) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH8 (0x1UL << 8) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH8_SHIFT 8 /* Shift value for DMA_RDSCH8 */ +# define _DMA_RDS_RDSCH8_MASK 0x100UL /* Bit mask for DMA_RDSCH8 */ +# define _DMA_RDS_RDSCH8_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH8_DEFAULT (_DMA_RDS_RDSCH8_DEFAULT << 8) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH9 (0x1UL << 9) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH9_SHIFT 9 /* Shift value for DMA_RDSCH9 */ +# define _DMA_RDS_RDSCH9_MASK 0x200UL /* Bit mask for DMA_RDSCH9 */ +# define _DMA_RDS_RDSCH9_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH9_DEFAULT (_DMA_RDS_RDSCH9_DEFAULT << 9) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH10 (0x1UL << 10) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH10_SHIFT 10 /* Shift value for DMA_RDSCH10 */ +# define _DMA_RDS_RDSCH10_MASK 0x400UL /* Bit mask for DMA_RDSCH10 */ +# define _DMA_RDS_RDSCH10_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH10_DEFAULT (_DMA_RDS_RDSCH10_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH11 (0x1UL << 11) /* Retain Descriptor State */ +# define _DMA_RDS_RDSCH11_SHIFT 11 /* Shift value for DMA_RDSCH11 */ +# define _DMA_RDS_RDSCH11_MASK 0x800UL /* Bit mask for DMA_RDSCH11 */ +# define _DMA_RDS_RDSCH11_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RDS */ +# define DMA_RDS_RDSCH11_DEFAULT (_DMA_RDS_RDSCH11_DEFAULT << 11) /* Shifted mode DEFAULT for DMA_RDS */ +#endif + +/* Bit fields for DMA LOOP0 */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_LOOP0_RESETVALUE 0x00000000UL /* Default value for DMA_LOOP0 */ +# define _DMA_LOOP0_MASK 0x000103FFUL /* Mask for DMA_LOOP0 */ + +# define _DMA_LOOP0_WIDTH_SHIFT 0 /* Shift value for DMA_WIDTH */ +# define _DMA_LOOP0_WIDTH_MASK 0x3FFUL /* Bit mask for DMA_WIDTH */ +# define _DMA_LOOP0_WIDTH_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_LOOP0 */ +# define DMA_LOOP0_WIDTH_DEFAULT (_DMA_LOOP0_WIDTH_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_LOOP0 */ +# define DMA_LOOP0_EN (0x1UL << 16) /* DMA Channel 0 Loop Enable */ +# define _DMA_LOOP0_EN_SHIFT 16 /* Shift value for DMA_EN */ +# define _DMA_LOOP0_EN_MASK 0x10000UL /* Bit mask for DMA_EN */ +# define _DMA_LOOP0_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_LOOP0 */ +# define DMA_LOOP0_EN_DEFAULT (_DMA_LOOP0_EN_DEFAULT << 16) /* Shifted mode DEFAULT for DMA_LOOP0 */ +#endif + +/* Bit fields for DMA LOOP1 */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_LOOP1_RESETVALUE 0x00000000UL /* Default value for DMA_LOOP1 */ +# define _DMA_LOOP1_MASK 0x000103FFUL /* Mask for DMA_LOOP1 */ + +# define _DMA_LOOP1_WIDTH_SHIFT 0 /* Shift value for DMA_WIDTH */ +# define _DMA_LOOP1_WIDTH_MASK 0x3FFUL /* Bit mask for DMA_WIDTH */ +# define _DMA_LOOP1_WIDTH_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_LOOP1 */ +# define DMA_LOOP1_WIDTH_DEFAULT (_DMA_LOOP1_WIDTH_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_LOOP1 */ +# define DMA_LOOP1_EN (0x1UL << 16) /* DMA Channel 1 Loop Enable */ +# define _DMA_LOOP1_EN_SHIFT 16 /* Shift value for DMA_EN */ +# define _DMA_LOOP1_EN_MASK 0x10000UL /* Bit mask for DMA_EN */ +# define _DMA_LOOP1_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_LOOP1 */ +# define DMA_LOOP1_EN_DEFAULT (_DMA_LOOP1_EN_DEFAULT << 16) /* Shifted mode DEFAULT for DMA_LOOP1 */ +#endif + +/* Bit fields for DMA RECT0 */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _DMA_RECT0_RESETVALUE 0x00000000UL /* Default value for DMA_RECT0 */ +# define _DMA_RECT0_MASK 0xFFFFFFFFUL /* Mask for DMA_RECT0 */ + +# define _DMA_RECT0_HEIGHT_SHIFT 0 /* Shift value for DMA_HEIGHT */ +# define _DMA_RECT0_HEIGHT_MASK 0x3FFUL /* Bit mask for DMA_HEIGHT */ +# define _DMA_RECT0_HEIGHT_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RECT0 */ +# define DMA_RECT0_HEIGHT_DEFAULT (_DMA_RECT0_HEIGHT_DEFAULT << 0) /* Shifted mode DEFAULT for DMA_RECT0 */ +# define _DMA_RECT0_SRCSTRIDE_SHIFT 10 /* Shift value for DMA_SRCSTRIDE */ +# define _DMA_RECT0_SRCSTRIDE_MASK 0x1FFC00UL /* Bit mask for DMA_SRCSTRIDE */ +# define _DMA_RECT0_SRCSTRIDE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RECT0 */ +# define DMA_RECT0_SRCSTRIDE_DEFAULT (_DMA_RECT0_SRCSTRIDE_DEFAULT << 10) /* Shifted mode DEFAULT for DMA_RECT0 */ +# define _DMA_RECT0_DSTSTRIDE_SHIFT 21 /* Shift value for DMA_DSTSTRIDE */ +# define _DMA_RECT0_DSTSTRIDE_MASK 0xFFE00000UL /* Bit mask for DMA_DSTSTRIDE */ +# define _DMA_RECT0_DSTSTRIDE_DEFAULT 0x00000000UL /* Mode DEFAULT for DMA_RECT0 */ +# define DMA_RECT0_DSTSTRIDE_DEFAULT (_DMA_RECT0_DSTSTRIDE_DEFAULT << 21) /* Shifted mode DEFAULT for DMA_RECT0 */ +#endif + +/* Bit fields for DMA CH_CTRL */ + +#define _DMA_CH_CTRL_RESETVALUE 0x00000000UL /* Default value for DMA_CH_CTRL */ +#define _DMA_CH_CTRL_MASK 0x003F000FUL /* Mask for DMA_CH_CTRL */ + +#define _DMA_CH_CTRL_SIGSEL_SHIFT 0 /* Shift value for DMA_SIGSEL */ +#define _DMA_CH_CTRL_SIGSEL_MASK 0xFUL /* Bit mask for DMA_SIGSEL */ + +#if defined(CONFIG_EFM32_EFM32GG) + +# define _DMA_CH_CTRL_SIGSEL_ADC0SINGLE 0x00000000UL /* Mode ADC0SINGLE for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_DAC0CH0 0x00000000UL /* Mode DAC0CH0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0RXDATAV 0x00000000UL /* Mode USART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1RXDATAV 0x00000000UL /* Mode USART1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2RXDATAV 0x00000000UL /* Mode USART2RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV 0x00000000UL /* Mode LEUART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV 0x00000000UL /* Mode LEUART1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C0RXDATAV 0x00000000UL /* Mode I2C0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C1RXDATAV 0x00000000UL /* Mode I2C1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0UFOF 0x00000000UL /* Mode TIMER0UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1UFOF 0x00000000UL /* Mode TIMER1UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2UFOF 0x00000000UL /* Mode TIMER2UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER3UFOF 0x00000000UL /* Mode TIMER3UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0RXDATAV 0x00000000UL /* Mode UART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART1RXDATAV 0x00000000UL /* Mode UART1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_MSCWDATA 0x00000000UL /* Mode MSCWDATA for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESDATAWR 0x00000000UL /* Mode AESDATAWR for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LESENSEBUFDATAV 0x00000000UL /* Mode LESENSEBUFDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_EBIPXL0EMPTY 0x00000000UL /* Mode EBIPXL0EMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_ADC0SCAN 0x00000001UL /* Mode ADC0SCAN for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_DAC0CH1 0x00000001UL /* Mode DAC0CH1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0TXBL 0x00000001UL /* Mode USART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1TXBL 0x00000001UL /* Mode USART1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2TXBL 0x00000001UL /* Mode USART2TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0TXBL 0x00000001UL /* Mode LEUART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1TXBL 0x00000001UL /* Mode LEUART1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C0TXBL 0x00000001UL /* Mode I2C0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C1TXBL 0x00000001UL /* Mode I2C1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC0 0x00000001UL /* Mode TIMER0CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC0 0x00000001UL /* Mode TIMER1CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC0 0x00000001UL /* Mode TIMER2CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER3CC0 0x00000001UL /* Mode TIMER3CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0TXBL 0x00000001UL /* Mode UART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART1TXBL 0x00000001UL /* Mode UART1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESXORDATAWR 0x00000001UL /* Mode AESXORDATAWR for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_EBIPXL1EMPTY 0x00000001UL /* Mode EBIPXL1EMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0TXEMPTY 0x00000002UL /* Mode USART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1TXEMPTY 0x00000002UL /* Mode USART1TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2TXEMPTY 0x00000002UL /* Mode USART2TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY 0x00000002UL /* Mode LEUART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY 0x00000002UL /* Mode LEUART1TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC1 0x00000002UL /* Mode TIMER0CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC1 0x00000002UL /* Mode TIMER1CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC1 0x00000002UL /* Mode TIMER2CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER3CC1 0x00000002UL /* Mode TIMER3CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0TXEMPTY 0x00000002UL /* Mode UART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART1TXEMPTY 0x00000002UL /* Mode UART1TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESDATARD 0x00000002UL /* Mode AESDATARD for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_EBIPXLFULL 0x00000002UL /* Mode EBIPXLFULL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1RXDATAVRIGHT 0x00000003UL /* Mode USART1RXDATAVRIGHT for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2RXDATAVRIGHT 0x00000003UL /* Mode USART2RXDATAVRIGHT for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC2 0x00000003UL /* Mode TIMER0CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC2 0x00000003UL /* Mode TIMER1CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC2 0x00000003UL /* Mode TIMER2CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER3CC2 0x00000003UL /* Mode TIMER3CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESKEYWR 0x00000003UL /* Mode AESKEYWR for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_EBIDDEMPTY 0x00000003UL /* Mode EBIDDEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1TXBLRIGHT 0x00000004UL /* Mode USART1TXBLRIGHT for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2TXBLRIGHT 0x00000004UL /* Mode USART2TXBLRIGHT for DMA_CH_CTRL */ + +# define DMA_CH_CTRL_SIGSEL_ADC0SINGLE (_DMA_CH_CTRL_SIGSEL_ADC0SINGLE << 0) /* Shifted mode ADC0SINGLE for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_DAC0CH0 (_DMA_CH_CTRL_SIGSEL_DAC0CH0 << 0) /* Shifted mode DAC0CH0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0RXDATAV (_DMA_CH_CTRL_SIGSEL_USART0RXDATAV << 0) /* Shifted mode USART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1RXDATAV (_DMA_CH_CTRL_SIGSEL_USART1RXDATAV << 0) /* Shifted mode USART1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2RXDATAV (_DMA_CH_CTRL_SIGSEL_USART2RXDATAV << 0) /* Shifted mode USART2RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV (_DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV << 0) /* Shifted mode LEUART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV (_DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV << 0) /* Shifted mode LEUART1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C0RXDATAV (_DMA_CH_CTRL_SIGSEL_I2C0RXDATAV << 0) /* Shifted mode I2C0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C1RXDATAV (_DMA_CH_CTRL_SIGSEL_I2C1RXDATAV << 0) /* Shifted mode I2C1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0UFOF (_DMA_CH_CTRL_SIGSEL_TIMER0UFOF << 0) /* Shifted mode TIMER0UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1UFOF (_DMA_CH_CTRL_SIGSEL_TIMER1UFOF << 0) /* Shifted mode TIMER1UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2UFOF (_DMA_CH_CTRL_SIGSEL_TIMER2UFOF << 0) /* Shifted mode TIMER2UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER3UFOF (_DMA_CH_CTRL_SIGSEL_TIMER3UFOF << 0) /* Shifted mode TIMER3UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0RXDATAV (_DMA_CH_CTRL_SIGSEL_UART0RXDATAV << 0) /* Shifted mode UART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART1RXDATAV (_DMA_CH_CTRL_SIGSEL_UART1RXDATAV << 0) /* Shifted mode UART1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_MSCWDATA (_DMA_CH_CTRL_SIGSEL_MSCWDATA << 0) /* Shifted mode MSCWDATA for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESDATAWR (_DMA_CH_CTRL_SIGSEL_AESDATAWR << 0) /* Shifted mode AESDATAWR for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LESENSEBUFDATAV (_DMA_CH_CTRL_SIGSEL_LESENSEBUFDATAV << 0) /* Shifted mode LESENSEBUFDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_EBIPXL0EMPTY (_DMA_CH_CTRL_SIGSEL_EBIPXL0EMPTY << 0) /* Shifted mode EBIPXL0EMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_ADC0SCAN (_DMA_CH_CTRL_SIGSEL_ADC0SCAN << 0) /* Shifted mode ADC0SCAN for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_DAC0CH1 (_DMA_CH_CTRL_SIGSEL_DAC0CH1 << 0) /* Shifted mode DAC0CH1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0TXBL (_DMA_CH_CTRL_SIGSEL_USART0TXBL << 0) /* Shifted mode USART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1TXBL (_DMA_CH_CTRL_SIGSEL_USART1TXBL << 0) /* Shifted mode USART1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2TXBL (_DMA_CH_CTRL_SIGSEL_USART2TXBL << 0) /* Shifted mode USART2TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0TXBL (_DMA_CH_CTRL_SIGSEL_LEUART0TXBL << 0) /* Shifted mode LEUART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1TXBL (_DMA_CH_CTRL_SIGSEL_LEUART1TXBL << 0) /* Shifted mode LEUART1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C0TXBL (_DMA_CH_CTRL_SIGSEL_I2C0TXBL << 0) /* Shifted mode I2C0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C1TXBL (_DMA_CH_CTRL_SIGSEL_I2C1TXBL << 0) /* Shifted mode I2C1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC0 (_DMA_CH_CTRL_SIGSEL_TIMER0CC0 << 0) /* Shifted mode TIMER0CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC0 (_DMA_CH_CTRL_SIGSEL_TIMER1CC0 << 0) /* Shifted mode TIMER1CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC0 (_DMA_CH_CTRL_SIGSEL_TIMER2CC0 << 0) /* Shifted mode TIMER2CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER3CC0 (_DMA_CH_CTRL_SIGSEL_TIMER3CC0 << 0) /* Shifted mode TIMER3CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0TXBL (_DMA_CH_CTRL_SIGSEL_UART0TXBL << 0) /* Shifted mode UART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART1TXBL (_DMA_CH_CTRL_SIGSEL_UART1TXBL << 0) /* Shifted mode UART1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESXORDATAWR (_DMA_CH_CTRL_SIGSEL_AESXORDATAWR << 0) /* Shifted mode AESXORDATAWR for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_EBIPXL1EMPTY (_DMA_CH_CTRL_SIGSEL_EBIPXL1EMPTY << 0) /* Shifted mode EBIPXL1EMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0TXEMPTY (_DMA_CH_CTRL_SIGSEL_USART0TXEMPTY << 0) /* Shifted mode USART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1TXEMPTY (_DMA_CH_CTRL_SIGSEL_USART1TXEMPTY << 0) /* Shifted mode USART1TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2TXEMPTY (_DMA_CH_CTRL_SIGSEL_USART2TXEMPTY << 0) /* Shifted mode USART2TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY (_DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY << 0) /* Shifted mode LEUART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY (_DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY << 0) /* Shifted mode LEUART1TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC1 (_DMA_CH_CTRL_SIGSEL_TIMER0CC1 << 0) /* Shifted mode TIMER0CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC1 (_DMA_CH_CTRL_SIGSEL_TIMER1CC1 << 0) /* Shifted mode TIMER1CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC1 (_DMA_CH_CTRL_SIGSEL_TIMER2CC1 << 0) /* Shifted mode TIMER2CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER3CC1 (_DMA_CH_CTRL_SIGSEL_TIMER3CC1 << 0) /* Shifted mode TIMER3CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0TXEMPTY (_DMA_CH_CTRL_SIGSEL_UART0TXEMPTY << 0) /* Shifted mode UART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART1TXEMPTY (_DMA_CH_CTRL_SIGSEL_UART1TXEMPTY << 0) /* Shifted mode UART1TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESDATARD (_DMA_CH_CTRL_SIGSEL_AESDATARD << 0) /* Shifted mode AESDATARD for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_EBIPXLFULL (_DMA_CH_CTRL_SIGSEL_EBIPXLFULL << 0) /* Shifted mode EBIPXLFULL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1RXDATAVRIGHT (_DMA_CH_CTRL_SIGSEL_USART1RXDATAVRIGHT << 0) /* Shifted mode USART1RXDATAVRIGHT for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2RXDATAVRIGHT (_DMA_CH_CTRL_SIGSEL_USART2RXDATAVRIGHT << 0) /* Shifted mode USART2RXDATAVRIGHT for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC2 (_DMA_CH_CTRL_SIGSEL_TIMER0CC2 << 0) /* Shifted mode TIMER0CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC2 (_DMA_CH_CTRL_SIGSEL_TIMER1CC2 << 0) /* Shifted mode TIMER1CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC2 (_DMA_CH_CTRL_SIGSEL_TIMER2CC2 << 0) /* Shifted mode TIMER2CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER3CC2 (_DMA_CH_CTRL_SIGSEL_TIMER3CC2 << 0) /* Shifted mode TIMER3CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESKEYWR (_DMA_CH_CTRL_SIGSEL_AESKEYWR << 0) /* Shifted mode AESKEYWR for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_EBIDDEMPTY (_DMA_CH_CTRL_SIGSEL_EBIDDEMPTY << 0) /* Shifted mode EBIDDEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1TXBLRIGHT (_DMA_CH_CTRL_SIGSEL_USART1TXBLRIGHT << 0) /* Shifted mode USART1TXBLRIGHT for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2TXBLRIGHT (_DMA_CH_CTRL_SIGSEL_USART2TXBLRIGHT << 0) /* Shifted mode USART2TXBLRIGHT for DMA_CH_CTRL */ + +#elif defined(CONFIG_EFM32_EFM32G) + +# define _DMA_CH_CTRL_SIGSEL_ADC0SINGLE 0x00000000UL /* Mode ADC0SINGLE for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_DAC0CH0 0x00000000UL /* Mode DAC0CH0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0RXDATAV 0x00000000UL /* Mode USART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1RXDATAV 0x00000000UL /* Mode USART1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2RXDATAV 0x00000000UL /* Mode USART2RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV 0x00000000UL /* Mode LEUART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV 0x00000000UL /* Mode LEUART1RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C0RXDATAV 0x00000000UL /* Mode I2C0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0UFOF 0x00000000UL /* Mode TIMER0UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1UFOF 0x00000000UL /* Mode TIMER1UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2UFOF 0x00000000UL /* Mode TIMER2UFOF for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0RXDATAV 0x00000000UL /* Mode UART0RXDATAV for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_MSCWDATA 0x00000000UL /* Mode MSCWDATA for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESDATAWR 0x00000000UL /* Mode AESDATAWR for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_ADC0SCAN 0x00000001UL /* Mode ADC0SCAN for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_DAC0CH1 0x00000001UL /* Mode DAC0CH1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0TXBL 0x00000001UL /* Mode USART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1TXBL 0x00000001UL /* Mode USART1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2TXBL 0x00000001UL /* Mode USART2TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0TXBL 0x00000001UL /* Mode LEUART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1TXBL 0x00000001UL /* Mode LEUART1TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_I2C0TXBL 0x00000001UL /* Mode I2C0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC0 0x00000001UL /* Mode TIMER0CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC0 0x00000001UL /* Mode TIMER1CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC0 0x00000001UL /* Mode TIMER2CC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0TXBL 0x00000001UL /* Mode UART0TXBL for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESXORDATAWR 0x00000001UL /* Mode AESXORDATAWR for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART0TXEMPTY 0x00000002UL /* Mode USART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART1TXEMPTY 0x00000002UL /* Mode USART1TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_USART2TXEMPTY 0x00000002UL /* Mode USART2TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY 0x00000002UL /* Mode LEUART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY 0x00000002UL /* Mode LEUART1TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC1 0x00000002UL /* Mode TIMER0CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC1 0x00000002UL /* Mode TIMER1CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC1 0x00000002UL /* Mode TIMER2CC1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_UART0TXEMPTY 0x00000002UL /* Mode UART0TXEMPTY for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESDATARD 0x00000002UL /* Mode AESDATARD for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER0CC2 0x00000003UL /* Mode TIMER0CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER1CC2 0x00000003UL /* Mode TIMER1CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_TIMER2CC2 0x00000003UL /* Mode TIMER2CC2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SIGSEL_AESKEYWR 0x00000003UL /* Mode AESKEYWR for DMA_CH_CTRL */ + +# define DMA_CH_CTRL_SIGSEL_ADC0SINGLE (0x00000000UL << 0) /* Shifted mode ADC0SINGLE for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_DAC0CH0 (0x00000000UL << 0) /* Shifted mode DAC0CH0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0RXDATAV (0x00000000UL << 0) /* Shifted mode USART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1RXDATAV (0x00000000UL << 0) /* Shifted mode USART1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2RXDATAV (0x00000000UL << 0) /* Shifted mode USART2RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV (0x00000000UL << 0) /* Shifted mode LEUART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV (0x00000000UL << 0) /* Shifted mode LEUART1RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C0RXDATAV (0x00000000UL << 0) /* Shifted mode I2C0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0UFOF (0x00000000UL << 0) /* Shifted mode TIMER0UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1UFOF (0x00000000UL << 0) /* Shifted mode TIMER1UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2UFOF (0x00000000UL << 0) /* Shifted mode TIMER2UFOF for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0RXDATAV (0x00000000UL << 0) /* Shifted mode UART0RXDATAV for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_MSCWDATA (0x00000000UL << 0) /* Shifted mode MSCWDATA for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESDATAWR (0x00000000UL << 0) /* Shifted mode AESDATAWR for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_ADC0SCAN (0x00000001UL << 0) /* Shifted mode ADC0SCAN for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_DAC0CH1 (0x00000001UL << 0) /* Shifted mode DAC0CH1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0TXBL (0x00000001UL << 0) /* Shifted mode USART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1TXBL (0x00000001UL << 0) /* Shifted mode USART1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2TXBL (0x00000001UL << 0) /* Shifted mode USART2TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0TXBL (0x00000001UL << 0) /* Shifted mode LEUART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1TXBL (0x00000001UL << 0) /* Shifted mode LEUART1TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_I2C0TXBL (0x00000001UL << 0) /* Shifted mode I2C0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC0 (0x00000001UL << 0) /* Shifted mode TIMER0CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC0 (0x00000001UL << 0) /* Shifted mode TIMER1CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC0 (0x00000001UL << 0) /* Shifted mode TIMER2CC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0TXBL (0x00000001UL << 0) /* Shifted mode UART0TXBL for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESXORDATAWR (0x00000001UL << 0) /* Shifted mode AESXORDATAWR for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART0TXEMPTY (0x00000002UL << 0) /* Shifted mode USART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART1TXEMPTY (0x00000002UL << 0) /* Shifted mode USART1TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_USART2TXEMPTY (0x00000002UL << 0) /* Shifted mode USART2TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY (0x00000002UL << 0) /* Shifted mode LEUART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY (0x00000002UL << 0) /* Shifted mode LEUART1TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC1 (0x00000002UL << 0) /* Shifted mode TIMER0CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC1 (0x00000002UL << 0) /* Shifted mode TIMER1CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC1 (0x00000002UL << 0) /* Shifted mode TIMER2CC1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_UART0TXEMPTY (0x00000002UL << 0) /* Shifted mode UART0TXEMPTY for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESDATARD (0x00000002UL << 0) /* Shifted mode AESDATARD for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER0CC2 (0x00000003UL << 0) /* Shifted mode TIMER0CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER1CC2 (0x00000003UL << 0) /* Shifted mode TIMER1CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_TIMER2CC2 (0x00000003UL << 0) /* Shifted mode TIMER2CC2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SIGSEL_AESKEYWR (0x00000003UL << 0) /* Shifted mode AESKEYWR for DMA_CH_CTRL */ + +#endif + +#define _DMA_CH_CTRL_SOURCESEL_SHIFT 16 /* Shift value for DMA_SOURCESEL */ +#define _DMA_CH_CTRL_SOURCESEL_MASK 0x3F0000UL /* Bit mask for DMA_SOURCESEL */ + +#if defined(CONFIG_EFM32_EFM32GG) + +# define _DMA_CH_CTRL_SOURCESEL_NONE 0x00000000UL /* Mode NONE for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_ADC0 0x00000008UL /* Mode ADC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_DAC0 0x0000000AUL /* Mode DAC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART0 0x0000000CUL /* Mode USART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART1 0x0000000DUL /* Mode USART1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART2 0x0000000EUL /* Mode USART2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_LEUART0 0x00000010UL /* Mode LEUART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_LEUART1 0x00000011UL /* Mode LEUART1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_I2C0 0x00000014UL /* Mode I2C0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_I2C1 0x00000015UL /* Mode I2C1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER0 0x00000018UL /* Mode TIMER0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER1 0x00000019UL /* Mode TIMER1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER2 0x0000001AUL /* Mode TIMER2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER3 0x0000001BUL /* Mode TIMER3 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_UART0 0x0000002CUL /* Mode UART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_UART1 0x0000002DUL /* Mode UART1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_MSC 0x00000030UL /* Mode MSC for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_AES 0x00000031UL /* Mode AES for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_LESENSE 0x00000032UL /* Mode LESENSE for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_EBI 0x00000033UL /* Mode EBI for DMA_CH_CTRL */ + +# define DMA_CH_CTRL_SOURCESEL_NONE (_DMA_CH_CTRL_SOURCESEL_NONE << 16) /* Shifted mode NONE for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_ADC0 (_DMA_CH_CTRL_SOURCESEL_ADC0 << 16) /* Shifted mode ADC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_DAC0 (_DMA_CH_CTRL_SOURCESEL_DAC0 << 16) /* Shifted mode DAC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART0 (_DMA_CH_CTRL_SOURCESEL_USART0 << 16) /* Shifted mode USART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART1 (_DMA_CH_CTRL_SOURCESEL_USART1 << 16) /* Shifted mode USART1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART2 (_DMA_CH_CTRL_SOURCESEL_USART2 << 16) /* Shifted mode USART2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_LEUART0 (_DMA_CH_CTRL_SOURCESEL_LEUART0 << 16) /* Shifted mode LEUART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_LEUART1 (_DMA_CH_CTRL_SOURCESEL_LEUART1 << 16) /* Shifted mode LEUART1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_I2C0 (_DMA_CH_CTRL_SOURCESEL_I2C0 << 16) /* Shifted mode I2C0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_I2C1 (_DMA_CH_CTRL_SOURCESEL_I2C1 << 16) /* Shifted mode I2C1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER0 (_DMA_CH_CTRL_SOURCESEL_TIMER0 << 16) /* Shifted mode TIMER0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER1 (_DMA_CH_CTRL_SOURCESEL_TIMER1 << 16) /* Shifted mode TIMER1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER2 (_DMA_CH_CTRL_SOURCESEL_TIMER2 << 16) /* Shifted mode TIMER2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER3 (_DMA_CH_CTRL_SOURCESEL_TIMER3 << 16) /* Shifted mode TIMER3 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_UART0 (_DMA_CH_CTRL_SOURCESEL_UART0 << 16) /* Shifted mode UART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_UART1 (_DMA_CH_CTRL_SOURCESEL_UART1 << 16) /* Shifted mode UART1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_MSC (_DMA_CH_CTRL_SOURCESEL_MSC << 16) /* Shifted mode MSC for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_AES (_DMA_CH_CTRL_SOURCESEL_AES << 16) /* Shifted mode AES for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_LESENSE (_DMA_CH_CTRL_SOURCESEL_LESENSE << 16) /* Shifted mode LESENSE for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_EBI (_DMA_CH_CTRL_SOURCESEL_EBI << 16) /* Shifted mode EBI for DMA_CH_CTRL */ + +#elif defined(CONFIG_EFM32_EFM32G) + +# define _DMA_CH_CTRL_SOURCESEL_NONE 0x00000000UL /* Mode NONE for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_ADC0 0x00000008UL /* Mode ADC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_DAC0 0x0000000AUL /* Mode DAC0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART0 0x0000000CUL /* Mode USART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART1 0x0000000DUL /* Mode USART1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_USART2 0x0000000EUL /* Mode USART2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_LEUART0 0x00000010UL /* Mode LEUART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_LEUART1 0x00000011UL /* Mode LEUART1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_I2C0 0x00000014UL /* Mode I2C0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER0 0x00000018UL /* Mode TIMER0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER1 0x00000019UL /* Mode TIMER1 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_TIMER2 0x0000001AUL /* Mode TIMER2 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_UART0 0x0000002CUL /* Mode UART0 for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_MSC 0x00000030UL /* Mode MSC for DMA_CH_CTRL */ +# define _DMA_CH_CTRL_SOURCESEL_AES 0x00000031UL /* Mode AES for DMA_CH_CTRL */ + +# define DMA_CH_CTRL_SOURCESEL_NONE (0x00000000UL << 16) /* Shifted mode NONE for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_ADC0 (0x00000008UL << 16) /* Shifted mode ADC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_DAC0 (0x0000000AUL << 16) /* Shifted mode DAC0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART0 (0x0000000CUL << 16) /* Shifted mode USART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART1 (0x0000000DUL << 16) /* Shifted mode USART1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_USART2 (0x0000000EUL << 16) /* Shifted mode USART2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_LEUART0 (0x00000010UL << 16) /* Shifted mode LEUART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_LEUART1 (0x00000011UL << 16) /* Shifted mode LEUART1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_I2C0 (0x00000014UL << 16) /* Shifted mode I2C0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER0 (0x00000018UL << 16) /* Shifted mode TIMER0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER1 (0x00000019UL << 16) /* Shifted mode TIMER1 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_TIMER2 (0x0000001AUL << 16) /* Shifted mode TIMER2 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_UART0 (0x0000002CUL << 16) /* Shifted mode UART0 for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_MSC (0x00000030UL << 16) /* Shifted mode MSC for DMA_CH_CTRL */ +# define DMA_CH_CTRL_SOURCESEL_AES (0x00000031UL << 16) /* Shifted mode AES for DMA_CH_CTRL */ + +#endif + +/* DMA Descriptor Bit Field Definitions ****************************************************************************************/ + +#define _DMA_CTRL_DST_INC_MASK 0xC0000000UL /* Data increment for destination, bit mask */ +#define _DMA_CTRL_DST_INC_SHIFT 30 /* Data increment for destination, shift value */ +#define _DMA_CTRL_DST_INC_BYTE 0x00 /* Byte/8-bit increment */ +#define _DMA_CTRL_DST_INC_HALFWORD 0x01 /* Half word/16-bit increment */ +#define _DMA_CTRL_DST_INC_WORD 0x02 /* Word/32-bit increment */ +#define _DMA_CTRL_DST_INC_NONE 0x03 /* No increment */ +#define DMA_CTRL_DST_INC_BYTE 0x00000000UL /* Byte/8-bit increment */ +#define DMA_CTRL_DST_INC_HALFWORD 0x40000000UL /* Half word/16-bit increment */ +#define DMA_CTRL_DST_INC_WORD 0x80000000UL /* Word/32-bit increment */ +#define DMA_CTRL_DST_INC_NONE 0xC0000000UL /* No increment */ +#define _DMA_CTRL_DST_SIZE_MASK 0x30000000UL /* Data size for destination - MUST be the same as source, bit mask */ +#define _DMA_CTRL_DST_SIZE_SHIFT 28 /* Data size for destination - MUST be the same as source, shift value */ +#define _DMA_CTRL_DST_SIZE_BYTE 0x00 /* Byte/8-bit data size */ +#define _DMA_CTRL_DST_SIZE_HALFWORD 0x01 /* Half word/16-bit data size */ +#define _DMA_CTRL_DST_SIZE_WORD 0x02 /* Word/32-bit data size */ +#define _DMA_CTRL_DST_SIZE_RSVD 0x03 /* Reserved */ +#define DMA_CTRL_DST_SIZE_BYTE 0x00000000UL /* Byte/8-bit data size */ +#define DMA_CTRL_DST_SIZE_HALFWORD 0x10000000UL /* Half word/16-bit data size */ +#define DMA_CTRL_DST_SIZE_WORD 0x20000000UL /* Word/32-bit data size */ +#define DMA_CTRL_DST_SIZE_RSVD 0x30000000UL /* Reserved - do not use */ +#define _DMA_CTRL_SRC_INC_MASK 0x0C000000UL /* Data increment for source, bit mask */ +#define _DMA_CTRL_SRC_INC_SHIFT 26 /* Data increment for source, shift value */ +#define _DMA_CTRL_SRC_INC_BYTE 0x00 /* Byte/8-bit increment */ +#define _DMA_CTRL_SRC_INC_HALFWORD 0x01 /* Half word/16-bit increment */ +#define _DMA_CTRL_SRC_INC_WORD 0x02 /* Word/32-bit increment */ +#define _DMA_CTRL_SRC_INC_NONE 0x03 /* No increment */ +#define DMA_CTRL_SRC_INC_BYTE 0x00000000UL /* Byte/8-bit increment */ +#define DMA_CTRL_SRC_INC_HALFWORD 0x04000000UL /* Half word/16-bit increment */ +#define DMA_CTRL_SRC_INC_WORD 0x08000000UL /* Word/32-bit increment */ +#define DMA_CTRL_SRC_INC_NONE 0x0C000000UL /* No increment */ +#define _DMA_CTRL_SRC_SIZE_MASK 0x03000000UL /* Data size for source - MUST be the same as destination, bit mask */ +#define _DMA_CTRL_SRC_SIZE_SHIFT 24 /* Data size for source - MUST be the same as destination, shift value */ +#define _DMA_CTRL_SRC_SIZE_BYTE 0x00 /* Byte/8-bit data size */ +#define _DMA_CTRL_SRC_SIZE_HALFWORD 0x01 /* Half word/16-bit data size */ +#define _DMA_CTRL_SRC_SIZE_WORD 0x02 /* Word/32-bit data size */ +#define _DMA_CTRL_SRC_SIZE_RSVD 0x03 /* Reserved */ +#define DMA_CTRL_SRC_SIZE_BYTE 0x00000000UL /* Byte/8-bit data size */ +#define DMA_CTRL_SRC_SIZE_HALFWORD 0x01000000UL /* Half word/16-bit data size */ +#define DMA_CTRL_SRC_SIZE_WORD 0x02000000UL /* Word/32-bit data size */ +#define DMA_CTRL_SRC_SIZE_RSVD 0x03000000UL /* Reserved - do not use */ +#define _DMA_CTRL_DST_PROT_CTRL_MASK 0x00E00000UL /* Protection flag for destination, bit mask */ +#define _DMA_CTRL_DST_PROT_CTRL_SHIFT 21 /* Protection flag for destination, shift value */ +#define DMA_CTRL_DST_PROT_PRIVILEGED 0x00200000UL /* Privileged mode for destination */ +#define DMA_CTRL_DST_PROT_NON_PRIVILEGED 0x00000000UL /* Non-privileged mode for estination */ +#define _DMA_CTRL_SRC_PROT_CTRL_MASK 0x001C0000UL /* Protection flag for source, bit mask */ +#define _DMA_CTRL_SRC_PROT_CTRL_SHIFT 18 /* Protection flag for source, shift value */ +#define DMA_CTRL_SRC_PROT_PRIVILEGED 0x00040000UL /* Privileged mode for destination */ +#define DMA_CTRL_SRC_PROT_NON_PRIVILEGED 0x00000000UL /* Non-privileged mode for estination */ +#define _DMA_CTRL_PROT_NON_PRIVILEGED 0x00 /* Protection bits to indicate non-privileged access */ +#define _DMA_CTRL_PROT_PRIVILEGED 0x01 /* Protection bits to indicate privileged access */ +#define _DMA_CTRL_R_POWER_MASK 0x0003C000UL /* DMA arbitration mask */ +#define _DMA_CTRL_R_POWER_SHIFT 14 /* Number of DMA cycles before controller does new arbitration in 2^R */ +#define _DMA_CTRL_R_POWER_1 0x00 /* Arbitrate after each transfer */ +#define _DMA_CTRL_R_POWER_2 0x01 /* Arbitrate after every 2 transfers */ +#define _DMA_CTRL_R_POWER_4 0x02 /* Arbitrate after every 4 transfers */ +#define _DMA_CTRL_R_POWER_8 0x03 /* Arbitrate after every 8 transfers */ +#define _DMA_CTRL_R_POWER_16 0x04 /* Arbitrate after every 16 transfers */ +#define _DMA_CTRL_R_POWER_32 0x05 /* Arbitrate after every 32 transfers */ +#define _DMA_CTRL_R_POWER_64 0x06 /* Arbitrate after every 64 transfers */ +#define _DMA_CTRL_R_POWER_128 0x07 /* Arbitrate after every 128 transfers */ +#define _DMA_CTRL_R_POWER_256 0x08 /* Arbitrate after every 256 transfers */ +#define _DMA_CTRL_R_POWER_512 0x09 /* Arbitrate after every 512 transfers */ +#define _DMA_CTRL_R_POWER_1024 0x0a /* Arbitrate after every 1024 transfers */ +#define DMA_CTRL_R_POWER_1 0x00000000UL /* Arbitrate after each transfer */ +#define DMA_CTRL_R_POWER_2 0x00004000UL /* Arbitrate after every 2 transfers */ +#define DMA_CTRL_R_POWER_4 0x00008000UL /* Arbitrate after every 4 transfers */ +#define DMA_CTRL_R_POWER_8 0x0000c000UL /* Arbitrate after every 8 transfers */ +#define DMA_CTRL_R_POWER_16 0x00010000UL /* Arbitrate after every 16 transfers */ +#define DMA_CTRL_R_POWER_32 0x00014000UL /* Arbitrate after every 32 transfers */ +#define DMA_CTRL_R_POWER_64 0x00018000UL /* Arbitrate after every 64 transfers */ +#define DMA_CTRL_R_POWER_128 0x0001c000UL /* Arbitrate after every 128 transfers */ +#define DMA_CTRL_R_POWER_256 0x00020000UL /* Arbitrate after every 256 transfers */ +#define DMA_CTRL_R_POWER_512 0x00024000UL /* Arbitrate after every 512 transfers */ +#define DMA_CTRL_R_POWER_1024 0x00028000UL /* Arbitrate after every 1024 transfers */ +#define _DMA_CTRL_N_MINUS_1_MASK 0x00003FF0UL /* Number of DMA transfers minus 1, bit mask. See PL230 documentation */ +#define _DMA_CTRL_N_MINUS_1_SHIFT 4 /* Number of DMA transfers minus 1, shift mask. See PL230 documentation */ +#define _DMA_CTRL_NEXT_USEBURST_MASK 0x00000008UL /* DMA useburst_set[C] is 1 when using scatter-gather DMA and using alternate data */ +#define _DMA_CTRL_NEXT_USEBURST_SHIFT 3 /* DMA useburst shift */ +#define _DMA_CTRL_CYCLE_CTRL_MASK 0x00000007UL /* DMA Cycle control bit mask - basic/auto/ping-poing/scath-gath */ +#define _DMA_CTRL_CYCLE_CTRL_SHIFT 0 /* DMA Cycle control bit shift */ +#define _DMA_CTRL_CYCLE_CTRL_INVALID 0x00 /* Invalid cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_BASIC 0x01 /* Basic cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_AUTO 0x02 /* Auto cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_PINGPONG 0x03 /* PingPong cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER 0x04 /* Memory scatter gather cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER_ALT 0x05 /* Memory scatter gather using alternate structure */ +#define _DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER 0x06 /* Peripheral scatter gather cycle type */ +#define _DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER_ALT 0x07 /* Peripheral scatter gather cycle type using alternate structure */ +#define DMA_CTRL_CYCLE_CTRL_INVALID 0x00000000UL /* Invalid cycle type */ +#define DMA_CTRL_CYCLE_CTRL_BASIC 0x00000001UL /* Basic cycle type */ +#define DMA_CTRL_CYCLE_CTRL_AUTO 0x00000002UL /* Auto cycle type */ +#define DMA_CTRL_CYCLE_CTRL_PINGPONG 0x00000003UL /* PingPong cycle type */ +#define DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER 0x000000004UL /* Memory scatter gather cycle type */ +#define DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER_ALT 0x000000005UL /* Memory scatter gather using alternate structure */ +#define DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER 0x000000006UL /* Peripheral scatter gather cycle type */ +#define DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER_ALT 0x000000007UL /* Peripheral scatter gather cycle type using alternate structure */ + +/* DMA Request Bit Definitions *************************************************************************************************/ + +#if defined(CONFIG_EFM32_EFM32GG) +# define DMAREQ_ADC0_SINGLE ((8 << 16) + 0) /* DMA channel select for ADC0_SINGLE */ +# define DMAREQ_ADC0_SCAN ((8 << 16) + 1) /* DMA channel select for ADC0_SCAN */ +# define DMAREQ_DAC0_CH0 ((10 << 16) + 0) /* DMA channel select for DAC0_CH0 */ +# define DMAREQ_DAC0_CH1 ((10 << 16) + 1) /* DMA channel select for DAC0_CH1 */ +# define DMAREQ_USART0_RXDATAV ((12 << 16) + 0) /* DMA channel select for USART0_RXDATAV */ +# define DMAREQ_USART0_TXBL ((12 << 16) + 1) /* DMA channel select for USART0_TXBL */ +# define DMAREQ_USART0_TXEMPTY ((12 << 16) + 2) /* DMA channel select for USART0_TXEMPTY */ +# define DMAREQ_USART1_RXDATAV ((13 << 16) + 0) /* DMA channel select for USART1_RXDATAV */ +# define DMAREQ_USART1_TXBL ((13 << 16) + 1) /* DMA channel select for USART1_TXBL */ +# define DMAREQ_USART1_TXEMPTY ((13 << 16) + 2) /* DMA channel select for USART1_TXEMPTY */ +# define DMAREQ_USART1_RXDATAVRIGHT ((13 << 16) + 3) /* DMA channel select for USART1_RXDATAVRIGHT */ +# define DMAREQ_USART1_TXBLRIGHT ((13 << 16) + 4) /* DMA channel select for USART1_TXBLRIGHT */ +# define DMAREQ_USART2_RXDATAV ((14 << 16) + 0) /* DMA channel select for USART2_RXDATAV */ +# define DMAREQ_USART2_TXBL ((14 << 16) + 1) /* DMA channel select for USART2_TXBL */ +# define DMAREQ_USART2_TXEMPTY ((14 << 16) + 2) /* DMA channel select for USART2_TXEMPTY */ +# define DMAREQ_USART2_RXDATAVRIGHT ((14 << 16) + 3) /* DMA channel select for USART2_RXDATAVRIGHT */ +# define DMAREQ_USART2_TXBLRIGHT ((14 << 16) + 4) /* DMA channel select for USART2_TXBLRIGHT */ +# define DMAREQ_LEUART0_RXDATAV ((16 << 16) + 0) /* DMA channel select for LEUART0_RXDATAV */ +# define DMAREQ_LEUART0_TXBL ((16 << 16) + 1) /* DMA channel select for LEUART0_TXBL */ +# define DMAREQ_LEUART0_TXEMPTY ((16 << 16) + 2) /* DMA channel select for LEUART0_TXEMPTY */ +# define DMAREQ_LEUART1_RXDATAV ((17 << 16) + 0) /* DMA channel select for LEUART1_RXDATAV */ +# define DMAREQ_LEUART1_TXBL ((17 << 16) + 1) /* DMA channel select for LEUART1_TXBL */ +# define DMAREQ_LEUART1_TXEMPTY ((17 << 16) + 2) /* DMA channel select for LEUART1_TXEMPTY */ +# define DMAREQ_I2C0_RXDATAV ((20 << 16) + 0) /* DMA channel select for I2C0_RXDATAV */ +# define DMAREQ_I2C0_TXBL ((20 << 16) + 1) /* DMA channel select for I2C0_TXBL */ +# define DMAREQ_I2C1_RXDATAV ((21 << 16) + 0) /* DMA channel select for I2C1_RXDATAV */ +# define DMAREQ_I2C1_TXBL ((21 << 16) + 1) /* DMA channel select for I2C1_TXBL */ +# define DMAREQ_TIMER0_UFOF ((24 << 16) + 0) /* DMA channel select for TIMER0_UFOF */ +# define DMAREQ_TIMER0_CC0 ((24 << 16) + 1) /* DMA channel select for TIMER0_CC0 */ +# define DMAREQ_TIMER0_CC1 ((24 << 16) + 2) /* DMA channel select for TIMER0_CC1 */ +# define DMAREQ_TIMER0_CC2 ((24 << 16) + 3) /* DMA channel select for TIMER0_CC2 */ +# define DMAREQ_TIMER1_UFOF ((25 << 16) + 0) /* DMA channel select for TIMER1_UFOF */ +# define DMAREQ_TIMER1_CC0 ((25 << 16) + 1) /* DMA channel select for TIMER1_CC0 */ +# define DMAREQ_TIMER1_CC1 ((25 << 16) + 2) /* DMA channel select for TIMER1_CC1 */ +# define DMAREQ_TIMER1_CC2 ((25 << 16) + 3) /* DMA channel select for TIMER1_CC2 */ +# define DMAREQ_TIMER2_UFOF ((26 << 16) + 0) /* DMA channel select for TIMER2_UFOF */ +# define DMAREQ_TIMER2_CC0 ((26 << 16) + 1) /* DMA channel select for TIMER2_CC0 */ +# define DMAREQ_TIMER2_CC1 ((26 << 16) + 2) /* DMA channel select for TIMER2_CC1 */ +# define DMAREQ_TIMER2_CC2 ((26 << 16) + 3) /* DMA channel select for TIMER2_CC2 */ +# define DMAREQ_TIMER3_UFOF ((27 << 16) + 0) /* DMA channel select for TIMER3_UFOF */ +# define DMAREQ_TIMER3_CC0 ((27 << 16) + 1) /* DMA channel select for TIMER3_CC0 */ +# define DMAREQ_TIMER3_CC1 ((27 << 16) + 2) /* DMA channel select for TIMER3_CC1 */ +# define DMAREQ_TIMER3_CC2 ((27 << 16) + 3) /* DMA channel select for TIMER3_CC2 */ +# define DMAREQ_UART0_RXDATAV ((44 << 16) + 0) /* DMA channel select for UART0_RXDATAV */ +# define DMAREQ_UART0_TXBL ((44 << 16) + 1) /* DMA channel select for UART0_TXBL */ +# define DMAREQ_UART0_TXEMPTY ((44 << 16) + 2) /* DMA channel select for UART0_TXEMPTY */ +# define DMAREQ_UART1_RXDATAV ((45 << 16) + 0) /* DMA channel select for UART1_RXDATAV */ +# define DMAREQ_UART1_TXBL ((45 << 16) + 1) /* DMA channel select for UART1_TXBL */ +# define DMAREQ_UART1_TXEMPTY ((45 << 16) + 2) /* DMA channel select for UART1_TXEMPTY */ +# define DMAREQ_MSC_WDATA ((48 << 16) + 0) /* DMA channel select for MSC_WDATA */ +# define DMAREQ_AES_DATAWR ((49 << 16) + 0) /* DMA channel select for AES_DATAWR */ +# define DMAREQ_AES_XORDATAWR ((49 << 16) + 1) /* DMA channel select for AES_XORDATAWR */ +# define DMAREQ_AES_DATARD ((49 << 16) + 2) /* DMA channel select for AES_DATARD */ +# define DMAREQ_AES_KEYWR ((49 << 16) + 3) /* DMA channel select for AES_KEYWR */ +# define DMAREQ_LESENSE_BUFDATAV ((50 << 16) + 0) /* DMA channel select for LESENSE_BUFDATAV */ +# define DMAREQ_EBI_PXL0EMPTY ((51 << 16) + 0) /* DMA channel select for EBI_PXL0EMPTY */ +# define DMAREQ_EBI_PXL1EMPTY ((51 << 16) + 1) /* DMA channel select for EBI_PXL1EMPTY */ +# define DMAREQ_EBI_PXLFULL ((51 << 16) + 2) /* DMA channel select for EBI_PXLFULL */ +# define DMAREQ_EBI_DDEMPTY ((51 << 16) + 3) /* DMA channel select for EBI_DDEMPTY */ +#elif defined(CONFIG_EFM32_EFM32G) +# define DMAREQ_ADC0_SINGLE ((8 << 16) + 0) /* DMA channel select for ADC0_SINGLE */ +# define DMAREQ_ADC0_SCAN ((8 << 16) + 1) /* DMA channel select for ADC0_SCAN */ +# define DMAREQ_DAC0_CH0 ((10 << 16) + 0) /* DMA channel select for DAC0_CH0 */ +# define DMAREQ_DAC0_CH1 ((10 << 16) + 1) /* DMA channel select for DAC0_CH1 */ +# define DMAREQ_USART0_RXDATAV ((12 << 16) + 0) /* DMA channel select for USART0_RXDATAV */ +# define DMAREQ_USART0_TXBL ((12 << 16) + 1) /* DMA channel select for USART0_TXBL */ +# define DMAREQ_USART0_TXEMPTY ((12 << 16) + 2) /* DMA channel select for USART0_TXEMPTY */ +# define DMAREQ_USART1_RXDATAV ((13 << 16) + 0) /* DMA channel select for USART1_RXDATAV */ +# define DMAREQ_USART1_TXBL ((13 << 16) + 1) /* DMA channel select for USART1_TXBL */ +# define DMAREQ_USART1_TXEMPTY ((13 << 16) + 2) /* DMA channel select for USART1_TXEMPTY */ +# define DMAREQ_USART2_RXDATAV ((14 << 16) + 0) /* DMA channel select for USART2_RXDATAV */ +# define DMAREQ_USART2_TXBL ((14 << 16) + 1) /* DMA channel select for USART2_TXBL */ +# define DMAREQ_USART2_TXEMPTY ((14 << 16) + 2) /* DMA channel select for USART2_TXEMPTY */ +# define DMAREQ_LEUART0_RXDATAV ((16 << 16) + 0) /* DMA channel select for LEUART0_RXDATAV */ +# define DMAREQ_LEUART0_TXBL ((16 << 16) + 1) /* DMA channel select for LEUART0_TXBL */ +# define DMAREQ_LEUART0_TXEMPTY ((16 << 16) + 2) /* DMA channel select for LEUART0_TXEMPTY */ +# define DMAREQ_LEUART1_RXDATAV ((17 << 16) + 0) /* DMA channel select for LEUART1_RXDATAV */ +# define DMAREQ_LEUART1_TXBL ((17 << 16) + 1) /* DMA channel select for LEUART1_TXBL */ +# define DMAREQ_LEUART1_TXEMPTY ((17 << 16) + 2) /* DMA channel select for LEUART1_TXEMPTY */ +# define DMAREQ_I2C0_RXDATAV ((20 << 16) + 0) /* DMA channel select for I2C0_RXDATAV */ +# define DMAREQ_I2C0_TXBL ((20 << 16) + 1) /* DMA channel select for I2C0_TXBL */ +# define DMAREQ_TIMER0_UFOF ((24 << 16) + 0) /* DMA channel select for TIMER0_UFOF */ +# define DMAREQ_TIMER0_CC0 ((24 << 16) + 1) /* DMA channel select for TIMER0_CC0 */ +# define DMAREQ_TIMER0_CC1 ((24 << 16) + 2) /* DMA channel select for TIMER0_CC1 */ +# define DMAREQ_TIMER0_CC2 ((24 << 16) + 3) /* DMA channel select for TIMER0_CC2 */ +# define DMAREQ_TIMER1_UFOF ((25 << 16) + 0) /* DMA channel select for TIMER1_UFOF */ +# define DMAREQ_TIMER1_CC0 ((25 << 16) + 1) /* DMA channel select for TIMER1_CC0 */ +# define DMAREQ_TIMER1_CC1 ((25 << 16) + 2) /* DMA channel select for TIMER1_CC1 */ +# define DMAREQ_TIMER1_CC2 ((25 << 16) + 3) /* DMA channel select for TIMER1_CC2 */ +# define DMAREQ_TIMER2_UFOF ((26 << 16) + 0) /* DMA channel select for TIMER2_UFOF */ +# define DMAREQ_TIMER2_CC0 ((26 << 16) + 1) /* DMA channel select for TIMER2_CC0 */ +# define DMAREQ_TIMER2_CC1 ((26 << 16) + 2) /* DMA channel select for TIMER2_CC1 */ +# define DMAREQ_TIMER2_CC2 ((26 << 16) + 3) /* DMA channel select for TIMER2_CC2 */ +# define DMAREQ_UART0_RXDATAV ((44 << 16) + 0) /* DMA channel select for UART0_RXDATAV */ +# define DMAREQ_UART0_TXBL ((44 << 16) + 1) /* DMA channel select for UART0_TXBL */ +# define DMAREQ_UART0_TXEMPTY ((44 << 16) + 2) /* DMA channel select for UART0_TXEMPTY */ +# define DMAREQ_MSC_WDATA ((48 << 16) + 0) /* DMA channel select for MSC_WDATA */ +# define DMAREQ_AES_DATAWR ((49 << 16) + 0) /* DMA channel select for AES_DATAWR */ +# define DMAREQ_AES_XORDATAWR ((49 << 16) + 1) /* DMA channel select for AES_XORDATAWR */ +# define DMAREQ_AES_DATARD ((49 << 16) + 2) /* DMA channel select for AES_DATARD */ +# define DMAREQ_AES_KEYWR ((49 << 16) + 3) /* DMA channel select for AES_KEYWR */ +#endif + +/******************************************************************************************************************************* + * Public Types + *******************************************************************************************************************************/ + +struct dma_descriptor_s +{ + volatile void * volatile srcend; /* DMA source address end */ + volatile void * volatile dstend; /* DMA destination address end */ + volatile uint32_t ctrl; /* DMA control register */ + volatile uint32_t user; /* DMA padding register, available for user */ +}; + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_DMA_H */ diff --git a/arch/arm/src/efm32/chip/efm32_emu.h b/arch/arm/src/efm32/chip/efm32_emu.h new file mode 100644 index 0000000000000000000000000000000000000000..9cd1c67bd9c6cd17c4f814c72bc7dc24b081bd98 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_emu.h @@ -0,0 +1,442 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_emu.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_EMU_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_EMU_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* EMU Register Offsets ********************************************************************************************************/ + +#define EFM32_EMU_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_EMU_MEMCTRL_OFFSET 0x0004 /* Memory Control Register */ +#define EFM32_EMU_LOCK_OFFSET 0x0008 /* Configuration Lock Register */ +#define EFM32_EMU_AUXCTRL_OFFSET 0x0024 /* Auxiliary Control Register */ +#define EFM32_EMU_EM4CONF_OFFSET 0x002c /* Energy mode 4 configuration register */ +#define EFM32_EMU_BUCTRL_OFFSET 0x0030 /* Backup Power configuration register */ +#define EFM32_EMU_PWRCONF_OFFSET 0x0034 /* Power connection configuration register */ +#define EFM32_EMU_BUINACT_OFFSET 0x0038 /* Backup mode inactive configuration register */ +#define EFM32_EMU_BUACT_OFFSET 0x003c /* Backup mode active configuration register */ +#define EFM32_EMU_STATUS_OFFSET 0x0040 /* status register */ +#define EFM32_EMU_ROUTE_OFFSET 0x0044 /* I/O Routing Register */ +#define EFM32_EMU_IF_OFFSET 0x0048 /* Interrupt Flag Register */ +#define EFM32_EMU_IFS_OFFSET 0x004c /* Interrupt Flag Set Register */ +#define EFM32_EMU_IFC_OFFSET 0x0050 /* Interrupt Flag Clear Register */ +#define EFM32_EMU_IEN_OFFSET 0x0054 /* Interrupt Enable Register */ +#define EFM32_EMU_BUBODBUVINCAL_OFFSET 0x0058 /* BU_VIN Backup BOD calibration */ +#define EFM32_EMU_BUBODUNREGCAL_OFFSET 0x005c /* Unregulated power Backup BOD calibration */ + +/* EMU Register Addresses ******************************************************************************************************/ + +#define EFM32_EMU_CTRL (EFM32_EMU_BASE+EFM32_EMU_CTRL_OFFSET) +#define EFM32_EMU_MEMCTRL (EFM32_EMU_BASE+EFM32_EMU_MEMCTRL_OFFSET) +#define EFM32_EMU_LOCK (EFM32_EMU_BASE+EFM32_EMU_LOCK_OFFSET) +#define EFM32_EMU_AUXCTRL (EFM32_EMU_BASE+EFM32_EMU_AUXCTRL_OFFSET) +#define EFM32_EMU_EM4CONF (EFM32_EMU_BASE+EFM32_EMU_EM4CONF_OFFSET) +#define EFM32_EMU_BUCTRL (EFM32_EMU_BASE+EFM32_EMU_BUCTRL_OFFSET) +#define EFM32_EMU_PWRCONF (EFM32_EMU_BASE+EFM32_EMU_PWRCONF_OFFSET) +#define EFM32_EMU_BUINACT (EFM32_EMU_BASE+EFM32_EMU_BUINACT_OFFSET) +#define EFM32_EMU_BUACT (EFM32_EMU_BASE+EFM32_EMU_BUACT_OFFSET) +#define EFM32_EMU_STATUS (EFM32_EMU_BASE+EFM32_EMU_STATUS_OFFSET) +#define EFM32_EMU_ROUTE (EFM32_EMU_BASE+EFM32_EMU_ROUTE_OFFSET) +#define EFM32_EMU_IF (EFM32_EMU_BASE+EFM32_EMU_IF_OFFSET) +#define EFM32_EMU_IFS (EFM32_EMU_BASE+EFM32_EMU_IFS_OFFSET) +#define EFM32_EMU_IFC (EFM32_EMU_BASE+EFM32_EMU_IFC_OFFSET) +#define EFM32_EMU_IEN (EFM32_EMU_BASE+EFM32_EMU_IEN_OFFSET) +#define EFM32_EMU_BUBODBUVINCAL (EFM32_EMU_BASE+EFM32_EMU_BUBODBUVINCAL_OFFSET) +#define EFM32_EMU_BUBODUNREGCAL (EFM32_EMU_BASE+EFM32_EMU_BUBODUNREGCAL_OFFSET) + +/* EMU Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for EMU CTRL */ + +#define _EMU_CTRL_RESETVALUE 0x00000000UL /* Default value for EMU_CTRL */ +#define _EMU_CTRL_MASK 0x0000000FUL /* Mask for EMU_CTRL */ + +#define EMU_CTRL_EMVREG (0x1UL << 0) /* Energy Mode Voltage Regulator Control */ +#define _EMU_CTRL_EMVREG_SHIFT 0 /* Shift value for EMU_EMVREG */ +#define _EMU_CTRL_EMVREG_MASK 0x1UL /* Bit mask for EMU_EMVREG */ +#define _EMU_CTRL_EMVREG_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_CTRL */ +#define _EMU_CTRL_EMVREG_REDUCED 0x00000000UL /* Mode REDUCED for EMU_CTRL */ +#define _EMU_CTRL_EMVREG_FULL 0x00000001UL /* Mode FULL for EMU_CTRL */ +#define EMU_CTRL_EMVREG_DEFAULT (_EMU_CTRL_EMVREG_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_CTRL */ +#define EMU_CTRL_EMVREG_REDUCED (_EMU_CTRL_EMVREG_REDUCED << 0) /* Shifted mode REDUCED for EMU_CTRL */ +#define EMU_CTRL_EMVREG_FULL (_EMU_CTRL_EMVREG_FULL << 0) /* Shifted mode FULL for EMU_CTRL */ +#define EMU_CTRL_EM2BLOCK (0x1UL << 1) /* Energy Mode 2 Block */ +#define _EMU_CTRL_EM2BLOCK_SHIFT 1 /* Shift value for EMU_EM2BLOCK */ +#define _EMU_CTRL_EM2BLOCK_MASK 0x2UL /* Bit mask for EMU_EM2BLOCK */ +#define _EMU_CTRL_EM2BLOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_CTRL */ +#define EMU_CTRL_EM2BLOCK_DEFAULT (_EMU_CTRL_EM2BLOCK_DEFAULT << 1) /* Shifted mode DEFAULT for EMU_CTRL */ +#define _EMU_CTRL_EM4CTRL_SHIFT 2 /* Shift value for EMU_EM4CTRL */ +#define _EMU_CTRL_EM4CTRL_MASK 0xCUL /* Bit mask for EMU_EM4CTRL */ +#define _EMU_CTRL_EM4CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_CTRL */ +#define EMU_CTRL_EM4CTRL_DEFAULT (_EMU_CTRL_EM4CTRL_DEFAULT << 2) /* Shifted mode DEFAULT for EMU_CTRL */ + +/* Bit fields for EMU MEMCTRL */ + +#define _EMU_MEMCTRL_RESETVALUE 0x00000000UL /* Default value for EMU_MEMCTRL */ +#define _EMU_MEMCTRL_MASK 0x00000007UL /* Mask for EMU_MEMCTRL */ + +#define _EMU_MEMCTRL_POWERDOWN_SHIFT 0 /* Shift value for EMU_POWERDOWN */ +#define _EMU_MEMCTRL_POWERDOWN_MASK 0x7UL /* Bit mask for EMU_POWERDOWN */ +#define _EMU_MEMCTRL_POWERDOWN_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_MEMCTRL */ +#define _EMU_MEMCTRL_POWERDOWN_BLK3 0x00000004UL /* Mode BLK3 for EMU_MEMCTRL */ +#define _EMU_MEMCTRL_POWERDOWN_BLK23 0x00000006UL /* Mode BLK23 for EMU_MEMCTRL */ +#define _EMU_MEMCTRL_POWERDOWN_BLK123 0x00000007UL /* Mode BLK123 for EMU_MEMCTRL */ +#define EMU_MEMCTRL_POWERDOWN_DEFAULT (_EMU_MEMCTRL_POWERDOWN_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_MEMCTRL */ +#define EMU_MEMCTRL_POWERDOWN_BLK3 (_EMU_MEMCTRL_POWERDOWN_BLK3 << 0) /* Shifted mode BLK3 for EMU_MEMCTRL */ +#define EMU_MEMCTRL_POWERDOWN_BLK23 (_EMU_MEMCTRL_POWERDOWN_BLK23 << 0) /* Shifted mode BLK23 for EMU_MEMCTRL */ +#define EMU_MEMCTRL_POWERDOWN_BLK123 (_EMU_MEMCTRL_POWERDOWN_BLK123 << 0) /* Shifted mode BLK123 for EMU_MEMCTRL */ + +/* Bit fields for EMU LOCK */ + +#define _EMU_LOCK_RESETVALUE 0x00000000UL /* Default value for EMU_LOCK */ +#define _EMU_LOCK_MASK 0x0000FFFFUL /* Mask for EMU_LOCK */ + +#define _EMU_LOCK_LOCKKEY_SHIFT 0 /* Shift value for EMU_LOCKKEY */ +#define _EMU_LOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for EMU_LOCKKEY */ +#define _EMU_LOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_LOCK */ +#define _EMU_LOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for EMU_LOCK */ +#define _EMU_LOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for EMU_LOCK */ +#define _EMU_LOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for EMU_LOCK */ +#define _EMU_LOCK_LOCKKEY_UNLOCK 0x0000ADE8UL /* Mode UNLOCK for EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_DEFAULT (_EMU_LOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_LOCK (_EMU_LOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_UNLOCKED (_EMU_LOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_LOCKED (_EMU_LOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_UNLOCK (_EMU_LOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for EMU_LOCK */ + +/* Bit fields for EMU AUXCTRL */ + +#define _EMU_AUXCTRL_RESETVALUE 0x00000000UL /* Default value for EMU_AUXCTRL */ +#define _EMU_AUXCTRL_MASK 0x00000101UL /* Mask for EMU_AUXCTRL */ + +#define EMU_AUXCTRL_HRCCLR (0x1UL << 0) /* Hard Reset Cause Clear */ +#define _EMU_AUXCTRL_HRCCLR_SHIFT 0 /* Shift value for EMU_HRCCLR */ +#define _EMU_AUXCTRL_HRCCLR_MASK 0x1UL /* Bit mask for EMU_HRCCLR */ +#define _EMU_AUXCTRL_HRCCLR_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_AUXCTRL */ +#define EMU_AUXCTRL_HRCCLR_DEFAULT (_EMU_AUXCTRL_HRCCLR_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_AUXCTRL */ +#define EMU_AUXCTRL_REDLFXOBOOST (0x1UL << 8) /* Reduce LFXO Start-up Boost Current */ +#define _EMU_AUXCTRL_REDLFXOBOOST_SHIFT 8 /* Shift value for EMU_REDLFXOBOOST */ +#define _EMU_AUXCTRL_REDLFXOBOOST_MASK 0x100UL /* Bit mask for EMU_REDLFXOBOOST */ +#define _EMU_AUXCTRL_REDLFXOBOOST_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_AUXCTRL */ +#define EMU_AUXCTRL_REDLFXOBOOST_DEFAULT (_EMU_AUXCTRL_REDLFXOBOOST_DEFAULT << 8) /* Shifted mode DEFAULT for EMU_AUXCTRL */ + +/* Bit fields for EMU EM4CONF */ + +#define _EMU_EM4CONF_RESETVALUE 0x00000000UL /* Default value for EMU_EM4CONF */ +#define _EMU_EM4CONF_MASK 0x0001001FUL /* Mask for EMU_EM4CONF */ + +#define EMU_EM4CONF_VREGEN (0x1UL << 0) /* EM4 voltage regulator enable */ +#define _EMU_EM4CONF_VREGEN_SHIFT 0 /* Shift value for EMU_VREGEN */ +#define _EMU_EM4CONF_VREGEN_MASK 0x1UL /* Bit mask for EMU_VREGEN */ +#define _EMU_EM4CONF_VREGEN_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_VREGEN_DEFAULT (_EMU_EM4CONF_VREGEN_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_BURTCWU (0x1UL << 1) /* Backup RTC EM4 wakeup enable */ +#define _EMU_EM4CONF_BURTCWU_SHIFT 1 /* Shift value for EMU_BURTCWU */ +#define _EMU_EM4CONF_BURTCWU_MASK 0x2UL /* Bit mask for EMU_BURTCWU */ +#define _EMU_EM4CONF_BURTCWU_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_BURTCWU_DEFAULT (_EMU_EM4CONF_BURTCWU_DEFAULT << 1) /* Shifted mode DEFAULT for EMU_EM4CONF */ +#define _EMU_EM4CONF_OSC_SHIFT 2 /* Shift value for EMU_OSC */ +#define _EMU_EM4CONF_OSC_MASK 0xCUL /* Bit mask for EMU_OSC */ +#define _EMU_EM4CONF_OSC_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_EM4CONF */ +#define _EMU_EM4CONF_OSC_ULFRCO 0x00000000UL /* Mode ULFRCO for EMU_EM4CONF */ +#define _EMU_EM4CONF_OSC_LFRCO 0x00000001UL /* Mode LFRCO for EMU_EM4CONF */ +#define _EMU_EM4CONF_OSC_LFXO 0x00000002UL /* Mode LFXO for EMU_EM4CONF */ +#define EMU_EM4CONF_OSC_DEFAULT (_EMU_EM4CONF_OSC_DEFAULT << 2) /* Shifted mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_OSC_ULFRCO (_EMU_EM4CONF_OSC_ULFRCO << 2) /* Shifted mode ULFRCO for EMU_EM4CONF */ +#define EMU_EM4CONF_OSC_LFRCO (_EMU_EM4CONF_OSC_LFRCO << 2) /* Shifted mode LFRCO for EMU_EM4CONF */ +#define EMU_EM4CONF_OSC_LFXO (_EMU_EM4CONF_OSC_LFXO << 2) /* Shifted mode LFXO for EMU_EM4CONF */ +#define EMU_EM4CONF_BUBODRSTDIS (0x1UL << 4) /* Disable reset from Backup BOD in EM4 */ +#define _EMU_EM4CONF_BUBODRSTDIS_SHIFT 4 /* Shift value for EMU_BUBODRSTDIS */ +#define _EMU_EM4CONF_BUBODRSTDIS_MASK 0x10UL /* Bit mask for EMU_BUBODRSTDIS */ +#define _EMU_EM4CONF_BUBODRSTDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_BUBODRSTDIS_DEFAULT (_EMU_EM4CONF_BUBODRSTDIS_DEFAULT << 4) /* Shifted mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_LOCKCONF (0x1UL << 16) /* EM4 configuration lock enable */ +#define _EMU_EM4CONF_LOCKCONF_SHIFT 16 /* Shift value for EMU_LOCKCONF */ +#define _EMU_EM4CONF_LOCKCONF_MASK 0x10000UL /* Bit mask for EMU_LOCKCONF */ +#define _EMU_EM4CONF_LOCKCONF_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_EM4CONF */ +#define EMU_EM4CONF_LOCKCONF_DEFAULT (_EMU_EM4CONF_LOCKCONF_DEFAULT << 16) /* Shifted mode DEFAULT for EMU_EM4CONF */ + +/* Bit fields for EMU BUCTRL */ + +#define _EMU_BUCTRL_RESETVALUE 0x00000000UL /* Default value for EMU_BUCTRL */ +#define _EMU_BUCTRL_MASK 0x00000067UL /* Mask for EMU_BUCTRL */ + +#define EMU_BUCTRL_EN (0x1UL << 0) /* Enable backup mode */ +#define _EMU_BUCTRL_EN_SHIFT 0 /* Shift value for EMU_EN */ +#define _EMU_BUCTRL_EN_MASK 0x1UL /* Bit mask for EMU_EN */ +#define _EMU_BUCTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_EN_DEFAULT (_EMU_BUCTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_STATEN (0x1UL << 1) /* Enable backup mode status export */ +#define _EMU_BUCTRL_STATEN_SHIFT 1 /* Shift value for EMU_STATEN */ +#define _EMU_BUCTRL_STATEN_MASK 0x2UL /* Bit mask for EMU_STATEN */ +#define _EMU_BUCTRL_STATEN_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_STATEN_DEFAULT (_EMU_BUCTRL_STATEN_DEFAULT << 1) /* Shifted mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_BODCAL (0x1UL << 2) /* Enable BOD calibration mode */ +#define _EMU_BUCTRL_BODCAL_SHIFT 2 /* Shift value for EMU_BODCAL */ +#define _EMU_BUCTRL_BODCAL_MASK 0x4UL /* Bit mask for EMU_BODCAL */ +#define _EMU_BUCTRL_BODCAL_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_BODCAL_DEFAULT (_EMU_BUCTRL_BODCAL_DEFAULT << 2) /* Shifted mode DEFAULT for EMU_BUCTRL */ +#define _EMU_BUCTRL_PROBE_SHIFT 5 /* Shift value for EMU_PROBE */ +#define _EMU_BUCTRL_PROBE_MASK 0x60UL /* Bit mask for EMU_PROBE */ +#define _EMU_BUCTRL_PROBE_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUCTRL */ +#define _EMU_BUCTRL_PROBE_DISABLE 0x00000000UL /* Mode DISABLE for EMU_BUCTRL */ +#define _EMU_BUCTRL_PROBE_VDDDREG 0x00000001UL /* Mode VDDDREG for EMU_BUCTRL */ +#define _EMU_BUCTRL_PROBE_BUIN 0x00000002UL /* Mode BUIN for EMU_BUCTRL */ +#define _EMU_BUCTRL_PROBE_BUOUT 0x00000003UL /* Mode BUOUT for EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_DEFAULT (_EMU_BUCTRL_PROBE_DEFAULT << 5) /* Shifted mode DEFAULT for EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_DISABLE (_EMU_BUCTRL_PROBE_DISABLE << 5) /* Shifted mode DISABLE for EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_VDDDREG (_EMU_BUCTRL_PROBE_VDDDREG << 5) /* Shifted mode VDDDREG for EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_BUIN (_EMU_BUCTRL_PROBE_BUIN << 5) /* Shifted mode BUIN for EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_BUOUT (_EMU_BUCTRL_PROBE_BUOUT << 5) /* Shifted mode BUOUT for EMU_BUCTRL */ + +/* Bit fields for EMU PWRCONF */ + +#define _EMU_PWRCONF_RESETVALUE 0x00000000UL /* Default value for EMU_PWRCONF */ +#define _EMU_PWRCONF_MASK 0x0000001FUL /* Mask for EMU_PWRCONF */ + +#define EMU_PWRCONF_VOUTWEAK (0x1UL << 0) /* BU_VOUT weak enable */ +#define _EMU_PWRCONF_VOUTWEAK_SHIFT 0 /* Shift value for EMU_VOUTWEAK */ +#define _EMU_PWRCONF_VOUTWEAK_MASK 0x1UL /* Bit mask for EMU_VOUTWEAK */ +#define _EMU_PWRCONF_VOUTWEAK_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_VOUTWEAK_DEFAULT (_EMU_PWRCONF_VOUTWEAK_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_VOUTMED (0x1UL << 1) /* BU_VOUT medium enable */ +#define _EMU_PWRCONF_VOUTMED_SHIFT 1 /* Shift value for EMU_VOUTMED */ +#define _EMU_PWRCONF_VOUTMED_MASK 0x2UL /* Bit mask for EMU_VOUTMED */ +#define _EMU_PWRCONF_VOUTMED_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_VOUTMED_DEFAULT (_EMU_PWRCONF_VOUTMED_DEFAULT << 1) /* Shifted mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_VOUTSTRONG (0x1UL << 2) /* BU_VOUT strong enable */ +#define _EMU_PWRCONF_VOUTSTRONG_SHIFT 2 /* Shift value for EMU_VOUTSTRONG */ +#define _EMU_PWRCONF_VOUTSTRONG_MASK 0x4UL /* Bit mask for EMU_VOUTSTRONG */ +#define _EMU_PWRCONF_VOUTSTRONG_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_VOUTSTRONG_DEFAULT (_EMU_PWRCONF_VOUTSTRONG_DEFAULT << 2) /* Shifted mode DEFAULT for EMU_PWRCONF */ +#define _EMU_PWRCONF_PWRRES_SHIFT 3 /* Shift value for EMU_PWRRES */ +#define _EMU_PWRCONF_PWRRES_MASK 0x18UL /* Bit mask for EMU_PWRRES */ +#define _EMU_PWRCONF_PWRRES_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_PWRCONF */ +#define _EMU_PWRCONF_PWRRES_RES0 0x00000000UL /* Mode RES0 for EMU_PWRCONF */ +#define _EMU_PWRCONF_PWRRES_RES1 0x00000001UL /* Mode RES1 for EMU_PWRCONF */ +#define _EMU_PWRCONF_PWRRES_RES2 0x00000002UL /* Mode RES2 for EMU_PWRCONF */ +#define _EMU_PWRCONF_PWRRES_RES3 0x00000003UL /* Mode RES3 for EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_DEFAULT (_EMU_PWRCONF_PWRRES_DEFAULT << 3) /* Shifted mode DEFAULT for EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_RES0 (_EMU_PWRCONF_PWRRES_RES0 << 3) /* Shifted mode RES0 for EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_RES1 (_EMU_PWRCONF_PWRRES_RES1 << 3) /* Shifted mode RES1 for EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_RES2 (_EMU_PWRCONF_PWRRES_RES2 << 3) /* Shifted mode RES2 for EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_RES3 (_EMU_PWRCONF_PWRRES_RES3 << 3) /* Shifted mode RES3 for EMU_PWRCONF */ + +/* Bit fields for EMU BUINACT */ + +#define _EMU_BUINACT_RESETVALUE 0x0000000BUL /* Default value for EMU_BUINACT */ +#define _EMU_BUINACT_MASK 0x0000007FUL /* Mask for EMU_BUINACT */ + +#define _EMU_BUINACT_BUENTHRES_SHIFT 0 /* Shift value for EMU_BUENTHRES */ +#define _EMU_BUINACT_BUENTHRES_MASK 0x7UL /* Bit mask for EMU_BUENTHRES */ +#define _EMU_BUINACT_BUENTHRES_DEFAULT 0x00000003UL /* Mode DEFAULT for EMU_BUINACT */ +#define EMU_BUINACT_BUENTHRES_DEFAULT (_EMU_BUINACT_BUENTHRES_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_BUINACT */ +#define _EMU_BUINACT_BUENRANGE_SHIFT 3 /* Shift value for EMU_BUENRANGE */ +#define _EMU_BUINACT_BUENRANGE_MASK 0x18UL /* Bit mask for EMU_BUENRANGE */ +#define _EMU_BUINACT_BUENRANGE_DEFAULT 0x00000001UL /* Mode DEFAULT for EMU_BUINACT */ +#define EMU_BUINACT_BUENRANGE_DEFAULT (_EMU_BUINACT_BUENRANGE_DEFAULT << 3) /* Shifted mode DEFAULT for EMU_BUINACT */ +#define _EMU_BUINACT_PWRCON_SHIFT 5 /* Shift value for EMU_PWRCON */ +#define _EMU_BUINACT_PWRCON_MASK 0x60UL /* Bit mask for EMU_PWRCON */ +#define _EMU_BUINACT_PWRCON_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUINACT */ +#define _EMU_BUINACT_PWRCON_NONE 0x00000000UL /* Mode NONE for EMU_BUINACT */ +#define _EMU_BUINACT_PWRCON_BUMAIN 0x00000001UL /* Mode BUMAIN for EMU_BUINACT */ +#define _EMU_BUINACT_PWRCON_MAINBU 0x00000002UL /* Mode MAINBU for EMU_BUINACT */ +#define _EMU_BUINACT_PWRCON_NODIODE 0x00000003UL /* Mode NODIODE for EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_DEFAULT (_EMU_BUINACT_PWRCON_DEFAULT << 5) /* Shifted mode DEFAULT for EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_NONE (_EMU_BUINACT_PWRCON_NONE << 5) /* Shifted mode NONE for EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_BUMAIN (_EMU_BUINACT_PWRCON_BUMAIN << 5) /* Shifted mode BUMAIN for EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_MAINBU (_EMU_BUINACT_PWRCON_MAINBU << 5) /* Shifted mode MAINBU for EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_NODIODE (_EMU_BUINACT_PWRCON_NODIODE << 5) /* Shifted mode NODIODE for EMU_BUINACT */ + +/* Bit fields for EMU BUACT */ + +#define _EMU_BUACT_RESETVALUE 0x0000000BUL /* Default value for EMU_BUACT */ +#define _EMU_BUACT_MASK 0x0000007FUL /* Mask for EMU_BUACT */ + +#define _EMU_BUACT_BUEXTHRES_SHIFT 0 /* Shift value for EMU_BUEXTHRES */ +#define _EMU_BUACT_BUEXTHRES_MASK 0x7UL /* Bit mask for EMU_BUEXTHRES */ +#define _EMU_BUACT_BUEXTHRES_DEFAULT 0x00000003UL /* Mode DEFAULT for EMU_BUACT */ +#define EMU_BUACT_BUEXTHRES_DEFAULT (_EMU_BUACT_BUEXTHRES_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_BUACT */ +#define _EMU_BUACT_BUEXRANGE_SHIFT 3 /* Shift value for EMU_BUEXRANGE */ +#define _EMU_BUACT_BUEXRANGE_MASK 0x18UL /* Bit mask for EMU_BUEXRANGE */ +#define _EMU_BUACT_BUEXRANGE_DEFAULT 0x00000001UL /* Mode DEFAULT for EMU_BUACT */ +#define EMU_BUACT_BUEXRANGE_DEFAULT (_EMU_BUACT_BUEXRANGE_DEFAULT << 3) /* Shifted mode DEFAULT for EMU_BUACT */ +#define _EMU_BUACT_PWRCON_SHIFT 5 /* Shift value for EMU_PWRCON */ +#define _EMU_BUACT_PWRCON_MASK 0x60UL /* Bit mask for EMU_PWRCON */ +#define _EMU_BUACT_PWRCON_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_BUACT */ +#define _EMU_BUACT_PWRCON_NONE 0x00000000UL /* Mode NONE for EMU_BUACT */ +#define _EMU_BUACT_PWRCON_BUMAIN 0x00000001UL /* Mode BUMAIN for EMU_BUACT */ +#define _EMU_BUACT_PWRCON_MAINBU 0x00000002UL /* Mode MAINBU for EMU_BUACT */ +#define _EMU_BUACT_PWRCON_NODIODE 0x00000003UL /* Mode NODIODE for EMU_BUACT */ +#define EMU_BUACT_PWRCON_DEFAULT (_EMU_BUACT_PWRCON_DEFAULT << 5) /* Shifted mode DEFAULT for EMU_BUACT */ +#define EMU_BUACT_PWRCON_NONE (_EMU_BUACT_PWRCON_NONE << 5) /* Shifted mode NONE for EMU_BUACT */ +#define EMU_BUACT_PWRCON_BUMAIN (_EMU_BUACT_PWRCON_BUMAIN << 5) /* Shifted mode BUMAIN for EMU_BUACT */ +#define EMU_BUACT_PWRCON_MAINBU (_EMU_BUACT_PWRCON_MAINBU << 5) /* Shifted mode MAINBU for EMU_BUACT */ +#define EMU_BUACT_PWRCON_NODIODE (_EMU_BUACT_PWRCON_NODIODE << 5) /* Shifted mode NODIODE for EMU_BUACT */ + +/* Bit fields for EMU STATUS */ + +#define _EMU_STATUS_RESETVALUE 0x00000000UL /* Default value for EMU_STATUS */ +#define _EMU_STATUS_MASK 0x00000001UL /* Mask for EMU_STATUS */ + +#define EMU_STATUS_BURDY (0x1UL << 0) /* Backup mode ready */ +#define _EMU_STATUS_BURDY_SHIFT 0 /* Shift value for EMU_BURDY */ +#define _EMU_STATUS_BURDY_MASK 0x1UL /* Bit mask for EMU_BURDY */ +#define _EMU_STATUS_BURDY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_STATUS */ +#define EMU_STATUS_BURDY_DEFAULT (_EMU_STATUS_BURDY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_STATUS */ + +/* Bit fields for EMU ROUTE */ + +#define _EMU_ROUTE_RESETVALUE 0x00000001UL /* Default value for EMU_ROUTE */ +#define _EMU_ROUTE_MASK 0x00000001UL /* Mask for EMU_ROUTE */ + +#define EMU_ROUTE_BUVINPEN (0x1UL << 0) /* BU_VIN Pin Enable */ +#define _EMU_ROUTE_BUVINPEN_SHIFT 0 /* Shift value for EMU_BUVINPEN */ +#define _EMU_ROUTE_BUVINPEN_MASK 0x1UL /* Bit mask for EMU_BUVINPEN */ +#define _EMU_ROUTE_BUVINPEN_DEFAULT 0x00000001UL /* Mode DEFAULT for EMU_ROUTE */ +#define EMU_ROUTE_BUVINPEN_DEFAULT (_EMU_ROUTE_BUVINPEN_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_ROUTE */ + +/* Bit fields for EMU IF */ + +#define _EMU_IF_RESETVALUE 0x00000000UL /* Default value for EMU_IF */ +#define _EMU_IF_MASK 0x00000001UL /* Mask for EMU_IF */ + +#define EMU_IF_BURDY (0x1UL << 0) /* Backup functionality ready Interrupt Flag */ +#define _EMU_IF_BURDY_SHIFT 0 /* Shift value for EMU_BURDY */ +#define _EMU_IF_BURDY_MASK 0x1UL /* Bit mask for EMU_BURDY */ +#define _EMU_IF_BURDY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_IF */ +#define EMU_IF_BURDY_DEFAULT (_EMU_IF_BURDY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_IF */ + +/* Bit fields for EMU IFS */ + +#define _EMU_IFS_RESETVALUE 0x00000000UL /* Default value for EMU_IFS */ +#define _EMU_IFS_MASK 0x00000001UL /* Mask for EMU_IFS */ + +#define EMU_IFS_BURDY (0x1UL << 0) /* Set Backup functionality ready Interrupt Flag */ +#define _EMU_IFS_BURDY_SHIFT 0 /* Shift value for EMU_BURDY */ +#define _EMU_IFS_BURDY_MASK 0x1UL /* Bit mask for EMU_BURDY */ +#define _EMU_IFS_BURDY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_IFS */ +#define EMU_IFS_BURDY_DEFAULT (_EMU_IFS_BURDY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_IFS */ + +/* Bit fields for EMU IFC */ + +#define _EMU_IFC_RESETVALUE 0x00000000UL /* Default value for EMU_IFC */ +#define _EMU_IFC_MASK 0x00000001UL /* Mask for EMU_IFC */ + +#define EMU_IFC_BURDY (0x1UL << 0) /* Clear Backup functionality ready Interrupt Flag */ +#define _EMU_IFC_BURDY_SHIFT 0 /* Shift value for EMU_BURDY */ +#define _EMU_IFC_BURDY_MASK 0x1UL /* Bit mask for EMU_BURDY */ +#define _EMU_IFC_BURDY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_IFC */ +#define EMU_IFC_BURDY_DEFAULT (_EMU_IFC_BURDY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_IFC */ + +/* Bit fields for EMU IEN */ + +#define _EMU_IEN_RESETVALUE 0x00000000UL /* Default value for EMU_IEN */ +#define _EMU_IEN_MASK 0x00000001UL /* Mask for EMU_IEN */ + +#define EMU_IEN_BURDY (0x1UL << 0) /* Backup functionality ready Interrupt Enable */ +#define _EMU_IEN_BURDY_SHIFT 0 /* Shift value for EMU_BURDY */ +#define _EMU_IEN_BURDY_MASK 0x1UL /* Bit mask for EMU_BURDY */ +#define _EMU_IEN_BURDY_DEFAULT 0x00000000UL /* Mode DEFAULT for EMU_IEN */ +#define EMU_IEN_BURDY_DEFAULT (_EMU_IEN_BURDY_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_IEN */ + +/* Bit fields for EMU BUBODBUVINCAL */ + +#define _EMU_BUBODBUVINCAL_RESETVALUE 0x0000000BUL /* Default value for EMU_BUBODBUVINCAL */ +#define _EMU_BUBODBUVINCAL_MASK 0x0000001FUL /* Mask for EMU_BUBODBUVINCAL */ + +#define _EMU_BUBODBUVINCAL_THRES_SHIFT 0 /* Shift value for EMU_THRES */ +#define _EMU_BUBODBUVINCAL_THRES_MASK 0x7UL /* Bit mask for EMU_THRES */ +#define _EMU_BUBODBUVINCAL_THRES_DEFAULT 0x00000003UL /* Mode DEFAULT for EMU_BUBODBUVINCAL */ +#define EMU_BUBODBUVINCAL_THRES_DEFAULT (_EMU_BUBODBUVINCAL_THRES_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_BUBODBUVINCAL */ +#define _EMU_BUBODBUVINCAL_RANGE_SHIFT 3 /* Shift value for EMU_RANGE */ +#define _EMU_BUBODBUVINCAL_RANGE_MASK 0x18UL /* Bit mask for EMU_RANGE */ +#define _EMU_BUBODBUVINCAL_RANGE_DEFAULT 0x00000001UL /* Mode DEFAULT for EMU_BUBODBUVINCAL */ +#define EMU_BUBODBUVINCAL_RANGE_DEFAULT (_EMU_BUBODBUVINCAL_RANGE_DEFAULT << 3) /* Shifted mode DEFAULT for EMU_BUBODBUVINCAL */ + +/* Bit fields for EMU BUBODUNREGCAL */ + +#define _EMU_BUBODUNREGCAL_RESETVALUE 0x0000000BUL /* Default value for EMU_BUBODUNREGCAL */ +#define _EMU_BUBODUNREGCAL_MASK 0x0000001FUL /* Mask for EMU_BUBODUNREGCAL */ + +#define _EMU_BUBODUNREGCAL_THRES_SHIFT 0 /* Shift value for EMU_THRES */ +#define _EMU_BUBODUNREGCAL_THRES_MASK 0x7UL /* Bit mask for EMU_THRES */ +#define _EMU_BUBODUNREGCAL_THRES_DEFAULT 0x00000003UL /* Mode DEFAULT for EMU_BUBODUNREGCAL */ +#define EMU_BUBODUNREGCAL_THRES_DEFAULT (_EMU_BUBODUNREGCAL_THRES_DEFAULT << 0) /* Shifted mode DEFAULT for EMU_BUBODUNREGCAL */ +#define _EMU_BUBODUNREGCAL_RANGE_SHIFT 3 /* Shift value for EMU_RANGE */ +#define _EMU_BUBODUNREGCAL_RANGE_MASK 0x18UL /* Bit mask for EMU_RANGE */ +#define _EMU_BUBODUNREGCAL_RANGE_DEFAULT 0x00000001UL /* Mode DEFAULT for EMU_BUBODUNREGCAL */ +#define EMU_BUBODUNREGCAL_RANGE_DEFAULT (_EMU_BUBODUNREGCAL_RANGE_DEFAULT << 3) /* Shifted mode DEFAULT for EMU_BUBODUNREGCAL */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_EMU_H */ diff --git a/arch/arm/src/efm32/chip/efm32_flash.h b/arch/arm/src/efm32/chip/efm32_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..5c9f153be079de5877448ac25ba564fa2dec8e04 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_flash.h @@ -0,0 +1,57 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip/efm32_flash.h + * + * Copyright (C) 2015 Bouteville Pierre-Noel. All rights reserved. + * Author: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_FLASH_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_FLASH_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_FLASH_PAGESIZE 4096 +#elif defined(CONFIG_EFM32_EFM32LG) +# define EFM32_FLASH_PAGESIZE 2048 +#elif defined(CONFIG_EFM32_EFM32WG) +# define EFM32_FLASH_PAGESIZE 2048 +#elif defined(CONFIG_EFM32_EFM32ZG) +# define EFM32_FLASH_PAGESIZE 1024 +#elif defined(CONFIG_EFM32_EFM32G) +# define EFM32_FLASH_PAGESIZE 512 +#elif defined(CONFIG_EFM32_EFM32TG) +# define EFM32_FLASH_PAGESIZE 512 +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_FLASH_H */ diff --git a/arch/arm/src/efm32/chip/efm32_gpio.h b/arch/arm/src/efm32/chip/efm32_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..ba3b7ebc0bf6b5d9ef8b8f01861f05f3967a8367 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_gpio.h @@ -0,0 +1,1486 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_gpio.h + * + * (C) Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_GPIO_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_GPIO_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) && !defined(CONFIG_EFM32_EFM32G) +# warning This is the EFM32GG/G header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +/* GPIO Register Offsets *******************************************************************************************************/ + +#define EFM32_GPIIO_PA 0 +#define EFM32_GPIIO_PB 1 +#define EFM32_GPIIO_PC 2 +#define EFM32_GPIIO_PD 3 +#define EFM32_GPIIO_PE 4 +#define EFM32_GPIIO_PF 5 + +#define EFM32_GPIO_Pn_OFFSET(n) (0x0024*(n)) +#define EFM32_GPIO_PA_OFFSET 0x0000 +#define EFM32_GPIO_PB_OFFSET 0x0024 +#define EFM32_GPIO_PC_OFFSET 0x0048 +#define EFM32_GPIO_PD_OFFSET 0x006c +#define EFM32_GPIO_PE_OFFSET 0x0090 +#define EFM32_GPIO_PF_OFFSET 0x00b4 + +#define EFM32_GPIO_Pn_CTRL_OFFSET 0x0000 /* Port Control Register */ +#define EFM32_GPIO_Pn_MODEL_OFFSET 0x0004 /* Port Pin Mode Low Register */ +#define EFM32_GPIO_Pn_MODEH_OFFSET 0x0008 /* Port Pin Mode High Register */ +#define EFM32_GPIO_Pn_DOUT_OFFSET 0x000C /* Port Data Out Register */ +#define EFM32_GPIO_Pn_DOUTSET_OFFSET 0x0010 /* Port Data Out Set Register */ +#define EFM32_GPIO_Pn_DOUTCLR_OFFSET 0x0014 /* Port Data Out Clear Register */ +#define EFM32_GPIO_Pn_DOUTTGL_OFFSET 0x0018 /* Port Data Out Toggle Register */ +#define EFM32_GPIO_Pn_DIN_OFFSET 0x001C /* Port Data In Register */ +#define EFM32_GPIO_Pn_PINLOCKN_OFFSET 0x0020 /* Port Unlocked Pins Register */ + +#define EFM32_GPIO_PA_CTRL_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PA_MODEL_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PA_MODEH_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PA_DOUT_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PA_DOUTSET_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PA_DOUTCLR_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PA_DOUTTGL_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PA_DIN_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PA_PINLOCKN_OFFSET (EFM32_GPIO_PA_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PB_CTRL_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PB_MODEL_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PB_MODEH_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PB_DOUT_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PB_DOUTSET_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PB_DOUTCLR_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PB_DOUTTGL_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PB_DIN_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PB_PINLOCKN_OFFSET (EFM32_GPIO_PB_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PC_CTRL_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PC_MODEL_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PC_MODEH_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PC_DOUT_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PC_DOUTSET_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PC_DOUTCLR_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PC_DOUTTGL_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PC_DIN_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PC_PINLOCKN_OFFSET (EFM32_GPIO_PC_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PD_CTRL_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PD_MODEL_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PD_MODEH_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PD_DOUT_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PD_DOUTSET_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PD_DOUTCLR_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PD_DOUTTGL_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PD_DIN_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PD_PINLOCKN_OFFSET (EFM32_GPIO_PD_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PE_CTRL_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PE_MODEL_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PE_MODEH_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PE_DOUT_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PE_DOUTSET_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PE_DOUTCLR_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PE_DOUTTGL_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PE_DIN_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PE_PINLOCKN_OFFSET (EFM32_GPIO_PE_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PF_CTRL_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_CTRL_OFFSET) +#define EFM32_GPIO_PF_MODEL_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_PF_MODEH_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_PF_DOUT_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_PF_DOUTSET_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_PF_DOUTCLR_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_PF_DOUTTGL_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_PF_DIN_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_PF_PINLOCKN_OFFSET (EFM32_GPIO_PF_OFFSET+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_EXTIPSELL_OFFSET 0x100 /* External Interrupt Port Select Low Register */ +#define EFM32_GPIO_EXTIPSELH_OFFSET 0x104 /* External Interrupt Port Select High Register */ +#define EFM32_GPIO_EXTIRISE_OFFSET 0x108 /* External Interrupt Rising Edge Trigger Register */ +#define EFM32_GPIO_EXTIFALL_OFFSET 0x10c /* External Interrupt Falling Edge Trigger Register */ +#define EFM32_GPIO_IEN_OFFSET 0x110 /* Interrupt Enable Register */ +#define EFM32_GPIO_IF_OFFSET 0x114 /* Interrupt Flag Register */ +#define EFM32_GPIO_IFS_OFFSET 0x118 /* Interrupt Flag Set Register */ +#define EFM32_GPIO_IFC_OFFSET 0x11c /* Interrupt Flag Clear Register */ +#define EFM32_GPIO_ROUTE_OFFSET 0x120 /* I/O Routing Register */ +#define EFM32_GPIO_INSENSE_OFFSET 0x124 /* Input Sense Register */ +#define EFM32_GPIO_LOCK_OFFSET 0x128 /* Configuration Lock Register */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_GPIO_CTRL_OFFSET 0x12c /* GPIO Control Register */ +# define EFM32_GPIO_CMD_OFFSET 0x130 /* GPIO Command Register */ +# define EFM32_GPIO_EM4WUEN_OFFSET 0x134 /* EM4 Wake-up Enable Register */ +# define EFM32_GPIO_EM4WUPOL_OFFSET 0x138 /* EM4 Wake-up Polarity Register */ +# define EFM32_GPIO_EM4WUCAUSE_OFFSET 0x13c /* EM4 Wake-up Cause Register */ +#endif + +/* GPIO Register Addresses *****************************************************************************************************/ + +#define EFM32_GPIO_Pn_BASE(n) (EFM32_GPIO_BASE+EFM32_GPIO_Pn_OFFSET(n)) +#define EFM32_GPIO_PA_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PA_OFFSET) +#define EFM32_GPIO_PB_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PB_OFFSET) +#define EFM32_GPIO_PC_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PC_OFFSET) +#define EFM32_GPIO_PD_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PD_OFFSET) +#define EFM32_GPIO_PE_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PE_OFFSET) +#define EFM32_GPIO_PF_BASE (EFM32_GPIO_BASE+EFM32_GPIO_PF_OFFSET) + +#define EFM32_GPIO_Pn_CTRL(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_CTRL_OFFSET ) +#define EFM32_GPIO_Pn_MODEL(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_MODEL_OFFSET) +#define EFM32_GPIO_Pn_MODEH(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_MODEH_OFFSET) +#define EFM32_GPIO_Pn_DOUT(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_DOUT_OFFSET) +#define EFM32_GPIO_Pn_DOUTSET(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_DOUTSET_OFFSET) +#define EFM32_GPIO_Pn_DOUTCLR(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_DOUTCLR_OFFSET) +#define EFM32_GPIO_Pn_DOUTTGL(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_DOUTTGL_OFFSET) +#define EFM32_GPIO_Pn_DIN(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_DIN_OFFSET) +#define EFM32_GPIO_Pn_PINLOCKN(n) (EFM32_GPIO_Pn_BASE(n)+EFM32_GPIO_Pn_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PA_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PA_CTRL_OFFSET) +#define EFM32_GPIO_PA_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PA_MODEL_OFFSET) +#define EFM32_GPIO_PA_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PA_MODEH_OFFSET) +#define EFM32_GPIO_PA_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PA_DOUT_OFFSET) +#define EFM32_GPIO_PA_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PA_DOUTSET_OFFSET) +#define EFM32_GPIO_PA_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PA_DOUTCLR_OFFSET) +#define EFM32_GPIO_PA_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PA_DOUTTGL_OFFSET) +#define EFM32_GPIO_PA_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PA_DIN_OFFSET) +#define EFM32_GPIO_PA_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PA_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PB_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PB_CTRL_OFFSET) +#define EFM32_GPIO_PB_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PB_MODEL_OFFSET) +#define EFM32_GPIO_PB_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PB_MODEH_OFFSET) +#define EFM32_GPIO_PB_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PB_DOUT_OFFSET) +#define EFM32_GPIO_PB_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PB_DOUTSET_OFFSET) +#define EFM32_GPIO_PB_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PB_DOUTCLR_OFFSET) +#define EFM32_GPIO_PB_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PB_DOUTTGL_OFFSET) +#define EFM32_GPIO_PB_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PB_DIN_OFFSET) +#define EFM32_GPIO_PB_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PB_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PC_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PC_CTRL_OFFSET) +#define EFM32_GPIO_PC_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PC_MODEL_OFFSET) +#define EFM32_GPIO_PC_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PC_MODEH_OFFSET) +#define EFM32_GPIO_PC_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PC_DOUT_OFFSET) +#define EFM32_GPIO_PC_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PC_DOUTSET_OFFSET) +#define EFM32_GPIO_PC_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PC_DOUTCLR_OFFSET) +#define EFM32_GPIO_PC_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PC_DOUTTGL_OFFSET) +#define EFM32_GPIO_PC_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PC_DIN_OFFSET) +#define EFM32_GPIO_PC_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PC_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PD_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PD_CTRL_OFFSET) +#define EFM32_GPIO_PD_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PD_MODEL_OFFSET) +#define EFM32_GPIO_PD_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PD_MODEH_OFFSET) +#define EFM32_GPIO_PD_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PD_DOUT_OFFSET) +#define EFM32_GPIO_PD_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PD_DOUTSET_OFFSET) +#define EFM32_GPIO_PD_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PD_DOUTCLR_OFFSET) +#define EFM32_GPIO_PD_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PD_DOUTTGL_OFFSET) +#define EFM32_GPIO_PD_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PD_DIN_OFFSET) +#define EFM32_GPIO_PD_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PD_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PE_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PE_CTRL_OFFSET) +#define EFM32_GPIO_PE_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PE_MODEL_OFFSET) +#define EFM32_GPIO_PE_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PE_MODEH_OFFSET) +#define EFM32_GPIO_PE_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PE_DOUT_OFFSET) +#define EFM32_GPIO_PE_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PE_DOUTSET_OFFSET) +#define EFM32_GPIO_PE_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PE_DOUTCLR_OFFSET) +#define EFM32_GPIO_PE_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PE_DOUTTGL_OFFSET) +#define EFM32_GPIO_PE_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PE_DIN_OFFSET) +#define EFM32_GPIO_PE_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PE_PINLOCKN_OFFSET) + +#define EFM32_GPIO_PF_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_PF_CTRL_OFFSET) +#define EFM32_GPIO_PF_MODEL (EFM32_GPIO_BASE+EFM32_GPIO_PF_MODEL_OFFSET) +#define EFM32_GPIO_PF_MODEH (EFM32_GPIO_BASE+EFM32_GPIO_PF_MODEH_OFFSET) +#define EFM32_GPIO_PF_DOUT (EFM32_GPIO_BASE+EFM32_GPIO_PF_DOUT_OFFSET) +#define EFM32_GPIO_PF_DOUTSET (EFM32_GPIO_BASE+EFM32_GPIO_PF_DOUTSET_OFFSET) +#define EFM32_GPIO_PF_DOUTCLR (EFM32_GPIO_BASE+EFM32_GPIO_PF_DOUTCLR_OFFSET) +#define EFM32_GPIO_PF_DOUTTGL (EFM32_GPIO_BASE+EFM32_GPIO_PF_DOUTTGL_OFFSET) +#define EFM32_GPIO_PF_DIN (EFM32_GPIO_BASE+EFM32_GPIO_PF_DIN_OFFSET) +#define EFM32_GPIO_PF_PINLOCKN (EFM32_GPIO_BASE+EFM32_GPIO_PF_PINLOCKN_OFFSET) + +#define EFM32_GPIO_EXTIPSELL (EFM32_GPIO_BASE+EFM32_GPIO_EXTIPSELL_OFFSET) +#define EFM32_GPIO_EXTIPSELH (EFM32_GPIO_BASE+EFM32_GPIO_EXTIPSELH_OFFSET) +#define EFM32_GPIO_EXTIRISE (EFM32_GPIO_BASE+EFM32_GPIO_EXTIRISE_OFFSET) +#define EFM32_GPIO_EXTIFALL (EFM32_GPIO_BASE+EFM32_GPIO_EXTIFALL_OFFSET) +#define EFM32_GPIO_IEN (EFM32_GPIO_BASE+EFM32_GPIO_IEN_OFFSET) +#define EFM32_GPIO_IF (EFM32_GPIO_BASE+EFM32_GPIO_IF_OFFSET) +#define EFM32_GPIO_IFS (EFM32_GPIO_BASE+EFM32_GPIO_IFS_OFFSET) +#define EFM32_GPIO_IFC (EFM32_GPIO_BASE+EFM32_GPIO_IFC_OFFSET) +#define EFM32_GPIO_ROUTE (EFM32_GPIO_BASE+EFM32_GPIO_ROUTE_OFFSET) +#define EFM32_GPIO_INSENSE (EFM32_GPIO_BASE+EFM32_GPIO_INSENSE_OFFSET) +#define EFM32_GPIO_LOCK (EFM32_GPIO_BASE+EFM32_GPIO_LOCK_OFFSET) + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_GPIO_CTRL (EFM32_GPIO_BASE+EFM32_GPIO_CTRL_OFFSET) +# define EFM32_GPIO_CMD (EFM32_GPIO_BASE+EFM32_GPIO_CMD_OFFSET) +# define EFM32_GPIO_EM4WUEN (EFM32_GPIO_BASE+EFM32_GPIO_EM4WUEN_OFFSET) +# define EFM32_GPIO_EM4WUPOL (EFM32_GPIO_BASE+EFM32_GPIO_EM4WUPOL_OFFSET) +# define EFM32_GPIO_EM4WUCAUSE (EFM32_GPIO_BASE+EFM32_GPIO_EM4WUCAUSE_OFFSET) +#endif + +/* GPIO Register Bit Field Definitions *****************************************************************************************/ + +/* Bit fields for GPIO P_CTRL */ + +#define _GPIO_P_CTRL_RESETVALUE 0x00000000UL /* Default value for GPIO_P_CTRL */ +#define _GPIO_P_CTRL_MASK 0x00000003UL /* Mask for GPIO_P_CTRL */ + +#define _GPIO_P_CTRL_DRIVEMODE_SHIFT 0 /* Shift value for GPIO_DRIVEMODE */ +#define _GPIO_P_CTRL_DRIVEMODE_MASK 0x3UL /* Bit mask for GPIO_DRIVEMODE */ +#define _GPIO_P_CTRL_DRIVEMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_CTRL */ +#define _GPIO_P_CTRL_DRIVEMODE_STANDARD 0x00000000UL /* Mode STANDARD for GPIO_P_CTRL */ +#define _GPIO_P_CTRL_DRIVEMODE_LOWEST 0x00000001UL /* Mode LOWEST for GPIO_P_CTRL */ +#define _GPIO_P_CTRL_DRIVEMODE_HIGH 0x00000002UL /* Mode HIGH for GPIO_P_CTRL */ +#define _GPIO_P_CTRL_DRIVEMODE_LOW 0x00000003UL /* Mode LOW for GPIO_P_CTRL */ +#define GPIO_P_CTRL_DRIVEMODE_DEFAULT (_GPIO_P_CTRL_DRIVEMODE_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_CTRL */ +#define GPIO_P_CTRL_DRIVEMODE_STANDARD (_GPIO_P_CTRL_DRIVEMODE_STANDARD << 0) /* Shifted mode STANDARD for GPIO_P_CTRL */ +#define GPIO_P_CTRL_DRIVEMODE_LOWEST (_GPIO_P_CTRL_DRIVEMODE_LOWEST << 0) /* Shifted mode LOWEST for GPIO_P_CTRL */ +#define GPIO_P_CTRL_DRIVEMODE_HIGH (_GPIO_P_CTRL_DRIVEMODE_HIGH << 0) /* Shifted mode HIGH for GPIO_P_CTRL */ +#define GPIO_P_CTRL_DRIVEMODE_LOW (_GPIO_P_CTRL_DRIVEMODE_LOW << 0) /* Shifted mode LOW for GPIO_P_CTRL */ + +/* Bit fields for GPIO P_MODEL */ + +#define _GPIO_P_MODEL_RESETVALUE 0x00000000UL /* Default value for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MASK 0xFFFFFFFFUL /* Mask for GPIO_P_MODEL */ + +#define _GPIO_P_MODEL_MODE0_SHIFT 0 /* Shift value for GPIO_MODE0 */ +#define _GPIO_P_MODEL_MODE0_MASK 0xFUL /* Bit mask for GPIO_MODE0 */ +#define _GPIO_P_MODEL_MODE0_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_DEFAULT (_GPIO_P_MODEL_MODE0_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_DISABLED (_GPIO_P_MODEL_MODE0_DISABLED << 0) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_INPUT (_GPIO_P_MODEL_MODE0_INPUT << 0) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_INPUTPULL (_GPIO_P_MODEL_MODE0_INPUTPULL << 0) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_INPUTPULLFILTER (_GPIO_P_MODEL_MODE0_INPUTPULLFILTER << 0) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_PUSHPULL (_GPIO_P_MODEL_MODE0_PUSHPULL << 0) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE0_PUSHPULLDRIVE << 0) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDOR (_GPIO_P_MODEL_MODE0_WIREDOR << 0) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE0_WIREDORPULLDOWN << 0) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDAND (_GPIO_P_MODEL_MODE0_WIREDAND << 0) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDFILTER (_GPIO_P_MODEL_MODE0_WIREDANDFILTER << 0) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDPULLUP (_GPIO_P_MODEL_MODE0_WIREDANDPULLUP << 0) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER << 0) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDDRIVE (_GPIO_P_MODEL_MODE0_WIREDANDDRIVE << 0) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER << 0) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP << 0) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER << 0) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_SHIFT 4 /* Shift value for GPIO_MODE1 */ +#define _GPIO_P_MODEL_MODE1_MASK 0xF0UL /* Bit mask for GPIO_MODE1 */ +#define _GPIO_P_MODEL_MODE1_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_DEFAULT (_GPIO_P_MODEL_MODE1_DEFAULT << 4) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_DISABLED (_GPIO_P_MODEL_MODE1_DISABLED << 4) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_INPUT (_GPIO_P_MODEL_MODE1_INPUT << 4) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_INPUTPULL (_GPIO_P_MODEL_MODE1_INPUTPULL << 4) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_INPUTPULLFILTER (_GPIO_P_MODEL_MODE1_INPUTPULLFILTER << 4) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_PUSHPULL (_GPIO_P_MODEL_MODE1_PUSHPULL << 4) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE1_PUSHPULLDRIVE << 4) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDOR (_GPIO_P_MODEL_MODE1_WIREDOR << 4) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE1_WIREDORPULLDOWN << 4) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDAND (_GPIO_P_MODEL_MODE1_WIREDAND << 4) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDFILTER (_GPIO_P_MODEL_MODE1_WIREDANDFILTER << 4) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDPULLUP (_GPIO_P_MODEL_MODE1_WIREDANDPULLUP << 4) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE1_WIREDANDPULLUPFILTER << 4) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDDRIVE (_GPIO_P_MODEL_MODE1_WIREDANDDRIVE << 4) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE1_WIREDANDDRIVEFILTER << 4) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUP << 4) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE1_WIREDANDDRIVEPULLUPFILTER << 4) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_SHIFT 8 /* Shift value for GPIO_MODE2 */ +#define _GPIO_P_MODEL_MODE2_MASK 0xF00UL /* Bit mask for GPIO_MODE2 */ +#define _GPIO_P_MODEL_MODE2_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_DEFAULT (_GPIO_P_MODEL_MODE2_DEFAULT << 8) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_DISABLED (_GPIO_P_MODEL_MODE2_DISABLED << 8) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_INPUT (_GPIO_P_MODEL_MODE2_INPUT << 8) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_INPUTPULL (_GPIO_P_MODEL_MODE2_INPUTPULL << 8) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_INPUTPULLFILTER (_GPIO_P_MODEL_MODE2_INPUTPULLFILTER << 8) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_PUSHPULL (_GPIO_P_MODEL_MODE2_PUSHPULL << 8) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE2_PUSHPULLDRIVE << 8) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDOR (_GPIO_P_MODEL_MODE2_WIREDOR << 8) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE2_WIREDORPULLDOWN << 8) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDAND (_GPIO_P_MODEL_MODE2_WIREDAND << 8) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDFILTER (_GPIO_P_MODEL_MODE2_WIREDANDFILTER << 8) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDPULLUP (_GPIO_P_MODEL_MODE2_WIREDANDPULLUP << 8) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE2_WIREDANDPULLUPFILTER << 8) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDDRIVE (_GPIO_P_MODEL_MODE2_WIREDANDDRIVE << 8) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE2_WIREDANDDRIVEFILTER << 8) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUP << 8) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE2_WIREDANDDRIVEPULLUPFILTER << 8) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_SHIFT 12 /* Shift value for GPIO_MODE3 */ +#define _GPIO_P_MODEL_MODE3_MASK 0xF000UL /* Bit mask for GPIO_MODE3 */ +#define _GPIO_P_MODEL_MODE3_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_DEFAULT (_GPIO_P_MODEL_MODE3_DEFAULT << 12) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_DISABLED (_GPIO_P_MODEL_MODE3_DISABLED << 12) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_INPUT (_GPIO_P_MODEL_MODE3_INPUT << 12) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_INPUTPULL (_GPIO_P_MODEL_MODE3_INPUTPULL << 12) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_INPUTPULLFILTER (_GPIO_P_MODEL_MODE3_INPUTPULLFILTER << 12) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_PUSHPULL (_GPIO_P_MODEL_MODE3_PUSHPULL << 12) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE3_PUSHPULLDRIVE << 12) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDOR (_GPIO_P_MODEL_MODE3_WIREDOR << 12) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE3_WIREDORPULLDOWN << 12) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDAND (_GPIO_P_MODEL_MODE3_WIREDAND << 12) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDFILTER (_GPIO_P_MODEL_MODE3_WIREDANDFILTER << 12) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDPULLUP (_GPIO_P_MODEL_MODE3_WIREDANDPULLUP << 12) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE3_WIREDANDPULLUPFILTER << 12) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDDRIVE (_GPIO_P_MODEL_MODE3_WIREDANDDRIVE << 12) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE3_WIREDANDDRIVEFILTER << 12) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUP << 12) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE3_WIREDANDDRIVEPULLUPFILTER << 12) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_SHIFT 16 /* Shift value for GPIO_MODE4 */ +#define _GPIO_P_MODEL_MODE4_MASK 0xF0000UL /* Bit mask for GPIO_MODE4 */ +#define _GPIO_P_MODEL_MODE4_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_DEFAULT (_GPIO_P_MODEL_MODE4_DEFAULT << 16) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_DISABLED (_GPIO_P_MODEL_MODE4_DISABLED << 16) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_INPUT (_GPIO_P_MODEL_MODE4_INPUT << 16) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_INPUTPULL (_GPIO_P_MODEL_MODE4_INPUTPULL << 16) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_INPUTPULLFILTER (_GPIO_P_MODEL_MODE4_INPUTPULLFILTER << 16) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_PUSHPULL (_GPIO_P_MODEL_MODE4_PUSHPULL << 16) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE4_PUSHPULLDRIVE << 16) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDOR (_GPIO_P_MODEL_MODE4_WIREDOR << 16) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE4_WIREDORPULLDOWN << 16) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDAND (_GPIO_P_MODEL_MODE4_WIREDAND << 16) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDFILTER (_GPIO_P_MODEL_MODE4_WIREDANDFILTER << 16) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDPULLUP (_GPIO_P_MODEL_MODE4_WIREDANDPULLUP << 16) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE4_WIREDANDPULLUPFILTER << 16) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDDRIVE (_GPIO_P_MODEL_MODE4_WIREDANDDRIVE << 16) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE4_WIREDANDDRIVEFILTER << 16) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUP << 16) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE4_WIREDANDDRIVEPULLUPFILTER << 16) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_SHIFT 20 /* Shift value for GPIO_MODE5 */ +#define _GPIO_P_MODEL_MODE5_MASK 0xF00000UL /* Bit mask for GPIO_MODE5 */ +#define _GPIO_P_MODEL_MODE5_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_DEFAULT (_GPIO_P_MODEL_MODE5_DEFAULT << 20) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_DISABLED (_GPIO_P_MODEL_MODE5_DISABLED << 20) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_INPUT (_GPIO_P_MODEL_MODE5_INPUT << 20) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_INPUTPULL (_GPIO_P_MODEL_MODE5_INPUTPULL << 20) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_INPUTPULLFILTER (_GPIO_P_MODEL_MODE5_INPUTPULLFILTER << 20) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_PUSHPULL (_GPIO_P_MODEL_MODE5_PUSHPULL << 20) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE5_PUSHPULLDRIVE << 20) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDOR (_GPIO_P_MODEL_MODE5_WIREDOR << 20) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE5_WIREDORPULLDOWN << 20) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDAND (_GPIO_P_MODEL_MODE5_WIREDAND << 20) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDFILTER (_GPIO_P_MODEL_MODE5_WIREDANDFILTER << 20) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDPULLUP (_GPIO_P_MODEL_MODE5_WIREDANDPULLUP << 20) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE5_WIREDANDPULLUPFILTER << 20) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDDRIVE (_GPIO_P_MODEL_MODE5_WIREDANDDRIVE << 20) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE5_WIREDANDDRIVEFILTER << 20) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUP << 20) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE5_WIREDANDDRIVEPULLUPFILTER << 20) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_SHIFT 24 /* Shift value for GPIO_MODE6 */ +#define _GPIO_P_MODEL_MODE6_MASK 0xF000000UL /* Bit mask for GPIO_MODE6 */ +#define _GPIO_P_MODEL_MODE6_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_DEFAULT (_GPIO_P_MODEL_MODE6_DEFAULT << 24) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_DISABLED (_GPIO_P_MODEL_MODE6_DISABLED << 24) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_INPUT (_GPIO_P_MODEL_MODE6_INPUT << 24) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_INPUTPULL (_GPIO_P_MODEL_MODE6_INPUTPULL << 24) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_INPUTPULLFILTER (_GPIO_P_MODEL_MODE6_INPUTPULLFILTER << 24) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_PUSHPULL (_GPIO_P_MODEL_MODE6_PUSHPULL << 24) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE6_PUSHPULLDRIVE << 24) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDOR (_GPIO_P_MODEL_MODE6_WIREDOR << 24) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE6_WIREDORPULLDOWN << 24) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDAND (_GPIO_P_MODEL_MODE6_WIREDAND << 24) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDFILTER (_GPIO_P_MODEL_MODE6_WIREDANDFILTER << 24) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDPULLUP (_GPIO_P_MODEL_MODE6_WIREDANDPULLUP << 24) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE6_WIREDANDPULLUPFILTER << 24) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDDRIVE (_GPIO_P_MODEL_MODE6_WIREDANDDRIVE << 24) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE6_WIREDANDDRIVEFILTER << 24) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUP << 24) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE6_WIREDANDDRIVEPULLUPFILTER << 24) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_SHIFT 28 /* Shift value for GPIO_MODE7 */ +#define _GPIO_P_MODEL_MODE7_MASK 0xF0000000UL /* Bit mask for GPIO_MODE7 */ +#define _GPIO_P_MODEL_MODE7_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define _GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_DEFAULT (_GPIO_P_MODEL_MODE7_DEFAULT << 28) /* Shifted mode DEFAULT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_DISABLED (_GPIO_P_MODEL_MODE7_DISABLED << 28) /* Shifted mode DISABLED for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_INPUT (_GPIO_P_MODEL_MODE7_INPUT << 28) /* Shifted mode INPUT for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_INPUTPULL (_GPIO_P_MODEL_MODE7_INPUTPULL << 28) /* Shifted mode INPUTPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_INPUTPULLFILTER (_GPIO_P_MODEL_MODE7_INPUTPULLFILTER << 28) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_PUSHPULL (_GPIO_P_MODEL_MODE7_PUSHPULL << 28) /* Shifted mode PUSHPULL for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_PUSHPULLDRIVE (_GPIO_P_MODEL_MODE7_PUSHPULLDRIVE << 28) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDOR (_GPIO_P_MODEL_MODE7_WIREDOR << 28) /* Shifted mode WIREDOR for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDORPULLDOWN (_GPIO_P_MODEL_MODE7_WIREDORPULLDOWN << 28) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDAND (_GPIO_P_MODEL_MODE7_WIREDAND << 28) /* Shifted mode WIREDAND for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDFILTER (_GPIO_P_MODEL_MODE7_WIREDANDFILTER << 28) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDPULLUP (_GPIO_P_MODEL_MODE7_WIREDANDPULLUP << 28) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDPULLUPFILTER (_GPIO_P_MODEL_MODE7_WIREDANDPULLUPFILTER << 28) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDDRIVE (_GPIO_P_MODEL_MODE7_WIREDANDDRIVE << 28) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDDRIVEFILTER (_GPIO_P_MODEL_MODE7_WIREDANDDRIVEFILTER << 28) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUP (_GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUP << 28) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEL */ +#define GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEL_MODE7_WIREDANDDRIVEPULLUPFILTER << 28) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEL */ + +/* Bit fields for GPIO P_MODEH */ + +#define _GPIO_P_MODEH_RESETVALUE 0x00000000UL /* Default value for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MASK 0xFFFFFFFFUL /* Mask for GPIO_P_MODEH */ + +#define _GPIO_P_MODEH_MODE8_SHIFT 0 /* Shift value for GPIO_MODE8 */ +#define _GPIO_P_MODEH_MODE8_MASK 0xFUL /* Bit mask for GPIO_MODE8 */ +#define _GPIO_P_MODEH_MODE8_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_DEFAULT (_GPIO_P_MODEH_MODE8_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_DISABLED (_GPIO_P_MODEH_MODE8_DISABLED << 0) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_INPUT (_GPIO_P_MODEH_MODE8_INPUT << 0) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_INPUTPULL (_GPIO_P_MODEH_MODE8_INPUTPULL << 0) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_INPUTPULLFILTER (_GPIO_P_MODEH_MODE8_INPUTPULLFILTER << 0) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_PUSHPULL (_GPIO_P_MODEH_MODE8_PUSHPULL << 0) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE8_PUSHPULLDRIVE << 0) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDOR (_GPIO_P_MODEH_MODE8_WIREDOR << 0) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE8_WIREDORPULLDOWN << 0) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDAND (_GPIO_P_MODEH_MODE8_WIREDAND << 0) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDFILTER (_GPIO_P_MODEH_MODE8_WIREDANDFILTER << 0) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDPULLUP (_GPIO_P_MODEH_MODE8_WIREDANDPULLUP << 0) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE8_WIREDANDPULLUPFILTER << 0) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDDRIVE (_GPIO_P_MODEH_MODE8_WIREDANDDRIVE << 0) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE8_WIREDANDDRIVEFILTER << 0) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUP << 0) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE8_WIREDANDDRIVEPULLUPFILTER << 0) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_SHIFT 4 /* Shift value for GPIO_MODE9 */ +#define _GPIO_P_MODEH_MODE9_MASK 0xF0UL /* Bit mask for GPIO_MODE9 */ +#define _GPIO_P_MODEH_MODE9_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_DEFAULT (_GPIO_P_MODEH_MODE9_DEFAULT << 4) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_DISABLED (_GPIO_P_MODEH_MODE9_DISABLED << 4) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_INPUT (_GPIO_P_MODEH_MODE9_INPUT << 4) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_INPUTPULL (_GPIO_P_MODEH_MODE9_INPUTPULL << 4) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_INPUTPULLFILTER (_GPIO_P_MODEH_MODE9_INPUTPULLFILTER << 4) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_PUSHPULL (_GPIO_P_MODEH_MODE9_PUSHPULL << 4) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE9_PUSHPULLDRIVE << 4) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDOR (_GPIO_P_MODEH_MODE9_WIREDOR << 4) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE9_WIREDORPULLDOWN << 4) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDAND (_GPIO_P_MODEH_MODE9_WIREDAND << 4) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDFILTER (_GPIO_P_MODEH_MODE9_WIREDANDFILTER << 4) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDPULLUP (_GPIO_P_MODEH_MODE9_WIREDANDPULLUP << 4) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE9_WIREDANDPULLUPFILTER << 4) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDDRIVE (_GPIO_P_MODEH_MODE9_WIREDANDDRIVE << 4) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE9_WIREDANDDRIVEFILTER << 4) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUP << 4) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE9_WIREDANDDRIVEPULLUPFILTER << 4) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_SHIFT 8 /* Shift value for GPIO_MODE10 */ +#define _GPIO_P_MODEH_MODE10_MASK 0xF00UL /* Bit mask for GPIO_MODE10 */ +#define _GPIO_P_MODEH_MODE10_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_DEFAULT (_GPIO_P_MODEH_MODE10_DEFAULT << 8) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_DISABLED (_GPIO_P_MODEH_MODE10_DISABLED << 8) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_INPUT (_GPIO_P_MODEH_MODE10_INPUT << 8) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_INPUTPULL (_GPIO_P_MODEH_MODE10_INPUTPULL << 8) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_INPUTPULLFILTER (_GPIO_P_MODEH_MODE10_INPUTPULLFILTER << 8) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_PUSHPULL (_GPIO_P_MODEH_MODE10_PUSHPULL << 8) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE10_PUSHPULLDRIVE << 8) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDOR (_GPIO_P_MODEH_MODE10_WIREDOR << 8) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE10_WIREDORPULLDOWN << 8) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDAND (_GPIO_P_MODEH_MODE10_WIREDAND << 8) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDFILTER (_GPIO_P_MODEH_MODE10_WIREDANDFILTER << 8) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDPULLUP (_GPIO_P_MODEH_MODE10_WIREDANDPULLUP << 8) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE10_WIREDANDPULLUPFILTER << 8) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDDRIVE (_GPIO_P_MODEH_MODE10_WIREDANDDRIVE << 8) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE10_WIREDANDDRIVEFILTER << 8) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUP << 8) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE10_WIREDANDDRIVEPULLUPFILTER << 8) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_SHIFT 12 /* Shift value for GPIO_MODE11 */ +#define _GPIO_P_MODEH_MODE11_MASK 0xF000UL /* Bit mask for GPIO_MODE11 */ +#define _GPIO_P_MODEH_MODE11_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_DEFAULT (_GPIO_P_MODEH_MODE11_DEFAULT << 12) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_DISABLED (_GPIO_P_MODEH_MODE11_DISABLED << 12) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_INPUT (_GPIO_P_MODEH_MODE11_INPUT << 12) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_INPUTPULL (_GPIO_P_MODEH_MODE11_INPUTPULL << 12) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_INPUTPULLFILTER (_GPIO_P_MODEH_MODE11_INPUTPULLFILTER << 12) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_PUSHPULL (_GPIO_P_MODEH_MODE11_PUSHPULL << 12) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE11_PUSHPULLDRIVE << 12) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDOR (_GPIO_P_MODEH_MODE11_WIREDOR << 12) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE11_WIREDORPULLDOWN << 12) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDAND (_GPIO_P_MODEH_MODE11_WIREDAND << 12) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDFILTER (_GPIO_P_MODEH_MODE11_WIREDANDFILTER << 12) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDPULLUP (_GPIO_P_MODEH_MODE11_WIREDANDPULLUP << 12) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE11_WIREDANDPULLUPFILTER << 12) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDDRIVE (_GPIO_P_MODEH_MODE11_WIREDANDDRIVE << 12) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE11_WIREDANDDRIVEFILTER << 12) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUP << 12) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE11_WIREDANDDRIVEPULLUPFILTER << 12) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_SHIFT 16 /* Shift value for GPIO_MODE12 */ +#define _GPIO_P_MODEH_MODE12_MASK 0xF0000UL /* Bit mask for GPIO_MODE12 */ +#define _GPIO_P_MODEH_MODE12_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_DEFAULT (_GPIO_P_MODEH_MODE12_DEFAULT << 16) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_DISABLED (_GPIO_P_MODEH_MODE12_DISABLED << 16) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_INPUT (_GPIO_P_MODEH_MODE12_INPUT << 16) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_INPUTPULL (_GPIO_P_MODEH_MODE12_INPUTPULL << 16) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_INPUTPULLFILTER (_GPIO_P_MODEH_MODE12_INPUTPULLFILTER << 16) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_PUSHPULL (_GPIO_P_MODEH_MODE12_PUSHPULL << 16) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE12_PUSHPULLDRIVE << 16) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDOR (_GPIO_P_MODEH_MODE12_WIREDOR << 16) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE12_WIREDORPULLDOWN << 16) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDAND (_GPIO_P_MODEH_MODE12_WIREDAND << 16) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDFILTER (_GPIO_P_MODEH_MODE12_WIREDANDFILTER << 16) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDPULLUP (_GPIO_P_MODEH_MODE12_WIREDANDPULLUP << 16) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE12_WIREDANDPULLUPFILTER << 16) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDDRIVE (_GPIO_P_MODEH_MODE12_WIREDANDDRIVE << 16) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE12_WIREDANDDRIVEFILTER << 16) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUP << 16) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE12_WIREDANDDRIVEPULLUPFILTER << 16) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_SHIFT 20 /* Shift value for GPIO_MODE13 */ +#define _GPIO_P_MODEH_MODE13_MASK 0xF00000UL /* Bit mask for GPIO_MODE13 */ +#define _GPIO_P_MODEH_MODE13_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_DEFAULT (_GPIO_P_MODEH_MODE13_DEFAULT << 20) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_DISABLED (_GPIO_P_MODEH_MODE13_DISABLED << 20) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_INPUT (_GPIO_P_MODEH_MODE13_INPUT << 20) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_INPUTPULL (_GPIO_P_MODEH_MODE13_INPUTPULL << 20) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_INPUTPULLFILTER (_GPIO_P_MODEH_MODE13_INPUTPULLFILTER << 20) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_PUSHPULL (_GPIO_P_MODEH_MODE13_PUSHPULL << 20) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE13_PUSHPULLDRIVE << 20) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDOR (_GPIO_P_MODEH_MODE13_WIREDOR << 20) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE13_WIREDORPULLDOWN << 20) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDAND (_GPIO_P_MODEH_MODE13_WIREDAND << 20) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDFILTER (_GPIO_P_MODEH_MODE13_WIREDANDFILTER << 20) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDPULLUP (_GPIO_P_MODEH_MODE13_WIREDANDPULLUP << 20) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE13_WIREDANDPULLUPFILTER << 20) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDDRIVE (_GPIO_P_MODEH_MODE13_WIREDANDDRIVE << 20) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE13_WIREDANDDRIVEFILTER << 20) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUP << 20) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE13_WIREDANDDRIVEPULLUPFILTER << 20) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_SHIFT 24 /* Shift value for GPIO_MODE14 */ +#define _GPIO_P_MODEH_MODE14_MASK 0xF000000UL /* Bit mask for GPIO_MODE14 */ +#define _GPIO_P_MODEH_MODE14_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_DEFAULT (_GPIO_P_MODEH_MODE14_DEFAULT << 24) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_DISABLED (_GPIO_P_MODEH_MODE14_DISABLED << 24) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_INPUT (_GPIO_P_MODEH_MODE14_INPUT << 24) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_INPUTPULL (_GPIO_P_MODEH_MODE14_INPUTPULL << 24) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_INPUTPULLFILTER (_GPIO_P_MODEH_MODE14_INPUTPULLFILTER << 24) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_PUSHPULL (_GPIO_P_MODEH_MODE14_PUSHPULL << 24) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE14_PUSHPULLDRIVE << 24) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDOR (_GPIO_P_MODEH_MODE14_WIREDOR << 24) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE14_WIREDORPULLDOWN << 24) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDAND (_GPIO_P_MODEH_MODE14_WIREDAND << 24) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDFILTER (_GPIO_P_MODEH_MODE14_WIREDANDFILTER << 24) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDPULLUP (_GPIO_P_MODEH_MODE14_WIREDANDPULLUP << 24) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE14_WIREDANDPULLUPFILTER << 24) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDDRIVE (_GPIO_P_MODEH_MODE14_WIREDANDDRIVE << 24) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE14_WIREDANDDRIVEFILTER << 24) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUP << 24) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE14_WIREDANDDRIVEPULLUPFILTER << 24) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_SHIFT 28 /* Shift value for GPIO_MODE15 */ +#define _GPIO_P_MODEH_MODE15_MASK 0xF0000000UL /* Bit mask for GPIO_MODE15 */ +#define _GPIO_P_MODEH_MODE15_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_DISABLED 0x00000000UL /* Mode DISABLED for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_INPUT 0x00000001UL /* Mode INPUT for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_INPUTPULL 0x00000002UL /* Mode INPUTPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_INPUTPULLFILTER 0x00000003UL /* Mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_PUSHPULL 0x00000004UL /* Mode PUSHPULL for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_PUSHPULLDRIVE 0x00000005UL /* Mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDOR 0x00000006UL /* Mode WIREDOR for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDORPULLDOWN 0x00000007UL /* Mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDAND 0x00000008UL /* Mode WIREDAND for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDFILTER 0x00000009UL /* Mode WIREDANDFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDPULLUP 0x0000000AUL /* Mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDPULLUPFILTER 0x0000000BUL /* Mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDDRIVE 0x0000000CUL /* Mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDDRIVEFILTER 0x0000000DUL /* Mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUP 0x0000000EUL /* Mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define _GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUPFILTER 0x0000000FUL /* Mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_DEFAULT (_GPIO_P_MODEH_MODE15_DEFAULT << 28) /* Shifted mode DEFAULT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_DISABLED (_GPIO_P_MODEH_MODE15_DISABLED << 28) /* Shifted mode DISABLED for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_INPUT (_GPIO_P_MODEH_MODE15_INPUT << 28) /* Shifted mode INPUT for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_INPUTPULL (_GPIO_P_MODEH_MODE15_INPUTPULL << 28) /* Shifted mode INPUTPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_INPUTPULLFILTER (_GPIO_P_MODEH_MODE15_INPUTPULLFILTER << 28) /* Shifted mode INPUTPULLFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_PUSHPULL (_GPIO_P_MODEH_MODE15_PUSHPULL << 28) /* Shifted mode PUSHPULL for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_PUSHPULLDRIVE (_GPIO_P_MODEH_MODE15_PUSHPULLDRIVE << 28) /* Shifted mode PUSHPULLDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDOR (_GPIO_P_MODEH_MODE15_WIREDOR << 28) /* Shifted mode WIREDOR for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDORPULLDOWN (_GPIO_P_MODEH_MODE15_WIREDORPULLDOWN << 28) /* Shifted mode WIREDORPULLDOWN for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDAND (_GPIO_P_MODEH_MODE15_WIREDAND << 28) /* Shifted mode WIREDAND for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDFILTER (_GPIO_P_MODEH_MODE15_WIREDANDFILTER << 28) /* Shifted mode WIREDANDFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDPULLUP (_GPIO_P_MODEH_MODE15_WIREDANDPULLUP << 28) /* Shifted mode WIREDANDPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDPULLUPFILTER (_GPIO_P_MODEH_MODE15_WIREDANDPULLUPFILTER << 28) /* Shifted mode WIREDANDPULLUPFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDDRIVE (_GPIO_P_MODEH_MODE15_WIREDANDDRIVE << 28) /* Shifted mode WIREDANDDRIVE for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDDRIVEFILTER (_GPIO_P_MODEH_MODE15_WIREDANDDRIVEFILTER << 28) /* Shifted mode WIREDANDDRIVEFILTER for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUP (_GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUP << 28) /* Shifted mode WIREDANDDRIVEPULLUP for GPIO_P_MODEH */ +#define GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUPFILTER (_GPIO_P_MODEH_MODE15_WIREDANDDRIVEPULLUPFILTER << 28) /* Shifted mode WIREDANDDRIVEPULLUPFILTER for GPIO_P_MODEH */ + +/* Bit fields for GPIO P_DOUT */ + +#define _GPIO_P_DOUT_RESETVALUE 0x00000000UL /* Default value for GPIO_P_DOUT */ +#define _GPIO_P_DOUT_MASK 0x0000FFFFUL /* Mask for GPIO_P_DOUT */ + +#define _GPIO_P_DOUT_DOUT_SHIFT 0 /* Shift value for GPIO_DOUT */ +#define _GPIO_P_DOUT_DOUT_MASK 0xFFFFUL /* Bit mask for GPIO_DOUT */ +#define _GPIO_P_DOUT_DOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_DOUT */ +#define GPIO_P_DOUT_DOUT_DEFAULT (_GPIO_P_DOUT_DOUT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_DOUT */ + +/* Bit fields for GPIO P_DOUTSET */ + +#define _GPIO_P_DOUTSET_RESETVALUE 0x00000000UL /* Default value for GPIO_P_DOUTSET */ +#define _GPIO_P_DOUTSET_MASK 0x0000FFFFUL /* Mask for GPIO_P_DOUTSET */ + +#define _GPIO_P_DOUTSET_DOUTSET_SHIFT 0 /* Shift value for GPIO_DOUTSET */ +#define _GPIO_P_DOUTSET_DOUTSET_MASK 0xFFFFUL /* Bit mask for GPIO_DOUTSET */ +#define _GPIO_P_DOUTSET_DOUTSET_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_DOUTSET */ +#define GPIO_P_DOUTSET_DOUTSET_DEFAULT (_GPIO_P_DOUTSET_DOUTSET_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_DOUTSET */ + +/* Bit fields for GPIO P_DOUTCLR */ + +#define _GPIO_P_DOUTCLR_RESETVALUE 0x00000000UL /* Default value for GPIO_P_DOUTCLR */ +#define _GPIO_P_DOUTCLR_MASK 0x0000FFFFUL /* Mask for GPIO_P_DOUTCLR */ + +#define _GPIO_P_DOUTCLR_DOUTCLR_SHIFT 0 /* Shift value for GPIO_DOUTCLR */ +#define _GPIO_P_DOUTCLR_DOUTCLR_MASK 0xFFFFUL /* Bit mask for GPIO_DOUTCLR */ +#define _GPIO_P_DOUTCLR_DOUTCLR_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_DOUTCLR */ +#define GPIO_P_DOUTCLR_DOUTCLR_DEFAULT (_GPIO_P_DOUTCLR_DOUTCLR_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_DOUTCLR */ + +/* Bit fields for GPIO P_DOUTTGL */ + +#define _GPIO_P_DOUTTGL_RESETVALUE 0x00000000UL /* Default value for GPIO_P_DOUTTGL */ +#define _GPIO_P_DOUTTGL_MASK 0x0000FFFFUL /* Mask for GPIO_P_DOUTTGL */ + +#define _GPIO_P_DOUTTGL_DOUTTGL_SHIFT 0 /* Shift value for GPIO_DOUTTGL */ +#define _GPIO_P_DOUTTGL_DOUTTGL_MASK 0xFFFFUL /* Bit mask for GPIO_DOUTTGL */ +#define _GPIO_P_DOUTTGL_DOUTTGL_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_DOUTTGL */ +#define GPIO_P_DOUTTGL_DOUTTGL_DEFAULT (_GPIO_P_DOUTTGL_DOUTTGL_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_DOUTTGL */ + +/* Bit fields for GPIO P_DIN */ + +#define _GPIO_P_DIN_RESETVALUE 0x00000000UL /* Default value for GPIO_P_DIN */ +#define _GPIO_P_DIN_MASK 0x0000FFFFUL /* Mask for GPIO_P_DIN */ + +#define _GPIO_P_DIN_DIN_SHIFT 0 /* Shift value for GPIO_DIN */ +#define _GPIO_P_DIN_DIN_MASK 0xFFFFUL /* Bit mask for GPIO_DIN */ +#define _GPIO_P_DIN_DIN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_P_DIN */ +#define GPIO_P_DIN_DIN_DEFAULT (_GPIO_P_DIN_DIN_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_DIN */ + +/* Bit fields for GPIO P_PINLOCKN */ + +#define _GPIO_P_PINLOCKN_RESETVALUE 0x0000FFFFUL /* Default value for GPIO_P_PINLOCKN */ +#define _GPIO_P_PINLOCKN_MASK 0x0000FFFFUL /* Mask for GPIO_P_PINLOCKN */ + +#define _GPIO_P_PINLOCKN_PINLOCKN_SHIFT 0 /* Shift value for GPIO_PINLOCKN */ +#define _GPIO_P_PINLOCKN_PINLOCKN_MASK 0xFFFFUL /* Bit mask for GPIO_PINLOCKN */ +#define _GPIO_P_PINLOCKN_PINLOCKN_DEFAULT 0x0000FFFFUL /* Mode DEFAULT for GPIO_P_PINLOCKN */ +#define GPIO_P_PINLOCKN_PINLOCKN_DEFAULT (_GPIO_P_PINLOCKN_PINLOCKN_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_P_PINLOCKN */ + +/* Bit fields for GPIO EXTIPSELL */ + +#define _GPIO_EXTIPSELL_RESETVALUE 0x00000000UL /* Default value for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_MASK 0x77777777UL /* Mask for GPIO_EXTIPSELL */ + +#define _GPIO_EXTIPSELL_EXTIPSEL0_SHIFT 0 /* Shift value for GPIO_EXTIPSEL0 */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_MASK 0x7UL /* Bit mask for GPIO_EXTIPSEL0 */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL0_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL0_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTA (_GPIO_EXTIPSELL_EXTIPSEL0_PORTA << 0) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTB (_GPIO_EXTIPSELL_EXTIPSEL0_PORTB << 0) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTC (_GPIO_EXTIPSELL_EXTIPSEL0_PORTC << 0) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTD (_GPIO_EXTIPSELL_EXTIPSEL0_PORTD << 0) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTE (_GPIO_EXTIPSELL_EXTIPSEL0_PORTE << 0) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL0_PORTF (_GPIO_EXTIPSELL_EXTIPSEL0_PORTF << 0) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_SHIFT 4 /* Shift value for GPIO_EXTIPSEL1 */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_MASK 0x70UL /* Bit mask for GPIO_EXTIPSEL1 */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL1_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL1_DEFAULT << 4) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTA (_GPIO_EXTIPSELL_EXTIPSEL1_PORTA << 4) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTB (_GPIO_EXTIPSELL_EXTIPSEL1_PORTB << 4) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTC (_GPIO_EXTIPSELL_EXTIPSEL1_PORTC << 4) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTD (_GPIO_EXTIPSELL_EXTIPSEL1_PORTD << 4) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTE (_GPIO_EXTIPSELL_EXTIPSEL1_PORTE << 4) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL1_PORTF (_GPIO_EXTIPSELL_EXTIPSEL1_PORTF << 4) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_SHIFT 8 /* Shift value for GPIO_EXTIPSEL2 */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_MASK 0x700UL /* Bit mask for GPIO_EXTIPSEL2 */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL2_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL2_DEFAULT << 8) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTA (_GPIO_EXTIPSELL_EXTIPSEL2_PORTA << 8) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTB (_GPIO_EXTIPSELL_EXTIPSEL2_PORTB << 8) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTC (_GPIO_EXTIPSELL_EXTIPSEL2_PORTC << 8) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTD (_GPIO_EXTIPSELL_EXTIPSEL2_PORTD << 8) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTE (_GPIO_EXTIPSELL_EXTIPSEL2_PORTE << 8) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL2_PORTF (_GPIO_EXTIPSELL_EXTIPSEL2_PORTF << 8) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_SHIFT 12 /* Shift value for GPIO_EXTIPSEL3 */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_MASK 0x7000UL /* Bit mask for GPIO_EXTIPSEL3 */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL3_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL3_DEFAULT << 12) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTA (_GPIO_EXTIPSELL_EXTIPSEL3_PORTA << 12) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTB (_GPIO_EXTIPSELL_EXTIPSEL3_PORTB << 12) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTC (_GPIO_EXTIPSELL_EXTIPSEL3_PORTC << 12) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTD (_GPIO_EXTIPSELL_EXTIPSEL3_PORTD << 12) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTE (_GPIO_EXTIPSELL_EXTIPSEL3_PORTE << 12) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL3_PORTF (_GPIO_EXTIPSELL_EXTIPSEL3_PORTF << 12) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_SHIFT 16 /* Shift value for GPIO_EXTIPSEL4 */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_MASK 0x70000UL /* Bit mask for GPIO_EXTIPSEL4 */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL4_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL4_DEFAULT << 16) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTA (_GPIO_EXTIPSELL_EXTIPSEL4_PORTA << 16) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTB (_GPIO_EXTIPSELL_EXTIPSEL4_PORTB << 16) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTC (_GPIO_EXTIPSELL_EXTIPSEL4_PORTC << 16) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTD (_GPIO_EXTIPSELL_EXTIPSEL4_PORTD << 16) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTE (_GPIO_EXTIPSELL_EXTIPSEL4_PORTE << 16) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL4_PORTF (_GPIO_EXTIPSELL_EXTIPSEL4_PORTF << 16) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_SHIFT 20 /* Shift value for GPIO_EXTIPSEL5 */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_MASK 0x700000UL /* Bit mask for GPIO_EXTIPSEL5 */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL5_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL5_DEFAULT << 20) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTA (_GPIO_EXTIPSELL_EXTIPSEL5_PORTA << 20) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTB (_GPIO_EXTIPSELL_EXTIPSEL5_PORTB << 20) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTC (_GPIO_EXTIPSELL_EXTIPSEL5_PORTC << 20) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTD (_GPIO_EXTIPSELL_EXTIPSEL5_PORTD << 20) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTE (_GPIO_EXTIPSELL_EXTIPSEL5_PORTE << 20) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL5_PORTF (_GPIO_EXTIPSELL_EXTIPSEL5_PORTF << 20) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_SHIFT 24 /* Shift value for GPIO_EXTIPSEL6 */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_MASK 0x7000000UL /* Bit mask for GPIO_EXTIPSEL6 */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL6_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL6_DEFAULT << 24) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTA (_GPIO_EXTIPSELL_EXTIPSEL6_PORTA << 24) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTB (_GPIO_EXTIPSELL_EXTIPSEL6_PORTB << 24) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTC (_GPIO_EXTIPSELL_EXTIPSEL6_PORTC << 24) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTD (_GPIO_EXTIPSELL_EXTIPSEL6_PORTD << 24) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTE (_GPIO_EXTIPSELL_EXTIPSEL6_PORTE << 24) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL6_PORTF (_GPIO_EXTIPSELL_EXTIPSEL6_PORTF << 24) /* Shifted mode PORTF for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_SHIFT 28 /* Shift value for GPIO_EXTIPSEL7 */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_MASK 0x70000000UL /* Bit mask for GPIO_EXTIPSEL7 */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELL */ +#define _GPIO_EXTIPSELL_EXTIPSEL7_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_DEFAULT (_GPIO_EXTIPSELL_EXTIPSEL7_DEFAULT << 28) /* Shifted mode DEFAULT for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTA (_GPIO_EXTIPSELL_EXTIPSEL7_PORTA << 28) /* Shifted mode PORTA for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTB (_GPIO_EXTIPSELL_EXTIPSEL7_PORTB << 28) /* Shifted mode PORTB for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTC (_GPIO_EXTIPSELL_EXTIPSEL7_PORTC << 28) /* Shifted mode PORTC for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTD (_GPIO_EXTIPSELL_EXTIPSEL7_PORTD << 28) /* Shifted mode PORTD for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTE (_GPIO_EXTIPSELL_EXTIPSEL7_PORTE << 28) /* Shifted mode PORTE for GPIO_EXTIPSELL */ +#define GPIO_EXTIPSELL_EXTIPSEL7_PORTF (_GPIO_EXTIPSELL_EXTIPSEL7_PORTF << 28) /* Shifted mode PORTF for GPIO_EXTIPSELL */ + +/* Bit fields for GPIO EXTIPSELH */ + +#define _GPIO_EXTIPSELH_RESETVALUE 0x00000000UL /* Default value for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_MASK 0x77777777UL /* Mask for GPIO_EXTIPSELH */ + +#define _GPIO_EXTIPSELH_EXTIPSEL8_SHIFT 0 /* Shift value for GPIO_EXTIPSEL8 */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_MASK 0x7UL /* Bit mask for GPIO_EXTIPSEL8 */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL8_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL8_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTA (_GPIO_EXTIPSELH_EXTIPSEL8_PORTA << 0) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTB (_GPIO_EXTIPSELH_EXTIPSEL8_PORTB << 0) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTC (_GPIO_EXTIPSELH_EXTIPSEL8_PORTC << 0) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTD (_GPIO_EXTIPSELH_EXTIPSEL8_PORTD << 0) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTE (_GPIO_EXTIPSELH_EXTIPSEL8_PORTE << 0) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL8_PORTF (_GPIO_EXTIPSELH_EXTIPSEL8_PORTF << 0) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_SHIFT 4 /* Shift value for GPIO_EXTIPSEL9 */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_MASK 0x70UL /* Bit mask for GPIO_EXTIPSEL9 */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL9_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL9_DEFAULT << 4) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTA (_GPIO_EXTIPSELH_EXTIPSEL9_PORTA << 4) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTB (_GPIO_EXTIPSELH_EXTIPSEL9_PORTB << 4) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTC (_GPIO_EXTIPSELH_EXTIPSEL9_PORTC << 4) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTD (_GPIO_EXTIPSELH_EXTIPSEL9_PORTD << 4) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTE (_GPIO_EXTIPSELH_EXTIPSEL9_PORTE << 4) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL9_PORTF (_GPIO_EXTIPSELH_EXTIPSEL9_PORTF << 4) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_SHIFT 8 /* Shift value for GPIO_EXTIPSEL10 */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_MASK 0x700UL /* Bit mask for GPIO_EXTIPSEL10 */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL10_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL10_DEFAULT << 8) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTA (_GPIO_EXTIPSELH_EXTIPSEL10_PORTA << 8) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTB (_GPIO_EXTIPSELH_EXTIPSEL10_PORTB << 8) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTC (_GPIO_EXTIPSELH_EXTIPSEL10_PORTC << 8) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTD (_GPIO_EXTIPSELH_EXTIPSEL10_PORTD << 8) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTE (_GPIO_EXTIPSELH_EXTIPSEL10_PORTE << 8) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL10_PORTF (_GPIO_EXTIPSELH_EXTIPSEL10_PORTF << 8) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_SHIFT 12 /* Shift value for GPIO_EXTIPSEL11 */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_MASK 0x7000UL /* Bit mask for GPIO_EXTIPSEL11 */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL11_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL11_DEFAULT << 12) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTA (_GPIO_EXTIPSELH_EXTIPSEL11_PORTA << 12) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTB (_GPIO_EXTIPSELH_EXTIPSEL11_PORTB << 12) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTC (_GPIO_EXTIPSELH_EXTIPSEL11_PORTC << 12) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTD (_GPIO_EXTIPSELH_EXTIPSEL11_PORTD << 12) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTE (_GPIO_EXTIPSELH_EXTIPSEL11_PORTE << 12) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL11_PORTF (_GPIO_EXTIPSELH_EXTIPSEL11_PORTF << 12) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_SHIFT 16 /* Shift value for GPIO_EXTIPSEL12 */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_MASK 0x70000UL /* Bit mask for GPIO_EXTIPSEL12 */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL12_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL12_DEFAULT << 16) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTA (_GPIO_EXTIPSELH_EXTIPSEL12_PORTA << 16) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTB (_GPIO_EXTIPSELH_EXTIPSEL12_PORTB << 16) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTC (_GPIO_EXTIPSELH_EXTIPSEL12_PORTC << 16) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTD (_GPIO_EXTIPSELH_EXTIPSEL12_PORTD << 16) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTE (_GPIO_EXTIPSELH_EXTIPSEL12_PORTE << 16) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL12_PORTF (_GPIO_EXTIPSELH_EXTIPSEL12_PORTF << 16) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_SHIFT 20 /* Shift value for GPIO_EXTIPSEL13 */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_MASK 0x700000UL /* Bit mask for GPIO_EXTIPSEL13 */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL13_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL13_DEFAULT << 20) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTA (_GPIO_EXTIPSELH_EXTIPSEL13_PORTA << 20) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTB (_GPIO_EXTIPSELH_EXTIPSEL13_PORTB << 20) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTC (_GPIO_EXTIPSELH_EXTIPSEL13_PORTC << 20) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTD (_GPIO_EXTIPSELH_EXTIPSEL13_PORTD << 20) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTE (_GPIO_EXTIPSELH_EXTIPSEL13_PORTE << 20) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL13_PORTF (_GPIO_EXTIPSELH_EXTIPSEL13_PORTF << 20) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_SHIFT 24 /* Shift value for GPIO_EXTIPSEL14 */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_MASK 0x7000000UL /* Bit mask for GPIO_EXTIPSEL14 */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL14_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL14_DEFAULT << 24) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTA (_GPIO_EXTIPSELH_EXTIPSEL14_PORTA << 24) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTB (_GPIO_EXTIPSELH_EXTIPSEL14_PORTB << 24) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTC (_GPIO_EXTIPSELH_EXTIPSEL14_PORTC << 24) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTD (_GPIO_EXTIPSELH_EXTIPSEL14_PORTD << 24) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTE (_GPIO_EXTIPSELH_EXTIPSEL14_PORTE << 24) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL14_PORTF (_GPIO_EXTIPSELH_EXTIPSEL14_PORTF << 24) /* Shifted mode PORTF for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_SHIFT 28 /* Shift value for GPIO_EXTIPSEL15 */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_MASK 0x70000000UL /* Bit mask for GPIO_EXTIPSEL15 */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTA 0x00000000UL /* Mode PORTA for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTB 0x00000001UL /* Mode PORTB for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTC 0x00000002UL /* Mode PORTC for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTD 0x00000003UL /* Mode PORTD for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTE 0x00000004UL /* Mode PORTE for GPIO_EXTIPSELH */ +#define _GPIO_EXTIPSELH_EXTIPSEL15_PORTF 0x00000005UL /* Mode PORTF for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_DEFAULT (_GPIO_EXTIPSELH_EXTIPSEL15_DEFAULT << 28) /* Shifted mode DEFAULT for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTA (_GPIO_EXTIPSELH_EXTIPSEL15_PORTA << 28) /* Shifted mode PORTA for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTB (_GPIO_EXTIPSELH_EXTIPSEL15_PORTB << 28) /* Shifted mode PORTB for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTC (_GPIO_EXTIPSELH_EXTIPSEL15_PORTC << 28) /* Shifted mode PORTC for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTD (_GPIO_EXTIPSELH_EXTIPSEL15_PORTD << 28) /* Shifted mode PORTD for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTE (_GPIO_EXTIPSELH_EXTIPSEL15_PORTE << 28) /* Shifted mode PORTE for GPIO_EXTIPSELH */ +#define GPIO_EXTIPSELH_EXTIPSEL15_PORTF (_GPIO_EXTIPSELH_EXTIPSEL15_PORTF << 28) /* Shifted mode PORTF for GPIO_EXTIPSELH */ + +/* Bit fields for GPIO EXTIRISE */ + +#define _GPIO_EXTIRISE_RESETVALUE 0x00000000UL /* Default value for GPIO_EXTIRISE */ +#define _GPIO_EXTIRISE_MASK 0x0000FFFFUL /* Mask for GPIO_EXTIRISE */ + +#define _GPIO_EXTIRISE_EXTIRISE_SHIFT 0 /* Shift value for GPIO_EXTIRISE */ +#define _GPIO_EXTIRISE_EXTIRISE_MASK 0xFFFFUL /* Bit mask for GPIO_EXTIRISE */ +#define _GPIO_EXTIRISE_EXTIRISE_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIRISE */ +#define GPIO_EXTIRISE_EXTIRISE_DEFAULT (_GPIO_EXTIRISE_EXTIRISE_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EXTIRISE */ + +/* Bit fields for GPIO EXTIFALL */ + +#define _GPIO_EXTIFALL_RESETVALUE 0x00000000UL /* Default value for GPIO_EXTIFALL */ +#define _GPIO_EXTIFALL_MASK 0x0000FFFFUL /* Mask for GPIO_EXTIFALL */ + +#define _GPIO_EXTIFALL_EXTIFALL_SHIFT 0 /* Shift value for GPIO_EXTIFALL */ +#define _GPIO_EXTIFALL_EXTIFALL_MASK 0xFFFFUL /* Bit mask for GPIO_EXTIFALL */ +#define _GPIO_EXTIFALL_EXTIFALL_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EXTIFALL */ +#define GPIO_EXTIFALL_EXTIFALL_DEFAULT (_GPIO_EXTIFALL_EXTIFALL_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EXTIFALL */ + +/* Bit fields for GPIO IEN */ + +#define _GPIO_IEN_RESETVALUE 0x00000000UL /* Default value for GPIO_IEN */ +#define _GPIO_IEN_MASK 0x0000FFFFUL /* Mask for GPIO_IEN */ + +#define _GPIO_IEN_EXT_SHIFT 0 /* Shift value for GPIO_EXT */ +#define _GPIO_IEN_EXT_MASK 0xFFFFUL /* Bit mask for GPIO_EXT */ +#define _GPIO_IEN_EXT_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_IEN */ +#define GPIO_IEN_EXT_DEFAULT (_GPIO_IEN_EXT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_IEN */ + +/* Bit fields for GPIO IF */ + +#define _GPIO_IF_RESETVALUE 0x00000000UL /* Default value for GPIO_IF */ +#define _GPIO_IF_MASK 0x0000FFFFUL /* Mask for GPIO_IF */ + +#define _GPIO_IF_EXT_SHIFT 0 /* Shift value for GPIO_EXT */ +#define _GPIO_IF_EXT_MASK 0xFFFFUL /* Bit mask for GPIO_EXT */ +#define _GPIO_IF_EXT_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_IF */ +#define GPIO_IF_EXT_DEFAULT (_GPIO_IF_EXT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_IF */ + +/* Bit fields for GPIO IFS */ + +#define _GPIO_IFS_RESETVALUE 0x00000000UL /* Default value for GPIO_IFS */ +#define _GPIO_IFS_MASK 0x0000FFFFUL /* Mask for GPIO_IFS */ + +#define _GPIO_IFS_EXT_SHIFT 0 /* Shift value for GPIO_EXT */ +#define _GPIO_IFS_EXT_MASK 0xFFFFUL /* Bit mask for GPIO_EXT */ +#define _GPIO_IFS_EXT_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_IFS */ +#define GPIO_IFS_EXT_DEFAULT (_GPIO_IFS_EXT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_IFS */ + +/* Bit fields for GPIO IFC */ + +#define _GPIO_IFC_RESETVALUE 0x00000000UL /* Default value for GPIO_IFC */ +#define _GPIO_IFC_MASK 0x0000FFFFUL /* Mask for GPIO_IFC */ + +#define _GPIO_IFC_EXT_SHIFT 0 /* Shift value for GPIO_EXT */ +#define _GPIO_IFC_EXT_MASK 0xFFFFUL /* Bit mask for GPIO_EXT */ +#define _GPIO_IFC_EXT_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_IFC */ +#define GPIO_IFC_EXT_DEFAULT (_GPIO_IFC_EXT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_IFC */ + +/* Bit fields for GPIO ROUTE */ + +#if defined(CONFIG_EFM32_EFM32TG) || defined(CONFIG_EFM32_EFM32G) +# define _GPIO_ROUTE_RESETVALUE 0x00000003UL /* Default value for GPIO_ROUTE */ +# define _GPIO_ROUTE_MASK 0x00000307UL /* Mask for GPIO_ROUTE */ +#elif defined(CONFIG_EFM32_EFM32GG) +# define _GPIO_ROUTE_RESETVALUE 0x00000003UL /* Default value for GPIO_ROUTE */ +# define _GPIO_ROUTE_MASK 0x0301F307UL /* Mask for GPIO_ROUTE */ +#endif + +#define GPIO_ROUTE_SWCLKPEN (0x1UL << 0) /* Serial Wire Clock Pin Enable */ +#define _GPIO_ROUTE_SWCLKPEN_SHIFT 0 /* Shift value for GPIO_SWCLKPEN */ +#define _GPIO_ROUTE_SWCLKPEN_MASK 0x1UL /* Bit mask for GPIO_SWCLKPEN */ +#define _GPIO_ROUTE_SWCLKPEN_DEFAULT 0x00000001UL /* Mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWCLKPEN_DEFAULT (_GPIO_ROUTE_SWCLKPEN_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWDIOPEN (0x1UL << 1) /* Serial Wire Data Pin Enable */ +#define _GPIO_ROUTE_SWDIOPEN_SHIFT 1 /* Shift value for GPIO_SWDIOPEN */ +#define _GPIO_ROUTE_SWDIOPEN_MASK 0x2UL /* Bit mask for GPIO_SWDIOPEN */ +#define _GPIO_ROUTE_SWDIOPEN_DEFAULT 0x00000001UL /* Mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWDIOPEN_DEFAULT (_GPIO_ROUTE_SWDIOPEN_DEFAULT << 1) /* Shifted mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWOPEN (0x1UL << 2) /* Serial Wire Viewer Output Pin Enable */ +#define _GPIO_ROUTE_SWOPEN_SHIFT 2 /* Shift value for GPIO_SWOPEN */ +#define _GPIO_ROUTE_SWOPEN_MASK 0x4UL /* Bit mask for GPIO_SWOPEN */ +#define _GPIO_ROUTE_SWOPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWOPEN_DEFAULT (_GPIO_ROUTE_SWOPEN_DEFAULT << 2) /* Shifted mode DEFAULT for GPIO_ROUTE */ +#define _GPIO_ROUTE_SWLOCATION_SHIFT 8 /* Shift value for GPIO_SWLOCATION */ +#define _GPIO_ROUTE_SWLOCATION_MASK 0x300UL /* Bit mask for GPIO_SWLOCATION */ +#define _GPIO_ROUTE_SWLOCATION_LOC0 0x00000000UL /* Mode LOC0 for GPIO_ROUTE */ +#define _GPIO_ROUTE_SWLOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +#define _GPIO_ROUTE_SWLOCATION_LOC1 0x00000001UL /* Mode LOC1 for GPIO_ROUTE */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _GPIO_ROUTE_SWLOCATION_LOC2 0x00000002UL /* Mode LOC2 for GPIO_ROUTE */ +# define _GPIO_ROUTE_SWLOCATION_LOC3 0x00000003UL /* Mode LOC3 for GPIO_ROUTE */ +#endif + +#define GPIO_ROUTE_SWLOCATION_LOC0 (_GPIO_ROUTE_SWLOCATION_LOC0 << 8) /* Shifted mode LOC0 for GPIO_ROUTE */ +#define GPIO_ROUTE_SWLOCATION_DEFAULT (_GPIO_ROUTE_SWLOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for GPIO_ROUTE */ +#define GPIO_ROUTE_SWLOCATION_LOC1 (_GPIO_ROUTE_SWLOCATION_LOC1 << 8) /* Shifted mode LOC1 for GPIO_ROUTE */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define GPIO_ROUTE_SWLOCATION_LOC2 (_GPIO_ROUTE_SWLOCATION_LOC2 << 8) /* Shifted mode LOC2 for GPIO_ROUTE */ +# define GPIO_ROUTE_SWLOCATION_LOC3 (_GPIO_ROUTE_SWLOCATION_LOC3 << 8) /* Shifted mode LOC3 for GPIO_ROUTE */ +# define GPIO_ROUTE_TCLKPEN (0x1UL << 12) /* ETM Trace Clock Pin Enable */ +# define _GPIO_ROUTE_TCLKPEN_SHIFT 12 /* Shift value for GPIO_TCLKPEN */ +# define _GPIO_ROUTE_TCLKPEN_MASK 0x1000UL /* Bit mask for GPIO_TCLKPEN */ +# define _GPIO_ROUTE_TCLKPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TCLKPEN_DEFAULT (_GPIO_ROUTE_TCLKPEN_DEFAULT << 12) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD0PEN (0x1UL << 13) /* ETM Trace Data Pin Enable */ +# define _GPIO_ROUTE_TD0PEN_SHIFT 13 /* Shift value for GPIO_TD0PEN */ +# define _GPIO_ROUTE_TD0PEN_MASK 0x2000UL /* Bit mask for GPIO_TD0PEN */ +# define _GPIO_ROUTE_TD0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD0PEN_DEFAULT (_GPIO_ROUTE_TD0PEN_DEFAULT << 13) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD1PEN (0x1UL << 14) /* ETM Trace Data Pin Enable */ +# define _GPIO_ROUTE_TD1PEN_SHIFT 14 /* Shift value for GPIO_TD1PEN */ +# define _GPIO_ROUTE_TD1PEN_MASK 0x4000UL /* Bit mask for GPIO_TD1PEN */ +# define _GPIO_ROUTE_TD1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD1PEN_DEFAULT (_GPIO_ROUTE_TD1PEN_DEFAULT << 14) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD2PEN (0x1UL << 15) /* ETM Trace Data Pin Enable */ +# define _GPIO_ROUTE_TD2PEN_SHIFT 15 /* Shift value for GPIO_TD2PEN */ +# define _GPIO_ROUTE_TD2PEN_MASK 0x8000UL /* Bit mask for GPIO_TD2PEN */ +# define _GPIO_ROUTE_TD2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD2PEN_DEFAULT (_GPIO_ROUTE_TD2PEN_DEFAULT << 15) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD3PEN (0x1UL << 16) /* ETM Trace Data Pin Enable */ +# define _GPIO_ROUTE_TD3PEN_SHIFT 16 /* Shift value for GPIO_TD3PEN */ +# define _GPIO_ROUTE_TD3PEN_MASK 0x10000UL /* Bit mask for GPIO_TD3PEN */ +# define _GPIO_ROUTE_TD3PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_TD3PEN_DEFAULT (_GPIO_ROUTE_TD3PEN_DEFAULT << 16) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define _GPIO_ROUTE_ETMLOCATION_SHIFT 24 /* Shift value for GPIO_ETMLOCATION */ +# define _GPIO_ROUTE_ETMLOCATION_MASK 0x3000000UL /* Bit mask for GPIO_ETMLOCATION */ +# define _GPIO_ROUTE_ETMLOCATION_LOC0 0x00000000UL /* Mode LOC0 for GPIO_ROUTE */ +# define _GPIO_ROUTE_ETMLOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_ROUTE */ +# define _GPIO_ROUTE_ETMLOCATION_LOC1 0x00000001UL /* Mode LOC1 for GPIO_ROUTE */ +# define _GPIO_ROUTE_ETMLOCATION_LOC2 0x00000002UL /* Mode LOC2 for GPIO_ROUTE */ +# define _GPIO_ROUTE_ETMLOCATION_LOC3 0x00000003UL /* Mode LOC3 for GPIO_ROUTE */ +# define GPIO_ROUTE_ETMLOCATION_LOC0 (_GPIO_ROUTE_ETMLOCATION_LOC0 << 24) /* Shifted mode LOC0 for GPIO_ROUTE */ +# define GPIO_ROUTE_ETMLOCATION_DEFAULT (_GPIO_ROUTE_ETMLOCATION_DEFAULT << 24) /* Shifted mode DEFAULT for GPIO_ROUTE */ +# define GPIO_ROUTE_ETMLOCATION_LOC1 (_GPIO_ROUTE_ETMLOCATION_LOC1 << 24) /* Shifted mode LOC1 for GPIO_ROUTE */ +# define GPIO_ROUTE_ETMLOCATION_LOC2 (_GPIO_ROUTE_ETMLOCATION_LOC2 << 24) /* Shifted mode LOC2 for GPIO_ROUTE */ +# define GPIO_ROUTE_ETMLOCATION_LOC3 (_GPIO_ROUTE_ETMLOCATION_LOC3 << 24) /* Shifted mode LOC3 for GPIO_ROUTE */ +#endif + +/* Bit fields for GPIO INSENSE */ + +#define _GPIO_INSENSE_RESETVALUE 0x00000003UL /* Default value for GPIO_INSENSE */ +#define _GPIO_INSENSE_MASK 0x00000003UL /* Mask for GPIO_INSENSE */ + +#define GPIO_INSENSE_INT (0x1UL << 0) /* Interrupt Sense Enable */ +#define _GPIO_INSENSE_INT_SHIFT 0 /* Shift value for GPIO_INT */ +#define _GPIO_INSENSE_INT_MASK 0x1UL /* Bit mask for GPIO_INT */ +#define _GPIO_INSENSE_INT_DEFAULT 0x00000001UL /* Mode DEFAULT for GPIO_INSENSE */ +#define GPIO_INSENSE_INT_DEFAULT (_GPIO_INSENSE_INT_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_INSENSE */ +#define GPIO_INSENSE_PRS (0x1UL << 1) /* PRS Sense Enable */ +#define _GPIO_INSENSE_PRS_SHIFT 1 /* Shift value for GPIO_PRS */ +#define _GPIO_INSENSE_PRS_MASK 0x2UL /* Bit mask for GPIO_PRS */ +#define _GPIO_INSENSE_PRS_DEFAULT 0x00000001UL /* Mode DEFAULT for GPIO_INSENSE */ +#define GPIO_INSENSE_PRS_DEFAULT (_GPIO_INSENSE_PRS_DEFAULT << 1) /* Shifted mode DEFAULT for GPIO_INSENSE */ + +/* Bit fields for GPIO LOCK */ + +#define _GPIO_LOCK_RESETVALUE 0x00000000UL /* Default value for GPIO_LOCK */ +#define _GPIO_LOCK_MASK 0x0000FFFFUL /* Mask for GPIO_LOCK */ + +#define _GPIO_LOCK_LOCKKEY_SHIFT 0 /* Shift value for GPIO_LOCKKEY */ +#define _GPIO_LOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for GPIO_LOCKKEY */ +#define _GPIO_LOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_LOCK */ +#define _GPIO_LOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for GPIO_LOCK */ +#define _GPIO_LOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for GPIO_LOCK */ +#define _GPIO_LOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for GPIO_LOCK */ +#define _GPIO_LOCK_LOCKKEY_UNLOCK 0x0000A534UL /* Mode UNLOCK for GPIO_LOCK */ +#define GPIO_LOCK_LOCKKEY_DEFAULT (_GPIO_LOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_LOCK */ +#define GPIO_LOCK_LOCKKEY_LOCK (_GPIO_LOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for GPIO_LOCK */ +#define GPIO_LOCK_LOCKKEY_UNLOCKED (_GPIO_LOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for GPIO_LOCK */ +#define GPIO_LOCK_LOCKKEY_LOCKED (_GPIO_LOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for GPIO_LOCK */ +#define GPIO_LOCK_LOCKKEY_UNLOCK (_GPIO_LOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for GPIO_LOCK */ + +/* Bit fields for GPIO CTRL */ + +#define _GPIO_CTRL_RESETVALUE 0x00000000UL /* Default value for GPIO_CTRL */ + +#define _GPIO_CTRL_MASK 0x00000001UL /* Mask for GPIO_CTRL */ +#define GPIO_CTRL_EM4RET (0x1UL << 0) /* Enable EM4 retention */ +#define _GPIO_CTRL_EM4RET_SHIFT 0 /* Shift value for GPIO_EM4RET */ +#define _GPIO_CTRL_EM4RET_MASK 0x1UL /* Bit mask for GPIO_EM4RET */ +#define _GPIO_CTRL_EM4RET_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_CTRL */ +#define GPIO_CTRL_EM4RET_DEFAULT (_GPIO_CTRL_EM4RET_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_CTRL */ + +/* Bit fields for GPIO CMD */ + +#define _GPIO_CMD_RESETVALUE 0x00000000UL /* Default value for GPIO_CMD */ +#define _GPIO_CMD_MASK 0x00000001UL /* Mask for GPIO_CMD */ + +#define GPIO_CMD_EM4WUCLR (0x1UL << 0) /* EM4 Wake-up clear */ +#define _GPIO_CMD_EM4WUCLR_SHIFT 0 /* Shift value for GPIO_EM4WUCLR */ +#define _GPIO_CMD_EM4WUCLR_MASK 0x1UL /* Bit mask for GPIO_EM4WUCLR */ +#define _GPIO_CMD_EM4WUCLR_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_CMD */ +#define GPIO_CMD_EM4WUCLR_DEFAULT (_GPIO_CMD_EM4WUCLR_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_CMD */ + +/* Bit fields for GPIO EM4WUEN */ + +#define _GPIO_EM4WUEN_RESETVALUE 0x00000000UL /* Default value for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_MASK 0x0000003FUL /* Mask for GPIO_EM4WUEN */ + +#define _GPIO_EM4WUEN_EM4WUEN_SHIFT 0 /* Shift value for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_MASK 0x3FUL /* Bit mask for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_A0 0x00000001UL /* Mode A0 for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_A6 0x00000002UL /* Mode A6 for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_C9 0x00000004UL /* Mode C9 for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_F1 0x00000008UL /* Mode F1 for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_F2 0x00000010UL /* Mode F2 for GPIO_EM4WUEN */ +#define _GPIO_EM4WUEN_EM4WUEN_E13 0x00000020UL /* Mode E13 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_DEFAULT (_GPIO_EM4WUEN_EM4WUEN_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_A0 (_GPIO_EM4WUEN_EM4WUEN_A0 << 0) /* Shifted mode A0 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_A6 (_GPIO_EM4WUEN_EM4WUEN_A6 << 0) /* Shifted mode A6 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_C9 (_GPIO_EM4WUEN_EM4WUEN_C9 << 0) /* Shifted mode C9 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_F1 (_GPIO_EM4WUEN_EM4WUEN_F1 << 0) /* Shifted mode F1 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_F2 (_GPIO_EM4WUEN_EM4WUEN_F2 << 0) /* Shifted mode F2 for GPIO_EM4WUEN */ +#define GPIO_EM4WUEN_EM4WUEN_E13 (_GPIO_EM4WUEN_EM4WUEN_E13 << 0) /* Shifted mode E13 for GPIO_EM4WUEN */ + +/* Bit fields for GPIO EM4WUPOL */ + +#define _GPIO_EM4WUPOL_RESETVALUE 0x00000000UL /* Default value for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_MASK 0x0000003FUL /* Mask for GPIO_EM4WUPOL */ + +#define _GPIO_EM4WUPOL_EM4WUPOL_SHIFT 0 /* Shift value for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_MASK 0x3FUL /* Bit mask for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_A0 0x00000001UL /* Mode A0 for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_A6 0x00000002UL /* Mode A6 for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_C9 0x00000004UL /* Mode C9 for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_F1 0x00000008UL /* Mode F1 for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_F2 0x00000010UL /* Mode F2 for GPIO_EM4WUPOL */ +#define _GPIO_EM4WUPOL_EM4WUPOL_E13 0x00000020UL /* Mode E13 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_DEFAULT (_GPIO_EM4WUPOL_EM4WUPOL_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_A0 (_GPIO_EM4WUPOL_EM4WUPOL_A0 << 0) /* Shifted mode A0 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_A6 (_GPIO_EM4WUPOL_EM4WUPOL_A6 << 0) /* Shifted mode A6 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_C9 (_GPIO_EM4WUPOL_EM4WUPOL_C9 << 0) /* Shifted mode C9 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_F1 (_GPIO_EM4WUPOL_EM4WUPOL_F1 << 0) /* Shifted mode F1 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_F2 (_GPIO_EM4WUPOL_EM4WUPOL_F2 << 0) /* Shifted mode F2 for GPIO_EM4WUPOL */ +#define GPIO_EM4WUPOL_EM4WUPOL_E13 (_GPIO_EM4WUPOL_EM4WUPOL_E13 << 0) /* Shifted mode E13 for GPIO_EM4WUPOL */ + +/* Bit fields for GPIO EM4WUCAUSE */ + +#define _GPIO_EM4WUCAUSE_RESETVALUE 0x00000000UL /* Default value for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_MASK 0x0000003FUL /* Mask for GPIO_EM4WUCAUSE */ + +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_SHIFT 0 /* Shift value for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_MASK 0x3FUL /* Bit mask for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_DEFAULT 0x00000000UL /* Mode DEFAULT for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_A0 0x00000001UL /* Mode A0 for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_A6 0x00000002UL /* Mode A6 for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_C9 0x00000004UL /* Mode C9 for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_F1 0x00000008UL /* Mode F1 for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_F2 0x00000010UL /* Mode F2 for GPIO_EM4WUCAUSE */ +#define _GPIO_EM4WUCAUSE_EM4WUCAUSE_E13 0x00000020UL /* Mode E13 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_DEFAULT (_GPIO_EM4WUCAUSE_EM4WUCAUSE_DEFAULT << 0) /* Shifted mode DEFAULT for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_A0 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_A0 << 0) /* Shifted mode A0 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_A6 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_A6 << 0) /* Shifted mode A6 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_C9 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_C9 << 0) /* Shifted mode C9 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_F1 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_F1 << 0) /* Shifted mode F1 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_F2 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_F2 << 0) /* Shifted mode F2 for GPIO_EM4WUCAUSE */ +#define GPIO_EM4WUCAUSE_EM4WUCAUSE_E13 (_GPIO_EM4WUCAUSE_EM4WUCAUSE_E13 << 0) /* Shifted mode E13 for GPIO_EM4WUCAUSE */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_GPIO_H */ diff --git a/arch/arm/src/efm32/chip/efm32_i2c.h b/arch/arm/src/efm32/chip/efm32_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..df8382a2a93c483b74925fe577c345088df06e9f --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_i2c.h @@ -0,0 +1,800 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_i2c.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_I2C_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_I2C_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* I2C Register Offsets ********************************************************************************************************/ + +#define EFM32_I2C_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_I2C_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_I2C_STATE_OFFSET 0x0008 /* State Register */ +#define EFM32_I2C_STATUS_OFFSET 0x000c /* Status Register */ +#define EFM32_I2C_CLKDIV_OFFSET 0x0010 /* Clock Division Register */ +#define EFM32_I2C_SADDR_OFFSET 0x0014 /* Slave Address Register */ +#define EFM32_I2C_SADDRMASK_OFFSET 0x0018 /* Slave Address Mask Register */ +#define EFM32_I2C_RXDATA_OFFSET 0x001c /* Receive Buffer Data Register */ +#define EFM32_I2C_RXDATAP_OFFSET 0x0020 /* Receive Buffer Data Peek Register */ +#define EFM32_I2C_TXDATA_OFFSET 0x0024 /* Transmit Buffer Data Register */ +#define EFM32_I2C_IF_OFFSET 0x0028 /* Interrupt Flag Register */ +#define EFM32_I2C_IFS_OFFSET 0x002c /* Interrupt Flag Set Register */ +#define EFM32_I2C_IFC_OFFSET 0x0030 /* Interrupt Flag Clear Register */ +#define EFM32_I2C_IEN_OFFSET 0x0034 /* Interrupt Enable Register */ +#define EFM32_I2C_ROUTE_OFFSET 0x0038 /* I/O Routing Register */ + +/* I2C Register Addresses ******************************************************************************************************/ + +#define EFM32_I2C0_CTRL (EFM32_I2C0_BASE+EFM32_I2C_CTRL_OFFSET) +#define EFM32_I2C0_CMD (EFM32_I2C0_BASE+EFM32_I2C_CMD_OFFSET) +#define EFM32_I2C0_STATE (EFM32_I2C0_BASE+EFM32_I2C_STATE_OFFSET) +#define EFM32_I2C0_STATUS (EFM32_I2C0_BASE+EFM32_I2C_STATUS_OFFSET) +#define EFM32_I2C0_CLKDIV (EFM32_I2C0_BASE+EFM32_I2C_CLKDIV_OFFSET) +#define EFM32_I2C0_SADDR (EFM32_I2C0_BASE+EFM32_I2C_SADDR_OFFSET) +#define EFM32_I2C0_SADDRMASK (EFM32_I2C0_BASE+EFM32_I2C_SADDRMASK_OFFSET) +#define EFM32_I2C0_RXDATA (EFM32_I2C0_BASE+EFM32_I2C_RXDATA_OFFSET) +#define EFM32_I2C0_RXDATAP (EFM32_I2C0_BASE+EFM32_I2C_RXDATAP_OFFSET) +#define EFM32_I2C0_TXDATA (EFM32_I2C0_BASE+EFM32_I2C_TXDATA_OFFSET) +#define EFM32_I2C0_IF (EFM32_I2C0_BASE+EFM32_I2C_IF_OFFSET) +#define EFM32_I2C0_IFS (EFM32_I2C0_BASE+EFM32_I2C_IFS_OFFSET) +#define EFM32_I2C0_IFC (EFM32_I2C0_BASE+EFM32_I2C_IFC_OFFSET) +#define EFM32_I2C0_IEN (EFM32_I2C0_BASE+EFM32_I2C_IEN_OFFSET) +#define EFM32_I2C0_ROUTE (EFM32_I2C0_BASE+EFM32_I2C_ROUTE_OFFSET) + +#define EFM32_I2C1_CTRL (EFM32_I2C1_BASE+EFM32_I2C_CTRL_OFFSET) +#define EFM32_I2C1_CMD (EFM32_I2C1_BASE+EFM32_I2C_CMD_OFFSET) +#define EFM32_I2C1_STATE (EFM32_I2C1_BASE+EFM32_I2C_STATE_OFFSET) +#define EFM32_I2C1_STATUS (EFM32_I2C1_BASE+EFM32_I2C_STATUS_OFFSET) +#define EFM32_I2C1_CLKDIV (EFM32_I2C1_BASE+EFM32_I2C_CLKDIV_OFFSET) +#define EFM32_I2C1_SADDR (EFM32_I2C1_BASE+EFM32_I2C_SADDR_OFFSET) +#define EFM32_I2C1_SADDRMASK (EFM32_I2C1_BASE+EFM32_I2C_SADDRMASK_OFFSET) +#define EFM32_I2C1_RXDATA (EFM32_I2C1_BASE+EFM32_I2C_RXDATA_OFFSET) +#define EFM32_I2C1_RXDATAP (EFM32_I2C1_BASE+EFM32_I2C_RXDATAP_OFFSET) +#define EFM32_I2C1_TXDATA (EFM32_I2C1_BASE+EFM32_I2C_TXDATA_OFFSET) +#define EFM32_I2C1_IF (EFM32_I2C1_BASE+EFM32_I2C_IF_OFFSET) +#define EFM32_I2C1_IFS (EFM32_I2C1_BASE+EFM32_I2C_IFS_OFFSET) +#define EFM32_I2C1_IFC (EFM32_I2C1_BASE+EFM32_I2C_IFC_OFFSET) +#define EFM32_I2C1_IEN (EFM32_I2C1_BASE+EFM32_I2C_IEN_OFFSET) +#define EFM32_I2C1_ROUTE (EFM32_I2C1_BASE+EFM32_I2C_ROUTE_OFFSET) + +/* I2C Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for I2C CTRL */ + +#define _I2C_CTRL_RESETVALUE 0x00000000UL /* Default value for I2C_CTRL */ +#define _I2C_CTRL_MASK 0x0007B37FUL /* Mask for I2C_CTRL */ + +#define I2C_CTRL_EN (0x1UL << 0) /* I2C Enable */ +#define _I2C_CTRL_EN_SHIFT 0 /* Shift value for I2C_EN */ +#define _I2C_CTRL_EN_MASK 0x1UL /* Bit mask for I2C_EN */ +#define _I2C_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_EN_DEFAULT (_I2C_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_SLAVE (0x1UL << 1) /* Addressable as Slave */ +#define _I2C_CTRL_SLAVE_SHIFT 1 /* Shift value for I2C_SLAVE */ +#define _I2C_CTRL_SLAVE_MASK 0x2UL /* Bit mask for I2C_SLAVE */ +#define _I2C_CTRL_SLAVE_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_SLAVE_DEFAULT (_I2C_CTRL_SLAVE_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOACK (0x1UL << 2) /* Automatic Acknowledge */ +#define _I2C_CTRL_AUTOACK_SHIFT 2 /* Shift value for I2C_AUTOACK */ +#define _I2C_CTRL_AUTOACK_MASK 0x4UL /* Bit mask for I2C_AUTOACK */ +#define _I2C_CTRL_AUTOACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOACK_DEFAULT (_I2C_CTRL_AUTOACK_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOSE (0x1UL << 3) /* Automatic STOP when Empty */ +#define _I2C_CTRL_AUTOSE_SHIFT 3 /* Shift value for I2C_AUTOSE */ +#define _I2C_CTRL_AUTOSE_MASK 0x8UL /* Bit mask for I2C_AUTOSE */ +#define _I2C_CTRL_AUTOSE_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOSE_DEFAULT (_I2C_CTRL_AUTOSE_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOSN (0x1UL << 4) /* Automatic STOP on NACK */ +#define _I2C_CTRL_AUTOSN_SHIFT 4 /* Shift value for I2C_AUTOSN */ +#define _I2C_CTRL_AUTOSN_MASK 0x10UL /* Bit mask for I2C_AUTOSN */ +#define _I2C_CTRL_AUTOSN_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_AUTOSN_DEFAULT (_I2C_CTRL_AUTOSN_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_ARBDIS (0x1UL << 5) /* Arbitration Disable */ +#define _I2C_CTRL_ARBDIS_SHIFT 5 /* Shift value for I2C_ARBDIS */ +#define _I2C_CTRL_ARBDIS_MASK 0x20UL /* Bit mask for I2C_ARBDIS */ +#define _I2C_CTRL_ARBDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_ARBDIS_DEFAULT (_I2C_CTRL_ARBDIS_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_GCAMEN (0x1UL << 6) /* General Call Address Match Enable */ +#define _I2C_CTRL_GCAMEN_SHIFT 6 /* Shift value for I2C_GCAMEN */ +#define _I2C_CTRL_GCAMEN_MASK 0x40UL /* Bit mask for I2C_GCAMEN */ +#define _I2C_CTRL_GCAMEN_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_GCAMEN_DEFAULT (_I2C_CTRL_GCAMEN_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_CTRL */ +#define _I2C_CTRL_CLHR_SHIFT 8 /* Shift value for I2C_CLHR */ +#define _I2C_CTRL_CLHR_MASK 0x300UL /* Bit mask for I2C_CLHR */ +#define _I2C_CTRL_CLHR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define _I2C_CTRL_CLHR_STANDARD 0x00000000UL /* Mode STANDARD for I2C_CTRL */ +#define _I2C_CTRL_CLHR_ASYMMETRIC 0x00000001UL /* Mode ASYMMETRIC for I2C_CTRL */ +#define _I2C_CTRL_CLHR_FAST 0x00000002UL /* Mode FAST for I2C_CTRL */ +#define I2C_CTRL_CLHR_DEFAULT (_I2C_CTRL_CLHR_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_CLHR_STANDARD (_I2C_CTRL_CLHR_STANDARD << 8) /* Shifted mode STANDARD for I2C_CTRL */ +#define I2C_CTRL_CLHR_ASYMMETRIC (_I2C_CTRL_CLHR_ASYMMETRIC << 8) /* Shifted mode ASYMMETRIC for I2C_CTRL */ +#define I2C_CTRL_CLHR_FAST (_I2C_CTRL_CLHR_FAST << 8) /* Shifted mode FAST for I2C_CTRL */ +#define _I2C_CTRL_BITO_SHIFT 12 /* Shift value for I2C_BITO */ +#define _I2C_CTRL_BITO_MASK 0x3000UL /* Bit mask for I2C_BITO */ +#define _I2C_CTRL_BITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define _I2C_CTRL_BITO_OFF 0x00000000UL /* Mode OFF for I2C_CTRL */ +#define _I2C_CTRL_BITO_40PCC 0x00000001UL /* Mode 40PCC for I2C_CTRL */ +#define _I2C_CTRL_BITO_80PCC 0x00000002UL /* Mode 80PCC for I2C_CTRL */ +#define _I2C_CTRL_BITO_160PCC 0x00000003UL /* Mode 160PCC for I2C_CTRL */ +#define I2C_CTRL_BITO_DEFAULT (_I2C_CTRL_BITO_DEFAULT << 12) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_BITO_OFF (_I2C_CTRL_BITO_OFF << 12) /* Shifted mode OFF for I2C_CTRL */ +#define I2C_CTRL_BITO_40PCC (_I2C_CTRL_BITO_40PCC << 12) /* Shifted mode 40PCC for I2C_CTRL */ +#define I2C_CTRL_BITO_80PCC (_I2C_CTRL_BITO_80PCC << 12) /* Shifted mode 80PCC for I2C_CTRL */ +#define I2C_CTRL_BITO_160PCC (_I2C_CTRL_BITO_160PCC << 12) /* Shifted mode 160PCC for I2C_CTRL */ +#define I2C_CTRL_GIBITO (0x1UL << 15) /* Go Idle on Bus Idle Timeout */ +#define _I2C_CTRL_GIBITO_SHIFT 15 /* Shift value for I2C_GIBITO */ +#define _I2C_CTRL_GIBITO_MASK 0x8000UL /* Bit mask for I2C_GIBITO */ +#define _I2C_CTRL_GIBITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_GIBITO_DEFAULT (_I2C_CTRL_GIBITO_DEFAULT << 15) /* Shifted mode DEFAULT for I2C_CTRL */ +#define _I2C_CTRL_CLTO_SHIFT 16 /* Shift value for I2C_CLTO */ +#define _I2C_CTRL_CLTO_MASK 0x70000UL /* Bit mask for I2C_CLTO */ +#define _I2C_CTRL_CLTO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CTRL */ +#define _I2C_CTRL_CLTO_OFF 0x00000000UL /* Mode OFF for I2C_CTRL */ +#define _I2C_CTRL_CLTO_40PCC 0x00000001UL /* Mode 40PCC for I2C_CTRL */ +#define _I2C_CTRL_CLTO_80PCC 0x00000002UL /* Mode 80PCC for I2C_CTRL */ +#define _I2C_CTRL_CLTO_160PCC 0x00000003UL /* Mode 160PCC for I2C_CTRL */ +#define _I2C_CTRL_CLTO_320PPC 0x00000004UL /* Mode 320PPC for I2C_CTRL */ +#define _I2C_CTRL_CLTO_1024PPC 0x00000005UL /* Mode 1024PPC for I2C_CTRL */ +#define I2C_CTRL_CLTO_DEFAULT (_I2C_CTRL_CLTO_DEFAULT << 16) /* Shifted mode DEFAULT for I2C_CTRL */ +#define I2C_CTRL_CLTO_OFF (_I2C_CTRL_CLTO_OFF << 16) /* Shifted mode OFF for I2C_CTRL */ +#define I2C_CTRL_CLTO_40PCC (_I2C_CTRL_CLTO_40PCC << 16) /* Shifted mode 40PCC for I2C_CTRL */ +#define I2C_CTRL_CLTO_80PCC (_I2C_CTRL_CLTO_80PCC << 16) /* Shifted mode 80PCC for I2C_CTRL */ +#define I2C_CTRL_CLTO_160PCC (_I2C_CTRL_CLTO_160PCC << 16) /* Shifted mode 160PCC for I2C_CTRL */ +#define I2C_CTRL_CLTO_320PPC (_I2C_CTRL_CLTO_320PPC << 16) /* Shifted mode 320PPC for I2C_CTRL */ +#define I2C_CTRL_CLTO_1024PPC (_I2C_CTRL_CLTO_1024PPC << 16) /* Shifted mode 1024PPC for I2C_CTRL */ + +/* Bit fields for I2C CMD */ + +#define _I2C_CMD_RESETVALUE 0x00000000UL /* Default value for I2C_CMD */ +#define _I2C_CMD_MASK 0x000000FFUL /* Mask for I2C_CMD */ + +#define I2C_CMD_START (0x1UL << 0) /* Send start condition */ +#define _I2C_CMD_START_SHIFT 0 /* Shift value for I2C_START */ +#define _I2C_CMD_START_MASK 0x1UL /* Bit mask for I2C_START */ +#define _I2C_CMD_START_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_START_DEFAULT (_I2C_CMD_START_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_STOP (0x1UL << 1) /* Send stop condition */ +#define _I2C_CMD_STOP_SHIFT 1 /* Shift value for I2C_STOP */ +#define _I2C_CMD_STOP_MASK 0x2UL /* Bit mask for I2C_STOP */ +#define _I2C_CMD_STOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_STOP_DEFAULT (_I2C_CMD_STOP_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_ACK (0x1UL << 2) /* Send ACK */ +#define _I2C_CMD_ACK_SHIFT 2 /* Shift value for I2C_ACK */ +#define _I2C_CMD_ACK_MASK 0x4UL /* Bit mask for I2C_ACK */ +#define _I2C_CMD_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_ACK_DEFAULT (_I2C_CMD_ACK_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_NACK (0x1UL << 3) /* Send NACK */ +#define _I2C_CMD_NACK_SHIFT 3 /* Shift value for I2C_NACK */ +#define _I2C_CMD_NACK_MASK 0x8UL /* Bit mask for I2C_NACK */ +#define _I2C_CMD_NACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_NACK_DEFAULT (_I2C_CMD_NACK_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CONT (0x1UL << 4) /* Continue transmission */ +#define _I2C_CMD_CONT_SHIFT 4 /* Shift value for I2C_CONT */ +#define _I2C_CMD_CONT_MASK 0x10UL /* Bit mask for I2C_CONT */ +#define _I2C_CMD_CONT_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CONT_DEFAULT (_I2C_CMD_CONT_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_ABORT (0x1UL << 5) /* Abort transmission */ +#define _I2C_CMD_ABORT_SHIFT 5 /* Shift value for I2C_ABORT */ +#define _I2C_CMD_ABORT_MASK 0x20UL /* Bit mask for I2C_ABORT */ +#define _I2C_CMD_ABORT_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_ABORT_DEFAULT (_I2C_CMD_ABORT_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CLEARTX (0x1UL << 6) /* Clear TX */ +#define _I2C_CMD_CLEARTX_SHIFT 6 /* Shift value for I2C_CLEARTX */ +#define _I2C_CMD_CLEARTX_MASK 0x40UL /* Bit mask for I2C_CLEARTX */ +#define _I2C_CMD_CLEARTX_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CLEARTX_DEFAULT (_I2C_CMD_CLEARTX_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CLEARPC (0x1UL << 7) /* Clear Pending Commands */ +#define _I2C_CMD_CLEARPC_SHIFT 7 /* Shift value for I2C_CLEARPC */ +#define _I2C_CMD_CLEARPC_MASK 0x80UL /* Bit mask for I2C_CLEARPC */ +#define _I2C_CMD_CLEARPC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CMD */ +#define I2C_CMD_CLEARPC_DEFAULT (_I2C_CMD_CLEARPC_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_CMD */ + +/* Bit fields for I2C STATE */ + +#define _I2C_STATE_RESETVALUE 0x00000001UL /* Default value for I2C_STATE */ +#define _I2C_STATE_MASK 0x000000FFUL /* Mask for I2C_STATE */ + +#define I2C_STATE_BUSY (0x1UL << 0) /* Bus Busy */ +#define _I2C_STATE_BUSY_SHIFT 0 /* Shift value for I2C_BUSY */ +#define _I2C_STATE_BUSY_MASK 0x1UL /* Bit mask for I2C_BUSY */ +#define _I2C_STATE_BUSY_DEFAULT 0x00000001UL /* Mode DEFAULT for I2C_STATE */ +#define I2C_STATE_BUSY_DEFAULT (_I2C_STATE_BUSY_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_STATE */ +#define I2C_STATE_MASTER (0x1UL << 1) /* Master */ +#define _I2C_STATE_MASTER_SHIFT 1 /* Shift value for I2C_MASTER */ +#define _I2C_STATE_MASTER_MASK 0x2UL /* Bit mask for I2C_MASTER */ +#define _I2C_STATE_MASTER_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATE */ +#define I2C_STATE_MASTER_DEFAULT (_I2C_STATE_MASTER_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_STATE */ +#define I2C_STATE_TRANSMITTER (0x1UL << 2) /* Transmitter */ +#define _I2C_STATE_TRANSMITTER_SHIFT 2 /* Shift value for I2C_TRANSMITTER */ +#define _I2C_STATE_TRANSMITTER_MASK 0x4UL /* Bit mask for I2C_TRANSMITTER */ +#define _I2C_STATE_TRANSMITTER_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATE */ +#define I2C_STATE_TRANSMITTER_DEFAULT (_I2C_STATE_TRANSMITTER_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_STATE */ +#define I2C_STATE_NACKED (0x1UL << 3) /* Nack Received */ +#define _I2C_STATE_NACKED_SHIFT 3 /* Shift value for I2C_NACKED */ +#define _I2C_STATE_NACKED_MASK 0x8UL /* Bit mask for I2C_NACKED */ +#define _I2C_STATE_NACKED_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATE */ +#define I2C_STATE_NACKED_DEFAULT (_I2C_STATE_NACKED_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_STATE */ +#define I2C_STATE_BUSHOLD (0x1UL << 4) /* Bus Held */ +#define _I2C_STATE_BUSHOLD_SHIFT 4 /* Shift value for I2C_BUSHOLD */ +#define _I2C_STATE_BUSHOLD_MASK 0x10UL /* Bit mask for I2C_BUSHOLD */ +#define _I2C_STATE_BUSHOLD_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATE */ +#define I2C_STATE_BUSHOLD_DEFAULT (_I2C_STATE_BUSHOLD_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_STATE */ +#define _I2C_STATE_STATE_SHIFT 5 /* Shift value for I2C_STATE */ +#define _I2C_STATE_STATE_MASK 0xE0UL /* Bit mask for I2C_STATE */ +#define _I2C_STATE_STATE_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATE */ +#define _I2C_STATE_STATE_IDLE 0x00000000UL /* Mode IDLE for I2C_STATE */ +#define _I2C_STATE_STATE_WAIT 0x00000001UL /* Mode WAIT for I2C_STATE */ +#define _I2C_STATE_STATE_START 0x00000002UL /* Mode START for I2C_STATE */ +#define _I2C_STATE_STATE_ADDR 0x00000003UL /* Mode ADDR for I2C_STATE */ +#define _I2C_STATE_STATE_ADDRACK 0x00000004UL /* Mode ADDRACK for I2C_STATE */ +#define _I2C_STATE_STATE_DATA 0x00000005UL /* Mode DATA for I2C_STATE */ +#define _I2C_STATE_STATE_DATAACK 0x00000006UL /* Mode DATAACK for I2C_STATE */ +#define I2C_STATE_STATE_DEFAULT (_I2C_STATE_STATE_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_STATE */ +#define I2C_STATE_STATE_IDLE (_I2C_STATE_STATE_IDLE << 5) /* Shifted mode IDLE for I2C_STATE */ +#define I2C_STATE_STATE_WAIT (_I2C_STATE_STATE_WAIT << 5) /* Shifted mode WAIT for I2C_STATE */ +#define I2C_STATE_STATE_START (_I2C_STATE_STATE_START << 5) /* Shifted mode START for I2C_STATE */ +#define I2C_STATE_STATE_ADDR (_I2C_STATE_STATE_ADDR << 5) /* Shifted mode ADDR for I2C_STATE */ +#define I2C_STATE_STATE_ADDRACK (_I2C_STATE_STATE_ADDRACK << 5) /* Shifted mode ADDRACK for I2C_STATE */ +#define I2C_STATE_STATE_DATA (_I2C_STATE_STATE_DATA << 5) /* Shifted mode DATA for I2C_STATE */ +#define I2C_STATE_STATE_DATAACK (_I2C_STATE_STATE_DATAACK << 5) /* Shifted mode DATAACK for I2C_STATE */ + +/* Bit fields for I2C STATUS */ + +#define _I2C_STATUS_RESETVALUE 0x00000080UL /* Default value for I2C_STATUS */ +#define _I2C_STATUS_MASK 0x000001FFUL /* Mask for I2C_STATUS */ + +#define I2C_STATUS_PSTART (0x1UL << 0) /* Pending START */ +#define _I2C_STATUS_PSTART_SHIFT 0 /* Shift value for I2C_PSTART */ +#define _I2C_STATUS_PSTART_MASK 0x1UL /* Bit mask for I2C_PSTART */ +#define _I2C_STATUS_PSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PSTART_DEFAULT (_I2C_STATUS_PSTART_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PSTOP (0x1UL << 1) /* Pending STOP */ +#define _I2C_STATUS_PSTOP_SHIFT 1 /* Shift value for I2C_PSTOP */ +#define _I2C_STATUS_PSTOP_MASK 0x2UL /* Bit mask for I2C_PSTOP */ +#define _I2C_STATUS_PSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PSTOP_DEFAULT (_I2C_STATUS_PSTOP_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PACK (0x1UL << 2) /* Pending ACK */ +#define _I2C_STATUS_PACK_SHIFT 2 /* Shift value for I2C_PACK */ +#define _I2C_STATUS_PACK_MASK 0x4UL /* Bit mask for I2C_PACK */ +#define _I2C_STATUS_PACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PACK_DEFAULT (_I2C_STATUS_PACK_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PNACK (0x1UL << 3) /* Pending NACK */ +#define _I2C_STATUS_PNACK_SHIFT 3 /* Shift value for I2C_PNACK */ +#define _I2C_STATUS_PNACK_MASK 0x8UL /* Bit mask for I2C_PNACK */ +#define _I2C_STATUS_PNACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PNACK_DEFAULT (_I2C_STATUS_PNACK_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PCONT (0x1UL << 4) /* Pending continue */ +#define _I2C_STATUS_PCONT_SHIFT 4 /* Shift value for I2C_PCONT */ +#define _I2C_STATUS_PCONT_MASK 0x10UL /* Bit mask for I2C_PCONT */ +#define _I2C_STATUS_PCONT_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PCONT_DEFAULT (_I2C_STATUS_PCONT_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PABORT (0x1UL << 5) /* Pending abort */ +#define _I2C_STATUS_PABORT_SHIFT 5 /* Shift value for I2C_PABORT */ +#define _I2C_STATUS_PABORT_MASK 0x20UL /* Bit mask for I2C_PABORT */ +#define _I2C_STATUS_PABORT_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_PABORT_DEFAULT (_I2C_STATUS_PABORT_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_TXC (0x1UL << 6) /* TX Complete */ +#define _I2C_STATUS_TXC_SHIFT 6 /* Shift value for I2C_TXC */ +#define _I2C_STATUS_TXC_MASK 0x40UL /* Bit mask for I2C_TXC */ +#define _I2C_STATUS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_TXC_DEFAULT (_I2C_STATUS_TXC_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_TXBL (0x1UL << 7) /* TX Buffer Level */ +#define _I2C_STATUS_TXBL_SHIFT 7 /* Shift value for I2C_TXBL */ +#define _I2C_STATUS_TXBL_MASK 0x80UL /* Bit mask for I2C_TXBL */ +#define _I2C_STATUS_TXBL_DEFAULT 0x00000001UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_TXBL_DEFAULT (_I2C_STATUS_TXBL_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_RXDATAV (0x1UL << 8) /* RX Data Valid */ +#define _I2C_STATUS_RXDATAV_SHIFT 8 /* Shift value for I2C_RXDATAV */ +#define _I2C_STATUS_RXDATAV_MASK 0x100UL /* Bit mask for I2C_RXDATAV */ +#define _I2C_STATUS_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_STATUS */ +#define I2C_STATUS_RXDATAV_DEFAULT (_I2C_STATUS_RXDATAV_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_STATUS */ + +/* Bit fields for I2C CLKDIV */ + +#define _I2C_CLKDIV_RESETVALUE 0x00000000UL /* Default value for I2C_CLKDIV */ +#define _I2C_CLKDIV_MASK 0x000001FFUL /* Mask for I2C_CLKDIV */ + +#define _I2C_CLKDIV_DIV_SHIFT 0 /* Shift value for I2C_DIV */ +#define _I2C_CLKDIV_DIV_MASK 0x1FFUL /* Bit mask for I2C_DIV */ +#define _I2C_CLKDIV_DIV_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_CLKDIV */ +#define I2C_CLKDIV_DIV_DEFAULT (_I2C_CLKDIV_DIV_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_CLKDIV */ + +/* Bit fields for I2C SADDR */ + +#define _I2C_SADDR_RESETVALUE 0x00000000UL /* Default value for I2C_SADDR */ +#define _I2C_SADDR_MASK 0x000000FEUL /* Mask for I2C_SADDR */ + +#define _I2C_SADDR_ADDR_SHIFT 1 /* Shift value for I2C_ADDR */ +#define _I2C_SADDR_ADDR_MASK 0xFEUL /* Bit mask for I2C_ADDR */ +#define _I2C_SADDR_ADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_SADDR */ +#define I2C_SADDR_ADDR_DEFAULT (_I2C_SADDR_ADDR_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_SADDR */ + +/* Bit fields for I2C SADDRMASK */ + +#define _I2C_SADDRMASK_RESETVALUE 0x00000000UL /* Default value for I2C_SADDRMASK */ +#define _I2C_SADDRMASK_MASK 0x000000FEUL /* Mask for I2C_SADDRMASK */ + +#define _I2C_SADDRMASK_MASK_SHIFT 1 /* Shift value for I2C_MASK */ +#define _I2C_SADDRMASK_MASK_MASK 0xFEUL /* Bit mask for I2C_MASK */ +#define _I2C_SADDRMASK_MASK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_SADDRMASK */ +#define I2C_SADDRMASK_MASK_DEFAULT (_I2C_SADDRMASK_MASK_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_SADDRMASK */ + +/* Bit fields for I2C RXDATA */ + +#define _I2C_RXDATA_RESETVALUE 0x00000000UL /* Default value for I2C_RXDATA */ +#define _I2C_RXDATA_MASK 0x000000FFUL /* Mask for I2C_RXDATA */ + +#define _I2C_RXDATA_RXDATA_SHIFT 0 /* Shift value for I2C_RXDATA */ +#define _I2C_RXDATA_RXDATA_MASK 0xFFUL /* Bit mask for I2C_RXDATA */ +#define _I2C_RXDATA_RXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_RXDATA */ +#define I2C_RXDATA_RXDATA_DEFAULT (_I2C_RXDATA_RXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_RXDATA */ + +/* Bit fields for I2C RXDATAP */ + +#define _I2C_RXDATAP_RESETVALUE 0x00000000UL /* Default value for I2C_RXDATAP */ +#define _I2C_RXDATAP_MASK 0x000000FFUL /* Mask for I2C_RXDATAP */ + +#define _I2C_RXDATAP_RXDATAP_SHIFT 0 /* Shift value for I2C_RXDATAP */ +#define _I2C_RXDATAP_RXDATAP_MASK 0xFFUL /* Bit mask for I2C_RXDATAP */ +#define _I2C_RXDATAP_RXDATAP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_RXDATAP */ +#define I2C_RXDATAP_RXDATAP_DEFAULT (_I2C_RXDATAP_RXDATAP_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_RXDATAP */ + +/* Bit fields for I2C TXDATA */ + +#define _I2C_TXDATA_RESETVALUE 0x00000000UL /* Default value for I2C_TXDATA */ +#define _I2C_TXDATA_MASK 0x000000FFUL /* Mask for I2C_TXDATA */ + +#define _I2C_TXDATA_TXDATA_SHIFT 0 /* Shift value for I2C_TXDATA */ +#define _I2C_TXDATA_TXDATA_MASK 0xFFUL /* Bit mask for I2C_TXDATA */ +#define _I2C_TXDATA_TXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_TXDATA */ +#define I2C_TXDATA_TXDATA_DEFAULT (_I2C_TXDATA_TXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_TXDATA */ + +/* Bit fields for I2C IF */ + +#define _I2C_IF_RESETVALUE 0x00000010UL /* Default value for I2C_IF */ +#define _I2C_IF_MASK 0x0001FFFFUL /* Mask for I2C_IF */ + +#define I2C_IF_START (0x1UL << 0) /* START condition Interrupt Flag */ +#define _I2C_IF_START_SHIFT 0 /* Shift value for I2C_START */ +#define _I2C_IF_START_MASK 0x1UL /* Bit mask for I2C_START */ +#define _I2C_IF_START_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_START_DEFAULT (_I2C_IF_START_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_RSTART (0x1UL << 1) /* Repeated START condition Interrupt Flag */ +#define _I2C_IF_RSTART_SHIFT 1 /* Shift value for I2C_RSTART */ +#define _I2C_IF_RSTART_MASK 0x2UL /* Bit mask for I2C_RSTART */ +#define _I2C_IF_RSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_RSTART_DEFAULT (_I2C_IF_RSTART_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_ADDR (0x1UL << 2) /* Address Interrupt Flag */ +#define _I2C_IF_ADDR_SHIFT 2 /* Shift value for I2C_ADDR */ +#define _I2C_IF_ADDR_MASK 0x4UL /* Bit mask for I2C_ADDR */ +#define _I2C_IF_ADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_ADDR_DEFAULT (_I2C_IF_ADDR_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_TXC (0x1UL << 3) /* Transfer Completed Interrupt Flag */ +#define _I2C_IF_TXC_SHIFT 3 /* Shift value for I2C_TXC */ +#define _I2C_IF_TXC_MASK 0x8UL /* Bit mask for I2C_TXC */ +#define _I2C_IF_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_TXC_DEFAULT (_I2C_IF_TXC_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_TXBL (0x1UL << 4) /* Transmit Buffer Level Interrupt Flag */ +#define _I2C_IF_TXBL_SHIFT 4 /* Shift value for I2C_TXBL */ +#define _I2C_IF_TXBL_MASK 0x10UL /* Bit mask for I2C_TXBL */ +#define _I2C_IF_TXBL_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_TXBL_DEFAULT (_I2C_IF_TXBL_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_RXDATAV (0x1UL << 5) /* Receive Data Valid Interrupt Flag */ +#define _I2C_IF_RXDATAV_SHIFT 5 /* Shift value for I2C_RXDATAV */ +#define _I2C_IF_RXDATAV_MASK 0x20UL /* Bit mask for I2C_RXDATAV */ +#define _I2C_IF_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_RXDATAV_DEFAULT (_I2C_IF_RXDATAV_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_ACK (0x1UL << 6) /* Acknowledge Received Interrupt Flag */ +#define _I2C_IF_ACK_SHIFT 6 /* Shift value for I2C_ACK */ +#define _I2C_IF_ACK_MASK 0x40UL /* Bit mask for I2C_ACK */ +#define _I2C_IF_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_ACK_DEFAULT (_I2C_IF_ACK_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_NACK (0x1UL << 7) /* Not Acknowledge Received Interrupt Flag */ +#define _I2C_IF_NACK_SHIFT 7 /* Shift value for I2C_NACK */ +#define _I2C_IF_NACK_MASK 0x80UL /* Bit mask for I2C_NACK */ +#define _I2C_IF_NACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_NACK_DEFAULT (_I2C_IF_NACK_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_MSTOP (0x1UL << 8) /* Master STOP Condition Interrupt Flag */ +#define _I2C_IF_MSTOP_SHIFT 8 /* Shift value for I2C_MSTOP */ +#define _I2C_IF_MSTOP_MASK 0x100UL /* Bit mask for I2C_MSTOP */ +#define _I2C_IF_MSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_MSTOP_DEFAULT (_I2C_IF_MSTOP_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_ARBLOST (0x1UL << 9) /* Arbitration Lost Interrupt Flag */ +#define _I2C_IF_ARBLOST_SHIFT 9 /* Shift value for I2C_ARBLOST */ +#define _I2C_IF_ARBLOST_MASK 0x200UL /* Bit mask for I2C_ARBLOST */ +#define _I2C_IF_ARBLOST_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_ARBLOST_DEFAULT (_I2C_IF_ARBLOST_DEFAULT << 9) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_BUSERR (0x1UL << 10) /* Bus Error Interrupt Flag */ +#define _I2C_IF_BUSERR_SHIFT 10 /* Shift value for I2C_BUSERR */ +#define _I2C_IF_BUSERR_MASK 0x400UL /* Bit mask for I2C_BUSERR */ +#define _I2C_IF_BUSERR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_BUSERR_DEFAULT (_I2C_IF_BUSERR_DEFAULT << 10) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_BUSHOLD (0x1UL << 11) /* Bus Held Interrupt Flag */ +#define _I2C_IF_BUSHOLD_SHIFT 11 /* Shift value for I2C_BUSHOLD */ +#define _I2C_IF_BUSHOLD_MASK 0x800UL /* Bit mask for I2C_BUSHOLD */ +#define _I2C_IF_BUSHOLD_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_BUSHOLD_DEFAULT (_I2C_IF_BUSHOLD_DEFAULT << 11) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_TXOF (0x1UL << 12) /* Transmit Buffer Overflow Interrupt Flag */ +#define _I2C_IF_TXOF_SHIFT 12 /* Shift value for I2C_TXOF */ +#define _I2C_IF_TXOF_MASK 0x1000UL /* Bit mask for I2C_TXOF */ +#define _I2C_IF_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_TXOF_DEFAULT (_I2C_IF_TXOF_DEFAULT << 12) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_RXUF (0x1UL << 13) /* Receive Buffer Underflow Interrupt Flag */ +#define _I2C_IF_RXUF_SHIFT 13 /* Shift value for I2C_RXUF */ +#define _I2C_IF_RXUF_MASK 0x2000UL /* Bit mask for I2C_RXUF */ +#define _I2C_IF_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_RXUF_DEFAULT (_I2C_IF_RXUF_DEFAULT << 13) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_BITO (0x1UL << 14) /* Bus Idle Timeout Interrupt Flag */ +#define _I2C_IF_BITO_SHIFT 14 /* Shift value for I2C_BITO */ +#define _I2C_IF_BITO_MASK 0x4000UL /* Bit mask for I2C_BITO */ +#define _I2C_IF_BITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_BITO_DEFAULT (_I2C_IF_BITO_DEFAULT << 14) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_CLTO (0x1UL << 15) /* Clock Low Timeout Interrupt Flag */ +#define _I2C_IF_CLTO_SHIFT 15 /* Shift value for I2C_CLTO */ +#define _I2C_IF_CLTO_MASK 0x8000UL /* Bit mask for I2C_CLTO */ +#define _I2C_IF_CLTO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_CLTO_DEFAULT (_I2C_IF_CLTO_DEFAULT << 15) /* Shifted mode DEFAULT for I2C_IF */ +#define I2C_IF_SSTOP (0x1UL << 16) /* Slave STOP condition Interrupt Flag */ +#define _I2C_IF_SSTOP_SHIFT 16 /* Shift value for I2C_SSTOP */ +#define _I2C_IF_SSTOP_MASK 0x10000UL /* Bit mask for I2C_SSTOP */ +#define _I2C_IF_SSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IF */ +#define I2C_IF_SSTOP_DEFAULT (_I2C_IF_SSTOP_DEFAULT << 16) /* Shifted mode DEFAULT for I2C_IF */ + +/* Bit fields for I2C IFS */ + +#define _I2C_IFS_RESETVALUE 0x00000000UL /* Default value for I2C_IFS */ +#define _I2C_IFS_MASK 0x0001FFCFUL /* Mask for I2C_IFS */ + +#define I2C_IFS_START (0x1UL << 0) /* Set START Interrupt Flag */ +#define _I2C_IFS_START_SHIFT 0 /* Shift value for I2C_START */ +#define _I2C_IFS_START_MASK 0x1UL /* Bit mask for I2C_START */ +#define _I2C_IFS_START_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_START_DEFAULT (_I2C_IFS_START_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_RSTART (0x1UL << 1) /* Set Repeated START Interrupt Flag */ +#define _I2C_IFS_RSTART_SHIFT 1 /* Shift value for I2C_RSTART */ +#define _I2C_IFS_RSTART_MASK 0x2UL /* Bit mask for I2C_RSTART */ +#define _I2C_IFS_RSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_RSTART_DEFAULT (_I2C_IFS_RSTART_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ADDR (0x1UL << 2) /* Set Address Interrupt Flag */ +#define _I2C_IFS_ADDR_SHIFT 2 /* Shift value for I2C_ADDR */ +#define _I2C_IFS_ADDR_MASK 0x4UL /* Bit mask for I2C_ADDR */ +#define _I2C_IFS_ADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ADDR_DEFAULT (_I2C_IFS_ADDR_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_TXC (0x1UL << 3) /* Set Transfer Completed Interrupt Flag */ +#define _I2C_IFS_TXC_SHIFT 3 /* Shift value for I2C_TXC */ +#define _I2C_IFS_TXC_MASK 0x8UL /* Bit mask for I2C_TXC */ +#define _I2C_IFS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_TXC_DEFAULT (_I2C_IFS_TXC_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ACK (0x1UL << 6) /* Set Acknowledge Received Interrupt Flag */ +#define _I2C_IFS_ACK_SHIFT 6 /* Shift value for I2C_ACK */ +#define _I2C_IFS_ACK_MASK 0x40UL /* Bit mask for I2C_ACK */ +#define _I2C_IFS_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ACK_DEFAULT (_I2C_IFS_ACK_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_NACK (0x1UL << 7) /* Set Not Acknowledge Received Interrupt Flag */ +#define _I2C_IFS_NACK_SHIFT 7 /* Shift value for I2C_NACK */ +#define _I2C_IFS_NACK_MASK 0x80UL /* Bit mask for I2C_NACK */ +#define _I2C_IFS_NACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_NACK_DEFAULT (_I2C_IFS_NACK_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_MSTOP (0x1UL << 8) /* Set MSTOP Interrupt Flag */ +#define _I2C_IFS_MSTOP_SHIFT 8 /* Shift value for I2C_MSTOP */ +#define _I2C_IFS_MSTOP_MASK 0x100UL /* Bit mask for I2C_MSTOP */ +#define _I2C_IFS_MSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_MSTOP_DEFAULT (_I2C_IFS_MSTOP_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ARBLOST (0x1UL << 9) /* Set Arbitration Lost Interrupt Flag */ +#define _I2C_IFS_ARBLOST_SHIFT 9 /* Shift value for I2C_ARBLOST */ +#define _I2C_IFS_ARBLOST_MASK 0x200UL /* Bit mask for I2C_ARBLOST */ +#define _I2C_IFS_ARBLOST_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_ARBLOST_DEFAULT (_I2C_IFS_ARBLOST_DEFAULT << 9) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BUSERR (0x1UL << 10) /* Set Bus Error Interrupt Flag */ +#define _I2C_IFS_BUSERR_SHIFT 10 /* Shift value for I2C_BUSERR */ +#define _I2C_IFS_BUSERR_MASK 0x400UL /* Bit mask for I2C_BUSERR */ +#define _I2C_IFS_BUSERR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BUSERR_DEFAULT (_I2C_IFS_BUSERR_DEFAULT << 10) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BUSHOLD (0x1UL << 11) /* Set Bus Held Interrupt Flag */ +#define _I2C_IFS_BUSHOLD_SHIFT 11 /* Shift value for I2C_BUSHOLD */ +#define _I2C_IFS_BUSHOLD_MASK 0x800UL /* Bit mask for I2C_BUSHOLD */ +#define _I2C_IFS_BUSHOLD_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BUSHOLD_DEFAULT (_I2C_IFS_BUSHOLD_DEFAULT << 11) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_TXOF (0x1UL << 12) /* Set Transmit Buffer Overflow Interrupt Flag */ +#define _I2C_IFS_TXOF_SHIFT 12 /* Shift value for I2C_TXOF */ +#define _I2C_IFS_TXOF_MASK 0x1000UL /* Bit mask for I2C_TXOF */ +#define _I2C_IFS_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_TXOF_DEFAULT (_I2C_IFS_TXOF_DEFAULT << 12) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_RXUF (0x1UL << 13) /* Set Receive Buffer Underflow Interrupt Flag */ +#define _I2C_IFS_RXUF_SHIFT 13 /* Shift value for I2C_RXUF */ +#define _I2C_IFS_RXUF_MASK 0x2000UL /* Bit mask for I2C_RXUF */ +#define _I2C_IFS_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_RXUF_DEFAULT (_I2C_IFS_RXUF_DEFAULT << 13) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BITO (0x1UL << 14) /* Set Bus Idle Timeout Interrupt Flag */ +#define _I2C_IFS_BITO_SHIFT 14 /* Shift value for I2C_BITO */ +#define _I2C_IFS_BITO_MASK 0x4000UL /* Bit mask for I2C_BITO */ +#define _I2C_IFS_BITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_BITO_DEFAULT (_I2C_IFS_BITO_DEFAULT << 14) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_CLTO (0x1UL << 15) /* Set Clock Low Interrupt Flag */ +#define _I2C_IFS_CLTO_SHIFT 15 /* Shift value for I2C_CLTO */ +#define _I2C_IFS_CLTO_MASK 0x8000UL /* Bit mask for I2C_CLTO */ +#define _I2C_IFS_CLTO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_CLTO_DEFAULT (_I2C_IFS_CLTO_DEFAULT << 15) /* Shifted mode DEFAULT for I2C_IFS */ +#define I2C_IFS_SSTOP (0x1UL << 16) /* Set SSTOP Interrupt Flag */ +#define _I2C_IFS_SSTOP_SHIFT 16 /* Shift value for I2C_SSTOP */ +#define _I2C_IFS_SSTOP_MASK 0x10000UL /* Bit mask for I2C_SSTOP */ +#define _I2C_IFS_SSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFS */ +#define I2C_IFS_SSTOP_DEFAULT (_I2C_IFS_SSTOP_DEFAULT << 16) /* Shifted mode DEFAULT for I2C_IFS */ + +/* Bit fields for I2C IFC */ + +#define _I2C_IFC_RESETVALUE 0x00000000UL /* Default value for I2C_IFC */ +#define _I2C_IFC_MASK 0x0001FFCFUL /* Mask for I2C_IFC */ + +#define I2C_IFC_START (0x1UL << 0) /* Clear START Interrupt Flag */ +#define _I2C_IFC_START_SHIFT 0 /* Shift value for I2C_START */ +#define _I2C_IFC_START_MASK 0x1UL /* Bit mask for I2C_START */ +#define _I2C_IFC_START_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_START_DEFAULT (_I2C_IFC_START_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_RSTART (0x1UL << 1) /* Clear Repeated START Interrupt Flag */ +#define _I2C_IFC_RSTART_SHIFT 1 /* Shift value for I2C_RSTART */ +#define _I2C_IFC_RSTART_MASK 0x2UL /* Bit mask for I2C_RSTART */ +#define _I2C_IFC_RSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_RSTART_DEFAULT (_I2C_IFC_RSTART_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ADDR (0x1UL << 2) /* Clear Address Interrupt Flag */ +#define _I2C_IFC_ADDR_SHIFT 2 /* Shift value for I2C_ADDR */ +#define _I2C_IFC_ADDR_MASK 0x4UL /* Bit mask for I2C_ADDR */ +#define _I2C_IFC_ADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ADDR_DEFAULT (_I2C_IFC_ADDR_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_TXC (0x1UL << 3) /* Clear Transfer Completed Interrupt Flag */ +#define _I2C_IFC_TXC_SHIFT 3 /* Shift value for I2C_TXC */ +#define _I2C_IFC_TXC_MASK 0x8UL /* Bit mask for I2C_TXC */ +#define _I2C_IFC_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_TXC_DEFAULT (_I2C_IFC_TXC_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ACK (0x1UL << 6) /* Clear Acknowledge Received Interrupt Flag */ +#define _I2C_IFC_ACK_SHIFT 6 /* Shift value for I2C_ACK */ +#define _I2C_IFC_ACK_MASK 0x40UL /* Bit mask for I2C_ACK */ +#define _I2C_IFC_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ACK_DEFAULT (_I2C_IFC_ACK_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_NACK (0x1UL << 7) /* Clear Not Acknowledge Received Interrupt Flag */ +#define _I2C_IFC_NACK_SHIFT 7 /* Shift value for I2C_NACK */ +#define _I2C_IFC_NACK_MASK 0x80UL /* Bit mask for I2C_NACK */ +#define _I2C_IFC_NACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_NACK_DEFAULT (_I2C_IFC_NACK_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_MSTOP (0x1UL << 8) /* Clear MSTOP Interrupt Flag */ +#define _I2C_IFC_MSTOP_SHIFT 8 /* Shift value for I2C_MSTOP */ +#define _I2C_IFC_MSTOP_MASK 0x100UL /* Bit mask for I2C_MSTOP */ +#define _I2C_IFC_MSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_MSTOP_DEFAULT (_I2C_IFC_MSTOP_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ARBLOST (0x1UL << 9) /* Clear Arbitration Lost Interrupt Flag */ +#define _I2C_IFC_ARBLOST_SHIFT 9 /* Shift value for I2C_ARBLOST */ +#define _I2C_IFC_ARBLOST_MASK 0x200UL /* Bit mask for I2C_ARBLOST */ +#define _I2C_IFC_ARBLOST_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_ARBLOST_DEFAULT (_I2C_IFC_ARBLOST_DEFAULT << 9) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BUSERR (0x1UL << 10) /* Clear Bus Error Interrupt Flag */ +#define _I2C_IFC_BUSERR_SHIFT 10 /* Shift value for I2C_BUSERR */ +#define _I2C_IFC_BUSERR_MASK 0x400UL /* Bit mask for I2C_BUSERR */ +#define _I2C_IFC_BUSERR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BUSERR_DEFAULT (_I2C_IFC_BUSERR_DEFAULT << 10) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BUSHOLD (0x1UL << 11) /* Clear Bus Held Interrupt Flag */ +#define _I2C_IFC_BUSHOLD_SHIFT 11 /* Shift value for I2C_BUSHOLD */ +#define _I2C_IFC_BUSHOLD_MASK 0x800UL /* Bit mask for I2C_BUSHOLD */ +#define _I2C_IFC_BUSHOLD_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BUSHOLD_DEFAULT (_I2C_IFC_BUSHOLD_DEFAULT << 11) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_TXOF (0x1UL << 12) /* Clear Transmit Buffer Overflow Interrupt Flag */ +#define _I2C_IFC_TXOF_SHIFT 12 /* Shift value for I2C_TXOF */ +#define _I2C_IFC_TXOF_MASK 0x1000UL /* Bit mask for I2C_TXOF */ +#define _I2C_IFC_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_TXOF_DEFAULT (_I2C_IFC_TXOF_DEFAULT << 12) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_RXUF (0x1UL << 13) /* Clear Receive Buffer Underflow Interrupt Flag */ +#define _I2C_IFC_RXUF_SHIFT 13 /* Shift value for I2C_RXUF */ +#define _I2C_IFC_RXUF_MASK 0x2000UL /* Bit mask for I2C_RXUF */ +#define _I2C_IFC_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_RXUF_DEFAULT (_I2C_IFC_RXUF_DEFAULT << 13) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BITO (0x1UL << 14) /* Clear Bus Idle Timeout Interrupt Flag */ +#define _I2C_IFC_BITO_SHIFT 14 /* Shift value for I2C_BITO */ +#define _I2C_IFC_BITO_MASK 0x4000UL /* Bit mask for I2C_BITO */ +#define _I2C_IFC_BITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_BITO_DEFAULT (_I2C_IFC_BITO_DEFAULT << 14) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_CLTO (0x1UL << 15) /* Clear Clock Low Interrupt Flag */ +#define _I2C_IFC_CLTO_SHIFT 15 /* Shift value for I2C_CLTO */ +#define _I2C_IFC_CLTO_MASK 0x8000UL /* Bit mask for I2C_CLTO */ +#define _I2C_IFC_CLTO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_CLTO_DEFAULT (_I2C_IFC_CLTO_DEFAULT << 15) /* Shifted mode DEFAULT for I2C_IFC */ +#define I2C_IFC_SSTOP (0x1UL << 16) /* Clear SSTOP Interrupt Flag */ +#define _I2C_IFC_SSTOP_SHIFT 16 /* Shift value for I2C_SSTOP */ +#define _I2C_IFC_SSTOP_MASK 0x10000UL /* Bit mask for I2C_SSTOP */ +#define _I2C_IFC_SSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IFC */ +#define I2C_IFC_SSTOP_DEFAULT (_I2C_IFC_SSTOP_DEFAULT << 16) /* Shifted mode DEFAULT for I2C_IFC */ + +/* Bit fields for I2C IEN */ + +#define _I2C_IEN_RESETVALUE 0x00000000UL /* Default value for I2C_IEN */ +#define _I2C_IEN_MASK 0x0001FFFFUL /* Mask for I2C_IEN */ + +#define I2C_IEN_START (0x1UL << 0) /* START Condition Interrupt Enable */ +#define _I2C_IEN_START_SHIFT 0 /* Shift value for I2C_START */ +#define _I2C_IEN_START_MASK 0x1UL /* Bit mask for I2C_START */ +#define _I2C_IEN_START_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_START_DEFAULT (_I2C_IEN_START_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RSTART (0x1UL << 1) /* Repeated START condition Interrupt Enable */ +#define _I2C_IEN_RSTART_SHIFT 1 /* Shift value for I2C_RSTART */ +#define _I2C_IEN_RSTART_MASK 0x2UL /* Bit mask for I2C_RSTART */ +#define _I2C_IEN_RSTART_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RSTART_DEFAULT (_I2C_IEN_RSTART_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ADDR (0x1UL << 2) /* Address Interrupt Enable */ +#define _I2C_IEN_ADDR_SHIFT 2 /* Shift value for I2C_ADDR */ +#define _I2C_IEN_ADDR_MASK 0x4UL /* Bit mask for I2C_ADDR */ +#define _I2C_IEN_ADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ADDR_DEFAULT (_I2C_IEN_ADDR_DEFAULT << 2) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXC (0x1UL << 3) /* Transfer Completed Interrupt Enable */ +#define _I2C_IEN_TXC_SHIFT 3 /* Shift value for I2C_TXC */ +#define _I2C_IEN_TXC_MASK 0x8UL /* Bit mask for I2C_TXC */ +#define _I2C_IEN_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXC_DEFAULT (_I2C_IEN_TXC_DEFAULT << 3) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXBL (0x1UL << 4) /* Transmit Buffer level Interrupt Enable */ +#define _I2C_IEN_TXBL_SHIFT 4 /* Shift value for I2C_TXBL */ +#define _I2C_IEN_TXBL_MASK 0x10UL /* Bit mask for I2C_TXBL */ +#define _I2C_IEN_TXBL_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXBL_DEFAULT (_I2C_IEN_TXBL_DEFAULT << 4) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RXDATAV (0x1UL << 5) /* Receive Data Valid Interrupt Enable */ +#define _I2C_IEN_RXDATAV_SHIFT 5 /* Shift value for I2C_RXDATAV */ +#define _I2C_IEN_RXDATAV_MASK 0x20UL /* Bit mask for I2C_RXDATAV */ +#define _I2C_IEN_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RXDATAV_DEFAULT (_I2C_IEN_RXDATAV_DEFAULT << 5) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ACK (0x1UL << 6) /* Acknowledge Received Interrupt Enable */ +#define _I2C_IEN_ACK_SHIFT 6 /* Shift value for I2C_ACK */ +#define _I2C_IEN_ACK_MASK 0x40UL /* Bit mask for I2C_ACK */ +#define _I2C_IEN_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ACK_DEFAULT (_I2C_IEN_ACK_DEFAULT << 6) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_NACK (0x1UL << 7) /* Not Acknowledge Received Interrupt Enable */ +#define _I2C_IEN_NACK_SHIFT 7 /* Shift value for I2C_NACK */ +#define _I2C_IEN_NACK_MASK 0x80UL /* Bit mask for I2C_NACK */ +#define _I2C_IEN_NACK_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_NACK_DEFAULT (_I2C_IEN_NACK_DEFAULT << 7) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_MSTOP (0x1UL << 8) /* MSTOP Interrupt Enable */ +#define _I2C_IEN_MSTOP_SHIFT 8 /* Shift value for I2C_MSTOP */ +#define _I2C_IEN_MSTOP_MASK 0x100UL /* Bit mask for I2C_MSTOP */ +#define _I2C_IEN_MSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_MSTOP_DEFAULT (_I2C_IEN_MSTOP_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ARBLOST (0x1UL << 9) /* Arbitration Lost Interrupt Enable */ +#define _I2C_IEN_ARBLOST_SHIFT 9 /* Shift value for I2C_ARBLOST */ +#define _I2C_IEN_ARBLOST_MASK 0x200UL /* Bit mask for I2C_ARBLOST */ +#define _I2C_IEN_ARBLOST_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_ARBLOST_DEFAULT (_I2C_IEN_ARBLOST_DEFAULT << 9) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BUSERR (0x1UL << 10) /* Bus Error Interrupt Enable */ +#define _I2C_IEN_BUSERR_SHIFT 10 /* Shift value for I2C_BUSERR */ +#define _I2C_IEN_BUSERR_MASK 0x400UL /* Bit mask for I2C_BUSERR */ +#define _I2C_IEN_BUSERR_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BUSERR_DEFAULT (_I2C_IEN_BUSERR_DEFAULT << 10) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BUSHOLD (0x1UL << 11) /* Bus Held Interrupt Enable */ +#define _I2C_IEN_BUSHOLD_SHIFT 11 /* Shift value for I2C_BUSHOLD */ +#define _I2C_IEN_BUSHOLD_MASK 0x800UL /* Bit mask for I2C_BUSHOLD */ +#define _I2C_IEN_BUSHOLD_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BUSHOLD_DEFAULT (_I2C_IEN_BUSHOLD_DEFAULT << 11) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXOF (0x1UL << 12) /* Transmit Buffer Overflow Interrupt Enable */ +#define _I2C_IEN_TXOF_SHIFT 12 /* Shift value for I2C_TXOF */ +#define _I2C_IEN_TXOF_MASK 0x1000UL /* Bit mask for I2C_TXOF */ +#define _I2C_IEN_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_TXOF_DEFAULT (_I2C_IEN_TXOF_DEFAULT << 12) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RXUF (0x1UL << 13) /* Receive Buffer Underflow Interrupt Enable */ +#define _I2C_IEN_RXUF_SHIFT 13 /* Shift value for I2C_RXUF */ +#define _I2C_IEN_RXUF_MASK 0x2000UL /* Bit mask for I2C_RXUF */ +#define _I2C_IEN_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_RXUF_DEFAULT (_I2C_IEN_RXUF_DEFAULT << 13) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BITO (0x1UL << 14) /* Bus Idle Timeout Interrupt Enable */ +#define _I2C_IEN_BITO_SHIFT 14 /* Shift value for I2C_BITO */ +#define _I2C_IEN_BITO_MASK 0x4000UL /* Bit mask for I2C_BITO */ +#define _I2C_IEN_BITO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_BITO_DEFAULT (_I2C_IEN_BITO_DEFAULT << 14) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_CLTO (0x1UL << 15) /* Clock Low Interrupt Enable */ +#define _I2C_IEN_CLTO_SHIFT 15 /* Shift value for I2C_CLTO */ +#define _I2C_IEN_CLTO_MASK 0x8000UL /* Bit mask for I2C_CLTO */ +#define _I2C_IEN_CLTO_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_CLTO_DEFAULT (_I2C_IEN_CLTO_DEFAULT << 15) /* Shifted mode DEFAULT for I2C_IEN */ +#define I2C_IEN_SSTOP (0x1UL << 16) /* SSTOP Interrupt Enable */ +#define _I2C_IEN_SSTOP_SHIFT 16 /* Shift value for I2C_SSTOP */ +#define _I2C_IEN_SSTOP_MASK 0x10000UL /* Bit mask for I2C_SSTOP */ +#define _I2C_IEN_SSTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_IEN */ +#define I2C_IEN_SSTOP_DEFAULT (_I2C_IEN_SSTOP_DEFAULT << 16) /* Shifted mode DEFAULT for I2C_IEN */ + +/* Bit fields for I2C ROUTE */ + +#define _I2C_ROUTE_RESETVALUE 0x00000000UL /* Default value for I2C_ROUTE */ +#define _I2C_ROUTE_MASK 0x00000703UL /* Mask for I2C_ROUTE */ + +#define I2C_ROUTE_SDAPEN (0x1UL << 0) /* SDA Pin Enable */ +#define _I2C_ROUTE_SDAPEN_SHIFT 0 /* Shift value for I2C_SDAPEN */ +#define _I2C_ROUTE_SDAPEN_MASK 0x1UL /* Bit mask for I2C_SDAPEN */ +#define _I2C_ROUTE_SDAPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_ROUTE */ +#define I2C_ROUTE_SDAPEN_DEFAULT (_I2C_ROUTE_SDAPEN_DEFAULT << 0) /* Shifted mode DEFAULT for I2C_ROUTE */ +#define I2C_ROUTE_SCLPEN (0x1UL << 1) /* SCL Pin Enable */ +#define _I2C_ROUTE_SCLPEN_SHIFT 1 /* Shift value for I2C_SCLPEN */ +#define _I2C_ROUTE_SCLPEN_MASK 0x2UL /* Bit mask for I2C_SCLPEN */ +#define _I2C_ROUTE_SCLPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_ROUTE */ +#define I2C_ROUTE_SCLPEN_DEFAULT (_I2C_ROUTE_SCLPEN_DEFAULT << 1) /* Shifted mode DEFAULT for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_SHIFT 8 /* Shift value for I2C_LOCATION */ +#define _I2C_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for I2C_LOCATION */ +#define _I2C_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC4 0x00000004UL /* Mode LOC4 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC5 0x00000005UL /* Mode LOC5 for I2C_ROUTE */ +#define _I2C_ROUTE_LOCATION_LOC6 0x00000006UL /* Mode LOC6 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC0 (_I2C_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_DEFAULT (_I2C_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC1 (_I2C_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC2 (_I2C_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC3 (_I2C_ROUTE_LOCATION_LOC3 << 8) /* Shifted mode LOC3 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC4 (_I2C_ROUTE_LOCATION_LOC4 << 8) /* Shifted mode LOC4 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC5 (_I2C_ROUTE_LOCATION_LOC5 << 8) /* Shifted mode LOC5 for I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_LOC6 (_I2C_ROUTE_LOCATION_LOC6 << 8) /* Shifted mode LOC6 for I2C_ROUTE */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_I2C_H */ diff --git a/arch/arm/src/efm32/chip/efm32_lcd.h b/arch/arm/src/efm32/chip/efm32_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..f00a4706f3f0eb1c0a58e5b00aac67f2bb8068a9 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_lcd.h @@ -0,0 +1,714 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_lcd.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LCD_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LCD_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* LCD Register Offsets ********************************************************************************************************/ + +#define EFM32_LCD_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_LCD_DISPCTRL_OFFSET 0x0004 /* Display Control Register */ +#define EFM32_LCD_SEGEN_OFFSET 0x0008 /* Segment Enable Register */ +#define EFM32_LCD_BACTRL_OFFSET 0x000c /* Blink and Animation Control Register */ +#define EFM32_LCD_STATUS_OFFSET 0x0010 /* Status Register */ +#define EFM32_LCD_AREGA_OFFSET 0x0014 /* Animation Register A */ +#define EFM32_LCD_AREGB_OFFSET 0x0018 /* Animation Register B */ +#define EFM32_LCD_IF_OFFSET 0x001c /* Interrupt Flag Register */ +#define EFM32_LCD_IFS_OFFSET 0x0020 /* Interrupt Flag Set Register */ +#define EFM32_LCD_IFC_OFFSET 0x0024 /* Interrupt Flag Clear Register */ +#define EFM32_LCD_IEN_OFFSET 0x0028 /* Interrupt Enable Register */ +#define EFM32_LCD_SEGD0L_OFFSET 0x0040 /* Segment Data Low Register 0 */ +#define EFM32_LCD_SEGD1L_OFFSET 0x0044 /* Segment Data Low Register 1 */ +#define EFM32_LCD_SEGD2L_OFFSET 0x0048 /* Segment Data Low Register 2 */ +#define EFM32_LCD_SEGD3L_OFFSET 0x004c /* Segment Data Low Register 3 */ +#define EFM32_LCD_SEGD0H_OFFSET 0x0050 /* Segment Data High Register 0 */ +#define EFM32_LCD_SEGD1H_OFFSET 0x0054 /* Segment Data High Register 1 */ +#define EFM32_LCD_SEGD2H_OFFSET 0x0058 /* Segment Data High Register 2 */ +#define EFM32_LCD_SEGD3H_OFFSET 0x005c /* Segment Data High Register 3 */ +#define EFM32_LCD_FREEZE_OFFSET 0x0060 /* Freeze Register */ +#define EFM32_LCD_SYNCBUSY_OFFSET 0x0064 /* Synchronization Busy Register */ +#define EFM32_LCD_SEGD4H_OFFSET 0x00b4 /* Segment Data High Register 4 */ +#define EFM32_LCD_SEGD5H_OFFSET 0x00b8 /* Segment Data High Register 5 */ +#define EFM32_LCD_SEGD6H_OFFSET 0x00bc /* Segment Data High Register 6 */ +#define EFM32_LCD_SEGD7H_OFFSET 0x00c0 /* Segment Data High Register 7 */ +#define EFM32_LCD_SEGD4L_OFFSET 0x00cc /* Segment Data Low Register 4 */ +#define EFM32_LCD_SEGD5L_OFFSET 0x00d0 /* Segment Data Low Register 5 */ +#define EFM32_LCD_SEGD6L_OFFSET 0x00d4 /* Segment Data Low Register 6 */ +#define EFM32_LCD_SEGD7L_OFFSET 0x00d8 /* Segment Data Low Register 7 */ + +/* LCD Register Addresses ******************************************************************************************************/ + +#define EFM32_LCD_CTRL (EFM32_LCD_BASE+EFM32_LCD_CTRL_OFFSET) +#define EFM32_LCD_DISPCTRL (EFM32_LCD_BASE+EFM32_LCD_DISPCTRL_OFFSET) +#define EFM32_LCD_SEGEN (EFM32_LCD_BASE+EFM32_LCD_SEGEN_OFFSET) +#define EFM32_LCD_BACTRL (EFM32_LCD_BASE+EFM32_LCD_BACTRL_OFFSET) +#define EFM32_LCD_STATUS (EFM32_LCD_BASE+EFM32_LCD_STATUS_OFFSET) +#define EFM32_LCD_AREGA (EFM32_LCD_BASE+EFM32_LCD_AREGA_OFFSET) +#define EFM32_LCD_AREGB (EFM32_LCD_BASE+EFM32_LCD_AREGB_OFFSET) +#define EFM32_LCD_IF (EFM32_LCD_BASE+EFM32_LCD_IF_OFFSET) +#define EFM32_LCD_IFS (EFM32_LCD_BASE+EFM32_LCD_IFS_OFFSET) +#define EFM32_LCD_IFC (EFM32_LCD_BASE+EFM32_LCD_IFC_OFFSET) +#define EFM32_LCD_IEN (EFM32_LCD_BASE+EFM32_LCD_IEN_OFFSET) +#define EFM32_LCD_SEGD0L (EFM32_LCD_BASE+EFM32_LCD_SEGD0L_OFFSET) +#define EFM32_LCD_SEGD1L (EFM32_LCD_BASE+EFM32_LCD_SEGD1L_OFFSET) +#define EFM32_LCD_SEGD2L (EFM32_LCD_BASE+EFM32_LCD_SEGD2L_OFFSET) +#define EFM32_LCD_SEGD3L (EFM32_LCD_BASE+EFM32_LCD_SEGD3L_OFFSET) +#define EFM32_LCD_SEGD0H (EFM32_LCD_BASE+EFM32_LCD_SEGD0H_OFFSET) +#define EFM32_LCD_SEGD1H (EFM32_LCD_BASE+EFM32_LCD_SEGD1H_OFFSET) +#define EFM32_LCD_SEGD2H (EFM32_LCD_BASE+EFM32_LCD_SEGD2H_OFFSET) +#define EFM32_LCD_SEGD3H (EFM32_LCD_BASE+EFM32_LCD_SEGD3H_OFFSET) +#define EFM32_LCD_FREEZE (EFM32_LCD_BASE+EFM32_LCD_FREEZE_OFFSET) +#define EFM32_LCD_SYNCBUSY (EFM32_LCD_BASE+EFM32_LCD_SYNCBUSY_OFFSET) +#define EFM32_LCD_SEGD4H (EFM32_LCD_BASE+EFM32_LCD_SEGD4H_OFFSET) +#define EFM32_LCD_SEGD5H (EFM32_LCD_BASE+EFM32_LCD_SEGD5H_OFFSET) +#define EFM32_LCD_SEGD6H (EFM32_LCD_BASE+EFM32_LCD_SEGD6H_OFFSET) +#define EFM32_LCD_SEGD7H (EFM32_LCD_BASE+EFM32_LCD_SEGD7H_OFFSET) +#define EFM32_LCD_SEGD4L (EFM32_LCD_BASE+EFM32_LCD_SEGD4L_OFFSET) +#define EFM32_LCD_SEGD5L (EFM32_LCD_BASE+EFM32_LCD_SEGD5L_OFFSET) +#define EFM32_LCD_SEGD6L (EFM32_LCD_BASE+EFM32_LCD_SEGD6L_OFFSET) +#define EFM32_LCD_SEGD7L (EFM32_LCD_BASE+EFM32_LCD_SEGD7L_OFFSET) + +/* LCD Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for LCD CTRL */ + +#define _LCD_CTRL_RESETVALUE 0x00000000UL /* Default value for LCD_CTRL */ +#define _LCD_CTRL_MASK 0x00800007UL /* Mask for LCD_CTRL */ + +#define LCD_CTRL_EN (0x1UL << 0) /* LCD Enable */ +#define _LCD_CTRL_EN_SHIFT 0 /* Shift value for LCD_EN */ +#define _LCD_CTRL_EN_MASK 0x1UL /* Bit mask for LCD_EN */ +#define _LCD_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_CTRL */ +#define LCD_CTRL_EN_DEFAULT (_LCD_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_CTRL */ +#define _LCD_CTRL_UDCTRL_SHIFT 1 /* Shift value for LCD_UDCTRL */ +#define _LCD_CTRL_UDCTRL_MASK 0x6UL /* Bit mask for LCD_UDCTRL */ +#define _LCD_CTRL_UDCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_CTRL */ +#define _LCD_CTRL_UDCTRL_REGULAR 0x00000000UL /* Mode REGULAR for LCD_CTRL */ +#define _LCD_CTRL_UDCTRL_FCEVENT 0x00000001UL /* Mode FCEVENT for LCD_CTRL */ +#define _LCD_CTRL_UDCTRL_FRAMESTART 0x00000002UL /* Mode FRAMESTART for LCD_CTRL */ +#define LCD_CTRL_UDCTRL_DEFAULT (_LCD_CTRL_UDCTRL_DEFAULT << 1) /* Shifted mode DEFAULT for LCD_CTRL */ +#define LCD_CTRL_UDCTRL_REGULAR (_LCD_CTRL_UDCTRL_REGULAR << 1) /* Shifted mode REGULAR for LCD_CTRL */ +#define LCD_CTRL_UDCTRL_FCEVENT (_LCD_CTRL_UDCTRL_FCEVENT << 1) /* Shifted mode FCEVENT for LCD_CTRL */ +#define LCD_CTRL_UDCTRL_FRAMESTART (_LCD_CTRL_UDCTRL_FRAMESTART << 1) /* Shifted mode FRAMESTART for LCD_CTRL */ +#define LCD_CTRL_DSC (0x1UL << 23) /* Direct Segment Control */ +#define _LCD_CTRL_DSC_SHIFT 23 /* Shift value for LCD_DSC */ +#define _LCD_CTRL_DSC_MASK 0x800000UL /* Bit mask for LCD_DSC */ +#define _LCD_CTRL_DSC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_CTRL */ +#define LCD_CTRL_DSC_DEFAULT (_LCD_CTRL_DSC_DEFAULT << 23) /* Shifted mode DEFAULT for LCD_CTRL */ + +/* Bit fields for LCD DISPCTRL */ + +#define _LCD_DISPCTRL_RESETVALUE 0x000C1F00UL /* Default value for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MASK 0x005D9F1FUL /* Mask for LCD_DISPCTRL */ + +#define _LCD_DISPCTRL_MUX_SHIFT 0 /* Shift value for LCD_MUX */ +#define _LCD_DISPCTRL_MUX_MASK 0x3UL /* Bit mask for LCD_MUX */ +#define _LCD_DISPCTRL_MUX_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUX_STATIC 0x00000000UL /* Mode STATIC for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUX_DUPLEX 0x00000001UL /* Mode DUPLEX for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUX_TRIPLEX 0x00000002UL /* Mode TRIPLEX for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUX_QUADRUPLEX 0x00000003UL /* Mode QUADRUPLEX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUX_DEFAULT (_LCD_DISPCTRL_MUX_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUX_STATIC (_LCD_DISPCTRL_MUX_STATIC << 0) /* Shifted mode STATIC for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUX_DUPLEX (_LCD_DISPCTRL_MUX_DUPLEX << 0) /* Shifted mode DUPLEX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUX_TRIPLEX (_LCD_DISPCTRL_MUX_TRIPLEX << 0) /* Shifted mode TRIPLEX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUX_QUADRUPLEX (_LCD_DISPCTRL_MUX_QUADRUPLEX << 0) /* Shifted mode QUADRUPLEX for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_BIAS_SHIFT 2 /* Shift value for LCD_BIAS */ +#define _LCD_DISPCTRL_BIAS_MASK 0xCUL /* Bit mask for LCD_BIAS */ +#define _LCD_DISPCTRL_BIAS_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_BIAS_STATIC 0x00000000UL /* Mode STATIC for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_BIAS_ONEHALF 0x00000001UL /* Mode ONEHALF for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_BIAS_ONETHIRD 0x00000002UL /* Mode ONETHIRD for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_BIAS_ONEFOURTH 0x00000003UL /* Mode ONEFOURTH for LCD_DISPCTRL */ +#define LCD_DISPCTRL_BIAS_DEFAULT (_LCD_DISPCTRL_BIAS_DEFAULT << 2) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_BIAS_STATIC (_LCD_DISPCTRL_BIAS_STATIC << 2) /* Shifted mode STATIC for LCD_DISPCTRL */ +#define LCD_DISPCTRL_BIAS_ONEHALF (_LCD_DISPCTRL_BIAS_ONEHALF << 2) /* Shifted mode ONEHALF for LCD_DISPCTRL */ +#define LCD_DISPCTRL_BIAS_ONETHIRD (_LCD_DISPCTRL_BIAS_ONETHIRD << 2) /* Shifted mode ONETHIRD for LCD_DISPCTRL */ +#define LCD_DISPCTRL_BIAS_ONEFOURTH (_LCD_DISPCTRL_BIAS_ONEFOURTH << 2) /* Shifted mode ONEFOURTH for LCD_DISPCTRL */ +#define LCD_DISPCTRL_WAVE (0x1UL << 4) /* Waveform Selection */ +#define _LCD_DISPCTRL_WAVE_SHIFT 4 /* Shift value for LCD_WAVE */ +#define _LCD_DISPCTRL_WAVE_MASK 0x10UL /* Bit mask for LCD_WAVE */ +#define _LCD_DISPCTRL_WAVE_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_WAVE_LOWPOWER 0x00000000UL /* Mode LOWPOWER for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_WAVE_NORMAL 0x00000001UL /* Mode NORMAL for LCD_DISPCTRL */ +#define LCD_DISPCTRL_WAVE_DEFAULT (_LCD_DISPCTRL_WAVE_DEFAULT << 4) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_WAVE_LOWPOWER (_LCD_DISPCTRL_WAVE_LOWPOWER << 4) /* Shifted mode LOWPOWER for LCD_DISPCTRL */ +#define LCD_DISPCTRL_WAVE_NORMAL (_LCD_DISPCTRL_WAVE_NORMAL << 4) /* Shifted mode NORMAL for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_CONLEV_SHIFT 8 /* Shift value for LCD_CONLEV */ +#define _LCD_DISPCTRL_CONLEV_MASK 0x1F00UL /* Bit mask for LCD_CONLEV */ +#define _LCD_DISPCTRL_CONLEV_MIN 0x00000000UL /* Mode MIN for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_CONLEV_DEFAULT 0x0000001FUL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_CONLEV_MAX 0x0000001FUL /* Mode MAX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONLEV_MIN (_LCD_DISPCTRL_CONLEV_MIN << 8) /* Shifted mode MIN for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONLEV_DEFAULT (_LCD_DISPCTRL_CONLEV_DEFAULT << 8) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONLEV_MAX (_LCD_DISPCTRL_CONLEV_MAX << 8) /* Shifted mode MAX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONCONF (0x1UL << 15) /* Contrast Configuration */ +#define _LCD_DISPCTRL_CONCONF_SHIFT 15 /* Shift value for LCD_CONCONF */ +#define _LCD_DISPCTRL_CONCONF_MASK 0x8000UL /* Bit mask for LCD_CONCONF */ +#define _LCD_DISPCTRL_CONCONF_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_CONCONF_VLCD 0x00000000UL /* Mode VLCD for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_CONCONF_GND 0x00000001UL /* Mode GND for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONCONF_DEFAULT (_LCD_DISPCTRL_CONCONF_DEFAULT << 15) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONCONF_VLCD (_LCD_DISPCTRL_CONCONF_VLCD << 15) /* Shifted mode VLCD for LCD_DISPCTRL */ +#define LCD_DISPCTRL_CONCONF_GND (_LCD_DISPCTRL_CONCONF_GND << 15) /* Shifted mode GND for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VLCDSEL (0x1UL << 16) /* VLCD Selection */ +#define _LCD_DISPCTRL_VLCDSEL_SHIFT 16 /* Shift value for LCD_VLCDSEL */ +#define _LCD_DISPCTRL_VLCDSEL_MASK 0x10000UL /* Bit mask for LCD_VLCDSEL */ +#define _LCD_DISPCTRL_VLCDSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VLCDSEL_VDD 0x00000000UL /* Mode VDD for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VLCDSEL_VEXTBOOST 0x00000001UL /* Mode VEXTBOOST for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VLCDSEL_DEFAULT (_LCD_DISPCTRL_VLCDSEL_DEFAULT << 16) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VLCDSEL_VDD (_LCD_DISPCTRL_VLCDSEL_VDD << 16) /* Shifted mode VDD for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VLCDSEL_VEXTBOOST (_LCD_DISPCTRL_VLCDSEL_VEXTBOOST << 16) /* Shifted mode VEXTBOOST for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_SHIFT 18 /* Shift value for LCD_VBLEV */ +#define _LCD_DISPCTRL_VBLEV_MASK 0x1C0000UL /* Bit mask for LCD_VBLEV */ +#define _LCD_DISPCTRL_VBLEV_LEVEL0 0x00000000UL /* Mode LEVEL0 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL1 0x00000001UL /* Mode LEVEL1 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL2 0x00000002UL /* Mode LEVEL2 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_DEFAULT 0x00000003UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL3 0x00000003UL /* Mode LEVEL3 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL4 0x00000004UL /* Mode LEVEL4 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL5 0x00000005UL /* Mode LEVEL5 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL6 0x00000006UL /* Mode LEVEL6 for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_VBLEV_LEVEL7 0x00000007UL /* Mode LEVEL7 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL0 (_LCD_DISPCTRL_VBLEV_LEVEL0 << 18) /* Shifted mode LEVEL0 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL1 (_LCD_DISPCTRL_VBLEV_LEVEL1 << 18) /* Shifted mode LEVEL1 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL2 (_LCD_DISPCTRL_VBLEV_LEVEL2 << 18) /* Shifted mode LEVEL2 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_DEFAULT (_LCD_DISPCTRL_VBLEV_DEFAULT << 18) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL3 (_LCD_DISPCTRL_VBLEV_LEVEL3 << 18) /* Shifted mode LEVEL3 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL4 (_LCD_DISPCTRL_VBLEV_LEVEL4 << 18) /* Shifted mode LEVEL4 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL5 (_LCD_DISPCTRL_VBLEV_LEVEL5 << 18) /* Shifted mode LEVEL5 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL6 (_LCD_DISPCTRL_VBLEV_LEVEL6 << 18) /* Shifted mode LEVEL6 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_VBLEV_LEVEL7 (_LCD_DISPCTRL_VBLEV_LEVEL7 << 18) /* Shifted mode LEVEL7 for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUXE (0x1UL << 22) /* Extended Mux Configuration */ +#define _LCD_DISPCTRL_MUXE_SHIFT 22 /* Shift value for LCD_MUXE */ +#define _LCD_DISPCTRL_MUXE_MASK 0x400000UL /* Bit mask for LCD_MUXE */ +#define _LCD_DISPCTRL_MUXE_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUXE_MUX 0x00000000UL /* Mode MUX for LCD_DISPCTRL */ +#define _LCD_DISPCTRL_MUXE_MUXE 0x00000001UL /* Mode MUXE for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUXE_DEFAULT (_LCD_DISPCTRL_MUXE_DEFAULT << 22) /* Shifted mode DEFAULT for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUXE_MUX (_LCD_DISPCTRL_MUXE_MUX << 22) /* Shifted mode MUX for LCD_DISPCTRL */ +#define LCD_DISPCTRL_MUXE_MUXE (_LCD_DISPCTRL_MUXE_MUXE << 22) /* Shifted mode MUXE for LCD_DISPCTRL */ + +/* Bit fields for LCD SEGEN */ + +#define _LCD_SEGEN_RESETVALUE 0x00000000UL /* Default value for LCD_SEGEN */ +#define _LCD_SEGEN_MASK 0x000003FFUL /* Mask for LCD_SEGEN */ + +#define _LCD_SEGEN_SEGEN_SHIFT 0 /* Shift value for LCD_SEGEN */ +#define _LCD_SEGEN_SEGEN_MASK 0x3FFUL /* Bit mask for LCD_SEGEN */ +#define _LCD_SEGEN_SEGEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGEN */ +#define LCD_SEGEN_SEGEN_DEFAULT (_LCD_SEGEN_SEGEN_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGEN */ + +/* Bit fields for LCD BACTRL */ + +#define _LCD_BACTRL_RESETVALUE 0x00000000UL /* Default value for LCD_BACTRL */ +#define _LCD_BACTRL_MASK 0x10FF01FFUL /* Mask for LCD_BACTRL */ + +#define LCD_BACTRL_BLINKEN (0x1UL << 0) /* Blink Enable */ +#define _LCD_BACTRL_BLINKEN_SHIFT 0 /* Shift value for LCD_BLINKEN */ +#define _LCD_BACTRL_BLINKEN_MASK 0x1UL /* Bit mask for LCD_BLINKEN */ +#define _LCD_BACTRL_BLINKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_BLINKEN_DEFAULT (_LCD_BACTRL_BLINKEN_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_BLANK (0x1UL << 1) /* Blank Display */ +#define _LCD_BACTRL_BLANK_SHIFT 1 /* Shift value for LCD_BLANK */ +#define _LCD_BACTRL_BLANK_MASK 0x2UL /* Bit mask for LCD_BLANK */ +#define _LCD_BACTRL_BLANK_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_BLANK_DEFAULT (_LCD_BACTRL_BLANK_DEFAULT << 1) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_AEN (0x1UL << 2) /* Animation Enable */ +#define _LCD_BACTRL_AEN_SHIFT 2 /* Shift value for LCD_AEN */ +#define _LCD_BACTRL_AEN_MASK 0x4UL /* Bit mask for LCD_AEN */ +#define _LCD_BACTRL_AEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_AEN_DEFAULT (_LCD_BACTRL_AEN_DEFAULT << 2) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGASC_SHIFT 3 /* Shift value for LCD_AREGASC */ +#define _LCD_BACTRL_AREGASC_MASK 0x18UL /* Bit mask for LCD_AREGASC */ +#define _LCD_BACTRL_AREGASC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGASC_NOSHIFT 0x00000000UL /* Mode NOSHIFT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGASC_SHIFTLEFT 0x00000001UL /* Mode SHIFTLEFT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGASC_SHIFTRIGHT 0x00000002UL /* Mode SHIFTRIGHT for LCD_BACTRL */ +#define LCD_BACTRL_AREGASC_DEFAULT (_LCD_BACTRL_AREGASC_DEFAULT << 3) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_AREGASC_NOSHIFT (_LCD_BACTRL_AREGASC_NOSHIFT << 3) /* Shifted mode NOSHIFT for LCD_BACTRL */ +#define LCD_BACTRL_AREGASC_SHIFTLEFT (_LCD_BACTRL_AREGASC_SHIFTLEFT << 3) /* Shifted mode SHIFTLEFT for LCD_BACTRL */ +#define LCD_BACTRL_AREGASC_SHIFTRIGHT (_LCD_BACTRL_AREGASC_SHIFTRIGHT << 3) /* Shifted mode SHIFTRIGHT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGBSC_SHIFT 5 /* Shift value for LCD_AREGBSC */ +#define _LCD_BACTRL_AREGBSC_MASK 0x60UL /* Bit mask for LCD_AREGBSC */ +#define _LCD_BACTRL_AREGBSC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGBSC_NOSHIFT 0x00000000UL /* Mode NOSHIFT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGBSC_SHIFTLEFT 0x00000001UL /* Mode SHIFTLEFT for LCD_BACTRL */ +#define _LCD_BACTRL_AREGBSC_SHIFTRIGHT 0x00000002UL /* Mode SHIFTRIGHT for LCD_BACTRL */ +#define LCD_BACTRL_AREGBSC_DEFAULT (_LCD_BACTRL_AREGBSC_DEFAULT << 5) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_AREGBSC_NOSHIFT (_LCD_BACTRL_AREGBSC_NOSHIFT << 5) /* Shifted mode NOSHIFT for LCD_BACTRL */ +#define LCD_BACTRL_AREGBSC_SHIFTLEFT (_LCD_BACTRL_AREGBSC_SHIFTLEFT << 5) /* Shifted mode SHIFTLEFT for LCD_BACTRL */ +#define LCD_BACTRL_AREGBSC_SHIFTRIGHT (_LCD_BACTRL_AREGBSC_SHIFTRIGHT << 5) /* Shifted mode SHIFTRIGHT for LCD_BACTRL */ +#define LCD_BACTRL_ALOGSEL (0x1UL << 7) /* Animate Logic Function Select */ +#define _LCD_BACTRL_ALOGSEL_SHIFT 7 /* Shift value for LCD_ALOGSEL */ +#define _LCD_BACTRL_ALOGSEL_MASK 0x80UL /* Bit mask for LCD_ALOGSEL */ +#define _LCD_BACTRL_ALOGSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_ALOGSEL_AND 0x00000000UL /* Mode AND for LCD_BACTRL */ +#define _LCD_BACTRL_ALOGSEL_OR 0x00000001UL /* Mode OR for LCD_BACTRL */ +#define LCD_BACTRL_ALOGSEL_DEFAULT (_LCD_BACTRL_ALOGSEL_DEFAULT << 7) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_ALOGSEL_AND (_LCD_BACTRL_ALOGSEL_AND << 7) /* Shifted mode AND for LCD_BACTRL */ +#define LCD_BACTRL_ALOGSEL_OR (_LCD_BACTRL_ALOGSEL_OR << 7) /* Shifted mode OR for LCD_BACTRL */ +#define LCD_BACTRL_FCEN (0x1UL << 8) /* Frame Counter Enable */ +#define _LCD_BACTRL_FCEN_SHIFT 8 /* Shift value for LCD_FCEN */ +#define _LCD_BACTRL_FCEN_MASK 0x100UL /* Bit mask for LCD_FCEN */ +#define _LCD_BACTRL_FCEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_FCEN_DEFAULT (_LCD_BACTRL_FCEN_DEFAULT << 8) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_FCPRESC_SHIFT 16 /* Shift value for LCD_FCPRESC */ +#define _LCD_BACTRL_FCPRESC_MASK 0x30000UL /* Bit mask for LCD_FCPRESC */ +#define _LCD_BACTRL_FCPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_FCPRESC_DIV1 0x00000000UL /* Mode DIV1 for LCD_BACTRL */ +#define _LCD_BACTRL_FCPRESC_DIV2 0x00000001UL /* Mode DIV2 for LCD_BACTRL */ +#define _LCD_BACTRL_FCPRESC_DIV4 0x00000002UL /* Mode DIV4 for LCD_BACTRL */ +#define _LCD_BACTRL_FCPRESC_DIV8 0x00000003UL /* Mode DIV8 for LCD_BACTRL */ +#define LCD_BACTRL_FCPRESC_DEFAULT (_LCD_BACTRL_FCPRESC_DEFAULT << 16) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_FCPRESC_DIV1 (_LCD_BACTRL_FCPRESC_DIV1 << 16) /* Shifted mode DIV1 for LCD_BACTRL */ +#define LCD_BACTRL_FCPRESC_DIV2 (_LCD_BACTRL_FCPRESC_DIV2 << 16) /* Shifted mode DIV2 for LCD_BACTRL */ +#define LCD_BACTRL_FCPRESC_DIV4 (_LCD_BACTRL_FCPRESC_DIV4 << 16) /* Shifted mode DIV4 for LCD_BACTRL */ +#define LCD_BACTRL_FCPRESC_DIV8 (_LCD_BACTRL_FCPRESC_DIV8 << 16) /* Shifted mode DIV8 for LCD_BACTRL */ +#define _LCD_BACTRL_FCTOP_SHIFT 18 /* Shift value for LCD_FCTOP */ +#define _LCD_BACTRL_FCTOP_MASK 0xFC0000UL /* Bit mask for LCD_FCTOP */ +#define _LCD_BACTRL_FCTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_FCTOP_DEFAULT (_LCD_BACTRL_FCTOP_DEFAULT << 18) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_ALOC (0x1UL << 28) /* Animation Location */ +#define _LCD_BACTRL_ALOC_SHIFT 28 /* Shift value for LCD_ALOC */ +#define _LCD_BACTRL_ALOC_MASK 0x10000000UL /* Bit mask for LCD_ALOC */ +#define _LCD_BACTRL_ALOC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_BACTRL */ +#define _LCD_BACTRL_ALOC_SEG0TO7 0x00000000UL /* Mode SEG0TO7 for LCD_BACTRL */ +#define _LCD_BACTRL_ALOC_SEG8TO15 0x00000001UL /* Mode SEG8TO15 for LCD_BACTRL */ +#define LCD_BACTRL_ALOC_DEFAULT (_LCD_BACTRL_ALOC_DEFAULT << 28) /* Shifted mode DEFAULT for LCD_BACTRL */ +#define LCD_BACTRL_ALOC_SEG0TO7 (_LCD_BACTRL_ALOC_SEG0TO7 << 28) /* Shifted mode SEG0TO7 for LCD_BACTRL */ +#define LCD_BACTRL_ALOC_SEG8TO15 (_LCD_BACTRL_ALOC_SEG8TO15 << 28) /* Shifted mode SEG8TO15 for LCD_BACTRL */ + +/* Bit fields for LCD STATUS */ + +#define _LCD_STATUS_RESETVALUE 0x00000000UL /* Default value for LCD_STATUS */ +#define _LCD_STATUS_MASK 0x0000010FUL /* Mask for LCD_STATUS */ + +#define _LCD_STATUS_ASTATE_SHIFT 0 /* Shift value for LCD_ASTATE */ +#define _LCD_STATUS_ASTATE_MASK 0xFUL /* Bit mask for LCD_ASTATE */ +#define _LCD_STATUS_ASTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_STATUS */ +#define LCD_STATUS_ASTATE_DEFAULT (_LCD_STATUS_ASTATE_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_STATUS */ +#define LCD_STATUS_BLINK (0x1UL << 8) /* Blink State */ +#define _LCD_STATUS_BLINK_SHIFT 8 /* Shift value for LCD_BLINK */ +#define _LCD_STATUS_BLINK_MASK 0x100UL /* Bit mask for LCD_BLINK */ +#define _LCD_STATUS_BLINK_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_STATUS */ +#define LCD_STATUS_BLINK_DEFAULT (_LCD_STATUS_BLINK_DEFAULT << 8) /* Shifted mode DEFAULT for LCD_STATUS */ + +/* Bit fields for LCD AREGA */ + +#define _LCD_AREGA_RESETVALUE 0x00000000UL /* Default value for LCD_AREGA */ +#define _LCD_AREGA_MASK 0x000000FFUL /* Mask for LCD_AREGA */ + +#define _LCD_AREGA_AREGA_SHIFT 0 /* Shift value for LCD_AREGA */ +#define _LCD_AREGA_AREGA_MASK 0xFFUL /* Bit mask for LCD_AREGA */ +#define _LCD_AREGA_AREGA_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_AREGA */ +#define LCD_AREGA_AREGA_DEFAULT (_LCD_AREGA_AREGA_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_AREGA */ + +/* Bit fields for LCD AREGB */ + +#define _LCD_AREGB_RESETVALUE 0x00000000UL /* Default value for LCD_AREGB */ +#define _LCD_AREGB_MASK 0x000000FFUL /* Mask for LCD_AREGB */ + +#define _LCD_AREGB_AREGB_SHIFT 0 /* Shift value for LCD_AREGB */ +#define _LCD_AREGB_AREGB_MASK 0xFFUL /* Bit mask for LCD_AREGB */ +#define _LCD_AREGB_AREGB_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_AREGB */ +#define LCD_AREGB_AREGB_DEFAULT (_LCD_AREGB_AREGB_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_AREGB */ + +/* Bit fields for LCD IF */ + +#define _LCD_IF_RESETVALUE 0x00000000UL /* Default value for LCD_IF */ +#define _LCD_IF_MASK 0x00000001UL /* Mask for LCD_IF */ + +#define LCD_IF_FC (0x1UL << 0) /* Frame Counter Interrupt Flag */ +#define _LCD_IF_FC_SHIFT 0 /* Shift value for LCD_FC */ +#define _LCD_IF_FC_MASK 0x1UL /* Bit mask for LCD_FC */ +#define _LCD_IF_FC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_IF */ +#define LCD_IF_FC_DEFAULT (_LCD_IF_FC_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_IF */ + +/* Bit fields for LCD IFS */ + +#define _LCD_IFS_RESETVALUE 0x00000000UL /* Default value for LCD_IFS */ +#define _LCD_IFS_MASK 0x00000001UL /* Mask for LCD_IFS */ + +#define LCD_IFS_FC (0x1UL << 0) /* Frame Counter Interrupt Flag Set */ +#define _LCD_IFS_FC_SHIFT 0 /* Shift value for LCD_FC */ +#define _LCD_IFS_FC_MASK 0x1UL /* Bit mask for LCD_FC */ +#define _LCD_IFS_FC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_IFS */ +#define LCD_IFS_FC_DEFAULT (_LCD_IFS_FC_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_IFS */ + +/* Bit fields for LCD IFC */ + +#define _LCD_IFC_RESETVALUE 0x00000000UL /* Default value for LCD_IFC */ +#define _LCD_IFC_MASK 0x00000001UL /* Mask for LCD_IFC */ + +#define LCD_IFC_FC (0x1UL << 0) /* Frame Counter Interrupt Flag Clear */ +#define _LCD_IFC_FC_SHIFT 0 /* Shift value for LCD_FC */ +#define _LCD_IFC_FC_MASK 0x1UL /* Bit mask for LCD_FC */ +#define _LCD_IFC_FC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_IFC */ +#define LCD_IFC_FC_DEFAULT (_LCD_IFC_FC_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_IFC */ + +/* Bit fields for LCD IEN */ + +#define _LCD_IEN_RESETVALUE 0x00000000UL /* Default value for LCD_IEN */ +#define _LCD_IEN_MASK 0x00000001UL /* Mask for LCD_IEN */ + +#define LCD_IEN_FC (0x1UL << 0) /* Frame Counter Interrupt Enable */ +#define _LCD_IEN_FC_SHIFT 0 /* Shift value for LCD_FC */ +#define _LCD_IEN_FC_MASK 0x1UL /* Bit mask for LCD_FC */ +#define _LCD_IEN_FC_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_IEN */ +#define LCD_IEN_FC_DEFAULT (_LCD_IEN_FC_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_IEN */ + +/* Bit fields for LCD SEGD0L */ + +#define _LCD_SEGD0L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD0L */ +#define _LCD_SEGD0L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD0L */ + +#define _LCD_SEGD0L_SEGD0L_SHIFT 0 /* Shift value for LCD_SEGD0L */ +#define _LCD_SEGD0L_SEGD0L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD0L */ +#define _LCD_SEGD0L_SEGD0L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD0L */ +#define LCD_SEGD0L_SEGD0L_DEFAULT (_LCD_SEGD0L_SEGD0L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD0L */ + +/* Bit fields for LCD SEGD1L */ + +#define _LCD_SEGD1L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD1L */ +#define _LCD_SEGD1L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD1L */ + +#define _LCD_SEGD1L_SEGD1L_SHIFT 0 /* Shift value for LCD_SEGD1L */ +#define _LCD_SEGD1L_SEGD1L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD1L */ +#define _LCD_SEGD1L_SEGD1L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD1L */ +#define LCD_SEGD1L_SEGD1L_DEFAULT (_LCD_SEGD1L_SEGD1L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD1L */ + +/* Bit fields for LCD SEGD2L */ + +#define _LCD_SEGD2L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD2L */ +#define _LCD_SEGD2L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD2L */ + +#define _LCD_SEGD2L_SEGD2L_SHIFT 0 /* Shift value for LCD_SEGD2L */ +#define _LCD_SEGD2L_SEGD2L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD2L */ +#define _LCD_SEGD2L_SEGD2L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD2L */ +#define LCD_SEGD2L_SEGD2L_DEFAULT (_LCD_SEGD2L_SEGD2L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD2L */ + +/* Bit fields for LCD SEGD3L */ + +#define _LCD_SEGD3L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD3L */ +#define _LCD_SEGD3L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD3L */ + +#define _LCD_SEGD3L_SEGD3L_SHIFT 0 /* Shift value for LCD_SEGD3L */ +#define _LCD_SEGD3L_SEGD3L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD3L */ +#define _LCD_SEGD3L_SEGD3L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD3L */ +#define LCD_SEGD3L_SEGD3L_DEFAULT (_LCD_SEGD3L_SEGD3L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD3L */ + +/* Bit fields for LCD SEGD0H */ + +#define _LCD_SEGD0H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD0H */ +#define _LCD_SEGD0H_MASK 0x000000FFUL /* Mask for LCD_SEGD0H */ + +#define _LCD_SEGD0H_SEGD0H_SHIFT 0 /* Shift value for LCD_SEGD0H */ +#define _LCD_SEGD0H_SEGD0H_MASK 0xFFUL /* Bit mask for LCD_SEGD0H */ +#define _LCD_SEGD0H_SEGD0H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD0H */ +#define LCD_SEGD0H_SEGD0H_DEFAULT (_LCD_SEGD0H_SEGD0H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD0H */ + +/* Bit fields for LCD SEGD1H */ + +#define _LCD_SEGD1H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD1H */ +#define _LCD_SEGD1H_MASK 0x000000FFUL /* Mask for LCD_SEGD1H */ + +#define _LCD_SEGD1H_SEGD1H_SHIFT 0 /* Shift value for LCD_SEGD1H */ +#define _LCD_SEGD1H_SEGD1H_MASK 0xFFUL /* Bit mask for LCD_SEGD1H */ +#define _LCD_SEGD1H_SEGD1H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD1H */ +#define LCD_SEGD1H_SEGD1H_DEFAULT (_LCD_SEGD1H_SEGD1H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD1H */ + +/* Bit fields for LCD SEGD2H */ + +#define _LCD_SEGD2H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD2H */ +#define _LCD_SEGD2H_MASK 0x000000FFUL /* Mask for LCD_SEGD2H */ + +#define _LCD_SEGD2H_SEGD2H_SHIFT 0 /* Shift value for LCD_SEGD2H */ +#define _LCD_SEGD2H_SEGD2H_MASK 0xFFUL /* Bit mask for LCD_SEGD2H */ +#define _LCD_SEGD2H_SEGD2H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD2H */ +#define LCD_SEGD2H_SEGD2H_DEFAULT (_LCD_SEGD2H_SEGD2H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD2H */ + +/* Bit fields for LCD SEGD3H */ + +#define _LCD_SEGD3H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD3H */ +#define _LCD_SEGD3H_MASK 0x000000FFUL /* Mask for LCD_SEGD3H */ + +#define _LCD_SEGD3H_SEGD3H_SHIFT 0 /* Shift value for LCD_SEGD3H */ +#define _LCD_SEGD3H_SEGD3H_MASK 0xFFUL /* Bit mask for LCD_SEGD3H */ +#define _LCD_SEGD3H_SEGD3H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD3H */ +#define LCD_SEGD3H_SEGD3H_DEFAULT (_LCD_SEGD3H_SEGD3H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD3H */ + +/* Bit fields for LCD FREEZE */ + +#define _LCD_FREEZE_RESETVALUE 0x00000000UL /* Default value for LCD_FREEZE */ +#define _LCD_FREEZE_MASK 0x00000001UL /* Mask for LCD_FREEZE */ + +#define LCD_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _LCD_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for LCD_REGFREEZE */ +#define _LCD_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for LCD_REGFREEZE */ +#define _LCD_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_FREEZE */ +#define _LCD_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for LCD_FREEZE */ +#define _LCD_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for LCD_FREEZE */ +#define LCD_FREEZE_REGFREEZE_DEFAULT (_LCD_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_FREEZE */ +#define LCD_FREEZE_REGFREEZE_UPDATE (_LCD_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for LCD_FREEZE */ +#define LCD_FREEZE_REGFREEZE_FREEZE (_LCD_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for LCD_FREEZE */ + +/* Bit fields for LCD SYNCBUSY */ + +#define _LCD_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for LCD_SYNCBUSY */ +#define _LCD_SYNCBUSY_MASK 0x000FFFFFUL /* Mask for LCD_SYNCBUSY */ + +#define LCD_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _LCD_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for LCD_CTRL */ +#define _LCD_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for LCD_CTRL */ +#define _LCD_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_CTRL_DEFAULT (_LCD_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_BACTRL (0x1UL << 1) /* BACTRL Register Busy */ +#define _LCD_SYNCBUSY_BACTRL_SHIFT 1 /* Shift value for LCD_BACTRL */ +#define _LCD_SYNCBUSY_BACTRL_MASK 0x2UL /* Bit mask for LCD_BACTRL */ +#define _LCD_SYNCBUSY_BACTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_BACTRL_DEFAULT (_LCD_SYNCBUSY_BACTRL_DEFAULT << 1) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_AREGA (0x1UL << 2) /* AREGA Register Busy */ +#define _LCD_SYNCBUSY_AREGA_SHIFT 2 /* Shift value for LCD_AREGA */ +#define _LCD_SYNCBUSY_AREGA_MASK 0x4UL /* Bit mask for LCD_AREGA */ +#define _LCD_SYNCBUSY_AREGA_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_AREGA_DEFAULT (_LCD_SYNCBUSY_AREGA_DEFAULT << 2) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_AREGB (0x1UL << 3) /* AREGB Register Busy */ +#define _LCD_SYNCBUSY_AREGB_SHIFT 3 /* Shift value for LCD_AREGB */ +#define _LCD_SYNCBUSY_AREGB_MASK 0x8UL /* Bit mask for LCD_AREGB */ +#define _LCD_SYNCBUSY_AREGB_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_AREGB_DEFAULT (_LCD_SYNCBUSY_AREGB_DEFAULT << 3) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD0L (0x1UL << 4) /* SEGD0L Register Busy */ +#define _LCD_SYNCBUSY_SEGD0L_SHIFT 4 /* Shift value for LCD_SEGD0L */ +#define _LCD_SYNCBUSY_SEGD0L_MASK 0x10UL /* Bit mask for LCD_SEGD0L */ +#define _LCD_SYNCBUSY_SEGD0L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD0L_DEFAULT (_LCD_SYNCBUSY_SEGD0L_DEFAULT << 4) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD1L (0x1UL << 5) /* SEGD1L Register Busy */ +#define _LCD_SYNCBUSY_SEGD1L_SHIFT 5 /* Shift value for LCD_SEGD1L */ +#define _LCD_SYNCBUSY_SEGD1L_MASK 0x20UL /* Bit mask for LCD_SEGD1L */ +#define _LCD_SYNCBUSY_SEGD1L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD1L_DEFAULT (_LCD_SYNCBUSY_SEGD1L_DEFAULT << 5) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD2L (0x1UL << 6) /* SEGD2L Register Busy */ +#define _LCD_SYNCBUSY_SEGD2L_SHIFT 6 /* Shift value for LCD_SEGD2L */ +#define _LCD_SYNCBUSY_SEGD2L_MASK 0x40UL /* Bit mask for LCD_SEGD2L */ +#define _LCD_SYNCBUSY_SEGD2L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD2L_DEFAULT (_LCD_SYNCBUSY_SEGD2L_DEFAULT << 6) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD3L (0x1UL << 7) /* SEGD3L Register Busy */ +#define _LCD_SYNCBUSY_SEGD3L_SHIFT 7 /* Shift value for LCD_SEGD3L */ +#define _LCD_SYNCBUSY_SEGD3L_MASK 0x80UL /* Bit mask for LCD_SEGD3L */ +#define _LCD_SYNCBUSY_SEGD3L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD3L_DEFAULT (_LCD_SYNCBUSY_SEGD3L_DEFAULT << 7) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD0H (0x1UL << 8) /* SEGD0H Register Busy */ +#define _LCD_SYNCBUSY_SEGD0H_SHIFT 8 /* Shift value for LCD_SEGD0H */ +#define _LCD_SYNCBUSY_SEGD0H_MASK 0x100UL /* Bit mask for LCD_SEGD0H */ +#define _LCD_SYNCBUSY_SEGD0H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD0H_DEFAULT (_LCD_SYNCBUSY_SEGD0H_DEFAULT << 8) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD1H (0x1UL << 9) /* SEGD1H Register Busy */ +#define _LCD_SYNCBUSY_SEGD1H_SHIFT 9 /* Shift value for LCD_SEGD1H */ +#define _LCD_SYNCBUSY_SEGD1H_MASK 0x200UL /* Bit mask for LCD_SEGD1H */ +#define _LCD_SYNCBUSY_SEGD1H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD1H_DEFAULT (_LCD_SYNCBUSY_SEGD1H_DEFAULT << 9) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD2H (0x1UL << 10) /* SEGD2H Register Busy */ +#define _LCD_SYNCBUSY_SEGD2H_SHIFT 10 /* Shift value for LCD_SEGD2H */ +#define _LCD_SYNCBUSY_SEGD2H_MASK 0x400UL /* Bit mask for LCD_SEGD2H */ +#define _LCD_SYNCBUSY_SEGD2H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD2H_DEFAULT (_LCD_SYNCBUSY_SEGD2H_DEFAULT << 10) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD3H (0x1UL << 11) /* SEGD3H Register Busy */ +#define _LCD_SYNCBUSY_SEGD3H_SHIFT 11 /* Shift value for LCD_SEGD3H */ +#define _LCD_SYNCBUSY_SEGD3H_MASK 0x800UL /* Bit mask for LCD_SEGD3H */ +#define _LCD_SYNCBUSY_SEGD3H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD3H_DEFAULT (_LCD_SYNCBUSY_SEGD3H_DEFAULT << 11) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD4H (0x1UL << 12) /* SEGD4H Register Busy */ +#define _LCD_SYNCBUSY_SEGD4H_SHIFT 12 /* Shift value for LCD_SEGD4H */ +#define _LCD_SYNCBUSY_SEGD4H_MASK 0x1000UL /* Bit mask for LCD_SEGD4H */ +#define _LCD_SYNCBUSY_SEGD4H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD4H_DEFAULT (_LCD_SYNCBUSY_SEGD4H_DEFAULT << 12) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD5H (0x1UL << 13) /* SEGD5H Register Busy */ +#define _LCD_SYNCBUSY_SEGD5H_SHIFT 13 /* Shift value for LCD_SEGD5H */ +#define _LCD_SYNCBUSY_SEGD5H_MASK 0x2000UL /* Bit mask for LCD_SEGD5H */ +#define _LCD_SYNCBUSY_SEGD5H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD5H_DEFAULT (_LCD_SYNCBUSY_SEGD5H_DEFAULT << 13) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD6H (0x1UL << 14) /* SEGD6H Register Busy */ +#define _LCD_SYNCBUSY_SEGD6H_SHIFT 14 /* Shift value for LCD_SEGD6H */ +#define _LCD_SYNCBUSY_SEGD6H_MASK 0x4000UL /* Bit mask for LCD_SEGD6H */ +#define _LCD_SYNCBUSY_SEGD6H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD6H_DEFAULT (_LCD_SYNCBUSY_SEGD6H_DEFAULT << 14) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD7H (0x1UL << 15) /* SEGD7H Register Busy */ +#define _LCD_SYNCBUSY_SEGD7H_SHIFT 15 /* Shift value for LCD_SEGD7H */ +#define _LCD_SYNCBUSY_SEGD7H_MASK 0x8000UL /* Bit mask for LCD_SEGD7H */ +#define _LCD_SYNCBUSY_SEGD7H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD7H_DEFAULT (_LCD_SYNCBUSY_SEGD7H_DEFAULT << 15) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD4L (0x1UL << 16) /* SEGD4L Register Busy */ +#define _LCD_SYNCBUSY_SEGD4L_SHIFT 16 /* Shift value for LCD_SEGD4L */ +#define _LCD_SYNCBUSY_SEGD4L_MASK 0x10000UL /* Bit mask for LCD_SEGD4L */ +#define _LCD_SYNCBUSY_SEGD4L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD4L_DEFAULT (_LCD_SYNCBUSY_SEGD4L_DEFAULT << 16) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD5L (0x1UL << 17) /* SEGD5L Register Busy */ +#define _LCD_SYNCBUSY_SEGD5L_SHIFT 17 /* Shift value for LCD_SEGD5L */ +#define _LCD_SYNCBUSY_SEGD5L_MASK 0x20000UL /* Bit mask for LCD_SEGD5L */ +#define _LCD_SYNCBUSY_SEGD5L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD5L_DEFAULT (_LCD_SYNCBUSY_SEGD5L_DEFAULT << 17) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD6L (0x1UL << 18) /* SEGD6L Register Busy */ +#define _LCD_SYNCBUSY_SEGD6L_SHIFT 18 /* Shift value for LCD_SEGD6L */ +#define _LCD_SYNCBUSY_SEGD6L_MASK 0x40000UL /* Bit mask for LCD_SEGD6L */ +#define _LCD_SYNCBUSY_SEGD6L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD6L_DEFAULT (_LCD_SYNCBUSY_SEGD6L_DEFAULT << 18) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD7L (0x1UL << 19) /* SEGD7L Register Busy */ +#define _LCD_SYNCBUSY_SEGD7L_SHIFT 19 /* Shift value for LCD_SEGD7L */ +#define _LCD_SYNCBUSY_SEGD7L_MASK 0x80000UL /* Bit mask for LCD_SEGD7L */ +#define _LCD_SYNCBUSY_SEGD7L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SYNCBUSY */ +#define LCD_SYNCBUSY_SEGD7L_DEFAULT (_LCD_SYNCBUSY_SEGD7L_DEFAULT << 19) /* Shifted mode DEFAULT for LCD_SYNCBUSY */ + +/* Bit fields for LCD SEGD4H */ + +#define _LCD_SEGD4H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD4H */ +#define _LCD_SEGD4H_MASK 0x000000FFUL /* Mask for LCD_SEGD4H */ + +#define _LCD_SEGD4H_SEGD4H_SHIFT 0 /* Shift value for LCD_SEGD4H */ +#define _LCD_SEGD4H_SEGD4H_MASK 0xFFUL /* Bit mask for LCD_SEGD4H */ +#define _LCD_SEGD4H_SEGD4H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD4H */ +#define LCD_SEGD4H_SEGD4H_DEFAULT (_LCD_SEGD4H_SEGD4H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD4H */ + +/* Bit fields for LCD SEGD5H */ + +#define _LCD_SEGD5H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD5H */ +#define _LCD_SEGD5H_MASK 0x000000FFUL /* Mask for LCD_SEGD5H */ + +#define _LCD_SEGD5H_SEGD5H_SHIFT 0 /* Shift value for LCD_SEGD5H */ +#define _LCD_SEGD5H_SEGD5H_MASK 0xFFUL /* Bit mask for LCD_SEGD5H */ +#define _LCD_SEGD5H_SEGD5H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD5H */ +#define LCD_SEGD5H_SEGD5H_DEFAULT (_LCD_SEGD5H_SEGD5H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD5H */ + +/* Bit fields for LCD SEGD6H */ + +#define _LCD_SEGD6H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD6H */ +#define _LCD_SEGD6H_MASK 0x000000FFUL /* Mask for LCD_SEGD6H */ + +#define _LCD_SEGD6H_SEGD6H_SHIFT 0 /* Shift value for LCD_SEGD6H */ +#define _LCD_SEGD6H_SEGD6H_MASK 0xFFUL /* Bit mask for LCD_SEGD6H */ +#define _LCD_SEGD6H_SEGD6H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD6H */ +#define LCD_SEGD6H_SEGD6H_DEFAULT (_LCD_SEGD6H_SEGD6H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD6H */ + +/* Bit fields for LCD SEGD7H */ + +#define _LCD_SEGD7H_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD7H */ +#define _LCD_SEGD7H_MASK 0x000000FFUL /* Mask for LCD_SEGD7H */ + +#define _LCD_SEGD7H_SEGD7H_SHIFT 0 /* Shift value for LCD_SEGD7H */ +#define _LCD_SEGD7H_SEGD7H_MASK 0xFFUL /* Bit mask for LCD_SEGD7H */ +#define _LCD_SEGD7H_SEGD7H_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD7H */ +#define LCD_SEGD7H_SEGD7H_DEFAULT (_LCD_SEGD7H_SEGD7H_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD7H */ + +/* Bit fields for LCD SEGD4L */ + +#define _LCD_SEGD4L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD4L */ +#define _LCD_SEGD4L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD4L */ + +#define _LCD_SEGD4L_SEGD4L_SHIFT 0 /* Shift value for LCD_SEGD4L */ +#define _LCD_SEGD4L_SEGD4L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD4L */ +#define _LCD_SEGD4L_SEGD4L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD4L */ +#define LCD_SEGD4L_SEGD4L_DEFAULT (_LCD_SEGD4L_SEGD4L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD4L */ + +/* Bit fields for LCD SEGD5L */ + +#define _LCD_SEGD5L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD5L */ +#define _LCD_SEGD5L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD5L */ + +#define _LCD_SEGD5L_SEGD5L_SHIFT 0 /* Shift value for LCD_SEGD5L */ +#define _LCD_SEGD5L_SEGD5L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD5L */ +#define _LCD_SEGD5L_SEGD5L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD5L */ +#define LCD_SEGD5L_SEGD5L_DEFAULT (_LCD_SEGD5L_SEGD5L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD5L */ + +/* Bit fields for LCD SEGD6L */ + +#define _LCD_SEGD6L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD6L */ +#define _LCD_SEGD6L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD6L */ + +#define _LCD_SEGD6L_SEGD6L_SHIFT 0 /* Shift value for LCD_SEGD6L */ +#define _LCD_SEGD6L_SEGD6L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD6L */ +#define _LCD_SEGD6L_SEGD6L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD6L */ +#define LCD_SEGD6L_SEGD6L_DEFAULT (_LCD_SEGD6L_SEGD6L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD6L */ + +/* Bit fields for LCD SEGD7L */ + +#define _LCD_SEGD7L_RESETVALUE 0x00000000UL /* Default value for LCD_SEGD7L */ +#define _LCD_SEGD7L_MASK 0xFFFFFFFFUL /* Mask for LCD_SEGD7L */ + +#define _LCD_SEGD7L_SEGD7L_SHIFT 0 /* Shift value for LCD_SEGD7L */ +#define _LCD_SEGD7L_SEGD7L_MASK 0xFFFFFFFFUL /* Bit mask for LCD_SEGD7L */ +#define _LCD_SEGD7L_SEGD7L_DEFAULT 0x00000000UL /* Mode DEFAULT for LCD_SEGD7L */ +#define LCD_SEGD7L_SEGD7L_DEFAULT (_LCD_SEGD7L_SEGD7L_DEFAULT << 0) /* Shifted mode DEFAULT for LCD_SEGD7L */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LCD_H */ diff --git a/arch/arm/src/efm32/chip/efm32_lesense.h b/arch/arm/src/efm32/chip/efm32_lesense.h new file mode 100644 index 0000000000000000000000000000000000000000..512a7095bb26cdb434c87affd0f9bea521ef36b6 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_lesense.h @@ -0,0 +1,2160 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_lesense.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LESENSE_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LESENSE_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* LESENSE Register Offsets ****************************************************************************************************/ + +#define EFM32_LESENSE_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_LESENSE_TIMCTRL_OFFSET 0x0004 /* Timing Control Register */ +#define EFM32_LESENSE_PERCTRL_OFFSET 0x0008 /* Peripheral Control Register */ +#define EFM32_LESENSE_DECCTRL_OFFSET 0x000c /* Decoder control Register */ +#define EFM32_LESENSE_BIASCTRL_OFFSET 0x0010 /* Bias Control Register */ +#define EFM32_LESENSE_CMD_OFFSET 0x0014 /* Command Register */ +#define EFM32_LESENSE_CHEN_OFFSET 0x0018 /* Channel enable Register */ +#define EFM32_LESENSE_SCANRES_OFFSET 0x001c /* Scan result register */ +#define EFM32_LESENSE_STATUS_OFFSET 0x0020 /* Status Register */ +#define EFM32_LESENSE_PTR_OFFSET 0x0024 /* Result buffer pointers */ +#define EFM32_LESENSE_BUFDATA_OFFSET 0x0028 /* Result buffer data register */ +#define EFM32_LESENSE_CURCH_OFFSET 0x002c /* Current channel index */ +#define EFM32_LESENSE_DECSTATE_OFFSET 0x0030 /* Current decoder state */ +#define EFM32_LESENSE_SENSORSTATE_OFFSET 0x0034 /* Decoder input register */ +#define EFM32_LESENSE_IDLECONF_OFFSET 0x0038 /* GPIO Idlephase configuration */ +#define EFM32_LESENSE_ALTEXCONF_OFFSET 0x003c /* Alternative excite pin configuration */ +#define EFM32_LESENSE_IF_OFFSET 0x0040 /* Interrupt Flag Register */ +#define EFM32_LESENSE_IFC_OFFSET 0x0044 /* Interrupt Flag Clear Register */ +#define EFM32_LESENSE_IFS_OFFSET 0x0048 /* Interrupt Flag Set Register */ +#define EFM32_LESENSE_IEN_OFFSET 0x004c /* Interrupt Enable Register */ +#define EFM32_LESENSE_SYNCBUSY_OFFSET 0x0050 /* Synchronization Busy Register */ +#define EFM32_LESENSE_ROUTE_OFFSET 0x0054 /* I/O Routing Register */ +#define EFM32_LESENSE_POWERDOWN_OFFSET 0x0058 /* LESENSE RAM power-down resgister */ + +#define EFM32_LESENSE_ST_OFFSET(n) (0x0200 + ((n) << 3)) +#define EFM32_LESENSE_ST0_OFFSET 0x0200 /* State 0 transition configuration offset */ +#define EFM32_LESENSE_ST1_OFFSET 0x0208 /* State 1 transition configuration offset */ +#define EFM32_LESENSE_ST2_OFFSET 0x0210 /* State 2 transition configuration offset */ +#define EFM32_LESENSE_ST3_OFFSET 0x0218 /* State 3 transition configuration offset */ +#define EFM32_LESENSE_ST4_OFFSET 0x0220 /* State 4 transition configuration offset */ +#define EFM32_LESENSE_ST5_OFFSET 0x0228 /* State 5 transition configuration offset */ +#define EFM32_LESENSE_ST6_OFFSET 0x0230 /* State 6 transition configuration offset */ +#define EFM32_LESENSE_ST7_OFFSET 0x0238 /* State 7 transition configuration offset */ +#define EFM32_LESENSE_ST8_OFFSET 0x0240 /* State 8 transition configuration offset */ +#define EFM32_LESENSE_ST9_OFFSET 0x0248 /* State 9 transition configuration offset */ +#define EFM32_LESENSE_ST10_OFFSET 0x0250 /* State 10 transition configuration offset */ +#define EFM32_LESENSE_ST11_OFFSET 0x0258 /* State 11 transition configuration offset */ +#define EFM32_LESENSE_ST12_OFFSET 0x0260 /* State 12 transition configuration offset */ +#define EFM32_LESENSE_ST13_OFFSET 0x0268 /* State 13 transition configuration offset */ +#define EFM32_LESENSE_ST14_OFFSET 0x0270 /* State 14 transition configuration offset */ +#define EFM32_LESENSE_ST15_OFFSET 0x0278 /* State 15 transition configuration offset */ + +#define EFM32_LESENSE_STn_TCONFA_OFFSET 0x0000 /* State transition configuration A */ +#define EFM32_LESENSE_STn_TCONFB_OFFSET 0x0004 /* State transition configuration B */ + +#define EFM32_LESENSE_BUF_DATA_OFFSET(n) (0x0280 + ((n) << 2)) +#define EFM32_LESENSE_BUF0_DATA_OFFSET 0x0280 /* Scan results 0 */ +#define EFM32_LESENSE_BUF1_DATA_OFFSET 0x0284 /* Scan results 1 */ +#define EFM32_LESENSE_BUF2_DATA_OFFSET 0x0288 /* Scan results 2 */ +#define EFM32_LESENSE_BUF3_DATA_OFFSET 0x028c /* Scan results 3 */ +#define EFM32_LESENSE_BUF4_DATA_OFFSET 0x0290 /* Scan results 4 */ +#define EFM32_LESENSE_BUF5_DATA_OFFSET 0x0294 /* Scan results 5 */ +#define EFM32_LESENSE_BUF6_DATA_OFFSET 0x0298 /* Scan results 6 */ +#define EFM32_LESENSE_BUF7_DATA_OFFSET 0x029c /* Scan results 7 */ +#define EFM32_LESENSE_BUF8_DATA_OFFSET 0x02a0 /* Scan results 8 */ +#define EFM32_LESENSE_BUF9_DATA_OFFSET 0x02a4 /* Scan results 9 */ +#define EFM32_LESENSE_BUF10_DATA_OFFSET 0x02a8 /* Scan results 10 */ +#define EFM32_LESENSE_BUF11_DATA_OFFSET 0x02ac /* Scan results 11 */ +#define EFM32_LESENSE_BUF12_DATA_OFFSET 0x02b0 /* Scan results 12 */ +#define EFM32_LESENSE_BUF13_DATA_OFFSET 0x02b4 /* Scan results 13 */ +#define EFM32_LESENSE_BUF14_DATA_OFFSET 0x02b8 /* Scan results 14 */ +#define EFM32_LESENSE_BUF15_DATA_OFFSET 0x02bc /* Scan results 15 */ + +#define EFM32_LESENSE_CH_OFFSET(n) (0x02c0 + ((n) << 4)) +#define EFM32_LESENSE_CH0_OFFSET 0x02c0 /* Channel 0 Offset */ +#define EFM32_LESENSE_CH1_OFFSET 0x02d0 /* Channel 1 Offset */ +#define EFM32_LESENSE_CH2_OFFSET 0x02e0 /* Channel 2 Offset */ +#define EFM32_LESENSE_CH3_OFFSET 0x02f0 /* Channel 3 Offset */ +#define EFM32_LESENSE_CH4_OFFSET 0x0300 /* Channel 4 Offset */ +#define EFM32_LESENSE_CH5_OFFSET 0x0310 /* Channel 5 Offset */ +#define EFM32_LESENSE_CH6_OFFSET 0x0320 /* Channel 6 Offset */ +#define EFM32_LESENSE_CH7_OFFSET 0x0330 /* Channel 7 Offset */ +#define EFM32_LESENSE_CH8_OFFSET 0x0340 /* Channel 8 Offset */ +#define EFM32_LESENSE_CH9_OFFSET 0x0350 /* Channel 9 Offset */ +#define EFM32_LESENSE_CH10_OFFSET 0x0360 /* Channel 10 Offset */ +#define EFM32_LESENSE_CH11_OFFSET 0x0370 /* Channel 11 Offset */ +#define EFM32_LESENSE_CH12_OFFSET 0x0380 /* Channel 12 Offset */ +#define EFM32_LESENSE_CH13_OFFSET 0x0390 /* Channel 13 Offset */ +#define EFM32_LESENSE_CH14_OFFSET 0x03a0 /* Channel 14 Offset */ +#define EFM32_LESENSE_CH15_OFFSET 0x03b0 /* Channel 15 Offset */ + +#define EFM32_LESENSE_CHn_TIMING_OFFSET 0x0000 /* Channel n Scan Configuration */ +#define EFM32_LESENSE_CHn_INTERACT_OFFSET 0x0004 /* Channel n Scan Configuration */ +#define EFM32_LESENSE_CHn_EVAL_OFFSET 0x0008 /* Channel n Scan Configuration */ + +/* LESENSE Register Addresses **************************************************************************************************/ + +#define EFM32_LESENSE_CTRL (EFM32_LESENSE_BASE+EFM32_LESENSE_CTRL_OFFSET) +#define EFM32_LESENSE_TIMCTRL (EFM32_LESENSE_BASE+EFM32_LESENSE_TIMCTRL_OFFSET) +#define EFM32_LESENSE_PERCTRL (EFM32_LESENSE_BASE+EFM32_LESENSE_PERCTRL_OFFSET) +#define EFM32_LESENSE_DECCTRL (EFM32_LESENSE_BASE+EFM32_LESENSE_DECCTRL_OFFSET) +#define EFM32_LESENSE_BIASCTRL (EFM32_LESENSE_BASE+EFM32_LESENSE_BIASCTRL_OFFSET) +#define EFM32_LESENSE_CMD (EFM32_LESENSE_BASE+EFM32_LESENSE_CMD_OFFSET) +#define EFM32_LESENSE_CHEN (EFM32_LESENSE_BASE+EFM32_LESENSE_CHEN_OFFSET) +#define EFM32_LESENSE_SCANRES (EFM32_LESENSE_BASE+EFM32_LESENSE_SCANRES_OFFSET) +#define EFM32_LESENSE_STATUS (EFM32_LESENSE_BASE+EFM32_LESENSE_STATUS_OFFSET) +#define EFM32_LESENSE_PTR (EFM32_LESENSE_BASE+EFM32_LESENSE_PTR_OFFSET) +#define EFM32_LESENSE_BUFDATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUFDATA_OFFSET) +#define EFM32_LESENSE_CURCH (EFM32_LESENSE_BASE+EFM32_LESENSE_CURCH_OFFSET) +#define EFM32_LESENSE_DECSTATE (EFM32_LESENSE_BASE+EFM32_LESENSE_DECSTATE_OFFSET) +#define EFM32_LESENSE_SENSORSTATE (EFM32_LESENSE_BASE+EFM32_LESENSE_SENSORSTATE_OFFSET) +#define EFM32_LESENSE_IDLECONF (EFM32_LESENSE_BASE+EFM32_LESENSE_IDLECONF_OFFSET) +#define EFM32_LESENSE_ALTEXCONF (EFM32_LESENSE_BASE+EFM32_LESENSE_ALTEXCONF_OFFSET) +#define EFM32_LESENSE_IF (EFM32_LESENSE_BASE+EFM32_LESENSE_IF_OFFSET) +#define EFM32_LESENSE_IFC (EFM32_LESENSE_BASE+EFM32_LESENSE_IFC_OFFSET) +#define EFM32_LESENSE_IFS (EFM32_LESENSE_BASE+EFM32_LESENSE_IFS_OFFSET) +#define EFM32_LESENSE_IEN (EFM32_LESENSE_BASE+EFM32_LESENSE_IEN_OFFSET) +#define EFM32_LESENSE_SYNCBUSY (EFM32_LESENSE_BASE+EFM32_LESENSE_SYNCBUSY_OFFSET) +#define EFM32_LESENSE_ROUTE (EFM32_LESENSE_BASE+EFM32_LESENSE_ROUTE_OFFSET) +#define EFM32_LESENSE_POWERDOWN (EFM32_LESENSE_BASE+EFM32_LESENSE_POWERDOWN_OFFSET) + +#define EFM32_LESENSE_ST_BASE(n) (EFM32_LESENSE_BASE+EFM32_LESENSE_ST_OFFSET(n)) +#define EFM32_LESENSE_ST0_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST0_OFFSET) +#define EFM32_LESENSE_ST1_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST1_OFFSET) +#define EFM32_LESENSE_ST2_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST2_OFFSET) +#define EFM32_LESENSE_ST3_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST3_OFFSET) +#define EFM32_LESENSE_ST4_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST4_OFFSET) +#define EFM32_LESENSE_ST5_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST5_OFFSET) +#define EFM32_LESENSE_ST6_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST6_OFFSET) +#define EFM32_LESENSE_ST7_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST7_OFFSET) +#define EFM32_LESENSE_ST8_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST8_OFFSET) +#define EFM32_LESENSE_ST9_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST9_OFFSET) +#define EFM32_LESENSE_ST10_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST10_OFFSET) +#define EFM32_LESENSE_ST11_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST11_OFFSET) +#define EFM32_LESENSE_ST12_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST12_OFFSET) +#define EFM32_LESENSE_ST13_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST13_OFFSET) +#define EFM32_LESENSE_ST14_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST14_OFFSET) +#define EFM32_LESENSE_ST15_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_ST15_OFFSET) + +#define EFM32_LESENSE_ST_TCONFA(n) (EFM32_LESENSE_ST_BASE(n)+EFM32_LESENSE_STn_TCONFA_OFFSET) +#define EFM32_LESENSE_ST_TCONFB(n) (EFM32_LESENSE_ST_BASE(n)+EFM32_LESENSE_STn_TCONFB_OFFSET) + +#define EFM32_LESENSE_BUF_DATA_OFFSET(n) (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF_DATA_OFFSET(n)) +#define EFM32_LESENSE_BUF0_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF0_DATA_OFFSET) +#define EFM32_LESENSE_BUF1_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF1_DATA_OFFSET) +#define EFM32_LESENSE_BUF2_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF2_DATA_OFFSET) +#define EFM32_LESENSE_BUF3_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF3_DATA_OFFSET) +#define EFM32_LESENSE_BUF4_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF4_DATA_OFFSET) +#define EFM32_LESENSE_BUF5_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF5_DATA_OFFSET) +#define EFM32_LESENSE_BUF6_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF6_DATA_OFFSET) +#define EFM32_LESENSE_BUF7_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF7_DATA_OFFSET) +#define EFM32_LESENSE_BUF8_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF8_DATA_OFFSET) +#define EFM32_LESENSE_BUF9_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF9_DATA_OFFSET) +#define EFM32_LESENSE_BUF10_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF10_DATA_OFFSET) +#define EFM32_LESENSE_BUF11_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF11_DATA_OFFSET) +#define EFM32_LESENSE_BUF12_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF12_DATA_OFFSET) +#define EFM32_LESENSE_BUF13_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF13_DATA_OFFSET) +#define EFM32_LESENSE_BUF14_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF14_DATA_OFFSET) +#define EFM32_LESENSE_BUF15_DATA (EFM32_LESENSE_BASE+EFM32_LESENSE_BUF15_DATA_OFFSET) + +#define EFM32_LESENSE_CH_BASE(n) (EFM32_LESENSE_BASE+EFM32_LESENSE_CH_OFFSET(n)) +#define EFM32_LESENSE_CH0_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH0_OFFSET) +#define EFM32_LESENSE_CH1_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH1_OFFSET) +#define EFM32_LESENSE_CH2_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH2_OFFSET) +#define EFM32_LESENSE_CH3_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH3_OFFSET) +#define EFM32_LESENSE_CH4_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH4_OFFSET) +#define EFM32_LESENSE_CH5_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH5_OFFSET) +#define EFM32_LESENSE_CH6_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH6_OFFSET) +#define EFM32_LESENSE_CH7_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH7_OFFSET) +#define EFM32_LESENSE_CH8_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH8_OFFSET) +#define EFM32_LESENSE_CH9_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH9_OFFSET) +#define EFM32_LESENSE_CH10_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH10_OFFSET) +#define EFM32_LESENSE_CH11_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH11_OFFSET) +#define EFM32_LESENSE_CH12_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH12_OFFSET) +#define EFM32_LESENSE_CH13_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH13_OFFSET) +#define EFM32_LESENSE_CH14_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH14_OFFSET) +#define EFM32_LESENSE_CH15_BASE (EFM32_LESENSE_BASE+EFM32_LESENSE_CH15_OFFSET) + +#define EFM32_LESENSE_CH_TIMING(n) (EFM32_LESENSE_CH_BASE(n)+EFM32_LESENSE_CHn_TIMING_OFFSET) +#define EFM32_LESENSE_CH_INTERACT(n) (EFM32_LESENSE_CH_BASE(n)+EFM32_LESENSE_CHn_INTERACT_OFFSET) +#define EFM32_LESENSE_CH_EVAL(n) (EFM32_LESENSE_CH_BASE(n)+EFM32_LESENSE_CHb_EVAL_OFFSET) + +/* LESENSE Register Bit Field Definitions **************************************************************************************/ + +/* Bit fields for LESENSE CTRL */ + +#define _LESENSE_CTRL_RESETVALUE 0x00000000UL /* Default value for LESENSE_CTRL */ +#define _LESENSE_CTRL_MASK 0x00772EFFUL /* Mask for LESENSE_CTRL */ + +#define _LESENSE_CTRL_SCANMODE_SHIFT 0 /* Shift value for LESENSE_SCANMODE */ +#define _LESENSE_CTRL_SCANMODE_MASK 0x3UL /* Bit mask for LESENSE_SCANMODE */ +#define _LESENSE_CTRL_SCANMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANMODE_PERIODIC 0x00000000UL /* Mode PERIODIC for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANMODE_ONESHOT 0x00000001UL /* Mode ONESHOT for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANMODE_PRS 0x00000002UL /* Mode PRS for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANMODE_DEFAULT (_LESENSE_CTRL_SCANMODE_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANMODE_PERIODIC (_LESENSE_CTRL_SCANMODE_PERIODIC << 0) /* Shifted mode PERIODIC for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANMODE_ONESHOT (_LESENSE_CTRL_SCANMODE_ONESHOT << 0) /* Shifted mode ONESHOT for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANMODE_PRS (_LESENSE_CTRL_SCANMODE_PRS << 0) /* Shifted mode PRS for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_SHIFT 2 /* Shift value for LESENSE_PRSSEL */ +#define _LESENSE_CTRL_PRSSEL_MASK 0x3CUL /* Bit mask for LESENSE_PRSSEL */ +#define _LESENSE_CTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LESENSE_CTRL */ +#define _LESENSE_CTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_DEFAULT (_LESENSE_CTRL_PRSSEL_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH0 (_LESENSE_CTRL_PRSSEL_PRSCH0 << 2) /* Shifted mode PRSCH0 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH1 (_LESENSE_CTRL_PRSSEL_PRSCH1 << 2) /* Shifted mode PRSCH1 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH2 (_LESENSE_CTRL_PRSSEL_PRSCH2 << 2) /* Shifted mode PRSCH2 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH3 (_LESENSE_CTRL_PRSSEL_PRSCH3 << 2) /* Shifted mode PRSCH3 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH4 (_LESENSE_CTRL_PRSSEL_PRSCH4 << 2) /* Shifted mode PRSCH4 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH5 (_LESENSE_CTRL_PRSSEL_PRSCH5 << 2) /* Shifted mode PRSCH5 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH6 (_LESENSE_CTRL_PRSSEL_PRSCH6 << 2) /* Shifted mode PRSCH6 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH7 (_LESENSE_CTRL_PRSSEL_PRSCH7 << 2) /* Shifted mode PRSCH7 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH8 (_LESENSE_CTRL_PRSSEL_PRSCH8 << 2) /* Shifted mode PRSCH8 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH9 (_LESENSE_CTRL_PRSSEL_PRSCH9 << 2) /* Shifted mode PRSCH9 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH10 (_LESENSE_CTRL_PRSSEL_PRSCH10 << 2) /* Shifted mode PRSCH10 for LESENSE_CTRL */ +#define LESENSE_CTRL_PRSSEL_PRSCH11 (_LESENSE_CTRL_PRSSEL_PRSCH11 << 2) /* Shifted mode PRSCH11 for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANCONF_SHIFT 6 /* Shift value for LESENSE_SCANCONF */ +#define _LESENSE_CTRL_SCANCONF_MASK 0xC0UL /* Bit mask for LESENSE_SCANCONF */ +#define _LESENSE_CTRL_SCANCONF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANCONF_DIRMAP 0x00000000UL /* Mode DIRMAP for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANCONF_INVMAP 0x00000001UL /* Mode INVMAP for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANCONF_TOGGLE 0x00000002UL /* Mode TOGGLE for LESENSE_CTRL */ +#define _LESENSE_CTRL_SCANCONF_DECDEF 0x00000003UL /* Mode DECDEF for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANCONF_DEFAULT (_LESENSE_CTRL_SCANCONF_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANCONF_DIRMAP (_LESENSE_CTRL_SCANCONF_DIRMAP << 6) /* Shifted mode DIRMAP for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANCONF_INVMAP (_LESENSE_CTRL_SCANCONF_INVMAP << 6) /* Shifted mode INVMAP for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANCONF_TOGGLE (_LESENSE_CTRL_SCANCONF_TOGGLE << 6) /* Shifted mode TOGGLE for LESENSE_CTRL */ +#define LESENSE_CTRL_SCANCONF_DECDEF (_LESENSE_CTRL_SCANCONF_DECDEF << 6) /* Shifted mode DECDEF for LESENSE_CTRL */ +#define LESENSE_CTRL_ACMP0INV (0x1UL << 9) /* Invert analog comparator 0 output */ +#define _LESENSE_CTRL_ACMP0INV_SHIFT 9 /* Shift value for LESENSE_ACMP0INV */ +#define _LESENSE_CTRL_ACMP0INV_MASK 0x200UL /* Bit mask for LESENSE_ACMP0INV */ +#define _LESENSE_CTRL_ACMP0INV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_ACMP0INV_DEFAULT (_LESENSE_CTRL_ACMP0INV_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_ACMP1INV (0x1UL << 10) /* Invert analog comparator 1 output */ +#define _LESENSE_CTRL_ACMP1INV_SHIFT 10 /* Shift value for LESENSE_ACMP1INV */ +#define _LESENSE_CTRL_ACMP1INV_MASK 0x400UL /* Bit mask for LESENSE_ACMP1INV */ +#define _LESENSE_CTRL_ACMP1INV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_ACMP1INV_DEFAULT (_LESENSE_CTRL_ACMP1INV_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_ALTEXMAP (0x1UL << 11) /* Alternative excitation map */ +#define _LESENSE_CTRL_ALTEXMAP_SHIFT 11 /* Shift value for LESENSE_ALTEXMAP */ +#define _LESENSE_CTRL_ALTEXMAP_MASK 0x800UL /* Bit mask for LESENSE_ALTEXMAP */ +#define _LESENSE_CTRL_ALTEXMAP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_ALTEXMAP_ALTEX 0x00000000UL /* Mode ALTEX for LESENSE_CTRL */ +#define _LESENSE_CTRL_ALTEXMAP_ACMP 0x00000001UL /* Mode ACMP for LESENSE_CTRL */ +#define LESENSE_CTRL_ALTEXMAP_DEFAULT (_LESENSE_CTRL_ALTEXMAP_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_ALTEXMAP_ALTEX (_LESENSE_CTRL_ALTEXMAP_ALTEX << 11) /* Shifted mode ALTEX for LESENSE_CTRL */ +#define LESENSE_CTRL_ALTEXMAP_ACMP (_LESENSE_CTRL_ALTEXMAP_ACMP << 11) /* Shifted mode ACMP for LESENSE_CTRL */ +#define LESENSE_CTRL_DUALSAMPLE (0x1UL << 13) /* Enable dual sample mode */ +#define _LESENSE_CTRL_DUALSAMPLE_SHIFT 13 /* Shift value for LESENSE_DUALSAMPLE */ +#define _LESENSE_CTRL_DUALSAMPLE_MASK 0x2000UL /* Bit mask for LESENSE_DUALSAMPLE */ +#define _LESENSE_CTRL_DUALSAMPLE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_DUALSAMPLE_DEFAULT (_LESENSE_CTRL_DUALSAMPLE_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFOW (0x1UL << 16) /* Result buffer overwrite */ +#define _LESENSE_CTRL_BUFOW_SHIFT 16 /* Shift value for LESENSE_BUFOW */ +#define _LESENSE_CTRL_BUFOW_MASK 0x10000UL /* Bit mask for LESENSE_BUFOW */ +#define _LESENSE_CTRL_BUFOW_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFOW_DEFAULT (_LESENSE_CTRL_BUFOW_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_STRSCANRES (0x1UL << 17) /* Enable storing of SCANRES */ +#define _LESENSE_CTRL_STRSCANRES_SHIFT 17 /* Shift value for LESENSE_STRSCANRES */ +#define _LESENSE_CTRL_STRSCANRES_MASK 0x20000UL /* Bit mask for LESENSE_STRSCANRES */ +#define _LESENSE_CTRL_STRSCANRES_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_STRSCANRES_DEFAULT (_LESENSE_CTRL_STRSCANRES_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFIDL (0x1UL << 18) /* Result buffer interrupt and DMA trigger level */ +#define _LESENSE_CTRL_BUFIDL_SHIFT 18 /* Shift value for LESENSE_BUFIDL */ +#define _LESENSE_CTRL_BUFIDL_MASK 0x40000UL /* Bit mask for LESENSE_BUFIDL */ +#define _LESENSE_CTRL_BUFIDL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_BUFIDL_HALFFULL 0x00000000UL /* Mode HALFFULL for LESENSE_CTRL */ +#define _LESENSE_CTRL_BUFIDL_FULL 0x00000001UL /* Mode FULL for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFIDL_DEFAULT (_LESENSE_CTRL_BUFIDL_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFIDL_HALFFULL (_LESENSE_CTRL_BUFIDL_HALFFULL << 18) /* Shifted mode HALFFULL for LESENSE_CTRL */ +#define LESENSE_CTRL_BUFIDL_FULL (_LESENSE_CTRL_BUFIDL_FULL << 18) /* Shifted mode FULL for LESENSE_CTRL */ +#define _LESENSE_CTRL_DMAWU_SHIFT 20 /* Shift value for LESENSE_DMAWU */ +#define _LESENSE_CTRL_DMAWU_MASK 0x300000UL /* Bit mask for LESENSE_DMAWU */ +#define _LESENSE_CTRL_DMAWU_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define _LESENSE_CTRL_DMAWU_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_CTRL */ +#define _LESENSE_CTRL_DMAWU_BUFDATAV 0x00000001UL /* Mode BUFDATAV for LESENSE_CTRL */ +#define _LESENSE_CTRL_DMAWU_BUFLEVEL 0x00000002UL /* Mode BUFLEVEL for LESENSE_CTRL */ +#define LESENSE_CTRL_DMAWU_DEFAULT (_LESENSE_CTRL_DMAWU_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_DMAWU_DISABLE (_LESENSE_CTRL_DMAWU_DISABLE << 20) /* Shifted mode DISABLE for LESENSE_CTRL */ +#define LESENSE_CTRL_DMAWU_BUFDATAV (_LESENSE_CTRL_DMAWU_BUFDATAV << 20) /* Shifted mode BUFDATAV for LESENSE_CTRL */ +#define LESENSE_CTRL_DMAWU_BUFLEVEL (_LESENSE_CTRL_DMAWU_BUFLEVEL << 20) /* Shifted mode BUFLEVEL for LESENSE_CTRL */ +#define LESENSE_CTRL_DEBUGRUN (0x1UL << 22) /* Debug Mode Run Enable */ +#define _LESENSE_CTRL_DEBUGRUN_SHIFT 22 /* Shift value for LESENSE_DEBUGRUN */ +#define _LESENSE_CTRL_DEBUGRUN_MASK 0x400000UL /* Bit mask for LESENSE_DEBUGRUN */ +#define _LESENSE_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CTRL */ +#define LESENSE_CTRL_DEBUGRUN_DEFAULT (_LESENSE_CTRL_DEBUGRUN_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_CTRL */ + +/* Bit fields for LESENSE TIMCTRL */ + +#define _LESENSE_TIMCTRL_RESETVALUE 0x00000000UL /* Default value for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_MASK 0x00CFF773UL /* Mask for LESENSE_TIMCTRL */ + +#define _LESENSE_TIMCTRL_AUXPRESC_SHIFT 0 /* Shift value for LESENSE_AUXPRESC */ +#define _LESENSE_TIMCTRL_AUXPRESC_MASK 0x3UL /* Bit mask for LESENSE_AUXPRESC */ +#define _LESENSE_TIMCTRL_AUXPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_AUXPRESC_DIV1 0x00000000UL /* Mode DIV1 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_AUXPRESC_DIV2 0x00000001UL /* Mode DIV2 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_AUXPRESC_DIV4 0x00000002UL /* Mode DIV4 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_AUXPRESC_DIV8 0x00000003UL /* Mode DIV8 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_AUXPRESC_DEFAULT (_LESENSE_TIMCTRL_AUXPRESC_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_AUXPRESC_DIV1 (_LESENSE_TIMCTRL_AUXPRESC_DIV1 << 0) /* Shifted mode DIV1 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_AUXPRESC_DIV2 (_LESENSE_TIMCTRL_AUXPRESC_DIV2 << 0) /* Shifted mode DIV2 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_AUXPRESC_DIV4 (_LESENSE_TIMCTRL_AUXPRESC_DIV4 << 0) /* Shifted mode DIV4 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_AUXPRESC_DIV8 (_LESENSE_TIMCTRL_AUXPRESC_DIV8 << 0) /* Shifted mode DIV8 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_SHIFT 4 /* Shift value for LESENSE_LFPRESC */ +#define _LESENSE_TIMCTRL_LFPRESC_MASK 0x70UL /* Bit mask for LESENSE_LFPRESC */ +#define _LESENSE_TIMCTRL_LFPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV1 0x00000000UL /* Mode DIV1 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV2 0x00000001UL /* Mode DIV2 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV4 0x00000002UL /* Mode DIV4 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV8 0x00000003UL /* Mode DIV8 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV16 0x00000004UL /* Mode DIV16 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV32 0x00000005UL /* Mode DIV32 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV64 0x00000006UL /* Mode DIV64 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_LFPRESC_DIV128 0x00000007UL /* Mode DIV128 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DEFAULT (_LESENSE_TIMCTRL_LFPRESC_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV1 (_LESENSE_TIMCTRL_LFPRESC_DIV1 << 4) /* Shifted mode DIV1 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV2 (_LESENSE_TIMCTRL_LFPRESC_DIV2 << 4) /* Shifted mode DIV2 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV4 (_LESENSE_TIMCTRL_LFPRESC_DIV4 << 4) /* Shifted mode DIV4 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV8 (_LESENSE_TIMCTRL_LFPRESC_DIV8 << 4) /* Shifted mode DIV8 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV16 (_LESENSE_TIMCTRL_LFPRESC_DIV16 << 4) /* Shifted mode DIV16 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV32 (_LESENSE_TIMCTRL_LFPRESC_DIV32 << 4) /* Shifted mode DIV32 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV64 (_LESENSE_TIMCTRL_LFPRESC_DIV64 << 4) /* Shifted mode DIV64 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_LFPRESC_DIV128 (_LESENSE_TIMCTRL_LFPRESC_DIV128 << 4) /* Shifted mode DIV128 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_SHIFT 8 /* Shift value for LESENSE_PCPRESC */ +#define _LESENSE_TIMCTRL_PCPRESC_MASK 0x700UL /* Bit mask for LESENSE_PCPRESC */ +#define _LESENSE_TIMCTRL_PCPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV1 0x00000000UL /* Mode DIV1 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV2 0x00000001UL /* Mode DIV2 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV4 0x00000002UL /* Mode DIV4 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV8 0x00000003UL /* Mode DIV8 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV16 0x00000004UL /* Mode DIV16 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV32 0x00000005UL /* Mode DIV32 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV64 0x00000006UL /* Mode DIV64 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCPRESC_DIV128 0x00000007UL /* Mode DIV128 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DEFAULT (_LESENSE_TIMCTRL_PCPRESC_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV1 (_LESENSE_TIMCTRL_PCPRESC_DIV1 << 8) /* Shifted mode DIV1 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV2 (_LESENSE_TIMCTRL_PCPRESC_DIV2 << 8) /* Shifted mode DIV2 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV4 (_LESENSE_TIMCTRL_PCPRESC_DIV4 << 8) /* Shifted mode DIV4 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV8 (_LESENSE_TIMCTRL_PCPRESC_DIV8 << 8) /* Shifted mode DIV8 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV16 (_LESENSE_TIMCTRL_PCPRESC_DIV16 << 8) /* Shifted mode DIV16 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV32 (_LESENSE_TIMCTRL_PCPRESC_DIV32 << 8) /* Shifted mode DIV32 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV64 (_LESENSE_TIMCTRL_PCPRESC_DIV64 << 8) /* Shifted mode DIV64 for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCPRESC_DIV128 (_LESENSE_TIMCTRL_PCPRESC_DIV128 << 8) /* Shifted mode DIV128 for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_PCTOP_SHIFT 12 /* Shift value for LESENSE_PCTOP */ +#define _LESENSE_TIMCTRL_PCTOP_MASK 0xFF000UL /* Bit mask for LESENSE_PCTOP */ +#define _LESENSE_TIMCTRL_PCTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_PCTOP_DEFAULT (_LESENSE_TIMCTRL_PCTOP_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_TIMCTRL */ +#define _LESENSE_TIMCTRL_STARTDLY_SHIFT 22 /* Shift value for LESENSE_STARTDLY */ +#define _LESENSE_TIMCTRL_STARTDLY_MASK 0xC00000UL /* Bit mask for LESENSE_STARTDLY */ +#define _LESENSE_TIMCTRL_STARTDLY_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_TIMCTRL */ +#define LESENSE_TIMCTRL_STARTDLY_DEFAULT (_LESENSE_TIMCTRL_STARTDLY_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_TIMCTRL */ + +/* Bit fields for LESENSE PERCTRL */ + +#define _LESENSE_PERCTRL_RESETVALUE 0x00000000UL /* Default value for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_MASK 0x0CF47FFFUL /* Mask for LESENSE_PERCTRL */ + +#define LESENSE_PERCTRL_DACCH0DATA (0x1UL << 0) /* DAC CH0 data selection. */ +#define _LESENSE_PERCTRL_DACCH0DATA_SHIFT 0 /* Shift value for LESENSE_DACCH0DATA */ +#define _LESENSE_PERCTRL_DACCH0DATA_MASK 0x1UL /* Bit mask for LESENSE_DACCH0DATA */ +#define _LESENSE_PERCTRL_DACCH0DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0DATA_DACDATA 0x00000000UL /* Mode DACDATA for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0DATA_ACMPTHRES 0x00000001UL /* Mode ACMPTHRES for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0DATA_DEFAULT (_LESENSE_PERCTRL_DACCH0DATA_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0DATA_DACDATA (_LESENSE_PERCTRL_DACCH0DATA_DACDATA << 0) /* Shifted mode DACDATA for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0DATA_ACMPTHRES (_LESENSE_PERCTRL_DACCH0DATA_ACMPTHRES << 0) /* Shifted mode ACMPTHRES for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1DATA (0x1UL << 1) /* DAC CH1 data selection. */ +#define _LESENSE_PERCTRL_DACCH1DATA_SHIFT 1 /* Shift value for LESENSE_DACCH1DATA */ +#define _LESENSE_PERCTRL_DACCH1DATA_MASK 0x2UL /* Bit mask for LESENSE_DACCH1DATA */ +#define _LESENSE_PERCTRL_DACCH1DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1DATA_DACDATA 0x00000000UL /* Mode DACDATA for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1DATA_ACMPTHRES 0x00000001UL /* Mode ACMPTHRES for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1DATA_DEFAULT (_LESENSE_PERCTRL_DACCH1DATA_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1DATA_DACDATA (_LESENSE_PERCTRL_DACCH1DATA_DACDATA << 1) /* Shifted mode DACDATA for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1DATA_ACMPTHRES (_LESENSE_PERCTRL_DACCH1DATA_ACMPTHRES << 1) /* Shifted mode ACMPTHRES for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0CONV_SHIFT 2 /* Shift value for LESENSE_DACCH0CONV */ +#define _LESENSE_PERCTRL_DACCH0CONV_MASK 0xCUL /* Bit mask for LESENSE_DACCH0CONV */ +#define _LESENSE_PERCTRL_DACCH0CONV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0CONV_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0CONV_CONTINUOUS 0x00000001UL /* Mode CONTINUOUS for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0CONV_SAMPLEHOLD 0x00000002UL /* Mode SAMPLEHOLD for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0CONV_SAMPLEOFF 0x00000003UL /* Mode SAMPLEOFF for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0CONV_DEFAULT (_LESENSE_PERCTRL_DACCH0CONV_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0CONV_DISABLE (_LESENSE_PERCTRL_DACCH0CONV_DISABLE << 2) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0CONV_CONTINUOUS (_LESENSE_PERCTRL_DACCH0CONV_CONTINUOUS << 2) /* Shifted mode CONTINUOUS for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0CONV_SAMPLEHOLD (_LESENSE_PERCTRL_DACCH0CONV_SAMPLEHOLD << 2) /* Shifted mode SAMPLEHOLD for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0CONV_SAMPLEOFF (_LESENSE_PERCTRL_DACCH0CONV_SAMPLEOFF << 2) /* Shifted mode SAMPLEOFF for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1CONV_SHIFT 4 /* Shift value for LESENSE_DACCH1CONV */ +#define _LESENSE_PERCTRL_DACCH1CONV_MASK 0x30UL /* Bit mask for LESENSE_DACCH1CONV */ +#define _LESENSE_PERCTRL_DACCH1CONV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1CONV_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1CONV_CONTINUOUS 0x00000001UL /* Mode CONTINUOUS for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1CONV_SAMPLEHOLD 0x00000002UL /* Mode SAMPLEHOLD for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1CONV_SAMPLEOFF 0x00000003UL /* Mode SAMPLEOFF for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1CONV_DEFAULT (_LESENSE_PERCTRL_DACCH1CONV_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1CONV_DISABLE (_LESENSE_PERCTRL_DACCH1CONV_DISABLE << 4) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1CONV_CONTINUOUS (_LESENSE_PERCTRL_DACCH1CONV_CONTINUOUS << 4) /* Shifted mode CONTINUOUS for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1CONV_SAMPLEHOLD (_LESENSE_PERCTRL_DACCH1CONV_SAMPLEHOLD << 4) /* Shifted mode SAMPLEHOLD for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1CONV_SAMPLEOFF (_LESENSE_PERCTRL_DACCH1CONV_SAMPLEOFF << 4) /* Shifted mode SAMPLEOFF for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0OUT_SHIFT 6 /* Shift value for LESENSE_DACCH0OUT */ +#define _LESENSE_PERCTRL_DACCH0OUT_MASK 0xC0UL /* Bit mask for LESENSE_DACCH0OUT */ +#define _LESENSE_PERCTRL_DACCH0OUT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0OUT_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0OUT_PIN 0x00000001UL /* Mode PIN for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0OUT_ADCACMP 0x00000002UL /* Mode ADCACMP for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH0OUT_PINADCACMP 0x00000003UL /* Mode PINADCACMP for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0OUT_DEFAULT (_LESENSE_PERCTRL_DACCH0OUT_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0OUT_DISABLE (_LESENSE_PERCTRL_DACCH0OUT_DISABLE << 6) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0OUT_PIN (_LESENSE_PERCTRL_DACCH0OUT_PIN << 6) /* Shifted mode PIN for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0OUT_ADCACMP (_LESENSE_PERCTRL_DACCH0OUT_ADCACMP << 6) /* Shifted mode ADCACMP for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH0OUT_PINADCACMP (_LESENSE_PERCTRL_DACCH0OUT_PINADCACMP << 6) /* Shifted mode PINADCACMP for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1OUT_SHIFT 8 /* Shift value for LESENSE_DACCH1OUT */ +#define _LESENSE_PERCTRL_DACCH1OUT_MASK 0x300UL /* Bit mask for LESENSE_DACCH1OUT */ +#define _LESENSE_PERCTRL_DACCH1OUT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1OUT_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1OUT_PIN 0x00000001UL /* Mode PIN for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1OUT_ADCACMP 0x00000002UL /* Mode ADCACMP for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACCH1OUT_PINADCACMP 0x00000003UL /* Mode PINADCACMP for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1OUT_DEFAULT (_LESENSE_PERCTRL_DACCH1OUT_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1OUT_DISABLE (_LESENSE_PERCTRL_DACCH1OUT_DISABLE << 8) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1OUT_PIN (_LESENSE_PERCTRL_DACCH1OUT_PIN << 8) /* Shifted mode PIN for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1OUT_ADCACMP (_LESENSE_PERCTRL_DACCH1OUT_ADCACMP << 8) /* Shifted mode ADCACMP for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACCH1OUT_PINADCACMP (_LESENSE_PERCTRL_DACCH1OUT_PINADCACMP << 8) /* Shifted mode PINADCACMP for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACPRESC_SHIFT 10 /* Shift value for LESENSE_DACPRESC */ +#define _LESENSE_PERCTRL_DACPRESC_MASK 0x7C00UL /* Bit mask for LESENSE_DACPRESC */ +#define _LESENSE_PERCTRL_DACPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACPRESC_DEFAULT (_LESENSE_PERCTRL_DACPRESC_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACREF (0x1UL << 18) /* DAC bandgap reference used */ +#define _LESENSE_PERCTRL_DACREF_SHIFT 18 /* Shift value for LESENSE_DACREF */ +#define _LESENSE_PERCTRL_DACREF_MASK 0x40000UL /* Bit mask for LESENSE_DACREF */ +#define _LESENSE_PERCTRL_DACREF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACREF_VDD 0x00000000UL /* Mode VDD for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_DACREF_BANDGAP 0x00000001UL /* Mode BANDGAP for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACREF_DEFAULT (_LESENSE_PERCTRL_DACREF_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACREF_VDD (_LESENSE_PERCTRL_DACREF_VDD << 18) /* Shifted mode VDD for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_DACREF_BANDGAP (_LESENSE_PERCTRL_DACREF_BANDGAP << 18) /* Shifted mode BANDGAP for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP0MODE_SHIFT 20 /* Shift value for LESENSE_ACMP0MODE */ +#define _LESENSE_PERCTRL_ACMP0MODE_MASK 0x300000UL /* Bit mask for LESENSE_ACMP0MODE */ +#define _LESENSE_PERCTRL_ACMP0MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP0MODE_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP0MODE_MUX 0x00000001UL /* Mode MUX for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP0MODE_MUXTHRES 0x00000002UL /* Mode MUXTHRES for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP0MODE_DEFAULT (_LESENSE_PERCTRL_ACMP0MODE_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP0MODE_DISABLE (_LESENSE_PERCTRL_ACMP0MODE_DISABLE << 20) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP0MODE_MUX (_LESENSE_PERCTRL_ACMP0MODE_MUX << 20) /* Shifted mode MUX for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP0MODE_MUXTHRES (_LESENSE_PERCTRL_ACMP0MODE_MUXTHRES << 20) /* Shifted mode MUXTHRES for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP1MODE_SHIFT 22 /* Shift value for LESENSE_ACMP1MODE */ +#define _LESENSE_PERCTRL_ACMP1MODE_MASK 0xC00000UL /* Bit mask for LESENSE_ACMP1MODE */ +#define _LESENSE_PERCTRL_ACMP1MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP1MODE_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP1MODE_MUX 0x00000001UL /* Mode MUX for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_ACMP1MODE_MUXTHRES 0x00000002UL /* Mode MUXTHRES for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP1MODE_DEFAULT (_LESENSE_PERCTRL_ACMP1MODE_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP1MODE_DISABLE (_LESENSE_PERCTRL_ACMP1MODE_DISABLE << 22) /* Shifted mode DISABLE for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP1MODE_MUX (_LESENSE_PERCTRL_ACMP1MODE_MUX << 22) /* Shifted mode MUX for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_ACMP1MODE_MUXTHRES (_LESENSE_PERCTRL_ACMP1MODE_MUXTHRES << 22) /* Shifted mode MUXTHRES for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_WARMUPMODE_SHIFT 26 /* Shift value for LESENSE_WARMUPMODE */ +#define _LESENSE_PERCTRL_WARMUPMODE_MASK 0xC000000UL /* Bit mask for LESENSE_WARMUPMODE */ +#define _LESENSE_PERCTRL_WARMUPMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_WARMUPMODE_NORMAL 0x00000000UL /* Mode NORMAL for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_WARMUPMODE_KEEPACMPWARM 0x00000001UL /* Mode KEEPACMPWARM for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_WARMUPMODE_KEEPDACWARM 0x00000002UL /* Mode KEEPDACWARM for LESENSE_PERCTRL */ +#define _LESENSE_PERCTRL_WARMUPMODE_KEEPACMPDACWARM 0x00000003UL /* Mode KEEPACMPDACWARM for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_WARMUPMODE_DEFAULT (_LESENSE_PERCTRL_WARMUPMODE_DEFAULT << 26) /* Shifted mode DEFAULT for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_WARMUPMODE_NORMAL (_LESENSE_PERCTRL_WARMUPMODE_NORMAL << 26) /* Shifted mode NORMAL for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_WARMUPMODE_KEEPACMPWARM (_LESENSE_PERCTRL_WARMUPMODE_KEEPACMPWARM << 26) /* Shifted mode KEEPACMPWARM for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_WARMUPMODE_KEEPDACWARM (_LESENSE_PERCTRL_WARMUPMODE_KEEPDACWARM << 26) /* Shifted mode KEEPDACWARM for LESENSE_PERCTRL */ +#define LESENSE_PERCTRL_WARMUPMODE_KEEPACMPDACWARM (_LESENSE_PERCTRL_WARMUPMODE_KEEPACMPDACWARM << 26) /* Shifted mode KEEPACMPDACWARM for LESENSE_PERCTRL */ + +/* Bit fields for LESENSE DECCTRL */ + +#define _LESENSE_DECCTRL_RESETVALUE 0x00000000UL /* Default value for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_MASK 0x03FFFDFFUL /* Mask for LESENSE_DECCTRL */ + +#define LESENSE_DECCTRL_DISABLE (0x1UL << 0) /* Disable the decoder */ +#define _LESENSE_DECCTRL_DISABLE_SHIFT 0 /* Shift value for LESENSE_DISABLE */ +#define _LESENSE_DECCTRL_DISABLE_MASK 0x1UL /* Bit mask for LESENSE_DISABLE */ +#define _LESENSE_DECCTRL_DISABLE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_DISABLE_DEFAULT (_LESENSE_DECCTRL_DISABLE_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_ERRCHK (0x1UL << 1) /* Enable check of current state */ +#define _LESENSE_DECCTRL_ERRCHK_SHIFT 1 /* Shift value for LESENSE_ERRCHK */ +#define _LESENSE_DECCTRL_ERRCHK_MASK 0x2UL /* Bit mask for LESENSE_ERRCHK */ +#define _LESENSE_DECCTRL_ERRCHK_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_ERRCHK_DEFAULT (_LESENSE_DECCTRL_ERRCHK_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INTMAP (0x1UL << 2) /* Enable decoder to channel interrupt mapping */ +#define _LESENSE_DECCTRL_INTMAP_SHIFT 2 /* Shift value for LESENSE_INTMAP */ +#define _LESENSE_DECCTRL_INTMAP_MASK 0x4UL /* Bit mask for LESENSE_INTMAP */ +#define _LESENSE_DECCTRL_INTMAP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INTMAP_DEFAULT (_LESENSE_DECCTRL_INTMAP_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS0 (0x1UL << 3) /* Enable decoder hysteresis on PRS0 output */ +#define _LESENSE_DECCTRL_HYSTPRS0_SHIFT 3 /* Shift value for LESENSE_HYSTPRS0 */ +#define _LESENSE_DECCTRL_HYSTPRS0_MASK 0x8UL /* Bit mask for LESENSE_HYSTPRS0 */ +#define _LESENSE_DECCTRL_HYSTPRS0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS0_DEFAULT (_LESENSE_DECCTRL_HYSTPRS0_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS1 (0x1UL << 4) /* Enable decoder hysteresis on PRS1 output */ +#define _LESENSE_DECCTRL_HYSTPRS1_SHIFT 4 /* Shift value for LESENSE_HYSTPRS1 */ +#define _LESENSE_DECCTRL_HYSTPRS1_MASK 0x10UL /* Bit mask for LESENSE_HYSTPRS1 */ +#define _LESENSE_DECCTRL_HYSTPRS1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS1_DEFAULT (_LESENSE_DECCTRL_HYSTPRS1_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS2 (0x1UL << 5) /* Enable decoder hysteresis on PRS2 output */ +#define _LESENSE_DECCTRL_HYSTPRS2_SHIFT 5 /* Shift value for LESENSE_HYSTPRS2 */ +#define _LESENSE_DECCTRL_HYSTPRS2_MASK 0x20UL /* Bit mask for LESENSE_HYSTPRS2 */ +#define _LESENSE_DECCTRL_HYSTPRS2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTPRS2_DEFAULT (_LESENSE_DECCTRL_HYSTPRS2_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTIRQ (0x1UL << 6) /* Enable decoder hysteresis on interrupt requests */ +#define _LESENSE_DECCTRL_HYSTIRQ_SHIFT 6 /* Shift value for LESENSE_HYSTIRQ */ +#define _LESENSE_DECCTRL_HYSTIRQ_MASK 0x40UL /* Bit mask for LESENSE_HYSTIRQ */ +#define _LESENSE_DECCTRL_HYSTIRQ_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_HYSTIRQ_DEFAULT (_LESENSE_DECCTRL_HYSTIRQ_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSCNT (0x1UL << 7) /* Enable count mode on decoder PRS channels 0 and 1 */ +#define _LESENSE_DECCTRL_PRSCNT_SHIFT 7 /* Shift value for LESENSE_PRSCNT */ +#define _LESENSE_DECCTRL_PRSCNT_MASK 0x80UL /* Bit mask for LESENSE_PRSCNT */ +#define _LESENSE_DECCTRL_PRSCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSCNT_DEFAULT (_LESENSE_DECCTRL_PRSCNT_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INPUT (0x1UL << 8) /* */ +#define _LESENSE_DECCTRL_INPUT_SHIFT 8 /* Shift value for LESENSE_INPUT */ +#define _LESENSE_DECCTRL_INPUT_MASK 0x100UL /* Bit mask for LESENSE_INPUT */ +#define _LESENSE_DECCTRL_INPUT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_INPUT_SENSORSTATE 0x00000000UL /* Mode SENSORSTATE for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_INPUT_PRS 0x00000001UL /* Mode PRS for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INPUT_DEFAULT (_LESENSE_DECCTRL_INPUT_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INPUT_SENSORSTATE (_LESENSE_DECCTRL_INPUT_SENSORSTATE << 8) /* Shifted mode SENSORSTATE for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_INPUT_PRS (_LESENSE_DECCTRL_INPUT_PRS << 8) /* Shifted mode PRS for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_SHIFT 10 /* Shift value for LESENSE_PRSSEL0 */ +#define _LESENSE_DECCTRL_PRSSEL0_MASK 0x3C00UL /* Bit mask for LESENSE_PRSSEL0 */ +#define _LESENSE_DECCTRL_PRSSEL0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH0 0x00000000UL /* Mode PRSCH0 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH1 0x00000001UL /* Mode PRSCH1 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH2 0x00000002UL /* Mode PRSCH2 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH3 0x00000003UL /* Mode PRSCH3 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH4 0x00000004UL /* Mode PRSCH4 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH5 0x00000005UL /* Mode PRSCH5 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH6 0x00000006UL /* Mode PRSCH6 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH7 0x00000007UL /* Mode PRSCH7 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH8 0x00000008UL /* Mode PRSCH8 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH9 0x00000009UL /* Mode PRSCH9 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL0_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_DEFAULT (_LESENSE_DECCTRL_PRSSEL0_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH0 (_LESENSE_DECCTRL_PRSSEL0_PRSCH0 << 10) /* Shifted mode PRSCH0 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH1 (_LESENSE_DECCTRL_PRSSEL0_PRSCH1 << 10) /* Shifted mode PRSCH1 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH2 (_LESENSE_DECCTRL_PRSSEL0_PRSCH2 << 10) /* Shifted mode PRSCH2 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH3 (_LESENSE_DECCTRL_PRSSEL0_PRSCH3 << 10) /* Shifted mode PRSCH3 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH4 (_LESENSE_DECCTRL_PRSSEL0_PRSCH4 << 10) /* Shifted mode PRSCH4 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH5 (_LESENSE_DECCTRL_PRSSEL0_PRSCH5 << 10) /* Shifted mode PRSCH5 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH6 (_LESENSE_DECCTRL_PRSSEL0_PRSCH6 << 10) /* Shifted mode PRSCH6 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH7 (_LESENSE_DECCTRL_PRSSEL0_PRSCH7 << 10) /* Shifted mode PRSCH7 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH8 (_LESENSE_DECCTRL_PRSSEL0_PRSCH8 << 10) /* Shifted mode PRSCH8 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH9 (_LESENSE_DECCTRL_PRSSEL0_PRSCH9 << 10) /* Shifted mode PRSCH9 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH10 (_LESENSE_DECCTRL_PRSSEL0_PRSCH10 << 10) /* Shifted mode PRSCH10 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL0_PRSCH11 (_LESENSE_DECCTRL_PRSSEL0_PRSCH11 << 10) /* Shifted mode PRSCH11 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_SHIFT 14 /* Shift value for LESENSE_PRSSEL1 */ +#define _LESENSE_DECCTRL_PRSSEL1_MASK 0x3C000UL /* Bit mask for LESENSE_PRSSEL1 */ +#define _LESENSE_DECCTRL_PRSSEL1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH0 0x00000000UL /* Mode PRSCH0 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH1 0x00000001UL /* Mode PRSCH1 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH2 0x00000002UL /* Mode PRSCH2 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH3 0x00000003UL /* Mode PRSCH3 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH4 0x00000004UL /* Mode PRSCH4 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH5 0x00000005UL /* Mode PRSCH5 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH6 0x00000006UL /* Mode PRSCH6 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH7 0x00000007UL /* Mode PRSCH7 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH8 0x00000008UL /* Mode PRSCH8 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH9 0x00000009UL /* Mode PRSCH9 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL1_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_DEFAULT (_LESENSE_DECCTRL_PRSSEL1_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH0 (_LESENSE_DECCTRL_PRSSEL1_PRSCH0 << 14) /* Shifted mode PRSCH0 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH1 (_LESENSE_DECCTRL_PRSSEL1_PRSCH1 << 14) /* Shifted mode PRSCH1 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH2 (_LESENSE_DECCTRL_PRSSEL1_PRSCH2 << 14) /* Shifted mode PRSCH2 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH3 (_LESENSE_DECCTRL_PRSSEL1_PRSCH3 << 14) /* Shifted mode PRSCH3 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH4 (_LESENSE_DECCTRL_PRSSEL1_PRSCH4 << 14) /* Shifted mode PRSCH4 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH5 (_LESENSE_DECCTRL_PRSSEL1_PRSCH5 << 14) /* Shifted mode PRSCH5 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH6 (_LESENSE_DECCTRL_PRSSEL1_PRSCH6 << 14) /* Shifted mode PRSCH6 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH7 (_LESENSE_DECCTRL_PRSSEL1_PRSCH7 << 14) /* Shifted mode PRSCH7 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH8 (_LESENSE_DECCTRL_PRSSEL1_PRSCH8 << 14) /* Shifted mode PRSCH8 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH9 (_LESENSE_DECCTRL_PRSSEL1_PRSCH9 << 14) /* Shifted mode PRSCH9 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH10 (_LESENSE_DECCTRL_PRSSEL1_PRSCH10 << 14) /* Shifted mode PRSCH10 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL1_PRSCH11 (_LESENSE_DECCTRL_PRSSEL1_PRSCH11 << 14) /* Shifted mode PRSCH11 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_SHIFT 18 /* Shift value for LESENSE_PRSSEL2 */ +#define _LESENSE_DECCTRL_PRSSEL2_MASK 0x3C0000UL /* Bit mask for LESENSE_PRSSEL2 */ +#define _LESENSE_DECCTRL_PRSSEL2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH0 0x00000000UL /* Mode PRSCH0 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH1 0x00000001UL /* Mode PRSCH1 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH2 0x00000002UL /* Mode PRSCH2 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH3 0x00000003UL /* Mode PRSCH3 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH4 0x00000004UL /* Mode PRSCH4 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH5 0x00000005UL /* Mode PRSCH5 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH6 0x00000006UL /* Mode PRSCH6 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH7 0x00000007UL /* Mode PRSCH7 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH8 0x00000008UL /* Mode PRSCH8 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH9 0x00000009UL /* Mode PRSCH9 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL2_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_DEFAULT (_LESENSE_DECCTRL_PRSSEL2_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH0 (_LESENSE_DECCTRL_PRSSEL2_PRSCH0 << 18) /* Shifted mode PRSCH0 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH1 (_LESENSE_DECCTRL_PRSSEL2_PRSCH1 << 18) /* Shifted mode PRSCH1 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH2 (_LESENSE_DECCTRL_PRSSEL2_PRSCH2 << 18) /* Shifted mode PRSCH2 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH3 (_LESENSE_DECCTRL_PRSSEL2_PRSCH3 << 18) /* Shifted mode PRSCH3 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH4 (_LESENSE_DECCTRL_PRSSEL2_PRSCH4 << 18) /* Shifted mode PRSCH4 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH5 (_LESENSE_DECCTRL_PRSSEL2_PRSCH5 << 18) /* Shifted mode PRSCH5 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH6 (_LESENSE_DECCTRL_PRSSEL2_PRSCH6 << 18) /* Shifted mode PRSCH6 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH7 (_LESENSE_DECCTRL_PRSSEL2_PRSCH7 << 18) /* Shifted mode PRSCH7 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH8 (_LESENSE_DECCTRL_PRSSEL2_PRSCH8 << 18) /* Shifted mode PRSCH8 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH9 (_LESENSE_DECCTRL_PRSSEL2_PRSCH9 << 18) /* Shifted mode PRSCH9 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH10 (_LESENSE_DECCTRL_PRSSEL2_PRSCH10 << 18) /* Shifted mode PRSCH10 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL2_PRSCH11 (_LESENSE_DECCTRL_PRSSEL2_PRSCH11 << 18) /* Shifted mode PRSCH11 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_SHIFT 22 /* Shift value for LESENSE_PRSSEL3 */ +#define _LESENSE_DECCTRL_PRSSEL3_MASK 0x3C00000UL /* Bit mask for LESENSE_PRSSEL3 */ +#define _LESENSE_DECCTRL_PRSSEL3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH0 0x00000000UL /* Mode PRSCH0 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH1 0x00000001UL /* Mode PRSCH1 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH2 0x00000002UL /* Mode PRSCH2 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH3 0x00000003UL /* Mode PRSCH3 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH4 0x00000004UL /* Mode PRSCH4 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH5 0x00000005UL /* Mode PRSCH5 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH6 0x00000006UL /* Mode PRSCH6 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH7 0x00000007UL /* Mode PRSCH7 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH8 0x00000008UL /* Mode PRSCH8 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH9 0x00000009UL /* Mode PRSCH9 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LESENSE_DECCTRL */ +#define _LESENSE_DECCTRL_PRSSEL3_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_DEFAULT (_LESENSE_DECCTRL_PRSSEL3_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH0 (_LESENSE_DECCTRL_PRSSEL3_PRSCH0 << 22) /* Shifted mode PRSCH0 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH1 (_LESENSE_DECCTRL_PRSSEL3_PRSCH1 << 22) /* Shifted mode PRSCH1 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH2 (_LESENSE_DECCTRL_PRSSEL3_PRSCH2 << 22) /* Shifted mode PRSCH2 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH3 (_LESENSE_DECCTRL_PRSSEL3_PRSCH3 << 22) /* Shifted mode PRSCH3 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH4 (_LESENSE_DECCTRL_PRSSEL3_PRSCH4 << 22) /* Shifted mode PRSCH4 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH5 (_LESENSE_DECCTRL_PRSSEL3_PRSCH5 << 22) /* Shifted mode PRSCH5 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH6 (_LESENSE_DECCTRL_PRSSEL3_PRSCH6 << 22) /* Shifted mode PRSCH6 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH7 (_LESENSE_DECCTRL_PRSSEL3_PRSCH7 << 22) /* Shifted mode PRSCH7 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH8 (_LESENSE_DECCTRL_PRSSEL3_PRSCH8 << 22) /* Shifted mode PRSCH8 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH9 (_LESENSE_DECCTRL_PRSSEL3_PRSCH9 << 22) /* Shifted mode PRSCH9 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH10 (_LESENSE_DECCTRL_PRSSEL3_PRSCH10 << 22) /* Shifted mode PRSCH10 for LESENSE_DECCTRL */ +#define LESENSE_DECCTRL_PRSSEL3_PRSCH11 (_LESENSE_DECCTRL_PRSSEL3_PRSCH11 << 22) /* Shifted mode PRSCH11 for LESENSE_DECCTRL */ + +/* Bit fields for LESENSE BIASCTRL */ + +#define _LESENSE_BIASCTRL_RESETVALUE 0x00000000UL /* Default value for LESENSE_BIASCTRL */ +#define _LESENSE_BIASCTRL_MASK 0x00000003UL /* Mask for LESENSE_BIASCTRL */ + +#define _LESENSE_BIASCTRL_BIASMODE_SHIFT 0 /* Shift value for LESENSE_BIASMODE */ +#define _LESENSE_BIASCTRL_BIASMODE_MASK 0x3UL /* Bit mask for LESENSE_BIASMODE */ +#define _LESENSE_BIASCTRL_BIASMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_BIASCTRL */ +#define _LESENSE_BIASCTRL_BIASMODE_DUTYCYCLE 0x00000000UL /* Mode DUTYCYCLE for LESENSE_BIASCTRL */ +#define _LESENSE_BIASCTRL_BIASMODE_HIGHACC 0x00000001UL /* Mode HIGHACC for LESENSE_BIASCTRL */ +#define _LESENSE_BIASCTRL_BIASMODE_DONTTOUCH 0x00000002UL /* Mode DONTTOUCH for LESENSE_BIASCTRL */ +#define LESENSE_BIASCTRL_BIASMODE_DEFAULT (_LESENSE_BIASCTRL_BIASMODE_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_BIASCTRL */ +#define LESENSE_BIASCTRL_BIASMODE_DUTYCYCLE (_LESENSE_BIASCTRL_BIASMODE_DUTYCYCLE << 0) /* Shifted mode DUTYCYCLE for LESENSE_BIASCTRL */ +#define LESENSE_BIASCTRL_BIASMODE_HIGHACC (_LESENSE_BIASCTRL_BIASMODE_HIGHACC << 0) /* Shifted mode HIGHACC for LESENSE_BIASCTRL */ +#define LESENSE_BIASCTRL_BIASMODE_DONTTOUCH (_LESENSE_BIASCTRL_BIASMODE_DONTTOUCH << 0) /* Shifted mode DONTTOUCH for LESENSE_BIASCTRL */ + +/* Bit fields for LESENSE CMD */ + +#define _LESENSE_CMD_RESETVALUE 0x00000000UL /* Default value for LESENSE_CMD */ +#define _LESENSE_CMD_MASK 0x0000000FUL /* Mask for LESENSE_CMD */ + +#define LESENSE_CMD_START (0x1UL << 0) /* Start scanning of sensors. */ +#define _LESENSE_CMD_START_SHIFT 0 /* Shift value for LESENSE_START */ +#define _LESENSE_CMD_START_MASK 0x1UL /* Bit mask for LESENSE_START */ +#define _LESENSE_CMD_START_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_START_DEFAULT (_LESENSE_CMD_START_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_STOP (0x1UL << 1) /* Stop scanning of sensors */ +#define _LESENSE_CMD_STOP_SHIFT 1 /* Shift value for LESENSE_STOP */ +#define _LESENSE_CMD_STOP_MASK 0x2UL /* Bit mask for LESENSE_STOP */ +#define _LESENSE_CMD_STOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_STOP_DEFAULT (_LESENSE_CMD_STOP_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_DECODE (0x1UL << 2) /* Start decoder */ +#define _LESENSE_CMD_DECODE_SHIFT 2 /* Shift value for LESENSE_DECODE */ +#define _LESENSE_CMD_DECODE_MASK 0x4UL /* Bit mask for LESENSE_DECODE */ +#define _LESENSE_CMD_DECODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_DECODE_DEFAULT (_LESENSE_CMD_DECODE_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_CLEARBUF (0x1UL << 3) /* Clear result buffer */ +#define _LESENSE_CMD_CLEARBUF_SHIFT 3 /* Shift value for LESENSE_CLEARBUF */ +#define _LESENSE_CMD_CLEARBUF_MASK 0x8UL /* Bit mask for LESENSE_CLEARBUF */ +#define _LESENSE_CMD_CLEARBUF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CMD */ +#define LESENSE_CMD_CLEARBUF_DEFAULT (_LESENSE_CMD_CLEARBUF_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_CMD */ + +/* Bit fields for LESENSE CHEN */ + +#define _LESENSE_CHEN_RESETVALUE 0x00000000UL /* Default value for LESENSE_CHEN */ +#define _LESENSE_CHEN_MASK 0x0000FFFFUL /* Mask for LESENSE_CHEN */ + +#define _LESENSE_CHEN_CHEN_SHIFT 0 /* Shift value for LESENSE_CHEN */ +#define _LESENSE_CHEN_CHEN_MASK 0xFFFFUL /* Bit mask for LESENSE_CHEN */ +#define _LESENSE_CHEN_CHEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CHEN */ +#define LESENSE_CHEN_CHEN_DEFAULT (_LESENSE_CHEN_CHEN_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CHEN */ + +/* Bit fields for LESENSE SCANRES */ + +#define _LESENSE_SCANRES_RESETVALUE 0x00000000UL /* Default value for LESENSE_SCANRES */ +#define _LESENSE_SCANRES_MASK 0x0000FFFFUL /* Mask for LESENSE_SCANRES */ + +#define _LESENSE_SCANRES_SCANRES_SHIFT 0 /* Shift value for LESENSE_SCANRES */ +#define _LESENSE_SCANRES_SCANRES_MASK 0xFFFFUL /* Bit mask for LESENSE_SCANRES */ +#define _LESENSE_SCANRES_SCANRES_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SCANRES */ +#define LESENSE_SCANRES_SCANRES_DEFAULT (_LESENSE_SCANRES_SCANRES_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_SCANRES */ + +/* Bit fields for LESENSE STATUS */ + +#define _LESENSE_STATUS_RESETVALUE 0x00000000UL /* Default value for LESENSE_STATUS */ +#define _LESENSE_STATUS_MASK 0x0000003FUL /* Mask for LESENSE_STATUS */ + +#define LESENSE_STATUS_BUFDATAV (0x1UL << 0) /* Result data valid */ +#define _LESENSE_STATUS_BUFDATAV_SHIFT 0 /* Shift value for LESENSE_BUFDATAV */ +#define _LESENSE_STATUS_BUFDATAV_MASK 0x1UL /* Bit mask for LESENSE_BUFDATAV */ +#define _LESENSE_STATUS_BUFDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_BUFDATAV_DEFAULT (_LESENSE_STATUS_BUFDATAV_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_BUFHALFFULL (0x1UL << 1) /* Result buffer half full */ +#define _LESENSE_STATUS_BUFHALFFULL_SHIFT 1 /* Shift value for LESENSE_BUFHALFFULL */ +#define _LESENSE_STATUS_BUFHALFFULL_MASK 0x2UL /* Bit mask for LESENSE_BUFHALFFULL */ +#define _LESENSE_STATUS_BUFHALFFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_BUFHALFFULL_DEFAULT (_LESENSE_STATUS_BUFHALFFULL_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_BUFFULL (0x1UL << 2) /* Result buffer full */ +#define _LESENSE_STATUS_BUFFULL_SHIFT 2 /* Shift value for LESENSE_BUFFULL */ +#define _LESENSE_STATUS_BUFFULL_MASK 0x4UL /* Bit mask for LESENSE_BUFFULL */ +#define _LESENSE_STATUS_BUFFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_BUFFULL_DEFAULT (_LESENSE_STATUS_BUFFULL_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_RUNNING (0x1UL << 3) /* LESENSE is active */ +#define _LESENSE_STATUS_RUNNING_SHIFT 3 /* Shift value for LESENSE_RUNNING */ +#define _LESENSE_STATUS_RUNNING_MASK 0x8UL /* Bit mask for LESENSE_RUNNING */ +#define _LESENSE_STATUS_RUNNING_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_RUNNING_DEFAULT (_LESENSE_STATUS_RUNNING_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_SCANACTIVE (0x1UL << 4) /* LESENSE is currently interfacing sensors. */ +#define _LESENSE_STATUS_SCANACTIVE_SHIFT 4 /* Shift value for LESENSE_SCANACTIVE */ +#define _LESENSE_STATUS_SCANACTIVE_MASK 0x10UL /* Bit mask for LESENSE_SCANACTIVE */ +#define _LESENSE_STATUS_SCANACTIVE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_SCANACTIVE_DEFAULT (_LESENSE_STATUS_SCANACTIVE_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_DACACTIVE (0x1UL << 5) /* LESENSE DAC interface is active */ +#define _LESENSE_STATUS_DACACTIVE_SHIFT 5 /* Shift value for LESENSE_DACACTIVE */ +#define _LESENSE_STATUS_DACACTIVE_MASK 0x20UL /* Bit mask for LESENSE_DACACTIVE */ +#define _LESENSE_STATUS_DACACTIVE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_STATUS */ +#define LESENSE_STATUS_DACACTIVE_DEFAULT (_LESENSE_STATUS_DACACTIVE_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_STATUS */ + +/* Bit fields for LESENSE PTR */ + +#define _LESENSE_PTR_RESETVALUE 0x00000000UL /* Default value for LESENSE_PTR */ +#define _LESENSE_PTR_MASK 0x000001EFUL /* Mask for LESENSE_PTR */ + +#define _LESENSE_PTR_RD_SHIFT 0 /* Shift value for LESENSE_RD */ +#define _LESENSE_PTR_RD_MASK 0xFUL /* Bit mask for LESENSE_RD */ +#define _LESENSE_PTR_RD_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PTR */ +#define LESENSE_PTR_RD_DEFAULT (_LESENSE_PTR_RD_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_PTR */ +#define _LESENSE_PTR_WR_SHIFT 5 /* Shift value for LESENSE_WR */ +#define _LESENSE_PTR_WR_MASK 0x1E0UL /* Bit mask for LESENSE_WR */ +#define _LESENSE_PTR_WR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_PTR */ +#define LESENSE_PTR_WR_DEFAULT (_LESENSE_PTR_WR_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_PTR */ + +/* Bit fields for LESENSE BUFDATA */ + +#define _LESENSE_BUFDATA_RESETVALUE 0x00000000UL /* Default value for LESENSE_BUFDATA */ +#define _LESENSE_BUFDATA_MASK 0x0000FFFFUL /* Mask for LESENSE_BUFDATA */ + +#define _LESENSE_BUFDATA_BUFDATA_SHIFT 0 /* Shift value for LESENSE_BUFDATA */ +#define _LESENSE_BUFDATA_BUFDATA_MASK 0xFFFFUL /* Bit mask for LESENSE_BUFDATA */ +#define _LESENSE_BUFDATA_BUFDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_BUFDATA */ +#define LESENSE_BUFDATA_BUFDATA_DEFAULT (_LESENSE_BUFDATA_BUFDATA_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_BUFDATA */ + +/* Bit fields for LESENSE CURCH */ + +#define _LESENSE_CURCH_RESETVALUE 0x00000000UL /* Default value for LESENSE_CURCH */ +#define _LESENSE_CURCH_MASK 0x0000000FUL /* Mask for LESENSE_CURCH */ + +#define _LESENSE_CURCH_CURCH_SHIFT 0 /* Shift value for LESENSE_CURCH */ +#define _LESENSE_CURCH_CURCH_MASK 0xFUL /* Bit mask for LESENSE_CURCH */ +#define _LESENSE_CURCH_CURCH_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CURCH */ +#define LESENSE_CURCH_CURCH_DEFAULT (_LESENSE_CURCH_CURCH_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CURCH */ + +/* Bit fields for LESENSE DECSTATE */ + +#define _LESENSE_DECSTATE_RESETVALUE 0x00000000UL /* Default value for LESENSE_DECSTATE */ +#define _LESENSE_DECSTATE_MASK 0x0000000FUL /* Mask for LESENSE_DECSTATE */ + +#define _LESENSE_DECSTATE_DECSTATE_SHIFT 0 /* Shift value for LESENSE_DECSTATE */ +#define _LESENSE_DECSTATE_DECSTATE_MASK 0xFUL /* Bit mask for LESENSE_DECSTATE */ +#define _LESENSE_DECSTATE_DECSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_DECSTATE */ +#define LESENSE_DECSTATE_DECSTATE_DEFAULT (_LESENSE_DECSTATE_DECSTATE_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_DECSTATE */ + +/* Bit fields for LESENSE SENSORSTATE */ + +#define _LESENSE_SENSORSTATE_RESETVALUE 0x00000000UL /* Default value for LESENSE_SENSORSTATE */ +#define _LESENSE_SENSORSTATE_MASK 0x0000000FUL /* Mask for LESENSE_SENSORSTATE */ + +#define _LESENSE_SENSORSTATE_SENSORSTATE_SHIFT 0 /* Shift value for LESENSE_SENSORSTATE */ +#define _LESENSE_SENSORSTATE_SENSORSTATE_MASK 0xFUL /* Bit mask for LESENSE_SENSORSTATE */ +#define _LESENSE_SENSORSTATE_SENSORSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SENSORSTATE */ +#define LESENSE_SENSORSTATE_SENSORSTATE_DEFAULT (_LESENSE_SENSORSTATE_SENSORSTATE_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_SENSORSTATE */ + +/* Bit fields for LESENSE IDLECONF */ + +#define _LESENSE_IDLECONF_RESETVALUE 0x00000000UL /* Default value for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_MASK 0xFFFFFFFFUL /* Mask for LESENSE_IDLECONF */ + +#define _LESENSE_IDLECONF_CH0_SHIFT 0 /* Shift value for LESENSE_CH0 */ +#define _LESENSE_IDLECONF_CH0_MASK 0x3UL /* Bit mask for LESENSE_CH0 */ +#define _LESENSE_IDLECONF_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH0_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH0_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH0_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH0_DACCH0 0x00000003UL /* Mode DACCH0 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH0_DEFAULT (_LESENSE_IDLECONF_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH0_DISABLE (_LESENSE_IDLECONF_CH0_DISABLE << 0) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH0_HIGH (_LESENSE_IDLECONF_CH0_HIGH << 0) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH0_LOW (_LESENSE_IDLECONF_CH0_LOW << 0) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH0_DACCH0 (_LESENSE_IDLECONF_CH0_DACCH0 << 0) /* Shifted mode DACCH0 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH1_SHIFT 2 /* Shift value for LESENSE_CH1 */ +#define _LESENSE_IDLECONF_CH1_MASK 0xCUL /* Bit mask for LESENSE_CH1 */ +#define _LESENSE_IDLECONF_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH1_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH1_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH1_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH1_DACCH0 0x00000003UL /* Mode DACCH0 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH1_DEFAULT (_LESENSE_IDLECONF_CH1_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH1_DISABLE (_LESENSE_IDLECONF_CH1_DISABLE << 2) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH1_HIGH (_LESENSE_IDLECONF_CH1_HIGH << 2) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH1_LOW (_LESENSE_IDLECONF_CH1_LOW << 2) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH1_DACCH0 (_LESENSE_IDLECONF_CH1_DACCH0 << 2) /* Shifted mode DACCH0 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH2_SHIFT 4 /* Shift value for LESENSE_CH2 */ +#define _LESENSE_IDLECONF_CH2_MASK 0x30UL /* Bit mask for LESENSE_CH2 */ +#define _LESENSE_IDLECONF_CH2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH2_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH2_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH2_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH2_DACCH0 0x00000003UL /* Mode DACCH0 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH2_DEFAULT (_LESENSE_IDLECONF_CH2_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH2_DISABLE (_LESENSE_IDLECONF_CH2_DISABLE << 4) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH2_HIGH (_LESENSE_IDLECONF_CH2_HIGH << 4) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH2_LOW (_LESENSE_IDLECONF_CH2_LOW << 4) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH2_DACCH0 (_LESENSE_IDLECONF_CH2_DACCH0 << 4) /* Shifted mode DACCH0 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH3_SHIFT 6 /* Shift value for LESENSE_CH3 */ +#define _LESENSE_IDLECONF_CH3_MASK 0xC0UL /* Bit mask for LESENSE_CH3 */ +#define _LESENSE_IDLECONF_CH3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH3_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH3_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH3_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH3_DACCH0 0x00000003UL /* Mode DACCH0 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH3_DEFAULT (_LESENSE_IDLECONF_CH3_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH3_DISABLE (_LESENSE_IDLECONF_CH3_DISABLE << 6) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH3_HIGH (_LESENSE_IDLECONF_CH3_HIGH << 6) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH3_LOW (_LESENSE_IDLECONF_CH3_LOW << 6) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH3_DACCH0 (_LESENSE_IDLECONF_CH3_DACCH0 << 6) /* Shifted mode DACCH0 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH4_SHIFT 8 /* Shift value for LESENSE_CH4 */ +#define _LESENSE_IDLECONF_CH4_MASK 0x300UL /* Bit mask for LESENSE_CH4 */ +#define _LESENSE_IDLECONF_CH4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH4_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH4_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH4_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH4_DEFAULT (_LESENSE_IDLECONF_CH4_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH4_DISABLE (_LESENSE_IDLECONF_CH4_DISABLE << 8) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH4_HIGH (_LESENSE_IDLECONF_CH4_HIGH << 8) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH4_LOW (_LESENSE_IDLECONF_CH4_LOW << 8) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH5_SHIFT 10 /* Shift value for LESENSE_CH5 */ +#define _LESENSE_IDLECONF_CH5_MASK 0xC00UL /* Bit mask for LESENSE_CH5 */ +#define _LESENSE_IDLECONF_CH5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH5_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH5_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH5_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH5_DEFAULT (_LESENSE_IDLECONF_CH5_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH5_DISABLE (_LESENSE_IDLECONF_CH5_DISABLE << 10) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH5_HIGH (_LESENSE_IDLECONF_CH5_HIGH << 10) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH5_LOW (_LESENSE_IDLECONF_CH5_LOW << 10) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH6_SHIFT 12 /* Shift value for LESENSE_CH6 */ +#define _LESENSE_IDLECONF_CH6_MASK 0x3000UL /* Bit mask for LESENSE_CH6 */ +#define _LESENSE_IDLECONF_CH6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH6_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH6_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH6_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH6_DEFAULT (_LESENSE_IDLECONF_CH6_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH6_DISABLE (_LESENSE_IDLECONF_CH6_DISABLE << 12) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH6_HIGH (_LESENSE_IDLECONF_CH6_HIGH << 12) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH6_LOW (_LESENSE_IDLECONF_CH6_LOW << 12) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH7_SHIFT 14 /* Shift value for LESENSE_CH7 */ +#define _LESENSE_IDLECONF_CH7_MASK 0xC000UL /* Bit mask for LESENSE_CH7 */ +#define _LESENSE_IDLECONF_CH7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH7_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH7_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH7_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH7_DEFAULT (_LESENSE_IDLECONF_CH7_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH7_DISABLE (_LESENSE_IDLECONF_CH7_DISABLE << 14) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH7_HIGH (_LESENSE_IDLECONF_CH7_HIGH << 14) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH7_LOW (_LESENSE_IDLECONF_CH7_LOW << 14) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH8_SHIFT 16 /* Shift value for LESENSE_CH8 */ +#define _LESENSE_IDLECONF_CH8_MASK 0x30000UL /* Bit mask for LESENSE_CH8 */ +#define _LESENSE_IDLECONF_CH8_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH8_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH8_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH8_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH8_DEFAULT (_LESENSE_IDLECONF_CH8_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH8_DISABLE (_LESENSE_IDLECONF_CH8_DISABLE << 16) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH8_HIGH (_LESENSE_IDLECONF_CH8_HIGH << 16) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH8_LOW (_LESENSE_IDLECONF_CH8_LOW << 16) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH9_SHIFT 18 /* Shift value for LESENSE_CH9 */ +#define _LESENSE_IDLECONF_CH9_MASK 0xC0000UL /* Bit mask for LESENSE_CH9 */ +#define _LESENSE_IDLECONF_CH9_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH9_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH9_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH9_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH9_DEFAULT (_LESENSE_IDLECONF_CH9_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH9_DISABLE (_LESENSE_IDLECONF_CH9_DISABLE << 18) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH9_HIGH (_LESENSE_IDLECONF_CH9_HIGH << 18) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH9_LOW (_LESENSE_IDLECONF_CH9_LOW << 18) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH10_SHIFT 20 /* Shift value for LESENSE_CH10 */ +#define _LESENSE_IDLECONF_CH10_MASK 0x300000UL /* Bit mask for LESENSE_CH10 */ +#define _LESENSE_IDLECONF_CH10_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH10_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH10_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH10_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH10_DEFAULT (_LESENSE_IDLECONF_CH10_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH10_DISABLE (_LESENSE_IDLECONF_CH10_DISABLE << 20) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH10_HIGH (_LESENSE_IDLECONF_CH10_HIGH << 20) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH10_LOW (_LESENSE_IDLECONF_CH10_LOW << 20) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH11_SHIFT 22 /* Shift value for LESENSE_CH11 */ +#define _LESENSE_IDLECONF_CH11_MASK 0xC00000UL /* Bit mask for LESENSE_CH11 */ +#define _LESENSE_IDLECONF_CH11_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH11_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH11_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH11_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH11_DEFAULT (_LESENSE_IDLECONF_CH11_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH11_DISABLE (_LESENSE_IDLECONF_CH11_DISABLE << 22) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH11_HIGH (_LESENSE_IDLECONF_CH11_HIGH << 22) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH11_LOW (_LESENSE_IDLECONF_CH11_LOW << 22) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH12_SHIFT 24 /* Shift value for LESENSE_CH12 */ +#define _LESENSE_IDLECONF_CH12_MASK 0x3000000UL /* Bit mask for LESENSE_CH12 */ +#define _LESENSE_IDLECONF_CH12_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH12_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH12_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH12_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH12_DACCH1 0x00000003UL /* Mode DACCH1 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH12_DEFAULT (_LESENSE_IDLECONF_CH12_DEFAULT << 24) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH12_DISABLE (_LESENSE_IDLECONF_CH12_DISABLE << 24) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH12_HIGH (_LESENSE_IDLECONF_CH12_HIGH << 24) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH12_LOW (_LESENSE_IDLECONF_CH12_LOW << 24) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH12_DACCH1 (_LESENSE_IDLECONF_CH12_DACCH1 << 24) /* Shifted mode DACCH1 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH13_SHIFT 26 /* Shift value for LESENSE_CH13 */ +#define _LESENSE_IDLECONF_CH13_MASK 0xC000000UL /* Bit mask for LESENSE_CH13 */ +#define _LESENSE_IDLECONF_CH13_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH13_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH13_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH13_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH13_DACCH1 0x00000003UL /* Mode DACCH1 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH13_DEFAULT (_LESENSE_IDLECONF_CH13_DEFAULT << 26) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH13_DISABLE (_LESENSE_IDLECONF_CH13_DISABLE << 26) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH13_HIGH (_LESENSE_IDLECONF_CH13_HIGH << 26) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH13_LOW (_LESENSE_IDLECONF_CH13_LOW << 26) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH13_DACCH1 (_LESENSE_IDLECONF_CH13_DACCH1 << 26) /* Shifted mode DACCH1 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH14_SHIFT 28 /* Shift value for LESENSE_CH14 */ +#define _LESENSE_IDLECONF_CH14_MASK 0x30000000UL /* Bit mask for LESENSE_CH14 */ +#define _LESENSE_IDLECONF_CH14_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH14_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH14_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH14_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH14_DACCH1 0x00000003UL /* Mode DACCH1 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH14_DEFAULT (_LESENSE_IDLECONF_CH14_DEFAULT << 28) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH14_DISABLE (_LESENSE_IDLECONF_CH14_DISABLE << 28) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH14_HIGH (_LESENSE_IDLECONF_CH14_HIGH << 28) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH14_LOW (_LESENSE_IDLECONF_CH14_LOW << 28) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH14_DACCH1 (_LESENSE_IDLECONF_CH14_DACCH1 << 28) /* Shifted mode DACCH1 for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH15_SHIFT 30 /* Shift value for LESENSE_CH15 */ +#define _LESENSE_IDLECONF_CH15_MASK 0xC0000000UL /* Bit mask for LESENSE_CH15 */ +#define _LESENSE_IDLECONF_CH15_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH15_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH15_HIGH 0x00000001UL /* Mode HIGH for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH15_LOW 0x00000002UL /* Mode LOW for LESENSE_IDLECONF */ +#define _LESENSE_IDLECONF_CH15_DACCH1 0x00000003UL /* Mode DACCH1 for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH15_DEFAULT (_LESENSE_IDLECONF_CH15_DEFAULT << 30) /* Shifted mode DEFAULT for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH15_DISABLE (_LESENSE_IDLECONF_CH15_DISABLE << 30) /* Shifted mode DISABLE for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH15_HIGH (_LESENSE_IDLECONF_CH15_HIGH << 30) /* Shifted mode HIGH for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH15_LOW (_LESENSE_IDLECONF_CH15_LOW << 30) /* Shifted mode LOW for LESENSE_IDLECONF */ +#define LESENSE_IDLECONF_CH15_DACCH1 (_LESENSE_IDLECONF_CH15_DACCH1 << 30) /* Shifted mode DACCH1 for LESENSE_IDLECONF */ + +/* Bit fields for LESENSE ALTEXCONF */ + +#define _LESENSE_ALTEXCONF_RESETVALUE 0x00000000UL /* Default value for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_MASK 0x00FFFFFFUL /* Mask for LESENSE_ALTEXCONF */ + +#define _LESENSE_ALTEXCONF_IDLECONF0_SHIFT 0 /* Shift value for LESENSE_IDLECONF0 */ +#define _LESENSE_ALTEXCONF_IDLECONF0_MASK 0x3UL /* Bit mask for LESENSE_IDLECONF0 */ +#define _LESENSE_ALTEXCONF_IDLECONF0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF0_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF0_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF0_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF0_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF0_DISABLE (_LESENSE_ALTEXCONF_IDLECONF0_DISABLE << 0) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF0_HIGH (_LESENSE_ALTEXCONF_IDLECONF0_HIGH << 0) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF0_LOW (_LESENSE_ALTEXCONF_IDLECONF0_LOW << 0) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF1_SHIFT 2 /* Shift value for LESENSE_IDLECONF1 */ +#define _LESENSE_ALTEXCONF_IDLECONF1_MASK 0xCUL /* Bit mask for LESENSE_IDLECONF1 */ +#define _LESENSE_ALTEXCONF_IDLECONF1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF1_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF1_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF1_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF1_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF1_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF1_DISABLE (_LESENSE_ALTEXCONF_IDLECONF1_DISABLE << 2) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF1_HIGH (_LESENSE_ALTEXCONF_IDLECONF1_HIGH << 2) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF1_LOW (_LESENSE_ALTEXCONF_IDLECONF1_LOW << 2) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF2_SHIFT 4 /* Shift value for LESENSE_IDLECONF2 */ +#define _LESENSE_ALTEXCONF_IDLECONF2_MASK 0x30UL /* Bit mask for LESENSE_IDLECONF2 */ +#define _LESENSE_ALTEXCONF_IDLECONF2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF2_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF2_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF2_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF2_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF2_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF2_DISABLE (_LESENSE_ALTEXCONF_IDLECONF2_DISABLE << 4) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF2_HIGH (_LESENSE_ALTEXCONF_IDLECONF2_HIGH << 4) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF2_LOW (_LESENSE_ALTEXCONF_IDLECONF2_LOW << 4) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF3_SHIFT 6 /* Shift value for LESENSE_IDLECONF3 */ +#define _LESENSE_ALTEXCONF_IDLECONF3_MASK 0xC0UL /* Bit mask for LESENSE_IDLECONF3 */ +#define _LESENSE_ALTEXCONF_IDLECONF3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF3_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF3_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF3_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF3_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF3_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF3_DISABLE (_LESENSE_ALTEXCONF_IDLECONF3_DISABLE << 6) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF3_HIGH (_LESENSE_ALTEXCONF_IDLECONF3_HIGH << 6) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF3_LOW (_LESENSE_ALTEXCONF_IDLECONF3_LOW << 6) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF4_SHIFT 8 /* Shift value for LESENSE_IDLECONF4 */ +#define _LESENSE_ALTEXCONF_IDLECONF4_MASK 0x300UL /* Bit mask for LESENSE_IDLECONF4 */ +#define _LESENSE_ALTEXCONF_IDLECONF4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF4_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF4_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF4_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF4_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF4_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF4_DISABLE (_LESENSE_ALTEXCONF_IDLECONF4_DISABLE << 8) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF4_HIGH (_LESENSE_ALTEXCONF_IDLECONF4_HIGH << 8) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF4_LOW (_LESENSE_ALTEXCONF_IDLECONF4_LOW << 8) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF5_SHIFT 10 /* Shift value for LESENSE_IDLECONF5 */ +#define _LESENSE_ALTEXCONF_IDLECONF5_MASK 0xC00UL /* Bit mask for LESENSE_IDLECONF5 */ +#define _LESENSE_ALTEXCONF_IDLECONF5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF5_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF5_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF5_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF5_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF5_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF5_DISABLE (_LESENSE_ALTEXCONF_IDLECONF5_DISABLE << 10) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF5_HIGH (_LESENSE_ALTEXCONF_IDLECONF5_HIGH << 10) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF5_LOW (_LESENSE_ALTEXCONF_IDLECONF5_LOW << 10) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF6_SHIFT 12 /* Shift value for LESENSE_IDLECONF6 */ +#define _LESENSE_ALTEXCONF_IDLECONF6_MASK 0x3000UL /* Bit mask for LESENSE_IDLECONF6 */ +#define _LESENSE_ALTEXCONF_IDLECONF6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF6_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF6_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF6_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF6_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF6_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF6_DISABLE (_LESENSE_ALTEXCONF_IDLECONF6_DISABLE << 12) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF6_HIGH (_LESENSE_ALTEXCONF_IDLECONF6_HIGH << 12) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF6_LOW (_LESENSE_ALTEXCONF_IDLECONF6_LOW << 12) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF7_SHIFT 14 /* Shift value for LESENSE_IDLECONF7 */ +#define _LESENSE_ALTEXCONF_IDLECONF7_MASK 0xC000UL /* Bit mask for LESENSE_IDLECONF7 */ +#define _LESENSE_ALTEXCONF_IDLECONF7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF7_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF7_HIGH 0x00000001UL /* Mode HIGH for LESENSE_ALTEXCONF */ +#define _LESENSE_ALTEXCONF_IDLECONF7_LOW 0x00000002UL /* Mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF7_DEFAULT (_LESENSE_ALTEXCONF_IDLECONF7_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF7_DISABLE (_LESENSE_ALTEXCONF_IDLECONF7_DISABLE << 14) /* Shifted mode DISABLE for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF7_HIGH (_LESENSE_ALTEXCONF_IDLECONF7_HIGH << 14) /* Shifted mode HIGH for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_IDLECONF7_LOW (_LESENSE_ALTEXCONF_IDLECONF7_LOW << 14) /* Shifted mode LOW for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX0 (0x1UL << 16) /* ALTEX0 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX0_SHIFT 16 /* Shift value for LESENSE_AEX0 */ +#define _LESENSE_ALTEXCONF_AEX0_MASK 0x10000UL /* Bit mask for LESENSE_AEX0 */ +#define _LESENSE_ALTEXCONF_AEX0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX0_DEFAULT (_LESENSE_ALTEXCONF_AEX0_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX1 (0x1UL << 17) /* ALTEX1 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX1_SHIFT 17 /* Shift value for LESENSE_AEX1 */ +#define _LESENSE_ALTEXCONF_AEX1_MASK 0x20000UL /* Bit mask for LESENSE_AEX1 */ +#define _LESENSE_ALTEXCONF_AEX1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX1_DEFAULT (_LESENSE_ALTEXCONF_AEX1_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX2 (0x1UL << 18) /* ALTEX2 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX2_SHIFT 18 /* Shift value for LESENSE_AEX2 */ +#define _LESENSE_ALTEXCONF_AEX2_MASK 0x40000UL /* Bit mask for LESENSE_AEX2 */ +#define _LESENSE_ALTEXCONF_AEX2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX2_DEFAULT (_LESENSE_ALTEXCONF_AEX2_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX3 (0x1UL << 19) /* ALTEX3 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX3_SHIFT 19 /* Shift value for LESENSE_AEX3 */ +#define _LESENSE_ALTEXCONF_AEX3_MASK 0x80000UL /* Bit mask for LESENSE_AEX3 */ +#define _LESENSE_ALTEXCONF_AEX3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX3_DEFAULT (_LESENSE_ALTEXCONF_AEX3_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX4 (0x1UL << 20) /* ALTEX4 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX4_SHIFT 20 /* Shift value for LESENSE_AEX4 */ +#define _LESENSE_ALTEXCONF_AEX4_MASK 0x100000UL /* Bit mask for LESENSE_AEX4 */ +#define _LESENSE_ALTEXCONF_AEX4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX4_DEFAULT (_LESENSE_ALTEXCONF_AEX4_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX5 (0x1UL << 21) /* ALTEX5 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX5_SHIFT 21 /* Shift value for LESENSE_AEX5 */ +#define _LESENSE_ALTEXCONF_AEX5_MASK 0x200000UL /* Bit mask for LESENSE_AEX5 */ +#define _LESENSE_ALTEXCONF_AEX5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX5_DEFAULT (_LESENSE_ALTEXCONF_AEX5_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX6 (0x1UL << 22) /* ALTEX6 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX6_SHIFT 22 /* Shift value for LESENSE_AEX6 */ +#define _LESENSE_ALTEXCONF_AEX6_MASK 0x400000UL /* Bit mask for LESENSE_AEX6 */ +#define _LESENSE_ALTEXCONF_AEX6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX6_DEFAULT (_LESENSE_ALTEXCONF_AEX6_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX7 (0x1UL << 23) /* ALTEX7 always excite enable */ +#define _LESENSE_ALTEXCONF_AEX7_SHIFT 23 /* Shift value for LESENSE_AEX7 */ +#define _LESENSE_ALTEXCONF_AEX7_MASK 0x800000UL /* Bit mask for LESENSE_AEX7 */ +#define _LESENSE_ALTEXCONF_AEX7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ALTEXCONF */ +#define LESENSE_ALTEXCONF_AEX7_DEFAULT (_LESENSE_ALTEXCONF_AEX7_DEFAULT << 23) /* Shifted mode DEFAULT for LESENSE_ALTEXCONF */ + +/* Bit fields for LESENSE IF */ + +#define _LESENSE_IF_RESETVALUE 0x00000000UL /* Default value for LESENSE_IF */ +#define _LESENSE_IF_MASK 0x007FFFFFUL /* Mask for LESENSE_IF */ + +#define LESENSE_IF_CH0 (0x1UL << 0) /* */ +#define _LESENSE_IF_CH0_SHIFT 0 /* Shift value for LESENSE_CH0 */ +#define _LESENSE_IF_CH0_MASK 0x1UL /* Bit mask for LESENSE_CH0 */ +#define _LESENSE_IF_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH0_DEFAULT (_LESENSE_IF_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH1 (0x1UL << 1) /* */ +#define _LESENSE_IF_CH1_SHIFT 1 /* Shift value for LESENSE_CH1 */ +#define _LESENSE_IF_CH1_MASK 0x2UL /* Bit mask for LESENSE_CH1 */ +#define _LESENSE_IF_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH1_DEFAULT (_LESENSE_IF_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH2 (0x1UL << 2) /* */ +#define _LESENSE_IF_CH2_SHIFT 2 /* Shift value for LESENSE_CH2 */ +#define _LESENSE_IF_CH2_MASK 0x4UL /* Bit mask for LESENSE_CH2 */ +#define _LESENSE_IF_CH2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH2_DEFAULT (_LESENSE_IF_CH2_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH3 (0x1UL << 3) /* */ +#define _LESENSE_IF_CH3_SHIFT 3 /* Shift value for LESENSE_CH3 */ +#define _LESENSE_IF_CH3_MASK 0x8UL /* Bit mask for LESENSE_CH3 */ +#define _LESENSE_IF_CH3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH3_DEFAULT (_LESENSE_IF_CH3_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH4 (0x1UL << 4) /* */ +#define _LESENSE_IF_CH4_SHIFT 4 /* Shift value for LESENSE_CH4 */ +#define _LESENSE_IF_CH4_MASK 0x10UL /* Bit mask for LESENSE_CH4 */ +#define _LESENSE_IF_CH4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH4_DEFAULT (_LESENSE_IF_CH4_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH5 (0x1UL << 5) /* */ +#define _LESENSE_IF_CH5_SHIFT 5 /* Shift value for LESENSE_CH5 */ +#define _LESENSE_IF_CH5_MASK 0x20UL /* Bit mask for LESENSE_CH5 */ +#define _LESENSE_IF_CH5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH5_DEFAULT (_LESENSE_IF_CH5_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH6 (0x1UL << 6) /* */ +#define _LESENSE_IF_CH6_SHIFT 6 /* Shift value for LESENSE_CH6 */ +#define _LESENSE_IF_CH6_MASK 0x40UL /* Bit mask for LESENSE_CH6 */ +#define _LESENSE_IF_CH6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH6_DEFAULT (_LESENSE_IF_CH6_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH7 (0x1UL << 7) /* */ +#define _LESENSE_IF_CH7_SHIFT 7 /* Shift value for LESENSE_CH7 */ +#define _LESENSE_IF_CH7_MASK 0x80UL /* Bit mask for LESENSE_CH7 */ +#define _LESENSE_IF_CH7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH7_DEFAULT (_LESENSE_IF_CH7_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH8 (0x1UL << 8) /* */ +#define _LESENSE_IF_CH8_SHIFT 8 /* Shift value for LESENSE_CH8 */ +#define _LESENSE_IF_CH8_MASK 0x100UL /* Bit mask for LESENSE_CH8 */ +#define _LESENSE_IF_CH8_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH8_DEFAULT (_LESENSE_IF_CH8_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH9 (0x1UL << 9) /* */ +#define _LESENSE_IF_CH9_SHIFT 9 /* Shift value for LESENSE_CH9 */ +#define _LESENSE_IF_CH9_MASK 0x200UL /* Bit mask for LESENSE_CH9 */ +#define _LESENSE_IF_CH9_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH9_DEFAULT (_LESENSE_IF_CH9_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH10 (0x1UL << 10) /* */ +#define _LESENSE_IF_CH10_SHIFT 10 /* Shift value for LESENSE_CH10 */ +#define _LESENSE_IF_CH10_MASK 0x400UL /* Bit mask for LESENSE_CH10 */ +#define _LESENSE_IF_CH10_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH10_DEFAULT (_LESENSE_IF_CH10_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH11 (0x1UL << 11) /* */ +#define _LESENSE_IF_CH11_SHIFT 11 /* Shift value for LESENSE_CH11 */ +#define _LESENSE_IF_CH11_MASK 0x800UL /* Bit mask for LESENSE_CH11 */ +#define _LESENSE_IF_CH11_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH11_DEFAULT (_LESENSE_IF_CH11_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH12 (0x1UL << 12) /* */ +#define _LESENSE_IF_CH12_SHIFT 12 /* Shift value for LESENSE_CH12 */ +#define _LESENSE_IF_CH12_MASK 0x1000UL /* Bit mask for LESENSE_CH12 */ +#define _LESENSE_IF_CH12_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH12_DEFAULT (_LESENSE_IF_CH12_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH13 (0x1UL << 13) /* */ +#define _LESENSE_IF_CH13_SHIFT 13 /* Shift value for LESENSE_CH13 */ +#define _LESENSE_IF_CH13_MASK 0x2000UL /* Bit mask for LESENSE_CH13 */ +#define _LESENSE_IF_CH13_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH13_DEFAULT (_LESENSE_IF_CH13_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH14 (0x1UL << 14) /* */ +#define _LESENSE_IF_CH14_SHIFT 14 /* Shift value for LESENSE_CH14 */ +#define _LESENSE_IF_CH14_MASK 0x4000UL /* Bit mask for LESENSE_CH14 */ +#define _LESENSE_IF_CH14_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH14_DEFAULT (_LESENSE_IF_CH14_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH15 (0x1UL << 15) /* */ +#define _LESENSE_IF_CH15_SHIFT 15 /* Shift value for LESENSE_CH15 */ +#define _LESENSE_IF_CH15_MASK 0x8000UL /* Bit mask for LESENSE_CH15 */ +#define _LESENSE_IF_CH15_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CH15_DEFAULT (_LESENSE_IF_CH15_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_SCANCOMPLETE (0x1UL << 16) /* */ +#define _LESENSE_IF_SCANCOMPLETE_SHIFT 16 /* Shift value for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IF_SCANCOMPLETE_MASK 0x10000UL /* Bit mask for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IF_SCANCOMPLETE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_SCANCOMPLETE_DEFAULT (_LESENSE_IF_SCANCOMPLETE_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_DEC (0x1UL << 17) /* */ +#define _LESENSE_IF_DEC_SHIFT 17 /* Shift value for LESENSE_DEC */ +#define _LESENSE_IF_DEC_MASK 0x20000UL /* Bit mask for LESENSE_DEC */ +#define _LESENSE_IF_DEC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_DEC_DEFAULT (_LESENSE_IF_DEC_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_DECERR (0x1UL << 18) /* */ +#define _LESENSE_IF_DECERR_SHIFT 18 /* Shift value for LESENSE_DECERR */ +#define _LESENSE_IF_DECERR_MASK 0x40000UL /* Bit mask for LESENSE_DECERR */ +#define _LESENSE_IF_DECERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_DECERR_DEFAULT (_LESENSE_IF_DECERR_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFDATAV (0x1UL << 19) /* */ +#define _LESENSE_IF_BUFDATAV_SHIFT 19 /* Shift value for LESENSE_BUFDATAV */ +#define _LESENSE_IF_BUFDATAV_MASK 0x80000UL /* Bit mask for LESENSE_BUFDATAV */ +#define _LESENSE_IF_BUFDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFDATAV_DEFAULT (_LESENSE_IF_BUFDATAV_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFLEVEL (0x1UL << 20) /* */ +#define _LESENSE_IF_BUFLEVEL_SHIFT 20 /* Shift value for LESENSE_BUFLEVEL */ +#define _LESENSE_IF_BUFLEVEL_MASK 0x100000UL /* Bit mask for LESENSE_BUFLEVEL */ +#define _LESENSE_IF_BUFLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFLEVEL_DEFAULT (_LESENSE_IF_BUFLEVEL_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFOF (0x1UL << 21) /* */ +#define _LESENSE_IF_BUFOF_SHIFT 21 /* Shift value for LESENSE_BUFOF */ +#define _LESENSE_IF_BUFOF_MASK 0x200000UL /* Bit mask for LESENSE_BUFOF */ +#define _LESENSE_IF_BUFOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_BUFOF_DEFAULT (_LESENSE_IF_BUFOF_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CNTOF (0x1UL << 22) /* */ +#define _LESENSE_IF_CNTOF_SHIFT 22 /* Shift value for LESENSE_CNTOF */ +#define _LESENSE_IF_CNTOF_MASK 0x400000UL /* Bit mask for LESENSE_CNTOF */ +#define _LESENSE_IF_CNTOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IF */ +#define LESENSE_IF_CNTOF_DEFAULT (_LESENSE_IF_CNTOF_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_IF */ + +/* Bit fields for LESENSE IFC */ + +#define _LESENSE_IFC_RESETVALUE 0x00000000UL /* Default value for LESENSE_IFC */ +#define _LESENSE_IFC_MASK 0x007FFFFFUL /* Mask for LESENSE_IFC */ + +#define LESENSE_IFC_CH0 (0x1UL << 0) /* */ +#define _LESENSE_IFC_CH0_SHIFT 0 /* Shift value for LESENSE_CH0 */ +#define _LESENSE_IFC_CH0_MASK 0x1UL /* Bit mask for LESENSE_CH0 */ +#define _LESENSE_IFC_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH0_DEFAULT (_LESENSE_IFC_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH1 (0x1UL << 1) /* */ +#define _LESENSE_IFC_CH1_SHIFT 1 /* Shift value for LESENSE_CH1 */ +#define _LESENSE_IFC_CH1_MASK 0x2UL /* Bit mask for LESENSE_CH1 */ +#define _LESENSE_IFC_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH1_DEFAULT (_LESENSE_IFC_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH2 (0x1UL << 2) /* */ +#define _LESENSE_IFC_CH2_SHIFT 2 /* Shift value for LESENSE_CH2 */ +#define _LESENSE_IFC_CH2_MASK 0x4UL /* Bit mask for LESENSE_CH2 */ +#define _LESENSE_IFC_CH2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH2_DEFAULT (_LESENSE_IFC_CH2_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH3 (0x1UL << 3) /* */ +#define _LESENSE_IFC_CH3_SHIFT 3 /* Shift value for LESENSE_CH3 */ +#define _LESENSE_IFC_CH3_MASK 0x8UL /* Bit mask for LESENSE_CH3 */ +#define _LESENSE_IFC_CH3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH3_DEFAULT (_LESENSE_IFC_CH3_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH4 (0x1UL << 4) /* */ +#define _LESENSE_IFC_CH4_SHIFT 4 /* Shift value for LESENSE_CH4 */ +#define _LESENSE_IFC_CH4_MASK 0x10UL /* Bit mask for LESENSE_CH4 */ +#define _LESENSE_IFC_CH4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH4_DEFAULT (_LESENSE_IFC_CH4_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH5 (0x1UL << 5) /* */ +#define _LESENSE_IFC_CH5_SHIFT 5 /* Shift value for LESENSE_CH5 */ +#define _LESENSE_IFC_CH5_MASK 0x20UL /* Bit mask for LESENSE_CH5 */ +#define _LESENSE_IFC_CH5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH5_DEFAULT (_LESENSE_IFC_CH5_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH6 (0x1UL << 6) /* */ +#define _LESENSE_IFC_CH6_SHIFT 6 /* Shift value for LESENSE_CH6 */ +#define _LESENSE_IFC_CH6_MASK 0x40UL /* Bit mask for LESENSE_CH6 */ +#define _LESENSE_IFC_CH6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH6_DEFAULT (_LESENSE_IFC_CH6_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH7 (0x1UL << 7) /* */ +#define _LESENSE_IFC_CH7_SHIFT 7 /* Shift value for LESENSE_CH7 */ +#define _LESENSE_IFC_CH7_MASK 0x80UL /* Bit mask for LESENSE_CH7 */ +#define _LESENSE_IFC_CH7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH7_DEFAULT (_LESENSE_IFC_CH7_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH8 (0x1UL << 8) /* */ +#define _LESENSE_IFC_CH8_SHIFT 8 /* Shift value for LESENSE_CH8 */ +#define _LESENSE_IFC_CH8_MASK 0x100UL /* Bit mask for LESENSE_CH8 */ +#define _LESENSE_IFC_CH8_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH8_DEFAULT (_LESENSE_IFC_CH8_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH9 (0x1UL << 9) /* */ +#define _LESENSE_IFC_CH9_SHIFT 9 /* Shift value for LESENSE_CH9 */ +#define _LESENSE_IFC_CH9_MASK 0x200UL /* Bit mask for LESENSE_CH9 */ +#define _LESENSE_IFC_CH9_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH9_DEFAULT (_LESENSE_IFC_CH9_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH10 (0x1UL << 10) /* */ +#define _LESENSE_IFC_CH10_SHIFT 10 /* Shift value for LESENSE_CH10 */ +#define _LESENSE_IFC_CH10_MASK 0x400UL /* Bit mask for LESENSE_CH10 */ +#define _LESENSE_IFC_CH10_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH10_DEFAULT (_LESENSE_IFC_CH10_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH11 (0x1UL << 11) /* */ +#define _LESENSE_IFC_CH11_SHIFT 11 /* Shift value for LESENSE_CH11 */ +#define _LESENSE_IFC_CH11_MASK 0x800UL /* Bit mask for LESENSE_CH11 */ +#define _LESENSE_IFC_CH11_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH11_DEFAULT (_LESENSE_IFC_CH11_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH12 (0x1UL << 12) /* */ +#define _LESENSE_IFC_CH12_SHIFT 12 /* Shift value for LESENSE_CH12 */ +#define _LESENSE_IFC_CH12_MASK 0x1000UL /* Bit mask for LESENSE_CH12 */ +#define _LESENSE_IFC_CH12_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH12_DEFAULT (_LESENSE_IFC_CH12_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH13 (0x1UL << 13) /* */ +#define _LESENSE_IFC_CH13_SHIFT 13 /* Shift value for LESENSE_CH13 */ +#define _LESENSE_IFC_CH13_MASK 0x2000UL /* Bit mask for LESENSE_CH13 */ +#define _LESENSE_IFC_CH13_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH13_DEFAULT (_LESENSE_IFC_CH13_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH14 (0x1UL << 14) /* */ +#define _LESENSE_IFC_CH14_SHIFT 14 /* Shift value for LESENSE_CH14 */ +#define _LESENSE_IFC_CH14_MASK 0x4000UL /* Bit mask for LESENSE_CH14 */ +#define _LESENSE_IFC_CH14_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH14_DEFAULT (_LESENSE_IFC_CH14_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH15 (0x1UL << 15) /* */ +#define _LESENSE_IFC_CH15_SHIFT 15 /* Shift value for LESENSE_CH15 */ +#define _LESENSE_IFC_CH15_MASK 0x8000UL /* Bit mask for LESENSE_CH15 */ +#define _LESENSE_IFC_CH15_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CH15_DEFAULT (_LESENSE_IFC_CH15_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_SCANCOMPLETE (0x1UL << 16) /* */ +#define _LESENSE_IFC_SCANCOMPLETE_SHIFT 16 /* Shift value for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IFC_SCANCOMPLETE_MASK 0x10000UL /* Bit mask for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IFC_SCANCOMPLETE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_SCANCOMPLETE_DEFAULT (_LESENSE_IFC_SCANCOMPLETE_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_DEC (0x1UL << 17) /* */ +#define _LESENSE_IFC_DEC_SHIFT 17 /* Shift value for LESENSE_DEC */ +#define _LESENSE_IFC_DEC_MASK 0x20000UL /* Bit mask for LESENSE_DEC */ +#define _LESENSE_IFC_DEC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_DEC_DEFAULT (_LESENSE_IFC_DEC_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_DECERR (0x1UL << 18) /* */ +#define _LESENSE_IFC_DECERR_SHIFT 18 /* Shift value for LESENSE_DECERR */ +#define _LESENSE_IFC_DECERR_MASK 0x40000UL /* Bit mask for LESENSE_DECERR */ +#define _LESENSE_IFC_DECERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_DECERR_DEFAULT (_LESENSE_IFC_DECERR_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFDATAV (0x1UL << 19) /* */ +#define _LESENSE_IFC_BUFDATAV_SHIFT 19 /* Shift value for LESENSE_BUFDATAV */ +#define _LESENSE_IFC_BUFDATAV_MASK 0x80000UL /* Bit mask for LESENSE_BUFDATAV */ +#define _LESENSE_IFC_BUFDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFDATAV_DEFAULT (_LESENSE_IFC_BUFDATAV_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFLEVEL (0x1UL << 20) /* */ +#define _LESENSE_IFC_BUFLEVEL_SHIFT 20 /* Shift value for LESENSE_BUFLEVEL */ +#define _LESENSE_IFC_BUFLEVEL_MASK 0x100000UL /* Bit mask for LESENSE_BUFLEVEL */ +#define _LESENSE_IFC_BUFLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFLEVEL_DEFAULT (_LESENSE_IFC_BUFLEVEL_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFOF (0x1UL << 21) /* */ +#define _LESENSE_IFC_BUFOF_SHIFT 21 /* Shift value for LESENSE_BUFOF */ +#define _LESENSE_IFC_BUFOF_MASK 0x200000UL /* Bit mask for LESENSE_BUFOF */ +#define _LESENSE_IFC_BUFOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_BUFOF_DEFAULT (_LESENSE_IFC_BUFOF_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CNTOF (0x1UL << 22) /* */ +#define _LESENSE_IFC_CNTOF_SHIFT 22 /* Shift value for LESENSE_CNTOF */ +#define _LESENSE_IFC_CNTOF_MASK 0x400000UL /* Bit mask for LESENSE_CNTOF */ +#define _LESENSE_IFC_CNTOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFC */ +#define LESENSE_IFC_CNTOF_DEFAULT (_LESENSE_IFC_CNTOF_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_IFC */ + +/* Bit fields for LESENSE IFS */ + +#define _LESENSE_IFS_RESETVALUE 0x00000000UL /* Default value for LESENSE_IFS */ +#define _LESENSE_IFS_MASK 0x007FFFFFUL /* Mask for LESENSE_IFS */ + +#define LESENSE_IFS_CH0 (0x1UL << 0) /* */ +#define _LESENSE_IFS_CH0_SHIFT 0 /* Shift value for LESENSE_CH0 */ +#define _LESENSE_IFS_CH0_MASK 0x1UL /* Bit mask for LESENSE_CH0 */ +#define _LESENSE_IFS_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH0_DEFAULT (_LESENSE_IFS_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH1 (0x1UL << 1) /* */ +#define _LESENSE_IFS_CH1_SHIFT 1 /* Shift value for LESENSE_CH1 */ +#define _LESENSE_IFS_CH1_MASK 0x2UL /* Bit mask for LESENSE_CH1 */ +#define _LESENSE_IFS_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH1_DEFAULT (_LESENSE_IFS_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH2 (0x1UL << 2) /* */ +#define _LESENSE_IFS_CH2_SHIFT 2 /* Shift value for LESENSE_CH2 */ +#define _LESENSE_IFS_CH2_MASK 0x4UL /* Bit mask for LESENSE_CH2 */ +#define _LESENSE_IFS_CH2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH2_DEFAULT (_LESENSE_IFS_CH2_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH3 (0x1UL << 3) /* */ +#define _LESENSE_IFS_CH3_SHIFT 3 /* Shift value for LESENSE_CH3 */ +#define _LESENSE_IFS_CH3_MASK 0x8UL /* Bit mask for LESENSE_CH3 */ +#define _LESENSE_IFS_CH3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH3_DEFAULT (_LESENSE_IFS_CH3_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH4 (0x1UL << 4) /* */ +#define _LESENSE_IFS_CH4_SHIFT 4 /* Shift value for LESENSE_CH4 */ +#define _LESENSE_IFS_CH4_MASK 0x10UL /* Bit mask for LESENSE_CH4 */ +#define _LESENSE_IFS_CH4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH4_DEFAULT (_LESENSE_IFS_CH4_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH5 (0x1UL << 5) /* */ +#define _LESENSE_IFS_CH5_SHIFT 5 /* Shift value for LESENSE_CH5 */ +#define _LESENSE_IFS_CH5_MASK 0x20UL /* Bit mask for LESENSE_CH5 */ +#define _LESENSE_IFS_CH5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH5_DEFAULT (_LESENSE_IFS_CH5_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH6 (0x1UL << 6) /* */ +#define _LESENSE_IFS_CH6_SHIFT 6 /* Shift value for LESENSE_CH6 */ +#define _LESENSE_IFS_CH6_MASK 0x40UL /* Bit mask for LESENSE_CH6 */ +#define _LESENSE_IFS_CH6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH6_DEFAULT (_LESENSE_IFS_CH6_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH7 (0x1UL << 7) /* */ +#define _LESENSE_IFS_CH7_SHIFT 7 /* Shift value for LESENSE_CH7 */ +#define _LESENSE_IFS_CH7_MASK 0x80UL /* Bit mask for LESENSE_CH7 */ +#define _LESENSE_IFS_CH7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH7_DEFAULT (_LESENSE_IFS_CH7_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH8 (0x1UL << 8) /* */ +#define _LESENSE_IFS_CH8_SHIFT 8 /* Shift value for LESENSE_CH8 */ +#define _LESENSE_IFS_CH8_MASK 0x100UL /* Bit mask for LESENSE_CH8 */ +#define _LESENSE_IFS_CH8_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH8_DEFAULT (_LESENSE_IFS_CH8_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH9 (0x1UL << 9) /* */ +#define _LESENSE_IFS_CH9_SHIFT 9 /* Shift value for LESENSE_CH9 */ +#define _LESENSE_IFS_CH9_MASK 0x200UL /* Bit mask for LESENSE_CH9 */ +#define _LESENSE_IFS_CH9_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH9_DEFAULT (_LESENSE_IFS_CH9_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH10 (0x1UL << 10) /* */ +#define _LESENSE_IFS_CH10_SHIFT 10 /* Shift value for LESENSE_CH10 */ +#define _LESENSE_IFS_CH10_MASK 0x400UL /* Bit mask for LESENSE_CH10 */ +#define _LESENSE_IFS_CH10_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH10_DEFAULT (_LESENSE_IFS_CH10_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH11 (0x1UL << 11) /* */ +#define _LESENSE_IFS_CH11_SHIFT 11 /* Shift value for LESENSE_CH11 */ +#define _LESENSE_IFS_CH11_MASK 0x800UL /* Bit mask for LESENSE_CH11 */ +#define _LESENSE_IFS_CH11_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH11_DEFAULT (_LESENSE_IFS_CH11_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH12 (0x1UL << 12) /* */ +#define _LESENSE_IFS_CH12_SHIFT 12 /* Shift value for LESENSE_CH12 */ +#define _LESENSE_IFS_CH12_MASK 0x1000UL /* Bit mask for LESENSE_CH12 */ +#define _LESENSE_IFS_CH12_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH12_DEFAULT (_LESENSE_IFS_CH12_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH13 (0x1UL << 13) /* */ +#define _LESENSE_IFS_CH13_SHIFT 13 /* Shift value for LESENSE_CH13 */ +#define _LESENSE_IFS_CH13_MASK 0x2000UL /* Bit mask for LESENSE_CH13 */ +#define _LESENSE_IFS_CH13_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH13_DEFAULT (_LESENSE_IFS_CH13_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH14 (0x1UL << 14) /* */ +#define _LESENSE_IFS_CH14_SHIFT 14 /* Shift value for LESENSE_CH14 */ +#define _LESENSE_IFS_CH14_MASK 0x4000UL /* Bit mask for LESENSE_CH14 */ +#define _LESENSE_IFS_CH14_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH14_DEFAULT (_LESENSE_IFS_CH14_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH15 (0x1UL << 15) /* */ +#define _LESENSE_IFS_CH15_SHIFT 15 /* Shift value for LESENSE_CH15 */ +#define _LESENSE_IFS_CH15_MASK 0x8000UL /* Bit mask for LESENSE_CH15 */ +#define _LESENSE_IFS_CH15_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CH15_DEFAULT (_LESENSE_IFS_CH15_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_SCANCOMPLETE (0x1UL << 16) /* */ +#define _LESENSE_IFS_SCANCOMPLETE_SHIFT 16 /* Shift value for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IFS_SCANCOMPLETE_MASK 0x10000UL /* Bit mask for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IFS_SCANCOMPLETE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_SCANCOMPLETE_DEFAULT (_LESENSE_IFS_SCANCOMPLETE_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_DEC (0x1UL << 17) /* */ +#define _LESENSE_IFS_DEC_SHIFT 17 /* Shift value for LESENSE_DEC */ +#define _LESENSE_IFS_DEC_MASK 0x20000UL /* Bit mask for LESENSE_DEC */ +#define _LESENSE_IFS_DEC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_DEC_DEFAULT (_LESENSE_IFS_DEC_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_DECERR (0x1UL << 18) /* */ +#define _LESENSE_IFS_DECERR_SHIFT 18 /* Shift value for LESENSE_DECERR */ +#define _LESENSE_IFS_DECERR_MASK 0x40000UL /* Bit mask for LESENSE_DECERR */ +#define _LESENSE_IFS_DECERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_DECERR_DEFAULT (_LESENSE_IFS_DECERR_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFDATAV (0x1UL << 19) /* */ +#define _LESENSE_IFS_BUFDATAV_SHIFT 19 /* Shift value for LESENSE_BUFDATAV */ +#define _LESENSE_IFS_BUFDATAV_MASK 0x80000UL /* Bit mask for LESENSE_BUFDATAV */ +#define _LESENSE_IFS_BUFDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFDATAV_DEFAULT (_LESENSE_IFS_BUFDATAV_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFLEVEL (0x1UL << 20) /* */ +#define _LESENSE_IFS_BUFLEVEL_SHIFT 20 /* Shift value for LESENSE_BUFLEVEL */ +#define _LESENSE_IFS_BUFLEVEL_MASK 0x100000UL /* Bit mask for LESENSE_BUFLEVEL */ +#define _LESENSE_IFS_BUFLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFLEVEL_DEFAULT (_LESENSE_IFS_BUFLEVEL_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFOF (0x1UL << 21) /* */ +#define _LESENSE_IFS_BUFOF_SHIFT 21 /* Shift value for LESENSE_BUFOF */ +#define _LESENSE_IFS_BUFOF_MASK 0x200000UL /* Bit mask for LESENSE_BUFOF */ +#define _LESENSE_IFS_BUFOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_BUFOF_DEFAULT (_LESENSE_IFS_BUFOF_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CNTOF (0x1UL << 22) /* */ +#define _LESENSE_IFS_CNTOF_SHIFT 22 /* Shift value for LESENSE_CNTOF */ +#define _LESENSE_IFS_CNTOF_MASK 0x400000UL /* Bit mask for LESENSE_CNTOF */ +#define _LESENSE_IFS_CNTOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IFS */ +#define LESENSE_IFS_CNTOF_DEFAULT (_LESENSE_IFS_CNTOF_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_IFS */ + +/* Bit fields for LESENSE IEN */ + +#define _LESENSE_IEN_RESETVALUE 0x00000000UL /* Default value for LESENSE_IEN */ +#define _LESENSE_IEN_MASK 0x007FFFFFUL /* Mask for LESENSE_IEN */ + +#define LESENSE_IEN_CH0 (0x1UL << 0) /* */ +#define _LESENSE_IEN_CH0_SHIFT 0 /* Shift value for LESENSE_CH0 */ +#define _LESENSE_IEN_CH0_MASK 0x1UL /* Bit mask for LESENSE_CH0 */ +#define _LESENSE_IEN_CH0_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH0_DEFAULT (_LESENSE_IEN_CH0_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH1 (0x1UL << 1) /* */ +#define _LESENSE_IEN_CH1_SHIFT 1 /* Shift value for LESENSE_CH1 */ +#define _LESENSE_IEN_CH1_MASK 0x2UL /* Bit mask for LESENSE_CH1 */ +#define _LESENSE_IEN_CH1_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH1_DEFAULT (_LESENSE_IEN_CH1_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH2 (0x1UL << 2) /* */ +#define _LESENSE_IEN_CH2_SHIFT 2 /* Shift value for LESENSE_CH2 */ +#define _LESENSE_IEN_CH2_MASK 0x4UL /* Bit mask for LESENSE_CH2 */ +#define _LESENSE_IEN_CH2_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH2_DEFAULT (_LESENSE_IEN_CH2_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH3 (0x1UL << 3) /* */ +#define _LESENSE_IEN_CH3_SHIFT 3 /* Shift value for LESENSE_CH3 */ +#define _LESENSE_IEN_CH3_MASK 0x8UL /* Bit mask for LESENSE_CH3 */ +#define _LESENSE_IEN_CH3_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH3_DEFAULT (_LESENSE_IEN_CH3_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH4 (0x1UL << 4) /* */ +#define _LESENSE_IEN_CH4_SHIFT 4 /* Shift value for LESENSE_CH4 */ +#define _LESENSE_IEN_CH4_MASK 0x10UL /* Bit mask for LESENSE_CH4 */ +#define _LESENSE_IEN_CH4_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH4_DEFAULT (_LESENSE_IEN_CH4_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH5 (0x1UL << 5) /* */ +#define _LESENSE_IEN_CH5_SHIFT 5 /* Shift value for LESENSE_CH5 */ +#define _LESENSE_IEN_CH5_MASK 0x20UL /* Bit mask for LESENSE_CH5 */ +#define _LESENSE_IEN_CH5_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH5_DEFAULT (_LESENSE_IEN_CH5_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH6 (0x1UL << 6) /* */ +#define _LESENSE_IEN_CH6_SHIFT 6 /* Shift value for LESENSE_CH6 */ +#define _LESENSE_IEN_CH6_MASK 0x40UL /* Bit mask for LESENSE_CH6 */ +#define _LESENSE_IEN_CH6_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH6_DEFAULT (_LESENSE_IEN_CH6_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH7 (0x1UL << 7) /* */ +#define _LESENSE_IEN_CH7_SHIFT 7 /* Shift value for LESENSE_CH7 */ +#define _LESENSE_IEN_CH7_MASK 0x80UL /* Bit mask for LESENSE_CH7 */ +#define _LESENSE_IEN_CH7_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH7_DEFAULT (_LESENSE_IEN_CH7_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH8 (0x1UL << 8) /* */ +#define _LESENSE_IEN_CH8_SHIFT 8 /* Shift value for LESENSE_CH8 */ +#define _LESENSE_IEN_CH8_MASK 0x100UL /* Bit mask for LESENSE_CH8 */ +#define _LESENSE_IEN_CH8_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH8_DEFAULT (_LESENSE_IEN_CH8_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH9 (0x1UL << 9) /* */ +#define _LESENSE_IEN_CH9_SHIFT 9 /* Shift value for LESENSE_CH9 */ +#define _LESENSE_IEN_CH9_MASK 0x200UL /* Bit mask for LESENSE_CH9 */ +#define _LESENSE_IEN_CH9_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH9_DEFAULT (_LESENSE_IEN_CH9_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH10 (0x1UL << 10) /* */ +#define _LESENSE_IEN_CH10_SHIFT 10 /* Shift value for LESENSE_CH10 */ +#define _LESENSE_IEN_CH10_MASK 0x400UL /* Bit mask for LESENSE_CH10 */ +#define _LESENSE_IEN_CH10_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH10_DEFAULT (_LESENSE_IEN_CH10_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH11 (0x1UL << 11) /* */ +#define _LESENSE_IEN_CH11_SHIFT 11 /* Shift value for LESENSE_CH11 */ +#define _LESENSE_IEN_CH11_MASK 0x800UL /* Bit mask for LESENSE_CH11 */ +#define _LESENSE_IEN_CH11_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH11_DEFAULT (_LESENSE_IEN_CH11_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH12 (0x1UL << 12) /* */ +#define _LESENSE_IEN_CH12_SHIFT 12 /* Shift value for LESENSE_CH12 */ +#define _LESENSE_IEN_CH12_MASK 0x1000UL /* Bit mask for LESENSE_CH12 */ +#define _LESENSE_IEN_CH12_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH12_DEFAULT (_LESENSE_IEN_CH12_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH13 (0x1UL << 13) /* */ +#define _LESENSE_IEN_CH13_SHIFT 13 /* Shift value for LESENSE_CH13 */ +#define _LESENSE_IEN_CH13_MASK 0x2000UL /* Bit mask for LESENSE_CH13 */ +#define _LESENSE_IEN_CH13_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH13_DEFAULT (_LESENSE_IEN_CH13_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH14 (0x1UL << 14) /* */ +#define _LESENSE_IEN_CH14_SHIFT 14 /* Shift value for LESENSE_CH14 */ +#define _LESENSE_IEN_CH14_MASK 0x4000UL /* Bit mask for LESENSE_CH14 */ +#define _LESENSE_IEN_CH14_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH14_DEFAULT (_LESENSE_IEN_CH14_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH15 (0x1UL << 15) /* */ +#define _LESENSE_IEN_CH15_SHIFT 15 /* Shift value for LESENSE_CH15 */ +#define _LESENSE_IEN_CH15_MASK 0x8000UL /* Bit mask for LESENSE_CH15 */ +#define _LESENSE_IEN_CH15_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CH15_DEFAULT (_LESENSE_IEN_CH15_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_SCANCOMPLETE (0x1UL << 16) /* */ +#define _LESENSE_IEN_SCANCOMPLETE_SHIFT 16 /* Shift value for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IEN_SCANCOMPLETE_MASK 0x10000UL /* Bit mask for LESENSE_SCANCOMPLETE */ +#define _LESENSE_IEN_SCANCOMPLETE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_SCANCOMPLETE_DEFAULT (_LESENSE_IEN_SCANCOMPLETE_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_DEC (0x1UL << 17) /* */ +#define _LESENSE_IEN_DEC_SHIFT 17 /* Shift value for LESENSE_DEC */ +#define _LESENSE_IEN_DEC_MASK 0x20000UL /* Bit mask for LESENSE_DEC */ +#define _LESENSE_IEN_DEC_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_DEC_DEFAULT (_LESENSE_IEN_DEC_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_DECERR (0x1UL << 18) /* */ +#define _LESENSE_IEN_DECERR_SHIFT 18 /* Shift value for LESENSE_DECERR */ +#define _LESENSE_IEN_DECERR_MASK 0x40000UL /* Bit mask for LESENSE_DECERR */ +#define _LESENSE_IEN_DECERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_DECERR_DEFAULT (_LESENSE_IEN_DECERR_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFDATAV (0x1UL << 19) /* */ +#define _LESENSE_IEN_BUFDATAV_SHIFT 19 /* Shift value for LESENSE_BUFDATAV */ +#define _LESENSE_IEN_BUFDATAV_MASK 0x80000UL /* Bit mask for LESENSE_BUFDATAV */ +#define _LESENSE_IEN_BUFDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFDATAV_DEFAULT (_LESENSE_IEN_BUFDATAV_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFLEVEL (0x1UL << 20) /* */ +#define _LESENSE_IEN_BUFLEVEL_SHIFT 20 /* Shift value for LESENSE_BUFLEVEL */ +#define _LESENSE_IEN_BUFLEVEL_MASK 0x100000UL /* Bit mask for LESENSE_BUFLEVEL */ +#define _LESENSE_IEN_BUFLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFLEVEL_DEFAULT (_LESENSE_IEN_BUFLEVEL_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFOF (0x1UL << 21) /* */ +#define _LESENSE_IEN_BUFOF_SHIFT 21 /* Shift value for LESENSE_BUFOF */ +#define _LESENSE_IEN_BUFOF_MASK 0x200000UL /* Bit mask for LESENSE_BUFOF */ +#define _LESENSE_IEN_BUFOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_BUFOF_DEFAULT (_LESENSE_IEN_BUFOF_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CNTOF (0x1UL << 22) /* */ +#define _LESENSE_IEN_CNTOF_SHIFT 22 /* Shift value for LESENSE_CNTOF */ +#define _LESENSE_IEN_CNTOF_MASK 0x400000UL /* Bit mask for LESENSE_CNTOF */ +#define _LESENSE_IEN_CNTOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_IEN */ +#define LESENSE_IEN_CNTOF_DEFAULT (_LESENSE_IEN_CNTOF_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_IEN */ + +/* Bit fields for LESENSE SYNCBUSY */ + +#define _LESENSE_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for LESENSE_SYNCBUSY */ +#define _LESENSE_SYNCBUSY_MASK 0x07E3FFFFUL /* Mask for LESENSE_SYNCBUSY */ + +#define LESENSE_SYNCBUSY_CTRL (0x1UL << 0) /* LESENSE_CTRL Register Busy */ +#define _LESENSE_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for LESENSE_CTRL */ +#define _LESENSE_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for LESENSE_CTRL */ +#define _LESENSE_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CTRL_DEFAULT (_LESENSE_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TIMCTRL (0x1UL << 1) /* LESENSE_TIMCTRL Register Busy */ +#define _LESENSE_SYNCBUSY_TIMCTRL_SHIFT 1 /* Shift value for LESENSE_TIMCTRL */ +#define _LESENSE_SYNCBUSY_TIMCTRL_MASK 0x2UL /* Bit mask for LESENSE_TIMCTRL */ +#define _LESENSE_SYNCBUSY_TIMCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TIMCTRL_DEFAULT (_LESENSE_SYNCBUSY_TIMCTRL_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_PERCTRL (0x1UL << 2) /* LESENSE_PERCTRL Register Busy */ +#define _LESENSE_SYNCBUSY_PERCTRL_SHIFT 2 /* Shift value for LESENSE_PERCTRL */ +#define _LESENSE_SYNCBUSY_PERCTRL_MASK 0x4UL /* Bit mask for LESENSE_PERCTRL */ +#define _LESENSE_SYNCBUSY_PERCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_PERCTRL_DEFAULT (_LESENSE_SYNCBUSY_PERCTRL_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DECCTRL (0x1UL << 3) /* LESENSE_DECCTRL Register Busy */ +#define _LESENSE_SYNCBUSY_DECCTRL_SHIFT 3 /* Shift value for LESENSE_DECCTRL */ +#define _LESENSE_SYNCBUSY_DECCTRL_MASK 0x8UL /* Bit mask for LESENSE_DECCTRL */ +#define _LESENSE_SYNCBUSY_DECCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DECCTRL_DEFAULT (_LESENSE_SYNCBUSY_DECCTRL_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_BIASCTRL (0x1UL << 4) /* LESENSE_BIASCTRL Register Busy */ +#define _LESENSE_SYNCBUSY_BIASCTRL_SHIFT 4 /* Shift value for LESENSE_BIASCTRL */ +#define _LESENSE_SYNCBUSY_BIASCTRL_MASK 0x10UL /* Bit mask for LESENSE_BIASCTRL */ +#define _LESENSE_SYNCBUSY_BIASCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_BIASCTRL_DEFAULT (_LESENSE_SYNCBUSY_BIASCTRL_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CMD (0x1UL << 5) /* LESENSE_CMD Register Busy */ +#define _LESENSE_SYNCBUSY_CMD_SHIFT 5 /* Shift value for LESENSE_CMD */ +#define _LESENSE_SYNCBUSY_CMD_MASK 0x20UL /* Bit mask for LESENSE_CMD */ +#define _LESENSE_SYNCBUSY_CMD_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CMD_DEFAULT (_LESENSE_SYNCBUSY_CMD_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CHEN (0x1UL << 6) /* LESENSE_CHEN Register Busy */ +#define _LESENSE_SYNCBUSY_CHEN_SHIFT 6 /* Shift value for LESENSE_CHEN */ +#define _LESENSE_SYNCBUSY_CHEN_MASK 0x40UL /* Bit mask for LESENSE_CHEN */ +#define _LESENSE_SYNCBUSY_CHEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CHEN_DEFAULT (_LESENSE_SYNCBUSY_CHEN_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_SCANRES (0x1UL << 7) /* LESENSE_SCANRES Register Busy */ +#define _LESENSE_SYNCBUSY_SCANRES_SHIFT 7 /* Shift value for LESENSE_SCANRES */ +#define _LESENSE_SYNCBUSY_SCANRES_MASK 0x80UL /* Bit mask for LESENSE_SCANRES */ +#define _LESENSE_SYNCBUSY_SCANRES_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_SCANRES_DEFAULT (_LESENSE_SYNCBUSY_SCANRES_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_STATUS (0x1UL << 8) /* LESENSE_STATUS Register Busy */ +#define _LESENSE_SYNCBUSY_STATUS_SHIFT 8 /* Shift value for LESENSE_STATUS */ +#define _LESENSE_SYNCBUSY_STATUS_MASK 0x100UL /* Bit mask for LESENSE_STATUS */ +#define _LESENSE_SYNCBUSY_STATUS_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_STATUS_DEFAULT (_LESENSE_SYNCBUSY_STATUS_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_PTR (0x1UL << 9) /* LESENSE_PTR Register Busy */ +#define _LESENSE_SYNCBUSY_PTR_SHIFT 9 /* Shift value for LESENSE_PTR */ +#define _LESENSE_SYNCBUSY_PTR_MASK 0x200UL /* Bit mask for LESENSE_PTR */ +#define _LESENSE_SYNCBUSY_PTR_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_PTR_DEFAULT (_LESENSE_SYNCBUSY_PTR_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_BUFDATA (0x1UL << 10) /* LESENSE_BUFDATA Register Busy */ +#define _LESENSE_SYNCBUSY_BUFDATA_SHIFT 10 /* Shift value for LESENSE_BUFDATA */ +#define _LESENSE_SYNCBUSY_BUFDATA_MASK 0x400UL /* Bit mask for LESENSE_BUFDATA */ +#define _LESENSE_SYNCBUSY_BUFDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_BUFDATA_DEFAULT (_LESENSE_SYNCBUSY_BUFDATA_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CURCH (0x1UL << 11) /* LESENSE_CURCH Register Busy */ +#define _LESENSE_SYNCBUSY_CURCH_SHIFT 11 /* Shift value for LESENSE_CURCH */ +#define _LESENSE_SYNCBUSY_CURCH_MASK 0x800UL /* Bit mask for LESENSE_CURCH */ +#define _LESENSE_SYNCBUSY_CURCH_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_CURCH_DEFAULT (_LESENSE_SYNCBUSY_CURCH_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DECSTATE (0x1UL << 12) /* LESENSE_DECSTATE Register Busy */ +#define _LESENSE_SYNCBUSY_DECSTATE_SHIFT 12 /* Shift value for LESENSE_DECSTATE */ +#define _LESENSE_SYNCBUSY_DECSTATE_MASK 0x1000UL /* Bit mask for LESENSE_DECSTATE */ +#define _LESENSE_SYNCBUSY_DECSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DECSTATE_DEFAULT (_LESENSE_SYNCBUSY_DECSTATE_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_SENSORSTATE (0x1UL << 13) /* LESENSE_SENSORSTATE Register Busy */ +#define _LESENSE_SYNCBUSY_SENSORSTATE_SHIFT 13 /* Shift value for LESENSE_SENSORSTATE */ +#define _LESENSE_SYNCBUSY_SENSORSTATE_MASK 0x2000UL /* Bit mask for LESENSE_SENSORSTATE */ +#define _LESENSE_SYNCBUSY_SENSORSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_SENSORSTATE_DEFAULT (_LESENSE_SYNCBUSY_SENSORSTATE_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_IDLECONF (0x1UL << 14) /* LESENSE_IDLECONF Register Busy */ +#define _LESENSE_SYNCBUSY_IDLECONF_SHIFT 14 /* Shift value for LESENSE_IDLECONF */ +#define _LESENSE_SYNCBUSY_IDLECONF_MASK 0x4000UL /* Bit mask for LESENSE_IDLECONF */ +#define _LESENSE_SYNCBUSY_IDLECONF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_IDLECONF_DEFAULT (_LESENSE_SYNCBUSY_IDLECONF_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_ALTEXCONF (0x1UL << 15) /* LESENSE_ALTEXCONF Register Busy */ +#define _LESENSE_SYNCBUSY_ALTEXCONF_SHIFT 15 /* Shift value for LESENSE_ALTEXCONF */ +#define _LESENSE_SYNCBUSY_ALTEXCONF_MASK 0x8000UL /* Bit mask for LESENSE_ALTEXCONF */ +#define _LESENSE_SYNCBUSY_ALTEXCONF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_ALTEXCONF_DEFAULT (_LESENSE_SYNCBUSY_ALTEXCONF_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_ROUTE (0x1UL << 16) /* LESENSE_ROUTE Register Busy */ +#define _LESENSE_SYNCBUSY_ROUTE_SHIFT 16 /* Shift value for LESENSE_ROUTE */ +#define _LESENSE_SYNCBUSY_ROUTE_MASK 0x10000UL /* Bit mask for LESENSE_ROUTE */ +#define _LESENSE_SYNCBUSY_ROUTE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_ROUTE_DEFAULT (_LESENSE_SYNCBUSY_ROUTE_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_POWERDOWN (0x1UL << 17) /* LESENSE_POWERDOWN Register Busy */ +#define _LESENSE_SYNCBUSY_POWERDOWN_SHIFT 17 /* Shift value for LESENSE_POWERDOWN */ +#define _LESENSE_SYNCBUSY_POWERDOWN_MASK 0x20000UL /* Bit mask for LESENSE_POWERDOWN */ +#define _LESENSE_SYNCBUSY_POWERDOWN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_POWERDOWN_DEFAULT (_LESENSE_SYNCBUSY_POWERDOWN_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TCONFA (0x1UL << 21) /* LESENSE_STx_TCONFA Register Busy */ +#define _LESENSE_SYNCBUSY_TCONFA_SHIFT 21 /* Shift value for LESENSE_TCONFA */ +#define _LESENSE_SYNCBUSY_TCONFA_MASK 0x200000UL /* Bit mask for LESENSE_TCONFA */ +#define _LESENSE_SYNCBUSY_TCONFA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TCONFA_DEFAULT (_LESENSE_SYNCBUSY_TCONFA_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TCONFB (0x1UL << 22) /* LESENSE_STx_TCONFB Register Busy */ +#define _LESENSE_SYNCBUSY_TCONFB_SHIFT 22 /* Shift value for LESENSE_TCONFB */ +#define _LESENSE_SYNCBUSY_TCONFB_MASK 0x400000UL /* Bit mask for LESENSE_TCONFB */ +#define _LESENSE_SYNCBUSY_TCONFB_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TCONFB_DEFAULT (_LESENSE_SYNCBUSY_TCONFB_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DATA (0x1UL << 23) /* LESENSE_BUFx_DATA Register Busy */ +#define _LESENSE_SYNCBUSY_DATA_SHIFT 23 /* Shift value for LESENSE_DATA */ +#define _LESENSE_SYNCBUSY_DATA_MASK 0x800000UL /* Bit mask for LESENSE_DATA */ +#define _LESENSE_SYNCBUSY_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_DATA_DEFAULT (_LESENSE_SYNCBUSY_DATA_DEFAULT << 23) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TIMING (0x1UL << 24) /* LESENSE_CHx_TIMING Register Busy */ +#define _LESENSE_SYNCBUSY_TIMING_SHIFT 24 /* Shift value for LESENSE_TIMING */ +#define _LESENSE_SYNCBUSY_TIMING_MASK 0x1000000UL /* Bit mask for LESENSE_TIMING */ +#define _LESENSE_SYNCBUSY_TIMING_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_TIMING_DEFAULT (_LESENSE_SYNCBUSY_TIMING_DEFAULT << 24) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_INTERACT (0x1UL << 25) /* LESENSE_CHx_INTERACT Register Busy */ +#define _LESENSE_SYNCBUSY_INTERACT_SHIFT 25 /* Shift value for LESENSE_INTERACT */ +#define _LESENSE_SYNCBUSY_INTERACT_MASK 0x2000000UL /* Bit mask for LESENSE_INTERACT */ +#define _LESENSE_SYNCBUSY_INTERACT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_INTERACT_DEFAULT (_LESENSE_SYNCBUSY_INTERACT_DEFAULT << 25) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_EVAL (0x1UL << 26) /* LESENSE_CHx_EVAL Register Busy */ +#define _LESENSE_SYNCBUSY_EVAL_SHIFT 26 /* Shift value for LESENSE_EVAL */ +#define _LESENSE_SYNCBUSY_EVAL_MASK 0x4000000UL /* Bit mask for LESENSE_EVAL */ +#define _LESENSE_SYNCBUSY_EVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_SYNCBUSY */ +#define LESENSE_SYNCBUSY_EVAL_DEFAULT (_LESENSE_SYNCBUSY_EVAL_DEFAULT << 26) /* Shifted mode DEFAULT for LESENSE_SYNCBUSY */ + +/* Bit fields for LESENSE ROUTE */ + +#define _LESENSE_ROUTE_RESETVALUE 0x00000000UL /* Default value for LESENSE_ROUTE */ +#define _LESENSE_ROUTE_MASK 0x00FFFFFFUL /* Mask for LESENSE_ROUTE */ + +#define LESENSE_ROUTE_CH0PEN (0x1UL << 0) /* CH0 Pin Enable */ +#define _LESENSE_ROUTE_CH0PEN_SHIFT 0 /* Shift value for LESENSE_CH0PEN */ +#define _LESENSE_ROUTE_CH0PEN_MASK 0x1UL /* Bit mask for LESENSE_CH0PEN */ +#define _LESENSE_ROUTE_CH0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH0PEN_DEFAULT (_LESENSE_ROUTE_CH0PEN_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH1PEN (0x1UL << 1) /* CH0 Pin Enable */ +#define _LESENSE_ROUTE_CH1PEN_SHIFT 1 /* Shift value for LESENSE_CH1PEN */ +#define _LESENSE_ROUTE_CH1PEN_MASK 0x2UL /* Bit mask for LESENSE_CH1PEN */ +#define _LESENSE_ROUTE_CH1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH1PEN_DEFAULT (_LESENSE_ROUTE_CH1PEN_DEFAULT << 1) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH2PEN (0x1UL << 2) /* CH2 Pin Enable */ +#define _LESENSE_ROUTE_CH2PEN_SHIFT 2 /* Shift value for LESENSE_CH2PEN */ +#define _LESENSE_ROUTE_CH2PEN_MASK 0x4UL /* Bit mask for LESENSE_CH2PEN */ +#define _LESENSE_ROUTE_CH2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH2PEN_DEFAULT (_LESENSE_ROUTE_CH2PEN_DEFAULT << 2) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH3PEN (0x1UL << 3) /* CH3 Pin Enable */ +#define _LESENSE_ROUTE_CH3PEN_SHIFT 3 /* Shift value for LESENSE_CH3PEN */ +#define _LESENSE_ROUTE_CH3PEN_MASK 0x8UL /* Bit mask for LESENSE_CH3PEN */ +#define _LESENSE_ROUTE_CH3PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH3PEN_DEFAULT (_LESENSE_ROUTE_CH3PEN_DEFAULT << 3) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH4PEN (0x1UL << 4) /* CH4 Pin Enable */ +#define _LESENSE_ROUTE_CH4PEN_SHIFT 4 /* Shift value for LESENSE_CH4PEN */ +#define _LESENSE_ROUTE_CH4PEN_MASK 0x10UL /* Bit mask for LESENSE_CH4PEN */ +#define _LESENSE_ROUTE_CH4PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH4PEN_DEFAULT (_LESENSE_ROUTE_CH4PEN_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH5PEN (0x1UL << 5) /* CH5 Pin Enable */ +#define _LESENSE_ROUTE_CH5PEN_SHIFT 5 /* Shift value for LESENSE_CH5PEN */ +#define _LESENSE_ROUTE_CH5PEN_MASK 0x20UL /* Bit mask for LESENSE_CH5PEN */ +#define _LESENSE_ROUTE_CH5PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH5PEN_DEFAULT (_LESENSE_ROUTE_CH5PEN_DEFAULT << 5) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH6PEN (0x1UL << 6) /* CH6 Pin Enable */ +#define _LESENSE_ROUTE_CH6PEN_SHIFT 6 /* Shift value for LESENSE_CH6PEN */ +#define _LESENSE_ROUTE_CH6PEN_MASK 0x40UL /* Bit mask for LESENSE_CH6PEN */ +#define _LESENSE_ROUTE_CH6PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH6PEN_DEFAULT (_LESENSE_ROUTE_CH6PEN_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH7PEN (0x1UL << 7) /* CH7 Pin Enable */ +#define _LESENSE_ROUTE_CH7PEN_SHIFT 7 /* Shift value for LESENSE_CH7PEN */ +#define _LESENSE_ROUTE_CH7PEN_MASK 0x80UL /* Bit mask for LESENSE_CH7PEN */ +#define _LESENSE_ROUTE_CH7PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH7PEN_DEFAULT (_LESENSE_ROUTE_CH7PEN_DEFAULT << 7) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH8PEN (0x1UL << 8) /* CH8 Pin Enable */ +#define _LESENSE_ROUTE_CH8PEN_SHIFT 8 /* Shift value for LESENSE_CH8PEN */ +#define _LESENSE_ROUTE_CH8PEN_MASK 0x100UL /* Bit mask for LESENSE_CH8PEN */ +#define _LESENSE_ROUTE_CH8PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH8PEN_DEFAULT (_LESENSE_ROUTE_CH8PEN_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH9PEN (0x1UL << 9) /* CH9 Pin Enable */ +#define _LESENSE_ROUTE_CH9PEN_SHIFT 9 /* Shift value for LESENSE_CH9PEN */ +#define _LESENSE_ROUTE_CH9PEN_MASK 0x200UL /* Bit mask for LESENSE_CH9PEN */ +#define _LESENSE_ROUTE_CH9PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH9PEN_DEFAULT (_LESENSE_ROUTE_CH9PEN_DEFAULT << 9) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH10PEN (0x1UL << 10) /* CH10 Pin Enable */ +#define _LESENSE_ROUTE_CH10PEN_SHIFT 10 /* Shift value for LESENSE_CH10PEN */ +#define _LESENSE_ROUTE_CH10PEN_MASK 0x400UL /* Bit mask for LESENSE_CH10PEN */ +#define _LESENSE_ROUTE_CH10PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH10PEN_DEFAULT (_LESENSE_ROUTE_CH10PEN_DEFAULT << 10) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH11PEN (0x1UL << 11) /* CH11 Pin Enable */ +#define _LESENSE_ROUTE_CH11PEN_SHIFT 11 /* Shift value for LESENSE_CH11PEN */ +#define _LESENSE_ROUTE_CH11PEN_MASK 0x800UL /* Bit mask for LESENSE_CH11PEN */ +#define _LESENSE_ROUTE_CH11PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH11PEN_DEFAULT (_LESENSE_ROUTE_CH11PEN_DEFAULT << 11) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH12PEN (0x1UL << 12) /* CH12 Pin Enable */ +#define _LESENSE_ROUTE_CH12PEN_SHIFT 12 /* Shift value for LESENSE_CH12PEN */ +#define _LESENSE_ROUTE_CH12PEN_MASK 0x1000UL /* Bit mask for LESENSE_CH12PEN */ +#define _LESENSE_ROUTE_CH12PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH12PEN_DEFAULT (_LESENSE_ROUTE_CH12PEN_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH13PEN (0x1UL << 13) /* CH13 Pin Enable */ +#define _LESENSE_ROUTE_CH13PEN_SHIFT 13 /* Shift value for LESENSE_CH13PEN */ +#define _LESENSE_ROUTE_CH13PEN_MASK 0x2000UL /* Bit mask for LESENSE_CH13PEN */ +#define _LESENSE_ROUTE_CH13PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH13PEN_DEFAULT (_LESENSE_ROUTE_CH13PEN_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH14PEN (0x1UL << 14) /* CH14 Pin Enable */ +#define _LESENSE_ROUTE_CH14PEN_SHIFT 14 /* Shift value for LESENSE_CH14PEN */ +#define _LESENSE_ROUTE_CH14PEN_MASK 0x4000UL /* Bit mask for LESENSE_CH14PEN */ +#define _LESENSE_ROUTE_CH14PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH14PEN_DEFAULT (_LESENSE_ROUTE_CH14PEN_DEFAULT << 14) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH15PEN (0x1UL << 15) /* CH15 Pin Enable */ +#define _LESENSE_ROUTE_CH15PEN_SHIFT 15 /* Shift value for LESENSE_CH15PEN */ +#define _LESENSE_ROUTE_CH15PEN_MASK 0x8000UL /* Bit mask for LESENSE_CH15PEN */ +#define _LESENSE_ROUTE_CH15PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_CH15PEN_DEFAULT (_LESENSE_ROUTE_CH15PEN_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX0PEN (0x1UL << 16) /* ALTEX0 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX0PEN_SHIFT 16 /* Shift value for LESENSE_ALTEX0PEN */ +#define _LESENSE_ROUTE_ALTEX0PEN_MASK 0x10000UL /* Bit mask for LESENSE_ALTEX0PEN */ +#define _LESENSE_ROUTE_ALTEX0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX0PEN_DEFAULT (_LESENSE_ROUTE_ALTEX0PEN_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX1PEN (0x1UL << 17) /* ALTEX1 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX1PEN_SHIFT 17 /* Shift value for LESENSE_ALTEX1PEN */ +#define _LESENSE_ROUTE_ALTEX1PEN_MASK 0x20000UL /* Bit mask for LESENSE_ALTEX1PEN */ +#define _LESENSE_ROUTE_ALTEX1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX1PEN_DEFAULT (_LESENSE_ROUTE_ALTEX1PEN_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX2PEN (0x1UL << 18) /* ALTEX2 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX2PEN_SHIFT 18 /* Shift value for LESENSE_ALTEX2PEN */ +#define _LESENSE_ROUTE_ALTEX2PEN_MASK 0x40000UL /* Bit mask for LESENSE_ALTEX2PEN */ +#define _LESENSE_ROUTE_ALTEX2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX2PEN_DEFAULT (_LESENSE_ROUTE_ALTEX2PEN_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX3PEN (0x1UL << 19) /* ALTEX3 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX3PEN_SHIFT 19 /* Shift value for LESENSE_ALTEX3PEN */ +#define _LESENSE_ROUTE_ALTEX3PEN_MASK 0x80000UL /* Bit mask for LESENSE_ALTEX3PEN */ +#define _LESENSE_ROUTE_ALTEX3PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX3PEN_DEFAULT (_LESENSE_ROUTE_ALTEX3PEN_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX4PEN (0x1UL << 20) /* ALTEX4 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX4PEN_SHIFT 20 /* Shift value for LESENSE_ALTEX4PEN */ +#define _LESENSE_ROUTE_ALTEX4PEN_MASK 0x100000UL /* Bit mask for LESENSE_ALTEX4PEN */ +#define _LESENSE_ROUTE_ALTEX4PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX4PEN_DEFAULT (_LESENSE_ROUTE_ALTEX4PEN_DEFAULT << 20) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX5PEN (0x1UL << 21) /* ALTEX5 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX5PEN_SHIFT 21 /* Shift value for LESENSE_ALTEX5PEN */ +#define _LESENSE_ROUTE_ALTEX5PEN_MASK 0x200000UL /* Bit mask for LESENSE_ALTEX5PEN */ +#define _LESENSE_ROUTE_ALTEX5PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX5PEN_DEFAULT (_LESENSE_ROUTE_ALTEX5PEN_DEFAULT << 21) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX6PEN (0x1UL << 22) /* ALTEX6 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX6PEN_SHIFT 22 /* Shift value for LESENSE_ALTEX6PEN */ +#define _LESENSE_ROUTE_ALTEX6PEN_MASK 0x400000UL /* Bit mask for LESENSE_ALTEX6PEN */ +#define _LESENSE_ROUTE_ALTEX6PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX6PEN_DEFAULT (_LESENSE_ROUTE_ALTEX6PEN_DEFAULT << 22) /* Shifted mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX7PEN (0x1UL << 23) /* ALTEX7 Pin Enable */ +#define _LESENSE_ROUTE_ALTEX7PEN_SHIFT 23 /* Shift value for LESENSE_ALTEX7PEN */ +#define _LESENSE_ROUTE_ALTEX7PEN_MASK 0x800000UL /* Bit mask for LESENSE_ALTEX7PEN */ +#define _LESENSE_ROUTE_ALTEX7PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ROUTE */ +#define LESENSE_ROUTE_ALTEX7PEN_DEFAULT (_LESENSE_ROUTE_ALTEX7PEN_DEFAULT << 23) /* Shifted mode DEFAULT for LESENSE_ROUTE */ + +/* Bit fields for LESENSE POWERDOWN */ + +#define _LESENSE_POWERDOWN_RESETVALUE 0x00000000UL /* Default value for LESENSE_POWERDOWN */ +#define _LESENSE_POWERDOWN_MASK 0x00000001UL /* Mask for LESENSE_POWERDOWN */ + +#define LESENSE_POWERDOWN_RAM (0x1UL << 0) /* LESENSE RAM power-down */ +#define _LESENSE_POWERDOWN_RAM_SHIFT 0 /* Shift value for LESENSE_RAM */ +#define _LESENSE_POWERDOWN_RAM_MASK 0x1UL /* Bit mask for LESENSE_RAM */ +#define _LESENSE_POWERDOWN_RAM_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_POWERDOWN */ +#define LESENSE_POWERDOWN_RAM_DEFAULT (_LESENSE_POWERDOWN_RAM_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_POWERDOWN */ + +/* Bit fields for LESENSE ST_TCONFA */ + +#define _LESENSE_ST_TCONFA_RESETVALUE 0x00000000UL /* Default value for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_MASK 0x00057FFFUL /* Mask for LESENSE_ST_TCONFA */ + +#define _LESENSE_ST_TCONFA_COMP_SHIFT 0 /* Shift value for LESENSE_COMP */ +#define _LESENSE_ST_TCONFA_COMP_MASK 0xFUL /* Bit mask for LESENSE_COMP */ +#define _LESENSE_ST_TCONFA_COMP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_COMP_DEFAULT (_LESENSE_ST_TCONFA_COMP_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_MASK_SHIFT 4 /* Shift value for LESENSE_MASK */ +#define _LESENSE_ST_TCONFA_MASK_MASK 0xF0UL /* Bit mask for LESENSE_MASK */ +#define _LESENSE_ST_TCONFA_MASK_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_MASK_DEFAULT (_LESENSE_ST_TCONFA_MASK_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_NEXTSTATE_SHIFT 8 /* Shift value for LESENSE_NEXTSTATE */ +#define _LESENSE_ST_TCONFA_NEXTSTATE_MASK 0xF00UL /* Bit mask for LESENSE_NEXTSTATE */ +#define _LESENSE_ST_TCONFA_NEXTSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_NEXTSTATE_DEFAULT (_LESENSE_ST_TCONFA_NEXTSTATE_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_SHIFT 12 /* Shift value for LESENSE_PRSACT */ +#define _LESENSE_ST_TCONFA_PRSACT_MASK 0x7000UL /* Bit mask for LESENSE_PRSACT */ +#define _LESENSE_ST_TCONFA_PRSACT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_NONE 0x00000000UL /* Mode NONE for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_UP 0x00000001UL /* Mode UP for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS0 0x00000001UL /* Mode PRS0 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS1 0x00000002UL /* Mode PRS1 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_DOWN 0x00000002UL /* Mode DOWN for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS01 0x00000003UL /* Mode PRS01 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS2 0x00000004UL /* Mode PRS2 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS02 0x00000005UL /* Mode PRS02 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_UPANDPRS2 0x00000005UL /* Mode UPANDPRS2 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS12 0x00000006UL /* Mode PRS12 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_DOWNANDPRS2 0x00000006UL /* Mode DOWNANDPRS2 for LESENSE_ST_TCONFA */ +#define _LESENSE_ST_TCONFA_PRSACT_PRS012 0x00000007UL /* Mode PRS012 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_DEFAULT (_LESENSE_ST_TCONFA_PRSACT_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_NONE (_LESENSE_ST_TCONFA_PRSACT_NONE << 12) /* Shifted mode NONE for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_UP (_LESENSE_ST_TCONFA_PRSACT_UP << 12) /* Shifted mode UP for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS0 (_LESENSE_ST_TCONFA_PRSACT_PRS0 << 12) /* Shifted mode PRS0 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS1 (_LESENSE_ST_TCONFA_PRSACT_PRS1 << 12) /* Shifted mode PRS1 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_DOWN (_LESENSE_ST_TCONFA_PRSACT_DOWN << 12) /* Shifted mode DOWN for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS01 (_LESENSE_ST_TCONFA_PRSACT_PRS01 << 12) /* Shifted mode PRS01 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS2 (_LESENSE_ST_TCONFA_PRSACT_PRS2 << 12) /* Shifted mode PRS2 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS02 (_LESENSE_ST_TCONFA_PRSACT_PRS02 << 12) /* Shifted mode PRS02 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_UPANDPRS2 (_LESENSE_ST_TCONFA_PRSACT_UPANDPRS2 << 12) /* Shifted mode UPANDPRS2 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS12 (_LESENSE_ST_TCONFA_PRSACT_PRS12 << 12) /* Shifted mode PRS12 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_DOWNANDPRS2 (_LESENSE_ST_TCONFA_PRSACT_DOWNANDPRS2 << 12) /* Shifted mode DOWNANDPRS2 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_PRSACT_PRS012 (_LESENSE_ST_TCONFA_PRSACT_PRS012 << 12) /* Shifted mode PRS012 for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_SETIF (0x1UL << 16) /* Set interrupt flag enable */ +#define _LESENSE_ST_TCONFA_SETIF_SHIFT 16 /* Shift value for LESENSE_SETIF */ +#define _LESENSE_ST_TCONFA_SETIF_MASK 0x10000UL /* Bit mask for LESENSE_SETIF */ +#define _LESENSE_ST_TCONFA_SETIF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_SETIF_DEFAULT (_LESENSE_ST_TCONFA_SETIF_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_CHAIN (0x1UL << 18) /* Enable state descriptor chaining */ +#define _LESENSE_ST_TCONFA_CHAIN_SHIFT 18 /* Shift value for LESENSE_CHAIN */ +#define _LESENSE_ST_TCONFA_CHAIN_MASK 0x40000UL /* Bit mask for LESENSE_CHAIN */ +#define _LESENSE_ST_TCONFA_CHAIN_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFA */ +#define LESENSE_ST_TCONFA_CHAIN_DEFAULT (_LESENSE_ST_TCONFA_CHAIN_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_ST_TCONFA */ + +/* Bit fields for LESENSE ST_TCONFB */ + +#define _LESENSE_ST_TCONFB_RESETVALUE 0x00000000UL /* Default value for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_MASK 0x00017FFFUL /* Mask for LESENSE_ST_TCONFB */ + +#define _LESENSE_ST_TCONFB_COMP_SHIFT 0 /* Shift value for LESENSE_COMP */ +#define _LESENSE_ST_TCONFB_COMP_MASK 0xFUL /* Bit mask for LESENSE_COMP */ +#define _LESENSE_ST_TCONFB_COMP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_COMP_DEFAULT (_LESENSE_ST_TCONFB_COMP_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_MASK_SHIFT 4 /* Shift value for LESENSE_MASK */ +#define _LESENSE_ST_TCONFB_MASK_MASK 0xF0UL /* Bit mask for LESENSE_MASK */ +#define _LESENSE_ST_TCONFB_MASK_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_MASK_DEFAULT (_LESENSE_ST_TCONFB_MASK_DEFAULT << 4) /* Shifted mode DEFAULT for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_NEXTSTATE_SHIFT 8 /* Shift value for LESENSE_NEXTSTATE */ +#define _LESENSE_ST_TCONFB_NEXTSTATE_MASK 0xF00UL /* Bit mask for LESENSE_NEXTSTATE */ +#define _LESENSE_ST_TCONFB_NEXTSTATE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_NEXTSTATE_DEFAULT (_LESENSE_ST_TCONFB_NEXTSTATE_DEFAULT << 8) /* Shifted mode DEFAULT for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_SHIFT 12 /* Shift value for LESENSE_PRSACT */ +#define _LESENSE_ST_TCONFB_PRSACT_MASK 0x7000UL /* Bit mask for LESENSE_PRSACT */ +#define _LESENSE_ST_TCONFB_PRSACT_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_NONE 0x00000000UL /* Mode NONE for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_UP 0x00000001UL /* Mode UP for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS0 0x00000001UL /* Mode PRS0 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS1 0x00000002UL /* Mode PRS1 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_DOWN 0x00000002UL /* Mode DOWN for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS01 0x00000003UL /* Mode PRS01 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS2 0x00000004UL /* Mode PRS2 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS02 0x00000005UL /* Mode PRS02 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_UPANDPRS2 0x00000005UL /* Mode UPANDPRS2 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS12 0x00000006UL /* Mode PRS12 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_DOWNANDPRS2 0x00000006UL /* Mode DOWNANDPRS2 for LESENSE_ST_TCONFB */ +#define _LESENSE_ST_TCONFB_PRSACT_PRS012 0x00000007UL /* Mode PRS012 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_DEFAULT (_LESENSE_ST_TCONFB_PRSACT_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_NONE (_LESENSE_ST_TCONFB_PRSACT_NONE << 12) /* Shifted mode NONE for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_UP (_LESENSE_ST_TCONFB_PRSACT_UP << 12) /* Shifted mode UP for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS0 (_LESENSE_ST_TCONFB_PRSACT_PRS0 << 12) /* Shifted mode PRS0 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS1 (_LESENSE_ST_TCONFB_PRSACT_PRS1 << 12) /* Shifted mode PRS1 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_DOWN (_LESENSE_ST_TCONFB_PRSACT_DOWN << 12) /* Shifted mode DOWN for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS01 (_LESENSE_ST_TCONFB_PRSACT_PRS01 << 12) /* Shifted mode PRS01 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS2 (_LESENSE_ST_TCONFB_PRSACT_PRS2 << 12) /* Shifted mode PRS2 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS02 (_LESENSE_ST_TCONFB_PRSACT_PRS02 << 12) /* Shifted mode PRS02 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_UPANDPRS2 (_LESENSE_ST_TCONFB_PRSACT_UPANDPRS2 << 12) /* Shifted mode UPANDPRS2 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS12 (_LESENSE_ST_TCONFB_PRSACT_PRS12 << 12) /* Shifted mode PRS12 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_DOWNANDPRS2 (_LESENSE_ST_TCONFB_PRSACT_DOWNANDPRS2 << 12) /* Shifted mode DOWNANDPRS2 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_PRSACT_PRS012 (_LESENSE_ST_TCONFB_PRSACT_PRS012 << 12) /* Shifted mode PRS012 for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_SETIF (0x1UL << 16) /* Set interrupt flag */ +#define _LESENSE_ST_TCONFB_SETIF_SHIFT 16 /* Shift value for LESENSE_SETIF */ +#define _LESENSE_ST_TCONFB_SETIF_MASK 0x10000UL /* Bit mask for LESENSE_SETIF */ +#define _LESENSE_ST_TCONFB_SETIF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_ST_TCONFB */ +#define LESENSE_ST_TCONFB_SETIF_DEFAULT (_LESENSE_ST_TCONFB_SETIF_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_ST_TCONFB */ + +/* Bit fields for LESENSE BUF_DATA */ + +#define _LESENSE_BUF_DATA_RESETVALUE 0x00000000UL /* Default value for LESENSE_BUF_DATA */ +#define _LESENSE_BUF_DATA_MASK 0x0000FFFFUL /* Mask for LESENSE_BUF_DATA */ + +#define _LESENSE_BUF_DATA_DATA_SHIFT 0 /* Shift value for LESENSE_DATA */ +#define _LESENSE_BUF_DATA_DATA_MASK 0xFFFFUL /* Bit mask for LESENSE_DATA */ +#define _LESENSE_BUF_DATA_DATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_BUF_DATA */ +#define LESENSE_BUF_DATA_DATA_DEFAULT (_LESENSE_BUF_DATA_DATA_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_BUF_DATA */ + +/* Bit fields for LESENSE CH_TIMING */ + +#define _LESENSE_CH_TIMING_RESETVALUE 0x00000000UL /* Default value for LESENSE_CH_TIMING */ +#define _LESENSE_CH_TIMING_MASK 0x000FFFFFUL /* Mask for LESENSE_CH_TIMING */ + +#define _LESENSE_CH_TIMING_EXTIME_SHIFT 0 /* Shift value for LESENSE_EXTIME */ +#define _LESENSE_CH_TIMING_EXTIME_MASK 0x3FUL /* Bit mask for LESENSE_EXTIME */ +#define _LESENSE_CH_TIMING_EXTIME_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_TIMING */ +#define LESENSE_CH_TIMING_EXTIME_DEFAULT (_LESENSE_CH_TIMING_EXTIME_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CH_TIMING */ +#define _LESENSE_CH_TIMING_SAMPLEDLY_SHIFT 6 /* Shift value for LESENSE_SAMPLEDLY */ +#define _LESENSE_CH_TIMING_SAMPLEDLY_MASK 0x1FC0UL /* Bit mask for LESENSE_SAMPLEDLY */ +#define _LESENSE_CH_TIMING_SAMPLEDLY_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_TIMING */ +#define LESENSE_CH_TIMING_SAMPLEDLY_DEFAULT (_LESENSE_CH_TIMING_SAMPLEDLY_DEFAULT << 6) /* Shifted mode DEFAULT for LESENSE_CH_TIMING */ +#define _LESENSE_CH_TIMING_MEASUREDLY_SHIFT 13 /* Shift value for LESENSE_MEASUREDLY */ +#define _LESENSE_CH_TIMING_MEASUREDLY_MASK 0xFE000UL /* Bit mask for LESENSE_MEASUREDLY */ +#define _LESENSE_CH_TIMING_MEASUREDLY_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_TIMING */ +#define LESENSE_CH_TIMING_MEASUREDLY_DEFAULT (_LESENSE_CH_TIMING_MEASUREDLY_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_CH_TIMING */ + +/* Bit fields for LESENSE CH_INTERACT */ + +#define _LESENSE_CH_INTERACT_RESETVALUE 0x00000000UL /* Default value for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_MASK 0x000FFFFFUL /* Mask for LESENSE_CH_INTERACT */ + +#define _LESENSE_CH_INTERACT_ACMPTHRES_SHIFT 0 /* Shift value for LESENSE_ACMPTHRES */ +#define _LESENSE_CH_INTERACT_ACMPTHRES_MASK 0xFFFUL /* Bit mask for LESENSE_ACMPTHRES */ +#define _LESENSE_CH_INTERACT_ACMPTHRES_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_ACMPTHRES_DEFAULT (_LESENSE_CH_INTERACT_ACMPTHRES_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLE (0x1UL << 12) /* Select sample mode */ +#define _LESENSE_CH_INTERACT_SAMPLE_SHIFT 12 /* Shift value for LESENSE_SAMPLE */ +#define _LESENSE_CH_INTERACT_SAMPLE_MASK 0x1000UL /* Bit mask for LESENSE_SAMPLE */ +#define _LESENSE_CH_INTERACT_SAMPLE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SAMPLE_COUNTER 0x00000000UL /* Mode COUNTER for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SAMPLE_ACMP 0x00000001UL /* Mode ACMP for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLE_DEFAULT (_LESENSE_CH_INTERACT_SAMPLE_DEFAULT << 12) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLE_COUNTER (_LESENSE_CH_INTERACT_SAMPLE_COUNTER << 12) /* Shifted mode COUNTER for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLE_ACMP (_LESENSE_CH_INTERACT_SAMPLE_ACMP << 12) /* Shifted mode ACMP for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SETIF_SHIFT 13 /* Shift value for LESENSE_SETIF */ +#define _LESENSE_CH_INTERACT_SETIF_MASK 0x6000UL /* Bit mask for LESENSE_SETIF */ +#define _LESENSE_CH_INTERACT_SETIF_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SETIF_NONE 0x00000000UL /* Mode NONE for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SETIF_LEVEL 0x00000001UL /* Mode LEVEL for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SETIF_POSEDGE 0x00000002UL /* Mode POSEDGE for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SETIF_NEGEDGE 0x00000003UL /* Mode NEGEDGE for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SETIF_DEFAULT (_LESENSE_CH_INTERACT_SETIF_DEFAULT << 13) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SETIF_NONE (_LESENSE_CH_INTERACT_SETIF_NONE << 13) /* Shifted mode NONE for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SETIF_LEVEL (_LESENSE_CH_INTERACT_SETIF_LEVEL << 13) /* Shifted mode LEVEL for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SETIF_POSEDGE (_LESENSE_CH_INTERACT_SETIF_POSEDGE << 13) /* Shifted mode POSEDGE for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SETIF_NEGEDGE (_LESENSE_CH_INTERACT_SETIF_NEGEDGE << 13) /* Shifted mode NEGEDGE for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXMODE_SHIFT 15 /* Shift value for LESENSE_EXMODE */ +#define _LESENSE_CH_INTERACT_EXMODE_MASK 0x18000UL /* Bit mask for LESENSE_EXMODE */ +#define _LESENSE_CH_INTERACT_EXMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXMODE_DISABLE 0x00000000UL /* Mode DISABLE for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXMODE_HIGH 0x00000001UL /* Mode HIGH for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXMODE_LOW 0x00000002UL /* Mode LOW for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXMODE_DACOUT 0x00000003UL /* Mode DACOUT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXMODE_DEFAULT (_LESENSE_CH_INTERACT_EXMODE_DEFAULT << 15) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXMODE_DISABLE (_LESENSE_CH_INTERACT_EXMODE_DISABLE << 15) /* Shifted mode DISABLE for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXMODE_HIGH (_LESENSE_CH_INTERACT_EXMODE_HIGH << 15) /* Shifted mode HIGH for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXMODE_LOW (_LESENSE_CH_INTERACT_EXMODE_LOW << 15) /* Shifted mode LOW for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXMODE_DACOUT (_LESENSE_CH_INTERACT_EXMODE_DACOUT << 15) /* Shifted mode DACOUT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXCLK (0x1UL << 17) /* Select clock used for excitation timing */ +#define _LESENSE_CH_INTERACT_EXCLK_SHIFT 17 /* Shift value for LESENSE_EXCLK */ +#define _LESENSE_CH_INTERACT_EXCLK_MASK 0x20000UL /* Bit mask for LESENSE_EXCLK */ +#define _LESENSE_CH_INTERACT_EXCLK_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXCLK_LFACLK 0x00000000UL /* Mode LFACLK for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_EXCLK_AUXHFRCO 0x00000001UL /* Mode AUXHFRCO for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXCLK_DEFAULT (_LESENSE_CH_INTERACT_EXCLK_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXCLK_LFACLK (_LESENSE_CH_INTERACT_EXCLK_LFACLK << 17) /* Shifted mode LFACLK for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_EXCLK_AUXHFRCO (_LESENSE_CH_INTERACT_EXCLK_AUXHFRCO << 17) /* Shifted mode AUXHFRCO for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLECLK (0x1UL << 18) /* Select clock used for timing of sample delay */ +#define _LESENSE_CH_INTERACT_SAMPLECLK_SHIFT 18 /* Shift value for LESENSE_SAMPLECLK */ +#define _LESENSE_CH_INTERACT_SAMPLECLK_MASK 0x40000UL /* Bit mask for LESENSE_SAMPLECLK */ +#define _LESENSE_CH_INTERACT_SAMPLECLK_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SAMPLECLK_LFACLK 0x00000000UL /* Mode LFACLK for LESENSE_CH_INTERACT */ +#define _LESENSE_CH_INTERACT_SAMPLECLK_AUXHFRCO 0x00000001UL /* Mode AUXHFRCO for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLECLK_DEFAULT (_LESENSE_CH_INTERACT_SAMPLECLK_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLECLK_LFACLK (_LESENSE_CH_INTERACT_SAMPLECLK_LFACLK << 18) /* Shifted mode LFACLK for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_SAMPLECLK_AUXHFRCO (_LESENSE_CH_INTERACT_SAMPLECLK_AUXHFRCO << 18) /* Shifted mode AUXHFRCO for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_ALTEX (0x1UL << 19) /* Use alternative excite pin */ +#define _LESENSE_CH_INTERACT_ALTEX_SHIFT 19 /* Shift value for LESENSE_ALTEX */ +#define _LESENSE_CH_INTERACT_ALTEX_MASK 0x80000UL /* Bit mask for LESENSE_ALTEX */ +#define _LESENSE_CH_INTERACT_ALTEX_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_INTERACT */ +#define LESENSE_CH_INTERACT_ALTEX_DEFAULT (_LESENSE_CH_INTERACT_ALTEX_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_CH_INTERACT */ + +/* Bit fields for LESENSE CH_EVAL */ + +#define _LESENSE_CH_EVAL_RESETVALUE 0x00000000UL /* Default value for LESENSE_CH_EVAL */ +#define _LESENSE_CH_EVAL_MASK 0x000FFFFFUL /* Mask for LESENSE_CH_EVAL */ + +#define _LESENSE_CH_EVAL_COMPTHRES_SHIFT 0 /* Shift value for LESENSE_COMPTHRES */ +#define _LESENSE_CH_EVAL_COMPTHRES_MASK 0xFFFFUL /* Bit mask for LESENSE_COMPTHRES */ +#define _LESENSE_CH_EVAL_COMPTHRES_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_COMPTHRES_DEFAULT (_LESENSE_CH_EVAL_COMPTHRES_DEFAULT << 0) /* Shifted mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_COMP (0x1UL << 16) /* Select mode for counter comparison */ +#define _LESENSE_CH_EVAL_COMP_SHIFT 16 /* Shift value for LESENSE_COMP */ +#define _LESENSE_CH_EVAL_COMP_MASK 0x10000UL /* Bit mask for LESENSE_COMP */ +#define _LESENSE_CH_EVAL_COMP_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_EVAL */ +#define _LESENSE_CH_EVAL_COMP_LESS 0x00000000UL /* Mode LESS for LESENSE_CH_EVAL */ +#define _LESENSE_CH_EVAL_COMP_GE 0x00000001UL /* Mode GE for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_COMP_DEFAULT (_LESENSE_CH_EVAL_COMP_DEFAULT << 16) /* Shifted mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_COMP_LESS (_LESENSE_CH_EVAL_COMP_LESS << 16) /* Shifted mode LESS for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_COMP_GE (_LESENSE_CH_EVAL_COMP_GE << 16) /* Shifted mode GE for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_DECODE (0x1UL << 17) /* Send result to decoder */ +#define _LESENSE_CH_EVAL_DECODE_SHIFT 17 /* Shift value for LESENSE_DECODE */ +#define _LESENSE_CH_EVAL_DECODE_MASK 0x20000UL /* Bit mask for LESENSE_DECODE */ +#define _LESENSE_CH_EVAL_DECODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_DECODE_DEFAULT (_LESENSE_CH_EVAL_DECODE_DEFAULT << 17) /* Shifted mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_STRSAMPLE (0x1UL << 18) /* Select if counter result should be stored */ +#define _LESENSE_CH_EVAL_STRSAMPLE_SHIFT 18 /* Shift value for LESENSE_STRSAMPLE */ +#define _LESENSE_CH_EVAL_STRSAMPLE_MASK 0x40000UL /* Bit mask for LESENSE_STRSAMPLE */ +#define _LESENSE_CH_EVAL_STRSAMPLE_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_STRSAMPLE_DEFAULT (_LESENSE_CH_EVAL_STRSAMPLE_DEFAULT << 18) /* Shifted mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_SCANRESINV (0x1UL << 19) /* Enable inversion of result */ +#define _LESENSE_CH_EVAL_SCANRESINV_SHIFT 19 /* Shift value for LESENSE_SCANRESINV */ +#define _LESENSE_CH_EVAL_SCANRESINV_MASK 0x80000UL /* Bit mask for LESENSE_SCANRESINV */ +#define _LESENSE_CH_EVAL_SCANRESINV_DEFAULT 0x00000000UL /* Mode DEFAULT for LESENSE_CH_EVAL */ +#define LESENSE_CH_EVAL_SCANRESINV_DEFAULT (_LESENSE_CH_EVAL_SCANRESINV_DEFAULT << 19) /* Shifted mode DEFAULT for LESENSE_CH_EVAL */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LESENSE_H */ diff --git a/arch/arm/src/efm32/chip/efm32_letimer.h b/arch/arm/src/efm32/chip/efm32_letimer.h new file mode 100644 index 0000000000000000000000000000000000000000..3b877d448f12da26de545ef43820de8f675df8ed --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_letimer.h @@ -0,0 +1,488 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_letimer.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LETIMER_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LETIMER_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* LETIMER Register Offsets ****************************************************************************************************/ + +#define EFM32_LETIMER_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_LETIMER_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_LETIMER_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_LETIMER_CNT_OFFSET 0x000c /* Counter Value Register */ +#define EFM32_LETIMER_COMP0_OFFSET 0x0010 /* Compare Value Register */ 0 +#define EFM32_LETIMER_COMP1_OFFSET 0x0014 /* Compare Value Register */ 1 +#define EFM32_LETIMER_REP0_OFFSET 0x0018 /* Repeat Counter Register 0 */ +#define EFM32_LETIMER_REP1_OFFSET 0x001c /* Repeat Counter Register 1 */ +#define EFM32_LETIMER_IF_OFFSET 0x0020 /* Interrupt Flag Register */ +#define EFM32_LETIMER_IFS_OFFSET 0x0024 /* Interrupt Flag Set Register */ +#define EFM32_LETIMER_IFC_OFFSET 0x0028 /* Interrupt Flag Clear Register */ +#define EFM32_LETIMER_IEN_OFFSET 0x002c /* Interrupt Enable Register */ +#define EFM32_LETIMER_FREEZE_OFFSET 0x0030 /* Freeze Register */ +#define EFM32_LETIMER_SYNCBUSY_OFFSET 0x0034 /* Synchronization Busy Register */ +#define EFM32_LETIMER_ROUTE_OFFSET 0x0040 /* I/O Routing Register */ + +/* LETIMER Register Addresses **************************************************************************************************/ + +#define EFM32_LETIMER0_CTRL (EFM32_LETIMER0_BASE+EFM32_LETIMER0_CTRL_OFFSET) +#define EFM32_LETIMER0_CMD (EFM32_LETIMER0_BASE+EFM32_LETIMER0_CMD_OFFSET) +#define EFM32_LETIMER0_STATUS (EFM32_LETIMER0_BASE+EFM32_LETIMER0_STATUS_OFFSET) +#define EFM32_LETIMER0_CNT (EFM32_LETIMER0_BASE+EFM32_LETIMER0_CNT_OFFSET) +#define EFM32_LETIMER0_COMP0 (EFM32_LETIMER0_BASE+EFM32_LETIMER0_COMP0_OFFSET) +#define EFM32_LETIMER0_COMP1 (EFM32_LETIMER0_BASE+EFM32_LETIMER0_COMP1_OFFSET) +#define EFM32_LETIMER0_REP0 (EFM32_LETIMER0_BASE+EFM32_LETIMER0_REP0_OFFSET) +#define EFM32_LETIMER0_REP1 (EFM32_LETIMER0_BASE+EFM32_LETIMER0_REP1_OFFSET) +#define EFM32_LETIMER0_IF (EFM32_LETIMER0_BASE+EFM32_LETIMER0_IF_OFFSET) +#define EFM32_LETIMER0_IFS (EFM32_LETIMER0_BASE+EFM32_LETIMER0_IFS_OFFSET) +#define EFM32_LETIMER0_IFC (EFM32_LETIMER0_BASE+EFM32_LETIMER0_IFC_OFFSET) +#define EFM32_LETIMER0_IEN (EFM32_LETIMER0_BASE+EFM32_LETIMER0_IEN_OFFSET) +#define EFM32_LETIMER0_FREEZE (EFM32_LETIMER0_BASE+EFM32_LETIMER0_FREEZE_OFFSET) +#define EFM32_LETIMER0_SYNCBUSY (EFM32_LETIMER0_BASE+EFM32_LETIMER0_SYNCBUSY_OFFSET) +#define EFM32_LETIMER0_ROUTE (EFM32_LETIMER0_BASE+EFM32_LETIMER0_ROUTE_OFFSET) + +/* LETIMER Register Bit Field Definitions **************************************************************************************/ + +/* Bit fields for LETIMER CTRL */ + +#define _LETIMER_CTRL_RESETVALUE 0x00000000UL /* Default value for LETIMER_CTRL */ +#define _LETIMER_CTRL_MASK 0x00001FFFUL /* Mask for LETIMER_CTRL */ + +#define _LETIMER_CTRL_REPMODE_SHIFT 0 /* Shift value for LETIMER_REPMODE */ +#define _LETIMER_CTRL_REPMODE_MASK 0x3UL /* Bit mask for LETIMER_REPMODE */ +#define _LETIMER_CTRL_REPMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define _LETIMER_CTRL_REPMODE_FREE 0x00000000UL /* Mode FREE for LETIMER_CTRL */ +#define _LETIMER_CTRL_REPMODE_ONESHOT 0x00000001UL /* Mode ONESHOT for LETIMER_CTRL */ +#define _LETIMER_CTRL_REPMODE_BUFFERED 0x00000002UL /* Mode BUFFERED for LETIMER_CTRL */ +#define _LETIMER_CTRL_REPMODE_DOUBLE 0x00000003UL /* Mode DOUBLE for LETIMER_CTRL */ +#define LETIMER_CTRL_REPMODE_DEFAULT (_LETIMER_CTRL_REPMODE_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_REPMODE_FREE (_LETIMER_CTRL_REPMODE_FREE << 0) /* Shifted mode FREE for LETIMER_CTRL */ +#define LETIMER_CTRL_REPMODE_ONESHOT (_LETIMER_CTRL_REPMODE_ONESHOT << 0) /* Shifted mode ONESHOT for LETIMER_CTRL */ +#define LETIMER_CTRL_REPMODE_BUFFERED (_LETIMER_CTRL_REPMODE_BUFFERED << 0) /* Shifted mode BUFFERED for LETIMER_CTRL */ +#define LETIMER_CTRL_REPMODE_DOUBLE (_LETIMER_CTRL_REPMODE_DOUBLE << 0) /* Shifted mode DOUBLE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA0_SHIFT 2 /* Shift value for LETIMER_UFOA0 */ +#define _LETIMER_CTRL_UFOA0_MASK 0xCUL /* Bit mask for LETIMER_UFOA0 */ +#define _LETIMER_CTRL_UFOA0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA0_NONE 0x00000000UL /* Mode NONE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA0_TOGGLE 0x00000001UL /* Mode TOGGLE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA0_PULSE 0x00000002UL /* Mode PULSE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA0_PWM 0x00000003UL /* Mode PWM for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA0_DEFAULT (_LETIMER_CTRL_UFOA0_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA0_NONE (_LETIMER_CTRL_UFOA0_NONE << 2) /* Shifted mode NONE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA0_TOGGLE (_LETIMER_CTRL_UFOA0_TOGGLE << 2) /* Shifted mode TOGGLE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA0_PULSE (_LETIMER_CTRL_UFOA0_PULSE << 2) /* Shifted mode PULSE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA0_PWM (_LETIMER_CTRL_UFOA0_PWM << 2) /* Shifted mode PWM for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA1_SHIFT 4 /* Shift value for LETIMER_UFOA1 */ +#define _LETIMER_CTRL_UFOA1_MASK 0x30UL /* Bit mask for LETIMER_UFOA1 */ +#define _LETIMER_CTRL_UFOA1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA1_NONE 0x00000000UL /* Mode NONE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA1_TOGGLE 0x00000001UL /* Mode TOGGLE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA1_PULSE 0x00000002UL /* Mode PULSE for LETIMER_CTRL */ +#define _LETIMER_CTRL_UFOA1_PWM 0x00000003UL /* Mode PWM for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA1_DEFAULT (_LETIMER_CTRL_UFOA1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA1_NONE (_LETIMER_CTRL_UFOA1_NONE << 4) /* Shifted mode NONE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA1_TOGGLE (_LETIMER_CTRL_UFOA1_TOGGLE << 4) /* Shifted mode TOGGLE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA1_PULSE (_LETIMER_CTRL_UFOA1_PULSE << 4) /* Shifted mode PULSE for LETIMER_CTRL */ +#define LETIMER_CTRL_UFOA1_PWM (_LETIMER_CTRL_UFOA1_PWM << 4) /* Shifted mode PWM for LETIMER_CTRL */ +#define LETIMER_CTRL_OPOL0 (0x1UL << 6) /* Output 0 Polarity */ +#define _LETIMER_CTRL_OPOL0_SHIFT 6 /* Shift value for LETIMER_OPOL0 */ +#define _LETIMER_CTRL_OPOL0_MASK 0x40UL /* Bit mask for LETIMER_OPOL0 */ +#define _LETIMER_CTRL_OPOL0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_OPOL0_DEFAULT (_LETIMER_CTRL_OPOL0_DEFAULT << 6) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_OPOL1 (0x1UL << 7) /* Output 1 Polarity */ +#define _LETIMER_CTRL_OPOL1_SHIFT 7 /* Shift value for LETIMER_OPOL1 */ +#define _LETIMER_CTRL_OPOL1_MASK 0x80UL /* Bit mask for LETIMER_OPOL1 */ +#define _LETIMER_CTRL_OPOL1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_OPOL1_DEFAULT (_LETIMER_CTRL_OPOL1_DEFAULT << 7) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_BUFTOP (0x1UL << 8) /* Buffered Top */ +#define _LETIMER_CTRL_BUFTOP_SHIFT 8 /* Shift value for LETIMER_BUFTOP */ +#define _LETIMER_CTRL_BUFTOP_MASK 0x100UL /* Bit mask for LETIMER_BUFTOP */ +#define _LETIMER_CTRL_BUFTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_BUFTOP_DEFAULT (_LETIMER_CTRL_BUFTOP_DEFAULT << 8) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_COMP0TOP (0x1UL << 9) /* Compare Value 0 Is Top Value */ +#define _LETIMER_CTRL_COMP0TOP_SHIFT 9 /* Shift value for LETIMER_COMP0TOP */ +#define _LETIMER_CTRL_COMP0TOP_MASK 0x200UL /* Bit mask for LETIMER_COMP0TOP */ +#define _LETIMER_CTRL_COMP0TOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_COMP0TOP_DEFAULT (_LETIMER_CTRL_COMP0TOP_DEFAULT << 9) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_RTCC0TEN (0x1UL << 10) /* RTC Compare 0 Trigger Enable */ +#define _LETIMER_CTRL_RTCC0TEN_SHIFT 10 /* Shift value for LETIMER_RTCC0TEN */ +#define _LETIMER_CTRL_RTCC0TEN_MASK 0x400UL /* Bit mask for LETIMER_RTCC0TEN */ +#define _LETIMER_CTRL_RTCC0TEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_RTCC0TEN_DEFAULT (_LETIMER_CTRL_RTCC0TEN_DEFAULT << 10) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_RTCC1TEN (0x1UL << 11) /* RTC Compare 1 Trigger Enable */ +#define _LETIMER_CTRL_RTCC1TEN_SHIFT 11 /* Shift value for LETIMER_RTCC1TEN */ +#define _LETIMER_CTRL_RTCC1TEN_MASK 0x800UL /* Bit mask for LETIMER_RTCC1TEN */ +#define _LETIMER_CTRL_RTCC1TEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_RTCC1TEN_DEFAULT (_LETIMER_CTRL_RTCC1TEN_DEFAULT << 11) /* Shifted mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_DEBUGRUN (0x1UL << 12) /* Debug Mode Run Enable */ +#define _LETIMER_CTRL_DEBUGRUN_SHIFT 12 /* Shift value for LETIMER_DEBUGRUN */ +#define _LETIMER_CTRL_DEBUGRUN_MASK 0x1000UL /* Bit mask for LETIMER_DEBUGRUN */ +#define _LETIMER_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CTRL */ +#define LETIMER_CTRL_DEBUGRUN_DEFAULT (_LETIMER_CTRL_DEBUGRUN_DEFAULT << 12) /* Shifted mode DEFAULT for LETIMER_CTRL */ + +/* Bit fields for LETIMER CMD */ + +#define _LETIMER_CMD_RESETVALUE 0x00000000UL /* Default value for LETIMER_CMD */ +#define _LETIMER_CMD_MASK 0x0000001FUL /* Mask for LETIMER_CMD */ + +#define LETIMER_CMD_START (0x1UL << 0) /* Start LETIMER */ +#define _LETIMER_CMD_START_SHIFT 0 /* Shift value for LETIMER_START */ +#define _LETIMER_CMD_START_MASK 0x1UL /* Bit mask for LETIMER_START */ +#define _LETIMER_CMD_START_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_START_DEFAULT (_LETIMER_CMD_START_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_STOP (0x1UL << 1) /* Stop LETIMER */ +#define _LETIMER_CMD_STOP_SHIFT 1 /* Shift value for LETIMER_STOP */ +#define _LETIMER_CMD_STOP_MASK 0x2UL /* Bit mask for LETIMER_STOP */ +#define _LETIMER_CMD_STOP_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_STOP_DEFAULT (_LETIMER_CMD_STOP_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CLEAR (0x1UL << 2) /* Clear LETIMER */ +#define _LETIMER_CMD_CLEAR_SHIFT 2 /* Shift value for LETIMER_CLEAR */ +#define _LETIMER_CMD_CLEAR_MASK 0x4UL /* Bit mask for LETIMER_CLEAR */ +#define _LETIMER_CMD_CLEAR_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CLEAR_DEFAULT (_LETIMER_CMD_CLEAR_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CTO0 (0x1UL << 3) /* Clear Toggle Output 0 */ +#define _LETIMER_CMD_CTO0_SHIFT 3 /* Shift value for LETIMER_CTO0 */ +#define _LETIMER_CMD_CTO0_MASK 0x8UL /* Bit mask for LETIMER_CTO0 */ +#define _LETIMER_CMD_CTO0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CTO0_DEFAULT (_LETIMER_CMD_CTO0_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CTO1 (0x1UL << 4) /* Clear Toggle Output 1 */ +#define _LETIMER_CMD_CTO1_SHIFT 4 /* Shift value for LETIMER_CTO1 */ +#define _LETIMER_CMD_CTO1_MASK 0x10UL /* Bit mask for LETIMER_CTO1 */ +#define _LETIMER_CMD_CTO1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CMD */ +#define LETIMER_CMD_CTO1_DEFAULT (_LETIMER_CMD_CTO1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_CMD */ + +/* Bit fields for LETIMER STATUS */ + +#define _LETIMER_STATUS_RESETVALUE 0x00000000UL /* Default value for LETIMER_STATUS */ +#define _LETIMER_STATUS_MASK 0x00000001UL /* Mask for LETIMER_STATUS */ + +#define LETIMER_STATUS_RUNNING (0x1UL << 0) /* LETIMER Running */ +#define _LETIMER_STATUS_RUNNING_SHIFT 0 /* Shift value for LETIMER_RUNNING */ +#define _LETIMER_STATUS_RUNNING_MASK 0x1UL /* Bit mask for LETIMER_RUNNING */ +#define _LETIMER_STATUS_RUNNING_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_STATUS */ +#define LETIMER_STATUS_RUNNING_DEFAULT (_LETIMER_STATUS_RUNNING_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_STATUS */ + +/* Bit fields for LETIMER CNT */ + +#define _LETIMER_CNT_RESETVALUE 0x00000000UL /* Default value for LETIMER_CNT */ +#define _LETIMER_CNT_MASK 0x0000FFFFUL /* Mask for LETIMER_CNT */ + +#define _LETIMER_CNT_CNT_SHIFT 0 /* Shift value for LETIMER_CNT */ +#define _LETIMER_CNT_CNT_MASK 0xFFFFUL /* Bit mask for LETIMER_CNT */ +#define _LETIMER_CNT_CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_CNT */ +#define LETIMER_CNT_CNT_DEFAULT (_LETIMER_CNT_CNT_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_CNT */ + +/* Bit fields for LETIMER COMP0 */ + +#define _LETIMER_COMP0_RESETVALUE 0x00000000UL /* Default value for LETIMER_COMP0 */ +#define _LETIMER_COMP0_MASK 0x0000FFFFUL /* Mask for LETIMER_COMP0 */ + +#define _LETIMER_COMP0_COMP0_SHIFT 0 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_COMP0_COMP0_MASK 0xFFFFUL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_COMP0_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_COMP0 */ +#define LETIMER_COMP0_COMP0_DEFAULT (_LETIMER_COMP0_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_COMP0 */ + +/* Bit fields for LETIMER COMP1 */ + +#define _LETIMER_COMP1_RESETVALUE 0x00000000UL /* Default value for LETIMER_COMP1 */ +#define _LETIMER_COMP1_MASK 0x0000FFFFUL /* Mask for LETIMER_COMP1 */ + +#define _LETIMER_COMP1_COMP1_SHIFT 0 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_COMP1_COMP1_MASK 0xFFFFUL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_COMP1_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_COMP1 */ +#define LETIMER_COMP1_COMP1_DEFAULT (_LETIMER_COMP1_COMP1_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_COMP1 */ + +/* Bit fields for LETIMER REP0 */ + +#define _LETIMER_REP0_RESETVALUE 0x00000000UL /* Default value for LETIMER_REP0 */ +#define _LETIMER_REP0_MASK 0x000000FFUL /* Mask for LETIMER_REP0 */ + +#define _LETIMER_REP0_REP0_SHIFT 0 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_REP0_REP0_MASK 0xFFUL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_REP0_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_REP0 */ +#define LETIMER_REP0_REP0_DEFAULT (_LETIMER_REP0_REP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_REP0 */ + +/* Bit fields for LETIMER REP1 */ + +#define _LETIMER_REP1_RESETVALUE 0x00000000UL /* Default value for LETIMER_REP1 */ +#define _LETIMER_REP1_MASK 0x000000FFUL /* Mask for LETIMER_REP1 */ + +#define _LETIMER_REP1_REP1_SHIFT 0 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_REP1_REP1_MASK 0xFFUL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_REP1_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_REP1 */ +#define LETIMER_REP1_REP1_DEFAULT (_LETIMER_REP1_REP1_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_REP1 */ + +/* Bit fields for LETIMER IF */ + +#define _LETIMER_IF_RESETVALUE 0x00000000UL /* Default value for LETIMER_IF */ +#define _LETIMER_IF_MASK 0x0000001FUL /* Mask for LETIMER_IF */ + +#define LETIMER_IF_COMP0 (0x1UL << 0) /* Compare Match 0 Interrupt Flag */ +#define _LETIMER_IF_COMP0_SHIFT 0 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_IF_COMP0_MASK 0x1UL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_IF_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_COMP0_DEFAULT (_LETIMER_IF_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_COMP1 (0x1UL << 1) /* Compare Match 1 Interrupt Flag */ +#define _LETIMER_IF_COMP1_SHIFT 1 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_IF_COMP1_MASK 0x2UL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_IF_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_COMP1_DEFAULT (_LETIMER_IF_COMP1_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_UF (0x1UL << 2) /* Underflow Interrupt Flag */ +#define _LETIMER_IF_UF_SHIFT 2 /* Shift value for LETIMER_UF */ +#define _LETIMER_IF_UF_MASK 0x4UL /* Bit mask for LETIMER_UF */ +#define _LETIMER_IF_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_UF_DEFAULT (_LETIMER_IF_UF_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_REP0 (0x1UL << 3) /* Repeat Counter 0 Interrupt Flag */ +#define _LETIMER_IF_REP0_SHIFT 3 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_IF_REP0_MASK 0x8UL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_IF_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_REP0_DEFAULT (_LETIMER_IF_REP0_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_REP1 (0x1UL << 4) /* Repeat Counter 1 Interrupt Flag */ +#define _LETIMER_IF_REP1_SHIFT 4 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_IF_REP1_MASK 0x10UL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_IF_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IF */ +#define LETIMER_IF_REP1_DEFAULT (_LETIMER_IF_REP1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_IF */ + +/* Bit fields for LETIMER IFS */ + +#define _LETIMER_IFS_RESETVALUE 0x00000000UL /* Default value for LETIMER_IFS */ +#define _LETIMER_IFS_MASK 0x0000001FUL /* Mask for LETIMER_IFS */ + +#define LETIMER_IFS_COMP0 (0x1UL << 0) /* Set Compare Match 0 Interrupt Flag */ +#define _LETIMER_IFS_COMP0_SHIFT 0 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_IFS_COMP0_MASK 0x1UL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_IFS_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_COMP0_DEFAULT (_LETIMER_IFS_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_COMP1 (0x1UL << 1) /* Set Compare Match 1 Interrupt Flag */ +#define _LETIMER_IFS_COMP1_SHIFT 1 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_IFS_COMP1_MASK 0x2UL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_IFS_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_COMP1_DEFAULT (_LETIMER_IFS_COMP1_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_UF (0x1UL << 2) /* Set Underflow Interrupt Flag */ +#define _LETIMER_IFS_UF_SHIFT 2 /* Shift value for LETIMER_UF */ +#define _LETIMER_IFS_UF_MASK 0x4UL /* Bit mask for LETIMER_UF */ +#define _LETIMER_IFS_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_UF_DEFAULT (_LETIMER_IFS_UF_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_REP0 (0x1UL << 3) /* Set Repeat Counter 0 Interrupt Flag */ +#define _LETIMER_IFS_REP0_SHIFT 3 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_IFS_REP0_MASK 0x8UL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_IFS_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_REP0_DEFAULT (_LETIMER_IFS_REP0_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_REP1 (0x1UL << 4) /* Set Repeat Counter 1 Interrupt Flag */ +#define _LETIMER_IFS_REP1_SHIFT 4 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_IFS_REP1_MASK 0x10UL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_IFS_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFS */ +#define LETIMER_IFS_REP1_DEFAULT (_LETIMER_IFS_REP1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_IFS */ + +/* Bit fields for LETIMER IFC */ + +#define _LETIMER_IFC_RESETVALUE 0x00000000UL /* Default value for LETIMER_IFC */ +#define _LETIMER_IFC_MASK 0x0000001FUL /* Mask for LETIMER_IFC */ + +#define LETIMER_IFC_COMP0 (0x1UL << 0) /* Clear Compare Match 0 Interrupt Flag */ +#define _LETIMER_IFC_COMP0_SHIFT 0 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_IFC_COMP0_MASK 0x1UL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_IFC_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_COMP0_DEFAULT (_LETIMER_IFC_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_COMP1 (0x1UL << 1) /* Clear Compare Match 1 Interrupt Flag */ +#define _LETIMER_IFC_COMP1_SHIFT 1 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_IFC_COMP1_MASK 0x2UL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_IFC_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_COMP1_DEFAULT (_LETIMER_IFC_COMP1_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_UF (0x1UL << 2) /* Clear Underflow Interrupt Flag */ +#define _LETIMER_IFC_UF_SHIFT 2 /* Shift value for LETIMER_UF */ +#define _LETIMER_IFC_UF_MASK 0x4UL /* Bit mask for LETIMER_UF */ +#define _LETIMER_IFC_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_UF_DEFAULT (_LETIMER_IFC_UF_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_REP0 (0x1UL << 3) /* Clear Repeat Counter 0 Interrupt Flag */ +#define _LETIMER_IFC_REP0_SHIFT 3 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_IFC_REP0_MASK 0x8UL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_IFC_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_REP0_DEFAULT (_LETIMER_IFC_REP0_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_REP1 (0x1UL << 4) /* Clear Repeat Counter 1 Interrupt Flag */ +#define _LETIMER_IFC_REP1_SHIFT 4 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_IFC_REP1_MASK 0x10UL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_IFC_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IFC */ +#define LETIMER_IFC_REP1_DEFAULT (_LETIMER_IFC_REP1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_IFC */ + +/* Bit fields for LETIMER IEN */ + +#define _LETIMER_IEN_RESETVALUE 0x00000000UL /* Default value for LETIMER_IEN */ +#define _LETIMER_IEN_MASK 0x0000001FUL /* Mask for LETIMER_IEN */ + +#define LETIMER_IEN_COMP0 (0x1UL << 0) /* Compare Match 0 Interrupt Enable */ +#define _LETIMER_IEN_COMP0_SHIFT 0 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_IEN_COMP0_MASK 0x1UL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_IEN_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_COMP0_DEFAULT (_LETIMER_IEN_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_COMP1 (0x1UL << 1) /* Compare Match 1 Interrupt Enable */ +#define _LETIMER_IEN_COMP1_SHIFT 1 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_IEN_COMP1_MASK 0x2UL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_IEN_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_COMP1_DEFAULT (_LETIMER_IEN_COMP1_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_UF (0x1UL << 2) /* Underflow Interrupt Enable */ +#define _LETIMER_IEN_UF_SHIFT 2 /* Shift value for LETIMER_UF */ +#define _LETIMER_IEN_UF_MASK 0x4UL /* Bit mask for LETIMER_UF */ +#define _LETIMER_IEN_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_UF_DEFAULT (_LETIMER_IEN_UF_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_REP0 (0x1UL << 3) /* Repeat Counter 0 Interrupt Enable */ +#define _LETIMER_IEN_REP0_SHIFT 3 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_IEN_REP0_MASK 0x8UL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_IEN_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_REP0_DEFAULT (_LETIMER_IEN_REP0_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_REP1 (0x1UL << 4) /* Repeat Counter 1 Interrupt Enable */ +#define _LETIMER_IEN_REP1_SHIFT 4 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_IEN_REP1_MASK 0x10UL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_IEN_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_IEN */ +#define LETIMER_IEN_REP1_DEFAULT (_LETIMER_IEN_REP1_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_IEN */ + +/* Bit fields for LETIMER FREEZE */ + +#define _LETIMER_FREEZE_RESETVALUE 0x00000000UL /* Default value for LETIMER_FREEZE */ +#define _LETIMER_FREEZE_MASK 0x00000001UL /* Mask for LETIMER_FREEZE */ + +#define LETIMER_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _LETIMER_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for LETIMER_REGFREEZE */ +#define _LETIMER_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for LETIMER_REGFREEZE */ +#define _LETIMER_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_FREEZE */ +#define _LETIMER_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for LETIMER_FREEZE */ +#define _LETIMER_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for LETIMER_FREEZE */ +#define LETIMER_FREEZE_REGFREEZE_DEFAULT (_LETIMER_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_FREEZE */ +#define LETIMER_FREEZE_REGFREEZE_UPDATE (_LETIMER_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for LETIMER_FREEZE */ +#define LETIMER_FREEZE_REGFREEZE_FREEZE (_LETIMER_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for LETIMER_FREEZE */ + +/* Bit fields for LETIMER SYNCBUSY */ + +#define _LETIMER_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for LETIMER_SYNCBUSY */ +#define _LETIMER_SYNCBUSY_MASK 0x0000003FUL /* Mask for LETIMER_SYNCBUSY */ + +#define LETIMER_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _LETIMER_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for LETIMER_CTRL */ +#define _LETIMER_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for LETIMER_CTRL */ +#define _LETIMER_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_CTRL_DEFAULT (_LETIMER_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_CMD (0x1UL << 1) /* CMD Register Busy */ +#define _LETIMER_SYNCBUSY_CMD_SHIFT 1 /* Shift value for LETIMER_CMD */ +#define _LETIMER_SYNCBUSY_CMD_MASK 0x2UL /* Bit mask for LETIMER_CMD */ +#define _LETIMER_SYNCBUSY_CMD_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_CMD_DEFAULT (_LETIMER_SYNCBUSY_CMD_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_COMP0 (0x1UL << 2) /* COMP0 Register Busy */ +#define _LETIMER_SYNCBUSY_COMP0_SHIFT 2 /* Shift value for LETIMER_COMP0 */ +#define _LETIMER_SYNCBUSY_COMP0_MASK 0x4UL /* Bit mask for LETIMER_COMP0 */ +#define _LETIMER_SYNCBUSY_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_COMP0_DEFAULT (_LETIMER_SYNCBUSY_COMP0_DEFAULT << 2) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_COMP1 (0x1UL << 3) /* COMP1 Register Busy */ +#define _LETIMER_SYNCBUSY_COMP1_SHIFT 3 /* Shift value for LETIMER_COMP1 */ +#define _LETIMER_SYNCBUSY_COMP1_MASK 0x8UL /* Bit mask for LETIMER_COMP1 */ +#define _LETIMER_SYNCBUSY_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_COMP1_DEFAULT (_LETIMER_SYNCBUSY_COMP1_DEFAULT << 3) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_REP0 (0x1UL << 4) /* REP0 Register Busy */ +#define _LETIMER_SYNCBUSY_REP0_SHIFT 4 /* Shift value for LETIMER_REP0 */ +#define _LETIMER_SYNCBUSY_REP0_MASK 0x10UL /* Bit mask for LETIMER_REP0 */ +#define _LETIMER_SYNCBUSY_REP0_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_REP0_DEFAULT (_LETIMER_SYNCBUSY_REP0_DEFAULT << 4) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_REP1 (0x1UL << 5) /* REP1 Register Busy */ +#define _LETIMER_SYNCBUSY_REP1_SHIFT 5 /* Shift value for LETIMER_REP1 */ +#define _LETIMER_SYNCBUSY_REP1_MASK 0x20UL /* Bit mask for LETIMER_REP1 */ +#define _LETIMER_SYNCBUSY_REP1_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_REP1_DEFAULT (_LETIMER_SYNCBUSY_REP1_DEFAULT << 5) /* Shifted mode DEFAULT for LETIMER_SYNCBUSY */ + +/* Bit fields for LETIMER ROUTE */ + +#define _LETIMER_ROUTE_RESETVALUE 0x00000000UL /* Default value for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_MASK 0x00000703UL /* Mask for LETIMER_ROUTE */ + +#define LETIMER_ROUTE_OUT0PEN (0x1UL << 0) /* Output 0 Pin Enable */ +#define _LETIMER_ROUTE_OUT0PEN_SHIFT 0 /* Shift value for LETIMER_OUT0PEN */ +#define _LETIMER_ROUTE_OUT0PEN_MASK 0x1UL /* Bit mask for LETIMER_OUT0PEN */ +#define _LETIMER_ROUTE_OUT0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_ROUTE */ +#define LETIMER_ROUTE_OUT0PEN_DEFAULT (_LETIMER_ROUTE_OUT0PEN_DEFAULT << 0) /* Shifted mode DEFAULT for LETIMER_ROUTE */ +#define LETIMER_ROUTE_OUT1PEN (0x1UL << 1) /* Output 1 Pin Enable */ +#define _LETIMER_ROUTE_OUT1PEN_SHIFT 1 /* Shift value for LETIMER_OUT1PEN */ +#define _LETIMER_ROUTE_OUT1PEN_MASK 0x2UL /* Bit mask for LETIMER_OUT1PEN */ +#define _LETIMER_ROUTE_OUT1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_ROUTE */ +#define LETIMER_ROUTE_OUT1PEN_DEFAULT (_LETIMER_ROUTE_OUT1PEN_DEFAULT << 1) /* Shifted mode DEFAULT for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_LOCATION_SHIFT 8 /* Shift value for LETIMER_LOCATION */ +#define _LETIMER_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for LETIMER_LOCATION */ +#define _LETIMER_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for LETIMER_ROUTE */ +#define _LETIMER_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_LOC0 (_LETIMER_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_DEFAULT (_LETIMER_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_LOC1 (_LETIMER_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_LOC2 (_LETIMER_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_LOC3 (_LETIMER_ROUTE_LOCATION_LOC3 << 8) /* Shifted mode LOC3 for LETIMER_ROUTE */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LETIMER_H */ diff --git a/arch/arm/src/efm32/chip/efm32_leuart.h b/arch/arm/src/efm32/chip/efm32_leuart.h new file mode 100644 index 0000000000000000000000000000000000000000..be5b1bc0de45a235a8ad2a35186339008c177208 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_leuart.h @@ -0,0 +1,827 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_leuart.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LEUART_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LEUART_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) && !defined(CONFIG_EFM32_EFM32G) +# warning This is the EFM32GG/G header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* LEUART Register Offsets *****************************************************************************************************/ + +#define EFM32_LEUART_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_LEUART_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_LEUART_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_LEUART_CLKDIV_OFFSET 0x000c /* Clock Control Register */ +#define EFM32_LEUART_STARTFRAME_OFFSET 0x0010 /* Start Frame Register */ +#define EFM32_LEUART_SIGFRAME_OFFSET 0x0014 /* Signal Frame Register */ +#define EFM32_LEUART_RXDATAX_OFFSET 0x0018 /* Receive Buffer Data Extended Register */ +#define EFM32_LEUART_RXDATA_OFFSET 0x001c /* Receive Buffer Data Register */ +#define EFM32_LEUART_RXDATAXP_OFFSET 0x0020 /* Receive Buffer Data Extended Peek Register */ +#define EFM32_LEUART_TXDATAX_OFFSET 0x0024 /* Transmit Buffer Data Extended Register */ +#define EFM32_LEUART_TXDATA_OFFSET 0x0028 /* Transmit Buffer Data Register */ +#define EFM32_LEUART_IF_OFFSET 0x002c /* Interrupt Flag Register */ +#define EFM32_LEUART_IFS_OFFSET 0x0030 /* Interrupt Flag Set Register */ +#define EFM32_LEUART_IFC_OFFSET 0x0034 /* Interrupt Flag Clear Register */ +#define EFM32_LEUART_IEN_OFFSET 0x0038 /* Interrupt Enable Register */ +#define EFM32_LEUART_PULSECTRL_OFFSET 0x003c /* Pulse Control Register */ +#define EFM32_LEUART_FREEZE_OFFSET 0x0040 /* Freeze Register */ +#define EFM32_LEUART_SYNCBUSY_OFFSET 0x0044 /* Synchronization Busy Register */ +#define EFM32_LEUART_ROUTE_OFFSET 0x0054 /* I/O Routing Register */ + +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_LEUART_INPUT_OFFSET 0x00ac /* LEUART Input Register */ +#endif + +/* LEUART Register Addresses ***************************************************************************************************/ + +#define EFM32_LEUART0_CTRL (EFM32_LEUART0_BASE+EFM32_LEUART_CTRL_OFFSET) +#define EFM32_LEUART0_CMD (EFM32_LEUART0_BASE+EFM32_LEUART_CMD_OFFSET) +#define EFM32_LEUART0_STATUS (EFM32_LEUART0_BASE+EFM32_LEUART_STATUS_OFFSET) +#define EFM32_LEUART0_CLKDIV (EFM32_LEUART0_BASE+EFM32_LEUART_CLKDIV_OFFSET) +#define EFM32_LEUART0_STARTFRAME (EFM32_LEUART0_BASE+EFM32_LEUART_STARTFRAME_OFFSET) +#define EFM32_LEUART0_SIGFRAME (EFM32_LEUART0_BASE+EFM32_LEUART_SIGFRAME_OFFSET) +#define EFM32_LEUART0_RXDATAX (EFM32_LEUART0_BASE+EFM32_LEUART_RXDATAX_OFFSET) +#define EFM32_LEUART0_RXDATA (EFM32_LEUART0_BASE+EFM32_LEUART_RXDATA_OFFSET) +#define EFM32_LEUART0_RXDATAXP (EFM32_LEUART0_BASE+EFM32_LEUART_RXDATAXP_OFFSET) +#define EFM32_LEUART0_TXDATAX (EFM32_LEUART0_BASE+EFM32_LEUART_TXDATAX_OFFSET) +#define EFM32_LEUART0_TXDATA (EFM32_LEUART0_BASE+EFM32_LEUART_TXDATA_OFFSET) +#define EFM32_LEUART0_IF (EFM32_LEUART0_BASE+EFM32_LEUART_IF_OFFSET) +#define EFM32_LEUART0_IFS (EFM32_LEUART0_BASE+EFM32_LEUART_IFS_OFFSET) +#define EFM32_LEUART0_IFC (EFM32_LEUART0_BASE+EFM32_LEUART_IFC_OFFSET) +#define EFM32_LEUART0_IEN (EFM32_LEUART0_BASE+EFM32_LEUART_IEN_OFFSET) +#define EFM32_LEUART0_PULSECTRL (EFM32_LEUART0_BASE+EFM32_LEUART_PULSECTRL_OFFSET) +#define EFM32_LEUART0_FREEZE (EFM32_LEUART0_BASE+EFM32_LEUART_FREEZE_OFFSET) +#define EFM32_LEUART0_SYNCBUSY (EFM32_LEUART0_BASE+EFM32_LEUART_SYNCBUSY_OFFSET) +#define EFM32_LEUART0_ROUTE (EFM32_LEUART0_BASE+EFM32_LEUART_ROUTE_OFFSET) + +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_LEUART0_INPUT (EFM32_LEUART0_BASE+EFM32_LEUART_INPUT_OFFSET) +#endif + +#ifdef CONFIG_EFM32_HAVE_LEUART1 +# define EFM32_LEUART1_CTRL (EFM32_LEUART1_BASE+EFM32_LEUART_CTRL_OFFSET) +# define EFM32_LEUART1_CMD (EFM32_LEUART1_BASE+EFM32_LEUART_CMD_OFFSET) +# define EFM32_LEUART1_STATUS (EFM32_LEUART1_BASE+EFM32_LEUART_STATUS_OFFSET) +# define EFM32_LEUART1_CLKDIV (EFM32_LEUART1_BASE+EFM32_LEUART_CLKDIV_OFFSET) +# define EFM32_LEUART1_STARTFRAME (EFM32_LEUART1_BASE+EFM32_LEUART_STARTFRAME_OFFSET) +# define EFM32_LEUART1_SIGFRAME (EFM32_LEUART1_BASE+EFM32_LEUART_SIGFRAME_OFFSET) +# define EFM32_LEUART1_RXDATAX (EFM32_LEUART1_BASE+EFM32_LEUART_RXDATAX_OFFSET) +# define EFM32_LEUART1_RXDATA (EFM32_LEUART1_BASE+EFM32_LEUART_RXDATA_OFFSET) +# define EFM32_LEUART1_RXDATAXP (EFM32_LEUART1_BASE+EFM32_LEUART_RXDATAXP_OFFSET) +# define EFM32_LEUART1_TXDATAX (EFM32_LEUART1_BASE+EFM32_LEUART_TXDATAX_OFFSET) +# define EFM32_LEUART1_TXDATA (EFM32_LEUART1_BASE+EFM32_LEUART_TXDATA_OFFSET) +# define EFM32_LEUART1_IF (EFM32_LEUART1_BASE+EFM32_LEUART_IF_OFFSET) +# define EFM32_LEUART1_IFS (EFM32_LEUART1_BASE+EFM32_LEUART_IFS_OFFSET) +# define EFM32_LEUART1_IFC (EFM32_LEUART1_BASE+EFM32_LEUART_IFC_OFFSET) +# define EFM32_LEUART1_IEN (EFM32_LEUART1_BASE+EFM32_LEUART_IEN_OFFSET) +# define EFM32_LEUART1_PULSECTRL (EFM32_LEUART1_BASE+EFM32_LEUART_PULSECTRL_OFFSET) +# define EFM32_LEUART1_FREEZE (EFM32_LEUART1_BASE+EFM32_LEUART_FREEZE_OFFSET) +# define EFM32_LEUART1_SYNCBUSY (EFM32_LEUART1_BASE+EFM32_LEUART_SYNCBUSY_OFFSET) +# define EFM32_LEUART1_ROUTE (EFM32_LEUART1_BASE+EFM32_LEUART_ROUTE_OFFSET) + +# ifdef CONFIG_EFM32_EFM32GG +# define EFM32_LEUART1_INPUT (EFM32_LEUART1_BASE+EFM32_LEUART_INPUT_OFFSET) +# endif +#endif + +/* LEUART Register Bit Field Definitions ***************************************************************************************/ + +/* Bit fields for LEUART CTRL */ + +#define _LEUART_CTRL_RESETVALUE 0x00000000UL /* Default value for LEUART_CTRL */ +#define _LEUART_CTRL_MASK 0x0000FFFFUL /* Mask for LEUART_CTRL */ + +#define LEUART_CTRL_AUTOTRI (0x1UL << 0) /* Automatic Transmitter Tristate */ +#define _LEUART_CTRL_AUTOTRI_SHIFT 0 /* Shift value for LEUART_AUTOTRI */ +#define _LEUART_CTRL_AUTOTRI_MASK 0x1UL /* Bit mask for LEUART_AUTOTRI */ +#define _LEUART_CTRL_AUTOTRI_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_AUTOTRI_DEFAULT (_LEUART_CTRL_AUTOTRI_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_DATABITS (0x1UL << 1) /* Data-Bit Mode */ +#define _LEUART_CTRL_DATABITS_SHIFT 1 /* Shift value for LEUART_DATABITS */ +#define _LEUART_CTRL_DATABITS_MASK 0x2UL /* Bit mask for LEUART_DATABITS */ +#define _LEUART_CTRL_DATABITS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define _LEUART_CTRL_DATABITS_EIGHT 0x00000000UL /* Mode EIGHT for LEUART_CTRL */ +#define _LEUART_CTRL_DATABITS_NINE 0x00000001UL /* Mode NINE for LEUART_CTRL */ +#define LEUART_CTRL_DATABITS_DEFAULT (_LEUART_CTRL_DATABITS_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_DATABITS_EIGHT (_LEUART_CTRL_DATABITS_EIGHT << 1) /* Shifted mode EIGHT for LEUART_CTRL */ +#define LEUART_CTRL_DATABITS_NINE (_LEUART_CTRL_DATABITS_NINE << 1) /* Shifted mode NINE for LEUART_CTRL */ +#define _LEUART_CTRL_PARITY_SHIFT 2 /* Shift value for LEUART_PARITY */ +#define _LEUART_CTRL_PARITY_MASK 0xCUL /* Bit mask for LEUART_PARITY */ +#define _LEUART_CTRL_PARITY_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define _LEUART_CTRL_PARITY_NONE 0x00000000UL /* Mode NONE for LEUART_CTRL */ +#define _LEUART_CTRL_PARITY_EVEN 0x00000002UL /* Mode EVEN for LEUART_CTRL */ +#define _LEUART_CTRL_PARITY_ODD 0x00000003UL /* Mode ODD for LEUART_CTRL */ +#define LEUART_CTRL_PARITY_DEFAULT (_LEUART_CTRL_PARITY_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_PARITY_NONE (_LEUART_CTRL_PARITY_NONE << 2) /* Shifted mode NONE for LEUART_CTRL */ +#define LEUART_CTRL_PARITY_EVEN (_LEUART_CTRL_PARITY_EVEN << 2) /* Shifted mode EVEN for LEUART_CTRL */ +#define LEUART_CTRL_PARITY_ODD (_LEUART_CTRL_PARITY_ODD << 2) /* Shifted mode ODD for LEUART_CTRL */ +#define LEUART_CTRL_STOPBITS (0x1UL << 4) /* Stop-Bit Mode */ +#define _LEUART_CTRL_STOPBITS_SHIFT 4 /* Shift value for LEUART_STOPBITS */ +#define _LEUART_CTRL_STOPBITS_MASK 0x10UL /* Bit mask for LEUART_STOPBITS */ +#define _LEUART_CTRL_STOPBITS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define _LEUART_CTRL_STOPBITS_ONE 0x00000000UL /* Mode ONE for LEUART_CTRL */ +#define _LEUART_CTRL_STOPBITS_TWO 0x00000001UL /* Mode TWO for LEUART_CTRL */ +#define LEUART_CTRL_STOPBITS_DEFAULT (_LEUART_CTRL_STOPBITS_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_STOPBITS_ONE (_LEUART_CTRL_STOPBITS_ONE << 4) /* Shifted mode ONE for LEUART_CTRL */ +#define LEUART_CTRL_STOPBITS_TWO (_LEUART_CTRL_STOPBITS_TWO << 4) /* Shifted mode TWO for LEUART_CTRL */ +#define LEUART_CTRL_INV (0x1UL << 5) /* Invert Input And Output */ +#define _LEUART_CTRL_INV_SHIFT 5 /* Shift value for LEUART_INV */ +#define _LEUART_CTRL_INV_MASK 0x20UL /* Bit mask for LEUART_INV */ +#define _LEUART_CTRL_INV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_INV_DEFAULT (_LEUART_CTRL_INV_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_ERRSDMA (0x1UL << 6) /* Clear RX DMA On Error */ +#define _LEUART_CTRL_ERRSDMA_SHIFT 6 /* Shift value for LEUART_ERRSDMA */ +#define _LEUART_CTRL_ERRSDMA_MASK 0x40UL /* Bit mask for LEUART_ERRSDMA */ +#define _LEUART_CTRL_ERRSDMA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_ERRSDMA_DEFAULT (_LEUART_CTRL_ERRSDMA_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_LOOPBK (0x1UL << 7) /* Loopback Enable */ +#define _LEUART_CTRL_LOOPBK_SHIFT 7 /* Shift value for LEUART_LOOPBK */ +#define _LEUART_CTRL_LOOPBK_MASK 0x80UL /* Bit mask for LEUART_LOOPBK */ +#define _LEUART_CTRL_LOOPBK_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_LOOPBK_DEFAULT (_LEUART_CTRL_LOOPBK_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_SFUBRX (0x1UL << 8) /* Start-Frame UnBlock RX */ +#define _LEUART_CTRL_SFUBRX_SHIFT 8 /* Shift value for LEUART_SFUBRX */ +#define _LEUART_CTRL_SFUBRX_MASK 0x100UL /* Bit mask for LEUART_SFUBRX */ +#define _LEUART_CTRL_SFUBRX_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_SFUBRX_DEFAULT (_LEUART_CTRL_SFUBRX_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_MPM (0x1UL << 9) /* Multi-Processor Mode */ +#define _LEUART_CTRL_MPM_SHIFT 9 /* Shift value for LEUART_MPM */ +#define _LEUART_CTRL_MPM_MASK 0x200UL /* Bit mask for LEUART_MPM */ +#define _LEUART_CTRL_MPM_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_MPM_DEFAULT (_LEUART_CTRL_MPM_DEFAULT << 9) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_MPAB (0x1UL << 10) /* Multi-Processor Address-Bit */ +#define _LEUART_CTRL_MPAB_SHIFT 10 /* Shift value for LEUART_MPAB */ +#define _LEUART_CTRL_MPAB_MASK 0x400UL /* Bit mask for LEUART_MPAB */ +#define _LEUART_CTRL_MPAB_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_MPAB_DEFAULT (_LEUART_CTRL_MPAB_DEFAULT << 10) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_BIT8DV (0x1UL << 11) /* Bit 8 Default Value */ +#define _LEUART_CTRL_BIT8DV_SHIFT 11 /* Shift value for LEUART_BIT8DV */ +#define _LEUART_CTRL_BIT8DV_MASK 0x800UL /* Bit mask for LEUART_BIT8DV */ +#define _LEUART_CTRL_BIT8DV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_BIT8DV_DEFAULT (_LEUART_CTRL_BIT8DV_DEFAULT << 11) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_RXDMAWU (0x1UL << 12) /* RX DMA Wakeup */ +#define _LEUART_CTRL_RXDMAWU_SHIFT 12 /* Shift value for LEUART_RXDMAWU */ +#define _LEUART_CTRL_RXDMAWU_MASK 0x1000UL /* Bit mask for LEUART_RXDMAWU */ +#define _LEUART_CTRL_RXDMAWU_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_RXDMAWU_DEFAULT (_LEUART_CTRL_RXDMAWU_DEFAULT << 12) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_TXDMAWU (0x1UL << 13) /* TX DMA Wakeup */ +#define _LEUART_CTRL_TXDMAWU_SHIFT 13 /* Shift value for LEUART_TXDMAWU */ +#define _LEUART_CTRL_TXDMAWU_MASK 0x2000UL /* Bit mask for LEUART_TXDMAWU */ +#define _LEUART_CTRL_TXDMAWU_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_TXDMAWU_DEFAULT (_LEUART_CTRL_TXDMAWU_DEFAULT << 13) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define _LEUART_CTRL_TXDELAY_SHIFT 14 /* Shift value for LEUART_TXDELAY */ +#define _LEUART_CTRL_TXDELAY_MASK 0xC000UL /* Bit mask for LEUART_TXDELAY */ +#define _LEUART_CTRL_TXDELAY_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CTRL */ +#define _LEUART_CTRL_TXDELAY_NONE 0x00000000UL /* Mode NONE for LEUART_CTRL */ +#define _LEUART_CTRL_TXDELAY_SINGLE 0x00000001UL /* Mode SINGLE for LEUART_CTRL */ +#define _LEUART_CTRL_TXDELAY_DOUBLE 0x00000002UL /* Mode DOUBLE for LEUART_CTRL */ +#define _LEUART_CTRL_TXDELAY_TRIPLE 0x00000003UL /* Mode TRIPLE for LEUART_CTRL */ +#define LEUART_CTRL_TXDELAY_DEFAULT (_LEUART_CTRL_TXDELAY_DEFAULT << 14) /* Shifted mode DEFAULT for LEUART_CTRL */ +#define LEUART_CTRL_TXDELAY_NONE (_LEUART_CTRL_TXDELAY_NONE << 14) /* Shifted mode NONE for LEUART_CTRL */ +#define LEUART_CTRL_TXDELAY_SINGLE (_LEUART_CTRL_TXDELAY_SINGLE << 14) /* Shifted mode SINGLE for LEUART_CTRL */ +#define LEUART_CTRL_TXDELAY_DOUBLE (_LEUART_CTRL_TXDELAY_DOUBLE << 14) /* Shifted mode DOUBLE for LEUART_CTRL */ +#define LEUART_CTRL_TXDELAY_TRIPLE (_LEUART_CTRL_TXDELAY_TRIPLE << 14) /* Shifted mode TRIPLE for LEUART_CTRL */ + +/* Bit fields for LEUART CMD */ + +#define _LEUART_CMD_RESETVALUE 0x00000000UL /* Default value for LEUART_CMD */ +#define _LEUART_CMD_MASK 0x000000FFUL /* Mask for LEUART_CMD */ + +#define LEUART_CMD_RXEN (0x1UL << 0) /* Receiver Enable */ +#define _LEUART_CMD_RXEN_SHIFT 0 /* Shift value for LEUART_RXEN */ +#define _LEUART_CMD_RXEN_MASK 0x1UL /* Bit mask for LEUART_RXEN */ +#define _LEUART_CMD_RXEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXEN_DEFAULT (_LEUART_CMD_RXEN_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXDIS (0x1UL << 1) /* Receiver Disable */ +#define _LEUART_CMD_RXDIS_SHIFT 1 /* Shift value for LEUART_RXDIS */ +#define _LEUART_CMD_RXDIS_MASK 0x2UL /* Bit mask for LEUART_RXDIS */ +#define _LEUART_CMD_RXDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXDIS_DEFAULT (_LEUART_CMD_RXDIS_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_TXEN (0x1UL << 2) /* Transmitter Enable */ +#define _LEUART_CMD_TXEN_SHIFT 2 /* Shift value for LEUART_TXEN */ +#define _LEUART_CMD_TXEN_MASK 0x4UL /* Bit mask for LEUART_TXEN */ +#define _LEUART_CMD_TXEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_TXEN_DEFAULT (_LEUART_CMD_TXEN_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_TXDIS (0x1UL << 3) /* Transmitter Disable */ +#define _LEUART_CMD_TXDIS_SHIFT 3 /* Shift value for LEUART_TXDIS */ +#define _LEUART_CMD_TXDIS_MASK 0x8UL /* Bit mask for LEUART_TXDIS */ +#define _LEUART_CMD_TXDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_TXDIS_DEFAULT (_LEUART_CMD_TXDIS_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXBLOCKEN (0x1UL << 4) /* Receiver Block Enable */ +#define _LEUART_CMD_RXBLOCKEN_SHIFT 4 /* Shift value for LEUART_RXBLOCKEN */ +#define _LEUART_CMD_RXBLOCKEN_MASK 0x10UL /* Bit mask for LEUART_RXBLOCKEN */ +#define _LEUART_CMD_RXBLOCKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXBLOCKEN_DEFAULT (_LEUART_CMD_RXBLOCKEN_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXBLOCKDIS (0x1UL << 5) /* Receiver Block Disable */ +#define _LEUART_CMD_RXBLOCKDIS_SHIFT 5 /* Shift value for LEUART_RXBLOCKDIS */ +#define _LEUART_CMD_RXBLOCKDIS_MASK 0x20UL /* Bit mask for LEUART_RXBLOCKDIS */ +#define _LEUART_CMD_RXBLOCKDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_RXBLOCKDIS_DEFAULT (_LEUART_CMD_RXBLOCKDIS_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_CLEARTX (0x1UL << 6) /* Clear TX */ +#define _LEUART_CMD_CLEARTX_SHIFT 6 /* Shift value for LEUART_CLEARTX */ +#define _LEUART_CMD_CLEARTX_MASK 0x40UL /* Bit mask for LEUART_CLEARTX */ +#define _LEUART_CMD_CLEARTX_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_CLEARTX_DEFAULT (_LEUART_CMD_CLEARTX_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_CLEARRX (0x1UL << 7) /* Clear RX */ +#define _LEUART_CMD_CLEARRX_SHIFT 7 /* Shift value for LEUART_CLEARRX */ +#define _LEUART_CMD_CLEARRX_MASK 0x80UL /* Bit mask for LEUART_CLEARRX */ +#define _LEUART_CMD_CLEARRX_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CMD */ +#define LEUART_CMD_CLEARRX_DEFAULT (_LEUART_CMD_CLEARRX_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_CMD */ + +/* Bit fields for LEUART STATUS */ + +#define _LEUART_STATUS_RESETVALUE 0x00000010UL /* Default value for LEUART_STATUS */ +#define _LEUART_STATUS_MASK 0x0000003FUL /* Mask for LEUART_STATUS */ + +#define LEUART_STATUS_RXENS (0x1UL << 0) /* Receiver Enable Status */ +#define _LEUART_STATUS_RXENS_SHIFT 0 /* Shift value for LEUART_RXENS */ +#define _LEUART_STATUS_RXENS_MASK 0x1UL /* Bit mask for LEUART_RXENS */ +#define _LEUART_STATUS_RXENS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_RXENS_DEFAULT (_LEUART_STATUS_RXENS_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXENS (0x1UL << 1) /* Transmitter Enable Status */ +#define _LEUART_STATUS_TXENS_SHIFT 1 /* Shift value for LEUART_TXENS */ +#define _LEUART_STATUS_TXENS_MASK 0x2UL /* Bit mask for LEUART_TXENS */ +#define _LEUART_STATUS_TXENS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXENS_DEFAULT (_LEUART_STATUS_TXENS_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_RXBLOCK (0x1UL << 2) /* Block Incoming Data */ +#define _LEUART_STATUS_RXBLOCK_SHIFT 2 /* Shift value for LEUART_RXBLOCK */ +#define _LEUART_STATUS_RXBLOCK_MASK 0x4UL /* Bit mask for LEUART_RXBLOCK */ +#define _LEUART_STATUS_RXBLOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_RXBLOCK_DEFAULT (_LEUART_STATUS_RXBLOCK_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXC (0x1UL << 3) /* TX Complete */ +#define _LEUART_STATUS_TXC_SHIFT 3 /* Shift value for LEUART_TXC */ +#define _LEUART_STATUS_TXC_MASK 0x8UL /* Bit mask for LEUART_TXC */ +#define _LEUART_STATUS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXC_DEFAULT (_LEUART_STATUS_TXC_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXBL (0x1UL << 4) /* TX Buffer Level */ +#define _LEUART_STATUS_TXBL_SHIFT 4 /* Shift value for LEUART_TXBL */ +#define _LEUART_STATUS_TXBL_MASK 0x10UL /* Bit mask for LEUART_TXBL */ +#define _LEUART_STATUS_TXBL_DEFAULT 0x00000001UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_TXBL_DEFAULT (_LEUART_STATUS_TXBL_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_RXDATAV (0x1UL << 5) /* RX Data Valid */ +#define _LEUART_STATUS_RXDATAV_SHIFT 5 /* Shift value for LEUART_RXDATAV */ +#define _LEUART_STATUS_RXDATAV_MASK 0x20UL /* Bit mask for LEUART_RXDATAV */ +#define _LEUART_STATUS_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STATUS */ +#define LEUART_STATUS_RXDATAV_DEFAULT (_LEUART_STATUS_RXDATAV_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_STATUS */ + +/* Bit fields for LEUART CLKDIV */ + +#define _LEUART_CLKDIV_RESETVALUE 0x00000000UL /* Default value for LEUART_CLKDIV */ +#define _LEUART_CLKDIV_MASK 0x00007FF8UL /* Mask for LEUART_CLKDIV */ + +#define _LEUART_CLKDIV_DIV_SHIFT 3 /* Shift value for LEUART_DIV */ +#define _LEUART_CLKDIV_DIV_MASK 0x7FF8UL /* Bit mask for LEUART_DIV */ +#define _LEUART_CLKDIV_DIV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_CLKDIV */ +#define LEUART_CLKDIV_DIV_DEFAULT (_LEUART_CLKDIV_DIV_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_CLKDIV */ + +/* Bit fields for LEUART STARTFRAME */ + +#define _LEUART_STARTFRAME_RESETVALUE 0x00000000UL /* Default value for LEUART_STARTFRAME */ +#define _LEUART_STARTFRAME_MASK 0x000001FFUL /* Mask for LEUART_STARTFRAME */ + +#define _LEUART_STARTFRAME_STARTFRAME_SHIFT 0 /* Shift value for LEUART_STARTFRAME */ +#define _LEUART_STARTFRAME_STARTFRAME_MASK 0x1FFUL /* Bit mask for LEUART_STARTFRAME */ +#define _LEUART_STARTFRAME_STARTFRAME_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_STARTFRAME */ +#define LEUART_STARTFRAME_STARTFRAME_DEFAULT (_LEUART_STARTFRAME_STARTFRAME_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_STARTFRAME */ + +/* Bit fields for LEUART SIGFRAME */ + +#define _LEUART_SIGFRAME_RESETVALUE 0x00000000UL /* Default value for LEUART_SIGFRAME */ +#define _LEUART_SIGFRAME_MASK 0x000001FFUL /* Mask for LEUART_SIGFRAME */ + +#define _LEUART_SIGFRAME_SIGFRAME_SHIFT 0 /* Shift value for LEUART_SIGFRAME */ +#define _LEUART_SIGFRAME_SIGFRAME_MASK 0x1FFUL /* Bit mask for LEUART_SIGFRAME */ +#define _LEUART_SIGFRAME_SIGFRAME_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SIGFRAME */ +#define LEUART_SIGFRAME_SIGFRAME_DEFAULT (_LEUART_SIGFRAME_SIGFRAME_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_SIGFRAME */ + +/* Bit fields for LEUART RXDATAX */ + +#define _LEUART_RXDATAX_RESETVALUE 0x00000000UL /* Default value for LEUART_RXDATAX */ +#define _LEUART_RXDATAX_MASK 0x0000C1FFUL /* Mask for LEUART_RXDATAX */ + +#define _LEUART_RXDATAX_RXDATA_SHIFT 0 /* Shift value for LEUART_RXDATA */ +#define _LEUART_RXDATAX_RXDATA_MASK 0x1FFUL /* Bit mask for LEUART_RXDATA */ +#define _LEUART_RXDATAX_RXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAX */ +#define LEUART_RXDATAX_RXDATA_DEFAULT (_LEUART_RXDATAX_RXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_RXDATAX */ +#define LEUART_RXDATAX_PERR (0x1UL << 14) /* Receive Data Parity Error */ +#define _LEUART_RXDATAX_PERR_SHIFT 14 /* Shift value for LEUART_PERR */ +#define _LEUART_RXDATAX_PERR_MASK 0x4000UL /* Bit mask for LEUART_PERR */ +#define _LEUART_RXDATAX_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAX */ +#define LEUART_RXDATAX_PERR_DEFAULT (_LEUART_RXDATAX_PERR_DEFAULT << 14) /* Shifted mode DEFAULT for LEUART_RXDATAX */ +#define LEUART_RXDATAX_FERR (0x1UL << 15) /* Receive Data Framing Error */ +#define _LEUART_RXDATAX_FERR_SHIFT 15 /* Shift value for LEUART_FERR */ +#define _LEUART_RXDATAX_FERR_MASK 0x8000UL /* Bit mask for LEUART_FERR */ +#define _LEUART_RXDATAX_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAX */ +#define LEUART_RXDATAX_FERR_DEFAULT (_LEUART_RXDATAX_FERR_DEFAULT << 15) /* Shifted mode DEFAULT for LEUART_RXDATAX */ + +/* Bit fields for LEUART RXDATA */ + +#define _LEUART_RXDATA_RESETVALUE 0x00000000UL /* Default value for LEUART_RXDATA */ +#define _LEUART_RXDATA_MASK 0x000000FFUL /* Mask for LEUART_RXDATA */ + +#define _LEUART_RXDATA_RXDATA_SHIFT 0 /* Shift value for LEUART_RXDATA */ +#define _LEUART_RXDATA_RXDATA_MASK 0xFFUL /* Bit mask for LEUART_RXDATA */ +#define _LEUART_RXDATA_RXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATA */ +#define LEUART_RXDATA_RXDATA_DEFAULT (_LEUART_RXDATA_RXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_RXDATA */ + +/* Bit fields for LEUART RXDATAXP */ + +#define _LEUART_RXDATAXP_RESETVALUE 0x00000000UL /* Default value for LEUART_RXDATAXP */ +#define _LEUART_RXDATAXP_MASK 0x0000C1FFUL /* Mask for LEUART_RXDATAXP */ + +#define _LEUART_RXDATAXP_RXDATAP_SHIFT 0 /* Shift value for LEUART_RXDATAP */ +#define _LEUART_RXDATAXP_RXDATAP_MASK 0x1FFUL /* Bit mask for LEUART_RXDATAP */ +#define _LEUART_RXDATAXP_RXDATAP_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAXP */ +#define LEUART_RXDATAXP_RXDATAP_DEFAULT (_LEUART_RXDATAXP_RXDATAP_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_RXDATAXP */ +#define LEUART_RXDATAXP_PERRP (0x1UL << 14) /* Receive Data Parity Error Peek */ +#define _LEUART_RXDATAXP_PERRP_SHIFT 14 /* Shift value for LEUART_PERRP */ +#define _LEUART_RXDATAXP_PERRP_MASK 0x4000UL /* Bit mask for LEUART_PERRP */ +#define _LEUART_RXDATAXP_PERRP_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAXP */ +#define LEUART_RXDATAXP_PERRP_DEFAULT (_LEUART_RXDATAXP_PERRP_DEFAULT << 14) /* Shifted mode DEFAULT for LEUART_RXDATAXP */ +#define LEUART_RXDATAXP_FERRP (0x1UL << 15) /* Receive Data Framing Error Peek */ +#define _LEUART_RXDATAXP_FERRP_SHIFT 15 /* Shift value for LEUART_FERRP */ +#define _LEUART_RXDATAXP_FERRP_MASK 0x8000UL /* Bit mask for LEUART_FERRP */ +#define _LEUART_RXDATAXP_FERRP_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_RXDATAXP */ +#define LEUART_RXDATAXP_FERRP_DEFAULT (_LEUART_RXDATAXP_FERRP_DEFAULT << 15) /* Shifted mode DEFAULT for LEUART_RXDATAXP */ + +/* Bit fields for LEUART TXDATAX */ + +#define _LEUART_TXDATAX_RESETVALUE 0x00000000UL /* Default value for LEUART_TXDATAX */ +#define _LEUART_TXDATAX_MASK 0x0000E1FFUL /* Mask for LEUART_TXDATAX */ + +#define _LEUART_TXDATAX_TXDATA_SHIFT 0 /* Shift value for LEUART_TXDATA */ +#define _LEUART_TXDATAX_TXDATA_MASK 0x1FFUL /* Bit mask for LEUART_TXDATA */ +#define _LEUART_TXDATAX_TXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_TXDATA_DEFAULT (_LEUART_TXDATAX_TXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_TXBREAK (0x1UL << 13) /* Transmit Data As Break */ +#define _LEUART_TXDATAX_TXBREAK_SHIFT 13 /* Shift value for LEUART_TXBREAK */ +#define _LEUART_TXDATAX_TXBREAK_MASK 0x2000UL /* Bit mask for LEUART_TXBREAK */ +#define _LEUART_TXDATAX_TXBREAK_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_TXBREAK_DEFAULT (_LEUART_TXDATAX_TXBREAK_DEFAULT << 13) /* Shifted mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_TXDISAT (0x1UL << 14) /* Disable TX After Transmission */ +#define _LEUART_TXDATAX_TXDISAT_SHIFT 14 /* Shift value for LEUART_TXDISAT */ +#define _LEUART_TXDATAX_TXDISAT_MASK 0x4000UL /* Bit mask for LEUART_TXDISAT */ +#define _LEUART_TXDATAX_TXDISAT_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_TXDISAT_DEFAULT (_LEUART_TXDATAX_TXDISAT_DEFAULT << 14) /* Shifted mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_RXENAT (0x1UL << 15) /* Enable RX After Transmission */ +#define _LEUART_TXDATAX_RXENAT_SHIFT 15 /* Shift value for LEUART_RXENAT */ +#define _LEUART_TXDATAX_RXENAT_MASK 0x8000UL /* Bit mask for LEUART_RXENAT */ +#define _LEUART_TXDATAX_RXENAT_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_TXDATAX */ +#define LEUART_TXDATAX_RXENAT_DEFAULT (_LEUART_TXDATAX_RXENAT_DEFAULT << 15) /* Shifted mode DEFAULT for LEUART_TXDATAX */ + +/* Bit fields for LEUART TXDATA */ + +#define _LEUART_TXDATA_RESETVALUE 0x00000000UL /* Default value for LEUART_TXDATA */ +#define _LEUART_TXDATA_MASK 0x000000FFUL /* Mask for LEUART_TXDATA */ + +#define _LEUART_TXDATA_TXDATA_SHIFT 0 /* Shift value for LEUART_TXDATA */ +#define _LEUART_TXDATA_TXDATA_MASK 0xFFUL /* Bit mask for LEUART_TXDATA */ +#define _LEUART_TXDATA_TXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_TXDATA */ +#define LEUART_TXDATA_TXDATA_DEFAULT (_LEUART_TXDATA_TXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_TXDATA */ + +/* Bit fields for LEUART IF */ + +#define _LEUART_IF_RESETVALUE 0x00000002UL /* Default value for LEUART_IF */ +#define _LEUART_IF_MASK 0x000007FFUL /* Mask for LEUART_IF */ + +#define LEUART_IF_TXC (0x1UL << 0) /* TX Complete Interrupt Flag */ +#define _LEUART_IF_TXC_SHIFT 0 /* Shift value for LEUART_TXC */ +#define _LEUART_IF_TXC_MASK 0x1UL /* Bit mask for LEUART_TXC */ +#define _LEUART_IF_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_TXC_DEFAULT (_LEUART_IF_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_TXBL (0x1UL << 1) /* TX Buffer Level Interrupt Flag */ +#define _LEUART_IF_TXBL_SHIFT 1 /* Shift value for LEUART_TXBL */ +#define _LEUART_IF_TXBL_MASK 0x2UL /* Bit mask for LEUART_TXBL */ +#define _LEUART_IF_TXBL_DEFAULT 0x00000001UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_TXBL_DEFAULT (_LEUART_IF_TXBL_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXDATAV (0x1UL << 2) /* RX Data Valid Interrupt Flag */ +#define _LEUART_IF_RXDATAV_SHIFT 2 /* Shift value for LEUART_RXDATAV */ +#define _LEUART_IF_RXDATAV_MASK 0x4UL /* Bit mask for LEUART_RXDATAV */ +#define _LEUART_IF_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXDATAV_DEFAULT (_LEUART_IF_RXDATAV_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXOF (0x1UL << 3) /* RX Overflow Interrupt Flag */ +#define _LEUART_IF_RXOF_SHIFT 3 /* Shift value for LEUART_RXOF */ +#define _LEUART_IF_RXOF_MASK 0x8UL /* Bit mask for LEUART_RXOF */ +#define _LEUART_IF_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXOF_DEFAULT (_LEUART_IF_RXOF_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXUF (0x1UL << 4) /* RX Underflow Interrupt Flag */ +#define _LEUART_IF_RXUF_SHIFT 4 /* Shift value for LEUART_RXUF */ +#define _LEUART_IF_RXUF_MASK 0x10UL /* Bit mask for LEUART_RXUF */ +#define _LEUART_IF_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_RXUF_DEFAULT (_LEUART_IF_RXUF_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_TXOF (0x1UL << 5) /* TX Overflow Interrupt Flag */ +#define _LEUART_IF_TXOF_SHIFT 5 /* Shift value for LEUART_TXOF */ +#define _LEUART_IF_TXOF_MASK 0x20UL /* Bit mask for LEUART_TXOF */ +#define _LEUART_IF_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_TXOF_DEFAULT (_LEUART_IF_TXOF_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_PERR (0x1UL << 6) /* Parity Error Interrupt Flag */ +#define _LEUART_IF_PERR_SHIFT 6 /* Shift value for LEUART_PERR */ +#define _LEUART_IF_PERR_MASK 0x40UL /* Bit mask for LEUART_PERR */ +#define _LEUART_IF_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_PERR_DEFAULT (_LEUART_IF_PERR_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_FERR (0x1UL << 7) /* Framing Error Interrupt Flag */ +#define _LEUART_IF_FERR_SHIFT 7 /* Shift value for LEUART_FERR */ +#define _LEUART_IF_FERR_MASK 0x80UL /* Bit mask for LEUART_FERR */ +#define _LEUART_IF_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_FERR_DEFAULT (_LEUART_IF_FERR_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_MPAF (0x1UL << 8) /* Multi-Processor Address Frame Interrupt Flag */ +#define _LEUART_IF_MPAF_SHIFT 8 /* Shift value for LEUART_MPAF */ +#define _LEUART_IF_MPAF_MASK 0x100UL /* Bit mask for LEUART_MPAF */ +#define _LEUART_IF_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_MPAF_DEFAULT (_LEUART_IF_MPAF_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_STARTF (0x1UL << 9) /* Start Frame Interrupt Flag */ +#define _LEUART_IF_STARTF_SHIFT 9 /* Shift value for LEUART_STARTF */ +#define _LEUART_IF_STARTF_MASK 0x200UL /* Bit mask for LEUART_STARTF */ +#define _LEUART_IF_STARTF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_STARTF_DEFAULT (_LEUART_IF_STARTF_DEFAULT << 9) /* Shifted mode DEFAULT for LEUART_IF */ +#define LEUART_IF_SIGF (0x1UL << 10) /* Signal Frame Interrupt Flag */ +#define _LEUART_IF_SIGF_SHIFT 10 /* Shift value for LEUART_SIGF */ +#define _LEUART_IF_SIGF_MASK 0x400UL /* Bit mask for LEUART_SIGF */ +#define _LEUART_IF_SIGF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IF */ +#define LEUART_IF_SIGF_DEFAULT (_LEUART_IF_SIGF_DEFAULT << 10) /* Shifted mode DEFAULT for LEUART_IF */ + +/* Bit fields for LEUART IFS */ + +#define _LEUART_IFS_RESETVALUE 0x00000000UL /* Default value for LEUART_IFS */ +#define _LEUART_IFS_MASK 0x000007F9UL /* Mask for LEUART_IFS */ + +#define LEUART_IFS_TXC (0x1UL << 0) /* Set TX Complete Interrupt Flag */ +#define _LEUART_IFS_TXC_SHIFT 0 /* Shift value for LEUART_TXC */ +#define _LEUART_IFS_TXC_MASK 0x1UL /* Bit mask for LEUART_TXC */ +#define _LEUART_IFS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_TXC_DEFAULT (_LEUART_IFS_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_RXOF (0x1UL << 3) /* Set RX Overflow Interrupt Flag */ +#define _LEUART_IFS_RXOF_SHIFT 3 /* Shift value for LEUART_RXOF */ +#define _LEUART_IFS_RXOF_MASK 0x8UL /* Bit mask for LEUART_RXOF */ +#define _LEUART_IFS_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_RXOF_DEFAULT (_LEUART_IFS_RXOF_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_RXUF (0x1UL << 4) /* Set RX Underflow Interrupt Flag */ +#define _LEUART_IFS_RXUF_SHIFT 4 /* Shift value for LEUART_RXUF */ +#define _LEUART_IFS_RXUF_MASK 0x10UL /* Bit mask for LEUART_RXUF */ +#define _LEUART_IFS_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_RXUF_DEFAULT (_LEUART_IFS_RXUF_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_TXOF (0x1UL << 5) /* Set TX Overflow Interrupt Flag */ +#define _LEUART_IFS_TXOF_SHIFT 5 /* Shift value for LEUART_TXOF */ +#define _LEUART_IFS_TXOF_MASK 0x20UL /* Bit mask for LEUART_TXOF */ +#define _LEUART_IFS_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_TXOF_DEFAULT (_LEUART_IFS_TXOF_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_PERR (0x1UL << 6) /* Set Parity Error Interrupt Flag */ +#define _LEUART_IFS_PERR_SHIFT 6 /* Shift value for LEUART_PERR */ +#define _LEUART_IFS_PERR_MASK 0x40UL /* Bit mask for LEUART_PERR */ +#define _LEUART_IFS_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_PERR_DEFAULT (_LEUART_IFS_PERR_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_FERR (0x1UL << 7) /* Set Framing Error Interrupt Flag */ +#define _LEUART_IFS_FERR_SHIFT 7 /* Shift value for LEUART_FERR */ +#define _LEUART_IFS_FERR_MASK 0x80UL /* Bit mask for LEUART_FERR */ +#define _LEUART_IFS_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_FERR_DEFAULT (_LEUART_IFS_FERR_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_MPAF (0x1UL << 8) /* Set Multi-Processor Address Frame Interrupt Flag */ +#define _LEUART_IFS_MPAF_SHIFT 8 /* Shift value for LEUART_MPAF */ +#define _LEUART_IFS_MPAF_MASK 0x100UL /* Bit mask for LEUART_MPAF */ +#define _LEUART_IFS_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_MPAF_DEFAULT (_LEUART_IFS_MPAF_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_STARTF (0x1UL << 9) /* Set Start Frame Interrupt Flag */ +#define _LEUART_IFS_STARTF_SHIFT 9 /* Shift value for LEUART_STARTF */ +#define _LEUART_IFS_STARTF_MASK 0x200UL /* Bit mask for LEUART_STARTF */ +#define _LEUART_IFS_STARTF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_STARTF_DEFAULT (_LEUART_IFS_STARTF_DEFAULT << 9) /* Shifted mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_SIGF (0x1UL << 10) /* Set Signal Frame Interrupt Flag */ +#define _LEUART_IFS_SIGF_SHIFT 10 /* Shift value for LEUART_SIGF */ +#define _LEUART_IFS_SIGF_MASK 0x400UL /* Bit mask for LEUART_SIGF */ +#define _LEUART_IFS_SIGF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFS */ +#define LEUART_IFS_SIGF_DEFAULT (_LEUART_IFS_SIGF_DEFAULT << 10) /* Shifted mode DEFAULT for LEUART_IFS */ + +/* Bit fields for LEUART IFC */ + +#define _LEUART_IFC_RESETVALUE 0x00000000UL /* Default value for LEUART_IFC */ +#define _LEUART_IFC_MASK 0x000007F9UL /* Mask for LEUART_IFC */ + +#define LEUART_IFC_TXC (0x1UL << 0) /* Clear TX Complete Interrupt Flag */ +#define _LEUART_IFC_TXC_SHIFT 0 /* Shift value for LEUART_TXC */ +#define _LEUART_IFC_TXC_MASK 0x1UL /* Bit mask for LEUART_TXC */ +#define _LEUART_IFC_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_TXC_DEFAULT (_LEUART_IFC_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_RXOF (0x1UL << 3) /* Clear RX Overflow Interrupt Flag */ +#define _LEUART_IFC_RXOF_SHIFT 3 /* Shift value for LEUART_RXOF */ +#define _LEUART_IFC_RXOF_MASK 0x8UL /* Bit mask for LEUART_RXOF */ +#define _LEUART_IFC_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_RXOF_DEFAULT (_LEUART_IFC_RXOF_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_RXUF (0x1UL << 4) /* Clear RX Underflow Interrupt Flag */ +#define _LEUART_IFC_RXUF_SHIFT 4 /* Shift value for LEUART_RXUF */ +#define _LEUART_IFC_RXUF_MASK 0x10UL /* Bit mask for LEUART_RXUF */ +#define _LEUART_IFC_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_RXUF_DEFAULT (_LEUART_IFC_RXUF_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_TXOF (0x1UL << 5) /* Clear TX Overflow Interrupt Flag */ +#define _LEUART_IFC_TXOF_SHIFT 5 /* Shift value for LEUART_TXOF */ +#define _LEUART_IFC_TXOF_MASK 0x20UL /* Bit mask for LEUART_TXOF */ +#define _LEUART_IFC_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_TXOF_DEFAULT (_LEUART_IFC_TXOF_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_PERR (0x1UL << 6) /* Clear Parity Error Interrupt Flag */ +#define _LEUART_IFC_PERR_SHIFT 6 /* Shift value for LEUART_PERR */ +#define _LEUART_IFC_PERR_MASK 0x40UL /* Bit mask for LEUART_PERR */ +#define _LEUART_IFC_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_PERR_DEFAULT (_LEUART_IFC_PERR_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_FERR (0x1UL << 7) /* Clear Framing Error Interrupt Flag */ +#define _LEUART_IFC_FERR_SHIFT 7 /* Shift value for LEUART_FERR */ +#define _LEUART_IFC_FERR_MASK 0x80UL /* Bit mask for LEUART_FERR */ +#define _LEUART_IFC_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_FERR_DEFAULT (_LEUART_IFC_FERR_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_MPAF (0x1UL << 8) /* Clear Multi-Processor Address Frame Interrupt Flag */ +#define _LEUART_IFC_MPAF_SHIFT 8 /* Shift value for LEUART_MPAF */ +#define _LEUART_IFC_MPAF_MASK 0x100UL /* Bit mask for LEUART_MPAF */ +#define _LEUART_IFC_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_MPAF_DEFAULT (_LEUART_IFC_MPAF_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_STARTF (0x1UL << 9) /* Clear Start-Frame Interrupt Flag */ +#define _LEUART_IFC_STARTF_SHIFT 9 /* Shift value for LEUART_STARTF */ +#define _LEUART_IFC_STARTF_MASK 0x200UL /* Bit mask for LEUART_STARTF */ +#define _LEUART_IFC_STARTF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_STARTF_DEFAULT (_LEUART_IFC_STARTF_DEFAULT << 9) /* Shifted mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_SIGF (0x1UL << 10) /* Clear Signal-Frame Interrupt Flag */ +#define _LEUART_IFC_SIGF_SHIFT 10 /* Shift value for LEUART_SIGF */ +#define _LEUART_IFC_SIGF_MASK 0x400UL /* Bit mask for LEUART_SIGF */ +#define _LEUART_IFC_SIGF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IFC */ +#define LEUART_IFC_SIGF_DEFAULT (_LEUART_IFC_SIGF_DEFAULT << 10) /* Shifted mode DEFAULT for LEUART_IFC */ + +/* Bit fields for LEUART IEN */ + +#define _LEUART_IEN_RESETVALUE 0x00000000UL /* Default value for LEUART_IEN */ +#define _LEUART_IEN_MASK 0x000007FFUL /* Mask for LEUART_IEN */ + +#define LEUART_IEN_TXC (0x1UL << 0) /* TX Complete Interrupt Enable */ +#define _LEUART_IEN_TXC_SHIFT 0 /* Shift value for LEUART_TXC */ +#define _LEUART_IEN_TXC_MASK 0x1UL /* Bit mask for LEUART_TXC */ +#define _LEUART_IEN_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_TXC_DEFAULT (_LEUART_IEN_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_TXBL (0x1UL << 1) /* TX Buffer Level Interrupt Enable */ +#define _LEUART_IEN_TXBL_SHIFT 1 /* Shift value for LEUART_TXBL */ +#define _LEUART_IEN_TXBL_MASK 0x2UL /* Bit mask for LEUART_TXBL */ +#define _LEUART_IEN_TXBL_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_TXBL_DEFAULT (_LEUART_IEN_TXBL_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXDATAV (0x1UL << 2) /* RX Data Valid Interrupt Enable */ +#define _LEUART_IEN_RXDATAV_SHIFT 2 /* Shift value for LEUART_RXDATAV */ +#define _LEUART_IEN_RXDATAV_MASK 0x4UL /* Bit mask for LEUART_RXDATAV */ +#define _LEUART_IEN_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXDATAV_DEFAULT (_LEUART_IEN_RXDATAV_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXOF (0x1UL << 3) /* RX Overflow Interrupt Enable */ +#define _LEUART_IEN_RXOF_SHIFT 3 /* Shift value for LEUART_RXOF */ +#define _LEUART_IEN_RXOF_MASK 0x8UL /* Bit mask for LEUART_RXOF */ +#define _LEUART_IEN_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXOF_DEFAULT (_LEUART_IEN_RXOF_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXUF (0x1UL << 4) /* RX Underflow Interrupt Enable */ +#define _LEUART_IEN_RXUF_SHIFT 4 /* Shift value for LEUART_RXUF */ +#define _LEUART_IEN_RXUF_MASK 0x10UL /* Bit mask for LEUART_RXUF */ +#define _LEUART_IEN_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_RXUF_DEFAULT (_LEUART_IEN_RXUF_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_TXOF (0x1UL << 5) /* TX Overflow Interrupt Enable */ +#define _LEUART_IEN_TXOF_SHIFT 5 /* Shift value for LEUART_TXOF */ +#define _LEUART_IEN_TXOF_MASK 0x20UL /* Bit mask for LEUART_TXOF */ +#define _LEUART_IEN_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_TXOF_DEFAULT (_LEUART_IEN_TXOF_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_PERR (0x1UL << 6) /* Parity Error Interrupt Enable */ +#define _LEUART_IEN_PERR_SHIFT 6 /* Shift value for LEUART_PERR */ +#define _LEUART_IEN_PERR_MASK 0x40UL /* Bit mask for LEUART_PERR */ +#define _LEUART_IEN_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_PERR_DEFAULT (_LEUART_IEN_PERR_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_FERR (0x1UL << 7) /* Framing Error Interrupt Enable */ +#define _LEUART_IEN_FERR_SHIFT 7 /* Shift value for LEUART_FERR */ +#define _LEUART_IEN_FERR_MASK 0x80UL /* Bit mask for LEUART_FERR */ +#define _LEUART_IEN_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_FERR_DEFAULT (_LEUART_IEN_FERR_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_MPAF (0x1UL << 8) /* Multi-Processor Address Frame Interrupt Enable */ +#define _LEUART_IEN_MPAF_SHIFT 8 /* Shift value for LEUART_MPAF */ +#define _LEUART_IEN_MPAF_MASK 0x100UL /* Bit mask for LEUART_MPAF */ +#define _LEUART_IEN_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_MPAF_DEFAULT (_LEUART_IEN_MPAF_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_STARTF (0x1UL << 9) /* Start Frame Interrupt Enable */ +#define _LEUART_IEN_STARTF_SHIFT 9 /* Shift value for LEUART_STARTF */ +#define _LEUART_IEN_STARTF_MASK 0x200UL /* Bit mask for LEUART_STARTF */ +#define _LEUART_IEN_STARTF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_STARTF_DEFAULT (_LEUART_IEN_STARTF_DEFAULT << 9) /* Shifted mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_SIGF (0x1UL << 10) /* Signal Frame Interrupt Enable */ +#define _LEUART_IEN_SIGF_SHIFT 10 /* Shift value for LEUART_SIGF */ +#define _LEUART_IEN_SIGF_MASK 0x400UL /* Bit mask for LEUART_SIGF */ +#define _LEUART_IEN_SIGF_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_IEN */ +#define LEUART_IEN_SIGF_DEFAULT (_LEUART_IEN_SIGF_DEFAULT << 10) /* Shifted mode DEFAULT for LEUART_IEN */ + +/* Bit fields for LEUART PULSECTRL */ + +#define _LEUART_PULSECTRL_RESETVALUE 0x00000000UL /* Default value for LEUART_PULSECTRL */ +#define _LEUART_PULSECTRL_MASK 0x0000003FUL /* Mask for LEUART_PULSECTRL */ + +#define _LEUART_PULSECTRL_PULSEW_SHIFT 0 /* Shift value for LEUART_PULSEW */ +#define _LEUART_PULSECTRL_PULSEW_MASK 0xFUL /* Bit mask for LEUART_PULSEW */ +#define _LEUART_PULSECTRL_PULSEW_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_PULSECTRL */ +#define LEUART_PULSECTRL_PULSEW_DEFAULT (_LEUART_PULSECTRL_PULSEW_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_PULSECTRL */ +#define LEUART_PULSECTRL_PULSEEN (0x1UL << 4) /* Pulse Generator/Extender Enable */ +#define _LEUART_PULSECTRL_PULSEEN_SHIFT 4 /* Shift value for LEUART_PULSEEN */ +#define _LEUART_PULSECTRL_PULSEEN_MASK 0x10UL /* Bit mask for LEUART_PULSEEN */ +#define _LEUART_PULSECTRL_PULSEEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_PULSECTRL */ +#define LEUART_PULSECTRL_PULSEEN_DEFAULT (_LEUART_PULSECTRL_PULSEEN_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_PULSECTRL */ +#define LEUART_PULSECTRL_PULSEFILT (0x1UL << 5) /* Pulse Filter */ +#define _LEUART_PULSECTRL_PULSEFILT_SHIFT 5 /* Shift value for LEUART_PULSEFILT */ +#define _LEUART_PULSECTRL_PULSEFILT_MASK 0x20UL /* Bit mask for LEUART_PULSEFILT */ +#define _LEUART_PULSECTRL_PULSEFILT_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_PULSECTRL */ +#define LEUART_PULSECTRL_PULSEFILT_DEFAULT (_LEUART_PULSECTRL_PULSEFILT_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_PULSECTRL */ + +/* Bit fields for LEUART FREEZE */ + +#define _LEUART_FREEZE_RESETVALUE 0x00000000UL /* Default value for LEUART_FREEZE */ +#define _LEUART_FREEZE_MASK 0x00000001UL /* Mask for LEUART_FREEZE */ + +#define LEUART_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _LEUART_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for LEUART_REGFREEZE */ +#define _LEUART_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for LEUART_REGFREEZE */ +#define _LEUART_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_FREEZE */ +#define _LEUART_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for LEUART_FREEZE */ +#define _LEUART_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for LEUART_FREEZE */ +#define LEUART_FREEZE_REGFREEZE_DEFAULT (_LEUART_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_FREEZE */ +#define LEUART_FREEZE_REGFREEZE_UPDATE (_LEUART_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for LEUART_FREEZE */ +#define LEUART_FREEZE_REGFREEZE_FREEZE (_LEUART_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for LEUART_FREEZE */ + +/* Bit fields for LEUART SYNCBUSY */ + +#define _LEUART_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for LEUART_SYNCBUSY */ +#define _LEUART_SYNCBUSY_MASK 0x000000FFUL /* Mask for LEUART_SYNCBUSY */ + +#define LEUART_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _LEUART_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for LEUART_CTRL */ +#define _LEUART_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for LEUART_CTRL */ +#define _LEUART_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_CTRL_DEFAULT (_LEUART_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_CMD (0x1UL << 1) /* CMD Register Busy */ +#define _LEUART_SYNCBUSY_CMD_SHIFT 1 /* Shift value for LEUART_CMD */ +#define _LEUART_SYNCBUSY_CMD_MASK 0x2UL /* Bit mask for LEUART_CMD */ +#define _LEUART_SYNCBUSY_CMD_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_CMD_DEFAULT (_LEUART_SYNCBUSY_CMD_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_CLKDIV (0x1UL << 2) /* CLKDIV Register Busy */ +#define _LEUART_SYNCBUSY_CLKDIV_SHIFT 2 /* Shift value for LEUART_CLKDIV */ +#define _LEUART_SYNCBUSY_CLKDIV_MASK 0x4UL /* Bit mask for LEUART_CLKDIV */ +#define _LEUART_SYNCBUSY_CLKDIV_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_CLKDIV_DEFAULT (_LEUART_SYNCBUSY_CLKDIV_DEFAULT << 2) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_STARTFRAME (0x1UL << 3) /* STARTFRAME Register Busy */ +#define _LEUART_SYNCBUSY_STARTFRAME_SHIFT 3 /* Shift value for LEUART_STARTFRAME */ +#define _LEUART_SYNCBUSY_STARTFRAME_MASK 0x8UL /* Bit mask for LEUART_STARTFRAME */ +#define _LEUART_SYNCBUSY_STARTFRAME_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_STARTFRAME_DEFAULT (_LEUART_SYNCBUSY_STARTFRAME_DEFAULT << 3) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_SIGFRAME (0x1UL << 4) /* SIGFRAME Register Busy */ +#define _LEUART_SYNCBUSY_SIGFRAME_SHIFT 4 /* Shift value for LEUART_SIGFRAME */ +#define _LEUART_SYNCBUSY_SIGFRAME_MASK 0x10UL /* Bit mask for LEUART_SIGFRAME */ +#define _LEUART_SYNCBUSY_SIGFRAME_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_SIGFRAME_DEFAULT (_LEUART_SYNCBUSY_SIGFRAME_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_TXDATAX (0x1UL << 5) /* TXDATAX Register Busy */ +#define _LEUART_SYNCBUSY_TXDATAX_SHIFT 5 /* Shift value for LEUART_TXDATAX */ +#define _LEUART_SYNCBUSY_TXDATAX_MASK 0x20UL /* Bit mask for LEUART_TXDATAX */ +#define _LEUART_SYNCBUSY_TXDATAX_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_TXDATAX_DEFAULT (_LEUART_SYNCBUSY_TXDATAX_DEFAULT << 5) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_TXDATA (0x1UL << 6) /* TXDATA Register Busy */ +#define _LEUART_SYNCBUSY_TXDATA_SHIFT 6 /* Shift value for LEUART_TXDATA */ +#define _LEUART_SYNCBUSY_TXDATA_MASK 0x40UL /* Bit mask for LEUART_TXDATA */ +#define _LEUART_SYNCBUSY_TXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_TXDATA_DEFAULT (_LEUART_SYNCBUSY_TXDATA_DEFAULT << 6) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_PULSECTRL (0x1UL << 7) /* PULSECTRL Register Busy */ +#define _LEUART_SYNCBUSY_PULSECTRL_SHIFT 7 /* Shift value for LEUART_PULSECTRL */ +#define _LEUART_SYNCBUSY_PULSECTRL_MASK 0x80UL /* Bit mask for LEUART_PULSECTRL */ +#define _LEUART_SYNCBUSY_PULSECTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_SYNCBUSY */ +#define LEUART_SYNCBUSY_PULSECTRL_DEFAULT (_LEUART_SYNCBUSY_PULSECTRL_DEFAULT << 7) /* Shifted mode DEFAULT for LEUART_SYNCBUSY */ + +/* Bit fields for LEUART ROUTE */ + +#define _LEUART_ROUTE_RESETVALUE 0x00000000UL /* Default value for LEUART_ROUTE */ +#define _LEUART_ROUTE_MASK 0x00000703UL /* Mask for LEUART_ROUTE */ + +#define LEUART_ROUTE_RXPEN (0x1UL << 0) /* RX Pin Enable */ +#define _LEUART_ROUTE_RXPEN_SHIFT 0 /* Shift value for LEUART_RXPEN */ +#define _LEUART_ROUTE_RXPEN_MASK 0x1UL /* Bit mask for LEUART_RXPEN */ +#define _LEUART_ROUTE_RXPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_ROUTE */ +#define LEUART_ROUTE_RXPEN_DEFAULT (_LEUART_ROUTE_RXPEN_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_ROUTE */ +#define LEUART_ROUTE_TXPEN (0x1UL << 1) /* TX Pin Enable */ +#define _LEUART_ROUTE_TXPEN_SHIFT 1 /* Shift value for LEUART_TXPEN */ +#define _LEUART_ROUTE_TXPEN_MASK 0x2UL /* Bit mask for LEUART_TXPEN */ +#define _LEUART_ROUTE_TXPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_ROUTE */ +#define LEUART_ROUTE_TXPEN_DEFAULT (_LEUART_ROUTE_TXPEN_DEFAULT << 1) /* Shifted mode DEFAULT for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_SHIFT 8 /* Shift value for LEUART_LOCATION */ +#define _LEUART_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for LEUART_LOCATION */ +#define _LEUART_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for LEUART_ROUTE */ +#define _LEUART_ROUTE_LOCATION_LOC4 0x00000004UL /* Mode LOC4 for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_LOC0 (_LEUART_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_DEFAULT (_LEUART_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_LOC1 (_LEUART_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_LOC2 (_LEUART_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_LOC3 (_LEUART_ROUTE_LOCATION_LOC3 << 8) /* Shifted mode LOC3 for LEUART_ROUTE */ +#define LEUART_ROUTE_LOCATION_LOC4 (_LEUART_ROUTE_LOCATION_LOC4 << 8) /* Shifted mode LOC4 for LEUART_ROUTE */ + +/* Bit fields for LEUART INPUT */ + +#ifdef CONFIG_EFM32_EFM32GG +# define _LEUART_INPUT_RESETVALUE 0x00000000UL /* Default value for LEUART_INPUT */ +# define _LEUART_INPUT_MASK 0x0000001FUL /* Mask for LEUART_INPUT */ + +# define _LEUART_INPUT_RXPRSSEL_SHIFT 0 /* Shift value for LEUART_RXPRSSEL */ +# define _LEUART_INPUT_RXPRSSEL_MASK 0xFUL /* Bit mask for LEUART_RXPRSSEL */ +# define _LEUART_INPUT_RXPRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for LEUART_INPUT */ +# define _LEUART_INPUT_RXPRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_DEFAULT (_LEUART_INPUT_RXPRSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH0 (_LEUART_INPUT_RXPRSSEL_PRSCH0 << 0) /* Shifted mode PRSCH0 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH1 (_LEUART_INPUT_RXPRSSEL_PRSCH1 << 0) /* Shifted mode PRSCH1 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH2 (_LEUART_INPUT_RXPRSSEL_PRSCH2 << 0) /* Shifted mode PRSCH2 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH3 (_LEUART_INPUT_RXPRSSEL_PRSCH3 << 0) /* Shifted mode PRSCH3 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH4 (_LEUART_INPUT_RXPRSSEL_PRSCH4 << 0) /* Shifted mode PRSCH4 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH5 (_LEUART_INPUT_RXPRSSEL_PRSCH5 << 0) /* Shifted mode PRSCH5 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH6 (_LEUART_INPUT_RXPRSSEL_PRSCH6 << 0) /* Shifted mode PRSCH6 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH7 (_LEUART_INPUT_RXPRSSEL_PRSCH7 << 0) /* Shifted mode PRSCH7 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH8 (_LEUART_INPUT_RXPRSSEL_PRSCH8 << 0) /* Shifted mode PRSCH8 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH9 (_LEUART_INPUT_RXPRSSEL_PRSCH9 << 0) /* Shifted mode PRSCH9 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH10 (_LEUART_INPUT_RXPRSSEL_PRSCH10 << 0) /* Shifted mode PRSCH10 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRSSEL_PRSCH11 (_LEUART_INPUT_RXPRSSEL_PRSCH11 << 0) /* Shifted mode PRSCH11 for LEUART_INPUT */ +# define LEUART_INPUT_RXPRS (0x1UL << 4) /* PRS RX Enable */ +# define _LEUART_INPUT_RXPRS_SHIFT 4 /* Shift value for LEUART_RXPRS */ +# define _LEUART_INPUT_RXPRS_MASK 0x10UL /* Bit mask for LEUART_RXPRS */ +# define _LEUART_INPUT_RXPRS_DEFAULT 0x00000000UL /* Mode DEFAULT for LEUART_INPUT */ +# define LEUART_INPUT_RXPRS_DEFAULT (_LEUART_INPUT_RXPRS_DEFAULT << 4) /* Shifted mode DEFAULT for LEUART_INPUT */ +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_LEUART_H */ diff --git a/arch/arm/src/efm32/chip/efm32_memorymap.h b/arch/arm/src/efm32/chip/efm32_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..62e0a24f82003e4de4299410f03f839ac20b501c --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_memorymap.h @@ -0,0 +1,56 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip/efm32_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_MEMORYMAP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_EFM32_EFM32TG) +# include "chip/efm32tg_memorymap.h" +#elif defined(CONFIG_EFM32_EFM32G) +# include "chip/efm32g_memorymap.h" +#elif defined(CONFIG_EFM32_EFM32GG) +# include "chip/efm32gg_memorymap.h" +#else +# error "Unsupported EFM32 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_MEMORYMAP_H */ diff --git a/arch/arm/src/efm32/chip/efm32_msc.h b/arch/arm/src/efm32/chip/efm32_msc.h new file mode 100644 index 0000000000000000000000000000000000000000..27b806743ca4a74563916ab8a0b95e6fc62b77b6 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_msc.h @@ -0,0 +1,637 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_msc.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_EFM32_MSC_H +#define __ARCH_ARM_SRC_EFM32_EFM32_EFM32_MSC_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include "chip/efm32_memorymap.h" + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +/* MSC Register Offsets ********************************************************************************************************/ + +#define EFM32_MSC_CTRL_OFFSET 0x0000 /* Memory System Control Register */ +#define EFM32_MSC_READCTRL_OFFSET 0x0004 /* Read Control Register */ +#define EFM32_MSC_WRITECTRL_OFFSET 0x0008 /* Write Control Register */ +#define EFM32_MSC_WRITECMD_OFFSET 0x000c /* Write Command Register */ +#define EFM32_MSC_ADDRB_OFFSET 0x0010 /* Page Erase/Write Address Buffer */ +#define EFM32_MSC_WDATA_OFFSET 0x0018 /* Write Data Register */ +#define EFM32_MSC_STATUS_OFFSET 0x001c /* Status Register */ +#define EFM32_MSC_IF_OFFSET 0x002c /* Interrupt Flag Register */ +#define EFM32_MSC_IFS_OFFSET 0x0030 /* Interrupt Flag Set Register */ +#define EFM32_MSC_IFC_OFFSET 0x0034 /* Interrupt Flag Clear Register */ +#define EFM32_MSC_IEN_OFFSET 0x0038 /* Interrupt Enable Register */ +#define EFM32_MSC_LOCK_OFFSET 0x003c /* Configuration Lock Register */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_MSC_CMD_OFFSET 0x0040 /* Command Register */ +# define EFM32_MSC_CACHEHITS_OFFSET 0x0044 /* Cache Hits Performance Counter */ +# define EFM32_MSC_CACHEMISSES_OFFSET 0x0048 /* Cache Misses Performance Counter */ +# define EFM32_MSC_TIMEBASE_OFFSET 0x0050 /* Flash Write and Erase Timebase */ +# define EFM32_MSC_MASSLOCK_OFFSET 0x0054 /* Mass Erase Lock Register */ +#endif + +/* MSC Register Addresses ******************************************************************************************************/ + +#define EFM32_MSC_CTRL (EFM32_MSC_BASE+EFM32_MSC_CTRL_OFFSET) +#define EFM32_MSC_READCTRL (EFM32_MSC_BASE+EFM32_MSC_READCTRL_OFFSET) +#define EFM32_MSC_WRITECTRL (EFM32_MSC_BASE+EFM32_MSC_WRITECTRL_OFFSET) +#define EFM32_MSC_WRITECMD (EFM32_MSC_BASE+EFM32_MSC_WRITECMD_OFFSET) +#define EFM32_MSC_ADDRB (EFM32_MSC_BASE+EFM32_MSC_ADDRB_OFFSET) +#define EFM32_MSC_WDATA (EFM32_MSC_BASE+EFM32_MSC_WDATA_OFFSET) +#define EFM32_MSC_STATUS (EFM32_MSC_BASE+EFM32_MSC_STATUS_OFFSET) +#define EFM32_MSC_IF (EFM32_MSC_BASE+EFM32_MSC_IF_OFFSET) +#define EFM32_MSC_IFS (EFM32_MSC_BASE+EFM32_MSC_IFS_OFFSET) +#define EFM32_MSC_IFC (EFM32_MSC_BASE+EFM32_MSC_IFC_OFFSET) +#define EFM32_MSC_IEN (EFM32_MSC_BASE+EFM32_MSC_IEN_OFFSET) +#define EFM32_MSC_LOCK (EFM32_MSC_BASE+EFM32_MSC_LOCK_OFFSET) + +#if defined(CONFIG_EFM32_EFM32GG) +# define EFM32_MSC_CMD (EFM32_MSC_BASE+EFM32_MSC_CMD_OFFSET) +# define EFM32_MSC_CACHEHITS (EFM32_MSC_BASE+EFM32_MSC_CACHEHITS_OFFSET) +# define EFM32_MSC_CACHEMISSES (EFM32_MSC_BASE+EFM32_MSC_CACHEMISSES_OFFSET) +# define EFM32_MSC_TIMEBASE (EFM32_MSC_BASE+EFM32_MSC_TIMEBASE_OFFSET) +# define EFM32_MSC_MASSLOCK (EFM32_MSC_BASE+EFM32_MSC_MASSLOCK_OFFSET) +#endif + +/* MSC Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for MSC CTRL */ + +#define _MSC_CTRL_RESETVALUE 0x00000001UL /* Default value for MSC_CTRL */ +#define _MSC_CTRL_MASK 0x00000001UL /* Mask for MSC_CTRL */ + +#define MSC_CTRL_BUSFAULT (0x1UL << 0) /* Bus Fault Response Enable */ +#define _MSC_CTRL_BUSFAULT_SHIFT 0 /* Shift value for MSC_BUSFAULT */ +#define _MSC_CTRL_BUSFAULT_MASK 0x1UL /* Bit mask for MSC_BUSFAULT */ +#define _MSC_CTRL_BUSFAULT_GENERATE 0x00000000UL /* Mode GENERATE for MSC_CTRL */ +#define _MSC_CTRL_BUSFAULT_DEFAULT 0x00000001UL /* Mode DEFAULT for MSC_CTRL */ +#define _MSC_CTRL_BUSFAULT_IGNORE 0x00000001UL /* Mode IGNORE for MSC_CTRL */ +#define MSC_CTRL_BUSFAULT_GENERATE (_MSC_CTRL_BUSFAULT_GENERATE << 0) /* Shifted mode GENERATE for MSC_CTRL */ +#define MSC_CTRL_BUSFAULT_DEFAULT (_MSC_CTRL_BUSFAULT_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_CTRL */ +#define MSC_CTRL_BUSFAULT_IGNORE (_MSC_CTRL_BUSFAULT_IGNORE << 0) /* Shifted mode IGNORE for MSC_CTRL */ + +/* Bit fields for MSC READCTRL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_READCTRL_RESETVALUE 0x00000001UL /* Default value for MSC_READCTRL */ +# define _MSC_READCTRL_MASK 0x000301FFUL /* Mask for MSC_READCTRL */ +#else +# define _MSC_READCTRL_RESETVALUE 0x00000001UL /* Default value for MSC_READCTRL */ +# define _MSC_READCTRL_MASK 0x00000001UL /* Mask for MSC_READCTRL */ +#endif + +#define _MSC_READCTRL_MODE_SHIFT 0 /* Shift value for MSC_MODE */ +#define _MSC_READCTRL_MODE_MASK 0x7UL /* Bit mask for MSC_MODE */ +#define _MSC_READCTRL_MODE_WS0 0x00000000UL /* Mode WS0 for MSC_READCTRL */ +#define _MSC_READCTRL_MODE_DEFAULT 0x00000001UL /* Mode DEFAULT for MSC_READCTRL */ +#define _MSC_READCTRL_MODE_WS1 0x00000001UL /* Mode WS1 for MSC_READCTRL */ +#define _MSC_READCTRL_MODE_WS0SCBTP 0x00000002UL /* Mode WS0SCBTP for MSC_READCTRL */ +#define _MSC_READCTRL_MODE_WS1SCBTP 0x00000003UL /* Mode WS1SCBTP for MSC_READCTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_READCTRL_MODE_WS2 0x00000004UL /* Mode WS2 for MSC_READCTRL */ +# define _MSC_READCTRL_MODE_WS2SCBTP 0x00000005UL /* Mode WS2SCBTP for MSC_READCTRL */ +# define _MSC_READCTRL_MODE_WSMAX _MSC_READCTRL_MODE_WS2 /* Max wait state setting (without SCBTP) */ +# define _MSC_READCTRL_MODE_WSMAXSCBTP _MSC_READCTRL_MODE_WS2SCBTP /* Max wait state setting (with SCBTP) */ +#else +# define _MSC_READCTRL_MODE_WSMAX _MSC_READCTRL_MODE_WS1 /* Max wait state setting (without SCBTP) */ +# define _MSC_READCTRL_MODE_WSMAXSCBTP _MSC_READCTRL_MODE_WS1SCBTP /* Max wait state setting (with SCBTP) */ +#endif +#define MSC_READCTRL_MODE_WS0 (_MSC_READCTRL_MODE_WS0 << 0) /* Shifted mode WS0 for MSC_READCTRL */ +#define MSC_READCTRL_MODE_DEFAULT (_MSC_READCTRL_MODE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_READCTRL */ +#define MSC_READCTRL_MODE_WS1 (_MSC_READCTRL_MODE_WS1 << 0) /* Shifted mode WS1 for MSC_READCTRL */ +#define MSC_READCTRL_MODE_WS0SCBTP (_MSC_READCTRL_MODE_WS0SCBTP << 0) /* Shifted mode WS0SCBTP for MSC_READCTRL */ +#define MSC_READCTRL_MODE_WS1SCBTP (_MSC_READCTRL_MODE_WS1SCBTP << 0) /* Shifted mode WS1SCBTP for MSC_READCTRL */ +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_READCTRL_MODE_WS2 (_MSC_READCTRL_MODE_WS2 << 0) /* Shifted mode WS2 for MSC_READCTRL */ +# define MSC_READCTRL_MODE_WS2SCBTP (_MSC_READCTRL_MODE_WS2SCBTP << 0) /* Shifted mode WS2SCBTP for MSC_READCTRL */ +#endif +#define MSC_READCTRL_MODE_WSMAX (_MSC_READCTRL_MODE_WSMAX << 0) /* Max wait state setting (without SCBTP) */ +#define MSC_READCTRL_MODE_WSMAXSCBTP (_MSC_READCTRL_MODE_WSMAXSCBTP << 0) /* Max wait state setting (with SCBTP) */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_READCTRL_IFCDIS (0x1UL << 3) /* Internal Flash Cache Disable */ +# define _MSC_READCTRL_IFCDIS_SHIFT 3 /* Shift value for MSC_IFCDIS */ +# define _MSC_READCTRL_IFCDIS_MASK 0x8UL /* Bit mask for MSC_IFCDIS */ +# define _MSC_READCTRL_IFCDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_IFCDIS_DEFAULT (_MSC_READCTRL_IFCDIS_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_AIDIS (0x1UL << 4) /* Automatic Invalidate Disable */ +# define _MSC_READCTRL_AIDIS_SHIFT 4 /* Shift value for MSC_AIDIS */ +# define _MSC_READCTRL_AIDIS_MASK 0x10UL /* Bit mask for MSC_AIDIS */ +# define _MSC_READCTRL_AIDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_AIDIS_DEFAULT (_MSC_READCTRL_AIDIS_DEFAULT << 4) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_ICCDIS (0x1UL << 5) /* Interrupt Context Cache Disable */ +# define _MSC_READCTRL_ICCDIS_SHIFT 5 /* Shift value for MSC_ICCDIS */ +# define _MSC_READCTRL_ICCDIS_MASK 0x20UL /* Bit mask for MSC_ICCDIS */ +# define _MSC_READCTRL_ICCDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_ICCDIS_DEFAULT (_MSC_READCTRL_ICCDIS_DEFAULT << 5) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_EBICDIS (0x1UL << 6) /* External Bus Interface Cache Disable */ +# define _MSC_READCTRL_EBICDIS_SHIFT 6 /* Shift value for MSC_EBICDIS */ +# define _MSC_READCTRL_EBICDIS_MASK 0x40UL /* Bit mask for MSC_EBICDIS */ +# define _MSC_READCTRL_EBICDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_EBICDIS_DEFAULT (_MSC_READCTRL_EBICDIS_DEFAULT << 6) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_RAMCEN (0x1UL << 7) /* RAM Cache Enable */ +# define _MSC_READCTRL_RAMCEN_SHIFT 7 /* Shift value for MSC_RAMCEN */ +# define _MSC_READCTRL_RAMCEN_MASK 0x80UL /* Bit mask for MSC_RAMCEN */ +# define _MSC_READCTRL_RAMCEN_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_RAMCEN_DEFAULT (_MSC_READCTRL_RAMCEN_DEFAULT << 7) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_PREFETCH (0x1UL << 8) /* Prefetch Mode */ +# define _MSC_READCTRL_PREFETCH_SHIFT 8 /* Shift value for MSC_PREFETCH */ +# define _MSC_READCTRL_PREFETCH_MASK 0x100UL /* Bit mask for MSC_PREFETCH */ +# define _MSC_READCTRL_PREFETCH_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_PREFETCH_DEFAULT (_MSC_READCTRL_PREFETCH_DEFAULT << 8) /* Shifted mode DEFAULT for MSC_READCTRL */ + +# define _MSC_READCTRL_BUSSTRATEGY_SHIFT 16 /* Shift value for MSC_BUSSTRATEGY */ +# define _MSC_READCTRL_BUSSTRATEGY_MASK 0x30000UL /* Bit mask for MSC_BUSSTRATEGY */ +# define _MSC_READCTRL_BUSSTRATEGY_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_READCTRL */ +# define _MSC_READCTRL_BUSSTRATEGY_CPU 0x00000000UL /* Mode CPU for MSC_READCTRL */ +# define _MSC_READCTRL_BUSSTRATEGY_DMA 0x00000001UL /* Mode DMA for MSC_READCTRL */ +# define _MSC_READCTRL_BUSSTRATEGY_DMAEM1 0x00000002UL /* Mode DMAEM1 for MSC_READCTRL */ +# define _MSC_READCTRL_BUSSTRATEGY_NONE 0x00000003UL /* Mode NONE for MSC_READCTRL */ +# define MSC_READCTRL_BUSSTRATEGY_DEFAULT (_MSC_READCTRL_BUSSTRATEGY_DEFAULT << 16) /* Shifted mode DEFAULT for MSC_READCTRL */ +# define MSC_READCTRL_BUSSTRATEGY_CPU (_MSC_READCTRL_BUSSTRATEGY_CPU << 16) /* Shifted mode CPU for MSC_READCTRL */ +# define MSC_READCTRL_BUSSTRATEGY_DMA (_MSC_READCTRL_BUSSTRATEGY_DMA << 16) /* Shifted mode DMA for MSC_READCTRL */ +# define MSC_READCTRL_BUSSTRATEGY_DMAEM1 (_MSC_READCTRL_BUSSTRATEGY_DMAEM1 << 16) /* Shifted mode DMAEM1 for MSC_READCTRL */ +# define MSC_READCTRL_BUSSTRATEGY_NONE (_MSC_READCTRL_BUSSTRATEGY_NONE << 16) /* Shifted mode NONE for MSC_READCTRL */ +#endif + +/* Bit fields for MSC WRITECTRL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_WRITECTRL_RESETVALUE 0x00000000UL /* Default value for MSC_WRITECTRL */ +# define _MSC_WRITECTRL_MASK 0x0000003FUL /* Mask for MSC_WRITECTRL */ +#else +# define _MSC_WRITECTRL_RESETVALUE 0x00000000UL /* Default value for MSC_WRITECTRL */ +# define _MSC_WRITECTRL_MASK 0x00000003UL /* Mask for MSC_WRITECTRL */ +#endif + +#define MSC_WRITECTRL_WREN (0x1UL << 0) /* Enable Write/Erase Controller */ +#define _MSC_WRITECTRL_WREN_SHIFT 0 /* Shift value for MSC_WREN */ +#define _MSC_WRITECTRL_WREN_MASK 0x1UL /* Bit mask for MSC_WREN */ +#define _MSC_WRITECTRL_WREN_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +#define MSC_WRITECTRL_WREN_DEFAULT (_MSC_WRITECTRL_WREN_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_WRITECTRL */ +#define MSC_WRITECTRL_IRQERASEABORT (0x1UL << 1) /* Abort Page Erase on Interrupt */ +#define _MSC_WRITECTRL_IRQERASEABORT_SHIFT 1 /* Shift value for MSC_IRQERASEABORT */ +#define _MSC_WRITECTRL_IRQERASEABORT_MASK 0x2UL /* Bit mask for MSC_IRQERASEABORT */ +#define _MSC_WRITECTRL_IRQERASEABORT_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +#define MSC_WRITECTRL_IRQERASEABORT_DEFAULT (_MSC_WRITECTRL_IRQERASEABORT_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_WRITECTRL */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_WRITECTRL_WDOUBLE (0x1UL << 2) /* Write two words at a time */ +# define _MSC_WRITECTRL_WDOUBLE_SHIFT 2 /* Shift value for MSC_WDOUBLE */ +# define _MSC_WRITECTRL_WDOUBLE_MASK 0x4UL /* Bit mask for MSC_WDOUBLE */ +# define _MSC_WRITECTRL_WDOUBLE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_WDOUBLE_DEFAULT (_MSC_WRITECTRL_WDOUBLE_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_LPWRITE (0x1UL << 3) /* Low-Power Erase */ +# define _MSC_WRITECTRL_LPWRITE_SHIFT 3 /* Shift value for MSC_LPWRITE */ +# define _MSC_WRITECTRL_LPWRITE_MASK 0x8UL /* Bit mask for MSC_LPWRITE */ +# define _MSC_WRITECTRL_LPWRITE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_LPWRITE_DEFAULT (_MSC_WRITECTRL_LPWRITE_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_LPERASE (0x1UL << 4) /* Low-Power Erase */ +# define _MSC_WRITECTRL_LPERASE_SHIFT 4 /* Shift value for MSC_LPERASE */ +# define _MSC_WRITECTRL_LPERASE_MASK 0x10UL /* Bit mask for MSC_LPERASE */ +# define _MSC_WRITECTRL_LPERASE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_LPERASE_DEFAULT (_MSC_WRITECTRL_LPERASE_DEFAULT << 4) /* Shifted mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_RWWEN (0x1UL << 5) /* Read-While-Write Enable */ +# define _MSC_WRITECTRL_RWWEN_SHIFT 5 /* Shift value for MSC_RWWEN */ +# define _MSC_WRITECTRL_RWWEN_MASK 0x20UL /* Bit mask for MSC_RWWEN */ +# define _MSC_WRITECTRL_RWWEN_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECTRL */ +# define MSC_WRITECTRL_RWWEN_DEFAULT (_MSC_WRITECTRL_RWWEN_DEFAULT << 5) /* Shifted mode DEFAULT for MSC_WRITECTRL */ +#endif + +/* Bit fields for MSC WRITECMD */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_WRITECMD_RESETVALUE 0x00000000UL /* Default value for MSC_WRITECMD */ +# define _MSC_WRITECMD_MASK 0x0000133FUL /* Mask for MSC_WRITECMD */ +#else +# define _MSC_WRITECMD_RESETVALUE 0x00000000UL /* Default value for MSC_WRITECMD */ +# define _MSC_WRITECMD_MASK 0x0000001FUL /* Mask for MSC_WRITECMD */ +#endif + +#define MSC_WRITECMD_LADDRIM (0x1UL << 0) /* Load MSC_ADDRB into ADDR */ +#define _MSC_WRITECMD_LADDRIM_SHIFT 0 /* Shift value for MSC_LADDRIM */ +#define _MSC_WRITECMD_LADDRIM_MASK 0x1UL /* Bit mask for MSC_LADDRIM */ +#define _MSC_WRITECMD_LADDRIM_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_LADDRIM_DEFAULT (_MSC_WRITECMD_LADDRIM_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_ERASEPAGE (0x1UL << 1) /* Erase Page */ +#define _MSC_WRITECMD_ERASEPAGE_SHIFT 1 /* Shift value for MSC_ERASEPAGE */ +#define _MSC_WRITECMD_ERASEPAGE_MASK 0x2UL /* Bit mask for MSC_ERASEPAGE */ +#define _MSC_WRITECMD_ERASEPAGE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_ERASEPAGE_DEFAULT (_MSC_WRITECMD_ERASEPAGE_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITEEND (0x1UL << 2) /* End Write Mode */ +#define _MSC_WRITECMD_WRITEEND_SHIFT 2 /* Shift value for MSC_WRITEEND */ +#define _MSC_WRITECMD_WRITEEND_MASK 0x4UL /* Bit mask for MSC_WRITEEND */ +#define _MSC_WRITECMD_WRITEEND_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITEEND_DEFAULT (_MSC_WRITECMD_WRITEEND_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITEONCE (0x1UL << 3) /* Word Write-Once Trigger */ +#define _MSC_WRITECMD_WRITEONCE_SHIFT 3 /* Shift value for MSC_WRITEONCE */ +#define _MSC_WRITECMD_WRITEONCE_MASK 0x8UL /* Bit mask for MSC_WRITEONCE */ +#define _MSC_WRITECMD_WRITEONCE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITEONCE_DEFAULT (_MSC_WRITECMD_WRITEONCE_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITETRIG (0x1UL << 4) /* Word Write Sequence Trigger */ +#define _MSC_WRITECMD_WRITETRIG_SHIFT 4 /* Shift value for MSC_WRITETRIG */ +#define _MSC_WRITECMD_WRITETRIG_MASK 0x10UL /* Bit mask for MSC_WRITETRIG */ +#define _MSC_WRITECMD_WRITETRIG_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +#define MSC_WRITECMD_WRITETRIG_DEFAULT (_MSC_WRITECMD_WRITETRIG_DEFAULT << 4) /* Shifted mode DEFAULT for MSC_WRITECMD */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_WRITECMD_ERASEABORT (0x1UL << 5) /* Abort erase sequence */ +# define _MSC_WRITECMD_ERASEABORT_SHIFT 5 /* Shift value for MSC_ERASEABORT */ +# define _MSC_WRITECMD_ERASEABORT_MASK 0x20UL /* Bit mask for MSC_ERASEABORT */ +# define _MSC_WRITECMD_ERASEABORT_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_ERASEABORT_DEFAULT (_MSC_WRITECMD_ERASEABORT_DEFAULT << 5) /* Shifted mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_ERASEMAIN0 (0x1UL << 8) /* Mass erase region 0 */ +# define _MSC_WRITECMD_ERASEMAIN0_SHIFT 8 /* Shift value for MSC_ERASEMAIN0 */ +# define _MSC_WRITECMD_ERASEMAIN0_MASK 0x100UL /* Bit mask for MSC_ERASEMAIN0 */ +# define _MSC_WRITECMD_ERASEMAIN0_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_ERASEMAIN0_DEFAULT (_MSC_WRITECMD_ERASEMAIN0_DEFAULT << 8) /* Shifted mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_ERASEMAIN1 (0x1UL << 9) /* Mass erase region 1 */ +# define _MSC_WRITECMD_ERASEMAIN1_SHIFT 9 /* Shift value for MSC_ERASEMAIN1 */ +# define _MSC_WRITECMD_ERASEMAIN1_MASK 0x200UL /* Bit mask for MSC_ERASEMAIN1 */ +# define _MSC_WRITECMD_ERASEMAIN1_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_ERASEMAIN1_DEFAULT (_MSC_WRITECMD_ERASEMAIN1_DEFAULT << 9) /* Shifted mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_CLEARWDATA (0x1UL << 12) /* Clear WDATA state */ +# define _MSC_WRITECMD_CLEARWDATA_SHIFT 12 /* Shift value for MSC_CLEARWDATA */ +# define _MSC_WRITECMD_CLEARWDATA_MASK 0x1000UL /* Bit mask for MSC_CLEARWDATA */ +# define _MSC_WRITECMD_CLEARWDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WRITECMD */ +# define MSC_WRITECMD_CLEARWDATA_DEFAULT (_MSC_WRITECMD_CLEARWDATA_DEFAULT << 12) /* Shifted mode DEFAULT for MSC_WRITECMD */ +#endif + +/* Bit fields for MSC ADDRB */ + +#define _MSC_ADDRB_RESETVALUE 0x00000000UL /* Default value for MSC_ADDRB */ +#define _MSC_ADDRB_MASK 0xFFFFFFFFUL /* Mask for MSC_ADDRB */ + +#define _MSC_ADDRB_ADDRB_SHIFT 0 /* Shift value for MSC_ADDRB */ +#define _MSC_ADDRB_ADDRB_MASK 0xFFFFFFFFUL /* Bit mask for MSC_ADDRB */ +#define _MSC_ADDRB_ADDRB_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_ADDRB */ +#define MSC_ADDRB_ADDRB_DEFAULT (_MSC_ADDRB_ADDRB_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_ADDRB */ + +/* Bit fields for MSC WDATA */ + +#define _MSC_WDATA_RESETVALUE 0x00000000UL /* Default value for MSC_WDATA */ +#define _MSC_WDATA_MASK 0xFFFFFFFFUL /* Mask for MSC_WDATA */ + +#define _MSC_WDATA_WDATA_SHIFT 0 /* Shift value for MSC_WDATA */ +#define _MSC_WDATA_WDATA_MASK 0xFFFFFFFFUL /* Bit mask for MSC_WDATA */ +#define _MSC_WDATA_WDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_WDATA */ +#define MSC_WDATA_WDATA_DEFAULT (_MSC_WDATA_WDATA_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_WDATA */ + +/* Bit fields for MSC STATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_STATUS_RESETVALUE 0x00000008UL /* Default value for MSC_STATUS */ +# define _MSC_STATUS_MASK 0x0000007FUL /* Mask for MSC_STATUS */ +#else +# define _MSC_STATUS_RESETVALUE 0x00000008UL /* Default value for MSC_STATUS */ +# define _MSC_STATUS_MASK 0x0000003FUL /* Mask for MSC_STATUS */ +#endif + +#define MSC_STATUS_BUSY (0x1UL << 0) /* Erase/Write Busy */ +#define _MSC_STATUS_BUSY_SHIFT 0 /* Shift value for MSC_BUSY */ +#define _MSC_STATUS_BUSY_MASK 0x1UL /* Bit mask for MSC_BUSY */ +#define _MSC_STATUS_BUSY_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_BUSY_DEFAULT (_MSC_STATUS_BUSY_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_LOCKED (0x1UL << 1) /* Access Locked */ +#define _MSC_STATUS_LOCKED_SHIFT 1 /* Shift value for MSC_LOCKED */ +#define _MSC_STATUS_LOCKED_MASK 0x2UL /* Bit mask for MSC_LOCKED */ +#define _MSC_STATUS_LOCKED_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_LOCKED_DEFAULT (_MSC_STATUS_LOCKED_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_INVADDR (0x1UL << 2) /* Invalid Write Address or Erase Page */ +#define _MSC_STATUS_INVADDR_SHIFT 2 /* Shift value for MSC_INVADDR */ +#define _MSC_STATUS_INVADDR_MASK 0x4UL /* Bit mask for MSC_INVADDR */ +#define _MSC_STATUS_INVADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_INVADDR_DEFAULT (_MSC_STATUS_INVADDR_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_WDATAREADY (0x1UL << 3) /* WDATA Write Ready */ +#define _MSC_STATUS_WDATAREADY_SHIFT 3 /* Shift value for MSC_WDATAREADY */ +#define _MSC_STATUS_WDATAREADY_MASK 0x8UL /* Bit mask for MSC_WDATAREADY */ +#define _MSC_STATUS_WDATAREADY_DEFAULT 0x00000001UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_WDATAREADY_DEFAULT (_MSC_STATUS_WDATAREADY_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_WORDTIMEOUT (0x1UL << 4) /* Flash Write Word Timeout */ +#define _MSC_STATUS_WORDTIMEOUT_SHIFT 4 /* Shift value for MSC_WORDTIMEOUT */ +#define _MSC_STATUS_WORDTIMEOUT_MASK 0x10UL /* Bit mask for MSC_WORDTIMEOUT */ +#define _MSC_STATUS_WORDTIMEOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_WORDTIMEOUT_DEFAULT (_MSC_STATUS_WORDTIMEOUT_DEFAULT << 4) /* Shifted mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_ERASEABORTED (0x1UL << 5) /* The Current Flash Erase Operation Aborted */ +#define _MSC_STATUS_ERASEABORTED_SHIFT 5 /* Shift value for MSC_ERASEABORTED */ +#define _MSC_STATUS_ERASEABORTED_MASK 0x20UL /* Bit mask for MSC_ERASEABORTED */ +#define _MSC_STATUS_ERASEABORTED_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +#define MSC_STATUS_ERASEABORTED_DEFAULT (_MSC_STATUS_ERASEABORTED_DEFAULT << 5) /* Shifted mode DEFAULT for MSC_STATUS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_STATUS_PCRUNNING (0x1UL << 6) /* Performance Counters Running */ +# define _MSC_STATUS_PCRUNNING_SHIFT 6 /* Shift value for MSC_PCRUNNING */ +# define _MSC_STATUS_PCRUNNING_MASK 0x40UL /* Bit mask for MSC_PCRUNNING */ +# define _MSC_STATUS_PCRUNNING_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_STATUS */ +# define MSC_STATUS_PCRUNNING_DEFAULT (_MSC_STATUS_PCRUNNING_DEFAULT << 6) /* Shifted mode DEFAULT for MSC_STATUS */ +#endif + +/* Bit fields for MSC IF */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_IF_RESETVALUE 0x00000000UL /* Default value for MSC_IF */ +# define _MSC_IF_MASK 0x0000000FUL /* Mask for MSC_IF */ +#else +# define _MSC_IF_RESETVALUE 0x00000000UL /* Default value for MSC_IF */ +# define _MSC_IF_MASK 0x00000003UL /* Mask for MSC_IF */ +#endif + +#define MSC_IF_ERASE (0x1UL << 0) /* Erase Done Interrupt Read Flag */ +#define _MSC_IF_ERASE_SHIFT 0 /* Shift value for MSC_ERASE */ +#define _MSC_IF_ERASE_MASK 0x1UL /* Bit mask for MSC_ERASE */ +#define _MSC_IF_ERASE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IF */ +#define MSC_IF_ERASE_DEFAULT (_MSC_IF_ERASE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_IF */ +#define MSC_IF_WRITE (0x1UL << 1) /* Write Done Interrupt Read Flag */ +#define _MSC_IF_WRITE_SHIFT 1 /* Shift value for MSC_WRITE */ +#define _MSC_IF_WRITE_MASK 0x2UL /* Bit mask for MSC_WRITE */ +#define _MSC_IF_WRITE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IF */ +#define MSC_IF_WRITE_DEFAULT (_MSC_IF_WRITE_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_IF */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_IF_CHOF (0x1UL << 2) /* Cache Hits Overflow Interrupt Flag */ +# define _MSC_IF_CHOF_SHIFT 2 /* Shift value for MSC_CHOF */ +# define _MSC_IF_CHOF_MASK 0x4UL /* Bit mask for MSC_CHOF */ +# define _MSC_IF_CHOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IF */ +# define MSC_IF_CHOF_DEFAULT (_MSC_IF_CHOF_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_IF */ +# define MSC_IF_CMOF (0x1UL << 3) /* Cache Misses Overflow Interrupt Flag */ +# define _MSC_IF_CMOF_SHIFT 3 /* Shift value for MSC_CMOF */ +# define _MSC_IF_CMOF_MASK 0x8UL /* Bit mask for MSC_CMOF */ +# define _MSC_IF_CMOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IF */ +# define MSC_IF_CMOF_DEFAULT (_MSC_IF_CMOF_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_IF */ +#endif + +/* Bit fields for MSC IFS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_IFS_RESETVALUE 0x00000000UL /* Default value for MSC_IFS */ +# define _MSC_IFS_MASK 0x0000000FUL /* Mask for MSC_IFS */ +#else +# define _MSC_IFS_RESETVALUE 0x00000000UL /* Default value for MSC_IFS */ +# define _MSC_IFS_MASK 0x00000003UL /* Mask for MSC_IFS */ +#endif + +#define MSC_IFS_ERASE (0x1UL << 0) /* Erase Done Interrupt Set */ +#define _MSC_IFS_ERASE_SHIFT 0 /* Shift value for MSC_ERASE */ +#define _MSC_IFS_ERASE_MASK 0x1UL /* Bit mask for MSC_ERASE */ +#define _MSC_IFS_ERASE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFS */ +#define MSC_IFS_ERASE_DEFAULT (_MSC_IFS_ERASE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_IFS */ +#define MSC_IFS_WRITE (0x1UL << 1) /* Write Done Interrupt Set */ +#define _MSC_IFS_WRITE_SHIFT 1 /* Shift value for MSC_WRITE */ +#define _MSC_IFS_WRITE_MASK 0x2UL /* Bit mask for MSC_WRITE */ +#define _MSC_IFS_WRITE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFS */ +#define MSC_IFS_WRITE_DEFAULT (_MSC_IFS_WRITE_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_IFS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_IFS_CHOF (0x1UL << 2) /* Cache Hits Overflow Interrupt Set */ +# define _MSC_IFS_CHOF_SHIFT 2 /* Shift value for MSC_CHOF */ +# define _MSC_IFS_CHOF_MASK 0x4UL /* Bit mask for MSC_CHOF */ +# define _MSC_IFS_CHOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFS */ +# define MSC_IFS_CHOF_DEFAULT (_MSC_IFS_CHOF_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_IFS */ +# define MSC_IFS_CMOF (0x1UL << 3) /* Cache Misses Overflow Interrupt Set */ +# define _MSC_IFS_CMOF_SHIFT 3 /* Shift value for MSC_CMOF */ +# define _MSC_IFS_CMOF_MASK 0x8UL /* Bit mask for MSC_CMOF */ +# define _MSC_IFS_CMOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFS */ +# define MSC_IFS_CMOF_DEFAULT (_MSC_IFS_CMOF_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_IFS */ +#endif + +/* Bit fields for MSC IFC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_IFC_RESETVALUE 0x00000000UL /* Default value for MSC_IFC */ +# define _MSC_IFC_MASK 0x0000000FUL /* Mask for MSC_IFC */ +#else +# define _MSC_IFC_RESETVALUE 0x00000000UL /* Default value for MSC_IFC */ +# define _MSC_IFC_MASK 0x00000003UL /* Mask for MSC_IFC */ +#endif + +#define MSC_IFC_ERASE (0x1UL << 0) /* Erase Done Interrupt Clear */ +#define _MSC_IFC_ERASE_SHIFT 0 /* Shift value for MSC_ERASE */ +#define _MSC_IFC_ERASE_MASK 0x1UL /* Bit mask for MSC_ERASE */ +#define _MSC_IFC_ERASE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFC */ +#define MSC_IFC_ERASE_DEFAULT (_MSC_IFC_ERASE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_IFC */ +#define MSC_IFC_WRITE (0x1UL << 1) /* Write Done Interrupt Clear */ +#define _MSC_IFC_WRITE_SHIFT 1 /* Shift value for MSC_WRITE */ +#define _MSC_IFC_WRITE_MASK 0x2UL /* Bit mask for MSC_WRITE */ +#define _MSC_IFC_WRITE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFC */ +#define MSC_IFC_WRITE_DEFAULT (_MSC_IFC_WRITE_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_IFC */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_IFC_CHOF (0x1UL << 2) /* Cache Hits Overflow Interrupt Clear */ +# define _MSC_IFC_CHOF_SHIFT 2 /* Shift value for MSC_CHOF */ +# define _MSC_IFC_CHOF_MASK 0x4UL /* Bit mask for MSC_CHOF */ +# define _MSC_IFC_CHOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFC */ +# define MSC_IFC_CHOF_DEFAULT (_MSC_IFC_CHOF_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_IFC */ +# define MSC_IFC_CMOF (0x1UL << 3) /* Cache Misses Overflow Interrupt Clear */ +# define _MSC_IFC_CMOF_SHIFT 3 /* Shift value for MSC_CMOF */ +# define _MSC_IFC_CMOF_MASK 0x8UL /* Bit mask for MSC_CMOF */ +# define _MSC_IFC_CMOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IFC */ +# define MSC_IFC_CMOF_DEFAULT (_MSC_IFC_CMOF_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_IFC */ +#endif + +/* Bit fields for MSC IEN */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_IEN_RESETVALUE 0x00000000UL /* Default value for MSC_IEN */ +# define _MSC_IEN_MASK 0x0000000FUL /* Mask for MSC_IEN */ +#else +# define _MSC_IEN_RESETVALUE 0x00000000UL /* Default value for MSC_IEN */ +# define _MSC_IEN_MASK 0x00000003UL /* Mask for MSC_IEN */ +#endif + +#define MSC_IEN_ERASE (0x1UL << 0) /* Erase Done Interrupt Enable */ +#define _MSC_IEN_ERASE_SHIFT 0 /* Shift value for MSC_ERASE */ +#define _MSC_IEN_ERASE_MASK 0x1UL /* Bit mask for MSC_ERASE */ +#define _MSC_IEN_ERASE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IEN */ +#define MSC_IEN_ERASE_DEFAULT (_MSC_IEN_ERASE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_IEN */ +#define MSC_IEN_WRITE (0x1UL << 1) /* Write Done Interrupt Enable */ +#define _MSC_IEN_WRITE_SHIFT 1 /* Shift value for MSC_WRITE */ +#define _MSC_IEN_WRITE_MASK 0x2UL /* Bit mask for MSC_WRITE */ +#define _MSC_IEN_WRITE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IEN */ +#define MSC_IEN_WRITE_DEFAULT (_MSC_IEN_WRITE_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_IEN */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define MSC_IEN_CHOF (0x1UL << 2) /* Cache Hits Overflow Interrupt Enable */ +# define _MSC_IEN_CHOF_SHIFT 2 /* Shift value for MSC_CHOF */ +# define _MSC_IEN_CHOF_MASK 0x4UL /* Bit mask for MSC_CHOF */ +# define _MSC_IEN_CHOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IEN */ +# define MSC_IEN_CHOF_DEFAULT (_MSC_IEN_CHOF_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_IEN */ +# define MSC_IEN_CMOF (0x1UL << 3) /* Cache Misses Overflow Interrupt Enable */ +# define _MSC_IEN_CMOF_SHIFT 3 /* Shift value for MSC_CMOF */ +# define _MSC_IEN_CMOF_MASK 0x8UL /* Bit mask for MSC_CMOF */ +# define _MSC_IEN_CMOF_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_IEN */ +# define MSC_IEN_CMOF_DEFAULT (_MSC_IEN_CMOF_DEFAULT << 3) /* Shifted mode DEFAULT for MSC_IEN */ +#endif + +/* Bit fields for MSC LOCK */ + +#define _MSC_LOCK_RESETVALUE 0x00000000UL /* Default value for MSC_LOCK */ +#define _MSC_LOCK_MASK 0x0000FFFFUL /* Mask for MSC_LOCK */ + +#define _MSC_LOCK_LOCKKEY_SHIFT 0 /* Shift value for MSC_LOCKKEY */ +#define _MSC_LOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for MSC_LOCKKEY */ +#define _MSC_LOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_LOCK */ +#define _MSC_LOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for MSC_LOCK */ +#define _MSC_LOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for MSC_LOCK */ +#define _MSC_LOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for MSC_LOCK */ +#define _MSC_LOCK_LOCKKEY_UNLOCK 0x00001B71UL /* Mode UNLOCK for MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_DEFAULT (_MSC_LOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_LOCK (_MSC_LOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_UNLOCKED (_MSC_LOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_LOCKED (_MSC_LOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_UNLOCK (_MSC_LOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for MSC_LOCK */ + +#define MSC_UNLOCK_CODE 0x1B71 /* MSC unlock code */ + +/* Bit fields for MSC CMD */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_CMD_RESETVALUE 0x00000000UL /* Default value for MSC_CMD */ +# define _MSC_CMD_MASK 0x00000007UL /* Mask for MSC_CMD */ + +# define MSC_CMD_INVCACHE (0x1UL << 0) /* Invalidate Instruction Cache */ +# define _MSC_CMD_INVCACHE_SHIFT 0 /* Shift value for MSC_INVCACHE */ +# define _MSC_CMD_INVCACHE_MASK 0x1UL /* Bit mask for MSC_INVCACHE */ +# define _MSC_CMD_INVCACHE_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_CMD */ +# define MSC_CMD_INVCACHE_DEFAULT (_MSC_CMD_INVCACHE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_CMD */ +# define MSC_CMD_STARTPC (0x1UL << 1) /* Start Performance Counters */ +# define _MSC_CMD_STARTPC_SHIFT 1 /* Shift value for MSC_STARTPC */ +# define _MSC_CMD_STARTPC_MASK 0x2UL /* Bit mask for MSC_STARTPC */ +# define _MSC_CMD_STARTPC_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_CMD */ +# define MSC_CMD_STARTPC_DEFAULT (_MSC_CMD_STARTPC_DEFAULT << 1) /* Shifted mode DEFAULT for MSC_CMD */ +# define MSC_CMD_STOPPC (0x1UL << 2) /* Stop Performance Counters */ +# define _MSC_CMD_STOPPC_SHIFT 2 /* Shift value for MSC_STOPPC */ +# define _MSC_CMD_STOPPC_MASK 0x4UL /* Bit mask for MSC_STOPPC */ +# define _MSC_CMD_STOPPC_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_CMD */ +# define MSC_CMD_STOPPC_DEFAULT (_MSC_CMD_STOPPC_DEFAULT << 2) /* Shifted mode DEFAULT for MSC_CMD */ +#endif + +/* Bit fields for MSC CACHEHITS */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_CACHEHITS_RESETVALUE 0x00000000UL /* Default value for MSC_CACHEHITS */ +# define _MSC_CACHEHITS_MASK 0x000FFFFFUL /* Mask for MSC_CACHEHITS */ + +# define _MSC_CACHEHITS_CACHEHITS_SHIFT 0 /* Shift value for MSC_CACHEHITS */ +# define _MSC_CACHEHITS_CACHEHITS_MASK 0xFFFFFUL /* Bit mask for MSC_CACHEHITS */ +# define _MSC_CACHEHITS_CACHEHITS_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_CACHEHITS */ +# define MSC_CACHEHITS_CACHEHITS_DEFAULT (_MSC_CACHEHITS_CACHEHITS_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_CACHEHITS */ +#endif + +/* Bit fields for MSC CACHEMISSES */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_CACHEMISSES_RESETVALUE 0x00000000UL /* Default value for MSC_CACHEMISSES */ +# define _MSC_CACHEMISSES_MASK 0x000FFFFFUL /* Mask for MSC_CACHEMISSES */ + +# define _MSC_CACHEMISSES_CACHEMISSES_SHIFT 0 /* Shift value for MSC_CACHEMISSES */ +# define _MSC_CACHEMISSES_CACHEMISSES_MASK 0xFFFFFUL /* Bit mask for MSC_CACHEMISSES */ +# define _MSC_CACHEMISSES_CACHEMISSES_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_CACHEMISSES */ +# define MSC_CACHEMISSES_CACHEMISSES_DEFAULT (_MSC_CACHEMISSES_CACHEMISSES_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_CACHEMISSES */ +#endif + +/* Bit fields for MSC TIMEBASE */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_TIMEBASE_RESETVALUE 0x00000010UL /* Default value for MSC_TIMEBASE */ +# define _MSC_TIMEBASE_MASK 0x0001003FUL /* Mask for MSC_TIMEBASE */ + +# define _MSC_TIMEBASE_BASE_SHIFT 0 /* Shift value for MSC_BASE */ +# define _MSC_TIMEBASE_BASE_MASK 0x3FUL /* Bit mask for MSC_BASE */ +# define _MSC_TIMEBASE_BASE_DEFAULT 0x00000010UL /* Mode DEFAULT for MSC_TIMEBASE */ +# define MSC_TIMEBASE_BASE_DEFAULT (_MSC_TIMEBASE_BASE_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_TIMEBASE */ +# define MSC_TIMEBASE_PERIOD (0x1UL << 16) /* Sets the timebase period */ +# define _MSC_TIMEBASE_PERIOD_SHIFT 16 /* Shift value for MSC_PERIOD */ +# define _MSC_TIMEBASE_PERIOD_MASK 0x10000UL /* Bit mask for MSC_PERIOD */ +# define _MSC_TIMEBASE_PERIOD_DEFAULT 0x00000000UL /* Mode DEFAULT for MSC_TIMEBASE */ +# define _MSC_TIMEBASE_PERIOD_1US 0x00000000UL /* Mode 1US for MSC_TIMEBASE */ +# define _MSC_TIMEBASE_PERIOD_5US 0x00000001UL /* Mode 5US for MSC_TIMEBASE */ +# define MSC_TIMEBASE_PERIOD_DEFAULT (_MSC_TIMEBASE_PERIOD_DEFAULT << 16) /* Shifted mode DEFAULT for MSC_TIMEBASE */ +# define MSC_TIMEBASE_PERIOD_1US (_MSC_TIMEBASE_PERIOD_1US << 16) /* Shifted mode 1US for MSC_TIMEBASE */ +# define MSC_TIMEBASE_PERIOD_5US (_MSC_TIMEBASE_PERIOD_5US << 16) /* Shifted mode 5US for MSC_TIMEBASE */ +#endif + +/* Bit fields for MSC MASSLOCK */ + +#if defined(CONFIG_EFM32_EFM32GG) +# define _MSC_MASSLOCK_RESETVALUE 0x00000001UL /* Default value for MSC_MASSLOCK */ +# define _MSC_MASSLOCK_MASK 0x0000FFFFUL /* Mask for MSC_MASSLOCK */ + +# define _MSC_MASSLOCK_LOCKKEY_SHIFT 0 /* Shift value for MSC_LOCKKEY */ +# define _MSC_MASSLOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for MSC_LOCKKEY */ +# define _MSC_MASSLOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for MSC_MASSLOCK */ +# define _MSC_MASSLOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for MSC_MASSLOCK */ +# define _MSC_MASSLOCK_LOCKKEY_DEFAULT 0x00000001UL /* Mode DEFAULT for MSC_MASSLOCK */ +# define _MSC_MASSLOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for MSC_MASSLOCK */ +# define _MSC_MASSLOCK_LOCKKEY_UNLOCK 0x0000631AUL /* Mode UNLOCK for MSC_MASSLOCK */ +# define MSC_MASSLOCK_LOCKKEY_LOCK (_MSC_MASSLOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for MSC_MASSLOCK */ +# define MSC_MASSLOCK_LOCKKEY_UNLOCKED (_MSC_MASSLOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for MSC_MASSLOCK */ +# define MSC_MASSLOCK_LOCKKEY_DEFAULT (_MSC_MASSLOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for MSC_MASSLOCK */ +# define MSC_MASSLOCK_LOCKKEY_LOCKED (_MSC_MASSLOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for MSC_MASSLOCK */ +# define MSC_MASSLOCK_LOCKKEY_UNLOCK (_MSC_MASSLOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for MSC_MASSLOCK */ +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_EFM32_MSC_H */ diff --git a/arch/arm/src/efm32/chip/efm32_pcnt.h b/arch/arm/src/efm32/chip/efm32_pcnt.h new file mode 100644 index 0000000000000000000000000000000000000000..e9947f5ba74751240535470a7fdf6503bfb7d0d0 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_pcnt.h @@ -0,0 +1,529 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_pcnt.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PCNT_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PCNT_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* PCNT Register Offsets *******************************************************************************************************/ + +#define EFM32_PCNT_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_PCNT_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_PCNT_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_PCNT_CNT_OFFSET 0x000c /* Counter Value Register */ +#define EFM32_PCNT_TOP_OFFSET 0x0010 /* Top Value Register */ +#define EFM32_PCNT_TOPB_OFFSET 0x0014 /* Top Value Buffer Register */ +#define EFM32_PCNT_IF_OFFSET 0x0018 /* Interrupt Flag Register */ +#define EFM32_PCNT_IFS_OFFSET 0x001c /* Interrupt Flag Set Register */ +#define EFM32_PCNT_IFC_OFFSET 0x0020 /* Interrupt Flag Clear Register */ +#define EFM32_PCNT_IEN_OFFSET 0x0024 /* Interrupt Enable Register */ +#define EFM32_PCNT_ROUTE_OFFSET 0x0028 /* I/O Routing Register */ +#define EFM32_PCNT_FREEZE_OFFSET 0x002c /* Freeze Register */ +#define EFM32_PCNT_SYNCBUSY_OFFSET 0x0030 /* Synchronization Busy Register */ +#define EFM32_PCNT_AUXCNT_OFFSET 0x0038 /* Auxillary Counter Value Register */ +#define EFM32_PCNT_INPUT_OFFSET 0x003c /* PCNT Input Register */ + +/* PCNT Register Addresses *****************************************************************************************************/ + +#define EFM32_PCNT0_CTRL (EFM32_PCNT0_BASE+EFM32_PCNT_CTRL_OFFSET) +#define EFM32_PCNT0_CMD (EFM32_PCNT0_BASE+EFM32_PCNT_CMD_OFFSET) +#define EFM32_PCNT0_STATUS (EFM32_PCNT0_BASE+EFM32_PCNT_STATUS_OFFSET) +#define EFM32_PCNT0_CNT (EFM32_PCNT0_BASE+EFM32_PCNT_CNT_OFFSET) +#define EFM32_PCNT0_TOP (EFM32_PCNT0_BASE+EFM32_PCNT_TOP_OFFSET) +#define EFM32_PCNT0_TOPB (EFM32_PCNT0_BASE+EFM32_PCNT_TOPB_OFFSET) +#define EFM32_PCNT0_IF (EFM32_PCNT0_BASE+EFM32_PCNT_IF_OFFSET) +#define EFM32_PCNT0_IFS (EFM32_PCNT0_BASE+EFM32_PCNT_IFS_OFFSET) +#define EFM32_PCNT0_IFC (EFM32_PCNT0_BASE+EFM32_PCNT_IFC_OFFSET) +#define EFM32_PCNT0_IEN (EFM32_PCNT0_BASE+EFM32_PCNT_IEN_OFFSET) +#define EFM32_PCNT0_ROUTE (EFM32_PCNT0_BASE+EFM32_PCNT_ROUTE_OFFSET) +#define EFM32_PCNT0_FREEZE (EFM32_PCNT0_BASE+EFM32_PCNT_FREEZE_OFFSET) +#define EFM32_PCNT0_SYNCBUSY (EFM32_PCNT0_BASE+EFM32_PCNT_SYNCBUSY_OFFSET) +#define EFM32_PCNT0_AUXCNT (EFM32_PCNT0_BASE+EFM32_PCNT_AUXCNT_OFFSET) +#define EFM32_PCNT0_INPUT (EFM32_PCNT0_BASE+EFM32_PCNT_INPUT_OFFSET) + +#define EFM32_PCNT1_CTRL (EFM32_PCNT1_BASE+EFM32_PCNT_CTRL_OFFSET) +#define EFM32_PCNT1_CMD (EFM32_PCNT1_BASE+EFM32_PCNT_CMD_OFFSET) +#define EFM32_PCNT1_STATUS (EFM32_PCNT1_BASE+EFM32_PCNT_STATUS_OFFSET) +#define EFM32_PCNT1_CNT (EFM32_PCNT1_BASE+EFM32_PCNT_CNT_OFFSET) +#define EFM32_PCNT1_TOP (EFM32_PCNT1_BASE+EFM32_PCNT_TOP_OFFSET) +#define EFM32_PCNT1_TOPB (EFM32_PCNT1_BASE+EFM32_PCNT_TOPB_OFFSET) +#define EFM32_PCNT1_IF (EFM32_PCNT1_BASE+EFM32_PCNT_IF_OFFSET) +#define EFM32_PCNT1_IFS (EFM32_PCNT1_BASE+EFM32_PCNT_IFS_OFFSET) +#define EFM32_PCNT1_IFC (EFM32_PCNT1_BASE+EFM32_PCNT_IFC_OFFSET) +#define EFM32_PCNT1_IEN (EFM32_PCNT1_BASE+EFM32_PCNT_IEN_OFFSET) +#define EFM32_PCNT1_ROUTE (EFM32_PCNT1_BASE+EFM32_PCNT_ROUTE_OFFSET) +#define EFM32_PCNT1_FREEZE (EFM32_PCNT1_BASE+EFM32_PCNT_FREEZE_OFFSET) +#define EFM32_PCNT1_SYNCBUSY (EFM32_PCNT1_BASE+EFM32_PCNT_SYNCBUSY_OFFSET) +#define EFM32_PCNT1_AUXCNT (EFM32_PCNT1_BASE+EFM32_PCNT_AUXCNT_OFFSET) +#define EFM32_PCNT1_INPUT (EFM32_PCNT1_BASE+EFM32_PCNT_INPUT_OFFSET) + +#define EFM32_PCNT2_CTRL (EFM32_PCNT2_BASE+EFM32_PCNT_CTRL_OFFSET) +#define EFM32_PCNT2_CMD (EFM32_PCNT2_BASE+EFM32_PCNT_CMD_OFFSET) +#define EFM32_PCNT2_STATUS (EFM32_PCNT2_BASE+EFM32_PCNT_STATUS_OFFSET) +#define EFM32_PCNT2_CNT (EFM32_PCNT2_BASE+EFM32_PCNT_CNT_OFFSET) +#define EFM32_PCNT2_TOP (EFM32_PCNT2_BASE+EFM32_PCNT_TOP_OFFSET) +#define EFM32_PCNT2_TOPB (EFM32_PCNT2_BASE+EFM32_PCNT_TOPB_OFFSET) +#define EFM32_PCNT2_IF (EFM32_PCNT2_BASE+EFM32_PCNT_IF_OFFSET) +#define EFM32_PCNT2_IFS (EFM32_PCNT2_BASE+EFM32_PCNT_IFS_OFFSET) +#define EFM32_PCNT2_IFC (EFM32_PCNT2_BASE+EFM32_PCNT_IFC_OFFSET) +#define EFM32_PCNT2_IEN (EFM32_PCNT2_BASE+EFM32_PCNT_IEN_OFFSET) +#define EFM32_PCNT2_ROUTE (EFM32_PCNT2_BASE+EFM32_PCNT_ROUTE_OFFSET) +#define EFM32_PCNT2_FREEZE (EFM32_PCNT2_BASE+EFM32_PCNT_FREEZE_OFFSET) +#define EFM32_PCNT2_SYNCBUSY (EFM32_PCNT2_BASE+EFM32_PCNT_SYNCBUSY_OFFSET) +#define EFM32_PCNT2_AUXCNT (EFM32_PCNT2_BASE+EFM32_PCNT_AUXCNT_OFFSET) +#define EFM32_PCNT2_INPUT (EFM32_PCNT2_BASE+EFM32_PCNT_INPUT_OFFSET) + +/* PCNT Register Bit Field Definitions *****************************************************************************************/ + +/* Bit fields for PCNT CTRL */ + +#define _PCNT_CTRL_RESETVALUE 0x00000000UL /* Default value for PCNT_CTRL */ +#define _PCNT_CTRL_MASK 0x0000CF3FUL /* Mask for PCNT_CTRL */ + +#define _PCNT_CTRL_MODE_SHIFT 0 /* Shift value for PCNT_MODE */ +#define _PCNT_CTRL_MODE_MASK 0x3UL /* Bit mask for PCNT_MODE */ +#define _PCNT_CTRL_MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_MODE_DISABLE 0x00000000UL /* Mode DISABLE for PCNT_CTRL */ +#define _PCNT_CTRL_MODE_OVSSINGLE 0x00000001UL /* Mode OVSSINGLE for PCNT_CTRL */ +#define _PCNT_CTRL_MODE_EXTCLKSINGLE 0x00000002UL /* Mode EXTCLKSINGLE for PCNT_CTRL */ +#define _PCNT_CTRL_MODE_EXTCLKQUAD 0x00000003UL /* Mode EXTCLKQUAD for PCNT_CTRL */ +#define PCNT_CTRL_MODE_DEFAULT (_PCNT_CTRL_MODE_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_MODE_DISABLE (_PCNT_CTRL_MODE_DISABLE << 0) /* Shifted mode DISABLE for PCNT_CTRL */ +#define PCNT_CTRL_MODE_OVSSINGLE (_PCNT_CTRL_MODE_OVSSINGLE << 0) /* Shifted mode OVSSINGLE for PCNT_CTRL */ +#define PCNT_CTRL_MODE_EXTCLKSINGLE (_PCNT_CTRL_MODE_EXTCLKSINGLE << 0) /* Shifted mode EXTCLKSINGLE for PCNT_CTRL */ +#define PCNT_CTRL_MODE_EXTCLKQUAD (_PCNT_CTRL_MODE_EXTCLKQUAD << 0) /* Shifted mode EXTCLKQUAD for PCNT_CTRL */ +#define PCNT_CTRL_CNTDIR (0x1UL << 2) /* Non-Quadrature Mode Counter Direction Control */ +#define _PCNT_CTRL_CNTDIR_SHIFT 2 /* Shift value for PCNT_CNTDIR */ +#define _PCNT_CTRL_CNTDIR_MASK 0x4UL /* Bit mask for PCNT_CNTDIR */ +#define _PCNT_CTRL_CNTDIR_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_CNTDIR_UP 0x00000000UL /* Mode UP for PCNT_CTRL */ +#define _PCNT_CTRL_CNTDIR_DOWN 0x00000001UL /* Mode DOWN for PCNT_CTRL */ +#define PCNT_CTRL_CNTDIR_DEFAULT (_PCNT_CTRL_CNTDIR_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_CNTDIR_UP (_PCNT_CTRL_CNTDIR_UP << 2) /* Shifted mode UP for PCNT_CTRL */ +#define PCNT_CTRL_CNTDIR_DOWN (_PCNT_CTRL_CNTDIR_DOWN << 2) /* Shifted mode DOWN for PCNT_CTRL */ +#define PCNT_CTRL_EDGE (0x1UL << 3) /* Edge Select */ +#define _PCNT_CTRL_EDGE_SHIFT 3 /* Shift value for PCNT_EDGE */ +#define _PCNT_CTRL_EDGE_MASK 0x8UL /* Bit mask for PCNT_EDGE */ +#define _PCNT_CTRL_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_EDGE_POS 0x00000000UL /* Mode POS for PCNT_CTRL */ +#define _PCNT_CTRL_EDGE_NEG 0x00000001UL /* Mode NEG for PCNT_CTRL */ +#define PCNT_CTRL_EDGE_DEFAULT (_PCNT_CTRL_EDGE_DEFAULT << 3) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_EDGE_POS (_PCNT_CTRL_EDGE_POS << 3) /* Shifted mode POS for PCNT_CTRL */ +#define PCNT_CTRL_EDGE_NEG (_PCNT_CTRL_EDGE_NEG << 3) /* Shifted mode NEG for PCNT_CTRL */ +#define PCNT_CTRL_FILT (0x1UL << 4) /* Enable Digital Pulse Width Filter */ +#define _PCNT_CTRL_FILT_SHIFT 4 /* Shift value for PCNT_FILT */ +#define _PCNT_CTRL_FILT_MASK 0x10UL /* Bit mask for PCNT_FILT */ +#define _PCNT_CTRL_FILT_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_FILT_DEFAULT (_PCNT_CTRL_FILT_DEFAULT << 4) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_RSTEN (0x1UL << 5) /* Enable PCNT Clock Domain Reset */ +#define _PCNT_CTRL_RSTEN_SHIFT 5 /* Shift value for PCNT_RSTEN */ +#define _PCNT_CTRL_RSTEN_MASK 0x20UL /* Bit mask for PCNT_RSTEN */ +#define _PCNT_CTRL_RSTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_RSTEN_DEFAULT (_PCNT_CTRL_RSTEN_DEFAULT << 5) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_HYST (0x1UL << 8) /* Enable Hysteresis */ +#define _PCNT_CTRL_HYST_SHIFT 8 /* Shift value for PCNT_HYST */ +#define _PCNT_CTRL_HYST_MASK 0x100UL /* Bit mask for PCNT_HYST */ +#define _PCNT_CTRL_HYST_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_HYST_DEFAULT (_PCNT_CTRL_HYST_DEFAULT << 8) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_S1CDIR (0x1UL << 9) /* Count direction determined by S1 */ +#define _PCNT_CTRL_S1CDIR_SHIFT 9 /* Shift value for PCNT_S1CDIR */ +#define _PCNT_CTRL_S1CDIR_MASK 0x200UL /* Bit mask for PCNT_S1CDIR */ +#define _PCNT_CTRL_S1CDIR_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_S1CDIR_DEFAULT (_PCNT_CTRL_S1CDIR_DEFAULT << 9) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_CNTEV_SHIFT 10 /* Shift value for PCNT_CNTEV */ +#define _PCNT_CTRL_CNTEV_MASK 0xC00UL /* Bit mask for PCNT_CNTEV */ +#define _PCNT_CTRL_CNTEV_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_CNTEV_BOTH 0x00000000UL /* Mode BOTH for PCNT_CTRL */ +#define _PCNT_CTRL_CNTEV_UP 0x00000001UL /* Mode UP for PCNT_CTRL */ +#define _PCNT_CTRL_CNTEV_DOWN 0x00000002UL /* Mode DOWN for PCNT_CTRL */ +#define _PCNT_CTRL_CNTEV_NONE 0x00000003UL /* Mode NONE for PCNT_CTRL */ +#define PCNT_CTRL_CNTEV_DEFAULT (_PCNT_CTRL_CNTEV_DEFAULT << 10) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_CNTEV_BOTH (_PCNT_CTRL_CNTEV_BOTH << 10) /* Shifted mode BOTH for PCNT_CTRL */ +#define PCNT_CTRL_CNTEV_UP (_PCNT_CTRL_CNTEV_UP << 10) /* Shifted mode UP for PCNT_CTRL */ +#define PCNT_CTRL_CNTEV_DOWN (_PCNT_CTRL_CNTEV_DOWN << 10) /* Shifted mode DOWN for PCNT_CTRL */ +#define PCNT_CTRL_CNTEV_NONE (_PCNT_CTRL_CNTEV_NONE << 10) /* Shifted mode NONE for PCNT_CTRL */ +#define _PCNT_CTRL_AUXCNTEV_SHIFT 14 /* Shift value for PCNT_AUXCNTEV */ +#define _PCNT_CTRL_AUXCNTEV_MASK 0xC000UL /* Bit mask for PCNT_AUXCNTEV */ +#define _PCNT_CTRL_AUXCNTEV_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CTRL */ +#define _PCNT_CTRL_AUXCNTEV_NONE 0x00000000UL /* Mode NONE for PCNT_CTRL */ +#define _PCNT_CTRL_AUXCNTEV_UP 0x00000001UL /* Mode UP for PCNT_CTRL */ +#define _PCNT_CTRL_AUXCNTEV_DOWN 0x00000002UL /* Mode DOWN for PCNT_CTRL */ +#define _PCNT_CTRL_AUXCNTEV_BOTH 0x00000003UL /* Mode BOTH for PCNT_CTRL */ +#define PCNT_CTRL_AUXCNTEV_DEFAULT (_PCNT_CTRL_AUXCNTEV_DEFAULT << 14) /* Shifted mode DEFAULT for PCNT_CTRL */ +#define PCNT_CTRL_AUXCNTEV_NONE (_PCNT_CTRL_AUXCNTEV_NONE << 14) /* Shifted mode NONE for PCNT_CTRL */ +#define PCNT_CTRL_AUXCNTEV_UP (_PCNT_CTRL_AUXCNTEV_UP << 14) /* Shifted mode UP for PCNT_CTRL */ +#define PCNT_CTRL_AUXCNTEV_DOWN (_PCNT_CTRL_AUXCNTEV_DOWN << 14) /* Shifted mode DOWN for PCNT_CTRL */ +#define PCNT_CTRL_AUXCNTEV_BOTH (_PCNT_CTRL_AUXCNTEV_BOTH << 14) /* Shifted mode BOTH for PCNT_CTRL */ + +/* Bit fields for PCNT CMD */ + +#define _PCNT_CMD_RESETVALUE 0x00000000UL /* Default value for PCNT_CMD */ +#define _PCNT_CMD_MASK 0x00000003UL /* Mask for PCNT_CMD */ + +#define PCNT_CMD_LCNTIM (0x1UL << 0) /* Load CNT Immediately */ +#define _PCNT_CMD_LCNTIM_SHIFT 0 /* Shift value for PCNT_LCNTIM */ +#define _PCNT_CMD_LCNTIM_MASK 0x1UL /* Bit mask for PCNT_LCNTIM */ +#define _PCNT_CMD_LCNTIM_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CMD */ +#define PCNT_CMD_LCNTIM_DEFAULT (_PCNT_CMD_LCNTIM_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_CMD */ +#define PCNT_CMD_LTOPBIM (0x1UL << 1) /* Load TOPB Immediately */ +#define _PCNT_CMD_LTOPBIM_SHIFT 1 /* Shift value for PCNT_LTOPBIM */ +#define _PCNT_CMD_LTOPBIM_MASK 0x2UL /* Bit mask for PCNT_LTOPBIM */ +#define _PCNT_CMD_LTOPBIM_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CMD */ +#define PCNT_CMD_LTOPBIM_DEFAULT (_PCNT_CMD_LTOPBIM_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_CMD */ + +/* Bit fields for PCNT STATUS */ + +#define _PCNT_STATUS_RESETVALUE 0x00000000UL /* Default value for PCNT_STATUS */ +#define _PCNT_STATUS_MASK 0x00000001UL /* Mask for PCNT_STATUS */ + +#define PCNT_STATUS_DIR (0x1UL << 0) /* Current Counter Direction */ +#define _PCNT_STATUS_DIR_SHIFT 0 /* Shift value for PCNT_DIR */ +#define _PCNT_STATUS_DIR_MASK 0x1UL /* Bit mask for PCNT_DIR */ +#define _PCNT_STATUS_DIR_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_STATUS */ +#define _PCNT_STATUS_DIR_UP 0x00000000UL /* Mode UP for PCNT_STATUS */ +#define _PCNT_STATUS_DIR_DOWN 0x00000001UL /* Mode DOWN for PCNT_STATUS */ +#define PCNT_STATUS_DIR_DEFAULT (_PCNT_STATUS_DIR_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_STATUS */ +#define PCNT_STATUS_DIR_UP (_PCNT_STATUS_DIR_UP << 0) /* Shifted mode UP for PCNT_STATUS */ +#define PCNT_STATUS_DIR_DOWN (_PCNT_STATUS_DIR_DOWN << 0) /* Shifted mode DOWN for PCNT_STATUS */ + +/* Bit fields for PCNT CNT */ + +#define _PCNT_CNT_RESETVALUE 0x00000000UL /* Default value for PCNT_CNT */ +#define _PCNT_CNT_MASK 0x0000FFFFUL /* Mask for PCNT_CNT */ + +#define _PCNT_CNT_CNT_SHIFT 0 /* Shift value for PCNT_CNT */ +#define _PCNT_CNT_CNT_MASK 0xFFFFUL /* Bit mask for PCNT_CNT */ +#define _PCNT_CNT_CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_CNT */ +#define PCNT_CNT_CNT_DEFAULT (_PCNT_CNT_CNT_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_CNT */ + +/* Bit fields for PCNT TOP */ + +#define _PCNT_TOP_RESETVALUE 0x000000FFUL /* Default value for PCNT_TOP */ +#define _PCNT_TOP_MASK 0x0000FFFFUL /* Mask for PCNT_TOP */ + +#define _PCNT_TOP_TOP_SHIFT 0 /* Shift value for PCNT_TOP */ +#define _PCNT_TOP_TOP_MASK 0xFFFFUL /* Bit mask for PCNT_TOP */ +#define _PCNT_TOP_TOP_DEFAULT 0x000000FFUL /* Mode DEFAULT for PCNT_TOP */ +#define PCNT_TOP_TOP_DEFAULT (_PCNT_TOP_TOP_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_TOP */ + +/* Bit fields for PCNT TOPB */ + +#define _PCNT_TOPB_RESETVALUE 0x000000FFUL /* Default value for PCNT_TOPB */ +#define _PCNT_TOPB_MASK 0x0000FFFFUL /* Mask for PCNT_TOPB */ + +#define _PCNT_TOPB_TOPB_SHIFT 0 /* Shift value for PCNT_TOPB */ +#define _PCNT_TOPB_TOPB_MASK 0xFFFFUL /* Bit mask for PCNT_TOPB */ +#define _PCNT_TOPB_TOPB_DEFAULT 0x000000FFUL /* Mode DEFAULT for PCNT_TOPB */ +#define PCNT_TOPB_TOPB_DEFAULT (_PCNT_TOPB_TOPB_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_TOPB */ + +/* Bit fields for PCNT IF */ + +#define _PCNT_IF_RESETVALUE 0x00000000UL /* Default value for PCNT_IF */ +#define _PCNT_IF_MASK 0x0000000FUL /* Mask for PCNT_IF */ + +#define PCNT_IF_UF (0x1UL << 0) /* Underflow Interrupt Read Flag */ +#define _PCNT_IF_UF_SHIFT 0 /* Shift value for PCNT_UF */ +#define _PCNT_IF_UF_MASK 0x1UL /* Bit mask for PCNT_UF */ +#define _PCNT_IF_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IF */ +#define PCNT_IF_UF_DEFAULT (_PCNT_IF_UF_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_IF */ +#define PCNT_IF_OF (0x1UL << 1) /* Overflow Interrupt Read Flag */ +#define _PCNT_IF_OF_SHIFT 1 /* Shift value for PCNT_OF */ +#define _PCNT_IF_OF_MASK 0x2UL /* Bit mask for PCNT_OF */ +#define _PCNT_IF_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IF */ +#define PCNT_IF_OF_DEFAULT (_PCNT_IF_OF_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_IF */ +#define PCNT_IF_DIRCNG (0x1UL << 2) /* Direction Change Detect Interrupt Flag */ +#define _PCNT_IF_DIRCNG_SHIFT 2 /* Shift value for PCNT_DIRCNG */ +#define _PCNT_IF_DIRCNG_MASK 0x4UL /* Bit mask for PCNT_DIRCNG */ +#define _PCNT_IF_DIRCNG_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IF */ +#define PCNT_IF_DIRCNG_DEFAULT (_PCNT_IF_DIRCNG_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_IF */ +#define PCNT_IF_AUXOF (0x1UL << 3) /* Overflow Interrupt Read Flag */ +#define _PCNT_IF_AUXOF_SHIFT 3 /* Shift value for PCNT_AUXOF */ +#define _PCNT_IF_AUXOF_MASK 0x8UL /* Bit mask for PCNT_AUXOF */ +#define _PCNT_IF_AUXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IF */ +#define PCNT_IF_AUXOF_DEFAULT (_PCNT_IF_AUXOF_DEFAULT << 3) /* Shifted mode DEFAULT for PCNT_IF */ + +/* Bit fields for PCNT IFS */ + +#define _PCNT_IFS_RESETVALUE 0x00000000UL /* Default value for PCNT_IFS */ +#define _PCNT_IFS_MASK 0x0000000FUL /* Mask for PCNT_IFS */ + +#define PCNT_IFS_UF (0x1UL << 0) /* Underflow interrupt set */ +#define _PCNT_IFS_UF_SHIFT 0 /* Shift value for PCNT_UF */ +#define _PCNT_IFS_UF_MASK 0x1UL /* Bit mask for PCNT_UF */ +#define _PCNT_IFS_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_UF_DEFAULT (_PCNT_IFS_UF_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_OF (0x1UL << 1) /* Overflow Interrupt Set */ +#define _PCNT_IFS_OF_SHIFT 1 /* Shift value for PCNT_OF */ +#define _PCNT_IFS_OF_MASK 0x2UL /* Bit mask for PCNT_OF */ +#define _PCNT_IFS_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_OF_DEFAULT (_PCNT_IFS_OF_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_DIRCNG (0x1UL << 2) /* Direction Change Detect Interrupt Set */ +#define _PCNT_IFS_DIRCNG_SHIFT 2 /* Shift value for PCNT_DIRCNG */ +#define _PCNT_IFS_DIRCNG_MASK 0x4UL /* Bit mask for PCNT_DIRCNG */ +#define _PCNT_IFS_DIRCNG_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_DIRCNG_DEFAULT (_PCNT_IFS_DIRCNG_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_AUXOF (0x1UL << 3) /* Auxiliary Overflow Interrupt Set */ +#define _PCNT_IFS_AUXOF_SHIFT 3 /* Shift value for PCNT_AUXOF */ +#define _PCNT_IFS_AUXOF_MASK 0x8UL /* Bit mask for PCNT_AUXOF */ +#define _PCNT_IFS_AUXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFS */ +#define PCNT_IFS_AUXOF_DEFAULT (_PCNT_IFS_AUXOF_DEFAULT << 3) /* Shifted mode DEFAULT for PCNT_IFS */ + +/* Bit fields for PCNT IFC */ + +#define _PCNT_IFC_RESETVALUE 0x00000000UL /* Default value for PCNT_IFC */ +#define _PCNT_IFC_MASK 0x0000000FUL /* Mask for PCNT_IFC */ + +#define PCNT_IFC_UF (0x1UL << 0) /* Underflow Interrupt Clear */ +#define _PCNT_IFC_UF_SHIFT 0 /* Shift value for PCNT_UF */ +#define _PCNT_IFC_UF_MASK 0x1UL /* Bit mask for PCNT_UF */ +#define _PCNT_IFC_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_UF_DEFAULT (_PCNT_IFC_UF_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_OF (0x1UL << 1) /* Overflow Interrupt Clear */ +#define _PCNT_IFC_OF_SHIFT 1 /* Shift value for PCNT_OF */ +#define _PCNT_IFC_OF_MASK 0x2UL /* Bit mask for PCNT_OF */ +#define _PCNT_IFC_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_OF_DEFAULT (_PCNT_IFC_OF_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_DIRCNG (0x1UL << 2) /* Direction Change Detect Interrupt Clear */ +#define _PCNT_IFC_DIRCNG_SHIFT 2 /* Shift value for PCNT_DIRCNG */ +#define _PCNT_IFC_DIRCNG_MASK 0x4UL /* Bit mask for PCNT_DIRCNG */ +#define _PCNT_IFC_DIRCNG_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_DIRCNG_DEFAULT (_PCNT_IFC_DIRCNG_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_AUXOF (0x1UL << 3) /* Auxiliary Overflow Interrupt Clear */ +#define _PCNT_IFC_AUXOF_SHIFT 3 /* Shift value for PCNT_AUXOF */ +#define _PCNT_IFC_AUXOF_MASK 0x8UL /* Bit mask for PCNT_AUXOF */ +#define _PCNT_IFC_AUXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IFC */ +#define PCNT_IFC_AUXOF_DEFAULT (_PCNT_IFC_AUXOF_DEFAULT << 3) /* Shifted mode DEFAULT for PCNT_IFC */ + +/* Bit fields for PCNT IEN */ + +#define _PCNT_IEN_RESETVALUE 0x00000000UL /* Default value for PCNT_IEN */ +#define _PCNT_IEN_MASK 0x0000000FUL /* Mask for PCNT_IEN */ + +#define PCNT_IEN_UF (0x1UL << 0) /* Underflow Interrupt Enable */ +#define _PCNT_IEN_UF_SHIFT 0 /* Shift value for PCNT_UF */ +#define _PCNT_IEN_UF_MASK 0x1UL /* Bit mask for PCNT_UF */ +#define _PCNT_IEN_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_UF_DEFAULT (_PCNT_IEN_UF_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_OF (0x1UL << 1) /* Overflow Interrupt Enable */ +#define _PCNT_IEN_OF_SHIFT 1 /* Shift value for PCNT_OF */ +#define _PCNT_IEN_OF_MASK 0x2UL /* Bit mask for PCNT_OF */ +#define _PCNT_IEN_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_OF_DEFAULT (_PCNT_IEN_OF_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_DIRCNG (0x1UL << 2) /* Direction Change Detect Interrupt Enable */ +#define _PCNT_IEN_DIRCNG_SHIFT 2 /* Shift value for PCNT_DIRCNG */ +#define _PCNT_IEN_DIRCNG_MASK 0x4UL /* Bit mask for PCNT_DIRCNG */ +#define _PCNT_IEN_DIRCNG_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_DIRCNG_DEFAULT (_PCNT_IEN_DIRCNG_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_AUXOF (0x1UL << 3) /* Auxiliary Overflow Interrupt Enable */ +#define _PCNT_IEN_AUXOF_SHIFT 3 /* Shift value for PCNT_AUXOF */ +#define _PCNT_IEN_AUXOF_MASK 0x8UL /* Bit mask for PCNT_AUXOF */ +#define _PCNT_IEN_AUXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_IEN */ +#define PCNT_IEN_AUXOF_DEFAULT (_PCNT_IEN_AUXOF_DEFAULT << 3) /* Shifted mode DEFAULT for PCNT_IEN */ + +/* Bit fields for PCNT ROUTE */ + +#define _PCNT_ROUTE_RESETVALUE 0x00000000UL /* Default value for PCNT_ROUTE */ +#define _PCNT_ROUTE_MASK 0x00000700UL /* Mask for PCNT_ROUTE */ + +#define _PCNT_ROUTE_LOCATION_SHIFT 8 /* Shift value for PCNT_LOCATION */ +#define _PCNT_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for PCNT_LOCATION */ +#define _PCNT_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for PCNT_ROUTE */ +#define _PCNT_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_ROUTE */ +#define _PCNT_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for PCNT_ROUTE */ +#define _PCNT_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for PCNT_ROUTE */ +#define _PCNT_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for PCNT_ROUTE */ +#define PCNT_ROUTE_LOCATION_LOC0 (_PCNT_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for PCNT_ROUTE */ +#define PCNT_ROUTE_LOCATION_DEFAULT (_PCNT_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for PCNT_ROUTE */ +#define PCNT_ROUTE_LOCATION_LOC1 (_PCNT_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for PCNT_ROUTE */ +#define PCNT_ROUTE_LOCATION_LOC2 (_PCNT_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for PCNT_ROUTE */ +#define PCNT_ROUTE_LOCATION_LOC3 (_PCNT_ROUTE_LOCATION_LOC3 << 8) /* Shifted mode LOC3 for PCNT_ROUTE */ + +/* Bit fields for PCNT FREEZE */ + +#define _PCNT_FREEZE_RESETVALUE 0x00000000UL /* Default value for PCNT_FREEZE */ +#define _PCNT_FREEZE_MASK 0x00000001UL /* Mask for PCNT_FREEZE */ + +#define PCNT_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _PCNT_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for PCNT_REGFREEZE */ +#define _PCNT_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for PCNT_REGFREEZE */ +#define _PCNT_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_FREEZE */ +#define _PCNT_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for PCNT_FREEZE */ +#define _PCNT_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for PCNT_FREEZE */ +#define PCNT_FREEZE_REGFREEZE_DEFAULT (_PCNT_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_FREEZE */ +#define PCNT_FREEZE_REGFREEZE_UPDATE (_PCNT_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for PCNT_FREEZE */ +#define PCNT_FREEZE_REGFREEZE_FREEZE (_PCNT_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for PCNT_FREEZE */ + +/* Bit fields for PCNT SYNCBUSY */ + +#define _PCNT_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for PCNT_SYNCBUSY */ +#define _PCNT_SYNCBUSY_MASK 0x00000007UL /* Mask for PCNT_SYNCBUSY */ + +#define PCNT_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _PCNT_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for PCNT_CTRL */ +#define _PCNT_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for PCNT_CTRL */ +#define _PCNT_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_SYNCBUSY */ +#define PCNT_SYNCBUSY_CTRL_DEFAULT (_PCNT_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_SYNCBUSY */ +#define PCNT_SYNCBUSY_CMD (0x1UL << 1) /* CMD Register Busy */ +#define _PCNT_SYNCBUSY_CMD_SHIFT 1 /* Shift value for PCNT_CMD */ +#define _PCNT_SYNCBUSY_CMD_MASK 0x2UL /* Bit mask for PCNT_CMD */ +#define _PCNT_SYNCBUSY_CMD_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_SYNCBUSY */ +#define PCNT_SYNCBUSY_CMD_DEFAULT (_PCNT_SYNCBUSY_CMD_DEFAULT << 1) /* Shifted mode DEFAULT for PCNT_SYNCBUSY */ +#define PCNT_SYNCBUSY_TOPB (0x1UL << 2) /* TOPB Register Busy */ +#define _PCNT_SYNCBUSY_TOPB_SHIFT 2 /* Shift value for PCNT_TOPB */ +#define _PCNT_SYNCBUSY_TOPB_MASK 0x4UL /* Bit mask for PCNT_TOPB */ +#define _PCNT_SYNCBUSY_TOPB_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_SYNCBUSY */ +#define PCNT_SYNCBUSY_TOPB_DEFAULT (_PCNT_SYNCBUSY_TOPB_DEFAULT << 2) /* Shifted mode DEFAULT for PCNT_SYNCBUSY */ + +/* Bit fields for PCNT AUXCNT */ + +#define _PCNT_AUXCNT_RESETVALUE 0x00000000UL /* Default value for PCNT_AUXCNT */ +#define _PCNT_AUXCNT_MASK 0x0000FFFFUL /* Mask for PCNT_AUXCNT */ + +#define _PCNT_AUXCNT_AUXCNT_SHIFT 0 /* Shift value for PCNT_AUXCNT */ +#define _PCNT_AUXCNT_AUXCNT_MASK 0xFFFFUL /* Bit mask for PCNT_AUXCNT */ +#define _PCNT_AUXCNT_AUXCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_AUXCNT */ +#define PCNT_AUXCNT_AUXCNT_DEFAULT (_PCNT_AUXCNT_AUXCNT_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_AUXCNT */ + +/* Bit fields for PCNT INPUT */ + +#define _PCNT_INPUT_RESETVALUE 0x00000000UL /* Default value for PCNT_INPUT */ +#define _PCNT_INPUT_MASK 0x000007DFUL /* Mask for PCNT_INPUT */ + +#define _PCNT_INPUT_S0PRSSEL_SHIFT 0 /* Shift value for PCNT_S0PRSSEL */ +#define _PCNT_INPUT_S0PRSSEL_MASK 0xFUL /* Bit mask for PCNT_S0PRSSEL */ +#define _PCNT_INPUT_S0PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for PCNT_INPUT */ +#define _PCNT_INPUT_S0PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_DEFAULT (_PCNT_INPUT_S0PRSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH0 (_PCNT_INPUT_S0PRSSEL_PRSCH0 << 0) /* Shifted mode PRSCH0 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH1 (_PCNT_INPUT_S0PRSSEL_PRSCH1 << 0) /* Shifted mode PRSCH1 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH2 (_PCNT_INPUT_S0PRSSEL_PRSCH2 << 0) /* Shifted mode PRSCH2 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH3 (_PCNT_INPUT_S0PRSSEL_PRSCH3 << 0) /* Shifted mode PRSCH3 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH4 (_PCNT_INPUT_S0PRSSEL_PRSCH4 << 0) /* Shifted mode PRSCH4 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH5 (_PCNT_INPUT_S0PRSSEL_PRSCH5 << 0) /* Shifted mode PRSCH5 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH6 (_PCNT_INPUT_S0PRSSEL_PRSCH6 << 0) /* Shifted mode PRSCH6 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH7 (_PCNT_INPUT_S0PRSSEL_PRSCH7 << 0) /* Shifted mode PRSCH7 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH8 (_PCNT_INPUT_S0PRSSEL_PRSCH8 << 0) /* Shifted mode PRSCH8 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH9 (_PCNT_INPUT_S0PRSSEL_PRSCH9 << 0) /* Shifted mode PRSCH9 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH10 (_PCNT_INPUT_S0PRSSEL_PRSCH10 << 0) /* Shifted mode PRSCH10 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSSEL_PRSCH11 (_PCNT_INPUT_S0PRSSEL_PRSCH11 << 0) /* Shifted mode PRSCH11 for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSEN (0x1UL << 4) /* S0IN PRS Enable */ +#define _PCNT_INPUT_S0PRSEN_SHIFT 4 /* Shift value for PCNT_S0PRSEN */ +#define _PCNT_INPUT_S0PRSEN_MASK 0x10UL /* Bit mask for PCNT_S0PRSEN */ +#define _PCNT_INPUT_S0PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_INPUT */ +#define PCNT_INPUT_S0PRSEN_DEFAULT (_PCNT_INPUT_S0PRSEN_DEFAULT << 4) /* Shifted mode DEFAULT for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_SHIFT 6 /* Shift value for PCNT_S1PRSSEL */ +#define _PCNT_INPUT_S1PRSSEL_MASK 0x3C0UL /* Bit mask for PCNT_S1PRSSEL */ +#define _PCNT_INPUT_S1PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for PCNT_INPUT */ +#define _PCNT_INPUT_S1PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_DEFAULT (_PCNT_INPUT_S1PRSSEL_DEFAULT << 6) /* Shifted mode DEFAULT for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH0 (_PCNT_INPUT_S1PRSSEL_PRSCH0 << 6) /* Shifted mode PRSCH0 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH1 (_PCNT_INPUT_S1PRSSEL_PRSCH1 << 6) /* Shifted mode PRSCH1 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH2 (_PCNT_INPUT_S1PRSSEL_PRSCH2 << 6) /* Shifted mode PRSCH2 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH3 (_PCNT_INPUT_S1PRSSEL_PRSCH3 << 6) /* Shifted mode PRSCH3 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH4 (_PCNT_INPUT_S1PRSSEL_PRSCH4 << 6) /* Shifted mode PRSCH4 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH5 (_PCNT_INPUT_S1PRSSEL_PRSCH5 << 6) /* Shifted mode PRSCH5 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH6 (_PCNT_INPUT_S1PRSSEL_PRSCH6 << 6) /* Shifted mode PRSCH6 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH7 (_PCNT_INPUT_S1PRSSEL_PRSCH7 << 6) /* Shifted mode PRSCH7 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH8 (_PCNT_INPUT_S1PRSSEL_PRSCH8 << 6) /* Shifted mode PRSCH8 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH9 (_PCNT_INPUT_S1PRSSEL_PRSCH9 << 6) /* Shifted mode PRSCH9 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH10 (_PCNT_INPUT_S1PRSSEL_PRSCH10 << 6) /* Shifted mode PRSCH10 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSSEL_PRSCH11 (_PCNT_INPUT_S1PRSSEL_PRSCH11 << 6) /* Shifted mode PRSCH11 for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSEN (0x1UL << 10) /* S1IN PRS Enable */ +#define _PCNT_INPUT_S1PRSEN_SHIFT 10 /* Shift value for PCNT_S1PRSEN */ +#define _PCNT_INPUT_S1PRSEN_MASK 0x400UL /* Bit mask for PCNT_S1PRSEN */ +#define _PCNT_INPUT_S1PRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PCNT_INPUT */ +#define PCNT_INPUT_S1PRSEN_DEFAULT (_PCNT_INPUT_S1PRSEN_DEFAULT << 10) /* Shifted mode DEFAULT for PCNT_INPUT */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PCNT_H*/ diff --git a/arch/arm/src/efm32/chip/efm32_prs.h b/arch/arm/src/efm32/chip/efm32_prs.h new file mode 100644 index 0000000000000000000000000000000000000000..b0d8d6e016100cc2bafd2b0eb24fd1adf3ca2689 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_prs.h @@ -0,0 +1,610 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_prs.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PRS_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PRS_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* PRS Register Offsets ********************************************************************************************************/ + +#define EFM32_PRS_SWPULSE_OFFSET 0x0000 /* Software Pulse Register */ +#define EFM32_PRS_SWLEVEL_OFFSET 0x0004 /* Software Level Register */ +#define EFM32_PRS_ROUTE_OFFSET 0x0008 /* I/O Routing Register + +#define EFM32_PRS_CH_CTRL_OFFSET(n) (0x0010 + ((n) << 2)) +#define EFM32_PRS_CH0_CTRL_OFFSET 0x0010 /* Channel 0 Control Register */ +#define EFM32_PRS_CH1_CTRL_OFFSET 0x0014 /* Channel 1 Control Register */ +#define EFM32_PRS_CH2_CTRL_OFFSET 0x0018 /* Channel 2 Control Register */ +#define EFM32_PRS_CH3_CTRL_OFFSET 0x001c /* Channel 3 Control Register */ +#define EFM32_PRS_CH4_CTRL_OFFSET 0x0010 /* Channel 4 Control Register */ +#define EFM32_PRS_CH5_CTRL_OFFSET 0x0014 /* Channel 5 Control Register */ +#define EFM32_PRS_CH6_CTRL_OFFSET 0x0018 /* Channel 6 Control Register */ +#define EFM32_PRS_CH7_CTRL_OFFSET 0x001c /* Channel 7 Control Register */ +#define EFM32_PRS_CH8_CTRL_OFFSET 0x0010 /* Channel 8 Control Register */ +#define EFM32_PRS_CH9_CTRL_OFFSET 0x0014 /* Channel 9 Control Register */ +#define EFM32_PRS_CH10_CTRL_OFFSET 0x0018 /* Channel 10 Control Register */ +#define EFM32_PRS_CH11_CTRL_OFFSET 0x003c /* Channel 11 Control Register */ + +/* PRS Register Addresses ******************************************************************************************************/ + +#define EFM32_PRS_SWPULSE (EFM32_PRS_BASE+EFM32_PRS_SWPULSE_OFFSET) +#define EFM32_PRS_SWLEVEL (EFM32_PRS_BASE+EFM32_PRS_SWLEVEL_OFFSET) +#define EFM32_PRS_ROUTE (EFM32_PRS_BASE+EFM32_PRS_ROUTE_OFFSET) + +#define EFM32_PRS_CH_CTRL(n) (EFM32_PRS_BASE+EFM32_PRS_CH_CTRL_OFFSET(n)) +#define EFM32_PRS_CH0_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH0_CTRL_OFFSET) +#define EFM32_PRS_CH1_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH1_CTRL_OFFSET) +#define EFM32_PRS_CH2_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH2_CTRL_OFFSET) +#define EFM32_PRS_CH3_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH3_CTRL_OFFSET) +#define EFM32_PRS_CH4_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH4_CTRL_OFFSET) +#define EFM32_PRS_CH5_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH5_CTRL_OFFSET) +#define EFM32_PRS_CH6_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH6_CTRL_OFFSET) +#define EFM32_PRS_CH7_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH7_CTRL_OFFSET) +#define EFM32_PRS_CH8_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH8_CTRL_OFFSET) +#define EFM32_PRS_CH9_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH9_CTRL_OFFSET) +#define EFM32_PRS_CH10_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH10_CTRL_OFFSET) +#define EFM32_PRS_CH11_CTRL (EFM32_PRS_BASE+EFM32_PRS_CH11_CTRL_OFFSET) + +/* PRS Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for PRS SWPULSE */ + +#define _PRS_SWPULSE_RESETVALUE 0x00000000UL /* Default value for PRS_SWPULSE */ +#define _PRS_SWPULSE_MASK 0x00000FFFUL /* Mask for PRS_SWPULSE */ + +#define PRS_SWPULSE_CH0PULSE (0x1UL << 0) /* Channel 0 Pulse Generation */ +#define _PRS_SWPULSE_CH0PULSE_SHIFT 0 /* Shift value for PRS_CH0PULSE */ +#define _PRS_SWPULSE_CH0PULSE_MASK 0x1UL /* Bit mask for PRS_CH0PULSE */ +#define _PRS_SWPULSE_CH0PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH0PULSE_DEFAULT (_PRS_SWPULSE_CH0PULSE_DEFAULT << 0) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH1PULSE (0x1UL << 1) /* Channel 1 Pulse Generation */ +#define _PRS_SWPULSE_CH1PULSE_SHIFT 1 /* Shift value for PRS_CH1PULSE */ +#define _PRS_SWPULSE_CH1PULSE_MASK 0x2UL /* Bit mask for PRS_CH1PULSE */ +#define _PRS_SWPULSE_CH1PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH1PULSE_DEFAULT (_PRS_SWPULSE_CH1PULSE_DEFAULT << 1) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH2PULSE (0x1UL << 2) /* Channel 2 Pulse Generation */ +#define _PRS_SWPULSE_CH2PULSE_SHIFT 2 /* Shift value for PRS_CH2PULSE */ +#define _PRS_SWPULSE_CH2PULSE_MASK 0x4UL /* Bit mask for PRS_CH2PULSE */ +#define _PRS_SWPULSE_CH2PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH2PULSE_DEFAULT (_PRS_SWPULSE_CH2PULSE_DEFAULT << 2) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH3PULSE (0x1UL << 3) /* Channel 3 Pulse Generation */ +#define _PRS_SWPULSE_CH3PULSE_SHIFT 3 /* Shift value for PRS_CH3PULSE */ +#define _PRS_SWPULSE_CH3PULSE_MASK 0x8UL /* Bit mask for PRS_CH3PULSE */ +#define _PRS_SWPULSE_CH3PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH3PULSE_DEFAULT (_PRS_SWPULSE_CH3PULSE_DEFAULT << 3) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH4PULSE (0x1UL << 4) /* Channel 4 Pulse Generation */ +#define _PRS_SWPULSE_CH4PULSE_SHIFT 4 /* Shift value for PRS_CH4PULSE */ +#define _PRS_SWPULSE_CH4PULSE_MASK 0x10UL /* Bit mask for PRS_CH4PULSE */ +#define _PRS_SWPULSE_CH4PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH4PULSE_DEFAULT (_PRS_SWPULSE_CH4PULSE_DEFAULT << 4) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH5PULSE (0x1UL << 5) /* Channel 5 Pulse Generation */ +#define _PRS_SWPULSE_CH5PULSE_SHIFT 5 /* Shift value for PRS_CH5PULSE */ +#define _PRS_SWPULSE_CH5PULSE_MASK 0x20UL /* Bit mask for PRS_CH5PULSE */ +#define _PRS_SWPULSE_CH5PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH5PULSE_DEFAULT (_PRS_SWPULSE_CH5PULSE_DEFAULT << 5) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH6PULSE (0x1UL << 6) /* Channel 6 Pulse Generation */ +#define _PRS_SWPULSE_CH6PULSE_SHIFT 6 /* Shift value for PRS_CH6PULSE */ +#define _PRS_SWPULSE_CH6PULSE_MASK 0x40UL /* Bit mask for PRS_CH6PULSE */ +#define _PRS_SWPULSE_CH6PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH6PULSE_DEFAULT (_PRS_SWPULSE_CH6PULSE_DEFAULT << 6) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH7PULSE (0x1UL << 7) /* Channel 7 Pulse Generation */ +#define _PRS_SWPULSE_CH7PULSE_SHIFT 7 /* Shift value for PRS_CH7PULSE */ +#define _PRS_SWPULSE_CH7PULSE_MASK 0x80UL /* Bit mask for PRS_CH7PULSE */ +#define _PRS_SWPULSE_CH7PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH7PULSE_DEFAULT (_PRS_SWPULSE_CH7PULSE_DEFAULT << 7) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH8PULSE (0x1UL << 8) /* Channel 8 Pulse Generation */ +#define _PRS_SWPULSE_CH8PULSE_SHIFT 8 /* Shift value for PRS_CH8PULSE */ +#define _PRS_SWPULSE_CH8PULSE_MASK 0x100UL /* Bit mask for PRS_CH8PULSE */ +#define _PRS_SWPULSE_CH8PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH8PULSE_DEFAULT (_PRS_SWPULSE_CH8PULSE_DEFAULT << 8) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH9PULSE (0x1UL << 9) /* Channel 9 Pulse Generation */ +#define _PRS_SWPULSE_CH9PULSE_SHIFT 9 /* Shift value for PRS_CH9PULSE */ +#define _PRS_SWPULSE_CH9PULSE_MASK 0x200UL /* Bit mask for PRS_CH9PULSE */ +#define _PRS_SWPULSE_CH9PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH9PULSE_DEFAULT (_PRS_SWPULSE_CH9PULSE_DEFAULT << 9) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH10PULSE (0x1UL << 10) /* Channel 10 Pulse Generation */ +#define _PRS_SWPULSE_CH10PULSE_SHIFT 10 /* Shift value for PRS_CH10PULSE */ +#define _PRS_SWPULSE_CH10PULSE_MASK 0x400UL /* Bit mask for PRS_CH10PULSE */ +#define _PRS_SWPULSE_CH10PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH10PULSE_DEFAULT (_PRS_SWPULSE_CH10PULSE_DEFAULT << 10) /* Shifted mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH11PULSE (0x1UL << 11) /* Channel 11 Pulse Generation */ +#define _PRS_SWPULSE_CH11PULSE_SHIFT 11 /* Shift value for PRS_CH11PULSE */ +#define _PRS_SWPULSE_CH11PULSE_MASK 0x800UL /* Bit mask for PRS_CH11PULSE */ +#define _PRS_SWPULSE_CH11PULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWPULSE */ +#define PRS_SWPULSE_CH11PULSE_DEFAULT (_PRS_SWPULSE_CH11PULSE_DEFAULT << 11) /* Shifted mode DEFAULT for PRS_SWPULSE */ + +/* Bit fields for PRS SWLEVEL */ + +#define _PRS_SWLEVEL_RESETVALUE 0x00000000UL /* Default value for PRS_SWLEVEL */ +#define _PRS_SWLEVEL_MASK 0x00000FFFUL /* Mask for PRS_SWLEVEL */ + +#define PRS_SWLEVEL_CH0LEVEL (0x1UL << 0) /* Channel 0 Software Level */ +#define _PRS_SWLEVEL_CH0LEVEL_SHIFT 0 /* Shift value for PRS_CH0LEVEL */ +#define _PRS_SWLEVEL_CH0LEVEL_MASK 0x1UL /* Bit mask for PRS_CH0LEVEL */ +#define _PRS_SWLEVEL_CH0LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH0LEVEL_DEFAULT (_PRS_SWLEVEL_CH0LEVEL_DEFAULT << 0) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH1LEVEL (0x1UL << 1) /* Channel 1 Software Level */ +#define _PRS_SWLEVEL_CH1LEVEL_SHIFT 1 /* Shift value for PRS_CH1LEVEL */ +#define _PRS_SWLEVEL_CH1LEVEL_MASK 0x2UL /* Bit mask for PRS_CH1LEVEL */ +#define _PRS_SWLEVEL_CH1LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH1LEVEL_DEFAULT (_PRS_SWLEVEL_CH1LEVEL_DEFAULT << 1) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH2LEVEL (0x1UL << 2) /* Channel 2 Software Level */ +#define _PRS_SWLEVEL_CH2LEVEL_SHIFT 2 /* Shift value for PRS_CH2LEVEL */ +#define _PRS_SWLEVEL_CH2LEVEL_MASK 0x4UL /* Bit mask for PRS_CH2LEVEL */ +#define _PRS_SWLEVEL_CH2LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH2LEVEL_DEFAULT (_PRS_SWLEVEL_CH2LEVEL_DEFAULT << 2) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH3LEVEL (0x1UL << 3) /* Channel 3 Software Level */ +#define _PRS_SWLEVEL_CH3LEVEL_SHIFT 3 /* Shift value for PRS_CH3LEVEL */ +#define _PRS_SWLEVEL_CH3LEVEL_MASK 0x8UL /* Bit mask for PRS_CH3LEVEL */ +#define _PRS_SWLEVEL_CH3LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH3LEVEL_DEFAULT (_PRS_SWLEVEL_CH3LEVEL_DEFAULT << 3) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH4LEVEL (0x1UL << 4) /* Channel 4 Software Level */ +#define _PRS_SWLEVEL_CH4LEVEL_SHIFT 4 /* Shift value for PRS_CH4LEVEL */ +#define _PRS_SWLEVEL_CH4LEVEL_MASK 0x10UL /* Bit mask for PRS_CH4LEVEL */ +#define _PRS_SWLEVEL_CH4LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH4LEVEL_DEFAULT (_PRS_SWLEVEL_CH4LEVEL_DEFAULT << 4) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH5LEVEL (0x1UL << 5) /* Channel 5 Software Level */ +#define _PRS_SWLEVEL_CH5LEVEL_SHIFT 5 /* Shift value for PRS_CH5LEVEL */ +#define _PRS_SWLEVEL_CH5LEVEL_MASK 0x20UL /* Bit mask for PRS_CH5LEVEL */ +#define _PRS_SWLEVEL_CH5LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH5LEVEL_DEFAULT (_PRS_SWLEVEL_CH5LEVEL_DEFAULT << 5) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH6LEVEL (0x1UL << 6) /* Channel 6 Software Level */ +#define _PRS_SWLEVEL_CH6LEVEL_SHIFT 6 /* Shift value for PRS_CH6LEVEL */ +#define _PRS_SWLEVEL_CH6LEVEL_MASK 0x40UL /* Bit mask for PRS_CH6LEVEL */ +#define _PRS_SWLEVEL_CH6LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH6LEVEL_DEFAULT (_PRS_SWLEVEL_CH6LEVEL_DEFAULT << 6) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH7LEVEL (0x1UL << 7) /* Channel 7 Software Level */ +#define _PRS_SWLEVEL_CH7LEVEL_SHIFT 7 /* Shift value for PRS_CH7LEVEL */ +#define _PRS_SWLEVEL_CH7LEVEL_MASK 0x80UL /* Bit mask for PRS_CH7LEVEL */ +#define _PRS_SWLEVEL_CH7LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH7LEVEL_DEFAULT (_PRS_SWLEVEL_CH7LEVEL_DEFAULT << 7) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH8LEVEL (0x1UL << 8) /* Channel 8 Software Level */ +#define _PRS_SWLEVEL_CH8LEVEL_SHIFT 8 /* Shift value for PRS_CH8LEVEL */ +#define _PRS_SWLEVEL_CH8LEVEL_MASK 0x100UL /* Bit mask for PRS_CH8LEVEL */ +#define _PRS_SWLEVEL_CH8LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH8LEVEL_DEFAULT (_PRS_SWLEVEL_CH8LEVEL_DEFAULT << 8) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH9LEVEL (0x1UL << 9) /* Channel 9 Software Level */ +#define _PRS_SWLEVEL_CH9LEVEL_SHIFT 9 /* Shift value for PRS_CH9LEVEL */ +#define _PRS_SWLEVEL_CH9LEVEL_MASK 0x200UL /* Bit mask for PRS_CH9LEVEL */ +#define _PRS_SWLEVEL_CH9LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH9LEVEL_DEFAULT (_PRS_SWLEVEL_CH9LEVEL_DEFAULT << 9) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH10LEVEL (0x1UL << 10) /* Channel 10 Software Level */ +#define _PRS_SWLEVEL_CH10LEVEL_SHIFT 10 /* Shift value for PRS_CH10LEVEL */ +#define _PRS_SWLEVEL_CH10LEVEL_MASK 0x400UL /* Bit mask for PRS_CH10LEVEL */ +#define _PRS_SWLEVEL_CH10LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH10LEVEL_DEFAULT (_PRS_SWLEVEL_CH10LEVEL_DEFAULT << 10) /* Shifted mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH11LEVEL (0x1UL << 11) /* Channel 11 Software Level */ +#define _PRS_SWLEVEL_CH11LEVEL_SHIFT 11 /* Shift value for PRS_CH11LEVEL */ +#define _PRS_SWLEVEL_CH11LEVEL_MASK 0x800UL /* Bit mask for PRS_CH11LEVEL */ +#define _PRS_SWLEVEL_CH11LEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_SWLEVEL */ +#define PRS_SWLEVEL_CH11LEVEL_DEFAULT (_PRS_SWLEVEL_CH11LEVEL_DEFAULT << 11) /* Shifted mode DEFAULT for PRS_SWLEVEL */ + +/* Bit fields for PRS ROUTE */ + +#define _PRS_ROUTE_RESETVALUE 0x00000000UL /* Default value for PRS_ROUTE */ +#define _PRS_ROUTE_MASK 0x0000070FUL /* Mask for PRS_ROUTE */ + +#define PRS_ROUTE_CH0PEN (0x1UL << 0) /* CH0 Pin Enable */ +#define _PRS_ROUTE_CH0PEN_SHIFT 0 /* Shift value for PRS_CH0PEN */ +#define _PRS_ROUTE_CH0PEN_MASK 0x1UL /* Bit mask for PRS_CH0PEN */ +#define _PRS_ROUTE_CH0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH0PEN_DEFAULT (_PRS_ROUTE_CH0PEN_DEFAULT << 0) /* Shifted mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH1PEN (0x1UL << 1) /* CH1 Pin Enable */ +#define _PRS_ROUTE_CH1PEN_SHIFT 1 /* Shift value for PRS_CH1PEN */ +#define _PRS_ROUTE_CH1PEN_MASK 0x2UL /* Bit mask for PRS_CH1PEN */ +#define _PRS_ROUTE_CH1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH1PEN_DEFAULT (_PRS_ROUTE_CH1PEN_DEFAULT << 1) /* Shifted mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH2PEN (0x1UL << 2) /* CH2 Pin Enable */ +#define _PRS_ROUTE_CH2PEN_SHIFT 2 /* Shift value for PRS_CH2PEN */ +#define _PRS_ROUTE_CH2PEN_MASK 0x4UL /* Bit mask for PRS_CH2PEN */ +#define _PRS_ROUTE_CH2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH2PEN_DEFAULT (_PRS_ROUTE_CH2PEN_DEFAULT << 2) /* Shifted mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH3PEN (0x1UL << 3) /* CH3 Pin Enable */ +#define _PRS_ROUTE_CH3PEN_SHIFT 3 /* Shift value for PRS_CH3PEN */ +#define _PRS_ROUTE_CH3PEN_MASK 0x8UL /* Bit mask for PRS_CH3PEN */ +#define _PRS_ROUTE_CH3PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_CH3PEN_DEFAULT (_PRS_ROUTE_CH3PEN_DEFAULT << 3) /* Shifted mode DEFAULT for PRS_ROUTE */ +#define _PRS_ROUTE_LOCATION_SHIFT 8 /* Shift value for PRS_LOCATION */ +#define _PRS_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for PRS_LOCATION */ +#define _PRS_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for PRS_ROUTE */ +#define _PRS_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_ROUTE */ +#define _PRS_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for PRS_ROUTE */ +#define PRS_ROUTE_LOCATION_LOC0 (_PRS_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for PRS_ROUTE */ +#define PRS_ROUTE_LOCATION_DEFAULT (_PRS_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for PRS_ROUTE */ +#define PRS_ROUTE_LOCATION_LOC1 (_PRS_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for PRS_ROUTE */ + +/* Bit fields for PRS CH_CTRL */ + +#define _PRS_CH_CTRL_RESETVALUE 0x00000000UL /* Default value for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_MASK 0x133F0007UL /* Mask for PRS_CH_CTRL */ + +#define _PRS_CH_CTRL_SIGSEL_SHIFT 0 /* Shift value for PRS_SIGSEL */ +#define _PRS_CH_CTRL_SIGSEL_MASK 0x7UL /* Bit mask for PRS_SIGSEL */ +#define _PRS_CH_CTRL_SIGSEL_VCMPOUT 0x00000000UL /* Mode VCMPOUT for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_ACMP0OUT 0x00000000UL /* Mode ACMP0OUT for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_ACMP1OUT 0x00000000UL /* Mode ACMP1OUT for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_DAC0CH0 0x00000000UL /* Mode DAC0CH0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_ADC0SINGLE 0x00000000UL /* Mode ADC0SINGLE for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART0IRTX 0x00000000UL /* Mode USART0IRTX for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER0UF 0x00000000UL /* Mode TIMER0UF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER1UF 0x00000000UL /* Mode TIMER1UF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER2UF 0x00000000UL /* Mode TIMER2UF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER3UF 0x00000000UL /* Mode TIMER3UF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USBSOF 0x00000000UL /* Mode USBSOF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_RTCOF 0x00000000UL /* Mode RTCOF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN0 0x00000000UL /* Mode GPIOPIN0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN8 0x00000000UL /* Mode GPIOPIN8 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LETIMER0CH0 0x00000000UL /* Mode LETIMER0CH0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_BURTCOF 0x00000000UL /* Mode BURTCOF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES0 0x00000000UL /* Mode LESENSESCANRES0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES8 0x00000000UL /* Mode LESENSESCANRES8 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSEDEC0 0x00000000UL /* Mode LESENSEDEC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_DAC0CH1 0x00000001UL /* Mode DAC0CH1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_ADC0SCAN 0x00000001UL /* Mode ADC0SCAN for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART0TXC 0x00000001UL /* Mode USART0TXC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART1TXC 0x00000001UL /* Mode USART1TXC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART2TXC 0x00000001UL /* Mode USART2TXC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER0OF 0x00000001UL /* Mode TIMER0OF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER1OF 0x00000001UL /* Mode TIMER1OF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER2OF 0x00000001UL /* Mode TIMER2OF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER3OF 0x00000001UL /* Mode TIMER3OF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USBSOFSR 0x00000001UL /* Mode USBSOFSR for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_RTCCOMP0 0x00000001UL /* Mode RTCCOMP0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_UART0TXC 0x00000001UL /* Mode UART0TXC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_UART1TXC 0x00000001UL /* Mode UART1TXC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN1 0x00000001UL /* Mode GPIOPIN1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN9 0x00000001UL /* Mode GPIOPIN9 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LETIMER0CH1 0x00000001UL /* Mode LETIMER0CH1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_BURTCCOMP0 0x00000001UL /* Mode BURTCCOMP0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES1 0x00000001UL /* Mode LESENSESCANRES1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES9 0x00000001UL /* Mode LESENSESCANRES9 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSEDEC1 0x00000001UL /* Mode LESENSEDEC1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART0RXDATAV 0x00000002UL /* Mode USART0RXDATAV for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART1RXDATAV 0x00000002UL /* Mode USART1RXDATAV for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_USART2RXDATAV 0x00000002UL /* Mode USART2RXDATAV for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER0CC0 0x00000002UL /* Mode TIMER0CC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER1CC0 0x00000002UL /* Mode TIMER1CC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER2CC0 0x00000002UL /* Mode TIMER2CC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER3CC0 0x00000002UL /* Mode TIMER3CC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_RTCCOMP1 0x00000002UL /* Mode RTCCOMP1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_UART0RXDATAV 0x00000002UL /* Mode UART0RXDATAV for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_UART1RXDATAV 0x00000002UL /* Mode UART1RXDATAV for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN2 0x00000002UL /* Mode GPIOPIN2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN10 0x00000002UL /* Mode GPIOPIN10 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES2 0x00000002UL /* Mode LESENSESCANRES2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES10 0x00000002UL /* Mode LESENSESCANRES10 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSEDEC2 0x00000002UL /* Mode LESENSEDEC2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER0CC1 0x00000003UL /* Mode TIMER0CC1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER1CC1 0x00000003UL /* Mode TIMER1CC1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER2CC1 0x00000003UL /* Mode TIMER2CC1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER3CC1 0x00000003UL /* Mode TIMER3CC1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN3 0x00000003UL /* Mode GPIOPIN3 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN11 0x00000003UL /* Mode GPIOPIN11 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES3 0x00000003UL /* Mode LESENSESCANRES3 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES11 0x00000003UL /* Mode LESENSESCANRES11 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER0CC2 0x00000004UL /* Mode TIMER0CC2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER1CC2 0x00000004UL /* Mode TIMER1CC2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER2CC2 0x00000004UL /* Mode TIMER2CC2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_TIMER3CC2 0x00000004UL /* Mode TIMER3CC2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN4 0x00000004UL /* Mode GPIOPIN4 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN12 0x00000004UL /* Mode GPIOPIN12 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES4 0x00000004UL /* Mode LESENSESCANRES4 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES12 0x00000004UL /* Mode LESENSESCANRES12 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN5 0x00000005UL /* Mode GPIOPIN5 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN13 0x00000005UL /* Mode GPIOPIN13 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES5 0x00000005UL /* Mode LESENSESCANRES5 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES13 0x00000005UL /* Mode LESENSESCANRES13 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN6 0x00000006UL /* Mode GPIOPIN6 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN14 0x00000006UL /* Mode GPIOPIN14 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES6 0x00000006UL /* Mode LESENSESCANRES6 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES14 0x00000006UL /* Mode LESENSESCANRES14 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN7 0x00000007UL /* Mode GPIOPIN7 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_GPIOPIN15 0x00000007UL /* Mode GPIOPIN15 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES7 0x00000007UL /* Mode LESENSESCANRES7 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SIGSEL_LESENSESCANRES15 0x00000007UL /* Mode LESENSESCANRES15 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_VCMPOUT (_PRS_CH_CTRL_SIGSEL_VCMPOUT << 0) /* Shifted mode VCMPOUT for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_ACMP0OUT (_PRS_CH_CTRL_SIGSEL_ACMP0OUT << 0) /* Shifted mode ACMP0OUT for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_ACMP1OUT (_PRS_CH_CTRL_SIGSEL_ACMP1OUT << 0) /* Shifted mode ACMP1OUT for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_DAC0CH0 (_PRS_CH_CTRL_SIGSEL_DAC0CH0 << 0) /* Shifted mode DAC0CH0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_ADC0SINGLE (_PRS_CH_CTRL_SIGSEL_ADC0SINGLE << 0) /* Shifted mode ADC0SINGLE for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART0IRTX (_PRS_CH_CTRL_SIGSEL_USART0IRTX << 0) /* Shifted mode USART0IRTX for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER0UF (_PRS_CH_CTRL_SIGSEL_TIMER0UF << 0) /* Shifted mode TIMER0UF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER1UF (_PRS_CH_CTRL_SIGSEL_TIMER1UF << 0) /* Shifted mode TIMER1UF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER2UF (_PRS_CH_CTRL_SIGSEL_TIMER2UF << 0) /* Shifted mode TIMER2UF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER3UF (_PRS_CH_CTRL_SIGSEL_TIMER3UF << 0) /* Shifted mode TIMER3UF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USBSOF (_PRS_CH_CTRL_SIGSEL_USBSOF << 0) /* Shifted mode USBSOF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_RTCOF (_PRS_CH_CTRL_SIGSEL_RTCOF << 0) /* Shifted mode RTCOF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN0 (_PRS_CH_CTRL_SIGSEL_GPIOPIN0 << 0) /* Shifted mode GPIOPIN0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN8 (_PRS_CH_CTRL_SIGSEL_GPIOPIN8 << 0) /* Shifted mode GPIOPIN8 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LETIMER0CH0 (_PRS_CH_CTRL_SIGSEL_LETIMER0CH0 << 0) /* Shifted mode LETIMER0CH0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_BURTCOF (_PRS_CH_CTRL_SIGSEL_BURTCOF << 0) /* Shifted mode BURTCOF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES0 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES0 << 0) /* Shifted mode LESENSESCANRES0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES8 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES8 << 0) /* Shifted mode LESENSESCANRES8 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC0 (_PRS_CH_CTRL_SIGSEL_LESENSEDEC0 << 0) /* Shifted mode LESENSEDEC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_DAC0CH1 (_PRS_CH_CTRL_SIGSEL_DAC0CH1 << 0) /* Shifted mode DAC0CH1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_ADC0SCAN (_PRS_CH_CTRL_SIGSEL_ADC0SCAN << 0) /* Shifted mode ADC0SCAN for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART0TXC (_PRS_CH_CTRL_SIGSEL_USART0TXC << 0) /* Shifted mode USART0TXC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART1TXC (_PRS_CH_CTRL_SIGSEL_USART1TXC << 0) /* Shifted mode USART1TXC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART2TXC (_PRS_CH_CTRL_SIGSEL_USART2TXC << 0) /* Shifted mode USART2TXC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER0OF (_PRS_CH_CTRL_SIGSEL_TIMER0OF << 0) /* Shifted mode TIMER0OF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER1OF (_PRS_CH_CTRL_SIGSEL_TIMER1OF << 0) /* Shifted mode TIMER1OF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER2OF (_PRS_CH_CTRL_SIGSEL_TIMER2OF << 0) /* Shifted mode TIMER2OF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER3OF (_PRS_CH_CTRL_SIGSEL_TIMER3OF << 0) /* Shifted mode TIMER3OF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USBSOFSR (_PRS_CH_CTRL_SIGSEL_USBSOFSR << 0) /* Shifted mode USBSOFSR for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_RTCCOMP0 (_PRS_CH_CTRL_SIGSEL_RTCCOMP0 << 0) /* Shifted mode RTCCOMP0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_UART0TXC (_PRS_CH_CTRL_SIGSEL_UART0TXC << 0) /* Shifted mode UART0TXC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_UART1TXC (_PRS_CH_CTRL_SIGSEL_UART1TXC << 0) /* Shifted mode UART1TXC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN1 (_PRS_CH_CTRL_SIGSEL_GPIOPIN1 << 0) /* Shifted mode GPIOPIN1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN9 (_PRS_CH_CTRL_SIGSEL_GPIOPIN9 << 0) /* Shifted mode GPIOPIN9 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LETIMER0CH1 (_PRS_CH_CTRL_SIGSEL_LETIMER0CH1 << 0) /* Shifted mode LETIMER0CH1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_BURTCCOMP0 (_PRS_CH_CTRL_SIGSEL_BURTCCOMP0 << 0) /* Shifted mode BURTCCOMP0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES1 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES1 << 0) /* Shifted mode LESENSESCANRES1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES9 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES9 << 0) /* Shifted mode LESENSESCANRES9 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC1 (_PRS_CH_CTRL_SIGSEL_LESENSEDEC1 << 0) /* Shifted mode LESENSEDEC1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART0RXDATAV (_PRS_CH_CTRL_SIGSEL_USART0RXDATAV << 0) /* Shifted mode USART0RXDATAV for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART1RXDATAV (_PRS_CH_CTRL_SIGSEL_USART1RXDATAV << 0) /* Shifted mode USART1RXDATAV for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_USART2RXDATAV (_PRS_CH_CTRL_SIGSEL_USART2RXDATAV << 0) /* Shifted mode USART2RXDATAV for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER0CC0 (_PRS_CH_CTRL_SIGSEL_TIMER0CC0 << 0) /* Shifted mode TIMER0CC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER1CC0 (_PRS_CH_CTRL_SIGSEL_TIMER1CC0 << 0) /* Shifted mode TIMER1CC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER2CC0 (_PRS_CH_CTRL_SIGSEL_TIMER2CC0 << 0) /* Shifted mode TIMER2CC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER3CC0 (_PRS_CH_CTRL_SIGSEL_TIMER3CC0 << 0) /* Shifted mode TIMER3CC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_RTCCOMP1 (_PRS_CH_CTRL_SIGSEL_RTCCOMP1 << 0) /* Shifted mode RTCCOMP1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_UART0RXDATAV (_PRS_CH_CTRL_SIGSEL_UART0RXDATAV << 0) /* Shifted mode UART0RXDATAV for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_UART1RXDATAV (_PRS_CH_CTRL_SIGSEL_UART1RXDATAV << 0) /* Shifted mode UART1RXDATAV for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN2 (_PRS_CH_CTRL_SIGSEL_GPIOPIN2 << 0) /* Shifted mode GPIOPIN2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN10 (_PRS_CH_CTRL_SIGSEL_GPIOPIN10 << 0) /* Shifted mode GPIOPIN10 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES2 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES2 << 0) /* Shifted mode LESENSESCANRES2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES10 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES10 << 0) /* Shifted mode LESENSESCANRES10 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC2 (_PRS_CH_CTRL_SIGSEL_LESENSEDEC2 << 0) /* Shifted mode LESENSEDEC2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER0CC1 (_PRS_CH_CTRL_SIGSEL_TIMER0CC1 << 0) /* Shifted mode TIMER0CC1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER1CC1 (_PRS_CH_CTRL_SIGSEL_TIMER1CC1 << 0) /* Shifted mode TIMER1CC1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER2CC1 (_PRS_CH_CTRL_SIGSEL_TIMER2CC1 << 0) /* Shifted mode TIMER2CC1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER3CC1 (_PRS_CH_CTRL_SIGSEL_TIMER3CC1 << 0) /* Shifted mode TIMER3CC1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN3 (_PRS_CH_CTRL_SIGSEL_GPIOPIN3 << 0) /* Shifted mode GPIOPIN3 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN11 (_PRS_CH_CTRL_SIGSEL_GPIOPIN11 << 0) /* Shifted mode GPIOPIN11 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES3 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES3 << 0) /* Shifted mode LESENSESCANRES3 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES11 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES11 << 0) /* Shifted mode LESENSESCANRES11 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER0CC2 (_PRS_CH_CTRL_SIGSEL_TIMER0CC2 << 0) /* Shifted mode TIMER0CC2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER1CC2 (_PRS_CH_CTRL_SIGSEL_TIMER1CC2 << 0) /* Shifted mode TIMER1CC2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER2CC2 (_PRS_CH_CTRL_SIGSEL_TIMER2CC2 << 0) /* Shifted mode TIMER2CC2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_TIMER3CC2 (_PRS_CH_CTRL_SIGSEL_TIMER3CC2 << 0) /* Shifted mode TIMER3CC2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN4 (_PRS_CH_CTRL_SIGSEL_GPIOPIN4 << 0) /* Shifted mode GPIOPIN4 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN12 (_PRS_CH_CTRL_SIGSEL_GPIOPIN12 << 0) /* Shifted mode GPIOPIN12 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES4 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES4 << 0) /* Shifted mode LESENSESCANRES4 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES12 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES12 << 0) /* Shifted mode LESENSESCANRES12 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN5 (_PRS_CH_CTRL_SIGSEL_GPIOPIN5 << 0) /* Shifted mode GPIOPIN5 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN13 (_PRS_CH_CTRL_SIGSEL_GPIOPIN13 << 0) /* Shifted mode GPIOPIN13 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES5 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES5 << 0) /* Shifted mode LESENSESCANRES5 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES13 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES13 << 0) /* Shifted mode LESENSESCANRES13 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN6 (_PRS_CH_CTRL_SIGSEL_GPIOPIN6 << 0) /* Shifted mode GPIOPIN6 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN14 (_PRS_CH_CTRL_SIGSEL_GPIOPIN14 << 0) /* Shifted mode GPIOPIN14 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES6 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES6 << 0) /* Shifted mode LESENSESCANRES6 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES14 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES14 << 0) /* Shifted mode LESENSESCANRES14 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN7 (_PRS_CH_CTRL_SIGSEL_GPIOPIN7 << 0) /* Shifted mode GPIOPIN7 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_GPIOPIN15 (_PRS_CH_CTRL_SIGSEL_GPIOPIN15 << 0) /* Shifted mode GPIOPIN15 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES7 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES7 << 0) /* Shifted mode LESENSESCANRES7 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES15 (_PRS_CH_CTRL_SIGSEL_LESENSESCANRES15 << 0) /* Shifted mode LESENSESCANRES15 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_SHIFT 16 /* Shift value for PRS_SOURCESEL */ +#define _PRS_CH_CTRL_SOURCESEL_MASK 0x3F0000UL /* Bit mask for PRS_SOURCESEL */ +#define _PRS_CH_CTRL_SOURCESEL_NONE 0x00000000UL /* Mode NONE for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_VCMP 0x00000001UL /* Mode VCMP for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_ACMP0 0x00000002UL /* Mode ACMP0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_ACMP1 0x00000003UL /* Mode ACMP1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_DAC0 0x00000006UL /* Mode DAC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_ADC0 0x00000008UL /* Mode ADC0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_USART0 0x00000010UL /* Mode USART0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_USART1 0x00000011UL /* Mode USART1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_USART2 0x00000012UL /* Mode USART2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_TIMER0 0x0000001CUL /* Mode TIMER0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_TIMER1 0x0000001DUL /* Mode TIMER1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_TIMER2 0x0000001EUL /* Mode TIMER2 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_TIMER3 0x0000001FUL /* Mode TIMER3 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_USB 0x00000024UL /* Mode USB for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_RTC 0x00000028UL /* Mode RTC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_UART0 0x00000029UL /* Mode UART0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_UART1 0x0000002AUL /* Mode UART1 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_GPIOL 0x00000030UL /* Mode GPIOL for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_GPIOH 0x00000031UL /* Mode GPIOH for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_LETIMER0 0x00000034UL /* Mode LETIMER0 for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_BURTC 0x00000037UL /* Mode BURTC for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_LESENSEL 0x00000039UL /* Mode LESENSEL for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_LESENSEH 0x0000003AUL /* Mode LESENSEH for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_SOURCESEL_LESENSED 0x0000003BUL /* Mode LESENSED for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_NONE (_PRS_CH_CTRL_SOURCESEL_NONE << 16) /* Shifted mode NONE for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_VCMP (_PRS_CH_CTRL_SOURCESEL_VCMP << 16) /* Shifted mode VCMP for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_ACMP0 (_PRS_CH_CTRL_SOURCESEL_ACMP0 << 16) /* Shifted mode ACMP0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_ACMP1 (_PRS_CH_CTRL_SOURCESEL_ACMP1 << 16) /* Shifted mode ACMP1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_DAC0 (_PRS_CH_CTRL_SOURCESEL_DAC0 << 16) /* Shifted mode DAC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_ADC0 (_PRS_CH_CTRL_SOURCESEL_ADC0 << 16) /* Shifted mode ADC0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_USART0 (_PRS_CH_CTRL_SOURCESEL_USART0 << 16) /* Shifted mode USART0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_USART1 (_PRS_CH_CTRL_SOURCESEL_USART1 << 16) /* Shifted mode USART1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_USART2 (_PRS_CH_CTRL_SOURCESEL_USART2 << 16) /* Shifted mode USART2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_TIMER0 (_PRS_CH_CTRL_SOURCESEL_TIMER0 << 16) /* Shifted mode TIMER0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_TIMER1 (_PRS_CH_CTRL_SOURCESEL_TIMER1 << 16) /* Shifted mode TIMER1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_TIMER2 (_PRS_CH_CTRL_SOURCESEL_TIMER2 << 16) /* Shifted mode TIMER2 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_TIMER3 (_PRS_CH_CTRL_SOURCESEL_TIMER3 << 16) /* Shifted mode TIMER3 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_USB (_PRS_CH_CTRL_SOURCESEL_USB << 16) /* Shifted mode USB for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_RTC (_PRS_CH_CTRL_SOURCESEL_RTC << 16) /* Shifted mode RTC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_UART0 (_PRS_CH_CTRL_SOURCESEL_UART0 << 16) /* Shifted mode UART0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_UART1 (_PRS_CH_CTRL_SOURCESEL_UART1 << 16) /* Shifted mode UART1 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_GPIOL (_PRS_CH_CTRL_SOURCESEL_GPIOL << 16) /* Shifted mode GPIOL for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_GPIOH (_PRS_CH_CTRL_SOURCESEL_GPIOH << 16) /* Shifted mode GPIOH for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_LETIMER0 (_PRS_CH_CTRL_SOURCESEL_LETIMER0 << 16) /* Shifted mode LETIMER0 for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_BURTC (_PRS_CH_CTRL_SOURCESEL_BURTC << 16) /* Shifted mode BURTC for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_LESENSEL (_PRS_CH_CTRL_SOURCESEL_LESENSEL << 16) /* Shifted mode LESENSEL for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_LESENSEH (_PRS_CH_CTRL_SOURCESEL_LESENSEH << 16) /* Shifted mode LESENSEH for PRS_CH_CTRL */ +#define PRS_CH_CTRL_SOURCESEL_LESENSED (_PRS_CH_CTRL_SOURCESEL_LESENSED << 16) /* Shifted mode LESENSED for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_EDSEL_SHIFT 24 /* Shift value for PRS_EDSEL */ +#define _PRS_CH_CTRL_EDSEL_MASK 0x3000000UL /* Bit mask for PRS_EDSEL */ +#define _PRS_CH_CTRL_EDSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_EDSEL_OFF 0x00000000UL /* Mode OFF for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_EDSEL_POSEDGE 0x00000001UL /* Mode POSEDGE for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_EDSEL_NEGEDGE 0x00000002UL /* Mode NEGEDGE for PRS_CH_CTRL */ +#define _PRS_CH_CTRL_EDSEL_BOTHEDGES 0x00000003UL /* Mode BOTHEDGES for PRS_CH_CTRL */ +#define PRS_CH_CTRL_EDSEL_DEFAULT (_PRS_CH_CTRL_EDSEL_DEFAULT << 24) /* Shifted mode DEFAULT for PRS_CH_CTRL */ +#define PRS_CH_CTRL_EDSEL_OFF (_PRS_CH_CTRL_EDSEL_OFF << 24) /* Shifted mode OFF for PRS_CH_CTRL */ +#define PRS_CH_CTRL_EDSEL_POSEDGE (_PRS_CH_CTRL_EDSEL_POSEDGE << 24) /* Shifted mode POSEDGE for PRS_CH_CTRL */ +#define PRS_CH_CTRL_EDSEL_NEGEDGE (_PRS_CH_CTRL_EDSEL_NEGEDGE << 24) /* Shifted mode NEGEDGE for PRS_CH_CTRL */ +#define PRS_CH_CTRL_EDSEL_BOTHEDGES (_PRS_CH_CTRL_EDSEL_BOTHEDGES << 24) /* Shifted mode BOTHEDGES for PRS_CH_CTRL */ +#define PRS_CH_CTRL_ASYNC (0x1UL << 28) /* Asynchronous reflex */ +#define _PRS_CH_CTRL_ASYNC_SHIFT 28 /* Shift value for PRS_ASYNC */ +#define _PRS_CH_CTRL_ASYNC_MASK 0x10000000UL /* Bit mask for PRS_ASYNC */ +#define _PRS_CH_CTRL_ASYNC_DEFAULT 0x00000000UL /* Mode DEFAULT for PRS_CH_CTRL */ +#define PRS_CH_CTRL_ASYNC_DEFAULT (_PRS_CH_CTRL_ASYNC_DEFAULT << 28) /* Shifted mode DEFAULT for PRS_CH_CTRL */ + +/* PRS Signals *****************************************************************************************************************/ + +#define PRS_VCMP_OUT ((1 << 16) + 0) /* PRS Voltage comparator output */ +#define PRS_ACMP0_OUT ((2 << 16) + 0) /* PRS Analog comparator output */ +#define PRS_ACMP1_OUT ((3 << 16) + 0) /* PRS Analog comparator output */ +#define PRS_DAC0_CH0 ((6 << 16) + 0) /* PRS DAC ch0 conversion done */ +#define PRS_DAC0_CH1 ((6 << 16) + 1) /* PRS DAC ch1 conversion done */ +#define PRS_ADC0_SINGLE ((8 << 16) + 0) /* PRS ADC single conversion done */ +#define PRS_ADC0_SCAN ((8 << 16) + 1) /* PRS ADC scan conversion done */ +#define PRS_USART0_IRTX ((16 << 16) + 0) /* PRS USART 0 IRDA out */ +#define PRS_USART0_TXC ((16 << 16) + 1) /* PRS USART 0 TX complete */ +#define PRS_USART0_RXDATAV ((16 << 16) + 2) /* PRS USART 0 RX Data Valid */ +#define PRS_USART1_TXC ((17 << 16) + 1) /* PRS USART 1 TX complete */ +#define PRS_USART1_RXDATAV ((17 << 16) + 2) /* PRS USART 1 RX Data Valid */ +#define PRS_USART2_TXC ((18 << 16) + 1) /* PRS USART 2 TX complete */ +#define PRS_USART2_RXDATAV ((18 << 16) + 2) /* PRS USART 2 RX Data Valid */ +#define PRS_TIMER0_UF ((28 << 16) + 0) /* PRS Timer 0 Underflow */ +#define PRS_TIMER0_OF ((28 << 16) + 1) /* PRS Timer 0 Overflow */ +#define PRS_TIMER0_CC0 ((28 << 16) + 2) /* PRS Timer 0 Compare/Capture 0 */ +#define PRS_TIMER0_CC1 ((28 << 16) + 3) /* PRS Timer 0 Compare/Capture 1 */ +#define PRS_TIMER0_CC2 ((28 << 16) + 4) /* PRS Timer 0 Compare/Capture 2 */ +#define PRS_TIMER1_UF ((29 << 16) + 0) /* PRS Timer 1 Underflow */ +#define PRS_TIMER1_OF ((29 << 16) + 1) /* PRS Timer 1 Overflow */ +#define PRS_TIMER1_CC0 ((29 << 16) + 2) /* PRS Timer 1 Compare/Capture 0 */ +#define PRS_TIMER1_CC1 ((29 << 16) + 3) /* PRS Timer 1 Compare/Capture 1 */ +#define PRS_TIMER1_CC2 ((29 << 16) + 4) /* PRS Timer 1 Compare/Capture 2 */ +#define PRS_TIMER2_UF ((30 << 16) + 0) /* PRS Timer 2 Underflow */ +#define PRS_TIMER2_OF ((30 << 16) + 1) /* PRS Timer 2 Overflow */ +#define PRS_TIMER2_CC0 ((30 << 16) + 2) /* PRS Timer 2 Compare/Capture 0 */ +#define PRS_TIMER2_CC1 ((30 << 16) + 3) /* PRS Timer 2 Compare/Capture 1 */ +#define PRS_TIMER2_CC2 ((30 << 16) + 4) /* PRS Timer 2 Compare/Capture 2 */ +#define PRS_TIMER3_UF ((31 << 16) + 0) /* PRS Timer 3 Underflow */ +#define PRS_TIMER3_OF ((31 << 16) + 1) /* PRS Timer 3 Overflow */ +#define PRS_TIMER3_CC0 ((31 << 16) + 2) /* PRS Timer 3 Compare/Capture 0 */ +#define PRS_TIMER3_CC1 ((31 << 16) + 3) /* PRS Timer 3 Compare/Capture 1 */ +#define PRS_TIMER3_CC2 ((31 << 16) + 4) /* PRS Timer 3 Compare/Capture 2 */ +#define PRS_USB_SOF ((36 << 16) + 0) /* PRS USB Start of Frame */ +#define PRS_USB_SOFSR ((36 << 16) + 1) /* PRS USB Start of Frame Sent/Received */ +#define PRS_RTC_OF ((40 << 16) + 0) /* PRS RTC Overflow */ +#define PRS_RTC_COMP0 ((40 << 16) + 1) /* PRS RTC Compare 0 */ +#define PRS_RTC_COMP1 ((40 << 16) + 2) /* PRS RTC Compare 1 */ +#define PRS_UART0_TXC ((41 << 16) + 1) /* PRS USART 0 TX complete */ +#define PRS_UART0_RXDATAV ((41 << 16) + 2) /* PRS USART 0 RX Data Valid */ +#define PRS_UART1_TXC ((42 << 16) + 1) /* PRS USART 0 TX complete */ +#define PRS_UART1_RXDATAV ((42 << 16) + 2) /* PRS USART 0 RX Data Valid */ +#define PRS_GPIO_PIN0 ((48 << 16) + 0) /* PRS GPIO pin 0 */ +#define PRS_GPIO_PIN1 ((48 << 16) + 1) /* PRS GPIO pin 1 */ +#define PRS_GPIO_PIN2 ((48 << 16) + 2) /* PRS GPIO pin 2 */ +#define PRS_GPIO_PIN3 ((48 << 16) + 3) /* PRS GPIO pin 3 */ +#define PRS_GPIO_PIN4 ((48 << 16) + 4) /* PRS GPIO pin 4 */ +#define PRS_GPIO_PIN5 ((48 << 16) + 5) /* PRS GPIO pin 5 */ +#define PRS_GPIO_PIN6 ((48 << 16) + 6) /* PRS GPIO pin 6 */ +#define PRS_GPIO_PIN7 ((48 << 16) + 7) /* PRS GPIO pin 7 */ +#define PRS_GPIO_PIN8 ((49 << 16) + 0) /* PRS GPIO pin 8 */ +#define PRS_GPIO_PIN9 ((49 << 16) + 1) /* PRS GPIO pin 9 */ +#define PRS_GPIO_PIN10 ((49 << 16) + 2) /* PRS GPIO pin 10 */ +#define PRS_GPIO_PIN11 ((49 << 16) + 3) /* PRS GPIO pin 11 */ +#define PRS_GPIO_PIN12 ((49 << 16) + 4) /* PRS GPIO pin 12 */ +#define PRS_GPIO_PIN13 ((49 << 16) + 5) /* PRS GPIO pin 13 */ +#define PRS_GPIO_PIN14 ((49 << 16) + 6) /* PRS GPIO pin 14 */ +#define PRS_GPIO_PIN15 ((49 << 16) + 7) /* PRS GPIO pin 15 */ +#define PRS_LETIMER0_CH0 ((52 << 16) + 0) /* PRS LETIMER CH0 Out */ +#define PRS_LETIMER0_CH1 ((52 << 16) + 1) /* PRS LETIMER CH1 Out */ +#define PRS_BURTC_OF ((55 << 16) + 0) /* PRS BURTC Overflow */ +#define PRS_BURTC_COMP0 ((55 << 16) + 1) /* PRS BURTC Compare 0 */ +#define PRS_LESENSE_SCANRES0 ((57 << 16) + 0) /* PRS LESENSE SCANRES register, bit 0 */ +#define PRS_LESENSE_SCANRES1 ((57 << 16) + 1) /* PRS LESENSE SCANRES register, bit 1 */ +#define PRS_LESENSE_SCANRES2 ((57 << 16) + 2) /* PRS LESENSE SCANRES register, bit 2 */ +#define PRS_LESENSE_SCANRES3 ((57 << 16) + 3) /* PRS LESENSE SCANRES register, bit 3 */ +#define PRS_LESENSE_SCANRES4 ((57 << 16) + 4) /* PRS LESENSE SCANRES register, bit 4 */ +#define PRS_LESENSE_SCANRES5 ((57 << 16) + 5) /* PRS LESENSE SCANRES register, bit 5 */ +#define PRS_LESENSE_SCANRES6 ((57 << 16) + 6) /* PRS LESENSE SCANRES register, bit 6 */ +#define PRS_LESENSE_SCANRES7 ((57 << 16) + 7) /* PRS LESENSE SCANRES register, bit 7 */ +#define PRS_LESENSE_SCANRES8 ((58 << 16) + 0) /* PRS LESENSE SCANRES register, bit 8 */ +#define PRS_LESENSE_SCANRES9 ((58 << 16) + 1) /* PRS LESENSE SCANRES register, bit 9 */ +#define PRS_LESENSE_SCANRES10 ((58 << 16) + 2) /* PRS LESENSE SCANRES register, bit 10 */ +#define PRS_LESENSE_SCANRES11 ((58 << 16) + 3) /* PRS LESENSE SCANRES register, bit 11 */ +#define PRS_LESENSE_SCANRES12 ((58 << 16) + 4) /* PRS LESENSE SCANRES register, bit 12 */ +#define PRS_LESENSE_SCANRES13 ((58 << 16) + 5) /* PRS LESENSE SCANRES register, bit 13 */ +#define PRS_LESENSE_SCANRES14 ((58 << 16) + 6) /* PRS LESENSE SCANRES register, bit 14 */ +#define PRS_LESENSE_SCANRES15 ((58 << 16) + 7) /* PRS LESENSE SCANRES register, bit 15 */ +#define PRS_LESENSE_DEC0 ((59 << 16) + 0) /* PRS LESENSE Decoder PRS out 0 */ +#define PRS_LESENSE_DEC1 ((59 << 16) + 1) /* PRS LESENSE Decoder PRS out 1 */ +#define PRS_LESENSE_DEC2 ((59 << 16) + 2) /* PRS LESENSE Decoder PRS out 2 */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_PRS_H */ diff --git a/arch/arm/src/efm32/chip/efm32_rmu.h b/arch/arm/src/efm32/chip/efm32_rmu.h new file mode 100644 index 0000000000000000000000000000000000000000..e383cce1352ef4238328dbbda2651249577e76af --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_rmu.h @@ -0,0 +1,205 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_rmu.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RMU_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RMU_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* RMU Register Offsets ********************************************************************************************************/ + +#define EFM32_RMU_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_RMU_RSTCAUSE_OFFSET 0x0004 /* Reset Cause Register */ +#define EFM32_RMU_CMD_OFFSET 0x0008 /* Command Register */ + +/* RMU Register Addresses ******************************************************************************************************/ + +#define EFM32_RMU_CTRL (EFM32_RMU_BASE+EFM32_RMU_CTRL_OFFSET) +#define EFM32_RMU_RSTCAUSE (EFM32_RMU_BASE+EFM32_RMU_RSTCAUSE_OFFSET) +#define EFM32_RMU_CMD (EFM32_RMU_BASE+EFM32_RMU_CMD_OFFSET) + +/* RMU Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for RMU CTRL */ + +#define _RMU_CTRL_RESETVALUE 0x00000002UL /**< Default value for RMU_CTRL */ +#define _RMU_CTRL_MASK 0x00000003UL /**< Mask for RMU_CTRL */ + +#define RMU_CTRL_LOCKUPRDIS (0x1UL << 0) /**< Lockup Reset Disable */ +#define _RMU_CTRL_LOCKUPRDIS_SHIFT 0 /**< Shift value for RMU_LOCKUPRDIS */ +#define _RMU_CTRL_LOCKUPRDIS_MASK 0x1UL /**< Bit mask for RMU_LOCKUPRDIS */ +#define _RMU_CTRL_LOCKUPRDIS_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_CTRL */ +#define RMU_CTRL_LOCKUPRDIS_DEFAULT (_RMU_CTRL_LOCKUPRDIS_DEFAULT << 0) /**< Shifted mode DEFAULT for RMU_CTRL */ +#define RMU_CTRL_BURSTEN (0x1UL << 1) /**< Backup domain reset enable */ +#define _RMU_CTRL_BURSTEN_SHIFT 1 /**< Shift value for RMU_BURSTEN */ +#define _RMU_CTRL_BURSTEN_MASK 0x2UL /**< Bit mask for RMU_BURSTEN */ +#define _RMU_CTRL_BURSTEN_DEFAULT 0x00000001UL /**< Mode DEFAULT for RMU_CTRL */ +#define RMU_CTRL_BURSTEN_DEFAULT (_RMU_CTRL_BURSTEN_DEFAULT << 1) /**< Shifted mode DEFAULT for RMU_CTRL */ + +/* Bit fields for RMU RSTCAUSE */ + +#define _RMU_RSTCAUSE_RESETVALUE 0x00000000UL /**< Default value for RMU_RSTCAUSE */ +#define _RMU_RSTCAUSE_MASK 0x0000FFFFUL /**< Mask for RMU_RSTCAUSE */ + +#define RMU_RSTCAUSE_PORST (0x1UL << 0) /**< Power On Reset */ +#define _RMU_RSTCAUSE_PORST_SHIFT 0 /**< Shift value for RMU_PORST */ +#define _RMU_RSTCAUSE_PORST_MASK 0x1UL /**< Bit mask for RMU_PORST */ +#define _RMU_RSTCAUSE_PORST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_PORST_DEFAULT (_RMU_RSTCAUSE_PORST_DEFAULT << 0) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODUNREGRST (0x1UL << 1) /**< Brown Out Detector Unregulated Domain Reset */ +#define _RMU_RSTCAUSE_BODUNREGRST_SHIFT 1 /**< Shift value for RMU_BODUNREGRST */ +#define _RMU_RSTCAUSE_BODUNREGRST_MASK 0x2UL /**< Bit mask for RMU_BODUNREGRST */ +#define _RMU_RSTCAUSE_BODUNREGRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODUNREGRST_DEFAULT (_RMU_RSTCAUSE_BODUNREGRST_DEFAULT << 1) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODREGRST (0x1UL << 2) /**< Brown Out Detector Regulated Domain Reset */ +#define _RMU_RSTCAUSE_BODREGRST_SHIFT 2 /**< Shift value for RMU_BODREGRST */ +#define _RMU_RSTCAUSE_BODREGRST_MASK 0x4UL /**< Bit mask for RMU_BODREGRST */ +#define _RMU_RSTCAUSE_BODREGRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODREGRST_DEFAULT (_RMU_RSTCAUSE_BODREGRST_DEFAULT << 2) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EXTRST (0x1UL << 3) /**< External Pin Reset */ +#define _RMU_RSTCAUSE_EXTRST_SHIFT 3 /**< Shift value for RMU_EXTRST */ +#define _RMU_RSTCAUSE_EXTRST_MASK 0x8UL /**< Bit mask for RMU_EXTRST */ +#define _RMU_RSTCAUSE_EXTRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EXTRST_DEFAULT (_RMU_RSTCAUSE_EXTRST_DEFAULT << 3) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_WDOGRST (0x1UL << 4) /**< Watchdog Reset */ +#define _RMU_RSTCAUSE_WDOGRST_SHIFT 4 /**< Shift value for RMU_WDOGRST */ +#define _RMU_RSTCAUSE_WDOGRST_MASK 0x10UL /**< Bit mask for RMU_WDOGRST */ +#define _RMU_RSTCAUSE_WDOGRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_WDOGRST_DEFAULT (_RMU_RSTCAUSE_WDOGRST_DEFAULT << 4) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_LOCKUPRST (0x1UL << 5) /**< LOCKUP Reset */ +#define _RMU_RSTCAUSE_LOCKUPRST_SHIFT 5 /**< Shift value for RMU_LOCKUPRST */ +#define _RMU_RSTCAUSE_LOCKUPRST_MASK 0x20UL /**< Bit mask for RMU_LOCKUPRST */ +#define _RMU_RSTCAUSE_LOCKUPRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_LOCKUPRST_DEFAULT (_RMU_RSTCAUSE_LOCKUPRST_DEFAULT << 5) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_SYSREQRST (0x1UL << 6) /**< System Request Reset */ +#define _RMU_RSTCAUSE_SYSREQRST_SHIFT 6 /**< Shift value for RMU_SYSREQRST */ +#define _RMU_RSTCAUSE_SYSREQRST_MASK 0x40UL /**< Bit mask for RMU_SYSREQRST */ +#define _RMU_RSTCAUSE_SYSREQRST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_SYSREQRST_DEFAULT (_RMU_RSTCAUSE_SYSREQRST_DEFAULT << 6) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EM4RST (0x1UL << 7) /**< EM4 Reset */ +#define _RMU_RSTCAUSE_EM4RST_SHIFT 7 /**< Shift value for RMU_EM4RST */ +#define _RMU_RSTCAUSE_EM4RST_MASK 0x80UL /**< Bit mask for RMU_EM4RST */ +#define _RMU_RSTCAUSE_EM4RST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EM4RST_DEFAULT (_RMU_RSTCAUSE_EM4RST_DEFAULT << 7) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EM4WURST (0x1UL << 8) /**< EM4 Wake-up Reset */ +#define _RMU_RSTCAUSE_EM4WURST_SHIFT 8 /**< Shift value for RMU_EM4WURST */ +#define _RMU_RSTCAUSE_EM4WURST_MASK 0x100UL /**< Bit mask for RMU_EM4WURST */ +#define _RMU_RSTCAUSE_EM4WURST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_EM4WURST_DEFAULT (_RMU_RSTCAUSE_EM4WURST_DEFAULT << 8) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODAVDD0 (0x1UL << 9) /**< AVDD0 Bod Reset */ +#define _RMU_RSTCAUSE_BODAVDD0_SHIFT 9 /**< Shift value for RMU_BODAVDD0 */ +#define _RMU_RSTCAUSE_BODAVDD0_MASK 0x200UL /**< Bit mask for RMU_BODAVDD0 */ +#define _RMU_RSTCAUSE_BODAVDD0_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODAVDD0_DEFAULT (_RMU_RSTCAUSE_BODAVDD0_DEFAULT << 9) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODAVDD1 (0x1UL << 10) /**< AVDD1 Bod Reset */ +#define _RMU_RSTCAUSE_BODAVDD1_SHIFT 10 /**< Shift value for RMU_BODAVDD1 */ +#define _RMU_RSTCAUSE_BODAVDD1_MASK 0x400UL /**< Bit mask for RMU_BODAVDD1 */ +#define _RMU_RSTCAUSE_BODAVDD1_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BODAVDD1_DEFAULT (_RMU_RSTCAUSE_BODAVDD1_DEFAULT << 10) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODVDDDREG (0x1UL << 11) /**< Backup Brown Out Detector, VDD_DREG */ +#define _RMU_RSTCAUSE_BUBODVDDDREG_SHIFT 11 /**< Shift value for RMU_BUBODVDDDREG */ +#define _RMU_RSTCAUSE_BUBODVDDDREG_MASK 0x800UL /**< Bit mask for RMU_BUBODVDDDREG */ +#define _RMU_RSTCAUSE_BUBODVDDDREG_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODVDDDREG_DEFAULT (_RMU_RSTCAUSE_BUBODVDDDREG_DEFAULT << 11) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODBUVIN (0x1UL << 12) /**< Backup Brown Out Detector, BU_VIN */ +#define _RMU_RSTCAUSE_BUBODBUVIN_SHIFT 12 /**< Shift value for RMU_BUBODBUVIN */ +#define _RMU_RSTCAUSE_BUBODBUVIN_MASK 0x1000UL /**< Bit mask for RMU_BUBODBUVIN */ +#define _RMU_RSTCAUSE_BUBODBUVIN_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODBUVIN_DEFAULT (_RMU_RSTCAUSE_BUBODBUVIN_DEFAULT << 12) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODUNREG (0x1UL << 13) /**< Backup Brown Out Detector Unregulated Domain */ +#define _RMU_RSTCAUSE_BUBODUNREG_SHIFT 13 /**< Shift value for RMU_BUBODUNREG */ +#define _RMU_RSTCAUSE_BUBODUNREG_MASK 0x2000UL /**< Bit mask for RMU_BUBODUNREG */ +#define _RMU_RSTCAUSE_BUBODUNREG_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODUNREG_DEFAULT (_RMU_RSTCAUSE_BUBODUNREG_DEFAULT << 13) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODREG (0x1UL << 14) /**< Backup Brown Out Detector Regulated Domain */ +#define _RMU_RSTCAUSE_BUBODREG_SHIFT 14 /**< Shift value for RMU_BUBODREG */ +#define _RMU_RSTCAUSE_BUBODREG_MASK 0x4000UL /**< Bit mask for RMU_BUBODREG */ +#define _RMU_RSTCAUSE_BUBODREG_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUBODREG_DEFAULT (_RMU_RSTCAUSE_BUBODREG_DEFAULT << 14) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUMODERST (0x1UL << 15) /**< Backup mode reset */ +#define _RMU_RSTCAUSE_BUMODERST_SHIFT 15 /**< Shift value for RMU_BUMODERST */ +#define _RMU_RSTCAUSE_BUMODERST_MASK 0x8000UL /**< Bit mask for RMU_BUMODERST */ +#define _RMU_RSTCAUSE_BUMODERST_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUMODERST_DEFAULT (_RMU_RSTCAUSE_BUMODERST_DEFAULT << 15) /**< Shifted mode DEFAULT for RMU_RSTCAUSE */ + +/* Bit fields for RMU CMD */ + +#define _RMU_CMD_RESETVALUE 0x00000000UL /**< Default value for RMU_CMD */ +#define _RMU_CMD_MASK 0x00000001UL /**< Mask for RMU_CMD */ + +#define RMU_CMD_RCCLR (0x1UL << 0) /**< Reset Cause Clear */ +#define _RMU_CMD_RCCLR_SHIFT 0 /**< Shift value for RMU_RCCLR */ +#define _RMU_CMD_RCCLR_MASK 0x1UL /**< Bit mask for RMU_RCCLR */ +#define _RMU_CMD_RCCLR_DEFAULT 0x00000000UL /**< Mode DEFAULT for RMU_CMD */ +#define RMU_CMD_RCCLR_DEFAULT (_RMU_CMD_RCCLR_DEFAULT << 0) /**< Shifted mode DEFAULT for RMU_CMD */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RMU_H */ diff --git a/arch/arm/src/efm32/chip/efm32_romtable.h b/arch/arm/src/efm32/chip/efm32_romtable.h new file mode 100644 index 0000000000000000000000000000000000000000..209fbd7d8d18ad9aa76c0fed763bb7e70038c17f --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_romtable.h @@ -0,0 +1,114 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_romtable.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ROMTABLE_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ROMTABLE_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +#define ROMTABLE ((const struct efm32_romtable_s *)EFM32_ROMTABLE_BASE) + +/* Bit fields for struct efm32_romtable_s */ + +#define _ROMTABLE_PID0_FAMILYLSB_MASK 0x000000C0UL /* Least Significant Bits [1:0] of CHIP FAMILY, mask */ +#define _ROMTABLE_PID0_FAMILYLSB_SHIFT 6 /* Least Significant Bits [1:0] of CHIP FAMILY, shift */ +#define _ROMTABLE_PID0_REVMAJOR_MASK 0x0000003FUL /* CHIP MAJOR Revison, mask */ +#define _ROMTABLE_PID0_REVMAJOR_SHIFT 0 /* CHIP MAJOR Revison, shift */ + +#define _ROMTABLE_PID1_FAMILYMSB_MASK 0x0000000FUL /* Most Significant Bits [5:2] of CHIP FAMILY, mask */ +#define _ROMTABLE_PID1_FAMILYMSB_SHIFT 0 /* Most Significant Bits [5:2] of CHIP FAMILY, shift */ + +#define _ROMTABLE_PID2_REVMINORMSB_MASK 0x000000F0UL /* Most Significant Bits [7:4] of CHIP MINOR revision, mask */ +#define _ROMTABLE_PID2_REVMINORMSB_SHIFT 4 /* Most Significant Bits [7:4] of CHIP MINOR revision, mask */ + +#define _ROMTABLE_PID3_REVMINORLSB_MASK 0x000000F0UL /* Least Significant Bits [3:0] of CHIP MINOR revision, mask */ +#define _ROMTABLE_PID3_REVMINORLSB_SHIFT 4 /* Least Significant Bits [3:0] of CHIP MINOR revision, shift */ + +/******************************************************************************************************************************* + * Public Type Definitions + *******************************************************************************************************************************/ + +struct efm32_romtable_s +{ + const uint32_t pid4; /* JEP_106_BANK */ + const uint32_t pid5; /* Unused */ + const uint32_t pid6; /* Unused */ + const uint32_t pid7; /* Unused */ + const uint32_t pid0; /* Chip family LSB, chip major revision */ + const uint32_t pid1; /* JEP_106_NO, Chip family MSB */ + const uint32_t pid2; /* Chip minor rev MSB, JEP_106_PRESENT, JEP_106_NO */ + const uint32_t pid3; /* Chip minor rev LSB */ + const uint32_t cid0; /* Unused */ +}; + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_ROMTABLE_H */ diff --git a/arch/arm/src/efm32/chip/efm32_rtc.h b/arch/arm/src/efm32/chip/efm32_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..044efae971e89f70a5ea45707d185e7b7a84ad48 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_rtc.h @@ -0,0 +1,281 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_rtc.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RTC_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RTC_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* RTC Register Offsets ********************************************************************************************************/ + +#define EFM32_RTC_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_RTC_CNT_OFFSET 0x0004 /* Counter Value Register */ +#define EFM32_RTC_COMP0_OFFSET 0x0008 /* Compare Value Register 0 */ +#define EFM32_RTC_COMP1_OFFSET 0x000c /* Compare Value Register 1 */ +#define EFM32_RTC_IF_OFFSET 0x0010 /* Interrupt Flag Register */ +#define EFM32_RTC_IFS_OFFSET 0x0014 /* Interrupt Flag Set Register */ +#define EFM32_RTC_IFC_OFFSET 0x0018 /* Interrupt Flag Clear Register */ +#define EFM32_RTC_IEN_OFFSET 0x001c /* Interrupt Enable Register */ +#define EFM32_RTC_FREEZE_OFFSET 0x0020 /* Freeze Register */ +#define EFM32_RTC_SYNCBUSY_OFFSET 0x0024 /* Synchronization Busy Register */ + +/* RTC Register Addresses ******************************************************************************************************/ + +#define EFM32_RTC_CTRL (EFM32_RTC_BASE+EFM32_RTC_CTRL_OFFSET) +#define EFM32_RTC_CNT (EFM32_RTC_BASE+EFM32_RTC_CNT_OFFSET) +#define EFM32_RTC_COMP0 (EFM32_RTC_BASE+EFM32_RTC_COMP0_OFFSET) +#define EFM32_RTC_COMP1 (EFM32_RTC_BASE+EFM32_RTC_COMP1_OFFSET) +#define EFM32_RTC_IF (EFM32_RTC_BASE+EFM32_RTC_IF_OFFSET) +#define EFM32_RTC_IFS (EFM32_RTC_BASE+EFM32_RTC_IFS_OFFSET) +#define EFM32_RTC_IFC (EFM32_RTC_BASE+EFM32_RTC_IFC_OFFSET) +#define EFM32_RTC_IEN (EFM32_RTC_BASE+EFM32_RTC_IEN_OFFSET) +#define EFM32_RTC_FREEZE (EFM32_RTC_BASE+EFM32_RTC_FREEZE_OFFSET) +#define EFM32_RTC_SYNCBUSY (EFM32_RTC_BASE+EFM32_RTC_SYNCBUSY_OFFSET) + +/* RTC Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for RTC CTRL */ + +#define _RTC_CTRL_RESETVALUE 0x00000000UL /* Default value for RTC_CTRL */ +#define _RTC_CTRL_MASK 0x00000007UL /* Mask for RTC_CTRL */ + +#define RTC_CTRL_EN (0x1UL << 0) /* RTC Enable */ +#define _RTC_CTRL_EN_SHIFT 0 /* Shift value for RTC_EN */ +#define _RTC_CTRL_EN_MASK 0x1UL /* Bit mask for RTC_EN */ +#define _RTC_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_CTRL */ +#define RTC_CTRL_EN_DEFAULT (_RTC_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_CTRL */ +#define RTC_CTRL_DEBUGRUN (0x1UL << 1) /* Debug Mode Run Enable */ +#define _RTC_CTRL_DEBUGRUN_SHIFT 1 /* Shift value for RTC_DEBUGRUN */ +#define _RTC_CTRL_DEBUGRUN_MASK 0x2UL /* Bit mask for RTC_DEBUGRUN */ +#define _RTC_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_CTRL */ +#define RTC_CTRL_DEBUGRUN_DEFAULT (_RTC_CTRL_DEBUGRUN_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_CTRL */ +#define RTC_CTRL_COMP0TOP (0x1UL << 2) /* Compare Channel 0 is Top Value */ +#define _RTC_CTRL_COMP0TOP_SHIFT 2 /* Shift value for RTC_COMP0TOP */ +#define _RTC_CTRL_COMP0TOP_MASK 0x4UL /* Bit mask for RTC_COMP0TOP */ +#define _RTC_CTRL_COMP0TOP_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_CTRL */ +#define _RTC_CTRL_COMP0TOP_DISABLE 0x00000000UL /* Mode DISABLE for RTC_CTRL */ +#define _RTC_CTRL_COMP0TOP_ENABLE 0x00000001UL /* Mode ENABLE for RTC_CTRL */ +#define RTC_CTRL_COMP0TOP_DEFAULT (_RTC_CTRL_COMP0TOP_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_CTRL */ +#define RTC_CTRL_COMP0TOP_DISABLE (_RTC_CTRL_COMP0TOP_DISABLE << 2) /* Shifted mode DISABLE for RTC_CTRL */ +#define RTC_CTRL_COMP0TOP_ENABLE (_RTC_CTRL_COMP0TOP_ENABLE << 2) /* Shifted mode ENABLE for RTC_CTRL */ + +/* Bit fields for RTC CNT */ + +#define _RTC_CNT_RESETVALUE 0x00000000UL /* Default value for RTC_CNT */ +#define _RTC_CNT_MASK 0x00FFFFFFUL /* Mask for RTC_CNT */ + +#define _RTC_CNT_CNT_SHIFT 0 /* Shift value for RTC_CNT */ +#define _RTC_CNT_CNT_MASK 0xFFFFFFUL /* Bit mask for RTC_CNT */ +#define _RTC_CNT_CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_CNT */ +#define RTC_CNT_CNT_DEFAULT (_RTC_CNT_CNT_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_CNT */ + +/* Bit fields for RTC COMP0 */ + +#define _RTC_COMP0_RESETVALUE 0x00000000UL /* Default value for RTC_COMP0 */ +#define _RTC_COMP0_MASK 0x00FFFFFFUL /* Mask for RTC_COMP0 */ + +#define _RTC_COMP0_COMP0_SHIFT 0 /* Shift value for RTC_COMP0 */ +#define _RTC_COMP0_COMP0_MASK 0xFFFFFFUL /* Bit mask for RTC_COMP0 */ +#define _RTC_COMP0_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_COMP0 */ +#define RTC_COMP0_COMP0_DEFAULT (_RTC_COMP0_COMP0_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_COMP0 */ + +/* Bit fields for RTC COMP1 */ + +#define _RTC_COMP1_RESETVALUE 0x00000000UL /* Default value for RTC_COMP1 */ +#define _RTC_COMP1_MASK 0x00FFFFFFUL /* Mask for RTC_COMP1 */ + +#define _RTC_COMP1_COMP1_SHIFT 0 /* Shift value for RTC_COMP1 */ +#define _RTC_COMP1_COMP1_MASK 0xFFFFFFUL /* Bit mask for RTC_COMP1 */ +#define _RTC_COMP1_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_COMP1 */ +#define RTC_COMP1_COMP1_DEFAULT (_RTC_COMP1_COMP1_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_COMP1 */ + +/* Bit fields for RTC IF */ + +#define _RTC_IF_RESETVALUE 0x00000000UL /* Default value for RTC_IF */ +#define _RTC_IF_MASK 0x00000007UL /* Mask for RTC_IF */ + +#define RTC_IF_OF (0x1UL << 0) /* Overflow Interrupt Flag */ +#define _RTC_IF_OF_SHIFT 0 /* Shift value for RTC_OF */ +#define _RTC_IF_OF_MASK 0x1UL /* Bit mask for RTC_OF */ +#define _RTC_IF_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IF */ +#define RTC_IF_OF_DEFAULT (_RTC_IF_OF_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_IF */ +#define RTC_IF_COMP0 (0x1UL << 1) /* Compare Match 0 Interrupt Flag */ +#define _RTC_IF_COMP0_SHIFT 1 /* Shift value for RTC_COMP0 */ +#define _RTC_IF_COMP0_MASK 0x2UL /* Bit mask for RTC_COMP0 */ +#define _RTC_IF_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IF */ +#define RTC_IF_COMP0_DEFAULT (_RTC_IF_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_IF */ +#define RTC_IF_COMP1 (0x1UL << 2) /* Compare Match 1 Interrupt Flag */ +#define _RTC_IF_COMP1_SHIFT 2 /* Shift value for RTC_COMP1 */ +#define _RTC_IF_COMP1_MASK 0x4UL /* Bit mask for RTC_COMP1 */ +#define _RTC_IF_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IF */ +#define RTC_IF_COMP1_DEFAULT (_RTC_IF_COMP1_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_IF */ + +/* Bit fields for RTC IFS */ + +#define _RTC_IFS_RESETVALUE 0x00000000UL /* Default value for RTC_IFS */ +#define _RTC_IFS_MASK 0x00000007UL /* Mask for RTC_IFS */ + +#define RTC_IFS_OF (0x1UL << 0) /* Set Overflow Interrupt Flag */ +#define _RTC_IFS_OF_SHIFT 0 /* Shift value for RTC_OF */ +#define _RTC_IFS_OF_MASK 0x1UL /* Bit mask for RTC_OF */ +#define _RTC_IFS_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFS */ +#define RTC_IFS_OF_DEFAULT (_RTC_IFS_OF_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_IFS */ +#define RTC_IFS_COMP0 (0x1UL << 1) /* Set Compare match 0 Interrupt Flag */ +#define _RTC_IFS_COMP0_SHIFT 1 /* Shift value for RTC_COMP0 */ +#define _RTC_IFS_COMP0_MASK 0x2UL /* Bit mask for RTC_COMP0 */ +#define _RTC_IFS_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFS */ +#define RTC_IFS_COMP0_DEFAULT (_RTC_IFS_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_IFS */ +#define RTC_IFS_COMP1 (0x1UL << 2) /* Set Compare match 1 Interrupt Flag */ +#define _RTC_IFS_COMP1_SHIFT 2 /* Shift value for RTC_COMP1 */ +#define _RTC_IFS_COMP1_MASK 0x4UL /* Bit mask for RTC_COMP1 */ +#define _RTC_IFS_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFS */ +#define RTC_IFS_COMP1_DEFAULT (_RTC_IFS_COMP1_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_IFS */ + +/* Bit fields for RTC IFC */ + +#define _RTC_IFC_RESETVALUE 0x00000000UL /* Default value for RTC_IFC */ +#define _RTC_IFC_MASK 0x00000007UL /* Mask for RTC_IFC */ + +#define RTC_IFC_OF (0x1UL << 0) /* Clear Overflow Interrupt Flag */ +#define _RTC_IFC_OF_SHIFT 0 /* Shift value for RTC_OF */ +#define _RTC_IFC_OF_MASK 0x1UL /* Bit mask for RTC_OF */ +#define _RTC_IFC_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFC */ +#define RTC_IFC_OF_DEFAULT (_RTC_IFC_OF_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_IFC */ +#define RTC_IFC_COMP0 (0x1UL << 1) /* Clear Compare match 0 Interrupt Flag */ +#define _RTC_IFC_COMP0_SHIFT 1 /* Shift value for RTC_COMP0 */ +#define _RTC_IFC_COMP0_MASK 0x2UL /* Bit mask for RTC_COMP0 */ +#define _RTC_IFC_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFC */ +#define RTC_IFC_COMP0_DEFAULT (_RTC_IFC_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_IFC */ +#define RTC_IFC_COMP1 (0x1UL << 2) /* Clear Compare match 1 Interrupt Flag */ +#define _RTC_IFC_COMP1_SHIFT 2 /* Shift value for RTC_COMP1 */ +#define _RTC_IFC_COMP1_MASK 0x4UL /* Bit mask for RTC_COMP1 */ +#define _RTC_IFC_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IFC */ +#define RTC_IFC_COMP1_DEFAULT (_RTC_IFC_COMP1_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_IFC */ + +/* Bit fields for RTC IEN */ + +#define _RTC_IEN_RESETVALUE 0x00000000UL /* Default value for RTC_IEN */ +#define _RTC_IEN_MASK 0x00000007UL /* Mask for RTC_IEN */ + +#define RTC_IEN_OF (0x1UL << 0) /* Overflow Interrupt Enable */ +#define _RTC_IEN_OF_SHIFT 0 /* Shift value for RTC_OF */ +#define _RTC_IEN_OF_MASK 0x1UL /* Bit mask for RTC_OF */ +#define _RTC_IEN_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IEN */ +#define RTC_IEN_OF_DEFAULT (_RTC_IEN_OF_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_IEN */ +#define RTC_IEN_COMP0 (0x1UL << 1) /* Compare Match 0 Interrupt Enable */ +#define _RTC_IEN_COMP0_SHIFT 1 /* Shift value for RTC_COMP0 */ +#define _RTC_IEN_COMP0_MASK 0x2UL /* Bit mask for RTC_COMP0 */ +#define _RTC_IEN_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IEN */ +#define RTC_IEN_COMP0_DEFAULT (_RTC_IEN_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_IEN */ +#define RTC_IEN_COMP1 (0x1UL << 2) /* Compare Match 1 Interrupt Enable */ +#define _RTC_IEN_COMP1_SHIFT 2 /* Shift value for RTC_COMP1 */ +#define _RTC_IEN_COMP1_MASK 0x4UL /* Bit mask for RTC_COMP1 */ +#define _RTC_IEN_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_IEN */ +#define RTC_IEN_COMP1_DEFAULT (_RTC_IEN_COMP1_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_IEN */ + +/* Bit fields for RTC FREEZE */ + +#define _RTC_FREEZE_RESETVALUE 0x00000000UL /* Default value for RTC_FREEZE */ +#define _RTC_FREEZE_MASK 0x00000001UL /* Mask for RTC_FREEZE */ + +#define RTC_FREEZE_REGFREEZE (0x1UL << 0) /* Register Update Freeze */ +#define _RTC_FREEZE_REGFREEZE_SHIFT 0 /* Shift value for RTC_REGFREEZE */ +#define _RTC_FREEZE_REGFREEZE_MASK 0x1UL /* Bit mask for RTC_REGFREEZE */ +#define _RTC_FREEZE_REGFREEZE_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_FREEZE */ +#define _RTC_FREEZE_REGFREEZE_UPDATE 0x00000000UL /* Mode UPDATE for RTC_FREEZE */ +#define _RTC_FREEZE_REGFREEZE_FREEZE 0x00000001UL /* Mode FREEZE for RTC_FREEZE */ +#define RTC_FREEZE_REGFREEZE_DEFAULT (_RTC_FREEZE_REGFREEZE_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_FREEZE */ +#define RTC_FREEZE_REGFREEZE_UPDATE (_RTC_FREEZE_REGFREEZE_UPDATE << 0) /* Shifted mode UPDATE for RTC_FREEZE */ +#define RTC_FREEZE_REGFREEZE_FREEZE (_RTC_FREEZE_REGFREEZE_FREEZE << 0) /* Shifted mode FREEZE for RTC_FREEZE */ + +/* Bit fields for RTC SYNCBUSY */ + +#define _RTC_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for RTC_SYNCBUSY */ +#define _RTC_SYNCBUSY_MASK 0x00000007UL /* Mask for RTC_SYNCBUSY */ + +#define RTC_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _RTC_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for RTC_CTRL */ +#define _RTC_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for RTC_CTRL */ +#define _RTC_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_CTRL_DEFAULT (_RTC_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_COMP0 (0x1UL << 1) /* COMP0 Register Busy */ +#define _RTC_SYNCBUSY_COMP0_SHIFT 1 /* Shift value for RTC_COMP0 */ +#define _RTC_SYNCBUSY_COMP0_MASK 0x2UL /* Bit mask for RTC_COMP0 */ +#define _RTC_SYNCBUSY_COMP0_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_COMP0_DEFAULT (_RTC_SYNCBUSY_COMP0_DEFAULT << 1) /* Shifted mode DEFAULT for RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_COMP1 (0x1UL << 2) /* COMP1 Register Busy */ +#define _RTC_SYNCBUSY_COMP1_SHIFT 2 /* Shift value for RTC_COMP1 */ +#define _RTC_SYNCBUSY_COMP1_MASK 0x4UL /* Bit mask for RTC_COMP1 */ +#define _RTC_SYNCBUSY_COMP1_DEFAULT 0x00000000UL /* Mode DEFAULT for RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_COMP1_DEFAULT (_RTC_SYNCBUSY_COMP1_DEFAULT << 2) /* Shifted mode DEFAULT for RTC_SYNCBUSY */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_RTC_H */ diff --git a/arch/arm/src/efm32/chip/efm32_timer.h b/arch/arm/src/efm32/chip/efm32_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..86b9aaa51a7e324ab3c6c8a7b4cb9f9c87ac8eef --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_timer.h @@ -0,0 +1,1219 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_timer.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_TIMER_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_TIMER_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this architecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ + +#define EFM32_TIMER_NCC 3 /* Three control channels */ + +/* TIMER Register Offsets ******************************************************************************************************/ + +#define EFM32_TIMER_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_TIMER_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_TIMER_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_TIMER_IEN_OFFSET 0x000c /* Interrupt Enable Register */ +#define EFM32_TIMER_IF_OFFSET 0x0010 /* Interrupt Flag Register */ +#define EFM32_TIMER_IFS_OFFSET 0x0014 /* Interrupt Flag Set Register */ +#define EFM32_TIMER_IFC_OFFSET 0x0018 /* Interrupt Flag Clear Register */ +#define EFM32_TIMER_TOP_OFFSET 0x001c /* Counter Top Value Register */ +#define EFM32_TIMER_TOPB_OFFSET 0x0020 /* Counter Top Value Buffer Register */ +#define EFM32_TIMER_CNT_OFFSET 0x0024 /* Counter Value Register */ +#define EFM32_TIMER_ROUTE_OFFSET 0x0028 /* I/O Routing Register */ + +#define EFM32_TIMER_CC_OFFSET(n) (0x0030 +((n) << 4)) +#define EFM32_TIMER_CC_CTRL_OFFSET 0x0000 /* CC Channel Control Register */ +#define EFM32_TIMER_CC_CCV_OFFSET 0x0004 /* CC Channel Value Register */ +#define EFM32_TIMER_CC_CCVP_OFFSET 0x0008 /* CC Channel Value Peek Register */ +#define EFM32_TIMER_CC_CCVB_OFFSET 0x000c /* CC Channel Buffer Register */ + +#define EFM32_TIMER_CC0_CTRL_OFFSET 0x0030 /* CC Channel Control Register */ +#define EFM32_TIMER_CC0_CCV_OFFSET 0x0034 /* CC Channel Value Register */ +#define EFM32_TIMER_CC0_CCVP_OFFSET 0x0038 /* CC Channel Value Peek Register */ +#define EFM32_TIMER_CC0_CCVB_OFFSET 0x003c /* CC Channel Buffer Register */ +#define EFM32_TIMER_CC1_CTRL_OFFSET 0x0040 /* CC Channel Control Register */ +#define EFM32_TIMER_CC1_CCV_OFFSET 0x0044 /* CC Channel Value Register */ +#define EFM32_TIMER_CC1_CCVP_OFFSET 0x0048 /* CC Channel Value Peek Register */ +#define EFM32_TIMER_CC1_CCVB_OFFSET 0x004c /* CC Channel Buffer Register */ +#define EFM32_TIMER_CC2_CTRL_OFFSET 0x0050 /* CC Channel Control Register */ +#define EFM32_TIMER_CC2_CCV_OFFSET 0x0054 /* CC Channel Value Register */ +#define EFM32_TIMER_CC2_CCVP_OFFSET 0x0058 /* CC Channel Value Peek Register */ +#define EFM32_TIMER_CC2_CCVB_OFFSET 0x005c /* CC Channel Buffer Register */ + +#define EFM32_TIMER_DTCTRL_OFFSET 0x0070 /* DTI Control Register */ +#define EFM32_TIMER_DTTIME_OFFSET 0x0074 /* DTI Time Control Register */ +#define EFM32_TIMER_DTFC_OFFSET 0x0078 /* DTI Fault Configuration Register */ +#define EFM32_TIMER_DTOGEN_OFFSET 0x007c /* DTI Output Generation Enable Register */ +#define EFM32_TIMER_DTFAULT_OFFSET 0x0080 /* DTI Fault Register */ +#define EFM32_TIMER_DTFAULTC_OFFSET 0x0084 /* DTI Fault Clear Register */ +#define EFM32_TIMER_DTLOCK_OFFSET 0x0088 /* DTI Configuration Lock Register */ + +/* TIMER Register Addresses ****************************************************************************************************/ + +#define EFM32_TIMER0_CTRL (EFM32_TIMER0_BASE+EFM32_TIMER_CTRL_OFFSET) +#define EFM32_TIMER0_CMD_ (EFM32_TIMER0_BASE+EFM32_TIMER_CMD_OFFSET) +#define EFM32_TIMER0_STATUS (EFM32_TIMER0_BASE+EFM32_TIMER_STATUS_OFFSET) +#define EFM32_TIMER0_IEN (EFM32_TIMER0_BASE+EFM32_TIMER_IEN_OFFSET) +#define EFM32_TIMER0_IF (EFM32_TIMER0_BASE+EFM32_TIMER_IF_OFFSET) +#define EFM32_TIMER0_IFS (EFM32_TIMER0_BASE+EFM32_TIMER_IFS_OFFSET) +#define EFM32_TIMER0_IFC (EFM32_TIMER0_BASE+EFM32_TIMER_IFC_OFFSET) +#define EFM32_TIMER0_TOP (EFM32_TIMER0_BASE+EFM32_TIMER_TOP_OFFSET) +#define EFM32_TIMER0_TOPB (EFM32_TIMER0_BASE+EFM32_TIMER_TOPB_OFFSET) +#define EFM32_TIMER0_CNT (EFM32_TIMER0_BASE+EFM32_TIMER_CNT_OFFSET) +#define EFM32_TIMER0_ROUTE (EFM32_TIMER0_BASE+EFM32_TIMER_ROUTE_OFFSET) + +#define EFM32_TIMER0_CC(n) (EFM32_TIMER0_BASE+EFM32_TIMER_CC_OFFSET(n)) +#define EFM32_TIMER0_CC_CTRL(n) (EFM32_TIMER0_CC(n)+EFM32_TIMER_CC_CTRL_OFFSET) +#define EFM32_TIMER0_CC_CCV(n) (EFM32_TIMER0_CC(n)+EFM32_TIMER_CC_CCV_OFFSET) +#define EFM32_TIMER0_CC_CCVP(n) (EFM32_TIMER0_CC(n)+EFM32_TIMER_CC_CCVP_OFFSET) +#define EFM32_TIMER0_CC_CCVB(n) (EFM32_TIMER0_CC(n)+EFM32_TIMER_CC_CCVB_OFFSET) + +#define EFM32_TIMER0_CC0_CTRL (EFM32_TIMER0_BASE+EFM32_TIMER_CC0_CTRL_OFFSET) +#define EFM32_TIMER0_CC0_CCV (EFM32_TIMER0_BASE+EFM32_TIMER_CC0_CCV_OFFSET) +#define EFM32_TIMER0_CC0_CCVP (EFM32_TIMER0_BASE+EFM32_TIMER_CC0_CCVP_OFFSET) +#define EFM32_TIMER0_CC0_CCVB (EFM32_TIMER0_BASE+EFM32_TIMER_CC0_CCVB_OFFSET) +#define EFM32_TIMER0_CC1_CTRL (EFM32_TIMER0_BASE+EFM32_TIMER_CC1_CTRL_OFFSET) +#define EFM32_TIMER0_CC1_CCV (EFM32_TIMER0_BASE+EFM32_TIMER_CC1_CCV_OFFSET) +#define EFM32_TIMER0_CC1_CCVP (EFM32_TIMER0_BASE+EFM32_TIMER_CC1_CCVP_OFFSET) +#define EFM32_TIMER0_CC1_CCVB (EFM32_TIMER0_BASE+EFM32_TIMER_CC1_CCVB_OFFSET) +#define EFM32_TIMER0_CC2_CTRL (EFM32_TIMER0_BASE+EFM32_TIMER_CC2_CTRL_OFFSET) +#define EFM32_TIMER0_CC2_CCV (EFM32_TIMER0_BASE+EFM32_TIMER_CC2_CCV_OFFSET) +#define EFM32_TIMER0_CC2_CCVP (EFM32_TIMER0_BASE+EFM32_TIMER_CC2_CCVP_OFFSET) +#define EFM32_TIMER0_CC2_CCVB (EFM32_TIMER0_BASE+EFM32_TIMER_CC2_CCVB_OFFSET) + +#define EFM32_TIMER0_DTCTRL (EFM32_TIMER0_BASE+EFM32_TIMER_DTCTRL_OFFSET) +#define EFM32_TIMER0_DTTIME (EFM32_TIMER0_BASE+EFM32_TIMER_DTTIME_OFFSET) +#define EFM32_TIMER0_DTFC (EFM32_TIMER0_BASE+EFM32_TIMER_DTFC_OFFSET) +#define EFM32_TIMER0_DTOGEN (EFM32_TIMER0_BASE+EFM32_TIMER_DTOGEN_OFFSET) +#define EFM32_TIMER0_DTFAULT (EFM32_TIMER0_BASE+EFM32_TIMER_DTFAULT_OFFSET) +#define EFM32_TIMER0_DTFAULTC (EFM32_TIMER0_BASE+EFM32_TIMER_DTFAULTC_OFFSET) +#define EFM32_TIMER0_DTLOCK (EFM32_TIMER0_BASE+EFM32_TIMER_DTLOCK_OFFSET) + +#define EFM32_TIMER1_CTRL (EFM32_TIMER1_BASE+EFM32_TIMER_CTRL_OFFSET) +#define EFM32_TIMER1_CMD_ (EFM32_TIMER1_BASE+EFM32_TIMER_CMD_OFFSET) +#define EFM32_TIMER1_STATUS (EFM32_TIMER1_BASE+EFM32_TIMER_STATUS_OFFSET) +#define EFM32_TIMER1_IEN (EFM32_TIMER1_BASE+EFM32_TIMER_IEN_OFFSET) +#define EFM32_TIMER1_IF (EFM32_TIMER1_BASE+EFM32_TIMER_IF_OFFSET) +#define EFM32_TIMER1_IFS (EFM32_TIMER1_BASE+EFM32_TIMER_IFS_OFFSET) +#define EFM32_TIMER1_IFC (EFM32_TIMER1_BASE+EFM32_TIMER_IFC_OFFSET) +#define EFM32_TIMER1_TOP (EFM32_TIMER1_BASE+EFM32_TIMER_TOP_OFFSET) +#define EFM32_TIMER1_TOPB (EFM32_TIMER1_BASE+EFM32_TIMER_TOPB_OFFSET) +#define EFM32_TIMER1_CNT (EFM32_TIMER1_BASE+EFM32_TIMER_CNT_OFFSET) +#define EFM32_TIMER1_ROUTE (EFM32_TIMER1_BASE+EFM32_TIMER_ROUTE_OFFSET) + +#define EFM32_TIMER1_CC(n) (EFM32_TIMER1_BASE+EFM32_TIMER_CC_OFFSET(n)) +#define EFM32_TIMER1_CC_CTRL(n) (EFM32_TIMER1_CC(n)+EFM32_TIMER_CC_CTRL_OFFSET) +#define EFM32_TIMER1_CC_CCV(n) (EFM32_TIMER1_CC(n)+EFM32_TIMER_CC_CCV_OFFSET) +#define EFM32_TIMER1_CC_CCVP(n) (EFM32_TIMER1_CC(n)+EFM32_TIMER_CC_CCVP_OFFSET) +#define EFM32_TIMER1_CC_CCVB(n) (EFM32_TIMER1_CC(n)+EFM32_TIMER_CC_CCVB_OFFSET) + +#define EFM32_TIMER1_CC0_CTRL (EFM32_TIMER1_BASE+EFM32_TIMER_CC0_CTRL_OFFSET) +#define EFM32_TIMER1_CC0_CCV (EFM32_TIMER1_BASE+EFM32_TIMER_CC0_CCV_OFFSET) +#define EFM32_TIMER1_CC0_CCVP (EFM32_TIMER1_BASE+EFM32_TIMER_CC0_CCVP_OFFSET) +#define EFM32_TIMER1_CC0_CCVB (EFM32_TIMER1_BASE+EFM32_TIMER_CC0_CCVB_OFFSET) +#define EFM32_TIMER1_CC1_CTRL (EFM32_TIMER1_BASE+EFM32_TIMER_CC1_CTRL_OFFSET) +#define EFM32_TIMER1_CC1_CCV (EFM32_TIMER1_BASE+EFM32_TIMER_CC1_CCV_OFFSET) +#define EFM32_TIMER1_CC1_CCVP (EFM32_TIMER1_BASE+EFM32_TIMER_CC1_CCVP_OFFSET) +#define EFM32_TIMER1_CC1_CCVB (EFM32_TIMER1_BASE+EFM32_TIMER_CC1_CCVB_OFFSET) +#define EFM32_TIMER1_CC2_CTRL (EFM32_TIMER1_BASE+EFM32_TIMER_CC2_CTRL_OFFSET) +#define EFM32_TIMER1_CC2_CCV (EFM32_TIMER1_BASE+EFM32_TIMER_CC2_CCV_OFFSET) +#define EFM32_TIMER1_CC2_CCVP (EFM32_TIMER1_BASE+EFM32_TIMER_CC2_CCVP_OFFSET) +#define EFM32_TIMER1_CC2_CCVB (EFM32_TIMER1_BASE+EFM32_TIMER_CC2_CCVB_OFFSET) + +#define EFM32_TIMER1_DTCTRL (EFM32_TIMER1_BASE+EFM32_TIMER_DTCTRL_OFFSET) +#define EFM32_TIMER1_DTTIME (EFM32_TIMER1_BASE+EFM32_TIMER_DTTIME_OFFSET) +#define EFM32_TIMER1_DTFC (EFM32_TIMER1_BASE+EFM32_TIMER_DTFC_OFFSET) +#define EFM32_TIMER1_DTOGEN (EFM32_TIMER1_BASE+EFM32_TIMER_DTOGEN_OFFSET) +#define EFM32_TIMER1_DTFAULT (EFM32_TIMER1_BASE+EFM32_TIMER_DTFAULT_OFFSET) +#define EFM32_TIMER1_DTFAULTC (EFM32_TIMER1_BASE+EFM32_TIMER_DTFAULTC_OFFSET) +#define EFM32_TIMER1_DTLOCK (EFM32_TIMER1_BASE+EFM32_TIMER_DTLOCK_OFFSET) + +#define EFM32_TIMER2_CTRL (EFM32_TIMER2_BASE+EFM32_TIMER_CTRL_OFFSET) +#define EFM32_TIMER2_CMD_ (EFM32_TIMER2_BASE+EFM32_TIMER_CMD_OFFSET) +#define EFM32_TIMER2_STATUS (EFM32_TIMER2_BASE+EFM32_TIMER_STATUS_OFFSET) +#define EFM32_TIMER2_IEN (EFM32_TIMER2_BASE+EFM32_TIMER_IEN_OFFSET) +#define EFM32_TIMER2_IF (EFM32_TIMER2_BASE+EFM32_TIMER_IF_OFFSET) +#define EFM32_TIMER2_IFS (EFM32_TIMER2_BASE+EFM32_TIMER_IFS_OFFSET) +#define EFM32_TIMER2_IFC (EFM32_TIMER2_BASE+EFM32_TIMER_IFC_OFFSET) +#define EFM32_TIMER2_TOP (EFM32_TIMER2_BASE+EFM32_TIMER_TOP_OFFSET) +#define EFM32_TIMER2_TOPB (EFM32_TIMER2_BASE+EFM32_TIMER_TOPB_OFFSET) +#define EFM32_TIMER2_CNT (EFM32_TIMER2_BASE+EFM32_TIMER_CNT_OFFSET) +#define EFM32_TIMER2_ROUTE (EFM32_TIMER2_BASE+EFM32_TIMER_ROUTE_OFFSET) + +#define EFM32_TIMER2_CC(n) (EFM32_TIMER2_BASE+EFM32_TIMER_CC_OFFSET(n)) +#define EFM32_TIMER2_CC_CTRL(n) (EFM32_TIMER2_CC(n)+EFM32_TIMER_CC_CTRL_OFFSET) +#define EFM32_TIMER2_CC_CCV(n) (EFM32_TIMER2_CC(n)+EFM32_TIMER_CC_CCV_OFFSET) +#define EFM32_TIMER2_CC_CCVP(n) (EFM32_TIMER2_CC(n)+EFM32_TIMER_CC_CCVP_OFFSET) +#define EFM32_TIMER2_CC_CCVB(n) (EFM32_TIMER2_CC(n)+EFM32_TIMER_CC_CCVB_OFFSET) + +#define EFM32_TIMER2_CC0_CTRL (EFM32_TIMER2_BASE+EFM32_TIMER_CC0_CTRL_OFFSET) +#define EFM32_TIMER2_CC0_CCV (EFM32_TIMER2_BASE+EFM32_TIMER_CC0_CCV_OFFSET) +#define EFM32_TIMER2_CC0_CCVP (EFM32_TIMER2_BASE+EFM32_TIMER_CC0_CCVP_OFFSET) +#define EFM32_TIMER2_CC0_CCVB (EFM32_TIMER2_BASE+EFM32_TIMER_CC0_CCVB_OFFSET) +#define EFM32_TIMER2_CC1_CTRL (EFM32_TIMER2_BASE+EFM32_TIMER_CC1_CTRL_OFFSET) +#define EFM32_TIMER2_CC1_CCV (EFM32_TIMER2_BASE+EFM32_TIMER_CC1_CCV_OFFSET) +#define EFM32_TIMER2_CC1_CCVP (EFM32_TIMER2_BASE+EFM32_TIMER_CC1_CCVP_OFFSET) +#define EFM32_TIMER2_CC1_CCVB (EFM32_TIMER2_BASE+EFM32_TIMER_CC1_CCVB_OFFSET) +#define EFM32_TIMER2_CC2_CTRL (EFM32_TIMER2_BASE+EFM32_TIMER_CC2_CTRL_OFFSET) +#define EFM32_TIMER2_CC2_CCV (EFM32_TIMER2_BASE+EFM32_TIMER_CC2_CCV_OFFSET) +#define EFM32_TIMER2_CC2_CCVP (EFM32_TIMER2_BASE+EFM32_TIMER_CC2_CCVP_OFFSET) +#define EFM32_TIMER2_CC2_CCVB (EFM32_TIMER2_BASE+EFM32_TIMER_CC2_CCVB_OFFSET) + +#define EFM32_TIMER2_DTCTRL (EFM32_TIMER2_BASE+EFM32_TIMER_DTCTRL_OFFSET) +#define EFM32_TIMER2_DTTIME (EFM32_TIMER2_BASE+EFM32_TIMER_DTTIME_OFFSET) +#define EFM32_TIMER2_DTFC (EFM32_TIMER2_BASE+EFM32_TIMER_DTFC_OFFSET) +#define EFM32_TIMER2_DTOGEN (EFM32_TIMER2_BASE+EFM32_TIMER_DTOGEN_OFFSET) +#define EFM32_TIMER2_DTFAULT (EFM32_TIMER2_BASE+EFM32_TIMER_DTFAULT_OFFSET) +#define EFM32_TIMER2_DTFAULTC (EFM32_TIMER2_BASE+EFM32_TIMER_DTFAULTC_OFFSET) +#define EFM32_TIMER2_DTLOCK (EFM32_TIMER2_BASE+EFM32_TIMER_DTLOCK_OFFSET) + +#define EFM32_TIMER3_CTRL (EFM32_TIMER3_BASE+EFM32_TIMER_CTRL_OFFSET) +#define EFM32_TIMER3_CMD_ (EFM32_TIMER3_BASE+EFM32_TIMER_CMD_OFFSET) +#define EFM32_TIMER3_STATUS (EFM32_TIMER3_BASE+EFM32_TIMER_STATUS_OFFSET) +#define EFM32_TIMER3_IEN (EFM32_TIMER3_BASE+EFM32_TIMER_IEN_OFFSET) +#define EFM32_TIMER3_IF (EFM32_TIMER3_BASE+EFM32_TIMER_IF_OFFSET) +#define EFM32_TIMER3_IFS (EFM32_TIMER3_BASE+EFM32_TIMER_IFS_OFFSET) +#define EFM32_TIMER3_IFC (EFM32_TIMER3_BASE+EFM32_TIMER_IFC_OFFSET) +#define EFM32_TIMER3_TOP (EFM32_TIMER3_BASE+EFM32_TIMER_TOP_OFFSET) +#define EFM32_TIMER3_TOPB (EFM32_TIMER3_BASE+EFM32_TIMER_TOPB_OFFSET) +#define EFM32_TIMER3_CNT (EFM32_TIMER3_BASE+EFM32_TIMER_CNT_OFFSET) +#define EFM32_TIMER3_ROUTE (EFM32_TIMER3_BASE+EFM32_TIMER_ROUTE_OFFSET) + +#define EFM32_TIMER3_CC(n) (EFM32_TIMER3_BASE+EFM32_TIMER_CC_OFFSET(n)) +#define EFM32_TIMER3_CC_CTRL(n) (EFM32_TIMER3_CC(n)+EFM32_TIMER_CC_CTRL_OFFSET) +#define EFM32_TIMER3_CC_CCV(n) (EFM32_TIMER3_CC(n)+EFM32_TIMER_CC_CCV_OFFSET) +#define EFM32_TIMER3_CC_CCVP(n) (EFM32_TIMER3_CC(n)+EFM32_TIMER_CC_CCVP_OFFSET) +#define EFM32_TIMER3_CC_CCVB(n) (EFM32_TIMER3_CC(n)+EFM32_TIMER_CC_CCVB_OFFSET) + +#define EFM32_TIMER3_CC0_CTRL (EFM32_TIMER3_BASE+EFM32_TIMER_CC0_CTRL_OFFSET) +#define EFM32_TIMER3_CC0_CCV (EFM32_TIMER3_BASE+EFM32_TIMER_CC0_CCV_OFFSET) +#define EFM32_TIMER3_CC0_CCVP (EFM32_TIMER3_BASE+EFM32_TIMER_CC0_CCVP_OFFSET) +#define EFM32_TIMER3_CC0_CCVB (EFM32_TIMER3_BASE+EFM32_TIMER_CC0_CCVB_OFFSET) +#define EFM32_TIMER3_CC1_CTRL (EFM32_TIMER3_BASE+EFM32_TIMER_CC1_CTRL_OFFSET) +#define EFM32_TIMER3_CC1_CCV (EFM32_TIMER3_BASE+EFM32_TIMER_CC1_CCV_OFFSET) +#define EFM32_TIMER3_CC1_CCVP (EFM32_TIMER3_BASE+EFM32_TIMER_CC1_CCVP_OFFSET) +#define EFM32_TIMER3_CC1_CCVB (EFM32_TIMER3_BASE+EFM32_TIMER_CC1_CCVB_OFFSET) +#define EFM32_TIMER3_CC2_CTRL (EFM32_TIMER3_BASE+EFM32_TIMER_CC2_CTRL_OFFSET) +#define EFM32_TIMER3_CC2_CCV (EFM32_TIMER3_BASE+EFM32_TIMER_CC2_CCV_OFFSET) +#define EFM32_TIMER3_CC2_CCVP (EFM32_TIMER3_BASE+EFM32_TIMER_CC2_CCVP_OFFSET) +#define EFM32_TIMER3_CC2_CCVB (EFM32_TIMER3_BASE+EFM32_TIMER_CC2_CCVB_OFFSET) + +#define EFM32_TIMER3_DTCTRL (EFM32_TIMER3_BASE+EFM32_TIMER_DTCTRL_OFFSET) +#define EFM32_TIMER3_DTTIME (EFM32_TIMER3_BASE+EFM32_TIMER_DTTIME_OFFSET) +#define EFM32_TIMER3_DTFC (EFM32_TIMER3_BASE+EFM32_TIMER_DTFC_OFFSET) +#define EFM32_TIMER3_DTOGEN (EFM32_TIMER3_BASE+EFM32_TIMER_DTOGEN_OFFSET) +#define EFM32_TIMER3_DTFAULT (EFM32_TIMER3_BASE+EFM32_TIMER_DTFAULT_OFFSET) +#define EFM32_TIMER3_DTFAULTC (EFM32_TIMER3_BASE+EFM32_TIMER_DTFAULTC_OFFSET) +#define EFM32_TIMER3_DTLOCK (EFM32_TIMER3_BASE+EFM32_TIMER_DTLOCK_OFFSET) + +/* TIMER Register Bit Field Definitions ****************************************************************************************/ + +/* Bit fields for TIMER CTRL */ + +#define _TIMER_CTRL_RESETVALUE 0x00000000UL /* Default value for TIMER_CTRL */ +#define _TIMER_CTRL_MASK 0x3F032FFBUL /* Mask for TIMER_CTRL */ + +#define _TIMER_CTRL_MODE_SHIFT 0 /* Shift value for TIMER_MODE */ +#define _TIMER_CTRL_MODE_MASK 0x3UL /* Bit mask for TIMER_MODE */ +#define _TIMER_CTRL_MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_MODE_UP 0x00000000UL /* Mode UP for TIMER_CTRL */ +#define _TIMER_CTRL_MODE_DOWN 0x00000001UL /* Mode DOWN for TIMER_CTRL */ +#define _TIMER_CTRL_MODE_UPDOWN 0x00000002UL /* Mode UPDOWN for TIMER_CTRL */ +#define _TIMER_CTRL_MODE_QDEC 0x00000003UL /* Mode QDEC for TIMER_CTRL */ +#define TIMER_CTRL_MODE_DEFAULT (_TIMER_CTRL_MODE_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_MODE_UP (_TIMER_CTRL_MODE_UP << 0) /* Shifted mode UP for TIMER_CTRL */ +#define TIMER_CTRL_MODE_DOWN (_TIMER_CTRL_MODE_DOWN << 0) /* Shifted mode DOWN for TIMER_CTRL */ +#define TIMER_CTRL_MODE_UPDOWN (_TIMER_CTRL_MODE_UPDOWN << 0) /* Shifted mode UPDOWN for TIMER_CTRL */ +#define TIMER_CTRL_MODE_QDEC (_TIMER_CTRL_MODE_QDEC << 0) /* Shifted mode QDEC for TIMER_CTRL */ +#define TIMER_CTRL_SYNC (0x1UL << 3) /* Timer Start/Stop/Reload Synchronization */ +#define _TIMER_CTRL_SYNC_SHIFT 3 /* Shift value for TIMER_SYNC */ +#define _TIMER_CTRL_SYNC_MASK 0x8UL /* Bit mask for TIMER_SYNC */ +#define _TIMER_CTRL_SYNC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_SYNC_DEFAULT (_TIMER_CTRL_SYNC_DEFAULT << 3) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_OSMEN (0x1UL << 4) /* One-shot Mode Enable */ +#define _TIMER_CTRL_OSMEN_SHIFT 4 /* Shift value for TIMER_OSMEN */ +#define _TIMER_CTRL_OSMEN_MASK 0x10UL /* Bit mask for TIMER_OSMEN */ +#define _TIMER_CTRL_OSMEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_OSMEN_DEFAULT (_TIMER_CTRL_OSMEN_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_QDM (0x1UL << 5) /* Quadrature Decoder Mode Selection */ +#define _TIMER_CTRL_QDM_SHIFT 5 /* Shift value for TIMER_QDM */ +#define _TIMER_CTRL_QDM_MASK 0x20UL /* Bit mask for TIMER_QDM */ +#define _TIMER_CTRL_QDM_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_QDM_X2 0x00000000UL /* Mode X2 for TIMER_CTRL */ +#define _TIMER_CTRL_QDM_X4 0x00000001UL /* Mode X4 for TIMER_CTRL */ +#define TIMER_CTRL_QDM_DEFAULT (_TIMER_CTRL_QDM_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_QDM_X2 (_TIMER_CTRL_QDM_X2 << 5) /* Shifted mode X2 for TIMER_CTRL */ +#define TIMER_CTRL_QDM_X4 (_TIMER_CTRL_QDM_X4 << 5) /* Shifted mode X4 for TIMER_CTRL */ +#define TIMER_CTRL_DEBUGRUN (0x1UL << 6) /* Debug Mode Run Enable */ +#define _TIMER_CTRL_DEBUGRUN_SHIFT 6 /* Shift value for TIMER_DEBUGRUN */ +#define _TIMER_CTRL_DEBUGRUN_MASK 0x40UL /* Bit mask for TIMER_DEBUGRUN */ +#define _TIMER_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_DEBUGRUN_DEFAULT (_TIMER_CTRL_DEBUGRUN_DEFAULT << 6) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_DMACLRACT (0x1UL << 7) /* DMA Request Clear on Active */ +#define _TIMER_CTRL_DMACLRACT_SHIFT 7 /* Shift value for TIMER_DMACLRACT */ +#define _TIMER_CTRL_DMACLRACT_MASK 0x80UL /* Bit mask for TIMER_DMACLRACT */ +#define _TIMER_CTRL_DMACLRACT_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_DMACLRACT_DEFAULT (_TIMER_CTRL_DMACLRACT_DEFAULT << 7) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_RISEA_SHIFT 8 /* Shift value for TIMER_RISEA */ +#define _TIMER_CTRL_RISEA_MASK 0x300UL /* Bit mask for TIMER_RISEA */ +#define _TIMER_CTRL_RISEA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_RISEA_NONE 0x00000000UL /* Mode NONE for TIMER_CTRL */ +#define _TIMER_CTRL_RISEA_START 0x00000001UL /* Mode START for TIMER_CTRL */ +#define _TIMER_CTRL_RISEA_STOP 0x00000002UL /* Mode STOP for TIMER_CTRL */ +#define _TIMER_CTRL_RISEA_RELOADSTART 0x00000003UL /* Mode RELOADSTART for TIMER_CTRL */ +#define TIMER_CTRL_RISEA_DEFAULT (_TIMER_CTRL_RISEA_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_RISEA_NONE (_TIMER_CTRL_RISEA_NONE << 8) /* Shifted mode NONE for TIMER_CTRL */ +#define TIMER_CTRL_RISEA_START (_TIMER_CTRL_RISEA_START << 8) /* Shifted mode START for TIMER_CTRL */ +#define TIMER_CTRL_RISEA_STOP (_TIMER_CTRL_RISEA_STOP << 8) /* Shifted mode STOP for TIMER_CTRL */ +#define TIMER_CTRL_RISEA_RELOADSTART (_TIMER_CTRL_RISEA_RELOADSTART << 8) /* Shifted mode RELOADSTART for TIMER_CTRL */ +#define _TIMER_CTRL_FALLA_SHIFT 10 /* Shift value for TIMER_FALLA */ +#define _TIMER_CTRL_FALLA_MASK 0xC00UL /* Bit mask for TIMER_FALLA */ +#define _TIMER_CTRL_FALLA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_FALLA_NONE 0x00000000UL /* Mode NONE for TIMER_CTRL */ +#define _TIMER_CTRL_FALLA_START 0x00000001UL /* Mode START for TIMER_CTRL */ +#define _TIMER_CTRL_FALLA_STOP 0x00000002UL /* Mode STOP for TIMER_CTRL */ +#define _TIMER_CTRL_FALLA_RELOADSTART 0x00000003UL /* Mode RELOADSTART for TIMER_CTRL */ +#define TIMER_CTRL_FALLA_DEFAULT (_TIMER_CTRL_FALLA_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_FALLA_NONE (_TIMER_CTRL_FALLA_NONE << 10) /* Shifted mode NONE for TIMER_CTRL */ +#define TIMER_CTRL_FALLA_START (_TIMER_CTRL_FALLA_START << 10) /* Shifted mode START for TIMER_CTRL */ +#define TIMER_CTRL_FALLA_STOP (_TIMER_CTRL_FALLA_STOP << 10) /* Shifted mode STOP for TIMER_CTRL */ +#define TIMER_CTRL_FALLA_RELOADSTART (_TIMER_CTRL_FALLA_RELOADSTART << 10) /* Shifted mode RELOADSTART for TIMER_CTRL */ +#define TIMER_CTRL_X2CNT (0x1UL << 13) /* 2x Count Mode */ +#define _TIMER_CTRL_X2CNT_SHIFT 13 /* Shift value for TIMER_X2CNT */ +#define _TIMER_CTRL_X2CNT_MASK 0x2000UL /* Bit mask for TIMER_X2CNT */ +#define _TIMER_CTRL_X2CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_X2CNT_DEFAULT (_TIMER_CTRL_X2CNT_DEFAULT << 13) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_CLKSEL_SHIFT 16 /* Shift value for TIMER_CLKSEL */ +#define _TIMER_CTRL_CLKSEL_MASK 0x30000UL /* Bit mask for TIMER_CLKSEL */ +#define _TIMER_CTRL_CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_CLKSEL_PRESCHFPERCLK 0x00000000UL /* Mode PRESCHFPERCLK for TIMER_CTRL */ +#define _TIMER_CTRL_CLKSEL_CC1 0x00000001UL /* Mode CC1 for TIMER_CTRL */ +#define _TIMER_CTRL_CLKSEL_TIMEROUF 0x00000002UL /* Mode TIMEROUF for TIMER_CTRL */ +#define TIMER_CTRL_CLKSEL_DEFAULT (_TIMER_CTRL_CLKSEL_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_CLKSEL_PRESCHFPERCLK (_TIMER_CTRL_CLKSEL_PRESCHFPERCLK << 16) /* Shifted mode PRESCHFPERCLK for TIMER_CTRL */ +#define TIMER_CTRL_CLKSEL_CC1 (_TIMER_CTRL_CLKSEL_CC1 << 16) /* Shifted mode CC1 for TIMER_CTRL */ +#define TIMER_CTRL_CLKSEL_TIMEROUF (_TIMER_CTRL_CLKSEL_TIMEROUF << 16) /* Shifted mode TIMEROUF for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_SHIFT 24 /* Shift value for TIMER_PRESC */ +#define _TIMER_CTRL_PRESC_MASK 0xF000000UL /* Bit mask for TIMER_PRESC */ +#define _TIMER_CTRL_PRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV1 0x00000000UL /* Mode DIV1 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV2 0x00000001UL /* Mode DIV2 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV4 0x00000002UL /* Mode DIV4 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV8 0x00000003UL /* Mode DIV8 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV16 0x00000004UL /* Mode DIV16 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV32 0x00000005UL /* Mode DIV32 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV64 0x00000006UL /* Mode DIV64 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV128 0x00000007UL /* Mode DIV128 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV256 0x00000008UL /* Mode DIV256 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV512 0x00000009UL /* Mode DIV512 for TIMER_CTRL */ +#define _TIMER_CTRL_PRESC_DIV1024 0x0000000AUL /* Mode DIV1024 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DEFAULT (_TIMER_CTRL_PRESC_DEFAULT << 24) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV1 (_TIMER_CTRL_PRESC_DIV1 << 24) /* Shifted mode DIV1 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV2 (_TIMER_CTRL_PRESC_DIV2 << 24) /* Shifted mode DIV2 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV4 (_TIMER_CTRL_PRESC_DIV4 << 24) /* Shifted mode DIV4 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV8 (_TIMER_CTRL_PRESC_DIV8 << 24) /* Shifted mode DIV8 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV16 (_TIMER_CTRL_PRESC_DIV16 << 24) /* Shifted mode DIV16 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV32 (_TIMER_CTRL_PRESC_DIV32 << 24) /* Shifted mode DIV32 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV64 (_TIMER_CTRL_PRESC_DIV64 << 24) /* Shifted mode DIV64 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV128 (_TIMER_CTRL_PRESC_DIV128 << 24) /* Shifted mode DIV128 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV256 (_TIMER_CTRL_PRESC_DIV256 << 24) /* Shifted mode DIV256 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV512 (_TIMER_CTRL_PRESC_DIV512 << 24) /* Shifted mode DIV512 for TIMER_CTRL */ +#define TIMER_CTRL_PRESC_DIV1024 (_TIMER_CTRL_PRESC_DIV1024 << 24) /* Shifted mode DIV1024 for TIMER_CTRL */ +#define TIMER_CTRL_ATI (0x1UL << 28) /* Always Track Inputs */ +#define _TIMER_CTRL_ATI_SHIFT 28 /* Shift value for TIMER_ATI */ +#define _TIMER_CTRL_ATI_MASK 0x10000000UL /* Bit mask for TIMER_ATI */ +#define _TIMER_CTRL_ATI_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_ATI_DEFAULT (_TIMER_CTRL_ATI_DEFAULT << 28) /* Shifted mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_RSSCOIST (0x1UL << 29) /* Reload-Start Sets Compare Ouptut initial State */ +#define _TIMER_CTRL_RSSCOIST_SHIFT 29 /* Shift value for TIMER_RSSCOIST */ +#define _TIMER_CTRL_RSSCOIST_MASK 0x20000000UL /* Bit mask for TIMER_RSSCOIST */ +#define _TIMER_CTRL_RSSCOIST_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CTRL */ +#define TIMER_CTRL_RSSCOIST_DEFAULT (_TIMER_CTRL_RSSCOIST_DEFAULT << 29) /* Shifted mode DEFAULT for TIMER_CTRL */ + +/* Bit fields for TIMER CMD */ + +#define _TIMER_CMD_RESETVALUE 0x00000000UL /* Default value for TIMER_CMD */ +#define _TIMER_CMD_MASK 0x00000003UL /* Mask for TIMER_CMD */ + +#define TIMER_CMD_START (0x1UL << 0) /* Start Timer */ +#define _TIMER_CMD_START_SHIFT 0 /* Shift value for TIMER_START */ +#define _TIMER_CMD_START_MASK 0x1UL /* Bit mask for TIMER_START */ +#define _TIMER_CMD_START_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CMD */ +#define TIMER_CMD_START_DEFAULT (_TIMER_CMD_START_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CMD */ +#define TIMER_CMD_STOP (0x1UL << 1) /* Stop Timer */ +#define _TIMER_CMD_STOP_SHIFT 1 /* Shift value for TIMER_STOP */ +#define _TIMER_CMD_STOP_MASK 0x2UL /* Bit mask for TIMER_STOP */ +#define _TIMER_CMD_STOP_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CMD */ +#define TIMER_CMD_STOP_DEFAULT (_TIMER_CMD_STOP_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_CMD */ + +/* Bit fields for TIMER STATUS */ + +#define _TIMER_STATUS_RESETVALUE 0x00000000UL /* Default value for TIMER_STATUS */ +#define _TIMER_STATUS_MASK 0x07070707UL /* Mask for TIMER_STATUS */ + +#define TIMER_STATUS_RUNNING (0x1UL << 0) /* Running */ +#define _TIMER_STATUS_RUNNING_SHIFT 0 /* Shift value for TIMER_RUNNING */ +#define _TIMER_STATUS_RUNNING_MASK 0x1UL /* Bit mask for TIMER_RUNNING */ +#define _TIMER_STATUS_RUNNING_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_RUNNING_DEFAULT (_TIMER_STATUS_RUNNING_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_DIR (0x1UL << 1) /* Direction */ +#define _TIMER_STATUS_DIR_SHIFT 1 /* Shift value for TIMER_DIR */ +#define _TIMER_STATUS_DIR_MASK 0x2UL /* Bit mask for TIMER_DIR */ +#define _TIMER_STATUS_DIR_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define _TIMER_STATUS_DIR_UP 0x00000000UL /* Mode UP for TIMER_STATUS */ +#define _TIMER_STATUS_DIR_DOWN 0x00000001UL /* Mode DOWN for TIMER_STATUS */ +#define TIMER_STATUS_DIR_DEFAULT (_TIMER_STATUS_DIR_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_DIR_UP (_TIMER_STATUS_DIR_UP << 1) /* Shifted mode UP for TIMER_STATUS */ +#define TIMER_STATUS_DIR_DOWN (_TIMER_STATUS_DIR_DOWN << 1) /* Shifted mode DOWN for TIMER_STATUS */ +#define TIMER_STATUS_TOPBV (0x1UL << 2) /* TOPB Valid */ +#define _TIMER_STATUS_TOPBV_SHIFT 2 /* Shift value for TIMER_TOPBV */ +#define _TIMER_STATUS_TOPBV_MASK 0x4UL /* Bit mask for TIMER_TOPBV */ +#define _TIMER_STATUS_TOPBV_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_TOPBV_DEFAULT (_TIMER_STATUS_TOPBV_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV0 (0x1UL << 8) /* CC0 CCVB Valid */ +#define _TIMER_STATUS_CCVBV0_SHIFT 8 /* Shift value for TIMER_CCVBV0 */ +#define _TIMER_STATUS_CCVBV0_MASK 0x100UL /* Bit mask for TIMER_CCVBV0 */ +#define _TIMER_STATUS_CCVBV0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV0_DEFAULT (_TIMER_STATUS_CCVBV0_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV1 (0x1UL << 9) /* CC1 CCVB Valid */ +#define _TIMER_STATUS_CCVBV1_SHIFT 9 /* Shift value for TIMER_CCVBV1 */ +#define _TIMER_STATUS_CCVBV1_MASK 0x200UL /* Bit mask for TIMER_CCVBV1 */ +#define _TIMER_STATUS_CCVBV1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV1_DEFAULT (_TIMER_STATUS_CCVBV1_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV2 (0x1UL << 10) /* CC2 CCVB Valid */ +#define _TIMER_STATUS_CCVBV2_SHIFT 10 /* Shift value for TIMER_CCVBV2 */ +#define _TIMER_STATUS_CCVBV2_MASK 0x400UL /* Bit mask for TIMER_CCVBV2 */ +#define _TIMER_STATUS_CCVBV2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCVBV2_DEFAULT (_TIMER_STATUS_CCVBV2_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV0 (0x1UL << 16) /* CC0 Input Capture Valid */ +#define _TIMER_STATUS_ICV0_SHIFT 16 /* Shift value for TIMER_ICV0 */ +#define _TIMER_STATUS_ICV0_MASK 0x10000UL /* Bit mask for TIMER_ICV0 */ +#define _TIMER_STATUS_ICV0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV0_DEFAULT (_TIMER_STATUS_ICV0_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV1 (0x1UL << 17) /* CC1 Input Capture Valid */ +#define _TIMER_STATUS_ICV1_SHIFT 17 /* Shift value for TIMER_ICV1 */ +#define _TIMER_STATUS_ICV1_MASK 0x20000UL /* Bit mask for TIMER_ICV1 */ +#define _TIMER_STATUS_ICV1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV1_DEFAULT (_TIMER_STATUS_ICV1_DEFAULT << 17) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV2 (0x1UL << 18) /* CC2 Input Capture Valid */ +#define _TIMER_STATUS_ICV2_SHIFT 18 /* Shift value for TIMER_ICV2 */ +#define _TIMER_STATUS_ICV2_MASK 0x40000UL /* Bit mask for TIMER_ICV2 */ +#define _TIMER_STATUS_ICV2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_ICV2_DEFAULT (_TIMER_STATUS_ICV2_DEFAULT << 18) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL0 (0x1UL << 24) /* CC0 Polarity */ +#define _TIMER_STATUS_CCPOL0_SHIFT 24 /* Shift value for TIMER_CCPOL0 */ +#define _TIMER_STATUS_CCPOL0_MASK 0x1000000UL /* Bit mask for TIMER_CCPOL0 */ +#define _TIMER_STATUS_CCPOL0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL0_LOWRISE 0x00000000UL /* Mode LOWRISE for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL0_HIGHFALL 0x00000001UL /* Mode HIGHFALL for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL0_DEFAULT (_TIMER_STATUS_CCPOL0_DEFAULT << 24) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL0_LOWRISE (_TIMER_STATUS_CCPOL0_LOWRISE << 24) /* Shifted mode LOWRISE for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL0_HIGHFALL (_TIMER_STATUS_CCPOL0_HIGHFALL << 24) /* Shifted mode HIGHFALL for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL1 (0x1UL << 25) /* CC1 Polarity */ +#define _TIMER_STATUS_CCPOL1_SHIFT 25 /* Shift value for TIMER_CCPOL1 */ +#define _TIMER_STATUS_CCPOL1_MASK 0x2000000UL /* Bit mask for TIMER_CCPOL1 */ +#define _TIMER_STATUS_CCPOL1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL1_LOWRISE 0x00000000UL /* Mode LOWRISE for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL1_HIGHFALL 0x00000001UL /* Mode HIGHFALL for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL1_DEFAULT (_TIMER_STATUS_CCPOL1_DEFAULT << 25) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL1_LOWRISE (_TIMER_STATUS_CCPOL1_LOWRISE << 25) /* Shifted mode LOWRISE for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL1_HIGHFALL (_TIMER_STATUS_CCPOL1_HIGHFALL << 25) /* Shifted mode HIGHFALL for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL2 (0x1UL << 26) /* CC2 Polarity */ +#define _TIMER_STATUS_CCPOL2_SHIFT 26 /* Shift value for TIMER_CCPOL2 */ +#define _TIMER_STATUS_CCPOL2_MASK 0x4000000UL /* Bit mask for TIMER_CCPOL2 */ +#define _TIMER_STATUS_CCPOL2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL2_LOWRISE 0x00000000UL /* Mode LOWRISE for TIMER_STATUS */ +#define _TIMER_STATUS_CCPOL2_HIGHFALL 0x00000001UL /* Mode HIGHFALL for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL2_DEFAULT (_TIMER_STATUS_CCPOL2_DEFAULT << 26) /* Shifted mode DEFAULT for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL2_LOWRISE (_TIMER_STATUS_CCPOL2_LOWRISE << 26) /* Shifted mode LOWRISE for TIMER_STATUS */ +#define TIMER_STATUS_CCPOL2_HIGHFALL (_TIMER_STATUS_CCPOL2_HIGHFALL << 26) /* Shifted mode HIGHFALL for TIMER_STATUS */ + +/* Bit fields for TIMER IEN */ + +#define _TIMER_IEN_RESETVALUE 0x00000000UL /* Default value for TIMER_IEN */ +#define _TIMER_IEN_MASK 0x00000773UL /* Mask for TIMER_IEN */ + +#define TIMER_IEN_OF (0x1UL << 0) /* Overflow Interrupt Enable */ +#define _TIMER_IEN_OF_SHIFT 0 /* Shift value for TIMER_OF */ +#define _TIMER_IEN_OF_MASK 0x1UL /* Bit mask for TIMER_OF */ +#define _TIMER_IEN_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_OF_DEFAULT (_TIMER_IEN_OF_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_UF (0x1UL << 1) /* Underflow Interrupt Enable */ +#define _TIMER_IEN_UF_SHIFT 1 /* Shift value for TIMER_UF */ +#define _TIMER_IEN_UF_MASK 0x2UL /* Bit mask for TIMER_UF */ +#define _TIMER_IEN_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_UF_DEFAULT (_TIMER_IEN_UF_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC0 (0x1UL << 4) /* CC Channel 0 Interrupt Enable */ +#define _TIMER_IEN_CC0_SHIFT 4 /* Shift value for TIMER_CC0 */ +#define _TIMER_IEN_CC0_MASK 0x10UL /* Bit mask for TIMER_CC0 */ +#define _TIMER_IEN_CC0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC0_DEFAULT (_TIMER_IEN_CC0_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC1 (0x1UL << 5) /* CC Channel 1 Interrupt Enable */ +#define _TIMER_IEN_CC1_SHIFT 5 /* Shift value for TIMER_CC1 */ +#define _TIMER_IEN_CC1_MASK 0x20UL /* Bit mask for TIMER_CC1 */ +#define _TIMER_IEN_CC1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC1_DEFAULT (_TIMER_IEN_CC1_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC2 (0x1UL << 6) /* CC Channel 2 Interrupt Enable */ +#define _TIMER_IEN_CC2_SHIFT 6 /* Shift value for TIMER_CC2 */ +#define _TIMER_IEN_CC2_MASK 0x40UL /* Bit mask for TIMER_CC2 */ +#define _TIMER_IEN_CC2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_CC2_DEFAULT (_TIMER_IEN_CC2_DEFAULT << 6) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF0 (0x1UL << 8) /* CC Channel 0 Input Capture Buffer Overflow Interrupt Enable */ +#define _TIMER_IEN_ICBOF0_SHIFT 8 /* Shift value for TIMER_ICBOF0 */ +#define _TIMER_IEN_ICBOF0_MASK 0x100UL /* Bit mask for TIMER_ICBOF0 */ +#define _TIMER_IEN_ICBOF0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF0_DEFAULT (_TIMER_IEN_ICBOF0_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF1 (0x1UL << 9) /* CC Channel 1 Input Capture Buffer Overflow Interrupt Enable */ +#define _TIMER_IEN_ICBOF1_SHIFT 9 /* Shift value for TIMER_ICBOF1 */ +#define _TIMER_IEN_ICBOF1_MASK 0x200UL /* Bit mask for TIMER_ICBOF1 */ +#define _TIMER_IEN_ICBOF1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF1_DEFAULT (_TIMER_IEN_ICBOF1_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF2 (0x1UL << 10) /* CC Channel 2 Input Capture Buffer Overflow Interrupt Enable */ +#define _TIMER_IEN_ICBOF2_SHIFT 10 /* Shift value for TIMER_ICBOF2 */ +#define _TIMER_IEN_ICBOF2_MASK 0x400UL /* Bit mask for TIMER_ICBOF2 */ +#define _TIMER_IEN_ICBOF2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IEN */ +#define TIMER_IEN_ICBOF2_DEFAULT (_TIMER_IEN_ICBOF2_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_IEN */ + +/* Bit fields for TIMER IF */ + +#define _TIMER_IF_RESETVALUE 0x00000000UL /* Default value for TIMER_IF */ +#define _TIMER_IF_MASK 0x00000773UL /* Mask for TIMER_IF */ + +#define TIMER_IF_OF (0x1UL << 0) /* Overflow Interrupt Flag */ +#define _TIMER_IF_OF_SHIFT 0 /* Shift value for TIMER_OF */ +#define _TIMER_IF_OF_MASK 0x1UL /* Bit mask for TIMER_OF */ +#define _TIMER_IF_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_OF_DEFAULT (_TIMER_IF_OF_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_UF (0x1UL << 1) /* Underflow Interrupt Flag */ +#define _TIMER_IF_UF_SHIFT 1 /* Shift value for TIMER_UF */ +#define _TIMER_IF_UF_MASK 0x2UL /* Bit mask for TIMER_UF */ +#define _TIMER_IF_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_UF_DEFAULT (_TIMER_IF_UF_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC0 (0x1UL << 4) /* CC Channel 0 Interrupt Flag */ +#define _TIMER_IF_CC0_SHIFT 4 /* Shift value for TIMER_CC0 */ +#define _TIMER_IF_CC0_MASK 0x10UL /* Bit mask for TIMER_CC0 */ +#define _TIMER_IF_CC0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC0_DEFAULT (_TIMER_IF_CC0_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC1 (0x1UL << 5) /* CC Channel 1 Interrupt Flag */ +#define _TIMER_IF_CC1_SHIFT 5 /* Shift value for TIMER_CC1 */ +#define _TIMER_IF_CC1_MASK 0x20UL /* Bit mask for TIMER_CC1 */ +#define _TIMER_IF_CC1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC1_DEFAULT (_TIMER_IF_CC1_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC2 (0x1UL << 6) /* CC Channel 2 Interrupt Flag */ +#define _TIMER_IF_CC2_SHIFT 6 /* Shift value for TIMER_CC2 */ +#define _TIMER_IF_CC2_MASK 0x40UL /* Bit mask for TIMER_CC2 */ +#define _TIMER_IF_CC2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_CC2_DEFAULT (_TIMER_IF_CC2_DEFAULT << 6) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF0 (0x1UL << 8) /* CC Channel 0 Input Capture Buffer Overflow Interrupt Flag */ +#define _TIMER_IF_ICBOF0_SHIFT 8 /* Shift value for TIMER_ICBOF0 */ +#define _TIMER_IF_ICBOF0_MASK 0x100UL /* Bit mask for TIMER_ICBOF0 */ +#define _TIMER_IF_ICBOF0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF0_DEFAULT (_TIMER_IF_ICBOF0_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF1 (0x1UL << 9) /* CC Channel 1 Input Capture Buffer Overflow Interrupt Flag */ +#define _TIMER_IF_ICBOF1_SHIFT 9 /* Shift value for TIMER_ICBOF1 */ +#define _TIMER_IF_ICBOF1_MASK 0x200UL /* Bit mask for TIMER_ICBOF1 */ +#define _TIMER_IF_ICBOF1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF1_DEFAULT (_TIMER_IF_ICBOF1_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF2 (0x1UL << 10) /* CC Channel 2 Input Capture Buffer Overflow Interrupt Flag */ +#define _TIMER_IF_ICBOF2_SHIFT 10 /* Shift value for TIMER_ICBOF2 */ +#define _TIMER_IF_ICBOF2_MASK 0x400UL /* Bit mask for TIMER_ICBOF2 */ +#define _TIMER_IF_ICBOF2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IF */ +#define TIMER_IF_ICBOF2_DEFAULT (_TIMER_IF_ICBOF2_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_IF */ + +/* Bit fields for TIMER IFS */ + +#define _TIMER_IFS_RESETVALUE 0x00000000UL /* Default value for TIMER_IFS */ +#define _TIMER_IFS_MASK 0x00000773UL /* Mask for TIMER_IFS */ + +#define TIMER_IFS_OF (0x1UL << 0) /* Overflow Interrupt Flag Set */ +#define _TIMER_IFS_OF_SHIFT 0 /* Shift value for TIMER_OF */ +#define _TIMER_IFS_OF_MASK 0x1UL /* Bit mask for TIMER_OF */ +#define _TIMER_IFS_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_OF_DEFAULT (_TIMER_IFS_OF_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_UF (0x1UL << 1) /* Underflow Interrupt Flag Set */ +#define _TIMER_IFS_UF_SHIFT 1 /* Shift value for TIMER_UF */ +#define _TIMER_IFS_UF_MASK 0x2UL /* Bit mask for TIMER_UF */ +#define _TIMER_IFS_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_UF_DEFAULT (_TIMER_IFS_UF_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC0 (0x1UL << 4) /* CC Channel 0 Interrupt Flag Set */ +#define _TIMER_IFS_CC0_SHIFT 4 /* Shift value for TIMER_CC0 */ +#define _TIMER_IFS_CC0_MASK 0x10UL /* Bit mask for TIMER_CC0 */ +#define _TIMER_IFS_CC0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC0_DEFAULT (_TIMER_IFS_CC0_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC1 (0x1UL << 5) /* CC Channel 1 Interrupt Flag Set */ +#define _TIMER_IFS_CC1_SHIFT 5 /* Shift value for TIMER_CC1 */ +#define _TIMER_IFS_CC1_MASK 0x20UL /* Bit mask for TIMER_CC1 */ +#define _TIMER_IFS_CC1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC1_DEFAULT (_TIMER_IFS_CC1_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC2 (0x1UL << 6) /* CC Channel 2 Interrupt Flag Set */ +#define _TIMER_IFS_CC2_SHIFT 6 /* Shift value for TIMER_CC2 */ +#define _TIMER_IFS_CC2_MASK 0x40UL /* Bit mask for TIMER_CC2 */ +#define _TIMER_IFS_CC2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_CC2_DEFAULT (_TIMER_IFS_CC2_DEFAULT << 6) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF0 (0x1UL << 8) /* CC Channel 0 Input Capture Buffer Overflow Interrupt Flag Set */ +#define _TIMER_IFS_ICBOF0_SHIFT 8 /* Shift value for TIMER_ICBOF0 */ +#define _TIMER_IFS_ICBOF0_MASK 0x100UL /* Bit mask for TIMER_ICBOF0 */ +#define _TIMER_IFS_ICBOF0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF0_DEFAULT (_TIMER_IFS_ICBOF0_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF1 (0x1UL << 9) /* CC Channel 1 Input Capture Buffer Overflow Interrupt Flag Set */ +#define _TIMER_IFS_ICBOF1_SHIFT 9 /* Shift value for TIMER_ICBOF1 */ +#define _TIMER_IFS_ICBOF1_MASK 0x200UL /* Bit mask for TIMER_ICBOF1 */ +#define _TIMER_IFS_ICBOF1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF1_DEFAULT (_TIMER_IFS_ICBOF1_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF2 (0x1UL << 10) /* CC Channel 2 Input Capture Buffer Overflow Interrupt Flag Set */ +#define _TIMER_IFS_ICBOF2_SHIFT 10 /* Shift value for TIMER_ICBOF2 */ +#define _TIMER_IFS_ICBOF2_MASK 0x400UL /* Bit mask for TIMER_ICBOF2 */ +#define _TIMER_IFS_ICBOF2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFS */ +#define TIMER_IFS_ICBOF2_DEFAULT (_TIMER_IFS_ICBOF2_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_IFS */ + +/* Bit fields for TIMER IFC */ + +#define _TIMER_IFC_RESETVALUE 0x00000000UL /* Default value for TIMER_IFC */ +#define _TIMER_IFC_MASK 0x00000773UL /* Mask for TIMER_IFC */ + +#define TIMER_IFC_OF (0x1UL << 0) /* Overflow Interrupt Flag Clear */ +#define _TIMER_IFC_OF_SHIFT 0 /* Shift value for TIMER_OF */ +#define _TIMER_IFC_OF_MASK 0x1UL /* Bit mask for TIMER_OF */ +#define _TIMER_IFC_OF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_OF_DEFAULT (_TIMER_IFC_OF_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_UF (0x1UL << 1) /* Underflow Interrupt Flag Clear */ +#define _TIMER_IFC_UF_SHIFT 1 /* Shift value for TIMER_UF */ +#define _TIMER_IFC_UF_MASK 0x2UL /* Bit mask for TIMER_UF */ +#define _TIMER_IFC_UF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_UF_DEFAULT (_TIMER_IFC_UF_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC0 (0x1UL << 4) /* CC Channel 0 Interrupt Flag Clear */ +#define _TIMER_IFC_CC0_SHIFT 4 /* Shift value for TIMER_CC0 */ +#define _TIMER_IFC_CC0_MASK 0x10UL /* Bit mask for TIMER_CC0 */ +#define _TIMER_IFC_CC0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC0_DEFAULT (_TIMER_IFC_CC0_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC1 (0x1UL << 5) /* CC Channel 1 Interrupt Flag Clear */ +#define _TIMER_IFC_CC1_SHIFT 5 /* Shift value for TIMER_CC1 */ +#define _TIMER_IFC_CC1_MASK 0x20UL /* Bit mask for TIMER_CC1 */ +#define _TIMER_IFC_CC1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC1_DEFAULT (_TIMER_IFC_CC1_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC2 (0x1UL << 6) /* CC Channel 2 Interrupt Flag Clear */ +#define _TIMER_IFC_CC2_SHIFT 6 /* Shift value for TIMER_CC2 */ +#define _TIMER_IFC_CC2_MASK 0x40UL /* Bit mask for TIMER_CC2 */ +#define _TIMER_IFC_CC2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_CC2_DEFAULT (_TIMER_IFC_CC2_DEFAULT << 6) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF0 (0x1UL << 8) /* CC Channel 0 Input Capture Buffer Overflow Interrupt Flag Clear */ +#define _TIMER_IFC_ICBOF0_SHIFT 8 /* Shift value for TIMER_ICBOF0 */ +#define _TIMER_IFC_ICBOF0_MASK 0x100UL /* Bit mask for TIMER_ICBOF0 */ +#define _TIMER_IFC_ICBOF0_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF0_DEFAULT (_TIMER_IFC_ICBOF0_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF1 (0x1UL << 9) /* CC Channel 1 Input Capture Buffer Overflow Interrupt Flag Clear */ +#define _TIMER_IFC_ICBOF1_SHIFT 9 /* Shift value for TIMER_ICBOF1 */ +#define _TIMER_IFC_ICBOF1_MASK 0x200UL /* Bit mask for TIMER_ICBOF1 */ +#define _TIMER_IFC_ICBOF1_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF1_DEFAULT (_TIMER_IFC_ICBOF1_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF2 (0x1UL << 10) /* CC Channel 2 Input Capture Buffer Overflow Interrupt Flag Clear */ +#define _TIMER_IFC_ICBOF2_SHIFT 10 /* Shift value for TIMER_ICBOF2 */ +#define _TIMER_IFC_ICBOF2_MASK 0x400UL /* Bit mask for TIMER_ICBOF2 */ +#define _TIMER_IFC_ICBOF2_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_IFC */ +#define TIMER_IFC_ICBOF2_DEFAULT (_TIMER_IFC_ICBOF2_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_IFC */ + +/* Bit fields for TIMER TOP */ + +#define _TIMER_TOP_RESETVALUE 0x0000FFFFUL /* Default value for TIMER_TOP */ +#define _TIMER_TOP_MASK 0x0000FFFFUL /* Mask for TIMER_TOP */ + +#define _TIMER_TOP_TOP_SHIFT 0 /* Shift value for TIMER_TOP */ +#define _TIMER_TOP_TOP_MASK 0xFFFFUL /* Bit mask for TIMER_TOP */ +#define _TIMER_TOP_TOP_DEFAULT 0x0000FFFFUL /* Mode DEFAULT for TIMER_TOP */ +#define TIMER_TOP_TOP_DEFAULT (_TIMER_TOP_TOP_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_TOP */ + +/* Bit fields for TIMER TOPB */ + +#define _TIMER_TOPB_RESETVALUE 0x00000000UL /* Default value for TIMER_TOPB */ +#define _TIMER_TOPB_MASK 0x0000FFFFUL /* Mask for TIMER_TOPB */ + +#define _TIMER_TOPB_TOPB_SHIFT 0 /* Shift value for TIMER_TOPB */ +#define _TIMER_TOPB_TOPB_MASK 0xFFFFUL /* Bit mask for TIMER_TOPB */ +#define _TIMER_TOPB_TOPB_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_TOPB */ +#define TIMER_TOPB_TOPB_DEFAULT (_TIMER_TOPB_TOPB_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_TOPB */ + +/* Bit fields for TIMER CNT */ + +#define _TIMER_CNT_RESETVALUE 0x00000000UL /* Default value for TIMER_CNT */ +#define _TIMER_CNT_MASK 0x0000FFFFUL /* Mask for TIMER_CNT */ + +#define _TIMER_CNT_CNT_SHIFT 0 /* Shift value for TIMER_CNT */ +#define _TIMER_CNT_CNT_MASK 0xFFFFUL /* Bit mask for TIMER_CNT */ +#define _TIMER_CNT_CNT_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CNT */ +#define TIMER_CNT_CNT_DEFAULT (_TIMER_CNT_CNT_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CNT */ + +/* Bit fields for TIMER ROUTE */ + +#define _TIMER_ROUTE_RESETVALUE 0x00000000UL /* Default value for TIMER_ROUTE */ +#define _TIMER_ROUTE_MASK 0x00070707UL /* Mask for TIMER_ROUTE */ + +#define TIMER_ROUTE_CC0PEN (0x1UL << 0) /* CC Channel 0 Pin Enable */ +#define _TIMER_ROUTE_CC0PEN_SHIFT 0 /* Shift value for TIMER_CC0PEN */ +#define _TIMER_ROUTE_CC0PEN_MASK 0x1UL /* Bit mask for TIMER_CC0PEN */ +#define _TIMER_ROUTE_CC0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CC0PEN_DEFAULT (_TIMER_ROUTE_CC0PEN_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CC1PEN (0x1UL << 1) /* CC Channel 1 Pin Enable */ +#define _TIMER_ROUTE_CC1PEN_SHIFT 1 /* Shift value for TIMER_CC1PEN */ +#define _TIMER_ROUTE_CC1PEN_MASK 0x2UL /* Bit mask for TIMER_CC1PEN */ +#define _TIMER_ROUTE_CC1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CC1PEN_DEFAULT (_TIMER_ROUTE_CC1PEN_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CC2PEN (0x1UL << 2) /* CC Channel 2 Pin Enable */ +#define _TIMER_ROUTE_CC2PEN_SHIFT 2 /* Shift value for TIMER_CC2PEN */ +#define _TIMER_ROUTE_CC2PEN_MASK 0x4UL /* Bit mask for TIMER_CC2PEN */ +#define _TIMER_ROUTE_CC2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CC2PEN_DEFAULT (_TIMER_ROUTE_CC2PEN_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI0PEN (0x1UL << 8) /* CC Channel 0 Complementary Dead-Time Insertion Pin Enable */ +#define _TIMER_ROUTE_CDTI0PEN_SHIFT 8 /* Shift value for TIMER_CDTI0PEN */ +#define _TIMER_ROUTE_CDTI0PEN_MASK 0x100UL /* Bit mask for TIMER_CDTI0PEN */ +#define _TIMER_ROUTE_CDTI0PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI0PEN_DEFAULT (_TIMER_ROUTE_CDTI0PEN_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI1PEN (0x1UL << 9) /* CC Channel 1 Complementary Dead-Time Insertion Pin Enable */ +#define _TIMER_ROUTE_CDTI1PEN_SHIFT 9 /* Shift value for TIMER_CDTI1PEN */ +#define _TIMER_ROUTE_CDTI1PEN_MASK 0x200UL /* Bit mask for TIMER_CDTI1PEN */ +#define _TIMER_ROUTE_CDTI1PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI1PEN_DEFAULT (_TIMER_ROUTE_CDTI1PEN_DEFAULT << 9) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI2PEN (0x1UL << 10) /* CC Channel 2 Complementary Dead-Time Insertion Pin Enable */ +#define _TIMER_ROUTE_CDTI2PEN_SHIFT 10 /* Shift value for TIMER_CDTI2PEN */ +#define _TIMER_ROUTE_CDTI2PEN_MASK 0x400UL /* Bit mask for TIMER_CDTI2PEN */ +#define _TIMER_ROUTE_CDTI2PEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_CDTI2PEN_DEFAULT (_TIMER_ROUTE_CDTI2PEN_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_SHIFT 16 /* Shift value for TIMER_LOCATION */ +#define _TIMER_ROUTE_LOCATION_MASK 0x70000UL /* Bit mask for TIMER_LOCATION */ +#define _TIMER_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_LOC4 0x00000004UL /* Mode LOC4 for TIMER_ROUTE */ +#define _TIMER_ROUTE_LOCATION_LOC5 0x00000005UL /* Mode LOC5 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC0 (_TIMER_ROUTE_LOCATION_LOC0 << 16) /* Shifted mode LOC0 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_DEFAULT (_TIMER_ROUTE_LOCATION_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC1 (_TIMER_ROUTE_LOCATION_LOC1 << 16) /* Shifted mode LOC1 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC2 (_TIMER_ROUTE_LOCATION_LOC2 << 16) /* Shifted mode LOC2 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC3 (_TIMER_ROUTE_LOCATION_LOC3 << 16) /* Shifted mode LOC3 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC4 (_TIMER_ROUTE_LOCATION_LOC4 << 16) /* Shifted mode LOC4 for TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_LOC5 (_TIMER_ROUTE_LOCATION_LOC5 << 16) /* Shifted mode LOC5 for TIMER_ROUTE */ + +/* Bit fields for TIMER CC_CTRL */ + +#define _TIMER_CC_CTRL_RESETVALUE 0x00000000UL /* Default value for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_MASK 0x0F3F3F17UL /* Mask for TIMER_CC_CTRL */ + +#define _TIMER_CC_CTRL_MODE_SHIFT 0 /* Shift value for TIMER_MODE */ +#define _TIMER_CC_CTRL_MODE_MASK 0x3UL /* Bit mask for TIMER_MODE */ +#define _TIMER_CC_CTRL_MODE_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_MODE_OFF 0x00000000UL /* Mode OFF for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_MODE_INPUTCAPTURE 0x00000001UL /* Mode INPUTCAPTURE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE 0x00000002UL /* Mode OUTPUTCOMPARE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_MODE_PWM 0x00000003UL /* Mode PWM for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_MODE_DEFAULT (_TIMER_CC_CTRL_MODE_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_MODE_OFF (_TIMER_CC_CTRL_MODE_OFF << 0) /* Shifted mode OFF for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_MODE_INPUTCAPTURE (_TIMER_CC_CTRL_MODE_INPUTCAPTURE << 0) /* Shifted mode INPUTCAPTURE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_MODE_OUTPUTCOMPARE (_TIMER_CC_CTRL_MODE_OUTPUTCOMPARE << 0) /* Shifted mode OUTPUTCOMPARE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_MODE_PWM (_TIMER_CC_CTRL_MODE_PWM << 0) /* Shifted mode PWM for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_OUTINV (0x1UL << 2) /* Output Invert */ +#define _TIMER_CC_CTRL_OUTINV_SHIFT 2 /* Shift value for TIMER_OUTINV */ +#define _TIMER_CC_CTRL_OUTINV_MASK 0x4UL /* Bit mask for TIMER_OUTINV */ +#define _TIMER_CC_CTRL_OUTINV_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_OUTINV_DEFAULT (_TIMER_CC_CTRL_OUTINV_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COIST (0x1UL << 4) /* Compare Output Initial State */ +#define _TIMER_CC_CTRL_COIST_SHIFT 4 /* Shift value for TIMER_COIST */ +#define _TIMER_CC_CTRL_COIST_MASK 0x10UL /* Bit mask for TIMER_COIST */ +#define _TIMER_CC_CTRL_COIST_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COIST_DEFAULT (_TIMER_CC_CTRL_COIST_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CMOA_SHIFT 8 /* Shift value for TIMER_CMOA */ +#define _TIMER_CC_CTRL_CMOA_MASK 0x300UL /* Bit mask for TIMER_CMOA */ +#define _TIMER_CC_CTRL_CMOA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CMOA_NONE 0x00000000UL /* Mode NONE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CMOA_TOGGLE 0x00000001UL /* Mode TOGGLE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CMOA_CLEAR 0x00000002UL /* Mode CLEAR for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CMOA_SET 0x00000003UL /* Mode SET for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CMOA_DEFAULT (_TIMER_CC_CTRL_CMOA_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CMOA_NONE (_TIMER_CC_CTRL_CMOA_NONE << 8) /* Shifted mode NONE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CMOA_TOGGLE (_TIMER_CC_CTRL_CMOA_TOGGLE << 8) /* Shifted mode TOGGLE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CMOA_CLEAR (_TIMER_CC_CTRL_CMOA_CLEAR << 8) /* Shifted mode CLEAR for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CMOA_SET (_TIMER_CC_CTRL_CMOA_SET << 8) /* Shifted mode SET for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_COFOA_SHIFT 10 /* Shift value for TIMER_COFOA */ +#define _TIMER_CC_CTRL_COFOA_MASK 0xC00UL /* Bit mask for TIMER_COFOA */ +#define _TIMER_CC_CTRL_COFOA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_COFOA_NONE 0x00000000UL /* Mode NONE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_COFOA_TOGGLE 0x00000001UL /* Mode TOGGLE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_COFOA_CLEAR 0x00000002UL /* Mode CLEAR for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_COFOA_SET 0x00000003UL /* Mode SET for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COFOA_DEFAULT (_TIMER_CC_CTRL_COFOA_DEFAULT << 10) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COFOA_NONE (_TIMER_CC_CTRL_COFOA_NONE << 10) /* Shifted mode NONE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COFOA_TOGGLE (_TIMER_CC_CTRL_COFOA_TOGGLE << 10) /* Shifted mode TOGGLE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COFOA_CLEAR (_TIMER_CC_CTRL_COFOA_CLEAR << 10) /* Shifted mode CLEAR for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_COFOA_SET (_TIMER_CC_CTRL_COFOA_SET << 10) /* Shifted mode SET for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CUFOA_SHIFT 12 /* Shift value for TIMER_CUFOA */ +#define _TIMER_CC_CTRL_CUFOA_MASK 0x3000UL /* Bit mask for TIMER_CUFOA */ +#define _TIMER_CC_CTRL_CUFOA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CUFOA_NONE 0x00000000UL /* Mode NONE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CUFOA_TOGGLE 0x00000001UL /* Mode TOGGLE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CUFOA_CLEAR 0x00000002UL /* Mode CLEAR for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_CUFOA_SET 0x00000003UL /* Mode SET for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CUFOA_DEFAULT (_TIMER_CC_CTRL_CUFOA_DEFAULT << 12) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CUFOA_NONE (_TIMER_CC_CTRL_CUFOA_NONE << 12) /* Shifted mode NONE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CUFOA_TOGGLE (_TIMER_CC_CTRL_CUFOA_TOGGLE << 12) /* Shifted mode TOGGLE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CUFOA_CLEAR (_TIMER_CC_CTRL_CUFOA_CLEAR << 12) /* Shifted mode CLEAR for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_CUFOA_SET (_TIMER_CC_CTRL_CUFOA_SET << 12) /* Shifted mode SET for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_SHIFT 16 /* Shift value for TIMER_PRSSEL */ +#define _TIMER_CC_CTRL_PRSSEL_MASK 0xF0000UL /* Bit mask for TIMER_PRSSEL */ +#define _TIMER_CC_CTRL_PRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_PRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_DEFAULT (_TIMER_CC_CTRL_PRSSEL_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH0 (_TIMER_CC_CTRL_PRSSEL_PRSCH0 << 16) /* Shifted mode PRSCH0 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH1 (_TIMER_CC_CTRL_PRSSEL_PRSCH1 << 16) /* Shifted mode PRSCH1 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH2 (_TIMER_CC_CTRL_PRSSEL_PRSCH2 << 16) /* Shifted mode PRSCH2 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH3 (_TIMER_CC_CTRL_PRSSEL_PRSCH3 << 16) /* Shifted mode PRSCH3 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH4 (_TIMER_CC_CTRL_PRSSEL_PRSCH4 << 16) /* Shifted mode PRSCH4 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH5 (_TIMER_CC_CTRL_PRSSEL_PRSCH5 << 16) /* Shifted mode PRSCH5 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH6 (_TIMER_CC_CTRL_PRSSEL_PRSCH6 << 16) /* Shifted mode PRSCH6 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH7 (_TIMER_CC_CTRL_PRSSEL_PRSCH7 << 16) /* Shifted mode PRSCH7 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH8 (_TIMER_CC_CTRL_PRSSEL_PRSCH8 << 16) /* Shifted mode PRSCH8 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH9 (_TIMER_CC_CTRL_PRSSEL_PRSCH9 << 16) /* Shifted mode PRSCH9 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH10 (_TIMER_CC_CTRL_PRSSEL_PRSCH10 << 16) /* Shifted mode PRSCH10 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_PRSSEL_PRSCH11 (_TIMER_CC_CTRL_PRSSEL_PRSCH11 << 16) /* Shifted mode PRSCH11 for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_INSEL (0x1UL << 20) /* Input Selection */ +#define _TIMER_CC_CTRL_INSEL_SHIFT 20 /* Shift value for TIMER_INSEL */ +#define _TIMER_CC_CTRL_INSEL_MASK 0x100000UL /* Bit mask for TIMER_INSEL */ +#define _TIMER_CC_CTRL_INSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_INSEL_PIN 0x00000000UL /* Mode PIN for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_INSEL_PRS 0x00000001UL /* Mode PRS for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_INSEL_DEFAULT (_TIMER_CC_CTRL_INSEL_DEFAULT << 20) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_INSEL_PIN (_TIMER_CC_CTRL_INSEL_PIN << 20) /* Shifted mode PIN for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_INSEL_PRS (_TIMER_CC_CTRL_INSEL_PRS << 20) /* Shifted mode PRS for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_FILT (0x1UL << 21) /* Digital Filter */ +#define _TIMER_CC_CTRL_FILT_SHIFT 21 /* Shift value for TIMER_FILT */ +#define _TIMER_CC_CTRL_FILT_MASK 0x200000UL /* Bit mask for TIMER_FILT */ +#define _TIMER_CC_CTRL_FILT_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_FILT_DISABLE 0x00000000UL /* Mode DISABLE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_FILT_ENABLE 0x00000001UL /* Mode ENABLE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_FILT_DEFAULT (_TIMER_CC_CTRL_FILT_DEFAULT << 21) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_FILT_DISABLE (_TIMER_CC_CTRL_FILT_DISABLE << 21) /* Shifted mode DISABLE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_FILT_ENABLE (_TIMER_CC_CTRL_FILT_ENABLE << 21) /* Shifted mode ENABLE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEDGE_SHIFT 24 /* Shift value for TIMER_ICEDGE */ +#define _TIMER_CC_CTRL_ICEDGE_MASK 0x3000000UL /* Bit mask for TIMER_ICEDGE */ +#define _TIMER_CC_CTRL_ICEDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEDGE_RISING 0x00000000UL /* Mode RISING for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEDGE_FALLING 0x00000001UL /* Mode FALLING for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEDGE_BOTH 0x00000002UL /* Mode BOTH for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEDGE_NONE 0x00000003UL /* Mode NONE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEDGE_DEFAULT (_TIMER_CC_CTRL_ICEDGE_DEFAULT << 24) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEDGE_RISING (_TIMER_CC_CTRL_ICEDGE_RISING << 24) /* Shifted mode RISING for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEDGE_FALLING (_TIMER_CC_CTRL_ICEDGE_FALLING << 24) /* Shifted mode FALLING for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEDGE_BOTH (_TIMER_CC_CTRL_ICEDGE_BOTH << 24) /* Shifted mode BOTH for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEDGE_NONE (_TIMER_CC_CTRL_ICEDGE_NONE << 24) /* Shifted mode NONE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_SHIFT 26 /* Shift value for TIMER_ICEVCTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_MASK 0xC000000UL /* Bit mask for TIMER_ICEVCTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE 0x00000000UL /* Mode EVERYEDGE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE 0x00000001UL /* Mode EVERYSECONDEDGE for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_RISING 0x00000002UL /* Mode RISING for TIMER_CC_CTRL */ +#define _TIMER_CC_CTRL_ICEVCTRL_FALLING 0x00000003UL /* Mode FALLING for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_DEFAULT (_TIMER_CC_CTRL_ICEVCTRL_DEFAULT << 26) /* Shifted mode DEFAULT for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE (_TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE << 26) /* Shifted mode EVERYEDGE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE (_TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE << 26) /* Shifted mode EVERYSECONDEDGE for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_RISING (_TIMER_CC_CTRL_ICEVCTRL_RISING << 26) /* Shifted mode RISING for TIMER_CC_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_FALLING (_TIMER_CC_CTRL_ICEVCTRL_FALLING << 26) /* Shifted mode FALLING for TIMER_CC_CTRL */ + +/* Bit fields for TIMER CC_CCV */ + +#define _TIMER_CC_CCV_RESETVALUE 0x00000000UL /* Default value for TIMER_CC_CCV */ +#define _TIMER_CC_CCV_MASK 0x0000FFFFUL /* Mask for TIMER_CC_CCV */ + +#define _TIMER_CC_CCV_CCV_SHIFT 0 /* Shift value for TIMER_CCV */ +#define _TIMER_CC_CCV_CCV_MASK 0xFFFFUL /* Bit mask for TIMER_CCV */ +#define _TIMER_CC_CCV_CCV_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CCV */ +#define TIMER_CC_CCV_CCV_DEFAULT (_TIMER_CC_CCV_CCV_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CC_CCV */ + +/* Bit fields for TIMER CC_CCVP */ + +#define _TIMER_CC_CCVP_RESETVALUE 0x00000000UL /* Default value for TIMER_CC_CCVP */ +#define _TIMER_CC_CCVP_MASK 0x0000FFFFUL /* Mask for TIMER_CC_CCVP */ + +#define _TIMER_CC_CCVP_CCVP_SHIFT 0 /* Shift value for TIMER_CCVP */ +#define _TIMER_CC_CCVP_CCVP_MASK 0xFFFFUL /* Bit mask for TIMER_CCVP */ +#define _TIMER_CC_CCVP_CCVP_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CCVP */ +#define TIMER_CC_CCVP_CCVP_DEFAULT (_TIMER_CC_CCVP_CCVP_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CC_CCVP */ + +/* Bit fields for TIMER CC_CCVB */ + +#define _TIMER_CC_CCVB_RESETVALUE 0x00000000UL /* Default value for TIMER_CC_CCVB */ +#define _TIMER_CC_CCVB_MASK 0x0000FFFFUL /* Mask for TIMER_CC_CCVB */ + +#define _TIMER_CC_CCVB_CCVB_SHIFT 0 /* Shift value for TIMER_CCVB */ +#define _TIMER_CC_CCVB_CCVB_MASK 0xFFFFUL /* Bit mask for TIMER_CCVB */ +#define _TIMER_CC_CCVB_CCVB_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_CC_CCVB */ +#define TIMER_CC_CCVB_CCVB_DEFAULT (_TIMER_CC_CCVB_CCVB_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_CC_CCVB */ + +/* Bit fields for TIMER DTCTRL */ + +#define _TIMER_DTCTRL_RESETVALUE 0x00000000UL /* Default value for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_MASK 0x010000FFUL /* Mask for TIMER_DTCTRL */ + +#define TIMER_DTCTRL_DTEN (0x1UL << 0) /* DTI Enable */ +#define _TIMER_DTCTRL_DTEN_SHIFT 0 /* Shift value for TIMER_DTEN */ +#define _TIMER_DTCTRL_DTEN_MASK 0x1UL /* Bit mask for TIMER_DTEN */ +#define _TIMER_DTCTRL_DTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTEN_DEFAULT (_TIMER_DTCTRL_DTEN_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTDAS (0x1UL << 1) /* DTI Automatic Start-up Functionality */ +#define _TIMER_DTCTRL_DTDAS_SHIFT 1 /* Shift value for TIMER_DTDAS */ +#define _TIMER_DTCTRL_DTDAS_MASK 0x2UL /* Bit mask for TIMER_DTDAS */ +#define _TIMER_DTCTRL_DTDAS_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTDAS_NORESTART 0x00000000UL /* Mode NORESTART for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTDAS_RESTART 0x00000001UL /* Mode RESTART for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTDAS_DEFAULT (_TIMER_DTCTRL_DTDAS_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTDAS_NORESTART (_TIMER_DTCTRL_DTDAS_NORESTART << 1) /* Shifted mode NORESTART for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTDAS_RESTART (_TIMER_DTCTRL_DTDAS_RESTART << 1) /* Shifted mode RESTART for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTIPOL (0x1UL << 2) /* DTI Inactive Polarity */ +#define _TIMER_DTCTRL_DTIPOL_SHIFT 2 /* Shift value for TIMER_DTIPOL */ +#define _TIMER_DTCTRL_DTIPOL_MASK 0x4UL /* Bit mask for TIMER_DTIPOL */ +#define _TIMER_DTCTRL_DTIPOL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTIPOL_DEFAULT (_TIMER_DTCTRL_DTIPOL_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTCINV (0x1UL << 3) /* DTI Complementary Output Invert. */ +#define _TIMER_DTCTRL_DTCINV_SHIFT 3 /* Shift value for TIMER_DTCINV */ +#define _TIMER_DTCTRL_DTCINV_MASK 0x8UL /* Bit mask for TIMER_DTCINV */ +#define _TIMER_DTCTRL_DTCINV_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTCINV_DEFAULT (_TIMER_DTCTRL_DTCINV_DEFAULT << 3) /* Shifted mode DEFAULT for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_SHIFT 4 /* Shift value for TIMER_DTPRSSEL */ +#define _TIMER_DTCTRL_DTPRSSEL_MASK 0xF0UL /* Bit mask for TIMER_DTPRSSEL */ +#define _TIMER_DTCTRL_DTPRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for TIMER_DTCTRL */ +#define _TIMER_DTCTRL_DTPRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_DEFAULT (_TIMER_DTCTRL_DTPRSSEL_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH0 (_TIMER_DTCTRL_DTPRSSEL_PRSCH0 << 4) /* Shifted mode PRSCH0 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH1 (_TIMER_DTCTRL_DTPRSSEL_PRSCH1 << 4) /* Shifted mode PRSCH1 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH2 (_TIMER_DTCTRL_DTPRSSEL_PRSCH2 << 4) /* Shifted mode PRSCH2 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH3 (_TIMER_DTCTRL_DTPRSSEL_PRSCH3 << 4) /* Shifted mode PRSCH3 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH4 (_TIMER_DTCTRL_DTPRSSEL_PRSCH4 << 4) /* Shifted mode PRSCH4 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH5 (_TIMER_DTCTRL_DTPRSSEL_PRSCH5 << 4) /* Shifted mode PRSCH5 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH6 (_TIMER_DTCTRL_DTPRSSEL_PRSCH6 << 4) /* Shifted mode PRSCH6 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH7 (_TIMER_DTCTRL_DTPRSSEL_PRSCH7 << 4) /* Shifted mode PRSCH7 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH8 (_TIMER_DTCTRL_DTPRSSEL_PRSCH8 << 4) /* Shifted mode PRSCH8 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH9 (_TIMER_DTCTRL_DTPRSSEL_PRSCH9 << 4) /* Shifted mode PRSCH9 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH10 (_TIMER_DTCTRL_DTPRSSEL_PRSCH10 << 4) /* Shifted mode PRSCH10 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSSEL_PRSCH11 (_TIMER_DTCTRL_DTPRSSEL_PRSCH11 << 4) /* Shifted mode PRSCH11 for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSEN (0x1UL << 24) /* DTI PRS Source Enable */ +#define _TIMER_DTCTRL_DTPRSEN_SHIFT 24 /* Shift value for TIMER_DTPRSEN */ +#define _TIMER_DTCTRL_DTPRSEN_MASK 0x1000000UL /* Bit mask for TIMER_DTPRSEN */ +#define _TIMER_DTCTRL_DTPRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSEN_DEFAULT (_TIMER_DTCTRL_DTPRSEN_DEFAULT << 24) /* Shifted mode DEFAULT for TIMER_DTCTRL */ + +/* Bit fields for TIMER DTTIME */ + +#define _TIMER_DTTIME_RESETVALUE 0x00000000UL /* Default value for TIMER_DTTIME */ +#define _TIMER_DTTIME_MASK 0x003F3F0FUL /* Mask for TIMER_DTTIME */ + +#define _TIMER_DTTIME_DTPRESC_SHIFT 0 /* Shift value for TIMER_DTPRESC */ +#define _TIMER_DTTIME_DTPRESC_MASK 0xFUL /* Bit mask for TIMER_DTPRESC */ +#define _TIMER_DTTIME_DTPRESC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV1 0x00000000UL /* Mode DIV1 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV2 0x00000001UL /* Mode DIV2 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV4 0x00000002UL /* Mode DIV4 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV8 0x00000003UL /* Mode DIV8 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV16 0x00000004UL /* Mode DIV16 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV32 0x00000005UL /* Mode DIV32 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV64 0x00000006UL /* Mode DIV64 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV128 0x00000007UL /* Mode DIV128 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV256 0x00000008UL /* Mode DIV256 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV512 0x00000009UL /* Mode DIV512 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTPRESC_DIV1024 0x0000000AUL /* Mode DIV1024 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DEFAULT (_TIMER_DTTIME_DTPRESC_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV1 (_TIMER_DTTIME_DTPRESC_DIV1 << 0) /* Shifted mode DIV1 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV2 (_TIMER_DTTIME_DTPRESC_DIV2 << 0) /* Shifted mode DIV2 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV4 (_TIMER_DTTIME_DTPRESC_DIV4 << 0) /* Shifted mode DIV4 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV8 (_TIMER_DTTIME_DTPRESC_DIV8 << 0) /* Shifted mode DIV8 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV16 (_TIMER_DTTIME_DTPRESC_DIV16 << 0) /* Shifted mode DIV16 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV32 (_TIMER_DTTIME_DTPRESC_DIV32 << 0) /* Shifted mode DIV32 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV64 (_TIMER_DTTIME_DTPRESC_DIV64 << 0) /* Shifted mode DIV64 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV128 (_TIMER_DTTIME_DTPRESC_DIV128 << 0) /* Shifted mode DIV128 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV256 (_TIMER_DTTIME_DTPRESC_DIV256 << 0) /* Shifted mode DIV256 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV512 (_TIMER_DTTIME_DTPRESC_DIV512 << 0) /* Shifted mode DIV512 for TIMER_DTTIME */ +#define TIMER_DTTIME_DTPRESC_DIV1024 (_TIMER_DTTIME_DTPRESC_DIV1024 << 0) /* Shifted mode DIV1024 for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTRISET_SHIFT 8 /* Shift value for TIMER_DTRISET */ +#define _TIMER_DTTIME_DTRISET_MASK 0x3F00UL /* Bit mask for TIMER_DTRISET */ +#define _TIMER_DTTIME_DTRISET_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTTIME */ +#define TIMER_DTTIME_DTRISET_DEFAULT (_TIMER_DTTIME_DTRISET_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_DTTIME */ +#define _TIMER_DTTIME_DTFALLT_SHIFT 16 /* Shift value for TIMER_DTFALLT */ +#define _TIMER_DTTIME_DTFALLT_MASK 0x3F0000UL /* Bit mask for TIMER_DTFALLT */ +#define _TIMER_DTTIME_DTFALLT_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTTIME */ +#define TIMER_DTTIME_DTFALLT_DEFAULT (_TIMER_DTTIME_DTFALLT_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_DTTIME */ + +/* Bit fields for TIMER DTFC */ + +#define _TIMER_DTFC_RESETVALUE 0x00000000UL /* Default value for TIMER_DTFC */ +#define _TIMER_DTFC_MASK 0x0F030707UL /* Mask for TIMER_DTFC */ + +#define _TIMER_DTFC_DTPRS0FSEL_SHIFT 0 /* Shift value for TIMER_DTPRS0FSEL */ +#define _TIMER_DTFC_DTPRS0FSEL_MASK 0x7UL /* Bit mask for TIMER_DTPRS0FSEL */ +#define _TIMER_DTFC_DTPRS0FSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS0FSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_DEFAULT (_TIMER_DTFC_DTPRS0FSEL_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH0 (_TIMER_DTFC_DTPRS0FSEL_PRSCH0 << 0) /* Shifted mode PRSCH0 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH1 (_TIMER_DTFC_DTPRS0FSEL_PRSCH1 << 0) /* Shifted mode PRSCH1 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH2 (_TIMER_DTFC_DTPRS0FSEL_PRSCH2 << 0) /* Shifted mode PRSCH2 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH3 (_TIMER_DTFC_DTPRS0FSEL_PRSCH3 << 0) /* Shifted mode PRSCH3 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH4 (_TIMER_DTFC_DTPRS0FSEL_PRSCH4 << 0) /* Shifted mode PRSCH4 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH5 (_TIMER_DTFC_DTPRS0FSEL_PRSCH5 << 0) /* Shifted mode PRSCH5 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH6 (_TIMER_DTFC_DTPRS0FSEL_PRSCH6 << 0) /* Shifted mode PRSCH6 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FSEL_PRSCH7 (_TIMER_DTFC_DTPRS0FSEL_PRSCH7 << 0) /* Shifted mode PRSCH7 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_SHIFT 8 /* Shift value for TIMER_DTPRS1FSEL */ +#define _TIMER_DTFC_DTPRS1FSEL_MASK 0x700UL /* Bit mask for TIMER_DTPRS1FSEL */ +#define _TIMER_DTFC_DTPRS1FSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for TIMER_DTFC */ +#define _TIMER_DTFC_DTPRS1FSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_DEFAULT (_TIMER_DTFC_DTPRS1FSEL_DEFAULT << 8) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH0 (_TIMER_DTFC_DTPRS1FSEL_PRSCH0 << 8) /* Shifted mode PRSCH0 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH1 (_TIMER_DTFC_DTPRS1FSEL_PRSCH1 << 8) /* Shifted mode PRSCH1 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH2 (_TIMER_DTFC_DTPRS1FSEL_PRSCH2 << 8) /* Shifted mode PRSCH2 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH3 (_TIMER_DTFC_DTPRS1FSEL_PRSCH3 << 8) /* Shifted mode PRSCH3 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH4 (_TIMER_DTFC_DTPRS1FSEL_PRSCH4 << 8) /* Shifted mode PRSCH4 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH5 (_TIMER_DTFC_DTPRS1FSEL_PRSCH5 << 8) /* Shifted mode PRSCH5 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH6 (_TIMER_DTFC_DTPRS1FSEL_PRSCH6 << 8) /* Shifted mode PRSCH6 for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FSEL_PRSCH7 (_TIMER_DTFC_DTPRS1FSEL_PRSCH7 << 8) /* Shifted mode PRSCH7 for TIMER_DTFC */ +#define _TIMER_DTFC_DTFA_SHIFT 16 /* Shift value for TIMER_DTFA */ +#define _TIMER_DTFC_DTFA_MASK 0x30000UL /* Bit mask for TIMER_DTFA */ +#define _TIMER_DTFC_DTFA_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define _TIMER_DTFC_DTFA_NONE 0x00000000UL /* Mode NONE for TIMER_DTFC */ +#define _TIMER_DTFC_DTFA_INACTIVE 0x00000001UL /* Mode INACTIVE for TIMER_DTFC */ +#define _TIMER_DTFC_DTFA_CLEAR 0x00000002UL /* Mode CLEAR for TIMER_DTFC */ +#define _TIMER_DTFC_DTFA_TRISTATE 0x00000003UL /* Mode TRISTATE for TIMER_DTFC */ +#define TIMER_DTFC_DTFA_DEFAULT (_TIMER_DTFC_DTFA_DEFAULT << 16) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTFA_NONE (_TIMER_DTFC_DTFA_NONE << 16) /* Shifted mode NONE for TIMER_DTFC */ +#define TIMER_DTFC_DTFA_INACTIVE (_TIMER_DTFC_DTFA_INACTIVE << 16) /* Shifted mode INACTIVE for TIMER_DTFC */ +#define TIMER_DTFC_DTFA_CLEAR (_TIMER_DTFC_DTFA_CLEAR << 16) /* Shifted mode CLEAR for TIMER_DTFC */ +#define TIMER_DTFC_DTFA_TRISTATE (_TIMER_DTFC_DTFA_TRISTATE << 16) /* Shifted mode TRISTATE for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FEN (0x1UL << 24) /* DTI PRS 0 Fault Enable */ +#define _TIMER_DTFC_DTPRS0FEN_SHIFT 24 /* Shift value for TIMER_DTPRS0FEN */ +#define _TIMER_DTFC_DTPRS0FEN_MASK 0x1000000UL /* Bit mask for TIMER_DTPRS0FEN */ +#define _TIMER_DTFC_DTPRS0FEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS0FEN_DEFAULT (_TIMER_DTFC_DTPRS0FEN_DEFAULT << 24) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FEN (0x1UL << 25) /* DTI PRS 1 Fault Enable */ +#define _TIMER_DTFC_DTPRS1FEN_SHIFT 25 /* Shift value for TIMER_DTPRS1FEN */ +#define _TIMER_DTFC_DTPRS1FEN_MASK 0x2000000UL /* Bit mask for TIMER_DTPRS1FEN */ +#define _TIMER_DTFC_DTPRS1FEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTPRS1FEN_DEFAULT (_TIMER_DTFC_DTPRS1FEN_DEFAULT << 25) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTDBGFEN (0x1UL << 26) /* DTI Debugger Fault Enable */ +#define _TIMER_DTFC_DTDBGFEN_SHIFT 26 /* Shift value for TIMER_DTDBGFEN */ +#define _TIMER_DTFC_DTDBGFEN_MASK 0x4000000UL /* Bit mask for TIMER_DTDBGFEN */ +#define _TIMER_DTFC_DTDBGFEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTDBGFEN_DEFAULT (_TIMER_DTFC_DTDBGFEN_DEFAULT << 26) /* Shifted mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTLOCKUPFEN (0x1UL << 27) /* DTI Lockup Fault Enable */ +#define _TIMER_DTFC_DTLOCKUPFEN_SHIFT 27 /* Shift value for TIMER_DTLOCKUPFEN */ +#define _TIMER_DTFC_DTLOCKUPFEN_MASK 0x8000000UL /* Bit mask for TIMER_DTLOCKUPFEN */ +#define _TIMER_DTFC_DTLOCKUPFEN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFC */ +#define TIMER_DTFC_DTLOCKUPFEN_DEFAULT (_TIMER_DTFC_DTLOCKUPFEN_DEFAULT << 27) /* Shifted mode DEFAULT for TIMER_DTFC */ + +/* Bit fields for TIMER DTOGEN */ + +#define _TIMER_DTOGEN_RESETVALUE 0x00000000UL /* Default value for TIMER_DTOGEN */ +#define _TIMER_DTOGEN_MASK 0x0000003FUL /* Mask for TIMER_DTOGEN */ + +#define TIMER_DTOGEN_DTOGCC0EN (0x1UL << 0) /* DTI CC0 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCC0EN_SHIFT 0 /* Shift value for TIMER_DTOGCC0EN */ +#define _TIMER_DTOGEN_DTOGCC0EN_MASK 0x1UL /* Bit mask for TIMER_DTOGCC0EN */ +#define _TIMER_DTOGEN_DTOGCC0EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCC0EN_DEFAULT (_TIMER_DTOGEN_DTOGCC0EN_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCC1EN (0x1UL << 1) /* DTI CC1 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCC1EN_SHIFT 1 /* Shift value for TIMER_DTOGCC1EN */ +#define _TIMER_DTOGEN_DTOGCC1EN_MASK 0x2UL /* Bit mask for TIMER_DTOGCC1EN */ +#define _TIMER_DTOGEN_DTOGCC1EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCC1EN_DEFAULT (_TIMER_DTOGEN_DTOGCC1EN_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCC2EN (0x1UL << 2) /* DTI CC2 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCC2EN_SHIFT 2 /* Shift value for TIMER_DTOGCC2EN */ +#define _TIMER_DTOGEN_DTOGCC2EN_MASK 0x4UL /* Bit mask for TIMER_DTOGCC2EN */ +#define _TIMER_DTOGEN_DTOGCC2EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCC2EN_DEFAULT (_TIMER_DTOGEN_DTOGCC2EN_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI0EN (0x1UL << 3) /* DTI CDTI0 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCDTI0EN_SHIFT 3 /* Shift value for TIMER_DTOGCDTI0EN */ +#define _TIMER_DTOGEN_DTOGCDTI0EN_MASK 0x8UL /* Bit mask for TIMER_DTOGCDTI0EN */ +#define _TIMER_DTOGEN_DTOGCDTI0EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI0EN_DEFAULT (_TIMER_DTOGEN_DTOGCDTI0EN_DEFAULT << 3) /* Shifted mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI1EN (0x1UL << 4) /* DTI CDTI1 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCDTI1EN_SHIFT 4 /* Shift value for TIMER_DTOGCDTI1EN */ +#define _TIMER_DTOGEN_DTOGCDTI1EN_MASK 0x10UL /* Bit mask for TIMER_DTOGCDTI1EN */ +#define _TIMER_DTOGEN_DTOGCDTI1EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI1EN_DEFAULT (_TIMER_DTOGEN_DTOGCDTI1EN_DEFAULT << 4) /* Shifted mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI2EN (0x1UL << 5) /* DTI CDTI2 Output Generation Enable */ +#define _TIMER_DTOGEN_DTOGCDTI2EN_SHIFT 5 /* Shift value for TIMER_DTOGCDTI2EN */ +#define _TIMER_DTOGEN_DTOGCDTI2EN_MASK 0x20UL /* Bit mask for TIMER_DTOGCDTI2EN */ +#define _TIMER_DTOGEN_DTOGCDTI2EN_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI2EN_DEFAULT (_TIMER_DTOGEN_DTOGCDTI2EN_DEFAULT << 5) /* Shifted mode DEFAULT for TIMER_DTOGEN */ + +/* Bit fields for TIMER DTFAULT */ + +#define _TIMER_DTFAULT_RESETVALUE 0x00000000UL /* Default value for TIMER_DTFAULT */ +#define _TIMER_DTFAULT_MASK 0x0000000FUL /* Mask for TIMER_DTFAULT */ + +#define TIMER_DTFAULT_DTPRS0F (0x1UL << 0) /* DTI PRS 0 Fault */ +#define _TIMER_DTFAULT_DTPRS0F_SHIFT 0 /* Shift value for TIMER_DTPRS0F */ +#define _TIMER_DTFAULT_DTPRS0F_MASK 0x1UL /* Bit mask for TIMER_DTPRS0F */ +#define _TIMER_DTFAULT_DTPRS0F_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTPRS0F_DEFAULT (_TIMER_DTFAULT_DTPRS0F_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTPRS1F (0x1UL << 1) /* DTI PRS 1 Fault */ +#define _TIMER_DTFAULT_DTPRS1F_SHIFT 1 /* Shift value for TIMER_DTPRS1F */ +#define _TIMER_DTFAULT_DTPRS1F_MASK 0x2UL /* Bit mask for TIMER_DTPRS1F */ +#define _TIMER_DTFAULT_DTPRS1F_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTPRS1F_DEFAULT (_TIMER_DTFAULT_DTPRS1F_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTDBGF (0x1UL << 2) /* DTI Debugger Fault */ +#define _TIMER_DTFAULT_DTDBGF_SHIFT 2 /* Shift value for TIMER_DTDBGF */ +#define _TIMER_DTFAULT_DTDBGF_MASK 0x4UL /* Bit mask for TIMER_DTDBGF */ +#define _TIMER_DTFAULT_DTDBGF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTDBGF_DEFAULT (_TIMER_DTFAULT_DTDBGF_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTLOCKUPF (0x1UL << 3) /* DTI Lockup Fault */ +#define _TIMER_DTFAULT_DTLOCKUPF_SHIFT 3 /* Shift value for TIMER_DTLOCKUPF */ +#define _TIMER_DTFAULT_DTLOCKUPF_MASK 0x8UL /* Bit mask for TIMER_DTLOCKUPF */ +#define _TIMER_DTFAULT_DTLOCKUPF_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTLOCKUPF_DEFAULT (_TIMER_DTFAULT_DTLOCKUPF_DEFAULT << 3) /* Shifted mode DEFAULT for TIMER_DTFAULT */ + +/* Bit fields for TIMER DTFAULTC */ + +#define _TIMER_DTFAULTC_RESETVALUE 0x00000000UL /* Default value for TIMER_DTFAULTC */ +#define _TIMER_DTFAULTC_MASK 0x0000000FUL /* Mask for TIMER_DTFAULTC */ + +#define TIMER_DTFAULTC_DTPRS0FC (0x1UL << 0) /* DTI PRS0 Fault Clear */ +#define _TIMER_DTFAULTC_DTPRS0FC_SHIFT 0 /* Shift value for TIMER_DTPRS0FC */ +#define _TIMER_DTFAULTC_DTPRS0FC_MASK 0x1UL /* Bit mask for TIMER_DTPRS0FC */ +#define _TIMER_DTFAULTC_DTPRS0FC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_DTPRS0FC_DEFAULT (_TIMER_DTFAULTC_DTPRS0FC_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_DTPRS1FC (0x1UL << 1) /* DTI PRS1 Fault Clear */ +#define _TIMER_DTFAULTC_DTPRS1FC_SHIFT 1 /* Shift value for TIMER_DTPRS1FC */ +#define _TIMER_DTFAULTC_DTPRS1FC_MASK 0x2UL /* Bit mask for TIMER_DTPRS1FC */ +#define _TIMER_DTFAULTC_DTPRS1FC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_DTPRS1FC_DEFAULT (_TIMER_DTFAULTC_DTPRS1FC_DEFAULT << 1) /* Shifted mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_DTDBGFC (0x1UL << 2) /* DTI Debugger Fault Clear */ +#define _TIMER_DTFAULTC_DTDBGFC_SHIFT 2 /* Shift value for TIMER_DTDBGFC */ +#define _TIMER_DTFAULTC_DTDBGFC_MASK 0x4UL /* Bit mask for TIMER_DTDBGFC */ +#define _TIMER_DTFAULTC_DTDBGFC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_DTDBGFC_DEFAULT (_TIMER_DTFAULTC_DTDBGFC_DEFAULT << 2) /* Shifted mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_TLOCKUPFC (0x1UL << 3) /* DTI Lockup Fault Clear */ +#define _TIMER_DTFAULTC_TLOCKUPFC_SHIFT 3 /* Shift value for TIMER_TLOCKUPFC */ +#define _TIMER_DTFAULTC_TLOCKUPFC_MASK 0x8UL /* Bit mask for TIMER_TLOCKUPFC */ +#define _TIMER_DTFAULTC_TLOCKUPFC_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_TLOCKUPFC_DEFAULT (_TIMER_DTFAULTC_TLOCKUPFC_DEFAULT << 3) /* Shifted mode DEFAULT for TIMER_DTFAULTC */ + +/* Bit fields for TIMER DTLOCK */ + +#define _TIMER_DTLOCK_RESETVALUE 0x00000000UL /* Default value for TIMER_DTLOCK */ +#define _TIMER_DTLOCK_MASK 0x0000FFFFUL /* Mask for TIMER_DTLOCK */ + +#define _TIMER_DTLOCK_LOCKKEY_SHIFT 0 /* Shift value for TIMER_LOCKKEY */ +#define _TIMER_DTLOCK_LOCKKEY_MASK 0xFFFFUL /* Bit mask for TIMER_LOCKKEY */ +#define _TIMER_DTLOCK_LOCKKEY_DEFAULT 0x00000000UL /* Mode DEFAULT for TIMER_DTLOCK */ +#define _TIMER_DTLOCK_LOCKKEY_LOCK 0x00000000UL /* Mode LOCK for TIMER_DTLOCK */ +#define _TIMER_DTLOCK_LOCKKEY_UNLOCKED 0x00000000UL /* Mode UNLOCKED for TIMER_DTLOCK */ +#define _TIMER_DTLOCK_LOCKKEY_LOCKED 0x00000001UL /* Mode LOCKED for TIMER_DTLOCK */ +#define _TIMER_DTLOCK_LOCKKEY_UNLOCK 0x0000CE80UL /* Mode UNLOCK for TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_DEFAULT (_TIMER_DTLOCK_LOCKKEY_DEFAULT << 0) /* Shifted mode DEFAULT for TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_LOCK (_TIMER_DTLOCK_LOCKKEY_LOCK << 0) /* Shifted mode LOCK for TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_UNLOCKED (_TIMER_DTLOCK_LOCKKEY_UNLOCKED << 0) /* Shifted mode UNLOCKED for TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_LOCKED (_TIMER_DTLOCK_LOCKKEY_LOCKED << 0) /* Shifted mode LOCKED for TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_UNLOCK (_TIMER_DTLOCK_LOCKKEY_UNLOCK << 0) /* Shifted mode UNLOCK for TIMER_DTLOCK */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_TIMER_H */ diff --git a/arch/arm/src/efm32/chip/efm32_usart.h b/arch/arm/src/efm32/chip/efm32_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..6cd1372c3be9fac2e7935ae4c99e40bf0f89d0bf --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_usart.h @@ -0,0 +1,1383 @@ +/******************************************************************************************************************************** + * arch/arm/src/efm32/EFM32GG/efm32_usart.h + * + * (C) Copyright 2014 Silicon Labs, http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no + * obligation to support this Software. Silicon Labs is providing the + * Software "AS IS", with no express or implied warranties of any kind, + * including, but not limited to, any implied warranties of merchantability + * or fitness for any particular purpose or warranties against infringement + * of any proprietary rights of a third party. + * + * Silicon Labs will not be liable for any consequential, incidental, or + * special damages, or any other relief, or for any claim by any third party, + * arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USART_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USART_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) && !defined(CONFIG_EFM32_EFM32G) +# warning This is the EFM32GG/G header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* The UART is functionally equivalent to the USART with the following exceptions. The register map and register descriptions + * are equal to those of the USART. + * + * - Synchronous operation Not available. SYNC, CSMA, CSINV, CPOL and CPHA in USARTn_CTRL, and MASTEREN in USARTn_STATUS + * are always 0. + * - Transmission direction Always LSB first. MSBF in USARTn_CTRL is always 0. + * - Chip-select Not available. AUTOCS in USARTn_CTRL is always 0. + * - SmartCard mode Not available. SCMODE in USARTn_CTRL is always 0. + * - Frame size Limited to 8-9 databits. Other configurations of DATABITS in USARTn_FRAME are not possible. + * - IrDA Not available. IREN in USARTn_IRCTRL is always 0. + */ + +/* USART Register Offsets ******************************************************************************************************/ + +#define EFM32_USART_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_USART_FRAME_OFFSET 0x0004 /* USART Frame Format Register */ +#define EFM32_USART_TRIGCTRL_OFFSET 0x0008 /* USART Trigger Control register */ +#define EFM32_USART_CMD_OFFSET 0x000c /* Command Register */ +#define EFM32_USART_STATUS_OFFSET 0x0010 /* USART Status Register */ +#define EFM32_USART_CLKDIV_OFFSET 0x0014 /* Clock Control Register */ +#define EFM32_USART_RXDATAX_OFFSET 0x0018 /* RX Buffer Data Extended Register */ +#define EFM32_USART_RXDATA_OFFSET 0x001c /* RX Buffer Data Register */ +#define EFM32_USART_RXDOUBLEX_OFFSET 0x0020 /* RX Buffer Double Data Extended Register */ +#define EFM32_USART_RXDOUBLE_OFFSET 0x0024 /* RX Double Data Register */ +#define EFM32_USART_RXDATAXP_OFFSET 0x0028 /* RX Buffer Data Extended Peek Register */ +#define EFM32_USART_RXDOUBLEXP_OFFSET 0x002c /* RX Buffer Double Data Extended Peek Register */ +#define EFM32_USART_TXDATAX_OFFSET 0x0030 /* TX Buffer Data Extended Register */ +#define EFM32_USART_TXDATA_OFFSET 0x0034 /* TX Buffer Data Register */ +#define EFM32_USART_TXDOUBLEX_OFFSET 0x0038 /* TX Buffer Double Data Extended Register */ +#define EFM32_USART_TXDOUBLE_OFFSET 0x003c /* TX Buffer Double Data Register */ +#define EFM32_USART_IF_OFFSET 0x0040 /* Interrupt Flag Register */ +#define EFM32_USART_IFS_OFFSET 0x0044 /* Interrupt Flag Set Register */ +#define EFM32_USART_IFC_OFFSET 0x0048 /* Interrupt Flag Clear Register */ +#define EFM32_USART_IEN_OFFSET 0x004c /* Interrupt Enable Register */ +#define EFM32_USART_IRCTRL_OFFSET 0x0050 /* IrDA Control Register */ +#define EFM32_USART_ROUTE_OFFSET 0x0054 /* I/O Routing Register */ +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_USART_INPUT_OFFSET 0x0058 /* USART Input Register */ +# define EFM32_USART_I2SCTRL_OFFSET 0x005c /* I2S Control Register */ +#endif + +/* USART Register Addresses ****************************************************************************************************/ + +#define EFM32_USART0_CTRL (EFM32_USART0_BASE+EFM32_USART_CTRL_OFFSET) +#define EFM32_USART0_FRAME (EFM32_USART0_BASE+EFM32_USART_FRAME_OFFSET) +#define EFM32_USART0_TRIGCTRL (EFM32_USART0_BASE+EFM32_USART_TRIGCTRL_OFFSET) +#define EFM32_USART0_CMD (EFM32_USART0_BASE+EFM32_USART_CMD_OFFSET) +#define EFM32_USART0_STATUS (EFM32_USART0_BASE+EFM32_USART_STATUS_OFFSET) +#define EFM32_USART0_CLKDIV (EFM32_USART0_BASE+EFM32_USART_CLKDIV_OFFSET) +#define EFM32_USART0_RXDATAX (EFM32_USART0_BASE+EFM32_USART_RXDATAX_OFFSET) +#define EFM32_USART0_RXDATA (EFM32_USART0_BASE+EFM32_USART_RXDATA_OFFSET) +#define EFM32_USART0_RXDOUBLEX (EFM32_USART0_BASE+EFM32_USART_RXDOUBLEX_OFFSET) +#define EFM32_USART0_RXDOUBLE (EFM32_USART0_BASE+EFM32_USART_RXDOUBLE_OFFSET) +#define EFM32_USART0_RXDATAXP (EFM32_USART0_BASE+EFM32_USART_RXDATAXP_OFFSET) +#define EFM32_USART0_RXDOUBLEXP (EFM32_USART0_BASE+EFM32_USART_RXDOUBLEXP_OFFSET) +#define EFM32_USART0_TXDATAX (EFM32_USART0_BASE+EFM32_USART_TXDATAX_OFFSET) +#define EFM32_USART0_TXDATA (EFM32_USART0_BASE+EFM32_USART_TXDATA_OFFSET) +#define EFM32_USART0_TXDOUBLEX (EFM32_USART0_BASE+EFM32_USART_TXDOUBLEX_OFFSET) +#define EFM32_USART0_TXDOUBLE (EFM32_USART0_BASE+EFM32_USART_TXDOUBLE_OFFSET) +#define EFM32_USART0_IF (EFM32_USART0_BASE+EFM32_USART_IF_OFFSET) +#define EFM32_USART0_IFS (EFM32_USART0_BASE+EFM32_USART_IFS_OFFSET) +#define EFM32_USART0_IFC (EFM32_USART0_BASE+EFM32_USART_IFC_OFFSET) +#define EFM32_USART0_IEN (EFM32_USART0_BASE+EFM32_USART_IEN_OFFSET) +#define EFM32_USART0_IRCTRL (EFM32_USART0_BASE+EFM32_USART_IRCTRL_OFFSET) +#define EFM32_USART0_ROUTE (EFM32_USART0_BASE+EFM32_USART_ROUTE_OFFSET) +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_USART0_INPUT (EFM32_USART0_BASE+EFM32_USART_INPUT_OFFSET) +# define EFM32_USART0_I2SCTRL (EFM32_USART0_BASE+EFM32_USART_I2SCTRL_OFFSET) +#endif + +#define EFM32_USART1_CTRL (EFM32_USART1_BASE+EFM32_USART_CTRL_OFFSET) +#define EFM32_USART1_FRAME (EFM32_USART1_BASE+EFM32_USART_FRAME_OFFSET) +#define EFM32_USART1_TRIGCTRL (EFM32_USART1_BASE+EFM32_USART_TRIGCTRL_OFFSET) +#define EFM32_USART1_CMD (EFM32_USART1_BASE+EFM32_USART_CMD_OFFSET) +#define EFM32_USART1_STATUS (EFM32_USART1_BASE+EFM32_USART_STATUS_OFFSET) +#define EFM32_USART1_CLKDIV (EFM32_USART1_BASE+EFM32_USART_CLKDIV_OFFSET) +#define EFM32_USART1_RXDATAX (EFM32_USART1_BASE+EFM32_USART_RXDATAX_OFFSET) +#define EFM32_USART1_RXDATA (EFM32_USART1_BASE+EFM32_USART_RXDATA_OFFSET) +#define EFM32_USART1_RXDOUBLEX (EFM32_USART1_BASE+EFM32_USART_RXDOUBLEX_OFFSET) +#define EFM32_USART1_RXDOUBLE (EFM32_USART1_BASE+EFM32_USART_RXDOUBLE_OFFSET) +#define EFM32_USART1_RXDATAXP (EFM32_USART1_BASE+EFM32_USART_RXDATAXP_OFFSET) +#define EFM32_USART1_RXDOUBLEXP (EFM32_USART1_BASE+EFM32_USART_RXDOUBLEXP_OFFSET) +#define EFM32_USART1_TXDATAX (EFM32_USART1_BASE+EFM32_USART_TXDATAX_OFFSET) +#define EFM32_USART1_TXDATA (EFM32_USART1_BASE+EFM32_USART_TXDATA_OFFSET) +#define EFM32_USART1_TXDOUBLEX (EFM32_USART1_BASE+EFM32_USART_TXDOUBLEX_OFFSET) +#define EFM32_USART1_TXDOUBLE (EFM32_USART1_BASE+EFM32_USART_TXDOUBLE_OFFSET) +#define EFM32_USART1_IF (EFM32_USART1_BASE+EFM32_USART_IF_OFFSET) +#define EFM32_USART1_IFS (EFM32_USART1_BASE+EFM32_USART_IFS_OFFSET) +#define EFM32_USART1_IFC (EFM32_USART1_BASE+EFM32_USART_IFC_OFFSET) +#define EFM32_USART1_IEN (EFM32_USART1_BASE+EFM32_USART_IEN_OFFSET) +#define EFM32_USART1_IRCTRL (EFM32_USART1_BASE+EFM32_USART_IRCTRL_OFFSET) +#define EFM32_USART1_ROUTE (EFM32_USART1_BASE+EFM32_USART_ROUTE_OFFSET) +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_USART1_INPUT (EFM32_USART1_BASE+EFM32_USART_INPUT_OFFSET) +# define EFM32_USART1_I2SCTRL (EFM32_USART1_BASE+EFM32_USART_I2SCTRL_OFFSET) +#endif + +#define EFM32_USART2_CTRL (EFM32_USART2_BASE+EFM32_USART_CTRL_OFFSET) +#define EFM32_USART2_FRAME (EFM32_USART2_BASE+EFM32_USART_FRAME_OFFSET) +#define EFM32_USART2_TRIGCTRL (EFM32_USART2_BASE+EFM32_USART_TRIGCTRL_OFFSET) +#define EFM32_USART2_CMD (EFM32_USART2_BASE+EFM32_USART_CMD_OFFSET) +#define EFM32_USART2_STATUS (EFM32_USART2_BASE+EFM32_USART_STATUS_OFFSET) +#define EFM32_USART2_CLKDIV (EFM32_USART2_BASE+EFM32_USART_CLKDIV_OFFSET) +#define EFM32_USART2_RXDATAX (EFM32_USART2_BASE+EFM32_USART_RXDATAX_OFFSET) +#define EFM32_USART2_RXDATA (EFM32_USART2_BASE+EFM32_USART_RXDATA_OFFSET) +#define EFM32_USART2_RXDOUBLEX (EFM32_USART2_BASE+EFM32_USART_RXDOUBLEX_OFFSET) +#define EFM32_USART2_RXDOUBLE (EFM32_USART2_BASE+EFM32_USART_RXDOUBLE_OFFSET) +#define EFM32_USART2_RXDATAXP (EFM32_USART2_BASE+EFM32_USART_RXDATAXP_OFFSET) +#define EFM32_USART2_RXDOUBLEXP (EFM32_USART2_BASE+EFM32_USART_RXDOUBLEXP_OFFSET) +#define EFM32_USART2_TXDATAX (EFM32_USART2_BASE+EFM32_USART_TXDATAX_OFFSET) +#define EFM32_USART2_TXDATA (EFM32_USART2_BASE+EFM32_USART_TXDATA_OFFSET) +#define EFM32_USART2_TXDOUBLEX (EFM32_USART2_BASE+EFM32_USART_TXDOUBLEX_OFFSET) +#define EFM32_USART2_TXDOUBLE (EFM32_USART2_BASE+EFM32_USART_TXDOUBLE_OFFSET) +#define EFM32_USART2_IF (EFM32_USART2_BASE+EFM32_USART_IF_OFFSET) +#define EFM32_USART2_IFS (EFM32_USART2_BASE+EFM32_USART_IFS_OFFSET) +#define EFM32_USART2_IFC (EFM32_USART2_BASE+EFM32_USART_IFC_OFFSET) +#define EFM32_USART2_IEN (EFM32_USART2_BASE+EFM32_USART_IEN_OFFSET) +#define EFM32_USART2_IRCTRL (EFM32_USART2_BASE+EFM32_USART_IRCTRL_OFFSET) +#define EFM32_USART2_ROUTE (EFM32_USART2_BASE+EFM32_USART_ROUTE_OFFSET) +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_USART2_INPUT (EFM32_USART2_BASE+EFM32_USART_INPUT_OFFSET) +# define EFM32_USART2_I2SCTRL (EFM32_USART2_BASE+EFM32_USART_I2SCTRL_OFFSET) +#endif + +#define EFM32_UART0_CTRL (EFM32_UART0_BASE+EFM32_USART_CTRL_OFFSET) +#define EFM32_UART0_FRAME (EFM32_UART0_BASE+EFM32_USART_FRAME_OFFSET) +#define EFM32_UART0_TRIGCTRL (EFM32_UART0_BASE+EFM32_USART_TRIGCTRL_OFFSET) +#define EFM32_UART0_CMD (EFM32_UART0_BASE+EFM32_USART_CMD_OFFSET) +#define EFM32_UART0_STATUS (EFM32_UART0_BASE+EFM32_USART_STATUS_OFFSET) +#define EFM32_UART0_CLKDIV (EFM32_UART0_BASE+EFM32_USART_CLKDIV_OFFSET) +#define EFM32_UART0_RXDATAX (EFM32_UART0_BASE+EFM32_USART_RXDATAX_OFFSET) +#define EFM32_UART0_RXDATA (EFM32_UART0_BASE+EFM32_USART_RXDATA_OFFSET) +#define EFM32_UART0_RXDOUBLEX (EFM32_UART0_BASE+EFM32_USART_RXDOUBLEX_OFFSET) +#define EFM32_UART0_RXDOUBLE (EFM32_UART0_BASE+EFM32_USART_RXDOUBLE_OFFSET) +#define EFM32_UART0_RXDATAXP (EFM32_UART0_BASE+EFM32_USART_RXDATAXP_OFFSET) +#define EFM32_UART0_RXDOUBLEXP (EFM32_UART0_BASE+EFM32_USART_RXDOUBLEXP_OFFSET) +#define EFM32_UART0_TXDATAX (EFM32_UART0_BASE+EFM32_USART_TXDATAX_OFFSET) +#define EFM32_UART0_TXDATA (EFM32_UART0_BASE+EFM32_USART_TXDATA_OFFSET) +#define EFM32_UART0_TXDOUBLEX (EFM32_UART0_BASE+EFM32_USART_TXDOUBLEX_OFFSET) +#define EFM32_UART0_TXDOUBLE (EFM32_UART0_BASE+EFM32_USART_TXDOUBLE_OFFSET) +#define EFM32_UART0_IF (EFM32_UART0_BASE+EFM32_USART_IF_OFFSET) +#define EFM32_UART0_IFS (EFM32_UART0_BASE+EFM32_USART_IFS_OFFSET) +#define EFM32_UART0_IFC (EFM32_UART0_BASE+EFM32_USART_IFC_OFFSET) +#define EFM32_UART0_IEN (EFM32_UART0_BASE+EFM32_USART_IEN_OFFSET) +#define EFM32_UART0_IRCTRL (EFM32_UART0_BASE+EFM32_USART_IRCTRL_OFFSET) +#define EFM32_UART0_ROUTE (EFM32_UART0_BASE+EFM32_USART_ROUTE_OFFSET) +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_UART0_INPUT (EFM32_UART0_BASE+EFM32_USART_INPUT_OFFSET) +# define EFM32_UART0_I2SCTRL (EFM32_UART0_BASE+EFM32_USART_I2SCTRL_OFFSET) +#endif + +#define EFM32_UART1_CTRL (EFM32_UART1_BASE+EFM32_USART_CTRL_OFFSET) +#define EFM32_UART1_FRAME (EFM32_UART1_BASE+EFM32_USART_FRAME_OFFSET) +#define EFM32_UART1_TRIGCTRL (EFM32_UART1_BASE+EFM32_USART_TRIGCTRL_OFFSET) +#define EFM32_UART1_CMD (EFM32_UART1_BASE+EFM32_USART_CMD_OFFSET) +#define EFM32_UART1_STATUS (EFM32_UART1_BASE+EFM32_USART_STATUS_OFFSET) +#define EFM32_UART1_CLKDIV (EFM32_UART1_BASE+EFM32_USART_CLKDIV_OFFSET) +#define EFM32_UART1_RXDATAX (EFM32_UART1_BASE+EFM32_USART_RXDATAX_OFFSET) +#define EFM32_UART1_RXDATA (EFM32_UART1_BASE+EFM32_USART_RXDATA_OFFSET) +#define EFM32_UART1_RXDOUBLEX (EFM32_UART1_BASE+EFM32_USART_RXDOUBLEX_OFFSET) +#define EFM32_UART1_RXDOUBLE (EFM32_UART1_BASE+EFM32_USART_RXDOUBLE_OFFSET) +#define EFM32_UART1_RXDATAXP (EFM32_UART1_BASE+EFM32_USART_RXDATAXP_OFFSET) +#define EFM32_UART1_RXDOUBLEXP (EFM32_UART1_BASE+EFM32_USART_RXDOUBLEXP_OFFSET) +#define EFM32_UART1_TXDATAX (EFM32_UART1_BASE+EFM32_USART_TXDATAX_OFFSET) +#define EFM32_UART1_TXDATA (EFM32_UART1_BASE+EFM32_USART_TXDATA_OFFSET) +#define EFM32_UART1_TXDOUBLEX (EFM32_UART1_BASE+EFM32_USART_TXDOUBLEX_OFFSET) +#define EFM32_UART1_TXDOUBLE (EFM32_UART1_BASE+EFM32_USART_TXDOUBLE_OFFSET) +#define EFM32_UART1_IF (EFM32_UART1_BASE+EFM32_USART_IF_OFFSET) +#define EFM32_UART1_IFS (EFM32_UART1_BASE+EFM32_USART_IFS_OFFSET) +#define EFM32_UART1_IFC (EFM32_UART1_BASE+EFM32_USART_IFC_OFFSET) +#define EFM32_UART1_IEN (EFM32_UART1_BASE+EFM32_USART_IEN_OFFSET) +#define EFM32_UART1_IRCTRL (EFM32_UART1_BASE+EFM32_USART_IRCTRL_OFFSET) +#define EFM32_UART1_ROUTE (EFM32_UART1_BASE+EFM32_USART_ROUTE_OFFSET) +#ifdef CONFIG_EFM32_EFM32GG +# define EFM32_UART1_INPUT (EFM32_UART1_BASE+EFM32_USART_INPUT_OFFSET) +# define EFM32_UART1_I2SCTRL (EFM32_UART1_BASE+EFM32_USART_I2SCTRL_OFFSET) +#endif + +/* USART Register Register Bit Definitions *************************************************************************************/ + +/* Bit fields for USART CTRL */ + +#define _USART_CTRL_RESETVALUE 0x00000000UL /* Default value for USART_CTRL */ +#define _USART_CTRL_MASK 0x7DFFFF7FUL /* Mask for USART_CTRL */ + +#define USART_CTRL_SYNC (0x1UL << 0) /* USART Synchronous Mode */ +#define _USART_CTRL_SYNC_SHIFT 0 /* Shift value for USART_SYNC */ +#define _USART_CTRL_SYNC_MASK 0x1UL /* Bit mask for USART_SYNC */ +#define _USART_CTRL_SYNC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SYNC_DEFAULT (_USART_CTRL_SYNC_DEFAULT << 0) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_LOOPBK (0x1UL << 1) /* Loopback Enable */ +#define _USART_CTRL_LOOPBK_SHIFT 1 /* Shift value for USART_LOOPBK */ +#define _USART_CTRL_LOOPBK_MASK 0x2UL /* Bit mask for USART_LOOPBK */ +#define _USART_CTRL_LOOPBK_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_LOOPBK_DEFAULT (_USART_CTRL_LOOPBK_DEFAULT << 1) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CCEN (0x1UL << 2) /* Collision Check Enable */ +#define _USART_CTRL_CCEN_SHIFT 2 /* Shift value for USART_CCEN */ +#define _USART_CTRL_CCEN_MASK 0x4UL /* Bit mask for USART_CCEN */ +#define _USART_CTRL_CCEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CCEN_DEFAULT (_USART_CTRL_CCEN_DEFAULT << 2) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MPM (0x1UL << 3) /* Multi-Processor Mode */ +#define _USART_CTRL_MPM_SHIFT 3 /* Shift value for USART_MPM */ +#define _USART_CTRL_MPM_MASK 0x8UL /* Bit mask for USART_MPM */ +#define _USART_CTRL_MPM_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MPM_DEFAULT (_USART_CTRL_MPM_DEFAULT << 3) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MPAB (0x1UL << 4) /* Multi-Processor Address-Bit */ +#define _USART_CTRL_MPAB_SHIFT 4 /* Shift value for USART_MPAB */ +#define _USART_CTRL_MPAB_MASK 0x10UL /* Bit mask for USART_MPAB */ +#define _USART_CTRL_MPAB_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MPAB_DEFAULT (_USART_CTRL_MPAB_DEFAULT << 4) /* Shifted mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_OVS_SHIFT 5 /* Shift value for USART_OVS */ +#define _USART_CTRL_OVS_MASK 0x60UL /* Bit mask for USART_OVS */ +#define _USART_CTRL_OVS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_OVS_X16 0x00000000UL /* Mode X16 for USART_CTRL */ +#define _USART_CTRL_OVS_X8 0x00000001UL /* Mode X8 for USART_CTRL */ +#define _USART_CTRL_OVS_X6 0x00000002UL /* Mode X6 for USART_CTRL */ +#define _USART_CTRL_OVS_X4 0x00000003UL /* Mode X4 for USART_CTRL */ +#define USART_CTRL_OVS_DEFAULT (_USART_CTRL_OVS_DEFAULT << 5) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_OVS_X16 (_USART_CTRL_OVS_X16 << 5) /* Shifted mode X16 for USART_CTRL */ +#define USART_CTRL_OVS_X8 (_USART_CTRL_OVS_X8 << 5) /* Shifted mode X8 for USART_CTRL */ +#define USART_CTRL_OVS_X6 (_USART_CTRL_OVS_X6 << 5) /* Shifted mode X6 for USART_CTRL */ +#define USART_CTRL_OVS_X4 (_USART_CTRL_OVS_X4 << 5) /* Shifted mode X4 for USART_CTRL */ +#define USART_CTRL_CLKPOL (0x1UL << 8) /* Clock Polarity */ +#define _USART_CTRL_CLKPOL_SHIFT 8 /* Shift value for USART_CLKPOL */ +#define _USART_CTRL_CLKPOL_MASK 0x100UL /* Bit mask for USART_CLKPOL */ +#define _USART_CTRL_CLKPOL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_CLKPOL_IDLELOW 0x00000000UL /* Mode IDLELOW for USART_CTRL */ +#define _USART_CTRL_CLKPOL_IDLEHIGH 0x00000001UL /* Mode IDLEHIGH for USART_CTRL */ +#define USART_CTRL_CLKPOL_DEFAULT (_USART_CTRL_CLKPOL_DEFAULT << 8) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CLKPOL_IDLELOW (_USART_CTRL_CLKPOL_IDLELOW << 8) /* Shifted mode IDLELOW for USART_CTRL */ +#define USART_CTRL_CLKPOL_IDLEHIGH (_USART_CTRL_CLKPOL_IDLEHIGH << 8) /* Shifted mode IDLEHIGH for USART_CTRL */ +#define USART_CTRL_CLKPHA (0x1UL << 9) /* Clock Edge For Setup/Sample */ +#define _USART_CTRL_CLKPHA_SHIFT 9 /* Shift value for USART_CLKPHA */ +#define _USART_CTRL_CLKPHA_MASK 0x200UL /* Bit mask for USART_CLKPHA */ +#define _USART_CTRL_CLKPHA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_CLKPHA_SAMPLELEADING 0x00000000UL /* Mode SAMPLELEADING for USART_CTRL */ +#define _USART_CTRL_CLKPHA_SAMPLETRAILING 0x00000001UL /* Mode SAMPLETRAILING for USART_CTRL */ +#define USART_CTRL_CLKPHA_DEFAULT (_USART_CTRL_CLKPHA_DEFAULT << 9) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CLKPHA_SAMPLELEADING (_USART_CTRL_CLKPHA_SAMPLELEADING << 9) /* Shifted mode SAMPLELEADING for USART_CTRL */ +#define USART_CTRL_CLKPHA_SAMPLETRAILING (_USART_CTRL_CLKPHA_SAMPLETRAILING << 9) /* Shifted mode SAMPLETRAILING for USART_CTRL */ +#define USART_CTRL_MSBF (0x1UL << 10) /* Most Significant Bit First */ +#define _USART_CTRL_MSBF_SHIFT 10 /* Shift value for USART_MSBF */ +#define _USART_CTRL_MSBF_MASK 0x400UL /* Bit mask for USART_MSBF */ +#define _USART_CTRL_MSBF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MSBF_DEFAULT (_USART_CTRL_MSBF_DEFAULT << 10) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CSMA (0x1UL << 11) /* Action On Slave-Select In Master Mode */ +#define _USART_CTRL_CSMA_SHIFT 11 /* Shift value for USART_CSMA */ +#define _USART_CTRL_CSMA_MASK 0x800UL /* Bit mask for USART_CSMA */ +#define _USART_CTRL_CSMA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_CSMA_NOACTION 0x00000000UL /* Mode NOACTION for USART_CTRL */ +#define _USART_CTRL_CSMA_GOTOSLAVEMODE 0x00000001UL /* Mode GOTOSLAVEMODE for USART_CTRL */ +#define USART_CTRL_CSMA_DEFAULT (_USART_CTRL_CSMA_DEFAULT << 11) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CSMA_NOACTION (_USART_CTRL_CSMA_NOACTION << 11) /* Shifted mode NOACTION for USART_CTRL */ +#define USART_CTRL_CSMA_GOTOSLAVEMODE (_USART_CTRL_CSMA_GOTOSLAVEMODE << 11) /* Shifted mode GOTOSLAVEMODE for USART_CTRL */ +#define USART_CTRL_TXBIL (0x1UL << 12) /* TX Buffer Interrupt Level */ +#define _USART_CTRL_TXBIL_SHIFT 12 /* Shift value for USART_TXBIL */ +#define _USART_CTRL_TXBIL_MASK 0x1000UL /* Bit mask for USART_TXBIL */ +#define _USART_CTRL_TXBIL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_TXBIL_EMPTY 0x00000000UL /* Mode EMPTY for USART_CTRL */ +#define _USART_CTRL_TXBIL_HALFFULL 0x00000001UL /* Mode HALFFULL for USART_CTRL */ +#define USART_CTRL_TXBIL_DEFAULT (_USART_CTRL_TXBIL_DEFAULT << 12) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_TXBIL_EMPTY (_USART_CTRL_TXBIL_EMPTY << 12) /* Shifted mode EMPTY for USART_CTRL */ +#define USART_CTRL_TXBIL_HALFFULL (_USART_CTRL_TXBIL_HALFFULL << 12) /* Shifted mode HALFFULL for USART_CTRL */ +#define USART_CTRL_RXINV (0x1UL << 13) /* Receiver Input Invert */ +#define _USART_CTRL_RXINV_SHIFT 13 /* Shift value for USART_RXINV */ +#define _USART_CTRL_RXINV_MASK 0x2000UL /* Bit mask for USART_RXINV */ +#define _USART_CTRL_RXINV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_RXINV_DEFAULT (_USART_CTRL_RXINV_DEFAULT << 13) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_TXINV (0x1UL << 14) /* Transmitter output Invert */ +#define _USART_CTRL_TXINV_SHIFT 14 /* Shift value for USART_TXINV */ +#define _USART_CTRL_TXINV_MASK 0x4000UL /* Bit mask for USART_TXINV */ +#define _USART_CTRL_TXINV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_TXINV_DEFAULT (_USART_CTRL_TXINV_DEFAULT << 14) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CSINV (0x1UL << 15) /* Chip Select Invert */ +#define _USART_CTRL_CSINV_SHIFT 15 /* Shift value for USART_CSINV */ +#define _USART_CTRL_CSINV_MASK 0x8000UL /* Bit mask for USART_CSINV */ +#define _USART_CTRL_CSINV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_CSINV_DEFAULT (_USART_CTRL_CSINV_DEFAULT << 15) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOCS (0x1UL << 16) /* Automatic Chip Select */ +#define _USART_CTRL_AUTOCS_SHIFT 16 /* Shift value for USART_AUTOCS */ +#define _USART_CTRL_AUTOCS_MASK 0x10000UL /* Bit mask for USART_AUTOCS */ +#define _USART_CTRL_AUTOCS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOCS_DEFAULT (_USART_CTRL_AUTOCS_DEFAULT << 16) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOTRI (0x1UL << 17) /* Automatic TX Tristate */ +#define _USART_CTRL_AUTOTRI_SHIFT 17 /* Shift value for USART_AUTOTRI */ +#define _USART_CTRL_AUTOTRI_MASK 0x20000UL /* Bit mask for USART_AUTOTRI */ +#define _USART_CTRL_AUTOTRI_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOTRI_DEFAULT (_USART_CTRL_AUTOTRI_DEFAULT << 17) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SCMODE (0x1UL << 18) /* SmartCard Mode */ +#define _USART_CTRL_SCMODE_SHIFT 18 /* Shift value for USART_SCMODE */ +#define _USART_CTRL_SCMODE_MASK 0x40000UL /* Bit mask for USART_SCMODE */ +#define _USART_CTRL_SCMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SCMODE_DEFAULT (_USART_CTRL_SCMODE_DEFAULT << 18) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SCRETRANS (0x1UL << 19) /* SmartCard Retransmit */ +#define _USART_CTRL_SCRETRANS_SHIFT 19 /* Shift value for USART_SCRETRANS */ +#define _USART_CTRL_SCRETRANS_MASK 0x80000UL /* Bit mask for USART_SCRETRANS */ +#define _USART_CTRL_SCRETRANS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SCRETRANS_DEFAULT (_USART_CTRL_SCRETRANS_DEFAULT << 19) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SKIPPERRF (0x1UL << 20) /* Skip Parity Error Frames */ +#define _USART_CTRL_SKIPPERRF_SHIFT 20 /* Shift value for USART_SKIPPERRF */ +#define _USART_CTRL_SKIPPERRF_MASK 0x100000UL /* Bit mask for USART_SKIPPERRF */ +#define _USART_CTRL_SKIPPERRF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_SKIPPERRF_DEFAULT (_USART_CTRL_SKIPPERRF_DEFAULT << 20) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_BIT8DV (0x1UL << 21) /* Bit 8 Default Value */ +#define _USART_CTRL_BIT8DV_SHIFT 21 /* Shift value for USART_BIT8DV */ +#define _USART_CTRL_BIT8DV_MASK 0x200000UL /* Bit mask for USART_BIT8DV */ +#define _USART_CTRL_BIT8DV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_BIT8DV_DEFAULT (_USART_CTRL_BIT8DV_DEFAULT << 21) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSDMA (0x1UL << 22) /* Halt DMA On Error */ +#define _USART_CTRL_ERRSDMA_SHIFT 22 /* Shift value for USART_ERRSDMA */ +#define _USART_CTRL_ERRSDMA_MASK 0x400000UL /* Bit mask for USART_ERRSDMA */ +#define _USART_CTRL_ERRSDMA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSDMA_DEFAULT (_USART_CTRL_ERRSDMA_DEFAULT << 22) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSRX (0x1UL << 23) /* Disable RX On Error */ +#define _USART_CTRL_ERRSRX_SHIFT 23 /* Shift value for USART_ERRSRX */ +#define _USART_CTRL_ERRSRX_MASK 0x800000UL /* Bit mask for USART_ERRSRX */ +#define _USART_CTRL_ERRSRX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSRX_DEFAULT (_USART_CTRL_ERRSRX_DEFAULT << 23) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSTX (0x1UL << 24) /* Disable TX On Error */ +#define _USART_CTRL_ERRSTX_SHIFT 24 /* Shift value for USART_ERRSTX */ +#define _USART_CTRL_ERRSTX_MASK 0x1000000UL /* Bit mask for USART_ERRSTX */ +#define _USART_CTRL_ERRSTX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_ERRSTX_DEFAULT (_USART_CTRL_ERRSTX_DEFAULT << 24) /* Shifted mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_TXDELAY_SHIFT 26 /* Shift value for USART_TXDELAY */ +#define _USART_CTRL_TXDELAY_MASK 0xC000000UL /* Bit mask for USART_TXDELAY */ +#define _USART_CTRL_TXDELAY_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define _USART_CTRL_TXDELAY_NONE 0x00000000UL /* Mode NONE for USART_CTRL */ +#define _USART_CTRL_TXDELAY_SINGLE 0x00000001UL /* Mode SINGLE for USART_CTRL */ +#define _USART_CTRL_TXDELAY_DOUBLE 0x00000002UL /* Mode DOUBLE for USART_CTRL */ +#define _USART_CTRL_TXDELAY_TRIPLE 0x00000003UL /* Mode TRIPLE for USART_CTRL */ +#define USART_CTRL_TXDELAY_DEFAULT (_USART_CTRL_TXDELAY_DEFAULT << 26) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_TXDELAY_NONE (_USART_CTRL_TXDELAY_NONE << 26) /* Shifted mode NONE for USART_CTRL */ +#define USART_CTRL_TXDELAY_SINGLE (_USART_CTRL_TXDELAY_SINGLE << 26) /* Shifted mode SINGLE for USART_CTRL */ +#define USART_CTRL_TXDELAY_DOUBLE (_USART_CTRL_TXDELAY_DOUBLE << 26) /* Shifted mode DOUBLE for USART_CTRL */ +#define USART_CTRL_TXDELAY_TRIPLE (_USART_CTRL_TXDELAY_TRIPLE << 26) /* Shifted mode TRIPLE for USART_CTRL */ +#define USART_CTRL_BYTESWAP (0x1UL << 28) /* Byteswap In Double Accesses */ +#define _USART_CTRL_BYTESWAP_SHIFT 28 /* Shift value for USART_BYTESWAP */ +#define _USART_CTRL_BYTESWAP_MASK 0x10000000UL /* Bit mask for USART_BYTESWAP */ +#define _USART_CTRL_BYTESWAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_BYTESWAP_DEFAULT (_USART_CTRL_BYTESWAP_DEFAULT << 28) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOTX (0x1UL << 29) /* Always Transmit When RX Not Full */ +#define _USART_CTRL_AUTOTX_SHIFT 29 /* Shift value for USART_AUTOTX */ +#define _USART_CTRL_AUTOTX_MASK 0x20000000UL /* Bit mask for USART_AUTOTX */ +#define _USART_CTRL_AUTOTX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_AUTOTX_DEFAULT (_USART_CTRL_AUTOTX_DEFAULT << 29) /* Shifted mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MVDIS (0x1UL << 30) /* Majority Vote Disable */ +#define _USART_CTRL_MVDIS_SHIFT 30 /* Shift value for USART_MVDIS */ +#define _USART_CTRL_MVDIS_MASK 0x40000000UL /* Bit mask for USART_MVDIS */ +#define _USART_CTRL_MVDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CTRL */ +#define USART_CTRL_MVDIS_DEFAULT (_USART_CTRL_MVDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USART_CTRL */ + +/* Bit fields for USART FRAME */ + +#define _USART_FRAME_RESETVALUE 0x00001005UL /* Default value for USART_FRAME */ +#define _USART_FRAME_MASK 0x0000330FUL /* Mask for USART_FRAME */ + +#define _USART_FRAME_DATABITS_SHIFT 0 /* Shift value for USART_DATABITS */ +#define _USART_FRAME_DATABITS_MASK 0xFUL /* Bit mask for USART_DATABITS */ +#define _USART_FRAME_DATABITS_FOUR 0x00000001UL /* Mode FOUR for USART_FRAME */ +#define _USART_FRAME_DATABITS_FIVE 0x00000002UL /* Mode FIVE for USART_FRAME */ +#define _USART_FRAME_DATABITS_SIX 0x00000003UL /* Mode SIX for USART_FRAME */ +#define _USART_FRAME_DATABITS_SEVEN 0x00000004UL /* Mode SEVEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_DEFAULT 0x00000005UL /* Mode DEFAULT for USART_FRAME */ +#define _USART_FRAME_DATABITS_EIGHT 0x00000005UL /* Mode EIGHT for USART_FRAME */ +#define _USART_FRAME_DATABITS_NINE 0x00000006UL /* Mode NINE for USART_FRAME */ +#define _USART_FRAME_DATABITS_TEN 0x00000007UL /* Mode TEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_ELEVEN 0x00000008UL /* Mode ELEVEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_TWELVE 0x00000009UL /* Mode TWELVE for USART_FRAME */ +#define _USART_FRAME_DATABITS_THIRTEEN 0x0000000AUL /* Mode THIRTEEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_FOURTEEN 0x0000000BUL /* Mode FOURTEEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_FIFTEEN 0x0000000CUL /* Mode FIFTEEN for USART_FRAME */ +#define _USART_FRAME_DATABITS_SIXTEEN 0x0000000DUL /* Mode SIXTEEN for USART_FRAME */ +#define USART_FRAME_DATABITS_FOUR (_USART_FRAME_DATABITS_FOUR << 0) /* Shifted mode FOUR for USART_FRAME */ +#define USART_FRAME_DATABITS_FIVE (_USART_FRAME_DATABITS_FIVE << 0) /* Shifted mode FIVE for USART_FRAME */ +#define USART_FRAME_DATABITS_SIX (_USART_FRAME_DATABITS_SIX << 0) /* Shifted mode SIX for USART_FRAME */ +#define USART_FRAME_DATABITS_SEVEN (_USART_FRAME_DATABITS_SEVEN << 0) /* Shifted mode SEVEN for USART_FRAME */ +#define USART_FRAME_DATABITS_DEFAULT (_USART_FRAME_DATABITS_DEFAULT << 0) /* Shifted mode DEFAULT for USART_FRAME */ +#define USART_FRAME_DATABITS_EIGHT (_USART_FRAME_DATABITS_EIGHT << 0) /* Shifted mode EIGHT for USART_FRAME */ +#define USART_FRAME_DATABITS_NINE (_USART_FRAME_DATABITS_NINE << 0) /* Shifted mode NINE for USART_FRAME */ +#define USART_FRAME_DATABITS_TEN (_USART_FRAME_DATABITS_TEN << 0) /* Shifted mode TEN for USART_FRAME */ +#define USART_FRAME_DATABITS_ELEVEN (_USART_FRAME_DATABITS_ELEVEN << 0) /* Shifted mode ELEVEN for USART_FRAME */ +#define USART_FRAME_DATABITS_TWELVE (_USART_FRAME_DATABITS_TWELVE << 0) /* Shifted mode TWELVE for USART_FRAME */ +#define USART_FRAME_DATABITS_THIRTEEN (_USART_FRAME_DATABITS_THIRTEEN << 0) /* Shifted mode THIRTEEN for USART_FRAME */ +#define USART_FRAME_DATABITS_FOURTEEN (_USART_FRAME_DATABITS_FOURTEEN << 0) /* Shifted mode FOURTEEN for USART_FRAME */ +#define USART_FRAME_DATABITS_FIFTEEN (_USART_FRAME_DATABITS_FIFTEEN << 0) /* Shifted mode FIFTEEN for USART_FRAME */ +#define USART_FRAME_DATABITS_SIXTEEN (_USART_FRAME_DATABITS_SIXTEEN << 0) /* Shifted mode SIXTEEN for USART_FRAME */ +#define _USART_FRAME_PARITY_SHIFT 8 /* Shift value for USART_PARITY */ +#define _USART_FRAME_PARITY_MASK 0x300UL /* Bit mask for USART_PARITY */ +#define _USART_FRAME_PARITY_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_FRAME */ +#define _USART_FRAME_PARITY_NONE 0x00000000UL /* Mode NONE for USART_FRAME */ +#define _USART_FRAME_PARITY_EVEN 0x00000002UL /* Mode EVEN for USART_FRAME */ +#define _USART_FRAME_PARITY_ODD 0x00000003UL /* Mode ODD for USART_FRAME */ +#define USART_FRAME_PARITY_DEFAULT (_USART_FRAME_PARITY_DEFAULT << 8) /* Shifted mode DEFAULT for USART_FRAME */ +#define USART_FRAME_PARITY_NONE (_USART_FRAME_PARITY_NONE << 8) /* Shifted mode NONE for USART_FRAME */ +#define USART_FRAME_PARITY_EVEN (_USART_FRAME_PARITY_EVEN << 8) /* Shifted mode EVEN for USART_FRAME */ +#define USART_FRAME_PARITY_ODD (_USART_FRAME_PARITY_ODD << 8) /* Shifted mode ODD for USART_FRAME */ +#define _USART_FRAME_STOPBITS_SHIFT 12 /* Shift value for USART_STOPBITS */ +#define _USART_FRAME_STOPBITS_MASK 0x3000UL /* Bit mask for USART_STOPBITS */ +#define _USART_FRAME_STOPBITS_HALF 0x00000000UL /* Mode HALF for USART_FRAME */ +#define _USART_FRAME_STOPBITS_DEFAULT 0x00000001UL /* Mode DEFAULT for USART_FRAME */ +#define _USART_FRAME_STOPBITS_ONE 0x00000001UL /* Mode ONE for USART_FRAME */ +#define _USART_FRAME_STOPBITS_ONEANDAHALF 0x00000002UL /* Mode ONEANDAHALF for USART_FRAME */ +#define _USART_FRAME_STOPBITS_TWO 0x00000003UL /* Mode TWO for USART_FRAME */ +#define USART_FRAME_STOPBITS_HALF (_USART_FRAME_STOPBITS_HALF << 12) /* Shifted mode HALF for USART_FRAME */ +#define USART_FRAME_STOPBITS_DEFAULT (_USART_FRAME_STOPBITS_DEFAULT << 12) /* Shifted mode DEFAULT for USART_FRAME */ +#define USART_FRAME_STOPBITS_ONE (_USART_FRAME_STOPBITS_ONE << 12) /* Shifted mode ONE for USART_FRAME */ +#define USART_FRAME_STOPBITS_ONEANDAHALF (_USART_FRAME_STOPBITS_ONEANDAHALF << 12) /* Shifted mode ONEANDAHALF for USART_FRAME */ +#define USART_FRAME_STOPBITS_TWO (_USART_FRAME_STOPBITS_TWO << 12) /* Shifted mode TWO for USART_FRAME */ + +/* Bit fields for USART TRIGCTRL */ + +#define _USART_TRIGCTRL_RESETVALUE 0x00000000UL /* Default value for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_MASK 0x00000077UL /* Mask for USART_TRIGCTRL */ + +#define _USART_TRIGCTRL_TSEL_SHIFT 0 /* Shift value for USART_TSEL */ +#define _USART_TRIGCTRL_TSEL_MASK 0x7UL /* Bit mask for USART_TSEL */ +#define _USART_TRIGCTRL_TSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for USART_TRIGCTRL */ +#define _USART_TRIGCTRL_TSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_DEFAULT (_USART_TRIGCTRL_TSEL_DEFAULT << 0) /* Shifted mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH0 (_USART_TRIGCTRL_TSEL_PRSCH0 << 0) /* Shifted mode PRSCH0 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH1 (_USART_TRIGCTRL_TSEL_PRSCH1 << 0) /* Shifted mode PRSCH1 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH2 (_USART_TRIGCTRL_TSEL_PRSCH2 << 0) /* Shifted mode PRSCH2 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH3 (_USART_TRIGCTRL_TSEL_PRSCH3 << 0) /* Shifted mode PRSCH3 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH4 (_USART_TRIGCTRL_TSEL_PRSCH4 << 0) /* Shifted mode PRSCH4 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH5 (_USART_TRIGCTRL_TSEL_PRSCH5 << 0) /* Shifted mode PRSCH5 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH6 (_USART_TRIGCTRL_TSEL_PRSCH6 << 0) /* Shifted mode PRSCH6 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TSEL_PRSCH7 (_USART_TRIGCTRL_TSEL_PRSCH7 << 0) /* Shifted mode PRSCH7 for USART_TRIGCTRL */ +#define USART_TRIGCTRL_RXTEN (0x1UL << 4) /* Receive Trigger Enable */ +#define _USART_TRIGCTRL_RXTEN_SHIFT 4 /* Shift value for USART_RXTEN */ +#define _USART_TRIGCTRL_RXTEN_MASK 0x10UL /* Bit mask for USART_RXTEN */ +#define _USART_TRIGCTRL_RXTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_RXTEN_DEFAULT (_USART_TRIGCTRL_RXTEN_DEFAULT << 4) /* Shifted mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TXTEN (0x1UL << 5) /* Transmit Trigger Enable */ +#define _USART_TRIGCTRL_TXTEN_SHIFT 5 /* Shift value for USART_TXTEN */ +#define _USART_TRIGCTRL_TXTEN_MASK 0x20UL /* Bit mask for USART_TXTEN */ +#define _USART_TRIGCTRL_TXTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_TXTEN_DEFAULT (_USART_TRIGCTRL_TXTEN_DEFAULT << 5) /* Shifted mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_AUTOTXTEN (0x1UL << 6) /* AUTOTX Trigger Enable */ +#define _USART_TRIGCTRL_AUTOTXTEN_SHIFT 6 /* Shift value for USART_AUTOTXTEN */ +#define _USART_TRIGCTRL_AUTOTXTEN_MASK 0x40UL /* Bit mask for USART_AUTOTXTEN */ +#define _USART_TRIGCTRL_AUTOTXTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TRIGCTRL */ +#define USART_TRIGCTRL_AUTOTXTEN_DEFAULT (_USART_TRIGCTRL_AUTOTXTEN_DEFAULT << 6) /* Shifted mode DEFAULT for USART_TRIGCTRL */ + +/* Bit fields for USART CMD */ + +#define _USART_CMD_RESETVALUE 0x00000000UL /* Default value for USART_CMD */ +#define _USART_CMD_MASK 0x00000FFFUL /* Mask for USART_CMD */ + +#define USART_CMD_RXEN (0x1UL << 0) /* Receiver Enable */ +#define _USART_CMD_RXEN_SHIFT 0 /* Shift value for USART_RXEN */ +#define _USART_CMD_RXEN_MASK 0x1UL /* Bit mask for USART_RXEN */ +#define _USART_CMD_RXEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_RXEN_DEFAULT (_USART_CMD_RXEN_DEFAULT << 0) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_RXDIS (0x1UL << 1) /* Receiver Disable */ +#define _USART_CMD_RXDIS_SHIFT 1 /* Shift value for USART_RXDIS */ +#define _USART_CMD_RXDIS_MASK 0x2UL /* Bit mask for USART_RXDIS */ +#define _USART_CMD_RXDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_RXDIS_DEFAULT (_USART_CMD_RXDIS_DEFAULT << 1) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_TXEN (0x1UL << 2) /* Transmitter Enable */ +#define _USART_CMD_TXEN_SHIFT 2 /* Shift value for USART_TXEN */ +#define _USART_CMD_TXEN_MASK 0x4UL /* Bit mask for USART_TXEN */ +#define _USART_CMD_TXEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_TXEN_DEFAULT (_USART_CMD_TXEN_DEFAULT << 2) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_TXDIS (0x1UL << 3) /* Transmitter Disable */ +#define _USART_CMD_TXDIS_SHIFT 3 /* Shift value for USART_TXDIS */ +#define _USART_CMD_TXDIS_MASK 0x8UL /* Bit mask for USART_TXDIS */ +#define _USART_CMD_TXDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_TXDIS_DEFAULT (_USART_CMD_TXDIS_DEFAULT << 3) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_MASTEREN (0x1UL << 4) /* Master Enable */ +#define _USART_CMD_MASTEREN_SHIFT 4 /* Shift value for USART_MASTEREN */ +#define _USART_CMD_MASTEREN_MASK 0x10UL /* Bit mask for USART_MASTEREN */ +#define _USART_CMD_MASTEREN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_MASTEREN_DEFAULT (_USART_CMD_MASTEREN_DEFAULT << 4) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_MASTERDIS (0x1UL << 5) /* Master Disable */ +#define _USART_CMD_MASTERDIS_SHIFT 5 /* Shift value for USART_MASTERDIS */ +#define _USART_CMD_MASTERDIS_MASK 0x20UL /* Bit mask for USART_MASTERDIS */ +#define _USART_CMD_MASTERDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_MASTERDIS_DEFAULT (_USART_CMD_MASTERDIS_DEFAULT << 5) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_RXBLOCKEN (0x1UL << 6) /* Receiver Block Enable */ +#define _USART_CMD_RXBLOCKEN_SHIFT 6 /* Shift value for USART_RXBLOCKEN */ +#define _USART_CMD_RXBLOCKEN_MASK 0x40UL /* Bit mask for USART_RXBLOCKEN */ +#define _USART_CMD_RXBLOCKEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_RXBLOCKEN_DEFAULT (_USART_CMD_RXBLOCKEN_DEFAULT << 6) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_RXBLOCKDIS (0x1UL << 7) /* Receiver Block Disable */ +#define _USART_CMD_RXBLOCKDIS_SHIFT 7 /* Shift value for USART_RXBLOCKDIS */ +#define _USART_CMD_RXBLOCKDIS_MASK 0x80UL /* Bit mask for USART_RXBLOCKDIS */ +#define _USART_CMD_RXBLOCKDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_RXBLOCKDIS_DEFAULT (_USART_CMD_RXBLOCKDIS_DEFAULT << 7) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_TXTRIEN (0x1UL << 8) /* Transmitter Tristate Enable */ +#define _USART_CMD_TXTRIEN_SHIFT 8 /* Shift value for USART_TXTRIEN */ +#define _USART_CMD_TXTRIEN_MASK 0x100UL /* Bit mask for USART_TXTRIEN */ +#define _USART_CMD_TXTRIEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_TXTRIEN_DEFAULT (_USART_CMD_TXTRIEN_DEFAULT << 8) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_TXTRIDIS (0x1UL << 9) /* Transmitter Tristate Disable */ +#define _USART_CMD_TXTRIDIS_SHIFT 9 /* Shift value for USART_TXTRIDIS */ +#define _USART_CMD_TXTRIDIS_MASK 0x200UL /* Bit mask for USART_TXTRIDIS */ +#define _USART_CMD_TXTRIDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_TXTRIDIS_DEFAULT (_USART_CMD_TXTRIDIS_DEFAULT << 9) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_CLEARTX (0x1UL << 10) /* Clear TX */ +#define _USART_CMD_CLEARTX_SHIFT 10 /* Shift value for USART_CLEARTX */ +#define _USART_CMD_CLEARTX_MASK 0x400UL /* Bit mask for USART_CLEARTX */ +#define _USART_CMD_CLEARTX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_CLEARTX_DEFAULT (_USART_CMD_CLEARTX_DEFAULT << 10) /* Shifted mode DEFAULT for USART_CMD */ +#define USART_CMD_CLEARRX (0x1UL << 11) /* Clear RX */ +#define _USART_CMD_CLEARRX_SHIFT 11 /* Shift value for USART_CLEARRX */ +#define _USART_CMD_CLEARRX_MASK 0x800UL /* Bit mask for USART_CLEARRX */ +#define _USART_CMD_CLEARRX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CMD */ +#define USART_CMD_CLEARRX_DEFAULT (_USART_CMD_CLEARRX_DEFAULT << 11) /* Shifted mode DEFAULT for USART_CMD */ + +/* Bit fields for USART STATUS */ + +#define _USART_STATUS_RESETVALUE 0x00000040UL /* Default value for USART_STATUS */ +#define _USART_STATUS_MASK 0x00001FFFUL /* Mask for USART_STATUS */ + +#define USART_STATUS_RXENS (0x1UL << 0) /* Receiver Enable Status */ +#define _USART_STATUS_RXENS_SHIFT 0 /* Shift value for USART_RXENS */ +#define _USART_STATUS_RXENS_MASK 0x1UL /* Bit mask for USART_RXENS */ +#define _USART_STATUS_RXENS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXENS_DEFAULT (_USART_STATUS_RXENS_DEFAULT << 0) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXENS (0x1UL << 1) /* Transmitter Enable Status */ +#define _USART_STATUS_TXENS_SHIFT 1 /* Shift value for USART_TXENS */ +#define _USART_STATUS_TXENS_MASK 0x2UL /* Bit mask for USART_TXENS */ +#define _USART_STATUS_TXENS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXENS_DEFAULT (_USART_STATUS_TXENS_DEFAULT << 1) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_MASTER (0x1UL << 2) /* SPI Master Mode */ +#define _USART_STATUS_MASTER_SHIFT 2 /* Shift value for USART_MASTER */ +#define _USART_STATUS_MASTER_MASK 0x4UL /* Bit mask for USART_MASTER */ +#define _USART_STATUS_MASTER_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_MASTER_DEFAULT (_USART_STATUS_MASTER_DEFAULT << 2) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXBLOCK (0x1UL << 3) /* Block Incoming Data */ +#define _USART_STATUS_RXBLOCK_SHIFT 3 /* Shift value for USART_RXBLOCK */ +#define _USART_STATUS_RXBLOCK_MASK 0x8UL /* Bit mask for USART_RXBLOCK */ +#define _USART_STATUS_RXBLOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXBLOCK_DEFAULT (_USART_STATUS_RXBLOCK_DEFAULT << 3) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXTRI (0x1UL << 4) /* Transmitter Tristated */ +#define _USART_STATUS_TXTRI_SHIFT 4 /* Shift value for USART_TXTRI */ +#define _USART_STATUS_TXTRI_MASK 0x10UL /* Bit mask for USART_TXTRI */ +#define _USART_STATUS_TXTRI_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXTRI_DEFAULT (_USART_STATUS_TXTRI_DEFAULT << 4) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXC (0x1UL << 5) /* TX Complete */ +#define _USART_STATUS_TXC_SHIFT 5 /* Shift value for USART_TXC */ +#define _USART_STATUS_TXC_MASK 0x20UL /* Bit mask for USART_TXC */ +#define _USART_STATUS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXC_DEFAULT (_USART_STATUS_TXC_DEFAULT << 5) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBL (0x1UL << 6) /* TX Buffer Level */ +#define _USART_STATUS_TXBL_SHIFT 6 /* Shift value for USART_TXBL */ +#define _USART_STATUS_TXBL_MASK 0x40UL /* Bit mask for USART_TXBL */ +#define _USART_STATUS_TXBL_DEFAULT 0x00000001UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBL_DEFAULT (_USART_STATUS_TXBL_DEFAULT << 6) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXDATAV (0x1UL << 7) /* RX Data Valid */ +#define _USART_STATUS_RXDATAV_SHIFT 7 /* Shift value for USART_RXDATAV */ +#define _USART_STATUS_RXDATAV_MASK 0x80UL /* Bit mask for USART_RXDATAV */ +#define _USART_STATUS_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXDATAV_DEFAULT (_USART_STATUS_RXDATAV_DEFAULT << 7) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXFULL (0x1UL << 8) /* RX FIFO Full */ +#define _USART_STATUS_RXFULL_SHIFT 8 /* Shift value for USART_RXFULL */ +#define _USART_STATUS_RXFULL_MASK 0x100UL /* Bit mask for USART_RXFULL */ +#define _USART_STATUS_RXFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXFULL_DEFAULT (_USART_STATUS_RXFULL_DEFAULT << 8) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBDRIGHT (0x1UL << 9) /* TX Buffer Expects Double Right Data */ +#define _USART_STATUS_TXBDRIGHT_SHIFT 9 /* Shift value for USART_TXBDRIGHT */ +#define _USART_STATUS_TXBDRIGHT_MASK 0x200UL /* Bit mask for USART_TXBDRIGHT */ +#define _USART_STATUS_TXBDRIGHT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBDRIGHT_DEFAULT (_USART_STATUS_TXBDRIGHT_DEFAULT << 9) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBSRIGHT (0x1UL << 10) /* TX Buffer Expects Single Right Data */ +#define _USART_STATUS_TXBSRIGHT_SHIFT 10 /* Shift value for USART_TXBSRIGHT */ +#define _USART_STATUS_TXBSRIGHT_MASK 0x400UL /* Bit mask for USART_TXBSRIGHT */ +#define _USART_STATUS_TXBSRIGHT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_TXBSRIGHT_DEFAULT (_USART_STATUS_TXBSRIGHT_DEFAULT << 10) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXDATAVRIGHT (0x1UL << 11) /* RX Data Right */ +#define _USART_STATUS_RXDATAVRIGHT_SHIFT 11 /* Shift value for USART_RXDATAVRIGHT */ +#define _USART_STATUS_RXDATAVRIGHT_MASK 0x800UL /* Bit mask for USART_RXDATAVRIGHT */ +#define _USART_STATUS_RXDATAVRIGHT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXDATAVRIGHT_DEFAULT (_USART_STATUS_RXDATAVRIGHT_DEFAULT << 11) /* Shifted mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXFULLRIGHT (0x1UL << 12) /* RX Full of Right Data */ +#define _USART_STATUS_RXFULLRIGHT_SHIFT 12 /* Shift value for USART_RXFULLRIGHT */ +#define _USART_STATUS_RXFULLRIGHT_MASK 0x1000UL /* Bit mask for USART_RXFULLRIGHT */ +#define _USART_STATUS_RXFULLRIGHT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_STATUS */ +#define USART_STATUS_RXFULLRIGHT_DEFAULT (_USART_STATUS_RXFULLRIGHT_DEFAULT << 12) /* Shifted mode DEFAULT for USART_STATUS */ + +/* Bit fields for USART CLKDIV */ + +#define _USART_CLKDIV_RESETVALUE 0x00000000UL /* Default value for USART_CLKDIV */ +#define _USART_CLKDIV_MASK 0x001FFFC0UL /* Mask for USART_CLKDIV */ + +#define _USART_CLKDIV_DIV_SHIFT 6 /* Shift value for USART_DIV */ +#define _USART_CLKDIV_DIV_MASK 0x1FFFC0UL /* Bit mask for USART_DIV */ +#define _USART_CLKDIV_DIV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_CLKDIV */ +#define USART_CLKDIV_DIV_DEFAULT (_USART_CLKDIV_DIV_DEFAULT << 6) /* Shifted mode DEFAULT for USART_CLKDIV */ + +/* Bit fields for USART RXDATAX */ + +#define _USART_RXDATAX_RESETVALUE 0x00000000UL /* Default value for USART_RXDATAX */ +#define _USART_RXDATAX_MASK 0x0000C1FFUL /* Mask for USART_RXDATAX */ + +#define _USART_RXDATAX_RXDATA_SHIFT 0 /* Shift value for USART_RXDATA */ +#define _USART_RXDATAX_RXDATA_MASK 0x1FFUL /* Bit mask for USART_RXDATA */ +#define _USART_RXDATAX_RXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAX */ +#define USART_RXDATAX_RXDATA_DEFAULT (_USART_RXDATAX_RXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDATAX */ +#define USART_RXDATAX_PERR (0x1UL << 14) /* Data Parity Error */ +#define _USART_RXDATAX_PERR_SHIFT 14 /* Shift value for USART_PERR */ +#define _USART_RXDATAX_PERR_MASK 0x4000UL /* Bit mask for USART_PERR */ +#define _USART_RXDATAX_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAX */ +#define USART_RXDATAX_PERR_DEFAULT (_USART_RXDATAX_PERR_DEFAULT << 14) /* Shifted mode DEFAULT for USART_RXDATAX */ +#define USART_RXDATAX_FERR (0x1UL << 15) /* Data Framing Error */ +#define _USART_RXDATAX_FERR_SHIFT 15 /* Shift value for USART_FERR */ +#define _USART_RXDATAX_FERR_MASK 0x8000UL /* Bit mask for USART_FERR */ +#define _USART_RXDATAX_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAX */ +#define USART_RXDATAX_FERR_DEFAULT (_USART_RXDATAX_FERR_DEFAULT << 15) /* Shifted mode DEFAULT for USART_RXDATAX */ + +/* Bit fields for USART RXDATA */ + +#define _USART_RXDATA_RESETVALUE 0x00000000UL /* Default value for USART_RXDATA */ +#define _USART_RXDATA_MASK 0x000000FFUL /* Mask for USART_RXDATA */ + +#define _USART_RXDATA_RXDATA_SHIFT 0 /* Shift value for USART_RXDATA */ +#define _USART_RXDATA_RXDATA_MASK 0xFFUL /* Bit mask for USART_RXDATA */ +#define _USART_RXDATA_RXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATA */ +#define USART_RXDATA_RXDATA_DEFAULT (_USART_RXDATA_RXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDATA */ + +/* Bit fields for USART RXDOUBLEX */ + +#define _USART_RXDOUBLEX_RESETVALUE 0x00000000UL /* Default value for USART_RXDOUBLEX */ +#define _USART_RXDOUBLEX_MASK 0xC1FFC1FFUL /* Mask for USART_RXDOUBLEX */ + +#define _USART_RXDOUBLEX_RXDATA0_SHIFT 0 /* Shift value for USART_RXDATA0 */ +#define _USART_RXDOUBLEX_RXDATA0_MASK 0x1FFUL /* Bit mask for USART_RXDATA0 */ +#define _USART_RXDOUBLEX_RXDATA0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_RXDATA0_DEFAULT (_USART_RXDOUBLEX_RXDATA0_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_PERR0 (0x1UL << 14) /* Data Parity Error 0 */ +#define _USART_RXDOUBLEX_PERR0_SHIFT 14 /* Shift value for USART_PERR0 */ +#define _USART_RXDOUBLEX_PERR0_MASK 0x4000UL /* Bit mask for USART_PERR0 */ +#define _USART_RXDOUBLEX_PERR0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_PERR0_DEFAULT (_USART_RXDOUBLEX_PERR0_DEFAULT << 14) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_FERR0 (0x1UL << 15) /* Data Framing Error 0 */ +#define _USART_RXDOUBLEX_FERR0_SHIFT 15 /* Shift value for USART_FERR0 */ +#define _USART_RXDOUBLEX_FERR0_MASK 0x8000UL /* Bit mask for USART_FERR0 */ +#define _USART_RXDOUBLEX_FERR0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_FERR0_DEFAULT (_USART_RXDOUBLEX_FERR0_DEFAULT << 15) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ +#define _USART_RXDOUBLEX_RXDATA1_SHIFT 16 /* Shift value for USART_RXDATA1 */ +#define _USART_RXDOUBLEX_RXDATA1_MASK 0x1FF0000UL /* Bit mask for USART_RXDATA1 */ +#define _USART_RXDOUBLEX_RXDATA1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_RXDATA1_DEFAULT (_USART_RXDOUBLEX_RXDATA1_DEFAULT << 16) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_PERR1 (0x1UL << 30) /* Data Parity Error 1 */ +#define _USART_RXDOUBLEX_PERR1_SHIFT 30 /* Shift value for USART_PERR1 */ +#define _USART_RXDOUBLEX_PERR1_MASK 0x40000000UL /* Bit mask for USART_PERR1 */ +#define _USART_RXDOUBLEX_PERR1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_PERR1_DEFAULT (_USART_RXDOUBLEX_PERR1_DEFAULT << 30) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_FERR1 (0x1UL << 31) /* Data Framing Error 1 */ +#define _USART_RXDOUBLEX_FERR1_SHIFT 31 /* Shift value for USART_FERR1 */ +#define _USART_RXDOUBLEX_FERR1_MASK 0x80000000UL /* Bit mask for USART_FERR1 */ +#define _USART_RXDOUBLEX_FERR1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_FERR1_DEFAULT (_USART_RXDOUBLEX_FERR1_DEFAULT << 31) /* Shifted mode DEFAULT for USART_RXDOUBLEX */ + +/* Bit fields for USART RXDOUBLE */ + +#define _USART_RXDOUBLE_RESETVALUE 0x00000000UL /* Default value for USART_RXDOUBLE */ +#define _USART_RXDOUBLE_MASK 0x0000FFFFUL /* Mask for USART_RXDOUBLE */ + +#define _USART_RXDOUBLE_RXDATA0_SHIFT 0 /* Shift value for USART_RXDATA0 */ +#define _USART_RXDOUBLE_RXDATA0_MASK 0xFFUL /* Bit mask for USART_RXDATA0 */ +#define _USART_RXDOUBLE_RXDATA0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLE */ +#define USART_RXDOUBLE_RXDATA0_DEFAULT (_USART_RXDOUBLE_RXDATA0_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDOUBLE */ +#define _USART_RXDOUBLE_RXDATA1_SHIFT 8 /* Shift value for USART_RXDATA1 */ +#define _USART_RXDOUBLE_RXDATA1_MASK 0xFF00UL /* Bit mask for USART_RXDATA1 */ +#define _USART_RXDOUBLE_RXDATA1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLE */ +#define USART_RXDOUBLE_RXDATA1_DEFAULT (_USART_RXDOUBLE_RXDATA1_DEFAULT << 8) /* Shifted mode DEFAULT for USART_RXDOUBLE */ + +/* Bit fields for USART RXDATAXP */ + +#define _USART_RXDATAXP_RESETVALUE 0x00000000UL /* Default value for USART_RXDATAXP */ +#define _USART_RXDATAXP_MASK 0x0000C1FFUL /* Mask for USART_RXDATAXP */ + +#define _USART_RXDATAXP_RXDATAP_SHIFT 0 /* Shift value for USART_RXDATAP */ +#define _USART_RXDATAXP_RXDATAP_MASK 0x1FFUL /* Bit mask for USART_RXDATAP */ +#define _USART_RXDATAXP_RXDATAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAXP */ +#define USART_RXDATAXP_RXDATAP_DEFAULT (_USART_RXDATAXP_RXDATAP_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDATAXP */ +#define USART_RXDATAXP_PERRP (0x1UL << 14) /* Data Parity Error Peek */ +#define _USART_RXDATAXP_PERRP_SHIFT 14 /* Shift value for USART_PERRP */ +#define _USART_RXDATAXP_PERRP_MASK 0x4000UL /* Bit mask for USART_PERRP */ +#define _USART_RXDATAXP_PERRP_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAXP */ +#define USART_RXDATAXP_PERRP_DEFAULT (_USART_RXDATAXP_PERRP_DEFAULT << 14) /* Shifted mode DEFAULT for USART_RXDATAXP */ +#define USART_RXDATAXP_FERRP (0x1UL << 15) /* Data Framing Error Peek */ +#define _USART_RXDATAXP_FERRP_SHIFT 15 /* Shift value for USART_FERRP */ +#define _USART_RXDATAXP_FERRP_MASK 0x8000UL /* Bit mask for USART_FERRP */ +#define _USART_RXDATAXP_FERRP_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDATAXP */ +#define USART_RXDATAXP_FERRP_DEFAULT (_USART_RXDATAXP_FERRP_DEFAULT << 15) /* Shifted mode DEFAULT for USART_RXDATAXP */ + +/* Bit fields for USART RXDOUBLEXP */ + +#define _USART_RXDOUBLEXP_RESETVALUE 0x00000000UL /* Default value for USART_RXDOUBLEXP */ +#define _USART_RXDOUBLEXP_MASK 0xC1FFC1FFUL /* Mask for USART_RXDOUBLEXP */ + +#define _USART_RXDOUBLEXP_RXDATAP0_SHIFT 0 /* Shift value for USART_RXDATAP0 */ +#define _USART_RXDOUBLEXP_RXDATAP0_MASK 0x1FFUL /* Bit mask for USART_RXDATAP0 */ +#define _USART_RXDOUBLEXP_RXDATAP0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_RXDATAP0_DEFAULT (_USART_RXDOUBLEXP_RXDATAP0_DEFAULT << 0) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_PERRP0 (0x1UL << 14) /* Data Parity Error 0 Peek */ +#define _USART_RXDOUBLEXP_PERRP0_SHIFT 14 /* Shift value for USART_PERRP0 */ +#define _USART_RXDOUBLEXP_PERRP0_MASK 0x4000UL /* Bit mask for USART_PERRP0 */ +#define _USART_RXDOUBLEXP_PERRP0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_PERRP0_DEFAULT (_USART_RXDOUBLEXP_PERRP0_DEFAULT << 14) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_FERRP0 (0x1UL << 15) /* Data Framing Error 0 Peek */ +#define _USART_RXDOUBLEXP_FERRP0_SHIFT 15 /* Shift value for USART_FERRP0 */ +#define _USART_RXDOUBLEXP_FERRP0_MASK 0x8000UL /* Bit mask for USART_FERRP0 */ +#define _USART_RXDOUBLEXP_FERRP0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_FERRP0_DEFAULT (_USART_RXDOUBLEXP_FERRP0_DEFAULT << 15) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ +#define _USART_RXDOUBLEXP_RXDATAP1_SHIFT 16 /* Shift value for USART_RXDATAP1 */ +#define _USART_RXDOUBLEXP_RXDATAP1_MASK 0x1FF0000UL /* Bit mask for USART_RXDATAP1 */ +#define _USART_RXDOUBLEXP_RXDATAP1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_RXDATAP1_DEFAULT (_USART_RXDOUBLEXP_RXDATAP1_DEFAULT << 16) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_PERRP1 (0x1UL << 30) /* Data Parity Error 1 Peek */ +#define _USART_RXDOUBLEXP_PERRP1_SHIFT 30 /* Shift value for USART_PERRP1 */ +#define _USART_RXDOUBLEXP_PERRP1_MASK 0x40000000UL /* Bit mask for USART_PERRP1 */ +#define _USART_RXDOUBLEXP_PERRP1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_PERRP1_DEFAULT (_USART_RXDOUBLEXP_PERRP1_DEFAULT << 30) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_FERRP1 (0x1UL << 31) /* Data Framing Error 1 Peek */ +#define _USART_RXDOUBLEXP_FERRP1_SHIFT 31 /* Shift value for USART_FERRP1 */ +#define _USART_RXDOUBLEXP_FERRP1_MASK 0x80000000UL /* Bit mask for USART_FERRP1 */ +#define _USART_RXDOUBLEXP_FERRP1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_FERRP1_DEFAULT (_USART_RXDOUBLEXP_FERRP1_DEFAULT << 31) /* Shifted mode DEFAULT for USART_RXDOUBLEXP */ + +/* Bit fields for USART TXDATAX */ + +#define _USART_TXDATAX_RESETVALUE 0x00000000UL /* Default value for USART_TXDATAX */ +#define _USART_TXDATAX_MASK 0x0000F9FFUL /* Mask for USART_TXDATAX */ + +#define _USART_TXDATAX_TXDATAX_SHIFT 0 /* Shift value for USART_TXDATAX */ +#define _USART_TXDATAX_TXDATAX_MASK 0x1FFUL /* Bit mask for USART_TXDATAX */ +#define _USART_TXDATAX_TXDATAX_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXDATAX_DEFAULT (_USART_TXDATAX_TXDATAX_DEFAULT << 0) /* Shifted mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_UBRXAT (0x1UL << 11) /* Unblock RX After Transmission */ +#define _USART_TXDATAX_UBRXAT_SHIFT 11 /* Shift value for USART_UBRXAT */ +#define _USART_TXDATAX_UBRXAT_MASK 0x800UL /* Bit mask for USART_UBRXAT */ +#define _USART_TXDATAX_UBRXAT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_UBRXAT_DEFAULT (_USART_TXDATAX_UBRXAT_DEFAULT << 11) /* Shifted mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXTRIAT (0x1UL << 12) /* Set TXTRI After Transmission */ +#define _USART_TXDATAX_TXTRIAT_SHIFT 12 /* Shift value for USART_TXTRIAT */ +#define _USART_TXDATAX_TXTRIAT_MASK 0x1000UL /* Bit mask for USART_TXTRIAT */ +#define _USART_TXDATAX_TXTRIAT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXTRIAT_DEFAULT (_USART_TXDATAX_TXTRIAT_DEFAULT << 12) /* Shifted mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXBREAK (0x1UL << 13) /* Transmit Data As Break */ +#define _USART_TXDATAX_TXBREAK_SHIFT 13 /* Shift value for USART_TXBREAK */ +#define _USART_TXDATAX_TXBREAK_MASK 0x2000UL /* Bit mask for USART_TXBREAK */ +#define _USART_TXDATAX_TXBREAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXBREAK_DEFAULT (_USART_TXDATAX_TXBREAK_DEFAULT << 13) /* Shifted mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXDISAT (0x1UL << 14) /* Clear TXEN After Transmission */ +#define _USART_TXDATAX_TXDISAT_SHIFT 14 /* Shift value for USART_TXDISAT */ +#define _USART_TXDATAX_TXDISAT_MASK 0x4000UL /* Bit mask for USART_TXDISAT */ +#define _USART_TXDATAX_TXDISAT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_TXDISAT_DEFAULT (_USART_TXDATAX_TXDISAT_DEFAULT << 14) /* Shifted mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_RXENAT (0x1UL << 15) /* Enable RX After Transmission */ +#define _USART_TXDATAX_RXENAT_SHIFT 15 /* Shift value for USART_RXENAT */ +#define _USART_TXDATAX_RXENAT_MASK 0x8000UL /* Bit mask for USART_RXENAT */ +#define _USART_TXDATAX_RXENAT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATAX */ +#define USART_TXDATAX_RXENAT_DEFAULT (_USART_TXDATAX_RXENAT_DEFAULT << 15) /* Shifted mode DEFAULT for USART_TXDATAX */ + +/* Bit fields for USART TXDATA */ + +#define _USART_TXDATA_RESETVALUE 0x00000000UL /* Default value for USART_TXDATA */ +#define _USART_TXDATA_MASK 0x000000FFUL /* Mask for USART_TXDATA */ + +#define _USART_TXDATA_TXDATA_SHIFT 0 /* Shift value for USART_TXDATA */ +#define _USART_TXDATA_TXDATA_MASK 0xFFUL /* Bit mask for USART_TXDATA */ +#define _USART_TXDATA_TXDATA_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDATA */ +#define USART_TXDATA_TXDATA_DEFAULT (_USART_TXDATA_TXDATA_DEFAULT << 0) /* Shifted mode DEFAULT for USART_TXDATA */ + +/* Bit fields for USART TXDOUBLEX */ + +#define _USART_TXDOUBLEX_RESETVALUE 0x00000000UL /* Default value for USART_TXDOUBLEX */ +#define _USART_TXDOUBLEX_MASK 0xF9FFF9FFUL /* Mask for USART_TXDOUBLEX */ + +#define _USART_TXDOUBLEX_TXDATA0_SHIFT 0 /* Shift value for USART_TXDATA0 */ +#define _USART_TXDOUBLEX_TXDATA0_MASK 0x1FFUL /* Bit mask for USART_TXDATA0 */ +#define _USART_TXDOUBLEX_TXDATA0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDATA0_DEFAULT (_USART_TXDOUBLEX_TXDATA0_DEFAULT << 0) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_UBRXAT0 (0x1UL << 11) /* Unblock RX After Transmission */ +#define _USART_TXDOUBLEX_UBRXAT0_SHIFT 11 /* Shift value for USART_UBRXAT0 */ +#define _USART_TXDOUBLEX_UBRXAT0_MASK 0x800UL /* Bit mask for USART_UBRXAT0 */ +#define _USART_TXDOUBLEX_UBRXAT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_UBRXAT0_DEFAULT (_USART_TXDOUBLEX_UBRXAT0_DEFAULT << 11) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXTRIAT0 (0x1UL << 12) /* Set TXTRI After Transmission */ +#define _USART_TXDOUBLEX_TXTRIAT0_SHIFT 12 /* Shift value for USART_TXTRIAT0 */ +#define _USART_TXDOUBLEX_TXTRIAT0_MASK 0x1000UL /* Bit mask for USART_TXTRIAT0 */ +#define _USART_TXDOUBLEX_TXTRIAT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXTRIAT0_DEFAULT (_USART_TXDOUBLEX_TXTRIAT0_DEFAULT << 12) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXBREAK0 (0x1UL << 13) /* Transmit Data As Break */ +#define _USART_TXDOUBLEX_TXBREAK0_SHIFT 13 /* Shift value for USART_TXBREAK0 */ +#define _USART_TXDOUBLEX_TXBREAK0_MASK 0x2000UL /* Bit mask for USART_TXBREAK0 */ +#define _USART_TXDOUBLEX_TXBREAK0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXBREAK0_DEFAULT (_USART_TXDOUBLEX_TXBREAK0_DEFAULT << 13) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDISAT0 (0x1UL << 14) /* Clear TXEN After Transmission */ +#define _USART_TXDOUBLEX_TXDISAT0_SHIFT 14 /* Shift value for USART_TXDISAT0 */ +#define _USART_TXDOUBLEX_TXDISAT0_MASK 0x4000UL /* Bit mask for USART_TXDISAT0 */ +#define _USART_TXDOUBLEX_TXDISAT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDISAT0_DEFAULT (_USART_TXDOUBLEX_TXDISAT0_DEFAULT << 14) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_RXENAT0 (0x1UL << 15) /* Enable RX After Transmission */ +#define _USART_TXDOUBLEX_RXENAT0_SHIFT 15 /* Shift value for USART_RXENAT0 */ +#define _USART_TXDOUBLEX_RXENAT0_MASK 0x8000UL /* Bit mask for USART_RXENAT0 */ +#define _USART_TXDOUBLEX_RXENAT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_RXENAT0_DEFAULT (_USART_TXDOUBLEX_RXENAT0_DEFAULT << 15) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define _USART_TXDOUBLEX_TXDATA1_SHIFT 16 /* Shift value for USART_TXDATA1 */ +#define _USART_TXDOUBLEX_TXDATA1_MASK 0x1FF0000UL /* Bit mask for USART_TXDATA1 */ +#define _USART_TXDOUBLEX_TXDATA1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDATA1_DEFAULT (_USART_TXDOUBLEX_TXDATA1_DEFAULT << 16) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_UBRXAT1 (0x1UL << 27) /* Unblock RX After Transmission */ +#define _USART_TXDOUBLEX_UBRXAT1_SHIFT 27 /* Shift value for USART_UBRXAT1 */ +#define _USART_TXDOUBLEX_UBRXAT1_MASK 0x8000000UL /* Bit mask for USART_UBRXAT1 */ +#define _USART_TXDOUBLEX_UBRXAT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_UBRXAT1_DEFAULT (_USART_TXDOUBLEX_UBRXAT1_DEFAULT << 27) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXTRIAT1 (0x1UL << 28) /* Set TXTRI After Transmission */ +#define _USART_TXDOUBLEX_TXTRIAT1_SHIFT 28 /* Shift value for USART_TXTRIAT1 */ +#define _USART_TXDOUBLEX_TXTRIAT1_MASK 0x10000000UL /* Bit mask for USART_TXTRIAT1 */ +#define _USART_TXDOUBLEX_TXTRIAT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXTRIAT1_DEFAULT (_USART_TXDOUBLEX_TXTRIAT1_DEFAULT << 28) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXBREAK1 (0x1UL << 29) /* Transmit Data As Break */ +#define _USART_TXDOUBLEX_TXBREAK1_SHIFT 29 /* Shift value for USART_TXBREAK1 */ +#define _USART_TXDOUBLEX_TXBREAK1_MASK 0x20000000UL /* Bit mask for USART_TXBREAK1 */ +#define _USART_TXDOUBLEX_TXBREAK1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXBREAK1_DEFAULT (_USART_TXDOUBLEX_TXBREAK1_DEFAULT << 29) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDISAT1 (0x1UL << 30) /* Clear TXEN After Transmission */ +#define _USART_TXDOUBLEX_TXDISAT1_SHIFT 30 /* Shift value for USART_TXDISAT1 */ +#define _USART_TXDOUBLEX_TXDISAT1_MASK 0x40000000UL /* Bit mask for USART_TXDISAT1 */ +#define _USART_TXDOUBLEX_TXDISAT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_TXDISAT1_DEFAULT (_USART_TXDOUBLEX_TXDISAT1_DEFAULT << 30) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_RXENAT1 (0x1UL << 31) /* Enable RX After Transmission */ +#define _USART_TXDOUBLEX_RXENAT1_SHIFT 31 /* Shift value for USART_RXENAT1 */ +#define _USART_TXDOUBLEX_RXENAT1_MASK 0x80000000UL /* Bit mask for USART_RXENAT1 */ +#define _USART_TXDOUBLEX_RXENAT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_RXENAT1_DEFAULT (_USART_TXDOUBLEX_RXENAT1_DEFAULT << 31) /* Shifted mode DEFAULT for USART_TXDOUBLEX */ + +/* Bit fields for USART TXDOUBLE */ + +#define _USART_TXDOUBLE_RESETVALUE 0x00000000UL /* Default value for USART_TXDOUBLE */ +#define _USART_TXDOUBLE_MASK 0x0000FFFFUL /* Mask for USART_TXDOUBLE */ + +#define _USART_TXDOUBLE_TXDATA0_SHIFT 0 /* Shift value for USART_TXDATA0 */ +#define _USART_TXDOUBLE_TXDATA0_MASK 0xFFUL /* Bit mask for USART_TXDATA0 */ +#define _USART_TXDOUBLE_TXDATA0_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLE */ +#define USART_TXDOUBLE_TXDATA0_DEFAULT (_USART_TXDOUBLE_TXDATA0_DEFAULT << 0) /* Shifted mode DEFAULT for USART_TXDOUBLE */ +#define _USART_TXDOUBLE_TXDATA1_SHIFT 8 /* Shift value for USART_TXDATA1 */ +#define _USART_TXDOUBLE_TXDATA1_MASK 0xFF00UL /* Bit mask for USART_TXDATA1 */ +#define _USART_TXDOUBLE_TXDATA1_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_TXDOUBLE */ +#define USART_TXDOUBLE_TXDATA1_DEFAULT (_USART_TXDOUBLE_TXDATA1_DEFAULT << 8) /* Shifted mode DEFAULT for USART_TXDOUBLE */ + +/* Bit fields for USART IF */ + +#define _USART_IF_RESETVALUE 0x00000002UL /* Default value for USART_IF */ +#define _USART_IF_MASK 0x00001FFFUL /* Mask for USART_IF */ + +#define USART_IF_TXC (0x1UL << 0) /* TX Complete Interrupt Flag */ +#define _USART_IF_TXC_SHIFT 0 /* Shift value for USART_TXC */ +#define _USART_IF_TXC_MASK 0x1UL /* Bit mask for USART_TXC */ +#define _USART_IF_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_TXC_DEFAULT (_USART_IF_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_TXBL (0x1UL << 1) /* TX Buffer Level Interrupt Flag */ +#define _USART_IF_TXBL_SHIFT 1 /* Shift value for USART_TXBL */ +#define _USART_IF_TXBL_MASK 0x2UL /* Bit mask for USART_TXBL */ +#define _USART_IF_TXBL_DEFAULT 0x00000001UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_TXBL_DEFAULT (_USART_IF_TXBL_DEFAULT << 1) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_RXDATAV (0x1UL << 2) /* RX Data Valid Interrupt Flag */ +#define _USART_IF_RXDATAV_SHIFT 2 /* Shift value for USART_RXDATAV */ +#define _USART_IF_RXDATAV_MASK 0x4UL /* Bit mask for USART_RXDATAV */ +#define _USART_IF_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_RXDATAV_DEFAULT (_USART_IF_RXDATAV_DEFAULT << 2) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_RXFULL (0x1UL << 3) /* RX Buffer Full Interrupt Flag */ +#define _USART_IF_RXFULL_SHIFT 3 /* Shift value for USART_RXFULL */ +#define _USART_IF_RXFULL_MASK 0x8UL /* Bit mask for USART_RXFULL */ +#define _USART_IF_RXFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_RXFULL_DEFAULT (_USART_IF_RXFULL_DEFAULT << 3) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_RXOF (0x1UL << 4) /* RX Overflow Interrupt Flag */ +#define _USART_IF_RXOF_SHIFT 4 /* Shift value for USART_RXOF */ +#define _USART_IF_RXOF_MASK 0x10UL /* Bit mask for USART_RXOF */ +#define _USART_IF_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_RXOF_DEFAULT (_USART_IF_RXOF_DEFAULT << 4) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_RXUF (0x1UL << 5) /* RX Underflow Interrupt Flag */ +#define _USART_IF_RXUF_SHIFT 5 /* Shift value for USART_RXUF */ +#define _USART_IF_RXUF_MASK 0x20UL /* Bit mask for USART_RXUF */ +#define _USART_IF_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_RXUF_DEFAULT (_USART_IF_RXUF_DEFAULT << 5) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_TXOF (0x1UL << 6) /* TX Overflow Interrupt Flag */ +#define _USART_IF_TXOF_SHIFT 6 /* Shift value for USART_TXOF */ +#define _USART_IF_TXOF_MASK 0x40UL /* Bit mask for USART_TXOF */ +#define _USART_IF_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_TXOF_DEFAULT (_USART_IF_TXOF_DEFAULT << 6) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_TXUF (0x1UL << 7) /* TX Underflow Interrupt Flag */ +#define _USART_IF_TXUF_SHIFT 7 /* Shift value for USART_TXUF */ +#define _USART_IF_TXUF_MASK 0x80UL /* Bit mask for USART_TXUF */ +#define _USART_IF_TXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_TXUF_DEFAULT (_USART_IF_TXUF_DEFAULT << 7) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_PERR (0x1UL << 8) /* Parity Error Interrupt Flag */ +#define _USART_IF_PERR_SHIFT 8 /* Shift value for USART_PERR */ +#define _USART_IF_PERR_MASK 0x100UL /* Bit mask for USART_PERR */ +#define _USART_IF_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_PERR_DEFAULT (_USART_IF_PERR_DEFAULT << 8) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_FERR (0x1UL << 9) /* Framing Error Interrupt Flag */ +#define _USART_IF_FERR_SHIFT 9 /* Shift value for USART_FERR */ +#define _USART_IF_FERR_MASK 0x200UL /* Bit mask for USART_FERR */ +#define _USART_IF_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_FERR_DEFAULT (_USART_IF_FERR_DEFAULT << 9) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_MPAF (0x1UL << 10) /* Multi-Processor Address Frame Interrupt Flag */ +#define _USART_IF_MPAF_SHIFT 10 /* Shift value for USART_MPAF */ +#define _USART_IF_MPAF_MASK 0x400UL /* Bit mask for USART_MPAF */ +#define _USART_IF_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_MPAF_DEFAULT (_USART_IF_MPAF_DEFAULT << 10) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_SSM (0x1UL << 11) /* Slave-Select In Master Mode Interrupt Flag */ +#define _USART_IF_SSM_SHIFT 11 /* Shift value for USART_SSM */ +#define _USART_IF_SSM_MASK 0x800UL /* Bit mask for USART_SSM */ +#define _USART_IF_SSM_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_SSM_DEFAULT (_USART_IF_SSM_DEFAULT << 11) /* Shifted mode DEFAULT for USART_IF */ +#define USART_IF_CCF (0x1UL << 12) /* Collision Check Fail Interrupt Flag */ +#define _USART_IF_CCF_SHIFT 12 /* Shift value for USART_CCF */ +#define _USART_IF_CCF_MASK 0x1000UL /* Bit mask for USART_CCF */ +#define _USART_IF_CCF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IF */ +#define USART_IF_CCF_DEFAULT (_USART_IF_CCF_DEFAULT << 12) /* Shifted mode DEFAULT for USART_IF */ + +/* Bit fields for USART IFS */ + +#define _USART_IFS_RESETVALUE 0x00000000UL /* Default value for USART_IFS */ +#define _USART_IFS_MASK 0x00001FF9UL /* Mask for USART_IFS */ + +#define USART_IFS_TXC (0x1UL << 0) /* Set TX Complete Interrupt Flag */ +#define _USART_IFS_TXC_SHIFT 0 /* Shift value for USART_TXC */ +#define _USART_IFS_TXC_MASK 0x1UL /* Bit mask for USART_TXC */ +#define _USART_IFS_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_TXC_DEFAULT (_USART_IFS_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_RXFULL (0x1UL << 3) /* Set RX Buffer Full Interrupt Flag */ +#define _USART_IFS_RXFULL_SHIFT 3 /* Shift value for USART_RXFULL */ +#define _USART_IFS_RXFULL_MASK 0x8UL /* Bit mask for USART_RXFULL */ +#define _USART_IFS_RXFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_RXFULL_DEFAULT (_USART_IFS_RXFULL_DEFAULT << 3) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_RXOF (0x1UL << 4) /* Set RX Overflow Interrupt Flag */ +#define _USART_IFS_RXOF_SHIFT 4 /* Shift value for USART_RXOF */ +#define _USART_IFS_RXOF_MASK 0x10UL /* Bit mask for USART_RXOF */ +#define _USART_IFS_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_RXOF_DEFAULT (_USART_IFS_RXOF_DEFAULT << 4) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_RXUF (0x1UL << 5) /* Set RX Underflow Interrupt Flag */ +#define _USART_IFS_RXUF_SHIFT 5 /* Shift value for USART_RXUF */ +#define _USART_IFS_RXUF_MASK 0x20UL /* Bit mask for USART_RXUF */ +#define _USART_IFS_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_RXUF_DEFAULT (_USART_IFS_RXUF_DEFAULT << 5) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_TXOF (0x1UL << 6) /* Set TX Overflow Interrupt Flag */ +#define _USART_IFS_TXOF_SHIFT 6 /* Shift value for USART_TXOF */ +#define _USART_IFS_TXOF_MASK 0x40UL /* Bit mask for USART_TXOF */ +#define _USART_IFS_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_TXOF_DEFAULT (_USART_IFS_TXOF_DEFAULT << 6) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_TXUF (0x1UL << 7) /* Set TX Underflow Interrupt Flag */ +#define _USART_IFS_TXUF_SHIFT 7 /* Shift value for USART_TXUF */ +#define _USART_IFS_TXUF_MASK 0x80UL /* Bit mask for USART_TXUF */ +#define _USART_IFS_TXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_TXUF_DEFAULT (_USART_IFS_TXUF_DEFAULT << 7) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_PERR (0x1UL << 8) /* Set Parity Error Interrupt Flag */ +#define _USART_IFS_PERR_SHIFT 8 /* Shift value for USART_PERR */ +#define _USART_IFS_PERR_MASK 0x100UL /* Bit mask for USART_PERR */ +#define _USART_IFS_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_PERR_DEFAULT (_USART_IFS_PERR_DEFAULT << 8) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_FERR (0x1UL << 9) /* Set Framing Error Interrupt Flag */ +#define _USART_IFS_FERR_SHIFT 9 /* Shift value for USART_FERR */ +#define _USART_IFS_FERR_MASK 0x200UL /* Bit mask for USART_FERR */ +#define _USART_IFS_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_FERR_DEFAULT (_USART_IFS_FERR_DEFAULT << 9) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_MPAF (0x1UL << 10) /* Set Multi-Processor Address Frame Interrupt Flag */ +#define _USART_IFS_MPAF_SHIFT 10 /* Shift value for USART_MPAF */ +#define _USART_IFS_MPAF_MASK 0x400UL /* Bit mask for USART_MPAF */ +#define _USART_IFS_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_MPAF_DEFAULT (_USART_IFS_MPAF_DEFAULT << 10) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_SSM (0x1UL << 11) /* Set Slave-Select in Master mode Interrupt Flag */ +#define _USART_IFS_SSM_SHIFT 11 /* Shift value for USART_SSM */ +#define _USART_IFS_SSM_MASK 0x800UL /* Bit mask for USART_SSM */ +#define _USART_IFS_SSM_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_SSM_DEFAULT (_USART_IFS_SSM_DEFAULT << 11) /* Shifted mode DEFAULT for USART_IFS */ +#define USART_IFS_CCF (0x1UL << 12) /* Set Collision Check Fail Interrupt Flag */ +#define _USART_IFS_CCF_SHIFT 12 /* Shift value for USART_CCF */ +#define _USART_IFS_CCF_MASK 0x1000UL /* Bit mask for USART_CCF */ +#define _USART_IFS_CCF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFS */ +#define USART_IFS_CCF_DEFAULT (_USART_IFS_CCF_DEFAULT << 12) /* Shifted mode DEFAULT for USART_IFS */ + +/* Bit fields for USART IFC */ + +#define _USART_IFC_RESETVALUE 0x00000000UL /* Default value for USART_IFC */ +#define _USART_IFC_MASK 0x00001FF9UL /* Mask for USART_IFC */ + +#define USART_IFC_TXC (0x1UL << 0) /* Clear TX Complete Interrupt Flag */ +#define _USART_IFC_TXC_SHIFT 0 /* Shift value for USART_TXC */ +#define _USART_IFC_TXC_MASK 0x1UL /* Bit mask for USART_TXC */ +#define _USART_IFC_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_TXC_DEFAULT (_USART_IFC_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_RXFULL (0x1UL << 3) /* Clear RX Buffer Full Interrupt Flag */ +#define _USART_IFC_RXFULL_SHIFT 3 /* Shift value for USART_RXFULL */ +#define _USART_IFC_RXFULL_MASK 0x8UL /* Bit mask for USART_RXFULL */ +#define _USART_IFC_RXFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_RXFULL_DEFAULT (_USART_IFC_RXFULL_DEFAULT << 3) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_RXOF (0x1UL << 4) /* Clear RX Overflow Interrupt Flag */ +#define _USART_IFC_RXOF_SHIFT 4 /* Shift value for USART_RXOF */ +#define _USART_IFC_RXOF_MASK 0x10UL /* Bit mask for USART_RXOF */ +#define _USART_IFC_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_RXOF_DEFAULT (_USART_IFC_RXOF_DEFAULT << 4) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_RXUF (0x1UL << 5) /* Clear RX Underflow Interrupt Flag */ +#define _USART_IFC_RXUF_SHIFT 5 /* Shift value for USART_RXUF */ +#define _USART_IFC_RXUF_MASK 0x20UL /* Bit mask for USART_RXUF */ +#define _USART_IFC_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_RXUF_DEFAULT (_USART_IFC_RXUF_DEFAULT << 5) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_TXOF (0x1UL << 6) /* Clear TX Overflow Interrupt Flag */ +#define _USART_IFC_TXOF_SHIFT 6 /* Shift value for USART_TXOF */ +#define _USART_IFC_TXOF_MASK 0x40UL /* Bit mask for USART_TXOF */ +#define _USART_IFC_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_TXOF_DEFAULT (_USART_IFC_TXOF_DEFAULT << 6) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_TXUF (0x1UL << 7) /* Clear TX Underflow Interrupt Flag */ +#define _USART_IFC_TXUF_SHIFT 7 /* Shift value for USART_TXUF */ +#define _USART_IFC_TXUF_MASK 0x80UL /* Bit mask for USART_TXUF */ +#define _USART_IFC_TXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_TXUF_DEFAULT (_USART_IFC_TXUF_DEFAULT << 7) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_PERR (0x1UL << 8) /* Clear Parity Error Interrupt Flag */ +#define _USART_IFC_PERR_SHIFT 8 /* Shift value for USART_PERR */ +#define _USART_IFC_PERR_MASK 0x100UL /* Bit mask for USART_PERR */ +#define _USART_IFC_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_PERR_DEFAULT (_USART_IFC_PERR_DEFAULT << 8) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_FERR (0x1UL << 9) /* Clear Framing Error Interrupt Flag */ +#define _USART_IFC_FERR_SHIFT 9 /* Shift value for USART_FERR */ +#define _USART_IFC_FERR_MASK 0x200UL /* Bit mask for USART_FERR */ +#define _USART_IFC_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_FERR_DEFAULT (_USART_IFC_FERR_DEFAULT << 9) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_MPAF (0x1UL << 10) /* Clear Multi-Processor Address Frame Interrupt Flag */ +#define _USART_IFC_MPAF_SHIFT 10 /* Shift value for USART_MPAF */ +#define _USART_IFC_MPAF_MASK 0x400UL /* Bit mask for USART_MPAF */ +#define _USART_IFC_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_MPAF_DEFAULT (_USART_IFC_MPAF_DEFAULT << 10) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_SSM (0x1UL << 11) /* Clear Slave-Select In Master Mode Interrupt Flag */ +#define _USART_IFC_SSM_SHIFT 11 /* Shift value for USART_SSM */ +#define _USART_IFC_SSM_MASK 0x800UL /* Bit mask for USART_SSM */ +#define _USART_IFC_SSM_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_SSM_DEFAULT (_USART_IFC_SSM_DEFAULT << 11) /* Shifted mode DEFAULT for USART_IFC */ +#define USART_IFC_CCF (0x1UL << 12) /* Clear Collision Check Fail Interrupt Flag */ +#define _USART_IFC_CCF_SHIFT 12 /* Shift value for USART_CCF */ +#define _USART_IFC_CCF_MASK 0x1000UL /* Bit mask for USART_CCF */ +#define _USART_IFC_CCF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IFC */ +#define USART_IFC_CCF_DEFAULT (_USART_IFC_CCF_DEFAULT << 12) /* Shifted mode DEFAULT for USART_IFC */ + +/* Bit fields for USART IEN */ + +#define _USART_IEN_RESETVALUE 0x00000000UL /* Default value for USART_IEN */ +#define _USART_IEN_MASK 0x00001FFFUL /* Mask for USART_IEN */ + +#define USART_IEN_TXC (0x1UL << 0) /* TX Complete Interrupt Enable */ +#define _USART_IEN_TXC_SHIFT 0 /* Shift value for USART_TXC */ +#define _USART_IEN_TXC_MASK 0x1UL /* Bit mask for USART_TXC */ +#define _USART_IEN_TXC_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_TXC_DEFAULT (_USART_IEN_TXC_DEFAULT << 0) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_TXBL (0x1UL << 1) /* TX Buffer Level Interrupt Enable */ +#define _USART_IEN_TXBL_SHIFT 1 /* Shift value for USART_TXBL */ +#define _USART_IEN_TXBL_MASK 0x2UL /* Bit mask for USART_TXBL */ +#define _USART_IEN_TXBL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_TXBL_DEFAULT (_USART_IEN_TXBL_DEFAULT << 1) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_RXDATAV (0x1UL << 2) /* RX Data Valid Interrupt Enable */ +#define _USART_IEN_RXDATAV_SHIFT 2 /* Shift value for USART_RXDATAV */ +#define _USART_IEN_RXDATAV_MASK 0x4UL /* Bit mask for USART_RXDATAV */ +#define _USART_IEN_RXDATAV_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_RXDATAV_DEFAULT (_USART_IEN_RXDATAV_DEFAULT << 2) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_RXFULL (0x1UL << 3) /* RX Buffer Full Interrupt Enable */ +#define _USART_IEN_RXFULL_SHIFT 3 /* Shift value for USART_RXFULL */ +#define _USART_IEN_RXFULL_MASK 0x8UL /* Bit mask for USART_RXFULL */ +#define _USART_IEN_RXFULL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_RXFULL_DEFAULT (_USART_IEN_RXFULL_DEFAULT << 3) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_RXOF (0x1UL << 4) /* RX Overflow Interrupt Enable */ +#define _USART_IEN_RXOF_SHIFT 4 /* Shift value for USART_RXOF */ +#define _USART_IEN_RXOF_MASK 0x10UL /* Bit mask for USART_RXOF */ +#define _USART_IEN_RXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_RXOF_DEFAULT (_USART_IEN_RXOF_DEFAULT << 4) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_RXUF (0x1UL << 5) /* RX Underflow Interrupt Enable */ +#define _USART_IEN_RXUF_SHIFT 5 /* Shift value for USART_RXUF */ +#define _USART_IEN_RXUF_MASK 0x20UL /* Bit mask for USART_RXUF */ +#define _USART_IEN_RXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_RXUF_DEFAULT (_USART_IEN_RXUF_DEFAULT << 5) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_TXOF (0x1UL << 6) /* TX Overflow Interrupt Enable */ +#define _USART_IEN_TXOF_SHIFT 6 /* Shift value for USART_TXOF */ +#define _USART_IEN_TXOF_MASK 0x40UL /* Bit mask for USART_TXOF */ +#define _USART_IEN_TXOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_TXOF_DEFAULT (_USART_IEN_TXOF_DEFAULT << 6) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_TXUF (0x1UL << 7) /* TX Underflow Interrupt Enable */ +#define _USART_IEN_TXUF_SHIFT 7 /* Shift value for USART_TXUF */ +#define _USART_IEN_TXUF_MASK 0x80UL /* Bit mask for USART_TXUF */ +#define _USART_IEN_TXUF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_TXUF_DEFAULT (_USART_IEN_TXUF_DEFAULT << 7) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_PERR (0x1UL << 8) /* Parity Error Interrupt Enable */ +#define _USART_IEN_PERR_SHIFT 8 /* Shift value for USART_PERR */ +#define _USART_IEN_PERR_MASK 0x100UL /* Bit mask for USART_PERR */ +#define _USART_IEN_PERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_PERR_DEFAULT (_USART_IEN_PERR_DEFAULT << 8) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_FERR (0x1UL << 9) /* Framing Error Interrupt Enable */ +#define _USART_IEN_FERR_SHIFT 9 /* Shift value for USART_FERR */ +#define _USART_IEN_FERR_MASK 0x200UL /* Bit mask for USART_FERR */ +#define _USART_IEN_FERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_FERR_DEFAULT (_USART_IEN_FERR_DEFAULT << 9) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_MPAF (0x1UL << 10) /* Multi-Processor Address Frame Interrupt Enable */ +#define _USART_IEN_MPAF_SHIFT 10 /* Shift value for USART_MPAF */ +#define _USART_IEN_MPAF_MASK 0x400UL /* Bit mask for USART_MPAF */ +#define _USART_IEN_MPAF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_MPAF_DEFAULT (_USART_IEN_MPAF_DEFAULT << 10) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_SSM (0x1UL << 11) /* Slave-Select In Master Mode Interrupt Enable */ +#define _USART_IEN_SSM_SHIFT 11 /* Shift value for USART_SSM */ +#define _USART_IEN_SSM_MASK 0x800UL /* Bit mask for USART_SSM */ +#define _USART_IEN_SSM_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_SSM_DEFAULT (_USART_IEN_SSM_DEFAULT << 11) /* Shifted mode DEFAULT for USART_IEN */ +#define USART_IEN_CCF (0x1UL << 12) /* Collision Check Fail Interrupt Enable */ +#define _USART_IEN_CCF_SHIFT 12 /* Shift value for USART_CCF */ +#define _USART_IEN_CCF_MASK 0x1000UL /* Bit mask for USART_CCF */ +#define _USART_IEN_CCF_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IEN */ +#define USART_IEN_CCF_DEFAULT (_USART_IEN_CCF_DEFAULT << 12) /* Shifted mode DEFAULT for USART_IEN */ + +/* Bit fields for USART IRCTRL */ + +#define _USART_IRCTRL_RESETVALUE 0x00000000UL /* Default value for USART_IRCTRL */ +#define _USART_IRCTRL_MASK 0x000000FFUL /* Mask for USART_IRCTRL */ + +#define USART_IRCTRL_IREN (0x1UL << 0) /* Enable IrDA Module */ +#define _USART_IRCTRL_IREN_SHIFT 0 /* Shift value for USART_IREN */ +#define _USART_IRCTRL_IREN_MASK 0x1UL /* Bit mask for USART_IREN */ +#define _USART_IRCTRL_IREN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IRCTRL */ +#define USART_IRCTRL_IREN_DEFAULT (_USART_IRCTRL_IREN_DEFAULT << 0) /* Shifted mode DEFAULT for USART_IRCTRL */ +#define _USART_IRCTRL_IRPW_SHIFT 1 /* Shift value for USART_IRPW */ +#define _USART_IRCTRL_IRPW_MASK 0x6UL /* Bit mask for USART_IRPW */ +#define _USART_IRCTRL_IRPW_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IRCTRL */ +#define _USART_IRCTRL_IRPW_ONE 0x00000000UL /* Mode ONE for USART_IRCTRL */ +#define _USART_IRCTRL_IRPW_TWO 0x00000001UL /* Mode TWO for USART_IRCTRL */ +#define _USART_IRCTRL_IRPW_THREE 0x00000002UL /* Mode THREE for USART_IRCTRL */ +#define _USART_IRCTRL_IRPW_FOUR 0x00000003UL /* Mode FOUR for USART_IRCTRL */ +#define USART_IRCTRL_IRPW_DEFAULT (_USART_IRCTRL_IRPW_DEFAULT << 1) /* Shifted mode DEFAULT for USART_IRCTRL */ +#define USART_IRCTRL_IRPW_ONE (_USART_IRCTRL_IRPW_ONE << 1) /* Shifted mode ONE for USART_IRCTRL */ +#define USART_IRCTRL_IRPW_TWO (_USART_IRCTRL_IRPW_TWO << 1) /* Shifted mode TWO for USART_IRCTRL */ +#define USART_IRCTRL_IRPW_THREE (_USART_IRCTRL_IRPW_THREE << 1) /* Shifted mode THREE for USART_IRCTRL */ +#define USART_IRCTRL_IRPW_FOUR (_USART_IRCTRL_IRPW_FOUR << 1) /* Shifted mode FOUR for USART_IRCTRL */ +#define USART_IRCTRL_IRFILT (0x1UL << 3) /* IrDA RX Filter */ +#define _USART_IRCTRL_IRFILT_SHIFT 3 /* Shift value for USART_IRFILT */ +#define _USART_IRCTRL_IRFILT_MASK 0x8UL /* Bit mask for USART_IRFILT */ +#define _USART_IRCTRL_IRFILT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IRCTRL */ +#define USART_IRCTRL_IRFILT_DEFAULT (_USART_IRCTRL_IRFILT_DEFAULT << 3) /* Shifted mode DEFAULT for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_SHIFT 4 /* Shift value for USART_IRPRSSEL */ +#define _USART_IRCTRL_IRPRSSEL_MASK 0x70UL /* Bit mask for USART_IRPRSSEL */ +#define _USART_IRCTRL_IRPRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for USART_IRCTRL */ +#define _USART_IRCTRL_IRPRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_DEFAULT (_USART_IRCTRL_IRPRSSEL_DEFAULT << 4) /* Shifted mode DEFAULT for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH0 (_USART_IRCTRL_IRPRSSEL_PRSCH0 << 4) /* Shifted mode PRSCH0 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH1 (_USART_IRCTRL_IRPRSSEL_PRSCH1 << 4) /* Shifted mode PRSCH1 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH2 (_USART_IRCTRL_IRPRSSEL_PRSCH2 << 4) /* Shifted mode PRSCH2 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH3 (_USART_IRCTRL_IRPRSSEL_PRSCH3 << 4) /* Shifted mode PRSCH3 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH4 (_USART_IRCTRL_IRPRSSEL_PRSCH4 << 4) /* Shifted mode PRSCH4 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH5 (_USART_IRCTRL_IRPRSSEL_PRSCH5 << 4) /* Shifted mode PRSCH5 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH6 (_USART_IRCTRL_IRPRSSEL_PRSCH6 << 4) /* Shifted mode PRSCH6 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSSEL_PRSCH7 (_USART_IRCTRL_IRPRSSEL_PRSCH7 << 4) /* Shifted mode PRSCH7 for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSEN (0x1UL << 7) /* IrDA PRS Channel Enable */ +#define _USART_IRCTRL_IRPRSEN_SHIFT 7 /* Shift value for USART_IRPRSEN */ +#define _USART_IRCTRL_IRPRSEN_MASK 0x80UL /* Bit mask for USART_IRPRSEN */ +#define _USART_IRCTRL_IRPRSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_IRCTRL */ +#define USART_IRCTRL_IRPRSEN_DEFAULT (_USART_IRCTRL_IRPRSEN_DEFAULT << 7) /* Shifted mode DEFAULT for USART_IRCTRL */ + +/* Bit fields for USART ROUTE */ + +#define _USART_ROUTE_RESETVALUE 0x00000000UL /* Default value for USART_ROUTE */ +#define _USART_ROUTE_MASK 0x0000070FUL /* Mask for USART_ROUTE */ + +#define USART_ROUTE_RXPEN (0x1UL << 0) /* RX Pin Enable */ +#define _USART_ROUTE_RXPEN_SHIFT 0 /* Shift value for USART_RXPEN */ +#define _USART_ROUTE_RXPEN_MASK 0x1UL /* Bit mask for USART_RXPEN */ +#define _USART_ROUTE_RXPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_RXPEN_DEFAULT (_USART_ROUTE_RXPEN_DEFAULT << 0) /* Shifted mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_TXPEN (0x1UL << 1) /* TX Pin Enable */ +#define _USART_ROUTE_TXPEN_SHIFT 1 /* Shift value for USART_TXPEN */ +#define _USART_ROUTE_TXPEN_MASK 0x2UL /* Bit mask for USART_TXPEN */ +#define _USART_ROUTE_TXPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_TXPEN_DEFAULT (_USART_ROUTE_TXPEN_DEFAULT << 1) /* Shifted mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_CSPEN (0x1UL << 2) /* CS Pin Enable */ +#define _USART_ROUTE_CSPEN_SHIFT 2 /* Shift value for USART_CSPEN */ +#define _USART_ROUTE_CSPEN_MASK 0x4UL /* Bit mask for USART_CSPEN */ +#define _USART_ROUTE_CSPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_CSPEN_DEFAULT (_USART_ROUTE_CSPEN_DEFAULT << 2) /* Shifted mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_CLKPEN (0x1UL << 3) /* CLK Pin Enable */ +#define _USART_ROUTE_CLKPEN_SHIFT 3 /* Shift value for USART_CLKPEN */ +#define _USART_ROUTE_CLKPEN_MASK 0x8UL /* Bit mask for USART_CLKPEN */ +#define _USART_ROUTE_CLKPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_CLKPEN_DEFAULT (_USART_ROUTE_CLKPEN_DEFAULT << 3) /* Shifted mode DEFAULT for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_SHIFT 8 /* Shift value for USART_LOCATION */ +#define _USART_ROUTE_LOCATION_MASK 0x700UL /* Bit mask for USART_LOCATION */ +#define _USART_ROUTE_LOCATION_LOC0 0x00000000UL /* Mode LOC0 for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_LOC1 0x00000001UL /* Mode LOC1 for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_LOC2 0x00000002UL /* Mode LOC2 for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_LOC3 0x00000003UL /* Mode LOC3 for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_LOC4 0x00000004UL /* Mode LOC4 for USART_ROUTE */ +#define _USART_ROUTE_LOCATION_LOC5 0x00000005UL /* Mode LOC5 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC0 (_USART_ROUTE_LOCATION_LOC0 << 8) /* Shifted mode LOC0 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_DEFAULT (_USART_ROUTE_LOCATION_DEFAULT << 8) /* Shifted mode DEFAULT for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC1 (_USART_ROUTE_LOCATION_LOC1 << 8) /* Shifted mode LOC1 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC2 (_USART_ROUTE_LOCATION_LOC2 << 8) /* Shifted mode LOC2 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC3 (_USART_ROUTE_LOCATION_LOC3 << 8) /* Shifted mode LOC3 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC4 (_USART_ROUTE_LOCATION_LOC4 << 8) /* Shifted mode LOC4 for USART_ROUTE */ +#define USART_ROUTE_LOCATION_LOC5 (_USART_ROUTE_LOCATION_LOC5 << 8) /* Shifted mode LOC5 for USART_ROUTE */ + +/* Bit fields for USART INPUT */ + +#define _USART_INPUT_RESETVALUE 0x00000000UL /* Default value for USART_INPUT */ +#define _USART_INPUT_MASK 0x0000001FUL /* Mask for USART_INPUT */ + +#define _USART_INPUT_RXPRSSEL_SHIFT 0 /* Shift value for USART_RXPRSSEL */ +#define _USART_INPUT_RXPRSSEL_MASK 0xFUL /* Bit mask for USART_RXPRSSEL */ +#define _USART_INPUT_RXPRSSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH0 0x00000000UL /* Mode PRSCH0 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH1 0x00000001UL /* Mode PRSCH1 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH2 0x00000002UL /* Mode PRSCH2 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH3 0x00000003UL /* Mode PRSCH3 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH4 0x00000004UL /* Mode PRSCH4 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH5 0x00000005UL /* Mode PRSCH5 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH6 0x00000006UL /* Mode PRSCH6 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH7 0x00000007UL /* Mode PRSCH7 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH8 0x00000008UL /* Mode PRSCH8 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH9 0x00000009UL /* Mode PRSCH9 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH10 0x0000000AUL /* Mode PRSCH10 for USART_INPUT */ +#define _USART_INPUT_RXPRSSEL_PRSCH11 0x0000000BUL /* Mode PRSCH11 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_DEFAULT (_USART_INPUT_RXPRSSEL_DEFAULT << 0) /* Shifted mode DEFAULT for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH0 (_USART_INPUT_RXPRSSEL_PRSCH0 << 0) /* Shifted mode PRSCH0 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH1 (_USART_INPUT_RXPRSSEL_PRSCH1 << 0) /* Shifted mode PRSCH1 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH2 (_USART_INPUT_RXPRSSEL_PRSCH2 << 0) /* Shifted mode PRSCH2 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH3 (_USART_INPUT_RXPRSSEL_PRSCH3 << 0) /* Shifted mode PRSCH3 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH4 (_USART_INPUT_RXPRSSEL_PRSCH4 << 0) /* Shifted mode PRSCH4 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH5 (_USART_INPUT_RXPRSSEL_PRSCH5 << 0) /* Shifted mode PRSCH5 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH6 (_USART_INPUT_RXPRSSEL_PRSCH6 << 0) /* Shifted mode PRSCH6 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH7 (_USART_INPUT_RXPRSSEL_PRSCH7 << 0) /* Shifted mode PRSCH7 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH8 (_USART_INPUT_RXPRSSEL_PRSCH8 << 0) /* Shifted mode PRSCH8 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH9 (_USART_INPUT_RXPRSSEL_PRSCH9 << 0) /* Shifted mode PRSCH9 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH10 (_USART_INPUT_RXPRSSEL_PRSCH10 << 0) /* Shifted mode PRSCH10 for USART_INPUT */ +#define USART_INPUT_RXPRSSEL_PRSCH11 (_USART_INPUT_RXPRSSEL_PRSCH11 << 0) /* Shifted mode PRSCH11 for USART_INPUT */ +#define USART_INPUT_RXPRS (0x1UL << 4) /* PRS RX Enable */ +#define _USART_INPUT_RXPRS_SHIFT 4 /* Shift value for USART_RXPRS */ +#define _USART_INPUT_RXPRS_MASK 0x10UL /* Bit mask for USART_RXPRS */ +#define _USART_INPUT_RXPRS_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_INPUT */ +#define USART_INPUT_RXPRS_DEFAULT (_USART_INPUT_RXPRS_DEFAULT << 4) /* Shifted mode DEFAULT for USART_INPUT */ + +/* Bit fields for USART I2SCTRL */ + +#define _USART_I2SCTRL_RESETVALUE 0x00000000UL /* Default value for USART_I2SCTRL */ +#define _USART_I2SCTRL_MASK 0x0000071FUL /* Mask for USART_I2SCTRL */ + +#define USART_I2SCTRL_EN (0x1UL << 0) /* Enable I2S Mode */ +#define _USART_I2SCTRL_EN_SHIFT 0 /* Shift value for USART_EN */ +#define _USART_I2SCTRL_EN_MASK 0x1UL /* Bit mask for USART_EN */ +#define _USART_I2SCTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_EN_DEFAULT (_USART_I2SCTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_MONO (0x1UL << 1) /* Stero or Mono */ +#define _USART_I2SCTRL_MONO_SHIFT 1 /* Shift value for USART_MONO */ +#define _USART_I2SCTRL_MONO_MASK 0x2UL /* Bit mask for USART_MONO */ +#define _USART_I2SCTRL_MONO_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_MONO_DEFAULT (_USART_I2SCTRL_MONO_DEFAULT << 1) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_JUSTIFY (0x1UL << 2) /* Justification of I2S Data */ +#define _USART_I2SCTRL_JUSTIFY_SHIFT 2 /* Shift value for USART_JUSTIFY */ +#define _USART_I2SCTRL_JUSTIFY_MASK 0x4UL /* Bit mask for USART_JUSTIFY */ +#define _USART_I2SCTRL_JUSTIFY_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define _USART_I2SCTRL_JUSTIFY_LEFT 0x00000000UL /* Mode LEFT for USART_I2SCTRL */ +#define _USART_I2SCTRL_JUSTIFY_RIGHT 0x00000001UL /* Mode RIGHT for USART_I2SCTRL */ +#define USART_I2SCTRL_JUSTIFY_DEFAULT (_USART_I2SCTRL_JUSTIFY_DEFAULT << 2) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_JUSTIFY_LEFT (_USART_I2SCTRL_JUSTIFY_LEFT << 2) /* Shifted mode LEFT for USART_I2SCTRL */ +#define USART_I2SCTRL_JUSTIFY_RIGHT (_USART_I2SCTRL_JUSTIFY_RIGHT << 2) /* Shifted mode RIGHT for USART_I2SCTRL */ +#define USART_I2SCTRL_DMASPLIT (0x1UL << 3) /* Separate DMA Request For Left/Right Data */ +#define _USART_I2SCTRL_DMASPLIT_SHIFT 3 /* Shift value for USART_DMASPLIT */ +#define _USART_I2SCTRL_DMASPLIT_MASK 0x8UL /* Bit mask for USART_DMASPLIT */ +#define _USART_I2SCTRL_DMASPLIT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_DMASPLIT_DEFAULT (_USART_I2SCTRL_DMASPLIT_DEFAULT << 3) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_DELAY (0x1UL << 4) /* Delay on I2S data */ +#define _USART_I2SCTRL_DELAY_SHIFT 4 /* Shift value for USART_DELAY */ +#define _USART_I2SCTRL_DELAY_MASK 0x10UL /* Bit mask for USART_DELAY */ +#define _USART_I2SCTRL_DELAY_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_DELAY_DEFAULT (_USART_I2SCTRL_DELAY_DEFAULT << 4) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_SHIFT 8 /* Shift value for USART_FORMAT */ +#define _USART_I2SCTRL_FORMAT_MASK 0x700UL /* Bit mask for USART_FORMAT */ +#define _USART_I2SCTRL_FORMAT_DEFAULT 0x00000000UL /* Mode DEFAULT for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W32D32 0x00000000UL /* Mode W32D32 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W32D24M 0x00000001UL /* Mode W32D24M for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W32D24 0x00000002UL /* Mode W32D24 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W32D16 0x00000003UL /* Mode W32D16 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W32D8 0x00000004UL /* Mode W32D8 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W16D16 0x00000005UL /* Mode W16D16 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W16D8 0x00000006UL /* Mode W16D8 for USART_I2SCTRL */ +#define _USART_I2SCTRL_FORMAT_W8D8 0x00000007UL /* Mode W8D8 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_DEFAULT (_USART_I2SCTRL_FORMAT_DEFAULT << 8) /* Shifted mode DEFAULT for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W32D32 (_USART_I2SCTRL_FORMAT_W32D32 << 8) /* Shifted mode W32D32 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W32D24M (_USART_I2SCTRL_FORMAT_W32D24M << 8) /* Shifted mode W32D24M for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W32D24 (_USART_I2SCTRL_FORMAT_W32D24 << 8) /* Shifted mode W32D24 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W32D16 (_USART_I2SCTRL_FORMAT_W32D16 << 8) /* Shifted mode W32D16 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W32D8 (_USART_I2SCTRL_FORMAT_W32D8 << 8) /* Shifted mode W32D8 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W16D16 (_USART_I2SCTRL_FORMAT_W16D16 << 8) /* Shifted mode W16D16 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W16D8 (_USART_I2SCTRL_FORMAT_W16D8 << 8) /* Shifted mode W16D8 for USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_W8D8 (_USART_I2SCTRL_FORMAT_W8D8 << 8) /* Shifted mode W8D8 for USART_I2SCTRL */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USART_H */ diff --git a/arch/arm/src/efm32/chip/efm32_usb.h b/arch/arm/src/efm32/chip/efm32_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..92c53e77a6204556d8968b9593e61d6bc02965bb --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_usb.h @@ -0,0 +1,3158 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_usb.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USB_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USB_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* General definitions */ + +#define EFM32_USB_EPTYPE_CTRL (0) /* Control */ +#define EFM32_USB_EPTYPE_ISOC (1) /* Isochronous */ +#define EFM32_USB_EPTYPE_BULK (2) /* Bulk */ +#define EFM32_USB_EPTYPE_INTR (3) /* Interrupt */ + +#define EFM32_USB_PID_DATA0 (0) +#define EFM32_USB_PID_DATA2 (1) +#define EFM32_USB_PID_DATA1 (2) +#define EFM32_USB_PID_MDATA (3) /* Non-control */ +#define EFM32_USB_PID_SETUP (3) /* Control */ + +/* USB Register Offsets ********************************************************************************************************/ + +#define EFM32_USB_CTRL_OFFSET 0x00000 /* System Control Register */ +#define EFM32_USB_STATUS_OFFSET 0x00004 /* System Status Register */ +#define EFM32_USB_IF_OFFSET 0x00008 /* Interrupt Flag Register */ +#define EFM32_USB_IFS_OFFSET 0x0000c /* Interrupt Flag Set Register */ +#define EFM32_USB_IFC_OFFSET 0x00010 /* Interrupt Flag Clear Register */ +#define EFM32_USB_IEN_OFFSET 0x00014 /* Interrupt Enable Register */ +#define EFM32_USB_ROUTE_OFFSET 0x00018 /* I/O Routing Register */ + +#define EFM32_USB_GOTGCTL_OFFSET 0x3c000 /* OTG Control and Status Register */ +#define EFM32_USB_GOTGINT_OFFSET 0x3c004 /* OTG Interrupt Register */ +#define EFM32_USB_GAHBCFG_OFFSET 0x3c008 /* AHB Configuration Register */ +#define EFM32_USB_GUSBCFG_OFFSET 0x3c00c /* USB Configuration Register */ +#define EFM32_USB_GRSTCTL_OFFSET 0x3c010 /* Reset Register */ +#define EFM32_USB_GINTSTS_OFFSET 0x3c014 /* Interrupt Register */ +#define EFM32_USB_GINTMSK_OFFSET 0x3c018 /* Interrupt Mask Register */ +#define EFM32_USB_GRXSTSR_OFFSET 0x3c01c /* Receive Status Debug Read Register */ +#define EFM32_USB_GRXSTSP_OFFSET 0x3c020 /* Receive Status Read and Pop Register */ +#define EFM32_USB_GRXFSIZ_OFFSET 0x3c024 /* Receive FIFO Size Register */ +#define EFM32_USB_GNPTXFSIZ_OFFSET 0x3c028 /* Non-periodic Transmit FIFO Size Register */ +#define EFM32_USB_DIEPTXF0_OFFSET 0x3c028 /* Endpoint 0 Transmit FIFO size */ +#define EFM32_USB_GNPTXSTS_OFFSET 0x3c02c /* Non-periodic Transmit FIFO/Queue Status Register */ +#define EFM32_USB_GDFIFOCFG_OFFSET 0x3c05c /* Global DFIFO Configuration Register */ +#define EFM32_USB_HPTXFSIZ_OFFSET 0x3c100 /* Host Periodic Transmit FIFO Size Register */ + +#define EFM32_USB_DIEPTXF_OFFSET(n) (0x3c104 + (((n)-1) << 2)) +#define EFM32_USB_DIEPTXF1_OFFSET 0x3c104 /* Device IN Endpoint Transmit FIFO 1 Size Register */ +#define EFM32_USB_DIEPTXF2_OFFSET 0x3c108 /* Device IN Endpoint Transmit FIFO 2 Size Register */ +#define EFM32_USB_DIEPTXF3_OFFSET 0x3c10c /* Device IN Endpoint Transmit FIFO 3 Size Register */ +#define EFM32_USB_DIEPTXF4_OFFSET 0x3c110 /* Device IN Endpoint Transmit FIFO 4 Size Register */ +#define EFM32_USB_DIEPTXF5_OFFSET 0x3c114 /* Device IN Endpoint Transmit FIFO 5 Size Register */ +#define EFM32_USB_DIEPTXF6_OFFSET 0x3c118 /* Device IN Endpoint Transmit FIFO 6 Size Register */ + +#define EFM32_USB_HCFG_OFFSET 0x3c400 /* Host Configuration Register */ +#define EFM32_USB_HFIR_OFFSET 0x3c404 /* Host Frame Interval Register */ +#define EFM32_USB_HFNUM_OFFSET 0x3c408 /* Host Frame Number/Frame Time Remaining Register */ +#define EFM32_USB_HPTXSTS_OFFSET 0x3c410 /* Host Periodic Transmit FIFO/Queue Status Register */ +#define EFM32_USB_HAINT_OFFSET 0x3c414 /* Host All Channels Interrupt Register */ +#define EFM32_USB_HAINTMSK_OFFSET 0x3c418 /* Host All Channels Interrupt Mask Register */ +#define EFM32_USB_HPRT_OFFSET 0x3c440 /* Host Port Control and Status Register */ + +#define EFM32_USB_HCn_OFFSET(n) (0x3c500 + ((n) << 5)) +#define EFM32_USB_HC0_OFFSET 0x3c500 /* Host Channel 0 Offset */ +#define EFM32_USB_HC1_OFFSET 0x3c520 /* Host Channel 1 Offset */ +#define EFM32_USB_HC2_OFFSET 0x3c540 /* Host Channel 2 Offset */ +#define EFM32_USB_HC3_OFFSET 0x3c560 /* Host Channel 3 Offset */ +#define EFM32_USB_HC4_OFFSET 0x3c580 /* Host Channel 4 Offset */ +#define EFM32_USB_HC5_OFFSET 0x3c5a0 /* Host Channel 5 Offset */ +#define EFM32_USB_HC6_OFFSET 0x3c5c0 /* Host Channel 6 Offset */ +#define EFM32_USB_HC7_OFFSET 0x3c5e0 /* Host Channel 7 Offset */ +#define EFM32_USB_HC8_OFFSET 0x3c600 /* Host Channel 8 Offset */ +#define EFM32_USB_HC9_OFFSET 0x3c620 /* Host Channel 9 Offset */ +#define EFM32_USB_HC10_OFFSET 0x3c640 /* Host Channel 10 Offset */ +#define EFM32_USB_HC11_OFFSET 0x3c660 /* Host Channel 11 Offset */ +#define EFM32_USB_HC12_OFFSET 0x3c680 /* Host Channel 12 Offset */ +#define EFM32_USB_HC13_OFFSET 0x3c6a0 /* Host Channel 13 Offset */ + +#define EFM32_USB_HCn_CHAR_OFFSET 0x00000 /* Host Channel n Characteristics Register */ +#define EFM32_USB_HCn_INT_OFFSET 0x00008 /* Host Channel n Interrupt Register */ +#define EFM32_USB_HCn_INTMSK_OFFSET 0x0000c /* Host Channel n Interrupt Mask Register */ +#define EFM32_USB_HCn_TSIZ_OFFSET 0x00010 /* Host Channel n Transfer Size Register */ +#define EFM32_USB_HCn_DMAADDR_OFFSET 0x00014 /* Host Channel n DMA Address Register */ + +#define EFM32_USB_DCFG_OFFSET 0x3c800 /* Device Configuration Register */ +#define EFM32_USB_DCTL_OFFSET 0x3c804 /* Device Control Register */ +#define EFM32_USB_DSTS_OFFSET 0x3c808 /* Device Status Register */ +#define EFM32_USB_DIEPMSK_OFFSET 0x3c810 /* Device IN Endpoint Common Interrupt Mask Register */ +#define EFM32_USB_DOEPMSK_OFFSET 0x3c814 /* Device OUT Endpoint Common Interrupt Mask Register */ +#define EFM32_USB_DAINT_OFFSET 0x3c818 /* Device All Endpoints Interrupt Register */ +#define EFM32_USB_DAINTMSK_OFFSET 0x3c81c /* Device All Endpoints Interrupt Mask Register */ +#define EFM32_USB_DVBUSDIS_OFFSET 0x3c828 /* Device VBUS Discharge Time Register */ +#define EFM32_USB_DVBUSPULSE_OFFSET 0x3c82C /* Device VBUS Pulsing Time Register */ +#define EFM32_USB_DIEPEMPMSK_OFFSET 0x3c834 /* Device IN Endpoint FIFO Empty Interrupt Mask Register */ + +#define EFM32_USB_DIEP_OFFSET(n) (0x3c900 + ((n) << 5)) +#define EFM32_USB_DIEP0_OFFSET 0x3c900 /* Device IN Endpoint 0 */ +#define EFM32_USB_DIEP1_OFFSET 0x3c920 /* Device IN Endpoint 1 */ +#define EFM32_USB_DIEP2_OFFSET 0x3c940 /* Device IN Endpoint 2 */ +#define EFM32_USB_DIEP3_OFFSET 0x3c960 /* Device IN Endpoint 3 */ +#define EFM32_USB_DIEP4_OFFSET 0x3c980 /* Device IN Endpoint 4 */ +#define EFM32_USB_DIEP5_OFFSET 0x3c9a0 /* Device IN Endpoint 5 */ +#define EFM32_USB_DIEP6_OFFSET 0x3c9c0 /* Device IN Endpoint 6 */ + +#define EFM32_USB_DIEPnCTL_OFFSET 0x00000 /* Device IN Endpoint n Control Register */ +#define EFM32_USB_DIEPnINT_OFFSET 0x00008 /* Device IN Endpoint n Interrupt Register */ +#define EFM32_USB_DIEPnTSIZ_OFFSET 0x00010 /* Device IN Endpoint n Transfer Size Register */ +#define EFM32_USB_DIEPnDMAADDR_OFFSET 0x00014 /* Device IN Endpoint n DMA Address Register */ +#define EFM32_USB_DIEPnTXFSTS_OFFSET 0x00018 /* Device IN Endpoint n Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP0CTL_OFFSET 0x3c900 /* Device IN Endpoint 0 Control Register */ +#define EFM32_USB_DIEP0INT_OFFSET 0x3c908 /* Device IN Endpoint 0 Interrupt Register */ +#define EFM32_USB_DIEP0TSIZ_OFFSET 0x3c910 /* Device IN Endpoint 0 Transfer Size Register */ +#define EFM32_USB_DIEP0DMAADDR_OFFSET 0x3c914 /* Device IN Endpoint 0 DMA Address Register */ +#define EFM32_USB_DIEP0TXFSTS_OFFSET 0x3c918 /* Device IN Endpoint 0 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP1CTL_OFFSET 0x3c920 /* Device IN Endpoint 1 Control Register */ +#define EFM32_USB_DIEP1INT_OFFSET 0x3c928 /* Device IN Endpoint 1 Interrupt Register */ +#define EFM32_USB_DIEP1TSIZ_OFFSET 0x3c930 /* Device IN Endpoint 1 Transfer Size Register */ +#define EFM32_USB_DIEP1DMAADDR_OFFSET 0x3c934 /* Device IN Endpoint 1 DMA Address Register */ +#define EFM32_USB_DIEP1TXFSTS_OFFSET 0x3c938 /* Device IN Endpoint 1 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP2CTL_OFFSET 0x3c940 /* Device IN Endpoint 2 Control Register */ +#define EFM32_USB_DIEP2INT_OFFSET 0x3c948 /* Device IN Endpoint 2 Interrupt Register */ +#define EFM32_USB_DIEP2TSIZ_OFFSET 0x3c950 /* Device IN Endpoint 2 Transfer Size Register */ +#define EFM32_USB_DIEP2DMAADDR_OFFSET 0x3c954 /* Device IN Endpoint 2 DMA Address Register */ +#define EFM32_USB_DIEP2TXFSTS_OFFSET 0x3c958 /* Device IN Endpoint 2 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP3CTL_OFFSET 0x3c960 /* Device IN Endpoint 3 Control Register */ +#define EFM32_USB_DIEP3INT_OFFSET 0x3c968 /* Device IN Endpoint 3 Interrupt Register */ +#define EFM32_USB_DIEP3TSIZ_OFFSET 0x3c970 /* Device IN Endpoint 3 Transfer Size Register */ +#define EFM32_USB_DIEP3DMAADDR_OFFSET 0x3c974 /* Device IN Endpoint 3 DMA Address Register */ +#define EFM32_USB_DIEP3TXFSTS_OFFSET 0x3c978 /* Device IN Endpoint 3 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP4CTL_OFFSET 0x3c980 /* Device IN Endpoint 4 Control Register */ +#define EFM32_USB_DIEP4INT_OFFSET 0x3c988 /* Device IN Endpoint 4 Interrupt Register */ +#define EFM32_USB_DIEP4TSIZ_OFFSET 0x3c990 /* Device IN Endpoint 4 Transfer Size Register */ +#define EFM32_USB_DIEP4DMAADDR_OFFSET 0x3c994 /* Device IN Endpoint 4 DMA Address Register */ +#define EFM32_USB_DIEP4TXFSTS_OFFSET 0x3c998 /* Device IN Endpoint 4 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP5CTL_OFFSET 0x3c9a0 /* Device IN Endpoint 5 Control Register */ +#define EFM32_USB_DIEP5INT_OFFSET 0x3c9a8 /* Device IN Endpoint 5 Interrupt Register */ +#define EFM32_USB_DIEP5TSIZ_OFFSET 0x3c9b0 /* Device IN Endpoint 5 Transfer Size Register */ +#define EFM32_USB_DIEP5DMAADDR_OFFSET 0x3c9b4 /* Device IN Endpoint 5 DMA Address Register */ +#define EFM32_USB_DIEP5TXFSTS_OFFSET 0x3c9b8 /* Device IN Endpoint 5 Transmit FIFO Status Register */ + +#define EFM32_USB_DIEP6CTL_OFFSET 0x3c9c0 /* Device IN Endpoint 6 Control Register */ +#define EFM32_USB_DIEP6INT_OFFSET 0x3c9c8 /* Device IN Endpoint 6 Interrupt Register */ +#define EFM32_USB_DIEP6TSIZ_OFFSET 0x3c9d0 /* Device IN Endpoint 6 Transfer Size Register */ +#define EFM32_USB_DIEP6DMAADDR_OFFSET 0x3c9d4 /* Device IN Endpoint 6 DMA Address Register */ +#define EFM32_USB_DIEP6TXFSTS_OFFSET 0x3c9d8 /* Device IN Endpoint 6 Transmit FIFO Status Register */ + +#define EFM32_USB_DOEP_OFFSET(n) (0x3cb00 + ((n) << 5)) +#define EFM32_USB_DOEP0_OFFSET 0x3cb00 /* Device OUT Endpoint 0 */ +#define EFM32_USB_DOEP1_OFFSET 0x3cb20 /* Device OUT Endpoint 1 */ +#define EFM32_USB_DOEP2_OFFSET 0x3cb40 /* Device OUT Endpoint 2 */ +#define EFM32_USB_DOEP3_OFFSET 0x3cb60 /* Device OUT Endpoint 3 */ +#define EFM32_USB_DOEP4_OFFSET 0x3cb80 /* Device OUT Endpoint 4 */ +#define EFM32_USB_DOEP5_OFFSET 0x3cba0 /* Device OUT Endpoint 5 */ +#define EFM32_USB_DOEP6_OFFSET 0x3cbc0 /* Device OUT Endpoint 6 */ + +#define EFM32_USB_DOEPnCTL_OFFSET 0x00000 /* Device OUT Endpoint n Control Register */ +#define EFM32_USB_DOEPnINT_OFFSET 0x00008 /* Device OUT Endpoint n Interrupt Register */ +#define EFM32_USB_DOEPnTSIZ_OFFSET 0x00010 /* Device OUT Endpoint n Transfer Size Register */ +#define EFM32_USB_DOEPnDMAADDR_OFFSET 0x00014 /* Device OUT Endpoint n DMA Address Register */ + +#define EFM32_USB_DOEP0CTL_OFFSET 0x3cb00 /* Device OUT Endpoint 0 Control Register */ +#define EFM32_USB_DOEP0INT_OFFSET 0x3cb08 /* Device OUT Endpoint 0 Interrupt Register */ +#define EFM32_USB_DOEP0TSIZ_OFFSET 0x3cb10 /* Device OUT Endpoint 0 Transfer Size Register */ +#define EFM32_USB_DOEP0DMAADDR_OFFSET 0x3cb14 /* Device OUT Endpoint 0 DMA Address Register */ + +#define EFM32_USB_DOEP1CTL_OFFSET 0x3cb20 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP1INT_OFFSET 0x3cb28 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP1TSIZ_OFFSET 0x3cb30 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP1DMAADDR_OFFSET 0x3cb34 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_DOEP2_CTL_OFFSET 0x3cb40 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP2_INT_OFFSET 0x3cb48 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP2_TSIZ_OFFSET 0x3cb50 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP2_DMAADDR_OFFSET 0x3cb54 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_DOEP3CTL_OFFSET 0x3cb60 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP3INT_OFFSET 0x3cb68 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP3TSIZ_OFFSET 0x3cb70 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP3DMAADDR_OFFSET 0x3cb74 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_DOEP4CTL_OFFSET 0x3cb80 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP4INT_OFFSET 0x3cb88 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP4TSIZ_OFFSET 0x3cb90 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP4DMAADDR_OFFSET 0x3cb94 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_DOEP5CTL_OFFSET 0x3cba0 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP5INT_OFFSET 0x3cba8 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP5TSIZ_OFFSET 0x3cbb0 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP5DMAADDR_OFFSET 0x3cbb4 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_DOEP6CTL_OFFSET 0x3cbc0 /* Device OUT Endpoint x Control Register */ +#define EFM32_USB_DOEP6INT_OFFSET 0x3cbc8 /* Device OUT Endpoint x Interrupt Register */ +#define EFM32_USB_DOEP6TSIZ_OFFSET 0x3cbd0 /* Device OUT Endpoint x Transfer Size Register */ +#define EFM32_USB_DOEP6DMAADDR_OFFSET 0x3cbd4 /* Device OUT Endpoint x DMA Address Register */ + +#define EFM32_USB_PCGCCTL_OFFSET 0x3ce00 /* Power and Clock Gating Control Register */ + +/* Device EP/Host Channel FIFOs */ + +#define EFM32_USB_FIFO_OFFSET(n) (0x3d000 + ((n) << 12)) +#define EFM32_USB_FIFO0_OFFSET 0x3d000 +#define EFM32_USB_FIFO1_OFFSET 0x3e000 +#define EFM32_USB_FIFO2_OFFSET 0x3f000 +#define EFM32_USB_FIFO3_OFFSET 0x40000 +#define EFM32_USB_FIFO4_OFFSET 0x41000 +#define EFM32_USB_FIFO5_OFFSET 0x42000 +#define EFM32_USB_FIFO6_OFFSET 0x43000 +#define EFM32_USB_FIFO7_OFFSET 0x44000 +#define EFM32_USB_FIFO8_OFFSET 0x45000 +#define EFM32_USB_FIFO9_OFFSET 0x46000 +#define EFM32_USB_FIFO10_OFFSET 0x47000 +#define EFM32_USB_FIFO11_OFFSET 0x48000 +#define EFM32_USB_FIFO12_OFFSET 0x49000 +#define EFM32_USB_FIFO13_OFFSET 0x4a000 + +#define EFM32_USB_FIFOD_OFFSET(n,d) (EFM32_USB_FIFO_OFFSET(n) + ((d) << 2)) +#define EFM32_FIFORAM_OFFSET(d) (0x5c000 + ((d) << 2)) + +/* USB Register Addresses ******************************************************************************************************/ + +#define EFM32_USB_CTRL (EFM32_USB_BASE+EFM32_USB_CTRL_OFFSET) +#define EFM32_USB_STATUS (EFM32_USB_BASE+EFM32_USB_STATUS_OFFSET) +#define EFM32_USB_IF (EFM32_USB_BASE+EFM32_USB_IF_OFFSET) +#define EFM32_USB_IFS (EFM32_USB_BASE+EFM32_USB_IFS_OFFSET) +#define EFM32_USB_IFC (EFM32_USB_BASE+EFM32_USB_IFC_OFFSET) +#define EFM32_USB_IEN (EFM32_USB_BASE+EFM32_USB_IEN_OFFSET) +#define EFM32_USB_ROUTE (EFM32_USB_BASE+EFM32_USB_ROUTE_OFFSET) + +#define EFM32_USB_GOTGCTL (EFM32_USB_BASE+EFM32_USB_GOTGCTL_OFFSET) +#define EFM32_USB_GOTGINT (EFM32_USB_BASE+EFM32_USB_GOTGINT_OFFSET) +#define EFM32_USB_GAHBCFG (EFM32_USB_BASE+EFM32_USB_GAHBCFG_OFFSET) +#define EFM32_USB_GUSBCFG (EFM32_USB_BASE+EFM32_USB_GUSBCFG_OFFSET) +#define EFM32_USB_GRSTCTL (EFM32_USB_BASE+EFM32_USB_GRSTCTL_OFFSET) +#define EFM32_USB_GINTSTS (EFM32_USB_BASE+EFM32_USB_GINTSTS_OFFSET) +#define EFM32_USB_GINTMSK (EFM32_USB_BASE+EFM32_USB_GINTMSK_OFFSET) +#define EFM32_USB_GRXSTSR (EFM32_USB_BASE+EFM32_USB_GRXSTSR_OFFSET) +#define EFM32_USB_GRXSTSP (EFM32_USB_BASE+EFM32_USB_GRXSTSP_OFFSET) +#define EFM32_USB_GRXFSIZ (EFM32_USB_BASE+EFM32_USB_GRXFSIZ_OFFSET) +#define EFM32_USB_GNPTXFSIZ (EFM32_USB_BASE+EFM32_USB_GNPTXFSIZ_OFFSET) +#define EFM32_USB_DIEPTXF0 (EFM32_USB_BASE+EFM32_USB_DIEPTXF0_OFFSET) +#define EFM32_USB_GNPTXSTS (EFM32_USB_BASE+EFM32_USB_GNPTXSTS_OFFSET) +#define EFM32_USB_GDFIFOCFG (EFM32_USB_BASE+EFM32_USB_GDFIFOCFG_OFFSET) +#define EFM32_USB_HPTXFSIZ (EFM32_USB_BASE+EFM32_USB_HPTXFSIZ_OFFSET) + +#define EFM32_USB_DIEPTXF(n) (EFM32_USB_BASE+EFM32_USB_DIEPTXF_OFFSET(n)) +#define EFM32_USB_DIEPTXF1 (EFM32_USB_BASE+EFM32_USB_DIEPTXF1_OFFSET) +#define EFM32_USB_DIEPTXF2 (EFM32_USB_BASE+EFM32_USB_DIEPTXF2_OFFSET) +#define EFM32_USB_DIEPTXF3 (EFM32_USB_BASE+EFM32_USB_DIEPTXF3_OFFSET) +#define EFM32_USB_DIEPTXF4 (EFM32_USB_BASE+EFM32_USB_DIEPTXF4_OFFSET) +#define EFM32_USB_DIEPTXF5 (EFM32_USB_BASE+EFM32_USB_DIEPTXF5_OFFSET) +#define EFM32_USB_DIEPTXF6 (EFM32_USB_BASE+EFM32_USB_DIEPTXF6_OFFSET) + +#define EFM32_USB_HCFG (EFM32_USB_BASE+EFM32_USB_HCFG_OFFSET) +#define EFM32_USB_HFIR (EFM32_USB_BASE+EFM32_USB_HFIR_OFFSET) +#define EFM32_USB_HFNUM (EFM32_USB_BASE+EFM32_USB_HFNUM_OFFSET) +#define EFM32_USB_HPTXSTS (EFM32_USB_BASE+EFM32_USB_HPTXSTS_OFFSET) +#define EFM32_USB_HAINT (EFM32_USB_BASE+EFM32_USB_HAINT_OFFSET) +#define EFM32_USB_HAINTMSK (EFM32_USB_BASE+EFM32_USB_HAINTMSK_OFFSET) +#define EFM32_USB_HPRT (EFM32_USB_BASE+EFM32_USB_HPRT_OFFSET) + +#define EFM32_USB_HCn_BASE(n) (EFM32_USB_BASE+EFM32_USB_HCn_OFFSET(n)) +#define EFM32_USB_HC0_BASE (EFM32_USB_BASE+EFM32_USB_HC0_OFFSET) +#define EFM32_USB_HC1_BASE (EFM32_USB_BASE+EFM32_USB_HC1_OFFSET) +#define EFM32_USB_HC2_BASE (EFM32_USB_BASE+EFM32_USB_HC2_OFFSET) +#define EFM32_USB_HC3_BASE (EFM32_USB_BASE+EFM32_USB_HC3_OFFSET) +#define EFM32_USB_HC4_BASE (EFM32_USB_BASE+EFM32_USB_HC4_OFFSET) +#define EFM32_USB_HC5_BASE (EFM32_USB_BASE+EFM32_USB_HC5_OFFSET) +#define EFM32_USB_HC6_BASE (EFM32_USB_BASE+EFM32_USB_HC6_OFFSET) +#define EFM32_USB_HC7_BASE (EFM32_USB_BASE+EFM32_USB_HC7_OFFSET) +#define EFM32_USB_HC8_BASE (EFM32_USB_BASE+EFM32_USB_HC8_OFFSET) +#define EFM32_USB_HC9_BASE (EFM32_USB_BASE+EFM32_USB_HC9_OFFSET) +#define EFM32_USB_HC10_BASE (EFM32_USB_BASE+EFM32_USB_HC10_OFFSET) +#define EFM32_USB_HC11_BASE (EFM32_USB_BASE+EFM32_USB_HC11_OFFSET) +#define EFM32_USB_HC12_BASE (EFM32_USB_BASE+EFM32_USB_HC12_OFFSET) +#define EFM32_USB_HC13_BASE (EFM32_USB_BASE+EFM32_USB_HC13_OFFSET) + +#define EFM32_USB_HCn_CHAR(n) (EFM32_USB_HCn_BASE(n)+EFM32_USB_HCn_CHAR_OFFSET) +#define EFM32_USB_HCn_INT(n) (EFM32_USB_HCn_BASE(n)+EFM32_USB_HCn_INT_OFFSET) +#define EFM32_USB_HCn_INTMSK(n) (EFM32_USB_HCn_BASE(n)+EFM32_USB_HCn_INTMSK_OFFSET) +#define EFM32_USB_HCn_TSIZ(n) (EFM32_USB_HCn_BASE(n)+EFM32_USB_HCn_TSIZ_OFFSET) +#define EFM32_USB_HCn_DMAADDR(n) (EFM32_USB_HCn_BASE(n)+EFM32_USB_HCn_DMAADDR_OFFSET) + +#define EFM32_USB_DCFG (EFM32_USB_BASE+EFM32_USB_DCFG_OFFSET) +#define EFM32_USB_DCTL (EFM32_USB_BASE+EFM32_USB_DCTL_OFFSET) +#define EFM32_USB_DSTS (EFM32_USB_BASE+EFM32_USB_DSTS_OFFSET) +#define EFM32_USB_DIEPMSK (EFM32_USB_BASE+EFM32_USB_DIEPMSK_OFFSET) +#define EFM32_USB_DOEPMSK (EFM32_USB_BASE+EFM32_USB_DOEPMSK_OFFSET) +#define EFM32_USB_DAINT (EFM32_USB_BASE+EFM32_USB_DAINT_OFFSET) +#define EFM32_USB_DAINTMSK (EFM32_USB_BASE+EFM32_USB_DAINTMSK_OFFSET) +#define EFM32_USB_DVBUSDIS (EFM32_USB_BASE+EFM32_USB_DVBUSDIS_OFFSET) +#define EFM32_USB_DVBUSPULSE (EFM32_USB_BASE+EFM32_USB_DVBUSPULSE_OFFSET) +#define EFM32_USB_DIEPEMPMSK (EFM32_USB_BASE+EFM32_USB_DIEPEMPMSK_OFFSET) + +#define EFM32_USB_DIEP_BASE(n) (EFM32_USB_BASE+EFM32_USB_DIEP_OFFSET(n)) +#define EFM32_USB_DIEP0_BASE (EFM32_USB_BASE+EFM32_USB_DIEP0_OFFSET) +#define EFM32_USB_DIEP1_BASE (EFM32_USB_BASE+EFM32_USB_DIEP1_OFFSET) +#define EFM32_USB_DIEP2_BASE (EFM32_USB_BASE+EFM32_USB_DIEP2_OFFSET) +#define EFM32_USB_DIEP3_BASE (EFM32_USB_BASE+EFM32_USB_DIEP3_OFFSET) +#define EFM32_USB_DIEP4_BASE (EFM32_USB_BASE+EFM32_USB_DIEP4_OFFSET) +#define EFM32_USB_DIEP5_BASE (EFM32_USB_BASE+EFM32_USB_DIEP5_OFFSET) +#define EFM32_USB_DIEP6_BASE (EFM32_USB_BASE+EFM32_USB_DIEP6_OFFSET) + +#define EFM32_USB_DIEPCTL(n) (EFM32_USB_DIEP_BASE(n)+EFM32_USB_DIEPnCTL_OFFSET) +#define EFM32_USB_DIEPINT(n) (EFM32_USB_DIEP_BASE(n)+EFM32_USB_DIEPnINT_OFFSET) +#define EFM32_USB_DIEPTSIZ(n) (EFM32_USB_DIEP_BASE(n)+EFM32_USB_DIEPnTSIZ_OFFSET) +#define EFM32_USB_DIEPDMAADDR(n) (EFM32_USB_DIEP_BASE(n)+EFM32_USB_DIEPnDMAADDR_OFFSET) +#define EFM32_USB_DIEPTXFSTS(n) (EFM32_USB_DIEP_BASE(n)+EFM32_USB_DIEPnTXFSTS_OFFSET) + +#define EFM32_USB_DIEP0CTL (EFM32_USB_BASE+EFM32_USB_DIEP0CTL_OFFSET) +#define EFM32_USB_DIEP0INT (EFM32_USB_BASE+EFM32_USB_DIEP0INT_OFFSET) +#define EFM32_USB_DIEP0TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP0TSIZ_OFFSET) +#define EFM32_USB_DIEP0DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP0DMAADDR_OFFSET) +#define EFM32_USB_DIEP0TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP0TXFSTS_OFFSET) + +#define EFM32_USB_DIEP1CTL (EFM32_USB_BASE+EFM32_USB_DIEP1CTL_OFFSET) +#define EFM32_USB_DIEP1INT (EFM32_USB_BASE+EFM32_USB_DIEP1INT_OFFSET) +#define EFM32_USB_DIEP1TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP1TSIZ_OFFSET) +#define EFM32_USB_DIEP1DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP1DMAADDR_OFFSET) +#define EFM32_USB_DIEP1TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP1TXFSTS_OFFSET) + +#define EFM32_USB_DIEP2CTL (EFM32_USB_BASE+EFM32_USB_DIEP2CTL_OFFSET) +#define EFM32_USB_DIEP2INT (EFM32_USB_BASE+EFM32_USB_DIEP2INT_OFFSET) +#define EFM32_USB_DIEP2TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP2TSIZ_OFFSET) +#define EFM32_USB_DIEP2DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP2DMAADDR_OFFSET) +#define EFM32_USB_DIEP2TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP2TXFSTS_OFFSET) + +#define EFM32_USB_DIEP3CTL (EFM32_USB_BASE+EFM32_USB_DIEP3CTL_OFFSET) +#define EFM32_USB_DIEP3INT (EFM32_USB_BASE+EFM32_USB_DIEP3INT_OFFSET) +#define EFM32_USB_DIEP3TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP3TSIZ_OFFSET) +#define EFM32_USB_DIEP3DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP3DMAADDR_OFFSET) +#define EFM32_USB_DIEP3_TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP3TXFSTS_OFFSET) + +#define EFM32_USB_DIEP4CTL (EFM32_USB_BASE+EFM32_USB_DIEP4CTL_OFFSET) +#define EFM32_USB_DIEP4INT (EFM32_USB_BASE+EFM32_USB_DIEP4INT_OFFSET) +#define EFM32_USB_DIEP4TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP4TSIZ_OFFSET) +#define EFM32_USB_DIEP4DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP4DMAADDR_OFFSET) +#define EFM32_USB_DIEP4TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP4TXFSTS_OFFSET) + +#define EFM32_USB_DIEP5CTL (EFM32_USB_BASE+EFM32_USB_DIEP5CTL_OFFSET) +#define EFM32_USB_DIEP5INT (EFM32_USB_BASE+EFM32_USB_DIEP5INT_OFFSET) +#define EFM32_USB_DIEP5TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP5TSIZ_OFFSET) +#define EFM32_USB_DIEP5DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP5DMAADDR_OFFSET) +#define EFM32_USB_DIEP5_TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP5TXFSTS_OFFSET) + +#define EFM32_USB_DIEP6CTL (EFM32_USB_BASE+EFM32_USB_DIEP6_CTL_OFFSET) +#define EFM32_USB_DIEP6INT (EFM32_USB_BASE+EFM32_USB_DIEP6_INT_OFFSET) +#define EFM32_USB_DIEP6TSIZ (EFM32_USB_BASE+EFM32_USB_DIEP6_TSIZ_OFFSET) +#define EFM32_USB_DIEP6DMAADDR (EFM32_USB_BASE+EFM32_USB_DIEP6_DMAADDR_OFFSET) +#define EFM32_USB_DIEP6TXFSTS (EFM32_USB_BASE+EFM32_USB_DIEP6_TXFSTS_OFFSET) + +#define EFM32_USB_DOEP_BASE(n) (EFM32_USB_BASE+EFM32_USB_DOEP_OFFSET(n)) +#define EFM32_USB_DOEP0_BASE (EFM32_USB_BASE+EFM32_USB_DOEP0_OFFSET) +#define EFM32_USB_DOEP1_BASE (EFM32_USB_BASE+EFM32_USB_DOEP1_OFFSET) +#define EFM32_USB_DOEP2_BASE (EFM32_USB_BASE+EFM32_USB_DOEP2_OFFSET) +#define EFM32_USB_DOEP3_BASE (EFM32_USB_BASE+EFM32_USB_DOEP3_OFFSET) +#define EFM32_USB_DOEP4_BASE (EFM32_USB_BASE+EFM32_USB_DOEP4_OFFSET) +#define EFM32_USB_DOEP5_BASE (EFM32_USB_BASE+EFM32_USB_DOEP5_OFFSET) +#define EFM32_USB_DOEP6_BASE (EFM32_USB_BASE+EFM32_USB_DOEP6_OFFSET) + +#define EFM32_USB_DOEPCTL(n) (EFM32_USB_DOEP_BASE(n)+EFM32_USB_DOEPnCTL_OFFSET) +#define EFM32_USB_DOEPINT(n) (EFM32_USB_DOEP_BASE(n)+EFM32_USB_DOEPnINT_OFFSET) +#define EFM32_USB_DOEPTSIZ(n) (EFM32_USB_DOEP_BASE(n)+EFM32_USB_DOEPnTSIZ_OFFSET) +#define EFM32_USB_DOEPDMAADDR(n) (EFM32_USB_DOEP_BASE(n)+EFM32_USB_DOEPnDMAADDR_OFFSET) + +#define EFM32_USB_DOEP0CTL (EFM32_USB_BASE+EFM32_USB_DOEP0CTL_OFFSET) +#define EFM32_USB_DOEP0INT (EFM32_USB_BASE+EFM32_USB_DOEP0INT_OFFSET) +#define EFM32_USB_DOEP0TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP0TSIZ_OFFSET) +#define EFM32_USB_DOEP0DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP0DMAADDR_OFFSET) + +#define EFM32_USB_DOEP1CTL (EFM32_USB_BASE+EFM32_USB_DOEP1CTL_OFFSET) +#define EFM32_USB_DOEP1INT (EFM32_USB_BASE+EFM32_USB_DOEP1INT_OFFSET) +#define EFM32_USB_DOEP1TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP1TSIZ_OFFSET) +#define EFM32_USB_DOEP1DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP1DMAADDR_OFFSET) + +#define EFM32_USB_DOEP2CTL (EFM32_USB_BASE+EFM32_USB_DOEP2CTL_OFFSET) +#define EFM32_USB_DOEP2INT (EFM32_USB_BASE+EFM32_USB_DOEP2INT_OFFSET) +#define EFM32_USB_DOEP2TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP2TSIZ_OFFSET) +#define EFM32_USB_DOEP2DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP2DMAADDR_OFFSET) + +#define EFM32_USB_DOEP3CTL (EFM32_USB_BASE+EFM32_USB_DOEP3CTL_OFFSET) +#define EFM32_USB_DOEP3INT (EFM32_USB_BASE+EFM32_USB_DOEP3INT_OFFSET) +#define EFM32_USB_DOEP3TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP3TSIZ_OFFSET) +#define EFM32_USB_DOEP3DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP3DMAADDR_OFFSET) + +#define EFM32_USB_DOEP4CTL (EFM32_USB_BASE+EFM32_USB_DOEP4CTL_OFFSET) +#define EFM32_USB_DOEP4INT (EFM32_USB_BASE+EFM32_USB_DOEP4INT_OFFSET) +#define EFM32_USB_DOEP4TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP4TSIZ_OFFSET) +#define EFM32_USB_DOEP4DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP4DMAADDR_OFFSET) + +#define EFM32_USB_DOEP5CTL (EFM32_USB_BASE+EFM32_USB_DOEP5CTL_OFFSET) +#define EFM32_USB_DOEP5INT (EFM32_USB_BASE+EFM32_USB_DOEP5INT_OFFSET) +#define EFM32_USB_DOEP5TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP5TSIZ_OFFSET) +#define EFM32_USB_DOEP5DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP5DMAADDR_OFFSET) + +#define EFM32_USB_DOEP6CTL (EFM32_USB_BASE+EFM32_USB_DOEP6CTL_OFFSET) +#define EFM32_USB_DOEP6INT (EFM32_USB_BASE+EFM32_USB_DOEP6INT_OFFSET) +#define EFM32_USB_DOEP6TSIZ (EFM32_USB_BASE+EFM32_USB_DOEP6TSIZ_OFFSET) +#define EFM32_USB_DOEP6DMAADDR (EFM32_USB_BASE+EFM32_USB_DOEP6DMAADDR_OFFSET) + +#define EFM32_USB_PCGCCTL (EFM32_USB_BASE+EFM32_USB_PCGCCTL_OFFSET) + +/* Device EP/Host Channel FIFOs */ + +#define EFM32_USB_FIFO_BASE(n) (EFM32_USB_BASE+EFM32_USB_FIFO_OFFSET(n)) +#define EFM32_USB_FIFO0_BASE (EFM32_USB_BASE+EFM32_USB_FIFO0_OFFSET) +#define EFM32_USB_FIFO1_BASE (EFM32_USB_BASE+EFM32_USB_FIFO1_OFFSET) +#define EFM32_USB_FIFO2_BASE (EFM32_USB_BASE+EFM32_USB_FIFO2_OFFSET) +#define EFM32_USB_FIFO3_BASE (EFM32_USB_BASE+EFM32_USB_FIFO3_OFFSET) +#define EFM32_USB_FIFO4_BASE (EFM32_USB_BASE+EFM32_USB_FIFO4_OFFSET) +#define EFM32_USB_FIFO5_BASE (EFM32_USB_BASE+EFM32_USB_FIFO5_OFFSET) +#define EFM32_USB_FIFO6_BASE (EFM32_USB_BASE+EFM32_USB_FIFO6_OFFSET) +#define EFM32_USB_FIFO7_BASE (EFM32_USB_BASE+EFM32_USB_FIFO7_OFFSET) +#define EFM32_USB_FIFO8_BASE (EFM32_USB_BASE+EFM32_USB_FIFO8_OFFSET) +#define EFM32_USB_FIFO9_BASE (EFM32_USB_BASE+EFM32_USB_FIFO9_OFFSET) +#define EFM32_USB_FIFO10_BASE (EFM32_USB_BASE+EFM32_USB_FIFO10_OFFSET) +#define EFM32_USB_FIFO11_BASE (EFM32_USB_BASE+EFM32_USB_FIFO11_OFFSET) +#define EFM32_USB_FIFO12_BASE (EFM32_USB_BASE+EFM32_USB_FIFO12_OFFSET) +#define EFM32_USB_FIFO13_BASE (EFM32_USB_BASE+EFM32_USB_FIFO13_OFFSET) + +#define EFM32_USB_FIFOD(n,d) (EFM32_USB_BASE+EFM32_USB_FIFOD_OFFSET(n,d)) +#define EFM32_FIFORAM(d) (EFM32_USB_BASE+EFM32_FIFORAM_OFFSET(d)) + +/* USB Register Bit Field Definitions ******************************************************************************************/ + +/* Bit fields for USB CTRL */ + +#define _USB_CTRL_RESETVALUE 0x00000000UL /* Default value for USB_CTRL */ +#define _USB_CTRL_MASK 0x03330003UL /* Mask for USB_CTRL */ + +#define USB_CTRL_VBUSENAP (0x1UL << 0) /* VBUSEN Active Polarity */ +#define _USB_CTRL_VBUSENAP_SHIFT 0 /* Shift value for USB_VBUSENAP */ +#define _USB_CTRL_VBUSENAP_MASK 0x1UL /* Bit mask for USB_VBUSENAP */ +#define _USB_CTRL_VBUSENAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define _USB_CTRL_VBUSENAP_LOW 0x00000000UL /* Mode LOW for USB_CTRL */ +#define _USB_CTRL_VBUSENAP_HIGH 0x00000001UL /* Mode HIGH for USB_CTRL */ +#define USB_CTRL_VBUSENAP_DEFAULT (_USB_CTRL_VBUSENAP_DEFAULT << 0) /* Shifted mode DEFAULT for USB_CTRL */ +#define USB_CTRL_VBUSENAP_LOW (_USB_CTRL_VBUSENAP_LOW << 0) /* Shifted mode LOW for USB_CTRL */ +#define USB_CTRL_VBUSENAP_HIGH (_USB_CTRL_VBUSENAP_HIGH << 0) /* Shifted mode HIGH for USB_CTRL */ +#define USB_CTRL_DMPUAP (0x1UL << 1) /* DMPU Active Polarity */ +#define _USB_CTRL_DMPUAP_SHIFT 1 /* Shift value for USB_DMPUAP */ +#define _USB_CTRL_DMPUAP_MASK 0x2UL /* Bit mask for USB_DMPUAP */ +#define _USB_CTRL_DMPUAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define _USB_CTRL_DMPUAP_LOW 0x00000000UL /* Mode LOW for USB_CTRL */ +#define _USB_CTRL_DMPUAP_HIGH 0x00000001UL /* Mode HIGH for USB_CTRL */ +#define USB_CTRL_DMPUAP_DEFAULT (_USB_CTRL_DMPUAP_DEFAULT << 1) /* Shifted mode DEFAULT for USB_CTRL */ +#define USB_CTRL_DMPUAP_LOW (_USB_CTRL_DMPUAP_LOW << 1) /* Shifted mode LOW for USB_CTRL */ +#define USB_CTRL_DMPUAP_HIGH (_USB_CTRL_DMPUAP_HIGH << 1) /* Shifted mode HIGH for USB_CTRL */ +#define USB_CTRL_VREGDIS (0x1UL << 16) /* Voltage Regulator Disable */ +#define _USB_CTRL_VREGDIS_SHIFT 16 /* Shift value for USB_VREGDIS */ +#define _USB_CTRL_VREGDIS_MASK 0x10000UL /* Bit mask for USB_VREGDIS */ +#define _USB_CTRL_VREGDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define USB_CTRL_VREGDIS_DEFAULT (_USB_CTRL_VREGDIS_DEFAULT << 16) /* Shifted mode DEFAULT for USB_CTRL */ +#define USB_CTRL_VREGOSEN (0x1UL << 17) /* VREGO Sense Enable */ +#define _USB_CTRL_VREGOSEN_SHIFT 17 /* Shift value for USB_VREGOSEN */ +#define _USB_CTRL_VREGOSEN_MASK 0x20000UL /* Bit mask for USB_VREGOSEN */ +#define _USB_CTRL_VREGOSEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define USB_CTRL_VREGOSEN_DEFAULT (_USB_CTRL_VREGOSEN_DEFAULT << 17) /* Shifted mode DEFAULT for USB_CTRL */ +#define _USB_CTRL_BIASPROGEM01_SHIFT 20 /* Shift value for USB_BIASPROGEM01 */ +#define _USB_CTRL_BIASPROGEM01_MASK 0x300000UL /* Bit mask for USB_BIASPROGEM01 */ +#define _USB_CTRL_BIASPROGEM01_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define USB_CTRL_BIASPROGEM01_DEFAULT (_USB_CTRL_BIASPROGEM01_DEFAULT << 20) /* Shifted mode DEFAULT for USB_CTRL */ +#define _USB_CTRL_BIASPROGEM23_SHIFT 24 /* Shift value for USB_BIASPROGEM23 */ +#define _USB_CTRL_BIASPROGEM23_MASK 0x3000000UL /* Bit mask for USB_BIASPROGEM23 */ +#define _USB_CTRL_BIASPROGEM23_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_CTRL */ +#define USB_CTRL_BIASPROGEM23_DEFAULT (_USB_CTRL_BIASPROGEM23_DEFAULT << 24) /* Shifted mode DEFAULT for USB_CTRL */ + +/* Bit fields for USB STATUS */ + +#define _USB_STATUS_RESETVALUE 0x00000000UL /* Default value for USB_STATUS */ +#define _USB_STATUS_MASK 0x00000001UL /* Mask for USB_STATUS */ + +#define USB_STATUS_VREGOS (0x1UL << 0) /* VREGO Sense Output */ +#define _USB_STATUS_VREGOS_SHIFT 0 /* Shift value for USB_VREGOS */ +#define _USB_STATUS_VREGOS_MASK 0x1UL /* Bit mask for USB_VREGOS */ +#define _USB_STATUS_VREGOS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_STATUS */ +#define USB_STATUS_VREGOS_DEFAULT (_USB_STATUS_VREGOS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_STATUS */ + +/* Bit fields for USB IF */ + +#define _USB_IF_RESETVALUE 0x00000003UL /* Default value for USB_IF */ +#define _USB_IF_MASK 0x00000003UL /* Mask for USB_IF */ + +#define USB_IF_VREGOSH (0x1UL << 0) /* VREGO Sense High Interrupt Flag */ +#define _USB_IF_VREGOSH_SHIFT 0 /* Shift value for USB_VREGOSH */ +#define _USB_IF_VREGOSH_MASK 0x1UL /* Bit mask for USB_VREGOSH */ +#define _USB_IF_VREGOSH_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_IF */ +#define USB_IF_VREGOSH_DEFAULT (_USB_IF_VREGOSH_DEFAULT << 0) /* Shifted mode DEFAULT for USB_IF */ +#define USB_IF_VREGOSL (0x1UL << 1) /* VREGO Sense Low Interrupt Flag */ +#define _USB_IF_VREGOSL_SHIFT 1 /* Shift value for USB_VREGOSL */ +#define _USB_IF_VREGOSL_MASK 0x2UL /* Bit mask for USB_VREGOSL */ +#define _USB_IF_VREGOSL_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_IF */ +#define USB_IF_VREGOSL_DEFAULT (_USB_IF_VREGOSL_DEFAULT << 1) /* Shifted mode DEFAULT for USB_IF */ + +/* Bit fields for USB IFS */ + +#define _USB_IFS_RESETVALUE 0x00000000UL /* Default value for USB_IFS */ +#define _USB_IFS_MASK 0x00000003UL /* Mask for USB_IFS */ + +#define USB_IFS_VREGOSH (0x1UL << 0) /* Set VREGO Sense High Interrupt Flag */ +#define _USB_IFS_VREGOSH_SHIFT 0 /* Shift value for USB_VREGOSH */ +#define _USB_IFS_VREGOSH_MASK 0x1UL /* Bit mask for USB_VREGOSH */ +#define _USB_IFS_VREGOSH_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IFS */ +#define USB_IFS_VREGOSH_DEFAULT (_USB_IFS_VREGOSH_DEFAULT << 0) /* Shifted mode DEFAULT for USB_IFS */ +#define USB_IFS_VREGOSL (0x1UL << 1) /* Set VREGO Sense Low Interrupt Flag */ +#define _USB_IFS_VREGOSL_SHIFT 1 /* Shift value for USB_VREGOSL */ +#define _USB_IFS_VREGOSL_MASK 0x2UL /* Bit mask for USB_VREGOSL */ +#define _USB_IFS_VREGOSL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IFS */ +#define USB_IFS_VREGOSL_DEFAULT (_USB_IFS_VREGOSL_DEFAULT << 1) /* Shifted mode DEFAULT for USB_IFS */ + +/* Bit fields for USB IFC */ + +#define _USB_IFC_RESETVALUE 0x00000000UL /* Default value for USB_IFC */ +#define _USB_IFC_MASK 0x00000003UL /* Mask for USB_IFC */ + +#define USB_IFC_VREGOSH (0x1UL << 0) /* Clear VREGO Sense High Interrupt Flag */ +#define _USB_IFC_VREGOSH_SHIFT 0 /* Shift value for USB_VREGOSH */ +#define _USB_IFC_VREGOSH_MASK 0x1UL /* Bit mask for USB_VREGOSH */ +#define _USB_IFC_VREGOSH_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IFC */ +#define USB_IFC_VREGOSH_DEFAULT (_USB_IFC_VREGOSH_DEFAULT << 0) /* Shifted mode DEFAULT for USB_IFC */ +#define USB_IFC_VREGOSL (0x1UL << 1) /* Clear VREGO Sense Low Interrupt Flag */ +#define _USB_IFC_VREGOSL_SHIFT 1 /* Shift value for USB_VREGOSL */ +#define _USB_IFC_VREGOSL_MASK 0x2UL /* Bit mask for USB_VREGOSL */ +#define _USB_IFC_VREGOSL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IFC */ +#define USB_IFC_VREGOSL_DEFAULT (_USB_IFC_VREGOSL_DEFAULT << 1) /* Shifted mode DEFAULT for USB_IFC */ + +/* Bit fields for USB IEN */ + +#define _USB_IEN_RESETVALUE 0x00000000UL /* Default value for USB_IEN */ +#define _USB_IEN_MASK 0x00000003UL /* Mask for USB_IEN */ + +#define USB_IEN_VREGOSH (0x1UL << 0) /* VREGO Sense High Interrupt Enable */ +#define _USB_IEN_VREGOSH_SHIFT 0 /* Shift value for USB_VREGOSH */ +#define _USB_IEN_VREGOSH_MASK 0x1UL /* Bit mask for USB_VREGOSH */ +#define _USB_IEN_VREGOSH_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IEN */ +#define USB_IEN_VREGOSH_DEFAULT (_USB_IEN_VREGOSH_DEFAULT << 0) /* Shifted mode DEFAULT for USB_IEN */ +#define USB_IEN_VREGOSL (0x1UL << 1) /* VREGO Sense Low Interrupt Enable */ +#define _USB_IEN_VREGOSL_SHIFT 1 /* Shift value for USB_VREGOSL */ +#define _USB_IEN_VREGOSL_MASK 0x2UL /* Bit mask for USB_VREGOSL */ +#define _USB_IEN_VREGOSL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_IEN */ +#define USB_IEN_VREGOSL_DEFAULT (_USB_IEN_VREGOSL_DEFAULT << 1) /* Shifted mode DEFAULT for USB_IEN */ + +/* Bit fields for USB ROUTE */ + +#define _USB_ROUTE_RESETVALUE 0x00000000UL /* Default value for USB_ROUTE */ +#define _USB_ROUTE_MASK 0x00000007UL /* Mask for USB_ROUTE */ + +#define USB_ROUTE_PHYPEN (0x1UL << 0) /* USB PHY Pin Enable */ +#define _USB_ROUTE_PHYPEN_SHIFT 0 /* Shift value for USB_PHYPEN */ +#define _USB_ROUTE_PHYPEN_MASK 0x1UL /* Bit mask for USB_PHYPEN */ +#define _USB_ROUTE_PHYPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_ROUTE */ +#define USB_ROUTE_PHYPEN_DEFAULT (_USB_ROUTE_PHYPEN_DEFAULT << 0) /* Shifted mode DEFAULT for USB_ROUTE */ +#define USB_ROUTE_VBUSENPEN (0x1UL << 1) /* VBUSEN Pin Enable */ +#define _USB_ROUTE_VBUSENPEN_SHIFT 1 /* Shift value for USB_VBUSENPEN */ +#define _USB_ROUTE_VBUSENPEN_MASK 0x2UL /* Bit mask for USB_VBUSENPEN */ +#define _USB_ROUTE_VBUSENPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_ROUTE */ +#define USB_ROUTE_VBUSENPEN_DEFAULT (_USB_ROUTE_VBUSENPEN_DEFAULT << 1) /* Shifted mode DEFAULT for USB_ROUTE */ +#define USB_ROUTE_DMPUPEN (0x1UL << 2) /* DMPU Pin Enable */ +#define _USB_ROUTE_DMPUPEN_SHIFT 2 /* Shift value for USB_DMPUPEN */ +#define _USB_ROUTE_DMPUPEN_MASK 0x4UL /* Bit mask for USB_DMPUPEN */ +#define _USB_ROUTE_DMPUPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_ROUTE */ +#define USB_ROUTE_DMPUPEN_DEFAULT (_USB_ROUTE_DMPUPEN_DEFAULT << 2) /* Shifted mode DEFAULT for USB_ROUTE */ + +/* Bit fields for USB GOTGCTL */ + +#define _USB_GOTGCTL_RESETVALUE 0x00010000UL /* Default value for USB_GOTGCTL */ +#define _USB_GOTGCTL_MASK 0x001F0FFFUL /* Mask for USB_GOTGCTL */ + +#define USB_GOTGCTL_SESREQSCS (0x1UL << 0) /* Session Request Success (device only) */ +#define _USB_GOTGCTL_SESREQSCS_SHIFT 0 /* Shift value for USB_SESREQSCS */ +#define _USB_GOTGCTL_SESREQSCS_MASK 0x1UL /* Bit mask for USB_SESREQSCS */ +#define _USB_GOTGCTL_SESREQSCS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_SESREQSCS_DEFAULT (_USB_GOTGCTL_SESREQSCS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_SESREQ (0x1UL << 1) /* Session Request (device only) */ +#define _USB_GOTGCTL_SESREQ_SHIFT 1 /* Shift value for USB_SESREQ */ +#define _USB_GOTGCTL_SESREQ_MASK 0x2UL /* Bit mask for USB_SESREQ */ +#define _USB_GOTGCTL_SESREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_SESREQ_DEFAULT (_USB_GOTGCTL_SESREQ_DEFAULT << 1) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_VBVALIDOVEN (0x1UL << 2) /* VBUS-Valid Override Enable */ +#define _USB_GOTGCTL_VBVALIDOVEN_SHIFT 2 /* Shift value for USB_VBVALIDOVEN */ +#define _USB_GOTGCTL_VBVALIDOVEN_MASK 0x4UL /* Bit mask for USB_VBVALIDOVEN */ +#define _USB_GOTGCTL_VBVALIDOVEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_VBVALIDOVEN_DEFAULT (_USB_GOTGCTL_VBVALIDOVEN_DEFAULT << 2) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_VBVALIDOVVAL (0x1UL << 3) /* VBUS Valid Override Value */ +#define _USB_GOTGCTL_VBVALIDOVVAL_SHIFT 3 /* Shift value for USB_VBVALIDOVVAL */ +#define _USB_GOTGCTL_VBVALIDOVVAL_MASK 0x8UL /* Bit mask for USB_VBVALIDOVVAL */ +#define _USB_GOTGCTL_VBVALIDOVVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_VBVALIDOVVAL_DEFAULT (_USB_GOTGCTL_VBVALIDOVVAL_DEFAULT << 3) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BVALIDOVEN (0x1UL << 4) /* BValid Override Enable */ +#define _USB_GOTGCTL_BVALIDOVEN_SHIFT 4 /* Shift value for USB_BVALIDOVEN */ +#define _USB_GOTGCTL_BVALIDOVEN_MASK 0x10UL /* Bit mask for USB_BVALIDOVEN */ +#define _USB_GOTGCTL_BVALIDOVEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BVALIDOVEN_DEFAULT (_USB_GOTGCTL_BVALIDOVEN_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BVALIDOVVAL (0x1UL << 5) /* Bvalid Override Value */ +#define _USB_GOTGCTL_BVALIDOVVAL_SHIFT 5 /* Shift value for USB_BVALIDOVVAL */ +#define _USB_GOTGCTL_BVALIDOVVAL_MASK 0x20UL /* Bit mask for USB_BVALIDOVVAL */ +#define _USB_GOTGCTL_BVALIDOVVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BVALIDOVVAL_DEFAULT (_USB_GOTGCTL_BVALIDOVVAL_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_AVALIDOVEN (0x1UL << 6) /* AValid Override Enable */ +#define _USB_GOTGCTL_AVALIDOVEN_SHIFT 6 /* Shift value for USB_AVALIDOVEN */ +#define _USB_GOTGCTL_AVALIDOVEN_MASK 0x40UL /* Bit mask for USB_AVALIDOVEN */ +#define _USB_GOTGCTL_AVALIDOVEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_AVALIDOVEN_DEFAULT (_USB_GOTGCTL_AVALIDOVEN_DEFAULT << 6) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_AVALIDOVVAL (0x1UL << 7) /* Avalid Override Value */ +#define _USB_GOTGCTL_AVALIDOVVAL_SHIFT 7 /* Shift value for USB_AVALIDOVVAL */ +#define _USB_GOTGCTL_AVALIDOVVAL_MASK 0x80UL /* Bit mask for USB_AVALIDOVVAL */ +#define _USB_GOTGCTL_AVALIDOVVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_AVALIDOVVAL_DEFAULT (_USB_GOTGCTL_AVALIDOVVAL_DEFAULT << 7) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HSTNEGSCS (0x1UL << 8) /* Host Negotiation Success (device only) */ +#define _USB_GOTGCTL_HSTNEGSCS_SHIFT 8 /* Shift value for USB_HSTNEGSCS */ +#define _USB_GOTGCTL_HSTNEGSCS_MASK 0x100UL /* Bit mask for USB_HSTNEGSCS */ +#define _USB_GOTGCTL_HSTNEGSCS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HSTNEGSCS_DEFAULT (_USB_GOTGCTL_HSTNEGSCS_DEFAULT << 8) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HNPREQ (0x1UL << 9) /* HNP Request (device only) */ +#define _USB_GOTGCTL_HNPREQ_SHIFT 9 /* Shift value for USB_HNPREQ */ +#define _USB_GOTGCTL_HNPREQ_MASK 0x200UL /* Bit mask for USB_HNPREQ */ +#define _USB_GOTGCTL_HNPREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HNPREQ_DEFAULT (_USB_GOTGCTL_HNPREQ_DEFAULT << 9) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HSTSETHNPEN (0x1UL << 10) /* Host Set HNP Enable (host only) */ +#define _USB_GOTGCTL_HSTSETHNPEN_SHIFT 10 /* Shift value for USB_HSTSETHNPEN */ +#define _USB_GOTGCTL_HSTSETHNPEN_MASK 0x400UL /* Bit mask for USB_HSTSETHNPEN */ +#define _USB_GOTGCTL_HSTSETHNPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_HSTSETHNPEN_DEFAULT (_USB_GOTGCTL_HSTSETHNPEN_DEFAULT << 10) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_DEVHNPEN (0x1UL << 11) /* Device HNP Enabled (device only) */ +#define _USB_GOTGCTL_DEVHNPEN_SHIFT 11 /* Shift value for USB_DEVHNPEN */ +#define _USB_GOTGCTL_DEVHNPEN_MASK 0x800UL /* Bit mask for USB_DEVHNPEN */ +#define _USB_GOTGCTL_DEVHNPEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_DEVHNPEN_DEFAULT (_USB_GOTGCTL_DEVHNPEN_DEFAULT << 11) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_CONIDSTS (0x1UL << 16) /* Connector ID Status (host and device) */ +#define _USB_GOTGCTL_CONIDSTS_SHIFT 16 /* Shift value for USB_CONIDSTS */ +#define _USB_GOTGCTL_CONIDSTS_MASK 0x10000UL /* Bit mask for USB_CONIDSTS */ +#define _USB_GOTGCTL_CONIDSTS_A 0x00000000UL /* Mode A for USB_GOTGCTL */ +#define _USB_GOTGCTL_CONIDSTS_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_GOTGCTL */ +#define _USB_GOTGCTL_CONIDSTS_B 0x00000001UL /* Mode B for USB_GOTGCTL */ +#define USB_GOTGCTL_CONIDSTS_A (_USB_GOTGCTL_CONIDSTS_A << 16) /* Shifted mode A for USB_GOTGCTL */ +#define USB_GOTGCTL_CONIDSTS_DEFAULT (_USB_GOTGCTL_CONIDSTS_DEFAULT << 16) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_CONIDSTS_B (_USB_GOTGCTL_CONIDSTS_B << 16) /* Shifted mode B for USB_GOTGCTL */ +#define USB_GOTGCTL_DBNCTIME (0x1UL << 17) /* Long/Short Debounce Time (host only) */ +#define _USB_GOTGCTL_DBNCTIME_SHIFT 17 /* Shift value for USB_DBNCTIME */ +#define _USB_GOTGCTL_DBNCTIME_MASK 0x20000UL /* Bit mask for USB_DBNCTIME */ +#define _USB_GOTGCTL_DBNCTIME_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define _USB_GOTGCTL_DBNCTIME_LONG 0x00000000UL /* Mode LONG for USB_GOTGCTL */ +#define _USB_GOTGCTL_DBNCTIME_SHORT 0x00000001UL /* Mode SHORT for USB_GOTGCTL */ +#define USB_GOTGCTL_DBNCTIME_DEFAULT (_USB_GOTGCTL_DBNCTIME_DEFAULT << 17) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_DBNCTIME_LONG (_USB_GOTGCTL_DBNCTIME_LONG << 17) /* Shifted mode LONG for USB_GOTGCTL */ +#define USB_GOTGCTL_DBNCTIME_SHORT (_USB_GOTGCTL_DBNCTIME_SHORT << 17) /* Shifted mode SHORT for USB_GOTGCTL */ +#define USB_GOTGCTL_ASESVLD (0x1UL << 18) /* A-Session Valid (host only) */ +#define _USB_GOTGCTL_ASESVLD_SHIFT 18 /* Shift value for USB_ASESVLD */ +#define _USB_GOTGCTL_ASESVLD_MASK 0x40000UL /* Bit mask for USB_ASESVLD */ +#define _USB_GOTGCTL_ASESVLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_ASESVLD_DEFAULT (_USB_GOTGCTL_ASESVLD_DEFAULT << 18) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BSESVLD (0x1UL << 19) /* B-Session Valid (device only) */ +#define _USB_GOTGCTL_BSESVLD_SHIFT 19 /* Shift value for USB_BSESVLD */ +#define _USB_GOTGCTL_BSESVLD_MASK 0x80000UL /* Bit mask for USB_BSESVLD */ +#define _USB_GOTGCTL_BSESVLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_BSESVLD_DEFAULT (_USB_GOTGCTL_BSESVLD_DEFAULT << 19) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_OTGVER (0x1UL << 20) /* OTG Version */ +#define _USB_GOTGCTL_OTGVER_SHIFT 20 /* Shift value for USB_OTGVER */ +#define _USB_GOTGCTL_OTGVER_MASK 0x100000UL /* Bit mask for USB_OTGVER */ +#define _USB_GOTGCTL_OTGVER_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGCTL */ +#define _USB_GOTGCTL_OTGVER_OTG13 0x00000000UL /* Mode OTG13 for USB_GOTGCTL */ +#define _USB_GOTGCTL_OTGVER_OTG20 0x00000001UL /* Mode OTG20 for USB_GOTGCTL */ +#define USB_GOTGCTL_OTGVER_DEFAULT (_USB_GOTGCTL_OTGVER_DEFAULT << 20) /* Shifted mode DEFAULT for USB_GOTGCTL */ +#define USB_GOTGCTL_OTGVER_OTG13 (_USB_GOTGCTL_OTGVER_OTG13 << 20) /* Shifted mode OTG13 for USB_GOTGCTL */ +#define USB_GOTGCTL_OTGVER_OTG20 (_USB_GOTGCTL_OTGVER_OTG20 << 20) /* Shifted mode OTG20 for USB_GOTGCTL */ + +/* Bit fields for USB GOTGINT */ + +#define _USB_GOTGINT_RESETVALUE 0x00000000UL /* Default value for USB_GOTGINT */ +#define _USB_GOTGINT_MASK 0x000E0304UL /* Mask for USB_GOTGINT */ + +#define USB_GOTGINT_SESENDDET (0x1UL << 2) /* Session End Detected (host and device) */ +#define _USB_GOTGINT_SESENDDET_SHIFT 2 /* Shift value for USB_SESENDDET */ +#define _USB_GOTGINT_SESENDDET_MASK 0x4UL /* Bit mask for USB_SESENDDET */ +#define _USB_GOTGINT_SESENDDET_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_SESENDDET_DEFAULT (_USB_GOTGINT_SESENDDET_DEFAULT << 2) /* Shifted mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_SESREQSUCSTSCHNG (0x1UL << 8) /* Session Request Success Status Change (host and device) */ +#define _USB_GOTGINT_SESREQSUCSTSCHNG_SHIFT 8 /* Shift value for USB_SESREQSUCSTSCHNG */ +#define _USB_GOTGINT_SESREQSUCSTSCHNG_MASK 0x100UL /* Bit mask for USB_SESREQSUCSTSCHNG */ +#define _USB_GOTGINT_SESREQSUCSTSCHNG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_SESREQSUCSTSCHNG_DEFAULT (_USB_GOTGINT_SESREQSUCSTSCHNG_DEFAULT << 8) /* Shifted mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_HSTNEGSUCSTSCHNG (0x1UL << 9) /* Host Negotiation Success Status Change (host and device) */ +#define _USB_GOTGINT_HSTNEGSUCSTSCHNG_SHIFT 9 /* Shift value for USB_HSTNEGSUCSTSCHNG */ +#define _USB_GOTGINT_HSTNEGSUCSTSCHNG_MASK 0x200UL /* Bit mask for USB_HSTNEGSUCSTSCHNG */ +#define _USB_GOTGINT_HSTNEGSUCSTSCHNG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_HSTNEGSUCSTSCHNG_DEFAULT (_USB_GOTGINT_HSTNEGSUCSTSCHNG_DEFAULT << 9) /* Shifted mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_HSTNEGDET (0x1UL << 17) /* Host Negotiation Detected (host and device) */ +#define _USB_GOTGINT_HSTNEGDET_SHIFT 17 /* Shift value for USB_HSTNEGDET */ +#define _USB_GOTGINT_HSTNEGDET_MASK 0x20000UL /* Bit mask for USB_HSTNEGDET */ +#define _USB_GOTGINT_HSTNEGDET_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_HSTNEGDET_DEFAULT (_USB_GOTGINT_HSTNEGDET_DEFAULT << 17) /* Shifted mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_ADEVTOUTCHG (0x1UL << 18) /* A-Device Timeout Change (host and device) */ +#define _USB_GOTGINT_ADEVTOUTCHG_SHIFT 18 /* Shift value for USB_ADEVTOUTCHG */ +#define _USB_GOTGINT_ADEVTOUTCHG_MASK 0x40000UL /* Bit mask for USB_ADEVTOUTCHG */ +#define _USB_GOTGINT_ADEVTOUTCHG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_ADEVTOUTCHG_DEFAULT (_USB_GOTGINT_ADEVTOUTCHG_DEFAULT << 18) /* Shifted mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_DBNCEDONE (0x1UL << 19) /* Debounce Done (host only) */ +#define _USB_GOTGINT_DBNCEDONE_SHIFT 19 /* Shift value for USB_DBNCEDONE */ +#define _USB_GOTGINT_DBNCEDONE_MASK 0x80000UL /* Bit mask for USB_DBNCEDONE */ +#define _USB_GOTGINT_DBNCEDONE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GOTGINT */ +#define USB_GOTGINT_DBNCEDONE_DEFAULT (_USB_GOTGINT_DBNCEDONE_DEFAULT << 19) /* Shifted mode DEFAULT for USB_GOTGINT */ + +/* Bit fields for USB GAHBCFG */ + +#define _USB_GAHBCFG_RESETVALUE 0x00000000UL /* Default value for USB_GAHBCFG */ +#define _USB_GAHBCFG_MASK 0x006001BFUL /* Mask for USB_GAHBCFG */ + +#define USB_GAHBCFG_GLBLINTRMSK (0x1UL << 0) /* Global Interrupt Mask (host and device) */ +#define _USB_GAHBCFG_GLBLINTRMSK_SHIFT 0 /* Shift value for USB_GLBLINTRMSK */ +#define _USB_GAHBCFG_GLBLINTRMSK_MASK 0x1UL /* Bit mask for USB_GLBLINTRMSK */ +#define _USB_GAHBCFG_GLBLINTRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_GLBLINTRMSK_DEFAULT (_USB_GAHBCFG_GLBLINTRMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_SHIFT 1 /* Shift value for USB_HBSTLEN */ +#define _USB_GAHBCFG_HBSTLEN_MASK 0x1EUL /* Bit mask for USB_HBSTLEN */ +#define _USB_GAHBCFG_HBSTLEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_SINGLE 0x00000000UL /* Mode SINGLE for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_INCR 0x00000001UL /* Mode INCR for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_INCR4 0x00000003UL /* Mode INCR4 for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_INCR8 0x00000005UL /* Mode INCR8 for USB_GAHBCFG */ +#define _USB_GAHBCFG_HBSTLEN_INCR16 0x00000007UL /* Mode INCR16 for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_DEFAULT (_USB_GAHBCFG_HBSTLEN_DEFAULT << 1) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_SINGLE (_USB_GAHBCFG_HBSTLEN_SINGLE << 1) /* Shifted mode SINGLE for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_INCR (_USB_GAHBCFG_HBSTLEN_INCR << 1) /* Shifted mode INCR for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_INCR4 (_USB_GAHBCFG_HBSTLEN_INCR4 << 1) /* Shifted mode INCR4 for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_INCR8 (_USB_GAHBCFG_HBSTLEN_INCR8 << 1) /* Shifted mode INCR8 for USB_GAHBCFG */ +#define USB_GAHBCFG_HBSTLEN_INCR16 (_USB_GAHBCFG_HBSTLEN_INCR16 << 1) /* Shifted mode INCR16 for USB_GAHBCFG */ +#define USB_GAHBCFG_DMAEN (0x1UL << 5) /* DMA Enable (host and device) */ +#define _USB_GAHBCFG_DMAEN_SHIFT 5 /* Shift value for USB_DMAEN */ +#define _USB_GAHBCFG_DMAEN_MASK 0x20UL /* Bit mask for USB_DMAEN */ +#define _USB_GAHBCFG_DMAEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_DMAEN_DEFAULT (_USB_GAHBCFG_DMAEN_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_NPTXFEMPLVL (0x1UL << 7) /* Non-Periodic TxFIFO Empty Level (host and device) */ +#define _USB_GAHBCFG_NPTXFEMPLVL_SHIFT 7 /* Shift value for USB_NPTXFEMPLVL */ +#define _USB_GAHBCFG_NPTXFEMPLVL_MASK 0x80UL /* Bit mask for USB_NPTXFEMPLVL */ +#define _USB_GAHBCFG_NPTXFEMPLVL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define _USB_GAHBCFG_NPTXFEMPLVL_HALFEMPTY 0x00000000UL /* Mode HALFEMPTY for USB_GAHBCFG */ +#define _USB_GAHBCFG_NPTXFEMPLVL_EMPTY 0x00000001UL /* Mode EMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_NPTXFEMPLVL_DEFAULT (_USB_GAHBCFG_NPTXFEMPLVL_DEFAULT << 7) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_NPTXFEMPLVL_HALFEMPTY (_USB_GAHBCFG_NPTXFEMPLVL_HALFEMPTY << 7) /* Shifted mode HALFEMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_NPTXFEMPLVL_EMPTY (_USB_GAHBCFG_NPTXFEMPLVL_EMPTY << 7) /* Shifted mode EMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_PTXFEMPLVL (0x1UL << 8) /* Periodic TxFIFO Empty Level (host only) */ +#define _USB_GAHBCFG_PTXFEMPLVL_SHIFT 8 /* Shift value for USB_PTXFEMPLVL */ +#define _USB_GAHBCFG_PTXFEMPLVL_MASK 0x100UL /* Bit mask for USB_PTXFEMPLVL */ +#define _USB_GAHBCFG_PTXFEMPLVL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define _USB_GAHBCFG_PTXFEMPLVL_HALFEMPTY 0x00000000UL /* Mode HALFEMPTY for USB_GAHBCFG */ +#define _USB_GAHBCFG_PTXFEMPLVL_EMPTY 0x00000001UL /* Mode EMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_PTXFEMPLVL_DEFAULT (_USB_GAHBCFG_PTXFEMPLVL_DEFAULT << 8) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_PTXFEMPLVL_HALFEMPTY (_USB_GAHBCFG_PTXFEMPLVL_HALFEMPTY << 8) /* Shifted mode HALFEMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_PTXFEMPLVL_EMPTY (_USB_GAHBCFG_PTXFEMPLVL_EMPTY << 8) /* Shifted mode EMPTY for USB_GAHBCFG */ +#define USB_GAHBCFG_REMMEMSUPP (0x1UL << 21) /* Remote Memory Support */ +#define _USB_GAHBCFG_REMMEMSUPP_SHIFT 21 /* Shift value for USB_REMMEMSUPP */ +#define _USB_GAHBCFG_REMMEMSUPP_MASK 0x200000UL /* Bit mask for USB_REMMEMSUPP */ +#define _USB_GAHBCFG_REMMEMSUPP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_REMMEMSUPP_DEFAULT (_USB_GAHBCFG_REMMEMSUPP_DEFAULT << 21) /* Shifted mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_NOTIALLDMAWRIT (0x1UL << 22) /* Notify All DMA Writes */ +#define _USB_GAHBCFG_NOTIALLDMAWRIT_SHIFT 22 /* Shift value for USB_NOTIALLDMAWRIT */ +#define _USB_GAHBCFG_NOTIALLDMAWRIT_MASK 0x400000UL /* Bit mask for USB_NOTIALLDMAWRIT */ +#define _USB_GAHBCFG_NOTIALLDMAWRIT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GAHBCFG */ +#define USB_GAHBCFG_NOTIALLDMAWRIT_DEFAULT (_USB_GAHBCFG_NOTIALLDMAWRIT_DEFAULT << 22) /* Shifted mode DEFAULT for USB_GAHBCFG */ + +/* Bit fields for USB GUSBCFG */ + +#define _USB_GUSBCFG_RESETVALUE 0x00001440UL /* Default value for USB_GUSBCFG */ +#define _USB_GUSBCFG_MASK 0xF0403F27UL /* Mask for USB_GUSBCFG */ + +#define _USB_GUSBCFG_TOUTCAL_SHIFT 0 /* Shift value for USB_TOUTCAL */ +#define _USB_GUSBCFG_TOUTCAL_MASK 0x7UL /* Bit mask for USB_TOUTCAL */ +#define _USB_GUSBCFG_TOUTCAL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_TOUTCAL_DEFAULT (_USB_GUSBCFG_TOUTCAL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FSINTF (0x1UL << 5) /* Full-Speed Serial Interface Select (host and device) */ +#define _USB_GUSBCFG_FSINTF_SHIFT 5 /* Shift value for USB_FSINTF */ +#define _USB_GUSBCFG_FSINTF_MASK 0x20UL /* Bit mask for USB_FSINTF */ +#define _USB_GUSBCFG_FSINTF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FSINTF_DEFAULT (_USB_GUSBCFG_FSINTF_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_SRPCAP (0x1UL << 8) /* SRP-Capable (host and device) */ +#define _USB_GUSBCFG_SRPCAP_SHIFT 8 /* Shift value for USB_SRPCAP */ +#define _USB_GUSBCFG_SRPCAP_MASK 0x100UL /* Bit mask for USB_SRPCAP */ +#define _USB_GUSBCFG_SRPCAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_SRPCAP_DEFAULT (_USB_GUSBCFG_SRPCAP_DEFAULT << 8) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_HNPCAP (0x1UL << 9) /* HNP-Capable (host and device) */ +#define _USB_GUSBCFG_HNPCAP_SHIFT 9 /* Shift value for USB_HNPCAP */ +#define _USB_GUSBCFG_HNPCAP_MASK 0x200UL /* Bit mask for USB_HNPCAP */ +#define _USB_GUSBCFG_HNPCAP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_HNPCAP_DEFAULT (_USB_GUSBCFG_HNPCAP_DEFAULT << 9) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define _USB_GUSBCFG_USBTRDTIM_SHIFT 10 /* Shift value for USB_USBTRDTIM */ +#define _USB_GUSBCFG_USBTRDTIM_MASK 0x3c00UL /* Bit mask for USB_USBTRDTIM */ +#define _USB_GUSBCFG_USBTRDTIM_DEFAULT 0x00000005UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_USBTRDTIM_DEFAULT (_USB_GUSBCFG_USBTRDTIM_DEFAULT << 10) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_USBTRDTIM(n) ((uint32_t)(n) << 10) /* Variable setting for USB_GUSBCFG */ +#define USB_GUSBCFG_TERMSELDLPULSE (0x1UL << 22) /* TermSel DLine Pulsing Selection (device only) */ +#define _USB_GUSBCFG_TERMSELDLPULSE_SHIFT 22 /* Shift value for USB_TERMSELDLPULSE */ +#define _USB_GUSBCFG_TERMSELDLPULSE_MASK 0x400000UL /* Bit mask for USB_TERMSELDLPULSE */ +#define _USB_GUSBCFG_TERMSELDLPULSE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define _USB_GUSBCFG_TERMSELDLPULSE_TXVALID 0x00000000UL /* Mode TXVALID for USB_GUSBCFG */ +#define _USB_GUSBCFG_TERMSELDLPULSE_TERMSEL 0x00000001UL /* Mode TERMSEL for USB_GUSBCFG */ +#define USB_GUSBCFG_TERMSELDLPULSE_DEFAULT (_USB_GUSBCFG_TERMSELDLPULSE_DEFAULT << 22) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_TERMSELDLPULSE_TXVALID (_USB_GUSBCFG_TERMSELDLPULSE_TXVALID << 22) /* Shifted mode TXVALID for USB_GUSBCFG */ +#define USB_GUSBCFG_TERMSELDLPULSE_TERMSEL (_USB_GUSBCFG_TERMSELDLPULSE_TERMSEL << 22) /* Shifted mode TERMSEL for USB_GUSBCFG */ +#define USB_GUSBCFG_TXENDDELAY (0x1UL << 28) /* Tx End Delay (device only) */ +#define _USB_GUSBCFG_TXENDDELAY_SHIFT 28 /* Shift value for USB_TXENDDELAY */ +#define _USB_GUSBCFG_TXENDDELAY_MASK 0x10000000UL /* Bit mask for USB_TXENDDELAY */ +#define _USB_GUSBCFG_TXENDDELAY_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_TXENDDELAY_DEFAULT (_USB_GUSBCFG_TXENDDELAY_DEFAULT << 28) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FORCEHSTMODE (0x1UL << 29) /* Force Host Mode (host and device) */ +#define _USB_GUSBCFG_FORCEHSTMODE_SHIFT 29 /* Shift value for USB_FORCEHSTMODE */ +#define _USB_GUSBCFG_FORCEHSTMODE_MASK 0x20000000UL /* Bit mask for USB_FORCEHSTMODE */ +#define _USB_GUSBCFG_FORCEHSTMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FORCEHSTMODE_DEFAULT (_USB_GUSBCFG_FORCEHSTMODE_DEFAULT << 29) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FORCEDEVMODE (0x1UL << 30) /* Force Device Mode (host and device) */ +#define _USB_GUSBCFG_FORCEDEVMODE_SHIFT 30 /* Shift value for USB_FORCEDEVMODE */ +#define _USB_GUSBCFG_FORCEDEVMODE_MASK 0x40000000UL /* Bit mask for USB_FORCEDEVMODE */ +#define _USB_GUSBCFG_FORCEDEVMODE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_FORCEDEVMODE_DEFAULT (_USB_GUSBCFG_FORCEDEVMODE_DEFAULT << 30) /* Shifted mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_CORRUPTTXPKT (0x1UL << 31) /* Corrupt Tx packet (host and device) */ +#define _USB_GUSBCFG_CORRUPTTXPKT_SHIFT 31 /* Shift value for USB_CORRUPTTXPKT */ +#define _USB_GUSBCFG_CORRUPTTXPKT_MASK 0x80000000UL /* Bit mask for USB_CORRUPTTXPKT */ +#define _USB_GUSBCFG_CORRUPTTXPKT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GUSBCFG */ +#define USB_GUSBCFG_CORRUPTTXPKT_DEFAULT (_USB_GUSBCFG_CORRUPTTXPKT_DEFAULT << 31) /* Shifted mode DEFAULT for USB_GUSBCFG */ + +/* Bit fields for USB GRSTCTL */ + +#define _USB_GRSTCTL_RESETVALUE 0x80000000UL /* Default value for USB_GRSTCTL */ +#define _USB_GRSTCTL_MASK 0xC00007F5UL /* Mask for USB_GRSTCTL */ + +#define USB_GRSTCTL_CSFTRST (0x1UL << 0) /* Core Soft Reset (host and device) */ +#define _USB_GRSTCTL_CSFTRST_SHIFT 0 /* Shift value for USB_CSFTRST */ +#define _USB_GRSTCTL_CSFTRST_MASK 0x1UL /* Bit mask for USB_CSFTRST */ +#define _USB_GRSTCTL_CSFTRST_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_CSFTRST_DEFAULT (_USB_GRSTCTL_CSFTRST_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_FRMCNTRRST (0x1UL << 2) /* Host Frame Counter Reset (host only) */ +#define _USB_GRSTCTL_FRMCNTRRST_SHIFT 2 /* Shift value for USB_FRMCNTRRST */ +#define _USB_GRSTCTL_FRMCNTRRST_MASK 0x4UL /* Bit mask for USB_FRMCNTRRST */ +#define _USB_GRSTCTL_FRMCNTRRST_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_FRMCNTRRST_DEFAULT (_USB_GRSTCTL_FRMCNTRRST_DEFAULT << 2) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_RXFFLSH (0x1UL << 4) /* RxFIFO Flush (host and device) */ +#define _USB_GRSTCTL_RXFFLSH_SHIFT 4 /* Shift value for USB_RXFFLSH */ +#define _USB_GRSTCTL_RXFFLSH_MASK 0x10UL /* Bit mask for USB_RXFFLSH */ +#define _USB_GRSTCTL_RXFFLSH_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_RXFFLSH_DEFAULT (_USB_GRSTCTL_RXFFLSH_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFFLSH (0x1UL << 5) /* TxFIFO Flush (host and device) */ +#define _USB_GRSTCTL_TXFFLSH_SHIFT 5 /* Shift value for USB_TXFFLSH */ +#define _USB_GRSTCTL_TXFFLSH_MASK 0x20UL /* Bit mask for USB_TXFFLSH */ +#define _USB_GRSTCTL_TXFFLSH_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFFLSH_DEFAULT (_USB_GRSTCTL_TXFFLSH_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_SHIFT 6 /* Shift value for USB_TXFNUM */ +#define _USB_GRSTCTL_TXFNUM_MASK 0x7C0UL /* Bit mask for USB_TXFNUM */ +#define _USB_GRSTCTL_TXFNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F0 0x00000000UL /* Mode F0 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F1 0x00000001UL /* Mode F1 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F2 0x00000002UL /* Mode F2 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F3 0x00000003UL /* Mode F3 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F4 0x00000004UL /* Mode F4 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F5 0x00000005UL /* Mode F5 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_F6 0x00000006UL /* Mode F6 for USB_GRSTCTL */ +#define _USB_GRSTCTL_TXFNUM_FALL 0x00000010UL /* Mode FALL for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_DEFAULT (_USB_GRSTCTL_TXFNUM_DEFAULT << 6) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F0 (_USB_GRSTCTL_TXFNUM_F0 << 6) /* Shifted mode F0 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F1 (_USB_GRSTCTL_TXFNUM_F1 << 6) /* Shifted mode F1 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F2 (_USB_GRSTCTL_TXFNUM_F2 << 6) /* Shifted mode F2 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F3 (_USB_GRSTCTL_TXFNUM_F3 << 6) /* Shifted mode F3 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F4 (_USB_GRSTCTL_TXFNUM_F4 << 6) /* Shifted mode F4 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F5 (_USB_GRSTCTL_TXFNUM_F5 << 6) /* Shifted mode F5 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F6 (_USB_GRSTCTL_TXFNUM_F6 << 6) /* Shifted mode F6 for USB_GRSTCTL */ +#define USB_GRSTCTL_TXFNUM_F(n) ((uint32_t)(n) << 6) /* TXFIFO n flush, n=0-15 */ +#define USB_GRSTCTL_TXFNUM_FALL (_USB_GRSTCTL_TXFNUM_FALL << 6) /* Shifted mode FALL for USB_GRSTCTL */ +#define USB_GRSTCTL_DMAREQ (0x1UL << 30) /* DMA Request Signal (host and device) */ +#define _USB_GRSTCTL_DMAREQ_SHIFT 30 /* Shift value for USB_DMAREQ */ +#define _USB_GRSTCTL_DMAREQ_MASK 0x40000000UL /* Bit mask for USB_DMAREQ */ +#define _USB_GRSTCTL_DMAREQ_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_DMAREQ_DEFAULT (_USB_GRSTCTL_DMAREQ_DEFAULT << 30) /* Shifted mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_AHBIDLE (0x1UL << 31) /* AHB Master Idle (host and device) */ +#define _USB_GRSTCTL_AHBIDLE_SHIFT 31 /* Shift value for USB_AHBIDLE */ +#define _USB_GRSTCTL_AHBIDLE_MASK 0x80000000UL /* Bit mask for USB_AHBIDLE */ +#define _USB_GRSTCTL_AHBIDLE_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_GRSTCTL */ +#define USB_GRSTCTL_AHBIDLE_DEFAULT (_USB_GRSTCTL_AHBIDLE_DEFAULT << 31) /* Shifted mode DEFAULT for USB_GRSTCTL */ + +/* Bit fields for USB GINTSTS */ + +#define _USB_GINTSTS_RESETVALUE 0x14000020UL /* Default value for USB_GINTSTS */ +#define _USB_GINTSTS_MASK 0xF7FC7CFFUL /* Mask for USB_GINTSTS */ + +#define USB_GINTSTS_CURMOD (0x1UL << 0) /* Current Mode of Operation (host and device) */ +#define _USB_GINTSTS_CURMOD_SHIFT 0 /* Shift value for USB_CURMOD */ +#define _USB_GINTSTS_CURMOD_MASK 0x1UL /* Bit mask for USB_CURMOD */ +#define _USB_GINTSTS_CURMOD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define _USB_GINTSTS_CURMOD_DEVICE 0x00000000UL /* Mode DEVICE for USB_GINTSTS */ +#define _USB_GINTSTS_CURMOD_HOST 0x00000001UL /* Mode HOST for USB_GINTSTS */ +#define USB_GINTSTS_CURMOD_DEFAULT (_USB_GINTSTS_CURMOD_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_CURMOD_DEVICE (_USB_GINTSTS_CURMOD_DEVICE << 0) /* Shifted mode DEVICE for USB_GINTSTS */ +#define USB_GINTSTS_CURMOD_HOST (_USB_GINTSTS_CURMOD_HOST << 0) /* Shifted mode HOST for USB_GINTSTS */ +#define USB_GINTSTS_MODEMIS (0x1UL << 1) /* Mode Mismatch Interrupt (host and device) */ +#define _USB_GINTSTS_MODEMIS_SHIFT 1 /* Shift value for USB_MODEMIS */ +#define _USB_GINTSTS_MODEMIS_MASK 0x2UL /* Bit mask for USB_MODEMIS */ +#define _USB_GINTSTS_MODEMIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_MODEMIS_DEFAULT (_USB_GINTSTS_MODEMIS_DEFAULT << 1) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_OTGINT (0x1UL << 2) /* OTG Interrupt (host and device) */ +#define _USB_GINTSTS_OTGINT_SHIFT 2 /* Shift value for USB_OTGINT */ +#define _USB_GINTSTS_OTGINT_MASK 0x4UL /* Bit mask for USB_OTGINT */ +#define _USB_GINTSTS_OTGINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_OTGINT_DEFAULT (_USB_GINTSTS_OTGINT_DEFAULT << 2) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_SOF (0x1UL << 3) /* Start of Frame (host and device) */ +#define _USB_GINTSTS_SOF_SHIFT 3 /* Shift value for USB_SOF */ +#define _USB_GINTSTS_SOF_MASK 0x8UL /* Bit mask for USB_SOF */ +#define _USB_GINTSTS_SOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_SOF_DEFAULT (_USB_GINTSTS_SOF_DEFAULT << 3) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_RXFLVL (0x1UL << 4) /* RxFIFO Non-Empty (host and device) */ +#define _USB_GINTSTS_RXFLVL_SHIFT 4 /* Shift value for USB_RXFLVL */ +#define _USB_GINTSTS_RXFLVL_MASK 0x10UL /* Bit mask for USB_RXFLVL */ +#define _USB_GINTSTS_RXFLVL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_RXFLVL_DEFAULT (_USB_GINTSTS_RXFLVL_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_NPTXFEMP (0x1UL << 5) /* Non-Periodic TxFIFO Empty (host only) */ +#define _USB_GINTSTS_NPTXFEMP_SHIFT 5 /* Shift value for USB_NPTXFEMP */ +#define _USB_GINTSTS_NPTXFEMP_MASK 0x20UL /* Bit mask for USB_NPTXFEMP */ +#define _USB_GINTSTS_NPTXFEMP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_NPTXFEMP_DEFAULT (_USB_GINTSTS_NPTXFEMP_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_GINNAKEFF (0x1UL << 6) /* Global IN Non-periodic NAK Effective (device only) */ +#define _USB_GINTSTS_GINNAKEFF_SHIFT 6 /* Shift value for USB_GINNAKEFF */ +#define _USB_GINTSTS_GINNAKEFF_MASK 0x40UL /* Bit mask for USB_GINNAKEFF */ +#define _USB_GINTSTS_GINNAKEFF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_GINNAKEFF_DEFAULT (_USB_GINTSTS_GINNAKEFF_DEFAULT << 6) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_GOUTNAKEFF (0x1UL << 7) /* Global OUT NAK Effective (device only) */ +#define _USB_GINTSTS_GOUTNAKEFF_SHIFT 7 /* Shift value for USB_GOUTNAKEFF */ +#define _USB_GINTSTS_GOUTNAKEFF_MASK 0x80UL /* Bit mask for USB_GOUTNAKEFF */ +#define _USB_GINTSTS_GOUTNAKEFF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_GOUTNAKEFF_DEFAULT (_USB_GINTSTS_GOUTNAKEFF_DEFAULT << 7) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ERLYSUSP (0x1UL << 10) /* Early Suspend (device only) */ +#define _USB_GINTSTS_ERLYSUSP_SHIFT 10 /* Shift value for USB_ERLYSUSP */ +#define _USB_GINTSTS_ERLYSUSP_MASK 0x400UL /* Bit mask for USB_ERLYSUSP */ +#define _USB_GINTSTS_ERLYSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ERLYSUSP_DEFAULT (_USB_GINTSTS_ERLYSUSP_DEFAULT << 10) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_USBSUSP (0x1UL << 11) /* USB Suspend (device only) */ +#define _USB_GINTSTS_USBSUSP_SHIFT 11 /* Shift value for USB_USBSUSP */ +#define _USB_GINTSTS_USBSUSP_MASK 0x800UL /* Bit mask for USB_USBSUSP */ +#define _USB_GINTSTS_USBSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_USBSUSP_DEFAULT (_USB_GINTSTS_USBSUSP_DEFAULT << 11) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_USBRST (0x1UL << 12) /* USB Reset (device only) */ +#define _USB_GINTSTS_USBRST_SHIFT 12 /* Shift value for USB_USBRST */ +#define _USB_GINTSTS_USBRST_MASK 0x1000UL /* Bit mask for USB_USBRST */ +#define _USB_GINTSTS_USBRST_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_USBRST_DEFAULT (_USB_GINTSTS_USBRST_DEFAULT << 12) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ENUMDONE (0x1UL << 13) /* Enumeration Done (device only) */ +#define _USB_GINTSTS_ENUMDONE_SHIFT 13 /* Shift value for USB_ENUMDONE */ +#define _USB_GINTSTS_ENUMDONE_MASK 0x2000UL /* Bit mask for USB_ENUMDONE */ +#define _USB_GINTSTS_ENUMDONE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ENUMDONE_DEFAULT (_USB_GINTSTS_ENUMDONE_DEFAULT << 13) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ISOOUTDROP (0x1UL << 14) /* Isochronous OUT Packet Dropped Interrupt (device only) */ +#define _USB_GINTSTS_ISOOUTDROP_SHIFT 14 /* Shift value for USB_ISOOUTDROP */ +#define _USB_GINTSTS_ISOOUTDROP_MASK 0x4000UL /* Bit mask for USB_ISOOUTDROP */ +#define _USB_GINTSTS_ISOOUTDROP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_ISOOUTDROP_DEFAULT (_USB_GINTSTS_ISOOUTDROP_DEFAULT << 14) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_IEPINT (0x1UL << 18) /* IN Endpoints Interrupt (device only) */ +#define _USB_GINTSTS_IEPINT_SHIFT 18 /* Shift value for USB_IEPINT */ +#define _USB_GINTSTS_IEPINT_MASK 0x40000UL /* Bit mask for USB_IEPINT */ +#define _USB_GINTSTS_IEPINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_IEPINT_DEFAULT (_USB_GINTSTS_IEPINT_DEFAULT << 18) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_OEPINT (0x1UL << 19) /* OUT Endpoints Interrupt (device only) */ +#define _USB_GINTSTS_OEPINT_SHIFT 19 /* Shift value for USB_OEPINT */ +#define _USB_GINTSTS_OEPINT_MASK 0x80000UL /* Bit mask for USB_OEPINT */ +#define _USB_GINTSTS_OEPINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_OEPINT_DEFAULT (_USB_GINTSTS_OEPINT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_INCOMPISOIN (0x1UL << 20) /* Incomplete Isochronous IN Transfer (device only) */ +#define _USB_GINTSTS_INCOMPISOIN_SHIFT 20 /* Shift value for USB_INCOMPISOIN */ +#define _USB_GINTSTS_INCOMPISOIN_MASK 0x100000UL /* Bit mask for USB_INCOMPISOIN */ +#define _USB_GINTSTS_INCOMPISOIN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_INCOMPISOIN_DEFAULT (_USB_GINTSTS_INCOMPISOIN_DEFAULT << 20) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_INCOMPLP (0x1UL << 21) /* Incomplete Periodic Transfer (device only) */ +#define _USB_GINTSTS_INCOMPLP_SHIFT 21 /* Shift value for USB_INCOMPLP */ +#define _USB_GINTSTS_INCOMPLP_MASK 0x200000UL /* Bit mask for USB_INCOMPLP */ +#define _USB_GINTSTS_INCOMPLP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_INCOMPLP_DEFAULT (_USB_GINTSTS_INCOMPLP_DEFAULT << 21) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_FETSUSP (0x1UL << 22) /* Data Fetch Suspended (device only) */ +#define _USB_GINTSTS_FETSUSP_SHIFT 22 /* Shift value for USB_FETSUSP */ +#define _USB_GINTSTS_FETSUSP_MASK 0x400000UL /* Bit mask for USB_FETSUSP */ +#define _USB_GINTSTS_FETSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_FETSUSP_DEFAULT (_USB_GINTSTS_FETSUSP_DEFAULT << 22) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_RESETDET (0x1UL << 23) /* Reset detected Interrupt (device only) */ +#define _USB_GINTSTS_RESETDET_SHIFT 23 /* Shift value for USB_RESETDET */ +#define _USB_GINTSTS_RESETDET_MASK 0x800000UL /* Bit mask for USB_RESETDET */ +#define _USB_GINTSTS_RESETDET_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_RESETDET_DEFAULT (_USB_GINTSTS_RESETDET_DEFAULT << 23) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_PRTINT (0x1UL << 24) /* Host Port Interrupt (host only) */ +#define _USB_GINTSTS_PRTINT_SHIFT 24 /* Shift value for USB_PRTINT */ +#define _USB_GINTSTS_PRTINT_MASK 0x1000000UL /* Bit mask for USB_PRTINT */ +#define _USB_GINTSTS_PRTINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_PRTINT_DEFAULT (_USB_GINTSTS_PRTINT_DEFAULT << 24) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_HCHINT (0x1UL << 25) /* Host Channels Interrupt (host only) */ +#define _USB_GINTSTS_HCHINT_SHIFT 25 /* Shift value for USB_HCHINT */ +#define _USB_GINTSTS_HCHINT_MASK 0x2000000UL /* Bit mask for USB_HCHINT */ +#define _USB_GINTSTS_HCHINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_HCHINT_DEFAULT (_USB_GINTSTS_HCHINT_DEFAULT << 25) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_PTXFEMP (0x1UL << 26) /* Periodic TxFIFO Empty (host only) */ +#define _USB_GINTSTS_PTXFEMP_SHIFT 26 /* Shift value for USB_PTXFEMP */ +#define _USB_GINTSTS_PTXFEMP_MASK 0x4000000UL /* Bit mask for USB_PTXFEMP */ +#define _USB_GINTSTS_PTXFEMP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_PTXFEMP_DEFAULT (_USB_GINTSTS_PTXFEMP_DEFAULT << 26) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_CONIDSTSCHNG (0x1UL << 28) /* Connector ID Status Change (host and device) */ +#define _USB_GINTSTS_CONIDSTSCHNG_SHIFT 28 /* Shift value for USB_CONIDSTSCHNG */ +#define _USB_GINTSTS_CONIDSTSCHNG_MASK 0x10000000UL /* Bit mask for USB_CONIDSTSCHNG */ +#define _USB_GINTSTS_CONIDSTSCHNG_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_CONIDSTSCHNG_DEFAULT (_USB_GINTSTS_CONIDSTSCHNG_DEFAULT << 28) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_DISCONNINT (0x1UL << 29) /* Disconnect Detected Interrupt (host only) */ +#define _USB_GINTSTS_DISCONNINT_SHIFT 29 /* Shift value for USB_DISCONNINT */ +#define _USB_GINTSTS_DISCONNINT_MASK 0x20000000UL /* Bit mask for USB_DISCONNINT */ +#define _USB_GINTSTS_DISCONNINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_DISCONNINT_DEFAULT (_USB_GINTSTS_DISCONNINT_DEFAULT << 29) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_SESSREQINT (0x1UL << 30) /* Session Request/New Session Detected Interrupt (host and device) */ +#define _USB_GINTSTS_SESSREQINT_SHIFT 30 /* Shift value for USB_SESSREQINT */ +#define _USB_GINTSTS_SESSREQINT_MASK 0x40000000UL /* Bit mask for USB_SESSREQINT */ +#define _USB_GINTSTS_SESSREQINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_SESSREQINT_DEFAULT (_USB_GINTSTS_SESSREQINT_DEFAULT << 30) /* Shifted mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_WKUPINT (0x1UL << 31) /* Resume/Remote Wakeup Detected Interrupt (host and device) */ +#define _USB_GINTSTS_WKUPINT_SHIFT 31 /* Shift value for USB_WKUPINT */ +#define _USB_GINTSTS_WKUPINT_MASK 0x80000000UL /* Bit mask for USB_WKUPINT */ +#define _USB_GINTSTS_WKUPINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTSTS */ +#define USB_GINTSTS_WKUPINT_DEFAULT (_USB_GINTSTS_WKUPINT_DEFAULT << 31) /* Shifted mode DEFAULT for USB_GINTSTS */ + +/* Bit fields for USB GINTMSK */ + +#define _USB_GINTMSK_RESETVALUE 0x00000000UL /* Default value for USB_GINTMSK */ +#define _USB_GINTMSK_MASK 0xF7FC7CFEUL /* Mask for USB_GINTMSK */ + +#define USB_GINTMSK_MODEMISMSK (0x1UL << 1) /* Mode Mismatch Interrupt Mask (host and device) */ +#define _USB_GINTMSK_MODEMISMSK_SHIFT 1 /* Shift value for USB_MODEMISMSK */ +#define _USB_GINTMSK_MODEMISMSK_MASK 0x2UL /* Bit mask for USB_MODEMISMSK */ +#define _USB_GINTMSK_MODEMISMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_MODEMISMSK_DEFAULT (_USB_GINTMSK_MODEMISMSK_DEFAULT << 1) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_OTGINTMSK (0x1UL << 2) /* OTG Interrupt Mask (host and device) */ +#define _USB_GINTMSK_OTGINTMSK_SHIFT 2 /* Shift value for USB_OTGINTMSK */ +#define _USB_GINTMSK_OTGINTMSK_MASK 0x4UL /* Bit mask for USB_OTGINTMSK */ +#define _USB_GINTMSK_OTGINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_OTGINTMSK_DEFAULT (_USB_GINTMSK_OTGINTMSK_DEFAULT << 2) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_SOFMSK (0x1UL << 3) /* Start of Frame Mask (host and device) */ +#define _USB_GINTMSK_SOFMSK_SHIFT 3 /* Shift value for USB_SOFMSK */ +#define _USB_GINTMSK_SOFMSK_MASK 0x8UL /* Bit mask for USB_SOFMSK */ +#define _USB_GINTMSK_SOFMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_SOFMSK_DEFAULT (_USB_GINTMSK_SOFMSK_DEFAULT << 3) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_RXFLVLMSK (0x1UL << 4) /* Receive FIFO Non-Empty Mask (host and device) */ +#define _USB_GINTMSK_RXFLVLMSK_SHIFT 4 /* Shift value for USB_RXFLVLMSK */ +#define _USB_GINTMSK_RXFLVLMSK_MASK 0x10UL /* Bit mask for USB_RXFLVLMSK */ +#define _USB_GINTMSK_RXFLVLMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_RXFLVLMSK_DEFAULT (_USB_GINTMSK_RXFLVLMSK_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_NPTXFEMPMSK (0x1UL << 5) /* Non-Periodic TxFIFO Empty Mask (host only) */ +#define _USB_GINTMSK_NPTXFEMPMSK_SHIFT 5 /* Shift value for USB_NPTXFEMPMSK */ +#define _USB_GINTMSK_NPTXFEMPMSK_MASK 0x20UL /* Bit mask for USB_NPTXFEMPMSK */ +#define _USB_GINTMSK_NPTXFEMPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_NPTXFEMPMSK_DEFAULT (_USB_GINTMSK_NPTXFEMPMSK_DEFAULT << 5) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_GINNAKEFFMSK (0x1UL << 6) /* Global Non-periodic IN NAK Effective Mask (device only) */ +#define _USB_GINTMSK_GINNAKEFFMSK_SHIFT 6 /* Shift value for USB_GINNAKEFFMSK */ +#define _USB_GINTMSK_GINNAKEFFMSK_MASK 0x40UL /* Bit mask for USB_GINNAKEFFMSK */ +#define _USB_GINTMSK_GINNAKEFFMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_GINNAKEFFMSK_DEFAULT (_USB_GINTMSK_GINNAKEFFMSK_DEFAULT << 6) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_GOUTNAKEFFMSK (0x1UL << 7) /* Global OUT NAK Effective Mask (device only) */ +#define _USB_GINTMSK_GOUTNAKEFFMSK_SHIFT 7 /* Shift value for USB_GOUTNAKEFFMSK */ +#define _USB_GINTMSK_GOUTNAKEFFMSK_MASK 0x80UL /* Bit mask for USB_GOUTNAKEFFMSK */ +#define _USB_GINTMSK_GOUTNAKEFFMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_GOUTNAKEFFMSK_DEFAULT (_USB_GINTMSK_GOUTNAKEFFMSK_DEFAULT << 7) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ERLYSUSPMSK (0x1UL << 10) /* Early Suspend Mask (device only) */ +#define _USB_GINTMSK_ERLYSUSPMSK_SHIFT 10 /* Shift value for USB_ERLYSUSPMSK */ +#define _USB_GINTMSK_ERLYSUSPMSK_MASK 0x400UL /* Bit mask for USB_ERLYSUSPMSK */ +#define _USB_GINTMSK_ERLYSUSPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ERLYSUSPMSK_DEFAULT (_USB_GINTMSK_ERLYSUSPMSK_DEFAULT << 10) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_USBSUSPMSK (0x1UL << 11) /* USB Suspend Mask (device only) */ +#define _USB_GINTMSK_USBSUSPMSK_SHIFT 11 /* Shift value for USB_USBSUSPMSK */ +#define _USB_GINTMSK_USBSUSPMSK_MASK 0x800UL /* Bit mask for USB_USBSUSPMSK */ +#define _USB_GINTMSK_USBSUSPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_USBSUSPMSK_DEFAULT (_USB_GINTMSK_USBSUSPMSK_DEFAULT << 11) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_USBRSTMSK (0x1UL << 12) /* USB Reset Mask (device only) */ +#define _USB_GINTMSK_USBRSTMSK_SHIFT 12 /* Shift value for USB_USBRSTMSK */ +#define _USB_GINTMSK_USBRSTMSK_MASK 0x1000UL /* Bit mask for USB_USBRSTMSK */ +#define _USB_GINTMSK_USBRSTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_USBRSTMSK_DEFAULT (_USB_GINTMSK_USBRSTMSK_DEFAULT << 12) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ENUMDONEMSK (0x1UL << 13) /* Enumeration Done Mask (device only) */ +#define _USB_GINTMSK_ENUMDONEMSK_SHIFT 13 /* Shift value for USB_ENUMDONEMSK */ +#define _USB_GINTMSK_ENUMDONEMSK_MASK 0x2000UL /* Bit mask for USB_ENUMDONEMSK */ +#define _USB_GINTMSK_ENUMDONEMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ENUMDONEMSK_DEFAULT (_USB_GINTMSK_ENUMDONEMSK_DEFAULT << 13) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ISOOUTDROPMSK (0x1UL << 14) /* Isochronous OUT Packet Dropped Interrupt Mask (device only) */ +#define _USB_GINTMSK_ISOOUTDROPMSK_SHIFT 14 /* Shift value for USB_ISOOUTDROPMSK */ +#define _USB_GINTMSK_ISOOUTDROPMSK_MASK 0x4000UL /* Bit mask for USB_ISOOUTDROPMSK */ +#define _USB_GINTMSK_ISOOUTDROPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_ISOOUTDROPMSK_DEFAULT (_USB_GINTMSK_ISOOUTDROPMSK_DEFAULT << 14) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_IEPINTMSK (0x1UL << 18) /* IN Endpoints Interrupt Mask (device only) */ +#define _USB_GINTMSK_IEPINTMSK_SHIFT 18 /* Shift value for USB_IEPINTMSK */ +#define _USB_GINTMSK_IEPINTMSK_MASK 0x40000UL /* Bit mask for USB_IEPINTMSK */ +#define _USB_GINTMSK_IEPINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_IEPINTMSK_DEFAULT (_USB_GINTMSK_IEPINTMSK_DEFAULT << 18) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_OEPINTMSK (0x1UL << 19) /* OUT Endpoints Interrupt Mask (device only) */ +#define _USB_GINTMSK_OEPINTMSK_SHIFT 19 /* Shift value for USB_OEPINTMSK */ +#define _USB_GINTMSK_OEPINTMSK_MASK 0x80000UL /* Bit mask for USB_OEPINTMSK */ +#define _USB_GINTMSK_OEPINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_OEPINTMSK_DEFAULT (_USB_GINTMSK_OEPINTMSK_DEFAULT << 19) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_INCOMPISOINMSK (0x1UL << 20) /* Incomplete Isochronous IN Transfer Mask (device only) */ +#define _USB_GINTMSK_INCOMPISOINMSK_SHIFT 20 /* Shift value for USB_INCOMPISOINMSK */ +#define _USB_GINTMSK_INCOMPISOINMSK_MASK 0x100000UL /* Bit mask for USB_INCOMPISOINMSK */ +#define _USB_GINTMSK_INCOMPISOINMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_INCOMPISOINMSK_DEFAULT (_USB_GINTMSK_INCOMPISOINMSK_DEFAULT << 20) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_INCOMPLPMSK (0x1UL << 21) /* Incomplete Periodic Transfer Mask (host only) */ +#define _USB_GINTMSK_INCOMPLPMSK_SHIFT 21 /* Shift value for USB_INCOMPLPMSK */ +#define _USB_GINTMSK_INCOMPLPMSK_MASK 0x200000UL /* Bit mask for USB_INCOMPLPMSK */ +#define _USB_GINTMSK_INCOMPLPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_INCOMPLPMSK_DEFAULT (_USB_GINTMSK_INCOMPLPMSK_DEFAULT << 21) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_FETSUSPMSK (0x1UL << 22) /* Data Fetch Suspended Mask (device only) */ +#define _USB_GINTMSK_FETSUSPMSK_SHIFT 22 /* Shift value for USB_FETSUSPMSK */ +#define _USB_GINTMSK_FETSUSPMSK_MASK 0x400000UL /* Bit mask for USB_FETSUSPMSK */ +#define _USB_GINTMSK_FETSUSPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_FETSUSPMSK_DEFAULT (_USB_GINTMSK_FETSUSPMSK_DEFAULT << 22) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_RESETDETMSK (0x1UL << 23) /* Reset detected Interrupt Mask (device only) */ +#define _USB_GINTMSK_RESETDETMSK_SHIFT 23 /* Shift value for USB_RESETDETMSK */ +#define _USB_GINTMSK_RESETDETMSK_MASK 0x800000UL /* Bit mask for USB_RESETDETMSK */ +#define _USB_GINTMSK_RESETDETMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_RESETDETMSK_DEFAULT (_USB_GINTMSK_RESETDETMSK_DEFAULT << 23) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_PRTINTMSK (0x1UL << 24) /* Host Port Interrupt Mask (host only) */ +#define _USB_GINTMSK_PRTINTMSK_SHIFT 24 /* Shift value for USB_PRTINTMSK */ +#define _USB_GINTMSK_PRTINTMSK_MASK 0x1000000UL /* Bit mask for USB_PRTINTMSK */ +#define _USB_GINTMSK_PRTINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_PRTINTMSK_DEFAULT (_USB_GINTMSK_PRTINTMSK_DEFAULT << 24) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_HCHINTMSK (0x1UL << 25) /* Host Channels Interrupt Mask (host only) */ +#define _USB_GINTMSK_HCHINTMSK_SHIFT 25 /* Shift value for USB_HCHINTMSK */ +#define _USB_GINTMSK_HCHINTMSK_MASK 0x2000000UL /* Bit mask for USB_HCHINTMSK */ +#define _USB_GINTMSK_HCHINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_HCHINTMSK_DEFAULT (_USB_GINTMSK_HCHINTMSK_DEFAULT << 25) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_PTXFEMPMSK (0x1UL << 26) /* Periodic TxFIFO Empty Mask (host only) */ +#define _USB_GINTMSK_PTXFEMPMSK_SHIFT 26 /* Shift value for USB_PTXFEMPMSK */ +#define _USB_GINTMSK_PTXFEMPMSK_MASK 0x4000000UL /* Bit mask for USB_PTXFEMPMSK */ +#define _USB_GINTMSK_PTXFEMPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_PTXFEMPMSK_DEFAULT (_USB_GINTMSK_PTXFEMPMSK_DEFAULT << 26) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_CONIDSTSCHNGMSK (0x1UL << 28) /* Connector ID Status Change Mask (host and device) */ +#define _USB_GINTMSK_CONIDSTSCHNGMSK_SHIFT 28 /* Shift value for USB_CONIDSTSCHNGMSK */ +#define _USB_GINTMSK_CONIDSTSCHNGMSK_MASK 0x10000000UL /* Bit mask for USB_CONIDSTSCHNGMSK */ +#define _USB_GINTMSK_CONIDSTSCHNGMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_CONIDSTSCHNGMSK_DEFAULT (_USB_GINTMSK_CONIDSTSCHNGMSK_DEFAULT << 28) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_DISCONNINTMSK (0x1UL << 29) /* Disconnect Detected Interrupt Mask (host and device) */ +#define _USB_GINTMSK_DISCONNINTMSK_SHIFT 29 /* Shift value for USB_DISCONNINTMSK */ +#define _USB_GINTMSK_DISCONNINTMSK_MASK 0x20000000UL /* Bit mask for USB_DISCONNINTMSK */ +#define _USB_GINTMSK_DISCONNINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_DISCONNINTMSK_DEFAULT (_USB_GINTMSK_DISCONNINTMSK_DEFAULT << 29) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_SESSREQINTMSK (0x1UL << 30) /* Session Request/New Session Detected Interrupt Mask (host and device) */ +#define _USB_GINTMSK_SESSREQINTMSK_SHIFT 30 /* Shift value for USB_SESSREQINTMSK */ +#define _USB_GINTMSK_SESSREQINTMSK_MASK 0x40000000UL /* Bit mask for USB_SESSREQINTMSK */ +#define _USB_GINTMSK_SESSREQINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_SESSREQINTMSK_DEFAULT (_USB_GINTMSK_SESSREQINTMSK_DEFAULT << 30) /* Shifted mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_WKUPINTMSK (0x1UL << 31) /* Resume/Remote Wakeup Detected Interrupt Mask (host and device) */ +#define _USB_GINTMSK_WKUPINTMSK_SHIFT 31 /* Shift value for USB_WKUPINTMSK */ +#define _USB_GINTMSK_WKUPINTMSK_MASK 0x80000000UL /* Bit mask for USB_WKUPINTMSK */ +#define _USB_GINTMSK_WKUPINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GINTMSK */ +#define USB_GINTMSK_WKUPINTMSK_DEFAULT (_USB_GINTMSK_WKUPINTMSK_DEFAULT << 31) /* Shifted mode DEFAULT for USB_GINTMSK */ + +/* Bit fields for USB GRXSTSR */ + +#define _USB_GRXSTSR_RESETVALUE 0x00000000UL /* Default value for USB_GRXSTSR */ +#define _USB_GRXSTSR_MASK 0x0F1FFFFFUL /* Mask for USB_GRXSTSR */ + +#define _USB_GRXSTSR_CHEPNUM_SHIFT 0 /* Shift value for USB_CHEPNUM */ +#define _USB_GRXSTSR_CHEPNUM_MASK 0xFUL /* Bit mask for USB_CHEPNUM */ +#define _USB_GRXSTSR_CHEPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSR */ +#define USB_GRXSTSR_CHEPNUM_DEFAULT (_USB_GRXSTSR_CHEPNUM_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GRXSTSR */ +#define _USB_GRXSTSR_BCNT_SHIFT 4 /* Shift value for USB_BCNT */ +#define _USB_GRXSTSR_BCNT_MASK 0x7FF0UL /* Bit mask for USB_BCNT */ +#define _USB_GRXSTSR_BCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSR */ +#define USB_GRXSTSR_BCNT_DEFAULT (_USB_GRXSTSR_BCNT_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GRXSTSR */ +#define _USB_GRXSTSR_DPID_SHIFT 15 /* Shift value for USB_DPID */ +#define _USB_GRXSTSR_DPID_MASK 0x18000UL /* Bit mask for USB_DPID */ +#define _USB_GRXSTSR_DPID_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSR */ +#define _USB_GRXSTSR_DPID_DATA0 0x00000000UL /* Mode DATA0 for USB_GRXSTSR */ +#define _USB_GRXSTSR_DPID_DATA1 0x00000001UL /* Mode DATA1 for USB_GRXSTSR */ +#define _USB_GRXSTSR_DPID_DATA2 0x00000002UL /* Mode DATA2 for USB_GRXSTSR */ +#define _USB_GRXSTSR_DPID_MDATA 0x00000003UL /* Mode MDATA for USB_GRXSTSR */ +#define USB_GRXSTSR_DPID_DEFAULT (_USB_GRXSTSR_DPID_DEFAULT << 15) /* Shifted mode DEFAULT for USB_GRXSTSR */ +#define USB_GRXSTSR_DPID_DATA0 (_USB_GRXSTSR_DPID_DATA0 << 15) /* Shifted mode DATA0 for USB_GRXSTSR */ +#define USB_GRXSTSR_DPID_DATA1 (_USB_GRXSTSR_DPID_DATA1 << 15) /* Shifted mode DATA1 for USB_GRXSTSR */ +#define USB_GRXSTSR_DPID_DATA2 (_USB_GRXSTSR_DPID_DATA2 << 15) /* Shifted mode DATA2 for USB_GRXSTSR */ +#define USB_GRXSTSR_DPID_MDATA (_USB_GRXSTSR_DPID_MDATA << 15) /* Shifted mode MDATA for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_SHIFT 17 /* Shift value for USB_PKTSTS */ +#define _USB_GRXSTSR_PKTSTS_MASK 0x1E0000UL /* Bit mask for USB_PKTSTS */ +#define _USB_GRXSTSR_PKTSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_GOUTNAK 0x00000001UL /* Mode GOUTNAK for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_PKTRCV 0x00000002UL /* Mode PKTRCV for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_XFERCOMPL 0x00000003UL /* Mode XFERCOMPL for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_SETUPCOMPL 0x00000004UL /* Mode SETUPCOMPL for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_TGLERR 0x00000005UL /* Mode TGLERR for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_SETUPRCV 0x00000006UL /* Mode SETUPRCV for USB_GRXSTSR */ +#define _USB_GRXSTSR_PKTSTS_CHLT 0x00000007UL /* Mode CHLT for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_DEFAULT (_USB_GRXSTSR_PKTSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_GOUTNAK (_USB_GRXSTSR_PKTSTS_GOUTNAK << 17) /* Shifted mode GOUTNAK for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_PKTRCV (_USB_GRXSTSR_PKTSTS_PKTRCV << 17) /* Shifted mode PKTRCV for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_XFERCOMPL (_USB_GRXSTSR_PKTSTS_XFERCOMPL << 17) /* Shifted mode XFERCOMPL for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_SETUPCOMPL (_USB_GRXSTSR_PKTSTS_SETUPCOMPL << 17) /* Shifted mode SETUPCOMPL for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_TGLERR (_USB_GRXSTSR_PKTSTS_TGLERR << 17) /* Shifted mode TGLERR for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_SETUPRCV (_USB_GRXSTSR_PKTSTS_SETUPRCV << 17) /* Shifted mode SETUPRCV for USB_GRXSTSR */ +#define USB_GRXSTSR_PKTSTS_CHLT (_USB_GRXSTSR_PKTSTS_CHLT << 17) /* Shifted mode CHLT for USB_GRXSTSR */ +#define _USB_GRXSTSR_FN_SHIFT 24 /* Shift value for USB_FN */ +#define _USB_GRXSTSR_FN_MASK 0xF000000UL /* Bit mask for USB_FN */ +#define _USB_GRXSTSR_FN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSR */ +#define USB_GRXSTSR_FN_DEFAULT (_USB_GRXSTSR_FN_DEFAULT << 24) /* Shifted mode DEFAULT for USB_GRXSTSR */ + +/* Bit fields for USB GRXSTSP */ + +#define _USB_GRXSTSP_RESETVALUE 0x00000000UL /* Default value for USB_GRXSTSP */ +#define _USB_GRXSTSP_MASK 0x01FFFFFFUL /* Mask for USB_GRXSTSP */ + +#define _USB_GRXSTSP_CHEPNUM_SHIFT 0 /* Shift value for USB_CHEPNUM */ +#define _USB_GRXSTSP_CHEPNUM_MASK 0xFUL /* Bit mask for USB_CHEPNUM */ +#define _USB_GRXSTSP_CHEPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSP */ +#define USB_GRXSTSP_CHEPNUM_DEFAULT (_USB_GRXSTSP_CHEPNUM_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GRXSTSP */ +#define _USB_GRXSTSP_BCNT_SHIFT 4 /* Shift value for USB_BCNT */ +#define _USB_GRXSTSP_BCNT_MASK 0x7FF0UL /* Bit mask for USB_BCNT */ +#define _USB_GRXSTSP_BCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSP */ +#define USB_GRXSTSP_BCNT_DEFAULT (_USB_GRXSTSP_BCNT_DEFAULT << 4) /* Shifted mode DEFAULT for USB_GRXSTSP */ +#define _USB_GRXSTSP_DPID_SHIFT 15 /* Shift value for USB_DPID */ +#define _USB_GRXSTSP_DPID_MASK 0x18000UL /* Bit mask for USB_DPID */ +#define _USB_GRXSTSP_DPID_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSP */ +#define _USB_GRXSTSP_DPID_DATA0 0x00000000UL /* Mode DATA0 for USB_GRXSTSP */ +#define _USB_GRXSTSP_DPID_DATA1 0x00000001UL /* Mode DATA1 for USB_GRXSTSP */ +#define _USB_GRXSTSP_DPID_DATA2 0x00000002UL /* Mode DATA2 for USB_GRXSTSP */ +#define _USB_GRXSTSP_DPID_MDATA 0x00000003UL /* Mode MDATA for USB_GRXSTSP */ +#define USB_GRXSTSP_DPID_DEFAULT (_USB_GRXSTSP_DPID_DEFAULT << 15) /* Shifted mode DEFAULT for USB_GRXSTSP */ +#define USB_GRXSTSP_DPID_DATA0 (_USB_GRXSTSP_DPID_DATA0 << 15) /* Shifted mode DATA0 for USB_GRXSTSP */ +#define USB_GRXSTSP_DPID_DATA1 (_USB_GRXSTSP_DPID_DATA1 << 15) /* Shifted mode DATA1 for USB_GRXSTSP */ +#define USB_GRXSTSP_DPID_DATA2 (_USB_GRXSTSP_DPID_DATA2 << 15) /* Shifted mode DATA2 for USB_GRXSTSP */ +#define USB_GRXSTSP_DPID_MDATA (_USB_GRXSTSP_DPID_MDATA << 15) /* Shifted mode MDATA for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_SHIFT 17 /* Shift value for USB_PKTSTS */ +#define _USB_GRXSTSP_PKTSTS_MASK 0x1E0000UL /* Bit mask for USB_PKTSTS */ +#define _USB_GRXSTSP_PKTSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_GOUTNAK 0x00000001UL /* Mode GOUTNAK for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_PKTRCV 0x00000002UL /* Mode PKTRCV for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_XFERCOMPL 0x00000003UL /* Mode XFERCOMPL for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_SETUPCOMPL 0x00000004UL /* Mode SETUPCOMPL for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_TGLERR 0x00000005UL /* Mode TGLERR for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_SETUPRCV 0x00000006UL /* Mode SETUPRCV for USB_GRXSTSP */ +#define _USB_GRXSTSP_PKTSTS_CHLT 0x00000007UL /* Mode CHLT for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_DEFAULT (_USB_GRXSTSP_PKTSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_GOUTNAK (_USB_GRXSTSP_PKTSTS_GOUTNAK << 17) /* Shifted mode GOUTNAK for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_PKTRCV (_USB_GRXSTSP_PKTSTS_PKTRCV << 17) /* Shifted mode PKTRCV for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_XFERCOMPL (_USB_GRXSTSP_PKTSTS_XFERCOMPL << 17) /* Shifted mode XFERCOMPL for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_SETUPCOMPL (_USB_GRXSTSP_PKTSTS_SETUPCOMPL << 17) /* Shifted mode SETUPCOMPL for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_TGLERR (_USB_GRXSTSP_PKTSTS_TGLERR << 17) /* Shifted mode TGLERR for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_SETUPRCV (_USB_GRXSTSP_PKTSTS_SETUPRCV << 17) /* Shifted mode SETUPRCV for USB_GRXSTSP */ +#define USB_GRXSTSP_PKTSTS_CHLT (_USB_GRXSTSP_PKTSTS_CHLT << 17) /* Shifted mode CHLT for USB_GRXSTSP */ +#define _USB_GRXSTSP_FN_SHIFT 21 /* Shift value for USB_FN */ +#define _USB_GRXSTSP_FN_MASK 0x1E00000UL /* Bit mask for USB_FN */ +#define _USB_GRXSTSP_FN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GRXSTSP */ +#define USB_GRXSTSP_FN_DEFAULT (_USB_GRXSTSP_FN_DEFAULT << 21) /* Shifted mode DEFAULT for USB_GRXSTSP */ + +/* Bit fields for USB GRXFSIZ */ + +#define _USB_GRXFSIZ_RESETVALUE 0x00000200UL /* Default value for USB_GRXFSIZ */ +#define _USB_GRXFSIZ_MASK 0x000003FFUL /* Mask for USB_GRXFSIZ */ + +#define _USB_GRXFSIZ_RXFDEP_SHIFT 0 /* Shift value for USB_RXFDEP */ +#define _USB_GRXFSIZ_RXFDEP_MASK 0x3FFUL /* Bit mask for USB_RXFDEP */ +#define _USB_GRXFSIZ_RXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GRXFSIZ */ +#define USB_GRXFSIZ_RXFDEP_DEFAULT (_USB_GRXFSIZ_RXFDEP_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GRXFSIZ */ + +/* Bit fields for USB GNPTXFSIZ */ + +#define _USB_GNPTXFSIZ_RESETVALUE 0x02000200UL /* Default value for USB_GNPTXFSIZ */ +#define _USB_GNPTXFSIZ_MASK 0xFFFF03FFUL /* Mask for USB_GNPTXFSIZ */ + +#define _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT 0 /* Shift value for USB_NPTXFSTADDR */ +#define _USB_GNPTXFSIZ_NPTXFSTADDR_MASK 0x3FFUL /* Bit mask for USB_NPTXFSTADDR */ +#define _USB_GNPTXFSIZ_NPTXFSTADDR_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GNPTXFSIZ */ +#define USB_GNPTXFSIZ_NPTXFSTADDR_DEFAULT (_USB_GNPTXFSIZ_NPTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GNPTXFSIZ */ +#define _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT 16 /* Shift value for USB_NPTXFINEPTXF0DEP */ +#define _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK 0xFFFF0000UL /* Bit mask for USB_NPTXFINEPTXF0DEP */ +#define _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GNPTXFSIZ */ +#define USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_DEFAULT (_USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_GNPTXFSIZ */ + +/* Bit fields for USB DIEPTXF0 */ + +#define _USB_DIEPTXF0_TXFSTADDR_SHIFT 0 /* Shift value for USB_NPTXFSTADDR */ +#define _USB_DIEPTXF0_TXFSTADDR_MASK 0x3FFUL /* Bit mask for USB_NPTXFSTADDR */ +#define _USB_DIEPTXF0_TXFSTADDR_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GNPTXFSIZ */ +#define USB_DIEPTXF0_TXFSTADDR_DEFAULT (_USB_DIEPTXF0_TXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GNPTXFSIZ */ +#define _USB_DIEPTXF0_TXFINEPTXF0DEP_SHIFT 16 /* Shift value for USB_NPTXFINEPTXF0DEP */ +#define _USB_DIEPTXF0_TXFINEPTXF0DEP_MASK 0xFFFF0000UL /* Bit mask for USB_NPTXFINEPTXF0DEP */ +#define _USB_DIEPTXF0_TXFINEPTXF0DEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GNPTXFSIZ */ +#define USB_DIEPTXF0_TXFINEPTXF0DEP_DEFAULT (_USB_DIEPTXF0_TXFINEPTXF0DEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_GNPTXFSIZ */ + +/* Bit fields for USB GNPTXSTS */ + +#define _USB_GNPTXSTS_RESETVALUE 0x00080200UL /* Default value for USB_GNPTXSTS */ +#define _USB_GNPTXSTS_MASK 0x7FFFFFFFUL /* Mask for USB_GNPTXSTS */ + +#define _USB_GNPTXSTS_NPTXFSPCAVAIL_SHIFT 0 /* Shift value for USB_NPTXFSPCAVAIL */ +#define _USB_GNPTXSTS_NPTXFSPCAVAIL_MASK 0xFFFFUL /* Bit mask for USB_NPTXFSPCAVAIL */ +#define _USB_GNPTXSTS_NPTXFSPCAVAIL_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GNPTXSTS */ +#define USB_GNPTXSTS_NPTXFSPCAVAIL_DEFAULT (_USB_GNPTXSTS_NPTXFSPCAVAIL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GNPTXSTS */ +#define _USB_GNPTXSTS_NPTXQSPCAVAIL_SHIFT 16 /* Shift value for USB_NPTXQSPCAVAIL */ +#define _USB_GNPTXSTS_NPTXQSPCAVAIL_MASK 0xFF0000UL /* Bit mask for USB_NPTXQSPCAVAIL */ +#define _USB_GNPTXSTS_NPTXQSPCAVAIL_DEFAULT 0x00000008UL /* Mode DEFAULT for USB_GNPTXSTS */ +#define USB_GNPTXSTS_NPTXQSPCAVAIL_DEFAULT (_USB_GNPTXSTS_NPTXQSPCAVAIL_DEFAULT << 16) /* Shifted mode DEFAULT for USB_GNPTXSTS */ +#define _USB_GNPTXSTS_NPTXQTOP_SHIFT 24 /* Shift value for USB_NPTXQTOP */ +#define _USB_GNPTXSTS_NPTXQTOP_MASK 0x7F000000UL /* Bit mask for USB_NPTXQTOP */ +#define _USB_GNPTXSTS_NPTXQTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_GNPTXSTS */ +#define USB_GNPTXSTS_NPTXQTOP_DEFAULT (_USB_GNPTXSTS_NPTXQTOP_DEFAULT << 24) /* Shifted mode DEFAULT for USB_GNPTXSTS */ + +/* Bit fields for USB GDFIFOCFG */ + +#define _USB_GDFIFOCFG_RESETVALUE 0x01F20200UL /* Default value for USB_GDFIFOCFG */ +#define _USB_GDFIFOCFG_MASK 0xFFFFFFFFUL /* Mask for USB_GDFIFOCFG */ + +#define _USB_GDFIFOCFG_GDFIFOCFG_SHIFT 0 /* Shift value for USB_GDFIFOCFG */ +#define _USB_GDFIFOCFG_GDFIFOCFG_MASK 0xFFFFUL /* Bit mask for USB_GDFIFOCFG */ +#define _USB_GDFIFOCFG_GDFIFOCFG_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_GDFIFOCFG */ +#define USB_GDFIFOCFG_GDFIFOCFG_DEFAULT (_USB_GDFIFOCFG_GDFIFOCFG_DEFAULT << 0) /* Shifted mode DEFAULT for USB_GDFIFOCFG */ +#define _USB_GDFIFOCFG_EPINFOBASEADDR_SHIFT 16 /* Shift value for USB_EPINFOBASEADDR */ +#define _USB_GDFIFOCFG_EPINFOBASEADDR_MASK 0xFFFF0000UL /* Bit mask for USB_EPINFOBASEADDR */ +#define _USB_GDFIFOCFG_EPINFOBASEADDR_DEFAULT 0x000001F2UL /* Mode DEFAULT for USB_GDFIFOCFG */ +#define USB_GDFIFOCFG_EPINFOBASEADDR_DEFAULT (_USB_GDFIFOCFG_EPINFOBASEADDR_DEFAULT << 16) /* Shifted mode DEFAULT for USB_GDFIFOCFG */ + +/* Bit fields for USB HPTXFSIZ */ + +#define _USB_HPTXFSIZ_RESETVALUE 0x02000400UL /* Default value for USB_HPTXFSIZ */ +#define _USB_HPTXFSIZ_MASK 0x03FF07FFUL /* Mask for USB_HPTXFSIZ */ + +#define _USB_HPTXFSIZ_PTXFSTADDR_SHIFT 0 /* Shift value for USB_PTXFSTADDR */ +#define _USB_HPTXFSIZ_PTXFSTADDR_MASK 0x7FFUL /* Bit mask for USB_PTXFSTADDR */ +#define _USB_HPTXFSIZ_PTXFSTADDR_DEFAULT 0x00000400UL /* Mode DEFAULT for USB_HPTXFSIZ */ +#define USB_HPTXFSIZ_PTXFSTADDR_DEFAULT (_USB_HPTXFSIZ_PTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HPTXFSIZ */ +#define _USB_HPTXFSIZ_PTXFSIZE_SHIFT 16 /* Shift value for USB_PTXFSIZE */ +#define _USB_HPTXFSIZ_PTXFSIZE_MASK 0x3FF0000UL /* Bit mask for USB_PTXFSIZE */ +#define _USB_HPTXFSIZ_PTXFSIZE_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_HPTXFSIZ */ +#define USB_HPTXFSIZ_PTXFSIZE_DEFAULT (_USB_HPTXFSIZ_PTXFSIZE_DEFAULT << 16) /* Shifted mode DEFAULT for USB_HPTXFSIZ */ + +/* Bit fields for USB DIEPTXF1 */ + +#define _USB_DIEPTXF1_RESETVALUE 0x02000400UL /* Default value for USB_DIEPTXF1 */ +#define _USB_DIEPTXF1_MASK 0x03FF07FFUL /* Mask for USB_DIEPTXF1 */ + +#define _USB_DIEPTXF1_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF1_INEPNTXFSTADDR_MASK 0x7FFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF1_INEPNTXFSTADDR_DEFAULT 0x00000400UL /* Mode DEFAULT for USB_DIEPTXF1 */ +#define USB_DIEPTXF1_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF1_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF1 */ +#define _USB_DIEPTXF1_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF1_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF1_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF1 */ +#define USB_DIEPTXF1_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF1_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF1 */ + +/* Bit fields for USB DIEPTXF2 */ + +#define _USB_DIEPTXF2_RESETVALUE 0x02000600UL /* Default value for USB_DIEPTXF2 */ +#define _USB_DIEPTXF2_MASK 0x03FF07FFUL /* Mask for USB_DIEPTXF2 */ + +#define _USB_DIEPTXF2_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF2_INEPNTXFSTADDR_MASK 0x7FFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF2_INEPNTXFSTADDR_DEFAULT 0x00000600UL /* Mode DEFAULT for USB_DIEPTXF2 */ +#define USB_DIEPTXF2_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF2_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF2 */ +#define _USB_DIEPTXF2_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF2_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF2_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF2 */ +#define USB_DIEPTXF2_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF2_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF2 */ + +/* Bit fields for USB DIEPTXF3 */ + +#define _USB_DIEPTXF3_RESETVALUE 0x02000800UL /* Default value for USB_DIEPTXF3 */ +#define _USB_DIEPTXF3_MASK 0x03FF0FFFUL /* Mask for USB_DIEPTXF3 */ + +#define _USB_DIEPTXF3_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF3_INEPNTXFSTADDR_MASK 0xFFFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF3_INEPNTXFSTADDR_DEFAULT 0x00000800UL /* Mode DEFAULT for USB_DIEPTXF3 */ +#define USB_DIEPTXF3_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF3_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF3 */ +#define _USB_DIEPTXF3_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF3_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF3_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF3 */ +#define USB_DIEPTXF3_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF3_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF3 */ + +/* Bit fields for USB DIEPTXF4 */ + +#define _USB_DIEPTXF4_RESETVALUE 0x02000A00UL /* Default value for USB_DIEPTXF4 */ +#define _USB_DIEPTXF4_MASK 0x03FF0FFFUL /* Mask for USB_DIEPTXF4 */ + +#define _USB_DIEPTXF4_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF4_INEPNTXFSTADDR_MASK 0xFFFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF4_INEPNTXFSTADDR_DEFAULT 0x00000A00UL /* Mode DEFAULT for USB_DIEPTXF4 */ +#define USB_DIEPTXF4_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF4_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF4 */ +#define _USB_DIEPTXF4_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF4_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF4_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF4 */ +#define USB_DIEPTXF4_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF4_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF4 */ + +/* Bit fields for USB DIEPTXF5 */ + +#define _USB_DIEPTXF5_RESETVALUE 0x02000C00UL /* Default value for USB_DIEPTXF5 */ +#define _USB_DIEPTXF5_MASK 0x03FF0FFFUL /* Mask for USB_DIEPTXF5 */ + +#define _USB_DIEPTXF5_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF5_INEPNTXFSTADDR_MASK 0xFFFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF5_INEPNTXFSTADDR_DEFAULT 0x00000C00UL /* Mode DEFAULT for USB_DIEPTXF5 */ +#define USB_DIEPTXF5_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF5_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF5 */ +#define _USB_DIEPTXF5_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF5_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF5_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF5 */ +#define USB_DIEPTXF5_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF5_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF5 */ + +/* Bit fields for USB DIEPTXF6 */ + +#define _USB_DIEPTXF6_RESETVALUE 0x02000E00UL /* Default value for USB_DIEPTXF6 */ +#define _USB_DIEPTXF6_MASK 0x03FF0FFFUL /* Mask for USB_DIEPTXF6 */ + +#define _USB_DIEPTXF6_INEPNTXFSTADDR_SHIFT 0 /* Shift value for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF6_INEPNTXFSTADDR_MASK 0xFFFUL /* Bit mask for USB_INEPNTXFSTADDR */ +#define _USB_DIEPTXF6_INEPNTXFSTADDR_DEFAULT 0x00000E00UL /* Mode DEFAULT for USB_DIEPTXF6 */ +#define USB_DIEPTXF6_INEPNTXFSTADDR_DEFAULT (_USB_DIEPTXF6_INEPNTXFSTADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXF6 */ +#define _USB_DIEPTXF6_INEPNTXFDEP_SHIFT 16 /* Shift value for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF6_INEPNTXFDEP_MASK 0x3FF0000UL /* Bit mask for USB_INEPNTXFDEP */ +#define _USB_DIEPTXF6_INEPNTXFDEP_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXF6 */ +#define USB_DIEPTXF6_INEPNTXFDEP_DEFAULT (_USB_DIEPTXF6_INEPNTXFDEP_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPTXF6 */ + +/* Bit fields for USB HCFG */ + +#define _USB_HCFG_RESETVALUE 0x00200000UL /* Default value for USB_HCFG */ +#define _USB_HCFG_MASK 0x8000FF87UL /* Mask for USB_HCFG */ + +#define _USB_HCFG_FSLSPCLKSEL_SHIFT 0 /* Shift value for USB_FSLSPCLKSEL */ +#define _USB_HCFG_FSLSPCLKSEL_MASK 0x3UL /* Bit mask for USB_FSLSPCLKSEL */ +#define _USB_HCFG_FSLSPCLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HCFG */ +#define _USB_HCFG_FSLSPCLKSEL_DIV1 0x00000001UL /* Mode DIV1 for USB_HCFG */ +#define _USB_HCFG_FSLSPCLKSEL_DIV8 0x00000002UL /* Mode DIV8 for USB_HCFG */ +#define USB_HCFG_FSLSPCLKSEL_DEFAULT (_USB_HCFG_FSLSPCLKSEL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HCFG */ +#define USB_HCFG_FSLSPCLKSEL_DIV1 (_USB_HCFG_FSLSPCLKSEL_DIV1 << 0) /* Shifted mode DIV1 for USB_HCFG */ +#define USB_HCFG_FSLSPCLKSEL_DIV8 (_USB_HCFG_FSLSPCLKSEL_DIV8 << 0) /* Shifted mode DIV8 for USB_HCFG */ +#define USB_HCFG_FSLSSUPP (0x1UL << 2) /* FS- and LS-Only Support */ +#define _USB_HCFG_FSLSSUPP_SHIFT 2 /* Shift value for USB_FSLSSUPP */ +#define _USB_HCFG_FSLSSUPP_MASK 0x4UL /* Bit mask for USB_FSLSSUPP */ +#define _USB_HCFG_FSLSSUPP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HCFG */ +#define _USB_HCFG_FSLSSUPP_HSFSLS 0x00000000UL /* Mode HSFSLS for USB_HCFG */ +#define _USB_HCFG_FSLSSUPP_FSLS 0x00000001UL /* Mode FSLS for USB_HCFG */ +#define USB_HCFG_FSLSSUPP_DEFAULT (_USB_HCFG_FSLSSUPP_DEFAULT << 2) /* Shifted mode DEFAULT for USB_HCFG */ +#define USB_HCFG_FSLSSUPP_HSFSLS (_USB_HCFG_FSLSSUPP_HSFSLS << 2) /* Shifted mode HSFSLS for USB_HCFG */ +#define USB_HCFG_FSLSSUPP_FSLS (_USB_HCFG_FSLSSUPP_FSLS << 2) /* Shifted mode FSLS for USB_HCFG */ +#define USB_HCFG_ENA32KHZS (0x1UL << 7) /* Enable 32 KHz Suspend mode */ +#define _USB_HCFG_ENA32KHZS_SHIFT 7 /* Shift value for USB_ENA32KHZS */ +#define _USB_HCFG_ENA32KHZS_MASK 0x80UL /* Bit mask for USB_ENA32KHZS */ +#define _USB_HCFG_ENA32KHZS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HCFG */ +#define USB_HCFG_ENA32KHZS_DEFAULT (_USB_HCFG_ENA32KHZS_DEFAULT << 7) /* Shifted mode DEFAULT for USB_HCFG */ +#define _USB_HCFG_RESVALID_SHIFT 8 /* Shift value for USB_RESVALID */ +#define _USB_HCFG_RESVALID_MASK 0xFF00UL /* Bit mask for USB_RESVALID */ +#define _USB_HCFG_RESVALID_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HCFG */ +#define USB_HCFG_RESVALID_DEFAULT (_USB_HCFG_RESVALID_DEFAULT << 8) /* Shifted mode DEFAULT for USB_HCFG */ +#define USB_HCFG_MODECHTIMEN (0x1UL << 31) /* Mode Change Time */ +#define _USB_HCFG_MODECHTIMEN_SHIFT 31 /* Shift value for USB_MODECHTIMEN */ +#define _USB_HCFG_MODECHTIMEN_MASK 0x80000000UL /* Bit mask for USB_MODECHTIMEN */ +#define _USB_HCFG_MODECHTIMEN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HCFG */ +#define USB_HCFG_MODECHTIMEN_DEFAULT (_USB_HCFG_MODECHTIMEN_DEFAULT << 31) /* Shifted mode DEFAULT for USB_HCFG */ + +/* Bit fields for USB HFIR */ + +#define _USB_HFIR_RESETVALUE 0x000017D7UL /* Default value for USB_HFIR */ +#define _USB_HFIR_MASK 0x0001FFFFUL /* Mask for USB_HFIR */ + +#define _USB_HFIR_FRINT_SHIFT 0 /* Shift value for USB_FRINT */ +#define _USB_HFIR_FRINT_MASK 0xFFFFUL /* Bit mask for USB_FRINT */ +#define _USB_HFIR_FRINT_DEFAULT 0x000017D7UL /* Mode DEFAULT for USB_HFIR */ +#define USB_HFIR_FRINT_DEFAULT (_USB_HFIR_FRINT_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HFIR */ +#define USB_HFIR_HFIRRLDCTRL (0x1UL << 16) /* Reload Control */ +#define _USB_HFIR_HFIRRLDCTRL_SHIFT 16 /* Shift value for USB_HFIRRLDCTRL */ +#define _USB_HFIR_HFIRRLDCTRL_MASK 0x10000UL /* Bit mask for USB_HFIRRLDCTRL */ +#define _USB_HFIR_HFIRRLDCTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HFIR */ +#define _USB_HFIR_HFIRRLDCTRL_STATIC 0x00000000UL /* Mode STATIC for USB_HFIR */ +#define _USB_HFIR_HFIRRLDCTRL_DYNAMIC 0x00000001UL /* Mode DYNAMIC for USB_HFIR */ +#define USB_HFIR_HFIRRLDCTRL_DEFAULT (_USB_HFIR_HFIRRLDCTRL_DEFAULT << 16) /* Shifted mode DEFAULT for USB_HFIR */ +#define USB_HFIR_HFIRRLDCTRL_STATIC (_USB_HFIR_HFIRRLDCTRL_STATIC << 16) /* Shifted mode STATIC for USB_HFIR */ +#define USB_HFIR_HFIRRLDCTRL_DYNAMIC (_USB_HFIR_HFIRRLDCTRL_DYNAMIC << 16) /* Shifted mode DYNAMIC for USB_HFIR */ + +/* Bit fields for USB HFNUM */ + +#define _USB_HFNUM_RESETVALUE 0x00003FFFUL /* Default value for USB_HFNUM */ +#define _USB_HFNUM_MASK 0xFFFFFFFFUL /* Mask for USB_HFNUM */ + +#define _USB_HFNUM_FRNUM_SHIFT 0 /* Shift value for USB_FRNUM */ +#define _USB_HFNUM_FRNUM_MASK 0xFFFFUL /* Bit mask for USB_FRNUM */ +#define _USB_HFNUM_FRNUM_DEFAULT 0x00003FFFUL /* Mode DEFAULT for USB_HFNUM */ +#define USB_HFNUM_FRNUM_DEFAULT (_USB_HFNUM_FRNUM_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HFNUM */ +#define _USB_HFNUM_FRREM_SHIFT 16 /* Shift value for USB_FRREM */ +#define _USB_HFNUM_FRREM_MASK 0xFFFF0000UL /* Bit mask for USB_FRREM */ +#define _USB_HFNUM_FRREM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HFNUM */ +#define USB_HFNUM_FRREM_DEFAULT (_USB_HFNUM_FRREM_DEFAULT << 16) /* Shifted mode DEFAULT for USB_HFNUM */ + +/* Bit fields for USB HPTXSTS */ + +#define _USB_HPTXSTS_RESETVALUE 0x00080200UL /* Default value for USB_HPTXSTS */ +#define _USB_HPTXSTS_MASK 0xFFFFFFFFUL /* Mask for USB_HPTXSTS */ + +#define _USB_HPTXSTS_PTXFSPCAVAIL_SHIFT 0 /* Shift value for USB_PTXFSPCAVAIL */ +#define _USB_HPTXSTS_PTXFSPCAVAIL_MASK 0xFFFFUL /* Bit mask for USB_PTXFSPCAVAIL */ +#define _USB_HPTXSTS_PTXFSPCAVAIL_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_HPTXSTS */ +#define USB_HPTXSTS_PTXFSPCAVAIL_DEFAULT (_USB_HPTXSTS_PTXFSPCAVAIL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HPTXSTS */ +#define _USB_HPTXSTS_PTXQSPCAVAIL_SHIFT 16 /* Shift value for USB_PTXQSPCAVAIL */ +#define _USB_HPTXSTS_PTXQSPCAVAIL_MASK 0xFF0000UL /* Bit mask for USB_PTXQSPCAVAIL */ +#define _USB_HPTXSTS_PTXQSPCAVAIL_DEFAULT 0x00000008UL /* Mode DEFAULT for USB_HPTXSTS */ +#define USB_HPTXSTS_PTXQSPCAVAIL_DEFAULT (_USB_HPTXSTS_PTXQSPCAVAIL_DEFAULT << 16) /* Shifted mode DEFAULT for USB_HPTXSTS */ +#define _USB_HPTXSTS_PTXQTOP_SHIFT 24 /* Shift value for USB_PTXQTOP */ +#define _USB_HPTXSTS_PTXQTOP_MASK 0xFF000000UL /* Bit mask for USB_PTXQTOP */ +#define _USB_HPTXSTS_PTXQTOP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPTXSTS */ +#define USB_HPTXSTS_PTXQTOP_DEFAULT (_USB_HPTXSTS_PTXQTOP_DEFAULT << 24) /* Shifted mode DEFAULT for USB_HPTXSTS */ + +/* Bit fields for USB HAINT */ + +#define _USB_HAINT_RESETVALUE 0x00000000UL /* Default value for USB_HAINT */ +#define _USB_HAINT_MASK 0x00003FFFUL /* Mask for USB_HAINT */ + +#define _USB_HAINT_HAINT_SHIFT 0 /* Shift value for USB_HAINT */ +#define _USB_HAINT_HAINT_MASK 0x3FFFUL /* Bit mask for USB_HAINT */ +#define _USB_HAINT_HAINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HAINT */ +#define USB_HAINT_HAINT_DEFAULT (_USB_HAINT_HAINT_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HAINT */ +#define USB_HAINT(n) (1UL << ((n) + _USB_HAINT_HAINT_SHIFT)) /* Channel n interrupt */ + +/* Bit fields for USB HAINTMSK */ + +#define _USB_HAINTMSK_RESETVALUE 0x00000000UL /* Default value for USB_HAINTMSK */ +#define _USB_HAINTMSK_MASK 0x00003FFFUL /* Mask for USB_HAINTMSK */ + +#define _USB_HAINTMSK_HAINTMSK_SHIFT 0 /* Shift value for USB_HAINTMSK */ +#define _USB_HAINTMSK_HAINTMSK_MASK 0x3FFFUL /* Bit mask for USB_HAINTMSK */ +#define _USB_HAINTMSK_HAINTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HAINTMSK */ +#define USB_HAINTMSK_HAINTMSK_DEFAULT (_USB_HAINTMSK_HAINTMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HAINTMSK */ + +/* Bit fields for USB HPRT */ + +#define _USB_HPRT_RESETVALUE 0x00000000UL /* Default value for USB_HPRT */ +#define _USB_HPRT_MASK 0x0007FDFFUL /* Mask for USB_HPRT */ + +#define USB_HPRT_PRTCONNSTS (0x1UL << 0) /* Port Connect Status */ +#define _USB_HPRT_PRTCONNSTS_SHIFT 0 /* Shift value for USB_PRTCONNSTS */ +#define _USB_HPRT_PRTCONNSTS_MASK 0x1UL /* Bit mask for USB_PRTCONNSTS */ +#define _USB_HPRT_PRTCONNSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTCONNSTS_DEFAULT (_USB_HPRT_PRTCONNSTS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTCONNDET (0x1UL << 1) /* Port Connect Detected */ +#define _USB_HPRT_PRTCONNDET_SHIFT 1 /* Shift value for USB_PRTCONNDET */ +#define _USB_HPRT_PRTCONNDET_MASK 0x2UL /* Bit mask for USB_PRTCONNDET */ +#define _USB_HPRT_PRTCONNDET_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTCONNDET_DEFAULT (_USB_HPRT_PRTCONNDET_DEFAULT << 1) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTENA (0x1UL << 2) /* Port Enable */ +#define _USB_HPRT_PRTENA_SHIFT 2 /* Shift value for USB_PRTENA */ +#define _USB_HPRT_PRTENA_MASK 0x4UL /* Bit mask for USB_PRTENA */ +#define _USB_HPRT_PRTENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTENA_DEFAULT (_USB_HPRT_PRTENA_DEFAULT << 2) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTENCHNG (0x1UL << 3) /* Port Enable/Disable Change */ +#define _USB_HPRT_PRTENCHNG_SHIFT 3 /* Shift value for USB_PRTENCHNG */ +#define _USB_HPRT_PRTENCHNG_MASK 0x8UL /* Bit mask for USB_PRTENCHNG */ +#define _USB_HPRT_PRTENCHNG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTENCHNG_DEFAULT (_USB_HPRT_PRTENCHNG_DEFAULT << 3) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTOVRCURRACT (0x1UL << 4) /* Port Overcurrent Active */ +#define _USB_HPRT_PRTOVRCURRACT_SHIFT 4 /* Shift value for USB_PRTOVRCURRACT */ +#define _USB_HPRT_PRTOVRCURRACT_MASK 0x10UL /* Bit mask for USB_PRTOVRCURRACT */ +#define _USB_HPRT_PRTOVRCURRACT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTOVRCURRACT_DEFAULT (_USB_HPRT_PRTOVRCURRACT_DEFAULT << 4) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTOVRCURRCHNG (0x1UL << 5) /* Port Overcurrent Change */ +#define _USB_HPRT_PRTOVRCURRCHNG_SHIFT 5 /* Shift value for USB_PRTOVRCURRCHNG */ +#define _USB_HPRT_PRTOVRCURRCHNG_MASK 0x20UL /* Bit mask for USB_PRTOVRCURRCHNG */ +#define _USB_HPRT_PRTOVRCURRCHNG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTOVRCURRCHNG_DEFAULT (_USB_HPRT_PRTOVRCURRCHNG_DEFAULT << 5) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTRES (0x1UL << 6) /* Port Resume */ +#define _USB_HPRT_PRTRES_SHIFT 6 /* Shift value for USB_PRTRES */ +#define _USB_HPRT_PRTRES_MASK 0x40UL /* Bit mask for USB_PRTRES */ +#define _USB_HPRT_PRTRES_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTRES_DEFAULT (_USB_HPRT_PRTRES_DEFAULT << 6) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTSUSP (0x1UL << 7) /* Port Suspend */ +#define _USB_HPRT_PRTSUSP_SHIFT 7 /* Shift value for USB_PRTSUSP */ +#define _USB_HPRT_PRTSUSP_MASK 0x80UL /* Bit mask for USB_PRTSUSP */ +#define _USB_HPRT_PRTSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTSUSP_DEFAULT (_USB_HPRT_PRTSUSP_DEFAULT << 7) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTRST (0x1UL << 8) /* Port Reset */ +#define _USB_HPRT_PRTRST_SHIFT 8 /* Shift value for USB_PRTRST */ +#define _USB_HPRT_PRTRST_MASK 0x100UL /* Bit mask for USB_PRTRST */ +#define _USB_HPRT_PRTRST_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTRST_DEFAULT (_USB_HPRT_PRTRST_DEFAULT << 8) /* Shifted mode DEFAULT for USB_HPRT */ +#define _USB_HPRT_PRTLNSTS_SHIFT 10 /* Shift value for USB_PRTLNSTS */ +#define _USB_HPRT_PRTLNSTS_MASK 0xC00UL /* Bit mask for USB_PRTLNSTS */ +#define _USB_HPRT_PRTLNSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTLNSTS_DEFAULT (_USB_HPRT_PRTLNSTS_DEFAULT << 10) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTPWR (0x1UL << 12) /* Port Power */ +#define _USB_HPRT_PRTPWR_SHIFT 12 /* Shift value for USB_PRTPWR */ +#define _USB_HPRT_PRTPWR_MASK 0x1000UL /* Bit mask for USB_PRTPWR */ +#define _USB_HPRT_PRTPWR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define _USB_HPRT_PRTPWR_OFF 0x00000000UL /* Mode OFF for USB_HPRT */ +#define _USB_HPRT_PRTPWR_ON 0x00000001UL /* Mode ON for USB_HPRT */ +#define USB_HPRT_PRTPWR_DEFAULT (_USB_HPRT_PRTPWR_DEFAULT << 12) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTPWR_OFF (_USB_HPRT_PRTPWR_OFF << 12) /* Shifted mode OFF for USB_HPRT */ +#define USB_HPRT_PRTPWR_ON (_USB_HPRT_PRTPWR_ON << 12) /* Shifted mode ON for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_SHIFT 13 /* Shift value for USB_PRTTSTCTL */ +#define _USB_HPRT_PRTTSTCTL_MASK 0x1E000UL /* Bit mask for USB_PRTTSTCTL */ +#define _USB_HPRT_PRTTSTCTL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_DISABLE 0x00000000UL /* Mode DISABLE for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_J 0x00000001UL /* Mode J for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_K 0x00000002UL /* Mode K for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_SE0NAK 0x00000003UL /* Mode SE0NAK for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_PACKET 0x00000004UL /* Mode PACKET for USB_HPRT */ +#define _USB_HPRT_PRTTSTCTL_FORCE 0x00000005UL /* Mode FORCE for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_DEFAULT (_USB_HPRT_PRTTSTCTL_DEFAULT << 13) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_DISABLE (_USB_HPRT_PRTTSTCTL_DISABLE << 13) /* Shifted mode DISABLE for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_J (_USB_HPRT_PRTTSTCTL_J << 13) /* Shifted mode J for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_K (_USB_HPRT_PRTTSTCTL_K << 13) /* Shifted mode K for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_SE0NAK (_USB_HPRT_PRTTSTCTL_SE0NAK << 13) /* Shifted mode SE0NAK for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_PACKET (_USB_HPRT_PRTTSTCTL_PACKET << 13) /* Shifted mode PACKET for USB_HPRT */ +#define USB_HPRT_PRTTSTCTL_FORCE (_USB_HPRT_PRTTSTCTL_FORCE << 13) /* Shifted mode FORCE for USB_HPRT */ +#define _USB_HPRT_PRTSPD_SHIFT 17 /* Shift value for USB_PRTSPD */ +#define _USB_HPRT_PRTSPD_MASK 0x60000UL /* Bit mask for USB_PRTSPD */ +#define _USB_HPRT_PRTSPD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HPRT */ +#define _USB_HPRT_PRTSPD_HS 0x00000000UL /* Mode HS for USB_HPRT */ +#define _USB_HPRT_PRTSPD_FS 0x00000001UL /* Mode FS for USB_HPRT */ +#define _USB_HPRT_PRTSPD_LS 0x00000002UL /* Mode LS for USB_HPRT */ +#define USB_HPRT_PRTSPD_DEFAULT (_USB_HPRT_PRTSPD_DEFAULT << 17) /* Shifted mode DEFAULT for USB_HPRT */ +#define USB_HPRT_PRTSPD_HS (_USB_HPRT_PRTSPD_HS << 17) /* Shifted mode HS for USB_HPRT */ +#define USB_HPRT_PRTSPD_FS (_USB_HPRT_PRTSPD_FS << 17) /* Shifted mode FS for USB_HPRT */ +#define USB_HPRT_PRTSPD_LS (_USB_HPRT_PRTSPD_LS << 17) /* Shifted mode LS for USB_HPRT */ + +/* Bit fields for USB HC_CHAR */ + +#define _USB_HC_CHAR_RESETVALUE 0x00000000UL /* Default value for USB_HC_CHAR */ +#define _USB_HC_CHAR_MASK 0xFFFEFFFFUL /* Mask for USB_HC_CHAR */ + +#define _USB_HC_CHAR_MPS_SHIFT 0 /* Shift value for USB_MPS */ +#define _USB_HC_CHAR_MPS_MASK 0x7FFUL /* Bit mask for USB_MPS */ +#define _USB_HC_CHAR_MPS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_MPS_DEFAULT (_USB_HC_CHAR_MPS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPNUM_SHIFT 11 /* Shift value for USB_EPNUM */ +#define _USB_HC_CHAR_EPNUM_MASK 0x7800UL /* Bit mask for USB_EPNUM */ +#define _USB_HC_CHAR_EPNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPNUM_DEFAULT (_USB_HC_CHAR_EPNUM_DEFAULT << 11) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPDIR (0x1UL << 15) /* Endpoint Direction */ +#define _USB_HC_CHAR_EPDIR_SHIFT 15 /* Shift value for USB_EPDIR */ +#define _USB_HC_CHAR_EPDIR_MASK 0x8000UL /* Bit mask for USB_EPDIR */ +#define _USB_HC_CHAR_EPDIR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPDIR_OUT 0x00000000UL /* Mode OUT for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPDIR_IN 0x00000001UL /* Mode IN for USB_HC_CHAR */ +#define USB_HC_CHAR_EPDIR_DEFAULT (_USB_HC_CHAR_EPDIR_DEFAULT << 15) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPDIR_OUT (_USB_HC_CHAR_EPDIR_OUT << 15) /* Shifted mode OUT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPDIR_IN (_USB_HC_CHAR_EPDIR_IN << 15) /* Shifted mode IN for USB_HC_CHAR */ +#define USB_HC_CHAR_LSPDDEV (0x1UL << 17) /* Low-Speed Device */ +#define _USB_HC_CHAR_LSPDDEV_SHIFT 17 /* Shift value for USB_LSPDDEV */ +#define _USB_HC_CHAR_LSPDDEV_MASK 0x20000UL /* Bit mask for USB_LSPDDEV */ +#define _USB_HC_CHAR_LSPDDEV_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_LSPDDEV_DEFAULT (_USB_HC_CHAR_LSPDDEV_DEFAULT << 17) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPTYPE_SHIFT 18 /* Shift value for USB_EPTYPE */ +#define _USB_HC_CHAR_EPTYPE_MASK 0xC0000UL /* Bit mask for USB_EPTYPE */ +#define _USB_HC_CHAR_EPTYPE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPTYPE_CONTROL 0x00000000UL /* Mode CONTROL for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPTYPE_ISO 0x00000001UL /* Mode ISO for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPTYPE_BULK 0x00000002UL /* Mode BULK for USB_HC_CHAR */ +#define _USB_HC_CHAR_EPTYPE_INT 0x00000003UL /* Mode INT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPTYPE_DEFAULT (_USB_HC_CHAR_EPTYPE_DEFAULT << 18) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_EPTYPE_CONTROL (_USB_HC_CHAR_EPTYPE_CONTROL << 18) /* Shifted mode CONTROL for USB_HC_CHAR */ +#define USB_HC_CHAR_EPTYPE_ISO (_USB_HC_CHAR_EPTYPE_ISO << 18) /* Shifted mode ISO for USB_HC_CHAR */ +#define USB_HC_CHAR_EPTYPE_BULK (_USB_HC_CHAR_EPTYPE_BULK << 18) /* Shifted mode BULK for USB_HC_CHAR */ +#define USB_HC_CHAR_EPTYPE_INT (_USB_HC_CHAR_EPTYPE_INT << 18) /* Shifted mode INT for USB_HC_CHAR */ +#define _USB_HC_CHAR_MC_SHIFT 20 /* Shift value for USB_MC */ +#define _USB_HC_CHAR_MC_MASK 0x300000UL /* Bit mask for USB_MC */ +#define _USB_HC_CHAR_MC_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_MC_DEFAULT (_USB_HC_CHAR_MC_DEFAULT << 20) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define _USB_HC_CHAR_DEVADDR_SHIFT 22 /* Shift value for USB_DEVADDR */ +#define _USB_HC_CHAR_DEVADDR_MASK 0x1FC00000UL /* Bit mask for USB_DEVADDR */ +#define _USB_HC_CHAR_DEVADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_DEVADDR_DEFAULT (_USB_HC_CHAR_DEVADDR_DEFAULT << 22) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_ODDFRM (0x1UL << 29) /* Odd Frame */ +#define _USB_HC_CHAR_ODDFRM_SHIFT 29 /* Shift value for USB_ODDFRM */ +#define _USB_HC_CHAR_ODDFRM_MASK 0x20000000UL /* Bit mask for USB_ODDFRM */ +#define _USB_HC_CHAR_ODDFRM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_ODDFRM_DEFAULT (_USB_HC_CHAR_ODDFRM_DEFAULT << 29) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_CHDIS (0x1UL << 30) /* Channel Disable */ +#define _USB_HC_CHAR_CHDIS_SHIFT 30 /* Shift value for USB_CHDIS */ +#define _USB_HC_CHAR_CHDIS_MASK 0x40000000UL /* Bit mask for USB_CHDIS */ +#define _USB_HC_CHAR_CHDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_CHDIS_DEFAULT (_USB_HC_CHAR_CHDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_CHENA (0x1UL << 31) /* Channel Enable */ +#define _USB_HC_CHAR_CHENA_SHIFT 31 /* Shift value for USB_CHENA */ +#define _USB_HC_CHAR_CHENA_MASK 0x80000000UL /* Bit mask for USB_CHENA */ +#define _USB_HC_CHAR_CHENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_CHAR */ +#define USB_HC_CHAR_CHENA_DEFAULT (_USB_HC_CHAR_CHENA_DEFAULT << 31) /* Shifted mode DEFAULT for USB_HC_CHAR */ + +/* Bit fields for USB HC_INT */ + +#define _USB_HC_INT_RESETVALUE 0x00000000UL /* Default value for USB_HC_INT */ +#define _USB_HC_INT_MASK 0x000007BFUL /* Mask for USB_HC_INT */ + +#define USB_HC_INT_XFERCOMPL (0x1UL << 0) /* Transfer Completed */ +#define _USB_HC_INT_XFERCOMPL_SHIFT 0 /* Shift value for USB_XFERCOMPL */ +#define _USB_HC_INT_XFERCOMPL_MASK 0x1UL /* Bit mask for USB_XFERCOMPL */ +#define _USB_HC_INT_XFERCOMPL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_XFERCOMPL_DEFAULT (_USB_HC_INT_XFERCOMPL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_CHHLTD (0x1UL << 1) /* Channel Halted */ +#define _USB_HC_INT_CHHLTD_SHIFT 1 /* Shift value for USB_CHHLTD */ +#define _USB_HC_INT_CHHLTD_MASK 0x2UL /* Bit mask for USB_CHHLTD */ +#define _USB_HC_INT_CHHLTD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_CHHLTD_DEFAULT (_USB_HC_INT_CHHLTD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_AHBERR (0x1UL << 2) /* AHB Error */ +#define _USB_HC_INT_AHBERR_SHIFT 2 /* Shift value for USB_AHBERR */ +#define _USB_HC_INT_AHBERR_MASK 0x4UL /* Bit mask for USB_AHBERR */ +#define _USB_HC_INT_AHBERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_AHBERR_DEFAULT (_USB_HC_INT_AHBERR_DEFAULT << 2) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_STALL (0x1UL << 3) /* STALL Response Received Interrupt */ +#define _USB_HC_INT_STALL_SHIFT 3 /* Shift value for USB_STALL */ +#define _USB_HC_INT_STALL_MASK 0x8UL /* Bit mask for USB_STALL */ +#define _USB_HC_INT_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_STALL_DEFAULT (_USB_HC_INT_STALL_DEFAULT << 3) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_NAK (0x1UL << 4) /* NAK Response Received Interrupt */ +#define _USB_HC_INT_NAK_SHIFT 4 /* Shift value for USB_NAK */ +#define _USB_HC_INT_NAK_MASK 0x10UL /* Bit mask for USB_NAK */ +#define _USB_HC_INT_NAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_NAK_DEFAULT (_USB_HC_INT_NAK_DEFAULT << 4) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_ACK (0x1UL << 5) /* ACK Response Received/Transmitted Interrupt */ +#define _USB_HC_INT_ACK_SHIFT 5 /* Shift value for USB_ACK */ +#define _USB_HC_INT_ACK_MASK 0x20UL /* Bit mask for USB_ACK */ +#define _USB_HC_INT_ACK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_ACK_DEFAULT (_USB_HC_INT_ACK_DEFAULT << 5) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_XACTERR (0x1UL << 7) /* Transaction Error */ +#define _USB_HC_INT_XACTERR_SHIFT 7 /* Shift value for USB_XACTERR */ +#define _USB_HC_INT_XACTERR_MASK 0x80UL /* Bit mask for USB_XACTERR */ +#define _USB_HC_INT_XACTERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_XACTERR_DEFAULT (_USB_HC_INT_XACTERR_DEFAULT << 7) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_BBLERR (0x1UL << 8) /* Babble Error */ +#define _USB_HC_INT_BBLERR_SHIFT 8 /* Shift value for USB_BBLERR */ +#define _USB_HC_INT_BBLERR_MASK 0x100UL /* Bit mask for USB_BBLERR */ +#define _USB_HC_INT_BBLERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_BBLERR_DEFAULT (_USB_HC_INT_BBLERR_DEFAULT << 8) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_FRMOVRUN (0x1UL << 9) /* Frame Overrun */ +#define _USB_HC_INT_FRMOVRUN_SHIFT 9 /* Shift value for USB_FRMOVRUN */ +#define _USB_HC_INT_FRMOVRUN_MASK 0x200UL /* Bit mask for USB_FRMOVRUN */ +#define _USB_HC_INT_FRMOVRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_FRMOVRUN_DEFAULT (_USB_HC_INT_FRMOVRUN_DEFAULT << 9) /* Shifted mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_DATATGLERR (0x1UL << 10) /* Data Toggle Error */ +#define _USB_HC_INT_DATATGLERR_SHIFT 10 /* Shift value for USB_DATATGLERR */ +#define _USB_HC_INT_DATATGLERR_MASK 0x400UL /* Bit mask for USB_DATATGLERR */ +#define _USB_HC_INT_DATATGLERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INT */ +#define USB_HC_INT_DATATGLERR_DEFAULT (_USB_HC_INT_DATATGLERR_DEFAULT << 10) /* Shifted mode DEFAULT for USB_HC_INT */ + +/* Bit fields for USB HC_INTMSK */ + +#define _USB_HC_INTMSK_RESETVALUE 0x00000000UL /* Default value for USB_HC_INTMSK */ +#define _USB_HC_INTMSK_MASK 0x000007BFUL /* Mask for USB_HC_INTMSK */ + +#define USB_HC_INTMSK_XFERCOMPLMSK (0x1UL << 0) /* Transfer Completed Mask */ +#define _USB_HC_INTMSK_XFERCOMPLMSK_SHIFT 0 /* Shift value for USB_XFERCOMPLMSK */ +#define _USB_HC_INTMSK_XFERCOMPLMSK_MASK 0x1UL /* Bit mask for USB_XFERCOMPLMSK */ +#define _USB_HC_INTMSK_XFERCOMPLMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_XFERCOMPLMSK_DEFAULT (_USB_HC_INTMSK_XFERCOMPLMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_CHHLTDMSK (0x1UL << 1) /* Channel Halted Mask */ +#define _USB_HC_INTMSK_CHHLTDMSK_SHIFT 1 /* Shift value for USB_CHHLTDMSK */ +#define _USB_HC_INTMSK_CHHLTDMSK_MASK 0x2UL /* Bit mask for USB_CHHLTDMSK */ +#define _USB_HC_INTMSK_CHHLTDMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_CHHLTDMSK_DEFAULT (_USB_HC_INTMSK_CHHLTDMSK_DEFAULT << 1) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_AHBERRMSK (0x1UL << 2) /* AHB Error Mask */ +#define _USB_HC_INTMSK_AHBERRMSK_SHIFT 2 /* Shift value for USB_AHBERRMSK */ +#define _USB_HC_INTMSK_AHBERRMSK_MASK 0x4UL /* Bit mask for USB_AHBERRMSK */ +#define _USB_HC_INTMSK_AHBERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_AHBERRMSK_DEFAULT (_USB_HC_INTMSK_AHBERRMSK_DEFAULT << 2) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_STALLMSK (0x1UL << 3) /* STALL Response Received Interrupt Mask */ +#define _USB_HC_INTMSK_STALLMSK_SHIFT 3 /* Shift value for USB_STALLMSK */ +#define _USB_HC_INTMSK_STALLMSK_MASK 0x8UL /* Bit mask for USB_STALLMSK */ +#define _USB_HC_INTMSK_STALLMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_STALLMSK_DEFAULT (_USB_HC_INTMSK_STALLMSK_DEFAULT << 3) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_NAKMSK (0x1UL << 4) /* NAK Response Received Interrupt Mask */ +#define _USB_HC_INTMSK_NAKMSK_SHIFT 4 /* Shift value for USB_NAKMSK */ +#define _USB_HC_INTMSK_NAKMSK_MASK 0x10UL /* Bit mask for USB_NAKMSK */ +#define _USB_HC_INTMSK_NAKMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_NAKMSK_DEFAULT (_USB_HC_INTMSK_NAKMSK_DEFAULT << 4) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_ACKMSK (0x1UL << 5) /* ACK Response Received/Transmitted Interrupt Mask */ +#define _USB_HC_INTMSK_ACKMSK_SHIFT 5 /* Shift value for USB_ACKMSK */ +#define _USB_HC_INTMSK_ACKMSK_MASK 0x20UL /* Bit mask for USB_ACKMSK */ +#define _USB_HC_INTMSK_ACKMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_ACKMSK_DEFAULT (_USB_HC_INTMSK_ACKMSK_DEFAULT << 5) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_XACTERRMSK (0x1UL << 7) /* Transaction Error Mask */ +#define _USB_HC_INTMSK_XACTERRMSK_SHIFT 7 /* Shift value for USB_XACTERRMSK */ +#define _USB_HC_INTMSK_XACTERRMSK_MASK 0x80UL /* Bit mask for USB_XACTERRMSK */ +#define _USB_HC_INTMSK_XACTERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_XACTERRMSK_DEFAULT (_USB_HC_INTMSK_XACTERRMSK_DEFAULT << 7) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_BBLERRMSK (0x1UL << 8) /* Babble Error Mask */ +#define _USB_HC_INTMSK_BBLERRMSK_SHIFT 8 /* Shift value for USB_BBLERRMSK */ +#define _USB_HC_INTMSK_BBLERRMSK_MASK 0x100UL /* Bit mask for USB_BBLERRMSK */ +#define _USB_HC_INTMSK_BBLERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_BBLERRMSK_DEFAULT (_USB_HC_INTMSK_BBLERRMSK_DEFAULT << 8) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_FRMOVRUNMSK (0x1UL << 9) /* Frame Overrun Mask */ +#define _USB_HC_INTMSK_FRMOVRUNMSK_SHIFT 9 /* Shift value for USB_FRMOVRUNMSK */ +#define _USB_HC_INTMSK_FRMOVRUNMSK_MASK 0x200UL /* Bit mask for USB_FRMOVRUNMSK */ +#define _USB_HC_INTMSK_FRMOVRUNMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_FRMOVRUNMSK_DEFAULT (_USB_HC_INTMSK_FRMOVRUNMSK_DEFAULT << 9) /* Shifted mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_DATATGLERRMSK (0x1UL << 10) /* Data Toggle Error Mask */ +#define _USB_HC_INTMSK_DATATGLERRMSK_SHIFT 10 /* Shift value for USB_DATATGLERRMSK */ +#define _USB_HC_INTMSK_DATATGLERRMSK_MASK 0x400UL /* Bit mask for USB_DATATGLERRMSK */ +#define _USB_HC_INTMSK_DATATGLERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_INTMSK */ +#define USB_HC_INTMSK_DATATGLERRMSK_DEFAULT (_USB_HC_INTMSK_DATATGLERRMSK_DEFAULT << 10) /* Shifted mode DEFAULT for USB_HC_INTMSK */ + +/* Bit fields for USB HC_TSIZ */ + +#define _USB_HC_TSIZ_RESETVALUE 0x00000000UL /* Default value for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_MASK 0x7FFFFFFFUL /* Mask for USB_HC_TSIZ */ + +#define _USB_HC_TSIZ_XFERSIZE_SHIFT 0 /* Shift value for USB_XFERSIZE */ +#define _USB_HC_TSIZ_XFERSIZE_MASK 0x7FFFFUL /* Bit mask for USB_XFERSIZE */ +#define _USB_HC_TSIZ_XFERSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_TSIZ */ +#define USB_HC_TSIZ_XFERSIZE_DEFAULT (_USB_HC_TSIZ_XFERSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PKTCNT_SHIFT 19 /* Shift value for USB_PKTCNT */ +#define _USB_HC_TSIZ_PKTCNT_MASK 0x1FF80000UL /* Bit mask for USB_PKTCNT */ +#define _USB_HC_TSIZ_PKTCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PKTCNT_DEFAULT (_USB_HC_TSIZ_PKTCNT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PID_SHIFT 29 /* Shift value for USB_PID */ +#define _USB_HC_TSIZ_PID_MASK 0x60000000UL /* Bit mask for USB_PID */ +#define _USB_HC_TSIZ_PID_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PID_DATA0 0x00000000UL /* Mode DATA0 for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PID_DATA2 0x00000001UL /* Mode DATA2 for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PID_DATA1 0x00000002UL /* Mode DATA1 for USB_HC_TSIZ */ +#define _USB_HC_TSIZ_PID_MDATA 0x00000003UL /* Mode MDATA for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PID_DEFAULT (_USB_HC_TSIZ_PID_DEFAULT << 29) /* Shifted mode DEFAULT for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PID_DATA0 (_USB_HC_TSIZ_PID_DATA0 << 29) /* Shifted mode DATA0 for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PID_DATA2 (_USB_HC_TSIZ_PID_DATA2 << 29) /* Shifted mode DATA2 for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PID_DATA1 (_USB_HC_TSIZ_PID_DATA1 << 29) /* Shifted mode DATA1 for USB_HC_TSIZ */ +#define USB_HC_TSIZ_PID_MDATA (_USB_HC_TSIZ_PID_MDATA << 29) /* Shifted mode MDATA for USB_HC_TSIZ */ + +/* Bit fields for USB HC_DMAADDR */ + +#define _USB_HC_DMAADDR_RESETVALUE 0x00000000UL /* Default value for USB_HC_DMAADDR */ +#define _USB_HC_DMAADDR_MASK 0xFFFFFFFFUL /* Mask for USB_HC_DMAADDR */ + +#define _USB_HC_DMAADDR_DMAADDR_SHIFT 0 /* Shift value for USB_DMAADDR */ +#define _USB_HC_DMAADDR_DMAADDR_MASK 0xFFFFFFFFUL /* Bit mask for USB_DMAADDR */ +#define _USB_HC_DMAADDR_DMAADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_HC_DMAADDR */ +#define USB_HC_DMAADDR_DMAADDR_DEFAULT (_USB_HC_DMAADDR_DMAADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_HC_DMAADDR */ + +/* Bit fields for USB DCFG */ + +#define _USB_DCFG_RESETVALUE 0x08200000UL /* Default value for USB_DCFG */ +#define _USB_DCFG_MASK 0xFC001FFFUL /* Mask for USB_DCFG */ + +#define _USB_DCFG_DEVSPD_SHIFT 0 /* Shift value for USB_DEVSPD */ +#define _USB_DCFG_DEVSPD_MASK 0x3UL /* Bit mask for USB_DEVSPD */ +#define _USB_DCFG_DEVSPD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCFG */ +#define _USB_DCFG_DEVSPD_LS 0x00000002UL /* Mode LS for USB_DCFG */ +#define _USB_DCFG_DEVSPD_FS 0x00000003UL /* Mode FS for USB_DCFG */ +#define USB_DCFG_DEVSPD_DEFAULT (_USB_DCFG_DEVSPD_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DCFG */ +#define USB_DCFG_DEVSPD_LS (_USB_DCFG_DEVSPD_LS << 0) /* Shifted mode LS for USB_DCFG */ +#define USB_DCFG_DEVSPD_FS (_USB_DCFG_DEVSPD_FS << 0) /* Shifted mode FS for USB_DCFG */ +#define USB_DCFG_NZSTSOUTHSHK (0x1UL << 2) /* Non-Zero-Length Status OUT Handshake */ +#define _USB_DCFG_NZSTSOUTHSHK_SHIFT 2 /* Shift value for USB_NZSTSOUTHSHK */ +#define _USB_DCFG_NZSTSOUTHSHK_MASK 0x4UL /* Bit mask for USB_NZSTSOUTHSHK */ +#define _USB_DCFG_NZSTSOUTHSHK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCFG */ +#define USB_DCFG_NZSTSOUTHSHK_DEFAULT (_USB_DCFG_NZSTSOUTHSHK_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DCFG */ +#define USB_DCFG_ENA32KHZSUSP (0x1UL << 3) /* Enable 32 KHz Suspend mode */ +#define _USB_DCFG_ENA32KHZSUSP_SHIFT 3 /* Shift value for USB_ENA32KHZSUSP */ +#define _USB_DCFG_ENA32KHZSUSP_MASK 0x8UL /* Bit mask for USB_ENA32KHZSUSP */ +#define _USB_DCFG_ENA32KHZSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCFG */ +#define USB_DCFG_ENA32KHZSUSP_DEFAULT (_USB_DCFG_ENA32KHZSUSP_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DCFG */ +#define _USB_DCFG_DEVADDR_SHIFT 4 /* Shift value for USB_DEVADDR */ +#define _USB_DCFG_DEVADDR_MASK 0x7F0UL /* Bit mask for USB_DEVADDR */ +#define _USB_DCFG_DEVADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCFG */ +#define USB_DCFG_DEVADDR_DEFAULT (_USB_DCFG_DEVADDR_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DCFG */ +#define _USB_DCFG_PERFRINT_SHIFT 11 /* Shift value for USB_PERFRINT */ +#define _USB_DCFG_PERFRINT_MASK 0x1800UL /* Bit mask for USB_PERFRINT */ +#define _USB_DCFG_PERFRINT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCFG */ +#define _USB_DCFG_PERFRINT_80PCNT 0x00000000UL /* Mode 80PCNT for USB_DCFG */ +#define _USB_DCFG_PERFRINT_85PCNT 0x00000001UL /* Mode 85PCNT for USB_DCFG */ +#define _USB_DCFG_PERFRINT_90PCNT 0x00000002UL /* Mode 90PCNT for USB_DCFG */ +#define _USB_DCFG_PERFRINT_95PCNT 0x00000003UL /* Mode 95PCNT for USB_DCFG */ +#define USB_DCFG_PERFRINT_DEFAULT (_USB_DCFG_PERFRINT_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DCFG */ +#define USB_DCFG_PERFRINT_80PCNT (_USB_DCFG_PERFRINT_80PCNT << 11) /* Shifted mode 80PCNT for USB_DCFG */ +#define USB_DCFG_PERFRINT_85PCNT (_USB_DCFG_PERFRINT_85PCNT << 11) /* Shifted mode 85PCNT for USB_DCFG */ +#define USB_DCFG_PERFRINT_90PCNT (_USB_DCFG_PERFRINT_90PCNT << 11) /* Shifted mode 90PCNT for USB_DCFG */ +#define USB_DCFG_PERFRINT_95PCNT (_USB_DCFG_PERFRINT_95PCNT << 11) /* Shifted mode 95PCNT for USB_DCFG */ +#define _USB_DCFG_RESVALID_SHIFT 26 /* Shift value for USB_RESVALID */ +#define _USB_DCFG_RESVALID_MASK 0xFC000000UL /* Bit mask for USB_RESVALID */ +#define _USB_DCFG_RESVALID_DEFAULT 0x00000002UL /* Mode DEFAULT for USB_DCFG */ +#define USB_DCFG_RESVALID_DEFAULT (_USB_DCFG_RESVALID_DEFAULT << 26) /* Shifted mode DEFAULT for USB_DCFG */ + +/* Bit fields for USB DCTL */ + +#define _USB_DCTL_RESETVALUE 0x00000000UL /* Default value for USB_DCTL */ +#define _USB_DCTL_MASK 0x00018FFFUL /* Mask for USB_DCTL */ + +#define USB_DCTL_RMTWKUPSIG (0x1UL << 0) /* Remote Wakeup Signaling */ +#define _USB_DCTL_RMTWKUPSIG_SHIFT 0 /* Shift value for USB_RMTWKUPSIG */ +#define _USB_DCTL_RMTWKUPSIG_MASK 0x1UL /* Bit mask for USB_RMTWKUPSIG */ +#define _USB_DCTL_RMTWKUPSIG_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_RMTWKUPSIG_DEFAULT (_USB_DCTL_RMTWKUPSIG_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_SFTDISCON (0x1UL << 1) /* Soft Disconnect */ +#define _USB_DCTL_SFTDISCON_SHIFT 1 /* Shift value for USB_SFTDISCON */ +#define _USB_DCTL_SFTDISCON_MASK 0x2UL /* Bit mask for USB_SFTDISCON */ +#define _USB_DCTL_SFTDISCON_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_SFTDISCON_DEFAULT (_USB_DCTL_SFTDISCON_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_GNPINNAKSTS (0x1UL << 2) /* Global Non-periodic IN NAK Status */ +#define _USB_DCTL_GNPINNAKSTS_SHIFT 2 /* Shift value for USB_GNPINNAKSTS */ +#define _USB_DCTL_GNPINNAKSTS_MASK 0x4UL /* Bit mask for USB_GNPINNAKSTS */ +#define _USB_DCTL_GNPINNAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_GNPINNAKSTS_DEFAULT (_USB_DCTL_GNPINNAKSTS_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_GOUTNAKSTS (0x1UL << 3) /* Global OUT NAK Status */ +#define _USB_DCTL_GOUTNAKSTS_SHIFT 3 /* Shift value for USB_GOUTNAKSTS */ +#define _USB_DCTL_GOUTNAKSTS_MASK 0x8UL /* Bit mask for USB_GOUTNAKSTS */ +#define _USB_DCTL_GOUTNAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_GOUTNAKSTS_DEFAULT (_USB_DCTL_GOUTNAKSTS_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DCTL */ +#define _USB_DCTL_TSTCTL_SHIFT 4 /* Shift value for USB_TSTCTL */ +#define _USB_DCTL_TSTCTL_MASK 0x70UL /* Bit mask for USB_TSTCTL */ +#define _USB_DCTL_TSTCTL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define _USB_DCTL_TSTCTL_DISABLE 0x00000000UL /* Mode DISABLE for USB_DCTL */ +#define _USB_DCTL_TSTCTL_J 0x00000001UL /* Mode J for USB_DCTL */ +#define _USB_DCTL_TSTCTL_K 0x00000002UL /* Mode K for USB_DCTL */ +#define _USB_DCTL_TSTCTL_SE0NAK 0x00000003UL /* Mode SE0NAK for USB_DCTL */ +#define _USB_DCTL_TSTCTL_PACKET 0x00000004UL /* Mode PACKET for USB_DCTL */ +#define _USB_DCTL_TSTCTL_FORCE 0x00000005UL /* Mode FORCE for USB_DCTL */ +#define USB_DCTL_TSTCTL_DEFAULT (_USB_DCTL_TSTCTL_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_TSTCTL_DISABLE (_USB_DCTL_TSTCTL_DISABLE << 4) /* Shifted mode DISABLE for USB_DCTL */ +#define USB_DCTL_TSTCTL_J (_USB_DCTL_TSTCTL_J << 4) /* Shifted mode J for USB_DCTL */ +#define USB_DCTL_TSTCTL_K (_USB_DCTL_TSTCTL_K << 4) /* Shifted mode K for USB_DCTL */ +#define USB_DCTL_TSTCTL_SE0NAK (_USB_DCTL_TSTCTL_SE0NAK << 4) /* Shifted mode SE0NAK for USB_DCTL */ +#define USB_DCTL_TSTCTL_PACKET (_USB_DCTL_TSTCTL_PACKET << 4) /* Shifted mode PACKET for USB_DCTL */ +#define USB_DCTL_TSTCTL_FORCE (_USB_DCTL_TSTCTL_FORCE << 4) /* Shifted mode FORCE for USB_DCTL */ +#define USB_DCTL_SGNPINNAK (0x1UL << 7) /* Set Global Non-periodic IN NAK */ +#define _USB_DCTL_SGNPINNAK_SHIFT 7 /* Shift value for USB_SGNPINNAK */ +#define _USB_DCTL_SGNPINNAK_MASK 0x80UL /* Bit mask for USB_SGNPINNAK */ +#define _USB_DCTL_SGNPINNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_SGNPINNAK_DEFAULT (_USB_DCTL_SGNPINNAK_DEFAULT << 7) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_CGNPINNAK (0x1UL << 8) /* Clear Global Non-periodic IN NAK */ +#define _USB_DCTL_CGNPINNAK_SHIFT 8 /* Shift value for USB_CGNPINNAK */ +#define _USB_DCTL_CGNPINNAK_MASK 0x100UL /* Bit mask for USB_CGNPINNAK */ +#define _USB_DCTL_CGNPINNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_CGNPINNAK_DEFAULT (_USB_DCTL_CGNPINNAK_DEFAULT << 8) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_SGOUTNAK (0x1UL << 9) /* Set Global OUT NAK */ +#define _USB_DCTL_SGOUTNAK_SHIFT 9 /* Shift value for USB_SGOUTNAK */ +#define _USB_DCTL_SGOUTNAK_MASK 0x200UL /* Bit mask for USB_SGOUTNAK */ +#define _USB_DCTL_SGOUTNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_SGOUTNAK_DEFAULT (_USB_DCTL_SGOUTNAK_DEFAULT << 9) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_CGOUTNAK (0x1UL << 10) /* Clear Global OUT NAK */ +#define _USB_DCTL_CGOUTNAK_SHIFT 10 /* Shift value for USB_CGOUTNAK */ +#define _USB_DCTL_CGOUTNAK_MASK 0x400UL /* Bit mask for USB_CGOUTNAK */ +#define _USB_DCTL_CGOUTNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_CGOUTNAK_DEFAULT (_USB_DCTL_CGOUTNAK_DEFAULT << 10) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_PWRONPRGDONE (0x1UL << 11) /* Power-On Programming Done */ +#define _USB_DCTL_PWRONPRGDONE_SHIFT 11 /* Shift value for USB_PWRONPRGDONE */ +#define _USB_DCTL_PWRONPRGDONE_MASK 0x800UL /* Bit mask for USB_PWRONPRGDONE */ +#define _USB_DCTL_PWRONPRGDONE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_PWRONPRGDONE_DEFAULT (_USB_DCTL_PWRONPRGDONE_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_IGNRFRMNUM (0x1UL << 15) /* Ignore Frame number For Isochronous End points */ +#define _USB_DCTL_IGNRFRMNUM_SHIFT 15 /* Shift value for USB_IGNRFRMNUM */ +#define _USB_DCTL_IGNRFRMNUM_MASK 0x8000UL /* Bit mask for USB_IGNRFRMNUM */ +#define _USB_DCTL_IGNRFRMNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_IGNRFRMNUM_DEFAULT (_USB_DCTL_IGNRFRMNUM_DEFAULT << 15) /* Shifted mode DEFAULT for USB_DCTL */ +#define USB_DCTL_NAKONBBLE (0x1UL << 16) /* NAK on Babble Error */ +#define _USB_DCTL_NAKONBBLE_SHIFT 16 /* Shift value for USB_NAKONBBLE */ +#define _USB_DCTL_NAKONBBLE_MASK 0x10000UL /* Bit mask for USB_NAKONBBLE */ +#define _USB_DCTL_NAKONBBLE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DCTL */ +#define USB_DCTL_NAKONBBLE_DEFAULT (_USB_DCTL_NAKONBBLE_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DCTL */ + +/* Bit fields for USB DSTS */ + +#define _USB_DSTS_RESETVALUE 0x00000002UL /* Default value for USB_DSTS */ +#define _USB_DSTS_MASK 0x003FFF0FUL /* Mask for USB_DSTS */ + +#define USB_DSTS_SUSPSTS (0x1UL << 0) /* Suspend Status */ +#define _USB_DSTS_SUSPSTS_SHIFT 0 /* Shift value for USB_SUSPSTS */ +#define _USB_DSTS_SUSPSTS_MASK 0x1UL /* Bit mask for USB_SUSPSTS */ +#define _USB_DSTS_SUSPSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DSTS */ +#define USB_DSTS_SUSPSTS_DEFAULT (_USB_DSTS_SUSPSTS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DSTS */ +#define _USB_DSTS_ENUMSPD_SHIFT 1 /* Shift value for USB_ENUMSPD */ +#define _USB_DSTS_ENUMSPD_MASK 0x6UL /* Bit mask for USB_ENUMSPD */ +#define _USB_DSTS_ENUMSPD_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_DSTS */ +#define _USB_DSTS_ENUMSPD_LS 0x00000002UL /* Mode LS for USB_DSTS */ +#define _USB_DSTS_ENUMSPD_FS 0x00000003UL /* Mode FS for USB_DSTS */ +#define USB_DSTS_ENUMSPD_DEFAULT (_USB_DSTS_ENUMSPD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DSTS */ +#define USB_DSTS_ENUMSPD_LS (_USB_DSTS_ENUMSPD_LS << 1) /* Shifted mode LS for USB_DSTS */ +#define USB_DSTS_ENUMSPD_FS (_USB_DSTS_ENUMSPD_FS << 1) /* Shifted mode FS for USB_DSTS */ +#define USB_DSTS_ERRTICERR (0x1UL << 3) /* Erratic Error */ +#define _USB_DSTS_ERRTICERR_SHIFT 3 /* Shift value for USB_ERRTICERR */ +#define _USB_DSTS_ERRTICERR_MASK 0x8UL /* Bit mask for USB_ERRTICERR */ +#define _USB_DSTS_ERRTICERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DSTS */ +#define USB_DSTS_ERRTICERR_DEFAULT (_USB_DSTS_ERRTICERR_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DSTS */ +#define _USB_DSTS_SOFFN_SHIFT 8 /* Shift value for USB_SOFFN */ +#define _USB_DSTS_SOFFN_MASK 0x3FFF00UL /* Bit mask for USB_SOFFN */ +#define _USB_DSTS_SOFFN_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DSTS */ +#define USB_DSTS_SOFFN_DEFAULT (_USB_DSTS_SOFFN_DEFAULT << 8) /* Shifted mode DEFAULT for USB_DSTS */ +#define _USB_DSTS_SOFFN_EVENODD_MASK 0x000100UL /* Bit mask for USB_SOFFN even/odd bit*/ +#define _USB_DSTS_SOFFN_EVEN 0 /* Frame number even */ +#define _USB_DSTS_SOFFN_ODD 1 /* Frame number odd */ +#define USB_DSTS_SOFFN_EVEN (_USB_DSTS_SOFFN_EVEN << 8) /* Frame number even */ +#define USB_DSTS_SOFFN_ODD (_USB_DSTS_SOFFN_ODD << 8) /* Frame number odd */ + +/* Bit fields for USB DIEPMSK */ + +#define _USB_DIEPMSK_RESETVALUE 0x00000000UL /* Default value for USB_DIEPMSK */ +#define _USB_DIEPMSK_MASK 0x0000215FUL /* Mask for USB_DIEPMSK */ + +#define USB_DIEPMSK_XFERCOMPLMSK (0x1UL << 0) /* Transfer Completed Interrupt Mask */ +#define _USB_DIEPMSK_XFERCOMPLMSK_SHIFT 0 /* Shift value for USB_XFERCOMPLMSK */ +#define _USB_DIEPMSK_XFERCOMPLMSK_MASK 0x1UL /* Bit mask for USB_XFERCOMPLMSK */ +#define _USB_DIEPMSK_XFERCOMPLMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_XFERCOMPLMSK_DEFAULT (_USB_DIEPMSK_XFERCOMPLMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_EPDISBLDMSK (0x1UL << 1) /* Endpoint Disabled Interrupt Mask */ +#define _USB_DIEPMSK_EPDISBLDMSK_SHIFT 1 /* Shift value for USB_EPDISBLDMSK */ +#define _USB_DIEPMSK_EPDISBLDMSK_MASK 0x2UL /* Bit mask for USB_EPDISBLDMSK */ +#define _USB_DIEPMSK_EPDISBLDMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_EPDISBLDMSK_DEFAULT (_USB_DIEPMSK_EPDISBLDMSK_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_AHBERRMSK (0x1UL << 2) /* AHB Error Mask */ +#define _USB_DIEPMSK_AHBERRMSK_SHIFT 2 /* Shift value for USB_AHBERRMSK */ +#define _USB_DIEPMSK_AHBERRMSK_MASK 0x4UL /* Bit mask for USB_AHBERRMSK */ +#define _USB_DIEPMSK_AHBERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_AHBERRMSK_DEFAULT (_USB_DIEPMSK_AHBERRMSK_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_TIMEOUTMSK (0x1UL << 3) /* Timeout Condition Mask */ +#define _USB_DIEPMSK_TIMEOUTMSK_SHIFT 3 /* Shift value for USB_TIMEOUTMSK */ +#define _USB_DIEPMSK_TIMEOUTMSK_MASK 0x8UL /* Bit mask for USB_TIMEOUTMSK */ +#define _USB_DIEPMSK_TIMEOUTMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_TIMEOUTMSK_DEFAULT (_USB_DIEPMSK_TIMEOUTMSK_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_INTKNTXFEMPMSK (0x1UL << 4) /* IN Token Received When TxFIFO Empty Mask */ +#define _USB_DIEPMSK_INTKNTXFEMPMSK_SHIFT 4 /* Shift value for USB_INTKNTXFEMPMSK */ +#define _USB_DIEPMSK_INTKNTXFEMPMSK_MASK 0x10UL /* Bit mask for USB_INTKNTXFEMPMSK */ +#define _USB_DIEPMSK_INTKNTXFEMPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_INTKNTXFEMPMSK_DEFAULT (_USB_DIEPMSK_INTKNTXFEMPMSK_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_INEPNAKEFFMSK (0x1UL << 6) /* IN Endpoint NAK Effective Mask */ +#define _USB_DIEPMSK_INEPNAKEFFMSK_SHIFT 6 /* Shift value for USB_INEPNAKEFFMSK */ +#define _USB_DIEPMSK_INEPNAKEFFMSK_MASK 0x40UL /* Bit mask for USB_INEPNAKEFFMSK */ +#define _USB_DIEPMSK_INEPNAKEFFMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_INEPNAKEFFMSK_DEFAULT (_USB_DIEPMSK_INEPNAKEFFMSK_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_TXFIFOUNDRNMSK (0x1UL << 8) /* Fifo Underrun Mask */ +#define _USB_DIEPMSK_TXFIFOUNDRNMSK_SHIFT 8 /* Shift value for USB_TXFIFOUNDRNMSK */ +#define _USB_DIEPMSK_TXFIFOUNDRNMSK_MASK 0x100UL /* Bit mask for USB_TXFIFOUNDRNMSK */ +#define _USB_DIEPMSK_TXFIFOUNDRNMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_TXFIFOUNDRNMSK_DEFAULT (_USB_DIEPMSK_TXFIFOUNDRNMSK_DEFAULT << 8) /* Shifted mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_NAKMSK (0x1UL << 13) /* NAK interrupt Mask */ +#define _USB_DIEPMSK_NAKMSK_SHIFT 13 /* Shift value for USB_NAKMSK */ +#define _USB_DIEPMSK_NAKMSK_MASK 0x2000UL /* Bit mask for USB_NAKMSK */ +#define _USB_DIEPMSK_NAKMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPMSK */ +#define USB_DIEPMSK_NAKMSK_DEFAULT (_USB_DIEPMSK_NAKMSK_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DIEPMSK */ + +/* Bit fields for USB DOEPMSK */ + +#define _USB_DOEPMSK_RESETVALUE 0x00000000UL /* Default value for USB_DOEPMSK */ +#define _USB_DOEPMSK_MASK 0x0000315FUL /* Mask for USB_DOEPMSK */ + +#define USB_DOEPMSK_XFERCOMPLMSK (0x1UL << 0) /* Transfer Completed Interrupt Mask */ +#define _USB_DOEPMSK_XFERCOMPLMSK_SHIFT 0 /* Shift value for USB_XFERCOMPLMSK */ +#define _USB_DOEPMSK_XFERCOMPLMSK_MASK 0x1UL /* Bit mask for USB_XFERCOMPLMSK */ +#define _USB_DOEPMSK_XFERCOMPLMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_XFERCOMPLMSK_DEFAULT (_USB_DOEPMSK_XFERCOMPLMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_EPDISBLDMSK (0x1UL << 1) /* Endpoint Disabled Interrupt Mask */ +#define _USB_DOEPMSK_EPDISBLDMSK_SHIFT 1 /* Shift value for USB_EPDISBLDMSK */ +#define _USB_DOEPMSK_EPDISBLDMSK_MASK 0x2UL /* Bit mask for USB_EPDISBLDMSK */ +#define _USB_DOEPMSK_EPDISBLDMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_EPDISBLDMSK_DEFAULT (_USB_DOEPMSK_EPDISBLDMSK_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_AHBERRMSK (0x1UL << 2) /* AHB Error */ +#define _USB_DOEPMSK_AHBERRMSK_SHIFT 2 /* Shift value for USB_AHBERRMSK */ +#define _USB_DOEPMSK_AHBERRMSK_MASK 0x4UL /* Bit mask for USB_AHBERRMSK */ +#define _USB_DOEPMSK_AHBERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_AHBERRMSK_DEFAULT (_USB_DOEPMSK_AHBERRMSK_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_SETUPMSK (0x1UL << 3) /* SETUP Phase Done Mask */ +#define _USB_DOEPMSK_SETUPMSK_SHIFT 3 /* Shift value for USB_SETUPMSK */ +#define _USB_DOEPMSK_SETUPMSK_MASK 0x8UL /* Bit mask for USB_SETUPMSK */ +#define _USB_DOEPMSK_SETUPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_SETUPMSK_DEFAULT (_USB_DOEPMSK_SETUPMSK_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_OUTTKNEPDISMSK (0x1UL << 4) /* OUT Token Received when Endpoint Disabled Mask */ +#define _USB_DOEPMSK_OUTTKNEPDISMSK_SHIFT 4 /* Shift value for USB_OUTTKNEPDISMSK */ +#define _USB_DOEPMSK_OUTTKNEPDISMSK_MASK 0x10UL /* Bit mask for USB_OUTTKNEPDISMSK */ +#define _USB_DOEPMSK_OUTTKNEPDISMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_OUTTKNEPDISMSK_DEFAULT (_USB_DOEPMSK_OUTTKNEPDISMSK_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_BACK2BACKSETUP (0x1UL << 6) /* Back-to-Back SETUP Packets Received Mask */ +#define _USB_DOEPMSK_BACK2BACKSETUP_SHIFT 6 /* Shift value for USB_BACK2BACKSETUP */ +#define _USB_DOEPMSK_BACK2BACKSETUP_MASK 0x40UL /* Bit mask for USB_BACK2BACKSETUP */ +#define _USB_DOEPMSK_BACK2BACKSETUP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_BACK2BACKSETUP_DEFAULT (_USB_DOEPMSK_BACK2BACKSETUP_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_OUTPKTERRMSK (0x1UL << 8) /* OUT Packet Error Mask */ +#define _USB_DOEPMSK_OUTPKTERRMSK_SHIFT 8 /* Shift value for USB_OUTPKTERRMSK */ +#define _USB_DOEPMSK_OUTPKTERRMSK_MASK 0x100UL /* Bit mask for USB_OUTPKTERRMSK */ +#define _USB_DOEPMSK_OUTPKTERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_OUTPKTERRMSK_DEFAULT (_USB_DOEPMSK_OUTPKTERRMSK_DEFAULT << 8) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_BBLEERRMSK (0x1UL << 12) /* Babble Error interrupt Mask */ +#define _USB_DOEPMSK_BBLEERRMSK_SHIFT 12 /* Shift value for USB_BBLEERRMSK */ +#define _USB_DOEPMSK_BBLEERRMSK_MASK 0x1000UL /* Bit mask for USB_BBLEERRMSK */ +#define _USB_DOEPMSK_BBLEERRMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_BBLEERRMSK_DEFAULT (_USB_DOEPMSK_BBLEERRMSK_DEFAULT << 12) /* Shifted mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_NAKMSK (0x1UL << 13) /* NAK interrupt Mask */ +#define _USB_DOEPMSK_NAKMSK_SHIFT 13 /* Shift value for USB_NAKMSK */ +#define _USB_DOEPMSK_NAKMSK_MASK 0x2000UL /* Bit mask for USB_NAKMSK */ +#define _USB_DOEPMSK_NAKMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPMSK */ +#define USB_DOEPMSK_NAKMSK_DEFAULT (_USB_DOEPMSK_NAKMSK_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DOEPMSK */ + +/* Bit fields for USB DAINT */ + +#define _USB_DAINT_RESETVALUE 0x00000000UL /* Default value for USB_DAINT */ +#define _USB_DAINT_MASK 0x007F007FUL /* Mask for USB_DAINT */ + +#define _USB_DAINT_INEPINT_SHIFT 0 /* Shift value for IN endpoint interrupt bits */ +#define _USB_DAINT_INEPINT_MASK 0x7FUL /* Mask of all IN endpoint interrupt bits */ +#define USB_DAINT_INEPINT(n) (0x1UL << ((n)+_USB_DAINT_INEPINT_SHIFT)) + +#define USB_DAINT_INEPINT0 (0x1UL << 0) /* IN Endpoint 0 Interrupt Bit */ +#define _USB_DAINT_INEPINT0_SHIFT 0 /* Shift value for USB_INEPINT0 */ +#define _USB_DAINT_INEPINT0_MASK 0x1UL /* Bit mask for USB_INEPINT0 */ +#define _USB_DAINT_INEPINT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT0_DEFAULT (_USB_DAINT_INEPINT0_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT1 (0x1UL << 1) /* IN Endpoint 1 Interrupt Bit */ +#define _USB_DAINT_INEPINT1_SHIFT 1 /* Shift value for USB_INEPINT1 */ +#define _USB_DAINT_INEPINT1_MASK 0x2UL /* Bit mask for USB_INEPINT1 */ +#define _USB_DAINT_INEPINT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT1_DEFAULT (_USB_DAINT_INEPINT1_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT2 (0x1UL << 2) /* IN Endpoint 2 Interrupt Bit */ +#define _USB_DAINT_INEPINT2_SHIFT 2 /* Shift value for USB_INEPINT2 */ +#define _USB_DAINT_INEPINT2_MASK 0x4UL /* Bit mask for USB_INEPINT2 */ +#define _USB_DAINT_INEPINT2_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT2_DEFAULT (_USB_DAINT_INEPINT2_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT3 (0x1UL << 3) /* IN Endpoint 3 Interrupt Bit */ +#define _USB_DAINT_INEPINT3_SHIFT 3 /* Shift value for USB_INEPINT3 */ +#define _USB_DAINT_INEPINT3_MASK 0x8UL /* Bit mask for USB_INEPINT3 */ +#define _USB_DAINT_INEPINT3_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT3_DEFAULT (_USB_DAINT_INEPINT3_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT4 (0x1UL << 4) /* IN Endpoint 4 Interrupt Bit */ +#define _USB_DAINT_INEPINT4_SHIFT 4 /* Shift value for USB_INEPINT4 */ +#define _USB_DAINT_INEPINT4_MASK 0x10UL /* Bit mask for USB_INEPINT4 */ +#define _USB_DAINT_INEPINT4_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT4_DEFAULT (_USB_DAINT_INEPINT4_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT5 (0x1UL << 5) /* IN Endpoint 5 Interrupt Bit */ +#define _USB_DAINT_INEPINT5_SHIFT 5 /* Shift value for USB_INEPINT5 */ +#define _USB_DAINT_INEPINT5_MASK 0x20UL /* Bit mask for USB_INEPINT5 */ +#define _USB_DAINT_INEPINT5_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT5_DEFAULT (_USB_DAINT_INEPINT5_DEFAULT << 5) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT6 (0x1UL << 6) /* IN Endpoint 6 Interrupt Bit */ +#define _USB_DAINT_INEPINT6_SHIFT 6 /* Shift value for USB_INEPINT6 */ +#define _USB_DAINT_INEPINT6_MASK 0x40UL /* Bit mask for USB_INEPINT6 */ +#define _USB_DAINT_INEPINT6_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_INEPINT6_DEFAULT (_USB_DAINT_INEPINT6_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DAINT */ + +#define _USB_DAINT_OUTEPINT_SHIFT 16 /* Shift value for all IN endpoint interrupt bits */ +#define _USB_DAINT_OUTEPINT_MASK 0x7F0000UL /* Mask of OUT IN endpoint interrupt bits */ +#define USB_DAINT_OUTEPINT(n) (0x1UL << ((n)+_USB_DAINT_OUTEPINT_SHIFT)) + +#define USB_DAINT_OUTEPINT0 (0x1UL << 16) /* OUT Endpoint 0 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT0_SHIFT 16 /* Shift value for USB_OUTEPINT0 */ +#define _USB_DAINT_OUTEPINT0_MASK 0x10000UL /* Bit mask for USB_OUTEPINT0 */ +#define _USB_DAINT_OUTEPINT0_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT0_DEFAULT (_USB_DAINT_OUTEPINT0_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT1 (0x1UL << 17) /* OUT Endpoint 1 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT1_SHIFT 17 /* Shift value for USB_OUTEPINT1 */ +#define _USB_DAINT_OUTEPINT1_MASK 0x20000UL /* Bit mask for USB_OUTEPINT1 */ +#define _USB_DAINT_OUTEPINT1_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT1_DEFAULT (_USB_DAINT_OUTEPINT1_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT2 (0x1UL << 18) /* OUT Endpoint 2 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT2_SHIFT 18 /* Shift value for USB_OUTEPINT2 */ +#define _USB_DAINT_OUTEPINT2_MASK 0x40000UL /* Bit mask for USB_OUTEPINT2 */ +#define _USB_DAINT_OUTEPINT2_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT2_DEFAULT (_USB_DAINT_OUTEPINT2_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT3 (0x1UL << 19) /* OUT Endpoint 3 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT3_SHIFT 19 /* Shift value for USB_OUTEPINT3 */ +#define _USB_DAINT_OUTEPINT3_MASK 0x80000UL /* Bit mask for USB_OUTEPINT3 */ +#define _USB_DAINT_OUTEPINT3_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT3_DEFAULT (_USB_DAINT_OUTEPINT3_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT4 (0x1UL << 20) /* OUT Endpoint 4 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT4_SHIFT 20 /* Shift value for USB_OUTEPINT4 */ +#define _USB_DAINT_OUTEPINT4_MASK 0x100000UL /* Bit mask for USB_OUTEPINT4 */ +#define _USB_DAINT_OUTEPINT4_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT4_DEFAULT (_USB_DAINT_OUTEPINT4_DEFAULT << 20) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT5 (0x1UL << 21) /* OUT Endpoint 5 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT5_SHIFT 21 /* Shift value for USB_OUTEPINT5 */ +#define _USB_DAINT_OUTEPINT5_MASK 0x200000UL /* Bit mask for USB_OUTEPINT5 */ +#define _USB_DAINT_OUTEPINT5_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT5_DEFAULT (_USB_DAINT_OUTEPINT5_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT6 (0x1UL << 22) /* OUT Endpoint 6 Interrupt Bit */ +#define _USB_DAINT_OUTEPINT6_SHIFT 22 /* Shift value for USB_OUTEPINT6 */ +#define _USB_DAINT_OUTEPINT6_MASK 0x400000UL /* Bit mask for USB_OUTEPINT6 */ +#define _USB_DAINT_OUTEPINT6_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINT */ +#define USB_DAINT_OUTEPINT6_DEFAULT (_USB_DAINT_OUTEPINT6_DEFAULT << 22) /* Shifted mode DEFAULT for USB_DAINT */ + +/* Bit fields for USB DAINTMSK */ + +#define _USB_DAINTMSK_RESETVALUE 0x00000000UL /* Default value for USB_DAINTMSK */ +#define _USB_DAINTMSK_MASK 0x007F007FUL /* Mask for USB_DAINTMSK */ + +#define USB_DAINTMSK_INEPMSK0 (0x1UL << 0) /* IN Endpoint 0 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK0_SHIFT 0 /* Shift value for USB_INEPMSK0 */ +#define _USB_DAINTMSK_INEPMSK0_MASK 0x1UL /* Bit mask for USB_INEPMSK0 */ +#define _USB_DAINTMSK_INEPMSK0_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK0_DEFAULT (_USB_DAINTMSK_INEPMSK0_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK1 (0x1UL << 1) /* IN Endpoint 1 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK1_SHIFT 1 /* Shift value for USB_INEPMSK1 */ +#define _USB_DAINTMSK_INEPMSK1_MASK 0x2UL /* Bit mask for USB_INEPMSK1 */ +#define _USB_DAINTMSK_INEPMSK1_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK1_DEFAULT (_USB_DAINTMSK_INEPMSK1_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK2 (0x1UL << 2) /* IN Endpoint 2 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK2_SHIFT 2 /* Shift value for USB_INEPMSK2 */ +#define _USB_DAINTMSK_INEPMSK2_MASK 0x4UL /* Bit mask for USB_INEPMSK2 */ +#define _USB_DAINTMSK_INEPMSK2_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK2_DEFAULT (_USB_DAINTMSK_INEPMSK2_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK3 (0x1UL << 3) /* IN Endpoint 3 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK3_SHIFT 3 /* Shift value for USB_INEPMSK3 */ +#define _USB_DAINTMSK_INEPMSK3_MASK 0x8UL /* Bit mask for USB_INEPMSK3 */ +#define _USB_DAINTMSK_INEPMSK3_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK3_DEFAULT (_USB_DAINTMSK_INEPMSK3_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK4 (0x1UL << 4) /* IN Endpoint 4 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK4_SHIFT 4 /* Shift value for USB_INEPMSK4 */ +#define _USB_DAINTMSK_INEPMSK4_MASK 0x10UL /* Bit mask for USB_INEPMSK4 */ +#define _USB_DAINTMSK_INEPMSK4_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK4_DEFAULT (_USB_DAINTMSK_INEPMSK4_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK5 (0x1UL << 5) /* IN Endpoint 5 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK5_SHIFT 5 /* Shift value for USB_INEPMSK5 */ +#define _USB_DAINTMSK_INEPMSK5_MASK 0x20UL /* Bit mask for USB_INEPMSK5 */ +#define _USB_DAINTMSK_INEPMSK5_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK5_DEFAULT (_USB_DAINTMSK_INEPMSK5_DEFAULT << 5) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK6 (0x1UL << 6) /* IN Endpoint 6 Interrupt mask Bit */ +#define _USB_DAINTMSK_INEPMSK6_SHIFT 6 /* Shift value for USB_INEPMSK6 */ +#define _USB_DAINTMSK_INEPMSK6_MASK 0x40UL /* Bit mask for USB_INEPMSK6 */ +#define _USB_DAINTMSK_INEPMSK6_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_INEPMSK6_DEFAULT (_USB_DAINTMSK_INEPMSK6_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK0 (0x1UL << 16) /* OUT Endpoint 0 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK0_SHIFT 16 /* Shift value for USB_OUTEPMSK0 */ +#define _USB_DAINTMSK_OUTEPMSK0_MASK 0x10000UL /* Bit mask for USB_OUTEPMSK0 */ +#define _USB_DAINTMSK_OUTEPMSK0_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK0_DEFAULT (_USB_DAINTMSK_OUTEPMSK0_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK1 (0x1UL << 17) /* OUT Endpoint 1 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK1_SHIFT 17 /* Shift value for USB_OUTEPMSK1 */ +#define _USB_DAINTMSK_OUTEPMSK1_MASK 0x20000UL /* Bit mask for USB_OUTEPMSK1 */ +#define _USB_DAINTMSK_OUTEPMSK1_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK1_DEFAULT (_USB_DAINTMSK_OUTEPMSK1_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK2 (0x1UL << 18) /* OUT Endpoint 2 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK2_SHIFT 18 /* Shift value for USB_OUTEPMSK2 */ +#define _USB_DAINTMSK_OUTEPMSK2_MASK 0x40000UL /* Bit mask for USB_OUTEPMSK2 */ +#define _USB_DAINTMSK_OUTEPMSK2_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK2_DEFAULT (_USB_DAINTMSK_OUTEPMSK2_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK3 (0x1UL << 19) /* OUT Endpoint 3 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK3_SHIFT 19 /* Shift value for USB_OUTEPMSK3 */ +#define _USB_DAINTMSK_OUTEPMSK3_MASK 0x80000UL /* Bit mask for USB_OUTEPMSK3 */ +#define _USB_DAINTMSK_OUTEPMSK3_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK3_DEFAULT (_USB_DAINTMSK_OUTEPMSK3_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK4 (0x1UL << 20) /* OUT Endpoint 4 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK4_SHIFT 20 /* Shift value for USB_OUTEPMSK4 */ +#define _USB_DAINTMSK_OUTEPMSK4_MASK 0x100000UL /* Bit mask for USB_OUTEPMSK4 */ +#define _USB_DAINTMSK_OUTEPMSK4_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK4_DEFAULT (_USB_DAINTMSK_OUTEPMSK4_DEFAULT << 20) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK5 (0x1UL << 21) /* OUT Endpoint 5 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK5_SHIFT 21 /* Shift value for USB_OUTEPMSK5 */ +#define _USB_DAINTMSK_OUTEPMSK5_MASK 0x200000UL /* Bit mask for USB_OUTEPMSK5 */ +#define _USB_DAINTMSK_OUTEPMSK5_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK5_DEFAULT (_USB_DAINTMSK_OUTEPMSK5_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK6 (0x1UL << 22) /* OUT Endpoint 6 Interrupt mask Bit */ +#define _USB_DAINTMSK_OUTEPMSK6_SHIFT 22 /* Shift value for USB_OUTEPMSK6 */ +#define _USB_DAINTMSK_OUTEPMSK6_MASK 0x400000UL /* Bit mask for USB_OUTEPMSK6 */ +#define _USB_DAINTMSK_OUTEPMSK6_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DAINTMSK */ +#define USB_DAINTMSK_OUTEPMSK6_DEFAULT (_USB_DAINTMSK_OUTEPMSK6_DEFAULT << 22) /* Shifted mode DEFAULT for USB_DAINTMSK */ + +/* Bit fields for USB DVBUSDIS */ + +#define _USB_DVBUSDIS_RESETVALUE 0x000017D7UL /* Default value for USB_DVBUSDIS */ +#define _USB_DVBUSDIS_MASK 0x0000FFFFUL /* Mask for USB_DVBUSDIS */ + +#define _USB_DVBUSDIS_DVBUSDIS_SHIFT 0 /* Shift value for USB_DVBUSDIS */ +#define _USB_DVBUSDIS_DVBUSDIS_MASK 0xFFFFUL /* Bit mask for USB_DVBUSDIS */ +#define _USB_DVBUSDIS_DVBUSDIS_DEFAULT 0x000017D7UL /* Mode DEFAULT for USB_DVBUSDIS */ +#define USB_DVBUSDIS_DVBUSDIS_DEFAULT (_USB_DVBUSDIS_DVBUSDIS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DVBUSDIS */ + +/* Bit fields for USB DVBUSPULSE */ + +#define _USB_DVBUSPULSE_RESETVALUE 0x000005B8UL /* Default value for USB_DVBUSPULSE */ +#define _USB_DVBUSPULSE_MASK 0x00000FFFUL /* Mask for USB_DVBUSPULSE */ + +#define _USB_DVBUSPULSE_DVBUSPULSE_SHIFT 0 /* Shift value for USB_DVBUSPULSE */ +#define _USB_DVBUSPULSE_DVBUSPULSE_MASK 0xFFFUL /* Bit mask for USB_DVBUSPULSE */ +#define _USB_DVBUSPULSE_DVBUSPULSE_DEFAULT 0x000005B8UL /* Mode DEFAULT for USB_DVBUSPULSE */ +#define USB_DVBUSPULSE_DVBUSPULSE_DEFAULT (_USB_DVBUSPULSE_DVBUSPULSE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DVBUSPULSE */ + +/* Bit fields for USB DIEPEMPMSK */ + +#define _USB_DIEPEMPMSK_RESETVALUE 0x00000000UL /* Default value for USB_DIEPEMPMSK */ +#define _USB_DIEPEMPMSK_MASK 0x0000FFFFUL /* Mask for USB_DIEPEMPMSK */ + +#define _USB_DIEPEMPMSK_DIEPEMPMSK_SHIFT 0 /* Shift value for USB_DIEPEMPMSK */ +#define _USB_DIEPEMPMSK_DIEPEMPMSK_MASK 0xFFFFUL /* Bit mask for USB_DIEPEMPMSK */ +#define _USB_DIEPEMPMSK_DIEPEMPMSK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPEMPMSK */ +#define USB_DIEPEMPMSK_DIEPEMPMSK_DEFAULT (_USB_DIEPEMPMSK_DIEPEMPMSK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPEMPMSK */ +#define USB_DIEPEMPMSK(n) (1UL << ((n) + _USB_DIEPEMPMSK_DIEPEMPMSK_SHIFT)) + +/* Bit fields for USB DIEP0CTL */ + +#define _USB_DIEP0CTL_RESETVALUE 0x00008000UL /* Default value for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_MASK 0xCFEE8003UL /* Mask for USB_DIEP0CTL */ + +#define _USB_DIEP0CTL_MPS_SHIFT 0 /* Shift value for USB_MPS */ +#define _USB_DIEP0CTL_MPS_MASK 0x3UL /* Bit mask for USB_MPS */ +#define _USB_DIEP0CTL_MPS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_MPS_64B 0x00000000UL /* Mode 64B for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_MPS_32B 0x00000001UL /* Mode 32B for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_MPS_16B 0x00000002UL /* Mode 16B for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_MPS_8B 0x00000003UL /* Mode 8B for USB_DIEP0CTL */ +#define USB_DIEP0CTL_MPS_DEFAULT (_USB_DIEP0CTL_MPS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_MPS_64B (_USB_DIEP0CTL_MPS_64B << 0) /* Shifted mode 64B for USB_DIEP0CTL */ +#define USB_DIEP0CTL_MPS_32B (_USB_DIEP0CTL_MPS_32B << 0) /* Shifted mode 32B for USB_DIEP0CTL */ +#define USB_DIEP0CTL_MPS_16B (_USB_DIEP0CTL_MPS_16B << 0) /* Shifted mode 16B for USB_DIEP0CTL */ +#define USB_DIEP0CTL_MPS_8B (_USB_DIEP0CTL_MPS_8B << 0) /* Shifted mode 8B for USB_DIEP0CTL */ +#define USB_DIEP0CTL_USBACTEP (0x1UL << 15) /* USB Active Endpoint */ +#define _USB_DIEP0CTL_USBACTEP_SHIFT 15 /* Shift value for USB_USBACTEP */ +#define _USB_DIEP0CTL_USBACTEP_MASK 0x8000UL /* Bit mask for USB_USBACTEP */ +#define _USB_DIEP0CTL_USBACTEP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_USBACTEP_DEFAULT (_USB_DIEP0CTL_USBACTEP_DEFAULT << 15) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_NAKSTS (0x1UL << 17) /* NAK Status */ +#define _USB_DIEP0CTL_NAKSTS_SHIFT 17 /* Shift value for USB_NAKSTS */ +#define _USB_DIEP0CTL_NAKSTS_MASK 0x20000UL /* Bit mask for USB_NAKSTS */ +#define _USB_DIEP0CTL_NAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_NAKSTS_DEFAULT (_USB_DIEP0CTL_NAKSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_EPTYPE_SHIFT 18 /* Shift value for USB_EPTYPE */ +#define _USB_DIEP0CTL_EPTYPE_MASK 0xC0000UL /* Bit mask for USB_EPTYPE */ +#define _USB_DIEP0CTL_EPTYPE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_EPTYPE_DEFAULT (_USB_DIEP0CTL_EPTYPE_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_STALL (0x1UL << 21) /* Handshake */ +#define _USB_DIEP0CTL_STALL_SHIFT 21 /* Shift value for USB_STALL */ +#define _USB_DIEP0CTL_STALL_MASK 0x200000UL /* Bit mask for USB_STALL */ +#define _USB_DIEP0CTL_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_STALL_DEFAULT (_USB_DIEP0CTL_STALL_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define _USB_DIEP0CTL_TXFNUM_SHIFT 22 /* Shift value for USB_TXFNUM */ +#define _USB_DIEP0CTL_TXFNUM_MASK 0x3c00000UL /* Bit mask for USB_TXFNUM */ +#define _USB_DIEP0CTL_TXFNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_TXFNUM_DEFAULT (_USB_DIEP0CTL_TXFNUM_DEFAULT << 22) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_CNAK (0x1UL << 26) /* Clear NAK */ +#define _USB_DIEP0CTL_CNAK_SHIFT 26 /* Shift value for USB_CNAK */ +#define _USB_DIEP0CTL_CNAK_MASK 0x4000000UL /* Bit mask for USB_CNAK */ +#define _USB_DIEP0CTL_CNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_CNAK_DEFAULT (_USB_DIEP0CTL_CNAK_DEFAULT << 26) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_SNAK (0x1UL << 27) /* Set NAK */ +#define _USB_DIEP0CTL_SNAK_SHIFT 27 /* Shift value for USB_SNAK */ +#define _USB_DIEP0CTL_SNAK_MASK 0x8000000UL /* Bit mask for USB_SNAK */ +#define _USB_DIEP0CTL_SNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_SNAK_DEFAULT (_USB_DIEP0CTL_SNAK_DEFAULT << 27) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_EPDIS (0x1UL << 30) /* Endpoint Disable */ +#define _USB_DIEP0CTL_EPDIS_SHIFT 30 /* Shift value for USB_EPDIS */ +#define _USB_DIEP0CTL_EPDIS_MASK 0x40000000UL /* Bit mask for USB_EPDIS */ +#define _USB_DIEP0CTL_EPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_EPDIS_DEFAULT (_USB_DIEP0CTL_EPDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_EPENA (0x1UL << 31) /* Endpoint Enable */ +#define _USB_DIEP0CTL_EPENA_SHIFT 31 /* Shift value for USB_EPENA */ +#define _USB_DIEP0CTL_EPENA_MASK 0x80000000UL /* Bit mask for USB_EPENA */ +#define _USB_DIEP0CTL_EPENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0CTL */ +#define USB_DIEP0CTL_EPENA_DEFAULT (_USB_DIEP0CTL_EPENA_DEFAULT << 31) /* Shifted mode DEFAULT for USB_DIEP0CTL */ + +/* Bit fields for USB DIEP0INT */ + +#define _USB_DIEP0INT_RESETVALUE 0x00000080UL /* Default value for USB_DIEP0INT */ +#define _USB_DIEP0INT_MASK 0x000038DFUL /* Mask for USB_DIEP0INT */ + +#define USB_DIEP0INT_XFERCOMPL (0x1UL << 0) /* Transfer Completed Interrupt */ +#define _USB_DIEP0INT_XFERCOMPL_SHIFT 0 /* Shift value for USB_XFERCOMPL */ +#define _USB_DIEP0INT_XFERCOMPL_MASK 0x1UL /* Bit mask for USB_XFERCOMPL */ +#define _USB_DIEP0INT_XFERCOMPL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_XFERCOMPL_DEFAULT (_USB_DIEP0INT_XFERCOMPL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_EPDISBLD (0x1UL << 1) /* Endpoint Disabled Interrupt */ +#define _USB_DIEP0INT_EPDISBLD_SHIFT 1 /* Shift value for USB_EPDISBLD */ +#define _USB_DIEP0INT_EPDISBLD_MASK 0x2UL /* Bit mask for USB_EPDISBLD */ +#define _USB_DIEP0INT_EPDISBLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_EPDISBLD_DEFAULT (_USB_DIEP0INT_EPDISBLD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_AHBERR (0x1UL << 2) /* AHB Error */ +#define _USB_DIEP0INT_AHBERR_SHIFT 2 /* Shift value for USB_AHBERR */ +#define _USB_DIEP0INT_AHBERR_MASK 0x4UL /* Bit mask for USB_AHBERR */ +#define _USB_DIEP0INT_AHBERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_AHBERR_DEFAULT (_USB_DIEP0INT_AHBERR_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_TIMEOUT (0x1UL << 3) /* Timeout Condition */ +#define _USB_DIEP0INT_TIMEOUT_SHIFT 3 /* Shift value for USB_TIMEOUT */ +#define _USB_DIEP0INT_TIMEOUT_MASK 0x8UL /* Bit mask for USB_TIMEOUT */ +#define _USB_DIEP0INT_TIMEOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_TIMEOUT_DEFAULT (_USB_DIEP0INT_TIMEOUT_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_INTKNTXFEMP (0x1UL << 4) /* IN Token Received When TxFIFO is Empty */ +#define _USB_DIEP0INT_INTKNTXFEMP_SHIFT 4 /* Shift value for USB_INTKNTXFEMP */ +#define _USB_DIEP0INT_INTKNTXFEMP_MASK 0x10UL /* Bit mask for USB_INTKNTXFEMP */ +#define _USB_DIEP0INT_INTKNTXFEMP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_INTKNTXFEMP_DEFAULT (_USB_DIEP0INT_INTKNTXFEMP_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_INEPNAKEFF (0x1UL << 6) /* IN Endpoint NAK Effective */ +#define _USB_DIEP0INT_INEPNAKEFF_SHIFT 6 /* Shift value for USB_INEPNAKEFF */ +#define _USB_DIEP0INT_INEPNAKEFF_MASK 0x40UL /* Bit mask for USB_INEPNAKEFF */ +#define _USB_DIEP0INT_INEPNAKEFF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_INEPNAKEFF_DEFAULT (_USB_DIEP0INT_INEPNAKEFF_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_TXFEMP (0x1UL << 7) /* Transmit FIFO Empty */ +#define _USB_DIEP0INT_TXFEMP_SHIFT 7 /* Shift value for USB_TXFEMP */ +#define _USB_DIEP0INT_TXFEMP_MASK 0x80UL /* Bit mask for USB_TXFEMP */ +#define _USB_DIEP0INT_TXFEMP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_TXFEMP_DEFAULT (_USB_DIEP0INT_TXFEMP_DEFAULT << 7) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_PKTDRPSTS (0x1UL << 11) /* Packet Drop Status */ +#define _USB_DIEP0INT_PKTDRPSTS_SHIFT 11 /* Shift value for USB_PKTDRPSTS */ +#define _USB_DIEP0INT_PKTDRPSTS_MASK 0x800UL /* Bit mask for USB_PKTDRPSTS */ +#define _USB_DIEP0INT_PKTDRPSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_PKTDRPSTS_DEFAULT (_USB_DIEP0INT_PKTDRPSTS_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_BBLEERR (0x1UL << 12) /* NAK Interrupt */ +#define _USB_DIEP0INT_BBLEERR_SHIFT 12 /* Shift value for USB_BBLEERR */ +#define _USB_DIEP0INT_BBLEERR_MASK 0x1000UL /* Bit mask for USB_BBLEERR */ +#define _USB_DIEP0INT_BBLEERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_BBLEERR_DEFAULT (_USB_DIEP0INT_BBLEERR_DEFAULT << 12) /* Shifted mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_NAKINTRPT (0x1UL << 13) /* NAK Interrupt */ +#define _USB_DIEP0INT_NAKINTRPT_SHIFT 13 /* Shift value for USB_NAKINTRPT */ +#define _USB_DIEP0INT_NAKINTRPT_MASK 0x2000UL /* Bit mask for USB_NAKINTRPT */ +#define _USB_DIEP0INT_NAKINTRPT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0INT */ +#define USB_DIEP0INT_NAKINTRPT_DEFAULT (_USB_DIEP0INT_NAKINTRPT_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DIEP0INT */ + +/* Bit fields for USB DIEP0TSIZ */ + +#define _USB_DIEP0TSIZ_RESETVALUE 0x00000000UL /* Default value for USB_DIEP0TSIZ */ +#define _USB_DIEP0TSIZ_MASK 0x0018007FUL /* Mask for USB_DIEP0TSIZ */ + +#define _USB_DIEP0TSIZ_XFERSIZE_SHIFT 0 /* Shift value for USB_XFERSIZE */ +#define _USB_DIEP0TSIZ_XFERSIZE_MASK 0x7FUL /* Bit mask for USB_XFERSIZE */ +#define _USB_DIEP0TSIZ_XFERSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0TSIZ */ +#define USB_DIEP0TSIZ_XFERSIZE_DEFAULT (_USB_DIEP0TSIZ_XFERSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEP0TSIZ */ +#define _USB_DIEP0TSIZ_PKTCNT_SHIFT 19 /* Shift value for USB_PKTCNT */ +#define _USB_DIEP0TSIZ_PKTCNT_MASK 0x180000UL /* Bit mask for USB_PKTCNT */ +#define _USB_DIEP0TSIZ_PKTCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0TSIZ */ +#define USB_DIEP0TSIZ_PKTCNT_DEFAULT (_USB_DIEP0TSIZ_PKTCNT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DIEP0TSIZ */ + +/* Bit fields for USB DIEP0DMAADDR */ + +#define _USB_DIEP0DMAADDR_RESETVALUE 0x00000000UL /* Default value for USB_DIEP0DMAADDR */ +#define _USB_DIEP0DMAADDR_MASK 0xFFFFFFFFUL /* Mask for USB_DIEP0DMAADDR */ + +#define _USB_DIEP0DMAADDR_DIEP0DMAADDR_SHIFT 0 /* Shift value for USB_DIEP0DMAADDR */ +#define _USB_DIEP0DMAADDR_DIEP0DMAADDR_MASK 0xFFFFFFFFUL /* Bit mask for USB_DIEP0DMAADDR */ +#define _USB_DIEP0DMAADDR_DIEP0DMAADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEP0DMAADDR */ +#define USB_DIEP0DMAADDR_DIEP0DMAADDR_DEFAULT (_USB_DIEP0DMAADDR_DIEP0DMAADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEP0DMAADDR */ + +/* Bit fields for USB DIEP0TXFSTS */ + +#define _USB_DIEP0TXFSTS_RESETVALUE 0x00000200UL /* Default value for USB_DIEP0TXFSTS */ +#define _USB_DIEP0TXFSTS_MASK 0x0000FFFFUL /* Mask for USB_DIEP0TXFSTS */ + +#define _USB_DIEP0TXFSTS_SPCAVAIL_SHIFT 0 /* Shift value for USB_SPCAVAIL */ +#define _USB_DIEP0TXFSTS_SPCAVAIL_MASK 0xFFFFUL /* Bit mask for USB_SPCAVAIL */ +#define _USB_DIEP0TXFSTS_SPCAVAIL_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEP0TXFSTS */ +#define USB_DIEP0TXFSTS_SPCAVAIL_DEFAULT (_USB_DIEP0TXFSTS_SPCAVAIL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEP0TXFSTS */ + +/* Bit fields for USB DIEPCTL */ + +#define _USB_DIEPCTL_RESETVALUE 0x00000000UL /* Default value for USB_DIEPCTL */ +#define _USB_DIEPCTL_MASK 0xFFEF87FFUL /* Mask for USB_DIEPCTL */ + +#define _USB_DIEPCTL_MPS_SHIFT 0 /* Shift value for USB_MPS */ +#define _USB_DIEPCTL_MPS_MASK 0x7FFUL /* Bit mask for USB_MPS */ +#define _USB_DIEPCTL_MPS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_MPS_DEFAULT (_USB_DIEPCTL_MPS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_USBACTEP (0x1UL << 15) /* USB Active Endpoint */ +#define _USB_DIEPCTL_USBACTEP_SHIFT 15 /* Shift value for USB_USBACTEP */ +#define _USB_DIEPCTL_USBACTEP_MASK 0x8000UL /* Bit mask for USB_USBACTEP */ +#define _USB_DIEPCTL_USBACTEP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_USBACTEP_DEFAULT (_USB_DIEPCTL_USBACTEP_DEFAULT << 15) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_DPIDEOF (0x1UL << 16) /* Endpoint Data PID / Even or Odd Frame */ +#define _USB_DIEPCTL_DPIDEOF_SHIFT 16 /* Shift value for USB_DPIDEOF */ +#define _USB_DIEPCTL_DPIDEOF_MASK 0x10000UL /* Bit mask for USB_DPIDEOF */ +#define _USB_DIEPCTL_DPIDEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define _USB_DIEPCTL_DPIDEOF_DATA0EVEN 0x00000000UL /* Mode DATA0EVEN for USB_DIEPCTL */ +#define _USB_DIEPCTL_DPIDEOF_DATA1ODD 0x00000001UL /* Mode DATA1ODD for USB_DIEPCTL */ +#define USB_DIEPCTL_DPIDEOF_DEFAULT (_USB_DIEPCTL_DPIDEOF_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_DPIDEOF_DATA0EVEN (_USB_DIEPCTL_DPIDEOF_DATA0EVEN << 16) /* Shifted mode DATA0EVEN for USB_DIEPCTL */ +#define USB_DIEPCTL_DPIDEOF_DATA1ODD (_USB_DIEPCTL_DPIDEOF_DATA1ODD << 16) /* Shifted mode DATA1ODD for USB_DIEPCTL */ +#define USB_DIEPCTL_NAKSTS (0x1UL << 17) /* NAK Status */ +#define _USB_DIEPCTL_NAKSTS_SHIFT 17 /* Shift value for USB_NAKSTS */ +#define _USB_DIEPCTL_NAKSTS_MASK 0x20000UL /* Bit mask for USB_NAKSTS */ +#define _USB_DIEPCTL_NAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_NAKSTS_DEFAULT (_USB_DIEPCTL_NAKSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define _USB_DIEPCTL_EPTYPE_SHIFT 18 /* Shift value for USB_EPTYPE */ +#define _USB_DIEPCTL_EPTYPE_MASK 0xC0000UL /* Bit mask for USB_EPTYPE */ +#define _USB_DIEPCTL_EPTYPE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define _USB_DIEPCTL_EPTYPE_CONTROL 0x00000000UL /* Mode CONTROL for USB_DIEPCTL */ +#define _USB_DIEPCTL_EPTYPE_ISO 0x00000001UL /* Mode ISO for USB_DIEPCTL */ +#define _USB_DIEPCTL_EPTYPE_BULK 0x00000002UL /* Mode BULK for USB_DIEPCTL */ +#define _USB_DIEPCTL_EPTYPE_INT 0x00000003UL /* Mode INT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPTYPE_DEFAULT (_USB_DIEPCTL_EPTYPE_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPTYPE_CONTROL (_USB_DIEPCTL_EPTYPE_CONTROL << 18) /* Shifted mode CONTROL for USB_DIEPCTL */ +#define USB_DIEPCTL_EPTYPE_ISO (_USB_DIEPCTL_EPTYPE_ISO << 18) /* Shifted mode ISO for USB_DIEPCTL */ +#define USB_DIEPCTL_EPTYPE_BULK (_USB_DIEPCTL_EPTYPE_BULK << 18) /* Shifted mode BULK for USB_DIEPCTL */ +#define USB_DIEPCTL_EPTYPE_INT (_USB_DIEPCTL_EPTYPE_INT << 18) /* Shifted mode INT for USB_DIEPCTL */ +#define USB_DIEPCTL_STALL (0x1UL << 21) /* Handshake */ +#define _USB_DIEPCTL_STALL_SHIFT 21 /* Shift value for USB_STALL */ +#define _USB_DIEPCTL_STALL_MASK 0x200000UL /* Bit mask for USB_STALL */ +#define _USB_DIEPCTL_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_STALL_DEFAULT (_USB_DIEPCTL_STALL_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define _USB_DIEPCTL_TXFNUM_SHIFT 22 /* Shift value for USB_TXFNUM */ +#define _USB_DIEPCTL_TXFNUM_MASK 0x3c00000UL /* Bit mask for USB_TXFNUM */ +#define _USB_DIEPCTL_TXFNUM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_TXFNUM_DEFAULT (_USB_DIEPCTL_TXFNUM_DEFAULT << 22) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_CNAK (0x1UL << 26) /* Clear NAK */ +#define _USB_DIEPCTL_CNAK_SHIFT 26 /* Shift value for USB_CNAK */ +#define _USB_DIEPCTL_CNAK_MASK 0x4000000UL /* Bit mask for USB_CNAK */ +#define _USB_DIEPCTL_CNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_CNAK_DEFAULT (_USB_DIEPCTL_CNAK_DEFAULT << 26) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SNAK (0x1UL << 27) /* Set NAK */ +#define _USB_DIEPCTL_SNAK_SHIFT 27 /* Shift value for USB_SNAK */ +#define _USB_DIEPCTL_SNAK_MASK 0x8000000UL /* Bit mask for USB_SNAK */ +#define _USB_DIEPCTL_SNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SNAK_DEFAULT (_USB_DIEPCTL_SNAK_DEFAULT << 27) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SETD0PIDEF (0x1UL << 28) /* Set DATA0 PID / Even Frame */ +#define _USB_DIEPCTL_SETD0PIDEF_SHIFT 28 /* Shift value for USB_SETD0PIDEF */ +#define _USB_DIEPCTL_SETD0PIDEF_MASK 0x10000000UL /* Bit mask for USB_SETD0PIDEF */ +#define _USB_DIEPCTL_SETD0PIDEF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SETD0PIDEF_DEFAULT (_USB_DIEPCTL_SETD0PIDEF_DEFAULT << 28) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SETD1PIDOF (0x1UL << 29) /* Set DATA1 PID / Odd Frame */ +#define _USB_DIEPCTL_SETD1PIDOF_SHIFT 29 /* Shift value for USB_SETD1PIDOF */ +#define _USB_DIEPCTL_SETD1PIDOF_MASK 0x20000000UL /* Bit mask for USB_SETD1PIDOF */ +#define _USB_DIEPCTL_SETD1PIDOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_SETD1PIDOF_DEFAULT (_USB_DIEPCTL_SETD1PIDOF_DEFAULT << 29) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPDIS (0x1UL << 30) /* Endpoint Disable */ +#define _USB_DIEPCTL_EPDIS_SHIFT 30 /* Shift value for USB_EPDIS */ +#define _USB_DIEPCTL_EPDIS_MASK 0x40000000UL /* Bit mask for USB_EPDIS */ +#define _USB_DIEPCTL_EPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPDIS_DEFAULT (_USB_DIEPCTL_EPDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPENA (0x1UL << 31) /* Endpoint Enable */ +#define _USB_DIEPCTL_EPENA_SHIFT 31 /* Shift value for USB_EPENA */ +#define _USB_DIEPCTL_EPENA_MASK 0x80000000UL /* Bit mask for USB_EPENA */ +#define _USB_DIEPCTL_EPENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPCTL */ +#define USB_DIEPCTL_EPENA_DEFAULT (_USB_DIEPCTL_EPENA_DEFAULT << 31) /* Shifted mode DEFAULT for USB_DIEPCTL */ + +/* Bit fields for USB DIEPINT */ + +#define _USB_DIEPINT_RESETVALUE 0x00000080UL /* Default value for USB_DIEPINT */ +#define _USB_DIEPINT_MASK 0x000038DFUL /* Mask for USB_DIEPINT */ + +#define USB_DIEPINT_XFERCOMPL (0x1UL << 0) /* Transfer Completed Interrupt */ +#define _USB_DIEPINT_XFERCOMPL_SHIFT 0 /* Shift value for USB_XFERCOMPL */ +#define _USB_DIEPINT_XFERCOMPL_MASK 0x1UL /* Bit mask for USB_XFERCOMPL */ +#define _USB_DIEPINT_XFERCOMPL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_XFERCOMPL_DEFAULT (_USB_DIEPINT_XFERCOMPL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_EPDISBLD (0x1UL << 1) /* Endpoint Disabled Interrupt */ +#define _USB_DIEPINT_EPDISBLD_SHIFT 1 /* Shift value for USB_EPDISBLD */ +#define _USB_DIEPINT_EPDISBLD_MASK 0x2UL /* Bit mask for USB_EPDISBLD */ +#define _USB_DIEPINT_EPDISBLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_EPDISBLD_DEFAULT (_USB_DIEPINT_EPDISBLD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_AHBERR (0x1UL << 2) /* AHB Error */ +#define _USB_DIEPINT_AHBERR_SHIFT 2 /* Shift value for USB_AHBERR */ +#define _USB_DIEPINT_AHBERR_MASK 0x4UL /* Bit mask for USB_AHBERR */ +#define _USB_DIEPINT_AHBERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_AHBERR_DEFAULT (_USB_DIEPINT_AHBERR_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_TIMEOUT (0x1UL << 3) /* Timeout Condition */ +#define _USB_DIEPINT_TIMEOUT_SHIFT 3 /* Shift value for USB_TIMEOUT */ +#define _USB_DIEPINT_TIMEOUT_MASK 0x8UL /* Bit mask for USB_TIMEOUT */ +#define _USB_DIEPINT_TIMEOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_TIMEOUT_DEFAULT (_USB_DIEPINT_TIMEOUT_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_INTKNTXFEMP (0x1UL << 4) /* IN Token Received When TxFIFO is Empty */ +#define _USB_DIEPINT_INTKNTXFEMP_SHIFT 4 /* Shift value for USB_INTKNTXFEMP */ +#define _USB_DIEPINT_INTKNTXFEMP_MASK 0x10UL /* Bit mask for USB_INTKNTXFEMP */ +#define _USB_DIEPINT_INTKNTXFEMP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_INTKNTXFEMP_DEFAULT (_USB_DIEPINT_INTKNTXFEMP_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_INEPNAKEFF (0x1UL << 6) /* IN Endpoint NAK Effective */ +#define _USB_DIEPINT_INEPNAKEFF_SHIFT 6 /* Shift value for USB_INEPNAKEFF */ +#define _USB_DIEPINT_INEPNAKEFF_MASK 0x40UL /* Bit mask for USB_INEPNAKEFF */ +#define _USB_DIEPINT_INEPNAKEFF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_INEPNAKEFF_DEFAULT (_USB_DIEPINT_INEPNAKEFF_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_TXFEMP (0x1UL << 7) /* Transmit FIFO Empty */ +#define _USB_DIEPINT_TXFEMP_SHIFT 7 /* Shift value for USB_TXFEMP */ +#define _USB_DIEPINT_TXFEMP_MASK 0x80UL /* Bit mask for USB_TXFEMP */ +#define _USB_DIEPINT_TXFEMP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_TXFEMP_DEFAULT (_USB_DIEPINT_TXFEMP_DEFAULT << 7) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_PKTDRPSTS (0x1UL << 11) /* Packet Drop Status */ +#define _USB_DIEPINT_PKTDRPSTS_SHIFT 11 /* Shift value for USB_PKTDRPSTS */ +#define _USB_DIEPINT_PKTDRPSTS_MASK 0x800UL /* Bit mask for USB_PKTDRPSTS */ +#define _USB_DIEPINT_PKTDRPSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_PKTDRPSTS_DEFAULT (_USB_DIEPINT_PKTDRPSTS_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_BBLEERR (0x1UL << 12) /* NAK Interrupt */ +#define _USB_DIEPINT_BBLEERR_SHIFT 12 /* Shift value for USB_BBLEERR */ +#define _USB_DIEPINT_BBLEERR_MASK 0x1000UL /* Bit mask for USB_BBLEERR */ +#define _USB_DIEPINT_BBLEERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_BBLEERR_DEFAULT (_USB_DIEPINT_BBLEERR_DEFAULT << 12) /* Shifted mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_NAKINTRPT (0x1UL << 13) /* NAK Interrupt */ +#define _USB_DIEPINT_NAKINTRPT_SHIFT 13 /* Shift value for USB_NAKINTRPT */ +#define _USB_DIEPINT_NAKINTRPT_MASK 0x2000UL /* Bit mask for USB_NAKINTRPT */ +#define _USB_DIEPINT_NAKINTRPT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPINT */ +#define USB_DIEPINT_NAKINTRPT_DEFAULT (_USB_DIEPINT_NAKINTRPT_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DIEPINT */ + +/* Bit fields for USB DIEPTSIZ */ + +#define _USB_DIEPTSIZ_RESETVALUE 0x00000000UL /* Default value for USB_DIEPTSIZ */ +#define _USB_DIEPTSIZ_MASK 0x7FFFFFFFUL /* Mask for USB_DIEPTSIZ */ + +#define _USB_DIEPTSIZ_XFERSIZE_SHIFT 0 /* Shift value for USB_XFERSIZE */ +#define _USB_DIEPTSIZ_XFERSIZE_MASK 0x7FFFFUL /* Bit mask for USB_XFERSIZE */ +#define _USB_DIEPTSIZ_XFERSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPTSIZ */ +#define USB_DIEPTSIZ_XFERSIZE_DEFAULT (_USB_DIEPTSIZ_XFERSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTSIZ */ +#define _USB_DIEPTSIZ_PKTCNT_SHIFT 19 /* Shift value for USB_PKTCNT */ +#define _USB_DIEPTSIZ_PKTCNT_MASK 0x1FF80000UL /* Bit mask for USB_PKTCNT */ +#define _USB_DIEPTSIZ_PKTCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPTSIZ */ +#define USB_DIEPTSIZ_PKTCNT_DEFAULT (_USB_DIEPTSIZ_PKTCNT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DIEPTSIZ */ +#define _USB_DIEPTSIZ_MC_SHIFT 29 /* Shift value for USB_MC */ +#define _USB_DIEPTSIZ_MC_MASK 0x60000000UL /* Bit mask for USB_MC */ +#define _USB_DIEPTSIZ_MC_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPTSIZ */ +#define USB_DIEPTSIZ_MC_DEFAULT (_USB_DIEPTSIZ_MC_DEFAULT << 29) /* Shifted mode DEFAULT for USB_DIEPTSIZ */ + +/* Bit fields for USB DIEPDMAADDR */ + +#define _USB_DIEPDMAADDR_RESETVALUE 0x00000000UL /* Default value for USB_DIEPDMAADDR */ +#define _USB_DIEPDMAADDR_MASK 0xFFFFFFFFUL /* Mask for USB_DIEPDMAADDR */ + +#define _USB_DIEPDMAADDR_DMAADDR_SHIFT 0 /* Shift value for USB_DMAADDR */ +#define _USB_DIEPDMAADDR_DMAADDR_MASK 0xFFFFFFFFUL /* Bit mask for USB_DMAADDR */ +#define _USB_DIEPDMAADDR_DMAADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DIEPDMAADDR */ +#define USB_DIEPDMAADDR_DMAADDR_DEFAULT (_USB_DIEPDMAADDR_DMAADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPDMAADDR */ + +/* Bit fields for USB DIEPTXFSTS */ + +#define _USB_DIEPTXFSTS_RESETVALUE 0x00000200UL /* Default value for USB_DIEPTXFSTS */ +#define _USB_DIEPTXFSTS_MASK 0x0000FFFFUL /* Mask for USB_DIEPTXFSTS */ + +#define _USB_DIEPTXFSTS_SPCAVAIL_SHIFT 0 /* Shift value for USB_SPCAVAIL */ +#define _USB_DIEPTXFSTS_SPCAVAIL_MASK 0xFFFFUL /* Bit mask for USB_SPCAVAIL */ +#define _USB_DIEPTXFSTS_SPCAVAIL_DEFAULT 0x00000200UL /* Mode DEFAULT for USB_DIEPTXFSTS */ +#define USB_DIEPTXFSTS_SPCAVAIL_DEFAULT (_USB_DIEPTXFSTS_SPCAVAIL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DIEPTXFSTS */ + +/* Bit fields for USB DOEP0CTL */ + +#define _USB_DOEP0CTL_RESETVALUE 0x00008000UL /* Default value for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_MASK 0xCC3E8003UL /* Mask for USB_DOEP0CTL */ + +#define _USB_DOEP0CTL_MPS_SHIFT 0 /* Shift value for USB_MPS */ +#define _USB_DOEP0CTL_MPS_MASK 0x3UL /* Bit mask for USB_MPS */ +#define _USB_DOEP0CTL_MPS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_MPS_64B 0x00000000UL /* Mode 64B for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_MPS_32B 0x00000001UL /* Mode 32B for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_MPS_16B 0x00000002UL /* Mode 16B for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_MPS_8B 0x00000003UL /* Mode 8B for USB_DOEP0CTL */ +#define USB_DOEP0CTL_MPS_DEFAULT (_USB_DOEP0CTL_MPS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_MPS_64B (_USB_DOEP0CTL_MPS_64B << 0) /* Shifted mode 64B for USB_DOEP0CTL */ +#define USB_DOEP0CTL_MPS_32B (_USB_DOEP0CTL_MPS_32B << 0) /* Shifted mode 32B for USB_DOEP0CTL */ +#define USB_DOEP0CTL_MPS_16B (_USB_DOEP0CTL_MPS_16B << 0) /* Shifted mode 16B for USB_DOEP0CTL */ +#define USB_DOEP0CTL_MPS_8B (_USB_DOEP0CTL_MPS_8B << 0) /* Shifted mode 8B for USB_DOEP0CTL */ +#define USB_DOEP0CTL_USBACTEP (0x1UL << 15) /* USB Active Endpoint */ +#define _USB_DOEP0CTL_USBACTEP_SHIFT 15 /* Shift value for USB_USBACTEP */ +#define _USB_DOEP0CTL_USBACTEP_MASK 0x8000UL /* Bit mask for USB_USBACTEP */ +#define _USB_DOEP0CTL_USBACTEP_DEFAULT 0x00000001UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_USBACTEP_DEFAULT (_USB_DOEP0CTL_USBACTEP_DEFAULT << 15) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_NAKSTS (0x1UL << 17) /* NAK Status */ +#define _USB_DOEP0CTL_NAKSTS_SHIFT 17 /* Shift value for USB_NAKSTS */ +#define _USB_DOEP0CTL_NAKSTS_MASK 0x20000UL /* Bit mask for USB_NAKSTS */ +#define _USB_DOEP0CTL_NAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_NAKSTS_DEFAULT (_USB_DOEP0CTL_NAKSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define _USB_DOEP0CTL_EPTYPE_SHIFT 18 /* Shift value for USB_EPTYPE */ +#define _USB_DOEP0CTL_EPTYPE_MASK 0xC0000UL /* Bit mask for USB_EPTYPE */ +#define _USB_DOEP0CTL_EPTYPE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_EPTYPE_DEFAULT (_USB_DOEP0CTL_EPTYPE_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_SNP (0x1UL << 20) /* Snoop Mode */ +#define _USB_DOEP0CTL_SNP_SHIFT 20 /* Shift value for USB_SNP */ +#define _USB_DOEP0CTL_SNP_MASK 0x100000UL /* Bit mask for USB_SNP */ +#define _USB_DOEP0CTL_SNP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_SNP_DEFAULT (_USB_DOEP0CTL_SNP_DEFAULT << 20) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_STALL (0x1UL << 21) /* Handshake */ +#define _USB_DOEP0CTL_STALL_SHIFT 21 /* Shift value for USB_STALL */ +#define _USB_DOEP0CTL_STALL_MASK 0x200000UL /* Bit mask for USB_STALL */ +#define _USB_DOEP0CTL_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_STALL_DEFAULT (_USB_DOEP0CTL_STALL_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_CNAK (0x1UL << 26) /* Clear NAK */ +#define _USB_DOEP0CTL_CNAK_SHIFT 26 /* Shift value for USB_CNAK */ +#define _USB_DOEP0CTL_CNAK_MASK 0x4000000UL /* Bit mask for USB_CNAK */ +#define _USB_DOEP0CTL_CNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_CNAK_DEFAULT (_USB_DOEP0CTL_CNAK_DEFAULT << 26) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_SNAK (0x1UL << 27) /* Set NAK */ +#define _USB_DOEP0CTL_SNAK_SHIFT 27 /* Shift value for USB_SNAK */ +#define _USB_DOEP0CTL_SNAK_MASK 0x8000000UL /* Bit mask for USB_SNAK */ +#define _USB_DOEP0CTL_SNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_SNAK_DEFAULT (_USB_DOEP0CTL_SNAK_DEFAULT << 27) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_EPDIS (0x1UL << 30) /* Endpoint Disable */ +#define _USB_DOEP0CTL_EPDIS_SHIFT 30 /* Shift value for USB_EPDIS */ +#define _USB_DOEP0CTL_EPDIS_MASK 0x40000000UL /* Bit mask for USB_EPDIS */ +#define _USB_DOEP0CTL_EPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_EPDIS_DEFAULT (_USB_DOEP0CTL_EPDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_EPENA (0x1UL << 31) /* Endpoint Enable */ +#define _USB_DOEP0CTL_EPENA_SHIFT 31 /* Shift value for USB_EPENA */ +#define _USB_DOEP0CTL_EPENA_MASK 0x80000000UL /* Bit mask for USB_EPENA */ +#define _USB_DOEP0CTL_EPENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0CTL */ +#define USB_DOEP0CTL_EPENA_DEFAULT (_USB_DOEP0CTL_EPENA_DEFAULT << 31) /* Shifted mode DEFAULT for USB_DOEP0CTL */ + +/* Bit fields for USB DOEP0INT */ + +#define _USB_DOEP0INT_RESETVALUE 0x00000000UL /* Default value for USB_DOEP0INT */ +#define _USB_DOEP0INT_MASK 0x0000385FUL /* Mask for USB_DOEP0INT */ + +#define USB_DOEP0INT_XFERCOMPL (0x1UL << 0) /* Transfer Completed Interrupt */ +#define _USB_DOEP0INT_XFERCOMPL_SHIFT 0 /* Shift value for USB_XFERCOMPL */ +#define _USB_DOEP0INT_XFERCOMPL_MASK 0x1UL /* Bit mask for USB_XFERCOMPL */ +#define _USB_DOEP0INT_XFERCOMPL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_XFERCOMPL_DEFAULT (_USB_DOEP0INT_XFERCOMPL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_EPDISBLD (0x1UL << 1) /* Endpoint Disabled Interrupt */ +#define _USB_DOEP0INT_EPDISBLD_SHIFT 1 /* Shift value for USB_EPDISBLD */ +#define _USB_DOEP0INT_EPDISBLD_MASK 0x2UL /* Bit mask for USB_EPDISBLD */ +#define _USB_DOEP0INT_EPDISBLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_EPDISBLD_DEFAULT (_USB_DOEP0INT_EPDISBLD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_AHBERR (0x1UL << 2) /* AHB Error */ +#define _USB_DOEP0INT_AHBERR_SHIFT 2 /* Shift value for USB_AHBERR */ +#define _USB_DOEP0INT_AHBERR_MASK 0x4UL /* Bit mask for USB_AHBERR */ +#define _USB_DOEP0INT_AHBERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_AHBERR_DEFAULT (_USB_DOEP0INT_AHBERR_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_SETUP (0x1UL << 3) /* Setup Phase Done */ +#define _USB_DOEP0INT_SETUP_SHIFT 3 /* Shift value for USB_SETUP */ +#define _USB_DOEP0INT_SETUP_MASK 0x8UL /* Bit mask for USB_SETUP */ +#define _USB_DOEP0INT_SETUP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_SETUP_DEFAULT (_USB_DOEP0INT_SETUP_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_OUTTKNEPDIS (0x1UL << 4) /* OUT Token Received When Endpoint Disabled */ +#define _USB_DOEP0INT_OUTTKNEPDIS_SHIFT 4 /* Shift value for USB_OUTTKNEPDIS */ +#define _USB_DOEP0INT_OUTTKNEPDIS_MASK 0x10UL /* Bit mask for USB_OUTTKNEPDIS */ +#define _USB_DOEP0INT_OUTTKNEPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_OUTTKNEPDIS_DEFAULT (_USB_DOEP0INT_OUTTKNEPDIS_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_BACK2BACKSETUP (0x1UL << 6) /* Back-to-Back SETUP Packets Received */ +#define _USB_DOEP0INT_BACK2BACKSETUP_SHIFT 6 /* Shift value for USB_BACK2BACKSETUP */ +#define _USB_DOEP0INT_BACK2BACKSETUP_MASK 0x40UL /* Bit mask for USB_BACK2BACKSETUP */ +#define _USB_DOEP0INT_BACK2BACKSETUP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_BACK2BACKSETUP_DEFAULT (_USB_DOEP0INT_BACK2BACKSETUP_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_PKTDRPSTS (0x1UL << 11) /* Packet Drop Status */ +#define _USB_DOEP0INT_PKTDRPSTS_SHIFT 11 /* Shift value for USB_PKTDRPSTS */ +#define _USB_DOEP0INT_PKTDRPSTS_MASK 0x800UL /* Bit mask for USB_PKTDRPSTS */ +#define _USB_DOEP0INT_PKTDRPSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_PKTDRPSTS_DEFAULT (_USB_DOEP0INT_PKTDRPSTS_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_BBLEERR (0x1UL << 12) /* NAK Interrupt */ +#define _USB_DOEP0INT_BBLEERR_SHIFT 12 /* Shift value for USB_BBLEERR */ +#define _USB_DOEP0INT_BBLEERR_MASK 0x1000UL /* Bit mask for USB_BBLEERR */ +#define _USB_DOEP0INT_BBLEERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_BBLEERR_DEFAULT (_USB_DOEP0INT_BBLEERR_DEFAULT << 12) /* Shifted mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_NAKINTRPT (0x1UL << 13) /* NAK Interrupt */ +#define _USB_DOEP0INT_NAKINTRPT_SHIFT 13 /* Shift value for USB_NAKINTRPT */ +#define _USB_DOEP0INT_NAKINTRPT_MASK 0x2000UL /* Bit mask for USB_NAKINTRPT */ +#define _USB_DOEP0INT_NAKINTRPT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0INT */ +#define USB_DOEP0INT_NAKINTRPT_DEFAULT (_USB_DOEP0INT_NAKINTRPT_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DOEP0INT */ + +/* Bit fields for USB DOEP0TSIZ */ + +#define _USB_DOEP0TSIZ_RESETVALUE 0x00000000UL /* Default value for USB_DOEP0TSIZ */ +#define _USB_DOEP0TSIZ_MASK 0x6008007FUL /* Mask for USB_DOEP0TSIZ */ + +#define _USB_DOEP0TSIZ_XFERSIZE_SHIFT 0 /* Shift value for USB_XFERSIZE */ +#define _USB_DOEP0TSIZ_XFERSIZE_MASK 0x7FUL /* Bit mask for USB_XFERSIZE */ +#define _USB_DOEP0TSIZ_XFERSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0TSIZ */ +#define USB_DOEP0TSIZ_XFERSIZE_DEFAULT (_USB_DOEP0TSIZ_XFERSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEP0TSIZ */ +#define USB_DOEP0TSIZ_PKTCNT (0x1UL << 19) /* Packet Count */ +#define _USB_DOEP0TSIZ_PKTCNT_SHIFT 19 /* Shift value for USB_PKTCNT */ +#define _USB_DOEP0TSIZ_PKTCNT_MASK 0x80000UL /* Bit mask for USB_PKTCNT */ +#define _USB_DOEP0TSIZ_PKTCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0TSIZ */ +#define USB_DOEP0TSIZ_PKTCNT_DEFAULT (_USB_DOEP0TSIZ_PKTCNT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DOEP0TSIZ */ +#define _USB_DOEP0TSIZ_SUPCNT_SHIFT 29 /* Shift value for USB_SUPCNT */ +#define _USB_DOEP0TSIZ_SUPCNT_MASK 0x60000000UL /* Bit mask for USB_SUPCNT */ +#define _USB_DOEP0TSIZ_SUPCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0TSIZ */ +#define USB_DOEP0TSIZ_SUPCNT_DEFAULT (_USB_DOEP0TSIZ_SUPCNT_DEFAULT << 29) /* Shifted mode DEFAULT for USB_DOEP0TSIZ */ + +/* Bit fields for USB DOEP0DMAADDR */ + +#define _USB_DOEP0DMAADDR_RESETVALUE 0x00000000UL /* Default value for USB_DOEP0DMAADDR */ +#define _USB_DOEP0DMAADDR_MASK 0xFFFFFFFFUL /* Mask for USB_DOEP0DMAADDR */ + +#define _USB_DOEP0DMAADDR_DOEP0DMAADDR_SHIFT 0 /* Shift value for USB_DOEP0DMAADDR */ +#define _USB_DOEP0DMAADDR_DOEP0DMAADDR_MASK 0xFFFFFFFFUL /* Bit mask for USB_DOEP0DMAADDR */ +#define _USB_DOEP0DMAADDR_DOEP0DMAADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEP0DMAADDR */ +#define USB_DOEP0DMAADDR_DOEP0DMAADDR_DEFAULT (_USB_DOEP0DMAADDR_DOEP0DMAADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEP0DMAADDR */ + +/* Bit fields for USB DOEPCTL */ + +#define _USB_DOEPCTL_RESETVALUE 0x00000000UL /* Default value for USB_DOEPCTL */ +#define _USB_DOEPCTL_MASK 0xFC3F87FFUL /* Mask for USB_DOEPCTL */ + +#define _USB_DOEPCTL_MPS_SHIFT 0 /* Shift value for USB_MPS */ +#define _USB_DOEPCTL_MPS_MASK 0x7FFUL /* Bit mask for USB_MPS */ +#define _USB_DOEPCTL_MPS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_MPS_DEFAULT (_USB_DOEPCTL_MPS_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_USBACTEP (0x1UL << 15) /* USB Active Endpoint */ +#define _USB_DOEPCTL_USBACTEP_SHIFT 15 /* Shift value for USB_USBACTEP */ +#define _USB_DOEPCTL_USBACTEP_MASK 0x8000UL /* Bit mask for USB_USBACTEP */ +#define _USB_DOEPCTL_USBACTEP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_USBACTEP_DEFAULT (_USB_DOEPCTL_USBACTEP_DEFAULT << 15) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_DPIDEOF (0x1UL << 16) /* Endpoint Data PID / Even-odd Frame */ +#define _USB_DOEPCTL_DPIDEOF_SHIFT 16 /* Shift value for USB_DPIDEOF */ +#define _USB_DOEPCTL_DPIDEOF_MASK 0x10000UL /* Bit mask for USB_DPIDEOF */ +#define _USB_DOEPCTL_DPIDEOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define _USB_DOEPCTL_DPIDEOF_DATA0EVEN 0x00000000UL /* Mode DATA0EVEN for USB_DOEPCTL */ +#define _USB_DOEPCTL_DPIDEOF_DATA1ODD 0x00000001UL /* Mode DATA1ODD for USB_DOEPCTL */ +#define USB_DOEPCTL_DPIDEOF_DEFAULT (_USB_DOEPCTL_DPIDEOF_DEFAULT << 16) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_DPIDEOF_DATA0EVEN (_USB_DOEPCTL_DPIDEOF_DATA0EVEN << 16) /* Shifted mode DATA0EVEN for USB_DOEPCTL */ +#define USB_DOEPCTL_DPIDEOF_DATA1ODD (_USB_DOEPCTL_DPIDEOF_DATA1ODD << 16) /* Shifted mode DATA1ODD for USB_DOEPCTL */ +#define USB_DOEPCTL_NAKSTS (0x1UL << 17) /* NAK Status */ +#define _USB_DOEPCTL_NAKSTS_SHIFT 17 /* Shift value for USB_NAKSTS */ +#define _USB_DOEPCTL_NAKSTS_MASK 0x20000UL /* Bit mask for USB_NAKSTS */ +#define _USB_DOEPCTL_NAKSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_NAKSTS_DEFAULT (_USB_DOEPCTL_NAKSTS_DEFAULT << 17) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define _USB_DOEPCTL_EPTYPE_SHIFT 18 /* Shift value for USB_EPTYPE */ +#define _USB_DOEPCTL_EPTYPE_MASK 0xC0000UL /* Bit mask for USB_EPTYPE */ +#define _USB_DOEPCTL_EPTYPE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define _USB_DOEPCTL_EPTYPE_CONTROL 0x00000000UL /* Mode CONTROL for USB_DOEPCTL */ +#define _USB_DOEPCTL_EPTYPE_ISO 0x00000001UL /* Mode ISO for USB_DOEPCTL */ +#define _USB_DOEPCTL_EPTYPE_BULK 0x00000002UL /* Mode BULK for USB_DOEPCTL */ +#define _USB_DOEPCTL_EPTYPE_INT 0x00000003UL /* Mode INT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPTYPE_DEFAULT (_USB_DOEPCTL_EPTYPE_DEFAULT << 18) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPTYPE_CONTROL (_USB_DOEPCTL_EPTYPE_CONTROL << 18) /* Shifted mode CONTROL for USB_DOEPCTL */ +#define USB_DOEPCTL_EPTYPE_ISO (_USB_DOEPCTL_EPTYPE_ISO << 18) /* Shifted mode ISO for USB_DOEPCTL */ +#define USB_DOEPCTL_EPTYPE_BULK (_USB_DOEPCTL_EPTYPE_BULK << 18) /* Shifted mode BULK for USB_DOEPCTL */ +#define USB_DOEPCTL_EPTYPE_INT (_USB_DOEPCTL_EPTYPE_INT << 18) /* Shifted mode INT for USB_DOEPCTL */ +#define USB_DOEPCTL_SNP (0x1UL << 20) /* Snoop Mode */ +#define _USB_DOEPCTL_SNP_SHIFT 20 /* Shift value for USB_SNP */ +#define _USB_DOEPCTL_SNP_MASK 0x100000UL /* Bit mask for USB_SNP */ +#define _USB_DOEPCTL_SNP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SNP_DEFAULT (_USB_DOEPCTL_SNP_DEFAULT << 20) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_STALL (0x1UL << 21) /* STALL Handshake */ +#define _USB_DOEPCTL_STALL_SHIFT 21 /* Shift value for USB_STALL */ +#define _USB_DOEPCTL_STALL_MASK 0x200000UL /* Bit mask for USB_STALL */ +#define _USB_DOEPCTL_STALL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_STALL_DEFAULT (_USB_DOEPCTL_STALL_DEFAULT << 21) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_CNAK (0x1UL << 26) /* Clear NAK */ +#define _USB_DOEPCTL_CNAK_SHIFT 26 /* Shift value for USB_CNAK */ +#define _USB_DOEPCTL_CNAK_MASK 0x4000000UL /* Bit mask for USB_CNAK */ +#define _USB_DOEPCTL_CNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_CNAK_DEFAULT (_USB_DOEPCTL_CNAK_DEFAULT << 26) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SNAK (0x1UL << 27) /* Set NAK */ +#define _USB_DOEPCTL_SNAK_SHIFT 27 /* Shift value for USB_SNAK */ +#define _USB_DOEPCTL_SNAK_MASK 0x8000000UL /* Bit mask for USB_SNAK */ +#define _USB_DOEPCTL_SNAK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SNAK_DEFAULT (_USB_DOEPCTL_SNAK_DEFAULT << 27) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SETD0PIDEF (0x1UL << 28) /* Set DATA0 PID / Even Frame */ +#define _USB_DOEPCTL_SETD0PIDEF_SHIFT 28 /* Shift value for USB_SETD0PIDEF */ +#define _USB_DOEPCTL_SETD0PIDEF_MASK 0x10000000UL /* Bit mask for USB_SETD0PIDEF */ +#define _USB_DOEPCTL_SETD0PIDEF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SETD0PIDEF_DEFAULT (_USB_DOEPCTL_SETD0PIDEF_DEFAULT << 28) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SETD1PIDOF (0x1UL << 29) /* Set DATA1 PID / Odd Frame */ +#define _USB_DOEPCTL_SETD1PIDOF_SHIFT 29 /* Shift value for USB_SETD1PIDOF */ +#define _USB_DOEPCTL_SETD1PIDOF_MASK 0x20000000UL /* Bit mask for USB_SETD1PIDOF */ +#define _USB_DOEPCTL_SETD1PIDOF_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_SETD1PIDOF_DEFAULT (_USB_DOEPCTL_SETD1PIDOF_DEFAULT << 29) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPDIS (0x1UL << 30) /* Endpoint Disable */ +#define _USB_DOEPCTL_EPDIS_SHIFT 30 /* Shift value for USB_EPDIS */ +#define _USB_DOEPCTL_EPDIS_MASK 0x40000000UL /* Bit mask for USB_EPDIS */ +#define _USB_DOEPCTL_EPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPDIS_DEFAULT (_USB_DOEPCTL_EPDIS_DEFAULT << 30) /* Shifted mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPENA (0x1UL << 31) /* Endpoint Enable */ +#define _USB_DOEPCTL_EPENA_SHIFT 31 /* Shift value for USB_EPENA */ +#define _USB_DOEPCTL_EPENA_MASK 0x80000000UL /* Bit mask for USB_EPENA */ +#define _USB_DOEPCTL_EPENA_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPCTL */ +#define USB_DOEPCTL_EPENA_DEFAULT (_USB_DOEPCTL_EPENA_DEFAULT << 31) /* Shifted mode DEFAULT for USB_DOEPCTL */ + +/* Bit fields for USB DOEPINT */ + +#define _USB_DOEPINT_RESETVALUE 0x00000000UL /* Default value for USB_DOEPINT */ +#define _USB_DOEPINT_MASK 0x0000385FUL /* Mask for USB_DOEPINT */ + +#define USB_DOEPINT_XFERCOMPL (0x1UL << 0) /* Transfer Completed Interrupt */ +#define _USB_DOEPINT_XFERCOMPL_SHIFT 0 /* Shift value for USB_XFERCOMPL */ +#define _USB_DOEPINT_XFERCOMPL_MASK 0x1UL /* Bit mask for USB_XFERCOMPL */ +#define _USB_DOEPINT_XFERCOMPL_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_XFERCOMPL_DEFAULT (_USB_DOEPINT_XFERCOMPL_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_EPDISBLD (0x1UL << 1) /* Endpoint Disabled Interrupt */ +#define _USB_DOEPINT_EPDISBLD_SHIFT 1 /* Shift value for USB_EPDISBLD */ +#define _USB_DOEPINT_EPDISBLD_MASK 0x2UL /* Bit mask for USB_EPDISBLD */ +#define _USB_DOEPINT_EPDISBLD_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_EPDISBLD_DEFAULT (_USB_DOEPINT_EPDISBLD_DEFAULT << 1) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_AHBERR (0x1UL << 2) /* AHB Error */ +#define _USB_DOEPINT_AHBERR_SHIFT 2 /* Shift value for USB_AHBERR */ +#define _USB_DOEPINT_AHBERR_MASK 0x4UL /* Bit mask for USB_AHBERR */ +#define _USB_DOEPINT_AHBERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_AHBERR_DEFAULT (_USB_DOEPINT_AHBERR_DEFAULT << 2) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_SETUP (0x1UL << 3) /* Setup Phase Done */ +#define _USB_DOEPINT_SETUP_SHIFT 3 /* Shift value for USB_SETUP */ +#define _USB_DOEPINT_SETUP_MASK 0x8UL /* Bit mask for USB_SETUP */ +#define _USB_DOEPINT_SETUP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_SETUP_DEFAULT (_USB_DOEPINT_SETUP_DEFAULT << 3) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_OUTTKNEPDIS (0x1UL << 4) /* OUT Token Received When Endpoint Disabled */ +#define _USB_DOEPINT_OUTTKNEPDIS_SHIFT 4 /* Shift value for USB_OUTTKNEPDIS */ +#define _USB_DOEPINT_OUTTKNEPDIS_MASK 0x10UL /* Bit mask for USB_OUTTKNEPDIS */ +#define _USB_DOEPINT_OUTTKNEPDIS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_OUTTKNEPDIS_DEFAULT (_USB_DOEPINT_OUTTKNEPDIS_DEFAULT << 4) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_BACK2BACKSETUP (0x1UL << 6) /* Back-to-Back SETUP Packets Received */ +#define _USB_DOEPINT_BACK2BACKSETUP_SHIFT 6 /* Shift value for USB_BACK2BACKSETUP */ +#define _USB_DOEPINT_BACK2BACKSETUP_MASK 0x40UL /* Bit mask for USB_BACK2BACKSETUP */ +#define _USB_DOEPINT_BACK2BACKSETUP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_BACK2BACKSETUP_DEFAULT (_USB_DOEPINT_BACK2BACKSETUP_DEFAULT << 6) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_PKTDRPSTS (0x1UL << 11) /* Packet Drop Status */ +#define _USB_DOEPINT_PKTDRPSTS_SHIFT 11 /* Shift value for USB_PKTDRPSTS */ +#define _USB_DOEPINT_PKTDRPSTS_MASK 0x800UL /* Bit mask for USB_PKTDRPSTS */ +#define _USB_DOEPINT_PKTDRPSTS_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_PKTDRPSTS_DEFAULT (_USB_DOEPINT_PKTDRPSTS_DEFAULT << 11) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_BBLEERR (0x1UL << 12) /* Babble Error */ +#define _USB_DOEPINT_BBLEERR_SHIFT 12 /* Shift value for USB_BBLEERR */ +#define _USB_DOEPINT_BBLEERR_MASK 0x1000UL /* Bit mask for USB_BBLEERR */ +#define _USB_DOEPINT_BBLEERR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_BBLEERR_DEFAULT (_USB_DOEPINT_BBLEERR_DEFAULT << 12) /* Shifted mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_NAKINTRPT (0x1UL << 13) /* NAK Interrupt */ +#define _USB_DOEPINT_NAKINTRPT_SHIFT 13 /* Shift value for USB_NAKINTRPT */ +#define _USB_DOEPINT_NAKINTRPT_MASK 0x2000UL /* Bit mask for USB_NAKINTRPT */ +#define _USB_DOEPINT_NAKINTRPT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPINT */ +#define USB_DOEPINT_NAKINTRPT_DEFAULT (_USB_DOEPINT_NAKINTRPT_DEFAULT << 13) /* Shifted mode DEFAULT for USB_DOEPINT */ + +/* Bit fields for USB DOEPTSIZ */ + +#define _USB_DOEPTSIZ_RESETVALUE 0x00000000UL /* Default value for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_MASK 0x7FFFFFFFUL /* Mask for USB_DOEPTSIZ */ + +#define _USB_DOEPTSIZ_XFERSIZE_SHIFT 0 /* Shift value for USB_XFERSIZE */ +#define _USB_DOEPTSIZ_XFERSIZE_MASK 0x7FFFFUL /* Bit mask for USB_XFERSIZE */ +#define _USB_DOEPTSIZ_XFERSIZE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_XFERSIZE_DEFAULT (_USB_DOEPTSIZ_XFERSIZE_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_PKTCNT_SHIFT 19 /* Shift value for USB_PKTCNT */ +#define _USB_DOEPTSIZ_PKTCNT_MASK 0x1FF80000UL /* Bit mask for USB_PKTCNT */ +#define _USB_DOEPTSIZ_PKTCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_PKTCNT_DEFAULT (_USB_DOEPTSIZ_PKTCNT_DEFAULT << 19) /* Shifted mode DEFAULT for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_SHIFT 29 /* Shift value for USB_RXDPIDSUPCNT */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_MASK 0x60000000UL /* Bit mask for USB_RXDPIDSUPCNT */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_DATA0 0x00000000UL /* Mode DATA0 for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_DATA2 0x00000001UL /* Mode DATA2 for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_DATA1 0x00000002UL /* Mode DATA1 for USB_DOEPTSIZ */ +#define _USB_DOEPTSIZ_RXDPIDSUPCNT_MDATA 0x00000003UL /* Mode MDATA for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_RXDPIDSUPCNT_DEFAULT (_USB_DOEPTSIZ_RXDPIDSUPCNT_DEFAULT << 29) /* Shifted mode DEFAULT for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_RXDPIDSUPCNT_DATA0 (_USB_DOEPTSIZ_RXDPIDSUPCNT_DATA0 << 29) /* Shifted mode DATA0 for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_RXDPIDSUPCNT_DATA2 (_USB_DOEPTSIZ_RXDPIDSUPCNT_DATA2 << 29) /* Shifted mode DATA2 for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_RXDPIDSUPCNT_DATA1 (_USB_DOEPTSIZ_RXDPIDSUPCNT_DATA1 << 29) /* Shifted mode DATA1 for USB_DOEPTSIZ */ +#define USB_DOEPTSIZ_RXDPIDSUPCNT_MDATA (_USB_DOEPTSIZ_RXDPIDSUPCNT_MDATA << 29) /* Shifted mode MDATA for USB_DOEPTSIZ */ + +/* Bit fields for USB DOEPDMAADDR */ + +#define _USB_DOEPDMAADDR_RESETVALUE 0x00000000UL /* Default value for USB_DOEPDMAADDR */ +#define _USB_DOEPDMAADDR_MASK 0xFFFFFFFFUL /* Mask for USB_DOEPDMAADDR */ + +#define _USB_DOEPDMAADDR_DMAADDR_SHIFT 0 /* Shift value for USB_DMAADDR */ +#define _USB_DOEPDMAADDR_DMAADDR_MASK 0xFFFFFFFFUL /* Bit mask for USB_DMAADDR */ +#define _USB_DOEPDMAADDR_DMAADDR_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_DOEPDMAADDR */ +#define USB_DOEPDMAADDR_DMAADDR_DEFAULT (_USB_DOEPDMAADDR_DMAADDR_DEFAULT << 0) /* Shifted mode DEFAULT for USB_DOEPDMAADDR */ + +/* Bit fields for USB PCGCCTL */ + +#define _USB_PCGCCTL_RESETVALUE 0x00000000UL /* Default value for USB_PCGCCTL */ +#define _USB_PCGCCTL_MASK 0x0000014FUL /* Mask for USB_PCGCCTL */ + +#define USB_PCGCCTL_STOPPCLK (0x1UL << 0) /* Stop PHY clock */ +#define _USB_PCGCCTL_STOPPCLK_SHIFT 0 /* Shift value for USB_STOPPCLK */ +#define _USB_PCGCCTL_STOPPCLK_MASK 0x1UL /* Bit mask for USB_STOPPCLK */ +#define _USB_PCGCCTL_STOPPCLK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_STOPPCLK_DEFAULT (_USB_PCGCCTL_STOPPCLK_DEFAULT << 0) /* Shifted mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_GATEHCLK (0x1UL << 1) /* Gate HCLK */ +#define _USB_PCGCCTL_GATEHCLK_SHIFT 1 /* Shift value for USB_GATEHCLK */ +#define _USB_PCGCCTL_GATEHCLK_MASK 0x2UL /* Bit mask for USB_GATEHCLK */ +#define _USB_PCGCCTL_GATEHCLK_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_GATEHCLK_DEFAULT (_USB_PCGCCTL_GATEHCLK_DEFAULT << 1) /* Shifted mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_PWRCLMP (0x1UL << 2) /* Power Clamp */ +#define _USB_PCGCCTL_PWRCLMP_SHIFT 2 /* Shift value for USB_PWRCLMP */ +#define _USB_PCGCCTL_PWRCLMP_MASK 0x4UL /* Bit mask for USB_PWRCLMP */ +#define _USB_PCGCCTL_PWRCLMP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_PWRCLMP_DEFAULT (_USB_PCGCCTL_PWRCLMP_DEFAULT << 2) /* Shifted mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_RSTPDWNMODULE (0x1UL << 3) /* Reset Power-Down Modules */ +#define _USB_PCGCCTL_RSTPDWNMODULE_SHIFT 3 /* Shift value for USB_RSTPDWNMODULE */ +#define _USB_PCGCCTL_RSTPDWNMODULE_MASK 0x8UL /* Bit mask for USB_RSTPDWNMODULE */ +#define _USB_PCGCCTL_RSTPDWNMODULE_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_RSTPDWNMODULE_DEFAULT (_USB_PCGCCTL_RSTPDWNMODULE_DEFAULT << 3) /* Shifted mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_PHYSLEEP (0x1UL << 6) /* PHY In Sleep */ +#define _USB_PCGCCTL_PHYSLEEP_SHIFT 6 /* Shift value for USB_PHYSLEEP */ +#define _USB_PCGCCTL_PHYSLEEP_MASK 0x40UL /* Bit mask for USB_PHYSLEEP */ +#define _USB_PCGCCTL_PHYSLEEP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_PHYSLEEP_DEFAULT (_USB_PCGCCTL_PHYSLEEP_DEFAULT << 6) /* Shifted mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_RESETAFTERSUSP (0x1UL << 8) /* Reset after suspend */ +#define _USB_PCGCCTL_RESETAFTERSUSP_SHIFT 8 /* Shift value for USB_RESETAFTERSUSP */ +#define _USB_PCGCCTL_RESETAFTERSUSP_MASK 0x100UL /* Bit mask for USB_RESETAFTERSUSP */ +#define _USB_PCGCCTL_RESETAFTERSUSP_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_PCGCCTL */ +#define USB_PCGCCTL_RESETAFTERSUSP_DEFAULT (_USB_PCGCCTL_RESETAFTERSUSP_DEFAULT << 8) /* Shifted mode DEFAULT for USB_PCGCCTL */ + +/* Bit fields for USB FIFO0D */ + +#define _USB_FIFO0D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO0D */ +#define _USB_FIFO0D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO0D */ + +#define _USB_FIFO0D_FIFO0D_SHIFT 0 /* Shift value for USB_FIFO0D */ +#define _USB_FIFO0D_FIFO0D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO0D */ +#define _USB_FIFO0D_FIFO0D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO0D */ +#define USB_FIFO0D_FIFO0D_DEFAULT (_USB_FIFO0D_FIFO0D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO0D */ + +/* Bit fields for USB FIFO1D */ + +#define _USB_FIFO1D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO1D */ +#define _USB_FIFO1D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO1D */ + +#define _USB_FIFO1D_FIFO1D_SHIFT 0 /* Shift value for USB_FIFO1D */ +#define _USB_FIFO1D_FIFO1D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO1D */ +#define _USB_FIFO1D_FIFO1D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO1D */ +#define USB_FIFO1D_FIFO1D_DEFAULT (_USB_FIFO1D_FIFO1D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO1D */ + +/* Bit fields for USB FIFO2D */ + +#define _USB_FIFO2D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO2D */ +#define _USB_FIFO2D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO2D */ + +#define _USB_FIFO2D_FIFO2D_SHIFT 0 /* Shift value for USB_FIFO2D */ +#define _USB_FIFO2D_FIFO2D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO2D */ +#define _USB_FIFO2D_FIFO2D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO2D */ +#define USB_FIFO2D_FIFO2D_DEFAULT (_USB_FIFO2D_FIFO2D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO2D */ + +/* Bit fields for USB FIFO3D */ + +#define _USB_FIFO3D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO3D */ +#define _USB_FIFO3D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO3D */ + +#define _USB_FIFO3D_FIFO3D_SHIFT 0 /* Shift value for USB_FIFO3D */ +#define _USB_FIFO3D_FIFO3D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO3D */ +#define _USB_FIFO3D_FIFO3D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO3D */ +#define USB_FIFO3D_FIFO3D_DEFAULT (_USB_FIFO3D_FIFO3D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO3D */ + +/* Bit fields for USB FIFO4D */ + +#define _USB_FIFO4D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO4D */ +#define _USB_FIFO4D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO4D */ + +#define _USB_FIFO4D_FIFO4D_SHIFT 0 /* Shift value for USB_FIFO4D */ +#define _USB_FIFO4D_FIFO4D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO4D */ +#define _USB_FIFO4D_FIFO4D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO4D */ +#define USB_FIFO4D_FIFO4D_DEFAULT (_USB_FIFO4D_FIFO4D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO4D */ + +/* Bit fields for USB FIFO5D */ + +#define _USB_FIFO5D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO5D */ +#define _USB_FIFO5D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO5D */ + +#define _USB_FIFO5D_FIFO5D_SHIFT 0 /* Shift value for USB_FIFO5D */ +#define _USB_FIFO5D_FIFO5D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO5D */ +#define _USB_FIFO5D_FIFO5D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO5D */ +#define USB_FIFO5D_FIFO5D_DEFAULT (_USB_FIFO5D_FIFO5D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO5D */ + +/* Bit fields for USB FIFO6D */ + +#define _USB_FIFO6D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO6D */ +#define _USB_FIFO6D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO6D */ + +#define _USB_FIFO6D_FIFO6D_SHIFT 0 /* Shift value for USB_FIFO6D */ +#define _USB_FIFO6D_FIFO6D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO6D */ +#define _USB_FIFO6D_FIFO6D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO6D */ +#define USB_FIFO6D_FIFO6D_DEFAULT (_USB_FIFO6D_FIFO6D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO6D */ + +/* Bit fields for USB FIFO7D */ + +#define _USB_FIFO7D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO7D */ +#define _USB_FIFO7D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO7D */ + +#define _USB_FIFO7D_FIFO7D_SHIFT 0 /* Shift value for USB_FIFO7D */ +#define _USB_FIFO7D_FIFO7D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO7D */ +#define _USB_FIFO7D_FIFO7D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO7D */ +#define USB_FIFO7D_FIFO7D_DEFAULT (_USB_FIFO7D_FIFO7D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO7D */ + +/* Bit fields for USB FIFO8D */ + +#define _USB_FIFO8D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO8D */ +#define _USB_FIFO8D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO8D */ + +#define _USB_FIFO8D_FIFO8D_SHIFT 0 /* Shift value for USB_FIFO8D */ +#define _USB_FIFO8D_FIFO8D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO8D */ +#define _USB_FIFO8D_FIFO8D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO8D */ +#define USB_FIFO8D_FIFO8D_DEFAULT (_USB_FIFO8D_FIFO8D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO8D */ + +/* Bit fields for USB FIFO9D */ + +#define _USB_FIFO9D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO9D */ +#define _USB_FIFO9D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO9D */ + +#define _USB_FIFO9D_FIFO9D_SHIFT 0 /* Shift value for USB_FIFO9D */ +#define _USB_FIFO9D_FIFO9D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO9D */ +#define _USB_FIFO9D_FIFO9D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO9D */ +#define USB_FIFO9D_FIFO9D_DEFAULT (_USB_FIFO9D_FIFO9D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO9D */ + +/* Bit fields for USB FIFO10D */ + +#define _USB_FIFO10D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO10D */ +#define _USB_FIFO10D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO10D */ + +#define _USB_FIFO10D_FIFO10D_SHIFT 0 /* Shift value for USB_FIFO10D */ +#define _USB_FIFO10D_FIFO10D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO10D */ +#define _USB_FIFO10D_FIFO10D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO10D */ +#define USB_FIFO10D_FIFO10D_DEFAULT (_USB_FIFO10D_FIFO10D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO10D */ + +/* Bit fields for USB FIFO11D */ + +#define _USB_FIFO11D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO11D */ +#define _USB_FIFO11D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO11D */ + +#define _USB_FIFO11D_FIFO11D_SHIFT 0 /* Shift value for USB_FIFO11D */ +#define _USB_FIFO11D_FIFO11D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO11D */ +#define _USB_FIFO11D_FIFO11D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO11D */ +#define USB_FIFO11D_FIFO11D_DEFAULT (_USB_FIFO11D_FIFO11D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO11D */ + +/* Bit fields for USB FIFO12D */ + +#define _USB_FIFO12D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO12D */ +#define _USB_FIFO12D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO12D */ + +#define _USB_FIFO12D_FIFO12D_SHIFT 0 /* Shift value for USB_FIFO12D */ +#define _USB_FIFO12D_FIFO12D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO12D */ +#define _USB_FIFO12D_FIFO12D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO12D */ +#define USB_FIFO12D_FIFO12D_DEFAULT (_USB_FIFO12D_FIFO12D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO12D */ + +/* Bit fields for USB FIFO13D */ + +#define _USB_FIFO13D_RESETVALUE 0x00000000UL /* Default value for USB_FIFO13D */ +#define _USB_FIFO13D_MASK 0xFFFFFFFFUL /* Mask for USB_FIFO13D */ + +#define _USB_FIFO13D_FIFO13D_SHIFT 0 /* Shift value for USB_FIFO13D */ +#define _USB_FIFO13D_FIFO13D_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFO13D */ +#define _USB_FIFO13D_FIFO13D_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFO13D */ +#define USB_FIFO13D_FIFO13D_DEFAULT (_USB_FIFO13D_FIFO13D_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFO13D */ + +/* Bit fields for USB FIFORAM */ + +#define _USB_FIFORAM_RESETVALUE 0x00000000UL /* Default value for USB_FIFORAM */ +#define _USB_FIFORAM_MASK 0xFFFFFFFFUL /* Mask for USB_FIFORAM */ + +#define _USB_FIFORAM_FIFORAM_SHIFT 0 /* Shift value for USB_FIFORAM */ +#define _USB_FIFORAM_FIFORAM_MASK 0xFFFFFFFFUL /* Bit mask for USB_FIFORAM */ +#define _USB_FIFORAM_FIFORAM_DEFAULT 0x00000000UL /* Mode DEFAULT for USB_FIFORAM */ +#define USB_FIFORAM_FIFORAM_DEFAULT (_USB_FIFORAM_FIFORAM_DEFAULT << 0) /* Shifted mode DEFAULT for USB_FIFORAM */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_USB_H */ diff --git a/arch/arm/src/efm32/chip/efm32_vcmp.h b/arch/arm/src/efm32/chip/efm32_vcmp.h new file mode 100644 index 0000000000000000000000000000000000000000..ec71abd87842e671bc14eee29ac9198ff5e66ccf --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_vcmp.h @@ -0,0 +1,255 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_vcmp.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_VCMP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_VCMP_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* VCMP Register Offsets *******************************************************************************************************/ + +#define EFM32_VCMP_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_VCMP_INPUTSEL_OFFSET 0x0004 /* Input Selection Register */ +#define EFM32_VCMP_STATUS_OFFSET 0x0008 /* Status Register */ +#define EFM32_VCMP_IEN_OFFSET 0x000c /* Interrupt Enable Register */ +#define EFM32_VCMP_IF_OFFSET 0x0010 /* Interrupt Flag Register */ +#define EFM32_VCMP_IFS_OFFSET 0x0014 /* Interrupt Flag Set Register */ +#define EFM32_VCMP_IFC_OFFSET 0x0018 /* Interrupt Flag Clear Register */ + +/* VCMP Register Addresses *****************************************************************************************************/ + +#define EFM32_VCMP_CTRL (EFM32_VCMP_BASE+EFM32_VCMP_CTRL_OFFSET) +#define EFM32_VCMP_INPUTSEL (EFM32_VCMP_BASE+EFM32_VCMP_INPUTSEL_OFFSET) +#define EFM32_VCMP_STATUS (EFM32_VCMP_BASE+EFM32_VCMP_STATUS_OFFSET) +#define EFM32_VCMP_IEN (EFM32_VCMP_BASE+EFM32_VCMP_IEN_OFFSET) +#define EFM32_VCMP_IF (EFM32_VCMP_BASE+EFM32_VCMP_IF_OFFSET) +#define EFM32_VCMP_IFS (EFM32_VCMP_BASE+EFM32_VCMP_IFS_OFFSET) +#define EFM32_VCMP_IFC (EFM32_VCMP_BASE+EFM32_VCMP_IFC_OFFSET) + +/* VCMP Register Bit Field Definitions *****************************************************************************************/ + +/* Bit fields for VCMP CTRL */ + +#define _VCMP_CTRL_RESETVALUE 0x47000000UL /* Default value for VCMP_CTRL */ +#define _VCMP_CTRL_MASK 0x4F030715UL /* Mask for VCMP_CTRL */ + +#define VCMP_CTRL_EN (0x1UL << 0) /* Voltage Supply Comparator Enable */ +#define _VCMP_CTRL_EN_SHIFT 0 /* Shift value for VCMP_EN */ +#define _VCMP_CTRL_EN_MASK 0x1UL /* Bit mask for VCMP_EN */ +#define _VCMP_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_EN_DEFAULT (_VCMP_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_INACTVAL (0x1UL << 2) /* Inactive Value */ +#define _VCMP_CTRL_INACTVAL_SHIFT 2 /* Shift value for VCMP_INACTVAL */ +#define _VCMP_CTRL_INACTVAL_MASK 0x4UL /* Bit mask for VCMP_INACTVAL */ +#define _VCMP_CTRL_INACTVAL_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_INACTVAL_DEFAULT (_VCMP_CTRL_INACTVAL_DEFAULT << 2) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_HYSTEN (0x1UL << 4) /* Hysteresis Enable */ +#define _VCMP_CTRL_HYSTEN_SHIFT 4 /* Shift value for VCMP_HYSTEN */ +#define _VCMP_CTRL_HYSTEN_MASK 0x10UL /* Bit mask for VCMP_HYSTEN */ +#define _VCMP_CTRL_HYSTEN_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_HYSTEN_DEFAULT (_VCMP_CTRL_HYSTEN_DEFAULT << 4) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_SHIFT 8 /* Shift value for VCMP_WARMTIME */ +#define _VCMP_CTRL_WARMTIME_MASK 0x700UL /* Bit mask for VCMP_WARMTIME */ +#define _VCMP_CTRL_WARMTIME_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_4CYCLES 0x00000000UL /* Mode 4CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_8CYCLES 0x00000001UL /* Mode 8CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_16CYCLES 0x00000002UL /* Mode 16CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_32CYCLES 0x00000003UL /* Mode 32CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_64CYCLES 0x00000004UL /* Mode 64CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_128CYCLES 0x00000005UL /* Mode 128CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_256CYCLES 0x00000006UL /* Mode 256CYCLES for VCMP_CTRL */ +#define _VCMP_CTRL_WARMTIME_512CYCLES 0x00000007UL /* Mode 512CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_DEFAULT (_VCMP_CTRL_WARMTIME_DEFAULT << 8) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_4CYCLES (_VCMP_CTRL_WARMTIME_4CYCLES << 8) /* Shifted mode 4CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_8CYCLES (_VCMP_CTRL_WARMTIME_8CYCLES << 8) /* Shifted mode 8CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_16CYCLES (_VCMP_CTRL_WARMTIME_16CYCLES << 8) /* Shifted mode 16CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_32CYCLES (_VCMP_CTRL_WARMTIME_32CYCLES << 8) /* Shifted mode 32CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_64CYCLES (_VCMP_CTRL_WARMTIME_64CYCLES << 8) /* Shifted mode 64CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_128CYCLES (_VCMP_CTRL_WARMTIME_128CYCLES << 8) /* Shifted mode 128CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_256CYCLES (_VCMP_CTRL_WARMTIME_256CYCLES << 8) /* Shifted mode 256CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_WARMTIME_512CYCLES (_VCMP_CTRL_WARMTIME_512CYCLES << 8) /* Shifted mode 512CYCLES for VCMP_CTRL */ +#define VCMP_CTRL_IRISE (0x1UL << 16) /* Rising Edge Interrupt Sense */ +#define _VCMP_CTRL_IRISE_SHIFT 16 /* Shift value for VCMP_IRISE */ +#define _VCMP_CTRL_IRISE_MASK 0x10000UL /* Bit mask for VCMP_IRISE */ +#define _VCMP_CTRL_IRISE_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_IRISE_DEFAULT (_VCMP_CTRL_IRISE_DEFAULT << 16) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_IFALL (0x1UL << 17) /* Falling Edge Interrupt Sense */ +#define _VCMP_CTRL_IFALL_SHIFT 17 /* Shift value for VCMP_IFALL */ +#define _VCMP_CTRL_IFALL_MASK 0x20000UL /* Bit mask for VCMP_IFALL */ +#define _VCMP_CTRL_IFALL_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_IFALL_DEFAULT (_VCMP_CTRL_IFALL_DEFAULT << 17) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define _VCMP_CTRL_BIASPROG_SHIFT 24 /* Shift value for VCMP_BIASPROG */ +#define _VCMP_CTRL_BIASPROG_MASK 0xF000000UL /* Bit mask for VCMP_BIASPROG */ +#define _VCMP_CTRL_BIASPROG_DEFAULT 0x00000007UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_BIASPROG_DEFAULT (_VCMP_CTRL_BIASPROG_DEFAULT << 24) /* Shifted mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_HALFBIAS (0x1UL << 30) /* Half Bias Current */ +#define _VCMP_CTRL_HALFBIAS_SHIFT 30 /* Shift value for VCMP_HALFBIAS */ +#define _VCMP_CTRL_HALFBIAS_MASK 0x40000000UL /* Bit mask for VCMP_HALFBIAS */ +#define _VCMP_CTRL_HALFBIAS_DEFAULT 0x00000001UL /* Mode DEFAULT for VCMP_CTRL */ +#define VCMP_CTRL_HALFBIAS_DEFAULT (_VCMP_CTRL_HALFBIAS_DEFAULT << 30) /* Shifted mode DEFAULT for VCMP_CTRL */ + +/* Bit fields for VCMP INPUTSEL */ + +#define _VCMP_INPUTSEL_RESETVALUE 0x00000000UL /* Default value for VCMP_INPUTSEL */ +#define _VCMP_INPUTSEL_MASK 0x0000013FUL /* Mask for VCMP_INPUTSEL */ + +#define _VCMP_INPUTSEL_TRIGLEVEL_SHIFT 0 /* Shift value for VCMP_TRIGLEVEL */ +#define _VCMP_INPUTSEL_TRIGLEVEL_MASK 0x3FUL /* Bit mask for VCMP_TRIGLEVEL */ +#define _VCMP_INPUTSEL_TRIGLEVEL_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_INPUTSEL */ +#define VCMP_INPUTSEL_TRIGLEVEL_DEFAULT (_VCMP_INPUTSEL_TRIGLEVEL_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_INPUTSEL */ +#define VCMP_INPUTSEL_LPREF (0x1UL << 8) /* Low Power Reference */ +#define _VCMP_INPUTSEL_LPREF_SHIFT 8 /* Shift value for VCMP_LPREF */ +#define _VCMP_INPUTSEL_LPREF_MASK 0x100UL /* Bit mask for VCMP_LPREF */ +#define _VCMP_INPUTSEL_LPREF_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_INPUTSEL */ +#define VCMP_INPUTSEL_LPREF_DEFAULT (_VCMP_INPUTSEL_LPREF_DEFAULT << 8) /* Shifted mode DEFAULT for VCMP_INPUTSEL */ + +/* Bit fields for VCMP STATUS */ + +#define _VCMP_STATUS_RESETVALUE 0x00000000UL /* Default value for VCMP_STATUS */ +#define _VCMP_STATUS_MASK 0x00000003UL /* Mask for VCMP_STATUS */ + +#define VCMP_STATUS_VCMPACT (0x1UL << 0) /* Voltage Supply Comparator Active */ +#define _VCMP_STATUS_VCMPACT_SHIFT 0 /* Shift value for VCMP_VCMPACT */ +#define _VCMP_STATUS_VCMPACT_MASK 0x1UL /* Bit mask for VCMP_VCMPACT */ +#define _VCMP_STATUS_VCMPACT_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_STATUS */ +#define VCMP_STATUS_VCMPACT_DEFAULT (_VCMP_STATUS_VCMPACT_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_STATUS */ +#define VCMP_STATUS_VCMPOUT (0x1UL << 1) /* Voltage Supply Comparator Output */ +#define _VCMP_STATUS_VCMPOUT_SHIFT 1 /* Shift value for VCMP_VCMPOUT */ +#define _VCMP_STATUS_VCMPOUT_MASK 0x2UL /* Bit mask for VCMP_VCMPOUT */ +#define _VCMP_STATUS_VCMPOUT_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_STATUS */ +#define VCMP_STATUS_VCMPOUT_DEFAULT (_VCMP_STATUS_VCMPOUT_DEFAULT << 1) /* Shifted mode DEFAULT for VCMP_STATUS */ + +/* Bit fields for VCMP IEN */ + +#define _VCMP_IEN_RESETVALUE 0x00000000UL /* Default value for VCMP_IEN */ +#define _VCMP_IEN_MASK 0x00000003UL /* Mask for VCMP_IEN */ + +#define VCMP_IEN_EDGE (0x1UL << 0) /* Edge Trigger Interrupt Enable */ +#define _VCMP_IEN_EDGE_SHIFT 0 /* Shift value for VCMP_EDGE */ +#define _VCMP_IEN_EDGE_MASK 0x1UL /* Bit mask for VCMP_EDGE */ +#define _VCMP_IEN_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IEN */ +#define VCMP_IEN_EDGE_DEFAULT (_VCMP_IEN_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_IEN */ +#define VCMP_IEN_WARMUP (0x1UL << 1) /* Warm-up Interrupt Enable */ +#define _VCMP_IEN_WARMUP_SHIFT 1 /* Shift value for VCMP_WARMUP */ +#define _VCMP_IEN_WARMUP_MASK 0x2UL /* Bit mask for VCMP_WARMUP */ +#define _VCMP_IEN_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IEN */ +#define VCMP_IEN_WARMUP_DEFAULT (_VCMP_IEN_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for VCMP_IEN */ + +/* Bit fields for VCMP IF */ + +#define _VCMP_IF_RESETVALUE 0x00000000UL /* Default value for VCMP_IF */ +#define _VCMP_IF_MASK 0x00000003UL /* Mask for VCMP_IF */ + +#define VCMP_IF_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag */ +#define _VCMP_IF_EDGE_SHIFT 0 /* Shift value for VCMP_EDGE */ +#define _VCMP_IF_EDGE_MASK 0x1UL /* Bit mask for VCMP_EDGE */ +#define _VCMP_IF_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IF */ +#define VCMP_IF_EDGE_DEFAULT (_VCMP_IF_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_IF */ +#define VCMP_IF_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag */ +#define _VCMP_IF_WARMUP_SHIFT 1 /* Shift value for VCMP_WARMUP */ +#define _VCMP_IF_WARMUP_MASK 0x2UL /* Bit mask for VCMP_WARMUP */ +#define _VCMP_IF_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IF */ +#define VCMP_IF_WARMUP_DEFAULT (_VCMP_IF_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for VCMP_IF */ + +/* Bit fields for VCMP IFS */ + +#define _VCMP_IFS_RESETVALUE 0x00000000UL /* Default value for VCMP_IFS */ +#define _VCMP_IFS_MASK 0x00000003UL /* Mask for VCMP_IFS */ + +#define VCMP_IFS_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag Set */ +#define _VCMP_IFS_EDGE_SHIFT 0 /* Shift value for VCMP_EDGE */ +#define _VCMP_IFS_EDGE_MASK 0x1UL /* Bit mask for VCMP_EDGE */ +#define _VCMP_IFS_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IFS */ +#define VCMP_IFS_EDGE_DEFAULT (_VCMP_IFS_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_IFS */ +#define VCMP_IFS_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag Set */ +#define _VCMP_IFS_WARMUP_SHIFT 1 /* Shift value for VCMP_WARMUP */ +#define _VCMP_IFS_WARMUP_MASK 0x2UL /* Bit mask for VCMP_WARMUP */ +#define _VCMP_IFS_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IFS */ +#define VCMP_IFS_WARMUP_DEFAULT (_VCMP_IFS_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for VCMP_IFS */ + +/* Bit fields for VCMP IFC */ + +#define _VCMP_IFC_RESETVALUE 0x00000000UL /* Default value for VCMP_IFC */ +#define _VCMP_IFC_MASK 0x00000003UL /* Mask for VCMP_IFC */ + +#define VCMP_IFC_EDGE (0x1UL << 0) /* Edge Triggered Interrupt Flag Clear */ +#define _VCMP_IFC_EDGE_SHIFT 0 /* Shift value for VCMP_EDGE */ +#define _VCMP_IFC_EDGE_MASK 0x1UL /* Bit mask for VCMP_EDGE */ +#define _VCMP_IFC_EDGE_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IFC */ +#define VCMP_IFC_EDGE_DEFAULT (_VCMP_IFC_EDGE_DEFAULT << 0) /* Shifted mode DEFAULT for VCMP_IFC */ +#define VCMP_IFC_WARMUP (0x1UL << 1) /* Warm-up Interrupt Flag Clear */ +#define _VCMP_IFC_WARMUP_SHIFT 1 /* Shift value for VCMP_WARMUP */ +#define _VCMP_IFC_WARMUP_MASK 0x2UL /* Bit mask for VCMP_WARMUP */ +#define _VCMP_IFC_WARMUP_DEFAULT 0x00000000UL /* Mode DEFAULT for VCMP_IFC */ +#define VCMP_IFC_WARMUP_DEFAULT (_VCMP_IFC_WARMUP_DEFAULT << 1) /* Shifted mode DEFAULT for VCMP_IFC */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_VCMP_H */ diff --git a/arch/arm/src/efm32/chip/efm32_wdog.h b/arch/arm/src/efm32/chip/efm32_wdog.h new file mode 100644 index 0000000000000000000000000000000000000000..4568dee1593913e6d5af35d158ba37d4febad99d --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32_wdog.h @@ -0,0 +1,178 @@ +/******************************************************************************************************************************* + * arch/arm/src/efm32/chip/efm32_wdog.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Pierre-noel Bouteville + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32_WDOG_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32_WDOG_H + +/******************************************************************************************************************************* + * Included Files + *******************************************************************************************************************************/ + +#include +#include "chip/efm32_memorymap.h" + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning This is the EFM32GG header file; Review/modification needed for this archtecture +#endif + +/******************************************************************************************************************************* + * Pre-processor Definitions + *******************************************************************************************************************************/ +/* WDOG Register Offsets *******************************************************************************************************/ + +#define EFM32_WDOG_CTRL_OFFSET 0x0000 /* Control Register */ +#define EFM32_WDOG_CMD_OFFSET 0x0004 /* Command Register */ +#define EFM32_WDOG_SYNCBUSY_OFFSET 0x0008 /* Synchronization Busy Register */ + +/* WDOG Register Addresses *****************************************************************************************************/ + +#define EFM32_WDOG_CTRL (EFM32_WDOG_BASE+EFM32_WDOG_CTRL_OFFSET) +#define EFM32_WDOG_CMD (EFM32_WDOG_BASE+EFM32_WDOG_CMD_OFFSET) +#define EFM32_WDOG_SYNCBUSY (EFM32_WDOG_BASE+EFM32_WDOG_SYNCBUSY_OFFSET) + +/* WDOG Register Bit Field Definitions *****************************************************************************************/ + +/* Bit fields for WDOG CTRL */ + +#define _WDOG_CTRL_RESETVALUE 0x00000F00UL /* Default value for WDOG_CTRL */ +#define _WDOG_CTRL_MASK 0x00003F7FUL /* Mask for WDOG_CTRL */ + +#define WDOG_CTRL_EN (0x1UL << 0) /* Watchdog Timer Enable */ +#define _WDOG_CTRL_EN_SHIFT 0 /* Shift value for WDOG_EN */ +#define _WDOG_CTRL_EN_MASK 0x1UL /* Bit mask for WDOG_EN */ +#define _WDOG_CTRL_EN_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EN_DEFAULT (_WDOG_CTRL_EN_DEFAULT << 0) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_DEBUGRUN (0x1UL << 1) /* Debug Mode Run Enable */ +#define _WDOG_CTRL_DEBUGRUN_SHIFT 1 /* Shift value for WDOG_DEBUGRUN */ +#define _WDOG_CTRL_DEBUGRUN_MASK 0x2UL /* Bit mask for WDOG_DEBUGRUN */ +#define _WDOG_CTRL_DEBUGRUN_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_DEBUGRUN_DEFAULT (_WDOG_CTRL_DEBUGRUN_DEFAULT << 1) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM2RUN (0x1UL << 2) /* Energy Mode 2 Run Enable */ +#define _WDOG_CTRL_EM2RUN_SHIFT 2 /* Shift value for WDOG_EM2RUN */ +#define _WDOG_CTRL_EM2RUN_MASK 0x4UL /* Bit mask for WDOG_EM2RUN */ +#define _WDOG_CTRL_EM2RUN_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM2RUN_DEFAULT (_WDOG_CTRL_EM2RUN_DEFAULT << 2) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM3RUN (0x1UL << 3) /* Energy Mode 3 Run Enable */ +#define _WDOG_CTRL_EM3RUN_SHIFT 3 /* Shift value for WDOG_EM3RUN */ +#define _WDOG_CTRL_EM3RUN_MASK 0x8UL /* Bit mask for WDOG_EM3RUN */ +#define _WDOG_CTRL_EM3RUN_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM3RUN_DEFAULT (_WDOG_CTRL_EM3RUN_DEFAULT << 3) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_LOCK (0x1UL << 4) /* Configuration lock */ +#define _WDOG_CTRL_LOCK_SHIFT 4 /* Shift value for WDOG_LOCK */ +#define _WDOG_CTRL_LOCK_MASK 0x10UL /* Bit mask for WDOG_LOCK */ +#define _WDOG_CTRL_LOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_LOCK_DEFAULT (_WDOG_CTRL_LOCK_DEFAULT << 4) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM4BLOCK (0x1UL << 5) /* Energy Mode 4 Block */ +#define _WDOG_CTRL_EM4BLOCK_SHIFT 5 /* Shift value for WDOG_EM4BLOCK */ +#define _WDOG_CTRL_EM4BLOCK_MASK 0x20UL /* Bit mask for WDOG_EM4BLOCK */ +#define _WDOG_CTRL_EM4BLOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_EM4BLOCK_DEFAULT (_WDOG_CTRL_EM4BLOCK_DEFAULT << 5) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_SWOSCBLOCK (0x1UL << 6) /* Software Oscillator Disable Block */ +#define _WDOG_CTRL_SWOSCBLOCK_SHIFT 6 /* Shift value for WDOG_SWOSCBLOCK */ +#define _WDOG_CTRL_SWOSCBLOCK_MASK 0x40UL /* Bit mask for WDOG_SWOSCBLOCK */ +#define _WDOG_CTRL_SWOSCBLOCK_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_SWOSCBLOCK_DEFAULT (_WDOG_CTRL_SWOSCBLOCK_DEFAULT << 6) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define _WDOG_CTRL_PERSEL_SHIFT 8 /* Shift value for WDOG_PERSEL */ +#define _WDOG_CTRL_PERSEL_MASK 0xF00UL /* Bit mask for WDOG_PERSEL */ +#define _WDOG_CTRL_PERSEL_DEFAULT 0x0000000FUL /* Mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_PERSEL_DEFAULT (_WDOG_CTRL_PERSEL_DEFAULT << 8) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define _WDOG_CTRL_CLKSEL_SHIFT 12 /* Shift value for WDOG_CLKSEL */ +#define _WDOG_CTRL_CLKSEL_MASK 0x3000UL /* Bit mask for WDOG_CLKSEL */ +#define _WDOG_CTRL_CLKSEL_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CTRL */ +#define _WDOG_CTRL_CLKSEL_ULFRCO 0x00000000UL /* Mode ULFRCO for WDOG_CTRL */ +#define _WDOG_CTRL_CLKSEL_LFRCO 0x00000001UL /* Mode LFRCO for WDOG_CTRL */ +#define _WDOG_CTRL_CLKSEL_LFXO 0x00000002UL /* Mode LFXO for WDOG_CTRL */ +#define WDOG_CTRL_CLKSEL_DEFAULT (_WDOG_CTRL_CLKSEL_DEFAULT << 12) /* Shifted mode DEFAULT for WDOG_CTRL */ +#define WDOG_CTRL_CLKSEL_ULFRCO (_WDOG_CTRL_CLKSEL_ULFRCO << 12) /* Shifted mode ULFRCO for WDOG_CTRL */ +#define WDOG_CTRL_CLKSEL_LFRCO (_WDOG_CTRL_CLKSEL_LFRCO << 12) /* Shifted mode LFRCO for WDOG_CTRL */ +#define WDOG_CTRL_CLKSEL_LFXO (_WDOG_CTRL_CLKSEL_LFXO << 12) /* Shifted mode LFXO for WDOG_CTRL */ + +/* Bit fields for WDOG CMD */ + +#define _WDOG_CMD_RESETVALUE 0x00000000UL /* Default value for WDOG_CMD */ +#define _WDOG_CMD_MASK 0x00000001UL /* Mask for WDOG_CMD */ + +#define WDOG_CMD_CLEAR (0x1UL << 0) /* Watchdog Timer Clear */ +#define _WDOG_CMD_CLEAR_SHIFT 0 /* Shift value for WDOG_CLEAR */ +#define _WDOG_CMD_CLEAR_MASK 0x1UL /* Bit mask for WDOG_CLEAR */ +#define _WDOG_CMD_CLEAR_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_CMD */ +#define _WDOG_CMD_CLEAR_UNCHANGED 0x00000000UL /* Mode UNCHANGED for WDOG_CMD */ +#define _WDOG_CMD_CLEAR_CLEARED 0x00000001UL /* Mode CLEARED for WDOG_CMD */ +#define WDOG_CMD_CLEAR_DEFAULT (_WDOG_CMD_CLEAR_DEFAULT << 0) /* Shifted mode DEFAULT for WDOG_CMD */ +#define WDOG_CMD_CLEAR_UNCHANGED (_WDOG_CMD_CLEAR_UNCHANGED << 0) /* Shifted mode UNCHANGED for WDOG_CMD */ +#define WDOG_CMD_CLEAR_CLEARED (_WDOG_CMD_CLEAR_CLEARED << 0) /* Shifted mode CLEARED for WDOG_CMD */ + +/* Bit fields for WDOG SYNCBUSY */ + +#define _WDOG_SYNCBUSY_RESETVALUE 0x00000000UL /* Default value for WDOG_SYNCBUSY */ +#define _WDOG_SYNCBUSY_MASK 0x00000003UL /* Mask for WDOG_SYNCBUSY */ + +#define WDOG_SYNCBUSY_CTRL (0x1UL << 0) /* CTRL Register Busy */ +#define _WDOG_SYNCBUSY_CTRL_SHIFT 0 /* Shift value for WDOG_CTRL */ +#define _WDOG_SYNCBUSY_CTRL_MASK 0x1UL /* Bit mask for WDOG_CTRL */ +#define _WDOG_SYNCBUSY_CTRL_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_SYNCBUSY */ +#define WDOG_SYNCBUSY_CTRL_DEFAULT (_WDOG_SYNCBUSY_CTRL_DEFAULT << 0) /* Shifted mode DEFAULT for WDOG_SYNCBUSY */ +#define WDOG_SYNCBUSY_CMD (0x1UL << 1) /* CMD Register Busy */ +#define _WDOG_SYNCBUSY_CMD_SHIFT 1 /* Shift value for WDOG_CMD */ +#define _WDOG_SYNCBUSY_CMD_MASK 0x2UL /* Bit mask for WDOG_CMD */ +#define _WDOG_SYNCBUSY_CMD_DEFAULT 0x00000000UL /* Mode DEFAULT for WDOG_SYNCBUSY */ +#define WDOG_SYNCBUSY_CMD_DEFAULT (_WDOG_SYNCBUSY_CMD_DEFAULT << 1) /* Shifted mode DEFAULT for WDOG_SYNCBUSY */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32_WDOG_H */ diff --git a/arch/arm/src/efm32/chip/efm32g_memorymap.h b/arch/arm/src/efm32/chip/efm32g_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..18fc11d243e8c0cf6f3890a516a93bf54a868346 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32g_memorymap.h @@ -0,0 +1,101 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip/efm32g_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: "EFM32G Reference Manual, Gecko Series", Energy Micro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32G_MEMORYMAP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32G_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Base Addresses */ + +#define EFM32_FLASH_MEM_BASE 0x00000000 /* FLASH base address */ +#define EFM32_RAM_CODE_MEM_BASE 0x10000000 /* RAM_CODE base address */ +#define EFM32_RAM_MEM_BASE 0x20000000 /* RAM base address */ +#define EFM32_PER_MEM_BASE 0x40000000 /* PER base address */ +#define EFM32_AES_MEM_BASE 0x400e0000 /* AES base address */ +#define EFM32_EBI0_BASE 0x80000000 /* EBI Region 0 */ +#define EFM32_EBI1_BASE 0x84000000 /* EBI Region 0 */ +#define EFM32_EBI2_BASE 0x88000000 /* EBI Region 0 */ +#define EFM32_EBI3_BASE 0x8c000000 /* EBI Region 0 */ +#define EFM32_CM3_BASE 0xe0000000 /* CM3 Peripherals */ + +/* Bit banding area */ + +#define EFM32_BITBAND_PER_BASE 0x42000000 /* Peripheral Address Space bit-band area */ +#define EFM32_BITBAND_RAM_BASE 0x22000000 /* SRAM Address Space bit-band area */ + +/* Flash and SRAM Addresses */ + +#define EFM32_FLASH_BASE 0x00000000 /* Flash Base Address */ +#define EFM32_SRAM_BASE 0x20000000 /* SRAM Base Address */ + +/* Peripheral Base Addresses */ + +#define EFM32_VCMP_BASE 0x40000000 /* VCMP base address */ +#define EFM32_ACMP0_BASE 0x40001000 /* ACMP0 base address */ +#define EFM32_ACMP1_BASE 0x40001400 /* ACMP1 base address */ +#define EFM32_ADC0_BASE 0x40002000 /* ADC0 base address */ +#define EFM32_DAC0_BASE 0x40004000 /* DAC0 base address */ +#define EFM32_GPIO_BASE 0x40006000 /* GPIO base address */ +#define EFM32_I2C0_BASE 0x4000a000 /* I2C0 base address */ +#define EFM32_USART0_BASE 0x4000c000 /* USART0 base address */ +#define EFM32_USART1_BASE 0x4000c400 /* USART1 base address */ +#define EFM32_USART2_BASE 0x4000c800 /* USART2 base address */ +#define EFM32_UART0_BASE 0x4000e000 /* UART0 base address */ +#define EFM32_TIMER0_BASE 0x40010000 /* TIMER0 base address */ +#define EFM32_TIMER1_BASE 0x40010400 /* TIMER1 base address */ +#define EFM32_TIMER2_BASE 0x40010800 /* TIMER2 base address */ +#define EFM32_RTC_BASE 0x40080000 /* RTC base address */ +#define EFM32_LETIMER0_BASE 0x40082000 /* LETIMER0 base address */ +#define EFM32_LEUART0_BASE 0x40084000 /* LEUART0 base address */ +#define EFM32_LEUART1_BASE 0x40084400 /* LEUART0 base address */ +#define EFM32_PCNT0_BASE 0x40086000 /* PCNT0 base address */ +#define EFM32_PCNT1_BASE 0x40086400 /* PCNT1 base address */ +#define EFM32_PCNT2_BASE 0x40086800 /* PCNT2 base address */ +#define EFM32_WDOG_BASE 0x40088000 /* WDOG base address */ +#define EFM32_LCD_BASE 0x4008a000 /* LCD base address */ +#define EFM32_MSC_BASE 0x400c0000 /* MSC base address */ +#define EFM32_DMA_BASE 0x400c2000 /* DMA base address */ +#define EFM32_EMU_BASE 0x400c6000 /* EMU base address */ +#define EFM32_CMU_BASE 0x400c8000 /* CMU base address */ +#define EFM32_RMU_BASE 0x400ca000 /* RMU base address */ +#define EFM32_PRS_BASE 0x400cc000 /* PRS base address */ +#define EFM32_AES_BASE 0x400e0000 /* AES base address */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32G_MEMORYMAP_H */ diff --git a/arch/arm/src/efm32/chip/efm32g_vectors.h b/arch/arm/src/efm32/chip/efm32g_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..01132533e778898dbde06a1080f243d54bff6019 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32g_vectors.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/src/efm32/chip/efm32ggxxx_vectors.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This file is included by efm32_vectors.S. It provides the macro VECTOR + * that supplies each EFM32G vector in terms of a (lower-case) ISR label and + * an (upper-case) IRQ number as defined in arch/arm/include/efm32/efm32g_irq.h. + * efm32_vectors.S will defined the VECTOR in different ways in order to + * generate the interrupt vectors and handlers in their final form. + * + * Vectors for low and medium density devices + */ + +#if defined(CONFIG_EFM32_EFM32G) + +/* If the common ARMv7-M vector handling is used, then all it needs is the + * following definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 30 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 30 + +#else + /* IRQ# Source */ + VECTOR(EFM32_IRQ_DMA, EFM32_IRQ_DMA ) /* 0 DMA */ + VECTOR(EFM32_IRQ_GPIO_EVEN, EFM32_IRQ_GPIO_EVEN ) /* 1 GPIO_EVEN */ + VECTOR(EFM32_IRQ_TIMER0, EFM32_IRQ_TIMER0 ) /* 2 TIMER0 */ + VECTOR(EFM32_IRQ_USART0_RX, EFM32_IRQ_USART0_RX ) /* 3 USART0_RX */ + VECTOR(EFM32_IRQ_USART0_TX, EFM32_IRQ_USART0_TX ) /* 4 USART0_TX */ + VECTOR(EFM32_IRQ_ACMP, EFM32_IRQ_ACMP ) /* 5 ACMP0/ACMP1 */ + VECTOR(EFM32_IRQ_ADC0, EFM32_IRQ_ADC0 ) /* 6 ADC0 */ + VECTOR(EFM32_IRQ_DAC0, EFM32_IRQ_DAC0 ) /* 7 DAC0 */ + VECTOR(EFM32_IRQ_I2C0, EFM32_IRQ_I2C0 ) /* 8 I2C0 */ + VECTOR(EFM32_IRQ_GPIO_ODD, EFM32_IRQ_GPIO_ODD ) /* 9 GPIO_ODD */ + VECTOR(EFM32_IRQ_TIMER1, EFM32_IRQ_TIMER1 ) /* 10 TIMER1 */ + VECTOR(EFM32_IRQ_TIMER2, EFM32_IRQ_TIMER2 ) /* 11 TIMER2 */ + VECTOR(EFM32_IRQ_USART1_RX, EFM32_IRQ_USART1_RX ) /* 12 USART1_RX */ + VECTOR(EFM32_IRQ_USART1_TX, EFM32_IRQ_USART1_TX ) /* 13 USART1_TX */ + VECTOR(EFM32_IRQ_USART2_RX, EFM32_IRQ_USART2_RX ) /* 14 USART2_RX */ + VECTOR(EFM32_IRQ_USART2_TX, EFM32_IRQ_USART2_TX ) /* 15 USART2_TX */ + VECTOR(EFM32_IRQ_UART0_RX, EFM32_IRQ_UART0_RX ) /* 16 UART0_RX */ + VECTOR(EFM32_IRQ_UART0_TX, EFM32_IRQ_UART0_TX ) /* 17 UART0_TX */ + VECTOR(EFM32_IRQ_LEUART0, EFM32_IRQ_LEUART0 ) /* 18 LEUART0 */ + VECTOR(EFM32_IRQ_LEUART1, EFM32_IRQ_LEUART1 ) /* 19 LEUART1 */ + VECTOR(EFM32_IRQ_LETIMER0, EFM32_IRQ_LETIMER0 ) /* 20 LETIMER0 */ + VECTOR(EFM32_IRQ_PCNT0, EFM32_IRQ_PCNT0 ) /* 21 PCNT0 */ + VECTOR(EFM32_IRQ_PCNT1, EFM32_IRQ_PCNT1 ) /* 22 PCNT1 */ + VECTOR(EFM32_IRQ_PCNT2, EFM32_IRQ_PCNT2 ) /* 23 PCNT2 */ + VECTOR(EFM32_IRQ_RTC, EFM32_IRQ_RTC ) /* 24 RTC */ + VECTOR(EFM32_IRQ_CMU, EFM32_IRQ_CMU ) /* 25 CMU */ + VECTOR(EFM32_IRQ_VCMP, EFM32_IRQ_VCMP ) /* 26 VCMP */ + VECTOR(EFM32_IRQ_LCD, EFM32_IRQ_LCD ) /* 27 LCD */ + VECTOR(EFM32_IRQ_MSC, EFM32_IRQ_MSC ) /* 28 MSC */ + VECTOR(EFM32_IRQ_AES, EFM32_IRQ_AES ) /* 29 AES */ + +#endif + +#else +# error "Unknown EFM32 Type" +#endif diff --git a/arch/arm/src/efm32/chip/efm32gg_memorymap.h b/arch/arm/src/efm32/chip/efm32gg_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..cdc89e2e95252ca7a175fc6b8246e75981d7aac8 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32gg_memorymap.h @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip/efm32gg_memorymap.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM32GG_MEMORYMAP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM32GG_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Base Addresses */ + +#define EFM32_FLASH_MEM_BASE 0x00000000 /* FLASH base address */ +# define EFM32_FLASH_MEM_BITS 0x00000028 /* FLASH used bits */ +#define EFM32_RAM_CODE_MEM_BASE 0x10000000 /* RAM_CODE base address */ +# define EFM32_RAM_CODE_MEM_BITS 0x00000014 /* RAM_CODE used bits */ +#define EFM32_RAM_MEM_BASE 0x20000000 /* RAM base address */ +# define EFM32_RAM_MEM_BITS 0x00000018 /* RAM used bits */ +#define EFM32_PER_MEM_BASE 0x40000000 /* PER base address */ +# define EFM32_PER_MEM_BITS 0x00000020 /* PER used bits */ +#define EFM32_AES_MEM_BASE 0x400e0000 /* AES base address */ +# define EFM32_AES_MEM_BITS 0x00000010 /* AES used bits */ + +/* Bit banding area */ + +#define EFM32_BITBAND_PER_BASE 0x42000000 /* Peripheral Address Space bit-band area */ +#define EFM32_BITBAND_RAM_BASE 0x22000000 /* SRAM Address Space bit-band area */ + +/* Flash and SRAM Addresses */ + +#define EFM32_FLASH_BASE 0x00000000 /* Flash Base Address */ +#define EFM32_SRAM_BASE 0x20000000 /* SRAM Base Address */ + +/* Peripheral Base Addresses */ + +#define EFM32_VCMP_BASE 0x40000000 /* VCMP base address */ +#define EFM32_ACMP0_BASE 0x40001000 /* ACMP0 base address */ +#define EFM32_ACMP1_BASE 0x40001400 /* ACMP1 base address */ +#define EFM32_ADC0_BASE 0x40002000 /* ADC0 base address */ +#define EFM32_DAC0_BASE 0x40004000 /* DAC0 base address */ +#define EFM32_GPIO_BASE 0x40006000 /* GPIO base address */ +#define EFM32_EBI_BASE 0x40008000 /* EBI base address */ +#define EFM32_I2C0_BASE 0x4000a000 /* I2C0 base address */ +#define EFM32_I2C1_BASE 0x4000a400 /* I2C0 base address */ +#define EFM32_USART0_BASE 0x4000c000 /* USART0 base address */ +#define EFM32_USART1_BASE 0x4000c400 /* USART1 base address */ +#define EFM32_USART2_BASE 0x4000c800 /* USART2 base address */ +#define EFM32_UART0_BASE 0x4000e000 /* UART0 base address */ +#define EFM32_UART1_BASE 0x4000e400 /* UART1 base address */ +#define EFM32_TIMER0_BASE 0x40010000 /* TIMER0 base address */ +#define EFM32_TIMER1_BASE 0x40010400 /* TIMER1 base address */ +#define EFM32_TIMER2_BASE 0x40010800 /* TIMER2 base address */ +#define EFM32_TIMER3_BASE 0x40010c00 /* TIMER3 base address */ +#define EFM32_RTC_BASE 0x40080000 /* RTC base address */ +#define EFM32_BCKRTC_BASE 0x40081000 /* BCKRTC base address */ +#define EFM32_LETIMER0_BASE 0x40082000 /* LETIMER0 base address */ +#define EFM32_LEUART0_BASE 0x40084000 /* LEUART0 base address */ +#define EFM32_LEUART1_BASE 0x40084400 /* LEUART1 base address */ +#define EFM32_PCNT0_BASE 0x40086000 /* PCNT0 base address */ +#define EFM32_PCNT1_BASE 0x40086400 /* PCNT1 base address */ +#define EFM32_PCNT2_BASE 0x40086800 /* PCNT2 base address */ +#define EFM32_WDOG_BASE 0x40088000 /* WDOG base address */ +#define EFM32_LCD_BASE 0x4008a000 /* LCD base address */ +#define EFM32_LESENSE_BASE 0x4008c000 /* LESENSE base address */ +#define EFM32_MSC_BASE 0x400c0000 /* MSC base address */ +#define EFM32_DMA_BASE 0x400c2000 /* DMA base address */ +#define EFM32_USB_BASE 0x400c4000 /* USB base address */ +#define EFM32_EMU_BASE 0x400c6000 /* EMU base address */ +#define EFM32_CMU_BASE 0x400c8000 /* CMU base address */ +#define EFM32_RMU_BASE 0x400ca000 /* RMU base address */ +#define EFM32_PRS_BASE 0x400cc000 /* PRS base address */ +#define EFM32_AES_BASE 0x400e0000 /* AES base address */ + +/* ROM specific region */ + +#define EFM32_ROMTABLE_BASE 0xe00fffd0 /* ROMTABLE base address */ + +/* Flash specific region */ + +#define EFM32_USERDATA_BASE 0x0fe00000 /* User data page base address */ +#define EFM32_LOCKBITS_BASE 0x0fe04000 /* Lock-bits page base address */ +#define EFM32_CALIBRATE_BASE 0x0fe08000 /* CALIBRATE base address */ +#define EFM32_DEVINFO_BASE 0x0fe081b0 /* DEVINFO base address */ + +#define EFM32_USERDATA_SIZE 0x00000800 /* User data page size */ +#define EFM32_USERDATA_NPAGES 1 /* User data page number */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM32GG_MEMORYMAP_H */ diff --git a/arch/arm/src/efm32/chip/efm32gg_vectors.h b/arch/arm/src/efm32/chip/efm32gg_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..834c988b1ceeb6db65b7b56a91e18be39d4014eb --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32gg_vectors.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm/src/efm32/chip/efm32ggxxx_vectors.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This file is included by efm32_vectors.S. It provides the macro VECTOR + * that supplies each EFM32GG vector in terms of a (lower-case) ISR label and + * an (upper-case) IRQ number as defined in arch/arm/include/efm32/efm32gg_irq.h. + * efm32_vectors.S will defined the VECTOR in different ways in order to + * generate the interrupt vectors and handlers in their final form. + * + * Vectors for low and medium density devices + */ + +#if defined(CONFIG_EFM32_EFM32GG) + +/* If the common ARMv7-M vector handling is used, then all it needs is the + * following definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 39 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 39 + +#else + VECTOR(EFM32_IRQ_DMA, EFM32_IRQ_DMA ) /* 0: EFM32_IRQ_DMA */ + VECTOR(EFM32_IRQ_GPIO_EVEN, EFM32_IRQ_GPIO_EVEN ) /* 1: EFM32_IRQ_GPIO_EVEN */ + VECTOR(EFM32_IRQ_TIMER0, EFM32_IRQ_TIMER0 ) /* 2: EFM32_IRQ_TIMER0 */ + VECTOR(EFM32_IRQ_USART0_RX, EFM32_IRQ_USART0_RX ) /* 3: EFM32_IRQ_USART0_RX */ + VECTOR(EFM32_IRQ_USART0_TX, EFM32_IRQ_USART0_TX ) /* 4: EFM32_IRQ_USART0_TX */ + VECTOR(EFM32_IRQ_USB, EFM32_IRQ_USB ) /* 5: EFM32_IRQ_USB */ + VECTOR(EFM32_IRQ_ACMP, EFM32_IRQ_ACMP ) /* 6: EFM32_IRQ_ACMP */ + VECTOR(EFM32_IRQ_ADC0, EFM32_IRQ_ADC0 ) /* 7: EFM32_IRQ_ADC0 */ + VECTOR(EFM32_IRQ_DAC0, EFM32_IRQ_DAC0 ) /* 8: EFM32_IRQ_DAC0 */ + VECTOR(EFM32_IRQ_I2C0, EFM32_IRQ_I2C0 ) /* 9: EFM32_IRQ_I2C0 */ + VECTOR(EFM32_IRQ_I2C1, EFM32_IRQ_I2C1 ) /* 10: EFM32_IRQ_I2C1 */ + VECTOR(EFM32_IRQ_GPIO_ODD, EFM32_IRQ_GPIO_ODD ) /* 11: EFM32_IRQ_GPIO_ODD */ + VECTOR(EFM32_IRQ_TIMER1, EFM32_IRQ_TIMER1 ) /* 12: EFM32_IRQ_TIMER1 */ + VECTOR(EFM32_IRQ_TIMER2, EFM32_IRQ_TIMER2 ) /* 13: EFM32_IRQ_TIMER2 */ + VECTOR(EFM32_IRQ_TIMER3, EFM32_IRQ_TIMER3 ) /* 14: EFM32_IRQ_TIMER3 */ + VECTOR(EFM32_IRQ_USART1_RX, EFM32_IRQ_USART1_RX ) /* 15: EFM32_IRQ_USART1_RX */ + VECTOR(EFM32_IRQ_USART1_TX, EFM32_IRQ_USART1_TX ) /* 16: EFM32_IRQ_USART1_TX */ + VECTOR(EFM32_IRQ_LESENSE, EFM32_IRQ_LESENSE ) /* 17: EFM32_IRQ_LESENSE */ + VECTOR(EFM32_IRQ_USART2_RX, EFM32_IRQ_USART2_RX ) /* 18: EFM32_IRQ_USART2_RX */ + VECTOR(EFM32_IRQ_USART2_TX, EFM32_IRQ_USART2_TX ) /* 19: EFM32_IRQ_USART2_TX */ + VECTOR(EFM32_IRQ_UART0_RX, EFM32_IRQ_UART0_RX ) /* 20: EFM32_IRQ_UART0_RX */ + VECTOR(EFM32_IRQ_UART0_TX, EFM32_IRQ_UART0_TX ) /* 21: EFM32_IRQ_UART0_TX */ + VECTOR(EFM32_IRQ_UART1_RX, EFM32_IRQ_UART1_RX ) /* 22: EFM32_IRQ_UART1_RX */ + VECTOR(EFM32_IRQ_UART1_TX, EFM32_IRQ_UART1_TX ) /* 23: EFM32_IRQ_UART1_TX */ + VECTOR(EFM32_IRQ_LEUART0, EFM32_IRQ_LEUART0 ) /* 24: EFM32_IRQ_LEUART0 */ + VECTOR(EFM32_IRQ_LEUART1, EFM32_IRQ_LEUART1 ) /* 25: EFM32_IRQ_LEUART1 */ + VECTOR(EFM32_IRQ_LETIMER0, EFM32_IRQ_LETIMER0 ) /* 26: EFM32_IRQ_LETIMER0 */ + VECTOR(EFM32_IRQ_PCNT0, EFM32_IRQ_PCNT0 ) /* 27: EFM32_IRQ_PCNT0 */ + VECTOR(EFM32_IRQ_PCNT1, EFM32_IRQ_PCNT1 ) /* 28: EFM32_IRQ_PCNT1 */ + VECTOR(EFM32_IRQ_PCNT2, EFM32_IRQ_PCNT2 ) /* 29: EFM32_IRQ_PCNT2 */ + VECTOR(EFM32_IRQ_RTC, EFM32_IRQ_RTC ) /* 30: EFM32_IRQ_RTC */ + VECTOR(EFM32_IRQ_BURTC, EFM32_IRQ_BURTC ) /* 31: EFM32_IRQ_BURTC */ + VECTOR(EFM32_IRQ_CMU, EFM32_IRQ_CMU ) /* 32: EFM32_IRQ_CMU */ + VECTOR(EFM32_IRQ_VCMP, EFM32_IRQ_VCMP ) /* 33: EFM32_IRQ_VCMP */ + VECTOR(EFM32_IRQ_LCD, EFM32_IRQ_LCD ) /* 34: EFM32_IRQ_LCD */ + VECTOR(EFM32_IRQ_MSC, EFM32_IRQ_MSC ) /* 35: EFM32_IRQ_MSC */ + VECTOR(EFM32_IRQ_AES, EFM32_IRQ_AES ) /* 36: EFM32_IRQ_AES */ + VECTOR(EFM32_IRQ_EBI, EFM32_IRQ_EBI ) /* 37: EFM32_IRQ_EBI */ + VECTOR(EFM32_IRQ_EMI, EFM32_IRQ_EMI ) /* 38: EFM32_IRQ_EMI */ +#endif + +#else +# error "Unknown EFM32 Type" +#endif diff --git a/arch/arm/src/efm32/chip/efm32tg_memorymap.h b/arch/arm/src/efm32/chip/efm32tg_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..d4755d62dc37026cb2dd15e7147157da76d6957b --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32tg_memorymap.h @@ -0,0 +1,128 @@ +/************************************************************************************ + * arch/arm/src/efm32/chip/efm32tg_memorymap.h + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_CHIP_EFM3TG_MEMORYMAP_H +#define __ARCH_ARM_SRC_EFM32_CHIP_EFM3TG_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Base addresses */ + +#define EFM32_FLASH_MEM_BASE 0x00000000 /* FLASH base address */ +# define EFM32_FLASH_MEM_BITS 0x00000028 /* FLASH used bits */ +#define EFM32_RAM_CODE_MEM_BASE 0x10000000 /* RAM_CODE base address */ +# define EFM32_RAM_CODE_MEM_BITS 0x00000014 /* RAM_CODE used bits */ +#define EFM32_RAM_MEM_BASE 0x20000000 /* RAM base address */ +# define EFM32_RAM_MEM_BITS 0x00000018 /* RAM used bits */ +#define EFM32_PER_MEM_BASE 0x40000000 /* PER base address */ +# define EFM32_PER_MEM_BITS 0x00000020 /* PER used bits */ +#define EFM32_AES_MEM_BASE 0x400e0000 /* AES base address */ +# define EFM32_AES_MEM_BITS 0x00000010 /* AES used bits */ + +/* Bit banding area */ + +#define EFM32_BITBAND_PER_BASE 0x42000000 /* Peripheral Address Space bit-band area */ +#define EFM32_BITBAND_RAM_BASE 0x22000000 /* SRAM Address Space bit-band area */ + +/* Flash and SRAM Addresses */ + +#define EFM32_FLASH_BASE 0x00000000 /* Flash Base Address */ +#define EFM32_SRAM_BASE 0x20000000 /* SRAM Base Address */ + +/* Peripheral base address */ + +#define EFM32_VCMP_BASE 0x40000000 /* VCMP base address */ +#define EFM32_ACMP0_BASE 0x40001000 /* ACMP0 base address */ +#define EFM32_ACMP1_BASE 0x40001400 /* ACMP1 base address */ +#define EFM32_ADC0_BASE 0x40002000 /* ADC0 base address */ +#define EFM32_DAC0_BASE 0x40004000 /* DAC0 base address */ +#define EFM32_GPIO_BASE 0x40006000 /* GPIO base address */ +#define EFM32_I2C0_BASE 0x4000a000 /* I2C0 base address */ +#define EFM32_USART0_BASE 0x4000c000 /* USART0 base address */ +#define EFM32_USART1_BASE 0x4000c400 /* USART1 base address */ +#define EFM32_TIMER0_BASE 0x40010000 /* TIMER0 base address */ +#define EFM32_TIMER1_BASE 0x40010400 /* TIMER1 base address */ +#define EFM32_RTC_BASE 0x40080000 /* RTC base address */ +#define EFM32_LEUART0_BASE 0x40084000 /* LEUART0 base address */ +#define EFM32_LETIMER0_BASE 0x40082000 /* LETIMER0 base address */ +#define EFM32_PCNT0_BASE 0x40086000 /* PCNT0 base address */ +#define EFM32_WDOG_BASE 0x40088000 /* WDOG base address */ +#define EFM32_LCD_BASE 0x4008a000 /* LCD base address */ +#define EFM32_LESENSE_BASE 0x4008c000 /* LESENSE base address */ +#define EFM32_MSC_BASE 0x400c0000 /* MSC base address */ +#define EFM32_DMA_BASE 0x400c2000 /* DMA base address */ +#define EFM32_CMU_BASE 0x400c8000 /* CMU base address */ +#define EFM32_EMU_BASE 0x400c6000 /* EMU base address */ +#define EFM32_RMU_BASE 0x400ca000 /* RMU base address */ +#define EFM32_PRS_BASE 0x400cc000 /* PRS base address */ +#define EFM32_AES_BASE 0x400e0000 /* AES base address */ + +/* ROM specific region */ + +#define EFM32_ROMTABLE_BASE 0xe00fffd0 /* ROMTABLE base address */ + +/* Flash specific region */ + +#define EFM32_USERDATA_BASE 0x0fe00000 /* User data page base address */ +#define EFM32_LOCKBITS_BASE 0x0fe04000 /* Lock-bits page base address */ +#define EFM32_CALIBRATE_BASE 0x0fe08000 /* CALIBRATE base address */ +#define EFM32_DEVINFO_BASE 0x0fe081b0 /* DEVINFO base address */ + +#endif /* __ARCH_ARM_SRC_EFM32_CHIP_EFM3TG_MEMORYMAP_H */ diff --git a/arch/arm/src/efm32/chip/efm32tg_vectors.h b/arch/arm/src/efm32/chip/efm32tg_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..16689f9bfe8761d5cb704ddcb1d2e71fcf706ce1 --- /dev/null +++ b/arch/arm/src/efm32/chip/efm32tg_vectors.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/src/efm32/chip/efm32tg_vectors.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This file is included by efm32_vectors.S. It provides the macro VECTOR that + * supplies ach EFM32TG vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/efm32/efm32tg_irq.h. + * efm32_vectors.S will defined the VECTOR in different ways in order to + * generate the interrupt vectors and handlers in their final form. + * + * Vectors for low and medium density devices + */ + +#if defined(CONFIG_EFM32_EFM32TG) + +/* If the common ARMv7-M vector handling is used, then all it needs is the + * following definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 23 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 23 + +#else + VECTOR(EFM32_IRQ_DMA, EFM32_IRQ_DMA ) /* 0: EFM32_IRQ_DMA */ + VECTOR(EFM32_IRQ_GPIO_EVEN, EFM32_IRQ_GPIO_EVEN ) /* 1: EFM32_IRQ_GPIO_EVEN */ + VECTOR(EFM32_IRQ_TIMER0, EFM32_IRQ_TIMER0 ) /* 2: EFM32_IRQ_TIMER0 */ + VECTOR(EFM32_IRQ_USART0_RX, EFM32_IRQ_USART0_RX ) /* 3: EFM32_IRQ_USART0_RX */ + VECTOR(EFM32_IRQ_USART0_TX, EFM32_IRQ_USART0_TX ) /* 4: EFM32_IRQ_USART0_TX */ + VECTOR(EFM32_IRQ_ACMP, EFM32_IRQ_ACMP ) /* 5: EFM32_IRQ_ACMP */ + VECTOR(EFM32_IRQ_ADC0, EFM32_IRQ_ADC0 ) /* 6: EFM32_IRQ_ADC0 */ + VECTOR(EFM32_IRQ_DAC0, EFM32_IRQ_DAC0 ) /* 7: EFM32_IRQ_DAC0 */ + VECTOR(EFM32_IRQ_I2C0, EFM32_IRQ_I2C0 ) /* 8: EFM32_IRQ_I2C0 */ + VECTOR(EFM32_IRQ_GPIO_ODD, EFM32_IRQ_GPIO_ODD ) /* 9: EFM32_IRQ_GPIO_ODD */ + VECTOR(EFM32_IRQ_TIMER1, EFM32_IRQ_TIMER1 ) /* 10: EFM32_IRQ_TIMER1 */ + VECTOR(EFM32_IRQ_USART1_RX, EFM32_IRQ_USART1_RX ) /* 11: EFM32_IRQ_USART1_RX */ + VECTOR(EFM32_IRQ_USART1_TX, EFM32_IRQ_USART1_TX ) /* 12: EFM32_IRQ_USART1_TX */ + VECTOR(EFM32_IRQ_LESENSE, EFM32_IRQ_LESENSE ) /* 13: EFM32_IRQ_LESENSE */ + VECTOR(EFM32_IRQ_LEUART0, EFM32_IRQ_LEUART0 ) /* 14: EFM32_IRQ_LEUART0 */ + VECTOR(EFM32_IRQ_LETIMER0, EFM32_IRQ_LETIMER0 ) /* 15: EFM32_IRQ_LETIMER0 */ + VECTOR(EFM32_IRQ_PCNT0, EFM32_IRQ_PCNT0 ) /* 16: EFM32_IRQ_PCNT0 */ + VECTOR(EFM32_IRQ_RTC, EFM32_IRQ_RTC ) /* 17: EFM32_IRQ_RTC */ + VECTOR(EFM32_IRQ_CMU, EFM32_IRQ_CMU ) /* 18: EFM32_IRQ_CMU */ + VECTOR(EFM32_IRQ_VCMP, EFM32_IRQ_VCMP ) /* 19: EFM32_IRQ_VCMP */ + VECTOR(EFM32_IRQ_LCD, EFM32_IRQ_LCD ) /* 20: EFM32_IRQ_LCD */ + VECTOR(EFM32_IRQ_MSC, EFM32_IRQ_MSC ) /* 21: EFM32_IRQ_MSC */ + VECTOR(EFM32_IRQ_AES, EFM32_IRQ_AES ) /* 22: EFM32_IRQ_AES */ +#endif + +#else +# error "Unknown EFM32 Type" +#endif diff --git a/arch/arm/src/efm32/efm32_adc.c b/arch/arm/src/efm32/efm32_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..102384ff3de3ca9130f475459840d434e2514c72 --- /dev/null +++ b/arch/arm/src/efm32/efm32_adc.c @@ -0,0 +1,1286 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_adc.c + * + * Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved. + * Authors: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "efm32.h" +#include "efm32_adc.h" + +/* ADC "upper half" support must be enabled */ + +#ifdef CONFIG_ADC + +/* Some ADC peripheral must be enabled */ + +#if defined(CONFIG_EFM32_ADC1) + +/* This implementation is for the EFM32GG Only */ + +#if defined(CONFIG_EFM32_EFM32GG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* ADC interrupts ***********************************************************/ + +/* The maximum number of channels that can be sampled. If dma support is + * not enabled, then only a single channel can be sampled. Otherwise, + * data overruns would occur. + */ + +#ifdef CONFIG_ADC_DMA +# define ADC_MAX_SAMPLES 16 +# warning "not tested !" +#else +# define ADC_MAX_SAMPLES 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of one ADC block */ + +struct efm32_dev_s +{ + uint8_t irq; /* Interrupt generated by this ADC block */ + uint8_t nchannels; /* Number of channels */ + uint8_t current; /* Current ADC channel being converted */ + xcpt_t isr; /* Interrupt handler for this ADC block */ + uint32_t base; /* Base address of registers unique to this ADC block */ + uint8_t chanlist[ADC_MAX_SAMPLES]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* ADC Register access */ + +static uint32_t adc_getreg(struct efm32_dev_s *priv, int offset); +static void adc_putreg(struct efm32_dev_s *priv, int offset, uint32_t value); +static void adc_hw_reset(struct efm32_dev_s *priv, bool reset); + +/* ADC Interrupt Handler */ + +static int adc_interrupt(FAR struct adc_dev_s *dev); + +/* ADC Driver Methods */ + +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); +static void adc_enable(FAR struct efm32_dev_s *priv, bool enable); + +#ifdef ADC_HAVE_TIMER +static void adc_timstart(FAR struct efm32_dev_s *priv, bool enable); +static int adc_timinit(FAR struct efm32_dev_s *priv); +#endif + +#if defined(CONFIG_EFM32_EFM32GG) +static void adc_startconv(FAR struct efm32_dev_s *priv, bool enable); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ADC interface operations */ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset = adc_reset, + .ao_setup = adc_setup, + .ao_shutdown = adc_shutdown, + .ao_rxint = adc_rxint, + .ao_ioctl = adc_ioctl, +}; + +/* ADC1 state */ + +#ifdef CONFIG_EFM32_ADC1 +static struct efm32_dev_s g_adcpriv1 = +{ + .irq = EFM32_IRQ_ADC0, + .isr = adc_interrupt, + .base = EFM32_ADC1_BASE, +}; + +static struct adc_dev_s g_adcdev1 = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv1, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc_getreg + * + * Description: + * Read the value of an ADC register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +static uint32_t adc_getreg(struct efm32_dev_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: adc_getreg + * + * Description: + * Read the value of an ADC register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_putreg(struct efm32_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: ADC_CalibrateLoadScan + * + * Description: + * Load SCAN calibrate register with predefined values for a certain + * reference. + * + * During production, calibration values are made and stored in the device + * information page for known references. Notice that for external references, + * calibration values must be determined explicitly, and this function + * will not modify the calibration register. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * ref - Reference to load calibrated values for. No values are loaded for + * external references. + * + ****************************************************************************/ + +static void ADC_CalibrateLoadScan(ADC_TypeDef *adc, ADC_Ref_TypeDef ref) +{ + uint32_t cal; + + /* Load proper calibration data depending on selected reference + * NOTE: We use ...SCAN... defines below, they are the same as + * similar ...SINGLE... defines. + */ + + switch (ref) + { + case adcRef1V25: + cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >> + _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >> + _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef2V5: + cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >> + _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >> + _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRefVDD: + cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >> + _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >> + _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef5VDIFF: + cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >> + _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >> + _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef2xVDD: + /* Gain value not of relevance for this reference, leave as is */ + + cal = adc->CAL & ~_ADC_CAL_SCANOFFSET_MASK; + cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >> + _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT; + adc->CAL = cal; + break; + + /* For external references, the calibration must be determined for the + * specific application and set explicitly. + */ + + default: + break; + } +} + +/**************************************************************************** + * Name: ADC_CalibrateLoadSingle + * + * Description: + * Load SINGLE calibrate register with predefined values for a certain + * reference. + * + * During production, calibration values are made and stored in the device + * information page for known references. Notice that for external references, + * calibration values must be determined explicitly, and this function + * will not modify the calibration register. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * ref - Reference to load calibrated values for. No values are loaded for + * external references. + * + ****************************************************************************/ + +static void ADC_CalibrateLoadSingle(ADC_TypeDef *adc, ADC_Ref_TypeDef ref) +{ + uint32_t cal; + + /* Load proper calibration data depending on selected reference + * NOTE: We use ...SCAN... defines below, they are the same as + * similar ...SINGLE... defines. + */ + + switch (ref) + { + case adcRef1V25: + cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >> + _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >> + _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef2V5: + cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >> + _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >> + _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRefVDD: + cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >> + _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >> + _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef5VDIFF: + cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK); + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >> + _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT; + cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >> + _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; + adc->CAL = cal; + break; + + case adcRef2xVDD: + /* Gain value not of relevance for this reference, leave as is */ + + cal = adc->CAL & ~_ADC_CAL_SINGLEOFFSET_MASK; + cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >> + _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT; + adc->CAL = cal; + break; + + /* For external references, the calibration must be determined for the + * specific application and set explicitly. + */ + + default: + break; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ADC_Init + * Initialize ADC. + * + * Description: + * Initializes common parts for both single conversion and scan sequence. + * In addition, single and/or scan control configuration must be done, please + * refer to ADC_InitSingle() and ADC_InitScan() respectively. + * + * NOTE: This function will stop any ongoing conversion. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * int - Pointer to ADC initialization structure. + * + ****************************************************************************/ + +void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init) +{ + uint32_t tmp; + + EFM_ASSERT(ADC_REF_VALID(adc)); + + /* Make sure conversion is not in progress */ + + adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP; + + tmp = ((uint32_t)(init->ovsRateSel) << _ADC_CTRL_OVSRSEL_SHIFT) | + (((uint32_t)(init->timebase) << _ADC_CTRL_TIMEBASE_SHIFT) & _ADC_CTRL_TIMEBASE_MASK) | + (((uint32_t)(init->prescale) << _ADC_CTRL_PRESC_SHIFT) & _ADC_CTRL_PRESC_MASK) | + ((uint32_t)(init->lpfMode) << _ADC_CTRL_LPFMODE_SHIFT) | + ((uint32_t)(init->warmUpMode) << _ADC_CTRL_WARMUPMODE_SHIFT); + + if (init->tailgate) + { + tmp |= ADC_CTRL_TAILGATE; + } + + adc->CTRL = tmp; +} + +/**************************************************************************** + * Name: ADC_InitScan + * + * Description: + * Initialize ADC scan sequence. + * + * Please refer to ADC_Start() for starting scan sequence. + * + * When selecting an external reference, the gain and offset calibration + * must be set explicitly (CAL register). For other references, the + * calibration is updated with values defined during manufacturing. + * + * NOTE: This function will stop any ongoing scan sequence. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * init - Pointer to ADC initialization structure. + * + ****************************************************************************/ + +void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init) +{ + uint32_t tmp; + + EFM_ASSERT(ADC_REF_VALID(adc)); + + /* Make sure scan sequence is not in progress */ + + adc->CMD = ADC_CMD_SCANSTOP; + + /* Load proper calibration data depending on selected reference */ + + ADC_CalibrateLoadScan(adc, init->reference); + + tmp = ((uint32_t)(init->prsSel) << _ADC_SCANCTRL_PRSSEL_SHIFT) | + ((uint32_t)(init->acqTime) << _ADC_SCANCTRL_AT_SHIFT) | + ((uint32_t)(init->reference) << _ADC_SCANCTRL_REF_SHIFT) | + init->input | + ((uint32_t)(init->resolution) << _ADC_SCANCTRL_RES_SHIFT); + + if (init->prsEnable) + { + tmp |= ADC_SCANCTRL_PRSEN; + } + + if (init->leftAdjust) + { + tmp |= ADC_SCANCTRL_ADJ_LEFT; + } + + if (init->diff) + { + tmp |= ADC_SCANCTRL_DIFF; + } + + if (init->rep) + { + tmp |= ADC_SCANCTRL_REP; + } + + adc->SCANCTRL = tmp; +} + +/**************************************************************************** + * Name: ADC_InitSingle + * + * Description: + * Initialize single ADC sample conversion. + * + * Please refer to ADC_Start() for starting single conversion. + * + * When selecting an external reference, the gain and offset calibration + * must be set explicitly (CAL register). For other references, the + * calibration is updated with values defined during manufacturing. + * + * NOTE: This function will stop any ongoing single conversion. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * init - Pointer to ADC initialization structure. + * + ****************************************************************************/ + +void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init) +{ + uint32_t tmp; + + EFM_ASSERT(ADC_REF_VALID(adc)); + + /* Make sure single conversion is not in progress */ + + adc->CMD = ADC_CMD_SINGLESTOP; + + /* Load proper calibration data depending on selected reference */ + + ADC_CalibrateLoadSingle(adc, init->reference); + + tmp = ((uint32_t)(init->prsSel) << _ADC_SINGLECTRL_PRSSEL_SHIFT) | + ((uint32_t)(init->acqTime) << _ADC_SINGLECTRL_AT_SHIFT) | + ((uint32_t)(init->reference) << _ADC_SINGLECTRL_REF_SHIFT) | + ((uint32_t)(init->input) << _ADC_SINGLECTRL_INPUTSEL_SHIFT) | + ((uint32_t)(init->resolution) << _ADC_SINGLECTRL_RES_SHIFT); + + if (init->prsEnable) + { + tmp |= ADC_SINGLECTRL_PRSEN; + } + + if (init->leftAdjust) + { + tmp |= ADC_SINGLECTRL_ADJ_LEFT; + } + + if (init->diff) + { + tmp |= ADC_SINGLECTRL_DIFF; + } + + if (init->rep) + { + tmp |= ADC_SINGLECTRL_REP; + } + + adc->SINGLECTRL = tmp; +} + +/**************************************************************************** + * Name: ADC_PrescaleCalc + * + * Description: + * Calculate prescaler value used to determine ADC clock. + * + * The ADC clock is given by: HFPERCLK / (prescale + 1). + * + * Input Parameters: + * adcFreq ADC frequency wanted. The frequency will automatically + * be adjusted to be within valid range according to reference manual. + * hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to + * use currently defined HFPER clock setting. + * + * Returned Value: + * Prescaler value to use for ADC in order to achieve a clock value + * <= @p adcFreq. + * + ****************************************************************************/ + +uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq) +{ + uint32_t ret; + + /* Make sure selected ADC clock is within valid range */ + + if (adcFreq > ADC_MAX_CLOCK) + { + adcFreq = ADC_MAX_CLOCK; + } + else if (adcFreq < ADC_MIN_CLOCK) + { + adcFreq = ADC_MIN_CLOCK; + } + + /* Use current HFPER frequency? */ + + if (!hfperFreq) + { + hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER); + } + + ret = (hfperFreq + adcFreq - 1) / adcFreq; + if (ret) + { + ret--; + } + + return (uint8_t)ret; +} + +/**************************************************************************** + * Name: ADC_Reset + * + * Description: + * Reset ADC to same state as after a HW reset. + * + * @note + * The ROUTE register is NOT reset by this function, in order to allow for + * centralized setup of this feature. + * + * Input Parameters: + * adc - Pointer to ADC peripheral register block. + * + ****************************************************************************/ + +void ADC_Reset(ADC_TypeDef *adc) +{ + /* Stop conversions, before resetting other registers. */ + + adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP; + adc->SINGLECTRL = _ADC_SINGLECTRL_RESETVALUE; + adc->SCANCTRL = _ADC_SCANCTRL_RESETVALUE; + adc->CTRL = _ADC_CTRL_RESETVALUE; + adc->IEN = _ADC_IEN_RESETVALUE; + adc->IFC = _ADC_IFC_MASK; + adc->BIASPROG = _ADC_BIASPROG_RESETVALUE; + + /* Load calibration values for the 1V25 internal reference. */ + + ADC_CalibrateLoadSingle(adc, adcRef1V25); + ADC_CalibrateLoadScan(adc, adcRef1V25); + + /* Do not reset route register, setting should be done independently */ +} + +/**************************************************************************** + * Name: ADC_TimebaseCalc + * + * Description: + * Calculate timebase value in order to get a timebase providing at least 1us. + * + * Input Parameters: + * hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to + * use currently defined HFPER clock setting. + * + * Returned Value: + * Timebase value to use for ADC in order to achieve at least 1 us. + * + ****************************************************************************/ + +uint8_t ADC_TimebaseCalc(uint32_t hfperFreq) +{ + if (!hfperFreq) + { + hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER); + + /* Just in case, make sure we get non-zero freq for below calculation */ + + if (!hfperFreq) + { + hfperFreq = 1; + } + } + +#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY) + /* Handle errata on Giant Gecko, max TIMEBASE is 5 bits wide or max 0x1F + * cycles. This will give a warmp up time of e.g. 0.645us, not the + * required 1us when operating at 48MHz. One must also increase acqTime + * to compensate for the missing clock cycles, adding up to 1us in total. + * See reference manual for details. + */ + + if (hfperFreq > 32000000) + { + hfperFreq = 32000000; + } +#endif + + /* Determine number of HFPERCLK cycle >= 1us */ + + hfperFreq += 999999; + hfperFreq /= 1000000; + + /* Return timebase value (N+1 format) */ + + return (uint8_t)(hfperFreq - 1); +} +endif /* defined(ADC_COUNT) && (ADC_COUNT > 0) */ + +/**************************************************************************** + * Name: adc_tim_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the ADC block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static void adc_tim_dumpregs(struct efm32_dev_s *priv, FAR const char *msg) +{ +#if defined(CONFIG_DEBUG_ANALOG) && defined(CONFIG_DEBUG_VERBOSE) + avdbg("%s:\n", msg); + avdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + tim_getreg(priv, EFM32_GTIM_CR1_OFFSET), + tim_getreg(priv, EFM32_GTIM_CR2_OFFSET), + tim_getreg(priv, EFM32_GTIM_SMCR_OFFSET), + tim_getreg(priv, EFM32_GTIM_DIER_OFFSET)); + avdbg(" SR: %04x EGR: 0000 CCMR1: %04x CCMR2: %04x\n", + tim_getreg(priv, EFM32_GTIM_SR_OFFSET), + tim_getreg(priv, EFM32_GTIM_CCMR1_OFFSET), + tim_getreg(priv, EFM32_GTIM_CCMR2_OFFSET)); + avdbg(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", + tim_getreg(priv, EFM32_GTIM_CCER_OFFSET), + tim_getreg(priv, EFM32_GTIM_CNT_OFFSET), + tim_getreg(priv, EFM32_GTIM_PSC_OFFSET), + tim_getreg(priv, EFM32_GTIM_ARR_OFFSET)); + avdbg(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + tim_getreg(priv, EFM32_GTIM_CCR1_OFFSET), + tim_getreg(priv, EFM32_GTIM_CCR2_OFFSET), + tim_getreg(priv, EFM32_GTIM_CCR3_OFFSET), + tim_getreg(priv, EFM32_GTIM_CCR4_OFFSET)); + + if (priv->tbase == EFM32_TIM1_BASE || priv->tbase == EFM32_TIM8_BASE) + { + avdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + tim_getreg(priv, EFM32_ATIM_RCR_OFFSET), + tim_getreg(priv, EFM32_ATIM_BDTR_OFFSET), + tim_getreg(priv, EFM32_ATIM_DCR_OFFSET), + tim_getreg(priv, EFM32_ATIM_DMAR_OFFSET)); + } + else + { + avdbg(" DCR: %04x DMAR: %04x\n", + tim_getreg(priv, EFM32_GTIM_DCR_OFFSET), + tim_getreg(priv, EFM32_GTIM_DMAR_OFFSET)); + } +#endif +} +#endif + +/**************************************************************************** + * Name: adc_startconv + * + * Description: + * Start (or stop) the ADC conversion process in DMA mode + * + * Input Parameters: + * priv - A reference to the ADC block status + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_EFM32_EFM32GG) +static void adc_startconv(struct efm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + avdbg("enable: %d\n", enable); + + regval = adc_getreg(priv, EFM32_ADC_CR2_OFFSET); + if (enable) + { + /* Start conversion of regular channles */ + + regval |= ADC_CR2_SWSTART; + } + else + { + /* Disable the conversion of regular channels */ + + regval &= ~ADC_CR2_SWSTART; + } + + adc_putreg(priv, EFM32_ADC_CR2_OFFSET, regval); +} +#endif + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Deinitializes the ADCx peripheral registers to their default + * reset values. It could set all the ADCs configured. + * + * Input Parameters: + * regaddr - The register to read + * reset - Condition, set or reset + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_hw_reset(struct efm32_dev_s *priv, bool reset) +{ + irqstate_t flags; + uint32_t regval; + uint32_t adcbit; + + /* Pick the appropriate bit in the APB2 reset register */ + + /* Disable interrupts. This is necessary because the APB2RTSR register + * is used by several different drivers. + */ + + flags = enter_critical_section(); + + /* Set or clear the selected bit in the APB2 reset register */ + + regval = getreg32(EFM32_RCC_APB2RSTR); + if (reset) + { + /* Enable ADC reset state */ + + regval |= adcbit; + } + else + { + /* Release ADC from reset state */ + + regval &= ~adcbit; + } + + putreg32(regval, EFM32_RCC_APB2RSTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: adc_enable + * + * Description : Enables or disables the specified ADC peripheral. + * Also, starts a conversion when the ADC is not + * triggered by timers + * + * Input Parameters: + * + * enable - true: enable ADC conversion + * false: disable ADC conversion + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_enable(FAR struct efm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + avdbg("enable: %d\n", enable); + + regval = adc_getreg(priv, EFM32_ADC_CR2_OFFSET); + if (enable) + { + regval |= ADC_CR2_ADON; + } + else + { + regval &= ~ADC_CR2_ADON; + } + + adc_putreg(priv, EFM32_ADC_CR2_OFFSET, regval); +} + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before adc_setup() and on error conditions. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_reset(FAR struct adc_dev_s *dev) +{ + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + irqstate_t flags; + uint32_t regval; + int offset; + int i; +#ifdef ADC_HAVE_TIMER + int ret; +#endif + + avdbg("intf: ADC%d\n", priv->intf); + flags = enter_critical_section(); + + /* Enable ADC reset state */ + + adc_hw_reset(priv, true); + + /* Release ADC from reset state */ + + adc_hw_reset(priv, false); + + /* Initialize the ADC data structures */ + + /* Initialize the watchdog high threshold register */ + + adc_putreg(priv, EFM32_ADC_HTR_OFFSET, 0x00000fff); + + /* Initialize the watchdog low threshold register */ + + adc_putreg(priv, EFM32_ADC_LTR_OFFSET, 0x00000000); + + /* Initialize the same sample time for each ADC 55.5 cycles + * + * During sample cycles channel selection bits must remain unchanged. + * + * 000: 1.5 cycles + * 001: 7.5 cycles + * 010: 13.5 cycles + * 011: 28.5 cycles + * 100: 41.5 cycles + * 101: 55.5 cycles + * 110: 71.5 cycles + * 111: 239.5 cycles + */ + + adc_putreg(priv, EFM32_ADC_SMPR1_OFFSET, 0x00b6db6d); + adc_putreg(priv, EFM32_ADC_SMPR2_OFFSET, 0x00b6db6d); + + /* ADC CR1 Configuration */ + + regval = adc_getreg(priv, EFM32_ADC_CR1_OFFSET); + + /* Initialize the Analog watchdog enable */ + + regval |= ADC_CR1_AWDEN; + regval |= (priv->chanlist[0] << ADC_CR1_AWDCH_SHIFT); + + /* Enable interrupt flags */ + + regval |= ADC_CR1_ALLINTS; + + adc_putreg(priv, EFM32_ADC_CR1_OFFSET, regval); + + /* ADC CR2 Configuration */ + + regval = adc_getreg(priv, EFM32_ADC_CR2_OFFSET); + + /* Clear CONT, continuous mode disable */ + + regval &= ~ADC_CR2_CONT; + + /* Set ALIGN (Right = 0) */ + + regval &= ~ADC_CR2_ALIGN; + + adc_putreg(priv, EFM32_ADC_CR2_OFFSET, regval); + + /* Configuration of the channel conversions */ + + regval = adc_getreg(priv, EFM32_ADC_SQR3_OFFSET) & ADC_SQR3_RESERVED; + for (i = 0, offset = 0; i < priv->nchannels && i < 6; i++, offset += 5) + { + regval |= (uint32_t)priv->chanlist[i] << offset; + } + + adc_putreg(priv, EFM32_ADC_SQR3_OFFSET, regval); + + regval = adc_getreg(priv, EFM32_ADC_SQR2_OFFSET) & ADC_SQR2_RESERVED; + for (i = 6, offset = 0; i < priv->nchannels && i < 12; i++, offset += 5) + { + regval |= (uint32_t)priv->chanlist[i] << offset; + } + + adc_putreg(priv, EFM32_ADC_SQR2_OFFSET, regval); + + regval = adc_getreg(priv, EFM32_ADC_SQR1_OFFSET) & ADC_SQR1_RESERVED; + for (i = 12, offset = 0; i < priv->nchannels && i < 16; i++, offset += 5) + { + regval |= (uint32_t)priv->chanlist[i] << offset; + } + + /* ADC CCR configuration */ + + regval = getreg32(EFM32_ADC_CCR); + regval &= ~(ADC_CCR_MULTI_MASK | ADC_CCR_DELAY_MASK | ADC_CCR_DDS | ADC_CCR_DMA_MASK | + ADC_CCR_ADCPRE_MASK | ADC_CCR_VBATE | ADC_CCR_TSVREFE); + regval |= (ADC_CCR_MULTI_NONE | ADC_CCR_DMA_DISABLED | ADC_CCR_ADCPRE_DIV2); + putreg32(regval, EFM32_ADC_CCR); + + /* Set the number of conversions */ + + DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES); + + regval |= (((uint32_t)priv->nchannels-1) << ADC_SQR1_L_SHIFT); + adc_putreg(priv, EFM32_ADC_SQR1_OFFSET, regval); + + /* Set the channel index of the first conversion */ + + priv->current = 0; + + /* Set ADON to wake up the ADC from Power Down state. */ + + adc_enable(priv, true); + + adc_startconv(priv, true); + + leave_critical_section(flags); + + avdbg("SR: 0x%08x CR1: 0x%08x CR2: 0x%08x\n", + adc_getreg(priv, EFM32_ADC_SR_OFFSET), + adc_getreg(priv, EFM32_ADC_CR1_OFFSET), + adc_getreg(priv, EFM32_ADC_CR2_OFFSET)); + avdbg("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x\n", + adc_getreg(priv, EFM32_ADC_SQR1_OFFSET), + adc_getreg(priv, EFM32_ADC_SQR2_OFFSET), + adc_getreg(priv, EFM32_ADC_SQR3_OFFSET)); +} + +/**************************************************************************** + * Name: adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. Interrupts + * are all disabled upon return. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_setup(FAR struct adc_dev_s *dev) +{ + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + int ret; + + /* Attach the ADC interrupt */ + + ret = irq_attach(priv->irq, priv->isr); + if (ret == OK) + { + /* Make sure that the ADC device is in the powered up, reset state */ + + adc_reset(dev); + + /* Enable the ADC interrupt */ + + avdbg("Enable the ADC interrupt: irq=%d\n", priv->irq); + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + + /* Disable ADC interrupts and detach the ADC interrupt handler */ + + up_disable_irq(priv->irq); + irq_detach(priv->irq); + + /* Disable and reset the ADC module */ + + adc_hw_reset(priv, true); +} + +/**************************************************************************** + * Name: adc_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + uint32_t regval; + + avdbg("intf: %d enable: %d\n", priv->intf, enable); + + regval = adc_getreg(priv, EFM32_ADC_CR1_OFFSET); + if (enable) + { + /* Enable the end-of-conversion ADC and analog watchdog interrupts */ + + regval |= ADC_CR1_ALLINTS; + } + else + { + /* Disable all ADC interrupts */ + + regval &= ~ADC_CR1_ALLINTS; + } + + adc_putreg(priv, EFM32_ADC_CR1_OFFSET, regval); +} + +/**************************************************************************** + * Name: adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: adc_interrupt + * + * Description: + * Common ADC interrupt handler. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_interrupt(FAR struct adc_dev_s *dev) +{ + FAR struct efm32_dev_s *priv = (FAR struct efm32_dev_s *)dev->ad_priv; + uint32_t adcsr; + int32_t value; + + /* Identifies the interruption AWD, OVR or EOC */ + + adcsr = adc_getreg(priv, EFM32_ADC_SR_OFFSET); + if ((adcsr & ADC_SR_AWD) != 0) + { + alldbg("WARNING: Analog Watchdog, Value converted out of range!\n"); + } + + /* EOC: End of conversion */ + + if ((adcsr & ADC_SR_EOC) != 0) + { + /* Read the converted value and clear EOC bit + * (It is cleared by reading the ADC_DR) + */ + + value = adc_getreg(priv, EFM32_ADC_DR_OFFSET); + value &= ADC_DR_DATA_MASK; + + /* Give the ADC data to the ADC driver. adc_receive accepts 3 parameters: + * + * 1) The first is the ADC device instance for this ADC block. + * 2) The second is the channel number for the data, and + * 3) The third is the converted data for the channel. + */ + + adc_receive(dev, priv->chanlist[priv->current], value); + + /* Set the channel number of the next channel that will complete conversion */ + + priv->current++; + + if (priv->current >= priv->nchannels) + { + /* Restart the conversion sequence from the beginning */ + + priv->current = 0; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_adcinitialize + * + * Description: + * Initialize the ADC. + * + * The logic is, save nchannels : # of channels (conversions) in ADC_SQR1_L + * Then, take the chanlist array and store it in the SQR Regs, + * chanlist[0] -> ADC_SQR3_SQ1 + * chanlist[1] -> ADC_SQR3_SQ2 + * ... + * chanlist[15]-> ADC_SQR1_SQ16 + * + * up to + * chanlist[nchannels] + * + * Input Parameters: + * intf - Could be {1,2,3} for ADC1, ADC2, or ADC3 + * chanlist - The list of channels + * nchannels - Number of channels + * + * Returned Value: + * Valid ADC device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s *efm32_adcinitialize(int intf, const uint8_t *chanlist, int nchannels) +{ + FAR struct adc_dev_s *dev; + FAR struct efm32_dev_s *priv; + + avdbg("intf: %d nchannels: %d\n", intf, nchannels); + +#ifdef CONFIG_EFM32_ADC1 + if (intf == 1) + { + avdbg("ADC1 Selected\n"); + dev = &g_adcdev1; + } + else +#endif +#ifdef CONFIG_EFM32_ADC2 + if (intf == 2) + { + avdbg("ADC2 Selected\n"); + dev = &g_adcdev2; + } + else +#endif +#ifdef CONFIG_EFM32_ADC3 + if (intf == 3) + { + avdbg("ADC3 Selected\n"); + dev = &g_adcdev3; + } + else +#endif + { + adbg("No ADC interface defined\n"); + return NULL; + } + + /* Configure the selected ADC */ + + priv = dev->ad_priv; + + DEBUGASSERT(nchannels <= ADC_MAX_SAMPLES); + priv->nchannels = nchannels; + + memcpy(priv->chanlist, chanlist, nchannels); + return dev; +} + +#endif /* CONFIG_EFM32_EFM32GG */ +#endif /* CONFIG_EFM32_ADC1 */ +#endif /* CONFIG_ADC */ diff --git a/arch/arm/src/efm32/efm32_adc.h b/arch/arm/src/efm32/efm32_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..9b892c0663e8ff1e683965909d8e7c0a1b9cbc2b --- /dev/null +++ b/arch/arm/src/efm32/efm32_adc.h @@ -0,0 +1,591 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_adc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_ADC_H +#define __ARCH_ARM_SRC_EFM32_EFM32_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#include "chip/efm32_adc.h" + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic ADC sampling. If CONFIG_EFM32_TIMn is defined then + * CONFIG_EFM32_TIMn_ADC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +/* For the EFM32 F1 line, timers 1-4 may be used. For EFM32 F4 line, timers 1-5 and + * 8 may be used. + */ + +#ifndef CONFIG_EFM32_TIM1 +# undef CONFIG_EFM32_TIM1_ADC +# undef CONFIG_EFM32_TIM1_ADC1 +# undef CONFIG_EFM32_TIM1_ADC2 +# undef CONFIG_EFM32_TIM1_ADC3 +#endif +#ifndef CONFIG_EFM32_TIM2 +# undef CONFIG_EFM32_TIM2_ADC +# undef CONFIG_EFM32_TIM2_ADC1 +# undef CONFIG_EFM32_TIM2_ADC2 +# undef CONFIG_EFM32_TIM2_ADC3 +#endif +#ifndef CONFIG_EFM32_TIM3 +# undef CONFIG_EFM32_TIM3_ADC +# undef CONFIG_EFM32_TIM3_ADC1 +# undef CONFIG_EFM32_TIM3_ADC2 +# undef CONFIG_EFM32_TIM3_ADC3 +#endif +#ifndef CONFIG_EFM32_TIM4 +# undef CONFIG_EFM32_TIM4_ADC +# undef CONFIG_EFM32_TIM4_ADC1 +# undef CONFIG_EFM32_TIM4_ADC2 +# undef CONFIG_EFM32_TIM4_ADC3 +#endif +#ifndef CONFIG_EFM32_TIM5 +# undef CONFIG_EFM32_TIM5_ADC +# undef CONFIG_EFM32_TIM5_ADC1 +# undef CONFIG_EFM32_TIM5_ADC2 +# undef CONFIG_EFM32_TIM5_ADC3 +#endif +#ifndef CONFIG_EFM32_TIM8 +# undef CONFIG_EFM32_TIM8_ADC +# undef CONFIG_EFM32_TIM8_ADC1 +# undef CONFIG_EFM32_TIM8_ADC2 +# undef CONFIG_EFM32_TIM8_ADC3 +#endif + +/* Timers 6, 7, and 10-14 are not used with the ADC by any supported family */ + +#undef CONFIG_EFM32_TIM6_ADC +#undef CONFIG_EFM32_TIM6_ADC1 +#undef CONFIG_EFM32_TIM6_ADC2 +#undef CONFIG_EFM32_TIM6_ADC3 +#undef CONFIG_EFM32_TIM7_ADC +#undef CONFIG_EFM32_TIM7_ADC1 +#undef CONFIG_EFM32_TIM7_ADC2 +#undef CONFIG_EFM32_TIM7_ADC3 +#undef CONFIG_EFM32_TIM9_ADC +#undef CONFIG_EFM32_TIM9_ADC1 +#undef CONFIG_EFM32_TIM9_ADC2 +#undef CONFIG_EFM32_TIM9_ADC3 +#undef CONFIG_EFM32_TIM10_ADC +#undef CONFIG_EFM32_TIM10_ADC1 +#undef CONFIG_EFM32_TIM10_ADC2 +#undef CONFIG_EFM32_TIM10_ADC3 +#undef CONFIG_EFM32_TIM11_ADC +#undef CONFIG_EFM32_TIM11_ADC1 +#undef CONFIG_EFM32_TIM11_ADC2 +#undef CONFIG_EFM32_TIM11_ADC3 +#undef CONFIG_EFM32_TIM12_ADC +#undef CONFIG_EFM32_TIM12_ADC1 +#undef CONFIG_EFM32_TIM12_ADC2 +#undef CONFIG_EFM32_TIM12_ADC3 +#undef CONFIG_EFM32_TIM13_ADC +#undef CONFIG_EFM32_TIM13_ADC1 +#undef CONFIG_EFM32_TIM13_ADC2 +#undef CONFIG_EFM32_TIM13_ADC3 +#undef CONFIG_EFM32_TIM14_ADC +#undef CONFIG_EFM32_TIM14_ADC1 +#undef CONFIG_EFM32_TIM14_ADC2 +#undef CONFIG_EFM32_TIM14_ADC3 + +/* Up to 3 ADC interfaces are supported */ + +#if EFM32_NADC < 3 +# undef CONFIG_EFM32_ADC3 +#endif + +#if EFM32_NADC < 2 +# undef CONFIG_EFM32_ADC2 +#endif + +#if EFM32_NADC < 1 +# undef CONFIG_EFM32_ADC1 +#endif + +#if defined(CONFIG_EFM32_ADC1) || defined(CONFIG_EFM32_ADC2) || defined(CONFIG_EFM32_ADC3) + +/* DMA support is not yet implemented for this driver */ + +#ifdef CONFIG_ADC_DMA +# warning "DMA is not supported by the current driver" +#endif + +/* Timer configuration: If a timer trigger is specified, then get information + * about the timer. + */ + +#if defined(CONFIG_EFM32_TIM1_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM1_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_EFM32_TIM2_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM2_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_EFM32_TIM3_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM3_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_EFM32_TIM4_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM4_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_EFM32_TIM5_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM5_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_EFM32_TIM8_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE EFM32_TIM8_BASE +# define ADC1_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM8_CLKIN +#else +# undef ADC1_HAVE_TIMER +#endif + +#ifdef ADC1_HAVE_TIMER +# ifndef CONFIG_EFM32_ADC1_SAMPLE_FREQUENCY +# error "CONFIG_EFM32_ADC1_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_EFM32_ADC1_TIMTRIG +# error "CONFIG_EFM32_ADC1_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(CONFIG_EFM32_TIM1_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM1_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_EFM32_TIM2_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM2_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_EFM32_TIM3_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM3_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_EFM32_TIM4_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM4_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_EFM32_TIM5_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM5_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_EFM32_TIM8_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE EFM32_TIM8_BASE +# define ADC2_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM8_CLKIN +#else +# undef ADC2_HAVE_TIMER +#endif + +#ifdef ADC2_HAVE_TIMER +# ifndef CONFIG_EFM32_ADC2_SAMPLE_FREQUENCY +# error "CONFIG_EFM32_ADC2_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_EFM32_ADC2_TIMTRIG +# error "CONFIG_EFM32_ADC2_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(CONFIG_EFM32_TIM1_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM1_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_EFM32_TIM2_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM2_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_EFM32_TIM3_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM3_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_EFM32_TIM4_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM4_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_EFM32_TIM5_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM5_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_EFM32_TIM8_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE EFM32_TIM8_BASE +# define ADC3_TIMER_PCLK_FREQUENCY EFM32_APB2_TIM8_CLKIN +#else +# undef ADC3_HAVE_TIMER +#endif + +#ifdef ADC3_HAVE_TIMER +# ifndef CONFIG_EFM32_ADC3_SAMPLE_FREQUENCY +# error "CONFIG_EFM32_ADC3_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_EFM32_ADC3_TIMTRIG +# error "CONFIG_EFM32_ADC3_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || defined(ADC3_HAVE_TIMER) +# define ADC_HAVE_TIMER 1 +# if defined(CONFIG_EFM32_EFM32F10XX) && !defined(CONFIG_EFM32_FORCEPOWER) +# warning "CONFIG_EFM32_FORCEPOWER must be defined to enable the timer(s)" +# endif +#else +# undef ADC_HAVE_TIMER +#endif + +/* NOTE: The following assumes that all possible combinations of timers and + * values are support EXTSEL. That is not so and it varies from one EFM32 to another. + * But this (wrong) assumptions keeps the logic as simple as possible. If un + * unsupported combination is used, an error will show up later during compilation + * although it may be difficult to track it back to this simplification. + */ + +#if defined(CONFIG_EFM32_TIM1_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM2_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM3_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM4_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM5_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM8_ADC1) +# if CONFIG_EFM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC1 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4 +# elif CONFIG_EFM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO +# else +# error "CONFIG_EFM32_ADC1_TIMTRIG is out of range" +# endif +#endif + +#if defined(CONFIG_EFM32_TIM1_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM2_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM3_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM4_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM5_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM8_ADC2) +# if CONFIG_EFM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC1 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4 +# elif CONFIG_EFM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO +# else +# error "CONFIG_EFM32_ADC2_TIMTRIG is out of range" +# endif +#endif + +#if defined(CONFIG_EFM32_TIM1_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM2_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM3_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM4_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM5_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_EFM32_TIM8_ADC3) +# if CONFIG_EFM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC1 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC2 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC3 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC4 +# elif CONFIG_EFM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8TRGO +# else +# error "CONFIG_EFM32_ADC3_TIMTRIG is out of range" +# endif +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: efm32_adcinitialize + * + * Description: + * Initialize the ADC. + * + * Input Parameters: + * intf - Could be {1,2,3} for ADC1, ADC2, or ADC3 + * chanlist - The list of channels + * nchannels - Number of channels + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s; +struct adc_dev_s *efm32_adcinitialize(int intf, const uint8_t *chanlist, + int nchannels); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_EFM32_ADC || CONFIG_EFM32_ADC2 || CONFIG_EFM32_ADC3 */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_ADC_H */ + diff --git a/arch/arm/src/efm32/efm32_bitband.c b/arch/arm/src/efm32/efm32_bitband.c new file mode 100644 index 0000000000000000000000000000000000000000..fa45b660b8348279fe4c020d3b42c1ff312a9e66 --- /dev/null +++ b/arch/arm/src/efm32/efm32_bitband.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_bitband.c + * + * Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved. + * Authors: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stdint.h" + +#include "efm32_bitband.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_EFM32_BITBAND) + +#ifndef EFM32_BITBAND_PER_BASE +# error "EFM32_BITBAND_PER_BASE not declared bitband may be not supported?" +#endif + +#ifndef EFM32_BITBAND_RAM_BASE +# error "EFM32_BITBAND_RAM_BASE not declared bitband may be not supported?" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bitband_set_peripheral + * + * Description: + * Perform bit-band write operation on peripheral memory location. + * + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Input Parmeters: + * addr Peripheral address location to modify bit in. + * bit Bit position to modify, 0-31. + * val Value to set bit to, 0 or 1. + * + ****************************************************************************/ + +inline void bitband_set_peripheral(uint32_t addr, uint32_t bit, uint32_t val) +{ + uint32_t regval; + regval = EFM32_BITBAND_PER_BASE + ((addr-EFM32_PER_MEM_BASE)*32) + (bit*4); + + *((volatile uint32_t *)regval) = (uint32_t)val; +} + +/**************************************************************************** + * Name: bitband_get_peripheral + * + * Description: + * Perform bit-band operation on peripheral memory location. + * + * This function reads a single bit from the peripheral bit-band alias region. + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Input Parmeters: + * addr Peripheral address location to read. + * bit Bit position to modify, 0-31. + * + * Returned Value: + * Return bit value read, 0 or 1. + * + ****************************************************************************/ + +inline uint32_t bitband_get_peripheral(uint32_t addr, uint32_t bit) +{ + uint32_t regval; + regval = EFM32_BITBAND_PER_BASE + ((addr-EFM32_PER_MEM_BASE)*32) + (bit*4); + + return *((volatile uint32_t *)regval); +} + +/**************************************************************************** + * Name: bitband_set_sram + * + * Description: + * Perform bit-band write operation on SRAM memory location. + * + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Input Parmeters: + * addr SRAM address location to modify bit in. + * bit Bit position to modify, 0-31. + * val Value to set bit to, 0 or 1. + * + ****************************************************************************/ + +inline void bitband_set_sram(uint32_t addr, uint32_t bit, uint32_t val) +{ + uint32_t regval; + regval = EFM32_BITBAND_RAM_BASE + ((addr-EFM32_RAM_MEM_BASE)*32) + (bit*4); + + *((volatile uint32_t *)regval) = (uint32_t)val; +} + +/**************************************************************************** + * Name: bitband_get_sram + * + * Description:: + * Perform bit-band operation on SRAM memory location. + * + * This function reads a single bit from the RAM bit-band alias region. + * Bit-banding provides atomic read-modify-write cycle for single bit + * modification. Please refer to the reference manual for further details + * about bit-banding. + * + * Note + * This function is only atomic on cores which fully support bitbanding. + * + * Input Parmeters: + * addr Peripheral address location to read. + * bit Bit position to modify, 0-31. + * + * Returned Value: + * Return bit value read, 0 or 1. + * + ****************************************************************************/ + +inline uint32_t bitband_get_sram(uint32_t addr, uint32_t bit) +{ + uint32_t regval; + regval = EFM32_BITBAND_RAM_BASE + ((addr-EFM32_RAM_MEM_BASE)*32) + (bit*4); + + return *((volatile uint32_t *)regval); +} +#endif diff --git a/arch/arm/src/efm32/efm32_bitband.h b/arch/arm/src/efm32/efm32_bitband.h new file mode 100644 index 0000000000000000000000000000000000000000..9c655de78a45fa8cde35b4b4b978a6b8e934fbd1 --- /dev/null +++ b/arch/arm/src/efm32/efm32_bitband.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_bitband.h + * + * Copyright (C) 2015 Pierre-noel Bouteville . All rights reserved. + * Authors: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H +#define __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip/efm32_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(CONFIG_EFM32_BITBAND) +inline void bitband_set_peripheral(uint32_t addr, uint32_t bit, uint32_t val); +inline uint32_t bitband_get_peripheral(uint32_t addr, uint32_t bit); +inline void bitband_set_sram(uint32_t addr, uint32_t bit, uint32_t val); +inline uint32_t bitband_get_sram(uint32_t addr, uint32_t bit); + +#else + +# define bitband_set_peripheral(addr,bit,val)\ + modifyreg32(addr,~(1<> bit) & 1) + +# define bitband_set_sram(add,bit,val)\ + modifyreg32(addr,~(1<> bit) & 1) + +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_BITBAND_H */ diff --git a/arch/arm/src/efm32/efm32_clockconfig.c b/arch/arm/src/efm32/efm32_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..e2f0d3b5df7fc7530b39e467470ce7f587dc56d0 --- /dev/null +++ b/arch/arm/src/efm32/efm32_clockconfig.c @@ -0,0 +1,970 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_clockconfig.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "itm_syslog.h" +#include "efm32_gpio.h" +#include "chip/efm32_msc.h" +#include "chip/efm32_cmu.h" +#include "chip/efm32_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* BOARD Configuration ******************************************************/ + +/* Pre-scalers not currently implemented */ + +#if defined(CONFIG_EFM32_EFM32GG) && defined(BOARD_HFCLKDIV) && BOARD_HFCLKDIV != 0 +# error HFCLK divisor not yet supported +#endif + +#if defined(BOARD_HFCORECLKDIV) && BOARD_HFCORECLKDIV != 0 +# error HFCORECLK divisor not yet supported +#endif + +#if defined(BOARD_HFPERCLKDIV) && BOARD_HFPERCLKDIV != 0 +# error HFPERCLK divisor not yet supported +#endif + +#ifdef BOARD_LFACLK_ULFRCO +# define BOARD_LFA_ULFCO_ENABLE true +#else +# define BOARD_LFA_ULFCO_ENABLE false +#endif + +#ifdef BOARD_LFBCLK_ULFRCO +# define BOARD_LFB_ULFCO_ENABLE true +#else +# define BOARD_LFB_ULFCO_ENABLE false +#endif + +#ifndef CONFIG_EFM32_LECLOCK +# if ( ( BOARD_LFACLKSEL != _CMU_LFCLKSEL_LFA_DISABLED ) || \ + ( BOARD_LFBCLKSEL != _CMU_LFCLKSEL_LFB_DISABLED ) || \ + ( defined ( CONFIG_EFM32_RTC_BURTC ) ) || \ + ( defined ( CONFIG_EFM32_LEUART0 ) ) || \ + ( defined ( CONFIG_EFM32_LEUART1 ) ) \ + ) +# define CONFIG_EFM32_LECLOCK +# endif +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_synchronize + * + * Description: + * Wait for ongoing sync of register(s) to low frequency domain to + * complete. + * + * Input Parameters: + * bitset - Bitset corresponding to SYNCBUSY register defined bits, + * indicating registers that must complete any ongoing + * synchronization. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void efm32_synchronize(uint32_t bitset) +{ + /* Avoid deadlock if modifying a register again after freeze mode is + * activated. + */ + + if ((getreg32(EFM32_CMU_FREEZE) & CMU_FREEZE_REGFREEZE) == 0) + { + /* Wait for any pending previous write operation to complete */ + + while ((getreg32(EFM32_CMU_SYNCBUSY) & bitset) != 0); + } +} + +/**************************************************************************** + * Name: efm32_statuswait + * + * Description: + * Wait for ongoing CMU status bit(s) to become set + * + * Input Parameters: + * bitset - Bitset corresponding to STATUS register defined bits, + * indicating events that we are waiting for. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void efm32_statuswait(uint32_t bitset) +{ + /* Wait for clock to stabilize if requested */ + + while ((getreg32(EFM32_CMU_STATUS) & bitset) == 0); +} + +/**************************************************************************** + * Name: efm32_enable_XXX + * + * Description: + * Enable specific oscillators + * + ****************************************************************************/ + +static void efm32_enable_lfrco(void) +{ + /* Enable the LFRCO */ + + putreg32(CMU_OSCENCMD_LFRCOEN, EFM32_CMU_OSCENCMD); + efm32_statuswait(CMU_STATUS_LFRCORDY); +} + +static void efm32_enable_lfxo(void) +{ + /* Enable the LFXO */ + + putreg32(CMU_OSCENCMD_LFXOEN, EFM32_CMU_OSCENCMD); + efm32_statuswait(CMU_STATUS_LFXORDY); +} + +static inline void efm32_enable_hfrco(void) +{ + /* Enable the HFRCO */ + + putreg32(CMU_OSCENCMD_HFRCOEN, EFM32_CMU_OSCENCMD); + efm32_statuswait(CMU_STATUS_HFRCORDY); +} + +static void efm32_enable_hfxo(void) +{ + /* Enable the HFXO */ + + putreg32(CMU_OSCENCMD_HFXOEN, EFM32_CMU_OSCENCMD); + efm32_statuswait(CMU_STATUS_HFXORDY); +} + +static inline void efm32_enable_auxhfrco(void) +{ + /* Enable the HFXO */ + + putreg32(CMU_OSCENCMD_AUXHFRCOEN, EFM32_CMU_OSCENCMD); + efm32_statuswait(CMU_STATUS_AUXHFRCORDY); +} + +/**************************************************************************** + * Name: efm32_enable_leclocking + * + * Description: + * Enable HFCORE clocking to the LE + * + ****************************************************************************/ + +static void efm32_enable_leclocking(void) +{ + uint32_t regval; + + regval = getreg32(EFM32_CMU_HFCORECLKEN0); + regval |= CMU_HFCORECLKEN0_LE; + putreg32(regval, EFM32_CMU_HFCORECLKEN0); +} + + +/**************************************************************************** + * Name: efm32_maxwaitstates + * + * Description: + * Configure flash access wait states to most maximum number of wait + * states, preserving the SCBTP setting. + * + ****************************************************************************/ + +static void efm32_maxwaitstates(void) +{ + uint32_t regval; + uint32_t mode; + + /* Get the READCTRL register content and mask out the mode setting */ + + regval = getreg32(EFM32_MSC_READCTRL); + mode = regval & _MSC_READCTRL_MODE_MASK; + regval &= ~_MSC_READCTRL_MODE_MASK; + + /* SCBTP mode? */ + + if (mode == MSC_READCTRL_MODE_WS0SCBTP + || mode == MSC_READCTRL_MODE_WS1SCBTP +#ifdef MSC_READCTRL_MODE_WS2SCBTP + || mode == MSC_READCTRL_MODE_WS2SCBTP +#endif + ) + { + /* Yes.. select the mximum number of wait states with SCBTP */ + + regval |= MSC_READCTRL_MODE_WSMAXSCBTP; + } + else + { + /* No.. select the mximum number of wait states without SCBTP */ + + regval |= MSC_READCTRL_MODE_WSMAX; + } + + /* And save the update READCTRL register */ + + putreg32(regval, EFM32_MSC_READCTRL); +} + +/**************************************************************************** + * Name: efm32_setwaitstates + * + * Description: + * Configure the optimal number of flash access wait states, preserving + * the SCBTP setting. + * + ****************************************************************************/ + +static void efm32_setwaitstates(uint32_t hfcoreclk) +{ + uint32_t regval; + uint32_t mode; + bool scbtp; + + /* SCBTP mode? */ + + regval = getreg32(EFM32_MSC_READCTRL); + mode = regval & _MSC_READCTRL_MODE_MASK; + scbtp = (mode == MSC_READCTRL_MODE_WS0SCBTP + || mode == MSC_READCTRL_MODE_WS1SCBTP +#ifdef MSC_READCTRL_MODE_WS2SCBTP + || mode == MSC_READCTRL_MODE_WS2SCBTP +#endif + ); + + /* Select the number of wait states based on the HFCORECLK frequency */ + + regval &= ~_MSC_READCTRL_MODE_MASK; + + /* We can't do more than 2 wait states in any configuration */ + +#ifdef MSC_READCTRL_MODE_WS2 + if (hfcoreclk > CMU_MAX_FREQ_2WS) + { + PANIC(); + } + else +#endif + + /* Check if we can use 2 wait states */ + + if (hfcoreclk > CMU_MAX_FREQ_1WS) + { +#ifdef MSC_READCTRL_MODE_WS2 + /* Yes.. select 2 wait states */ + + regval |= (scbtp ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2); +#else + /* No.. this MCU does not support 2 wait states */ + + PANIC(); +#endif + } + + /* Check if we can use 1 wait states */ + + else if (hfcoreclk > CMU_MAX_FREQ_0WS) + { + /* Yes.. select 1 wait state */ + + regval |= (scbtp ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1); + } + + /* Check if we can use no wait states */ + + else + { + /* Select no wait states */ + + regval |= (scbtp ? MSC_READCTRL_MODE_WS0SCBTP : MSC_READCTRL_MODE_WS0); + } + + /* And save the update READCTRL register */ + + putreg32(regval, EFM32_MSC_READCTRL); +} + +/**************************************************************************** + * Name: efm32_hfclk_config + * + * Description: + * Configure the High Frequency Clock, HFCLK. + * + * HFCLK is the selected High Frequency Clock. This clock is used by the + * CMU and drives the two prescalers that generate HFCORECLK and HFPERCLK. + * The HFCLK can be driven by a high-frequency oscillator (HFRCO or HFXO) + * or one of the low-frequency oscillators (LFRCO or LFXO). By default the + * HFRCO is selected. To change the selected HFCLK write to HFCLKSEL in + * CMU_CMD. The HFCLK is running in EM0 and EM1. + * + * HFCLK can optionally be divided down by setting HFCLKDIV in CMU_CTRL to + * a non-zero value. This divides down HFCLK to all high frequency + * components except the USB Core and is typically used to save energy in + * USB applications where the system is not required to run at 48 MHz. + * Combined with the HFCORECLK and HFPERCLK prescalers the HFCLK divider + * also allows for more flexible clock division. + * + ****************************************************************************/ + +static inline uint32_t efm32_hfclk_config(uint32_t hfclksel, uint32_t hfclkdiv) +{ + uint32_t frequency; +#ifdef CMU_CTRL_HFLE + uint32_t regval; +#endif + + /* The HFRCO oscillator is selected by hardware as the clock source for + * HFCLK when the device starts up . After reset, the HFRCO frequency is + * 14 MHz. + * + * First enable the oscillator and wait for the oscillator to become ready + * before switching the clock source. This way, the system continues to run + * on the HFRCO until the oscillator has timed out and provides a reliable + * clock. + */ + + switch (hfclksel) + { + case _CMU_CMD_HFCLKSEL_LFRCO: + { + frequency = BOARD_LFRCO_FREQUENCY; + efm32_enable_lfrco(); + } + break; + + case _CMU_CMD_HFCLKSEL_LFXO: + { + frequency = BOARD_LFXO_FREQUENCY; + efm32_enable_lfxo(); + } + break; + + case _CMU_CMD_HFCLKSEL_HFRCO: + { + frequency = BOARD_HFRCO_FREQUENCY; + efm32_enable_hfrco(); + } + break; + + case _CMU_CMD_HFCLKSEL_HFXO: + { + frequency = BOARD_HFXO_FREQUENCY; + +#ifdef CMU_CTRL_HFLE +#if BOARD_HFXO_FREQUENCY > CMU_MAX_FREQ_HFLE + /* Adjust HFXO buffer current for high crystal frequencies, enable HFLE + * for frequencies above CMU_MAX_FREQ_HFLE. + * + * We must also have HFLE enabled to access some LE peripherals >= 32MHz. + */ + + regval = getreg32(EFM32_CMU_CTRL); + regval &= ~_CMU_CTRL_HFXOBUFCUR_MASK; + regval |= CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ | CMU_CTRL_HFLE; + putreg32(regval, EFM32_CMU_CTRL); + + /* Set DIV4 factor for peripheral clock if HFCORE clock for LE is + * enabled. + */ + + if ((getreg32(EFM32_CMU_HFCORECLKEN0) & CMU_HFCORECLKEN0_LE) != 0) + { + regval = getreg32(EFM32_CMU_HFCORECLKDIV); + regval |= CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4; + putreg32(regval, EFM32_CMU_HFCORECLKDIV); + } +#else + /* No boost... no HFLE */ + + regval = getreg32(EFM32_CMU_CTRL); + regval &= ~(_CMU_CTRL_HFXOBUFCUR_MASK | CMU_CTRL_HFLE); + regval |= CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ; + putreg32(regval, EFM32_CMU_CTRL); +#endif +#endif + /* Enable the HFXO */ + + efm32_enable_hfxo(); + } + break; + +#ifdef CONFIG_DEBUG + default: + PANIC(); +#endif + } + + /* Set the maximum number of FLASH wait states before selecting the new + * HFCLK source. + */ + + efm32_maxwaitstates(); + + /* Switch to selected oscillator */ + + putreg32(hfclksel << _CMU_CMD_HFCLKSEL_SHIFT, EFM32_CMU_CMD); + + /* Now select the optimal number of FLASH wait states */ + + efm32_setwaitstates(frequency); + return frequency; +} + +/**************************************************************************** + * Name: efm32_hfcoreclk_config + * + * Description: + * Configure the High Frequency Core Clock, HFCORECLK. + * + * HFCORECLK is a prescaled version of HFCLK. This clock drives the Core + * Modules, which consists of the CPU and modules that are tightly coupled + * to the CPU, e.g. MSC, DMA etc. This also includes the interface to the + * Low Energy Peripherals. Some of the modules that are driven by this + * clock can be clock gated completely when not in use. This is done by + * clearing the clock enable bit for the specific module in + * CMU_HFCORECLKEN0. The frequency of HFCORECLK is set using the + * CMU_HFCORECLKDIV register. The setting can be changed dynamically and + * the new setting takes effect immediately. + * + * The USB Core clock (USBC) is always undivided regardless of the + * HFCLKDIV setting. When the USB Core is active this clock must be + * switched to a 32 kHz clock (LFRCO or LFXO) when entering EM2. The USB + * Core uses this clock for monitoring the USB bus. The switch is done by + * writing USBCCLKSEL in CMU_CMD. The currently active clock can be + * checked by reading CMU_STATUS. The clock switch can take up to 1.5 32 + * kHz cycle (45 us). To avoid polling the clock selection status when + * switching switching from 32 kHz to HFCLK when coming up from EM2 the + * USBCHFCLKSEL interrupt can be used. EM3 is not supported when the USB + * is active. + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_LECLOCK +uint32_t efm32_coreleclk_config(int frequency) +{ +#ifdef CMU_CTRL_HFLE + uint32_t regval; + + /* Check if the core frequency is higher than CMU_MAX_FREQ_HFLE */ + + if (frequency > CMU_MAX_FREQ_HFLE) + { + /* Enable HFLE */ + + regval = getreg32(EFM32_CMU_CTRL); + regval |= CMU_CTRL_HFLE; + putreg32(regval, EFM32_CMU_CTRL); + + /* Enable DIV4 factor for peripheral clock */ + + regval = getreg32(EFM32_CMU_HFCORECLKDIV); + regval |= CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4; + putreg32(regval, EFM32_CMU_HFCORECLKDIV); + frequency /= 4; + } +#else + frequency /= 2; +#endif + + /* Enable core clocking to the LE */ + + efm32_enable_leclocking(); + + return frequency; +} +#else +# define efm32_coreleclk_config 0 +#endif + +/**************************************************************************** + * Name: efm32_hfcoreclk_config + * + * Description: + * Configure the High Frequency Core Clock, HFCORECLK. + * + * HFCORECLK is a prescaled version of HFCLK. This clock drives the Core + * Modules, which consists of the CPU and modules that are tightly coupled + * to the CPU, e.g. MSC, DMA etc. This also includes the interface to the + * Low Energy Peripherals. Some of the modules that are driven by this + * clock can be clock gated completely when not in use. This is done by + * clearing the clock enable bit for the specific module in + * CMU_HFCORECLKEN0. The frequency of HFCORECLK is set using the + * CMU_HFCORECLKDIV register. The setting can be changed dynamically and + * the new setting takes effect immediately. + * + * The USB Core clock (USBC) is always undivided regardless of the + * HFCLKDIV setting. When the USB Core is active this clock must be + * switched to a 32 kHz clock (LFRCO or LFXO) when entering EM2. The USB + * Core uses this clock for monitoring the USB bus. The switch is done by + * writing USBCCLKSEL in CMU_CMD. The currently active clock can be + * checked by reading CMU_STATUS. The clock switch can take up to 1.5 32 + * kHz cycle (45 us). To avoid polling the clock selection status when + * switching switching from 32 kHz to HFCLK when coming up from EM2 the + * USBCHFCLKSEL interrupt can be used. EM3 is not supported when the USB + * is active. + * + ****************************************************************************/ + +static inline uint32_t efm32_hfcoreclk_config(uint32_t hfcoreclkdiv, + uint32_t hfclk) +{ + /* REVISIT: Divider not currently used */ + return hfclk; +} + +/**************************************************************************** + * Name: efm32_hfperclk_config + * + * Description: + * Configure the High Frequency Peripheral Clock, HFPERCLK. + * + * Like HFCORECLK, HFPERCLK can also be a prescaled version of HFCLK. This + * clock drives the High-Frequency Peripherals. All the peripherals that + * are driven by this clock can be clock gated completely when not in use. + * This is done by clearing the clock enable bit for the specific + * peripheral in CMU_HFPERCLKEN0. The frequency of HFPERCLK is set using + * the CMU_HFPERCLKDIV register. The setting can be changed dynamically + * and the new setting takes effect immediately. + * + ****************************************************************************/ + +static inline uint32_t efm32_hfperclk_config(uint32_t hfperclkdiv, + uint32_t hfclk) +{ + uint32_t regval; + unsigned int divider; + + DEBUGASSERT(hfperclkdiv <= _CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512); + + /* Set the divider and enable the HFPERCLK */ + + regval = (hfperclkdiv << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT) | + CMU_HFPERCLKDIV_HFPERCLKEN; + putreg32(regval, EFM32_CMU_HFPERCLKDIV); + + /* The value of hfperclkdiv is log2 of the arithmetic divisor: + * 0->1, 1->2, 2->4, 3->8, ... 9->512. + */ + + divider = 1 << hfperclkdiv; + return hfclk / divider; +} + +/**************************************************************************** + * Name: efm32_lfaclk_config + * + * Description: + * Configure the Low Frequency A Clock, LFACLK. + * + * LFACLK is the selected clock for the Low Energy A Peripherals. There + * are four selectable sources for LFACLK: LFRCO, LFXO, HFCORECLK/2 and + * ULFRCO. In addition, the LFACLK can be disabled. From reset, the + * LFACLK source is set to LFRCO. However, note that the LFRCO is disabled + * from reset. The selection is configured using the LFA field in + * CMU_LFCLKSEL. The HFCORECLK/2 setting allows the Low Energy A + * Peripherals to be used as high-frequency peripherals. + * + * Each Low Energy Peripheral that is clocked by LFACLK has its own + * prescaler setting and enable bit. The prescaler settings are configured + * using CMU_LFAPRESC0 and the clock enable bits can be found in + * CMU_LFACLKEN0. Notice that the LCD has an additional high resolution + * prescaler for Frame Rate Control, configured by FDIV in CMU_LCDCTRL. + * When operating in oversampling mode, the pulse counters are clocked by + * LFACLK. This is configured for each pulse counter (n) individually by + * setting PCNTnCLKSEL in CMU_PCNTCTRL. + * + ****************************************************************************/ + +static inline uint32_t efm32_lfaclk_config(uint32_t lfaclksel, bool ulfrco, + uint32_t hfcoreclk) +{ + uint32_t lfaclk; + uint32_t regval; + + /* ULFRCO is a special case */ + + if (ulfrco) + { + /* ULFRCO is always enabled */ + + lfaclksel = _CMU_LFCLKSEL_LFA_DISABLED; + lfaclk = BOARD_ULFRCO_FREQUNCY; + } + else + { + /* Enable the oscillator source */ + + switch (lfaclksel) + { + default: + case _CMU_LFCLKSEL_LFA_DISABLED: + { + lfaclk = 0; + } + break; + + case CMU_LFCLKSEL_LFA_LFRCO: + { + efm32_enable_lfrco(); + lfaclk = BOARD_LFRCO_FREQUENCY; + } + break; + + case _CMU_LFCLKSEL_LFA_LFXO: + { + efm32_enable_lfxo(); + lfaclk = BOARD_LFXO_FREQUENCY; + } + break; + + case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2: + { + lfaclk = hfcoreclk >> 1; + } + break; + } + } + + /* Enable the LFA clock in the LFCLKSEL register */ + + regval = getreg32(EFM32_CMU_LFCLKSEL); + +#ifdef CMU_LFCLKSEL_LFAE + regval &= ~_CMU_LFCLKSEL_LFAE_MASK; +#endif + + regval &= ~_CMU_LFCLKSEL_LFA_MASK; + regval |= (lfaclksel << _CMU_LFCLKSEL_LFA_SHIFT); + +#ifdef CMU_LFCLKSEL_LFAE_ULFRCO + regval |= ((uint32_t)ulfrco << _CMU_LFCLKSEL_LFAE_SHIFT); +#endif + + putreg32(regval, EFM32_CMU_LFCLKSEL); + + return lfaclk; +} + +/**************************************************************************** + * Name: efm32_lfbclk_config + * + * Description: + * Configure the Low Frequency B Clock, LFBCLK. + * + * LFBCLK is the selected clock for the Low Energy B Peripherals. There + * are four selectable sources for LFBCLK: LFRCO, LFXO, HFCORECLK/2 and + * ULFRCO. In addition, the LFBCLK can be disabled. From reset, the LFBCLK + * source is set to LFRCO. However, note that the LFRCO is disabled from + * reset. The selection is configured using the LFB field in CMU_LFCLKSEL. + * The HFCORECLK/2 setting allows the Low Energy B Peripherals to be used + * as high-frequency peripherals. + * + * Each Low Energy Peripheral that is clocked by LFBCLK has its own + * prescaler setting and enable bit. The prescaler settings are + * configured using CMU_LFBPRESC0 and the clock enable bits can be found + * in CMU_LFBCLKEN0. + * + ****************************************************************************/ + +static inline uint32_t efm32_lfbclk_config(uint32_t lfbclksel, bool ulfrco, + uint32_t hfcoreclk) +{ + uint32_t lfbclk; + uint32_t regval; + + /* ULFRCO is a special case */ + + if (ulfrco) + { + /* ULFRCO is always enabled */ + + lfbclksel = _CMU_LFCLKSEL_LFB_DISABLED; + lfbclk = BOARD_ULFRCO_FREQUNCY; + } + else + { + /* Enable the oscillator source */ + + switch (lfbclksel) + { + default: + case _CMU_LFCLKSEL_LFB_DISABLED: + { + lfbclk = 0; + } + break; + + case CMU_LFCLKSEL_LFB_LFRCO: + { + efm32_enable_lfrco(); + } + break; + + case _CMU_LFCLKSEL_LFB_LFXO: + { + efm32_enable_lfxo(); + lfbclk = BOARD_LFXO_FREQUENCY; + } + break; + + case _CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2: + { + lfbclk = hfcoreclk >> 1; + } + break; + } + } + + /* Enable the LFB clock in the LFCLKSEL register */ + + regval = getreg32(EFM32_CMU_LFCLKSEL); + +#ifdef CMU_LFCLKSEL_LFBE + regval &= ~_CMU_LFCLKSEL_LFBE_MASK; +#endif + + regval &= ~_CMU_LFCLKSEL_LFB_MASK; + regval |= (lfbclksel << _CMU_LFCLKSEL_LFB_SHIFT); + +#ifdef CMU_LFCLKSEL_LFBE_ULFRCO + regval |= ((uint32_t)ulfrco << _CMU_LFCLKSEL_LFBE_SHIFT); +#endif + + putreg32(regval, EFM32_CMU_LFCLKSEL); + + return lfbclk; +} + +/**************************************************************************** + * Name: efm32_pcntclk_config + * + * Description: + * Configure the Pulse Counter n Clock, PCNTnCLK. + * + * Each available pulse counter is driven by its own clock, PCNTnCLK where + * n is the pulse counter instance number. Each pulse counter can be + * configured to use an external pin (PCNTn_S0) or LFACLK as PCNTnCLK. + * + ****************************************************************************/ + +static inline void efm32_pcntclk_config(void) +{ + /* REVISIT: Not yet implemented */ +} + +/**************************************************************************** + * Name: efm32_wdogclk_config + * + * Description: + * Configure the Watchdog Timer Clock, WDOGCLK. + * + * The Watchdog Timer (WDOG) can be configured to use one of three + * different clock sources: LFRCO, LFXO or ULFRCO. ULFRCO (Ultra Low + * Frequency RC Oscillator) is a separate 1 kHz RC oscillator that also + * runs in EM3. + * + ****************************************************************************/ + +static inline void efm32_wdogclk_config(void) +{ + /* REVISIT: Not yet implemented */ +} + +/**************************************************************************** + * Name: efm32_auxclk_config + * + * Description: + * Configure the Auxiliary Clock, AUXCLK. + * + * AUXCLK is a 1-28 MHz clock driven by a separate RC oscillator, AUXHFRCO. + * This clock is used for flash programming, and Serial Wire Output (SWO), + * and LESENSE operation. During flash programming, or if needed by + * LESENSE, this clock will be active. If the AUXHFRCO has not been + * enabled explicitly by software, the MSC or LESENSE module will + * automatically start and stop it. The AUXHFRCO is enabled by writing a 1 + * to AUXHFRCOEN in CMU_OSCENCMD. This explicit enabling is required when + * SWO is used. + * + ****************************************************************************/ + +static inline void efm32_auxclk_config(void) +{ + /* REVISIT: Not yet implemented */ +} + +/**************************************************************************** + * Name: efm32_gpioclock + * + * Description: + * Enable clocking to the GPIO + * + ****************************************************************************/ + +static inline void efm32_gpioclock(void) +{ + uint32_t regval; + + /* Enable clocking to the GPIO be setting the GPIO bit in the High + * Frequency Peripheral Clock Enable. + */ + + regval = getreg32(EFM32_CMU_HFPERCLKEN0); + regval |= CMU_HFPERCLKEN0_GPIO; + putreg32(regval, EFM32_CMU_HFPERCLKEN0); +} + +/**************************************************************************** + * Name: efm32_itm_syslog + * + * Description: + * Enable Serial wire output pin, configure debug clocking, and enable + * ITM syslog support. + * + ****************************************************************************/ + +#if defined(CONFIG_SYSLOG) || defined(CONFIG_ARMV7M_ITMSYSLOG) +static inline void efm32_itm_syslog(void) +{ + int regval; + + /* Enable Serial wire output pin + * + * Set location and enable output on the pin. All pin configuration + * information must be provided in the board.h header file. + */ + + regval = getreg32(EFM32_GPIO_ROUTE); + regval &= ~_GPIO_ROUTE_SWLOCATION_MASK; + regval |= GPIO_ROUTE_SWOPEN; + regval |= ((uint32_t)BOARD_SWOPORT_LOCATION << _GPIO_ROUTE_SWLOCATION_SHIFT); + putreg32(regval, EFM32_GPIO_ROUTE); + + /* Enable output on pin */ + + efm32_configgpio(BOARD_GPIO_SWOPORT); + + /* Enable debug clock AUXHFRCO */ + + efm32_enable_auxhfrco(); + + /* Then perform ARMv7-M ITM SYSLOG initialization */ + + itm_syslog_initialize(); +} +#else +# define efm32_itm_syslog() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_clockconfig + * + * Description: + * Called to initialize the EFM32 chip. This does whatever setup is + * needed to put the MCU in a usable state. This includes the + * initialization of clocking using the settings in board.h. + * + ****************************************************************************/ + +void efm32_clockconfig(void) +{ + uint32_t hfclk; + uint32_t hfcoreclk; + uint32_t hfperclk; + uint32_t coreleclk; + uint32_t lfaclk; + uint32_t lfbclk; + + /* Enable clocks and set dividers as determined by the board.h header file */ + + hfclk = efm32_hfclk_config(BOARD_HFCLKSEL, BOARD_HFCLKDIV); + hfcoreclk = efm32_hfcoreclk_config(BOARD_HFCORECLKDIV, hfclk); + hfperclk = efm32_hfperclk_config(BOARD_HFPERCLKDIV, hfclk); + coreleclk = efm32_coreleclk_config(hfclk); + lfaclk = efm32_lfaclk_config(BOARD_LFACLKSEL, BOARD_LFA_ULFCO_ENABLE, hfcoreclk); + lfbclk = efm32_lfbclk_config(BOARD_LFBCLKSEL, BOARD_LFB_ULFCO_ENABLE, hfcoreclk); + + efm32_pcntclk_config(); + efm32_wdogclk_config(); + efm32_auxclk_config(); + + UNUSED(hfperclk); + UNUSED(coreleclk); + UNUSED(lfaclk); + UNUSED(lfbclk); + + /* Enable clocking of the GPIO ports */ + + efm32_gpioclock(); + + /* Enable Serial wire output pin, configure debug clocking, and enable ITM + * syslog support. + */ + + efm32_itm_syslog(); +} diff --git a/arch/arm/src/efm32/efm32_clockconfig.h b/arch/arm/src/efm32/efm32_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..64e2bf56bea1160038a49b1a7dde0d937b3b7917 --- /dev/null +++ b/arch/arm/src/efm32/efm32_clockconfig.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_clockconfig.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_EFM32_EFM32_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_clockconfig + * + * Description: + * Called to initialize the EFM32. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void efm32_clockconfig(void); + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_CLOCKCONFIG_H */ diff --git a/arch/arm/src/efm32/efm32_config.h b/arch/arm/src/efm32/efm32_config.h new file mode 100644 index 0000000000000000000000000000000000000000..b60c3a60e4dcb267198c7bd710df888e5c5937fe --- /dev/null +++ b/arch/arm/src/efm32/efm32_config.h @@ -0,0 +1,236 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_config.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_CONFIG_H +#define __ARCH_ARM_SRC_EFM32_EFM32_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Make sure that the configuration does not enable UARTs that the MCU does + * not have. + */ + +#ifndef CONFIG_EFM32_HAVE_USART2 +# undef CONFIG_EFM32_USART2 +#endif + +#ifndef CONFIG_EFM32_HAVE_UART0 +# undef CONFIG_EFM32_UART0 +#endif + +#ifndef CONFIG_EFM32_HAVE_UART1 +# undef CONFIG_EFM32_UART1 +#endif + +#ifndef CONFIG_EFM32_HAVE_LEUART1 +# undef CONFIG_EFM32_LEUART1 +#endif + +/* Is there a UART device? Or an SPI device? */ + +#ifndef CONFIG_EFM32_USART_ISUART +# undef CONFIG_EFM32_USART0_ISUART +# undef CONFIG_EFM32_USART1_ISUART +# undef CONFIG_EFM32_USART2_ISUART +#endif + +#ifndef CONFIG_EFM32_UART +# undef CONFIG_EFM32_UART0 +# undef CONFIG_EFM32_UART1 +#endif + +#ifndef CONFIG_EFM32_USART0 +# undef CONFIG_EFM32_USART0_ISUART +# undef CONFIG_EFM32_USART0_ISSPI +#endif + +#ifndef CONFIG_EFM32_USART1 +# undef CONFIG_EFM32_USART1_ISUART +# undef CONFIG_EFM32_USART1_ISSPI +#endif + +#ifndef CONFIG_EFM32_USART2 +# undef CONFIG_EFM32_USART2_ISUART +# undef CONFIG_EFM32_USART2_ISSPI +#endif + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_EFM32_USART0_ISUART) || \ + defined(CONFIG_EFM32_USART1_ISUART) || \ + defined(CONFIG_EFM32_USART2_ISUART) || \ + defined(CONFIG_EFM32_UART0) || \ + defined(CONFIG_EFM32_UART1) +# define HAVE_UART_DEVICE 1 +#endif + +#undef HAVE_SPI_DEVICE +#if defined(CONFIG_EFM32_USART0_ISSPI) || \ + defined(CONFIG_EFM32_USART1_ISSPI) || \ + defined(CONFIG_EFM32_USART2_ISSPI) +# define HAVE_SPI_DEVICE 1 +#endif + +/* Is there an LEUART device? */ + +#ifndef CONFIG_EFM32_LEUART +# undef CONFIG_EFM32_LEUART0 +# undef CONFIG_EFM32_LEUART1 +#endif + +#undef HAVE_LEUART_DEVICE +#if defined(CONFIG_EFM32_LEUART0) || defined(CONFIG_EFM32_LEUART1) +# define HAVE_LEUART_DEVICE 1 +#endif + +/* Is there a serial console? (Low energy UARTs not yet supported) */ + +#undef HAVE_UART_CONSOLE +#undef HAVE_LEUART_CONSOLE + +#if defined(CONFIG_SYSLOG_CONSOLE) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +#else +# if defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_EFM32_USART0_ISUART) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_EFM32_USART1_ISUART) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_EFM32_USART2_ISUART) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_EFM32_UART0) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_EFM32_UART1) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_LEUART0_SERIAL_CONSOLE) && defined(CONFIG_EFM32_LEUART0) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# define HAVE_LEUART_CONSOLE 1 +# elif defined(CONFIG_LEUART1_SERIAL_CONSOLE) && defined(CONFIG_EFM32_LEUART1) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# define HAVE_LEUART_CONSOLE 1 +# else +# ifdef CONFIG_DEV_CONSOLE +# warning "No valid CONFIG_U[S]ART[n]_SERIAL_CONSOLE Setting" +# endif +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_LEUART0_SERIAL_CONSOLE +# undef CONFIG_LEUART1_SERIAL_CONSOLE +# endif +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_CONFIG_H */ diff --git a/arch/arm/src/efm32/efm32_dma.c b/arch/arm/src/efm32/efm32_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..a96bc160c0de6a072f6d9b4e3227ff576f5eec97 --- /dev/null +++ b/arch/arm/src/efm32/efm32_dma.c @@ -0,0 +1,832 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_dma.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/efm32_cmu.h" +#include "chip/efm32_dma.h" +#include "efm32_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALIGN_MASK(s) ((1 << s) - 1) +#define ALIGN_DOWN(v,m) ((v) & ~m) +#define ALIGN_UP(v,m) (((v) + (m)) & ~m) + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This structure describes one DMA channel */ + +struct dma_channel_s +{ + uint8_t chan; /* DMA channel number (0-EFM32_DMA_NCHANNELS) */ + bool inuse; /* TRUE: The DMA channel is in use */ + dma_config_t config; /* Current configuration */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/* This structure describes the state of the DMA controller */ + +struct dma_controller_s +{ + sem_t exclsem; /* Protects channel table */ + sem_t chansem; /* Count of free channels */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the overall state of the DMA controller */ + +static struct dma_controller_s g_dmac; + +/* This is the array of all DMA channels */ + +static struct dma_channel_s g_dmach[EFM32_DMA_NCHANNELS]; + +/* This array describes the available channel control data structures. Each + * structure must be aligned to a 256 address boundary. The last 8 or 9 + * bits of address are provided by the DMA controller: + * + * 8-Channels: + * Bit 7: Selects the alternate descriptor list + * Bits 4-6: The DMA channel (0-7) + * Bits 2-3: Selects the descriptor field + * Bits 0-1: Always zero + * + * 12-Channels: + * Bit 8: Selects the alternate descriptor list + * Bits 4-7: The DMA channel (0-11) + * Bits 2-3: Selects the descriptor field + * Bits 0-1: Always zero + */ + +#if EFM32_DMA_NCHANNELS <= 8 +# define DESC_TABLE_SIZE 8 +# define DESC_TABLE_ALIGN 256 /* 2*8*16 */ +#elif EFM32_DMA_NCHANNELS <= 16 +# define DESC_TABLE_SIZE 16 +# define DESC_TABLE_ALIGN 512 /* 2*16*16 */ +#else +# error Unknown descriptor table size +#endif + +#ifdef CONFIG_EFM32_DMA_ALTDSEC +static struct dma_descriptor_s g_descriptors[DESC_TABLE_SIZE + EFM32_DMA_NCHANNELS] + __attribute__((aligned(DESC_TABLE_ALIGN))); +#else +static struct dma_descriptor_s g_descriptors[EFM32_DMA_NCHANNELS] + __attribute__((aligned(DESC_TABLE_ALIGN))); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_set_chctrl + * + * Description: + * Set the channel control register + * + ****************************************************************************/ + +static void efm32_set_chctrl(struct dma_channel_s *dmach, dma_config_t config) +{ + uintptr_t regaddr; + uint32_t decoded; + uint32_t regval; + + decoded = (uint32_t)(config & EFM32_DMA_SIGSEL_MASK) >> EFM32_DMA_SIGSEL_SHIFT; + regval = (decoded << _DMA_CH_CTRL_SIGSEL_SHIFT); + decoded = (uint32_t)(config & EFM32_DMA_SOURCSEL_MASK) >> EFM32_DMA_SOURCSEL_SHIFT; + regval |= (decoded << _DMA_CH_CTRL_SOURCESEL_SHIFT); + + regaddr = EFM32_DMA_CHn_CTRL(dmach->chan); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: efm32_align_shift + * + * Description: + * Set the channel control register + * + ****************************************************************************/ + +static inline unsigned int efm32_align_shift(dma_config_t config) +{ + unsigned int shift; + + shift = (config & EFM32_DMA_XFERSIZE_MASK) >> EFM32_DMA_XFERSIZE_SHIFT; + DEBUGASSERT(shift != 3); + return shift; +} + +/**************************************************************************** + * Name: efm32_get_descriptor + * + * Description: + * Get the address of the primary or alternate descriptor assigned to the + * DMA channel + * + ****************************************************************************/ + +static inline struct dma_descriptor_s * +efm32_get_descriptor(struct dma_channel_s *dmach, bool alt) +{ + uintptr_t base = alt ? getreg32(EFM32_DMA_ALTCTRLBASE) : + getreg32(EFM32_DMA_CTRLBASE); + return ((struct dma_descriptor_s *)base) + dmach->chan; +} + +/**************************************************************************** + * Name: efm32_dmac_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int efm32_dmac_interrupt(int irq, void *context) +{ + struct dma_channel_s *dmach; + unsigned int chndx; + uint32_t pending; + uint32_t bit; + + /* Get the set of pending, unmasked global XDMAC interrupts */ + + pending = getreg32(EFM32_DMA_IF) & getreg32(EFM32_DMA_IEN); + putreg32(pending, EFM32_DMA_IFC); + + /* Check each bit to see which channel(s) have interrupted */ + + for (chndx = 0; chndx < EFM32_DMA_NCHANNELS && pending != 0; chndx++) + { + /* Are any interrupts pending for this channel? */ + + bit = 1 << chndx; + if ((pending & bit) != 0) + { + dmach = &g_dmach[chndx]; + + /* Put the DMA channel in the stopped state */ + + efm32_dmastop((DMA_HANDLE)dmach); + + /* Call the DMA completion callback */ + + if (dmach->callback) + { + dmach->callback((DMA_HANDLE)dmach, OK, dmach->arg); + dmach->callback = NULL; + } + + dmach->arg = NULL; + + /* Clear the bit in the sampled set of pending interrupts */ + + pending &= !bit; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + uint32_t regval; + int i; + + dmallvdbg("Initialize XDMAC0\n"); + + /* Initialize the channel list */ + + sem_init(&g_dmac.exclsem, 0, 1); + sem_init(&g_dmac.chansem, 0, EFM32_DMA_NCHANNELS); + + for (i = 0; i < EFM32_DMA_NCHANNELS; i++) + { + g_dmach[i].chan = i; + } + + /* Enable clocking to the DMA module. DMA is clocked by HFCORECLK. */ + + regval = getreg32(EFM32_CMU_HFCORECLKEN0); + regval |= CMU_HFCORECLKEN0_DMA; + putreg32(regval, EFM32_CMU_HFCORECLKEN0); + + /* Set the control base addresses. Note: EFM32_DMA_ALTCTRLBASE + * is a read-only register that provides the location where hardware + * will obtain the alternative descriptors. + */ + + putreg32((uint32_t)g_descriptors, EFM32_DMA_CTRLBASE); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(EFM32_IRQ_DMA, efm32_dmac_interrupt); + + /* Enable the DMA controller */ + + putreg32(DMA_CONFIG_EN, EFM32_DMA_CONFIG); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(EFM32_IRQ_DMA); +} + +/**************************************************************************** + * Name: efm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to a DMA channel. + * + * If no DMA channel is available, then efm32_dmachannel() will wait + * until the holder of a channel relinquishes the channel by calling + * efm32_dmafree(). + * + * Input parameters: + * None + * + * Returned Value: + * This function ALWAYS returns a non-NULL, void* DMA channel handle. + * + * Assumptions: + * - The caller can wait for a DMA channel to be freed if it is not + * available. + * + ****************************************************************************/ + +DMA_HANDLE efm32_dmachannel(void) +{ + struct dma_channel_s *dmach; + unsigned int chndx; + uint32_t bit; + + /* Take a count from from the channel counting semaphore. We may block + * if there are no free channels. When we get the count, then we can + * be assured that a channel is available in the channel list and is + * reserved for us. + */ + + while (sem_wait(&g_dmac.chansem) < 0) + { + /* sem_wait should fail only if it is awakened by a a signal */ + + DEBUGASSERT(errno == EINTR); + } + + /* Get exclusive access to the DMA channel list */ + + while (sem_wait(&g_dmac.exclsem) < 0) + { + /* sem_wait should fail only if it is awakened by a a signal */ + + DEBUGASSERT(errno == EINTR); + } + + /* Search for an available DMA channel */ + + for (chndx = 0, dmach = NULL; chndx < EFM32_DMA_NCHANNELS; chndx++) + { + struct dma_channel_s *candidate = &g_dmach[chndx]; + if (!candidate->inuse) + { + dmach = candidate; + dmach->inuse = true; + + /* Clear any pending channel interrupts */ + + bit = 1 << chndx; + putreg32(bit, EFM32_DMA_IFC); + + /* Disable the channel */ + + putreg32(bit, EFM32_DMA_CHENC); + break; + } + } + + sem_post(&g_dmac.exclsem); + + /* Since we have reserved a DMA descriptor by taking a count from chansem, + * it would be a serious logic failure if we could not find a free channel + * for our use. + */ + + DEBUGASSERT(dmach); + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: efm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to efm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until efm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void efm32_dmafree(DMA_HANDLE handle) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + dmavdbg("DMA channel %d\n", dmach->chan); + + /* Disable the channel */ + + putreg32(1 << dmach->chan, EFM32_DMA_CHENC); + + /* Mark the channel no longer in use. Clearing the in-use flag is an atomic + * operation and so should be safe. + */ + + dmach->inuse = false; + + /* And increment the count of free channels... possibly waking up a + * thread that may be waiting for a channel. + */ + + sem_post(&g_dmac.chansem); +} + +/**************************************************************************** + * Name: efm32_rxdmasetup + * + * Description: + * Configure an RX (peripheral-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (source) + * maddr - Memory address (destination) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void efm32_rxdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + struct dma_descriptor_s *desc; + unsigned int xfersize; + unsigned int shift; + uint32_t regval; + uint32_t incr; + uint32_t mask; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + + /* Get the properly alignment shift and mask */ + + shift = efm32_align_shift(config); + mask = ALIGN_MASK(shift); + + /* Make sure that the number of bytes we are asked to transfer is a multiple + * of the transfer size. + */ + + xfersize = (1 << shift); + nbytes = ALIGN_DOWN(nbytes, mask); + DEBUGASSERT(nbytes > 0); + + /* Save the configuration (for efm32_dmastart()). */ + + dmach->config = config; + + /* Configure for the selected peripheral */ + + efm32_set_chctrl(dmach, config); + + /* Configure the primary channel descriptor */ + + desc = efm32_get_descriptor(dmach, false); + desc->srcend = (uint32_t *)paddr; + desc->dstend = (uint32_t *)(maddr + nbytes - xfersize); + + /* No source increment, destination increments according to transfer size. + * No privileges. Arbitrate after each transfer. Default priority. + */ + + regval = DMA_CTRL_SRC_INC_NONE | DMA_CTRL_DST_PROT_NON_PRIVILEGED | + DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_1 | + (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) | _DMA_CTRL_CYCLE_CTRL_BASIC; + + switch (shift) + { + default: + case 0: /* Byte transfer */ + regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE; + incr = DMA_CTRL_DST_INC_BYTE; + break; + + case 1: /* Half word transfer */ + regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD; + incr = DMA_CTRL_DST_INC_HALFWORD; + break; + + case 2: /* Word transfer */ + regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD; + incr = DMA_CTRL_DST_INC_WORD; + break; + } + + /* Do we need to increment the memory address? */ + + if ((config & EFM32_DMA_MEMINCR_MASK) == EFM32_DMA_MEMINCR) + { + regval |= incr; + } + + /* Set the number of transfers (minus 1) */ + + DEBUGASSERT((nbytes >> shift) < 1024); + regval |= ((nbytes >> shift) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT; + desc->ctrl = regval; + desc->user = 0; +} + +/**************************************************************************** + * Name: efm32_txdmasetup + * + * Description: + * Configure an TX (memory-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (destination) + * maddr - Memory address (source) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ****************************************************************************/ + +void efm32_txdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + struct dma_descriptor_s *desc; + unsigned int xfersize; + unsigned int shift; + uint32_t regval; + uint32_t incr; + uint32_t mask; + + DEBUGASSERT(dmach != NULL && dmach->inuse); + + /* Get the properly alignment shift and mask */ + + shift = efm32_align_shift(config); + mask = ALIGN_MASK(shift); + + /* Make sure that the number of bytes we are asked to transfer is a multiple + * of the transfer size. + */ + + xfersize = (1 << shift); + nbytes = ALIGN_DOWN(nbytes, mask); + DEBUGASSERT(nbytes > 0); + + /* Save the configuration (for efm32_dmastart()). */ + + dmach->config = config; + + /* Configure for the selected peripheral */ + + efm32_set_chctrl(dmach, config); + + /* Configure the primary channel descriptor */ + + desc = efm32_get_descriptor(dmach, false); + desc->srcend = (uint32_t *)(maddr + nbytes - xfersize); + desc->dstend = (uint32_t *)paddr; + + /* No destination increment, source increments according to transfer size. + * No privileges. Arbitrate after each transfer. Default priority. + */ + + regval = DMA_CTRL_DST_INC_NONE | DMA_CTRL_DST_PROT_NON_PRIVILEGED | + DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_1 | + (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) | _DMA_CTRL_CYCLE_CTRL_BASIC; + + switch (shift) + { + default: + case 0: /* Byte transfer */ + regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE; + incr = DMA_CTRL_SRC_INC_BYTE; + break; + + case 1: /* Half word transfer */ + regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD; + incr = DMA_CTRL_SRC_INC_HALFWORD; + break; + + case 2: /* Word transfer */ + regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD; + incr = DMA_CTRL_SRC_INC_WORD; + break; + } + + /* Do we need to increment the memory address? */ + + if ((config & EFM32_DMA_MEMINCR_MASK) == EFM32_DMA_MEMINCR) + { + regval |= incr; + } + + /* Set the number of transfers (minus 1) */ + + DEBUGASSERT((nbytes >> shift) < 1024); + regval |= ((nbytes >> shift) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT; + desc->ctrl = regval; + desc->user = 0; +} + +/**************************************************************************** + * Name: efm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + irqstate_t flags; + uint32_t regval; + uint32_t bit; + + DEBUGASSERT(dmach && dmach->inuse && dmach->desc); + + /* Save the DMA complete callback info */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Finish configuring the channel */ + + bit = 1 << dmach->chan; + if ((dmach->config & EFM32_DMA_SINGLE_MASK) == EFM32_DMA_BUFFER_FULL) + { + /* Disable the single requests for the channel (i.e. do not react to data + * available, wait for buffer full) + */ + + putreg32(bit, EFM32_DMA_CHUSEBURSTS); + + /* Enable buffer-full requests for the channel */ + + putreg32(bit, EFM32_DMA_CHREQMASKC); + } + else + { + /* Enable the single requests for the channel */ + + putreg32(bit, EFM32_DMA_CHUSEBURSTC); + + /* Disable buffer-full requests for the channel */ + + putreg32(bit, EFM32_DMA_CHREQMASKS); + } + + /* Use the primary data structure for the channel */ + + putreg32(bit, EFM32_DMA_CHALTC); + + /* Enable DMA completion interrupts */ + + flags = enter_critical_section(); + regval = getreg32(EFM32_DMA_IEN); + regval |= bit; + putreg32(regval, EFM32_DMA_IEN); + + /* Enable the channel */ + + putreg32(bit, EFM32_DMA_CHENS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_dmastop + * + * Description: + * Cancel the DMA. After efm32_dmastop() is called, the DMA channel is + * reset and efm32_dmasetup() must be called before efm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ****************************************************************************/ + +void efm32_dmastop(DMA_HANDLE handle) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + irqstate_t flags; + uint32_t regval; + uint32_t bit; + + DEBUGASSERT(dmach); + bit = 1 << dmach->chan; + + /* Disable the channel */ + + flags = enter_critical_section(); + putreg32(bit, EFM32_DMA_CHENC); + + /* Disable Channel interrupts */ + + regval = getreg32(EFM32_DMA_IEN); + regval |= bit; + putreg32(regval, EFM32_DMA_IEN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void efm32_dmasample(DMA_HANDLE handle, struct efm32_dmaregs_s *regs) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + uintptr_t regaddr; + irqstate_t flags; + + /* Sample DMA registers. */ + + flags = enter_critical_section(); + + regs->status = getreg32(EFM32_DMA_STATUS); + regs->ctrlbase = getreg32(EFM32_DMA_CTRLBASE); + regs->altctrlbase = getreg32(EFM32_DMA_ALTCTRLBASE); + regs->chwaitstatus = getreg32(EFM32_DMA_CHWAITSTATUS); + regs->chusebursts = getreg32(EFM32_DMA_CHUSEBURSTS); + regs->chreqmasks = getreg32(EFM32_DMA_CHREQMASKS); + regs->chens = getreg32(EFM32_DMA_CHENS); + regs->chalts = getreg32(EFM32_DMA_CHALTS); + regs->chpris = getreg32(EFM32_DMA_CHPRIS); + regs->errorc = getreg32(EFM32_DMA_ERRORC); + regs->chreqstatus = getreg32(EFM32_DMA_CHREQSTATUS); + regs->chsreqstatus = getreg32(EFM32_DMA_CHSREQSTATUS); + regs->ifr = getreg32(EFM32_DMA_IF); + regs->ien = getreg32(EFM32_DMA_IEN); +#if defined(CONFIG_EFM32_EFM32GG) + regs->ctrl = getreg32(EFM32_DMA_CTRL); + regs->rds = getreg32(EFM32_DMA_RDS); + regs->loop0 = getreg32(EFM32_DMA_LOOP0); + regs->loop1 = getreg32(EFM32_DMA_LOOP1); + regs->rect0 = getreg32(EFM32_DMA_RECT0); +#endif + + /* Sample channel control register */ + + regaddr = EFM32_DMA_CHn_CTRL(dmach->chan) + regs->chnctrl = getreg32(regaddr); + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: efm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void efm32_dmadump(DMA_HANDLE handle, const struct efm32_dmaregs_s *regs, + const char *msg) +{ + struct dma_channel_s *dmach = (struct dma_channel_s *)handle; + + dmadbg("%s\n", msg); + dmadbg(" DMA Registers:\n"); + dmadbg(" STATUS: %08x\n", regs->status); + dmadbg(" CTRLBASE: %08x\n", regs->ctrlbase); + dmadbg(" ALTCTRLBASE: %08x\n", regs->altctrlbase); + dmadbg(" CHWAITSTATUS: %08x\n", regs->chwaitstatus); + dmadbg(" CHUSEBURSTS: %08x\n", regs->chusebursts); + dmadbg(" CHREQMASKS: %08x\n", regs->chreqmasks); + dmadbg(" CHENS: %08x\n", regs->chens); + dmadbg(" CHALTS: %08x\n", regs->chalts); + dmadbg(" CHPRIS: %08x\n", regs->chpris); + dmadbg(" ERRORC: %08x\n", regs->errorc); + dmadbg(" CHREQSTATUS: %08x\n", regs->chreqstatus); + dmadbg(" CHSREQSTATUS: %08x\n", regs->chsreqstatus); + dmadbg(" IEN: %08x\n", regs->ien); +#if defined(CONFIG_EFM32_EFM32GG) + dmadbg(" CTRL: %08x\n", regs->ctrl); + dmadbg(" RDS: %08x\n", regs->rds); + dmadbg(" LOOP0: %08x\n", regs->loop0); + dmadbg(" LOOP1: %08x\n", regs->loop1); + dmadbg(" RECT0: %08x\n", regs->rect0); +#endif + dmadbg(" DMA Channel %d Registers:\n", dmach->chan); + dmadbg(" CHCTRL: %08x\n", regs->chnctrl); +} +#endif diff --git a/arch/arm/src/efm32/efm32_dma.h b/arch/arm/src/efm32/efm32_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..2cedb881f3822b3203365ba51a074c2747f0dfbb --- /dev/null +++ b/arch/arm/src/efm32/efm32_dma.h @@ -0,0 +1,315 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_dma.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_DMA_H +#define __ARCH_ARM_SRC_EFM32_EFM32_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include "chip.h" +#include "chip/efm32_dma.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bit encoded input parameter to efm32_channel(). These encodings must fit in the + * an unsigned integer of type dma_config_t. + * + * Current limitations/assumptions in the encoding: + * + * - RX transfers are peripheral to memory + * - TX transfers are memory to peripheral + * - Memory address is always incremented. + */ + +#define EFM32_DMA_SIGSEL_SHIFT (0) /* Bits 0-3: _DMA_CH_CTRL_ * value */ +#define EFM32_DMA_SIGSEL_MASK (15 << EFM32_DMA_SIGSEL_SHIFT) +# define EFM32_DMA_SIGSEL(n) ((dma_config_t)(n) << EFM32_DMA_SIGSEL_SHIFT) + +#define EFM32_DMA_SOURCSEL_SHIFT (4) /* Bits 4-9: _DMA_CH_SOURCESEL_* value */ +#define EFM32_DMA_SOURCSEL_MASK (63 << EFM32_DMA_SOURCSEL_SHIFT) +# define EFM32_DMA_SOURCSEL(n) ((dma_config_t)(n) << EFM32_DMA_SOURCSEL_SHIFT) + +#define EFM32_DMA_XFERSIZE_SHIFT (10) /* Bits 10-11: Transfer size */ +#define EFM32_DMA_XFERSIZE_MASK (3 << EFM32_DMA_XFERSIZE_SHIFT) +# define EFM32_DMA_XFERSIZE_BYTE (0 << EFM32_DMA_SOURCSEL_SHIFT) +# define EFM32_DMA_XFERSIZE_HWORD (1 << EFM32_DMA_SOURCSEL_SHIFT) +# define EFM32_DMA_XFERSIZE_WORD (2 << EFM32_DMA_SOURCSEL_SHIFT) + +#define EFM32_DMA_SINGLE_MASK (1 << 12) /* Bit 12: Single or Buffer full request */ +# define EFM32_DMA_SINGLE (1 << 12) /* 1=Buffer full request */ +# define EFM32_DMA_BUFFER_FULL (0) /* 0=Buffer full request */ + +#define EFM32_DMA_MEMINCR_MASK (1 << 13) /* Bit 13: Increment memory address */ +# define EFM32_DMA_MEMINCR (1 << 13) /* 1=Increment memory address */ +# define EFM32_DMA_NOINCR (0) /* 0=No memory address increment */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA + * channel. + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the the + * completion of the DMA. + * + * Input Parameters: + * handle - Refers tot he DMA channel or stream + * status - A bit encoded value that provides the completion status. See the + * DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when efm32_dmastart() was + * called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +#ifdef CONFIG_DEBUG_DMA +struct efm32_dmaregs_s +{ + uint32_t status; /* DMA Status Register */ + uint32_t ctrlbase; /* Channel Control Data Base Pointer Register */ + uint32_t altctrlbase; /* Channel Alternate Control Data Base Pointer Register */ + uint32_t chwaitstatus; /* Channel Wait on Request Status Register */ + uint32_t chusebursts; /* Channel Useburst Set Register */ + uint32_t chreqmasks; /* Channel Request Mask Set Register */ + uint32_t chens; /* Channel Enable Set Register */ + uint32_t chalts; /* Channel Alternate Set Register */ + uint32_t chpris; /* Channel Priority Set Register */ + uint32_t errorc; /* Bus Error Clear Register */ + uint32_t chreqstatus; /* Channel Request Status */ + uint32_t chsreqstatus; /* Channel Single Request Status */ + uint32_t ifr; /* Interrupt Flag Register */ + uint32_t ien; /* Interrupt Enable register */ +#if defined(CONFIG_EFM32_EFM32GG) + uint32_t ctrl; /* DMA Control Register */ + uint32_t rds; /* DMA Retain Descriptor State */ + uint32_t loop0; /* Channel 0 Loop Register */ + uint32_t loop1; /* Channel 1 Loop Register */ + uint32_t rect0; /* Channel 0 Rectangle Register */ +#endif + uint32_t chnctrl; /* Channel n Control Register */ +}; +#endif + +/* Type of 'config' argument passed to efm32_rxdmasetup() and efm32_txdmasetup. + * See EFM32_DMA_* encodings above. If these encodings exceed 16-bits, then this + * should be changed to a uint32_t. + */ + +typedef uint16_t dma_config_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually exclusive + * access to a DMA channel. + * + * If no DMA channel is available, then efm32_dmachannel() will wait until the + * holder of a channel relinquishes the channel by calling efm32_dmafree(). + * + * Input parameters: + * None + * + * Returned Value: + * This function ALWAYS returns a non-NULL, void* DMA channel handle. + * + * Assumptions: + * - The caller can wait for a DMA channel to be freed if it is not available. + * + ************************************************************************************/ + +DMA_HANDLE efm32_dmachannel(void); + +/************************************************************************************ + * Name: efm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel in a + * call to efm32_dmachannel, then this function will re-assign the DMA channel to + * that thread and wake it up. NOTE: The 'handle' used in this argument must + * NEVER be used again until efm32_dmachannel() is called again to re-gain access + * to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ************************************************************************************/ + +void efm32_dmafree(DMA_HANDLE handle); + +/************************************************************************************ + * Name: efm32_rxdmasetup + * + * Description: + * Configure an RX (peripheral-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (source) + * maddr - Memory address (destination) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ************************************************************************************/ + +void efm32_rxdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config); + +/************************************************************************************ + * Name: efm32_txdmasetup + * + * Description: + * Configure an TX (memory-to-memory) DMA before starting the transfer. + * + * Input Parameters: + * paddr - Peripheral address (destination) + * maddr - Memory address (source) + * nbytes - Number of bytes to transfer. Must be an even multiple of the + * configured transfer size. + * config - Channel configuration selections + * + ************************************************************************************/ + +void efm32_txdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr, + size_t nbytes, dma_config_t config); + +/************************************************************************************ + * Name: efm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * - No DMA in progress + * + ************************************************************************************/ + +void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/************************************************************************************ + * Name: efm32_dmastop + * + * Description: + * Cancel the DMA. After efm32_dmastop() is called, the DMA channel is reset and + * efm32_dmasetup() must be called before efm32_dmastart() can be called again + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ************************************************************************************/ + +void efm32_dmastop(DMA_HANDLE handle); + +/************************************************************************************ + * Name: efm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void efm32_dmasample(DMA_HANDLE handle, struct efm32_dmaregs_s *regs); +#else +# define efm32_dmasample(handle,regs) +#endif + +/************************************************************************************ + * Name: efm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by efm32_dmachannel() + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void efm32_dmadump(DMA_HANDLE handle, const struct efm32_dmaregs_s *regs, + const char *msg); +#else +# define efm32_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_DMA_H */ diff --git a/arch/arm/src/efm32/efm32_flash.c b/arch/arm/src/efm32/efm32_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..a35422b73da9786785ef5b7f692b386b5a4f1031 --- /dev/null +++ b/arch/arm/src/efm32/efm32_flash.c @@ -0,0 +1,864 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_flash.c + * + * Copyright 2014 Silicon Laboratories, Inc. http://www.silabs.com + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc. + * has no obligation to support this Software. Silicon Laboratories, Inc. is + * providing the Software "AS IS", with no express or implied warranties of any + * kind, including, but not limited to, any implied warranties of + * merchantability or fitness for any particular purpose or warranties against + * infringement of any proprietary rights of a third party. + * + * Silicon Laboratories, Inc. will not be liable for any consequential, + * incidental, or special damages, or any other relief, or for any claim by + * any third party, arising from your use of this Software. + * + * Copyright (C) 2015 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Provides standard flash access functions, to be used by the flash mtd driver. + * The interface is defined in the include/nuttx/progmem.h + * + * Requirements during write/erase operations on FLASH: + * - HSI must be ON. + * - Low Power Modes are not permitted during write/erase + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/efm32_msc.h" +#include "chip/efm32_devinfo.h" + +#include "efm32_bitband.h" + +#include "nuttx/progmem.h" + +/* Only for the EFM32 family for now */ + +#if (defined(CONFIG_ARCH_CHIP_EFM32) && defined(CONFIG_EFM32_FLASHPROG)) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef CONFIG_ARCH_RAMFUNCS +# error "Flashing function should executed in ram" +#endif + +#ifndef EFM32_USERDATA_SIZE +# error "EFM32_USERDATA_SIZE should be defined" +#endif + +#ifndef EFM32_USERDATA_BASE +# define "EFM32_USERDATA_BASE should be defined" +#endif + +#ifndef EFM32_USERDATA_NPAGES +# define "EFM32_FLASH_NPAGES should be defined" +#endif + +#ifndef EFM32_USERDATA_PAGESIZE +# define EFM32_USERDATA_PAGESIZE (EFM32_USERDATA_SIZE/EFM32_USERDATA_NPAGES) +#endif + +/* brief: + * The timeout used while waiting for the flash to become ready after + * a write. This number indicates the number of iterations to perform before + * issuing a timeout. + * note: + * This timeout is set very large (in the order of 100x longer than + * necessary). This is to avoid any corner cases. + */ + +#define MSC_PROGRAM_TIMEOUT 10000000ul + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +void efm32_flash_unlock(void) +{ + uint32_t regval; + + /* Unlock the EFM32_MSC */ + + putreg32(MSC_UNLOCK_CODE, EFM32_MSC_LOCK); + + /* Disable writing to the flash */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 0); + +#if defined(_MSC_TIMEBASE_MASK) + + regval = getreg32(EFM32_MSC_TIMEBASE); + regval &= ~(_MSC_TIMEBASE_BASE_MASK | _MSC_TIMEBASE_PERIOD_MASK); + + /* Configure EFM32_MSC_TIMEBASE according to selected frequency */ + + if (BOARD_AUXCLK_FREQUENCY > 7000000) + { + uint32_t freq; + uint32_t cycles; + + /* Calculate number of clock cycles for 1us as base period */ + + freq = (BOARD_AUXCLK_FREQUENCY * 11) / 10; + cycles = (freq / 1000000) + 1; + + /* Configure clock cycles for flash timing */ + + regval |= MSC_TIMEBASE_PERIOD_1US; + regval |= (cycles << _MSC_TIMEBASE_BASE_SHIFT); + } + else + { + uint32_t freq; + uint32_t cycles; + + /* Calculate number of clock cycles for 5us as base period */ + + freq = (BOARD_AUXCLK_FREQUENCY * 5 * 11) / 10; + cycles = (freq / 1000000) + 1; + + /* Configure clock cycles for flash timing */ + + regval |= MSC_TIMEBASE_PERIOD_5US; + regval |= (cycles << _MSC_TIMEBASE_BASE_SHIFT); + } + + putreg32(regval, EFM32_MSC_TIMEBASE); + +#endif +} + +/**************************************************************************** + * Name: msc_load_verify_address + * + * Description: + * Perform address phase of FLASH write cycle. + * + * This function performs the address phase of a Flash write operation by + * writing the given flash address to the ADDRB register and issuing the + * LADDRIM command to load the address. + * note: + * This function MUST be executed from RAM. Failure to execute this portion + * of the code in RAM will result in a hardfault. For IAR, Rowley and + * Codesourcery this will be achieved automatically. For Keil uVision 4 you + * must define a section called "ram_code" and place this manually in your + * project's scatter file. + * param: + * address : Address in flash memory. Must be aligned at a 4 byte boundary. + * return: + * Returns the status of the address load operation, #msc_Return_TypeDef + * OK - Operation completed successfully. + * -EBUSY - Busy timeout. + * -EINVAL - Operation tried to access a non-flash area. + * -EACCES - Operation tried to access a locked area of the flash. + ****************************************************************************/ + +int __ramfunc__ msc_load_verify_address(uint32_t *address) +{ + uint32_t status; + uint32_t timeout; + + /* Wait for the MSC to become ready. */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((getreg32(EFM32_MSC_STATUS) & MSC_STATUS_BUSY) && (timeout != 0)) + { + timeout--; + } + + /* Check for timeout */ + + if (timeout == 0) + { + return -EBUSY; + } + + /* Load address */ + + putreg32((uint32_t) (address), EFM32_MSC_ADDRB); + putreg32(MSC_WRITECMD_LADDRIM, EFM32_MSC_WRITECMD); + + status = getreg32(EFM32_MSC_STATUS); + if (status & (MSC_STATUS_INVADDR | MSC_STATUS_LOCKED)) + { + + /* Check for invalid address */ + + if (status & MSC_STATUS_INVADDR) + { + return -EINVAL; + } + + /* Check for write protected page */ + + if (status & MSC_STATUS_LOCKED) + { + return -EACCES; + } + } + + return OK; +} + +/**************************************************************************** + * Name:msc_load_data + * + * Description: + * Perform data phase of FLASH write cycle. + * + * This function performs the data phase of a Flash write operation by loading + * the given number of 32-bit words to the WDATA register. + * + * note: + * This function MUST be executed from RAM. Failure to execute this portion + * of the code in RAM will result in a hardfault. For IAR, Rowley and + * Codesourcery this will be achieved automatically. For Keil uVision 4 you + * must define a section called "ram_code" and place this manually in your + * project's scatter file. + * + * Input Parameters: + * data : Pointer to the first data word to load. + * num_words : Number of data words (32-bit) to load. + * + * Returned Value: + * Returns the status of the data load operation, #msc_Return_TypeDef + * OK - Operation completed successfully. + * -ETIMEDOUT - Operation timed out waiting for flash operation + * to complete. + ****************************************************************************/ + +int __ramfunc__ msc_load_write_data(uint32_t *data, uint32_t num_words, + bool write_strategy_safe) +{ + int timeout; + int word_index; + int words_per_data_phase; + int ret = 0; + +#if defined(_MSC_WRITECTRL_LPWRITE_MASK) && defined(_MSC_WRITECTRL_WDOUBLE_MASK) + + /* If LPWRITE (Low Power Write) is NOT enabled, set WDOUBLE (Write Double word) */ + + if (!(getreg32(EFM32_MSC_WRITECTRL) & MSC_WRITECTRL_LPWRITE)) + { + /* If the number of words to be written are odd, we need to align by writing + * a single word first, before setting the WDOUBLE bit. + */ + + if (num_words & 0x1) + { + /* Wait for the msc to be ready for the next word. */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((!(getreg32(EFM32_MSC_STATUS) & MSC_STATUS_WDATAREADY)) && \ + (timeout != 0)) + { + timeout--; + } + + /* Check for timeout */ + + if (timeout == 0) + { + return -ETIMEDOUT; + } + + /* Clear double word option, in order to write one single word. */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WDOUBLE_SHIFT, 0); + + /* Write first data word. */ + + putreg32(*data++, EFM32_MSC_WDATA); + putreg32(MSC_WRITECMD_WRITEONCE, EFM32_MSC_WRITECMD); + + /* Wait for the operation to finish. It may be required to change the + * WDOUBLE config after the initial write. It should not be changed + * while BUSY. + */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((getreg32(EFM32_MSC_STATUS) & MSC_STATUS_BUSY) && (timeout != 0)) + { + timeout--; + } + + /* Check for timeout */ + + if (timeout == 0) + { + return -ETIMEDOUT; + } + + /* Subtract this initial odd word for the write loop below */ + + num_words --; + ret = 0; + } + + /* Now we can set the double word option in order to write two words per + * data phase. + */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WDOUBLE_SHIFT, 1); + words_per_data_phase = 2; + } + else +#endif + { + words_per_data_phase = 1; + } + + /* Write the rest as double word write if wordsPerDataPhase == 2 */ + + if (num_words > 0) + { + /* Write strategy: msc_write_int_safe */ + + if (write_strategy_safe) + { + + /* Requires a system core clock at 1MHz or higher */ + + DEBUGASSERT(BOARD_SYSTEM_FREQUENCY >= 1000000); + + word_index = 0; + while (word_index < num_words) + { + putreg32(*data++, EFM32_MSC_WDATA); + word_index++; + if (words_per_data_phase == 2) + { + while (!(getreg32(EFM32_MSC_STATUS) & MSC_STATUS_WDATAREADY)) + { + } + + putreg32(*data++, EFM32_MSC_WDATA); + word_index++; + } + + putreg32(MSC_WRITECMD_WRITEONCE, EFM32_MSC_WRITECMD); + + /* Wait for the transaction to finish. */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((getreg32(EFM32_MSC_STATUS) & MSC_STATUS_BUSY) && \ + (timeout != 0)) + { + timeout--; + } + + /* Check for timeout */ + + if (timeout == 0) + { + ret = -ETIMEDOUT; + break; + } + +#if defined(CONFIG_EFM32_EFM32G) + putreg32(getreg32(EFM32_MSC_ADDRB)+4, EFM32_MSC_ADDRB); + putreg32(MSC_WRITECMD_LADDRIM, EFM32_MSC_WRITECMD); +#endif + } + } + + /* Write strategy: msc_write_fast */ + + else + { +#if defined(CONFIG_EFM32_EFM32G) + + /* Gecko does not have auto-increment of ADDR. */ + + DEBUGASSERT(0); +#else + + /* Requires a system core clock at 14MHz or higher */ + + DEBUGASSERT(BOARD_SYSTEM_FREQUENCY >= 14000000); + + word_index = 0; + + while (word_index < num_words) + { + + /* Wait for the MSC to be ready for the next word. */ + + while (!(getreg32(EFM32_MSC_STATUS) & MSC_STATUS_WDATAREADY)) + { + uint32_t regval; + + /* If the write to MSC->WDATA below missed the 30us timeout + * and the following MSC_WRITECMD_WRITETRIG command arrived + * while MSC_STATUS_BUSY is 1, then the MSC_WRITECMD_WRITETRIG + * could be ignored by the MSC. In this case, + * MSC_STATUS_WORDTIMEOUT is set to 1 and MSC_STATUS_BUSY is + * 0. A new trigger is therefore needed here to complete write + * of data in MSC->WDATA. If WDATAREADY became high since + * entry into this loop, exit and continue to the next WDATA + * write. + */ + + regval = getreg32(EFM32_MSC_STATUS); + regval &= MSC_STATUS_WORDTIMEOUT; + regval &= MSC_STATUS_BUSY; + regval &= MSC_STATUS_WDATAREADY; + if (regval == MSC_STATUS_WORDTIMEOUT) + { + putreg32(MSC_WRITECMD_WRITETRIG, EFM32_MSC_WRITECMD); + } + } + + putreg32(*data, EFM32_MSC_WDATA); + if ((words_per_data_phase == 1) || \ + ((words_per_data_phase == 2) && (word_index & 0x1))) + { + putreg32(MSC_WRITECMD_WRITETRIG, EFM32_MSC_WRITECMD); + } + + data++; + word_index++; + } + + /* Wait for the transaction to finish. */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((getreg32(EFM32_MSC_STATUS) & MSC_STATUS_BUSY) && \ + (timeout != 0)) + { + timeout--; + } + + /* Check for timeout */ + + if (timeout == 0) + { + ret = -ETIMEDOUT; + } +#endif + } + } +#ifdef _MSC_WRITECTRL_WDOUBLE_MASK + + /* Clear double word option, which should not be left on when returning. */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WDOUBLE_SHIFT, 0); + +#endif + + return ret; +} + +void efm32_flash_lock(void) +{ + /* Disable writing to the flash */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 0); + + /* Unlock the EFM32_MSC */ + + putreg32(0, EFM32_MSC_LOCK); +} + +#ifndef EFM32_FLASH_SIZE +#define EFM32_FLASH_SIZE efm32_get_flash_size() +uint32_t efm32_get_flash_size(void) +{ + uint32_t regval; + regval = getreg32(EFM32_DEVINFO_MEMINFO_SIZE); + regval = (regval & _DEVINFO_MEMINFO_SIZE_FLASH_MASK) \ + >> _DEVINFO_MEMINFO_SIZE_FLASH_SHIFT; + + return regval*1024; +} +#endif + +#ifndef EFM32_FLASH_PAGESIZE +#define EFM32_FLASH_PAGESIZE efm32_get_flash_page_size() +uint32_t efm32_get_flash_page_size(void) +{ + uint32_t regval; + regval = getreg32(EFM32_DEVINFO_MEMINFO_PAGE_SIZE); + regval = (regval & _DEVINFO_MEMINFO_FLASH_PAGE_SIZE_MASK) \ + >> _DEVINFO_MEMINFO_FLASH_PAGE_SIZE_SHIFT; + if (regval == 0xff) + { + return 512; + } + + return 1 << (regval+10); +} +#endif + +#ifndef EFM32_FLASH_NPAGES +#define EFM32_FLASH_NPAGES efm32_get_flash_page_nbr() +uint32_t efm32_get_flash_page_nbr(void) +{ + return (EFM32_FLASH_SIZE/EFM32_FLASH_PAGESIZE); +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +size_t up_progmem_pagesize(size_t page) +{ + if (page < EFM32_FLASH_NPAGES) + { + return EFM32_FLASH_PAGESIZE; + } + + page -= EFM32_FLASH_NPAGES; + + if (page < EFM32_USERDATA_NPAGES) + { + return EFM32_USERDATA_PAGESIZE; + } + + return 0; +} + +ssize_t up_progmem_getpage(size_t addr) +{ +#if (EFM32_FLASH_BASE != 0) + if ((addr >= (EFM32_FLASH_BASE)) && \ + (addr < (EFM32_FLASH_BASE+EFM32_FLASH_SIZE))) + { + addr -= EFM32_FLASH_BASE; + + return addr / EFM32_FLASH_PAGESIZE; + } + +#else + if (addr < EFM32_FLASH_SIZE) + { + return addr / EFM32_FLASH_PAGESIZE; + } +#endif + + if ((addr >= (EFM32_USERDATA_BASE)) && \ + (addr < (EFM32_USERDATA_BASE+EFM32_USERDATA_SIZE))) + { + addr -= EFM32_USERDATA_BASE; + + return (addr / EFM32_USERDATA_NPAGES) + EFM32_FLASH_NPAGES; + } + + return -EFAULT; +} + +size_t up_progmem_getaddress(size_t page) +{ + if (page < EFM32_FLASH_NPAGES) + { + return page * EFM32_FLASH_PAGESIZE + EFM32_FLASH_BASE; + } + + page -= EFM32_FLASH_NPAGES; + + if (page < EFM32_USERDATA_NPAGES) + { + return EFM32_USERDATA_BASE + (page * EFM32_USERDATA_NPAGES); + } + + return SIZE_MAX; +} + +size_t up_progmem_npages(void) +{ + return EFM32_FLASH_NPAGES+EFM32_USERDATA_NPAGES; +} + +bool up_progmem_isuniform(void) +{ + return false; +} + +ssize_t __ramfunc__ up_progmem_erasepage(size_t page) +{ + int ret = 0; + int timeout; + uint32_t regval; + irqstate_t flags; + + if (page >= (EFM32_FLASH_NPAGES+EFM32_USERDATA_NPAGES)) + { + return -EFAULT; + } + + efm32_flash_unlock(); + + flags = enter_critical_section(); + + /* enable writing to the flash */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 1); + + /* Load address */ + + putreg32((uint32_t)up_progmem_getaddress(page), EFM32_MSC_ADDRB); + putreg32(MSC_WRITECMD_LADDRIM, EFM32_MSC_WRITECMD); + + regval = getreg32(EFM32_MSC_STATUS); + + /* Check for invalid address */ + + if (regval & MSC_STATUS_INVADDR) + { + ret = -EINVAL; + } + + /* Check for write protected page */ + + if ((ret == 0) && (regval & MSC_STATUS_LOCKED)) + { + ret = -EPERM; + } + + /* Send erase page command */ + + if (ret == 0) + { + putreg32(MSC_WRITECMD_ERASEPAGE, EFM32_MSC_WRITECMD); + + /* Wait for the erase to complete */ + + timeout = MSC_PROGRAM_TIMEOUT; + while ((getreg32(EFM32_MSC_STATUS) & MSC_STATUS_BUSY) && (timeout != 0)) + { + timeout--; + } + + if (timeout == 0) + { + ret = -ETIMEDOUT; + } + } + + /* Disable writing to the MSC */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 0); + + if (ret == 0) + { + /* Verify */ + + if (up_progmem_ispageerased(page) != 0) + { + ret = -EIO; + } + } + + leave_critical_section(flags); + + if (ret != 0) + { + return ret; + } + + /* Success */ + + return up_progmem_pagesize(page); +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= (EFM32_FLASH_NPAGES+EFM32_USERDATA_NPAGES)) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != 0xff) + { + bwritten++; + } + } + + return bwritten; + +} + +ssize_t __ramfunc__ up_progmem_write(size_t addr, const void *buf, size_t size) +{ + int ret = 0; + int word_count; + int num_words; + int page_words; + uint32_t *p_data; + uint32_t *address = (uint32_t *)addr; + uint32_t num_bytes = size; + + /* EFM32 requires word access */ + + if (addr & 3) + { + return -EINVAL; + } + + /* EFM32 requires word access */ + + if (num_bytes & 3) + { + return -EINVAL; + } + + efm32_flash_unlock(); + + /* enable writing to the flash */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 1); + + /* Convert bytes to words */ + + num_words = num_bytes >> 2; + + /* The following loop splits the data into chunks corresponding to flash pages. + * The address is loaded only once per page, because the hardware automatically + * increments the address internally for each data load inside a page. + */ + + for (word_count = 0, p_data = (uint32_t *)buf; word_count < num_words; ) + { + int page_bytes; + ssize_t page_idx; + irqstate_t flags; + + /* Compute the number of words to write to the current page. */ + + page_idx = up_progmem_getpage((size_t)address+(word_count << 2)); + if (page_idx < 0) + { + ret = -EINVAL; + break; + } + + page_bytes = up_progmem_pagesize(page_idx); + if (page_bytes < 0) + { + ret = -EINVAL; + break; + } + + page_words = (page_bytes - (((uint32_t) (address + word_count)) & \ + (page_bytes-1))) / sizeof(uint32_t); + + if (page_words > num_words - word_count) + { + page_words = num_words - word_count; + } + + flags = enter_critical_section(); + + /* First we load address. The address is auto-incremented within a page. + * Therefore the address phase is only needed once for each page. + */ + + ret = msc_load_verify_address(address + word_count); + + /* Now write the data in the current page. */ + + if (ret == 0) + { + ret = msc_load_write_data(p_data, page_words, true); + } + + leave_critical_section(flags); + + if (ret != 0) + { + break; + } + + word_count += page_words; + p_data += page_words; + } + + /* Disable writing to the MSC */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 0); + +#if (defined(CONFIG_EFM32_EFM32GG) || defined(CONFIG_EFM32_EFM32WG)) && (2==WORDS_PER_DATA_PHASE) + + /* Turn off double word write cycle support. */ + + bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WDOUBLE_SHIFT, 0); + +#endif + + if (ret < 0) + { + return ret; + } + + return word_count; +} + +#endif /* defined(CONFIG_ARCH_CHIP_EFM32) */ diff --git a/arch/arm/src/efm32/efm32_gpio.c b/arch/arm/src/efm32/efm32_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..77bc980481dd95c755d85472b73cf584915a8715 --- /dev/null +++ b/arch/arm/src/efm32/efm32_gpio.c @@ -0,0 +1,399 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_gpio.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip/efm32_gpio.h" +#include "efm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define __GPIO_INPUT (1 << 0) /* Bit 0: GPIO is an input */ +#define __GPIO_OUTPUT (1 << 1) /* Bit 1: GPIO is an output */ +#define __GPIO_DOUT (1 << 2) /* Bit 2: An input modified with DOUT setting */ +#define __GPIO_DRIVE (1 << 3) /* Bit 3: An output with drive selection */ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static const uint8_t g_gpiomode[16] = +{ + (__GPIO_DOUT), /* 0 DISABLED Input disabled. Pullup if DOUT is + * set. */ + (__GPIO_INPUT | __GPIO_DOUT), /* 1 INPUT Input enabled. Filter if DOUT is set. */ + (__GPIO_INPUT | __GPIO_DOUT), /* 2 INPUTPULL Input enabled. DOUT determines pull + * direction */ + (__GPIO_INPUT | __GPIO_DOUT), /* 3 INPUTPULLFILTER Input enabled with filter. + * COUT determines pull direction */ + (__GPIO_OUTPUT), /* 4 PUSHPULL Push-pull output */ + (__GPIO_OUTPUT | __GPIO_DRIVE), /* 5 PUSHPULLDRIVE Push-pull output with drive- + * strength set by DRIVEMODE */ + (__GPIO_OUTPUT), /* 6 WIREDOR Wired-or output */ + (__GPIO_OUTPUT), /* 7 WIREDORPULLDOWN Wired-or output with pull- + * down */ + (__GPIO_OUTPUT), /* 8 WIREDAND Open-drain output */ + (__GPIO_OUTPUT), /* 9 WIREDANDFILTER Open-drain output with filter */ + (__GPIO_OUTPUT), /* 10 WIREDANDPULLUP Open-drain output with pullup */ + (__GPIO_OUTPUT), /* 11 WIREDANDPULLUPFILTER Open-drain output with + * filter and pullup */ + (__GPIO_OUTPUT | __GPIO_DRIVE), /* 12 WIREDANDDRIVE Open-drain output with + * drive-strength set by DRIVEMODE */ + (__GPIO_OUTPUT | __GPIO_DRIVE), /* 13 WIREDANDDRIVEFILTER Open-drain output with + * filter and drive-strength set by DRIVEMODE */ + (__GPIO_OUTPUT | __GPIO_DRIVE), /* 14 WIREDANDDRIVEPULLUP Open-drain output with + * pullup and drive-strength set by DRIVEMODE */ + (__GPIO_OUTPUT | __GPIO_DRIVE) /* 15 WIREDANDDRIVEPULLUPFILTER Open-drain output + * with filter, pullup and drive-strength set + * by DRIVEMODE */ +}; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_getport + * + * Description: + * Extract the encoded port number + * + ************************************************************************************/ + +static inline uint8_t efm32_getport(gpio_pinset_t cfgset) +{ + return (uint8_t)((cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +/************************************************************************************ + * Name: efm32_getpin + * + * Description: + * Extract the encoded pin number + * + ************************************************************************************/ + +static inline uint8_t efm32_getpin(gpio_pinset_t cfgset) +{ + return (uint8_t)((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/************************************************************************************ + * Name: efm32_getmode + * + * Description: + * Extract the encoded pin mode + * + ************************************************************************************/ + +static inline uint8_t efm32_getmode(gpio_pinset_t cfgset) +{ + return (uint8_t)((cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT); +} + +/************************************************************************************ + * Name: efm32_getdrive + * + * Description: + * Extract the output drive strength from the encoded configuration + * + ************************************************************************************/ + +static uint8_t efm32_getdrive(uint8_t mode, gpio_pinset_t cfgset) +{ + if ((g_gpiomode[mode] & __GPIO_DRIVE) != 0) + { + return (uint8_t)((cfgset & GPIO_DRIVE_MASK) >> GPIO_DRIVE_SHIFT); + } + else + { + return _GPIO_DRIVE_STANDARD; + } +} + +/************************************************************************************ + * Name: efm32_setdrive + * + * Description: + * Set the GPIO output drive strength + * + ************************************************************************************/ + +static inline void efm32_setdrive(uintptr_t base, uint8_t pin, uint8_t drive) +{ + /* Select drive mode for all pins on port configured with alternate drive + * strength. + * + * REVISIT: Is there any sane way to manage this for multiple pins in the port + * with different drive values? + */ + if (drive != _GPIO_DRIVE_STANDARD) + { + putreg32((uint32_t)drive << _GPIO_P_CTRL_DRIVEMODE_SHIFT, + base + EFM32_GPIO_Pn_CTRL_OFFSET); + } +} + +/************************************************************************************ + * Name: efm32_getdout + * + * Description: + * Extract the encoded port number + * + ************************************************************************************/ + +static inline bool efm32_getdout(uint8_t mode, gpio_pinset_t cfgset) +{ + if ((g_gpiomode[mode] & __GPIO_DOUT) != 0) + { + return (bool)((cfgset >> GPIO_MODE_DOUT_SHIFT) & 1); + } + else if ((g_gpiomode[mode] & __GPIO_OUTPUT) != 0) + { + return (bool)((cfgset >> GPIO_OUTPUT_SHIFT) & 1); + } + else + { + return 0; + } +} + +/************************************************************************************ + * Name: efm32_setdout + * + * Description: + * Set the GPIO output data value + * + ************************************************************************************/ + +static inline void efm32_setdout(uintptr_t base, uint8_t pin, bool dout) +{ + /* Set or clear the port data out bit */ + + if (dout) + { + putreg32(1 << pin, base + EFM32_GPIO_Pn_DOUTSET_OFFSET); + } + else + { + putreg32(1 << pin, base + EFM32_GPIO_Pn_DOUTCLR_OFFSET); + } +} + +/************************************************************************************ + * Name: efm32_getdin + * + * Description: + * Get the GPIO input value + * + ************************************************************************************/ + +static inline bool efm32_getdin(uintptr_t base, uint8_t pin) +{ + return ((getreg32(base + EFM32_GPIO_Pn_DIN_OFFSET) & ((uint32_t)1 << pin)) != 0); +} + +/************************************************************************************ + * Name: efm32_setmode + * + * Description: + * Set the GPIO mode + * + ************************************************************************************/ + +static inline void efm32_setmode(uintptr_t base, uint8_t pin, uint8_t mode) +{ + uintptr_t regaddr; + unsigned int shift; + uint32_t regval; + + /* Select high or low register */ + + if (pin < 8) + { + regaddr = base + EFM32_GPIO_Pn_MODEL_OFFSET; + shift = (unsigned int)pin << 2; + } + else + { + regaddr = base + EFM32_GPIO_Pn_MODEH_OFFSET; + shift = (unsigned int)(pin - 8) << 2; + } + + /* Set the new mode */ + + regval = getreg32(regaddr); + regval &= ~((uint32_t)15 << shift); + regval |= (uint32_t)mode << shift; + putreg32(regval, regaddr); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_configgpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int efm32_configgpio(gpio_pinset_t cfgset) +{ + uintptr_t base; + uint8_t port; + uint8_t pin; + uint8_t mode; + uint8_t drive; + bool dout; + + /* Get basic pin configuration information */ + + port = efm32_getport(cfgset); + base = EFM32_GPIO_Pn_BASE(port); + pin = efm32_getpin(cfgset); + mode = efm32_getmode(cfgset); + + /* Set the drive strength in the GPIO control register */ + + drive = efm32_getdrive(mode, cfgset); + efm32_setdrive(base, pin, drive); + + /* Set the port data out register */ + + dout = efm32_getdout(mode, cfgset); + efm32_setdout(base, pin, dout); + + /* Finally, set the pin mode */ + + efm32_setmode(base, pin, mode); + return OK; +} + +/************************************************************************************ + * Name: efm32_unconfiggpio + * + * Description: + * unConfigure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int efm32_unconfiggpio(gpio_pinset_t cfgset) +{ + cfgset &= GPIO_PIN_MASK | GPIO_PORT_MASK; + cfgset |= _GPIO_DISABLE; + + return efm32_configgpio(cfgset); +} + +/************************************************************************************ + * Name: efm32_gpiowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ************************************************************************************/ + +void efm32_gpiowrite(gpio_pinset_t pinset, bool value) +{ + uintptr_t base; + uint8_t port; + uint8_t pin; + + /* Get basic pin configuration information */ + + port = efm32_getport(pinset); + base = EFM32_GPIO_Pn_BASE(port); + pin = efm32_getpin(pinset); + + /* And set the output value */ + + efm32_setdout(base, pin, value); +} + +/************************************************************************************ + * Name: efm32_gpioread + * + * Description: + * Read one or zero from the selected PIO pin + * + ************************************************************************************/ + +bool efm32_gpioread(gpio_pinset_t pinset) +{ + uintptr_t base; + uint8_t port; + uint8_t pin; + + /* Get basic pin configuration information */ + + port = efm32_getport(pinset); + base = EFM32_GPIO_Pn_BASE(port); + pin = efm32_getpin(pinset); + + /* And return the input value of the pin */ + + return efm32_getdin(base, pin); +} + +/************************************************************************************ + * Function: efm32_dumpgpio + * + * Description: + * Dump all PIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int efm32_dumpgpio(uint32_t pinset, const char *msg) +{ +#warning Missing logic + return -ENOSYS; +} +#endif diff --git a/arch/arm/src/efm32/efm32_gpio.h b/arch/arm/src/efm32/efm32_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..ed54bb5148c80f63ad81b579f1f91840e3933eac --- /dev/null +++ b/arch/arm/src/efm32/efm32_gpio.h @@ -0,0 +1,365 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_gpio.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_GPIO_H +#define __ARCH_ARM_SRC_EFM32_EFM32_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#define EFM32_NGPIO 5 /* (5) GPIOA-F */ + +/* Bit-encoded input to efm32_configgpio() *******************************************/ + +/* 16-bit Encoding: + * + * Input: MMMM OII. .PPP BBBB + * Output: MMMM VDD. .PPP BBBB + */ + +/* Port mode: + * + * MMMM O... .... .... + */ + +#define GPIO_MODE_SHIFT (12) /* Bits 12-15: Port mode */ +#define GPIO_MODE_MASK (15 << GPIO_MODE_SHIFT) + +#define GPIO_MODE_DOUT_SHIFT (11) /* Bit 11: Input mode modifer */ +#define GPIO_MODE_DOUT_MASK (1 << GPIO_MODE_DOUT_SHIFT) +# define GPIO_MODE_DOUT GPIO_MODE_DOUT_MASK + +/* Input modes */ + +# define _GPIO_DISABLE (0 << GPIO_MODE_SHIFT) +# define _GPIO_INPUT (1 << GPIO_MODE_SHIFT) +# define _GPIO_INPUT_PULL (2 << GPIO_MODE_SHIFT) +# define _GPIO_INPUT_PULL_FILTER (3 << GPIO_MODE_SHIFT) + +# define GPIO_PULLUP \ + (_GPIO_DISABLE | GPIO_MODE_DOUT) +# define GPIO_INPUT \ + _GPIO_INPUT +# define GPIO_INPUT_FILTER \ + (_GPIO_INPUT | GPIO_MODE_DOUT) +# define GPIO_INPUT_PULLDOWN \ + _GPIO_INPUT_PULL +# define GPIO_INPUT_PULLUP \ + (_GPIO_INPUT_PULL | GPIO_MODE_DOUT) +# define GPIO_INPUT_PULLDOWN_FILTER \ + _GPIO_INPUT_PULL_FILTER +# define GPIO_INPUT_PULLUP_FILTER \ + (_GPIO_INPUT_PULL_FILTER | GPIO_MODE_DOUT) + +/* Output modes */ + +# define GPIO_OUTPUT_PUSHPULL \ + (4 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_PUSHPULL_DRIVE \ + (5 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDOR \ + (6 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDOR_PULLDOWN \ + (7 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND \ + (8 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_FILTER \ + (9 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_PULLUP \ + (10 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_PULLUP_FILTER \ + (11 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_DRIVE \ + (12 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_DRIVE_FILTER \ + (13 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_DRIVE_PULLUP \ + (14 << GPIO_MODE_SHIFT) +# define GPIO_OUTPUT_WIREDAND_DRIVE_PULLUP_FILTER \ + (15 << GPIO_MODE_SHIFT) + +/* If the pin is an PIO output, then this identifies the initial output value: + * + * .... V... .... .... + */ + +#define GPIO_OUTPUT_SHIFT (11) /* Bit 11: Initial value of output */ +#define GPIO_OUTPUT_MASK (1 << GPIO_OUTPUT_SHIFT) +# define GPIO_OUTPUT_SET GPIO_OUTPUT_MASK +# define GPIO_OUTPUT_CLEAR (0) + +/* Output drive: + * + * .... .DD. .... .... + */ + +#define GPIO_DRIVE_SHIFT (9) /* Bits 9-10: Output drive strength */ +#define GPIO_DRIVE_MASK (3 << GPIO_DRIVE_SHIFT) +# define _GPIO_DRIVE_STANDARD (0) /* 6 mA drive current */ +# define _GPIO_DRIVE_LOWEST (1) /* 0.5 mA drive current */ +# define _GPIO_DRIVE_HIGH (2) /* 20 mA drive current */ +# define _GPIO_DRIVE_LOW (3) /* 2 mA drive current */ +# define GPIO_DRIVE_STANDARD (_GPIO_DRIVE_STANDARD << GPIO_DRIVE_SHIFT) +# define GPIO_DRIVE_LOWEST (_GPIO_DRIVE_LOWEST << GPIO_DRIVE_SHIFT) +# define GPIO_DRIVE_HIGH (_GPIO_DRIVE_HIGH << GPIO_DRIVE_SHIFT) +# define GPIO_DRIVE_LOW (_GPIO_DRIVE_LOW << GPIO_DRIVE_SHIFT) + +/* Interrupt Mode (Input only): + * + * .... .II. .... .... + */ + +#define GPIO_INT_SHIFT (9) /* Bits 9-10: Interrupt mode */ +#define GPIO_INT_MASK (3 << GPIO_INT_SHIFT) +# define GPIO_INT_NONE (0) +# define GPIO_INT_RISING (1 << GPIO_INT_SHIFT) +# define GPIO_INT_FALLING (2 << GPIO_INT_SHIFT) +# define GPIO_INT_BOTH (GPIO_INT_RISING | GPIO_INT_FALLING) + +/* This identifies the PIO port: + * + * .... .... .PPP .... + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-6: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +/* This identifies the pin in the port: + * + * .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: Pin number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 16-bit encoding */ + +typedef uint16_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for PIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_GPIO_IRQ +void efm32_gpioirqinitialize(void); +#else +# define efm32_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: efm32_configgpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int efm32_configgpio(gpio_pinset_t cfgset); + +/************************************************************************************ + * Name: efm32_unconfiggpio + * + * Description: + * UnConfigure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int efm32_unconfiggpio(gpio_pinset_t cfgset); + +/************************************************************************************ + * Name: efm32_gpiowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ************************************************************************************/ + +void efm32_gpiowrite(gpio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: efm32_gpioread + * + * Description: + * Read one or zero from the selected PIO pin + * + ************************************************************************************/ + +bool efm32_gpioread(gpio_pinset_t pinset); + +/************************************************************************************ + * Name: efm32_gpioirq + * + * Description: + * Configure an interrupt for the specified PIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_GPIO_IRQ +void efm32_gpioirq(gpio_pinset_t pinset); +#else +# define efm32_gpioirq(pinset) +#endif + +/************************************************************************************ + * Name: efm32_gpioirqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_GPIO_IRQ +void efm32_gpioirqenable(int irq); +#else +# define efm32_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: efm32_gpioirqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_GPIO_IRQ +void efm32_gpioirqdisable(int irq); +#else +# define efm32_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Name: efm32_gpioirqclear + * + * Description: + * clear the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_GPIO_IRQ +void efm32_gpioirqclear(int irq); +#else +# define efm32_gpioirqclear(irq) +#endif + +/************************************************************************************ + * Function: efm32_dumpgpio + * + * Description: + * Dump all PIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int efm32_dumpgpio(uint32_t pinset, const char *msg); +#else +# define efm32_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_GPIO_H */ diff --git a/arch/arm/src/efm32/efm32_gpioirq.c b/arch/arm/src/efm32/efm32_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..8c3527e9f55d2cfcaac2b6c4cbcd3108a898292e --- /dev/null +++ b/arch/arm/src/efm32/efm32_gpioirq.c @@ -0,0 +1,357 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_gpioirq.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/efm32_gpio.h" +#include "efm32_gpio.h" +#include "efm32_bitband.h" + +#ifdef CONFIG_EFM32_GPIO_IRQ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_getport + * + * Description: + * Extract the encoded port number + * + ************************************************************************************/ + +static inline uint8_t efm32_getport(gpio_pinset_t cfgset) +{ + return (uint8_t)((cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +/************************************************************************************ + * Name: efm32_getpin + * + * Description: + * Extract the encoded pin number + * + ************************************************************************************/ + +static inline uint8_t efm32_getpin(gpio_pinset_t cfgset) +{ + return (uint8_t)((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/************************************************************************************ + * Name: efm32_gpio_interrupt + * + * Description: + * Common GPIO interrupt handling logic + * + ************************************************************************************/ + +static int efm32_gpio_interrupt(uint32_t mask, void *context) +{ + uint32_t pending; + uint32_t bit; + int irq; + + /* Get the set of even/odd, pending, enabled interrupts */ + + pending = getreg32(EFM32_GPIO_IF) & getreg32(EFM32_GPIO_IEN) & mask; + putreg32(pending, EFM32_GPIO_IFC); + + /* Then dispatch each interrupt */ + + for (bit = 1, irq = EFM32_IRQ_EXTI0; pending != 0; bit <<= 1, irq++) + { + if ((pending & bit) != 0) + { + /* Re-deliver the IRQ (recurses! We got here from irq_dispatch!) */ + + irq_dispatch(irq, context); + + /* Remove this from the set of pending interrupts */ + + pending &= ~bit; + } + } + + return OK; +} + +/************************************************************************************ + * Name: efm32_even_interrupt + * + * Description: + * Even GPIO interrupt handling logic + * + ************************************************************************************/ + +static int efm32_even_interrupt(int irq, void *context) +{ + return efm32_gpio_interrupt(0x00005555, context); +} + +/************************************************************************************ + * Name: efm32_even_interrupt + * + * Description: + * Even GPIO interrupt handling logic + * + ************************************************************************************/ + +static int efm32_odd_interrupt(int irq, void *context) +{ + return efm32_gpio_interrupt(0x0000aaaa, context); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for PIO pins. + * + ************************************************************************************/ + +void efm32_gpioirqinitialize(void) +{ + /* Initialize GPIO interrupt registers, disabling GPIO interrupts at the source */ + + putreg32(0, EFM32_GPIO_EXTIRISE); + putreg32(0, EFM32_GPIO_EXTIFALL); + putreg32(0, EFM32_GPIO_IEN); + + /* Attach the even and odd interrupt handlers */ + + DEBUGVERIFY(irq_attach(EFM32_IRQ_GPIO_EVEN, efm32_even_interrupt)); + DEBUGVERIFY(irq_attach(EFM32_IRQ_GPIO_ODD, efm32_odd_interrupt)); + + /* Enable GPIO even and odd interrupts at the NVIC */ + + up_enable_irq(EFM32_IRQ_GPIO_ODD); + up_enable_irq(EFM32_IRQ_GPIO_EVEN); +} + +/************************************************************************************ + * Name: efm32_gpioirq + * + * Description: + * Configure an interrupt for the specified PIO pin. + * + ************************************************************************************/ + +void efm32_gpioirq(gpio_pinset_t pinset) +{ + irqstate_t flags; + unsigned int shift; + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + uint8_t port; + uint8_t pin; + + /* Get basic pin configuration information */ + + port = efm32_getport(pinset); + pin = efm32_getpin(pinset); + bit = ((uint32_t)1 << pin); + + /* Make sure that the pin interrupt is disabled */ + + flags = enter_critical_section(); + regval = getreg32(EFM32_GPIO_IEN); + regval &= ~bit; + putreg32(regval, EFM32_GPIO_IEN); + + /* Set the interrupt port */ + + if (pin < 8) + { + regaddr = EFM32_GPIO_EXTIPSELL; + shift = (unsigned int)pin << 2; + } + else + { + regaddr = EFM32_GPIO_EXTIPSELH; + shift = (unsigned int)(pin - 8) << 2; + } + + regval = getreg32(regaddr); + regval &= ~(7 << shift); + regval |= ((uint32_t)port << shift); + putreg32(regval, regaddr); + + /* Set/clear rising edge interrupt detection */ + + regval = getreg32(EFM32_GPIO_EXTIRISE); + if ((pinset & GPIO_INT_RISING) != 0) + { + regval |= bit; + } + else + { + regval &= ~bit; + } + + putreg32(regval, EFM32_GPIO_EXTIRISE); + + /* Set/clear rising edge interrupt detection */ + + regval = getreg32(EFM32_GPIO_EXTIFALL); + if ((pinset & GPIO_INT_FALLING) != 0) + { + regval |= bit; + } + else + { + regval &= ~bit; + } + + putreg32(regval, EFM32_GPIO_EXTIFALL); + leave_critical_section(flags); +} + +/************************************************************************************ + * Name: efm32_gpioirqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +void efm32_gpioirqenable(int irq) +{ + + if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) + { + /* Enable the interrupt associated with the pin */ + +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; + bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); + flags = enter_critical_section(); + regval = getreg32(EFM32_GPIO_IEN); + regval |= bit; + putreg32(regval, EFM32_GPIO_IEN); + leave_critical_section(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IEN, (irq - EFM32_IRQ_EXTI0), 1); +#endif + } +} + +/************************************************************************************ + * Name: efm32_gpioirqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +void efm32_gpioirqdisable(int irq) +{ + if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) + { + /* Enable the interrupt associated with the pin */ + +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; + + bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); + flags = enter_critical_section(); + regval = getreg32(EFM32_GPIO_IEN); + regval &= ~bit; + putreg32(regval, EFM32_GPIO_IEN); + leave_critical_section(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IEN, (irq - EFM32_IRQ_EXTI0), 0); +#endif + } +} + +/************************************************************************************ + * Name: efm32_gpioirqclear + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +void efm32_gpioirqclear(int irq) +{ + if (irq >= EFM32_IRQ_EXTI0 && irq <= EFM32_IRQ_EXTI15) + { + /* Enable the interrupt associated with the pin */ + +#ifndef CONFIG_EFM32_BITBAND + irqstate_t flags; + uint32_t regval; + uint32_t bit; + + bit = ((uint32_t)1 << (irq - EFM32_IRQ_EXTI0)); + flags = enter_critical_section(); + regval = getreg32(EFM32_GPIO_IFC); + regval |= bit; + putreg32(regval, EFM32_GPIO_IFC); + leave_critical_section(flags); +#else + bitband_set_peripheral(EFM32_GPIO_IFC, (irq - EFM32_IRQ_EXTI0), 1); +#endif + } +} + +#endif /* CONFIG_EFM32_GPIO_IRQ */ diff --git a/arch/arm/src/efm32/efm32_i2c.c b/arch/arm/src/efm32/efm32_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..3f4638390e6b5871642d944b870a58353fe9680f --- /dev/null +++ b/arch/arm/src/efm32/efm32_i2c.c @@ -0,0 +1,1817 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_i2c.c + * EFM32 I2C Hardware Layer - Device Driver + * + * Copyright (C) 2015 Pierre-noel Bouteville . All rights reserved. + * Authors: Pierre-noel Bouteville + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Supports: + * - Master operation, 100 kHz (standard) and 400 kHz (full speed) + * TODO: + * - Multiple instances (shared bus) + * - Interrupt based operation + * + * Structure naming: + * - Device: structure as defined by the nuttx/i2c/i2c.h + * - Instance: represents each individual access to the I2C driver, obtained by + * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; + * Instance points to OPS, to common I2C Hardware private data and contains + * its own private data, as frequency, address, mode of operation (in the + * future) + * - Private: Private data of an I2C Hardware + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "efm32_gpio.h" +#include "chip/efm32_cmu.h" +#include "chip/efm32_i2c.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_EFM32_I2C0) || defined(CONFIG_EFM32_I2C1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **************************************************************/ + +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +#if !defined(CONFIG_EFM32_EFM32GG) +# warning "Tested only on EFM32GG family" +#endif + +#ifndef CONFIG_I2C_POLLED +# warning "Not tested with interrupt" +#endif + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_EFM32_I2CTIMEOSEC) && !defined(CONFIG_EFM32_I2CTIMEOMS) +# define CONFIG_EFM32_I2CTIMEOSEC 0 +# define CONFIG_EFM32_I2CTIMEOMS 500/* Default is 500 milliseconds */ +#elif !defined(CONFIG_EFM32_I2CTIMEOSEC) +# define CONFIG_EFM32_I2CTIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_EFM32_I2CTIMEOMS) +# define CONFIG_EFM32_I2CTIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_EFM32_I2CTIMEOTICKS +# define CONFIG_EFM32_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_EFM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_EFM32_I2CTIMEOMS)) +#endif + +#ifndef CONFIG_EFM32_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_EFM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_EFM32_I2CTIMEOTICKS) +#endif + +/* Macros to convert a I2C pin to a GPIO output */ + +#define I2C_OUTPUT (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD) + +#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ****************************************************************************/ + +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, + * low-level debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define efm32_i2c_tracereset(p) +# define efm32_i2c_tracenew(p) +# define efm32_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/* Error flags indicating I2C transfer has failed somehow. + * Notice that I2C_IF_TXOF (transmit overflow) is not really possible with + * this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) + * RXUF is only likely to occur with this SW if using a debugger peeking into + * RXDATA register. Thus, we ignore those types of fault. + */ + +#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST) + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* I2C result state */ + +enum efm32_result_e +{ + I2CRESULT_SWFAULT = -5, /* SW fault. */ + I2CRESULT_USAGEFAULT = -4, /* Usage fault. */ + I2CRESULT_ARBLOST = -3, /* Arbitration lost during transfer. */ + I2CRESULT_BUSERR = -2, /* Bus error during transfer (misplaced + * START/STOP). */ + I2CRESULT_NACK = -1, /* NACK received during transfer. */ + I2CRESULT_INPROGRESS = 0, /* Transfer in progress. */ + I2CRESULT_DONE = 1, /* Transfer completed successfully. */ + I2CRESULT_NONE = 2 /* Nothing. */ +}; + +enum efm32_i2cstate_e +{ + I2CSTATE_NONE = 0, /* Send start + (first part of) address. */ + I2CSTATE_STARTADDRSEND, /* Send start + (first part of) address. */ + I2CSTATE_ADDRWFACKNACK, /* Wait for ACK/NACK on (first part of) + * address. */ + I2CSTATE_ADDRWF2NDACKNACK, /* Wait for ACK/NACK on second part of 10 bit + * address. */ + I2CSTATE_RSTARTADDRSEND, /* Send repeated start + (first part of) + * address. */ + I2CSTATE_RADDRWFACKNACK, /* Wait for ACK/NACK on address sent after + * repeated start. */ + I2CSTATE_DATASEND, /* Send data. */ + I2CSTATE_DATAWFACKNACK, /* Wait for ACK/NACK on data sent. */ + I2CSTATE_WFDATA, /* Wait for data. */ + I2CSTATE_WFSTOPSENT, /* Wait for STOP to have been transmitted. */ + I2CSTATE_DONE /* Transfer completed successfully. */ +}; + +/* Trace data */ + +struct efm32_trace_s +{ + uint32_t i2c_state; /* I2C state machine current state */ + uint32_t i2c_reg_state; /* I2C register I2Cx_STATES */ + uint32_t i2c_reg_if; /* I2C register I2Cx_IF */ + uint32_t count; /* Interrupt count when status change */ + systime_t time; /* First of event or first status */ + int dcnt; /* Interrupt count when status change */ +}; + +/* I2C Device hardware configuration */ + +struct efm32_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t route; /* route location of I2C */ + uint32_t reset_bit; /* Reset bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr) (int, void *); /* Interrupt handler */ + uint32_t irq; /* Event IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct efm32_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct efm32_i2c_config_s *config; /* Port configuration */ + int refs; /* Referernce count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + + volatile int8_t result; /* result of transfer */ + + uint8_t i2c_state; /* i2c state machine */ + uint32_t i2c_reg_if; /* Current state of I2Cx_IF register. */ + uint32_t i2c_reg_state; /* Current state of I2Cx_STATES register. */ + + int addr; /* Message address */ + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + int dcnt; /* Current message length */ + uint32_t flags; /* Current message flags */ + uint32_t frequency; /* Current I2C frequency */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + systime_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct efm32_trace_s trace[CONFIG_I2C_NTRACE]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t efm32_i2c_getreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset); +static inline void efm32_i2c_putreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset, uint32_t value); +static inline void efm32_i2c_modifyreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits); +static inline void efm32_i2c_sem_wait(FAR struct efm32_i2c_priv_s *priv); + +#ifdef CONFIG_EFM32_I2C_DYNTIMEOUT +static useconds_t efm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_EFM32_I2C_DYNTIMEOUT */ + +static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv); +static inline void efm32_i2c_sem_post(FAR struct efm32_i2c_priv_s *priv); +static inline void efm32_i2c_sem_init(FAR struct efm32_i2c_priv_s *priv); +static inline void efm32_i2c_sem_destroy(FAR struct efm32_i2c_priv_s *priv); + +#ifdef CONFIG_I2C_TRACE +static void efm32_i2c_tracereset(FAR struct efm32_i2c_priv_s *priv); +static void efm32_i2c_tracenew(FAR struct efm32_i2c_priv_s *priv); +static void efm32_i2c_tracedump(FAR struct efm32_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +static void efm32_i2c_setclock(FAR struct efm32_i2c_priv_s *priv, + uint32_t frequency); + +static int efm32_i2c_isr(struct efm32_i2c_priv_s *priv); + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_EFM32_I2C0 +static int efm32_i2c0_isr(int irq, void *context); +#endif +#ifdef CONFIG_EFM32_I2C1 +static int efm32_i2c1_isr(int irq, void *context); +#endif +#endif /* !CONFIG_I2C_POLLED */ + +static void efm32_i2c_hwreset(FAR struct efm32_i2c_priv_s *priv); +static int efm32_i2c_init(FAR struct efm32_i2c_priv_s *priv); +static int efm32_i2c_deinit(FAR struct efm32_i2c_priv_s *priv); +static int efm32_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int efm32_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +#ifdef CONFIG_I2C_TRACE +static const char *efm32_i2c_state_str(int i2c_state); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* I2C interface */ + +static const struct i2c_ops_s efm32_i2c_ops = +{ + .transfer = efm32_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = efm32_i2c_reset +#endif +}; + +/* I2C device structures */ + +#ifdef CONFIG_EFM32_I2C0 +static const struct efm32_i2c_config_s efm32_i2c0_config = +{ + .base = EFM32_I2C0_BASE, + .clk_bit = CMU_HFPERCLKEN0_I2C0, + .route = BOARD_I2C1_ROUTE_LOCATION, + .scl_pin = BOARD_I2C0_SCL, + .sda_pin = BOARD_I2C0_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = efm32_i2c0_isr, + .irq = EFM32_IRQ_I2C0 +#endif +}; + +static struct efm32_i2c_priv_s efm32_i2c0_priv = +{ + .ops = &efm32_i2c_ops, + .config = &efm32_i2c0_config, + .refs = 0, + .result = I2CRESULT_NONE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, +}; +#endif + +#ifdef CONFIG_EFM32_I2C1 +static const struct efm32_i2c_config_s efm32_i2c1_config = +{ + .base = EFM32_I2C1_BASE, + .clk_bit = CMU_HFPERCLKEN0_I2C1, + .route = BOARD_I2C1_ROUTE_LOCATION, + .scl_pin = BOARD_I2C1_SCL, + .sda_pin = BOARD_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = efm32_i2c1_isr, + .irq = EFM32_IRQ_I2C1 +#endif +}; + +static struct efm32_i2c_priv_s efm32_i2c1_priv = +{ + .ops = &efm32_i2c_ops, + .config = &efm32_i2c1_config, + .refs = 0, + .result = I2CRESULT_NONE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ****************************************************************************/ + +static inline uint32_t efm32_i2c_getreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg32(priv->config->base + offset); +} + +/**************************************************************************** + * Name: efm32_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ****************************************************************************/ + +static inline void efm32_i2c_putreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->config->base + offset); +} + +/**************************************************************************** + * Name: efm32_i2c_modifyreg + * + * Description: + * Modify a 16-bit register value by offset + * + ****************************************************************************/ + +static inline void efm32_i2c_modifyreg(FAR struct efm32_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->config->base + offset, clearbits, setbits); +} + +/**************************************************************************** + * Name: efm32_i2c_state_str + * + * Description: + * Convert i2c_state into corresponding text. + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static const char *efm32_i2c_state_str(int i2c_state) +{ + switch (i2c_state) + { + case I2CSTATE_NONE: + return "Send start + (first part of) address."; + case I2CSTATE_STARTADDRSEND: + return "Send start + (first part of) address."; + case I2CSTATE_ADDRWFACKNACK: + return "Wait for ACK/NACK on (first part of) address."; + case I2CSTATE_ADDRWF2NDACKNACK: + return "Wait for ACK/NACK on second part of 10 bit address."; + case I2CSTATE_RSTARTADDRSEND: + return "Send repeated start + (first part of) address."; + case I2CSTATE_RADDRWFACKNACK: + return "Wait for ACK/NACK on address sent after repeated start."; + case I2CSTATE_DATASEND: + return "Send data."; + case I2CSTATE_DATAWFACKNACK: + return "Wait for ACK/NACK on data sent."; + case I2CSTATE_WFDATA: + return "Wait for data."; + case I2CSTATE_WFSTOPSENT: + return "Wait for STOP to have been transmitted."; + case I2CSTATE_DONE: + return "Transfer completed successfully."; + default: + return "Unknown state!"; + } +} +#endif + +/**************************************************************************** + * Name: efm32_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ****************************************************************************/ + +static inline void efm32_i2c_sem_wait(FAR struct efm32_i2c_priv_s *priv) +{ + while (sem_wait(&priv->sem_excl) != OK) + { + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: efm32_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be + * processed. + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_I2C_DYNTIMEO +static useconds_t efm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. */ + + return (useconds_t) (CONFIG_EFM32_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/**************************************************************************** + * Name: efm32_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ****************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv) +{ + struct timespec abstime; + int ret; + + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_EFM32_I2CTIMEOSEC > 0 + abstime.tv_sec += CONFIG_EFM32_I2CTIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_EFM32_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * efm32_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec > 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_EFM32_I2CTIMEOMS > 0 + abstime.tv_nsec += CONFIG_EFM32_I2CTIMEOMS * 1000 * 1000; + if (abstime.tv_nsec > 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + + /* Enable I2C interrupts */ + + efm32_i2c_putreg(priv, EFM32_I2C_IEN_OFFSET, I2C_IF_NACK | I2C_IF_ACK | + I2C_IF_MSTOP | I2C_IF_RXDATAV | I2C_IF_ERRORS); + + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->sem_isr, &abstime); + + /* Disable I2C interrupts */ + + efm32_i2c_putreg(priv, EFM32_I2C_IEN_OFFSET, 0); + + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would include + * timeouts and mystery errors reported by sem_timedwait. NOTE that + * we try again if we are awakened by a signal (EINTR). + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->result == I2CRESULT_INPROGRESS); + + i2cvdbg("result: %s elapsed: %d threshold: %d i2c_state %s " + "I2Cx_STATES: %08x I2Cx_IF: %08x\n", + efm32_i2c_result_str(priv->result), elapsed, timeout, + efm32_i2c_state_str(priv->i2c_state), priv->i2c_reg_state, + priv->i2c_reg_if); + + return ret; +} +#else +static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + + /* Get the timeout value */ + +#ifdef CONFIG_EFM32_I2C_DYNTIMEO + timeout = USEC2TICK(efm32_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_EFM32_I2CTIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts are + * currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + start = clock_systimer(); + + do + { + /* Poll by simply calling the timer interrupt handler until it reports + * that it is done. + */ + + efm32_i2c_isr(priv); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while ((priv->result == I2CRESULT_INPROGRESS) && elapsed < timeout); + + i2cvdbg("result: %s elapsed: %d threshold: %d i2c_state %s " + "I2Cx_STATES: %08x I2Cx_IF: %08x\n", + efm32_i2c_result_str(priv->result), elapsed, timeout, + efm32_i2c_state_str(priv->i2c_state), priv->i2c_reg_state, + priv->i2c_reg_if); + + if (elapsed < timeout) + { + return OK; + } + + return -1; +} +#endif + +/**************************************************************************** + * Name: efm32_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ****************************************************************************/ + +static inline void efm32_i2c_sem_post(FAR struct efm32_i2c_priv_s *priv) +{ + sem_post(&priv->sem_excl); +} + +/**************************************************************************** + * Name: efm32_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ****************************************************************************/ + +static inline void efm32_i2c_sem_init(FAR struct efm32_i2c_priv_s *priv) +{ + sem_init(&priv->sem_excl, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->sem_isr, 0, 0); +#endif +} + +/**************************************************************************** + * Name: efm32_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ****************************************************************************/ + +static inline void efm32_i2c_sem_destroy(FAR struct efm32_i2c_priv_s *priv) +{ + sem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->sem_isr); +#endif +} + +/**************************************************************************** + * Name: efm32_i2c_trace* + * + * Description: + * I2C trace instrumentation + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void efm32_i2c_traceclear(FAR struct efm32_i2c_priv_s *priv) +{ + struct efm32_trace_s *trace = &priv->trace[priv->tndx]; + + trace->i2c_state = I2CSTATE_NONE; /* I2C current state of state machine */ + trace->i2c_reg_if = 0; /* I2C I2Cx_IF register */ + trace->i2c_reg_state = 0; /* I2C I2Cx_STATES register */ + trace->count = 0; /* Interrupt count when status change */ + trace->time = 0; /* Time of first status or event */ +} + +static void efm32_i2c_tracereset(FAR struct efm32_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systimer(); + efm32_i2c_traceclear(priv); +} + +static void efm32_i2c_tracenew(FAR struct efm32_i2c_priv_s *priv) +{ + struct efm32_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the states changed? */ + + if ((trace->count == 0) || + (priv->i2c_reg_if != trace->i2c_reg_if) || + (priv->i2c_reg_state != trace->i2c_reg_state) || + (priv->dcnt != trace->dcnt) || + (priv->i2c_state != trace->i2c_state)) + { + /* Yes.. Was it the states changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE - 1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + efm32_i2c_traceclear(priv); + trace->i2c_state = priv->i2c_state; + trace->i2c_reg_state = priv->i2c_reg_state; + trace->i2c_reg_if = priv->i2c_reg_if; + trace->count = 1; + trace->dcnt = priv->dcnt; + trace->time = clock_systimer(); + } + else + { + /* Just increment the count of times that we have seen this states */ + + trace->count++; + } +} + +static void efm32_i2c_tracedump(FAR struct efm32_i2c_priv_s *priv) +{ + struct efm32_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->start_time)); + + for (i = 0; i < priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. I2Cx_STATE: %08x I2Cx_PENDING: %08x dcnt %3d COUNT: %3d " + "STATE: %s(%2d) TIME: %ld\n", + i + 1, trace->i2c_reg_state, trace->i2c_reg_if, trace->dcnt, + trace->count, efm32_i2c_state_str(trace->i2c_state), + trace->i2c_state, (long)(trace->time - priv->start_time)); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/**************************************************************************** + * Name: efm32_i2c_setclock + * + * Description: + * Set the I2C clock + * + ****************************************************************************/ + +static void efm32_i2c_setclock(FAR struct efm32_i2c_priv_s *priv, + uint32_t frequency) +{ + uint32_t div; + + /* Has the I2C bus frequency changed? */ + + if (priv->frequency != frequency) + { + /* Set the CLHR (clock low to high ratio). */ + + efm32_i2c_modifyreg(priv, EFM32_I2C_CTRL_OFFSET, _I2C_CTRL_CLHR_MASK, +#if defined(CONFIG_EFM32_I2C_CLHR_FAST) + _I2C_CTRL_CLHR_FAST /* Ratio is 11:3 */ +#elif defined(CONFIG_EFM32_I2C_CLHR_ASYMMETRIC) + _I2C_CTRL_CLHR_ASYMMETRIC /* Ratio is 6:3 */ +#else /* CLHR STANDARD */ + _I2C_CTRL_CLHR_STANDARD /* Ratio is 4:4 */ +#endif + << _I2C_CTRL_CLHR_SHIFT); + + /* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), + * thus DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 + */ + +#if defined(CONFIG_EFM32_I2C_CLHR_FAST) +# define n (11 + 6) /* Ratio is 11:3 */ +#elif defined(CONFIG_EFM32_I2C_CLHR_ASYMMETRIC) +# define n (6 + 3) /* Ratio is 6:3 */ +#else /* CLHR STANDARD */ +# define n ( 4 + 4) /* Ratio is 4:4 */ +#endif + + div = (BOARD_HFPERCLK_FREQUENCY - (4 * frequency)) / (n * frequency); + + /* Clock divisor must be at least 1 in slave mode according to + * reference manual (in which case there is normally no need to set + * bus frequency). + */ + + if ((efm32_i2c_getreg(priv, EFM32_I2C_CTRL_OFFSET) & I2C_CTRL_SLAVE) && !div) + { + div = 1; + } + + DEBUGASSERT(div <= (_I2C_CLKDIV_DIV_MASK >> _I2C_CLKDIV_DIV_SHIFT)); + + efm32_i2c_putreg(priv, EFM32_I2C_CLKDIV_OFFSET, div); + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: efm32_i2c_isr + * + * Description: + * Common Interrupt Service Routine + * + ****************************************************************************/ + +static int efm32_i2c_isr(struct efm32_i2c_priv_s *priv) +{ + for (; ; ) + { + int regval; + + priv->i2c_reg_if = efm32_i2c_getreg(priv, EFM32_I2C_IF_OFFSET); + priv->i2c_reg_state = efm32_i2c_getreg(priv, EFM32_I2C_STATE_OFFSET); + + /* Check for new trace setup */ + + efm32_i2c_tracenew(priv); + + /* If some sort of fault, abort transfer. */ + + if (priv->i2c_reg_if & I2C_IF_ERRORS) + { + if (priv->i2c_reg_if & I2C_IF_ARBLOST) + { + /* If arbitration fault, it indicates either a slave device not + * responding as expected, or other master which is not supported + * by this SW. */ + + priv->result = I2CRESULT_ARBLOST; + } + else if (priv->i2c_reg_if & I2C_IF_BUSERR) + { + /* A bus error indicates a misplaced start or stop, which should + * not occur in master mode controlled by this SW. + */ + + priv->result = I2CRESULT_BUSERR; + } + + /* If error situation occurred, it is difficult to know exact cause + * and how to resolve. It will be up to a wrapper to determine how to + * handle a fault/recovery if possible. + */ + + priv->i2c_state = I2CSTATE_DONE; + goto done; + } + + switch (priv->i2c_state) + { + /*************************************************** + * Send first start+address (first byte if 10 bit) + */ + + case I2CSTATE_STARTADDRSEND: + if (priv->flags & I2C_M_TEN) + { + if (priv->flags & I2C_M_READ) + { + regval = I2C_READADDR10H(priv->addr); + } + else + { + regval = I2C_WRITEADDR10H(priv->addr); + } + } + else + { + if (priv->flags & I2C_M_READ) + { + regval = I2C_READADDR8(priv->addr); + } + else + { + regval = I2C_WRITEADDR8(priv->addr); + } + } + + if ((priv->flags & I2C_M_READ) && (priv->dcnt == 1)) + { + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_NACK); + } + + /* Data not transmitted until START sent */ + + efm32_i2c_putreg(priv, EFM32_I2C_TXDATA_OFFSET, regval); + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_START); + priv->i2c_state = I2CSTATE_ADDRWFACKNACK; + + goto done; + + /******************************************************* + * Wait for ACK/NACK on address (first byte if 10 bit) + */ + + case I2CSTATE_ADDRWFACKNACK: + if (priv->i2c_reg_if & I2C_IF_NACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_NACK); + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + priv->result = I2CRESULT_NACK; + priv->i2c_state = I2CSTATE_WFSTOPSENT; + } + else if (priv->i2c_reg_if & I2C_IF_ACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_ACK); + + /* If 10 bit address, send 2nd byte of address. */ + + if (priv->flags & I2C_M_TEN) + { + if (priv->flags & I2C_M_READ) + { + regval = I2C_READADDR10L(priv->addr); + } + else + { + regval = I2C_WRITEADDR10L(priv->addr); + } + + efm32_i2c_putreg(priv, EFM32_I2C_TXDATA_OFFSET, regval); + priv->i2c_state = I2CSTATE_ADDRWF2NDACKNACK; + } + else + { + /* Determine whether receiving or sending data */ + + if (priv->flags & I2C_M_READ) + { + priv->i2c_state = I2CSTATE_WFDATA; + } + else + { + priv->i2c_state = I2CSTATE_DATASEND; + continue; + } + } + } + + goto done; + + /****************************************************** + * Wait for ACK/NACK on second byte of 10 bit address + */ + + case I2CSTATE_ADDRWF2NDACKNACK: + if (priv->i2c_reg_if & I2C_IF_NACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_NACK); + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + priv->result = I2CRESULT_NACK; + priv->i2c_state = I2CSTATE_WFSTOPSENT; + } + else if (priv->i2c_reg_if & I2C_IF_ACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_ACK); + + /* If using plain read sequence with 10 bit address, switch to + * send repeated start. + */ + + if (priv->flags & I2C_M_READ) + { + priv->i2c_state = I2CSTATE_RSTARTADDRSEND; + } + + /* Otherwise expected to write 0 or more bytes */ + + else + { + priv->i2c_state = I2CSTATE_DATASEND; + } + continue; + } + + goto done; + + /******************************* + * Send repeated start+address + */ + + case I2CSTATE_RSTARTADDRSEND: + if (priv->flags & I2C_M_TEN) + { + if (priv->flags & I2C_M_READ) + { + regval = I2C_READADDR10H(priv->addr); + } + else + { + regval = I2C_WRITEADDR10H(priv->addr); + } + } + else + { + if (priv->flags & I2C_M_READ) + { + regval = I2C_READADDR8(priv->addr); + } + else + { + regval = I2C_WRITEADDR8(priv->addr); + } + } + + if ((priv->flags & I2C_M_READ) && (priv->dcnt == 1)) + { + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_NACK); + } + + priv->i2c_state = I2CSTATE_RADDRWFACKNACK; + + /* We have to write START cmd first since repeated start, otherwise + * data would be sent first. + */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_START); + efm32_i2c_putreg(priv, EFM32_I2C_TXDATA_OFFSET, regval); + goto done; + + /*********************************************** + * Wait for ACK/NACK on repeated start+address + * (first byte if 10 bit) + */ + + case I2CSTATE_RADDRWFACKNACK: + if (priv->i2c_reg_if & I2C_IF_NACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_NACK); + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + priv->result = I2CRESULT_NACK; + priv->i2c_state = I2CSTATE_WFSTOPSENT; + } + else if (priv->i2c_reg_if & I2C_IF_ACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_ACK); + + /* Determine whether receiving or sending data */ + + if (priv->flags & I2C_M_READ) + { + priv->i2c_state = I2CSTATE_WFDATA; + } + else + { + priv->i2c_state = I2CSTATE_DATASEND; + continue; + } + } + + goto done; + + /***************************** + * Send a data byte to slave + */ + + case I2CSTATE_DATASEND: + /* Reached end of data buffer? */ + + if (priv->dcnt == 0) + { + if (priv->msgc == 0) + { + /* No more message part */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + priv->i2c_state = I2CSTATE_WFSTOPSENT; + goto done; + } + + /* Move to next message part */ + + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->addr = priv->msgv->addr; + priv->msgv++; + priv->msgc--; + + /* Send byte continue with/without restart ? */ + + if (!(priv->flags & I2C_M_NORESTART)) + { + priv->i2c_state = I2CSTATE_RSTARTADDRSEND; + continue; + } + } + + /* Send byte */ + + efm32_i2c_putreg(priv, EFM32_I2C_TXDATA_OFFSET, *priv->ptr++); + priv->dcnt--; + priv->i2c_state = I2CSTATE_DATAWFACKNACK; + goto done; + + /********************************************************* + * Wait for ACK/NACK from slave after sending data to it + */ + + case I2CSTATE_DATAWFACKNACK: + if (priv->i2c_reg_if & I2C_IF_NACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_NACK); + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + priv->result = I2CRESULT_NACK; + priv->i2c_state = I2CSTATE_WFSTOPSENT; + } + else if (priv->i2c_reg_if & I2C_IF_ACK) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_ACK); + priv->i2c_state = I2CSTATE_DATASEND; + continue; + } + goto done; + + /**************************** + * Wait for data from slave + */ + + case I2CSTATE_WFDATA: + if (priv->i2c_reg_if & I2C_IF_RXDATAV) + { + /* Must read out data in order to not block further progress */ + + regval = efm32_i2c_getreg(priv, EFM32_I2C_RXDATA_OFFSET); + + /* Make sure not storing beyond end of buffer just in case */ + + if (priv->dcnt > 0) + { + *(priv->ptr++) = regval; + priv->dcnt--; + } + + /* If we have read all requested data, then the sequence should + * end + */ + + if (priv->dcnt == 0) + { + priv->i2c_state = I2CSTATE_WFSTOPSENT; + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_STOP); + + } + else + { + /* Send ACK and wait for next byte */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_ACK); + + if (priv->dcnt == 1) + { + /* If there is more than one byte to receive and this is + * the next to last byte we need to transmit the NACK + * now, before receiving the last byte. + */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_NACK); + } + } + } + goto done; + + /*********************************** + * Wait for STOP to have been sent + */ + + case I2CSTATE_WFSTOPSENT: + if (priv->i2c_reg_if & I2C_IF_MSTOP) + { + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, I2C_IFC_MSTOP); + priv->i2c_state = I2CSTATE_DONE; + } + + goto done; + + /******************************/ + /* Unexpected state, SW fault */ + /******************************/ + + default: + priv->result = I2CRESULT_SWFAULT; + priv->i2c_state = I2CSTATE_DONE; + goto done; + } + } + +done: + if (priv->i2c_state == I2CSTATE_DONE) + { +#ifndef CONFIG_I2C_POLLED + sem_post(&priv->sem_isr); +#endif + /* Disable interrupt sources when done */ + + efm32_i2c_putreg(priv, EFM32_I2C_IEN_OFFSET, 0); + + /* Update result unless some fault already occurred */ + + if (priv->result == I2CRESULT_INPROGRESS) + { + priv->result = I2CRESULT_DONE; + } + } + + return OK; +} + +#ifndef CONFIG_I2C_POLLED + +/**************************************************************************** + * Name: efm32_i2c0_isr + * + * Description: + * I2C0 interrupt service routine + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_I2C0 +static int efm32_i2c0_isr(int irq, void *context) +{ + return efm32_i2c_isr(&efm32_i2c0_priv); +} +#endif + +/**************************************************************************** + * Name: efm32_i2c1_isr + * + * Description: + * I2C1 interrupt service routine + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_I2C1 +static int efm32_i2c1_isr(int irq, void *context) +{ + return efm32_i2c_isr(&efm32_i2c1_priv); +} +#endif + +#endif + +/**************************************************************************** + * Private Initialization and Deinitialization + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_i2c_hwreset + * + * Description: + * Reset I2C to same state as after a HW reset. + * + ****************************************************************************/ + +static void efm32_i2c_hwreset(FAR struct efm32_i2c_priv_s *priv) +{ + efm32_i2c_putreg(priv, EFM32_I2C_CTRL_OFFSET, _I2C_CTRL_RESETVALUE); + efm32_i2c_putreg(priv, EFM32_I2C_CLKDIV_OFFSET, _I2C_CLKDIV_RESETVALUE); + efm32_i2c_putreg(priv, EFM32_I2C_SADDR_OFFSET, _I2C_SADDR_RESETVALUE); + efm32_i2c_putreg(priv, EFM32_I2C_SADDRMASK_OFFSET, _I2C_SADDRMASK_RESETVALUE); + efm32_i2c_putreg(priv, EFM32_I2C_IEN_OFFSET, _I2C_IEN_RESETVALUE); + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, _I2C_IFC_MASK); + + /* Do not reset route register, setting should be done independently */ +} + +/**************************************************************************** + * Name: efm32_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * Prepare and start an I2C transfer (single master mode only). + * + ****************************************************************************/ + +static int efm32_i2c_init(FAR struct efm32_i2c_priv_s *priv) +{ + int regval; + + /* Power-up and configure GPIOs */ + + /* Enable power and reset the peripheral */ + + /* Enable I2C Clock */ + + modifyreg32(EFM32_CMU_HFPERCLKEN0, 0, priv->config->clk_bit); + + /* Eeset all resgister */ + + efm32_i2c_hwreset(priv); + + /* Configure pins */ + + if (efm32_configgpio(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (efm32_configgpio(priv->config->sda_pin) < 0) + { + return ERROR; + } + + /* Set Route */ + + regval = priv->config->route << _I2C_ROUTE_LOCATION_SHIFT; + + /* and enable pins */ + + regval |= I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN; + + /* Apply it */ + + efm32_i2c_putreg(priv, EFM32_I2C_ROUTE_OFFSET, regval); + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->irq, priv->config->isr); + up_enable_irq(priv->config->irq); +#endif + + efm32_i2c_setclock(priv, 100000); + + /* Enable I2C */ + + efm32_i2c_putreg(priv, EFM32_I2C_CTRL_OFFSET, I2C_CTRL_EN); + + /* Send abort CMD to be done after reset if i2c peripheral timeout is not + * used + */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_ABORT); + + return OK; +} + +/**************************************************************************** + * Name: efm32_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ****************************************************************************/ + +static int efm32_i2c_deinit(FAR struct efm32_i2c_priv_s *priv) +{ + /* Disable I2C */ + + efm32_i2c_hwreset(priv); + + /* Unconfigure GPIO pins */ + + efm32_unconfiggpio(priv->config->scl_pin); + efm32_configgpio(priv->config->sda_pin); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->irq); + irq_detach(priv->config->irq); +#endif + + /* Disable clocking */ + + modifyreg32(EFM32_CMU_HFPERCLKEN0, priv->config->clk_bit, 0); + return OK; +} + +/**************************************************************************** + * Device Driver Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ****************************************************************************/ + +static int efm32_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev; + int ret = OK; + + ASSERT(count); + + if (count == 0 || msgs == NULL) + { + return -1; + } + + /* Ensure that address or flags don't change meanwhile */ + + efm32_i2c_sem_wait(priv); + + /* Reset ptr and dcnt to ensure an unexpected data interrupt doesn't + * overwrite stale data. + */ + + priv->dcnt = 0; + priv->ptr = NULL; + priv->msgv = msgs; + priv->msgc = count; + + /* Reset I2C trace logic */ + + efm32_i2c_tracereset(priv); + + /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !). + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + efm32_i2c_setclock(priv, msgs->frequency); + + /* Prepare for a transfer */ + + priv->result = I2CRESULT_INPROGRESS; + priv->i2c_state = I2CSTATE_STARTADDRSEND; + priv->i2c_reg_if = 0; + priv->i2c_reg_state = 0; + + /* Get run-time data */ + + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->addr = priv->msgv->addr; + priv->msgv++; + priv->msgc--; + + /* Ensure buffers are empty */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, + I2C_CMD_CLEARPC | I2C_CMD_CLEARTX); + if (efm32_i2c_getreg(priv, EFM32_I2C_IF_OFFSET) & I2C_IF_RXDATAV) + { + (void)efm32_i2c_getreg(priv, EFM32_I2C_RXDATA_OFFSET); + } + + /* Clear all pending interrupts prior to starting transfer. */ + + efm32_i2c_putreg(priv, EFM32_I2C_IFC_OFFSET, _I2C_IFC_MASK); + + /* Call once isr to start state machine. I2C interrupt are disabled and will + * be enabled in efm32_i2c_sem_waitdone if CONFIG_I2C_POLLED is NOT defined + */ + + efm32_i2c_isr(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get the + * BUSY flag. + */ + + if (efm32_i2c_sem_waitdone(priv) < 0) + { + ret = -ETIMEDOUT; + + i2cdbg("Timed out: I2Cx_STATE: 0x%04x I2Cx_STATUS: 0x%08x\n", + efm32_i2c_getreg(priv, EFM32_I2C_STATE_OFFSET), + efm32_i2c_getreg(priv, EFM32_I2C_STATUS_OFFSET)); + + /* Abort */ + + efm32_i2c_putreg(priv, EFM32_I2C_CMD_OFFSET, I2C_CMD_ABORT); + } + else + { + /* Check for error status conditions */ + + switch (priv->result) + { + /* Arbitration lost during transfer. */ + + case I2CRESULT_ARBLOST: + ret = -EAGAIN; + break; + + /* NACK received during transfer. */ + + case I2CRESULT_NACK: + ret = -ENXIO; + break; + + /* SW fault. */ + + case I2CRESULT_SWFAULT: + ret = -EIO; + break; + + /* Usage fault. */ + + case I2CRESULT_USAGEFAULT: + ret = -EINTR; + break; + + /* Bus error during transfer (misplaced START/STOP). + * I2C Bus is for some reason busy + */ + + case I2CRESULT_BUSERR: + ret = -EBUSY; + break; + } + } + + /* Dump the trace result */ + + efm32_i2c_tracedump(priv); + + /* Ensure that any ISR happening after we finish can't overwrite any user + * data + */ + + priv->result = I2CRESULT_NONE; + priv->dcnt = 0; + priv->ptr = NULL; + + efm32_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: efm32_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +int efm32_i2c_reset(FAR struct i2c_master_s *dev) +{ + FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + int ret = ERROR; + + ASSERT(dev); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + efm32_i2c_sem_wait(priv); + + /* De-init the port */ + + efm32_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + efm32_configgpio(scl_gpio); + efm32_configgpio(sda_gpio); + + /* Let SDA go high */ + + efm32_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!efm32_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. If the bus + * never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!efm32_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + efm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + efm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave state machines. */ + + efm32_gpiowrite(sda_gpio, 0); + up_udelay(10); + efm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + efm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + efm32_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + efm32_unconfiggpio(sda_gpio); + efm32_unconfiggpio(scl_gpio); + + /* Re-init the port */ + + efm32_i2c_init(priv); + ret = OK; + +out: + /* Release the port for re-use by other clients */ + + efm32_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ****************************************************************************/ + +FAR struct i2c_master_s *efm32_i2cbus_initialize(int port) +{ + struct efm32_i2c_priv_s *priv = NULL; + irqstate_t flags; + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_EFM32_I2C0 + case 0: + priv = (struct efm32_i2c_priv_s *)&efm32_i2c0_priv; + break; +#endif + +#ifdef CONFIG_EFM32_I2C1 + case 1: + priv = (struct efm32_i2c_priv_s *)&efm32_i2c1_priv; + break; +#endif + + default: + return NULL; + } + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + efm32_i2c_sem_init(priv); + efm32_i2c_init(priv); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/**************************************************************************** + * Name: efm32_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ****************************************************************************/ + +int efm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev; + irqstate_t flags; + + ASSERT(dev); + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + efm32_i2c_deinit(priv); + + /* Release unused resources */ + + efm32_i2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_EFM32_I2C0 || CONFIG_EFM32_I2C1 */ diff --git a/arch/arm/src/efm32/efm32_i2c.h b/arch/arm/src/efm32/efm32_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..16e51434bef338805e641197a898d2ca2cb2ac98 --- /dev/null +++ b/arch/arm/src/efm32/efm32_i2c.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_I2C_H +#define __ARCH_ARM_SRC_EFM32_EFM32_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *efm32_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: efm32_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the efm32_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int efm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_I2C_H */ diff --git a/arch/arm/src/efm32/efm32_idle.c b/arch/arm/src/efm32/efm32_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..62d4e6315ba8021e99b4390648d63b2dce98d3b6 --- /dev/null +++ b/arch/arm/src/efm32/efm32_idle.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_idle.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" +#include "efm32_pm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + * REVISIT: These power management hooks were taken with no modification + * from the EFM32 implementation and need review against EFM32 reduced + * power modes. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + efm32_pmstop(true); + break; + + case PM_SLEEP: + (void)efm32_pmstandby(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +} diff --git a/arch/arm/src/efm32/efm32_irq.c b/arch/arm/src/efm32/efm32_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..821d5cdc76d469b0538df013ede64f8509ddecff --- /dev/null +++ b/arch/arm/src/efm32/efm32_irq.c @@ -0,0 +1,635 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_irq.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#include "chip.h" +#include "efm32_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void efm32_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32) + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 48) + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64) + lldbg(" %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY)); +#endif +#endif +#endif + leave_critical_section(flags); +} +#else +# define efm32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: efm32_nmi, efm32_busfault, efm32_usagefault, efm32_pendsv, + * efm32_dbgmonitor, efm32_pendsv, efm32_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int efm32_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int efm32_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int efm32_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int efm32_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int efm32_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int efm32_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: efm32_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void efm32_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: efm32_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int efm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= EFM32_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt or (a second level GPIO interrupt) */ + + if (irq >= EFM32_IRQ_INTERRUPTS) + { + /* Is this an external interrupt? */ + + if (irq < NR_VECTORS) + { + /* Yes.. We have support implemented for vectors 0-95 */ + + DEBUGASSERT(irq < (EFM32_IRQ_INTERRUPTS + 96)); + +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32) + /* Check for vectors 0-31 */ + + if (irq < EFM32_IRQ_INTERRUPTS + 32) +#endif + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS); + } +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32) + /* Yes.. Check for vectors 32-63 */ + + else +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64) + if (irq < EFM32_IRQ_INTERRUPTS + 64) +#endif + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 32); + } +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64) + /* Yes.. Check for vectors 64-95 */ + + else +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 96) + /* Yes.. Check for vectors 64-95 */ + + if (irq < NR_VECTORS) +#endif + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 64); + } +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 96) + else + { + return -EINVAL; /* We should never get here */ + } +#endif +#endif +#endif + } + else + { + return -EINVAL; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == EFM32_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == EFM32_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == EFM32_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == EFM32_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return -EINVAL; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32) + putreg32(0, NVIC_IRQ32_63_ENABLE); +#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64) + putreg32(0, NVIC_IRQ64_95_ENABLE); +#endif +#endif + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Colorize the interrupt stack for debug purposes */ + + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(EFM32_IRQ_SVCALL, up_svcall); + irq_attach(EFM32_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + efm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(EFM32_IRQ_MEMFAULT, up_memfault); + up_enable_irq(EFM32_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(EFM32_IRQ_NMI, efm32_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(EFM32_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault); + irq_attach(EFM32_IRQ_USAGEFAULT, efm32_usagefault); + irq_attach(EFM32_IRQ_PENDSV, efm32_pendsv); + irq_attach(EFM32_IRQ_DBGMONITOR, efm32_dbgmonitor); + irq_attach(EFM32_IRQ_RESERVED, efm32_reserved); +#endif + + efm32_dumpnvic("initial", NR_VECTORS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS +#ifdef CONFIG_EFM32_GPIO_IRQ + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + + efm32_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (efm32_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= EFM32_IRQ_INTERRUPTS) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_EFM32_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + efm32_gpioirqdisable(irq); + } +#endif + + efm32_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (efm32_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= EFM32_IRQ_INTERRUPTS) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_EFM32_GPIO_IRQ + else + { + /* Maybe it is a (derived) PIO IRQ */ + + efm32_gpioirqenable(irq); + } +#endif + + efm32_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= EFM32_IRQ_MEMFAULT && irq < NR_VECTORS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < EFM32_IRQ_INTERRUPTS) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else (irq < NR_VECTORS) + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= EFM32_IRQ_INTERRUPTS; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + else + { + /* Must be a GPIO interrupt */ + + return -EINVAL; + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + efm32_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/efm32/efm32_leserial.c b/arch/arm/src/efm32/efm32_leserial.c new file mode 100644 index 0000000000000000000000000000000000000000..e57af783531a4c39980ec868be90b3534fed7043 --- /dev/null +++ b/arch/arm/src/efm32/efm32_leserial.c @@ -0,0 +1,887 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_leserial.c + * + * Copyright (C) 2024 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/efm32_leuart.h" +#include "efm32_config.h" +#include "efm32_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Is there at least one UART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_LEUART_DEVICE +# warning "No LEUARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which LEUART with be ttyLE0/console and which ttyLE1? The console will always + * be ttyLE0. If there is no console then will use the lowest numbered LEUART. + */ + +/* First pick the console and ttys0. This could be either LEUART0-1 */ + +#if defined(CONFIG_LEUART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_leuart0port /* LEUART0 is console */ +# define TTYLE0_DEV g_leuart0port /* LEUART0 is ttyLE0 */ +# define LEUART0_ASSIGNED 1 +#elif defined(CONFIG_LEUART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_leuart1port /* LEUART1 is console */ +# define TTYLE0_DEV g_leuart1port /* LEUART1 is ttyLE0 */ +# define LEUART1_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_EFM32_LEUART0) +# define TTYLE0_DEV g_leuart0port /* LEUART0 is ttyLE0 */ +# define LEUART0_ASSIGNED 1 +# elif defined(CONFIG_EFM32_LEUART1) +# define TTYLE0_DEV g_leuart1port /* LEUART1 is ttyLE0 */ +# define LEUART1_ASSIGNED 1 +# endif +#endif + +/* Pick ttyLE1. This could be any of LEUART0-1, excluding the and the + * LEUART already selected for ttyLE0 + */ + +#if defined(CONFIG_EFM32_LEUART0) && !defined(LEUART0_ASSIGNED) +# define TTYLE1_DEV g_leuart0port /* LEUART0 is ttyLE1 */ +# define LEUART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_LEUART1) && !defined(LEUART1_ASSIGNED) +# define TTYLE1_DEV g_leuart1port /* LEUART1 is ttyLE1 */ +# define LEUART1_ASSIGNED 1 +#endif + +/* TX/RX interrupts */ + +#define EFM32_TXERR_INTS (LEUART_IEN_TXOF) +#define EFM32_RXERR_INTS (LEUART_IEN_RXOF | LEUART_IEN_PERR | \ + LEUART_IEN_FERR) +#ifdef CONFIG_DEBUG +# define EFM32_TX_INTS (LEUART_IEN_TXBL | EFM32_TXERR_INTS) +# define EFM32_RX_INTS (LEUART_IEN_RXDATAV | EFM32_RXERR_INTS) +#else +# define EFM32_TX_INTS LEUART_IEN_TXBL +# define EFM32_RX_INTS LEUART_IEN_RXDATAV +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct efm32_config_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + xcpt_t handler; /* Interrupt handler */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this LEUART (for enable) */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ + bool stop2; /* True: 2 stop bits */ +}; + +struct efm32_leuart_s +{ + const struct efm32_config_s *config; + uint16_t ien; /* Interrupts enabled */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t efm32_serialin(struct efm32_leuart_s *priv, int offset); +static inline void efm32_serialout(struct efm32_leuart_s *priv, int offset, + uint32_t value); +static inline void efm32_setuartint(struct efm32_leuart_s *priv); + +static void efm32_restoreuartint(struct efm32_leuart_s *priv, uint32_t ien); +static void efm32_disableuartint(struct efm32_leuart_s *priv, uint32_t *ien); +static int efm32_setup(struct uart_dev_s *dev); +static void efm32_shutdown(struct uart_dev_s *dev); +static int efm32_attach(struct uart_dev_s *dev); +static void efm32_detach(struct uart_dev_s *dev); +static int efm32_interrupt(struct uart_dev_s *dev); +#if defined(CONFIG_EFM32_LEUART0) +static int efm32_leuart0_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_LEUART1) +static int efm32_leuart1_interrupt(int irq, void *context); +#endif +static int efm32_ioctl(struct file *filep, int cmd, unsigned long arg); +static int efm32_receive(struct uart_dev_s *dev, uint32_t *status); +static void efm32_rxint(struct uart_dev_s *dev, bool enable); +static bool efm32_rxavailable(struct uart_dev_s *dev); +static void efm32_send(struct uart_dev_s *dev, int ch); +static void efm32_txint(struct uart_dev_s *dev, bool enable); +static bool efm32_txready(struct uart_dev_s *dev); +static bool efm32_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_leuart_ops = +{ + .setup = efm32_setup, + .shutdown = efm32_shutdown, + .attach = efm32_attach, + .detach = efm32_detach, + .ioctl = efm32_ioctl, + .receive = efm32_receive, + .rxint = efm32_rxint, + .rxavailable = efm32_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = efm32_send, + .txint = efm32_txint, + .txready = efm32_txready, + .txempty = efm32_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_EFM32_LEUART0 +static char g_leuart0rxbuffer[CONFIG_LEUART0_RXBUFSIZE]; +static char g_leuart0txbuffer[CONFIG_LEUART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_EFM32_LEUART1 +static char g_leuart1rxbuffer[CONFIG_LEUART1_RXBUFSIZE]; +static char g_leuart1txbuffer[CONFIG_LEUART1_TXBUFSIZE]; +#endif + +/* This describes the state of the EFM32 LEUART0 port. */ + +#ifdef CONFIG_EFM32_LEUART0 +static const struct efm32_config_s g_leuart0config = +{ + .uartbase = EFM32_LEUART0_BASE, + .handler = efm32_leuart0_interrupt, + .baud = CONFIG_LEUART0_BAUD, + .irq = EFM32_IRQ_LEUART0, + .parity = CONFIG_LEUART0_PARITY, + .bits = CONFIG_LEUART0_BITS, + .stop2 = CONFIG_LEUART0_2STOP, +}; + +static struct efm32_leuart_s g_leuart0priv = +{ + .config = &g_leuart0config, +}; + +static struct uart_dev_s g_leuart0port = +{ + .recv = + { + .size = CONFIG_LEUART0_RXBUFSIZE, + .buffer = g_leuart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_LEUART0_TXBUFSIZE, + .buffer = g_leuart0txbuffer, + }, + .ops = &g_leuart_ops, + .priv = &g_leuart0priv, +}; +#endif + +/* This describes the state of the EFM32 LEUART1 port. */ + +#ifdef CONFIG_EFM32_LEUART1 +static struct efm32_config_s g_leuart1config = +{ + .uartbase = EFM32_LEUART1_BASE, + .handler = efm32_leuart1_interrupt, + .baud = CONFIG_LEUART1_BAUD, + .irq = EFM32_IRQ_LEUART1, + .parity = CONFIG_LEUART1_PARITY, + .bits = CONFIG_LEUART1_BITS, + .stop2 = CONFIG_LEUART1_2STOP, +}; + +static struct efm32_leuart_s g_leuart1priv = +{ + .config = &g_leuart1config, +}; + +static struct uart_dev_s g_leuart1port = +{ + .recv = + { + .size = CONFIG_LEUART1_RXBUFSIZE, + .buffer = g_leuart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_LEUART1_TXBUFSIZE, + .buffer = g_leuart1txbuffer, + }, + .ops = &g_leuart_ops, + .priv = &g_leuart1priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_serialin + ****************************************************************************/ + +static inline uint32_t efm32_serialin(struct efm32_leuart_s *priv, int offset) +{ + return getreg32(priv->config->uartbase + offset); +} + +/**************************************************************************** + * Name: efm32_serialout + ****************************************************************************/ + +static inline void efm32_serialout(struct efm32_leuart_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->config->uartbase + offset); +} + +/**************************************************************************** + * Name: efm32_setuartint + ****************************************************************************/ + +static inline void efm32_setuartint(struct efm32_leuart_s *priv) +{ + efm32_serialout(priv, EFM32_LEUART_IEN_OFFSET, priv->ien); +} + +/**************************************************************************** + * Name: efm32_restoreuartint + ****************************************************************************/ + +static void efm32_restoreuartint(struct efm32_leuart_s *priv, uint32_t ien) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ien */ + + flags = enter_critical_section(); + priv->ien = ien; + efm32_setuartint(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_disableuartint + ****************************************************************************/ + +static void efm32_disableuartint(struct efm32_leuart_s *priv, uint32_t *ien) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ien) + { + *ien = priv->ien; + } + + efm32_restoreuartint(priv, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int efm32_setup(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_LEUART_CONFIG + const struct efm32_config_s *config = priv->config; + + /* Configure the UART as an RS-232 UART */ + + efm32_leuartconfigure(config->uartbase, config->baud, config->parity, + config->bits, config->stop2); +#endif + + /* Make sure that all interrupts are disabled */ + + efm32_restoreuartint(priv, 0); + return OK; +} + +/**************************************************************************** + * Name: efm32_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void efm32_shutdown(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + + /* Disable interrupts */ + + efm32_restoreuartint(priv, 0); + + /* Reset the LEUART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + */ + + efm32_leuart_reset(priv->config->uartbase); +} + +/**************************************************************************** + * Name: efm32_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int efm32_attach(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + const struct efm32_config_s *config = priv->config; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(config->irq, config->handler); + if (ret >= 0) + { + up_enable_irq(config->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: efm32_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void efm32_detach(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + const struct efm32_config_s *config = priv->config; + + /* Disable interrupts */ + + efm32_restoreuartint(priv, 0); + up_disable_irq(config->irq); + + /* Detach from the interrupt(s) */ + + irq_detach(config->irq); +} + +/**************************************************************************** + * Name: efm32_interrupt + * + * Description: + * This is the common UART RX interrupt handler. + * + ****************************************************************************/ + +static int efm32_interrupt(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + uint32_t intflags; + + DEBUGASSERT(priv); + + /* Read the interrupt flags register */ + + intflags = efm32_serialin(priv, EFM32_LEUART_IF_OFFSET); + + /* Clear pending interrupts by writing to the interrupt flag clear + * register. + */ + + efm32_serialout(priv, EFM32_LEUART_IFC_OFFSET, intflags); + + /* Check if the receive data is available is full (RXDATAV). */ + + if ((intflags & LEUART_IEN_RXDATAV) != 0) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + + /* Check if the transmit data buffer became empty */ + + if ((intflags & LEUART_IEN_TXBL) != 0) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + } + +#ifdef CONFIG_DEBUG + /* Check for receive errors */ + + if ((intflags & EFM32_RXERR_INTS) != 0) + { + /* RXOF - RX Overflow Interrupt Enable + * RXUF - RX Underflow Interrupt Enable + * TXUF - TX Underflow Interrupt Enable + * PERR - Parity Error Interrupt Enable + * FERR - Framing Error Interrupt Enable + */ + + lldbg("RX ERROR: %08x\n", intflags); + } + + /* Check for transmit errors */ + + if ((intflags & EFM32_TXERR_INTS) != 0) + { + /* TXOF - TX Overflow Interrupt Enable */ + + lldbg("RX ERROR: %08x\n", intflags); + } +#endif + + return OK; +} + +#if defined(CONFIG_EFM32_LEUART0) +static int efm32_leuart0_interrupt(int irq, void *context) +{ + return efm32_interrupt(&g_leuart0port); +} +#endif + +#if defined(CONFIG_EFM32_LEUART1) +static int efm32_leuart1_interrupt(int irq, void *context) +{ + return efm32_interrupt(&g_leuart1port); +} +#endif + +/**************************************************************************** + * Name: efm32_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int efm32_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + struct inode *inode; + struct uart_dev_s *dev; + struct efm32_leuart_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct efm32_leuart_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: efm32_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int efm32_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + uint32_t rxdatax; + + /* Get error status information: + * + * FERR Data Framing Error + * PERR Data Parity Error + */ + + rxdatax = efm32_serialin(priv, EFM32_LEUART_RXDATAX_OFFSET); + + /* Return status information */ + + if (status) + { + *status = rxdatax; + } + + /* Then return the actual received byte. */ + + return (int)(rxdatax & _LEUART_RXDATAX_RXDATA_MASK); +} + +/**************************************************************************** + * Name: efm32_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void efm32_rxint(struct uart_dev_s *dev, bool enable) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ien |= EFM32_RX_INTS; + efm32_setuartint(priv); +#endif + } + else + { + priv->ien &= ~EFM32_RX_INTS; + efm32_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool efm32_rxavailable(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + + /* Return true if the receive data is available (RXDATAV). */ + + return (efm32_serialin(priv, EFM32_LEUART_STATUS_OFFSET) & LEUART_STATUS_RXDATAV) != 0; +} + +/**************************************************************************** + * Name: efm32_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void efm32_send(struct uart_dev_s *dev, int ch) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + efm32_serialout(priv, EFM32_LEUART_TXDATA_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: efm32_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void efm32_txint(struct uart_dev_s *dev, bool enable) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ien |= EFM32_TX_INTS; + efm32_setuartint(priv); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ien &= ~EFM32_TX_INTS; + efm32_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_txready + * + * Description: + * Return true if the transmit data register is not full + * + ****************************************************************************/ + +static bool efm32_txready(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + + /* The TX Buffer Level (TXBL) status bit indicates the level of the + * transmit buffer. Set when the transmit buffer is empty, and cleared + * when it is full. + */ + + return (efm32_serialin(priv, EFM32_LEUART_STATUS_OFFSET) & LEUART_STATUS_TXBL) != 0; +} + +/**************************************************************************** + * Name: efm32_txempty + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool efm32_txempty(struct uart_dev_s *dev) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv; + + /* TX Complete (TXC) is set when a transmission has completed and no more + * data is available in the transmit buffer. + */ + + return (efm32_serialin(priv, EFM32_LEUART_STATUS_OFFSET) & LEUART_STATUS_TXC) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in efm32_consoleinit() and main clock iniialization + * performed in efm32_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit() + */ + + efm32_restoreuartint(TTYLE0_DEV.priv, 0); +#ifdef TTYLE1_DEV + efm32_restoreuartint(TTYLE1_DEV.priv, 0); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + efm32_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyLE0", &TTYLE0_DEV); +#ifdef TTYLE1_DEV + (void)uart_register("/dev/ttyLE1", &TTYLE1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_CONSOLE +int up_putc(int ch) +{ + struct efm32_leuart_s *priv = (struct efm32_leuart_s *)CONSOLE_DEV.priv; + uint32_t ien; + + efm32_disableuartint(priv, &ien); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + efm32_lowputc('\r'); + } + + efm32_lowputc(ch); + efm32_restoreuartint(priv, ien); + return ch; +} +#endif + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_CONSOLE +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + efm32_lowputc('\r'); + } + + efm32_lowputc(ch); + return ch; +} +#endif + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/efm32/efm32_lowputc.c b/arch/arm/src/efm32/efm32_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..b3fa2ee3866e0077a4bf4db7595c3d358cfd7937 --- /dev/null +++ b/arch/arm/src/efm32/efm32_lowputc.c @@ -0,0 +1,785 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_lowputc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "chip/efm32_memorymap.h" +#include "chip/efm32_usart.h" +#include "chip/efm32_leuart.h" +#include "chip/efm32_cmu.h" + +#include "efm32_gpio.h" +#include "efm32_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Console U[S]ART base address */ + +#if defined(HAVE_UART_CONSOLE) +# if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_USART0_BASE +# define CONSOLE_BAUD CONFIG_USART0_BAUD +# define CONSOLE_PARITY CONFIG_USART0_PARITY +# define CONSOLE_NBITS CONFIG_UART0_BITS +# define CONSOLE_2STOP CONFIG_UART0_2STOP +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_USART1_BASE +# define CONSOLE_BAUD CONFIG_USART1_BAUD +# define CONSOLE_PARITY CONFIG_USART1_PARITY +# define CONSOLE_NBITS CONFIG_UART1_BITS +# define CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_USART2_BASE +# define CONSOLE_BAUD CONFIG_USART2_BAUD +# define CONSOLE_PARITY CONFIG_USART2_PARITY +# define CONSOLE_NBITS CONFIG_UART2_BITS +# define CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_UART0_BASE +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_NBITS CONFIG_UART0_BITS +# define CONSOLE_2STOP CONFIG_UART0_2STOP +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_UART1_BASE +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_NBITS CONFIG_UART1_BITS +# define CONSOLE_2STOP CONFIG_UART1_2STOP +# else +# error No U[S]ART console is selected???? Internal craziness!!! +# endif +#elif defined(HAVE_LEUART_CONSOLE) +# if defined(CONFIG_LEUART0_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_LEUART0_BASE +# define CONSOLE_BAUD CONFIG_LEUART0_BAUD +# define CONSOLE_PARITY CONFIG_LEUART0_PARITY +# define CONSOLE_NBITS CONFIG_LEUART0_BITS +# define CONSOLE_2STOP CONFIG_LEUART0_2STOP +# elif defined(CONFIG_LEUART1_SERIAL_CONSOLE) +# define CONSOLE_BASE EFM32_LEUART1_BASE +# define CONSOLE_BAUD CONFIG_LEUART1_BAUD +# define CONSOLE_PARITY CONFIG_LEUART1_PARITY +# define CONSOLE_NBITS CONFIG_LEUART1_BITS +# define CONSOLE_2STOP CONFIG_LEUART1_2STOP +# else +# error No U[S]ART console is selected???? Internal craziness!!! +# endif +#endif /* HAVE_UART_CONSOLE */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_uart_setbaud + * + * Description: + * Set optimal oversampling and set the baud for this U[S]ART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static void efm32_uart_setbaud(uintptr_t base, uint32_t baud) +{ + uint64_t clkdiv; + uint64_t maxover; + uint32_t oversample; + uint32_t regval; + uint32_t ovs; + + /* Select oversampling. We would like to oversample at the standard value + * of 16, but we may not be able to achieve the baud with sufficient + * accuracy if the baud is close to the HFPERCLK frequency. + * + * USART baud is generated according to: + * + * baud = fHFPERCLK/(oversample * (1 + CLKDIV/256)) + * + * Or, equivalently: + * + * CLKDIV = 256 * (fHFPERCLK / (oversample * baud) - 1) + * oversample = 256 * fHFPERCLK / (baud * (CLKDIV + 256)) + * + * Suppose we insist on a CLKDIV >= 24, then: + * + * MAXoversample = 256 * fHFPERCLK / (280 * baud)) + * + * Example 1: fHPERCLK = 32MHz, baud=115200 + * MAXoversample = 254.0, Use oversample = 16 + * CLKDIV = 4188.4 + * baud = 115200.0 + * Example 2: fHPERCLK = 32.768KHz, baud=2400 + * MAXoversample = 12.5, Use oversample = 8 + * CLKDIV = 180.90 + * baud = 2400.0 + */ + + maxover = (((uint64_t)BOARD_HFPERCLK_FREQUENCY << 8) / 280) / baud; + if (maxover >= 16) + { + DEBUGASSERT(baud <= (BOARD_HFPERCLK_FREQUENCY / 16)); + oversample = 16; + ovs = USART_CTRL_OVS_X16; + } + else if (maxover >= 8) + { + DEBUGASSERT(baud <= (BOARD_HFPERCLK_FREQUENCY / 8)); + oversample = 8; + ovs = USART_CTRL_OVS_X8; + } + else if (maxover >= 6) + { + DEBUGASSERT(baud <= (BOARD_HFPERCLK_FREQUENCY / 6)); + oversample = 6; + ovs = USART_CTRL_OVS_X6; + } + else /* if (maxover >= 4) */ + { + DEBUGASSERT(maxover >= 4 && baud <= (BOARD_HFPERCLK_FREQUENCY / 4)); + oversample = 4; + ovs = USART_CTRL_OVS_X4; + } + + /* CLKDIV in asynchronous mode is given by: + * + * CLKDIV = 256 * (fHFPERCLK / (oversample * baud) - 1) + * + * or + * + * CLKDIV = (256 * fHFPERCLK) / (oversample * baud) - 256 + */ + + clkdiv = ((uint64_t)BOARD_HFPERCLK_FREQUENCY << 8) / ((uint64_t)baud * oversample); + if (clkdiv > 256) + { + clkdiv -= 256; + } + else + { + clkdiv = 0; + } + + /* Set up the selected oversampling */ + + regval = getreg32(base + EFM32_USART_CTRL_OFFSET); + regval &= ~_USART_CTRL_OVS_MASK; + regval |= ovs; + putreg32(regval, base + EFM32_USART_CTRL_OFFSET); + + /* Set up the selected baud divisor. The computation above already took + * in account of _USART_CLKDIV_DIV_SHIFT + */ + + regval = (uint32_t)clkdiv & _USART_CLKDIV_MASK; + putreg32(regval, base + EFM32_USART_CLKDIV_OFFSET); +} +#endif + +/**************************************************************************** + * Name: efm32_leuart_setbaud + * + * Description: + * Set optimal oversampling and set the baud for this U[S]ART. + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_DEVICE +static void efm32_leuart_setbaud(uintptr_t base, uint32_t baud) +{ + uint32_t clkdiv; + + /* Baud is configured by: + * + * baud = fLEUART / (1 + CLKDIV / 256) + * + * Or + * + * CLKDIV = 256 * (fLEUART / baud - 1) + * CLKDIV = (256 * fLEUART) / baud - 256 + */ + + clkdiv = (BOARD_LFBCLK_FREQUENCY << 8) / baud; + if (clkdiv > 256) + { + clkdiv -= 256; + } + else + { + clkdiv = 0; + } + + DEBUGASSERT(clkdiv <= _LEUART_CLKDIV_MASK); + + /* Set up the selected baud */ + + putreg32((uint32_t)clkdiv & _LEUART_CLKDIV_DIV_MASK, + base + EFM32_LEUART_CLKDIV_OFFSET); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void efm32_lowsetup(void) +{ +#if defined(HAVE_UART_DEVICE) || defined(HAVE_LEUART_DEVICE) + uint32_t regval; +#endif + +#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE) + /* Enable clocking to configured UART/USART interfaces */ + + regval = getreg32(EFM32_CMU_HFPERCLKEN0); + regval &= ~(CMU_HFPERCLKEN0_USART0 + | CMU_HFPERCLKEN0_USART1 +#ifdef CONFIG_EFM32_HAVE_USART2 + | CMU_HFPERCLKEN0_USART2 +#endif +#ifdef CONFIG_EFM32_HAVE_UART0 + | CMU_HFPERCLKEN0_UART0 +#endif +#ifdef CONFIG_EFM32_HAVE_UART1 + | CMU_HFPERCLKEN0_UART1 +#endif + ); + +#ifdef CONFIG_EFM32_USART0 + regval |= CMU_HFPERCLKEN0_USART0; +#endif + +#ifdef CONFIG_EFM32_USART1 + regval |= CMU_HFPERCLKEN0_USART1; +#endif + +#ifdef CONFIG_EFM32_USART2 + regval |= CMU_HFPERCLKEN0_USART2; +#endif + +#ifdef CONFIG_EFM32_UART0 + regval |= CMU_HFPERCLKEN0_UART0; +#endif + +#ifdef CONFIG_EFM32_UART1 + regval |= CMU_HFPERCLKEN0_UART1; +#endif + + putreg32(regval, EFM32_CMU_HFPERCLKEN0); +#endif /* HAVE_UART_DEVICE */ + +#ifdef HAVE_LEUART_DEVICE + /* Enable the LE interface clock must be enabled in CMU_HFCORECLKEN0 */ + + regval = getreg32(EFM32_CMU_HFCORECLKEN0); + regval |= CMU_HFCORECLKEN0_LE; + putreg32(regval, EFM32_CMU_HFCORECLKEN0); + + /* Enable clocking to configured LEUART interfaces */ + + regval = getreg32(EFM32_CMU_LFBCLKEN0); + regval &= ~(CMU_LFBCLKEN0_LEUART0 +#ifdef CONFIG_EFM32_LEUART1 + | CMU_LFBCLKEN0_LEUART1 +#endif + ); + +#ifdef CONFIG_EFM32_LEUART0 + regval |= CMU_LFBCLKEN0_LEUART0; +#endif + +#ifdef CONFIG_EFM32_LEUART1 + regval |= CMU_LFBCLKEN0_LEUART1; +#endif + + putreg32(regval, EFM32_CMU_LFBCLKEN0); +#endif /* HAVE_LEUART_DEVICE */ + +#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE) + /* Enable output on U[S]ART output pins */ + +#ifdef CONFIG_EFM32_USART0 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_USART0_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART0_TX_GPIO); +#ifdef CONFIG_EFM32_USART0_ISSPI + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART0_CLK_GPIO); +#endif +#endif + +#ifdef CONFIG_EFM32_USART1 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_USART1_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART1_TX_GPIO); +#ifdef CONFIG_EFM32_USART1_ISSPI + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART1_CLK_GPIO); +#endif +#endif + +#ifdef CONFIG_EFM32_USART2 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_USART2_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART2_TX_GPIO); +#ifdef CONFIG_EFM32_USART2_ISSPI + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_USART2_CLK_GPIO); +#endif +#endif + +#ifdef CONFIG_EFM32_UART0 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_UART0_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_UART0_TX_GPIO); +#endif + +#ifdef CONFIG_EFM32_UART1 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_UART1_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_UART1_TX_GPIO); +#endif +#endif /* HAVE_UART_DEVICE */ + +#ifdef HAVE_LEUART_DEVICE + /* Enable output on LEUART output pins */ + +#ifdef CONFIG_EFM32_LEUART0 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_LEUART0_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_LEUART0_TX_GPIO); +#endif + +#ifdef CONFIG_EFM32_LEUART1 + efm32_configgpio(GPIO_INPUT | GPIO_INT_NONE | BOARD_LEUART1_RX_GPIO); + efm32_configgpio(GPIO_OUTPUT_PUSHPULL | GPIO_OUTPUT_CLEAR | + GPIO_DRIVE_STANDARD | BOARD_LEUART1_TX_GPIO); +#endif +#endif /* HAVE_LEUART_DEVICE */ + +#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE) + /* Set location in the U[S]ART ROUTE registers */ + +#ifdef CONFIG_EFM32_USART0 + regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | + (BOARD_USART0_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT)); +#ifdef CONFIG_EFM32_USART0_ISSPI + regval |= USART_ROUTE_CLKPEN; +#endif + putreg32(regval, EFM32_USART0_ROUTE); +#endif + +#ifdef CONFIG_EFM32_USART1 + regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | + (BOARD_USART1_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT)); +#ifdef CONFIG_EFM32_USART1_ISSPI + regval |= USART_ROUTE_CLKPEN; +#endif + putreg32(regval, EFM32_USART1_ROUTE); +#endif + +#ifdef CONFIG_EFM32_USART2 + regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | + (BOARD_USART2_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT)); +#ifdef CONFIG_EFM32_USART2_ISSPI + regval |= USART_ROUTE_CLKPEN; +#endif + putreg32(regval, EFM32_USART2_ROUTE); +#endif + +#ifdef CONFIG_EFM32_UART0 + regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | + (BOARD_UART0_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT)); + putreg32(regval, EFM32_UART0_ROUTE); +#endif + +#ifdef CONFIG_EFM32_UART1 + regval = (USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | + (BOARD_UART1_ROUTE_LOCATION << _USART_ROUTE_LOCATION_SHIFT)); + putreg32(regval, EFM32_UART1_ROUTE); +#endif +#endif /* HAVE_UART_DEVICE */ + +#ifdef HAVE_LEUART_DEVICE + /* Set location in the LEUART ROUTE registers */ + +#ifdef CONFIG_EFM32_LEUART0 + regval = (LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | + (BOARD_LEUART0_ROUTE_LOCATION << _LEUART_ROUTE_LOCATION_SHIFT)); + putreg32(regval, EFM32_LEUART0_ROUTE); +#endif + +#ifdef CONFIG_EFM32_LEUART1 + regval = (LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | + (BOARD_LEUART1_ROUTE_LOCATION << _LEUART_ROUTE_LOCATION_SHIFT)); + putreg32(regval, EFM32_LEUART1_ROUTE); +#endif +#endif /* HAVE_LEUART_DEVICE */ + +#if defined(HAVE_UART_CONSOLE) + /* Configure the U[S]ART serial console */ + + efm32_uartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_PARITY, + CONSOLE_NBITS, CONSOLE_2STOP); + +#elif defined(HAVE_LEUART_CONSOLE) + /* Configure the LEUART serial console */ + + efm32_leuartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_PARITY, + CONSOLE_NBITS, CONSOLE_2STOP); + +#endif +} + +/**************************************************************************** + * Name: efm32_lowputc + * + * Description: + * Output one character to the UART using a simple polling method. + * + ****************************************************************************/ + +#if defined(HAVE_UART_CONSOLE) +void efm32_lowputc(uint32_t ch) +{ + /* The TX Buffer Level (TXBL) status bit indicates the level of the + * transmit buffer. If TXBIL is set, TXBL is set whenever the transmit + * buffer is half-full or empty. + */ + + while ((getreg32(CONSOLE_BASE + EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) == 0); + + /* Then send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE + EFM32_USART_TXDATA_OFFSET); +} + +#elif defined(HAVE_LEUART_CONSOLE) +void efm32_lowputc(uint32_t ch) +{ + /* The TX Buffer Level (TXBL) status bit indicates the level of the + * transmit buffer. If TXBIL is set, TXBL is set whenever the transmit + * buffer is half-full or empty. + */ + + while ((getreg32(CONSOLE_BASE + EFM32_LEUART_STATUS_OFFSET) & LEUART_STATUS_TXBL) == 0); + + /* Then send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE + EFM32_LEUART_TXDATA_OFFSET); +} +#endif + +/**************************************************************************** + * Name: efm32_uartconfigure + * + * Description: + * Configure a U[S]ART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void efm32_uartconfigure(uintptr_t base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2) +{ + uint32_t regval = 0; + + /* Make sure that the U[S]ART registers are in the reset state (except for + * ROUTE information which must be preserved). + */ + + efm32_uart_reset(base); + + /* Configure number of data bits */ + + switch (nbits) + { + case 4: + regval |= USART_FRAME_DATABITS_FOUR; + break; + + case 5: + regval |= USART_FRAME_DATABITS_FIVE; + break; + + case 6: + regval |= USART_FRAME_DATABITS_SIX; + break; + + case 7: + regval |= USART_FRAME_DATABITS_SEVEN; + break; + + default: + case 8: + regval |= USART_FRAME_DATABITS_EIGHT; + break; + + case 9: + regval |= USART_FRAME_DATABITS_NINE; + break; + + case 10: + regval |= USART_FRAME_DATABITS_TEN; + break; + + case 11: + regval |= USART_FRAME_DATABITS_ELEVEN; + break; + + case 12: + regval |= USART_FRAME_DATABITS_TWELVE; + break; + + case 13: + regval |= USART_FRAME_DATABITS_THIRTEEN; + break; + + case 14: + regval |= USART_FRAME_DATABITS_FOURTEEN; + break; + + case 15: + regval |= USART_FRAME_DATABITS_FIFTEEN; + break; + + case 16: + regval |= USART_FRAME_DATABITS_SIXTEEN; + break; + } + + /* Configure parity */ + + switch (parity) + { + default: + case 0: + regval |= USART_FRAME_PARITY_NONE; + break; + + case 1: + regval |= USART_FRAME_PARITY_ODD; + break; + + case 2: + regval |= USART_FRAME_PARITY_EVEN; + break; + } + + /* Configure stop bits */ + + if (stop2) + { + regval |= USART_FRAME_STOPBITS_TWO; + } + else + { + regval |= USART_FRAME_STOPBITS_ONE; + } + + putreg32(regval, base + EFM32_USART_FRAME_OFFSET); + + /* Set the baud clock divisor */ + + efm32_uart_setbaud(base, baud); + + /* Enable the U[S]ART */ + + putreg32(USART_CMD_RXEN | USART_CMD_TXEN, base + EFM32_USART_CMD_OFFSET); +} +#endif + +/**************************************************************************** + * Name: efm32_leuartconfigure + * + * Description: + * Configure a LEUART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_DEVICE +void efm32_leuartconfigure(uintptr_t base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2) +{ + uint32_t regval = 0; + + /* Make sure that the LEUART registers are in the reset state (except for + * ROUTE information which must be preserved). + */ + + efm32_leuart_reset(base); + + /* Configure number of data bits */ + + switch (nbits) + { + default: + case 8: + regval |= LEUART_CTRL_DATABITS_EIGHT; + break; + + case 9: + regval |= LEUART_CTRL_DATABITS_NINE; + break; + } + + /* Configure parity */ + + switch (parity) + { + default: + case 0: + regval |= LEUART_CTRL_PARITY_NONE; + break; + + case 1: + regval |= LEUART_CTRL_PARITY_ODD; + break; + + case 2: + regval |= LEUART_CTRL_PARITY_EVEN; + break; + + } + + /* Configure stop bits */ + + if (stop2) + { + regval |= _LEUART_CTRL_STOPBITS_TWO; + } + else + { + regval |= _LEUART_CTRL_STOPBITS_ONE; + } + + putreg32(regval, base + EFM32_LEUART_CTRL_OFFSET); + + /* Set the baud clock divisor */ + + efm32_leuart_setbaud(base, baud); + + /* Enable the LEUART */ + + putreg32(LEUART_CMD_RXEN | LEUART_CMD_TXEN, base + EFM32_LEUART_CMD_OFFSET); +} +#endif + +/**************************************************************************** + * Name: efm32_uart_reset + * + * Description: + * Reset the USART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + * + ****************************************************************************/ + +#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE) +void efm32_uart_reset(uintptr_t base) +{ + putreg32(USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS | + USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX | + USART_CMD_CLEARRX, base + EFM32_USART_CMD_OFFSET); + putreg32(_USART_CTRL_RESETVALUE, base + EFM32_USART_CTRL_OFFSET); + putreg32(_USART_FRAME_RESETVALUE, base + EFM32_USART_FRAME_OFFSET); + putreg32(_USART_TRIGCTRL_RESETVALUE, base + EFM32_USART_TRIGCTRL_OFFSET); + putreg32(_USART_CLKDIV_RESETVALUE, base + EFM32_USART_CLKDIV_OFFSET); + putreg32(_USART_IEN_RESETVALUE, base + EFM32_USART_IEN_OFFSET); + putreg32(_USART_IFC_MASK, base + EFM32_USART_IFC_OFFSET); + + putreg32(_USART_IRCTRL_RESETVALUE, base + EFM32_USART_IRCTRL_OFFSET); +#if defined(EFM32_USART_INPUT_OFFSET) + putreg32(_USART_INPUT_RESETVALUE, base + EFM32_USART_INPUT_OFFSET); +#endif +#if defined(EFM32_USART_I2SCTRL_OFFSET) + putreg32(_USART_I2SCTRL_RESETVALUE, base + EFM32_USART_I2SCTRL_OFFSET); +#endif +} +#endif + +/**************************************************************************** + * Name: efm32_leuart_reset + * + * Description: + * Reset the USART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_DEVICE +void efm32_leuart_reset(uintptr_t base) +{ + putreg32(LEUART_CMD_RXDIS | LEUART_CMD_TXDIS | LEUART_CMD_RXBLOCKDIS | + LEUART_CMD_CLEARTX | LEUART_CMD_CLEARRX, + base + EFM32_LEUART_CMD_OFFSET); + putreg32(_LEUART_CTRL_RESETVALUE, base + EFM32_LEUART_CTRL_OFFSET); + putreg32(_LEUART_CLKDIV_RESETVALUE, base + EFM32_LEUART_CLKDIV_OFFSET); + putreg32(_LEUART_STARTFRAME_RESETVALUE, base + EFM32_LEUART_STARTFRAME_OFFSET); + putreg32(_LEUART_SIGFRAME_RESETVALUE, base + EFM32_LEUART_SIGFRAME_OFFSET); + putreg32(_LEUART_IEN_RESETVALUE, base + EFM32_LEUART_IEN_OFFSET); + putreg32(_LEUART_IFC_MASK, base + EFM32_LEUART_IFC_OFFSET); + putreg32(_LEUART_PULSECTRL_RESETVALUE, base + EFM32_LEUART_PULSECTRL_OFFSET); +#if defined(EFM32_LEUART_INPUT_OFFSET) + putreg32(_LEUART_INPUT_RESETVALUE, base + EFM32_LEUART_INPUT_OFFSET); +#endif +} +#endif diff --git a/arch/arm/src/efm32/efm32_lowputc.h b/arch/arm/src/efm32/efm32_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..f6ad56f47413e3c06bcbaf69bede2238d7e10263 --- /dev/null +++ b/arch/arm/src/efm32/efm32_lowputc.h @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_lowputc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_LOWPUTC_H +#define __ARCH_ARM_SRC_EFM32_EFM32_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "efm32_config.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void efm32_lowsetup(void); + +/**************************************************************************** + * Name: efm32_lowputc + * + * Description: + * Output one character to the UART using a simple polling method. + * + ****************************************************************************/ + +#if defined(HAVE_UART_CONSOLE) || defined(HAVE_LEUART_CONSOLE) +void efm32_lowputc(uint32_t ch); +#endif + +/**************************************************************************** + * Name: efm32_uartconfigure + * + * Description: + * Configure a U[S]ART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void efm32_uartconfigure(uintptr_t base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2); +#endif + +/**************************************************************************** + * Name: efm32_leuartconfigure + * + * Description: + * Configure a LEUART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_DEVICE +void efm32_leuartconfigure(uintptr_t base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2); +#endif + +/**************************************************************************** + * Name: efm32_uart_reset + * + * Description: + * Reset the USART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + * + ****************************************************************************/ + +#if defined(HAVE_UART_DEVICE) || defined(HAVE_SPI_DEVICE) +void efm32_uart_reset(uintptr_t base); +#endif + +/**************************************************************************** + * Name: efm32_uart_reset + * + * Description: + * Reset the USART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + * + ****************************************************************************/ + +#ifdef HAVE_LEUART_DEVICE +void efm32_leuart_reset(uintptr_t base); +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_LOWPUTC_H */ diff --git a/arch/arm/src/efm32/efm32_pm.h b/arch/arm/src/efm32/efm32_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..6846de31a394e61ba9f5c9c0aba60de1401acab2 --- /dev/null +++ b/arch/arm/src/efm32/efm32_pm.h @@ -0,0 +1,155 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_pm.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_PM_H +#define __ARCH_ARM_SRC_EFM32_EFM32_PM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_pmstop + * + * Description: + * Enter STOP mode. + * + * REVISIT: This power management interface was taken with no modification + * from the EFM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the EFM32! + * + * Input Parameters: + * lpds - true: To further reduce power consumption in Stop mode, put the + * internal voltage regulator in low-power mode using the LPDS bit + * of the Power control register (PWR_CR). + * + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +int efm32_pmstop(bool lpds); + +/**************************************************************************** + * Name: efm32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * REVISIT: This power management interface was taken with no modification + * from the EFM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the EFM32! + * + * Input Parameters: + * None + * + * Returned Value. + * On success, this function will not return (STANDBY mode can only be + * terminated with a reset event). Otherwise, STANDBY mode did not occur + * and a negated errno value is returned to indicate the cause of the + * failure. + * + ****************************************************************************/ + +int efm32_pmstandby(void); + +/**************************************************************************** + * Name: efm32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * REVISIT: This power management interface was taken with no modification + * from the EFM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the EFM32! + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep mode + * as soon as WFI or WFE instruction is executed. + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +void efm32_pmsleep(bool sleeponexit); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_PM_H */ diff --git a/arch/arm/src/efm32/efm32_pwm.c b/arch/arm/src/efm32/efm32_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..04941d44344cae714da23e60e40ac909b4ec1937 --- /dev/null +++ b/arch/arm/src/efm32/efm32_pwm.c @@ -0,0 +1,943 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_pwm.c + * + * Copyright (C) 2014 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/efm32_cmu.h" +#include "chip/efm32_timer.h" +#include "efm32_timer.h" +#include "efm32_config.h" +#include "efm32_gpio.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_EFM32_TIMER0_PWM) || \ + defined(CONFIG_EFM32_TIMER1_PWM) || \ + defined(CONFIG_EFM32_TIMER2_PWM) || \ + defined(CONFIG_EFM32_TIMER3_PWM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) efm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct efm32_pwmtimer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {1,...,14} */ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint8_t pinloc; /* Timer output channel pin location */ +#ifdef CONFIG_PWM_PULSECOUNT + uint8_t irq; /* Timer update IRQ */ + uint8_t prev; /* The previous value of the RCR (pre-loaded) */ + uint8_t curr; /* The current value of the RCR (pre-loaded) */ + uint32_t count; /* Remaining pulse count */ +#endif + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +#ifdef CONFIG_PWM_PULSECOUNT + FAR void *handle; /* Handle used for upper-half callback */ +#endif +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t pwm_getreg(struct efm32_pwmtimer_s *priv, int offset); +static void pwm_putreg(struct efm32_pwmtimer_s *priv, int offset, + uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct efm32_pwmtimer_s *priv, FAR const char *msg); +#else +# define pwm_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int pwm_timer(FAR struct efm32_pwmtimer_s *priv, + FAR const struct pwm_info_s *info); + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_EFM32_TIMER0_PWM) || \ + defined(CONFIG_EFM32_TIMER1_PWM) || \ + defined(CONFIG_EFM32_TIMER2_PWM) || \ + defined(CONFIG_EFM32_TIMER3_PWM) \ + ) +static int pwm_interrupt(struct efm32_pwmtimer_s *priv); +#if defined(CONFIG_EFM32_TIMER0_PWM) +static int pwm_timer0_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_TIMER1_PWM) +static int pwm_timer1_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_TIMER2_PWM) +static int pwm_timer2_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_TIMER3_PWM) +static int pwm_timer3_interrupt(int irq, void *context); +#endif +static uint8_t pwm_pulsecount(uint32_t count); + +#endif + +/* PWM driver methods */ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + +#ifdef CONFIG_PWM_PULSECOUNT +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info, + FAR void *handle); +#else +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); +#endif + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +#ifdef CONFIG_EFM32_TIMER0_PWM +static struct efm32_pwmtimer_s g_pwm0dev = +{ + .ops = &g_pwmops, + .timid = 0, + .channel = CONFIG_EFM32_TIMER0_CHANNEL, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = EFM32_IRQ_TIMER0, +#endif + .base = EFM32_TIMER0_BASE, + .pincfg = BOARD_PWM_TIMER0_PINCFG, + .pinloc = BOARD_PWM_TIMER0_PINLOC, + .pclk = BOARD_PWM_TIMER0_CLKIN, +}; +#endif + +#ifdef CONFIG_EFM32_TIMER1_PWM +static struct efm32_pwmtimer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 0, + .channel = CONFIG_EFM32_TIMER1_CHANNEL, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = EFM32_IRQ_TIMER1, +#endif + .base = EFM32_TIMER1_BASE, + .pincfg = BOARD_PWM_TIMER1_PINCFG, + .pinloc = BOARD_PWM_TIMER1_PINLOC, + .pclk = BOARD_PWM_TIMER1_CLKIN, +}; +#endif + +#ifdef CONFIG_EFM32_TIMER2_PWM +static struct efm32_pwmtimer_s g_pwm2dev = +{ + .ops = &g_pwmops, + .timid = 0, + .channel = CONFIG_EFM32_TIMER2_CHANNEL, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = EFM32_IRQ_TIMER2, +#endif + .base = EFM32_TIMER2_BASE, + .pincfg = BOARD_PWM_TIMER2_PINCFG, + .pinloc = BOARD_PWM_TIMER2_PINLOC, + .pclk = BOARD_PWM_TIMER2_CLKIN, +}; +#endif + +#ifdef CONFIG_EFM32_TIMER3_PWM +static struct efm32_pwmtimer_s g_pwm3dev = +{ + .ops = &g_pwmops, + .timid = 0, + .channel = CONFIG_EFM32_TIMER3_CHANNEL, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = EFM32_IRQ_TIMER3, +#endif + .base = EFM32_TIMER3_BASE, + .pincfg = BOARD_PWM_TIMER3_PINCFG, + .pinloc = BOARD_PWM_TIMER3_PINLOC, + .pclk = BOARD_PWM_TIMER3_CLKIN, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t pwm_getreg(struct efm32_pwmtimer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_putreg(struct efm32_pwmtimer_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct efm32_pwmtimer_s *priv, FAR const char *msg) +{ + /* TODO debug pwm_dumpregs */ + +#if 0 + pwmvdbg("%s:\n", msg); + pwmvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + pwm_getreg(priv, STM32_GTIM_CR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_SMCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); + pwmvdbg(" SR: %04x EGR: %04x CCMR1: %04x CCMR2: %04x\n", + pwm_getreg(priv, STM32_GTIM_SR_OFFSET), + pwm_getreg(priv, STM32_GTIM_EGR_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET)); + pwmvdbg(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCER_OFFSET), + pwm_getreg(priv, STM32_GTIM_CNT_OFFSET), + pwm_getreg(priv, STM32_GTIM_PSC_OFFSET), + pwm_getreg(priv, STM32_GTIM_ARR_OFFSET)); + pwmvdbg(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR3_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR4_OFFSET)); +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, STM32_ATIM_RCR_OFFSET), + pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET), + pwm_getreg(priv, STM32_ATIM_DCR_OFFSET), + pwm_getreg(priv, STM32_ATIM_DMAR_OFFSET)); + } + else +#endif + { + pwmvdbg(" DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, STM32_GTIM_DCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DMAR_OFFSET)); + } +#endif +} +#endif + +/**************************************************************************** + * Name: pwm_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_timer(FAR struct efm32_pwmtimer_s *priv, + FAR const struct pwm_info_s *info) +{ + /* Register contents */ + + uint32_t regval; + uint32_t cc_offet = EFM32_TIMER_CC_OFFSET(priv->channel); + + DEBUGASSERT(priv != NULL && info != NULL); + +#ifdef CONFIG_PWM_PULSECOUNT + pwmvdbg("TIMER%d channel: %d frequency: %d duty: %08x count: %d\n", + priv->timid, priv->channel, info->frequency, + info->duty, info->count); +#else + pwmvdbg("TIMER%d channel: %d frequency: %d duty: %08x\n", + priv->timid, priv->channel, info->frequency, info->duty); +#endif + DEBUGASSERT(info->frequency > 0 && info->duty >= 0 && + info->duty < uitoub16(100)); + + efm32_timer_reset(priv->base); + +#ifdef CONFIG_PWM_PULSECOUNT +#error "Not implemented ! Sorry" +#endif + + if (efm32_timer_set_freq(priv->base, priv->pclk, info->frequency) < 0) + { + pwmdbg("Cannot set TIMER frequency %dHz from clock %dHz\n", + info->frequency, priv->pclk); + return -EINVAL; + } + + regval = ((uint32_t)(priv->pinloc)) << _TIMER_ROUTE_LOCATION_SHIFT; + + switch (priv->channel) + { + case 0: + regval |= _TIMER_ROUTE_CC0PEN_MASK; + break; + + case 1: + regval |= _TIMER_ROUTE_CC1PEN_MASK; + break; + + case 2: + regval |= _TIMER_ROUTE_CC2PEN_MASK; + break; + + default: + ASSERT(false); + } + + pwm_putreg(priv, EFM32_TIMER_ROUTE_OFFSET, regval); + + regval = (info->duty * pwm_getreg(priv, EFM32_TIMER_TOP_OFFSET)) >> 16; + pwm_putreg(priv, cc_offet + EFM32_TIMER_CC_CCV_OFFSET, regval); + //pwm_putreg(priv, cc_offet + EFM32_TIMER_CC_CCVB_OFFSET, regval); + + regval = (_TIMER_CC_CTRL_MODE_PWM << _TIMER_CC_CTRL_MODE_SHIFT) | \ + (_TIMER_CC_CTRL_CMOA_CLEAR << _TIMER_CC_CTRL_CMOA_SHIFT) | \ + (_TIMER_CC_CTRL_COFOA_SET << _TIMER_CC_CTRL_COFOA_SHIFT) ; + + pwm_putreg(priv, cc_offet + EFM32_TIMER_CC_CTRL_OFFSET, regval); + + /* Start Timer */ + + pwm_putreg(priv, EFM32_TIMER_CMD_OFFSET, TIMER_CMD_START); + pwm_dumpregs(priv, "After starting"); + return OK; +} + +/**************************************************************************** + * Name: pwm_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_EFM32_TIMER0_PWM) || \ + defined(CONFIG_EFM32_TIMER1_PWM) || \ + defined(CONFIG_EFM32_TIMER2_PWM) || \ + defined(CONFIG_EFM32_TIMER3_PWM) \ + ) +#warning "not yet implemented" +static int pwm_interrupt(struct efm32_pwmtimer_s *priv) +{ + /* TODO pwm_interrupt */ +#if 0 + uint32_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = pwm_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + pwm_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + if (priv->count <= priv->prev) + { + /* We are finished. Turn off the mast output to stop the output as + * quickly as possible. + */ + + regval = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + regval &= ~ATIM_BDTR_MOE; + pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, regval); + + /* Disable first interrupts, stop and reset the timer */ + + (void)pwm_stop((FAR struct pwm_lowerhalf_s *)priv); + + /* Then perform the callback into the upper half driver */ + + pwm_expired(priv->handle); + + priv->handle = NULL; + priv->count = 0; + priv->prev = 0; + priv->curr = 0; + } + else + { + /* Decrement the count of pulses remaining using the number of + * pulses generated since the last interrupt. + */ + + priv->count -= priv->prev; + + /* Set up the next RCR. Set 'prev' to the value of the RCR that + * was loaded when the update occurred (just before this interrupt) + * and set 'curr' to the current value of the RCR register (which + * will bet loaded on the next update event). + */ + + priv->prev = priv->curr; + priv->curr = pwm_pulsecount(priv->count - priv->prev); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint32_t)priv->curr - 1); + } + + /* Now all of the time critical stuff is done so we can do some debug output */ + + pwmllvdbg("Update interrupt SR: %04x prev: %d curr: %d count: %d\n", + regval, priv->prev, priv->curr, priv->count); + + return OK; +#else + return -ENODEV; +#endif +} +#endif + +/**************************************************************************** + * Name: pwm_timer1/3_interrupt + * + * Description: + * Handle timer 1..3 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_EFM32_TIMER0_PWM) +static int pwm_timer0_interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm0dev); +} +#endif + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_EFM32_TIMER1_PWM) +static int pwm_timer1_interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm1dev); +} +#endif + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_EFM32_TIMER2_PWM) +static int pwm_timer2_interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm2dev); +} +#endif + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_EFM32_TIMER3_PWM) +static int pwm_timer3_interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm3dev); +} +#endif + +/**************************************************************************** + * Name: pwm_pulsecount + * + * Description: + * Pick an optimal pulse count to program the RCR. + * + * Input parameters: + * count - The total count remaining + * + * Returned Value: + * The recommended pulse count + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_EFM32_TIMER0_PWM) || \ + defined(CONFIG_EFM32_TIMER1_PWM) || \ + defined(CONFIG_EFM32_TIMER2_PWM) || \ + defined(CONFIG_EFM32_TIMER3_PWM) \ + ) +static uint8_t pwm_pulsecount(uint32_t count) +{ + /* The the remaining pulse count is less than or equal to the maximum, the + * just return the count. + */ + + if (count <= ATIM_RCR_REP_MAX) + { + return count; + } + + /* Otherwise, we have to be careful. We do not want a small number of + * counts at the end because we might have trouble responding fast enough. + * If the remaining count is less than 150% of the maximum, then return + * half of the maximum. In this case the final sequence will be between 64 + * and 128. + */ + + else if (count < (3 * ATIM_RCR_REP_MAX / 2)) + { + return (ATIM_RCR_REP_MAX + 1) >> 1; + } + + /* Otherwise, return the maximum. The final count will be 64 or more */ + + else + { + return ATIM_RCR_REP_MAX; + } +} +#endif + + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + + pwmvdbg("TIMER%d pincfg: %08x\n", priv->timid, priv->pincfg); + pwm_dumpregs(priv, "Initially"); + + /* Configure the PWM output pin, but do not start the timer yet */ + + /* Dnable TIMER clock */ + + switch (priv->timid) + { + case 0: + modifyreg32(EFM32_CMU_HFPERCLKEN0, 0, CMU_HFPERCLKEN0_TIMER0); + break; + + case 1: + modifyreg32(EFM32_CMU_HFPERCLKEN0, 0, CMU_HFPERCLKEN0_TIMER1); + break; + + case 2: + modifyreg32(EFM32_CMU_HFPERCLKEN0, 0, CMU_HFPERCLKEN0_TIMER2); + break; + + case 3: + modifyreg32(EFM32_CMU_HFPERCLKEN0, 0, CMU_HFPERCLKEN0_TIMER3); + break; + + default: + ASSERT(false); + break; + } + + efm32_configgpio(priv->pincfg); + pwm_putreg(priv, EFM32_TIMER_ROUTE_OFFSET, BOARD_PWM_TIMER0_PINLOC); + pwm_dumpgpio(priv->pincfg, "PWM setup"); + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + uint32_t pincfg; + + pwmvdbg("TIMER%d pincfg: %08x\n", priv->timid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + pwm_stop(dev); + + /* Then put the GPIO pin back to the default state */ + + pincfg = priv->pincfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); + + pincfg |= (_GPIO_DISABLE); + + efm32_configgpio(pincfg); + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef CONFIG_PWM_PULSECOUNT +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info, + FAR void *handle) +{ + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + + /* Save the handle */ + + priv->handle = handle; + + /* Start the time */ + + return pwm_timer(priv, info); +} +#else +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + return pwm_timer(priv, info); +} +#endif + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + irqstate_t flags; + + pwmvdbg("TIMER%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Reset the timer - stopping the output and putting the timer back + * into a state where pwm_start() can be called. + */ + + pwm_putreg(priv, EFM32_TIMER_CMD_OFFSET, TIMER_CMD_STOP); + + leave_critical_section(flags); + + pwm_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct efm32_pwmtimer_s *priv = (FAR struct efm32_pwmtimer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("TIMER%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *efm32_pwminitialize(int timer) +{ + FAR struct efm32_pwmtimer_s *lower; + + pwmvdbg("TIMER%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_EFM32_TIMER0_PWM + case 0: + lower = &g_pwm0dev; + + /* Attach but disable the TIM1 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_timer0_interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif + +#ifdef CONFIG_EFM32_TIMER1_PWM + case 1: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_timer0_interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif +#ifdef CONFIG_EFM32_TIMER2_PWM + case 2: + lower = &g_pwm2dev; + + /* Attach but disable the TIM1 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_timer2_interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif +#ifdef CONFIG_EFM32_TIMER3_PWM + case 3: + lower = &g_pwm3dev; + + /* Attach but disable the TIM1 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_timer3_interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_EFM32_TIMn_PWM, n = 0,..,3 */ diff --git a/arch/arm/src/efm32/efm32_pwm.h b/arch/arm/src/efm32/efm32_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..af46c3b6f8bccea22bb397435a0b3ce16293ebe1 --- /dev/null +++ b/arch/arm/src/efm32/efm32_pwm.h @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_pwm.h + * + * Copyright (C) 2014 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_PWM_H +#define __ARCH_ARM_SRC_EFM32_EFM32_PWM_H + +/* The EFM32 does not have dedicated PWM hardware. Rather, pulsed output + * control is a capability of the EFM32 timers. The logic in this file + * implements the lower half of the standard, NuttX PWM interface using the + * EFM32 timers. That interface is described in include/nuttx/pwm.h. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration **************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is + * to generate modulated outputs for such things as motor control. + * If CONFIG_EFM32_TIMERn is defined then the CONFIG_EFM32_TIMERn_PWM must also + * be defined to indicate that timer "n" is intended to be used for pulsed + * output signal generation. + */ + +#ifndef CONFIG_EFM32_TIMER0 +# undef CONFIG_EFM32_TIMER0_PWM +#endif +#ifndef CONFIG_EFM32_TIMER1 +# undef CONFIG_EFM32_TIMER1_PWM +#endif +#ifndef CONFIG_EFM32_TIMER2 +# undef CONFIG_EFM32_TIMER2_PWM +#endif +#ifndef CONFIG_EFM32_TIMER3 +# undef CONFIG_EFM32_TIMER3_PWM +#endif + +/* Check if PWM support for any channel is enabled. */ + +#if defined(CONFIG_EFM32_TIMER0_PWM) || \ + defined(CONFIG_EFM32_TIMER1_PWM) || \ + defined(CONFIG_EFM32_TIMER2_PWM) || \ + defined(CONFIG_EFM32_TIMER3_PWM) + +#include +#include "chip/efm32_timer.h" + +/* For each timer that is enabled for PWM usage, we need the following additional + * configuration settings: + * + * CONFIG_EFM32_TIMERx_CHANNEL - Specifies the timer output channel {0,1,3} + * BOARD_PWM_TIMERx_PINCFG - Specifies the timer output pin configuration. + * example : (GPIO_PORTC|GPIO_PIN0|GPIO_OUTPUT_PUSHPULL) + * + * BOARD_PWM_TIMERx_PINLOC - Specifies the timer output pin location. + * example : _TIMER_ROUTE_LOCATION_LOC4 + * + * BOARD_PWM_TIMERx_CLKIN - Specifies the timer input clock frequency (in Hz). + * example : 48e6 for 48MHz + * + * NOTE: The EFM32 timers are each capable of generating different signals on + * each of the four channels with different duty cycles. That capability is + * not supported by this driver: Only one output channel per timer. + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the EFM32 MCU and MCU family but is somewhere in + * the range of {0,..,3}. + * + * Returned Value: + * On success, a pointer to the EFM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +FAR struct pwm_lowerhalf_s *efm32_pwminitialize(int timer); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_EFM32_TIMERx_PWM */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_PWM_H */ diff --git a/arch/arm/src/efm32/efm32_rmu.c b/arch/arm/src/efm32/efm32_rmu.c new file mode 100644 index 0000000000000000000000000000000000000000..6b77564b24d73e5ff3805a804e75bf11bb06edbd --- /dev/null +++ b/arch/arm/src/efm32/efm32_rmu.c @@ -0,0 +1,279 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_rmu.c + * + * Copyright (C) 2015 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/efm32_emu.h" +#include "chip/efm32_rmu.h" + +#include "efm32_rmu.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +#ifdef CONFIG_EFM32_RMU_DEBUG +typedef struct +{ + const uint32_t val; + const uint32_t mask; + const char *str; +} efm32_reset_cause_list_t; +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_EFM32_RMU_DEBUG +static efm32_reset_cause_list_t efm32_reset_cause_list[] = +{ + { + 0x0001, /* 0bXXXX XXXX XXXX XXX1 */ + 0x0001, /* 0bXXXX XXXX XXXX XXX1 */ + "A Power-on Reset has been performed. X bits are don't care." + }, + { + 0x0002, /* 0bXXXX XXXX 0XXX XX10 */ + 0x0003, /* 0bXXXX XXXX 1XXX XX11 */ + "A Brown-out has been detected on the unregulated power." + }, + { + 0x0004, /* 0bXXXX XXXX XXX0 0100 */ + 0x001F, /* 0bXXXX XXXX XXX1 1111 */ + "A Brown-out has been detected on the regulated power." + }, + { + 0x0008, /* 0bXXXX XXXX XXXX 1X00 */ + 0x000B, /* 0bXXXX XXXX XXXX 1X11 */ + "An external reset has been applied." + }, + { + 0x0010, /* 0bXXXX XXXX XXX1 XX00 */ + 0x0013, /* 0bXXXX XXXX XXX1 XX11 */ + "A watchdog reset has occurred." + }, + { + 0x0020, /* 0bXXXX X000 0010 0000 */ + 0x07FF, /* 0bXXXX X111 1111 1111 */ + "A lockup reset has occurred." + }, + { + 0x0040, /* 0bXXXX X000 01X0 0000 */ + 0x07DF, /* 0bXXXX X111 11X1 1111 */ + "A system request reset has occurred." + }, + { + 0x0080, /* 0bXXXX X000 1XX0 0XX0 */ + 0x0799, /* 0bXXXX X111 1XX1 1XX1 */ + "The system has woken up from EM4." + }, + { + 0x0180, /* 0bXXXX X001 1XX0 0XX0 */ + 0x0799, /* 0bXXXX X111 1XX1 1XX1 */ + "The system has woken up from EM4 on an EM4 wakeup reset request from pin." + }, + { + 0x0200, /* 0bXXXX X01X XXX0 0000 */ + 0x061F, /* 0bXXXX X11X XXX1 1111 */ + "A Brown-out has been detected on Analog Power Domain 0 (AVDD0)." + }, + { + 0x0400, /* 0bXXXX X10X XXX0 0000 */ + 0x061F, /* 0bXXXX X11X XXX1 1111 */ + "A Brown-out has been detected on Analog Power Domain 1 (AVDD1)." + }, + { + 0x0800, /* 0bXXXX 1XXX XXXX 0XX0 */ + 0x0809, /* 0bXXXX 1XXX XXXX 1XX1 */ + "A Brown-out has been detected by the Backup BOD on VDD_DREG." + }, + { + 0x1000, /* 0bXXX1 XXXX XXXX 0XX0 */ + 0x1009, /* 0bXXX1 XXXX XXXX 1XX1 */ + "A Brown-out has been detected by the Backup BOD on BU_VIN." + }, + { + 0x2000, /* 0bXX1X XXXX XXXX 0XX0 */ + 0x2009, /* 0bXX1X XXXX XXXX 1XX1 */ + "A Brown-out has been detected by the Backup BOD on unregulated power" + }, + { + 0x4000, /* 0bX1XX XXXX XXXX 0XX0 */ + 0x4009, /* 0bX1XX XXXX XXXX 1XX1 */ + "A Brown-out has been detected by the Backup BOD on regulated power." + }, + { + 0x8000, /* 0b1XXX XXXX XXXX XXX0 */ + 0x8001, /* 0b1XXX XXXX XXXX XXX1 */ + "The system has been in Backup mode." + } +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* Variable old last reset cause of cpu. */ + +uint32_t g_efm32_rstcause; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_reset_cause_list_str + * + * Description: + * Return next reset cause string, NULL if no more reset cause. + * + * Input Parmeters: + * reg: reset cause register to decode (like g_efm32_rstcause) + * idx: Use to keep in maind reset cause decoding position. + * set *idx to zero before first call. + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_RMU_DEBUG +const char *efm32_reset_cause_list_str(uint32_t reg, unsigned int *idx) +{ + int len = sizeof(efm32_reset_cause_list)/sizeof(efm32_reset_cause_list[0]); + efm32_reset_cause_list_t *ptr = NULL; + + do + { + if (*idx >= len) + { + return NULL; + } + + ptr = &efm32_reset_cause_list[*idx]; + (*idx)++; + } + while ((ptr->mask & reg) != ptr->val); + + if (ptr != NULL) + { + return ptr->str; + } + + return NULL; +} +#endif + +/************************************************************************************ + * Name: efm32_rmu_initialize + * + * Description: + * Store reset cause into g_efm32_rstcause then clear reset cause register. + * + ************************************************************************************/ + +void efm32_rmu_initialize(void) +{ +#ifdef CONFIG_EFM32_RMU_DEBUG + unsigned int idx = 0; +#endif + uint32_t locked; + + g_efm32_rstcause = getreg32(EFM32_RMU_RSTCAUSE); + + /* Now clear reset cause */ + + putreg32(RMU_CMD_RCCLR, EFM32_RMU_CMD); + + /* Clear some reset causes not cleared with RMU CMD register + * (If EMU registers locked, they must be unlocked first) + */ + + locked = getreg32(EFM32_EMU_LOCK) & EMU_LOCK_LOCKKEY_LOCKED; + if (locked) + { + /* EMU unlock */ + + putreg32(EMU_LOCK_LOCKKEY_LOCK, EMU_LOCK_LOCKKEY_UNLOCK); + } + + modifyreg32(EFM32_EMU_AUXCTRL, 0, EMU_AUXCTRL_HRCCLR); + modifyreg32(EFM32_EMU_AUXCTRL, EMU_AUXCTRL_HRCCLR, 0); + + if (locked) + { + /* EMU lock */ + + putreg32(EMU_LOCK_LOCKKEY_LOCK, EMU_LOCK_LOCKKEY_LOCK); + } + +#ifdef CONFIG_EFM32_RMU_DEBUG + rmudbg("RMU => reg = 0x%08X\n", g_efm32_rstcause); + for (; ; ) + { + const char *str; + + str = efm32_reset_cause_list_str(g_efm32_rstcause, &idx); + if (str == NULL) + { + break; + } + + rmudbg("RMU => %s\n", str); + } +#endif +} diff --git a/arch/arm/src/efm32/efm32_rmu.h b/arch/arm/src/efm32/efm32_rmu.h new file mode 100644 index 0000000000000000000000000000000000000000..0aae6fbb0d97b34543af55153e1831a3a72ea1c4 --- /dev/null +++ b/arch/arm/src/efm32/efm32_rmu.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_rmu.h + * + * Copyright (C) 2015 Pierre-noel Bouteville . All rights reserved. + * Authors: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_RMU_H +#define __ARCH_ARM_SRC_EFM32_EFM32_RMU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/efm32_rmu.h" + +#ifdef CONFIG_EFM32_RMU + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_EFM32_RMU_DEBUG +#endif + +#ifdef CONFIG_EFM32_RMU_DEBUG +# define rmudbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define rmuvdbg lldbg +# else +# define rmuvdbg(x...) +# endif +#else +# define rmudbg(x...) +# define rmuvdbg(x...) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern uint32_t g_efm32_rstcause; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +/************************************************************************************ + * Name: efm32_rmu_initialize + * + * Description: + * Store reset cause into g_efm32_rstcause then clear reset cause register. + * + ************************************************************************************/ + +void efm32_rmu_initialize(void); +const char* efm32_reset_cause_list_str(uint32_t reg, unsigned int *idx); + +/************************************************************************************ + * Name: efm32_reset_cause_list_str + * + * Description: + * Return next reset cause string, NULL if no more reset cause. + * + * Input Parmeters: + * reg: reset cause register to decode (like g_efm32_rstcause) + * idx: Use to keep in maind reset cause decoding position. + * set *idx to zero before first call. + * + ************************************************************************************/ + +#ifdef CONFIG_EFM32_RMU_DEBUG +const char *efm32_reset_cause_list_str(uint32_t reg, unsigned int *idx); +#endif + +#endif /* CONFIG_EFM32_RMU */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_RMU_H */ diff --git a/arch/arm/src/efm32/efm32_rtc.h b/arch/arm/src/efm32/efm32_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..0bedb9f69672cd49d5b39761f850f756045afef4 --- /dev/null +++ b/arch/arm/src/efm32/efm32_rtc.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_rtc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_RTC_H +#define __ARCH_ARM_SRC_EFM32_EFM32_RTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The form of an alarm callback */ + +typedef void (*alarmcb_t)(void); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/************************************************************************************ + * Name: efm32_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct timespec; +int efm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); +#endif + +/************************************************************************************ + * Name: efm32_rtc_cancelalarm + * + * Description: + * Cancel a pending alarm alarm + * + * Input Parameters: + * none + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int efm32_rtc_cancelalarm(void); +#endif + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_RTC_H */ + diff --git a/arch/arm/src/efm32/efm32_rtc_burtc.c b/arch/arm/src/efm32/efm32_rtc_burtc.c new file mode 100644 index 0000000000000000000000000000000000000000..914ebd03ff3b226f7ac48575f32d17596dcdbb71 --- /dev/null +++ b/arch/arm/src/efm32/efm32_rtc_burtc.c @@ -0,0 +1,611 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_burtc.c + * + * Copyright (C) 2015 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "chip/efm32_burtc.h" + +#include "efm32_rmu.h" +#include "efm32_rtc.h" +#include "efm32_bitband.h" +#include "clock/clock.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_RTC_HIRES +# ifndef CONFIG_RTC_FREQUENCY +# error "CONFIG_RTC_FREQUENCY is required for CONFIG_RTC_HIRES" +# endif +#else +# ifndef CONFIG_RTC_FREQUENCY +# define CONFIG_RTC_FREQUENCY 1 +# endif +# if CONFIG_RTC_FREQUENCY != 1 +# error "Only lo-res CONFIG_RTC_FREQUENCY of 1Hz is supported" +# endif +#endif + +#ifndef BOARD_BURTC_MODE +# define BOARD_BURTC_MODE BURTC_CTRL_MODE_EM4EN +#endif + +#ifndef BOARD_BURTC_PRESC +# define BOARD_BURTC_PRESC BURTC_CTRL_PRESC_DIV1 +#endif + +#ifndef BOARD_BURTC_CLKSRC +# define BOARD_BURTC_CLKSRC BURTC_CTRL_CLKSEL_LFRCO +#endif + +#if (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV1) +# define BURTC_CLK_DIV 1 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV2) +# define BURTC_CLK_DIV 2 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV4) +# define BURTC_CLK_DIV 4 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV8) +# define BURTC_CLK_DIV 8 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV16) +# define BURTC_CLK_DIV 16 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV32) +# define BURTC_CLK_DIV 32 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV64) +# define BURTC_CLK_DIV 64 +#elif (BOARD_BURTC_PRESC == BURTC_CTRL_PRESC_DIV64) +# define BURTC_CLK_DIV 128 +#else +# error "BOARD_BURTC_PRESC is setted with unknown value" +#endif + +#if (BOARD_BURTC_CLKSRC == BURTC_CTRL_CLKSEL_LFRCO) +# if (CONFIG_RTC_FREQUENCY*BURTC_CLK_DIV != BOARD_LFRCO_FREQUENCY) +# error "CONFIG_RTC_FREQUENCY is not well be setted" +# endif +#elif (BOARD_BURTC_CLKSRC == BURTC_CTRL_CLKSEL_LFXO) +# if (CONFIG_RTC_FREQUENCY*BURTC_CLK_DIV != BOARD_LFXO_FREQUENCY) +# error "CONFIG_RTC_FREQUENCY is not well be setted" +# endif +#elif (BOARD_BURTC_CLKSRC == BURTC_CTRL_CLKSEL_ULFRCO) +# if (CONFIG_RTC_FREQUENCY*BURTC_CLK_DIV != BOARD_ULFRCO_FREQUENCY) +# error "CONFIG_RTC_FREQUENCY is not well be setted" +# endif +#else +# error "BOARD_BURTC_CLKSRC badly setted !" +#endif + +#define __CNT_TOP (((uint64_t)(_BURTC_CNT_MASK))+1) +#define __CNT_CARRY_REG EFM32_BURTC_RET_REG(0) +#define __CNT_ZERO_REG EFM32_BURTC_RET_REG(1) + +#if defined CONFIG_DEBUG && defined CONFIG_RTC_DEBUG +# define burtcdbg lldbg +#else +# define burtcdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* Variable determines the state of the LSE oscillator. + * Possible errors: + * - on start-up + * - during operation, reported by LSE interrupt + */ + +uint32_t g_efm32_burtc_reset_status; + +bool g_efm32_burtc_reseted = false; + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: efm32_rtc_interrupt + * + * Description: + * BURTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +static int efm32_rtc_burtc_interrupt(int irq, void *context) +{ + uint32_t source = getreg32(EFM32_BURTC_IF); + + if (source & BURTC_IF_LFXOFAIL) + { + burtcdbg("BURTC_IF_LFXOFAIL"); + } + +#ifdef CONFIG_RTC_HIRES + if (source & BURTC_IF_OF) + { + uint32_t regval; + + regval = getreg32(__CNT_CARRY_REG); + regval++; + putreg32(regval, __CNT_CARRY_REG); + } +#endif + +#ifdef CONFIG_RTC_ALARM + if (source & BURTC_IFC_COMP0) + { + if (g_alarmcb != NULL) + { + /* Alarm callback */ + + g_alarmcb(); + g_alarmcb = NULL; + } + } +#endif + + /* Clear pending flags, leave RSF high */ + + putreg32(BURTC_IFC_OF | BURTC_IFC_COMP0 | BURTC_IFC_LFXOFAIL, EFM32_BURTC_IFC); + + return 0; +} + +/************************************************************************************ + * Name: efm32_burtc_init + * + * Description: + * board initialization of burtc RTC. + * This function is called once in efm32_boardinitialize + * + * Note + * efm32_rmu_initialize should be called one since boot. + * + ************************************************************************************/ + +static void efm32_rtc_burtc_init(void) +{ + uint32_t regval; + uint32_t regval2; + + regval = g_efm32_rstcause; + regval2 = getreg32(EFM32_BURTC_CTRL); + + burtcdbg("BURTC RESETCAUSE=0x%08X BURTC_CTRL=0x%08X\n", regval, regval2); + + if (!(regval2 & BURTC_CTRL_RSTEN) && + !(regval & RMU_RSTCAUSE_BUBODREG) && + !(regval & RMU_RSTCAUSE_BUBODUNREG) && + !(regval & RMU_RSTCAUSE_BUBODBUVIN) && + !(regval & RMU_RSTCAUSE_EXTRST) && + !(regval & RMU_RSTCAUSE_PORST)) + { + g_efm32_burtc_reset_status = getreg32(EFM32_BURTC_STATUS); + + /* Reset timestamp BURTC clear status */ + + putreg32(BURTC_CMD_CLRSTATUS, EFM32_BURTC_CMD); + + /* restore saved base time */ + + burtcdbg("BURTC OK\n"); + return; + } + + burtcdbg("BURTC RESETED\n"); + + /* Disable reset of BackupDomain */ + + bitband_set_peripheral(EFM32_RMU_CTRL, _RMU_CTRL_BURSTEN_SHIFT, 0); + + /* Make sure all registers are updated simultaneously */ + + putreg32(BURTC_FREEZE_REGFREEZE_FREEZE, EFM32_BURTC_FREEZE); + + /* Restore all not setted BURTC registers to default value */ + +// putreg32(_BURTC_LPMODE_RESETVALUE, EFM32_BURTC_LPMODE); +// putreg32(_BURTC_LFXOFDET_RESETVALUE, EFM32_BURTC_LFXOFDET); +// putreg32(_BURTC_COMP0_RESETVALUE, EFM32_BURTC_COMP0); + + /* New configuration */ + + regval = ((BOARD_BURTC_MODE) | + (BURTC_CTRL_DEBUGRUN_DEFAULT) | + (BURTC_CTRL_COMP0TOP_DEFAULT) | + (BURTC_CTRL_LPCOMP_DEFAULT) | + (BOARD_BURTC_PRESC) | + (BOARD_BURTC_CLKSRC) | + (BURTC_CTRL_BUMODETSEN_DEFAULT)); + + /* Clear interrupts */ + + putreg32(0xFFFFFFFF, EFM32_BURTC_IFC); + + /* Set new configuration */ + + putreg32(regval | BURTC_CTRL_RSTEN, EFM32_BURTC_CTRL); + + /* Clear freeze */ + + putreg32(0, EFM32_BURTC_FREEZE); + + /* To enable BURTC counter, we need to disable reset */ + + putreg32(regval, EFM32_BURTC_CTRL); + + /* Enable BURTC interrupt on compare match and counter overflow */ + + putreg32(BURTC_IF_OF | BURTC_IF_LFXOFAIL, EFM32_BURTC_IEN); + + /* Lock BURTC to avoid modification */ + + putreg32(BURTC_LOCK_LOCKKEY_LOCK, EFM32_BURTC_LOCK); + + /* reset BURTC retention REG used */ + + putreg32(0, __CNT_CARRY_REG); + putreg32(0, __CNT_ZERO_REG); + + /* inform rest of software that BURTC was reset at boot */ + + g_efm32_burtc_reseted = true; +} + +static uint64_t efm32_get_burtc_tick(void) +{ + uint32_t cnt_carry; + uint32_t cnt_zero; + uint32_t cnt; + uint64_t val; + irqstate_t flags; + + flags = enter_critical_section(); + + do + { + /* pending IRQ so theat it */ + + if (getreg32(EFM32_BURTC_IF) & BURTC_IF_COMP0) + { + efm32_rtc_burtc_interrupt(EFM32_IRQ_BURTC, NULL); + } + + cnt = getreg32(EFM32_BURTC_CNT); + cnt_zero = getreg32(__CNT_ZERO_REG); + cnt_carry = getreg32(__CNT_CARRY_REG); + } + + /* Retry if IRQ appear during register reading */ + + while (getreg32(EFM32_BURTC_IF) & BURTC_IF_COMP0); + + leave_critical_section(flags); + + val = (uint64_t)cnt_carry*__CNT_TOP + cnt + cnt_zero; + + burtcdbg("Get Tick carry %u zero %u reg %u\n", cnt_carry, cnt_carry,cnt); + + return val; +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + efm32_rtc_burtc_init(); + + /* Configure RTC interrupt to catch overflow and alarm interrupts. */ + + irq_attach(EFM32_IRQ_BURTC, efm32_rtc_burtc_interrupt); + up_enable_irq(EFM32_IRQ_BURTC); + + g_rtc_enabled = true; + + return OK; +} + +/************************************************************************************ + * Name: up_rtc_time + * + * Description: + * Get the current time in seconds. This is similar to the standard time() + * function. This interface is only required if the low-resolution RTC/counter + * hardware implementation selected. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC is set but neither + * CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set. + * + * Input Parameters: + * None + * + * Returned Value: + * The current time in seconds + * + ************************************************************************************/ + +#ifndef CONFIG_RTC_HIRES +time_t up_rtc_time(void) +{ + return (time_t)efm32_get_burtc_tick()/CONFIG_RTC_FREQUENCY; +} +#endif + +/************************************************************************************ + * Name: up_rtc_gettime + * + * Description: + * Get the current time from the high resolution RTC clock/counter. This interface + * is only supported by the high-resolution RTC/counter hardware implementation. + * It is used to replace the system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_HIRES +int up_rtc_gettime(FAR struct timespec *tp) +{ + uint64_t val; + + val = efm32_get_burtc_tick(); + + /* Then we can save the time in seconds and fractional seconds. */ + + tp->tv_sec = val / CONFIG_RTC_FREQUENCY; + tp->tv_nsec = (val % CONFIG_RTC_FREQUENCY)*(NSEC_PER_SEC/CONFIG_RTC_FREQUENCY); + + burtcdbg("Get RTC %u.%09u\n", tp->tv_sec, tp->tv_nsec); + + return OK; +} +#endif + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + uint32_t cnt_carry; + uint32_t cnt; + uint32_t cnt_reg; + uint64_t val; + irqstate_t flags; + + flags = enter_critical_section(); + + cnt_reg = getreg32(EFM32_BURTC_CNT); + + /* Compute Burtc offset because we cannot reset counter */ + + val = (((uint64_t)tp->tv_sec) * CONFIG_RTC_FREQUENCY) + \ + (tp->tv_nsec / (NSEC_PER_SEC / CONFIG_RTC_FREQUENCY)); + + if (val < cnt_reg) + { + val = 0; + } + else + { + val -= cnt_reg; + } + + cnt_carry = val / __CNT_TOP; + cnt = val % __CNT_TOP; + + burtcdbg("Set RTC %u.%09u carry %u zero %u reg %u\n", + tp->tv_sec, tp->tv_nsec, cnt_carry, cnt, cnt_reg); + + putreg32(cnt_carry, __CNT_CARRY_REG); + putreg32(cnt , __CNT_ZERO_REG); + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: efm32_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +#error "Sorry ! not yet implemented, just copied from STM32" +int efm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + struct rtc_regvals_s regvals; + irqstate_t flags; + uint16_t cr; + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Break out the time values */ + + efm32_rtc_breakout(tp, ®vals); + + /* Enable RTC alarm */ + + cr = getreg16(STM32_RTC_CRH); + cr |= RTC_CRH_ALRIE; + putreg16(cr, STM32_RTC_CRH); + + /* The set the alarm */ + + flags = enter_critical_section(); + stm32_rtc_beginwr(); + putreg16(regvals.cnth, STM32_RTC_ALRH); + putreg16(regvals.cntl, STM32_RTC_ALRL); + stm32_rtc_endwr(); + leave_critical_section(flags); + + ret = OK; + } + + return ret; +} +#endif + +/************************************************************************************ + * Name: efm32_rtc_cancelalarm + * + * Description: + * Cancel a pending alarm alarm + * + * Input Parameters: + * none + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +#error "Sorry ! not yet implemented, just copied from STM32" +int efm32_rtc_cancelalarm(void) +{ + irqstate_t flags; + int ret = -ENODATA; + + if (g_alarmcb != NULL) + { + /* Cancel the global callback function */ + + g_alarmcb = NULL; + + /* Unset the alarm */ + + flags = enter_critical_section(); + stm32_rtc_beginwr(); + putreg16(0xffff, STM32_RTC_ALRH); + putreg16(0xffff, STM32_RTC_ALRL); + stm32_rtc_endwr(); + leave_critical_section(flags); + + ret = OK; + } + + return ret; +} +#endif diff --git a/arch/arm/src/efm32/efm32_serial.c b/arch/arm/src/efm32/efm32_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..fed33adcba28fc10f17177ba5fb58b8ecd775f47 --- /dev/null +++ b/arch/arm/src/efm32/efm32_serial.c @@ -0,0 +1,1362 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_serial.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/efm32_usart.h" +#include "efm32_config.h" +#include "efm32_gpio.h" +#include "efm32_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Is there at least one UART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_UART_DEVICE +# warning "No UARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be ttyS0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of USART0-2 or + * UART0-1. + */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_EFM32_USART0_ISUART) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +# elif defined(CONFIG_EFM32_USART1_ISUART) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +# elif defined(CONFIG_EFM32_USART2_ISUART) +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +# elif defined(CONFIG_EFM32_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_EFM32_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of USART0-2 or UART0-1, excluding the + * console UART. There are really only 4 unassigned. + */ + +#if defined(CONFIG_EFM32_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of USART1-5 or UART0-1. It can't be USART0 + * because that was either assigned as ttyS0 or ttys1. One of these could + * also be the console. There are really only 3 unassigned. + */ + +#if defined(CONFIG_EFM32_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED) +# define TTYS2_DEV g_uart0port /* UART0 is ttyS2 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2 or UART0-1. It can't be USART0-1 + * because those have already been assigned to ttsyS0, 1, or 2. One of + * these could also be the console. There are really only 2 unassigned. + */ + +#if defined(CONFIG_EFM32_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED) +# define TTYS3_DEV g_uart0port /* UART0 is ttyS3 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART1) && !defined(UART1_ASSIGNED) +# define TTYS3_DEV g_uart1port /* UART1 is ttyS3 */ +# define UART1_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART0-1. It can't be USART0-2 because + * those have already been assigned to ttsyS0, 1, 2, or 3. One of + * these could also be the console. There is really only 1 unassigned. + */ + +#if defined(CONFIG_EFM32_UART0) && !defined(UART0_ASSIGNED) +# define TTYS4_DEV g_uart0port /* UART0 is ttyS4 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_EFM32_UART1) && !defined(UART1_ASSIGNED) +# define TTYS4_DEV g_uart1port /* UART1 is ttyS4 */ +# define UART1_ASSIGNED 1 +#endif + +/* TX/RX interrupts */ + +#define EFM32_TXERR_INTS (USART_IEN_TXOF) +#define EFM32_RXERR_INTS (USART_IEN_RXOF | USART_IEN_RXUF | \ + USART_IEN_PERR | USART_IEN_FERR) +#ifdef CONFIG_DEBUG +# define EFM32_TX_INTS (USART_IEN_TXBL | EFM32_TXERR_INTS) +# define EFM32_RX_INTS (USART_IEN_RXDATAV | EFM32_RXERR_INTS) +#else +# define EFM32_TX_INTS USART_IEN_TXBL +# define EFM32_RX_INTS USART_IEN_RXDATAV +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct efm32_config_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + xcpt_t rxhandler; /* RX interrupt handler */ + xcpt_t txhandler; /* TX interrupt handler */ + uint32_t baud; /* Configured baud */ + uint8_t rxirq; /* RX IRQ associated with this UART (for enable) */ + uint8_t txirq; /* TX IRQ associated with this UART (for enable) */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ + bool stop2; /* True: 2 stop bits */ +}; + +struct efm32_usart_s +{ +#ifdef CONFIG_SERIAL_TERMIOS + struct efm32_config_s *config; +#else + const struct efm32_config_s *config; +#endif + uint16_t ien; /* Interrupts enabled */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t efm32_serialin(struct efm32_usart_s *priv, int offset); +static inline void efm32_serialout(struct efm32_usart_s *priv, int offset, + uint32_t value); +static inline void efm32_setuartint(struct efm32_usart_s *priv); + +static void efm32_restoreuartint(struct efm32_usart_s *priv, uint32_t ien); +#ifdef HAVE_UART_CONSOLE +static void efm32_disableuartint(struct efm32_usart_s *priv, uint32_t *ien); +#endif +static int efm32_setup(struct uart_dev_s *dev); +static void efm32_shutdown(struct uart_dev_s *dev); +static int efm32_attach(struct uart_dev_s *dev); +static void efm32_detach(struct uart_dev_s *dev); +static int efm32_rxinterrupt(struct uart_dev_s *dev); +#if defined(CONFIG_EFM32_USART0_ISUART) +static int efm32_usart0_rxinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_USART1_ISUART) +static int efm32_usart1_rxinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_USART2_ISUART) +static int efm32_usart2_rxinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_UART0) +static int efm32_uart0_rxinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_UART1) +static int efm32_uart1_rxinterrupt(int irq, void *context); +#endif +static int efm32_txinterrupt(struct uart_dev_s *dev); +#if defined(CONFIG_EFM32_USART0_ISUART) +static int efm32_usart0_txinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_USART1_ISUART) +static int efm32_usart1_txinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_USART2_ISUART) +static int efm32_usart2_txinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_UART0) +static int efm32_uart0_txinterrupt(int irq, void *context); +#endif +#if defined(CONFIG_EFM32_UART1) +static int efm32_uart1_txinterrupt(int irq, void *context); +#endif +static int efm32_ioctl(struct file *filep, int cmd, unsigned long arg); +static int efm32_receive(struct uart_dev_s *dev, uint32_t *status); +static void efm32_rxint(struct uart_dev_s *dev, bool enable); +static bool efm32_rxavailable(struct uart_dev_s *dev); +static void efm32_send(struct uart_dev_s *dev, int ch); +static void efm32_txint(struct uart_dev_s *dev, bool enable); +static bool efm32_txready(struct uart_dev_s *dev); +static bool efm32_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = efm32_setup, + .shutdown = efm32_shutdown, + .attach = efm32_attach, + .detach = efm32_detach, + .ioctl = efm32_ioctl, + .receive = efm32_receive, + .rxint = efm32_rxint, + .rxavailable = efm32_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = efm32_send, + .txint = efm32_txint, + .txready = efm32_txready, + .txempty = efm32_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_EFM32_USART0_ISUART +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_EFM32_USART1_ISUART +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_EFM32_USART2_ISUART +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_EFM32_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_EFM32_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +/* This describes the state of the EFM32 USART0 port. */ + +#ifdef CONFIG_EFM32_USART0_ISUART +static const struct efm32_usart_s g_usart0config = +{ + .uartbase = EFM32_USART0_BASE, + .rxhandler = efm32_usart0_rxinterrupt, + .txhandler = efm32_usart0_txinterrupt, + .baud = CONFIG_USART0_BAUD, + .rxirq = EFM32_IRQ_USART0_RX, + .txirq = EFM32_IRQ_USART0_TX, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stop2 = CONFIG_USART0_2STOP, +}; + +static struct efm32_usart_s g_usart0priv = +{ + .config = &g_usart0config, +}; + +static struct uart_dev_s g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the EFM32 USART1 port. */ + +#ifdef CONFIG_EFM32_USART1_ISUART +static struct efm32_config_s g_usart1config = +{ + .uartbase = EFM32_USART1_BASE, + .rxhandler = efm32_usart1_rxinterrupt, + .txhandler = efm32_usart1_txinterrupt, + .baud = CONFIG_USART1_BAUD, + .rxirq = EFM32_IRQ_USART1_RX, + .txirq = EFM32_IRQ_USART1_TX, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stop2 = CONFIG_USART1_2STOP, +}; + +static struct efm32_usart_s g_usart1priv = +{ + .config = &g_usart1config, +}; + +static struct uart_dev_s g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the EFM32 USART2 port. */ + +#ifdef CONFIG_EFM32_USART2_ISUART +static struct efm32_config_s g_usart2config = +{ + .uartbase = EFM32_USART2_BASE, + .rxhandler = efm32_usart2_rxinterrupt, + .txhandler = efm32_usart2_txinterrupt, + .baud = CONFIG_USART2_BAUD, + .rxirq = EFM32_IRQ_USART2_RX, + .txirq = EFM32_IRQ_USART2_TX, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stop2 = CONFIG_USART2_2STOP, +}; + +static struct efm32_usart_s g_usart2priv = +{ + .config = &g_usart2config, +}; + +static struct uart_dev_s g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/* This describes the state of the EFM32 UART0 port. */ + +#ifdef CONFIG_EFM32_UART0 +static struct efm32_config_s g_uart0config = +{ + .uartbase = EFM32_UART0_BASE, + .rxhandler = efm32_uart0_rxinterrupt, + .txhandler = efm32_uart0_txinterrupt, + .baud = CONFIG_UART0_BAUD, + .rxirq = EFM32_IRQ_UART0_RX, + .txirq = EFM32_IRQ_UART0_TX, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stop2 = CONFIG_UART0_2STOP, +}; + +static struct efm32_usart_s g_uart0priv = +{ + .config = &g_uart0config, +}; + +static struct uart_dev_s g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the EFM32 UART1 port. */ + +#ifdef CONFIG_EFM32_UART1 +static struct efm32_usart_s g_uart1config = +{ + .uartbase = EFM32_UART1_BASE, + .rxhandler = efm32_uart1_rxinterrupt, + .txhandler = efm32_uart1_txinterrupt, + .baud = CONFIG_UART1_BAUD, + .rxirq = EFM32_IRQ_UART1_RX, + .txirq = EFM32_IRQ_UART1_TX, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stop2 = CONFIG_UART1_2STOP, +}; + +static struct efm32_usart_s g_uart1priv = +{ + .config = &g_uart1config, +}; + +static struct uart_dev_s g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_serialin + ****************************************************************************/ + +static inline uint32_t efm32_serialin(struct efm32_usart_s *priv, int offset) +{ + return getreg32(priv->config->uartbase + offset); +} + +/**************************************************************************** + * Name: efm32_serialout + ****************************************************************************/ + +static inline void efm32_serialout(struct efm32_usart_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->config->uartbase + offset); +} + +/**************************************************************************** + * Name: efm32_setuartint + ****************************************************************************/ + +static inline void efm32_setuartint(struct efm32_usart_s *priv) +{ + efm32_serialout(priv, EFM32_USART_IEN_OFFSET, priv->ien); +} + +/**************************************************************************** + * Name: efm32_restoreuartint + ****************************************************************************/ + +static void efm32_restoreuartint(struct efm32_usart_s *priv, uint32_t ien) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ien */ + + flags = enter_critical_section(); + priv->ien = ien; + efm32_setuartint(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_disableuartint + ****************************************************************************/ + +#if defined(HAVE_UART_CONSOLE) || defined(CONFIG_SERIAL_TERMIOS) +static void efm32_disableuartint(struct efm32_usart_s *priv, uint32_t *ien) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ien) + { + *ien = priv->ien; + } + + efm32_restoreuartint(priv, 0); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: efm32_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int efm32_setup(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + uint32_t regval; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + const struct efm32_config_s *config = priv->config; + + /* Configure the UART as an RS-232 UART */ + + efm32_uartconfigure(config->uartbase, config->baud, config->parity, + config->bits, config->stop2); +#endif + + /* Make sure that all interrupts are disabled */ + + efm32_restoreuartint(priv, 0); + + /* Set the TXIL bit in the USART CTRL register. This will cause TXBL + * interrupts when the TX buffer is half full. + */ + + regval = efm32_serialin(priv, EFM32_USART_CTRL_OFFSET); + regval |= USART_CTRL_TXBIL_HALFFULL; + efm32_serialout(priv, EFM32_USART_CTRL_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Name: efm32_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void efm32_shutdown(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + + /* Disable interrupts */ + + efm32_restoreuartint(priv, 0); + + /* Reset the USART/UART by disabling it and restoring all of the registers + * to the initial, reset value. Only the ROUTE data set by efm32_lowsetup + * is preserved. + */ + + efm32_uart_reset(priv->config->uartbase); +} + +/**************************************************************************** + * Name: efm32_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int efm32_attach(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + const struct efm32_config_s *config = priv->config; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(config->rxirq, config->rxhandler); + if (ret < 0) + { + return ret; + } + + ret = irq_attach(config->txirq, config->txhandler); + if (ret < 0) + { + irq_detach(config->rxirq); + return ret; + } + + up_enable_irq(config->rxirq); + up_enable_irq(config->txirq); + return ret; +} + +/**************************************************************************** + * Name: efm32_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void efm32_detach(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + const struct efm32_config_s *config = priv->config; + + /* Disable interrupts */ + + efm32_restoreuartint(priv, 0); + up_disable_irq(config->rxirq); + up_disable_irq(config->txirq); + + /* Detach from the interrupt(s) */ + + irq_detach(config->rxirq); + irq_detach(config->txirq); +} + +/**************************************************************************** + * Name: efm32_rxinterrupt + * + * Description: + * This is the common UART RX interrupt handler. + * + ****************************************************************************/ + +static int efm32_rxinterrupt(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + uint32_t intflags; + + DEBUGASSERT(priv); + + /* Read the interrupt flags register */ + + intflags = efm32_serialin(priv, EFM32_USART_IF_OFFSET); + + /* Clear pending interrupts by writing to the interrupt flag clear + * register. + */ + + efm32_serialout(priv, EFM32_USART_IFC_OFFSET, intflags & EFM32_RX_INTS); + + /* Check if the receive data is available is full (RXDATAV). */ + + if ((intflags & USART_IEN_RXDATAV) != 0) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + +#ifdef CONFIG_DEBUG + /* Check for receive errors */ + + if ((intflags & EFM32_RXERR_INTS) != 0) + { + /* RXOF - RX Overflow Interrupt Enable + * RXUF - RX Underflow Interrupt Enable + * TXUF - TX Underflow Interrupt Enable + * PERR - Parity Error Interrupt Enable + * FERR - Framing Error Interrupt Enable + */ + + lldbg("RX ERROR: %08x\n", intflags); + } +#endif + + return OK; +} + +#if defined(CONFIG_EFM32_USART0_ISUART) +static int efm32_usart0_rxinterrupt(int irq, void *context) +{ + return efm32_rxinterrupt(&g_usart0port); +} +#endif + +#if defined(CONFIG_EFM32_USART1_ISUART) +static int efm32_usart1_rxinterrupt(int irq, void *context) +{ + return efm32_rxinterrupt(&g_usart1port); +} +#endif + +#if defined(CONFIG_EFM32_USART2_ISUART) +static int efm32_usart2_rxinterrupt(int irq, void *context) +{ + return efm32_rxinterrupt(&g_usart2port); +} +#endif + +#if defined(CONFIG_EFM32_UART0) +static int efm32_uart0_rxinterrupt(int irq, void *context) +{ + return efm32_rxinterrupt(&g_uart0port); +} +#endif + +#if defined(CONFIG_EFM32_UART1) +static int efm32_uart1_rxinterrupt(int irq, void *context) +{ + return efm32_rxinterrupt(&g_uart1port); +} +#endif + +/**************************************************************************** + * Name: efm32_txinterrupt + * + * Description: + * This is the common UART TX interrupt handler. + * + ****************************************************************************/ + +static int efm32_txinterrupt(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + uint32_t intflags; + + DEBUGASSERT(priv); + + /* Read the interrupt flags register */ + + intflags = efm32_serialin(priv, EFM32_USART_IF_OFFSET); + + /* Clear pending interrupts by writing to the interrupt flag clear + * register. We won't clear RX errors until they have been reported. + */ + + efm32_serialout(priv, EFM32_USART_IFC_OFFSET, intflags & EFM32_TX_INTS); + + /* Check if the transmit data buffer became half full */ + + if ((intflags & USART_IEN_TXBL) != 0) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + } + +#ifdef CONFIG_DEBUG + /* Check for transmit errors */ + + if ((intflags & EFM32_TXERR_INTS) != 0) + { + /* TXOF - TX Overflow Interrupt Enable */ + + lldbg("RX ERROR: %08x\n", intflags); + } +#endif + + return OK; +} + +#if defined(CONFIG_EFM32_USART0_ISUART) +static int efm32_usart0_txinterrupt(int irq, void *context) +{ + return efm32_txinterrupt(&g_usart0port); +} +#endif + +#if defined(CONFIG_EFM32_USART1_ISUART) +static int efm32_usart1_txinterrupt(int irq, void *context) +{ + return efm32_txinterrupt(&g_usart1port); +} +#endif + +#if defined(CONFIG_EFM32_USART2_ISUART) +static int efm32_usart2_txinterrupt(int irq, void *context) +{ + return efm32_txinterrupt(&g_usart2port); +} +#endif + +#if defined(CONFIG_EFM32_UART0) +static int efm32_uart0_txinterrupt(int irq, void *context) +{ + return efm32_txinterrupt(&g_uart0port); +} +#endif + +#if defined(CONFIG_EFM32_UART1) +static int efm32_uart1_txinterrupt(int irq, void *context) +{ + return efm32_txinterrupt(&g_uart1port); +} +#endif + +/**************************************************************************** + * Name: efm32_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int efm32_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode; + struct uart_dev_s *dev; +#ifdef CONFIG_SERIAL_TERMIOS + struct efm32_usart_s *priv; +#endif + + int ret = OK; + + DEBUGASSERT(filep); + DEBUGASSERT(filep->f_inode); + + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev); + DEBUGASSERT(dev->priv); + +#ifdef CONFIG_SERIAL_TERMIOS + priv = (struct efm32_usart_s *)dev->priv; +#endif + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->config->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = CS8; + + /* TODO: PARENB, PARODD, CSTOPB, CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + /* TODO : PARENB, PARODD, CSTOPB, CCTS_OFLOW, CCTS_IFLOW */ + +#if 0 + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif +#endif + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + { + uint32_t ien; + struct efm32_config_s *config = priv->config; + + config->baud = cfgetispeed(termiosp); + + /* Just speed is yet implemented */ + + efm32_disableuartint(priv, &ien); + + efm32_uartconfigure(config->uartbase, config->baud, config->parity, + config->bits, config->stop2); + + efm32_restoreuartint(priv, ien); + } + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: efm32_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int efm32_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + uint32_t rxdatax; + + /* Get error status information: + * + * FERR Data Framing Error + * PERR Data Parity Error + */ + + rxdatax = efm32_serialin(priv, EFM32_USART_RXDATAX_OFFSET); + + /* Return status information */ + + if (status) + { + *status = rxdatax; + } + + /* Then return the actual received byte. */ + + return (int)(rxdatax & _USART_RXDATAX_RXDATA_MASK); +} + +/**************************************************************************** + * Name: efm32_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void efm32_rxint(struct uart_dev_s *dev, bool enable) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ien |= EFM32_RX_INTS; + efm32_setuartint(priv); +#endif + } + else + { + priv->ien &= ~EFM32_RX_INTS; + efm32_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool efm32_rxavailable(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + + /* Return true if the receive data is available (RXDATAV). */ + + return (efm32_serialin(priv, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0; +} + +/**************************************************************************** + * Name: efm32_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void efm32_send(struct uart_dev_s *dev, int ch) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + efm32_serialout(priv, EFM32_USART_TXDATA_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: efm32_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void efm32_txint(struct uart_dev_s *dev, bool enable) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ien |= EFM32_TX_INTS; + efm32_setuartint(priv); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ien &= ~EFM32_TX_INTS; + efm32_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_txready + * + * Description: + * Return true if the transmit data register is not full + * + ****************************************************************************/ + +static bool efm32_txready(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + + /* The TX Buffer Level (TXBL) status bit indicates the level of the + * transmit buffer. If TXBIL is set, TXBL is set whenever the transmit + * buffer is half-full or empty. + */ + + return (efm32_serialin(priv, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) != 0; +} + +/**************************************************************************** + * Name: efm32_txempty + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool efm32_txempty(struct uart_dev_s *dev) +{ + struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv; + + /* TX Complete (TXC) is set when a transmission has completed and no more + * data is available in the transmit buffer. + */ + + return (efm32_serialin(priv, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXC) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in efm32_consoleinit() and main clock iniialization + * performed in efm32_clkinitialize(). + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit() + */ + + efm32_restoreuartint(TTYS0_DEV.priv, 0); +#ifdef TTYS1_DEV + efm32_restoreuartint(TTYS1_DEV.priv, 0); +#endif +#ifdef TTYS2_DEV + efm32_restoreuartint(TTYS2_DEV.priv, 0); +#endif +#ifdef TTYS3_DEV + efm32_restoreuartint(TTYS3_DEV.priv, 0); +#endif +#ifdef TTYS4_DEV + efm32_restoreuartint(TTYS4_DEV.priv, 0); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + efm32_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifndef HAVE_LEUART_CONSOLE +int up_putc(int ch) +{ +#ifdef HAVE_UART_CONSOLE + struct efm32_usart_s *priv = (struct efm32_usart_s *)CONSOLE_DEV.priv; + uint32_t ien; + + efm32_disableuartint(priv, &ien); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + efm32_lowputc('\r'); + } + + efm32_lowputc(ch); + efm32_restoreuartint(priv, ien); +#endif + return ch; +} +#endif + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifndef HAVE_LEUART_CONSOLE +int up_putc(int ch) +{ +#ifdef HAVE_UART_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + efm32_lowputc('\r'); + } + + efm32_lowputc(ch); +#endif + return ch; +} +#endif + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/efm32/efm32_spi.c b/arch/arm/src/efm32/efm32_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..05c0ab7c5197bf77625fd22f03f0889d8f70c4c2 --- /dev/null +++ b/arch/arm/src/efm32/efm32_spi.c @@ -0,0 +1,1748 @@ +/**************************************************************************** + * arm/arm/src/efm32/efm32_spi.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved. + * Authors: Gregory Nutt + * Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/efm32_usart.h" +#include "efm32_config.h" +#include "efm32_dma.h" +#include "efm32_lowputc.h" +#include "efm32_spi.h" +#include "efm32_gpio.h" + +#ifdef HAVE_SPI_DEVICE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* SPI DMA */ + +#ifndef CONFIG_EFM32_SPI_DMA_TIMEO_NSEC +# define CONFIG_EFM32_SPI_DMA_TIMEO_NSEC 500 +#endif + +#ifndef CONFIG_EFM32_SPI_DMA_MINSIZE +# define CONFIG_EFM32_SPI_DMA_MINSIZE 16 +#endif + +/* DMA definitions **********************************************************/ + +#define SPI_DMA8_CONFIG (EFM32_DMA_XFERSIZE_BYTE| EFM32_DMA_MEMINCR) +#define SPI_DMA8NULL_CONFIG (EFM32_DMA_XFERSIZE_BYTE | EFM32_DMA_NOINCR) +#define SPI_DMA16_CONFIG (EFM32_DMA_XFERSIZE_HWORD | EFM32_DMA_MEMINCR) +#define SPI_DMA16NULL_CONFIG (EFM32_DMA_XFERSIZE_HWORD | EFM32_DMA_NOINCR) + +/* Debug ********************************************************************/ +/* Check if SPI debug is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type constant configuration one SPI peripheral */ + +struct efm32_spidev_s; +struct efm32_spiconfig_s +{ + uintptr_t base; /* USART base address */ +#ifdef CONFIG_EFM32_SPI_DMA + dma_config_t rxconfig; /* RX DMA configuration */ + dma_config_t txconfig; /* TX DMA configuration */ +#endif + + /* SPI-specific methods */ + + void (*select)(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); + uint8_t (*status)(struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA + int (*cmddata)(struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +}; + +/* This type represents the state of one SPI peripheral */ + +struct efm32_spidev_s +{ + const struct spi_ops_s *spidev; /* Externally visible SPI interface */ + const struct efm32_spiconfig_s *config; /* Constant SPI hardware configuration */ + +#ifdef CONFIG_EFM32_SPI_DMA + WDOG_ID wdog; /* Timer to catch hung DMA */ + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the TX DMA */ + DMA_HANDLE rxdmach; /* RX DMA channel handle */ + DMA_HANDLE txdmach; /* TX DMA channel handle */ + sem_t rxdmasem; /* Wait for RX DMA to complete */ + sem_t txdmasem; /* Wait for TX DMA to complete */ +#endif + + sem_t exclsem; /* Supports mutually exclusive access */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (4-16) */ + bool lsbfirst; /* True: Bit order is LSB first */ + bool initialized; /* True: Already initialized */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Low level SPI access */ + +static uint32_t spi_getreg(const struct efm32_spiconfig_s *config, + unsigned int regoffset); +static void spi_putreg(const struct efm32_spiconfig_s *config, + unsigned int regoffset, uint32_t regval); +static void spi_rxflush(const struct efm32_spiconfig_s *config); +static void spi_wait_status(const struct efm32_spiconfig_s *config, + uint32_t mask, uint32_t match); + +/* DMA support */ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dma_timeout(int argc, uint32_t arg1, ...); +static void spi_dmarxwait(struct efm32_spidev_s *priv); +static void spi_dmatxwait(struct efm32_spidev_s *priv); +static inline void spi_dmarxwakeup(struct efm32_spidev_s *priv); +static inline void spi_dmatxwakeup(struct efm32_spidev_s *priv); +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t status, + void *arg); +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t status, + void *arg); +static void spi_dmarxsetup(struct efm32_spidev_s *priv, + void *rxbuffer, void *rxdummy, size_t nwords); +static void spi_dmatxsetup(struct efm32_spidev_s *priv, + const void *txbuffer, const void *txdummy, + size_t nwords); +static inline void spi_dmarxstart(FAR struct efm32_spidev_s *priv); +static inline void spi_dmatxstart(FAR struct efm32_spidev_s *priv); +#endif + +/* SPI methods */ + +static int spi_lock(struct spi_dev_s *dev, bool lock); +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint32_t spi_setfrequency(struct spi_dev_s *dev, + uint32_t frequency); +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(struct spi_dev_s *dev, int nbits); +static uint8_t spi_status(struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +static int spi_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +#endif +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd); +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer, + size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, void *rxbuffer, + size_t nwords); +#endif + +/* Initialization */ + +static int spi_portinitialize(struct efm32_spidev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Common SPI operations */ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, +#endif + .status = spi_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = spi_cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, +}; + +#ifdef CONFIG_EFM32_USART0_ISSPI +/* Support for SPI on USART0 */ + +static struct efm32_spidev_s g_spi0dev; +static const struct efm32_spiconfig_s g_spi0config = +{ + .base = EFM32_USART0_BASE, +#ifdef CONFIG_EFM32_SPI_DMA + .rxconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART0RXDATAV) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART0) | + EFM32_DMA_SINGLE, + .txconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART0TXBL) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART0) | + EFM32_DMA_SINGLE, +#endif + .select = efm32_spi0_select, + .status = efm32_spi0_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = efm32_spi0_cmddata, +#endif +}; +#endif /* CONFIG_EFM32_USART0_ISSPI */ + +#ifdef CONFIG_EFM32_USART1_ISSPI +/* Support for SPI on USART1 */ + +static struct efm32_spidev_s g_spi1dev; +static const struct efm32_spiconfig_s g_spi1config = +{ + .base = EFM32_USART1_BASE, +#ifdef CONFIG_EFM32_SPI_DMA + .rxconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART1RXDATAV) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART1) | + EFM32_DMA_SINGLE, + .txconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART1TXBL) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART1) | + EFM32_DMA_SINGLE, +#endif + .select = efm32_spi1_select, + .status = efm32_spi1_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = efm32_spi1_cmddata, +#endif +}; +#endif /* CONFIG_EFM32_USART1_ISSPI */ + +#ifdef CONFIG_EFM32_USART2_ISSPI +/* Support for SPI on USART2 */ + +static struct efm32_spidev_s g_spi2dev; +static const struct efm32_spiconfig_s g_spi2config = +{ + .base = EFM32_USART2_BASE, +#ifdef CONFIG_EFM32_SPI_DMA + .rxconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART2RXDATAV) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART2) | + EFM32_DMA_SINGLE, + .txconfig = EFM32_DMA_SIGSEL(_DMA_CH_CTRL_SIGSEL_USART2TXBL) | + EFM32_DMA_SOURCSEL(_DMA_CH_CTRL_SOURCESEL_USART2) | + EFM32_DMA_SINGLE, +#endif + .select = efm32_spi2_select, + .status = efm32_spi2_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = efm32_spi2_cmddata, +#endif +}; +#endif /* CONFIG_EFM32_USART2_ISSPI */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read the contents of one SPI register + * + * Input Parameters: + * config - Device-specific configuration data + * regoffset - Offset to the SPI register + * + * Returned Value: + * Value read from the SPI register + * + ****************************************************************************/ + +static uint32_t spi_getreg(const struct efm32_spiconfig_s *config, + unsigned int regoffset) +{ + uintptr_t regaddr = config->base + regoffset; + return getreg32(regaddr); +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to one SPI register + * + * Input Parameters: + * config - Device-specific configuration data + * regoffset - Offset to the SPI register + * regval - The value to be written + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_putreg(const struct efm32_spiconfig_s *config, + unsigned int regoffset, uint32_t regval) +{ + uintptr_t regaddr = config->base + regoffset; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: spi_rxflush + * + * Description: + * Flush any garbage from the RX buffer + * + ****************************************************************************/ + +static void spi_rxflush(const struct efm32_spiconfig_s *config) +{ + /* Loop while data is available */ + + while ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0) + { + /* Read and discard the data */ + + (void)spi_getreg(config, EFM32_USART_RXDATA_OFFSET); + } +} + +/**************************************************************************** + * Name: spi_wait_status + * + * Description: + * Poll until the SPI status under the mask is equal to the mask value. + * + ****************************************************************************/ + +static void spi_wait_status(const struct efm32_spiconfig_s *config, + uint32_t mask, uint32_t match) +{ + while ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & mask) != match); +} + +/**************************************************************************** + * Name: spi_dma_timeout + * + * Description: + * Invoked when a DMA timeout occurs + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dma_timeout(int argc, uint32_t arg1, ...) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)((uintptr_t)arg1); + + /* Mark DMA timeout error and wakeup form RX and TX waiters */ + + DEBUGASSERT(priv->rxresult == EINPROGRESS || priv->txresult == EINPROGRESS); + if (priv->rxresult == EINPROGRESS) + { + priv->rxresult = ETIMEDOUT; + spi_dmarxwakeup(priv); + } + + if (priv->txresult == EINPROGRESS) + { + priv->txresult = ETIMEDOUT; + spi_dmatxwakeup(priv); + } +} +#endif + +/**************************************************************************** + * Name: spi_dmarxwait + * + * Description: + * Wait for RX DMA to complete. + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmarxwait(struct efm32_spidev_s *priv) +{ + irqstate_t flags; + + /* Take the semaphore (perhaps waiting). */ + + flags = enter_critical_section(); + while (sem_wait(&priv->rxdmasem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + + /* Cancel the timeout only if both the RX and TX transfers have completed */ + + DEBUGASSERT(priv->rxresult != EINPROGRESS); + if (priv->txresult != EINPROGRESS) + { + wd_cancel(priv->wdog); + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxwait + * + * Description: + * Wait for DMA to complete. + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmatxwait(struct efm32_spidev_s *priv) +{ + irqstate_t flags; + + /* Take the semaphore (perhaps waiting). */ + + flags = enter_critical_section(); + while (sem_wait(&priv->txdmasem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + + /* Cancel the timeout only if both the RX and TX transfers have completed */ + + DEBUGASSERT(priv->txresult != EINPROGRESS); + if (priv->rxresult != EINPROGRESS) + { + wd_cancel(priv->wdog); + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxwakeup + * + * Description: + * Signal that DMA is complete + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static inline void spi_dmarxwakeup(struct efm32_spidev_s *priv) +{ + (void)sem_post(&priv->rxdmasem); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxwakeup + * + * Description: + * Signal that DMA is complete + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static inline void spi_dmatxwakeup(struct efm32_spidev_s *priv) +{ + (void)sem_post(&priv->txdmasem); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)arg; + DEBUGASSERT(priv && status != EINPROGRESS); + + /* Wake-up the SPI driver */ + + priv->rxresult = status; + spi_dmarxwakeup(priv); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxcallback + * + * Description: + * Called when the RX DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)arg; + DEBUGASSERT(priv && status != EINPROGRESS); + + /* Wake-up the SPI driver */ + + priv->txresult = status; + spi_dmatxwakeup(priv); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxsetup + * + * Description: + * Setup to perform RX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmarxsetup(struct efm32_spidev_s *priv, void *rxbuffer, + void *rxdummy, size_t nwords) +{ + const struct efm32_spiconfig_s *config = priv->config; + dma_config_t dmaconfig = config->rxconfig; + size_t nbytes; + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + dmaconfig |= SPI_DMA16_CONFIG; + } + else + { + rxbuffer = rxdummy; + dmaconfig |= SPI_DMA16NULL_CONFIG; + } + + nbytes = nwords << 1; + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + dmaconfig |= SPI_DMA8_CONFIG; + } + else + { + rxbuffer = rxdummy; + dmaconfig |= SPI_DMA8NULL_CONFIG; + } + + nbytes = nwords; + } + + /* Configure the RX DMA */ + + efm32_rxdmasetup(priv->rxdmach, config->base + EFM32_USART_RXDATA_OFFSET, + (uintptr_t)rxbuffer, nbytes, dmaconfig); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxsetup + * + * Description: + * Setup to perform TX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmatxsetup(struct efm32_spidev_s *priv, const void *txbuffer, + const void *txdummy, size_t nwords) +{ + const struct efm32_spiconfig_s *config = priv->config; + dma_config_t dmaconfig = config->txconfig; + size_t nbytes; + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (txbuffer) + { + dmaconfig |= SPI_DMA16_CONFIG; + } + else + { + txbuffer = txdummy; + dmaconfig |= SPI_DMA16NULL_CONFIG; + } + + nbytes = nwords << 1; + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (txbuffer) + { + dmaconfig |= SPI_DMA8_CONFIG; + } + else + { + txbuffer = txdummy; + dmaconfig |= SPI_DMA8NULL_CONFIG; + } + + nbytes = nwords; + } + + /* Configure the RX DMA */ + + efm32_txdmasetup(priv->txdmach, config->base + EFM32_USART_TXDATA_OFFSET, + (uintptr_t)txbuffer, nbytes, dmaconfig); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxstart + * + * Description: + * Start RX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_dmarxstart(FAR struct efm32_spidev_s *priv) +{ + priv->rxresult = EINPROGRESS; + efm32_dmastart(priv->rxdmach, spi_dmarxcallback, priv); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxstart + * + * Description: + * Start TX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static inline void spi_dmatxstart(FAR struct efm32_spidev_s *priv) +{ + priv->txresult = EINPROGRESS; + efm32_dmastart(priv->txdmach, spi_dmatxcallback, priv); +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(struct spi_dev_s *dev, bool lock) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_select + * + * Description: + * Enable/disable the SPI chip select. + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - true: slave selected, false: slave de-selected + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + DEBUGASSERT(config->select); + + /* Defer to the board chip select logic */ + + config->select(dev, devid, selected); +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + uint32_t clkdiv; + uint32_t actual; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Has the frequency changed? */ + + if (frequency == priv->frequency) + { + /* No... just return the actual frequency from the last calcualtion */ + + actual = priv->actual; + } + else + { + /* We want to use integer division to avoid forcing in float division + * utils, and yet keep rounding effect errors to a minimum. + * + * CLKDIV in synchronous mode is given by: + * + * CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1) + * or + * CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256 = (128 * fHFPERCLK)/br - 256 + * + * The basic problem with integer division in the above formula is that + * the dividend (128 * fHFPERCLK) may become higher than max 32 bit + * integer. Yet, we want to evaluate dividend first before dividing in + * order to get as small rounding effects as possible. We do not want + * to make too harsh restrictions on max fHFPERCLK value either. + * + * One can possibly factorize 128 and br. However, since the last + * 6 bits of CLKDIV are don't care, we can base our integer arithmetic + * on the below formula without loosing any extra precision: + * + * CLKDIV / 64 = (2 * fHFPERCLK)/br - 4 + * + * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK + * up to 2GHz without overflowing a 32 bit value! + */ + + /* Calculate and set CLKDIV with fractional bits */ + + clkdiv = (2 * BOARD_HFPERCLK_FREQUENCY + (frequency - 1)) / frequency; + clkdiv = 64 * (clkdiv - 4); + + /* Make sure we don't use fractional bits by rounding CLKDIV up (and + * thus reducing baudrate, not increasing baudrate above. + * specified value). + */ + + clkdiv = (clkdiv + 0xc0) & 0xffffff00; + + /* Verify that resulting clock divider is within limits */ + + DEBUGASSERT(clkdiv <= _USART_CLKDIV_MASK); + + clkdiv &= _USART_CLKDIV_DIV_MASK; + spi_putreg(config, EFM32_USART_CLKDIV_OFFSET, clkdiv); + + /* The actual frequency is then given by: + * + * br = fHFPERCLK / (2 * (1 + CLKDIV / 256)) + * = 128 * fHFPERCLK / (256 + CLKDIV) + */ + + actual = (BOARD_HFPERCLK_FREQUENCY << 7) / (256 + clkdiv); + spivdbg("frequency=%u actual=%u\n", frequency, actual); + + /* Save the frequency selection so that subsequent reconfigurations + * will be faster. + */ + + priv->frequency = frequency; + priv->actual = actual; + } + + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns void + * + ****************************************************************************/ + +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + uint32_t setting; + uint32_t regval; + + spivdbg("mode=%d\n", mode); + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + setting = 0; + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setting = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setting = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setting = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setting = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING; + break; + + default: + return; + } + + regval = spi_getreg(config, EFM32_USART_CTRL_OFFSET); + regval &= ~(_USART_CTRL_CLKPOL_MASK | _USART_CTRL_CLKPHA_MASK); + regval |= setting; + spi_putreg(config, EFM32_USART_CTRL_OFFSET, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + uint32_t regval; + uint32_t setting; + bool lsbfirst; + + spivdbg("nbits=%d\n", nbits); + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Bit order is encoded by the sign of nbits */ + + if (nbits < 0) + { + /* LSB first */ + + lsbfirst = true; + nbits = -nbits; + } + else + { + /* MSH first */ + + lsbfirst = false; + } + + /* Has the number of bits or the bit order changed? */ + + if (nbits != priv->nbits || lsbfirst != priv->lsbfirst) + { + /* Set the new bit order */ + + regval = spi_getreg(config, EFM32_USART_CTRL_OFFSET); + if (lsbfirst) + { + regval &= ~USART_CTRL_MSBF; + } + else + { + regval |= USART_CTRL_MSBF; + } + + spi_putreg(config, EFM32_USART_CTRL_OFFSET, regval); + + /* Select the new number of bits */ + + switch (nbits) + { + case 4: + setting = USART_FRAME_DATABITS_FOUR; + break; + + case 5: + setting = USART_FRAME_DATABITS_FIVE; + break; + + case 6: + setting = USART_FRAME_DATABITS_SIX; + break; + + case 7: + setting = USART_FRAME_DATABITS_SEVEN; + break; + + case 8: + setting = USART_FRAME_DATABITS_EIGHT; + break; + + case 9: + setting = USART_FRAME_DATABITS_NINE; + break; + + case 10: + setting = USART_FRAME_DATABITS_TEN; + break; + + case 11: + setting = USART_FRAME_DATABITS_ELEVEN; + break; + + case 12: + setting = USART_FRAME_DATABITS_TWELVE; + break; + + case 13: + setting = USART_FRAME_DATABITS_THIRTEEN; + break; + + case 14: + setting = USART_FRAME_DATABITS_FOURTEEN; + break; + + case 15: + setting = USART_FRAME_DATABITS_FIFTEEN; + break; + + case 16: + setting = USART_FRAME_DATABITS_SIXTEEN; + break; + + default: + return; + } + + regval = spi_getreg(config, EFM32_USART_FRAME_OFFSET); + regval &= _USART_FRAME_DATABITS_MASK; + regval |= setting; + spi_putreg(config, EFM32_USART_FRAME_OFFSET, regval); + + /* Save the selection so the subsequence re-configurations will be + * faster + */ + + priv->nbits = nbits; + priv->lsbfirst = lsbfirst; + } +} + +/**************************************************************************** + * Name: spi_status + * + * Description: + * Get SPI/MMC status. Optional. + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to report status on + * + * Returned Value: + * Returns a bitset of status values (see SPI_STATUS_* defines) + * + ****************************************************************************/ + +static uint8_t spi_status(struct spi_dev_s *dev, enum spi_dev_e devid) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Defer to the board chip status logic */ + + return config->status(dev, devid); +} + +/**************************************************************************** + * Name: spi_cmddata + * + * Description: + * Some devices require and additional out-of-band bit to specify if the + * next word sent to the device is a command or data. This is typical, for + * example, in "9-bit" displays where the 9th bit is the CMD/DATA bit. + * This function provides selection of command or data. + * + * This "latches" the CMD/DATA state. It does not have to be called before + * every word is transferred; only when the CMD/DATA state changes. This + * method is required if CONFIG_SPI_CMDDATA is selected in the NuttX + * configuration + * + * Input Parameters: + * dev - Device-specific state data + * cmd - TRUE: The following word is a command; FALSE: the following words + * are data. + * + * Returned Value: + * OK unless an error occurs. Then a negated errno value is returned + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +static int spi_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + DEBUGASSERT(config->cmddata); + + /* Defer to the board chip cmd/data logic */ + + return config->cmddata(dev, devid, cmd); +} +#endif + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * Response + * + ****************************************************************************/ + +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + uint16_t ret; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Wait until there is space in the TX buffer */ + + spi_wait_status(config, _USART_STATUS_TXBL_MASK, USART_STATUS_TXBL); + + /* Flush any unread data */ + + spi_rxflush(config); + + /* Write the data */ + + spi_putreg(config, EFM32_USART_TXDATA_OFFSET, (uint32_t)wd); + + /* Wait for receive data to be available */ + + spi_wait_status(config, _USART_STATUS_RXDATAV_MASK, USART_STATUS_RXDATAV); + ret = (uint16_t)spi_getreg(config, EFM32_USART_RXDATA_OFFSET); + + spivdbg("Sent: %04x Return: %04x \n", wd, ret); + return ret; +} + +/**************************************************************************** + * Name: spi_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_EFM32_SPI_DMA) && CONFIG_EFM32_SPI_DMA_MINSIZE > 0 +static void spi_exchange_nodma(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#else +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#endif +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + const struct efm32_spiconfig_s *config; + size_t unrecvd; + size_t unsent; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Flush any unread data */ + + spi_rxflush(config); + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + unrecvd = nwords; + unsent = nwords; + while (unrecvd > 0) + { + /* REVISIT: Could this cause RX data overruns??? */ + /* Send data if there is space in the TX buffer. */ + + if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) != 0 && + unsent > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Send one word */ + + spi_putreg(config, EFM32_USART_TXDATA_OFFSET, (uint32_t)word); + unsent--; + } + + /* Receive data if there is data available */ + + if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0 && + unrecvd > 0) + { + /* Receive the data */ + + word = (uint16_t)spi_getreg(config, EFM32_USART_RXDATA_OFFSET); + unrecvd--; + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + unrecvd = nwords; + unsent = nwords; + while (unrecvd > 0) + { + /* REVISIT: Could this cause RX data overruns??? */ + /* Send data if there is space in the TX buffer. */ + + if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) != 0 && + unsent > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Send one word */ + + spi_putreg(config, EFM32_USART_TXDATA_OFFSET, (uint32_t)word); + unsent--; + } + + /* Receive data if there is data available */ + + if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0 && + unrecvd > 0) + { + /* Receive the data */ + + word = (uint8_t)spi_getreg(config, EFM32_USART_RXDATA_OFFSET); + unrecvd--; + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + } + + DEBUGASSERT(unsent == 0); +} + +/**************************************************************************** + * Name: spi_exchange (with DMA capability) + * + * Description: + * Exchange a block of data on SPI using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - The length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_SPI_DMA +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +{ + struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev; + static uint16_t rxdummy = 0xffff; + static const uint16_t txdummy = 0xffff; + irqstate_t flags; + uint64_t ticks; + int ret; + + DEBUGASSERT(priv && priv->config); + +#if CONFIG_EFM32_SPI_DMA_MINSIZE > 0 + if (nwords <= CONFIG_EFM32_SPI_DMA_MINSIZE) + { + /* Small transfer, fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + } + else +#endif + { + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", + txbuffer, rxbuffer, nwords); + + /* Pre-calculate the timeout value */ + + ticks = (CONFIG_EFM32_SPI_DMA_TIMEO_NSEC * nwords) / NSEC_PER_TICK; + if (ticks < 1) + { + ticks = 1; + } + + /* Setup DMAs */ + + spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords); + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords); + + /* Start the DMAs */ + + flags = enter_critical_section(); + spi_dmarxstart(priv); + spi_dmatxstart(priv); + + /* Start a timer to catch hung DMA transfers. Timeout will be canceled + * when both RX and TX transfers complete. + */ + + ret = wd_start(priv->wdog, (int)ticks, spi_dma_timeout, 1, (uint32_t)priv); + if (ret < 0) + { + spidbg("ERROR: Failed to start timeout\n"); + } + + /* Then wait for each to complete. TX should complete first */ + + spi_dmatxwait(priv); + spi_dmarxwait(priv); + leave_critical_section(flags); + } +} +#endif /* CONFIG_EFM32_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - The length of data to send from the buffer in number of + * words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits + * <= 8, the data is packed into uint8_t's; if nbits >8, the + * data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer, + size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - The length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number + * of bits-per-word selected for the SPI interface. If nbits + * <= 8, the data is packed into uint8_t's; if nbits >8, the + * data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(struct spi_dev_s *dev, void *rxbuffer, + size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_portinitialize + * + * Description: + * Initialize the selected SPI port in its default state (Master, 8-bit, + * mode 0, etc.) + * + * Input Parameter: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_portinitialize(struct efm32_spidev_s *priv) +{ + const struct efm32_spiconfig_s *config = priv->config; + uint32_t regval; + + /* Initialize USART registers to HW reset state. */ + + efm32_uart_reset(config->base); + + /* NOTES: + * + * 1. USART GPIO pins were configured in efm32_lowsetup(). Chip select + * pins must be configured by board specific logic before + * efm32_spibus_initialize() is called. + * 2. Clocking for the USART as also enabled in efm32_lowsetup(); + */ + + /* Set bits for synchronous mode */ + + regval = _USART_CTRL_RESETVALUE | USART_CTRL_SYNC | USART_CTRL_CLKPOL_IDLELOW | + USART_CTRL_CLKPHA_SAMPLELEADING; + + /* MSB First, 8 bits */ + + regval &= ~_USART_FRAME_DATABITS_MASK; + regval |= USART_FRAME_DATABITS_EIGHT | USART_CTRL_MSBF; + spi_putreg(config, EFM32_USART_CTRL_OFFSET, regval); + + priv->frequency = 0; + priv->mode = SPIDEV_MODE0; + priv->nbits = 8; + priv->lsbfirst = false; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((struct spi_dev_s *)priv, 400000); + + /* Master mode */ + + spi_putreg(config, EFM32_USART_CMD_OFFSET, USART_CMD_MASTEREN); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_EFM32_SPI_DMA + /* Allocate two DMA channels... one for the RX and one for the TX side of + * the transfer. + */ + + priv->rxdmach = efm32_dmachannel(); + if (!priv->rxdmach) + { + spidbg("ERROR: Failed to allocate the RX DMA channel for SPI port: %d\n", + port); + goto errout; + } + + priv->txdmach = efm32_dmachannel(); + if (!priv->txdmach) + { + spidbg("ERROR: Failed to allocate the TX DMA channel for SPI port: %d\n", + port); + goto errout_with_rxdmach; + } + + /* Allocate a timer to catch hung DMA transfers */ + + priv->wdog = wd_create(); + if (!priv->wdog) + { + spidbg("ERROR: Failed to create a timer for SPI port: %d\n", port); + goto errout_with_txdmach; + } + + /* Initialized semaphores used to wait for DMA completion */ + + (void)sem_init(&priv->rxdmasem, 0, 0); + (void)sem_init(&priv->txdmasem, 0, 0); +#endif + + /* Enable SPI */ + + spi_putreg(config, EFM32_USART_CMD_OFFSET, USART_CMD_RXEN | USART_CMD_TXEN); + return OK; + +#ifdef CONFIG_EFM32_SPI_DMA +errout_with_txdmach: + efm32_dmafree(priv->txdmach); + priv->txdmach = NULL; + +errout_with_rxdmach: + efm32_dmafree(priv->rxdmach); + priv->rxdmach = NULL; + +errout: + return -EBUSY; +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * port - SPI port number to initialize. One of {0,1,2} + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *efm32_spibus_initialize(int port) +{ + const struct efm32_spiconfig_s *config; + struct efm32_spidev_s *priv; + irqstate_t flags; + int ret; + +#ifdef CONFIG_EFM32_USART0_ISSPI + if (port == 0) + { + priv = &g_spi0dev; + config = &g_spi0config; + if (!priv->initialized) + { + efm32_configgpio(BOARD_SPI0_CLK); + efm32_configgpio(BOARD_SPI0_MOSI); + efm32_configgpio(BOARD_SPI0_MISO); + } + } + else +#endif +#ifdef CONFIG_EFM32_USART1_ISSPI + if (port == 1) + { + priv = &g_spi1dev; + config = &g_spi1config; + if (!priv->initialized) + { + efm32_configgpio(BOARD_SPI1_CLK); + efm32_configgpio(BOARD_SPI1_MOSI); + efm32_configgpio(BOARD_SPI1_MISO); + } + } + else +#endif +#ifdef CONFIG_EFM32_USART2_ISSPI + if (port == 2) + { + priv = &g_spi2dev; + config = &g_spi2config; + if (!priv->initialized) + { + efm32_configgpio(BOARD_SPI2_CLK); + efm32_configgpio(BOARD_SPI2_MOSI); + efm32_configgpio(BOARD_SPI2_MISO); + } + } + else +#endif + { + spidbg("ERROR: Unsupported SPI port: %d\n", port); + return NULL; + } + + /* Has this port been initialized yet? */ + + if (!priv->initialized) + { + /* No, then initialize it now */ + + flags = enter_critical_section(); + + /* Initialize the state structure */ + + priv->spidev = &g_spiops; + priv->config = config; + + /* Initialize the SPI device */ + + ret = spi_portinitialize(priv); + if (ret < 0) + { + spidbg("ERROR: Failed to initialize SPI port %d\n", port); + leave_critical_section(flags); + return NULL; + } + + /* Now we are initialized */ + + priv->initialized = true; + leave_critical_section(flags); + } + + return (struct spi_dev_s *)priv; +} + +#endif /* HAVE_SPI_DEVICE */ diff --git a/arch/arm/src/efm32/efm32_spi.h b/arch/arm/src/efm32/efm32_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..315eb0615d7baa174c3b21a4a61174fca99fdf07 --- /dev/null +++ b/arch/arm/src/efm32/efm32_spi.h @@ -0,0 +1,127 @@ +/**************************************************************************** + * arm/arm/src/efm32/efm32_spi.h + * + * Copyright (C) 2009-2013 Bouteville Pierre-Noel. All rights reserved. + * Author: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_EFM32_EFM32_SPI_H +#define __ARCH_ARM_EFM32_EFM32_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "efm32_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: efm32_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * port - SPI port number to initialize. One of {0,1,2} + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *efm32_spibus_initialize(int port); + +/**************************************************************************** + * Name: efm32_spi[n]_select, efm32_spi[n]_status, and efm32_spi[n]_cmddata + * + * Description: + * The external functions, efm32_spi[n]_select, efm32_spi[n]_status, and + * efm32_spi[n]_cmddata must be provided by board-specific logic. These + * are implementations of the select, status, and cmddata methods of the + * SPI interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). + * All other methods (including efm32_spibus_initialize()) are provided by common + * EFM32 logic. To use this common SPI logic on your board: + * + * 1. Provide logic in efm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide efm32_spi[n]_select() and efm32_spi[n]_status() functions in + * your board-specific logic. These functions will perform chip + * selection and status operations using GPIOs in the way your board is + * configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, + * then provide efm32_spi[n]_cmddata() functions in your board-specific + * logic. These functions will perform cmd/data selection operations + * using GPIOs in the way your board is configured. + * 4. Add a calls to efm32_spibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by efm32_spibus_initialize() may then be used to bind + * the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_USART0_ISSPI +void efm32_spi0_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t efm32_spi0_status(struct spi_dev_s *dev, enum spi_dev_e devid); +int efm32_spi0_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +#endif + +#ifdef CONFIG_EFM32_USART1_ISSPI +void efm32_spi1_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t efm32_spi1_status(struct spi_dev_s *dev, enum spi_dev_e devid); +int efm32_spi1_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +#endif + +#ifdef CONFIG_EFM32_USART2_ISSPI +void efm32_spi2_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t efm32_spi2_status(struct spi_dev_s *dev, enum spi_dev_e devid); +int efm32_spi2_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid, + bool cmd); +#endif + +#endif /* __ARCH_ARM_EFM32_EFM32_SPI_H */ diff --git a/arch/arm/src/efm32/efm32_start.c b/arch/arm/src/efm32/efm32_start.c new file mode 100644 index 0000000000000000000000000000000000000000..ec0171f2307b17cc93b29c239364aedf98435788 --- /dev/null +++ b/arch/arm/src/efm32/efm32_start.c @@ -0,0 +1,317 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_start.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "efm32_config.h" +#include "efm32_lowputc.h" +#include "efm32_clockconfig.h" +#include "efm32_start.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void efm32_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked,no_instrument_function,noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# if defined(CONFIG_ARMV7M_ITMSYSLOG) +# define showprogress(c) (void)syslog_putc(c) +# elif defined(HAVE_UART_CONSOLE) || defined(HAVE_LEUART_CONSOLE) +# define showprogress(c) efm32_lowputc(c) +# else +# define showprogress(c) +# endif +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Name: efm32_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void efm32_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void efm32_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define efm32_fpuconfig() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Configure the uart so that we can get debug output as soon as possible */ + + efm32_clockconfig(); + efm32_fpuconfig(); + efm32_lowsetup(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + + up_earlyserialinit(); + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_NUTTX_KERNEL + efm32_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + efm32_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/efm32/efm32_start.h b/arch/arm/src/efm32/efm32_start.h new file mode 100644 index 0000000000000000000000000000000000000000..8b73d92f2239612a953ed6e87036e55d4fff7a10 --- /dev/null +++ b/arch/arm/src/efm32/efm32_start.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_start.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_START_H +#define __ARCH_ARM_SRC_EFM32_EFM32_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_boardinitialize + * + * Description: + * All EFM32 architectures must provide the following entry point. This + * entry point is called early in the initialization before any devices + * have been initialized. + * + ****************************************************************************/ + +void efm32_boardinitialize(void); + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_START_H */ diff --git a/arch/arm/src/efm32/efm32_timer.c b/arch/arm/src/efm32/efm32_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..19c50b56c20e7dd9de87526934eaf1344ded0de2 --- /dev/null +++ b/arch/arm/src/efm32/efm32_timer.c @@ -0,0 +1,271 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_timer.c + * + * Copyright (C) 2014 Pierre-Noel Bouteville. All rights reserved. + * Author: Pierre-Noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/efm32_timer.h" +#include "efm32_config.h" +#include "efm32_gpio.h" + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing TIMER */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_TIMER +#endif + +#ifdef CONFIG_DEBUG_TIMER +# define efm32_timerdbg dbg +# define efm32_timerlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define efm32_timervdbg vdbg +# define efm32_timerllvdbg llvdbg +# define efm32_timer_dumpgpio(p,m) efm32_dumpgpio(p,m) +# else +# define efm32_timerlldbg(x...) +# define efm32_timerllvdbg(x...) +# define efm32_timer_dumpgpio(p,m) +# endif +#else +# define efm32_timerdbg(x...) +# define efm32_timerlldbg(x...) +# define efm32_timervdbg(x...) +# define efm32_timerllvdbg(x...) +# define efm32_timer_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_timer_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * base - A base address of timer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void efm32_timer_dumpregs(uintptr_t base, FAR const char *msg) +{ + int i; + + efm32_timervdbg("%s:\n", msg); + efm32_timervdbg(" CTRL: %04x STATUS: %04x IEN: %04x IF: %04x\n", + getreg32(base + EFM32_TIMER_CTRL_OFFSET ), + getreg32(base + EFM32_TIMER_STATUS_OFFSET ), + getreg32(base + EFM32_TIMER_IEN_OFFSET ), + getreg32(base + EFM32_TIMER_IF_OFFSET ) + ); + efm32_timervdbg(" TOP: %04x TOPB: %04x CNT: %04x ROUTE: %04x\n", + getreg32(base + EFM32_TIMER_TOP_OFFSET ), + getreg32(base + EFM32_TIMER_TOPB_OFFSET ), + getreg32(base + EFM32_TIMER_CNT_OFFSET ), + getreg32(base + EFM32_TIMER_ROUTE_OFFSET ) + ); + + for (i = 0; i < EFM32_TIMER_NCC; i++) + { +#if defined(CONFIG_DEBUG_TIMER) && defined(CONFIG_DEBUG_VERBOSE) + uintptr_t base_cc = base + EFM32_TIMER_CC_OFFSET(i); +#endif + efm32_timervdbg("CC%d => CTRL: %04x CCV: %04x CCVP: %04x CCVB: %04x\n", + i + getreg32(base_cc + EFM32_TIMER_CC_CTRL_OFFSET ), + getreg32(base_cc + EFM32_TIMER_CC_CCV_OFFSET ), + getreg32(base_cc + EFM32_TIMER_CC_CCVP_OFFSET ), + getreg32(base_cc + EFM32_TIMER_CC_CCVB_OFFSET ) + ); + } + + efm32_timervdbg("DTCTRL: %04x DTTIME: %04x DTFC: %04x DTOGEN: %04x\n", + getreg32(base + EFM32_TIMER_CTRL_OFFSET ), + getreg32(base + EFM32_TIMER_STATUS_OFFSET ), + getreg32(base + EFM32_TIMER_IEN_OFFSET ), + getreg32(base + EFM32_TIMER_IF_OFFSET ) + ); + efm32_timervdbg("DTFAULT: %04x DTFAULTC: %04x DTLOCK: %04x \n", + getreg32(base + EFM32_TIMER_CTRL_OFFSET ), + getreg32(base + EFM32_TIMER_STATUS_OFFSET ), + getreg32(base + EFM32_TIMER_IEN_OFFSET ), + getreg32(base + EFM32_TIMER_IF_OFFSET ) + ); +} + +/**************************************************************************** + * Name: efm32_timer_reset + * + * Description: + * reset timer into reset state + * + * Input parameters: + * base - A base address of timer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void efm32_timer_reset(uintptr_t base) +{ + int i; + + /* Make sure disabled first, before resetting other registers */ + + putreg32(TIMER_CMD_STOP, base + EFM32_TIMER_CMD_OFFSET); + + /* Reset timer register */ + + putreg32(_TIMER_CTRL_RESETVALUE, base + EFM32_TIMER_CTRL_OFFSET ); + putreg32(_TIMER_IEN_RESETVALUE, base + EFM32_TIMER_STATUS_OFFSET ); + putreg32(_TIMER_IFC_MASK, base + EFM32_TIMER_IEN_OFFSET ); + putreg32(_TIMER_TOP_RESETVALUE, base + EFM32_TIMER_IF_OFFSET ); + putreg32(_TIMER_TOPB_RESETVALUE, base + EFM32_TIMER_CTRL_OFFSET ); + putreg32(_TIMER_CNT_RESETVALUE, base + EFM32_TIMER_CMD_OFFSET ); + + /* Do not reset route register, setting should be done independently + * (Note: ROUTE register may be locked by DTLOCK register.) + */ + + //putreg32(_TIMER_ROUTE_RESETVALUE, base + EFM32_TIMER_ROUTE_OFFSET ); + + for (i = 0; i < EFM32_TIMER_NCC; i++) + { + uintptr_t base_cc = base + EFM32_TIMER_CC_OFFSET(i); + putreg32(_TIMER_CC_CTRL_RESETVALUE, base_cc+EFM32_TIMER_CC_CTRL_OFFSET); + putreg32(_TIMER_CC_CCV_RESETVALUE, base_cc+EFM32_TIMER_CC_CCV_OFFSET ); + putreg32(_TIMER_CC_CCVB_RESETVALUE, base_cc+EFM32_TIMER_CC_CCVB_OFFSET); + } + + /* Reset dead time insertion module, no effect on timers without DTI */ + +#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK + /* Unlock DTI registers first in case locked */ + + putreg32(TIMER_DTLOCK_LOCKKEY_UNLOCK, base + EFM32_TIMER_DTLOCK_OFFSET); + + putreg32(_TIMER_DTCTRL_RESETVALUE, base + EFM32_TIMER_DTCTRL_OFFSET); + putreg32(_TIMER_DTTIME_RESETVALUE, base + EFM32_TIMER_DTTIME_OFFSET); + putreg32(_TIMER_DTFC_RESETVALUE, base + EFM32_TIMER_DTFC_OFFSET); + putreg32(_TIMER_DTOGEN_RESETVALUE,base + EFM32_TIMER_DTOGEN_OFFSET); + putreg32(_TIMER_DTFAULTC_MASK, base + EFM32_TIMER_DTFAULTC_OFFSET); +#endif +} + +/**************************************************************************** + * Name: efm32_timer_set_freq + * + * Description: + * set prescaler and top timer with best value to have "freq" + * + * Input parameters: + * base - A base address of timer + * clk_freq - Clock soure of timer. + * freq - Wanted freqency. + * + * Returned Value: + * prescaler setted, -1 in case of error. + * + ****************************************************************************/ +int efm32_timer_set_freq(uintptr_t base, uint32_t clk_freq, uint32_t freq) +{ + int prescaler = 0; + int cnt_freq = clk_freq >> 16; + int reload; + + while (cnt_freq > freq) + { + prescaler++; + cnt_freq >>= 1; + if (prescaler > (_TIMER_CTRL_PRESC_MASK >> _TIMER_CTRL_PRESC_SHIFT)) + { + return -1; + } + } + + modifyreg32(base + EFM32_TIMER_CTRL_OFFSET, + _TIMER_CTRL_PRESC_MASK, + prescaler << _TIMER_CTRL_PRESC_SHIFT); + + prescaler = 1 << prescaler; + + reload = (clk_freq / prescaler / freq); + + efm32_timerdbg("Source: %4xHz Div: %4x Reload: %4x \n", + clk_freq, prescaler, reload); + + putreg32(reload, base + EFM32_TIMER_TOP_OFFSET); + + return prescaler; +} diff --git a/arch/arm/src/efm32/efm32_timer.h b/arch/arm/src/efm32/efm32_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..3ed36baad78291c250d9b6e57215eb338853910b --- /dev/null +++ b/arch/arm/src/efm32/efm32_timer.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_timer.h + * + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Authors: Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_TIMER_H +#define __ARCH_ARM_SRC_EFM32_EFM32_TIMER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/efm32_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +void efm32_timer_reset(uintptr_t base); +void efm32_timer_dumpregs(uintptr_t base, FAR const char *msg); +int efm32_timer_set_freq(uintptr_t base, uint32_t clk_freq, uint32_t freq); + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_TIMER_H */ + diff --git a/arch/arm/src/efm32/efm32_timerisr.c b/arch/arm/src/efm32/efm32_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..4810d5c3b6ea60a87a645fc45dde662174adeb24 --- /dev/null +++ b/arch/arm/src/efm32/efm32_timerisr.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_timerisr.c + * + * Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014 Pierre-noel Bouteville . All rights reserved. + * Author: Gregory Nutt + * Pierre-noel Bouteville + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + */ + +#define SYSTICK_RELOAD ((BOARD_HFCORECLK_FREQUENCY / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set correctly */ + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(EFM32_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(EFM32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/efm32/efm32_usb.h b/arch/arm/src/efm32/efm32_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..7b31eb467a356cc64816b2cfb6f1d40782c6f495 --- /dev/null +++ b/arch/arm/src/efm32/efm32_usb.h @@ -0,0 +1,225 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_usb.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_OTGFS_H +#define __ARCH_ARM_SRC_EFM32_EFM32_OTGFS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip/efm32_usb.h" + +#if defined(CONFIG_EFM32_OTGFS) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifndef CONFIG_OTGFS_PRI +# define CONFIG_OTGFS_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#if defined(HAVE_USBHOST_TRACE) && defined(CONFIG_EFM32_OTGFS) +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + USBHOST_TRACE1_DEVDISCONN, /* OTGFS ERROR: Host Port Device disconnected */ + USBHOST_TRACE1_IRQATTACH, /* OTGFS ERROR: Failed to attach IRQ */ + USBHOST_TRACE1_TRNSFRFAILED, /* OTGFS ERROR: Host Port Transfer Failed */ + USBHOST_TRACE1_SENDSETUP, /* OTGFS ERROR: sendsetup() failed with: */ + USBHOST_TRACE1_SENDDATA, /* OTGFS ERROR: senddata() failed with: */ + USBHOST_TRACE1_RECVDATA, /* OTGFS ERROR: recvdata() failed with: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + USBHOST_VTRACE1_CONNECTED, /* OTGFS Host Port connected */ + USBHOST_VTRACE1_DISCONNECTED, /* OTGFS Host Port disconnected */ + USBHOST_VTRACE1_GINT, /* OTGFS Handling Interrupt. Entry Point */ + USBHOST_VTRACE1_GINT_SOF, /* OTGFS Handle the start of frame interrupt */ + USBHOST_VTRACE1_GINT_RXFLVL, /* OTGFS Handle the RxFIFO non-empty interrupt */ + USBHOST_VTRACE1_GINT_NPTXFE, /* OTGFS Handle the non-periodic TxFIFO empty interrupt */ + USBHOST_VTRACE1_GINT_PTXFE, /* OTGFS Handle the periodic TxFIFO empty interrupt */ + USBHOST_VTRACE1_GINT_HC, /* OTGFS Handle the host channels interrupt */ + USBHOST_VTRACE1_GINT_HPRT, /* OTGFS Handle the host port interrupt */ + USBHOST_VTRACE1_GINT_HPRT_POCCHNG, /* OTGFS HPRT: Port Over-Current Change*/ + USBHOST_VTRACE1_GINT_HPRT_PCDET, /* OTGFS HPRT: Port Connect Detect */ + USBHOST_VTRACE1_GINT_HPRT_PENCHNG, /* OTGFS HPRT: Port Enable Changed */ + USBHOST_VTRACE1_GINT_HPRT_LSDEV, /* OTGFS HPRT: Low Speed Device Connected */ + USBHOST_VTRACE1_GINT_HPRT_FSDEV, /* OTGFS HPRT: Full Speed Device Connected */ + USBHOST_VTRACE1_GINT_HPRT_LSFSSW, /* OTGFS HPRT: Host Switch: LS -> FS */ + USBHOST_VTRACE1_GINT_HPRT_FSLSSW, /* OTGFS HPRT: Host Switch: FS -> LS */ + USBHOST_VTRACE1_GINT_DISC, /* OTGFS Handle the disconnect detected interrupt */ + USBHOST_VTRACE1_GINT_IPXFR, /* OTGFS Handle the incomplete periodic transfer */ +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + USBHOST_TRACE2_CLIP, /* OTGFS CLIP: chidx: buflen: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + USBHOST_VTRACE2_CHANWAKEUP_IN, /* OTGFS IN Channel wake up with result */ + USBHOST_VTRACE2_CHANWAKEUP_OUT, /* OTGFS OUT Channel wake up with result */ + USBHOST_VTRACE2_CTRLIN, /* OTGFS CTRLIN */ + USBHOST_VTRACE2_CTRLOUT, /* OTGFS CTRLOUT */ + USBHOST_VTRACE2_INTRIN, /* OTGFS INTRIN */ + USBHOST_VTRACE2_INTROUT, /* OTGFS INTROUT */ + USBHOST_VTRACE2_BULKIN, /* OTGFS BULKIN */ + USBHOST_VTRACE2_BULKOUT, /* OTGFS BULKOUT */ + USBHOST_VTRACE2_ISOCIN, /* OTGFS ISOCIN */ + USBHOST_VTRACE2_ISOCOUT, /* OTGFS ISOCOUT */ + USBHOST_VTRACE2_STARTTRANSFER, /* OTGFS EP buflen */ + USBHOST_VTRACE2_CHANCONF_CTRL_IN, + USBHOST_VTRACE2_CHANCONF_CTRL_OUT, + USBHOST_VTRACE2_CHANCONF_INTR_IN, + USBHOST_VTRACE2_CHANCONF_INTR_OUT, + USBHOST_VTRACE2_CHANCONF_BULK_IN, + USBHOST_VTRACE2_CHANCONF_BULK_OUT, + USBHOST_VTRACE2_CHANCONF_ISOC_IN, + USBHOST_VTRACE2_CHANCONF_ISOC_OUT, + USBHOST_VTRACE2_CHANHALT, /* Channel halted. chidx: , reason: */ +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) + +#endif /* HAVE_USBHOST_TRACE && CONFIG_EFM32_OTGFS */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: efm32_usbhost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +FAR struct usbhost_connection_s *efm32_usbhost_initialize(int controller); +#endif + +/*********************************************************************************** + * Name: efm32_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be provided be + * each platform that implements the EFM32 OTG FS host interface + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interface. Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ***********************************************************************************/ + +#ifdef CONFIG_USBHOST +void efm32_usbhost_vbusdrive(int iface, bool enable); +#endif + +/************************************************************************************ + * Name: efm32_usbsuspend + * + * Description: + * Board logic must provide the efm32_usbsuspend logic if the OTG FS device driver + * is used. This function is called whenever the USB enters or leaves suspend + * mode. This is an opportunity for the board logic to shutdown clocks, power, + * etc. while the USB is suspended. + * + ************************************************************************************/ + +#ifdef CONFIG_USBDEV +struct usbdev_s; +void efm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_EFM32_OTGFS */ +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_OTGFS_H */ diff --git a/arch/arm/src/efm32/efm32_usbdev.c b/arch/arm/src/efm32/efm32_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..fb20993657f4f926aa58d0d9f1cc6ee91a4dcd18 --- /dev/null +++ b/arch/arm/src/efm32/efm32_usbdev.c @@ -0,0 +1,5716 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_usbdev.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/efm32_cmu.h" + +#include "efm32_usb.h" + +#if defined(CONFIG_USBDEV) && (defined(CONFIG_EFM32_OTGFS)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* There is 1.25Kb of FIFO memory. The default partitions this memory + * so that there is a TxFIFO allocated for each endpoint and with more + * memory provided for the common RxFIFO. A more knowledge-able + * configuration would not allocate any TxFIFO space to OUT endpoints. + */ + +#ifndef CONFIG_USBDEV_RXFIFO_SIZE +# define CONFIG_USBDEV_RXFIFO_SIZE 512 +#endif + +#ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 192 +#endif + +#if (CONFIG_USBDEV_RXFIFO_SIZE + CONFIG_USBDEV_EP0_TXFIFO_SIZE + \ + CONFIG_USBDEV_EP2_TXFIFO_SIZE + CONFIG_USBDEV_EP3_TXFIFO_SIZE) > 1280 +# error "FIFO allocations exceed FIFO memory size" +#endif + +/* The actual FIFO addresses that we use must be aligned to 4-byte boundaries; + * FIFO sizes must be provided in units of 32-bit words. + */ + +#define EFM32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3) +#define EFM32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2) + +#define EFM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) +#define EFM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) + +#if EFM32_EP0_TXFIFO_WORDS < 16 || EFM32_EP0_TXFIFO_WORDS > 256 +# error "CONFIG_USBDEV_EP0_TXFIFO_SIZE is out of range" +#endif + +#define EFM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) +#define EFM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) + +#if EFM32_EP1_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP1_TXFIFO_SIZE is out of range" +#endif + +#define EFM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) +#define EFM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) + +#if EFM32_EP2_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP2_TXFIFO_SIZE is out of range" +#endif + +#define EFM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) +#define EFM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) + +#if EFM32_EP3_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range" +#endif + +/* Debug ***********************************************************************/ +/* Trace error codes */ + +#define EFM32_TRACEERR_ALLOCFAIL 0x01 +#define EFM32_TRACEERR_BADCLEARFEATURE 0x02 +#define EFM32_TRACEERR_BADDEVGETSTATUS 0x03 +#define EFM32_TRACEERR_BADEPNO 0x04 +#define EFM32_TRACEERR_BADEPGETSTATUS 0x05 +#define EFM32_TRACEERR_BADGETCONFIG 0x06 +#define EFM32_TRACEERR_BADGETSETDESC 0x07 +#define EFM32_TRACEERR_BADGETSTATUS 0x08 +#define EFM32_TRACEERR_BADSETADDRESS 0x09 +#define EFM32_TRACEERR_BADSETCONFIG 0x0a +#define EFM32_TRACEERR_BADSETFEATURE 0x0b +#define EFM32_TRACEERR_BADTESTMODE 0x0c +#define EFM32_TRACEERR_BINDFAILED 0x0d +#define EFM32_TRACEERR_DISPATCHSTALL 0x0e +#define EFM32_TRACEERR_DRIVER 0x0f +#define EFM32_TRACEERR_DRIVERREGISTERED 0x10 +#define EFM32_TRACEERR_EP0NOSETUP 0x11 +#define EFM32_TRACEERR_EP0SETUPSTALLED 0x12 +#define EFM32_TRACEERR_EPINNULLPACKET 0x13 +#define EFM32_TRACEERR_EPINUNEXPECTED 0x14 +#define EFM32_TRACEERR_EPOUTNULLPACKET 0x15 +#define EFM32_TRACEERR_EPOUTUNEXPECTED 0x16 +#define EFM32_TRACEERR_INVALIDCTRLREQ 0x17 +#define EFM32_TRACEERR_INVALIDPARMS 0x18 +#define EFM32_TRACEERR_IRQREGISTRATION 0x19 +#define EFM32_TRACEERR_NOEP 0x1a +#define EFM32_TRACEERR_NOTCONFIGURED 0x1b +#define EFM32_TRACEERR_EPOUTQEMPTY 0x1c +#define EFM32_TRACEERR_EPINREQEMPTY 0x1d +#define EFM32_TRACEERR_NOOUTSETUP 0x1e +#define EFM32_TRACEERR_POLLTIMEOUT 0x1f + +/* Trace interrupt codes */ + +#define EFM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */ +#define EFM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */ + +#define EFM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */ +#define EFM32_TRACEINTID_EPIN (10 + 1) +#define EFM32_TRACEINTID_MISMATCH (10 + 2) +#define EFM32_TRACEINTID_WAKEUP (10 + 3) +#define EFM32_TRACEINTID_SUSPEND (10 + 4) +#define EFM32_TRACEINTID_SOF (10 + 5) +#define EFM32_TRACEINTID_RXFIFO (10 + 6) +#define EFM32_TRACEINTID_DEVRESET (10 + 7) +#define EFM32_TRACEINTID_ENUMDNE (10 + 8) +#define EFM32_TRACEINTID_IISOIXFR (10 + 9) +#define EFM32_TRACEINTID_IISOOXFR (10 + 10) +#define EFM32_TRACEINTID_SRQ (10 + 11) +#define EFM32_TRACEINTID_OTG (10 + 12) + +#define EFM32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */ +#define EFM32_TRACEINTID_EPOUT_EPDISD (40 + 1) +#define EFM32_TRACEINTID_EPOUT_SETUP (40 + 2) +#define EFM32_TRACEINTID_DISPATCH (40 + 3) + +#define EFM32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */ +#define EFM32_TRACEINTID_EPGETSTATUS (50 + 1) +#define EFM32_TRACEINTID_DEVGETSTATUS (50 + 2) +#define EFM32_TRACEINTID_IFGETSTATUS (50 + 3) +#define EFM32_TRACEINTID_CLEARFEATURE (50 + 4) +#define EFM32_TRACEINTID_SETFEATURE (50 + 5) +#define EFM32_TRACEINTID_SETADDRESS (50 + 6) +#define EFM32_TRACEINTID_GETSETDESC (50 + 7) +#define EFM32_TRACEINTID_GETCONFIG (50 + 8) +#define EFM32_TRACEINTID_SETCONFIG (50 + 9) +#define EFM32_TRACEINTID_GETSETIF (50 + 10) +#define EFM32_TRACEINTID_SYNCHFRAME (50 + 11) + +#define EFM32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */ +#define EFM32_TRACEINTID_EPIN_TOC (70 + 1) +#define EFM32_TRACEINTID_EPIN_ITTXFE (70 + 2) +#define EFM32_TRACEINTID_EPIN_EPDISD (70 + 3) +#define EFM32_TRACEINTID_EPIN_TXFE (70 + 4) + +#define EFM32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */ + +#define EFM32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */ +#define EFM32_TRACEINTID_OUTRECVD (90 + 1) +#define EFM32_TRACEINTID_OUTDONE (90 + 2) +#define EFM32_TRACEINTID_SETUPDONE (90 + 3) +#define EFM32_TRACEINTID_SETUPRECVD (90 + 4) + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define EFM32_NENDPOINTS (7) /* ep0-6 x 2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define EFM32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN) +#define EFM32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT) + +/* Endpoint 0 */ + +#define EP0 (0) + +/* The set of all enpoints available to the class implementation (1-3) */ + +#define EFM32_EP_AVAILABLE (0x0e) /* All available endpoints */ + +/* Maximum packet sizes for full speed endpoints */ + +#define EFM32_MAXPACKET (64) /* Max packet size (1-64) */ + +/* Delays **********************************************************************/ + +#define EFM32_READY_DELAY 200000 +#define EFM32_FLUSH_DELAY 200000 + +/* Request queue operations ****************************************************/ + +#define efm32_rqempty(ep) ((ep)->head == NULL) +#define efm32_rqpeek(ep) ((ep)->head) + +/* Standard stuff **************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Overall device state */ + +enum efm32_devstate_e +{ + DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply + * means that the device is not yet been given an + * address. + * SET: At initialization, uninitialization, + * reset, and whenever the device address + * is set to zero + * TESTED: Never + */ + DEVSTATE_ADDRESSED, /* Device address has been assigned, not no + * configuration has yet been selected. + * SET: When either a non-zero device address + * is first assigned or when the device + * is unconfigured (with configuration == 0) + * TESTED: never + */ + DEVSTATE_CONFIGURED, /* Address assigned and configured: + * SET: When the device has been addressed and + * an non-zero configuration has been selected. + * TESTED: In many places to assure that the USB device + * has been properly configured by the host. + */ +}; + +/* Endpoint 0 states */ + +enum efm32_ep0state_e +{ + EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or + * epsubmit: + * SET: In efm32_epin() and efm32_epout() when + * we revert from request processing to + * SETUP processing. + * TESTED: Never + */ + EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA + * OUT phase of SETUP Packet to complete before + * processing a SETUP command (without a USB request): + * SET: Set in efm32_rxinterrupt() when SETUP OUT + * packet is received. + * TESTED: In efm32_ep0out_receive() + */ + EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and + * accompanying data have been received. Processing + * of SETUP command will happen soon. + * SET: (1) efm32_ep0out_receive() when the OUT + * SETUP data phase completes, or (2) + * efm32_rxinterrupt() when an IN SETUP is + * packet received. + * TESTED: Tested in efm32_epout_interrupt() when + * SETUP phase is done to see if the SETUP + * command is ready to be processed. Also + * tested in efm32_ep0out_setup() just to + * double-check that we have a SETUP request + * and any accompanying data. + */ + EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by efm32_ep0out_setup(): + * SET: When SETUP packet received in EP0 OUT + * TESTED: Never + */ + EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request): + * SET: When SETUP response is sent by + * efm32_ep0in_setupresponse() + * TESTED: Never + */ + EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request): + * SET: In efm32_epin_request() when a write + * request is processed on EP0. + * TESTED: In efm32_epin() to see if we should + * revert to SETUP processing. + */ + EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a + * USB request) + * SET: In efm32_epout_request() when a read + * request is processed on EP0. + * TESTED: In efm32_epout() to see if we should + * revert to SETUP processing + */ +}; + +/* Parsed control request */ + +struct efm32_ctrlreq_s +{ + uint8_t type; + uint8_t req; + uint16_t value; + uint16_t index; + uint16_t len; +}; + +/* A container for a request so that the request may be retained in a list */ + +struct efm32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct efm32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct efm32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct efm32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* EFM32-specific fields */ + + struct efm32_usbdev_s *dev; /* Reference to private driver data */ + struct efm32_req_s *head; /* Request list for this endpoint */ + struct efm32_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t eptype:2; /* Endpoint type */ + uint8_t active:1; /* 1: A request is being processed */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t isin:1; /* 1: IN Endpoint */ + uint8_t odd:1; /* 1: Odd frame */ + uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */ +}; + +/* This structure retains the state of the USB device controller */ + +struct efm32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct efm32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* EFM32-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t addressed:1; /* 1: Peripheral address has been set */ + uint8_t configured:1; /* 1: Class driver has been configured */ + uint8_t wakeup:1; /* 1: Device remote wake-up */ + uint8_t dotest:1; /* 1: Test mode selected */ + + uint8_t devstate:4; /* See enum efm32_devstate_e */ + uint8_t ep0state:4; /* See enum efm32_ep0state_e */ + uint8_t testmode:4; /* Selected test mode */ + uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */ + + /* E0 SETUP data buffering. + * + * ctrlreq: + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The pack receipt logic will save + * the accompanying EP0 IN data in ep0data[] before the SETUP command is + * processed. + * + * For IN SETUP requests, the DATA phase will occurr AFTER the SETUP + * control request is processed. In that case, ep0data[] may be used as + * the response buffer. + * + * ep0datlen + * Lenght of OUT DATA received in ep0data[] (Not used with OUT data) + */ + + struct usb_ctrlreq_s ctrlreq; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint lists */ + + struct efm32_ep_s epin[EFM32_NENDPOINTS]; + struct efm32_ep_s epout[EFM32_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_EFM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t efm32_getreg(uint32_t addr); +static void efm32_putreg(uint32_t val, uint32_t addr); +#else +# define efm32_getreg(addr) getreg32(addr) +# define efm32_putreg(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations ****************************************************/ + +static FAR struct efm32_req_s *efm32_req_remfirst(FAR struct efm32_ep_s *privep); +static bool efm32_req_addlast(FAR struct efm32_ep_s *privep, + FAR struct efm32_req_s *req); + +/* Low level data transfers and request operations *****************************/ +/* Special endpoint 0 data transfer logic */ + +static void efm32_ep0in_setupresponse(FAR struct efm32_usbdev_s *priv, + FAR uint8_t *data, uint32_t nbytes); +static inline void efm32_ep0in_transmitzlp(FAR struct efm32_usbdev_s *priv); +static void efm32_ep0in_activate(void); + +static void efm32_ep0out_ctrlsetup(FAR struct efm32_usbdev_s *priv); + +/* IN request and TxFIFO handling */ + +static void efm32_txfifo_write(FAR struct efm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void efm32_epin_transfer(FAR struct efm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void efm32_epin_request(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep); + +/* OUT request and RxFIFO handling */ + +static void efm32_rxfifo_read(FAR struct efm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len); +static void efm32_rxfifo_discard(FAR struct efm32_ep_s *privep, int len); +static void efm32_epout_complete(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep); +static inline void efm32_ep0out_receive(FAR struct efm32_ep_s *privep, int bcnt); +static inline void efm32_epout_receive(FAR struct efm32_ep_s *privep, int bcnt); +static void efm32_epout_request(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep); + +/* General request handling */ + +static void efm32_ep_flush(FAR struct efm32_ep_s *privep); +static void efm32_req_complete(FAR struct efm32_ep_s *privep, + int16_t result); +static void efm32_req_cancel(FAR struct efm32_ep_s *privep, + int16_t status); + +/* Interrupt handling **********************************************************/ + +static struct efm32_ep_s *efm32_ep_findbyaddr(struct efm32_usbdev_s *priv, + uint16_t eplog); +static int efm32_req_dispatch(FAR struct efm32_usbdev_s *priv, + FAR const struct usb_ctrlreq_s *ctrl); +static void efm32_usbreset(FAR struct efm32_usbdev_s *priv); + +/* Second level OUT endpoint interrupt processing */ + +static inline void efm32_ep0out_testmode(FAR struct efm32_usbdev_s *priv, + uint16_t index); +static inline void efm32_ep0out_stdrequest(struct efm32_usbdev_s *priv, + FAR struct efm32_ctrlreq_s *ctrlreq); +static inline void efm32_ep0out_setup(struct efm32_usbdev_s *priv); +static inline void efm32_epout(FAR struct efm32_usbdev_s *priv, + uint8_t epno); +static inline void efm32_epout_interrupt(FAR struct efm32_usbdev_s *priv); + +/* Second level IN endpoint interrupt processing */ + +static inline void efm32_epin_runtestmode(FAR struct efm32_usbdev_s *priv); +static inline void efm32_epin(FAR struct efm32_usbdev_s *priv, uint8_t epno); +static inline void efm32_epin_txfifoempty(FAR struct efm32_usbdev_s *priv, int epno); +static inline void efm32_epin_interrupt(FAR struct efm32_usbdev_s *priv); + +/* Other second level interrupt processing */ + +static inline void efm32_resumeinterrupt(FAR struct efm32_usbdev_s *priv); +static inline void efm32_suspendinterrupt(FAR struct efm32_usbdev_s *priv); +static inline void efm32_rxinterrupt(FAR struct efm32_usbdev_s *priv); +static inline void efm32_enuminterrupt(FAR struct efm32_usbdev_s *priv); +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void efm32_isocininterrupt(FAR struct efm32_usbdev_s *priv); +static inline void efm32_isocoutinterrupt(FAR struct efm32_usbdev_s *priv); +#endif +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void efm32_sessioninterrupt(FAR struct efm32_usbdev_s *priv); +static inline void efm32_otginterrupt(FAR struct efm32_usbdev_s *priv); +#endif + +/* First level interrupt processing */ + +static int efm32_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ +/* Global OUT NAK controls */ + +static void efm32_enablegonak(FAR struct efm32_ep_s *privep); +static void efm32_disablegonak(FAR struct efm32_ep_s *privep); + +/* Endpoint configuration */ + +static int efm32_epout_configure(FAR struct efm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int efm32_epin_configure(FAR struct efm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int efm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, bool last); +static void efm32_ep0_configure(FAR struct efm32_usbdev_s *priv); + +/* Endpoint disable */ + +static void efm32_epout_disable(FAR struct efm32_ep_s *privep); +static void efm32_epin_disable(FAR struct efm32_ep_s *privep); +static int efm32_ep_disable(FAR struct usbdev_ep_s *ep); + +/* Endpoint request management */ + +static FAR struct usbdev_req_s *efm32_ep_allocreq(FAR struct usbdev_ep_s *ep); +static void efm32_ep_freereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); + +/* Endpoint buffer management */ + +#ifdef CONFIG_USBDEV_DMA +static void *efm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void efm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif + +/* Endpoint request submission */ + +static int efm32_ep_submit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Endpoint request cancellation */ + +static int efm32_ep_cancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Stall handling */ + +static int efm32_epout_setstall(FAR struct efm32_ep_s *privep); +static int efm32_epin_setstall(FAR struct efm32_ep_s *privep); +static int efm32_ep_setstall(FAR struct efm32_ep_s *privep); +static int efm32_ep_clrstall(FAR struct efm32_ep_s *privep); +static int efm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume); +static void efm32_ep0_stall(FAR struct efm32_usbdev_s *priv); + +/* Endpoint allocation */ + +static FAR struct usbdev_ep_s *efm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void efm32_ep_free(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep); + +/* USB device controller operations ********************************************/ + +static int efm32_getframe(struct usbdev_s *dev); +static int efm32_wakeup(struct usbdev_s *dev); +static int efm32_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int efm32_pullup(struct usbdev_s *dev, bool enable); +static void efm32_setaddress(struct efm32_usbdev_s *priv, + uint16_t address); +static int efm32_txfifo_flush(uint32_t txfnum); +static int efm32_rxfifo_flush(void); + +/* Initialization **************************************************************/ + +static void efm32_swinitialize(FAR struct efm32_usbdev_s *priv); +static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct efm32_usbdev_s g_otgfsdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = efm32_ep_configure, + .disable = efm32_ep_disable, + .allocreq = efm32_ep_allocreq, + .freereq = efm32_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = efm32_ep_allocbuffer, + .freebuffer = efm32_ep_freebuffer, +#endif + .submit = efm32_ep_submit, + .cancel = efm32_ep_cancel, + .stall = efm32_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = efm32_ep_alloc, + .freeep = efm32_ep_free, + .getframe = efm32_getframe, + .wakeup = efm32_wakeup, + .selfpowered = efm32_selfpowered, + .pullup = efm32_pullup, +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(EFM32_TRACEERR_ALLOCFAIL ), + TRACE_STR(EFM32_TRACEERR_BADCLEARFEATURE ), + TRACE_STR(EFM32_TRACEERR_BADDEVGETSTATUS ), + TRACE_STR(EFM32_TRACEERR_BADEPNO ), + TRACE_STR(EFM32_TRACEERR_BADEPGETSTATUS ), + TRACE_STR(EFM32_TRACEERR_BADGETCONFIG ), + TRACE_STR(EFM32_TRACEERR_BADGETSETDESC ), + TRACE_STR(EFM32_TRACEERR_BADGETSTATUS ), + TRACE_STR(EFM32_TRACEERR_BADSETADDRESS ), + TRACE_STR(EFM32_TRACEERR_BADSETCONFIG ), + TRACE_STR(EFM32_TRACEERR_BADSETFEATURE ), + TRACE_STR(EFM32_TRACEERR_BADTESTMODE ), + TRACE_STR(EFM32_TRACEERR_BINDFAILED ), + TRACE_STR(EFM32_TRACEERR_DISPATCHSTALL ), + TRACE_STR(EFM32_TRACEERR_DRIVER ), + TRACE_STR(EFM32_TRACEERR_DRIVERREGISTERED), + TRACE_STR(EFM32_TRACEERR_EP0NOSETUP ), + TRACE_STR(EFM32_TRACEERR_EP0SETUPSTALLED ), + TRACE_STR(EFM32_TRACEERR_EPINNULLPACKET ), + TRACE_STR(EFM32_TRACEERR_EPINUNEXPECTED ), + TRACE_STR(EFM32_TRACEERR_EPOUTNULLPACKET ), + TRACE_STR(EFM32_TRACEERR_EPOUTUNEXPECTED ), + TRACE_STR(EFM32_TRACEERR_INVALIDCTRLREQ ), + TRACE_STR(EFM32_TRACEERR_INVALIDPARMS ), + TRACE_STR(EFM32_TRACEERR_IRQREGISTRATION ), + TRACE_STR(EFM32_TRACEERR_NOEP ), + TRACE_STR(EFM32_TRACEERR_NOTCONFIGURED ), + TRACE_STR(EFM32_TRACEERR_EPOUTQEMPTY ), + TRACE_STR(EFM32_TRACEERR_EPINREQEMPTY ), + TRACE_STR(EFM32_TRACEERR_NOOUTSETUP ), + TRACE_STR(EFM32_TRACEERR_POLLTIMEOUT ), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(EFM32_TRACEINTID_USB ), + TRACE_STR(EFM32_TRACEINTID_INTPENDING ), + TRACE_STR(EFM32_TRACEINTID_EPOUT ), + TRACE_STR(EFM32_TRACEINTID_EPIN ), + TRACE_STR(EFM32_TRACEINTID_MISMATCH ), + TRACE_STR(EFM32_TRACEINTID_WAKEUP ), + TRACE_STR(EFM32_TRACEINTID_SUSPEND ), + TRACE_STR(EFM32_TRACEINTID_SOF ), + TRACE_STR(EFM32_TRACEINTID_RXFIFO ), + TRACE_STR(EFM32_TRACEINTID_DEVRESET ), + TRACE_STR(EFM32_TRACEINTID_ENUMDNE ), + TRACE_STR(EFM32_TRACEINTID_IISOIXFR ), + TRACE_STR(EFM32_TRACEINTID_IISOOXFR ), + TRACE_STR(EFM32_TRACEINTID_SRQ ), + TRACE_STR(EFM32_TRACEINTID_OTG ), + TRACE_STR(EFM32_TRACEINTID_EPOUT_XFRC ), + TRACE_STR(EFM32_TRACEINTID_EPOUT_EPDISD), + TRACE_STR(EFM32_TRACEINTID_EPOUT_SETUP ), + TRACE_STR(EFM32_TRACEINTID_DISPATCH ), + TRACE_STR(EFM32_TRACEINTID_GETSTATUS ), + TRACE_STR(EFM32_TRACEINTID_EPGETSTATUS ), + TRACE_STR(EFM32_TRACEINTID_DEVGETSTATUS), + TRACE_STR(EFM32_TRACEINTID_IFGETSTATUS ), + TRACE_STR(EFM32_TRACEINTID_CLEARFEATURE), + TRACE_STR(EFM32_TRACEINTID_SETFEATURE ), + TRACE_STR(EFM32_TRACEINTID_SETADDRESS ), + TRACE_STR(EFM32_TRACEINTID_GETSETDESC ), + TRACE_STR(EFM32_TRACEINTID_GETCONFIG ), + TRACE_STR(EFM32_TRACEINTID_SETCONFIG ), + TRACE_STR(EFM32_TRACEINTID_GETSETIF ), + TRACE_STR(EFM32_TRACEINTID_SYNCHFRAME ), + TRACE_STR(EFM32_TRACEINTID_EPIN_XFRC ), + TRACE_STR(EFM32_TRACEINTID_EPIN_TOC ), + TRACE_STR(EFM32_TRACEINTID_EPIN_ITTXFE ), + TRACE_STR(EFM32_TRACEINTID_EPIN_EPDISD ), + TRACE_STR(EFM32_TRACEINTID_EPIN_TXFE ), + TRACE_STR(EFM32_TRACEINTID_EPIN_EMPWAIT), + TRACE_STR(EFM32_TRACEINTID_OUTNAK ), + TRACE_STR(EFM32_TRACEINTID_OUTRECVD ), + TRACE_STR(EFM32_TRACEINTID_OUTDONE ), + TRACE_STR(EFM32_TRACEINTID_SETUPDONE ), + TRACE_STR(EFM32_TRACEINTID_SETUPRECVD ), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_getreg + * + * Description: + * Get the contents of an EFM32 register + * + ****************************************************************************/ + +#if defined(CONFIG_EFM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t efm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: efm32_putreg + * + * Description: + * Set the contents of an EFM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_EFM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void efm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: efm32_req_remfirst + * + * Description: + * Remove a request from the head of an endpoint request queue + * + ****************************************************************************/ + +static FAR struct efm32_req_s *efm32_req_remfirst(FAR struct efm32_ep_s *privep) +{ + FAR struct efm32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: efm32_req_addlast + * + * Description: + * Add a request to the end of an endpoint request queue + * + ****************************************************************************/ + +static bool efm32_req_addlast(FAR struct efm32_ep_s *privep, + FAR struct efm32_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + return is_empty; +} + +/**************************************************************************** + * Name: efm32_ep0in_setupresponse + * + * Description: + * Schedule a short transfer on Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static void efm32_ep0in_setupresponse(FAR struct efm32_usbdev_s *priv, + FAR uint8_t *buf, uint32_t nbytes) +{ + efm32_epin_transfer(&priv->epin[EP0], buf, nbytes); + priv->ep0state = EP0STATE_SETUPRESPONSE; + efm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: efm32_ep0in_transmitzlp + * + * Description: + * Send a zero length packet (ZLP) on endpoint 0 IN + * + ****************************************************************************/ + +static inline void efm32_ep0in_transmitzlp(FAR struct efm32_usbdev_s *priv) +{ + efm32_ep0in_setupresponse(priv, NULL, 0); +} + +/**************************************************************************** + * Name: efm32_ep0in_activate + * + * Description: + * Activate the endpoint 0 IN endpoint. + * + ****************************************************************************/ + +static void efm32_ep0in_activate(void) +{ + uint32_t regval; + + /* Set the max packet size of the IN EP. */ + + regval = efm32_getreg(EFM32_USB_DIEP0CTL); + regval &= ~_USB_DIEP0CTL_MPS_MASK; + +#if CONFIG_USBDEV_EP0_MAXSIZE == 8 + regval |= _USB_DIEP0CTL_MPS_8B; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 16 + regval |= _USB_DIEP0CTL_MPS_16B; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 32 + regval |= _USB_DIEP0CTL_MPS_32B; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 64 + regval |= _USB_DIEP0CTL_MPS_64B; +#else +# error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE" +#endif + + efm32_putreg(regval, EFM32_USB_DIEP0CTL); + + /* Clear global IN NAK */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval |= USB_DCTL_CGNPINNAK; + efm32_putreg(regval, EFM32_USB_DCTL); +} + +/**************************************************************************** + * Name: efm32_ep0out_ctrlsetup + * + * Description: + * Setup to receive a SETUP packet. + * + ****************************************************************************/ + +static void efm32_ep0out_ctrlsetup(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Setup the hardware to perform the SETUP transfer */ + + regval = (USB_SIZEOF_CTRLREQ * 3 << _USB_DOEP0TSIZ_XFERSIZE_SHIFT) | + (USB_DOEP0TSIZ_PKTCNT) | + (3 << _USB_DOEP0TSIZ_SUPCNT_SHIFT); + efm32_putreg(regval, EFM32_USB_DOEP0TSIZ); + + /* Then clear NAKing and enable the transfer */ + + regval = efm32_getreg(EFM32_USB_DOEP0CTL); + regval |= (USB_DOEP0CTL_CNAK | USB_DOEP0CTL_EPENA); + efm32_putreg(regval, EFM32_USB_DOEP0CTL); +} + +/**************************************************************************** + * Name: efm32_txfifo_write + * + * Description: + * Send data to the endpoint's TxFIFO. + * + ****************************************************************************/ + +static void efm32_txfifo_write(FAR struct efm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t regaddr; + uint32_t regval; + int nwords; + int i; + + /* Convert the number of bytes to words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the TxFIFO for this endpoint (same as the endpoint number) */ + + regaddr = EFM32_USB_FIFO_BASE(privep->epphy); + + /* Then transfer each word to the TxFIFO */ + + for (i = 0; i < nwords; i++) + { + /* Read four bytes from the source buffer (to avoid unaligned accesses) + * and pack these into one 32-bit word (little endian). + */ + + regval = (uint32_t)*buf++; + regval |= ((uint32_t)*buf++) << 8; + regval |= ((uint32_t)*buf++) << 16; + regval |= ((uint32_t)*buf++) << 24; + + /* Then write the packet data to the TxFIFO */ + + efm32_putreg(regval, regaddr); + } +} + +/**************************************************************************** + * Name: efm32_epin_transfer + * + * Description: + * Start the Tx data transfer + * + ****************************************************************************/ + +static void efm32_epin_transfer(FAR struct efm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t pktcnt; + uint32_t regval; + + /* Read the DIEPSIZx register */ + + regval = efm32_getreg(EFM32_USB_DIEPTSIZ(privep->epphy)); + + /* Clear the XFERSIZE, PKTCNT, and MCNT field of the DIEPSIZx register */ + + regval &= ~(_USB_DIEPTSIZ_XFERSIZE_MASK | _USB_DIEPTSIZ_PKTCNT_MASK | + _USB_DIEPTSIZ_MC_MASK); + + /* Are we sending a zero length packet (ZLP) */ + + if (nbytes == 0) + { + /* Yes.. leave the transfer size at zero and set the packet count to 1 */ + + pktcnt = 1; + } + else + { + /* No.. Program the transfer size and packet count . First calculate: + * + * xfrsize = The total number of bytes to be sent. + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + */ + + pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + } + + /* Set the XFERSIZE and PKTCNT */ + + regval |= (pktcnt << _USB_DIEPTSIZ_PKTCNT_SHIFT); + regval |= ((uint32_t)nbytes << _USB_DIEPTSIZ_XFERSIZE_SHIFT); + + /* If this is an isconchronous endpoint, then set the multi-count field to + * the PKTCNT as well. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + regval |= (pktcnt << _USB_DIEPTSIZ_MC_SHIFT); + } + + /* Save DIEPSIZx register value */ + + efm32_putreg(regval, EFM32_USB_DIEPTSIZ(privep->epphy)); + + /* Read the DIEPCTLx register */ + + regval = efm32_getreg(EFM32_USB_DIEPCTL(privep->epphy)); + + /* If this is an isochronous endpoint, then set the even/odd frame bit + * the DIEPCTLx register. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + /* Check bit 0 of the frame number of the received SOF and set the + * even/odd frame to match. + */ + + uint32_t status = efm32_getreg(EFM32_USB_DSTS); + if ((status & _USB_DSTS_SOFFN_EVENODD_MASK) == USB_DSTS_SOFFN_EVEN) + { + regval |= USB_DIEPCTL_SETD0PIDEF; + } + else + { + regval |= USB_DIEPCTL_SETD1PIDOF; + } + } + + /* EP enable, IN data in FIFO */ + + regval &= ~USB_DIEPCTL_EPDIS; + regval |= (USB_DIEPCTL_CNAK | USB_DIEPCTL_EPENA); + efm32_putreg(regval, EFM32_USB_DIEPCTL(privep->epphy)); + + /* Transfer the data to the TxFIFO. At this point, the caller has already + * assured that there is sufficient space in the TxFIFO to hold the transfer + * we can just blindly continue. + */ + + efm32_txfifo_write(privep, buf, nbytes); +} + +/**************************************************************************** + * Name: efm32_epin_request + * + * Description: + * Begin or continue write request processing. + * + ****************************************************************************/ + +static void efm32_epin_request(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep) +{ + struct efm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint8_t *buf; + int nbytes; + int nwords; + int bytesleft; + + /* We get here in one of four possible ways. From three interrupting + * events: + * + * 1. From efm32_epin as part of the transfer complete interrupt processing + * This interrupt indicates that the last transfer has completed. + * 2. As part of the ITTXFE interrupt processing. That interrupt indicates + * that an IN token was received when the associated TxFIFO was empty. + * 3. From efm32_epin_txfifoempty as part of the TXFE interrupt processing. + * The TXFE interrupt is only enabled when the TxFIFO is full and the + * software must wait for space to become available in the TxFIFO. + * + * And this function may be called immediately when the write request is + * queue to start up the next transaction. + * + * 4. From efm32_ep_submit when a new write request is received WHILE the + * endpoint is not active (privep->active == false). + */ + + /* Check the request from the head of the endpoint request queue */ + + privreq = efm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPINREQEMPTY), privep->epphy); + + /* There is no TX transfer in progress and no new pending TX + * requests to send. To stop transmitting any data on a particular + * IN endpoint, the application must set the IN NAK bit. To set this + * bit, the following field must be programmed. + */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval |= USB_DIEPCTL_SNAK; + efm32_putreg(regval, regaddr); + + /* The endpoint is no longer active */ + + privep->active = false; + return; + } + + ullvdbg("EP%d req=%p: len=%d xfrd=%d zlp=%d\n", + privep->epphy, privreq, privreq->req.len, + privreq->req.xfrd, privep->zlp); + + /* Check for a special case: If we are just starting a request (xfrd==0) and + * the class driver is trying to send a zero-length packet (len==0). Then set + * the ZLP flag so that the packet will be sent. + */ + + if (privreq->req.len == 0) + { + /* The ZLP flag is set TRUE whenever we want to force the driver to + * send a zero-length-packet on the next pass through the loop (below). + * The flag is cleared whenever a packet is sent in the loop below. + */ + + privep->zlp = true; + } + + /* Add one more packet to the TxFIFO. We will wait for the transfer + * complete event before we add the next packet (or part of a packet + * to the TxFIFO). + * + * The documentation says that we can can multiple packets to the TxFIFO, + * but it seems that we need to get the transfer complete event before + * we can add the next (or maybe I have got something wrong?) + */ + +#if 0 + while (privreq->req.xfrd < privreq->req.len || privep->zlp) +#else + if (privreq->req.xfrd < privreq->req.len || privep->zlp) +#endif + { + /* Get the number of bytes left to be sent in the request */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + + /* Assume no zero-length-packet on the next pass through this loop */ + + privep->zlp = false; + + /* Limit the size of the transfer to one full packet and handle + * zero-length packets (ZLPs). + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* The ZLP flag is set TRUE whenever we want to force + * the driver to send a zero-length-packet on the next + * pass through this loop. The flag is cleared (above) + * whenever we are committed to sending any packet and + * set here when we want to force one more pass through + * the loop. + */ + + privep->zlp = true; + } + } + } + + /* Get the transfer size in 32-bit words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the number of 32-bit words available in the TxFIFO. The + * DXTFSTS indicates the amount of free space available in the + * endpoint TxFIFO. Values are in terms of 32-bit words: + * + * 0: Endpoint TxFIFO is full + * 1: 1 word available + * 2: 2 words available + * n: n words available + */ + + regaddr = EFM32_USB_DIEPTXFSTS(privep->epphy); + + /* Check for space in the TxFIFO. If space in the TxFIFO is not + * available, then set up an interrupt to resume the transfer when + * the TxFIFO is empty. + */ + + regval = efm32_getreg(regaddr); + if ((int)(regval & _USB_DIEPTXFSTS_MASK) < nwords) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval); + + /* There is insufficient space in the TxFIFO. Wait for a TxFIFO + * empty interrupt and try again. + */ + + uint32_t empmsk = efm32_getreg(EFM32_USB_DIEPEMPMSK); + empmsk |= USB_DIEPEMPMSK(privep->epphy); + efm32_putreg(empmsk, EFM32_USB_DIEPEMPMSK); + + /* Terminate the transfer. We will try again when the TxFIFO empty + * interrupt is received. + */ + + return; + } + + /* Transfer data to the TxFIFO */ + + buf = privreq->req.buf + privreq->req.xfrd; + efm32_epin_transfer(privep, buf, nbytes); + + /* If it was not before, the OUT endpoint is now actively transferring + * data. + */ + + privep->active = true; + + /* EP0 is a special case */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_IN; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* Note that the ZLP, if any, must be sent as a separate transfer. The need + * for a ZLP is indicated by privep->zlp. If all of the bytes were sent + * (including any final null packet) then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->zlp) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + + /* We are finished with the request (although the transfer has not + * yet completed). + */ + + efm32_req_complete(privep, OK); + } +} + +/**************************************************************************** + * Name: efm32_rxfifo_read + * + * Description: + * Read packet from the RxFIFO into a read request. + * + ****************************************************************************/ + +static void efm32_rxfifo_read(FAR struct efm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len) +{ + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO. Note: there is only one RxFIFO so + * we might as well use the addess associated with EP0. + */ + + regaddr = EFM32_USB_FIFO_BASE(EP0); + + /* Read 32-bits and write 4 x 8-bits at time (to avoid unaligned accesses) */ + + for (i = 0; i < len; i += 4) + { + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Read 1 x 32-bits of EP0 packet data */ + + data.w = efm32_getreg(regaddr); + + /* Write 4 x 8-bits of EP0 packet data */ + + *dest++ = data.b[0]; + *dest++ = data.b[1]; + *dest++ = data.b[2]; + *dest++ = data.b[3]; + } +} + +/**************************************************************************** + * Name: efm32_rxfifo_discard + * + * Description: + * Discard packet data from the RxFIFO. + * + ****************************************************************************/ + +static void efm32_rxfifo_discard(FAR struct efm32_ep_s *privep, int len) +{ + if (len > 0) + { + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = EFM32_USB_FIFO_BASE(EP0); + + /* Read 32-bits at time */ + + for (i = 0; i < len; i += 4) + { + volatile uint32_t data = efm32_getreg(regaddr); + (void)data; + } + } +} + +/**************************************************************************** + * Name: efm32_epout_complete + * + * Description: + * This function is called when an OUT transfer complete interrupt is + * received. It completes the read request at the head of the endpoint's + * request queue. + * + ****************************************************************************/ + +static void efm32_epout_complete(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep) +{ + struct efm32_req_s *privreq; + + /* Since a transfer just completed, there must be a read request at the head of + * the endpoint request queue. + */ + + privreq = efm32_rqpeek(privep); + DEBUGASSERT(privreq); + + if (!privreq) + { + /* An OUT transfer completed, but no packet to receive the data. This + * should not happen. + */ + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + privep->epphy, privreq->req.len, privreq->req.xfrd); + + /* Return the completed read request to the class driver and mark the state + * IDLE. + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + efm32_req_complete(privep, OK); + privep->active = false; + + /* Now set up the next read request (if any) */ + + efm32_epout_request(priv, privep); +} + +/**************************************************************************** + * Name: efm32_ep0out_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void efm32_ep0out_receive(FAR struct efm32_ep_s *privep, int bcnt) +{ + FAR struct efm32_usbdev_s *priv; + + /* Sanity Checking */ + + DEBUGASSERT(privep && privep->ep.priv); + priv = (FAR struct efm32_usbdev_s *)privep->ep.priv; + + ullvdbg("EP0: bcnt=%d\n", bcnt); + usbtrace(TRACE_READ(EP0), bcnt); + + /* Verify that an OUT SETUP request as received before this data was + * received in the RxFIFO. + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Read the data into our special buffer for SETUP data */ + + int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt); + efm32_rxfifo_read(privep, priv->ep0data, readlen); + + /* Do we have to discard any excess bytes? */ + + efm32_rxfifo_discard(privep, bcnt - readlen); + + /* Now we can process the setup command */ + + privep->active = false; + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + + efm32_ep0out_setup(priv); + } + else + { + /* This is an error. We don't have any idea what to do with the EP0 + * data in this case. Just read and discard it so that the RxFIFO + * does not become constipated. + */ + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_NOOUTSETUP), priv->ep0state); + efm32_rxfifo_discard(privep, bcnt); + privep->active = false; + } +} + +/**************************************************************************** + * Name: efm32_epout_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void efm32_epout_receive(FAR struct efm32_ep_s *privep, int bcnt) +{ + struct efm32_req_s *privreq; + uint8_t *dest; + int buflen; + int readlen; + + /* Get a reference to the request at the head of the endpoint's request + * queue. + */ + + privreq = efm32_rqpeek(privep); + if (!privreq) + { + /* Incoming data is available in the RxFIFO, but there is no read setup + * to receive the receive the data. This should not happen for data + * endpoints; those endpoints should have been NAKing any OUT data tokens. + * + * We should get here normally on OUT data phase following an OUT + * SETUP command. EP0 data will still receive data in this case and it + * should not be NAKing. + */ + + if (privep->epphy == 0) + { + efm32_ep0out_receive(privep, bcnt); + } + else + { + /* Otherwise, the data is lost. This really should not happen if + * NAKing is working as expected. + */ + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* Discard the data in the RxFIFO */ + + efm32_rxfifo_discard(privep, bcnt); + } + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", privep->epphy, privreq->req.len, privreq->req.xfrd); + usbtrace(TRACE_READ(privep->epphy), bcnt); + + /* Get the number of bytes to transfer from the RxFIFO */ + + buflen = privreq->req.len - privreq->req.xfrd; + DEBUGASSERT(buflen > 0 && buflen >= bcnt); + readlen = MIN(buflen, bcnt); + + /* Get the destination of the data transfer */ + + dest = privreq->req.buf + privreq->req.xfrd; + + /* Transfer the data from the RxFIFO to the request's data buffer */ + + efm32_rxfifo_read(privep, dest, readlen); + + /* If there were more bytes in the RxFIFO than could be held in the read + * request, then we will have to discard those. + */ + + efm32_rxfifo_discard(privep, bcnt - readlen); + + /* Update the number of bytes transferred */ + + privreq->req.xfrd += readlen; +} + +/**************************************************************************** + * Name: efm32_epout_request + * + * Description: + * This function is called when either (1) new read request is received, or + * (2) a pending receive request completes. If there is no read in pending, + * then this function will initiate the next OUT (read) operation. + * + ****************************************************************************/ + +static void efm32_epout_request(FAR struct efm32_usbdev_s *priv, + FAR struct efm32_ep_s *privep) +{ + struct efm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; + + /* Make sure that there is not already a pending request request. If there is, + * just return, leaving the newly received request in the request queue. + */ + + if (!privep->active) + { + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an invalid + * read request is encountered. + */ + + for (; ; ) + { + /* Get a reference to the request at the head of the endpoint's request queue */ + + privreq = efm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* There are no read requests to be setup. Configure the hardware to + * NAK any incoming packets. (This should already be the case. I + * think that the hardware will automatically NAK after a transfer is + * completed until SNAK is cleared). + */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval |= USB_DOEPCTL_SNAK; + efm32_putreg(regval, regaddr); + + /* This endpoint is no longer actively transferring */ + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d\n", privep->epphy, privreq->req.len); + + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ + + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPOUTNULLPACKET), 0); + efm32_req_complete(privep, OK); + } + + /* Otherwise, we have a usable read request... break out of the loop */ + + else + { + break; + } + } + + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ + + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = EFM32_USB_DOEPTSIZ(privep->epphy); + regval = efm32_getreg(regaddr); + regval &= ~(_USB_DOEPTSIZ_XFERSIZE_MASK | _USB_DOEPTSIZ_PKTCNT_MASK); + regval |= (xfrsize << _USB_DOEPTSIZ_XFERSIZE_SHIFT); + regval |= (pktcnt << _USB_DOEPTSIZ_PKTCNT_SHIFT); + efm32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + + /* When an isochronous transfer is enabled the Even/Odd frame bit must + * also be set appropriately. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + if (privep->odd) + { + regval |= USB_DOEPCTL_SODDFRM; + } + else + { + regval |= USB_DOEPCTL_SEVNFRM; + } + } +#endif + + /* Clearing NAKing and enable the transfer. */ + + regval |= (USB_DOEPCTL_CNAK | USB_DOEPCTL_EPENA); + efm32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + + /* EP0 is a special case. We need to know when to switch back to + * normal SETUP processing. + */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_OUT; + } + } +} + +/**************************************************************************** + * Name: efm32_ep_flush + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void efm32_ep_flush(struct efm32_ep_s *privep) +{ + if (privep->isin) + { + efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_F(privep->epphy)); + } + else + { + efm32_rxfifo_flush(); + } +} + +/**************************************************************************** + * Name: efm32_req_complete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void efm32_req_complete(struct efm32_ep_s *privep, int16_t result) +{ + FAR struct efm32_req_s *privreq; + + /* Remove the request at the head of the request list */ + + privreq = efm32_req_remfirst(privep); + DEBUGASSERT(privreq != NULL); + + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == EP0) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: efm32_req_cancel + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void efm32_req_cancel(struct efm32_ep_s *privep, int16_t status) +{ + if (!efm32_rqempty(privep)) + { + efm32_ep_flush(privep); + } + + while (!efm32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (efm32_rqpeek(privep))->req.xfrd); + efm32_req_complete(privep, status); + } +} + +/**************************************************************************** + * Name: efm32_ep_findbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct efm32_ep_s *efm32_ep_findbyaddr(struct efm32_usbdev_s *priv, + uint16_t eplog) +{ + struct efm32_ep_s *privep; + uint8_t epphy = USB_EPNO(eplog); + + if (epphy >= EFM32_NENDPOINTS) + { + return NULL; + } + + /* Is this an IN or an OUT endpoint? */ + + if (USB_ISEPIN(eplog)) + { + privep = &priv->epin[epphy]; + } + else + { + privep = &priv->epout[epphy]; + } + + /* Return endpoint reference */ + + DEBUGASSERT(privep->epphy == epphy); + return privep; +} + +/**************************************************************************** + * Name: efm32_req_dispatch + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static int efm32_req_dispatch(struct efm32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, + priv->ep0data, priv->ep0datlen); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } + + return ret; +} + +/**************************************************************************** + * Name: efm32_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void efm32_usbreset(struct efm32_usbdev_s *priv) +{ + FAR struct efm32_ep_s *privep; + uint32_t regval; + int i; + + /* Clear the Remote Wake-up Signaling */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval &= ~USB_DCTL_RMTWKUPSIG; + efm32_putreg(regval, EFM32_USB_DCTL); + + /* Flush the EP0 Tx FIFO */ + + efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_F(EP0)); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Mark all endpoints as available */ + + priv->epavail[0] = EFM32_EP_AVAILABLE; + priv->epavail[1] = EFM32_EP_AVAILABLE; + + /* Disable all end point interrupts */ + + for (i = 0; i < EFM32_NENDPOINTS ; i++) + { + /* Disable endpoint interrupts */ + + efm32_putreg(0xff, EFM32_USB_DIEPINT(i)); + efm32_putreg(0xff, EFM32_USB_DOEPINT(i)); + + /* Return write requests to the class implementation */ + + privep = &priv->epin[i]; + efm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset IN endpoint status */ + + privep->stalled = false; + + /* Return read requests to the class implementation */ + + privep = &priv->epout[i]; + efm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + efm32_putreg(0xffffffff, EFM32_USB_DAINT); + + /* Mask all device endpoint interrupts except EP0 */ + + regval = (USB_DAINT_INEPINT(EP0) | USB_DAINT_OUTEPINT(EP0)); + efm32_putreg(regval, EFM32_USB_DAINTMSK); + + /* Unmask OUT interrupts */ + + regval = (USB_DOEPMSK_XFERCOMPLMSK | USB_DOEPMSK_SETUPMSK | + USB_DOEPMSK_EPDISBLDMSK); + efm32_putreg(regval, EFM32_USB_DOEPMSK); + + /* Unmask IN interrupts */ + + regval = (USB_DIEPMSK_XFERCOMPLMSK | USB_DIEPMSK_EPDISBLDMSK | + USB_DIEPMSK_TIMEOUTMSK); + efm32_putreg(regval, EFM32_USB_DIEPMSK); + + /* Reset device address to 0 */ + + efm32_setaddress(priv, 0); + priv->devstate = DEVSTATE_DEFAULT; + priv->usbdev.speed = USB_SPEED_FULL; + + /* Re-configure EP0 */ + + efm32_ep0_configure(priv); + + /* Setup EP0 to receive SETUP packets */ + + efm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: efm32_ep0out_testmode + * + * Description: + * Select test mode + * + ****************************************************************************/ + +static inline void efm32_ep0out_testmode(FAR struct efm32_usbdev_s *priv, + uint16_t index) +{ + uint8_t testmode; + + testmode = index >> 8; + switch (testmode) + { + case 1: + priv->testmode = _USB_DCTL_TSTCTL_J; + break; + + case 2: + priv->testmode = _USB_DCTL_TSTCTL_K; + break; + + case 3: + priv->testmode = _USB_DCTL_TSTCTL_SE0NAK; + break; + + case 4: + priv->testmode = _USB_DCTL_TSTCTL_PACKET; + break; + + case 5: + priv->testmode = _USB_DCTL_TSTCTL_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = _USB_DCTL_TSTCTL_DISABLE; + priv->stalled = true; + } + + priv->dotest = true; + efm32_ep0in_transmitzlp(priv); +} + +/**************************************************************************** + * Name: efm32_ep0out_stdrequest + * + * Description: + * Handle a stanard request on EP0. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver. + * + ****************************************************************************/ + +static inline void efm32_ep0out_stdrequest(struct efm32_usbdev_s *priv, + FAR struct efm32_ctrlreq_s *ctrlreq) +{ + FAR struct efm32_ep_s *privep; + + /* Handle standard request */ + + switch (ctrlreq->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPGETSTATUS), 0); + privep = efm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + efm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and selfpowered */ + + priv->ep0data[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + efm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; + + efm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = efm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + efm32_ep_clrstall(privep); + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + efm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = efm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + efm32_ep_setstall(privep); + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + efm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETADDRESS), ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + efm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + efm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ + + int ret = efm32_req_dispatch(priv, &priv->ctrlreq); + + /* If the class driver accepted the configuration, then mark the + * device state as configured (or not, depending on the + * configuration). + */ + + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETIF), 0); + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } +} + +/**************************************************************************** + * Name: efm32_ep0out_setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void efm32_ep0out_setup(struct efm32_usbdev_s *priv) +{ + struct efm32_ctrlreq_s ctrlreq; + + /* Verify that a SETUP was received */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + + /* Terminate any pending requests */ + + efm32_req_cancel(&priv->epout[EP0], -EPROTO); + efm32_req_cancel(&priv->epin[EP0], -EPROTO); + + /* Assume NOT stalled */ + + priv->epout[EP0].stalled = false; + priv->epin[EP0].stalled = false; + priv->stalled = false; + + /* Starting to process a control request - update state */ + + priv->ep0state = EP0STATE_SETUP_PROCESS; + + /* And extract the little-endian 16-bit values to host order */ + + ctrlreq.type = priv->ctrlreq.type; + ctrlreq.req = priv->ctrlreq.req; + ctrlreq.value = GETUINT16(priv->ctrlreq.value); + ctrlreq.index = GETUINT16(priv->ctrlreq.index); + ctrlreq.len = GETUINT16(priv->ctrlreq.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrlreq.type, ctrlreq.req, ctrlreq.value, ctrlreq.index, ctrlreq.len); + + /* Check for a standard request */ + + if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + /* Dispatch any non-standard requests */ + + (void)efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + /* Handle standard requests. */ + + efm32_ep0out_stdrequest(priv, &ctrlreq); + } + + /* Check if the setup processing resulted in a STALL */ + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + efm32_ep0_stall(priv); + } + + /* Reset state/data associated with thie SETUP request */ + + priv->ep0datlen = 0; +} + +/**************************************************************************** + * Name: efm32_epout + * + * Description: + * This is part of the OUT endpoint interrupt processing. This function + * handles the OUT event for a single endpoint. + * + ****************************************************************************/ + +static inline void efm32_epout(FAR struct efm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct efm32_ep_s *privep; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + privep = &priv->epout[EP0]; + + /* In the EP0STATE_DATA_OUT state, we are receiving data into the + * request buffer. In that case, we must continue the request + * processing. + */ + + if (priv->ep0state == EP0STATE_DATA_OUT) + { + /* Continue processing data from the EP0 OUT request queue */ + + efm32_epout_complete(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + efm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an OUT request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + efm32_epout_complete(priv, &priv->epout[epno]); + } +} + +/**************************************************************************** + * Name: efm32_epout_interrupt + * + * Description: + * USB OUT endpoint interrupt handler. The core generates this interrupt when + * there is an interrupt is pending on one of the OUT endpoints of the core. + * The driver must read the OTGFS DAINT register to determine the exact number + * of the OUT endpoint on which the interrupt occurred, and then read the + * corresponding OTGFS DOEPINTx register to determine the exact cause of the + * interrupt. + * + ****************************************************************************/ + +static inline void efm32_epout_interrupt(FAR struct efm32_usbdev_s *priv) +{ + uint32_t daint; + uint32_t regval; + uint32_t doepint; + int epno; + + /* Get the pending, enabled interrupts for the OUT endpoint from the endpoint + * interrupt status register. + */ + + regval = efm32_getreg(EFM32_USB_DAINT); + regval &= efm32_getreg(EFM32_USB_DAINTMSK); + daint = (regval & _USB_DAINT_OUTEPINT_MASK) >> _USB_DAINT_OUTEPINT_SHIFT; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + regval = efm32_getreg(EFM32_USB_DAINT); + daint = (regval & _USB_DAINT_OUTEPINT_MASK) >> _USB_DAINT_OUTEPINT_SHIFT; + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPOUTUNEXPECTED), + (uint16_t)regval); + + epno = 0; + while (daint) + { + if ((daint & 1) != 0) + { + regval = efm32_getreg(EFM32_USB_DOEPINT(epno)); + ulldbg("DOEPINT(%d) = %08x\n", epno, regval); + efm32_putreg(0xFF, EFM32_USB_DOEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an OUT interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Yes.. get the OUT endpoint interrupt status */ + + doepint = efm32_getreg(EFM32_USB_DOEPINT(epno)); + doepint &= efm32_getreg(EFM32_USB_DOEPMSK); + + /* Transfer completed interrupt. This interrupt is trigged when + * efm32_rxinterrupt() removes the last packet data from the RxFIFO. + * In this case, core internally sets the NAK bit for this endpoint to + * prevent it from receiving any more packets. + */ + + if ((doepint & USB_DOEPINT_XFERCOMPL) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT_XFRC), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + efm32_putreg(USB_DOEPINT_XFERCOMPL, EFM32_USB_DOEPINT(epno)); + + /* Handle the RX transfer data ready event */ + + efm32_epout(priv, epno); + } + + /* Endpoint disabled interrupt (ignored because this interrupt is + * used in polled mode by the endpoint disable logic). + */ +#if 1 + /* REVISIT: */ + if ((doepint & USB_DOEPINT_EPDISBLD) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + efm32_putreg(USB_DOEPINT_EPDISBLD, EFM32_USB_DOEPINT(epno)); + } +#endif + /* Setup Phase Done (control EPs) */ + + if ((doepint & USB_DOEPINT_SETUP) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT_SETUP), priv->ep0state); + + /* Handle the receipt of the IN SETUP packets now (OUT setup + * packet processing may be delayed until the accompanying + * OUT DATA is received) + */ + + if (priv->ep0state == EP0STATE_SETUP_READY) + { + efm32_ep0out_setup(priv); + } + efm32_putreg(USB_DOEPINT_SETUP, EFM32_USB_DOEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: efm32_epin_runtestmode + * + * Description: + * Execute the test mode setup by the SET FEATURE request + * + ****************************************************************************/ + +static inline void efm32_epin_runtestmode(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval = efm32_getreg(EFM32_USB_DCTL); + regval &= ~_USB_DCTL_TSTCTL_MASK; + regval |= (uint32_t)priv->testmode << _USB_DCTL_TSTCTL_SHIFT; + efm32_putreg(regval , EFM32_USB_DCTL); + + priv->dotest = 0; + priv->testmode = _USB_DCTL_TSTCTL_DISABLE; +} + +/**************************************************************************** + * Name: efm32_epin + * + * Description: + * This is part of the IN endpoint interrupt processing. This function + * handles the IN event for a single endpoint. + * + ****************************************************************************/ + +static inline void efm32_epin(FAR struct efm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct efm32_ep_s *privep = &priv->epin[epno]; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + /* In the EP0STATE_DATA_IN state, we are sending data from request + * buffer. In that case, we must continue the request processing. + */ + + if (priv->ep0state == EP0STATE_DATA_IN) + { + /* Continue processing data from the EP0 OUT request queue */ + + efm32_epin_request(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + efm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + + /* Test mode is another special case */ + + if (priv->dotest) + { + efm32_epin_runtestmode(priv); + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an IN request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + /* Continue processing data from the endpoint write request queue */ + + efm32_epin_request(priv, privep); + } +} + +/**************************************************************************** + * Name: efm32_epin_txfifoempty + * + * Description: + * TxFIFO empty interrupt handling + * + ****************************************************************************/ + +static inline void efm32_epin_txfifoempty(FAR struct efm32_usbdev_s *priv, int epno) +{ + FAR struct efm32_ep_s *privep = &priv->epin[epno]; + + /* Continue processing the write request queue. This may mean sending + * more data from the exisiting request or terminating the current requests + * and (perhaps) starting the IN transfer from the next write request. + */ + + efm32_epin_request(priv, privep); +} + +/**************************************************************************** + * Name: efm32_epin_interrupt + * + * Description: + * USB IN endpoint interrupt handler. The core generates this interrupt when + * an interrupt is pending on one of the IN endpoints of the core. The driver + * must read the OTGFS DAINT register to determine the exact number of the IN + * endpoint on which the interrupt occurred, and then read the corresponding + * OTGFS DIEPINTx register to determine the exact cause of the interrupt. + * + ****************************************************************************/ + +static inline void efm32_epin_interrupt(FAR struct efm32_usbdev_s *priv) +{ + uint32_t diepint; + uint32_t daint; + uint32_t mask; + uint32_t empty; + int epno; + + /* Get the pending, enabled interrupts for the IN endpoint from the endpoint + * interrupt status register. + */ + + daint = efm32_getreg(EFM32_USB_DAINT); + daint &= efm32_getreg(EFM32_USB_DAINTMSK); + daint &= _USB_DAINT_INEPINT_MASK; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + daint = efm32_getreg(EFM32_USB_DAINT); + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_EPINUNEXPECTED), + (uint16_t)daint); + + daint &= _USB_DAINT_INEPINT_MASK; + epno = 0; + + while (daint) + { + if ((daint & 1) != 0) + { + ulldbg("DIEPINT(%d) = %08x\n", + epno, efm32_getreg(EFM32_USB_DIEPINT(epno))); + efm32_putreg(0xFF, EFM32_USB_DIEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an IN interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Get IN interrupt mask register. Bits 0-6 correspond to enabled + * interrupts as will be found in the DIEPINT interrupt status + * register. + */ + + mask = efm32_getreg(EFM32_USB_DIEPMSK); + + /* Check if the TxFIFO not empty interrupt is enabled for this + * endpoint in the DIEPMSK register. Bits n corresponds to + * endpoint n in the register. That condition corresponds to + * bit 7 of the DIEPINT interrupt status register. There is + * no TXFE bit in the mask register, so we fake one here. + */ + + empty = efm32_getreg(EFM32_USB_DIEPEMPMSK); + if ((empty & USB_DIEPEMPMSK(epno)) != 0) + { + mask |= USB_DIEPINT_TXFEMP; + } + + /* Now, read the interrupt status and mask out all disabled + * interrupts. + */ + + diepint = efm32_getreg(EFM32_USB_DIEPINT(epno)) & mask; + + /* Decode and process the enabled, pending interrupts */ + /* Transfer completed interrupt */ + + if ((diepint & USB_DIEPINT_XFERCOMPL) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_XFRC), + (uint16_t)diepint); + + /* It is possible that logic may be waiting for a the + * TxFIFO to become empty. We disable the TxFIFO empty + * interrupt here; it will be re-enabled if there is still + * insufficient space in the TxFIFO. + */ + + empty &= ~USB_DIEPEMPMSK(epno); + efm32_putreg(empty, EFM32_USB_DIEPEMPMSK); + efm32_putreg(USB_DIEPINT_XFERCOMPL, EFM32_USB_DIEPINT(epno)); + + /* IN transfer complete */ + + efm32_epin(priv, epno); + } + + /* Timeout condition */ + + if ((diepint & USB_DIEPINT_TIMEOUT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_TOC), (uint16_t)diepint); + efm32_putreg(USB_DIEPINT_TIMEOUT, EFM32_USB_DIEPINT(epno)); + } + + /* IN token received when TxFIFO is empty. Applies to non-periodic IN + * endpoints only. This interrupt indicates that an IN token was received + * when the associated TxFIFO (periodic/non-periodic) was empty. This + * interrupt is asserted on the endpoint for which the IN token was + * received. + */ + + if ((diepint & USB_DIEPINT_INTKNTXFEMP) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_ITTXFE), (uint16_t)diepint); + efm32_epin_request(priv, &priv->epin[epno]); + efm32_putreg(USB_DIEPINT_INTKNTXFEMP, EFM32_USB_DIEPINT(epno)); + } + + /* IN endpoint NAK effective (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & USB_DIEPINT_INEPNAKEFF) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_INEPNE), (uint16_t)diepint); + efm32_putreg(USB_DIEPINT_INEPNAKEFF, EFM32_USB_DIEPINT(epno)); + } +#endif + /* Endpoint disabled interrupt (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & USB_DIEPINT_EPDISBLD) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_EPDISD), (uint16_t)diepint); + efm32_putreg(USB_DIEPINT_EPDISBLD, EFM32_USB_DIEPINT(epno)); + } +#endif + /* Transmit FIFO empty */ + + if ((diepint & USB_DIEPINT_TXFEMP) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint); + + /* If we were waiting for TxFIFO to become empty, the we might have both + * XFRC and TXFE interrupts pending. Since we do the same thing for both + * cases, ignore the TXFE if we have already processed the XFRC. + */ + + if ((diepint & USB_DIEPINT_XFERCOMPL) == 0) + { + /* Mask further FIFO empty interrupts. This will be re-enabled + * whenever we need to wait for a FIFO event. + */ + + empty &= ~USB_DIEPEMPMSK(epno); + efm32_putreg(empty, EFM32_USB_DIEPEMPMSK); + + /* Handle TxFIFO empty */ + + efm32_epin_txfifoempty(priv, epno); + } + + /* Clear the pending TxFIFO empty interrupt */ + + efm32_putreg(USB_DIEPINT_TXFEMP, EFM32_USB_DIEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: efm32_resumeinterrupt + * + * Description: + * Resume/remote wakeup detected interrupt + * + ****************************************************************************/ + +static inline void efm32_resumeinterrupt(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Restart the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = efm32_getreg(EFM32_USB_PCGCCTL); + regval &= ~(OTGFS_PCGCCTL_STPPCLK | OTGFS_PCGCCTL_GATEHCLK); + efm32_putreg(regval, EFM32_USB_PCGCCTL); +#endif + + /* Clear remote wake-up signaling */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval &= ~USB_DCTL_RMTWKUPSIG; + efm32_putreg(regval, EFM32_USB_DCTL); + + /* Restore full power -- whatever that means for this particular board */ + + efm32_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: efm32_suspendinterrupt + * + * Description: + * USB suspend interrupt + * + ****************************************************************************/ + +static inline void efm32_suspendinterrupt(FAR struct efm32_usbdev_s *priv) +{ +#ifdef CONFIG_USBDEV_LOWPOWER + uint32_t regval; +#endif + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + +#ifdef CONFIG_USBDEV_LOWPOWER + /* USB_DSTS_SUSPSTS is set as long as the suspend condition is detected + * on USB. Check if we are still have the suspend condition, that we are + * connected to the host, and that we have been configured. + */ + + regval = efm32_getreg(EFM32_USB_DSTS); + + if ((regval & USB_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED) + { + /* Switch off OTG FS clocking. Setting OTGFS_PCGCCTL_STPPCLK stops the + * PHY clock. + */ + + regval = efm32_getreg(EFM32_USB_PCGCCTL); + regval |= OTGFS_PCGCCTL_STPPCLK; + efm32_putreg(regval, EFM32_USB_PCGCCTL); + + /* Setting OTGFS_PCGCCTL_GATEHCLK gate HCLK to modules other than + * the AHB Slave and Master and wakeup logic. + */ + + regval |= OTGFS_PCGCCTL_GATEHCLK; + efm32_putreg(regval, EFM32_USB_PCGCCTL); + } +#endif + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + efm32_usbsuspend((FAR struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: efm32_rxinterrupt + * + * Description: + * RxFIFO non-empty interrupt. This interrupt indicates that there is at + * least one packet pending to be read from the RxFIFO. + * + ****************************************************************************/ + +static inline void efm32_rxinterrupt(FAR struct efm32_usbdev_s *priv) +{ + FAR struct efm32_ep_s *privep; + uint32_t regval; + int bcnt; + int epphy; + + /* Disable the Rx status queue level interrupt */ + + regval = efm32_getreg(EFM32_USB_GINTMSK); + regval &= ~USB_GINTMSK_RXFLVLMSK; + efm32_putreg(regval, EFM32_USB_GINTMSK); + + /* Get the status from the top of the FIFO */ + + regval = efm32_getreg(EFM32_USB_GRXSTSP); + + /* Decode status fields */ + + epphy = (regval & _USB_GRXSTSP_CHEPNUM_MASK) >> _USB_GRXSTSP_CHEPNUM_SHIFT; + privep = &priv->epout[epphy]; + + /* Handle the RX event according to the packet status field */ + + switch (regval & _USB_GRXSTSP_PKTSTS_MASK) + { + /* Global OUT NAK. This indicate that the global OUT NAK bit has taken + * effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't + * Care. + */ + + case USB_GRXSTSP_PKTSTS_GOUTNAK: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, DPID = Actual Data PID. + */ + + case USB_GRXSTSP_PKTSTS_PKTRCV: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & _USB_GRXSTSP_BCNT_MASK) >> _USB_GRXSTSP_BCNT_SHIFT; + if (bcnt > 0) + { + efm32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. This indicates that an OUT data transfer for + * the specified OUT endpoint has completed. After this entry is popped + * from the receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ + + case USB_GRXSTSP_PKTSTS_XFERCOMPL: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup stage for + * the specified endpoint has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core asserts a + * Setup interrupt on the specified control OUT endpoint (triggers an + * interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case USB_GRXSTSP_PKTSTS_SETUPCOMPL: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPDONE), epphy); + } + break; + + /* SETUP data packet received. This indicates that a SETUP packet for the + * specified endpoint is now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case USB_GRXSTSP_PKTSTS_SETUPRCV: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ + + efm32_rxfifo_read(&priv->epout[EP0], (FAR uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero length, + * then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = efm32_getreg(EFM32_USB_DOEP0CTL); + regval |= USB_DOEP0CTL_CNAK; + efm32_putreg(regval, EFM32_USB_DOEP0CTL); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word is + * popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), + (regval & _USB_GRXSTSP_PKTSTS_MASK) >> _USB_GRXSTSP_PKTSTS_SHIFT); + } + break; + } + + /* Enable the Rx Status Queue Level interrupt */ + + regval = efm32_getreg(EFM32_USB_GINTMSK); + regval |= USB_GINTMSK_RXFLVLMSK; + efm32_putreg(regval, EFM32_USB_GINTMSK); +} + +/**************************************************************************** + * Name: efm32_enuminterrupt + * + * Description: + * Enumeration done interrupt + * + ****************************************************************************/ + +static inline void efm32_enuminterrupt(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Activate EP0 */ + + efm32_ep0in_activate(); + + /* Set USB turn-around time for the full speed device with internal PHY interface. */ + + regval = efm32_getreg(EFM32_USB_GUSBCFG); + regval &= ~_USB_GUSBCFG_USBTRDTIM_MASK; + regval |= USB_GUSBCFG_USBTRDTIM(5); + efm32_putreg(regval, EFM32_USB_GUSBCFG); +} + +/**************************************************************************** + * Name: efm32_isocininterrupt + * + * Description: + * Incomplete isochronous IN transfer interrupt. Assertion of the incomplete + * isochronous IN transfer interrupt indicates an incomplete isochronous IN + * transfer on at least one of the isochronous IN endpoints. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void efm32_isocininterrupt(FAR struct efm32_usbdev_s *priv) +{ + int i; + + /* The application must read the endpoint control register for all isochronous + * IN endpoints to detect endpoints with incomplete IN data transfers. + */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + /* Is this an isochronous IN endpoint? */ + + privep = &priv->epin[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + doepctl = efm32_getreg(regaddr); + dsts = efm32_getreg(EFM32_USB_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & USB_DIEPCTL_EONUM) != 0); + soffn = ((dsts & _USB_DSTS_SOFFN_EVENODD_MASK) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous IN endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + efm32_req_complete(privep, -EIO); +#warning "Will clear USB_DIEPCTL_USBACTEP too" + efm32_epin_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: efm32_isocoutinterrupt + * + * Description: + * Incomplete periodic transfer interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void efm32_isocoutinterrupt(FAR struct efm32_usbdev_s *priv) +{ + FAR struct efm32_ep_s *privep; + FAR struct efm32_req_s *privreq; + uint32_t regaddr; + uint32_t doepctl; + uint32_t dsts; + bool eonum; + bool soffn; + + /* When it receives an IISOOXFR interrupt, the application must read the + * control registers of all isochronous OUT endpoints to determine which + * endpoints had an incomplete transfer in the current microframe. An + * endpoint transfer is incomplete if both the following conditions are true: + * + * DOEPCTLx:EONUM = DSTS:SOFFN[0], and + * DOEPCTLx:EPENA = 1 + */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + /* Is this an isochronous OUT endpoint? */ + + privep = &priv->epout[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + doepctl = efm32_getreg(regaddr); + dsts = efm32_getreg(EFM32_USB_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & USB_DOEPCTL_EONUM) != 0); + soffn = ((dsts & _USB_DSTS_SOFFN_EVENODD_MASK) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous OUT endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + efm32_req_complete(privep, -EIO); +#warning "Will clear USB_DOEPCTL_USBACTEP too" + efm32_epout_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: efm32_sessioninterrupt + * + * Description: + * Session request/new session detected interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void efm32_sessioninterrupt(FAR struct efm32_usbdev_s *priv) +{ +#warning "Missing logic" +} +#endif + +/**************************************************************************** + * Name: efm32_otginterrupt + * + * Description: + * OTG interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void efm32_otginterrupt(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Check for session end detected */ + + regval = efm32_getreg(EFM32_USB_GOTGINT); + if ((regval & OTGFS_GOTGINT_SEDET) != 0) + { +#warning "Missing logic" + } + + /* Clear OTG interrupt */ + + efm32_putreg(retval, EFM32_USB_GOTGINT); +} +#endif + +/**************************************************************************** + * Name: efm32_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int efm32_usbinterrupt(int irq, FAR void *context) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbdev_s *priv = &g_otgfsdev; + uint32_t regval; + + usbtrace(TRACE_INTENTRY(EFM32_TRACEINTID_USB), 0); + + /* Assure that we are in device mode */ + + DEBUGASSERT((efm32_getreg(EFM32_USB_GINTSTS) & USB_GINTSTS_CURMOD) == + USB_GINTSTS_CURMOD_DEVICE); + + /* Get the state of all enabled interrupts. We will do this repeatedly + * some interrupts (like RXFLVL) will generate additional interrupting + * events. + */ + + for (; ; ) + { + /* Get the set of pending, un-masked interrupts */ + + regval = efm32_getreg(EFM32_USB_GINTSTS); + regval &= efm32_getreg(EFM32_USB_GINTMSK); + + /* Break out of the loop when there are no further pending (and + * unmasked) interrupts to be processes. + */ + + if (regval == 0) + { + break; + } + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_INTPENDING), (uint16_t)regval); + + /* OUT endpoint interrupt. The core sets this bit to indicate that an + * interrupt is pending on one of the OUT endpoints of the core. + */ + + if ((regval & USB_GINTSTS_OEPINT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT), (uint16_t)regval); + efm32_epout_interrupt(priv); + } + + /* IN endpoint interrupt. The core sets this bit to indicate that + * an interrupt is pending on one of the IN endpoints of the core. + */ + + if ((regval & USB_GINTSTS_IEPINT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN), (uint16_t)regval); + efm32_epin_interrupt(priv); + } + + /* Host/device mode mismatch error interrupt */ + +#ifdef CONFIG_DEBUG_USB + if ((regval & USB_GINTSTS_MODEMIS) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_MISMATCH), (uint16_t)regval); + efm32_putreg(USB_GINTSTS_MODEMIS, EFM32_USB_GINTSTS); + } +#endif + + /* Resume/remote wakeup detected interrupt */ + + if ((regval & USB_GINTSTS_WKUPINT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_WAKEUP), (uint16_t)regval); + efm32_resumeinterrupt(priv); + efm32_putreg(USB_GINTSTS_WKUPINT, EFM32_USB_GINTSTS); + } + + /* USB suspend interrupt */ + + if ((regval & USB_GINTSTS_USBSUSP) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SUSPEND), (uint16_t)regval); + efm32_suspendinterrupt(priv); + efm32_putreg(USB_GINTSTS_USBSUSP, EFM32_USB_GINTSTS); + } + + /* Start of frame interrupt */ + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + if ((regval & USB_GINTSTS_SOF) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SOF), (uint16_t)regval); + efm32_putreg(USB_GINTSTS_SOF, EFM32_USB_GINTSTS); + } +#endif + + /* RxFIFO non-empty interrupt. Indicates that there is at least one + * packet pending to be read from the RxFIFO. + */ + + if ((regval & USB_GINTSTS_RXFLVL) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_RXFIFO), (uint16_t)regval); + efm32_rxinterrupt(priv); + } + + /* USB reset interrupt */ + + if ((regval & USB_GINTSTS_USBRST) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_DEVRESET), (uint16_t)regval); + + /* Perform the device reset */ + + efm32_usbreset(priv); + usbtrace(TRACE_INTEXIT(EFM32_TRACEINTID_USB), 0); + efm32_putreg(USB_GINTSTS_USBRST, EFM32_USB_GINTSTS); + return OK; + } + + /* Enumeration done interrupt */ + + if ((regval & USB_GINTSTS_ENUMDONE) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_ENUMDNE), (uint16_t)regval); + efm32_enuminterrupt(priv); + efm32_putreg(USB_GINTSTS_ENUMDONE, EFM32_USB_GINTSTS); + } + + /* Incomplete isochronous IN transfer interrupt. When the core finds + * non-empty any of the isochronous IN endpoint FIFOs scheduled for + * the current frame non-empty, the core generates an IISOIXFR + * interrupt. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if ((regval & USB_GINTSTS_IISOIXFR) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_IISOIXFR), (uint16_t)regval); + efm32_isocininterrupt(priv); + efm32_putreg(USB_GINTSTS_IISOIXFR, EFM32_USB_GINTSTS); + } + + /* Incomplete isochronous OUT transfer. For isochronous OUT + * endpoints, the XFRC interrupt may not always be asserted. If the + * core drops isochronous OUT data packets, the application could fail + * to detect the XFRC interrupt. The incomplete Isochronous OUT data + * interrupt indicates that an XFRC interrupt was not asserted on at + * least one of the isochronous OUT endpoints. At this point, the + * endpoint with the incomplete transfer remains enabled, but no active + * transfers remain in progress on this endpoint on the USB. + */ + + if ((regval & USB_GINTSTS_IISOOXFR) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_IISOOXFR), (uint16_t)regval); + efm32_isocoutinterrupt(priv); + efm32_putreg(USB_GINTSTS_IISOOXFR, EFM32_USB_GINTSTS); + } +#endif + + /* Session request/new session detected interrupt */ + +#ifdef CONFIG_USBDEV_VBUSSENSING + if ((regval & USB_GINTSTS_SESSREQINT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SRQ), (uint16_t)regval); + efm32_sessioninterrupt(priv); + efm32_putreg(USB_GINTSTS_SESSREQINT, EFM32_USB_GINTSTS); + } + + /* OTG interrupt */ + + if ((regval & USB_GINTSTS_OTGINT) != 0) + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OTG), (uint16_t)regval); + efm32_otginterrupt(priv); + } +#endif + } + + usbtrace(TRACE_INTEXIT(EFM32_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_enablegonak + * + * Description: + * Enable global OUT NAK mode + * + ****************************************************************************/ + +static void efm32_enablegonak(FAR struct efm32_ep_s *privep) +{ + uint32_t regval; + + /* First, make sure that there is no GNOAKEFF interrupt pending. */ + +#if 0 + efm32_putreg(USB_GINTSTS_GONAKEFF, EFM32_USB_GINTSTS); +#endif + + /* Enable Global OUT NAK mode in the core. */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval |= USB_DCTL_SGOUTNAK; + efm32_putreg(regval, EFM32_USB_DCTL); + +#if 0 + /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK + * mode is in effect. When the interrupt handler pops the OUTNAK word + * from the RxFIFO, the core sets the GONAKEFF interrupt. + */ + + while ((efm32_getreg(EFM32_USB_GINTSTS) & USB_GINTSTS_GONAKEFF) == 0); + efm32_putreg(USB_GINTSTS_GONAKEFF, EFM32_USB_GINTSTS); + +#else + /* Since we are in the interrupt handler, we cannot wait inline for the + * GONAKEFF because it cannot occur until service th RXFLVL global interrupt + * and pop the OUTNAK word from the RxFIFO. + * + * Perhaps it is sufficient to wait for Global OUT NAK status to be reported + * in OTGFS DCTL register? + */ + + while ((efm32_getreg(EFM32_USB_DCTL) & USB_DCTL_GOUTNAKSTS) == 0); +#endif +} + +/**************************************************************************** + * Name: efm32_disablegonak + * + * Description: + * Disable global OUT NAK mode + * + ****************************************************************************/ + +static void efm32_disablegonak(FAR struct efm32_ep_s *privep) +{ + uint32_t regval; + + /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval |= USB_DCTL_CGOUTNAK; + efm32_putreg(regval, EFM32_USB_DCTL); +} + +/**************************************************************************** + * Name: efm32_epout_configure + * + * Description: + * Configure an OUT endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int efm32_epout_configure(FAR struct efm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = USB_DOEP0CTL_MPS_8B; + break; + + case 16: + mpsiz = USB_DOEP0CTL_MPS_16B; + break; + + case 32: + mpsiz = USB_DOEP0CTL_MPS_32B; + break; + + case 64: + mpsiz = USB_DOEP0CTL_MPS_64B; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << _USB_DOEPCTL_MPS_SHIFT); + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + if ((regval & USB_DOEPCTL_USBACTEP) == 0) + { + if (regval & USB_DOEPCTL_NAKSTS) + { + regval |= USB_DOEPCTL_CNAK; + } + + regval &= ~(_USB_DOEPCTL_MPS_MASK | _USB_DOEPCTL_EPTYPE_MASK); + regval |= mpsiz; + regval |= (eptype << _USB_DOEPCTL_EPTYPE_SHIFT); + regval |= (USB_DOEPCTL_SETD0PIDEF | USB_DOEPCTL_USBACTEP); + efm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = efm32_getreg(EFM32_USB_DAINTMSK); + regval |= USB_DAINT_OUTEPINT(privep->epphy); + efm32_putreg(regval, EFM32_USB_DAINTMSK); + return OK; +} + +/**************************************************************************** + * Name: efm32_epin_configure + * + * Description: + * Configure an IN endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int efm32_epin_configure(FAR struct efm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = _USB_DIEP0CTL_MPS_8B; + break; + + case 16: + mpsiz = _USB_DIEP0CTL_MPS_16B; + break; + + case 32: + mpsiz = _USB_DIEP0CTL_MPS_32B; + break; + + case 64: + mpsiz = _USB_DIEP0CTL_MPS_64B; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << _USB_DIEPCTL_MPS_SHIFT); + } + + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + if ((regval & USB_DIEPCTL_USBACTEP) == 0) + { + if (regval & USB_DIEPCTL_NAKSTS) + { + regval |= USB_DIEPCTL_CNAK; + } + + regval &= ~(_USB_DIEPCTL_MPS_MASK | _USB_DIEPCTL_EPTYPE_MASK | + _USB_DIEPCTL_TXFNUM_MASK); + regval |= mpsiz; + regval |= (eptype << _USB_DIEPCTL_EPTYPE_SHIFT); + regval |= (eptype << _USB_DIEPCTL_TXFNUM_SHIFT); + regval |= (USB_DIEPCTL_SETD0PIDEF | USB_DIEPCTL_USBACTEP); + efm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = efm32_getreg(EFM32_USB_DAINTMSK); + regval |= USB_DAINT_INEPINT(privep->epphy); + efm32_putreg(regval, EFM32_USB_DAINTMSK); + + return OK; +} + +/**************************************************************************** + * Name: efm32_ep_configure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int efm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + uint16_t maxpacket; + uint8_t eptype; + int ret; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialize EP capabilities */ + + maxpacket = GETUINT16(desc->mxpacketsize); + eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK; + + /* Setup Endpoint Control Register */ + + if (privep->isin) + { + ret = efm32_epin_configure(privep, eptype, maxpacket); + } + else + { + ret = efm32_epout_configure(privep, eptype, maxpacket); + } + + return ret; +} + +/**************************************************************************** + * Name: efm32_ep0_configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void efm32_ep0_configure(FAR struct efm32_usbdev_s *priv) +{ + /* Enable EP0 IN and OUT */ + + (void)efm32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); + (void)efm32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); +} + +/**************************************************************************** + * Name: efm32_epout_disable + * + * Description: + * Diable an OUT endpoint will no longer be used + * + ****************************************************************************/ + +static void efm32_epout_disable(FAR struct efm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + /* Before disabling any OUT endpoint, the application must enable + * Global OUT NAK mode in the core. + */ + + flags = enter_critical_section(); + efm32_enablegonak(privep); + + /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits + * int DOECPTL register. + */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval &= ~USB_DOEPCTL_USBACTEP; + regval |= (USB_DOEPCTL_EPDIS | USB_DOEPCTL_SNAK); + efm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = EFM32_USB_DOEPINT(privep->epphy); + while ((efm32_getreg(regaddr) & USB_DOEPINT_EPDISBLD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Clear the EPDISD interrupt indication */ + + efm32_putreg(USB_DOEPINT_EPDISBLD, EFM32_USB_DOEPINT(privep->epphy)); + + /* Then disble the Global OUT NAK mode to continue receiving data + * from other non-disabled OUT endpoints. + */ + + efm32_disablegonak(privep); + + /* Disable endpoint interrupts */ + + regval = efm32_getreg(EFM32_USB_DAINTMSK); + regval &= ~USB_DAINT_OUTEPINT(privep->epphy); + efm32_putreg(regval, EFM32_USB_DAINTMSK); + + /* Cancel any queued read requests */ + + efm32_req_cancel(privep, -ESHUTDOWN); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_epin_disable + * + * Description: + * Disable an IN endpoint when it will no longer be used + * + ****************************************************************************/ + +static void efm32_epin_disable(FAR struct efm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* After USB reset, the endpoint will already be deactivated by the + * hardware. Trying to disable again will just hang in the wait. + */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + if ((regval & USB_DIEPCTL_USBACTEP) == 0) + { + return; + } + + /* This INEPNE wait logic is suggested by reference manual, but seems + * to get stuck to infinite loop. + */ + +#if 0 + /* Make sure that there is no pending IPEPNE interrupt (because we are + * to poll this bit below). + */ + + efm32_putreg(USB_DIEPINT_INEPNAKEFF, EFM32_USB_DIEPINT(privep->epphy)); + + /* Set the endpoint in NAK mode */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval &= ~USB_DIEPCTL_USBACTEP; + regval |= (USB_DIEPCTL_EPDIS | USB_DIEPCTL_SNAK); + efm32_putreg(regval, regaddr); + + /* Wait for the INEPNE interrupt that indicates that we are now in NAK mode */ + + regaddr = EFM32_USB_DIEPINT(privep->epphy); + while ((efm32_getreg(regaddr) & USB_DIEPINT_INEPNAKEFF) == 0); + + /* Clear the INEPNE interrupt indication */ + + efm32_putreg(USB_DIEPINT_INEPNAKEFF, regaddr); +#endif + + /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits + * the DIEPCTLx register. + */ + + flags = enter_critical_section(); + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval &= ~USB_DIEPCTL_USBACTEP; + regval |= (USB_DIEPCTL_EPDIS | USB_DIEPCTL_SNAK); + efm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the IN + * endpoint is completely disabled. + */ + + regaddr = EFM32_USB_DIEPINT(privep->epphy); + while ((efm32_getreg(regaddr) & USB_DIEPINT_EPDISBLD) == 0); + + /* Clear the EPDISD interrupt indication */ + + efm32_putreg(USB_DIEPINT_EPDISBLD, efm32_getreg(regaddr)); + + /* Flush any data remaining in the TxFIFO */ + + efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_F(privep->epphy)); + + /* Disable endpoint interrupts */ + + regval = efm32_getreg(EFM32_USB_DAINTMSK); + regval &= ~USB_DAINT_INEPINT(privep->epphy); + efm32_putreg(regval, EFM32_USB_DAINTMSK); + + /* Cancel any queued write requests */ + + efm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: efm32_ep_disable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int efm32_ep_disable(FAR struct usbdev_ep_s *ep) +{ + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + if (privep->isin) + { + /* Disable the IN endpoint */ + + efm32_epin_disable(privep); + } + else + { + /* Disable the OUT endpoint */ + + efm32_epout_disable(privep); + } + + return OK; +} + +/**************************************************************************** + * Name: efm32_ep_allocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *efm32_ep_allocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct efm32_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((FAR struct efm32_ep_s *)ep)->epphy); + + privreq = (FAR struct efm32_req_s *)kmm_malloc(sizeof(struct efm32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct efm32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: efm32_ep_freereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void efm32_ep_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct efm32_req_s *privreq = (FAR struct efm32_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct efm32_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: efm32_ep_allocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *efm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: efm32_ep_freebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void efm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: efm32_ep_submit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int efm32_ep_submit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct efm32_req_s *privreq = (FAR struct efm32_req_s *)req; + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + FAR struct efm32_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + + /* Some sanity checking */ + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint. */ + + if (efm32_req_addlast(privep, privreq) && !privep->active) + { + /* If a request was added to an IN endpoint, then attempt to send + * the request data buffer now. + */ + + if (privep->isin) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the endpoint is not busy with another write request, + * then process the newly received write request now. + */ + + if (!privep->active) + { + efm32_epin_request(priv, privep); + } + } + + /* If the request was added to an OUT endoutput, then attempt to + * setup a read into the request data buffer now (this will, of + * course, fail if there is already a read in place). + */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + efm32_epout_request(priv, privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: efm32_ep_cancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int efm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + efm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: efm32_epout_setstall + * + * Description: + * Stall an OUT endpoint + * + ****************************************************************************/ + +static int efm32_epout_setstall(FAR struct efm32_ep_s *privep) +{ +#if 1 + /* This implementation follows the requirements from the EFM32 F4 reference + * manual. + */ + + uint32_t regaddr; + uint32_t regval; + + /* Put the core in the Global OUT NAK mode */ + + efm32_enablegonak(privep); + + /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits + * in the DOECPTL register. + */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval |= (USB_DOEPCTL_EPDIS | USB_DOEPCTL_STALL); + efm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = EFM32_USB_DOEPINT(privep->epphy); + while ((efm32_getreg(regaddr) & USB_DOEPINT_EPDISBLD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Disable Global OUT NAK mode */ + + efm32_disablegonak(privep); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#else + /* This implementation follows the STMicro code example. */ + /* REVISIT: */ + + uint32_t regaddr; + uint32_t regval; + + /* Stall the OUT endpoint by setting the STALL bit in the DOECPTL register. */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + regval |= USB_DOEPCTL_STALL; + efm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#endif +} + +/**************************************************************************** + * Name: efm32_epin_setstall + * + * Description: + * Stall an IN endpoint + * + ****************************************************************************/ + +static int efm32_epin_setstall(FAR struct efm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + + /* Get the IN endpoint device control register */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + regval = efm32_getreg(regaddr); + + /* Then stall the endpoint */ + + regval |= USB_DIEPCTL_STALL; + efm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +} + +/**************************************************************************** + * Name: efm32_ep_setstall + * + * Description: + * Stall an endpoint + * + ****************************************************************************/ + +static int efm32_ep_setstall(FAR struct efm32_ep_s *privep) +{ + usbtrace(TRACE_EPSTALL, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + return efm32_epin_setstall(privep); + } + else + { + return efm32_epout_setstall(privep); + } +} + +/**************************************************************************** + * Name: efm32_ep_clrstall + * + * Description: + * Resume a stalled endpoint + * + ****************************************************************************/ + +static int efm32_ep_clrstall(FAR struct efm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t stallbit; + uint32_t data0bit; + + usbtrace(TRACE_EPRESUME, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = EFM32_USB_DIEPCTL(privep->epphy); + stallbit = USB_DIEPCTL_STALL; + data0bit = USB_DIEPCTL_SETD0PIDEF; + } + else + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = EFM32_USB_DOEPCTL(privep->epphy); + stallbit = USB_DOEPCTL_STALL; + data0bit = USB_DOEPCTL_SETD0PIDEF; + } + + /* Clear the stall bit */ + + regval = efm32_getreg(regaddr); + regval &= ~stallbit; + + /* Set the DATA0 pid for interrupt and bulk endpoints */ + + if (privep->eptype == USB_EP_ATTR_XFER_INT || + privep->eptype == USB_EP_ATTR_XFER_BULK) + { + /* Writing this bit sets the DATA0 PID */ + + regval |= data0bit; + } + + efm32_putreg(regval, regaddr); + + /* The endpoint is no longer stalled */ + + privep->stalled = false; + return OK; +} + +/**************************************************************************** + * Name: efm32_ep_stall + * + * Description: + * Stall or resume an endpoint + * + ****************************************************************************/ + +static int efm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + irqstate_t flags; + int ret; + + /* Set or clear the stall condition as requested */ + + flags = enter_critical_section(); + if (resume) + { + ret = efm32_ep_clrstall(privep); + } + else + { + ret = efm32_ep_setstall(privep); + } + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: efm32_ep0_stall + * + * Description: + * Stall endpoint 0 + * + ****************************************************************************/ + +static void efm32_ep0_stall(FAR struct efm32_usbdev_s *priv) +{ + efm32_epin_setstall(&priv->epin[EP0]); + efm32_epout_setstall(&priv->epout[EP0]); + priv->stalled = true; + efm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_ep_alloc + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *efm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t eplog, bool in, + uint8_t eptype) +{ + FAR struct efm32_usbdev_s *priv = (FAR struct efm32_usbdev_s *)dev; + uint8_t epavail; + irqstate_t flags; + int epphy; + int epno = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + epphy = USB_EPNO(eplog); + + /* Get the set of available endpoints depending on the direction */ + + flags = enter_critical_section(); + epavail = priv->epavail[in]; + + /* A physical address of 0 means that any endpoint will do */ + + if (epphy > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epphy >= EFM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADEPNO), (uint16_t)epphy); + return NULL; + } + + /* Remove all of the candidate endpoints from the bitset except for the + * this physical endpoint number. + */ + + epavail &= (1 << epphy); + } + + /* Is there an available endpoint? */ + + if (epavail) + { + /* Yes.. Select the lowest numbered endpoint in the set of available + * endpoints. + */ + + for (epno = 1; epno < EFM32_NENDPOINTS; epno++) + { + uint8_t bit = 1 << epno; + if ((epavail & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail[in] &= ~(1 << epno); + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return in ? &priv->epin[epno].ep : &priv->epout[epno].ep; + } + } + + /* We should not get here */ + } + + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_NOEP), (uint16_t)eplog); + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: efm32_ep_free + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void efm32_ep_free(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct efm32_usbdev_s *priv = (FAR struct efm32_usbdev_s *)dev; + FAR struct efm32_ep_s *privep = (FAR struct efm32_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail[privep->isin] |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: efm32_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int efm32_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* Return the last frame number of the last SOF detected by the hardware */ + + regval = efm32_getreg(EFM32_USB_DSTS); + return (int)((regval & _USB_DSTS_SOFFN_MASK) >> _USB_DSTS_SOFFN_SHIFT); +} + +/**************************************************************************** + * Name: efm32_wakeup + * + * Description: + * Exit suspend mode. + * + ****************************************************************************/ + +static int efm32_wakeup(struct usbdev_s *dev) +{ + FAR struct efm32_usbdev_s *priv = (FAR struct efm32_usbdev_s *)dev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + /* Is wakeup enabled? */ + + flags = enter_critical_section(); + if (priv->wakeup) + { + /* Yes... is the core suspended? */ + + regval = efm32_getreg(EFM32_USB_DSTS); + if ((regval & USB_DSTS_SUSPSTS) != 0) + { + /* Re-start the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = efm32_getreg(EFM32_USB_PCGCCTL); + regval &= ~(OTGFS_PCGCCTL_STPPCLK | OTGFS_PCGCCTL_GATEHCLK); + efm32_putreg(regval, EFM32_USB_PCGCCTL); +#endif + /* Activate Remote wakeup signaling */ + + regval = efm32_getreg(EFM32_USB_DCTL); + regval |= USB_DCTL_RMTWKUPSIG; + efm32_putreg(regval, EFM32_USB_DCTL); + up_mdelay(5); + regval &= ~USB_DCTL_RMTWKUPSIG; + efm32_putreg(regval, EFM32_USB_DCTL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: efm32_selfpowered + * + * Description: + * Sets/clears the device self-powered feature + * + ****************************************************************************/ + +static int efm32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct efm32_usbdev_s *priv = (FAR struct efm32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: efm32_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int efm32_pullup(struct usbdev_s *dev, bool enable) +{ + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + regval = efm32_getreg(EFM32_USB_DCTL); + if (enable) + { + /* Connect the device by clearing the soft disconnect bit in the DCTL + * register + */ + + regval &= ~USB_DCTL_SFTDISCON; + } + else + { + /* Connect the device by setting the soft disconnect bit in the DCTL + * register + */ + + regval |= USB_DCTL_SFTDISCON; + } + + efm32_putreg(regval, EFM32_USB_DCTL); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: efm32_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static void efm32_setaddress(struct efm32_usbdev_s *priv, uint16_t address) +{ + uint32_t regval; + + /* Set the device address in the DCFG register */ + + regval = efm32_getreg(EFM32_USB_DCFG); + regval &= ~_USB_DCFG_DEVADDR_MASK; + regval |= ((uint32_t)address << _USB_DCFG_DEVADDR_SHIFT); + efm32_putreg(regval, EFM32_USB_DCFG); + + /* Are we now addressed? (i.e., do we have a non-NULL device + * address?) + */ + + if (address != 0) + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->addressed = true; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + priv->addressed = false; + } +} + +/**************************************************************************** + * Name: efm32_txfifo_flush + * + * Description: + * Flush the specific TX fifo. + * + ****************************************************************************/ + +static int efm32_txfifo_flush(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = USB_GRSTCTL_TXFFLSH | txfnum; + efm32_putreg(regval, EFM32_USB_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < EFM32_FLUSH_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: efm32_rxfifo_flush + * + * Description: + * Flush the RX fifo. + * + ****************************************************************************/ + +static int efm32_rxfifo_flush(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + efm32_putreg(USB_GRSTCTL_RXFFLSH, EFM32_USB_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < EFM32_FLUSH_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: efm32_swinitialize + * + * Description: + * Initialize all driver data structures. + * + ****************************************************************************/ + +static void efm32_swinitialize(FAR struct efm32_usbdev_s *priv) +{ + FAR struct efm32_ep_s *privep; + int i; + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct efm32_usbdev_s)); + + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->epin[EP0].ep; + + priv->epavail[0] = EFM32_EP_AVAILABLE; + priv->epavail[1] = EFM32_EP_AVAILABLE; + + priv->epin[EP0].ep.priv = priv; + priv->epout[EP0].ep.priv = priv; + + /* Initialize the endpoint lists */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epin[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->isin = 1; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = EFM32_EPPHYIN2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } + + /* Initialize the endpoint lists */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epout[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = EFM32_EPPHYOUT2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } +} + +/**************************************************************************** + * Name: efm32_hwinitialize + * + * Description: + * Configure the OTG FS core for operation. + * + ****************************************************************************/ + +static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv) +{ + uint32_t regval; + uint32_t timeout; + uint32_t address; + int i; + + /* "The application must perform the following steps to initialize the core + * at device on, power on, or after a mode change from Host to Device. + * 1. Program the following fields in USB_DCFG register. + * - Device Speed + * - NonZero Length Status OUT Handshake + * - Periodic Frame Interval + * 2. Program the USB_GINTMSK register to unmask the following interrupts. + * - USB Reset + * - Enumeration Done + * - Early Suspend + * - USB Suspend + * 3. Wait for the USB_GINTSTS.USBRST interrupt, which indicates a reset + * has been detected on the USB and lasts for about 10 ms. On receiving + * this interrupt, the application must perform the steps listed in + * Initialization on USB Reset ... + * 4. Wait for the USB_GINTSTS.ENUMDONE interrupt. This interrupt indicates + * the end of reset on the USB. On receiving this interrupt, the + * application must read the USB_DSTS register to determine the + * enumeration speed and perform the steps listed in Initialization on + * Enumeration Completion ..." + * + * "Initialization on USB Reset + * 1. Set the NAK bit for all OUT endpoints + * - USB_DOEPx_CTL.SNAK = 1 (for all OUT endpoints) + * 2. Unmask the following interrupt bits: + * - USB_USB_DAINTMSK.INEP0 = 1 (control 0 IN endpoint) + * - USB_USB_DAINTMSK.OUTEP0 = 1 (control 0 OUT endpoint) + * - USB_DOEPMSK.SETUP = 1 + * - USB_DOEPMSK.XFERCOMPL = 1 + * - USB_DIEPMSK.XFERCOMPL = 1 + * - USB_DIEPMSK.TIMEOUTMSK = 1 + * 3. To transmit or receive data, the device must initialize more + * registers as specified in Device DMA/Slave Mode Initialization ... + * 4. Set up the Data FIFO RAM for each of the FIFOs + * - Program the USB_GRXFSIZ Register, to be able to receive control + * OUT data and setup data. At a minimum, this must be equal to 1 max + * packet size of control endpoint 0 + 2 DWORDs (for the status of the + * control OUT data packet) + 10 DWORDs (for setup packets). + * - Program the Device IN Endpoint Transmit FIFO size register + * (depending on the FIFO number chosen), to be able to transmit + * control IN data. At a minimum, this must be equal to 1 max packet + * size of control endpoint 0. + * 5. Program the following fields in the endpoint-specific registers for + * control OUT endpoint 0 to receive a SETUP packet + * - USB_DOEP0TSIZ.SUPCNT = 3 (to receive up to 3 back-to-back SETUP + * packets) + * - In DMA mode, USB_DOEP0DMAADDR register with a memory address to + * store any SETUP packets received" + * + * "Initialization on Enumeration Completion + * 1. On the Enumeration Done interrupt (USB_GINTSTS.ENUMDONE, read the + * USB_DSTS register to determine the enumeration speed. + * 2. Program the USB_DIEP0CTL.MPS field to set the maximum packet size. + * This step configures control endpoint 0. The maximum packet size + * for a control endpoint depends on the enumeration speed. + * 3. In DMA mode, program the USB_DOEP0CTL register to enable control + * OUT endpoint 0, to receive a SETUP packet. + * - USB_DOEP0CTL.EPENA = 1" + */ + + /* First Turn on USB clocking */ + + modifyreg32(EFM32_CMU_HFCORECLKEN0, 0, + CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC); + + /* At start-up the core is in FS mode. */ + + /* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG + * register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO + * interrupts will occur when the TxFIFO is truly empty (not just half full). + */ + + /* I never saw this in original EFM32 lib + * and in refrence manual I found: + * "Non-periodic TxFIFO Empty Level (can be enabled only when the core is + * operating in Slave mode as a host.)" + */ + + efm32_putreg(USB_GAHBCFG_NPTXFEMPLVL_EMPTY, EFM32_USB_GAHBCFG); + //efm32_putreg(0, EFM32_USB_GAHBCFG); + + /* Enable PHY USB */ + + efm32_putreg(USB_ROUTE_PHYPEN, EFM32_USB_ROUTE); + + /* Common USB OTG core initialization */ + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < EFM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_AHBIDLE) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + efm32_putreg(USB_GRSTCTL_CSFTRST, EFM32_USB_GRSTCTL); + for (timeout = 0; timeout < EFM32_READY_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_CSFTRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Force Device Mode */ + + regval = efm32_getreg(EFM32_USB_GUSBCFG); + regval &= ~(_USB_GUSBCFG_FORCEHSTMODE_MASK | _USB_GUSBCFG_CORRUPTTXPKT_MASK); + regval |= USB_GUSBCFG_FORCEDEVMODE; + efm32_putreg(regval, EFM32_USB_GUSBCFG); + up_mdelay(50); + + /* Initialize device mode */ + /* Restart the PHY Clock */ + + efm32_putreg(0, EFM32_USB_PCGCCTL); + + /* Device configuration register */ + + regval = efm32_getreg(EFM32_USB_DCFG); + regval &= ~_USB_DCFG_PERFRINT_MASK; + regval |= USB_DCFG_PERFRINT_80PCNT; + efm32_putreg(regval, EFM32_USB_DCFG); + + /* Set full speed PHY */ + + regval = efm32_getreg(EFM32_USB_DCFG); + regval &= ~_USB_DCFG_DEVSPD_MASK; + regval |= USB_DCFG_DEVSPD_FS; + efm32_putreg(regval, EFM32_USB_DCFG); + + /* Set Rx FIFO size */ + + efm32_putreg(EFM32_RXFIFO_WORDS << _USB_GRXFSIZ_RXFDEP_SHIFT, + EFM32_USB_GRXFSIZ); + + /* EP0 TX */ + + address = EFM32_RXFIFO_WORDS; + regval = (address << _USB_DIEPTXF0_TXFSTADDR_SHIFT) | + (EFM32_EP0_TXFIFO_WORDS << _USB_DIEPTXF0_TXFINEPTXF0DEP_SHIFT); + efm32_putreg(regval, EFM32_USB_DIEPTXF0); + + /* EP1 TX */ + + address += EFM32_EP0_TXFIFO_WORDS; + regval = (address << _USB_DIEPTXF1_INEPNTXFSTADDR_SHIFT) | + (EFM32_EP1_TXFIFO_WORDS << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT); + efm32_putreg(regval, EFM32_USB_DIEPTXF1); + + /* EP2 TX */ + + address += EFM32_EP1_TXFIFO_WORDS; + regval = (address << _USB_DIEPTXF2_INEPNTXFSTADDR_SHIFT) | + (EFM32_EP2_TXFIFO_WORDS << _USB_DIEPTXF2_INEPNTXFDEP_SHIFT); + efm32_putreg(regval, EFM32_USB_DIEPTXF2); + + /* EP3 TX */ + + address += EFM32_EP2_TXFIFO_WORDS; + regval = (address << _USB_DIEPTXF3_INEPNTXFSTADDR_SHIFT) | + (EFM32_EP3_TXFIFO_WORDS << _USB_DIEPTXF3_INEPNTXFDEP_SHIFT); + efm32_putreg(regval, EFM32_USB_DIEPTXF3); + + /* Flush the FIFOs */ + + efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_FALL); + efm32_rxfifo_flush(); + + /* Clear all pending Device Interrupts */ + + efm32_putreg(0, EFM32_USB_DIEPMSK); + efm32_putreg(0, EFM32_USB_DOEPMSK); + efm32_putreg(0, EFM32_USB_DIEPEMPMSK); + efm32_putreg(0xffffffff, EFM32_USB_DAINT); + efm32_putreg(0, EFM32_USB_DAINTMSK); + + /* Configure all IN endpoints */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + regval = efm32_getreg(EFM32_USB_DIEPCTL(i)); + if ((regval & USB_DIEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = USB_DIEPCTL_EPENA | USB_DIEPCTL_SNAK; + } + else + { + regval = 0; + } + + efm32_putreg(regval, EFM32_USB_DIEPCTL(i)); + efm32_putreg(0, EFM32_USB_DIEPTSIZ(i)); + efm32_putreg(0xff, EFM32_USB_DIEPINT(i)); + } + + /* Configure all OUT endpoints */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + regval = efm32_getreg(EFM32_USB_DOEPCTL(i)); + if ((regval & USB_DOEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = USB_DOEPCTL_EPENA | USB_DOEPCTL_SNAK; + } + else + { + regval = 0; + } + + efm32_putreg(regval, EFM32_USB_DOEPCTL(i)); + efm32_putreg(0, EFM32_USB_DOEPTSIZ(i)); + efm32_putreg(0xff, EFM32_USB_DOEPINT(i)); + } + + /* Disable all interrupts. */ + + efm32_putreg(0, EFM32_USB_GINTMSK); + + /* Clear any pending USB_OTG Interrupts */ + + efm32_putreg(0xffffffff, EFM32_USB_GOTGINT); + + /* Clear any pending interrupts */ + + efm32_putreg(0xbfffffff, EFM32_USB_GINTSTS); + + /* Enable the interrupts in the INTMSK */ + + regval = (USB_GINTMSK_RXFLVLMSK | USB_GINTMSK_USBSUSPMSK | USB_GINTMSK_ENUMDONEMSK | + USB_GINTMSK_IEPINTMSK | USB_GINTMSK_OEPINTMSK | USB_GINTMSK_USBRSTMSK); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + regval |= (USB_GINTMSK_INCOMPISOINMSK | USB_GINTMSK_INCOMPLPMSK); +#endif + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + regval |= USB_GINTMSK_SOFMSK; +#endif + +#ifdef CONFIG_USBDEV_VBUSSENSING + regval |= (USB_GINTMSK_OTGINTMSK | USB_GINTMSK_SESSREQINTMSK); +#endif + +#ifdef CONFIG_DEBUG_USB + regval |= USB_GINTMSK_MODEMISMSK; +#endif + + efm32_putreg(regval, EFM32_USB_GINTMSK); + + /* Enable the USB global interrupt by setting GINTMSK in the global OTG + * FS AHB configuration register; Set the TXFELVL bit in the GAHBCFG + * register so that TxFIFO interrupts will occur when the TxFIFO is truly + * empty (not just half full). + */ + + efm32_putreg(USB_GAHBCFG_GLBLINTRMSK | USB_GAHBCFG_NPTXFEMPLVL_EMPTY, + EFM32_USB_GAHBCFG); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbdev_s *priv = &g_otgfsdev; + int ret; + + usbtrace(TRACE_DEVINIT, 0); + + /* "The USB requires the device to run from a 48 MHz crystal (2500 ppm or + * better). The core part of the USB will always run from HFCORECLKUSBC + * which is HFCLK undivided (48 MHz). The current consumption for the + * rest of the device can be reduced by dividing down HFCORECLK using + * the CMU_HFCORECLKDIV register. ..." + * + * "Follow these steps to enable the USB: + * 1. Enable the clock to the system part by setting USB in + * CMU_HFCORECLKEN0. + * 2. If the internal USB regulator is bypassed (by applying 3.3V on + * USB_VREGI and USB_VREGO externally), disable the regulator by + * setting VREGDIS in USB_CTRL. + * 3. If the PHY is powered from VBUS using the internal regulator, the + * VREGO sense circuit should be enabled by setting VREGOSEN in + * USB_CTRL. + * 4. Enable the USB PHY pins by setting PHYPEN in USB_ROUTE. + * 5. If host or OTG dual-role device, set VBUSENAP in USB_CTRL to the + * desired value and then enable the USB_VBUSEN pin in USB_ROUTE. Set + * the MODE for the pin to PUSHPULL. + * 6. If low-speed device, set DMPUAP in USB_CTRL to the desired value + * and then enable the USB_DMPU pin in USB_ROUTE. Set the MODE for the + * pin to PUSHPULL. + * 7. Make sure HFXO is ready and selected. The core part requires the + * undivided HFCLK to be 48 MHz when USB is active (during + * suspend/session-off a 32 kHz clock is used).. + * 8. Enable the clock to the core part by setting USBC in + * CMU_HFCORECLKEN0. + * 9. Wait for the core to come out of reset. This is easiest done by + * polling a core register with non-zero reset value until it reads a + * non-zero value. This takes approximately 20 48-MHz cycles. + * 10. Start initializing the USB core ... + */ + + /* Uninitialize the hardware so that we know that we are starting from a + * known state. */ + + up_usbuninitialize(); + + /* Initialie the driver data structure */ + + efm32_swinitialize(priv); + + /* Attach the OTG FS interrupt handler */ + + ret = irq_attach(EFM32_IRQ_USB, efm32_usbinterrupt); + if (ret < 0) + { + udbg("irq_attach failed\n", ret); + goto errout; + } + + /* Initialize the USB OTG core */ + + efm32_hwinitialize(priv); + + /* Disconnect device */ + + efm32_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + efm32_usbreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(EFM32_IRQ_USB); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(EFM32_IRQ_USB, CONFIG_OTGFS_PRI); +#endif + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbdev_s *priv = &g_otgfsdev; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVUNINIT, 0); + + /* To be sure that usb ref are writen, turn on USB clocking */ + + modifyreg32(EFM32_CMU_HFCORECLKEN0, 0, + CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + efm32_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(EFM32_IRQ_USB); + irq_detach(EFM32_IRQ_USB); + + /* Disable all endpoint interrupts */ + + for (i = 0; i < EFM32_NENDPOINTS; i++) + { + efm32_putreg(0xff, EFM32_USB_DIEPINT(i)); + efm32_putreg(0xff, EFM32_USB_DOEPINT(i)); + } + + efm32_putreg(0, EFM32_USB_DIEPMSK); + efm32_putreg(0, EFM32_USB_DOEPMSK); + efm32_putreg(0, EFM32_USB_DIEPEMPMSK); + efm32_putreg(0, EFM32_USB_DAINTMSK); + efm32_putreg(0xffffffff, EFM32_USB_DAINT); + + /* Flush the FIFOs */ + + efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_FALL); + efm32_rxfifo_flush(); + + /* Turn off USB clocking */ + + modifyreg32(EFM32_CMU_HFCORECLKEN0, + CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC, 0); + + /* TODO: Turn off USB power and clocking */ + + priv->devstate = DEVSTATE_DEFAULT; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbdev_s *priv = &g_otgfsdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(EFM32_IRQ_USB); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + efm32_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbdev_s *priv = &g_otgfsdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + efm32_usbreset(priv); + leave_critical_section(flags); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts */ + + flags = enter_critical_section(); + up_disable_irq(EFM32_IRQ_USB); + + /* Disconnect device */ + + efm32_pullup(&priv->usbdev, false); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_EFM32_OTGFSDEV */ diff --git a/arch/arm/src/efm32/efm32_usbhost.c b/arch/arm/src/efm32/efm32_usbhost.c new file mode 100644 index 0000000000000000000000000000000000000000..cc9fe1c7d8d0a3037c98b0b74bfa2e488578ab1b --- /dev/null +++ b/arch/arm/src/efm32/efm32_usbhost.c @@ -0,0 +1,5378 @@ +/**************************************************************************** + * arch/arm/src/efm32/efm32_usbhost.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" /* Includes default GPIO settings */ +#include /* May redefine GPIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "efm32_usb.h" + +#if defined(CONFIG_USBHOST) && defined(CONFIG_EFM32_OTGFS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* EFM32 USB OTG FS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_EFM32_OTGFS - Enable the EFM32 USB OTG FS block + * + * Options: + * + * CONFIG_EFM32_OTGFS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_EFM32_OTGFS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_EFM32_OTGFS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_EFM32_OTGFS_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_EFM32_OTGFS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * CONFIG_EFM32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG. + * CONFIG_EFM32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * packets. Depends on CONFIG_DEBUG. + */ + +/* Default RxFIFO size */ + +#ifndef CONFIG_EFM32_OTGFS_RXFIFO_SIZE +# define CONFIG_EFM32_OTGFS_RXFIFO_SIZE 128 +#endif + +/* Default host non-periodic Tx FIFO size */ + +#ifndef CONFIG_EFM32_OTGFS_NPTXFIFO_SIZE +# define CONFIG_EFM32_OTGFS_NPTXFIFO_SIZE 96 +#endif + +/* Default host periodic Tx fifo size register */ + +#ifndef CONFIG_EFM32_OTGFS_PTXFIFO_SIZE +# define CONFIG_EFM32_OTGFS_PTXFIFO_SIZE 96 +#endif + +/* Maximum size of a descriptor */ + +#ifndef CONFIG_EFM32_OTGFS_DESCSIZE +# define CONFIG_EFM32_OTGFS_DESCSIZE 128 +#endif + +/* Register/packet debug depends on CONFIG_DEBUG */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_EFM32_USBHOST_REGDEBUG +# undef CONFIG_EFM32_USBHOST_PKTDUMP +#endif + +/* HCD Setup *******************************************************************/ +/* Hardware capabilities */ + +#define EFM32_NHOST_CHANNELS 8 /* Number of host channels */ +#define EFM32_MAX_PACKET_SIZE 64 /* Full speed max packet size */ +#define EFM32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */ +#define EFM32_EP0_MAX_PACKET_SIZE 64 /* EP0 FS max packet size */ +#define EFM32_MAX_TX_FIFOS 15 /* Max number of TX FIFOs */ +#define EFM32_MAX_PKTCOUNT 256 /* Max packet count */ +#define EFM32_RETRY_COUNT 3 /* Number of ctrl transfer retries */ + +/* Delays **********************************************************************/ + +#define EFM32_READY_DELAY 200000 /* In loop counts */ +#define EFM32_FLUSH_DELAY 200000 /* In loop counts */ +#define EFM32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ +#define EFM32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ + +/* Ever-present MIN/MAX macros */ + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +/* Tracing *********************************************************************/ + +#define TR_FMT1 false +#define TR_FMT2 true + +#define TRENTRY(id,fmt1,string) {string} + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The following enumeration represents the various states of the USB host + * state machine (for debug purposes only) + */ + +enum efm32_smstate_e +{ + SMSTATE_DETACHED = 0, /* Not attached to a device */ + SMSTATE_ATTACHED, /* Attached to a device */ + SMSTATE_ENUM, /* Attached, enumerating */ + SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */ +}; + +/* This enumeration provides the reason for the channel halt. */ + +enum efm32_chreason_e +{ + CHREASON_IDLE = 0, /* Inactive (initial state) */ + CHREASON_FREED, /* Channel is no longer in use */ + CHREASON_XFRC, /* Transfer complete */ + CHREASON_NAK, /* NAK received */ + CHREASON_NYET, /* NotYet received */ + CHREASON_STALL, /* Endpoint stalled */ + CHREASON_TXERR, /* Transfer error received */ + CHREASON_DTERR, /* Data toggle error received */ + CHREASON_FRMOR, /* Frame overrun */ + CHREASON_CANCELLED /* Transfer cancelled */ +}; + +/* This structure retains the state of one host channel. NOTE: Since there + * is only one channel operation active at a time, some of the fields in + * in the structure could be moved in struct efm32_ubhost_s to achieve + * some memory savings. + */ + +struct efm32_chan_s +{ + sem_t waitsem; /* Channel wait semaphore */ + volatile uint8_t result; /* The result of the transfer */ + volatile uint8_t chreason; /* Channel halt reason. See enum efm32_chreason_e */ + uint8_t chidx; /* Channel index */ + uint8_t epno; /* Device endpoint number (0-127) */ + uint8_t eptype; /* See EFM32_USB_EPTYPE_* definitions */ + uint8_t funcaddr; /* Device function address */ + uint8_t speed; /* Device speed */ + uint8_t pid; /* Data PID */ + uint8_t npackets; /* Number of packets (for data toggle) */ + bool inuse; /* True: This channel is "in use" */ + volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */ + volatile bool outdata1; /* OUT data toggle. True: DATA01 */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + uint16_t maxpacket; /* Max packet size */ + uint16_t buflen; /* Buffer length (at start of transfer) */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ + volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */ + FAR uint8_t *buffer; /* Transfer buffer pointer */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + FAR void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* A channel represents on uni-directional endpoint. So, in the case of the + * bi-directional, control endpoint, there must be two channels to represent + * the endpoint. + */ + +struct efm32_ctrlinfo_s +{ + uint8_t inndx; /* EP0 IN control channel index */ + uint8_t outndx; /* EP0 OUT control channel index */ +}; + +/* This structure retains the state of the USB host controller */ + +struct efm32_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to structefm32_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Overall driver status */ + + volatile uint8_t smstate; /* The state of the USB host state machine */ + uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */ + volatile bool connected; /* Connected to device */ + volatile bool change; /* Connection change */ + volatile bool pscwait; /* True: Thread is waiting for a port event */ + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for a port event */ + struct efm32_ctrlinfo_s ep0; /* Root hub port EP0 description */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* The state of each host channel */ + + struct efm32_chan_s chan[EFM32_MAX_TX_FIFOS]; +}; + +#ifdef HAVE_USBHOST_TRACE +/* Format of one trace entry */ + +struct efm32_usbhost_trace_s +{ +#if 0 + uint16_t id; + bool fmt2; +#endif + FAR const char *string; +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_EFM32_USBHOST_REGDEBUG +static void efm32_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void efm32_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t efm32_getreg(uint32_t addr); +static void efm32_putreg(uint32_t addr, uint32_t value); +#else +# define efm32_getreg(addr) getreg32(addr) +# define efm32_putreg(addr,val) putreg32(val,addr) +#endif + +static inline void efm32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits); + +#ifdef CONFIG_EFM32_USBHOST_PKTDUMP +# define efm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) +#else +# define efm32_pktdump(m,b,n) +#endif + +/* Semaphores ******************************************************************/ + +static void efm32_takesem(sem_t *sem); +#define efm32_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t efm32_getle16(const uint8_t *val); + +/* Channel management **********************************************************/ + +static int efm32_chan_alloc(FAR struct efm32_usbhost_s *priv); +static inline void efm32_chan_free(FAR struct efm32_usbhost_s *priv, int chidx); +static inline void efm32_chan_freeall(FAR struct efm32_usbhost_s *priv); +static void efm32_chan_configure(FAR struct efm32_usbhost_s *priv, int chidx); +static void efm32_chan_halt(FAR struct efm32_usbhost_s *priv, int chidx, + enum efm32_chreason_e chreason); +static int efm32_chan_waitsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan); +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_chan_asynchsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int efm32_chan_wait(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan); +static void efm32_chan_wakeup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan); +static int efm32_ctrlchan_alloc(FAR struct efm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct efm32_ctrlinfo_s *ctrlep); +static int efm32_ctrlep_alloc(FAR struct efm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int efm32_xfrep_alloc(FAR struct efm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); + +/* Control/data transfer logic *************************************************/ + +static void efm32_transfer_start(FAR struct efm32_usbhost_s *priv, int chidx); +#if 0 /* Not used */ +static inline uint16_t efm32_getframe(void); +#endif +static int efm32_ctrl_sendsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req); +static int efm32_ctrl_senddata(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int efm32_ctrl_recvdata(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int efm32_in_setup(FAR struct efm32_usbhost_s *priv, int chidx); +static ssize_t efm32_in_transfer(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void efm32_in_next(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan); +static int efm32_in_asynch(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int efm32_out_setup(FAR struct efm32_usbhost_s *priv, int chidx); +static ssize_t efm32_out_transfer(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void efm32_out_next(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan); +static int efm32_out_asynch(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif + +/* Interrupt handling **********************************************************/ +/* Lower level interrupt handlers */ + +static void efm32_gint_wrpacket(FAR struct efm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen); +static inline void efm32_gint_hcinisr(FAR struct efm32_usbhost_s *priv, + int chidx); +static inline void efm32_gint_hcoutisr(FAR struct efm32_usbhost_s *priv, + int chidx); +static void efm32_gint_connected(FAR struct efm32_usbhost_s *priv); +static void efm32_gint_disconnected(FAR struct efm32_usbhost_s *priv); + +/* Second level interrupt handlers */ + +#ifdef CONFIG_EFM32_OTGFS_SOFINTR +static inline void efm32_gint_sofisr(FAR struct efm32_usbhost_s *priv); +#endif +static inline void efm32_gint_rxflvlisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_nptxfeisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_ptxfeisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_hcisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_hprtisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_discisr(FAR struct efm32_usbhost_s *priv); +static inline void efm32_gint_ipxfrisr(FAR struct efm32_usbhost_s *priv); + +/* First level, global interrupt handler */ + +static int efm32_gint_isr(int irq, FAR void *context); + +/* Interrupt controls */ + +static void efm32_gint_enable(void); +static void efm32_gint_disable(void); +static inline void efm32_hostinit_enable(void); +static void efm32_txfe_enable(FAR struct efm32_usbhost_s *priv, int chidx); + +/* USB host controller operations **********************************************/ + +static int efm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int efm32_rh_enumerate(FAR struct efm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int efm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int efm32_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int efm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const FAR struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int efm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int efm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int efm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int efm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int efm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int efm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer); +static int efm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer); +static ssize_t efm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int efm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int efm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected); +#endif +static void efm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static void efm32_portreset(FAR struct efm32_usbhost_s *priv); +static void efm32_flush_txfifos(uint32_t txfnum); +static void efm32_flush_rxfifo(void); +static void efm32_vbusdrive(FAR struct efm32_usbhost_s *priv, bool state); +static void efm32_host_initialize(FAR struct efm32_usbhost_s *priv); + +static inline void efm32_sw_initialize(FAR struct efm32_usbhost_s *priv); +static inline int efm32_hw_initialize(FAR struct efm32_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct efm32_usbhost_s g_usbhost; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = efm32_wait, + .enumerate = efm32_enumerate, +}; + +#ifdef HAVE_USBHOST_TRACE +/* Trace strings */ + +static const struct efm32_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] = +{ + TRENTRY(USBHOST_TRACE1_DEVDISCONN, TR_FMT1, "OTGFS ERROR: Host Port %d. Device disconnected\n"), + TRENTRY(USBHOST_TRACE1_IRQATTACH, TR_FMT1, "OTGFS ERROR: Failed to attach IRQ\n"), + TRENTRY(USBHOST_TRACE1_TRNSFRFAILED, TR_FMT1, "OTGFS ERROR: Transfer Failed. ret=%d\n"), + TRENTRY(USBHOST_TRACE1_SENDSETUP, TR_FMT1, "OTGFS ERROR: ctrl_sendsetup() failed with: %d\n"), + TRENTRY(USBHOST_TRACE1_SENDDATA, TR_FMT1, "OTGFS ERROR: ctrl_senddata() failed with: %d\n"), + TRENTRY(USBHOST_TRACE1_RECVDATA, TR_FMT1, "OTGFS ERROR: ctrl_recvdata() failed with: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(USBHOST_VTRACE1_CONNECTED, TR_FMT1, "OTGFS Host Port %d connected.\n"), + TRENTRY(USBHOST_VTRACE1_DISCONNECTED, TR_FMT1, "OTGFS Host Port %d disconnected.\n"), + TRENTRY(USBHOST_VTRACE1_GINT, TR_FMT1, "OTGFS Handling Interrupt. Entry Point.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_SOF, TR_FMT1, "OTGFS Handle the start of frame interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_RXFLVL, TR_FMT1, "OTGFS Handle the RxFIFO non-empty interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_NPTXFE, TR_FMT1, "OTGFS Handle the non-periodic TxFIFO empty interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_PTXFE, TR_FMT1, "OTGFS Handle the periodic TxFIFO empty interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HC, TR_FMT1, "OTGFS Handle the host channels interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT, TR_FMT1, "OTGFS Handle the host port interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_POCCHNG, TR_FMT1, "OTGFS HPRT: Port Over-Current Change.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_PCDET, TR_FMT1, "OTGFS HPRT: Port Connect Detect.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_PENCHNG, TR_FMT1, "OTGFS HPRT: Port Enable Changed.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_LSDEV, TR_FMT1, "OTGFS HPRT: Low Speed Device Connected.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_FSDEV, TR_FMT1, "OTGFS HPRT: Full Speed Device Connected.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_LSFSSW, TR_FMT1, "OTGFS HPRT: Host Switch: LS -> FS.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_HPRT_FSLSSW, TR_FMT1, "OTGFS HPRT: Host Switch: FS -> LS.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_DISC, TR_FMT1, "OTGFS Handle the disconnect detected interrupt.\n"), + TRENTRY(USBHOST_VTRACE1_GINT_IPXFR, TR_FMT1, "OTGFS Handle the incomplete periodic transfer.\n"), +#endif +}; + +static const struct efm32_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] = +{ + TRENTRY(USBHOST_TRACE2_CLIP, TR_FMT2, "OTGFS CLIP: chidx: %d buflen: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(USBHOST_VTRACE2_CHANWAKEUP_IN, TR_FMT2, "OTGFS EP%d(IN) wake up with result: %d\n"), + TRENTRY(USBHOST_VTRACE2_CHANWAKEUP_OUT, TR_FMT2, "OTGFS EP%d(OUT) wake up with result: %d\n"), + TRENTRY(USBHOST_VTRACE2_CTRLIN, TR_FMT2, "OTGFS CTRL_IN type: %02x req: %02x\n"), + TRENTRY(USBHOST_VTRACE2_CTRLOUT, TR_FMT2, "OTGFS CTRL_OUT type: %02x req: %02x\n"), + TRENTRY(USBHOST_VTRACE2_INTRIN, TR_FMT2, "OTGFS INTR_IN chidx: %02x len: %02x\n"), + TRENTRY(USBHOST_VTRACE2_INTROUT, TR_FMT2, "OTGFS INTR_OUT chidx: %02x len: %02x\n"), + TRENTRY(USBHOST_VTRACE2_BULKIN, TR_FMT2, "OTGFS BULK_IN chidx: %02x len: %02x\n"), + TRENTRY(USBHOST_VTRACE2_BULKOUT, TR_FMT2, "OTGFS BULK_OUT chidx: %02x len: %02x\n"), + TRENTRY(USBHOST_VTRACE2_ISOCIN, TR_FMT2, "OTGFS ISOC_IN chidx: %02x len: %04d\n"), + TRENTRY(USBHOST_VTRACE2_ISOCOUT, TR_FMT2, "OTGFS ISOC_OUT chidx: %02x req: %02x\n"), + TRENTRY(USBHOST_VTRACE2_STARTTRANSFER, TR_FMT2, "OTGFS Transfer chidx: %d buflen: %d\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_CTRL_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,CTRL)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_CTRL_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,CTRL)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_INTR_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,INTR)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_INTR_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,INTR)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_BULK_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,BULK)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_BULK_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,BULK)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_ISOC_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,ISOC)\n"), + TRENTRY(USBHOST_VTRACE2_CHANCONF_ISOC_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,ISOC)\n"), + TRENTRY(USBHOST_VTRACE2_CHANHALT, TR_FMT2, "OTGFS Channel halted. chidx: %d, reason: %d\n"), +#endif +}; +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_printreg + * + * Description: + * Print the contents of an EFM32xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_USBHOST_REGDEBUG +static void efm32_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: efm32_checkreg + * + * Description: + * Get the contents of an EFM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_USBHOST_REGDEBUG +static void efm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + efm32_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + efm32_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: efm32_getreg + * + * Description: + * Get the contents of an EFM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_USBHOST_REGDEBUG +static uint32_t efm32_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + efm32_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: efm32_putreg + * + * Description: + * Set the contents of an EFM32 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_USBHOST_REGDEBUG +static void efm32_putreg(uint32_t addr, uint32_t val) +{ + /* Check if we need to print this value */ + + efm32_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: efm32_modifyreg + * + * Description: + * Modify selected bits of an EFM32 register. + * + ****************************************************************************/ + +static inline void efm32_modifyreg(uint32_t addr, uint32_t clrbits, uint32_t setbits) +{ + efm32_putreg(addr, (((efm32_getreg(addr)) & ~clrbits) | setbits)); +} + +/**************************************************************************** + * Name: efm32_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void efm32_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: efm32_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t efm32_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: efm32_chan_alloc + * + * Description: + * Allocate a channel. + * + ****************************************************************************/ + +static int efm32_chan_alloc(FAR struct efm32_usbhost_s *priv) +{ + int chidx; + + /* Search the table of channels */ + + for (chidx = 0; chidx < EFM32_NHOST_CHANNELS; chidx++) + { + /* Is this channel available? */ + + if (!priv->chan[chidx].inuse) + { + /* Yes... make it "in use" and return the index */ + + priv->chan[chidx].inuse = true; + return chidx; + } + } + + /* All of the channels are "in-use" */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: efm32_chan_free + * + * Description: + * Free a previoiusly allocated channel. + * + ****************************************************************************/ + +static void efm32_chan_free(FAR struct efm32_usbhost_s *priv, int chidx) +{ + DEBUGASSERT((unsigned)chidx < EFM32_NHOST_CHANNELS); + + /* Halt the channel */ + + efm32_chan_halt(priv, chidx, CHREASON_FREED); + + /* Mark the channel available */ + + priv->chan[chidx].inuse = false; +} + +/**************************************************************************** + * Name: efm32_chan_freeall + * + * Description: + * Free all channels. + * + ****************************************************************************/ + +static inline void efm32_chan_freeall(FAR struct efm32_usbhost_s *priv) +{ + uint8_t chidx; + + /* Free all host channels */ + + for (chidx = 2; chidx < EFM32_NHOST_CHANNELS; chidx ++) + { + efm32_chan_free(priv, chidx); + } +} + +/**************************************************************************** + * Name: efm32_chan_configure + * + * Description: + * Configure or re-configure a host channel. Host channels are configured + * when endpoint is allocated and EP0 (only) is re-configured with the + * max packet size or device address changes. + * + ****************************************************************************/ + +static void efm32_chan_configure(FAR struct efm32_usbhost_s *priv, int chidx) +{ + FAR struct efm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + + /* Clear any old pending interrupts for this host channel. */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), 0xffffffff); + + /* Enable channel interrupts required for transfers on this channel. */ + + regval = 0; + + switch (chan->eptype) + { + case EFM32_USB_EPTYPE_CTRL: + case EFM32_USB_EPTYPE_BULK: + { +#ifdef HAVE_USBHOST_TRACE_VERBOSE + uint16_t intrace; + uint16_t outtrace; + + /* Determine the definitive trace ID to use below */ + + if (chan->eptype == EFM32_USB_EPTYPE_CTRL) + { + intrace = USBHOST_VTRACE2_CHANCONF_CTRL_IN; + outtrace = USBHOST_VTRACE2_CHANCONF_CTRL_OUT; + } + else + { + intrace = USBHOST_VTRACE2_CHANCONF_BULK_IN; + outtrace = USBHOST_VTRACE2_CHANCONF_BULK_OUT; + } +#endif + + /* Interrupts required for CTRL and BULK endpoints */ + + regval |= (USB_HC_INTMSK_XFERCOMPLMSK | USB_HC_INTMSK_STALLMSK | + USB_HC_INTMSK_NAKMSK | USB_HC_INTMSK_XACTERRMSK | + USB_HC_INTMSK_DATATGLERRMSK); + + /* Additional setting for IN/OUT endpoints */ + + if (chan->in) + { + usbhost_vtrace2(intrace, chidx, chan->epno); + regval |= USB_HC_INTMSK_BBLERRMSK; + } + else + { + usbhost_vtrace2(outtrace, chidx, chan->epno); + } + } + break; + + case EFM32_USB_EPTYPE_INTR: + { + /* Interrupts required for INTR endpoints */ + + regval |= (USB_HC_INTMSK_XFERCOMPLMSK | USB_HC_INTMSK_STALLMSK | + USB_HC_INTMSK_NAKMSK | USB_HC_INTMSK_XACTERRMSK | + USB_HC_INTMSK_FRMOVRUNMSK | USB_HC_INTMSK_DATATGLERRMSK); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(USBHOST_VTRACE2_CHANCONF_INTR_IN, chidx, + chan->epno); + regval |= USB_HC_INTMSK_BBLERRMSK; + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(USBHOST_VTRACE2_CHANCONF_INTR_OUT, chidx, + chan->epno); + } +#endif + } + break; + + case EFM32_USB_EPTYPE_ISOC: + { + /* Interrupts required for ISOC endpoints */ + + regval |= (USB_HC_INTMSK_XFERCOMPLMSK | USB_HC_INTMSK_ACKMSK | + USB_HC_INTMSK_FRMOVRUNMSK); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(USBHOST_VTRACE2_CHANCONF_ISOC_IN, chidx, + chan->epno); + regval |= (USB_HC_INTMSK_XACTERRMSK | USB_HC_INTMSK_BBLERRMSK); + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(USBHOST_VTRACE2_CHANCONF_ISOC_OUT, chidx, + chan->epno); + } +#endif + } + break; + } + + efm32_putreg(EFM32_USB_HCn_INTMSK(chidx), regval); + + /* Enable the top level host channel interrupt. */ + + efm32_modifyreg(EFM32_USB_HAINTMSK, 0, USB_HAINT(chidx)); + + /* Make sure host channel interrupts are enabled. */ + + efm32_modifyreg(EFM32_USB_GINTMSK, 0, USB_GINTMSK_HCHINTMSK); + + /* Program the HCCHAR register */ + + regval = ((uint32_t)chan->maxpacket << _USB_HC_CHAR_MPS_SHIFT) | + ((uint32_t)chan->epno << _USB_HC_CHAR_EPNUM_SHIFT) | + ((uint32_t)chan->eptype << _USB_HC_CHAR_EPTYPE_SHIFT) | + ((uint32_t)chan->funcaddr << _USB_HC_CHAR_DEVADDR_SHIFT); + + /* Special case settings for low speed devices */ + + if (chan->speed == USB_SPEED_LOW) + { + regval |= USB_HC_CHAR_LSPDDEV; + } + + /* Special case settings for IN endpoints */ + + if (chan->in) + { + regval |= USB_HC_CHAR_EPDIR_IN; + } + + /* Special case settings for INTR endpoints */ + + if (chan->eptype == EFM32_USB_EPTYPE_INTR) + { + regval |= USB_HC_CHAR_ODDFRM; + } + + /* Write the channel configuration */ + + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), regval); +} + +/**************************************************************************** + * Name: efm32_chan_halt + * + * Description: + * Halt the channel associated with 'chidx' by setting the CHannel DISable + * (CHDIS) bit in in the HCCHAR register. + * + ****************************************************************************/ + +static void efm32_chan_halt(FAR struct efm32_usbhost_s *priv, int chidx, + enum efm32_chreason_e chreason) +{ + uint32_t hcchar; + uint32_t intmsk; + uint32_t eptype; + unsigned int avail; + + /* Save the reason for the halt. We need this in the channel halt interrupt + * handling logic to know what to do next. + */ + + usbhost_vtrace2(USBHOST_VTRACE2_CHANHALT, chidx, chreason); + + priv->chan[chidx].chreason = (uint8_t)chreason; + + /* "The application can disable any channel by programming the OTG_FS_HCCHARx + * register with the CHDIS and CHENA bits set to 1. This enables the OTG_FS + * host to flush the posted requests (if any) and generates a channel halted + * interrupt. The application must wait for the CHH interrupt in OTG_FS_HCINTx + * before reallocating the channel for other transactions. The OTG_FS host + * does not interrupt the transaction that has already been started on the + * USB." + */ + + hcchar = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + hcchar |= (USB_HC_CHAR_CHDIS | USB_HC_CHAR_CHENA); + + /* Get the endpoint type from the HCCHAR register */ + + eptype = hcchar & _USB_HC_CHAR_EPTYPE_MASK; + + /* Check for space in the Tx FIFO to issue the halt. + * + * "Before disabling a channel, the application must ensure that there is at + * least one free space available in the non-periodic request queue (when + * disabling a non-periodic channel) or the periodic request queue (when + * disabling a periodic channel). The application can simply flush the + * posted requests when the Request queue is full (before disabling the + * channel), by programming the OTG_FS_HCCHARx register with the CHDIS bit + * set to 1, and the CHENA bit cleared to 0. + */ + + if (eptype == USB_HC_CHAR_EPTYPE_CONTROL || eptype == USB_HC_CHAR_EPTYPE_BULK) + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = efm32_getreg(EFM32_USB_GNPTXSTS) & _USB_GNPTXSTS_NPTXFSPCAVAIL_MASK; + } + else /* if (eptype == USB_HCCHAR_EPTYP_ISOC || eptype == USB_HC_CHAR_EPTYPE_INT) */ + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = efm32_getreg(EFM32_USB_HPTXSTS) & _USB_HPTXSTS_PTXFSPCAVAIL_MASK; + } + + /* Check if there is any space available in the Tx FIFO. */ + + if (avail == 0) + { + /* The Tx FIFO is full... disable the channel to flush the requests */ + + hcchar &= ~USB_HC_CHAR_CHENA; + } + + /* Unmask the CHannel Halted (CHH) interrupt */ + + intmsk = efm32_getreg(EFM32_USB_HCn_INTMSK(chidx)); + intmsk |= USB_HC_INTMSK_CHHLTDMSK; + efm32_putreg(EFM32_USB_HCn_INTMSK(chidx), intmsk); + + /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */ + + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), hcchar); +} + +/**************************************************************************** + * Name: efm32_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been started. + * + ****************************************************************************/ + +static int efm32_chan_waitsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: efm32_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_chan_asynchsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: efm32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int efm32_chan_wait(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan) +{ + irqstate_t flags; + int ret; + + /* Disable interrupts so that the following operations will be atomic. On + * the OTG FS global interrupt needs to be disabled. However, here we disable + * all interrupts to exploit that fact that interrupts will be re-enabled + * while we wait. + */ + + flags = enter_critical_section(); + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; 'waiter' + * will be set to false and 'result' will be set appropriately when the + * transfer is completed. + */ + + do + { + /* Wait for the transfer to complete. NOTE the transfer may already + * completed before we get here or the transfer may complete while we + * wait here. + */ + + ret = sem_wait(&chan->waitsem); + + /* sem_wait should succeed. But it is possible that we could be + * awakened by a signal too. + */ + + DEBUGASSERT(ret == OK || get_errno() == EINTR); + } + while (chan->waiter); + + /* The transfer is complete re-enable interrupts and return the result */ + + ret = -(int)chan->result; + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: efm32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void efm32_chan_wakeup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan) +{ + /* Is the transfer complete? */ + + if (chan->result != EBUSY) + { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + /* Wake'em up! */ + + usbhost_vtrace2(chan->in ? USBHOST_VTRACE2_CHANWAKEUP_IN : + USBHOST_VTRACE2_CHANWAKEUP_OUT, + chan->epno, chan->result); + + efm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + /* Handle continuation of IN/OUT pipes */ + + if (chan->in) + { + efm32_in_next(priv, chan); + } + else + { + efm32_out_next(priv, chan); + } + } +#endif + } +} + +/**************************************************************************** + * Name: efm32_ctrlchan_alloc + * + * Description: + * Allocate and configured channels for a control pipe. + * + ****************************************************************************/ + +static int efm32_ctrlchan_alloc(FAR struct efm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct efm32_ctrlinfo_s *ctrlep) +{ + FAR struct efm32_chan_s *chan; + int inndx; + int outndx; + + outndx = efm32_chan_alloc(priv); + if (outndx < 0) + { + return -ENOMEM; + } + + ctrlep->outndx = outndx; + chan = &priv->chan[outndx]; + chan->epno = epno; + chan->in = false; + chan->eptype = EFM32_USB_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = EFM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control OUT channels */ + + efm32_chan_configure(priv, outndx); + + /* Allocate and initialize the control IN channel */ + + inndx = efm32_chan_alloc(priv); + if (inndx < 0) + { + efm32_chan_free(priv, outndx); + return -ENOMEM; + } + + ctrlep->inndx = inndx; + chan = &priv->chan[inndx]; + chan->epno = epno; + chan->in = true; + chan->eptype = EFM32_USB_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = EFM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control IN channels */ + + efm32_chan_configure(priv, inndx); + return OK; +} + +/**************************************************************************** + * Name: efm32_ctrlep_alloc + * + * Description: + * Allocate a container and channels for control pipe. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_ctrlep_alloc(FAR struct efm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct usbhost_hubport_s *hport; + FAR struct efm32_ctrlinfo_s *ctrlep; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a container for the control endpoint */ + + ctrlep = (FAR struct efm32_ctrlinfo_s *)kmm_malloc(sizeof(struct efm32_ctrlinfo_s)); + if (ctrlep == NULL) + { + udbg("ERROR: Failed to allocate control endpoint container\n"); + return -ENOMEM; + } + + /* Then allocate and configure the IN/OUT channnels */ + + ret = efm32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK, + hport->funcaddr, hport->speed, ctrlep); + if (ret < 0) + { + udbg("ERROR: efm32_ctrlchan_alloc failed: %d\n", ret); + kmm_free(ctrlep); + return ret; + } + + /* Return a pointer to the control pipe container as the pipe "handle" */ + + *ep = (usbhost_ep_t)ctrlep; + return OK; +} + +/************************************************************************************ + * Name: efm32_xfrep_alloc + * + * Description: + * Allocate and configure one unidirectional endpoint. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_xfrep_alloc(FAR struct efm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + FAR struct efm32_chan_s *chan; + int chidx; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a host channel for the endpoint */ + + chidx = efm32_chan_alloc(priv); + if (chidx < 0) + { + udbg("ERROR: Failed to allocate a host channel\n"); + return -ENOMEM; + } + + /* Decode the endpoint descriptor to initialize the channel data structures. + * Note: Here we depend on the fact that the endpoint point type is + * encoded in the same way in the endpoint descriptor as it is in the OTG + * HS hardware. + */ + + chan = &priv->chan[chidx]; + chan->epno = epdesc->addr & USB_EPNO_MASK; + chan->in = epdesc->in; + chan->eptype = epdesc->xfrtype; + chan->funcaddr = hport->funcaddr; + chan->speed = hport->speed; + chan->maxpacket = epdesc->mxpacketsize; + chan->indata1 = false; + chan->outdata1 = false; + + /* Then configure the endpoint */ + + efm32_chan_configure(priv, chidx); + + /* Return the index to the allocated channel as the endpoint "handle" */ + + *ep = (usbhost_ep_t)chidx; + return OK; +} + +/**************************************************************************** + * Name: efm32_transfer_start + * + * Description: + * Start at transfer on the select IN or OUT channel. + * + ****************************************************************************/ + +static void efm32_transfer_start(FAR struct efm32_usbhost_s *priv, int chidx) +{ + FAR struct efm32_chan_s *chan; + uint32_t regval; + unsigned int npackets; + unsigned int maxpacket; + unsigned int avail; + unsigned int wrsize; + unsigned int minsize; + + /* Set up the initial state of the transfer */ + + chan = &priv->chan[chidx]; + + usbhost_vtrace2(USBHOST_VTRACE2_STARTTRANSFER, chidx, chan->buflen); + + chan->result = EBUSY; + chan->inflight = 0; + chan->xfrd = 0; + priv->chidx = chidx; + + /* Compute the expected number of packets associated to the transfer. + * If the transfer length is zero (or less than the size of one maximum + * size packet), then one packet is expected. + */ + + /* If the transfer size is greater than one packet, then calculate the + * number of packets that will be received/sent, including any partial + * final packet. + */ + + maxpacket = chan->maxpacket; + + if (chan->buflen > maxpacket) + { + npackets = (chan->buflen + maxpacket - 1) / maxpacket; + + /* Clip if the buffer length if it exceeds the maximum number of + * packets that can be transferred (this should not happen). + */ + + if (npackets > EFM32_MAX_PKTCOUNT) + { + npackets = EFM32_MAX_PKTCOUNT; + chan->buflen = EFM32_MAX_PKTCOUNT * maxpacket; + usbhost_trace2(USBHOST_TRACE2_CLIP, chidx, chan->buflen); + } + } + else + { + /* One packet will be sent/received (might be a zero length packet) */ + + npackets = 1; + } + + /* If it is an IN transfer, then adjust the size of the buffer UP to + * a full number of packets. Hmmm... couldn't this cause an overrun + * into unallocated memory? + */ + +#if 0 /* Think about this */ + if (chan->in) + { + /* Force the buffer length to an even multiple of maxpacket */ + + chan->buflen = npackets * maxpacket; + } +#endif + + /* Save the number of packets in the transfer. We will need this in + * order to set the next data toggle correctly when the transfer + * completes. + */ + + chan->npackets = (uint8_t)npackets; + + /* Setup the HCn_TSIZ register */ + + regval = ((uint32_t)chan->buflen << _USB_HC_TSIZ_XFERSIZE_SHIFT) | + ((uint32_t)npackets << _USB_HC_TSIZ_PKTCNT_SHIFT) | + ((uint32_t)chan->pid << _USB_HC_TSIZ_PID_SHIFT); + efm32_putreg(EFM32_USB_HCn_TSIZ(chidx), regval); + + /* Setup the HCCHAR register: Frame oddness and host channel enable */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + + /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd + * Frame. This field is applicable for only periodic (isochronous and + * interrupt) channels. + */ + + if ((efm32_getreg(EFM32_USB_HFNUM) & 1) == 0) + { + regval |= USB_HC_CHAR_ODDFRM; + } + else + { + regval &= ~USB_HC_CHAR_ODDFRM; + } + + regval &= ~USB_HC_CHAR_CHDIS; + regval |= USB_HC_CHAR_CHENA; + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), regval); + + /* If this is an out transfer, then we need to do more.. we need to copy + * the outgoing data into the correct TxFIFO. + */ + + if (!chan->in && chan->buflen > 0) + { + /* Handle non-periodic (CTRL and BULK) OUT transfers differently than + * periodic (INTR and ISOC) OUT transfers. + */ + + minsize = MIN(chan->buflen, chan->maxpacket); + + switch (chan->eptype) + { + case EFM32_USB_EPTYPE_CTRL: /* Non periodic transfer */ + case EFM32_USB_EPTYPE_BULK: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = efm32_getreg(EFM32_USB_GNPTXSTS); + avail = ((regval & _USB_GNPTXSTS_NPTXFSPCAVAIL_MASK) >> _USB_GNPTXSTS_NPTXFSPCAVAIL_SHIFT) << 2; + } + break; + + /* Periodic transfer */ + + case EFM32_USB_EPTYPE_INTR: + case EFM32_USB_EPTYPE_ISOC: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = efm32_getreg(EFM32_USB_HPTXSTS); + avail = ((regval & _USB_HPTXSTS_PTXFSPCAVAIL_MASK) >> _USB_HPTXSTS_PTXFSPCAVAIL_SHIFT) << 2; + } + break; + + default: + DEBUGASSERT(false); + return; + } + + /* Is there space in the TxFIFO to hold the minimum size packet? */ + + if (minsize <= avail) + { + /* Yes.. Get the size of the biggest thing that we can put in the Tx FIFO now */ + + wrsize = chan->buflen; + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Write packet into the Tx FIFO. */ + + efm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); + } + + /* Did we put the entire buffer into the Tx FIFO? */ + + if (chan->buflen > avail) + { + /* No, there was insufficient space to hold the entire transfer ... + * Enable the Tx FIFO interrupt to handle the transfer when the Tx + * FIFO becomes empty. + */ + + efm32_txfe_enable(priv, chidx); + } + } +} + +/**************************************************************************** + * Name: efm32_getframe + * + * Description: + * Get the current frame number. The frame number (FRNUM) field increments + * when a new SOF is transmitted on the USB, and is cleared to 0 when it + * reaches 0x3fff. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static inline uint16_t efm32_getframe(void) +{ + return (uint16_t)(efm32_getreg(EFM32_USB_HFNUM) & _USB_HFNUM_FRNUM_MASK); +} +#endif + +/**************************************************************************** + * Name: efm32_ctrl_sendsetup + * + * Description: + * Send an IN/OUT SETUP packet. + * + ****************************************************************************/ + +static int efm32_ctrl_sendsetup(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req) +{ + FAR struct efm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop while the device reports NAK (and a timeout is not exceeded */ + + chan = &priv->chan[ep0->outndx]; + start = clock_systimer(); + + do + { + /* Send the SETUP packet */ + + chan->pid = EFM32_USB_PID_SETUP; + chan->buffer = (FAR uint8_t *)req; + chan->buflen = USB_SIZEOF_CTRLREQ; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = efm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + efm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete */ + + ret = efm32_chan_wait(priv, chan); + + /* Return on success and for all failures other than EAGAIN. EAGAIN + * means that the device NAKed the SETUP command and that we should + * try a few more times. + */ + + if (ret != -EAGAIN) + { + /* Output some debug information if the transfer failed */ + + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_TRNSFRFAILED, ret); + } + + /* Return the result in any event */ + + return ret; + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < EFM32_SETUP_DELAY); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: efm32_ctrl_senddata + * + * Description: + * Send data in the data phase of an OUT control transfer. Or send status + * in the status phase of an IN control transfer + * + ****************************************************************************/ + +static int efm32_ctrl_senddata(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct efm32_chan_s *chan = &priv->chan[ep0->outndx]; + int ret; + + /* Save buffer information */ + + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set the DATA PID */ + + if (buflen == 0) + { + /* For status OUT stage with buflen == 0, set PID DATA1 */ + + chan->outdata1 = true; + } + + /* Set the Data PID as per the outdata1 boolean */ + + chan->pid = chan->outdata1 ? EFM32_USB_PID_DATA1 : EFM32_USB_PID_DATA0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = efm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + efm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete and return the result */ + + return efm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: efm32_ctrl_recvdata + * + * Description: + * Receive data in the data phase of an IN control transfer. Or receive status + * in the status phase of an OUT control transfer + * + ****************************************************************************/ + +static int efm32_ctrl_recvdata(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct efm32_chan_s *chan = &priv->chan[ep0->inndx]; + int ret; + + /* Save buffer information */ + + chan->pid = EFM32_USB_PID_DATA1; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = efm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + efm32_transfer_start(priv, ep0->inndx); + + /* Wait for the transfer to complete and return the result */ + + return efm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: efm32_in_setup + * + * Description: + * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int efm32_in_setup(FAR struct efm32_usbhost_s *priv, int chidx) +{ + FAR struct efm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case EFM32_USB_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case EFM32_USB_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the IN data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_ISOCIN, chidx, chan->buflen); + chan->pid = EFM32_USB_PID_DATA0; + } + break; + + case EFM32_USB_EPTYPE_BULK: /* Bulk */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_BULKIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? EFM32_USB_PID_DATA1 : EFM32_USB_PID_DATA0; + } + break; + + case EFM32_USB_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_INTRIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? EFM32_USB_PID_DATA1 : EFM32_USB_PID_DATA0; + } + break; + } + + /* Start the transfer */ + + efm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: efm32_in_transfer + * + * Description: + * Transfer 'buflen' bytes into 'buffer' from an IN channel. + * + ****************************************************************************/ + +static ssize_t efm32_in_transfer(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct efm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + start = clock_systimer(); + while ((chan->xfrd < chan->buflen > 0) + { + /* Set up for the wait BEFORE starting the transfer */ + + ret = efm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = efm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: efm32_in_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = efm32_chan_wait(priv, chan); + + /* EAGAIN indicates that the device NAKed the transfer and we need + * do try again. Anything else (success or other errors) will + * cause use to return + */ + + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= EFM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: efm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + } + } + + return (ssize_t)chan->xfrd; +} + +/**************************************************************************** + * Name: efm32_in_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void efm32_in_next(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = efm32_in_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: efm32_in_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: efm32_in_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_in_asynch(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct efm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = efm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: efm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = efm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: efm32_in_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: efm32_out_setup + * + * Description: + * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int efm32_out_setup(FAR struct efm32_usbhost_s *priv, int chidx) +{ + FAR struct efm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case EFM32_USB_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case EFM32_USB_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the OUT data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_ISOCOUT, chidx, chan->buflen); + chan->pid = EFM32_USB_PID_DATA0; + } + break; + + case EFM32_USB_EPTYPE_BULK: /* Bulk */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_BULKOUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? EFM32_USB_PID_DATA1 : EFM32_USB_PID_DATA0; + } + break; + + case EFM32_USB_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(USBHOST_VTRACE2_INTROUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? EFM32_USB_PID_DATA1 : EFM32_USB_PID_DATA0; + + /* Toggle the OUT data PID for the next transfer */ + + chan->outdata1 ^= true; + } + break; + } + + /* Start the transfer */ + + efm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: efm32_out_transfer + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' through an OUT channel. + * + ****************************************************************************/ + +static ssize_t efm32_out_transfer(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct efm32_chan_s *chan; + systime_t start; + systime_t elapsed; + size_t xfrlen; + ssize_t xfrd; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + start = clock_systimer(); + xfrd = 0; + + while (buflen > 0) + { + /* Transfer one packet at a time. The hardware is capable of queueing + * multiple OUT packets, but I just haven't figured out how to handle + * the case where a single OUT packet in the group is NAKed. + */ + + xfrlen = MIN(chan->maxpacket, buflen); + chan->buffer = buffer; + chan->buflen = xfrlen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = efm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = efm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: efm32_out_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = efm32_chan_wait(priv, chan); + + /* Handle transfer failures */ + + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= EFM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: efm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Is this flush really necessary? What does the hardware do with the + * data in the FIFO when the NAK occurs? Does it discard it? + */ + + efm32_flush_txfifos(USB_GRSTCTL_TXFNUM_FALL); + + /* Get the device a little time to catch up. Then retry the transfer + * using the same buffer pointer and length. + */ + + usleep(20*1000); + } + else + { + /* Successfully transferred. Update the buffer pointer and length */ + + buffer += xfrlen; + buflen -= xfrlen; + xfrd += chan->xfrd; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: efm32_out_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void efm32_out_next(FAR struct efm32_usbhost_s *priv, + FAR struct efm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = efm32_out_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: efm32_out_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: efm32_out_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_out_asynch(FAR struct efm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct efm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = efm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: efm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = efm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: efm32_out_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: efm32_gint_wrpacket + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with + * 'chidx' (non-DMA). + * + ****************************************************************************/ + +static void efm32_gint_wrpacket(FAR struct efm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen) +{ + FAR uint32_t *src; + uint32_t fifo; + int buflen32; + + efm32_pktdump("Sending", buffer, buflen); + + /* Get the number of 32-byte words associated with this byte size */ + + buflen32 = (buflen + 3) >> 2; + + /* Get the address of the Tx FIFO associated with this channel */ + + fifo = EFM32_USB_FIFO_BASE(chidx); + + /* Transfer all of the data into the Tx FIFO */ + + src = (FAR uint32_t *)buffer; + for (; buflen32 > 0; buflen32--) + { + uint32_t data = *src++; + efm32_putreg(fifo, data); + } + + /* Increment the count of bytes "in-flight" in the Tx FIFO */ + + priv->chan[chidx].inflight += buflen; +} + +/**************************************************************************** + * Name: efm32_gint_hcinisr + * + * Description: + * USB OTG FS host IN channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void efm32_gint_hcinisr(FAR struct efm32_usbhost_s *priv, + int chidx) +{ + FAR struct efm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = efm32_getreg(EFM32_USB_HCn_INT(chidx)); + regval = efm32_getreg(EFM32_USB_HCn_INTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & USB_HC_INT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_ACK); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & USB_HC_INT_STALL) != 0) + { + /* Clear the NAK and STALL Conditions. */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), (USB_HC_INT_NAK | USB_HC_INT_STALL)); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_STALL); + + /* When there is a STALL, clear any pending NAK so that it is not + * processed below. + */ + + pending &= ~USB_HC_INT_NAK; + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if ((pending & USB_HC_INT_DATATGLERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the NAK and data toggle error conditions */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), (USB_HC_INT_NAK | USB_HC_INT_DATATGLERR)); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + if ((pending & USB_HC_INT_FRMOVRUN) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the FRaMe OverRun (FRMOR) condition */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_FRMOVRUN); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & USB_HC_INT_XFERCOMPL) != 0) + { + /* Clear the TransFeR Completed (XFRC) condition */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_XFERCOMPL); + + /* Then handle the transfer completion event based on the endpoint type */ + + if (chan->eptype == EFM32_USB_EPTYPE_CTRL || chan->eptype == EFM32_USB_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear any pending NAK condition. The 'indata1' data toggle + * should have been appropriately updated by the RxFIFO + * logic as each packet was received. + */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_NAK); + } + else if (chan->eptype == EFM32_USB_EPTYPE_INTR) + { + /* Force the next transfer on an ODD frame */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + regval |= USB_HC_CHAR_ODDFRM; + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), regval); + + /* Set the request done state */ + + chan->result = OK; + } + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & USB_HC_INT_CHHLTD) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = efm32_getreg(EFM32_USB_HCn_INTMSK(chidx)); + regval &= ~USB_HC_INT_CHHLTD; + efm32_putreg(EFM32_USB_HCn_INTMSK(chidx), regval); + + /* Update the request state based on the host state machine state */ + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the request I/O error result */ + + chan->result = EIO; + } + else if (chan->chreason == CHREASON_NAK) + { + /* Halt on NAK only happens on an INTR channel. Fetch the HCCHAR register + * and check for an interrupt endpoint. + */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + if ((regval & _USB_HC_CHAR_EPTYPE_MASK) == USB_HC_CHAR_EPTYPE_INT) + { + /* Toggle the IN data toggle (Used by Bulk and INTR only) */ + + chan->indata1 ^= true; + } + + /* Set the NAK error result */ + + chan->result = EAGAIN; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame overrun error result */ + + chan->result = EPIPE; + } + + /* Clear the CHannel Halted (CHH) condition */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_CHHLTD); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & USB_HC_INT_XACTERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the Transaction ERror (TXERR) condition */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_XACTERR); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & USB_HC_INT_NAK) != 0) + { + /* For a BULK transfer, the hardware is capable of retrying + * automatically on a NAK. However, this is not always + * what we need to do. So we always halt the transfer and + * return control to high level logic in the event of a NAK. + */ + +#if 1 + /* Halt the interrupt channel */ + + if (chan->eptype == EFM32_USB_EPTYPE_INTR) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_NAK); + } + + /* Re-activate CTRL and BULK channels. + * REVISIT: This can cause a lot of interrupts! + */ + + else if (chan->eptype == EFM32_USB_EPTYPE_CTRL || + chan->eptype == EFM32_USB_EPTYPE_BULK) + { + /* Re-activate the channel by clearing CHDIS and assuring that + * CHENA is set + */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + regval |= USB_HC_CHAR_CHENA; + regval &= ~USB_HC_CHAR_CHDIS; + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), regval); + } +#else + /* Halt all transfers on the NAK -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_NAK); +#endif + + /* Clear the NAK condition */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_NAK); + } + + /* Check for a transfer complete event */ + + efm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: efm32_gint_hcoutisr + * + * Description: + * USB OTG FS host OUT channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void efm32_gint_hcoutisr(FAR struct efm32_usbhost_s *priv, + int chidx) +{ + FAR struct efm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = efm32_getreg(EFM32_USB_HCn_INT(chidx)); + regval = efm32_getreg(EFM32_USB_HCn_INTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & USB_HC_INT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_ACK); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + else if ((pending & USB_HC_INT_FRMOVRUN) != 0) + { + /* Halt the channel (probably not necessary for FRMOR) */ + + efm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_FRMOVRUN); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & USB_HC_INT_XFERCOMPL) != 0) + { + /* Decrement the number of bytes remaining by the number of + * bytes that were "in-flight". + */ + + priv->chan[chidx].buffer += priv->chan[chidx].inflight; + priv->chan[chidx].xfrd += priv->chan[chidx].inflight; + priv->chan[chidx].inflight = 0; + + /* Halt the channel -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear the pending the TransFeR Completed (XFRC) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_XFERCOMPL); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & USB_HC_INT_STALL) != 0) + { + /* Clear the pending the STALL response receiv (STALL) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_STALL); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_STALL); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & USB_HC_INT_NAK) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + efm32_chan_halt(priv, chidx, CHREASON_NAK); + + /* Clear the pending the NAK response received (NAK) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_NAK); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & USB_HC_INT_XACTERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the pending the Transaction ERror (TXERR) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_XACTERR); + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if (pending & USB_HC_INT_DATATGLERR) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + efm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), (USB_HC_INT_DATATGLERR | USB_HC_INT_NAK)); + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & USB_HC_INT_CHHLTD) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = efm32_getreg(EFM32_USB_HCn_INTMSK(chidx)); + regval &= ~USB_HC_INT_CHHLTD; + efm32_putreg(EFM32_USB_HCn_INTMSK(chidx), regval); + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + + /* Read the HCCHAR register to get the HCCHAR register to get + * the endpoint type. + */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + + /* Is it a bulk endpoint? Were an odd number of packets + * transferred? + */ + + if ((regval & _USB_HC_CHAR_EPTYPE_MASK) == USB_HC_CHAR_EPTYPE_BULK && + (chan->npackets & 1) != 0) + { + /* Yes to both... toggle the data out PID */ + + chan->outdata1 ^= true; + } + } + else if (chan->chreason == CHREASON_NAK || + chan->chreason == CHREASON_NYET) + { + /* Set the try again later result */ + + chan->result = EAGAIN; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the I/O failure result */ + + chan->result = EIO; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame error result */ + + chan->result = EPIPE; + } + + /* Clear the pending the CHannel Halted (CHH) interrupt */ + + efm32_putreg(EFM32_USB_HCn_INT(chidx), USB_HC_INT_CHHLTD); + } + + /* Check for a transfer complete event */ + + efm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: efm32_gint_connected + * + * Description: + * Handle a connection event. + * + ****************************************************************************/ + +static void efm32_gint_connected(FAR struct efm32_usbhost_s *priv) +{ + /* We we previously disconnected? */ + + if (!priv->connected) + { + /* Yes.. then now we are connected */ + + usbhost_vtrace1(USBHOST_VTRACE1_CONNECTED, 0); + priv->connected = true; + priv->change = true; + DEBUGASSERT(priv->smstate == SMSTATE_DETACHED); + + /* Notify any waiters */ + + priv->smstate = SMSTATE_ATTACHED; + if (priv->pscwait) + { + efm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: efm32_gint_disconnected + * + * Description: + * Handle a disconnection event. + * + ****************************************************************************/ + +static void efm32_gint_disconnected(FAR struct efm32_usbhost_s *priv) +{ + /* Were we previously connected? */ + + if (priv->connected) + { + /* Yes.. then we no longer connected */ + + usbhost_vtrace1(USBHOST_VTRACE1_DISCONNECTED, 0); + + /* Are we bound to a class driver? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class driver */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Re-Initialize Host for new Enumeration */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = true; + efm32_chan_freeall(priv); + + priv->rhport.hport.speed = USB_SPEED_FULL; + + /* Notify any waiters that there is a change in the connection state */ + + if (priv->pscwait) + { + efm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: efm32_gint_sofisr + * + * Description: + * USB OTG FS start-of-frame interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_EFM32_OTGFS_SOFINTR +static inline void efm32_gint_sofisr(FAR struct efm32_usbhost_s *priv) +{ + /* Handle SOF interrupt */ +#warning "Do what?" + + /* Clear pending SOF interrupt */ + + efm32_putreg(EFM32_USB_GINTSTS, USB_GINTSTS_SOF); +} +#endif + +/**************************************************************************** + * Name: efm32_gint_rxflvlisr + * + * Description: + * USB OTG FS RxFIFO non-empty interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_rxflvlisr(FAR struct efm32_usbhost_s *priv) +{ + FAR uint32_t *dest; + uint32_t grxsts; + uint32_t intmsk; + uint32_t hcchar; + uint32_t hctsiz; + uint32_t fifo; + int bcnt; + int bcnt32; + int chidx; + int i; + + /* Disable the RxFIFO non-empty interrupt */ + + intmsk = efm32_getreg(EFM32_USB_GINTMSK); + intmsk &= ~USB_GINTMSK_RXFLVLMSK; + efm32_putreg(EFM32_USB_GINTMSK, intmsk); + + /* Read and pop the next status from the Rx FIFO */ + + grxsts = efm32_getreg(EFM32_USB_GRXSTSP); + ullvdbg("GRXSTS: %08x\n", grxsts); + + /* Isolate the channel number/index in the status word */ + + chidx = (grxsts & _USB_GRXSTSP_CHEPNUM_MASK) >> _USB_GRXSTSP_CHEPNUM_SHIFT; + + /* Get the host channel characteristics register (HCCHAR) for this channel */ + + hcchar = efm32_getreg(EFM32_USB_HCn_CHAR(chidx)); + + /* Then process the interrupt according to the packet status */ + + switch (grxsts & _USB_GRXSTSP_PKTSTS_MASK) + { + case USB_GRXSTSP_PKTSTS_PKTRCV: /* IN data packet received */ + { + /* Read the data into the host buffer. */ + + bcnt = (grxsts & _USB_GRXSTSP_BCNT_MASK) >> _USB_GRXSTSP_BCNT_SHIFT; + if (bcnt > 0 && priv->chan[chidx].buffer != NULL) + { + /* Transfer the packet from the Rx FIFO into the user buffer */ + + dest = (FAR uint32_t *)priv->chan[chidx].buffer; + fifo = EFM32_USB_FIFO_BASE(0); + bcnt32 = (bcnt + 3) >> 2; + + for (i = 0; i < bcnt32; i++) + { + *dest++ = efm32_getreg(fifo); + } + + efm32_pktdump("Received", priv->chan[chidx].buffer, bcnt); + + /* Toggle the IN data pid (Used by Bulk and INTR only) */ + + priv->chan[chidx].indata1 ^= true; + + /* Manage multiple packet transfers */ + + priv->chan[chidx].buffer += bcnt; + priv->chan[chidx].xfrd += bcnt; + + /* Check if more packets are expected */ + + hctsiz = efm32_getreg(EFM32_USB_HCn_TSIZ(chidx)); + if ((hctsiz & _USB_HC_TSIZ_PKTCNT_MASK) != 0) + { + /* Re-activate the channel when more packets are expected */ + + hcchar |= USB_HC_CHAR_CHENA; + hcchar &= ~USB_HC_CHAR_CHDIS; + efm32_putreg(EFM32_USB_HCn_CHAR(chidx), hcchar); + } + } + } + break; + + case USB_GRXSTSP_PKTSTS_XFERCOMPL: /* IN transfer completed */ + case USB_GRXSTSP_PKTSTS_TGLERR: /* Data toggle error */ + case USB_GRXSTSP_PKTSTS_CHLT: /* Channel halted */ + default: + break; + } + + /* Re-enable the RxFIFO non-empty interrupt */ + + intmsk |= USB_GINTMSK_RXFLVLMSK; + efm32_putreg(EFM32_USB_GINTMSK, intmsk); +} + +/**************************************************************************** + * Name: efm32_gint_nptxfeisr + * + * Description: + * USB OTG FS non-periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_nptxfeisr(FAR struct efm32_usbhost_s *priv) +{ + FAR struct efm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the NPTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + efm32_modifyreg(EFM32_USB_GINTMSK, USB_GINTMSK_NPTXFEMPMSK, 0); + return; + } + + /* Read the status from the top of the non-periodic TxFIFO */ + + regval = efm32_getreg(EFM32_USB_GNPTXSTS); + + /* Extract the number of bytes available in the non-periodic Tx FIFO. */ + + avail = ((regval & _USB_GNPTXSTS_NPTXFSPCAVAIL_MASK) >> + _USB_GNPTXSTS_NPTXFSPCAVAIL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further NPTXFE interrupts. + */ + + else + { + efm32_modifyreg(EFM32_USB_GINTMSK, USB_GINTMSK_NPTXFEMPMSK, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HNPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + efm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: efm32_gint_ptxfeisr + * + * Description: + * USB OTG FS periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_ptxfeisr(FAR struct efm32_usbhost_s *priv) +{ + FAR struct efm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transfered the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the PTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + efm32_modifyreg(EFM32_USB_GINTMSK, USB_GINTMSK_NPTXFEMPMSK, 0); + return; + } + + /* Read the status from the top of the periodic TxFIFO */ + + regval = efm32_getreg(EFM32_USB_HPTXSTS); + + /* Extract the number of bytes available in the periodic Tx FIFO. */ + + avail = ((regval & _USB_HPTXSTS_PTXFSPCAVAIL_MASK) >> _USB_HPTXSTS_PTXFSPCAVAIL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further PTXFE interrupts. + */ + + else + { + efm32_modifyreg(EFM32_USB_GINTMSK, USB_GINTMSK_NPTXFEMPMSK, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + efm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: efm32_gint_hcisr + * + * Description: + * USB OTG FS host channels interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_hcisr(FAR struct efm32_usbhost_s *priv) +{ + uint32_t haint; + uint32_t hcchar; + int i = 0; + + /* Read the Host all channels interrupt register and test each bit in the + * register. Each bit i, i=0...(EFM32_NHOST_CHANNELS-1), corresponds to + * a pending interrupt on channel i. + */ + + haint = efm32_getreg(EFM32_USB_HAINT); + for (i = 0; i < EFM32_NHOST_CHANNELS; i++) + { + /* Is an interrupt pending on this channel? */ + + if ((haint & USB_HAINT(i)) != 0) + { + /* Yes... read the HCCHAR register to get the direction bit */ + + hcchar = efm32_getreg(EFM32_USB_HCn_CHAR(i)); + + /* Was this an interrupt on an IN or an OUT channel? */ + + if ((hcchar & _USB_HC_CHAR_EPDIR_MASK) != _USB_HC_CHAR_EPDIR_OUT) + { + /* Handle the HC IN channel interrupt */ + + efm32_gint_hcinisr(priv, i); + } + else + { + /* Handle the HC OUT channel interrupt */ + + efm32_gint_hcoutisr(priv, i); + } + } + } +} + +/**************************************************************************** + * Name: efm32_gint_hprtisr + * + * Description: + * USB OTG FS host port interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_hprtisr(FAR struct efm32_usbhost_s *priv) +{ + uint32_t hprt; + uint32_t newhprt; + uint32_t hcfg; + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT, 0); + + /* Read the port status and control register (HPRT) */ + + hprt = efm32_getreg(EFM32_USB_HPRT); + + /* Setup to clear the interrupt bits in GINTSTS by setting the corresponding + * bits in the HPRT. The HCINT interrupt bit is cleared when the appropriate + * status bits in the HPRT register are cleared. + */ + + newhprt = hprt & ~(USB_HPRT_PRTENA | USB_HPRT_PRTCONNDET | USB_HPRT_PRTENCHNG | + USB_HPRT_PRTOVRCURRCHNG); + + /* Check for Port Overcurrent CHaNGe (POCCHNG) */ + + if ((hprt & USB_HPRT_PRTOVRCURRCHNG) != 0) + { + /* Set up to clear the POCCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_POCCHNG, 0); + newhprt |= USB_HPRT_PRTOVRCURRCHNG; + } + + /* Check for Port Connect DETected (PCDET). The core sets this bit when a + * device connection is detected. + */ + + if ((hprt & USB_HPRT_PRTCONNDET) != 0) + { + /* Set up to clear the PCDET status in the new HPRT contents. Then + * process the new connection event. + */ + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_PCDET, 0); + newhprt |= USB_HPRT_PRTCONNDET; + efm32_portreset(priv); + efm32_gint_connected(priv); + } + + /* Check for Port Enable CHaNGed (PENCHNG) */ + + if ((hprt & USB_HPRT_PRTENCHNG) != 0) + { + /* Set up to clear the PENCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_PENCHNG, 0); + newhprt |= USB_HPRT_PRTENCHNG; + + /* Was the port enabled? */ + + if ((hprt & USB_HPRT_PRTENA) != 0) + { + /* Yes.. handle the new connection event */ + + efm32_gint_connected(priv); + + /* Check the Host ConFiGuration register (HCFG) */ + + hcfg = efm32_getreg(EFM32_USB_HCFG); + + /* Is this a low speed or full speed connection (OTG FS does not + * support high speed) + */ + + if ((hprt & _USB_HPRT_PRTSPD_MASK) == USB_HPRT_PRTSPD_LS) + { + /* Set the Host Frame Interval Register for the 6KHz speed */ + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_LSDEV, 0); + efm32_putreg(EFM32_USB_HFIR, 6000); + + /* Are we switching from FS to LS? */ + + if ((hcfg & _USB_HCFG_FSLSPCLKSEL_MASK) != USB_HCFG_FSLSPCLKSEL_DIV8) + { + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_FSLSSW, 0); + /* Yes... configure for LS */ + + hcfg &= ~_USB_HCFG_FSLSPCLKSEL_MASK; + hcfg |= USB_HCFG_FSLSPCLKSEL_DIV8; + efm32_putreg(EFM32_USB_HCFG, hcfg); + + /* And reset the port */ + + efm32_portreset(priv); + } + } + else /* if ((hprt & _USB_HPRT_PRTSPD_MASK) == USB_HPRT_PSPD_FS) */ + { + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_FSDEV, 0); + efm32_putreg(EFM32_USB_HFIR, 48000); + + /* Are we switching from LS to FS? */ + + if ((hcfg & _USB_HCFG_FSLSPCLKSEL_MASK) != USB_HCFG_FSLSPCLKSEL_DIV1) + { + + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HPRT_LSFSSW, 0); + /* Yes... configure for FS */ + + hcfg &= ~_USB_HCFG_FSLSPCLKSEL_MASK; + hcfg |= USB_HCFG_FSLSPCLKSEL_DIV1; + efm32_putreg(EFM32_USB_HCFG, hcfg); + + /* And reset the port */ + + efm32_portreset(priv); + } + } + } + } + + /* Clear port interrupts by setting bits in the HPRT */ + + efm32_putreg(EFM32_USB_HPRT, newhprt); +} + +/**************************************************************************** + * Name: efm32_gint_discisr + * + * Description: + * USB OTG FS disconnect detected interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_discisr(FAR struct efm32_usbhost_s *priv) +{ + /* Handle the disconnection event */ + + efm32_gint_disconnected(priv); + + /* Clear the dicsonnect interrupt */ + + efm32_putreg(EFM32_USB_GINTSTS, USB_GINTSTS_DISCONNINT); +} + +/**************************************************************************** + * Name: efm32_gint_ipxfrisr + * + * Description: + * USB OTG FS incomplete periodic interrupt handler + * + ****************************************************************************/ + +static inline void efm32_gint_ipxfrisr(FAR struct efm32_usbhost_s *priv) +{ + uint32_t regval; + + /* CHENA : Set to enable the channel + * CHDIS : Set to stop transmitting/receiving data on a channel + */ + + regval = efm32_getreg(EFM32_USB_HCn_CHAR(0)); + regval |= (USB_HC_CHAR_CHDIS | USB_HC_CHAR_CHENA); + efm32_putreg(EFM32_USB_HCn_CHAR(0), regval); + + /* Clear the incomplete isochronous OUT interrupt */ + + efm32_putreg(EFM32_USB_GINTSTS, USB_GINTSTS_INCOMPLP); +} + +/**************************************************************************** + * Name: efm32_gint_isr + * + * Description: + * USB OTG FS global interrupt handler + * + ****************************************************************************/ + +static int efm32_gint_isr(int irq, FAR void *context) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbhost_s *priv = &g_usbhost; + uint32_t pending; + + /* If OTG were supported, we would need to check if we are in host or + * device mode when the global interrupt occurs. Here we support only + * host mode + */ + + /* Loop while there are pending interrupts to process. This loop may save a + * little interrupt handling overhead. + */ + + for (; ; ) + { + /* Get the unmasked bits in the GINT status */ + + pending = efm32_getreg(EFM32_USB_GINTSTS); + pending &= efm32_getreg(EFM32_USB_GINTMSK); + + /* Return from the interrupt when there are no further pending + * interrupts. + */ + + if (pending == 0) + { + return OK; + } + + /* Otherwise, process each pending, unmasked GINT interrupts */ + + /* Handle the start of frame interrupt */ + +#ifdef CONFIG_EFM32_OTGFS_SOFINTR + if ((pending & USB_GINTSTS_SOF) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_SOF, 0); + efm32_gint_sofisr(priv); + } +#endif + + /* Handle the RxFIFO non-empty interrupt */ + + if ((pending & USB_GINTSTS_RXFLVL) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_RXFLVL, 0); + efm32_gint_rxflvlisr(priv); + } + + /* Handle the non-periodic TxFIFO empty interrupt */ + + if ((pending & USB_GINTSTS_NPTXFEMP) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_NPTXFE, 0); + efm32_gint_nptxfeisr(priv); + } + + /* Handle the periodic TxFIFO empty interrupt */ + + if ((pending & USB_GINTSTS_PTXFEMP) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_PTXFE, 0); + efm32_gint_ptxfeisr(priv); + } + + /* Handle the host channels interrupt */ + + if ((pending & USB_GINTSTS_HCHINT) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_HC, 0); + efm32_gint_hcisr(priv); + } + + /* Handle the host port interrupt */ + + if ((pending & USB_GINTSTS_PRTINT) != 0) + { + efm32_gint_hprtisr(priv); + } + + /* Handle the disconnect detected interrupt */ + + if ((pending & USB_GINTSTS_DISCONNINT) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_DISC, 0); + efm32_gint_discisr(priv); + } + + /* Handle the incomplete periodic transfer */ + + if ((pending & USB_GINTSTS_INCOMPLP) != 0) + { + usbhost_vtrace1(USBHOST_VTRACE1_GINT_IPXFR, 0); + efm32_gint_ipxfrisr(priv); + } + } + + /* We won't get here */ + + return OK; +} + +/**************************************************************************** + * Name: efm32_gint_enable and efm32_gint_disable + * + * Description: + * Respectively enable or disable the global OTG FS interrupt. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void efm32_gint_enable(void) +{ + uint32_t regval; + + /* Set the GINTMSK bit to unmask the interrupt */ + + regval = efm32_getreg(EFM32_USB_GAHBCFG); + regval |= USB_GAHBCFG_GLBLINTRMSK; + efm32_putreg(EFM32_USB_GAHBCFG, regval); +} + +static void efm32_gint_disable(void) +{ + uint32_t regval; + + /* Clear the GINTMSK bit to mask the interrupt */ + + regval = efm32_getreg(EFM32_USB_GAHBCFG); + regval &= ~USB_GAHBCFG_GLBLINTRMSK; + efm32_putreg(EFM32_USB_GAHBCFG, regval); +} + +/**************************************************************************** + * Name: efm32_hostinit_enable + * + * Description: + * Enable host interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void efm32_hostinit_enable(void) +{ + uint32_t regval; + + /* Disable all interrupts. */ + + efm32_putreg(EFM32_USB_GINTMSK, 0); + + /* Clear any pending interrupts. */ + + efm32_putreg(EFM32_USB_GINTSTS, 0xffffffff); + + /* Clear any pending USB OTG Interrupts (should be done elsewhere if OTG is supported) */ + + efm32_putreg(EFM32_USB_GOTGINT, 0xffffffff); + + /* Clear any pending USB OTG interrupts */ + + efm32_putreg(EFM32_USB_GINTSTS, 0xbfffffff); + + /* Enable the host interrupts */ + /* Common interrupts: + * + * USB_GINTMSK_WKUPINTMSK : Resume/remote wakeup detected interrupt + * USB_GINTMSK_USBSUSPMSK : USB suspend + */ + + regval = (USB_GINTMSK_WKUPINTMSK | USB_GINTMSK_USBSUSPMSK); + + /* If OTG were supported, we would need to enable the following as well: + * + * USB_GINTMSK_OTGINTMSK : OTG interrupt + * USB_GINTMSK_SESSREQINTMSK : Session request/new session detected interrupt + * USB_GINTMSK_CONIDSTSCHNGMSK : Connector ID status change + */ + + /* Host-specific interrupts + * + * USB_GINTMSK_SOFMSK : Start of frame + * USB_GINTMSK_RXFLVLMSK : RxFIFO non-empty + * USB_GINTMSK_INCOMPLPMSK : Incomplete isochronous OUT transfer + * USB_GINTMSK_PRTINTMSK : Host port interrupt + * USB_GINTMSK_HCHINTMSK : Host channels interrupt + * USB_GINTMSK_DISCONNINTMSK : Disconnect detected interrupt + */ + +#ifdef CONFIG_EFM32_OTGFS_SOFINTR + regval |= (USB_GINTMSK_SOFMSK | USB_GINTMSK_RXFLVLMSK | + USB_GINTMSK_INCOMPLPMSK | USB_GINTMSK_PRTINTMSK | + USB_GINTMSK_HCHINTMSK | USB_GINTMSK_DISCONNINTMSK); +#else + regval |= (USB_GINTMSK_RXFLVLMSK | USB_GINTMSK_INCOMPLPMSK | + USB_GINTMSK_PRTINTMSK | USB_GINTMSK_HCHINTMSK | + USB_GINTMSK_DISCONNINTMSK); +#endif + efm32_putreg(EFM32_USB_GINTMSK, regval); +} + +/**************************************************************************** + * Name: efm32_txfe_enable + * + * Description: + * Enable Tx FIFO empty interrupts. This is necessary when the entire + * transfer will not fit into Tx FIFO. The transfer will then be completed + * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled + * the fifo empty interrupt handler when the transfer is complete. + * + * Input Parameters: + * priv - Driver state structure reference + * chidx - The channel that requires the Tx FIFO empty interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Called from user task context. Interrupts must be disabled to assure + * exclusive access to the GINTMSK register. + * + ****************************************************************************/ + +static void efm32_txfe_enable(FAR struct efm32_usbhost_s *priv, int chidx) +{ + FAR struct efm32_chan_s *chan = &priv->chan[chidx]; + irqstate_t flags; + uint32_t regval; + + /* Disable all interrupts so that we have exclusive access to the GINTMSK + * (it would be sufficent just to disable the GINT interrupt). + */ + + flags = enter_critical_section(); + + /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */ + + regval = efm32_getreg(EFM32_USB_GINTMSK); + switch (chan->eptype) + { + default: + case EFM32_USB_EPTYPE_CTRL: /* Non periodic transfer */ + case EFM32_USB_EPTYPE_BULK: + regval |= USB_GINTMSK_NPTXFEMPMSK; + break; + + case EFM32_USB_EPTYPE_INTR: /* Periodic transfer */ + case EFM32_USB_EPTYPE_ISOC: + regval |= USB_GINTMSK_PTXFEMPMSK; + break; + } + + /* Enable interrupts */ + + efm32_putreg(EFM32_USB_GINTMSK, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + FAR struct efm32_usbhost_s *priv = &g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + + /* Loop until a change in connection state is detected */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + + /* Yes. Remember the new state */ + + connport->connected = priv->connected; + priv->change = false; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + uvdbg("RHport Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + uvdbg("Hub port Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + efm32_takesem(&priv->pscsem); + } +} + +/**************************************************************************** + * Name: efm32_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_rh_enumerate(FAR struct efm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + uint32_t regval; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + usbhost_trace1(USBHOST_TRACE1_DEVDISCONN, 0); + return -ENODEV; + } + + DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED); + + /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */ + + usleep(100*1000); + + /* Reset the host port */ + + efm32_portreset(priv); + + /* Get the current device speed */ + + regval = efm32_getreg(EFM32_USB_HPRT); + if ((regval & _USB_HPRT_PRTSPD_MASK) == USB_HPRT_PRTSPD_LS) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + /* Allocate and initialize the root hub port EP0 channels */ + + ret = efm32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, &priv->ep0); + if (ret < 0) + { + udbg("ERROR: Failed to allocate a control endpoint: %d\n", ret); + } + + return ret; +} + +static int efm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + FAR struct efm32_usbhost_s *priv = &g_usbhost; + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = efm32_rh_enumerate(priv, conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uvdbg("Enumerate the device\n"); + priv->smstate = SMSTATE_ENUM; + ret = usbhost_enumerate(hport, &hport->devclass); + + /* The enumeration may fail either because of some HCD interfaces failure + * or because the device class is not supported. In either case, we just + * need to perform the disconnection operation and make ready for a new + * enumeration. + */ + + if (ret < 0) + { + /* Return to the disconnected state */ + + udbg("ERROR: Enumeration failed: %d\n", ret); + efm32_gint_disconnected(priv); + } + + return ret; +} + +/************************************************************************************ + * Name: efm32_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support an + * external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + FAR struct efm32_ctrlinfo_s *ep0info = (FAR struct efm32_ctrlinfo_s *)ep0; + FAR struct efm32_chan_s *chan; + + DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 && + maxpacketsize <= 64); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Configure the EP0 OUT channel */ + + chan = &priv->chan[ep0info->outndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + efm32_chan_configure(priv, ep0info->outndx); + + /* Configure the EP0 IN channel */ + + chan = &priv->chan[ep0info->inndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + efm32_chan_configure(priv, ep0info->inndx); + + efm32_givesem(&priv->exclsem); + return OK; +} + +/************************************************************************************ + * Name: efm32_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Handler control pipes differently from other endpoint types. This is + * because the normal, "transfer" endpoints are unidirectional an require + * only a single channel. Control endpoints, however, are bi-diretional + * and require two channels, one for the IN and one for the OUT direction. + */ + + if (epdesc->xfrtype == EFM32_USB_EPTYPE_CTRL) + { + ret = efm32_ctrlep_alloc(priv, epdesc, ep); + } + else + { + ret = efm32_xfrep_alloc(priv, epdesc, ep); + } + + efm32_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: efm32_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpoint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + + DEBUGASSERT(priv); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* A single channel is represent by an index in the range of 0 to EFM32_MAX_TX_FIFOS. + * Otherwise, the ep must be a pointer to an allocated control endpoint structure. + */ + + if ((uintptr_t)ep < EFM32_MAX_TX_FIFOS) + { + /* Halt the channel and mark the channel available */ + + efm32_chan_free(priv, (int)ep); + } + else + { + /* Halt both control channel and mark the channels available */ + + FAR struct efm32_ctrlinfo_s *ctrlep = (FAR struct efm32_ctrlinfo_s *)ep; + efm32_chan_free(priv, ctrlep->inndx); + efm32_chan_free(priv, ctrlep->outndx); + + /* And free the control endpoint container */ + + kmm_free(ctrlep); + } + + efm32_givesem(&priv->exclsem); + return OK; +} + +/**************************************************************************** + * Name: efm32_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special memory requirement for the EFM32. */ + + alloc = (FAR uint8_t *)kmm_malloc(CONFIG_EFM32_OTGFS_DESCSIZE); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated address and size of the descriptor buffer */ + + *buffer = alloc; + *maxlen = CONFIG_EFM32_OTGFS_DESCSIZE; + return OK; +} + +/**************************************************************************** + * Name: efm32_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to free that + * request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: efm32_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* There is no special memory requirement */ + + alloc = (FAR uint8_t *)kmm_malloc(buflen); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated buffer */ + + *buffer = alloc; + return OK; +} + +/************************************************************************************ + * Name: efm32_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int efm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: efm32_ctrlin and efm32_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int efm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + FAR struct efm32_ctrlinfo_s *ep0info = (FAR struct efm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(USBHOST_VTRACE2_CTRLIN, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = efm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < EFM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = efm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the IN data phase (if any) */ + + if (buflen > 0) + { + ret = efm32_ctrl_recvdata(priv, ep0info, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_RECVDATA, -ret); + } + } + + /* Handle the status OUT phase */ + + if (ret == OK) + { + priv->chan[ep0info->outndx].outdata1 ^= true; + ret = efm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactions exit here */ + + efm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(USBHOST_TRACE1_SENDDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < EFM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + efm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +static int efm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + FAR struct efm32_ctrlinfo_s *ep0info = (FAR struct efm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(USBHOST_VTRACE2_CTRLOUT, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = efm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < EFM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = efm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the data OUT phase (if any) */ + + if (buflen > 0) + { + /* Start DATA out transfer (only one DATA packet) */ + + priv->chan[ep0info->outndx].outdata1 = true; + ret = efm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret < 0) + { + usbhost_trace1(USBHOST_TRACE1_SENDDATA, -ret); + } + } + + /* Handle the status IN phase */ + + if (ret == OK) + { + ret = efm32_ctrl_recvdata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactins exit here */ + + efm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(USBHOST_TRACE1_RECVDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < EFM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + efm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: efm32_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t efm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + ssize_t nbytes; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < EFM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + nbytes = efm32_in_transfer(priv, chidx, buffer, buflen); + } + else + { + nbytes = efm32_out_transfer(priv, chidx, buffer, buflen); + } + + efm32_givesem(&priv->exclsem); + return nbytes; +} + +/**************************************************************************** + * Name: efm32_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int efm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + int ret; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < EFM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + efm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + ret = efm32_in_asynch(priv, chidx, buffer, buflen, callback, arg); + } + else + { + ret = efm32_out_asynch(priv, chidx, buffer, buflen, callback, arg); + } + + efm32_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: efm32_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int efm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + FAR struct efm32_chan_s *chan; + unsigned int chidx = (unsigned int)ep; + irqstate_t flags; + + uvdbg("chidx: %u: %d\n", chidx); + + DEBUGASSERT(priv && chidx < EFM32_MAX_TX_FIFOS); + chan = &priv->chan[chidx]; + + /* We need to disable interrupts to avoid race conditions with the asynchronous + * completion of the transfer being cancelled. + */ + + flags = enter_critical_section(); + + /* Halt the channel */ + + efm32_chan_halt(priv, chidx, CHREASON_CANCELLED); + chan->result = -ESHUTDOWN; + + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + + /* Wake'em up! */ + + efm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + usbhost_asynch_t callback; + FAR void *arg; + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + callback(arg, -ESHUTDOWN); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: efm32_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int efm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + FAR struct efm32_usbhost_s *priv = (FAR struct efm32_usbhost_s *)drvr; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && hport != NULL); + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + efm32_givesem(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: efm32_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void efm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: efm32_portreset + * + * Description: + * Reset the USB host port. + * + * NOTE: "Before starting to drive a USB reset, the application waits for the + * OTG interrupt triggered by the debounce done bit (DBCDNE bit in + * OTG_FS_GOTGINT), which indicates that the bus is stable again after the + * electrical debounce caused by the attachment of a pull-up resistor on DP + * (FS) or DM (LS). + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void efm32_portreset(FAR struct efm32_usbhost_s *priv) +{ + uint32_t regval; + + regval = efm32_getreg(EFM32_USB_HPRT); + regval &= ~(USB_HPRT_PRTENA | USB_HPRT_PRTCONNDET | USB_HPRT_PRTENCHNG | + USB_HPRT_PRTOVRCURRCHNG); + regval |= USB_HPRT_PRTRST; + efm32_putreg(EFM32_USB_HPRT, regval); + + up_mdelay(20); + + regval &= ~USB_HPRT_PRTRST; + efm32_putreg(EFM32_USB_HPRT, regval); + + up_mdelay(20); +} + +/**************************************************************************** + * Name: efm32_flush_txfifos + * + * Description: + * Flush the selected Tx FIFO. + * + * Input Parameters: + * txfnum -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void efm32_flush_txfifos(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = USB_GRSTCTL_TXFFLSH | txfnum; + efm32_putreg(regval, EFM32_USB_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < EFM32_FLUSH_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: efm32_flush_rxfifo + * + * Description: + * Flush the Rx FIFO. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void efm32_flush_rxfifo(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + efm32_putreg(USB_GRSTCTL_RXFFLSH, EFM32_USB_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < EFM32_FLUSH_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: efm32_vbusdrive + * + * Description: + * Drive the Vbus +5V. + * + * Input Parameters: + * priv - USB host driver private data structure. + * state - True: Drive, False: Don't drive + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void efm32_vbusdrive(FAR struct efm32_usbhost_s *priv, bool state) +{ + uint32_t regval; + + /* Enable/disable the external charge pump */ + + efm32_usbhost_vbusdrive(0, state); + + /* Turn on the Host port power. */ + + regval = efm32_getreg(EFM32_USB_HPRT); + regval &= ~(USB_HPRT_PRTENA | USB_HPRT_PRTCONNDET | USB_HPRT_PRTENCHNG | + USB_HPRT_PRTOVRCURRCHNG); + + if (((regval & USB_HPRT_PRTPWR) == 0) && state) + { + regval |= USB_HPRT_PRTPWR; + efm32_putreg(EFM32_USB_HPRT, regval); + } + + if (((regval & USB_HPRT_PRTPWR) != 0) && !state) + { + regval &= ~USB_HPRT_PRTPWR; + efm32_putreg(EFM32_USB_HPRT, regval); + } + + up_mdelay(200); +} + +/**************************************************************************** + * Name: efm32_host_initialize + * + * Description: + * Initialize/re-initialize hardware for host mode operation. At present, + * this function is called only from efm32_hw_initialize(). But if OTG mode + * were supported, this function would also be called to swtich between + * host and device modes on a connector ID change interrupt. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void efm32_host_initialize(FAR struct efm32_usbhost_s *priv) +{ + uint32_t regval; + uint32_t offset; + int i; + + /* Restart the PHY Clock */ + + efm32_putreg(EFM32_USB_PCGCCTL, 0); + + /* Initialize Host Configuration (HCFG) register */ + + regval = efm32_getreg(EFM32_USB_HCFG); + regval &= ~_USB_HCFG_FSLSPCLKSEL_MASK; + regval |= USB_HCFG_FSLSPCLKSEL_DIV1; + efm32_putreg(EFM32_USB_HCFG, regval); + + /* Reset the host port */ + + efm32_portreset(priv); + + /* Clear the FS-/LS-only support bit in the HCFG register */ + + regval = efm32_getreg(EFM32_USB_HCFG); + regval &= ~USB_HCFG_FSLSSUPP; + efm32_putreg(EFM32_USB_HCFG, regval); + + /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */ + /* Configure Rx FIFO size (GRXFSIZ) */ + + efm32_putreg(EFM32_USB_GRXFSIZ, CONFIG_EFM32_OTGFS_RXFIFO_SIZE); + offset = CONFIG_EFM32_OTGFS_RXFIFO_SIZE; + + /* Setup the host non-periodic Tx FIFO size (GNPTXFSIZ) */ + + regval = (offset | (CONFIG_EFM32_OTGFS_NPTXFIFO_SIZE << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT)); + efm32_putreg(EFM32_USB_GNPTXFSIZ, regval); + offset += CONFIG_EFM32_OTGFS_NPTXFIFO_SIZE; + + /* Set up the host periodic Tx FIFO size register (HPTXFSIZ) */ + + regval = (offset | (CONFIG_EFM32_OTGFS_PTXFIFO_SIZE << _USB_HPTXFSIZ_PTXFSIZE_SHIFT)); + efm32_putreg(EFM32_USB_HPTXFSIZ, regval); + + /* If OTG were supported, we would need to clear HNP enable bit in the + * USB_OTG control register about here. + */ + + /* Flush all FIFOs */ + + efm32_flush_txfifos(USB_GRSTCTL_TXFNUM_FALL); + efm32_flush_rxfifo(); + + /* Clear all pending HC Interrupts */ + + for (i = 0; i < EFM32_NHOST_CHANNELS; i++) + { + efm32_putreg(EFM32_USB_HCn_INT(i), 0xffffffff); + efm32_putreg(EFM32_USB_HCn_INTMSK(i), 0); + } + + /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + efm32_vbusdrive(priv, true); + + /* Enable host interrupts */ + + efm32_hostinit_enable(); +} + +/**************************************************************************** + * Name: efm32_sw_initialize + * + * Description: + * One-time setup of the host driver state structure. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void efm32_sw_initialize(FAR struct efm32_usbhost_s *priv) +{ + FAR struct usbhost_driver_s *drvr; + FAR struct usbhost_hubport_s *hport; + int i; + + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = efm32_ep0configure; + drvr->epalloc = efm32_epalloc; + drvr->epfree = efm32_epfree; + drvr->alloc = efm32_alloc; + drvr->free = efm32_free; + drvr->ioalloc = efm32_ioalloc; + drvr->iofree = efm32_iofree; + drvr->ctrlin = efm32_ctrlin; + drvr->ctrlout = efm32_ctrlout; + drvr->transfer = efm32_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = efm32_asynch; +#endif + drvr->cancel = efm32_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = efm32_connect; +#endif + drvr->disconnect = efm32_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = (usbhost_ep_t)&priv->ep0; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->rhport); + + /* Initialize semaphores */ + + sem_init(&priv->pscsem, 0, 0); + sem_init(&priv->exclsem, 0, 1); + + /* Initialize the driver state data */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = false; + + /* Put all of the channels back in their initial, allocated state */ + + memset(priv->chan, 0, EFM32_MAX_TX_FIFOS * sizeof(struct efm32_chan_s)); + + /* Initialize each channel */ + + for (i = 0; i < EFM32_MAX_TX_FIFOS; i++) + { + FAR struct efm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + sem_init(&chan->waitsem, 0, 0); + } +} + +/**************************************************************************** + * Name: efm32_hw_initialize + * + * Description: + * One-time setup of the host controller harware for normal operations. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline int efm32_hw_initialize(FAR struct efm32_usbhost_s *priv) +{ + uint32_t regval; + unsigned long timeout; + + /* "To initialize the core as host, the application must perform the + * following steps. + * 1. Program USB_GINTMSK.PRTINT to unmask. + * 2. Program the USB_HCFG register to select full-speed host. + * 3. Program the USB_HPRT.PRTPWR bit to 1. This drives VBUS on the USB. + * 4. Wait for the USB_HPRT.PRTCONNDET interrupt. This indicates that a + * device is connect to the port. + * 5. Program the USB_HPRT.PRTRST bit to 1. This starts the reset process. + * 6. Wait at least 10 ms for the reset process to complete. + * 7. Program the USB_HPRT.PRTRST bit to 0. + * 8. Wait for the USB_HPRT.PRTENCHNG interrupt. + * 9. Read the USB_HPRT.PRTSPD field to get the enumerated speed. + * 10. Program the USB_HFIR register with a value corresponding to the + * selected PHY clock. At this point, the host is up and running and + * the port register begins to report device disconnects, etc. The + * port is active with SOFs occurring down the enabled port. + * 11. Program the RXFSIZE register to select the size of the receive FIFO. + * 12. Program the NPTXFSIZE register to select the size and the start + * address of the Non-periodic Transmit FIFO for non-periodic + * transactions. + * 13. Program the USB_HPTXFSIZ register to select the size and start + * address of the Periodic Transmit FIFO for periodic transactions." + */ +#warning Review for missing logic + + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < EFM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_AHBIDLE) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + efm32_putreg(EFM32_USB_GRSTCTL, USB_GRSTCTL_CSFTRST); + for (timeout = 0; timeout < EFM32_READY_DELAY; timeout++) + { + regval = efm32_getreg(EFM32_USB_GRSTCTL); + if ((regval & USB_GRSTCTL_CSFTRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + * bits would need to be set in the GUSBCFG register about here. + */ + + /* Force Host Mode */ + + regval = efm32_getreg(EFM32_USB_GUSBCFG); + regval &= ~_USB_GUSBCFG_FORCEDEVMODE_MASK; + regval |= USB_GUSBCFG_FORCEHSTMODE; + efm32_putreg(EFM32_USB_GUSBCFG, regval); + up_mdelay(50); + + /* Initialize host mode and return success */ + + efm32_host_initialize(priv); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_usbhost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *efm32_usbhost_initialize(int controller) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct efm32_usbhost_s *priv = &g_usbhost; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + + /* "The USB requires the device to run from a 48 MHz crystal (2500 ppm or + * better). The core part of the USB will always run from HFCORECLKUSBC + * which is HFCLK undivided (48 MHz). The current consumption for the + * rest of the device can be reduced by dividing down HFCORECLK using + * the CMU_HFCORECLKDIV register. ..." + * + * "Follow these steps to enable the USB: + * 1. Enable the clock to the system part by setting USB in + * CMU_HFCORECLKEN0. + * 2. If the internal USB regulator is bypassed (by applying 3.3V on + * USB_VREGI and USB_VREGO externally), disable the regulator by + * setting VREGDIS in USB_CTRL. + * 3. If the PHY is powered from VBUS using the internal regulator, the + * VREGO sense circuit should be enabled by setting VREGOSEN in + * USB_CTRL. + * 4. Enable the USB PHY pins by setting PHYPEN in USB_ROUTE. + * 5. If host or OTG dual-role device, set VBUSENAP in USB_CTRL to the + * desired value and then enable the USB_VBUSEN pin in USB_ROUTE. Set + * the MODE for the pin to PUSHPULL. + * 6. If low-speed device, set DMPUAP in USB_CTRL to the desired value + * and then enable the USB_DMPU pin in USB_ROUTE. Set the MODE for the + * pin to PUSHPULL. + * 7. Make sure HFXO is ready and selected. The core part requires the + * undivided HFCLK to be 48 MHz when USB is active (during + * suspend/session-off a 32 kHz clock is used).. + * 8. Enable the clock to the core part by setting USBC in + * CMU_HFCORECLKEN0. + * 9. Wait for the core to come out of reset. This is easiest done by + * polling a core register with non-zero reset value until it reads a + * non-zero value. This takes approximately 20 48-MHz cycles. + * 10. Start initializing the USB core ..." + */ +#warning Missing Logic + + /* Make sure that interrupts from the OTG FS core are disabled */ + + efm32_gint_disable(); + + /* Reset the state of the host driver */ + + efm32_sw_initialize(priv); + + /* Initialize the USB OTG FS core */ + + efm32_hw_initialize(priv); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(EFM32_IRQ_USB, efm32_gint_isr) != 0) + { + usbhost_trace1(USBHOST_TRACE1_IRQATTACH, 0); + return NULL; + } + + /* Enable USB OTG FS global interrupts */ + + efm32_gint_enable(); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(EFM32_IRQ_USB); + return &g_usbconn; +} + +#endif /* CONFIG_USBHOST && CONFIG_EFM32_OTGFS */ diff --git a/arch/arm/src/efm32/efm32_vectors.S b/arch/arm/src/efm32/efm32_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..488c8581e01806f2b6941e31d6d04adebd3bce5c --- /dev/null +++ b/arch/arm/src/efm32/efm32_vectors.S @@ -0,0 +1,116 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_vectors.S + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "exc_return.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the + * MSP to the stack pointer of the interrupted thread. If the interrupted thread + * was a privileged thread, that will be the MSP otherwise it will be the PSP. If + * the PSP is used, then the value of the MSP will be invalid when the interrupt + * handler returns because it will be a pointer to an old position in the + * unprivileged stack. Then when the high priority interrupt occurs and uses this + * stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt + * handler will always set the the MSP to the interrupt stack. So when the high + * priority interrupt occurs, it will either use the MSP of the last privileged + * thread to run or, in the case of the nested interrupt, the interrupt stack if + * no privileged task has run. + */ + +# if defined(CONFIG_NUTTX_KERNEL) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "efm32_vectors.S" + +/* The EFM32 chips all use the common ARMv7 interrupt vectoring. + * (see arch/arm/src/armv7-m/up_vectors.S) + */ + +/************************************************************************************ + * .rodata + ************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/imx1/Kconfig b/arch/arm/src/imx1/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..e138090e457be5297dd4b9f87eca67762a3ba54d --- /dev/null +++ b/arch/arm/src/imx1/Kconfig @@ -0,0 +1,45 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_IMX1 + +# choice "iMX.1 Chip Selection" + +menu "iMX.1 Peripheral Selection" + +config IMX1_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + +config IMX1_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + +config IMX1_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + +config IMX1_SPI1 + bool "SPI1" + default n + select SPI + +config IMX1_SPI2 + bool "SPI2" + default n + select SPI + +endmenu # iMX Peripheral Selection + +config RAM_NUTTXENTRY + hex "NuttX entry point" + default 0x01004000 + ---help--- + The virtual address of the NuttX entry point + +endif # ARCH_CHIP_IMX1 diff --git a/arch/arm/src/imx1/Make.defs b/arch/arm/src/imx1/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..40999a4e5fcf4b78c07534427973c8f5f6304797 --- /dev/null +++ b/arch/arm/src/imx1/Make.defs @@ -0,0 +1,68 @@ +############################################################################ +# arch/arm/src/imx1/Make.defs +# +# Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = up_head.S + +CMN_ASRCS = up_cache.S up_fullcontextrestore.S up_saveusercontext.S +CMN_ASRCS += up_vectors.S up_vectoraddrexcptn.S up_vectortab.S vfork.S +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_prefetchabort.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = imx_lowputc.S +CHIP_CSRCS = imx_boot.c imx_gpio.c imx_allocateheap.c imx_irq.c +CHIP_CSRCS += imx_serial.c imx_decodeirq.c imx_spi.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += imx_timerisr.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += imx_usbdev.c +endif diff --git a/arch/arm/src/imx1/chip.h b/arch/arm/src/imx1/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..24d8f05a9aa58759fb33e1a287b4a9af9d696d18 --- /dev/null +++ b/arch/arm/src/imx1/chip.h @@ -0,0 +1,65 @@ +/************************************************************************************ + * arch/arm/src/imx1/chip.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_CHIP_H +#define __ARCH_ARM_IMX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "imx_memorymap.h" +#include "imx_system.h" +#include "imx_wdog.h" +#include "imx_timer.h" +#include "imx_rtc.h" +#include "imx_uart.h" +#include "imx_dma.h" +#include "imx_usbd.h" +#include "imx_i2c.h" +#include "imx_cspi.h" +#include "imx_gpio.h" +#include "imx_eim.h" +#include "imx_aitc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_CHIP_H */ diff --git a/arch/arm/src/imx1/imx_aitc.h b/arch/arm/src/imx1/imx_aitc.h new file mode 100644 index 0000000000000000000000000000000000000000..5a72ed2a32a7262cd34c1226670ed090c13074fa --- /dev/null +++ b/arch/arm/src/imx1/imx_aitc.h @@ -0,0 +1,119 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_aitc.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_AITC_H +#define __ARCH_ARM_IMX_AITC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* AITC Register Offsets ************************************************************/ + +#define AITC_INTCNTL_OFFSET 0x0000 /* Interrupt Control Register */ +#define AITC_NIMASK_OFFSET 0x0004 /* Normal Interrupt Mask Register */ +#define AITC_INTENNUM_OFFSET 0x0008 /* Interrupt Enable Number Register */ +#define AITC_INTDISNUM_OFFSET 0x000c /* Interrupt Disable Number Register */ +#define AITC_INTENABLEH_OFFSET 0x0010 /* Interrupt Enable Register High */ +#define AITC_INTENABLEL_OFFSET 0x0014 /* Interrupt Enable Register Low */ +#define AITC_INTTYPEH_OFFSET 0x0018 +#define AITC_INTTYPEL_OFFSET 0x001c +#define AITC_NIPRIORITY7_OFFSET 0x0020 +#define AITC_NIPRIORITY6_OFFSET 0x0024 +#define AITC_NIPRIORITY5_OFFSET 0x0028 +#define AITC_NIPRIORITY4_OFFSET 0x002c +#define AITC_NIPRIORITY3_OFFSET 0x0030 +#define AITC_NIPRIORITY2_OFFSET 0x0034 +#define AITC_NIPRIORITY1_OFFSET 0x0038 +#define AITC_NIPRIORITY0_OFFSET 0x003c +#define AITC_NIPRIORITY_OFFSET(n) (AITC_NIPRIORITY7_OFFSET + 4*(7-(n))) +#define AITC_NIVECSR_OFFSET 0x0040 +#define AITC_FIVECSR_OFFSET 0x0044 +#define AITC_INTSRCH_OFFSET 0x0048 +#define AITC_INTSRCL_OFFSET 0x004c +#define AITC_INTFRCH_OFFSET 0x0050 +#define AITC_INTFRCL_OFFSET 0x0054 +#define AITC_NIPNDH_OFFSET 0x0058 +#define AITC_NIPNDL_OFFSET 0x005c +#define AITC_FIPNDH_OFFSET 0x0060 +#define AITC_FIPNDL_OFFSET 0x0064 + +/* AITC Register Addresses **********************************************************/ + +#define IMX_AITC_INTCNTL (IMX_AITC_VBASE + AITC_INTCNTL_OFFSET) +#define IMX_AITC_NIMASK (IMX_AITC_VBASE + AITC_NIMASK_OFFSET) +#define IMX_AITC_INTENNUM (IMX_AITC_VBASE + AITC_INTENNUM_OFFSET) +#define IMX_AITC_INTDISNUM (IMX_AITC_VBASE + AITC_INTDISNUM_OFFSET) +#define IMX_AITC_INTENABLEH (IMX_AITC_VBASE + AITC_INTENABLEH_OFFSET) +#define IMX_AITC_INTENABLEL (IMX_AITC_VBASE + AITC_INTENABLEL_OFFSET) +#define IMX_AITC_INTTYPEH (IMX_AITC_VBASE + AITC_INTTYPEH_OFFSET) +#define IMX_AITC_INTTYPEL (IMX_AITC_VBASE + AITC_INTTYPEL_OFFSET) +#define IMX_AITC_NIPRIORITY7 (IMX_AITC_VBASE + AITC_NIPRIORITY7_OFFSET) +#define IMX_AITC_NIPRIORITY6 (IMX_AITC_VBASE + AITC_NIPRIORITY6_OFFSET) +#define IMX_AITC_NIPRIORITY5 (IMX_AITC_VBASE + AITC_NIPRIORITY5_OFFSET) +#define IMX_AITC_NIPRIORITY4 (IMX_AITC_VBASE + AITC_NIPRIORITY4_OFFSET) +#define IMX_AITC_NIPRIORITY3 (IMX_AITC_VBASE + AITC_NIPRIORITY3_OFFSET) +#define IMX_AITC_NIPRIORITY2 (IMX_AITC_VBASE + AITC_NIPRIORITY2_OFFSET) +#define IMX_AITC_NIPRIORITY1 (IMX_AITC_VBASE + AITC_NIPRIORITY1_OFFSET) +#define IMX_AITC_NIPRIORITY0 (IMX_AITC_VBASE + AITC_NIPRIORITY0_OFFSET) +#define IMX_AITC_NIPRIORITY(n) (IMX_AITC_VBASE + AITC_NIPRIORITY_OFFSET(n))) +#define IMX_AITC_NIVECSR (IMX_AITC_VBASE + AITC_NIVECSR_OFFSET) +#define IMX_AITC_FIVECSR (IMX_AITC_VBASE + AITC_FIVECSR_OFFSET) +#define IMX_AITC_INTSRCH (IMX_AITC_VBASE + AITC_INTSRCH_OFFSET) +#define IMX_AITC_INTSRCL (IMX_AITC_VBASE + AITC_INTSRCL_OFFSET) +#define IMX_AITC_INTFRCH (IMX_AITC_VBASE + AITC_INTFRCH_OFFSET) +#define IMX_AITC_INTFRCL (IMX_AITC_VBASE + AITC_INTFRCL_OFFSET) +#define IMX_AITC_NIPNDH (IMX_AITC_VBASE + AITC_NIPNDH_OFFSET) +#define IMX_AITC_NIPNDL (IMX_AITC_VBASE + AITC_NIPNDL_OFFSET) +#define IMX_AITC_FIPNDH (IMX_AITC_VBASE + AITC_FIPNDH_OFFSET) +#define IMX_AITC_FIPNDL (IMX_AITC_VBASE + AITC_FIPNDL_OFFSET) + +/* AITC Register Bit Definitions ****************************************************/ + + +#define AITC_NIVECSR_NIPRILVL_SHIFT 0 /* Bits 15–0: Priority of highest priority interrupt */ +#define AITC_NIVECSR_NIPRILVL_MASK (0x0000ffff << AITC_NIVECSR_NIPRILVL_SHIFT); +#define AITC_NIVECSR_NIVECTOR_SHIFT 16 /* Bits 31–16: Vector index of highest priority interrupt */ +#define AITC_NIVECSR_NIVECTOR_MASK (0x0000ffff << AITC_NIVECSR_NIVECTOR_SHIFT); + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_AITC_H */ diff --git a/arch/arm/src/imx1/imx_allocateheap.c b/arch/arm/src/imx1/imx_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..550a26e471ae71849ee3e3c12522ed14ecd0f262 --- /dev/null +++ b/arch/arm/src/imx1/imx_allocateheap.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/imx1/imx_allocateheap.c + * + * Copyright (C) 2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = (IMX_SDRAM_VSECTION + CONFIG_RAM_SIZE) - g_idle_topstack; +} + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + /* If a bootloader that copies us to DRAM, but not to the beginning of DRAM, + * then recover that memory by adding another memory region. + */ + +#if !defined(CONFIG_BOOT_RUNFROMFLASH) && !defined(CONFIG_BOOT_COPYTORAM) +# if (CONFIG_RAM_NUTTXENTRY & 0xffff0000) != CONFIG_RAM_VSTART + uint32_t start = CONFIG_RAM_VSTART + 0x1000; + uint32_t end = (CONFIG_RAM_NUTTXENTRY & 0xffff0000); + kmm_addregion((FAR void *)start, end - start); +# endif +#endif + + /* Check for any additional memory regions */ + +#if defined(CONFIG_HEAP2_BASE) && defined(CONFIG_HEAP2_SIZE) + kmm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/imx1/imx_boot.c b/arch/arm/src/imx1/imx_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..f28d2cd7ee13482dbe6191fc0456d67566c5b050 --- /dev/null +++ b/arch/arm/src/imx1/imx_boot.c @@ -0,0 +1,227 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_boot.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct section_mapping_s +{ + uint32_t physbase; /* Physical address of the region to be mapped */ + uint32_t virtbase; /* Virtual address of the region to be mapped */ + uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ + uint32_t nsections; /* Number of mappings in the region */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Mapping of the external memory regions will probably have to be made board + * specific. + */ + +static const struct section_mapping_s section_mapping[] = +{ + { IMX_PERIPHERALS_PSECTION, IMX_PERIPHERALS_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_PERIPHERALS_NSECTIONS}, + { IMX_FLASH_PSECTION, IMX_FLASH_VSECTION, + IMX_FLASH_MMUFLAGS, IMX_FLASH_NSECTIONS}, + { IMX_CS1_PSECTION, IMX_CS1_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_CS1_NSECTIONS}, + { IMX_CS2_PSECTION, IMX_CS2_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_CS2_NSECTIONS}, + { IMX_CS3_PSECTION, IMX_CS3_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_CS3_NSECTIONS}, + { IMX_CS4_PSECTION, IMX_CS4_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_CS4_NSECTIONS}, + { IMX_CS5_PSECTION, IMX_CS5_VSECTION, + IMX_PERIPHERALS_MMUFLAGS, IMX_CS5_NSECTIONS}, +}; + +#define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s)) + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/* All i.MX architectures must provide the following entry point. This entry point + * is called early in the intitialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + */ + +void imx_board_initialize(void); + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_setlevel1entry + ************************************************************************************/ + +static inline void up_setlevel1entry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *pgtable = (uint32_t *)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + pgtable[index] = (paddr | mmuflags); +} + +/************************************************************************************ + * Name: up_setupmappings + ************************************************************************************/ + +static void up_setupmappings(void) +{ + int i, j; + + for (i = 0; i < NMAPPINGS; i++) + { + uint32_t sect_paddr = section_mapping[i].physbase; + uint32_t sect_vaddr = section_mapping[i].virtbase; + uint32_t mmuflags = section_mapping[i].mmuflags; + + for (j = 0; j < section_mapping[i].nsections; j++) + { + up_setlevel1entry(sect_paddr, sect_vaddr, mmuflags); + sect_paddr += SECTION_SIZE; + sect_vaddr += SECTION_SIZE; + } + } +} + +/************************************************************************************ + * Name: up_copyvectorblock + ************************************************************************************/ + +static void up_copyvectorblock(void) +{ + /* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case: + * + * - Our vectors must be located at the beginning of FLASH and will + * also be mapped to address zero (because of the i.MX's "double map image." + * - There is nothing to be done here in this case. + * + * 2. We boot in FLASH but copy ourselves to DRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case: + * + * - Our code image is in FLASH and we boot to FLASH initially, then copy + * ourself to DRAM, and + * - DRAM will be mapped to address zero. + * - There is nothing to be done here in this case. + * + * 3. There is bootloader that copies us to DRAM, but probably not to the beginning + * of DRAM (say to 0x0900:0000) (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). + * In this case: + * + * - DRAM will be mapped to address zero. + * - Interrupt vectors will be copied to address zero in this function. + */ + +#if !defined(CONFIG_BOOT_RUNFROMFLASH) && !defined(CONFIG_BOOT_COPYTORAM) + uint32_t *src = (uint32_t *)&_vector_start; + uint32_t *end = (uint32_t *)&_vector_end; + uint32_t *dest = (uint32_t *)VECTOR_BASE; + + while (src < end) + { + *dest++ = *src++; + } +#endif +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void up_boot(void) +{ + /* __start provided the basic MMU mappings for SDRAM. Now provide mappings for all + * IO regions (Including the vector region). + */ + + up_setupmappings(); + + /* Setup up vector block. _vector_start and _vector_end are exported from + * up_vector.S + */ + + up_copyvectorblock(); + + /* Perform board-specific initialiation */ + + imx_board_initialize(); + + /* Set up the board-specific LEDs */ + +#ifdef CONFIG_ARCH_LEDS + board_autoled_initialize(); +#endif + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif +} diff --git a/arch/arm/src/imx1/imx_cspi.h b/arch/arm/src/imx1/imx_cspi.h new file mode 100644 index 0000000000000000000000000000000000000000..4a43e5546943b4b37725211fd913a45aa09c4dea --- /dev/null +++ b/arch/arm/src/imx1/imx_cspi.h @@ -0,0 +1,240 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_cspi.h + * + * Copyright (C) 2009-2010, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_CSPI_H +#define __ARCH_ARM_IMX_CSPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* CSPI Register Offsets ************************************************************/ + +#define CSPI_RXD_OFFSET 0x0000 /* Receive Data Register */ +#define CSPI_TXD_OFFSET 0x0004 /* Transmit Data Register */ +#define CSPI_CTRL_OFFSET 0x0008 /* Control Register */ +#define CSPI_INTCS_OFFSET 0x000c /* Interrupt Control/Status Register */ +#define CSPI_TEST_OFFSET 0x0010 /* Test Register */ +#define CSPI_SPCR_OFFSET 0x0014 /* Sample Period Control Register */ +#define CSPI_DMA_OFFSET 0x0018 /* DMA Control Register */ +#define CSPI_RESET_OFFSET 0x001c /* Soft Reset Register */ + +/* CSPI Register Addresses **********************************************************/ + +/* CSPI1 */ + +#define IMX_CSPI1_RXD (IMX_CSPI1_VBASE + CSPI_RXD_OFFSET) +#define IMX_CSPI1_TXD (IMX_CSPI1_VBASE + CSPI_TXD_OFFSET) +#define IMX_CSPI1_CTRL (IMX_CSPI1_VBASE + CSPI_CTRL_OFFSET) +#define IMX_CSPI1_INTCS (IMX_CSPI1_VBASE + CSPI_INTCS_OFFSET) +#define IMX_CSPI1_SPITEST (IMX_CSPI1_VBASE + CSPI_TEST_OFFSET) +#define IMX_CSPI1_SPISPCR (IMX_CSPI1_VBASE + CSPI_SPCR_OFFSET) +#define IMX_CSPI1_SPIDMA (IMX_CSPI1_VBASE + CSPI_DMA_OFFSET) +#define IMX_CSPI1_SPIRESET (IMX_CSPI1_VBASE + CSPI_RESET_OFFSET) + +/* CSPI1 */ + +#define IMX_CSPI2_RXD (IMX_CSPI2_VBASE + CSPI_RXD_OFFSET) +#define IMX_CSPI2_TXD (IMX_CSPI2_VBASE + CSPI_TXD_OFFSET) +#define IMX_CSPI2_CTRL (IMX_CSPI2_VBASE + CSPI_CTRL_OFFSET) +#define IMX_CSPI2_INTCS (IMX_CSPI2_VBASE + CSPI_INTCS_OFFSET) +#define IMX_CSPI2_SPITEST (IMX_CSPI2_VBASE + CSPI_TEST_OFFSET) +#define IMX_CSPI2_SPISPCR (IMX_CSPI2_VBASE + CSPI_SPCR_OFFSET) +#define IMX_CSPI2_SPIDMA (IMX_CSPI2_VBASE + CSPI_DMA_OFFSET) +#define IMX_CSPI2_SPIRESET (IMX_CSPI2_VBASE + CSPI_RESET_OFFSET) + +/* CSPI Register Bit Definitions ****************************************************/ + +/* CSPI Control Register */ + +#define CSPI_CTRL_DATARATE_SHIFT 13 +#define CSPI_CTRL_DATARATE_MASK (7 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV4 (0 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV8 (1 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV16 (2 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV32 (3 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV64 (4 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV128 (5 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV256 (6 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DIV512 (7 << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_CTRL_DRCTL_SHIFT 11 +#define CSPI_CTRL_DRCTL_MASK (3 << CSPI_CTRL_DRCTL_SHIFT) +#define CSPI_CTRL_DRCTL_IGNRDY (0 << CSPI_CTRL_DRCTL_SHIFT) +#define CSPI_CTRL_DRCTL_FALLING (1 << CSPI_CTRL_DRCTL_SHIFT) +#define CSPI_CTRL_DRCTL_ACTVLOW (2 << CSPI_CTRL_DRCTL_SHIFT) +#define CSPI_CTRL_MODE (1 << 10) +#define CSPI_CTRL_SPIEN (1 << 9) +#define CSPI_CTRL_XCH (1 << 8) +#define CSPI_CTRL_SSPOL (1 << 7) +#define CSPI_CTRL_SSCTL (1 << 6) +#define CSPI_CTRL_PHA (1 << 5) +#define CSPI_CTRL_POL (1 << 4) +#define CSPI_CTRL_BITCOUNT_SHIFT 0 +#define CSPI_CTRL_BITCOUNT_MASK (15 << CSPI_CTRL_BITCOUNT_SHIFT) + +/* CSPI Interrrupt Control/Status Register */ + +#define CSPI_INTCS_TE (1 << 0) /* Bit 0: TXFIFO Empty Status */ +#define CSPI_INTCS_TH (1 << 1) /* Bit 1: TXFIFO Half Status */ +#define CSPI_INTCS_TF (1 << 2) /* Bit 2: TXFIFO Full Status */ +#define CSPI_INTCS_RR (1 << 3) /* Bit 3: RXFIFO Data Ready Status */ +#define CSPI_INTCS_RH (1 << 4) /* Bit 4: RXFIFO Half Status */ +#define CSPI_INTCS_RF (1 << 5) /* Bit 5: RXFIFO Full Status */ +#define CSPI_INTCS_RO (1 << 6) /* Bit 6: RXFIFO Overflow */ +#define CSPI_INTCS_BO (1 << 7) /* Bit 7: Bit Count Overflow */ +#define CSPI_INTCS_TEEN (1 << 8) /* Bit 8: TXFIFO Empty Interrupt Enable */ +#define CSPI_INTCS_THEN (1 << 9) /* Bit 9: TXFIFO Half Interrupt Enable */ +#define CSPI_INTCS_TFEN (1 << 10) /* Bit 10: TXFIFO Full Interrupt Enable */ +#define CSPI_INTCS_RREN (1 << 11) /* Bit 11: RXFIFO Data Ready Interrupt Enable */ +#define CSPI_INTCS_RHEN (1 << 12) /* Bit 12: RXFIFO Half Interrupt Enable */ +#define CSPI_INTCS_RFEN (1 << 13) /* Bit 13: RXFIFO Full Interrupt Enable */ +#define CSPI_INTCS_ROEN (1 << 14) /* BIT 14: RXFIFO Overflow Interrupt Enable */ +#define CSPI_INTCS_BOEN (1 << 15) /* Bit 15: Bit Count Overflow Interrupt Enable */ + +#define CSPI_INTCS_ALLINTS 0x0000ff00 + +/* CSPI Sample Period Control Register */ + +#define CSPI_SPCR_WAIT_SHIFT 0 +#define CSPI_SPCR_WAIT_MASK (0x7ff << CSPI_CTRL_DATARATE_SHIFT) +#define CSPI_SPCR_CSRC (1 << 15) /* Bit 15: 1:32768 or 32 kHz clock source */ + +/* CSPI DMA Control Register */ + +#define CSPI_DMA_RHDMA (1 << 4) /* Bit 4: RXFIFO Half Status */ +#define CSPI_DMA_RFDMA (1 << 5) /* Bit 5: RXFIFO Full Status */ +#define CSPI_DMA_TEDMA (1 << 6) /* Bit 6: TXFIFO Empty Status */ +#define CSPI_DMA_THDMA (1 << 7) /* Bit 7: TXFIFO Half Status */ +#define CSPI_DMA_RHDEN (1 << 12) /* Bit 12: Enable RXFIFO Half DMA Request */ +#define CSPI_DMA_RFDEN (1 << 13) /* Bit 13: Enables RXFIFO Full DMA Request */ +#define CSPI_DMA_TEDEN (1 << 14) /* Bit 14: Enable TXFIFO Empty DMA Request */ +#define CSPI_DMA_THDEN (1 << 15) /* Bit 15: Enable TXFIFO Half DMA Request */ + +/* Soft Reset Register */ + +#define CSPI_RESET_START (1 << 0) /* Bit 0: Execute soft reset */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif /* __cplusplus */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: imx_spibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *imx_spibus_initialize(int port); + +/**************************************************************************** + * The external functions, imx_spiselect, imx_spistatus, and imx_cmddaa must be + * provided by board-specific logic. These are implementations of the select and + * status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including imx_spibus_initialize()) are + * provided by common logic. To use this common SPI logic on your board: + * + * 1. Provide imx_spiselect() and imx_spistatus() functions in your board-specific + * logic. This function will perform chip selection and status operations using + * GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration, provide the + * imx_spicmddata() function in your board-specific logic. This function will + * perform cmd/data selection operations using GPIOs in the way your board is + * configured. + * 3. Add a call to imx_spibus_initialize() in your low level initialization logic + * 4. The handle returned by imx_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + * + ****************************************************************************/ + +void imx_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t imx_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int imx_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_IMX_CSPI_H */ diff --git a/arch/arm/src/imx1/imx_decodeirq.c b/arch/arm/src/imx1/imx_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..5c35e68fab2dbc619aeea11cc6146698c74a09b4 --- /dev/null +++ b/arch/arm/src/imx1/imx_decodeirq.c @@ -0,0 +1,154 @@ +/******************************************************************************** + * arch/arm/src/imx1/imx_decodeirq.c + * + * Copyright (C) 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + uint32_t regval; + int irq; + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(CURRENT_REGS == NULL); + CURRENT_REGS = regs; + + /* Loop while there are pending interrupts to be processed */ + + do + { + /* Decode the interrupt. First, fetch the NIVECSR register. */ + + regval = getreg32(IMX_AITC_NIVECSR); + + /* The MS 16 bits of the NIVECSR register contains vector index for the + * highest pending normal interrupt. + */ + + irq = regval >> AITC_NIVECSR_NIVECTOR_SHIFT; + + /* If irq < 64, then this is the IRQ. If there is no pending interrupt, + * then irq will be >= 64 (it will be 0xffff for illegal source). + */ + + if (irq < NR_IRQS) + { + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. + * If an interrupt level context switch has occurred, then restore + * the floating point state and the establish the correct address + * environment before returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + } + } + while (irq < NR_IRQS); + + /* Set CURRENT_REGS to NULL to indicate that we are no longer in + * an interrupt handler. + */ + + CURRENT_REGS = NULL; +#endif +} diff --git a/arch/arm/src/imx1/imx_dma.h b/arch/arm/src/imx1/imx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..00deeae8380e2e12e6e091a52255a10adc72cdb7 --- /dev/null +++ b/arch/arm/src/imx1/imx_dma.h @@ -0,0 +1,250 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_dma.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_DMA_H +#define __ARCH_ARM_IMX_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* DMA Register Offsets *************************************************************/ + +#define DMA_SYS_OFFSET 0x0000 +#define DMA_M2D_OFFSET 0x0040 +#define DMA_CH0_OFFSET 0x0080 +#define DMA_CH1_OFFSET 0x00c0 +#define DMA_CH2_OFFSET 0x0100 +#define DMA_CH3_OFFSET 0x0140 +#define DMA_CH4_OFFSET 0x0180 +#define DMA_CH5_OFFSET 0x01C0 +#define DMA_CH6_OFFSET 0x0200 +#define DMA_CH7_OFFSET 0x0240 +#define DMA_CH8_OFFSET 0x0280 +#define DMA_CH9_OFFSET 0x02c0 +#define DMA_CH10_OFFSET 0x0300 +#define DMA_CH_OFFSET(n) (DMA_CH0_OFFSET + (n)*0x0040) +#define DMA_TST_OFFSET 0x0340 + +#define DMA_DCR_OFFSET 0x0000 +#define DMA_ISR_OFFSET 0x0004 +#define DMA_IMR_OFFSET 0x0008 +#define DMA_BTOSR_OFFSET 0x000c +#define DMA_RTOSR_OFFSET 0x0010 +#define DMA_TESR_OFFSET 0x0014 +#define DMA_BOSR_OFFSET 0x0018 +#define DMA_BTOCR_OFFSET 0x001c + +#define DMA_WSRA_OFFSET 0x0000 +#define DMA_XSRA_OFFSET 0x0004 +#define DMA_YSRA_OFFSET 0x0008 +#define DMA_WSRB_OFFSET 0x000c +#define DMA_XSRB_OFFSET 0x0010 +#define DMA_YSRB_OFFSET 0x0014 + +#define DMA_SAR_OFFSET 0x0000 +#define DMA_DAR_OFFSET 0x0004 +#define DMA_CNTR_OFFSET 0x0008 +#define DMA_CCR_OFFSET 0x000c +#define DMA_RSSR_OFFSET 0x0010 +#define DMA_BLR_OFFSET 0x0014 +#define DMA_RTOR_OFFSET 0x0018 +#define DMA_BUCR_OFFSET 0x0018 + +#define DMA_TCR_OFFSET 0x0000 +#define DMA_TFIFOA_OFFSET 0x0004 +#define DMA_TDRR_OFFSET 0x0008 +#define DMA_TDIPR_OFFSET 0x000c +#define DMA_TFIFOB_OFFSET 0x0010 + +/* DMA Register Addresses ***********************************************************/ + +#define IMX_DMA_SYS_BASE (IMX_DMA_VBASE + DMA_SYS_OFFSET) +#define IMX_DMA_M2D_BASE (IMX_DMA_VBASE + DMA_M2D_OFFSET) +#define IMX_DMA_CH0_BASE (IMX_DMA_VBASE + DMA_CH0_OFFSET) +#define IMX_DMA_CH1_BASE (IMX_DMA_VBASE + DMA_CH1_OFFSET) +#define IMX_DMA_CH2_BASE (IMX_DMA_VBASE + DMA_CH2_OFFSET) +#define IMX_DMA_CH3_BASE (IMX_DMA_VBASE + DMA_CH3_OFFSET) +#define IMX_DMA_CH4_BASE (IMX_DMA_VBASE + DMA_CH4_OFFSET) +#define IMX_DMA_CH5_BASE (IMX_DMA_VBASE + DMA_CH5_OFFSET) +#define IMX_DMA_CH6_BASE (IMX_DMA_VBASE + DMA_CH6_OFFSET) +#define IMX_DMA_CH7_BASE (IMX_DMA_VBASE + DMA_CH7_OFFSET) +#define IMX_DMA_CH8_BASE (IMX_DMA_VBASE + DMA_CH8_OFFSET) +#define IMX_DMA_CH9_BASE (IMX_DMA_VBASE + DMA_CH9_OFFSET) +#define IMX_DMA_CH10_BASE (IMX_DMA_VBASE + DMA_CH10_OFFSET) +#define IMX_DMA_CH_BASE(n) (IMX_DMA_VBASE + DMA_CH_OFFSET(n)) +#define IMX_DMA_TST_BASE (IMX_DMA_VBASE + DMA_TST_OFFSET) + +#define IMX_DMA_DCR (DMA_SYS_BASE + DMA_DCR_OFFSET) +#define IMX_DMA_ISR (DMA_SYS_BASE + DMA_ISR_OFFSET) +#define IMX_DMA_IMR (DMA_SYS_BASE + DMA_IMR_OFFSET) +#define IMX_DMA_BTOSR (DMA_SYS_BASE + DMA_BTOSR_OFFSET) +#define IMX_DMA_RTOSR (DMA_SYS_BASE + DMA_RTOSR_OFFSET) +#define IMX_DMA_TESR (DMA_SYS_BASE + DMA_TESR_OFFSET) +#define IMX_DMA_BOSR (DMA_SYS_BASE + DMA_BOSR_OFFSET) +#define IMX_DMA_BTOCR (DMA_SYS_BASE + DMA_BTOCR_OFFSET) + +#define IMX_DMA_WSRA (DMA_M2D_BASE + DMA_WSRA_OFFSET) +#define IMX_DMA_XSRA (DMA_M2D_BASE + DMA_XSRA_OFFSET) +#define IMX_DMA_YSRA (DMA_M2D_BASE + DMA_YSRA_OFFSET) +#define IMX_DMA_WSRB (DMA_M2D_BASE + DMA_WSRB_OFFSET) +#define IMX_DMA_XSRB (DMA_M2D_BASE + DMA_XSRB_OFFSET) +#define IMX_DMA_YSRB (DMA_M2D_BASE + DMA_YSRB_OFFSET) + +#define IMX_DMA_SAR0 (DMA_CH0_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR0 (DMA_CH0_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR0 (DMA_CH0_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR0 (DMA_CH0_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR0 (DMA_CH0_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR0 (DMA_CH0_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR0 (DMA_CH0_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR0 (DMA_CH0_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR1 (DMA_CH1_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR1 (DMA_CH1_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR1 (DMA_CH1_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR1 (DMA_CH1_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR1 (DMA_CH1_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR1 (DMA_CH1_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR1 (DMA_CH1_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR1 (DMA_CH1_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR2 (DMA_CH2_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR2 (DMA_CH2_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR2 (DMA_CH2_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR2 (DMA_CH2_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR2 (DMA_CH2_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR2 (DMA_CH2_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR2 (DMA_CH2_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR2 (DMA_CH2_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR3 (DMA_CH3_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR3 (DMA_CH3_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR3 (DMA_CH3_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR3 (DMA_CH3_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR3 (DMA_CH3_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR3 (DMA_CH3_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR3 (DMA_CH3_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR3 (DMA_CH3_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR4 (DMA_CH4_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR4 (DMA_CH4_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR4 (DMA_CH4_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR4 (DMA_CH4_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR4 (DMA_CH4_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR4 (DMA_CH4_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR4 (DMA_CH4_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR4 (DMA_CH4_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR5 (DMA_CH5_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR5 (DMA_CH5_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR5 (DMA_CH5_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR5 (DMA_CH5_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR5 (DMA_CH5_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR5 (DMA_CH5_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR5 (DMA_CH5_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR5 (DMA_CH5_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR6 (DMA_CH6_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR6 (DMA_CH6_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR6 (DMA_CH6_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR6 (DMA_CH6_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR6 (DMA_CH6_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR6 (DMA_CH6_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR6 (DMA_CH6_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR6 (DMA_CH6_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR7 (DMA_CH7_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR7 (DMA_CH7_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR7 (DMA_CH7_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR7 (DMA_CH7_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR7 (DMA_CH7_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR7 (DMA_CH7_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR7 (DMA_CH7_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR7 (DMA_CH7_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR8 (DMA_CH8_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR8 (DMA_CH8_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR8 (DMA_CH8_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR8 (DMA_CH8_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR8 (DMA_CH8_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR8 (DMA_CH8_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR8 (DMA_CH8_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR8 (DMA_CH8_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR9 (DMA_CH9_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR9 (DMA_CH9_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR9 (DMA_CH9_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR9 (DMA_CH9_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR9 (DMA_CH9_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR9 (DMA_CH9_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR9 (DMA_CH9_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR9 (DMA_CH9_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR10 (DMA_CH10_BASE + DMA_SAR_OFFSET) +#define IMX_DMA_DAR10 (DMA_CH10_BASE + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR10 (DMA_CH10_BASE + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR10 (DMA_CH10_BASE + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR10 (DMA_CH10_BASE + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR10 (DMA_CH10_BASE + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR10 (DMA_CH10_BASE + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR10 (DMA_CH10_BASE + DMA_BUCR_OFFSET) + +#define IMX_DMA_SAR(n) (DMA_CH_BASE(n) + DMA_SAR_OFFSET) +#define IMX_DMA_DAR(n) (DMA_CH_BASE(n) + DMA_DAR_OFFSET) +#define IMX_DMA_CNTR(n) (DMA_CH_BASE(n) + DMA_CNTR_OFFSET) +#define IMX_DMA_CCR(n) (DMA_CH_BASE(n) + DMA_CCR_OFFSET) +#define IMX_DMA_RSSR(n) (DMA_CH_BASE(n) + DMA_RSSR_OFFSET) +#define IMX_DMA_BLR(n) (DMA_CH_BASE(n) + DMA_BLR_OFFSET) +#define IMX_DMA_RTOR(n) (DMA_CH_BASE(n) + DMA_RTOR_OFFSET) +#define IMX_DMA_BUCR(n) (DMA_CH_BASE(n) + DMA_BUCR_OFFSET) + +#define IMX_DMA_TCR (DMA_TST_BASE + DMA_TCR_OFFSET) +#define IMX_DMA_TFIFOA (DMA_TST_BASE + DMA_TFIFOA_OFFSET) +#define IMX_DMA_TDRR (DMA_TST_BASE + DMA_TDRR_OFFSET) +#define IMX_DMA_TDIPR (DMA_TST_BASE + DMA_TDIPR_OFFSET) +#define IMX_DMA_TFIFOB (DMA_TST_BASE + DMA_TFIFOB_OFFSET) + +/* DMA Register Bit Definitions *****************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_DMA_H */ diff --git a/arch/arm/src/imx1/imx_eim.h b/arch/arm/src/imx1/imx_eim.h new file mode 100644 index 0000000000000000000000000000000000000000..f48434982c09480dbe2a81e9e11f63054037f66b --- /dev/null +++ b/arch/arm/src/imx1/imx_eim.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_eim.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_WIEM_H +#define __ARCH_ARM_IMX_WIEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* EIM Register Offsets ************************************************************/ + +#define EIM_CS0H_OFFSET 0x00 +#define EIM_CS0L_OFFSET 0x04 +#define EIM_CS1H_OFFSET 0x08 +#define EIM_CS1L_OFFSET 0x0c +#define EIM_CS2H_OFFSET 0x10 +#define EIM_CS2L_OFFSET 0x14 +#define EIM_CS3H_OFFSET 0x18 +#define EIM_CS3L_OFFSET 0x1c +#define EIM_CS4H_OFFSET 0x20 +#define EIM_CS4L_OFFSET 0x24 +#define EIM_CS5H_OFFSET 0x28 +#define EIM_CS5L_OFFSET 0x2c +#define EIM_WEIM_OFFSET 0x30 + +/* EIM Register Addresses ***********************************************************/ + +#define IMX_EIM_CS0H (EIM_BASE_ADDR + EIM_CS0H_OFFSET) +#define IMX_EIM_CS0L (EIM_BASE_ADDR + EIM_CS0L_OFFSET) +#define IMX_EIM_CS1H (EIM_BASE_ADDR + EIM_CS1H_OFFSET) +#define IMX_EIM_CS1L (EIM_BASE_ADDR + EIM_CS1L_OFFSET) +#define IMX_EIM_CS2H (EIM_BASE_ADDR + EIM_CS2H_OFFSET) +#define IMX_EIM_CS2L (EIM_BASE_ADDR + EIM_CS2L_OFFSET) +#define IMX_EIM_CS3H (EIM_BASE_ADDR + EIM_CS3H_OFFSET) +#define IMX_EIM_CS3L (EIM_BASE_ADDR + EIM_CS3L_OFFSET) +#define IMX_EIM_CS4H (EIM_BASE_ADDR + EIM_CS4H_OFFSET) +#define IMX_EIM_CS4L (EIM_BASE_ADDR + EIM_CS4L_OFFSET) +#define IMX_EIM_CS5H (EIM_BASE_ADDR + EIM_CS5H_OFFSET) +#define IMX_EIM_CS5L (EIM_BASE_ADDR + EIM_CS5L_OFFSET) +#define IMX_EIM_WEIM (EIM_BASE_ADDR + EIM_WEIM_OFFSET) + +/* EIM Register Bit Definitions *****************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_EIM_H */ diff --git a/arch/arm/src/imx1/imx_gpio.c b/arch/arm/src/imx1/imx_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..6789f202ebfa8dfbbc6eaaa93f3fbee76fd3ed31 --- /dev/null +++ b/arch/arm/src/imx1/imx_gpio.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/arm/src/imx1/imx_gpio.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "up_arch.h" +#include "imx_gpio.h" + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxgpio_configoutput + ****************************************************************************/ + +void imxgpio_configoutput(int port, int bit, int value) +{ + imxgpio_configinput(port, bit); /* Same as input except: */ + imxgpio_dirout(port, bit); /* Output */ + + if (value) + { + imxgpio_setoutput(port, bit); /* Set output = 1 */ + } + else + { + imxgpio_clroutput(port, bit); /* Set output = 0 */ + } +} + +/**************************************************************************** + * Name: imxgpio_configinput + ****************************************************************************/ + +void imxgpio_configinput(int port, int bit) +{ + imxgpio_pullupdisable(port, bit); /* No pullup */ + imxgpio_dirin(port, bit); /* Input */ + imxgpio_gpiofunc(port, bit); /* Use as GPIO */ + imxgpio_primaryperipheralfunc(port, bit); /* Not necessary */ + imxgpio_ocrain(port, bit); /* Output AIN */ + imxgpio_aoutgpio(port, bit); /* AOUT input is GPIO */ + imxgpio_boutgpio(port, bit); /* BOUT input is GPIO */ +} + +/**************************************************************************** + * Name: imxgpio_configpfoutput + ****************************************************************************/ + +void imxgpio_configpfoutput(int port, int bit) +{ + imxgpio_configinput(port, bit); /* Same as input except: */ + imxgpio_peripheralfunc(port, bit); /* Use as peripheral */ + imxgpio_primaryperipheralfunc(port, bit); /* Primary function */ + imxgpio_dirout(port, bit); /* Make output */ +} + +/**************************************************************************** + * Name: imxgpio_configpfinput + ****************************************************************************/ + +void imxgpio_configpfinput(int port, int bit) +{ + imxgpio_configinput(port, bit); /* Same as input except: */ + imxgpio_peripheralfunc(port, bit); /* Use as peripheral */ + imxgpio_primaryperipheralfunc(port, bit); /* Primary function */ +} diff --git a/arch/arm/src/imx1/imx_gpio.h b/arch/arm/src/imx1/imx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..14e911ddf4d3eac1f7c378f520752fd730b986fb --- /dev/null +++ b/arch/arm/src/imx1/imx_gpio.h @@ -0,0 +1,561 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_gpio.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX1_IMX_GPIO_H +#define __ARCH_ARM_SRC_IMX1_IMX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif +#include "up_arch.h" /* getreg32(), putreg32() */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO Register Offsets ************************************************************/ + +#define GPIO_DDIR_OFFSET 0x0000 /* Data Direction Register */ +#define GPIO_OCR1_OFFSET 0x0004 /* Output Configuration Register 1 */ +#define GPIO_OCR2_OFFSET 0x0008 /* Output Configuration Register 2 */ +#define GPIO_ICONFA1_OFFSET 0x000c /* Input Configuration Register A1 */ +#define GPIO_ICONFA2_OFFSET 0x0010 /* Input Configuration Register A2 */ +#define GPIO_ICONFB1_OFFSET 0x0014 /* Input Configuration Register B1 */ +#define GPIO_ICONFB2_OFFSET 0x0018 /* Input Configuration Register B2 */ +#define GPIO_DR_OFFSET 0x001c /* Data Register */ +#define GPIO_GIUS_OFFSET 0x0020 /* GPIO In Use Register */ +#define GPIO_SSR_OFFSET 0x0024 /* Sample Status Register */ +#define GPIO_ICR1_OFFSET 0x0028 /* Interrupt Configuration Register 1 */ +#define GPIO_ICR2_OFFSET 0x002c /* Interrupt Configuration Register 2 */ +#define GPIO_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define GPIO_ISR_OFFSET 0x0034 /* Interrupt Status Register */ +#define GPIO_GPR_OFFSET 0x0038 /* General Purpose Register */ +#define GPIO_SWR_OFFSET 0x003c /* Software Reset Register */ +#define GPIO_PUEN_OFFSET 0x0040 /* Pull_Up Enable Register */ + +#define GPIO_PTA_OFFSET 0x0000 /* Port A offset */ +#define GPIO_PTB_OFFSET 0x0100 /* Port B offset */ +#define GPIO_PTC_OFFSET 0x0200 /* Port C offset */ +#define GPIO_PTD_OFFSET 0x0300 /* Port D offset */ + +#define GPIOA 0 /* Port A index */ +#define GPIOB 1 /* Port B index */ +#define GPIOC 2 /* Port C index */ +#define GPIOD 3 /* Port D index */ +#define GPIO_PT_OFFSET(n) (GPIO_PTA_OFFSET + (n)*0x0100) + +/* GPIO Register Addresses **********************************************************/ + +#define IMX_PTA_VBASE (IMX_GPIO_VBASE + GPIO_PTA_OFFSET) +#define IMX_PTB_VBASE (IMX_GPIO_VBASE + GPIO_PTB_OFFSET) +#define IMX_PTC_VBASE (IMX_GPIO_VBASE + GPIO_PTC_OFFSET) +#define IMX_PTD_VBASE (IMX_GPIO_VBASE + GPIO_PTD_OFFSET) +#define IMX_PT_VBASE(n) (IMX_GPIO_VBASE + GPIO_PT_OFFSET(n)) + +#define IMX_GPIOA_DDIR (IMX_PTA_VBASE + GPIO_DDIR_OFFSET) +#define IMX_GPIOA_OCR1 (IMX_PTA_VBASE + GPIO_OCR1_OFFSET) +#define IMX_GPIOA_OCR2 (IMX_PTA_VBASE + GPIO_OCR2_OFFSET) +#define IMX_GPIOA_ICONFA1 (IMX_PTA_VBASE + GPIO_ICONFA1_OFFSET) +#define IMX_GPIOA_ICONFA2 (IMX_PTA_VBASE + GPIO_ICONFA2_OFFSET) +#define IMX_GPIOA_ICONFB1 (IMX_PTA_VBASE + GPIO_ICONFB1_OFFSET) +#define IMX_GPIOA_ICONFB2 (IMX_PTA_VBASE + GPIO_ICONFB2_OFFSET) +#define IMX_GPIOA_DR (IMX_PTA_VBASE + GPIO_DR_OFFSET) +#define IMX_GPIOA_GIUS (IMX_PTA_VBASE + GPIO_GIUS_OFFSET) +#define IMX_GPIOA_SSR (IMX_PTA_VBASE + GPIO_SSR_OFFSET) +#define IMX_GPIOA_ICR1 (IMX_PTA_VBASE + GPIO_ICR1_OFFSET) +#define IMX_GPIOA_ICR2 (IMX_PTA_VBASE + GPIO_ICR2_OFFSET) +#define IMX_GPIOA_IMR (IMX_PTA_VBASE + GPIO_IMR_OFFSET) +#define IMX_GPIOA_ISR (IMX_PTA_VBASE + GPIO_ISR_OFFSET) +#define IMX_GPIOA_GPR (IMX_PTA_VBASE + GPIO_GPR_OFFSET) +#define IMX_GPIOA_SWR (IMX_PTA_VBASE + GPIO_SWR_OFFSET) +#define IMX_GPIOA_PUEN (IMX_PTA_VBASE + GPIO_PUEN_OFFSET) + +#define IMX_GPIOB_DDIR (IMX_PTB_VBASE + GPIO_DDIR_OFFSET) +#define IMX_GPIOB_OCR1 (IMX_PTB_VBASE + GPIO_OCR1_OFFSET) +#define IMX_GPIOB_OCR2 (IMX_PTB_VBASE + GPIO_OCR2_OFFSET) +#define IMX_GPIOB_ICONFA1 (IMX_PTB_VBASE + GPIO_ICONFA1_OFFSET) +#define IMX_GPIOB_ICONFA2 (IMX_PTB_VBASE + GPIO_ICONFA2_OFFSET) +#define IMX_GPIOB_ICONFB1 (IMX_PTB_VBASE + GPIO_ICONFB1_OFFSET) +#define IMX_GPIOB_ICONFB2 (IMX_PTB_VBASE + GPIO_ICONFB2_OFFSET) +#define IMX_GPIOB_DR (IMX_PTB_VBASE + GPIO_DR_OFFSET) +#define IMX_GPIOB_GIUS (IMX_PTB_VBASE + GPIO_GIUS_OFFSET) +#define IMX_GPIOB_SSR (IMX_PTB_VBASE + GPIO_SSR_OFFSET) +#define IMX_GPIOB_ICR1 (IMX_PTB_VBASE + GPIO_ICR1_OFFSET) +#define IMX_GPIOB_ICR2 (IMX_PTB_VBASE + GPIO_ICR2_OFFSET) +#define IMX_GPIOB_IMR (IMX_PTB_VBASE + GPIO_IMR_OFFSET) +#define IMX_GPIOB_ISR (IMX_PTB_VBASE + GPIO_ISR_OFFSET) +#define IMX_GPIOB_GPR (IMX_PTB_VBASE + GPIO_GPR_OFFSET) +#define IMX_GPIOB_SWR (IMX_PTB_VBASE + GPIO_SWR_OFFSET) +#define IMX_GPIOB_PUEN (IMX_PTB_VBASE + GPIO_PUEN_OFFSET) + +#define IMX_GPIOC_DDIR (IMX_PTC_VBASE + GPIO_DDIR_OFFSET) +#define IMX_GPIOC_OCR1 (IMX_PTC_VBASE + GPIO_OCR1_OFFSET) +#define IMX_GPIOC_OCR2 (IMX_PTC_VBASE + GPIO_OCR2_OFFSET) +#define IMX_GPIOC_ICONFA1 (IMX_PTC_VBASE + GPIO_ICONFA1_OFFSET) +#define IMX_GPIOC_ICONFA2 (IMX_PTC_VBASE + GPIO_ICONFA2_OFFSET) +#define IMX_GPIOC_ICONFB1 (IMX_PTC_VBASE + GPIO_ICONFB1_OFFSET) +#define IMX_GPIOC_ICONFB2 (IMX_PTC_VBASE + GPIO_ICONFB2_OFFSET) +#define IMX_GPIOC_DR (IMX_PTC_VBASE + GPIO_DR_OFFSET) +#define IMX_GPIOC_GIUS (IMX_PTC_VBASE + GPIO_GIUS_OFFSET) +#define IMX_GPIOC_SSR (IMX_PTC_VBASE + GPIO_SSR_OFFSET) +#define IMX_GPIOC_ICR1 (IMX_PTC_VBASE + GPIO_ICR1_OFFSET) +#define IMX_GPIOC_ICR2 (IMX_PTC_VBASE + GPIO_ICR2_OFFSET) +#define IMX_GPIOC_IMR (IMX_PTC_VBASE + GPIO_IMR_OFFSET) +#define IMX_GPIOC_ISR (IMX_PTC_VBASE + GPIO_ISR_OFFSET) +#define IMX_GPIOC_GPR (IMX_PTC_VBASE + GPIO_GPR_OFFSET) +#define IMX_GPIOC_SWR (IMX_PTC_VBASE + GPIO_SWR_OFFSET) +#define IMX_GPIOC_PUEN (IMX_PTC_VBASE + GPIO_PUEN_OFFSET) + +#define IMX_GPIOD_DDIR (IMX_PTD_VBASE + GPIO_DDIR_OFFSET) +#define IMX_GPIOD_OCR1 (IMX_PTD_VBASE + GPIO_OCR1_OFFSET) +#define IMX_GPIOD_OCR2 (IMX_PTD_VBASE + GPIO_OCR2_OFFSET) +#define IMX_GPIOD_ICONFA1 (IMX_PTD_VBASE + GPIO_ICONFA1_OFFSET) +#define IMX_GPIOD_ICONFA2 (IMX_PTD_VBASE + GPIO_ICONFA2_OFFSET) +#define IMX_GPIOD_ICONFB1 (IMX_PTD_VBASE + GPIO_ICONFB1_OFFSET) +#define IMX_GPIOD_ICONFB2 (IMX_PTD_VBASE + GPIO_ICONFB2_OFFSET) +#define IMX_GPIOD_DR (IMX_PTD_VBASE + GPIO_DR_OFFSET) +#define IMX_GPIOD_GIUS (IMX_PTD_VBASE + GPIO_GIUS_OFFSET) +#define IMX_GPIOD_SSR (IMX_PTD_VBASE + GPIO_SSR_OFFSET) +#define IMX_GPIOD_ICR1 (IMX_PTD_VBASE + GPIO_ICR1_OFFSET) +#define IMX_GPIOD_ICR2 (IMX_PTD_VBASE + GPIO_ICR2_OFFSET) +#define IMX_GPIOD_IMR (IMX_PTD_VBASE + GPIO_IMR_OFFSET) +#define IMX_GPIOD_ISR (IMX_PTD_VBASE + GPIO_ISR_OFFSET) +#define IMX_GPIOD_GPR (IMX_PTD_VBASE + GPIO_GPR_OFFSET) +#define IMX_GPIOD_SWR (IMX_PTD_VBASE + GPIO_SWR_OFFSET) +#define IMX_GPIOD_PUEN (IMX_PTD_VBASE + GPIO_PUEN_OFFSET) + +#define IMX_GPIO_DDIR(n) (IMX_PT_VBASE(n) + GPIO_DDIR_OFFSET) +#define IMX_GPIO_OCR1(n) (IMX_PT_VBASE(n) + GPIO_OCR1_OFFSET) +#define IMX_GPIO_OCR2(n) (IMX_PT_VBASE(n) + GPIO_OCR2_OFFSET) +#define IMX_GPIO_ICONFA1(n) (IMX_PT_VBASE(n) + GPIO_ICONFA1_OFFSET) +#define IMX_GPIO_ICONFA2(n) (IMX_PT_VBASE(n) + GPIO_ICONFA2_OFFSET) +#define IMX_GPIO_ICONFB1(n) (IMX_PT_VBASE(n) + GPIO_ICONFB1_OFFSET) +#define IMX_GPIO_ICONFB2(n) (IMX_PT_VBASE(n) + GPIO_ICONFB2_OFFSET) +#define IMX_GPIO_DR(n) (IMX_PT_VBASE(n) + GPIO_DR_OFFSET) +#define IMX_GPIO_GIUS(n) (IMX_PT_VBASE(n) + GPIO_GIUS_OFFSET) +#define IMX_GPIO_SSR(n) (IMX_PT_VBASE(n) + GPIO_SSR_OFFSET) +#define IMX_GPIO_ICR1(n) (IMX_PT_VBASE(n) + GPIO_ICR1_OFFSET) +#define IMX_GPIO_ICR2(n) (IMX_PT_VBASE(n) + GPIO_ICR2_OFFSET) +#define IMX_GPIO_IMR(n) (IMX_PT_VBASE(n) + GPIO_IMR_OFFSET) +#define IMX_GPIO_ISR(n) (IMX_PT_VBASE(n) + GPIO_ISR_OFFSET) +#define IMX_GPIO_GPR(n) (IMX_PT_VBASE(n) + GPIO_GPR_OFFSET) +#define IMX_GPIO_SWR(n) (IMX_PT_VBASE(n) + GPIO_SWR_OFFSET) +#define IMX_GPIO_PUEN(n) (IMX_PT_VBASE(n) + GPIO_PUEN_OFFSET) + +/* GPIO Register Bit Definitions ****************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_IMX1_IMX_GPIO_H */ + +#ifndef __ASSEMBLY__ + +/* Handler circular include... This file includes up_arch.h, but this file is + * included by up_arch.h (via chip.h) BEFORE getreg32 is defined. + */ + +#if !defined(__ARCH_ARM_IMX_GPIOHELPERS_H) && defined(getreg32) +#define __ARCH_ARM_IMX_GPIOHELPERS_H + +/* Select whether the pin is an input or output */ + +static inline void imxgpio_dirout(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_DDIR(port)); + regval |= (1 << bit); + putreg32(regval, IMX_GPIO_DDIR(port)); +} + +static inline void imxgpio_dirin(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_DDIR(port)); + regval &= ~(1 << bit); + putreg32(regval, IMX_GPIO_DDIR(port)); +} + +/* Select input configuration */ + +static inline void imxgpio_ocrain(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_OCR1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_OCR2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_ocrbin(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_OCR1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_OCR2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (1 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_ocrcin(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_OCR1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_OCR2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (2 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_ocrodrin(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_OCR1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_OCR2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval |= (3 << shift); + putreg32(regval, regaddr); +} + +/* Input configuration */ + +static inline void imxgpio_aoutgpio(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFA1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFA2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_aoutisr(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFA1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFA2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (1 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_aout0(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFA1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFA2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (2 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_aout1(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFA1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFA2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval |= (3 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_boutgpio(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFB1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFB2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_boutisr(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFB1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFB2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (1 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_bout0(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFB1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFB2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval &= ~(3 << shift); + regval |= (2 << shift); + putreg32(regval, regaddr); +} + +static inline void imxgpio_bout1(int port, int bit) +{ + uint32_t regval; + uint32_t regaddr; + int shift; + + if (bit < 16) + { + regaddr = IMX_GPIO_ICONFB1(port); + shift = (bit << 1); + } + else + { + regaddr = IMX_GPIO_ICONFB2(port); + shift = ((bit - 16) << 1); + } + + regval = getreg32(regaddr); + regval |= (3 << shift); + putreg32(regval, regaddr); +} + +/* Select whether the pin is used for its GPIO function or for + * its peripheral function. Also select the primary or alternate + * peripheral function. + */ + +static inline void imxgpio_gpiofunc(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_GIUS(port)); + regval |= (1 << bit); + putreg32(regval, IMX_GPIO_GIUS(port)); +} + +static inline void imxgpio_peripheralfunc(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_GIUS(port)); + regval &= ~(1 << bit); + putreg32(regval, IMX_GPIO_GIUS(port)); +} + +static inline void imxgpio_altperipheralfunc(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_GPR(port)); + regval |= (1 << bit); + putreg32(regval, IMX_GPIO_GPR(port)); +} + +static inline void imxgpio_primaryperipheralfunc(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_GPR(port)); + regval &= ~(1 << bit); + putreg32(regval, IMX_GPIO_GPR(port)); +} + +/* Enable/disable pullups */ + +static inline void imxgpio_pullupenable(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_PUEN(port)); + regval |= (1 << bit); + putreg32(regval, IMX_GPIO_PUEN(port)); +} + +static inline void imxgpio_pullupdisable(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_PUEN(port)); + regval &= ~(1 << bit); + putreg32(regval, IMX_GPIO_PUEN(port)); +} + +static inline void imxgpio_setoutput(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_DR(port)); + regval |= (1 << bit); + putreg32(regval, IMX_GPIO_DR(port)); +} + +static inline void imxgpio_clroutput(int port, int bit) +{ + uint32_t regval = getreg32(IMX_GPIO_DR(port)); + regval &= ~(1 << bit); + putreg32(regval, IMX_GPIO_DR(port)); +} + +/* Useful functions for normal configurations */ + +void imxgpio_configoutput(int port, int bit, int value); +void imxgpio_configinput(int port, int bit); + +void imxgpio_configpfoutput(int port, int bit); +void imxgpio_configpfinput(int port, int bit); + +#endif + +#endif /* __ARCH_ARM_IMX_GPIOHELPERS_H */ diff --git a/arch/arm/src/imx1/imx_i2c.h b/arch/arm/src/imx1/imx_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..b9a3aca661c1bd2373f94f358de5fba0286c24cc --- /dev/null +++ b/arch/arm/src/imx1/imx_i2c.h @@ -0,0 +1,69 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_i2c.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_I2C_H +#define __ARCH_ARM_IMX_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* I2C Register Offsets *************************************************************/ + +#define I2C_IADR_OFFSET 0x0000 +#define I2C_IFDR_OFFSET 0x0004 +#define I2C_I2CR_OFFSET 0x0008 +#define I2C_I2SR_OFFSET 0x000c +#define I2C_I2DR_OFFSET 0x0010 + +/* I2C Register Addresses ***********************************************************/ + +#define IMX_I2C_IADR (IMX_I2C_VBASE + I2C_IADR_OFFSET) +#define IMX_I2C_IFDR (IMX_I2C_VBASE + I2C_IFDR_OFFSET) +#define IMX_I2C_I2CR (IMX_I2C_VBASE + I2C_I2CR_OFFSET) +#define IMX_I2C_I2SR (IMX_I2C_VBASE + I2C_I2SR_OFFSET) +#define IMX_I2C_I2DR (IMX_I2C_VBASE + I2C_I2DR_OFFSET) + +/* I2C Register Bit Definitions *****************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_I2C_H */ diff --git a/arch/arm/src/imx1/imx_irq.c b/arch/arm/src/imx1/imx_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..038a60ad647b9c3731f9cf9d3ccc6abcf7e5fc49 --- /dev/null +++ b/arch/arm/src/imx1/imx_irq.c @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/arm/src/imc/imx_irq.c + * arch/arm/src/chip/imx_irq.c + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Clear, disable and configure all interrupts. */ + + putreg32(0, IMX_AITC_INTENABLEH); + putreg32(0, IMX_AITC_INTENABLEL); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Set masking of normal interrupts by priority. Writing all ones + * (or -1) to the NIMASK register sets the normal interrupt mask to + * -1 and does not disable any normal interrupt priority levels. + */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + putreg32(-1, IMX_AITC_NIMASK); /* -1: No priority levels masked */ + + /* Initialize FIQs */ + +#ifdef CONFIG_ARCH_FIQ + up_fiqinitialize(); +#endif + + /* And finally, enable interrupts */ + + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + putreg32(irq, IMX_AITC_INTDISNUM); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + putreg32(irq, IMX_AITC_INTENNUM); +} diff --git a/arch/arm/src/imx1/imx_lowputc.S b/arch/arm/src/imx1/imx_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..6eae14ac9d531d483ceb44acfc1d5c42dba95cf7 --- /dev/null +++ b/arch/arm/src/imx1/imx_lowputc.S @@ -0,0 +1,130 @@ +/************************************************************************** + * arch/arm/src/imx1/imx_lowputc.S + * arch/arm/src/chip/imx_lowputc.S + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + ldr r2, =IMX_UART1_VBASE /* r2=UART1 base */ +#else + ldr r2, =IMX_UART2_VBASE /* r2=UART0 base */ +#endif + + /* Poll the TX fifo trigger level bit of the UART status register #2 . + * When the bit is non-zero, the TX Buffer FIFO is empty. + */ + +1: ldr r1, [r2, #UART_USR2] + tst r1, #UART_USR2_TXFE + beq 1b + + /* Send the character by writing it into the UART_DTRR + * register. + */ + + str r0, [r2, #UART_TXD0] + + /* If the character that we just sent was a linefeed, + * then send a carriage return as well. + */ + + teq r0, #'\n' + moveq r0, #'\r' + beq 1b + + /* Wait for the tranmsit regiser to be emptied. When the bit is + * non-zero, the TX Buffer FIFO is empty. + */ + +2: ldrh r1, [r2, #UART_USR2] + tst r1, #UART_USR2_TXFE + beq 2b + + /* Then return */ + + mov pc, lr + .end + diff --git a/arch/arm/src/imx1/imx_memorymap.h b/arch/arm/src/imx1/imx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..9db13245567a083e01e2cd2c80e9b66bd2eb6165 --- /dev/null +++ b/arch/arm/src/imx1/imx_memorymap.h @@ -0,0 +1,259 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_memorymap.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_MEMORYMAP_H +#define __ARCH_ARM_IMX_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "arm.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Physical Memory Map **************************************************************/ + + /* -0x000fffff Double Map Image 1Mb */ + /* -0x001fffff Bootstrap ROM 1Mb */ +#define IMX_PERIPHERALS_PSECTION 0x00200000 /* -0x002fffff Peripherals 1Mb */ +#define IMX_ESRAM_PSECTION 0x00300000 /* -0x003fffff Embedded SRAM 128Kb */ +#define IMX_SDRAM0_PSECTION 0x08000000 /* -0x0bffffff SDRAM0 (CSD0) 64Mb */ +#define IMX_SDRAM1_PSECTION 0x0c000000 /* -0x0fffffff SDRAM1 (CSD1) 64Mb */ +#define IMX_FLASH_PSECTION 0x10000000 /* -0x11ffffff FLASH (CS0) 32Mb */ +#define IMX_CS1_PSECTION 0x12000000 /* -0x12ffffff CS1 16Mb */ +#define IMX_CS2_PSECTION 0x13000000 /* -0x13ffffff CS2 16Mb */ +#define IMX_CS3_PSECTION 0x14000000 /* -0x14ffffff CS3 16Mb */ +#define IMX_CS4_PSECTION 0x15000000 /* -0x15ffffff CS4 16Mb */ +#define IMX_CS5_PSECTION 0x16000000 /* -0x16ffffff CS5 16Mb */ + +/* Sizes of Address Sections ********************************************************/ + +/* Mapped sections */ +#define IMX_PERIPHERALS_NSECTIONS 1 /* 1Mb 1 section */ +#define IMX_SDRAM0_NSECTIONS 16 /* 16Mb Based on CONFIG_RAM_SIZE */ +#define IMX_SDRAM1_NSECTIONS 0 /* 64Mb (Not mapped) */ +#define IMX_FLASH_NSECTIONS 32 /* 64Mb Based on CONFIG_FLASH_SIZE */ +#define IMX_CS1_NSECTIONS 16 /* 16Mb */ +#define IMX_CS2_NSECTIONS 16 /* 16Mb */ +#define IMX_CS3_NSECTIONS 16 /* 16Mb */ +#define IMX_CS4_NSECTIONS 16 /* 16Mb */ +#define IMX_CS5_NSECTIONS 16 /* 16Mb */ + +/* Virtual Memory Map ***************************************************************/ + +/* There are three operational memory configurations: + * + * 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case: + * + * - Our vectors must be located at the beginning of FLASH and will + * also be mapped to address zero (because of the i.MX's "double map image." + * - All vector addresses are FLASH absolute addresses, + * - DRAM cannot reside at address zero, + * - Vectors at address zero (CR_V is not set), + * - The boot logic must configure SDRAM and, + * - The .data section in RAM must be initialized. + * + * 2. We boot in FLASH but copy ourselves to DRAM from better performance. + * (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case: + * + * - Our code image is in FLASH and we boot to FLASH initially, then copy + * ourself to DRAM, + * - DRAM will be mapped to address zero, + * - The RESET vector is a FLASH absolute address, + * - All other vectors are absulte and reference functions in the final mapped SDRAM address + * - Vectors at address zero (CR_V is not set), and + * - The boot logic must configure SDRAM. + * + * 3. There is bootloader that copies us to DRAM, but probably not to the beginning + * of DRAM (say to 0x0900:0000) (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). + * In this case: + * + * - DRAM will be mapped to address zero, + * - Interrupt vectors will be copied to address zero, + * - Memory between the end of the vector area (say 0x0800:0400) and the beginning + * of the page table (0x0900:0000) will be given to the memory manager as a second + * memory region, + * - All vectors are absulte and reference functions in the final mapped SDRAM address + * - Vectors at address zero (CR_V is not set), and + * - We must assume that the bootloader has configured SDRAM. + */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Use the identity mapping */ + +# define IMX_SDRAM_VSECTION 0x08000000 /* -(+CONFIG_RAM_SIZE) */ +#else + /* Map SDRAM to address zero */ + +# define IMX_SDRAM_VSECTION 0x00000000 /* -(+CONFIG_RAM_SIZE) */ +#endif + +/* We use a identity mapping for other regions */ + +#define IMX_PERIPHERALS_VSECTION 0x00200000 /* -0x002fffff 1Mb */ +#define IMX_FLASH_VSECTION 0x10000000 /* -(+CONFIG_FLASH_SIZE) */ +#define IMX_CS1_VSECTION 0x12000000 /* -0x12ffffff CS1 32Mb */ +#define IMX_CS2_VSECTION 0x13000000 /* -0x13ffffff CS2 32Mb */ +#define IMX_CS3_VSECTION 0x14000000 /* -0x14ffffff CS3 32Mb */ +#define IMX_CS4_VSECTION 0x15000000 /* -0x15ffffff CS4 32Mb */ +#define IMX_CS5_VSECTION 0x16000000 /* -0x16ffffff CS5 32Mb */ + +/* In any event, the vector base address is 0x0000:0000 */ + +#define VECTOR_BASE 0x00000000 + +/* Peripheral Register Offsets ******************************************************/ + +#define IMX_AIPI1_OFFSET 0x00000000 /* -0x00000fff AIPI1 4Kb */ +#define IMX_WDOG_OFFSET 0x00001000 /* -0x00001fff WatchDog 4Kb */ +#define IMX_TIMER1_OFFSET 0x00002000 /* -0x00002fff Timer1 4Kb */ +#define IMX_TIMER2_OFFSET 0x00003000 /* -0x00003fff Timer2 4Kb */ +#define IMX_RTC_OFFSET 0x00004000 /* -0x00004fff RTC 4Kb */ +#define IMX_LCDC_OFFSET 0x00005000 /* -0x00005fff LCD 4Kb */ +#define IMX_LCDC_COLORMAP 0x00005800 +#define IMX_UART1_OFFSET 0x00006000 /* -0x00006fff UART1 4Kb */ +#define IMX_UART2_OFFSET 0x00007000 /* -0x00007fff UART2 4Kb */ +#define IMX_PWM1_OFFSET 0x00008000 /* -0x00008fff PWM 4Kb */ +#define IMX_DMA_OFFSET 0x00009000 /* -0x00009fff DMA 4Kb */ +#define IMX_UART3_OFFSET 0x0000a000 /* -0x0000afff UART3 4Kb */ + /* -0x0000ffff Reserved 20Kb */ +#define IMX_AIPI2_OFFSET 0x00010000 /* -0x00010fff AIPI2 4Kb */ +#define IMX_SIM_OFFSET 0x00011000 /* -0x00011fff SIM 4Kb */ +#define IMX_USBD_OFFSET 0x00012000 /* -0x00012fff USBD 4Kb */ +#define IMX_CSPI1_OFFSET 0x00013000 /* -0x00013fff CSPI1 4Kb */ +#define IMX_MMC_OFFSET 0x00014000 /* -0x00014fff MMC 4Kb */ +#define IMX_ASP_OFFSET 0x00015000 /* -0x00015fff ASP 4Kb */ +#define IMX_BTA_OFFSET 0x00016000 /* -0x00016fff BTA 4Kb */ +#define IMX_I2C_OFFSET 0x00017000 /* -0x00017fff I2C 4Kb */ +#define IMX_SSI_OFFSET 0x00018000 /* -0x00018fff SSI 4Kb */ +#define IMX_CSPI2_OFFSET 0x00019000 /* -0x00019fff CSPI2 4Kb */ +#define IMX_MSHC_OFFSET 0x0001a000 /* -0x0001afff Memory Stick 4Kb */ +#define IMX_CRM_OFFSET 0x0001b000 /* -0x0001bfff CRM 4Kb */ +#define IMX_PLL_OFFSET 0x0001b000 +#define IMX_SC_OFFSET 0x0001b800 +#define IMX_GPIO_OFFSET 0x0001c000 /* -0x0001cfff GPIO 4Kb */ + /* -0x0001ffff Reserved 12Kb */ +#define IMX_EIM_OFFSET 0x00020000 /* -0x00020fff EIM 4Kb */ +#define IMX_SDRAMC_OFFSET 0x00021000 /* -0x00021fff SDRAMC 4Kb */ +#define IMX_DSPA_OFFSET 0x00022000 /* -0x00022fff DSPA 4Kb */ +#define IMX_AITC_OFFSET 0x00023000 /* -0x00023fff AITC 4Kb */ +#define IMX_CSI_OFFSET 0x00024000 /* -0x00024fff CSI 4Kb */ + /* -0x000fffff Reserved 876Kb */ + +/* Peripheral Register Offsets ******************************************************/ + +#define IMX_AIPI1_VBASE (IMX_PERIPHERALS_VSECTION + IMX_AIPI1_OFFSET) +#define IMX_WDOG_VBASE (IMX_PERIPHERALS_VSECTION + IMX_WDOG_OFFSET) +#define IMX_TIMER1_VBASE (IMX_PERIPHERALS_VSECTION + IMX_TIMER1_OFFSET) +#define IMX_TIMER2_VBASE (IMX_PERIPHERALS_VSECTION + IMX_TIMER2_OFFSET) +#define IMX_RTC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_RTC_OFFSET) +#define IMX_LCDC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_LCDC_OFFSET) +#define IMX_LCDC_COLORMAP_VBASE (IMX_PERIPHERALS_VSECTION + IMX_LCDC_COLORMAP) +#define IMX_UART1_VBASE (IMX_PERIPHERALS_VSECTION + IMX_UART1_OFFSET) +#define IMX_UART2_VBASE (IMX_PERIPHERALS_VSECTION + IMX_UART2_OFFSET) +#define IMX_PWM1_VBASE (IMX_PERIPHERALS_VSECTION + IMX_PWM1_OFFSET) +#define IMX_DMA_VBASE (IMX_PERIPHERALS_VSECTION + IMX_DMA_OFFSET) +#define IMX_UART3_VBASE (IMX_PERIPHERALS_VSECTION + IMX_UART3_OFFSET) +#define IMX_AIP2_VBASE (IMX_PERIPHERALS_VSECTION + IMX_AIPI2_OFFSET) +#define IMX_SIM_VBASE (IMX_PERIPHERALS_VSECTION + IMX_SIM_OFFSET) +#define IMX_USBD_VBASE (IMX_PERIPHERALS_VSECTION + IMX_USBD_OFFSET) +#define IMX_CSPI1_VBASE (IMX_PERIPHERALS_VSECTION + IMX_CSPI1_OFFSET) +#define IMX_MMC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_MMC_OFFSET) +#define IMX_ASP_VBASE (IMX_PERIPHERALS_VSECTION + IMX_ASP_OFFSET) +#define IMX_BTA_VBASE (IMX_PERIPHERALS_VSECTION + IMX_BTA_OFFSET) +#define IMX_I2C_VBASE (IMX_PERIPHERALS_VSECTION + IMX_I2C_OFFSET) +#define IMX_SSI_VBASE (IMX_PERIPHERALS_VSECTION + IMX_SSI_OFFSET) +#define IMX_CSPI2_VBASE (IMX_PERIPHERALS_VSECTION + IMX_CSPI2_OFFSET) +#define IMX_MSHC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_MSHC_OFFSET) +#define IMX_CRM_VBASE (IMX_PERIPHERALS_VSECTION + IMX_CRM_OFFSET) +#define IMX_PLL_VBASE (IMX_PERIPHERALS_VSECTION + IMX_PLL_OFFSET) +#define IMX_SC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_SC_OFFSET) +#define IMX_GPIO_VBASE (IMX_PERIPHERALS_VSECTION + IMX_GPIO_OFFSET) +#define IMX_EIM_VBASE (IMX_PERIPHERALS_VSECTION + IMX_EIM_OFFSET) +#define IMX_SDRAMC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_SDRAMC_OFFSET) +#define IMX_DSPA_VBASE (IMX_PERIPHERALS_VSECTION + IMX_DSPA_OFFSET) +#define IMX_AITC_VBASE (IMX_PERIPHERALS_VSECTION + IMX_AITC_OFFSET) +#define IMX_CSI_VBASE (IMX_PERIPHERALS_VSECTION + IMX_CSI_OFFSET) + +/* Memory Mapping Info **************************************************************/ + +/* The NuttX entry point starts at an offset from the virtual beginning of DRAM. + * This offset reserves space for the MMU page cache. + */ + +#define NUTTX_START_VADDR ((CONFIG_RAM_NUTTXENTRY & 0xfff00000) | PGTABLE_SIZE) +#define NUTTX_START_PADDR (IMX_SDRAM0_PSECTION | PGTABLE_SIZE) + +#if NUTTX_START_VADDR != CONFIG_RAM_NUTTXENTRY +# error "CONFIG_RAM_NUTTXENTRY does not have correct offset for page table" +#endif + +/* Section MMU Flags */ + +#define IMX_FLASH_MMUFLAGS MMU_IOFLAGS +#define IMX_PERIPHERALS_MMUFLAGS MMU_IOFLAGS + +/* 16Kb of memory is reserved at the beginning of SDRAM to hold the + * page table for the virtual mappings. A portion of this table is + * not accessible in the virtual address space (for normal operation). + * We will reuse this memory for coarse page tables as follows: + */ + +#define PGTABLE_BASE_PADDR IMX_SDRAM0_PSECTION +#define PGTABLE_SDRAM_PADDR PGTABLE_BASE_PADDR +#define PGTABLE_COARSE_PBASE (PGTABLE_BASE_PADDR+0x00000800) +#define PGTABLE_COARSE_PEND (PGTABLE_BASE_PADDR+0x00003000) +#define PTTABLE_PERIPHERALS_PBASE (PGTABLE_BASE_PADDR+0x00003000) +#define PGTABLE_PEND (PGTABLE_BASE_PADDR+0x00004000) + +#define PGTABLE_BASE_VADDR IMX_SDRAM_VSECTION +#define PGTABLE_SDRAM_VADDR PGTABLE_BASE_VADDR +#define PGTABLE_COARSE_VBASE (PGTABLE_BASE_VADDR+0x00000800) +#define PGTABLE_COARSE_VEND (PGTABLE_BASE_VADDR+0x00003000) +#define PTTABLE_PERIPHERALS_VBASE (PGTABLE_BASE_VADDR+0x00003000) +#define PGTABLE_VEND (PGTABLE_BASE_VADDR+0x00004000) + +#define PGTABLE_COARSE_TABLE_SIZE (4*256) +#define PGTABLE_COARSE_ALLOC (PGTABLE_COARSE_VEND-PGTABLE_COARSE_VBASE) +#define PGTABLE_NCOARSE_TABLES (PGTABLE_COARSE_SIZE / PGTBALE_COARSE_TABLE_ALLOC) + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_MEMORYMAP_H */ diff --git a/arch/arm/src/imx1/imx_rtc.h b/arch/arm/src/imx1/imx_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..44341192302f2107f9c8762ab992002ed5bcaf60 --- /dev/null +++ b/arch/arm/src/imx1/imx_rtc.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_rtc.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_RTC_H +#define __ARCH_ARM_IMX_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* RTC Register Offsets *************************************************************/ + +#define RTC_HOURMIN_OFFSET 0x0000 +#define RTC_SECOND_OFFSET 0x0004 +#define RTC_ALRM_HM_OFFSET 0x0008 +#define RTC_ALRM_SEC_OFFSET 0x000c +#define RTC_RTCCTL_OFFSET 0x0010 +#define RTC_RTCISR_OFFSET 0x0014 +#define RTC_RTCIENR_OFFSET 0x0018 +#define RTC_STPWCH_OFFSET 0x001c +#define RTC_DAYR_OFFSET 0x0020 +#define RTC_DAYALARM_OFFSET 0x0024 +#define RTC_TEST1_OFFSET 0x0028 +#define RTC_TEST2_OFFSET 0x002c +#define RTC_TEST3_OFFSET 0x0030 + +/* RTC Register Addresses ***********************************************************/ + +#define IMX_RTC_HOURMIN (IMX_RTC_VBASE + RTC_HOURMIN_OFFSET) +#define IMX_RTC_SECOND (IMX_RTC_VBASE + RTC_SECOND_OFFSET) +#define IMX_RTC_ALRM_HM (IMX_RTC_VBASE + RTC_ALRM_HM_OFFSET) +#define IMX_RTC_ALRM_SEC (IMX_RTC_VBASE + RTC_ALRM_SEC_OFFSET) +#define IMX_RTC_RTCCTL (IMX_RTC_VBASE + RTC_RTCCTL_OFFSET) +#define IMX_RTC_RTCISR (IMX_RTC_VBASE + RTC_RTCISR_OFFSET) +#define IMX_RTC_RTCIENR (IMX_RTC_VBASE + RTC_RTCIENR_OFFSET) +#define IMX_RTC_STPWCH (IMX_RTC_VBASE + RTC_STPWCH_OFFSET) +#define IMX_RTC_DAYR (IMX_RTC_VBASE + RTC_DAYR_OFFSET) +#define IMX_RTC_DAYALARM (IMX_RTC_VBASE + RTC_DAYALARM_OFFSET) +#define IMX_RTC_TEST1 (IMX_RTC_VBASE + RTC_TEST1_OFFSET) +#define IMX_RTC_TEST2 (IMX_RTC_VBASE + RTC_TEST2_OFFSET) +#define IMX_RTC_TEST3 (IMX_RTC_VBASE + RTC_TEST3_OFFSET) + +/* RTC Register Bit Definitions *****************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_RTC_H */ diff --git a/arch/arm/src/imx1/imx_serial.c b/arch/arm/src/imx1/imx_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..e3826192b22433a46464f3b70086c537a682af32 --- /dev/null +++ b/arch/arm/src/imx1/imx_serial.c @@ -0,0 +1,1306 @@ +/**************************************************************************** + * arch/arm/src/imx1/imx_serial.c + * arch/arm/src/chip/imx_serial.c + * + * Copyright (C) 2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "imx_gpio.h" +#include "up_internal.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* The i.MXL chip has only two UARTs */ + +#if defined(CONFIG_ARCH_CHIP_IMXL) && defined(CONFIG_IMX1_UART3) +# undef CONFIG_IMX1_UART3 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ucr1; /* Saved UCR1 value */ +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + uint8_t rxirq; /* Rx IRQ associated with this UART */ + uint8_t txirq; /* Tx IRQ associated with this UART */ +#else + uint8_t irq; /* IRQ associated with this UART */ +#endif + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + uint8_t stopbits2:1; /* 1: Configure with 2 stop bits vs 1 */ + uint8_t hwfc:1; /* 1: Hardware flow control */ + uint8_t reserved:6; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, uint32_t offset); +static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value); +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ucr1); +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ucr1); +static inline void up_waittxready(struct up_dev_s *priv); + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static inline struct uart_dev_s *up_mapirq(int irq); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_IMX1_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX1_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX1_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif + +/* This describes the state of the IMX uart1 port. */ + +#ifdef CONFIG_IMX1_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = IMX_UART1_VBASE, + .baud = CONFIG_UART1_BAUD, +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + .rxirq = IMX_IRQ_UART1RX, + .txirq = IMX_IRQ_UART1TX, +#else + .irq = IMX_IRQ_UART1, +#endif + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static struct uart_dev_s g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the IMX uart2 port. */ + +#ifdef CONFIG_IMX1_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = IMX_UART2_VBASE, + .baud = CONFIG_UART2_BAUD, +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + .rxirq = IMX_IRQ_UART2RX, + .txirq = IMX_IRQ_UART2TX, +#else + .irq = IMX_IRQ_UART2, +#endif + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static struct uart_dev_s g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +#ifdef CONFIG_IMX1_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = IMX_UART3_REGISTER_BASE, + .baud = IMX_UART3_VBASE, +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + .rxirq = IMX_IRQ_UART3RX, + .txirq = IMX_IRQ_UART3TX, +#else + .irq = IMX_IRQ_UART3, +#endif + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static struct uart_dev_s g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* Now, which one with be tty0/console and which tty1 and tty2? */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_IMX1_UART1) +# define CONSOLE_DEV g_uart1port /* UART1 is /dev/console */ +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define TTYS0_DEV g_uart1port /* UART1 is /dev/ttyS0 */ +# if defined(CONFIG_IMX1_UART2) +# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */ +# if defined(CONFIG_IMX1_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */ +# else +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif +# elif defined(CONFIG_IMX1_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# else +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif + +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_IMX1_UART2) +# define CONSOLE_DEV g_uart2port /* UART2 is /dev/console */ +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define TTYS0_DEV g_uart2port /* UART2 is /dev/ttyS0 */ +# if defined(CONFIG_IMX1_UART1) +# define TTYS1_DEV g_uart1port /* UART1 is /dev/ttyS1 */ +# if defined(CONFIG_IMX1_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */ +# else +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif +# elif defined(CONFIG_IMX1_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is /dev/ttyS1 */ +# else +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif + +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_IMX1_UART3) +# define CONSOLE_DEV g_uart3port /* UART3 is /dev/console */ +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define TTYS0_DEV g_uart3port /* UART3 is /dev/ttyS0 */ +# if defined(CONFIG_IMX1_UART1) +# define TTYS1_DEV g_uart1port /* UART1 is /dev/ttyS1 */ +# if defined(CONFIG_IMX1_UART2) +# define TTYS2_DEV g_uart2port /* UART2 is /dev/ttyS2 */ +# else +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif +# elif defined(CONFIG_IMX1_UART2) +# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# else +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif + +#else +# undef CONSOLE_DEV g_uart1port /* No /dev/console */ +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE + +# if defined(CONFIG_IMX1_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is /dev/ttyS0 */ +# if defined(CONFIG_IMX1_UART2) +# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */ +# if defined(CONFIG_IMX1_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is /dev/ttyS2 */ +# else +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif +# elif defined(CONFIG_IMX1_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# else +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif + +# elif defined(CONFIG_IMX1_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is /dev/ttyS0 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# if defined(CONFIG_IMX1_UART3) +# define TTYS1_DEV g_uart2port /* UART2 is /dev/ttyS1 */ +# else +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# endif + +# elif defined(CONFIG_IMX1_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is /dev/ttyS0 */ +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ + +# else +# error "No UARTs enabled" +# undef TTYS0_DEV /* No /dev/ttyS0 */ +# undef TTYS1_DEV /* No /dev/ttyS1 */ +# undef TTYS2_DEV /* No /dev/ttyS2 */ +# endif +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, uint32_t offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ucr1) +{ + /* Return the current Rx and Tx interrupt state */ + + if (ucr1) + { + *ucr1 = priv->ucr1 & (UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + } + + /* Then disable both Rx and Tx interrupts */ + + priv->ucr1 &= ~(UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + up_serialout(priv, UART_UCR1, priv->ucr1); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ucr1) +{ + /* Enable/disable any interrupts that are currently disabled but should be + * enabled/disabled. + */ + + priv->ucr1 &= ~(UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + priv->ucr1 |= ucr1 & (UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + up_serialout(priv, UART_UCR1, priv->ucr1); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((up_serialin(priv, UART_UTS) & UART_UTS_TXFULL) == 0) + { + break; + } + } +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint64_t tmp; + uint32_t regval; + uint32_t ucr2; + uint32_t refclk; + uint32_t div; + uint32_t num; + uint32_t den; + b16_t ratio; + + /* Disable the UART */ + + up_serialout(priv, UART_UCR1, 0); + up_serialout(priv, UART_UCR2, 0); + up_serialout(priv, UART_UCR3, 0); + up_serialout(priv, UART_UCR4, 0); + + /* Set up UCR2 */ + + ucr2 = up_serialin(priv, UART_UCR2); + ucr2 |= (UART_UCR2_SRST | UART_UCR2_IRTS) + + /* Select the number of data bits */ + + DEBUGASSERT(priv->bits == 7 || priv->bits == 8); + if (priv->bits == 8) + { + ucr2 |= UART_UCR2_WS; + } + + /* Select the number of stop bits */ + + if (priv->stopbits2) + { + ucr2 |= UART_UCR2_STPB; + } + + /* Select even/odd parity */ + + if (priv->parity) + { + DEBUGASSERT(priv->parity == 1 || priv->parity == 2); + ucr2 |= UART_UCR2_PREN; + if (priv->parity == 1) + { + ucr2 |= UART_UCR2_PROE; + } + } + + /* Setup hardware flow control */ + + regval = 0; + +#if 0 + if (priv->hwfc) + { + /* Don't ignore RTS */ + + ucr2 &= ~UART_UCR2_IRTS; + + /* CTS controled by Rx FIFO */ + + ucr2 |= UART_UCR2_CTSC; + + /* Set CTS trigger level */ + + regval |= 30 << UART_UCR4_CTSTL_SHIFT; + } +#endif + + /* i.MX reference clock (PERCLK1) is configured for 16MHz */ + + up_serialout(priv, UART_UCR4, regval | UART_UCR4_REF16); + + /* Setup the new UART configuration */ + + up_serialout(priv, UART_UCR2, ucr2); + + /* Select a reference clock divider. + * REVISIT: For now we just use a divider of 3. That might not be + * optimal for very high or very low baud settings. + */ + + div = 3; + refclk = (IMX_PERCLK1_FREQ / 3); + + /* Set the baud. + * + * baud = REFFREQ / (16 * NUM/DEN) + * baud = REFFREQ / 16 / RATIO + * RATIO = REFREQ / 16 / baud; + * + * NUM = SCALE * RATIO + * DEN = SCALE + * + * UMBR = NUM-1 + * UBIR = DEN-1; + */ + + tmp = ((uint64_t)refclk << (16 - 4)) / config->baud; + DEBUGASSERT(tmp < 0x0000000100000000LL); + ratio = (b16_t)tmp; + + /* Pick a scale factor that gives us about 14 bits of accuracy. + * REVISIT: Why not go all the way to 16-bits? + */ + + if (ratio < b16HALF) + { + den = (1 << 15); + num = b16toi(ratio << 15); + DEBUGASSERT(num > 0); + } + else if (ratio < b16ONE) + { + den = (1 << 14); + num = b16toi(ratio << 14); + } + else if (ratio < itob16(2)) + { + den = (1 << 13); + num = b16toi(ratio << 13); + } + else if (ratio < itob16(4)) + { + den = (1 << 12); + num = b16toi(ratio << 12); + } + else if (ratio < itob16(8)) + { + den = (1 << 11); + num = b16toi(ratio << 11); + } + else if (ratio < itob16(16)) + { + den = (1 << 10); + num = b16toi(ratio << 10); + } + else if (ratio < itob16(32)) + { + den = (1 << 9); + num = b16toi(ratio << 9); + } + else if (ratio < itob16(64)) + { + den = (1 << 8); + num = b16toi(ratio << 8); + } + else if (ratio < itob16(128)) + { + den = (1 << 7); + num = b16toi(ratio << 7); + } + else if (ratio < itob16(256)) + { + den = (1 << 6); + num = b16toi(ratio << 6); + } + else if (ratio < itob16(512)) + { + den = (1 << 5); + num = b16toi(ratio << 5); + } + else if (ratio < itob16(1024)) + { + den = (1 << 4); + num = b16toi(ratio << 4); + } + else if (ratio < itob16(2048)) + { + den = (1 << 3); + num = b16toi(ratio << 3); + } + else if (ratio < itob16(4096)) + { + den = (1 << 2); + num = b16toi(ratio << 2); + } + else if (ratio < itob16(8192)) + { + den = (1 << 1); + num = b16toi(ratio << 1); + } + else /* if (ratio < itob16(16384)) */ + { + DEBUGASSERT(ratio < itob16(16384)); + den = (1 << 0); + num = b16toi(ratio); + } + + /* Reduce if possible without losing accuracy. */ + + while ((num & 1) == 0 && (den & 1) == 0) + { + num >>= 1; + den >>= 1; + } + + /* The actual values are we write to the registers need to be + * decremented by 1. NOTE that the UBIR must be set before + * the UBMR. + */ + + up_serialout(priv, UART_UBIR, den - 1); + up_serialout(priv, UART_UBMR, num - 1); + + /* Fixup the divisor, the value in the UFCR regiser is + * + * 000 = Divide input clock by 6 + * 001 = Divide input clock by 5 + * 010 = Divide input clock by 4 + * 011 = Divide input clock by 3 + * 100 = Divide input clock by 2 + * 101 = Divide input clock by 1 + * 110 = Divide input clock by 7 + */ + + if (div == 7) + { + div = 6; + } + else + { + div = 6 - div; + } + regval = div << UART_UFCR_RFDIV_SHIFT; + + /* Set the TX trigger level to interrupt when the TxFIFO has 2 or fewer characters. + * Set the RX trigger level to interrupt when the RxFIFO has 1 character. + */ + + regval |= ((2 << UART_UFCR_TXTL_SHIFT) | (1 << UART_UFCR_RXTL_SHIFT)); + up_serialout(priv, UART_UFCR, regval); + + /* Initialize the UCR1 shadow register */ + + priv->ucr1 = up_serialin(priv, UART_UCR1); + + /* Enable the UART + * + * UART_UCR1_UARTCLEN = Enable UART clocking + */ + + ucr2 |= (UART_UCR2_TXEN | UART_UCR2_RXEN); + up_serialout(priv, UART_UCR1, ucr2); + + priv->ucr1 |= UART_UCR1_UARTCLEN; + up_serialout(priv, UART_UCR1, priv->ucr1); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable the UART */ + + up_serialout(priv, UART_UCR1, 0); + up_serialout(priv, UART_UCR2, 0); + up_serialout(priv, UART_UCR3, 0); + up_serialout(priv, UART_UCR4, 0); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + ret = irq_attach(priv->rxirq, up_interrupt); + if (ret < 0) + { + return ret; + } + + ret = irq_attach(priv->txirq, up_interrupt); + if (ret < 0) + { + irq_detach(priv->rxirq); + return ret; + } + + /* Enable the interrupts (interrupts are still disabled in the UART) */ + + up_enable_irq(priv->rxirq); + up_enable_irq(priv->txirq); + +#else + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } +#endif + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + up_disable_irq(priv->rxirq); + up_disable_irq(priv->txirq); + irq_detach(priv->rxirq); + irq_detach(priv->txirq); +#else + up_disable_irq(priv->irq); + irq_detach(priv->irq); +#endif +} + +/**************************************************************************** + * Name: up_mapirq + * + * Description: + * Map an IRQ number to internal UART state structure + * + ****************************************************************************/ + +static inline struct uart_dev_s *up_mapirq(int irq) +{ + struct uart_dev_s *dev; + + switch (irq) + { +#ifdef CONFIG_IMX1_UART1 +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + case IMX_IRQ_UART1RX: + case IMX_IRQ_UART1TX: +#else + case IMX_IRQ_UART1: +#endif + dev = &g_uart1port; + break; +#endif + +#ifdef CONFIG_IMX1_UART2 +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + case IMX_IRQ_UART2RX: + case IMX_IRQ_UART2TX: +#else + case IMX_IRQ_UART2: +#endif + dev = &g_uart2port; + break; +#endif + +#ifdef CONFIG_IMX1_UART3 +#if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) + case IMX_IRQ_UART3RX: + case IMX_IRQ_UART3TX: +#else + case IMX_IRQ_UART3: +#endif + dev = &g_uart3port; + break; +#endif + + default: + PANIC(); + break; + } + return dev; +} + +/**************************************************************************** + * Name: up_interrupt (and front-ends) + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev; + struct up_dev_s *priv; + uint32_t usr1; + int passes = 0; + + dev = up_mapirq(irq); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (; ; ) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + usr1 = up_serialin(priv, UART_USR1); + usr1 &= (UART_USR1_RRDY | UART_USR1_TRDY); + + if (usr1 == 0 || passes > 256) + { + return OK; + } + + /* Handline incoming, receive bytes */ + + if (usr1 & UART_USR1_RRDY) + { + uart_recvchars(dev); + } + + /* Handle outgoing, transmit bytes */ + + if (usr1 & UART_USR1_TRDY && + (up_serialin(priv, UART_UCR1) & UART_UCR1_TXEMPTYEN) != 0) + { + uart_xmitchars(dev); + } + + /* Keep track of how many times we do this in case there + * is some hardware failure condition. + */ + + passes++; + } +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rxd0; + + rxd0 = up_serialin(priv, UART_RXD0); + *status = rxd0; + return (rxd0 & UART_RXD_DATA_MASK) >> UART_RXD_DATA_SHIFT; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Enable interrupts for data availab at Rx FIFO */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ucr1 |= UART_UCR1_RRDYEN; +#endif + } + else + { + priv->ucr1 &= ~UART_UCR1_RRDYEN; + } + up_serialout(priv, UART_UCR1, priv->ucr1); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is ready in the Rx FIFO */ + + return ((up_serialin(priv, UART_USR2) & UART_USR2_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_TXD0, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* We won't take an interrupt until the FIFO is completely empty (although + * there may still be a transmission in progress). + */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ucr1 |= UART_UCR1_TXEMPTYEN; +#endif + } + else + { + priv->ucr1 &= ~UART_UCR1_TXEMPTYEN; + } + up_serialout(priv, UART_UCR1, priv->ucr1); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* When TXFULL is set, there is no space in the Tx FIFO */ + + return ((up_serialin(priv, UART_UTS) & UART_UTS_TXFULL) == 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* When TXDC is set, the FIFO is empty and the transmission is complete */ + + return ((up_serialin(priv, UART_USR2) & UART_USR2_TXDC) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Configure and disable the UART1 */ + +#ifdef CONFIG_IMX1_UART1 + up_serialout(&g_uart1priv, UART_UCR1, 0); + up_serialout(&g_uart1priv, UART_UCR2, 0); + + /* Configure UART1 pins: RXD, TXD, RTS, and CTS */ + + imxgpio_configpfoutput(GPIOC, 9); /* Port C, pin 9: CTS */ + imxgpio_configpfinput(GPIOC, 10); /* Port C, pin 10: RTS */ + imxgpio_configpfoutput(GPIOC, 11); /* Port C, pin 11: TXD */ + imxgpio_configpfinput(GPIOC, 12); /* Port C, pin 12: RXD */ +#endif + + /* Configure and disable the UART2 */ + +#ifdef CONFIG_IMX1_UART2 + up_serialout(&g_uart2priv, UART_UCR1, 0); + up_serialout(&g_uart2priv, UART_UCR2, 0); + + /* Configure UART2 pins: RXD, TXD, RTS, and CTS (only, also + * supports DTR, DCD, RI, and DSR -- not configured) + */ + + imxgpio_configpfoutput(GPIOB, 28); /* Port B, pin 28: CTS */ + imxgpio_configpfinput(GPIOB, 29); /* Port B, pin 29: RTS */ + imxgpio_configpfoutput(GPIOB, 30); /* Port B, pin 30: TXD */ + imxgpio_configpfinput(GPIOB, 31); /* Port B, pin 31: RXD */ +#endif + + /* Configure and disable the UART3 */ + +#ifdef CONFIG_IMX1_UART3 + up_serialout(&g_uart3priv, UART_UCR1, 0); + up_serialout(&g_uart3priv, UART_UCR2, 0); + + /* Configure UART2 pins: RXD, TXD, RTS, and CTS (only, also + * supports DTR, DCD, RI, and DSR -- not configured) + */ + + imxgpio_configpfoutput(GPIOC, 28); /* Port C, pin 18: CTS */ + imxgpio_configpfinput(GPIOC, 29); /* Port C, pin 29: RTS */ + imxgpio_configpfoutput(GPIOC, 30); /* Port C, pin 30: TXD */ + imxgpio_configpfinput(GPIOC, 31); /* Port C, pin 31: RXD */ +#endif + + /* Then enable the console UART. The others will be initialized + * if and when they are opened. + */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +# ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +# ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +# endif +# endif +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_serialout(priv, UART_TXD0, (uint32_t)'\r'); + up_waittxready(priv); + } + + up_serialout(priv, UART_TXD0, (uint32_t)ch); + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define IMX_REGISTER_BASE IMX_UART1_VBASE +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define IMX_REGISTER_BASE IMX_UART2_VBASE +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define IMX_REGISTER_BASE IMX_UART3_VBASE +# endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void up_waittxready(void) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Loop until TXFULL is zero -- meaning that there is space available + * in the TX FIFO. + */ + + if ((getreg32(IMX_REGISTER_BASE + UART_UTS) & UART_UTS_TXFULL) == 0) + { + break; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int up_putc(int ch) +{ + up_waittxready(); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + putreg32((uint16_t)'\r', IMX_REGISTER_BASE + UART_TXD0); + up_waittxready(); + } + + putreg32((uint16_t)ch, IMX_REGISTER_BASE + UART_TXD0); + return ch; +} + +#endif /* USE_SERIALDRIVER */ + + diff --git a/arch/arm/src/imx1/imx_spi.c b/arch/arm/src/imx1/imx_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..fb5831438699a061fcad0194bca16d613a5e6c1e --- /dev/null +++ b/arch/arm/src/imx1/imx_spi.c @@ -0,0 +1,1181 @@ +/**************************************************************************** + * arch/arm/src/imx1/imx_spi.c + * + * Copyright (C) 2009-2010, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "imx_gpio.h" +#include "imx_cspi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The i.MX1/L supports 2 SPI interfaces. Which have been enabled? */ + +#ifdef CONFIG_IMX1_SPI1 +# define SPI1_NDX 0 /* Index to SPI1 in g_spidev[] */ +# ifdef CONFIG_IMX1_SPI2 +# define SPI2_NDX 1 /* Index to SPI2 in g_spidev[] */ +# define NSPIS 2 /* Two SPI interfaces: SPI1 & SPI2 */ +# else +# define NSPIS 1 /* One SPI interface: SPI1 */ +# endif +#else +# ifdef CONFIG_IMX1_SPI2 +# define SPI2_NDX 0 /* Index to SPI2 in g_spidev[] */ +# define NSPIS 1 /* One SPI interface: SPI2 */ +# else +# define NSPIS 0 /* No SPI interfaces */ +# endif +#endif + +/* Compile the rest of the file only if at least one SPI interface has been + * enabled. + */ + +#if NSPIS > 0 + +/* The number of words that will fit in the Tx FIFO */ + +#define IMX_TXFIFO_WORDS 8 + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct imx_spidev_s +{ + const struct spi_ops_s *ops; /* Common SPI operations */ +#ifndef CONFIG_SPI_POLLWAIT + sem_t waitsem; /* Wait for transfer to complete */ +#endif + sem_t exclsem; /* Supports mutually exclusive access */ + + /* These following are the source and destination buffers of the transfer. + * they are retained in this structure so that they will be accessible + * from an interrupt handler. The actual type of the buffer is uint8_t is + * nbits <=8 and uint16_t is nbits >8. + */ + + void *txbuffer; /* Source buffer */ + void *rxbuffer; /* Destination buffer */ + + /* These are functions pointers that are configured to perform the + * appropriate transfer for the particular kind of exchange that is + * occurring. Differnt functions may be selected depending on (1) + * if the tx or txbuffer is NULL and depending on the number of bits + * per word. + */ + + void (*txword)(struct imx_spidev_s *priv); + void (*rxword)(struct imx_spidev_s *priv); + + uint32_t base; /* SPI register base address */ + uint32_t frequency; /* Current desired SCLK frequency */ + uint32_t actual; /* Current actual SCLK frequency */ + + int ntxwords; /* Number of words left to transfer on the Tx FIFO */ + int nrxwords; /* Number of words received on the Rx FIFO */ + int nwords; /* Number of words to be exchanged */ + + uint8_t mode; /* Current mode */ + uint8_t nbits; /* Current number of bits per word */ +#ifndef CONFIG_SPI_POLLWAIT + uint8_t irq; /* SPI IRQ number */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI register access */ + +static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset); +static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value); + +/* SPI data transfer */ + +static void spi_txnull(struct imx_spidev_s *priv); +static void spi_txuint16(struct imx_spidev_s *priv); +static void spi_txuint8(struct imx_spidev_s *priv); +static void spi_rxnull(struct imx_spidev_s *priv); +static void spi_rxuint16(struct imx_spidev_s *priv); +static void spi_rxuint8(struct imx_spidev_s *priv); +static int spi_performtx(struct imx_spidev_s *priv); +static inline void spi_performrx(struct imx_spidev_s *priv); +static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer, + void *rxbuffer, unsigned int nwords); + +/* Interrupt handling */ + +#ifndef CONFIG_SPI_POLLWAIT +static inline struct imx_spidev_s *spi_mapirq(int irq); +static int spi_interrupt(int irq, void *context); +#endif + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +#ifdef CONFIG_SPI_EXCHANGE +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#else +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Common SPI operations */ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = imx_spiselect, /* Provided externally by board logic */ + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = imx_spistatus, /* Provided externally by board logic */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = imx_spicmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +}; + +/* This supports is up to two SPI busses/ports */ + +static struct imx_spidev_s g_spidev[] = +{ +#ifdef CONFIG_IMX1_SPI1 + { + .ops = &g_spiops, + .base = IMX_CSPI1_VBASE, +#ifndef CONFIG_SPI_POLLWAIT + .irq = IMX_IRQ_CSPI1, +#endif + }, +#endif +#ifdef CONFIG_IMX1_SPI2 + { + .ops = &g_spiops, + .base = IMX_CSPI2_VBASE, +#ifndef CONFIG_SPI_POLLWAIT + .irq = IMX_IRQ_CSPI2, +#endif + }, +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read the SPI register at this offeset + * + * Input Parameters: + * priv - Device-specific state data + * offset - Offset to the SPI register from the register base address + * + * Returned Value: + * Value of the register at this offset + * + ****************************************************************************/ + +static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write the value to the SPI register at this offeset + * + * Input Parameters: + * priv - Device-specific state data + * offset - Offset to the SPI register from the register base address + * value - Value to write + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: spi_txnull, spi_txuint16, and spi_txuint8 + * + * Description: + * Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the txbuffer + * pointer appropriately. The selected function dependes on (1) if there + * is a source txbuffer provided, and (2) if the number of bits per + * word is <=8 or >8. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_txnull(struct imx_spidev_s *priv) +{ + spi_putreg(priv, CSPI_TXD_OFFSET, 0xffff); +} + +static void spi_txuint16(struct imx_spidev_s *priv) +{ + uint16_t *ptr = (uint16_t *)priv->txbuffer; + spi_putreg(priv, CSPI_TXD_OFFSET, *ptr++); + priv->txbuffer = (void *)ptr; +} + +static void spi_txuint8(struct imx_spidev_s *priv) +{ + uint8_t *ptr = (uint8_t *)priv->txbuffer; + spi_putreg(priv, CSPI_TXD_OFFSET, *ptr++); + priv->txbuffer = (void *)ptr; +} + +/**************************************************************************** + * Name: spi_rxnull,spi_rxuint16, and spi_rxuint8 + * + * Description: + * Discard input, save a uint8_t, or or save a uint16_t from Tx FIFO in the + * user rxvbuffer and update the rxbuffer pointer appropriately. The + * selected function dependes on (1) if there is a desination rxbuffer + * provided, and (2) if the number of bits per word is <=8 or >8. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_rxnull(struct imx_spidev_s *priv) +{ + (void)spi_getreg(priv, CSPI_RXD_OFFSET); +} + +static void spi_rxuint16(struct imx_spidev_s *priv) +{ + uint16_t *ptr = (uint16_t *)priv->rxbuffer; + *ptr++ = (uint16_t)spi_getreg(priv, CSPI_TXD_OFFSET); + priv->rxbuffer = (void *)ptr; +} + +static void spi_rxuint8(struct imx_spidev_s *priv) +{ + uint8_t *ptr = (uint8_t *)priv->rxbuffer; + *ptr++ = (uint8_t)spi_getreg(priv, CSPI_TXD_OFFSET); + priv->rxbuffer = (void *)ptr; +} + +/**************************************************************************** + * Name: spi_performtx + * + * Description: + * If the Tx FIFO is empty, then transfer as many words as we can to + * the FIFO. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * The number of words written to the Tx FIFO (a value from 0 to 8, + * inclusive). + * + ****************************************************************************/ + +static int spi_performtx(struct imx_spidev_s *priv) +{ + uint32_t regval; + int ntxd = 0; /* Number of words written to Tx FIFO */ + + /* Check if the Tx FIFO is empty */ + + if ((spi_getreg(priv, CSPI_INTCS_OFFSET) & CSPI_INTCS_TE) != 0) + { + /* Check if all of the Tx words have been sent */ + + if (priv->ntxwords > 0) + { + /* No.. Transfer more words until either the TxFIFO is full or + * until all of the user provided data has been sent. + */ + + for (; ntxd < priv->ntxwords && ntxd < IMX_TXFIFO_WORDS; ntxd++) + { + priv->txword(priv); + } + + /* Update the count of words to to transferred */ + + priv->ntxwords -= ntxd; + } + else + { + /* Yes.. The transfer is complete, disable Tx FIFO empty interrupt */ + + regval = spi_getreg(priv, CSPI_INTCS_OFFSET); + regval &= ~CSPI_INTCS_TEEN; + spi_putreg(priv, CSPI_INTCS_OFFSET, regval); + } + } + return ntxd; +} + +/**************************************************************************** + * Name: spi_performrx + * + * Description: + * Transfer as many bytes as possible from the Rx FIFO to the user Rx + * buffer (if one was provided). + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_performrx(struct imx_spidev_s *priv) +{ + /* Loop while data is available in the Rx FIFO */ + + while ((spi_getreg(priv, CSPI_INTCS_OFFSET) & CSPI_INTCS_RR) != 0) + { + /* Have all of the requested words been transferred from the Rx FIFO? */ + + if (priv->nrxwords < priv->nwords) + { + /* No.. Read more data from Rx FIFO */ + + priv->rxword(priv); + priv->nrxwords++; + } + } +} + +/**************************************************************************** + * Name: spi_startxfr + * + * Description: + * If data was added to the Tx FIFO, then start the exchange + * + * Input Parameters: + * priv - Device-specific state data + * ntxd - The number of bytes added to the Tx FIFO by spi_performtx. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_startxfr(struct imx_spidev_s *priv, int ntxd) +{ + uint32_t regval; + + /* The XCH bit initiates an exchange in master mode. It remains set + * remains set while the exchange is in progress but is automatically + * clear when all data in the Tx FIFO and shift register are shifted out. + * So if we have added data to the Tx FIFO on this interrupt, we must + * set the XCH bit to resume the exchange. + */ + + if (ntxd > 0) + { + regval = spi_getreg(priv, CSPI_CTRL_OFFSET); + regval |= CSPI_CTRL_XCH; + spi_putreg(priv, CSPI_CTRL_OFFSET, regval); + } +} + +/**************************************************************************** + * Name: spi_transfer + * + * Description: + * Exchange a block data with the SPI device + * + * Input Parameters: + * priv - Device-specific state data + * txbuffer - The buffer of data to send to the device (may be NULL). + * rxbuffer - The buffer to receive data from the device (may be NULL). + * nwords - The total number of words to be exchanged. If the interface + * uses <= 8 bits per word, then this is the number of uint8_t's; + * if the interface uses >8 bits per word, then this is the + * number of uint16_t's + * + * Returned Value: + * 0: success, <0:Negated error number on failure + * + ****************************************************************************/ + +static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer, + void *rxbuffer, unsigned int nwords) +{ +#ifndef CONFIG_SPI_POLLWAIT + irqstate_t flags; + uint32_t regval; + int ret; +#endif + int ntxd; + + /* Set up to perform the transfer */ + + priv->txbuffer = (uint8_t *)txbuffer; /* Source buffer */ + priv->rxbuffer = (uint8_t *)rxbuffer; /* Destination buffer */ + priv->ntxwords = nwords; /* Number of words left to send */ + priv->nrxwords = 0; /* Number of words received */ + priv->nwords = nwords; /* Total number of exchanges */ + + /* Set up the low-level data transfer function pointers */ + + if (priv->nbits > 8) + { + priv->txword = spi_txuint16; + priv->rxword = spi_rxuint16; + } + else + { + priv->txword = spi_txuint8; + priv->rxword = spi_rxuint8; + } + + if (!txbuffer) + { + priv->txword = spi_txnull; + } + + if (!rxbuffer) + { + priv->rxword = spi_rxnull; + } + + /* Prime the Tx FIFO to start the sequence (saves one interrupt) */ + +#ifndef CONFIG_SPI_POLLWAIT + flags = enter_critical_section(); + ntxd = spi_performtx(priv); + spi_startxfr(priv, ntxd); + + /* Enable transmit empty interrupt */ + + regval = spi_getreg(priv, CSPI_INTCS_OFFSET); + regval |= CSPI_INTCS_TEEN; + spi_putreg(priv, CSPI_INTCS_OFFSET, regval); + leave_critical_section(flags); + + /* Wait for the transfer to complete. Since there is no handshake + * with SPI, the following should complete even if there are problems + * with the transfer, so it should be safe with no timeout. + */ + + do + { + /* Wait to be signaled from the interrupt handler */ + + ret = sem_wait(&priv->waitsem); + } + while (ret < 0 && errno == EINTR); + +#else + /* Perform the transfer using polling logic. This will totally + * dominate the CPU until the transfer is complete. Only recommended + * if (1) your SPI is very fast, and (2) if you only use very short + * transfers. + */ + + do + { + /* Handle outgoing Tx FIFO transfers */ + + ntxd = spi_performtx(priv); + + /* Handle incoming Rx FIFO transfers */ + + spi_performrx(priv); + + /* Resume the transfer */ + + spi_startxfr(priv, ntxd); + + /* If there are other threads at this same priority level, + * the following may help: + */ + + sched_yield(); + } + while (priv->nrxwords < priv->nwords); +#endif + return OK; +} + +/**************************************************************************** + * Name: spi_mapirq + * + * Description: + * Map an IRQ number into the appropriate SPI device + * + * Input Parameters: + * irq - The IRQ number to be mapped + * + * Returned Value: + * On success, a reference to the private data structgure for this IRQ. + * NULL on failrue. + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_POLLWAIT +static inline struct imx_spidev_s *spi_mapirq(int irq) +{ + switch (irq) + { +#ifdef CONFIG_IMX1_SPI1 + case IMX_IRQ_CSPI1: + return &g_spidev[SPI1_NDX]; +#endif +#ifdef CONFIG_IMX1_SPI2 + case IMX_IRQ_CSPI2: + return &g_spidev[SPI2_NDX]; +#endif + default: + return NULL; + } +} +#endif + +/**************************************************************************** + * Name: spi_interrupt + * + * Description: + * Exchange a block data with the SPI device + * + * Input Parameters: + * priv - Device-specific state data + * txbuffer - The buffer of data to send to the device (may be NULL). + * rxbuffer - The buffer to receive data from the device (may be NULL). + * nwords - The total number of words to be exchanged. If the interface + * uses <= 8 bits per word, then this is the number of uint8_t's; + * if the interface uses >8 bits per word, then this is the + * number of uint16_t's + * + * Returned Value: + * 0: success, <0:Negated error number on failure + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_POLLWAIT +static int spi_interrupt(int irq, void *context) +{ + struct imx_spidev_s *priv = spi_mapirq(irq); + int ntxd; + + DEBUGASSERT(priv != NULL); + + /* Handle outgoing Tx FIFO transfers */ + + ntxd = spi_performtx(priv); + + /* Handle incoming Rx FIFO transfers */ + + spi_performrx(priv); + + /* Resume the transfer */ + + spi_startxfr(priv, ntxd); + + /* Check if the transfer is complete */ + + if (priv->nrxwords >= priv->nwords) + { + /* Yes, wake up the waiting thread */ + + sem_post(&priv->waitsem); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + uint32_t actual; + + DEBUGASSERT(priv); + actual = priv->actual; + + if (frequency != priv->frequency) + { + uint32_t freqbits; + uint32_t regval; + + if (frequency >= IMX_PERCLK2_FREQ / 4) + { + freqbits = CSPI_CTRL_DIV4; + actual = IMX_PERCLK2_FREQ / 4; + } + else if (frequency >= IMX_PERCLK2_FREQ / 8) + { + freqbits = CSPI_CTRL_DIV8; + actual = IMX_PERCLK2_FREQ / 8; + } + else if (frequency >= IMX_PERCLK2_FREQ / 16) + { + freqbits = CSPI_CTRL_DIV16; + actual = IMX_PERCLK2_FREQ / 16; + } + else if (frequency >= IMX_PERCLK2_FREQ / 32) + { + freqbits = CSPI_CTRL_DIV32; + actual = IMX_PERCLK2_FREQ / 32; + } + else if (frequency >= IMX_PERCLK2_FREQ / 64) + { + freqbits = CSPI_CTRL_DIV64; + actual = IMX_PERCLK2_FREQ / 64; + } + else if (frequency >= IMX_PERCLK2_FREQ / 128) + { + freqbits = CSPI_CTRL_DIV128; + actual = IMX_PERCLK2_FREQ / 128; + } + else if (frequency >= IMX_PERCLK2_FREQ / 256) + { + freqbits = CSPI_CTRL_DIV256; + actual = IMX_PERCLK2_FREQ / 256; + } + else /* if (frequency >= IMX_PERCLK2_FREQ / 512) */ + { + freqbits = CSPI_CTRL_DIV512; + actual = IMX_PERCLK2_FREQ / 512; + } + + /* Then set the selected frequency */ + + regval = spi_getreg(priv, CSPI_CTRL_OFFSET); + regval &= ~(CSPI_CTRL_DATARATE_MASK); + regval |= freqbits; + spi_putreg(priv, CSPI_CTRL_OFFSET, regval); + + priv->frequency = frequency; + priv->actual = actual; + } + + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + if (priv && mode != priv->mode) + { + uint32_t modebits; + uint32_t regval; + + /* Select the CTL register bits based on the selected mode */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */ + modebits = 0; + break; + + case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */ + modebits = CSPI_CTRL_PHA; + break; + + case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */ + modebits = CSPI_CTRL_POL; + break; + + case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */ + modebits = CSPI_CTRL_PHA | CSPI_CTRL_POL; + break; + + default: + return; + } + + /* Then set the selected mode */ + + regval = spi_getreg(priv, CSPI_CTRL_OFFSET); + regval &= ~(CSPI_CTRL_PHA | CSPI_CTRL_POL); + regval |= modebits; + spi_putreg(priv, CSPI_CTRL_OFFSET, regval); + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + if (priv && nbits != priv->nbits && nbits > 0 && nbits <= 16) + { + uint32_t regval = spi_getreg(priv, CSPI_CTRL_OFFSET); + regval &= ~CSPI_CTRL_BITCOUNT_MASK; + regval |= ((nbits - 1) << CSPI_CTRL_BITCOUNT_SHIFT); + spi_putreg(priv, CSPI_CTRL_OFFSET, regval); + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + uint16_t response = 0; + + (void)spi_transfer(priv, &wd, &response, 1); + return response; +} + +/**************************************************************************** + * Name: SPI_EXCHANGE + * + * Description: + * Exahange a block of data from SPI. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_EXCHANGE +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + (void)spi_transfer(priv, txbuffer, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + (void)spi_transfer(priv, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + struct imx_spidev_s *priv = (struct imx_spidev_s *)dev; + (void)spi_transfer(priv, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_spibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *imx_spibus_initialize(int port) +{ + struct imx_spidev_s *priv; + uint8_t regval; + + /* Only the SPI1 interface is supported */ + + switch (port) + { +#ifdef CONFIG_IMX1_SPI1 + case 1: + /* Select SPI1 */ + + priv = &g_spidev[SPI1_NDX]; + + /* Configure SPI1 GPIOs (NOTE that SS is not initialized here, the + * logic in this file makes no assumptions about chip select) + */ + + imxgpio_configpfinput(GPIOC, 13); /* Port C, pin 13: RDY */ + imxgpio_configpfoutput(GPIOC, 14); /* Port C, pin 14: SCLK */ + imxgpio_configpfinput(GPIOC, 16); /* Port C, pin 16: MISO */ + imxgpio_configpfoutput(GPIOC, 17); /* Port C, pin 17: MOSI */ + break; +#endif /* CONFIG_IMX1_SPI1 */ + +#ifdef CONFIG_IMX1_SPI2 + case 2: + /* Select SPI2 */ + + priv = &g_spidev[SPI2_NDX]; + + /* Configure SPI2 GPIOs */ + /* SCLK: AIN of Port A, pin 0 -OR- AIN of Port D, pin 7 */ + +#if 1 + imxgpio_configoutput(GPIOA, 0); /* Set GIUS=1 OCR=0 DIR=OUT */ +#else + imxgpio_configoutput(GPIOD, 7); /* Set GIUS=1 OCR=0 DIR=OUT */ +#endif + + /* SS: AIN of Port A, pin 17 -OR- AIN of Port D, pin 8.(NOTE that SS + * is not initialized here, the logic in this file makes no assumptions + * about chip select) + */ + + /* RXD: AOUT of Port A, pin 1 -OR- AOUT of Port D, pin 9 */ + +#if 1 + imxgpio_configinput(GPIOA, 1); /* Set GIUS=1 OCR=0 DIR=IN */ + + /* Select input from SPI2_RXD_0 pin (AOUT Port A, pin 1) */ + + regval = getreg32(IMX_SC_FMCR); + regval &= ~FMCR_SPI2_RXDSEL; + putreg32(regval, IMX_SC_FMCR); +#else + imxgpio_configinput(GPIOD, 9); /* Set GIUS=1 OCR=0 DIR=IN */ + + /* Select input from SPI2_RXD_1 pin (AOUT Port D, pin 9) */ + + regval = getreg32(IMX_SC_FMCR); + regval |= FMCR_SPI2_RXDSEL; + putreg32(regval, IMX_SC_FMCR); +#endif + + /* TXD: BIN of Port D, pin 31 -OR- AIN of Port D, pin 10 */ + +#if 1 + imxgpio_configinput(GPIOD, 31); + imxgpio_ocrbin(GPIOD, 31); + imxgpio_dirout(GPIOD, 31); +#else + imxgpio_configoutput(GPIOD, 10); +#endif + break; +#endif /* CONFIG_IMX1_SPI2 */ + + default: + return NULL; + } + + /* Initialize the state structure */ + +#ifndef CONFIG_SPI_POLLWAIT + sem_init(&priv->waitsem, 0, 0); +#endif + sem_init(&priv->exclsem, 0, 1); + + /* Initialize control register: min frequency, ignore ready, master mode, mode=0, 8-bit */ + + spi_putreg(priv, CSPI_CTRL_OFFSET, + CSPI_CTRL_DIV512 | /* Lowest frequency */ + CSPI_CTRL_DRCTL_IGNRDY | /* Ignore ready */ + CSPI_CTRL_MODE | /* Master mode */ + (7 << CSPI_CTRL_BITCOUNT_SHIFT)); /* 8-bit data */ + + /* Make sure state agrees with data */ + + priv->mode = SPIDEV_MODE0; + priv->nbits = 8; + + /* Set the initial clock frequency for identification mode < 400kHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Enable interrupts on data ready (and certain error conditions */ + +#ifndef CONFIG_SPI_POLLWAIT + spi_putreg(priv, CSPI_INTCS_OFFSET, + CSPI_INTCS_RREN | /* RXFIFO Data Ready Interrupt Enable */ + CSPI_INTCS_ROEN | /* RXFIFO Overflow Interrupt Enable */ + CSPI_INTCS_BOEN); /* Bit Count Overflow Interrupt Enable */ +#else + spi_putreg(priv, CSPI_INTCS_OFFSET, 0); /* No interrupts */ +#endif + + /* Set the clock source=bit clock and number of clocks inserted between + * transactions = 2. + */ + + spi_putreg(priv, CSPI_SPCR_OFFSET, 2); + + /* No DMA */ + + spi_putreg(priv, CSPI_DMA_OFFSET, 0); + + /* Attach the interrupt */ + +#ifndef CONFIG_SPI_POLLWAIT + irq_attach(priv->irq, (xcpt_t)spi_interrupt); +#endif + + /* Enable SPI */ + + regval = spi_getreg(priv, CSPI_CTRL_OFFSET); + regval |= CSPI_CTRL_SPIEN; + spi_putreg(priv, CSPI_CTRL_OFFSET, regval); + + /* Enable SPI interrupts */ + +#ifndef CONFIG_SPI_POLLWAIT + up_enable_irq(priv->irq); +#endif + return (FAR struct spi_dev_s *)priv; +} + +#endif /* NSPIS > 0 */ diff --git a/arch/arm/src/imx1/imx_system.h b/arch/arm/src/imx1/imx_system.h new file mode 100644 index 0000000000000000000000000000000000000000..4d4f5596e195819a2ec4a2f126e89a3767b7afd3 --- /dev/null +++ b/arch/arm/src/imx1/imx_system.h @@ -0,0 +1,187 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_system.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_SYSTEM_H +#define __ARCH_ARM_IMX_SYSTEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* AIPI Register Offsets ************************************************************/ + +#define AIPI_PSR0_OFFSET 0x0000 /* Peripheral Size Register 0 */ +#define AIPI_PSR1_OFFSET 0x0004 /* Peripheral Size Register 1 */ +#define AIPI_PAR_OFFSET 0x0008 /* Peripheral Access Register */ + +/* AIPI Register Addresses **********************************************************/ + +#define IMX_AIPI1_PSR0 (IMX_AIPI1_VBASE + AIPI_PSR0_OFFSET) +#define IMX_AIPI1_PSR1 (IMX_AIPI1_VBASE + AIPI_PSR1_OFFSET) +#define IMX_AIPI1_PAR (IMX_AIPI1_VBASE + AIPI_PAR_OFFSET) + +#define IMX_AIPI2_PSR0 (IMX_AIP2_VBASE + AIPI_PSR0_OFFSET) +#define IMX_AIPI2_PSR1 (IMX_AIP2_VBASE + AIPI_PSR1_OFFSET) +#define IMX_AIPI2_PAR (IMX_AIP2_VBASE + 0xAIPI_PAR_OFFSET) + +/* AIPI Register Bit Definitions ****************************************************/ + +/* PLL Register Offsets *************************************************************/ + +#define PLL_CSCR_OFFSET 0x0000 /* Clock Source Control Register */ +#define PLL_MPCTL0_OFFSET 0x0004 /* MCU PLL Control Register 0 */ +#define PLL_MPCTL1_OFFSET 0x0008 /* MCU PLL & System Clock Control Register 1 */ +#define PLL_SPCTL0_OFFSET 0x000c /* System PLL Control Register 0 */ +#define PLL_SPCTL1_OFFSET 0x0010 /* System PLL Control Register 1 */ +#define PLL_PCDR_OFFSET 0x0020 /* Peripherial Clock Divider Register */ + +/* PLL Register Addresses ***********************************************************/ + +#define IMX_PLL_CSCR (IMX_PLL_VBASE + PLL_CSCR_OFFSET) +#define IMX_PLL_MPCTL0 (IMX_PLL_VBASE + PLL_MPCTL0_OFFSET) +#define IMX_PLL_MPCTL1 (IMX_PLL_VBASE + PLL_MPCTL1_OFFSET) +#define IMX_PLL_SPCTL0 (IMX_PLL_VBASE + PLL_SPCTL0_OFFSET) +#define IMX_PLL_SPCTL1 (IMX_PLL_VBASE + PLL_SPCTL1_OFFSET) +#define IMX_PLL_PCDR (IMX_PLL_VBASE + PLL_PCDR_OFFSET) + +/* PLL Register Bit Definitions *****************************************************/ + +#define PLL_CSCR_MPEN (1 << 0) /* Bit 0: 1 = MCU PLL enabled */ +#define PLL_CSCR_SPEN (1 << 1) /* Bit 1: System PLL Enable */ +#define PLL_CSCR_BCLKDIV_SHIFT 10 /* Bits 13–10: BClock Divider */ +#define PLL_CSCR_BCLKDIV_MASK (15 << PLL_CSCR_BCLK_DIV_SHIFT) +#define PLL_CSCR_PRESC (1 << 15) /* Bit 15: MPU PLL clock prescaler */ +#define PLL_CSCR_SYSTEM_SEL (1 << 16) /* Bit 16: System clock source select */ +#define PLL_CSCR_OSCEN (1 << 17) /* Bit 17: Ext. 16MHz oscillator enable */ +#define PLL_CSCR_CLK16_SEL (1 << 18) /* Bit 18: Select BT ref RFBTCLK16 */ +#define PLL_CSCR_MPLLRESTART (1 << 21) /* Bit 21: MPLL Restart */ +#define PLL_CSCR_SPLLRESTART (1 << 22) /* Bit 22: SPLL Restart */ +#define PLL_CSCR_SDCNT_SHIFT 24 /* Bits 25–24: Shut-Down Control */ +#define PLL_CSCR_SDCNT_MASK (3 << PLL_CSCR_SDCNT_SHIFT) +#define CSCR_SDCNT_2ndEDGE (1 << PLL_CSCR_SDCNT_SHIFT) +#define CSCR_SDCNT_3rdEDGE (2 << PLL_CSCR_SDCNT_SHIFT) +#define CSCR_SDCNT_4thEDGE (3 << PLL_CSCR_SDCNT_SHIFT) +#define PLL_CSCR_USBDIV_SHIFT 28 /* Bits 28–26: USB Divider */ +#define PLL_CSCR_USBDIV_MASK (7 << PLL_CSCR_USB_DIV_SHIFT) +#define PLL_CSCR_CLKOSEL_SHIFT 29 /* Bits 31–29: CLKO Select */ +#define PLL_CSCR_CLKOSEL_MASK (7 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_PERCLK1 (0 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_HCLK (1 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_CLK48M (2 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_CLK16M (3 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_PREMCLK (4 << PLL_CSCR_CLKOSEL_SHIFT) +#define CSCR_CLKOSEL_FCLK (5 << PLL_CSCR_CLKOSEL_SHIFT) + +#define PLL_MPCTL0_MFN_SHIFT 0 /* Bits 9–0: Multiplication Factor (Numerator) */ +#define PLL_MPCTL0_MFN_MASK (0x03ff << PLL_MPCTL0_MFN_SHIFT) +#define PLL_MPCTL0_MFI_SHIFT 10 /* Bits 13–10: Multiplication Factor (Integer) */ +#define PLL_MPCTL0_MFI_MASK (0x0f << PLL_MPCTL0_MFI_SHIFT) +#define PLL_MPCTL0_MFD_SHIFT 16 /* Bits 25–16: Multiplication Factor (Denominator) */ +#define PLL_MPCTL0_MFD_MASK (0x03ff << PLL_MPCTL0_MFD_SHIFT) +#define PLL_MPCTL0_PD_SHIFT 26 /* Bits 29–26: Predivider Factor */ +#define PLL_MPCTL0_PD_MASK (0x0f << PLL_MPCTL0_PD_SHIFT + +#define PLL_MPCTL1_BRMO (1 << 6) /* Bit 6: Controls the BRM order */ + +#define PLL_SPCTL0_MFN_SHIFT 0 /* Bits 9–0: Multiplication Factor (Numerator) */ +#define PLL_SPCTL0_MFN_MASK (0x03ff << PLL_SPCTL0_MFN_SHIFT) +#define PLL_SPCTL0_MFI_SHIFT 10 /* Bits 13–10: Multiplication Factor (Integer) */ +#define PLL_SPCTL0_MFI_MASK (0x0f << PLL_SPCTL0_MFI_SHIFT) +#define PLL_SPCTL0_MFD_SHIFT 16 /* Bits 25–16: Multiplication Factor (Denominator) */ +#define PLL_SPCTL0_MFD_MASK (0x03ff << PLL_SPCTL0_MFD_SHIFT) +#define PLL_SPCTL0_PD_SHIFT 26 /* Bits 29–26: Predivider Factor */ +#define PLL_SPCTL0_PD_MASK (0x0f << PLL_SPCTL0_PD_SHIFT) + +#define PLL_SPCTL1_BRMO (1 << 6) /* Bit 6: Controls the BRM order */ +#define PLL_SPCTL1_LF (1 << 15) /* Bit 15: Indicates if System PLL is locked */ + +#define PLL_PCDR_PCLKDIV1_SHIFT 0 /* Bits 3–0: Peripheral Clock Divider 1 */ +#define PLL_PCDR_PCLKDIV1_MASK (0x0f << PLL_PCDR_PCLKDIV1_SHIFT) +#define PLL_PCDR_PCLKDIV2_SHIFT 4 /* Bits 7–4: Peripheral Clock Divider 2 */ +#define PLL_PCDR_PCLKDIV2_MASK (0x0f << PLL_PCDR_PCLKDIV2_SHIFT) +#define PLL_PCDR_PCLKDIV3_SHIFT 16 /* Bits 22–16: Peripheral Clock Divider 3 */ +#define PLL_PCDR_PCLKDIV3_MASK (0x7f << PLL_PCDR_PCLKDIV3_SHIFT) + +/* PLL Helper Macros ****************************************************************/ + +/* SC Register Offsets **************************************************************/ + +#define SC_RSR_OFFSET 0x0000 /* Reset Source Register */ +#define SC_SIDR_OFFSET 0x0004 /* Silicon ID Register */ +#define SC_FMCR_OFFSET 0x0008 /* Function Muxing Control Register */ +#define SC_GPCR_OFFSET 0x000c /* Global Peripheral Control Regiser */ + +/* SC Register Addresses ************************************************************/ + +#define IMX_SC_RSR (IMX_SC_VBASE + SC_RSR_OFFSET) +#define IMX_SC_SIDR (IMX_SC_VBASE + SC_SIDR_OFFSET) +#define IMX_SC_FMCR (IMX_SC_VBASE + SC_FMCR_OFFSET) +#define IMX_SC_GPCR (IMX_SC_VBASE + SC_GPCR_OFFSET) + +/* SC Register Bit Definitions ******************************************************/ + + +#define FMCR_SDCS_SEL (1 << 0) /* Bit 0: 1:CSD0 selected */ +#define FMCR_SDCS1_SEL (1 << 1) /* Bit 1: 1:CSD1 selected */ +#define FMCR_EXT_BREN (1 << 2) /* Bit 2: 1:External bus request enabled */ +#define FMCR_SSI_TXCLKSEL (1 << 3) /* Bit 3: 1:Input from Port B[19] SIM_CLK pin */ +#define FMCR_SSI_TXFSSEL (1 << 4) /* Bit 4: 1:Input from Port B[18] SIM_RST pin */ +#define FMCR_SSI_RXDATSEL (1 << 5) /* Bit 5: 1:Input from Port B[16] SIM_TX pin */ +#define FMCR_SSI_RXCLKSEL (1 << 6) /* Bit 6: 1:Input from Port B[15] SIM_PD pin */ +#define FMCR_SSI_RXFSSEL (1 << 7) /* Bit 7: 1:Input from Port B[14] SIM_SVEN pin */ +#define FMCR_SPI2_RXDSEL (1 << 8) /* Bit 8: 1:Input from SPI2_RXD_1 pin + * (AOUT of Port D[9]) */ + +/* SDRAMC Register Offsets **********************************************************/ + +#define SDRAMC_SDCTL0_OFFSET 0x0000 +#define SDRAMC_SDCTL1_OFFSET 0x0004 + +/* SDRAMC Register Addresses ********************************************************/ + +#define IMX_SDRAMC_SDCTL0 (IMX_SDRAMC_VBASE + SDRAMC_SDCTL0_OFFSET) +#define IMX_SDRAMC_SDCTL1 (IMX_SDRAMC_VBASE + SDRAMC_SDCTL1_OFFSET)) + +/* SDRAMC Register Bit Definitions **************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_SYSTEM_H */ diff --git a/arch/arm/src/imx1/imx_timer.h b/arch/arm/src/imx1/imx_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..1a7e33e60fcc8820c2053a166d70b3be02b19648 --- /dev/null +++ b/arch/arm/src/imx1/imx_timer.h @@ -0,0 +1,104 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_timer.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_TIMER_H +#define __ARCH_ARM_IMX_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Timer Register Offsets ***********************************************************/ + +#define TIMER_TCTL_OFFSET 0x0000 /* Timer control register */ +#define TIMER_TPRER_OFFSET 0x0004 /* Timer prescaler register */ +#define TIMER_TCMP_OFFSET 0x0008 /* Timer compare register */ +#define TIMER_TCR_OFFSET 0x000c /* Timer capture register */ +#define TIMER_TCN_OFFSET 0x0010 /* Timer counter regiser */ +#define TIMER_TSTAT_OFFSET 0x0014 /* Timer status register */ + +/* Timer Register Addresses *********************************************************/ + +#define IMX_TIMER1_TCTL (IMX_TIMER1_VBASE + TIMER_TCTL_OFFSET) +#define IMX_TIMER1_TPRER (IMX_TIMER1_VBASE + TIMER_TPRER_OFFSET) +#define IMX_TIMER1_TCMP (IMX_TIMER1_VBASE + TIMER_TCMP_OFFSET) +#define IMX_TIMER1_TCR (IMX_TIMER1_VBASE + TIMER_TCR_OFFSET) +#define IMX_TIMER1_TCN (IMX_TIMER1_VBASE + TIMER_TCN_OFFSET) +#define IMX_TIMER1_TSTAT (IMX_TIMER1_VBASE + TIMER_TSTAT_OFFSET) + +#define IMX_TIMER2_TCTL (IMX_TIMER2_VBASE + TIMER_TCTL_OFFSET) +#define IMX_TIMER2_TPRER (IMX_TIMER2_VBASE + TIMER_TPRER_OFFSET) +#define IMX_TIMER2_TCMP (IMX_TIMER2_VBASE + TIMER_TCMP_OFFSET) +#define IMX_TIMER2_TCR (IMX_TIMER2_VBASE + TIMER_TCR_OFFSET) +#define IMX_TIMER2_TCN (IMX_TIMER2_VBASE + TIMER_TCN_OFFSET) +#define IMX_TIMER2_TSTAT (IMX_TIMER2_VBASE + TIMER_TSTAT_OFFSET) + +/* Timer Register Bit Definitions ***************************************************/ + +/* Timer Control Register */ + +#define TIMER_TCTL_TEN (1 << 0) /* Bit 0: Timer Enable */ +#define TIMER_TCTL_CLKSOURCE_SHIFT 1 /* Bit 1-4: Clock Source */ +#define TIMER_TCTL_CLKSOURCE_MASK (0x07 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TCTL_CLKSOURCE_STOPCOUNT (0x00 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TCTL_CLKSOURCE_PERCLK1 (0x01 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TCTL_CLKSOURCE_PERCLK1D16 (0x02 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TCTL_CLKSOURCE_TIN (0x03 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TCTL_CLKSOURCE_32KHX (0x04 << TIMER_TCTL_CLKSOURCE_SHIFT) +#define TIMER_TCTL_IRQEN (1 << 5) /* Bit 5: Interrupt Request Enable */ +#define TIMER_TCTL_OM (1 << 6) /* Bit 6: Output Mode */ +#define TIMER_TCTL_CAP (1 << 7) /* Bit 7: Capture Edge */ +#define TIMER_TCTL_FRR (1 << 8) /* Bit 8: Free-Run/Reset */ +#define TIMER_TCTL_SWR (1 << 15) /* Bit 15: Software Reset */ + +/* Timer Prescaler Register */ + +#define TIMER_TPRER_PRESCALER_SHIFT 0 /* Bits 0-7: Prescaler */ +#define TIMER_TPRER_PRESCALER_MASK (0xff << TIMER_TPRER_PRESCALER_SHIFT) + +/* Timer Status Register */ + +#define TIMER_TSTAT_COMP (1 << 0) /* Bit 0: Compare Event */ +#define TIMER_TSTAT_CAPT (1 << 1) /* Bit 1: Capture Event */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_TIMER_H */ diff --git a/arch/arm/src/imx1/imx_timerisr.c b/arch/arm/src/imx1/imx_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..77facd7cc913fe7239102af2717a8296ac81f0aa --- /dev/null +++ b/arch/arm/src/imx1/imx_timerisr.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/arm/src/imx1/imx_timerisr.c + * arch/arm/src/chip/imx_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + uint32_t tstat; + int ret = -EIO; + + /* Get and clear the interrupt status */ + + tstat = getreg32(IMX_TIMER1_TSTAT); + putreg32(0, IMX_TIMER1_TSTAT); + + /* Verify that this is a timer interrupt */ + + if ((tstat & TIMER_TSTAT_COMP) != 0) + { + /* Process timer interrupt */ + + sched_process_timer(); + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t tctl; + + /* Make sure the timer interrupts are disabled */ + + up_disable_irq(IMX_IRQ_SYSTIMER); + + /* Make sure that timer1 is disabled */ + + putreg32(0, IMX_TIMER1_TCTL); + putreg32(0, IMX_TIMER1_TPRER); + + /* Select restart mode with source = PERCLK1. In restart mode, after + * the compare value is reached, the counter resets to 0x00000000, the + * compare event (COMP) bit of the timer status register is set, an + * interrupt is issued if the interrupt request enable (IRQEN) bit of + * the corresponding TCTL register is set, and the counter resumes + * counting. + */ + + tctl = TCTL_CLKSOURCE_PERCLK1; + putreg32(tctl, IMX_TIMER1_TCTL); + + /* The timer is driven by PERCLK1. Set prescaler for division by one + * so that the clock is driven at PERCLK1. + * + * putreg(0, IMX_TIMER1_TPRER); -- already the case + * + * Set the compare register so that the COMP interrupt is generated + * with a period of USEC_PER_TICK. The value IMX_PERCLK1_FREQ/1000 + * (defined in board.h) is the number of counts in millisecond, so: + */ + + putreg32(MSEC2TICK(IMX_PERCLK1_FREQ / 1000), IMX_TIMER1_TCMP); + + /* Configure to provide timer COMP interrupts when TCN increments + * to TCMP. + */ + + tctl |= TIMER_TCTL_IRQEN; + putreg32(tctl, IMX_TIMER1_TCTL); + + /* Finally, enable the timer (be be the last operation on TCTL) */ + + tctl |= TIMER_TCTL_TEN; + putreg32(tctl, IMX_TIMER1_TCTL); + + /* Attach and enable the timer interrupt */ + + irq_attach(IMX_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(IMX_IRQ_SYSTIMER); +} + diff --git a/arch/arm/src/imx1/imx_uart.h b/arch/arm/src/imx1/imx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..17be84f37144d7b27428043a31c5f08ed01e4d20 --- /dev/null +++ b/arch/arm/src/imx1/imx_uart.h @@ -0,0 +1,227 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_uart.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX1_CHIP_IMX_UART_H +#define __ARCH_ARM_SRC_IMX1_CHIP_IMX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* UART Register Offsets ************************************************************/ + +#define UART_RXD0 0x0000 /* UART receiver register 0 */ +#define UART_RXD1 0x0004 /* UART receiver register 1 */ +#define UART_RXD2 0x0008 /* UART receiver register 2 */ +#define UART_RXD3 0x000c /* UART receiver register 3 */ +#define UART_TXD0 0x0040 /* UART receiver register 0 */ +#define UART_TXD1 0x0044 /* UART receiver register 1 */ +#define UART_TXD2 0x0048 /* UART receiver register 2 */ +#define UART_TXD3 0x004c /* UART receiver register 3 */ +#define UART_UCR1 0x0080 /* UART control register 1 */ +#define UART_UCR2 0x0084 /* UART control register 2 */ +#define UART_UCR3 0x0088 /* UART control register 3 */ +#define UART_UCR4 0x008c /* UART control register 4 */ +#define UART_UFCR 0x0090 /* UART FIFO control register */ +#define UART_USR1 0x0094 /* UART status register 1 */ +#define UART_USR2 0x0098 /* UART status register 2 */ +#define UART_UESC 0x009c /* UART escape character register */ +#define UART_UTIM 0x00a0 /* UART escape timer register */ +#define UART_UBIR 0x00a4 /* UART BRM incremental register */ +#define UART_UBMR 0x00a8 /* UART BRM modulator register */ +#define UART_UBRC 0x00ac /* UART baud rate counter register */ +#define UART_BIPR1 0x00b0 /* UART BRM incremental preset register 1 */ +#define UART_BIPR2 0x00b4 /* UART BRM incremental preset register 2 */ +#define UART_BIPR3 0x00b8 /* UART BRM incremental preset register 3 */ +#define UART_BIPR4 0x00bc /* UART BRM incremental preset register 4 */ +#define UART_BMPR1 0x00c0 /* UART BRM modulator preset register 1 */ +#define UART_BMPR2 0x00c4 /* UART BRM modulator preset register 2 */ +#define UART_BMPR3 0x00c8 /* UART BRM modulator preset register 3 */ +#define UART_BMPR4 0x00cc /* UART BRM modulator preset register 4 */ +#define UART_UTS 0x00d0 /* UART test register */ + +/* UART Register Bit Definitions ****************************************************/ + +/* UART Receiver Register */ + +#define UART_RXD_DATA_SHIFT 0 /* Bits 0-7: Received Data */ +#define UART_RXD_DATA_MASK (0xff << UART_RXD_DATA_SHIFT) +#define UART_RXD_PRERR (1 << 10) /* Bit 10: Parity Error */ +#define UART_RXD_BRK (1 << 11) /* Bit 11: Break Detect */ +#define UART_RXD_FRMERR (1 << 12) /* Bit 12: Frame Error */ +#define UART_RXD_OVRRUN (1 << 13) /* Bit 13: Receiver Overrun */ +#define UART_RXD_ERR (1 << 14) /* Bit 14: Error Detect */ +#define UART_RXD_CHARRDY (1 << 15) /* Bit 15: Character Ready */ + +/* UART Transmitter Register */ + +#define UART_TXDATA_SHIFT 0 /* Bits 0-7: Transmit Data */ +#define UART_TXDATA_MASK (0xff << UART_UCR4_TXDATA_SHIFT) + +/* UART Control Register 1 */ + +#define UART_UCR1_UARTEN (1 << 0) /* Bit 0: Enable/disable uart */ +#define UART_UCR1_DOZE (1 << 1) /* Bit 1: UART Doze enable */ +#define UART_UCR1_UARTCLEN (1 << 2) /* Bit 2: UART clock enable */ +#define UART_UCR1_TDMAEN (1 << 3) /* Bit 3: Transmitter ready data enable */ +#define UART_UCR1_SNDBRK (1 << 4) /* Bit 4: Send BREAK */ +#define UART_UCR1_RTSDEN (1 << 5) /* Bit 5: RTS Delta interrupt enable */ +#define UART_UCR1_TXEMPTYEN (1 << 6) /* Bit 6: Transmitter empty interrupt enable */ +#define UART_UCR1_IREN (1 << 7) /* Bit 7: Infrared Interface enable */ +#define UART_UCR1_RDMAEN (1 << 8) /* Bit 8: Receive ready DMA enable */ +#define UART_UCR1_RRDYEN (1 << 9) /* Bit 9: Receiver ready interrupt enable */ +#define UART_UCR1_ICD_SHIFT 10 /* Bit 10-11: Idle condition detect */ +#define UART_UCR1_ICD_MASK (0x03 << UART_UCR1_ICD_SHIFT) +#define UART_UCR1_IDEN (1 << 12) /* Bit 12: Idle condition detected interrupt enable */ +#define UART_UCR1_TRDYEN (1 << 13) /* Bit 13: Transmitter ready interrupt enable */ +#define UART_UCR1_ADBR (1 << 14) /* Bit 14: Automatic detection of baud rate */ +#define UART_UCR1_ADEN (1 << 15) /* Bit 15: Automatic baud rate detection interrupt enable */ + +/* UART Control Register 2 */ + +#define UART_UCR2_SRST (1 << 0) /* Bit 0: Software reset */ +#define UART_UCR2_RXEN (1 << 1) /* Bit 1: Receiver enable */ +#define UART_UCR2_TXEN (1 << 2) /* Bit 2: Transmitter enable */ +#define UART_UCR2_RTSEN (1 << 4) /* Bit 4: RTS interrupt enable/disable */ +#define UART_UCR2_WS (1 << 5) /* Bit 5: Word size */ +#define UART_UCR2_STPB (1 << 6) /* Bit 6: Controls number of stop bits */ +#define UART_UCR2_PROE (1 << 7) /* Bit 7: Parity Odd/Even */ +#define UART_UCR2_PREN (1 << 8) /* Bit 8: Parity enable */ +#define UART_UCR2_RTEC_SHIFT 9 /* Bit 9-10: Request to send edge control */ +#define UART_UCR2_RTEC_MASK (0x03 << UART_UCR2_RTEC_SHIFT) +#define UART_UCR2_ESCEN (1 << 11) /* Bit 11: Escape enable */ +#define UART_UCR2_CTS (1 << 12) /* Bit 12: Clear To Send pin */ +#define UART_UCR2_CTSC (1 << 13) /* Bit 13: CTS Pin control */ +#define UART_UCR2_IRTS (1 << 14) /* Bit 14: Ignore RTS Pin */ +#define UART_UCR2_ESCI (1 << 15) /* Bit 15: Escape Sequence Interrupt Enable */ + +/* UART1 Control Register 3 */ + +#define UART1_UCR3_BPEN (1 << 0) /* Bit 0: Preset Registers Enable */ +#define UART1_UCR3_INVT (1 << 1) /* Bit 1: Inverted Infrared Transmission */ +#define UART1_UCR3_REF30 (1 << 2) /* Bit 2: Reference frequency 30 mhz */ +#define UART1_UCR3_REF25 (1 << 3) /* Bit 3: Reference frequency 25 mhz */ +#define UART1_UCR3_AWAKEN (1 << 4) /* Bit 4: Asynchronous wake interrupt enable */ +#define UART1_UCR3_AIRINTEN (1 << 5) /* Bit 5: Asynchronous IR Wake interrupt enable */ +#define UART1_UCR3_RXDSEN (1 << 6) /* Bit 6: Receive status interrupt enable */ +#define UART1_UCR3_FRAERREN (1 << 11) /* Bit 11: Frame error interrupt enable */ +#define UART1_UCR3_PARERREN (1 << 12) /* Bit 12: Parity error interrupt enable */ + +/* UART2/3 Control Register 4 */ + +#define UART2_UCR3_BPEN (1 << 0) /* Bit 0: Preset Registers Enable */ +#define UART2_UCR3_INVT (1 << 1) /* Bit 1: Inverted Infrared Transmission */ +#define UART2_UCR3_REF30 (1 << 2) /* Bit 2: Reference frequency 30 mhz */ +#define UART2_UCR3_REF25 (1 << 3) /* Bit 3: Reference frequency 25 mhz */ +#define UART2_UCR3_AWAKEN (1 << 4) /* Bit 4: Asychronous WAKE Interrupt Enable */ +#define UART2_UCR3_AIRINTEN (1 << 5) /* Bit 5: Asychronous IR WAKE Interrupt Enable */ +#define UART2_UCR3_RXDSEN (1 << 6) /* Bit 6: Receive Status Interrupt Enable */ +#define UART2_UCR3_RI (1 << 7) /* Bit 7: Ring Indicator */ +#define UART2_UCR3_Reserved2 (1 << 8) /* Bit 8: Reserved */ +#define UART2_UCR3_DCD (1 << 9) /* Bit 9: Data Carrier Detect */ +#define UART2_UCR3_DSR (1 << 10) /* Bit 10: Data Set Ready */ +#define UART2_UCR3_FRAERREN (1 << 11) /* Bit 11: Frame Error Interrupt Enable */ +#define UART2_UCR3_PARERREN (1 << 12) /* Bit 12: Parity Error Interrupt Enable */ +#define UART2_UCR3_DTREN (1 << 13) /* Bit 13: Data Terminal Ready Interrupt Enable */ +#define UART2_UCR3_DPEC_SHIFT 14 /* Bit 14-15: DTR Interrupt Edge Control */ +#define UART2_UCR3_DPEC_MASK (0x03 << UART_UCR4_DPEC_SHIFT) + +/* UART Control Register 4 */ + +#define UART_UCR4_DREN (1 << 0) /* Bit 0: Receive data ready interrupt enable */ +#define UART_UCR4_OREN (1 << 1) /* Bit 1: Receiver overrun interrupt enable */ +#define UART_UCR4_BKEN (1 << 2) /* Bit 2: Break condition detected interrupt enable */ +#define UART_UCR4_TCEN (1 << 3) /* Bit 3: Transmit complete interrupt enable */ +#define UART_UCR4_IRSC (1 << 5) /* Bit 5: IR special case */ +#define UART_UCR4_REF16 (1 << 6) /* Bit 6: Reference Frequency 16 mhz */ +#define UART_UCR4_WKEN (1 << 7) /* Bit 7: Wake interrupt enable */ +#define UART_UCR4_ENIRI (1 << 8) /* Bit 8: Serial infrared interrupt enable */ +#define UART_UCR4_INVR (1 << 9) /* Bit 9: Inverted infrared reception */ +#define UART_UCR4_CTSTL_SHIFT 10 /* Bits 10-15: CTS trigger level */ +#define UART_UCR4_CTSTL_MASK (0x3f << UART_UCR4_CTSTL_SHIFT) + +/* UART FIFO Control Register */ + +#define UART_UFCR_RXTL_SHIFT 0 /* Bits 0-6: Receiver Trigger Level */ +#define UART_UFCR_RXTL_MASK (0x3f << UART_UFCR_RXTL_SHIFT) +#define UART_UFCR_RFDIV_SHIFT 7 /* Bits 7-9: Reference Frequency Divider */ +#define UART_UFCR_RFDIV_MASK (0x07 << UART_UFCR_RFDIV_SHIFT) +#define UART_UFCR_TXTL_SHIFT 10 /* Bits 10-15: Transmitter Trigger Level */ +#define UART_UFCR_TXTL_MASK (0x3f << UART_UFCR_TXTL_SHIFT) + +/* UART Status 1 Register */ + +#define UART_USR1_AWAKE (1 << 4) /* Bit 4: Asynchronous WAKE Interrupt Flag */ +#define UART_USR1_AIRINT (1 << 5) /* Bit 5: Asynchronous IR WAKE Interrupt Flag */ +#define UART_USR1_RXDS (1 << 6) /* Bit 6: Receiver IDLE Interrupt Flag */ +#define UART_USR1_RRDY (1 << 9) /* Bit 9: RX Ready Interrupt/DMA Flag */ +#define UART_USR1_FRAMERR (1 << 10) /* Bit 10: Frame Error Interrupt Flag */ +#define UART_USR1_ESCF (1 << 11) /* Bit 11: Escape Sequence Interrupt Flag */ +#define UART_USR1_RTSD (1 << 12) /* Bit 12: RTS Delta */ +#define UART_USR1_TRDY (1 << 13) /* Bit 13: TX Ready Interrupt/DMA Flag */ +#define UART_USR1_RTSS (1 << 14) /* Bit 14: RTS Pin Status */ +#define UART_USR1_PARITYERR (1 << 15) /* Bit 15: Parity Error Interrupt Flag */ + +/* UART Status 2 Register */ + +#define UART_USR2_RDR (1 << 0) /* Bit 0: Receive data ready */ +#define UART_USR2_ORE (1 << 1) /* Bit 1: Overrun error */ +#define UART_USR2_BRCD (1 << 2) /* Bit 2: Break condition detected */ +#define UART_USR2_TXDC (1 << 3) /* Bit 3: Transmitter complete */ +#define UART_USR2_RTSF (1 << 4) /* Bit 4: RTS Edge Triggered Interrupt flag */ +#define UART_USR2_WAKE (1 << 7) /* Bit 7: Wake */ +#define UART_USR2_IRINT (1 << 8) /* Bit 8: Serial infrared interrupt flag */ +#define UART_USR2_IDLE (1 << 12) /* Bit 12: Idle condition */ +#define UART_USR2_DTRF (1 << 13) /* Bit 13: DTR edge triggered interrupt flag */ +#define UART_USR2_TXFE (1 << 14) /* Bit 14: Transmit Buffer FIFO empty */ +#define UART_USR2_ADET (1 << 15) /* Bit 15: Automatic baud rate detection complete */ + +/* UART Test Register */ + +#define UART_UTS_TXFULL (1 << 4) /* Bit 4: TxFIFO FULL */ +#define UART_UTS_RXEMPTY (1 << 5) /* Bit 5: RxFIFO Empty */ +#define UART_UTS_TXEMPTY (1 << 6) /* Bit 6: TxFIFO */ +#define UART_UTS_LOOP (1 << 12) /* Bit 12: Loop TX and RX for Test */ +#define UART_UTS_FRCPERR (1 << 13) /* Bit 13: Force Parity Error */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_IMX1_CHIP_IMX_UART_H */ diff --git a/arch/arm/src/imx1/imx_usbd.h b/arch/arm/src/imx1/imx_usbd.h new file mode 100644 index 0000000000000000000000000000000000000000..b07b4c82d32f065b138217d38d4db07924b676c3 --- /dev/null +++ b/arch/arm/src/imx1/imx_usbd.h @@ -0,0 +1,320 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_usbd.h + * + * Copyright (c) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_USBD_H +#define __ARCH_ARM_IMX_USBD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* USBD Register Offsets ************************************************************/ + +#define USBD_FRAME_OFFSET 0x0000 +#define USBD_SPEC_OFFSET 0x0004 +#define USBD_STAT_OFFSET 0x0008 +#define USBD_CTRL_OFFSET 0x000c +#define USBD_DADR_OFFSET 0x0010 +#define USBD_DDAT_OFFSET 0x0014 +#define USBD_INTR_OFFSET 0x0018 +#define USBD_MASK_OFFSET 0x001c +#define USBD_ENAB_OFFSET 0x0024 + +#define USBD_EP0_OFFSET 0x0030 +#define USBD_EP1_OFFSET 0x0060 +#define USBD_EP2_OFFSET 0x0090 +#define USBD_EP3_OFFSET 0x00c0 +#define USBD_EP4_OFFSET 0x00f0 +#define USBD_EP5_OFFSET 0x0120 +#define USBD_EP_OFFSET(n) (USBD_EP0_OFFSET + (n)*0x0030) + +#define USBD_EP_STAT_OFFSET 0x0000 +#define USBD_EP_INTR_OFFSET 0x0004 +#define USBD_EP_MASK_OFFSET 0x0008 +#define USBD_EP_FDAT_OFFSET 0x000c +#define USBD_EP_FSTAT_OFFSET 0x0010 +#define USBD_EP_FCTRL_OFFSET 0x0014 +#define USBD_EP_LRFP_OFFSET 0x0018 +#define USBD_EP_LRWP_OFFSET 0x001c +#define USBD_EP_FALRM_OFFSET 0x0020 +#define USBD_EP_FRDP_OFFSET 0x0024 +#define USBD_EP_FRWP_OFFSET 0x0028 + +/* USBD Register Addresses **********************************************************/ + +#define IMX_USBD_FRAME (IMX_USBD_VBASE + USBD_FRAME_OFFSET) +#define IMX_USBD_SPEC (IMX_USBD_VBASE + USBD_SPEC_OFFSET) +#define IMX_USBD_STAT (IMX_USBD_VBASE + USBD_STAT_OFFSET) +#define IMX_USBD_CTRL (IMX_USBD_VBASE + USBD_CTRL_OFFSET) +#define IMX_USBD_DADR (IMX_USBD_VBASE + USBD_DADR_OFFSET) +#define IMX_USBD_DDAT (IMX_USBD_VBASE + USBD_DDAT_OFFSET) +#define IMX_USBD_INTR (IMX_USBD_VBASE + USBD_INTR_OFFSET) +#define IMX_USBD_MASK (IMX_USBD_VBASE + USBD_MASK_OFFSET) +#define IMX_USBD_ENAB (IMX_USBD_VBASE + USBD_ENAB_OFFSET) + +#define IMX_USBD_EP0_BASE (IMX_USBD_VBASE + USBD_EP0_OFFSET) +#define IMX_USBD_EP1_BASE (IMX_USBD_VBASE + USBD_EP1_OFFSET) +#define IMX_USBD_EP2_BASE (IMX_USBD_VBASE + USBD_EP2_OFFSET) +#define IMX_USBD_EP3_BASE (IMX_USBD_VBASE + USBD_EP3_OFFSET) +#define IMX_USBD_EP4_BASE (IMX_USBD_VBASE + USBD_EP4_OFFSET) +#define IMX_USBD_EP5_BASE (IMX_USBD_VBASE + USBD_EP5_OFFSET) +#define IMX_USBD_EP_BASE(n) (IMX_USBD_VBASE + USBD_EP_OFFSET(n)) + +#define IMX_USBD_EP0_STAT (IMX_USBD_EP0_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP0_INTR (IMX_USBD_EP0_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP0_MASK (IMX_USBD_EP0_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP0_FDAT (IMX_USBD_EP0_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP0_FSTAT (IMX_USBD_EP0_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP0_FCTRL (IMX_USBD_EP0_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP0_LRFP (IMX_USBD_EP0_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP0_LRWP (IMX_USBD_EP0_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP0_FALRM (IMX_USBD_EP0_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP0_FRDP (IMX_USBD_EP0_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP0_FRWP (IMX_USBD_EP0_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP1_STAT (IMX_USBD_EP1_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP1_INTR (IMX_USBD_EP1_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP1_MASK (IMX_USBD_EP1_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP1_FDAT (IMX_USBD_EP1_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP1_FSTAT (IMX_USBD_EP1_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP1_FCTRL (IMX_USBD_EP1_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP1_LRFP (IMX_USBD_EP1_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP1_LRWP (IMX_USBD_EP1_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP1_FALRM (IMX_USBD_EP1_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP1_FRDP (IMX_USBD_EP1_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP1_FRWP (IMX_USBD_EP1_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP2_STAT (IMX_USBD_EP2_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP2_INTR (IMX_USBD_EP2_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP2_MASK (IMX_USBD_EP2_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP2_FDAT (IMX_USBD_EP2_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP2_FSTAT (IMX_USBD_EP2_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP2_FCTRL (IMX_USBD_EP2_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP2_LRFP (IMX_USBD_EP2_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP2_LRWP (IMX_USBD_EP2_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP2_FALRM (IMX_USBD_EP2_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP2_FRDP (IMX_USBD_EP2_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP2_FRWP (IMX_USBD_EP2_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP3_STAT (IMX_USBD_EP3_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP3_INTR (IMX_USBD_EP3_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP3_MASK (IMX_USBD_EP3_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP3_FDAT (IMX_USBD_EP3_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP3_FSTAT (IMX_USBD_EP3_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP3_FCTRL (IMX_USBD_EP3_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP3_LRFP (IMX_USBD_EP3_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP3_LRWP (IMX_USBD_EP3_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP3_FALRM (IMX_USBD_EP3_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP3_FRDP (IMX_USBD_EP3_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP3_FRWP (IMX_USBD_EP3_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP4_STAT (IMX_USBD_EP4_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP4_INTR (IMX_USBD_EP4_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP4_MASK (IMX_USBD_EP4_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP4_FDAT (IMX_USBD_EP4_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP4_FSTAT (IMX_USBD_EP4_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP4_FCTRL (IMX_USBD_EP4_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP4_LRFP (IMX_USBD_EP4_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP4_LRWP (IMX_USBD_EP4_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP4_FALRM (IMX_USBD_EP4_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP4_FRDP (IMX_USBD_EP4_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP4_FRWP (IMX_USBD_EP4_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP5_STAT (IMX_USBD_EP5_BASE + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP5_INTR (IMX_USBD_EP5_BASE + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP5_MASK (IMX_USBD_EP5_BASE + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP5_FDAT (IMX_USBD_EP5_BASE + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP5_FSTAT (IMX_USBD_EP5_BASE + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP5_FCTRL (IMX_USBD_EP5_BASE + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP5_LRFP (IMX_USBD_EP5_BASE + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP5_LRWP (IMX_USBD_EP5_BASE + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP5_FALRM (IMX_USBD_EP5_BASE + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP5_FRDP (IMX_USBD_EP5_BASE + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP5_FRWP (IMX_USBD_EP5_BASE + USBD_EP_FRWP_OFFSET) + +#define IMX_USBD_EP_STAT(n) (IMX_USBD_EP_BASE(n) + USBD_EP_STAT_OFFSET) +#define IMX_USBD_EP_INTR(n) (IMX_USBD_EP_BASE(n) + USBD_EP_INTR_OFFSET) +#define IMX_USBD_EP_MASK(n) (IMX_USBD_EP_BASE(n) + USBD_EP_MASK_OFFSET) +#define IMX_USBD_EP_FDAT(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FDAT_OFFSET) +#define IMX_USBD_EP_FSTAT(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FSTAT_OFFSET) +#define IMX_USBD_EP_FCTRL(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FCTRL_OFFSET) +#define IMX_USBD_EP_LRFP(n) (IMX_USBD_EP_BASE(n) + USBD_EP_LRFP_OFFSET) +#define IMX_USBD_EP_LRWP(n) (IMX_USBD_EP_BASE(n) + USBD_EP_LRWP_OFFSET) +#define IMX_USBD_EP_FALRM(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FALRM_OFFSET) +#define IMX_USBD_EP_FRDP(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FRDP_OFFSET) +#define IMX_USBD_EP_FRWP(n) (IMX_USBD_EP_BASE(n) + USBD_EP_FRWP_OFFSET) + +/* USBD Register Bit Definitions ****************************************************/ + +/* USBD FRAME Register */ + +#define USBD_FRAME_FRAME_SHIFT 0 /* Bit 0-10: Frame Field */ +#define USBD_FRAME_FRAME_MASK (0x07ff << USBD_FRAME_FRAME_SHIFT) +#define USBD_FRAME_MATCH_SHIFT 16 /* Bit 16-26: Match Field */ +#define USBD_FRAME_MATCH_MASK (0x07ff << USBD_FRAME_MATCH_SHIFT) + +/* USBD STAT Register */ + +#define USBD_STAT_ALTSET_SHIFT 0 /* Bit 0-2: Alternate Setting */ +#define USBD_STAT_ALTSET_MASK (0x07 << USBD_FRAME_MATCH_SHIFT) +#define USBD_STAT_INTF_SHIFT 3 /* Bit 3-4: Interface */ +#define USBD_STAT_INTF_MASK (0x03 << USBD_FRAME_MATCH_SHIFT) +#define USBD_STAT_CFG_SHIFT 5 /* Bit 5-6: Configuration */ +#define USBD_STAT_CFG_MASK (0x03 << USBD_FRAME_MATCH_SHIFT) +#define USBD_STAT_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBD_STAT_RST (1 << 8) /* Bit 8: Reset Signaling */ + +/* USBD CTRL Register */ + +#define USBD_CTRL_RESUME (1 << 0) /* Bit 0: Resume */ +#define USBD_CTRL_AFEENA (1 << 1) /* Bit 1: Analog Front-End Enable */ +#define USBD_CTRL_UDCRST (1 << 2) /* Bit 2: UDC Reset */ +#define USBD_CTRL_USBENA (1 << 3) /* Bit 3: USB Enable */ +#define USBD_CTRL_USBSPD (1 << 4) /* Bit 4: USB Speed */ +#define USBD_CTRL_CMDERROR (1 << 5) /* Bit 5: Command Error */ +#define USBD_CTRL_CMDOVER (1 << 6) /* Bit 6: Command Over */ + +/* USBD DADR Register */ + +#define USBD_DADR_DADR_SHIFT 0 /* Bit 0-8: Desired RAM Address */ +#define USBD_DADR_DADR_MASK (0x1ff << USBD_DADR_DADR_SHIFT) +#define USBD_DADR_BSY (1 << 30) /* Bit 30: Busy */ +#define USBD_DADR_CFG (1 << 31) /* Bit 31: Configuration */ + +/* USBD DDAT Register */ + +#define USBD_DDAT_DDAT_SHIFT 0 /* Bit 0-7: Descriptor Data Buffer */ +#define USBD_DDAT_DDAT_MASK (0xff << USBD_DDAT_DDAT_SHIFT) + +/* USBD INTR Register */ + +#define USBD_INTR_CFGCHG (1 << 0) /* Bit 0: Configuration Change */ +#define USBD_INTR_FRAMEMATCH (1 << 1) /* Bit 1: FRAME_MATCH */ +#define USBD_INTR_SUSP (1 << 2) /* Bit 2: Active to Suspend */ +#define USBD_INTR_RES (1 << 3) /* Bit 3: Suspend to Resume */ +#define USBD_INTR_RESETSTART (1 << 4) /* Bit 4: Restart Signaling Start */ +#define USBD_INTR_RESETSTOP (1 << 5) /* Bit 5: Restart Signaling Stop */ +#define USBD_INTR_SOF (1 << 6) /* Bit 6: Start-of-Frame Interrupt */ +#define USBD_INTR_MSOF (1 << 7) /* Bit 7: Missed Start-of-Frame Interrupt */ +#define USBD_INTR_WAKEUP (1 << 31) /* Bit 31: Wakeup */ + +/* USBD MASK Register */ + +#define USBD_MASK_CFGCHG (1 << 0) /* Bit 0: Configuration Change */ +#define USBD_MASK_FRAMEMATCH (1 << 1) /* Bit 1: FRAME_MATCH */ +#define USBD_MASK_SUSP (1 << 2) /* Bit 2: Active to Suspend */ +#define USBD_MASK_RES (1 << 3) /* Bit 3: Suspend to Resume */ +#define USBD_MASK_RESETSTART (1 << 4) /* Bit 4: Restart Signaling Start */ +#define USBD_MASK_RESETSTOP (1 << 5) /* Bit 5: Restart Signaling Stop */ +#define USBD_MASK_SOF (1 << 6) /* Bit 6: Start-of-Frame Interrupt */ +#define USBD_MASK_MSOF (1 << 7) /* Bit 7: Missed Start-of-Frame Interrupt */ +#define USBD_MASK_WAKEUP (1 << 31) /* Bit 31: Wakeup */ + +/* USBD ENAB Register */ + +#define USBD_ENAB_PWDMD (1 << 0) /* Bit 0: Power Mode */ +#define USBD_ENAB_ENDIANMODE (1 << 28) /* Bit 28: Endian Mode Select */ +#define USBD_ENAB_SUSPEND (1 << 29) /* Bit 29: Suspend */ +#define USBD_ENAB_ENAB (1 << 30) /* Bit 30: Enable */ +#define USBD_ENAB_RST (1 << 31) /* Bit 31: Reset */ + +/* USBD EPSTAT Register */ + +#define USBD_EPSTAT_FORCESTALL (1 << 0) /* Bit 0: Force a Stall Condition */ +#define USBD_EPSTAT_FLUSH (1 << 1) /* Bit 1: Flush */ +#define USBD_EPSTAT_ZLPS (1 << 2) /* Bit 2: Zero Length Packet Send */ +#define USBD_EPSTAT_TYP_SHIFT 3 /* Bit 3-4: Endpoint Type */ +#define USBD_EPSTAT_TYP_MASK (0x03 << USBD_EPSTAT_TYP_SHIFT) +#define USBD_EPSTAT_MAX_SHIFT 5 /* Bit 5-6: Maximum Packet Size */ +#define USBD_EPSTAT_MAX_MASK (0x03 << USBD_EPSTAT_MAX_SHIFT) +#define USBD_EPSTAT_DIR (1 << 7) /* Bit 7: Transfer Direction */ +#define USBD_EPSTAT_SIP (1 << 8) /* Bit 8: Setup Packet in Progress */ +#define USBD_EPSTAT_BYTECOUNT_SHIFT 16 /* Bit 16-22: Byte Count */ +#define USBD_EPSTAT_BYTECOUNT_MASK (0x7f << USBD_EPSTAT_BYTECOUNT_SHIFT) + +/* USBD EPINTR Register */ + +#define USBD_EPINTR_EOF (1 << 0) /* Bit 0: End-of-Frame */ +#define USBD_EPINTR_DEVREQ (1 << 1) /* Bit 1: Device Request */ +#define USBD_EPINTR_EOT (1 << 2) /* Bit 2: End of Transfer */ +#define USBD_EPINTR_MDEVREQ (1 << 3) /* Bit 3: Multiple Device Request */ +#define USBD_EPINTR_FIFOLOW (1 << 4) /* Bit 4: FIFO Low */ +#define USBD_EPINTR_FIFOHIGH (1 << 5) /* Bit 5: FIFO High */ +#define USBD_EPINTR_FIFOERROR (1 << 6) /* Bit 6: FIFO Error */ +#define USBD_EPINTR_FIFOEMPTY (1 << 7) /* Bit 7: FIFO Empty */ +#define USBD_EPINTR_FIFOFULL (1 << 8) /* Bit 8: FIFO Full */ + +/* USBD EPMASK Register */ + +#define USBD_EPMASK_EOF (1 << 0) /* Bit 0: End-of-Frame */ +#define USBD_EPMASK_DEVREQ (1 << 1) /* Bit 1: Device Request */ +#define USBD_EPMASK_EOT (1 << 2) /* Bit 2: End of Transfer */ +#define USBD_EPMASK_MDEVREQ (1 << 3) /* Bit 3: Multiple Device Request */ +#define USBD_EPMASK_FIFOLOW (1 << 4) /* Bit 4: FIFO Low */ +#define USBD_EPMASK_FIFOHIGH (1 << 5) /* Bit 5: FIFO High */ +#define USBD_EPMASK_FIFOERROR (1 << 6) /* Bit 6: FIFO Error */ +#define USBD_EPMASK_FIFOEMPTY (1 << 7) /* Bit 7: FIFO Empty */ +#define USBD_EPMASK_FIFOFULL (1 << 8) /* Bit 8: FIFO Full */ + +/* USBD EPFSTAT Register */ + +#define USBD_EPFSTAT_EMPTY (1 << 16) /* Bit 16: FIFO Empty */ +#define USBD_EPFSTAT_ALARM (1 << 17) /* Bit 17: FIFO Alarm */ +#define USBD_EPFSTAT_FULL (1 << 18) /* Bit 18: FIFO Full */ +#define USBD_EPFSTAT_FR (1 << 19) /* Bit 19: FIFO Ready */ +#define USBD_EPFSTAT_OF (1 << 20) /* Bit 20: FIFO Overflow */ +#define USBD_EPFSTAT_UF (1 << 21) /* Bit 21: FIFO Underflow */ +#define USBD_EPFSTAT_ERROR (1 << 22) /* Bit 22: FIFO Error */ +#define USBD_EPFSTAT_FRAME3 (1 << 24) /* Bit 24: Frame Status Bit 3 */ +#define USBD_EPFSTAT_FRAME2 (1 << 25) /* Bit 25: Frame Status Bit 2 */ +#define USBD_EPFSTAT_FRAME1 (1 << 26) /* Bit 26: Frame Status Bit 1 */ +#define USBD_EPFSTAT_FRAME0 (1 << 27) /* Bit 27: Frame Status Bit 0 */ + +/* USBD EPFCTRL Register */ + +#define USBD_EPCTRL_GR_SHIFT 24 /* Bit 24-26: Granularity */ +#define USBD_EPCTRL_GR_MASK (0x07 << USBD_EPCTRL_GR_SHIFT) +#define USBD_EPCTRL_FRAME (1 << 27) /* Bit 27: Frame Mode */ +#define USBD_EPCTRL_WFR (1 << 28) /* Bit 29: Write Frame End */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_USBD_H */ diff --git a/arch/arm/src/imx1/imx_wdog.h b/arch/arm/src/imx1/imx_wdog.h new file mode 100644 index 0000000000000000000000000000000000000000..1336c76c669467cd2345725076e5e69250212da9 --- /dev/null +++ b/arch/arm/src/imx1/imx_wdog.h @@ -0,0 +1,81 @@ +/************************************************************************************ + * arch/arm/src/imx1/imx_wdog.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_IMX_WDOG_H +#define __ARCH_ARM_IMX_WDOG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* WDOG Register Offsets ************************************************************/ + +#define WDOG_WCR_OFFSET 0x0000 /* Watchdog Control Register */ +#define WDOG_WSR_OFFSET 0x0004 /* Watchdog Service Register */ +#define WDOG_WSTR_OFFSET 0x0008 /* Watchdog Status Register */ + +/* WDOG Register Addresses **********************************************************/ + +#define IMX_WDOG_WCR (IMX_WDOG_VBASE + WDOG_WCR_OFFSET) +#define IMX_WDOG_WSR (IMX_WDOG_VBASE + WDOG_WSR_OFFSET) +#define IMX_WDOG_WSTRT (IMX_WDOG_VBASE + WDOG_WSTR_OFFSET) + +/* WDOG Register Bit Definitions ****************************************************/ + +/* Watchdog Control Register */ + +#define WDOG_WCR_WDE (1 << 0) /* Bit 0: Watchdog Enable */ +#define WDOG_WCR_WDEC (1 << 1) /* Bit 1: Watchdog Enable Control */ +#define WDOG_WCR_SWR (1 << 2) /* Bit 2: Software Reset Enable */ +#define WDOG_WCR_TMD (1 << 3) /* Bit 3: Test Mode Enable */ +#define WDOG_WCR_WIE (1 << 4) /* Bit 4: Watchdog Interrupt Enable */ +#define WDOG_WCR_WT_SHIFT 8 /* Bit 8-14: Watchdog Timeout */ +#define WDOG_WCR_WT_MASK (0x7f << WDOG_WCR_WT_SHIFT) +#define WDOG_WCR_WHALT (1 << 15) /* Bit 15: Watchdog Halt */ + +/* Watchdog Service Register */ + +#define WDOG_WSR_SHIFT 0 /* Bit 0-15: Watchdog Service Register */ +#define WDOG_WT_MASK (0xffff << WDOG_WSR_SHIFT) + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_IMX_WDOG_H */ diff --git a/arch/arm/src/imx6/Kconfig b/arch/arm/src/imx6/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..7250001d5622e2b40ab11388e47cd1e064d4ba2d --- /dev/null +++ b/arch/arm/src/imx6/Kconfig @@ -0,0 +1,126 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_IMX6 + +menu "iMX.6 Chip Selection" + +choice + prompt "iMX.6 Core Configuration" + default IMX6_6QUAD + +config ARCH_CHIP_IMX6_6SOLOLITE + bool "i.MX 6SoloLite" + select ARMV7A_HAVE_GICv2 + select ARMV7A_HAVE_GTM + select ARMV7A_HAVE_PTM + +config ARCH_CHIP_IMX6_6SOLO + bool "i.MX 6Solo" + select ARMV7A_HAVE_GICv2 + select ARMV7A_HAVE_GTM + select ARMV7A_HAVE_PTM + +config ARCH_CHIP_IMX6_6DUALLITE + bool "i.MX 6DualLite" + select ARCH_HAVE_MULTICPU + select ARMV7A_HAVE_GICv2 + select ARMV7A_HAVE_GTM + select ARMV7A_HAVE_PTM + +config ARCH_CHIP_IMX6_6DUAL + bool "i.MX 6Dual" + select ARCH_HAVE_MULTICPU + select ARMV7A_HAVE_GICv2 + select ARMV7A_HAVE_GTM + select ARMV7A_HAVE_PTM + +config ARCH_CHIP_IMX6_6QUAD + bool "i.MX 6Quad" + select ARCH_HAVE_MULTICPU + select ARMV7A_HAVE_GICv2 + select ARMV7A_HAVE_GTM + select ARMV7A_HAVE_PTM + +endchoice # iMX.6 Chip Selection + +config IMX6_HAVE_HDCP + bool "HDCP enabled" + default n + ---help--- + HDCP - High-bandwidth Digital Content Protection + +endmenu # "iMX.6 Chip Selection" + +menu "iMX.6 Peripheral Selection" + +config IMX6_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + +config IMX6_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + +config IMX6_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + +config IMX6_UART4 + bool "UART4" + default n + select ARCH_HAVE_UART4 + +config IMX6_UART5 + bool "UART5" + default n + select ARCH_HAVE_UART5 + +config IMX6_SPI1 + bool "SPI1" + default n + select SPI + +config IMX6_SPI2 + bool "SPI2" + default n + select SPI + +endmenu # iMX Peripheral Selection + +config IMX_DDR_SIZE + int "Installed DRAM size (bytes)" + default 268435456 + +choice + prompt "i.MX6 Boot Configuration" + default IMX6_BOOT_SDRAM + ---help--- + The startup code needs to know if the code is running from internal SRAM, + external SRAM, or CS0-3 in order to initialize properly. Note that the + boot device is not specified for cases where the code is copied into + RAM. + +config IMX6_BOOT_OCRAM + bool "Running from internal OCRAM" + select BOOT_RUNFROMISRAM + +config IMX6_BOOT_SDRAM + bool "Running from external SDRAM" + select BOOT_RUNFROMSDRAM + +config IMX6_BOOT_NOR + bool "Running from external NOR FLASH" + select BOOT_RUNFROMFLASH + +config IMX6_BOOT_SRAM + bool "Running from external SRAM" + select BOOT_RUNFROMEXTSRAM + +endchoice # i.MX6 Boot Configuration +endif # ARCH_CHIP_IMX6 diff --git a/arch/arm/src/imx6/Make.defs b/arch/arm/src/imx6/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..8ddf77b5e847c810d1a49cb499c2fefe697f209d --- /dev/null +++ b/arch/arm/src/imx6/Make.defs @@ -0,0 +1,149 @@ +############################################################################ +# arch/arm/imx6/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The vector table is the "head" object, i.e., the one that must forced into +# the link in order to draw in all of the other components + +HEAD_ASRC = arm_vectortab.S + +ifeq ($(CONFIG_BUILD_KERNEL),y) +STARTUP_OBJS = crt0$(OBJEXT) +endif + +# Force the start-up logic to be at the beginning of the .text to simplify +# debug. + +ifeq ($(CONFIG_PAGING),y) +CMN_ASRCS = arm_pghead.S +else +CMN_ASRCS = arm_head.S +endif + +# Common assembly language files + +CMN_ASRCS += arm_vectors.S arm_fpuconfig.S arm_fullcontextrestore.S +CMN_ASRCS += arm_saveusercontext.S arm_vectoraddrexcptn.S arm_vfork.S +CMN_ASRCS += arm_testset.S +CMN_ASRCS += cp15_coherent_dcache.S cp15_invalidate_dcache.S +CMN_ASRCS += cp15_clean_dcache.S cp15_flush_dcache.S cp15_invalidate_dcache_all.S + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += arm_memcpy.S +endif + +# Common C source files + +CMN_CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_exit.c +CMN_CSRCS += up_createstack.c up_releasestack.c up_usestack.c up_vfork.c +CMN_CSRCS += up_puts.c up_mdelay.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c +CMN_CSRCS += arm_doirq.c arm_gicv2.c arm_initialstate.c arm_mmu.c +CMN_CSRCS += arm_prefetchabort.c arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c +CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c + +ifeq ($(CONFIG_SMP),y) +CMN_CSRCS += arm_cpuindex.c arm_cpustart.c arm_cpupause.c +endif + +ifeq ($(CONFIG_DEBUG_IRQ),y) +CMN_CSRCS += arm_gicv2_dump.c +endif + +# Use common heap allocation for now (may need to be customized later) + +CMN_CSRCS += up_allocateheap.c + +# Configuration dependent C and assembly language files + +ifeq ($(CONFIG_PAGING),y) +CMN_CSRCS += arm_allocpage.c arm_checkmapping.c arm_pginitialize.c +CMN_CSRCS += arm_va2pte.c +endif + +ifeq ($(CONFIG_BUILD_KERNEL),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c arm_signal_dispatch.c +endif + +ifeq ($(CONFIG_ARCH_ADDRENV),y) +CMN_CSRCS += arm_addrenv.c arm_addrenv_utils.c arm_pgalloc.c +ifeq ($(CONFIG_ARCH_STACK_DYNAMIC),y) +CMN_CSRCS += arm_addrenv_ustack.c +endif +ifeq ($(CONFIG_ARCH_KERNEL_STACK),y) +CMN_CSRCS += arm_addrenv_kstack.c +endif +ifeq ($(CONFIG_MM_SHM),y) +CMN_CSRCS += arm_addrenv_shm.c +endif +endif + +ifeq ($(CONFIG_MM_PGALLOC),y) +CMN_CSRCS += arm_physpgaddr.c +ifeq ($(CONFIG_ARCH_PGPOOL_MAPPING),y) +CMN_CSRCS += arm_virtpgaddr.c +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_savefpu.S arm_restorefpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# i.MX6-specific assembly language files + +CHIP_ASRCS = + +# i.MX6-specific C source files + +CHIP_CSRCS = imx_boot.c imx_memorymap.c imx_clockconfig.c imx_irq.c +CHIP_CSRCS += imx_timerisr.c imx_gpio.c imx_iomuxc.c +CHIP_CSRCS += imx_serial.c imx_lowputc.c + +ifeq ($(CONFIG_SMP),y) +CHIP_CSRCS += imx_cpuinit.c +endif diff --git a/arch/arm/src/imx6/chip.h b/arch/arm/src/imx6/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..504e1ee4d2d10d90377ab95d003e86681b55fc8a --- /dev/null +++ b/arch/arm/src/imx6/chip.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/imx6/chip.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_H +#define __ARCH_ARM_SRC_IMX6_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/imx_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MPCore registers are memory mapped and accessed through a processor + * specific private address space via the SCU. The Cortex-A9 MCU chip.h + * header file must provide the definition CHIP_MPCORE_VBASE to access this + * the registers in this memory region. + */ + +#define CHIP_MPCORE_VBASE IMX_ARMMP_VSECTION + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_H */ diff --git a/arch/arm/src/imx6/chip/imx_ccm.h b/arch/arm/src/imx6/chip/imx_ccm.h new file mode 100644 index 0000000000000000000000000000000000000000..73faa18365e27b555d5835dcf5fa1d0139ef7030 --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_ccm.h @@ -0,0 +1,1035 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_ccm.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_CCM_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_CCM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* CCM Register Offsets *************************************************************/ + +#define IMX_CCM_CCR_OFFSET 0x0000 /* CCM Control Register */ +#define IMX_CCM_CCDR_OFFSET 0x0004 /* CCM Control Divider Register */ +#define IMX_CCM_CSR_OFFSET 0x0008 /* CCM Status Register */ +#define IMX_CCM_CCSR_OFFSET 0x000c /* CCM Clock Switcher Register */ +#define IMX_CCM_CACRR_OFFSET 0x0010 /* CCM Arm Clock Root Register */ +#define IMX_CCM_CBCDR_OFFSET 0x0014 /* CCM Bus Clock Divider Register */ +#define IMX_CCM_CBCMR_OFFSET 0x0018 /* CCM Bus Clock Multiplexer Register */ +#define IMX_CCM_CSCMR1_OFFSET 0x001c /* CCM Serial Clock Multiplexer Register 1 */ +#define IMX_CCM_CSCMR2_OFFSET 0x0020 /* CCM Serial Clock Multiplexer Register 2 */ +#define IMX_CCM_CSCDR1_OFFSET 0x0024 /* CCM Serial Clock Divider Register 1 */ +#define IMX_CCM_CS1CDR_OFFSET 0x0028 /* CCM SSI1 Clock Divider Register */ +#define IMX_CCM_CS2CDR_OFFSET 0x002c /* CCM SSI2 Clock Divider Register */ +#define IMX_CCM_CDCDR_OFFSET 0x0030 /* CCM D1 Clock Divider Register */ +#define IMX_CCM_CHSCCDR_OFFSET 0x0034 /* CCM HSC Clock Divider Register */ +#define IMX_CCM_CSCDR2_OFFSET 0x0038 /* CCM Serial Clock Divider Register 2 */ +#define IMX_CCM_CSCDR3_OFFSET 0x003c /* CCM Serial Clock Divider Register 3 */ +#define IMX_CCM_CWDR_OFFSET 0x0044 /* CCM Wakeup Detector Register */ +#define IMX_CCM_CDHIPR_OFFSET 0x0048 /* CCM Divider Handshake In-Process Register */ +#define IMX_CCM_CLPCR_OFFSET 0x0054 /* CCM Low Power Control Register */ +#define IMX_CCM_CISR_OFFSET 0x0058 /* CCM Interrupt Status Register */ +#define IMX_CCM_CIMR_OFFSET 0x005c /* CCM Interrupt Mask Register */ +#define IMX_CCM_CCOSR_OFFSET 0x0060 /* CCM Clock Output Source Register */ +#define IMX_CCM_CGPR_OFFSET 0x0064 /* CCM General Purpose Register */ +#define IMX_CCM_CCGR0_OFFSET 0x0068 /* CCM Clock Gating Register 0 */ +#define IMX_CCM_CCGR1_OFFSET 0x006c /* CCM Clock Gating Register 1 */ +#define IMX_CCM_CCGR2_OFFSET 0x0070 /* CCM Clock Gating Register 2 */ +#define IMX_CCM_CCGR3_OFFSET 0x0074 /* CCM Clock Gating Register 3 */ +#define IMX_CCM_CCGR4_OFFSET 0x0078 /* CCM Clock Gating Register 4 */ +#define IMX_CCM_CCGR5_OFFSET 0x007c /* CCM Clock Gating Register 5 */ +#define IMX_CCM_CCGR6_OFFSET 0x0080 /* CCM Clock Gating Register 6 */ +#define IMX_CCM_CMEOR_OFFSET 0x0088 /* CCM Module Enable Overide Register */ + +/* CCM Register Addresses ***********************************************************/ + +#define IMX_CCM_CCR (IMX_CCM_VBASE+IMX_CCM_CCR_OFFSET) +#define IMX_CCM_CCDR (IMX_CCM_VBASE+IMX_CCM_CCDR_OFFSET) +#define IMX_CCM_CSR (IMX_CCM_VBASE+IMX_CCM_CSR_OFFSET) +#define IMX_CCM_CCSR (IMX_CCM_VBASE+IMX_CCM_CCSR_OFFSET) +#define IMX_CCM_CACRR (IMX_CCM_VBASE+IMX_CCM_CACRR_OFFSET) +#define IMX_CCM_CBCDR (IMX_CCM_VBASE+IMX_CCM_CBCDR_OFFSET) +#define IMX_CCM_CBCMR (IMX_CCM_VBASE+IMX_CCM_CBCMR_OFFSET) +#define IMX_CCM_CSCMR1 (IMX_CCM_VBASE+IMX_CCM_CSCMR1_OFFSET) +#define IMX_CCM_CSCMR2 (IMX_CCM_VBASE+IMX_CCM_CSCMR2_OFFSET) +#define IMX_CCM_CSCDR1 (IMX_CCM_VBASE+IMX_CCM_CSCDR1_OFFSET) +#define IMX_CCM_CS1CDR (IMX_CCM_VBASE+IMX_CCM_CS1CDR_OFFSET) +#define IMX_CCM_CS2CDR (IMX_CCM_VBASE+IMX_CCM_CS2CDR_OFFSET) +#define IMX_CCM_CDCDR (IMX_CCM_VBASE+IMX_CCM_CDCDR_OFFSET) +#define IMX_CCM_CHSCCDR (IMX_CCM_VBASE+IMX_CCM_CHSCCDR_OFFSET) +#define IMX_CCM_CSCDR2 (IMX_CCM_VBASE+IMX_CCM_CSCDR2_OFFSET) +#define IMX_CCM_CSCDR3 (IMX_CCM_VBASE+IMX_CCM_CSCDR3_OFFSET) +#define IMX_CCM_CWDR (IMX_CCM_VBASE+IMX_CCM_CWDR_OFFSET) +#define IMX_CCM_CDHIPR (IMX_CCM_VBASE+IMX_CCM_CDHIPR_OFFSET) +#define IMX_CCM_CLPCR (IMX_CCM_VBASE+IMX_CCM_CLPCR_OFFSET) +#define IMX_CCM_CISR (IMX_CCM_VBASE+IMX_CCM_CISR_OFFSET) +#define IMX_CCM_CIMR (IMX_CCM_VBASE+IMX_CCM_CIMR_OFFSET) +#define IMX_CCM_CCOSR (IMX_CCM_VBASE+IMX_CCM_CCOSR_OFFSET) +#define IMX_CCM_CGPR (IMX_CCM_VBASE+IMX_CCM_CGPR_OFFSET) +#define IMX_CCM_CCGR0 (IMX_CCM_VBASE+IMX_CCM_CCGR0_OFFSET) +#define IMX_CCM_CCGR1 (IMX_CCM_VBASE+IMX_CCM_CCGR1_OFFSET) +#define IMX_CCM_CCGR2 (IMX_CCM_VBASE+IMX_CCM_CCGR2_OFFSET) +#define IMX_CCM_CCGR3 (IMX_CCM_VBASE+IMX_CCM_CCGR3_OFFSET) +#define IMX_CCM_CCGR4 (IMX_CCM_VBASE+IMX_CCM_CCGR4_OFFSET) +#define IMX_CCM_CCGR5 (IMX_CCM_VBASE+IMX_CCM_CCGR5_OFFSET) +#define IMX_CCM_CCGR6 (IMX_CCM_VBASE+IMX_CCM_CCGR6_OFFSET) +#define IMX_CCM_CMEOR (IMX_CCM_VBASE+IMX_CCM_CMEOR_OFFSET) + +/* CCM Register Bit Definitions *****************************************************/ + +/* CCM Control Register */ + +#define CCM_CCR_OSCNT_SHIFT (0) /* Bits 0-7: Oscillator ready counter value */ +#define CCM_CCR_OSCNT_MASK (0xff << CCM_CCR_OSCNT_SHIFT) +# define CCM_CCR_OSCNT(n) ((uint32_t)(n) << CCM_CCR_OSCNT_SHIFT) +#define CCM_CCR_COSC_EN (1 << 12) /* Bit 12: On chip oscillator enable bit */ +#define CCM_CCR_WB_COUNT_SHIFT (16) /* Bits 16-18: Well Bias counter */ +#define CCM_CCR_WB_COUNT_MASK (7 << CCM_CCR_WB_COUNT_SHIFT) +# define CCM_CCR_WB_COUNT(n) ((uint32_t)(n) << CCM_CCR_WB_COUNT_SHIFT) +#define CCM_CCR_REG_BYPASS_COUNT_SHIFT (21) /* Bits 21-26: Counter for analog_reg_bypass signal assertion */ +#define CCM_CCR_REG_BYPASS_COUNT_MASK (0x3f << CCM_CCR_REG_BYPASS_COUNT_SHIFT) +# define CCM_CCR_REG_BYPASS_COUNT(n) ((uint32_t)(n) << CCM_CCR_REG_BYPASS_COUNT_SHIFT) +#define CCM_CCR_RBC_EN (1 << 27) /* Bit 27: Enable for REG_BYPASS_COUNTER */ + +/* CCM Control Divider Register */ + +#define CCM_CCDR_MMDC_CH1_MASK (1 << 16) /* Bit 16: Mask handshake with mmdc_ch1 */ +#define CCM_CCDR_MMDC_CH0_MASK (1 << 17) /* Bit 17: Mask handshake with mmdc_ch0 */ + +/* CCM Status Register */ + +#define CCM_CSR_REF_EN_B (1 << 0) /* Bit 0: Value of CCM_REF_EN_B output */ +#define CCM_CSR_COSC_READY (1 << 5) /* Bit 5: Status of on-board oscillator */ + +/* CCM Clock Switcher Register */ + +#define CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0) /* Bit 0: Selects source to generate pll3_sw_clk */ +#define CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) /* Bit 2: Selects source to generate pll1_sw_clk */ +#define CCM_CCSR_STEP_SEL (1 << 8) /* Bit 8: Step frequency when shifting ARM frequency */ +#define CCM_CCSR_PLL2_PFD2_DIS (1 << 9) /* Bit 9: Mask of PLL2 PFD2 auto-disable */ +#define CCM_CCSR_PLL2_PFD0_DIS (1 << 10) /* Bit 10: Mask of PLL2 PFD0 auto-disable */ +#define CCM_CCSR_PLL2_PFD1_594M_DIS (1 << 11) /* Bit 11: Mask of PLL2 PFD1 auto-disable */ +#define CCM_CCSR_PLL3_PFD2_DIS (1 << 12) /* Bit 12: Mask of PLL3 PFD2 auto-disable */ +#define CCM_CCSR_PLL3_PFD3_DIS (1 << 13) /* Bit 13: Mask of PLL3 PFD3 auto-disable */ +#define CCM_CCSR_PLL3_PFD0_DIS (1 << 14) /* Bit 14: Mask of PLL3 PFD0 auto-disable */ +#define CCM_CCSR_PLL3_PFD1_DIS (1 << 15) /* Bit 15: Mask of PLL3 PFD1 auto-disable */ + +/* CCM Arm Clock Root Register */ + +#define CCM_CACRR_ARM_PODF_SHIFT (0) /* Bits 0-2: Divider for ARM clock root */ +#define CCM_CACRR_ARM_PODF_MASK (7 << CCM_CACRR_ARM_PODF_SHIFT) +# define CCM_CACRR_ARM_PODF(n) ((uint32_t)(n) << CCM_CACRR_ARM_PODF_SHIFT) + +/* CCM Bus Clock Divider Register */ + +#define CCM_CBCDR_PERIPH2_CLK2_PODF_SHIFT (0) /* Bits 0-2: Divider for periph2_clk2 podf */ +#define CCM_CBCDR_PERIPH2_CLK2_PODF_MASK (7 << CCM_CBCDR_PERIPH2_CLK2_PODF_SHIFT) +# define CCM_CBCDR_PERIPH2_CLK2_PODF(n) ((uint32_t)(n) << CCM_CBCDR_PERIPH2_CLK2_PODF_SHIFT) +#define CCM_CBCDR_MMDC_CH1_AXI_PODF_SHIFT (3) /* Bits 3-5: Divider for mmdc_ch1_axi podf */ +#define CCM_CBCDR_MMDC_CH1_AXI_PODF_MASK (7 << CCM_CBCDR_MMDC_CH1_AXI_PODF_SHIFT) +# define CCM_CBCDR_MMDC_CH1_AXI_PODF(n) ((uint32_t)(n) << CCM_CBCDR_MMDC_CH1_AXI_PODF_SHIFT) +#define CCM_CBCDR_AXI_SEL (1 << 6) /* Bit 6: AXI clock source select */ +#define CCM_CBCDR_AXI_ALT_SEL (1 << 7) /* Bit 7: AXI alternative clock select */ +#define CCM_CBCDR_IPG_PODF_SHIFT (8) /* Bits 8-9: Divider for ipg podf */ +#define CCM_CBCDR_IPG_PODF_MASK (3 << CCM_CBCDR_IPG_PODF_SHIFT) +# define CCM_CBCDR_IPG_PODF(n) ((uint32_t)(n) << CCM_CBCDR_IPG_PODF_SHIFT) +#define CCM_CBCDR_AHB_PODF_SHIFT (10) /* Bits 10-12: Divider for AHB PODF */ +#define CCM_CBCDR_AHB_PODF_MASK (7 << CCM_CBCDR_AHB_PODF_SHIFT) +# define CCM_CBCDR_AHB_PODF(n) ((uint32_t)(n) << CCM_CBCDR_AHB_PODF_SHIFT) +#define CCM_CBCDR_AXI_PODF_SHIFT (16) /* Bits 16-18: Divider for AXI PODF */ +#define CCM_CBCDR_AXI_PODF_MASK (7 << CCM_CBCDR_AXI_PODF_SHIFT) +# define CCM_CBCDR_AXI_PODF(n) ((uint32_t)(n) << CCM_CBCDR_AXI_PODF_SHIFT) +#define CCM_CBCDR_MMDC_CH0_AXI_PODF_SHIFT (19) /* Bits 19-21: Divider for mmdc_ch0_axi podf */ +#define CCM_CBCDR_MMDC_CH0_AXI_PODF_MASK (7 << CCM_CBCDR_MMDC_CH0_AXI_PODF_SHIFT) +# define CCM_CBCDR_MMDC_CH0_AXI_PODF(n) ((uint32_t)(n) << CCM_CBCDR_MMDC_CH0_AXI_PODF_SHIFT) +#define CCM_CBCDR_PERIPH_CLK_SEL (1 << 25) /* Bit 25: Selector for peripheral main clock */ +#define CCM_CBCDR_PERIPH2_CLK_SEL (1 << 26) /* Bit 26: Selector for peripheral2 main clock */ +#define CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT (27) /* Bits 27-29: Divider for periph2 clock podf */ +#define CCM_CBCDR_PERIPH_CLK2_PODF_MASK (7 << CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) +# define CCM_CBCDR_PERIPH_CLK2_PODF(n) ((uint32_t)(n) << CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + +/* CCM Bus Clock Multiplexer Register */ + +#define CCM_CBCMR_GPU2D_AXI_CLK_SEL (1 << 0) /* Bit 0: Selector for gpu2d_axi clock multiplexer */ +#define CCM_CBCMR_GPU3D_AXI_CLK_SEL (1 << 1) /* Bit 1: Selector for gpu3d_axi clock multiplexer */ +#define CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT (4) /* Bits 4-5: Selector for gpu3d_core clock multiplexer */ +#define CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK (3 << CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT) +# define CCM_CBCMR_GPU3D_CORE_CLK_SEL_MMDC_CH0 (0 << CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 */ +# define CCM_CBCMR_GPU3D_CORE_CLK_SEL_PLL3_SWCLK (1 << CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CBCMR_GPU3D_CORE_CLK_SEL_PLL2_PFD1 (2 << CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD1 */ +# define CCM_CBCMR_GPU3D_CORE_CLK_SEL_PLL2_PFD2 (3 << CCM_CBCMR_GPU3D_CORE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +#define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT (8) /* Bits 8-9: Selector for gpu3d_shader clock multiplexer */ +#define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK (3 << CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT) +# define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MMDC_CH0 (0 << CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clk */ +# define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_PLL3_SWCLK (1 << CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_PLL2_PFD1 (2 << CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD1 */ +# define CCM_CBCMR_GPU3D_SHADER_CLK_SEL_PLL3_PFD0 (3 << CCM_CBCMR_GPU3D_SHADER_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD0 */ +#define CCM_CBCMR_PCIE_AXI_CLK_SEL (1 << 10) /* Bit 10: Selector for pcie_axi clock multiplexer */ +#define CCM_CBCMR_VDOAXI_CLK_SEL (1 << 11) /* Bit 11: Selector for vdoaxi clock multiplexer */ +#define CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT (12) /* Bits 12-13: Selector for peripheral clk2 clock multiplexer */ +#define CCM_CBCMR_PERIPH_CLK2_SEL_MASK (3 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) +# define CCM_CBCMR_PERIPH_CLK2_SEL_PLL3_SWCLK (0 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CBCMR_PERIPH_CLK2_SEL_OSC_CLK (1 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) /* Derive clock from osc_clk (pll1_ref_clk) */ +# define CCM_CBCMR_PERIPH_CLK2_SEL_PLL2_BYPASS (2 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) /* Derive clock from pll2_bypass_clk */ +#define CCM_CBCMR_VPU_AXI_CLK_SEL_SHIFT (14) /* Bits 14-15: Selector for VPU axi clock multiplexer */ +#define CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (3 << CCM_CBCMR_VPU_AXI_CLK_SEL_SHIFT) +# define CCM_CBCMR_VPU_AXI_CLK_SEL_AXI (0 << CCM_CBCMR_VPU_AXI_CLK_SEL_SHIFT) /* Derive clock from AXI */ +# define CCM_CBCMR_VPU_AXI_CLK_SEL_PLL2_PFD2 (1 << CCM_CBCMR_VPU_AXI_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CBCMR_VPU_AXI_CLK_SEL_PLL2_PFD0 (2 << CCM_CBCMR_VPU_AXI_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +#define CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT (16) /* Bits 16-17: Selector for open vg (GPU2D Core) clock multiplexer */ +#define CCM_CBCMR_GPU2D_CORE_CLK_SEL_MASK (3 << CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT) +# define CCM_CBCMR_GPU2D_CORE_CLK_SEL_AXI (0 << CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT) /* Derive clock from AXI */ +# define CCM_CBCMR_GPU2D_CORE_CLK_SEL_PLL3_SWCLK (1 << CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CBCMR_GPU2D_CORE_CLK_SEL_PLL2_PFD0 (2 << CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CBCMR_GPU2D_CORE_CLK_SEL_PLL2_PFD2 (3 << CCM_CBCMR_GPU2D_CORE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +#define CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT (18) /* Bits 18-19: Selector for pre_periph clock multiplexer */ +#define CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK (3 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2 (0 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) /* Derive clock from PLL2 */ +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD2 (1 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD0 (2 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_DIV_PLL2_PFD2 (3 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) /* Derive clock from divided (/2) PLL2 PFD2 */ +#define CCM_CBCMR_PERIPH2_CLK2_SEL (1 << 20) /* Bit 20: Selector for periph2_clk2 clock multiplexer */ +#define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT (21) /* Bits 21-22: Selector for pre_periph2 clock multiplexer */ +#define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK (3 << CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT) +# define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_PLL2 (0 << CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT) /* Derive clock from PLL2 */ +# define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_PLL2_PFD2 (1 << CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_PLL2_PFD0 (2 << CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CBCMR_PRE_PERIPH2_CLK_SEL_DIV_PLL2_PFD2 (3 << CCM_CBCMR_PRE_PERIPH2_CLK_SEL_SHIFT) /* Derive clock from divided (/2) PLL2 PFD2 */ +#define CCM_CBCMR_GPU2D_CORE_CLK_PODF_SHIFT (23) /* Bits 23-25: Divider for gpu2d_core clock */ +#define CCM_CBCMR_GPU2D_CORE_CLK_PODF_MASK (7 << CCM_CBCMR_GPU2D_CORE_CLK_PODF_SHIFT) +# define CCM_CBCMR_GPU2D_CORE_CLK_PODF(n) ((uint32_t)(n) << CCM_CBCMR_GPU2D_CORE_CLK_PODF_SHIFT) +#define CCM_CBCMR_GPU3D_CORE_PODF_SHIFT (26) /* Bits 26-28: Divider for gpu3d_core clock */ +#define CCM_CBCMR_GPU3D_CORE_PODF_MASK (7 << CCM_CBCMR_GPU3D_CORE_PODF_SHIFT) +# define CCM_CBCMR_GPU3D_CORE_PODF(n) ((uint32_t)(n) << CCM_CBCMR_GPU3D_CORE_PODF_SHIFT) +#define CCM_CBCMR_GPU3D_SHADER_PODF_SHIFT (29) /* Bits 29-31: Divider for gpu3d_shader clock */ +#define CCM_CBCMR_GPU3D_SHADER_PODF_MASK (7 << CCM_CBCMR_GPU3D_SHADER_PODF_SHIFT) +# define CCM_CBCMR_GPU3D_SHADER_PODF(n) ((uint32_t)(n) << CCM_CBCMR_GPU3D_SHADER_PODF_SHIFT) + +/* CCM Serial Clock Multiplexer Register 1 */ + +#define CCM_CSCMR1_PERCLK_PODF_SHIFT (0) /* Bits 0-5: Divider for perclk podf */ +#define CCM_CSCMR1_PERCLK_PODF_MASK (0x3f << CCM_CSCMR1_PERCLK_PODF_SHIFT) +# define CCM_CSCMR1_PERCLK_PODF(n) ((uint32_t)(n) << CCM_CSCMR1_PERCLK_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCMR1_SSI1_CLK_SEL_SHIFT (10) /* Bits 10-11: Selector for ssi1 clock multiplexer */ +#define CCM_CSCMR1_SSI1_CLK_SEL_MASK (3 << CCM_CSCMR1_SSI1_CLK_SEL_SHIFT) +# define CCM_CSCMR1_SSI1_CLK_SEL_PLL3_PFD2 (0 << CCM_CSCMR1_SSI1_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 */ +# define CCM_CSCMR1_SSI1_CLK_SEL_PLL3_PFD3 (1 << CCM_CSCMR1_SSI1_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 */ +# define CCM_CSCMR1_SSI1_CLK_SEL_PLL4 (2 << CCM_CSCMR1_SSI1_CLK_SEL_SHIFT) /* Derive clock from PLL4 */ +#define CCM_CSCMR1_SSI2_CLK_SEL_SHIFT (12) /* Bits 12-13: Selector for ssi2 clock multiplexer */ +#define CCM_CSCMR1_SSI2_CLK_SEL_MASK (3 << CCM_CSCMR1_SSI2_CLK_SEL_SHIFT) +# define CCM_CSCMR1_SSI2_CLK_SEL_PLL3_PFD2 (0 << CCM_CSCMR1_SSI2_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 */ +# define CCM_CSCMR1_SSI2_CLK_SEL_PLL3_PFD3 (1 << CCM_CSCMR1_SSI2_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 */ +# define CCM_CSCMR1_SSI2_CLK_SEL_PLL4 (2 << CCM_CSCMR1_SSI2_CLK_SEL_SHIFT) /* Derive clock from PLL4 */ +#define CCM_CSCMR1_SSI3_CLK_SEL_SHIFT (14) /* Bits 14-15: Selector for ssi3 clock multiplexer */ +#define CCM_CSCMR1_SSI3_CLK_SEL_MASK (3 << CCM_CSCMR1_SSI3_CLK_SEL_SHIFT) +# define CCM_CSCMR1_SSI3_CLK_SEL_PLL3_PFD2 (0 << CCM_CSCMR1_SSI3_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 */ +# define CCM_CSCMR1_SSI3_CLK_SEL_PLL3_PFD3 (1 << CCM_CSCMR1_SSI3_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 */ +# define CCM_CSCMR1_SSI3_CLK_SEL_PLL4 (2 << CCM_CSCMR1_SSI3_CLK_SEL_SHIFT) /* Derive clock from PLL4 */ +#define CCM_CSCMR1_USDHC1_CLK_SEL (1 << 16) /* Bit 16: Selector for usdhc1 clock multiplexer */ +#define CCM_CSCMR1_USDHC2_CLK_SEL (1 << 17) /* Bit 17: Selector for usdhc2 clock multiplexer */ +#define CCM_CSCMR1_USDHC3_CLK_SEL (1 << 18) /* Bit 18: Selector for usdhc3 clock multiplexer */ +#define CCM_CSCMR1_USDHC4_CLK_SEL (1 << 19) /* Bit 19: Selector for usdhc4 clock multiplexer */ +#define CCM_CSCMR1_ACLK_PODF_SHIFT (20) /* Bits 20-22: Divider for aclk clock root */ +#define CCM_CSCMR1_ACLK_PODF_MASK (7 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV1 (6 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV1 (0 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV2 (7 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV2 (1 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV3 (4 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV3 (2 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV4 (5 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV4 (3 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV5 (2 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV5 (4 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV6 (3 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV6 (5 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV7 (0 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV7 (6 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_WDIV8 (1 << CCM_CSCMR1_ACLK_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_PODF_RDIV8 (7 << CCM_CSCMR1_ACLK_PODF_SHIFT) +#define CCM_CSCMR1_ACLK_EIM_SLOW_PODF_SHIFT (23) /* Bits 23-25: Divider for aclk_eim_slow clock root */ +#define CCM_CSCMR1_ACLK_EIM_SLOW_PODF_MASK (7 << CCM_CSCMR1_ACLK_EIM_SLOW_PODF_SHIFT) +# define CCM_CSCMR1_ACLK_EIM_SLOW_PODF(n) ((uint32_t)(n) << CCM_CSCMR1_ACLK_EIM_SLOW_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCMR1_ACLK_SEL_SHIFT (27) /* Bits 27-28: Selector for aclk root clock multiplexer */ +#define CCM_CSCMR1_ACLK_SEL_MASK (3 << CCM_CSCMR1_ACLK_SEL_SHIFT) +# define CCM_CSCMR1_ACLK_SEL_PLL2_PFD2 (0 << CCM_CSCMR1_ACLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CSCMR1_ACLK_SEL_PLL3_SWCLK (1 << CCM_CSCMR1_ACLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CSCMR1_ACLK_SEL_AXI (2 << CCM_CSCMR1_ACLK_SEL_SHIFT) /* Derive clock from AXI */ +# define CCM_CSCMR1_ACLK_SEL_PLL2_PFD0 (3 << CCM_CSCMR1_ACLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +#define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT (29) /* Bits 29-30: Selector for aclk_eim_slow root clock multiplexer */ +#define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_MASK (3 << CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT) +# define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_AXI (0 << CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT) /* Derive clock from AXI */ +# define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_PLL3_SWCLK (1 << CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_PLL2_PFD (2 << CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CSCMR1_ACLK_EIM_SLOW_SEL_PLL2_PFD0 (3 << CCM_CSCMR1_ACLK_EIM_SLOW_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ + +/* CCM Serial Clock Multiplexer Register 2 */ + +#define CCM_CSCMR2_CAN_CLK_PODF_SHIFT (2) /* Bits 2-7: Divider for can clock podf */ +#define CCM_CSCMR2_CAN_CLK_PODF_MASK (0x3f << CCM_CSCMR2_CAN_CLK_PODF_SHIFT) +# define CCM_CSCMR2_CAN_CLK_PODF(n) ((uint32_t)(n) << CCM_CSCMR2_CAN_CLK_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCMR2_LDB_DI0_IPU_DIV (1 << 10) /* Bit 10: Control for divider of ldb clock for IPU di0 */ +#define CCM_CSCMR2_LDB_DI1_IPU_DIV (1 << 11) /* Bit 11: Control for divider of ldb clock for IPU di1 */ +#define CCM_CSCMR2_ESAI_CLK_SEL_SHIFT (19) /* Bits 19-20: Selector for esai clock multiplexer */ +#define CCM_CSCMR2_ESAI_CLK_SEL_MASK (3 << CCM_CSCMR2_ESAI_CLK_SEL_SHIFT) +# define CCM_CSCMR2_ESAI_CLK_SEL_DIV_PLL4 (0 << CCM_CSCMR2_ESAI_CLK_SEL_SHIFT) /* Derive clock from PLL4 divided clock */ +# define CCM_CSCMR2_ESAI_CLK_SEL_PLL3_PFD2 (1 << CCM_CSCMR2_ESAI_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 clock */ +# define CCM_CSCMR2_ESAI_CLK_SEL_PLL3_PFD3 (2 << CCM_CSCMR2_ESAI_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 clock */ +# define CCM_CSCMR2_ESAI_CLK_SEL_PLL3_SWCLK (3 << CCM_CSCMR2_ESAI_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ + +/* CCM Serial Clock Divider Register 1 */ + +#define CCM_CSCDR1_UART_CLK_PODF_SHIFT (0) /* Bits 0-5: Divider for uart clock podf */ +#define CCM_CSCDR1_UART_CLK_PODF_MASK (0x3f << CCM_CSCDR1_UART_CLK_PODF_SHIFT) +# define CCM_CSCDR1_UART_CLK_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_UART_CLK_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR1_USDHC1_PODF_SHIFT (11) /* Bits 11-13: Divider for usdhc1 clock podf */ +#define CCM_CSCDR1_USDHC1_PODF_MASK (7 << CCM_CSCDR1_USDHC1_PODF_SHIFT) +# define CCM_CSCDR1_USDHC1_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_USDHC1_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR1_USDHC2_PODF_SHIFT (16) /* Bits 16-18: Divider for usdhc2 clock */ +#define CCM_CSCDR1_USDHC2_PODF_MASK (7 << CCM_CSCDR1_USDHC2_PODF_SHIFT) +# define CCM_CSCDR1_USDHC2_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_USDHC2_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR1_USDHC3_PODF_SHIFT (19) /* Bits 19-21: Divider for usdhc3 clock podf */ +#define CCM_CSCDR1_USDHC3_PODF_MASK (7 << CCM_CSCDR1_USDHC3_PODF_SHIFT) +# define CCM_CSCDR1_USDHC3_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_USDHC3_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR1_USDHC4_PODF_SHIFT (22) /* Bits 22-24: Divider for usdhc4 clock pred */ +#define CCM_CSCDR1_USDHC4_PODF_MASK (7 << CCM_CSCDR1_USDHC4_PODF_SHIFT) +# define CCM_CSCDR1_USDHC4_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_USDHC4_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR1_VPU_AXI_PODF_SHIFT (25) /* Bits 25-27: Divider for vpu axi clock podf */ +#define CCM_CSCDR1_VPU_AXI_PODF_MASK (7 << CCM_CSCDR1_VPU_AXI_PODF_SHIFT) +# define CCM_CSCDR1_VPU_AXI_PODF(n) ((uint32_t)(n) << CCM_CSCDR1_VPU_AXI_PODF_SHIFT) /* n=(divisor-1) */ + +/* CCM SSI1 Clock Divider Register */ + +#define CCM_CS1CDR_SSI1_CLK_PODF_SHIFT (0) /* Bits 0-5: Divider for ssi1 clock podf */ +#define CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3f << CCM_CS1CDR_SSI1_CLK_PODF_SHIFT) +# define CCM_CS1CDR_SSI1_CLK_PODF(n) ((uint32_t)(n) << CCM_CS1CDR_SSI1_CLK_PODF_SHIFT) +#define CCM_CS1CDR_SSI1_CLK_PRED_SHIFT (6) /* Bits 6-8: Divider for ssi1 clock pred */ +#define CCM_CS1CDR_SSI1_CLK_PRED_MASK (7 << CCM_CS1CDR_SSI1_CLK_PRED_SHIFT) +# define CCM_CS1CDR_SSI1_CLK_PRED(n) ((uint32_t)(n) << CCM_CS1CDR_SSI1_CLK_PRED_SHIFT) /* n=(divisor-1) */ +#define CCM_CS1CDR_ESAI_CLK_PRED_SHIFT (9) /* Bits 9-11: Divider for esai clock pred */ +#define CCM_CS1CDR_ESAI_CLK_PRED_MASK (7 << CCM_CS1CDR_ESAI_CLK_PRED_SHIFT) +# define CCM_CS1CDR_ESAI_CLK_PRED(n) ((uint32_t)(n) << CCM_CS1CDR_ESAI_CLK_PRED_SHIFT) /* n=(divisor-1) */ +#define CCM_CS1CDR_SSI3_CLK_PODF_SHIFT (16) /* Bits 16-21: Divider for ssi3 clock podf */ +#define CCM_CS1CDR_SSI3_CLK_PODF_MASK (0x3f << CCM_CS1CDR_SSI3_CLK_PODF_SHIFT) +# define CCM_CS1CDR_SSI3_CLK_PODF(n) ((uint32_t)(n) << CCM_CS1CDR_SSI3_CLK_PODF_SHIFT) +#define CCM_CS1CDR_SSI3_CLK_PRED_SHIFT (22) /* Bits 22-24: Divider for ssi3 clock pred */ +#define CCM_CS1CDR_SSI3_CLK_PRED_MASK (7 << CCM_CS1CDR_SSI3_CLK_PRED_SHIFT) +# define CCM_CS1CDR_SSI3_CLK_PRED(n) ((uint32_t)(n) << CCM_CS1CDR_SSI3_CLK_PRED_SHIFT) /* n=(divisor-1) */ +#define CCM_CS1CDR_ESAI_CLK_PODF_SHIFT (25) /* Bits 25-27: Divider for esai clock podf */ +#define CCM_CS1CDR_ESAI_CLK_PODF_MASK (7 << CCM_CS1CDR_ESAI_CLK_PODF_SHIFT) +# define CCM_CS1CDR_ESAI_CLK_PODF(n) ((uint32_t)(n) << CCM_CS1CDR_ESAI_CLK_PODF_SHIFT) /* n=(divisor-1) */ + +/* CCM SSI2 Clock Divider Register */ + +#define CCM_CS2CDR_SSI2_CLK_PODF_SHIFT (0) /* Bits 0-5: Divider for ssi2 clock podf */ +#define CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3f << CCM_CS2CDR_SSI2_CLK_PODF_SHIFT) +# define CCM_CS2CDR_SSI2_CLK_PODF(n) ((uint32_t)(n) << CCM_CS2CDR_SSI2_CLK_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CS2CDR_SSI2_CLK_PRED_SHIFT (6) /* Bits 6-8: Divider for ssi2 clock pred */ +#define CCM_CS2CDR_SSI2_CLK_PRED_MASK (7 << CCM_CS2CDR_SSI2_CLK_PRED_SHIFT) +# define CCM_CS2CDR_SSI2_CLK_PRED(n) ((uint32_t)(n) << CCM_CS2CDR_SSI2_CLK_PRED_SHIFT) /* n=(divisor-1) */ +#define CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT (9) /* Bits 9-11: Selector for ldb_di1 clock multiplexer */ +#define CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK (7 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) +# define CCM_CS2CDR_LDB_DI0_CLK_SEL_PLL5 (0 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) /* Derive from PLL5 clock */ +# define CCM_CS2CDR_LDB_DI0_CLK_SEL_PLL2_PFD0 (1 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CS2CDR_LDB_DI0_CLK_SEL_PLL2_PFD2 (2 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CS2CDR_LDB_DI0_CLK_SEL_MMDC_CH1 (3 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch1 clock */ +# define CCM_CS2CDR_LDB_DI0_CLK_SEL_PLL3_SWCLK (4 << CCM_CS2CDR_LDB_DI0_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +#define CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT (12) /* Bits 12-14: Selector for ldb_di1 clock multiplexer */ +#define CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK (7 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) +# define CCM_CS2CDR_LDB_DI1_CLK_SEL_PLL5 (0 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) /* Derive PLL5 clock */ +# define CCM_CS2CDR_LDB_DI1_CLK_SEL_PLL2_PFD0 (1 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CS2CDR_LDB_DI1_CLK_SEL_PLL2_PFD2 (2 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CS2CDR_LDB_DI1_CLK_SEL_MMDC_CH1 (3 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch1 clock */ +# define CCM_CS2CDR_LDB_DI1_CLK_SEL_PLL3_SWCLK (4 << CCM_CS2CDR_LDB_DI1_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +#define CCM_CS2CDR_ENFC_CLK_SEL_SHIFT (16) /* Bits 16-17: Selector for enfc clock multiplexer */ +#define CCM_CS2CDR_ENFC_CLK_SEL_MASK (3 << CCM_CS2CDR_ENFC_CLK_SEL_SHIFT) +# define CCM_CS2CDR_ENFC_CLK_SEL_PLL2_PFD0 (0 << CCM_CS2CDR_ENFC_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CS2CDR_ENFC_CLK_SEL_PLL2 (1 << CCM_CS2CDR_ENFC_CLK_SEL_SHIFT) /* Derive clock from PLL2 */ +# define CCM_CS2CDR_ENFC_CLK_SEL_PLL3_SWCLK (2 << CCM_CS2CDR_ENFC_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CS2CDR_ENFC_CLK_SEL_PLL2_PFD2 (3 << CCM_CS2CDR_ENFC_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +#define CCM_CS2CDR_ENFC_CLK_PRED_SHIFT (18) /* Bits 18-20: Divider for enfc clock pred divider */ +#define CCM_CS2CDR_ENFC_CLK_PRED_MASK (7 << CCM_CS2CDR_ENFC_CLK_PRED_SHIFT) +# define CCM_CS2CDR_ENFC_CLK_PRED(n) ((uint32_t)(n) << CCM_CS2CDR_ENFC_CLK_PRED_SHIFT) /* n=(divisor-1) */ +#define CCM_CS2CDR_ENFC_CLK_PODF_SHIFT (21) /* Bits 21-26: Divider for enfc clock divider */ +#define CCM_CS2CDR_ENFC_CLK_PODF_MASK (0x3f << CCM_CS2CDR_ENFC_CLK_PODF_SHIFT) +# define CCM_CS2CDR_ENFC_CLK_PODF(n) ((uint32_t)(n) << CCM_CS2CDR_ENFC_CLK_PODF_SHIFT) + +/* CCM D1 Clock Divider Register */ + +#define CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT (7) /* Bits 7-8: Selector for spdif1 clock multiplexer */ +#define CCM_CDCDR_SPDIF1_CLK_SEL_MASK (3 << CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT) +# define CCM_CDCDR_SPDIF1_CLK_SEL_DIV_PLL4 (0 << CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT) /* Derive clock from PLL4 divided clock */ +# define CCM_CDCDR_SPDIF1_CLK_SEL_PLL3_PFD2 (1 << CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 */ +# define CCM_CDCDR_SPDIF1_CLK_SEL_PLL3_PFD3 (2 << CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 */ +# define CCM_CDCDR_SPDIF1_CLK_SEL_PLL3_SWCLK (3 << CCM_CDCDR_SPDIF1_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +#define CCM_CDCDR_SPDIF1_CLK_PODF_SHIFT (9) /* Bits 9-11: Divider for spdif1 clock podf */ +#define CCM_CDCDR_SPDIF1_CLK_PODF_MASK (7 << CCM_CDCDR_SPDIF1_CLK_PODF_SHIFT) +# define CCM_CDCDR_SPDIF1_CLK_PODF(n) ((uint32_t)(n) << CCM_CDCDR_SPDIF1_CLK_PODF_SHIFT) /* n=0,7 (divisor-1) */ +#define CCM_CDCDR_SPDIF1_CLK_PRED_SHIFT (12) /* Bits 12-14: Divider for spdif1 clock pred */ +#define CCM_CDCDR_SPDIF1_CLK_PRED_MASK (7 << CCM_CDCDR_SPDIF1_CLK_PRED_SHIFT) +# define CCM_CDCDR_SPDIF1_CLK_PRED(n) ((uint32_t)(n) << CCM_CDCDR_SPDIF1_CLK_PRED_SHIFT) /* n=0,1,2,7 (divisor-1) */ +#define CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT (20) /* Bits 20-21: Selector for spdif0 clock multiplexer */ +#define CCM_CDCDR_SPDIF0_CLK_SEL_MASK (3 << CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT) +# define CCM_CDCDR_SPDIF0_CLK_SEL_DIV_PLL4 (0 << CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT) /* Derive clock from PLL4 divided clock */ +# define CCM_CDCDR_SPDIF0_CLK_SEL_PLL3_PFD2 (1 << CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD2 */ +# define CCM_CDCDR_SPDIF0_CLK_SEL_PLL3_PFD3 (2 << CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD3 */ +# define CCM_CDCDR_SPDIF0_CLK_SEL_PLL3_SWCLK (3 << CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +#define CCM_CDCDR_SPDIF0_CLK_PODF_SHIFT (22) /* Bits 22-24: Divider for spdif0 clock podf */ +#define CCM_CDCDR_SPDIF0_CLK_PODF_MASK (7 << CCM_CDCDR_SPDIF0_CLK_PODF_SHIFT) +# define CCM_CDCDR_SPDIF0_CLK_PODF(n) ((uint32_t)(n) << CCM_CDCDR_SPDIF0_CLK_PODF_SHIFT) /* n=0,7 (divisor-1) */ +#define CCM_CDCDR_SPDIF0_CLK_PRED_SHIFT (25) /* Bits 25-27: Divider for spdif0 clock pred */ +#define CCM_CDCDR_SPDIF0_CLK_PRED_MASK (7 << CCM_CDCDR_SPDIF0_CLK_PRED_SHIFT) +# define CCM_CDCDR_SPDIF0_CLK_PRED(n) ((uint32_t)(n) << CCM_CDCDR_SPDIF0_CLK_PRED_SHIFT) /* n=0,1,2,7 (divisor-1) */ +#define CCM_CDCDR_HSI_TX_CLK_SEL (1 << 28) /* Bit 28: Selector for hsi_tx clock multiplexer */ +#define CCM_CDCDR_HSI_TX_PODF_SHIFT (29) /* Bits 29-31: Divider for hsi_tx clock podf */ +#define CCM_CDCDR_HSI_TX_PODF_MASK (7 << CCM_CDCDR_HSI_TX_PODF_SHIFT) +# define CCM_CDCDR_HSI_TX_PODF(n) ((uint32_t)(n) << CCM_CDCDR_HSI_TX_PODF_SHIFT) /* n=(divisor-1) */ + +/* CCM HSC Clock Divider Register */ + +#define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT (0) /* Bits 0-2: Selector for ipu1 di0 root clock multiplexer */ +#define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK (7 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) +# define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_DIV_IPU1 (0 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) /* Derive clock from divided pre-muxed ipu1 di0 clock */ +# define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI0_CLK (1 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) /* Derive clock from ipp_di0_clk */ +# define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI1_CLK (2 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) /* Derive clock from ipp_di1_clk */ +# define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI0_CLK (3 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) /* Derive clock from ldb_di0_clk */ +# define CCM_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI1_CLK (4 << CCM_CHSCCDR_IPU1_DI0_CLK_SEL_SHIFT) /* Derive clock from ldb_di1_clk */ +#define CCM_CHSCCDR_IPU1_DI0_PODF_SHIFT (3) /* Bits 3-5: Divider for ipu1_di0 clock divider */ +#define CCM_CHSCCDR_IPU1_DI0_PODF_MASK (7 << CCM_CHSCCDR_IPU1_DI0_PODF_SHIFT) +# define CCM_CHSCCDR_IPU1_DI0_PODF(n) ((uint32_t)(n) << CCM_CHSCCDR_IPU1_DI0_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT (6) /* Bits 6-8: Selector for ipu1 di0 root clock pre-multiplexer */ +#define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK (7 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MMDC_CH0 (0 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_SWCLK (1 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL5 (2 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from pll5 */ +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD0 (3 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD2 (4 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_PFD1 (5 << CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ +#define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT (9) /* Bits 9-11: Selector for ipu1 di1 root clock multiplexer */ +#define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK (7 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) +# define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_DIV_IPU1 (0 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) /* Derive clock from divided pre-muxed ipu1 di1 clock */ +# define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI0_CLK (1 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) /* Derive clock from ipp_di0_clk */ +# define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI1_CLK (2 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) /* Derive clock from ipp_di1_clk */ +# define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI0_CLK (3 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) /* Derive clock from ldb_di0_clk */ +# define CCM_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI1_CLK (4 << CCM_CHSCCDR_IPU1_DI1_CLK_SEL_SHIFT) /* Derive clock from ldb_di1_clk */ +#define CCM_CHSCCDR_IPU1_DI1_PODF_SHIFT (12) /* Bits 12-14: Divider for ipu1_di clock divider */ +#define CCM_CHSCCDR_IPU1_DI1_PODF_MASK (7 << CCM_CHSCCDR_IPU1_DI1_PODF_SHIFT) +# define CCM_CHSCCDR_IPU1_DI1_PODF(n) ((uint32_t)(n) << CCM_CHSCCDR_IPU1_DI1_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT (15) /* Bits 15-17: Selector for ipu1 di1 root clock pre-multiplexer */ +#define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK (7 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MMDC_CH0 (0 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_SWCLK (1 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL5 (2 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from pll5 */ +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD0 (3 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD2 (4 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_PFD1 (5 << CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ + +/* CCM Serial Clock Divider Register 2 */ + +#define CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT (0) /* Bits 0-2: Selector for ipu2 di0 root clock multiplexer */ +#define CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK (7 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) +# define CCM_CSCDR2_IPU2_DI0_CLK_SEL_DIV_IPU1 (0 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) /* Derive clock from divided pre-muxed ipu1 di0 clock */ +# define CCM_CSCDR2_IPU2_DI0_CLK_SEL_IPP_DI0_CLK (1 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) /* Derive clock from ipp_di0_clk */ +# define CCM_CSCDR2_IPU2_DI0_CLK_SEL_IPP_DI1_CLK (2 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) /* Derive clock from ipp_di1_clk */ +# define CCM_CSCDR2_IPU2_DI0_CLK_SEL_LDB_DI0_CLK (3 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) /* Derive clock from ldb_di0_clk */ +# define CCM_CSCDR2_IPU2_DI0_CLK_SEL_LDB_DI1_CLK (4 << CCM_CSCDR2_IPU2_DI0_CLK_SEL_SHIFT) /* Derive clock from ldb_di1_clk */ +#define CCM_CSCDR2_IPU2_DI0_PODF_SHIFT (3) /* Bits 3-5: Divider for ipu2_di0 clock divider */ +#define CCM_CSCDR2_IPU2_DI0_PODF_MASK (7 << CCM_CSCDR2_IPU2_DI0_PODF_SHIFT) +# define CCM_CSCDR2_IPU2_DI0_PODF(n) ((uint32_t)(n) << CCM_CSCDR2_IPU2_DI0_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT (6) /* Bits 6-8: Selector for ipu2 di0 root clock pre-multiplexer */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK (7 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MMDC_CH0 (0 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_PLL3_SWCLK (1 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_PLL5 (2 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from pll5 */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_PLL2_PFD (3 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_PLL2_PFD2 (4 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +#define CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_PLL3_PFD1 (5 << CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ +#define CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT (9) /* Bits 9-11: Selector for ipu1 di2 root clock multiplexer */ +#define CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK (7 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) +# define CCM_CSCDR2_IPU2_DI1_CLK_SEL_DIV_IPU1 (0 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) /* Derive clock from divided pre-muxed ipu1 di1 clock */ +# define CCM_CSCDR2_IPU2_DI1_CLK_SEL_IPP_DI0_CLK (1 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) /* Derive clock from ipp_di0_clk */ +# define CCM_CSCDR2_IPU2_DI1_CLK_SEL_IPP_DI1_CLK (2 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) /* Derive clock from ipp_di1_clk */ +# define CCM_CSCDR2_IPU2_DI1_CLK_SEL_LDB_DI0_CLK (3 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) /* Derive clock from ldb_di0_clk */ +# define CCM_CSCDR2_IPU2_DI1_CLK_SEL_LDB_DI1_CLK (4 << CCM_CSCDR2_IPU2_DI1_CLK_SEL_SHIFT) /* Derive clock from ldb_di1_clk */ +#define CCM_CSCDR2_IPU2_DI1_PODF_SHIFT (12) /* Bits 12-14: Divider for ipu2_di1 clock divider */ +#define CCM_CSCDR2_IPU2_DI1_PODF_MASK (7 << CCM_CSCDR2_IPU2_DI1_PODF_SHIFT) +# define CCM_CSCDR2_IPU2_DI1_PODF(n) ((uint32_t)(n) << CCM_CSCDR2_IPU2_DI1_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT (15) /* Bits 15-17: Selector for ipu2 di1 root clock pre-multiplexer */ +#define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK (7 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MMDC_CH0 (0 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_PLL3_SWCLK (1 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from pll3_sw_clk */ +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_PLL5 (2 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL5 */ +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_PLL2_PFD0 (3 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD0 */ +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_PLL2_PFD2 (4 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_PLL3_PFD1 (5 << CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ +#define CCM_CSCDR2_ECSPI_CLK_PODF_SHIFT (19) /* Bits 19-24: Divider for ecspi clock podf */ +#define CCM_CSCDR2_ECSPI_CLK_PODF_MASK (0x3f << CCM_CSCDR2_ECSPI_CLK_PODF_SHIFT) +# define CCM_CSCDR2_ECSPI_CLK_PODF(n) ((uint32_t)(n) << CCM_CSCDR2_ECSPI_CLK_PODF_SHIFT) /* n=(divisor-1) */ + +/* CCM Serial Clock Divider Register 3 */ + +#define CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT (9) /* Bits 9-10: Selector for ipu1_hsp clock multiplexer */ +#define CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK (3 << CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT) +# define CCM_CSCDR3_IPU1_HSP_CLK_SEL_MMDC_CH0 (0 << CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +# define CCM_CSCDR3_IPU1_HSP_CLK_SEL_PLL2_PFD2 (1 << CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CSCDR3_IPU1_HSP_CLK_SEL_PLL3_120M (2 << CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT) /* Derive clock from pll3_120M */ +# define CCM_CSCDR3_IPU1_HSP_CLK_SEL_PLL3_PFD1 (3 << CCM_CSCDR3_IPU1_HSP_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ +#define CCM_CSCDR3_IPU1_HSP_PODF_SHIFT (11) /* Bits 11-13: Divider for ipu1_hsp clock */ +#define CCM_CSCDR3_IPU1_HSP_PODF_MASK (7 << CCM_CSCDR3_IPU1_HSP_PODF_SHIFT) +# define CCM_CSCDR3_IPU1_HSP_PODF(n) ((uint32_t)(n) << CCM_CSCDR3_IPU1_HSP_PODF_SHIFT) /* n=(divisor-1) */ +#define CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT (14) /* Bits 14-15: Selector for ipu2_hsp clock multiplexer */ +#define CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK (3 << CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT) +# define CCM_CSCDR3_IPU2_HSP_CLK_SEL_MMDC_CH0 (0 << CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT) /* Derive clock from mmdc_ch0 clock */ +# define CCM_CSCDR3_IPU2_HSP_CLK_SEL_PLL2_PFD2 (1 << CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT) /* Derive clock from PLL2 PFD2 */ +# define CCM_CSCDR3_IPU2_HSP_CLK_SEL_PLL3_120M (2 << CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT) /* Derive clock from pll3_120M */ +# define CCM_CSCDR3_IPU2_HSP_CLK_SEL_PLL3_PFD1 (3 << CCM_CSCDR3_IPU2_HSP_CLK_SEL_SHIFT) /* Derive clock from PLL3 PFD1 */ +#define CCM_CSCDR3_IPU2_HSP_PODF_SHIFT (16) /* Bits 16-18: Divider for ipu2_hsp clock */ +#define CCM_CSCDR3_IPU2_HSP_PODF_MASK (7 << CCM_CSCDR3_IPU2_HSP_PODF_SHIFT) +# define CCM_CSCDR3_IPU2_HSP_PODF(n) ((uint32_t)(n) << CCM_CSCDR3_IPU2_HSP_PODF_SHIFT) /* n=(divisor-1) */ + +/* CCM Wakeup Detector Register -- Reserved, has no defined fields */ + +/* CCM Divider Handshake In-Process Register */ + +#define CCM_CDHIPR_AXI_PODF_BUSY (1 << 0) /* Bit 0: Busy indicator for axi_podf */ +#define CCM_CDHIPR_AHB_PODF_BUSY (1 << 1) /* Bit 1: Busy indicator for ahb_podf */ +#define CCM_CDHIPR_MMDC_CH1_PODF_BUSY (1 << 2) /* Bit 2: Busy indicator for mmdc_ch1_axi_podf */ +#define CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY (1 << 3) /* Bit 3: Busy indicator for periph2_clk_sel mux control */ +#define CCM_CDHIPR_MMDC_CH0_PODF_BUSY (1 << 4) /* Bit 4: Busy indicator for mmdc_ch0_axi_podf */ +#define CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5) /* Bit 5: Busy indicator for periph_clk_sel mux control */ +#define CCM_CDHIPR_ARM_PODF_BUSY (1 << 16) /* Bit 16: Busy indicator for arm_podf */ + +/* CCM Low Power Control Register */ + +#define CCM_CLPCR_LPM_SHIFT (0) /* Bits 0-1: Low power mode on next dsm_request signal */ +#define CCM_CLPCR_LPM_MASK (3 << CCM_CLPCR_LPM_SHIFT) +# define CCM_CLPCR_LPM_RUNMODE (0 << CCM_CLPCR_LPM_SHIFT) /* Remain in run mode */ +# define CCM_CLPCR_LPM_WAITMODE (1 << CCM_CLPCR_LPM_SHIFT) /* Transfer to wait mode */ +# define CCM_CLPCR_LPM_STOPMODE (2 << CCM_CLPCR_LPM_SHIFT) /* Transfer to stop mode */ +#define CCM_CLPCR_ARM_CLK_DIS_ON_LPM (1 << 5) /* Bit 5: ARM clocks disabled on wait mode */ +#define CCM_CLPCR_SBYOS (1 << 6) /* Bit 6: Standby clock oscillator bit */ +#define CCM_CLPCR_DIS_REF_OSC (1 << 7) /* Bit 7: Control closing of external reference oscillator clock */ +#define CCM_CLPCR_VSTBY (1 << 8) /* Bit 8: Voltage standby request bit */ +#define CCM_CLPCR_STBY_COUNT_SHIFT (9) /* Bits 9-10: Standby counter definition */ +#define CCM_CLPCR_STBY_COUNT_MASK (3 << CCM_CLPCR_STBY_COUNT_SHIFT) +# define CCM_CLPCR_STBY_COUNT_1 (0 << CCM_CLPCR_STBY_COUNT_SHIFT) /* Wait (1*pmic_delay_scaler)+1 ckil clocks */ +# define CCM_CLPCR_STBY_COUNT_3 (1 << CCM_CLPCR_STBY_COUNT_SHIFT) /* Wait (3*pmic_delay_scaler)+1 ckil clocks */ +# define CCM_CLPCR_STBY_COUNT_7 (2 << CCM_CLPCR_STBY_COUNT_SHIFT) /* Wait (7*pmic_delay_scaler)+1 ckil clocks */ +# define CCM_CLPCR_STBY_COUNT_15 (3 << CCM_CLPCR_STBY_COUNT_SHIFT) /* Wait (15*pmic_delay_scaler)+1 ckil clocks */ +#define CCM_CLPCR_COSC_PWRDOWN (1 << 11) /* Bit 11: Control powering down of on chip oscillator */ +#define CCM_CLPCR_WB_PER_AT_LPM (1 << 16) /* Bit 16: Enable periphery charge pump for well biasing at low power mode */ +#define CCM_CLPCR_BYPASS_MMDC_CH0_LPM_HS (1 << 19) /* Bit 19: Bypass handshake with mmdc_ch0 on next entrance to low power mode */ +#define CCM_CLPCR_BYPASS_MMDC_CH1_LPM_HS (1 << 21) /* Bit 21: Bypass handshake with mmdc_ch1 on next entrance to low power mode */ +#define CCM_CLPCR_MASK_CORE0_WFI (1 << 22) /* Bit 22: Mask WFI of core0 for entering low power mode */ +#define CCM_CLPCR_MASK_CORE1_WFI (1 << 23) /* Bit 23: Mask WFI of core1 for entering low power mode */ +#define CCM_CLPCR_MASK_CORE2_WFI (1 << 24) /* Bit 24: Mask WFI of core2 for entering low power mode */ +#define CCM_CLPCR_MASK_CORE3_WFI (1 << 25) /* Bit 25: Mask WFI of core3 for entering low power mode */ +#define CCM_CLPCR_MASK_SCU_IDLE (1 << 26) /* Bit 26: Mask SCU IDLE for entering low power mode */ +#define CCM_CLPCR_MASK_L2CC_IDLE (1 << 27) /* Bit 27: Mask L2CC IDLE for entering low power mode */ + +/* CCM Interrupt Status Register and CCM Interrupt Mask Register */ + +#define CCM_CINT_LRF_PLL (1 << 0) /* Bit 0: Lock of all enabled and not bypaseed PLLs interrupt */ +#define CCM_CINT_COSC_READY (1 << 6) /* Bit 6: On board oscillator ready interrupt */ +#define CCM_CINT_AXI_PODF_LOADED (1 << 17) /* Bit 17: Frequency change of axi_podf interrupt */ +#define CCM_CINT_MASK_MMDC_CH0_AXI_PODF_LOADED (1 << 18) /* Bit 18: Frequency change of mmdc_ch0_axi_podf interrupt */ +#define CCM_CINT_PERIPH2_CLK_SEL_LOADED (1 << 19) /* Bit 19: Frequency change of periph2_clk_sel interrupt */ +#define CCM_CINT_AHB_PODF_LOADED (1 << 20) /* Bit 20: Frequency change of ahb_podf interrupt */ +#define CCM_CINT_MMDC_CH1_PODF_LOADED (1 << 21) /* Bit 21: Frequency change of mmdc_ch0_podf_ loaded interrupt */ +#define CCM_CINT_PERIPH_CLK_SEL_LOADED (1 << 22) /* Bit 22: Update of periph_clk_sel interrupt */ +#define CCM_CINT_MMDC_CH0_PODF_LOADED (1 << 23) /* Bit 23: Update of mmdc_ch0_axi_podf interrupt */ +#define CCM_CINT_ARM_PODF_LOADED (1 << 26) /* Bit 26: Frequency change of arm_podf interrupt */ + +/* CCM Clock Output Source Register */ + +#define CCM_CCOSR_CLKO1_SEL_SHIFT (0) /* Bits 0-3: Selection of the clock to be generated on CCM_CLKO1 */ +#define CCM_CCOSR_CLKO1_SEL_MASK (15 << CCM_CCOSR_CLKO1_SEL_SHIFT) +# define CCM_CCOSR_CLKO1_SEL_PLL3_SW_CLK (0 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* pll3_sw_clk (/2) */ +# define CCM_CCOSR_CLKO1_SEL_PLL2_MAIN_CLK (1 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* pll2_main_clk (/2) */ +# define CCM_CCOSR_CLKO1_SEL_PLL1_MAIN_CLK (2 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* pll1_main_clk (/2) */ +# define CCM_CCOSR_CLKO1_SEL_PLL5_MAIN_CLK (3 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* pll5_main_clk (/2) */ +# define CCM_CCOSR_CLKO1_SEL_VIDEO_27M_CLK_ROOT (4 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* video_27M_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_AXI_CLK_ROOT (5 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* axi_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_ENFC_CLK_ROOT (6 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* enfc_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_IPU1_DI0_CLK_ROOT (7 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ipu1_di0_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_IPU1_DI1_CLK_ROOT (8 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ipu1_di1_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_IPU2_DI0_CLK_ROOT (9 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ipu2_di0_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_IPU2_DI1_CLK_ROOT (10 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ipu2_di1_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_AHB_CLK_ROOT (11 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ahb_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_IPG_CLK_ROOT (12 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ipg_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_PERCLK_ROOT (13 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* perclk_root */ +# define CCM_CCOSR_CLKO1_SEL_CKIL_SYNC_CLK_ROOT (14 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* ckil_sync_clk_root */ +# define CCM_CCOSR_CLKO1_SEL_PLL4_MAIN_CLK (15 << CCM_CCOSR_CLKO1_SEL_SHIFT) /* pll4_main_clk */ +#define CCM_CCOSR_CLKO1_DIV_SHIFT (4) /* Bits 4-6: Setting the divider of CCM_CLKO1 */ +#define CCM_CCOSR_CLKO1_DIV_MASK (7 << CCM_CCOSR_CLKO1_DIV_SHIFT) +# define CCM_CCOSR_CLKO1_DIV(n) ((uint32_t)(n) << CCM_CCOSR_CLKO1_DIV_SHIFT) /* n=(divisor-1) */ +#define CCM_CCOSR_CLKO1_EN (1 << 7) /* Bit 7: Enable of CCM_CLKO1 clock */ +#define CCM_CCOSR_CLK_OUT_SEL (1 << 8) /* Bit 8: CCM_CLKO1 output to reflect CCM_CLKO1 or CCM_CLKO2 clocks */ +#define CCM_CCOSR_CLKO2_SEL_SHIFT (16) /* Bits 16-20: Selection of the clock to be generated on CCM_CLKO2 */ +#define CCM_CCOSR_CLKO2_SEL_MASK (0x1f << CCM_CCOSR_CLKO2_SEL_SHIFT) +# define CCM_CCOSR_CLKO2_SEL_MMDC_CH0_CLK_ROOT (0 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* mmdc_ch0_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_MMDC_CH1_CLK_ROOT (1 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* mmdc_ch1_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_USDHC4_CLK_ROOT (2 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* usdhc4_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_USDHC1_CLK_ROOT (3 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* usdhc1_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_GPU2D_AXI_CLK_ROOT (4 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* gpu2d_axi_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_WRCK_CLK_ROOT (5 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* wrck_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_ECSPI_CLK_ROOT (6 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ecspi_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_GPU3D_AXI_CLK_ROOT (7 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* gpu3d_axi_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_USDHC3_CLK_ROOT (8 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* usdhc3_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_125M_CLK_ROOT (9 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* 125M_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_ARM_CLK_ROOT (10 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* arm_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_IPU1_HSP_CLK_ROOT (11 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ipu1_hsp_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_IPU2_HSP_CLK_ROOT (12 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ipu2_hsp_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_VDO_AXI_CLK_ROOT (13 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* vdo_axi_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_OSC_CLK (14 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* osc_clk */ +# define CCM_CCOSR_CLKO2_SEL_GPU2D_CORE_CLK_ROOT (15 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* gpu2d_core_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_GPU3D_CORE_CLK_ROOT (16 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* gpu3d_core_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_USDHC2_CLK_ROOT (17 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* usdhc2_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_SSI1_CLK_ROOT (18 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ssi1_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_SSI2_CLK_ROOT (19 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ssi2_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_SSI3_CLK_ROOT (20 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ssi3_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_GPU3D_SHADER_CLK_ROOT (21 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* gpu3d_shader_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_VPU_AXI_CLK_ROOT (22 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* vpu_axi_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_CAN_CLK_ROOT (23 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* can_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_LDB_DI0_SERIAL_CLK_ROOT (24 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ldb_di0_serial_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_LDB_DI1_SERIAL_CLK_ROOT (25 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* ldb_di1_serial_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_ESAI_CLK_ROOT (26 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* esai_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_ACLK_EIM_SLOW_CLK_ROOT (27 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* aclk_eim_slow_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_UART_CLK_ROOT (28 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* uart_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_SPDIF0_CLK_ROOT (29 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* spdif0_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_SPDIF1_CLK_ROOT (30 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* spdif1_clk_root */ +# define CCM_CCOSR_CLKO2_SEL_HSI_TX_CLK_ROOT (31 << CCM_CCOSR_CLKO2_SEL_SHIFT) /* hsi_tx_clk_root */ +#define CCM_CCOSR_CLKO2_DIV_SHIFT (21) /* Bits 21-23: Setting the divider of CCM_CLKO2 */ +#define CCM_CCOSR_CLKO2_DIV_MASK (7 << CCM_CCOSR_CLKO2_DIV_SHIFT) +# define CCM_CCOSR_CLKO2_DIV(n) ((uint32_t)(n) << CCM_CCOSR_CLKO2_DIV_SHIFT) /* n=(divisor-1) */ +#define CCM_CCOSR_CLKO2_EN (1 << 24) /* Bit 24: Enable of CCM_CLKO2 clock */ + +/* CCM General Purpose Register */ + +#define CCM_CGPR_PMIC_DELAY_SCALER (1 << 0) /* Bit 0: Defines clock dividion of clock for stby_count */ +#define CCM_CGPR_MMDC_EXT_CLK_DIS (1 << 2) /* Bit 2: Disable external clock driver of MMDC during STOP mode */ +#define CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (1 << 4) /* Bit 4: Defines the value of the output signal cgpr_dout[4] */ +#define CCM_CGPR_FPL (1 << 16) /* Bit 16: Fast PLL enable */ +#define CCM_CGPR_INT_MEM_CLK_LPM (1 << 17) /* Bit 17: Control for the Deep Sleep signal to the ARM Platform memories */ + +/* CCM Clock Gating Register 0-6 common definitions */ + +#define CCM_CCGR_OFF 0 /* Clock is off during all modes */ +#define CCM_CCGR_RUNMODE 1 /* Clock is on in run mode, but off in WAIT and STOP modes */ +#define CCM_CCGR_ALLMODES 3 /* Clock is on during all modes, except STOP mode */ + +/* CCM Clock Gating Register 0 */ + +#define CCM_CCGR0_CG0_SHIFT (0) /* Bits 0-1: aips_tz1 clocks (aips_tz1_clk_enable) */ +#define CCM_CCGR0_CG0_MASK (3 << CCM_CCGR0_CG0_SHIFT) +# define CCM_CCGR0_CG0(n) ((uint32_t)(n) << CCM_CCGR0_CG0_SHIFT) +#define CCM_CCGR0_CG1_SHIFT (2) /* Bits 2-3: aips_tz2 clocks (aips_tz2_clk_enable) */ +#define CCM_CCGR0_CG1_MASK (3 << CCM_CCGR0_CG1_SHIFT) +# define CCM_CCGR0_CG1(n) ((uint32_t)(n) << CCM_CCGR0_CG1_SHIFT) +#define CCM_CCGR0_CG2_SHIFT (4) /* Bits 4-5: apbhdma hclk clock (apbhdma_hclk_enable) */ +#define CCM_CCGR0_CG2_MASK (3 << CCM_CCGR0_CG2_SHIFT) +# define CCM_CCGR0_CG2(n) ((uint32_t)(n) << CCM_CCGR0_CG2_SHIFT) +#define CCM_CCGR0_CG3_SHIFT (6) /* Bits 6-7: asrc clock (asrc_clk_enable) */ +#define CCM_CCGR0_CG3_MASK (3 << CCM_CCGR0_CG3_SHIFT) +# define CCM_CCGR0_CG3(n) ((uint32_t)(n) << CCM_CCGR0_CG3_SHIFT) +#define CCM_CCGR0_CG4_SHIFT (8) /* Bits 8-9: caam_secure_mem clock (caam_secure_mem_clk_enable) */ +#define CCM_CCGR0_CG4_MASK (3 << CCM_CCGR0_CG4_SHIFT) +# define CCM_CCGR0_CG4(n) ((uint32_t)(n) << CCM_CCGR0_CG4_SHIFT) +#define CCM_CCGR0_CG5_SHIFT (10) /* Bits 10-11: caam_wrapper_aclk clock (caam_wrapper_aclk_enable) */ +#define CCM_CCGR0_CG5_MASK (3 << CCM_CCGR0_CG5_SHIFT) +# define CCM_CCGR0_CG5(n) ((uint32_t)(n) << CCM_CCGR0_CG5_SHIFT) +#define CCM_CCGR0_CG6_SHIFT (12) /* Bits 12-13: caam_wrapper_ipg clock (caam_wrapper_ipg_enable) */ +#define CCM_CCGR0_CG6_MASK (3 << CCM_CCGR0_CG6_SHIFT) +# define CCM_CCGR0_CG6(n) ((uint32_t)(n) << CCM_CCGR0_CG6_SHIFT) +#define CCM_CCGR0_CG7_SHIFT (14) /* Bits 14-15: can1 clock (can1_clk_enable) */ +#define CCM_CCGR0_CG7_MASK (3 << CCM_CCGR0_CG7_SHIFT) +# define CCM_CCGR0_CG7(n) ((uint32_t)(n) << CCM_CCGR0_CG7_SHIFT) +#define CCM_CCGR0_CG8_SHIFT (16) /* Bits 16-17: can1_serial clock (can1_serial_clk_enable) */ +#define CCM_CCGR0_CG8_MASK (3 << CCM_CCGR0_CG8_SHIFT) +# define CCM_CCGR0_CG8(n) ((uint32_t)(n) << CCM_CCGR0_CG8_SHIFT) +#define CCM_CCGR0_CG9_SHIFT (18) /* Bits 18-19: can2 clock (can2_clk_enable) */ +#define CCM_CCGR0_CG9_MASK (3 << CCM_CCGR0_CG9_SHIFT) +# define CCM_CCGR0_CG9(n) ((uint32_t)(n) << CCM_CCGR0_CG9_SHIFT) +#define CCM_CCGR0_CG10_SHIFT (20) /* Bits 20-21: can2_serial clock (can2_serial_clk_enable) */ +#define CCM_CCGR0_CG10_MASK (3 << CCM_CCGR0_CG10_SHIFT) +# define CCM_CCGR0_CG10(n) ((uint32_t)(n) << CCM_CCGR0_CG10_SHIFT) +#define CCM_CCGR0_CG11_SHIFT (22) /* Bits 22-23: CPU debug clocks (arm_dbg_clk_enable) */ +#define CCM_CCGR0_CG11_MASK (3 << CCM_CCGR0_CG11_SHIFT) +# define CCM_CCGR0_CG11(n) ((uint32_t)(n) << CCM_CCGR0_CG11_SHIFT) +#define CCM_CCGR0_CG12_SHIFT (24) /* Bits 24-25: dcic1 clocks (dcic1_clk_enable) */ +#define CCM_CCGR0_CG12_MASK (3 << CCM_CCGR0_CG12_SHIFT) +# define CCM_CCGR0_CG12(n) ((uint32_t)(n) << CCM_CCGR0_CG12_SHIFT) +#define CCM_CCGR0_CG13_SHIFT (26) /* Bits 26-27: dcic2 clocks (dcic2_clk_enable) */ +#define CCM_CCGR0_CG13_MASK (3 << CCM_CCGR0_CG13_SHIFT) +# define CCM_CCGR0_CG13(n) ((uint32_t)(n) << CCM_CCGR0_CG13_SHIFT) +#define CCM_CCGR0_CG14_SHIFT (28) /* Bits 28-29: dtcp clocks (dtcp_clk_enable) */ +#define CCM_CCGR0_CG14_MASK (3 << CCM_CCGR0_CG14_SHIFT) +# define CCM_CCGR0_CG14(n) ((uint32_t)(n) << CCM_CCGR0_CG14_SHIFT) +#define CCM_CCGR0_CG15_SHIFT (30) /* Bits 30-31: Reserved */ +#define CCM_CCGR0_CG15_MASK (3 << CCM_CCGR0_CG15_SHIFT) +# define CCM_CCGR0_CG15(n) ((uint32_t)(n) << CCM_CCGR0_CG15_SHIFT) + +/* CCM Clock Gating Register 1 */ + +#define CCM_CCGR1_CG0_SHIFT (0) /* Bits 0-1: ecspi1 clocks (ecspi1_clk_enable) */ +#define CCM_CCGR1_CG0_MASK (3 << CCM_CCGR1_CG0_SHIFT) +# define CCM_CCGR1_CG0(n) ((uint32_t)(n) << CCM_CCGR1_CG0_SHIFT) +#define CCM_CCGR1_CG1_SHIFT (2) /* Bits 2-3: ecspi2 clocks (ecspi2_clk_enable) */ +#define CCM_CCGR1_CG1_MASK (3 << CCM_CCGR1_CG1_SHIFT) +# define CCM_CCGR1_CG1(n) ((uint32_t)(n) << CCM_CCGR1_CG1_SHIFT) +#define CCM_CCGR1_CG2_SHIFT (4) /* Bits 4-5: ecspi3 clocks (ecspi3_clk_enable) */ +#define CCM_CCGR1_CG2_MASK (3 << CCM_CCGR1_CG2_SHIFT) +# define CCM_CCGR1_CG2(n) ((uint32_t)(n) << CCM_CCGR1_CG2_SHIFT) +#define CCM_CCGR1_CG3_SHIFT (6) /* Bits 6-7: ecspi4 clocks (ecspi4_clk_enable) */ +#define CCM_CCGR1_CG3_MASK (3 << CCM_CCGR1_CG3_SHIFT) +# define CCM_CCGR1_CG3(n) ((uint32_t)(n) << CCM_CCGR1_CG3_SHIFT) +#define CCM_CCGR1_CG4_SHIFT (8) /* Bits 8-9: ecspi5 clocks (ecspi5_clk_enable) */ +#define CCM_CCGR1_CG4_MASK (3 << CCM_CCGR1_CG4_SHIFT) +# define CCM_CCGR1_CG4(n) ((uint32_t)(n) << CCM_CCGR1_CG4_SHIFT) +#define CCM_CCGR1_CG5_SHIFT (10) /* Bits 10-11: enet clock (enet_clk_enable) */ +#define CCM_CCGR1_CG5_MASK (3 << CCM_CCGR1_CG5_SHIFT) +# define CCM_CCGR1_CG5(n) ((uint32_t)(n) << CCM_CCGR1_CG5_SHIFT) +#define CCM_CCGR1_CG6_SHIFT (12) /* Bits 12-13: epit1 clocks (epit1_clk_enable) */ +#define CCM_CCGR1_CG6_MASK (3 << CCM_CCGR1_CG6_SHIFT) +# define CCM_CCGR1_CG6(n) ((uint32_t)(n) << CCM_CCGR1_CG6_SHIFT) +#define CCM_CCGR1_CG7_SHIFT (14) /* Bits 14-15: epit2 clocks (epit2_clk_enable) */ +#define CCM_CCGR1_CG7_MASK (3 << CCM_CCGR1_CG7_SHIFT) +# define CCM_CCGR1_CG7(n) ((uint32_t)(n) << CCM_CCGR1_CG7_SHIFT) +#define CCM_CCGR1_CG8_SHIFT (16) /* Bits 16-17: esai clocks (esai_clk_enable) */ +#define CCM_CCGR1_CG8_MASK (3 << CCM_CCGR1_CG8_SHIFT) +# define CCM_CCGR1_CG8(n) ((uint32_t)(n) << CCM_CCGR1_CG8_SHIFT) +#define CCM_CCGR1_CG9_SHIFT (18) /* Bits 18-19: Reserved */ +#define CCM_CCGR1_CG9_MASK (3 << CCM_CCGR1_CG9_SHIFT) +# define CCM_CCGR1_CG9(n) ((uint32_t)(n) << CCM_CCGR1_CG9_SHIFT) +#define CCM_CCGR1_CG10_SHIFT (20) /* Bits 20-21: gpt bus clock (gpt_clk_enable) */ +#define CCM_CCGR1_CG10_MASK (3 << CCM_CCGR1_CG10_SHIFT) +# define CCM_CCGR1_CG10(n) ((uint32_t)(n) << CCM_CCGR1_CG10_SHIFT) +#define CCM_CCGR1_CG11_SHIFT (22) /* Bits 22-23: gpt serial clock (gpt_serial_clk_enable) */ +#define CCM_CCGR1_CG11_MASK (3 << CCM_CCGR1_CG11_SHIFT) +# define CCM_CCGR1_CG11(n) ((uint32_t)(n) << CCM_CCGR1_CG11_SHIFT) +#define CCM_CCGR1_CG12_SHIFT (24) /* Bits 24-25: gpu2d clock (gpu2d_clk_enable) */ +#define CCM_CCGR1_CG12_MASK (3 << CCM_CCGR1_CG12_SHIFT) +# define CCM_CCGR1_CG12(n) ((uint32_t)(n) << CCM_CCGR1_CG12_SHIFT) +#define CCM_CCGR1_CG13_SHIFT (26) /* Bits 26-27: gpu3d clock (gpu3d_clk_enable) */ +#define CCM_CCGR1_CG13_MASK (3 << CCM_CCGR1_CG13_SHIFT) +# define CCM_CCGR1_CG13(n) ((uint32_t)(n) << CCM_CCGR1_CG13_SHIFT) +#define CCM_CCGR1_CG14_SHIFT (28) /* Bits 28-29: Reserved */ +#define CCM_CCGR1_CG14_MASK (3 << CCM_CCGR1_CG14_SHIFT) +# define CCM_CCGR1_CG14(n) ((uint32_t)(n) << CCM_CCGR1_CG14_SHIFT) +#define CCM_CCGR1_CG15_SHIFT (30) /* Bits 30-31: Reserved */ +#define CCM_CCGR1_CG15_MASK (3 << CCM_CCGR1_CG15_SHIFT) +# define CCM_CCGR1_CG15(n) ((uint32_t)(n) << CCM_CCGR1_CG15_SHIFT) + +/* CCM Clock Gating Register 2 */ + +#define CCM_CCGR2_CG0_SHIFT (0) /* Bits 0-1: hdmi_tx_iahbclk, hdmi_tx_ihclk clock (hdmi_tx_enable) */ +#define CCM_CCGR2_CG0_MASK (3 << CCM_CCGR2_CG0_SHIFT) +# define CCM_CCGR2_CG0(n) ((uint32_t)(n) << CCM_CCGR2_CG0_SHIFT) +#define CCM_CCGR2_CG1_SHIFT (2) /* Bits 2-3: Reserved */ +#define CCM_CCGR2_CG1_MASK (3 << CCM_CCGR2_CG1_SHIFT) +# define CCM_CCGR2_CG1(n) ((uint32_t)(n) << CCM_CCGR2_CG1_SHIFT) +#define CCM_CCGR2_CG2_SHIFT (4) /* Bits 4-5: hdmi_tx_isfrclk clock (hdmi_tx_isfrclk_enable) */ +#define CCM_CCGR2_CG2_MASK (3 << CCM_CCGR2_CG2_SHIFT) +# define CCM_CCGR2_CG2(n) ((uint32_t)(n) << CCM_CCGR2_CG2_SHIFT) +#define CCM_CCGR2_CG3_SHIFT (6) /* Bits 6-7: i2c1_serial clock (i2c1_serial_clk_enable) */ +#define CCM_CCGR2_CG3_MASK (3 << CCM_CCGR2_CG3_SHIFT) +# define CCM_CCGR2_CG3(n) ((uint32_t)(n) << CCM_CCGR2_CG3_SHIFT) +#define CCM_CCGR2_CG4_SHIFT (8) /* Bits 8-9: i2c2_serial clock (i2c2_serial_clk_enable) */ +#define CCM_CCGR2_CG4_MASK (3 << CCM_CCGR2_CG4_SHIFT) +# define CCM_CCGR2_CG4(n) ((uint32_t)(n) << CCM_CCGR2_CG4_SHIFT) +#define CCM_CCGR2_CG5_SHIFT (10) /* Bits 10-11: i2c3_serial clock (i2c3_serial_clk_enable) */ +#define CCM_CCGR2_CG5_MASK (3 << CCM_CCGR2_CG5_SHIFT) +# define CCM_CCGR2_CG5(n) ((uint32_t)(n) << CCM_CCGR2_CG5_SHIFT) +#define CCM_CCGR2_CG6_SHIFT (12) /* Bits 12-13: OCOTP_CTRL clock (iim_clk_enable) */ +#define CCM_CCGR2_CG6_MASK (3 << CCM_CCGR2_CG6_SHIFT) +# define CCM_CCGR2_CG6(n) ((uint32_t)(n) << CCM_CCGR2_CG6_SHIFT) +#define CCM_CCGR2_CG7_SHIFT (14) /* Bits 14-15: iomux_ipt_clk_io clock (iomux_ipt_clk_io_enable) */ +#define CCM_CCGR2_CG7_MASK (3 << CCM_CCGR2_CG7_SHIFT) +# define CCM_CCGR2_CG7(n) ((uint32_t)(n) << CCM_CCGR2_CG7_SHIFT) +#define CCM_CCGR2_CG8_SHIFT (16) /* Bits 16-17: ipmux1 clock (ipmux1_clk_enable) */ +#define CCM_CCGR2_CG8_MASK (3 << CCM_CCGR2_CG8_SHIFT) +# define CCM_CCGR2_CG8(n) ((uint32_t)(n) << CCM_CCGR2_CG8_SHIFT) +#define CCM_CCGR2_CG9_SHIFT (18) /* Bits 18-19: ipmux2 clock (ipmux2_clk_enable) */ +#define CCM_CCGR2_CG9_MASK (3 << CCM_CCGR2_CG9_SHIFT) +# define CCM_CCGR2_CG9(n) ((uint32_t)(n) << CCM_CCGR2_CG9_SHIFT) +#define CCM_CCGR2_CG10_SHIFT (20) /* Bits 20-21: ipmux3 clock (ipmux3_clk_enable) */ +#define CCM_CCGR2_CG10_MASK (3 << CCM_CCGR2_CG10_SHIFT) +# define CCM_CCGR2_CG10(n) ((uint32_t)(n) << CCM_CCGR2_CG10_SHIFT) +#define CCM_CCGR2_CG11_SHIFT (22) /* Bits 22-23: ipsync_ip2apb_tzasc1_ipg clocks (ipsync_ip2apb_tzasc1_ipg_master_clk_enable) */ +#define CCM_CCGR2_CG11_MASK (3 << CCM_CCGR2_CG11_SHIFT) +# define CCM_CCGR2_CG11(n) ((uint32_t)(n) << CCM_CCGR2_CG11_SHIFT) +#define CCM_CCGR2_CG12_SHIFT (24) /* Bits 24-25: ipsync_ip2apb_tzasc2_ipg clocks (ipsync_ip2apb_tzasc2_ipg_master_clk_enable) */ +#define CCM_CCGR2_CG12_MASK (3 << CCM_CCGR2_CG12_SHIFT) +# define CCM_CCGR2_CG12(n) ((uint32_t)(n) << CCM_CCGR2_CG12_SHIFT) +#define CCM_CCGR2_CG13_SHIFT (26) /* Bits 26-27: ipsync_vdoa_ipg clocks (ipsync_vdoa_ipg_master_clk_enable)) */ +#define CCM_CCGR2_CG13_MASK (3 << CCM_CCGR2_CG13_SHIFT) +# define CCM_CCGR2_CG13(n) ((uint32_t)(n) << CCM_CCGR2_CG13_SHIFT) +#define CCM_CCGR2_CG14_SHIFT (28) /* Bits 28-29: Reserved */ +#define CCM_CCGR2_CG14_MASK (3 << CCM_CCGR2_CG14_SHIFT) +# define CCM_CCGR2_CG14(n) ((uint32_t)(n) << CCM_CCGR2_CG14_SHIFT) +#define CCM_CCGR2_CG15_SHIFT (30) /* Bits 30-31: Reserved */ +#define CCM_CCGR2_CG15_MASK (3 << CCM_CCGR2_CG15_SHIFT) +# define CCM_CCGR2_CG15(n) ((uint32_t)(n) << CCM_CCGR2_CG15_SHIFT) + +/* CCM Clock Gating Register 3 */ + +#define CCM_CCGR3_CG0_SHIFT (0) /* Bits 0-1: ipu1_ipu clock (ipu1_ipu_clk_enable) */ +#define CCM_CCGR3_CG0_MASK (3 << CCM_CCGR3_CG0_SHIFT) +# define CCM_CCGR3_CG0(n) ((uint32_t)(n) << CCM_CCGR3_CG0_SHIFT) +#define CCM_CCGR3_CG1_SHIFT (2) /* Bits 2-3: ipu1_di0 clock and pre-clock (ipu1_ipu_di0_clk_enable) */ +#define CCM_CCGR3_CG1_MASK (3 << CCM_CCGR3_CG1_SHIFT) +# define CCM_CCGR3_CG1(n) ((uint32_t)(n) << CCM_CCGR3_CG1_SHIFT) +#define CCM_CCGR3_CG2_SHIFT (4) /* Bits 4-5: ipu1_di1 clock and pre-clock (ipu1_ipu_di1_clk_enable) */ +#define CCM_CCGR3_CG2_MASK (3 << CCM_CCGR3_CG2_SHIFT) +# define CCM_CCGR3_CG2(n) ((uint32_t)(n) << CCM_CCGR3_CG2_SHIFT) +#define CCM_CCGR3_CG3_SHIFT (6) /* Bits 6-7: ipu2_ipu clock (ipu2_ipu_clk_enable) */ +#define CCM_CCGR3_CG3_MASK (3 << CCM_CCGR3_CG3_SHIFT) +# define CCM_CCGR3_CG3(n) ((uint32_t)(n) << CCM_CCGR3_CG3_SHIFT) +#define CCM_CCGR3_CG4_SHIFT (8) /* Bits 8-9: ipu2_di0 clock and pre-clock (ipu2_ipu_di0_clk_enable) */ +#define CCM_CCGR3_CG4_MASK (3 << CCM_CCGR3_CG4_SHIFT) +# define CCM_CCGR3_CG4(n) ((uint32_t)(n) << CCM_CCGR3_CG4_SHIFT) +#define CCM_CCGR3_CG5_SHIFT (10) /* Bits 10-11: ipu2_di1 clock and pre-clock (ipu2_ipu_di1_clk_enable) */ +#define CCM_CCGR3_CG5_MASK (3 << CCM_CCGR3_CG5_SHIFT) +# define CCM_CCGR3_CG5(n) ((uint32_t)(n) << CCM_CCGR3_CG5_SHIFT) +#define CCM_CCGR3_CG6_SHIFT (12) /* Bits 12-13: ldb_di0 clock (ldb_di0_clk_enable) */ +#define CCM_CCGR3_CG6_MASK (3 << CCM_CCGR3_CG6_SHIFT) +# define CCM_CCGR3_CG6(n) ((uint32_t)(n) << CCM_CCGR3_CG6_SHIFT) +#define CCM_CCGR3_CG7_SHIFT (14) /* Bits 14-15: ldb_di1 clock (ldb_di1_clk_enable) */ +#define CCM_CCGR3_CG7_MASK (3 << CCM_CCGR3_CG7_SHIFT) +# define CCM_CCGR3_CG7(n) ((uint32_t)(n) << CCM_CCGR3_CG7_SHIFT) +#define CCM_CCGR3_CG8_SHIFT (16) /* Bits 16-17: mipi_core_cfg clock (mipi_core_cfg_clk_enable) */ +#define CCM_CCGR3_CG8_MASK (3 << CCM_CCGR3_CG8_SHIFT) +# define CCM_CCGR3_CG8(n) ((uint32_t)(n) << CCM_CCGR3_CG8_SHIFT) +#define CCM_CCGR3_CG9_SHIFT (18) /* Bits 18-19: mlb clock (mlb_clk_enable) */ +#define CCM_CCGR3_CG9_MASK (3 << CCM_CCGR3_CG9_SHIFT) +# define CCM_CCGR3_CG9(n) ((uint32_t)(n) << CCM_CCGR3_CG9_SHIFT) +#define CCM_CCGR3_CG10_SHIFT (20) /* Bits 20-21: mmdc_core_aclk_fast_core_p0 clock (mmdc_core_aclk_fast_core_p0_enable) */ +#define CCM_CCGR3_CG10_MASK (3 << CCM_CCGR3_CG10_SHIFT) +# define CCM_CCGR3_CG10(n) ((uint32_t)(n) << CCM_CCGR3_CG10_SHIFT) +#define CCM_CCGR3_CG11_SHIFT (22) /* Bits 22-23: Reserved */ +#define CCM_CCGR3_CG11_MASK (3 << CCM_CCGR3_CG11_SHIFT) +# define CCM_CCGR3_CG11(n) ((uint32_t)(n) << CCM_CCGR3_CG11_SHIFT) +#define CCM_CCGR3_CG12_SHIFT (24) /* Bits 24-25: mmdc_core_ipg_clk_p0 clock (mmdc_core_ipg_clk_p0_enable) */ +#define CCM_CCGR3_CG12_MASK (3 << CCM_CCGR3_CG12_SHIFT) +# define CCM_CCGR3_CG12(n) ((uint32_t)(n) << CCM_CCGR3_CG12_SHIFT) +#define CCM_CCGR3_CG13_SHIFT (26) /* Bits 26-27: Reserved */ +#define CCM_CCGR3_CG13_MASK (3 << CCM_CCGR3_CG13_SHIFT) +# define CCM_CCGR3_CG13(n) ((uint32_t)(n) << CCM_CCGR3_CG13_SHIFT) +#define CCM_CCGR3_CG14_SHIFT (28) /* Bits 28-29: ocram clock (ocram_clk_enable) */ +#define CCM_CCGR3_CG14_MASK (3 << CCM_CCGR3_CG14_SHIFT) +# define CCM_CCGR3_CG14(n) ((uint32_t)(n) << CCM_CCGR3_CG14_SHIFT) +#define CCM_CCGR3_CG15_SHIFT (30) /* Bits 30-31: openvgaxiclk clock (openvgaxiclk_clk_root_enable) */ +#define CCM_CCGR3_CG15_MASK (3 << CCM_CCGR3_CG15_SHIFT) +# define CCM_CCGR3_CG15(n) ((uint32_t)(n) << CCM_CCGR3_CG15_SHIFT) + +/* CCM Clock Gating Register 4 */ + +#define CCM_CCGR4_CG0_SHIFT (0) /* Bits 0-1: pcie clock (pcie_root_enable) */ +#define CCM_CCGR4_CG0_MASK (3 << CCM_CCGR4_CG0_SHIFT) +# define CCM_CCGR4_CG0(n) ((uint32_t)(n) << CCM_CCGR4_CG0_SHIFT) +#define CCM_CCGR4_CG1_SHIFT (2) /* Bits 2-3: Reserved */ +#define CCM_CCGR4_CG1_MASK (3 << CCM_CCGR4_CG1_SHIFT) +# define CCM_CCGR4_CG1(n) ((uint32_t)(n) << CCM_CCGR4_CG1_SHIFT) +#define CCM_CCGR4_CG2_SHIFT (4) /* Bits 4-5: Reserved */ +#define CCM_CCGR4_CG2_MASK (3 << CCM_CCGR4_CG2_SHIFT) +# define CCM_CCGR4_CG2(n) ((uint32_t)(n) << CCM_CCGR4_CG2_SHIFT) +#define CCM_CCGR4_CG3_SHIFT (6) /* Bits 6-7: ? */ +#define CCM_CCGR4_CG3_MASK (3 << CCM_CCGR4_CG3_SHIFT) +# define CCM_CCGR4_CG3(n) ((uint32_t)(n) << CCM_CCGR4_CG3_SHIFT) +#define CCM_CCGR4_CG4_SHIFT (8) /* Bits 8-9: pl301_mx6qfast1_s133 clock (pl301_mx6qfast1_s133clk_enable) */ +#define CCM_CCGR4_CG4_MASK (3 << CCM_CCGR4_CG4_SHIFT) +# define CCM_CCGR4_CG4(n) ((uint32_t)(n) << CCM_CCGR4_CG4_SHIFT) +#define CCM_CCGR4_CG5_SHIFT (10) /* Bits 10-11: Reserved */ +#define CCM_CCGR4_CG5_MASK (3 << CCM_CCGR4_CG5_SHIFT) +# define CCM_CCGR4_CG5(n) ((uint32_t)(n) << CCM_CCGR4_CG5_SHIFT) +#define CCM_CCGR4_CG6_SHIFT (12) /* Bits 12-13: pl301_mx6qper1_bch clocks (pl301_mx6qper1_bchclk_enable) */ +#define CCM_CCGR4_CG6_MASK (3 << CCM_CCGR4_CG6_SHIFT) +# define CCM_CCGR4_CG6(n) ((uint32_t)(n) << CCM_CCGR4_CG6_SHIFT) +#define CCM_CCGR4_CG7_SHIFT (14) /* Bits 14-15: pl301_mx6qper2_mainclk_enable (pl301_mx6qper2_mainclk_enable) */ +#define CCM_CCGR4_CG7_MASK (3 << CCM_CCGR4_CG7_SHIFT) +# define CCM_CCGR4_CG7(n) ((uint32_t)(n) << CCM_CCGR4_CG7_SHIFT) +#define CCM_CCGR4_CG8_SHIFT (16) /* Bits 16-17: pwm1 clocks (pwm1_clk_enable) */ +#define CCM_CCGR4_CG8_MASK (3 << CCM_CCGR4_CG8_SHIFT) +# define CCM_CCGR4_CG8(n) ((uint32_t)(n) << CCM_CCGR4_CG8_SHIFT) +#define CCM_CCGR4_CG9_SHIFT (18) /* Bits 18-19: pwm2 clocks (pwm2_clk_enable) */ +#define CCM_CCGR4_CG9_MASK (3 << CCM_CCGR4_CG9_SHIFT) +# define CCM_CCGR4_CG9(n) ((uint32_t)(n) << CCM_CCGR4_CG9_SHIFT) +#define CCM_CCGR4_CG10_SHIFT (20) /* Bits 20-21: pwm3 clocks (pwm3_clk_enable) */ +#define CCM_CCGR4_CG10_MASK (3 << CCM_CCGR4_CG10_SHIFT) +# define CCM_CCGR4_CG10(n) ((uint32_t)(n) << CCM_CCGR4_CG10_SHIFT) +#define CCM_CCGR4_CG11_SHIFT (22) /* Bits 22-23: pwm4 clocks (pwm4_clk_enable) */ +#define CCM_CCGR4_CG11_MASK (3 << CCM_CCGR4_CG11_SHIFT) +# define CCM_CCGR4_CG11(n) ((uint32_t)(n) << CCM_CCGR4_CG11_SHIFT) +#define CCM_CCGR4_CG12_SHIFT (24) /* Bits 24-25: rawnand_u_bch_input_apb clock (rawnand_u_bch_input_apb_clk_enable) */ +#define CCM_CCGR4_CG12_MASK (3 << CCM_CCGR4_CG12_SHIFT) +# define CCM_CCGR4_CG12(n) ((uint32_t)(n) << CCM_CCGR4_CG12_SHIFT) +#define CCM_CCGR4_CG13_SHIFT (26) /* Bits 26-27: rawnand_u_gpmi_bch_input_bch clock (rawnand_u_gpmi_bch_input_bch_clk_enable)) */ +#define CCM_CCGR4_CG13_MASK (3 << CCM_CCGR4_CG13_SHIFT) +# define CCM_CCGR4_CG13(n) ((uint32_t)(n) << CCM_CCGR4_CG13_SHIFT) +#define CCM_CCGR4_CG14_SHIFT (28) /* Bits 28-29: rawnand_u_gpmi_bch_input_gpmi_io clock (rawnand_u_gpmi_bch_input_gpmi_io_clk_enable) */ +#define CCM_CCGR4_CG14_MASK (3 << CCM_CCGR4_CG14_SHIFT) +# define CCM_CCGR4_CG14(n) ((uint32_t)(n) << CCM_CCGR4_CG14_SHIFT) +#define CCM_CCGR4_CG15_SHIFT (30) /* Bits 30-31: rawnand_u_gpmi_input_apb clock (rawnand_u_gpmi_input_apb_clk_enable) */ +#define CCM_CCGR4_CG15_MASK (3 << CCM_CCGR4_CG15_SHIFT) +# define CCM_CCGR4_CG15(n) ((uint32_t)(n) << CCM_CCGR4_CG15_SHIFT) + +/* CCM Clock Gating Register 5 */ + +#define CCM_CCGR5_CG0_SHIFT (0) /* Bits 0-1: rom clock (rom_clk_enable) */ +#define CCM_CCGR5_CG0_MASK (3 << CCM_CCGR5_CG0_SHIFT) +# define CCM_CCGR5_CG0(n) ((uint32_t)(n) << CCM_CCGR5_CG0_SHIFT) +#define CCM_CCGR5_CG1_SHIFT (2) /* Bits 2-3: Reserved */ +#define CCM_CCGR5_CG1_MASK (3 << CCM_CCGR5_CG1_SHIFT) +# define CCM_CCGR5_CG1(n) ((uint32_t)(n) << CCM_CCGR5_CG1_SHIFT) +#define CCM_CCGR5_CG2_SHIFT (4) /* Bits 4-5: sata clock (sata_clk_enable) */ +#define CCM_CCGR5_CG2_MASK (3 << CCM_CCGR5_CG2_SHIFT) +# define CCM_CCGR5_CG2(n) ((uint32_t)(n) << CCM_CCGR5_CG2_SHIFT) +#define CCM_CCGR5_CG3_SHIFT (6) /* Bits 6-7: sdma clock (sdma_clk_enable) */ +#define CCM_CCGR5_CG3_MASK (3 << CCM_CCGR5_CG3_SHIFT) +# define CCM_CCGR5_CG3(n) ((uint32_t)(n) << CCM_CCGR5_CG3_SHIFT) +#define CCM_CCGR5_CG4_SHIFT (8) /* Bits 8-9: Reserved */ +#define CCM_CCGR5_CG4_MASK (3 << CCM_CCGR5_CG4_SHIFT) +# define CCM_CCGR5_CG4(n) ((uint32_t)(n) << CCM_CCGR5_CG4_SHIFT) +#define CCM_CCGR5_CG5_SHIFT (10) /* Bits 10-11: Reserved */ +#define CCM_CCGR5_CG5_MASK (3 << CCM_CCGR5_CG5_SHIFT) +# define CCM_CCGR5_CG5(n) ((uint32_t)(n) << CCM_CCGR5_CG5_SHIFT) +#define CCM_CCGR5_CG6_SHIFT (12) /* Bits 12-13: spba clock (spba_clk_enable) */ +#define CCM_CCGR5_CG6_MASK (3 << CCM_CCGR5_CG6_SHIFT) +# define CCM_CCGR5_CG6(n) ((uint32_t)(n) << CCM_CCGR5_CG6_SHIFT) +#define CCM_CCGR5_CG7_SHIFT (14) /* Bits 14-15: spdif clock (spdif_clk_enable) */ +#define CCM_CCGR5_CG7_MASK (3 << CCM_CCGR5_CG7_SHIFT) +# define CCM_CCGR5_CG7(n) ((uint32_t)(n) << CCM_CCGR5_CG7_SHIFT) +#define CCM_CCGR5_CG8_SHIFT (16) /* Bits 16-17: Reserved */ +#define CCM_CCGR5_CG8_MASK (3 << CCM_CCGR5_CG8_SHIFT) +# define CCM_CCGR5_CG8(n) ((uint32_t)(n) << CCM_CCGR5_CG8_SHIFT) +#define CCM_CCGR5_CG9_SHIFT (18) /* Bits 18-19: ssi1 clocks (ssi1_clk_enable) */ +#define CCM_CCGR5_CG9_MASK (3 << CCM_CCGR5_CG9_SHIFT) +# define CCM_CCGR5_CG9(n) ((uint32_t)(n) << CCM_CCGR5_CG9_SHIFT) +#define CCM_CCGR5_CG10_SHIFT (20) /* Bits 20-21: ssi2 clocks (ssi2_clk_enable) */ +#define CCM_CCGR5_CG10_MASK (3 << CCM_CCGR5_CG10_SHIFT) +# define CCM_CCGR5_CG10(n) ((uint32_t)(n) << CCM_CCGR5_CG10_SHIFT) +#define CCM_CCGR5_CG11_SHIFT (22) /* Bits 22-23: ssi3 clocks (ssi3_clk_enable) */ +#define CCM_CCGR5_CG11_MASK (3 << CCM_CCGR5_CG11_SHIFT) +# define CCM_CCGR5_CG11(n) ((uint32_t)(n) << CCM_CCGR5_CG11_SHIFT) +#define CCM_CCGR5_CG12_SHIFT (24) /* Bits 24-25: uart clock (uart_clk_enable) */ +#define CCM_CCGR5_CG12_MASK (3 << CCM_CCGR5_CG12_SHIFT) +# define CCM_CCGR5_CG12(n) ((uint32_t)(n) << CCM_CCGR5_CG12_SHIFT) +#define CCM_CCGR5_CG13_SHIFT (26) /* Bits 26-27: uart_serial clock (uart_serial_clk_enable)) */ +#define CCM_CCGR5_CG13_MASK (3 << CCM_CCGR5_CG13_SHIFT) +# define CCM_CCGR5_CG13(n) ((uint32_t)(n) << CCM_CCGR5_CG13_SHIFT) +#define CCM_CCGR5_CG14_SHIFT (28) /* Bits 28-29: Reserved */ +#define CCM_CCGR5_CG14_MASK (3 << CCM_CCGR5_CG14_SHIFT) +# define CCM_CCGR5_CG14(n) ((uint32_t)(n) << CCM_CCGR5_CG14_SHIFT) +#define CCM_CCGR5_CG15_SHIFT (30) /* Bits 30-31: Reserved */ +#define CCM_CCGR5_CG15_MASK (3 << CCM_CCGR5_CG15_SHIFT) +# define CCM_CCGR5_CG15(n) ((uint32_t)(n) << CCM_CCGR5_CG15_SHIFT) + +/* CCM Clock Gating Register 6 */ + +#define CCM_CCGR6_CG0_SHIFT (0) /* Bits 0-1: usboh3 clock (usboh3_clk_enable) */ +#define CCM_CCGR6_CG0_MASK (3 << CCM_CCGR6_CG0_SHIFT) +# define CCM_CCGR6_CG0(n) ((uint32_t)(n) << CCM_CCGR6_CG0_SHIFT) +#define CCM_CCGR6_CG1_SHIFT (2) /* Bits 2-3: usdhc1 clocks (usdhc1_clk_enable) */ +#define CCM_CCGR6_CG1_MASK (3 << CCM_CCGR6_CG1_SHIFT) +# define CCM_CCGR6_CG1(n) ((uint32_t)(n) << CCM_CCGR6_CG1_SHIFT) +#define CCM_CCGR6_CG2_SHIFT (4) /* Bits 4-5: usdhc2 clocks (usdhc2_clk_enable) */ +#define CCM_CCGR6_CG2_MASK (3 << CCM_CCGR6_CG2_SHIFT) +# define CCM_CCGR6_CG2(n) ((uint32_t)(n) << CCM_CCGR6_CG2_SHIFT) +#define CCM_CCGR6_CG3_SHIFT (6) /* Bits 6-7: usdhc3 clocks (usdhc3_clk_enable) */ +#define CCM_CCGR6_CG3_MASK (3 << CCM_CCGR6_CG3_SHIFT) +# define CCM_CCGR6_CG3(n) ((uint32_t)(n) << CCM_CCGR6_CG3_SHIFT) +#define CCM_CCGR6_CG4_SHIFT (8) /* Bits 8-9: usdhc4 clocks (usdhc4_clk_enable) */ +#define CCM_CCGR6_CG4_MASK (3 << CCM_CCGR6_CG4_SHIFT) +# define CCM_CCGR6_CG4(n) ((uint32_t)(n) << CCM_CCGR6_CG4_SHIFT) +#define CCM_CCGR6_CG5_SHIFT (10) /* Bits 10-11: eim_slow clocks (eim_slow_clk_enable) */ +#define CCM_CCGR6_CG5_MASK (3 << CCM_CCGR6_CG5_SHIFT) +# define CCM_CCGR6_CG5(n) ((uint32_t)(n) << CCM_CCGR6_CG5_SHIFT) +#define CCM_CCGR6_CG6_SHIFT (12) /* Bits 12-13: vdoaxiclk root clock (vdoaxiclk_clk_enable) */ +#define CCM_CCGR6_CG6_MASK (3 << CCM_CCGR6_CG6_SHIFT) +# define CCM_CCGR6_CG6(n) ((uint32_t)(n) << CCM_CCGR6_CG6_SHIFT) +#define CCM_CCGR6_CG7_SHIFT (14) /* Bits 14-15: vpu clocks (vpu_clk_enable) */ +#define CCM_CCGR6_CG7_MASK (3 << CCM_CCGR6_CG7_SHIFT) +# define CCM_CCGR6_CG7(n) ((uint32_t)(n) << CCM_CCGR6_CG7_SHIFT) +#define CCM_CCGR6_CG8_SHIFT (16) /* Bits 16-17: Reserved */ +#define CCM_CCGR6_CG8_MASK (3 << CCM_CCGR6_CG8_SHIFT) +# define CCM_CCGR6_CG8(n) ((uint32_t)(n) << CCM_CCGR6_CG8_SHIFT) +#define CCM_CCGR6_CG9_SHIFT (18) /* Bits 18-19: Reserved */ +#define CCM_CCGR6_CG9_MASK (3 << CCM_CCGR6_CG9_SHIFT) +# define CCM_CCGR6_CG9(n) ((uint32_t)(n) << CCM_CCGR6_CG9_SHIFT) +#define CCM_CCGR6_CG10_SHIFT (20) /* Bits 20-21: Reserved */ +#define CCM_CCGR6_CG10_MASK (3 << CCM_CCGR6_CG10_SHIFT) +# define CCM_CCGR6_CG10(n) ((uint32_t)(n) << CCM_CCGR6_CG10_SHIFT) +#define CCM_CCGR6_CG11_SHIFT (22) /* Bits 22-23: Reserved */ +#define CCM_CCGR6_CG11_MASK (3 << CCM_CCGR6_CG11_SHIFT) +# define CCM_CCGR6_CG11(n) ((uint32_t)(n) << CCM_CCGR6_CG11_SHIFT) +#define CCM_CCGR6_CG12_SHIFT (24) /* Bits 24-25: Reserved */ +#define CCM_CCGR6_CG12_MASK (3 << CCM_CCGR6_CG12_SHIFT) +# define CCM_CCGR6_CG12(n) ((uint32_t)(n) << CCM_CCGR6_CG12_SHIFT) +#define CCM_CCGR6_CG13_SHIFT (26) /* Bits 26-27: Reserved) */ +#define CCM_CCGR6_CG13_MASK (3 << CCM_CCGR6_CG13_SHIFT) +# define CCM_CCGR6_CG13(n) ((uint32_t)(n) << CCM_CCGR6_CG13_SHIFT) +#define CCM_CCGR6_CG14_SHIFT (28) /* Bits 28-29: Reserved */ +#define CCM_CCGR6_CG14_MASK (3 << CCM_CCGR6_CG14_SHIFT) +# define CCM_CCGR6_CG14(n) ((uint32_t)(n) << CCM_CCGR6_CG14_SHIFT) +#define CCM_CCGR6_CG15_SHIFT (30) /* Bits 30-31: Reserved */ +#define CCM_CCGR6_CG15_MASK (3 << CCM_CCGR6_CG15_SHIFT) +# define CCM_CCGR6_CG15(n) ((uint32_t)(n) << CCM_CCGR6_CG15_SHIFT) + +/* CCM Module Enable Overide Register */ + +#define CCM_CMEOR_MOD_EN_OV_VDOA (1 << 4) /* Bit 4: Overide clock enable signal from vdoa */ +#define CCM_CMEOR_MOD_EN_OV_GPT (1 << 5) /* Bit 5: Overide clock enable signal from GPT */ +#define CCM_CMEOR_MOD_EN_OV_EPIT (1 << 6) /* Bit 6: Overide clock enable signal from EPIT */ +#define CCM_CMEOR_MOD_EN_USDHC (1 << 7) /* Bit 7: Overide clock enable signal from USDHC */ +#define CCM_CMEOR_MOD_EN_OV_DAP (1 << 8) /* Bit 8: Overide clock enable signal from DAP */ +#define CCM_CMEOR_MOD_EN_OV_VPU (1 << 9) /* Bit 9: Overide clock enable signal from VPU */ +#define CCM_CMEOR_MOD_EN_OV_GPU2D (1 << 10) /* Bit 10: Overide clock enable signal from GPU2D */ +#define CCM_CMEOR_MOD_EN_OV_GPU3D (1 << 11) /* Bit 11: Overide clock enable signal from GPU3D */ +#define CCM_CMEOR_MOD_EN_OV_CAN2_CPI (1 << 28) /* Bit 28: Overide clock enable signal from CAN2 */ +#define CCM_CMEOR_MOD_EN_OV_CAN1_CPI (1 << 30) /* Bit 30: Overide clock enable signal from CAN1 */ + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_CCM_H */ diff --git a/arch/arm/src/imx6/chip/imx_gpio.h b/arch/arm/src/imx6/chip/imx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..b63cb1a963e5f6d46a1145eed8ffa58d04140989 --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_gpio.h @@ -0,0 +1,170 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_gpio.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPIO_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define GPIO1 0 /* Port 1 index */ +#define GPIO2 1 /* Port 2 index */ +#define GPIO3 2 /* Port 3 index */ +#define GPIO4 3 /* Port 4 index */ +#define GPIO5 4 /* Port 5 index */ +#define GPIO6 5 /* Port 6 index */ +#define GPIO7 6 /* Port 7 index */ + +#define IMX_GPIO_NPORTS 7 /* Seven total ports */ +#define IMX_GPIO_NPINS 32 /* Up to 32 pins per port */ + +/* GPIO Register Offsets ************************************************************/ + +#define IMX_GPIO_DR_OFFSET 0x0000 /* Data Register */ +#define IMX_GPIO_GDIR_OFFSET 0x0004 /* Data Direction Register */ +#define IMX_GPIO_PSR_OFFSET 0x0008 /* Pad Status Register */ +#define IMX_GPIO_ICR1_OFFSET 0x000c /* Interrupt Configuration Register 1 */ +#define IMX_GPIO_ICR2_OFFSET 0x0010 /* Interrupt Configuration Register 2 */ +#define IMX_GPIO_IMR_OFFSET 0x0014 /* Interrupt Mask Register */ +#define IMX_GPIO_ISR_OFFSET 0x0018 /* Interrupt Status Register */ +#define IMX_GPIO_EDGE_OFFSET 0x001c /* Interrupt Status Register */ + +/* GPIO Register Addresses **********************************************************/ + +#define IMX_GPIO_DR(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO_GDIR(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO_PSR(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO_ICR1(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO_ICR2(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO_IMR(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO_ISR(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO_EDGE(n) (IMX_GPIO_VBASE(n)+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO1_DR (IMX_GPIO1_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO1_GDIR (IMX_GPIO1_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO1_PSR (IMX_GPIO1_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO1_ICR1 (IMX_GPIO1_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO1_ICR2 (IMX_GPIO1_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO1_IMR (IMX_GPIO1_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO1_ISR (IMX_GPIO1_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO1_EDGE (IMX_GPIO1_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO2_DR (IMX_GPIO2_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO2_GDIR (IMX_GPIO2_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO2_PSR (IMX_GPIO2_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO2_ICR1 (IMX_GPIO2_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO2_ICR2 (IMX_GPIO2_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO2_IMR (IMX_GPIO2_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO2_ISR (IMX_GPIO2_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO2_EDGE (IMX_GPIO2_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO3_DR (IMX_GPIO3_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO3_GDIR (IMX_GPIO3_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO3_PSR (IMX_GPIO3_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO3_ICR1 (IMX_GPIO3_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO3_ICR2 (IMX_GPIO3_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO3_IMR (IMX_GPIO3_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO3_ISR (IMX_GPIO3_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO3_EDGE (IMX_GPIO3_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO4_DR (IMX_GPIO4_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO4_GDIR (IMX_GPIO4_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO4_PSR (IMX_GPIO4_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO4_ICR1 (IMX_GPIO4_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO4_ICR2 (IMX_GPIO4_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO4_IMR (IMX_GPIO4_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO4_ISR (IMX_GPIO4_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO4_EDGE (IMX_GPIO4_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO5_DR (IMX_GPIO5_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO5_GDIR (IMX_GPIO5_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO5_PSR (IMX_GPIO5_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO5_ICR1 (IMX_GPIO5_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO5_ICR2 (IMX_GPIO5_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO5_IMR (IMX_GPIO5_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO5_ISR (IMX_GPIO5_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO5_EDGE (IMX_GPIO5_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO6_DR (IMX_GPIO6_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO6_GDIR (IMX_GPIO6_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO6_PSR (IMX_GPIO6_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO6_ICR1 (IMX_GPIO6_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO6_ICR2 (IMX_GPIO6_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO6_IMR (IMX_GPIO6_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO6_ISR (IMX_GPIO6_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO6_EDGE (IMX_GPIO6_VBASE+IMX_GPIO_EDGE_OFFSET) + +#define IMX_GPIO7_DR (IMX_GPIO7_VBASE+IMX_GPIO_DR_OFFSET) +#define IMX_GPIO7_GDIR (IMX_GPIO7_VBASE+IMX_GPIO_GDIR_OFFSET) +#define IMX_GPIO7_PSR (IMX_GPIO7_VBASE+IMX_GPIO_PSR_OFFSET) +#define IMX_GPIO7_ICR1 (IMX_GPIO7_VBASE+IMX_GPIO_ICR1_OFFSET) +#define IMX_GPIO7_ICR2 (IMX_GPIO7_VBASE+IMX_GPIO_ICR2_OFFSET) +#define IMX_GPIO7_IMR (IMX_GPIO7_VBASE+IMX_GPIO_IMR_OFFSET) +#define IMX_GPIO7_ISR (IMX_GPIO7_VBASE+IMX_GPIO_ISR_OFFSET) +#define IMX_GPIO7_EDGE (IMX_GPIO7_VBASE+IMX_GPIO_EDGE_OFFSET) + +/* GPIO Register Bit Definitions ****************************************************/ + +/* Most registers are laid out simply with one bit per pin */ + +#define GPIO_PIN(n) (1 << (n)) /* Bit n: Pin n, n=0-31 */ + +/* GPIO interrupt configuration register 1/2 */ + +#define GPIO_ICR_INDEX(n) (((n) >> 4) & 1) +#define GPIO_ICR_OFFSET(n) (GPIO_ICR1_OFFSET + (GPIO_ICR_INDEX(n) << 2)) + +#define GPIO_ICR_LOWLEVEL 0 /* Interrupt is low-level sensitive */ +#define GPIO_ICR_HIGHLEVEL 1 /* Interrupt is high-level sensitive */ +#define GPIO_ICR_RISINGEDGE 2 /* Interrupt is rising-edge sensitive */ +#define GPIO_ICR_FALLINGEDGE 3 /* Interrupt is falling-edge sensitive */ + +#define GPIO_ICR_SHIFT(n) (((n) & 15) << 1) +#define GPIO_ICR_MASK(n) (3 << GPIO_ICR_SHIFT(n)) +#define GPIO_ICR(i,n) ((uint32_t)(n) << GPIO_ICR_SHIFT(n)) + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPIO_H */ diff --git a/arch/arm/src/imx6/chip/imx_gpt.h b/arch/arm/src/imx6/chip/imx_gpt.h new file mode 100644 index 0000000000000000000000000000000000000000..ad741f19c87e6820e928f8fca323439646d012e1 --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_gpt.h @@ -0,0 +1,157 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_gpt.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPT_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPT Register Offsets ************************************************************/ + +#define IMX_GPT_CR_OFFSET 0x0000 /* GPT Control Register */ +#define IMX_GPT_PR_OFFSET 0x0004 /* GPT Prescaler Register */ +#define IMX_GPT_SR_OFFSET 0x0008 /* GPT Status Register */ +#define IMX_GPT_IR_OFFSET 0x000c /* GPT Interrupt Register */ +#define IMX_GPT_OCR1_OFFSET 0x0010 /* GPT Output Compare Register 1 */ +#define IMX_GPT_OCR2_OFFSET 0x0014 /* GPT Output Compare Register 2 */ +#define IMX_GPT_OCR3_OFFSET 0x0018 /* GPT Output Compare Register 3 */ +#define IMX_GPT_ICR1_OFFSET 0x001c /* GPT Input Capture Register 1 */ +#define IMX_GPT_ICR2_OFFSET 0x0020 /* GPT Input Capture Register 2 */ +#define IMX_GPT_CNT_OFFSET 0x0024 /* GPT Counter Register */ + +/* GPT Register Addresses **********************************************************/ + +#define IMX_GPT_CR (IMX_GPT_VBASE+IMX_GPT_CR_OFFSET) +#define IMX_GPT_PR (IMX_GPT_VBASE+IMX_GPT_PR_OFFSET) +#define IMX_GPT_SR (IMX_GPT_VBASE+IMX_GPT_SR_OFFSET) +#define IMX_GPT_IR (IMX_GPT_VBASE+IMX_GPT_IR_OFFSET) +#define IMX_GPT_OCR1 (IMX_GPT_VBASE+IMX_GPT_OCR1_OFFSET) +#define IMX_GPT_OCR2 (IMX_GPT_VBASE+IMX_GPT_OCR2_OFFSET) +#define IMX_GPT_OCR3 (IMX_GPT_VBASE+IMX_GPT_OCR3_OFFSET) +#define IMX_GPT_ICR1 (IMX_GPT_VBASE+IMX_GPT_ICR1_OFFSET) +#define IMX_GPT_ICR2 (IMX_GPT_VBASE+IMX_GPT_ICR2_OFFSET) +#define IMX_GPT_CNT (IMX_GPT_VBASE+IMX_GPT_CNT_OFFSET) + +/* GPT Register Bit Definitions ****************************************************/ + +/* GPT Control Register */ + +#define GPT_CR_EN (1 << 0) /* Bit 0: GPT Enable */ +#define GPT_CR_ENMOD (1 << 1) /* Bit 1: GPT Enable mode */ +#define GPT_CR_DBGEN (1 << 2) /* Bit 2: GPT debug mode enable */ +#define GPT_CR_WAITEN (1 << 3) /* Bit 3: GPT Wait Mode enable */ +#define GPT_CR_DOZEEN (1 << 4) /* Bit 4: GPT Doze Mode Enable */ +#define GPT_CR_STOPEN (1 << 5) /* Bit 5: GPT Stop Mode enable */ +#define GPT_CR_CLKSRC_SHIFT (6) /* Bits 6-8: Clock source select */ +#define GPT_CR_CLKSRC_MASK (7 << GPT_CR_CLKSRC_SHIFT) +# define GPT_CR_CLKSRC_NONE (0 << GPT_CR_CLKSRC_SHIFT) /* No clock */ +# define GPT_CR_CLKSRC_PERIPHCLK (1 << GPT_CR_CLKSRC_SHIFT) /* Peripheral Clock */ +# define GPT_CR_CLKSRC_HFREF (2 << GPT_CR_CLKSRC_SHIFT) /* High Frequency Reference Clock */ +# define GPT_CR_CLKSRC_CLKIN (3 << GPT_CR_CLKSRC_SHIFT) /* External Clock (CLKIN) */ +# define GPT_CR_CLKSRC_LFREF (4 << GPT_CR_CLKSRC_SHIFT) /* Low Frequency Reference Clock */ +# define GPT_CR_CLKSRC_OSCDIV8 (5 << GPT_CR_CLKSRC_SHIFT) /* Crystal oscillator divided by 8 as Reference Clock */ +# define GPT_CR_CLKSRC_OSC (7 << GPT_CR_CLKSRC_SHIFT) /* Crystal oscillator as Reference Clock */ +#define GPT_CR_FFR (1 << 9) /* Bit 9: Free-Run or Restart mode */ +#define GPT_CR_SWR (1 << 15) /* Bit 15: Software reset */ +#define GPT_CR_IM1_SHIFT (16) /* Bits 16-17: Input Capture Channel 1 operating mode */ +#define GPT_CR_IM1_MASK (3 << GPT_CR_IM1_SHIFT) +# define GPT_CR_IM1_DISABLED (0 << GPT_CR_IM1_SHIFT) /* Capture disabled */ +# define GPT_CR_IM1_RISING (1 << GPT_CR_IM1_SHIFT) /* Capture on rising edge only */ +# define GPT_CR_IM1_FALLING (2 << GPT_CR_IM1_SHIFT) /* Capture on falling edge only */ +# define GPT_CR_IM1_BOTH (3 << GPT_CR_IM1_SHIFT) /* Capture on both edges */ +#define GPT_CR_IM2_SHIFT (18) /* Bits 18-19: Input Capture Channel 2 operating mode */ +#define GPT_CR_IM2_MASK (3 << GPT_CR_IM2_SHIFT) +# define GPT_CR_IM2_DISABLED (0 << GPT_CR_IM2_SHIFT) /* Capture disabled */ +# define GPT_CR_IM2_RISING (1 << GPT_CR_IM2_SHIFT) /* Capture on rising edge only */ +# define GPT_CR_IM2_FALLING (2 << GPT_CR_IM2_SHIFT) /* Capture on falling edge only */ +# define GPT_CR_IM2_BOTH (3 << GPT_CR_IM2_SHIFT) /* Capture on both edges */ +#define GPT_CR_OM1_SHIFT (22) /* Bits 20-22: Output Compare Channel 1 operating mode */ +#define GPT_CR_OM1_MASK (7 << GPT_CR_OM1_SHIFT) +# define GPT_CR_OM1_DISCON (0 << GPT_CR_OM1_SHIFT) /* Output disconnected */ +# define GPT_CR_OM1_TOGGLE (1 << GPT_CR_OM1_SHIFT) /* Toggle output pin */ +# define GPT_CR_OM1_CLEAR (2 << GPT_CR_OM1_SHIFT) /* Clear output pin */ +# define GPT_CR_OM1_SET (3 << GPT_CR_OM1_SHIFT) /* Set output pin */ +# define GPT_CR_OM1_PULSE (4 << GPT_CR_OM1_SHIFT) /* Generate an active low pulse */ +#define GPT_CR_OM2_SHIFT (23) /* Bits 23-25: Output Compare Channel 2 operating mode */ +#define GPT_CR_OM2_MASK (7 << GPT_CR_OM2_SHIFT) +# define GPT_CR_OM2_DISCON (0 << GPT_CR_OM2_SHIFT) /* Output disconnected */ +# define GPT_CR_OM2_TOGGLE (1 << GPT_CR_OM2_SHIFT) /* Toggle output pin */ +# define GPT_CR_OM2_CLEAR (2 << GPT_CR_OM2_SHIFT) /* Clear output pin */ +# define GPT_CR_OM2_SET (3 << GPT_CR_OM2_SHIFT) /* Set output pin */ +# define GPT_CR_OM2_PULSE (4 << GPT_CR_OM2_SHIFT) /* Generate an active low pulse */ +#define GPT_CR_OM3_SHIFT (26) /* Bits 26-28: Output Compare Channel 3 operating mode */ +#define GPT_CR_OM3_MASK (7 << GPT_CR_OM3_SHIFT) +# define GPT_CR_OM3_DISCON (0 << GPT_CR_OM3_SHIFT) /* Output disconnected */ +# define GPT_CR_OM3_TOGGLE (1 << GPT_CR_OM3_SHIFT) /* Toggle output pin */ +# define GPT_CR_OM3_CLEAR (2 << GPT_CR_OM3_SHIFT) /* Clear output pin */ +# define GPT_CR_OM3_SET (3 << GPT_CR_OM3_SHIFT) /* Set output pin */ +# define GPT_CR_OM3_PULSE (4 << GPT_CR_OM3_SHIFT) /* Generate an active low pulse */ +#define GPT_CR_FO1 (1 << 29) /* FO1 Force Output Compare Channel 1 */ +#define GPT_CR_FO2 (1 << 30) /* FO2 Force Output Compare Channel 2 */ +#define GPT_CR_FO3 (1 << 31) /* Force Output Compare Channel 3 */ + +/* GPT Prescaler Register */ + +#define GPT_PR_MASK 0xfff /* Bits 0-11: Prescaler value - 1 */ + +/* GPT Status Register and GPT Interrupt Register */ + +#define GPT_INT_OF1 (1 << 0) /* Bit 0: OF3 Output Compare 1 Flag */ +#define GPT_INT_OF2 (1 << 1) /* Bit 1: OF3 Output Compare 2 Flag */ +#define GPT_INT_OF3 (1 << 2) /* Bit 2: OF3 Output Compare 3 Flag */ +#define GPT_INT_IF1 (1 << 3) /* Bit 3: IF2 Input capture 1 Flag */ +#define GPT_INT_IF2 (1 << 4) /* Bit 4: IF2 Input capture 2 Flag */ +#define GPT_INT_ROV (1 << 5) /* Bit 5: Rollover flag */ + +#define GPT_INT_ALL 0x0000003f + +/* GPT Output Compare Register 1,2,3 -- 32-bit compare registers */ +/* GPT Input Capture Register 1,2 -- 32-bit capture registers */ +/* GPT Counter Register -- 32-bit counter */ + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_GPT_H */ diff --git a/arch/arm/src/imx6/chip/imx_iomuxc.h b/arch/arm/src/imx6/chip/imx_iomuxc.h new file mode 100644 index 0000000000000000000000000000000000000000..f0c14adf8c5308a16a630d382d35bb40d588ae3d --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_iomuxc.h @@ -0,0 +1,2274 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_iomuxc.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_IOMUXC_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_IOMUXC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/* These definitions derive from specifications for the i.MX 6Quad/6Dual and require + * review and modification in order to support other family members. + */ + +#if defined(CONFIG_ARCH_CHIP_IMX6_6QUAD) || defined(CONFIG_ARCH_CHIP_IMX6_6DUAL) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IOMUXC Register Offsets **********************************************************/ +/* General Purpose Registers */ + +#define IMX_IOMUXC_GPR0_OFFSET 0x0000 +#define IMX_IOMUXC_GPR1_OFFSET 0x0004 +#define IMX_IOMUXC_GPR2_OFFSET 0x0008 +#define IMX_IOMUXC_GPR3_OFFSET 0x000c +#define IMX_IOMUXC_GPR4_OFFSET 0x0010 +#define IMX_IOMUXC_GPR5_OFFSET 0x0014 +#define IMX_IOMUXC_GPR6_OFFSET 0x0018 +#define IMX_IOMUXC_GPR7_OFFSET 0x001c +#define IMX_IOMUXC_GPR8_OFFSET 0x0020 +#define IMX_IOMUXC_GPR9_OFFSET 0x0024 +#define IMX_IOMUXC_GPR10_OFFSET 0x0028 +#define IMX_IOMUXC_GPR11_OFFSET 0x002c +#define IMX_IOMUXC_GPR12_OFFSET 0x0030 +#define IMX_IOMUXC_GPR13_OFFSET 0x0034 + +/* Pad Mux Registers */ +/* Pad Mux Register Indices (used by software for table lookups) */ + +#define IMX_PADMUX_SD2_DATA1_INDEX 0 +#define IMX_PADMUX_SD2_DATA2_INDEX 1 +#define IMX_PADMUX_SD2_DATA0_INDEX 2 +#define IMX_PADMUX_RGMII_TXC_INDEX 3 +#define IMX_PADMUX_RGMII_TD0_INDEX 4 +#define IMX_PADMUX_RGMII_TD1_INDEX 5 +#define IMX_PADMUX_RGMII_TD2_INDEX 6 +#define IMX_PADMUX_RGMII_TD3_INDEX 7 +#define IMX_PADMUX_RGMII_RX_CTL_INDEX 8 +#define IMX_PADMUX_RGMII_RD0_INDEX 9 +#define IMX_PADMUX_RGMII_TX_CTL_INDEX 10 +#define IMX_PADMUX_RGMII_RD1_INDEX 11 +#define IMX_PADMUX_RGMII_RD2_INDEX 12 +#define IMX_PADMUX_RGMII_RD3_INDEX 13 +#define IMX_PADMUX_RGMII_RXC_INDEX 14 +#define IMX_PADMUX_EIM_ADDR25_INDEX 15 +#define IMX_PADMUX_EIM_EB2_INDEX 16 +#define IMX_PADMUX_EIM_DATA16_INDEX 17 +#define IMX_PADMUX_EIM_DATA17_INDEX 18 +#define IMX_PADMUX_EIM_DATA18_INDEX 19 +#define IMX_PADMUX_EIM_DATA19_INDEX 20 +#define IMX_PADMUX_EIM_DATA20_INDEX 21 +#define IMX_PADMUX_EIM_DATA21_INDEX 22 +#define IMX_PADMUX_EIM_DATA22_INDEX 23 +#define IMX_PADMUX_EIM_DATA23_INDEX 24 +#define IMX_PADMUX_EIM_EB3_INDEX 25 +#define IMX_PADMUX_EIM_DATA24_INDEX 26 +#define IMX_PADMUX_EIM_DATA25_INDEX 27 +#define IMX_PADMUX_EIM_DATA26_INDEX 28 +#define IMX_PADMUX_EIM_DATA27_INDEX 29 +#define IMX_PADMUX_EIM_DATA28_INDEX 30 +#define IMX_PADMUX_EIM_DATA29_INDEX 31 +#define IMX_PADMUX_EIM_DATA30_INDEX 32 +#define IMX_PADMUX_EIM_DATA31_INDEX 33 +#define IMX_PADMUX_EIM_ADDR24_INDEX 34 +#define IMX_PADMUX_EIM_ADDR23_INDEX 35 +#define IMX_PADMUX_EIM_ADDR22_INDEX 36 +#define IMX_PADMUX_EIM_ADDR21_INDEX 37 +#define IMX_PADMUX_EIM_ADDR20_INDEX 38 +#define IMX_PADMUX_EIM_ADDR19_INDEX 49 +#define IMX_PADMUX_EIM_ADDR18_INDEX 40 +#define IMX_PADMUX_EIM_ADDR17_INDEX 41 +#define IMX_PADMUX_EIM_ADDR16_INDEX 42 +#define IMX_PADMUX_EIM_CS0_INDEX 43 +#define IMX_PADMUX_EIM_CS1_INDEX 44 +#define IMX_PADMUX_EIM_OE_INDEX 45 +#define IMX_PADMUX_EIM_RW_INDEX 46 +#define IMX_PADMUX_EIM_LBA_INDEX 47 +#define IMX_PADMUX_EIM_EB0_INDEX 58 +#define IMX_PADMUX_EIM_EB1_INDEX 59 +#define IMX_PADMUX_EIM_AD00_INDEX 50 +#define IMX_PADMUX_EIM_AD01_INDEX 51 +#define IMX_PADMUX_EIM_AD02_INDEX 52 +#define IMX_PADMUX_EIM_AD03_INDEX 53 +#define IMX_PADMUX_EIM_AD04_INDEX 54 +#define IMX_PADMUX_EIM_AD05_INDEX 55 +#define IMX_PADMUX_EIM_AD06_INDEX 56 +#define IMX_PADMUX_EIM_AD07_INDEX 67 +#define IMX_PADMUX_EIM_AD08_INDEX 68 +#define IMX_PADMUX_EIM_AD09_INDEX 69 +#define IMX_PADMUX_EIM_AD10_INDEX 60 +#define IMX_PADMUX_EIM_AD11_INDEX 61 +#define IMX_PADMUX_EIM_AD12_INDEX 62 +#define IMX_PADMUX_EIM_AD13_INDEX 63 +#define IMX_PADMUX_EIM_AD14_INDEX 64 +#define IMX_PADMUX_EIM_AD15_INDEX 65 +#define IMX_PADMUX_EIM_WAIT_INDEX 66 +#define IMX_PADMUX_EIM_BCLK_INDEX 67 +#define IMX_PADMUX_DI0_DISP_CLK_INDEX 68 +#define IMX_PADMUX_DI0_PIN15_INDEX 69 +#define IMX_PADMUX_DI0_PIN02_INDEX 70 +#define IMX_PADMUX_DI0_PIN03_INDEX 71 +#define IMX_PADMUX_DI0_PIN04_INDEX 72 +#define IMX_PADMUX_DISP0_DATA00_INDEX 73 +#define IMX_PADMUX_DISP0_DATA01_INDEX 74 +#define IMX_PADMUX_DISP0_DATA02_INDEX 75 +#define IMX_PADMUX_DISP0_DATA03_INDEX 76 +#define IMX_PADMUX_DISP0_DATA04_INDEX 77 +#define IMX_PADMUX_DISP0_DATA05_INDEX 78 +#define IMX_PADMUX_DISP0_DATA06_INDEX 79 +#define IMX_PADMUX_DISP0_DATA07_INDEX 80 +#define IMX_PADMUX_DISP0_DATA08_INDEX 81 +#define IMX_PADMUX_DISP0_DATA09_INDEX 82 +#define IMX_PADMUX_DISP0_DATA10_INDEX 83 +#define IMX_PADMUX_DISP0_DATA11_INDEX 84 +#define IMX_PADMUX_DISP0_DATA12_INDEX 85 +#define IMX_PADMUX_DISP0_DATA13_INDEX 86 +#define IMX_PADMUX_DISP0_DATA14_INDEX 87 +#define IMX_PADMUX_DISP0_DATA15_INDEX 88 +#define IMX_PADMUX_DISP0_DATA16_INDEX 89 +#define IMX_PADMUX_DISP0_DATA17_INDEX 90 +#define IMX_PADMUX_DISP0_DATA18_INDEX 91 +#define IMX_PADMUX_DISP0_DATA19_INDEX 92 +#define IMX_PADMUX_DISP0_DATA20_INDEX 93 +#define IMX_PADMUX_DISP0_DATA21_INDEX 94 +#define IMX_PADMUX_DISP0_DATA22_INDEX 95 +#define IMX_PADMUX_DISP0_DATA23_INDEX 96 +#define IMX_PADMUX_ENET_MDIO_INDEX 97 +#define IMX_PADMUX_ENET_REF_CLK_INDEX 98 +#define IMX_PADMUX_ENET_RX_ER_INDEX 99 +#define IMX_PADMUX_ENET_CRS_DV_INDEX 100 +#define IMX_PADMUX_ENET_RX_DATA1_INDEX 101 +#define IMX_PADMUX_ENET_RX_DATA0_INDEX 102 +#define IMX_PADMUX_ENET_TX_EN_INDEX 103 +#define IMX_PADMUX_ENET_TX_DATA1_INDEX 104 +#define IMX_PADMUX_ENET_TX_DATA0_INDEX 105 +#define IMX_PADMUX_ENET_MDC_INDEX 106 +#define IMX_PADMUX_KEY_COL0_INDEX 107 +#define IMX_PADMUX_KEY_ROW0_INDEX 108 +#define IMX_PADMUX_KEY_COL1_INDEX 109 +#define IMX_PADMUX_KEY_ROW1_INDEX 110 +#define IMX_PADMUX_KEY_COL2_INDEX 111 +#define IMX_PADMUX_KEY_ROW2_INDEX 112 +#define IMX_PADMUX_KEY_COL3_INDEX 113 +#define IMX_PADMUX_KEY_ROW3_INDEX 114 +#define IMX_PADMUX_KEY_COL4_INDEX 115 +#define IMX_PADMUX_KEY_ROW4_INDEX 116 +#define IMX_PADMUX_GPIO00_INDEX 117 +#define IMX_PADMUX_GPIO01_INDEX 118 +#define IMX_PADMUX_GPIO09_INDEX 119 +#define IMX_PADMUX_GPIO03_INDEX 120 +#define IMX_PADMUX_GPIO06_INDEX 121 +#define IMX_PADMUX_GPIO02_INDEX 122 +#define IMX_PADMUX_GPIO04_INDEX 123 +#define IMX_PADMUX_GPIO05_INDEX 124 +#define IMX_PADMUX_GPIO07_INDEX 125 +#define IMX_PADMUX_GPIO08_INDEX 126 +#define IMX_PADMUX_GPIO16_INDEX 127 +#define IMX_PADMUX_GPIO17_INDEX 128 +#define IMX_PADMUX_GPIO18_INDEX 129 +#define IMX_PADMUX_GPIO19_INDEX 130 +#define IMX_PADMUX_CSI0_PIXCLK_INDEX 131 +#define IMX_PADMUX_CSI0_HSYNC_INDEX 132 +#define IMX_PADMUX_CSI0_DATA_EN_INDEX 133 +#define IMX_PADMUX_CSI0_VSYNC_INDEX 134 +#define IMX_PADMUX_CSI0_DATA04_INDEX 135 +#define IMX_PADMUX_CSI0_DATA05_INDEX 136 +#define IMX_PADMUX_CSI0_DATA06_INDEX 137 +#define IMX_PADMUX_CSI0_DATA07_INDEX 138 +#define IMX_PADMUX_CSI0_DATA08_INDEX 139 +#define IMX_PADMUX_CSI0_DATA09_INDEX 140 +#define IMX_PADMUX_CSI0_DATA10_INDEX 141 +#define IMX_PADMUX_CSI0_DATA11_INDEX 142 +#define IMX_PADMUX_CSI0_DATA12_INDEX 143 +#define IMX_PADMUX_CSI0_DATA13_INDEX 144 +#define IMX_PADMUX_CSI0_DATA14_INDEX 145 +#define IMX_PADMUX_CSI0_DATA15_INDEX 146 +#define IMX_PADMUX_CSI0_DATA16_INDEX 147 +#define IMX_PADMUX_CSI0_DATA17_INDEX 148 +#define IMX_PADMUX_CSI0_DATA18_INDEX 149 +#define IMX_PADMUX_CSI0_DATA19_INDEX 150 +#define IMX_PADMUX_SD3_DATA7_INDEX 151 +#define IMX_PADMUX_SD3_DATA6_INDEX 152 +#define IMX_PADMUX_SD3_DATA5_INDEX 153 +#define IMX_PADMUX_SD3_DATA4_INDEX 154 +#define IMX_PADMUX_SD3_CMD_INDEX 155 +#define IMX_PADMUX_SD3_CLK_INDEX 156 +#define IMX_PADMUX_SD3_DATA0_INDEX 157 +#define IMX_PADMUX_SD3_DATA1_INDEX 158 +#define IMX_PADMUX_SD3_DATA2_INDEX 159 +#define IMX_PADMUX_SD3_DATA3_INDEX 160 +#define IMX_PADMUX_SD3_RESET_INDEX 161 +#define IMX_PADMUX_NAND_CLE_INDEX 162 +#define IMX_PADMUX_NAND_ALE_INDEX 163 +#define IMX_PADMUX_NAND_WP_INDEX 164 +#define IMX_PADMUX_NAND_READY_INDEX 165 +#define IMX_PADMUX_NAND_CS0_INDEX 166 +#define IMX_PADMUX_NAND_CS1_INDEX 167 +#define IMX_PADMUX_NAND_CS2_INDEX 168 +#define IMX_PADMUX_NAND_CS3_INDEX 169 +#define IMX_PADMUX_SD4_CMD_INDEX 170 +#define IMX_PADMUX_SD4_CLK_INDEX 171 +#define IMX_PADMUX_NAND_DATA00_INDEX 172 +#define IMX_PADMUX_NAND_DATA01_INDEX 173 +#define IMX_PADMUX_NAND_DATA02_INDEX 174 +#define IMX_PADMUX_NAND_DATA03_INDEX 175 +#define IMX_PADMUX_NAND_DATA04_INDEX 176 +#define IMX_PADMUX_NAND_DATA05_INDEX 177 +#define IMX_PADMUX_NAND_DATA06_INDEX 178 +#define IMX_PADMUX_NAND_DATA07_INDEX 189 +#define IMX_PADMUX_SD4_DATA0_INDEX 180 +#define IMX_PADMUX_SD4_DATA1_INDEX 181 +#define IMX_PADMUX_SD4_DATA2_INDEX 182 +#define IMX_PADMUX_SD4_DATA3_INDEX 183 +#define IMX_PADMUX_SD4_DATA4_INDEX 184 +#define IMX_PADMUX_SD4_DATA5_INDEX 185 +#define IMX_PADMUX_SD4_DATA6_INDEX 186 +#define IMX_PADMUX_SD4_DATA7_INDEX 187 +#define IMX_PADMUX_SD1_DATA1_INDEX 188 +#define IMX_PADMUX_SD1_DATA0_INDEX 189 +#define IMX_PADMUX_SD1_DATA3_INDEX 190 +#define IMX_PADMUX_SD1_CMD_INDEX 191 +#define IMX_PADMUX_SD1_DATA2_INDEX 192 +#define IMX_PADMUX_SD1_CLK_INDEX 193 +#define IMX_PADMUX_SD2_CLK_INDEX 194 +#define IMX_PADMUX_SD2_CMD_INDEX 195 +#define IMX_PADMUX_SD2_DATA3_INDEX 196 + +#define IMX_PADMUX_NREGISTERS 197 + +/* Pad Mux Register Offsets */ + +#define IMX_PADMUX_OFFSET(n) (0x004c + ((unsigned int)(n) << 2)) + +#define IMX_PADMUX_SD2_DATA1_OFFSET 0x004c +#define IMX_PADMUX_SD2_DATA2_OFFSET 0x0050 +#define IMX_PADMUX_SD2_DATA0_OFFSET 0x0054 +#define IMX_PADMUX_RGMII_TXC_OFFSET 0x0058 +#define IMX_PADMUX_RGMII_TD0_OFFSET 0x005c +#define IMX_PADMUX_RGMII_TD1_OFFSET 0x0060 +#define IMX_PADMUX_RGMII_TD2_OFFSET 0x0064 +#define IMX_PADMUX_RGMII_TD3_OFFSET 0x0068 +#define IMX_PADMUX_RGMII_RX_CTL_OFFSET 0x006c +#define IMX_PADMUX_RGMII_RD0_OFFSET 0x0070 +#define IMX_PADMUX_RGMII_TX_CTL_OFFSET 0x0074 +#define IMX_PADMUX_RGMII_RD1_OFFSET 0x0078 +#define IMX_PADMUX_RGMII_RD2_OFFSET 0x007c +#define IMX_PADMUX_RGMII_RD3_OFFSET 0x0080 +#define IMX_PADMUX_RGMII_RXC_OFFSET 0x0084 +#define IMX_PADMUX_EIM_ADDR25_OFFSET 0x0088 +#define IMX_PADMUX_EIM_EB2_OFFSET 0x008c +#define IMX_PADMUX_EIM_DATA16_OFFSET 0x0090 +#define IMX_PADMUX_EIM_DATA17_OFFSET 0x0094 +#define IMX_PADMUX_EIM_DATA18_OFFSET 0x0098 +#define IMX_PADMUX_EIM_DATA19_OFFSET 0x009c +#define IMX_PADMUX_EIM_DATA20_OFFSET 0x00a0 +#define IMX_PADMUX_EIM_DATA21_OFFSET 0x00a4 +#define IMX_PADMUX_EIM_DATA22_OFFSET 0x00a8 +#define IMX_PADMUX_EIM_DATA23_OFFSET 0x00ac +#define IMX_PADMUX_EIM_EB3_OFFSET 0x00b0 +#define IMX_PADMUX_EIM_DATA24_OFFSET 0x00b4 +#define IMX_PADMUX_EIM_DATA25_OFFSET 0x00b8 +#define IMX_PADMUX_EIM_DATA26_OFFSET 0x00bc +#define IMX_PADMUX_EIM_DATA27_OFFSET 0x00c0 +#define IMX_PADMUX_EIM_DATA28_OFFSET 0x00c4 +#define IMX_PADMUX_EIM_DATA29_OFFSET 0x00c8 +#define IMX_PADMUX_EIM_DATA30_OFFSET 0x00cc +#define IMX_PADMUX_EIM_DATA31_OFFSET 0x00d0 +#define IMX_PADMUX_EIM_ADDR24_OFFSET 0x00d4 +#define IMX_PADMUX_EIM_ADDR23_OFFSET 0x00d8 +#define IMX_PADMUX_EIM_ADDR22_OFFSET 0x00dc +#define IMX_PADMUX_EIM_ADDR21_OFFSET 0x00e0 +#define IMX_PADMUX_EIM_ADDR20_OFFSET 0x00e4 +#define IMX_PADMUX_EIM_ADDR19_OFFSET 0x00e8 +#define IMX_PADMUX_EIM_ADDR18_OFFSET 0x00ec +#define IMX_PADMUX_EIM_ADDR17_OFFSET 0x00f0 +#define IMX_PADMUX_EIM_ADDR16_OFFSET 0x00f4 +#define IMX_PADMUX_EIM_CS0_OFFSET 0x00f8 +#define IMX_PADMUX_EIM_CS1_OFFSET 0x00fc +#define IMX_PADMUX_EIM_OE_OFFSET 0x0100 +#define IMX_PADMUX_EIM_RW_OFFSET 0x0104 +#define IMX_PADMUX_EIM_LBA_OFFSET 0x0108 +#define IMX_PADMUX_EIM_EB0_OFFSET 0x010c +#define IMX_PADMUX_EIM_EB1_OFFSET 0x0110 +#define IMX_PADMUX_EIM_AD00_OFFSET 0x0114 +#define IMX_PADMUX_EIM_AD01_OFFSET 0x0118 +#define IMX_PADMUX_EIM_AD02_OFFSET 0x011c +#define IMX_PADMUX_EIM_AD03_OFFSET 0x0120 +#define IMX_PADMUX_EIM_AD04_OFFSET 0x0124 +#define IMX_PADMUX_EIM_AD05_OFFSET 0x0128 +#define IMX_PADMUX_EIM_AD06_OFFSET 0x012c +#define IMX_PADMUX_EIM_AD07_OFFSET 0x0130 +#define IMX_PADMUX_EIM_AD08_OFFSET 0x0134 +#define IMX_PADMUX_EIM_AD09_OFFSET 0x0138 +#define IMX_PADMUX_EIM_AD10_OFFSET 0x013c +#define IMX_PADMUX_EIM_AD11_OFFSET 0x0140 +#define IMX_PADMUX_EIM_AD12_OFFSET 0x0144 +#define IMX_PADMUX_EIM_AD13_OFFSET 0x0148 +#define IMX_PADMUX_EIM_AD14_OFFSET 0x014c +#define IMX_PADMUX_EIM_AD15_OFFSET 0x0150 +#define IMX_PADMUX_EIM_WAIT_OFFSET 0x0154 +#define IMX_PADMUX_EIM_BCLK_OFFSET 0x0158 +#define IMX_PADMUX_DI0_DISP_CLK_OFFSET 0x015c +#define IMX_PADMUX_DI0_PIN15_OFFSET 0x0160 +#define IMX_PADMUX_DI0_PIN02_OFFSET 0x0164 +#define IMX_PADMUX_DI0_PIN03_OFFSET 0x0168 +#define IMX_PADMUX_DI0_PIN04_OFFSET 0x016c +#define IMX_PADMUX_DISP0_DATA00_OFFSET 0x0170 +#define IMX_PADMUX_DISP0_DATA01_OFFSET 0x0174 +#define IMX_PADMUX_DISP0_DATA02_OFFSET 0x0178 +#define IMX_PADMUX_DISP0_DATA03_OFFSET 0x017c +#define IMX_PADMUX_DISP0_DATA04_OFFSET 0x0180 +#define IMX_PADMUX_DISP0_DATA05_OFFSET 0x0184 +#define IMX_PADMUX_DISP0_DATA06_OFFSET 0x0188 +#define IMX_PADMUX_DISP0_DATA07_OFFSET 0x018c +#define IMX_PADMUX_DISP0_DATA08_OFFSET 0x0190 +#define IMX_PADMUX_DISP0_DATA09_OFFSET 0x0194 +#define IMX_PADMUX_DISP0_DATA10_OFFSET 0x0198 +#define IMX_PADMUX_DISP0_DATA11_OFFSET 0x019c +#define IMX_PADMUX_DISP0_DATA12_OFFSET 0x01a0 +#define IMX_PADMUX_DISP0_DATA13_OFFSET 0x01a4 +#define IMX_PADMUX_DISP0_DATA14_OFFSET 0x01a8 +#define IMX_PADMUX_DISP0_DATA15_OFFSET 0x01ac +#define IMX_PADMUX_DISP0_DATA16_OFFSET 0x01b0 +#define IMX_PADMUX_DISP0_DATA17_OFFSET 0x01b4 +#define IMX_PADMUX_DISP0_DATA18_OFFSET 0x01b8 +#define IMX_PADMUX_DISP0_DATA19_OFFSET 0x01bc +#define IMX_PADMUX_DISP0_DATA20_OFFSET 0x01c0 +#define IMX_PADMUX_DISP0_DATA21_OFFSET 0x01c4 +#define IMX_PADMUX_DISP0_DATA22_OFFSET 0x01c8 +#define IMX_PADMUX_DISP0_DATA23_OFFSET 0x01cc +#define IMX_PADMUX_ENET_MDIO_OFFSET 0x01d0 +#define IMX_PADMUX_ENET_REF_CLK_OFFSET 0x01d4 +#define IMX_PADMUX_ENET_RX_ER_OFFSET 0x01d8 +#define IMX_PADMUX_ENET_CRS_DV_OFFSET 0x01dc +#define IMX_PADMUX_ENET_RX_DATA1_OFFSET 0x01e0 +#define IMX_PADMUX_ENET_RX_DATA0_OFFSET 0x01e4 +#define IMX_PADMUX_ENET_TX_EN_OFFSET 0x01e8 +#define IMX_PADMUX_ENET_TX_DATA1_OFFSET 0x01ec +#define IMX_PADMUX_ENET_TX_DATA0_OFFSET 0x01f0 +#define IMX_PADMUX_ENET_MDC_OFFSET 0x01f4 +#define IMX_PADMUX_KEY_COL0_OFFSET 0x01f8 +#define IMX_PADMUX_KEY_ROW0_OFFSET 0x01fc +#define IMX_PADMUX_KEY_COL1_OFFSET 0x0200 +#define IMX_PADMUX_KEY_ROW1_OFFSET 0x0204 +#define IMX_PADMUX_KEY_COL2_OFFSET 0x0208 +#define IMX_PADMUX_KEY_ROW2_OFFSET 0x020c +#define IMX_PADMUX_KEY_COL3_OFFSET 0x0210 +#define IMX_PADMUX_KEY_ROW3_OFFSET 0x0214 +#define IMX_PADMUX_KEY_COL4_OFFSET 0x0218 +#define IMX_PADMUX_KEY_ROW4_OFFSET 0x021c +#define IMX_PADMUX_GPIO00_OFFSET 0x0220 +#define IMX_PADMUX_GPIO01_OFFSET 0x0224 +#define IMX_PADMUX_GPIO09_OFFSET 0x0228 +#define IMX_PADMUX_GPIO03_OFFSET 0x022c +#define IMX_PADMUX_GPIO06_OFFSET 0x0230 +#define IMX_PADMUX_GPIO02_OFFSET 0x0234 +#define IMX_PADMUX_GPIO04_OFFSET 0x0238 +#define IMX_PADMUX_GPIO05_OFFSET 0x023c +#define IMX_PADMUX_GPIO07_OFFSET 0x0240 +#define IMX_PADMUX_GPIO08_OFFSET 0x0244 +#define IMX_PADMUX_GPIO16_OFFSET 0x0248 +#define IMX_PADMUX_GPIO17_OFFSET 0x024c +#define IMX_PADMUX_GPIO18_OFFSET 0x0250 +#define IMX_PADMUX_GPIO19_OFFSET 0x0254 +#define IMX_PADMUX_CSI0_PIXCLK_OFFSET 0x0258 +#define IMX_PADMUX_CSI0_HSYNC_OFFSET 0x025c +#define IMX_PADMUX_CSI0_DATA_EN_OFFSET 0x0260 +#define IMX_PADMUX_CSI0_VSYNC_OFFSET 0x0264 +#define IMX_PADMUX_CSI0_DATA04_OFFSET 0x0268 +#define IMX_PADMUX_CSI0_DATA05_OFFSET 0x026c +#define IMX_PADMUX_CSI0_DATA06_OFFSET 0x0270 +#define IMX_PADMUX_CSI0_DATA07_OFFSET 0x0274 +#define IMX_PADMUX_CSI0_DATA08_OFFSET 0x0278 +#define IMX_PADMUX_CSI0_DATA09_OFFSET 0x027c +#define IMX_PADMUX_CSI0_DATA10_OFFSET 0x0280 +#define IMX_PADMUX_CSI0_DATA11_OFFSET 0x0284 +#define IMX_PADMUX_CSI0_DATA12_OFFSET 0x0288 +#define IMX_PADMUX_CSI0_DATA13_OFFSET 0x028c +#define IMX_PADMUX_CSI0_DATA14_OFFSET 0x0290 +#define IMX_PADMUX_CSI0_DATA15_OFFSET 0x0294 +#define IMX_PADMUX_CSI0_DATA16_OFFSET 0x0298 +#define IMX_PADMUX_CSI0_DATA17_OFFSET 0x029c +#define IMX_PADMUX_CSI0_DATA18_OFFSET 0x02a0 +#define IMX_PADMUX_CSI0_DATA19_OFFSET 0x02a4 +#define IMX_PADMUX_SD3_DATA7_OFFSET 0x02a8 +#define IMX_PADMUX_SD3_DATA6_OFFSET 0x02ac +#define IMX_PADMUX_SD3_DATA5_OFFSET 0x02b0 +#define IMX_PADMUX_SD3_DATA4_OFFSET 0x02b4 +#define IMX_PADMUX_SD3_CMD_OFFSET 0x02b8 +#define IMX_PADMUX_SD3_CLK_OFFSET 0x02bc +#define IMX_PADMUX_SD3_DATA0_OFFSET 0x02c0 +#define IMX_PADMUX_SD3_DATA1_OFFSET 0x02c4 +#define IMX_PADMUX_SD3_DATA2_OFFSET 0x02c8 +#define IMX_PADMUX_SD3_DATA3_OFFSET 0x02cc +#define IMX_PADMUX_SD3_RESET_OFFSET 0x02d0 +#define IMX_PADMUX_NAND_CLE_OFFSET 0x02d4 +#define IMX_PADMUX_NAND_ALE_OFFSET 0x02d8 +#define IMX_PADMUX_NAND_WP_OFFSET 0x02dc +#define IMX_PADMUX_NAND_READY_OFFSET 0x02e0 +#define IMX_PADMUX_NAND_CS0_OFFSET 0x02e4 +#define IMX_PADMUX_NAND_CS1_OFFSET 0x02e8 +#define IMX_PADMUX_NAND_CS2_OFFSET 0x02ec +#define IMX_PADMUX_NAND_CS3_OFFSET 0x02f0 +#define IMX_PADMUX_SD4_CMD_OFFSET 0x02f4 +#define IMX_PADMUX_SD4_CLK_OFFSET 0x02f8 +#define IMX_PADMUX_NAND_DATA00_OFFSET 0x02fc +#define IMX_PADMUX_NAND_DATA01_OFFSET 0x0300 +#define IMX_PADMUX_NAND_DATA02_OFFSET 0x0304 +#define IMX_PADMUX_NAND_DATA03_OFFSET 0x0308 +#define IMX_PADMUX_NAND_DATA04_OFFSET 0x030c +#define IMX_PADMUX_NAND_DATA05_OFFSET 0x0310 +#define IMX_PADMUX_NAND_DATA06_OFFSET 0x0314 +#define IMX_PADMUX_NAND_DATA07_OFFSET 0x0318 +#define IMX_PADMUX_SD4_DATA0_OFFSET 0x031c +#define IMX_PADMUX_SD4_DATA1_OFFSET 0x0320 +#define IMX_PADMUX_SD4_DATA2_OFFSET 0x0324 +#define IMX_PADMUX_SD4_DATA3_OFFSET 0x0328 +#define IMX_PADMUX_SD4_DATA4_OFFSET 0x032c +#define IMX_PADMUX_SD4_DATA5_OFFSET 0x0330 +#define IMX_PADMUX_SD4_DATA6_OFFSET 0x0334 +#define IMX_PADMUX_SD4_DATA7_OFFSET 0x0338 +#define IMX_PADMUX_SD1_DATA1_OFFSET 0x033c +#define IMX_PADMUX_SD1_DATA0_OFFSET 0x0340 +#define IMX_PADMUX_SD1_DATA3_OFFSET 0x0344 +#define IMX_PADMUX_SD1_CMD_OFFSET 0x0348 +#define IMX_PADMUX_SD1_DATA2_OFFSET 0x034c +#define IMX_PADMUX_SD1_CLK_OFFSET 0x0350 +#define IMX_PADMUX_SD2_CLK_OFFSET 0x0354 +#define IMX_PADMUX_SD2_CMD_OFFSET 0x0358 +#define IMX_PADMUX_SD2_DATA3_OFFSET 0x035c + +/* Pad Control Registers */ +/* Pad Mux Register Indices (used by software for table lookups) */ + +#define IMX_PADCTL_SD2_DATA1_INDEX 0 +#define IMX_PADCTL_SD2_DATA2_INDEX 1 +#define IMX_PADCTL_SD2_DATA0_INDEX 2 +#define IMX_PADCTL_RGMII_TXC_INDEX 3 +#define IMX_PADCTL_RGMII_TD0_INDEX 4 +#define IMX_PADCTL_RGMII_TD1_INDEX 5 +#define IMX_PADCTL_RGMII_TD2_INDEX 6 +#define IMX_PADCTL_RGMII_TD3_INDEX 7 +#define IMX_PADCTL_RGMII_RX_CTL_INDEX 8 +#define IMX_PADCTL_RGMII_RD0_INDEX 9 +#define IMX_PADCTL_RGMII_TX_CTL_INDEX 10 +#define IMX_PADCTL_RGMII_RD1_INDEX 11 +#define IMX_PADCTL_RGMII_RD2_INDEX 12 +#define IMX_PADCTL_RGMII_RD3_INDEX 13 +#define IMX_PADCTL_RGMII_RXC_INDEX 14 +#define IMX_PADCTL_EIM_ADDR25_INDEX 15 +#define IMX_PADCTL_EIM_EB2_INDEX 16 +#define IMX_PADCTL_EIM_DATA16_INDEX 17 +#define IMX_PADCTL_EIM_DATA17_INDEX 18 +#define IMX_PADCTL_EIM_DATA18_INDEX 19 +#define IMX_PADCTL_EIM_DATA19_INDEX 20 +#define IMX_PADCTL_EIM_DATA20_INDEX 21 +#define IMX_PADCTL_EIM_DATA21_INDEX 22 +#define IMX_PADCTL_EIM_DATA22_INDEX 23 +#define IMX_PADCTL_EIM_DATA23_INDEX 24 +#define IMX_PADCTL_EIM_EB3_INDEX 25 +#define IMX_PADCTL_EIM_DATA24_INDEX 26 +#define IMX_PADCTL_EIM_DATA25_INDEX 27 +#define IMX_PADCTL_EIM_DATA26_INDEX 28 +#define IMX_PADCTL_EIM_DATA27_INDEX 29 +#define IMX_PADCTL_EIM_DATA28_INDEX 30 +#define IMX_PADCTL_EIM_DATA29_INDEX 31 +#define IMX_PADCTL_EIM_DATA30_INDEX 32 +#define IMX_PADCTL_EIM_DATA31_INDEX 33 +#define IMX_PADCTL_EIM_ADDR24_INDEX 34 +#define IMX_PADCTL_EIM_ADDR23_INDEX 35 +#define IMX_PADCTL_EIM_ADDR22_INDEX 36 +#define IMX_PADCTL_EIM_ADDR21_INDEX 37 +#define IMX_PADCTL_EIM_ADDR20_INDEX 38 +#define IMX_PADCTL_EIM_ADDR19_INDEX 39 +#define IMX_PADCTL_EIM_ADDR18_INDEX 40 +#define IMX_PADCTL_EIM_ADDR17_INDEX 41 +#define IMX_PADCTL_EIM_ADDR16_INDEX 42 +#define IMX_PADCTL_EIM_CS0_INDEX 43 +#define IMX_PADCTL_EIM_CS1_INDEX 44 +#define IMX_PADCTL_EIM_OE_INDEX 45 +#define IMX_PADCTL_EIM_RW_INDEX 46 +#define IMX_PADCTL_EIM_LBA_INDEX 47 +#define IMX_PADCTL_EIM_EB0_INDEX 48 +#define IMX_PADCTL_EIM_EB1_INDEX 49 +#define IMX_PADCTL_EIM_AD00_INDEX 50 +#define IMX_PADCTL_EIM_AD01_INDEX 51 +#define IMX_PADCTL_EIM_AD02_INDEX 52 +#define IMX_PADCTL_EIM_AD03_INDEX 53 +#define IMX_PADCTL_EIM_AD04_INDEX 54 +#define IMX_PADCTL_EIM_AD05_INDEX 55 +#define IMX_PADCTL_EIM_AD06_INDEX 56 +#define IMX_PADCTL_EIM_AD07_INDEX 57 +#define IMX_PADCTL_EIM_AD08_INDEX 58 +#define IMX_PADCTL_EIM_AD09_INDEX 59 +#define IMX_PADCTL_EIM_AD10_INDEX 60 +#define IMX_PADCTL_EIM_AD11_INDEX 61 +#define IMX_PADCTL_EIM_AD12_INDEX 62 +#define IMX_PADCTL_EIM_AD13_INDEX 63 +#define IMX_PADCTL_EIM_AD14_INDEX 64 +#define IMX_PADCTL_EIM_AD15_INDEX 65 +#define IMX_PADCTL_EIM_WAIT_INDEX 66 +#define IMX_PADCTL_EIM_BCLK_INDEX 67 +#define IMX_PADCTL_DI0_DISP_CLK_INDEX 68 +#define IMX_PADCTL_DI0_PIN15_INDEX 69 +#define IMX_PADCTL_DI0_PIN02_INDEX 70 +#define IMX_PADCTL_DI0_PIN03_INDEX 71 +#define IMX_PADCTL_DI0_PIN04_INDEX 72 +#define IMX_PADCTL_DISP0_DATA00_INDEX 73 +#define IMX_PADCTL_DISP0_DATA01_INDEX 74 +#define IMX_PADCTL_DISP0_DATA02_INDEX 75 +#define IMX_PADCTL_DISP0_DATA03_INDEX 76 +#define IMX_PADCTL_DISP0_DATA04_INDEX 77 +#define IMX_PADCTL_DISP0_DATA05_INDEX 78 +#define IMX_PADCTL_DISP0_DATA06_INDEX 79 +#define IMX_PADCTL_DISP0_DATA07_INDEX 80 +#define IMX_PADCTL_DISP0_DATA08_INDEX 81 +#define IMX_PADCTL_DISP0_DATA09_INDEX 82 +#define IMX_PADCTL_DISP0_DATA10_INDEX 83 +#define IMX_PADCTL_DISP0_DATA11_INDEX 84 +#define IMX_PADCTL_DISP0_DATA12_INDEX 85 +#define IMX_PADCTL_DISP0_DATA13_INDEX 86 +#define IMX_PADCTL_DISP0_DATA14_INDEX 87 +#define IMX_PADCTL_DISP0_DATA15_INDEX 88 +#define IMX_PADCTL_DISP0_DATA16_INDEX 89 +#define IMX_PADCTL_DISP0_DATA17_INDEX 90 +#define IMX_PADCTL_DISP0_DATA18_INDEX 91 +#define IMX_PADCTL_DISP0_DATA19_INDEX 92 +#define IMX_PADCTL_DISP0_DATA20_INDEX 93 +#define IMX_PADCTL_DISP0_DATA21_INDEX 94 +#define IMX_PADCTL_DISP0_DATA22_INDEX 95 +#define IMX_PADCTL_DISP0_DATA23_INDEX 96 +#define IMX_PADCTL_ENET_MDIO_INDEX 97 +#define IMX_PADCTL_ENET_REF_CLK_INDEX 98 +#define IMX_PADCTL_ENET_RX_ER_INDEX 99 +#define IMX_PADCTL_ENET_CRS_DV_INDEX 100 +#define IMX_PADCTL_ENET_RX_DATA1_INDEX 101 +#define IMX_PADCTL_ENET_RX_DATA0_INDEX 102 +#define IMX_PADCTL_ENET_TX_EN_INDEX 103 +#define IMX_PADCTL_ENET_TX_DATA1_INDEX 104 +#define IMX_PADCTL_ENET_TX_DATA0_INDEX 105 +#define IMX_PADCTL_ENET_MDC_INDEX 106 +#define IMX_PADCTL_DRAM_SDQS5_P_INDEX 107 +#define IMX_PADCTL_DRAM_DQM5_INDEX 108 +#define IMX_PADCTL_DRAM_DQM4_INDEX 109 +#define IMX_PADCTL_DRAM_SDQS4_P_INDEX 110 +#define IMX_PADCTL_DRAM_SDQS3_P_INDEX 111 +#define IMX_PADCTL_DRAM_DQM3_INDEX 112 +#define IMX_PADCTL_DRAM_SDQS2_P_INDEX 113 +#define IMX_PADCTL_DRAM_DQM2_INDEX 114 +#define IMX_PADCTL_DRAM_ADDR00_INDEX 115 +#define IMX_PADCTL_DRAM_ADDR01_INDEX 116 +#define IMX_PADCTL_DRAM_ADDR02_INDEX 117 +#define IMX_PADCTL_DRAM_ADDR03_INDEX 118 +#define IMX_PADCTL_DRAM_ADDR04_INDEX 119 +#define IMX_PADCTL_DRAM_ADDR05_INDEX 120 +#define IMX_PADCTL_DRAM_ADDR06_INDEX 121 +#define IMX_PADCTL_DRAM_ADDR07_INDEX 122 +#define IMX_PADCTL_DRAM_ADDR08_INDEX 123 +#define IMX_PADCTL_DRAM_ADDR09_INDEX 124 +#define IMX_PADCTL_DRAM_ADDR10_INDEX 125 +#define IMX_PADCTL_DRAM_ADDR11_INDEX 126 +#define IMX_PADCTL_DRAM_ADDR12_INDEX 127 +#define IMX_PADCTL_DRAM_ADDR13_INDEX 128 +#define IMX_PADCTL_DRAM_ADDR14_INDEX 129 +#define IMX_PADCTL_DRAM_ADDR15_INDEX 130 +#define IMX_PADCTL_DRAM_CAS_INDEX 131 +#define IMX_PADCTL_DRAM_CS0_INDEX 132 +#define IMX_PADCTL_DRAM_CS1_INDEX 133 +#define IMX_PADCTL_DRAM_RAS_INDEX 134 +#define IMX_PADCTL_DRAM_RESET_INDEX 135 +#define IMX_PADCTL_DRAM_SDBA0_INDEX 136 +#define IMX_PADCTL_DRAM_SDBA1_INDEX 137 +#define IMX_PADCTL_DRAM_SDCLK0_P_INDEX 138 +#define IMX_PADCTL_DRAM_SDBA2_INDEX 149 +#define IMX_PADCTL_DRAM_SDCKE0_INDEX 140 +#define IMX_PADCTL_DRAM_SDCLK1_P_INDEX 141 +#define IMX_PADCTL_DRAM_SDCKE1_INDEX 142 +#define IMX_PADCTL_DRAM_ODT0_INDEX 143 +#define IMX_PADCTL_DRAM_ODT1_INDEX 144 +#define IMX_PADCTL_DRAM_SDWE_B_INDEX 145 +#define IMX_PADCTL_DRAM_SDQS0_P_INDEX 146 +#define IMX_PADCTL_DRAM_DQM0_INDEX 147 +#define IMX_PADCTL_DRAM_SDQS1_P_INDEX 148 +#define IMX_PADCTL_DRAM_DQM1_INDEX 149 +#define IMX_PADCTL_DRAM_SDQS6_P_INDEX 150 +#define IMX_PADCTL_DRAM_DQM6_INDEX 151 +#define IMX_PADCTL_DRAM_SDQS7_P_INDEX 152 +#define IMX_PADCTL_DRAM_DQM7_INDEX 153 +#define IMX_PADCTL_KEY_COL0_INDEX 154 +#define IMX_PADCTL_KEY_ROW0_INDEX 155 +#define IMX_PADCTL_KEY_COL1_INDEX 156 +#define IMX_PADCTL_KEY_ROW1_INDEX 157 +#define IMX_PADCTL_KEY_COL2_INDEX 158 +#define IMX_PADCTL_KEY_ROW2_INDEX 159 +#define IMX_PADCTL_KEY_COL3_INDEX 160 +#define IMX_PADCTL_KEY_ROW3_INDEX 161 +#define IMX_PADCTL_KEY_COL4_INDEX 162 +#define IMX_PADCTL_KEY_ROW4_INDEX 163 +#define IMX_PADCTL_GPIO00_INDEX 164 +#define IMX_PADCTL_GPIO01_INDEX 165 +#define IMX_PADCTL_GPIO09_INDEX 166 +#define IMX_PADCTL_GPIO03_INDEX 167 +#define IMX_PADCTL_GPIO06_INDEX 168 +#define IMX_PADCTL_GPIO02_INDEX 169 +#define IMX_PADCTL_GPIO04_INDEX 170 +#define IMX_PADCTL_GPIO05_INDEX 171 +#define IMX_PADCTL_GPIO07_INDEX 172 +#define IMX_PADCTL_GPIO08_INDEX 173 +#define IMX_PADCTL_GPIO16_INDEX 174 +#define IMX_PADCTL_GPIO17_INDEX 175 +#define IMX_PADCTL_GPIO18_INDEX 176 +#define IMX_PADCTL_GPIO19_INDEX 177 +#define IMX_PADCTL_CSI0_PIXCLK_INDEX 178 +#define IMX_PADCTL_CSI0_HSYNC_INDEX 179 +#define IMX_PADCTL_CSI0_DATA_EN_INDEX 180 +#define IMX_PADCTL_CSI0_VSYNC_INDEX 181 +#define IMX_PADCTL_CSI0_DATA04_INDEX 182 +#define IMX_PADCTL_CSI0_DATA05_INDEX 183 +#define IMX_PADCTL_CSI0_DATA06_INDEX 184 +#define IMX_PADCTL_CSI0_DATA07_INDEX 185 +#define IMX_PADCTL_CSI0_DATA08_INDEX 186 +#define IMX_PADCTL_CSI0_DATA09_INDEX 187 +#define IMX_PADCTL_CSI0_DATA10_INDEX 188 +#define IMX_PADCTL_CSI0_DATA11_INDEX 189 +#define IMX_PADCTL_CSI0_DATA12_INDEX 190 +#define IMX_PADCTL_CSI0_DATA13_INDEX 191 +#define IMX_PADCTL_CSI0_DATA14_INDEX 192 +#define IMX_PADCTL_CSI0_DATA15_INDEX 193 +#define IMX_PADCTL_CSI0_DATA16_INDEX 194 +#define IMX_PADCTL_CSI0_DATA17_INDEX 195 +#define IMX_PADCTL_CSI0_DATA18_INDEX 196 +#define IMX_PADCTL_CSI0_DATA19_INDEX 197 +#define IMX_PADCTL_JTAG_TMS_INDEX 198 +#define IMX_PADCTL_JTAG_MOD_INDEX 199 +#define IMX_PADCTL_JTAG_TRSTB_INDEX 200 +#define IMX_PADCTL_JTAG_TDI_INDEX 201 +#define IMX_PADCTL_JTAG_TCK_INDEX 202 +#define IMX_PADCTL_JTAG_TDO_INDEX 203 +#define IMX_PADCTL_SD3_DATA7_INDEX 204 +#define IMX_PADCTL_SD3_DATA6_INDEX 205 +#define IMX_PADCTL_SD3_DATA5_INDEX 206 +#define IMX_PADCTL_SD3_DATA4_INDEX 207 +#define IMX_PADCTL_SD3_CMD_INDEX 208 +#define IMX_PADCTL_SD3_CLK_INDEX 209 +#define IMX_PADCTL_SD3_DATA0_INDEX 210 +#define IMX_PADCTL_SD3_DATA1_INDEX 211 +#define IMX_PADCTL_SD3_DATA2_INDEX 212 +#define IMX_PADCTL_SD3_DATA3_INDEX 213 +#define IMX_PADCTL_SD3_RESET_INDEX 214 +#define IMX_PADCTL_NAND_CLE_INDEX 215 +#define IMX_PADCTL_NAND_ALE_INDEX 216 +#define IMX_PADCTL_NAND_WP_INDEX 217 +#define IMX_PADCTL_NAND_READY_INDEX 218 +#define IMX_PADCTL_NAND_CS0_INDEX 219 +#define IMX_PADCTL_NAND_CS1_INDEX 220 +#define IMX_PADCTL_NAND_CS2_INDEX 221 +#define IMX_PADCTL_NAND_CS3_INDEX 222 +#define IMX_PADCTL_SD4_CMD_INDEX 223 +#define IMX_PADCTL_SD4_CLK_INDEX 224 +#define IMX_PADCTL_NAND_DATA00_INDEX 225 +#define IMX_PADCTL_NAND_DATA01_INDEX 226 +#define IMX_PADCTL_NAND_DATA02_INDEX 227 +#define IMX_PADCTL_NAND_DATA03_INDEX 228 +#define IMX_PADCTL_NAND_DATA04_INDEX 229 +#define IMX_PADCTL_NAND_DATA05_INDEX 230 +#define IMX_PADCTL_NAND_DATA06_INDEX 231 +#define IMX_PADCTL_NAND_DATA07_INDEX 232 +#define IMX_PADCTL_SD4_DATA0_INDEX 233 +#define IMX_PADCTL_SD4_DATA1_INDEX 234 +#define IMX_PADCTL_SD4_DATA2_INDEX 235 +#define IMX_PADCTL_SD4_DATA3_INDEX 236 +#define IMX_PADCTL_SD4_DATA4_INDEX 237 +#define IMX_PADCTL_SD4_DATA5_INDEX 238 +#define IMX_PADCTL_SD4_DATA6_INDEX 239 +#define IMX_PADCTL_SD4_DATA7_INDEX 240 +#define IMX_PADCTL_SD1_DATA1_INDEX 241 +#define IMX_PADCTL_SD1_DATA0_INDEX 242 +#define IMX_PADCTL_SD1_DATA3_INDEX 243 +#define IMX_PADCTL_SD1_CMD_INDEX 244 +#define IMX_PADCTL_SD1_DATA2_INDEX 245 +#define IMX_PADCTL_SD1_CLK_INDEX 246 +#define IMX_PADCTL_SD2_CLK_INDEX 247 +#define IMX_PADCTL_SD2_CMD_INDEX 248 +#define IMX_PADCTL_SD2_DATA3_INDEX 249 + +#define IMX_PADCTL_NREGISTERS 250 + +/* Pad Control Register Offsets */ + +#define IMX_PADCTL_OFFSET(n) (0x0360 + ((unsigned int)(n) << 2)) + +#define IMX_PADCTL_SD2_DATA1_OFFSET 0x0360 +#define IMX_PADCTL_SD2_DATA2_OFFSET 0x0364 +#define IMX_PADCTL_SD2_DATA0_OFFSET 0x0368 +#define IMX_PADCTL_RGMII_TXC_OFFSET 0x036c +#define IMX_PADCTL_RGMII_TD0_OFFSET 0x0370 +#define IMX_PADCTL_RGMII_TD1_OFFSET 0x0374 +#define IMX_PADCTL_RGMII_TD2_OFFSET 0x0378 +#define IMX_PADCTL_RGMII_TD3_OFFSET 0x037c +#define IMX_PADCTL_RGMII_RX_CTL_OFFSET 0x0380 +#define IMX_PADCTL_RGMII_RD0_OFFSET 0x0384 +#define IMX_PADCTL_RGMII_TX_CTL_OFFSET 0x0388 +#define IMX_PADCTL_RGMII_RD1_OFFSET 0x038c +#define IMX_PADCTL_RGMII_RD2_OFFSET 0x0390 +#define IMX_PADCTL_RGMII_RD3_OFFSET 0x0394 +#define IMX_PADCTL_RGMII_RXC_OFFSET 0x0398 +#define IMX_PADCTL_EIM_ADDR25_OFFSET 0x039c +#define IMX_PADCTL_EIM_EB2_OFFSET 0x03a0 +#define IMX_PADCTL_EIM_DATA16_OFFSET 0x03a4 +#define IMX_PADCTL_EIM_DATA17_OFFSET 0x03a8 +#define IMX_PADCTL_EIM_DATA18_OFFSET 0x03ac +#define IMX_PADCTL_EIM_DATA19_OFFSET 0x03b0 +#define IMX_PADCTL_EIM_DATA20_OFFSET 0x03b4 +#define IMX_PADCTL_EIM_DATA21_OFFSET 0x03b8 +#define IMX_PADCTL_EIM_DATA22_OFFSET 0x03bc +#define IMX_PADCTL_EIM_DATA23_OFFSET 0x03c0 +#define IMX_PADCTL_EIM_EB3_OFFSET 0x03c4 +#define IMX_PADCTL_EIM_DATA24_OFFSET 0x03c8 +#define IMX_PADCTL_EIM_DATA25_OFFSET 0x03cc +#define IMX_PADCTL_EIM_DATA26_OFFSET 0x03d0 +#define IMX_PADCTL_EIM_DATA27_OFFSET 0x03d4 +#define IMX_PADCTL_EIM_DATA28_OFFSET 0x03d8 +#define IMX_PADCTL_EIM_DATA29_OFFSET 0x03dc +#define IMX_PADCTL_EIM_DATA30_OFFSET 0x03e0 +#define IMX_PADCTL_EIM_DATA31_OFFSET 0x03e4 +#define IMX_PADCTL_EIM_ADDR24_OFFSET 0x03e8 +#define IMX_PADCTL_EIM_ADDR23_OFFSET 0x03ec +#define IMX_PADCTL_EIM_ADDR22_OFFSET 0x03f0 +#define IMX_PADCTL_EIM_ADDR21_OFFSET 0x03f4 +#define IMX_PADCTL_EIM_ADDR20_OFFSET 0x03f8 +#define IMX_PADCTL_EIM_ADDR19_OFFSET 0x03fc +#define IMX_PADCTL_EIM_ADDR18_OFFSET 0x0400 +#define IMX_PADCTL_EIM_ADDR17_OFFSET 0x0404 +#define IMX_PADCTL_EIM_ADDR16_OFFSET 0x0408 +#define IMX_PADCTL_EIM_CS0_OFFSET 0x040c +#define IMX_PADCTL_EIM_CS1_OFFSET 0x0410 +#define IMX_PADCTL_EIM_OE_OFFSET 0x0414 +#define IMX_PADCTL_EIM_RW_OFFSET 0x0418 +#define IMX_PADCTL_EIM_LBA_OFFSET 0x041c +#define IMX_PADCTL_EIM_EB0_OFFSET 0x0420 +#define IMX_PADCTL_EIM_EB1_OFFSET 0x0424 +#define IMX_PADCTL_EIM_AD00_OFFSET 0x0428 +#define IMX_PADCTL_EIM_AD01_OFFSET 0x042c +#define IMX_PADCTL_EIM_AD02_OFFSET 0x0430 +#define IMX_PADCTL_EIM_AD03_OFFSET 0x0434 +#define IMX_PADCTL_EIM_AD04_OFFSET 0x0438 +#define IMX_PADCTL_EIM_AD05_OFFSET 0x043c +#define IMX_PADCTL_EIM_AD06_OFFSET 0x0440 +#define IMX_PADCTL_EIM_AD07_OFFSET 0x0444 +#define IMX_PADCTL_EIM_AD08_OFFSET 0x0448 +#define IMX_PADCTL_EIM_AD09_OFFSET 0x044c +#define IMX_PADCTL_EIM_AD10_OFFSET 0x0450 +#define IMX_PADCTL_EIM_AD11_OFFSET 0x0454 +#define IMX_PADCTL_EIM_AD12_OFFSET 0x0458 +#define IMX_PADCTL_EIM_AD13_OFFSET 0x045c +#define IMX_PADCTL_EIM_AD14_OFFSET 0x0460 +#define IMX_PADCTL_EIM_AD15_OFFSET 0x0464 +#define IMX_PADCTL_EIM_WAIT_OFFSET 0x0468 +#define IMX_PADCTL_EIM_BCLK_OFFSET 0x046c +#define IMX_PADCTL_DI0_DISP_CLK_OFFSET 0x0470 +#define IMX_PADCTL_DI0_PIN15_OFFSET 0x0474 +#define IMX_PADCTL_DI0_PIN02_OFFSET 0x0478 +#define IMX_PADCTL_DI0_PIN03_OFFSET 0x047c +#define IMX_PADCTL_DI0_PIN04_OFFSET 0x0480 +#define IMX_PADCTL_DISP0_DATA00_OFFSET 0x0484 +#define IMX_PADCTL_DISP0_DATA01_OFFSET 0x0488 +#define IMX_PADCTL_DISP0_DATA02_OFFSET 0x048c +#define IMX_PADCTL_DISP0_DATA03_OFFSET 0x0490 +#define IMX_PADCTL_DISP0_DATA04_OFFSET 0x0494 +#define IMX_PADCTL_DISP0_DATA05_OFFSET 0x0498 +#define IMX_PADCTL_DISP0_DATA06_OFFSET 0x049c +#define IMX_PADCTL_DISP0_DATA07_OFFSET 0x04a0 +#define IMX_PADCTL_DISP0_DATA08_OFFSET 0x04a4 +#define IMX_PADCTL_DISP0_DATA09_OFFSET 0x04a8 +#define IMX_PADCTL_DISP0_DATA10_OFFSET 0x04ac +#define IMX_PADCTL_DISP0_DATA11_OFFSET 0x04b0 +#define IMX_PADCTL_DISP0_DATA12_OFFSET 0x04b4 +#define IMX_PADCTL_DISP0_DATA13_OFFSET 0x04b8 +#define IMX_PADCTL_DISP0_DATA14_OFFSET 0x04bc +#define IMX_PADCTL_DISP0_DATA15_OFFSET 0x04c0 +#define IMX_PADCTL_DISP0_DATA16_OFFSET 0x04c4 +#define IMX_PADCTL_DISP0_DATA17_OFFSET 0x04c8 +#define IMX_PADCTL_DISP0_DATA18_OFFSET 0x04cc +#define IMX_PADCTL_DISP0_DATA19_OFFSET 0x04d0 +#define IMX_PADCTL_DISP0_DATA20_OFFSET 0x04d4 +#define IMX_PADCTL_DISP0_DATA21_OFFSET 0x04d8 +#define IMX_PADCTL_DISP0_DATA22_OFFSET 0x04dc +#define IMX_PADCTL_DISP0_DATA23_OFFSET 0x04e0 +#define IMX_PADCTL_ENET_MDIO_OFFSET 0x04e4 +#define IMX_PADCTL_ENET_REF_CLK_OFFSET 0x04e8 +#define IMX_PADCTL_ENET_RX_ER_OFFSET 0x04ec +#define IMX_PADCTL_ENET_CRS_DV_OFFSET 0x04f0 +#define IMX_PADCTL_ENET_RX_DATA1_OFFSET 0x04f4 +#define IMX_PADCTL_ENET_RX_DATA0_OFFSET 0x04f8 +#define IMX_PADCTL_ENET_TX_EN_OFFSET 0x04fc +#define IMX_PADCTL_ENET_TX_DATA1_OFFSET 0x0500 +#define IMX_PADCTL_ENET_TX_DATA0_OFFSET 0x0504 +#define IMX_PADCTL_ENET_MDC_OFFSET 0x0508 +#define IMX_PADCTL_DRAM_SDQS5_P_OFFSET 0x050c +#define IMX_PADCTL_DRAM_DQM5_OFFSET 0x0510 +#define IMX_PADCTL_DRAM_DQM4_OFFSET 0x0514 +#define IMX_PADCTL_DRAM_SDQS4_P_OFFSET 0x0518 +#define IMX_PADCTL_DRAM_SDQS3_P_OFFSET 0x051c +#define IMX_PADCTL_DRAM_DQM3_OFFSET 0x0520 +#define IMX_PADCTL_DRAM_SDQS2_P_OFFSET 0x0524 +#define IMX_PADCTL_DRAM_DQM2_OFFSET 0x0528 +#define IMX_PADCTL_DRAM_ADDR00_OFFSET 0x052c +#define IMX_PADCTL_DRAM_ADDR01_OFFSET 0x0530 +#define IMX_PADCTL_DRAM_ADDR02_OFFSET 0x0534 +#define IMX_PADCTL_DRAM_ADDR03_OFFSET 0x0538 +#define IMX_PADCTL_DRAM_ADDR04_OFFSET 0x053c +#define IMX_PADCTL_DRAM_ADDR05_OFFSET 0x0540 +#define IMX_PADCTL_DRAM_ADDR06_OFFSET 0x0544 +#define IMX_PADCTL_DRAM_ADDR07_OFFSET 0x0548 +#define IMX_PADCTL_DRAM_ADDR08_OFFSET 0x054c +#define IMX_PADCTL_DRAM_ADDR09_OFFSET 0x0550 +#define IMX_PADCTL_DRAM_ADDR10_OFFSET 0x0554 +#define IMX_PADCTL_DRAM_ADDR11_OFFSET 0x0558 +#define IMX_PADCTL_DRAM_ADDR12_OFFSET 0x055c +#define IMX_PADCTL_DRAM_ADDR13_OFFSET 0x0560 +#define IMX_PADCTL_DRAM_ADDR14_OFFSET 0x0564 +#define IMX_PADCTL_DRAM_ADDR15_OFFSET 0x0568 +#define IMX_PADCTL_DRAM_CAS_OFFSET 0x056c +#define IMX_PADCTL_DRAM_CS0_OFFSET 0x0570 +#define IMX_PADCTL_DRAM_CS1_OFFSET 0x0574 +#define IMX_PADCTL_DRAM_RAS_OFFSET 0x0578 +#define IMX_PADCTL_DRAM_RESET_OFFSET 0x057c +#define IMX_PADCTL_DRAM_SDBA0_OFFSET 0x0580 +#define IMX_PADCTL_DRAM_SDBA1_OFFSET 0x0584 +#define IMX_PADCTL_DRAM_SDCLK0_P_OFFSET 0x0588 +#define IMX_PADCTL_DRAM_SDBA2_OFFSET 0x058c +#define IMX_PADCTL_DRAM_SDCKE0_OFFSET 0x0590 +#define IMX_PADCTL_DRAM_SDCLK1_P_OFFSET 0x0594 +#define IMX_PADCTL_DRAM_SDCKE1_OFFSET 0x0598 +#define IMX_PADCTL_DRAM_ODT0_OFFSET 0x059c +#define IMX_PADCTL_DRAM_ODT1_OFFSET 0x05a0 +#define IMX_PADCTL_DRAM_SDWE_B_OFFSET 0x05a4 +#define IMX_PADCTL_DRAM_SDQS0_P_OFFSET 0x05a8 +#define IMX_PADCTL_DRAM_DQM0_OFFSET 0x05ac +#define IMX_PADCTL_DRAM_SDQS1_P_OFFSET 0x05b0 +#define IMX_PADCTL_DRAM_DQM1_OFFSET 0x05b4 +#define IMX_PADCTL_DRAM_SDQS6_P_OFFSET 0x05b8 +#define IMX_PADCTL_DRAM_DQM6_OFFSET 0x05bc +#define IMX_PADCTL_DRAM_SDQS7_P_OFFSET 0x05c0 +#define IMX_PADCTL_DRAM_DQM7_OFFSET 0x05c4 +#define IMX_PADCTL_KEY_COL0_OFFSET 0x05c8 +#define IMX_PADCTL_KEY_ROW0_OFFSET 0x05cc +#define IMX_PADCTL_KEY_COL1_OFFSET 0x05d0 +#define IMX_PADCTL_KEY_ROW1_OFFSET 0x05d4 +#define IMX_PADCTL_KEY_COL2_OFFSET 0x05d8 +#define IMX_PADCTL_KEY_ROW2_OFFSET 0x05dc +#define IMX_PADCTL_KEY_COL3_OFFSET 0x05e0 +#define IMX_PADCTL_KEY_ROW3_OFFSET 0x05e4 +#define IMX_PADCTL_KEY_COL4_OFFSET 0x05e8 +#define IMX_PADCTL_KEY_ROW4_OFFSET 0x05ec +#define IMX_PADCTL_GPIO00_OFFSET 0x05f0 +#define IMX_PADCTL_GPIO01_OFFSET 0x05f4 +#define IMX_PADCTL_GPIO09_OFFSET 0x05f8 +#define IMX_PADCTL_GPIO03_OFFSET 0x05fc +#define IMX_PADCTL_GPIO06_OFFSET 0x0600 +#define IMX_PADCTL_GPIO02_OFFSET 0x0604 +#define IMX_PADCTL_GPIO04_OFFSET 0x0608 +#define IMX_PADCTL_GPIO05_OFFSET 0x060c +#define IMX_PADCTL_GPIO07_OFFSET 0x0610 +#define IMX_PADCTL_GPIO08_OFFSET 0x0614 +#define IMX_PADCTL_GPIO16_OFFSET 0x0618 +#define IMX_PADCTL_GPIO17_OFFSET 0x061c +#define IMX_PADCTL_GPIO18_OFFSET 0x0620 +#define IMX_PADCTL_GPIO19_OFFSET 0x0624 +#define IMX_PADCTL_CSI0_PIXCLK_OFFSET 0x0628 +#define IMX_PADCTL_CSI0_HSYNC_OFFSET 0x062c +#define IMX_PADCTL_CSI0_DATA_EN_OFFSET 0x0630 +#define IMX_PADCTL_CSI0_VSYNC_OFFSET 0x0634 +#define IMX_PADCTL_CSI0_DATA04_OFFSET 0x0638 +#define IMX_PADCTL_CSI0_DATA05_OFFSET 0x063c +#define IMX_PADCTL_CSI0_DATA06_OFFSET 0x0640 +#define IMX_PADCTL_CSI0_DATA07_OFFSET 0x0644 +#define IMX_PADCTL_CSI0_DATA08_OFFSET 0x0648 +#define IMX_PADCTL_CSI0_DATA09_OFFSET 0x064c +#define IMX_PADCTL_CSI0_DATA10_OFFSET 0x0650 +#define IMX_PADCTL_CSI0_DATA11_OFFSET 0x0654 +#define IMX_PADCTL_CSI0_DATA12_OFFSET 0x0658 +#define IMX_PADCTL_CSI0_DATA13_OFFSET 0x065c +#define IMX_PADCTL_CSI0_DATA14_OFFSET 0x0660 +#define IMX_PADCTL_CSI0_DATA15_OFFSET 0x0664 +#define IMX_PADCTL_CSI0_DATA16_OFFSET 0x0668 +#define IMX_PADCTL_CSI0_DATA17_OFFSET 0x066c +#define IMX_PADCTL_CSI0_DATA18_OFFSET 0x0670 +#define IMX_PADCTL_CSI0_DATA19_OFFSET 0x0674 +#define IMX_PADCTL_JTAG_TMS_OFFSET 0x0678 +#define IMX_PADCTL_JTAG_MOD_OFFSET 0x067c +#define IMX_PADCTL_JTAG_TRSTB_OFFSET 0x0680 +#define IMX_PADCTL_JTAG_TDI_OFFSET 0x0684 +#define IMX_PADCTL_JTAG_TCK_OFFSET 0x0688 +#define IMX_PADCTL_JTAG_TDO_OFFSET 0x068c +#define IMX_PADCTL_SD3_DATA7_OFFSET 0x0690 +#define IMX_PADCTL_SD3_DATA6_OFFSET 0x0694 +#define IMX_PADCTL_SD3_DATA5_OFFSET 0x0698 +#define IMX_PADCTL_SD3_DATA4_OFFSET 0x069c +#define IMX_PADCTL_SD3_CMD_OFFSET 0x06a0 +#define IMX_PADCTL_SD3_CLK_OFFSET 0x06a4 +#define IMX_PADCTL_SD3_DATA0_OFFSET 0x06a8 +#define IMX_PADCTL_SD3_DATA1_OFFSET 0x06ac +#define IMX_PADCTL_SD3_DATA2_OFFSET 0x06b0 +#define IMX_PADCTL_SD3_DATA3_OFFSET 0x06b4 +#define IMX_PADCTL_SD3_RESET_OFFSET 0x06b8 +#define IMX_PADCTL_NAND_CLE_OFFSET 0x06bc +#define IMX_PADCTL_NAND_ALE_OFFSET 0x06c0 +#define IMX_PADCTL_NAND_WP_OFFSET 0x06c4 +#define IMX_PADCTL_NAND_READY_OFFSET 0x06c8 +#define IMX_PADCTL_NAND_CS0_OFFSET 0x06cc +#define IMX_PADCTL_NAND_CS1_OFFSET 0x06d0 +#define IMX_PADCTL_NAND_CS2_OFFSET 0x06d4 +#define IMX_PADCTL_NAND_CS3_OFFSET 0x06d8 +#define IMX_PADCTL_SD4_CMD_OFFSET 0x06dc +#define IMX_PADCTL_SD4_CLK_OFFSET 0x06e0 +#define IMX_PADCTL_NAND_DATA00_OFFSET 0x06e4 +#define IMX_PADCTL_NAND_DATA01_OFFSET 0x06e8 +#define IMX_PADCTL_NAND_DATA02_OFFSET 0x06ec +#define IMX_PADCTL_NAND_DATA03_OFFSET 0x06f0 +#define IMX_PADCTL_NAND_DATA04_OFFSET 0x06f4 +#define IMX_PADCTL_NAND_DATA05_OFFSET 0x06f8 +#define IMX_PADCTL_NAND_DATA06_OFFSET 0x06fc +#define IMX_PADCTL_NAND_DATA07_OFFSET 0x0700 +#define IMX_PADCTL_SD4_DATA0_OFFSET 0x0704 +#define IMX_PADCTL_SD4_DATA1_OFFSET 0x0708 +#define IMX_PADCTL_SD4_DATA2_OFFSET 0x070c +#define IMX_PADCTL_SD4_DATA3_OFFSET 0x0710 +#define IMX_PADCTL_SD4_DATA4_OFFSET 0x0714 +#define IMX_PADCTL_SD4_DATA5_OFFSET 0x0718 +#define IMX_PADCTL_SD4_DATA6_OFFSET 0x071c +#define IMX_PADCTL_SD4_DATA7_OFFSET 0x0720 +#define IMX_PADCTL_SD1_DATA1_OFFSET 0x0724 +#define IMX_PADCTL_SD1_DATA0_OFFSET 0x0728 +#define IMX_PADCTL_SD1_DATA3_OFFSET 0x072c +#define IMX_PADCTL_SD1_CMD_OFFSET 0x0730 +#define IMX_PADCTL_SD1_DATA2_OFFSET 0x0734 +#define IMX_PADCTL_SD1_CLK_OFFSET 0x0738 +#define IMX_PADCTL_SD2_CLK_OFFSET 0x073c +#define IMX_PADCTL_SD2_CMD_OFFSET 0x0740 +#define IMX_PADCTL_SD2_DATA3_OFFSET 0x0744 + +/* Pad Group Control Registers */ + +#define IMX_PADGROUP_B7DS_OFFSET 0x0748 +#define IMX_PADGROUP_ADDDS_OFFSET 0x074c +#define IMX_PADGROUP_DDRMODE_CTL_OFFSET 0x0750 +#define IMX_PADGROUP_TERM_CTL0_OFFSET 0x0754 +#define IMX_PADGROUP_DDRPKE_OFFSET 0x0758 +#define IMX_PADGROUP_TERM_CTL1_OFFSET 0x075c +#define IMX_PADGROUP_TERM_CTL2_OFFSET 0x0760 +#define IMX_PADGROUP_TERM_CTL3_OFFSET 0x0764 +#define IMX_PADGROUP_DDRPK_OFFSET 0x0768 +#define IMX_PADGROUP_TERM_CTL4_OFFSET 0x076c +#define IMX_PADGROUP_DDRHYS_OFFSET 0x0770 +#define IMX_PADGROUP_DDRMODE_OFFSET 0x0774 +#define IMX_PADGROUP_TERM_CTL5_OFFSET 0x0778 +#define IMX_PADGROUP_TERM_CTL6_OFFSET 0x077c +#define IMX_PADGROUP_TERM_CTL7_OFFSET 0x0780 +#define IMX_PADGROUP_B0DS_OFFSET 0x0784 +#define IMX_PADGROUP_B1DS_OFFSET 0x0788 +#define IMX_PADGROUP_CTLDS_OFFSET 0x078c +#define IMX_PADGROUP_DDR_TYPE_RGMII_OFFSET 0x0790 +#define IMX_PADGROUP_B2DS_OFFSET 0x0794 +#define IMX_PADGROUP_DDR_TYPE_OFFSET 0x0798 +#define IMX_PADGROUP_B3DS_OFFSET 0x079c +#define IMX_PADGROUP_B4DS_OFFSET 0x07a0 +#define IMX_PADGROUP_B5DS_OFFSET 0x07a4 +#define IMX_PADGROUP_B6DS_OFFSET 0x07a8 +#define IMX_PADGROUP_RGMII_TERM_OFFSET 0x07ac + +/* Select Input Registers */ + +#define IMX_INPUT_ASRC_ASRCK_CLOCK_6_OFFSET 0x07b0 +#define IMX_INPUT_AUD4_INPUT_DA_AMX_OFFSET 0x07b4 +#define IMX_INPUT_AUD4_INPUT_DB_AMX_OFFSET 0x07b8 +#define IMX_INPUT_AUD4_INPUT_RXCLK_AMX_OFFSET 0x07bc +#define IMX_INPUT_AUD4_INPUT_RXFS_AMX_OFFSET 0x07c0 +#define IMX_INPUT_AUD4_INPUT_TXCLK_AMX_OFFSET 0x07c4 +#define IMX_INPUT_AUD4_INPUT_TXFS_AMX_OFFSET 0x07c8 +#define IMX_INPUT_AUD5_INPUT_DA_AMX_OFFSET 0x07cc +#define IMX_INPUT_AUD5_INPUT_DB_AMX_OFFSET 0x07d0 +#define IMX_INPUT_AUD5_INPUT_RXCLK_AMX_OFFSET 0x07d4 +#define IMX_INPUT_AUD5_INPUT_RXFS_AMX_OFFSET 0x07d8 +#define IMX_INPUT_AUD5_INPUT_TXCLK_AMX_OFFSET 0x07dc +#define IMX_INPUT_AUD5_INPUT_TXFS_AMX_OFFSET 0x07e0 +#define IMX_INPUT_FLEXCAN1_RX_OFFSET 0x07e4 +#define IMX_INPUT_FLEXCAN2_RX_OFFSET 0x07e8 +#define IMX_INPUT_CCM_PMIC_READY_OFFSET 0x07e0 +#define IMX_INPUT_ECSPI1_CSPI_CLK_IN_OFFSET 0x07f4 +#define IMX_INPUT_ECSPI1_MISO_OFFSET 0x07f8 +#define IMX_INPUT_ECSPI1_MOSI_OFFSET 0x07fc +#define IMX_INPUT_ECSPI1_SS0_OFFSET 0x0800 +#define IMX_INPUT_ECSPI1_SS1_OFFSET 0x0804 +#define IMX_INPUT_ECSPI1_SS2_OFFSET 0x0808 +#define IMX_INPUT_ECSPI1_SS3_OFFSET 0x080c +#define IMX_INPUT_ECSPI2_CSPI_CLK_IN_OFFSET 0x0810 +#define IMX_INPUT_ECSPI2_MISO_OFFSET 0x0814 +#define IMX_INPUT_ECSPI2_MOSI_OFFSET 0x0818 +#define IMX_INPUT_ECSPI2_SS0_OFFSET 0x081c +#define IMX_INPUT_ECSPI2_SS1_OFFSET 0x0820 +#define IMX_INPUT_ECSPI4_SS0_OFFSET 0x0824 +#define IMX_INPUT_ECSPI5_CSPI_CLK_IN_OFFSET 0x0828 +#define IMX_INPUT_ECSPI5_MISO_OFFSET 0x082c +#define IMX_INPUT_ECSPI5_MOSI_OFFSET 0x0830 +#define IMX_INPUT_ECSPI5_SS0_OFFSET 0x0834 +#define IMX_INPUT_ECSPI5_SS1_OFFSET 0x0838 +#define IMX_INPUT_ENET_REF_CLK_OFFSET 0x083c +#define IMX_INPUT_ENET_MAC0_MDIO_OFFSET 0x0840 +#define IMX_INPUT_ENET_MAC0_RX_CLK_OFFSET 0x0844 +#define IMX_INPUT_ENET_MAC0_RX_DATA0_OFFSET 0x0848 +#define IMX_INPUT_ENET_MAC0_RX_DATA1_OFFSET 0x084c +#define IMX_INPUT_ENET_MAC0_RX_DATA2_OFFSET 0x0850 +#define IMX_INPUT_ENET_MAC0_RX_DATA3_OFFSET 0x0854 +#define IMX_INPUT_ENET_MAC0_RX_EN_OFFSET 0x0858 +#define IMX_INPUT_ESAI_RX_FS_OFFSET 0x085c +#define IMX_INPUT_ESAI_TX_FS_OFFSET 0x0860 +#define IMX_INPUT_ESAI_RX_HF_CLK_OFFSET 0x0864 +#define IMX_INPUT_ESAI_TX_HF_CLK_OFFSET 0x0868 +#define IMX_INPUT_ESAI_RX_CLK_OFFSET 0x086c +#define IMX_INPUT_ESAI_TX_CLK_OFFSET 0x0870 +#define IMX_INPUT_ESAI_SDO0_OFFSET 0x0874 +#define IMX_INPUT_ESAI_SDO1_OFFSET 0x0878 +#define IMX_INPUT_ESAI_SDO2_SDI3_OFFSET 0x087c +#define IMX_INPUT_ESAI_SDO3_SDI2_OFFSET 0x0880 +#define IMX_INPUT_ESAI_SDO4_SDI1_OFFSET 0x0884 +#define IMX_INPUT_ESAI_SDO5_SDI0_OFFSET 0x0888 +#define IMX_INPUT_HDMI_ICECIN_OFFSET 0x088c +#define IMX_INPUT_HDMI_II2C_CLKIN_OFFSET 0x0890 +#define IMX_INPUT_HDMI_II2C_DATAIN_OFFSET 0x0894 +#define IMX_INPUT_I2C1_SCL_IN_OFFSET 0x0898 +#define IMX_INPUT_I2C1_SDA_IN_OFFSET 0x089c +#define IMX_INPUT_I2C2_SCL_IN_OFFSET 0x08a0 +#define IMX_INPUT_I2C2_SDA_IN_OFFSET 0x08a4 +#define IMX_INPUT_I2C3_SCL_IN_OFFSET 0x08a8 +#define IMX_INPUT_I2C3_SDA_IN_OFFSET 0x08ac +#define IMX_INPUT_IPU2_SENS1_DATA10_OFFSET 0x08b0 +#define IMX_INPUT_IPU2_SENS1_DATA11_OFFSET 0x08b4 +#define IMX_INPUT_IPU2_SENS1_DATA12_OFFSET 0x08b8 +#define IMX_INPUT_IPU2_SENS1_DATA13_OFFSET 0x08bc +#define IMX_INPUT_IPU2_SENS1_DATA14_OFFSET 0x08c0 +#define IMX_INPUT_IPU2_SENS1_DATA15_OFFSET 0x08c4 +#define IMX_INPUT_IPU2_SENS1_DATA16_OFFSET 0x08c8 +#define IMX_INPUT_IPU2_SENS1_DATA17_OFFSET 0x08cc +#define IMX_INPUT_IPU2_SENS1_DATA18_OFFSET 0x08d0 +#define IMX_INPUT_IPU2_SENS1_DATA19_OFFSET 0x08d4 +#define IMX_INPUT_IPU2_SENS1_DATA_EN_OFFSET 0x08d8 +#define IMX_INPUT_IPU2_SENS1_HSYNC_OFFSET 0x08dc +#define IMX_INPUT_IPU2_SENS1_PIX_CLK_OFFSET 0x08e0 +#define IMX_INPUT_IPU2_SENS1_VSYNC_OFFSET 0x08e4 +#define IMX_INPUT_KEY_COL5_OFFSET 0x08e8 +#define IMX_INPUT_KEY_COL6_OFFSET 0x08ec +#define IMX_INPUT_KEY_COL7_OFFSET 0x08f0 +#define IMX_INPUT_KEY_ROW5_OFFSET 0x08f4 +#define IMX_INPUT_KEY_ROW6_OFFSET 0x08f8 +#define IMX_INPUT_KEY_ROW7_OFFSET 0x08fc +#define IMX_INPUT_MLB_MLB_CLK_IN_OFFSET 0x0900 +#define IMX_INPUT_MLB_MLB_DATA_IN_OFFSET 0x0904 +#define IMX_INPUT_MLB_MLB_SIG_IN_OFFSET 0x0908 +#define IMX_INPUT_SDMA_EVENTS14_OFFSET 0x090c +#define IMX_INPUT_SDMA_EVENTS47_OFFSET 0x0910 +#define IMX_INPUT_SPDIF_SPDIF_IN1_OFFSET 0x0914 +#define IMX_INPUT_SPDIF_TX_CLK2_OFFSET 0x0918 +#define IMX_INPUT_UART1_UART_RTS_B_OFFSET 0x091c +#define IMX_INPUT_UART1_UART_RX_DATA_OFFSET 0x0920 +#define IMX_INPUT_UART2_UART_RTS_B_OFFSET 0x0924 +#define IMX_INPUT_UART2_UART_RX_DATA_OFFSET 0x0928 +#define IMX_INPUT_UART3_UART_RTS_B_OFFSET 0x092c +#define IMX_INPUT_UART3_UART_RX_DATA_OFFSET 0x0930 +#define IMX_INPUT_UART4_UART_RTS_B_OFFSET 0x0934 +#define IMX_INPUT_UART4_UART_RX_DATA_OFFSET 0x0938 +#define IMX_INPUT_UART5_UART_RTS_B_OFFSET 0x093c +#define IMX_INPUT_UART5_UART_RX_DATA_OFFSET 0x0940 +#define IMX_INPUT_USB_OTG_OC_OFFSET 0x0944 +#define IMX_INPUT_USB_H1_OC_OFFSET 0x0948 +#define IMX_INPUT_USDHC1_WP_ON_OFFSET 0x094c + +/* IOMUXC Register Addresses ********************************************************/ +/* General Purpose Registers */ + +#define IMX_IOMUXC_GPR0 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR0_OFFSET) +#define IMX_IOMUXC_GPR1 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR1_OFFSET) +#define IMX_IOMUXC_GPR2 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR2_OFFSET) +#define IMX_IOMUXC_GPR3 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR3_OFFSET) +#define IMX_IOMUXC_GPR4 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR4_OFFSET) +#define IMX_IOMUXC_GPR5 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR5_OFFSET) +#define IMX_IOMUXC_GPR6 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR6_OFFSET) +#define IMX_IOMUXC_GPR7 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR7_OFFSET) +#define IMX_IOMUXC_GPR8 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR8_OFFSET) +#define IMX_IOMUXC_GPR9 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR9_OFFSET) +#define IMX_IOMUXC_GPR10 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR10_OFFSET) +#define IMX_IOMUXC_GPR11 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR11_OFFSET) +#define IMX_IOMUXC_GPR12 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR12_OFFSET) +#define IMX_IOMUXC_GPR13 (IMX_IOMUXC_VBASE+IMX_IOMUXC_GPR13_OFFSET) + +/* Pad Mux Registers */ + +#define IMX_PADMUX_ADDRESS(n) (IMX_IOMUXC_VBASE+IMX_PADMUX_OFFSET(n)) + +#define IMX_PADMUX_SD2_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_DATA1_OFFSET) +#define IMX_PADMUX_SD2_DATA2 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_DATA2_OFFSET) +#define IMX_PADMUX_SD2_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_DATA0_OFFSET) +#define IMX_PADMUX_RGMII_TXC (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TXC_OFFSET) +#define IMX_PADMUX_RGMII_TD0 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TD0_OFFSET) +#define IMX_PADMUX_RGMII_TD1 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TD1_OFFSET) +#define IMX_PADMUX_RGMII_TD2 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TD2_OFFSET) +#define IMX_PADMUX_RGMII_TD3 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TD3_OFFSET) +#define IMX_PADMUX_RGMII_RX_CTL (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RX_CTL_OFFSET) +#define IMX_PADMUX_RGMII_RD0 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RD0_OFFSET) +#define IMX_PADMUX_RGMII_TX_CTL (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_TX_CTL_OFFSET) +#define IMX_PADMUX_RGMII_RD1 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RD1_OFFSET) +#define IMX_PADMUX_RGMII_RD2 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RD2_OFFSET) +#define IMX_PADMUX_RGMII_RD3 (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RD3_OFFSET) +#define IMX_PADMUX_RGMII_RXC (IMX_IOMUXC_VBASE+IMX_PADMUX_RGMII_RXC_OFFSET) +#define IMX_PADMUX_EIM_ADDR25 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR25_OFFSET) +#define IMX_PADMUX_EIM_EB2 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_EB2_OFFSET) +#define IMX_PADMUX_EIM_DATA16 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA16_OFFSET) +#define IMX_PADMUX_EIM_DATA17 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA17_OFFSET) +#define IMX_PADMUX_EIM_DATA18 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA18_OFFSET) +#define IMX_PADMUX_EIM_DATA19 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA19_OFFSET) +#define IMX_PADMUX_EIM_DATA20 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA20_OFFSET) +#define IMX_PADMUX_EIM_DATA21 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA21_OFFSET) +#define IMX_PADMUX_EIM_DATA22 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA22_OFFSET) +#define IMX_PADMUX_EIM_DATA23 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA23_OFFSET) +#define IMX_PADMUX_EIM_EB3 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_EB3_OFFSET) +#define IMX_PADMUX_EIM_DATA24 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA24_OFFSET) +#define IMX_PADMUX_EIM_DATA25 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA25_OFFSET) +#define IMX_PADMUX_EIM_DATA26 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA26_OFFSET) +#define IMX_PADMUX_EIM_DATA27 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA27_OFFSET) +#define IMX_PADMUX_EIM_DATA28 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA28_OFFSET) +#define IMX_PADMUX_EIM_DATA29 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA29_OFFSET) +#define IMX_PADMUX_EIM_DATA30 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA30_OFFSET) +#define IMX_PADMUX_EIM_DATA31 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_DATA31_OFFSET) +#define IMX_PADMUX_EIM_ADDR24 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR24_OFFSET) +#define IMX_PADMUX_EIM_ADDR23 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR23_OFFSET) +#define IMX_PADMUX_EIM_ADDR22 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR22_OFFSET) +#define IMX_PADMUX_EIM_ADDR21 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR21_OFFSET) +#define IMX_PADMUX_EIM_ADDR20 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR20_OFFSET) +#define IMX_PADMUX_EIM_ADDR19 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR19_OFFSET) +#define IMX_PADMUX_EIM_ADDR18 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR18_OFFSET) +#define IMX_PADMUX_EIM_ADDR17 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR17_OFFSET) +#define IMX_PADMUX_EIM_ADDR16 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_ADDR16_OFFSET) +#define IMX_PADMUX_EIM_CS0 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_CS0_OFFSET) +#define IMX_PADMUX_EIM_CS1 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_CS1_OFFSET) +#define IMX_PADMUX_EIM_OE (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_OE_OFFSET) +#define IMX_PADMUX_EIM_RW (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_RW_OFFSET) +#define IMX_PADMUX_EIM_LBA (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_LBA_OFFSET) +#define IMX_PADMUX_EIM_EB0 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_EB0_OFFSET) +#define IMX_PADMUX_EIM_EB1 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_EB1_OFFSET) +#define IMX_PADMUX_EIM_AD00 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD00_OFFSET) +#define IMX_PADMUX_EIM_AD01 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD01_OFFSET) +#define IMX_PADMUX_EIM_AD02 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD02_OFFSET) +#define IMX_PADMUX_EIM_AD03 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD03_OFFSET) +#define IMX_PADMUX_EIM_AD04 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD04_OFFSET) +#define IMX_PADMUX_EIM_AD05 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD05_OFFSET) +#define IMX_PADMUX_EIM_AD06 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD06_OFFSET) +#define IMX_PADMUX_EIM_AD07 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD07_OFFSET) +#define IMX_PADMUX_EIM_AD08 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD08_OFFSET) +#define IMX_PADMUX_EIM_AD09 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD09_OFFSET) +#define IMX_PADMUX_EIM_AD10 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD10_OFFSET) +#define IMX_PADMUX_EIM_AD11 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD11_OFFSET) +#define IMX_PADMUX_EIM_AD12 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD12_OFFSET) +#define IMX_PADMUX_EIM_AD13 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD13_OFFSET) +#define IMX_PADMUX_EIM_AD14 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD14_OFFSET) +#define IMX_PADMUX_EIM_AD15 (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_AD15_OFFSET) +#define IMX_PADMUX_EIM_WAIT (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_WAIT_OFFSET) +#define IMX_PADMUX_EIM_BCLK (IMX_IOMUXC_VBASE+IMX_PADMUX_EIM_BCLK_OFFSET) +#define IMX_PADMUX_DI0_DISP_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_DI0_DISP_CLK_OFFSET) +#define IMX_PADMUX_DI0_PIN15 (IMX_IOMUXC_VBASE+IMX_PADMUX_DI0_PIN15_OFFSET) +#define IMX_PADMUX_DI0_PIN02 (IMX_IOMUXC_VBASE+IMX_PADMUX_DI0_PIN02_OFFSET) +#define IMX_PADMUX_DI0_PIN03 (IMX_IOMUXC_VBASE+IMX_PADMUX_DI0_PIN03_OFFSET) +#define IMX_PADMUX_DI0_PIN04 (IMX_IOMUXC_VBASE+IMX_PADMUX_DI0_PIN04_OFFSET) +#define IMX_PADMUX_DISP0_DATA00 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA00_OFFSET) +#define IMX_PADMUX_DISP0_DATA01 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA01_OFFSET) +#define IMX_PADMUX_DISP0_DATA02 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA02_OFFSET) +#define IMX_PADMUX_DISP0_DATA03 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA03_OFFSET) +#define IMX_PADMUX_DISP0_DATA04 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA04_OFFSET) +#define IMX_PADMUX_DISP0_DATA05 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA05_OFFSET) +#define IMX_PADMUX_DISP0_DATA06 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA06_OFFSET) +#define IMX_PADMUX_DISP0_DATA07 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA07_OFFSET) +#define IMX_PADMUX_DISP0_DATA08 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA08_OFFSET) +#define IMX_PADMUX_DISP0_DATA09 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA09_OFFSET) +#define IMX_PADMUX_DISP0_DATA10 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA10_OFFSET) +#define IMX_PADMUX_DISP0_DATA11 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA11_OFFSET) +#define IMX_PADMUX_DISP0_DATA12 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA12_OFFSET) +#define IMX_PADMUX_DISP0_DATA13 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA13_OFFSET) +#define IMX_PADMUX_DISP0_DATA14 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA14_OFFSET) +#define IMX_PADMUX_DISP0_DATA15 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA15_OFFSET) +#define IMX_PADMUX_DISP0_DATA16 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA16_OFFSET) +#define IMX_PADMUX_DISP0_DATA17 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA17_OFFSET) +#define IMX_PADMUX_DISP0_DATA18 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA18_OFFSET) +#define IMX_PADMUX_DISP0_DATA19 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA19_OFFSET) +#define IMX_PADMUX_DISP0_DATA20 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA20_OFFSET) +#define IMX_PADMUX_DISP0_DATA21 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA21_OFFSET) +#define IMX_PADMUX_DISP0_DATA22 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA22_OFFSET) +#define IMX_PADMUX_DISP0_DATA23 (IMX_IOMUXC_VBASE+IMX_PADMUX_DISP0_DATA23_OFFSET) +#define IMX_PADMUX_ENET_MDIO (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_MDIO_OFFSET) +#define IMX_PADMUX_ENET_REF_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_REF_CLK_OFFSET) +#define IMX_PADMUX_ENET_RX_ER (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_RX_ER_OFFSET) +#define IMX_PADMUX_ENET_CRS_DV (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_CRS_DV_OFFSET) +#define IMX_PADMUX_ENET_RX_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_RX_DATA1_OFFSET) +#define IMX_PADMUX_ENET_RX_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_RX_DATA0_OFFSET) +#define IMX_PADMUX_ENET_TX_EN (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_TX_EN_OFFSET) +#define IMX_PADMUX_ENET_TX_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_TX_DATA1_OFFSET) +#define IMX_PADMUX_ENET_TX_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_TX_DATA0_OFFSET) +#define IMX_PADMUX_ENET_MDC (IMX_IOMUXC_VBASE+IMX_PADMUX_ENET_MDC_OFFSET) +#define IMX_PADMUX_KEY_COL0 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_COL0_OFFSET) +#define IMX_PADMUX_KEY_ROW0 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_ROW0_OFFSET) +#define IMX_PADMUX_KEY_COL1 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_COL1_OFFSET) +#define IMX_PADMUX_KEY_ROW1 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_ROW1_OFFSET) +#define IMX_PADMUX_KEY_COL2 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_COL2_OFFSET) +#define IMX_PADMUX_KEY_ROW2 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_ROW2_OFFSET) +#define IMX_PADMUX_KEY_COL3 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_COL3_OFFSET) +#define IMX_PADMUX_KEY_ROW3 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_ROW3_OFFSET) +#define IMX_PADMUX_KEY_COL4 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_COL4_OFFSET) +#define IMX_PADMUX_KEY_ROW4 (IMX_IOMUXC_VBASE+IMX_PADMUX_KEY_ROW4_OFFSET) +#define IMX_PADMUX_GPIO00 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO00_OFFSET) +#define IMX_PADMUX_GPIO01 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO01_OFFSET) +#define IMX_PADMUX_GPIO09 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO09_OFFSET) +#define IMX_PADMUX_GPIO03 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO03_OFFSET) +#define IMX_PADMUX_GPIO06 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO06_OFFSET) +#define IMX_PADMUX_GPIO02 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO02_OFFSET) +#define IMX_PADMUX_GPIO04 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO04_OFFSET) +#define IMX_PADMUX_GPIO05 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO05_OFFSET) +#define IMX_PADMUX_GPIO07 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO07_OFFSET) +#define IMX_PADMUX_GPIO08 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO08_OFFSET) +#define IMX_PADMUX_GPIO16 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO16_OFFSET) +#define IMX_PADMUX_GPIO17 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO17_OFFSET) +#define IMX_PADMUX_GPIO18 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO18_OFFSET) +#define IMX_PADMUX_GPIO19 (IMX_IOMUXC_VBASE+IMX_PADMUX_GPIO19_OFFSET) +#define IMX_PADMUX_CSI0_PIXCLK (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_PIXCLK_OFFSET) +#define IMX_PADMUX_CSI0_HSYNC (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_HSYNC_OFFSET) +#define IMX_PADMUX_CSI0_DATA_EN (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA_EN_OFFSET) +#define IMX_PADMUX_CSI0_VSYNC (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_VSYNC_OFFSET) +#define IMX_PADMUX_CSI0_DATA04 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA04_OFFSET) +#define IMX_PADMUX_CSI0_DATA05 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA05_OFFSET) +#define IMX_PADMUX_CSI0_DATA06 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA06_OFFSET) +#define IMX_PADMUX_CSI0_DATA07 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA07_OFFSET) +#define IMX_PADMUX_CSI0_DATA08 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA08_OFFSET) +#define IMX_PADMUX_CSI0_DATA09 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA09_OFFSET) +#define IMX_PADMUX_CSI0_DATA10 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA10_OFFSET) +#define IMX_PADMUX_CSI0_DATA11 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA11_OFFSET) +#define IMX_PADMUX_CSI0_DATA12 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA12_OFFSET) +#define IMX_PADMUX_CSI0_DATA13 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA13_OFFSET) +#define IMX_PADMUX_CSI0_DATA14 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA14_OFFSET) +#define IMX_PADMUX_CSI0_DATA15 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA15_OFFSET) +#define IMX_PADMUX_CSI0_DATA16 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA16_OFFSET) +#define IMX_PADMUX_CSI0_DATA17 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA17_OFFSET) +#define IMX_PADMUX_CSI0_DATA18 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA18_OFFSET) +#define IMX_PADMUX_CSI0_DATA19 (IMX_IOMUXC_VBASE+IMX_PADMUX_CSI0_DATA19_OFFSET) +#define IMX_PADMUX_SD3_DATA7 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA7_OFFSET) +#define IMX_PADMUX_SD3_DATA6 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA6_OFFSET) +#define IMX_PADMUX_SD3_DATA5 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA5_OFFSET) +#define IMX_PADMUX_SD3_DATA4 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA4_OFFSET) +#define IMX_PADMUX_SD3_CMD (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_CMD_OFFSET) +#define IMX_PADMUX_SD3_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_CLK_OFFSET) +#define IMX_PADMUX_SD3_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA0_OFFSET) +#define IMX_PADMUX_SD3_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA1_OFFSET) +#define IMX_PADMUX_SD3_DATA2 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA2_OFFSET) +#define IMX_PADMUX_SD3_DATA3 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_DATA3_OFFSET) +#define IMX_PADMUX_SD3_RESET (IMX_IOMUXC_VBASE+IMX_PADMUX_SD3_RESET_OFFSET) +#define IMX_PADMUX_NAND_CLE (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_CLE_OFFSET) +#define IMX_PADMUX_NAND_ALE (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_ALE_OFFSET) +#define IMX_PADMUX_NAND_WP (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_WP_OFFSET) +#define IMX_PADMUX_NAND_READY (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_READY_OFFSET) +#define IMX_PADMUX_NAND_CS0 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_CS0_OFFSET) +#define IMX_PADMUX_NAND_CS1 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_CS1_OFFSET) +#define IMX_PADMUX_NAND_CS2 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_CS2_OFFSET) +#define IMX_PADMUX_NAND_CS3 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_CS3_OFFSET) +#define IMX_PADMUX_SD4_CMD (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_CMD_OFFSET) +#define IMX_PADMUX_SD4_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_CLK_OFFSET) +#define IMX_PADMUX_NAND_DATA00 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA00_OFFSET) +#define IMX_PADMUX_NAND_DATA01 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA01_OFFSET) +#define IMX_PADMUX_NAND_DATA02 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA02_OFFSET) +#define IMX_PADMUX_NAND_DATA03 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA03_OFFSET) +#define IMX_PADMUX_NAND_DATA04 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA04_OFFSET) +#define IMX_PADMUX_NAND_DATA05 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA05_OFFSET) +#define IMX_PADMUX_NAND_DATA06 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA06_OFFSET) +#define IMX_PADMUX_NAND_DATA07 (IMX_IOMUXC_VBASE+IMX_PADMUX_NAND_DATA07_OFFSET) +#define IMX_PADMUX_SD4_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA0_OFFSET) +#define IMX_PADMUX_SD4_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA1_OFFSET) +#define IMX_PADMUX_SD4_DATA2 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA2_OFFSET) +#define IMX_PADMUX_SD4_DATA3 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA3_OFFSET) +#define IMX_PADMUX_SD4_DATA4 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA4_OFFSET) +#define IMX_PADMUX_SD4_DATA5 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA5_OFFSET) +#define IMX_PADMUX_SD4_DATA6 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA6_OFFSET) +#define IMX_PADMUX_SD4_DATA7 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD4_DATA7_OFFSET) +#define IMX_PADMUX_SD1_DATA1 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_DATA1_OFFSET) +#define IMX_PADMUX_SD1_DATA0 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_DATA0_OFFSET) +#define IMX_PADMUX_SD1_DATA3 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_DATA3_OFFSET) +#define IMX_PADMUX_SD1_CMD (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_CMD_OFFSET) +#define IMX_PADMUX_SD1_DATA2 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_DATA2_OFFSET) +#define IMX_PADMUX_SD1_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_SD1_CLK_OFFSET) +#define IMX_PADMUX_SD2_CLK (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_CLK_OFFSET) +#define IMX_PADMUX_SD2_CMD (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_CMD_OFFSET) +#define IMX_PADMUX_SD2_DATA3 (IMX_IOMUXC_VBASE+IMX_PADMUX_SD2_DATA3_OFFSET) + +/* Pad Control Registers */ + +#define IMX_PADCTL_ADDRESS(n) (IMX_IOMUXC_VBASE+IMX_PADCTL_OFFSET(n)) + +#define IMX_PADCTL_SD2_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_DATA1_OFFSET) +#define IMX_PADCTL_SD2_DATA2 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_DATA2_OFFSET) +#define IMX_PADCTL_SD2_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_DATA0_OFFSET) +#define IMX_PADCTL_RGMII_TXC (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TXC_OFFSET) +#define IMX_PADCTL_RGMII_TD0 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TD0_OFFSET) +#define IMX_PADCTL_RGMII_TD1 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TD1_OFFSET) +#define IMX_PADCTL_RGMII_TD2 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TD2_OFFSET) +#define IMX_PADCTL_RGMII_TD3 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TD3_OFFSET) +#define IMX_PADCTL_RGMII_RX_CTL (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RX_CTL_OFFSET) +#define IMX_PADCTL_RGMII_RD0 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RD0_OFFSET) +#define IMX_PADCTL_RGMII_TX_CTL (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_TX_CTL_OFFSET) +#define IMX_PADCTL_RGMII_RD1 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RD1_OFFSET) +#define IMX_PADCTL_RGMII_RD2 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RD2_OFFSET) +#define IMX_PADCTL_RGMII_RD3 (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RD3_OFFSET) +#define IMX_PADCTL_RGMII_RXC (IMX_IOMUXC_VBASE+IMX_PADCTL_RGMII_RXC_OFFSET) +#define IMX_PADCTL_EIM_ADDR25 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR25_OFFSET) +#define IMX_PADCTL_EIM_EB2 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_EB2_OFFSET) +#define IMX_PADCTL_EIM_DATA16 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA16_OFFSET) +#define IMX_PADCTL_EIM_DATA17 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA17_OFFSET) +#define IMX_PADCTL_EIM_DATA18 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA18_OFFSET) +#define IMX_PADCTL_EIM_DATA19 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA19_OFFSET) +#define IMX_PADCTL_EIM_DATA20 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA20_OFFSET) +#define IMX_PADCTL_EIM_DATA21 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA21_OFFSET) +#define IMX_PADCTL_EIM_DATA22 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA22_OFFSET) +#define IMX_PADCTL_EIM_DATA23 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA23_OFFSET) +#define IMX_PADCTL_EIM_EB3 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_EB3_OFFSET) +#define IMX_PADCTL_EIM_DATA24 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA24_OFFSET) +#define IMX_PADCTL_EIM_DATA25 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA25_OFFSET) +#define IMX_PADCTL_EIM_DATA26 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA26_OFFSET) +#define IMX_PADCTL_EIM_DATA27 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA27_OFFSET) +#define IMX_PADCTL_EIM_DATA28 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA28_OFFSET) +#define IMX_PADCTL_EIM_DATA29 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA29_OFFSET) +#define IMX_PADCTL_EIM_DATA30 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA30_OFFSET) +#define IMX_PADCTL_EIM_DATA31 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_DATA31_OFFSET) +#define IMX_PADCTL_EIM_ADDR24 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR24_OFFSET) +#define IMX_PADCTL_EIM_ADDR23 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR23_OFFSET) +#define IMX_PADCTL_EIM_ADDR22 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR22_OFFSET) +#define IMX_PADCTL_EIM_ADDR21 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR21_OFFSET) +#define IMX_PADCTL_EIM_ADDR20 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR20_OFFSET) +#define IMX_PADCTL_EIM_ADDR19 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR19_OFFSET) +#define IMX_PADCTL_EIM_ADDR18 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR18_OFFSET) +#define IMX_PADCTL_EIM_ADDR17 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR17_OFFSET) +#define IMX_PADCTL_EIM_ADDR16 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_ADDR16_OFFSET) +#define IMX_PADCTL_EIM_CS0 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_CS0_OFFSET) +#define IMX_PADCTL_EIM_CS1 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_CS1_OFFSET) +#define IMX_PADCTL_EIM_OE (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_OE_OFFSET) +#define IMX_PADCTL_EIM_RW (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_RW_OFFSET) +#define IMX_PADCTL_EIM_LBA (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_LBA_OFFSET) +#define IMX_PADCTL_EIM_EB0 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_EB0_OFFSET) +#define IMX_PADCTL_EIM_EB1 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_EB1_OFFSET) +#define IMX_PADCTL_EIM_AD00 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD00_OFFSET) +#define IMX_PADCTL_EIM_AD01 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD01_OFFSET) +#define IMX_PADCTL_EIM_AD02 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD02_OFFSET) +#define IMX_PADCTL_EIM_AD03 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD03_OFFSET) +#define IMX_PADCTL_EIM_AD04 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD04_OFFSET) +#define IMX_PADCTL_EIM_AD05 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD05_OFFSET) +#define IMX_PADCTL_EIM_AD06 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD06_OFFSET) +#define IMX_PADCTL_EIM_AD07 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD07_OFFSET) +#define IMX_PADCTL_EIM_AD08 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD08_OFFSET) +#define IMX_PADCTL_EIM_AD09 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD09_OFFSET) +#define IMX_PADCTL_EIM_AD10 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD10_OFFSET) +#define IMX_PADCTL_EIM_AD11 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD11_OFFSET) +#define IMX_PADCTL_EIM_AD12 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD12_OFFSET) +#define IMX_PADCTL_EIM_AD13 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD13_OFFSET) +#define IMX_PADCTL_EIM_AD14 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD14_OFFSET) +#define IMX_PADCTL_EIM_AD15 (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_AD15_OFFSET) +#define IMX_PADCTL_EIM_WAIT (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_WAIT_OFFSET) +#define IMX_PADCTL_EIM_BCLK (IMX_IOMUXC_VBASE+IMX_PADCTL_EIM_BCLK_OFFSET) +#define IMX_PADCTL_DI0_DISP_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_DI0_DISP_CLK_OFFSET) +#define IMX_PADCTL_DI0_PIN15 (IMX_IOMUXC_VBASE+IMX_PADCTL_DI0_PIN15_OFFSET) +#define IMX_PADCTL_DI0_PIN02 (IMX_IOMUXC_VBASE+IMX_PADCTL_DI0_PIN02_OFFSET) +#define IMX_PADCTL_DI0_PIN03 (IMX_IOMUXC_VBASE+IMX_PADCTL_DI0_PIN03_OFFSET) +#define IMX_PADCTL_DI0_PIN04 (IMX_IOMUXC_VBASE+IMX_PADCTL_DI0_PIN04_OFFSET) +#define IMX_PADCTL_DISP0_DATA00 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA00_OFFSET) +#define IMX_PADCTL_DISP0_DATA01 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA01_OFFSET) +#define IMX_PADCTL_DISP0_DATA02 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA02_OFFSET) +#define IMX_PADCTL_DISP0_DATA03 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA03_OFFSET) +#define IMX_PADCTL_DISP0_DATA04 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA04_OFFSET) +#define IMX_PADCTL_DISP0_DATA05 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA05_OFFSET) +#define IMX_PADCTL_DISP0_DATA06 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA06_OFFSET) +#define IMX_PADCTL_DISP0_DATA07 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA07_OFFSET) +#define IMX_PADCTL_DISP0_DATA08 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA08_OFFSET) +#define IMX_PADCTL_DISP0_DATA09 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA09_OFFSET) +#define IMX_PADCTL_DISP0_DATA10 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA10_OFFSET) +#define IMX_PADCTL_DISP0_DATA11 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA11_OFFSET) +#define IMX_PADCTL_DISP0_DATA12 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA12_OFFSET) +#define IMX_PADCTL_DISP0_DATA13 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA13_OFFSET) +#define IMX_PADCTL_DISP0_DATA14 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA14_OFFSET) +#define IMX_PADCTL_DISP0_DATA15 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA15_OFFSET) +#define IMX_PADCTL_DISP0_DATA16 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA16_OFFSET) +#define IMX_PADCTL_DISP0_DATA17 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA17_OFFSET) +#define IMX_PADCTL_DISP0_DATA18 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA18_OFFSET) +#define IMX_PADCTL_DISP0_DATA19 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA19_OFFSET) +#define IMX_PADCTL_DISP0_DATA20 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA20_OFFSET) +#define IMX_PADCTL_DISP0_DATA21 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA21_OFFSET) +#define IMX_PADCTL_DISP0_DATA22 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA22_OFFSET) +#define IMX_PADCTL_DISP0_DATA23 (IMX_IOMUXC_VBASE+IMX_PADCTL_DISP0_DATA23_OFFSET) +#define IMX_PADCTL_ENET_MDIO (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_MDIO_OFFSET) +#define IMX_PADCTL_ENET_REF_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_REF_CLK_OFFSET) +#define IMX_PADCTL_ENET_RX_ER (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_RX_ER_OFFSET) +#define IMX_PADCTL_ENET_CRS_DV (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_CRS_DV_OFFSET) +#define IMX_PADCTL_ENET_RX_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_RX_DATA1_OFFSET) +#define IMX_PADCTL_ENET_RX_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_RX_DATA0_OFFSET) +#define IMX_PADCTL_ENET_TX_EN (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_TX_EN_OFFSET) +#define IMX_PADCTL_ENET_TX_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_TX_DATA1_OFFSET) +#define IMX_PADCTL_ENET_TX_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_TX_DATA0_OFFSET) +#define IMX_PADCTL_ENET_MDC (IMX_IOMUXC_VBASE+IMX_PADCTL_ENET_MDC_OFFSET) +#define IMX_PADCTL_DRAM_SDQS5_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS5_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM5 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM5_OFFSET) +#define IMX_PADCTL_DRAM_DQM4 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM4_OFFSET) +#define IMX_PADCTL_DRAM_SDQS4_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS4_P_OFFSET) +#define IMX_PADCTL_DRAM_SDQS3_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS3_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM3 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM3_OFFSET) +#define IMX_PADCTL_DRAM_SDQS2_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS2_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM2 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM2_OFFSET) +#define IMX_PADCTL_DRAM_ADDR00 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR00_OFFSET) +#define IMX_PADCTL_DRAM_ADDR01 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR01_OFFSET) +#define IMX_PADCTL_DRAM_ADDR02 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR02_OFFSET) +#define IMX_PADCTL_DRAM_ADDR03 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR03_OFFSET) +#define IMX_PADCTL_DRAM_ADDR04 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR04_OFFSET) +#define IMX_PADCTL_DRAM_ADDR05 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR05_OFFSET) +#define IMX_PADCTL_DRAM_ADDR06 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR06_OFFSET) +#define IMX_PADCTL_DRAM_ADDR07 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR07_OFFSET) +#define IMX_PADCTL_DRAM_ADDR08 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR08_OFFSET) +#define IMX_PADCTL_DRAM_ADDR09 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR09_OFFSET) +#define IMX_PADCTL_DRAM_ADDR10 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR10_OFFSET) +#define IMX_PADCTL_DRAM_ADDR11 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR11_OFFSET) +#define IMX_PADCTL_DRAM_ADDR12 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR12_OFFSET) +#define IMX_PADCTL_DRAM_ADDR13 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR13_OFFSET) +#define IMX_PADCTL_DRAM_ADDR14 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR14_OFFSET) +#define IMX_PADCTL_DRAM_ADDR15 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ADDR15_OFFSET) +#define IMX_PADCTL_DRAM_CAS (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_CAS_OFFSET) +#define IMX_PADCTL_DRAM_CS0 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_CS0_OFFSET) +#define IMX_PADCTL_DRAM_CS1 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_CS1_OFFSET) +#define IMX_PADCTL_DRAM_RAS (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_RAS_OFFSET) +#define IMX_PADCTL_DRAM_RESET (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_RESET_OFFSET) +#define IMX_PADCTL_DRAM_SDBA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDBA0_OFFSET) +#define IMX_PADCTL_DRAM_SDBA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDBA1_OFFSET) +#define IMX_PADCTL_DRAM_SDCLK0_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDCLK0_P_OFFSET) +#define IMX_PADCTL_DRAM_SDBA2 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDBA2_OFFSET) +#define IMX_PADCTL_DRAM_SDCKE0 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDCKE0_OFFSET) +#define IMX_PADCTL_DRAM_SDCLK1_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDCLK1_P_OFFSET) +#define IMX_PADCTL_DRAM_SDCKE1 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDCKE1_OFFSET) +#define IMX_PADCTL_DRAM_ODT0 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ODT0_OFFSET) +#define IMX_PADCTL_DRAM_ODT1 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_ODT1_OFFSET) +#define IMX_PADCTL_DRAM_SDWE_B (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDWE_B_OFFSET) +#define IMX_PADCTL_DRAM_SDQS0_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS0_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM0 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM0_OFFSET) +#define IMX_PADCTL_DRAM_SDQS1_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS1_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM1 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM1_OFFSET) +#define IMX_PADCTL_DRAM_SDQS6_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS6_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM6 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM6_OFFSET) +#define IMX_PADCTL_DRAM_SDQS7_P (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_SDQS7_P_OFFSET) +#define IMX_PADCTL_DRAM_DQM7 (IMX_IOMUXC_VBASE+IMX_PADCTL_DRAM_DQM7_OFFSET) +#define IMX_PADCTL_KEY_COL0 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_COL0_OFFSET) +#define IMX_PADCTL_KEY_ROW0 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_ROW0_OFFSET) +#define IMX_PADCTL_KEY_COL1 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_COL1_OFFSET) +#define IMX_PADCTL_KEY_ROW1 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_ROW1_OFFSET) +#define IMX_PADCTL_KEY_COL2 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_COL2_OFFSET) +#define IMX_PADCTL_KEY_ROW2 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_ROW2_OFFSET) +#define IMX_PADCTL_KEY_COL3 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_COL3_OFFSET) +#define IMX_PADCTL_KEY_ROW3 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_ROW3_OFFSET) +#define IMX_PADCTL_KEY_COL4 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_COL4_OFFSET) +#define IMX_PADCTL_KEY_ROW4 (IMX_IOMUXC_VBASE+IMX_PADCTL_KEY_ROW4_OFFSET) +#define IMX_PADCTL_GPIO00 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO00_OFFSET) +#define IMX_PADCTL_GPIO01 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO01_OFFSET) +#define IMX_PADCTL_GPIO09 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO09_OFFSET) +#define IMX_PADCTL_GPIO03 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO03_OFFSET) +#define IMX_PADCTL_GPIO06 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO06_OFFSET) +#define IMX_PADCTL_GPIO02 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO02_OFFSET) +#define IMX_PADCTL_GPIO04 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO04_OFFSET) +#define IMX_PADCTL_GPIO05 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO05_OFFSET) +#define IMX_PADCTL_GPIO07 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO07_OFFSET) +#define IMX_PADCTL_GPIO08 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO08_OFFSET) +#define IMX_PADCTL_GPIO16 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO16_OFFSET) +#define IMX_PADCTL_GPIO17 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO17_OFFSET) +#define IMX_PADCTL_GPIO18 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO18_OFFSET) +#define IMX_PADCTL_GPIO19 (IMX_IOMUXC_VBASE+IMX_PADCTL_GPIO19_OFFSET) +#define IMX_PADCTL_CSI0_PIXCLK (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_PIXCLK_OFFSET) +#define IMX_PADCTL_CSI0_HSYNC (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_HSYNC_OFFSET) +#define IMX_PADCTL_CSI0_DATA_EN (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA_EN_OFFSET) +#define IMX_PADCTL_CSI0_VSYNC (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_VSYNC_OFFSET) +#define IMX_PADCTL_CSI0_DATA04 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA04_OFFSET) +#define IMX_PADCTL_CSI0_DATA05 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA05_OFFSET) +#define IMX_PADCTL_CSI0_DATA06 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA06_OFFSET) +#define IMX_PADCTL_CSI0_DATA07 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA07_OFFSET) +#define IMX_PADCTL_CSI0_DATA08 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA08_OFFSET) +#define IMX_PADCTL_CSI0_DATA09 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA09_OFFSET) +#define IMX_PADCTL_CSI0_DATA10 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA10_OFFSET) +#define IMX_PADCTL_CSI0_DATA11 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA11_OFFSET) +#define IMX_PADCTL_CSI0_DATA12 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA12_OFFSET) +#define IMX_PADCTL_CSI0_DATA13 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA13_OFFSET) +#define IMX_PADCTL_CSI0_DATA14 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA14_OFFSET) +#define IMX_PADCTL_CSI0_DATA15 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA15_OFFSET) +#define IMX_PADCTL_CSI0_DATA16 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA16_OFFSET) +#define IMX_PADCTL_CSI0_DATA17 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA17_OFFSET) +#define IMX_PADCTL_CSI0_DATA18 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA18_OFFSET) +#define IMX_PADCTL_CSI0_DATA19 (IMX_IOMUXC_VBASE+IMX_PADCTL_CSI0_DATA19_OFFSET) +#define IMX_PADCTL_JTAG_TMS (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_TMS_OFFSET) +#define IMX_PADCTL_JTAG_MOD (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_MOD_OFFSET) +#define IMX_PADCTL_JTAG_TRSTB (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_TRSTB_OFFSET) +#define IMX_PADCTL_JTAG_TDI (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_TDI_OFFSET) +#define IMX_PADCTL_JTAG_TCK (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_TCK_OFFSET) +#define IMX_PADCTL_JTAG_TDO (IMX_IOMUXC_VBASE+IMX_PADCTL_JTAG_TDO_OFFSET) +#define IMX_PADCTL_SD3_DATA7 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA7_OFFSET) +#define IMX_PADCTL_SD3_DATA6 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA6_OFFSET) +#define IMX_PADCTL_SD3_DATA5 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA5_OFFSET) +#define IMX_PADCTL_SD3_DATA4 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA4_OFFSET) +#define IMX_PADCTL_SD3_CMD (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_CMD_OFFSET) +#define IMX_PADCTL_SD3_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_CLK_OFFSET) +#define IMX_PADCTL_SD3_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA0_OFFSET) +#define IMX_PADCTL_SD3_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA1_OFFSET) +#define IMX_PADCTL_SD3_DATA2 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA2_OFFSET) +#define IMX_PADCTL_SD3_DATA3 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_DATA3_OFFSET) +#define IMX_PADCTL_SD3_RESET (IMX_IOMUXC_VBASE+IMX_PADCTL_SD3_RESET_OFFSET) +#define IMX_PADCTL_NAND_CLE (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_CLE_OFFSET) +#define IMX_PADCTL_NAND_ALE (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_ALE_OFFSET) +#define IMX_PADCTL_NAND_WP (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_WP_OFFSET) +#define IMX_PADCTL_NAND_READY (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_READY_OFFSET) +#define IMX_PADCTL_NAND_CS0 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_CS0_OFFSET) +#define IMX_PADCTL_NAND_CS1 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_CS1_OFFSET) +#define IMX_PADCTL_NAND_CS2 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_CS2_OFFSET) +#define IMX_PADCTL_NAND_CS3 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_CS3_OFFSET) +#define IMX_PADCTL_SD4_CMD (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_CMD_OFFSET) +#define IMX_PADCTL_SD4_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_CLK_OFFSET) +#define IMX_PADCTL_NAND_DATA00 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA00_OFFSET) +#define IMX_PADCTL_NAND_DATA01 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA01_OFFSET) +#define IMX_PADCTL_NAND_DATA02 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA02_OFFSET) +#define IMX_PADCTL_NAND_DATA03 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA03_OFFSET) +#define IMX_PADCTL_NAND_DATA04 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA04_OFFSET) +#define IMX_PADCTL_NAND_DATA05 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA05_OFFSET) +#define IMX_PADCTL_NAND_DATA06 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA06_OFFSET) +#define IMX_PADCTL_NAND_DATA07 (IMX_IOMUXC_VBASE+IMX_PADCTL_NAND_DATA07_OFFSET) +#define IMX_PADCTL_SD4_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA0_OFFSET) +#define IMX_PADCTL_SD4_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA1_OFFSET) +#define IMX_PADCTL_SD4_DATA2 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA2_OFFSET) +#define IMX_PADCTL_SD4_DATA3 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA3_OFFSET) +#define IMX_PADCTL_SD4_DATA4 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA4_OFFSET) +#define IMX_PADCTL_SD4_DATA5 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA5_OFFSET) +#define IMX_PADCTL_SD4_DATA6 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA6_OFFSET) +#define IMX_PADCTL_SD4_DATA7 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD4_DATA7_OFFSET) +#define IMX_PADCTL_SD1_DATA1 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_DATA1_OFFSET) +#define IMX_PADCTL_SD1_DATA0 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_DATA0_OFFSET) +#define IMX_PADCTL_SD1_DATA3 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_DATA3_OFFSET) +#define IMX_PADCTL_SD1_CMD (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_CMD_OFFSET) +#define IMX_PADCTL_SD1_DATA2 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_DATA2_OFFSET) +#define IMX_PADCTL_SD1_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_SD1_CLK_OFFSET) +#define IMX_PADCTL_SD2_CLK (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_CLK_OFFSET) +#define IMX_PADCTL_SD2_CMD (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_CMD_OFFSET) +#define IMX_PADCTL_SD2_DATA3 (IMX_IOMUXC_VBASE+IMX_PADCTL_SD2_DATA3_OFFSET) + +/* Pad Group Control Registers */ + +#define IMX_PADGROUP_B7DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B7DS_OFFSET) +#define IMX_PADGROUP_ADDDS (IMX_IOMUXC_VBASE+IMX_PADGROUP_ADDDS_OFFSET) +#define IMX_PADGROUP_DDRMODE_CTL (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDRMODE_CTL_OFFSET) +#define IMX_PADGROUP_TERM_CTL0 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL0_OFFSET) +#define IMX_PADGROUP_DDRPKE (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDRPKE_OFFSET) +#define IMX_PADGROUP_TERM_CTL1 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL1_OFFSET) +#define IMX_PADGROUP_TERM_CTL2 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL2_OFFSET) +#define IMX_PADGROUP_TERM_CTL3 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL3_OFFSET) +#define IMX_PADGROUP_DDRPK (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDRPK_OFFSET) +#define IMX_PADGROUP_TERM_CTL4 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL4_OFFSET) +#define IMX_PADGROUP_DDRHYS (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDRHYS_OFFSET) +#define IMX_PADGROUP_DDRMODE (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDRMODE_OFFSET) +#define IMX_PADGROUP_TERM_CTL5 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL5_OFFSET) +#define IMX_PADGROUP_TERM_CTL6 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL6_OFFSET) +#define IMX_PADGROUP_TERM_CTL7 (IMX_IOMUXC_VBASE+IMX_PADGROUP_TERM_CTL7_OFFSET) +#define IMX_PADGROUP_B0DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B0DS_OFFSET) +#define IMX_PADGROUP_B1DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B1DS_OFFSET) +#define IMX_PADGROUP_CTLDS (IMX_IOMUXC_VBASE+IMX_PADGROUP_CTLDS_OFFSET) +#define IMX_PADGROUP_DDR_TYPE_RGMII (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDR_TYPE_RGMII_OFFSET) +#define IMX_PADGROUP_B2DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B2DS_OFFSET) +#define IMX_PADGROUP_DDR_TYPE (IMX_IOMUXC_VBASE+IMX_PADGROUP_DDR_TYPE_OFFSET) +#define IMX_PADGROUP_B3DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B3DS_OFFSET) +#define IMX_PADGROUP_B4DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B4DS_OFFSET) +#define IMX_PADGROUP_B5DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B5DS_OFFSET) +#define IMX_PADGROUP_B6DS (IMX_IOMUXC_VBASE+IMX_PADGROUP_B6DS_OFFSET) +#define IMX_PADGROUP_RGMII_TERM (IMX_IOMUXC_VBASE+IMX_PADGROUP_RGMII_TERM_OFFSET) + +/* Select Input Registers */ + +#define IMX_INPUT_ASRC_ASRCK_CLOCK_6 (IMX_IOMUXC_VBASE+IMX_INPUT_ASRC_ASRCK_CLOCK_6_OFFSET) +#define IMX_INPUT_AUD4_INPUT_DA_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_DA_AMX_OFFSET) +#define IMX_INPUT_AUD4_INPUT_DB_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_DB_AMX_OFFSET) +#define IMX_INPUT_AUD4_INPUT_RXCLK_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_RXCLK_AMX_OFFSET) +#define IMX_INPUT_AUD4_INPUT_RXFS_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_RXFS_AMX_OFFSET) +#define IMX_INPUT_AUD4_INPUT_TXCLK_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_TXCLK_AMX_OFFSET) +#define IMX_INPUT_AUD4_INPUT_TXFS_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD4_INPUT_TXFS_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_DA_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_DA_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_DB_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_DB_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_RXCLK_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_RXCLK_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_RXFS_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_RXFS_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_TXCLK_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_TXCLK_AMX_OFFSET) +#define IMX_INPUT_AUD5_INPUT_TXFS_AMX (IMX_IOMUXC_VBASE+IMX_INPUT_AUD5_INPUT_TXFS_AMX_OFFSET) +#define IMX_INPUT_FLEXCAN1_RX (IMX_IOMUXC_VBASE+IMX_INPUT_FLEXCAN1_RX_OFFSET) +#define IMX_INPUT_FLEXCAN2_RX (IMX_IOMUXC_VBASE+IMX_INPUT_FLEXCAN2_RX_OFFSET) +#define IMX_INPUT_CCM_PMIC_READY (IMX_IOMUXC_VBASE+IMX_INPUT_CCM_PMIC_READY_OFFSET) +#define IMX_INPUT_ECSPI1_CSPI_CLK_IN (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_CSPI_CLK_IN_OFFSET) +#define IMX_INPUT_ECSPI1_MISO (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_MISO_OFFSET) +#define IMX_INPUT_ECSPI1_MOSI (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_MOSI_OFFSET) +#define IMX_INPUT_ECSPI1_SS0 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_SS0_OFFSET) +#define IMX_INPUT_ECSPI1_SS1 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_SS1_OFFSET) +#define IMX_INPUT_ECSPI1_SS2 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_SS2_OFFSET) +#define IMX_INPUT_ECSPI1_SS3 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI1_SS3_OFFSET) +#define IMX_INPUT_ECSPI2_CSPI_CLK_IN (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI2_CSPI_CLK_IN_OFFSET) +#define IMX_INPUT_ECSPI2_MISO (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI2_MISO_OFFSET) +#define IMX_INPUT_ECSPI2_MOSI (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI2_MOSI_OFFSET) +#define IMX_INPUT_ECSPI2_SS0 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI2_SS0_OFFSET) +#define IMX_INPUT_ECSPI2_SS1 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI2_SS1_OFFSET) +#define IMX_INPUT_ECSPI4_SS0 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI4_SS0_OFFSET) +#define IMX_INPUT_ECSPI5_CSPI_CLK_IN (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI5_CSPI_CLK_IN_OFFSET) +#define IMX_INPUT_ECSPI5_MISO (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI5_MISO_OFFSET) +#define IMX_INPUT_ECSPI5_MOSI (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI5_MOSI_OFFSET) +#define IMX_INPUT_ECSPI5_SS0 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI5_SS0_OFFSET) +#define IMX_INPUT_ECSPI5_SS1 (IMX_IOMUXC_VBASE+IMX_INPUT_ECSPI5_SS1_OFFSET) +#define IMX_INPUT_ENET_REF_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_REF_CLK_OFFSET) +#define IMX_INPUT_ENET_MAC0_MDIO (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_MDIO_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_CLK_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_DATA0 (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_DATA0_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_DATA1 (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_DATA1_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_DATA2 (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_DATA2_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_DATA3 (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_DATA3_OFFSET) +#define IMX_INPUT_ENET_MAC0_RX_EN (IMX_IOMUXC_VBASE+IMX_INPUT_ENET_MAC0_RX_EN_OFFSET) +#define IMX_INPUT_ESAI_RX_FS (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_RX_FS_OFFSET) +#define IMX_INPUT_ESAI_TX_FS (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_TX_FS_OFFSET) +#define IMX_INPUT_ESAI_RX_HF_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_RX_HF_CLK_OFFSET) +#define IMX_INPUT_ESAI_TX_HF_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_TX_HF_CLK_OFFSET) +#define IMX_INPUT_ESAI_RX_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_RX_CLK_OFFSET) +#define IMX_INPUT_ESAI_TX_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_TX_CLK_OFFSET) +#define IMX_INPUT_ESAI_SDO0 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO0_OFFSET) +#define IMX_INPUT_ESAI_SDO1 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO1_OFFSET) +#define IMX_INPUT_ESAI_SDO2_SDI3 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO2_SDI3_OFFSET) +#define IMX_INPUT_ESAI_SDO3_SDI2 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO3_SDI2_OFFSET) +#define IMX_INPUT_ESAI_SDO4_SDI1 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO4_SDI1_OFFSET) +#define IMX_INPUT_ESAI_SDO5_SDI0 (IMX_IOMUXC_VBASE+IMX_INPUT_ESAI_SDO5_SDI0_OFFSET) +#define IMX_INPUT_HDMI_ICECIN (IMX_IOMUXC_VBASE+IMX_INPUT_HDMI_ICECIN_OFFSET) +#define IMX_INPUT_HDMI_II2C_CLKIN (IMX_IOMUXC_VBASE+IMX_INPUT_HDMI_II2C_CLKIN_OFFSET) +#define IMX_INPUT_HDMI_II2C_DATAIN (IMX_IOMUXC_VBASE+IMX_INPUT_HDMI_II2C_DATAIN_OFFSET) +#define IMX_INPUT_I2C1_SCL_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C1_SCL_IN_OFFSET) +#define IMX_INPUT_I2C1_SDA_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C1_SDA_IN_OFFSET) +#define IMX_INPUT_I2C2_SCL_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C2_SCL_IN_OFFSET) +#define IMX_INPUT_I2C2_SDA_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C2_SDA_IN_OFFSET) +#define IMX_INPUT_I2C3_SCL_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C3_SCL_IN_OFFSET) +#define IMX_INPUT_I2C3_SDA_IN (IMX_IOMUXC_VBASE+IMX_INPUT_I2C3_SDA_IN_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA10 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA10_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA11 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA11_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA12 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA12_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA13 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA13_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA14 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA14_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA15 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA15_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA16 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA16_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA17 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA17_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA18 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA18_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA19 (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA19_OFFSET) +#define IMX_INPUT_IPU2_SENS1_DATA_EN (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_DATA_EN_OFFSET) +#define IMX_INPUT_IPU2_SENS1_HSYNC (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_HSYNC_OFFSET) +#define IMX_INPUT_IPU2_SENS1_PIX_CLK (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_PIX_CLK_OFFSET) +#define IMX_INPUT_IPU2_SENS1_VSYNC (IMX_IOMUXC_VBASE+IMX_INPUT_IPU2_SENS1_VSYNC_OFFSET) +#define IMX_INPUT_KEY_COL5 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_COL5_OFFSET) +#define IMX_INPUT_KEY_COL6 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_COL6_OFFSET) +#define IMX_INPUT_KEY_COL7 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_COL7_OFFSET) +#define IMX_INPUT_KEY_ROW5 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_ROW5_OFFSET) +#define IMX_INPUT_KEY_ROW6 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_ROW6_OFFSET) +#define IMX_INPUT_KEY_ROW7 (IMX_IOMUXC_VBASE+IMX_INPUT_KEY_ROW7_OFFSET) +#define IMX_INPUT_MLB_MLB_CLK_IN (IMX_IOMUXC_VBASE+IMX_INPUT_MLB_MLB_CLK_IN_OFFSET) +#define IMX_INPUT_MLB_MLB_DATA_IN (IMX_IOMUXC_VBASE+IMX_INPUT_MLB_MLB_DATA_IN_OFFSET) +#define IMX_INPUT_MLB_MLB_SIG_IN (IMX_IOMUXC_VBASE+IMX_INPUT_MLB_MLB_SIG_IN_OFFSET) +#define IMX_INPUT_SDMA_EVENTS14 (IMX_IOMUXC_VBASE+IMX_INPUT_SDMA_EVENTS14_OFFSET) +#define IMX_INPUT_SDMA_EVENTS47 (IMX_IOMUXC_VBASE+IMX_INPUT_SDMA_EVENTS47_OFFSET) +#define IMX_INPUT_SPDIF_SPDIF_IN1 (IMX_IOMUXC_VBASE+IMX_INPUT_SPDIF_SPDIF_IN1_OFFSET) +#define IMX_INPUT_SPDIF_TX_CLK2 (IMX_IOMUXC_VBASE+IMX_INPUT_SPDIF_TX_CLK2_OFFSET) +#define IMX_INPUT_UART1_UART_RTS_B (IMX_IOMUXC_VBASE+IMX_INPUT_UART1_UART_RTS_B_OFFSET) +#define IMX_INPUT_UART1_UART_RX_DATA (IMX_IOMUXC_VBASE+IMX_INPUT_UART1_UART_RX_DATA_OFFSET) +#define IMX_INPUT_UART2_UART_RTS_B (IMX_IOMUXC_VBASE+IMX_INPUT_UART2_UART_RTS_B_OFFSET) +#define IMX_INPUT_UART2_UART_RX_DATA (IMX_IOMUXC_VBASE+IMX_INPUT_UART2_UART_RX_DATA_OFFSET) +#define IMX_INPUT_UART3_UART_RTS_B (IMX_IOMUXC_VBASE+IMX_INPUT_UART3_UART_RTS_B_OFFSET) +#define IMX_INPUT_UART3_UART_RX_DATA (IMX_IOMUXC_VBASE+IMX_INPUT_UART3_UART_RX_DATA_OFFSET) +#define IMX_INPUT_UART4_UART_RTS_B (IMX_IOMUXC_VBASE+IMX_INPUT_UART4_UART_RTS_B_OFFSET) +#define IMX_INPUT_UART4_UART_RX_DATA (IMX_IOMUXC_VBASE+IMX_INPUT_UART4_UART_RX_DATA_OFFSET) +#define IMX_INPUT_UART5_UART_RTS_B (IMX_IOMUXC_VBASE+IMX_INPUT_UART5_UART_RTS_B_OFFSET) +#define IMX_INPUT_UART5_UART_RX_DATA (IMX_IOMUXC_VBASE+IMX_INPUT_UART5_UART_RX_DATA_OFFSET) +#define IMX_INPUT_USB_OTG_OC (IMX_IOMUXC_VBASE+IMX_INPUT_USB_OTG_OC_OFFSET) +#define IMX_INPUT_USB_H1_OC (IMX_IOMUXC_VBASE+IMX_INPUT_USB_H1_OC_OFFSET) +#define IMX_INPUT_USDHC1_WP_ON (IMX_IOMUXC_VBASE+IMX_INPUT_USDHC1_WP_ON_OFFSET) + +/* IOMUXC Register Bit Definitions **************************************************/ + +/* General Purpose Register 0 (GPR0) */ + +#define GPR0_DMAREQ_MUX_SEL0 (1 << 0) +#define GPR0_DMAREQ_MUX_SEL1 (1 << 1) +#define GPR0_DMAREQ_MUX_SEL2 (1 << 2) +#define GPR0_DMAREQ_MUX_SEL3 (1 << 3) +#define GPR0_DMAREQ_MUX_SEL4 (1 << 4) +#define GPR0_DMAREQ_MUX_SEL5 (1 << 5) +#define GPR0_DMAREQ_MUX_SEL6 (1 << 6) +#define GPR0_DMAREQ_MUX_SEL7 (1 << 7) +#define GPR0_AUDIO_VIDEO_MUXING_SHIFT (8) +#define GPR0_AUDIO_VIDEO_MUXING_MASK (0x3f << GPR0_TX_CLK2_MUX_SEL_SHIFT) +#define GPR0_TX_CLK2_MUX_SEL_SHIFT (14) +#define GPR0_TX_CLK2_MUX_SEL_MASK (3 << GPR0_TX_CLK2_MUX_SEL_SHIFT) +# define GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK1 (0 << GPR0_TX_CLK2_MUX_SEL_SHIFT) +# define GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK2 (1 << GPR0_TX_CLK2_MUX_SEL_SHIFT) +# define GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK3 (2 << GPR0_TX_CLK2_MUX_SEL_SHIFT) +#define GPR0_CLOCK_1_MUX_SEL_SHIFT (16) +#define GPR0_CLOCK_1_MUX_SEL_MASK (3 << GPR0_CLOCK_1_MUX_SEL_SHIFT) +# define GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1_MUXED (0 << GPR0_CLOCK_1_MUX_SEL_SHIFT) +# define GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1 (1 << GPR0_CLOCK_1_MUX_SEL_SHIFT) +# define GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_SRCK (2 << GPR0_CLOCK_1_MUX_SEL_SHIFT) +# define GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_RX_BIT_CLK (3 << GPR0_CLOCK_1_MUX_SEL_SHIFT) +#define GPR0_CLOCK_9_MUX_SEL_SHIFT (3 << 18) +#define GPR0_CLOCK_9_MUX_SEL_MASK (3 << GPR0_CLOCK_9_MUX_SEL_SHIFT) +# define GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1_MUXED (0 << GPR0_CLOCK_9_MUX_SEL_SHIFT) +# define GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1 (1 << GPR0_CLOCK_9_MUX_SEL_SHIFT) +# define GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_STCK (2 << GPR0_CLOCK_9_MUX_SEL_SHIFT) +# define GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_TX_BIT_CLK (3 << GPR0_CLOCK_9_MUX_SEL_SHIFT) +#define GPR0_CLOCK_2_MUX_SEL_SHIFT (20) +#define GPR0_CLOCK_2_MUX_SEL_MASK (3 << GPR0_CLOCK_2_MUX_SEL_SHIFT) +# define GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2_MUXED (0 << GPR0_CLOCK_2_MUX_SEL_SHIFT) +# define GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2 (1 << GPR0_CLOCK_2_MUX_SEL_SHIFT) +# define GPR0_CLOCK_2_MUX_SEL_SSI2_SSI_SRCK (2 << GPR0_CLOCK_2_MUX_SEL_SHIFT) +# define GPR0_CLOCK_2_MUX_SEL_SSI2_RX_BIT_CLK (3 << GPR0_CLOCK_2_MUX_SEL_SHIFT) +#define GPR0_CLOCK_A_MUX_SEL_SHIFT (22) +#define GPR0_CLOCK_A_MUX_SEL_MASK (3 << GPR0_CLOCK_A_MUX_SEL_SHIFT) +# define GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2_MUXED (0 << GPR0_CLOCK_A_MUX_SEL_SHIFT) +# define GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2 (1 << GPR0_CLOCK_A_MUX_SEL_SHIFT) +# define GPR0_CLOCK_A_MUX_SEL_SSI2_SSI_STCK (2 << GPR0_CLOCK_A_MUX_SEL_SHIFT) +# define GPR0_CLOCK_A_MUX_SEL_SSI2_TX_BIT_CLK (3 << GPR0_CLOCK_A_MUX_SEL_SHIFT) +#define GPR0_CLOCK_3_MUX_SEL_SHIFT (24) +#define GPR0_CLOCK_3_MUX_SEL_MASK (3 << GPR0_CLOCK_3_MUX_SEL_SHIFT) +# define GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7_MUXED (3 << GPR0_CLOCK_3_MUX_SEL_SHIFT) +# define GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7 (3 << GPR0_CLOCK_3_MUX_SEL_SHIFT) +# define GPR0_CLOCK_3_MUX_SEL_SSI3_SSI_SRCK (3 << GPR0_CLOCK_3_MUX_SEL_SHIFT) +# define GPR0_CLOCK_3_MUX_SEL_SSI3_RX_BIT_CLK (3 << GPR0_CLOCK_3_MUX_SEL_SHIFT) +#define GPR0_CLOCK_B_MUX_SEL_SHIFT (26) +#define GPR0_CLOCK_B_MUX_SEL_MASK (3 << GPR0_CLOCK_B_MUX_SEL_SHIFT) +# define GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7_MUXED (0 << GPR0_CLOCK_B_MUX_SEL_SHIFT) +# define GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7 (1 << GPR0_CLOCK_B_MUX_SEL_SHIFT) +# define GPR0_CLOCK_B_MUX_SEL_SSI3_SSI_STCK (2 << GPR0_CLOCK_B_MUX_SEL_SHIFT) +# define GPR0_CLOCK_B_MUX_SEL_SSI3_TX_BIT_CLK (3 << GPR0_CLOCK_B_MUX_SEL_SHIFT) +#define GPR0_CLOCK_0_MUX_SEL_SHIFT (28) +#define GPR0_CLOCK_0_MUX_SEL_MASK (3 << GPR0_CLOCK_0_MUX_SEL_SHIFT) +# define GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR_MUXED (0 << GPR0_CLOCK_0_MUX_SEL_SHIFT) +# define GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR (1 << GPR0_CLOCK_0_MUX_SEL_SHIFT) +# define GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_DO_SCKR (2 << GPR0_CLOCK_0_MUX_SEL_SHIFT) +#define GPR0_CLOCK_8_MUX_SEL_SHIFT (30) +#define GPR0_CLOCK_8_MUX_SEL_MASK (3 << GPR0_CLOCK_8_MUX_SEL_SHIFT) +# define GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7_MUXED (0 << GPR0_CLOCK_8_MUX_SEL_SHIFT) +# define GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7 (1 << GPR0_CLOCK_8_MUX_SEL_SHIFT) +# define GPR0_CLOCK_8_MUX_SEL_SSI3_SSI_SRCK (2 << GPR0_CLOCK_8_MUX_SEL_SHIFT) +# define GPR0_CLOCK_8_MUX_SEL_SSI3_RX_BIT_CLK (3 << GPR0_CLOCK_8_MUX_SEL_SHIFT) +#define GPR1_REF_SSP_EN (1 << 16) + +/* General Purpose Register 1 (GPR1) */ + +#define GPR1_ACT_CS0 (1 << 0) +#define GPR1_ADDRS0_SHIFT (1) +#define GPR1_ADDRS0_MASK (3 << GPR1_ADDRS0_SHIFT) +# define GPR1_ADDRS0(n) ((uint32_t)(n) << GPR1_ADDRS0_SHIFT) +#define GPR1_ACT_CS1 (1 << 3) +#define GPR1_ADDRS1_SHIFT (4) +#define GPR1_ADDRS1_MASK (3 << GPR1_ADDRS1_SHIFT) +# define GPR1_ADDRS1(n) ((uint32_t)(n) << GPR1_ADDRS1_SHIFT) +#define GPR1_ACT_CS2 (1 << 6) +#define GPR1_ADDRS2_SHFIT (7) +#define GPR1_ADDRS2_MASK (3 << GPR1_ADDRS2_SHFIT) +# define GPR1_ADDRS2(n) ((uint32_t)(n) << GPR1_ADDRS2_SHFIT) +#define GPR1_ACT_CS3 (1 << 9) +#define GPR1_ADDRS3_SHIFT (10) +#define GPR1_ADDRS3_MASK (3 << GPR1_ADDRS3_SHIFT) +# define GPR1_ADDRS3_32MB (0 << GPR1_ADDRS3_SHIFT) +# define GPR1_ADDRS3_64MB (1 << GPR1_ADDRS3_SHIFT) +# define GPR1_ADDRS3_128MB (2 << GPR1_ADDRS3_SHIFT) +#define GPR1_GINT (1 << 12) +#define GPR1_USB_OTG_ID_SEL (1 << 13) +#define GPR1_SYS_INT (1 << 14) +#define GPR1_USB_EXP_MODE (1 << 15) +#define GPR1_IPU_VPU_MUX (1 << 17) +#define GPR1_TEST_POWERDOWN (1 << 18) +#define GPR1_MIPI_IPU1_MUX (1 << 19) +#define GPR1_MIPI_IPU2_MUX (1 << 20) +#define GPR1_ENET_CLK_SEL (1 << 21) +#define GPR1_EXC_MON (1 << 22) +#define GPR1_MIPI_DPI_OFF (1 << 24) +#define GPR1_MIPI_COLOR_SW (1 << 25) +#define GPR1_APP_REQ_ENTR_L1 (1 << 26) +#define GPR1_APP_READY_ENTR_L23 (1 << 27) +#define GPR1_APP_REQ_EXIT_L1 (1 << 28) +#define GPR1_APP_CLK_REQ_N (1 << 30) +#define GPR1_CFG_L1_CLK_REMOVAL_EN (1 << 31) + +/* General Purpose Register 2 (GPR2) */ + +#define GPR2_CH0_MODE_SHIFT (0) +#define GPR2_CH0_MODE_MASK (3 << GPR2_CH0_MODE_SHIFT) +# define GPR2_CH0_MODE_DISABLED (0 << GPR2_CH0_MODE_SHIFT) +# define GPR2_CH0_MODE_ROUTED_DI0 (1 << GPR2_CH0_MODE_SHIFT) +# define GPR2_CH0_MODE_ROUTED_DI1 (3 << GPR2_CH0_MODE_SHIFT) +#define GPR2_CH1_MODE_SHIFT (2) +#define GPR2_CH1_MODE_MASK (3 << GPR2_CH1_MODE_SHIFT) +# define GPR2_CH1_MODE_DISABLED (0 << GPR2_CH1_MODE_SHIFT) +# define GPR2_CH1_MODE_ROUTED_DI0 (1 << GPR2_CH1_MODE_SHIFT) +# define GPR2_CH1_MODE_ROUTED_DI1 (3 << GPR2_CH1_MODE_SHIFT) +#define GPR2_SPLIT_MODE_EN (1 << 4) +#define GPR2_DATA_WIDTH_CH0 (1 << 5) +#define GPR2_BIT_MAPPING_CH0 (1 << 6) +#define GPR2_DATA_WIDTH_CH1 (1 << 7) +#define GPR2_BIT_MAPPING_CH1 (1 << 8) +#define GPR2_DI0_VS_POLARITY (1 << 9) +#define GPR2_DI1_VS_POLARITY (1 << 10) +#define GPR2_LVDS_CLK_SHIFT_SHIFT (16) +#define GPR2_LVDS_CLK_SHIFT_MASK (7 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT0 (0 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT1 (1 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT2 (2 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT3 (3 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT4 (4 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT5 (5 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT6 (6 << GPR2_LVDS_CLK_SHIFT_SHIFT) +# define GPR2_LVDS_CLK_SHIFT7 (7 << GPR2_LVDS_CLK_SHIFT_SHIFT) +#define GPR2_COUNTER_RESET_VAL_SHIFT (20) +#define GPR2_COUNTER_RESET_VAL_MASK (3 << GPR2_COUNTER_RESET_VAL_SHIFT) +# define GPR2_COUNTER_RESET_VAL5 (0 << GPR2_COUNTER_RESET_VAL_SHIFT) +# define GPR2_COUNTER_RESET_VAL3 (1 << GPR2_COUNTER_RESET_VAL_SHIFT) +# define GPR2_COUNTER_RESET_VAL4 (2 << GPR2_COUNTER_RESET_VAL_SHIFT) +# define GPR2_COUNTER_RESET_VAL6 (3 << GPR2_COUNTER_RESET_VAL_SHIFT) + +/* General Purpose Register 3 (GPR3) */ + +#define GPR3_HDMI_MUX_CTL_SHIFT (2) +#define GPR3_HDMI_MUX_CTL_MASK (3 << GPR3_HDMI_MUX_CTL_SHIFT) +# define GPR3_HDMI_MUX_CTL_IPU1_DI0 (0 << GPR3_HDMI_MUX_CTL_SHIFT) +# define GPR3_HDMI_MUX_CTL_IPU1_DI1 (1 << GPR3_HDMI_MUX_CTL_SHIFT) +# define GPR3_HDMI_MUX_CTL_IPU2_DI0 (2 << GPR3_HDMI_MUX_CTL_SHIFT) +# define GPR3_HDMI_MUX_CTL_IPU2_DI1 (3 << GPR3_HDMI_MUX_CTL_SHIFT) +#define GPR3_MIPI_MUX_CTL_SHIFT (4) +#define GPR3_MIPI_MUX_CTL_MASK (3 << GPR3_MIPI_MUX_CTL_SHIFT) +# define GPR3_MIPI_MUX_CTL_IPU1_DI0 (0 << GPR3_MIPI_MUX_CTL_SHIFT) +# define GPR3_MIPI_MUX_CTL_IPU1_DI1 (1 << GPR3_MIPI_MUX_CTL_SHIFT) +# define GPR3_MIPI_MUX_CTL_IPU2_DI0 (2 << GPR3_MIPI_MUX_CTL_SHIFT) +# define GPR3_MIPI_MUX_CTL_IPU2_DI1 (3 << GPR3_MIPI_MUX_CTL_SHIFT) +#define GPR3_LVDS0_MUX_CTL_SHIFT (6) +#define GPR3_LVDS0_MUX_CTL_MASK (3 << GPR3_LVDS0_MUX_CTL_SHIFT) +# define GPR3_LVDS0_MUX_CTL_IPU1_DI0 (0 << GPR3_LVDS0_MUX_CTL_SHIFT) +# define GPR3_LVDS0_MUX_CTL_IPU1_DI1 (1 << GPR3_LVDS0_MUX_CTL_SHIFT) +# define GPR3_LVDS0_MUX_CTL_IPU2_DI0 (2 << GPR3_LVDS0_MUX_CTL_SHIFT) +# define GPR3_LVDS0_MUX_CTL_IPU2_DI1 (3 << GPR3_LVDS0_MUX_CTL_SHIFT) +#define GPR3_LVDS1_MUX_CTL_SHIFT (8) +#define GPR3_LVDS1_MUX_CTL_MASK (3 << GPR3_LVDS1_MUX_CTL_SHIFT) +# define GPR3_LVDS1_MUX_CTL_IPU1_DI0 (0 << GPR3_LVDS1_MUX_CTL_SHIFT) +# define GPR3_LVDS1_MUX_CTL_IPU1_DI1 (1 << GPR3_LVDS1_MUX_CTL_SHIFT) +# define GPR3_LVDS1_MUX_CTL_IPU2_DI0 (2 << GPR3_LVDS1_MUX_CTL_SHIFT) +# define GPR3_LVDS1_MUX_CTL_IPU2_DI1 (3 << GPR3_LVDS1_MUX_CTL_SHIFT) +#define GPR3_IPU_DIAG (1 << 10) +#define GPR3_TZASC1_BOOT_LOCK (1 << 11) +#define GPR3_TZASC2_BOOT_LOCK (1 << 12) +#define GPR3_CORE0_DBG_ACK_EN (1 << 13) +#define GPR3_CORE1_DBG_ACK_EN (1 << 14) +#define GPR3_CORE2_DBG_ACK_EN (1 << 15) +#define GPR3_CORE3_DBG_ACK_EN (1 << 16) +#define GPR3_OCRAM_STATUS_SHIFT (17) +#define GPR3_OCRAM_STATUS_MASK (15 << GPR3_OCRAM_STATUS_SHIFT) +# define GPR3_OCRAM_STATUS(n) ((uint32_t)(n) << GPR3_OCRAM_STATUS_SHIFT) +#define GPR3_OCRAM_CTL_SHIFT (21) +#define GPR3_OCRAM_CTL_MASK (15 << GPR3_OCRAM_CTL_SHIFT) +# define GPR3_OCRAM_CTL(n) ((uint32_t)(n) << GPR3_OCRAM_CTL_SHIFT) +#define GPR3_USDHCX_WR_CACHE_CTL (1 << 26) +#define GPR3_USDHCX_RD_CACHE_CTL (1 << 25) +#define GPR3_BCH_RD_CACHE_CTL (1 << 27) +#define GPR3_BCH_WR_CACHE_CTL (1 << 28) +#define GPR3_GPU_DBG_SHIFT (29) +#define GPR3_GPU_DBG_MASK (3 << GPR3_GPU_DBG_SHIFT) +# define GPR3_GPU_DBG_GPU3D (0 << GPR3_GPU_DBG_SHIFT) +# define GPR3_GPU_DBG_GPU2D (1 << GPR3_GPU_DBG_SHIFT) +# define GPR3_GPU_DBG_OPENVG (2 << GPR3_GPU_DBG_SHIFT) + +/* General Purpose Register 4 (GPR4) */ + +#define GPR4_IPU_RD_CACHE_CTL (1 << 0) +#define GPR4_IPU_WR_CACHE_CTL (1 << 1) +#define GPR4_VPU_P_RD_CACHE_VAL (1 << 2) +#define GPR4_VPU_P_WR_CACHE_VAL (1 << 3) +#define GPR4_VPU_RD_CACHE_SEL (1 << 6) +#define GPR4_VPU_WR_CACHE_SEL (1 << 7) +#define GPR4_SOC_VERSION_SHIFT (8) +#define GPR4_SOC_VERSION_MASK (0xff << GPR4_SOC_VERSION_SHIFT) +#define GPR4_ENET_STOP_ACK (1 << 16) +#define GPR4_CAN1_STOP_ACK (1 << 17) +#define GPR4_CAN2_STOP_ACK (1 << 18) +#define GPR4_SDMA_STOP_ACK (1 << 19) +#define GPR4_PCIE_RD_CACHE_VAL (1 << 24) +#define GPR4_PCIE_WR_CACHE_VAL (1 << 25) +#define GPR4_PCIE_RD_CACHE_SEL (1 << 26) +#define GPR4_PCIE_WR_CACHE_SEL (1 << 27) +#define GPR4_VDOA_RD_CACHE_VAL (1 << 28) +#define GPR4_VDOA_WR_CACHE_VAL (1 << 29) +#define GPR4_VDOA_RD_CACHE_SEL (1 << 30) +#define GPR4_VDOA_WR_CACHE_SEL (1 << 31) + +/* General Purpose Register 5 (GPR5) */ + +#define GPR5_ARM_WFI_SHIFT (0) +#define GPR5_ARM_WFI_MASK (15 << GPR5_ARM_WFI_SHIFT) +#define GPR5_ARM_WFE_SHIFT (4) +#define GPR5_ARM_WFE_MASK (15 << GPR5_ARM_WFE_SHIFT) +#define GPR5_L2_CLK_STOP (1 << 8) + +/* General Purpose Register 6 (GPR6) */ + +#define GPR6_IPU1_ID00_WR_QOS_SHIFT (0) +#define GPR6_IPU1_ID00_WR_QOS_MASK (15 << GPR6_IPU1_ID00_WR_QOS_SHIFT) +# define GPR6_IPU1_ID00_WR_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID00_WR_QOS_SHIFT) +#define GPR6_IPU1_ID01_WR_QOS_SHIFT (4) +#define GPR6_IPU1_ID01_WR_QOS_MASK (15 << GPR6_IPU1_ID01_WR_QOS_SHIFT) +# define GPR6_IPU1_ID01_WR_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID01_WR_QOS_SHIFT) +#define GPR6_IPU1_ID10_WR_QOS_SHIFT (8) +#define GPR6_IPU1_ID10_WR_QOS_MASK (15 << GPR6_IPU1_ID10_WR_QOS_SHIFT) +# define GPR6_IPU1_ID10_WR_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID10_WR_QOS_SHIFT) +#define GPR6_IPU1_ID11_WR_QOS_SHIFT (12) +#define GPR6_IPU1_ID11_WR_QOS_MASK (15 << GPR6_IPU1_ID11_WR_QOS_SHIFT) +# define GPR6_IPU1_ID11_WR_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID11_WR_QOS_SHIFT) +#define GPR6_IPU1_ID00_RD_QOS_SHIFT (16) +#define GPR6_IPU1_ID00_RD_QOS_MASK (15 << GPR6_IPU1_ID00_RD_QOS_SHIFT) +# define GPR6_IPU1_ID00_RD_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID00_RD_QOS_SHIFT) +#define GPR6_IPU1_ID01_RD_QOS_SHIFT (20) +#define GPR6_IPU1_ID01_RD_QOS_MASK (15 << GPR6_IPU1_ID01_RD_QOS_SHIFT) +# define GPR6_IPU1_ID01_RD_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID01_RD_QOS_SHIFT) +#define GPR6_IPU1_ID10_RD_QOS_SHIFT (24) +#define GPR6_IPU1_ID10_RD_QOS_MASK (15 << GPR6_IPU1_ID10_RD_QOS_SHIFT) +# define GPR6_IPU1_ID10_RD_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID10_RD_QOS_SHIFT) +#define GPR6_IPU1_ID11_RD_QOS_SHIFT (28) +#define GPR6_IPU1_ID11_RD_QOS_MASK (15 << GPR6_IPU1_ID11_RD_QOS_SHIFT) +# define GPR6_IPU1_ID11_RD_QOS(n) ((uint32_t)(n) << GPR6_IPU1_ID11_RD_QOS_SHIFT) + +/* General Purpose Register 7 (GPR7) */ + +#define GPR7_IPU2_ID00_WR_QOS_SHIFT (0) +#define GPR7_IPU2_ID00_WR_QOS_MASK (15 << GPR7_IPU2_ID00_WR_QOS_SHIFT) +# define GPR7_IPU2_ID00_WR_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID00_WR_QOS_SHIFT) +#define GPR7_IPU2_ID01_WR_QOS_SHIFT (4) +#define GPR7_IPU2_ID01_WR_QOS_MASK (15 << GPR7_IPU2_ID01_WR_QOS_SHIFT) +# define GPR7_IPU2_ID01_WR_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID01_WR_QOS_SHIFT) +#define GPR7_IPU2_ID10_WR_QOS_SHIFT (8) +#define GPR7_IPU2_ID10_WR_QOS_MASK (15 << GPR7_IPU2_ID10_WR_QOS_SHIFT) +# define GPR7_IPU2_ID10_WR_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID10_WR_QOS_SHIFT) +#define GPR7_IPU2_ID11_WR_QOS_SHIFT (12) +#define GPR7_IPU2_ID11_WR_QOS_MASK (15 << GPR7_IPU2_ID11_WR_QOS_SHIFT) +# define GPR7_IPU2_ID11_WR_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID11_WR_QOS_SHIFT) +#define GPR7_IPU2_ID00_RD_QOS_SHIFT (16) +#define GPR7_IPU2_ID00_RD_QOS_MASK (15 << GPR7_IPU2_ID00_RD_QOS_SHIFT) +# define GPR7_IPU2_ID00_RD_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID00_RD_QOS_SHIFT) +#define GPR7_IPU2_ID01_RD_QOS_SHIFT (20) +#define GPR7_IPU2_ID01_RD_QOS_MASK (15 << GPR7_IPU2_ID01_RD_QOS_SHIFT) +# define GPR7_IPU2_ID01_RD_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID01_RD_QOS_SHIFT) +#define GPR7_IPU2_ID10_RD_QOS_SHIFT (24) +#define GPR7_IPU2_ID10_RD_QOS_MASK (15 << GPR7_IPU2_ID10_RD_QOS_SHIFT) +# define GPR7_IPU2_ID10_RD_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID10_RD_QOS_SHIFT) +#define GPR7_IPU2_ID11_RD_QOS_SHIFT (28) +#define GPR7_IPU2_ID11_RD_QOS_MASK (15 << GPR7_IPU2_ID11_RD_QOS_SHIFT) +# define GPR7_IPU2_ID11_RD_QOS(n) ((uint32_t)(n) << GPR7_IPU2_ID11_RD_QOS_SHIFT) + +/* General Purpose Register 8 (GPR8) */ + +#define GPR8_PCS_TX_DEEMPH_GEN1_SHIFT (0) +#define GPR8_PCS_TX_DEEMPH_GEN1_MASK (0x3f << GPR8_PCS_TX_DEEMPH_GEN1_SHIFT) +# define GPR8_PCS_TX_DEEMPH_GEN1(n) ((uint32_t)(n) << GPR8_PCS_TX_DEEMPH_GEN1_SHIFT) +#define GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_SHIFT (6) +#define GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_MASK (0x3f << GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_SHIFT) +# define GPR8_PCS_TX_DEEMPH_GEN2_3P5DB(n) ((uint32_t)(n) << GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_SHIFT) +#define GPR8_PCS_TX_DEEMPH_GEN2_6DB_SHIFT (12) +#define GPR8_PCS_TX_DEEMPH_GEN2_6DB_MASK (0x3f << GPR8_PCS_TX_DEEMPH_GEN2_6DB_SHIFT) +# define GPR8_PCS_TX_DEEMPH_GEN2_6DB(n) ((uint32_t)(n) << GPR8_PCS_TX_DEEMPH_GEN2_6DB_SHIFT) +#define GPR8_PCS_TX_SWING_FULL_SHIFT (18) +#define GPR8_PCS_TX_SWING_FULL_MASK (0x7f << GPR8_PCS_TX_SWING_FULL_SHIFT) +# define GPR8_PCS_TX_SWING_FULL(n) ((uint32_t)(n) << GPR8_PCS_TX_SWING_FULL_SHIFT) +#define GPR8_PCS_TX_SWING_LOW_SHIFT (25) +#define GPR8_PCS_TX_SWING_LOW_MASK (0x7f << GPR8_PCS_TX_SWING_LOW_SHIFT) +# define GPR8_PCS_TX_SWING_LOW(n) ((uint32_t)(n) << GPR8_PCS_TX_SWING_LOW_SHIFT) + +/* General Purpose Register 9 (GPR9) */ + +#define GPR9_TZASC1_BYP (1 << 0) +#define GPR9_TZASC2_BYP (1 << 1) + +/* General Purpose Register 10 (GPR10) */ + +#define GPR10_DCIC1_MUX_CTL_SHIFT (0) +#define GPR10_DCIC1_MUX_CTL_MASK (3 << GPR10_DCIC1_MUX_CTL_SHIFT) +# define GPR10_DCIC1_MUX_CTL_IPU1_DI0 (0 << GPR10_DCIC1_MUX_CTL_SHIFT) +# define GPR10_DCIC1_MUX_CTL_IPU1_DI1 (1 << GPR10_DCIC1_MUX_CTL_SHIFT) +# define GPR10_DCIC1_MUX_CTL_IPU2_DI0 (2 << GPR10_DCIC1_MUX_CTL_SHIFT) +# define GPR10_DCIC1_MUX_CTL_IPU2_DI1 (3 << GPR10_DCIC1_MUX_CTL_SHIFT) +#define GPR10_DCIC2_MUX_CTL_SHIFT (2) +#define GPR10_DCIC2_MUX_CTL_MASK (3 << GPR10_DCIC2_MUX_CTL_SHIFT) +# define GPR10_DCIC2_MUX_CTL_IPU1_DI0 (0 << GPR10_DCIC2_MUX_CTL_SHIFT) +# define GPR10_DCIC2_MUX_CTL_IPU1_DI1 (1 << GPR10_DCIC2_MUX_CTL_SHIFT) +# define GPR10_DCIC2_MUX_CTL_IPU2_DI0 (2 << GPR10_DCIC2_MUX_CTL_SHIFT) +# define GPR10_DCIC2_MUX_CTL_IPU2_DI1 (3 << GPR10_DCIC2_MUX_CTL_SHIFT) +#define GPR10_OCRAM_TZ_EN (1 << 4) +#define GPR10_OCRAM_TZ_ADDR_SHIFT (5) +#define GPR10_OCRAM_TZ_ADDR_MASK (0x3f << GPR10_OCRAM_TZ_ADDR_SHIFT) +# define GPR10_OCRAM_TZ_ADDR(n) ((uint32_t)(n) << GPR10_OCRAM_TZ_ADDR_SHIFT) +#define GPR10_SEC_ERR_RESP (1 << 11) +#define GPR10_DBG_CLK_EN (1 << 12) +#define GPR10_DBG_EN (1 << 13) +#define GPR10_LOCK_DCIC1_MUX_SHIFT (16) +#define GPR10_LOCK_DCIC1_MUX_MASK (3 << GPR10_LOCK_DCIC1_MUX_SHIFT) +# define GPR10_LOCK_DCIC1_MUX_IPU1 (0 << GPR10_LOCK_DCIC1_MUX_SHIFT) /* DCIC-1 source is IPU1 or IPU2 DI0 port */ +# define GPR10_LOCK_DCIC1_MUX_LVDS0 (1 << GPR10_LOCK_DCIC1_MUX_SHIFT) /* DCIC-1 source is LVDS0 */ +# define GPR10_LOCK_DCIC1_MUX_LVDS1 (2 << GPR10_LOCK_DCIC1_MUX_SHIFT) /* DCIC-1 source is LVDS1 */ +# define GPR10_LOCK_DCIC1_MUX_MIPI (3 << GPR10_LOCK_DCIC1_MUX_SHIFT) /* DCIC-1 source is MIPI DPI */ +#define GPR10_LOCK_DCIC2_MUX_SHIFT (18) +#define GPR10_LOCK_DCIC2_MUX_MASK (3 << GPR10_LOCK_DCIC2_MUX_SHIFT) +# define GPR10_LOCK_DCIC2_MUX_IPU1 (0 << GPR10_LOCK_DCIC2_MUX_SHIFT) /* DCIC-2 source is IPU1 DI1 port */ +# define GPR10_LOCK_DCIC2_MUX_LVDS0 (1 << GPR10_LOCK_DCIC2_MUX_SHIFT) /* DCIC-2 source is LVDS0 */ +# define GPR10_LOCK_DCIC2_MUX_LVDS1 (2 << GPR10_LOCK_DCIC2_MUX_SHIFT) /* DCIC-2 source is LVDS1 */ +# define GPR10_LOCK_DCIC2_MUX_MIPI (3 << GPR10_LOCK_DCIC2_MUX_SHIFT) /* DCIC-2 source is MIPI DPI */ +#define GPR10_LOCK_OCRAM_TZ_EN (1 << 20) +#define GPR10_LOCK_OCRAM_TZ_ADDR_SHIFT (21) +#define GPR10_LOCK_OCRAM_TZ_ADDR_MASK (0x3f << GPR10_LOCK_OCRAM_TZ_ADDR_SHIFT) +# define GPR10_LOCK_OCRAM_TZ_ADDR(n) ((uint32_t)(n) << GPR10_LOCK_OCRAM_TZ_ADDR_SHIFT) +#define GPR10_LOCK_SEC_ERR_RESP (1 << 27) +#define GPR10_LOCK_DBG_CLK_EN (1 << 28) +#define GPR10_LOCK_DBG_EN (1 << 29) + +/* General Purpose Register 11 (GPR11) -- Contains no fields of interest. */ +/* General Purpose Register 12 (GPR12) */ + +#define GPR12_USDHC_DBG_MUX_SHIFT (2) +#define GPR12_USDHC_DBG_MUX_MASK (3 << GPR12_USDHC_DBG_MUX_SHIFT) +# define GPR12_USDHC_DBG_MUX_USDHC1 (0 << GPR12_USDHC_DBG_MUX_SHIFT) /* uSDHC1 debug */ +# define GPR12_USDHC_DBG_MUX_USDHC2 (1 << GPR12_USDHC_DBG_MUX_SHIFT) /* uSDHC2 debug */ +# define GPR12_USDHC_DBG_MUX_USDHC3 (2 << GPR12_USDHC_DBG_MUX_SHIFT) /* uSDHC3 debug */ +# define GPR12_USDHC_DBG_MUX_USDHC4 (3 << GPR12_USDHC_DBG_MUX_SHIFT) /* uSDHC4 debug */ +#define GPR12_LOS_LEVEL_SHIFT (4) +#define GPR12_LOS_LEVEL_MASK (0x1f << GPR12_LOS_LEVEL_SHIFT) +# define GPR12_LOS_LEVEL(n) ((uint32_t)(n) << GPR12_LOS_LEVEL_SHIFT) +#define GPR12_APPS_PM_XMT_PME (1 << 9) +#define GPR12_APP_LTSSM_ENABLE (1 << 10) +#define GPR12_APP_INIT_RST (1 << 11) +#define GPR12_DEVICE_TYPE_SHIFT (12) +#define GPR12_DEVICE_TYPE_MASK (15 << GPR12_DEVICE_SHIFT) +# define GPR12_DEVICE_TYPE_PCIE_EP (0 << GPR12_DEVICE_SHIFT) /* EP mode */ +# define GPR12_DEVICE_TYPE_PCIE_RC (2 << GPR12_DEVICE_SHIFT) /* RC mode */ +#define GPR12_APPS_PM_XMT_TURNOFF (1 << 16) +#define GPR12_DIA_STATUS_BUS_SELECT_SHIFT (17) +#define GPR12_DIA_STATUS_BUS_SELECT_MASK (15 << GPR12_DIA_STATUS_BUS_SELECT_SHIFT) +# define GPR12_DIA_STATUS_BUS_SELECT(n) ((uint32_t)(n) << GPR12_DIA_STATUS_BUS_SELECT_SHIFT) +#define GPR12_PCIE_CTL_7_SHIFT (21) +#define GPR12_PCIE_CTL_7_MASK (7 << GPR12_PCIE_CTL_7_SHIFT) + #define GPR12_PCIE_CTL_7(n) ((uint32_t)(n) << GPR12_PCIE_CTL_7_SHIFT) +#define GPR12_ARMP_APB_CLK_EN (1 << 24) +#define GPR12_ARMP_ATB_CLK_EN (1 << 25) +#define GPR12_ARMP_AHB_CLK_EN (1 << 26) +#define GPR12_ARMP_IPG_CLK_EN (1 << 27) + +/* General Purpose Register 13 (GPR13) */ + +#define GPR13_SATA_PHY_0 (1 << 0) +#define GPR13_SATA_PHY_1 (1 << 1) +#define GPR13_SATA_PHY_2_SHIFT (2) +#define GPR13_SATA_PHY_2_MASK (0x1f << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p937_V (0x00 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p947_V (0x01 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p957_V (0x02 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p966_V (0x03 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p976_V (0x04 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p986_V (0x05 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_0p996_V (0x06 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p005_V (0x07 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p015_V (0x08 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p025_V (0x09 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p035_V (0x0a << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p045_V (0x0b << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p054_V (0x0c << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p064_V (0x0d << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p074_V (0x0e << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p084_V (0x0f << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p094_V (0x10 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p104_V (0x11 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p113_V (0x12 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p123_V (0x13 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p133_V (0x14 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p143_V (0x15 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p152_V (0x16 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p162_V (0x17 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p172_V (0x18 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p182_V (0x19 << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p191_V (0x1a << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p201_V (0x1b << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p211_V (0x1c << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p221_V (0x1d << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p230_V (0x1e << GPR13_SATA_PHY_2_SHIFT) +# define GPR13_SATA_PHY_2_1p240_V (0x1f << GPR13_SATA_PHY_2_SHIFT) +#define GPR13_SATA_PHY_3_SHIFT (7) +#define GPR13_SATA_PHY_3_MASK (15 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_0p00_DB (0 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_0p37_DB (1 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_0p74_DB (2 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_1p11_DB (3 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_1p48_DB (4 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_1p85_DB (5 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_2p22_DB (6 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_2p59_DB (7 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_2p96_DB (8 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_3p33_DB (9 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_3p70_DB (10 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_4p07_DB (11 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_4p44_DB (12 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_4p81_DB (13 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_5p28_DB (14 << GPR13_SATA_PHY_3_SHIFT) +# define GPR13_SATA_PHY_3_5p75_DB (15 << GPR13_SATA_PHY_3_SHIFT) +#define GPR13SATA_PHY_4_SHIFT (11) +#define GPR13SATA_PHY_4_MASK (7 << GPR13SATA_PHY_4_SHIFT) +# define GPR13SATA_PHY_4_16_16 (0 << GPR13SATA_PHY_4_SHIFT) /* 16/16 */ +# define GPR13SATA_PHY_4_14_16 (1 << GPR13SATA_PHY_4_SHIFT) /* 14/16 */ +# define GPR13SATA_PHY_4_12_16 (2 << GPR13SATA_PHY_4_SHIFT) /* 12/16 */ +# define GPR13SATA_PHY_4_10_16 (3 << GPR13SATA_PHY_4_SHIFT) /* 10/16 */ +# define GPR13SATA_PHY_4_9_16 (4 << GPR13SATA_PHY_4_SHIFT) /* 9/16 (default) */ +# define GPR13SATA_PHY_4_8_16 (5 << GPR13SATA_PHY_4_SHIFT) /* 8/16 */ +#define GPR13_SATA_PHY_5 (1 << 14) +# define GPR13_SATA_PHY_5_SSEN (1 << 14) +#define GPR13_SATA_SPEED (1 << 15) +#define GPR13_SSATA_PHY_6_SHIFT (16) +#define GPR13_SSATA_PHY_6_MASK (7 << GPR13_SSATA_PHY_6_SHIFT) +# define GPR13_SSATA_PHY_6_1P_1F (0 << GPR13_SSATA_PHY_6_SHIFT) +# define GPR13_SSATA_PHY_6_2P_2F (1 << GPR13_SSATA_PHY_6_SHIFT) +# define GPR13_SSATA_PHY_6_1P_4F (2 << GPR13_SSATA_PHY_6_SHIFT) +# define GPR13_SSATA_PHY_6_2P_4F (3 << GPR13_SSATA_PHY_6_SHIFT) +#define GPR13_SATA_PHY_7_SHIFT (19) +#define GPR13_SATA_PHY_7_MASK (0x1f << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA1I (0x10 << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA1M (0x10 << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA1X (0x1a << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA2I (0x12 << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA2M (0x12 << GPR13_SATA_PHY_7_SHIFT) +# define GPR13_SATA_PHY_7_SATA2X (0x1a << GPR13_SATA_PHY_7_SHIFT) +#define GPR13_SATA_PHY_8_SHIFT (24) +#define GPR13_SATA_PHY_8_MASK (7 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_0p5_DB (0 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_1p0_DB (1 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_1p5_DB (2 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_2p0_DB (3 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_2p5_DB (4 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_3p0_DB (5 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_3p5_DB (6 << GPR13_SATA_PHY_8_SHIFT) +# define GPR13_SATA_PHY_8_4p0_DB (7 << GPR13_SATA_PHY_8_SHIFT) +#define GPR13_ENET_STOP_REQ (1 << 27) +#define GPR13_CAN1_STOP_REQ (1 << 28) +#define GPR13_CAN2_STOP_REQ (1 << 29) +#define GPR13_SDMA_STOP_REQ (1 << 30) + +/* Pad Mux Registers */ + +#define PADMUX_MUXMODE_SHIFT (0) /* Bit 0-2: Software Input On Field */ +#define PADMUX_MUXMODE_MASK (7 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT0 (0 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT1 (1 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT2 (2 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT3 (3 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT4 (4 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT5 (5 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT6 (6 << PADMUX_MUXMODE_SHIFT) +# define PADMUX_MUXMODE_ALT7 (7 << PADMUX_MUXMODE_SHIFT) +#define PADMUX_SION (1 << 4) /* Bit 4: Software Input On Field */ + +/* Pad Control Registers */ + +#define DRIVE_HIZ (0) /* HI-Z */ +#define DRIVE_260OHM (1) /* 150 Ohm @3.3V, 260 Ohm @1.8V */ +#define DRIVE_130OHM (2) /* 75 Ohm @3.3V, 130 Ohm @1.8V */ +#define DRIVE_90OHM (3) /* 50 Ohm @3.3V, 90 Ohm @1.8V */ +#define DRIVE_60OHM (4) /* 37 Ohm @3.3V, 60 Ohm @1.8V */ +#define DRIVE_50OHM (5) /* 30 Ohm @3.3V, 50 Ohm @1.8V */ +#define DRIVE_40OHM (6) /* 25 Ohm @3.3V, 40 Ohm @1.8V */ +#define DRIVE_33OHM (7) /* 20 Ohm @3.3V, 33 Ohm @1.8V */ + +#define SPEED_LOW (0) /* Low frequency (50 MHz) */ +#define SPEED_MEDIUM (2) /* Medium frequency (100, 150 MHz) */ +#define SPEED_MAX (3) /* Maximum frequency (100, 150, 200 MHz) */ + +#define PULL_DOWN_100K (0) /* 100K Ohm Pull Down */ +#define PULL_UP_47K (1) /* 47K Ohm Pull Up */ +#define PULL_UP_100K (2) /* 100K Ohm Pull Up */ +#define PULL_UP_22K (3) /* 22K Ohm Pull Up */ + +#define PADCTL_SRE (1 << 0) /* Bit 0: Slew Rate Field */ +#define PADCTL_DSE_SHIFT (3) /* Bits 3-5: Drive Strength Field */ +#define PADCTL_DSE_MASK (7 << PADCTL_DSE_SHIFT) +# define PADCTL_DSE(n) ((uint32_t)(n) << PADCTL_DSE_SHIFT) /* n=DRIVE_* */ +# define PADCTL_DSE_HIZ (0 << PADCTL_DSE_SHIFT) /* HI-Z */ +# define PADCTL_DSE_260OHM (1 << PADCTL_DSE_SHIFT) /* 150 Ohm @3.3V, 260 Ohm @1.8V */ +# define PADCTL_DSE_130OHM (2 << PADCTL_DSE_SHIFT) /* 75 Ohm @3.3V, 130 Ohm @1.8V */ +# define PADCTL_DSE_90OHM (3 << PADCTL_DSE_SHIFT) /* 50 Ohm @3.3V, 90 Ohm @1.8V */ +# define PADCTL_DSE_60OHM (4 << PADCTL_DSE_SHIFT) /* 37 Ohm @3.3V, 60 Ohm @1.8V */ +# define PADCTL_DSE_50OHM (5 << PADCTL_DSE_SHIFT) /* 30 Ohm @3.3V, 50 Ohm @1.8V */ +# define PADCTL_DSE_40OHM (6 << PADCTL_DSE_SHIFT) /* 25 Ohm @3.3V, 40 Ohm @1.8V */ +# define PADCTL_DSE_33OHM (7 << PADCTL_DSE_SHIFT) /* 20 Ohm @3.3V, 33 Ohm @1.8V */ +#define PADCTL_SPEED_SHIFT (6) /* Bits 6-7: Speed Field */ +#define PADCTL_SPEED_MASK (3 << PADCTL_SPEED_SHIFT) +# define PADCTL_SPEED(n) ((uint32_t)(n) << PADCTL_SPEED_SHIFT) /* n=SPEED_* */ +# define PADCTL_SPEED_LOW (0 << PADCTL_SPEED_SHIFT) /* Low frequency (50 MHz) */ +# define PADCTL_SPEED_MEDIUM (1 << PADCTL_SPEED_SHIFT) /* Medium frequency (100, 150 MHz) */ +# define PADCTL_SPEED_MAX (3 << PADCTL_SPEED_SHIFT) /* Maximum frequency (100, 150, 200 MHz) */ +#define PADCTL_ODE (1 << 11) /* Bit 11: Open Drain Enable Field */ +#define PADCTL_PKE (1 << 12) /* Bit 12: Pull / Keep Enable Field */ +#define PADCTL_PUE (1 << 13) /* Bit 13: Pull / Keep Select Field */ +#define PADCTL_PUS_SHIFT (14) /* Bits 14-15: Pull Up / Down Config. Field */ +#define PADCTL_PUS_MASK (3 << PADCTL_PUS_SHIFT) +# define PADCTL_PUS(n) ((uint32_t)(n) << PADCTL_PUS_SHIFT) /* n=PULL_* */ +# define PADCTL_PUS_DOWN_100K (0 << PADCTL_PUS_SHIFT) /* 100K Ohm Pull Down */ +# define PADCTL_PUS_UP_47K (1 << PADCTL_PUS_SHIFT) /* 47K Ohm Pull Up */ +# define PADCTL_PUS_UP_100K (2 << PADCTL_PUS_SHIFT) /* 100K Ohm Pull Up */ +# define PADCTL_PUS_UP_22K (3 << PADCTL_PUS_SHIFT) /* 22K Ohm Pull Up */ +#define PADCTL_HYS (1 << 16) /* Bit 16: Hysteresis Enable Field */ + +/* Pad Group Control Registers */ +/* Select Input Registers */ + +#endif /* CONFIG_ARCH_CHIP_IMX6_6QUAD || CONFIG_ARCH_CHIP_IMX6_6DUAL */ +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_IOMUXC_H */ diff --git a/arch/arm/src/imx6/chip/imx_memorymap.h b/arch/arm/src/imx6/chip/imx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..c91fb924e093e1095bb85200a4c28fbbf03404f5 --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_memorymap.h @@ -0,0 +1,1004 @@ +/************************************************************************************ + * arch/arm/src/imx6/chip/imx_memorymap.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_MEMORYMAP_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + +/* Overview ***************************************************************** + * + * i.MX6 Physical (unmapped) Memory Map + * - i.MX6 System 1MB PSECTIONS + * - i.MX6 DMA PSECTION Offsets + * - i.MX6 OCRAM PSECTION Offsets + * - i.MX6 ARM MP PSECTION Offsets + * - i.MX6 PCIE PSECTION Offsets + * - i.MX6 AIPS-1 PSECTION Offsets + * - i.MX6 AIPS-2 PSECTION Offsets + * - i.MX6 DAP AIPS-2 PSECTION Offsets + * - i.MX6 SATA PSECTION Offsets + * - i.MX6 DMA Physical Base Addresses + * - i.MX6 OCRAM Physical Base Addresses + * - i.MX6 ARM MP Physical Base Addresses + * - i.MX6 PCIE Physical Base Addresses + * - i.MX6 AIPS-1 Physical Base Addresses + * - i.MX6 AIPS-2 Physical Base Addresses + * - i.MX6 DAP AIPS-2 Physical Base Addresses + * - i.MX6 SATA Physical Base Addresses + * Sizes of memory regions in bytes + * Sizes of memory regions in sections + * Section MMU Flags + * i.MX6 Virtual (mapped) Memory Map + * - i.MX6 DMA Virtual Base Addresses + * - i.MX6 OCRAM Virtual Base Addresses + * - i.MX6 ARM MP Virtual Base Addresses + * - i.MX6 PCIE Virtual Base Addresses + * - i.MX6 AIPS-1 Virtual Base Addresses + * - i.MX6 AIPS-2 Virtual Base Addresses + * - i.MX6 DAP AIPS-2 Virtual Base Addresses + * - i.MX6 SATA Virtual Base Addresses + * - NuttX vitual base address + * MMU Page Table Location + * Page table start addresses + * Base address of the interrupt vector table + * + ****************************************************************************/ + +/* i.MX6 Physical (unmapped) Memory Map *************************************/ +/* i.MX6 System PSECTIONS */ + +#define IMX_ROMCP_PSECTION 0x00000000 /* 00000000-00017fff 96 KB Boot ROM (ROMCP) */ + /* 00018000-000fffff 928 KB Reserved */ +#define IMX_DMA_PSECTION 0x00100000 /* 00100000-001fffff 1 MB See offsets below */ +#define IMX_GPV2_PSECTION 0x00200000 /* 00200000-002fffff 1 MB GPV_2 PL301 (per1) configuration port */ +#define IMX_GPV3_PSECTION 0x00300000 /* 00300000-003fffff 1 MB GPV_3 PL301 (per2) configuration port */ + /* 00400000-007fffff 4 MB Reserved */ +#define IMX_GPV4_PSECTION 0x00800000 /* 00800000-008fffff 1 MB GPV_4 PL301 (fast3) configuration port */ +#define IMX_OCRAM_PSECTION 0x00900000 /* 00900000-009fffff 1 MB OCRAM */ +#define IMX_ARMMP_PSECTION 0x00a00000 /* 00a00000-00afffff 8 KB ARM MP */ +#define IMX_GPV0PL301_PSECTION 0x00b00000 /* 00b00000-00bfffff 1 MB GPV0 PL301 (fast2) configuration port */ +#define IMX_GPV1PL301_PSECTION 0x00c00000 /* 00c00000-00cfffff 1 MB GPV1 PL301 (fast1) configuration port */ + /* 00d00000-00ffffff 3072 KB Reserved */ +#define IMX_PCIE_PSECTION 0x01000000 /* 01000000-01ffffff 16 MB PCIe */ +#define IMX_AIPS1_PSECTION 0x02000000 /* 02000000-020fffff 1 MB Peripheral IPs via AIPS-1 */ +#define IMX_AIPS2_PSECTION 0x02100000 /* 02100000-021fffff 1 MB Peripheral IPs via AIPS-2 */ +#define IMX_SATA_PSECTION 0x02200000 /* 02200000-0220bfff 48 KB SATA */ + /* 0220c000-023fffff 2 MB Reserved */ +#define IMX_IPU1_PSECTION 0x02600000 /* 02600000-029fffff 4 MB IPU-1 */ +#define IMX_IPU2_PSECTION 0x02a00000 /* 02a00000-02dfffff 4 MB IPU-2 */ +#define IMX_EIM_PSECTION 0x08000000 /* 08000000-0fffffff 128 MB EIM - (NOR/SRAM) */ +#define IMX_MMDCDDR_PSECTION 0x10000000 /* 10000000-ffffffff 3840 MB MMDC-DDR Controller */ + /* 10000000-7fffffff 1792 MB */ + +/* i.MX6 DMA PSECTION Offsets */ + +#define IMX_CAAMRAM_OFFSET 0x00000000 /* 00000000-00003fff 16 KB CAAM (16K secure RAM) */ + /* 00004000-0000ffff 48 KB Reserved */ +#define IMX_APBHDMA_OFFSET 0x00010000 /* 00010000-00011fff 8 KB APBH-Bridge-DMA */ +#define IMX_GPMI_OFFSET 0x00012000 /* 00012000-00013fff 8 KB GPMI */ +#define IMX_BCH_OFFSET 0x00014000 /* 00014000-00017fff 16 KB BCH */ + /* 00018000-0001ffff 32 KB Reserved */ +#define IMX_HDMI_OFFSET 0x00020000 /* 00020000-00028fff 36 KB HDMI */ + /* 00029000-0002ffff 28 KB Reserved */ +#define IMX_GPU3D_OFFSET 0x00030000 /* 00030000-00033fff 16 KB GPU 3D */ +#define IMX_GPU2D_OFFSET 0x00034000 /* 00034000-00037fff 16 KB GPU 2D (GC320) */ +#define IMX_DTCP_OFFSET 0x00038000 /* 00038000-0003bfff 16 KB DTCP */ + /* 0003c000-000fffff 784 KB Reserved */ +/* i.MX6 OCRAM PSECTION Offsets */ + +#define IMX_OCRAM_OFFSET 0x00000000 /* 00000000-0003ffff 0.25 MB OCRAM 256 KB */ +#define IMX_OCRAMALIAS_OFFSET 0x00040000 /* 00040000-000fffff 0.75 MB OCRAM aliased */ + +/* i.MX6 ARM MP PSECTION Offsets */ + +#define IMX_MPSCU_OFFSET 0x00000000 /* 00000000-000000fc 0.25 KB SCU registers */ +#define IMX_MPICC_OFFSET 0x00000100 /* 00000100-000001ff 0.25 KB Interrupt controller interfaces */ +#define IMX_MPGTM_OFFSET 0x00000200 /* 00000200-000002ff 0.25 KB Global timer */ + /* 00000300-000005ff Reserved */ +#define IMX_MPPTM_OFFSET 0x00000600 /* 00000600-000006ff 0.25 KB Private timers and watchdogs */ + /* 00000700-00000fff Reserved */ +#define IMX_MPICD_OFFSET 0x00001000 /* 00001000-00001fff 4 KB Interrupt distributor */ +#define IMX_PL310_OFFSET 0x00002000 /* 00002000-00002fff 4 KB PL310 (L2 Cache controller) */ + /* 00003000-000fffff 1012 KB Reserved */ + +/* i.MX6 PCIE PSECTION Offsets */ + +#define IMX_PCIE_OFFSET 0x00000000 /* 00000000-00ffbfff 16368 KB PCIe */ +#define IMX_PCIEREGS_OFFSET 0x00ffc000 /* 00ffc000-00ffffff 16 KB PCIe registers */ + +/* i.MX6 AIPS-1 PSECTION Offsets */ + + /* 00000000 00003fff Reserved for SDMA internal registers 16 KB */ +#define IMX_SPDIF_OFFSET 0x00004000 /* 00004000 00007fff SPDIF 16 KB */ +#define IMX_ECSPI1_OFFSET 0x00008000 /* 00008000 0000bfff eCSPI1 16 KB */ +#define IMX_ECSPI2_OFFSET 0x0000c000 /* 0000c000 0000ffff eCSPI2 16KB */ +#define IMX_ECSPI3_OFFSET 0x00010000 /* 00010000 00013fff eCSPI3 16 KB */ +#define IMX_ECSPI4_OFFSET 0x00014000 /* 00014000 00017fff eCSPI4 16 KB */ +#define IMX_ECSPI5_OFFSET 0x00018000 /* 00018000 0001bfff eCSPI5 16 KB */ + /* 0001c000 0001ffff Reserved for SDMA internal registers 16 KB */ +#define IMX_UART1_OFFSET 0x00020000 /* 00020000 00023fff UART1 16 KB */ +#define IMX_ESAI_OFFSET 0x00024000 /* 00024000 00027fff ESAI 16 KB */ +#define IMX_SSI1_OFFSET 0x00028000 /* 00028000 0002bfff SSI1 16 KB */ +#define IMX_SSI2_OFFSET 0x0002c000 /* 0002c000 0002ffff SSI2 16 KB */ +#define IMX_SSI3_OFFSET 0x00030000 /* 00030000 00033fff SSI3 16 KB */ +#define IMX_ASRC_OFFSET 0x00034000 /* 00034000 00037fff ASRC 16 KB */ + /* 00038000 0003bfff Reserved for SDMA internal registers 16 KB */ +#define IMX_SPBA_OFFSET 0x0003c000 /* 0003c000 0003ffff SPBA 16 KB */ +#define IMX_VPU_OFFSET 0x00040000 /* 00040000 0007bfff AIPS-1 VPU 240 KB */ +#define IMX_APIS1CFG_OFFSET 0x0007c000 /* 0007c000 0007ffff AIPS-1 Configuration 16 KB */ +#define IMX_PWM1_OFFSET 0x00080000 /* 00080000 00083fff PWM1 16 KB */ +#define IMX_PWM2_OFFSET 0x00084000 /* 00084000 00087fff PWM2 16 KB */ +#define IMX_PWM3_OFFSET 0x00088000 /* 00088000 0008bfff PWM2 16 KB */ +#define IMX_PWM4_OFFSET 0x0008c000 /* 0008c000 0008ffff PWM4 16 KB */ +#define IMX_CAN1_OFFSET 0x00090000 /* 00090000 00093fff CAN1 16 KB */ +#define IMX_CAN2_OFFSET 0x00094000 /* 00094000 00097fff CAN2 16 KB */ +#define IMX_GPT_OFFSET 0x00098000 /* 00098000 0009bfff GPT 16 KB */ +#define IMX_GPIO_OFFSET(n) (0x0009c000 + ((n) << 14)) /* n=0..6 */ +#define IMX_GPIO1_OFFSET 0x0009c000 /* 0009c000 0009ffff GPIO1 16 KB */ +#define IMX_GPIO2_OFFSET 0x000a0000 /* 000a0000 000a3fff GPIO2 16 KB */ +#define IMX_GPIO3_OFFSET 0x000a4000 /* 000a4000 000a7fff GPIO3 16 KB */ +#define IMX_GPIO4_OFFSET 0x000a8000 /* 000a8000 000abfff GPIO4 16 KB */ +#define IMX_GPIO5_OFFSET 0x000ac000 /* 000ac000 000affff GPIO5 16 KB */ +#define IMX_GPIO6_OFFSET 0x000b0000 /* 000b0000 000b3fff GPIO6 16 KB */ +#define IMX_GPIO7_OFFSET 0x000b4000 /* 000b4000 000b7fff GPIO7 16 KB */ +#define IMX_KPP_OFFSET 0x000b8000 /* 000b8000 000bbfff KPP 16 KB */ +#define IMX_WDOG1_OFFSET 0x000bc000 /* 000bc000 000bffff WDOG1 16 KB */ +#define IMX_WDOG2_OFFSET 0x000c0000 /* 000c0000 000c3fff WDOG2 16 KB */ +#define IMX_CCM_OFFSET 0x000c4000 /* 000c4000 000c7fff CCM 16 KB */ +#define IMX_ANALOG_OFFSET 0x000c8000 /* 000c8000 000c8fff ANALOG 4 KB */ +#define IMX_USBPHY1_OFFSET 0x000c9000 /* 000c9000 000c9fff USBPHY1 4 KB */ +#define IMX_USBPHY2_OFFSET 0x000ca000 /* 000ca000 000cafff USBPHY2 4 KB */ + /* 000cb000 000cbfff Reserved 4 KB */ +#define IMX_SNVSHP_OFFSET 0x000cc000 /* 000cc000 000cffff SNVSHP 16 KB */ +#define IMX_EPIT1_OFFSET 0x000d0000 /* 000d0000 000d3fff EPIT1 16 KB */ +#define IMX_EPIT2_OFFSET 0x000d4000 /* 000d4000 000d7fff EPIT2 16 KB */ +#define IMX_SRC_OFFSET 0x000d8000 /* 000d8000 000dbfff SRC 16 KB */ +#define IMX_GPC_OFFSET 0x000dc000 /* 000dc000 000dd25f GPC 608 B */ +#define IMX_PGCPU_OFFSET 0x000dc260 /* 000dc260 000dd27f PGCPU 32 B */ + /* 000dc280 000dd29f Reserved 32 B */ +#define IMX_PGCARM_OFFSET 0x000dc2a0 /* 000dc2a0 000dd2bf PGCARM 32 B */ + /* 000dc2C0 000dffff Reserved 15680 B */ +#define IMX_IOMUXC_OFFSET 0x000e0000 /* 000e0000 000e3fff IOMUXC 16 KB */ +#define IMX_DCIC1_OFFSET 0x000e4000 /* 000e4000 000e7fff DCIC1 16 KB */ +#define IMX_DCIC2_OFFSET 0x000e8000 /* 000e8000 000ebfff DCIC2 16 KB */ +#define IMX_SDMA_OFFSET 0x000ec000 /* 000ec000 000effff SDMA 16 KB */ + /* 000f0000 000f3fff Reserved 16 KB */ + /* 000f4000 000f7fff Reserved 16 KB */ + /* 000f8000 000fbfff Reserved 16 KB */ + /* 000fc000 000fffff AIPS-1 Reserved 16 KB */ +/* i.MX6 AIPS-2 PSECTION Offsets */ + +#define IMX_CAAM_OFFSET 0x00100000 /* 00100000 0210ffff CAAM 64 KB */ + /* 00110000 0213ffff Reserved 192 KB */ +#define IMX_DAP_OFFSET 0x00140000 /* 00140000 00160fff ARM Cortex A9 MPCore / DAP 132 KB (See below) */ + /* 00161000 0017bfff ARM Cortex A9 MPCore - Reserved 108 KB */ +#define IMX_AIPS2CGF_OFFSET 0x0017c000 /* 0017c000 0017ffff AIPS-2 configuration 16 KB */ + /* 00180000 00183fff Reserved 16 KB */ +#define IMX_USBOH3_OFFSET 0x00184000 /* 00184000 00187fff USBOH3 (USB) 16 KB */ +#define IMX_ENET_OFFSET 0x00188000 /* 00188000 0018bfff ENET 16 KB */ +#define IMX_MLB150_OFFSET 0x0018c000 /* 0018c000 0018ffff MLB150 16 KB */ +#define IMX_USDHC1_OFFSET 0x00190000 /* 00190000 00193fff uSDHC1 16 KB */ +#define IMX_USDHC2_OFFSET 0x00194000 /* 00194000 00197fff uSDHC2 16 KB */ +#define IMX_USDHC3_OFFSET 0x00198000 /* 00198000 0019bfff uSDHC3 16 KB */ +#define IMX_USDHC4_OFFSET 0x0019c000 /* 0019c000 0019ffff uSDHC4 16 KB */ +#define IMX_I2C1_OFFSET 0x001a0000 /* 001a0000 001a3fff I2C1 16 KB */ +#define IMX_I2C2_OFFSET 0x001a4000 /* 001a4000 001a7fff I2C2 16 KB */ +#define IMX_I2C3_OFFSET 0x001a8000 /* 001a8000 001abfff I2C3 16 KB */ +#define IMX_ROMCP_OFFSET 0x001ac000 /* 001ac000 001affff ROMCP 16 KB */ +#define IMX_MMDC_OFFSET 0x001b0000 /* 001b0000 001b3fff MMDC 16 KB */ +#define IMX_MMDCP1_OFFSET 0x001b4000 /* 001b4000 001b7fff MMDC (port 1) 16 KB */ +#define IMX_EIM_OFFSET 0x001b8000 /* 001b8000 001bbfff EIM 16 KB */ +#define IMX_OCOTPCTRL_OFFSET 0x001bc000 /* 001bc000 001bffff OCOTPCTRL 16 KB */ +#define IMX_CSU_OFFSET 0x001c0000 /* 001c0000 001c3fff CSU 16 KB */ + /* 001c4000 001c7fff Reserved */ + /* 001c8000 Reserved */ + /* 001cc000 Reserved */ +#define IMX_TZASC1_OFFSET 0x001d0000 /* 001d0000 001d3fff TZASC1 16 KB */ +#define IMX_TZASC2_OFFSET 0x001d4000 /* 001d4000 001d7fff TZASC2 16 KB */ +#define IMX_AUDMUX_OFFSET 0x001d8000 /* 001d8000 001dbfff AUDMUX 16 KB */ +#define IMX_MIPICSI_OFFSET 0x001dc000 /* 001dc000 001dffff MIPI (CSI port) 16 KB */ +#define IMX_MIPIDSI_OFFSET 0x001e0000 /* 001e0000 001e3fff MIPI (DSI port) 16 KB */ +#define IMX_VDOA_OFFSET 0x001e4000 /* 001e4000 001e7fff VDOA 16 KB */ +#define IMX_UART2_OFFSET 0x001e8000 /* 001e8000 001ebfff UART2 16 KB */ +#define IMX_UART3_OFFSET 0x001ec000 /* 001ec000 001effff UART3 16 KB */ +#define IMX_UART4_OFFSET 0x001f0000 /* 001f0000 001f3fff UART4 16 KB */ +#define IMX_UART5_OFFSET 0x001f4000 /* 001f4000 001f7fff UART5 16 KB */ + /* 001f8000 001fbfff Reserved 16 KB */ + +/* i.MX6 DAP AIPS-2 PSECTION Offsets */ + +#define IMX_DAPROM_OFFSET 0x00140000 /* 00140000 00140fff 4 KB DAP ROM Table */ +#define IMX_ETB_OFFSET 0x00141000 /* 00141000 00141fff 4 KB ETB */ +#define IMX_EXTCTI_OFFSET 0x00142000 /* 00142000 00142fff 4 KB ext. CTI */ +#define IMX_TPIU_OFFSET 0x00143000 /* 00143000 00143fff 4 KB TPIU */ +#define IMX_FUNNEL_OFFSET 0x00144000 /* 00144000 00144fff 4 KB FUNNEL */ + /* 00145000 0014efff 40 KB Reserved */ +#define IMX_CA9INTEG_OFFSET 0x0014f000 /* 0014f000 0014ffff 4 KB CA9-INTEG */ +#define IMX_CPUDBG_OFFSET(n) (0x00150000 + ((n) << 13)) +#define IMX_CPUPMU_OFFSET(n) (0x00151000 + ((n) << 13)) +#define IMX_CPU0DBG_OFFSET 0x00150000 /* 00150000 00150fff 4 KB CPU0 Debug I/F */ +#define IMX_CPU0PMU_OFFSET 0x00151000 /* 00151000 00151fff 4 KB CPU0 PMU */ +#define IMX_CPU1DBG_OFFSET 0x00152000 /* 00152000 00152fff 4 KB CPU1 Debug I/F */ +#define IMX_CPU1PMC_OFFSET 0x00153000 /* 00153000 00153fff 4 KB CPU1 PMU */ +#define IMX_CPU2DBG_OFFSET 0x00154000 /* 00154000 00154fff 4 KB CPU2 Debug I/F */ +#define IMX_CPU2PMU_OFFSET 0x00155000 /* 00155000 00155fff 4 KB CPU2 PMU */ +#define IMX_CPU3DBG_OFFSET 0x00156000 /* 00156000 00156fff 4 KB CPU3 Debug I/F */ +#define IMX_CPU3PMU_OFFSET 0x00157000 /* 00157000 00157fff 4 KB CPU3 PMU */ +#define IMX_CTI_OFFSET(n) (0x00158000 + ((n) << 12)) +#define IMX_CTI0_OFFSET 0x00158000 /* 00158000 00158fff 4 KB CTI0 */ +#define IMX_CTI1_OFFSET 0x00159000 /* 00159000 00159fff 4 KB CTI1 */ +#define IMX_CTI2_OFFSET 0x0015a000 /* 0015a000 0015afff 4 KB CTI2 */ +#define IMX_CTI3_OFFSET 0x0015b000 /* 0015b000 0015bfff 4 KB CTI3 */ +#define IMX_PTM_OFFSET(n) (0x0015c000 + ((n) << 12)) +#define IMX_PTM0_OFFSET 0x0015c000 /* 0015c000 0015cfff 4 KB PTM0 */ +#define IMX_PTM1_OFFSET 0x0015d000 /* 0015d000 0015dfff 4 KB PTM1 */ +#define IMX_PTM2_OFFSET 0x0015e000 /* 0015e000 0015efff 4 KB PTM2 */ +#define IMX_PTM3_OFFSET 0x0015f000 /* 0015f000 0015ffff 4 KB PTM3 */ +#define IMX_PLATCTRL_OFFSET 0x00160000 /* 00160000 00160fff 4 KB Platform Control */ + +/* i.MX6 SATA PSECTION Offsets */ + +#define IMX_SATA_OFFSET 0x00200000 /* 00200000-02203fff 16 KB SATA */ +#define IMX_OPENVG_OFFSET 0x00204000 /* 00204000-02207fff 16 KB OpenVG (GC355) */ +#define IMX_MIPIHSI_OFFSET 0x00208000 /* 00208000-0220bfff 16 KB MIPIHSI */ + /* 0020c000-000fffff 2 MB Reserved */ +/* i.MX6 DMA Physical Base Addresses */ + +#define IMX_CAAMRAM_PBASE (IMX_DMA_PSECTION+IMX_CAAMRAM_OFFSET) +#define IMX_APBHDMA_PBASE (IMX_DMA_PSECTION+IMX_APBHDMA_OFFSET) +#define IMX_GPMI_PBASE (IMX_DMA_PSECTION+IMX_GPMI_OFFSET) +#define IMX_BCH_PBASE (IMX_DMA_PSECTION+IMX_BCH_OFFSET) +#define IMX_HDMI_PBASE (IMX_DMA_PSECTION+IMX_HDMI_OFFSET) +#define IMX_GPU3D_PBASE (IMX_DMA_PSECTION+IMX_GPU3D_OFFSET) +#define IMX_GPU2D_PBASE (IMX_DMA_PSECTION+IMX_GPU2D_OFFSET) +#define IMX_DTCP_PBASE (IMX_DMA_PSECTION+IMX_DTCP_OFFSET) + +/* i.MX6 OCRAM Physical Base Addresses */ + +#define IMX_OCRAM_PBASE (IMX_OCRAM_PSECTION+IMX_OCRAM_OFFSET) +#define IMX_OCRAMALIAS_PBASE (IMX_OCRAM_PSECTION+IMX_OCRAMALIAS_OFFSET) + +/* i.MX6 ARM MP Physical Base Addresses */ + +#define IMX_MPSCU_PBASE (IMX_ARMMP_PSECTION+IMX_MPSCU_OFFSET) +#define IMX_MPICC_PBASE (IMX_ARMMP_PSECTION+IMX_MPICC_OFFSET) +#define IMX_MPGTM_PBASE (IMX_ARMMP_PSECTION+IMX_MPGTM_OFFSET) +#define IMX_MPPTM_PBASE (IMX_ARMMP_PSECTION+IMX_MPPTM_OFFSET) +#define IMX_MPICD_PBASE (IMX_ARMMP_PSECTION+IMX_MPICD_OFFSET) +#define IMX_PL310_PBASE (IMX_ARMMP_PSECTION+IMX_PL310_OFFSET) + +/* i.MX6 PCIE Physical Base Addresses */ + +#define IMX_PCIE_PBASE (IMX_PCIE_PSECTION+IMX_PCIE_OFFSET) +#define IMX_PCIEREGS_PBASE (IMX_PCIE_PSECTION+IMX_PCIEREGS_OFFSET) + +/* i.MX6 AIPS-1 Physical Base Addresses */ + +#define IMX_SPDIF_PBASE (IMX_AIPS1_PSECTION+IMX_SPDIF_OFFSET) +#define IMX_ECSPI1_PBASE (IMX_AIPS1_PSECTION+IMX_ECSPI1_OFFSET) +#define IMX_ECSPI2_PBASE (IMX_AIPS1_PSECTION+IMX_ECSPI2_OFFSET) +#define IMX_ECSPI3_PBASE (IMX_AIPS1_PSECTION+IMX_ECSPI3_OFFSET) +#define IMX_ECSPI4_PBASE (IMX_AIPS1_PSECTION+IMX_ECSPI4_OFFSET) +#define IMX_ECSPI5_PBASE (IMX_AIPS1_PSECTION+IMX_ECSPI5_OFFSET) +#define IMX_UART1_PBASE (IMX_AIPS1_PSECTION+IMX_UART1_OFFSET) +#define IMX_ESAI_PBASE (IMX_AIPS1_PSECTION+IMX_ESAI_OFFSET) +#define IMX_SSI1_PBASE (IMX_AIPS1_PSECTION+IMX_SSI1_OFFSET) +#define IMX_SSI2_PBASE (IMX_AIPS1_PSECTION+IMX_SSI2_OFFSET) +#define IMX_SSI3_PBASE (IMX_AIPS1_PSECTION+IMX_SSI3_OFFSET) +#define IMX_ASRC_PBASE (IMX_AIPS1_PSECTION+IMX_ASRC_OFFSET) +#define IMX_SPBA_PBASE (IMX_AIPS1_PSECTION+IMX_SPBA_OFFSET) +#define IMX_VPU_PBASE (IMX_AIPS1_PSECTION+IMX_VPU_OFFSET) +#define IMX_APIS1CFG_PBASE (IMX_AIPS1_PSECTION+IMX_APIS1CFG_OFFSET) +#define IMX_PWM1_PBASE (IMX_AIPS1_PSECTION+IMX_PWM1_OFFSET) +#define IMX_PWM2_PBASE (IMX_AIPS1_PSECTION+IMX_PWM2_OFFSET) +#define IMX_PWM3_PBASE (IMX_AIPS1_PSECTION+IMX_PWM3_OFFSET) +#define IMX_PWM4_PBASE (IMX_AIPS1_PSECTION+IMX_PWM4_OFFSET) +#define IMX_CAN1_PBASE (IMX_AIPS1_PSECTION+IMX_CAN1_OFFSET) +#define IMX_CAN2_PBASE (IMX_AIPS1_PSECTION+IMX_CAN2_OFFSET) +#define IMX_GPT_PBASE (IMX_AIPS1_PSECTION+IMX_GPT_OFFSET) +#define IMX_GPIO_PBASE(n) (IMX_AIPS1_PSECTION+IMX_GPIO_OFFSET(n)) +#define IMX_GPIO1_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO1_OFFSET) +#define IMX_GPIO2_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO2_OFFSET) +#define IMX_GPIO3_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO3_OFFSET) +#define IMX_GPIO4_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO4_OFFSET) +#define IMX_GPIO5_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO5_OFFSET) +#define IMX_GPIO6_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO6_OFFSET) +#define IMX_GPIO7_PBASE (IMX_AIPS1_PSECTION+IMX_GPIO7_OFFSET) +#define IMX_KPP_PBASE (IMX_AIPS1_PSECTION+IMX_KPP_OFFSET) +#define IMX_WDOG1_PBASE (IMX_AIPS1_PSECTION+IMX_WDOG1_OFFSET) +#define IMX_WDOG2_PBASE (IMX_AIPS1_PSECTION+IMX_WDOG2_OFFSET) +#define IMX_CCM_PBASE (IMX_AIPS1_PSECTION+IMX_CCM_OFFSET) +#define IMX_ANALOG_PBASE (IMX_AIPS1_PSECTION+IMX_ANALOG_OFFSET) +#define IMX_USBPHY1_PBASE (IMX_AIPS1_PSECTION+IMX_USBPHY1_OFFSET) +#define IMX_USBPHY2_PBASE (IMX_AIPS1_PSECTION+IMX_USBPHY2_OFFSET) +#define IMX_SNVSHP_PBASE (IMX_AIPS1_PSECTION+IMX_SNVSHP_OFFSET) +#define IMX_EPIT1_PBASE (IMX_AIPS1_PSECTION+IMX_EPIT1_OFFSET) +#define IMX_EPIT2_PBASE (IMX_AIPS1_PSECTION+IMX_EPIT2_OFFSET) +#define IMX_SRC_PBASE (IMX_AIPS1_PSECTION+IMX_SRC_OFFSET) +#define IMX_GPC_PBASE (IMX_AIPS1_PSECTION+IMX_GPC_OFFSET) +#define IMX_PGCPU_PBASE (IMX_AIPS1_PSECTION+IMX_PGCPU_OFFSET) +#define IMX_PGCARM_PBASE (IMX_AIPS1_PSECTION+IMX_PGCARM_OFFSET) +#define IMX_IOMUXC_PBASE (IMX_AIPS1_PSECTION+IMX_IOMUXC_OFFSET) +#define IMX_DCIC1_PBASE (IMX_AIPS1_PSECTION+IMX_DCIC1_OFFSET) +#define IMX_DCIC2_PBASE (IMX_AIPS1_PSECTION+IMX_DCIC2_OFFSET) +#define IMX_SDMA_PBASE (IMX_AIPS1_PSECTION+IMX_SDMA_OFFSET) + +/* i.MX6 AIPS-2 Physical Base Addresses */ + +#define IMX_CAAM_PBASE (IMX_AIPS2_PSECTION+IMX_CAAM_OFFSET) +#define IMX_DAP_PBASE (IMX_AIPS2_PSECTION+IMX_DAP_OFFSET) +#define IMX_AIPS2CGF_PBASE (IMX_AIPS2_PSECTION+IMX_AIPS2CGF_OFFSET) +#define IMX_USBOH3_PBASE (IMX_AIPS2_PSECTION+IMX_USBOH3_OFFSET) +#define IMX_ENET_PBASE (IMX_AIPS2_PSECTION+IMX_ENET_OFFSET) +#define IMX_MLB150_PBASE (IMX_AIPS2_PSECTION+IMX_MLB150_OFFSET) +#define IMX_USDHC1_PBASE (IMX_AIPS2_PSECTION+IMX_USDHC1_OFFSET) +#define IMX_USDHC2_PBASE (IMX_AIPS2_PSECTION+IMX_USDHC2_OFFSET) +#define IMX_USDHC3_PBASE (IMX_AIPS2_PSECTION+IMX_USDHC3_OFFSET) +#define IMX_USDHC4_PBASE (IMX_AIPS2_PSECTION+IMX_USDHC4_OFFSET) +#define IMX_I2C1_PBASE (IMX_AIPS2_PSECTION+IMX_I2C1_OFFSET) +#define IMX_I2C2_PBASE (IMX_AIPS2_PSECTION+IMX_I2C2_OFFSET) +#define IMX_I2C3_PBASE (IMX_AIPS2_PSECTION+IMX_I2C3_OFFSET) +#define IMX_ROMCP_PBASE (IMX_AIPS2_PSECTION+IMX_ROMCP_OFFSET) +#define IMX_MMDC_PBASE (IMX_AIPS2_PSECTION+IMX_MMDC_OFFSET) +#define IMX_MMDCP1_PBASE (IMX_AIPS2_PSECTION+IMX_MMDCP1_OFFSET) +#define IMX_EIM_PBASE (IMX_AIPS2_PSECTION+IMX_EIM_OFFSET) +#define IMX_OCOTPCTRL_PBASE (IMX_AIPS2_PSECTION+IMX_OCOTPCTRL_OFFSET) +#define IMX_TZASC1_PBASE (IMX_AIPS2_PSECTION+IMX_TZASC1_OFFSET) +#define IMX_TZASC2_PBASE (IMX_AIPS2_PSECTION+IMX_TZASC2_OFFSET) +#define IMX_AUDMUX_PBASE (IMX_AIPS2_PSECTION+IMX_AUDMUX_OFFSET) +#define IMX_MIPICSI_PBASE (IMX_AIPS2_PSECTION+IMX_MIPICSI_OFFSET) +#define IMX_MIPIDSI_PBASE (IMX_AIPS2_PSECTION+IMX_MIPIDSI_OFFSET) +#define IMX_VDOA_PBASE (IMX_AIPS2_PSECTION+IMX_VDOA_OFFSET) +#define IMX_UART2_PBASE (IMX_AIPS2_PSECTION+IMX_UART2_OFFSET) +#define IMX_UART3_PBASE (IMX_AIPS2_PSECTION+IMX_UART3_OFFSET) +#define IMX_UART4_PBASE (IMX_AIPS2_PSECTION+IMX_UART4_OFFSET) +#define IMX_UART5_PBASE (IMX_AIPS2_PSECTION+IMX_UART5_OFFSET) + +/* i.MX6 DAP AIPS-2 Physical Base Addresses */ + +#define IMX_DAPROM_PBASE (IMX_AIPS2_PSECTION+IMX_DAPROM_OFFSET) +#define IMX_ETB_PBASE (IMX_AIPS2_PSECTION+IMX_ETB_OFFSET) +#define IMX_EXTCTI_PBASE (IMX_AIPS2_PSECTION+IMX_EXTCTI_OFFSET) +#define IMX_TPIU_PBASE (IMX_AIPS2_PSECTION+IMX_TPIU_OFFSET) +#define IMX_FUNNEL_PBASE (IMX_AIPS2_PSECTION+IMX_FUNNEL_OFFSET) +#define IMX_CA9INTEG_PBASE (IMX_AIPS2_PSECTION+IMX_CA9INTEG_OFFSET) +#define IMX_CPUDBG_PBASE(n) (IMX_AIPS2_PSECTION+IMX_CPUDBG_OFFSET(n)) +#define IMX_CPUPMU_PBASE(n) (IMX_AIPS2_PSECTION+IMX_CPUPMU_OFFSET(n)) +#define IMX_CPU0DBG_PBASE (IMX_AIPS2_PSECTION+IMX_CPU0DBG_OFFSET) +#define IMX_CPU0PMU_PBASE (IMX_AIPS2_PSECTION+IMX_CPU0PMU_OFFSET) +#define IMX_CPU1DBG_PBASE (IMX_AIPS2_PSECTION+IMX_CPU1DBG_OFFSET) +#define IMX_CPU1PMC_PBASE (IMX_AIPS2_PSECTION+IMX_CPU1PMC_OFFSET) +#define IMX_CPU2DBG_PBASE (IMX_AIPS2_PSECTION+IMX_CPU2DBG_OFFSET) +#define IMX_CPU2PMU_PBASE (IMX_AIPS2_PSECTION+IMX_CPU2PMU_OFFSET) +#define IMX_CPU3DBG_PBASE (IMX_AIPS2_PSECTION+IMX_CPU3DBG_OFFSET) +#define IMX_CPU3PMU_PBASE (IMX_AIPS2_PSECTION+IMX_CPU3PMU_OFFSET) +#define IMX_CTI_PBASE(n) (IMX_AIPS2_PSECTION+IMX_CTI_OFFSET(n)) +#define IMX_CTI0_PBASE (IMX_AIPS2_PSECTION+IMX_CTI0_OFFSET) +#define IMX_CTI1_PBASE (IMX_AIPS2_PSECTION+IMX_CTI1_OFFSET) +#define IMX_CTI2_PBASE (IMX_AIPS2_PSECTION+IMX_CTI2_OFFSET) +#define IMX_CTI3_PBASE (IMX_AIPS2_PSECTION+IMX_CTI3_OFFSET) +#define IMX_PTM_PBASE(n) (IMX_AIPS2_PSECTION+IMX_PTM_OFFSET(n)) +#define IMX_PTM0_PBASE (IMX_AIPS2_PSECTION+IMX_PTM0_OFFSET) +#define IMX_PTM1_PBASE (IMX_AIPS2_PSECTION+IMX_PTM1_OFFSET) +#define IMX_PTM2_PBASE (IMX_AIPS2_PSECTION+IMX_PTM2_OFFSET) +#define IMX_PTM3_PBASE (IMX_AIPS2_PSECTION+IMX_PTM3_OFFSET) +#define IMX_PLATCTRL_PBASE (IMX_AIPS2_PSECTION+IMX_PLATCTRL_OFFSET) + +/* i.MX6 SATA Physical Base Addresses */ + +#define IMX_SATA_PBASE (IMX_SATA_PSECTION+IMX_SATA_OFFSET) +#define IMX_OPENVG_PBASE (IMX_SATA_PSECTION+IMX_OPENVG_OFFSET) +#define IMX_MIPIHSI_PBASE (IMX_SATA_PSECTION+IMX_MIPIHSI_OFFSET) + +/* Sizes of memory regions in bytes. + * + * These sizes exclude the undefined addresses at the end of the memory + * region. The implemented sizes of the EBI CS0-3 and DDRCS regions + * are not known apriori and must be specified with configuration settings. + */ + +#define IMX_ROMCP_SECSIZE (96*1024) /* 00000000-00017fff 96 KB Boot ROM (ROMCP) */ + /* 00018000-000fffff 928 KB Reserved */ +#define IMX_DMA_SECSIZE (1024*1024) /* 00100000-001fffff 1 MB See offsets below */ +#define IMX_GPV2_SECSIZE (1024*1024) /* 00200000-002fffff 1 MB GPV_2 PL301 (per1) configuration port */ +#define IMX_GPV3_SECSIZE (1024*1024) /* 00300000-003fffff 1 MB GPV_3 PL301 (per2) configuration port */ + /* 00400000-007fffff 4 MB Reserved */ +#define IMX_GPV4_SECSIZE (1024*1024) /* 00800000-008fffff 1 MB GPV_4 PL301 (fast3) configuration port */ +#define IMX_OCRAM_SECSIZE (1024*1024) /* 00900000-009fffff 1 MB OCRAM section size */ +#define IMX_ARMMP_SECSIZE (8*1024) /* 00a00000-00afffff 8 KB ARM MP */ +#define IMX_GPV0PL301_SECSIZE (1024*1024) /* 00b00000-00bfffff 1 MB GPV0 PL301 (fast2) configuration port */ +#define IMX_GPV1PL301_SECSIZE (1024*1024) /* 00c00000-00cfffff 1 MB GPV1 PL301 (fast1) configuration port */ + /* 00d00000-00ffffff 3072 KB Reserved */ +#define IMX_PCIE_SECSIZE (16*1024*1024) /* 01000000-01ffffff 16 MB PCIe */ +#define IMX_AIPS1_SECSIZE (1024*1024) /* 02000000-020fffff 1 MB Peripheral IPs via AIPS-1 */ +#define IMX_AIPS2_SECSIZE (1024*1024) /* 02100000-021fffff 1 MB Peripheral IPs via AIPS-2 */ +#define IMX_SATA_SECSIZE (48*1024) /* 02200000-0220bfff 48 KB SATA */ + /* 0220c000-023fffff 2 MB Reserved */ +#define IMX_IPU1_SECSIZE (4*1024*1024) /* 02600000-029fffff 4 MB IPU-1 */ +#define IMX_IPU2_SECSIZE (4*1024*1024) /* 02a00000-02dfffff 4 MB IPU-2 */ +#define IMX_EIM_SECSIZE MKULONG(CONFIG_IMX_EIM_SIZE) /* 08000000-0fffffff 128 MB EIM - (NOR/SRAM) */ +#define IMX_MMDCDDR_SECSIZE MKULONG(CONFIG_IMX_DDR_SIZE) /* 10000000-ffffffff 3840 MB MMDC-DDR Controller */ + /* 10000000-7fffffff 1792 MB */ + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of memory regions in sections. + * + * The boot logic in sam_boot.c, will select 1Mb level 1 MMU mappings to + * span the entire physical address space. The definitions below specify + * the number of 1Mb entries that are required to span a particular address + * region. + */ + +#define IMX_ROMCP_NSECTIONS _NSECTIONS(IMX_ROMCP_SECSIZE) +#define IMX_DMA_NSECTIONS _NSECTIONS(IMX_DMA_SECSIZE) +#define IMX_GPV2_NSECTIONS _NSECTIONS(IMX_GPV2_SECSIZE) +#define IMX_GPV3_NSECTIONS _NSECTIONS(IMX_GPV3_SECSIZE) +#define IMX_GPV4_NSECTIONS _NSECTIONS(IMX_GPV4_SECSIZE) +#define IMX_OCRAM_NSECTIONS _NSECTIONS(IMX_OCRAM_SECSIZE) +#define IMX_ARMMP_NSECTIONS _NSECTIONS(IMX_ARMMP_SECSIZE) +#define IMX_GPV0PL301_NSECTIONS _NSECTIONS(IMX_GPV0PL301_SECSIZE) +#define IMX_GPV1PL301_NSECTIONS _NSECTIONS(IMX_GPV1PL301_SECSIZE) +#define IMX_PCIE_NSECTIONS _NSECTIONS(IMX_PCIE_SECSIZE) +#define IMX_AIPS1_NSECTIONS _NSECTIONS(IMX_AIPS1_SECSIZE) +#define IMX_AIPS2_NSECTIONS _NSECTIONS(IMX_AIPS2_SECSIZE) +#define IMX_SATA_NSECTIONS _NSECTIONS(IMX_SATA_SECSIZE) +#define IMX_IPU1_NSECTIONS _NSECTIONS(IMX_IPU1_SECSIZE) +#define IMX_IPU2_NSECTIONS _NSECTIONS(IMX_IPU2_SECSIZE) +#define IMX_EIM_NSECTIONS _NSECTIONS(IMX_EIM_SECSIZE) +#define IMX_MMDCDDR_NSECTIONS _NSECTIONS(IMX_MMDCDDR_SECSIZE) + +/* Section MMU Flags + * + * SDRAM is a special case because it requires non-cached access of its + * initial configuration, then cached access thereafter. + */ + +#define IMX_ROMCP_MMUFLAGS MMU_ROMFLAGS +#define IMX_DMA_MMUFLAGS MMU_IOFLAGS +#define IMX_GPV2_MMUFLAGS MMU_IOFLAGS +#define IMX_GPV3_MMUFLAGS MMU_IOFLAGS +#define IMX_GPV4_MMUFLAGS MMU_IOFLAGS +#define IMX_OCRAM_MMUFLAGS MMU_MEMFLAGS +#define IMX_ARMMP_MMUFLAGS MMU_IOFLAGS +#define IMX_GPV0PL301_MMUFLAGS MMU_IOFLAGS +#define IMX_GPV1PL301_MMUFLAGS MMU_IOFLAGS +#define IMX_PCIE_MMUFLAGS MMU_IOFLAGS +#define IMX_AIPS1_MMUFLAGS MMU_IOFLAGS +#define IMX_AIPS2_MMUFLAGS MMU_IOFLAGS +#define IMX_SATA_MMUFLAGS MMU_IOFLAGS +#define IMX_IPU1_MMUFLAGS MMU_IOFLAGS +#define IMX_IPU2_MMUFLAGS MMU_IOFLAGS +#define IMX_EIM_MMUFLAGS MMU_ROMFLAGS /* REVISIT */ +#define IMX_MMDCDDR_MMUFLAGS MMU_MEMFLAGS + +/* i.MX6 Virtual (mapped) Memory Map + * + * board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* i.MX6 Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + +/* The default mappings are a simple 1-to-1 mapping */ + +# define IMX_ROMCP_VSECTION IMX_ROMCP_PSECTION /* 96 KB Boot ROM (ROMCP) */ +# define IMX_DMA_VSECTION IMX_DMA_PSECTION /* 1 MB See offsets below */ +# define IMX_GPV2_VSECTION IMX_GPV2_PSECTION /* 1 MB GPV_2 PL301 (per1) configuration port */ +# define IMX_GPV3_VSECTION IMX_GPV3_PSECTION /* 1 MB GPV_3 PL301 (per2) configuration port */ +# define IMX_GPV4_VSECTION IMX_GPV4_PSECTION /* 1 MB GPV_4 PL301 (fast3) configuration port */ +# define IMX_OCRAM_VSECTION IMX_OCRAM_PSECTION /* 1 MB OCRAM */ +# define IMX_ARMMP_VSECTION IMX_ARMMP_PSECTION /* 8 KB ARM MP */ +# define IMX_GPV0PL301_VSECTION IMX_GPV0PL301_PSECTION /* 1 MB GPV0 PL301 (fast2) configuration port */ +# define IMX_GPV1PL301_VSECTION IMX_GPV1PL301_PSECTION /* 1 MB GPV1 PL301 (fast1) configuration port */ +# define IMX_PCIE_VSECTION IMX_PCIE_PSECTION /* 16 MB PCIe */ +# define IMX_AIPS1_VSECTION IMX_AIPS1_PSECTION /* 1 MB Peripheral IPs via AIPS-1 */ +# define IMX_AIPS2_VSECTION IMX_AIPS2_PSECTION /* 1 MB Peripheral IPs via AIPS-2 */ +# define IMX_SATA_VSECTION IMX_SATA_PSECTION /* 48 KB SATA */ +# define IMX_IPU1_VSECTION IMX_IPU1_PSECTION /* 4 MB IPU-1 */ +# define IMX_IPU2_VSECTION IMX_IPU2_PSECTION /* 4 MB IPU-2 */ +# define IMX_EIM_VSECTION IMX_EIM_PSECTION /* 128 MB EIM - (NOR/SRAM) */ +# define IMX_MMDCDDR_VSECTION IMX_MMDCDDR_PSECTION /* 3840 MB MMDC-DDR Controller */ +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +/* i.MX6 DMA Virtual Base Addresses */ + +#define IMX_CAAMRAM_VBASE (IMX_DMA_VSECTION+IMX_CAAMRAM_OFFSET) +#define IMX_APBHDMA_VBASE (IMX_DMA_VSECTION+IMX_APBHDMA_OFFSET) +#define IMX_GPMI_VBASE (IMX_DMA_VSECTION+IMX_GPMI_OFFSET) +#define IMX_BCH_VBASE (IMX_DMA_VSECTION+IMX_BCH_OFFSET) +#define IMX_HDMI_VBASE (IMX_DMA_VSECTION+IMX_HDMI_OFFSET) +#define IMX_GPU3D_VBASE (IMX_DMA_VSECTION+IMX_GPU3D_OFFSET) +#define IMX_GPU2D_VBASE (IMX_DMA_VSECTION+IMX_GPU2D_OFFSET) +#define IMX_DTCP_VBASE (IMX_DMA_VSECTION+IMX_DTCP_OFFSET) + +/* i.MX6 OCRAM Virtual Base Addresses */ + +#define IMX_OCRAM_VBASE (IMX_OCRAM_VSECTION+IMX_OCRAM_OFFSET) +#define IMX_OCRAMALIAS_VBASE (IMX_OCRAM_VSECTION+IMX_OCRAMALIAS_OFFSET) + +/* i.MX6 ARM MP Virtual Base Addresses */ + +#define IMX_MPSCU_VBASE (IMX_ARMMP_VSECTION+IMX_MPSCU_OFFSET) +#define IMX_MPICC_VBASE (IMX_ARMMP_VSECTION+IMX_MPICC_OFFSET) +#define IMX_MPGTM_VBASE (IMX_ARMMP_VSECTION+IMX_MPGTM_OFFSET) +#define IMX_MPPTM_VBASE (IMX_ARMMP_VSECTION+IMX_MPPTM_OFFSET) +#define IMX_MPICD_VBASE (IMX_ARMMP_VSECTION+IMX_MPICD_OFFSET) +#define IMX_PL310_VBASE (IMX_ARMMP_VSECTION+IMX_PL310_OFFSET) + +/* i.MX6 PCIE Virtual Base Addresses */ + +#define IMX_PCIE_VBASE (IMX_PCIE_VSECTION+IMX_PCIE_OFFSET) +#define IMX_PCIEREGS_VBASE (IMX_PCIE_VSECTION+IMX_PCIEREGS_OFFSET) + +/* i.MX6 AIPS-1 Virtual Base Addresses */ + +#define IMX_SPDIF_VBASE (IMX_AIPS1_VSECTION+IMX_SPDIF_OFFSET) +#define IMX_ECSPI1_VBASE (IMX_AIPS1_VSECTION+IMX_ECSPI1_OFFSET) +#define IMX_ECSPI2_VBASE (IMX_AIPS1_VSECTION+IMX_ECSPI2_OFFSET) +#define IMX_ECSPI3_VBASE (IMX_AIPS1_VSECTION+IMX_ECSPI3_OFFSET) +#define IMX_ECSPI4_VBASE (IMX_AIPS1_VSECTION+IMX_ECSPI4_OFFSET) +#define IMX_ECSPI5_VBASE (IMX_AIPS1_VSECTION+IMX_ECSPI5_OFFSET) +#define IMX_UART1_VBASE (IMX_AIPS1_VSECTION+IMX_UART1_OFFSET) +#define IMX_ESAI_VBASE (IMX_AIPS1_VSECTION+IMX_ESAI_OFFSET) +#define IMX_SSI1_VBASE (IMX_AIPS1_VSECTION+IMX_SSI1_OFFSET) +#define IMX_SSI2_VBASE (IMX_AIPS1_VSECTION+IMX_SSI2_OFFSET) +#define IMX_SSI3_VBASE (IMX_AIPS1_VSECTION+IMX_SSI3_OFFSET) +#define IMX_ASRC_VBASE (IMX_AIPS1_VSECTION+IMX_ASRC_OFFSET) +#define IMX_SPBA_VBASE (IMX_AIPS1_VSECTION+IMX_SPBA_OFFSET) +#define IMX_VPU_VBASE (IMX_AIPS1_VSECTION+IMX_VPU_OFFSET) +#define IMX_APIS1CFG_VBASE (IMX_AIPS1_VSECTION+IMX_APIS1CFG_OFFSET) +#define IMX_PWM1_VBASE (IMX_AIPS1_VSECTION+IMX_PWM1_OFFSET) +#define IMX_PWM2_VBASE (IMX_AIPS1_VSECTION+IMX_PWM2_OFFSET) +#define IMX_PWM3_VBASE (IMX_AIPS1_VSECTION+IMX_PWM3_OFFSET) +#define IMX_PWM4_VBASE (IMX_AIPS1_VSECTION+IMX_PWM4_OFFSET) +#define IMX_CAN1_VBASE (IMX_AIPS1_VSECTION+IMX_CAN1_OFFSET) +#define IMX_CAN2_VBASE (IMX_AIPS1_VSECTION+IMX_CAN2_OFFSET) +#define IMX_GPT_VBASE (IMX_AIPS1_VSECTION+IMX_GPT_OFFSET) +#define IMX_GPIO_VBASE(n) (IMX_AIPS1_VSECTION+IMX_GPIO_OFFSET(n)) +#define IMX_GPIO1_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO1_OFFSET) +#define IMX_GPIO2_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO2_OFFSET) +#define IMX_GPIO3_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO3_OFFSET) +#define IMX_GPIO4_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO4_OFFSET) +#define IMX_GPIO5_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO5_OFFSET) +#define IMX_GPIO6_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO6_OFFSET) +#define IMX_GPIO7_VBASE (IMX_AIPS1_VSECTION+IMX_GPIO7_OFFSET) +#define IMX_KPP_VBASE (IMX_AIPS1_VSECTION+IMX_KPP_OFFSET) +#define IMX_WDOG1_VBASE (IMX_AIPS1_VSECTION+IMX_WDOG1_OFFSET) +#define IMX_WDOG2_VBASE (IMX_AIPS1_VSECTION+IMX_WDOG2_OFFSET) +#define IMX_CCM_VBASE (IMX_AIPS1_VSECTION+IMX_CCM_OFFSET) +#define IMX_ANALOG_VBASE (IMX_AIPS1_VSECTION+IMX_ANALOG_OFFSET) +#define IMX_USBPHY1_VBASE (IMX_AIPS1_VSECTION+IMX_USBPHY1_OFFSET) +#define IMX_USBPHY2_VBASE (IMX_AIPS1_VSECTION+IMX_USBPHY2_OFFSET) +#define IMX_SNVSHP_VBASE (IMX_AIPS1_VSECTION+IMX_SNVSHP_OFFSET) +#define IMX_EPIT1_VBASE (IMX_AIPS1_VSECTION+IMX_EPIT1_OFFSET) +#define IMX_EPIT2_VBASE (IMX_AIPS1_VSECTION+IMX_EPIT2_OFFSET) +#define IMX_SRC_VBASE (IMX_AIPS1_VSECTION+IMX_SRC_OFFSET) +#define IMX_GPC_VBASE (IMX_AIPS1_VSECTION+IMX_GPC_OFFSET) +#define IMX_PGCPU_VBASE (IMX_AIPS1_VSECTION+IMX_PGCPU_OFFSET) +#define IMX_PGCARM_VBASE (IMX_AIPS1_VSECTION+IMX_PGCARM_OFFSET) +#define IMX_IOMUXC_VBASE (IMX_AIPS1_VSECTION+IMX_IOMUXC_OFFSET) +#define IMX_DCIC1_VBASE (IMX_AIPS1_VSECTION+IMX_DCIC1_OFFSET) +#define IMX_DCIC2_VBASE (IMX_AIPS1_VSECTION+IMX_DCIC2_OFFSET) +#define IMX_SDMA_VBASE (IMX_AIPS1_VSECTION+IMX_SDMA_OFFSET) + +/* i.MX6 AIPS-2 Virtual Base Addresses */ + +#define IMX_CAAM_VBASE (IMX_AIPS2_VSECTION+IMX_CAAM_OFFSET) +#define IMX_DAP_VBASE (IMX_AIPS2_VSECTION+IMX_DAP_OFFSET) +#define IMX_AIPS2CGF_VBASE (IMX_AIPS2_VSECTION+IMX_AIPS2CGF_OFFSET) +#define IMX_USBOH3_VBASE (IMX_AIPS2_VSECTION+IMX_USBOH3_OFFSET) +#define IMX_ENET_VBASE (IMX_AIPS2_VSECTION+IMX_ENET_OFFSET) +#define IMX_MLB150_VBASE (IMX_AIPS2_VSECTION+IMX_MLB150_OFFSET) +#define IMX_USDHC1_VBASE (IMX_AIPS2_VSECTION+IMX_USDHC1_OFFSET) +#define IMX_USDHC2_VBASE (IMX_AIPS2_VSECTION+IMX_USDHC2_OFFSET) +#define IMX_USDHC3_VBASE (IMX_AIPS2_VSECTION+IMX_USDHC3_OFFSET) +#define IMX_USDHC4_VBASE (IMX_AIPS2_VSECTION+IMX_USDHC4_OFFSET) +#define IMX_I2C1_VBASE (IMX_AIPS2_VSECTION+IMX_I2C1_OFFSET) +#define IMX_I2C2_VBASE (IMX_AIPS2_VSECTION+IMX_I2C2_OFFSET) +#define IMX_I2C3_VBASE (IMX_AIPS2_VSECTION+IMX_I2C3_OFFSET) +#define IMX_ROMCP_VBASE (IMX_AIPS2_VSECTION+IMX_ROMCP_OFFSET) +#define IMX_MMDC_VBASE (IMX_AIPS2_VSECTION+IMX_MMDC_OFFSET) +#define IMX_MMDCP1_VBASE (IMX_AIPS2_VSECTION+IMX_MMDCP1_OFFSET) +#define IMX_EIM_VBASE (IMX_AIPS2_VSECTION+IMX_EIM_OFFSET) +#define IMX_OCOTPCTRL_VBASE (IMX_AIPS2_VSECTION+IMX_OCOTPCTRL_OFFSET) +#define IMX_TZASC1_VBASE (IMX_AIPS2_VSECTION+IMX_TZASC1_OFFSET) +#define IMX_TZASC2_VBASE (IMX_AIPS2_VSECTION+IMX_TZASC2_OFFSET) +#define IMX_AUDMUX_VBASE (IMX_AIPS2_VSECTION+IMX_AUDMUX_OFFSET) +#define IMX_MIPICSI_VBASE (IMX_AIPS2_VSECTION+IMX_MIPICSI_OFFSET) +#define IMX_MIPIDSI_VBASE (IMX_AIPS2_VSECTION+IMX_MIPIDSI_OFFSET) +#define IMX_VDOA_VBASE (IMX_AIPS2_VSECTION+IMX_VDOA_OFFSET) +#define IMX_UART2_VBASE (IMX_AIPS2_VSECTION+IMX_UART2_OFFSET) +#define IMX_UART3_VBASE (IMX_AIPS2_VSECTION+IMX_UART3_OFFSET) +#define IMX_UART4_VBASE (IMX_AIPS2_VSECTION+IMX_UART4_OFFSET) +#define IMX_UART5_VBASE (IMX_AIPS2_VSECTION+IMX_UART5_OFFSET) + +/* i.MX6 DAP AIPS-2 Virtual Base Addresses */ + +#define IMX_DAPROM_VBASE (IMX_AIPS2_VSECTION+IMX_DAPROM_OFFSET) +#define IMX_ETB_VBASE (IMX_AIPS2_VSECTION+IMX_ETB_OFFSET) +#define IMX_EXTCTI_VBASE (IMX_AIPS2_VSECTION+IMX_EXTCTI_OFFSET) +#define IMX_TPIU_VBASE (IMX_AIPS2_VSECTION+IMX_TPIU_OFFSET) +#define IMX_FUNNEL_VBASE (IMX_AIPS2_VSECTION+IMX_FUNNEL_OFFSET) +#define IMX_CA9INTEG_VBASE (IMX_AIPS2_VSECTION+IMX_CA9INTEG_OFFSET) +#define IMX_CPUDBG_VBASE(n) (IMX_AIPS2_VSECTION+IMX_CPUDBG_OFFSET(n)) +#define IMX_CPUPMU_VBASE(n) (IMX_AIPS2_VSECTION+IMX_CPUPMU_OFFSET(n)) +#define IMX_CPU0DBG_VBASE (IMX_AIPS2_VSECTION+IMX_CPU0DBG_OFFSET) +#define IMX_CPU0PMU_VBASE (IMX_AIPS2_VSECTION+IMX_CPU0PMU_OFFSET) +#define IMX_CPU1DBG_VBASE (IMX_AIPS2_VSECTION+IMX_CPU1DBG_OFFSET) +#define IMX_CPU1PMC_VBASE (IMX_AIPS2_VSECTION+IMX_CPU1PMC_OFFSET) +#define IMX_CPU2DBG_VBASE (IMX_AIPS2_VSECTION+IMX_CPU2DBG_OFFSET) +#define IMX_CPU2PMU_VBASE (IMX_AIPS2_VSECTION+IMX_CPU2PMU_OFFSET) +#define IMX_CPU3DBG_VBASE (IMX_AIPS2_VSECTION+IMX_CPU3DBG_OFFSET) +#define IMX_CPU3PMU_VBASE (IMX_AIPS2_VSECTION+IMX_CPU3PMU_OFFSET) +#define IMX_CTI_VBASE(n) (IMX_AIPS2_VSECTION+IMX_CTI_OFFSET(n)) +#define IMX_CTI0_VBASE (IMX_AIPS2_VSECTION+IMX_CTI0_OFFSET) +#define IMX_CTI1_VBASE (IMX_AIPS2_VSECTION+IMX_CTI1_OFFSET) +#define IMX_CTI2_VBASE (IMX_AIPS2_VSECTION+IMX_CTI2_OFFSET) +#define IMX_CTI3_VBASE (IMX_AIPS2_VSECTION+IMX_CTI3_OFFSET) +#define IMX_PTM_VBASE(n) (IMX_AIPS2_VSECTION+IMX_PTM_OFFSET(n)) +#define IMX_PTM0_VBASE (IMX_AIPS2_VSECTION+IMX_PTM0_OFFSET) +#define IMX_PTM1_VBASE (IMX_AIPS2_VSECTION+IMX_PTM1_OFFSET) +#define IMX_PTM2_VBASE (IMX_AIPS2_VSECTION+IMX_PTM2_OFFSET) +#define IMX_PTM3_VBASE (IMX_AIPS2_VSECTION+IMX_PTM3_OFFSET) +#define IMX_PLATCTRL_VBASE (IMX_AIPS2_VSECTION+IMX_PLATCTRL_OFFSET) + +/* i.MX6 SATA Virtual Base Addresses */ + +#define IMX_SATA_VBASE (IMX_SATA_VSECTION+IMX_SATA_OFFSET) +#define IMX_OPENVG_VBASE (IMX_SATA_VSECTION+IMX_OPENVG_OFFSET) +#define IMX_MIPIHSI_VBASE (IMX_SATA_VSECTION+IMX_MIPIHSI_OFFSET) + +/* NuttX virtual base address + * + * The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX could be running from EIM NOR + * FLASH, EIM SRAM, or MMDC SDRAM. If we are running from FLASH, then we + * must have a separate mapping for the non-contiguous RAM region. + */ + +#ifdef CONFIG_IMX6_BOOT_NOR + +/* Some sanity checks. If we are running from FLASH, then one of the + * external chip selects must be configured to boot from NOR flash. + * And, if so, then its size must agree with the configured size. + */ + +# if defined(CONFIG_IMX_EIM) && defined(CONFIG_IMX_EIM_NOR) +# if CONFIG_IMX_EIM_SIZE != CONFIG_FLASH_SIZE +# error EIM FLASH size disagreement +# endif +# else +# error CONFIG_IMX6_BOOT_NOR=y, but no bootable NOR flash defined +# endif + + /* Set up the NOR FLASH region as the NUTTX .text region */ + +# define NUTTX_TEXT_VADDR (CONFIG_FLASH_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_FLASH_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_FLASH_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + + /* The "primary" RAM is the SDRAM or SRAM used for .bss and .data */ + +# define NUTTX_RAM_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_RAM_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_RAM_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_RAM_SIZE (NUTTX_RAM_PEND - NUTTX_RAM_PADDR) + +#else /* CONFIG_IMX6_BOOT_NOR */ + /* Must be CONFIG_IMX6_BOOT_OCRAM || CONFIG_IMX6_BOOT_SDRAM || CONFIG_IMX6_BOOT_SRAM */ + + /* Otherwise we are running from some kind of RAM (OCRAM, SRAM, or SDRAM). + * Setup the RAM region as the NUTTX .txt, .bss, and .data region. + */ + +# define NUTTX_TEXT_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + +#endif /* CONFIG_IMX6_BOOT_NOR */ + +/* MMU Page Table Location + * + * Determine the address of the MMU page table. We will always attempt to + * use the bottom 16KB of RAM (SRAM or DRAM) for the page table, but there + * are a few conditions that affect this: + * + * If CONFIG_ARCH_ROMPGTABLE, then the page table resides in ROM and we will + * not use any page table in RAM, and in that case the user must sepcify the + * address of the page table explicitly by defining PGTABLE_BASE_VADDR and + * PGTABLE_BASE_PADDR in the board.h file. + */ + +#undef PGTABLE_IN_HIGHSRAM +#undef PGTABLE_IN_LOWSRAM +#undef ARMV7A_PGTABLE_MAPPING /* We do not remap the page table */ + +/* Check if the user has configured the page table address */ + +#if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + + /* We must declare the page table at the bottom or at the top of OCRAM. */ + /* Yes.. do the vectors lie in low memory? */ + +# ifdef CONFIG_ARCH_LOWVECTORS + + /* In this case, page table must lie at the top 16Kb of OCRAM. */ + +# define PGTABLE_BASE_PADDR (IMX_OCRAM_PBASE + IMX_OCRAM_SIZE - PGTABLE_SIZE) +# define PGTABLE_BASE_VADDR (IMX_OCRAM_VBASE + IMX_OCRAM_SIZE - PGTABLE_SIZE) +# define PGTABLE_IN_HIGHSRAM 1 + + /* We will force the IDLE stack to precede the page table */ + +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR - CONFIG_IDLETHREAD_STACKSIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR - CONFIG_IDLETHREAD_STACKSIZE) + +# else /* CONFIG_ARCH_LOWVECTORS */ + + /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, + * perhaps elsewhere in OCRAM). The page table will then be positioned + * at the first 16Kb of SRAM. + */ + +# define PGTABLE_BASE_PADDR IMX_OCRAM_PBASE +# define PGTABLE_BASE_VADDR IMX_OCRAM_VBASE +# define PGTABLE_IN_LOWSRAM 1 + + /* We will force the IDLE stack to follow the page table */ + +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) + +# endif /* CONFIG_ARCH_LOWVECTORS */ + + /* In either case, the page table lies in OCRAM. If OCRAM is not the + * primary RAM region, then we will need to set-up a special mapping for + * the page table at boot time. + */ + +# if defined(CONFIG_BOOT_RUNFROMFLASH) + /* If we are running from FLASH, then the primary memory region is + * given by NUTTX_RAM_PADDR. + */ + +# if NUTTX_RAM_PADDR != SAM_OCRAM_PSECTION +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +/* Otherwise, we are running from RAM and that RAM is also the primary + * RAM. If that is not OCRAM, then we will need to create a mapping + * for the OCRAM at start-up. + */ + +# elif !defined(CONFIG_IMX6_BOOT_OCRAM) +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +#else /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + + /* Sanity check.. if one is defined, both should be defined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "One of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is undefined" +# endif + + /* The page table then lies at the beginning of the OSSRAM and + * the IDLE stack follows immediately. + */ + +# define PGTABLE_BASE_PADDR IMX_OCRAM_PBASE +# define PGTABLE_BASE_VADDR IMX_OCRAM_VBASE +# define PGTABLE_IN_LOWSRAM 1 + + /* We will force the IDLE stack to follow the page table */ + +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) + +#endif /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + +/* Level 2 Page table start addresses. + * + * The maximum size of the L1 page table is: + * + * (4GB address range / 1 MB per section ) * 4 bytes per entry = 16KB + * + * The maximum size of the L2 page table is: + * + * (4GB address range / 4 KB per page ) * 4 bytes per entry = 4MB + * + * 16KB of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation with a one-to-one address mapping). There is this large + * hole in the physcal address space for which there will never be level 1 + * mappings: + * + * 0x80000000-0xefffffff: Undefined (1.75 GB) + * + * That is the offset where the main L2 page tables will be positioned. This + * corresponds to page table offsets 0x000002000 up to 0x000003c00. That + * is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual + * address space) + * + * Up to two L2 page tables may be used: + * + * 1) One mapping the vector table. However, L2 page tables must be aligned + * to 1KB address boundaries, so the minimum L2 page table size is then + * 1KB, mapping up a full megabyte of virtual address space. + * + * This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not* + * defined. The i.MX6 boot-up logic will map the beginning of the boot + * memory to address 0x0000:0000 using both the MMU and the AXI matrix + * REMAP register. So no L2 page table is required. + * + * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional + * L2 page table is needed. This page table will use the remainder of + * the address space. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Vector L2 page table offset/size */ + +# define VECTOR_L2_OFFSET 0x000002000 +# define VECTOR_L2_SIZE 0x000000400 + + /* Vector L2 page table base addresses */ + +# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR + VECTOR_L2_OFFSET) +# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR + VECTOR_L2_OFFSET) + + /* Vector L2 page table end addresses */ + +# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE + VECTOR_L2_SIZE) +# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE + VECTOR_L2_SIZE) + + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002400 +# define PGTABLE_L2_SIZE 0x000001800 + +#else + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002000 +# define PGTABLE_L2_SIZE 0x000001c00 +#endif + +/* Paging L2 page table base addresses + * + * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR + PGTABLE_L2_OFFSET) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR + PGTABLE_L2_OFFSET) + +/* Paging L2 page table end addresses */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE + PGTABLE_L2_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE + PGTABLE_L2_SIZE) + +/* Base address of the interrupt vector table. + * + * IMX_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * IMX_VECTOR_VSRAM - Virtual address of vector table in SRAM + * IMX_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + +#define VECTOR_TABLE_SIZE 0x00010000 + +/* REVISIT: These definitions are not used: The vector table is at some + * arbitrary (but aligned) position in RAM or NOR FLASH and is positioned + * using the VBAR register. + */ + +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + + /* Vectors will always lie at the beginnin of OCRAM */ + +# define IMX_VECTOR_PADDR IMX_OCRAM_PBASE +# define IMX_VECTOR_VSRAM IMX_OCRAM_VBASE +# define IMX_VECTOR_VADDR 0x00000000 + +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ + +# define IMX_VECTOR_PADDR (IMX_OCRAM_PBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE) +# define IMX_VECTOR_VSRAM (IMX_OCRAM_VBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE) +# define IMX_VECTOR_VADDR 0xffff0000 + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_MEMORYMAP_H */ diff --git a/arch/arm/src/imx6/chip/imx_pinmux.h b/arch/arm/src/imx6/chip/imx_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..2cd840b9a14f660fe920b78b2eac115108036a1e --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_pinmux.h @@ -0,0 +1,967 @@ +/***************************************************************************************************** + * arch/arm/src/imx6/imx_pinmux.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_PINMUX_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_PINMUX_H + +/***************************************************************************************************** + * Pre-processor Definitions + *****************************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, however, + * will use the pin selection without the numeric suffix. Additional definitions are required in the + * board.h file. For example, if UART1 RXD connects via the SD3_DATA6 pin, then the following + * definition should appear in the board.h header file for that board: + * + * #define GPIO_UART1_RX_DATA GPIO_UART1_RX_DATA_1 + * + * The driver will then automatically configere to use the SD3_DATA6 pin for UART RXD. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific IOMUX options such as frequency, open-drain, + * push-pull, and pull-up/down! Just the basics are defined for most pins in this file. See the + * upper imx_gpio.h and imx_iomuxc.h header files for available definitions. + */ + +/* ARM */ + +#define GPIO_ARM_EVENTI (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO05_INDEX)) +#define GPIO_ARM_EVENTO (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_PIXCLK_INDEX)) +#define GPIO_ARM_TRACE_CLK (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA_EN_INDEX)) +#define GPIO_ARM_TRACE_CTL (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_HSYNC_INDEX)) +#define GPIO_ARM_TRACE00 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_VSYNC_INDEX)) +#define GPIO_ARM_TRACE01 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_ARM_TRACE02 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_ARM_TRACE03 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) +#define GPIO_ARM_TRACE04 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_ARM_TRACE05 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) +#define GPIO_ARM_TRACE06 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_ARM_TRACE07 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA10_INDEX)) +#define GPIO_ARM_TRACE08 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA11_INDEX)) +#define GPIO_ARM_TRACE09 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA12_INDEX)) +#define GPIO_ARM_TRACE10 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA13_INDEX)) +#define GPIO_ARM_TRACE11 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA14_INDEX)) +#define GPIO_ARM_TRACE12 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA15_INDEX)) +#define GPIO_ARM_TRACE13 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA16_INDEX)) +#define GPIO_ARM_TRACE14 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA17_INDEX)) +#define GPIO_ARM_TRACE15 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA18_INDEX)) + +/* Asynchronous Sample Rate Generator (ASRC) */ + +#define GPIO_ASRC_EXT_CLK_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_ASRC_EXT_CLK_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_ASRC_EXT_CLK_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) + +/* Audio Multiplexor */ + +#define GPIO_AUD3_RXC (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA10_INDEX)) +#define GPIO_AUD3_RXD (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_AUD3_RXFS (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA11_INDEX)) +#define GPIO_AUD3_TXC (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_AUD3_TXD (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_AUD3_TXFS (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) + +#define GPIO_AUD4_RXC_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_CMD_INDEX)) +#define GPIO_AUD4_RXC_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_AUD4_RXD_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA23_INDEX)) +#define GPIO_AUD4_RXD_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA0_INDEX)) +#define GPIO_AUD4_RXFS_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_CLK_INDEX)) +#define GPIO_AUD4_RXFS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) +#define GPIO_AUD4_TXC_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA20_INDEX)) +#define GPIO_AUD4_TXC_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA3_INDEX)) +#define GPIO_AUD4_TXD_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA21_INDEX)) +#define GPIO_AUD4_TXD_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA2_INDEX)) +#define GPIO_AUD4_TXFS_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA22_INDEX)) +#define GPIO_AUD4_TXFS_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA1_INDEX)) + +#define GPIO_AUD5_RXC_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA14_INDEX)) +#define GPIO_AUD5_RXC_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX)) +#define GPIO_AUD5_RXD_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX)) +#define GPIO_AUD5_RXD_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_AUD5_RXFS_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA13_INDEX)) +#define GPIO_AUD5_RXFS_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX)) +#define GPIO_AUD5_TXC_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX)) +#define GPIO_AUD5_TXC_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA16_INDEX)) +#define GPIO_AUD5_TXD_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX)) +#define GPIO_AUD5_TXD_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA17_INDEX)) +#define GPIO_AUD5_TXFS_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX)) +#define GPIO_AUD5_TXFS_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) + +#define GPIO_AUD6_RXC (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA06_INDEX)) +#define GPIO_AUD6_RXD (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN04_INDEX)) +#define GPIO_AUD6_RXFS (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA05_INDEX)) +#define GPIO_AUD6_TXC (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN15_INDEX)) +#define GPIO_AUD6_TXD (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN02_INDEX)) +#define GPIO_AUD6_TXFS (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN03_INDEX)) + +/* Clock Controller Module (CCM) */ + +#define GPIO_CCM_CLKO1_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_CCM_CLKO1_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_HSYNC_INDEX)) +#define GPIO_CCM_CLKO1_3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO05_INDEX)) +#define GPIO_CCM_CLKO1_4 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) +#define GPIO_CCM_CLKO2_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_CCM_CLKO2_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_CCM_PMIC_READY_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO17_INDEX)) +#define GPIO_CCM_PMIC_READY_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_EB0_INDEX)) +#define GPIO_CCM_REF_EN (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) + +/* Display Content Integrity Checker (DCIC) */ + +#define GPIO_DCIC1_OUT_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_DCIC1_OUT_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX)) + +#define GPIO_DCIC2_OUT_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX)) +#define GPIO_DCIC2_OUT_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA0_INDEX)) + +/* Enhanced Configurable SPI (ECSPI) */ + +#define GPIO_ECSPI1_MISO_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX)) +#define GPIO_ECSPI1_MISO_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_ECSPI1_MISO_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) +#define GPIO_ECSPI1_MISO_4 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA22_INDEX)) +#define GPIO_ECSPI1_MOSI_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX)) +#define GPIO_ECSPI1_MOSI_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_ECSPI1_MOSI_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_ECSPI1_MOSI_4 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA21_INDEX)) +#define GPIO_ECSPI1_RDY (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) +#define GPIO_ECSPI1_SCLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX)) +#define GPIO_ECSPI1_SCLK_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) +#define GPIO_ECSPI1_SCLK_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_ECSPI1_SCLK_4 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA20_INDEX)) +#define GPIO_ECSPI1_SS0_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX)) +#define GPIO_ECSPI1_SS0_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_ECSPI1_SS0_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_ECSPI1_SS0_4 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA23_INDEX)) +#define GPIO_ECSPI1_SS1_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_ECSPI1_SS1_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX)) +#define GPIO_ECSPI1_SS1_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA15_INDEX)) +#define GPIO_ECSPI1_SS2_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_ECSPI1_SS2_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX)) +#define GPIO_ECSPI1_SS3_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_ECSPI1_SS3_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX)) + +#define GPIO_ECSPI2_MISO_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA10_INDEX)) +#define GPIO_ECSPI2_MISO_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA17_INDEX)) +#define GPIO_ECSPI2_MISO_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_OE_INDEX)) +#define GPIO_ECSPI2_MOSI_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_ECSPI2_MOSI_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA16_INDEX)) +#define GPIO_ECSPI2_MOSI_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_CS1_INDEX)) +#define GPIO_ECSPI2_RDY (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_ECSPI2_SCLK_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) +#define GPIO_ECSPI2_SCLK_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_ECSPI2_SCLK_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_CS0_INDEX)) +#define GPIO_ECSPI2_SS0_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA11_INDEX)) +#define GPIO_ECSPI2_SS0_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) +#define GPIO_ECSPI2_SS0_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_RW_INDEX)) +#define GPIO_ECSPI2_SS1_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_LBA_INDEX)) +#define GPIO_ECSPI2_SS1_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA15_INDEX)) +#define GPIO_ECSPI2_SS2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX)) +#define GPIO_ECSPI2_SS3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX)) + +#define GPIO_ECSPI3_MISO (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA02_INDEX)) +#define GPIO_ECSPI3_MOSI (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA01_INDEX)) +#define GPIO_ECSPI3_RDY (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA07_INDEX)) +#define GPIO_ECSPI3_SCLK (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA00_INDEX)) +#define GPIO_ECSPI3_SS0 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA03_INDEX)) +#define GPIO_ECSPI3_SS1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA04_INDEX)) +#define GPIO_ECSPI3_SS2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA05_INDEX)) +#define GPIO_ECSPI3_SS3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA06_INDEX)) + +#define GPIO_ECSPI4_MISO (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_ECSPI4_MOSI (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_ECSPI4_RDY (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX)) +#define GPIO_ECSPI4_SCLK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_ECSPI4_SS0_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX)) +#define GPIO_ECSPI4_SS0_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX)) +#define GPIO_ECSPI4_SS1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_ECSPI4_SS2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX)) +#define GPIO_ECSPI4_SS3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX)) + +#define GPIO_ECSPI5_MISO_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA0_INDEX)) +#define GPIO_ECSPI5_MISO_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA0_INDEX)) +#define GPIO_ECSPI5_MOSI_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_CMD_INDEX)) +#define GPIO_ECSPI5_MOSI_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_CMD_INDEX)) +#define GPIO_ECSPI5_RDY (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) +#define GPIO_ECSPI5_SCLK_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_CLK_INDEX)) +#define GPIO_ECSPI5_SCLK_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_CLK_INDEX)) +#define GPIO_ECSPI5_SS0_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA1_INDEX)) +#define GPIO_ECSPI5_SS0_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA1_INDEX)) +#define GPIO_ECSPI5_SS1_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) +#define GPIO_ECSPI5_SS1_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA2_INDEX)) +#define GPIO_ECSPI5_SS2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) +#define GPIO_ECSPI5_SS3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA3_INDEX)) + +/* EIM-PSRAM/NOR Flash controller */ + +#define GPIO_EIM_ADDR00 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD00_INDEX)) +#define GPIO_EIM_ADDR01 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD01_INDEX)) +#define GPIO_EIM_ADDR02 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD02_INDEX)) +#define GPIO_EIM_ADDR03 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD03_INDEX)) +#define GPIO_EIM_ADDR04 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD04_INDEX)) +#define GPIO_EIM_ADDR05 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD05_INDEX)) +#define GPIO_EIM_ADDR06 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD06_INDEX)) +#define GPIO_EIM_ADDR07 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD07_INDEX)) +#define GPIO_EIM_ADDR08 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD08_INDEX)) +#define GPIO_EIM_ADDR09 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD09_INDEX)) +#define GPIO_EIM_ADDR10 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD10_INDEX)) +#define GPIO_EIM_ADDR11 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD11_INDEX)) +#define GPIO_EIM_ADDR12 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD12_INDEX)) +#define GPIO_EIM_ADDR13 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD13_INDEX)) +#define GPIO_EIM_ADDR14 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD14_INDEX)) +#define GPIO_EIM_ADDR15 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_AD15_INDEX)) +#define GPIO_EIM_ADDR16 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR16_INDEX)) +#define GPIO_EIM_ADDR17 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR17_INDEX)) +#define GPIO_EIM_ADDR18 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR18_INDEX)) +#define GPIO_EIM_ADDR19 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR19_INDEX)) +#define GPIO_EIM_ADDR20 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR20_INDEX)) +#define GPIO_EIM_ADDR21 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR21_INDEX)) +#define GPIO_EIM_ADDR22 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR22_INDEX)) +#define GPIO_EIM_ADDR23 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_EIM_ADDR24 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_EIM_ADDR25 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_EIM_ADDR26 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_NAND_CS3_INDEX)) +#define GPIO_EIM_BCLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_BCLK_INDEX)) +#define GPIO_EIM_CRE (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_EIM_CS0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_CS0_INDEX)) +#define GPIO_EIM_CS1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_CS1_INDEX)) +#define GPIO_EIM_CS2_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA1_INDEX)) +#define GPIO_EIM_CS2_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) +#define GPIO_EIM_CS3_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA2_INDEX)) +#define GPIO_EIM_CS3_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_EIM_DATA00 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA_EN_INDEX)) +#define GPIO_EIM_DATA01 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_VSYNC_INDEX)) +#define GPIO_EIM_DATA02 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_EIM_DATA03 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_EIM_DATA04 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) +#define GPIO_EIM_DATA05 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_EIM_DATA06 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) +#define GPIO_EIM_DATA07 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_EIM_DATA08 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA12_INDEX)) +#define GPIO_EIM_DATA09 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA13_INDEX)) +#define GPIO_EIM_DATA10 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA14_INDEX)) +#define GPIO_EIM_DATA11 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA15_INDEX)) +#define GPIO_EIM_DATA12 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA16_INDEX)) +#define GPIO_EIM_DATA13 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA17_INDEX)) +#define GPIO_EIM_DATA14 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA18_INDEX)) +#define GPIO_EIM_DATA15 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA19_INDEX)) +#define GPIO_EIM_DATA16 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) +#define GPIO_EIM_DATA17 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_EIM_DATA18 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_EIM_DATA19 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX)) +#define GPIO_EIM_DATA20 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX)) +#define GPIO_EIM_DATA21 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_EIM_DATA22 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_EIM_DATA23 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX)) +#define GPIO_EIM_DATA24 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX)) +#define GPIO_EIM_DATA25 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX)) +#define GPIO_EIM_DATA26 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_EIM_DATA27 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_EIM_DATA28 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_EIM_DATA29 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX)) +#define GPIO_EIM_DATA30 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX)) +#define GPIO_EIM_DATA31 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX)) +#define GPIO_EIM_DTACK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_WAIT_INDEX)) +#define GPIO_EIM_EB0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_EB0_INDEX)) +#define GPIO_EIM_EB1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_EB1_INDEX)) +#define GPIO_EIM_EB2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_EIM_EB3 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX)) +#define GPIO_EIM_LBA (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_LBA_INDEX)) +#define GPIO_EIM_OE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_OE_INDEX)) +#define GPIO_EIM_RW (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_RW_INDEX)) +#define GPIO_EIM_WAIT (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_EIM_WAIT_INDEX)) + +/* Ethernet */ + +#define GPIO_ENET_1588_EVENT0_IN (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA1_INDEX)) +#define GPIO_ENET_1588_EVENT0_OUT (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) +#define GPIO_ENET_1588_EVENT1_IN (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_ENET_MDC_INDEX)) +#define GPIO_ENET_1588_EVENT1_OUT (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_ENET_MDIO_INDEX)) +#define GPIO_ENET_1588_EVENT2_IN (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) +#define GPIO_ENET_1588_EVENT2_OUT (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_ER_INDEX)) +#define GPIO_ENET_1588_EVENT3_IN (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO17_INDEX)) +#define GPIO_ENET_1588_EVENT3_OUT (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA1_INDEX)) +#define GPIO_ENET_COL (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX)) +#define GPIO_ENET_CRS (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_ENET_MDC_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_MDC_INDEX)) +#define GPIO_ENET_MDC_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_ENET_MDIO_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_MDIO_INDEX)) +#define GPIO_ENET_MDIO_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX)) +#define GPIO_ENET_REF_CLK_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) +#define GPIO_ENET_REF_CLK_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_RGMII_TX_CTL_INDEX)) +#define GPIO_ENET_RX_CLK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) +#define GPIO_ENET_RX_DATA0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA0_INDEX)) +#define GPIO_ENET_RX_DATA1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA1_INDEX)) +#define GPIO_ENET_RX_DATA2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_ENET_RX_DATA3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX)) +#define GPIO_ENET_RX_EN (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_CRS_DV_INDEX)) +#define GPIO_ENET_RX_ER (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_ER_INDEX)) +#define GPIO_ENET_TX_CLK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_REF_CLK_INDEX)) +#define GPIO_ENET_TX_DATA0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA0_INDEX)) +#define GPIO_ENET_TX_DATA1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA1_INDEX)) +#define GPIO_ENET_TX_DATA2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_ENET_TX_DATA3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX)) +#define GPIO_ENET_TX_EN (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_EN_INDEX)) +#define GPIO_ENET_TX_ER (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) + +/* Enhanced Periodic Interrupt Timer (EPIT) */ + +#define GPIO_EPIT1_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) +#define GPIO_EPIT1_OUT_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_EPIT1_OUT_3 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX)) + +#define GPIO_EPIT2_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) +#define GPIO_EPIT2_OUT_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX)) + +/* Enhanced Serial Audio Interface (ESAI) */ + +#define GPIO_ESAI_RX_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) +#define GPIO_ESAI_RX_CLK_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_MDIO_INDEX)) +#define GPIO_ESAI_RX_FS_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) +#define GPIO_ESAI_RX_FS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_REF_CLK_INDEX)) +#define GPIO_ESAI_RX_HF_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_ESAI_RX_HF_CLK_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_ER_INDEX)) +#define GPIO_ESAI_TX_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO06_INDEX)) +#define GPIO_ESAI_TX_CLK_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_CRS_DV_INDEX)) +#define GPIO_ESAI_TX_FS_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO02_INDEX)) +#define GPIO_ESAI_TX_FS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA1_INDEX)) +#define GPIO_ESAI_TX_HF_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO04_INDEX)) +#define GPIO_ESAI_TX_HF_CLK_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA0_INDEX)) +#define GPIO_ESAI_TX0_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO17_INDEX)) +#define GPIO_ESAI_TX0_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_ESAI_TX1_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) +#define GPIO_ESAI_TX1_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_NAND_CS3_INDEX)) +#define GPIO_ESAI_TX2_RX3_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO05_INDEX)) +#define GPIO_ESAI_TX2_RX3_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA1_INDEX)) +#define GPIO_ESAI_TX3_RX2_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) +#define GPIO_ESAI_TX3_RX2_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_EN_INDEX)) +#define GPIO_ESAI_TX4_RX1_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) +#define GPIO_ESAI_TX4_RX1_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA0_INDEX)) +#define GPIO_ESAI_TX5_RX0_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) +#define GPIO_ESAI_TX5_RX0_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_ENET_MDC_INDEX)) + +/* Flexible Controller Area Network (FLEXCAN) */ + +#define GPIO_FLEXCAN1_RX_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_FLEXCAN1_RX_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD3_CLK_INDEX)) +#define GPIO_FLEXCAN1_RX_3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) +#define GPIO_FLEXCAN1_TX_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_FLEXCAN1_TX_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD3_CMD_INDEX)) +#define GPIO_FLEXCAN1_TX_3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) + +#define GPIO_FLEXCAN2_RX_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW4_INDEX)) +#define GPIO_FLEXCAN2_RX_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA1_INDEX)) +#define GPIO_FLEXCAN2_TX_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_COL4_INDEX)) +#define GPIO_FLEXCAN2_TX_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA0_INDEX)) + +/* General Purpose Timer (GPT) */ + +#define GPIO_GPT_CAPTURE1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA0_INDEX)) +#define GPIO_GPT_CAPTURE2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA1_INDEX)) +#define GPIO_GPT_CLKIN (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_CLK_INDEX)) +#define GPIO_GPT_COMPARE1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_CMD_INDEX)) +#define GPIO_GPT_COMPARE2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) +#define GPIO_GPT_COMPARE3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) + +/* HDMI */ + +#define GPIO_HDMI_TX_CEC_LINE_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_HDMI_TX_CEC_LINE_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_HDMI_TX_DDC_SCL_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_HDMI_TX_DDC_SCL_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_HDMI_TX_DDC_SDA_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_HDMI_TX_DDC_SDA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) + +/* High Speed Synchronous Interface (HSI) */ + +#define GPIO_HSI_RX_DATA (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD2_INDEX)) +#define GPIO_HSI_RX_FLAG (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD1_INDEX)) +#define GPIO_HSI_RX_READY (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD0_INDEX)) +#define GPIO_HSI_RX_WAKE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD3_INDEX)) +#define GPIO_HSI_TX_DATA (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD2_INDEX)) +#define GPIO_HSI_TX_FLAG (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD1_INDEX)) +#define GPIO_HSI_TX_READY (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD0_INDEX)) +#define GPIO_HSI_TX_WAKE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD3_INDEX)) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_I2C1_SCL_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_I2C1_SDA_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_I2C1_SDA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) + +#define GPIO_I2C2_SCL_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_I2C2_SCL_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_I2C2_SDA_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_I2C2_SDA_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) + +#define GPIO_I2C3_SCL_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_I2C3_SCL_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_I2C3_SCL_3 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO05_INDEX)) +#define GPIO_I2C3_SDA_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO06_INDEX)) +#define GPIO_I2C3_SDA_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_I2C3_SDA_3 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) + +/* Image Processing Unit (IPU) */ + +#define GPIO_IPU1_CSI0_DATA_EN (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA_EN_INDEX)) +#define GPIO_IPU1_CSI0_DATA00 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_IPU1_CSI0_DATA01 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_IPU1_CSI0_DATA02 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX)) +#define GPIO_IPU1_CSI0_DATA03 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX)) +#define GPIO_IPU1_CSI0_DATA04 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_IPU1_CSI0_DATA05 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_IPU1_CSI0_DATA06 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) +#define GPIO_IPU1_CSI0_DATA07 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_IPU1_CSI0_DATA08 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) +#define GPIO_IPU1_CSI0_DATA09 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_IPU1_CSI0_DATA10 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA10_INDEX)) +#define GPIO_IPU1_CSI0_DATA11 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA11_INDEX)) +#define GPIO_IPU1_CSI0_DATA12 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA12_INDEX)) +#define GPIO_IPU1_CSI0_DATA13 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA13_INDEX)) +#define GPIO_IPU1_CSI0_DATA14 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA14_INDEX)) +#define GPIO_IPU1_CSI0_DATA15 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA15_INDEX)) +#define GPIO_IPU1_CSI0_DATA16 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA16_INDEX)) +#define GPIO_IPU1_CSI0_DATA17 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA17_INDEX)) +#define GPIO_IPU1_CSI0_DATA18 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA18_INDEX)) +#define GPIO_IPU1_CSI0_DATA19 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA19_INDEX)) +#define GPIO_IPU1_CSI0_HSYNC (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_HSYNC_INDEX)) +#define GPIO_IPU1_CSI0_PIXCLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_PIXCLK_INDEX)) +#define GPIO_IPU1_CSI0_VSYNC (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_CSI0_VSYNC_INDEX)) +#define GPIO_IPU1_DI0_D0_CS (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX)) +#define GPIO_IPU1_DI0_D1_CS (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_IPU1_DI0_DISP_CLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DI0_DISP_CLK_INDEX)) +#define GPIO_IPU1_DI0_PIN01 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_IPU1_DI0_PIN02 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN02_INDEX)) +#define GPIO_IPU1_DI0_PIN03 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN03_INDEX)) +#define GPIO_IPU1_DI0_PIN04 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN04_INDEX)) +#define GPIO_IPU1_DI0_PIN05 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) +#define GPIO_IPU1_DI0_PIN06 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_IPU1_DI0_PIN07 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_IPU1_DI0_PIN08 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX)) +#define GPIO_IPU1_DI0_PIN11 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX)) +#define GPIO_IPU1_DI0_PIN12 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX)) +#define GPIO_IPU1_DI0_PIN13 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_IPU1_DI0_PIN14 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX)) +#define GPIO_IPU1_DI0_PIN15 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN15_INDEX)) +#define GPIO_IPU1_DI0_PIN16 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX)) +#define GPIO_IPU1_DI0_PIN17 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_IPU1_DI1_D0_CS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD13_INDEX)) +#define GPIO_IPU1_DI1_D0_CS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_IPU1_DI1_D1_CS (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD14_INDEX)) +#define GPIO_IPU1_DI1_DISP_CLK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR16_INDEX)) +#define GPIO_IPU1_DI1_PIN01 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD15_INDEX)) +#define GPIO_IPU1_DI1_PIN02_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD11_INDEX)) +#define GPIO_IPU1_DI1_PIN02_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX)) +#define GPIO_IPU1_DI1_PIN03_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD12_INDEX)) +#define GPIO_IPU1_DI1_PIN03_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX)) +#define GPIO_IPU1_DI1_PIN04 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD15_INDEX)) +#define GPIO_IPU1_DI1_PIN05 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_CS0_INDEX)) +#define GPIO_IPU1_DI1_PIN06 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_CS1_INDEX)) +#define GPIO_IPU1_DI1_PIN07 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_OE_INDEX)) +#define GPIO_IPU1_DI1_PIN08 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_RW_INDEX)) +#define GPIO_IPU1_DI1_PIN11 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_IPU1_DI1_PIN12 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR25_INDEX)) +#define GPIO_IPU1_DI1_PIN13 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_IPU1_DI1_PIN14 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX)) +#define GPIO_IPU1_DI1_PIN15_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD10_INDEX)) +#define GPIO_IPU1_DI1_PIN15_2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX)) +#define GPIO_IPU1_DI1_PIN16 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_BCLK_INDEX)) +#define GPIO_IPU1_DI1_PIN17 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_LBA_INDEX)) +#define GPIO_IPU1_DISP0_DATA00 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA00_INDEX)) +#define GPIO_IPU1_DISP0_DATA01 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA01_INDEX)) +#define GPIO_IPU1_DISP0_DATA02 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA02_INDEX)) +#define GPIO_IPU1_DISP0_DATA03 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA03_INDEX)) +#define GPIO_IPU1_DISP0_DATA04 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA04_INDEX)) +#define GPIO_IPU1_DISP0_DATA05 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA05_INDEX)) +#define GPIO_IPU1_DISP0_DATA06 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA06_INDEX)) +#define GPIO_IPU1_DISP0_DATA07 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA07_INDEX)) +#define GPIO_IPU1_DISP0_DATA08 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA08_INDEX)) +#define GPIO_IPU1_DISP0_DATA09 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA09_INDEX)) +#define GPIO_IPU1_DISP0_DATA10 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA10_INDEX)) +#define GPIO_IPU1_DISP0_DATA11 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA11_INDEX)) +#define GPIO_IPU1_DISP0_DATA12 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA12_INDEX)) +#define GPIO_IPU1_DISP0_DATA13 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA13_INDEX)) +#define GPIO_IPU1_DISP0_DATA14 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA14_INDEX)) +#define GPIO_IPU1_DISP0_DATA15 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA15_INDEX)) +#define GPIO_IPU1_DISP0_DATA16 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA16_INDEX)) +#define GPIO_IPU1_DISP0_DATA17 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA17_INDEX)) +#define GPIO_IPU1_DISP0_DATA18 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) +#define GPIO_IPU1_DISP0_DATA19 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_IPU1_DISP0_DATA20 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA20_INDEX)) +#define GPIO_IPU1_DISP0_DATA21 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA21_INDEX)) +#define GPIO_IPU1_DISP0_DATA22 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA22_INDEX)) +#define GPIO_IPU1_DISP0_DATA23 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA23_INDEX)) +#define GPIO_IPU1_DISP1_DATA00 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD09_INDEX)) +#define GPIO_IPU1_DISP1_DATA01 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD08_INDEX)) +#define GPIO_IPU1_DISP1_DATA02 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD07_INDEX)) +#define GPIO_IPU1_DISP1_DATA03 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD06_INDEX)) +#define GPIO_IPU1_DISP1_DATA04 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD05_INDEX)) +#define GPIO_IPU1_DISP1_DATA05 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD04_INDEX)) +#define GPIO_IPU1_DISP1_DATA06 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD03_INDEX)) +#define GPIO_IPU1_DISP1_DATA07 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD02_INDEX)) +#define GPIO_IPU1_DISP1_DATA08 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD01_INDEX)) +#define GPIO_IPU1_DISP1_DATA09 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_AD00_INDEX)) +#define GPIO_IPU1_DISP1_DATA10 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_EB1_INDEX) ) +#define GPIO_IPU1_DISP1_DATA11 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_EB0_INDEX)) +#define GPIO_IPU1_DISP1_DATA12 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR17_INDEX)) +#define GPIO_IPU1_DISP1_DATA13 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR18_INDEX)) +#define GPIO_IPU1_DISP1_DATA14 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR19_INDEX)) +#define GPIO_IPU1_DISP1_DATA15 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR20_INDEX)) +#define GPIO_IPU1_DISP1_DATA16 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR21_INDEX)) +#define GPIO_IPU1_DISP1_DATA17 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR22_INDEX)) +#define GPIO_IPU1_DISP1_DATA18 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_IPU1_DISP1_DATA19 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_IPU1_DISP1_DATA20 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX)) +#define GPIO_IPU1_DISP1_DATA21 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX)) +#define GPIO_IPU1_DISP1_DATA22 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_IPU1_DISP1_DATA23 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_IPU1_EXT_TRIG (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_IPU1_SISG0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_IPU1_SISG1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_CS3_INDEX)) +#define GPIO_IPU1_SISG2_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_IPU1_SISG2_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_IPU1_SISG3_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_IPU1_SISG3_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_IPU1_SISG4 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_COL4_INDEX)) +#define GPIO_IPU1_SISG5 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW4_INDEX)) + +#define GPIO_IPU2_CSI1_DATA_EN_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD10_INDEX)) +#define GPIO_IPU2_CSI1_DATA_EN_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX)) +#define GPIO_IPU2_CSI1_DATA00 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD09_INDEX)) +#define GPIO_IPU2_CSI1_DATA01 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD08_INDEX)) +#define GPIO_IPU2_CSI1_DATA02 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD07_INDEX)) +#define GPIO_IPU2_CSI1_DATA03 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD06_INDEX)) +#define GPIO_IPU2_CSI1_DATA04 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD05_INDEX)) +#define GPIO_IPU2_CSI1_DATA05 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD04_INDEX)) +#define GPIO_IPU2_CSI1_DATA06 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD03_INDEX)) +#define GPIO_IPU2_CSI1_DATA07 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD02_INDEX)) +#define GPIO_IPU2_CSI1_DATA08 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD01_INDEX)) +#define GPIO_IPU2_CSI1_DATA09 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD00_INDEX)) +#define GPIO_IPU2_CSI1_DATA10_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_EB1_INDEX)) +#define GPIO_IPU2_CSI1_DATA10_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_IPU2_CSI1_DATA11_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_EB0_INDEX)) +#define GPIO_IPU2_CSI1_DATA11_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_IPU2_CSI1_DATA12_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR17_INDEX)) +#define GPIO_IPU2_CSI1_DATA12_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX)) +#define GPIO_IPU2_CSI1_DATA13_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR18_INDEX)) +#define GPIO_IPU2_CSI1_DATA13_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX)) +#define GPIO_IPU2_CSI1_DATA14_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR19_INDEX)) +#define GPIO_IPU2_CSI1_DATA14_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX)) +#define GPIO_IPU2_CSI1_DATA15_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR20_INDEX)) +#define GPIO_IPU2_CSI1_DATA15_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX)) +#define GPIO_IPU2_CSI1_DATA16_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR21_INDEX)) +#define GPIO_IPU2_CSI1_DATA16_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX)) +#define GPIO_IPU2_CSI1_DATA17_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR22_INDEX)) +#define GPIO_IPU2_CSI1_DATA17_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA18_INDEX)) +#define GPIO_IPU2_CSI1_DATA18_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_IPU2_CSI1_DATA18_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA16_INDEX)) +#define GPIO_IPU2_CSI1_DATA19_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_IPU2_CSI1_DATA19_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_IPU2_CSI1_HSYNC_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD11_INDEX)) +#define GPIO_IPU2_CSI1_HSYNC_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX)) +#define GPIO_IPU2_CSI1_PIXCLK_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR16_INDEX)) +#define GPIO_IPU2_CSI1_PIXCLK_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA17_INDEX)) +#define GPIO_IPU2_CSI1_VSYNC_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_AD12_INDEX)) +#define GPIO_IPU2_CSI1_VSYNC_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX)) +#define GPIO_IPU2_DI0_DISP_CLK (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DI0_DISP_CLK_INDEX)) +#define GPIO_IPU2_DI0_PIN01 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_READY_INDEX)) +#define GPIO_IPU2_DI0_PIN02 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN02_INDEX)) +#define GPIO_IPU2_DI0_PIN03 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN03_INDEX)) +#define GPIO_IPU2_DI0_PIN04 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN04_INDEX)) +#define GPIO_IPU2_DI0_PIN15 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN15_INDEX)) +#define GPIO_IPU2_DISP0_DATA00 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA00_INDEX)) +#define GPIO_IPU2_DISP0_DATA01 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA01_INDEX)) +#define GPIO_IPU2_DISP0_DATA02 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA02_INDEX)) +#define GPIO_IPU2_DISP0_DATA03 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA03_INDEX)) +#define GPIO_IPU2_DISP0_DATA04 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA04_INDEX)) +#define GPIO_IPU2_DISP0_DATA05 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA05_INDEX)) +#define GPIO_IPU2_DISP0_DATA06 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA06_INDEX)) +#define GPIO_IPU2_DISP0_DATA07 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA07_INDEX)) +#define GPIO_IPU2_DISP0_DATA08 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA08_INDEX)) +#define GPIO_IPU2_DISP0_DATA09 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA09_INDEX)) +#define GPIO_IPU2_DISP0_DATA10 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA10_INDEX)) +#define GPIO_IPU2_DISP0_DATA11 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA11_INDEX)) +#define GPIO_IPU2_DISP0_DATA12 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA12_INDEX)) +#define GPIO_IPU2_DISP0_DATA13 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA13_INDEX)) +#define GPIO_IPU2_DISP0_DATA14 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA14_INDEX)) +#define GPIO_IPU2_DISP0_DATA15 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA15_INDEX)) +#define GPIO_IPU2_DISP0_DATA16 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA16_INDEX)) +#define GPIO_IPU2_DISP0_DATA17 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA17_INDEX)) +#define GPIO_IPU2_DISP0_DATA18 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA18_INDEX)) +#define GPIO_IPU2_DISP0_DATA19 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA19_INDEX)) +#define GPIO_IPU2_DISP0_DATA20 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA20_INDEX)) +#define GPIO_IPU2_DISP0_DATA21 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA21_INDEX)) +#define GPIO_IPU2_DISP0_DATA22 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA22_INDEX)) +#define GPIO_IPU2_DISP0_DATA23 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA23_INDEX)) +#define GPIO_IPU2_SISG0 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_IPU2_SISG1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_NAND_CS3_INDEX)) +#define GPIO_IPU2_SISG2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_IPU2_SISG3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_IPU2_SISG4 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_CLE_INDEX)) +#define GPIO_IPU2_SISG5 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_WP_INDEX)) + +/* JTAG */ + +#define GPIO_JTAG_DE (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) + +/* Keypad Port (KPP) */ + +#define GPIO_KEY_COL0 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX)) +#define GPIO_KEY_COL1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX)) +#define GPIO_KEY_COL2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_KEY_COL3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_KEY_COL4 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_COL4_INDEX)) +#define GPIO_KEY_COL5_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) +#define GPIO_KEY_COL5_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_KEY_COL5_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD2_CLK_INDEX)) +#define GPIO_KEY_COL5_4 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA04_INDEX)) +#define GPIO_KEY_COL6_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) +#define GPIO_KEY_COL6_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA3_INDEX)) +#define GPIO_KEY_COL6_3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA06_INDEX)) +#define GPIO_KEY_COL7_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO04_INDEX)) +#define GPIO_KEY_COL7_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA08_INDEX)) +#define GPIO_KEY_COL7_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA1_INDEX)) +#define GPIO_KEY_ROW0 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX)) +#define GPIO_KEY_ROW1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX)) +#define GPIO_KEY_ROW2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_KEY_ROW3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_KEY_ROW4 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW4_INDEX)) +#define GPIO_KEY_ROW5_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) +#define GPIO_KEY_ROW5_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD2_CMD_INDEX)) +#define GPIO_KEY_ROW5_3 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA05_INDEX)) +#define GPIO_KEY_ROW6_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO02_INDEX)) +#define GPIO_KEY_ROW6_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA07_INDEX)) +#define GPIO_KEY_ROW6_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA2_INDEX)) +#define GPIO_KEY_ROW7_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO05_INDEX)) +#define GPIO_KEY_ROW7_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA09_INDEX)) +#define GPIO_KEY_ROW7_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA0_INDEX)) + +/* MediaLB (MLB)*/ + +#define GPIO_MLB_CLK_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_ENET_TX_DATA1_INDEX)) +#define GPIO_MLB_CLK_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_MLB_DATA_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_ENET_MDC_INDEX)) +#define GPIO_MLB_DATA_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO02_INDEX)) +#define GPIO_MLB_SIG_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA1_INDEX)) +#define GPIO_MLB_SIG_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO06_INDEX)) + +/* NAND */ + +#define GPIO_NAND_ALE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_ALE_INDEX)) +#define GPIO_NAND_CE0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_CS0_INDEX)) +#define GPIO_NAND_CE1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_CS1_INDEX)) +#define GPIO_NAND_CE2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_CS2_INDEX)) +#define GPIO_NAND_CE3 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_CS3_INDEX)) +#define GPIO_NAND_CLE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_CLE_INDEX)) +#define GPIO_NAND_DATA00 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA00_INDEX)) +#define GPIO_NAND_DATA01 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA01_INDEX)) +#define GPIO_NAND_DATA02 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA02_INDEX)) +#define GPIO_NAND_DATA03 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA03_INDEX)) +#define GPIO_NAND_DATA04 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA04_INDEX)) +#define GPIO_NAND_DATA05 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA05_INDEX)) +#define GPIO_NAND_DATA06 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA06_INDEX)) +#define GPIO_NAND_DATA07 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA07_INDEX)) +#define GPIO_NAND_DQS (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA0_INDEX)) +#define GPIO_NAND_RE (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_CMD_INDEX)) +#define GPIO_NAND_READY (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_READY_INDEX)) +#define GPIO_NAND_WE (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_CLK_INDEX)) +#define GPIO_NAND_WP (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_NAND_WP_INDEX)) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWM1_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA08_INDEX)) +#define GPIO_PWM1_OUT_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) +#define GPIO_PWM1_OUT_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) + +#define GPIO_PWM2_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA09_INDEX)) +#define GPIO_PWM2_OUT_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) +#define GPIO_PWM2_OUT_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) + +#define GPIO_PWM3_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA1_INDEX)) +#define GPIO_PWM3_OUT_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA1_INDEX)) + +#define GPIO_PWM4_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD1_CMD_INDEX)) +#define GPIO_PWM4_OUT_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA2_INDEX)) + +/* RGMII */ + +#define GPIO_RGMII_RD0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD0_INDEX)) +#define GPIO_RGMII_RD1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD1_INDEX)) +#define GPIO_RGMII_RD2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD2_INDEX)) +#define GPIO_RGMII_RD3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RD3_INDEX)) +#define GPIO_RGMII_RX_CTL (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RX_CTL_INDEX)) +#define GPIO_RGMII_RXC (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_RXC_INDEX)) +#define GPIO_RGMII_TD0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD0_INDEX)) +#define GPIO_RGMII_TD1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD1_INDEX)) +#define GPIO_RGMII_TD2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD2_INDEX)) +#define GPIO_RGMII_TD3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TD3_INDEX)) +#define GPIO_RGMII_TX_CTL (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TX_CTL_INDEX)) +#define GPIO_RGMII_TXC (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_RGMII_TXC_INDEX)) + +/* SD card */ + +#define GPIO_SD1_CD (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) +#define GPIO_SD1_CLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_CLK_INDEX)) +#define GPIO_SD1_CMD (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_CMD_INDEX)) +#define GPIO_SD1_DATA0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA0_INDEX)) +#define GPIO_SD1_DATA1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA1_INDEX)) +#define GPIO_SD1_DATA2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) +#define GPIO_SD1_DATA3 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) +#define GPIO_SD1_DATA4 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA00_INDEX)) +#define GPIO_SD1_DATA5 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA01_INDEX)) +#define GPIO_SD1_DATA6 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA02_INDEX)) +#define GPIO_SD1_DATA7 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA03_INDEX)) +#define GPIO_SD1_LCTL (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) +#define GPIO_SD1_VSELECT_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX)) +#define GPIO_SD1_VSELECT_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_SD1_WP_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DI0_PIN04_INDEX)) +#define GPIO_SD1_WP_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) + +#define GPIO_SD2_CD (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO04_INDEX)) +#define GPIO_SD2_CLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_CLK_INDEX)) +#define GPIO_SD2_CMD (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_CMD_INDEX)) +#define GPIO_SD2_DATA0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA0_INDEX)) +#define GPIO_SD2_DATA1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA1_INDEX)) +#define GPIO_SD2_DATA2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA2_INDEX)) +#define GPIO_SD2_DATA3 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD2_DATA3_INDEX)) +#define GPIO_SD2_DATA4 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA04_INDEX)) +#define GPIO_SD2_DATA5 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA05_INDEX)) +#define GPIO_SD2_DATA6 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA06_INDEX)) +#define GPIO_SD2_DATA7 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_DATA07_INDEX)) +#define GPIO_SD2_LCTL (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO06_INDEX)) +#define GPIO_SD2_VSELECT_1 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW2_INDEX)) +#define GPIO_SD2_VSELECT_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX)) +#define GPIO_SD2_WP (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO02_INDEX)) + +#define GPIO_SD3_CLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_CLK_INDEX)) +#define GPIO_SD3_CMD (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_CMD_INDEX)) +#define GPIO_SD3_DATA0 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA0_INDEX)) +#define GPIO_SD3_DATA1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA1_INDEX)) +#define GPIO_SD3_DATA2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA2_INDEX)) +#define GPIO_SD3_DATA3 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA3_INDEX)) +#define GPIO_SD3_DATA4 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA4_INDEX)) +#define GPIO_SD3_DATA5 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA5_INDEX)) +#define GPIO_SD3_DATA6 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA6_INDEX)) +#define GPIO_SD3_DATA7 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA7_INDEX)) +#define GPIO_SD3_RESET (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD3_RESET_INDEX)) +#define GPIO_SD3_VSELECT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) +#define GPIO_SD3_VSELECT_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_NAND_CS1_INDEX)) + +#define GPIO_SD4_CLK (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD4_CLK_INDEX)) +#define GPIO_SD4_CMD (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_SD4_CMD_INDEX)) +#define GPIO_SD4_DATA0 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA0_INDEX)) +#define GPIO_SD4_DATA1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA1_INDEX)) +#define GPIO_SD4_DATA2 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA2_INDEX)) +#define GPIO_SD4_DATA3 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA3_INDEX)) +#define GPIO_SD4_DATA4 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA4_INDEX)) +#define GPIO_SD4_DATA5 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA5_INDEX)) +#define GPIO_SD4_DATA6 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA6_INDEX)) +#define GPIO_SD4_DATA7 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA7_INDEX)) +#define GPIO_SD4_RESET (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_ALE_INDEX)) +#define GPIO_SD4_VSELECT (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_NAND_CS1_INDEX)) + +/* Smart Direct Memory Access Controller (SDMA) */ + +#define GPIO_SDMA_EXT_EVENT0_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO17_INDEX)) +#define GPIO_SDMA_EXT_EVENT0_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA16_INDEX)) +#define GPIO_SDMA_EXT_EVENT1_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) +#define GPIO_SDMA_EXT_EVENT1_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA17_INDEX)) + +/* Secure Non-Volatile Storage (SNVS) */ + +#define GPIO_SNVS_VIO_5 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_SNVS_VIO_5_CTL (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO18_INDEX)) + +/* Sony/Philips Digital Interface (SPDIF) */ + +#define GPIO_SPDIF_EXT_CLK_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_RGMII_TXC_INDEX)) +#define GPIO_SPDIF_EXT_CLK_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_ENET_CRS_DV_INDEX)) +#define GPIO_SPDIF_IN_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_ER_INDEX)) +#define GPIO_SPDIF_IN_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO16_INDEX)) +#define GPIO_SPDIF_IN_3 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_COL3_INDEX)) +#define GPIO_SPDIF_IN_4 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_SPDIF_LOCK_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_ENET_MDIO_INDEX)) +#define GPIO_SPDIF_LOCK_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) +#define GPIO_SPDIF_OUT_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_GPIO19_INDEX)) +#define GPIO_SPDIF_OUT_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA0_INDEX)) +#define GPIO_SPDIF_OUT_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO17_INDEX)) +#define GPIO_SPDIF_OUT_4 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_SPDIF_SR_CLK_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_ENET_REF_CLK_INDEX)) +#define GPIO_SPDIF_SR_CLK_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) + +/* System Reset Controller (SRC) */ + +#define GPIO_SRC_BOOT_CFG00 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD00_INDEX)) +#define GPIO_SRC_BOOT_CFG01 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD01_INDEX)) +#define GPIO_SRC_BOOT_CFG02 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD02_INDEX)) +#define GPIO_SRC_BOOT_CFG03 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD03_INDEX)) +#define GPIO_SRC_BOOT_CFG04 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD04_INDEX)) +#define GPIO_SRC_BOOT_CFG05 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD05_INDEX)) +#define GPIO_SRC_BOOT_CFG06 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD06_INDEX)) +#define GPIO_SRC_BOOT_CFG07 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD07_INDEX)) +#define GPIO_SRC_BOOT_CFG08 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD08_INDEX)) +#define GPIO_SRC_BOOT_CFG09 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD09_INDEX)) +#define GPIO_SRC_BOOT_CFG10 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD10_INDEX)) +#define GPIO_SRC_BOOT_CFG11 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD11_INDEX)) +#define GPIO_SRC_BOOT_CFG12 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD12_INDEX)) +#define GPIO_SRC_BOOT_CFG13 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD13_INDEX)) +#define GPIO_SRC_BOOT_CFG14 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD14_INDEX)) +#define GPIO_SRC_BOOT_CFG15 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_AD15_INDEX)) +#define GPIO_SRC_BOOT_CFG16 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR16_INDEX)) +#define GPIO_SRC_BOOT_CFG17 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR17_INDEX)) +#define GPIO_SRC_BOOT_CFG18 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR18_INDEX)) +#define GPIO_SRC_BOOT_CFG19 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR19_INDEX)) +#define GPIO_SRC_BOOT_CFG20 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR20_INDEX)) +#define GPIO_SRC_BOOT_CFG21 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR21_INDEX)) +#define GPIO_SRC_BOOT_CFG22 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR22_INDEX)) +#define GPIO_SRC_BOOT_CFG23 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR23_INDEX)) +#define GPIO_SRC_BOOT_CFG24 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_ADDR24_INDEX)) +#define GPIO_SRC_BOOT_CFG25 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_WAIT_INDEX)) +#define GPIO_SRC_BOOT_CFG26 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_LBA_INDEX)) +#define GPIO_SRC_BOOT_CFG27 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_EB0_INDEX)) +#define GPIO_SRC_BOOT_CFG28 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_EB1_INDEX)) +#define GPIO_SRC_BOOT_CFG29 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_RW_INDEX)) +#define GPIO_SRC_BOOT_CFG30 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_EB2_INDEX)) +#define GPIO_SRC_BOOT_CFG31 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX)) + +/* UARTs */ + +#define IOMUX_UART (IOMUX_PULL_UP_100K | IOMUX_CMOS_OUTPUT | IOMUX_DRIVE_40OHM | \ + IOMUX_SLEW_FAST | IOMUX_SPEED_MEDIUM | IOMUX_SCHMITT_TRIGGER) + +#define GPIO_UART1_CTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA0_INDEX) | IOMUX_UART) +#define GPIO_UART1_CTS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA19_INDEX) | IOMUX_UART) +#define GPIO_UART1_DCD (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX) | IOMUX_UART) +#define GPIO_UART1_DSR (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX) | IOMUX_UART) +#define GPIO_UART1_DTR (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX) | IOMUX_UART) +#define GPIO_UART1_RI (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX) | IOMUX_UART) +#define GPIO_UART1_RTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA1_INDEX) | IOMUX_UART) +#define GPIO_UART1_RTS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA20_INDEX) | IOMUX_UART) +#define GPIO_UART1_RX_DATA_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA6_INDEX) | IOMUX_UART) +#define GPIO_UART1_RX_DATA_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA11_INDEX) | IOMUX_UART) +#define GPIO_UART1_TX_DATA_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA7_INDEX) | IOMUX_UART) +#define GPIO_UART1_TX_DATA_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA10_INDEX) | IOMUX_UART) + +#define GPIO_UART2_CTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_CMD_INDEX) | IOMUX_UART) +#define GPIO_UART2_CTS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA6_INDEX) | IOMUX_UART) +#define GPIO_UART2_CTS_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA28_INDEX) | IOMUX_UART) +#define GPIO_UART2_RTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_CLK_INDEX) | IOMUX_UART) +#define GPIO_UART2_RTS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA5_INDEX) | IOMUX_UART) +#define GPIO_UART2_RTS_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA29_INDEX) | IOMUX_UART) +#define GPIO_UART2_RX_DATA_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA4_INDEX) | IOMUX_UART) +#define GPIO_UART2_RX_DATA_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA4_INDEX) | IOMUX_UART) +#define GPIO_UART2_RX_DATA_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA27_INDEX) | IOMUX_UART) +#define GPIO_UART2_RX_DATA_4 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX) | IOMUX_UART) +#define GPIO_UART2_TX_DATA_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA5_INDEX) | IOMUX_UART) +#define GPIO_UART2_TX_DATA_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_DATA7_INDEX) | IOMUX_UART) +#define GPIO_UART2_TX_DATA_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA26_INDEX) | IOMUX_UART) +#define GPIO_UART2_TX_DATA_4 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX) | IOMUX_UART) + +#define GPIO_UART3_CTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_DATA3_INDEX) | IOMUX_UART) +#define GPIO_UART3_CTS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA23_INDEX) | IOMUX_UART) +#define GPIO_UART3_CTS_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX) | IOMUX_UART) +#define GPIO_UART3_RTS_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_SD3_RESET_INDEX) | IOMUX_UART) +#define GPIO_UART3_RTS_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_EB3_INDEX) | IOMUX_UART) +#define GPIO_UART3_RTS_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX) | IOMUX_UART) +#define GPIO_UART3_RX_DATA_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA25_INDEX) | IOMUX_UART) +#define GPIO_UART3_RX_DATA_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_CLK_INDEX) | IOMUX_UART) +#define GPIO_UART3_TX_DATA_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA24_INDEX) | IOMUX_UART) +#define GPIO_UART3_TX_DATA_2 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD4_CMD_INDEX) | IOMUX_UART) + +#define GPIO_UART4_CTS (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA17_INDEX) | IOMUX_UART) +#define GPIO_UART4_RTS (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA16_INDEX) | IOMUX_UART) +#define GPIO_UART4_RX_DATA_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA13_INDEX) | IOMUX_UART) +#define GPIO_UART4_RX_DATA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW0_INDEX) | IOMUX_UART) +#define GPIO_UART4_TX_DATA_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA12_INDEX) | IOMUX_UART) +#define GPIO_UART4_TX_DATA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_COL0_INDEX) | IOMUX_UART) + +#define GPIO_UART5_CTS_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA19_INDEX) | IOMUX_UART) +#define GPIO_UART5_CTS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW4_INDEX) | IOMUX_UART) +#define GPIO_UART5_RTS_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA18_INDEX) | IOMUX_UART) +#define GPIO_UART5_RTS_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_COL4_INDEX) | IOMUX_UART) +#define GPIO_UART5_RX_DATA_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA15_INDEX) | IOMUX_UART) +#define GPIO_UART5_RX_DATA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW1_INDEX) | IOMUX_UART) +#define GPIO_UART5_TX_DATA_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_CSI0_DATA14_INDEX) | IOMUX_UART) +#define GPIO_UART5_TX_DATA_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_KEY_COL1_INDEX) | IOMUX_UART) + +/* USB */ + +#define GPIO_USB_H1_OC_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA30_INDEX)) +#define GPIO_USB_H1_OC_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_USB_H1_PWR_1 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA31_INDEX)) +#define GPIO_USB_H1_PWR_2 (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_GPIO00_INDEX)) +#define GPIO_USB_H1_PWR_CTL_WAKE (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_KEY_COL2_INDEX)) +#define GPIO_USB_H2_DATA (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TXC_INDEX)) +#define GPIO_USB_H2_STROBE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_TX_CTL_INDEX)) +#define GPIO_USB_H3_DATA (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RX_CTL_INDEX)) +#define GPIO_USB_H3_STROBE (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_RGMII_RXC_INDEX)) +#define GPIO_USB_OTG_HOST_MODE (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO07_INDEX)) +#define GPIO_USB_OTG_ID_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_ER_INDEX)) +#define GPIO_USB_OTG_ID_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) +#define GPIO_USB_OTG_OC_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_COL4_INDEX)) +#define GPIO_USB_OTG_OC_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA21_INDEX)) +#define GPIO_USB_OTG_PWR_1 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW4_INDEX)) +#define GPIO_USB_OTG_PWR_2 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_EIM_DATA22_INDEX)) +#define GPIO_USB_OTG_PWR_CTL_WAKE (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) + +/* WDOGs */ + +#define GPIO_WDOG1_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO09_INDEX)) +#define GPIO_WDOG1_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA08_INDEX)) +#define GPIO_WDOG1_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) +#define GPIO_WDOG1_RESET_DEB (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA2_INDEX)) + +#define GPIO_WDOG2_1 (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO01_INDEX)) +#define GPIO_WDOG2_2 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_DISP0_DATA09_INDEX)) +#define GPIO_WDOG2_3 (GPIO_PERIPH | GPIO_ALT4 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) +#define GPIO_WDOG2_RESET_DEB (GPIO_PERIPH | GPIO_ALT6 | GPIO_PADMUX(IMX_PADMUX_SD1_DATA3_INDEX)) + +/* Crystal Osciallator */ + +#define GPIO_XTALOSC_OSC32K_32K_OUT_1 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_ENET_RX_DATA0_INDEX)) +#define GPIO_XTALOSC_OSC32K_32K_OUT_2 (GPIO_PERIPH | GPIO_ALT0 | GPIO_PADMUX(IMX_PADMUX_KEY_ROW3_INDEX)) +#define GPIO_XTALOSC_OSC32K_32K_OUT_3 (GPIO_PERIPH | GPIO_ALT2 | GPIO_PADMUX(IMX_PADMUX_SD1_CLK_INDEX)) +#define GPIO_XTALOSC_REF_CLK_24M_1 (GPIO_PERIPH | GPIO_ALT3 | GPIO_PADMUX(IMX_PADMUX_GPIO03_INDEX)) +#define GPIO_XTALOSC_REF_CLK_24M_2 (GPIO_PERIPH | GPIO_ALT7 | GPIO_PADMUX(IMX_PADMUX_RGMII_TXC_INDEX)) +#define GPIO_XTALOSC_REF_CLK_32K (GPIO_PERIPH | GPIO_ALT1 | GPIO_PADMUX(IMX_PADMUX_GPIO08_INDEX)) + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_PINMUX_H */ diff --git a/arch/arm/src/imx6/chip/imx_uart.h b/arch/arm/src/imx6/chip/imx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..8f21d9768f667da10e48ac1804558b298f6e28c8 --- /dev/null +++ b/arch/arm/src/imx6/chip/imx_uart.h @@ -0,0 +1,367 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_uart.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Reference: + * "i.MX 6Dual/6Quad ApplicationsProcessor Reference Manual," Document Number + * IMX6DQRM, Rev. 3, 07/2015, FreeScale. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_CHIP_IMX_UART_H +#define __ARCH_ARM_SRC_IMX6_CHIP_IMX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* UART Register Offsets ************************************************************/ + +#define UART_RXD_OFFSET 0x0000 /* UART receiver register */ +#define UART_TXD_OFFSET 0x0040 /* UART receiver register */ +#define UART_UCR1_OFFSET 0x0080 /* UART control register 1 */ +#define UART_UCR2_OFFSET 0x0084 /* UART control register 2 */ +#define UART_UCR3_OFFSET 0x0088 /* UART control register 3 */ +#define UART_UCR4_OFFSET 0x008c /* UART control register 4 */ +#define UART_UFCR_OFFSET 0x0090 /* UART FIFO control register */ +#define UART_USR1_OFFSET 0x0094 /* UART status register 1 */ +#define UART_USR2_OFFSET 0x0098 /* UART status register 2 */ +#define UART_UESC_OFFSET 0x009c /* UART escape character register */ +#define UART_UTIM_OFFSET 0x00a0 /* UART escape timer register */ +#define UART_UBIR_OFFSET 0x00a4 /* UART BRM incremental register */ +#define UART_UBMR_OFFSET 0x00a8 /* UART BRM modulator register */ +#define UART_UBRC_OFFSET 0x00ac /* UART baud rate counter register */ +#define UART_ONEMS_OFFSET 0x00b0 /* UART One Millisecond Register */ +#define UART_UTS_OFFSET 0x00b4 /* UART test register */ +#define UART_UMCR_OFFSET 0x00b8 /* UART RS-485 Mode Control Register */ + +/* UART Register Addresses **********************************************************/ + +#define UART1_RXD (IMX_UART1_VBASE+UART_RXD_OFFSET) +#define UART1_TXD (IMX_UART1_VBASE+UART_TXD_OFFSET) +#define UART1_UCR1 (IMX_UART1_VBASE+UART_UCR1_OFFSET) +#define UART1_UCR2 (IMX_UART1_VBASE+UART_UCR2_OFFSET) +#define UART1_UCR3 (IMX_UART1_VBASE+UART_UCR3_OFFSET) +#define UART1_UCR4 (IMX_UART1_VBASE+UART_UCR4_OFFSET) +#define UART1_UFCR (IMX_UART1_VBASE+UART_UFCR_OFFSET) +#define UART1_USR1 (IMX_UART1_VBASE+UART_USR1_OFFSET) +#define UART1_USR2 (IMX_UART1_VBASE+UART_USR2_OFFSET) +#define UART1_UESC (IMX_UART1_VBASE+UART_UESC_OFFSET) +#define UART1_UTIM (IMX_UART1_VBASE+UART_UTIM_OFFSET) +#define UART1_UBIR (IMX_UART1_VBASE+UART_UBIR_OFFSET) +#define UART1_UBMR (IMX_UART1_VBASE+UART_UBMR_OFFSET) +#define UART1_UBRC (IMX_UART1_VBASE+UART_UBRC_OFFSET) +#define UART1_ONEMS (IMX_UART1_VBASE+UART_ONEMS_OFFSET) +#define UART1_UTS (IMX_UART1_VBASE+UART_UTS_OFFSET) +#define UART1_UMCR (IMX_UART1_VBASE+UART_UMCR_OFFSET) + +#define UART2_RXD (IMX_UART2_VBASE+UART_RXD_OFFSET) +#define UART2_TXD (IMX_UART2_VBASE+UART_TXD_OFFSET) +#define UART2_UCR1 (IMX_UART2_VBASE+UART_UCR1_OFFSET) +#define UART2_UCR2 (IMX_UART2_VBASE+UART_UCR2_OFFSET) +#define UART2_UCR3 (IMX_UART2_VBASE+UART_UCR3_OFFSET) +#define UART2_UCR4 (IMX_UART2_VBASE+UART_UCR4_OFFSET) +#define UART2_UFCR (IMX_UART2_VBASE+UART_UFCR_OFFSET) +#define UART2_USR1 (IMX_UART2_VBASE+UART_USR1_OFFSET) +#define UART2_USR2 (IMX_UART2_VBASE+UART_USR2_OFFSET) +#define UART2_UESC (IMX_UART2_VBASE+UART_UESC_OFFSET) +#define UART2_UTIM (IMX_UART2_VBASE+UART_UTIM_OFFSET) +#define UART2_UBIR (IMX_UART2_VBASE+UART_UBIR_OFFSET) +#define UART2_UBMR (IMX_UART2_VBASE+UART_UBMR_OFFSET) +#define UART2_UBRC (IMX_UART2_VBASE+UART_UBRC_OFFSET) +#define UART2_ONEMS (IMX_UART2_VBASE+UART_ONEMS_OFFSET) +#define UART2_UTS (IMX_UART2_VBASE+UART_UTS_OFFSET) +#define UART2_UMCR (IMX_UART2_VBASE+UART_UMCR_OFFSET) + +#define UART3_RXD (IMX_UART3_VBASE+UART_RXD_OFFSET) +#define UART3_TXD (IMX_UART3_VBASE+UART_TXD_OFFSET) +#define UART3_UCR1 (IMX_UART3_VBASE+UART_UCR1_OFFSET) +#define UART3_UCR2 (IMX_UART3_VBASE+UART_UCR2_OFFSET) +#define UART3_UCR3 (IMX_UART3_VBASE+UART_UCR3_OFFSET) +#define UART3_UCR4 (IMX_UART3_VBASE+UART_UCR4_OFFSET) +#define UART3_UFCR (IMX_UART3_VBASE+UART_UFCR_OFFSET) +#define UART3_USR1 (IMX_UART3_VBASE+UART_USR1_OFFSET) +#define UART3_USR2 (IMX_UART3_VBASE+UART_USR2_OFFSET) +#define UART3_UESC (IMX_UART3_VBASE+UART_UESC_OFFSET) +#define UART3_UTIM (IMX_UART3_VBASE+UART_UTIM_OFFSET) +#define UART3_UBIR (IMX_UART3_VBASE+UART_UBIR_OFFSET) +#define UART3_UBMR (IMX_UART3_VBASE+UART_UBMR_OFFSET) +#define UART3_UBRC (IMX_UART3_VBASE+UART_UBRC_OFFSET) +#define UART3_ONEMS (IMX_UART3_VBASE+UART_ONEMS_OFFSET) +#define UART3_UTS (IMX_UART3_VBASE+UART_UTS_OFFSET) +#define UART3_UMCR (IMX_UART3_VBASE+UART_UMCR_OFFSET) + +#define UART4_RXD (IMX_UART4_VBASE+UART_RXD_OFFSET) +#define UART4_TXD (IMX_UART4_VBASE+UART_TXD_OFFSET) +#define UART4_UCR1 (IMX_UART4_VBASE+UART_UCR1_OFFSET) +#define UART4_UCR2 (IMX_UART4_VBASE+UART_UCR2_OFFSET) +#define UART4_UCR3 (IMX_UART4_VBASE+UART_UCR3_OFFSET) +#define UART4_UCR4 (IMX_UART4_VBASE+UART_UCR4_OFFSET) +#define UART4_UFCR (IMX_UART4_VBASE+UART_UFCR_OFFSET) +#define UART4_USR1 (IMX_UART4_VBASE+UART_USR1_OFFSET) +#define UART4_USR2 (IMX_UART4_VBASE+UART_USR2_OFFSET) +#define UART4_UESC (IMX_UART4_VBASE+UART_UESC_OFFSET) +#define UART4_UTIM (IMX_UART4_VBASE+UART_UTIM_OFFSET) +#define UART4_UBIR (IMX_UART4_VBASE+UART_UBIR_OFFSET) +#define UART4_UBMR (IMX_UART4_VBASE+UART_UBMR_OFFSET) +#define UART4_UBRC (IMX_UART4_VBASE+UART_UBRC_OFFSET) +#define UART4_ONEMS (IMX_UART4_VBASE+UART_ONEMS_OFFSET) +#define UART4_UTS (IMX_UART4_VBASE+UART_UTS_OFFSET) +#define UART4_UMCR (IMX_UART4_VBASE+UART_UMCR_OFFSET) + +#define UART5_RXD (IMX_UART5_VBASE+UART_RXD_OFFSET) +#define UART5_TXD (IMX_UART5_VBASE+UART_TXD_OFFSET) +#define UART5_UCR1 (IMX_UART5_VBASE+UART_UCR1_OFFSET) +#define UART5_UCR2 (IMX_UART5_VBASE+UART_UCR2_OFFSET) +#define UART5_UCR3 (IMX_UART5_VBASE+UART_UCR3_OFFSET) +#define UART5_UCR4 (IMX_UART5_VBASE+UART_UCR4_OFFSET) +#define UART5_UFCR (IMX_UART5_VBASE+UART_UFCR_OFFSET) +#define UART5_USR1 (IMX_UART5_VBASE+UART_USR1_OFFSET) +#define UART5_USR2 (IMX_UART5_VBASE+UART_USR2_OFFSET) +#define UART5_UESC (IMX_UART5_VBASE+UART_UESC_OFFSET) +#define UART5_UTIM (IMX_UART5_VBASE+UART_UTIM_OFFSET) +#define UART5_UBIR (IMX_UART5_VBASE+UART_UBIR_OFFSET) +#define UART5_UBMR (IMX_UART5_VBASE+UART_UBMR_OFFSET) +#define UART5_UBRC (IMX_UART5_VBASE+UART_UBRC_OFFSET) +#define UART5_ONEMS (IMX_UART5_VBASE+UART_ONEMS_OFFSET) +#define UART5_UTS (IMX_UART5_VBASE+UART_UTS_OFFSET) +#define UART5_UMCR (IMX_UART5_VBASE+UART_UMCR_OFFSET) + +/* UART Register Bit Definitions ****************************************************/ + +/* UART Receiver Register */ + +#define UART_RXD_DATA_SHIFT 0 /* Bits 0-7: Received Data */ +#define UART_RXD_DATA_MASK (0xff << UART_RXD_DATA_SHIFT) +#define UART_RXD_PRERR (1 << 10) /* Bit 10: Parity Error */ +#define UART_RXD_BRK (1 << 11) /* Bit 11: Break Detect */ +#define UART_RXD_FRMERR (1 << 12) /* Bit 12: Frame Error */ +#define UART_RXD_OVRRUN (1 << 13) /* Bit 13: Receiver Overrun */ +#define UART_RXD_ERR (1 << 14) /* Bit 14: Error Detect */ +#define UART_RXD_CHARRDY (1 << 15) /* Bit 15: Character Ready */ + +/* UART Transmitter Register */ + +#define UART_TXDATA_SHIFT 0 /* Bits 0-7: Transmit Data */ +#define UART_TXDATA_MASK (0xff << UART_UCR4_TXDATA_SHIFT) + +/* UART Control Register 1 */ + +#define UART_UCR1_UARTEN (1 << 0) /* Bit 0: Enable/disable UART */ +#define UART_UCR1_DOZE (1 << 1) /* Bit 1: UART Doze enable */ +#define UART_UCR1_ATDMAEN (1 << 2) /* Bit 2: Aging DMA Timer Enable */ +#define UART_UCR1_TXDMAEN (1 << 3) /* Bit 3: Transmitter Ready DMA Enable */ +#define UART_UCR1_SNDBRK (1 << 4) /* Bit 4: Send BREAK */ +#define UART_UCR1_RTSDEN (1 << 5) /* Bit 5: RTS Delta interrupt enable */ +#define UART_UCR1_TXEMPTYEN (1 << 6) /* Bit 6: Transmitter empty interrupt enable */ +#define UART_UCR1_IREN (1 << 7) /* Bit 7: Infrared Interface enable */ +#define UART_UCR1_RDMAEN (1 << 8) /* Bit 8: Receive ready DMA enable */ +#define UART_UCR1_RRDYEN (1 << 9) /* Bit 9: Receiver ready interrupt enable */ +#define UART_UCR1_ICD_SHIFT 10 /* Bit 10-11: Idle condition detect */ +#define UART_UCR1_ICD_MASK (3 << UART_UCR1_ICD_SHIFT) +# define UART_UCR1_ICD_4FRMS (0 << UART_UCR1_ICD_SHIFT) /* Idle for more than 4 frames */ +# define UART_UCR1_ICD_8FRMS (1 << UART_UCR1_ICD_SHIFT) /* Idle for more than 8 frames */ +# define UART_UCR1_ICD_16FRMS (2 << UART_UCR1_ICD_SHIFT) /* Idle for more than 16 frames */ +# define UART_UCR1_ICD_32FRMS (3 << UART_UCR1_ICD_SHIFT) /* Idle for more than 32 frames */ +#define UART_UCR1_IDEN (1 << 12) /* Bit 12: Idle condition detected interrupt enable */ +#define UART_UCR1_TRDYEN (1 << 13) /* Bit 13: Transmitter ready interrupt enable */ +#define UART_UCR1_ADBR (1 << 14) /* Bit 14: Automatic detection of baud rate */ +#define UART_UCR1_ADEN (1 << 15) /* Bit 15: Automatic baud rate detection interrupt enable */ + +/* UART Control Register 2 */ + +#define UART_UCR2_SRST (1 << 0) /* Bit 0: Software reset */ +#define UART_UCR2_RXEN (1 << 1) /* Bit 1: Receiver enable */ +#define UART_UCR2_TXEN (1 << 2) /* Bit 2: Transmitter enable */ +#define UART_UCR2_ATEN (1 << 3) /* Bit 2: Aging Timer Enable */ +#define UART_UCR2_RTSEN (1 << 4) /* Bit 4: RTS interrupt enable/disable */ +#define UART_UCR2_WS (1 << 5) /* Bit 5: Word size */ +#define UART_UCR2_STPB (1 << 6) /* Bit 6: Controls number of stop bits */ +#define UART_UCR2_PROE (1 << 7) /* Bit 7: Parity Odd/Even */ +#define UART_UCR2_PREN (1 << 8) /* Bit 8: Parity enable */ +#define UART_UCR2_RTEC_SHIFT 9 /* Bit 9-10: Request to send edge control */ +#define UART_UCR2_RTEC_MASK (3 << UART_UCR2_RTEC_SHIFT) +# define UART_UCR2_RTEC_RISE (0 << UART_UCR2_RTEC_SHIFT) /* Interrupt on rising edge */ +# define UART_UCR2_RTEC_FALL (1 << UART_UCR2_RTEC_SHIFT) /* Interrupt on falling edge */ +# define UART_UCR2_RTEC_BOTH (2 << UART_UCR2_RTEC_SHIFT) /* Interrupt on any edge */ +#define UART_UCR2_ESCEN (1 << 11) /* Bit 11: Escape enable */ +#define UART_UCR2_CTS (1 << 12) /* Bit 12: Clear To Send pin */ +#define UART_UCR2_CTSC (1 << 13) /* Bit 13: CTS Pin control */ +#define UART_UCR2_IRTS (1 << 14) /* Bit 14: Ignore RTS Pin */ +#define UART_UCR2_ESCI (1 << 15) /* Bit 15: Escape Sequence Interrupt Enable */ + +/* UART Control Register 3 */ + +#define UART_UCR3_ACIEN (1 << 0) /* Bit 0: Autobaud Counter Interrupt Enable */ +#define UART_UCR3_INVT (1 << 1) /* Bit 1: Inverted output */ +#define UART_UCR3_RXDMUXSEL (1 << 2) /* Bit 2: RXD muxed input selected */ +#define UART_UCR3_DTRDEN (1 << 3) /* Bit 3: Data Terminal Ready delta enable */ +#define UART_UCR3_AWAKEN (1 << 4) /* Bit 4: Asynchronous wake interrupt enable */ +#define UART_UCR3_AIRINTEN (1 << 5) /* Bit 5: Asynchronous IR Wake interrupt enable */ +#define UART_UCR3_RXDSEN (1 << 6) /* Bit 6: Receive status interrupt enable */ +#define UART_UCR3_ADNIMP (1 << 7) /* Bit 7: Autobaud Detection Not Improved */ +#define UART_UCR3_RI (1 << 8) /* Bit 8: Ring Indicator */ +#define UART_UCR3_DCD (1 << 9) /* Bit 9: Data Carrier Detect */ +#define UART_UCR3_DSR (1 << 10) /* Bit 10: Data Set Ready */ +#define UART_UCR3_FRAERREN (1 << 11) /* Bit 11: Frame error interrupt enable */ +#define UART_UCR3_PARERREN (1 << 12) /* Bit 12: Parity error interrupt enable */ +#define UART_UCR3_DTREN (1 << 13) /* Bit 13: Data Terminal Ready interrupt enable */ +#define UART_UCR3_DPEC_SHIFT (14) /* Bits 14-15: DTR/DSR interrupt edge control */ +#define UART_UCR3_DPEC_MASK (3 << UART_UCR3_DPEC_SHIFT) +# define UART1_DPEC_RISING (0 << UART_UCR3_DPEC_SHIFT) /* Interrupt on rising edge */ +# define UART1_DPEC_FALLING (1 << UART_UCR3_DPEC_SHIFT) /* Interrupt on falling edge */ +# define UART1_DPEC_BOTH (2 << UART_UCR3_DPEC_SHIFT) /* Interrupt on either edge */ + +/* UART Control Register 4 */ + +#define UART_UCR4_DREN (1 << 0) /* Bit 0: Receive data ready interrupt enable */ +#define UART_UCR4_OREN (1 << 1) /* Bit 1: Receiver overrun interrupt enable */ +#define UART_UCR4_BKEN (1 << 2) /* Bit 2: Break condition detected interrupt enable */ +#define UART_UCR4_TCEN (1 << 3) /* Bit 3: Transmit complete interrupt enable */ +#define UART_UCR4_LPBYP (1 << 4) /* Bit 4: Low Power B */ +#define UART_UCR4_IRSC (1 << 5) /* Bit 5: IR special case */ +#define UART_UCR4_IDDMAEN (1 << 6) /* Bit 6: DMA IDLE Condition Detected interrupt enable */ +#define UART_UCR4_WKEN (1 << 7) /* Bit 7: Wake interrupt enable */ +#define UART_UCR4_ENIRI (1 << 8) /* Bit 8: Serial infrared interrupt enable */ +#define UART_UCR4_INVR (1 << 9) /* Bit 9: Inverted reception */ +#define UART_UCR4_CTSTL_SHIFT 10 /* Bits 10-15: CTS trigger level */ +#define UART_UCR4_CTSTL_MASK (0x3f << UART_UCR4_CTSTL_SHIFT) +# define UART_UCR4_CTSTL(n) ((uint32_t)(n) << UART_UCR4_CTSTL_SHIFT) + +/* UART FIFO Control Register */ + +#define UART_UFCR_RXTL_SHIFT 0 /* Bits 0-6: Receiver Trigger Level */ +#define UART_UFCR_RXTL_MASK (0x3f << UART_UFCR_RXTL_SHIFT) +# define UART_UFCR_RXTL(n) ((uint32_t)(n) << UART_UFCR_RXTL_SHIFT) +#define UART_UFCR_RFDIV_SHIFT 7 /* Bits 7-9: Reference Frequency Divider */ +#define UART_UFCR_RFDIV_MASK (7 << UART_UFCR_RFDIV_SHIFT) +# define UART_UFCR_RFDIV6 (0 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 6 */ +# define UART_UFCR_RFDIV5 (1 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 5 */ +# define UART_UFCR_RFDIV4 (2 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 4 */ +# define UART_UFCR_RFDIV3 (3 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 3 */ +# define UART_UFCR_RFDIV2 (4 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 2 */ +# define UART_UFCR_RFDIV1 (5 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 1 */ +# define UART_UFCR_RFDIV7 (6 << UART_UFCR_RFDIV_SHIFT) /* Divide input clock by 7 */ +#define UART_UFCR_TXTL_SHIFT 10 /* Bits 10-15: Transmitter Trigger Level */ +#define UART_UFCR_TXTL_MASK (0x3f << UART_UFCR_TXTL_SHIFT) +# define UART_UFCR_TXTL(n) ((uint32_t)(n) << UART_UFCR_TXTL_SHIFT) + +/* UART Status 1 Register */ + +#define UART_USR1_SAD (1 << 3) /* Bit 3: RS-485 Slave Address Detected Interrupt Flag */ +#define UART_USR1_AWAKE (1 << 4) /* Bit 4: Asynchronous WAKE Interrupt Flag */ +#define UART_USR1_AIRINT (1 << 5) /* Bit 5: Asynchronous IR WAKE Interrupt Flag */ +#define UART_USR1_RXDS (1 << 6) /* Bit 6: Receiver IDLE Interrupt Flag */ +#define UART_USR1_DTRD (1 << 7) /* Bit 7: DTR Delta */ +#define UART_USR1_AGTIM (1 << 8) /* Bit 8: Aging Timer Interrupt Flag */ +#define UART_USR1_RRDY (1 << 9) /* Bit 9: RX Ready Interrupt/DMA Flag */ +#define UART_USR1_FRAMERR (1 << 10) /* Bit 10: Frame Error Interrupt Flag */ +#define UART_USR1_ESCF (1 << 11) /* Bit 11: Escape Sequence Interrupt Flag */ +#define UART_USR1_RTSD (1 << 12) /* Bit 12: RTS Delta */ +#define UART_USR1_TRDY (1 << 13) /* Bit 13: TX Ready Interrupt/DMA Flag */ +#define UART_USR1_RTSS (1 << 14) /* Bit 14: RTS_B Pin Status */ +#define UART_USR1_PARITYERR (1 << 15) /* Bit 15: Parity Error Interrupt Flag */ + +/* UART Status 2 Register */ + +#define UART_USR2_RDR (1 << 0) /* Bit 0: Receive data ready */ +#define UART_USR2_ORE (1 << 1) /* Bit 1: Overrun error */ +#define UART_USR2_BRCD (1 << 2) /* Bit 2: Break condition detected */ +#define UART_USR2_TXDC (1 << 3) /* Bit 3: Transmitter complete */ +#define UART_USR2_RTSF (1 << 4) /* Bit 4: RTS Edge Triggered Interrupt flag */ +#define UART_USR2_DCDIN (1 << 5) /* Bit 5: Data Carrier Detect Input */ +#define UART_USR2_DCDDELT (1 << 6) /* Bit 6: Data Carrier Detect Delta */ +#define UART_USR2_WAKE (1 << 7) /* Bit 7: Wake */ +#define UART_USR2_IRINT (1 << 8) /* Bit 8: Serial infrared interrupt flag */ +#define UART_USR2_RIIN (1 << 9) /* Bit 9: Ring Indicator Input */ +#define UART_USR2_RIDELT (1 << 10) /* Bit 10: Ring Indicator */ +#define UART_USR2_ACST (1 << 11) /* Bit 11: Autobaud Counter Stopped */ +#define UART_USR2_IDLE (1 << 12) /* Bit 12: Idle condition */ +#define UART_USR2_DTRF (1 << 13) /* Bit 13: DTR edge triggered interrupt flag */ +#define UART_USR2_TXFE (1 << 14) /* Bit 14: Transmit Buffer FIFO empty */ +#define UART_USR2_ADET (1 << 15) /* Bit 15: Automatic baud rate detection complete */ + +/* UART Escape Character Register */ + +#define UART_UESC_MASK 0xff /* Bits 0-7: UART Escape Character */ + +/* UART Escape Timer Register */ + +#define UART_UTIM_MASK 0xfff /* Bits 0-11: UART Escape Timer */ + +/* UART BRM Incremental Register */ + +#define UART_UBIR_MASK 0xffff /* Bits 0-15: Incremental Numerator */ + +/* UART BRM Modulator Register */ + +#define UART_UBMR_MASK 0xffff /* Bits 0-15: Modulator Denominator */ + +/* UART Baud Rate Count Register */ + +#define UART_UBRC_MASK 0xffff /* Bits 0-15: Baud Rate Count Register */ + +/* UART One Millisecond Register */ + +#define UART_ONEMS_MASK 0xffffff /* Bits 0-23: One Millisecond Register */ + +/* UART Test Register */ + +#define UART_UTS_SOFTRST (1 << 0) /* Bit 0: Software Reset */ +#define UART_UTS_RXFULL (1 << 3) /* Bit 3: RxFIFO FULL */ +#define UART_UTS_TXFULL (1 << 4) /* Bit 4: TxFIFO FULL */ +#define UART_UTS_RXEMPTY (1 << 5) /* Bit 5: RxFIFO Empty */ +#define UART_UTS_TXEMPTY (1 << 6) /* Bit 6: TxFIFO Empty */ +#define UART_UTS_RXDBG (1 << 9) /* Bit 9: RX FIFO debug mode */ +#define UART_UTS_LOOPIR (1 << 10) /* Bit 10: Loop TX and RX for IR Test (LOOPIR)*/ +#define UART_UTS_DBGEN (1 << 11) /* Bit 11: Debug enable B */ +#define UART_UTS_LOOP (1 << 12) /* Bit 12: Loop TX and RX for Test */ +#define UART_UTS_FRCPERR (1 << 13) /* Bit 13: Force Parity Error */ + +/* UART RS-485 Mode Control Register */ + +#define UART_UMCR_MDEN (1 << 0) /* Bit 0: 9-bit data or Multidrop Mode (RS-485) Enable */ +#define UART_UMCR_SLAM (1 << 1) /* Bit 1: RS-485 Slave Address Detect Mode Selection */ +#define UART_UMCR_TXB8 (1 << 2) /* Bit 2: Transmit RS-485 bit 8 */ +#define UART_UMCR_SADEN (1 << 3) /* Bit 3: RS-485 Slave Address Detected Interrupt Enable */ +#define UART_UMCR_SLADDR_SHIFT (8) /* Bits 8-15: RS-485 Slave Address Character */ +#define UART_UMCR_SLADDR_MASK (0xff << UART_UMCR_SLADDR_SHIFT) +# define UART_UMCR_SLADDR(n) ((uint32_t)(n) << UART_UMCR_SLADDR_SHIFT) + +#endif /* __ARCH_ARM_SRC_IMX6_CHIP_IMX_UART_H */ diff --git a/arch/arm/src/imx6/imx_boot.c b/arch/arm/src/imx6/imx_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..ae3cc1a123bbb041863ae7191a0be1620d6056f1 --- /dev/null +++ b/arch/arm/src/imx6/imx_boot.c @@ -0,0 +1,502 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_boot.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_PAGING +# include +#endif + +#include + +#include "chip.h" +#include "arm.h" +#include "mmu.h" +#include "cache.h" +#include "fpu.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "imx_config.h" +#include "imx_clockconfig.h" +#include "imx_memorymap.h" +#include "imx_lowputc.h" +#include "imx_serial.h" +#include "imx_boot.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Symbols defined via the linker script */ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_setupmappings + * + * Description + * Map all of the initial memory regions defined in g_section_mapping[] + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline void imx_setupmappings(void) +{ + int i; + + /* Set up each group of section mappings */ + + for (i = 0; i < g_num_mappings; i++) + { + mmu_l1_map_region(&g_section_mapping[i]); + } +} +#else +# define imx_setupmappings() +#endif + +/**************************************************************************** + * Name: imx_remap + * + * Description + * Map all of the final memory regions defined in g_operational_mapping[] + * + ****************************************************************************/ + +#ifdef NEED_SDRAM_REMAPPING +static inline void imx_remap(void) +{ + int i; + + /* Re-map each group of section */ + + for (i = 0; i < g_num_opmappings; i++) + { + mmu_l1_map_region(&g_operational_mapping[i]); + } +} +#endif + +/**************************************************************************** + * Name: imx_vectorpermissions + * + * Description: + * Set permissions on the vector mapping. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \ + defined(CONFIG_PAGING) +static void imx_vectorpermissions(uint32_t mmuflags) +{ + /* The PTE for the beginning of OCRAM is at the base of the L2 page table */ + + uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0); + + /* Mask out the old MMU flags from the page table entry. + * + * The pte might be zero the first time this function is called. + */ + + if (pte == 0) + { + pte = PG_VECT_PBASE; + } + else + { + pte &= PG_L1_PADDRMASK; + } + + /* Update the page table entry with the MMU flags and save */ + + mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags); +} +#endif + +/**************************************************************************** + * Name: imx_vectorsize + * + * Description: + * Return the size of the vector data + * + ****************************************************************************/ + +static inline size_t imx_vectorsize(void) +{ + uintptr_t src; + uintptr_t end; + + src = (uintptr_t)&_vector_start; + end = (uintptr_t)&_vector_end; + + return (size_t)(end - src); +} + +/**************************************************************************** + * Name: imx_vectormapping + * + * Description: + * Setup a special mapping for the interrupt vectors when the interrupt + * vectors are located at the high address, 0xffff0000. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_LOWVECTORS +static void imx_vectormapping(void) +{ + uint32_t vector_paddr = IMX_VECTOR_PADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_vaddr = IMX_VECTOR_VADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start; + uint32_t end_paddr = IMX_VECTOR_PADDR + vector_size; + + /* REVISIT: Cannot really assert in this context */ + + DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE); + + /* We want to keep our interrupt vectors and interrupt-related logic in + * on-chip RAM (OCRAM). The i.MX6 has 256Kb of OCRAM positioned at + * physical address 0x0090:0000; we need to map this to 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr, + MMU_L2_VECTORFLAGS); + vector_paddr += 4096; + vector_vaddr += 4096; + } + + /* Now set the level 1 descriptor to refer to the level 2 page table. */ + + mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, + IMX_VECTOR_VADDR & PMD_PTE_PADDR_MASK, + MMU_L1_VECTORFLAGS); +} +#else + /* No vector remap */ + +# define imx_vectormapping() +#endif + +/**************************************************************************** + * Name: imx_copyvectorblock + * + * Description: + * Copy the interrupt block to its final destination. Vectors are already + * positioned at the beginning of the text region and only need to be + * copied in the case where we are using high vectors or where the beginning + * of the text region cannot be remapped to address zero. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_LOWVECTORS +static void imx_copyvectorblock(void) +{ + uint32_t *src; + uint32_t *end; + uint32_t *dest; + +#ifdef CONFIG_PAGING + /* If we are using re-mapped vectors in an area that has been marked + * read only, then temporarily mark the mapping write-able (non-buffered). + */ + + imx_vectorpermissions(MMU_L2_VECTRWFLAGS); +#endif + + /* Copy the vectors into OCRAM at the address that will be mapped to the vector + * address: + * + * IMX_VECTOR_PADDR - Unmapped, physical address of vector table in OCRAM + * IMX_VECTOR_VSRAM - Virtual address of vector table in OCRAM + * IMX_VECTOR_VADDR - Virtual address of vector table (0x00000000 or + * 0xffff0000) + */ + + src = (uint32_t *)&_vector_start; + end = (uint32_t *)&_vector_end; + dest = (uint32_t *)IMX_VECTOR_VSRAM; + + while (src < end) + { + *dest++ = *src++; + } + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + /* Make the vectors read-only, cacheable again */ + + imx_vectorpermissions(MMU_L2_VECTORFLAGS); + +#else + /* Flush the DCache to assure that the vector data is in physical RAM */ + + arch_clean_dcache((uintptr_t)IMX_VECTOR_VSRAM, + (uintptr_t)IMX_VECTOR_VSRAM + imx_vectorsize()); +#endif +} + +#else +/* Don't copy the vectors */ + +# define imx_copyvectorblock() +#endif + +/**************************************************************************** + * Name: imx_wdtdisable + * + * Description: + * Disable the watchdog timer. The i.MX6 always boots with the watchdog + * timer enabled at its maximum timeout (16 seconds). The watchdog timer + * can disabled by writing to the Watchdog Mode Register (WDT_MR). The + * WDT_MR, however, can be written only one time after the CPU has been + * reset. + * + * So if no watchdog timer driver has been configured, the watchdog timer + * must be disabled as part of the start up logic. But, on the other + * hand, we must not write to the WDT_MR register if the watchdog timer + * driver is configured. In that case, some later application will + * configure the WDT and begin periodic pinging (within 16 seconds, + * hopefully). + * + ****************************************************************************/ + +#ifndef CONFIG_IMX6_WDT +static inline void imx_wdtdisable(void) +{ +# warning REVISIT WDT initialization +} +#else +# define imx_wdtdisable() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * Boot Sequence + * + * This logic may be executing in OCRAM or in external memory: CS0, DDR, + * CS1, CS2, or CS3. It may be executing in CS0 or OCRAM through the + * action of the i.MX6 "first level bootloader;" it might be executing in + * CS1-3 through the action of some second level bootloader that provides + * configuration for those memories. + * + * The system always boots from the ROM memory at address 0x0000:0000, + * starting the internal first level bootloader. That bootloader can be + * configured to work in different ways using the BMS pin and the contents + * of the Boot Sequence Configuration Register (BSC_CR). + * + * If the BMS_BIT is read "1", then the first level bootloader will + * support execution of code in the memory connected to CS0 on the EBI + * interface (presumably NOR flash). The following sequence is performed + * by the first level bootloader if BMS_BIT is "1": + * + * - The main clock is the on-chip 12 MHz RC oscillator, + * - The Static Memory Controller is configured with timing allowing + * code execution in CS0 external memory at 12 MHz + * - AXI matrix is configured to remap EBI CS0 address at 0x0 + * - 0x0000:0000 is loaded in the Program Counter register + * + * The user software in the external memory must perform the next + * operation in order to complete the clocks and SMC timings configuration + * to run at a higher clock frequency: + * + * - Enable the 32768 Hz oscillator if best accuracy is needed + * - Reprogram the SMC setup, cycle, hold, mode timing registers for EBI + * CS0, to adapt them to the new clock. + * - Program the PMC (Main Oscillator Enable or Bypass mode) + * - Program and Start the PLL + * - Switch the system clock to the new value + * + * If the BMS_BIT is read "0", then the first level bootloader will + * perform: + * + * - Basic chip initialization: XTal or external clock frequency + * detection: + * + * a. Stack Setup for ARM supervisor mode + * b. Main Oscillator Detection: The bootloader attempts to use an + * external crystal. If this is not successful, then the 12 MHz + * Fast RC internal oscillator is used as the main osciallator. + * c. Main Clock Selection: The Master Clock source is switched from + * to the main oscillator without prescaler. PCK and MCK are now + * the Main Clock. + * d. PLLA Initialization: PLLA is configured to get a PCK at 96 MHz + * and an MCK at 48 MHz. If an external clock or crystal frequency + * running at 12 MHz is found, then the PLLA is configured to allow + * USB communication. + * + * - Attempt to retrieve a valid code from external non-volatile + * memories (NVM): SPI0 CS0 Flash Boot, SD Card Boot, NAND Flash Boot, + * SPI0 CS1 Flash Boot, or TWI EEPROM Boot. Different heuristics are + * used with each media type. If a valid image is found, it is copied + * to internal OCRAM and started. + * + ****************************************************************************/ + +void up_boot(void) +{ +#ifdef CONFIG_ARCH_RAMFUNCS + const uint32_t *src; + uint32_t *dest; +#endif + + /* __start provided the basic MMU mappings for OCRAM. Now provide mappings + * for all IO regions (Including the vector region). + */ + + imx_setupmappings(); + imx_lowputc('A'); + + /* Provide a special mapping for the OCRAM interrupt vector positioned in + * high memory. + */ + + imx_vectormapping(); + imx_lowputc('B'); + +#ifdef CONFIG_ARCH_RAMFUNCS + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in OCRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs + */ + + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } + + imx_lowputc('C'); + + /* Flush the copied RAM functions into physical RAM so that will + * be available when fetched into the I-Cache. + */ + + arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs) + imx_lowputc('D'); +#endif + + /* Setup up vector block. _vector_start and _vector_end are exported from + * arm_vector.S + */ + + imx_copyvectorblock(); + imx_lowputc('E'); + + /* Disable the watchdog timer */ + + imx_wdtdisable(); + imx_lowputc('F'); + + /* Initialize clocking to settings provided by board-specific logic */ + + imx_clockconfig(); + imx_lowputc('G'); + +#ifdef CONFIG_ARCH_FPU + /* Initialize the FPU */ + + arm_fpuconfig(); + imx_lowputc('H'); +#endif + + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (PIOs, LEDs, etc). + * + * NOTE: We must use caution prior to this point to make sure that + * the logic does not access any global variables that might lie + * in SDRAM. + */ + + imx_board_initialize(); + imx_lowputc('I'); + +#ifdef NEED_SDRAM_REMAPPING + /* SDRAM was configured in a temporary state to support low-level + * initialization. Now that the SDRAM has been fully initialized, + * we can reconfigure the SDRAM in its final, fully cache-able state. + */ + + imx_remap(); + imx_lowputc('J'); +#endif + +#ifdef CONFIG_BOOT_SDRAM_DATA + /* If .data and .bss reside in SDRAM, then initialize the data sections + * now after SDRAM has been initialized. + */ + + arm_data_initialize(); + imx_lowputc('K'); +#endif + + /* Perform common, low-level chip initialization (might do nothing) */ + + imx_lowsetup(); + imx_lowputc('L'); + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization if we are going to use the serial + * driver. + */ + + imx_earlyserialinit(); + imx_lowputc('M'); +#endif + imx_lowputc('\n'); +} diff --git a/arch/arm/src/imx6/imx_boot.h b/arch/arm/src/imx6/imx_boot.h new file mode 100644 index 0000000000000000000000000000000000000000..8e63cc9e9d6005d0a80cd01f9ba85dfb2cdb26cb --- /dev/null +++ b/arch/arm/src/imx6/imx_boot.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/imx/imx_boot.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_BOOT_H +#define __ARCH_ARM_SRC_IMX6_IMX_BOOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_board_initialize + * + * Description: + * All i.MX6 architectures must provide the following entry point. This + * entry point is called early in the initialization -- after all memory + * has been configured and mapped but before any devices have been + * initialized. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void imx_board_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_IMX6_IMX_BOOT_H */ diff --git a/arch/arm/src/imx6/imx_clockconfig.c b/arch/arm/src/imx6/imx_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..68613e4c0781b362caa8aae6ee4ac573adb54bf6 --- /dev/null +++ b/arch/arm/src/imx6/imx_clockconfig.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_clockconfig.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip/imx_ccm.h" +#include "imx_config.h" +#include "imx_clockconfig.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_clockconfig + * + * Description: + * Called to initialize the i.MX6. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void imx_clockconfig(void) +{ + /* Don't change the current basic clock configuration if we are running + * from SDRAM. In this case, some bootloader logic has already configured + * clocking and SDRAM. We are pretty much committed to using things the + * way that the bootloader has left them. + * + * Clocking will be configured at 792 MHz initially when started via + * U-Boot. The Linux kernel will uses the CPU frequency scaling code + * which will switch the processor frequency between 400 MHz and 1GHz based + * on load and temperature. For now, NuttX simply leaves the clocking at + * 792MHz. + */ + +#ifndef CONFIG_IMX6_BOOT_SDRAM +# warning Missing logic +#endif +} diff --git a/arch/arm/src/imx6/imx_clockconfig.h b/arch/arm/src/imx6/imx_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..b2b52bd16a71968ed614b68c7d7cc6ba4c61ac32 --- /dev/null +++ b/arch/arm/src/imx6/imx_clockconfig.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_clockconfig.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_IMX6_IMX_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_clockconfig + * + * Description: + * Called to initialize the i.MX6. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void imx_clockconfig(void); + +#endif /* __ARCH_ARM_SRC_IMX6_IMX_CLOCKCONFIG_H */ diff --git a/arch/arm/src/imx6/imx_config.h b/arch/arm/src/imx6/imx_config.h new file mode 100644 index 0000000000000000000000000000000000000000..a2214e70038ffa52fb9978a0db2f63380c85dbf0 --- /dev/null +++ b/arch/arm/src/imx6/imx_config.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_config.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_CONFIG_H +#define __ARCH_ARM_SRC_IMX6_IMX_CONFIG_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* Is there a UART enabled? */ + +#if defined(CONFIG_IMX6_UART1) || defined(CONFIG_IMX6_UART2) || \ + defined(CONFIG_IMX6_UART3) || defined(CONFIG_IMX6_UART4) || \ + defined(CONFIG_IMX6_UART5) +# define IMX_HAVE_UART +#endif + +#undef SUPPRESS_CONSOLE_CONFIG +#ifdef CONFIG_SUPPRESS_UART_CONFIG +# define SUPPRESS_CONSOLE_CONFIG 1 +#endif + +/* Is there a serial console? It could be on UART1-5 */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_IMX6_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define IMX_HAVE_UART_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_IMX6_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define IMX_HAVE_UART_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_IMX6_UART3) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define IMX_HAVE_UART_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_IMX6_UART4) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define IMX_HAVE_UART_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_IMX6_UART5) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define IMX_HAVE_UART_CONSOLE 1 +#else +# warning "No valid CONFIG_UARTn/USARTn_SERIAL_CONSOLE Setting" +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef IMX_HAVE_UART_CONSOLE +#endif + +#endif /* __ARCH_ARM_SRC_IMX6_IMX_CONFIG_H */ diff --git a/arch/arm/src/imx6/imx_cpuinit.c b/arch/arm/src/imx6/imx_cpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..d928781408bd36060106d91dc358428931c7b492 --- /dev/null +++ b/arch/arm/src/imx6/imx_cpuinit.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_clockconfig.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "gic.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_initialize + * + * Description: + * After the CPU has been started (via up_cpu_start()) the system will + * call back into the architecture-specific code with this function on the + * thread of execution of the newly started CPU. This gives the + * architecture-specific a chance to perform ny initial, CPU-specific + * initialize on that thread. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_initialize(void) +{ + /* Initialize the Generic Interrupt Controller (GIC) for CPUn (n != 0) */ + + arm_gic_initialize(); + return OK; +} + +#endif /* CONFIG_SMP */ diff --git a/arch/arm/src/imx6/imx_gpio.c b/arch/arm/src/imx6/imx_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..ddf747545b9e698177e730af3a4c2eeaf48e418d --- /dev/null +++ b/arch/arm/src/imx6/imx_gpio.c @@ -0,0 +1,615 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_gpio.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "imx_iomuxc.h" +#include "imx_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMX_PADMUX_INVALID 255 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_gpio1_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_GPIO00_INDEX, /* GPIO1 Pin 0 */ + IMX_PADMUX_GPIO01_INDEX, /* GPIO1 Pin 1 */ + IMX_PADMUX_GPIO02_INDEX, /* GPIO1 Pin 2 */ + IMX_PADMUX_GPIO03_INDEX, /* GPIO1 Pin 3 */ + IMX_PADMUX_GPIO04_INDEX, /* GPIO1 Pin 4 */ + IMX_PADMUX_GPIO05_INDEX, /* GPIO1 Pin 5 */ + IMX_PADMUX_GPIO06_INDEX, /* GPIO1 Pin 6 */ + IMX_PADMUX_GPIO07_INDEX, /* GPIO1 Pin 7 */ + + IMX_PADMUX_GPIO08_INDEX, /* GPIO1 Pin 8 */ + IMX_PADMUX_GPIO09_INDEX, /* GPIO1 Pin 9 */ + IMX_PADMUX_SD2_CLK_INDEX, /* GPIO1 Pin 10 */ + IMX_PADMUX_SD2_CMD_INDEX, /* GPIO1 Pin 11 */ + IMX_PADMUX_SD2_DATA3_INDEX, /* GPIO1 Pin 12 */ + IMX_PADMUX_SD2_DATA2_INDEX, /* GPIO1 Pin 13 */ + IMX_PADMUX_SD2_DATA1_INDEX, /* GPIO1 Pin 14 */ + IMX_PADMUX_SD2_DATA0_INDEX, /* GPIO1 Pin 15 */ + + IMX_PADMUX_SD1_DATA0_INDEX, /* GPIO1 Pin 16 */ + IMX_PADMUX_SD1_DATA1_INDEX, /* GPIO1 Pin 17 */ + IMX_PADMUX_SD1_CMD_INDEX, /* GPIO1 Pin 18 */ + IMX_PADMUX_SD1_DATA2_INDEX, /* GPIO1 Pin 19 */ + IMX_PADMUX_SD1_CLK_INDEX, /* GPIO1 Pin 20 */ + IMX_PADMUX_SD1_DATA3_INDEX, /* GPIO1 Pin 21 */ + IMX_PADMUX_ENET_MDIO_INDEX, /* GPIO1 Pin 22 */ + IMX_PADMUX_ENET_REF_CLK_INDEX, /* GPIO1 Pin 23 */ + + IMX_PADMUX_ENET_RX_ER_INDEX, /* GPIO1 Pin 24 */ + IMX_PADMUX_ENET_CRS_DV_INDEX, /* GPIO1 Pin 25 */ + IMX_PADMUX_ENET_RX_DATA1_INDEX, /* GPIO1 Pin 26 */ + IMX_PADMUX_ENET_RX_DATA0_INDEX, /* GPIO1 Pin 27 */ + IMX_PADMUX_ENET_TX_EN_INDEX, /* GPIO1 Pin 28 */ + IMX_PADMUX_ENET_TX_DATA1_INDEX, /* GPIO1 Pin 29 */ + IMX_PADMUX_ENET_TX_DATA0_INDEX, /* GPIO1 Pin 30 */ + IMX_PADMUX_ENET_MDC_INDEX /* GPIO1 Pin 31 */ +}; + +static const uint8_t g_gpio2_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_NAND_DATA00_INDEX, /* GPIO2 Pin 0 */ + IMX_PADMUX_NAND_DATA01_INDEX, /* GPIO2 Pin 1 */ + IMX_PADMUX_NAND_DATA02_INDEX, /* GPIO2 Pin 2 */ + IMX_PADMUX_NAND_DATA03_INDEX, /* GPIO2 Pin 3 */ + IMX_PADMUX_NAND_DATA04_INDEX, /* GPIO2 Pin 4 */ + IMX_PADMUX_NAND_DATA05_INDEX, /* GPIO2 Pin 5 */ + IMX_PADMUX_NAND_DATA06_INDEX, /* GPIO2 Pin 6 */ + IMX_PADMUX_NAND_DATA07_INDEX, /* GPIO2 Pin 7 */ + + IMX_PADMUX_SD4_DATA0_INDEX, /* GPIO2 Pin 8 */ + IMX_PADMUX_SD4_DATA1_INDEX, /* GPIO2 Pin 9 */ + IMX_PADMUX_SD4_DATA2_INDEX, /* GPIO2 Pin 10 */ + IMX_PADMUX_SD4_DATA3_INDEX, /* GPIO2 Pin 11 */ + IMX_PADMUX_SD4_DATA4_INDEX, /* GPIO2 Pin 12 */ + IMX_PADMUX_SD4_DATA5_INDEX, /* GPIO2 Pin 13 */ + IMX_PADMUX_SD4_DATA6_INDEX, /* GPIO2 Pin 14 */ + IMX_PADMUX_SD4_DATA7_INDEX, /* GPIO2 Pin 15 */ + + IMX_PADMUX_EIM_ADDR22_INDEX, /* GPIO2 Pin 16 */ + IMX_PADMUX_EIM_ADDR21_INDEX, /* GPIO2 Pin 17 */ + IMX_PADMUX_EIM_ADDR20_INDEX, /* GPIO2 Pin 18 */ + IMX_PADMUX_EIM_ADDR19_INDEX, /* GPIO2 Pin 19 */ + IMX_PADMUX_EIM_ADDR18_INDEX, /* GPIO2 Pin 20 */ + IMX_PADMUX_EIM_ADDR17_INDEX, /* GPIO2 Pin 21 */ + IMX_PADMUX_EIM_ADDR16_INDEX, /* GPIO2 Pin 22 */ + IMX_PADMUX_EIM_CS0_INDEX, /* GPIO2 Pin 23 */ + + IMX_PADMUX_EIM_CS1_INDEX, /* GPIO2 Pin 24 */ + IMX_PADMUX_EIM_OE_INDEX, /* GPIO2 Pin 25 */ + IMX_PADMUX_EIM_RW_INDEX, /* GPIO2 Pin 26 */ + IMX_PADMUX_EIM_LBA_INDEX, /* GPIO2 Pin 27 */ + IMX_PADMUX_EIM_EB0_INDEX, /* GPIO2 Pin 28 */ + IMX_PADMUX_EIM_EB1_INDEX, /* GPIO2 Pin 29 */ + IMX_PADMUX_EIM_EB2_INDEX, /* GPIO2 Pin 30 */ + IMX_PADMUX_EIM_EB3_INDEX, /* GPIO2 Pin 31 */ +}; + +static const uint8_t g_gpio3_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_EIM_AD00_INDEX, /* GPIO3 Pin 0 */ + IMX_PADMUX_EIM_AD01_INDEX, /* GPIO3 Pin 1 */ + IMX_PADMUX_EIM_AD02_INDEX, /* GPIO3 Pin 2 */ + IMX_PADMUX_EIM_AD03_INDEX, /* GPIO3 Pin 3 */ + IMX_PADMUX_EIM_AD04_INDEX, /* GPIO3 Pin 4 */ + IMX_PADMUX_EIM_AD05_INDEX, /* GPIO3 Pin 5 */ + IMX_PADMUX_EIM_AD06_INDEX, /* GPIO3 Pin 6 */ + IMX_PADMUX_EIM_AD07_INDEX, /* GPIO3 Pin 7 */ + + IMX_PADMUX_EIM_AD08_INDEX, /* GPIO3 Pin 8 */ + IMX_PADMUX_EIM_AD09_INDEX, /* GPIO3 Pin 9 */ + IMX_PADMUX_EIM_AD10_INDEX, /* GPIO3 Pin 10 */ + IMX_PADMUX_EIM_AD11_INDEX, /* GPIO3 Pin 11 */ + IMX_PADMUX_EIM_AD12_INDEX, /* GPIO3 Pin 12 */ + IMX_PADMUX_EIM_AD13_INDEX, /* GPIO3 Pin 13 */ + IMX_PADMUX_EIM_AD14_INDEX, /* GPIO3 Pin 14 */ + IMX_PADMUX_EIM_AD15_INDEX, /* GPIO3 Pin 15 */ + + IMX_PADMUX_EIM_DATA16_INDEX, /* GPIO3 Pin 16 */ + IMX_PADMUX_EIM_DATA17_INDEX, /* GPIO3 Pin 17 */ + IMX_PADMUX_EIM_DATA18_INDEX, /* GPIO3 Pin 18 */ + IMX_PADMUX_EIM_DATA19_INDEX, /* GPIO3 Pin 19 */ + IMX_PADMUX_EIM_DATA20_INDEX, /* GPIO3 Pin 20 */ + IMX_PADMUX_EIM_DATA21_INDEX, /* GPIO3 Pin 21 */ + IMX_PADMUX_EIM_DATA22_INDEX, /* GPIO3 Pin 22 */ + IMX_PADMUX_EIM_DATA23_INDEX, /* GPIO3 Pin 23 */ + + IMX_PADMUX_EIM_DATA24_INDEX, /* GPIO3 Pin 24 */ + IMX_PADMUX_EIM_DATA25_INDEX, /* GPIO3 Pin 25 */ + IMX_PADMUX_EIM_DATA26_INDEX, /* GPIO3 Pin 26 */ + IMX_PADMUX_EIM_DATA27_INDEX, /* GPIO3 Pin 27 */ + IMX_PADMUX_EIM_DATA28_INDEX, /* GPIO3 Pin 28 */ + IMX_PADMUX_EIM_DATA29_INDEX, /* GPIO3 Pin 29 */ + IMX_PADMUX_EIM_DATA30_INDEX, /* GPIO3 Pin 30 */ + IMX_PADMUX_EIM_DATA31_INDEX, /* GPIO3 Pin 31 */ +}; + +static const uint8_t g_gpio4_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_INVALID, /* GPIO4 Pin 0 */ + IMX_PADMUX_INVALID, /* GPIO4 Pin 1 */ + IMX_PADMUX_INVALID, /* GPIO4 Pin 2 */ + IMX_PADMUX_INVALID, /* GPIO4 Pin 3 */ + IMX_PADMUX_INVALID, /* GPIO4 Pin 4 */ + IMX_PADMUX_GPIO19_INDEX, /* GPIO4 Pin 5 */ + IMX_PADMUX_KEY_COL0_INDEX, /* GPIO4 Pin 6 */ + IMX_PADMUX_KEY_ROW0_INDEX, /* GPIO4 Pin 7 */ + + IMX_PADMUX_KEY_COL1_INDEX, /* GPIO4 Pin 8 */ + IMX_PADMUX_KEY_ROW1_INDEX, /* GPIO4 Pin 9 */ + IMX_PADMUX_KEY_COL2_INDEX, /* GPIO4 Pin 10 */ + IMX_PADMUX_KEY_ROW2_INDEX, /* GPIO4 Pin 11 */ + IMX_PADMUX_KEY_COL3_INDEX, /* GPIO4 Pin 12 */ + IMX_PADMUX_KEY_ROW3_INDEX, /* GPIO4 Pin 13 */ + IMX_PADMUX_KEY_COL4_INDEX, /* GPIO4 Pin 14 */ + IMX_PADMUX_KEY_ROW4_INDEX, /* GPIO4 Pin 15 */ + + IMX_PADMUX_DI0_DISP_CLK_INDEX, /* GPIO4 Pin 16 */ + IMX_PADMUX_DI0_PIN15_INDEX, /* GPIO4 Pin 17 */ + IMX_PADMUX_DI0_PIN02_INDEX, /* GPIO4 Pin 18 */ + IMX_PADMUX_DI0_PIN03_INDEX, /* GPIO4 Pin 19 */ + IMX_PADMUX_DI0_PIN04_INDEX, /* GPIO4 Pin 20 */ + IMX_PADMUX_DISP0_DATA00_INDEX, /* GPIO4 Pin 21 */ + IMX_PADMUX_DISP0_DATA01_INDEX, /* GPIO4 Pin 22 */ + IMX_PADMUX_DISP0_DATA02_INDEX, /* GPIO4 Pin 23 */ + + IMX_PADMUX_DISP0_DATA03_INDEX, /* GPIO4 Pin 24 */ + IMX_PADMUX_DISP0_DATA04_INDEX, /* GPIO4 Pin 25 */ + IMX_PADMUX_DISP0_DATA05_INDEX, /* GPIO4 Pin 26 */ + IMX_PADMUX_DISP0_DATA06_INDEX, /* GPIO4 Pin 27 */ + IMX_PADMUX_DISP0_DATA07_INDEX, /* GPIO4 Pin 28 */ + IMX_PADMUX_DISP0_DATA08_INDEX, /* GPIO4 Pin 29 */ + IMX_PADMUX_DISP0_DATA09_INDEX, /* GPIO4 Pin 30 */ + IMX_PADMUX_DISP0_DATA10_INDEX, /* GPIO4 Pin 31 */ +}; + +static const uint8_t g_gpio5_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_EIM_WAIT_INDEX, /* GPIO5 Pin 0 */ + IMX_PADMUX_INVALID, /* GPIO5 Pin 1 */ + IMX_PADMUX_EIM_ADDR25_INDEX, /* GPIO5 Pin 2 */ + IMX_PADMUX_INVALID, /* GPIO5 Pin 3 */ + IMX_PADMUX_EIM_ADDR24_INDEX, /* GPIO5 Pin 4 */ + IMX_PADMUX_DISP0_DATA11_INDEX, /* GPIO5 Pin 5 */ + IMX_PADMUX_DISP0_DATA12_INDEX, /* GPIO5 Pin 6 */ + IMX_PADMUX_DISP0_DATA13_INDEX, /* GPIO5 Pin 7 */ + + IMX_PADMUX_DISP0_DATA14_INDEX, /* GPIO5 Pin 8 */ + IMX_PADMUX_DISP0_DATA15_INDEX, /* GPIO5 Pin 9 */ + IMX_PADMUX_DISP0_DATA16_INDEX, /* GPIO5 Pin 10 */ + IMX_PADMUX_DISP0_DATA17_INDEX, /* GPIO5 Pin 11 */ + IMX_PADMUX_DISP0_DATA18_INDEX, /* GPIO5 Pin 12 */ + IMX_PADMUX_DISP0_DATA19_INDEX, /* GPIO5 Pin 13 */ + IMX_PADMUX_DISP0_DATA20_INDEX, /* GPIO5 Pin 14 */ + IMX_PADMUX_DISP0_DATA21_INDEX, /* GPIO5 Pin 15 */ + + IMX_PADMUX_DISP0_DATA22_INDEX, /* GPIO5 Pin 16 */ + IMX_PADMUX_DISP0_DATA23_INDEX, /* GPIO5 Pin 17 */ + IMX_PADMUX_CSI0_PIXCLK_INDEX, /* GPIO5 Pin 18 */ + IMX_PADMUX_CSI0_HSYNC_INDEX, /* GPIO5 Pin 19 */ + IMX_PADMUX_CSI0_DATA_EN_INDEX, /* GPIO5 Pin 20 */ + IMX_PADMUX_CSI0_VSYNC_INDEX, /* GPIO5 Pin 21 */ + IMX_PADMUX_CSI0_DATA04_INDEX, /* GPIO5 Pin 22 */ + IMX_PADMUX_CSI0_DATA05_INDEX, /* GPIO5 Pin 23 */ + + IMX_PADMUX_CSI0_DATA06_INDEX, /* GPIO5 Pin 24 */ + IMX_PADMUX_CSI0_DATA07_INDEX, /* GPIO5 Pin 25 */ + IMX_PADMUX_CSI0_DATA08_INDEX, /* GPIO5 Pin 26 */ + IMX_PADMUX_CSI0_DATA09_INDEX, /* GPIO5 Pin 27 */ + IMX_PADMUX_CSI0_DATA10_INDEX, /* GPIO5 Pin 28 */ + IMX_PADMUX_CSI0_DATA11_INDEX, /* GPIO5 Pin 29 */ + IMX_PADMUX_CSI0_DATA12_INDEX, /* GPIO5 Pin 30 */ + IMX_PADMUX_CSI0_DATA13_INDEX, /* GPIO5 Pin 31 */ +}; + +static const uint8_t g_gpio6_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_CSI0_DATA14_INDEX, /* GPIO6 Pin 0 */ + IMX_PADMUX_CSI0_DATA15_INDEX, /* GPIO6 Pin 1 */ + IMX_PADMUX_CSI0_DATA16_INDEX, /* GPIO6 Pin 2 */ + IMX_PADMUX_CSI0_DATA17_INDEX, /* GPIO6 Pin 3 */ + IMX_PADMUX_CSI0_DATA18_INDEX, /* GPIO6 Pin 4 */ + IMX_PADMUX_CSI0_DATA19_INDEX, /* GPIO6 Pin 5 */ + IMX_PADMUX_EIM_ADDR23_INDEX, /* GPIO6 Pin 6 */ + IMX_PADMUX_NAND_CLE_INDEX, /* GPIO6 Pin 7 */ + + IMX_PADMUX_NAND_ALE_INDEX, /* GPIO6 Pin 8 */ + IMX_PADMUX_NAND_WP_INDEX, /* GPIO6 Pin 9 */ + IMX_PADMUX_NAND_READY_INDEX, /* GPIO6 Pin 10 */ + IMX_PADMUX_NAND_CS0_INDEX, /* GPIO6 Pin 11 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 12 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 13 */ + IMX_PADMUX_NAND_CS1_INDEX, /* GPIO6 Pin 14 */ + IMX_PADMUX_NAND_CS2_INDEX, /* GPIO6 Pin 15 */ + + IMX_PADMUX_NAND_CS3_INDEX, /* GPIO6 Pin 16 */ + IMX_PADMUX_SD3_DATA7_INDEX, /* GPIO6 Pin 17 */ + IMX_PADMUX_SD3_DATA6_INDEX, /* GPIO6 Pin 18 */ + IMX_PADMUX_RGMII_TXC_INDEX, /* GPIO6 Pin 19 */ + IMX_PADMUX_RGMII_TD0_INDEX, /* GPIO6 Pin 20 */ + IMX_PADMUX_RGMII_TD1_INDEX, /* GPIO6 Pin 21 */ + IMX_PADMUX_RGMII_TD2_INDEX, /* GPIO6 Pin 22 */ + IMX_PADMUX_RGMII_TD3_INDEX, /* GPIO6 Pin 23 */ + + IMX_PADMUX_RGMII_RX_CTL_INDEX, /* GPIO6 Pin 24 */ + IMX_PADMUX_RGMII_RD0_INDEX, /* GPIO6 Pin 25 */ + IMX_PADMUX_RGMII_TX_CTL_INDEX, /* GPIO6 Pin 26 */ + IMX_PADMUX_RGMII_RD1_INDEX, /* GPIO6 Pin 27 */ + IMX_PADMUX_RGMII_RD2_INDEX, /* GPIO6 Pin 28 */ + IMX_PADMUX_RGMII_RD3_INDEX, /* GPIO6 Pin 29 */ + IMX_PADMUX_RGMII_RXC_INDEX, /* GPIO6 Pin 30 */ + IMX_PADMUX_EIM_BCLK_INDEX, /* GPIO6 Pin 31 */ +}; + +static const uint8_t g_gpio7_padmux[IMX_GPIO_NPINS] = +{ + IMX_PADMUX_SD3_DATA5_INDEX, /* GPIO7 Pin 0 */ + IMX_PADMUX_SD3_DATA4_INDEX, /* GPIO7 Pin 1 */ + IMX_PADMUX_SD3_CMD_INDEX, /* GPIO7 Pin 2 */ + IMX_PADMUX_SD3_CLK_INDEX, /* GPIO7 Pin 3 */ + IMX_PADMUX_SD3_DATA0_INDEX, /* GPIO7 Pin 4 */ + IMX_PADMUX_SD3_DATA1_INDEX, /* GPIO7 Pin 5 */ + IMX_PADMUX_SD3_DATA2_INDEX, /* GPIO7 Pin 6 */ + IMX_PADMUX_SD3_DATA3_INDEX, /* GPIO7 Pin 7 */ + + IMX_PADMUX_SD3_RESET_INDEX, /* GPIO7 Pin 8 */ + IMX_PADMUX_SD4_CMD_INDEX, /* GPIO7 Pin 9 */ + IMX_PADMUX_SD4_CLK_INDEX, /* GPIO7 Pin 10 */ + IMX_PADMUX_GPIO16_INDEX, /* GPIO7 Pin 11 */ + IMX_PADMUX_GPIO17_INDEX, /* GPIO7 Pin 12 */ + IMX_PADMUX_GPIO18_INDEX, /* GPIO7 Pin 13 */ + IMX_PADMUX_INVALID, /* GPIO7 Pin 14 */ + IMX_PADMUX_INVALID, /* GPIO7 Pin 15 */ + + IMX_PADMUX_INVALID, /* GPIO6 Pin 16 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 17 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 18 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 19 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 20 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 21 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 22 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 23 */ + + IMX_PADMUX_INVALID, /* GPIO6 Pin 24 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 25 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 26 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 27 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 28 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 29 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 30 */ + IMX_PADMUX_INVALID, /* GPIO6 Pin 31 */ +}; + +static FAR const uint8_t *g_gpio_padmux[IMX_GPIO_NPORTS+1] = +{ + g_gpio1_padmux, /* GPIO1 */ + g_gpio2_padmux, /* GPIO2 */ + g_gpio3_padmux, /* GPIO3 */ + g_gpio4_padmux, /* GPIO4 */ + g_gpio5_padmux, /* GPIO5 */ + g_gpio6_padmux, /* GPIO6 */ + g_gpio7_padmux, /* GPIO7 */ + NULL /* GPIO8 */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_gpio_dirout + ****************************************************************************/ + +static inline void imx_gpio_dirout(int port, int pin) +{ + uint32_t regval = getreg32(IMX_GPIO_GDIR(port)); + regval |= GPIO_PIN(pin); + putreg32(regval, IMX_GPIO_GDIR(port)); +} + +/**************************************************************************** + * Name: imx_gpio_dirin + ****************************************************************************/ + +static inline void imx_gpio_dirin(int port, int pin) +{ + uint32_t regval = getreg32(IMX_GPIO_GDIR(port)); + regval &= ~GPIO_PIN(pin); + putreg32(regval, IMX_GPIO_GDIR(port)); +} + +/**************************************************************************** + * Name: imx_gpio_setoutput + ****************************************************************************/ + +static void imx_gpio_setoutput(int port, int pin, bool value) +{ + uintptr_t regaddr = IMX_GPIO_DR(port); + uint32_t regval; + + regval = getreg32(regaddr); + if (value) + { + regval |= GPIO_PIN(pin); + } + else + { + regval &= ~GPIO_PIN(pin); + } + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: imx_gpio_getinput + ****************************************************************************/ + +static inline bool imx_gpio_getinput(int port, int pin) +{ + uintptr_t regaddr = IMX_GPIO_DR(port); + uint32_t regval; + + regval = getreg32(regaddr); + return ((regval & GPIO_PIN(pin)) != 0); +} + +/**************************************************************************** + * Name: imx_gpio_configinput + ****************************************************************************/ + +static int imx_gpio_configinput(gpio_pinset_t pinset) +{ + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + FAR const uint8_t *table; + iomux_pinset_t ioset; + uintptr_t regaddr; + unsigned int index; + + /* Configure pin as in input */ + + imx_gpio_dirin(port, pin); + + /* Configure pin as a GPIO */ + + table = g_gpio_padmux[port]; + if (table == NULL) + { + return -EINVAL; + } + + index = (unsigned int)table[pin]; + if (index >= IMX_PADMUX_NREGISTERS) + { + return -EINVAL; + } + + regaddr = IMX_PADMUX_ADDRESS(index); + putreg32(PADMUX_MUXMODE_ALT5, regaddr); + + /* Configure pin pad settings */ + + index = imx_padmux_map(index); + if (index >= IMX_PADCTL_NREGISTERS) + { + return -EINVAL; + } + + regaddr = IMX_PADCTL_ADDRESS(index); + ioset = (iomux_pinset_t)((pinset & GPIO_IOMUX_MASK) >> GPIO_IOMUX_SHIFT); + return imx_iomux_configure(regaddr, ioset); +} + +/**************************************************************************** + * Name: imx_gpio_configoutput + ****************************************************************************/ + +static inline int imx_gpio_configoutput(gpio_pinset_t pinset) +{ + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + bool value = ((pinset & GPIO_OUTPUT_ONE) != 0); + + /* Set the output value */ + + imx_gpio_setoutput(port, pin, value); + + /* Convert the configured input GPIO to an output */ + + imx_gpio_dirout(port, pin); + return OK; +} + +/**************************************************************************** + * Name: imx_gpio_configperiph + ****************************************************************************/ + +static inline int imx_gpio_configperiph(gpio_pinset_t pinset) +{ + iomux_pinset_t ioset; + uintptr_t regaddr; + uint32_t regval; + uint32_t value; + unsigned int index; + + /* Configure pin as a peripheral */ + + index = ((pinset & GPIO_PADMUX_MASK) >> GPIO_PADMUX_SHIFT); + regaddr = IMX_PADMUX_ADDRESS(index); + + value = ((pinset & GPIO_ALT_MASK) >> GPIO_ALT_SHIFT); + regval = (value << PADMUX_MUXMODE_SHIFT); + + putreg32(regval, regaddr); + + /* Configure pin pad settings */ + + index = imx_padmux_map(index); + if (index >= IMX_PADCTL_NREGISTERS) + { + return -EINVAL; + } + + regaddr = IMX_PADCTL_ADDRESS(index); + ioset = (iomux_pinset_t)((pinset & GPIO_IOMUX_MASK) >> GPIO_IOMUX_SHIFT); + return imx_iomux_configure(regaddr, ioset); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_config_gpio + * + * Description: + * Configure a GPIO pin based on pin-encoded description of the pin. + * + ****************************************************************************/ + +int imx_config_gpio(gpio_pinset_t pinset) +{ + irqstate_t flags; + int ret; + + /* Configure the pin as an input initially to avoid any spurios outputs */ + + flags = enter_critical_section(); + + /* Configure based upon the pin mode */ + + switch (pinset & GPIO_MODE_MASK) + { + case GPIO_INPUT: + { + /* Configure the pin as a GPIO input */ + + ret = imx_gpio_configinput(pinset); + } + break; + + case GPIO_OUTPUT: + { + /* First coonfigure the pin as a GPIO input to avoid output + * glitches. + */ + + ret = imx_gpio_configinput(pinset); + if (ret >= 0) + { + /* Convert the input to an output */ + + ret = imx_gpio_configoutput(pinset); + } + } + break; + + case GPIO_PERIPH: + { + /* Configure the pin as a peripheral */ + + ret = imx_gpio_configperiph(pinset); + } + break; + + default: + ret = -EINVAL; + break; + } + + leave_critical_section(flags); + return ret; +} + +/************************************************************************************ + * Name: imx_gpio_write + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void imx_gpio_write(gpio_pinset_t pinset, bool value) +{ + irqstate_t flags; + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + flags = enter_critical_section(); + imx_gpio_setoutput(port, pin, value); + leave_critical_section(flags); +} + +/************************************************************************************ + * Name: imx_gpio_read + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool imx_gpio_read(gpio_pinset_t pinset) +{ + irqstate_t flags; + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + bool value; + + flags = enter_critical_section(); + value = imx_gpio_getinput(port, pin); + leave_critical_section(flags); + return value; +} diff --git a/arch/arm/src/imx6/imx_gpio.h b/arch/arm/src/imx6/imx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..2c3acd9abe28c35dc8baad9849f46c6fc9394e48 --- /dev/null +++ b/arch/arm/src/imx6/imx_gpio.h @@ -0,0 +1,301 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_gpio.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_GPIO_H +#define __ARCH_ARM_SRC_IMX6_IMX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip/imx_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* 32-bit Encoding: + * + * ENCODING IIXX XXXX XXXX XXXX MMMM MMMM MMMM MMMM + * GPIO INPUT 00.. .... GGGP PPPP MMMM MMMM MMMM MMMM + * GPIO OUTPUT 01V. .... GGGP PPPP MMMM MMMM MMMM MMMM + * PERIPHERAL 10AA A... IIII IIII MMMM MMMM MMMM MMMM + */ + +/* Input/Output Selection: + * + * ENCODING II.. .... .... .... .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (30) /* Bits 30-31: Pin mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* GPIO input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* GPIO output */ +# define GPIO_PERIPH (2 << GPIO_MODE_SHIFT) /* Peripheral */ + +/* Initial Ouptut Value: + * + * GPIO OUTPUT 01V. .... .... .... .... .... .... .... + */ + +#define GPIO_OUTPUT_ZERO (0) /* Bit 29: 0=Initial output is low */ +#define GPIO_OUTPUT_ONE (1 << 29) /* Bit 29: 1=Initial output is high */ + +/* GPIO Port Number + * + * GPIO INPUT 00.. .... GGG. .... .... .... .... .... + * GPIO OUTPUT 01.. .... GGG. .... .... .... .... .... + */ + +#define GPIO_PORT_SHIFT (21) /* Bits 21-23: GPIO port index */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT1 (0 << GPIO_PORT_SHIFT) /* GPIO1 */ +# define GPIO_PORT2 (1 << GPIO_PORT_SHIFT) /* GPIO2 */ +# define GPIO_PORT3 (2 << GPIO_PORT_SHIFT) /* GPIO3 */ +# define GPIO_PORT4 (3 << GPIO_PORT_SHIFT) /* GPIO4 */ +# define GPIO_PORT5 (4 << GPIO_PORT_SHIFT) /* GPIO5 */ +# define GPIO_PORT6 (5 << GPIO_PORT_SHIFT) /* GPIO6 */ +# define GPIO_PORT7 (6 << GPIO_PORT_SHIFT) /* GPIO7 */ + +/* GPIO Pin Number: + * + * GPIO INPUT 00.. .... ...P PPPP .... .... .... .... + * GPIO OUTPUT 01.. .... ...P PPPP .... .... .... .... + */ + +#define GPIO_PIN_SHIFT (16) /* Bits 16-20: GPIO pin number */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) /* Pin 0 */ +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) /* Pin 1 */ +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) /* Pin 2 */ +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) /* Pin 3 */ +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) /* Pin 4 */ +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) /* Pin 5 */ +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) /* Pin 6 */ +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) /* Pin 7 */ +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) /* Pin 8 */ +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) /* Pin 9 */ +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) /* Pin 10 */ +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) /* Pin 11 */ +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) /* Pin 12 */ +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) /* Pin 13 */ +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) /* Pin 14 */ +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) /* Pin 15 */ +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) /* Pin 16 */ +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) /* Pin 17 */ +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) /* Pin 18 */ +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) /* Pin 19 */ +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) /* Pin 20 */ +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) /* Pin 21 */ +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) /* Pin 22 */ +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) /* Pin 23 */ +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) /* Pin 24 */ +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) /* Pin 25 */ +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) /* Pin 26 */ +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) /* Pin 27 */ +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) /* Pin 28 */ +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) /* Pin 29 */ +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) /* Pin 30 */ +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) /* Pin 31 */ + +/* Peripheral Alternate Function: + * + * PERIPHERAL 10AA A... .... .... MMMM MMMM MMMM MMMM + */ + +#define GPIO_ALT_SHIFT (27) /* Bits 27-29: Peripheral alternate function */ +#define GPIO_ALT_MASK (15 << GPIO_ALT_SHIFT) +# define GPIO_ALT0 (0 << GPIO_ALT_SHIFT) /* Alternate function 1 */ +# define GPIO_ALT1 (1 << GPIO_ALT_SHIFT) /* Alternate function 2 */ +# define GPIO_ALT2 (2 << GPIO_ALT_SHIFT) /* Alternate function 3 */ +# define GPIO_ALT3 (3 << GPIO_ALT_SHIFT) /* Alternate function 4 */ +# define GPIO_ALT4 (4 << GPIO_ALT_SHIFT) /* Alternate function 5 */ + /* Alternate function 5 is GPIO */ +# define GPIO_ALT6 (6 << GPIO_ALT_SHIFT) /* Alternate function 1 */ +# define GPIO_ALT7 (7 << GPIO_ALT_SHIFT) /* Alternate function 1 */ + +/* Pad Mux Register Index: + * + * PERIPHERAL 10.. .... IIII IIII MMMM MMMM MMMM MMMM + */ + +#define GPIO_PADMUX_SHIFT (16) /* Bits 16-23: Peripheral alternate function */ +#define GPIO_PADMUX_MASK (0xff << GPIO_PADMUX_SHIFT) +# define GPIO_PADMUX(n) ((uint32_t)(n) << GPIO_PADMUX_SHIFT) + +/* IOMUX Pin Configuration: + * + * ENCODING .... .... .... .... MMMM MMMM MMMM MMMM + * + * See imx_iomuxc.h for detailed content. + */ + +#define GPIO_IOMUX_SHIFT (0) /* Bits 9-15: IOMUX pin configuration */ +#define GPIO_IOMUX_MASK (0xffff << GPIO_IOMUX_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* The smallest integer type that can hold the GPIO encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: imx_gpioirq_initialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_IMX6_GPIO_IRQ +void imx_gpioirq_initialize(void); +#else +# define imx_gpio_irqinitialize() +#endif + +/************************************************************************************ + * Name: imx_config_gpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int imx_config_gpio(gpio_pinset_t pinset); + +/************************************************************************************ + * Name: imx_gpio_write + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void imx_gpio_write(gpio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: imx_gpio_read + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool imx_gpio_read(gpio_pinset_t pinset); + +/************************************************************************************ + * Name: imx_gpioirq + * + * Description: + * Configure an interrupt for the specified GPIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_IMX6_GPIO_IRQ +void imx_gpioirq(gpio_pinset_t pinset); +#else +# define imx_gpioirq(pinset) +#endif + +/************************************************************************************ + * Name: imx_gpioirq_enable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_IMX6_GPIO_IRQ +void imx_gpioirq_enable(int irq); +#else +# define imx_gpioirq_enable(irq) +#endif + +/************************************************************************************ + * Name: imx_gpioirq_disable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_IMX6_GPIO_IRQ +void imx_gpioirq_disable(int irq); +#else +# define imx_gpioirq_disable(irq) +#endif + +/************************************************************************************ + * Function: imx_dump_gpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int imx_dump_gpio(uint32_t pinset, const char *msg); +#else +# define imx_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ARCH_ARM_SRC_IMX6_IMX_GPIO_H */ diff --git a/arch/arm/src/imx6/imx_iomuxc.c b/arch/arm/src/imx6/imx_iomuxc.c new file mode 100644 index 0000000000000000000000000000000000000000..8d7562b4d17b16fdc554626f499ec9d75afc25b2 --- /dev/null +++ b/arch/arm/src/imx6/imx_iomuxc.c @@ -0,0 +1,428 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_irq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" +#include "imx_iomuxc.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This table is indexed by the Pad Mux register index and provides the index + * to the corresponding Pad Control register. + * + * REVISIT: This could be greatly simplified: The Pad Control registers + * map 1-to-1 with the Pad Mux registers except for two regions where + * there are no corresponding Pad Mux registers. The entire table could be + * replaced to two range checks and the appropriate offset added to the Pad + * Mux Register index. + */ + +static const uint8_t g_mux2ctl_map[IMX_PADMUX_NREGISTERS] = +{ + /* The first mappings are simple 1-to-1 mappings. This may be a little wasteful */ + + IMX_PADCTL_SD2_DATA1_INDEX, /* IMX_PADMUX_SD2_DATA1_INDEX */ + IMX_PADCTL_SD2_DATA2_INDEX, /* IMX_PADMUX_SD2_DATA2_INDEX */ + IMX_PADCTL_SD2_DATA0_INDEX, /* IMX_PADMUX_SD2_DATA0_INDEX */ + IMX_PADCTL_RGMII_TXC_INDEX, /* IMX_PADMUX_RGMII_TXC_INDEX */ + IMX_PADCTL_RGMII_TD0_INDEX, /* IMX_PADMUX_RGMII_TD0_INDEX */ + IMX_PADCTL_RGMII_TD1_INDEX, /* IMX_PADMUX_RGMII_TD1_INDEX */ + IMX_PADCTL_RGMII_TD2_INDEX, /* IMX_PADMUX_RGMII_TD2_INDEX */ + IMX_PADCTL_RGMII_TD3_INDEX, /* IMX_PADMUX_RGMII_TD3_INDEX */ + IMX_PADCTL_RGMII_RX_CTL_INDEX, /* IMX_PADMUX_RGMII_RX_CTL_INDEX */ + IMX_PADCTL_RGMII_RD0_INDEX, /* IMX_PADMUX_RGMII_RD0_INDEX */ + IMX_PADCTL_RGMII_TX_CTL_INDEX, /* IMX_PADMUX_RGMII_TX_CTL_INDEX */ + IMX_PADCTL_RGMII_RD1_INDEX, /* IMX_PADMUX_RGMII_RD1_INDEX */ + IMX_PADCTL_RGMII_RD2_INDEX, /* IMX_PADMUX_RGMII_RD2_INDEX */ + IMX_PADCTL_RGMII_RD3_INDEX, /* IMX_PADMUX_RGMII_RD3_INDEX */ + IMX_PADCTL_RGMII_RXC_INDEX, /* IMX_PADMUX_RGMII_RXC_INDEX */ + IMX_PADCTL_EIM_ADDR25_INDEX, /* IMX_PADMUX_EIM_ADDR25_INDEX */ + IMX_PADCTL_EIM_EB2_INDEX, /* IMX_PADMUX_EIM_EB2_INDEX */ + IMX_PADCTL_EIM_DATA16_INDEX, /* IMX_PADMUX_EIM_DATA16_INDEX */ + IMX_PADCTL_EIM_DATA17_INDEX, /* IMX_PADMUX_EIM_DATA17_INDEX */ + IMX_PADCTL_EIM_DATA18_INDEX, /* IMX_PADMUX_EIM_DATA18_INDEX */ + IMX_PADCTL_EIM_DATA19_INDEX, /* IMX_PADMUX_EIM_DATA19_INDEX */ + IMX_PADCTL_EIM_DATA20_INDEX, /* IMX_PADMUX_EIM_DATA20_INDEX */ + IMX_PADCTL_EIM_DATA21_INDEX, /* IMX_PADMUX_EIM_DATA21_INDEX */ + IMX_PADCTL_EIM_DATA22_INDEX, /* IMX_PADMUX_EIM_DATA22_INDEX */ + IMX_PADCTL_EIM_DATA23_INDEX, /* IMX_PADMUX_EIM_DATA23_INDEX */ + IMX_PADCTL_EIM_EB3_INDEX, /* IMX_PADMUX_EIM_EB3_INDEX */ + IMX_PADCTL_EIM_DATA24_INDEX, /* IMX_PADMUX_EIM_DATA24_INDEX */ + IMX_PADCTL_EIM_DATA25_INDEX, /* IMX_PADMUX_EIM_DATA25_INDEX */ + IMX_PADCTL_EIM_DATA26_INDEX, /* IMX_PADMUX_EIM_DATA26_INDEX */ + IMX_PADCTL_EIM_DATA27_INDEX, /* IMX_PADMUX_EIM_DATA27_INDEX */ + IMX_PADCTL_EIM_DATA28_INDEX, /* IMX_PADMUX_EIM_DATA28_INDEX */ + IMX_PADCTL_EIM_DATA29_INDEX, /* IMX_PADMUX_EIM_DATA29_INDEX */ + IMX_PADCTL_EIM_DATA30_INDEX, /* IMX_PADMUX_EIM_DATA30_INDEX */ + IMX_PADCTL_EIM_DATA31_INDEX, /* IMX_PADMUX_EIM_DATA31_INDEX */ + IMX_PADCTL_EIM_ADDR24_INDEX, /* IMX_PADMUX_EIM_ADDR24_INDEX */ + IMX_PADCTL_EIM_ADDR23_INDEX, /* IMX_PADMUX_EIM_ADDR23_INDEX */ + IMX_PADCTL_EIM_ADDR22_INDEX, /* IMX_PADMUX_EIM_ADDR22_INDEX */ + IMX_PADCTL_EIM_ADDR21_INDEX, /* IMX_PADMUX_EIM_ADDR21_INDEX */ + IMX_PADCTL_EIM_ADDR20_INDEX, /* IMX_PADMUX_EIM_ADDR20_INDEX */ + IMX_PADCTL_EIM_ADDR19_INDEX, /* IMX_PADMUX_EIM_ADDR19_INDEX */ + IMX_PADCTL_EIM_ADDR18_INDEX, /* IMX_PADMUX_EIM_ADDR18_INDEX */ + IMX_PADCTL_EIM_ADDR17_INDEX, /* IMX_PADMUX_EIM_ADDR17_INDEX */ + IMX_PADCTL_EIM_ADDR16_INDEX, /* IMX_PADMUX_EIM_ADDR16_INDEX */ + IMX_PADCTL_EIM_CS0_INDEX, /* IMX_PADMUX_EIM_CS0_INDEX */ + IMX_PADCTL_EIM_CS1_INDEX, /* IMX_PADMUX_EIM_CS1_INDEX */ + IMX_PADCTL_EIM_OE_INDEX, /* IMX_PADMUX_EIM_OE_INDEX */ + IMX_PADCTL_EIM_RW_INDEX, /* IMX_PADMUX_EIM_RW_INDEX */ + IMX_PADCTL_EIM_LBA_INDEX, /* IMX_PADMUX_EIM_LBA_INDEX */ + IMX_PADCTL_EIM_EB0_INDEX, /* IMX_PADMUX_EIM_EB0_INDEX */ + IMX_PADCTL_EIM_EB1_INDEX, /* IMX_PADMUX_EIM_EB1_INDEX */ + IMX_PADCTL_EIM_AD00_INDEX, /* IMX_PADMUX_EIM_AD00_INDEX */ + IMX_PADCTL_EIM_AD01_INDEX, /* IMX_PADMUX_EIM_AD01_INDEX */ + IMX_PADCTL_EIM_AD02_INDEX, /* IMX_PADMUX_EIM_AD02_INDEX */ + IMX_PADCTL_EIM_AD03_INDEX, /* IMX_PADMUX_EIM_AD03_INDEX */ + IMX_PADCTL_EIM_AD04_INDEX, /* IMX_PADMUX_EIM_AD04_INDEX */ + IMX_PADCTL_EIM_AD05_INDEX, /* IMX_PADMUX_EIM_AD05_INDEX */ + IMX_PADCTL_EIM_AD06_INDEX, /* IMX_PADMUX_EIM_AD06_INDEX */ + IMX_PADCTL_EIM_AD07_INDEX, /* IMX_PADMUX_EIM_AD07_INDEX */ + IMX_PADCTL_EIM_AD08_INDEX, /* IMX_PADMUX_EIM_AD08_INDEX */ + IMX_PADCTL_EIM_AD09_INDEX, /* IMX_PADMUX_EIM_AD09_INDEX */ + IMX_PADCTL_EIM_AD10_INDEX, /* IMX_PADMUX_EIM_AD10_INDEX */ + IMX_PADCTL_EIM_AD11_INDEX, /* IMX_PADMUX_EIM_AD11_INDEX */ + IMX_PADCTL_EIM_AD12_INDEX, /* IMX_PADMUX_EIM_AD12_INDEX */ + IMX_PADCTL_EIM_AD13_INDEX, /* IMX_PADMUX_EIM_AD13_INDEX */ + IMX_PADCTL_EIM_AD14_INDEX, /* IMX_PADMUX_EIM_AD14_INDEX */ + IMX_PADCTL_EIM_AD15_INDEX, /* IMX_PADMUX_EIM_AD15_INDEX */ + IMX_PADCTL_EIM_WAIT_INDEX, /* IMX_PADMUX_EIM_WAIT_INDEX */ + IMX_PADCTL_EIM_BCLK_INDEX, /* IMX_PADMUX_EIM_BCLK_INDEX */ + IMX_PADCTL_DI0_DISP_CLK_INDEX, /* IMX_PADMUX_DI0_DISP_CLK_INDEX */ + IMX_PADCTL_DI0_PIN15_INDEX, /* IMX_PADMUX_DI0_PIN15_INDEX */ + IMX_PADCTL_DI0_PIN02_INDEX, /* IMX_PADMUX_DI0_PIN02_INDEX */ + IMX_PADCTL_DI0_PIN03_INDEX, /* IMX_PADMUX_DI0_PIN03_INDEX */ + IMX_PADCTL_DI0_PIN04_INDEX, /* IMX_PADMUX_DI0_PIN04_INDEX */ + IMX_PADCTL_DISP0_DATA00_INDEX, /* IMX_PADMUX_DISP0_DATA00_INDEX */ + IMX_PADCTL_DISP0_DATA01_INDEX, /* IMX_PADMUX_DISP0_DATA01_INDEX */ + IMX_PADCTL_DISP0_DATA02_INDEX, /* IMX_PADMUX_DISP0_DATA02_INDEX */ + IMX_PADCTL_DISP0_DATA03_INDEX, /* IMX_PADMUX_DISP0_DATA03_INDEX */ + IMX_PADCTL_DISP0_DATA04_INDEX, /* IMX_PADMUX_DISP0_DATA04_INDEX */ + IMX_PADCTL_DISP0_DATA05_INDEX, /* IMX_PADMUX_DISP0_DATA05_INDEX */ + IMX_PADCTL_DISP0_DATA06_INDEX, /* IMX_PADMUX_DISP0_DATA06_INDEX */ + IMX_PADCTL_DISP0_DATA07_INDEX, /* IMX_PADMUX_DISP0_DATA07_INDEX */ + IMX_PADCTL_DISP0_DATA08_INDEX, /* IMX_PADMUX_DISP0_DATA08_INDEX */ + IMX_PADCTL_DISP0_DATA09_INDEX, /* IMX_PADMUX_DISP0_DATA09_INDEX */ + IMX_PADCTL_DISP0_DATA10_INDEX, /* IMX_PADMUX_DISP0_DATA10_INDEX */ + IMX_PADCTL_DISP0_DATA11_INDEX, /* IMX_PADMUX_DISP0_DATA11_INDEX */ + IMX_PADCTL_DISP0_DATA12_INDEX, /* IMX_PADMUX_DISP0_DATA12_INDEX */ + IMX_PADCTL_DISP0_DATA13_INDEX, /* IMX_PADMUX_DISP0_DATA13_INDEX */ + IMX_PADCTL_DISP0_DATA14_INDEX, /* IMX_PADMUX_DISP0_DATA14_INDEX */ + IMX_PADCTL_DISP0_DATA15_INDEX, /* IMX_PADMUX_DISP0_DATA15_INDEX */ + + + IMX_PADCTL_DISP0_DATA16_INDEX, /* IMX_PADMUX_DISP0_DATA16_INDEX */ + IMX_PADCTL_DISP0_DATA17_INDEX, /* IMX_PADMUX_DISP0_DATA17_INDEX */ + IMX_PADCTL_DISP0_DATA18_INDEX, /* IMX_PADMUX_DISP0_DATA18_INDEX */ + IMX_PADCTL_DISP0_DATA19_INDEX, /* IMX_PADMUX_DISP0_DATA19_INDEX */ + IMX_PADCTL_DISP0_DATA20_INDEX, /* IMX_PADMUX_DISP0_DATA20_INDEX */ + IMX_PADCTL_DISP0_DATA21_INDEX, /* IMX_PADMUX_DISP0_DATA21_INDEX */ + IMX_PADCTL_DISP0_DATA22_INDEX, /* IMX_PADMUX_DISP0_DATA22_INDEX */ + IMX_PADCTL_DISP0_DATA23_INDEX, /* IMX_PADMUX_DISP0_DATA23_INDEX */ + IMX_PADCTL_ENET_MDIO_INDEX, /* IMX_PADMUX_ENET_MDIO_INDEX */ + IMX_PADCTL_ENET_REF_CLK_INDEX, /* IMX_PADMUX_ENET_REF_CLK_INDEX */ + IMX_PADCTL_ENET_RX_ER_INDEX, /* IMX_PADMUX_ENET_RX_ER_INDEX */ + IMX_PADCTL_ENET_CRS_DV_INDEX, /* IMX_PADMUX_ENET_CRS_DV_INDEX */ + IMX_PADCTL_ENET_RX_DATA1_INDEX, /* IMX_PADMUX_ENET_RX_DATA1_INDEX */ + IMX_PADCTL_ENET_RX_DATA0_INDEX, /* IMX_PADMUX_ENET_RX_DATA0_INDEX */ + IMX_PADCTL_ENET_TX_EN_INDEX, /* IMX_PADMUX_ENET_TX_EN_INDEX */ + IMX_PADCTL_ENET_TX_DATA1_INDEX, /* IMX_PADMUX_ENET_TX_DATA1_INDEX */ + IMX_PADCTL_ENET_TX_DATA0_INDEX, /* IMX_PADMUX_ENET_TX_DATA0_INDEX */ + IMX_PADCTL_ENET_MDC_INDEX, /* IMX_PADMUX_ENET_MDC_INDEX */ + + /* There is then a group of Pad Control registers with no Pad Mux register counterpart */ + + /* IMX_PADCTL_DRAM_SDQS5_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM5_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM4_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS4_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS3_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM3_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS2_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM2_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR00_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR01_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR02_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR03_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR04_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR05_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR06_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR07_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR08_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR09_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR10_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR11_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR12_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR13_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR14_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ADDR15_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_CAS_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_CS0_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_CS1_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_RAS_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_RESET_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDBA0_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDBA1_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDCLK0_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDBA2_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDCKE0_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDCLK1_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDCKE1_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ODT0_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_ODT1_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDWE_B_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS0_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM0_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS1_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM1_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS6_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM6_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_SDQS7_P_INDEX - No counterpart */ + /* IMX_PADCTL_DRAM_DQM7_INDEX - No counterpart */ + + /* The mapping is again 1-to-1 with an offset for the above registers that + * have no Pad Mux register counterpart. + */ + + IMX_PADCTL_KEY_COL0_INDEX, /* IMX_PADMUX_KEY_COL0_INDEX */ + IMX_PADCTL_KEY_ROW0_INDEX, /* IMX_PADMUX_KEY_ROW0_INDEX */ + IMX_PADCTL_KEY_COL1_INDEX, /* IMX_PADMUX_KEY_COL1_INDEX */ + IMX_PADCTL_KEY_ROW1_INDEX, /* IMX_PADMUX_KEY_ROW1_INDEX */ + IMX_PADCTL_KEY_COL2_INDEX, /* IMX_PADMUX_KEY_COL2_INDEX */ + IMX_PADCTL_KEY_ROW2_INDEX, /* IMX_PADMUX_KEY_ROW2_INDEX */ + IMX_PADCTL_KEY_COL3_INDEX, /* IMX_PADMUX_KEY_COL3_INDEX */ + IMX_PADCTL_KEY_ROW3_INDEX, /* IMX_PADMUX_KEY_ROW3_INDEX */ + IMX_PADCTL_KEY_COL4_INDEX, /* IMX_PADMUX_KEY_COL4_INDEX */ + IMX_PADCTL_KEY_ROW4_INDEX, /* IMX_PADMUX_KEY_ROW4_INDEX */ + IMX_PADCTL_GPIO00_INDEX, /* IMX_PADMUX_GPIO00_INDEX */ + IMX_PADCTL_GPIO01_INDEX, /* IMX_PADMUX_GPIO01_INDEX */ + IMX_PADCTL_GPIO09_INDEX, /* IMX_PADMUX_GPIO09_INDEX */ + IMX_PADCTL_GPIO03_INDEX, /* IMX_PADMUX_GPIO03_INDEX */ + IMX_PADCTL_GPIO06_INDEX, /* IMX_PADMUX_GPIO06_INDEX */ + IMX_PADCTL_GPIO02_INDEX, /* IMX_PADMUX_GPIO02_INDEX */ + IMX_PADCTL_GPIO04_INDEX, /* IMX_PADMUX_GPIO04_INDEX */ + IMX_PADCTL_GPIO05_INDEX, /* IMX_PADMUX_GPIO05_INDEX */ + IMX_PADCTL_GPIO07_INDEX, /* IMX_PADMUX_GPIO07_INDEX */ + IMX_PADCTL_GPIO08_INDEX, /* IMX_PADMUX_GPIO08_INDEX */ + IMX_PADCTL_GPIO16_INDEX, /* IMX_PADMUX_GPIO16_INDEX */ + IMX_PADCTL_GPIO17_INDEX, /* IMX_PADMUX_GPIO17_INDEX */ + IMX_PADCTL_GPIO18_INDEX, /* IMX_PADMUX_GPIO18_INDEX */ + IMX_PADCTL_GPIO19_INDEX, /* IMX_PADMUX_GPIO19_INDEX */ + IMX_PADCTL_CSI0_PIXCLK_INDEX, /* IMX_PADMUX_CSI0_PIXCLK_INDEX */ + IMX_PADCTL_CSI0_HSYNC_INDEX, /* IMX_PADMUX_CSI0_HSYNC_INDEX */ + IMX_PADCTL_CSI0_DATA_EN_INDEX, /* IMX_PADMUX_CSI0_DATA_EN_INDEX */ + IMX_PADCTL_CSI0_VSYNC_INDEX, /* IMX_PADMUX_CSI0_VSYNC_INDEX */ + IMX_PADCTL_CSI0_DATA04_INDEX, /* IMX_PADMUX_CSI0_DATA04_INDEX */ + IMX_PADCTL_CSI0_DATA05_INDEX, /* IMX_PADMUX_CSI0_DATA05_INDEX */ + IMX_PADCTL_CSI0_DATA06_INDEX, /* IMX_PADMUX_CSI0_DATA06_INDEX */ + IMX_PADCTL_CSI0_DATA07_INDEX, /* IMX_PADMUX_CSI0_DATA07_INDEX */ + IMX_PADCTL_CSI0_DATA08_INDEX, /* IMX_PADMUX_CSI0_DATA08_INDEX */ + IMX_PADCTL_CSI0_DATA09_INDEX, /* IMX_PADMUX_CSI0_DATA09_INDEX */ + IMX_PADCTL_CSI0_DATA10_INDEX, /* IMX_PADMUX_CSI0_DATA10_INDEX */ + IMX_PADCTL_CSI0_DATA11_INDEX, /* IMX_PADMUX_CSI0_DATA11_INDEX */ + IMX_PADCTL_CSI0_DATA12_INDEX, /* IMX_PADMUX_CSI0_DATA12_INDEX */ + IMX_PADCTL_CSI0_DATA13_INDEX, /* IMX_PADMUX_CSI0_DATA13_INDEX */ + IMX_PADCTL_CSI0_DATA14_INDEX, /* IMX_PADMUX_CSI0_DATA14_INDEX */ + IMX_PADCTL_CSI0_DATA15_INDEX, /* IMX_PADMUX_CSI0_DATA15_INDEX */ + IMX_PADCTL_CSI0_DATA16_INDEX, /* IMX_PADMUX_CSI0_DATA16_INDEX */ + IMX_PADCTL_CSI0_DATA17_INDEX, /* IMX_PADMUX_CSI0_DATA17_INDEX */ + IMX_PADCTL_CSI0_DATA18_INDEX, /* IMX_PADMUX_CSI0_DATA18_INDEX */ + IMX_PADCTL_CSI0_DATA19_INDEX, /* IMX_PADMUX_CSI0_DATA19_INDEX */ + + /* There is a second group of Pad Control registers with no Pad Mux register counterpart */ + + /* IMX_PADCTL_JTAG_TMS_INDEX - No counterpart */ + /* IMX_PADCTL_JTAG_MOD_INDEX - No counterpart */ + /* IMX_PADCTL_JTAG_TRSTB_INDEX - No counterpart */ + /* IMX_PADCTL_JTAG_TDI_INDEX - No counterpart */ + /* IMX_PADCTL_JTAG_TCK_INDEX - No counterpart */ + /* IMX_PADCTL_JTAG_TDO_INDEX - No counterpart */ + + /* The mapping is again 1-to-1 with an offset for the above registers that + * have no Pad Mux register counterpart. + */ + + IMX_PADCTL_SD3_DATA7_INDEX, /* IMX_PADMUX_SD3_DATA7_INDEX */ + IMX_PADCTL_SD3_DATA6_INDEX, /* IMX_PADMUX_SD3_DATA6_INDEX */ + IMX_PADCTL_SD3_DATA5_INDEX, /* IMX_PADMUX_SD3_DATA5_INDEX */ + IMX_PADCTL_SD3_DATA4_INDEX, /* IMX_PADMUX_SD3_DATA4_INDEX */ + IMX_PADCTL_SD3_CMD_INDEX, /* IMX_PADMUX_SD3_CMD_INDEX */ + IMX_PADCTL_SD3_CLK_INDEX, /* IMX_PADMUX_SD3_CLK_INDEX */ + IMX_PADCTL_SD3_DATA0_INDEX, /* IMX_PADMUX_SD3_DATA0_INDEX */ + IMX_PADCTL_SD3_DATA1_INDEX, /* IMX_PADMUX_SD3_DATA1_INDEX */ + IMX_PADCTL_SD3_DATA2_INDEX, /* IMX_PADMUX_SD3_DATA2_INDEX */ + IMX_PADCTL_SD3_DATA3_INDEX, /* IMX_PADMUX_SD3_DATA3_INDEX */ + IMX_PADCTL_SD3_RESET_INDEX, /* IMX_PADMUX_SD3_RESET_INDEX */ + IMX_PADCTL_NAND_CLE_INDEX, /* IMX_PADMUX_NAND_CLE_INDEX */ + IMX_PADCTL_NAND_ALE_INDEX, /* IMX_PADMUX_NAND_ALE_INDEX */ + IMX_PADCTL_NAND_WP_INDEX, /* IMX_PADMUX_NAND_WP_INDEX */ + IMX_PADCTL_NAND_READY_INDEX, /* IMX_PADMUX_NAND_READY_INDEX */ + IMX_PADCTL_NAND_CS0_INDEX, /* IMX_PADMUX_NAND_CS0_INDEX */ + IMX_PADCTL_NAND_CS1_INDEX, /* IMX_PADMUX_NAND_CS1_INDEX */ + IMX_PADCTL_NAND_CS2_INDEX, /* IMX_PADMUX_NAND_CS2_INDEX */ + IMX_PADCTL_NAND_CS3_INDEX, /* IMX_PADMUX_NAND_CS3_INDEX */ + IMX_PADCTL_SD4_CMD_INDEX, /* IMX_PADMUX_SD4_CMD_INDEX */ + IMX_PADCTL_SD4_CLK_INDEX, /* IMX_PADMUX_SD4_CLK_INDEX */ + IMX_PADCTL_NAND_DATA00_INDEX, /* IMX_PADMUX_NAND_DATA00_INDEX */ + IMX_PADCTL_NAND_DATA01_INDEX, /* IMX_PADMUX_NAND_DATA01_INDEX */ + IMX_PADCTL_NAND_DATA02_INDEX, /* IMX_PADMUX_NAND_DATA02_INDEX */ + IMX_PADCTL_NAND_DATA03_INDEX, /* IMX_PADMUX_NAND_DATA03_INDEX */ + IMX_PADCTL_NAND_DATA04_INDEX, /* IMX_PADMUX_NAND_DATA04_INDEX */ + IMX_PADCTL_NAND_DATA05_INDEX, /* IMX_PADMUX_NAND_DATA05_INDEX */ + IMX_PADCTL_NAND_DATA06_INDEX, /* IMX_PADMUX_NAND_DATA06_INDEX */ + IMX_PADCTL_NAND_DATA07_INDEX, /* IMX_PADMUX_NAND_DATA07_INDEX */ + IMX_PADCTL_SD4_DATA0_INDEX, /* IMX_PADMUX_SD4_DATA0_INDEX */ + IMX_PADCTL_SD4_DATA1_INDEX, /* IMX_PADMUX_SD4_DATA1_INDEX */ + IMX_PADCTL_SD4_DATA2_INDEX, /* IMX_PADMUX_SD4_DATA2_INDEX */ + IMX_PADCTL_SD4_DATA3_INDEX, /* IMX_PADMUX_SD4_DATA3_INDEX */ + IMX_PADCTL_SD4_DATA4_INDEX, /* IMX_PADMUX_SD4_DATA4_INDEX */ + IMX_PADCTL_SD4_DATA5_INDEX, /* IMX_PADMUX_SD4_DATA5_INDEX */ + IMX_PADCTL_SD4_DATA6_INDEX, /* IMX_PADMUX_SD4_DATA6_INDEX */ + IMX_PADCTL_SD4_DATA7_INDEX, /* IMX_PADMUX_SD4_DATA7_INDEX */ + IMX_PADCTL_SD1_DATA1_INDEX, /* IMX_PADMUX_SD1_DATA1_INDEX */ + IMX_PADCTL_SD1_DATA0_INDEX, /* IMX_PADMUX_SD1_DATA0_INDEX */ + IMX_PADCTL_SD1_DATA3_INDEX, /* IMX_PADMUX_SD1_DATA3_INDEX */ + IMX_PADCTL_SD1_CMD_INDEX, /* IMX_PADMUX_SD1_CMD_INDEX */ + IMX_PADCTL_SD1_DATA2_INDEX, /* IMX_PADMUX_SD1_DATA2_INDEX */ + IMX_PADCTL_SD1_CLK_INDEX, /* IMX_PADMUX_SD1_CLK_INDEX */ + IMX_PADCTL_SD2_CLK_INDEX, /* IMX_PADMUX_SD2_CLK_INDEX */ + IMX_PADCTL_SD2_CMD_INDEX, /* IMX_PADMUX_SD2_CMD_INDEX */ + IMX_PADCTL_SD2_DATA3_INDEX, /* IMX_PADMUX_SD2_DATA3_INDEX */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_padmux_map + * + * Description: + * This function map a Pad Mux register index to the corresponding Pad + * Control register index. + * + ****************************************************************************/ + +unsigned int imx_padmux_map(unsigned int padmux) +{ + DEBUGASSERT(padmux < IMX_PADMUX_NREGISTERS); + return (unsigned int)g_mux2ctl_map[padmux]; +} + +/**************************************************************************** + * Name: imx_iomux_configure + * + * Description: + * This function writes the encoded pad configuration to the Pad Control + * register. + * + ****************************************************************************/ + +int imx_iomux_configure(uintptr_t padctl, iomux_pinset_t ioset) +{ + uint32_t regval = 0; + uint32_t value; + + /* Select CMOS input or Schmitt Trigger input */ + + if ((ioset & IOMUX_SCHMITT_TRIGGER) != 0) + { + regval |= PADCTL_SRE; + } + + /* Select drive strength */ + + value = (ioset & IOMUX_DRIVE_MASK) >> IOMUX_DRIVE_SHIFT; + regval |= PADCTL_DSE(value); + + /* Select spped */ + + value = (ioset & IOMUX_SPEED_MASK) >> IOMUX_SPEED_SHIFT; + regval |= PADCTL_SPEED(value); + + /* Select CMOS output or Open Drain outpout */ + + if ((ioset & IOMUX_OPENDRAIN) != 0) + { + regval |= PADCTL_ODE; + } + + /* Handle pull/keep selection */ + + switch (ioset & _IOMUX_PULLTYPE_MASK) + { + default: + case _IOMUX_PULL_NONE: + break; + + case _IOMUX_PULL_KEEP: + { + regval |= PADCTL_PKE; + } + break; + + case _IOMUX_PULL_ENABLE: + { + regval |= (PADCTL_PKE | PADCTL_PUE); + + value = (ioset & _IOMUX_PULLDESC_MASK) >> _IOMUX_PULLDESC_SHIFT; + regval |= PADCTL_PUS(value); + } + break; + } + + /* Select slow/fast slew rate */ + + if ((ioset & IOMUX_SLEW_FAST) != 0) + { + regval |= PADCTL_HYS; + } + + /* Write the result to the specified Pad Control register */ + + putreg32(regval, padctl); + return OK; +} diff --git a/arch/arm/src/imx6/imx_iomuxc.h b/arch/arm/src/imx6/imx_iomuxc.h new file mode 100644 index 0000000000000000000000000000000000000000..2a28fdf1cfbc030d0fd0ae99c5ebf259ce583a60 --- /dev/null +++ b/arch/arm/src/imx6/imx_iomuxc.h @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/imx/imx_iomuxc.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_IOMUXC_H +#define __ARCH_ARM_SRC_IMX6_IMX_IOMUXC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip/imx_iomuxc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* 16-bit Encoding: + * + * .... RRRR ODDD LSST + */ + +/* Output Pull Up/Down: + * + * .... RRRR .... .... + */ + +#define _IOMUX_PULLTYPE_SHIFT (8) /* Bits 8-9: Pull up/down type */ +#define _IOMUX_PULLTYPE_MASK (3 << _IOMUX_PULLTYPE_SHIFT) +# define _IOMUX_PULL_NONE (0 << _IOMUX_PULLTYPE_SHIFT) /* Pull/keeper disabled */ +# define _IOMUX_PULL_KEEP (1 << _IOMUX_PULLTYPE_SHIFT) /* Output determined by keeper */ +# define _IOMUX_PULL_ENABLE (2 << _IOMUX_PULLTYPE_SHIFT) /* Output pulled up or down */ + +#define _IOMUX_PULLDESC_SHIFT (10) /* Bits 10-11: Pull up/down description */ +#define _IOMUX_PULLDESC_MASK (3 << _IOMUX_PULLDESC_SHIFT) +# define _IOMUX_PULL_UP_22K (PULL_UP_22K << _IOMUX_PULLDESC_SHIFT) /* Pull up with 22 KOhm resister */ +# define _IOMUX_PULL_UP_47K (PULL_UP_47K << _IOMUX_PULLDESC_SHIFT) /* Pull up with 47 KOhm resister */ +# define _IOMUX_PULL_UP_100K (PULL_UP_100K << _IOMUX_PULLDESC_SHIFT) /* Pull up with 100 KOhm resister */ +# define _IOMUX_PULL_DOWN_100K (PULL_DOWN_100K << _IOMUX_PULLDESC_SHIFT) /* Pull down with 100 KOhm resister */ + +#define IOMUX_PULL_SHIFT (8) /* Bits 8-11: Pull up/down selection */ +#define IOMUX_PULL_MASK (15 << IOMUX_PULL_SHIFT) +# define IOMUX_PULL_NONE _IOMUX_PULL_NONE +# define IOMUX_PULL_KEEP _IOMUX_PULL_KEEP +# define IOMUX_PULL_UP_22K (_IOMUX_PULL_ENABLE | _IOMUX_PULL_UP_22K) +# define IOMUX_PULL_UP_47K (_IOMUX_PULL_ENABLE | _IOMUX_PULL_UP_47K) +# define IOMUX_PULL_UP_100K (_IOMUX_PULL_ENABLE | _IOMUX_PULL_UP_100K) +# define IOMUX_PULL_DOWN_100K (_IOMUX_PULL_ENABLE | _IOMUX_PULL_DOWN_100K) + +/* Open Drain Output: + * + * .... .... O... .... + */ + +#define IOMUX_CMOS_OUTPUT (0) /* Bit 7: 0=CMOS output */ +#define IOMUX_OPENDRAIN (1 << 7) /* Bit 7: 1=Enable open-drain output */ + +/* Output Drive Strength: + * + * .... .... .DDD .... + */ + +#define IOMUX_DRIVE_SHIFT (4) /* Bits 4-6: Output Drive Strength */ +#define IOMUX_DRIVE_MASK (7 << IOMUX_DRIVE_SHIFT) +# define IOMUX_DRIVE_HIZ (DRIVE_HIZ << IOMUX_DRIVE_SHIFT) /* HI-Z */ +# define IOMUX_DRIVE_260OHM (DRIVE_260OHM << IOMUX_DRIVE_SHIFT) /* 150 Ohm @3.3V, 260 Ohm @1.8V */ +# define IOMUX_DRIVE_130OHM (DRIVE_130OHM << IOMUX_DRIVE_SHIFT) /* 75 Ohm @3.3V, 130 Ohm @1.8V */ +# define IOMUX_DRIVE_90OHM (DRIVE_90OHM << IOMUX_DRIVE_SHIFT) /* 50 Ohm @3.3V, 90 Ohm @1.8V */ +# define IOMUX_DRIVE_60OHM (DRIVE_60OHM << IOMUX_DRIVE_SHIFT) /* 37 Ohm @3.3V, 60 Ohm @1.8V */ +# define IOMUX_DRIVE_50OHM (DRIVE_50OHM << IOMUX_DRIVE_SHIFT) /* 30 Ohm @3.3V, 50 Ohm @1.8V */ +# define IOMUX_DRIVE_40OHM (DRIVE_40OHM << IOMUX_DRIVE_SHIFT) /* 25 Ohm @3.3V, 40 Ohm @1.8V */ +# define IOMUX_DRIVE_33OHM (DRIVE_33OHM << IOMUX_DRIVE_SHIFT) /* 20 Ohm @3.3V, 33 Ohm @1.8V */ + +/* Output Slew Rate: + * + * .... .... .... L... + */ + +#define IOMUX_SLEW_SLOW (0) /* Bit 3: 0=Slow Slew Rate */ +#define IOMUX_SLEW_FAST (1 << 3) /* Bit 3: 1=Fast Slew Rate */ + +/* Output Speed: + * + * .... .... .... .SS. + */ + +#define IOMUX_SPEED_SHIFT (2) /* Bits 2-3: Speed */ +#define IOMUX_SPEED_MASK (3 << IOMUX_SPEED_SHIFT) +# define IOMUX_SPEED_LOW (SPEED_LOW << IOMUX_SPEED_SHIFT) /* Low frequency (50 MHz) */ +# define IOMUX_SPEED_MEDIUM (SPEED_MEDIUM << IOMUX_SPEED_SHIFT) /* Medium frequency (100, 150 MHz) */ +# define IOMUX_SPEED_MAX (SPEED_MAX << IOMUX_SPEED_SHIFT) /* Maximum frequency (100, 150, 200 MHz) */ + +/* Input Schmitt Trigger: + * + * .... .... .... ...T + */ + +#define IOMUX_CMOS_INPUT (0) /* Bit 0: 0=CMOS input */ +#define IOMUX_SCHMITT_TRIGGER (1 << 0) /* Bit 0: 1=Enable Schmitt trigger if input */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + + /* The smallest integer type that can hold the IOMUX encoding */ + +typedef uint16_t iomux_pinset_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_padmux_map + * + * Description: + * This function map a Pad Mux register index to the corresponding Pad + * Control register index. + * + ****************************************************************************/ + +unsigned int imx_padmux_map(unsigned int padmux); + +/**************************************************************************** + * Name: imx_iomux_configure + * + * Description: + * This function writes the encoded pad configuration to the Pad Control + * register. + * + ****************************************************************************/ + +int imx_iomux_configure(uintptr_t padctl, iomux_pinset_t ioset); + +#endif /* __ARCH_ARM_SRC_IMX6_IMX_IOMUXC_H */ diff --git a/arch/arm/src/imx6/imx_irq.c b/arch/arm/src/imx6/imx_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..e00a8e9527dfa0585a8760d097da4663353c8d45 --- /dev/null +++ b/arch/arm/src/imx6/imx_irq.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_irq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "sctlr.h" +#include "gic.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +#ifdef CONFIG_SMP +/* For the case of configurations with multiple CPUs, then there must be one + * such value for each processor that can receive an interrupt. + */ + +volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +#else +volatile uint32_t *g_current_regs[1]; +#endif + +/* Symbols defined via the linker script */ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * This function is called by up_initialize() during the bring-up of the + * system. It is the responsibility of this function to but the interrupt + * subsystem into the working and ready state. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* The following operations need to be atomic, but since this function is + * called early in the initialization sequence, we expect to have exclusive + * access to the GIC. + */ + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Initialize the Generic Interrupt Controller (GIC) for CPU0 */ + + arm_gic0_initialize(); /* Initialization unique to CPU0 */ + arm_gic_initialize(); /* Initialization common to all CPUs */ + +#ifdef CONFIG_ARCH_LOWVECTORS + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are two ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * The second method is used by this logic. + */ + + /* Set the VBAR register to the address of the vector table */ + + DEBUGASSERT((((uintptr_t)&_vector_start) & ~VBAR_MASK) == 0); + cp15_wrvbar((uint32_t)&_vector_start); +#endif /* CONFIG_ARCH_LOWVECTORS */ + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * PIO pins. + */ + +#ifdef CONFIG_IMX6_PIO_IRQ + imx_gpioirq_initialize(); +#endif + + /* And finally, enable interrupts */ + + (void)up_irq_enable(); +#endif +} diff --git a/arch/arm/src/imx6/imx_lowputc.c b/arch/arm/src/imx6/imx_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..a6387e732168c2b2bda1cb45c3b4ab04fb0077a0 --- /dev/null +++ b/arch/arm/src/imx6/imx_lowputc.c @@ -0,0 +1,621 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_lowputc.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip/imx_iomuxc.h" +#include "chip/imx_ccm.h" +#include "chip/imx_uart.h" +#include "imx_config.h" +#include "imx_iomuxc.h" +#include "imx_gpio.h" +#include "imx_lowputc.h" + +#include "up_internal.h" + +#include "chip/imx_pinmux.h" +#include /* Include last: has dependencies */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef IMX_HAVE_UART_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART1_VBASE +# define IMX_CONSOLE_BAUD CONFIG_UART1_BAUD +# define IMX_CONSOLE_BITS CONFIG_UART1_BITS +# define IMX_CONSOLE_PARITY CONFIG_UART1_PARITY +# define IMX_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART2_VBASE +# define IMX_CONSOLE_BAUD CONFIG_UART2_BAUD +# define IMX_CONSOLE_BITS CONFIG_UART2_BITS +# define IMX_CONSOLE_PARITY CONFIG_UART2_PARITY +# define IMX_CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART3_VBASE +# define IMX_CONSOLE_BAUD CONFIG_UART3_BAUD +# define IMX_CONSOLE_BITS CONFIG_UART3_BITS +# define IMX_CONSOLE_PARITY CONFIG_UART3_PARITY +# define IMX_CONSOLE_2STOP CONFIG_UART3_2STOP +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART4_VBASE +# define IMX_CONSOLE_BAUD CONFIG_UART4_BAUD +# define IMX_CONSOLE_BITS CONFIG_UART4_BITS +# define IMX_CONSOLE_PARITY CONFIG_UART4_PARITY +# define IMX_CONSOLE_2STOP CONFIG_UART4_2STOP +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART5_VBASE +# define IMX_CONSOLE_BAUD CONFIG_UART5_BAUD +# define IMX_CONSOLE_BITS CONFIG_UART5_BITS +# define IMX_CONSOLE_PARITY CONFIG_UART5_PARITY +# define IMX_CONSOLE_2STOP CONFIG_UART5_2STOP +# endif +#endif + +/* Clocking *****************************************************************/ +/* the UART module receives two clocks, a peripheral_clock (ipg_clk) and the + * module_clock (ipg_perclk). The peripheral_clock is used as write clock + * of the TxFIFO, read clock of the RxFIFO and synchronization of the modem + * control input pins. It must always be running when UART is enabled. + * + * The default ipg_clk is 66MHz (max 66.5MHz). ipg_clk is gated by + * CCGR5[CG12], uart_clk_enable. ipg_clk is shared among many modules and + * should not be controlled by the UART logic. + * + * The module_clock is for all the state machines, writing RxFIFO, reading + * TxFIFO, etc. It must always be running when UART is sending or receiving + * characters. This clock is used in order to allow frequency scaling on + * peripheral_clock without changing configuration of baud rate. + * + * The default ipg_perclk is 80MHz (max 80MHz). ipg_perclk is gated by + * CCGR5[CG13], uart_serial_clk_enable. The clock generation sequence is: + * + * pll3_sw_clk (480M) -> CCGR5[CG13] -> 3 bit divider cg podf=6 -> + * PLL3_80M (80Mhz) -> CDCDR1: uart_clk_podf -> + * 6 bit divider default=1 -> UART_CLK_ROOT + * + * REVISIT: This logic assumes that all dividers are at the default value + * and that the value of the ipg_perclk is 80MHz. + */ + +#define IPG_PERCLK_FREQUENCY 80000000 + +/* The BRM sub-block receives ref_clk (module_clock clock after divider). + * From this clock, and with integer and non-integer division, BRM generates + * a 16x baud rate clock. + */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef IMX_HAVE_UART_CONSOLE +static const struct uart_config_s g_console_config = +{ + .baud = IMX_CONSOLE_BAUD, /* Configured baud */ + .parity = IMX_CONSOLE_PARITY, /* 0=none, 1=odd, 2=even */ + .bits = IMX_CONSOLE_BITS, /* Number of bits (5-9) */ + .stopbits2 = IMX_CONSOLE_2STOP, /* true: Configure with 2 stop bits instead of 1 */ +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void imx_lowsetup(void) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG +#ifdef IMX_HAVE_UART + uint32_t regval; + + /* Make certain that the ipg_clock and ipg_perclk are enabled for the UART + * modules. Here we set BOTH the ipg_clk and ipg_perclk so that clocking + * is on in all modes (except STOP). + */ + + regval = getreg32(IMX_CCM_CCGR5); + regval &= ~(CCM_CCGR5_CG12_MASK | CCM_CCGR5_CG13_MASK); + regval |= (CCM_CCGR5_CG12(CCM_CCGR_ALLMODES) | + CCM_CCGR5_CG13(CCM_CCGR_ALLMODES)); + putreg32(regval, IMX_CCM_CCGR5); + +#ifdef CONFIG_IMX6_UART1 + /* Disable and configure UART1 */ + + putreg32(0, IMX_UART1_VBASE + UART_UCR1_OFFSET); + putreg32(0, IMX_UART1_VBASE + UART_UCR2_OFFSET); + putreg32(0, IMX_UART1_VBASE + UART_UCR3_OFFSET); + putreg32(0, IMX_UART1_VBASE + UART_UCR4_OFFSET); + + /* Configure UART1 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. REVISIT: DTR, DCD, RI, and DSR -- not configured. + */ + + (void)imx_config_gpio(GPIO_UART1_RX_DATA); + (void)imx_config_gpio(GPIO_UART1_TX_DATA); +#ifdef CONFIG_UART1_OFLOWCONTROL + (void)imx_config_gpio(GPIO_UART1_CTS); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + (void)imx_config_gpio(GPIO_UART1_RTS); +#endif +#endif + +#ifdef CONFIG_IMX6_UART2 + /* Disable and configure UART2 */ + + putreg32(0, IMX_UART2_VBASE + UART_UCR1_OFFSET); + putreg32(0, IMX_UART2_VBASE + UART_UCR2_OFFSET); + putreg32(0, IMX_UART2_VBASE + UART_UCR3_OFFSET); + putreg32(0, IMX_UART2_VBASE + UART_UCR4_OFFSET); + + /* Configure UART2 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + (void)imx_config_gpio(GPIO_UART2_RX_DATA); + (void)imx_config_gpio(GPIO_UART2_TX_DATA); +#ifdef CONFIG_UART1_OFLOWCONTROL + (void)imx_config_gpio(GPIO_UART2_CTS); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + (void)imx_config_gpio(GPIO_UART2_RTS); +#endif +#endif + +#ifdef CONFIG_IMX6_UART3 + /* Disable and configure UART3 */ + + putreg32(0, IMX_UART3_VBASE + UART_UCR1_OFFSET); + putreg32(0, IMX_UART3_VBASE + UART_UCR2_OFFSET); + putreg32(0, IMX_UART3_VBASE + UART_UCR3_OFFSET); + putreg32(0, IMX_UART3_VBASE + UART_UCR4_OFFSET); + + /* Configure UART3 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + (void)imx_config_gpio(GPIO_UART3_RX_DATA); + (void)imx_config_gpio(GPIO_UART3_TX_DATA); +#ifdef CONFIG_UART1_OFLOWCONTROL + (void)imx_config_gpio(GPIO_UART3_CTS); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + (void)imx_config_gpio(GPIO_UART3_RTS); +#endif +#endif + +#ifdef CONFIG_IMX6_UART4 + /* Disable and configure UART4 */ + + putreg32(0, IMX_UART4_VBASE + UART_UCR1_OFFSET); + putreg32(0, IMX_UART4_VBASE + UART_UCR2_OFFSET); + putreg32(0, IMX_UART4_VBASE + UART_UCR3_OFFSET); + putreg32(0, IMX_UART4_VBASE + UART_UCR4_OFFSET); + + /* Configure UART4 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + (void)imx_config_gpio(GPIO_UART4_RX_DATA); + (void)imx_config_gpio(GPIO_UART4_TX_DATA); +#ifdef CONFIG_UART1_OFLOWCONTROL + (void)imx_config_gpio(GPIO_UART4_CTS); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + (void)imx_config_gpio(GPIO_UART4_RTS); +#endif +#endif + +#ifdef CONFIG_IMX6_UART5 + /* Disable and configure UART5 */ + + putreg32(0, IMX_UART5_VBASE + UART_UCR1_OFFSET); + putreg32(0, IMX_UART5_VBASE + UART_UCR2_OFFSET); + putreg32(0, IMX_UART5_VBASE + UART_UCR3_OFFSET); + putreg32(0, IMX_UART5_VBASE + UART_UCR4_OFFSET); + + /* Configure UART5 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + (void)imx_config_gpio(GPIO_UART5_RX_DATA); + (void)imx_config_gpio(GPIO_UART5_TX_DATA); +#ifdef CONFIG_UART1_OFLOWCONTROL + (void)imx_config_gpio(GPIO_UART5_CTS); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + (void)imx_config_gpio(GPIO_UART5_RTS); +#endif +#endif + +#ifdef IMX_HAVE_UART_CONSOLE + /* Configure the serial console for initial, non-interrupt driver mode */ + + (void)imx_uart_configure(IMX_CONSOLE_VBASE, &g_console_config); +#endif +#endif /* IMX_HAVE_UART */ +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ +} + +/************************************************************************************ + * Name: imx_uart_configure + * + * Description: + * Configure a UART for non-interrupt driven operation + * + ************************************************************************************/ + +#ifdef IMX_HAVE_UART +int imx_uart_configure(uint32_t base, FAR const struct uart_config_s *config) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint64_t tmp; + uint32_t regval; + uint32_t ucr2; + uint32_t refclk; + uint32_t div; + uint32_t num; + uint32_t den; + b16_t ratio; + + /* Disable the UART */ + + putreg32(0, base + UART_UCR1_OFFSET); + putreg32(0, base + UART_UCR2_OFFSET); + putreg32(0, base + UART_UCR3_OFFSET); + putreg32(0, base + UART_UCR4_OFFSET); + + /* Wait for the UART to come out of reset */ + + while ((getreg32(base + UART_UCR2_OFFSET) & UART_UCR2_SRST) == 0); + + /* Set up UCR2, Clearing all bits that will be configured below. */ + + ucr2 = getreg32(base + UART_UCR2_OFFSET); + ucr2 &= ~(UART_UCR2_WS | UART_UCR2_STPB | UART_UCR2_PREN | + UART_UCR2_PROE | UART_UCR2_IRTS | UART_UCR2_CTSC); + + /* Select the number of data bits */ + + DEBUGASSERT(config->bits == 7 || config->bits == 8); + if (config->bits == 8) + { + ucr2 |= UART_UCR2_WS; + } + + /* Select the number of stop bits */ + + if (config->stopbits2) + { + ucr2 |= UART_UCR2_STPB; + } + + /* Select even/odd parity */ + + if (config->parity != 0) + { + DEBUGASSERT(config->parity == 1 || config->parity == 2); + ucr2 |= UART_UCR2_PREN; + if (config->parity == 1) + { + ucr2 |= UART_UCR2_PROE; + } + } + + /* Setup hardware flow control */ + + regval = 0; + +#if 0 + if (config->hwfc) + { + /* CTS controled by Rx FIFO */ + + ucr2 |= UART_UCR2_CTSC; + + /* Set CTS trigger level */ + + regval |= 30 << UART_UCR4_CTSTL_SHIFT; + + /* REVISIT: There are other relevant bits that must be managed in + * UCR1 and UCR3. + */ + } + else +#endif + { + /* Ignore RTS */ + + ucr2 |= UART_UCR2_IRTS; + } + + putreg32(regval, base + UART_UCR4_OFFSET); + + /* Setup the new UART configuration */ + + putreg32(ucr2, base + UART_UCR2_OFFSET); + + /* Select a reference clock divider. + * REVISIT: For now we just use a divider of 2. That might not be + * optimal for very high or very low baud settings. + */ + + div = 2; + refclk = (IPG_PERCLK_FREQUENCY >> 1); + + /* Set the baud. + * + * baud = REFFREQ / (16 * NUM/DEN) + * baud = REFFREQ / 16 / RATIO + * RATIO = REFREQ / 16 / baud; + * + * NUM = SCALE * RATIO + * DEN = SCALE + * + * UMBR = NUM-1 + * UBIR = DEN-1; + */ + + tmp = ((uint64_t)refclk << (16 - 4)) / config->baud; + DEBUGASSERT(tmp < 0x0000000100000000LL); + ratio = (b16_t)tmp; + + /* Pick a scale factor that gives us about 14 bits of accuracy. + * REVISIT: Why not go all the way to 16-bits? + */ + + if (ratio < b16HALF) + { + den = (1 << 15); + num = b16toi(ratio << 15); + DEBUGASSERT(num > 0); + } + else if (ratio < b16ONE) + { + den = (1 << 14); + num = b16toi(ratio << 14); + } + else if (ratio < itob16(2)) + { + den = (1 << 13); + num = b16toi(ratio << 13); + } + else if (ratio < itob16(4)) + { + den = (1 << 12); + num = b16toi(ratio << 12); + } + else if (ratio < itob16(8)) + { + den = (1 << 11); + num = b16toi(ratio << 11); + } + else if (ratio < itob16(16)) + { + den = (1 << 10); + num = b16toi(ratio << 10); + } + else if (ratio < itob16(32)) + { + den = (1 << 9); + num = b16toi(ratio << 9); + } + else if (ratio < itob16(64)) + { + den = (1 << 8); + num = b16toi(ratio << 8); + } + else if (ratio < itob16(128)) + { + den = (1 << 7); + num = b16toi(ratio << 7); + } + else if (ratio < itob16(256)) + { + den = (1 << 6); + num = b16toi(ratio << 6); + } + else if (ratio < itob16(512)) + { + den = (1 << 5); + num = b16toi(ratio << 5); + } + else if (ratio < itob16(1024)) + { + den = (1 << 4); + num = b16toi(ratio << 4); + } + else if (ratio < itob16(2048)) + { + den = (1 << 3); + num = b16toi(ratio << 3); + } + else if (ratio < itob16(4096)) + { + den = (1 << 2); + num = b16toi(ratio << 2); + } + else if (ratio < itob16(8192)) + { + den = (1 << 1); + num = b16toi(ratio << 1); + } + else /* if (ratio < itob16(16384)) */ + { + DEBUGASSERT(ratio < itob16(16384)); + den = (1 << 0); + num = b16toi(ratio); + } + + /* Reduce if possible without losing accuracy. */ + + while ((num & 1) == 0 && (den & 1) == 0) + { + num >>= 1; + den >>= 1; + } + + /* The actual values are we write to the registers need to be + * decremented by 1. NOTE that the UBIR must be set before + * the UBMR. + */ + + putreg32(den - 1, base + UART_UBIR_OFFSET); + putreg32(num - 1, base + UART_UBMR_OFFSET); + + /* Fixup the divisor, the value in the UFCR regiser is + * + * 000 = Divide input clock by 6 + * 001 = Divide input clock by 5 + * 010 = Divide input clock by 4 + * 011 = Divide input clock by 3 + * 100 = Divide input clock by 2 + * 101 = Divide input clock by 1 + * 110 = Divide input clock by 7 + */ + + if (div == 7) + { + div = 6; + } + else + { + div = 6 - div; + } + + regval = div << UART_UFCR_RFDIV_SHIFT; + + /* Set the TX trigger level to interrupt when the TxFIFO has 2 or fewer + * characters. Set the RX trigger level to interrupt when the RxFIFO has + * 1 character. + */ + + regval |= ((2 << UART_UFCR_TXTL_SHIFT) | (1 << UART_UFCR_RXTL_SHIFT)); + putreg32(regval, base + UART_UFCR_OFFSET); + + /* Selected. Selects proper input pins for serial and Infrared input + * signal. NOTE: In this chip, UARTs are used in MUXED mode, so that this + * bit should always be set. + */ + + putreg32(UART_UCR3_RXDMUXSEL, base + UART_UCR3_OFFSET); + + /* Enable the TX and RX */ + + ucr2 |= (UART_UCR2_TXEN | UART_UCR2_RXEN); + putreg32(ucr2, base + UART_UCR2_OFFSET); + + /* Enable the UART */ + + regval = getreg32(base + UART_UCR1_OFFSET); + regval |= UART_UCR1_UARTEN; + putreg32(regval, base + UART_UCR1_OFFSET); +#endif + + return OK; +} +#endif /* IMX_HAVE_UART */ + +/************************************************************************************ + * Name: imx_lowputc + * + * Description: + * Output a byte with as few system dependencies as possible. This will even work + * BEFORE the console is initialized if we are booting from U-Boot (and the same + * UART is used for the console, of course.) + * + ************************************************************************************/ + +#if defined(IMX_HAVE_UART) && defined(CONFIG_DEBUG) +void imx_lowputc(int ch) +{ + /* Poll the TX fifo trigger level bit of the UART status register. When the TXFE + * bit is non-zero, the TX Buffer FIFO is empty. + */ + + while ((getreg32(IMX_CONSOLE_VBASE + UART_USR2_OFFSET) & UART_USR2_TXFE) == 0); + + /* If the character to output is a newline, then pre-pend a carriage return */ + + if (ch == '\n') + { + /* Send the carrage return by writing it into the UART_TXD register. */ + + putreg32((uint32_t)'\r', IMX_CONSOLE_VBASE + UART_TXD_OFFSET); + + /* Wait for the tranmsit regiser to be emptied. When the TXFE bit is non-zero, + * the TX Buffer FIFO is empty. + */ + + while ((getreg32(IMX_CONSOLE_VBASE + UART_USR2_OFFSET) & UART_USR2_TXFE) == 0); + } + + /* Send the character by writing it into the UART_TXD register. */ + + putreg32((uint32_t)ch, IMX_CONSOLE_VBASE + UART_TXD_OFFSET); + + /* Wait for the tranmsit regiser to be emptied. When the TXFE bit is non-zero, + * the TX Buffer FIFO is empty. + */ + + while ((getreg32(IMX_CONSOLE_VBASE + UART_USR2_OFFSET) & UART_USR2_TXFE) == 0); +} +#endif diff --git a/arch/arm/src/imx6/imx_lowputc.h b/arch/arm/src/imx6/imx_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..d487931dc63362a429f80b953a7255e818a04312 --- /dev/null +++ b/arch/arm/src/imx6/imx_lowputc.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/src/imx/imx_lowputc.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_LOWPUTC_H +#define __ARCH_ARM_SRC_IMX6_IMX_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef IMX_HAVE_UART +/* This structure describes the configuration of an UART */ + +struct uart_config_s +{ + uint32_t baud; /* Configured baud */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-9) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void imx_lowsetup(void); + +/************************************************************************************ + * Name: imx_uart_configure + * + * Description: + * Configure a UART for non-interrupt driven operation + * + ************************************************************************************/ + +#ifdef IMX_HAVE_UART +int imx_uart_configure(uint32_t base, FAR const struct uart_config_s *config); +#endif + +/************************************************************************************ + * Name: imx_lowputc + * + * Description: + * Output a byte with as few system dependencies as possible. This will even work + * BEFORE the console is initialized if we are booting from U-Boot (and the same + * UART is used for the console, of course.) + * + ************************************************************************************/ + +#if defined(IMX_HAVE_UART) && defined(CONFIG_DEBUG) +void imx_lowputc(int ch); +#else +# define imx_lowputc(ch) +#endif + +#endif /* __ARCH_ARM_SRC_IMX6_IMX_LOWPUTC_H */ diff --git a/arch/arm/src/imx6/imx_memorymap.c b/arch/arm/src/imx6/imx_memorymap.c new file mode 100644 index 0000000000000000000000000000000000000000..1189dd5d7f8c85cfbde0dbc4e6b8bf296e499e8f --- /dev/null +++ b/arch/arm/src/imx6/imx_memorymap.c @@ -0,0 +1,220 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_memorymap.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "mmu.h" + +#include "chip/imx_memorymap.h" +#include "imx_memorymap.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +/* This table describes how to map a set of 1Mb pages to space the physical + * address space of the i.MX6. + */ + +const struct section_mapping_s g_section_mapping[] = +{ + /* i.MX6 Address Sections Memories */ + + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are two ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * This is the method used by this logic. + * + * The system always boots from the ROM memory at address 0x0. After + * reset, and until the Remap command is performed, the OCRAM is accessible + * at address 0x0090 0000. + * + * If we are executing from external SDRAM, then a secondary bootloader must + * have loaded us into SDRAM. In this case, simply set the VBAR register + * to the address of the vector table (not necessary at the beginning + * or SDRAM). + */ + + { IMX_ROMCP_PSECTION, IMX_ROMCP_VSECTION, /* Boot ROM (ROMCP) */ + IMX_ROMCP_MMUFLAGS, IMX_ROMCP_NSECTIONS + }, + { IMX_DMA_PSECTION, IMX_DMA_VSECTION, /* "DMA" sectinon peripherals */ + IMX_DMA_MMUFLAGS, IMX_DMA_NSECTIONS + }, + { IMX_GPV2_PSECTION, IMX_GPV2_VSECTION, /* GPV_2 PL301 (per1) configuration port */ + IMX_GPV2_MMUFLAGS, IMX_GPV2_NSECTIONS + }, + { IMX_GPV3_PSECTION, IMX_GPV3_VSECTION, /* GPV_3 PL301 (per2) configuration port */ + IMX_GPV3_MMUFLAGS, IMX_GPV3_NSECTIONS + }, + { IMX_GPV4_PSECTION, IMX_GPV4_VSECTION, /* GPV_4 PL301 (fast3) configuration port */ + IMX_GPV4_MMUFLAGS, IMX_GPV4_NSECTIONS + }, + { IMX_OCRAM_PSECTION, IMX_OCRAM_VSECTION, /* OCRAM */ + IMX_OCRAM_MMUFLAGS, IMX_OCRAM_NSECTIONS + }, + { IMX_ARMMP_PSECTION, IMX_ARMMP_VSECTION, /* ARM MP */ + IMX_ARMMP_MMUFLAGS, IMX_ARMMP_NSECTIONS + }, + { IMX_GPV0PL301_PSECTION, IMX_GPV0PL301_VSECTION, /* GPV0 PL301 (fast2) configuration port */ + IMX_GPV0PL301_MMUFLAGS, IMX_GPV0PL301_NSECTIONS + }, + { IMX_GPV1PL301_PSECTION, IMX_GPV1PL301_VSECTION, /* GPV1 PL301 (fast1) configuration port */ + IMX_GPV1PL301_MMUFLAGS, IMX_GPV1PL301_NSECTIONS + }, + { IMX_PCIE_PSECTION, IMX_PCIE_VSECTION, /* PCIe */ + IMX_PCIE_MMUFLAGS, IMX_PCIE_NSECTIONS + }, + { IMX_AIPS1_PSECTION, IMX_AIPS1_VSECTION, /* Peripheral IPs via AIPS-1 */ + IMX_AIPS1_MMUFLAGS, IMX_AIPS1_NSECTIONS + }, + { IMX_AIPS2_PSECTION, IMX_AIPS2_VSECTION, /* Peripheral IPs via AIPS-2 */ + IMX_AIPS2_MMUFLAGS, IMX_AIPS2_NSECTIONS + }, + { IMX_SATA_PSECTION, IMX_SATA_VSECTION, /* SATA */ + IMX_SATA_MMUFLAGS, IMX_SATA_NSECTIONS + }, + { IMX_IPU1_PSECTION, IMX_IPU1_VSECTION, /* IPU-1 */ + IMX_IPU1_MMUFLAGS, IMX_IPU1_NSECTIONS + }, + { IMX_IPU2_PSECTION, IMX_IPU2_VSECTION, /* IPU-2 */ + IMX_IPU2_MMUFLAGS, IMX_IPU2_NSECTIONS + }, + +#ifdef CONFIG_IMX6_EIM + { IMX_EIM_PSECTION, IMX_EIM_VSECTION, /* EIM - (NOR/SRAM) */ + IMX_EIM_MMUFLAGS, IMX_EIM_NSECTIONS + }, +#endif + + /* i.MX6 External SDRAM Memory. The SDRAM is not usable until it has been + * initialized. If we are running out of SDRAM now, we can assume that some + * second level boot loader has properly configured SRAM for us. In that + * case, we set the MMU flags for the final, fully cache-able state. + * + * Also, in this case, the mapping for the SDRAM was done in arm_head.S and + * need not be repeated here. + * + * If we are running from OCRAM or NOR flash, then we will need to configure + * the SDRAM ourselves. In this case, we set the MMU flags to the strongly + * ordered, non-cacheable state. We need this direct access to SDRAM in + * order to configure it. Once SDRAM has been initialized, it will be re- + * configured in its final state. + */ + +#ifdef NEED_SDRAM_MAPPING + { IMX_MMDCDDR_PSECTION, IMX_MMDCDDR_VSECTION, /* MMDC-DDR Controller */ + MMU_STRONGLY_ORDERED, IMX_MMDCDDR_NSECTIONS + }, +#else + { IMX_MMDCDDR_PSECTION, IMX_MMDCDDR_VSECTION, /* MMDC-DDR Controller */ + IMX_MMDCDDR_MMUFLAGS, IMX_MMDCDDR_NSECTIONS + }, +#endif + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + * + * If SDRAM will be reconfigured, then we will defer setup of the framebuffer + * until after the SDRAM remapping (since the framebuffer problem resides) in + * SDRAM. + */ + +#if defined(CONFIG_IMX6_LCDC) && !defined(NEED_SDRAM_REMAPPING) + { CONFIG_IMX6_LCDC_FB_PBASE, CONFIG_IMX6_LCDC_FB_VBASE, + MMU_IOFLAGS, IMX6_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the mapping table */ + +#define NMAPPINGS \ + (sizeof(g_section_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_mappings = NMAPPINGS; + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +/* i.MX6 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +const struct section_mapping_s g_operational_mapping[] = +{ + /* This entry reprograms the SDRAM entry, making it cacheable and + * bufferable. + */ + + { IMX_MMDCDDR_PSECTION, IMX_MMDCDDR_VSECTION, /* MMDC-DDR Controller */ + IMX_MMDCDDR_MMUFLAGS, IMX_MMDCDDR_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + */ + +#ifdef CONFIG_IMX6_LCDC + {CONFIG_IMX6_LCDC_FB_PBASE, CONFIG_IMX6_LCDC_FB_VBASE, + MMU_IOFLAGS, IMX6_LCDC_FBNSECTIONS + }, +#endif + +}; + +/* The number of entries in the operational mapping table */ + +#define NREMAPPINGS \ + (sizeof(g_operational_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_opmappings = NREMAPPINGS; + +#endif /* NEED_SDRAM_REMAPPING */ diff --git a/arch/arm/src/imx6/imx_memorymap.h b/arch/arm/src/imx6/imx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..6259c1b7e0177a16bd93e240532542a9b950270c --- /dev/null +++ b/arch/arm/src/imx6/imx_memorymap.h @@ -0,0 +1,116 @@ +/************************************************************************************ + * arch/arm/src/imx6/imx_memorymap.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_MEMORYMAP_H +#define __ARCH_ARM_SRC_IMX6_IMX_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "mmu.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* The vectors are, by default, positioned at the beginning of the text + * section. Under what conditions do we have to remap the these vectors? + * + * 1) If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case, + * the vectors will lie at virtual address 0xffff:000 and we will need + * to a) copy the vectors to another location, and b) map the vectors + * to that address, and + * + * For the case of CONFIG_ARCH_LOWVECTORS=y, defined. The i.MX6 boot-up + * logic will map the beginning of the boot memory to address 0x0000:0000 + * using both the MMU and the AXI matrix REMAP register. No vector copy + * is required because the vectors are position at the beginning of the + * boot memory at link time and no additional MMU mapping required. + * + * 2) We are not using a ROM page table. We cannot set any custom mappings in + * the case and the build must conform to the ROM page table properties + */ + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE) +# error High vector remap cannot be performed if we are using a ROM page table +#endif + +/* If SDRAM needs to be configured, then it will be configured twice: It + * will first be configured to a temporary state to support low-level + * initialization. After the SDRAM has been fully initialized, SRAM be used + * to set the SDRM in its final, fully cache-able state. + */ + +#undef NEED_SDRAM_CONFIGURATION +#if defined(CONFIG_IMX6_MMDC) && !defined(CONFIG_IMX6_BOOT_SDRAM) +# define NEED_SDRAM_CONFIGURATION 1 +#endif + +#undef NEED_SDRAM_MAPPING +#undef NEED_SDRAM_REMAPPING +#if defined(NEED_SDRAM_CONFIGURATION) && !defined(CONFIG_ARCH_ROMPGTABLE) +# define NEED_SDRAM_MAPPING 1 +# define NEED_SDRAM_REMAPPING 1 +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + + /* This table describes how to map a set of 1Mb pages to space the physical + * address space of the i.MX6. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +extern const struct section_mapping_s g_section_mapping[]; +extern const size_t g_num_mappings; +#endif + +/* i.MX6 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +extern const struct section_mapping_s g_operational_mapping[]; +extern const size_t g_num_opmappings; +#endif + +#endif /* __ARCH_ARM_SRC_IMX6_IMX_MEMORYMAP_H */ diff --git a/arch/arm/src/imx6/imx_serial.c b/arch/arm/src/imx6/imx_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..39a61fddffd8f442a86f7a22b8f25aa97042de27 --- /dev/null +++ b/arch/arm/src/imx6/imx_serial.c @@ -0,0 +1,1091 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_serial.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/imx_uart.h" +#include "imx_config.h" +#include "imx_lowputc.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Which UART with be tty0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART1-5 */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART5 is console */ +# define TTYS5_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_IMX6_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_IMX6_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_IMX6_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_IMX6_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_IMX6_UART5) +# define TTYS0_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART1-5 excluding the console UART. + * One of UART1-5 could be the console; one of UART1-5 has already been + * assigned to ttys0. + */ + +#if defined(CONFIG_IMX6_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART5) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART2-5. It can't be UART1 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-5 could be the + * console. One of UART2-5 has already been assigned to ttys0 or ttyS1. + */ + +#if defined(CONFIG_IMX6_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART5) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART3-5. It can't be UART1-2 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART32-5 could also be the console. One of UART3-5 has already + * been assigned to ttys0, 1, or 3. + */ + +#if defined(CONFIG_IMX6_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART5) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART4-5. It can't be UART1-3 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 4-5 could be the console. One of UART4-5 has already been + * assigned to ttys0, 1, 3, or 4. + */ + +#if defined(CONFIG_IMX6_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_IMX6_UART5) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#endif + +/* UART, if avaialble, should have been assigned to ttyS0-4. */ + +#if defined(CONFIG_IMX6_UART5) && !defined(UART5_ASSIGNED) +# errnor UART5 was not assigned to a TTY. +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct imx_uart_s +{ + xcpt_t handler; /* Interrupt handler */ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ucr1; /* Saved UCR1 value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + uint8_t stopbits2:1; /* 1: Configure with 2 stop bits vs 1 */ + uint8_t hwfc:1; /* 1: Hardware flow control */ + uint8_t reserved:6; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t imx_serialin(struct imx_uart_s *priv, + uint32_t offset); +static inline void imx_serialout(struct imx_uart_s *priv, uint32_t offset, + uint32_t value); +static inline void imx_disableuartint(struct imx_uart_s *priv, + uint32_t *ucr1); +static inline void imx_restoreuartint(struct imx_uart_s *priv, + uint32_t ucr1); +static inline void imx_waittxready(struct imx_uart_s *priv); + +static int imx_setup(struct uart_dev_s *dev); +static void imx_shutdown(struct uart_dev_s *dev); +static int imx_attach(struct uart_dev_s *dev); +static void imx_detach(struct uart_dev_s *dev); + +static int imx_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_IMX6_UART1 +static int imx_uart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_IMX6_UART2 +static int imx_uart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_IMX6_UART3 +static int imx_uart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_IMX6_UART4 +static int imx_uart4_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_IMX6_UART5 +static int imx_uart5_interrupt(int irq, void *context); +#endif + +static int imx_ioctl(struct file *filep, int cmd, unsigned long arg); +static int imx_receive(struct uart_dev_s *dev, uint32_t *status); +static void imx_rxint(struct uart_dev_s *dev, bool enable); +static bool imx_rxavailable(struct uart_dev_s *dev); +static void imx_send(struct uart_dev_s *dev, int ch); +static void imx_txint(struct uart_dev_s *dev, bool enable); +static bool imx_txready(struct uart_dev_s *dev); +static bool imx_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = imx_setup, + .shutdown = imx_shutdown, + .attach = imx_attach, + .detach = imx_detach, + .ioctl = imx_ioctl, + .receive = imx_receive, + .rxint = imx_rxint, + .rxavailable = imx_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = imx_send, + .txint = imx_txint, + .txready = imx_txready, + .txempty = imx_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_IMX6_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX6_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX6_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX6_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif + +#ifdef CONFIG_IMX6_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif + +/* This describes the state of the IMX uart1 port. */ + +#ifdef CONFIG_IMX6_UART1 +static struct imx_uart_s g_uart1priv = +{ + .handler = imx_uart1_interrupt, + .uartbase = IMX_UART1_VBASE, + .baud = CONFIG_UART1_BAUD, + .irq = IMX_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static struct uart_dev_s g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the IMX uart2 port. */ + +#ifdef CONFIG_IMX6_UART2 +static struct imx_uart_s g_uart2priv = +{ + .handler = imx_uart2_interrupt, + .uartbase = IMX_UART2_VBASE, + .baud = CONFIG_UART2_BAUD, + .irq = IMX_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static struct uart_dev_s g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +#ifdef CONFIG_IMX6_UART3 +static struct imx_uart_s g_uart3priv = +{ + .handler = imx_uart3_interrupt, + .uartbase = IMX_UART3_REGISTER_BASE, + .baud = IMX_UART3_VBASE, + .irq = IMX_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static struct uart_dev_s g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +#ifdef CONFIG_IMX6_UART4 +static struct imx_uart_s g_uart4priv = +{ + .handler = imx_uart4_interrupt, + .uartbase = IMX_UART4_REGISTER_BASE, + .baud = IMX_UART4_VBASE, + .irq = IMX_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static struct uart_dev_s g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +#ifdef CONFIG_IMX6_UART5 +static struct imx_uart_s g_uart5priv = +{ + .handler = imx_uart5_interrupt, + .uartbase = IMX_UART5_REGISTER_BASE, + .baud = IMX_UART5_VBASE, + .irq = IMX_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +}; + +static struct uart_dev_s g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_serialin + ****************************************************************************/ + +static inline uint32_t imx_serialin(struct imx_uart_s *priv, uint32_t offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: imx_serialout + ****************************************************************************/ + +static inline void imx_serialout(struct imx_uart_s *priv, uint32_t offset, + uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: imx_disableuartint + ****************************************************************************/ + +static inline void imx_disableuartint(struct imx_uart_s *priv, + uint32_t *ucr1) +{ + /* Return the current Rx and Tx interrupt state */ + + if (ucr1 != NULL) + { + *ucr1 = priv->ucr1 & (UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + } + + /* Then disable both Rx and Tx interrupts */ + + priv->ucr1 &= ~(UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + imx_serialout(priv, UART_UCR1_OFFSET, priv->ucr1); +} + +/**************************************************************************** + * Name: imx_restoreuartint + ****************************************************************************/ + +static inline void imx_restoreuartint(struct imx_uart_s *priv, uint32_t ucr1) +{ + /* Enable/disable any interrupts that are currently disabled but should be + * enabled/disabled. + */ + + priv->ucr1 &= ~(UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + priv->ucr1 |= ucr1 & (UART_UCR1_RRDYEN | UART_UCR1_TXEMPTYEN); + imx_serialout(priv, UART_UCR1_OFFSET, priv->ucr1); +} + +/**************************************************************************** + * Name: imx_waittxready + ****************************************************************************/ + +static inline void imx_waittxready(struct imx_uart_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((imx_serialin(priv, UART_UTS_OFFSET) & UART_UTS_TXFULL) == 0) + { + break; + } + } +} + +/**************************************************************************** + * Name: imx_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int imx_setup(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct uart_config_s config; + int ret; + + /* Configure the UART */ + + config.baud = priv->baud; /* Configured baud */ + config.parity = priv->parity; /* 0=none, 1=odd, 2=even */ + config.bits = priv->bits; /* Number of bits (5-9) */ + config.stopbits2 = priv->stopbits2; /* true: Configure with 2 stop bits instead of 1 */ + + ret = imx_uart_configure(priv->uartbase, &config); + + /* Initialize the UCR1 shadow register */ + + priv->ucr1 = imx_serialin(priv, UART_UCR1_OFFSET); + return ret; + +#else + /* Initialize the UCR1 shadow register */ + + priv->ucr1 = imx_serialin(priv, UART_UCR1_OFFSET); + return OK; +#endif +} + +/**************************************************************************** + * Name: imx_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void imx_shutdown(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* Disable the UART */ + + imx_serialout(priv, UART_UCR1_OFFSET, 0); + imx_serialout(priv, UART_UCR2_OFFSET, 0); + imx_serialout(priv, UART_UCR3_OFFSET, 0); + imx_serialout(priv, UART_UCR4_OFFSET, 0); +} + +/**************************************************************************** + * Name: imx_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int imx_attach(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: imx_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void imx_detach(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: imx_interrupt (and front-ends) + * + * Description: + * This is the common UART interrupt handler. It should cal + * uart_transmitchars or uart_receivechar to perform the appropriate data + * transfers. + * + ****************************************************************************/ + +static int imx_interrupt(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + uint32_t usr1; + int passes = 0; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (; ; ) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + usr1 = imx_serialin(priv, UART_USR1_OFFSET); + usr1 &= (UART_USR1_RRDY | UART_USR1_TRDY); + + if (usr1 == 0 || passes > 256) + { + return OK; + } + + /* Handline incoming, receive bytes */ + + if (usr1 & UART_USR1_RRDY) + { + uart_recvchars(dev); + } + + /* Handle outgoing, transmit bytes */ + + if (usr1 & UART_USR1_TRDY && + (imx_serialin(priv, UART_UCR1_OFFSET) & UART_UCR1_TXEMPTYEN) != 0) + { + uart_xmitchars(dev); + } + + /* Keep track of how many times we do this in case there + * is some hardware failure condition. + */ + + passes++; + } +} + +/**************************************************************************** + * Name: imx_uart[n]_interrupt + * + * Description: + * UART-specific interrupt handlers just transfer control to the common + * UART interrupt handler, passing the relevant driver state structure. + * + ****************************************************************************/ + +#ifdef CONFIG_IMX6_UART1 +static int imx_uart1_interrupt(int irq, void *context) +{ + return imx_interrupt(&g_uart1port); +} +#endif +#ifdef CONFIG_IMX6_UART2 +static int imx_uart2_interrupt(int irq, void *context) +{ + return imx_interrupt(&g_uart2port); +} +#endif +#ifdef CONFIG_IMX6_UART3 +static int imx_uart3_interrupt(int irq, void *context) +{ + return imx_interrupt(&g_uart3port); +} +#endif +#ifdef CONFIG_IMX6_UART4 +static int imx_uart4_interrupt(int irq, void *context) +{ + return imx_interrupt(&g_uart4port); +} +#endif +#ifdef CONFIG_IMX6_UART5 +static int imx_uart5_interrupt(int irq, void *context) +{ + return imx_interrupt(&g_uart5port); +} +#endif + +/**************************************************************************** + * Name: imx_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int imx_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct imx_uart_s *user = (struct imx_uart_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct imx_uart_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: imx_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int imx_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + uint32_t rxd0; + + rxd0 = imx_serialin(priv, UART_RXD_OFFSET); + *status = rxd0; + return (rxd0 & UART_RXD_DATA_MASK) >> UART_RXD_DATA_SHIFT; +} + +/**************************************************************************** + * Name: imx_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void imx_rxint(struct uart_dev_s *dev, bool enable) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* Enable interrupts for data availab at Rx FIFO */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ucr1 |= UART_UCR1_RRDYEN; +#endif + } + else + { + priv->ucr1 &= ~UART_UCR1_RRDYEN; + } + + imx_serialout(priv, UART_UCR1_OFFSET, priv->ucr1); +} + +/**************************************************************************** + * Name: imx_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool imx_rxavailable(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* Return true is data is ready in the Rx FIFO */ + + return ((imx_serialin(priv, UART_USR2_OFFSET) & UART_USR2_RDR) != 0); +} + +/**************************************************************************** + * Name: imx_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void imx_send(struct uart_dev_s *dev, int ch) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + imx_serialout(priv, UART_TXD_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: imx_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void imx_txint(struct uart_dev_s *dev, bool enable) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* We won't take an interrupt until the FIFO is completely empty (although + * there may still be a transmission in progress). + */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ucr1 |= UART_UCR1_TXEMPTYEN; +#endif + } + else + { + priv->ucr1 &= ~UART_UCR1_TXEMPTYEN; + } + + imx_serialout(priv, UART_UCR1_OFFSET, priv->ucr1); +} + +/**************************************************************************** + * Name: imx_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool imx_txready(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* When TXFULL is set, there is no space in the Tx FIFO */ + + return ((imx_serialin(priv, UART_UTS_OFFSET) & UART_UTS_TXFULL) == 0); +} + +/**************************************************************************** + * Name: imx_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool imx_txempty(struct uart_dev_s *dev) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)dev->priv; + + /* When TXDC is set, the FIFO is empty and the transmission is complete */ + + return ((imx_serialin(priv, UART_USR2_OFFSET) & UART_USR2_TXDC) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void imx_earlyserialinit(void) +{ + /* NOTE: This function assumes that low level hardware configuration + * -- including all clocking and pin configuration -- was perfomed by the + * function imx_lowsetup() earlier in the boot sequence. + */ + + /* Enable the console UART. The other UARTs will be initialized if and + * when they are first opened. + */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + imx_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that imx_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +# ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +# ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +# ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS2_DEV); +# ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS2_DEV); +# endif +# endif +# endif +# endif +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct imx_uart_s *priv = (struct imx_uart_s *)CONSOLE_DEV.priv; + uint32_t ier; + + imx_disableuartint(priv, &ier); + imx_waittxready(priv); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + imx_serialout(priv, UART_TXD_OFFSET, (uint32_t)'\r'); + imx_waittxready(priv); + } + + imx_serialout(priv, UART_TXD_OFFSET, (uint32_t)ch); + imx_waittxready(priv); + imx_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +# undef IMX_CONSOLE_VBASE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART1_VBASE +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART2_VBASE +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART3_VBASE +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART4_VBASE +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define IMX_CONSOLE_VBASE IMX_UART5_VBASE +# endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef IMX_CONSOLE_VBASE +static inline void imx_waittxready(void) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Loop until TXFULL is zero -- meaning that there is space available + * in the TX FIFO. + */ + + if ((getreg32(IMX_CONSOLE_VBASE + UART_UTS) & UART_UTS_TXFULL) == 0) + { + break; + } + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef IMX_CONSOLE_VBASE + imx_waittxready(); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + putreg32((uint16_t)'\r', IMX_CONSOLE_VBASE + UART_TXD_OFFSET); + imx_waittxready(); + } + + putreg32((uint16_t)ch, IMX_CONSOLE_VBASE + UART_TXD_OFFSET); +#endif + + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/imx6/imx_serial.h b/arch/arm/src/imx6/imx_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..45093f26046f3ea00b5fd05b527fc542dab6d637 --- /dev/null +++ b/arch/arm/src/imx6/imx_serial.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_serial.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX6_IMX_SERIAL_H +#define __ARCH_ARM_SRC_IMX6_IMX_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" +#include "imx_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void imx_earlyserialinit(void); +#endif + +/**************************************************************************** + * Name: uart_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#if defined(USE_EARLYSERIALINIT) && defined(IMX6_HAVE_UART) +void uart_earlyserialinit(void); +#endif + +/**************************************************************************** + * Name: uart_serialinit + * + * Description: + * Register the UART serial console and serial ports. This assumes that + * uart_earlyserialinit was called previously. + * + ****************************************************************************/ + +#ifdef IMX6_HAVE_UART +void uart_serialinit(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_IMX6_IMX_SERIAL_H */ diff --git a/arch/arm/src/imx6/imx_timerisr.c b/arch/arm/src/imx6/imx_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..50d405973f607ca1d11a6813ee139eaeacc023df --- /dev/null +++ b/arch/arm/src/imx6/imx_timerisr.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_timerisr.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/imx_ccm.h" +#include "chip/imx_gpt.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The Peripheral Clock (ipg_clk) is selected as the GPT clock source. NOTE + * that the ipg_clk may be turned off in low power modes, stopping the timer + * which is probably what you want. + * + * REVISIT: Here we assume that the Peripheral Clock is 66MHz. That is: + * + * PLL528 -> CBCDR: ahb_podf -> CBCDR: ipg_podf ->ipg_clk_root + * 3-bit timer 3-bit timer + * default=4 default=2 + * + * So, Peripheral Clock Frequency = 528 / 4 / 2 = 66 MHz + */ + +#define GPT_CLOCK 66000000 +#define GPT_CLKSRC_VALUE GPT_CR_CLKSRC_PERIPHCLK + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * We should be able to use a prescaler of 1. + */ + +#define GPT_PR_VALUE 1 +#define GPT_OCR3_VALUE ((GPT_CLOCK + ((1*CLK_TCK) >> 1)) / (1*CLK_TCK)) +#define GPT_OCR2_VALUE ((GPT_CLOCK + ((2*CLK_TCK) >> 1)) / (2*CLK_TCK)) +#define GPT_OCR1_VALUE ((GPT_CLOCK + ((3*CLK_TCK) >> 1)) / (3*CLK_TCK)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_output_compare + * + * Description: + * Handle one pending output compare interrupt. + * + ****************************************************************************/ + +static void up_output_compare(uint32_t sr, uint32_t of) +{ + /* Check for a pending output compare interrupt */ + + if ((sr & of) != 0) + { + /* Clear the pending output compare interrupt */ + + putreg32(of, IMX_GPT_SR); + + /* Process timer interrupt event */ + + sched_process_timer(); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Sample the SR (once) and process all pending output compare interrupt */ + + uint32_t sr = getreg32(IMX_GPT_SR); + up_output_compare(sr, GPT_INT_OF1); + up_output_compare(sr, GPT_INT_OF2); + up_output_compare(sr, GPT_INT_OF3); + return OK; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + uint32_t cr; + + /* Disable GPT interrupts at the GIC */ + + up_disable_irq(IMX_IRQ_GPT); + + /* Make certain that the ipg_clock and ipg_clk_highfreq are enabled for + * the GPT module. Here we set BOTH the ipg_clk and ipg_clk_highfreq so + * that clocking is on in all modes (except STOP). + */ + + regval = getreg32(IMX_CCM_CCGR1); + regval &= ~(CCM_CCGR1_CG10_MASK | CCM_CCGR1_CG11_MASK); + regval |= (CCM_CCGR1_CG10(CCM_CCGR_ALLMODES) | + CCM_CCGR1_CG11(CCM_CCGR_ALLMODES)); + putreg32(regval, IMX_CCM_CCGR1); + + /* Disable GPT by setting EN=0 in GPT_CR register */ + + cr = getreg32(IMX_GPT_CR); + cr &= ~GPT_CR_EN; + putreg32(cr, IMX_GPT_CR); + + /* Disable GPT interrupt register (GPT_IR) */ + + putreg32(0, IMX_GPT_IR); + + /* Configure Output Mode to unconnected/ disconnected—Write zeros in OM3, + * OM2, and OM1 in GPT_CR. + */ + + cr &= ~(GPT_CR_OM1_MASK | GPT_CR_OM2_MASK | GPT_CR_OM3_MASK); + cr |= (GPT_CR_OM1_DISCON | GPT_CR_OM2_DISCON | GPT_CR_OM3_DISCON); + putreg32(cr, IMX_GPT_CR); + + /* Disable Input Capture Modes—Write zeros in IM1 and IM2 in GPT_CR */ + + cr &= ~(GPT_CR_IM1_MASK | GPT_CR_IM2_MASK); + cr |= (GPT_CR_IM1_DISABLED | GPT_CR_IM2_DISABLED); + putreg32(cr, IMX_GPT_CR); + + /* Change clock source CLKSRC to the desired value in GPT_CR register */ + + cr &= ~GPT_CR_CLKSRC_MASK; + cr |= GPT_CLKSRC_VALUE; + putreg32(cr, IMX_GPT_CR); + + /* Assert the SWR bit in GPT_CR register. The SWR bit is cleared when the + * reset procedure finishes. Setting the SWR bit resets all of the + * registers to their default reset values, except for the CLKSRC, EN, + * ENMOD, STOPEN, WAITEN, and DBGEN bits in the GPT Control Register. + */ + + putreg32(cr | GPT_CR_SWR, IMX_GPT_CR); + + /* Clear GPT status register */ + + putreg32(GPT_INT_ALL, IMX_GPT_SR); + + /* Configure the prescaler and output compare registers */ + + putreg32(GPT_OCR1_VALUE, IMX_GPT_OCR1); + putreg32(GPT_OCR2_VALUE, IMX_GPT_OCR2); + putreg32(GPT_OCR3_VALUE, IMX_GPT_OCR3); + + putreg32(GPT_PR_VALUE - 1, IMX_GPT_PR); + + /* Configure restart mode. Interrupts will be received on OC3, then OC2, + * then OC1 when the counter will be reset to zero and the whole sequence + * starts again. + * + * FFR=0: Restart mode + */ + + cr &= ~GPT_CR_FFR; + putreg32(cr | GPT_CR_SWR, IMX_GPT_CR); + + /* Set ENMOD=1 in GPT_CR register, to bring GPT counter to 0x00000000. If + * the ENMOD bit is 1, then the Main Counter and Prescaler Counter values + * are reset to 0 *after* GPT is enabled (EN=1). + */ + + cr |= GPT_CR_ENMOD; + putreg32(cr, IMX_GPT_CR); + + /* Enable GPT (EN=1) in GPT_CR register */ + + cr |= GPT_CR_EN; + putreg32(cr, IMX_GPT_CR); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(IMX_IRQ_GPT, (xcpt_t)up_timerisr); + + /* Enable all three GPT output compare interrupts */ + + putreg32(GPT_INT_OF1 | GPT_INT_OF2 | GPT_INT_OF3, IMX_GPT_IR); + + /* And enable the timer interrupt at the GIC */ + + up_enable_irq(IMX_IRQ_GPT); +} diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9540050b6680cc6843dfccb0353b8065d43c96ce --- /dev/null +++ b/arch/arm/src/kinetis/Kconfig @@ -0,0 +1,526 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Kinetis Configuration Options" + +choice + prompt "Kinetis Chip Selection" + default ARCH_CHIP_MK60N512VMD100 + depends on ARCH_CHIP_KINETIS + +config ARCH_CHIP_MK20DN32VLH5 + bool "MK20DN32VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX32VLH5 + bool "MK20DX32VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DN64VLH5 + bool "MK20DN64VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX64VLH5 + bool "MK20DX64VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DN128VLH5 + bool "MK20DN128VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX128VLH5 + bool "MK20DX128VLH5" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX64VLH7 + bool "MK20DX64VLH7" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX128VLH7 + bool "MK20DX128VLH7" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK20DX256VLH7 + bool "MK20DX256VLH7" + select ARCH_FAMILY_K20 + +config ARCH_CHIP_MK40N512VLQ100 + bool "MK40N512VLQ100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK40N512VMD100 + bool "MK40N512VMD100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK40X128VLQ100 + bool "MK40X128VLQ100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK40X128VMD100 + bool "MK40X128VMD100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK40X256VLQ100 + bool "MK40X256VLQ100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK40X256VMD100 + bool "MK40X256VMD100" + select ARCH_FAMILY_K40 + +config ARCH_CHIP_MK60N256VLQ100 + bool "MK60N256VLQ100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60N256VMD100 + bool "MK60N256VMD100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60N512VLL100 + bool "MK60N512VLL100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60N512VLQ100 + bool "MK60N512VLQ100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60N512VMD100 + bool "MK60N512VMD100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60X256VLQ100 + bool "MK60X256VLQ100" + select ARCH_FAMILY_K60 + +config ARCH_CHIP_MK60X256VMD100 + bool "MK60X256VMD100" + select ARCH_FAMILY_K60 + +endchoice + +# Chip families + +config ARCH_FAMILY_K20 + bool + default n + +config ARCH_FAMILY_K40 + bool + default n + +config ARCH_FAMILY_K60 + bool + default n + +menu "Kinetis Peripheral Support" + +config KINETIS_TRACE + bool "Trace" + default n + ---help--- + Enable trace clocking on power up. + +config KINETIS_FLEXBUS + bool "FlexBus" + default n + ---help--- + Enable flexbus clocking on power up. + +config KINETIS_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + ---help--- + Support UART0 + +config KINETIS_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + ---help--- + Support UART1 + +config KINETIS_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + ---help--- + Support UART2 + +config KINETIS_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + ---help--- + Support UART3 + +config KINETIS_UART4 + bool "UART4" + default n + select ARCH_HAVE_UART4 + ---help--- + Support UART4 + +config KINETIS_UART5 + bool "UART5" + default n + select ARCH_HAVE_UART5 + ---help--- + Support UART5 + +config KINETIS_ENET + bool "Ethernet" + default n + depends on ARCH_FAMILY_K60 + select NET + select ARCH_HAVE_NETDEV_STATISTICS + ---help--- + Support Ethernet (K60 only) + +config KINETIS_RNGB + bool "Random number generator" + default n + depends on ARCH_FAMILY_K60 + select ARCH_HAVE_RNG + ---help--- + Support the random number generator(K60 only) + +config KINETIS_FLEXCAN0 + bool "FlexCAN0" + default n + ---help--- + Support FlexCAN0 + +config KINETIS_FLEXCAN1 + bool "FlexCAN1" + default n + ---help--- + Support FlexCAN1 + +config KINETIS_SPI0 + bool "SPI0" + default n + ---help--- + Support SPI0 + +config KINETIS_SPI1 + bool "SPI1" + default n + ---help--- + Support SPI1 + +config KINETIS_SPI2 + bool "SPI2" + default n + ---help--- + Support SPI2 + +config KINETIS_I2C0 + bool "I2C0" + default n + ---help--- + Support I2C0 + +config KINETIS_I2C1 + bool "I2C1" + default n + ---help--- + Support I2C1 + +config KINETIS_I2S + bool "I2S" + default n + ---help--- + Support I2S + +config KINETIS_DAC0 + bool "DAC0" + default n + ---help--- + Support DAC0 + +config KINETIS_DAC1 + bool "DAC1" + default n + ---help--- + Support DAC1 + +config KINETIS_ADC0 + bool "ADC0" + default n + ---help--- + Support ADC0 + +config KINETIS_ADC1 + bool "ADC1" + default n + ---help--- + Support ADC1 + +config KINETIS_CMP + bool "CMP" + default n + ---help--- + Support CMP + +config KINETIS_VREF + bool "VREF" + default n + ---help--- + Support VREF + +config KINETIS_SDHC + bool "SDHC" + default n + select ARCH_HAVE_SDIO + ---help--- + Support SD host controller + +config KINETIS_FTM0 + bool "FTM0" + default n + ---help--- + Support FlexTimer 0 + +config KINETIS_FTM1 + bool "FTM1" + default n + ---help--- + Support FlexTimer 1 + +config KINETIS_FTM2 + bool "FTM2" + default n + ---help--- + Support FlexTimer 2 + +config KINETIS_LPTIMER + bool "Low power timer (LPTIMER)" + default n + ---help--- + Support the low power timer + +config KINETIS_RTC + bool "RTC" + default n + ---help--- + Support RTC + +config KINETIS_SLCD + bool "Segment LCD (SLCD)" + default n + depends on ARCH_FAMILY_K40 + ---help--- + Support the segment LCD (K40 only) + +config KINETIS_EWM + bool "External watchdog (WVM)" + default n + ---help--- + Support the external watchdog + +config KINETIS_CMT + bool "Carrier modulator transmitter (CMT)" + default n + ---help--- + Support Carrier Modulator Transmitter + +config KINETIS_USBOTG + bool "USB OTG" + default n + ---help--- + Support USB OTG (see also USBHOST and USBDEV) + +config KINETIS_USBDCD + bool "USB device controller" + default n + ---help--- + Support the USB Device Charger Detection module + +config KINETIS_LLWU + bool "Low leakage wake-up unit (LLWU)" + default n + ---help--- + Support the Low Leakage Wake-Up Unit + +config KINETIS_TSI + bool "Touchscreen interface (TSI)" + default n + ---help--- + Support the touch screeen interface + +config KINETIS_FTFL + bool "FLASH (FTFL)" + default n + ---help--- + Support FLASH + +config KINETIS_DMA + bool "DMA" + default n + ---help--- + Support DMA + +config KINETIS_CRC + bool "CRC" + default n + ---help--- + Support CRC + +config KINETIS_PDB + bool "Programmable delay block (PDB)" + default n + ---help--- + Support the Programmable Delay Block + +config KINETIS_PIT + bool "Programmable interval timer (PIT)" + default n + ---help--- + Support Programmable Interval Timers + +endmenu + +comment "Kinetis GPIO Interrupt Configuration" + +config GPIO_IRQ + bool "GPIO pin interrupts" + ---help--- + Enable support for interrupting GPIO pins + +if GPIO_IRQ + +config KINETIS_PORTAINTS + bool "GPIOA interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port A pins + +config KINETIS_PORTBINTS + bool "GPIOB interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port B pins + +config KINETIS_PORTCINTS + bool "GPIOC interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port C pins + +config KINETIS_PORTDINTS + bool "GPIOD interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port D pins + +config KINETIS_PORTEINTS + bool "GPIOE interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port E pins + +endif + +if KINETIS_ENET + +comment "Kinetis Ethernet Configuration" + +config ENET_ENHANCEDBD + bool "Use enhanced buffer descriptors" + default n + ---help--- + Use enhanced, 32-byte buffer descriptors + +config ENET_NETHIFS + int "Number of Ethernet interfaces" + default 1 + ---help--- + Number of Ethernet interfaces supported by the hardware. Must be + one for now. + +config ENET_NRXBUFFERS + int "Number of Ethernet Rx buffers" + default 6 + ---help--- + Number of Ethernet Rx buffers to use. The size of one buffer is + determined by NET_BUFSIZE + +config ENET_NTXBUFFERS + int "Number of Ethernet Tx buffers" + default 2 + ---help--- + Number of Ethernet Tx buffers to use. The size of one buffer is + determined by NET_BUFSIZE + +config ENET_PHYADDR + int "PHY address" + default 1 + ---help--- + MII/RMII address of the PHY + +config ENET_USEMII + bool "Use MII interface" + default n + ---help--- + The the MII PHY interface. Default: Use RMII interface + +endif + +if KINETIS_SDHC + +comment "Kinetis SDHC Configuration" + +config KINETIS_SDHC_ABSFREQ + bool "Custom transfer frequencies" + default n + ---help--- + Select SDCLK frequencies corresponding to various modes of operation. + These values may be provided in either the NuttX configuration file + or in the board.h file + + NOTE: These settings are not currently used. Since there are only + four frequencies, it makes more sense to just "can" the fixed + frequency prescaler and divider values. + +if KINETIS_SDHC_ABSFREQ + +config KINETIS_IDMODE_FREQ + int "ID mode frequency" + default 400000 + ---help--- + Initial, ID mode SD frequency + +config KINETIS_MMCXFR_FREQ + int "MMC transfer frequency" + default 20000000 + ---help--- + Frequency to use for transferring data to/from an MMC card + +config KINETIS_SD1BIT_FREQ + int "SD 1-bit transfer frequency" + default 20000000 + depends on SDIO_WIDTH_D1_ONLY + ---help--- + Frequency to use for transferring data to/from an SD card using on a single data liune. + +config KINETIS_SD4BIT_FREQ + int "SD 4-bit transfer frequency" + default 20000000 + depends on !SDIO_WIDTH_D1_ONLY + ---help--- + Frequency to use for transferring data to/from an SD card using all four data lines. + +endif + +config KINETIS_SDHC_DMAPRIO + int "SDHC DMA priority" + depends on SDIO_DMA + ---help--- + SDHC DMA priority + +endif + +comment "Kinetis UART Configuration" + +config KINETIS_UARTFIFOS + bool "Enable UART0 FIFO" + default n + depends on KINETIS_UART0 diff --git a/arch/arm/src/kinetis/Make.defs b/arch/arm/src/kinetis/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..c9c5ec6ca802c979bb4f056e4a6ff9b8e95ff2fd --- /dev/null +++ b/arch/arm/src/kinetis/Make.defs @@ -0,0 +1,134 @@ +############################################################################ +# arch/arm/src/kinetis/Make.defs +# +# Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = kinetis_vectors.S + +# Common ARM and Cortex-M3 files + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_releasepending.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_checkstack.c up_vfork.c +CMN_CSRCS += up_systemreset.c + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +# Use of common/up_etherstub.c is deprecated. The preferred mechanism is to +# use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in +# up_initialize(). Then this stub would not be needed. + +ifeq ($(CONFIG_NET),y) +ifneq ($(CONFIG_KINETIS_ENET),y) +CMN_CSRCS += up_etherstub.c +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +# Required Kinetis files + +CHIP_ASRCS = + +CHIP_CSRCS = kinetis_allocateheap.c kinetis_clockconfig.c +CHIP_CSRCS += kinetis_clrpend.c kinetis_idle.c kinetis_irq.c +CHIP_CSRCS += kinetis_lowputc.c kinetis_pin.c kinetis_pingpio.c +CHIP_CSRCS += kinetis_serial.c kinetis_start.c kinetis_wdog.c +CHIP_CSRCS += kinetis_cfmconfig.c + +# Configuration-dependent Kinetis files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += kinetis_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += kinetis_userspace.c kinetis_mpuinit.c +endif + +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += kinetis_pinirq.c +endif + +ifeq ($(CONFIG_DEBUG_GPIO),y) +CHIP_CSRCS += kinetis_pindbg.c +endif + +ifeq ($(CONFIG_KINETIS_SDHC),y) +CHIP_CSRCS += kinetis_sdhc.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += kinetis_usbdev.c +endif + +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += kinetis_usbhost.c +endif + +ifeq ($(CONFIG_KINETIS_DMA),y) +CHIP_CSRCS += kinetis_dma.c kinetis_pindma.c +endif + +ifeq ($(CONFIG_NET),y) +ifeq ($(CONFIG_KINETIS_ENET),y) +CHIP_CSRCS += kinetis_enet.c +endif +endif diff --git a/arch/arm/src/kinetis/chip.h b/arch/arm/src/kinetis/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..0ed152bac2f52203fe3ac39ebe4a6a48b6eac622 --- /dev/null +++ b/arch/arm/src/kinetis/chip.h @@ -0,0 +1,68 @@ +/************************************************************************************ + * arch/arm/src/kinetis/chip.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_H +#define __ARCH_ARM_SRC_KINETIS_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include "kinetis_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_H */ diff --git a/arch/arm/src/kinetis/kinetis.h b/arch/arm/src/kinetis/kinetis.h new file mode 100644 index 0000000000000000000000000000000000000000..f84dd226b8981c108dd5fee707e5ff9582f5a04a --- /dev/null +++ b/arch/arm/src/kinetis/kinetis.h @@ -0,0 +1,849 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis.h + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "kinetis_config.h" +#include "chip.h" +#include "kinetis_port.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +/* Bit-encoded input to kinetis_pinconfig() *****************************************/ +/* General form (32-bits, only 22 bits are unused in the encoding): + * + * oooo mmmv iiii ifd- ---- -ppp ---b bbbb + */ + +/* Bits 25-31: 7 bits are used to encode the basic pin configuration: + * + * oooo mmm- ---- ---- ---- ---- ---- ---- + * | `--- mmm: mode + * `------- oooo: options (may be combined) + */ + +#define _PIN_MODE_SHIFT (25) /* Bits 25-27: Pin mode */ +#define _PIN_MODE_MASK (7 << _PIN_MODE_SHIFT) +#define _PIN_OPTIONS_SHIFT (28) /* Bits 28-31: Pin mode options */ +#define _PIN_OPTIONS_MASK (15 << _PIN_OPTIONS_SHIFT) + +/* Port Modes */ + /* Unshifted versions: */ +#define PIN_MODE_ANALOG (0) /* 000 Pin Disabled (Analog) */ +#define PIN_MODE_GPIO (1) /* 001 Alternative 1 (GPIO) */ +#define PIN_MODE_ALT2 (2) /* 010 Alternative 2 */ +#define PIN_MODE_ALT3 (3) /* 011 Alternative 3 */ +#define PIN_MODE_ALT4 (4) /* 100 Alternative 4 */ +#define PIN_MODE_ALT5 (5) /* 101 Alternative 5 */ +#define PIN_MODE_ALT6 (6) /* 110 Alternative 6 */ +#define PIN_MODE_ALT7 (7) /* 111 Alternative 7 */ + /* Shifted versions: */ +#define _PIN_MODE_ANALOG (0 << _PIN_MODE_SHIFT) /* 000 Pin Disabled (Analog) */ +#define _PIN_MODE_GPIO (1 << _PIN_MODE_SHIFT) /* 001 Alternative 1 (GPIO) */ +#define _PIN_MODE_ALT2 (2 << _PIN_MODE_SHIFT) /* 010 Alternative 2 */ +#define _PIN_MODE_ALT3 (3 << _PIN_MODE_SHIFT) /* 011 Alternative 3 */ +#define _PIN_MODE_ALT4 (4 << _PIN_MODE_SHIFT) /* 100 Alternative 4 */ +#define _PIN_MODE_ALT5 (5 << _PIN_MODE_SHIFT) /* 101 Alternative 5 */ +#define _PIN_MODE_ALT6 (6 << _PIN_MODE_SHIFT) /* 110 Alternative 6 */ +#define _PIN_MODE_ALT7 (7 << _PIN_MODE_SHIFT) /* 111 Alternative 7 */ + +/* Options for all digital modes (Alternatives 1-7). None of the digital + * options apply if the analog mode is selected. + */ + +#define _PIN_IO_MASK (1 << _PIN_OPTIONS_SHIFT) /* xxx1 Digital input/output mask */ +#define _PIN_INPUT (0 << _PIN_OPTIONS_SHIFT) /* xxx0 Digital input */ +#define _PIN_OUTPUT (1 << _PIN_OPTIONS_SHIFT) /* xxx1 Digital output */ + +#define _PIN_INPUT_PULLMASK (7 << _PIN_OPTIONS_SHIFT) /* x111 Mask for pull-up or -down bits */ +#define _PIN_INPUT_PULLDOWN (2 << _PIN_OPTIONS_SHIFT) /* x010 Input with internal pull-down resistor */ +#define _PIN_INPUT_PULLUP (6 << _PIN_OPTIONS_SHIFT) /* x110 Input with internal pull-up resistor */ + +#define _PIN_OUTPUT_SLEW_MASK (3 << _PIN_OPTIONS_SHIFT) /* xx11 Mask to test for slow slew rate */ +#define _PIN_OUTPUT_FAST (1 << _PIN_OPTIONS_SHIFT) /* xx01 Output with fast slew rate */ +#define _PIN_OUTPUT_SLOW (3 << _PIN_OPTIONS_SHIFT) /* xx11 Output with slow slew rate */ +#define _PIN_OUTPUT_OD_MASK (5 << _PIN_OPTIONS_SHIFT) /* x1x1 Mask to test for open drain */ +#define _PIN_OUTPUT_OPENDRAIN (5 << _PIN_OPTIONS_SHIFT) /* x1x1 Output with open drain enabled */ +#define _PIN_OUTPUT_DRIVE_MASK (9 << _PIN_OPTIONS_SHIFT) /* 1xx1 Mask to test for high drive strengh */ +#define _PIN_OUTPUT_LOWDRIVE (1 << _PIN_OPTIONS_SHIFT) /* 0xx1 Output with low drive strength */ +#define _PIN_OUTPUT_HIGHDRIVE (9 << _PIN_OPTIONS_SHIFT) /* 1xx1 Output with high drive strength */ + +/* End-user pin modes and configurations. Notes: (1) None of the digital options + * are available for the analog mode, (2) digital settings may be combined (OR'ed) + * provided that input-only and output-only options are not intermixed. + */ + +#define PIN_ANALOG _PIN_MODE_ANALOG + +#define GPIO_INPUT (_PIN_MODE_GPIO | _PIN_INPUT) +#define GPIO_PULLDOWN (_PIN_MODE_GPIO | _PIN_INPUT_PULLDOWN) +#define GPIO_PULLUP (_PIN_MODE_GPIO | _PIN_INPUT_PULLUP) +#define GPIO_OUTPUT (_PIN_MODE_GPIO | _PIN_OUTPUT) +#define GPIO_FAST (_PIN_MODE_GPIO | _PIN_OUTPUT_FAST) +#define GPIO_SLOW (_PIN_MODE_GPIO | _PIN_OUTPUT_SLOW) +#define GPIO_OPENDRAIN (_PIN_MODE_GPIO | _PIN_OUTPUT_LOWDRIVE) +#define GPIO_LOWDRIVE (_PIN_MODE_GPIO | _PIN_OUTPUT_OPENDRAIN) +#define GPIO_HIGHDRIVE (_PIN_MODE_GPIO | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT2 _PIN_MODE_ALT2 +#define PIN_ALT2_INPUT (_PIN_MODE_ALT2 | _PIN_INPUT) +#define PIN_ALT2_PULLDOWN (_PIN_MODE_ALT2 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT2_PULLUP (_PIN_MODE_ALT2 | _PIN_INPUT_PULLUP) +#define PIN_ALT2_OUTPUT (_PIN_MODE_ALT2 | _PIN_OUTPUT) +#define PIN_ALT2_FAST (_PIN_MODE_ALT2 | _PIN_OUTPUT_FAST) +#define PIN_ALT2_SLOW (_PIN_MODE_ALT2 | _PIN_OUTPUT_SLOW) +#define PIN_ALT2_OPENDRAIN (_PIN_MODE_ALT2 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT2_LOWDRIVE (_PIN_MODE_ALT2 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT2_HIGHDRIVE (_PIN_MODE_ALT2 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT3 _PIN_MODE_ALT3 +#define PIN_ALT3_INPUT (_PIN_MODE_ALT3 | _PIN_INPUT) +#define PIN_ALT3_PULLDOWN (_PIN_MODE_ALT3 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT3_PULLUP (_PIN_MODE_ALT3 | _PIN_INPUT_PULLUP) +#define PIN_ALT3_OUTPUT (_PIN_MODE_ALT3 | _PIN_OUTPUT) +#define PIN_ALT3_FAST (_PIN_MODE_ALT3 | _PIN_OUTPUT_FAST) +#define PIN_ALT3_SLOW (_PIN_MODE_ALT3 | _PIN_OUTPUT_SLOW) +#define PIN_ALT3_OPENDRAIN (_PIN_MODE_ALT3 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT3_LOWDRIVE (_PIN_MODE_ALT3 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT3_HIGHDRIVE (_PIN_MODE_ALT3 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT4 _PIN_MODE_ALT4 +#define PIN_ALT4_INPUT (_PIN_MODE_ALT4 | _PIN_INPUT) +#define PIN_ALT4_PULLDOWN (_PIN_MODE_ALT4 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT4_PULLUP (_PIN_MODE_ALT4 | _PIN_INPUT_PULLUP) +#define PIN_ALT4_OUTPUT (_PIN_MODE_ALT4 | _PIN_OUTPUT) +#define PIN_ALT4_FAST (_PIN_MODE_ALT4 | _PIN_OUTPUT_FAST) +#define PIN_ALT4_SLOW (_PIN_MODE_ALT4 | _PIN_OUTPUT_SLOW) +#define PIN_ALT4_OPENDRAIN (_PIN_MODE_ALT4 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT4_LOWDRIVE (_PIN_MODE_ALT4 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT4_HIGHDRIVE (_PIN_MODE_ALT4 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT5 _PIN_MODE_ALT5 +#define PIN_ALT5_INPUT (_PIN_MODE_ALT5 | _PIN_INPUT) +#define PIN_ALT5_PULLDOWN (_PIN_MODE_ALT5 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT5_PULLUP (_PIN_MODE_ALT5 | _PIN_INPUT_PULLUP) +#define PIN_ALT5_OUTPUT (_PIN_MODE_ALT5 | _PIN_OUTPUT) +#define PIN_ALT5_FAST (_PIN_MODE_ALT5 | _PIN_OUTPUT_FAST) +#define PIN_ALT5_SLOW (_PIN_MODE_ALT5 | _PIN_OUTPUT_SLOW) +#define PIN_ALT5_OPENDRAIN (_PIN_MODE_ALT5 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT5_LOWDRIVE (_PIN_MODE_ALT5 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT5_HIGHDRIVE (_PIN_MODE_ALT5 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT6 _PIN_MODE_ALT6 +#define PIN_ALT6_INPUT (_PIN_MODE_ALT6 | _PIN_INPUT) +#define PIN_ALT6_PULLDOWN (_PIN_MODE_ALT6 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT6_PULLUP (_PIN_MODE_ALT6 | _PIN_INPUT_PULLUP) +#define PIN_ALT6_OUTPUT (_PIN_MODE_ALT6 | _PIN_OUTPUT) +#define PIN_ALT6_FAST (_PIN_MODE_ALT6 | _PIN_OUTPUT_FAST) +#define PIN_ALT6_SLOW (_PIN_MODE_ALT6 | _PIN_OUTPUT_SLOW) +#define PIN_ALT6_OPENDRAIN (_PIN_MODE_ALT6 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT6_LOWDRIVE (_PIN_MODE_ALT6 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT6_HIGHDRIVE (_PIN_MODE_ALT6 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT7 _PIN_MODE_ALT7 +#define PIN_ALT7_INPUT (_PIN_MODE_ALT7 | _PIN_INPUT) +#define PIN_ALT7_PULLDOWN (_PIN_MODE_ALT7 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT7_PULLUP (_PIN_MODE_ALT7 | _PIN_INPUT_PULLUP) +#define PIN_ALT7_OUTPUT (_PIN_MODE_ALT7 | _PIN_OUTPUT) +#define PIN_ALT7_FAST (_PIN_MODE_ALT7 | _PIN_OUTPUT_FAST) +#define PIN_ALT7_SLOW (_PIN_MODE_ALT7 | _PIN_OUTPUT_SLOW) +#define PIN_ALT7_OPENDRAIN (_PIN_MODE_ALT7 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT7_LOWDRIVE (_PIN_MODE_ALT7 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT7_HIGHDRIVE (_PIN_MODE_ALT7 | _PIN_OUTPUT_HIGHDRIVE) + +/* The initial value for GPIO (Alternative 1 outputs): + * + * ---- ---v ---- ---- ---- ---- ---- ---- + * + * Passive Filter and digital filter enable are valid in all digital pin + * muxing modes. + */ + +#define GPIO_OUTPUT_ONE (1 << 24) /* Bit 24: 1:Initial output value=1 */ +#define GPIO_OUTPUT_ZER0 (0) /* Bit 24: 0:Initial output value=0 */ + +/* Five bits are used to incode DMA/interrupt options: + * + * ---- ---- iiii i--- ---- ---- ---- ---- + * + * The pin interrupt configuration is valid in all digital pin muxing modes + * (restricted to inputs). + */ + +#define _PIN_INT_SHIFT (20) +#define _PIN_INT_MASK (31 << _PIN_INT_SHIFT) + +#define _PIN_INTDMA_MASK (3 << _PIN_INT_SHIFT) +#define _PIN_INTDMA_NONE (0 << _PIN_INT_SHIFT) +#define _PIN_DMA (1 << _PIN_INT_SHIFT) +#define _PIN_INTERRUPT (2 << _PIN_INT_SHIFT) + +#define PIN_DMA_RISING (5 << _PIN_INT_SHIFT) /* 00101 DMA Request on rising edge */ +#define PIN_DMA_FALLING (9 << _PIN_INT_SHIFT) /* 01001 DMA Request on falling edge */ +#define PIN_DMA_BOTH (13 << _PIN_INT_SHIFT) /* 01101 DMA Request on either edge */ +#define PIN_INT_ZERO (2 << _PIN_INT_SHIFT) /* 00010 Interrupt when logic zero */ +#define PIN_INT_RISING (6 << _PIN_INT_SHIFT) /* 00110 Interrupt on rising edge */ +#define PIN_INT_FALLING (10 << _PIN_INT_SHIFT) /* 01010 Interrupt on falling edge */ +#define PIN_INT_BOTH (14 << _PIN_INT_SHIFT) /* 01110 Interrupt on either edge */ +#define PIN_INT_ONE (18 << _PIN_INT_SHIFT) /* 10010 Interrupt when logic one */ + +/* Two bits is used to enable the filter options: + * + * ---- ---- ---- -fd- ---- ---- ---- ---- + * + * Passive Filter and digital filter enable are valid in all digital pin + * muxing modes. + */ + +#define PIN_PASV_FILTER (1 << 18) /* Bit 18: Enable passive filter */ +#define PIN_DIG_FILTER (1 << 17) /* Bit 17: Enable digital filter */ + +/* Three bits are used to define the port number: + * + * ---- ---- ---- ---- ---- -ppp ---- ---- + */ + +#define _PIN_PORT_SHIFT (8) /* Bits 8-10: port number */ +#define _PIN_PORT_MASK (7 << _PIN_PORT_SHIFT) + +#define PIN_PORTA (KINETIS_PORTA << _PIN_PORT_SHIFT) +#define PIN_PORTB (KINETIS_PORTB << _PIN_PORT_SHIFT) +#define PIN_PORTC (KINETIS_PORTC << _PIN_PORT_SHIFT) +#define PIN_PORTD (KINETIS_PORTD << _PIN_PORT_SHIFT) +#define PIN_PORTE (KINETIS_PORTE << _PIN_PORT_SHIFT) + +/* Five bits are used to define the pin number: + * + * ---- ---- ---- ---- ---- ---- ---b bbbb + */ + +#define _PIN_SHIFT (0) /* Bits 0-4: port number */ +#define _PIN_MASK (31 << _PIN_SHIFT) + +#define PIN(n) ((n) << _PIN_SHIFT) +#define PIN0 (0 << _PIN_SHIFT) +#define PIN1 (1 << _PIN_SHIFT) +#define PIN2 (2 << _PIN_SHIFT) +#define PIN3 (3 << _PIN_SHIFT) +#define PIN4 (4 << _PIN_SHIFT) +#define PIN5 (5 << _PIN_SHIFT) +#define PIN6 (6 << _PIN_SHIFT) +#define PIN7 (7 << _PIN_SHIFT) +#define PIN8 (8 << _PIN_SHIFT) +#define PIN9 (9 << _PIN_SHIFT) +#define PIN10 (10 << _PIN_SHIFT) +#define PIN11 (11 << _PIN_SHIFT) +#define PIN12 (12 << _PIN_SHIFT) +#define PIN13 (13 << _PIN_SHIFT) +#define PIN14 (14 << _PIN_SHIFT) +#define PIN15 (15 << _PIN_SHIFT) +#define PIN16 (16 << _PIN_SHIFT) +#define PIN17 (17 << _PIN_SHIFT) +#define PIN18 (18 << _PIN_SHIFT) +#define PIN19 (19 << _PIN_SHIFT) +#define PIN20 (20 << _PIN_SHIFT) +#define PIN21 (21 << _PIN_SHIFT) +#define PIN22 (22 << _PIN_SHIFT) +#define PIN23 (23 << _PIN_SHIFT) +#define PIN24 (24 << _PIN_SHIFT) +#define PIN25 (25 << _PIN_SHIFT) +#define PIN26 (26 << _PIN_SHIFT) +#define PIN27 (27 << _PIN_SHIFT) +#define PIN28 (28 << _PIN_SHIFT) +#define PIN29 (29 << _PIN_SHIFT) +#define PIN30 (30 << _PIN_SHIFT) +#define PIN31 (31 << _PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct kinetis_dmaglobalregs_s +{ +#warning "Missing logic" + /* Global Registers */ +}; + +struct kinetis_dmachanregs_s +{ +#warning "Missing logic" + /* Channel Registers */ +}; + +struct kinetis_dmaregs_s +{ + /* Global Registers */ + + struct kinetis_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct kinetis_dmachanregs_s ch; +}; +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: kinetis_clockconfig + * + * Description: + * Called to initialize the Kinetis chip. This does whatever setup is needed to + * put the MCU in a usable state. This includes the initialization of clocking + * using the settings in board.h. + * + ************************************************************************************/ + +void kinetis_clockconfig(void); + +/************************************************************************************ + * Name: kinetis_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void kinetis_lowsetup(void); + +/**************************************************************************** + * Name: kinetis_uartreset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kinetis_uartreset(uintptr_t uart_base); +#endif + +/**************************************************************************** + * Name: kinetis_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock, + unsigned int parity, unsigned int nbits); +#endif + +/************************************************************************************ + * Name: kinetis_wddisable + * + * Description: + * Disable the watchdog timer + * + ************************************************************************************/ + +void kinetis_wddisable(void); + +/************************************************************************************ + * Name: kinetis_pinconfig + * + * Description: + * Configure a pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int kinetis_pinconfig(uint32_t cfgset); + +/************************************************************************************ + * Name: kinetis_pinfilter + * + * Description: + * Configure the digital filter associated with a port. The digital filter + * capabilities of the PORT module are available in all digital pin muxing modes. + * + * Input parmeters: + * port - See KINETIS_PORTn definitions in kinetis_port.h + * lpo - true: Digital Filters are clocked by the bus clock + * false: Digital Filters are clocked by the 1 kHz LPO clock + * width - Filter Length + * + ************************************************************************************/ + +int kinetis_pinfilter(unsigned int port, bool lpo, unsigned int width); + +/************************************************************************************ + * Name: kinetis_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void kinetis_gpiowrite(uint32_t pinset, bool value); + +/************************************************************************************ + * Name: kinetis_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool kinetis_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: kinetis_pinirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void kinetis_pinirqinitialize(void); +#else +# define kinetis_pinirqinitialize() +#endif + +/************************************************************************************ + * Name: kinetis_pinirqattach + * + * Description: + * Attach a pin interrupt handler. The normal initalization sequence is: + * + * 1. Call kinetis_pinconfig() to configure the interrupting pin (pin interrupts + * will be disabled. + * 2. Call kinetis_pinirqattach() to attach the pin interrupt handling function. + * 3. Call kinetis_pinirqenable() to enable interrupts on the pin. + * + * Parameters: + * - pinset: Pin configuration + * - pinisr: Pin interrupt service routine + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t kinetis_pinirqattach(uint32_t pinset, xcpt_t pinisr); + +/************************************************************************************ + * Name: kinetis_pinirqenable + * + * Description: + * Enable the interrupt for specified pin IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void kinetis_pinirqenable(uint32_t pinset); +#else +# define kinetis_pinirqenable(pinset) +#endif + +/************************************************************************************ + * Name: kinetis_pinirqdisable + * + * Description: + * Disable the interrupt for specified pin + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void kinetis_pinirqdisable(uint32_t pinset); +#else +# define kinetis_pinirqdisable(pinset) +#endif + +/************************************************************************************ + * Name: kinetis_pindmaenable + * + * Description: + * Enable DMA for specified pin + * + ************************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +void kinetis_pindmaenable(uint32_t pinset); +#endif + +/************************************************************************************ + * Name: kinetis_pindmadisable + * + * Description: + * Disable DMA for specified pin + * + ************************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +void kinetis_pindmadisable(uint32_t pinset); +#endif + +/************************************************************************************ + * Function: kinetis_pindump + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int kinetis_pindump(uint32_t pinset, const char *msg); +#else +# define kinetis_pindump(p,m) +#endif + +/************************************************************************************ + * Name: kinetis_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. + * + ************************************************************************************/ + +void kinetis_clrpend(int irq); + +/************************************************************************************ + * Name: kinetis_spi[n]select, kinetis_spi[n]status, and kinetis_spi[n]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including kinetis_spibus_initialize()) are provided by common Kinetis logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in kinetis_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide kinetis_spi[n]select() and kinetis_spi[n]status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * kinetis_spi[n]cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to kinetis_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by kinetis_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +#ifdef CONFIG_KINETIS_SPI0 +void kinetis_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t kinetis_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int kinetis_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif +#ifdef CONFIG_KINETIS_SPI1 +void kinetis_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t kinetis_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int kinetis_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif +#ifdef CONFIG_KINETIS_SPI2 +void kinetis_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t kinetis_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int kinetis_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from spi[n]select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_KINETIS_SPI0) || defined(CONFIG_KINETIS_SPI0) || defined(CONFIG_KINETIS_SPI2) +struct spi_dev_s; +void spi_flush(FAR struct spi_dev_s *dev); +#endif + +/**************************************************************************** + * Name: kinetis_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +void kinetis_dmainitilaize(void); +#endif + +/**************************************************************************** + * Name: kinetis_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +DMA_HANDLE kinetis_dmachannel(void); +#endif + +/**************************************************************************** + * Name: kinetis_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until kinetis_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +void kinetis_dmafree(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: kinetis_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +int kinetis_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); +#endif + +/**************************************************************************** + * Name: kinetis_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +int kinetis_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); +#endif + +/**************************************************************************** + * Name: kinetis_dmastop + * + * Description: + * Cancel the DMA. After kinetis_dmastop() is called, the DMA channel is + * reset and kinetis_dmasetup() must be called before kinetis_dmastart() can be + * called again + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +void kinetis_dmastop(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: kinetis_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmasample(DMA_HANDLE handle, struct kinetis_dmaregs_s *regs); +#else +# define kinetis_dmasample(handle,regs) +#endif +#endif + +/**************************************************************************** + * Name: kinetis_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_DMA +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmadump(DMA_HANDLE handle, const struct kinetis_dmaregs_s *regs, + const char *msg); +#else +# define kinetis_dmadump(handle,regs,msg) +#endif +#endif + +/**************************************************************************** + * Name: sdhc_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_SDHC +struct sdio_dev_s; +FAR struct sdio_dev_s *sdhc_initialize(int slotno); +#endif + +/**************************************************************************** + * Name: sdhc_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_SDHC +void sdhc_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); +#endif + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_SDHC +void sdhc_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); +#endif +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_H */ diff --git a/arch/arm/src/kinetis/kinetis_adc.h b/arch/arm/src/kinetis/kinetis_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..a17aa06c7f4274ca8a612e933cafec3c43c9bd71 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_adc.h @@ -0,0 +1,313 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_adc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_ADC_SC1A_OFFSET 0x0000 /* ADC status and control registers 1 */ +#define KINETIS_ADC_SC1B_OFFSET 0x0004 /* ADC status and control registers 1 */ +#define KINETIS_ADC_CFG1_OFFSET 0x0008 /* ADC configuration register 1 */ +#define KINETIS_ADC_CFG2_OFFSET 0x000c /* Configuration register 2 */ +#define KINETIS_ADC_RA_OFFSET 0x0010 /* ADC data result register */ +#define KINETIS_ADC_RB_OFFSET 0x0014 /* ADC data result register */ +#define KINETIS_ADC_CV1_OFFSET 0x0018 /* Compare value registers */ +#define KINETIS_ADC_CV2_OFFSET 0x001c /* Compare value registers */ +#define KINETIS_ADC_SC2_OFFSET 0x0020 /* Status and control register 2 */ +#define KINETIS_ADC_SC3_OFFSET 0x0024 /* Status and control register 3 */ +#define KINETIS_ADC_OFS_OFFSET 0x0028 /* ADC offset correction register */ +#define KINETIS_ADC_PG_OFFSET 0x002c /* ADC plus-side gain register */ +#define KINETIS_ADC_MG_OFFSET 0x0030 /* ADC minus-side gain register */ +#define KINETIS_ADC_CLPD_OFFSET 0x0034 /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLPS_OFFSET 0x0038 /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLP4_OFFSET 0x003c /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLP3_OFFSET 0x0040 /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLP2_OFFSET 0x0044 /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLP1_OFFSET 0x0048 /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_CLP0_OFFSET 0x004c /* ADC plus-side general calibration value register */ +#define KINETIS_ADC_PGA_OFFSET 0x0050 /* ADC PGA register */ +#define KINETIS_ADC_CLMD_OFFSET 0x0054 /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLMS_OFFSET 0x0058 /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLM4_OFFSET 0x005c /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLM3_OFFSET 0x0060 /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLM2_OFFSET 0x0064 /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLM1_OFFSET 0x0068 /* ADC minus-side general calibration value register */ +#define KINETIS_ADC_CLM0_OFFSET 0x006c /* ADC minus-side general calibration value register */ + +/* Register Addresses ***********************************************************************/ +# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */ + +#define KINETIS_ADC0_SC1A (KINETIS_ADC0_BASE+KINETIS_ADC_SC1A_OFFSET) +#define KINETIS_ADC0_SC1B (KINETIS_ADC0_BASE+KINETIS_ADC_SC1B_OFFSET) +#define KINETIS_ADC0_CFG1 (KINETIS_ADC0_BASE+KINETIS_ADC_CFG1_OFFSET) +#define KINETIS_ADC0_CFG2 (KINETIS_ADC0_BASE+KINETIS_ADC_CFG2_OFFSET) +#define KINETIS_ADC0_RA (KINETIS_ADC0_BASE+KINETIS_ADC_RA_OFFSET) +#define KINETIS_ADC0_RB (KINETIS_ADC0_BASE+KINETIS_ADC_RB_OFFSET) +#define KINETIS_ADC0_CV1 (KINETIS_ADC0_BASE+KINETIS_ADC_CV1_OFFSET) +#define KINETIS_ADC0_CV2 (KINETIS_ADC0_BASE+KINETIS_ADC_CV2_OFFSET) +#define KINETIS_ADC0_SC2 (KINETIS_ADC0_BASE+KINETIS_ADC_SC2_OFFSET) +#define KINETIS_ADC0_SC3 (KINETIS_ADC0_BASE+KINETIS_ADC_SC3_OFFSET) +#define KINETIS_ADC0_OFS (KINETIS_ADC0_BASE+KINETIS_ADC_OFS_OFFSET) +#define KINETIS_ADC0_PG (KINETIS_ADC0_BASE+KINETIS_ADC_PG_OFFSET) +#define KINETIS_ADC0_MG (KINETIS_ADC0_BASE+KINETIS_ADC_MG_OFFSET) +#define KINETIS_ADC0_CLPD (KINETIS_ADC0_BASE+KINETIS_ADC_CLPD_OFFSET) +#define KINETIS_ADC0_CLPS (KINETIS_ADC0_BASE+KINETIS_ADC_CLPS_OFFSET) +#define KINETIS_ADC0_CLP4 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP4_OFFSET) +#define KINETIS_ADC0_CLP3 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP3_OFFSET) +#define KINETIS_ADC0_CLP2 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP2_OFFSET) +#define KINETIS_ADC0_CLP1 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP1_OFFSET) +#define KINETIS_ADC0_CLP0 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP0_OFFSET) +#define KINETIS_ADC0_PGA (KINETIS_ADC0_BASE+KINETIS_ADC_PGA_OFFSET) +#define KINETIS_ADC0_CLMD (KINETIS_ADC0_BASE+KINETIS_ADC_CLMD_OFFSET) +#define KINETIS_ADC0_CLMS (KINETIS_ADC0_BASE+KINETIS_ADC_CLMS_OFFSET) +#define KINETIS_ADC0_CLM4 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM4_OFFSET) +#define KINETIS_ADC0_CLM3 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM3_OFFSET) +#define KINETIS_ADC0_CLM2 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM2_OFFSET) +#define KINETIS_ADC0_CLM1 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM1_OFFSET) +#define KINETIS_ADC0_CLM0 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM0_OFFSET) + +#define KINETIS_ADC1_SC1A (KINETIS_ADC1_BASE+KINETIS_ADC_SC1A_OFFSET) +#define KINETIS_ADC1_SC1B (KINETIS_ADC1_BASE+KINETIS_ADC_SC1B_OFFSET) +#define KINETIS_ADC1_CFG1 (KINETIS_ADC1_BASE+KINETIS_ADC_CFG1_OFFSET) +#define KINETIS_ADC1_CFG2 (KINETIS_ADC1_BASE+KINETIS_ADC_CFG2_OFFSET) +#define KINETIS_ADC1_RA (KINETIS_ADC1_BASE+KINETIS_ADC_RA_OFFSET) +#define KINETIS_ADC1_RB (KINETIS_ADC1_BASE+KINETIS_ADC_RB_OFFSET) +#define KINETIS_ADC1_CV1 (KINETIS_ADC1_BASE+KINETIS_ADC_CV1_OFFSET) +#define KINETIS_ADC1_CV2 (KINETIS_ADC1_BASE+KINETIS_ADC_CV2_OFFSET) +#define KINETIS_ADC1_SC2 (KINETIS_ADC1_BASE+KINETIS_ADC_SC2_OFFSET) +#define KINETIS_ADC1_SC3 (KINETIS_ADC1_BASE+KINETIS_ADC_SC3_OFFSET) +#define KINETIS_ADC1_OFS (KINETIS_ADC1_BASE+KINETIS_ADC_OFS_OFFSET) +#define KINETIS_ADC1_PG (KINETIS_ADC1_BASE+KINETIS_ADC_PG_OFFSET) +#define KINETIS_ADC1_MG (KINETIS_ADC1_BASE+KINETIS_ADC_MG_OFFSET) +#define KINETIS_ADC1_CLPD (KINETIS_ADC1_BASE+KINETIS_ADC_CLPD_OFFSET) +#define KINETIS_ADC1_CLPS (KINETIS_ADC1_BASE+KINETIS_ADC_CLPS_OFFSET) +#define KINETIS_ADC1_CLP4 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP4_OFFSET) +#define KINETIS_ADC1_CLP3 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP3_OFFSET) +#define KINETIS_ADC1_CLP2 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP2_OFFSET) +#define KINETIS_ADC1_CLP1 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP1_OFFSET) +#define KINETIS_ADC1_CLP0 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP0_OFFSET) +#define KINETIS_ADC1_PGA (KINETIS_ADC1_BASE+KINETIS_ADC_PGA_OFFSET) +#define KINETIS_ADC1_CLMD (KINETIS_ADC1_BASE+KINETIS_ADC_CLMD_OFFSET) +#define KINETIS_ADC1_CLMS (KINETIS_ADC1_BASE+KINETIS_ADC_CLMS_OFFSET) +#define KINETIS_ADC1_CLM4 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM4_OFFSET) +#define KINETIS_ADC1_CLM3 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM3_OFFSET) +#define KINETIS_ADC1_CLM2 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM2_OFFSET) +#define KINETIS_ADC1_CLM1 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM1_OFFSET) +#define KINETIS_ADC1_CLM0 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM0_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* ADC status and control registers 1 */ + +#define ADC_SC1_ADCH_SHIFT (0) /* Bits 0-4: Input channel select */ +#define ADC_SC1_ADCH_MASK (31 << ADC_SC1_ADCH_SHIFT) +# define ADC_SC1_ADCH_DADP0 (0 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 DADP0; DIFF=1, DAD0 */ +# define ADC_SC1_ADCH_DADP1 (1 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 DADP1; DIFF=1, DAD1 */ +# define ADC_SC1_ADCH_DADP2 (2 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 DADP2; DIFF=1, DAD2 */ +# define ADC_SC1_ADCH_DADP3 (3 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 DADP3; DIFF=1, DAD3 */ +# define ADC_SC1_ADCH_AD4 (4 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD4; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD5 (5 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD5; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD6 (6 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD6; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD7 (7 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD7; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD8 (8 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD8; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD9 (9 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD9; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD10 (10 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD10; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD11 (11 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD11; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD12 (12 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD12; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD13 (13 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD13; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD14 (14 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD14; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD15 (15 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD15; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD16 (16 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD16; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD17 (17 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD17; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD18 (18 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD18; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD19 (19 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD19; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD20 (20 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD20; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD21 (21 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD21; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD22 (22 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD22; DIFF=1 reserved */ +# define ADC_SC1_ADCH_AD23 (23 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 AD23; DIFF=1 reserved */ +# define ADC_SC1_ADCH_TEMP (26 << ADC_SC1_ADCH_SHIFT) /* Temp sensor */ +# define ADC_SC1_ADCH_BANDGAP (27 << ADC_SC1_ADCH_SHIFT) /* Bandgap */ +# define ADC_SC1_ADCH_VREFSH (29 << ADC_SC1_ADCH_SHIFT) /* VREFSH */ +# define ADC_SC1_ADCH_VREFSL (30 << ADC_SC1_ADCH_SHIFT) /* DIFF=0 VREFSL; DIFF=1 reserved */ +# define ADC_SC1_ADCH_DISABLED (31 << ADC_SC1_ADCH_SHIFT) /* Module disabled */ +#define ADC_SC1_DIFF (1 << 5) /* Bit 5: Differential mode enable */ +#define ADC_SC1_AIEN (1 << 6) /* Bit 6: Interrupt enable */ +#define ADC_SC1_COCO (1 << 7) /* Bit 7: Conversion complete flag */ + /* Bits 8-31: Reserved */ +/* ADC configuration register 1 */ + +#define ADC_CFG1_ADICLK_SHIFT (0) /* Bits 0-1: Input clock select */ +#define ADC_CFG1_ADICLK_MASK (3 << ADC_CFG1_ADICLK_SHIFT) +# define ADC_CFG1_ADICLK_BUSCLK (0 << ADC_CFG1_ADICLK_SHIFT) /* Bus clock */ +# define ADC_CFG1_ADICLK_BUSDIV2 (1 << ADC_CFG1_ADICLK_SHIFT) /* Bus clock/ 2 */ +# define ADC_CFG1_ADICLK_ALTCLK (2 << ADC_CFG1_ADICLK_SHIFT) /* Alternate clock */ +# define ADC_CFG1_ADICLK_ADACK (3 << ADC_CFG1_ADICLK_SHIFT) /* Asynchronous clock */ +#define ADC_CFG1_MODE_SHIFT (2) /* Bits 2-3: Conversion mode selection */ +#define ADC_CFG1_MODE_MASK (3 << ADC_CFG1_MODE_SHIFT) +# define ADC_CFG1_MODE_89BIT (0 << ADC_CFG1_MODE_SHIFT) /* DIFF=0 8-bit; DIFF=1 9-bit */ +# define ADC_CFG1_MODE_1213BIT (1 << ADC_CFG1_MODE_SHIFT) /* DIFF=0 12-bit; DIFF=1 13-bit */ +# define ADC_CFG1_MODE_1011BIT (2 << ADC_CFG1_MODE_SHIFT) /* DIFF=0 10-bit; DIFF=1 11-bit */ +# define ADC_CFG1_MODE_1616BIT (3 << ADC_CFG1_MODE_SHIFT) /* DIFF=0 16-bit; DIFF=1 16-bit */ +#define ADC_CFG1_ADLSMP (1 << 4) /* Bit 4: Sample time configuration */ +#define ADC_CFG1_ADIV_SHIFT (5) /* Bits 5-6: Clock divide select */ +#define ADC_CFG1_ADIV_MASK (3 << ADC_CFG1_ADIV_SHIFT) +# define ADC_CFG1_ADIV_DIV1 (0 << ADC_CFG1_ADIV_SHIFT) /* Divider=1 rate=input clock */ +# define ADC_CFG1_ADIV_DIV2 (1 << ADC_CFG1_ADIV_SHIFT) /* Divider=2 rate=input clock/2 */ +# define ADC_CFG1_ADIV_DIV4 (2 << ADC_CFG1_ADIV_SHIFT) /* Divider=4 rate=input clock/4 */ +# define ADC_CFG1_ADIV_DIV5 (3 << ADC_CFG1_ADIV_SHIFT) /* Divider=8 rate=input clock/8 */ +#define ADC_CFG1_ADLPC (1 << 7) /* Bit 7: Low-power configuration */ + /* Bits 8-31: Reserved */ +/* Configuration register 2 */ + +#define ADC_CFG2_ADLSTS_SHIFT (0) /* Bits 0-1: Long sample time select */ +#define ADC_CFG2_ADLSTS_MASK (3 << ADC_CFG2_ADLSTS_SHIFT) +# define ADC_CFG2_ADLSTS_LONGEST (0 << ADC_CFG2_ADLSTS_SHIFT) /* Default longest sample time */ +# define ADC_CFG2_ADLSTS_PLUS12 (1 << ADC_CFG2_ADLSTS_SHIFT) /* 12 extra ADCK cycles */ +# define ADC_CFG2_ADLSTS_PLUS6 (2 << ADC_CFG2_ADLSTS_SHIFT) /* 6 extra ADCK cycles */ +# define ADC_CFG2_ADLSTS_PLUS2 (3 << ADC_CFG2_ADLSTS_SHIFT) /* 2 extra ADCK cycles */ +#define ADC_CFG2_ADHSC (1 << 2) /* Bit 2: High speed configuration */ +#define ADC_CFG2_ADACKEN (1 << 3) /* Bit 3: Asynchronous clock output enable */ +#define ADC_CFG2_MUXSEL (1 << 4) /* Bit 4: ADC Mux select */ + /* Bits 5-31: Reserved */ +/* ADC data result register */ + +#define ADC_R_MASK (0xffff) /* 16-bit signed or unsigned data */ + +/* Compare value registers */ + +#define ADC_CV_MASK (0xffff) /* Compare value */ + +/* Status and control register 2 */ + +#define ADC_SC2_REFSEL_SHIFT (0) /* Bits 0-1: Voltage reference selection */ +#define ADC_SC2_REFSEL_MASK (3 << ADC_SC2_REFSEL_SHIFT) +# define ADC_SC2_REFSEL_DEFAULT (0 << ADC_SC2_REFSEL_SHIFT) /* Default reference: V REFH and V REFL */ +# define ADC_SC2_REFSEL_ALT (1 << ADC_SC2_REFSEL_SHIFT) /* Alternate reference: V ALTH and V ALTL */ +#define ADC_SC2_DMAEN (1 << 2) /* Bit 2: DMA enable */ +#define ADC_SC2_ACREN (1 << 3) /* Bit 3: Compare function range enable */ +#define ADC_SC2_ACFGT (1 << 4) /* Bit 4: Compare function greater than enable */ +#define ADC_SC2_ACFE (1 << 5) /* Bit 5: Compare function enable */ +#define ADC_SC2_ADTRG (1 << 6) /* Bit 6: Conversion trigger select */ +#define ADC_SC2_ADACT (1 << 7) /* Bit 7: Conversion active */ + /* Bits 8-31: Reserved */ +/* Status and control register 3 */ + +#define ADC_SC3_AVGS_SHIFT (0) /* Bits 0-1: Hardware average select */ +#define ADC_SC3_AVGS_MASK (3 << ADC_SC3_AVGS_SHIFT) +# define ADC_SC3_AVGS_4SMPLS (0 << ADC_SC3_AVGS_SHIFT) /* 4 samples averaged */ +# define ADC_SC3_AVGS_8SMPLS (1 << ADC_SC3_AVGS_SHIFT) /* 8 samples averaged */ +# define ADC_SC3_AVGS_16SMPLS (2 << ADC_SC3_AVGS_SHIFT) /* 18 samples averaged */ +# define ADC_SC3_AVGS_32SMPLS (3 << ADC_SC3_AVGS_SHIFT) /* 32 samples averaged */ +#define ADC_SC3_AVGE (1 << 2) /* Bit 2: Hardware average enable */ +#define ADC_SC3_ADCO (1 << 3) /* Bit 3: Continuous conversion enable */ + /* Bits 4-5: Reserved */ +#define ADC_SC3_CALF (1 << 6) /* Bit 6: Calibration failed flag */ +#define ADC_SC3_CAL (1 << 7) /* Bit 7: Calibration */ + /* Bits 8-31: Reserved */ +/* ADC offset correction register */ + +#define ADC_OFS_MASK (0xffff) /* Bits 0-15: Offset error correction value */ + +/* ADC plus-side gain register */ + +#define ADC_PG_MASK (0xffff) /* Bits 0-15: Plus-side gain */ + +/* ADC minus-side gain register */ + +#define ADC_MG_MASK (0xffff) /* Bits 0-15: Minus-side gain */ + +/* ADC plus-side general calibration value registers */ + +#define ADC_CLPD_MASK (0x3f) /* Bits 0-5: Calibration value */ +#define ADC_CLPS_MASK (0x3f) /* Bits 0-5: Calibration value */ +#define ADC_CLP4_MASK (0x3ff) /* Bits 0-9: Calibration value */ +#define ADC_CLP3_MASK (0x1ff) /* Bits 0-8: Calibration value */ +#define ADC_CLP2_MASK (0xff) /* Bits 0-7: Calibration value */ +#define ADC_CLP1_MASK (0x7f) /* Bits 0-6: Calibration value */ +#define ADC_CLP0_MASK (0x3f) /* Bits 0-5: Calibration value */ + +/* ADC PGA register */ + /* Bits 0-15: Reserved */ +#define ADC_PGA_PGAG_SHIFT (16) /* Bits 16-19: PGA gain setting*/ +#define ADC_PGA_PGAG_MASK (15 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_1 (0 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_2 (1 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_4 (2 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_8 (3 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_16 (4 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_32 (5 << ADC_PGA_PGAG_SHIFT) +# define ADC_PGA_PGAG_64 (6 << ADC_PGA_PGAG_SHIFT) +#ifdef KINETIS_K40 +# define ADC_PGA_PGALP (1 << 20) /* Bit 20: PGA low-power mode control */ +#endif + /* Bits 21-22: Reserved */ +#define ADC_PGA_PGAEN (1 << 23) /* Bit 23: PGA enable*/ + /* Bits 24-31: Reserved */ +/* ADC minus-side general calibration value registers */ + +#define ADC_CLMD_MASK (0x3f) /* Bits 0-5: Calibration value */ +#define ADC_CLMS_MASK (0x3f) /* Bits 0-5: Calibration value */ +#define ADC_CLM4_MASK (0x3ff) /* Bits 0-9: Calibration value */ +#define ADC_CLM3_MASK (0x1ff) /* Bits 0-8: Calibration value */ +#define ADC_CLM2_MASK (0xff) /* Bits 0-7: Calibration value */ +#define ADC_CLM1_MASK (0x7f) /* Bits 0-6: Calibration value */ +#define ADC_CLM0_MASK (0x3f) /* Bits 0-5: Calibration value */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H */ diff --git a/arch/arm/src/kinetis/kinetis_aips.h b/arch/arm/src/kinetis/kinetis_aips.h new file mode 100644 index 0000000000000000000000000000000000000000..8f460567f76125052a24664fdc02843624729dba --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_aips.h @@ -0,0 +1,208 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_aips.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define KINETIS_AIPS_MPRA_OFFSET 0x0000 /* Master Privilege Register A */ + +#define KINETIS_AIPS_PACRA_OFFSET 0x0020 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRB_OFFSET 0x0024 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRC_OFFSET 0x0028 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRD_OFFSET 0x002c /* Peripheral Access Control Register */ + +#define KINETIS_AIPS_PACRE_OFFSET 0x0040 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRF_OFFSET 0x0044 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRG_OFFSET 0x0048 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRH_OFFSET 0x004c /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRI_OFFSET 0x0050 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRJ_OFFSET 0x0054 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRK_OFFSET 0x0058 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRL_OFFSET 0x005c /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRM_OFFSET 0x0060 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRN_OFFSET 0x0064 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRO_OFFSET 0x0068 /* Peripheral Access Control Register */ +#define KINETIS_AIPS_PACRP_OFFSET 0x006c /* Peripheral Access Control Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_AIPS0_MPRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_MPRA_OFFSET) +#define KINETIS_AIPS0_PACRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRA_OFFSET) +#define KINETIS_AIPS0_PACRB (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRB_OFFSET) +#define KINETIS_AIPS0_PACRC (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRC_OFFSET) +#define KINETIS_AIPS0_PACRD (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRD_OFFSET) +#define KINETIS_AIPS0_PACRE (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRE_OFFSET) +#define KINETIS_AIPS0_PACRF (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRF_OFFSET) +#define KINETIS_AIPS0_PACRG (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRG_OFFSET) +#define KINETIS_AIPS0_PACRH (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRH_OFFSET) +#define KINETIS_AIPS0_PACRI (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRI_OFFSET) +#define KINETIS_AIPS0_PACRJ (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRJ_OFFSET) +#define KINETIS_AIPS0_PACRK (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRK_OFFSET) +#define KINETIS_AIPS0_PACRL (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRL_OFFSET) +#define KINETIS_AIPS0_PACRM (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRM_OFFSET) +#define KINETIS_AIPS0_PACRN (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRN_OFFSET) +#define KINETIS_AIPS0_PACRO (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRO_OFFSET) +#define KINETIS_AIPS0_PACRP (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRP_OFFSET) + +#define KINETIS_AIPS1_MPRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_MPRA_OFFSET) +#define KINETIS_AIPS1_PACRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRA_OFFSET) +#define KINETIS_AIPS1_PACRB (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRB_OFFSET) +#define KINETIS_AIPS1_PACRC (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRC_OFFSET) +#define KINETIS_AIPS1_PACRD (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRD_OFFSET) +#define KINETIS_AIPS1_PACRE (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRE_OFFSET) +#define KINETIS_AIPS1_PACRF (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRF_OFFSET) +#define KINETIS_AIPS1_PACRG (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRG_OFFSET) +#define KINETIS_AIPS1_PACRH (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRH_OFFSET) +#define KINETIS_AIPS1_PACRI (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRI_OFFSET) +#define KINETIS_AIPS1_PACRJ (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRJ_OFFSET) +#define KINETIS_AIPS1_PACRK (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRK_OFFSET) +#define KINETIS_AIPS1_PACRL (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRL_OFFSET) +#define KINETIS_AIPS1_PACRM (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRM_OFFSET) +#define KINETIS_AIPS1_PACRN (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRN_OFFSET) +#define KINETIS_AIPS1_PACRO (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRO_OFFSET) +#define KINETIS_AIPS1_PACRP (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRP_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Master Privilege Register A */ + + /* Bits 0-7: Reserved */ +#define AIPS_MPRA_MPL5 (1 << 8) /* Bit 8: Master privilege level */ +#define AIPS_MPRA_MTW5 (1 << 9) /* Bit 9: Master trusted for writes */ +#define AIPS_MPRA_MTR5 (1 << 10) /* Bit 10: Master trusted for read */ + /* Bit 11 Reserved */ +#define AIPS_MPRA_MPL4 (1 << 12) /* Bit 12: Master privilege level */ +#define AIPS_MPRA_MTW4 (1 << 13) /* Bit 13: Master trusted for writes */ +#define AIPS_MPRA_MTR4 (1 << 14) /* Bit 14: Master trusted for read */ + /* Bit 15: Reserved */ +#define AIPS_MPRA_MPL3 (1 << 16) /* Bit 16: Master privilege level */ +#define AIPS_MPRA_MTW3 (1 << 17) /* Bit 17: Master trusted for writes */ +#define AIPS_MPRA_MTR3 (1 << 18) /* Bit 18: Master trusted for read */ + /* Bit 19: Reserved */ +#define AIPS_MPRA_MPL2 (1 << 20) /* Bit 20: Master privilege level */ +#define AIPS_MPRA_MTW2 (1 << 21) /* Bit 21: Master trusted for writes */ +#define AIPS_MPRA_MTR2 (1 << 22) /* Bit 22: Master trusted for read */ + /* Bit 23: Reserved */ +#define AIPS_MPRA_MPL1 (1 << 24) /* Bit 24: Master privilege level */ +#define AIPS_MPRA_MTW1 (1 << 25) /* Bit 25: Master trusted for writes */ +#define AIPS_MPRA_MTR1 (1 << 26) /* Bit 26: Master trusted for read */ + /* Bit 27: Reserved */ +#define AIPS_MPRA_MPL0 (1 << 28) /* Bit 28: Master privilege level */ +#define AIPS_MPRA_MTW0 (1 << 29) /* Bit 29: Master trusted for writes */ +#define AIPS_MPRA_MTR0 (1 << 30) /* Bit 30: Master trusted for read */ + /* Bit 31: Reserved */ + +/* Peripheral Access Control Register. Naming here is only accurate for PACRA. + * PACRA: PACR0 PACR1 PACR2 PACR3 PACR4 PACR5 PACR6 PACR7 + * PACRB: PACR8 PACR9 PACR10 PACR11 PACR12 PACR13 PACR14 PACR15 + * PACRC: PACR16 PACR17 PACR18 PACR19 PACR20 PACR21 PACR22 PACR23 + * PACRD: PACR24 PACR25 PACR26 PACR27 PACR28 PACR29 PACR30 PACR31 + * PACRE: PACR32 PACR33 PACR34 PACR35 PACR36 PACR37 PACR38 PACR39 + * PACRF: PACR40 PACR41 PACR42 PACR43 PACR44 PACR45 PACR46 PACR47 + * PACRG: PACR48 PACR49 PACR50 PACR51 PACR52 PACR53 PACR54 PACR55 + * PACRH: PACR56 PACR57 PACR58 PACR59 PACR60 PACR61 PACR62 PACR63 + * PACRI: PACR64 PACR65 PACR66 PACR67 PACR68 PACR69 PACR70 PACR71 + * PACRJ: PACR72 PACR73 PACR74 PACR75 PACR76 PACR77 PACR78 PACR79 + * PACRK: PACR80 PACR81 PACR82 PACR83 PACR84 PACR85 PACR86 PACR87 + * PACRL: PACR88 PACR89 PACR90 PACR91 PACR92 PACR93 PACR94 PACR95 + * PACRM: PACR96 PACR97 PACR98 PACR99 PACR100 PACR101 PACR102 PACR103 + * PACRN: PACR104 PACR105 PACR106 PACR107 PACR108 PACR109 PACR110 PACR111 + * PACRO: PACR112 PACR113 PACR114 PACR115 PACR116 PACR117 PACR118 PACR119 + * PACRP: PACR120 PACR121 PACR122 PACR123 PACR124 PACR125 PACR126 PACR127 + */ + +#define AIPS_PACR_TP(n) (1 << ((7 - ((n) & 7)) << 2)) +#define AIPS_PACR_WP(n) (2 << ((7 - ((n) & 7)) << 2)) +#define AIPS_PACR_SP(n) (4 << ((7 - ((n) & 7)) << 2)) + +#define AIPS_PACR_TP7 (1 << 0) /* Bit 0: Trusted protect */ +#define AIPS_PACR_WP7 (1 << 1) /* Bit 1: Write protect */ +#define AIPS_PACR_SP7 (1 << 2) /* Bit 2: Supervisor protect */ + /* Bit 3: Reserved */ +#define AIPS_PACR_TP6 (1 << 4) /* Bit 4: Trusted protect */ +#define AIPS_PACR_WP6 (1 << 5) /* Bit 5: Write protect */ +#define AIPS_PACR_SP6 (1 << 6) /* Bit 6: Supervisor protect */ + /* Bit 7: Reserved */ +#define AIPS_PACR_TP5 (1 << 8) /* Bit 8: Trusted protect */ +#define AIPS_PACR_WP5 (1 << 9) /* Bit 9: Write protect */ +#define AIPS_PACR_SP5 (1 << 10) /* Bit 10: Supervisor protect */ + /* Bit 11: Reserved */ +#define AIPS_PACR_TP4 (1 << 12) /* Bit 12: Trusted protect */ +#define AIPS_PACR_WP4 (1 << 13) /* Bit 13: Write protect */ +#define AIPS_PACR_SP4 (1 << 14) /* Bit 14: Supervisor protect */ + /* Bit 15: Reserved */ +#define AIPS_PACR_TP3 (1 << 16) /* Bit 16: Trusted protect */ +#define AIPS_PACR_WP3 (1 << 17) /* Bit 17: Write protect */ +#define AIPS_PACR_SP3 (1 << 18) /* Bit 18: Supervisor protect */ + /* Bit 19: Reserved */ +#define AIPS_PACR_TP2 (1 << 20) /* Bit 20: Trusted protect */ +#define AIPS_PACR_WP2 (1 << 21) /* Bit 21: Write protect */ +#define AIPS_PACR_SP2 (1 << 22) /* Bit 22: Supervisor protect */ + /* Bit 23: Reserved */ +#define AIPS_PACR_TP1 (1 << 24) /* Bit 24: Trusted protect */ +#define AIPS_PACR_WP1 (1 << 25) /* Bit 25: Write protect */ +#define AIPS_PACR_SP1 (1 << 26) /* Bit 26: Supervisor protect */ + /* Bit 27: Reserved */ +#define AIPS_PACR_TP0 (1 << 28) /* Bit 28: Trusted protect */ +#define AIPS_PACR_WP0 (1 << 29) /* Bit 29: Write protect */ +#define AIPS_PACR_SP0 (1 << 30) /* Bit 30: Supervisor protect */ + /* Bit 31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H */ diff --git a/arch/arm/src/kinetis/kinetis_allocateheap.c b/arch/arm/src/kinetis/kinetis_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..1eb21eeb4d944d89bc4b334e062d4779ea7390ed --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_allocateheap.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_allocateheap.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "kinetis_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + kinetis_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif diff --git a/arch/arm/src/kinetis/kinetis_axbs.h b/arch/arm/src/kinetis/kinetis_axbs.h new file mode 100644 index 0000000000000000000000000000000000000000..bf8543d4dac5a5dc5b13a4b110e447483d1dcdb7 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_axbs.h @@ -0,0 +1,251 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_axbs.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_AXBS_PRS_OFFSET(n) (0x0000 + ((n) << 8)) +#define KINETIS_AXBS_CRS_OFFSET(n) (0x0010 + ((n) << 8)) +#define KINETIS_AXBS_MGPCR_OFFSET(n) (0x0800 + ((n) << 8)) + +#define KINETIS_AXBS_PRS0_OFFSET 0x0000 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS0_OFFSET 0x0010 /* Control Register */ +#define KINETIS_AXBS_PRS1_OFFSET 0x0100 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS1_OFFSET 0x0110 /* Control Register */ +#define KINETIS_AXBS_PRS2_OFFSET 0x0200 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS2_OFFSET 0x0210 /* Control Register */ +#define KINETIS_AXBS_PRS3_OFFSET 0x0300 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS3_OFFSET 0x0310 /* Control Register */ +#define KINETIS_AXBS_PRS4_OFFSET 0x0400 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS4_OFFSET 0x0410 /* Control Register */ +#define KINETIS_AXBS_PRS5_OFFSET 0x0500 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS5_OFFSET 0x0510 /* Control Register */ +#define KINETIS_AXBS_PRS6_OFFSET 0x0600 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS6_OFFSET 0x0610 /* Control Register */ +#define KINETIS_AXBS_PRS7_OFFSET 0x0700 /* Priority Registers Slave */ +#define KINETIS_AXBS_CRS7_OFFSET 0x0710 /* Control Register */ +#define KINETIS_AXBS_MGPCR0_OFFSET 0x0800 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR1_OFFSET 0x0900 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR2_OFFSET 0x0a00 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR3_OFFSET 0x0b00 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR4_OFFSET 0x0c00 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR5_OFFSET 0x0d00 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR6_OFFSET 0x0e00 /* Master General Purpose Control Register */ +#define KINETIS_AXBS_MGPCR7_OFFSET 0x0f00 /* Master General Purpose Control Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_AXBS_PRS(n) (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS_OFFSET(n)) +#define KINETIS_AXBS_CRS(n) (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS_OFFSET(n)) +#define KINETIS_AXBS_PRS0 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS0_OFFSET) +#define KINETIS_AXBS_CRS0 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS0_OFFSET) +#define KINETIS_AXBS_PRS1 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS1_OFFSET) +#define KINETIS_AXBS_CRS1 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS1_OFFSET) +#define KINETIS_AXBS_PRS2 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS2_OFFSET) +#define KINETIS_AXBS_CRS2 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS2_OFFSET) +#define KINETIS_AXBS_PRS3 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS3_OFFSET) +#define KINETIS_AXBS_CRS3 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS3_OFFSET) +#define KINETIS_AXBS_PRS4 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS4_OFFSET) +#define KINETIS_AXBS_CRS4 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS4_OFFSET) +#define KINETIS_AXBS_PRS5 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS5_OFFSET) +#define KINETIS_AXBS_CRS5 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS5_OFFSET) +#define KINETIS_AXBS_PRS6 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS6_OFFSET) +#define KINETIS_AXBS_CRS6 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS6_OFFSET) +#define KINETIS_AXBS_PRS7 (KINETIS_XBAR_BASE+KINETIS_AXBS_PRS7_OFFSET) +#define KINETIS_AXBS_CRS7 (KINETIS_XBAR_BASE+KINETIS_AXBS_CRS7_OFFSET) + +#define KINETIS_AXBS_MGPCR(n) (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR_OFFSET(n)) +#define KINETIS_AXBS_MGPCR0 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR0_OFFSET) +#define KINETIS_AXBS_MGPCR1 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR1_OFFSET) +#define KINETIS_AXBS_MGPCR2 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR2_OFFSET) +#define KINETIS_AXBS_MGPCR3 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR3_OFFSET) +#define KINETIS_AXBS_MGPCR4 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR4_OFFSET) +#define KINETIS_AXBS_MGPCR5 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR5_OFFSET) +#define KINETIS_AXBS_MGPCR6 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR6_OFFSET) +#define KINETIS_AXBS_MGPCR7 (KINETIS_XBAR_BASE+KINETIS_AXBS_MGPCR7_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Priority Registers Slave */ + +#define AXBS_PRS_M0_SHIFT (0) /* Bits 0-2: Master 0 priority */ +#define AXBS_PRS_M0_MASK (7 << AXBS_PRS_M0_SHIFT) +# define AXBS_PRS_M0_PRI1 (0 << AXBS_PRS_M0_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M0_PRI2 (1 << AXBS_PRS_M0_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M0_PRI3 (2 << AXBS_PRS_M0_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M0_PRI4 (3 << AXBS_PRS_M0_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M0_PRI5 (4 << AXBS_PRS_M0_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M0_PRI6 (5 << AXBS_PRS_M0_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M0_PRI7 (6 << AXBS_PRS_M0_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M0_PRI8 (7 << AXBS_PRS_M0_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 3: Reserved */ +#define AXBS_PRS_M1_SHIFT (4) /* Bits 4-6: Master 1 priority */ +#define AXBS_PRS_M1_MASK (7 << AXBS_PRS_M1_SHIFT) +# define AXBS_PRS_M1_PRI1 (0 << AXBS_PRS_M1_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M1_PRI2 (1 << AXBS_PRS_M1_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M1_PRI3 (2 << AXBS_PRS_M1_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M1_PRI4 (3 << AXBS_PRS_M1_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M1_PRI5 (4 << AXBS_PRS_M1_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M1_PRI6 (5 << AXBS_PRS_M1_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M1_PRI7 (6 << AXBS_PRS_M1_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M1_PRI8 (7 << AXBS_PRS_M1_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 7: Reserved */ +#define AXBS_PRS_M2_SHIFT (8) /* Bits 8-10: Master 2 priority */ +#define AXBS_PRS_M2_MASK (7 << AXBS_PRS_M2_SHIFT) +# define AXBS_PRS_M2_PRI1 (0 << AXBS_PRS_M2_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M2_PRI2 (1 << AXBS_PRS_M2_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M2_PRI3 (2 << AXBS_PRS_M2_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M2_PRI4 (3 << AXBS_PRS_M2_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M2_PRI5 (4 << AXBS_PRS_M2_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M2_PRI6 (5 << AXBS_PRS_M2_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M2_PRI7 (6 << AXBS_PRS_M2_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M2_PRI8 (7 << AXBS_PRS_M2_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 11: Reserved */ +#define AXBS_PRS_M3_SHIFT (12) /* Bits 12-14: Master 3 priority */ +#define AXBS_PRS_M3_MASK (7 << AXBS_PRS_M3_SHIFT) +# define AXBS_PRS_M3_PRI1 (0 << AXBS_PRS_M3_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M3_PRI2 (1 << AXBS_PRS_M3_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M3_PRI3 (2 << AXBS_PRS_M3_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M3_PRI4 (3 << AXBS_PRS_M3_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M3_PRI5 (4 << AXBS_PRS_M3_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M3_PRI6 (5 << AXBS_PRS_M3_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M3_PRI7 (6 << AXBS_PRS_M3_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M3_PRI8 (7 << AXBS_PRS_M3_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 15: Reserved */ +#define AXBS_PRS_M4_SHIFT (16) /* Bits 16-18: Master 4 priority */ +#define AXBS_PRS_M4_MASK (7 << AXBS_PRS_M4_SHIFT) +# define AXBS_PRS_M4_PRI1 (0 << AXBS_PRS_M4_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M4_PRI2 (1 << AXBS_PRS_M4_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M4_PRI3 (2 << AXBS_PRS_M4_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M4_PRI4 (3 << AXBS_PRS_M4_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M4_PRI5 (4 << AXBS_PRS_M4_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M4_PRI6 (5 << AXBS_PRS_M4_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M4_PRI7 (6 << AXBS_PRS_M4_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M4_PRI8 (7 << AXBS_PRS_M4_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 19: Reserved */ +#define AXBS_PRS_M5_SHIFT (20) /* Bits 20-22: Master 5 priority */ +#define AXBS_PRS_M5_MASK (7 << AXBS_PRS_M5_SHIFT) +# define AXBS_PRS_M5_PRI1 (0 << AXBS_PRS_M5_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M5_PRI2 (1 << AXBS_PRS_M5_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M5_PRI3 (2 << AXBS_PRS_M5_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M5_PRI4 (3 << AXBS_PRS_M5_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M5_PRI5 (4 << AXBS_PRS_M5_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M5_PRI6 (5 << AXBS_PRS_M5_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M5_PRI7 (6 << AXBS_PRS_M5_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M5_PRI8 (7 << AXBS_PRS_M5_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 23: Reserved */ +#define AXBS_PRS_M6_SHIFT (24) /* Bits 24-26: Master 6 priority */ +#define AXBS_PRS_M6_MASK (7 << AXBS_PRS_M6_SHIFT) +# define AXBS_PRS_M6_PRI1 (0 << AXBS_PRS_M6_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M6_PRI2 (1 << AXBS_PRS_M6_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M6_PRI3 (2 << AXBS_PRS_M6_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M6_PRI4 (3 << AXBS_PRS_M6_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M6_PRI5 (4 << AXBS_PRS_M6_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M6_PRI6 (5 << AXBS_PRS_M6_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M6_PRI7 (6 << AXBS_PRS_M6_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M6_PRI8 (7 << AXBS_PRS_M6_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 27: Reserved */ +#define AXBS_PRS_M7_SHIFT (28) /* Bits 28-30: Master 7 priority */ +#define AXBS_PRS_M7_MASK (7 << AXBS_PRS_M7_SHIFT) +# define AXBS_PRS_M7_PRI1 (0 << AXBS_PRS_M7_SHIFT) /* Master has pri 1 (highest) access to slave port */ +# define AXBS_PRS_M7_PRI2 (1 << AXBS_PRS_M7_SHIFT) /* Master has pri 2 access to slave port */ +# define AXBS_PRS_M7_PRI3 (2 << AXBS_PRS_M7_SHIFT) /* Master has pri 3 access to slave port */ +# define AXBS_PRS_M7_PRI4 (3 << AXBS_PRS_M7_SHIFT) /* Master has pri 4 access to slave port */ +# define AXBS_PRS_M7_PRI5 (4 << AXBS_PRS_M7_SHIFT) /* Master has pri 5 access to slave port */ +# define AXBS_PRS_M7_PRI6 (5 << AXBS_PRS_M7_SHIFT) /* Master has pri 6 access to slave port */ +# define AXBS_PRS_M7_PRI7 (6 << AXBS_PRS_M7_SHIFT) /* Master has pri 7 access to slave port */ +# define AXBS_PRS_M7_PRI8 (7 << AXBS_PRS_M7_SHIFT) /* Master has pri 8 (lowest) access to slave port */ + /* Bit 31: Reserved */ +/* Control Register */ + +#define AXBS_CRS_PARK_SHIFT (0) /* Bits 0-2: Park */ +#define AXBS_CRS_PARK_MASK (7 << AXBS_CRS_PARK_SHIFT) +# define AXBS_CRS_PARK_M0 (0 << AXBS_CRS_PARK_SHIFT) /* Park on master port M0 */ +# define AXBS_CRS_PARK_M1 (1 << AXBS_CRS_PARK_SHIFT) /* Park on master port M1 */ +# define AXBS_CRS_PARK_M2 (2 << AXBS_CRS_PARK_SHIFT) /* Park on master port M2 */ +# define AXBS_CRS_PARK_M3 (3 << AXBS_CRS_PARK_SHIFT) /* Park on master port M3 */ +# define AXBS_CRS_PARK_M4 (4 << AXBS_CRS_PARK_SHIFT) /* Park on master port M4 */ +# define AXBS_CRS_PARK_M5 (5 << AXBS_CRS_PARK_SHIFT) /* Park on master port M5 */ +#define AXBS_CRS_PCTL_SHIFT (4) /* Bits 4-5: Parking control */ +#define AXBS_CRS_PCTL_MASK (2 << AXBS_CRS_PCTL_SHIFT) +# define AXBS_CRS_PCTL_PARK (0 << AXBS_CRS_PCTL_SHIFT) /* Defined by the PARK bit field */ +# define AXBS_CRS_PCTL_LAST (1 << AXBS_CRS_PCTL_SHIFT) /* Last master in control of slave port */ +# define AXBS_CRS_PCTL_NOT (2 << AXBS_CRS_PCTL_SHIFT) /* Not parked on a master */ +#define AXBS_CRS_ARB_SHIFT (8) /* Bits 8-9: Arbitration mode */ +#define AXBS_CRS_ARB_MASK (3 << AXBS_CRS_ARB_SHIFT) +# define AXBS_CRS_ARB_FIXED (0 << AXBS_CRS_ARB_SHIFT) /* Fixed priority */ +# define AXBS_CRS_ARB_MASK (1 << AXBS_CRS_ARB_SHIFT) /* Round-robin (rotating) priority */ + /* Bits 10-29: Reserved */ +#define AXBS_CRS_HLP (1 < 30) /* Bit 30: Halt low priority */ +#define AXBS_CRS_RO (1 < 31) /* Bit 31: Read only */ + +/* Master General Purpose Control Register */ + +#define AXBS_MGPCR_AULB_SHIFT (0) /* Bits 0-2: Arbitrate on undefined length bursts */ +#define AXBS_MGPCR_AULB_MASK (7 << AXBS_MGPCR_AULB_SHIFT) +# define AXBS_MGPCR_AULB_NONE (0 << AXBS_MGPCR_AULB_SHIFT) /* No arbitration allowed */ +# define AXBS_MGPCR_AULB_ANY (1 << AXBS_MGPCR_AULB_SHIFT) /* Arbitration allowed at any time */ +# define AXBS_MGPCR_AULB_4BEATS (2 << AXBS_MGPCR_AULB_SHIFT) /* Arbitration allowed after four beats */ +# define AXBS_MGPCR_AULB_8BEATS (3 << AXBS_MGPCR_AULB_SHIFT) /* Arbitration allowed after eight beats */ +# define AXBS_MGPCR_AULB_16BEATS (4 << AXBS_MGPCR_AULB_SHIFT) /* Arbitration allowed after 16 beats */ + /* Bits 3-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H */ diff --git a/arch/arm/src/kinetis/kinetis_cfmconfig.c b/arch/arm/src/kinetis/kinetis_cfmconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..5742f05b594661931dd46423c0928a7dea31c620 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_cfmconfig.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * Taken from: + * + * https://github.com/jodersky/nuttx/tree/teensy31-7.6 + * + * Barely based on "bare metal" sample from Freedom board: + * Copyright (c) 2012-2013 Andrew Payne + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +__attribute__ ((section(".cfmconfig"))) +const uint8_t __flashconfigbytes[16] = +{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff +}; diff --git a/arch/arm/src/kinetis/kinetis_clockconfig.c b/arch/arm/src/kinetis/kinetis_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..dc2fe0482bf893b6fda5a199785dfbb3ae184c41 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_clockconfig.c @@ -0,0 +1,379 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_clockconfig.c + * arch/arm/src/chip/kinetis_clockconfig.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" + +#include "kinetis.h" +#include "kinetis_mcg.h" +#include "kinetis_sim.h" +#include "kinetis_fmc.h" +#include "kinetis_llwu.h" +#include "kinetis_pinmux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ARCH_RAMFUNCS +# error "CONFIG_ARCH_RAMFUNCS must be defined for this logic" +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +void __ramfunc__ +kinesis_setdividers(uint32_t div1, uint32_t div2, uint32_t div3, uint32_t div4); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinesis_portclocks + * + * Description: + * Enable all of the port clocks + * + ****************************************************************************/ + +static inline void kinesis_portclocks(void) +{ + uint32_t regval; + + /* Enable all of the port clocks */ + + regval = getreg32(KINETIS_SIM_SCGC5); + regval |= (SIM_SCGC5_PORTA | SIM_SCGC5_PORTB | SIM_SCGC5_PORTC | + SIM_SCGC5_PORTD | SIM_SCGC5_PORTE); + putreg32(regval, KINETIS_SIM_SCGC5); +} + +/**************************************************************************** + * Name: kinetis_pllconfig + * + * Description: + * Initialize the PLL using the settings in board.h. This assumes that + * the MCG is in default FLL Engaged Internal (FEI mode) out of reset. + * + ****************************************************************************/ + +void kinetis_pllconfig(void) +{ + uint32_t regval32; + uint8_t regval8; + + /* Transition to FLL Bypassed External (FBE) mode */ + +#ifdef BOARD_EXTCLOCK + /* IRCS = 0 (Internal Reference Clock Select) + * LP = 0 (Low Power Select) + * EREFS = 0 (External Reference Select) + * HGO = 0 (High Gain Oscillator Select) + * RANGE = 0 (Oscillator of 32 kHz to 40 kHz) + */ + + putreg8(0, KINETIS_MCG_C2); +#else + /* Enable external oscillator: + * + * IRCS = 0 (Internal Reference Clock Select) + * LP = 0 (Low Power Select) + * EREFS = 1 (External Reference Select) + * HGO = 1 (High Gain Oscillator Select) + * RANGE = 2 (Oscillator of 8 MHz to 32 MHz) + */ + + putreg8(MCG_C2_EREFS | MCG_C2_HGO | MCG_C2_RANGE_VHIGH, KINETIS_MCG_C2); +#endif + + /* Released latched state of oscillator and GPIO */ + + regval32 = getreg32(KINETIS_SIM_SCGC4); + regval32 |= SIM_SCGC4_LLWU; + putreg32(regval32, KINETIS_SIM_SCGC4); + + regval8 = getreg8(KINETIS_LLWU_CS); + regval8 |= LLWU_CS_ACKISO; + putreg8(regval8, KINETIS_LLWU_CS); + + /* Select external oscillator and Reference Divider and clear IREFS to + * start the external oscillator. + * + * IREFSTEN = 0 (Internal Reference Stop Enable) + * IRCLKEN = 0 (Internal Reference Clock Enable) + * IREFS = 0 (Internal Reference Select) + * FRDIV = 3 (FLL External Reference Divider, RANGE!=0 divider=256) + * CLKS = 2 (Clock Source Select, External reference clock) + */ + + putreg8(MCG_C1_FRDIV_DIV256 | MCG_C1_CLKS_EXTREF, KINETIS_MCG_C1); + + /* If we aren't using an oscillator input we don't need to wait for the + * oscillator to initialize + */ + +#ifndef BOARD_EXTCLOCK + while ((getreg8(KINETIS_MCG_S) & MCG_S_OSCINIT) == 0); +#endif + + /* Wait for Reference clock Status bit to clear */ + + while ((getreg8(KINETIS_MCG_S) & MCG_S_IREFST) != 0); + + /* Wait for clock status bits to show that the clock source is the + * external reference clock. + */ + + while ((getreg8(KINETIS_MCG_S) & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTREF); + + /* We are now in FLL Bypassed External (FBE) mode. Configure PLL + * reference clock divider: + * + * PLLCLKEN = 0 + * PLLSTEN = 0 + * PRDIV = Determined by PLL reference clock frequency + * + * Either the external clock or crystal frequency is used to select the + * PRDIV value. Only reference clock frequencies are supported that will + * produce a 2MHz reference clock to the PLL. + */ + + putreg8(MCG_C5_PRDIV(BOARD_PRDIV), KINETIS_MCG_C5); + + /* Ensure that MCG_C6 is at the reset default of 0: LOLIE disabled, PLL + * disabled, clk monitor disabled, PLL VCO divider cleared. + */ + + putreg8(0, KINETIS_MCG_C6); + + /* Set system options dividers based on settings from the board.h file. + * + * MCG = PLL + * Core = MCG / BOARD_OUTDIV1 + * bus = MCG / BOARD_OUTDIV2 + * FlexBus = MCG / BOARD_OUTDIV3 + * Flash clock = MCG / BOARD_OUTDIV4 + */ + + kinesis_setdividers(BOARD_OUTDIV1, BOARD_OUTDIV2, BOARD_OUTDIV3, BOARD_OUTDIV4); + + /* Set the VCO divider, VDIV, is defined in the board.h file. VDIV + * selects the amount to divide the VCO output of the PLL. The VDIV bits + * establish the multiplication factor applied to the reference clock + * frequency. Also set + * + * LOLIE = 0 (Loss of Lock Interrrupt Enable) + * PLLS = 1 (PLL Select) + * CME = 0 (Clock Monitor Enable) + */ + + putreg8(MCG_C6_PLLS | MCG_C6_VDIV(BOARD_VDIV), KINETIS_MCG_C6); + + /* Wait for the PLL status bit to set */ + + while ((getreg8(KINETIS_MCG_S) & MCG_S_PLLST) == 0); + + /* Wait for the PLL LOCK bit to set */ + + while ((getreg8(KINETIS_MCG_S) & MCG_S_LOCK) == 0); + + /* We are now running in PLL Bypassed External (PBE) mode. Transition to + * PLL Engaged External (PEE) mode by setting CLKS to 0 + */ + + regval8 = getreg8(KINETIS_MCG_C1); + regval8 &= ~MCG_C1_CLKS_MASK; + putreg8(regval8, KINETIS_MCG_C1); + + /* Wait for clock status bits to update */ + + while ((getreg8(KINETIS_MCG_S) & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL); + + /* We are now running in PLL Engaged External (PEE) mode. */ +} + +/**************************************************************************** + * Name: kinetis_traceconfig + * + * Description: + * Enable trace clocks. + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_TRACE +static inline void kinetis_traceconfig(void) +{ + uint32_t regval; + + /* Set the trace clock to the core clock frequency in the SIM SOPT2 register */ + + regval = getreg32(KINETIS_SIM_SOPT2); + regval |= SIM_SOPT2_TRACECLKSEL; + putreg32(regval, KINETIS_SIM_SOPT2); + + /* Enable the TRACE_CLKOUT pin function on the configured pin */ + + kinetis_gpioconfig(GPIO_TRACE_CLKOUT); +} +#else +# define kinetis_traceconfig() +#endif + +/**************************************************************************** + * Name: kinetis_fbconfig + * + * Description: + * Enable FlexBus clocking. + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_FLEXBUS +static inline void kinetis_fbconfig(void) +{ + uint32_t regval; + + /* Enable the clock to the FlexBus module */ + + regval = getreg32(KINETIS_SIM_SCGC7); + regval |= SIM_SCGC7_FLEXBUS; + putreg32(regval, KINETIS_SIM_SCGC7); + + /* Enable the FB_CLKOUT function on PTC3 (alt5 function) */ + + kinetis_gpioconfig(GPIO_FB_CLKOUT); +} +#else +# define kinetis_fbconfig() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_clockconfig + * + * Description: + * Called to initialize the Kinetis chip. This does whatever setup is + * needed to put the MCU in a usable state. This includes the + * initialization of clocking using the settings in board.h. + * + ****************************************************************************/ + +void kinetis_clockconfig(void) +{ + /* Enable all of the port clocks */ + + kinesis_portclocks(); + + /* Configure the PLL based on settings in the board.h file */ + + kinetis_pllconfig(); + + /* For debugging, we will normally want to enable the trace clock and/or + * the FlexBus clock. + */ + + kinetis_traceconfig(); + kinetis_fbconfig(); +} + +/**************************************************************************** + * Name: kinesis_setdividers + * + * Description: + * "This routine must be placed in RAM. It is a workaround for errata e2448. + * Flash prefetch must be disabled when the flash clock divider is changed. + * This cannot be performed while executing out of flash. There must be a + * short delay after the clock dividers are changed before prefetch can be + * re-enabled." + * + * NOTE: This must have global scope only to prevent optimization logic from + * inlining the function. + * + ****************************************************************************/ + +void __ramfunc__ +kinesis_setdividers(uint32_t div1, uint32_t div2, uint32_t div3, uint32_t div4) +{ + uint32_t regval; + int i; + + /* Save the current value of the Flash Access Protection Register */ + + regval = getreg32(KINETIS_FMC_PFAPR); + + /* Set M0PFD through M7PFD to 1 to disable prefetch */ + + putreg32(FMC_PFAPR_M7PFD | FMC_PFAPR_M6PFD | FMC_PFAPR_M5PFD | + FMC_PFAPR_M4PFD | FMC_PFAPR_M3PFD | FMC_PFAPR_M2PFD | + FMC_PFAPR_M1PFD | FMC_PFAPR_M0PFD, + KINETIS_FMC_PFAPR); + + /* Set clock dividers to desired value */ + + putreg32(SIM_CLKDIV1_OUTDIV1(div1) | SIM_CLKDIV1_OUTDIV2(div2) | + SIM_CLKDIV1_OUTDIV3(div3) | SIM_CLKDIV1_OUTDIV4(div4), + KINETIS_SIM_CLKDIV1); + + /* Wait for dividers to change */ + + for (i = 0 ; i < div4 ; i++); + + /* Re-store the saved value of FMC_PFAPR */ + + putreg32(regval, KINETIS_FMC_PFAPR); +} + + + diff --git a/arch/arm/src/kinetis/kinetis_clrpend.c b/arch/arm/src/kinetis/kinetis_clrpend.c new file mode 100644 index 0000000000000000000000000000000000000000..7f0395c4aeb2f1cbe7f9038a275b2ad40a8bbe99 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_clrpend.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_clrpend.c + * arch/arm/src/chip/kinetis_clrpend.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nvic.h" +#include "up_arch.h" +#include "kinetis.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. Don't know why... + * + * I keep it in a separate file so that it will not increase the footprint + * on Kinetis platforms that do not need this function. + * + ****************************************************************************/ + +void kinetis_clrpend(int irq) +{ + /* Check for external interrupt */ + + if (irq >= KINETIS_IRQ_EXTINT) + { + if (irq < (KINETIS_IRQ_EXTINT+32)) + { + putreg32(1 << (irq - KINETIS_IRQ_EXTINT), NVIC_IRQ0_31_CLRPEND); + } + else if (irq < (KINETIS_IRQ_EXTINT+64)) + { + putreg32(1 << (irq - KINETIS_IRQ_EXTINT - 32), NVIC_IRQ32_63_CLRPEND); + } + else if (irq < (KINETIS_IRQ_EXTINT+96)) + { + putreg32(1 << (irq - KINETIS_IRQ_EXTINT - 64), NVIC_IRQ64_95_CLRPEND); + } + else if (irq < NR_IRQS) + { + putreg32(1 << (irq - KINETIS_IRQ_EXTINT - 96), NVIC_IRQ96_127_CLRPEND); + } + } +} diff --git a/arch/arm/src/kinetis/kinetis_cmp.h b/arch/arm/src/kinetis/kinetis_cmp.h new file mode 100644 index 0000000000000000000000000000000000000000..822b7a339f5de9603af3e3236f03d1e5b47068ba --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_cmp.h @@ -0,0 +1,190 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_cmp.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINESIS_CMP_OFFSET(n) ((n) << 3) +#define KINESIS_CMP0_OFFSET 0x0000 +#define KINESIS_CMP1_OFFSET 0x0008 +#define KINESIS_CMP2_OFFSET 0x0010 + +#define KINETIS_CMP_CR0_OFFSET 0x0000 /* CMP Control Register 0 */ +#define KINETIS_CMP_CR1_OFFSET 0x0001 /* CMP Control Register 1 */ +#define KINETIS_CMP_FPR_OFFSET 0x0002 /* CMP Filter Period Register */ +#define KINETIS_CMP_SCR_OFFSET 0x0003 /* CMP Status and Control Register */ +#define KINETIS_CMP_DACCR_OFFSET 0x0004 /* DAC Control Register */ +#define KINETIS_CMP_MUXCR_OFFSET 0x0005 /* MUX Control Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINESIS_CMP_BASE(n) (KINETIS_CMP_BASE+KINESIS_CMP_OFFSET(n)) +#define KINESIS_CMP0_BASE (KINETIS_CMP_BASE+KINESIS_CMP0_OFFSET) +#define KINESIS_CMP1_BASE (KINETIS_CMP_BASE+KINESIS_CMP1_OFFSET) +#define KINESIS_CMP2_BASE (KINETIS_CMP_BASE+KINESIS_CMP2_OFFSET) + +#define KINETIS_CMP_CR0(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_CR0_OFFSET) +#define KINETIS_CMP_CR1(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_CR1_OFFSET) +#define KINETIS_CMP_FPR(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_FPR_OFFSET) +#define KINETIS_CMP_SCR(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_SCR_OFFSET) +#define KINETIS_CMP_DACCR(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_DACCR_OFFSET) +#define KINETIS_CMP_MUXCR(n) (KINESIS_CMP_BASE(n)+KINETIS_CMP_MUXCR_OFFSET) + +#define KINETIS_CMP0_CR0 (KINETIS_CMP0_BASE+KINETIS_CMP_CR0_OFFSET) +#define KINETIS_CMP0_CR1 (KINETIS_CMP0_BASE+KINETIS_CMP_CR1_OFFSET) +#define KINETIS_CMP0_FPR (KINETIS_CMP0_BASE+KINETIS_CMP_FPR_OFFSET) +#define KINETIS_CMP0_SCR (KINETIS_CMP0_BASE+KINETIS_CMP_SCR_OFFSET) +#define KINETIS_CMP0_DACCR (KINETIS_CMP0_BASE+KINETIS_CMP_DACCR_OFFSET) +#define KINETIS_CMP0_MUXCR (KINETIS_CMP0_BASE+KINETIS_CMP_MUXCR_OFFSET) + +#define KINETIS_CMP1_CR0 (KINETIS_CMP1_BASE+KINETIS_CMP_CR0_OFFSET) +#define KINETIS_CMP1_CR1 (KINETIS_CMP1_BASE+KINETIS_CMP_CR1_OFFSET) +#define KINETIS_CMP1_FPR (KINETIS_CMP1_BASE+KINETIS_CMP_FPR_OFFSET) +#define KINETIS_CMP1_SCR (KINETIS_CMP1_BASE+KINETIS_CMP_SCR_OFFSET) +#define KINETIS_CMP1_DACCR (KINETIS_CMP1_BASE+KINETIS_CMP_DACCR_OFFSET) +#define KINETIS_CMP1_MUXCR (KINETIS_CMP1_BASE+KINETIS_CMP_MUXCR_OFFSET) + +#define KINETIS_CMP2_CR0 (KINETIS_CMP2_BASE+KINETIS_CMP_CR0_OFFSET) +#define KINETIS_CMP2_CR1 (KINETIS_CMP2_BASE+KINETIS_CMP_CR1_OFFSET) +#define KINETIS_CMP2_FPR (KINETIS_CMP2_BASE+KINETIS_CMP_FPR_OFFSET) +#define KINETIS_CMP2_SCR (KINETIS_CMP2_BASE+KINETIS_CMP_SCR_OFFSET) +#define KINETIS_CMP2_DACCR (KINETIS_CMP2_BASE+KINETIS_CMP_DACCR_OFFSET) +#define KINETIS_CMP2_MUXCR (KINETIS_CMP2_BASE+KINETIS_CMP_MUXCR_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* CMP Control Register 0 (8-bit) */ + +#define CMP_CR0_HYSTCTR_SHIFT (0) /* Bits 0-1: Comparator hard block hysteresis control */ +#define CMP_CR0_HYSTCTR_MASK (3 << CMP_CR0_HYSTCTR_SHIFT) +# define CMP_CR0_HYSTCTR_LVL0 (0 << CMP_CR0_HYSTCTR_SHIFT) +# define CMP_CR0_HYSTCTR_LVL1 (1 << CMP_CR0_HYSTCTR_SHIFT) +# define CMP_CR0_HYSTCTR_LVL2 (2 << CMP_CR0_HYSTCTR_SHIFT) +# define CMP_CR0_HYSTCTR_LVL3 (3 << CMP_CR0_HYSTCTR_SHIFT) + /* Bits 2-3: Reserved */ +#define CMP_CR0_FILTER_CNT_SHIFT (4) /* Bits 4-6: Filter Sample Count */ +#define CMP_CR0_FILTER_CNT_MASK (7 << CMP_CR0_FILTER_CNT_SHIFT) +# define CMP_CR0_FILTER_DISABLED (0 << CMP_CR0_FILTER_CNT_SHIFT) /* Filter is disabled */ +# define CMP_CR0_FILTER_CNT1 (1 << CMP_CR0_FILTER_CNT_SHIFT) /* 1 consecutive sample must agree */ +# define CMP_CR0_FILTER_CNT2 (2 << CMP_CR0_FILTER_CNT_SHIFT) /* 2 consecutive samples must agree */ +# define CMP_CR0_FILTER_CNT3 (3 << CMP_CR0_FILTER_CNT_SHIFT) /* 3 consecutive samples must agree */ +# define CMP_CR0_FILTER_CNT4 (4 << CMP_CR0_FILTER_CNT_SHIFT) /* 4 consecutive samples must agree */ +# define CMP_CR0_FILTER_CNT5 (5 << CMP_CR0_FILTER_CNT_SHIFT) /* 5 consecutive samples must agree */ +# define CMP_CR0_FILTER_CNT6 (6 << CMP_CR0_FILTER_CNT_SHIFT) /* 6 consecutive samples must agree */ +# define CMP_CR0_FILTER_CNT7 (7 << CMP_CR0_FILTER_CNT_SHIFT) /* 7 consecutive samples must agree */ + /* Bit 7: Reserved */ +/* CMP Control Register 1 (8-bit) */ + +#define CMP_CR1_EN (1 << 0) /* Bit 0: Comparator Module Enable */ +#define CMP_CR1_OPE (1 << 1) /* Bit 1: Comparator Output Pin Enable */ +#define CMP_CR1_COS (1 << 2) /* Bit 2: Comparator Output Select */ +#define CMP_CR1_INV (1 << 3) /* Bit 3: Comparator INVERT */ +#define CMP_CR1_PMODE (1 << 4) /* Bit 4: Power Mode Select */ + /* Bit 5: Reserved */ +#define CMP_CR1_WE (1 << 6) /* Bit 6: Windowing Enable */ +#define CMP_CR1_SE (1 << 7) /* Bit 7: Sample Enable */ + +/* CMP Filter Period Register (8-bit Filter Sample Period) */ + + +/* CMP Status and Control Register (8-bit) */ + +#define CMP_SCR_COUT (1 << 0) /* Bit 0: Analog Comparator Output */ +#define CMP_SCR_CFF (1 << 1) /* Bit 1: Analog Comparator Flag Falling */ +#define CMP_SCR_CFR (1 << 2) /* Bit 2: Analog Comparator Flag Rising */ +#define CMP_SCR_IEF (1 << 3) /* Bit 3: Comparator Interrupt Enable Falling */ +#define CMP_SCR_IER (1 << 4) /* Bit 4: Comparator Interrupt Enable Rising */ +#define CMP_SCR_SMELB (1 << 5) /* Bit 5: Stop Mode Edge/Level Interrupt Control */ +#define CMP_SCR_DMAEN (1 << 6) /* Bit 6: DMA Enable Control */ + /* Bit 7: Reserved */ +/* DAC Control Register (8-bit) */ + +#define CMP_DACCR_VOSEL_SHIFT (0) /* Bits 0-5: DAC Output Voltage Select */ +#define CMP_DACCR_VOSEL_MASK (0x3f << CMP_DACCR_VOSEL_SHIFT) +#define CMP_DACCR_VRSEL (1 << 6) /* Bit 6: Supply Voltage Reference Source Select */ +#define CMP_DACCR_DACEN (1 << 7) /* Bit 7: DAC Enable */ + +/* MUX Control Register (8-bit) */ + +#define CMP_MUXCR_MSEL_SHIFT (0) /* Bits 0-2: Minus Input MUX Control */ +#define CMP_MUXCR_MSEL_MASK (7 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN0 (0 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN1 (1 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN2 (2 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN3 (3 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN4 (4 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN5 (5 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN6 (6 << CMP_MUXCR_MSEL_SHIFT) +# define CMP_MUXCR_MSEL_IN7 (7 << CMP_MUXCR_MSEL_SHIFT) +#define CMP_MUXCR_PSEL_SHIFT (3) /* Bits 3-5: Plus Input MUX Control */ +#define CMP_MUXCR_PSEL_MASK (7 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN0 (0 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN1 (1 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN2 (2 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN3 (3 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN4 (4 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN5 (5 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN6 (6 << CMP_MUXCR_PSEL_SHIFT) +# define CMP_MUXCR_PSEL_IN7 (7 << CMP_MUXCR_PSEL_SHIFT) +#define CMP_MUXCR_MEN (1 << 6) /* Bit 6: MMUX Enable */ +#define CMP_MUXCR_PEN (1 << 7) /* Bit 7: PMUX Enable */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H */ diff --git a/arch/arm/src/kinetis/kinetis_cmt.h b/arch/arm/src/kinetis/kinetis_cmt.h new file mode 100644 index 0000000000000000000000000000000000000000..c3c47bb6761254a0ce4c86484a43e41809433cdf --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_cmt.h @@ -0,0 +1,138 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_cmt.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_CMT_CGH1_OFFSET 0x0000 /* CMT Carrier Generator High Data Register 1 */ +#define KINETIS_CMT_CGL1_OFFSET 0x0001 /* CMT Carrier Generator Low Data Register 1 */ +#define KINETIS_CMT_CGH2_OFFSET 0x0002 /* CMT Carrier Generator High Data Register 2 */ +#define KINETIS_CMT_CGL2_OFFSET 0x0003 /* CMT Carrier Generator Low Data Register 2 */ +#define KINETIS_CMT_OC_OFFSET 0x0004 /* CMT Output Control Register */ +#define KINETIS_CMT_MSC_OFFSET 0x0005 /* CMT Modulator Status and Control Register */ +#define KINETIS_CMT_CMD1_OFFSET 0x0006 /* CMT Modulator Data Register Mark High */ +#define KINETIS_CMT_CMD2_OFFSET 0x0007 /* CMT Modulator Data Register Mark Low */ +#define KINETIS_CMT_CMD3_OFFSET 0x0008 /* CMT Modulator Data Register Space High */ +#define KINETIS_CMT_CMD4_OFFSET 0x0009 /* CMT Modulator Data Register Space Low */ +#define KINETIS_CMT_PPS_OFFSET 0x000a /* CMT Primary Prescaler Register */ +#define KINETIS_CMT_DMA_OFFSET 0x000b /* CMT Direct Memory Access */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_CMT_CGH1 (KINETIS_CMT_BASE+KINETIS_CMT_CGH1_OFFSET) +#define KINETIS_CMT_CGL1 (KINETIS_CMT_BASE+KINETIS_CMT_CGL1_OFFSET) +#define KINETIS_CMT_CGH2 (KINETIS_CMT_BASE+KINETIS_CMT_CGH2_OFFSET) +#define KINETIS_CMT_CGL2 (KINETIS_CMT_BASE+KINETIS_CMT_CGL2_OFFSET) +#define KINETIS_CMT_OC (KINETIS_CMT_BASE+KINETIS_CMT_OC_OFFSET) +#define KINETIS_CMT_MSC (KINETIS_CMT_BASE+KINETIS_CMT_MSC_OFFSET) +#define KINETIS_CMT_CMD1 (KINETIS_CMT_BASE+KINETIS_CMT_CMD1_OFFSET) +#define KINETIS_CMT_CMD2 (KINETIS_CMT_BASE+KINETIS_CMT_CMD2_OFFSET) +#define KINETIS_CMT_CMD3 (KINETIS_CMT_BASE+KINETIS_CMT_CMD3_OFFSET) +#define KINETIS_CMT_CMD4 (KINETIS_CMT_BASE+KINETIS_CMT_CMD4_OFFSET) +#define KINETIS_CMT_PPS (KINETIS_CMT_BASE+KINETIS_CMT_PPS_OFFSET) +#define KINETIS_CMT_DMA (KINETIS_CMT_BASE+KINETIS_CMT_DMA_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* CMT Carrier Generator High/Low Data Register 1 (8-bit Primary Carrier High Time + * Data Value) + */ + +/* CMT Carrier Generator High/Low Data Register 2 (8-bit Secondary Carrier High Time + * Data Value) + */ + +/* CMT Output Control Register (8-bit) */ + /* Bits 0-4: Reserved */ +#define CMT_OC_IROPEN (1 << 5) /* Bit 5: IRO Pin Enable */ +#define CMT_OC_CMTPOL (1 << 6) /* Bit 6: CMT Output Polarity */ +#define CMT_OC_IROL (1 << 7) /* Bit 7: IRO Latch Control */ + +/* CMT Modulator Status and Control Register (8-bit) */ + +#define CMT_MSC_MCGEN (1 << 0) /* Bit 0: Modulator and Carrier Generator Enable */ +#define CMT_MSC_EOCIE (1 << 1) /* Bit 1: End of Cycle Interrupt Enable */ +#define CMT_MSC_FSK (1 << 2) /* Bit 2: FSK Mode Select */ +#define CMT_MSC_BASE (1 << 3) /* Bit 3: Baseband Enable */ +#define CMT_MSC_EXSPC (1 << 4) /* Bit 4: Extended Space Enable */ +#define CMT_MSC_CMTDIV_SHIFT (5) /* Bits 5-6: CMT Clock Divide Prescaler */ +#define CMT_MSC_CMTDIV_MASK (3 << CMT_MSC_CMTDIV_SHIFT) +# define CMT_MSC_CMTDIV_DIV1 (0 << CMT_MSC_CMTDIV_SHIFT) /* IF / 1 */ +# define CMT_MSC_CMTDIV_DIV2 (1 << CMT_MSC_CMTDIV_SHIFT) /* IF / 2 */ +# define CMT_MSC_CMTDIV_DIV4 (2 << CMT_MSC_CMTDIV_SHIFT) /* IF / 4 */ +# define CMT_MSC_CMTDIV_DIV8 (3 << CMT_MSC_CMTDIV_SHIFT) /* IF / 8 */ +#define CMT_MSC_EOCF (1 << 7) /* Bit 7: End Of Cycle Status Flag */ + +/* CMT Modulator Data Register Mark High/Low (8-bit command data) */ +/* CMT Modulator Data Register Space High/Low (8-bit command data)*/ + +/* CMT Primary Prescaler Register (8-bit) */ + +#define CMT_PPS_SHIFT (0) /* Bits 0-3: Primary Prescaler Divider */ +#define CMT_PPS_MASK (15 << CMT_PPS_SHIFT) +# define CMT_PPS_DIV(n) (((n)-1) << CMT_PPS_SHIFT) /* Bus clock / n, n=1..16 */ + /* Bits 4-7: Reserved */ +/* CMT Direct Memory Access (8-bit) */ + +#define CMT_DMA_ENABLE (1 << 0) /* Bit 0: DMA Enable + /* Bits 1-7: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H */ diff --git a/arch/arm/src/kinetis/kinetis_config.h b/arch/arm/src/kinetis/kinetis_config.h new file mode 100644 index 0000000000000000000000000000000000000000..ce1c6efedf79b6d7348ef4a04fb77b12d3cc1d15 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_config.h @@ -0,0 +1,235 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_config.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H +#define __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ +/* Make that no unsupported UARTs are enabled */ + +#ifndef KINETIS_NISO7816 +# define KINETIS_NISO7816 0 +#endif + +#if (KINETIS_NISO7816 + KINETIS_NUART) < 6 +# undef CONFIG_KINETIS_UART5 +# if (KINETIS_NISO7816 + KINETIS_NUART) < 5 +# undef CONFIG_KINETIS_UART4 +# if (KINETIS_NISO7816 + KINETIS_NUART) < 4 +# undef CONFIG_KINETIS_UART3 +# if (KINETIS_NISO7816 + KINETIS_NUART) < 3 +# undef CONFIG_KINETIS_UART2 +# if (KINETIS_NISO7816 + KINETIS_NUART) < 2 +# undef CONFIG_KINETIS_UART1 +# if (KINETIS_NISO7816 + KINETIS_NUART) < 1 +# undef CONFIG_KINETIS_UART0 +# endif +# endif +# endif +# endif +# endif +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_KINETIS_UART0) || defined(CONFIG_KINETIS_UART1) || \ + defined(CONFIG_KINETIS_UART2) || defined(CONFIG_KINETIS_UART3) || \ + defined(CONFIG_KINETIS_UART5) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3,4,5 + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART4) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART5) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Check UART flow control (Not yet supported) */ + +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART2_FLOWCONTROL +# undef CONFIG_UART3_FLOWCONTROL +# undef CONFIG_UART4_FLOWCONTROL +# undef CONFIG_UART5_FLOWCONTROL + +/* UART FIFO support is not fully implemented. + * + * NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs + * (1-deep). There appears to be no way to know when the FIFO is not + * full (other than reading the FIFO length and comparing the FIFO count). + * Hence, the FIFOs are not used in this implementation and, as a result + * TDRE indeed mean that the single output buffer is available. + * + * Performance on UART0 could be improved by enabling the FIFO and by + * redesigning all of the FIFO status logic. + */ + +#undef CONFIG_KINETIS_UARTFIFOS + +/* UART Default Interrupt Priorities */ + +#ifndef CONFIG_KINETIS_UART0PRIO +# define CONFIG_KINETIS_UART0PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_UART1PRIO +# define CONFIG_KINETIS_UART1PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_UART2PRIO +# define CONFIG_KINETIS_UART2PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_UART3PRIO +# define CONFIG_KINETIS_UART3PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_UART4PRIO +# define CONFIG_KINETIS_UART4PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_UART5PRIO +# define CONFIG_KINETIS_UART5PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Ethernet controller configuration */ + +#ifndef CONFIG_ENET_NRXBUFFERS +# define CONFIG_ENET_NRXBUFFERS 6 +#endif +#ifndef CONFIG_ENET_NTXBUFFERS +# define CONFIG_ENET_NTXBUFFERS 2 +#endif + +#ifndef CONFIG_ENET_PHYADDR +# define CONFIG_ENET_PHYADDR 1 +#endif + +#ifndef CONFIG_ENET_NETHIFS +# define CONFIG_ENET_NETHIFS 1 +#endif + +/* EMAC Default Interrupt Priorities */ + +#ifndef CONFIG_KINETIS_EMACTMR_PRIO +# define CONFIG_KINETIS_EMACTMR_PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_EMACTX_PRIO +# define CONFIG_KINETIS_EMACTX_PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_EMACRX_PRIO +# define CONFIG_KINETIS_EMACRX_PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_KINETIS_EMACMISC_PRIO +# define CONFIG_KINETIS_EMACMISC_PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H */ diff --git a/arch/arm/src/kinetis/kinetis_crc.h b/arch/arm/src/kinetis/kinetis_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..7b590cf3a9a0c39374982f0c8b747da54bb71ccf --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_crc.h @@ -0,0 +1,117 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_crc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(KINETIS_NCRC) && KINETIS_NCRC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_CRC_CRC_OFFSET 0x0000 /* CRC Data Register */ +#define KINETIS_CRC_GPOLY_OFFSET 0x0004 /* CRC Polynomial Register */ +#define KINETIS_CRC_CTRL_OFFSET 0x0008 /* CRC Control Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_CRC_CRC (KINETIS_CRC_BASE+KINETIS_CRC_CRC_OFFSET) +#define KINETIS_CRC_GPOLY (KINETIS_CRC_BASE+KINETIS_CRC_GPOLY_OFFSET) +#define KINETIS_CRC_CTRL (KINETIS_CRC_BASE+KINETIS_CRC_CTRL_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* CRC Data Register (32-bit) */ + +#define CRC_CRC_LL_SHIFT (0) /* Bits 0-7: CRC Low Lower Byte */ +#define CRC_CRC_LL_MASK (0xff << CRC_CRC_LL_SHIFT) +#define CRC_CRC_LU_SHIFT (8) /* Bits 8-15: CRC Low Upper Byte */ +#define CRC_CRC_LU_MASK (0xff << CRC_CRC_LU_SHIFT) +#define CRC_CRC_HL_SHIFT (16) /* Bits 16-23: CRC High Lower Byte */ +#define CRC_CRC_HL_MASK (0xff << CRC_CRC_HL_SHIFT) +#define CRC_CRC_HU_SHIFT (24) /* Bits 24-31: CRC High Upper Byte */ +#define CRC_CRC_HU_MASK (0xff << CRC_CRC_HU_SHIFT) + +/* CRC Polynomial Register */ + +#define CRC_GPOLY_LOW_SHIFT (0) /* Bits 0-15: Low polynominal half-word */ +#define CRC_GPOLY_LOW_MASK (0xffff << CRC_GPOLY_LOW_SHIFT) +#define CRC_GPOLY_HIGH_SHIFT (16) /* Bits 16-31: High polynominal half-word */ +#define CRC_GPOLY_HIGH_MASK (0xffff << CRC_GPOLY_HIGH_SHIFT) + +/* CRC Control Register */ + /* Bits 0-23: Reserved */ +#define CRC_CTRL_TCRC (1 << 24) /* Bit 24: Width of CRC protocol */ +#define CRC_CTRL_WAS (1 << 25) /* Bit 25: Write CRC data register as seed */ +#define CRC_CTRL_FXOR (1 << 26) /* Bit 26: Complement Read of CRC data register */ + /* Bit 27: Reserved */ +#define CRC_CTRL_TOTR_SHIFT (28) /* Bits 28-29: Type of Transpose for Read */ +#define CRC_CTRL_TOTR_MASK (3 << CRC_CTRL_TOTR_SHIFT) +# define CRC_CTRL_TOTR_NONE (0 << CRC_CTRL_TOTR_SHIFT) /* No transposition */ +# define CRC_CTRL_TOTR_BITS (1 << CRC_CTRL_TOTR_SHIFT) /* Bits transposed; bytes are not */ +# define CRC_CTRL_TOTR_BOTH (2 << CRC_CTRL_TOTR_SHIFT) /* Both bits bytes and bytes transposed */ +# define CRC_CTRL_TOTR_BYTES (3 << CRC_CTRL_TOTR_SHIFT) /* Bytes transposed; bits in byte are not */ +#define CRC_CTRL_TOT_SHIFT (30) /* Bits 30-31: Type of Transpose for Writes */ +#define CRC_CTRL_TOT_MASK (3 << CRC_CTRL_TOT_SHIFT) +# define CRC_CTRL_TOT_NONE (0 << CRC_CTRL_TOT_SHIFT) /* No transposition */ +# define CRC_CTRL_TOT_BITS (1 << CRC_CTRL_TOT_SHIFT) /* Bits transposed; bytes are not */ +# define CRC_CTRL_TOT_BOTH (2 << CRC_CTRL_TOT_SHIFT) /* Both bits bytes and bytes transposed */ +# define CRC_CTRL_TOT_BYTES (3 << CRC_CTRL_TOT_SHIFT) /* Bytes transposed; bits in byte are not */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* KINETIS_NCRC && KINETIS_NCRC > 0 */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H */ diff --git a/arch/arm/src/kinetis/kinetis_dac.h b/arch/arm/src/kinetis/kinetis_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..5c3b5c0c037503fc669c2427f5581f6b2322285d --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_dac.h @@ -0,0 +1,235 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_dac.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_DAC_DATL_OFFSET(n) (0x0000+((n)<<1)) +#define KINETIS_DAC_DATH_OFFSET(n) (0x0001+((n)<<1)) + +#define KINETIS_DAC_DAT0L_OFFSET 0x0000 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT0H_OFFSET 0x0001 /* DAC Data High Register */ +#define KINETIS_DAC_DAT1L_OFFSET 0x0002 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT1H_OFFSET 0x0003 /* DAC Data High Register */ +#define KINETIS_DAC_DAT2L_OFFSET 0x0004 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT2H_OFFSET 0x0005 /* DAC Data High Register */ +#define KINETIS_DAC_DAT3L_OFFSET 0x0006 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT3H_OFFSET 0x0007 /* DAC Data High Register */ +#define KINETIS_DAC_DAT4L_OFFSET 0x0008 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT4H_OFFSET 0x0009 /* DAC Data High Register */ +#define KINETIS_DAC_DAT5L_OFFSET 0x000a /* DAC Data Low Register */ +#define KINETIS_DAC_DAT5H_OFFSET 0x000b /* DAC Data High Register */ +#define KINETIS_DAC_DAT6L_OFFSET 0x000c /* DAC Data Low Register */ +#define KINETIS_DAC_DAT6H_OFFSET 0x000d /* DAC Data High Register */ +#define KINETIS_DAC_DAT7L_OFFSET 0x000e /* DAC Data Low Register */ +#define KINETIS_DAC_DAT7H_OFFSET 0x000f /* DAC Data High Register */ +#define KINETIS_DAC_DAT8L_OFFSET 0x0010 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT8H_OFFSET 0x0011 /* DAC Data High Register */ +#define KINETIS_DAC_DAT9L_OFFSET 0x0012 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT9H_OFFSET 0x0013 /* DAC Data High Register */ +#define KINETIS_DAC_DAT10L_OFFSET 0x0014 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT10H_OFFSET 0x0015 /* DAC Data High Register */ +#define KINETIS_DAC_DAT11L_OFFSET 0x0016 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT11H_OFFSET 0x0017 /* DAC Data High Register */ +#define KINETIS_DAC_DAT12L_OFFSET 0x0018 /* DAC Data Low Register */ +#define KINETIS_DAC_DAT12H_OFFSET 0x0019 /* DAC Data High Register */ +#define KINETIS_DAC_DAT13L_OFFSET 0x001a /* DAC Data Low Register */ +#define KINETIS_DAC_DAT13H_OFFSET 0x001b /* DAC Data High Register */ +#define KINETIS_DAC_DAT14L_OFFSET 0x001c /* DAC Data Low Register */ +#define KINETIS_DAC_DAT14H_OFFSET 0x001d /* DAC Data High Register */ +#define KINETIS_DAC_DAT15L_OFFSET 0x001e /* DAC Data Low Register */ +#define KINETIS_DAC_DAT15H_OFFSET 0x001f /* DAC Data High Register */ +#define KINETIS_DAC_SR_OFFSET 0x0020 /* DAC Status Register */ +#define KINETIS_DAC_C0_OFFSET 0x0021 /* DAC Control Register */ +#define KINETIS_DAC_C1_OFFSET 0x0022 /* DAC Control Register 1 */ +#define KINETIS_DAC_C2_OFFSET 0x0023 /* DAC Control Register 2 */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_DAC0_DATL(n) (KINETIS_DAC0_BASE+KINETIS_DAC_DATL_OFFSET(n)) +#define KINETIS_DAC0_DATH(n) (KINETIS_DAC0_BASE+KINETIS_DAC_DATH_OFFSET(n)) + +#define KINETIS_DAC0_DAT0L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT0L_OFFSET) +#define KINETIS_DAC0_DAT0H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT0H_OFFSET) +#define KINETIS_DAC0_DAT1L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT1L_OFFSET) +#define KINETIS_DAC0_DAT1H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT1H_OFFSET) +#define KINETIS_DAC0_DAT2L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT2L_OFFSET) +#define KINETIS_DAC0_DAT2H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT2H_OFFSET) +#define KINETIS_DAC0_DAT3L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT3L_OFFSET) +#define KINETIS_DAC0_DAT3H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT3H_OFFSET) +#define KINETIS_DAC0_DAT4L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT4L_OFFSET) +#define KINETIS_DAC0_DAT4H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT4H_OFFSET) +#define KINETIS_DAC0_DAT5L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT5L_OFFSET) +#define KINETIS_DAC0_DAT5H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT5H_OFFSET) +#define KINETIS_DAC0_DAT6L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT6L_OFFSET) +#define KINETIS_DAC0_DAT6H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT6H_OFFSET) +#define KINETIS_DAC0_DAT7L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT7L_OFFSET) +#define KINETIS_DAC0_DAT7H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT7H_OFFSET) +#define KINETIS_DAC0_DAT8L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT8L_OFFSET) +#define KINETIS_DAC0_DAT8H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT8H_OFFSET) +#define KINETIS_DAC0_DAT9L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT9L_OFFSET) +#define KINETIS_DAC0_DAT9H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT9H_OFFSET) +#define KINETIS_DAC0_DAT10L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT10L_OFFSET) +#define KINETIS_DAC0_DAT10H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT10H_OFFSET) +#define KINETIS_DAC0_DAT11L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT11L_OFFSET) +#define KINETIS_DAC0_DAT11H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT11H_OFFSET) +#define KINETIS_DAC0_DAT12L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT12L_OFFSET) +#define KINETIS_DAC0_DAT12H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT12H_OFFSET) +#define KINETIS_DAC0_DAT13L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT13L_OFFSET) +#define KINETIS_DAC0_DAT13H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT13H_OFFSET) +#define KINETIS_DAC0_DAT14L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT14L_OFFSET) +#define KINETIS_DAC0_DAT14H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT14H_OFFSET) +#define KINETIS_DAC0_DAT15L (KINETIS_DAC0_BASE+KINETIS_DAC_DAT15L_OFFSET) +#define KINETIS_DAC0_DAT15H (KINETIS_DAC0_BASE+KINETIS_DAC_DAT15H_OFFSET) +#define KINETIS_DAC0_SR (KINETIS_DAC0_BASE+KINETIS_DAC_SR_OFFSET) +#define KINETIS_DAC0_C0 (KINETIS_DAC0_BASE+KINETIS_DAC_C0_OFFSET) +#define KINETIS_DAC0_C1 (KINETIS_DAC0_BASE+KINETIS_DAC_C1_OFFSET) +#define KINETIS_DAC0_C2 (KINETIS_DAC0_BASE+KINETIS_DAC_C2_OFFSET) + +#define KINETIS_DAC1_DATL(n) (KINETIS_DAC1_BASE+KINETIS_DAC_DATL_OFFSET(n)) +#define KINETIS_DAC1_DATH(n) (KINETIS_DAC1_BASE+KINETIS_DAC_DATH_OFFSET(n)) + +#define KINETIS_DAC1_DAT0L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT0L_OFFSET) +#define KINETIS_DAC1_DAT0H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT0H_OFFSET) +#define KINETIS_DAC1_DAT1L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT1L_OFFSET) +#define KINETIS_DAC1_DAT1H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT1H_OFFSET) +#define KINETIS_DAC1_DAT2L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT2L_OFFSET) +#define KINETIS_DAC1_DAT2H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT2H_OFFSET) +#define KINETIS_DAC1_DAT3L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT3L_OFFSET) +#define KINETIS_DAC1_DAT3H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT3H_OFFSET) +#define KINETIS_DAC1_DAT4L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT4L_OFFSET) +#define KINETIS_DAC1_DAT4H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT4H_OFFSET) +#define KINETIS_DAC1_DAT5L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT5L_OFFSET) +#define KINETIS_DAC1_DAT5H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT5H_OFFSET) +#define KINETIS_DAC1_DAT6L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT6L_OFFSET) +#define KINETIS_DAC1_DAT6H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT6H_OFFSET) +#define KINETIS_DAC1_DAT7L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT7L_OFFSET) +#define KINETIS_DAC1_DAT7H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT7H_OFFSET) +#define KINETIS_DAC1_DAT8L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT8L_OFFSET) +#define KINETIS_DAC1_DAT8H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT8H_OFFSET) +#define KINETIS_DAC1_DAT9L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT9L_OFFSET) +#define KINETIS_DAC1_DAT9H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT9H_OFFSET) +#define KINETIS_DAC1_DAT10L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT10L_OFFSET) +#define KINETIS_DAC1_DAT10H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT10H_OFFSET) +#define KINETIS_DAC1_DAT11L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT11L_OFFSET) +#define KINETIS_DAC1_DAT11H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT11H_OFFSET) +#define KINETIS_DAC1_DAT12L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT12L_OFFSET) +#define KINETIS_DAC1_DAT12H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT12H_OFFSET) +#define KINETIS_DAC1_DAT13L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT13L_OFFSET) +#define KINETIS_DAC1_DAT13H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT13H_OFFSET) +#define KINETIS_DAC1_DAT14L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT14L_OFFSET) +#define KINETIS_DAC1_DAT14H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT14H_OFFSET) +#define KINETIS_DAC1_DAT15L (KINETIS_DAC1_BASE+KINETIS_DAC_DAT15L_OFFSET) +#define KINETIS_DAC1_DAT15H (KINETIS_DAC1_BASE+KINETIS_DAC_DAT15H_OFFSET) +#define KINETIS_DAC1_SR (KINETIS_DAC1_BASE+KINETIS_DAC_SR_OFFSET) +#define KINETIS_DAC1_C0 (KINETIS_DAC1_BASE+KINETIS_DAC_C0_OFFSET) +#define KINETIS_DAC1_C1 (KINETIS_DAC1_BASE+KINETIS_DAC_C1_OFFSET) +#define KINETIS_DAC1_C2 (KINETIS_DAC1_BASE+KINETIS_DAC_C2_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* DAC Data Low Register (8-bits of data DATA[7:0]) */ +/* DAC Data High Register */ + +#define DAC_DAT0H_MASK (0x0f) /* Bits 0-3: DATA[11:8] */ + +/* DAC Status Register */ + +#define DAC_SR_DACBFRPBF (1 << 0) /* Bit 0: DAC buffer read pointer bottom position flag */ +#define DAC_SR_DACBFRPTF (1 << 1) /* Bit 1: DAC buffer read pointer top position flag */ +#define DAC_SR_DACBFWMF (1 << 2) /* Bit 2: DAC buffer watermark flag + /* Bits 3-7: Reserved */ +/* DAC Control Register */ + +#define DAC_C0_DACBBIEN (1 << 0) /* Bit 0: DAC buffer read pointer bottom flag interrupt enable */ +#define DAC_C0_DACBTIEN (1 << 1) /* Bit 1: DAC buffer read pointer top flag interrupt enable */ +#define DAC_C0_LPEN (1 << 3) /* Bit 3: DAC low power control */ +#define DAC_C0_DACBWIEN (1 << 2) /* Bit 2: DAC buffer watermark interrupt enable */ +#define DAC_C0_DACSWTRG (1 << 4) /* Bit 4: DAC software trigger */ +#define DAC_C0_DACTRGSEL (1 << 5) /* Bit 5: DAC trigger select */ +#define DAC_C0_DACRFS (1 << 6) /* Bit 6: DAC Reference Select */ +#define DAC_C0_DACEN (1 << 7) /* Bit 7: DAC enable */ + +/* DAC Control Register 1 */ + +#define DAC_C1_DACBFEN (1 << 0) /* Bit nn: DAC buffer enable */ +#define DAC_C1_DACBFMD_SHIFT (1) /* Bits 1-2: DAC buffer work mode select00 Normal Mode */ +#define DAC_C1_DACBFMD_MASK (3 << DAC_C1_DACBFMD_SHIFT) +# define DAC_C1_DACBFMD_NORMAL (0 << DAC_C1_DACBFMD_SHIFT) /* Normal Mode */ +# define DAC_C1_DACBFMD_SWING (1 << DAC_C1_DACBFMD_SHIFT) /* Swing Mode */ +# define DAC_C1_DACBFMD_OTSCAN (2 << DAC_C1_DACBFMD_SHIFT) /* One-Time Scan Mode */ +#define DAC_C1_DACBFWM_SHIFT (3) /* Bits 3-4: DAC buffer watermark select */ +#define DAC_C1_DACBFWM_MASK (3 << DAC_C1_DACBFWM_SHIFT) +# define DAC_C1_DACBFWM_1WORD (0 << DAC_C1_DACBFWM_SHIFT) +# define DAC_C1_DACBFWM_2WORDS (1 << DAC_C1_DACBFWM_SHIFT) +# define DAC_C1_DACBFWM_3WORDS (2 << DAC_C1_DACBFWM_SHIFT) +# define DAC_C1_DACBFWM_4WORDS (3 << DAC_C1_DACBFWM_SHIFT) + /* Bits 5-6: Reserved */ +#define DAC_C1_DMAEN (1 << 7) /* Bit 7: DMA enable select */ + +/* DAC Control Register 2 */ + +#define DAC_C2_DACBFRP_SHIFT (4) /* Bits 4-7: DAC buffer read pointer */ +#define DAC_C2_DACBFRP_MASK (15 << DAC_C2_DACBFRP_SHIFT) +#define DAC_C2_DACBFUP_SHIFT (0) /* Bits 0-3: DAC buffer upper limit */ +#define DAC_C2_DACBFUP_MASK (15 << DAC_C2_DACBFUP_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H */ diff --git a/arch/arm/src/kinetis/kinetis_dma.h b/arch/arm/src/kinetis/kinetis_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..9876a46a0f0fdc794f55676c284e2f446ea5dd8a --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_dma.h @@ -0,0 +1,775 @@ +/**************************************************************************************************** + * arch/arm/src/kinetis/kinetis_dma.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define KINETIS_DMA_CR_OFFSET 0x0000 /* Control Register */ +#define KINETIS_DMA_ES_OFFSET 0x0004 /* Error Status Register */ +#define KINETIS_DMA_ERQ_OFFSET 0x000c /* Enable Request Register */ +#define KINETIS_DMA_EEI_OFFSET 0x0014 /* Enable Error Interrupt Register */ +#define KINETIS_DMA_CEEI_OFFSET 0x0018 /* Clear Enable Error Interrupt Register */ +#define KINETIS_DMA_SEEI_OFFSET 0x0019 /* Set Enable Error Interrupt Register */ +#define KINETIS_DMA_CERQ_OFFSET 0x001a /* Clear Enable Request Register */ +#define KINETIS_DMA_SERQ_OFFSET 0x001b /* Set Enable Request Register */ +#define KINETIS_DMA_CDNE_OFFSET 0x001c /* Clear DONE Status Bit Register */ +#define KINETIS_DMA_SSRT_OFFSET 0x001d /* Set START Bit Register */ +#define KINETIS_DMA_CERR_OFFSET 0x001e /* Clear Error Register */ +#define KINETIS_DMA_CINT_OFFSET 0x001f /* Clear Interrupt Request Register */ +#define KINETIS_DMA_INT_OFFSET 0x0024 /* Interrupt Request Register */ +#define KINETIS_DMA_ERR_OFFSET 0x002c /* Error Register */ +#define KINETIS_DMA_HRS_OFFSET 0x0034 /* Hardware Request Status Register */ + +#define KINETIS_DMA_DCHPRI3_OFFSET 0x0100 /* Channel 3 Priority Register */ +#define KINETIS_DMA_DCHPRI2_OFFSET 0x0101 /* Channel 2 Priority Register */ +#define KINETIS_DMA_DCHPRI1_OFFSET 0x0102 /* Channel 1 Priority Register */ +#define KINETIS_DMA_DCHPRI0_OFFSET 0x0103 /* Channel 0 Priority Register */ +#define KINETIS_DMA_DCHPRI7_OFFSET 0x0104 /* Channel 7 Priority Register */ +#define KINETIS_DMA_DCHPRI6_OFFSET 0x0105 /* Channel 6 Priority Register */ +#define KINETIS_DMA_DCHPRI5_OFFSET 0x0106 /* Channel 5 Priority Register */ +#define KINETIS_DMA_DCHPRI4_OFFSET 0x0107 /* Channel 4 Priority Register */ +#define KINETIS_DMA_DCHPRI11_OFFSET 0x0108 /* Channel 11 Priority Register */ +#define KINETIS_DMA_DCHPRI10_OFFSET 0x0109 /* Channel 10 Priority Register */ +#define KINETIS_DMA_DCHPRI9_OFFSET 0x010a /* Channel 9 Priority Register */ +#define KINETIS_DMA_DCHPRI8_OFFSET 0x010b /* Channel 8 Priority Register */ +#define KINETIS_DMA_DCHPRI15_OFFSET 0x010c /* Channel 15 Priority Register */ +#define KINETIS_DMA_DCHPRI14_OFFSET 0x010d /* Channel 14 Priority Register */ +#define KINETIS_DMA_DCHPRI13_OFFSET 0x010e /* Channel 13 Priority Register */ +#define KINETIS_DMA_DCHPRI12_OFFSET 0x010f /* Channel 12 Priority Register */ + +#define KINETIS_DMA_TCD_OFFSET(n) (0x0000+((n) << 5)) +#define KINETIS_DMA_TCD_SADDR_OFFSET 0x0000 /* TCD Source Address */ +#define KINETIS_DMA_TCD_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD_DADDR_OFFSET 0x0010 /* TCD Destination Address */ +#define KINETIS_DMA_TCD_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD_CSR_OFFSET 0x001c /* TCD Control and Status */ +#define KINETIS_DMA_TCD_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD0_SADDR_OFFSET 0x0000 /* TCD Source Address */ +#define KINETIS_DMA_TCD0_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD0_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD0_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD0_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD0_DADDR_OFFSET 0x0010 /* TCD Destination Address */ +#define KINETIS_DMA_TCD0_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD0_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD0_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD0_CSR_OFFSET 0x001c /* TCD Control and Status */ +#define KINETIS_DMA_TCD0_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD1_SADDR_OFFSET 0x0020 /* TCD Source Address */ +#define KINETIS_DMA_TCD1_SOFF_OFFSET 0x0024 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD1_ATTR_OFFSET 0x0026 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD1_NBYTES_OFFSET 0x0028 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD1_SLAST_OFFSET 0x002c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD1_DADDR_OFFSET 0x0030 /* TCD Destination Address */ +#define KINETIS_DMA_TCD1_DOFF_OFFSET 0x0034 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD1_CITER_OFFSET 0x0036 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD1_DLASTSGA_OFFSET 0x0038 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD1_CSR_OFFSET 0x003c /* TCD Control and Status */ +#define KINETIS_DMA_TCD1_BITER_OFFSET 0x003e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD2_SADDR_OFFSET 0x0040 /* TCD Source Address */ +#define KINETIS_DMA_TCD2_SOFF_OFFSET 0x0044 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD2_ATTR_OFFSET 0x0046 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD2_NBYTES_OFFSET 0x0048 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD2_SLAST_OFFSET 0x004c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD2_DADDR_OFFSET 0x0050 /* TCD Destination Address */ +#define KINETIS_DMA_TCD2_DOFF_OFFSET 0x0054 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD2_CITER_OFFSET 0x0056 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD2_DLASTSGA_OFFSET 0x0058 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD2_CSR_OFFSET 0x005c /* TCD Control and Status */ +#define KINETIS_DMA_TCD2_BITER_OFFSET 0x005e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD3_SADDR_OFFSET 0x0060 /* TCD Source Address */ +#define KINETIS_DMA_TCD3_SOFF_OFFSET 0x0064 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD3_ATTR_OFFSET 0x0066 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD3_NBYTES_OFFSET 0x0068 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD3_SLAST_OFFSET 0x006c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD3_DADDR_OFFSET 0x0070 /* TCD Destination Address */ +#define KINETIS_DMA_TCD3_DOFF_OFFSET 0x0074 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD3_CITER_OFFSET 0x0076 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD3_DLASTSGA_OFFSET 0x0078 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD3_CSR_OFFSET 0x007c /* TCD Control and Status */ +#define KINETIS_DMA_TCD3_BITER_OFFSET 0x007e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD4_SADDR_OFFSET 0x0080 /* TCD Source Address */ +#define KINETIS_DMA_TCD4_SOFF_OFFSET 0x0084 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD4_ATTR_OFFSET 0x0086 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD4_NBYTES_OFFSET 0x0088 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD4_SLAST_OFFSET 0x008c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD4_DADDR_OFFSET 0x0090 /* TCD Destination Address */ +#define KINETIS_DMA_TCD4_DOFF_OFFSET 0x0094 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD4_CITER_OFFSET 0x0096 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD4_DLASTSGA_OFFSET 0x0098 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD4_CSR_OFFSET 0x009c /* TCD Control and Status */ +#define KINETIS_DMA_TCD4_BITER_OFFSET 0x009e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD5_SADDR_OFFSET 0x00a0 /* TCD Source Address */ +#define KINETIS_DMA_TCD5_SOFF_OFFSET 0x00a4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD5_ATTR_OFFSET 0x00a6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD5_NBYTES_OFFSET 0x00a8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD5_SLAST_OFFSET 0x00ac /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD5_DADDR_OFFSET 0x00b0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD5_DOFF_OFFSET 0x00b4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD5_CITER_OFFSET 0x00b6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD5_DLASTSGA_OFFSET 0x00b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD5_CSR_OFFSET 0x00bc /* TCD Control and Status */ +#define KINETIS_DMA_TCD5_BITER_OFFSET 0x00be /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD6_SADDR_OFFSET 0x00c0 /* TCD Source Address */ +#define KINETIS_DMA_TCD6_SOFF_OFFSET 0x00c4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD6_ATTR_OFFSET 0x00c6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD6_NBYTES_OFFSET 0x00c8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD6_SLAST_OFFSET 0x00cc /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD6_DADDR_OFFSET 0x00d0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD6_DOFF_OFFSET 0x00d4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD6_CITER_OFFSET 0x00d6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD6_DLASTSGA_OFFSET 0x00d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD6_CSR_OFFSET 0x00dc /* TCD Control and Status */ +#define KINETIS_DMA_TCD6_BITER_OFFSET 0x00de /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD7_SADDR_OFFSET 0x00e0 /* TCD Source Address */ +#define KINETIS_DMA_TCD7_SOFF_OFFSET 0x00e4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD7_ATTR_OFFSET 0x00e6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD7_NBYTES_OFFSET 0x00e8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD7_SLAST_OFFSET 0x00ec /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD7_DADDR_OFFSET 0x00f0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD7_DOFF_OFFSET 0x00f4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD7_CITER_OFFSET 0x00f6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD7_DLASTSGA_OFFSET 0x00f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD7_CSR_OFFSET 0x00fc /* TCD Control and Status */ +#define KINETIS_DMA_TCD7_BITER_OFFSET 0x00fe /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD8_SADDR_OFFSET 0x0100 /* TCD Source Address */ +#define KINETIS_DMA_TCD8_SOFF_OFFSET 0x0104 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD8_ATTR_OFFSET 0x0106 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD8_NBYTES_OFFSET 0x0108 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD8_SLAST_OFFSET 0x010c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD8_DADDR_OFFSET 0x0110 /* TCD Destination Address */ +#define KINETIS_DMA_TCD8_DOFF_OFFSET 0x0114 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD8_CITER_OFFSET 0x0116 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD8_DLASTSGA_OFFSET 0x0118 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD8_CSR_OFFSET 0x011c /* TCD Control and Status */ +#define KINETIS_DMA_TCD8_BITER_OFFSET 0x011e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD9_SADDR_OFFSET 0x0120 /* TCD Source Address */ +#define KINETIS_DMA_TCD9_SOFF_OFFSET 0x0124 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD9_ATTR_OFFSET 0x0126 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD9_NBYTES_OFFSET 0x0128 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD9_SLAST_OFFSET 0x012c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD9_DADDR_OFFSET 0x0130 /* TCD Destination Address */ +#define KINETIS_DMA_TCD9_DOFF_OFFSET 0x0134 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD9_CITER_OFFSET 0x0136 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD9_DLASTSGA_OFFSET 0x0138 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD9_CSR_OFFSET 0x013c /* TCD Control and Status */ +#define KINETIS_DMA_TCD9_BITER_OFFSET 0x013e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD10_SADDR_OFFSET 0x0140 /* TCD Source Address */ +#define KINETIS_DMA_TCD10_SOFF_OFFSET 0x0144 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD10_ATTR_OFFSET 0x0146 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD10_NBYTES_OFFSET 0x0148 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD10_SLAST_OFFSET 0x014c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD10_DADDR_OFFSET 0x0150 /* TCD Destination Address */ +#define KINETIS_DMA_TCD10_DOFF_OFFSET 0x0154 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD10_CITER_OFFSET 0x0156 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD10_DLASTSGA_OFFSET 0x0158 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD10_CSR_OFFSET 0x015c /* TCD Control and Status */ +#define KINETIS_DMA_TCD10_BITER_OFFSET 0x015e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD11_SADDR_OFFSET 0x0160 /* TCD Source Address */ +#define KINETIS_DMA_TCD11_SOFF_OFFSET 0x0164 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD11_ATTR_OFFSET 0x0166 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD11_NBYTES_OFFSET 0x0168 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD11_SLAST_OFFSET 0x016c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD11_DADDR_OFFSET 0x0170 /* TCD Destination Address */ +#define KINETIS_DMA_TCD11_DOFF_OFFSET 0x0174 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD11_CITER_OFFSET 0x0176 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD11_DLASTSGA_OFFSET 0x0178 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD11_CSR_OFFSET 0x017c /* TCD Control and Status */ +#define KINETIS_DMA_TCD11_BITER_OFFSET 0x017e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD12_SADDR_OFFSET 0x0180 /* TCD Source Address */ +#define KINETIS_DMA_TCD12_SOFF_OFFSET 0x0184 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD12_ATTR_OFFSET 0x0186 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD12_NBYTES_OFFSET 0x0188 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD12_SLAST_OFFSET 0x018c /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD12_DADDR_OFFSET 0x0190 /* TCD Destination Address */ +#define KINETIS_DMA_TCD12_DOFF_OFFSET 0x0194 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD12_CITER_OFFSET 0x0196 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD12_DLASTSGA_OFFSET 0x0198 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD12_CSR_OFFSET 0x019c /* TCD Control and Status */ +#define KINETIS_DMA_TCD12_BITER_OFFSET 0x019e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD13_SADDR_OFFSET 0x01a0 /* TCD Source Address */ +#define KINETIS_DMA_TCD13_SOFF_OFFSET 0x01a4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD13_ATTR_OFFSET 0x01a6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD13_NBYTES_OFFSET 0x01a8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD13_SLAST_OFFSET 0x01ac /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD13_DADDR_OFFSET 0x01b0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD13_DOFF_OFFSET 0x01b4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD13_CITER_OFFSET 0x01b6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD13_DLASTSGA_OFFSET 0x01b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD13_CSR_OFFSET 0x01bc /* TCD Control and Status */ +#define KINETIS_DMA_TCD13_BITER_OFFSET 0x01be /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD14_SADDR_OFFSET 0x01c0 /* TCD Source Address */ +#define KINETIS_DMA_TCD14_SOFF_OFFSET 0x01c4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD14_ATTR_OFFSET 0x01c6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD14_NBYTES_OFFSET 0x01c8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD14_SLAST_OFFSET 0x01cc /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD14_DADDR_OFFSET 0x01d0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD14_DOFF_OFFSET 0x01d4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD14_CITER_OFFSET 0x01d6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD14_DLASTSGA_OFFSET 0x01d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD14_CSR_OFFSET 0x01dc /* TCD Control and Status */ +#define KINETIS_DMA_TCD14_BITER_OFFSET 0x01de /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_DMA_TCD15_SADDR_OFFSET 0x01e0 /* TCD Source Address */ +#define KINETIS_DMA_TCD15_SOFF_OFFSET 0x01e4 /* TCD Signed Source Address Offset */ +#define KINETIS_DMA_TCD15_ATTR_OFFSET 0x01e6 /* TCD Transfer Attributes */ +#define KINETIS_DMA_TCD15_NBYTES_OFFSET 0x01e8 /* TCD Minor Byte Count */ +#define KINETIS_DMA_TCD15_SLAST_OFFSET 0x01ec /* TCD Last Source Address Adjustment */ +#define KINETIS_DMA_TCD15_DADDR_OFFSET 0x01f0 /* TCD Destination Address */ +#define KINETIS_DMA_TCD15_DOFF_OFFSET 0x01f4 /* TCD Signed Destination Address Offset */ +#define KINETIS_DMA_TCD15_CITER_OFFSET 0x01f6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_DMA_TCD15_DLASTSGA_OFFSET 0x01f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_DMA_TCD15_CSR_OFFSET 0x01fc /* TCD Control and Status */ +#define KINETIS_DMA_TCD15_BITER_OFFSET 0x01fe /* TCD Beginning Minor Loop Link, Major Loop Count */ + +/* Register Addresses *******************************************************************************/ + +#define KINETIS_DMA_CR (KINETIS_DMAC_BASE+KINETIS_DMA_CR_OFFSET) +#define KINETIS_DMA_ES (KINETIS_DMAC_BASE+KINETIS_DMA_ES_OFFSET) +#define KINETIS_DMA_ERQ (KINETIS_DMAC_BASE+KINETIS_DMA_ERQ_OFFSET) +#define KINETIS_DMA_EEI (KINETIS_DMAC_BASE+KINETIS_DMA_EEI_OFFSET) +#define KINETIS_DMA_CEEI (KINETIS_DMAC_BASE+KINETIS_DMA_CEEI_OFFSET) +#define KINETIS_DMA_SEEI (KINETIS_DMAC_BASE+KINETIS_DMA_SEEI_OFFSET) +#define KINETIS_DMA_CERQ (KINETIS_DMAC_BASE+KINETIS_DMA_CERQ_OFFSET) +#define KINETIS_DMA_SERQ (KINETIS_DMAC_BASE+KINETIS_DMA_SERQ_OFFSET) +#define KINETIS_DMA_CDNE (KINETIS_DMAC_BASE+KINETIS_DMA_CDNE_OFFSET) +#define KINETIS_DMA_SSRT (KINETIS_DMAC_BASE+KINETIS_DMA_SSRT_OFFSET) +#define KINETIS_DMA_CERR (KINETIS_DMAC_BASE+KINETIS_DMA_CERR_OFFSET) +#define KINETIS_DMA_CINT (KINETIS_DMAC_BASE+KINETIS_DMA_CINT_OFFSET) +#define KINETIS_DMA_INT (KINETIS_DMAC_BASE+KINETIS_DMA_INT_OFFSET) +#define KINETIS_DMA_ERR (KINETIS_DMAC_BASE+KINETIS_DMA_ERR_OFFSET) +#define KINETIS_DMA_HRS (KINETIS_DMAC_BASE+KINETIS_DMA_HRS_OFFSET) + +#define KINETIS_DMA_DCHPRI3 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI3_OFFSET) +#define KINETIS_DMA_DCHPRI2 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI2_OFFSET) +#define KINETIS_DMA_DCHPRI1 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI1_OFFSET) +#define KINETIS_DMA_DCHPRI0 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI0_OFFSET) +#define KINETIS_DMA_DCHPRI7 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI7_OFFSET) +#define KINETIS_DMA_DCHPRI6 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI6_OFFSET) +#define KINETIS_DMA_DCHPRI5 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI5_OFFSET) +#define KINETIS_DMA_DCHPRI4 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI4_OFFSET) +#define KINETIS_DMA_DCHPRI11 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI11_OFFSET) +#define KINETIS_DMA_DCHPRI10 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI10_OFFSET) +#define KINETIS_DMA_DCHPRI9 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI9_OFFSET) +#define KINETIS_DMA_DCHPRI8 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI8_OFFSET) +#define KINETIS_DMA_DCHPRI15 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI15_OFFSET) +#define KINETIS_DMA_DCHPRI14 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI14_OFFSET) +#define KINETIS_DMA_DCHPRI13 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI13_OFFSET) +#define KINETIS_DMA_DCHPRI12 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI12_OFFSET) + +#define KINETIS_DMA_TCD_BASE(n) (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD_OFFSET(n)) + +#define KINETIS_DMA_TCD_SADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SADDR_OFFSET) +#define KINETIS_DMA_TCD_SOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SOFF_OFFSET) +#define KINETIS_DMA_TCD_ATTR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_ATTR_OFFSET) +#define KINETIS_DMA_TCD_NBYTES(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_NBYTES_OFFSET) +#define KINETIS_DMA_TCD_SLAST(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SLAST_OFFSET) +#define KINETIS_DMA_TCD_DADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DADDR_OFFSET) +#define KINETIS_DMA_TCD_DOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DOFF_OFFSET) +#define KINETIS_DMA_TCD_CITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CITER_OFFSET) +#define KINETIS_DMA_TCD_DLASTSGA(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD_CSR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CSR_OFFSET) +#define KINETIS_DMA_TCD_BITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_BITER_OFFSET) + +#define KINETIS_DMA_TCD0_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_SADDR_OFFSET) +#define KINETIS_DMA_TCD0_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_SOFF_OFFSET) +#define KINETIS_DMA_TCD0_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_ATTR_OFFSET) +#define KINETIS_DMA_TCD0_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_NBYTES_OFFSET) +#define KINETIS_DMA_TCD0_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_SLAST_OFFSET) +#define KINETIS_DMA_TCD0_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_DADDR_OFFSET) +#define KINETIS_DMA_TCD0_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_DOFF_OFFSET) +#define KINETIS_DMA_TCD0_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_CITER_OFFSET) +#define KINETIS_DMA_TCD0_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD0_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_CSR_OFFSET) +#define KINETIS_DMA_TCD0_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_BITER_OFFSET) + +#define KINETIS_DMA_TCD1_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_SADDR_OFFSET) +#define KINETIS_DMA_TCD1_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_SOFF_OFFSET) +#define KINETIS_DMA_TCD1_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_ATTR_OFFSET) +#define KINETIS_DMA_TCD1_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_NBYTES_OFFSET) +#define KINETIS_DMA_TCD1_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_SLAST_OFFSET) +#define KINETIS_DMA_TCD1_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_DADDR_OFFSET) +#define KINETIS_DMA_TCD1_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_DOFF_OFFSET) +#define KINETIS_DMA_TCD1_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_CITER_OFFSET) +#define KINETIS_DMA_TCD1_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD1_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_CSR_OFFSET) +#define KINETIS_DMA_TCD1_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD1_BITER_OFFSET) + +#define KINETIS_DMA_TCD2_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_SADDR_OFFSET) +#define KINETIS_DMA_TCD2_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_SOFF_OFFSET) +#define KINETIS_DMA_TCD2_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_ATTR_OFFSET) +#define KINETIS_DMA_TCD2_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_NBYTES_OFFSET) +#define KINETIS_DMA_TCD2_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_SLAST_OFFSET) +#define KINETIS_DMA_TCD2_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_DADDR_OFFSET) +#define KINETIS_DMA_TCD2_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_DOFF_OFFSET) +#define KINETIS_DMA_TCD2_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_CITER_OFFSET) +#define KINETIS_DMA_TCD2_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD2_CSR_ (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_CSR_OFFSET) +#define KINETIS_DMA_TCD2_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD2_BITER_OFFSET) + +#define KINETIS_DMA_TCD3_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_SADDR_OFFSET) +#define KINETIS_DMA_TCD3_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_SOFF_OFFSET) +#define KINETIS_DMA_TCD3_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_ATTR_OFFSET) +#define KINETIS_DMA_TCD3_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_NBYTES_OFFSET) +#define KINETIS_DMA_TCD3_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_SLAST_OFFSET) +#define KINETIS_DMA_TCD3_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_DADDR_OFFSET) +#define KINETIS_DMA_TCD3_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_DOFF_OFFSET) +#define KINETIS_DMA_TCD3_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_CITER_OFFSET) +#define KINETIS_DMA_TCD3_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_DLASTSGA_OFFSET +#define KINETIS_DMA_TCD3_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_CSR_OFFSET) +#define KINETIS_DMA_TCD3_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD3_BITER_OFFSET) + +#define KINETIS_DMA_TCD4_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_SADDR_OFFSET) +#define KINETIS_DMA_TCD4_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_SOFF_OFFSET) +#define KINETIS_DMA_TCD4_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_ATTR_OFFSET0) +#define KINETIS_DMA_TCD4_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_NBYTES_OFFSET) +#define KINETIS_DMA_TCD4_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_SLAST_OFFSET) +#define KINETIS_DMA_TCD4_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_DADDR_OFFSET) +#define KINETIS_DMA_TCD4_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_DOFF_OFFSET) +#define KINETIS_DMA_TCD4_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_CITER_OFFSET) +#define KINETIS_DMA_TCD4_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD4_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_CSR_OFFSET) +#define KINETIS_DMA_TCD4_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD4_BITER_OFFSET) + +#define KINETIS_DMA_TCD5_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_SADDR_OFFSET) +#define KINETIS_DMA_TCD5_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_SOFF_OFFSET) +#define KINETIS_DMA_TCD5_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_ATTR_OFFSET) +#define KINETIS_DMA_TCD5_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_NBYTES_OFFSET) +#define KINETIS_DMA_TCD5_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_SLAST_OFFSET) +#define KINETIS_DMA_TCD5_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_DADDR_OFFSET) +#define KINETIS_DMA_TCD5_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_DOFF_OFFSET) +#define KINETIS_DMA_TCD5_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_CITER_OFFSET) +#define KINETIS_DMA_TCD5_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD5_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_CSR_OFFSET) +#define KINETIS_DMA_TCD5_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD5_BITER_OFFSET) + +#define KINETIS_DMA_TCD6_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_SADDR_OFFSET) +#define KINETIS_DMA_TCD6_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_SOFF_OFFSET) +#define KINETIS_DMA_TCD6_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_ATTR_OFFSET) +#define KINETIS_DMA_TCD6_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_NBYTES_OFFSET) +#define KINETIS_DMA_TCD6_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_SLAST_OFFSET) +#define KINETIS_DMA_TCD6_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_DADDR_OFFSET) +#define KINETIS_DMA_TCD6_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_DOFF_OFFSET) +#define KINETIS_DMA_TCD6_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_CITER_OFFSET) +#define KINETIS_DMA_TCD6_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD6_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_CSR_OFFSET) +#define KINETIS_DMA_TCD6_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD6_BITER_OFFSET) + +#define KINETIS_DMA_TCD7_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_SADDR_OFFSET) +#define KINETIS_DMA_TCD7_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_SOFF_OFFSET) +#define KINETIS_DMA_TCD7_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_ATTR_OFFSET) +#define KINETIS_DMA_TCD7_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_NBYTES_OFFSET) +#define KINETIS_DMA_TCD7_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_SLAST_OFFSET) +#define KINETIS_DMA_TCD7_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_DADDR_OFFSET) +#define KINETIS_DMA_TCD7_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_DOFF_OFFSET) +#define KINETIS_DMA_TCD7_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_CITER_OFFSET) +#define KINETIS_DMA_TCD7_DLASTSGA_ (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD7_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_CSR_OFFSET) +#define KINETIS_DMA_TCD7_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD7_BITER_OFFSET) + +#define KINETIS_DMA_TCD8_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_SADDR_OFFSET) +#define KINETIS_DMA_TCD8_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_SOFF_OFFSET) +#define KINETIS_DMA_TCD8_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_ATTR_OFFSET) +#define KINETIS_DMA_TCD8_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_NBYTES_OFFSET) +#define KINETIS_DMA_TCD8_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_SLAST_OFFSET) +#define KINETIS_DMA_TCD8_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_DADDR_OFFSET) +#define KINETIS_DMA_TCD8_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_DOFF_OFFSET) +#define KINETIS_DMA_TCD8_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_CITER_OFFSET) +#define KINETIS_DMA_TCD8_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD8_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_CSR_OFFSET) +#define KINETIS_DMA_TCD8_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD8_BITER_OFFSET) + +#define KINETIS_DMA_TCD9_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_SADDR_OFFSET) +#define KINETIS_DMA_TCD9_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_SOFF_OFFSET) +#define KINETIS_DMA_TCD9_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_ATTR_OFFSET) +#define KINETIS_DMA_TCD9_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_NBYTES_OFFSET) +#define KINETIS_DMA_TCD9_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_SLAST_OFFSET) +#define KINETIS_DMA_TCD9_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_DADDR_OFFSET) +#define KINETIS_DMA_TCD9_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_DOFF_OFFSET) +#define KINETIS_DMA_TCD9_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_CITER_OFFSET) +#define KINETIS_DMA_TCD9_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD9_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_CSR_OFFSET) +#define KINETIS_DMA_TCD9_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD9_BITER_OFFSET) + +#define KINETIS_DMA_TCD10_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_SADDR_OFFSET) +#define KINETIS_DMA_TCD10_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_SOFF_OFFSET) +#define KINETIS_DMA_TCD10_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_ATTR_OFFSET) +#define KINETIS_DMA_TCD10_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_NBYTES_OFFSET) +#define KINETIS_DMA_TCD10_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_SLAST_OFFSET) +#define KINETIS_DMA_TCD10_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_DADDR_OFFSET) +#define KINETIS_DMA_TCD10_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_DOFF_OFFSET) +#define KINETIS_DMA_TCD10_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_CITER_OFFSET) +#define KINETIS_DMA_TCD10_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD10_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_CSR_OFFSET) +#define KINETIS_DMA_TCD10_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD10_BITER_OFFSET) + +#define KINETIS_DMA_TCD11_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_SADDR_OFFSET) +#define KINETIS_DMA_TCD11_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_SOFF_OFFSET) +#define KINETIS_DMA_TCD11_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_ATTR_OFFSET) +#define KINETIS_DMA_TCD11_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_NBYTES_OFFSET) +#define KINETIS_DMA_TCD11_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_SLAST_OFFSET) +#define KINETIS_DMA_TCD11_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_DADDR_OFFSET) +#define KINETIS_DMA_TCD11_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_DOFF_OFFSET) +#define KINETIS_DMA_TCD11_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_CITER_OFFSET) +#define KINETIS_DMA_TCD11_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD11_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_CSR_OFFSET) +#define KINETIS_DMA_TCD11_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD11_BITER_OFFSET) + +#define KINETIS_DMA_TCD12_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_SADDR_OFFSET) +#define KINETIS_DMA_TCD12_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_SOFF_OFFSET) +#define KINETIS_DMA_TCD12_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_ATTR_OFFSET) +#define KINETIS_DMA_TCD12_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_NBYTES_OFFSET) +#define KINETIS_DMA_TCD12_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_SLAST_OFFSET) +#define KINETIS_DMA_TCD12_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_DADDR_OFFSET) +#define KINETIS_DMA_TCD12_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_DOFF_OFFSET) +#define KINETIS_DMA_TCD12_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_CITER_OFFSET) +#define KINETIS_DMA_TCD12_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD12_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_CSR_OFFSET) +#define KINETIS_DMA_TCD12_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD12_BITER_OFFSET) + +#define KINETIS_DMA_TCD13_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_SADDR_OFFSET) +#define KINETIS_DMA_TCD13_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_SOFF_OFFSET) +#define KINETIS_DMA_TCD13_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_ATTR_OFFSET) +#define KINETIS_DMA_TCD13_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_NBYTES_OFFSET) +#define KINETIS_DMA_TCD13_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_SLAST_OFFSET) +#define KINETIS_DMA_TCD13_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_DADDR_OFFSET) +#define KINETIS_DMA_TCD13_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_DOFF_OFFSET) +#define KINETIS_DMA_TCD13_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_CITER_OFFSET) +#define KINETIS_DMA_TCD13_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD13_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_CSR_OFFSET) +#define KINETIS_DMA_TCD13_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD13_BITER_OFFSET) + +#define KINETIS_DMA_TCD14_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_SADDR_OFFSET) +#define KINETIS_DMA_TCD14_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_SOFF_OFFSET) +#define KINETIS_DMA_TCD14_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_ATTR_OFFSET) +#define KINETIS_DMA_TCD14_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_NBYTES_OFFSET) +#define KINETIS_DMA_TCD14_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_SLAST_OFFSET) +#define KINETIS_DMA_TCD14_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_DADDR_OFFSET) +#define KINETIS_DMA_TCD14_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_DOFF_OFFSET) +#define KINETIS_DMA_TCD14_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_CITER_OFFSET) +#define KINETIS_DMA_TCD14_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD14_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_CSR_OFFSET) +#define KINETIS_DMA_TCD14_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD14_BITER_OFFSET) + +#define KINETIS_DMA_TCD15_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_SADDR_OFFSET) +#define KINETIS_DMA_TCD15_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_SOFF_OFFSET) +#define KINETIS_DMA_TCD15_ATTR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_ATTR_OFFSET) +#define KINETIS_DMA_TCD15_NBYTES (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_NBYTES_OFFSET) +#define KINETIS_DMA_TCD15_SLAST (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_SLAST_OFFSET) +#define KINETIS_DMA_TCD15_DADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_DADDR_OFFSET) +#define KINETIS_DMA_TCD15_DOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_DOFF_OFFSET) +#define KINETIS_DMA_TCD15_CITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_CITER_OFFSET) +#define KINETIS_DMA_TCD15_DLASTSGA (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_DLASTSGA_OFFSET) +#define KINETIS_DMA_TCD15_CSR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_CSR_OFFSET) +#define KINETIS_DMA_TCD15_BITER (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD15_BITER_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Control Register (32-bit) */ + /* Bit 0: Reserved */ +#define DMA_CR_EDBG (1 << 1) /* Bit 1: Enable debug */ +#define DMA_CR_ERCA (1 << 2) /* Bit 2: Enable round robin channel arbitration */ + /* Bit 3: Reserved */ +#define DMA_CR_HOE (1 << 4) /* Bit 4: Halt on error */ +#define DMA_CR_HALT (1 << 5) /* Bit 5: Halt DMA operations */ +#define DMA_CR_CLM (1 << 6) /* Bit 6: Continuous link mode */ +#define DMA_CR_EMLM (1 << 7) /* Bit 7: Enable minor loop mapping */ + /* Bits 8-15: Reserved */ +#define DMA_CR_ECX (1 << 16) /* Bit 16: Error cancel transfer */ +#define DMA_CR_CX (1 << 17) /* Bit 17: Cancel transfer */ + /* Bits 18-31: Reserved */ +/* Error Status Register */ + +#define DMA_ES_DBE (1 << 0) /* Bit 0: Destination bus error */ +#define DMA_ES_SBE (1 << 1) /* Bit 1: Source bus error */ +#define DMA_ES_SGE (1 << 2) /* Bit 2: Scatter/gather configuration error */ +#define DMA_ES_NCE (1 << 3) /* Bit 3: NBYTES/CITER configuration error */ +#define DMA_ES_DOE (1 << 4) /* Bit 4: Destination offset error */ +#define DMA_ES_DAE (1 << 5) /* Bit 5: Destination address error */ +#define DMA_ES_SOE (1 << 6) /* Bit 6: Source offset error */ +#define DMA_ES_SAE (1 << 7) /* Bit 7: Source address error */ +#define DMA_ES_ERRCHN_SHIFT (8) /* Bits 8-11: Error channel number or cancelled channel number */ +#define DMA_ES_ERRCHN_MASK (15 << DMA_ES_ERRCHN_SHIFT) + /* Bits 12-13: Reserved */ +#define DMA_ES_CPE (1 << 14) /* Bit 14: Channel priority error */ + /* Bit 15: Reserved */ +#define DMA_ES_ECX (1 << 16) /* Bit 16: Transfer cancelled */ + /* Bits 17-30: Reserved */ +#define DMA_ES_VLD (1 << 31) /* Bit 31: Logical OR of all ERR status bits */ + +/* Enable Request Register, Enable Error Interrupt Register, Interrupt Request Register, Error + * Register, Hardware Request Status Register common bit definitions (32-bit, except for Error + * Register which is 16-bit) + */ + +#define DMA_REQ(n) (1 << (n)) /* Bit n: DMA Request n */ +#define DMA_REQ0 (1 << 0) /* Bit 0: DMA Request 0 */ +#define DMA_REQ1 (1 << 1) /* Bit 1: DMA Request 1 */ +#define DMA_REQ2 (1 << 2) /* Bit 2: DMA Request 2 */ +#define DMA_REQ3 (1 << 3) /* Bit 3: DMA Request 3 */ +#define DMA_REQ4 (1 << 4) /* Bit 4: DMA Request 4 */ +#define DMA_REQ5 (1 << 5) /* Bit 5: DMA Request 5 */ +#define DMA_REQ6 (1 << 6) /* Bit 6: DMA Request 6 */ +#define DMA_REQ7 (1 << 7) /* Bit 7: DMA Request 7 */ +#define DMA_REQ8 (1 << 8) /* Bit 8: DMA Request 8 */ +#define DMA_REQ9 (1 << 9) /* Bit 9: DMA Request 9 */ +#define DMA_REQ10 (1 << 10) /* Bit 10: DMA Request 10 */ +#define DMA_REQ11 (1 << 11) /* Bit 11: DMA Request 11 */ +#define DMA_REQ12 (1 << 12) /* Bit 12: DMA Request 12 */ +#define DMA_REQ13 (1 << 13) /* Bit 13: DMA Request 13 */ +#define DMA_REQ14 (1 << 14) /* Bit 14: DMA Request 14 */ +#define DMA_REQ15 (1 << 15) /* Bit 15: DMA Request 15 */ + /* Bits 16-31: Reserved */ +/* Clear Enable Error Interrupt Register (8-bit) */ + +#define DMA_CEEI_SHIFT (0) /* Bits 0-3: Clear enable error interrupt */ +#define DMA_CEEI_MASK (15 << DMA_CEEI_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_CEEI_CAEE (1 << 6) /* Bit 6: Clear all enable error interrupts */ +#define DMA_CEEI_NOP (1 << 7) /* Bit 7: No operation */ + +/* Set Enable Error Interrupt Register (8-bit) */ + +#define DMA_SEEI_SHIFT (0) /* Bits 0-3: Set enable error interrupt */ +#define DMA_SEEI_MASK (15 << DMA_SEEI_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_SEEI_SAEE (1 << 6) /* Bit 6: Set all enable error interrupts */ +#define DMA_SEEI_NOP (1 << 7) /* Bit 7: No operation */ + +/* Clear Enable Request Register (8-bit) */ + +#define DMA_CERQ_SHIFT (0) /* Bits 0-3: Clear enable request */ +#define DMA_CERQ_MASK (15 << DMA_CERQ_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_CERQ_CAER (1 << 6) /* Bit 6: Clear all enable requests */ +#define DMA_CERQ_NOP (1 << 7) /* Bit 7: No operation */ + +/* Set Enable Request Register (8-bit) */ + +#define DMA_SERQ_SHIFT (0) /* Bits 0-3: Set enable request */ +#define DMA_SERQ_MASK (15 << DMA_SERQ_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_SERQ_SAER (1 << 6) /* Bit 6: Set all enable requests */ +#define DMA_SERQ_NOP (1 << 7) /* Bit 7: No operation */ + +/* Clear DONE Status Bit Register (8-bit) */ + +#define DMA_CDNE_SHIFT (0) /* Bits 0-3: Clear DONE bit */ +#define DMA_CDNE_MASK (15 << DMA_CDNE_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_CDNE_CADN (1 << 6) /* Bit 6: Clears all DONE bits */ +#define DMA_CDNE_NOP (1 << 7) /* Bit 7: No operation */ + +/* Set START Bit Register (8-bit) */ + +#define DMA_SSRT_SHIFT (0) /* Bits 0-3: Set START bit */ +#define DMA_SSRT_MASK (15 << DMA_SSRT_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_SSRT_SAST (1 << 6) /* Bit 6: Set all START bits (activates all channels) */ +#define DMA_SSRT_NOP (1 << 7) /* Bit 7: No operation */ + +/* Clear Error Register (8-bit) */ + +#define DMA_CERR_SHIFT (0) /* Bits 0-3: Clear error indicator */ +#define DMA_CERR_MASK (15 << DMA_CERR_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_CERR_CAEI (1 << 6) /* Bit 6: Clear all error indicators */ +#define DMA_CERR_NOP (1 << 7) /* Bit 7: No operation */ + +/* Clear Interrupt Request Register (8-bit) */ + +#define DMA_CINT_SHIFT (0) /* Bits 0-3: Clear interrupt request */ +#define DMA_CINT_MASK (15 << DMA_CINT_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_CINT_CAIR (1 << 6) /* Bit 6: Clear all interrupt requests */ +#define DMA_CINT_NOP (1 << 7) /* Bit 7: No operation */ + +/* Channel n Priority Register (8-bit) */ + +#define DMA_DCHPR_SHIFT (0) /* Bits 0-3: Channel n arbitration priority */ +#define DMA_DCHPR_MASK (15 << DMA_DCHPR_SHIFT) + /* Bits 4-5: Reserved */ +#define DMA_DCHPR_DPA (1 << 6) /* Bit 6: Disable preempt ability */ +#define DMA_DCHPR_ECP (1 << 7) /* Bit 7: Enable channel preemption */ + + +/* TCD Source Address. 32-bit address value. */ +/* TCD Signed Source Address Offset. 32-bit offset value. */ + +/* TCD Transfer Attributes (16-bit) */ + +#define DMA_TCD_ATTR_DSIZE_SHIFT (0) /* Bits 0-2: Destination data transfer size */ +#define DMA_TCD_ATTR_DSIZE_MASK (7 << DMA_TCD_ATTR_DSIZE_SHIFT) +# define DMA_TCD_ATTR_DSIZE_8BIT (0 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */ +# define DMA_TCD_ATTR_DSIZE_16BIT (1 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 16-bit */ +# define DMA_TCD_ATTR_DSIZE_32BIT (2 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 32-bit */ +# define DMA_TCD_ATTR_DSIZE_16BYTE (4 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 16-byte */ +#define DMA_TCD_ATTR_DMOD_SHIFT (3) /* Bits 3-7: Destination address modulo */ +#define DMA_TCD_ATTR_DMOD_MASK (31 << DMA_TCD_ATTR_DMOD_SHIFT) +#define DMA_TCD_ATTR_SSIZE_SHIFT (8) /* Bits 8-10: Source data transfer size */ +#define DMA_TCD_ATTR_SSIZE_MASK (7 << DMA_TCD_ATTR_SSIZE_SHIFT) +# define DMA_TCD_ATTR_SSIZE_8BIT (0 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */ +# define DMA_TCD_ATTR_SSIZE_16BIT (1 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 16-bit */ +# define DMA_TCD_ATTR_SSIZE_32BIT (2 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 32-bit */ +# define DMA_TCD_ATTR_SSIZE_16BYTE (4 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 16-byte */ +#define DMA_TCD_ATTR_SMOD_SHIFT (11) /* Bits 11-15: Source address modulo */ +#define DMA_TCD_ATTR_SMOD_MASK (31 << DMA_TCD_ATTR_SMOD_SHIFT) + +/* TCD Minor Byte Count. + * Case 1: Minor Loop Disabled. In this case, the register holds a simple 32-bit count value. + * Case 2: Minor Loop Enabled and Offset Disabled: + */ + +#define DMA_TCD_NBYTES2_SHIFT (0) /* Bits 0-29: Minor byte transfer count */ +#define DMA_TCD_NBYTES2_MASK (0x3fffffff) +#define DMA_TCD_NBYTES_DMLOE (1 << 30) /* Bit 30: Destination minor loop offset enable (Case 2&3) */ +#define DMA_TCD_NBYTES_SMLOE (1 << 31) /* Bit 31: Source minor loop offset enable (Case 2&3) */ + +/* Case 3: (Minor Loop and Offset Enabled): */ + +#define DMA_TCD_NBYTES3_SHIFT (0) /* Bits 0-9: Minor byte transfer count */ +#define DMA_TCD_NBYTES3_MASK (0x3ff << DMA_TCD_NBYTES3_SHIFT) +#define DMA_TCD_NBYTES_MLOFF_SHIFT (10) /* Bits 10-29: Sign-extended address offset */ +#define DMA_TCD_NBYTES_MLOFF_MASK (0xfffff << DMA_TCD_NBYTES_MLOFF_SHIFT) + /* Bit 30: Same as Case 2 */ + /* Bit 31: Same as Case 2 */ + +/* TCD Last Source Address Adjustment. 32-bit address value. */ +/* TCD Destination Address. 32-bit address value. */ +/* TCD Signed Destination Address Offset. 32-bit offset value. */ + +/* TCD Current Minor Loop Link, Major Loop Count. 16-bit. + * Case 1: Channel Linking Enabled: + */ + +#define DMA_TCD_CITER1_SHIFT (0) /* Bits 0-8: Current major iteration count */ +#define DMA_TCD_CITER1_MASK (0x1ff << DMA_TCD_CITER1_SHIFT) +#define DMA_TCD_CITER1_LINKCH_SHIFT (9) /* Bits 9-12: Link channel number */ +#define DMA_TCD_CITER1_LINKCH_MASK (15 << DMA_TCD_CITER1_LINKCH_SHIFT) + /* Bits 13-14: Reserved */ +#define DMA_TCD_CITER_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking on minor-loop complete (Case 1&2) */ + +/* Case 2: Channel Linking Disabled: */ + +#define DMA_TCD_CITER2_SHIFT (0) /* Bits 0-14: Current major iteration count */ +#define DMA_TCD_CITER2_MASK (0x7fff << DMA_TCD_CITER2_SHIFT) + /* Bits 15: Same as Case 1 */ + +/* TCD Last Destination Address Adjustment/Scatter Gather Address. 32-bit address value. */ + +/* TCD Control and Status (16-bit) */ + +#define DMA_TCD_CSR_START (1 << 0) /* Bit 0: Channel start */ +#define DMA_TCD_CSR_INTMAJOR (1 << 1) /* Bit 1: Enable an interrupt when major iteration count completes */ +#define DMA_TCD_CSR_INTHALF (1 << 2) /* Bit 2: Enable an interrupt when major counter is half complete */ +#define DMA_TCD_CSR_DREQ (1 << 3) /* Bit 3: Disable request */ +#define DMA_TCD_CSR_ESG (1 << 4) /* Bit 4: Enable scatter/gather processing */ +#define DMA_TCD_CSR_MAJORELINK (1 << 5) /* Bit 5: Enable channel-to-channel linking on major loop complete */ +#define DMA_TCD_CSR_ACTIVE (1 << 6) /* Bit 6: Channel active */ +#define DMA_TCD_CSR_DONE (1 << 7) /* Bit 7: Channel done */ +#define DMA_TCD_CSR_MAJORLINKCH_SHIFT (8) /* Bits 8-11: Link channel number */ +#define DMA_TCD_CSR_MAJORLINKCH_MASK (15 << DMA_TCD_CSR_MAJORLINKCH_SHIFT) + /* Bits 12-13: Reserved */ +#define DMA_TCD_CSR_BWC_SHIFT (14) /* Bits 14-15: Bandwidth control */ +#define DMA_TCD_CSR_BWC_MASK (3 << DMA_TCD_CSR_BWC_SHIFT) +# define DMA_TCD_CSR_BWC_NOSTALLS (0 << DMA_TCD_CSR_BWC_SHIFT) /* No eDMA engine stalls */ +# define DMA_TCD_CSR_BWC_4CYCLES (2 << DMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls 4 cycles after each R/W */ +# define DMA_TCD_CSR_BWC_8CYCLES (3 << DMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls 8 cycles after each R/W */ + +/* TCD Beginning Minor Loop Link, Major Loop Count (16-bit). + * + * Case 1: Channel Linking Enabled: + */ + +#define DMA_TCD_BITER1_SHIFT (0) /* Bits 0-8: Starting major iteration count */ +#define DMA_TCD_BITER1_MASK (0x1ff << DMA_TCD_BITER1_SHIFT) +#define DMA_TCD_BITER1_LINKCH_SHIFT (9) /* Bits 9-12: Link channel number */ +#define DMA_TCD_BITER1_LINKCH_MASK (15 << DMA_TCD_BITER1_LINKCH_SHIFT) + /* Bits 13-14: Reserved */ +#define DMA_TCD_BITER_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking on minor-loop complete (Case 1&2) */ + +/* Case 2: Channel Linking Disabled: */ + +#define DMA_TCD_BITER2_SHIFT (0) /* Bits 0-14: Starting major iteration count */ +#define DMA_TCD_BITER2_MASK (0x7fff << DMA_TCD_CITER2_SHIFT) + /* Bits 15: Same as Case 1 */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H */ diff --git a/arch/arm/src/kinetis/kinetis_dmamux.h b/arch/arm/src/kinetis/kinetis_dmamux.h new file mode 100644 index 0000000000000000000000000000000000000000..b83579180ea0ca53d2d0b99d55ac6de604ab51e8 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_dmamux.h @@ -0,0 +1,111 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_dmamux.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_DMAMUX_CHCFG_OFFSET(n) (n) /* Channel n Configuration Register */ +#define KINETIS_DMAMUX_CHCFG0_OFFSET 0x0000 /* Channel 0 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG1_OFFSET 0x0001 /* Channel 1 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG2_OFFSET 0x0002 /* Channel 2 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG3_OFFSET 0x0003 /* Channel 3 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG4_OFFSET 0x0004 /* Channel 4 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG5_OFFSET 0x0005 /* Channel 5 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG6_OFFSET 0x0006 /* Channel 6 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG7_OFFSET 0x0007 /* Channel 7 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG8_OFFSET 0x0008 /* Channel 8 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG9_OFFSET 0x0009 /* Channel 9 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG10_OFFSET 0x000a /* Channel 10 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG11_OFFSET 0x000b /* Channel 11 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG12_OFFSET 0x000c /* Channel 12 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG13_OFFSET 0x000d /* Channel 13 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG14_OFFSET 0x000e /* Channel 14 Configuration Register */ +#define KINETIS_DMAMUX_CHCFG15_OFFSET 0x000f /* Channel 15 Configuration Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_DMAMUX_CHCFG(n) (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG_OFFSET(n)) +#define KINETIS_DMAMUX_CHCFG0 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG0_OFFSET) +#define KINETIS_DMAMUX_CHCFG1 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG1_OFFSET) +#define KINETIS_DMAMUX_CHCFG2 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG2_OFFSET) +#define KINETIS_DMAMUX_CHCFG3 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG3_OFFSET) +#define KINETIS_DMAMUX_CHCFG4 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG4_OFFSET) +#define KINETIS_DMAMUX_CHCFG5 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG5_OFFSET) +#define KINETIS_DMAMUX_CHCFG6 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG6_OFFSET) +#define KINETIS_DMAMUX_CHCFG7 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG7_OFFSET) +#define KINETIS_DMAMUX_CHCFG8 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG8_OFFSET) +#define KINETIS_DMAMUX_CHCFG9 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG9_OFFSET) +#define KINETIS_DMAMUX_CHCFG10 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG10_OFFSET) +#define KINETIS_DMAMUX_CHCFG11 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG11_OFFSET) +#define KINETIS_DMAMUX_CHCFG12 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG12_OFFSET) +#define KINETIS_DMAMUX_CHCFG13 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG13_OFFSET) +#define KINETIS_DMAMUX_CHCFG14 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG14_OFFSET) +#define KINETIS_DMAMUX_CHCFG15 (KINETIS_DMAMUX0_BASE+KINETIS_DMAMUX_CHCFG15_OFFSET) + +/* Register Bit Definitions *****************************************************************/ +/* Channel n Configuration Register */ + +#define DMAMUX_CHCFG_SOURCE_SHIFT (0) /* Bits 0-5: DMA Channel Source (slot) */ +#define DMAMUX_CHCFG_SOURCE_MASK (63 << DMAMUX_CHCFG_SOURCE_SHIFT) +#define DMAMUX_CHCFG_TRIG (1 << 6) /* Bit 6: DMA Channel Trigger Enable */ +#define DMAMUX_CHCFG_ENBL (1 << 7) /* Bit 7: DMA Channel Enable */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H */ diff --git a/arch/arm/src/kinetis/kinetis_dspi.h b/arch/arm/src/kinetis/kinetis_dspi.h new file mode 100644 index 0000000000000000000000000000000000000000..e682ef23e8555ab5f706903846579803d7c16e39 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_dspi.h @@ -0,0 +1,321 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_dspi.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETICS_SPI_MCR_OFFSET 0x0000 /* DSPI Module Configuration Register */ +#define KINETICS_SPI_TCR_OFFSET 0x0008 /* DSPI Transfer Count Register */ +#define KINETICS_SPI_CTAR0_OFFSET 0x000c /* DSPI Clock and Transfer Attributes Register */ +#define KINETICS_SPI_CTAR1_OFFSET 0x0010 /* DSPI Clock and Transfer Attributes Register */ +#define KINETICS_SPI_SR_OFFSET 0x002c /* DSPI Status Register */ +#define KINETICS_SPI_RSER_OFFSET 0x0030 /* DSPI DMA/Interrupt Request Select and Enable Register */ +#define KINETICS_SPI_PUSHR_OFFSET 0x0034 /* DSPI PUSH TX FIFO Register */ +#define KINETICS_SPI_POPR_OFFSET 0x0038 /* DSPI POP RX FIFO Register */ +#define KINETICS_SPI_TXFR0_OFFSET 0x003c /* DSPI Transmit FIFO Registers */ +#define KINETICS_SPI_TXFR1_OFFSET 0x0040 /* DSPI Transmit FIFO Registers */ +#define KINETICS_SPI_TXFR2_OFFSET 0x0044 /* DSPI Transmit FIFO Registers */ +#define KINETICS_SPI_TXFR3_OFFSET 0x0048 /* DSPI Transmit FIFO Registers */ +#define KINETICS_SPI_RXFR0_OFFSET 0x007c /* DSPI Receive FIFO Registers */ +#define KINETICS_SPI_RXFR1_OFFSET 0x0080 /* DSPI Receive FIFO Registers */ +#define KINETICS_SPI_RXFR2_OFFSET 0x0084 /* DSPI Receive FIFO Registers */ +#define KINETICS_SPI_RXFR3_OFFSET 0x0088 /* DSPI Receive FIFO Registers */ + +/* Register Addresses ***********************************************************************/ + +#define KINETICS_SPI0_MCR (KINETIS_SPI0_BASE+KINETICS_SPI_MCR_OFFSET) +#define KINETICS_SPI0_TCR (KINETIS_SPI0_BASE+KINETICS_SPI_TCR_OFFSET) +#define KINETICS_SPI0_CTAR0 (KINETIS_SPI0_BASE+KINETICS_SPI_CTAR0_OFFSET) +#define KINETICS_SPI0_CTAR1 (KINETIS_SPI0_BASE+KINETICS_SPI_CTAR1_OFFSET) +#define KINETICS_SPI0_SR (KINETIS_SPI0_BASE+KINETICS_SPI_SR_OFFSET) +#define KINETICS_SPI0_RSER (KINETIS_SPI0_BASE+KINETICS_SPI_RSER_OFFSET) +#define KINETICS_SPI0_PUSHR (KINETIS_SPI0_BASE+KINETICS_SPI_PUSHR_OFFSET) +#define KINETICS_SPI0_POPR (KINETIS_SPI0_BASE+KINETICS_SPI_POPR_OFFSET) +#define KINETICS_SPI0_TXFR0 (KINETIS_SPI0_BASE+KINETICS_SPI_TXFR0_OFFSET) +#define KINETICS_SPI0_TXFR1 (KINETIS_SPI0_BASE+KINETICS_SPI_TXFR1_OFFSET) +#define KINETICS_SPI0_TXFR2 (KINETIS_SPI0_BASE+KINETICS_SPI_TXFR2_OFFSET) +#define KINETICS_SPI0_TXFR3 (KINETIS_SPI0_BASE+KINETICS_SPI_TXFR3_OFFSET) +#define KINETICS_SPI0_RXFR0 (KINETIS_SPI0_BASE+KINETICS_SPI_RXFR0_OFFSET) +#define KINETICS_SPI0_RXFR1 (KINETIS_SPI0_BASE+KINETICS_SPI_RXFR1_OFFSET) +#define KINETICS_SPI0_RXFR2 (KINETIS_SPI0_BASE+KINETICS_SPI_RXFR2_OFFSET) +#define KINETICS_SPI0_RXFR3 (KINETIS_SPI0_BASE+KINETICS_SPI_RXFR3_OFFSET) + +#define KINETICS_SPI1_MCR (KINETIS_SPI1_BASE+KINETICS_SPI_MCR_OFFSET) +#define KINETICS_SPI1_TCR (KINETIS_SPI1_BASE+KINETICS_SPI_TCR_OFFSET) +#define KINETICS_SPI1_CTAR0 (KINETIS_SPI1_BASE+KINETICS_SPI_CTAR0_OFFSET) +#define KINETICS_SPI1_CTAR1 (KINETIS_SPI1_BASE+KINETICS_SPI_CTAR1_OFFSET) +#define KINETICS_SPI1_SR (KINETIS_SPI1_BASE+KINETICS_SPI_SR_OFFSET) +#define KINETICS_SPI1_RSER (KINETIS_SPI1_BASE+KINETICS_SPI_RSER_OFFSET) +#define KINETICS_SPI1_PUSHR (KINETIS_SPI1_BASE+KINETICS_SPI_PUSHR_OFFSET) +#define KINETICS_SPI1_POPR (KINETIS_SPI1_BASE+KINETICS_SPI_POPR_OFFSET) +#define KINETICS_SPI1_TXFR0 (KINETIS_SPI1_BASE+KINETICS_SPI_TXFR0_OFFSET) +#define KINETICS_SPI1_TXFR1 (KINETIS_SPI1_BASE+KINETICS_SPI_TXFR1_OFFSET) +#define KINETICS_SPI1_TXFR2 (KINETIS_SPI1_BASE+KINETICS_SPI_TXFR2_OFFSET) +#define KINETICS_SPI1_TXFR3 (KINETIS_SPI1_BASE+KINETICS_SPI_TXFR3_OFFSET) +#define KINETICS_SPI1_RXFR0 (KINETIS_SPI1_BASE+KINETICS_SPI_RXFR0_OFFSET) +#define KINETICS_SPI1_RXFR1 (KINETIS_SPI1_BASE+KINETICS_SPI_RXFR1_OFFSET) +#define KINETICS_SPI1_RXFR2 (KINETIS_SPI1_BASE+KINETICS_SPI_RXFR2_OFFSET) +#define KINETICS_SPI1_RXFR3 (KINETIS_SPI1_BASE+KINETICS_SPI_RXFR3_OFFSET) + +#define KINETICS_SPI2_MCR (KINETIS_SPI2_BASE+KINETICS_SPI_MCR_OFFSET) +#define KINETICS_SPI2_TCR (KINETIS_SPI2_BASE+KINETICS_SPI_TCR_OFFSET) +#define KINETICS_SPI2_CTAR0 (KINETIS_SPI2_BASE+KINETICS_SPI_CTAR0_OFFSET) +#define KINETICS_SPI2_CTAR1 (KINETIS_SPI2_BASE+KINETICS_SPI_CTAR1_OFFSET) +#define KINETICS_SPI2_SR (KINETIS_SPI2_BASE+KINETICS_SPI_SR_OFFSET) +#define KINETICS_SPI2_RSER (KINETIS_SPI2_BASE+KINETICS_SPI_RSER_OFFSET) +#define KINETICS_SPI2_PUSHR (KINETIS_SPI2_BASE+KINETICS_SPI_PUSHR_OFFSET) +#define KINETICS_SPI2_POPR (KINETIS_SPI2_BASE+KINETICS_SPI_POPR_OFFSET) +#define KINETICS_SPI2_TXFR0 (KINETIS_SPI2_BASE+KINETICS_SPI_TXFR0_OFFSET) +#define KINETICS_SPI2_TXFR1 (KINETIS_SPI2_BASE+KINETICS_SPI_TXFR1_OFFSET) +#define KINETICS_SPI2_TXFR2 (KINETIS_SPI2_BASE+KINETICS_SPI_TXFR2_OFFSET) +#define KINETICS_SPI2_TXFR3 (KINETIS_SPI2_BASE+KINETICS_SPI_TXFR3_OFFSET) +#define KINETICS_SPI2_RXFR0 (KINETIS_SPI2_BASE+KINETICS_SPI_RXFR0_OFFSET) +#define KINETICS_SPI2_RXFR1 (KINETIS_SPI2_BASE+KINETICS_SPI_RXFR1_OFFSET) +#define KINETICS_SPI2_RXFR2 (KINETIS_SPI2_BASE+KINETICS_SPI_RXFR2_OFFSET) +#define KINETICS_SPI2_RXFR3 (KINETIS_SPI2_BASE+KINETICS_SPI_RXFR3_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* DSPI Module Configuration Register */ + +#define SPI_MCR_HALT (1 << 0) /* Bit 0: Halt */ + /* Bits 1-7: Reserved */ +#define SPI_MCR_SMPL_PT_SHIFT (8) /* Bits 8-9: Sample Point */ +#define SPI_MCR_SMPL_PT_MASK (3 << SPI_MCR_SMPL_PT_SHIFT) +# define SPI_MCR_SMPL_PT_0CLKS (0 << SPI_MCR_SMPL_PT_SHIFT) /* 0 clocks between edge and sample */ +# define SPI_MCR_SMPL_PT_1CLKS (1 << SPI_MCR_SMPL_PT_SHIFT) /* 1 clock between edge and sample */ +# define SPI_MCR_SMPL_PT_2CLKS (2 << SPI_MCR_SMPL_PT_SHIFT) /* 2 clocks between edge and sample */ +#define SPI_MCR_CLR_RXF (1 << 10) /* Bit 10: Clear RX FIFO */ +#define SPI_MCR_CLR_TXF (1 << 11) /* Bit 11: Clear TX FIFO */ +#define SPI_MCR_DIS_RXF (1 << 12) /* Bit 12: Disable Receive FIFO */ +#define SPI_MCR_DIS_TXF (1 << 13) /* Bit 13: Disable Transmit FIFO */ +#define SPI_MCR_MDIS (1 << 14) /* Bit 14: Module Disable */ +#define SPI_MCR_DOZE (1 << 15) /* Bit 15: Doze Enable */ +#define SPI_MCR_PCSIS_SHIFT (16) /* Bits 16-21: Peripheral Chip Select x Inactive State */ +#define SPI_MCR_PCSIS_MASK (0x3f << SPI_MCR_PCSIS_SHIFT) +# define SPI_MCR_PCSIS_CS(n) ((1 << (n)) << SPI_MCR_PCSIS_SHIFT) + /* Bits 22–23: Reserved */ +#define SPI_MCR_ROOE (1 << 24) /* Bit 24: Receive FIFO Overflow Overwrite Enable */ +#define SPI_MCR_PCSSE (1 << 25) /* Bit 25: Peripheral Chip Select Strobe Enable */ +#define SPI_MCR_MTFE (1 << 26) /* Bit 26: Modified Timing Format Enable */ +#define SPI_MCR_FRZ (1 << 27) /* Bit 27: Freeze */ +#define SPI_MCR_DCONF_SHIFT (28) /* Bits 28-29: DSPI Configuration */ +#define SPI_MCR_DCONF_MASK (3 << SPI_MCR_DCONF_SHIFT) +# define SPI_MCR_DCONF_SPI (0 << SPI_MCR_DCONF_SHIFT) +#define SPI_MCR_CONT_SCKE (1 << 30) /* Bit 30: Continuous SCK Enable */ +#define SPI_MCR_MSTR (1 << 31) /* Bit 31: Master/Slave Mode Select */ + +/* DSPI Transfer Count Register */ + /* Bits 0-15: Reserved */ +#define SPI_TCR_SPI_TCNT_SHIFT (16) /* Bits 16-31: SPI Transfer Counter */ +#define SPI_TCR_SPI_TCNT_MASK (0xffff << SPI_TCR_SPI_TCNT_SHIFT) + +/* DSPI Clock and Transfer Attributes Register (Common Bits) */ + +#define SPI_CTAR_CPHA (1 << 25) /* Bit 25: Clock Phase */ +#define SPI_CTAR_CPOL (1 << 26) /* Bit 26: Clock Polarity */ + +/* DSPI Clock and Transfer Attributes Register (Master Mode) */ + +#define SPI_CTARM_BR_SHIFT (0) /* Bits 0-3: Baud Rate Scaler */ +#define SPI_CTARM_BR_MASK (15 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_2 (0 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_4 (1 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_6 (2 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_8 (3 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_16 (4 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_32 (5 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_64 (6 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_128 (7 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_256 (8 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_512 (9 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_1024 (10 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_2048 (11 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_4096 (12 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_8192 (13 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_16384 (14 << SPI_CTARM_BR_SHIFT) +# define SPI_CTARM_BR_32768 (15 << SPI_CTARM_BR_SHIFT) +#define SPI_CTARM_DT_SHIFT (4) /* Bits 4-7: Delay After Transfer Scaler */ +#define SPI_CTARM_DT_MASK (15 << SPI_CTARM_DT_SHIFT) +#define SPI_CTARM_ASC_SHIFT (8) /* Bits 8-11: After SCK Delay Scaler */ +#define SPI_CTARM_ASC_MASK (15 << SPI_CTARM_ASC_SHIFT) +#define SPI_CTARM_CSSCK_SHIFT (12) /* Bits 12-15: PCS to SCK Delay Scaler */ +#define SPI_CTARM_CSSCK_MASK (15 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_2 (0 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_4 (1 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_8 (2 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_16 (3 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_32 (4 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_64 (5 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_128 (6 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_256 (7 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_512 (8 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_1024 (9 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_2048 (10 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_4096 (11 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_8192 (12 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_16384 (13 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_32768 (14 << SPI_CTARM_CSSCK_SHIFT) +# define SPI_CTARM_CSSCK_65536 (15 << SPI_CTARM_CSSCK_SHIFT) +#define SPI_CTARM_PBR_SHIFT (16) /* Bits 16-17: Baud Rate Prescaler */ +#define SPI_CTARM_PBR_MASK (3 << SPI_CTARM_PBR_SHIFT) +# define SPI_CTARM_PBR_2 (0 << SPI_CTARM_PBR_SHIFT) +# define SPI_CTARM_PBR_3 (1 << SPI_CTARM_PBR_SHIFT) +# define SPI_CTARM_PBR_5 (2 << SPI_CTARM_PBR_SHIFT) +# define SPI_CTARM_PBR_7 (3 << SPI_CTARM_PBR_SHIFT) +#define SPI_CTARM_PDT_SHIFT (18) /* Bits 18-19: Delay after Transfer Prescaler */ +#define SPI_CTARM_PDT_MASK (3 << SPI_CTARM_PDT_SHIFT) +# define SPI_CTARM_PDT_1 (0 << SPI_CTARM_PDT_SHIFT) +# define SPI_CTARM_PDT_3 (1 << SPI_CTARM_PDT_SHIFT) +# define SPI_CTARM_PDT_5 (2 << SPI_CTARM_PDT_SHIFT) +# define SPI_CTARM_PDT_7 (3 << SPI_CTARM_PDT_SHIFT) +#define SPI_CTARM_PASC_SHIFT (20) /* Bits 20-21: After SCK Delay Prescaler */ +#define SPI_CTARM_PASC_MASK (3 << SPI_CTARM_PASC_SHIFT) +# define SPI_CTARM_PASC_1 (0 << SPI_CTARM_PASC_SHIFT) +# define SPI_CTARM_PASC_3 (1 << SPI_CTARM_PASC_SHIFT) +# define SPI_CTARM_PASC_5 (2 << SPI_CTARM_PASC_SHIFT) +# define SPI_CTARM_PASC_7 (3 << SPI_CTARM_PASC_SHIFT) +#define SPI_CTARM_PCSSCK_SHIFT (22) /* Bits 22-23: PCS to SCK Delay Prescaler */ +#define SPI_CTARM_PCSSCK_MASK (3 << SPI_CTARM_PCSSCK_SHIFT) +# define SPI_CTARM_PCSSCK_1 (0 << SPI_CTARM_PCSSCK_SHIFT) +# define SPI_CTARM_PCSSCK_3 (1 << SPI_CTARM_PCSSCK_SHIFT) +# define SPI_CTARM_PCSSCK_5 (2 << SPI_CTARM_PCSSCK_SHIFT) +# define SPI_CTARM_PCSSCK_7 (3 << SPI_CTARM_PCSSCK_SHIFT) +#define SPI_CTARM_LSBFE (1 << 24) /* Bit 24: LBS First */ + /* Bits 25-26: See common bits above */ +#define SPI_CTARM_FMSZ_SHIFT (27) /* Bits 27-30: Frame Size */ +#define SPI_CTARM_FMSZ_MASK (15 << SPI_CTARM_FMSZ_SHIFT) +#define SPI_CTARM_DBR (1 << 31) /* Bit 31: Double Baud Rate */ + +/* DSPI Clock and Transfer Attributes Register (Slave Mode) */ + /* Bits 0-24: Reserved */ + /* Bits 25-26: See common bits above */ +#define SPI_CTARS_FMSZ_SHIFT (27) /* Bits 27-31: Frame Size */ +#define SPI_CTARS_FMSZ_MASK (31 << SPI_CTARS_FMSZ_SHIFT) + +/* DSPI Status Register */ + +#define SPI_SR_POPNXTPTR_SHIFT (0) /* Bits 0-3: Pop Next Pointer */ +#define SPI_SR_POPNXTPTR_MASK (15 << SPI_SR_POPNXTPTR_SHIFT) +#define SPI_SR_RXCTR_SHIFT (4) /* Bits 4-7: RX FIFO Counter */ +#define SPI_SR_RXCTR_MASK (15 << SPI_SR_RXCTR_SHIFT) +#define SPI_SR_TXNXTPTR_SHIFT (8) /* Bits 8-11: Transmit Next Pointer */ +#define SPI_SR_TXNXTPTR_MASK (15 << SPI_SR_TXNXTPTR_SHIFT) +#define SPI_SR_TXCTR_SHIFT (12) /* Bits 12-15: TX FIFO Counter */ +#define SPI_SR_TXCTR_MASK (15 << SPI_SR_TXCTR_SHIFT) + /* Bit 16: Reserved */ +#define SPI_SR_RFDF (1 << 17) /* Bit 17: Receive FIFO Drain Flag */ + /* Bit 18: Reserved */ +#define SPI_SR_RFOF (1 << 19) /* Bit 19: Receive FIFO Overflow Flag */ + /* Bit 20-24: Reserved */ +#define SPI_SR_TFFF (1 << 25) /* Bit 25: Transmit FIFO Fill Flag */ + /* Bit 26: Reserved */ +#define SPI_SR_TFUF (1 << 27) /* Bit 27: Transmit FIFO Underflow Flag */ +#define SPI_SR_EOQF (1 << 28) /* Bit 28: End of Queue Flag */ + /* Bit 29: Reserved */ +#define SPI_SR_TXRXS (1 << 30) /* Bit 30: TX and RX Status */ +#define SPI_SR_TCF (1 << 31) /* Bit 31: Transfer Complete Flag */ + +/* DSPI DMA/Interrupt Request Select and Enable Register */ + /* Bits 0-15: Reserved */ +#define SPI_RSER_RFDF_DIRS (1 << 16) /* Bit 16: Receive FIFO Drain DMA or Interrupt Request Select */ +#define SPI_RSER_RFDF_RE (1 << 17) /* Bit 17: Receive FIFO Drain Request Enable */ + /* Bit 18: Reserved */ +#define SPI_RSER_RFOF_RE (1 << 19) /* Bit 19: Receive FIFO Overflow Request Enable */ + /* Bit 20-23: Reserved */ +#define SPI_RSER_TFFF_DIRS (1 << 24) /* Bit 24: Transmit FIFO Fill DMA or Interrupt Request Select */ +#define SPI_RSER_TFFF_RE (1 << 25) /* Bit 25: Transmit FIFO Fill Request Enable */ + /* Bit 26: Reserved */ +#define SPI_RSER_TFUF_RE (1 << 27) /* Bit 27: Transmit FIFO Underflow Request Enable */ +#define SPI_RSER_EOQF_RE (1 << 28) /* Bit 28: DSPI Finished Request Enable */ + /* Bits 29-30: Reserved */ +#define SPI_RSER_TCF_RE (1 << 31) /* Bit 31: Transmission Complete Request Enable */ + +/* DSPI PUSH TX FIFO Register (Master Mode)*/ + +#define SPI_PUSHR_TXDATA_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define SPI_PUSHR_TXDATA_MASK (0xffff << SPI_PUSHR_TXDATA_SHIFT) +#define SPI_PUSHR_PCS_SHIFT (16) /* Bits 16-21: Select PCS signals to assert */ +#define SPI_PUSHR_PCS_MASK (0x3f << SPI_PUSHR_PCS_SHIFT) +# define SPI_PUSHR_PCS(n) ((1 << (n)) << SPI_PUSHR_PCS_SHIFT) + /* Bit 22-25: Reserved */ +#define SPI_PUSHR_CTCNT (1 << 26) /* Bit 26: Clear Transfer Counter */ +#define SPI_PUSHR_EOQ (1 << 27) /* Bit 27: End Of Queue */ +#define SPI_PUSHR_CTAS_SHIFT (28) /* Bits 28-30: Clock and Transfer Attributes Select */ +#define SPI_PUSHR_CTAS_MASK (7 << SPI_PUSHR_CTAS_SHIFT) +# define SPI_PUSHR_CTAS_CTAR0 (0 << SPI_PUSHR_CTAS_SHIFT) +# define SPI_PUSHR_CTAS_CTAR1 (1 << SPI_PUSHR_CTAS_SHIFT) +#define SPI_PUSHR_CONT (1 << 31) /* Bit 31: Continuous Peripheral Chip Select Enable */ + +/* DSPI PUSH TX FIFO Register (Slave Mode, 32-bits of RXDATA)*/ + +/* DSPI POP RX FIFO Register (32-bits of RXDATA) */ + +/* DSPI Transmit FIFO Registers */ + +#define SPI_TXFR_TXDATA_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define SPI_TXFR_TXDATA_MASK (0xffff << SPI_TXFR_TXDATA_SHIFT) +#define SPI_TXFR_TXCDATA_SHIFT (16) /* Bits 16-31: Transmit Command or Transmit Data */ +#define SPI_TXFR_TXCDATA_MASK (0xffff << SPI_TXFR_TXCDATA_SHIFT) + +/* DSPI Receive FIFO Registers (32-bits of RXDATA) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H */ diff --git a/arch/arm/src/kinetis/kinetis_enet.c b/arch/arm/src/kinetis/kinetis_enet.c new file mode 100644 index 0000000000000000000000000000000000000000..95e511546ff441ae6d5b9ca11b842b8f7d9bccbb --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_enet.c @@ -0,0 +1,1784 @@ +/**************************************************************************** + * drivers/net/kinetis_enet.c + * + * Copyright (C) 2011-2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_KINETIS_ENET) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "chip.h" +#include "kinetis.h" +#include "kinetis_config.h" +#include "kinetis_pinmux.h" +#include "kinetis_sim.h" +#include "kinetis_mpu.h" +#include "kinetis_enet.h" + +#if defined(KINETIS_NENET) && KINETIS_NENET > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIG_ENET_NETHIFS determines the number of physical interfaces + * that will be supported. + */ + +#if CONFIG_ENET_NETHIFS != 1 +# error "CONFIG_ENET_NETHIFS must be one for now" +#endif + +#if CONFIG_ENET_NTXBUFFERS < 1 +# error "Need at least one TX buffer" +#endif + +#if CONFIG_ENET_NRXBUFFERS < 1 +# error "Need at least one RX buffer" +#endif + +#define NENET_NBUFFERS (CONFIG_ENET_NTXBUFFERS+CONFIG_ENET_NRXBUFFERS) + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER is required in the configuration" +#endif + +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define KINETIS_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define KINETIS_TXTIMEOUT (60*CLK_TCK) +#define MII_MAXPOLLS (0x1ffff) +#define LINK_WAITUS (500*1000) + +/* PHY hardware specifics. This was copied from the FreeScale code examples. + * this is a vendor specific register and bit settings. I really should + * do the research and find out what this really is. + */ + +#define PHY_STATUS (0x1f) +#define PHY_DUPLEX_STATUS (4 << 2) +#define PHY_SPEED_STATUS (1 << 2) + +/* Estimate the hold time to use based on the peripheral (bus) clock: + * + * HOLD_TIME = (2*BUS_FREQ_MHZ)/5 + 1 + * = (BUS_FREQ)/2500000 + 1 + * + * For example, if BUS_FREQ_MHZ=48 (MHz): + * + * HOLD_TIME = 48Mhz, hold time clocks + * = 48000000/2500000 + 1 + * = 20 + */ + +#define KINETIS_MII_SPEED (BOARD_BUS_FREQ/2500000 + 1) +#if KINETIS_MII_SPEED > 63 +# error "KINETIS_MII_SPEED is out-of-range" +#endif + +/* Interrupt groups */ + +#define RX_INTERRUPTS (ENET_INT_RXF | ENET_INT_RXB) +#define TX_INTERRUPTS ENET_INT_TXF +#define ERROR_INTERRUPTS (ENET_INT_UN | ENET_INT_RL | ENET_INT_LC | \ + ENET_INT_EBERR | ENET_INT_BABT | ENET_INT_BABR) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +#define KINETIS_BUF_SIZE ((CONFIG_NET_ETH_MTU & 0xfffffff0) + 0x10) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* The kinetis_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct kinetis_driver_s +{ + bool bifup; /* true:ifup false:ifdown */ + uint8_t txtail; /* The oldest busy TX descriptor */ + uint8_t txhead; /* The next TX descriptor to use */ + uint8_t rxtail; /* The next RX descriptor to use */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ + struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */ + struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* The DMA descriptors. A unaligned uint8_t is used to allocate the + * memory; 16 is added to assure that we can meet the descriptor alignment + * requirements. + */ + + uint8_t desc[NENET_NBUFFERS * sizeof(struct enet_desc_s) + 16]; + + /* The DMA buffers. Again, A unaligned uint8_t is used to allocate the + * memory; 16 is added to assure that we can meet the descriptor alignment + * requirements. + */ + + uint8_t buffers[NENET_NBUFFERS * KINETIS_BUF_SIZE + 16]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct kinetis_driver_s g_enet[CONFIG_ENET_NETHIFS]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Utility functions */ + +#ifndef KINETIS_BUFFERS_SWAP +# define kinesis_swap32(value) (value) +# define kinesis_swap16(value) (value) +#else +#if 0 /* Use builtins if the compiler supports them */ +static inline uint32_t kinesis_swap32(uint32_t value); +static inline uint16_t kinesis_swap16(uint16_t value); +#else +# define kinesis_swap32 __builtin_bswap32 +# define kinesis_swap16 __builtin_bswap16 +#endif +#endif + +/* Common TX logic */ + +static bool kinetics_txringfull(FAR struct kinetis_driver_s *priv); +static int kinetis_transmit(FAR struct kinetis_driver_s *priv); +static int kinetis_txpoll(struct net_driver_s *dev); + +/* Interrupt handling */ + +static void kinetis_receive(FAR struct kinetis_driver_s *priv); +static void kinetis_txdone(FAR struct kinetis_driver_s *priv); +static int kinetis_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static void kinetis_polltimer(int argc, uint32_t arg, ...); +static void kinetis_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int kinetis_ifup(struct net_driver_s *dev); +static int kinetis_ifdown(struct net_driver_s *dev); +static int kinetis_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int kinetis_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int kinetis_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY/MII support */ + +static inline void kinetis_initmii(struct kinetis_driver_s *priv); +static inline void kinetis_initphy(struct kinetis_driver_s *priv); + +/* Initialization */ + +static void kinetis_initbuffers(struct kinetis_driver_s *priv); +static void kinetis_reset(struct kinetis_driver_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: kinetis_swap16/32 + * + * Description: + * The descriptors are represented by structures Unfortunately, when the + * structures are overlayed on the data, the bytes are reversed because + * the underlying hardware writes the data in big-endian byte order. + * + * Parameters: + * value - The value to be byte swapped + * + * Returned Value: + * The byte swapped value + * + ****************************************************************************/ + +#if 0 /* Use builtins if the compiler supports them */ +#ifndef CONFIG_ENDIAN_BIG +static inline uint32_t kinesis_swap32(uint32_t value) +{ + uint32_t result = 0; + + __asm__ __volatile__ + ( + "rev %0, %1" + :"=r" (result) + : "r"(value) + ); + return result; +} + +static inline uint16_t kinesis_swap16(uint16_t value) +{ + uint16_t result = 0; + + __asm__ __volatile__ + ( + "revsh %0, %1" + :"=r" (result) + : "r"(value) + ); + return result; +} +#endif +#endif + +/**************************************************************************** + * Function: kinetics_txringfull + * + * Description: + * Check if all of the TX descriptors are in use. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * true is the TX ring is full; false if there are free slots at the + * head index. + * + ****************************************************************************/ + +static bool kinetics_txringfull(FAR struct kinetis_driver_s *priv) +{ + uint8_t txnext; + + /* Check if there is room in the hardware to hold another outgoing + * packet. The ring is full if incrementing the head pointer would + * collide with the tail pointer. + */ + + txnext = priv->txhead + 1; + if (txnext >= CONFIG_ENET_NTXBUFFERS) + { + txnext = 0; + } + + return priv->txtail == txnext; +} + +/**************************************************************************** + * Function: kinetis_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int kinetis_transmit(FAR struct kinetis_driver_s *priv) +{ + struct enet_desc_s *txdesc; + uint32_t regval; + uint8_t *buf; + + /* Since this can be called from kinetis_receive, it is possible that + * the transmit queue is full, so check for that now. If this is the + * case, the outgoing packet will be dropped (e.g. an ARP reply) + */ + + if (kinetics_txringfull(priv)) + { + return -EBUSY; + } + + /* When we get here the TX descriptor should show that the previous + * transfer has completed. If we get here, then we are committed to + * sending a packet; Higher level logic must have assured that there is + * no transmission in progress. + */ + + txdesc = &priv->txdesc[priv->txhead]; + priv->txhead++; + if (priv->txhead >= CONFIG_ENET_NTXBUFFERS) + { + priv->txhead = 0; + } + + DEBUGASSERT(priv->txtail != priv->txhead && + (txdesc->status1 & TXDESC_R) == 0); + + /* Increment statistics */ + + NETDEV_TXPACKETS(&priv->dev); + + /* Setup the buffer descriptor for transmission: address=priv->dev.d_buf, + * length=priv->dev.d_len + */ + + txdesc->length = kinesis_swap16(priv->dev.d_len); +#ifdef CONFIG_ENET_ENHANCEDBD + txdesc->bdu = 0x00000000; + txdesc->status2 = TXDESC_INT | TXDESC_TS; /* | TXDESC_IINS | TXDESC_PINS; */ +#endif + txdesc->status1 |= (TXDESC_R | TXDESC_L | TXDESC_TC); + + buf = (uint8_t*)kinesis_swap32((uint32_t)priv->dev.d_buf); + if (priv->rxdesc[priv->rxtail].data == buf) + { + struct enet_desc_s *rxdesc = &priv->rxdesc[priv->rxtail]; + + /* Data was written into the RX buffer, so swap the TX and RX buffers */ + + DEBUGASSERT((rxdesc->status1 & RXDESC_E) == 0); + rxdesc->data = txdesc->data; + txdesc->data = buf; + } + else + { + ASSERT(txdesc->data == buf); + } + + /* Start the TX transfer (if it was not already waiting for buffers) */ + + putreg32(ENET_TDAR, KINETIS_ENET_TDAR); + + /* Enable TX interrupts */ + + regval = getreg32(KINETIS_ENET_EIMR); + regval |= TX_INTERRUPTS; + putreg32(regval, KINETIS_ENET_EIMR); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout, 1, + (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: kinetis_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int kinetis_txpoll(struct net_driver_s *dev) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + kinetis_transmit(priv); + priv->dev.d_buf = + (uint8_t*)kinesis_swap32((uint32_t)priv->txdesc[priv->txhead].data); + + /* Check if there is room in the device to hold another packet. If not, + * return a non-zero value to terminate the poll. + */ + + if (kinetics_txringfull(priv)) + { + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: kinetis_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void kinetis_receive(FAR struct kinetis_driver_s *priv) +{ + /* Loop while there are received packets to be processed */ + + while ((priv->rxdesc[priv->rxtail].status1 & RXDESC_E) == 0) + { + /* Update statistics */ + + NETDEV_RXPACKETS(&priv->dev); + + /* Copy the buffer pointer to priv->dev.d_buf. Set amount of data in + * priv->dev.d_len + */ + + priv->dev.d_len = kinesis_swap16(priv->rxdesc[priv->rxtail].length); + priv->dev.d_buf = + (uint8_t *)kinesis_swap32((uint32_t)priv->rxdesc[priv->rxtail].data); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + kinetis_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + kinetis_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + NETDEV_RXARP(&priv->dev); + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should + * be sent out on the network, the field d_len will set to a + * value > 0. + */ + + if (priv->dev.d_len > 0) + { + kinetis_transmit(priv); + } + } +#endif + else + { + NETDEV_RXDROPPED(&priv->dev); + } + + /* Point the packet buffer back to the next TX buffer, which will be used during + * the next write. If the write queue is full, then this will point at an active + * buffer, which must not be written to. This is OK because devif_poll won't be + * called unless the queue is not full. + */ + + priv->dev.d_buf = + (uint8_t*)kinesis_swap32((uint32_t)priv->txdesc[priv->txhead].data); + priv->rxdesc[priv->rxtail].status1 |= RXDESC_E; + + /* Update the index to the next descriptor */ + + priv->rxtail++; + if (priv->rxtail >= CONFIG_ENET_NRXBUFFERS) + { + priv->rxtail = 0; + } + + /* Indicate that there have been empty receive buffers produced */ + + putreg32(ENET_RDAR, KINETIS_ENET_RDAR); + } +} + +/**************************************************************************** + * Function: kinetis_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void kinetis_txdone(FAR struct kinetis_driver_s *priv) +{ + uint32_t regval; + + /* Verify that the oldest descriptor descriptor completed */ + + while (((priv->txdesc[priv->txtail].status1 & TXDESC_R) == 0) && + (priv->txtail != priv->txhead)) + { + /* Yes.. bump up the tail pointer, making space for a new TX descriptor */ + + priv->txtail++; + if (priv->txtail >= CONFIG_ENET_NTXBUFFERS) + { + priv->txtail = 0; + } + + /* Update statistics */ + + NETDEV_TXDONE(&priv->dev); + } + + /* Are there other transmissions queued? */ + + if (priv->txtail == priv->txhead) + { + /* No.. Cancel the TX timeout and disable further Tx interrupts. */ + + wd_cancel(priv->txtimeout); + + regval = getreg32(KINETIS_ENET_EIMR); + regval &= ~TX_INTERRUPTS; + putreg32(regval, KINETIS_ENET_EIMR); + } + + /* There should be space for a new TX in any event. Poll uIP for new XMIT + * data + */ + + (void)devif_poll(&priv->dev, kinetis_txpoll); +} + +/**************************************************************************** + * Function: kinetis_interrupt + * + * Description: + * Three interrupt sources will vector this this function: + * 1. Ethernet MAC transmit interrupt handler + * 2. Ethernet MAC receive interrupt handler + * 3. + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int kinetis_interrupt(int irq, FAR void *context) +{ + register FAR struct kinetis_driver_s *priv = &g_enet[0]; + uint32_t pending; + + /* Get the set of unmasked, pending interrupt. */ + + pending = getreg32(KINETIS_ENET_EIR) & getreg32(KINETIS_ENET_EIMR); + + /* Clear the pending interrupts */ + + putreg32(pending, KINETIS_ENET_EIR); + + /* Check for the receipt of a packet */ + + if ((pending & ENET_INT_RXF) != 0) + { + /* A packet has been received, call kinetis_receive() to handle the + * packet. + */ + + kinetis_receive(priv); + } + + /* Check if a packet transmission has completed */ + + if ((pending & ENET_INT_TXF) != 0) + { + /* Call kinetis_txdone to handle the end of transfer even. NOTE that + * this may disable further Tx interrupts if there are no pending + * tansmissions. + */ + + kinetis_txdone(priv); + } + + /* Check for errors */ + + if (pending & ERROR_INTERRUPTS) + { + /* An error has occurred, update statistics */ + + NETDEV_ERRORS(&priv->dev); + + /* Reinitialize all buffers. */ + + kinetis_initbuffers(priv); + + /* Indicate that there have been empty receive buffers produced */ + + putreg32(ENET_RDAR, KINETIS_ENET_RDAR); + } + + return OK; +} + +/**************************************************************************** + * Function: kinetis_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void kinetis_txtimeout(int argc, uint32_t arg, ...) +{ + FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg; + + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(&priv->dev); + + /* Take the interface down and bring it back up. The is the most agressive + * hardware reset. + */ + + (void)kinetis_ifdown(&priv->dev); + (void)kinetis_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->dev, kinetis_txpoll); +} + +/**************************************************************************** + * Function: kinetis_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void kinetis_polltimer(int argc, uint32_t arg, ...) +{ + FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg; + + /* Check if there is there is a transmission in progress. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ + + if (!kinetics_txringfull(priv)) + { + /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. + * might be bug here. Does this mean if there is a transmit in progress, + * we will missing TCP time state updates? + */ + + (void)devif_timer(&priv->dev, kinetis_txpoll); + } + + /* Setup the watchdog poll timer again in any case */ + + (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: kinetis_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int kinetis_ifup(struct net_driver_s *dev) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + uint8_t *mac = dev->d_mac.ether_addr_octet; + uint32_t regval; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Initialize ENET buffers */ + + kinetis_initbuffers(priv); + + /* Reset and disable the interface */ + + kinetis_reset(priv); + + /* Configure the MII interface */ + + kinetis_initmii(priv); + + /* Set the MAC address */ + + putreg32((mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3], + KINETIS_ENET_PALR); + putreg32((mac[4] << 24) | (mac[5] << 16), KINETIS_ENET_PAUR); + + /* Clear the Individual and Group Address Hash registers */ + + putreg32(0, KINETIS_ENET_IALR); + putreg32(0, KINETIS_ENET_IAUR); + putreg32(0, KINETIS_ENET_GALR); + putreg32(0, KINETIS_ENET_GAUR); + + /* Configure the PHY */ + + kinetis_initphy(priv); + + /* Handle promiscuous mode */ + +#ifdef CONFIG_NET_PROMISCUOUS + regval = getreg32(KINETIS_ENET_RCR); + regval |= ENET_RCR_PROM; + putreg32(regval, KINETIS_ENET_RCR); +#endif + + /* Select legacy of enhanced buffer descriptor format */ + +#ifdef CONFIG_ENET_ENHANCEDBD + putreg32(ENET_ECR_EN1588, KINETIS_ENET_ECR); +#else + putreg32(0, KINETIS_ENET_ECR); +#endif + + /* Set the RX buffer size */ + + putreg32(KINETIS_BUF_SIZE, KINETIS_ENET_MRBR); + + /* Point to the start of the circular RX buffer descriptor queue */ + + putreg32((uint32_t)priv->rxdesc, KINETIS_ENET_RDSR); + + /* Point to the start of the circular TX buffer descriptor queue */ + + putreg32((uint32_t)priv->txdesc, KINETIS_ENET_TDSR); + + /* And enable the MAC itself */ + + regval = getreg32(KINETIS_ENET_ECR); + regval |= ENET_ECR_ETHEREN +#ifdef KINETIS_USE_DBSWAP + | ENET_ECR_DBSWP +#endif + ; + putreg32(regval, KINETIS_ENET_ECR); + + /* Indicate that there have been empty receive buffers produced */ + + putreg32(ENET_RDAR, KINETIS_ENET_RDAR); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, + (uint32_t)priv); + + /* Clear all pending ENET interrupt */ + + putreg32(0xffffffff, KINETIS_ENET_EIR); + + /* Enable RX and error interrupts at the controller (TX interrupts are + * still disabled). + */ + + putreg32(RX_INTERRUPTS | ERROR_INTERRUPTS, + KINETIS_ENET_EIMR); + + /* Mark the interrupt "up" and enable interrupts at the NVIC */ + + priv->bifup = true; +#if 0 + up_enable_irq(KINETIS_IRQ_EMACTMR); +#endif + up_enable_irq(KINETIS_IRQ_EMACTX); + up_enable_irq(KINETIS_IRQ_EMACRX); + up_enable_irq(KINETIS_IRQ_EMACMISC); + return OK; +} + +/**************************************************************************** + * Function: kinetis_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int kinetis_ifdown(struct net_driver_s *dev) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupts at the NVIC */ + + flags = enter_critical_section(); + up_disable_irq(KINETIS_IRQ_EMACTMR); + up_disable_irq(KINETIS_IRQ_EMACTX); + up_disable_irq(KINETIS_IRQ_EMACRX); + up_disable_irq(KINETIS_IRQ_EMACMISC); + putreg32(0, KINETIS_ENET_EIMR); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the kinetis_ifup() always + * successfully brings the interface back up. + */ + + kinetis_reset(priv); + + /* Mark the device "down" */ + + priv->bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: kinetis_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int kinetis_txavail(struct net_driver_s *dev) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->bifup) + { + /* Check if there is room in the hardware to hold another outgoing + * packet. + */ + + if (!kinetics_txringfull(priv)) + { + /* No, there is space for another transfer. Poll uIP for new + * XMIT data. + */ + + (void)devif_poll(&priv->dev, kinetis_txpoll); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: kinetis_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int kinetis_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + + return OK; +} +#endif + +/**************************************************************************** + * Function: kinetis_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int kinetis_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + + UNUSED(priv); + return OK; +} +#endif + +/**************************************************************************** + * Function: kinetis_ioctl + * + * Description: + * PHY ioctl command handler + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * cmd - ioctl command + * arg - Argument accompanying the command + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + int ret; + FAR struct kinetis_driver_s *priv = + (FAR struct kinetis_driver_s *)dev->d_private; + + switch (cmd) + { + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = CONFIG_ENET_PHYADDR; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = kinetis_readmii(priv, req->phy_id, req->reg_num, &req->val_out); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = kinetis_writemii(priv, req->phy_id, req->reg_num, req->val_in); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: kinetis_initmii + * + * Description: + * Configure the MII interface + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void kinetis_initmii(struct kinetis_driver_s *priv) +{ + /* Speed is based on the peripheral (bus) clock; hold time is 1 module + * clock. This hold time value may need to be increased on some platforms + */ + + putreg32(ENET_MSCR_HOLDTIME_1CYCLE | + KINETIS_MII_SPEED << ENET_MSCR_MII_SPEED_SHIFT, + KINETIS_ENET_MSCR); +} + +/**************************************************************************** + * Function: kinetis_writemii + * + * Description: + * Write a 16-bit value to a PHY register. + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * phyaddr - The PHY address + * regaddr - The PHY register address + * data - The data to write to the PHY register + * + * Returned Value: + * Zero on success, a negated errno value on failure. + * + ****************************************************************************/ + +static int kinetis_writemii(struct kinetis_driver_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t data) +{ + int timeout; + + /* Clear the MII interrupt bit */ + + putreg32(ENET_INT_MII, KINETIS_ENET_EIR); + + /* Initiatate the MII Management write */ + + putreg32(data | + 2 << ENET_MMFR_TA_SHIFT | + (uint32_t)regaddr << ENET_MMFR_RA_SHIFT | + (uint32_t)phyaddr << ENET_MMFR_PA_SHIFT | + ENET_MMFR_OP_WRMII | + 1 << ENET_MMFR_ST_SHIFT, + KINETIS_ENET_MMFR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < MII_MAXPOLLS; timeout++) + { + if ((getreg32(KINETIS_ENET_EIR) & ENET_INT_MII) != 0) + { + break; + } + } + + /* Check for a timeout */ + + if (timeout == MII_MAXPOLLS) + { + return -ETIMEDOUT; + } + + /* Clear the MII interrupt bit */ + + putreg32(ENET_INT_MII, KINETIS_ENET_EIR); + return OK; +} + +/**************************************************************************** + * Function: kinetis_writemii + * + * Description: + * Read a 16-bit value from a PHY register. + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * phyaddr - The PHY address + * regaddr - The PHY register address + * data - A pointer to the location to return the data + * + * Returned Value: + * Zero on success, a negated errno value on failure. + * + ****************************************************************************/ + +static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *data) +{ + int timeout; + + /* Clear the MII interrupt bit */ + + putreg32(ENET_INT_MII, KINETIS_ENET_EIR); + + /* Initiatate the MII Management read */ + + putreg32(2 << ENET_MMFR_TA_SHIFT | + (uint32_t)regaddr << ENET_MMFR_RA_SHIFT | + (uint32_t)phyaddr << ENET_MMFR_PA_SHIFT | + ENET_MMFR_OP_RDMII | + 1 << ENET_MMFR_ST_SHIFT, + KINETIS_ENET_MMFR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < MII_MAXPOLLS; timeout++) + { + if ((getreg32(KINETIS_ENET_EIR) & ENET_INT_MII) != 0) + { + break; + } + } + + /* Check for a timeout */ + + if (timeout >= MII_MAXPOLLS) + { + return -ETIMEDOUT; + } + + /* Clear the MII interrupt bit */ + + putreg32(ENET_INT_MII, KINETIS_ENET_EIR); + + /* And return the MII data */ + + *data = (uint16_t)(getreg32(KINETIS_ENET_MMFR) & ENET_MMFR_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: kinetis_initphy + * + * Description: + * Configure the PHY + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void kinetis_initphy(struct kinetis_driver_s *priv) +{ + uint32_t rcr; + uint32_t tcr; + uint16_t phydata; + + /* Loop (potentially infinitely?) until we successfully communicate with + * the PHY. + */ + + do + { + usleep(LINK_WAITUS); + phydata = 0xffff; + kinetis_readmii(priv, CONFIG_ENET_PHYADDR, MII_PHYID1, &phydata); + } + while (phydata == 0xffff); + + /* Start auto negotiation */ + + kinetis_writemii(priv, CONFIG_ENET_PHYADDR, MII_MCR, + (MII_MCR_ANRESTART | MII_MCR_ANENABLE)); + + /* Wait (potentially forever) for auto negotiation to complete */ + + do + { + usleep(LINK_WAITUS); + kinetis_readmii(priv, CONFIG_ENET_PHYADDR, MII_MSR, &phydata); + + } + while ((phydata & MII_MSR_ANEGCOMPLETE) == 0); + + /* When we get here we have a link - Find the negotiated speed and duplex. */ + + phydata = 0; + kinetis_readmii(priv, CONFIG_ENET_PHYADDR, PHY_STATUS, &phydata); + + /* Set up the transmit and receive contrel registers based on the + * configuration and the auto negotiation results. + */ + +#ifdef CONFIG_ENET_USEMII + rcr = ENET_RCR_MII_MODE | ENET_RCR_CRCFWD | + CONFIG_NET_ETH_MTU << ENET_RCR_MAX_FL_SHIFT | + ENET_RCR_MII_MODE; +#else + rcr = ENET_RCR_RMII_MODE | ENET_RCR_CRCFWD | + CONFIG_NET_ETH_MTU << ENET_RCR_MAX_FL_SHIFT | + ENET_RCR_MII_MODE; +#endif + tcr = 0; + + putreg32(rcr, KINETIS_ENET_RCR); + putreg32(tcr, KINETIS_ENET_TCR); + + /* Setup half or full duplex */ + + if ((phydata & PHY_DUPLEX_STATUS) != 0) + { + /* Full duplex */ + + tcr |= ENET_TCR_FDEN; + } + else + { + /* Half duplex */ + + rcr |= ENET_RCR_DRT; + } + + if ((phydata & PHY_SPEED_STATUS) != 0) + { + /* 10Mbps */ + + rcr |= ENET_RCR_RMII_10T; + } + + putreg32(rcr, KINETIS_ENET_RCR); + putreg32(tcr, KINETIS_ENET_TCR); +} + +/**************************************************************************** + * Function: kinetis_initbuffers + * + * Description: + * Initialize ENET buffers and descriptors + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void kinetis_initbuffers(struct kinetis_driver_s *priv) +{ + uintptr_t addr; + int i; + + /* Get an aligned TX descriptor (array)address */ + + addr = ((uintptr_t)priv->desc + 0x0f) & ~0x0f; + priv->txdesc = (struct enet_desc_s *)addr; + + /* Get an aligned RX descriptor (array) address */ + + addr += CONFIG_ENET_NTXBUFFERS * sizeof(struct enet_desc_s); + priv->rxdesc = (struct enet_desc_s *)addr; + + /* Get the beginning of the first aligned buffer */ + + addr = ((uintptr_t)priv->buffers + 0x0f) & ~0x0f; + + /* Then fill in the TX descriptors */ + + for (i = 0; i < CONFIG_ENET_NTXBUFFERS; i++) + { + priv->txdesc[i].status1 = 0; + priv->txdesc[i].length = 0; + priv->txdesc[i].data = (uint8_t *)kinesis_swap32((uint32_t)addr); +#ifdef CONFIG_ENET_ENHANCEDBD + priv->txdesc[i].status2 = TXDESC_IINS | TXDESC_PINS; +#endif + addr += KINETIS_BUF_SIZE; + } + + /* Then fill in the RX descriptors */ + + for (i = 0; i < CONFIG_ENET_NRXBUFFERS; i++) + { + priv->rxdesc[i].status1 = RXDESC_E; + priv->rxdesc[i].length = 0; + priv->rxdesc[i].data = (uint8_t *)kinesis_swap32((uint32_t)addr); +#ifdef CONFIG_ENET_ENHANCEDBD + priv->rxdesc[i].bdu = 0; + priv->rxdesc[i].status2 = RXDESC_INT; +#endif + addr += KINETIS_BUF_SIZE; + } + + /* Set the wrap bit in the last descriptors to form a ring */ + + priv->txdesc[CONFIG_ENET_NTXBUFFERS-1].status1 |= TXDESC_W; + priv->rxdesc[CONFIG_ENET_NRXBUFFERS-1].status1 |= RXDESC_W; + + /* We start with RX descriptor 0 and with no TX descriptors in use */ + + priv->txtail = 0; + priv->txhead = 0; + priv->rxtail = 0; + + /* Initialize the packet buffer, which is used when sending */ + + priv->dev.d_buf = + (uint8_t*)kinesis_swap32((uint32_t)priv->txdesc[priv->txhead].data); +} + +/**************************************************************************** + * Function: kinetis_reset + * + * Description: + * Put the EMAC in the non-operational, reset state + * + * Parameters: + * priv - Reference to the private ENET driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void kinetis_reset(struct kinetis_driver_s *priv) +{ + unsigned int i; + + /* Set the reset bit and clear the enable bit */ + + putreg32(ENET_ECR_RESET, KINETIS_ENET_ECR); + + /* Wait at least 8 clock cycles */ + + for (i = 0; i < 10; i++) + { + asm volatile ("nop"); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: kinetis_netinitialize + * + * Description: + * Initialize the Ethernet controller and driver + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int kinetis_netinitialize(int intf) +{ + struct kinetis_driver_s *priv; + uint32_t regval; + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(intf < CONFIG_ENET_NETHIFS); + priv = &g_enet[intf]; + + /* Enable the ENET clock */ + + regval = getreg32(KINETIS_SIM_SCGC2); + regval |= SIM_SCGC2_ENET; + putreg32(regval, KINETIS_SIM_SCGC2); + + /* Allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, + * otherwise a bus error will result. + */ + + putreg32(0, KINETIS_MPU_CESR); + + /* Configure all ENET/MII pins */ + +#ifdef CONFIG_ENET_USEMII + kinetis_pinconfig(PIN_MII0_MDIO); + kinetis_pinconfig(PIN_MII0_MDC); + kinetis_pinconfig(PIN_MII0_RXDV); + kinetis_pinconfig(PIN_MII0_RXER); + kinetis_pinconfig(PIN_MII0_TXER); + kinetis_pinconfig(PIN_MII0_RXD0); + kinetis_pinconfig(PIN_MII0_RXD1); + kinetis_pinconfig(PIN_MII0_RXD2); + kinetis_pinconfig(PIN_MII0_RXD3); + kinetis_pinconfig(PIN_MII0_TXD0); + kinetis_pinconfig(PIN_MII0_TXD1); + kinetis_pinconfig(PIN_MII0_TXD3); + kinetis_pinconfig(PIN_MII0_TXD2); + kinetis_pinconfig(PIN_MII0_TXEN); + kinetis_pinconfig(PIN_MII0_RXCLK); + kinetis_pinconfig(PIN_MII0_TXCLK); + kinetis_pinconfig(PIN_MII0_CRS); + kinetis_pinconfig(PIN_MII0_COL); +#else + kinetis_pinconfig(PIN_RMII0_MDIO); + kinetis_pinconfig(PIN_RMII0_MDC); + kinetis_pinconfig(PIN_RMII0_CRS_DV); + kinetis_pinconfig(PIN_RMII0_RXER); + kinetis_pinconfig(PIN_RMII0_RXD0); + kinetis_pinconfig(PIN_RMII0_RXD1); + kinetis_pinconfig(PIN_RMII0_TXD0); + kinetis_pinconfig(PIN_RMII0_TXD1); + kinetis_pinconfig(PIN_RMII0_TXEN); +#endif + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set interrupt priority levels */ + + up_prioritize_irq(KINETIS_IRQ_EMACTMR, CONFIG_KINETIS_EMACTMR_PRIO); + up_prioritize_irq(KINETIS_IRQ_EMACTX, CONFIG_KINETIS_EMACTX_PRIO); + up_prioritize_irq(KINETIS_IRQ_EMACRX, CONFIG_KINETIS_EMACRX_PRIO); + up_prioritize_irq(KINETIS_IRQ_EMACMISC, CONFIG_KINETIS_EMACMISC_PRIO); +#endif + + /* Attach the Ethernet MAC IEEE 1588 timer interrupt handler */ + +#if 0 + if (irq_attach(KINETIS_IRQ_EMACTMR, kinetis_tmrinterrupt)) + { + /* We could not attach the ISR to the interrupt */ + + ndbg("Failed to attach EMACTMR IRQ\n"); + return -EAGAIN; + } +#endif + + /* Attach the Ethernet MAC transmit interrupt handler */ + + if (irq_attach(KINETIS_IRQ_EMACTX, kinetis_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + ndbg("Failed to attach EMACTX IRQ\n"); + return -EAGAIN; + } + + /* Attach the Ethernet MAC receive interrupt handler */ + + if (irq_attach(KINETIS_IRQ_EMACRX, kinetis_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + ndbg("Failed to attach EMACRX IRQ\n"); + return -EAGAIN; + } + + /* Attach the Ethernet MAC error and misc interrupt handler */ + + if (irq_attach(KINETIS_IRQ_EMACMISC, kinetis_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + ndbg("Failed to attach EMACMISC IRQ\n"); + return -EAGAIN; + } + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct kinetis_driver_s)); + priv->dev.d_ifup = kinetis_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = kinetis_ifdown; /* I/F down callback */ + priv->dev.d_txavail = kinetis_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = kinetis_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = kinetis_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = kinetis_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)g_enet; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Put the interface in the down state. This usually amounts to resetting + * the device and/or calling kinetis_ifdown(). + */ + + (void)kinetis_ifdown(&priv->dev); + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one + * interface in the chip, then board-specific logic will have to provide + * this function to determine which, if any, Ethernet controllers should + * be initialized. + * + ****************************************************************************/ + +#if CONFIG_ENET_NETHIFS == 1 +void up_netinitialize(void) +{ + (void)kinetis_netinitialize(0); +} +#endif + +#endif /* KINETIS_NENET > 0 */ +#endif /* CONFIG_NET && CONFIG_KINETIS_ENET */ diff --git a/arch/arm/src/kinetis/kinetis_enet.h b/arch/arm/src/kinetis/kinetis_enet.h new file mode 100644 index 0000000000000000000000000000000000000000..cadd006d8ce114644b37fc9a77b5c2cb87dd67f3 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_enet.h @@ -0,0 +1,652 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_enet.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(KINETIS_NENET) && KINETIS_NENET > 0 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_ENET_EIR_OFFSET 0x0004 /* Interrupt Event Register */ +#define KINETIS_ENET_EIMR_OFFSET 0x0008 /* Interrupt Mask Register */ +#define KINETIS_ENET_RDAR_OFFSET 0x0010 /* Receive Descriptor Active Register */ +#define KINETIS_ENET_TDAR_OFFSET 0x0014 /* Transmit Descriptor Active Register */ +#define KINETIS_ENET_ECR_OFFSET 0x0024 /* Ethernet Control Register */ +#define KINETIS_ENET_MMFR_OFFSET 0x0040 /* MII Management Frame Register */ +#define KINETIS_ENET_MSCR_OFFSET 0x0044 /* MII Speed Control Register */ +#define KINETIS_ENET_MIBC_OFFSET 0x0064 /* MIB Control Register */ +#define KINETIS_ENET_RCR_OFFSET 0x0084 /* Receive Control Register */ +#define KINETIS_ENET_TCR_OFFSET 0x00c4 /* Transmit Control Register */ +#define KINETIS_ENET_PALR_OFFSET 0x00e4 /* Physical Address Lower Register */ +#define KINETIS_ENET_PAUR_OFFSET 0x00e8 /* Physical Address Upper Register */ +#define KINETIS_ENET_OPD_OFFSET 0x00ec /* Opcode/Pause Duration Register */ +#define KINETIS_ENET_IAUR_OFFSET 0x0118 /* Descriptor Individual Upper Address Register */ +#define KINETIS_ENET_IALR_OFFSET 0x011c /* Descriptor Individual Lower Address Register */ +#define KINETIS_ENET_GAUR_OFFSET 0x0120 /* Descriptor Group Upper Address Register */ +#define KINETIS_ENET_GALR_OFFSET 0x0124 /* Descriptor Group Lower Address Register */ +#define KINETIS_ENET_TFWR_OFFSET 0x0144 /* Transmit FIFO Watermark Register */ +#define KINETIS_ENET_RDSR_OFFSET 0x0180 /* Receive Descriptor Ring Start Register */ +#define KINETIS_ENET_TDSR_OFFSET 0x0184 /* Transmit Buffer Descriptor Ring Start Register */ +#define KINETIS_ENET_MRBR_OFFSET 0x0188 /* Maximum Receive Buffer Size Register */ +#define KINETIS_ENET_RSFL_OFFSET 0x0190 /* Receive FIFO Section Full Threshold */ +#define KINETIS_ENET_RSEM_OFFSET 0x0194 /* Receive FIFO Section Empty Threshold */ +#define KINETIS_ENET_RAEM_OFFSET 0x0198 /* Receive FIFO Almost Empty Threshold */ +#define KINETIS_ENET_RAFL_OFFSET 0x019c /* Receive FIFO Almost Full Threshold */ +#define KINETIS_ENET_TSEM_OFFSET 0x01a0 /* Transmit FIFO Section Empty Threshold */ +#define KINETIS_ENET_TAEM_OFFSET 0x01a4 /* Transmit FIFO Almost Empty Threshold */ +#define KINETIS_ENET_TAFL_OFFSET 0x01a8 /* Transmit FIFO Almost Full Threshold */ +#define KINETIS_ENET_TIPG_OFFSET 0x01ac /* Transmit Inter-Packet Gap */ +#define KINETIS_ENET_FTRL_OFFSET 0x01b0 /* Frame Truncation Length */ +#define KINETIS_ENET_TACC_OFFSET 0x01c0 /* Transmit Accelerator Function Configuration */ +#define KINETIS_ENET_RACC_OFFSET 0x01c4 /* Receive Accelerator Function Configuration */ + +#define KINETIS_ENET_ATCR_OFFSET 0x0400 /* Timer Control Register */ +#define KINETIS_ENET_ATVR_OFFSET 0x0404 /* Timer Value Register */ +#define KINETIS_ENET_ATOFF_OFFSET 0x0408 /* Timer Offset Register */ +#define KINETIS_ENET_ATPER_OFFSET 0x040c /* Timer Period Register */ +#define KINETIS_ENET_ATCOR_OFFSET 0x0410 /* Timer Correction Register */ +#define KINETIS_ENET_ATINC_OFFSET 0x0414 /* Time-Stamping Clock Period Register */ +#define KINETIS_ENET_ATSTMP_OFFSET 0x0418 /* Timestamp of Last Transmitted Frame */ + +#define KINETIS_ENET_TGSR_OFFSET 0x0604 /* Timer Global Status Register */ +#define KINETIS_ENET_TCSR0_OFFSET 0x0608 /* Timer Control Status Register */ +#define KINETIS_ENET_TCCR0_OFFSET 0x060c /* Timer Compare Capture Register */ +#define KINETIS_ENET_TCSR1_OFFSET 0x0610 /* Timer Control Status Register */ +#define KINETIS_ENET_TCCR1_OFFSET 0x0614 /* Timer Compare Capture Register */ +#define KINETIS_ENET_TCSR2_OFFSET 0x0618 /* Timer Control Status Register */ +#define KINETIS_ENET_TCCR2_OFFSET 0x061c /* Timer Compare Capture Register */ +#define KINETIS_ENET_TCSR3_OFFSET 0x0620 /* Timer Control Status Register */ +#define KINETIS_ENET_TCCR3_OFFSET 0x0624 /* Timer Compare Capture Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_ENET_EIR (KINETIS_EMAC_BASE+KINETIS_ENET_EIR_OFFSET) +#define KINETIS_ENET_EIMR (KINETIS_EMAC_BASE+KINETIS_ENET_EIMR_OFFSET) +#define KINETIS_ENET_RDAR (KINETIS_EMAC_BASE+KINETIS_ENET_RDAR_OFFSET) +#define KINETIS_ENET_TDAR (KINETIS_EMAC_BASE+KINETIS_ENET_TDAR_OFFSET) +#define KINETIS_ENET_ECR (KINETIS_EMAC_BASE+KINETIS_ENET_ECR_OFFSET) +#define KINETIS_ENET_MMFR (KINETIS_EMAC_BASE+KINETIS_ENET_MMFR_OFFSET) +#define KINETIS_ENET_MSCR (KINETIS_EMAC_BASE+KINETIS_ENET_MSCR_OFFSET) +#define KINETIS_ENET_MIBC (KINETIS_EMAC_BASE+KINETIS_ENET_MIBC_OFFSET) +#define KINETIS_ENET_RCR (KINETIS_EMAC_BASE+KINETIS_ENET_RCR_OFFSET) +#define KINETIS_ENET_TCR (KINETIS_EMAC_BASE+KINETIS_ENET_TCR_OFFSET) +#define KINETIS_ENET_PALR (KINETIS_EMAC_BASE+KINETIS_ENET_PALR_OFFSET) +#define KINETIS_ENET_PAUR (KINETIS_EMAC_BASE+KINETIS_ENET_PAUR_OFFSET) +#define KINETIS_ENET_OPD (KINETIS_EMAC_BASE+KINETIS_ENET_OPD_OFFSET) +#define KINETIS_ENET_IAUR (KINETIS_EMAC_BASE+KINETIS_ENET_IAUR_OFFSET) +#define KINETIS_ENET_IALR (KINETIS_EMAC_BASE+KINETIS_ENET_IALR_OFFSET) +#define KINETIS_ENET_GAUR (KINETIS_EMAC_BASE+KINETIS_ENET_GAUR_OFFSET) +#define KINETIS_ENET_GALR (KINETIS_EMAC_BASE+KINETIS_ENET_GALR_OFFSET) +#define KINETIS_ENET_TFWR (KINETIS_EMAC_BASE+KINETIS_ENET_TFWR_OFFSET) +#define KINETIS_ENET_RDSR (KINETIS_EMAC_BASE+KINETIS_ENET_RDSR_OFFSET) +#define KINETIS_ENET_TDSR (KINETIS_EMAC_BASE+KINETIS_ENET_TDSR_OFFSET) +#define KINETIS_ENET_MRBR (KINETIS_EMAC_BASE+KINETIS_ENET_MRBR_OFFSET) +#define KINETIS_ENET_RSFL (KINETIS_EMAC_BASE+KINETIS_ENET_RSFL_OFFSET) +#define KINETIS_ENET_RSEM (KINETIS_EMAC_BASE+KINETIS_ENET_RSEM_OFFSET) +#define KINETIS_ENET_RAEM (KINETIS_EMAC_BASE+KINETIS_ENET_RAEM_OFFSET) +#define KINETIS_ENET_RAFL (KINETIS_EMAC_BASE+KINETIS_ENET_RAFL_OFFSET) +#define KINETIS_ENET_TSEM (KINETIS_EMAC_BASE+KINETIS_ENET_TSEM_OFFSET) +#define KINETIS_ENET_TAEM (KINETIS_EMAC_BASE+KINETIS_ENET_TAEM_OFFSET) +#define KINETIS_ENET_TAFL (KINETIS_EMAC_BASE+KINETIS_ENET_TAFL_OFFSET) +#define KINETIS_ENET_TIPG (KINETIS_EMAC_BASE+KINETIS_ENET_TIPG_OFFSET) +#define KINETIS_ENET_FTRL (KINETIS_EMAC_BASE+KINETIS_ENET_FTRL_OFFSET) +#define KINETIS_ENET_TACC (KINETIS_EMAC_BASE+KINETIS_ENET_TACC_OFFSET) +#define KINETIS_ENET_RACC (KINETIS_EMAC_BASE+KINETIS_ENET_RACC_OFFSET) + +#define KINETIS_ENET_ATCR (KINETIS_EMAC_BASE+KINETIS_ENET_ATCR_OFFSET) +#define KINETIS_ENET_ATVR (KINETIS_EMAC_BASE+KINETIS_ENET_ATVR_OFFSET) +#define KINETIS_ENET_ATOFF (KINETIS_EMAC_BASE+KINETIS_ENET_ATOFF_OFFSET) +#define KINETIS_ENET_ATPER (KINETIS_EMAC_BASE+KINETIS_ENET_ATPER_OFFSET) +#define KINETIS_ENET_ATCOR (KINETIS_EMAC_BASE+KINETIS_ENET_ATCOR_OFFSET) +#define KINETIS_ENET_ATINC (KINETIS_EMAC_BASE+KINETIS_ENET_ATINC_OFFSET) +#define KINETIS_ENET_ATSTMP (KINETIS_EMAC_BASE+KINETIS_ENET_ATSTMP_OFFSET) + +#define KINETIS_ENET_TGSR (KINETIS_EMAC_BASE+KINETIS_ENET_TGSR_OFFSET) +#define KINETIS_ENET_TCSR0 (KINETIS_EMAC_BASE+KINETIS_ENET_TCSR0_OFFSET) +#define KINETIS_ENET_TCCR0 (KINETIS_EMAC_BASE+KINETIS_ENET_TCCR0_OFFSET) +#define KINETIS_ENET_TCSR1 (KINETIS_EMAC_BASE+KINETIS_ENET_TCSR1_OFFSET) +#define KINETIS_ENET_TCCR1 (KINETIS_EMAC_BASE+KINETIS_ENET_TCCR1_OFFSET) +#define KINETIS_ENET_TCSR2 (KINETIS_EMAC_BASE+KINETIS_ENET_TCSR2_OFFSET) +#define KINETIS_ENET_TCCR2 (KINETIS_EMAC_BASE+KINETIS_ENET_TCCR2_OFFSET) +#define KINETIS_ENET_TCSR3 (KINETIS_EMAC_BASE+KINETIS_ENET_TCSR3_OFFSET) +#define KINETIS_ENET_TCCR3 (KINETIS_EMAC_BASE+KINETIS_ENET_TCCR3_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* Interrupt Event Register, Interrupt Mask Register */ + /* Bits 0-14: Reserved */ +#define ENET_INT_TS_TIMER (1 << 15) /* Bit 15: Timestamp timer */ +#define ENET_INT_TS_AVAIL (1 << 16) /* Bit 16: Transmit timestamp available */ +#define ENET_INT_WAKEUP (1 << 17) /* Bit 17: Node wake-up request indication */ +#define ENET_INT_PLR (1 << 18) /* Bit 18: Payload receive error */ +#define ENET_INT_UN (1 << 19) /* Bit 19: Transmit FIFO underrun */ +#define ENET_INT_RL (1 << 20) /* Bit 20: Collision Retry Limit */ +#define ENET_INT_LC (1 << 21) /* Bit 21: Late Collision */ +#define ENET_INT_EBERR (1 << 22) /* Bit 22: Ethernet Bus Error */ +#define ENET_INT_MII (1 << 23) /* Bit 23: MII Interrupt */ +#define ENET_INT_RXB (1 << 24) /* Bit 24: Receive Buffer Interrupt */ +#define ENET_INT_RXF (1 << 25) /* Bit 25: Receive Frame Interrupt */ +#define ENET_INT_TXB (1 << 26) /* Bit 26: Transmit Buffer Interrupt */ +#define ENET_INT_TXF (1 << 27) /* Bit 27: Transmit Frame Interrupt */ +#define ENET_INT_GRA (1 << 28) /* Bit 28: Graceful Stop Complete */ +#define ENET_INT_BABT (1 << 29) /* Bit 29: Babbling Transmit Error */ +#define ENET_INT_BABR (1 << 30) /* Bit 30: Babbling Receive Error */ + /* Bit 31: Reserved */ +/* Receive Descriptor Active Register */ + /* Bits 0-23: Reserved */ +#define ENET_RDAR (1 << 24) /* Bit 24: Receive descriptor active */ + /* Bits 25-31: Reserved */ +/* Transmit Descriptor Active Register */ + /* Bits 0-23: Reserved */ +#define ENET_TDAR (1 << 24) /* Bit 24: Transmit descriptor active */ + /* Bits 25-31: Reserved */ +/* Ethernet Control Register */ + +#define ENET_ECR_RESET (1 << 0) /* Bit 0: Ethernet MAC reset */ +#define ENET_ECR_ETHEREN (1 << 1) /* Bit 1: Ethernet enable */ +#define ENET_ECR_MAGICEN (1 << 2) /* Bit 2: Magic packet detection enable */ +#define ENET_ECR_SLEEP (1 << 3) /* Bit 3: Sleep mode enable */ +#define ENET_ECR_EN1588 (1 << 4) /* Bit 4: EN1588 enable */ + /* Bit 5: Reserved */ +#define ENET_ECR_DBGEN (1 << 6) /* Bit 6: Debug enable */ +#define ENET_ECR_STOPEN (1 << 7) /* Bit 7: STOPEN Signal Control */ +#ifdef KINETIS_ENET_HAS_DBSWAP +#define ENET_ECR_DBSWP (1 << 8) /* Bit 8: Swap bytes */ +#endif + /* Bits 9-31: Reserved */ +/* MII Management Frame Register */ + +#define ENET_MMFR_DATA_SHIFT (0) /* Bits 0-15: Management frame data */ +#define ENET_MMFR_DATA_MASK (0xffff << ENET_MMFR_DATA_SHIFT) +#define ENET_MMFR_TA_SHIFT (16) /* Bits 16-17: Turn around */ +#define ENET_MMFR_TA_MASK (3 << ENET_MMFR_TA_SHIFT) +#define ENET_MMFR_RA_SHIFT (18) /* Bits 18-22: Register address */ +#define ENET_MMFR_RA_MASK (31 << ENET_MMFR_RA_SHIFT) +#define ENET_MMFR_PA_SHIFT (23) /* Bits 23-27: PHY address */ +#define ENET_MMFR_PA_MASK (31 << ENET_MMFR_PA_SHIFT) +#define ENET_MMFR_OP_SHIFT (28) /* Bits 28-29: Operation code */ +#define ENET_MMFR_OP_MASK (3 << ENET_MMFR_OP_SHIFT) +# define ENET_MMFR_OP_WRNOTMII (0 << ENET_MMFR_OP_SHIFT) /* Write frame, not MII compliant */ +# define ENET_MMFR_OP_WRMII (1 << ENET_MMFR_OP_SHIFT) /* Write frame, MII management frame */ +# define ENET_MMFR_OP_RDMII (2 << ENET_MMFR_OP_SHIFT) /* Read frame, MII management frame */ +# define ENET_MMFR_OP_RdNOTMII (3 << ENET_MMFR_OP_SHIFT) /* Read frame, not MII compliant */ +#define ENET_MMFR_ST_SHIFT (30) /* Bits 30-31: Start of frame delimiter */ +#define ENET_MMFR_ST_MASK (3 << ENET_MMFR_ST_SHIFT) + +/* MII Speed Control Register */ + /* Bit 0: Reserved */ +#define ENET_MSCR_MII_SPEED_SHIFT (1) /* Bits 1-6: MII speed */ +#define ENET_MSCR_MII_SPEED_MASK (63 << ENET_MSCR_MII_SPEED_SHIFT) +#define ENET_MSCR_DIS_PRE (1 << 7) /* Bit 7: Disable preamble */ +#define ENET_MSCR_HOLDTIME_SHIFT (8) /* Bits 8-10: Holdtime on MDIO output */ +#define ENET_MSCR_HOLDTIME_MASK (7 << ENET_MSCR_HOLDTIME_SHIFT) +# define ENET_MSCR_HOLDTIME_1CYCLE (0 << ENET_MSCR_HOLDTIME_SHIFT) /* 1 internal module clock cycle */ +# define ENET_MSCR_HOLDTIME_2CYCLES (1 << ENET_MSCR_HOLDTIME_SHIFT) /* 2 internal module clock cycles */ +# define ENET_MSCR_HOLDTIME_3CYCLES (2 << ENET_MSCR_HOLDTIME_SHIFT) /* 3 internal module clock cycles */ +# define ENET_MSCR_HOLDTIME_8CYCLES (7 << ENET_MSCR_HOLDTIME_SHIFT) /* 8 internal module clock cycles */ + /* Bits 11-31: Reserved */ +/* MIB Control Register */ + /* Bits 0-28: Reserved */ +#define ENET_MIBC_MIB_CLEAR (1 << 29) /* Bit 29: MIB clear */ +#define ENET_MIBC_MIB_IDLE (1 << 30) /* Bit 30: MIB idle */ +#define ENET_MIBC_MIB_DIS (1 << 31) /* Bit 31: Disable MIB logic */ + +/* Receive Control Register */ + +#define ENET_RCR_LOOP (1 << 0) /* Bit 0: Internal loopback */ +#define ENET_RCR_DRT (1 << 1) /* Bit 1: Disable receive on transmit */ +#define ENET_RCR_MII_MODE (1 << 2) /* Bit 2: Media independent interface mode */ +#define ENET_RCR_PROM (1 << 3) /* Bit 3: Promiscuous mode */ +#define ENET_RCR_BC_REJ (1 << 4) /* Bit 4: Broadcast frame reject */ +#define ENET_RCR_FCE (1 << 5) /* Bit 5: Flow control enable */ + /* Bits 6-7: Reserved */ +#define ENET_RCR_RMII_MODE (1 << 8) /* Bit 8: RMII mode enable */ +#define ENET_RCR_RMII_10T (1 << 9) /* Bit 9: Enables 10-Mbps mode of the RMII */ + /* Bits 10-11: Reserved */ +#define ENET_RCR_PADEN (1 << 12) /* Bit 12: Enable frame padding remove on receive */ +#define ENET_RCR_PAUFWD (1 << 13) /* Bit 13: Terminate/forward pause frames */ +#define ENET_RCR_CRCFWD (1 << 14) /* Bit 14: Terminate/forward received CRC */ +#define ENET_RCR_CFEN (1 << 15) /* Bit 15: MAC control frame enable */ +#define ENET_RCR_MAX_FL_SHIFT (16) /* Bits 16-29: Maximum frame length */ +#define ENET_RCR_MAX_FL_MASK (0x3fff << ENET_RCR_MAX_FL_SHIFT) +#define ENET_RCR_NLC (1 << 30) /* Bit 30: Payload length check disable */ +#define ENET_RCR_GRS (1 << 31) /* Bit 31: Graceful receive stopped */ + +/* Transmit Control Register */ + +#define ENET_TCR_GTS (1 << 0) /* Bit 0: Graceful transmit stop */ + /* Bit 1: Reserved */ +#define ENET_TCR_ADDINS (1 << 8) /* Bit 8: Set MAC address on transmit */ +#define ENET_TCR_FDEN (1 << 2) /* Bit 2: Full duplex enable */ +#define ENET_TCR_TFC_PAUSE (1 << 3) /* Bit 3: Transmit frame control pause */ +#define ENET_TCR_RFC_PAUSE (1 << 4) /* Bit 4: Receive frame control pause */ +#define ENET_TCR_ADDSEL_SHIFT (5) /* Bits 5-7: Source MAC address select on transmit */ +#define ENET_TCR_ADDSEL_MASK (7 << ENET_TCR_ADDSEL_SHIFT) +# define ENET_TCR_ADDSEL_PADDR12 (0 << ENET_TCR_ADDSEL_SHIFT) /* Node MAC address programmed on PADDR1/2 registers */ +#define ENET_TCR_CRCFWD (1 << 9) /* Bit 9: Forward frame from application with CRC */ + /* Bits 10-31: Reserved */ +/* Physical Address Lower/Upper Register (32-bits of 48-address) */ +/* Physical Address Upper Register */ + +#define ENET_PAUR_TYPE_SHIFT (0) /* Bits 0-15: Type field in PAUSE frame */ +#define ENET_PAUR_TYPE_MASK (0xffff << ENET_PAUR_TYPE_MASK) +#define ENET_PAUR_PADDR2_SHIFT (16) /* Bits 16-31: Bytes 4 and 5 of the 6-byte address */ +#define ENET_PAUR_PADDR2_MASK (0xffff << ENET_PAUR_PADDR2_SHIFT) + +/* Opcode/Pause Duration Register */ + +#define ENET_OPD_PAUSE_DUR_SHIFT (0) /* Bits 0-15: Pause duration */ +#define ENET_OPD_PAUSE_DUR_MASK (0xffff << ENET_OPD_PAUSE_DUR_SHIFT) +#define ENET_OPD_OPCODE_SHIFT (16) /* Bits 16-31: Opcode field in PAUSE frames */ +#define ENET_OPD_OPCODE_MASK (0xffff << ENET_OPD_OPCODE_SHIFT) + +/* Descriptor Individual Uupper/Lower Address Register (64-bit address in two 32-bit registers) */ +/* Descriptor Group Upper/Lower Address Register (64-bit address in two 32-bit registers) */ + +/* Transmit FIFO Watermark Register */ + +#define ENET_TFWR_TFWR_SHIFT (0) /* Bits 0-5: Transmit FIFO write */ + /* Bits 6-7: Reserved */ +#define ENET_TFWR_TFWR_MASK (63 << ENET_TFWR_TFWR_SHIFT) +#define ENET_TFWR_STRFWD (1 << 8) /* Bit 8: Store and forward enable */ + /* Bits 9-31: Reserved */ +/* Receive Descriptor Ring Start Register */ + /* Bits 0-2: Reserved */ +#define ENET_RDSR_SHIFT (3) /* Bits 3-31: Start of the receive buffer descriptor queue */ +#define ENET_RDSR_MASK (0xfffffff8) + +/* Transmit Buffer Descriptor Ring Start Register */ + /* Bits 0-2: Reserved */ +#define ENET_TDSR_SHIFT (3) /* Bits 3-31: Start of the transmit buffer descriptor queue */ +#define ENET_TDSR_MASK (0xfffffff8) + +/* Maximum Receive Buffer Size Register */ + /* Bits 14-31: Reserved */ +#define ENET_MRBR_SHIFT (4) /* Bits 4-13: Receive buffer size in bytes */ +#define ENET_MRBR_MASK (0x3ff << ENET_MRBR_SHIFT) + /* Bits 0-3: Reserved */ +/* Receive FIFO Section Full Threshold */ + /* Bits 8-31: Reserved */ +#define ENET_RSFL_SHIFT (0) /* Bits 0-7: Value of receive FIFO section full threshold */ +#define ENET_RSFL_MASK (0xff << ENET_RSFL_SHIFT) + +/* Receive FIFO Section Empty Threshold */ + +#define ENET_RSEM_SHIFT (0) /* Bits 0-7: Value of the receive FIFO section empty threshold */ +#define ENET_RSEM_MASK (0xff << ENET_RSEM_SHIFT) + /* Bits 8-31: Reserved */ +/* Receive FIFO Almost Empty Threshold */ + +#define ENET_RAEM_SHIFT (0) /* Bits 0-7: Value of the receive FIFO almost empty threshold */ +#define ENET_RAEM_MASK (0xff << ENET_RAEM_SHIFT) + /* Bits 8-31: Reserved */ +/* Receive FIFO Almost Full Threshold */ + +#define ENET_RAFL_SHIFT (0) /* Bits 0-7: Value of the receive FIFO almost full threshold */ +#define ENET_RAFL_MASK (0xff << ENET_RAFL_SHIFT) + /* Bits 8-31: Reserved */ +/* Transmit FIFO Section Empty Threshold */ + +#define ENET_TSEM_SHIFT (0) /* Bits 0-7: Value of the transmit FIFO section empty threshold */ +#define ENET_TSEM_MASK (0xff << ENET_TSEM_SHIFT) + /* Bits 8-31: Reserved */ +/* Transmit FIFO Almost Empty Threshold */ + +#define ENET_TAEM_SHIFT (0) /* Bits 0-7: Value of the transmit FIFO section empty threshold */ +#define ENET_TAEM_MASK (0xff << ENET_TAEM_SHIFT) + /* Bits 8-31: Reserved */ +/* Transmit FIFO Almost Full Threshold */ + +#define ENET_TAFL_SHIFT (0) /* Bits 0-7: Value of the transmit FIFO section empty threshold */ +#define ENET_TAFL_MASK (0xff << ENET_TAFL_SHIFT) + /* Bits 8-31: Reserved */ +/* Transmit Inter-Packet Gap */ + +#define ENET_TIPG_SHIFT (0) /* Bits 0-4: Value of the transmit FIFO section empty threshold */ +#define ENET_TIPG_MASK (31 << ENET_TIPG_SHIFT) + /* Bits 5-31: Reserved */ +/* Frame Truncation Length */ + +#define ENET_FTRL_SHIFT (0) /* Bits 0-13: Value of the transmit FIFO section empty threshold */ +#define ENET_FTRL_MASK (0x3fff << ENET_FTRL_SHIFT) + /* Bits 14-31: Reserved */ +/* Transmit Accelerator Function Configuration */ + +#define ENET_TACC_SHIFT16 (1 << 0) /* Bit 0: TX FIFO shift-16 */ + /* Bits 1-2: Reserved */ +#define ENET_TACC_IPCHK (1 << 3) /* Bit 3: Enables insertion of IP header checksum */ +#define ENET_TACC_PROCHK (1 << 4) /* Bit 4: Enables insertion of protocol checksum */ + /* Bits 5-31: Reserved */ +/* Receive Accelerator Function Configuration */ + +#define ENET_RACC_PADREM (1 << 0) /* Bit 0: Enable padding removal for short IP frames */ +#define ENET_RACC_IPDIS (1 << 1) /* Bit 1: Enable discard of frames with wrong IPv4 header checksum */ +#define ENET_RACC_PRODIS (1 << 2) /* Bit 2: Enable discard of frames with wrong protocol checksum */ + /* Bits 3-5: Reserved */ +#define ENET_RACC_LINEDIS (1 << 6) /* Bit 6: Enable discard of frames with MAC layer errors */ +#define ENET_RACC_SHIFT16 (1 << 7) /* Bit 7: RX FIFO shift-16 */ + /* Bits 8-31: Reserved */ +/* Timer Control Register */ + +#define ENET_ATCR_EN (1 << 0) /* Bit 0: Enable timer */ + /* Bit 1: Reserved */ +#define ENET_ATCR_OFFEN (1 << 2) /* Bit 2: Enable one-shot offset event */ +#define ENET_ATCR_OFFRST (1 << 3) /* Bit 3: Reset timer on offset event */ +#define ENET_ATCR_PEREN (1 << 4) /* Bit 4: Enable periodical event */ + /* Bits 5-6: Reserved */ +#define ENET_ATCR_PINPER (1 << 7) /* Bit 7: Enables event signal output assertion on period event */ + /* Bit 8: Reserved */ +#define ENET_ATCR_RESTART (1 << 9) /* Bit 9: Reset timer */ + /* Bit 10: Reserved */ +#define ENET_ATCR_CAPTURE (1 << 11) /* Bit 11: Capture timer value */ + /* Bit 12: Reserved */ +#define ENET_ATCR_SLAVE (1 << 13) /* Bit 13: Enable timer slave mode */ + /* Bits 14-31: Reserved */ +/* Timer Value Register (32-bit timer value) */ +/* Timer Offset Register (32-bit offset value) */ +/* Timer Period Register (32-bit timer period) */ + +/* Timer Correction Register */ + +#define ENET_ATCOR_MASK (0x7fffffff) /* Bits 0-3: Correction counter wrap-around value */ + /* Bit 31: Reserved */ +/* Time-Stamping Clock Period Register */ + +#define ENET_ATINC_INC_SHIFT (0) /* Bits 0-6: Clock period of the timestamping clock (ts_clk) in nanoseconds */ +#define ENET_ATINC_INC_MASK (0x7f << ENET_ATINC_INC_SHIFT) + /* Bit 7: Reserved */ +#define ENET_ATINC_INC_CORR_SHIFT (8) /* Bits 8-14: Correction increment value */ +#define ENET_ATINC_INC_CORR_MASK (0x7f << ENET_ATINC_INC_CORR_SHIFT) + /* Bits 15-31: Reserved */ +/* Timestamp of Last Transmitted Frame (32-bit timestamp) */ + +/* Timer Global Status Register */ + +#define ENET_TGSR_TF0 (1 << 0) /* Bit 0: Copy of Timer Flag for channel 0 */ +#define ENET_TGSR_TF1 (1 << 1) /* Bit 1: Copy of Timer Flag for channel 1 */ +#define ENET_TGSR_TF2 (1 << 2) /* Bit 2: Copy of Timer Flag for channel 2 */ +#define ENET_TGSR_TF3 (1 << 3) /* Bit 3: Copy of Timer Flag for channel 3 */ + /* Bits 14-31: Reserved */ +/* Timer Control Status Register n */ + +#define ENET_TCSR_TDRE (1 << 0) /* Bit 0: Timer DMA Request Enable */ + /* Bit 1: Reserved */ +#define ENET_TCSR_TMODE_SHIFT (2) /* Bits 2-5: Timer Mode */ +#define ENET_TCSR_TMODE_MASK (15 << ENET_TCSR_TMODE_SHIFT) +# define ENET_TCSR_TMODE_DISABLED (0 << ENET_TCSR_TMODE_SHIFT) /* Disabled */ +# define ENET_TCSR_TMODE_ICRISING (1 << ENET_TCSR_TMODE_SHIFT) /* Input Capture on rising edge */ +# define ENET_TCSR_TMODE_ICFALLLING (2 << ENET_TCSR_TMODE_SHIFT) /* Input Capture on falling edge */ +# define ENET_TCSR_TMODE_ICBOTH (3 << ENET_TCSR_TMODE_SHIFT) /* Input Capture on both edges */ +# define ENET_TCSR_TMODE_OCSW (4 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, S/W only */ +# define ENET_TCSR_TMODE_OCTOGGLE (5 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, toggle on compare */ +# define ENET_TCSR_TMODE_OCCLR (6 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, clear on compare */ +# define ENET_TCSR_TMODE_OCSET (7 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, set on compare */ +# define ENET_TCSR_TMODE_OCSETCLR (9 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, set on compare, clear on overflow */ +# define ENET_TCSR_TMODE_OCCLRSET (10 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, clear on compare, set on overflow */ +# define ENET_TCSR_TMODE_PCPULSEL (14 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, pulse low on compare */ +# define ENET_TCSR_TMODE_PCPULSEH (15 << ENET_TCSR_TMODE_SHIFT) /* Output Compare, pulse high on compare */ +#define ENET_TCSR_TIE (1 << 6) /* Bit 6: Timer interrupt enable */ +#define ENET_TCSR_TF (1 << 7) /* Bit 7: Timer Flag */ + /* Bits 8-31: Reserved */ +/* Timer Compare Capture Register (32-bit compare value) */ + +/* Buffer Descriptors ***********************************************************************/ +/* Endian-independent descriptor offsets */ + +#define DESC_STATUS1_OFFSET (0) +#define DESC_LENGTH_OFFSET (2) +#define DESC_DATAPTR_OFFSET (4) +#define DESC_LEGACY_LEN (8) + +#define DESC_STATUS2_OFFSET (8) +#define DESC_LENPROTO_OFFSET (12) +#define DESC_CHECKSUM_OFFSET (14) +#define DESC_BDU_OFFSET (16) +#define DESC_TIMESTAMP_OFFSET (20) +#define DESC_ENHANCED_LEN (32) + +/* Legacy/Common TX Buffer Descriptor Bit Definitions. + * + * The descriptors are represented by structures Unfortunately, when the + * structures are overlayed on the data, the bytes are reversed because + * the underlying hardware writes the data in big-endian byte order. + */ + +#ifdef KINETIS_ENET_HAS_DBSWAP +# ifndef CONFIG_ENDIAN_BIG +# define KINETIS_USE_DBSWAP +# endif +#else +# ifndef CONFIG_ENDIAN_BIG +# define KINETIS_BUFFERS_SWAP +# endif +#endif + +#ifndef KINETIS_BUFFERS_SWAP +# define TXDESC_ABC (1 << 9) /* Legacy */ +# define TXDESC_TC (1 << 10) /* Common */ +# define TXDESC_L (1 << 11) /* Common */ +# define TXDESC_TO2 (1 << 12) /* Common */ +# define TXDESC_W (1 << 13) /* Common */ +# define TXDESC_TO1 (1 << 14) /* Common */ +# define TXDESC_R (1 << 15) /* Common */ +#else +# define TXDESC_ABC (1 << 1) /* Legacy */ +# define TXDESC_TC (1 << 2) /* Common */ +# define TXDESC_L (1 << 3) /* Common */ +# define TXDESC_TO2 (1 << 4) /* Common */ +# define TXDESC_W (1 << 5) /* Common */ +# define TXDESC_TO1 (1 << 6) /* Common */ +# define TXDESC_R (1 << 7) /* Common */ +#endif + +/* Enhanced (only) TX Buffer Descriptor Bit Definitions */ + +#ifndef KINETIS_BUFFERS_SWAP +# define TXDESC_TSE (1 << 8) +# define TXDESC_OE (1 << 9) +# define TXDESC_LCE (1 << 10) +# define TXDESC_FE (1 << 11) +# define TXDESC_EE (1 << 12) +# define TXDESC_UE (1 << 13) +# define TXDESC_TXE (1 << 15) + +# define TXDESC_IINS (1 << 27) +# define TXDESC_PINS (1 << 28) +# define TXDESC_TS (1 << 29) +# define TXDESC_INT (1 << 30) + +# define TXDESC_BDU (1 << 31) +#else +# define TXDESC_IINS (1 << 3) +# define TXDESC_PINS (1 << 4) +# define TXDESC_TS (1 << 5) +# define TXDESC_INT (1 << 6) + +# define TXDESC_TSE (1 << 16) +# define TXDESC_OE (1 << 17) +# define TXDESC_LCE (1 << 18) +# define TXDESC_FE (1 << 19) +# define TXDESC_EE (1 << 20) +# define TXDESC_UE (1 << 21) +# define TXDESC_TXE (1 << 23) + +# define TXDESC_BDU (1 << 7) +#endif + +/* Legacy (and Common) RX Buffer Descriptor Bit Definitions */ + +#ifndef KINETIS_BUFFERS_SWAP +# define RXDESC_TR (1 << 0) +# define RXDESC_OV (1 << 1) +# define RXDESC_CR (1 << 2) +# define RXDESC_NO (1 << 4) +# define RXDESC_LG (1 << 5) +# define RXDESC_MC (1 << 6) +# define RXDESC_BC (1 << 7) +# define RXDESC_M (1 << 8) +# define RXDESC_L (1 << 11) +# define RXDESC_R02 (1 << 12) +# define RXDESC_W (1 << 13) +# define RXDESC_R01 (1 << 14) +# define RXDESC_E (1 << 15) +#else +# define RXDESC_M (1 << 0) +# define RXDESC_L (1 << 3) +# define RXDESC_R02 (1 << 4) +# define RXDESC_W (1 << 5) +# define RXDESC_R01 (1 << 6) +# define RXDESC_E (1 << 7) +# define RXDESC_TR (1 << 8) +# define RXDESC_OV (1 << 9) +# define RXDESC_CR (1 << 10) +# define RXDESC_NO (1 << 12) +# define RXDESC_LG (1 << 13) +# define RXDESC_MC (1 << 14) +# define RXDESC_BC (1 << 15) +#endif + +/* Enhanced (only) TX Buffer Descriptor Bit Definitions */ + +#ifndef KINETIS_BUFFERS_SWAP +# define RXDESC_FRAG (1 << 0) +# define RXDESC_IPV6 (1 << 1) +# define RXDESC_VLAN (1 << 2) +# define RXDESC_PCR (1 << 4) +# define RXDESC_ICE (1 << 5) +# define RXDESC_INT (1 << 23) +# define RXDESC_UC (1 << 24) +# define RXDESC_CE (1 << 25) +# define RXDESC_PE (1 << 26) +# define RXDESC_ME (1 << 31) + +# define RXDESC_BDU (1 << 31) +#else +# define RXDESC_UC (1 << 0) +# define RXDESC_CE (1 << 1) +# define RXDESC_PE (1 << 2) +# define RXDESC_ME (1 << 7) +# define RXDESC_INT (1 << 15) +# define RXDESC_FRAG (1 << 24) +# define RXDESC_IPV6 (1 << 25) +# define RXDESC_VLAN (1 << 26) +# define RXDESC_PCR (1 << 28) +# define RXDESC_ICE (1 << 29) + +# define RXDESC_BDU (1 << 7) +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ +/* Buffer Descriptors ***********************************************************************/ +/* Legacy Buffer Descriptor */ + +#ifdef CONFIG_ENET_ENHANCEDBD +#ifdef KINETIS_USE_DBSWAP +/* When DBSWP is used to swap the bytes in hardware, it is done 32-bits + * at a time. Therefore, all 16 bit elements need to be swapped to + * compensate. + */ + +struct enet_desc_s +{ + uint16_t length; /* Data length */ + uint16_t status1; /* Control and status */ + uint8_t *data; /* Buffer address */ + uint32_t status2; /* Extended status */ + uint16_t checksum; /* Payload checksum */ + uint16_t lenproto; /* Header length + Protocol type */ + uint32_t bdu; /* BDU */ + uint32_t timestamp; /* Time stamp */ + uint32_t reserved1; /* unused */ + uint32_t reserved2; /* unused */ +}; +#else +struct enet_desc_s +{ + uint16_t status1; /* Control and status */ + uint16_t length; /* Data length */ + uint8_t *data; /* Buffer address */ + uint32_t status2; /* Extended status */ + uint16_t lenproto; /* Header length + Protocol type */ + uint16_t checksum; /* Payload checksum */ + uint32_t bdu; /* BDU */ + uint32_t timestamp; /* Time stamp */ + uint32_t reserved1; /* unused */ + uint32_t reserved2; /* unused */ +}; +#endif +#else +#ifdef KINETIS_USE_DBSWAP +struct enet_desc_s +{ + uint16_t length; /* Data length */ + uint16_t status1; /* Control and status */ + uint8_t *data; /* Buffer address */ +}; +#else +struct enet_desc_s +{ + uint16_t status1; /* Control and status */ + uint16_t length; /* Data length */ + uint8_t *data; /* Buffer address */ +}; +#endif +#endif + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* KINETIS_NENET && KINETIS_NENET > 0 */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H */ diff --git a/arch/arm/src/kinetis/kinetis_ewm.h b/arch/arm/src/kinetis/kinetis_ewm.h new file mode 100644 index 0000000000000000000000000000000000000000..e259a3cf29af2f891e40532f4afd01ff3e5626bc --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_ewm.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_ewm.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_EWM_CTRL_OFFSET 0x0000 /* Control Register */ +#define KINETIS_EWM_SERV_OFFSET 0x0001 /* Service Register */ +#define KINETIS_EWM_CMPL_OFFSET 0x0002 /* Compare Low Register */ +#define KINETIS_EWM_CMPH_OFFSET 0x0003 /* Compare High Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_EWM_CTRL (KINETIS_EWM_BASE+KINETIS_EWM_CTRL_OFFSET) +#define KINETIS_EWM_SERV (KINETIS_EWM_BASE+KINETIS_EWM_SERV_OFFSET) +#define KINETIS_EWM_CMPL (KINETIS_EWM_BASE+KINETIS_EWM_CMPL_OFFSET) +#define KINETIS_EWM_CMPH (KINETIS_EWM_BASE+KINETIS_EWM_CMPH_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Control Register (8-bit) */ + +#define EWM_CTRL_EWMEN (1 << 0) /* Bit 0: EWM enable */ +#define EWM_CTRL_ASSIN (1 << 2) /* Bit 1: EWM_in's Assertion State Select */ +#define EWM_CTRL_INEN (1 << 3) /* Bit 2: Input Enable */ + /* Bits 7–3: Reserved */ + +/* Service Register (8-bit values: 0xb4 followed by 0x2c) */ +/* Compare Low Register (8-bit compare low value) */ +/* Compare High Register (8-bit compare high value) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H */ diff --git a/arch/arm/src/kinetis/kinetis_flexbus.h b/arch/arm/src/kinetis/kinetis_flexbus.h new file mode 100644 index 0000000000000000000000000000000000000000..37992320fb18804f50c1d985bcfe5a3e13a85bef --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_flexbus.h @@ -0,0 +1,213 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_flexbus.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_FB_CS_OFFSET(n) (0x0000+(12*(n))) +#define KINETIS_FB_CSAR_OFFSET 0x0000 /* Chip select n address register */ +#define KINETIS_FB_CSMR_OFFSET 0x0004 /* Chip select n mask register */ +#define KINETIS_FB_CSCR_OFFSET 0x0008 /* Chip select n control register */ + +#define KINETIS_FB_CSAR0_OFFSET 0x0000 /* Chip select 0 address register */ +#define KINETIS_FB_CSMR0_OFFSET 0x0004 /* Chip select 0 mask register */ +#define KINETIS_FB_CSCR0_OFFSET 0x0008 /* Chip select 0 control register */ + +#define KINETIS_FB_CSAR1_OFFSET 0x000c /* Chip select 1 address register */ +#define KINETIS_FB_CSMR1_OFFSET 0x0010 /* Chip select 1 mask register */ +#define KINETIS_FB_CSCR1_OFFSET 0x0014 /* Chip select 1 control register */ + +#define KINETIS_FB_CSAR2_OFFSET 0x0018 /* Chip select 2 address register */ +#define KINETIS_FB_CSMR2_OFFSET 0x001c /* Chip select 2 mask register */ +#define KINETIS_FB_CSCR2_OFFSET 0x0020 /* Chip select 2 control register */ + +#define KINETIS_FB_CSAR3_OFFSET 0x0024 /* Chip select 3 address register */ +#define KINETIS_FB_CSMR3_OFFSET 0x0028 /* Chip select 3 mask register */ +#define KINETIS_FB_CSCR3_OFFSET 0x002c /* Chip select 3 control register */ + +#define KINETIS_FB_CSAR4_OFFSET 0x0030 /* Chip select 4 address register */ +#define KINETIS_FB_CSMR4_OFFSET 0x0034 /* Chip select 4 mask register */ +#define KINETIS_FB_CSCR4_OFFSET 0x0038 /* Chip select 4 control register */ + +#define KINETIS_FB_CSAR5_OFFSET 0x003c /* Chip select 5 address register */ +#define KINETIS_FB_CSMR5_OFFSET 0x0040 /* Chip select 5 mask register */ +#define KINETIS_FB_CSCR5_OFFSET 0x0044 /* Chip select 5 control register */ + +#define KINETIS_FB_CSPMCR_OFFSET 0x0060 /* Chip select port multiplexing control register */ + +/* Register Addresses ***************************************************************/ +# define 0x4000c000 /* FlexBus */ + +#define KINETIS_FB_CS_BASE(n) (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CS_OFFSET(n)) +#define KINETIS_FB_CSAR(n) (KINETIS_FB_CS_BASE(n)+KINETIS_FB_CSAR_OFFSET) +#define KINETIS_FB_CSMR(n) (KINETIS_FB_CS_BASE(n)+KINETIS_FB_CSMR_OFFSET) +#define KINETIS_FB_CSCR(n) (KINETIS_FB_CS_BASE(n)+KINETIS_FB_CSCR_OFFSET) + +#define KINETIS_FB_CSAR0 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR0_OFFSET) +#define KINETIS_FB_CSMR0 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR0_OFFSET) +#define KINETIS_FB_CSCR0 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR0_OFFSET) + +#define KINETIS_FB_CSAR1 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR1_OFFSET) +#define KINETIS_FB_CSMR1 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR1_OFFSET) +#define KINETIS_FB_CSCR1 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR1_OFFSET) + +#define KINETIS_FB_CSAR2 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR2_OFFSET) +#define KINETIS_FB_CSMR2 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR2_OFFSET) +#define KINETIS_FB_CSCR2 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR2_OFFSET) + +#define KINETIS_FB_CSAR3 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR3_OFFSET) +#define KINETIS_FB_CSMR3 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR3_OFFSET) +#define KINETIS_FB_CSCR3 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR3_OFFSET) + +#define KINETIS_FB_CSAR4 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR4_OFFSET) +#define KINETIS_FB_CSMR4 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR4_OFFSET) +#define KINETIS_FB_CSCR4 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR4_OFFSET) + +#define KINETIS_FB_CSAR5 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSAR5_OFFSET) +#define KINETIS_FB_CSMR5 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSMR5_OFFSET) +#define KINETIS_FB_CSCR5 (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSCR5_OFFSET) + +#define KINETIS_FB_CSPMCR (KINETIS_FLEXBUSC_BASE+KINETIS_FB_CSPMCR_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Chip select address register (32-bit) */ + +#define FB_CSAR_BA_SHIFT (16) /* Bits 16-31: Base address */ +#define FB_CSAR_BA_MASK (0xffff << FB_CSAR_BA_SHIFT) + /* Bits 0-15: Reserved */ + +/* Chip select mask register (32-bit) */ + +#define FB_CSMR_V (1 << 0) /* Bit 0: Valid */ + /* Bits 1-7: Reserved */ +#define FB_CSMR_WP (1 << 8) /* Bit 8: Write protect + /* Bits 9-15: Reserved */ +#define FB_CSMR_BAM_SHIFT (16) /* Bits 16-31: Base address mask */ +#define FB_CSMR_BAM_MASK (0xffff << FB_CSMR_BAM_SHIFT) + +/* Chip select control register (32-bit) */ + /* Bits 0-1: Reserved */ +#define FB_CSCR_BSTW (1 << 3) /* Bit 3: Burst-write enable */ +#define FB_CSCR_BSTR (1 << 4) /* Bit 4: Burst-read enable */ +#define FB_CSCR_BEM (1 << 5) /* Bit 5: Byte-enable mode */ +#define FB_CSCR_PS_SHIFT (6) /* Bits 6-7: Port size */ +#define FB_CSCR_PS_MASK (3 << FB_CSCR_PS_SHIFT) +# define FB_CSCR_PS_32BIT (0 << FB_CSCR_PS_SHIFT) /* 32-bit port size */ +# define FB_CSCR_PS_8BIT (1 << FB_CSCR_PS_SHIFT) /* 8-bit port size */ +# define FB_CSCR_PS_16BIT (2 << FB_CSCR_PS_SHIFT) /* 16-bit port size */ +#define FB_CSCR_AA (1 << 8) /* Bit 8: Auto-acknowledge enable */ +#define FB_CSCR_BLS (1 << 9) /* Bit 9: Byte-lane shift */ +#define FB_CSCR_WS_SHIFT (10) /* Bits 19-15: Wait states */ +#define FB_CSCR_WS_SHIFT (10) /* Bits 19-15: Wait states */ +#define FB_CSCR_WRAH_SHIFT (16) /* Bits 16-17: Write address hold or deselect */ +#define FB_CSCR_WRAH_MASK (3 << FB_CSCR_WRAH_SHIFT) +# define FB_CSCR_WRAH_HOLD1 (0 << FB_CSCR_WRAH_SHIFT) /* Hold one cycle after FB_CSn */ +# define FB_CSCR_WRAH_HOLD2 (1 << FB_CSCR_WRAH_SHIFT) /* Hold two cycles after FB_CSn */ +# define FB_CSCR_WRAH_HOLD3 (2 << FB_CSCR_WRAH_SHIFT) /* Hold three cycles after FB_CSn */ +# define FB_CSCR_WRAH_HOLD4 (3 << FB_CSCR_WRAH_SHIFT) /* Hold four cycles after FB_CSn */ +#define FB_CSCR_RDAH_SHIFT (18) /* Bits 18-19: Read address hold or deselect */ +#define FB_CSCR_RDAH_MASK (3 << FB_CSCR_RDAH_SHIFT) +# define FB_CSCR_RDAH_10CYCLES (0 << FB_CSCR_RDAH_SHIFT) /* AA=0:1 cycle else 0 cycles */ +# define FB_CSCR_RDAH_21CYCLES (1 << FB_CSCR_RDAH_SHIFT) /* AA=0:2 cycles else 1 cycle */ +# define FB_CSCR_RDAH_32CYCLES (2 << FB_CSCR_RDAH_SHIFT) /* AA=0:3 cycles else 2 cycles */ +# define FB_CSCR_RDAH_43CYCLES (3 << FB_CSCR_RDAH_SHIFT) /* AA=0:4 cycles else 3 cycles */ +#define FB_CSCR_ASET_SHIFT (20) /* Bits 20-21: Address setup */ +#define FB_CSCR_ASET_MASK (3 << FB_CSCR_ASET_SHIFT) +# define FB_CSCR_ASET_1STRISING (0 << FB_CSCR_ASET_SHIFT) /* Assert CR on first rising clock edge */ +# define FB_CSCR_ASET_2NDRISING (1 << FB_CSCR_ASET_SHIFT) /* Assert CR on second rising clock edge */ +# define FB_CSCR_ASET_3RDRISING (2 << FB_CSCR_ASET_SHIFT) /* Assert CR on third rising clock edge */ +# define FB_CSCR_ASET_4thRISING (3 << FB_CSCR_ASET_SHIFT) /* Assert CR on fourth rising clock edge */ +#define FB_CSCR_EXTS (1 << 22) /* Bit 22: Extended address latch enable */ +#define FB_CSCR_SWSEN (1 << 23) /* Bit 23: Secondary wait state enable */ + /* Bits 24-25: Reserved */ +#define FB_CSCR_SWS_SHIFT (26) /* Bits 26-31: Secondary wait states */ +#define FB_CSCR_SWS_MASK (0x3f << FB_CSCR_SWS_SHIFT) + +/* Chip select port multiplexing control register (32-bit) */ + /* Bits 0-11: Reserved */ +#define FB_CSPMCR_GROUP5_SHIFT (12) /* Bits 12-15: FlexBus signal group 5 multiplex control */ +#define FB_CSPMCR_GROUP5_MASK (15 << FB_CSPMCR_GROUP5_SHIFT) +# define FB_CSPMCR_GROUP5_TA (0 << FB_CSPMCR_GROUP5_SHIFT) /* FB_TA */ +# define FB_CSPMCR_GROUP5_CS3 (1 << FB_CSPMCR_GROUP5_SHIFT) /* FB_CS3 */ +# define FB_CSPMCR_GROUP5_BE70 (2 << FB_CSPMCR_GROUP5_SHIFT) /* FB_BE_7_0 */ +#define FB_CSPMCR_GROUP4_SHIFT (16) /* Bits 16-19: FlexBus signal group 4 multiplex control */ +#define FB_CSPMCR_GROUP4_MASK (15 << FB_CSPMCR_GROUP4_SHIFT) +# define FB_CSPMCR_GROUP4_TBST (0 << FB_CSPMCR_GROUP4_SHIFT) /* FB_TBST */ +# define FB_CSPMCR_GROUP4_CS2 (1 << FB_CSPMCR_GROUP4_SHIFT) /* FB_CS2 */ +# define FB_CSPMCR_GROUP4_BE158 (2 << FB_CSPMCR_GROUP4_SHIFT) /* FB_BE_15_8 */ +#define FB_CSPMCR_GROUP3_SHIFT (20) /* Bits 29-23: FlexBus signal group 3 multiplex control */ +#define FB_CSPMCR_GROUP3_MASK (15 << FB_CSPMCR_GROUP3_SHIFT) +# define FB_CSPMCR_GROUP3_CS5 (0 << FB_CSPMCR_GROUP3_SHIFT) /* FB_CS5 */ +# define FB_CSPMCR_GROUP3_TSIZ1 (1 << FB_CSPMCR_GROUP3_SHIFT) /* FB_TSIZ1 */ +# define FB_CSPMCR_GROUP3_BE2316 (2 << FB_CSPMCR_GROUP3_SHIFT) /* FB_BE_23_16 */ +#define FB_CSPMCR_GROUP2_SHIFT (24) /* Bits 24-27: FlexBus signal group 2 multiplex control */ +#define FB_CSPMCR_GROUP2_MASK (15 << FB_CSPMCR_GROUP2_SHIFT) +# define FB_CSPMCR_GROUP2_CS4 (0 << FB_CSPMCR_GROUP2_SHIFT) /* FB_CS4 */ +# define FB_CSPMCR_GROUP2_TSIZ0 (1 << FB_CSPMCR_GROUP2_SHIFT) /* FB_TSIZ0 */ +# define FB_CSPMCR_GROUP2_BE3124 (2 << FB_CSPMCR_GROUP2_SHIFT) /* FB_BE_31_24 */ +#define FB_CSPMCR_GROUP1_SHIFT (28) /* Bits 28-31: FlexBus signal group 1 multiplex control */ +#define FB_CSPMCR_GROUP1_MASK (15 << FB_CSPMCR_GROUP1_MASK) +# define FB_CSPMCR_GROUP1_ALE (0 << FB_CSPMCR_GROUP1_MASK) /* FB_ALE */ +# define FB_CSPMCR_GROUP1_CS1 (1 << FB_CSPMCR_GROUP1_MASK) /* FB_CS1 */ +# define FB_CSPMCR_GROUP1_TS (2 << FB_CSPMCR_GROUP1_MASK) /* FB_TS */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H */ diff --git a/arch/arm/src/kinetis/kinetis_flexcan.h b/arch/arm/src/kinetis/kinetis_flexcan.h new file mode 100644 index 0000000000000000000000000000000000000000..db151d5403474d7dd1dc48ee249a8043846ae774 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_flexcan.h @@ -0,0 +1,318 @@ +/**************************************************************************************************** + * arch/arm/src/kinetis/kinetis_flexcan.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define KINETIS_CAN_MCR_OFFSET 0x0000 /* Module Configuration Register */ +#define KINETIS_CAN_CTRL1_OFFSET 0x0004 /* Control 1 Register */ +#define KINETIS_CAN_TIMER_OFFSET 0x0008 /* Free Running Timer */ +#define KINETIS_CAN_RXMGMASK_OFFSET 0x0010 /* Rx Mailboxes Global Mask Register */ +#define KINETIS_CAN_RX14MASK_OFFSET 0x0014 /* Rx 14 Mask Register */ +#define KINETIS_CAN_RX15MASK_OFFSET 0x0018 /* Rx 15 Mask Register */ +#define KINETIS_CAN_ECR_OFFSET 0x001c /* Error Counter */ +#define KINETIS_CAN_ESR1_OFFSET 0x0020 /* Error and Status 1 Register */ +#define KINETIS_CAN_IMASK2_OFFSET 0x0024 /* Interrupt Masks 2 Register */ +#define KINETIS_CAN_IMASK1_OFFSET 0x0028 /* Interrupt Masks 1 Register */ +#define KINETIS_CAN_IFLAG2_OFFSET 0x002c /* Interrupt Flags 2 Register */ +#define KINETIS_CAN_IFLAG1_OFFSET 0x0030 /* Interrupt Flags 1 Register */ +#define KINETIS_CAN_CTRL2_OFFSET 0x0034 /* Control 2 Register */ +#define KINETIS_CAN_ESR2_OFFSET 0x0038 /* Error and Status 2 Register */ +#define KINETIS_CAN_CRCR_OFFSET 0x0044 /* CRC Register */ +#define KINETIS_CAN_RXFGMASK_OFFSET 0x0048 /* Rx FIFO Global Mask Register */ +#define KINETIS_CAN_RXFIR_OFFSET 0x004c /* Rx FIFO Information Register */ + +#define KINETIS_CAN_RXIMR_OFFSET(n) (0x0880+((n)<<2)) /* Rn Individual Mask Registers */ +#define KINETIS_CAN_RXIMR0_OFFSET 0x0880 /* R0 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR1_OFFSET 0x0884 /* R1 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR2_OFFSET 0x0888 /* R2 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR3_OFFSET 0x088c /* R3 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR4_OFFSET 0x0890 /* R4 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR5_OFFSET 0x0894 /* R5 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR6_OFFSET 0x0898 /* R6 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR7_OFFSET 0x089c /* R7 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR8_OFFSET 0x08a0 /* R8 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR9_OFFSET 0x08a4 /* R9 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR10_OFFSET 0x08a8 /* R10 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR11_OFFSET 0x08ac /* R11 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR12_OFFSET 0x08b0 /* R12 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR13_OFFSET 0x08b4 /* R13 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR14_OFFSET 0x08b8 /* R14 Individual Mask Registers */ +#define KINETIS_CAN_RXIMR15_OFFSET 0x08bc /* R15 Individual Mask Registers */ + +/* Register Addresses *******************************************************************************/ + +#define KINETIS_CAN0_MCR (KINETIS_CAN0_BASE+KINETIS_CAN_MCR_OFFSET) +#define KINETIS_CAN0_CTRL1 (KINETIS_CAN0_BASE+KINETIS_CAN_CTRL1_OFFSET) +#define KINETIS_CAN0_TIMER (KINETIS_CAN0_BASE+KINETIS_CAN_TIMER_OFFSET) +#define KINETIS_CAN0_RXMGMASK (KINETIS_CAN0_BASE+KINETIS_CAN_RXMGMASK_OFFSET) +#define KINETIS_CAN0_RX14MASK (KINETIS_CAN0_BASE+KINETIS_CAN_RX14MASK_OFFSET) +#define KINETIS_CAN0_RX15MASK (KINETIS_CAN0_BASE+KINETIS_CAN_RX15MASK_OFFSET) +#define KINETIS_CAN0_ECR (KINETIS_CAN0_BASE+KINETIS_CAN_ECR_OFFSET) +#define KINETIS_CAN0_ESR1 (KINETIS_CAN0_BASE+KINETIS_CAN_ESR1_OFFSET) +#define KINETIS_CAN0_IMASK2 (KINETIS_CAN0_BASE+KINETIS_CAN_IMASK2_OFFSET) +#define KINETIS_CAN0_IMASK1 (KINETIS_CAN0_BASE+KINETIS_CAN_IMASK1_OFFSET) +#define KINETIS_CAN0_IFLAG2 (KINETIS_CAN0_BASE+KINETIS_CAN_IFLAG2_OFFSET) +#define KINETIS_CAN0_IFLAG1 (KINETIS_CAN0_BASE+KINETIS_CAN_IFLAG1_OFFSET) +#define KINETIS_CAN0_CTRL2 (KINETIS_CAN0_BASE+KINETIS_CAN_CTRL2_OFFSET) +#define KINETIS_CAN0_ESR2 (KINETIS_CAN0_BASE+KINETIS_CAN_ESR2_OFFSET) +#define KINETIS_CAN0_CRCR (KINETIS_CAN0_BASE+KINETIS_CAN_CRCR_OFFSET) +#define KINETIS_CAN0_RXFGMASK (KINETIS_CAN0_BASE+KINETIS_CAN_RXFGMASK_OFFSET) +#define KINETIS_CAN0_RXFIR (KINETIS_CAN0_BASE+KINETIS_CAN_RXFIR_OFFSET) + +#define KINETIS_CAN0_RXIMR(n) (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR_OFFSET(n)) +#define KINETIS_CAN0_RXIMR0 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR0_OFFSET) +#define KINETIS_CAN0_RXIMR1 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR1_OFFSET) +#define KINETIS_CAN0_RXIMR2 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR2_OFFSET) +#define KINETIS_CAN0_RXIMR3 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR3_OFFSET) +#define KINETIS_CAN0_RXIMR4 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR4_OFFSET) +#define KINETIS_CAN0_RXIMR5 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR5_OFFSET) +#define KINETIS_CAN0_RXIMR6 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR6_OFFSET) +#define KINETIS_CAN0_RXIMR7 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR7_OFFSET) +#define KINETIS_CAN0_RXIMR8 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR8_OFFSET) +#define KINETIS_CAN0_RXIMR9 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR9_OFFSET) +#define KINETIS_CAN0_RXIMR10 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR10_OFFSET) +#define KINETIS_CAN0_RXIMR11 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR11_OFFSET) +#define KINETIS_CAN0_RXIMR12 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR12_OFFSET) +#define KINETIS_CAN0_RXIMR13 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR13_OFFSET) +#define KINETIS_CAN0_RXIMR14 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR14_OFFSET) +#define KINETIS_CAN0_RXIMR15 (KINETIS_CAN0_BASE+KINETIS_CAN_RXIMR15_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Module Configuration Register */ + +#define CAN_MCR_MAXMB_SHIFT (0) /* Bits 0-6: Number of the Last Message Buffer */ +#define CAN_MCR_MAXMB_MASK (0x7f << CAN_MCR_MAXMB_SHIFT) + /* Bit 7: Reserved */ +#define CAN_MCR_IDAM_SHIFT (8) /* Bits 8-9: ID Acceptance Mode */ +#define CAN_MCR_IDAM_MASK (3 << CAN_MCR_IDAM_SHIFT) +# define CAN_MCR_IDAM_FMTA (0 << CAN_MCR_IDAM_SHIFT) /* Format A: One full ID */ +# define CAN_MCR_IDAM_FMTB (1 << CAN_MCR_IDAM_SHIFT) /* Format B: Two full (or partial) IDs */ +# define CAN_MCR_IDAM_FMTC (2 << CAN_MCR_IDAM_SHIFT) /* Format C: Four partial IDs */ +# define CAN_MCR_IDAM_FMTD (3 << CAN_MCR_IDAM_SHIFT) /* Format D: All frames rejected */ + /* Bits 10-11: Reserved */ +#define CAN_MCR_AEN (1 << 12) /* Bit 12: Abort Enable */ +#define CAN_MCR_LPRIOEN (1 << 13) /* Bit 13: Local Priority Enable */ + /* Bits 14-15: Reserved */ +#define CAN_MCR_IRMQ (1 << 16) /* Bit 16: Individual Rx Masking and Queue Enable */ +#define CAN_MCR_SRXDIS (1 << 17) /* Bit 17: Self Reception Disable */ +#define CAN_MCR_DOZE (1 << 18) /* Bit 18: Doze Mode Enable */ + /* Bit 19: Reserved */ +#define CAN_MCR_LPMACK (1 << 20) /* Bit 20: Low Power Mode Acknowledge */ +#define CAN_MCR_WRNEN (1 << 21) /* Bit 21: Warning Interrupt Enable */ +#define CAN_MCR_SLFWAK (1 << 22) /* Bit 22: Self Wake Up */ +#define CAN_MCR_SUPV (1 << 23) /* Bit 23: Supervisor Mode */ +#define CAN_MCR_FRZACK (1 << 24) /* Bit 24: Freeze Mode Acknowledge */ +#define CAN_MCR_SOFTRST (1 << 25) /* Bit 25: Soft Reset */ +#define CAN_MCR_WAKMSK (1 << 26) /* Bit 26: Wake Up Interrupt Mask */ +#define CAN_MCR_NOTRDY (1 << 27) /* Bit 27: FlexCAN Not Ready */ +#define CAN_MCR_HALT (1 << 28) /* Bit 28: Halt FlexCAN */ +#define CAN_MCR_RFEN (1 << 29) /* Bit 29: Rx FIFO Enable */ +#define CAN_MCR_FRZ (1 << 30) /* Bit 30: Freeze Enable */ +#define CAN_MCR_MDIS (1 << 31) /* Bit 31: Module Disable */ + +/* Control 1 Register */ + +#define CAN_CTRL1_ROPSEG_SHIFT (0) /* Bits 0-2: Propagation Segment */ +#define CAN_CTRL1_ROPSEG_MASK (7 << CAN_CTRL1_ROPSEG_SHIFT) +#define CAN_CTRL1_LOM (1 << 3) /* Bit 3: Listen-Only Mode */ +#define CAN_CTRL1_LBUF (1 << 4) /* Bit 4: Lowest Buffer Transmitted First */ +#define CAN_CTRL1_TSYN (1 << 5) /* Bit 5: Timer Sync */ +#define CAN_CTRL1_BOFFREC (1 << 6) /* Bit 6: Bus Off Recovery */ +#define CAN_CTRL1_SMP (1 << 7) /* Bit 7: CAN Bit Sampling */ + /* Bits 8-9: Reserved */ +#define CAN_CTRL1_RWRNMSK (1 << 10) /* Bit 10: Rx Warning Interrupt Mask */ +#define CAN_CTRL1_TWRNMSK (1 << 11) /* Bit 11: Tx Warning Interrupt Mask */ +#define CAN_CTRL1_LPB (1 << 12) /* Bit 12: Loop Back Mode */ +#define CAN_CTRL1_CLKSRC (1 << 13) /* Bit 13: CAN Engine Clock Source */ +#define CAN_CTRL1_ERRMSK (1 << 14) /* Bit 14: Error Mask */ +#define CAN_CTRL1_BOFFMSK (1 << 15) /* Bit 15: Bus Off Mask */ +#define CAN_CTRL1_PSEG2_SHIFT (16) /* Bits 16-18: Phase Segment 2 */ +#define CAN_CTRL1_PSEG2_MASK (7 << CAN_CTRL1_PSEG2_SHIFT) +#define CAN_CTRL1_PSEG1_SHIFT (19) /* Bits 19-21: Phase Segment 1 */ +#define CAN_CTRL1_PSEG1_MASK (7 << CAN_CTRL1_PSEG1_SHIFT) +#define CAN_CTRL1_RJW_SHIFT (22) /* Bits 22-23: Resync Jump Width */ +#define CAN_CTRL1_RJW_MASK (3 << CAN_CTRL1_RJW_SHIFT) +#define CAN_CTRL1_PRESDIV_SHIFT (24) /* Bits 24-31: Prescaler Division Factor */ +#define CAN_CTRL1_PRESDIV_MASK (0xff << CAN_CTRL1_PRESDIV_SHIFT) + +/* Free Running Timer */ + +#define CAN_TIMER_SHIFT (0) /* Bits 0-15: Timer value */ +#define CAN_TIMER_MASK (0xffff << CAN_TIMER_SHIFT) + /* Bits 16-31: Reserved */ +/* Rx Mailboxes Global Mask Register (32 Rx Mailboxes Global Mask Bits) */ + +#define CAN_RXMGMASK(n) (1 << (n)) /* Bit n: Rx Mailboxe n Global Mask Bit */ + +/* Rx 14 Mask Register */ + +#define CAN_RX14MASK(n) (1 << (n)) /* Bit n: Rx Buffer 14 Mask Bit n */ + +/* Rx 15 Mask Register */ + +#define CAN_RX15MASK(n) (1 << (n)) /* Bit n: Rx Buffer 15 Mask Bit n */ + +/* Error Counter */ + +#define CAN_ECR_TXERRCNT_SHIFT (0) /* Bits 0-7: Transmit Error Counter */ +#define CAN_ECR_TXERRCNT_MASK (0xff << CAN_ECR_TXERRCNT_SHIFT) +#define CAN_ECR_RXERRCNT_SHIFT (8) /* Bits 8-15: Receive Error Counter */ +#define CAN_ECR_RXERRCNT_MASK (0xff << CAN_ECR_RXERRCNT_SHIFT) + /* Bits 16-31: Reserved */ +/* Error and Status 1 Register */ + +#define CAN_ESR1_WAKINT (1 << 0) /* Bit 0: Wake-Up Interrupt */ +#define CAN_ESR1_ERRINT (1 << 1) /* Bit 1: Error Interrupt */ +#define CAN_ESR1_BOFFINT (1 << 2) /* Bit 2: 'Bus Off' Interrupt */ +#define CAN_ESR1_RX (1 << 3) /* Bit 3: FlexCAN in Reception */ +#define CAN_ESR1_FLTCONF_SHIFT (4) /* Bits 4-5: Fault Confinement State */ +#define CAN_ESR1_FLTCONF_MASK (3 << CAN_ESR1_FLTCONF_SHIFT) +# define CAN_ESR1_FLTCONF_ACTV (0 << CAN_ESR1_FLTCONF_SHIFT) /* Error Active */ +# define CAN_ESR1_FLTCONF_PASV (1 << CAN_ESR1_FLTCONF_SHIFT) /* Error Passive */ +# define CAN_ESR1_FLTCONF_OFF (2 << CAN_ESR1_FLTCONF_SHIFT) /* Bus Off */ +#define CAN_ESR1_TX (1 << 6) /* Bit 6: FlexCAN in Transmission */ +#define CAN_ESR1_IDLE (1 << 7) /* Bit 7: CAN bus is in IDLE state */ +#define CAN_ESR1_RXWRN (1 << 8) /* Bit 8: Rx Error Warning */ +#define CAN_ESR1_TXWRN (1 << 9) /* Bit 9: TX Error Warning */ +#define CAN_ESR1_STFERR (1 << 10) /* Bit 10: Stuffing Error */ +#define CAN_ESR1_FRMERR (1 << 11) /* Bit 11: Form Error */ +#define CAN_ESR1_CRCERR (1 << 12) /* Bit 12: Cyclic Redundancy Check Error */ +#define CAN_ESR1_ACKERR (1 << 13) /* Bit 13: Acknowledge Error */ +#define CAN_ESR1_BIT0ERR (1 << 14) /* Bit 14: Bit0 Error */ +#define CAN_ESR1_BIT1ERR (1 << 15) /* Bit 15: Bit1 Error */ +#define CAN_ESR1_RWRNINT (1 << 16) /* Bit 16: Rx Warning Interrupt Flag */ +#define CAN_ESR1_TWRNINT (1 << 17) /* Bit 17: Tx Warning Interrupt Flag */ +#define CAN_ESR1_SYNCH (1 << 18) /* Bit 18: CAN Synchronization Status */ + /* Bits 19-31: Reserved */ +/* Interrupt Masks 2 Register */ + +#define CAN_IMASK2(n) (1 << (n)) /* Bit n: Buffer MBn Mask */ + +/* Interrupt Masks 1 Register */ + +#define CAN_IMASK1(n) (1 << (n)) /* Bit n: Buffer MBn Mask */ + +/* Interrupt Flags 2 Register */ + +#define CAN_IFLAG2(n) (1 << (n)) /* Bit n: Buffer MBn Interrupt */ + +/* Interrupt Flags 1 Register */ + +#define CAN_IFLAG1(n) (1 << (n)) /* Bit n: Buffer MBn Interrupt, n=0..4,8..31 */ + +/* Control 2 Register */ + /* Bits 0-15: Reserved */ +#define CAN_CTRL2_EACEN (1 << 16) /* Bit 16: Entire Frame Arbitration Field Comparison Enable (Rx) */ +#define CAN_CTRL2_RRS (1 << 17) /* Bit 17: Remote Request Storing */ +#define CAN_CTRL2_MRP (1 << 18) /* Bit 18: Mailboxes Reception Priority */ +#define CAN_CTRL2_TASD_SHIFT (19) /* Bits 19-23: Tx Arbitration Start Delay */ +#define CAN_CTRL2_TASD_MASK (31 << CAN_CTRL2_TASD_SHIFT) +#define CAN_CTRL2_RFFN_SHIFT (24) /* Bits 24-27: Number of Rx FIFO Filters */ +#define CAN_CTRL2_RFFN_MASK (15 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_8MB (0 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_16MB (1 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_24MB (2 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_32MB (3 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_40MB (4 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_48MB (5 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_56MB (6 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_64MB (7 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_72MB (8 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_80MB (9 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_88MB (10 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_96MB (11 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_104MB (12 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_112MB (13 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_120MB (14 << CAN_CTRL2_RFFN_SHIFT) +# define CAN_CTRL2_RFFN_128MB (15 << CAN_CTRL2_RFFN_SHIFT) +#define CAN_CTRL2_WRMFRZ (1 << 28) /* Bit 28: Write-Access to Memory in Freeze mode */ + /* Bits 29-31: Reserved */ +/* Error and Status 2 Register */ + /* Bits 0-12: Reserved */ +#define CAN_ESR2_IMB (1 << 13) /* Bit 13: Inactive Mailbox */ +#define CAN_ESR2_VPS (1 << 14) /* Bit 14: Valid Priority Status */ + /* Bit 15: Reserved */ +#define CAN_ESR2_VPS (1 << 14) /* Bit 14: Valid Priority Status */ +#define CAN_ESR2_LPTM_SHIFT (16) /* Bits 16-22: Lowest Priority Tx Mailbox */ +#define CAN_ESR2_LPTM_MASK (0x7f << CAN_ESR2_LPTM_SHIFT) + /* Bits 23-31: Reserved */ +/* CRC Register */ + /* Bits 23-31: Reserved */ +#define CAN_CRCR_MBCRC_SHIFT (16) /* Bits 16-22: CRC Mailbox */ +#define CAN_CRCR_MBCRC_MASK (0x7f << CAN_CRCR_MBCRC_SHIFT) + /* Bit 15: Reserved */ +#define CAN_CRCR_TXCRC_SHIFT (0) /* Bits 0-14: CRC Transmitted */ +#define CAN_CRCR_TXCRC_MASK (0x7fff << CAN_CRCR_TXCRC_SHIFT) + +/* Rx FIFO Global Mask Register (32 Rx FIFO Global Mask Bits) */ + +/* Rx FIFO Information Register */ + /* Bits 9-31: Reserved */ +#define CAN_RXFIR_IDHIT_SHIFT (0) /* Bits 0-8: Identifier Acceptance Filter Hit Indicator */ +#define CAN_RXFIR_IDHIT_MASK (0x1ff << CAN_RXFIR_IDHIT_SHIFT) + +/* Rn Individual Mask Registers */ + +#define CAN_RXIMR(n) (1 << (n)) /* Bit n: Individual Mask Bits */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H */ diff --git a/arch/arm/src/kinetis/kinetis_fmc.h b/arch/arm/src/kinetis/kinetis_fmc.h new file mode 100644 index 0000000000000000000000000000000000000000..66f3a390926777330a36fed3374cc2a7632741d7 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_fmc.h @@ -0,0 +1,389 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_fmc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_FMC_PFAPR_OFFSET 0x0000 /* Flash Access Protection Register */ +#define KINETIS_FMC_PFB0CR_OFFSET 0x0004 /* Flash Bank 0 Control Register */ +#define KINETIS_FMC_PFB1CR_OFFSET 0x0008 /* Flash Bank 1 Control Register */ + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define KINETIS_FMC_TAGVD_OFFSET(w,s) (0x100+((w)<<5)+((s)<<2)) + +#define KINETIS_FMC_TAGVDW0S0_OFFSET 0x0100 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S1_OFFSET 0x0104 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S2_OFFSET 0x0108 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S3_OFFSET 0x010c /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S4_OFFSET 0x0110 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S5_OFFSET 0x0114 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S6_OFFSET 0x0118 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW0S7_OFFSET 0x011c /* Cache Directory Storage */ + +#define KINETIS_FMC_TAGVDW1S0_OFFSET 0x0120 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S1_OFFSET 0x0124 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S2_OFFSET 0x0128 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S3_OFFSET 0x012c /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S4_OFFSET 0x0130 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S5_OFFSET 0x0134 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S6_OFFSET 0x0138 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW1S7_OFFSET 0x013c /* Cache Directory Storage */ + +#define KINETIS_FMC_TAGVDW2S0_OFFSET 0x0140 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S1_OFFSET 0x0144 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S2_OFFSET 0x0148 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S3_OFFSET 0x014c /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S4_OFFSET 0x0150 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S5_OFFSET 0x0154 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S6_OFFSET 0x0158 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW2S7_OFFSET 0x015c /* Cache Directory Storage */ + +#define KINETIS_FMC_TAGVDW3S0_OFFSET 0x0160 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S1_OFFSET 0x0164 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S2_OFFSET 0x0168 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S3_OFFSET 0x016c /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S4_OFFSET 0x0170 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S5_OFFSET 0x0174 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S6_OFFSET 0x0178 /* Cache Directory Storage */ +#define KINETIS_FMC_TAGVDW3S7_OFFSET 0x017c /* Cache Directory Storage */ + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */ + +#define KINETIS_FMC_DATAU_OFFSET(w,s) (0x200+((w)<<6)+((s)<<2)) +#define KINETIS_FMC_DATAL_OFFSET(w,s) (0x204+((w)<<6)+((s)<<2)) + +#define KINETIS_FMC_DATAW0S0U_OFFSET 0x0200 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S0L_OFFSET 0x0204 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S1U_OFFSET 0x0208 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S1L_OFFSET 0x020c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S2U_OFFSET 0x0210 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S2L_OFFSET 0x0214 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S3U_OFFSET 0x0218 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S3L_OFFSET 0x021c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S4U_OFFSET 0x0220 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S4L_OFFSET 0x0224 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S5U_OFFSET 0x0228 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S5L_OFFSET 0x022c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S6U_OFFSET 0x0230 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S6L_OFFSET 0x0234 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW0S7U_OFFSET 0x0238 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW0S7L_OFFSET 0x023c /* Cache Data Storage (lower word) */ + +#define KINETIS_FMC_DATAW1S0U_OFFSET 0x0240 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S0L_OFFSET 0x0244 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S1U_OFFSET 0x0248 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S1L_OFFSET 0x024c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S2U_OFFSET 0x0250 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S2L_OFFSET 0x0254 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S3U_OFFSET 0x0258 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S3L_OFFSET 0x025c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S4U_OFFSET 0x0260 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S4L_OFFSET 0x0264 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S5U_OFFSET 0x0268 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S5L_OFFSET 0x026c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S6U_OFFSET 0x0270 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S6L_OFFSET 0x0274 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW1S7U_OFFSET 0x0278 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW1S7L_OFFSET 0x027c /* Cache Data Storage (lower word) */ + +#define KINETIS_FMC_DATAW2S0U_OFFSET 0x0280 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S0L_OFFSET 0x0284 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S1U_OFFSET 0x0288 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S1L_OFFSET 0x028c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S2U_OFFSET 0x0290 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S2L_OFFSET 0x0294 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S3U_OFFSET 0x0298 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S3L_OFFSET 0x029c /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S4U_OFFSET 0x02a0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S4L_OFFSET 0x02a4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S5U_OFFSET 0x02a8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S5L_OFFSET 0x02ac /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S6U_OFFSET 0x02b0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S6L_OFFSET 0x02b4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW2S7U_OFFSET 0x02b8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW2S7L_OFFSET 0x02bc /* Cache Data Storage (lower word) */ + +#define KINETIS_FMC_DATAW3S0U_OFFSET 0x02c0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S0L_OFFSET 0x02c4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S1U_OFFSET 0x02c8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S1L_OFFSET 0x02cc /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S2U_OFFSET 0x02d0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S2L_OFFSET 0x02d4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S3U_OFFSET 0x02d8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S3L_OFFSET 0x02dc /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S4U_OFFSET 0x02e0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S4L_OFFSET 0x02e4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S5U_OFFSET 0x02e8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S5L_OFFSET 0x02ec /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S6U_OFFSET 0x02f0 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S6L_OFFSET 0x02f4 /* Cache Data Storage (lower word) */ +#define KINETIS_FMC_DATAW3S7U_OFFSET 0x02f8 /* Cache Data Storage (upper word) */ +#define KINETIS_FMC_DATAW3S7L_OFFSET 0x02fc /* Cache Data Storage (lower word) */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_FMC_PFAPR (KINETIS_FMC_BASE+KINETIS_FMC_PFAPR_OFFSET) +#define KINETIS_FMC_PFB0CR (KINETIS_FMC_BASE+KINETIS_FMC_PFB0CR_OFFSET) +#define KINETIS_FMC_PFB1CR (KINETIS_FMC_BASE+KINETIS_FMC_PFB1CR_OFFSET) + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define KINETIS_FMC_TAGVD(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_TAGVD_OFFSET(w,s)) + +#define KINETIS_FMC_TAGVDW0S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S0_OFFSET) +#define KINETIS_FMC_TAGVDW0S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S1_OFFSET) +#define KINETIS_FMC_TAGVDW0S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S2_OFFSET) +#define KINETIS_FMC_TAGVDW0S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S3_OFFSET) +#define KINETIS_FMC_TAGVDW0S4 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S4_OFFSET) +#define KINETIS_FMC_TAGVDW0S5 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S5_OFFSET) +#define KINETIS_FMC_TAGVDW0S6 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S6_OFFSET) +#define KINETIS_FMC_TAGVDW0S7 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S7_OFFSET) + +#define KINETIS_FMC_TAGVDW1S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S0_OFFSET) +#define KINETIS_FMC_TAGVDW1S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S1_OFFSET) +#define KINETIS_FMC_TAGVDW1S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S2_OFFSET) +#define KINETIS_FMC_TAGVDW1S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S3_OFFSET) +#define KINETIS_FMC_TAGVDW1S4 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S4_OFFSET) +#define KINETIS_FMC_TAGVDW1S5 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S5_OFFSET) +#define KINETIS_FMC_TAGVDW1S6 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S6_OFFSET) +#define KINETIS_FMC_TAGVDW1S7 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S7_OFFSET) + +#define KINETIS_FMC_TAGVDW2S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S0_OFFSET) +#define KINETIS_FMC_TAGVDW2S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S1_OFFSET) +#define KINETIS_FMC_TAGVDW2S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S2_OFFSET) +#define KINETIS_FMC_TAGVDW2S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S3_OFFSET) +#define KINETIS_FMC_TAGVDW2S4 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S4_OFFSET) +#define KINETIS_FMC_TAGVDW2S5 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S5_OFFSET) +#define KINETIS_FMC_TAGVDW2S6 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S6_OFFSET) +#define KINETIS_FMC_TAGVDW2S7 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S7_OFFSET) + +#define KINETIS_FMC_TAGVDW3S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S0_OFFSET) +#define KINETIS_FMC_TAGVDW3S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S1_OFFSET) +#define KINETIS_FMC_TAGVDW3S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S2_OFFSET) +#define KINETIS_FMC_TAGVDW3S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S3_OFFSET) +#define KINETIS_FMC_TAGVDW3S4 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S4_OFFSET) +#define KINETIS_FMC_TAGVDW3S5 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S5_OFFSET) +#define KINETIS_FMC_TAGVDW3S6 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S6_OFFSET) +#define KINETIS_FMC_TAGVDW3S7 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S7_OFFSET) + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */ + +#define KINETIS_FMC_DATAU(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_DATAU_OFFSET(w,s)) +#define KINETIS_FMC_DATAL(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_DATAL_OFFSET(w,s)) + +#define KINETIS_FMC_DATAW0S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S0U_OFFSET) +#define KINETIS_FMC_DATAW0S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S0L_OFFSET) +#define KINETIS_FMC_DATAW0S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S1U_OFFSET) +#define KINETIS_FMC_DATAW0S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S1L_OFFSET) +#define KINETIS_FMC_DATAW0S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S2U_OFFSET) +#define KINETIS_FMC_DATAW0S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S2L_OFFSET) +#define KINETIS_FMC_DATAW0S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S3U_OFFSET) +#define KINETIS_FMC_DATAW0S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S3L_OFFSET) +#define KINETIS_FMC_DATAW0S4U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S4U_OFFSET) +#define KINETIS_FMC_DATAW0S4L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S4L_OFFSET) +#define KINETIS_FMC_DATAW0S5U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S5U_OFFSET) +#define KINETIS_FMC_DATAW0S5L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S5L_OFFSET) +#define KINETIS_FMC_DATAW0S6U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S6U_OFFSET) +#define KINETIS_FMC_DATAW0S6L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S6L_OFFSET) +#define KINETIS_FMC_DATAW0S7U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S7U_OFFSET) +#define KINETIS_FMC_DATAW0S7L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S7L_OFFSET) + +#define KINETIS_FMC_DATAW1S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S0U_OFFSET) +#define KINETIS_FMC_DATAW1S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S0L_OFFSET) +#define KINETIS_FMC_DATAW1S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S1U_OFFSET) +#define KINETIS_FMC_DATAW1S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S1L_OFFSET) +#define KINETIS_FMC_DATAW1S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S2U_OFFSET) +#define KINETIS_FMC_DATAW1S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S2L_OFFSET) +#define KINETIS_FMC_DATAW1S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S3U_OFFSET) +#define KINETIS_FMC_DATAW1S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S3L_OFFSET) +#define KINETIS_FMC_DATAW1S4U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S4U_OFFSET) +#define KINETIS_FMC_DATAW1S4L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S4L_OFFSET) +#define KINETIS_FMC_DATAW1S5U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S5U_OFFSET) +#define KINETIS_FMC_DATAW1S5L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S5L_OFFSET) +#define KINETIS_FMC_DATAW1S6U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S6U_OFFSET) +#define KINETIS_FMC_DATAW1S6L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S6L_OFFSET) +#define KINETIS_FMC_DATAW1S7U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S7U_OFFSET) +#define KINETIS_FMC_DATAW1S7L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S7L_OFFSET) + +#define KINETIS_FMC_DATAW2S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S0U_OFFSET) +#define KINETIS_FMC_DATAW2S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S0L_OFFSET) +#define KINETIS_FMC_DATAW2S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S1U_OFFSET) +#define KINETIS_FMC_DATAW2S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S1L_OFFSET) +#define KINETIS_FMC_DATAW2S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S2U_OFFSET) +#define KINETIS_FMC_DATAW2S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S2L_OFFSET) +#define KINETIS_FMC_DATAW2S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S3U_OFFSET) +#define KINETIS_FMC_DATAW2S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S3L_OFFSET) +#define KINETIS_FMC_DATAW2S4U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S4U_OFFSET) +#define KINETIS_FMC_DATAW2S4L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S4L_OFFSET) +#define KINETIS_FMC_DATAW2S5U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S5U_OFFSET) +#define KINETIS_FMC_DATAW2S5L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S5L_OFFSET) +#define KINETIS_FMC_DATAW2S6U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S6U_OFFSET) +#define KINETIS_FMC_DATAW2S6L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S6L_OFFSET) +#define KINETIS_FMC_DATAW2S7U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S7U_OFFSET) +#define KINETIS_FMC_DATAW2S7L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S7L_OFFSET) + +#define KINETIS_FMC_DATAW3S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S0U_OFFSET) +#define KINETIS_FMC_DATAW3S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S0L_OFFSET) +#define KINETIS_FMC_DATAW3S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S1U_OFFSET) +#define KINETIS_FMC_DATAW3S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S1L_OFFSET) +#define KINETIS_FMC_DATAW3S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S2U_OFFSET) +#define KINETIS_FMC_DATAW3S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S2L_OFFSET) +#define KINETIS_FMC_DATAW3S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S3U_OFFSET) +#define KINETIS_FMC_DATAW3S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S3L_OFFSET) +#define KINETIS_FMC_DATAW3S4U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S4U_OFFSET) +#define KINETIS_FMC_DATAW3S4L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S4L_OFFSET) +#define KINETIS_FMC_DATAW3S5U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S5U_OFFSET) +#define KINETIS_FMC_DATAW3S5L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S5L_OFFSET) +#define KINETIS_FMC_DATAW3S6U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S6U_OFFSET) +#define KINETIS_FMC_DATAW3S6L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S6L_OFFSET) +#define KINETIS_FMC_DATAW3S7U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S7U_OFFSET) +#define KINETIS_FMC_DATAW3S7L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S7L_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Flash Access Protection Register */ +/* Access protection bits (all masters) */ + +#define FMC_PFAPR_NONE 0 /* No access may be performed by this master */ +#define FMC_PFAPR_RDONLY 1 /* Only read accesses may be performed by this master */ +#define FMC_PFAPR_WRONLY 2 /* Only write accesses may be performed by this master */ +#define FMC_PFAPR_RDWR 3 /* Both read and write accesses may be performed by this master */ + +#define FMC_PFAPR_M0AP_SHIFT (0) /* Bits 0-1: Master 0 Access Protection */ +#define FMC_PFAPR_M0AP_MASK (3 << FMC_PFAPR_M0AP_SHIFT) +#define FMC_PFAPR_M1AP_SHIFT (2) /* Bits 2-3: Master 1 Access Protection */ +#define FMC_PFAPR_M1AP_MASK (3 << FMC_PFAPR_M1AP_SHIFT) +#define FMC_PFAPR_M2AP_SHIFT (4) /* Bits 4-5: Master 2 Access Protection */ +#define FMC_PFAPR_M2AP_MASK (3 << FMC_PFAPR_M2AP_SHIFT) +#define FMC_PFAPR_M3AP_SHIFT (6) /* Bits 6-7: Master 3 Access Protection */ +#define FMC_PFAPR_M3AP_MASK (3 << FMC_PFAPR_M3AP_SHIFT) +#define FMC_PFAPR_M4AP_SHIFT (8) /* Bits 8-9: Master 4 Access Protection */ +#define FMC_PFAPR_M4AP_MASK (3 << FMC_PFAPR_M4AP_SHIFT) +#define FMC_PFAPR_M5AP_SHIFT (10) /* Bits 10-11: Master 5 Access Protection */ +#define FMC_PFAPR_M5AP_MASK (3 << FMC_PFAPR_M5AP_SHIFT) +#define FMC_PFAPR_M6AP_SHIFT (12) /* Bits 12-13: Master 6 Access Protection */ +#define FMC_PFAPR_M6AP_MASK (3 << FMC_PFAPR_M6AP_SHIFT) +#define FMC_PFAPR_M7AP_SHIFT (14) /* Bits 14-15: Master 7 Access Protection */ +#define FMC_PFAPR_M7AP_MASK (3 << FMC_PFAPR_M7AP_SHIFT) +#define FMC_PFAPR_M0PFD (1 << 16) /* Bit 16: Master 0 Prefetch Disable */ +#define FMC_PFAPR_M1PFD (1 << 17) /* Bit 17: Master 1 Prefetch Disable */ +#define FMC_PFAPR_M2PFD (1 << 18) /* Bit 18: Master 2 Prefetch Disable */ +#define FMC_PFAPR_M3PFD (1 << 19) /* Bit 19: Master 3 Prefetch Disable */ +#define FMC_PFAPR_M4PFD (1 << 20) /* Bit 20: Master 4 Prefetch Disable */ +#define FMC_PFAPR_M5PFD (1 << 21) /* Bit 21: Master 5 Prefetch Disable */ +#define FMC_PFAPR_M6PFD (1 << 22) /* Bit 22: Master 6 Prefetch Disable */ +#define FMC_PFAPR_M7PFD (1 << 23) /* Bit 23: Master 7 Prefetch Disable */ + /* Bits 24-31: Reserved */ +/* Flash Bank 0 Control Register */ + +#define FMC_PFB0CR_B0SEBE (1 << 0) /* Bit 0: Bank 0 Single Entry Buffer Enable */ +#define FMC_PFB0CR_B0IPE (1 << 1) /* Bit 1: Bank 0 Instruction Prefetch Enable */ +#define FMC_PFB0CR_B0DPE (1 << 2) /* Bit 2: Bank 0 Data Prefetch Enable */ +#define FMC_PFB0CR_B0ICE (1 << 3) /* Bit 3: Bank 0 Instruction Cache Enable */ +#define FMC_PFB0CR_B0DCE (1 << 4) /* Bit 4: Bank 0 Data Cache Enable */ +#define FMC_PFB0CR_CRC_SHIFT (5) /* Bits 5-7: Cache Replacement Control */ +#define FMC_PFB0CR_CRC_MASK (7 << FMC_PFB0CR_CRC_SHIFT) +# define FMC_PFB0CR_CRC_ALL (0 << FMC_PFB0CR_CRC_SHIFT) /* LRU all four ways */ +# define FMC_PFB0CR_CRC_I01D23 (2 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-1 data 2-3 */ +# define FMC_PFB0CR_CRC_I012D3 (3 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-3 data 3 */ + /* Bits 8-16: Reserved */ +#define FMC_PFB0CR_B0MW_SHIFT (17) /* Bits 17-18: Bank 0 Memory Width */ +#define FMC_PFB0CR_B0MW_MASK (3 << FMC_PFB0CR_B0MW_SHIFT) +# define FMC_PFB0CR_B0MW_32BITS (0 << FMC_PFB0CR_B0MW_SHIFT) /* 32 bits */ +# define FMC_PFB0CR_B0MW_64BITS (1 << FMC_PFB0CR_B0MW_SHIFT) /* 64 bits */ +#define FMC_PFB0CR_S_B_INV (1 << 19) /* Bit 19: Invalidate Prefetch Speculation Buffer */ +#define FMC_PFB0CR_CINV_WAY_SHIFT (20) /* Bits 20-23: Cache Invalidate Way x */ +#define FMC_PFB0CR_CINV_WAY_MASK (15 << FMC_PFB0CR_CINV_WAY_SHIFT) +#define FMC_PFB0CR_CLCK_WAY_SHIFT (24) /* Bits 24-27: Cache Lock Way x */ +#define FMC_PFB0CR_CLCK_WAY_MASK (15 << FMC_PFB0CR_CLCK_WAY_SHIFT) +#define FMC_PFB0CR_B0RWSC_SHIFT (28) /* Bits 28-31: Bank 0 Read Wait State Control */ +#define FMC_PFB0CR_B0RWSC_MASK (15 << FMC_PFB0CR_B0RWSC_SHIFT) + +/* Flash Bank 1 Control Register */ + +#define FMC_PFB1CR_B1SEBE (1 << 0) /* Bit 0: Bank 1 Single Entry Buffer Enable */ +#define FMC_PFB1CR_B1IPE (1 << 1) /* Bit 1: Bank 1 Instruction Prefetch Enable */ +#define FMC_PFB1CR_B1DPE (1 << 2) /* Bit 2: Bank 1 Data Prefetch Enable */ +#define FMC_PFB1CR_B1ICE (1 << 3) /* Bit 3: Bank 1 Instruction Cache Enable */ +#define FMC_PFB1CR_B1DCE (1 << 4) /* Bit 4: Bank 1 Data Cache Enable */ + /* Bits 5-16: Reserved */ +#define FMC_PFB1CR_B1MW_SHIFT (17) /* Bits 17-18: Bank 1 Memory Width */ +#define FMC_PFB1CR_B1MW_MASK (3 << FMC_PFB1CR_B1MW_SHIFT) +# define FMC_PFB1CR_B1MW_32BITS (0 << FMC_PFB1CR_B1MW_SHIFT) /* 32 bits */ +# define FMC_PFB1CR_B1MW_64BITS (1 << FMC_PFB1CR_B1MW_SHIFT) /* 64 bits */ + /* Bits 19-27: Reserved */ +#define FMC_PFB1CR_B1RWSC_SHIFT (28) /* Bits 28-31: Bank 1 Read Wait State Control */ +#define FMC_PFB1CR_B1RWSC_MASK (15 << FMC_PFB1CR_B0RWSC_SHIFT) + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define FMC_TAGVD_VALID (1 << 0) /* Bit 0: 1-bit valid for cache entry */ + /* Bits 1-5: Reserved */ +#define FMC_TAGVD_TAG_SHIFT (6) /* Bits 6-18: 13-bit tag for cache entry */ +#define FMC_TAGVD_TAG_MASK (0x1fff << FMC_TAGVD_TAG_SHIFT) + /* Bits 19-31: Reserved */ + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7. + * 64-bit data in two 32-bit registers. + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H */ diff --git a/arch/arm/src/kinetis/kinetis_ftfl.h b/arch/arm/src/kinetis/kinetis_ftfl.h new file mode 100644 index 0000000000000000000000000000000000000000..92e53b650d03d2cfbaf6ba3b3cd9427304069d8d --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_ftfl.h @@ -0,0 +1,159 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_ftfl.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_FTFL_FSTAT_OFFSET 0x0000 /* Flash Status Register */ +#define KINETIS_FTFL_FCNFG_OFFSET 0x0001 /* Flash Configuration Register */ +#define KINETIS_FTFL_FSEC_OFFSET 0x0002 /* Flash Security Register */ +#define KINETIS_FTFL_FOPT_OFFSET 0x0003 /* Flash Option Register */ + +#define KINETIS_FTFL_FCCOB3_OFFSET 0x0004 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB2_OFFSET 0x0005 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB1_OFFSET 0x0006 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB0_OFFSET 0x0007 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB7_OFFSET 0x0008 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB6_OFFSET 0x0009 /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB5_OFFSET 0x000a /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB4_OFFSET 0x000b /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOBB_OFFSET 0x000c /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOBA_OFFSET 0x000d /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB9_OFFSET 0x000e /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FCCOB8_OFFSET 0x000f /* Flash Common Command Object Registers */ +#define KINETIS_FTFL_FPROT3_OFFSET 0x0010 /* Program Flash Protection Registers */ +#define KINETIS_FTFL_FPROT2_OFFSET 0x0011 /* Program Flash Protection Registers */ +#define KINETIS_FTFL_FPROT1_OFFSET 0x0012 /* Program Flash Protection Registers */ +#define KINETIS_FTFL_FPROT0_OFFSET 0x0013 /* Program Flash Protection Registers */ +#define KINETIS_FTFL_FEPROT_OFFSET 0x0016 /* EEPROM Protection Register */ +#define KINETIS_FTFL_FDPROT_OFFSET 0x0017 /* Data Flash Protection Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_FTFL_FSTAT (KINETIS_FTFL_BASE+KINETIS_FTFL_FSTAT_OFFSET) +#define KINETIS_FTFL_FCNFG (KINETIS_FTFL_BASE+KINETIS_FTFL_FCNFG_OFFSET) +#define KINETIS_FTFL_FSEC (KINETIS_FTFL_BASE+KINETIS_FTFL_FSEC_OFFSET) +#define KINETIS_FTFL_FOPT (KINETIS_FTFL_BASE+KINETIS_FTFL_FOPT_OFFSET) +#define KINETIS_FTFL_FCCOB3 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB3_OFFSET) +#define KINETIS_FTFL_FCCOB2 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB2_OFFSET) +#define KINETIS_FTFL_FCCOB1 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB1_OFFSET) +#define KINETIS_FTFL_FCCOB0 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB0_OFFSET) +#define KINETIS_FTFL_FCCOB7 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB7_OFFSET) +#define KINETIS_FTFL_FCCOB6 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB6_OFFSET) +#define KINETIS_FTFL_FCCOB5 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB5_OFFSET) +#define KINETIS_FTFL_FCCOB4 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB4_OFFSET) +#define KINETIS_FTFL_FCCOBB (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOBB_OFFSET) +#define KINETIS_FTFL_FCCOBA (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOBA_OFFSET) +#define KINETIS_FTFL_FCCOB9 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB9_OFFSET) +#define KINETIS_FTFL_FCCOB8 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB8_OFFSET) +#define KINETIS_FTFL_FPROT3 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT3_OFFSET) +#define KINETIS_FTFL_FPROT2 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT2_OFFSET) +#define KINETIS_FTFL_FPROT1 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT1_OFFSET) +#define KINETIS_FTFL_FPROT0 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT0_OFFSET) +#define KINETIS_FTFL_FEPROT (KINETIS_FTFL_BASE+KINETIS_FTFL_FEPROT_OFFSET) +#define KINETIS_FTFL_FDPROT (KINETIS_FTFL_BASE+KINETIS_FTFL_FDPROT_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Flash Status Register */ + +#define FTFL_FSTAT_MGSTAT0 (1 << 0) /* Bit 0: Memory Controller Command Completion Status Flag */ + /* Bits 1-3: Reserved */ +#define FTFL_FSTAT_FPVIOL (1 << 4) /* Bit 4: Flash Protection Violation Flag */ +#define FTFL_FSTAT_ACCERR (1 << 5) /* Bit 5: Flash Access Error Flag */ +#define FTFL_FSTAT_RDCOLERR (1 << 6) /* Bit 6: FTFL Read Collision Error Flag */ +#define FTFL_FSTAT_CCIF (1 << 7) /* Bit 7: Command Complete Interrupt Flag */ + +/* Flash Configuration Register */ + +#define FTFL_FCNFG_EEERDY (1 << 0) /* Bit 0: FEEPROM backup data copied to FlexRAM */ +#define FTFL_FCNFG_RAMRDY (1 << 1) /* Bit 1: RAM Ready */ +#define FTFL_FCNFG_PFLSH (1 << 2) /* Bit 2: FTFL configuration */ +#define FTFL_FCNFG_SWAP (1 << 3) /* Bit 3: Swap */ +#define FTFL_FCNFG_ERSSUSP (1 << 4) /* Bit 4: Erase Suspend */ +#define FTFL_FCNFG_ERSAREQ (1 << 5) /* Bit 5: Erase All Request */ +#define FTFL_FCNFG_RDCOLLIE (1 << 6) /* Bit 6: Read Collision Error Interrupt Enable */ +#define FTFL_FCNFG_CCIE (1 << 7) /* Bit 7: Command Complete Interrupt Enable */ + +/* Flash Security Register */ + +#define FTFL_FSEC_SEC_SHIFT (0) /* Bits 0-1: Flash Security */ +#define FTFL_FSEC_SEC_MASK (3 << FTFL_FSEC_SEC_SHIFT) +# define FTFL_FSEC_SEC_SECURE (0 << FTFL_FSEC_SEC_SHIFT) /* 00,01,11: status is secure */ +# define FTFL_FSEC_SEC_UNSECURE (2 << FTFL_FSEC_SEC_SHIFT) /* 10: status is insecure */ +#define FTFL_FSEC_FSLACC_SHIFT (2) /* Bits 2-3: Freescale Failure Analysis Access Code */ +#define FTFL_FSEC_FSLACC_MASK (3 << FTFL_FSEC_FSLACC_SHIFT) +# define FTFL_FSEC_FSLACC_GRANTED (0 << FTFL_FSEC_FSLACC_SHIFT) /* 00 or 11: Access granted */ +# define FTFL_FSEC_FSLACC_DENIED (1 << FTFL_FSEC_FSLACC_SHIFT) /* 01 or 10: Access denied */ +#define FTFL_FSEC_MEEN_SHIFT (4) /* Bits 4-5: Mass Erase Enable Bits */ +#define FTFL_FSEC_MEEN_MASK (3 << FTFL_FSEC_MEEN_SHIFT) +# define FTFL_FSEC_MEEN_ENABLED (0 << FTFL_FSEC_MEEN_SHIFT) /* All values are enabled */ +#define FTFL_FSEC_KEYEN_SHIFT (6) /* Bits 6-7: Backdoor Key Security Enable */ +#define FTFL_FSEC_KEYEN_MASK (3 << FTFL_FSEC_KEYEN_SHIFT) +# define FTFL_FSEC_KEYEN_DISABLED (1 << FTFL_FSEC_KEYEN_SHIFT) /* All values are disabled */ + +/* Flash Option Register (32-bits, see Chip Configuration details) */ +/* Flash Common Command Object Registers (8-bit flash command data) */ +/* Program Flash Protection Registers (8-bit flash protection data) */ +/* EEPROM Protection Register (8-bit eeprom protection data) */ +/* Data Flash Protection Register (8-bit data flash protection data) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H */ diff --git a/arch/arm/src/kinetis/kinetis_ftm.h b/arch/arm/src/kinetis/kinetis_ftm.h new file mode 100644 index 0000000000000000000000000000000000000000..2f031b5dd9b68e6e1d71831b638a213f72478d04 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_ftm.h @@ -0,0 +1,528 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_ftm.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_FTM_SC_OFFSET 0x0000 /* Status and Control */ +#define KINETIS_FTM_CNT_OFFSET 0x0004 /* Counter */ +#define KINETIS_FTM_MOD_OFFSET 0x0008 /* Modulo */ + +#define KINETIS_FTM_CSC_OFFSET(n) (0x000c+((n)<<3)) /* Channel (n) Status and Control */ +#define KINETIS_FTM_CV_OFFSET(n) (0x0010+((n)<<3)) /* Channel (n) Value */ +#define KINETIS_FTM_C0SC_OFFSET 0x000c /* Channel 0 Status and Control */ +#define KINETIS_FTM_C0V_OFFSET 0x0010 /* Channel 0 Value */ +#define KINETIS_FTM_C1SC_OFFSET 0x0014 /* Channel 1 Status and Control */ +#define KINETIS_FTM_C1V_OFFSET 0x0018 /* Channel 1 Value */ +#define KINETIS_FTM_C2SC_OFFSET 0x001c /* Channel 2 Status and Control */ +#define KINETIS_FTM_C2V_OFFSET 0x0020 /* Channel 2 Value */ +#define KINETIS_FTM_C3SC_OFFSET 0x0024 /* Channel 3 Status and Control */ +#define KINETIS_FTM_C3V_OFFSET 0x0028 /* Channel 3 Value */ +#define KINETIS_FTM_C4SC_OFFSET 0x002c /* Channel 4 Status and Control */ +#define KINETIS_FTM_C4V_OFFSET 0x0030 /* Channel 4 Value */ +#define KINETIS_FTM_C5SC_OFFSET 0x0034 /* Channel 5 Status and Control */ +#define KINETIS_FTM_C5V_OFFSET 0x0038 /* Channel 5 Value */ +#define KINETIS_FTM_C6SC_OFFSET 0x003c /* Channel 6 Status and Control */ +#define KINETIS_FTM_C6V_OFFSET 0x0040 /* Channel 6 Value */ +#define KINETIS_FTM_C7SC_OFFSET 0x0044 /* Channel 7 Status and Control */ +#define KINETIS_FTM_C7V_OFFSET 0x0048 /* Channel 7 Value */ + +#define KINETIS_FTM_CNTIN_OFFSET 0x004c /* Counter Initial Value */ +#define KINETIS_FTM_STATUS_OFFSET 0x0050 /* Capture and Compare Status */ +#define KINETIS_FTM_MODE_OFFSET 0x0054 /* Features Mode Selection */ +#define KINETIS_FTM_SYNC_OFFSET 0x0058 /* Synchronization */ +#define KINETIS_FTM_OUTINIT_OFFSET 0x005c /* Initial State for Channels Output */ +#define KINETIS_FTM_OUTMASK_OFFSET 0x0060 /* Output Mask */ +#define KINETIS_FTM_COMBINE_OFFSET 0x0064 /* Function for Linked Channels */ +#define KINETIS_FTM_DEADTIME_OFFSET 0x0068 /* Deadtime Insertion Control */ +#define KINETIS_FTM_EXTTRIG_OFFSET 0x006c /* FTM External Trigger */ +#define KINETIS_FTM_POL_OFFSET 0x0070 /* Channels Polarity */ +#define KINETIS_FTM_FMS_OFFSET 0x0074 /* Fault Mode Status */ +#define KINETIS_FTM_FILTER_OFFSET 0x0078 /* Input Capture Filter Control */ +#define KINETIS_FTM_FLTCTRL_OFFSET 0x007c /* Fault Control */ +#define KINETIS_FTM_QDCTRL_OFFSET 0x0080 /* Quadrature Decoder Control and Status */ +#define KINETIS_FTM_CONF_OFFSET 0x0084 /* Configuration */ +#define KINETIS_FTM_FLTPOL_OFFSET 0x0088 /* FTM Fault Input Polarity */ +#define KINETIS_FTM_SYNCONF_OFFSET 0x008c /* Synchronization Configuration */ +#define KINETIS_FTM_INVCTRL_OFFSET 0x0090 /* FTM Inverting Control */ +#define KINETIS_FTM_SWOCTRL_OFFSET 0x0094 /* FTM Software Output Control */ +#define KINETIS_FTM_PWMLOAD_OFFSET 0x0098 /* FTM PWM Load */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_FTM0_SC (KINETIS_FTM0_BASE+KINETIS_FTM_SC_OFFSET) +#define KINETIS_FTM0_CNT (KINETIS_FTM0_BASE+KINETIS_FTM_CNT_OFFSET) +#define KINETIS_FTM0_MOD (KINETIS_FTM0_BASE+KINETIS_FTM_MOD_OFFSET) + +#define KINETIS_FTM0_CSC(n) (KINETIS_FTM0_BASE+KINETIS_FTM_CSC_OFFSET(n)) +#define KINETIS_FTM0_CV(n) (KINETIS_FTM0_BASE+KINETIS_FTM_CV_OFFSET(n)) +#define KINETIS_FTM0_C0SC (KINETIS_FTM0_BASE+KINETIS_FTM_C0SC_OFFSET) +#define KINETIS_FTM0_C0V (KINETIS_FTM0_BASE+KINETIS_FTM_C0V_OFFSET) +#define KINETIS_FTM0_C1SC (KINETIS_FTM0_BASE+KINETIS_FTM_C1SC_OFFSET) +#define KINETIS_FTM0_C1V (KINETIS_FTM0_BASE+KINETIS_FTM_C1V_OFFSET) +#define KINETIS_FTM0_C2SC (KINETIS_FTM0_BASE+KINETIS_FTM_C2SC_OFFSET) +#define KINETIS_FTM0_C2V (KINETIS_FTM0_BASE+KINETIS_FTM_C2V_OFFSET) +#define KINETIS_FTM0_C3SC (KINETIS_FTM0_BASE+KINETIS_FTM_C3SC_OFFSET) +#define KINETIS_FTM0_C3V (KINETIS_FTM0_BASE+KINETIS_FTM_C3V_OFFSET) +#define KINETIS_FTM0_C4SC (KINETIS_FTM0_BASE+KINETIS_FTM_C4SC_OFFSET) +#define KINETIS_FTM0_C4V (KINETIS_FTM0_BASE+KINETIS_FTM_C4V_OFFSET) +#define KINETIS_FTM0_C5SC (KINETIS_FTM0_BASE+KINETIS_FTM_C5SC_OFFSET) +#define KINETIS_FTM0_C5V (KINETIS_FTM0_BASE+KINETIS_FTM_C5V_OFFSET) +#define KINETIS_FTM0_C6SC (KINETIS_FTM0_BASE+KINETIS_FTM_C6SC_OFFSET) +#define KINETIS_FTM0_C6V (KINETIS_FTM0_BASE+KINETIS_FTM_C6V_OFFSET) +#define KINETIS_FTM0_C7SC (KINETIS_FTM0_BASE+KINETIS_FTM_C7SC_OFFSET) +#define KINETIS_FTM0_C7V (KINETIS_FTM0_BASE+KINETIS_FTM_C7V_OFFSET) + +#define KINETIS_FTM0_CNTIN (KINETIS_FTM0_BASE+KINETIS_FTM_CNTIN_OFFSET) +#define KINETIS_FTM0_STATUS (KINETIS_FTM0_BASE+KINETIS_FTM_STATUS_OFFSET) +#define KINETIS_FTM0_MODE (KINETIS_FTM0_BASE+KINETIS_FTM_MODE_OFFSET) +#define KINETIS_FTM0_SYNC (KINETIS_FTM0_BASE+KINETIS_FTM_SYNC_OFFSET) +#define KINETIS_FTM0_OUTINIT (KINETIS_FTM0_BASE+KINETIS_FTM_OUTINIT_OFFSET) +#define KINETIS_FTM0_OUTMASK (KINETIS_FTM0_BASE+KINETIS_FTM_OUTMASK_OFFSET) +#define KINETIS_FTM0_COMBINE (KINETIS_FTM0_BASE+KINETIS_FTM_COMBINE_OFFSET) +#define KINETIS_FTM0_DEADTIME (KINETIS_FTM0_BASE+KINETIS_FTM_DEADTIME_OFFSET) +#define KINETIS_FTM0_EXTTRIG (KINETIS_FTM0_BASE+KINETIS_FTM_EXTTRIG_OFFSET) +#define KINETIS_FTM0_POL (KINETIS_FTM0_BASE+KINETIS_FTM_POL_OFFSET) +#define KINETIS_FTM0_FMS (KINETIS_FTM0_BASE+KINETIS_FTM_FMS_OFFSET) +#define KINETIS_FTM0_FILTER (KINETIS_FTM0_BASE+KINETIS_FTM_FILTER_OFFSET) +#define KINETIS_FTM0_FLTCTRL (KINETIS_FTM0_BASE+KINETIS_FTM_FLTCTRL_OFFSET) +#define KINETIS_FTM0_QDCTRL (KINETIS_FTM0_BASE+KINETIS_FTM_QDCTRL_OFFSET) +#define KINETIS_FTM0_CONF (KINETIS_FTM0_BASE+KINETIS_FTM_CONF_OFFSET) +#define KINETIS_FTM0_FLTPOL (KINETIS_FTM0_BASE+KINETIS_FTM_FLTPOL_OFFSET) +#define KINETIS_FTM0_SYNCONF (KINETIS_FTM0_BASE+KINETIS_FTM_SYNCONF_OFFSET) +#define KINETIS_FTM0_INVCTRL (KINETIS_FTM0_BASE+KINETIS_FTM_INVCTRL_OFFSET) +#define KINETIS_FTM0_SWOCTRL (KINETIS_FTM0_BASE+KINETIS_FTM_SWOCTRL_OFFSET) +#define KINETIS_FTM0_PWMLOAD (KINETIS_FTM0_BASE+KINETIS_FTM_PWMLOAD_OFFSET) + +#define KINETIS_FTM1_SC (KINETIS_FTM1_BASE+KINETIS_FTM_SC_OFFSET) +#define KINETIS_FTM1_CNT (KINETIS_FTM1_BASE+KINETIS_FTM_CNT_OFFSET) +#define KINETIS_FTM1_MOD (KINETIS_FTM1_BASE+KINETIS_FTM_MOD_OFFSET) + +#define KINETIS_FTM1_CSC(n) (KINETIS_FTM1_BASE+KINETIS_FTM_CSC_OFFSET(n)) +#define KINETIS_FTM1_CV(n) (KINETIS_FTM1_BASE+KINETIS_FTM_CV_OFFSET(n)) +#define KINETIS_FTM1_C0SC (KINETIS_FTM1_BASE+KINETIS_FTM_C0SC_OFFSET) +#define KINETIS_FTM1_C0V (KINETIS_FTM1_BASE+KINETIS_FTM_C0V_OFFSET) +#define KINETIS_FTM1_C1SC (KINETIS_FTM1_BASE+KINETIS_FTM_C1SC_OFFSET) +#define KINETIS_FTM1_C1V (KINETIS_FTM1_BASE+KINETIS_FTM_C1V_OFFSET) +#define KINETIS_FTM1_C2SC (KINETIS_FTM1_BASE+KINETIS_FTM_C2SC_OFFSET) +#define KINETIS_FTM1_C2V (KINETIS_FTM1_BASE+KINETIS_FTM_C2V_OFFSET) +#define KINETIS_FTM1_C3SC (KINETIS_FTM1_BASE+KINETIS_FTM_C3SC_OFFSET) +#define KINETIS_FTM1_C3V (KINETIS_FTM1_BASE+KINETIS_FTM_C3V_OFFSET) +#define KINETIS_FTM1_C4SC (KINETIS_FTM1_BASE+KINETIS_FTM_C4SC_OFFSET) +#define KINETIS_FTM1_C4V (KINETIS_FTM1_BASE+KINETIS_FTM_C4V_OFFSET) +#define KINETIS_FTM1_C5SC (KINETIS_FTM1_BASE+KINETIS_FTM_C5SC_OFFSET) +#define KINETIS_FTM1_C5V (KINETIS_FTM1_BASE+KINETIS_FTM_C5V_OFFSET) +#define KINETIS_FTM1_C6SC (KINETIS_FTM1_BASE+KINETIS_FTM_C6SC_OFFSET) +#define KINETIS_FTM1_C6V (KINETIS_FTM1_BASE+KINETIS_FTM_C6V_OFFSET) +#define KINETIS_FTM1_C7SC (KINETIS_FTM1_BASE+KINETIS_FTM_C7SC_OFFSET) +#define KINETIS_FTM1_C7V (KINETIS_FTM1_BASE+KINETIS_FTM_C7V_OFFSET) + +#define KINETIS_FTM1_CNTIN (KINETIS_FTM1_BASE+KINETIS_FTM_CNTIN_OFFSET) +#define KINETIS_FTM1_STATUS (KINETIS_FTM1_BASE+KINETIS_FTM_STATUS_OFFSET) +#define KINETIS_FTM1_MODE (KINETIS_FTM1_BASE+KINETIS_FTM_MODE_OFFSET) +#define KINETIS_FTM1_SYNC (KINETIS_FTM1_BASE+KINETIS_FTM_SYNC_OFFSET) +#define KINETIS_FTM1_OUTINIT (KINETIS_FTM1_BASE+KINETIS_FTM_OUTINIT_OFFSET) +#define KINETIS_FTM1_OUTMASK (KINETIS_FTM1_BASE+KINETIS_FTM_OUTMASK_OFFSET) +#define KINETIS_FTM1_COMBINE (KINETIS_FTM1_BASE+KINETIS_FTM_COMBINE_OFFSET) +#define KINETIS_FTM1_DEADTIME (KINETIS_FTM1_BASE+KINETIS_FTM_DEADTIME_OFFSET) +#define KINETIS_FTM1_EXTTRIG (KINETIS_FTM1_BASE+KINETIS_FTM_EXTTRIG_OFFSET) +#define KINETIS_FTM1_POL (KINETIS_FTM1_BASE+KINETIS_FTM_POL_OFFSET) +#define KINETIS_FTM1_FMS (KINETIS_FTM1_BASE+KINETIS_FTM_FMS_OFFSET) +#define KINETIS_FTM1_FILTER (KINETIS_FTM1_BASE+KINETIS_FTM_FILTER_OFFSET) +#define KINETIS_FTM1_FLTCTRL (KINETIS_FTM1_BASE+KINETIS_FTM_FLTCTRL_OFFSET) +#define KINETIS_FTM1_QDCTRL (KINETIS_FTM1_BASE+KINETIS_FTM_QDCTRL_OFFSET) +#define KINETIS_FTM1_CONF (KINETIS_FTM1_BASE+KINETIS_FTM_CONF_OFFSET) +#define KINETIS_FTM1_FLTPOL (KINETIS_FTM1_BASE+KINETIS_FTM_FLTPOL_OFFSET) +#define KINETIS_FTM1_SYNCONF (KINETIS_FTM1_BASE+KINETIS_FTM_SYNCONF_OFFSET) +#define KINETIS_FTM1_INVCTRL (KINETIS_FTM1_BASE+KINETIS_FTM_INVCTRL_OFFSET) +#define KINETIS_FTM1_SWOCTRL (KINETIS_FTM1_BASE+KINETIS_FTM_SWOCTRL_OFFSET) +#define KINETIS_FTM1_PWMLOAD (KINETIS_FTM1_BASE+KINETIS_FTM_PWMLOAD_OFFSET) + +#define KINETIS_FTM2_SC (KINETIS_FTM2_BASE+KINETIS_FTM_SC_OFFSET) +#define KINETIS_FTM2_CNT (KINETIS_FTM2_BASE+KINETIS_FTM_CNT_OFFSET) +#define KINETIS_FTM2_MOD (KINETIS_FTM2_BASE+KINETIS_FTM_MOD_OFFSET) + +#define KINETIS_FTM2_CSC(n) (KINETIS_FTM2_BASE+KINETIS_FTM_CSC_OFFSET(n)) +#define KINETIS_FTM2_CV(n) (KINETIS_FTM2_BASE+KINETIS_FTM_CV_OFFSET(n)) +#define KINETIS_FTM2_C0SC (KINETIS_FTM2_BASE+KINETIS_FTM_C0SC_OFFSET) +#define KINETIS_FTM2_C0V (KINETIS_FTM2_BASE+KINETIS_FTM_C0V_OFFSET) +#define KINETIS_FTM2_C1SC (KINETIS_FTM2_BASE+KINETIS_FTM_C1SC_OFFSET) +#define KINETIS_FTM2_C1V (KINETIS_FTM2_BASE+KINETIS_FTM_C1V_OFFSET) +#define KINETIS_FTM2_C2SC (KINETIS_FTM2_BASE+KINETIS_FTM_C2SC_OFFSET) +#define KINETIS_FTM2_C2V (KINETIS_FTM2_BASE+KINETIS_FTM_C2V_OFFSET) +#define KINETIS_FTM2_C3SC (KINETIS_FTM2_BASE+KINETIS_FTM_C3SC_OFFSET) +#define KINETIS_FTM2_C3V (KINETIS_FTM2_BASE+KINETIS_FTM_C3V_OFFSET) +#define KINETIS_FTM2_C4SC (KINETIS_FTM2_BASE+KINETIS_FTM_C4SC_OFFSET) +#define KINETIS_FTM2_C4V (KINETIS_FTM2_BASE+KINETIS_FTM_C4V_OFFSET) +#define KINETIS_FTM2_C5SC (KINETIS_FTM2_BASE+KINETIS_FTM_C5SC_OFFSET) +#define KINETIS_FTM2_C5V (KINETIS_FTM2_BASE+KINETIS_FTM_C5V_OFFSET) +#define KINETIS_FTM2_C6SC (KINETIS_FTM2_BASE+KINETIS_FTM_C6SC_OFFSET) +#define KINETIS_FTM2_C6V (KINETIS_FTM2_BASE+KINETIS_FTM_C6V_OFFSET) +#define KINETIS_FTM2_C7SC (KINETIS_FTM2_BASE+KINETIS_FTM_C7SC_OFFSET) +#define KINETIS_FTM2_C7V (KINETIS_FTM2_BASE+KINETIS_FTM_C7V_OFFSET) + +#define KINETIS_FTM2_CNTIN (KINETIS_FTM2_BASE+KINETIS_FTM_CNTIN_OFFSET) +#define KINETIS_FTM2_STATUS (KINETIS_FTM2_BASE+KINETIS_FTM_STATUS_OFFSET) +#define KINETIS_FTM2_MODE (KINETIS_FTM2_BASE+KINETIS_FTM_MODE_OFFSET) +#define KINETIS_FTM2_SYNC (KINETIS_FTM2_BASE+KINETIS_FTM_SYNC_OFFSET) +#define KINETIS_FTM2_OUTINIT (KINETIS_FTM2_BASE+KINETIS_FTM_OUTINIT_OFFSET) +#define KINETIS_FTM2_OUTMASK (KINETIS_FTM2_BASE+KINETIS_FTM_OUTMASK_OFFSET) +#define KINETIS_FTM2_COMBINE (KINETIS_FTM2_BASE+KINETIS_FTM_COMBINE_OFFSET) +#define KINETIS_FTM2_DEADTIME (KINETIS_FTM2_BASE+KINETIS_FTM_DEADTIME_OFFSET) +#define KINETIS_FTM2_EXTTRIG (KINETIS_FTM2_BASE+KINETIS_FTM_EXTTRIG_OFFSET) +#define KINETIS_FTM2_POL (KINETIS_FTM2_BASE+KINETIS_FTM_POL_OFFSET) +#define KINETIS_FTM2_FMS (KINETIS_FTM2_BASE+KINETIS_FTM_FMS_OFFSET) +#define KINETIS_FTM2_FILTER (KINETIS_FTM2_BASE+KINETIS_FTM_FILTER_OFFSET) +#define KINETIS_FTM2_FLTCTRL (KINETIS_FTM2_BASE+KINETIS_FTM_FLTCTRL_OFFSET) +#define KINETIS_FTM2_QDCTRL (KINETIS_FTM2_BASE+KINETIS_FTM_QDCTRL_OFFSET) +#define KINETIS_FTM2_CONF (KINETIS_FTM2_BASE+KINETIS_FTM_CONF_OFFSET) +#define KINETIS_FTM2_FLTPOL (KINETIS_FTM2_BASE+KINETIS_FTM_FLTPOL_OFFSET) +#define KINETIS_FTM2_SYNCONF (KINETIS_FTM2_BASE+KINETIS_FTM_SYNCONF_OFFSET) +#define KINETIS_FTM2_INVCTRL (KINETIS_FTM2_BASE+KINETIS_FTM_INVCTRL_OFFSET) +#define KINETIS_FTM2_SWOCTRL (KINETIS_FTM2_BASE+KINETIS_FTM_SWOCTRL_OFFSET) +#define KINETIS_FTM2_PWMLOAD (KINETIS_FTM2_BASE+KINETIS_FTM_PWMLOAD_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* Status and Control */ + +#define FTM_SC_PS_SHIFT (0) /* Bits 0-2: Prescale Factor Selection */ +#define FTM_SC_PS_MASK (7 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_1 (0 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_2 (1 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_4 (2 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_8 (3 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_16 (4 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_32 (5 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_64 (6 << FTM_SC_PS_SHIFT) +# define FTM_SC_PS_128 (7 << FTM_SC_PS_SHIFT) +#define FTM_SC_CLKS_SHIFT (3) /* Bits 3-4: Clock Source Selection */ +#define FTM_SC_CLKS_MASK (3 << FTM_SC_CLKS_SHIFT) +# define FTM_SC_CLKS_NONE (0 << FTM_SC_CLKS_SHIFT) /* No clock selected */ +# define FTM_SC_CLKS_SYSCLK (1 << FTM_SC_CLKS_SHIFT) /* System clock */ +# define FTM_SC_CLKS_FIXED (2 << FTM_SC_CLKS_SHIFT) /* Fixed frequency clock */ +# define FTM_SC_CLKS_EXTCLK (3 << FTM_SC_CLKS_SHIFT) /* External clock */ +#define FTM_SC_CPWMS (1 << 5) /* Bit 5: Center-aligned PWM Select */ +#define FTM_SC_TOIE (1 << 6) /* Bit 6: Timer Overflow Interrupt Enable */ +#define FTM_SC_TOF (1 << 7) /* Bit 7: Timer Overflow Flag */ + /* Bits 8-31: Reserved */ +/* Counter */ + +#define FTM_CNT_SHIFT (0) /* Bits 0-15: Counter value */ +#define FTM_CNT_MASK (0xffff << FTM_CNT_SHIFT) + /* Bits 16-31: Reserved */ + +/* Modulo */ + +#define FTM_MOD_SHIFT (0) /* Bits 0-15: Modulo value */ +#define FTM_MOD_MASK (0xffff << FTM_MOD_SHIFT) + /* Bits 16-31: Reserved */ + +/* Channel (n) Status and Control */ + +#define FTM_CSC_DMA (1 << 0) /* Bit 0: DMA Enable */ + /* Bit 1: Reserved */ +#define FTM_CSC_ELSA (1 << 2) /* Bit 2: Edge or Level Select */ +#define FTM_CSC_ELSB (1 << 3) /* Bit 3: Edge or Level Select */ +#define FTM_CSC_MSA (1 << 4) /* Bit 4: Channel Mode Select */ +#define FTM_CSC_MSB (1 << 5) /* Bit 5: Channel Mode Select */ +#define FTM_CSC_CHIE (1 << 6) /* Bit 6: Channel Interrupt Enable */ +#define FTM_CSC_CHF (1 << 7) /* Bit 7: Channel Flag */ + /* Bits 8-31: Reserved */ +/* Channel (n) Value */ + +#define FTM_CV_SHIFT (0) /* Bits 0-15: Channel Value */ +#define FTM_CV_MASK (0xffff << FTM_CV_SHIFT) + /* Bits 16-31: Reserved */ +/* Counter Initial Value */ + +#define FTM_CNTIN_SHIFT (0) /* Bits 0-15: Initial Value of the FTM Counter */ +#define FTM_CNTIN_MASK (0xffff << FTM_CNTIN_SHIFT) + /* Bits 16-31: Reserved */ +/* Capture and Compare Status */ + +#define FTM_STATUS(n) (1 << (n)) /* Channel (n) Flag, n=0..7 */ + /* Bits 8-31: Reserved */ + +/* Features Mode Selection */ + +#define FTM_MODE_FTMEN (1 << 0) /* Bit 0: FTM Enable */ +#define FTM_MODE_INIT (1 << 1) /* Bit 1: Initialize the Channels Output */ +#define FTM_MODE_WPDIS (1 << 2) /* Bit 2: Write Protection Disable */ +#define FTM_MODE_PWMSYNC (1 << 3) /* Bit 3: PWM Synchronization Mode */ +#define FTM_MODE_CAPTEST (1 << 4) /* Bit 4: Capture Test Mode Enable */ +#define FTM_MODE_FAULTM_SHIFT (5) /* Bits 5-6: Fault Control Mode */ +#define FTM_MODE_FAULTM_MASK (3 << FTM_MODE_FAULTM_SHIFT) +# define FTM_MODE_FAULTM_DISABLED (0 << FTM_MODE_FAULTM_SHIFT) /* Disabled */ +# define FTM_MODE_FAULTM_EVEN (1 << FTM_MODE_FAULTM_SHIFT) /* Enable even channels, manual fault clearing */ +# define FTM_MODE_FAULTM_MANUAL (2 << FTM_MODE_FAULTM_SHIFT) /* Enable all channels, manual fault clearing */ +# define FTM_MODE_FAULTM_AUTO (3 << FTM_MODE_FAULTM_SHIFT) /* Enable all channels, automatic fault clearing */ +#define FTM_MODE_FAULTIE (1 << 7) /* Bit 7: Fault Interrupt Enable */ + /* Bits 8-31: Reserved */ +/* Synchronization */ + +#define FTM_SYNC_CNTMIN (1 << 0) /* Bit 0: Minimum loading point enable */ +#define FTM_SYNC_CNTMAX (1 << 1) /* Bit 1: Maximum loading point enable */ +#define FTM_SYNC_REINIT (1 << 2) /* Bit 2: FTM Counter Reinitialization by Synchron */ +#define FTM_SYNC_SYNCHOM (1 << 3) /* Bit 3: Output Mask Synchronization */ +#define FTM_SYNC_TRIG0 (1 << 4) /* Bit 4: PWM Synchronization Hardware Trigger 0 */ +#define FTM_SYNC_TRIG1 (1 << 5) /* Bit 5: PWM Synchronization Hardware Trigger 1 */ +#define FTM_SYNC_TRIG2 (1 << 6) /* Bit 6: PWM Synchronization Hardware Trigger 2 */ +#define FTM_SYNC_SWSYNC (1 << 7) /* Bit 7: PWM Synchronization Software Trigger */ + /* Bits 8-31: Reserved */ +/* Initial State for Channels Output */ + +#define FTM_OUTINIT(n) (1 << (n)) /* Channel (n) Output Initialization Value, n=0..7 */ + /* Bits 8-31: Reserved */ +/* Output Mask */ + +#define FTM_OUTMASK(n) (1 << (n)) /* Channel (n) Output Mask, n=0..7 */ + /* Bits 8-31: Reserved */ +/* Function for Linked Channels */ + +#define FTM_COMBINE_COMBINE0 (1 << 0) /* Bit 0: Combine Channels for n = 0 */ +#define FTM_COMBINE_COMP0 (1 << 1) /* Bit 1: Complement of Channel (n) for n = 0 */ +#define FTM_COMBINE_DECAPEN0 (1 << 2) /* Bit 2: Dual Edge Capture Mode Enable for n = 0 */ +#define FTM_COMBINE_DECAP0 (1 << 3) /* Bit 3: Dual Edge Capture Mode Captures for n = 0 */ +#define FTM_COMBINE_DTEN0 (1 << 4) /* Bit 4: Deadtime Enable for n = 0 */ +#define FTM_COMBINE_SYNCEN0 (1 << 5) /* Bit 5: Synchronization Enable for n = 0 */ +#define FTM_COMBINE_FAULTEN0 (1 << 6) /* Bit 6: Fault Control Enable for n = 0 */ + /* Bit 7: Reserved */ +#define FTM_COMBINE_COMBINE1 (1 << 8) /* Bit 8: Combine Channels for n = 2 */ +#define FTM_COMBINE_COMP1 (1 << 9) /* Bit 9: Complement of Channel (n) for n = 2 */ +#define FTM_COMBINE_DECAPEN1 (1 << 10) /* Bit 10: Dual Edge Capture Mode Enable for n = 2 */ +#define FTM_COMBINE_DECAP1 (1 << 11) /* Bit 11: Dual Edge Capture Mode Captures for n = 2 */ +#define FTM_COMBINE_DTEN1 (1 << 12) /* Bit 12: Deadtime Enable for n = 2 */ +#define FTM_COMBINE_SYNCEN1 (1 << 13) /* Bit 13: Synchronization Enable for n = 2 */ +#define FTM_COMBINE_FAULTEN1 (1 << 14) /* Bit 14: Fault Control Enable for n = 2 */ + /* Bit 15: Reserved */ +#define FTM_COMBINE_COMBINE2 (1 << 16) /* Bit 16: Combine Channels for n = 4 */ +#define FTM_COMBINE_COMP2 (1 << 17) /* Bit 17: Complement of Channel (n) for n = 4 */ +#define FTM_COMBINE_DECAPEN2 (1 << 18) /* Bit 18: Dual Edge Capture Mode Enable for n = 4 */ +#define FTM_COMBINE_DECAP2 (1 << 19) /* Bit 19: Dual Edge Capture Mode Captures for n = 4 */ +#define FTM_COMBINE_DTEN2 (1 << 20) /* Bit 20: Deadtime Enable for n = 4 */ +#define FTM_COMBINE_SYNCEN2 (1 << 21) /* Bit 21: Synchronization Enable for n = 4 */ +#define FTM_COMBINE_FAULTEN2 (1 << 22) /* Bit 22: Fault Control Enable for n = 4 */ + /* Bit 23: Reserved */ +#define FTM_COMBINE_COMBINE3 (1 << 24) /* Bit 24: Combine Channels for n = 6 */ +#define FTM_COMBINE_COMP3 (1 << 25) /* Bit 25: Complement of Channel (n) for n = 6 */ +#define FTM_COMBINE_DECAPEN3 (1 << 26) /* Bit 26: Dual Edge Capture Mode Enable for n = 6 */ +#define FTM_COMBINE_DECAP3 (1 << 27) /* Bit 27: Dual Edge Capture Mode Captures for n = 6 */ +#define FTM_COMBINE_DTEN3 (1 << 28) /* Bit 28: Deadtime Enable for n = 6 */ +#define FTM_COMBINE_SYNCEN3 (1 << 29) /* Bit 29: Synchronization Enable for n = 6 */ +#define FTM_COMBINE_FAULTEN3 (1 << 30) /* Bit 30: Fault Control Enable for n = 6 */ + /* Bit 31: Reserved */ +/* Deadtime Insertion Control */ + +#define FTM_DEADTIME_DTVAL_SHIFT (0) /* Bits 0-5: Deadtime Value */ +#define FTM_DEADTIME_DTVAL_MASK (63 << FTM_DEADTIME_DTVAL_SHIFT) +#define FTM_DEADTIME_DTPS_SHIFT (6) /* Bits 6-7: Deadtime Prescaler Value */ +#define FTM_DEADTIME_DTPS_MASK (3 << FTM_DEADTIME_DTPS_SHIFT) +# define FTM_DEADTIME_DTPS_DIV1 (0 << FTM_DEADTIME_DTPS_SHIFT) +# define FTM_DEADTIME_DTPS_DIV4 (2 << FTM_DEADTIME_DTPS_SHIFT) +# define FTM_DEADTIME_DTPS_DIV16 (3 << FTM_DEADTIME_DTPS_SHIFT) + /* Bits 8-31: Reserved */ +/* FTM External Trigger */ + +#define FTM_EXTTRIG_CH2TRIG (1 << 0) /* Bit 0: Channel 2 Trigger Enable */ +#define FTM_EXTTRIG_CH3TRIG (1 << 1) /* Bit 1: Channel 3 Trigger Enable */ +#define FTM_EXTTRIG_CH4TRIG (1 << 2) /* Bit 2: Channel 4 Trigger Enable */ +#define FTM_EXTTRIG_CH5TRIG (1 << 3) /* Bit 3: Channel 5 Trigger Enable */ +#define FTM_EXTTRIG_CH0TRIG (1 << 4) /* Bit 4: Channel 0 Trigger Enable */ +#define FTM_EXTTRIG_CH1TRIG (1 << 5) /* Bit 5: Channel 1 Trigger Enable */ +#define FTM_EXTTRIG_INITTRIGEN (1 << 6) /* Bit 6: Initialization Trigger Enable */ +#define FTM_EXTTRIG_TRIGF (1 << 7) /* Bit 7: Channel Trigger Flag */ + /* Bits 8-31: Reserved */ +/* Channels Polarity */ + +#define FTM_POL(n) (1 << (n)) /* Channel (n) Polarity, n=0..7 */ + /* Bits 8-31: Reserved */ + +/* Fault Mode Status */ + +#define FTM_FMS_FAULTF0 (1 << 0) /* Bit 0: Fault Detection Flag 0 */ +#define FTM_FMS_FAULTF1 (1 << 1) /* Bit 1: Fault Detection Flag 1 */ +#define FTM_FMS_FAULTF2 (1 << 2) /* Bit 2: Fault Detection Flag 2 */ +#define FTM_FMS_FAULTF3 (1 << 3) /* Bit 3: Fault Detection Flag 3 */ + /* Bit 4: Reserved */ +#define FTM_FMS_FAULTIN (1 << 5) /* Bit 5: Fault Inputs */ +#define FTM_FMS_WPEN (1 << 6) /* Bit 6: Write Protection Enable */ +#define FTM_FMS_FAULTF (1 << 7) /* Bit 7: Fault Detection Flag */ + /* Bits 8-31: Reserved */ +/* Input Capture Filter Control */ + +#define FTM_FILTER_CH0FVAL_SHIFT (0) /* Bits 0-3: Channel 0 Input Filter */ +#define FTM_FILTER_CH0FVAL_MASK (15 << FTM_FILTER_CH0FVAL_SHIFT) +#define FTM_FILTER_CH1FVAL_SHIFT (4) /* Bits 4-7: Channel 1 Input Filter */ +#define FTM_FILTER_CH1FVAL_MASK (15 << FTM_FILTER_CH1FVAL_SHIFT) +#define FTM_FILTER_CH2FVAL_SHIFT (8) /* Bits 8-11: Channel 2 Input Filter */ +#define FTM_FILTER_CH2FVAL_MASK (15 << FTM_FILTER_CH2FVAL_SHIFT) +#define FTM_FILTER_CH3FVAL_SHIFT (12) /* Bits 12-15: Channel 3 Input Filter */ +#define FTM_FILTER_CH3FVAL_MASK (15 << FTM_FILTER_CH3FVAL_SHIFT) + /* Bits 16-31: Reserved */ +/* Fault Control */ + +#define FTM_FLTCTRL_FAULT0EN (1 << 0) /* Bit 0: Fault Input 0 Enable */ +#define FTM_FLTCTRL_FAULT1EN (1 << 1) /* Bit 1: Fault Input 1 Enable */ +#define FTM_FLTCTRL_FAULT2EN (1 << 2) /* Bit 2: Fault Input 2 Enable */ +#define FTM_FLTCTRL_FAULT3EN (1 << 3) /* Bit 3: Fault Input 3 Enable */ +#define FTM_FLTCTRL_FFLTR0EN (1 << 4) /* Bit 4: Fault Input 0 Filter Enable */ +#define FTM_FLTCTRL_FFLTR1EN (1 << 5) /* Bit 5: Fault Input 1 Filter Enable */ +#define FTM_FLTCTRL_FFLTR2EN (1 << 6) /* Bit 6: Fault Input 2 Filter Enable */ +#define FTM_FLTCTRL_FFLTR3EN (1 << 7) /* Bit 7: Fault Input 3 Filter Enable */ +#define FTM_FLTCTRL_FFVAL_SHIFT (8) /* Bits 8-11: Fault Input Filter */ +#define FTM_FLTCTRL_FFVAL_MASK (15 << FTM_FLTCTRL_FFVAL_SHIFT) + /* Bits 12-31: Reserved */ +/* Quadrature Decoder Control and Status */ + +#define FTM_QDCTRL_QUADEN (1 << 0) /* Bit 0: Quadrature Decoder Mode Enable */ +#define FTM_QDCTRL_TOFDIR (1 << 1) /* Bit 1: Timer Overflow Direction in Quadrature Decoder Mode */ +#define FTM_QDCTRL_QUADIR (1 << 2) /* Bit 2: FTM Counter Direction in Quadrature Decoder Mode */ +#define FTM_QDCTRL_QUADMODE (1 << 3) /* Bit 3: Quadrature Decoder Mode */ +#define FTM_QDCTRL_PHBPOL (1 << 4) /* Bit 4: Phase B Input Polarity */ +#define FTM_QDCTRL_PHAPOL (1 << 5) /* Bit 5: Phase A Input Polarity */ +#define FTM_QDCTRL_PHBFLTREN (1 << 6) /* Bit 6: Phase B Input Filter Enable */ +#define FTM_QDCTRL_PHAFLTREN (1 << 7) /* Bit 7: Phase A Input Filter Enable */ + /* Bits 8-31: Reserved */ +/* Configuration */ + +#define FTM_CONF_NUMTOF_SHIFT (0) /* Bits 0-4: TOF Frequency */ +#define FTM_CONF_NUMTOF_MASK (31 << FTM_CONF_NUMTOF_SHIFT) + /* Bit 5: Reserved */ +#define FTM_CONF_BDMMODE_SHIFT (6) /* Bits 6-7: BDM Mode */ +#define FTM_CONF_BDMMODE_MASK (3 << FTM_CONF_BDMMODE_SHIFT) + /* Bit 8: Reserved */ +#define FTM_CONF_GTBEEN (1 << 9) /* Bit 9: Global time base enable */ +#define FTM_CONF_GTBEOUT (1 << 10) /* Bit 10: Global time base output */ + /* Bits 11-31: Reserved */ +/* FTM Fault Input Polarity */ + +#define FTM_FLTPOL_FLT0POL (1 << 0) /* Bit 0: Fault Input 0 Polarity */ +#define FTM_FLTPOL_FLT1POL (1 << 1) /* Bit 1: Fault Input 1 Polarity */ +#define FTM_FLTPOL_FLT2POL (1 << 2) /* Bit 2: Fault Input 2 Polarity */ +#define FTM_FLTPOL_FLT3POL (1 << 3) /* Bit 3: Fault Input 3 Polarity */ + /* Bits 4-31: Reserved */ +/* Synchronization Configuration */ + +#define FTM_SYNCONF_HWTRIGMODE (1 << 0) /* Bit 0: Hardware Trigger Mode */ + /* Bit 1: Reserved */ +#define FTM_SYNCONF_CNTINC (1 << 2) /* Bit 2: CNTIN register synchronization */ + /* Bit 3: Reserved */ +#define FTM_SYNCONF_INVC (1 << 4) /* Bit 4: INVCTRL register synchronization */ +#define FTM_SYNCONF_SWOC (1 << 5) /* Bit 5: SWOCTRL register synchronization */ + /* Bit 6: Reserved */ +#define FTM_SYNCONF_SYNCMODE (1 << 7) /* Bit 7: Synchronization Mode */ +#define FTM_SYNCONF_SWRSTCNT (1 << 8) /* Bit 8: FTM counter synchronization (S/W) */ +#define FTM_SYNCONF_SWWRBUF (1 << 9) /* Bit 9: MOD, CNTIN, and CV registers synchronization (S/W) */ +#define FTM_SYNCONF_SWOM (1 << 10) /* Bit 10: Output mask synchronization (S/W) */ +#define FTM_SYNCONF_SWINVC (1 << 11) /* Bit 11: Inverting control synchronization (S/W) */ +#define FTM_SYNCONF_SWSOC (1 << 12) /* Bit 12: Software output control synchronization (S/W) */ + /* Bits 13-15: Reserved */ +#define FTM_SYNCONF_HWRSTCNT (1 << 16) /* Bit 16: FTM counter synchronization (H/W) */ +#define FTM_SYNCONF_HWWRBUF (1 << 17) /* Bit 17: MOD, CNTIN, and CV registers synchronization (H/W) */ +#define FTM_SYNCONF_HWOM (1 << 18) /* Bit 18: Output mask synchronization (H/W) */ +#define FTM_SYNCONF_HWINVC (1 << 19) /* Bit 19: Inverting control synchronization (H/W) */ +#define FTM_SYNCONF_HWSOC (1 << 20) /* Bit 20: Software output control synchronization (H/W) */ + /* Bits 21-31: Reserved */ +/* FTM Inverting Control */ + +#define FTM_INVCTRL_INV0EN (1 << 0) /* Bit 0: Pair Channels 0 Inverting Enable */ +#define FTM_INVCTRL_INV1EN (1 << 1) /* Bit 1: Pair Channels 1 Inverting Enable */ +#define FTM_INVCTRL_INV2EN (1 << 2) /* Bit 2: Pair Channels 2 Inverting Enable */ +#define FTM_INVCTRL_INV3EN (1 << 3) /* Bit 3: Pair Channels 3 Inverting Enable */ + /* Bits 4-31: Reserved */ +/* FTM Software Output Control */ + +#define FTM_SWOCTRL_CHOC(n) (1 << (n)) /* Bits 0-7: Channel (n) Software Output Control Enable */ +#define FTM_SWOCTRL_CH0OC (1 << 0) /* Bit 0: Channel 0 Software Output Control Enable */ +#define FTM_SWOCTRL_CH1OC (1 << 1) /* Bit 1: Channel 1 Software Output Control Enable */ +#define FTM_SWOCTRL_CH2OC (1 << 2) /* Bit 2: Channel 2 Software Output Control Enable */ +#define FTM_SWOCTRL_CH3OC (1 << 3) /* Bit 3: Channel 3 Software Output Control Enable */ +#define FTM_SWOCTRL_CH4OC (1 << 4) /* Bit 4: Channel 4 Software Output Control Enable */ +#define FTM_SWOCTRL_CH5OC (1 << 5) /* Bit 5: Channel 5 Software Output Control Enable */ +#define FTM_SWOCTRL_CH6OC (1 << 6) /* Bit 6: Channel 6 Software Output Control Enable */ +#define FTM_SWOCTRL_CH7OC (1 << 7) /* Bit 7: Channel 7 Software Output Control Enable */ +#define FTM_SWOCTRL_CHOCV(n) (1 << ((n)+8)) /* Bits 8-15: Channel (n) Software Output Control Value */ +#define FTM_SWOCTRL_CH0OCV (1 << 8) /* Bit 8: Channel 0 Software Output Control Value */ +#define FTM_SWOCTRL_CH1OCV (1 << 9) /* Bit 9: Channel 1 Software Output Control Value */ +#define FTM_SWOCTRL_CH2OCV (1 << 10) /* Bit 10: Channel 2 Software Output Control Value */ +#define FTM_SWOCTRL_CH3OCV (1 << 11) /* Bit 11: Channel 3 Software Output Control Value */ +#define FTM_SWOCTRL_CH4OCV (1 << 12) /* Bit 12: Channel 4 Software Output Control Value */ +#define FTM_SWOCTRL_CH5OCV (1 << 13) /* Bit 13: Channel 5 Software Output Control Value */ +#define FTM_SWOCTRL_CH6OCV (1 << 14) /* Bit 14: Channel 6 Software Output Control Value */ +#define FTM_SWOCTRL_CH7OCV (1 << 15) /* Bit 15: Channel 7 Software Output Control Value */ + /* Bits 16-31: Reserved */ +/* FTM PWM Load */ + +#define FTM_PWMLOAD_CHSEL(n) (1 << (n)) /* Bits 0-7: Channel (n) Select */ +#define FTM_PWMLOAD_CH0SEL (1 << 0) /* Bit 0: Channel 0 Select */ +#define FTM_PWMLOAD_CH1SEL (1 << 1) /* Bit 1: Channel 1 Select */ +#define FTM_PWMLOAD_CH2SEL (1 << 2) /* Bit 2: Channel 2 Select */ +#define FTM_PWMLOAD_CH3SEL (1 << 3) /* Bit 3: Channel 3 Select */ +#define FTM_PWMLOAD_CH4SEL (1 << 4) /* Bit 4: Channel 4 Select */ +#define FTM_PWMLOAD_CH5SEL (1 << 5) /* Bit 5: Channel 5 Select */ +#define FTM_PWMLOAD_CH6SEL (1 << 6) /* Bit 6: Channel 6 Select */ +#define FTM_PWMLOAD_CH7SEL (1 << 7) /* Bit 7: Channel 7 Select */ + /* Bit 8: Reserved */ +#define FTM_PWMLOAD_LDOK (1 << 9) /* Bit 9: Load Enable */ + /* Bits 10-31: Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H */ diff --git a/arch/arm/src/kinetis/kinetis_gpio.h b/arch/arm/src/kinetis/kinetis_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..1d3d10553fbe93dae7787f8b953291e1df3299a8 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_gpio.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_gpio.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_GPIO_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_GPIO_PDOR_OFFSET 0x0000 /* Port Data Output Register */ +#define KINETIS_GPIO_PSOR_OFFSET 0x0004 /* Port Set Output Register */ +#define KINETIS_GPIO_PCOR_OFFSET 0x0008 /* Port Clear Output Register */ +#define KINETIS_GPIO_PTOR_OFFSET 0x000c /* Port Toggle Output Register */ +#define KINETIS_GPIO_PDIR_OFFSET 0x0010 /* Port Data Input Register */ +#define KINETIS_GPIO_PDDR_OFFSET 0x0014 /* Port Data Direction Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_GPIO_PDOR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIO_PSOR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIO_PCOR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIO_PTOR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIO_PDIR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIO_PDDR(n) (KINETIS_GPIO_BASE(n)+KINETIS_GPIO_PDDR_OFFSET) + +#define KINETIS_GPIOA_PDOR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIOA_PSOR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIOA_PCOR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIOA_PTOR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIOA_PDIR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIOA_PDDR (KINETIS_GPIOA_BASE+KINETIS_GPIO_PDDR_OFFSET) + +#define KINETIS_GPIOB_PDOR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIOB_PSOR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIOB_PCOR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIOB_PTOR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIOB_PDIR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIOB_PDDR (KINETIS_GPIOB_BASE+KINETIS_GPIO_PDDR_OFFSET) + +#define KINETIS_GPIOC_PDOR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIOC_PSOR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIOC_PCOR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIOC_PTOR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIOC_PDIR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIOC_PDDR (KINETIS_GPIOC_BASE+KINETIS_GPIO_PDDR_OFFSET) + +#define KINETIS_GPIOD_PDOR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIOD_PSOR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIOD_PCOR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIOD_PTOR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIOD_PDIR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIOD_PDDR (KINETIS_GPIOD_BASE+KINETIS_GPIO_PDDR_OFFSET) + +#define KINETIS_GPIOE_PDOR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PDOR_OFFSET) +#define KINETIS_GPIOE_PSOR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PSOR_OFFSET) +#define KINETIS_GPIOE_PCOR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PCOR_OFFSET) +#define KINETIS_GPIOE_PTOR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PTOR_OFFSET) +#define KINETIS_GPIOE_PDIR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PDIR_OFFSET) +#define KINETIS_GPIOE_PDDR (KINETIS_GPIOE_BASE+KINETIS_GPIO_PDDR_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Port Data Output Register */ + +#define GPIO_PDOR(n) (1 << (n)) + +/* Port Set Output Register */ + +#define GPIO_PSOR(n) (1 << (n)) + +/* Port Clear Output Register */ + +#define GPIO_PCOR(n) (1 << (n)) + +/* Port Toggle Output Register */ + +#define GPIO_PTOR(n) (1 << (n)) + +/* Port Data Input Register */ + +#define GPIO_PDIR(n) (1 << (n)) + +/* Port Data Direction Register */ + +#define GPIO_PDDR(n) (1 << (n)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_GPIO_H */ diff --git a/arch/arm/src/kinetis/kinetis_i2c.h b/arch/arm/src/kinetis/kinetis_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..bee9ef92db16c19ffe2dc0eb1815140211295345 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_i2c.h @@ -0,0 +1,185 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_i2c.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_I2C_A1_OFFSET 0x0000 /* I2C Address Register 1 */ +#define KINETIS_I2C_F_OFFSET 0x0001 /* I2C Frequency Divider register */ +#define KINETIS_I2C_C1_OFFSET 0x0002 /* I2C Control Register 1 */ +#define KINETIS_I2C_S_OFFSET 0x0003 /* I2C Status Register */ +#define KINETIS_I2C_D_OFFSET 0x0004 /* I2C Data I/O register */ +#define KINETIS_I2C_C2_OFFSET 0x0005 /* I2C Control Register 2 */ +#define KINETIS_I2C_FLT_OFFSET 0x0006 /* I2C Programmable Input Glitch Filter register */ +#define KINETIS_I2C_RA_OFFSET 0x0007 /* I2C Range Address register */ +#define KINETIS_I2C_SMB_OFFSET 0x0008 /* I2C SMBus Control and Status register */ +#define KINETIS_I2C_A2_OFFSET 0x0009 /* I2C Address Register 2 */ +#define KINETIS_I2C_SLTH_OFFSET 0x000a /* I2C SCL Low Timeout Register High */ +#define KINETIS_I2C_SLTL_OFFSET 0x000b /* I2C SCL Low Timeout Register Low */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_I2C0_A1 (KINETIS_I2C0_BASE+KINETIS_I2C_A1_OFFSET) +#define KINETIS_I2C0_F (KINETIS_I2C0_BASE+KINETIS_I2C_F_OFFSET) +#define KINETIS_I2C0_C1 (KINETIS_I2C0_BASE+KINETIS_I2C_C1_OFFSET) +#define KINETIS_I2C0_S (KINETIS_I2C0_BASE+KINETIS_I2C_S_OFFSET) +#define KINETIS_I2C0_D (KINETIS_I2C0_BASE+KINETIS_I2C_D_OFFSET) +#define KINETIS_I2C0_C2 (KINETIS_I2C0_BASE+KINETIS_I2C_C2_OFFSET) +#define KINETIS_I2C0_FLT (KINETIS_I2C0_BASE+KINETIS_I2C_FLT_OFFSET) +#define KINETIS_I2C0_RA (KINETIS_I2C0_BASE+KINETIS_I2C_RA_OFFSET) +#define KINETIS_I2C0_SMB (KINETIS_I2C0_BASE+KINETIS_I2C_SMB_OFFSET) +#define KINETIS_I2C0_A2 (KINETIS_I2C0_BASE+KINETIS_I2C_A2_OFFSET) +#define KINETIS_I2C0_SLTH (KINETIS_I2C0_BASE+KINETIS_I2C_SLTH_OFFSET) +#define KINETIS_I2C0_SLTL (KINETIS_I2C0_BASE+KINETIS_I2C_SLTL_OFFSET) + +#define KINETIS_I2C1_A1 (KINETIS_I2C1_BASE+KINETIS_I2C_A1_OFFSET) +#define KINETIS_I2C1_F (KINETIS_I2C1_BASE+KINETIS_I2C_F_OFFSET) +#define KINETIS_I2C1_C1 (KINETIS_I2C1_BASE+KINETIS_I2C_C1_OFFSET) +#define KINETIS_I2C1_S (KINETIS_I2C1_BASE+KINETIS_I2C_S_OFFSET) +#define KINETIS_I2C1_D (KINETIS_I2C1_BASE+KINETIS_I2C_D_OFFSET) +#define KINETIS_I2C1_C2 (KINETIS_I2C1_BASE+KINETIS_I2C_C2_OFFSET) +#define KINETIS_I2C1_FLT (KINETIS_I2C1_BASE+KINETIS_I2C_FLT_OFFSET) +#define KINETIS_I2C1_RA (KINETIS_I2C1_BASE+KINETIS_I2C_RA_OFFSET) +#define KINETIS_I2C1_SMB (KINETIS_I2C1_BASE+KINETIS_I2C_SMB_OFFSET) +#define KINETIS_I2C1_A2 (KINETIS_I2C1_BASE+KINETIS_I2C_A2_OFFSET) +#define KINETIS_I2C1_SLTH (KINETIS_I2C1_BASE+KINETIS_I2C_SLTH_OFFSET) +#define KINETIS_I2C1_SLTL (KINETIS_I2C1_BASE+KINETIS_I2C_SLTL_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* I2C Address Register 1 (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_A1_SHIFT (1) /* Bits 1-7: Address */ +#define I2C_A1_MASK (0x7f << I2C_A1_SHIFT) + +/* I2C Frequency Divider register (8-bit) */ + +#define I2C_F_ICR_SHIFT (0) /* Bits 0-5: Clock rate */ +#define I2C_F_ICR_MASK (0x3f << I2C_F_ICR_SHIFT) +#define I2C_F_MULT_SHIFT (6) /* Bits 6-7: Multiplier factor */ +#define I2C_F_MULT_MASK (3 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_1 (0 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_2 (1 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_4 (2 << I2C_F_MULT_SHIFT) + +/* I2C Control Register 1 (8-bit) */ + +#define I2C_C1_DMAEN (1 << 0) /* Bit 0: DMA enable */ +#define I2C_C1_WUEN (1 << 1) /* Bit 1: Wakeup enable */ +#define I2C_C1_RSTA (1 << 2) /* Bit 2: Repeat START */ +#define I2C_C1_TXAK (1 << 3) /* Bit 3: Transmit acknowledge enable */ +#define I2C_C1_TX (1 << 4) /* Bit 4: Transmit mode select */ +#define I2C_C1_MST (1 << 5) /* Bit 5: Master mode select */ +#define I2C_C1_IICIE (1 << 6) /* Bit 6: I2C interrupt enable */ +#define I2C_C1_IICEN (1 << 7) /* Bit 7: I2C enable */ + +/* I2C Status Register (8-bit) */ + +#define I2C_S_RXAK (1 << 0) /* Bit 0: Receive acknowledge */ +#define I2C_S_IICIF (1 << 1) /* Bit 1: Interrupt flag */ +#define I2C_S_SRW (1 << 2) /* Bit 2: Slave read/write */ +#define I2C_S_RAM (1 << 3) /* Bit 3: Range address match */ +#define I2C_S_ARBL (1 << 4) /* Bit 4: Arbitration lost */ +#define I2C_S_BUSY (1 << 5) /* Bit 5: Bus busy */ +#define I2C_S_IAAS (1 << 6) /* Bit 6: Addressed as a slave */ +#define I2C_S_TCF (1 << 7) /* Bit 7: Transfer complete flag */ + +/* I2C Data I/O register (8-bit data register) */ + +/* I2C Control Register 2 (8-bit) */ + +#define I2C_C2_AD_SHIFT (0) /* Bits 0-2: Slave address */ +#define I2C_C2_AD_MASK (7 << I2C_C2_AD_SHIFT) +#define I2C_C2_RMEN (1 << 3) /* Bit 3: Range address matching enable */ +#define I2C_C2_SBRC (1 << 4) /* Bit 4: Slave baud rate control */ +#define I2C_C2_HDRS (1 << 5) /* Bit 5: High drive select */ +#define I2C_C2_ADEXT (1 << 6) /* Bit 6: Address extension */ +#define I2C_C2_GCAEN (1 << 7) /* Bit 7: General call address enable */ + +/* I2C Programmable Input Glitch Filter register (8-bit) */ + /* Bits 5-7: Reserved */ +#define I2C_FLT_SHIFT (0) /* Bits 0-4: I2C programmable filter factor */ +#define I2C_FLT_MASK (31 << I2C_FLT_SHIFT) + +/* I2C Range Address register (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_RA_SHIFT (1) /* Bits 1-7: Range slave address */ +#define I2C_RA_MASK (0x7f << I2C_RA_SHIFT) + +/* I2C SMBus Control and Status register (8-bit) */ + +#define I2C_SMB_SHTF2IE (1 << 0) /* Bit 0: SHTF2 interrupt enable */ +#define I2C_SMB_SHTF2 (1 << 1) /* Bit 1: SCL high timeout flag 2 */ +#define I2C_SMB_SHTF1 (1 << 2) /* Bit 2: SCL high timeout flag 1 */ +#define I2C_SMB_SLTF (1 << 3) /* Bit 3: SCL low timeout flag */ +#define I2C_SMB_TCKSEL (1 << 4) /* Bit 4: Timeout counter clock select */ +#define I2C_SMB_SIICAEN (1 << 5) /* Bit 5: Second I2C address enable */ +#define I2C_SMB_ALERTEN (1 << 6) /* Bit 6: SMBus alert response address enable */ +#define I2C_SMB_FACK (1 << 7) /* Bit 7: Fast NACK/ACK enable */ + +/* I2C Address Register 2 (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_A2_SHIFT (1) /* Bits 1-7: SMBus address */ +#define I2C_A2_MASK (0x7f << I2C_A2_SHIFT) + +/* I2C SCL Low Timeout Register High/Low (16-bit data in two 8-bit registers) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H */ diff --git a/arch/arm/src/kinetis/kinetis_i2s.h b/arch/arm/src/kinetis/kinetis_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..11bcc0995562bbb550a7380bf8191bf8534e2c42 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_i2s.h @@ -0,0 +1,297 @@ +/**************************************************************************************************** + * arch/arm/src/kinetis/kinetis_i2s.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define KINETIS_I2S_TX0_OFFSET 0x000 /* I2S Transmit Data Registers 0 */ +#define KINETIS_I2S_TX1_OFFSET 0x004 /* I2S Transmit Data Registers 1 */ +#define KINETIS_I2S_RX0_OFFSET 0x008 /* I2S Receive Data Registers 0 */ +#define KINETIS_I2S_RX1_OFFSET 0x00c /* I2S Receive Data Registers 1 */ +#define KINETIS_I2S_CR_OFFSET 0x010 /* I2S Control Register */ +#define KINETIS_I2S_ISR_OFFSET 0x014 /* I2S Interrupt Status Register */ +#define KINETIS_I2S_IER_OFFSET 0x018 /* I2S Interrupt Enable Register */ +#define KINETIS_I2S_TCR_OFFSET 0x01c /* I2S Transmit Configuration Register */ +#define KINETIS_I2S_RCR_OFFSET 0x020 /* I2S Receive Configuration Register */ +#define KINETIS_I2S_TCCR_OFFSET 0x024 /* I2S Transmit Clock Control Registers */ +#define KINETIS_I2S_RCCR_OFFSET 0x028 /* I2S Receive Clock Control Registers */ +#define KINETIS_I2S_FCSR_OFFSET 0x02c /* I2S FIFO Control/Status Register */ +#define KINETIS_I2S_ACNT_OFFSET 0x038 /* I2S AC97 Control Register */ +#define KINETIS_I2S_ACADD_OFFSET 0x03c /* I2S AC97 Command Address Register */ +#define KINETIS_I2S_ACDAT_OFFSET 0x040 /* I2S AC97 Command Data Register */ +#define KINETIS_I2S_ATAG_OFFSET 0x044 /* I2S AC97 Tag Register */ +#define KINETIS_I2S_TMSK_OFFSET 0x048 /* I2S Transmit Time Slot Mask Register */ +#define KINETIS_I2S_RMSK_OFFSET 0x04c /* I2S Receive Time Slot Mask Register */ +#define KINETIS_I2S_ACCST_OFFSET 0x050 /* I2S AC97 Channel Status Register */ +#define KINETIS_I2S_ACCEN_OFFSET 0x054 /* I2S AC97 Channel Enable Register */ +#define KINETIS_I2S_ACCDIS_OFFSET 0x058 /* I2S AC97 Channel Disable Register */ + +/* Register Addresses *******************************************************************************/ + +#define KINETIS_I2S0_TX0 (KINETIS_I2S0_BASE+KINETIS_I2S_TX0_OFFSET) +#define KINETIS_I2S0_TX1 (KINETIS_I2S0_BASE+KINETIS_I2S_TX1_OFFSET) +#define KINETIS_I2S0_RX0 (KINETIS_I2S0_BASE+KINETIS_I2S_RX0_OFFSET) +#define KINETIS_I2S0_RX1 (KINETIS_I2S0_BASE+KINETIS_I2S_RX1_OFFSET) +#define KINETIS_I2S0_CR (KINETIS_I2S0_BASE+KINETIS_I2S_CR_OFFSET) +#define KINETIS_I2S0_ISR (KINETIS_I2S0_BASE+KINETIS_I2S_ISR_OFFSET) +#define KINETIS_I2S0_IER (KINETIS_I2S0_BASE+KINETIS_I2S_IER_OFFSET) +#define KINETIS_I2S0_TCR (KINETIS_I2S0_BASE+KINETIS_I2S_TCR_OFFSET) +#define KINETIS_I2S0_RCR (KINETIS_I2S0_BASE+KINETIS_I2S_RCR_OFFSET) +#define KINETIS_I2S0_TCCR (KINETIS_I2S0_BASE+KINETIS_I2S_TCCR_OFFSET) +#define KINETIS_I2S0_RCCR (KINETIS_I2S0_BASE+KINETIS_I2S_RCCR_OFFSET) +#define KINETIS_I2S0_FCSR (KINETIS_I2S0_BASE+KINETIS_I2S_FCSR_OFFSET) +#define KINETIS_I2S0_ACNT (KINETIS_I2S0_BASE+KINETIS_I2S_ACNT_OFFSET) +#define KINETIS_I2S0_ACADD (KINETIS_I2S0_BASE+KINETIS_I2S_ACADD_OFFSET) +#define KINETIS_I2S0_ACDAT (KINETIS_I2S0_BASE+KINETIS_I2S_ACDAT_OFFSET) +#define KINETIS_I2S0_ATAG (KINETIS_I2S0_BASE+KINETIS_I2S_ATAG_OFFSET) +#define KINETIS_I2S0_TMSK (KINETIS_I2S0_BASE+KINETIS_I2S_TMSK_OFFSET) +#define KINETIS_I2S0_RMSK (KINETIS_I2S0_BASE+KINETIS_I2S_RMSK_OFFSET) +#define KINETIS_I2S0_ACCST (KINETIS_I2S0_BASE+KINETIS_I2S_ACCST_OFFSET) +#define KINETIS_I2S0_ACCEN (KINETIS_I2S0_BASE+KINETIS_I2S_ACCEN_OFFSET) +#define KINETIS_I2S0_ACCDIS (KINETIS_I2S0_BASE+KINETIS_I2S_ACCDIS_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* I2S Transmit Data Registers 0/1 and I2S Receive Data Registers 0/1: 32-bit I2S data */ + +/* I2S Control Register */ + +#define I2S_CR_I2SEN (1 << 0) /* Bit 0: I2S Enable */ +#define I2S_CR_TE (1 << 1) /* Bit 1: Transmit Enable */ +#define I2S_CR_RE (1 << 2) /* Bit 2: Receive Enable */ +#define I2S_CR_NET (1 << 3) /* Bit 3: Network Mode */ +#define I2S_CR_SYN (1 << 4) /* Bit 4: Synchronous Mode */ +#define I2S_CR_I2SMODE_SHIFT (5) /* Bits 5-6: I2S Mode Select */ +#define I2S_CR_I2SMODE_MASK (3 << I2S_CR_I2SMODE_SHIFT) +# define I2S_CR_I2SMODE_NORMAL (0 << I2S_CR_I2SMODE_SHIFT) /* Normal mode */ +# define I2S_CR_I2SMODE_MASTER (1 << I2S_CR_I2SMODE_SHIFT) /* I2S master mode */ +# define I2S_CR_I2SMODE_SLAVE (2 << I2S_CR_I2SMODE_SHIFT) /* I2S slave mode */ +#define I2S_CR_SYSCLKEN (1 << 7) /* Bit 7: System Clock (Oversampling Clock) Enable */ +#define I2S_CR_TCHEN (1 << 8) /* Bit 8: Two-Channel Operation Enable */ +#define I2S_CR_CLKIST (1 << 9) /* Bit 9: Clock Idle */ +#define I2S_CR_TFRCLKDIS (1 << 10) /* Bit 10: Transmit Frame Clock Disable */ +#define I2S_CR_RFRCLKDIS (1 << 11) /* Bit 11: Receive Frame Clock Disable */ +#define I2S_CR_SYNCTXFS (1 << 12) /* Bit 12: CR[TE] latched with FS occurrence */ + /* Bits 13-31: Reserved */ +/* I2S Interrupt Status Register and I2S Interrupt Enable Register common bit definitions */ + +#define I2S_INT_TFE0 (1 << 0) /* Bit 0: Transmit FIFO Empty 0 */ +#define I2S_INT_TFE1 (1 << 1) /* Bit 1: Transmit FIFO Empty 1 */ +#define I2S_INT_RFF0 (1 << 2) /* Bit 2: Receive FIFO Full 0 */ +#define I2S_INT_RFF1 (1 << 3) /* Bit 3: Receive FIFO Full 1 */ +#define I2S_INT_RLS (1 << 4) /* Bit 4: Receive Last Time Slot */ +#define I2S_INT_TLS (1 << 5) /* Bit 5: Transmit Last Time Slot */ +#define I2S_INT_RFS (1 << 6) /* Bit 6: Receive Frame Sync */ +#define I2S_INT_TFS (1 << 7) /* Bit 7: Transmit Frame Sync */ +#define I2S_INT_TUE0 (1 << 8) /* Bit 8: Transmitter Underrun Error 1 */ +#define I2S_INT_TUE1 (1 << 9) /* Bit 9: Transmitter Underrun Error 1 */ +#define I2S_INT_ROE0 (1 << 10) /* Bit 10: Receiver Overrun Error 0 */ +#define I2S_INT_ROE1 (1 << 11) /* Bit 11: Receiver Overrun Error 1 */ +#define I2S_INT_TDE0 (1 << 12) /* Bit 12: Transmit Data Register Empty 0 */ +#define I2S_INT_TDE1 (1 << 13) /* Bit 13: Transmit Data Register Empty 1 */ +#define I2S_INT_RDR0 (1 << 14) /* Bit 14: Receive Data Ready 0 */ +#define I2S_INT_RDR1 (1 << 15) /* Bit 15: Receive Data Ready 1 */ +#define I2S_INT_RXT (1 << 16) /* Bit 16: Receive Tag Updated */ +#define I2S_INT_CMDDU (1 << 17) /* Bit 17: Command Data Register Updated */ +#define I2S_INT_CMDAU (1 << 18) /* Bit 18: Command Address Register Updated */ + /* Bits 19-22: Reserved */ +#define I2S_INT_TRFC (1 << 23) /* Bit 23: Transmit Frame Complete */ +#define I2S_INT_RFRC (1 << 24) /* Bit 24: Receive Frame Complete */ + /* Bits 25-31: Reserved */ +/* I2S Interrupt Status Register (see common definitions above) */ +/* I2S Interrupt Enable Register (see common definitions above and unique definitions below)*/ + /* Bits 0-18: See common definitions above */ +#define I2S_IER_TIE (1 << 19) /* Bit 19: Transmit Interrupt Enable */ +#define I2S_IER_TDMAE (1 << 20) /* Bit 20: Transmit DMA Enable */ +#define I2S_IER_RIE (1 << 21) /* Bit 21: Receive Interrupt Enable */ +#define I2S_IER_RDMAE (1 << 22) /* Bit 22: Receive DMA Enable */ + /* Bits 23-24: See common definitions above */ + /* Bits 25-31: Reserved */ +/* I2S Transmit Configuration Register */ + +#define I2S_TCR_TEFS (1 << 0) /* Bit 0: Transmit Early Frame Sync */ +#define I2S_TCR_TFSL (1 << 1) /* Bit 1: Transmit Frame Sync Length */ +#define I2S_TCR_TFSI (1 << 2) /* Bit 2: Transmit Frame Sync Invert */ +#define I2S_TCR_TSCKP (1 << 3) /* Bit 3: Transmit Clock Polarity */ +#define I2S_TCR_TSHFD (1 << 4) /* Bit 4: Transmit Shift Direction */ +#define I2S_TCR_TXDIR (1 << 5) /* Bit 5: Transmit clock direction */ +#define I2S_TCR_TFDIR (1 << 6) /* Bit 6: Transmit Frame Direction */ +#define I2S_TCR_TFEN0 (1 << 7) /* Bit 7: Transmit FIFO Enable 0 */ +#define I2S_TCR_TFEN1 (1 << 8) /* Bit 8: Transmit FIFO Enable 1 */ +#define I2S_TCR_TXBIT0 (1 << 9) /* Bit 9: Transmit Bit 0 */ + /* Bits 10-31: Reserved */ +/* I2S Receive Configuration Register */ + +#define I2S_RCR_REFS (1 << 0) /* Bit 0: Receive Early Frame Sync */ +#define I2S_RCR_RFSL (1 << 1) /* Bit 1: Receive Frame Sync Length */ +#define I2S_RCR_RFSI (1 << 2) /* Bit 2: Receive Frame Sync Invert */ +#define I2S_RCR_RSCKP (1 << 3) /* Bit 3: Receive Clock Polarity */ +#define I2S_RCR_RSHFD (1 << 4) /* Bit 4: Receive Shift Direction */ +#define I2S_RCR_RXDIR (1 << 5) /* Bit 5: Receive Clock Direction */ +#define I2S_RCR_RFDIR (1 << 6) /* Bit 6: Receive Frame Direction */ +#define I2S_RCR_RFEN0 (1 << 7) /* Bit 7: Receive FIFO Enable 0 */ +#define I2S_RCR_RFEN1 (1 << 8) /* Bit 8: Receive FIFO Enable 1 */ +#define I2S_RCR_RXBIT0 (1 << 9) /* Bit 9: Receive Bit 0 */ +#define I2S_RCR_RXEXT (1 << 10) /* Bit 10: Receive Data Extension */ + /* Bits 11-31: Reserved */ +/* I2S Transmit Clock Control Registers */ + +#define I2S_TCCR_PM_SHIFT (0) /* Bits 0-7: Prescaler Modulus Select */ +#define I2S_TCCR_PM_MASK (0xff << I2S_TCCR_PM_SHIFT) +#define I2S_TCCR_DC_SHIFT (8) /* Bits 8-12: Frame Rate Divider Control */ +#define I2S_TCCR_DC_MASK (31 << I2S_TCCR_DC_SHIFT) +#define I2S_TCCR_WL_SHIFT (13) /* Bits 13-16: Word Length Control */ +#define I2S_TCCR_WL_MASK (15 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_8 (3 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_10 (4 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_12 (5 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_16 (7 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_18 (8 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_20 (9 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_22 (10 << I2S_TCCR_WL_SHIFT) +# define I2S_TCCR_WL_24 (11 << I2S_TCCR_WL_SHIFT) +#define I2S_TCCR_PSR (1 << 17) /* Bit 17: Prescaler Range */ +#define I2S_TCCR_DIV2 (1 << 18) /* Bit 18: Divide By 2 */ + /* Bits 19-31: Reserved */ +/* I2S Receive Clock Control Registers */ + +#define I2S_RCCR_PM_SHIFT (0) /* Bits 0-7: Prescaler Modulus Select */ +#define I2S_RCCR_PM_MASK (0xff << I2S_RCCR_PM_SHIFT) +#define I2S_RCCR_DC_SHIFT (8) /* Bits 8-12: Frame Rate Divider Control */ +#define I2S_RCCR_DC_MASK (31 << I2S_RCCR_DC_SHIFT) +#define I2S_RCCR_WL_SHIFT (13) /* Bits 13-16: Word Length Control */ +#define I2S_RCCR_WL_MASK (15 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_8 (3 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_10 (4 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_12 (5 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_16 (7 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_18 (8 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_20 (9 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_22 (10 << I2S_RCCR_WL_SHIFT) +# define I2S_RCCR_WL_24 (11 << I2S_RCCR_WL_SHIFT) +#define I2S_RCCR_PSR (1 << 17) /* Bit 17: Prescaler Range */ +#define I2S_RCCR_DIV2 (1 << 18) /* Bit 18: Divide By 2 */ + /* Bits 19-31: Reserved */ +/* I2S FIFO Control/Status Register */ + +#define I2S_FCSR_TFWM0_SHIFT (0) /* Bits 0-3: Transmit FIFO Empty WaterMark 0 */ +#define I2S_FCSR_TFWM0_MASK (15 << I2S_FCSR_TFWM0_SHIFT) +#define I2S_FCSR_RFWM0_SHIFT (4) /* Bits 4-7: Receive FIFO Full WaterMark 0 */ +#define I2S_FCSR_RFWM0_MASK (15 << I2S_FCSR_RFWM0_SHIFT) +#define I2S_FCSR_TFCNT0_SHIFT (8) /* Bits 8-11: Transmit FIFO Counter 0 */ +#define I2S_FCSR_TFCNT0_MASK (15 << I2S_FCSR_TFCNT0_SHIFT) +#define I2S_FCSR_RFCNT0_SHIFT (12) /* Bits 12-15: Receive FIFO Counter 0 */ +#define I2S_FCSR_RFCNT0_MASK (15 << I2S_FCSR_RFCNT0_SHIFT) +#define I2S_FCSR_TFWM1_SHIFT (16) /* Bits 16-19: Transmit FIFO Empty WaterMark 1 */ +#define I2S_FCSR_TFWM1_MASK (15 << I2S_FCSR_TFWM1_SHIFT) +#define I2S_FCSR_RFWM1_SHIFT (20) /* Bits 20-23: Receive FIFO Full WaterMark 1 */ +#define I2S_FCSR_RFWM1_MASK (15 << I2S_FCSR_RFWM1_SHIFT) +#define I2S_FCSR_TFCNT1_SHIFT (24) /* Bits 24-27: Transmit FIFO Counter 1 */ +#define I2S_FCSR_TFCNT1_MASK (15 << I2S_FCSR_TFCNT1_SHIFT) +#define I2S_FCSR_RFCNT1_SHIFT (28) /* Bits 28-31: Receive FIFO Counter 1 */ +#define I2S_FCSR_RFCNT1_MASK (15 << I2S_FCSR_RFCNT1_SHIFT) + +/* I2S AC97 Control Register */ + +#define I2S_ACNT_AC97EN (1 << 0) /* Bit 0: AC97 Mode Enable */ +#define I2S_ACNT_FV (1 << 1) /* Bit 1: Fixed/Variable Operation */ +#define I2S_ACNT_TIF (1 << 2) /* Bit 2: Tag in FIFO */ +#define I2S_ACNT_RD (1 << 3) /* Bit 3: Read Command */ +#define I2S_ACNT_WR (1 << 4) /* Bit 4: Write Command */ +#define I2S_ACNT_FRDIV_SHIFT (5) /* Bits 5-10: Frame Rate Divider */ +#define I2S_ACNT_FRDIV_MASK (63 << I2S_ACNT_FRDIV_SHIFT) + /* Bits 11-31: Reserved */ +/* I2S AC97 Command Address Register */ + +#define I2S_ACADD_ACADD_SHIFT (0) /* Bits 0-18: AC97 Command Address */ +#define I2S_ACADD_ACADD_MASK (0x7ffff << I2S_ACADD_ACADD_SHIFT) + /* Bits 19-31: Reserved */ +/* I2S AC97 Command Data Register */ + +#define I2S_ACDAT_ACADD_SHIFT (0) /* Bits 0-18: AC97 Command Data */ +#define I2S_ACDAT_ACADD_MASK (0x7ffff << I2S_ACDAT_ACADD_SHIFT) + /* Bits 19-31: Reserved */ +/* I2S AC97 Tag Register */ + +#define I2S_ATAG_ACADD_SHIFT (0) /* Bits 0-15: AC97 Tag Value */ +#define I2S_ATAG_ACADD_MASK (0xffff << I2S_ACDAT_ACADD_SHIFT) + /* Bits 16-31: Reserved */ +/* I2S Transmit Time Slot Mask Register (32-bit Transmit Mask) */ +/* I2S Receive Time Slot Mask Register (32-bit Receive Mask) */ + +/* I2S AC97 Channel Status Register */ + +#define I2S_ACCST_ACCST_SHIFT (0) /* Bits 0-9: AC97 Channel Status */ +#define I2S_ACCST_ACCST_MASK (0x3ff << I2S_ACCST_ACCST_SHIFT) + /* Bits 10-31: Reserved */ +/* I2S AC97 Channel Enable Register */ + +#define I2S_ACCEN_ACCST_SHIFT (0) /* Bits 0-9: AC97 Channel Enable */ +#define I2S_ACCEN_ACCST_MASK (0x3ff << I2S_ACCEN_ACCST_SHIFT) + /* Bits 10-31: Reserved */ +/* I2S AC97 Channel Disable Register */ +#define I2S__ + +#define I2S_ACCDIS_ACCST_SHIFT (0) /* Bits 0-9: AC97 AC97 Channel Disable */ +#define I2S_ACCDIS_ACCST_MASK (0x3ff << I2S_ACCEN_ACCST_SHIFT) + /* Bits 10-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H */ diff --git a/arch/arm/src/kinetis/kinetis_idle.c b/arch/arm/src/kinetis/kinetis_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..71ee037c14cf124e4bfa003bfef37a49325afeba --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_idle.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_idle.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Sleep until an interrupt occurs to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} + diff --git a/arch/arm/src/kinetis/kinetis_irq.c b/arch/arm/src/kinetis/kinetis_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..456dc140a2e13fed34b6cc7e75fdd196a241901b --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_irq.c @@ -0,0 +1,588 @@ +/**************************************************************************** + * arch/arm/src/lpc17/kinetis_irq.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" +#include "kinetis.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void kinetis_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE); + getreg32(NVIC_IRQ64_95_ENABLE), getreg32(NVIC_IRQ96_127_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), getreg32(NVIC_IRQ92_95_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), getreg32(NVIC_IRQ108_111_PRIORITY)); +#if NR_VECTORS > 111 + lldbg(" %08x %08x\n", + getreg32(NVIC_IRQ112_115_PRIORITY), getreg32(NVIC_IRQ116_119_PRIORITY)); +#endif + + leave_critical_section(flags); +} +#else +# define kinetis_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: kinetis_nmi, kinetis_busfault, kinetis_usagefault, kinetis_pendsv, + * kinetis_dbgmonitor, kinetis_pendsv, kinetis_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int kinetis_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int kinetis_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int kinetis_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int kinetis_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int kinetis_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int kinetis_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: kinetis_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void kinetis_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: kinetis_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int kinetis_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= KINETIS_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= KINETIS_IRQ_EXTINT) + { + if (irq < (KINETIS_IRQ_EXTINT+32)) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - KINETIS_IRQ_EXTINT); + } + else if (irq < (KINETIS_IRQ_EXTINT+64)) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - KINETIS_IRQ_EXTINT - 32); + } + else if (irq < (KINETIS_IRQ_EXTINT+96)) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - KINETIS_IRQ_EXTINT - 64); + } + else if (irq < NR_IRQS) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (irq - KINETIS_IRQ_EXTINT - 96); + } + else + { + return ERROR; /* Invalid irq */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == KINETIS_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == KINETIS_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == KINETIS_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == KINETIS_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(KINETIS_IRQ_SVCALL, up_svcall); + irq_attach(KINETIS_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(KINETIS_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + kinetis_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault); + up_enable_irq(KINETIS_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(KINETIS_IRQ_NMI, kinetis_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault); + irq_attach(KINETIS_IRQ_USAGEFAULT, kinetis_usagefault); + irq_attach(KINETIS_IRQ_PENDSV, kinetis_pendsv); + irq_attach(KINETIS_IRQ_DBGMONITOR, kinetis_dbgmonitor); + irq_attach(KINETIS_IRQ_RESERVED, kinetis_reserved); +#endif + + kinetis_dumpnvic("initial", NR_IRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * configured pin interrupts. + */ + +#ifdef CONFIG_GPIO_IRQ + kinetis_pinirqinitialize(); +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (kinetis_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= KINETIS_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + kinetis_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (kinetis_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= KINETIS_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + kinetis_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +#if 0 /* Does not appear to be necessary in most cases */ + kinetis_clrpend(irq); +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= KINETIS_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < KINETIS_IRQ_EXTINT) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= KINETIS_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + kinetis_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/kinetis/kinetis_k20pinmux.h b/arch/arm/src/kinetis/kinetis_k20pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..a4ca3eda29b7dfd8ee96ff4d4be9b89133adf717 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_k20pinmux.h @@ -0,0 +1,352 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_k40pinmux.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Reference: Paragraph 10.3.1, p 207, of FreeScale document K20P64M72SF1RM + * + * In most cases, there are alternative configurations for various pins. Those alternative + * pins are labelled with a suffix like _1, _2, etc. in order to distinguish them. Logic in + * the board.h file must select the correct pin configuration for the board by defining a pin + * configuration (with no suffix) that maps to the correct alternative. + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) + +# define PIN_ADC0_SE4b (PIN_ALT0 | PIN_PORTC | PIN2) +# define PIN_ADC0_SE5b (PIN_ALT0 | PIN_PORTD | PIN1) +# define PIN_ADC0_SE6b (PIN_ALT0 | PIN_PORTD | PIN5) +# define PIN_ADC0_SE7b (PIN_ALT0 | PIN_PORTD | PIN6) +# define PIN_ADC0_SE8 (PIN_ALT0 | PIN_PORTB | PIN0) +# define PIN_ADC0_SE9 (PIN_ALT0 | PIN_PORTB | PIN1) +# define PIN_ADC0_SE12 (PIN_ALT0 | PIN_PORTB | PIN2) +# define PIN_ADC0_SE13 (PIN_ALT0 | PIN_PORTB | PIN3) +# define PIN_ADC0_SE14 (PIN_ALT0 | PIN_PORTC | PIN0) +# define PIN_ADC0_SE15 (PIN_ALT0 | PIN_PORTC | PIN1) +# define PIN_ADC1_SE4a (PIN_ALT0 | PIN_PORTE | PIN0) +# define PIN_ADC1_SE4b (PIN_ALT0 | PIN_PORTC | PIN8) +# define PIN_ADC1_SE5a (PIN_ALT0 | PIN_PORTE | PIN1) +# define PIN_ADC1_SE5b (PIN_ALT0 | PIN_PORTC | PIN9) +# define PIN_ADC1_SE6b (PIN_ALT0 | PIN_PORTC | PIN10) +# define PIN_ADC1_SE7b (PIN_ALT0 | PIN_PORTC | PIN11) +# define PIN_ADC1_SE8 (PIN_ALT0 | PIN_PORTB | PIN0) +# define PIN_ADC1_SE9 (PIN_ALT0 | PIN_PORTB | PIN1) + +# define PIN_CAN0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN13) +# define PIN_CAN0_RX_2 (PIN_ALT2 | PIN_PORTB | PIN19) +# define PIN_CAN0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN12) +# define PIN_CAN0_TX_2 (PIN_ALT2 | PIN_PORTB | PIN18) +# define PIN_CLKOUT (PIN_ALT5 | PIN_PORTC | PIN3) +# define PIN_CMP0_IN0 (PIN_ALT0 | PIN_PORTC | PIN6) +# define PIN_CMP0_IN1 (PIN_ALT0 | PIN_PORTC | PIN7) +# define PIN_CMP0_IN2 (PIN_ALT0 | PIN_PORTC | PIN8) +# define PIN_CMP0_IN3 (PIN_ALT0 | PIN_PORTC | PIN9) +# define PIN_CMP0_OUT (PIN_ALT6 | PIN_PORTC | PIN5) +# define PIN_CMP1_IN0 (PIN_ALT0 | PIN_PORTC | PIN2) +# define PIN_CMP1_IN1 (PIN_ALT0 | PIN_PORTC | PIN3) +# define PIN_CMP1_OUT (PIN_ALT6 | PIN_PORTC | PIN4) +# define PIN_CMP2_IN0 (PIN_ALT0 | PIN_PORTA | PIN12) +# define PIN_CMP2_IN1 (PIN_ALT0 | PIN_PORTA | PIN13) +# define PIN_CMP2_OUT (PIN_ALT4 | PIN_PORTA | PIN5) +# define PIN_CMT_IRO (PIN_ALT2 | PIN_PORTD | PIN7) +# define PIN_EWM_IN_1 (PIN_ALT6 | PIN_PORTB | PIN16) +# define PIN_EWM_IN_2 (PIN_ALT6 | PIN_PORTD | PIN4) +# define PIN_EWM_OUT_b_1 (PIN_ALT6 | PIN_PORTB | PIN17) +# define PIN_EWM_OUT_b_2 (PIN_ALT6 | PIN_PORTD | PIN5) + +# define PIN_FB_AD0 (PIN_ALT5 | PIN_PORTD | PIN6) +# define PIN_FB_AD1 (PIN_ALT5 | PIN_PORTD | PIN5) +# define PIN_FB_AD2 (PIN_ALT5 | PIN_PORTD | PIN4) +# define PIN_FB_AD3 (PIN_ALT5 | PIN_PORTD | PIN3) +# define PIN_FB_AD4 (PIN_ALT5 | PIN_PORTD | PIN2) +# define PIN_FB_AD5 (PIN_ALT5 | PIN_PORTC | PIN10) +# define PIN_FB_AD6 (PIN_ALT5 | PIN_PORTC | PIN9) +# define PIN_FB_AD7 (PIN_ALT5 | PIN_PORTC | PIN8) +# define PIN_FB_AD8 (PIN_ALT5 | PIN_PORTC | PIN7) +# define PIN_FB_AD9 (PIN_ALT5 | PIN_PORTC | PIN6) +# define PIN_FB_AD10 (PIN_ALT5 | PIN_PORTC | PIN5) +# define PIN_FB_AD11 (PIN_ALT5 | PIN_PORTC | PIN4) +# define PIN_FB_AD12 (PIN_ALT5 | PIN_PORTC | PIN2) +# define PIN_FB_AD13 (PIN_ALT5 | PIN_PORTC | PIN1) +# define PIN_FB_AD14 (PIN_ALT5 | PIN_PORTC | PIN0) +# define PIN_FB_AD15 (PIN_ALT5 | PIN_PORTB | PIN18) +# define PIN_FB_AD16 (PIN_ALT5 | PIN_PORTB | PIN17) +# define PIN_FB_AD17 (PIN_ALT5 | PIN_PORTB | PIN16) +# define PIN_FB_ALE (PIN_ALT5 | PIN_PORTD | PIN0) +# define PIN_FB_CS0_b (PIN_ALT5 | PIN_PORTD | PIN1) +# define PIN_FB_CS1_b (PIN_ALT5 | PIN_PORTD | PIN0) +# define PIN_FB_OE_b (PIN_ALT5 | PIN_PORTB | PIN19) +# define PIN_FB_RW_b (PIN_ALT5 | PIN_PORTC | PIN11) +# define PIN_FB_TS_b (PIN_ALT5 | PIN_PORTD | PIN0) + +# define PIN_FTM_CLKIN0 (PIN_ALT4 | PIN_PORTA | PIN18) +# define PIN_FTM_CLKIN1 (PIN_ALT4 | PIN_PORTA | PIN19) +# define PIN_FTM0_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN3) +# define PIN_FTM0_CH0_2 (PIN_ALT4 | PIN_PORTC | PIN1) +# define PIN_FTM0_CH1_1 (PIN_ALT2 | PIN_PORTA | PIN4) +# define PIN_FTM0_CH1_2 (PIN_ALT4 | PIN_PORTC | PIN2) +# define PIN_FTM0_CH2_1 (PIN_ALT2 | PIN_PORTA | PIN5) +# define PIN_FTM0_CH2_2 (PIN_ALT4 | PIN_PORTC | PIN3) +# define PIN_FTM0_CH3 (PIN_ALT4 | PIN_PORTC | PIN4) +# define PIN_FTM0_CH4 (PIN_ALT4 | PIN_PORTD | PIN4) +# define PIN_FTM0_CH5_1 (PIN_ALT3 | PIN_PORTA | PIN0) +# define PIN_FTM0_CH5_2 (PIN_ALT4 | PIN_PORTD | PIN5) +# define PIN_FTM0_CH6_1 (PIN_ALT3 | PIN_PORTA | PIN1) +# define PIN_FTM0_CH6_2 (PIN_ALT4 | PIN_PORTD | PIN6) +# define PIN_FTM0_CH7_1 (PIN_ALT3 | PIN_PORTA | PIN2) +# define PIN_FTM0_CH7_2 (PIN_ALT4 | PIN_PORTD | PIN7) +# define PIN_FTM0_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN3) +# define PIN_FTM0_FLT0_2 (PIN_ALT6 | PIN_PORTD | PIN6) +# define PIN_FTM0_FLT1 (PIN_ALT6 | PIN_PORTD | PIN7) +# define PIN_FTM0_FLT2 (PIN_ALT3 | PIN_PORTA | PIN18) +# define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2) +# define PIN_FTM1_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN12) +# define PIN_FTM1_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN0) +# define PIN_FTM1_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN13) +# define PIN_FTM1_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN1) +# define PIN_FTM1_FLT0 (PIN_ALT3 | PIN_PORTA | PIN19) +# define PIN_FTM1_QD_PHA_1 (PIN_ALT6 | PIN_PORTB | PIN0) +# define PIN_FTM1_QD_PHA_2 (PIN_ALT7 | PIN_PORTA | PIN12) +# define PIN_FTM1_QD_PHB_1 (PIN_ALT6 | PIN_PORTB | PIN1) +# define PIN_FTM1_QD_PHB_2 (PIN_ALT7 | PIN_PORTA | PIN13) +# define PIN_FTM2_CH0 (PIN_ALT3 | PIN_PORTB | PIN18) +# define PIN_FTM2_CH1 (PIN_ALT3 | PIN_PORTB | PIN19) +# define PIN_FTM2_FLT0 (PIN_ALT6 | PIN_PORTC | PIN9) +# define PIN_FTM2_QD_PHA (PIN_ALT6 | PIN_PORTB | PIN18) +# define PIN_FTM2_QD_PHB (PIN_ALT6 | PIN_PORTB | PIN19) + +# define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0) +# define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2) +# define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1) +# define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3) +# define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10) +# define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1) +# define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11) +# define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0) + +# define PIN_I2S0_MCLK_1 (PIN_ALT4 | PIN_PORTC | PIN8) +# define PIN_I2S0_MCLK_2 (PIN_ALT6 | PIN_PORTC | PIN6) +# define PIN_I2S0_RX_BCLK_1 (PIN_ALT4 | PIN_PORTC | PIN6) +# define PIN_I2S0_RX_BCLK_2 (PIN_ALT4 | PIN_PORTC | PIN9) +# define PIN_I2S0_RX_FS_1 (PIN_ALT4 | PIN_PORTC | PIN10) +# define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN7) +# define PIN_I2S0_RXD0 (PIN_ALT4 | PIN_PORTC | PIN5) +# define PIN_I2S0_RXD1 (PIN_ALT4 | PIN_PORTC | PIN11) +# define PIN_I2S0_TX_BCLK_1 (PIN_ALT4 | PIN_PORTB | PIN18) +# define PIN_I2S0_TX_BCLK_2 (PIN_ALT5 | PIN_PORTA | PIN5) +# define PIN_I2S0_TX_BCLK_3 (PIN_ALT6 | PIN_PORTC | PIN3) +# define PIN_I2S0_TX_FS_1 (PIN_ALT4 | PIN_PORTB | PIN19) +# define PIN_I2S0_TX_FS_2 (PIN_ALT6 | PIN_PORTA | PIN13) +# define PIN_I2S0_TX_FS_3 (PIN_ALT6 | PIN_PORTC | PIN2) +# define PIN_I2S0_TXD0_1 (PIN_ALT6 | PIN_PORTA | PIN12) +# define PIN_I2S0_TXD0_2 (PIN_ALT6 | PIN_PORTC | PIN1) +# define PIN_I2S0_TXD1 (PIN_ALT6 | PIN_PORTC | PIN0) + +# define PIN_JTAG_TCLK (PIN_ALT7 | PIN_PORTA | PIN0) +# define PIN_JTAG_TDI (PIN_ALT7 | PIN_PORTA | PIN1) +# define PIN_JTAG_TDO (PIN_ALT7 | PIN_PORTA | PIN2) +# define PIN_JTAG_TMS (PIN_ALT7 | PIN_PORTA | PIN3) +# define PIN_JTAG_TRST_b (PIN_ALT6 | PIN_PORTA | PIN5) + +# define PIN_LLWU_P0 (PIN_ALT1 | PIN_PORTE | PIN1) +# define PIN_LLWU_P3 (PIN_ALT1 | PIN_PORTA | PIN4) +# define PIN_LLWU_P4 (PIN_ALT1 | PIN_PORTA | PIN13) +# define PIN_LLWU_P5 (PIN_ALT1 | PIN_PORTB | PIN0) +# define PIN_LLWU_P6 (PIN_ALT1 | PIN_PORTC | PIN1) +# define PIN_LLWU_P7 (PIN_ALT1 | PIN_PORTC | PIN3) +# define PIN_LLWU_P8 (PIN_ALT1 | PIN_PORTC | PIN4) +# define PIN_LLWU_P9 (PIN_ALT1 | PIN_PORTC | PIN5) +# define PIN_LLWU_P10 (PIN_ALT1 | PIN_PORTC | PIN6) +# define PIN_LLWU_P11 (PIN_ALT1 | PIN_PORTC | PIN11) +# define PIN_LLWU_P12 (PIN_ALT1 | PIN_PORTD | PIN0) +# define PIN_LLWU_P13 (PIN_ALT1 | PIN_PORTD | PIN2) +# define PIN_LLWU_P14 (PIN_ALT1 | PIN_PORTD | PIN4) +# define PIN_LLWU_P15 (PIN_ALT1 | PIN_PORTD | PIN6) + +# define PIN_LPTMR0_ALT1 (PIN_ALT6 | PIN_PORTA | PIN19) +# define PIN_LPTMR0_ALT2 (PIN_ALT3 | PIN_PORTC | PIN5) + +# define PIN_NMI_b (PIN_ALT6 | PIN_PORTA | PIN4) + +# define PIN_PDB0_EXTRG_1 (PIN_ALT3 | PIN_PORTC | PIN0) +# define PIN_PDB0_EXTRG_2 (PIN_ALT3 | PIN_PORTC | PIN6) + +# define PIN_PTA0 (PIN_ALT1 | PIN_PORTA | PIN0) +# define PIN_PTA1 (PIN_ALT1 | PIN_PORTA | PIN1) +# define PIN_PTA2 (PIN_ALT1 | PIN_PORTA | PIN2) +# define PIN_PTA3 (PIN_ALT1 | PIN_PORTA | PIN3) +# define PIN_PTA4 (PIN_ALT1 | PIN_PORTA | PIN4) +# define PIN_PTA5 (PIN_ALT0 | PIN_PORTA | PIN5) +# define PIN_PTA12 (PIN_ALT1 | PIN_PORTA | PIN12) +# define PIN_PTA13 (PIN_ALT1 | PIN_PORTA | PIN13) +# define PIN_PTA18 (PIN_ALT1 | PIN_PORTA | PIN18) +# define PIN_PTA19 (PIN_ALT1 | PIN_PORTA | PIN19) +# define PIN_PTB0 (PIN_ALT1 | PIN_PORTB | PIN0) +# define PIN_PTB1 (PIN_ALT1 | PIN_PORTB | PIN1) +# define PIN_PTB2 (PIN_ALT1 | PIN_PORTB | PIN2) +# define PIN_PTB3 (PIN_ALT1 | PIN_PORTB | PIN3) +# define PIN_PTB16 (PIN_ALT1 | PIN_PORTB | PIN16) +# define PIN_PTB17 (PIN_ALT1 | PIN_PORTB | PIN17) +# define PIN_PTB18 (PIN_ALT1 | PIN_PORTB | PIN18) +# define PIN_PTB19 (PIN_ALT1 | PIN_PORTB | PIN19) +# define PIN_PTC0 (PIN_ALT1 | PIN_PORTC | PIN0) +# define PIN_PTC1 (PIN_ALT1 | PIN_PORTC | PIN1) +# define PIN_PTC2 (PIN_ALT1 | PIN_PORTC | PIN2) +# define PIN_PTC3 (PIN_ALT1 | PIN_PORTC | PIN3) +# define PIN_PTC4 (PIN_ALT1 | PIN_PORTC | PIN4) +# define PIN_PTC5 (PIN_ALT1 | PIN_PORTC | PIN5) +# define PIN_PTC6 (PIN_ALT1 | PIN_PORTC | PIN6) +# define PIN_PTC7 (PIN_ALT1 | PIN_PORTC | PIN7) +# define PIN_PTC8 (PIN_ALT1 | PIN_PORTC | PIN8) +# define PIN_PTC9 (PIN_ALT1 | PIN_PORTC | PIN9) +# define PIN_PTC10 (PIN_ALT1 | PIN_PORTC | PIN10) +# define PIN_PTC11 (PIN_ALT1 | PIN_PORTC | PIN11) +# define PIN_PTD0 (PIN_ALT1 | PIN_PORTD | PIN0) +# define PIN_PTD1 (PIN_ALT1 | PIN_PORTD | PIN1) +# define PIN_PTD2 (PIN_ALT1 | PIN_PORTD | PIN2) +# define PIN_PTD3 (PIN_ALT1 | PIN_PORTD | PIN3) +# define PIN_PTD4 (PIN_ALT1 | PIN_PORTD | PIN4) +# define PIN_PTD5 (PIN_ALT1 | PIN_PORTD | PIN5) +# define PIN_PTD6 (PIN_ALT1 | PIN_PORTD | PIN6) +# define PIN_PTD7 (PIN_ALT1 | PIN_PORTD | PIN7) +# define PIN_PTE0 (PIN_ALT1 | PIN_PORTE | PIN0) +# define PIN_PTE1 (PIN_ALT1 | PIN_PORTE | PIN1) + +# define PIN_RTC_CLKOUT (PIN_ALT7 | PIN_PORTE | PIN0) + +# define PIN_SPI0_PCS0_1 (PIN_ALT2 | PIN_PORTC | PIN4) +# define PIN_SPI0_PCS0_2 (PIN_ALT2 | PIN_PORTD | PIN0) +# define PIN_SPI0_PCS1_1 (PIN_ALT2 | PIN_PORTC | PIN3) +# define PIN_SPI0_PCS1_2 (PIN_ALT2 | PIN_PORTD | PIN4) +# define PIN_SPI0_PCS2_1 (PIN_ALT2 | PIN_PORTC | PIN2) +# define PIN_SPI0_PCS2_2 (PIN_ALT2 | PIN_PORTD | PIN5) +# define PIN_SPI0_PCS3_1 (PIN_ALT2 | PIN_PORTC | PIN1) +# define PIN_SPI0_PCS3_2 (PIN_ALT2 | PIN_PORTD | PIN6) +# define PIN_SPI0_PCS4 (PIN_ALT2 | PIN_PORTC | PIN0) +# define PIN_SPI0_SCK_1 (PIN_ALT2 | PIN_PORTC | PIN5) +# define PIN_SPI0_SCK_2 (PIN_ALT2 | PIN_PORTD | PIN1) +# define PIN_SPI0_SIN_1 (PIN_ALT2 | PIN_PORTC | PIN7) +# define PIN_SPI0_SIN_2 (PIN_ALT2 | PIN_PORTD | PIN3) +# define PIN_SPI0_SOUT_1 (PIN_ALT2 | PIN_PORTC | PIN6) +# define PIN_SPI0_SOUT_2 (PIN_ALT2 | PIN_PORTD | PIN2) +# define PIN_SPI1_PCS1 (PIN_ALT2 | PIN_PORTE | PIN0) +# define PIN_SPI1_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN17) +# define PIN_SPI1_SIN_2 (PIN_ALT7 | PIN_PORTE | PIN1) +# define PIN_SPI1_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN16) +# define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1) + +# define PIN_SWD_CLK (PIN_ALT7 | PIN_PORTA | PIN0) +# define PIN_SWD_DIO (PIN_ALT7 | PIN_PORTA | PIN3) +# define PIN_TRACE_SWO (PIN_ALT7 | PIN_PORTA | PIN2) +# define PIN_TSI0_CH0 (PIN_ALT0 | PIN_PORTB | PIN0) +# define PIN_TSI0_CH1 (PIN_ALT0 | PIN_PORTA | PIN0) +# define PIN_TSI0_CH2 (PIN_ALT0 | PIN_PORTA | PIN1) +# define PIN_TSI0_CH3 (PIN_ALT0 | PIN_PORTA | PIN2) +# define PIN_TSI0_CH4 (PIN_ALT0 | PIN_PORTA | PIN3) +# define PIN_TSI0_CH5 (PIN_ALT0 | PIN_PORTA | PIN4) +# define PIN_TSI0_CH6 (PIN_ALT0 | PIN_PORTB | PIN1) +# define PIN_TSI0_CH7 (PIN_ALT0 | PIN_PORTB | PIN2) +# define PIN_TSI0_CH8 (PIN_ALT0 | PIN_PORTB | PIN3) +# define PIN_TSI0_CH9 (PIN_ALT0 | PIN_PORTB | PIN16) +# define PIN_TSI0_CH10 (PIN_ALT0 | PIN_PORTB | PIN17) +# define PIN_TSI0_CH11 (PIN_ALT0 | PIN_PORTB | PIN18) +# define PIN_TSI0_CH12 (PIN_ALT0 | PIN_PORTB | PIN19) +# define PIN_TSI0_CH13 (PIN_ALT0 | PIN_PORTC | PIN0) +# define PIN_TSI0_CH14 (PIN_ALT0 | PIN_PORTC | PIN1) +# define PIN_TSI0_CH15 (PIN_ALT0 | PIN_PORTC | PIN2) + +# define PIN_UART0_COL_b_1 (PIN_ALT2 | PIN_PORTA | PIN0) +# define PIN_UART0_COL_b_2 (PIN_ALT3 | PIN_PORTB | PIN3) +# define PIN_UART0_COL_b_3 (PIN_ALT3 | PIN_PORTD | PIN5) +# define PIN_UART0_CTS_b_1 (PIN_ALT2 | PIN_PORTA | PIN0) +# define PIN_UART0_CTS_b_2 (PIN_ALT3 | PIN_PORTB | PIN3) +# define PIN_UART0_CTS_b_3 (PIN_ALT3 | PIN_PORTD | PIN5) +# define PIN_UART0_RTS_b_1 (PIN_ALT2 | PIN_PORTA | PIN3) +# define PIN_UART0_RTS_b_2 (PIN_ALT3 | PIN_PORTB | PIN2) +# define PIN_UART0_RTS_b_3 (PIN_ALT3 | PIN_PORTD | PIN4) +# define PIN_UART0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN1) +# define PIN_UART0_RX_2 (PIN_ALT3 | PIN_PORTB | PIN16) +# define PIN_UART0_RX_3 (PIN_ALT3 | PIN_PORTD | PIN6) +# define PIN_UART0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN2) +# define PIN_UART0_TX_2 (PIN_ALT3 | PIN_PORTB | PIN17) +# define PIN_UART0_TX_3 (PIN_ALT3 | PIN_PORTD | PIN7) +# define PIN_UART1_CTS_b (PIN_ALT3 | PIN_PORTC | PIN2) +# define PIN_UART1_RTS_b (PIN_ALT3 | PIN_PORTC | PIN1) +# define PIN_UART1_RX_1 (PIN_ALT3 | PIN_PORTC | PIN3) +# define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1) +# define PIN_UART1_TX_1 (PIN_ALT3 | PIN_PORTC | PIN4) +# define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0) +# define PIN_UART2_CTS_b (PIN_ALT3 | PIN_PORTD | PIN1) +# define PIN_UART2_RTS_b (PIN_ALT3 | PIN_PORTD | PIN0) +# define PIN_UART2_RX (PIN_ALT3 | PIN_PORTD | PIN2) +# define PIN_UART2_TX (PIN_ALT3 | PIN_PORTD | PIN3) + +# define PIN_USB_CLKIN (PIN_ALT1 | PIN_PORTA | PIN5) +# define PIN_USB_SOF_OUT (PIN_ALT3 | PIN_PORTC | PIN7) + +# define PIN_EXTAL0 (PIN_ALT0 | PIN_PORTA | PIN18) +# define PIN_XTAL0 (PIN_ALT0 | PIN_PORTA | PIN19) + +#else + /* The pin muxing for other K20 parts is defined in other documents */ + +# error "No pin multiplexing for this Kinetis K20 part" +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H */ diff --git a/arch/arm/src/kinetis/kinetis_k40pinmux.h b/arch/arm/src/kinetis/kinetis_k40pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..9798eda6be1522e19bf0b7fc2bc1d176a61a0fed --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_k40pinmux.h @@ -0,0 +1,518 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_k40pinmux.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Reference: Paragraph 10.3.1, p 227, of FreeScale document K40P144M100SF2RM + * + * In most cases, there are alternative configurations for various pins. Those alternative + * pins are labeled with a suffix like _1, _2, etc. in order to distinguish them. Logic in + * the board.h file must select the correct pin configuration for the board by defining a pin + * configuration (with no suffix) that maps to the correct alternative. + */ + +#if defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) + +#define PIN_TSI0_CH1 (PIN_ANALOG | PIN_PORTA | PIN0) +#define PIN_UART0_CTS_1 (PIN_ALT2 | PIN_PORTA | PIN0) +#define PIN_FTM0_CH5_1 (PIN_ALT3 | PIN_PORTA | PIN0) +#define PIN_JTAG_TCLK (PIN_ALT7 | PIN_PORTA | PIN0) +#define PIN_SWD_CLK (PIN_ALT7 | PIN_PORTA | PIN0) +#define PIN_TSI0_CH2 (PIN_ANALOG | PIN_PORTA | PIN1) +#define PIN_UART0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN1) +#define PIN_FTM0_CH6_1 (PIN_ALT3 | PIN_PORTA | PIN1) +#define PIN_JTAG_TDI (PIN_ALT7 | PIN_PORTA | PIN1) +#define PIN_TSI0_CH3 (PIN_ANALOG | PIN_PORTA | PIN2) +#define PIN_UART0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN2) +#define PIN_FTM0_CH7_1 (PIN_ALT3 | PIN_PORTA | PIN2) +#define PIN_JTAG_TDO (PIN_ALT7 | PIN_PORTA | PIN2) +#define PIN_TRACE_SWO (PIN_ALT7 | PIN_PORTA | PIN2) +#define PIN_TSI0_CH4 (PIN_ANALOG | PIN_PORTA | PIN3) +#define PIN_UART0_RTS_1 (PIN_ALT2 | PIN_PORTA | PIN3) +#define PIN_FTM0_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN3) +#define PIN_JTAG_TMS (PIN_ALT7 | PIN_PORTA | PIN3) +#define PIN_SWD_DIO (PIN_ALT7 | PIN_PORTA | PIN3) +#define PIN_TSI0_CH5 (PIN_ANALOG | PIN_PORTA | PIN4) +#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4) +#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4) +#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5) +#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5) +#define PIN_I2S0_RX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN5) +#define PIN_JTAG_TRST (PIN_ALT7 | PIN_PORTA | PIN5) +#define PIN_FTM0_CH3_1 (PIN_ALT3 | PIN_PORTA | PIN6) +#define PIN_FB_CLKOUT (PIN_ALT5 | PIN_PORTA | PIN6) +#define PIN_TRACE_CLKOUT (PIN_ALT7 | PIN_PORTA | PIN6) +#define PIN_ADC0_SE10 (PIN_ANALOG | PIN_PORTA | PIN7) +#define PIN_FTM0_CH4_1 (PIN_ALT3 | PIN_PORTA | PIN7) +#define PIN_FB_AD18 (PIN_ALT5 | PIN_PORTA | PIN7) +#define PIN_TRACE_D3 (PIN_ALT7 | PIN_PORTA | PIN7) +#define PIN_ADC0_SE11 (PIN_ANALOG | PIN_PORTA | PIN8) +#define PIN_FTM1_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN8) +#define PIN_FB_AD17 (PIN_ALT5 | PIN_PORTA | PIN8) +#define PIN_FTM1_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN8) +#define PIN_TRACE_D2 (PIN_ALT7 | PIN_PORTA | PIN8) +#define PIN_FTM1_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN9) +#define PIN_FB_AD16 (PIN_ALT5 | PIN_PORTA | PIN9) +#define PIN_FTM1_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN9) +#define PIN_TRACE_D1 (PIN_ALT7 | PIN_PORTA | PIN9) +#define PIN_FTM2_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN10) +#define PIN_FB_AD15 (PIN_ALT5 | PIN_PORTA | PIN10) +#define PIN_FTM2_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN10) +#define PIN_TRACE_D0 (PIN_ALT7 | PIN_PORTA | PIN10) +#define PIN_FTM2_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN11) +#define PIN_FB_OE (PIN_ALT5 | PIN_PORTA | PIN11) +#define PIN_FTM2_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN11) +#define PIN_CMP2_IN0 (PIN_ANALOG | PIN_PORTA | PIN12) +#define PIN_CAN0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN12) +#define PIN_FTM1_CH0_2 (PIN_ALT3 | PIN_PORTA | PIN12) +#define PIN_FB_CS5 (PIN_ALT5 | PIN_PORTA | PIN12) +#define PIN_FB_TSIZ1 (PIN_ALT5 | PIN_PORTA | PIN12) +#define PIN_FB_BE23_16_BLS15_8 (PIN_ALT5 | PIN_PORTA | PIN12) +#define PIN_I2S0_TXD_1 (PIN_ALT6 | PIN_PORTA | PIN12) +#define PIN_FTM1_QD_PHA_2 (PIN_ALT7 | PIN_PORTA | PIN12) +#define PIN_CMP2_IN1 (PIN_ANALOG | PIN_PORTA | PIN13) +#define PIN_CAN0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN13) +#define PIN_FTM1_CH1_2 (PIN_ALT3 | PIN_PORTA | PIN13) +#define PIN_FB_CS4 (PIN_ALT5 | PIN_PORTA | PIN13) +#define PIN_FB_TSIZ0 (PIN_ALT5 | PIN_PORTA | PIN13) +#define PIN_FB_BE31_24_BLS7_0 (PIN_ALT5 | PIN_PORTA | PIN13) +#define PIN_I2S0_TX_FS_1 (PIN_ALT6 | PIN_PORTA | PIN13) +#define PIN_FTM1_QD_PHB_2 (PIN_ALT7 | PIN_PORTA | PIN13) +#define PIN_SPI0_PCS0_1 (PIN_ALT2 | PIN_PORTA | PIN14) +#define PIN_UART0_TX_2 (PIN_ALT3 | PIN_PORTA | PIN14) +#define PIN_FB_AD31 (PIN_ALT5 | PIN_PORTA | PIN14) +#define PIN_I2S0_TX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN14) +#define PIN_SPI0_SCK_1 (PIN_ALT2 | PIN_PORTA | PIN15) +#define PIN_UART0_RX_2 (PIN_ALT3 | PIN_PORTA | PIN15) +#define PIN_FB_AD30 (PIN_ALT5 | PIN_PORTA | PIN15) +#define PIN_I2S0_RXD_1 (PIN_ALT6 | PIN_PORTA | PIN15) +#define PIN_SPI0_SOUT_1 (PIN_ALT2 | PIN_PORTA | PIN16) +#define PIN_UART0_CTS_2 (PIN_ALT3 | PIN_PORTA | PIN16) +#define PIN_FB_AD29 (PIN_ALT5 | PIN_PORTA | PIN16) +#define PIN_I2S0_RX_FS_1 (PIN_ALT6 | PIN_PORTA | PIN16) +#define PIN_ADC1_SE17 (PIN_ANALOG | PIN_PORTA | PIN17) +#define PIN_SPI0_SIN_1 (PIN_ALT2 | PIN_PORTA | PIN17) +#define PIN_UART0_RTS_2 (PIN_ALT3 | PIN_PORTA | PIN17) +#define PIN_FB_AD28 (PIN_ALT5 | PIN_PORTA | PIN17) +#define PIN_I2S0_MCLK_1 (PIN_ALT6 | PIN_PORTA | PIN17) +#define PIN_I2S0_CLKIN_1 (PIN_ALT7 | PIN_PORTA | PIN17) +#define PIN_EXTAL (PIN_ANALOG | PIN_PORTA | PIN18) +#define PIN_FTM0_FLT2_1 (PIN_ALT3 | PIN_PORTA | PIN18) +#define PIN_FTM_CLKIN0 (PIN_ALT4 | PIN_PORTA | PIN18) +#define PIN_XTAL (PIN_ANALOG | PIN_PORTA | PIN19) +#define PIN_FTM1_FLT0_1 (PIN_ALT3 | PIN_PORTA | PIN19) +#define PIN_FTM_CLKIN1 (PIN_ALT4 | PIN_PORTA | PIN19) +#define PIN_LPT0_ALT1 (PIN_ALT6 | PIN_PORTA | PIN19) +#define PIN_FB_AD14 (PIN_ALT5 | PIN_PORTA | PIN24) +#define PIN_FB_AD13 (PIN_ALT5 | PIN_PORTA | PIN25) +#define PIN_FB_AD12 (PIN_ALT5 | PIN_PORTA | PIN26) +#define PIN_FB_AD11 (PIN_ALT5 | PIN_PORTA | PIN27) +#define PIN_FB_AD10 (PIN_ALT5 | PIN_PORTA | PIN28) +#define PIN_FB_AD19 (PIN_ALT5 | PIN_PORTA | PIN29) + +#define PIN_LCD_P0 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_ADC1_SE8 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0) +#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0) +#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0) +#define PIN_LCD_P0F (PIN_ALT7 | PIN_PORTB | PIN0) +#define PIN_LCD_P1 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_ADC1_SE9 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_TSI0_CH6 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1) +#define PIN_FTM1_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN1) +#define PIN_FTM1_QD_PHB (PIN_ALT6 | PIN_PORTB | PIN1) +#define PIN_LCD_P1F (PIN_ALT7 | PIN_PORTB | PIN1) +#define PIN_LCD_P2 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_TSI0_CH7 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2) +#define PIN_UART0_RTS_3 (PIN_ALT3 | PIN_PORTB | PIN2) +#define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2) +#define PIN_LCD_P2F (PIN_ALT7 | PIN_PORTB | PIN2) +#define PIN_LCD_P3 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_TSI0_CH8 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3) +#define PIN_UART0_CTS_3 (PIN_ALT3 | PIN_PORTB | PIN3) +#define PIN_FTM0_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN3) +#define PIN_LCD_P3F (PIN_ALT7 | PIN_PORTB | PIN3) +#define PIN_LCD_P4 (PIN_ANALOG | PIN_PORTB | PIN4) +#define PIN_ADC1_SE10 (PIN_ANALOG | PIN_PORTB | PIN4) +#define PIN_FTM1_FLT0_2 (PIN_ALT6 | PIN_PORTB | PIN4) +#define PIN_LCD_P4F (PIN_ALT7 | PIN_PORTB | PIN4) +#define PIN_LCD_P5 (PIN_ANALOG | PIN_PORTB | PIN5) +#define PIN_ADC1_SE11 (PIN_ANALOG | PIN_PORTB | PIN5) +#define PIN_FTM2_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN5) +#define PIN_LCD_P5F (PIN_ALT7 | PIN_PORTB | PIN5) +#define PIN_LCD_P6 (PIN_ANALOG | PIN_PORTB | PIN6) +#define PIN_ADC1_SE12 (PIN_ANALOG | PIN_PORTB | PIN6) +#define PIN_LCD_P6F (PIN_ALT7 | PIN_PORTB | PIN6) +#define PIN_LCD_P7 (PIN_ANALOG | PIN_PORTB | PIN7) +#define PIN_ADC1_SE13 (PIN_ANALOG | PIN_PORTB | PIN7) +#define PIN_LCD_P7F (PIN_ALT7 | PIN_PORTB | PIN7) +#define PIN_LCD_P8 (PIN_ANALOG | PIN_PORTB | PIN8) +#define PIN_UART3_RTS_1 (PIN_ALT3 | PIN_PORTB | PIN8) +#define PIN_LCD_P8F (PIN_ALT7 | PIN_PORTB | PIN8) +#define PIN_LCD_P9 (PIN_ANALOG | PIN_PORTB | PIN9) +#define PIN_SPI1_PCS1_1 (PIN_ALT2 | PIN_PORTB | PIN9) +#define PIN_UART3_CTS_1 (PIN_ALT3 | PIN_PORTB | PIN9) +#define PIN_LCD_P9F (PIN_ALT7 | PIN_PORTB | PIN9) +#define PIN_LCD_P10 (PIN_ANALOG | PIN_PORTB | PIN10) +#define PIN_ADC1_SE14 (PIN_ANALOG | PIN_PORTB | PIN10) +#define PIN_SPI1_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN10) +#define PIN_UART3_RX_1 (PIN_ALT3 | PIN_PORTB | PIN10) +#define PIN_FTM0_FLT1_1 (PIN_ALT6 | PIN_PORTB | PIN10) +#define PIN_LCD_P10F (PIN_ALT7 | PIN_PORTB | PIN10) +#define PIN_LCD_P11 (PIN_ANALOG | PIN_PORTB | PIN11) +#define PIN_ADC1_SE15 (PIN_ANALOG | PIN_PORTB | PIN11) +#define PIN_SPI1_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN11) +#define PIN_UART3_TX_1 (PIN_ALT3 | PIN_PORTB | PIN11) +#define PIN_FTM0_FLT2_2 (PIN_ALT6 | PIN_PORTB | PIN11) +#define PIN_LCD_P11F (PIN_ALT7 | PIN_PORTB | PIN11) +#define PIN_LCD_P12 (PIN_ANALOG | PIN_PORTB | PIN16) +#define PIN_TSI0_CH9 (PIN_ANALOG | PIN_PORTB | PIN16) +#define PIN_SPI1_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN16) +#define PIN_UART0_RX_3 (PIN_ALT3 | PIN_PORTB | PIN16) +#define PIN_EWM_IN_1 (PIN_ALT6 | PIN_PORTB | PIN16) +#define PIN_LCD_P12F (PIN_ALT7 | PIN_PORTB | PIN16) +#define PIN_LCD_P13 (PIN_ANALOG | PIN_PORTB | PIN17) +#define PIN_TSI0_CH10 (PIN_ANALOG | PIN_PORTB | PIN17) +#define PIN_SPI1_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN17) +#define PIN_UART0_TX_3 (PIN_ALT3 | PIN_PORTB | PIN17) +#define PIN_EWM_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN17) +#define PIN_LCD_P13F (PIN_ALT7 | PIN_PORTB | PIN17) +#define PIN_LCD_P14 (PIN_ANALOG | PIN_PORTB | PIN18) +#define PIN_TSI0_CH11 (PIN_ANALOG | PIN_PORTB | PIN18) +#define PIN_CAN0_TX_2 (PIN_ALT2 | PIN_PORTB | PIN18) +#define PIN_FTM2_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN18) +#define PIN_I2S0_TX_BCLK_2 (PIN_ALT4 | PIN_PORTB | PIN18) +#define PIN_FTM2_QD_PHA_2 (PIN_ALT6 | PIN_PORTB | PIN18) +#define PIN_LCD_P14F (PIN_ALT7 | PIN_PORTB | PIN18) +#define PIN_LCD_P15 (PIN_ANALOG | PIN_PORTB | PIN19) +#define PIN_TSI0_CH12 (PIN_ANALOG | PIN_PORTB | PIN19) +#define PIN_CAN0_RX_2 (PIN_ALT2 | PIN_PORTB | PIN19) +#define PIN_FTM2_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN19) +#define PIN_I2S0_TX_FS_2 (PIN_ALT4 | PIN_PORTB | PIN19) +#define PIN_FTM2_QD_PHB_2 (PIN_ALT6 | PIN_PORTB | PIN19) +#define PIN_LCD_P15F (PIN_ALT7 | PIN_PORTB | PIN19) +#define PIN_LCD_P16 (PIN_ANALOG | PIN_PORTB | PIN20) +#define PIN_SPI2_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN20) +#define PIN_CMP0_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN20) +#define PIN_LCD_P16F (PIN_ALT7 | PIN_PORTB | PIN20) +#define PIN_LCD_P17 (PIN_ANALOG | PIN_PORTB | PIN21) +#define PIN_SPI2_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN21) +#define PIN_CMP1_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN21) +#define PIN_LCD_P17F (PIN_ALT7 | PIN_PORTB | PIN21) +#define PIN_LCD_P18 (PIN_ANALOG | PIN_PORTB | PIN22) +#define PIN_SPI2_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN22) +#define PIN_CMP2_OUT_2 (PIN_ALT6 | PIN_PORTB | PIN22) +#define PIN_LCD_P18F (PIN_ALT7 | PIN_PORTB | PIN22) +#define PIN_LCD_P19 (PIN_ANALOG | PIN_PORTB | PIN23) +#define PIN_SPI2_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN23) +#define PIN_SPI0_PCS5 (PIN_ALT3 | PIN_PORTB | PIN23) +#define PIN_LCD_P19F (PIN_ALT7 | PIN_PORTB | PIN23) + +#define PIN_LCD_P20 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_ADC0_SE14 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_TSI0_CH13 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_SPI0_PCS4 (PIN_ALT2 | PIN_PORTC | PIN0) +#define PIN_PDB0_EXTRG_1 (PIN_ALT3 | PIN_PORTC | PIN0) +#define PIN_I2S0_TXD_2 (PIN_ALT4 | PIN_PORTC | PIN0) +#define PIN_LCD_P20F (PIN_ALT7 | PIN_PORTC | PIN0) +#define PIN_LCD_P21 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_ADC0_SE15 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_TSI0_CH14 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_SPI0_PCS3_1 (PIN_ALT2 | PIN_PORTC | PIN1) +#define PIN_UART1_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN1) +#define PIN_FTM0_CH0_2 (PIN_ALT4 | PIN_PORTC | PIN1) +#define PIN_LCD_P21F (PIN_ALT7 | PIN_PORTC | PIN1) +#define PIN_LCD_P22 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_ADC0_SE4B (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_CMP1_IN0 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_TSI0_CH15 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_SPI0_PCS2_1 (PIN_ALT2 | PIN_PORTC | PIN2) +#define PIN_UART1_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN2) +#define PIN_FTM0_CH1_2 (PIN_ALT4 | PIN_PORTC | PIN2) +#define PIN_LCD_P22F (PIN_ALT7 | PIN_PORTC | PIN2) +#define PIN_LCD_P23 (PIN_ANALOG | PIN_PORTC | PIN3) +#define PIN_CMP1_IN1 (PIN_ANALOG | PIN_PORTC | PIN3) +#define PIN_SPI0_PCS1_1 (PIN_ALT2 | PIN_PORTC | PIN3) +#define PIN_UART1_RX_1 (PIN_ALT3 | PIN_PORTC | PIN3) +#define PIN_FTM0_CH2_2 (PIN_ALT4 | PIN_PORTC | PIN3) +#define PIN_LCD_P23F (PIN_ALT7 | PIN_PORTC | PIN3) +#define PIN_LCD_P24 (PIN_ANALOG | PIN_PORTC | PIN4) +#define PIN_SPI0_PCS0_2 (PIN_ALT2 | PIN_PORTC | PIN4) +#define PIN_UART1_TX_1 (PIN_ALT3 | PIN_PORTC | PIN4) +#define PIN_FTM0_CH3_2 (PIN_ALT4 | PIN_PORTC | PIN4) +#define PIN_CMP1_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN4) +#define PIN_LCD_P24F (PIN_ALT7 | PIN_PORTC | PIN4) +#define PIN_LCD_P25 (PIN_ANALOG | PIN_PORTC | PIN5) +#define PIN_SPI0_SCK_2 (PIN_ALT2 | PIN_PORTC | PIN5) +#define PIN_LPT0_ALT2 (PIN_ALT4 | PIN_PORTC | PIN5) +#define PIN_CMP0_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN5) +#define PIN_LCD_P25F (PIN_ALT7 | PIN_PORTC | PIN5) +#define PIN_LCD_P26 (PIN_ANALOG | PIN_PORTC | PIN6) +#define PIN_CMP0_IN0 (PIN_ANALOG | PIN_PORTC | PIN6) +#define PIN_SPI0_SOUT_2 (PIN_ALT2 | PIN_PORTC | PIN6) +#define PIN_PDB0_EXTRG_2 (PIN_ALT3 | PIN_PORTC | PIN6) +#define PIN_LCD_P26F (PIN_ALT7 | PIN_PORTC | PIN6) +#define PIN_LCD_P27 (PIN_ANALOG | PIN_PORTC | PIN7) +#define PIN_CMP0_IN1 (PIN_ANALOG | PIN_PORTC | PIN7) +#define PIN_SPI0_SIN_2 (PIN_ALT2 | PIN_PORTC | PIN7) +#define PIN_LCD_P27F (PIN_ALT7 | PIN_PORTC | PIN7) +#define PIN_LCD_P28 (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_ADC1_SE4B (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_CMP0_IN2 (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_I2S0_MCLK_2 (PIN_ALT4 | PIN_PORTC | PIN8) +#define PIN_I2S0_CLKIN_2 (PIN_ALT5 | PIN_PORTC | PIN8) +#define PIN_LCD_P28F (PIN_ALT7 | PIN_PORTC | PIN8) +#define PIN_LCD_P29 (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_ADC1_SE5B (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_CMP0_IN3 (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_I2S0_RX_BCLK_2 (PIN_ALT4 | PIN_PORTC | PIN9) +#define PIN_FTM2_FLT0_2 (PIN_ALT6 | PIN_PORTC | PIN9) +#define PIN_LCD_P29F (PIN_ALT7 | PIN_PORTC | PIN9) +#define PIN_LCD_P30 (PIN_ANALOG | PIN_PORTC | PIN10) +#define PIN_ADC1_SE6B (PIN_ANALOG | PIN_PORTC | PIN10) +#define PIN_CMP0_IN4 (PIN_ANALOG | PIN_PORTC | PIN10) +#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10) +#define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN10) +#define PIN_LCD_P30F (PIN_ALT7 | PIN_PORTC | PIN10) +#define PIN_LCD_P31 (PIN_ANALOG | PIN_PORTC | PIN11) +#define PIN_ADC1_SE7B (PIN_ANALOG | PIN_PORTC | PIN11) +#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11) +#define PIN_I2S0_RXD_2 (PIN_ALT4 | PIN_PORTC | PIN11) +#define PIN_LCD_P31F (PIN_ALT7 | PIN_PORTC | PIN11) +#define PIN_LCD_P32 (PIN_ANALOG | PIN_PORTC | PIN12) +#define PIN_UART4_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN12) +#define PIN_LCD_P32F (PIN_ALT7 | PIN_PORTC | PIN12) +#define PIN_LCD_P33 (PIN_ANALOG | PIN_PORTC | PIN13) +#define PIN_UART4_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN13) +#define PIN_LCD_P33F (PIN_ALT7 | PIN_PORTC | PIN13) +#define PIN_LCD_P34 (PIN_ANALOG | PIN_PORTC | PIN14) +#define PIN_UART4_RX_1 (PIN_ALT3 | PIN_PORTC | PIN14) +#define PIN_LCD_P34F (PIN_ALT7 | PIN_PORTC | PIN14) +#define PIN_LCD_P35 (PIN_ANALOG | PIN_PORTC | PIN15) +#define PIN_UART4_TX_1 (PIN_ALT3 | PIN_PORTC | PIN15) +#define PIN_LCD_P35F (PIN_ALT7 | PIN_PORTC | PIN15) +#define PIN_LCD_P36 (PIN_ANALOG | PIN_PORTC | PIN16) +#define PIN_CAN1_RX_1 (PIN_ALT2 | PIN_PORTC | PIN16) +#define PIN_UART3_RX_2 (PIN_ALT3 | PIN_PORTC | PIN16) +#define PIN_LCD_P36F (PIN_ALT7 | PIN_PORTC | PIN16) +#define PIN_LCD_P37 (PIN_ANALOG | PIN_PORTC | PIN17) +#define PIN_CAN1_TX_1 (PIN_ALT2 | PIN_PORTC | PIN17) +#define PIN_UART3_TX_2 (PIN_ALT3 | PIN_PORTC | PIN17) +#define PIN_LCD_P37F (PIN_ALT7 | PIN_PORTC | PIN17) +#define PIN_LCD_P38 (PIN_ANALOG | PIN_PORTC | PIN18) +#define PIN_UART3_RTS_2 (PIN_ALT3 | PIN_PORTC | PIN18) +#define PIN_LCD_P38F (PIN_ALT7 | PIN_PORTC | PIN18) +#define PIN_LCD_P39 (PIN_ANALOG | PIN_PORTC | PIN19) +#define PIN_UART3_CTS_2 (PIN_ALT3 | PIN_PORTC | PIN19) +#define PIN_LCD_P39F (PIN_ALT7 | PIN_PORTC | PIN19) + +#define PIN_LCD_P40 (PIN_ANALOG | PIN_PORTD | PIN0) +#define PIN_SPI0_PCS0_3 (PIN_ALT2 | PIN_PORTD | PIN0) +#define PIN_UART2_RTS (PIN_ALT3 | PIN_PORTD | PIN0) +#define PIN_LCD_P40F (PIN_ALT7 | PIN_PORTD | PIN0) +#define PIN_LCD_P41 (PIN_ANALOG | PIN_PORTD | PIN1) +#define PIN_ADC0_SE5B (PIN_ANALOG | PIN_PORTD | PIN1) +#define PIN_SPI0_SCK_3 (PIN_ALT2 | PIN_PORTD | PIN1) +#define PIN_UART2_CTS (PIN_ALT3 | PIN_PORTD | PIN1) +#define PIN_LCD_P41F (PIN_ALT7 | PIN_PORTD | PIN1) +#define PIN_LCD_P42 (PIN_ANALOG | PIN_PORTD | PIN2) +#define PIN_SPI0_SOUT_3 (PIN_ALT2 | PIN_PORTD | PIN2) +#define PIN_UART2_RX (PIN_ALT3 | PIN_PORTD | PIN2) +#define PIN_LCD_P42F (PIN_ALT7 | PIN_PORTD | PIN2) +#define PIN_LCD_P43 (PIN_ANALOG | PIN_PORTD | PIN3) +#define PIN_SPI0_SIN_3 (PIN_ALT2 | PIN_PORTD | PIN3) +#define PIN_UART2_TX (PIN_ALT3 | PIN_PORTD | PIN3) +#define PIN_LCD_P43F (PIN_ALT7 | PIN_PORTD | PIN3) +#define PIN_LCD_P44 (PIN_ANALOG | PIN_PORTD | PIN4) +#define PIN_SPI0_PCS1_2 (PIN_ALT2 | PIN_PORTD | PIN4) +#define PIN_UART0_RTS_4 (PIN_ALT3 | PIN_PORTD | PIN4) +#define PIN_FTM0_CH4_2 (PIN_ALT4 | PIN_PORTD | PIN4) +#define PIN_EWM_IN_2 (PIN_ALT6 | PIN_PORTD | PIN4) +#define PIN_LCD_P44F (PIN_ALT7 | PIN_PORTD | PIN4) +#define PIN_LCD_P45 (PIN_ANALOG | PIN_PORTD | PIN5) +#define PIN_ADC0_SE6B (PIN_ANALOG | PIN_PORTD | PIN5) +#define PIN_SPI0_PCS2_2 (PIN_ALT2 | PIN_PORTD | PIN5) +#define PIN_UART0_CTS_4 (PIN_ALT3 | PIN_PORTD | PIN5) +#define PIN_FTM0_CH5_2 (PIN_ALT4 | PIN_PORTD | PIN5) +#define PIN_EWM_OUT_2 (PIN_ALT6 | PIN_PORTD | PIN5) +#define PIN_LCD_P45F (PIN_ALT7 | PIN_PORTD | PIN5) +#define PIN_LCD_P46 (PIN_ANALOG | PIN_PORTD | PIN6) +#define PIN_ADC0_SE7B (PIN_ANALOG | PIN_PORTD | PIN6) +#define PIN_SPI0_PCS3_2 (PIN_ALT2 | PIN_PORTD | PIN6) +#define PIN_UART0_RX_4 (PIN_ALT3 | PIN_PORTD | PIN6) +#define PIN_FTM0_CH6_2 (PIN_ALT4 | PIN_PORTD | PIN6) +#define PIN_FTM0_FLT0_2 (PIN_ALT6 | PIN_PORTD | PIN6) +#define PIN_LCD_P46F (PIN_ALT7 | PIN_PORTD | PIN6) +#define PIN_LCD_P47 (PIN_ANALOG | PIN_PORTD | PIN7) +#define PIN_CMT_IRO (PIN_ALT2 | PIN_PORTD | PIN7) +#define PIN_UART0_TX_4 (PIN_ALT3 | PIN_PORTD | PIN7) +#define PIN_FTM0_CH7_2 (PIN_ALT4 | PIN_PORTD | PIN7) +#define PIN_FTM0_FLT1_2 (PIN_ALT6 | PIN_PORTD | PIN7) +#define PIN_LCD_P47F (PIN_ALT7 | PIN_PORTD | PIN7) +#define PIN_UART5_RTS_1 (PIN_ALT3 | PIN_PORTD | PIN10) +#define PIN_FB_AD9 (PIN_ALT5 | PIN_PORTD | PIN10) +#define PIN_SPI2_PCS0_2 (PIN_ALT2 | PIN_PORTD | PIN11) +#define PIN_UART5_CTS_1 (PIN_ALT3 | PIN_PORTD | PIN11) +#define PIN_SDHC0_CLKIN (PIN_ALT4 | PIN_PORTD | PIN11) +#define PIN_FB_AD8 (PIN_ALT5 | PIN_PORTD | PIN11) +#define PIN_SPI2_SCK_2 (PIN_ALT2 | PIN_PORTD | PIN12) +#define PIN_SDHC0_D4 (PIN_ALT4 | PIN_PORTD | PIN12) +#define PIN_FB_AD7 (PIN_ALT5 | PIN_PORTD | PIN12) +#define PIN_SPI2_SOUT_2 (PIN_ALT2 | PIN_PORTD | PIN13) +#define PIN_SDHC0_D5 (PIN_ALT4 | PIN_PORTD | PIN13) +#define PIN_FB_AD6 (PIN_ALT5 | PIN_PORTD | PIN13) +#define PIN_SPI2_SIN_2 (PIN_ALT2 | PIN_PORTD | PIN14) +#define PIN_SDHC0_D6 (PIN_ALT4 | PIN_PORTD | PIN14) +#define PIN_FB_AD5 (PIN_ALT5 | PIN_PORTD | PIN14) +#define PIN_SPI2_PCS1 (PIN_ALT2 | PIN_PORTD | PIN15) +#define PIN_SDHC0_D7 (PIN_ALT4 | PIN_PORTD | PIN15) +#define PIN_FB_RW (PIN_ALT5 | PIN_PORTD | PIN15) + +#define PIN_ADC1_SE4A (PIN_ANALOG | PIN_PORTE | PIN0) +#define PIN_SPI1_PCS1_2 (PIN_ALT2 | PIN_PORTE | PIN0) +#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0) +#define PIN_SDHC0_D1 (PIN_ALT4 | PIN_PORTE | PIN0) +#define PIN_FB_AD27 (PIN_ALT5 | PIN_PORTE | PIN0) +#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0) +#define PIN_ADC1_SE5A (PIN_ANALOG | PIN_PORTE | PIN1) +#define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1) +#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1) +#define PIN_SDHC0_D0 (PIN_ALT4 | PIN_PORTE | PIN1) +#define PIN_FB_AD26 (PIN_ALT5 | PIN_PORTE | PIN1) +#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1) +#define PIN_ADC1_SE6A (PIN_ANALOG | PIN_PORTE | PIN2) +#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTE | PIN2) +#define PIN_UART1_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN2) +#define PIN_SDHC0_DCLK (PIN_ALT4 | PIN_PORTE | PIN2) +#define PIN_FB_AD25 (PIN_ALT5 | PIN_PORTE | PIN2) +#define PIN_ADC1_SE7A (PIN_ANALOG | PIN_PORTE | PIN3) +#define PIN_SPI1_SIN_2 (PIN_ALT2 | PIN_PORTE | PIN3) +#define PIN_UART1_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN3) +#define PIN_SDHC0_CMD (PIN_ALT4 | PIN_PORTE | PIN3) +#define PIN_FB_AD24 (PIN_ALT5 | PIN_PORTE | PIN3) +#define PIN_SPI1_PCS0_2 (PIN_ALT2 | PIN_PORTE | PIN4) +#define PIN_UART3_TX_3 (PIN_ALT3 | PIN_PORTE | PIN4) +#define PIN_SDHC0_D3 (PIN_ALT4 | PIN_PORTE | PIN4) +#define PIN_FB_CS3 (PIN_ALT5 | PIN_PORTE | PIN4) +#define PIN_FB_BE7_0_BLS31_24 (PIN_ALT5 | PIN_PORTE | PIN4) +#define PIN_FB_TA (PIN_ALT6 | PIN_PORTE | PIN4) +#define PIN_SPI1_PCS2 (PIN_ANALOG | PIN_PORTE | PIN5) +#define PIN_UART3_RX_3 (PIN_ALT2 | PIN_PORTE | PIN5) +#define PIN_SDHC0_D2 (PIN_ALT3 | PIN_PORTE | PIN5) +#define PIN_FB_TBST (PIN_ALT4 | PIN_PORTE | PIN5) +#define PIN_FB_CS2 (PIN_ALT5 | PIN_PORTE | PIN5) +#define PIN_FB_BE15_8_BLS23_16 (PIN_ALT5 | PIN_PORTE | PIN5) +#define PIN_SPI1_PCS3 (PIN_ALT2 | PIN_PORTE | PIN6) +#define PIN_UART3_CTS_3 (PIN_ALT3 | PIN_PORTE | PIN6) +#define PIN_I2S0_MCLK_3 (PIN_ALT4 | PIN_PORTE | PIN6) +#define PIN_FB_ALE (PIN_ALT5 | PIN_PORTE | PIN6) +#define PIN_FB_CS1 (PIN_ALT5 | PIN_PORTE | PIN6) +#define PIN_FB_TS (PIN_ALT5 | PIN_PORTE | PIN6) +#define PIN_I2S0_CLKIN_3 (PIN_ALT6 | PIN_PORTE | PIN6) +#define PIN_UART3_RTS_3 (PIN_ALT3 | PIN_PORTE | PIN7) +#define PIN_I2S0_RXD_3 (PIN_ALT4 | PIN_PORTE | PIN7) +#define PIN_FB_CS0 (PIN_ALT5 | PIN_PORTE | PIN7) +#define PIN_UART5_TX (PIN_ALT3 | PIN_PORTE | PIN8) +#define PIN_I2S0_RX_FS_3 (PIN_ALT4 | PIN_PORTE | PIN8) +#define PIN_FB_AD4 (PIN_ALT5 | PIN_PORTE | PIN8) +#define PIN_UART5_RX (PIN_ALT3 | PIN_PORTE | PIN9) +#define PIN_I2S0_RX_BCLK_3 (PIN_ALT4 | PIN_PORTE | PIN9) +#define PIN_FB_AD3 (PIN_ALT5 | PIN_PORTE | PIN9) +#define PIN_UART5_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN10) +#define PIN_I2S0_TXD_3 (PIN_ALT4 | PIN_PORTE | PIN10) +#define PIN_FB_AD2 (PIN_ALT5 | PIN_PORTE | PIN10) +#define PIN_UART5_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN11) +#define PIN_I2S0_TX_FS_3 (PIN_ALT4 | PIN_PORTE | PIN11) +#define PIN_FB_AD1 (PIN_ALT5 | PIN_PORTE | PIN11) +#define PIN_I2S0_TX_BCLK_3 (PIN_ALT4 | PIN_PORTE | PIN12) +#define PIN_FB_AD0 (PIN_ALT5 | PIN_PORTE | PIN12) +#define PIN_ADC0_SE17 (PIN_ANALOG | PIN_PORTE | PIN24) +#define PIN_CAN1_TX_2 (PIN_ALT2 | PIN_PORTE | PIN24) +#define PIN_UART4_TX_2 (PIN_ALT3 | PIN_PORTE | PIN24) +#define PIN_EWM_OUT_3 (PIN_ALT6 | PIN_PORTE | PIN24) +#define PIN_ADC0_SE18 (PIN_ANALOG | PIN_PORTE | PIN25) +#define PIN_CAN1_RX_2 (PIN_ALT2 | PIN_PORTE | PIN25) +#define PIN_UART4_RX_2 (PIN_ALT3 | PIN_PORTE | PIN25) +#define PIN_FB_AD23 (PIN_ALT5 | PIN_PORTE | PIN25) +#define PIN_EWM_IN_3 (PIN_ALT6 | PIN_PORTE | PIN25) +#define PIN_UART4_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN26) +#define PIN_FB_AD22 (PIN_ALT5 | PIN_PORTE | PIN26) +#define PIN_RTC_CLKOUT (PIN_ALT6 | PIN_PORTE | PIN26) +#define PIN_USB_CLKIN (PIN_ALT7 | PIN_PORTE | PIN26) +#define PIN_UART4_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN27) +#define PIN_FB_AD21 (PIN_ALT5 | PIN_PORTE | PIN27) +#define PIN_FB_AD20 (PIN_ALT5 | PIN_PORTE | PIN28) + +#else + /* The pin muxing for other K40 parts is defined in other documents */ + +# error "No pin multiplexing for this Kinetis K40 part" +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H */ diff --git a/arch/arm/src/kinetis/kinetis_k60pinmux.h b/arch/arm/src/kinetis/kinetis_k60pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..7fd69a0813e7f3c3bad938e38e69b5a77deb1719 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_k60pinmux.h @@ -0,0 +1,482 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_k60pinset.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Reference: Paragraph 10.3.1, p 258, of FreeScale document K60P144M100SF2RM + * + * In most cases, there are alternative configurations for various pins. Those alternative + * pins are labeled with a suffix like _1, _2, etc. in order to distinguish them. Logic in + * the board.h file must select the correct pin configuration for the board by defining a pin + * configuration (with no suffix) that maps to the correct alternative. + */ + +#if defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLL100) + +#define PIN_TSI0_CH1 (PIN_ANALOG | PIN_PORTA | PIN0) +#define PIN_UART0_CTS_1 (PIN_ALT2 | PIN_PORTA | PIN0) +#define PIN_FTM0_CH5_1 (PIN_ALT3 | PIN_PORTA | PIN0) +#define PIN_JTAG_TCLK (PIN_ALT7 | PIN_PORTA | PIN0) +#define PIN_SWD_CLK (PIN_ALT7 | PIN_PORTA | PIN0) +#define PIN_TSI0_CH2 (PIN_ANALOG | PIN_PORTA | PIN1) +#define PIN_UART0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN1) +#define PIN_FTM0_CH6_1 (PIN_ALT3 | PIN_PORTA | PIN1) +#define PIN_JTAG_TDI (PIN_ALT7 | PIN_PORTA | PIN1) +#define PIN_TSI0_CH3 (PIN_ANALOG | PIN_PORTA | PIN2) +#define PIN_UART0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN2) +#define PIN_FTM0_CH7_1 (PIN_ALT3 | PIN_PORTA | PIN2) +#define PIN_JTAG_TDO (PIN_ALT7 | PIN_PORTA | PIN2) +#define PIN_TRACE_SWO (PIN_ALT7 | PIN_PORTA | PIN2) +#define PIN_TSI0_CH4 (PIN_ANALOG | PIN_PORTA | PIN3) +#define PIN_UART0_RTS_1 (PIN_ALT2 | PIN_PORTA | PIN3) +#define PIN_FTM0_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN3) +#define PIN_JTAG_TMS (PIN_ALT7 | PIN_PORTA | PIN3) +#define PIN_SWD_DIO (PIN_ALT7 | PIN_PORTA | PIN3) +#define PIN_TSI0_CH5 (PIN_ANALOG | PIN_PORTA | PIN4) +#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4) +#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4) +#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5) +#if 0 +# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5) +# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5) +#else +# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5) +# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5) +#endif +#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5) +#define PIN_I2S0_RX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN5) +#define PIN_JTAG_TRST (PIN_ALT7 | PIN_PORTA | PIN5) +#define PIN_FTM0_CH3_1 (PIN_ALT3 | PIN_PORTA | PIN6) +#define PIN_TRACE_CLKOUT (PIN_ALT7 | PIN_PORTA | PIN6) +#define PIN_ADC0_SE10 (PIN_ANALOG | PIN_PORTA | PIN7) +#define PIN_FTM0_CH4_1 (PIN_ALT3 | PIN_PORTA | PIN7) +#define PIN_TRACE_D3 (PIN_ALT7 | PIN_PORTA | PIN7) +#define PIN_ADC0_SE11 (PIN_ANALOG | PIN_PORTA | PIN8) +#define PIN_FTM1_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN8) +#define PIN_FTM1_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN8) +#define PIN_TRACE_D2 (PIN_ALT7 | PIN_PORTA | PIN8) +#define PIN_FTM1_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN9) +#define PIN_MII0_RXD3 (PIN_ALT4 | PIN_PORTA | PIN9) +#define PIN_FTM1_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN9) +#define PIN_TRACE_D1 (PIN_ALT7 | PIN_PORTA | PIN9) +#define PIN_FTM2_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN10) +#define PIN_MII0_RXD2 (PIN_ALT4 | PIN_PORTA | PIN10) +#define PIN_FTM2_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN10) +#define PIN_TRACE_D0 (PIN_ALT7 | PIN_PORTA | PIN10) +#define PIN_FTM2_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN11) +#define PIN_MII0_RXCLK (PIN_ALT4 | PIN_PORTA | PIN11) +#define PIN_FTM2_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN11) +#define PIN_CMP2_IN0 (PIN_ANALOG | PIN_PORTA | PIN12) +#define PIN_CAN0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN12) +#define PIN_FTM1_CH0_2 (PIN_ALT3 | PIN_PORTA | PIN12) +#define PIN_RMII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12) +#define PIN_MII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12) +#define PIN_I2S0_TXD_1 (PIN_ALT6 | PIN_PORTA | PIN12) +#define PIN_FTM1_QD_PHA_2 (PIN_ALT7 | PIN_PORTA | PIN12) +#define PIN_CMP2_IN1 (PIN_ANALOG | PIN_PORTA | PIN13) +#define PIN_CAN0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN13) +#define PIN_FTM1_CH1_2 (PIN_ALT3 | PIN_PORTA | PIN13) +#define PIN_RMII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13) +#define PIN_MII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13) +#define PIN_I2S0_TX_FS_1 (PIN_ALT6 | PIN_PORTA | PIN13) +#define PIN_FTM1_QD_PHB_2 (PIN_ALT7 | PIN_PORTA | PIN13) +#define PIN_SPI0_PCS0_1 (PIN_ALT2 | PIN_PORTA | PIN14) +#define PIN_UART0_TX_2 (PIN_ALT3 | PIN_PORTA | PIN14) +#define PIN_RMII0_CRS_DV (PIN_ALT4 | PIN_PORTA | PIN14) +#define PIN_MII0_RXDV (PIN_ALT4 | PIN_PORTA | PIN14) +#define PIN_I2S0_TX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN14) +#define PIN_SPI0_SCK_1 (PIN_ALT2 | PIN_PORTA | PIN15) +#define PIN_UART0_RX_2 (PIN_ALT3 | PIN_PORTA | PIN15) +#define PIN_RMII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15) +#define PIN_MII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15) +#define PIN_I2S0_RXD_1 (PIN_ALT6 | PIN_PORTA | PIN15) +#define PIN_SPI0_SOUT_1 (PIN_ALT2 | PIN_PORTA | PIN16) +#define PIN_UART0_CTS_2 (PIN_ALT3 | PIN_PORTA | PIN16) +#define PIN_RMII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16) +#define PIN_MII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16) +#define PIN_I2S0_RX_FS_1 (PIN_ALT6 | PIN_PORTA | PIN16) +#define PIN_ADC1_SE17 (PIN_ANALOG | PIN_PORTA | PIN17) +#define PIN_SPI0_SIN_1 (PIN_ALT2 | PIN_PORTA | PIN17) +#define PIN_UART0_RTS_2 (PIN_ALT3 | PIN_PORTA | PIN17) +#define PIN_RMII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17) +#define PIN_MII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17) +#define PIN_I2S0_MCLK_1 (PIN_ALT6 | PIN_PORTA | PIN17) +#define PIN_I2S0_CLKIN_1 (PIN_ALT7 | PIN_PORTA | PIN17) +#define PIN_EXTAL (PIN_ANALOG | PIN_PORTA | PIN18) +#define PIN_FTM0_FLT2_1 (PIN_ALT3 | PIN_PORTA | PIN18) +#define PIN_FTM_CLKIN0 (PIN_ALT4 | PIN_PORTA | PIN18) +#define PIN_XTAL (PIN_ANALOG | PIN_PORTA | PIN19) +#define PIN_FTM1_FLT0_1 (PIN_ALT3 | PIN_PORTA | PIN19) +#define PIN_FTM_CLKIN1 (PIN_ALT4 | PIN_PORTA | PIN19) +#define PIN_LPT0_ALT1 (PIN_ALT6 | PIN_PORTA | PIN19) +#define PIN_MII0_TXD2 (PIN_ALT4 | PIN_PORTA | PIN24) +#define PIN_FB_A29 (PIN_ALT6 | PIN_PORTA | PIN24) +#define PIN_MII0_TXCLK (PIN_ALT4 | PIN_PORTA | PIN25) +#define PIN_FB_A28 (PIN_ALT6 | PIN_PORTA | PIN25) +#define PIN_MII0_TXD3 (PIN_ALT4 | PIN_PORTA | PIN26) +#define PIN_FB_A27 (PIN_ALT6 | PIN_PORTA | PIN26) +#define PIN_MII0_CRS (PIN_ALT4 | PIN_PORTA | PIN27) +#define PIN_FB_A26 (PIN_ALT6 | PIN_PORTA | PIN27) +#define PIN_MII0_TXER (PIN_ALT4 | PIN_PORTA | PIN28) +#define PIN_FB_A25 (PIN_ALT6 | PIN_PORTA | PIN28) +#define PIN_MII0_COL (PIN_ALT4 | PIN_PORTA | PIN29) +#define PIN_FB_A24 (PIN_ALT6 | PIN_PORTA | PIN29) + +#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_ADC1_SE8 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0) +#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0) +#define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0) +#define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0) +#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0) +#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_ADC1_SE9 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_TSI0_CH6 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1) +#define PIN_FTM1_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN1) +#define PIN_RMII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1) +#define PIN_MII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1) +#define PIN_FTM1_QD_PHB_3 (PIN_ALT6 | PIN_PORTB | PIN1) +#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_TSI0_CH7 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2) +#define PIN_UART0_RTS_3 (PIN_ALT3 | PIN_PORTB | PIN2) +#define PIN_ENET0_1588_TMR0_1 (PIN_ALT4 | PIN_PORTB | PIN2) +#define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2) +#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_TSI0_CH8 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3) +#define PIN_UART0_CTS_3 (PIN_ALT3 | PIN_PORTB | PIN3) +#define PIN_ENET0_1588_TMR1_1 (PIN_ALT4 | PIN_PORTB | PIN3) +#define PIN_FTM0_FLT0_2 (PIN_ALT6 | PIN_PORTB | PIN3) +#define PIN_ADC1_SE10 (PIN_ANALOG | PIN_PORTB | PIN4) +#define PIN_ENET0_1588_TMR2_1 (PIN_ALT4 | PIN_PORTB | PIN4) +#define PIN_FTM1_FLT0_2 (PIN_ALT6 | PIN_PORTB | PIN4) +#define PIN_ADC1_SE11 (PIN_ANALOG | PIN_PORTB | PIN5) +#define PIN_ENET0_1588_TMR3_1 (PIN_ALT4 | PIN_PORTB | PIN5) +#define PIN_FTM2_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN5) +#define PIN_ADC1_SE12 (PIN_ANALOG | PIN_PORTB | PIN6) +#define PIN_FB_AD23 (PIN_ALT5 | PIN_PORTB | PIN6) +#define PIN_ADC1_SE13 (PIN_ANALOG | PIN_PORTB | PIN7) +#define PIN_FB_AD22 (PIN_ALT5 | PIN_PORTB | PIN7) +#define PIN_UART3_RTS_1 (PIN_ALT3 | PIN_PORTB | PIN8) +#define PIN_FB_AD21 (PIN_ALT5 | PIN_PORTB | PIN8) +#define PIN_SPI1_PCS1_1 (PIN_ALT2 | PIN_PORTB | PIN9) +#define PIN_UART3_CTS_1 (PIN_ALT3 | PIN_PORTB | PIN9) +#define PIN_FB_AD20 (PIN_ALT5 | PIN_PORTB | PIN9) +#define PIN_ADC1_SE14 (PIN_ANALOG | PIN_PORTB | PIN10) +#define PIN_SPI1_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN10) +#define PIN_UART3_RX_1 (PIN_ALT3 | PIN_PORTB | PIN10) +#define PIN_FB_AD19 (PIN_ALT5 | PIN_PORTB | PIN10) +#define PIN_FTM0_FLT1_1 (PIN_ALT6 | PIN_PORTB | PIN10) +#define PIN_ADC1_SE15 (PIN_ANALOG | PIN_PORTB | PIN11) +#define PIN_SPI1_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN11) +#define PIN_UART3_TX_1 (PIN_ALT3 | PIN_PORTB | PIN11) +#define PIN_FB_AD18 (PIN_ALT5 | PIN_PORTB | PIN11) +#define PIN_FTM0_FLT2_2 (PIN_ALT6 | PIN_PORTB | PIN11) +#define PIN_TSI0_CH9 (PIN_ANALOG | PIN_PORTB | PIN16) +#define PIN_SPI1_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN16) +#define PIN_UART0_RX_3 (PIN_ALT3 | PIN_PORTB | PIN16) +#define PIN_FB_AD17 (PIN_ALT5 | PIN_PORTB | PIN16) +#define PIN_EWM_IN_1 (PIN_ALT6 | PIN_PORTB | PIN16) +#define PIN_TSI0_CH10 (PIN_ANALOG | PIN_PORTB | PIN17) +#define PIN_SPI1_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN17) +#define PIN_UART0_TX_3 (PIN_ALT3 | PIN_PORTB | PIN17) +#define PIN_FB_AD16 (PIN_ALT5 | PIN_PORTB | PIN17) +#define PIN_EWM_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN17) +#define PIN_TSI0_CH11 (PIN_ANALOG | PIN_PORTB | PIN18) +#define PIN_CAN0_TX_2 (PIN_ALT2 | PIN_PORTB | PIN18) +#define PIN_FTM2_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN18) +#define PIN_I2S0_TX_BCLK_2 (PIN_ALT4 | PIN_PORTB | PIN18) +#define PIN_FB_AD15 (PIN_ALT5 | PIN_PORTB | PIN18) +#define PIN_FTM2_QD_PHA_2 (PIN_ALT6 | PIN_PORTB | PIN18) +#define PIN_TSI0_CH12 (PIN_ANALOG | PIN_PORTB | PIN19) +#define PIN_CAN0_RX_2 (PIN_ALT2 | PIN_PORTB | PIN19) +#define PIN_FTM2_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN19) +#define PIN_I2S0_TX_FS_2 (PIN_ALT4 | PIN_PORTB | PIN19) +#define PIN_FB_OE (PIN_ALT5 | PIN_PORTB | PIN19) +#define PIN_FTM2_QD_PHB_2 (PIN_ALT6 | PIN_PORTB | PIN19) +#define PIN_SPI2_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN20) +#define PIN_FB_AD31 (PIN_ALT5 | PIN_PORTB | PIN20) +#define PIN_CMP0_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN20) +#define PIN_SPI2_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN21) +#define PIN_FB_AD30 (PIN_ALT5 | PIN_PORTB | PIN21) +#define PIN_CMP1_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN21) +#define PIN_SPI2_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN22) +#define PIN_FB_AD29 (PIN_ALT5 | PIN_PORTB | PIN22) +#define PIN_CMP2_OUT_2 (PIN_ALT6 | PIN_PORTB | PIN22) +#define PIN_SPI2_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN23) +#define PIN_SPI0_PCS5 (PIN_ALT3 | PIN_PORTB | PIN23) +#define PIN_FB_AD28 (PIN_ALT5 | PIN_PORTB | PIN23) + +#define PIN_ADC0_SE14 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_TSI0_CH13 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_SPI0_PCS4 (PIN_ALT2 | PIN_PORTC | PIN0) +#define PIN_PDB0_EXTRG_1 (PIN_ALT3 | PIN_PORTC | PIN0) +#define PIN_I2S0_TXD_2 (PIN_ALT4 | PIN_PORTC | PIN0) +#define PIN_FB_AD14 (PIN_ALT5 | PIN_PORTC | PIN0) +#define PIN_ADC0_SE15 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_TSI0_CH14 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_SPI0_PCS3_1 (PIN_ALT2 | PIN_PORTC | PIN1) +#define PIN_UART1_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN1) +#define PIN_FTM0_CH0_2 (PIN_ALT4 | PIN_PORTC | PIN1) +#define PIN_FB_AD13 (PIN_ALT5 | PIN_PORTC | PIN1) +#define PIN_ADC0_SE4B (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_CMP1_IN0 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_TSI0_CH15 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_SPI0_PCS2_2 (PIN_ALT2 | PIN_PORTC | PIN2) +#define PIN_UART1_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN2) +#define PIN_FTM0_CH1_2 (PIN_ALT4 | PIN_PORTC | PIN2) +#define PIN_FB_AD12 (PIN_ALT5 | PIN_PORTC | PIN2) +#define PIN_CMP1_IN1 (PIN_ANALOG | PIN_PORTC | PIN3) +#define PIN_SPI0_PCS1_1 (PIN_ALT2 | PIN_PORTC | PIN3) +#define PIN_UART1_RX_1 (PIN_ALT3 | PIN_PORTC | PIN3) +#define PIN_FTM0_CH2_2 (PIN_ALT4 | PIN_PORTC | PIN3) +#define PIN_FB_CLKOUT (PIN_ALT5 | PIN_PORTC | PIN3) +#define PIN_SPI0_PCS0_2 (PIN_ALT2 | PIN_PORTC | PIN4) +#define PIN_UART1_TX_1 (PIN_ALT3 | PIN_PORTC | PIN4) +#define PIN_FTM0_CH3_2 (PIN_ALT4 | PIN_PORTC | PIN4) +#define PIN_FB_AD11 (PIN_ALT5 | PIN_PORTC | PIN4) +#define PIN_CMP1_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN4) +#define PIN_SPI0_SCK_2 (PIN_ALT2 | PIN_PORTC | PIN5) +#define PIN_LPT0_ALT2 (PIN_ALT4 | PIN_PORTC | PIN5) +#define PIN_FB_AD10 (PIN_ALT5 | PIN_PORTC | PIN5) +#define PIN_CMP0_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN5) +#define PIN_CMP0_IN0 (PIN_ANALOG | PIN_PORTC | PIN6) +#define PIN_SPI0_SOUT_2 (PIN_ALT2 | PIN_PORTC | PIN6) +#define PIN_PDB0_EXTRG_2 (PIN_ALT3 | PIN_PORTC | PIN6) +#define PIN_FB_AD9 (PIN_ALT5 | PIN_PORTC | PIN6) +#define PIN_CMP0_IN1 (PIN_ANALOG | PIN_PORTC | PIN7) +#define PIN_SPI0_SIN_2 (PIN_ALT2 | PIN_PORTC | PIN7) +#define PIN_FB_AD8 (PIN_ALT5 | PIN_PORTC | PIN7) +#define PIN_ADC1_SE4B (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_CMP0_IN2 (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_I2S0_MCLK_2 (PIN_ALT3 | PIN_PORTC | PIN8) +#define PIN_I2S0_CLKIN_2 (PIN_ALT4 | PIN_PORTC | PIN8) +#define PIN_FB_AD7 (PIN_ALT5 | PIN_PORTC | PIN8) +#define PIN_ADC1_SE5B (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_CMP0_IN3 (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_I2S0_RX_BCLK_2 (PIN_ALT4 | PIN_PORTC | PIN9) +#define PIN_FB_AD6 (PIN_ALT5 | PIN_PORTC | PIN9) +#define PIN_FTM2_FLT0_2 (PIN_ALT6 | PIN_PORTC | PIN9) +#define PIN_ADC1_SE6B (PIN_ANALOG | PIN_PORTC | PIN10) +#define PIN_CMP0_IN4 (PIN_ANALOG | PIN_PORTC | PIN10) +#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10) +#define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN10) +#define PIN_FB_AD5 (PIN_ALT5 | PIN_PORTC | PIN10) +#define PIN_ADC1_SE7B (PIN_ANALOG | PIN_PORTC | PIN11) +#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11) +#define PIN_I2S0_RXD_2 (PIN_ALT4 | PIN_PORTC | PIN11) +#define PIN_FB_RW (PIN_ALT5 | PIN_PORTC | PIN11) +#define PIN_UART4_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN12) +#define PIN_FB_AD27 (PIN_ALT5 | PIN_PORTC | PIN12) +#define PIN_UART4_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN13) +#define PIN_FB_AD26 (PIN_ALT5 | PIN_PORTC | PIN13) +#define PIN_UART4_RX_1 (PIN_ALT3 | PIN_PORTC | PIN14) +#define PIN_FB_AD25 (PIN_ALT5 | PIN_PORTC | PIN14) +#define PIN_UART4_TX_1 (PIN_ALT3 | PIN_PORTC | PIN15) +#define PIN_FB_AD24 (PIN_ALT5 | PIN_PORTC | PIN15) +#define PIN_CAN1_RX_1 (PIN_ALT2 | PIN_PORTC | PIN16) +#define PIN_UART3_RX_2 (PIN_ALT3 | PIN_PORTC | PIN16) +#define PIN_ENET0_1588_TMR0_2 (PIN_ALT4 | PIN_PORTC | PIN16) +#define PIN_FB_CS5 (PIN_ALT5 | PIN_PORTC | PIN16) +#define PIN_FB_TSIZ1 (PIN_ALT5 | PIN_PORTC | PIN16) +#define PIN_FB_BE23_16_BLS15_8 (PIN_ALT5 | PIN_PORTC | PIN16) +#define PIN_CAN1_TX_1 (PIN_ALT2 | PIN_PORTC | PIN17) +#define PIN_UART3_TX_2 (PIN_ALT3 | PIN_PORTC | PIN17) +#define PIN_ENET0_1588_TMR1_2 (PIN_ALT4 | PIN_PORTC | PIN17) +#define PIN_FB_CS4 (PIN_ALT5 | PIN_PORTC | PIN17) +#define PIN_FB_TSIZ0 (PIN_ALT5 | PIN_PORTC | PIN17) +#define PIN_FB_BE31_24_BLS7_0 (PIN_ALT5 | PIN_PORTC | PIN17) +#define PIN_UART3_RTS_2 (PIN_ALT3 | PIN_PORTC | PIN18) +#define PIN_ENET0_1588_TMR2_2 (PIN_ALT4 | PIN_PORTC | PIN18) +#define PIN_FB_TBST (PIN_ALT5 | PIN_PORTC | PIN18) +#define PIN_FB_CS2 (PIN_ALT5 | PIN_PORTC | PIN18) +#define PIN_FB_BE15_8_BLS23_16 (PIN_ALT5 | PIN_PORTC | PIN18) +#define PIN_UART3_CTS_2 (PIN_ALT3 | PIN_PORTC | PIN19) +#define PIN_ENET0_1588_TMR3_2 (PIN_ALT4 | PIN_PORTC | PIN19) +#define PIN_FB_CS3 (PIN_ALT5 | PIN_PORTC | PIN19) +#define PIN_FB_BE7_0_BLS31_24 (PIN_ALT5 | PIN_PORTC | PIN19) +#define PIN_FB_TA (PIN_ALT6 | PIN_PORTC | PIN19) + +#define PIN_SPI0_PCS0_3 (PIN_ALT2 | PIN_PORTD | PIN0) +#define PIN_UART2_RTS (PIN_ALT3 | PIN_PORTD | PIN0) +#define PIN_FB_ALE (PIN_ALT5 | PIN_PORTD | PIN0) +#define PIN_FB_CS1 (PIN_ALT5 | PIN_PORTD | PIN0) +#define PIN_FB_TS (PIN_ALT5 | PIN_PORTD | PIN0) +#define PIN_ADC0_SE5B (PIN_ANALOG | PIN_PORTD | PIN1) +#define PIN_SPI0_SCK_3 (PIN_ALT2 | PIN_PORTD | PIN1) +#define PIN_UART2_CTS (PIN_ALT3 | PIN_PORTD | PIN1) +#define PIN_FB_CS0 (PIN_ALT5 | PIN_PORTD | PIN1) +#define PIN_SPI0_SOUT_3 (PIN_ALT2 | PIN_PORTD | PIN2) +#define PIN_UART2_RX (PIN_ALT3 | PIN_PORTD | PIN2) +#define PIN_FB_AD4 (PIN_ALT5 | PIN_PORTD | PIN2) +#define PIN_SPI0_SIN_3 (PIN_ALT2 | PIN_PORTD | PIN3) +#define PIN_UART2_TX (PIN_ALT3 | PIN_PORTD | PIN3) +#define PIN_FB_AD3 (PIN_ALT5 | PIN_PORTD | PIN3) +#define PIN_SPI0_PCS1_2 (PIN_ALT2 | PIN_PORTD | PIN4) +#define PIN_UART0_RTS_4 (PIN_ALT3 | PIN_PORTD | PIN4) +#define PIN_FTM0_CH4_2 (PIN_ALT4 | PIN_PORTD | PIN4) +#define PIN_FB_AD2 (PIN_ALT5 | PIN_PORTD | PIN4) +#define PIN_EWM_IN_2 (PIN_ALT6 | PIN_PORTD | PIN4) +#define PIN_ADC0_SE6B (PIN_ANALOG | PIN_PORTD | PIN5) +#define PIN_SPI0_PCS2_1 (PIN_ALT2 | PIN_PORTD | PIN5) +#define PIN_UART0_CTS_4 (PIN_ALT3 | PIN_PORTD | PIN5) +#define PIN_FTM0_CH5_2 (PIN_ALT4 | PIN_PORTD | PIN5) +#define PIN_FB_AD1 (PIN_ALT5 | PIN_PORTD | PIN5) +#define PIN_EWM_OUT_2 (PIN_ALT6 | PIN_PORTD | PIN5) +#define PIN_ADC0_SE7B (PIN_ANALOG | PIN_PORTD | PIN6) +#define PIN_SPI0_PCS3_2 (PIN_ALT2 | PIN_PORTD | PIN6) +#define PIN_UART0_RX_4 (PIN_ALT3 | PIN_PORTD | PIN6) +#define PIN_FTM0_CH6_2 (PIN_ALT4 | PIN_PORTD | PIN6) +#define PIN_FB_AD0 (PIN_ALT5 | PIN_PORTD | PIN6) +#define PIN_FTM0_FLT0_1 (PIN_ALT6 | PIN_PORTD | PIN6) +#define PIN_CMT_IRO (PIN_ALT2 | PIN_PORTD | PIN7) +#define PIN_UART0_TX_4 (PIN_ALT3 | PIN_PORTD | PIN7) +#define PIN_FTM0_CH7_2 (PIN_ALT4 | PIN_PORTD | PIN7) +#define PIN_FTM0_FLT1_2 (PIN_ALT6 | PIN_PORTD | PIN7) +#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTD | PIN8) +#define PIN_UART5_RX_1 (PIN_ALT3 | PIN_PORTD | PIN8) +#define PIN_FB_A16 (PIN_ALT6 | PIN_PORTD | PIN8) +#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTD | PIN9) +#define PIN_UART5_TX_1 (PIN_ALT3 | PIN_PORTD | PIN9) +#define PIN_FB_A17 (PIN_ALT6 | PIN_PORTD | PIN9) +#define PIN_UART5_RTS_1 (PIN_ALT3 | PIN_PORTD | PIN10) +#define PIN_FB_A18 (PIN_ALT6 | PIN_PORTD | PIN10) +#define PIN_SPI2_PCS0_2 (PIN_ALT2 | PIN_PORTD | PIN11) +#define PIN_UART5_CTS_1 (PIN_ALT3 | PIN_PORTD | PIN11) +#define PIN_SDHC0_CLKIN (PIN_ALT4 | PIN_PORTD | PIN11) +#define PIN_FB_A19 (PIN_ALT6 | PIN_PORTD | PIN11) +#define PIN_SPI2_SCK_2 (PIN_ALT2 | PIN_PORTD | PIN12) +#define PIN_SDHC0_D4 (PIN_ALT4 | PIN_PORTD | PIN12) +#define PIN_FB_A20 (PIN_ALT6 | PIN_PORTD | PIN12) +#define PIN_SPI2_SOUT_2 (PIN_ALT2 | PIN_PORTD | PIN13) +#define PIN_SDHC0_D5 (PIN_ALT4 | PIN_PORTD | PIN13) +#define PIN_FB_A21 (PIN_ALT6 | PIN_PORTD | PIN13) +#define PIN_SPI2_SIN_2 (PIN_ALT2 | PIN_PORTD | PIN14) +#define PIN_SDHC0_D6 (PIN_ALT4 | PIN_PORTD | PIN14) +#define PIN_FB_A22 (PIN_ALT6 | PIN_PORTD | PIN14) +#define PIN_SPI2_PCS1 (PIN_ALT2 | PIN_PORTD | PIN15) +#define PIN_SDHC0_D7 (PIN_ALT4 | PIN_PORTD | PIN15) +#define PIN_FB_A23 (PIN_ALT6 | PIN_PORTD | PIN15) + +#define PIN_ADC1_SE4A (PIN_ANALOG | PIN_PORTE | PIN0) +#define PIN_SPI1_PCS1_2 (PIN_ALT2 | PIN_PORTE | PIN0) +#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0) +#define PIN_SDHC0_D1 (PIN_ALT4 | PIN_PORTE | PIN0) +#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0) +#define PIN_ADC1_SE5A (PIN_ANALOG | PIN_PORTE | PIN1) +#define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1) +#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1) +#define PIN_SDHC0_D0 (PIN_ALT4 | PIN_PORTE | PIN1) +#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1) +#define PIN_ADC1_SE6A (PIN_ANALOG | PIN_PORTE | PIN2) +#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTE | PIN2) +#define PIN_UART1_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN2) +#define PIN_SDHC0_DCLK (PIN_ALT4 | PIN_PORTE | PIN2) +#define PIN_ADC1_SE7A (PIN_ANALOG | PIN_PORTE | PIN3) +#define PIN_SPI1_SIN_2 (PIN_ALT2 | PIN_PORTE | PIN3) +#define PIN_UART1_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN3) +#define PIN_SDHC0_CMD (PIN_ALT4 | PIN_PORTE | PIN3) +#define PIN_SPI1_PCS0_2 (PIN_ALT2 | PIN_PORTE | PIN4) +#define PIN_UART3_TX_3 (PIN_ALT3 | PIN_PORTE | PIN4) +#define PIN_SDHC0_D3 (PIN_ALT4 | PIN_PORTE | PIN4) +#define PIN_SPI1_PCS2 (PIN_ALT2 | PIN_PORTE | PIN5) +#define PIN_UART3_RX_3 (PIN_ALT3 | PIN_PORTE | PIN5) +#define PIN_SDHC0_D2 (PIN_ALT4 | PIN_PORTE | PIN5) +#define PIN_SPI1_PCS3 (PIN_ALT2 | PIN_PORTE | PIN6) +#define PIN_UART3_CTS_3 (PIN_ALT3 | PIN_PORTE | PIN6) +#define PIN_I2S0_MCLK_3 (PIN_ALT4 | PIN_PORTE | PIN6) +#define PIN_I2S0_CLKIN_3 (PIN_ALT6 | PIN_PORTE | PIN6) +#define PIN_UART3_RTS_3 (PIN_ALT3 | PIN_PORTE | PIN7) +#define PIN_I2S0_RXD_3 (PIN_ALT4 | PIN_PORTE | PIN7) +#define PIN_UART5_TX_2 (PIN_ALT3 | PIN_PORTE | PIN8) +#define PIN_I2S0_RX_FS_3 (PIN_ALT4 | PIN_PORTE | PIN8) +#define PIN_UART5_RX_2 (PIN_ALT3 | PIN_PORTE | PIN9) +#define PIN_I2S0_RX_BCLK_3 (PIN_ALT4 | PIN_PORTE | PIN9) +#define PIN_UART5_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN10) +#define PIN_I2S0_TXD_3 (PIN_ALT4 | PIN_PORTE | PIN10) +#define PIN_UART5_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN11) +#define PIN_I2S0_TX_FS_3 (PIN_ALT4 | PIN_PORTE | PIN11) +#define PIN_I2S0_TX_BCLK_3 (PIN_ALT4 | PIN_PORTE | PIN12) +#define PIN_ADC0_SE17 (PIN_ANALOG | PIN_PORTE | PIN24) +#define PIN_CAN1_TX_2 (PIN_ALT2 | PIN_PORTE | PIN24) +#define PIN_UART4_TX_2 (PIN_ALT3 | PIN_PORTE | PIN24) +#define PIN_EWM_OUT_3 (PIN_ALT6 | PIN_PORTE | PIN24) +#define PIN_ADC0_SE18 (PIN_ANALOG | PIN_PORTE | PIN25) +#define PIN_CAN1_RX_2 (PIN_ALT2 | PIN_PORTE | PIN25) +#define PIN_UART4_RX_2 (PIN_ALT3 | PIN_PORTE | PIN25) +#define PIN_EWM_IN_3 (PIN_ALT6 | PIN_PORTE | PIN25) +#define PIN_UART4_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN26) +#define PIN_ENET_1588_CLKIN (PIN_ALT4 | PIN_PORTE | PIN26) +#define PIN_RTC_CLKOUT (PIN_ALT6 | PIN_PORTE | PIN26) +#define PIN_USB_CLKIN (PIN_ALT7 | PIN_PORTE | PIN26) +#define PIN_UART4_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN27) + +#else + /* The pin muxing for other K60 parts is defined in other documents */ + +# error "No pin multiplexing for this Kinetis K60 part" +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H */ diff --git a/arch/arm/src/kinetis/kinetis_llwu.h b/arch/arm/src/kinetis/kinetis_llwu.h new file mode 100644 index 0000000000000000000000000000000000000000..4324a76251b412e0a542816025f408c85514f8a2 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_llwu.h @@ -0,0 +1,252 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_llwu.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_LLWU_PE1_OFFSET 0x0000 /* LLWU Pin Enable 1 Register */ +#define KINETIS_LLWU_PE2_OFFSET 0x0001 /* LLWU Pin Enable 2 Register */ +#define KINETIS_LLWU_PE3_OFFSET 0x0002 /* LLWU Pin Enable 3 Register */ +#define KINETIS_LLWU_PE4_OFFSET 0x0003 /* LLWU Pin Enable 4 Register */ +#define KINETIS_LLWU_ME_OFFSET 0x0004 /* LLWU Module Enable Register */ +#define KINETIS_LLWU_F1_OFFSET 0x0005 /* LLWU Flag 1 Register */ +#define KINETIS_LLWU_F2_OFFSET 0x0006 /* LLWU Flag 2 Register */ +#define KINETIS_LLWU_F3_OFFSET 0x0007 /* LLWU Flag 3 Register */ +#define KINETIS_LLWU_CS_OFFSET 0x0008 /* LLWU Control and Status Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_LLWU_PE1 (KINETIS_LLWU_BASE+KINETIS_LLWU_PE1_OFFSET) +#define KINETIS_LLWU_PE2 (KINETIS_LLWU_BASE+KINETIS_LLWU_PE2_OFFSET) +#define KINETIS_LLWU_PE3 (KINETIS_LLWU_BASE+KINETIS_LLWU_PE3_OFFSET) +#define KINETIS_LLWU_PE4 (KINETIS_LLWU_BASE+KINETIS_LLWU_PE4_OFFSET) +#define KINETIS_LLWU_ME (KINETIS_LLWU_BASE+KINETIS_LLWU_ME_OFFSET) +#define KINETIS_LLWU_F1 (KINETIS_LLWU_BASE+KINETIS_LLWU_F1_OFFSET) +#define KINETIS_LLWU_F2 (KINETIS_LLWU_BASE+KINETIS_LLWU_F2_OFFSET) +#define KINETIS_LLWU_F3 (KINETIS_LLWU_BASE+KINETIS_LLWU_F3_OFFSET) +#define KINETIS_LLWU_CS (KINETIS_LLWU_BASE+KINETIS_LLWU_CS_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* LLWU Pin Enable 1 Register */ + +#define LLWU_PE1_WUPE0_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P0 */ +#define LLWU_PE1_WUPE0_MASK (3 << LLWU_PE1_WUPE0_SHIFT) +# define LLWU_PE1_WUPE0_DISABLED (0 << LLWU_PE1_WUPE0_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE0_RISING (1 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE0_FALLING (2 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE0_BOTH (3 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE1_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P1 */ +#define LLWU_PE1_WUPE1_MASK (3 << LLWU_PE1_WUPE1_SHIFT) +# define LLWU_PE1_WUPE1_DISABLED (0 << LLWU_PE1_WUPE1_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE1_RISING (1 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE1_FALLING (2 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE1_BOTH (3 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE2_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P2 */ +#define LLWU_PE1_WUPE2_MASK (3 << LLWU_PE1_WUPE2_SHIFT) +# define LLWU_PE1_WUPE2_DISABLED (0 << LLWU_PE1_WUPE2_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE2_RISING (1 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE2_FALLING (2 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE2_BOTH (3 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE3_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P3 */ +#define LLWU_PE1_WUPE3_MASK (3 << LLWU_PE1_WUPE3_SHIFT) +# define LLWU_PE1_WUPE3_DISABLED (0 << LLWU_PE1_WUPE3_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE3_RISING (1 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE3_FALLING (2 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE3_BOTH (3 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 2 Register */ + +#define LLWU_PE2_WUPE4_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P4 */ +#define LLWU_PE2_WUPE4_MASK (3 << LLWU_PE2_WUPE4_SHIFT) +# define LLWU_PE2_WUPE4_DISABLED (0 << LLWU_PE2_WUPE4_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE4_RISING (1 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE4_FALLING (2 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE4_BOTH (3 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE5_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P5 */ +#define LLWU_PE2_WUPE5_MASK (3 << LLWU_PE2_WUPE5_SHIFT) +# define LLWU_PE2_WUPE5_DISABLED (0 << LLWU_PE2_WUPE5_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE5_RISING (1 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE5_FALLING (2 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE5_BOTH (3 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE6_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P6 */ +#define LLWU_PE2_WUPE6_MASK (3 << LLWU_PE2_WUPE6_SHIFT) +# define LLWU_PE2_WUPE6_DISABLED (0 << LLWU_PE2_WUPE6_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE6_RISING (1 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE6_FALLING (2 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE6_BOTH (3 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE7_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P7 */ +#define LLWU_PE2_WUPE7_MASK (3 << LLWU_PE2_WUPE7_SHIFT) +# define LLWU_PE2_WUPE7_DISABLED (0 << LLWU_PE2_WUPE7_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE7_RISING (1 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE7_FALLING (2 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE7_BOTH (3 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 3 Register */ + +#define LLWU_PE3_WUPE8_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P8 */ +#define LLWU_PE3_WUPE8_MASK (3 << LLWU_PE3_WUPE8_SHIFT) +# define LLWU_PE3_WUPE8_DISABLED (0 << LLWU_PE3_WUPE8_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE8_RISING (1 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE8_FALLING (2 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE8_BOTH (3 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE9_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P9 */ +#define LLWU_PE3_WUPE9_MASK (3 << LLWU_PE3_WUPE9_SHIFT) +# define LLWU_PE3_WUPE9_DISABLED (0 << LLWU_PE3_WUPE9_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE9_RISING (1 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE9_FALLING (2 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE9_BOTH (3 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE10_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P10 */ +#define LLWU_PE3_WUPE10_MASK (3 << LLWU_PE3_WUPE10_SHIFT) +# define LLWU_PE3_WUPE10_DISABLED (0 << LLWU_PE3_WUPE10_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE10_RISING (1 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE10_FALLING (2 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE10_BOTH (3 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE11_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P11 */ +#define LLWU_PE3_WUPE11_MASK (3 << LLWU_PE3_WUPE11_SHIFT) +# define LLWU_PE3_WUPE11_DISABLED (0 << LLWU_PE3_WUPE11_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE11_RISING (1 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE11_FALLING (2 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE11_BOTH (3 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 4 Register */ + +#define LLWU_PE4_WUPE12_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P12 */ +#define LLWU_PE4_WUPE12_MASK (3 << LLWU_PE4_WUPE12_SHIFT) +# define LLWU_PE4_WUPE12_DISABLED (0 << LLWU_PE4_WUPE12_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE12_RISING (1 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE12_FALLING (2 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE12_BOTH (3 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE13_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P13 */ +#define LLWU_PE4_WUPE13_MASK (3 << LLWU_PE4_WUPE13_SHIFT) +# define LLWU_PE4_WUPE13_DISABLED (0 << LLWU_PE4_WUPE13_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE13_RISING (1 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE13_FALLING (2 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE13_BOTH (3 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE14_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P14 */ +#define LLWU_PE4_WUPE14_MASK (3 << LLWU_PE4_WUPE14_SHIFT) +# define LLWU_PE4_WUPE14_DISABLED (0 << LLWU_PE4_WUPE14_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE14_RISING (1 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE14_FALLING (2 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE14_BOTH (3 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE15_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P15 */ +#define LLWU_PE4_WUPE15_MASK (3 << LLWU_PE4_WUPE15_SHIFT) +# define LLWU_PE4_WUPE15_DISABLED (0 << LLWU_PE4_WUPE15_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE15_RISING (1 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE15_FALLING (2 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE15_BOTH (3 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Module Enable Register */ + +#define LLWU_ME_WUME(n) (1 << (n)) +#define LLWU_ME_WUME0 (1 << 0) /* Bit 0: Wakeup Module Enable for Module 0 */ +#define LLWU_ME_WUME1 (1 << 1) /* Bit 1: Wakeup Module Enable for Module 1 */ +#define LLWU_ME_WUME2 (1 << 2) /* Bit 2: Wakeup Module Enable for Module 2 */ +#define LLWU_ME_WUME3 (1 << 3) /* Bit 3: Wakeup Module Enable for Module 3 */ +#define LLWU_ME_WUME4 (1 << 4) /* Bit 4: Wakeup Module Enable for Module 4 */ +#define LLWU_ME_WUME5 (1 << 5) /* Bit 5: Wakeup Module Enable for Module 5 */ +#define LLWU_ME_WUME6 (1 << 6) /* Bit 6: Wakeup Module Enable for Module 6 */ +#define LLWU_ME_WUME7 (1 << 7) /* Bit 7: Wakeup Module Enable for Module 7 */ + +/* LLWU Flag 1 Register */ + +#define LLWU_F1_WUF(n) (1 << (n)) +#define LLWU_F1_WUF0 (1 << 0) /* Bit 0: Wakeup Flag for LLWU_P0 */ +#define LLWU_F1_WUF1 (1 << 1) /* Bit 1: Wakeup Flag for LLWU_P1 */ +#define LLWU_F1_WUF2 (1 << 2) /* Bit 2: Wakeup Flag for LLWU_P2 */ +#define LLWU_F1_WUF3 (1 << 3) /* Bit 3: Wakeup Flag for LLWU_P3 */ +#define LLWU_F1_WUF4 (1 << 4) /* Bit 4: Wakeup Flag for LLWU_P4 */ +#define LLWU_F1_WUF5 (1 << 5) /* Bit 5: Wakeup Flag for LLWU_P5 */ +#define LLWU_F1_WUF6 (1 << 6) /* Bit 6: Wakeup Flag for LLWU_P6 */ +#define LLWU_F1_WUF7 (1 << 7) /* Bit 7: Wakeup Flag for LLWU_P7 */ + +/* LLWU Flag 2 Register */ + +#define LLWU_F2_WUF(n) (1 << ((n)-8)) +#define LLWU_F2_WUF8 (1 << 8) /* Bit 0: Wakeup Flag for LLWU_P8 */ +#define LLWU_F2_WUF9 (1 << 9) /* Bit 1: Wakeup Flag for LLWU_P9 */ +#define LLWU_F2_WUF10 (1 << 10) /* Bit 2: Wakeup Flag for LLWU_P10 */ +#define LLWU_F2_WUF11 (1 << 11) /* Bit 3: Wakeup Flag for LLWU_P11 */ +#define LLWU_F2_WUF12 (1 << 12) /* Bit 4: Wakeup Flag for LLWU_P12 */ +#define LLWU_F2_WUF13 (1 << 13) /* Bit 5: Wakeup Flag for LLWU_P13 */ +#define LLWU_F2_WUF14 (1 << 14) /* Bit 6: Wakeup Flag for LLWU_P14 */ +#define LLWU_F2_WUF15 (1 << 15) /* Bit 7: Wakeup Flag for LLWU_P15 */ + +/* LLWU Flag 3 Register */ + +#define LLWU_F3_MWUF(n) (1 << (n)) +#define LLWU_F3_MWUF0 (1 << 0) /* Bit 0: Wakeup flag for module 0 */ +#define LLWU_F3_MWUF1 (1 << 1) /* Bit 1: Wakeup flag for module 1 */ +#define LLWU_F3_MWUF2 (1 << 2) /* Bit 2: Wakeup flag for module 2 */ +#define LLWU_F3_MWUF3 (1 << 3) /* Bit 3: Wakeup flag for module 3 */ +#define LLWU_F3_MWUF4 (1 << 4) /* Bit 4: Wakeup flag for module 4 */ +#define LLWU_F3_MWUF5 (1 << 5) /* Bit 5: Wakeup flag for module 5 */ +#define LLWU_F3_MWUF6 (1 << 6) /* Bit 6: Wakeup flag for module 6 */ +#define LLWU_F3_MWUF7 (1 << 7) /* Bit 7: Wakeup flag for module 7 */ + +/* LLWU Control and Status Register */ + +#define LLWU_CS_ACKISO (1 << 7) /* Bit 7: Acknowledge Isolation */ + /* Bits 2-6: Reserved */ +#define LLWU_CS_FLTEP (1 << 1) /* Bit 1: Digital Filter on External Pin */ +#define LLWU_CS_FLTR (1 << 0) /* Bit 0: Digital Filter on RESET Pin */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H */ diff --git a/arch/arm/src/kinetis/kinetis_lowputc.c b/arch/arm/src/kinetis/kinetis_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..bd3b27a8769bd97d4945ad5d32e2d6e3637bfd52 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_lowputc.c @@ -0,0 +1,450 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_lowputc.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "kinetis_config.h" +#include "kinetis.h" +#include "kinetis_uart.h" +#include "kinetis_sim.h" +#include "kinetis_pinmux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART0_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART1_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART2_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART3_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART3_BAUD +# define CONSOLE_BITS CONFIG_UART3_BITS +# define CONSOLE_PARITY CONFIG_UART3_PARITY +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART4_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART4_BAUD +# define CONSOLE_BITS CONFIG_UART4_BITS +# define CONSOLE_PARITY CONFIG_UART4_PARITY +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_BASE KINETIS_UART5_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART5_BAUD +# define CONSOLE_BITS CONFIG_UART5_BITS +# define CONSOLE_PARITY CONFIG_UART5_PARITY +#elif defined(HAVE_SERIAL_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps an encoded FIFO depth (index) to the actual size of the + * FIFO (indexed value). NOTE: That there is no 8th value. + */ + +#ifdef CONFIG_KINETIS_UARTFIFOS +static uint8_t g_sizemap[8] = {1, 4, 8, 16, 32, 64, 128, 0}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART_DEVICE && defined HAVE_SERIAL_CONSOLE +#ifdef CONFIG_KINETIS_UARTFIFOS + /* Wait until there is space in the TX FIFO: Read the number of bytes + * currently in the FIFO and compare that to the size of the FIFO. If + * there are fewer bytes in the FIFO than the size of the FIFO, then we + * are able to transmit. + */ + +# error "Missing logic" +#else + /* Wait until the transmit data register is "empty" (TDRE). This state + * depends on the TX watermark setting and may not mean that the transmit + * buffer is truly empty. It just means that we can now add another + * characterto the transmit buffer without exceeding the watermark. + * + * NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs + * (1-deep). There appears to be no way to know when the FIFO is not + * full (other than reading the FIFO length and comparing the FIFO count). + * Hence, the FIFOs are not used in this implementation and, as a result + * TDRE indeed mean that the single output buffer is available. + * + * Performance on UART0 could be improved by enabling the FIFO and by + * redesigning all of the FIFO status logic. + */ + + while ((getreg8(CONSOLE_BASE+KINETIS_UART_S1_OFFSET) & UART_S1_TDRE) == 0); +#endif + + /* Then write the character to the UART data register */ + + putreg8((uint8_t)ch, CONSOLE_BASE+KINETIS_UART_D_OFFSET); +#endif +} + +/**************************************************************************** + * Name: kinetis_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void kinetis_lowsetup(void) +{ +#ifdef HAVE_UART_DEVICE + uint32_t regval; + + /* Enable peripheral clocking for all enabled UARTs. Clocking for UARTs + * 0-3 is enabled in the SCGC4 register. + */ + +#if defined(CONFIG_KINETIS_UART0) || defined(CONFIG_KINETIS_UART1) || \ + defined(CONFIG_KINETIS_UART2) || defined(CONFIG_KINETIS_UART3) + + regval = getreg32(KINETIS_SIM_SCGC4); +# ifdef CONFIG_KINETIS_UART0 + regval |= SIM_SCGC4_UART0; +# endif +# ifdef CONFIG_KINETIS_UART1 + regval |= SIM_SCGC4_UART1; +# endif +# ifdef CONFIG_KINETIS_UART2 + regval |= SIM_SCGC4_UART2; +# endif +# ifdef CONFIG_KINETIS_UART3 + regval |= SIM_SCGC4_UART3; +# endif + putreg32(regval, KINETIS_SIM_SCGC4); + +#endif + + /* Clocking for UARTs 4-5 is enabled in the SCGC1 register. */ + +#if defined(CONFIG_KINETIS_UART4) || defined(CONFIG_KINETIS_UART5) + + regval = getreg32(KINETIS_SIM_SCGC1); +# ifdef CONFIG_KINETIS_UART4 + regval |= SIM_SCGC1_UART4; +# endif +# ifdef CONFIG_KINETIS_UART5 + regval |= SIM_SCGC1_UART5; +# endif + putreg32(regval, KINETIS_SIM_SCGC1); + +#endif + + /* Configure UART pins for the all enabled UARTs */ + +#ifdef CONFIG_KINETIS_UART0 + kinetis_pinconfig(PIN_UART0_TX); + kinetis_pinconfig(PIN_UART0_RX); +#endif +#ifdef CONFIG_KINETIS_UART1 + kinetis_pinconfig(PIN_UART1_TX); + kinetis_pinconfig(PIN_UART1_RX); +#endif +#ifdef CONFIG_KINETIS_UART2 + kinetis_pinconfig(PIN_UART2_TX); + kinetis_pinconfig(PIN_UART2_RX); +#endif +#ifdef CONFIG_KINETIS_UART3 + kinetis_pinconfig(PIN_UART3_TX); + kinetis_pinconfig(PIN_UART3_RX); +#endif +#ifdef CONFIG_KINETIS_UART4 + kinetis_pinconfig(PIN_UART4_TX); + kinetis_pinconfig(PIN_UART4_RX); +#endif +#ifdef CONFIG_KINETIS_UART5 + kinetis_pinconfig(PIN_UART5_TX); + kinetis_pinconfig(PIN_UART5_RX); +#endif + + /* Configure the console (only) now. Other UARTs will be configured + * when the serial driver is opened. + */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + kinetis_uartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, + CONSOLE_PARITY, CONSOLE_BITS); +#endif +#endif /* HAVE_UART_DEVICE */ +} + +/**************************************************************************** + * Name: kinetis_uartreset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kinetis_uartreset(uintptr_t uart_base) +{ + uint8_t regval; + + /* Just disable the transmitter and receiver */ + + regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET); + regval &= ~(UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base+KINETIS_UART_C2_OFFSET); +} +#endif + +/**************************************************************************** + * Name: kinetis_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud, + uint32_t clock, unsigned int parity, + unsigned int nbits) +{ + uint32_t sbr; + uint32_t brfa; + uint32_t tmp; + uint8_t regval; +#ifdef CONFIG_KINETIS_UARTFIFOS + unsigned int depth; +#endif + + /* Disable the transmitter and receiver throughout the reconfiguration */ + + regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET); + regval &= ~(UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base+KINETIS_UART_C2_OFFSET); + + /* Configure number of bits, stop bits and parity */ + + regval = 0; + + /* Check for odd parity */ + + if (parity == 1) + { + regval |= (UART_C1_PE | UART_C1_PT); /* Enable + odd parity type */ + } + + /* Check for even parity */ + + else if (parity == 2) + { + regval |= UART_C1_PE; /* Enable (even parity default) */ + } + + /* The only other option is no parity */ + + else + { + DEBUGASSERT(parity == 0); + } + + /* Check for 9-bit operation */ + + if (nbits == 9) + { + regval |= UART_C1_M; + } + + /* The only other option is 8-bit operation */ + + else + { + DEBUGASSERT(nbits == 8); + } + + putreg8(regval, uart_base+KINETIS_UART_C1_OFFSET); + + /* Calculate baud settings (truncating) */ + + sbr = clock / (baud << 4); + DEBUGASSERT(sbr < 0x2000); + + /* Save the new baud divisor, retaining other bits in the UARTx_BDH + * register. + */ + + regval = getreg8(uart_base+KINETIS_UART_BDH_OFFSET) & UART_BDH_SBR_MASK; + tmp = sbr >> 8; + regval |= (((uint8_t)tmp) << UART_BDH_SBR_SHIFT) & UART_BDH_SBR_MASK; + putreg8(regval, uart_base+KINETIS_UART_BDH_OFFSET); + + regval = sbr & 0xff; + putreg8(regval, uart_base+KINETIS_UART_BDL_OFFSET); + + /* Calculate a fractional divider to get closer to the requested baud. + * The fractional divider, BRFA, is a 5 bit fractional value that is + * logically added to the SBR: + * + * UART baud rate = clock / (16 × (SBR + BRFD)) + * + * The BRFA the remainder. This will be a non-negative value since the SBR + * was calculated by truncation. + */ + + tmp = clock - (sbr * (baud << 4)); + brfa = (tmp << 5) / (baud << 4); + + /* Set the BRFA field (retaining other bits in the UARTx_C4 register) */ + + regval = getreg8(uart_base+KINETIS_UART_C4_OFFSET) & UART_C4_BRFA_MASK; + regval |= ((uint8_t)brfa << UART_C4_BRFA_SHIFT) & UART_C4_BRFA_MASK; + putreg8(regval, uart_base+KINETIS_UART_C4_OFFSET); + + /* Set the FIFO watermarks. + * + * NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs + * (1-deep). There appears to be no way to know when the FIFO is not + * full (other than reading the FIFO length and comparing the FIFO count). + * Hence, the FIFOs are not used in this implementation and, as a result + * TDRE indeed mean that the single output buffer is available. + * + * Performance on UART0 could be improved by enabling the FIFO and by + * redesigning all of the FIFO status logic. + */ + +#ifdef CONFIG_KINETIS_UARTFIFOS + depth = g_sizemap[(regval & UART_PFIFO_RXFIFOSIZE_MASK) >> UART_PFIFO_RXFIFOSIZE_SHIFT]; + if (depth > 1) + { + depth = (3 * depth) >> 2; + } + putreg8(depth , uart_base+KINETIS_UART_RWFIFO_OFFSET); + + depth = g_sizemap[(regval & UART_PFIFO_TXFIFOSIZE_MASK) >> UART_PFIFO_TXFIFOSIZE_SHIFT]; + if (depth > 3) + { + depth = (depth >> 2); + } + putreg8(depth, uart_base+KINETIS_UART_TWFIFO_OFFSET); + + /* Enable RX and TX FIFOs */ + + putreg8(UART_PFIFO_RXFE | UART_PFIFO_TXFE, uart_base+KINETIS_UART_PFIFO_OFFSET); +#else + /* Otherwise, disable the FIFOs. Then the FIFOs are disable, the effective + * FIFO depth is 1. So set the watermarks as follows: + * + * TWFIFO[TXWATER] = 0: TDRE will be set when the number of queued bytes + * (1 in this case) is less than or equal to 0. + * RWFIFO[RXWATER] = 1: RDRF will be set when the number of queued bytes + * (1 in this case) is greater than or equal to 1. + * + * Set the watermarks to one/zero and disable the FIFOs + */ + + putreg8(1, uart_base+KINETIS_UART_RWFIFO_OFFSET); + putreg8(0, uart_base+KINETIS_UART_TWFIFO_OFFSET); + putreg8(0, uart_base+KINETIS_UART_PFIFO_OFFSET); +#endif + + /* Now we can (re-)enable the transmitter and receiver */ + + regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET); + regval |= (UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base+KINETIS_UART_C2_OFFSET); +} +#endif + diff --git a/arch/arm/src/kinetis/kinetis_lptmr.h b/arch/arm/src/kinetis/kinetis_lptmr.h new file mode 100644 index 0000000000000000000000000000000000000000..863b24108eacec47e4808534cc2a7e93ff602132 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_lptmr.h @@ -0,0 +1,133 @@ +/**************************************************************************************************** + * arch/arm/src/kinetis/kinetis_lptmr.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define KINETIS_LPTMR_CSR_OFFSET 0x0000 /* Low Power Timer Control Status Register */ +#define KINETIS_LPTMR_PSR_OFFSET 0x0004 /* Low Power Timer Prescale Register */ +#define KINETIS_LPTMR_CMR_OFFSET 0x0008 /* Low Power Timer Compare Register */ +#define KINETIS_LPTMR_CNR_OFFSET 0x000c /* Low Power Timer Counter Register */ + +/* Register Addresses *******************************************************************************/ + +#define KINETIS_LPTMR0_CSR (KINETIS_LPTMR_BASE+KINETIS_LPTMR_CSR_OFFSET) +#define KINETIS_LPTMR0_PSR (KINETIS_LPTMR_BASE+KINETIS_LPTMR_PSR_OFFSET) +#define KINETIS_LPTMR0_CMR (KINETIS_LPTMR_BASE+KINETIS_LPTMR_CMR_OFFSET) +#define KINETIS_LPTMR0_CNR (KINETIS_LPTMR_BASE+KINETIS_LPTMR_CNR_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Low Power Timer Control Status Register (32-bit) */ + +#define LPTMR_CSR_TEN (1 << 0) /* Bit 0: Timer Enable */ +#define LPTMR_CSR_TMS (1 << 1) /* Bit 1: Timer Mode Select */ +#define LPTMR_CSR_TFC (1 << 2) /* Bit 2: Timer Free Running Counter */ +#define LPTMR_CSR_TPP (1 << 3) /* Bit 3: Timer Pin Polarity */ +#define LPTMR_CSR_TPS_SHIFT (4) /* Bits 4-5: Timer Pin Select */ +#define LPTMR_CSR_TPS_MASK (3 << LPTMR_CSR_TPS_SHIFT) +# define LPTMR_CSR_TPS_INPUT0 (0 << LPTMR_CSR_TPS_SHIFT) /* Pulse counter input 0 selected */ +# define LPTMR_CSR_TPS_INPUT1 (1 << LPTMR_CSR_TPS_SHIFT) /* Pulse counter input 1 selected */ +# define LPTMR_CSR_TPS_INPUT2 (2 << LPTMR_CSR_TPS_SHIFT) /* Pulse counter input 2 selected */ +# define LPTMR_CSR_TPS_INPUT3 (3 << LPTMR_CSR_TPS_SHIFT) /* Pulse counter input 3 selected */ +#define LPTMR_CSR_TIE (1 << 6) /* Bit 6: Timer Interrupt Enable */ +#define LPTMR_CSR_TCF (1 << 7) /* Bit 7: Timer Compare Flag */ + +/* Low Power Timer Prescale Register (32-bit) */ + +#define LPTMR_PSR_PCS_SHIFT (0) /* Bits 0-1: Prescaler Clock Select */ +#define LPTMR_PSR_PCS_MASK (3 << LPTMR_PSR_PCS_SHIFT) +# define LPTMR_PSR_PCS_CLOCK (0 << LPTMR_PSR_PCS_SHIFT) /* Prescaler/glitch filter clock 0 */ +# define LPTMR_PSR_PCS_CLOCK (1 << LPTMR_PSR_PCS_SHIFT) /* Prescaler/glitch filter clock 1 */ +# define LPTMR_PSR_PCS_CLOCK (2 << LPTMR_PSR_PCS_SHIFT) /* Prescaler/glitch filter clock 2 */ +# define LPTMR_PSR_PCS_CLOCK (3 << LPTMR_PSR_PCS_SHIFT) /* Prescaler/glitch filter clock 3 */ +#define LPTMR_PSR_PBYP (1 << 2) /* Bit 2: Prescaler Bypass */ +#define LPTMR_PSR_PRESCALE_SHIFT (6) /* Bits 3-6: Prescale Value */ +#define LPTMR_PSR_PRESCALE_MASK (15 << LPTMR_PSR_PRESCALE_SHIFT) /* Prescale divider: Glitch filter after: */ +# define LPTMR_PSR_PRESCALE_DIV2 (0 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=2 N/S */ +# define LPTMR_PSR_PRESCALE_DIV4 (1 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=4 2 edges */ +# define LPTMR_PSR_PRESCALE_DIV8 (2 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=8 4 edges */ +# define LPTMR_PSR_PRESCALE_DIV16 (3 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=16 8 edges */ +# define LPTMR_PSR_PRESCALE_DIV32 (4 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=32 16 edges */ +# define LPTMR_PSR_PRESCALE_DIV64 (5 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=64 32 edges */ +# define LPTMR_PSR_PRESCALE_DIV128 (6 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=128 64 edges */ +# define LPTMR_PSR_PRESCALE_DIV256 (7 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=256 128 edges */ +# define LPTMR_PSR_PRESCALE_DIV512 (8 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=512 256 edges */ +# define LPTMR_PSR_PRESCALE_DIV1K (9 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=1024 512 edges */ +# define LPTMR_PSR_PRESCALE_DIV2K (10 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=2048 1024 edges */ +# define LPTMR_PSR_PRESCALE_DIV4K (11 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=4096 2048 edges */ +# define LPTMR_PSR_PRESCALE_DIV8K (12 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=8192 4096 edges */ +# define LPTMR_PSR_PRESCALE_DIV16K (13 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=16384 8192 edges */ +# define LPTMR_PSR_PRESCALE_DIV32K (14 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=32768 16384 edges */ +# define LPTMR_PSR_PRESCALE_DIV64K (15 << LPTMR_PSR_PRESCALE_SHIFT) /* Divider=65536 32768 edges */ + /* Bits 7-31: Reserved */ +/* Low Power Timer Compare Register */ + +#define LPTMR_CMR_SHIFT (0) /* Bits 0-15: Compare Value */ +#define LPTMR_CMR_MASK (0xffff << LPTMR_CMR_COMPARE_SHIFT) + /* Bits 16-31: Reserved */ +/* Low Power Timer Counter Register */ + +#define LPTMR_CNR_SHIFT (0) /* Bits 0-15: Counter Value */ +#define LPTMR_CNR_MASK (0xffff << LPTMR_CNR_COMPARE_SHIFT) + /* Bits 16-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H */ diff --git a/arch/arm/src/kinetis/kinetis_mcg.h b/arch/arm/src/kinetis/kinetis_mcg.h new file mode 100644 index 0000000000000000000000000000000000000000..60f13cd2a0b788ef8e897b0c9adbeee28387aae0 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mcg.h @@ -0,0 +1,186 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_mcg.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_MCG_C1_OFFSET 0x0000 /* MCG Control 1 Register */ +#define KINETIS_MCG_C2_OFFSET 0x0001 /* MCG Control 2 Register */ +#define KINETIS_MCG_C3_OFFSET 0x0002 /* MCG Control 3 Register */ +#define KINETIS_MCG_C4_OFFSET 0x0003 /* MCG Control 4 Register */ +#define KINETIS_MCG_C5_OFFSET 0x0004 /* MCG Control 5 Register */ +#define KINETIS_MCG_C6_OFFSET 0x0005 /* MCG Control 6 Register */ +#define KINETIS_MCG_S_OFFSET 0x0006 /* MCG Status Register */ +#define KINETIS_MCG_ATC_OFFSET 0x0008 /* MCG Auto Trim Control Register */ +#define KINETIS_MCG_ATCVH_OFFSET 0x000a /* MCG Auto Trim Compare Value High Register */ +#define KINETIS_MCG_ATCVL_OFFSET 0x000b /* MCG Auto Trim Compare Value Low Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_MCG_C1 (KINETIS_MCG_BASE+KINETIS_MCG_C1_OFFSET) +#define KINETIS_MCG_C2 (KINETIS_MCG_BASE+KINETIS_MCG_C2_OFFSET) +#define KINETIS_MCG_C3 (KINETIS_MCG_BASE+KINETIS_MCG_C3_OFFSET) +#define KINETIS_MCG_C4 (KINETIS_MCG_BASE+KINETIS_MCG_C4_OFFSET) +#define KINETIS_MCG_C5 (KINETIS_MCG_BASE+KINETIS_MCG_C5_OFFSET) +#define KINETIS_MCG_C6 (KINETIS_MCG_BASE+KINETIS_MCG_C6_OFFSET) +#define KINETIS_MCG_S (KINETIS_MCG_BASE+KINETIS_MCG_S_OFFSET) +#define KINETIS_MCG_ATC (KINETIS_MCG_BASE+KINETIS_MCG_ATC_OFFSET) +#define KINETIS_MCG_ATCVH (KINETIS_MCG_BASE+KINETIS_MCG_ATCVH_OFFSET) +#define KINETIS_MCG_ATCVL (KINETIS_MCG_BASE+KINETIS_MCG_ATCVL_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* MCG Control 1 Register (8-bit) */ + +#define MCG_C1_IREFSTEN (1 << 0) /* Bit 0: Internal Reference Stop Enable */ +#define MCG_C1_IRCLKEN (1 << 1) /* Bit 1: Internal Reference Clock Enable */ +#define MCG_C1_IREFS (1 << 2) /* Bit 2: Internal Reference Select */ +#define MCG_C1_FRDIV_SHIFT (3) /* Bits 3-5: FLL External Reference Divider */ +#define MCG_C1_FRDIV_MASK (7 << MCG_C1_FRDIV_SHIFT) +# define MCG_C1_FRDIV_R0DIV1 (0 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=1 */ +# define MCG_C1_FRDIV_R0DIV2 (1 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=2 */ +# define MCG_C1_FRDIV_R0DIV4 (2 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=4 */ +# define MCG_C1_FRDIV_R0DIV8 (3 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=8 */ +# define MCG_C1_FRDIV_R0DIV16 (4 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=16 */ +# define MCG_C1_FRDIV_R0DIV32 (5 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=32 */ +# define MCG_C1_FRDIV_R0DIV64 (6 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=64 */ +# define MCG_C1_FRDIV_R0DIV128 (7 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=128 */ +# define MCG_C1_FRDIV_DIV32 (0 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=32 */ +# define MCG_C1_FRDIV_DIV64 (1 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=64 */ +# define MCG_C1_FRDIV_DIV128 (2 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=128 */ +# define MCG_C1_FRDIV_DIV256 (3 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=256 */ +# define MCG_C1_FRDIV_DIV512 (4 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=512 */ +# define MCG_C1_FRDIV_DIV1024 (5 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=1024 */ +#define MCG_C1_CLKS_SHIFT (6) /* Bits 6-7: Clock Source Select */ +#define MCG_C1_CLKS_MASK (3 << MCG_C1_CLKS_SHIFT) +# define MCG_C1_CLKS_PLL (0 << MCG_C1_CLKS_SHIFT) /* FLL or PLL output */ +# define MCG_C1_CLKS_INTREF (1 << MCG_C1_CLKS_SHIFT) /* Internal reference clock */ +# define MCG_C1_CLKS_EXTREF (2 << MCG_C1_CLKS_SHIFT) /* External reference clock */ + +/* MCG Control 2 Register */ + +#define MCG_C2_IRCS (1 << 0) /* Bit 0: Internal Reference Clock Select */ +#define MCG_C2_LP (1 << 1) /* Bit 1: Low Power Select */ +#define MCG_C2_EREFS (1 << 2) /* Bit 2: External Reference Select */ +#define MCG_C2_HGO (1 << 3) /* Bit 3: High Gain Oscillator Select */ +#define MCG_C2_RANGE_SHIFT (4) /* Bits 4-5: Frequency Range Select */ +#define MCG_C2_RANGE_MASK (3 << MCG_C2_RANGE_SHIFT) +# define MCG_C2_RANGE_LOW (0 << MCG_C2_RANGE_SHIFT) /* Oscillator of 32 kHz to 40 kHz */ +# define MCG_C2_RANGE_HIGH (1 << MCG_C2_RANGE_SHIFT) /* Oscillator of 1 MHz to 8 MHz */ +# define MCG_C2_RANGE_VHIGH (2 << MCG_C2_RANGE_SHIFT) /* Oscillator of 8 MHz to 32 MHz */ + /* Bits 6-7: Reserved */ +/* MCG Control 3 Register (8-bit Slow Internal Reference Clock Trim Setting) */ + +/* MCG Control 4 Register (8-bit) */ + +#define MCG_C4_SCFTRIM (1 << 0) /* Bit 0: Slow Internal Reference Clock Fine Trim */ +#define MCG_C4_FCTRIM_SHIFT (1) /* Bits 1-4: Fast Internal Reference Clock Trim Setting */ +#define MCG_C4_FCTRIM_MASK (15 << MCG_C4_FCTRIM_SHIFT) +#define MCG_C4_DRST_DRS_SHIFT (5) /* Bits 5-6: DCO Range Select */ +#define MCG_C4_DRST_DRS_MASK (3 << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_LOW (nn << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_MID (nn << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_MIDHIGH (nn << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_HIGH (nn << MCG_C4_DRST_DRS_SHIFT) +#define MCG_C4_DMX32 (1 << 7) /* Bit 7: DCO Maximum Frequency with 32.768 kHz Reference */ + +/* MCG Control 5 Register */ + +#define MCG_C5_PRDIV_SHIFT (0) /* Bits 0-4: PLL External Reference Divider */ +#define MCG_C5_PRDIV_MASK (31 << MCG_C5_PRDIV_SHIFT) +# define MCG_C5_PRDIV(n) (((n)-1) << MCG_C5_PRDIV_SHIFT) /* Divide factor n=1..25 */ +#define MCG_C5_PLLSTEN (1 << 5) /* Bit 5: PLL Stop Enable */ +#define MCG_C5_PLLCLKEN (1 << 6) /* Bit 6: PLL Clock Enable */ + /* Bit 7: Reserved */ + +/* MCG Control 6 Register */ + +#define MCG_C6_VDIV_SHIFT (0) /* Bits 0-4: VCO Divider */ +#define MCG_C6_VDIV_MASK (31 << MCG_C6_VDIV_SHIFT) +# define MCG_C6_VDIV(n) (((n)-24) << MCG_C6_VDIV_SHIFT) /* Divide factor n=24..55 */ +#define MCG_C6_CME (1 << 5) /* Bit 5: Clock Monitor Enable */ +#define MCG_C6_PLLS (1 << 6) /* Bit 6: PLL Select */ +#define MCG_C6_LOLIE (1 << 7) /* Bit 7: Loss of Lock Interrrupt Enable */ + +/* MCG Status Register */ + +#define MCG_S_IRCST (1 << 0) /* Bit 0: Internal Reference Clock Status */ +#define MCG_S_OSCINIT (1 << 1) /* Bit 1: OSC Initialization */ +#define MCG_S_CLKST_SHIFT (2) /* Bits 2-3: Clock Mode Status */ +#define MCG_S_CLKST_MASK (3 << MCG_S_CLKST_SHIFT) +# define MCG_S_CLKST_FLL (0 << MCG_S_CLKST_SHIFT) /* Output of the FLL */ +# define MCG_S_CLKST_INTREF (1 << MCG_S_CLKST_SHIFT) /* Internal reference clock */ +# define MCG_S_CLKST_EXTREF (2 << MCG_S_CLKST_SHIFT) /* External reference clock */ +# define MCG_S_CLKST_PLL (3 << MCG_S_CLKST_SHIFT) /* Output of the PLL */ +#define MCG_S_IREFST (1 << 4) /* Bit 4: Internal Reference Status */ +#define MCG_S_PLLST (1 << 5) /* Bit 5: PLL Select Status */ +#define MCG_S_LOCK (1 << 6) /* Bit 6: Lock Status */ +#define MCG_S_LOLS (1 << 7) /* Bit 7: Loss of Lock Status */ + +/* MCG Auto Trim Control Register */ + /* Bits 0-4: Reserved */ +#define MCG_ATC_ATMF (1 << 5) /* Bit 5: Automatic Trim machine Fail Flag */ +#define MCG_ATC_ATMS (1 << 6) /* Bit 6: Automatic Trim Machine Select */ +#define MCG_ATC_ATME (1 << 7) /* Bit 7: Automatic Trim Machine Enable */ + +/* MCG Auto Trim Compare Value High/Low Registers (8-bit compare value) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H */ diff --git a/arch/arm/src/kinetis/kinetis_mcm.h b/arch/arm/src/kinetis/kinetis_mcm.h new file mode 100644 index 0000000000000000000000000000000000000000..d899b77027ac135150314bfaf214ef3cc7ba6c29 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mcm.h @@ -0,0 +1,151 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_mcm.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_MCM_PLASC_OFFSET 0x0008 /* Crossbar switch (AXBS) slave configuration */ +#define KINETIS_MCM_PLAMC_OFFSET 0x000a /* Crossbar switch (AXBS) master configuration */ +#define KINETIS_MCM_SRAMAP_OFFSET 0x000c /* SRAM arbitration and protection */ +#define KINETIS_MCM_ISR_OFFSET 0x0010 /* Interrupt status register */ +#define KINETIS_MCM_ETBCC_OFFSET 0x0014 /* ETB counter control register */ +#define KINETIS_MCM_ETBRL_OFFSET 0x0018 /* ETB reload register */ +#define KINETIS_MCM_ETBCNT_OFFSET 0x001c /* ETB counter value register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_MCM_PLASC (KINETIS_MCM_BASE+KINETIS_MCM_PLASC_OFFSET) +#define KINETIS_MCM_PLAMC (KINETIS_MCM_BASE+KINETIS_MCM_PLAMC_OFFSET) +#define KINETIS_MCM_SRAMAP (KINETIS_MCM_BASE+KINETIS_MCM_SRAMAP_OFFSET) +#define KINETIS_MCM_ISR (KINETIS_MCM_BASE+KINETIS_MCM_ISR_OFFSET) +#define KINETIS_MCM_ETBCC (KINETIS_MCM_BASE+KINETIS_MCM_ETBCC_OFFSET) +#define KINETIS_MCM_ETBRL (KINETIS_MCM_BASE+KINETIS_MCM_ETBRL_OFFSET) +#define KINETIS_MCM_ETBCNT (KINETIS_MCM_BASE+KINETIS_MCM_ETBCNT_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Crossbar switch (AXBS) slave configuration */ + +#define MCM_PLASC_ASC_SHIFT (0) /* Bits 0-7: Each bit in the ASC field + * indicates if there is a corresponding + * connection to the crossbar switch's + * slave input port. */ +#define MCM_PLASC_ASC_MASK (0xff << MCM_PLASC_ASC_SHIFT) +#define MCM_PLASC_ASC(n) ((1 << (n)) << MCM_PLASC_ASC_SHIFT) + /* Bits 8-15: Reserved */ + +/* Crossbar switch (AXBS) master configuration */ + +#define MCM_PLAMC_AMC_SHIFT (0) /* Bits 0-7: Each bit in the AMC field + * indicates if there is a corresponding + * connection to the AXBS master input port. */ +#define MCM_PLAMC_AMC_MASK (0xff << MCM_PLAMC_AMC_SHIFT) +#define MCM_PLAMC_AMC(n) ((1 << (n)) << MCM_PLAMC_AMC_SHIFT) + /* Bits 8-15: Reserved */ + +/* SRAM arbitration and protection */ + /* Bits 0-23: Reserved */ +#define MCM_SRAMAP_SRAMUAP_SHIFT (24) /* Bits 24-25: SRAM_U arbitration priority */ +#define MCM_SRAMAP_SRAMUAP_MASK (3 << MCM_SRAMAP_SRAMUAP_SHIFT) +# define MCM_SRAMAP_SRAMUAP_RR (0 << MCM_SRAMAP_SRAMUAP_SHIFT) /* Round robin */ +# define MCM_SRAMAP_SRAMUAP_SRR (1 << MCM_SRAMAP_SRAMUAP_SHIFT) /* Special round robin */ +# define MCM_SRAMAP_SRAMUAP_FIXED1 (2 << MCM_SRAMAP_SRAMUAP_SHIFT) /* Fixed pri. Proc highest/backdoor lowest */ +# define MCM_SRAMAP_SRAMUAP_FIXED2 (3 << MCM_SRAMAP_SRAMUAP_SHIFT) /* Fixed pri. Backdoor highest/proc lowest */ +#define MCM_SRAMAP_SRAMUWP (1 << 26) /* Bit 26: SRAM_U write protect */ + /* Bit 27: Reserved */ +#define MCM_SRAMAP_SRAMLAP_SHIFT (28) /* Bits 28-29: SRAM_L arbitration priority */ +#define MCM_SRAMAP_SRAMLAP_MASK (3 << MCM_SRAMAP_SRAMLAP_SHIFT) +# define MCM_SRAMAP_SRAMLAP_RR (0 << MCM_SRAMAP_SRAMLAP_SHIFT) /* Round robin */ +# define MCM_SRAMAP_SRAMLAP_SRR (1 << MCM_SRAMAP_SRAMLAP_SHIFT) /* Special round robin */ +# define MCM_SRAMAP_SRAMLAP_FIXED1 (2 << MCM_SRAMAP_SRAMLAP_SHIFT) /* Fixed pri. Proc highest/backdoor lowest */ +# define MCM_SRAMAP_SRAMLAP_FIXED2 (3 << MCM_SRAMAP_SRAMLAP_SHIFT) /* Fixed pri. Backdoor highest/proc lowest */ +#define MCM_SRAMAP_SRAMLWP (1 << 30) /* Bit 30: SRAM_L write protect */ + /* Bit 31: Reserved */ +/* Interrupt status register */ + /* Bit 0: Reserved */ +#define MCM_ISR_IRQ (1 << 1) /* Bit 1: Normal interrupt pending */ +#define MCM_ISR_NMI (1 << 2) /* Bit 2: Non-maskable interrupt pending */ + /* Bits 3-31: Reserved */ +/* ETB counter control register */ + +#define MCM_ETBCC_CNTEN (1 << 0) /* Bit 0: Counter enable */ +#define MCM_ETBCC_RSPT_SHIFT (1) /* Bits 1-2: Response type */ +#define MCM_ETBCC_RSPT_MASK (3 << MCM_ETBCC_RSPT_SHIFT) +# define MCM_ETBCC_RSPT_NONE (0 << MCM_ETBCC_RSPT_SHIFT) /* No response when ETB count expires */ +# define MCM_ETBCC_RSPT_INT (1 << MCM_ETBCC_RSPT_SHIFT) /* Normal interrupt when ETB count expires */ +# define MCM_ETBCC_RSPT_NMI (2 << MCM_ETBCC_RSPT_SHIFT) /* NMI when ETB count expires */ +# define MCM_ETBCC_RSPT_HALT (3 << MCM_ETBCC_RSPT_SHIFT) /* Debug halt when ETB count expires */ +#define MCM_ETBCC_RLRQ (1 << 3) /* Bit 3: Reload request */ +#define MCM_ETBCC_ETDIS (1 << 4) /* Bit 4: ETM-to-TPIU disable */ +#define MCM_ETBCC_ITDIS (1 << 5) /* Bit 5: ITM-to-TPIU disable */ + /* Bits 6-31: Reserved */ +/* ETB reload register */ + +#define MCM_ETBRL_RELOAD_SHIFT (0) /* Bits 0-10: Byte count reload value */ +#define MCM_ETBRL_RELOAD_MASK (0x7ff << MCM_ETBRL_RELOAD_SHIFT) + /* Bits 11-31: Reserved */ +/* ETB counter value register */ + +#define MCM_ETBCNT_COUNTER_SHIFT (0) /* Bits 0-10: Byte count counter value */ +#define MCM_ETBCNT_COUNTER_MASK (0x7ff << MCM_ETBCNT_COUNTER_SHIFT) + /* Bits 11-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H */ diff --git a/arch/arm/src/kinetis/kinetis_memorymap.h b/arch/arm/src/kinetis/kinetis_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..1e7d2820de451ebfd117c086c31a2de30e2ba3ff --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_memorymap.h @@ -0,0 +1,461 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_memorymap.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ +/* K20 Family + * + * The memory map for the following parts is defined in Freescale document + * K20P64M72SF1RM + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) + +# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read- + * only data (Includes exception + * vectors in first 1024 bytes) */ +# if !defined(KINETIS_FLEXMEM_SIZE) +# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */ +# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */ +# endif + /* 0x18000000 * –0x1bffffff Reserved */ +# define KINETIS_SRAML_BASE 0x1c000000 /* –0x1fffffff SRAM_L: Lower SRAM + * (ICODE/DCODE) */ +# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband + * region */ + /* 0x20100000 * –0x21ffffff Reserved */ +# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */ + /* 0x24000000 * –0x3fffffff Reserved */ +# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral + * bridge 0 (AIPS-Lite0) */ +# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral + * bridge 1 (AIPS-Lite1) */ +# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general + * purpose input/output (GPIO) */ + /* 0x40100000 * –0x41ffffff Reserved */ +# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge + * (AIPS-Lite) and general purpose + * input/output (GPIO) bitband */ + /* 0x44000000 * –0xdfffffff Reserved */ +# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */ + /* 0xe0100000 * –0xffffffff Reserved */ + +/* Peripheral Bridge 0 Memory Map ***************************************************/ + +# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */ +# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */ +# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */ +# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */ +# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */ +# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */ +# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */ +# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */ +# define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */ +# define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */ +# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */ +# define KINETIS_CRC_BASE 0x40032000 /* CRC */ +# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */ +# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */ +# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */ +# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */ +# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */ +# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */ +# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */ +# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */ +# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */ +# define KINETIS_SYSR_BASE 0x40041000 /* System register file */ +# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */ +# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */ +# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */ +# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12)) +# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */ +# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */ +# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */ +# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */ +# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */ +# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */ +# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */ +# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */ +# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */ +# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */ +# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */ +# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */ +# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */ +# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */ +# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */ +# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */ +# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */ +# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */ +# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */ +# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */ +# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */ + +/* Peripheral Bridge 1 Memory Map ***************************************************/ + +# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */ +# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */ +# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */ +# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */ + +# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general + * purpose input/output module that shares the + * crossbar switch slave port with the AIPS-Lite + * is accessed at this address. */ +# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6)) +# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */ +# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */ +# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */ +# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */ +# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */ + +/* Private Peripheral Bus (PPB) Memory Map ******************************************/ + +# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */ +# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */ +# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */ +# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */ +# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */ +# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */ +# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */ + +/* Memory Map ***********************************************************************/ +/* K40 Family + * + * The memory map for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) + +# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read- + * only data (Includes exception + * vectors in first 1024 bytes) */ +# if !defined(KINETIS_FLEXMEM_SIZE) +# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */ +# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */ +# endif +# define KINETIS_SRAML_BASE 0x18000000 /* –0x1fffffff SRAM_L: Lower SRAM + * (ICODE/DCODE) */ +# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband + * region */ + /* 0x20100000 * –0x21ffffff Reserved */ +# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */ + /* 0x24000000 * –0x3fffffff Reserved */ +# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral + * bridge 0 (AIPS-Lite0) */ +# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral + * bridge 1 (AIPS-Lite1) */ +# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general + * purpose input/output (GPIO) */ + /* 0x40100000 * –0x41ffffff Reserved */ +# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge + * (AIPS-Lite) and general purpose + * input/output (GPIO) bitband */ + /* 0x44000000 * –0x5fffffff Reserved */ +# define KINETIS_FLEXBUS_WBBASE 0x60000000 /* –0x7fffffff FlexBus (External Memory - + * Write-back) */ +# define KINETIS_FLEXBUS_WTBASE 0x80000000 /* –0x9fffffff FlexBus (External Memory - + * Write-through) */ +# define KINETIS_FLEXBUS_NXBASE 0xa0000000 /* –0xdfffffff FlexBus (External Memory - + * Non-executable) */ +# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */ + /* 0xe0100000 * –0xffffffff Reserved */ + +/* Peripheral Bridge 0 Memory Map ***************************************************/ + +# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */ +# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */ +# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */ +# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */ +# define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */ +# define KINETIS_MPU_BASE 0x4000d000 /* MPU */ +# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */ +# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */ +# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */ +# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */ +# define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */ +# define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */ +# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */ +# define KINETIS_CRC_BASE 0x40032000 /* CRC */ +# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */ +# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */ +# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */ +# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */ +# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */ +# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */ +# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */ +# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */ +# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */ +# define KINETIS_SYSR_BASE 0x40041000 /* System register file */ +# define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */ +# define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */ +# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */ +# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */ +# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */ +# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12)) +# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */ +# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */ +# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */ +# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */ +# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */ +# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */ +# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */ +# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */ +# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */ +# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */ +# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */ +# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */ +# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */ +# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */ +# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */ +# define KINETIS_UART3_BASE 0x4006d000 /* UART3 */ +# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */ +# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */ +# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */ +# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */ +# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */ +# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */ + +/* Peripheral Bridge 1 Memory Map ***************************************************/ + +# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */ +# define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */ +# define KINETIS_SPI2_BASE 0x400ac000 /* SPI 2 */ +# define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */ +# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */ +# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */ +# define KINETIS_SLCD_BASE 0x400be000 /* Segment LCD */ +# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */ +# define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */ +# define KINETIS_UART4_BASE 0x400ea000 /* UART4 */ +# define KINETIS_UART5_BASE 0x400eb000 /* UART5 */ +# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general + * purpose input/output module that shares the + * crossbar switch slave port with the AIPS-Lite + * is accessed at this address. */ +# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6)) +# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */ +# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */ +# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */ +# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */ +# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */ + +/* Private Peripheral Bus (PPB) Memory Map ******************************************/ + +# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */ +# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */ +# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */ +# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */ +# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */ +# define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */ +# define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */ +# define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */ +# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */ +# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */ + +/* Memory Map ***********************************************************************/ +/* K60 Family + * + * The memory map for the following parts is defined in Freescale document + * K60P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLL100) + +# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read- + * only data (Includes exception + * vectors in first 1024 bytes) */ +# if !defined(KINETIS_FLEXMEM_SIZE) +# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */ +# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */ +# endif +# define KINETIS_SRAML_BASE 0x18000000 /* –0x1fffffff SRAM_L: Lower SRAM + * (ICODE/DCODE) */ +# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband + * region */ + /* 0x20100000 * –0x21ffffff Reserved */ +# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */ + /* 0x24000000 * –0x3fffffff Reserved */ +# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral + * bridge 0 (AIPS-Lite0) */ +# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral + * bridge 1 (AIPS-Lite1) */ +# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general + * purpose input/output (GPIO) */ + /* 0x40100000 * –0x41ffffff Reserved */ +# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge + * (AIPS-Lite) and general purpose + * input/output (GPIO) bitband */ + /* 0x44000000 * –0x5fffffff Reserved */ +# define KINETIS_FLEXBUS_BASE 0x60000000 /* –0x7fffffff FlexBus */ +# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */ + /* 0xe0100000 * –0xffffffff Reserved */ + +/* Peripheral Bridge 0 Memory Map ***************************************************/ + +# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */ +# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */ +# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */ +# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */ +# define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */ +# define KINETIS_MPU_BASE 0x4000d000 /* MPU */ +# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */ +# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */ +# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */ +# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */ +# define KINETIS_SPI0_BASE 0x4002c000 /* DSPI 0 */ +# define KINETIS_SPI1_BASE 0x4002d000 /* DSPI 1 */ +# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */ +# define KINETIS_CRC_BASE 0x40032000 /* CRC */ +# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */ +# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */ +# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */ +# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer (FTM) 0 */ +# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer (FTM) 1 */ +# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */ +# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */ +# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */ +# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */ +# define KINETIS_SYSR_BASE 0x40041000 /* System register file */ +# define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */ +# define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */ +# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */ +# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */ +# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */ +# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12)) +# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */ +# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */ +# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */ +# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */ +# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */ +# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */ +# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */ +# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */ +# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */ +# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (XOSC) */ +# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */ +# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */ +# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */ +# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */ +# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */ +# define KINETIS_UART3_BASE 0x4006d000 /* UART3 */ +# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */ +# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */ +# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */ +# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */ +# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */ +# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */ + +/* Peripheral Bridge 1 Memory Map ***************************************************/ + +# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */ +# define KINETIS_RNGB_BASE 0x400a0000 /* Random number generator (RNGB) */ +# define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */ +# define KINETIS_SPI2_BASE 0x400ac000 /* DSPI 2 */ +# define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */ +# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */ +# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */ +# define KINETIS_EMAC_BASE 0x400c0000 /* Ethernet MAC and IEEE 1588 timers */ +# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */ +# define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */ +# define KINETIS_UART4_BASE 0x400ea000 /* UART4 */ +# define KINETIS_UART5_BASE 0x400eb000 /* UART5 */ +# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general + * purpose input/output module that shares the + * crossbar switch slave port with the AIPS-Lite + * is accessed at this address. */ +# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6)) +# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */ +# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */ +# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */ +# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */ +# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */ + +/* Private Peripheral Bus (PPB) Memory Map ******************************************/ + +# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */ +# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */ +# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */ +# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */ +# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */ +# define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */ +# define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */ +# define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */ +# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */ +# define KINETIS_MMCAU_BASE 0xe0081000 /* Memory Mapped Cryptographic Acceleration Unit (MMCAU) */ +# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */ + +#else + /* The memory map for other parts is defined in other documents and may or may not + * be the same as above (the family members are all very similar) This error just + * means that you have to look at the document and determine for yourself if the + * memory map is the same. + */ + +# error "No memory map for this Kinetis part" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H */ diff --git a/arch/arm/src/kinetis/kinetis_mmcau.h b/arch/arm/src/kinetis/kinetis_mmcau.h new file mode 100644 index 0000000000000000000000000000000000000000..7468a1d0bfe3b3563918e57adf8a99bdfb0aed86 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mmcau.h @@ -0,0 +1,138 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_mmcau.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(KINETIS_NMMCAU) && KINETIS_NMMCAU > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define KINETIS_CAU_CASR_OFFSET 0x0000 /* Status Register */ +#define KINETIS_CAU_CAA_OFFSET 0x0001 /* Accumulator */ + +#define KINETIS_CAU_CA_OFFSET(n) ((n)+2) /* General Purpose Register n */ +#define KINETIS_CAU_CA0_OFFSET 0x0002 /* General Purpose Register 0 */ +#define KINETIS_CAU_CA1_OFFSET 0x0003 /* General Purpose Register 1 */ +#define KINETIS_CAU_CA2_OFFSET 0x0004 /* General Purpose Register 2 */ +#define KINETIS_CAU_CA3_OFFSET 0x0005 /* General Purpose Register 3 */ +#define KINETIS_CAU_CA4_OFFSET 0x0006 /* General Purpose Register 4 */ +#define KINETIS_CAU_CA5_OFFSET 0x0007 /* General Purpose Register 5 */ +#define KINETIS_CAU_CA6_OFFSET 0x0008 /* General Purpose Register 6 */ +#define KINETIS_CAU_CA7_OFFSET 0x0009 /* General Purpose Register 7 */ +#define KINETIS_CAU_CA8_OFFSET 0x000a /* General Purpose Register 8 */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_CAU_CASR (KINETIS_MMCAU_BASE+KINETIS_CAU_CASR_OFFSET) +#define KINETIS_CAU_CAA (KINETIS_MMCAU_BASE+KINETIS_CAU_CAA_OFFSET) + +#define KINETIS_CAU_CA(n) (KINETIS_MMCAU_BASE+KINETIS_CAU_CA_OFFSET(n)) +#define KINETIS_CAU_CA0 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA0_OFFSET) +#define KINETIS_CAU_CA1 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA1_OFFSET) +#define KINETIS_CAU_CA2 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA2_OFFSET) +#define KINETIS_CAU_CA3 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA3_OFFSET) +#define KINETIS_CAU_CA4 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA4_OFFSET) +#define KINETIS_CAU_CA5 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA5_OFFSET) +#define KINETIS_CAU_CA6 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA6_OFFSET) +#define KINETIS_CAU_CA7 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA7_OFFSET) +#define KINETIS_CAU_CA8 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA8_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Status Register */ + +#define CAU_CASR_IC (1 << 0) /* Bit 0: Illegal command */ +#define CAU_CASR_DPE (1 << 1) /* Bit 1: DES parity error */ + /* Bits 2-27: Reserved */ +#define CAU_CASR_VER_SHIFT (28) /* Bits 28-31: CAU version */ +#define CAU_CASR_VER_MASK (15 << CAU_CASR_VER_SHIFT) + +/* Accumulator (32-bit accumulated value)*/ +/* General Purpose Register n (32-bit value used by CAU commands) */ + +/* CAU Commands *********************************************************************/ + +/* Bits 4-8 of 9-bit commands (bits 0-3 may be arguments of the command) */ + +#define CAU_CMD_CNOP 0x000 /* No Operation */ +#define CAU_CMD_LDR 0x010 /* Load Reg */ +#define CAU_CMD_STR 0x020 /* Store Reg */ +#define CAU_CMD_ADR 0x030 /* Add */ +#define CAU_CMD_RADR 0x040 /* Reverse and Add */ +#define CAU_CMD_ADRA 0x050 /* Add Reg to Acc */ +#define CAU_CMD_XOR 0x060 /* Exclusive Or */ +#define CAU_CMD_ROTL 0x070 /* Rotate Left */ +#define CAU_CMD_MVRA 0x080 /* Move Reg to Acc */ +#define CAU_CMD_MVAR 0x090 /* Move Acc to Reg */ +#define CAU_CMD_AESS 0x0a0 /* AES Sub Bytes */ +#define CAU_CMD_AESIS 0x0b0 /* AES Inv Sub Bytes */ +#define CAU_CMD_AESC 0x0c0 /* AES Column Op */ +#define CAU_CMD_AESIC 0x0d0 /* AES Inv Column Op */ +#define CAU_CMD_AESR 0x0e0 /* AES Shift Rows */ +#define CAU_CMD_AESIR 0x0f0 /* AES Inv Shift Rows */ +#define CAU_CMD_DESR 0x100 /* DES Round */ +#define CAU_CMD_DESK 0x110 /* DES Key Setup */ +#define CAU_CMD_HASH 0x120 /* Hash Function */ +#define CAU_CMD_SHS 0x130 /* Secure Hash Shift */ +#define CAU_CMD_MDS 0x140 /* Message Digest Shift */ +#define CAU_CMD_SHS2 0x150 /* Secure Hash Shift 2 */ +#define CAU_CMD_ILL 0x1f0 /* Illegal Command */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* KINETIS_NMMCAU && KINETIS_NMMCAU > 0 */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H */ diff --git a/arch/arm/src/kinetis/kinetis_mpu.h b/arch/arm/src/kinetis/kinetis_mpu.h new file mode 100644 index 0000000000000000000000000000000000000000..f2b1bf914338bc5c94ca0baff83c7fff5faf2260 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mpu.h @@ -0,0 +1,398 @@ +/**************************************************************************************************** + * arch/arm/src/kinetis/kinetis_mpu.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define KINETIS_MPU_CESR_OFFSET 0x0000 /* Control/Error Status Register */ + +#define KINETIS_MPU_EAR_OFFSET(n) (0x0010+((n)<<3)) /* Error Address Register, Slave Port n */ +#define KINETIS_MPU_EDR_OFFSET(n) (0x0014+((n)<<3)) /* Error Detail Register, Slave Port n */ + +#define KINETIS_MPU_EAR0_OFFSET 0x0010 /* Error Address Register, Slave Port 0 */ +#define KINETIS_MPU_EDR0_OFFSET 0x0014 /* Error Detail Register, Slave Port 0 */ +#define KINETIS_MPU_EAR1_OFFSET 0x0018 /* Error Address Register, Slave Port 1 */ +#define KINETIS_MPU_EDR1_OFFSET 0x001c /* Error Detail Register, Slave Port 1 */ +#define KINETIS_MPU_EAR2_OFFSET 0x0020 /* Error Address Register, Slave Port 2 */ +#define KINETIS_MPU_EDR2_OFFSET 0x0024 /* Error Detail Register, Slave Port 2 */ +#define KINETIS_MPU_EAR3_OFFSET 0x0028 /* Error Address Register, Slave Port 3 */ +#define KINETIS_MPU_EDR3_OFFSET 0x002c /* Error Detail Register, Slave Port 3 */ +#define KINETIS_MPU_EAR4_OFFSET 0x0030 /* Error Address Register, Slave Port 4 */ +#define KINETIS_MPU_EDR4_OFFSET 0x0034 /* Error Detail Register, Slave Port 4 */ + +#define KINETIS_MPU_RGD_WORD_OFFSET(n,m) (x0400+((n)<<4)+((m)<< 2) /* Region Descriptor n, Word m */ + +#define KINETIS_MPU_RGD0_WORD0_OFFSET 0x0400 /* Region Descriptor 0, Word 0 */ +#define KINETIS_MPU_RGD0_WORD1_OFFSET 0x0404 /* Region Descriptor 0, Word 1 */ +#define KINETIS_MPU_RGD0_WORD2_OFFSET 0x0408 /* Region Descriptor 0, Word 2 */ +#define KINETIS_MPU_RGD0_WORD3_OFFSET 0x040c /* Region Descriptor 0, Word 3 */ +#define KINETIS_MPU_RGD1_WORD0_OFFSET 0x0410 /* Region Descriptor 1, Word 0 */ +#define KINETIS_MPU_RGD1_WORD1_OFFSET 0x0414 /* Region Descriptor 1, Word 1 */ +#define KINETIS_MPU_RGD1_WORD2_OFFSET 0x0418 /* Region Descriptor 1, Word 2 */ +#define KINETIS_MPU_RGD1_WORD3_OFFSET 0x041c /* Region Descriptor 1, Word 3 */ +#define KINETIS_MPU_RGD2_WORD0_OFFSET 0x0420 /* Region Descriptor 2, Word 0 */ +#define KINETIS_MPU_RGD2_WORD1_OFFSET 0x0424 /* Region Descriptor 2, Word 1 */ +#define KINETIS_MPU_RGD2_WORD2_OFFSET 0x0428 /* Region Descriptor 2, Word 2 */ +#define KINETIS_MPU_RGD2_WORD3_OFFSET 0x042c /* Region Descriptor 2, Word 3 */ +#define KINETIS_MPU_RGD3_WORD0_OFFSET 0x0430 /* Region Descriptor 3, Word 0 */ +#define KINETIS_MPU_RGD3_WORD1_OFFSET 0x0434 /* Region Descriptor 3, Word 1 */ +#define KINETIS_MPU_RGD3_WORD2_OFFSET 0x0438 /* Region Descriptor 3, Word 2 */ +#define KINETIS_MPU_RGD3_WORD3_OFFSET 0x043c /* Region Descriptor 3, Word 3 */ +#define KINETIS_MPU_RGD4_WORD0_OFFSET 0x0440 /* Region Descriptor 4, Word 0 */ +#define KINETIS_MPU_RGD4_WORD1_OFFSET 0x0444 /* Region Descriptor 4, Word 1 */ +#define KINETIS_MPU_RGD4_WORD2_OFFSET 0x0448 /* Region Descriptor 4, Word 2 */ +#define KINETIS_MPU_RGD4_WORD3_OFFSET 0x044c /* Region Descriptor 4, Word 3 */ +#define KINETIS_MPU_RGD5_WORD0_OFFSET 0x0450 /* Region Descriptor 5, Word 0 */ +#define KINETIS_MPU_RGD5_WORD1_OFFSET 0x0454 /* Region Descriptor 5, Word 1 */ +#define KINETIS_MPU_RGD5_WORD2_OFFSET 0x0458 /* Region Descriptor 5, Word 2 */ +#define KINETIS_MPU_RGD5_WORD3_OFFSET 0x045c /* Region Descriptor 5, Word 3 */ +#define KINETIS_MPU_RGD6_WORD0_OFFSET 0x0460 /* Region Descriptor 6, Word 0 */ +#define KINETIS_MPU_RGD6_WORD1_OFFSET 0x0464 /* Region Descriptor 6, Word 1 */ +#define KINETIS_MPU_RGD6_WORD2_OFFSET 0x0468 /* Region Descriptor 6, Word 2 */ +#define KINETIS_MPU_RGD6_WORD3_OFFSET 0x046c /* Region Descriptor 6, Word 3 */ +#define KINETIS_MPU_RGD7_WORD0_OFFSET 0x0470 /* Region Descriptor 7, Word 0 */ +#define KINETIS_MPU_RGD7_WORD1_OFFSET 0x0474 /* Region Descriptor 7, Word 1 */ +#define KINETIS_MPU_RGD7_WORD2_OFFSET 0x0478 /* Region Descriptor 7, Word 2 */ +#define KINETIS_MPU_RGD7_WORD3_OFFSET 0x047c /* Region Descriptor 7, Word 3 */ +#define KINETIS_MPU_RGD8_WORD0_OFFSET 0x0480 /* Region Descriptor 8, Word 0 */ +#define KINETIS_MPU_RGD8_WORD1_OFFSET 0x0484 /* Region Descriptor 8, Word 1 */ +#define KINETIS_MPU_RGD8_WORD2_OFFSET 0x0488 /* Region Descriptor 8, Word 2 */ +#define KINETIS_MPU_RGD8_WORD3_OFFSET 0x048c /* Region Descriptor 8, Word 3 */ +#define KINETIS_MPU_RGD9_WORD0_OFFSET 0x0490 /* Region Descriptor 9, Word 0 */ +#define KINETIS_MPU_RGD9_WORD1_OFFSET 0x0494 /* Region Descriptor 9, Word 1 */ +#define KINETIS_MPU_RGD9_WORD2_OFFSET 0x0498 /* Region Descriptor 9, Word 2 */ +#define KINETIS_MPU_RGD9_WORD3_OFFSET 0x049c /* Region Descriptor 9, Word 3 */ +#define KINETIS_MPU_RGD10_WORD0_OFFSET 0x04a0 /* Region Descriptor 10, Word 0 */ +#define KINETIS_MPU_RGD10_WORD1_OFFSET 0x04a4 /* Region Descriptor 10, Word 1 */ +#define KINETIS_MPU_RGD10_WORD2_OFFSET 0x04a8 /* Region Descriptor 10, Word 2 */ +#define KINETIS_MPU_RGD10_WORD3_OFFSET 0x04ac /* Region Descriptor 10, Word 3 */ +#define KINETIS_MPU_RGD11_WORD0_OFFSET 0x04b0 /* Region Descriptor 11, Word 0 */ +#define KINETIS_MPU_RGD11_WORD1_OFFSET 0x04b4 /* Region Descriptor 11, Word 1 */ +#define KINETIS_MPU_RGD11_WORD2_OFFSET 0x04b8 /* Region Descriptor 11, Word 2 */ +#define KINETIS_MPU_RGD11_WORD3_OFFSET 0x04bc /* Region Descriptor 11, Word 3 */ +#define KINETIS_MPU_RGD12_WORD0_OFFSET 0x04c0 /* Region Descriptor 12, Word 0 */ +#define KINETIS_MPU_RGD12_WORD1_OFFSET 0x04c4 /* Region Descriptor 12, Word 1 */ +#define KINETIS_MPU_RGD12_WORD2_OFFSET 0x04c8 /* Region Descriptor 12, Word 2 */ +#define KINETIS_MPU_RGD12_WORD3_OFFSET 0x04cc /* Region Descriptor 12, Word 3 */ +#define KINETIS_MPU_RGD13_WORD0_OFFSET 0x04d0 /* Region Descriptor 13, Word 0 */ +#define KINETIS_MPU_RGD13_WORD1_OFFSET 0x04d4 /* Region Descriptor 13, Word 1 */ +#define KINETIS_MPU_RGD13_WORD2_OFFSET 0x04d8 /* Region Descriptor 13, Word 2 */ +#define KINETIS_MPU_RGD13_WORD3_OFFSET 0x04dc /* Region Descriptor 13, Word 3 */ +#define KINETIS_MPU_RGD14_WORD0_OFFSET 0x04e0 /* Region Descriptor 14, Word 0 */ +#define KINETIS_MPU_RGD14_WORD1_OFFSET 0x04e4 /* Region Descriptor 14, Word 1 */ +#define KINETIS_MPU_RGD14_WORD2_OFFSET 0x04e8 /* Region Descriptor 14, Word 2 */ +#define KINETIS_MPU_RGD14_WORD3_OFFSET 0x04ec /* Region Descriptor 14, Word 3 */ +#define KINETIS_MPU_RGD15_WORD0_OFFSET 0x04f0 /* Region Descriptor 15, Word 0 */ +#define KINETIS_MPU_RGD15_WORD1_OFFSET 0x04f4 /* Region Descriptor 15, Word 1 */ +#define KINETIS_MPU_RGD15_WORD2_OFFSET 0x04f8 /* Region Descriptor 15, Word 2 */ +#define KINETIS_MPU_RGD15_WORD3_OFFSET 0x04fc /* Region Descriptor 15, Word 3 */ + +#define KINETIS_MPU_RGDAAC_OFFSET(n) (0x0800+((n)<<2)) /* Region Descriptor Alternate Access Control n */ + +#define KINETIS_MPU_RGDAAC0_OFFSET 0x0800 /* Region Descriptor Alternate Access Control 0 */ +#define KINETIS_MPU_RGDAAC1_OFFSET 0x0804 /* Region Descriptor Alternate Access Control 1 */ +#define KINETIS_MPU_RGDAAC2_OFFSET 0x0808 /* Region Descriptor Alternate Access Control 2 */ +#define KINETIS_MPU_RGDAAC3_OFFSET 0x080c /* Region Descriptor Alternate Access Control 3 */ +#define KINETIS_MPU_RGDAAC4_OFFSET 0x0810 /* Region Descriptor Alternate Access Control 4 */ +#define KINETIS_MPU_RGDAAC5_OFFSET 0x0814 /* Region Descriptor Alternate Access Control 5 */ +#define KINETIS_MPU_RGDAAC6_OFFSET 0x0818 /* Region Descriptor Alternate Access Control 6 */ +#define KINETIS_MPU_RGDAAC7_OFFSET 0x081c /* Region Descriptor Alternate Access Control 7 */ +#define KINETIS_MPU_RGDAAC8_OFFSET 0x0820 /* Region Descriptor Alternate Access Control 8 */ +#define KINETIS_MPU_RGDAAC9_OFFSET 0x0824 /* Region Descriptor Alternate Access Control 9 */ +#define KINETIS_MPU_RGDAAC10_OFFSET 0x0828 /* Region Descriptor Alternate Access Control 10 */ +#define KINETIS_MPU_RGDAAC11_OFFSET 0x082c /* Region Descriptor Alternate Access Control 11 */ +#define KINETIS_MPU_RGDAAC12_OFFSET 0x0830 /* Region Descriptor Alternate Access Control 12 */ +#define KINETIS_MPU_RGDAAC13_OFFSET 0x0834 /* Region Descriptor Alternate Access Control 13 */ +#define KINETIS_MPU_RGDAAC14_OFFSET 0x0838 /* Region Descriptor Alternate Access Control 14 */ +#define KINETIS_MPU_RGDAAC15_OFFSET 0x083c /* Region Descriptor Alternate Access Control 15 */ + +/* Register Addresses *******************************************************************************/ + +#define KINETIS_MPU_CESR (KINETIS_MPU_BASE+KINETIS_MPU_CESR_OFFSET) + +#define KINETIS_MPU_EAR(n) (KINETIS_MPU_BASE+KINETIS_MPU_EAR_OFFSET(n)) +#define KINETIS_MPU_EDR(n) (KINETIS_MPU_BASE+KINETIS_MPU_EDR_OFFSET(n)) + +#define KINETIS_MPU_EAR0 (KINETIS_MPU_BASE+KINETIS_MPU_EAR0_OFFSET) +#define KINETIS_MPU_EDR0 (KINETIS_MPU_BASE+KINETIS_MPU_EDR0_OFFSET) +#define KINETIS_MPU_EAR1 (KINETIS_MPU_BASE+KINETIS_MPU_EAR1_OFFSET) +#define KINETIS_MPU_EDR1 (KINETIS_MPU_BASE+KINETIS_MPU_EDR1_OFFSET) +#define KINETIS_MPU_EAR2 (KINETIS_MPU_BASE+KINETIS_MPU_EAR2_OFFSET) +#define KINETIS_MPU_EDR2 (KINETIS_MPU_BASE+KINETIS_MPU_EDR2_OFFSET) +#define KINETIS_MPU_EAR3 (KINETIS_MPU_BASE+KINETIS_MPU_EAR3_OFFSET) +#define KINETIS_MPU_EDR3 (KINETIS_MPU_BASE+KINETIS_MPU_EDR3_OFFSET) +#define KINETIS_MPU_EAR4 (KINETIS_MPU_BASE+KINETIS_MPU_EAR4_OFFSET) +#define KINETIS_MPU_EDR4 (KINETIS_MPU_BASE+KINETIS_MPU_EDR4_OFFSET) + +#define KINETIS_MPU_RGD_WORD(n,m) (KINETIS_MPU_BASE+KINETIS_MPU_RGD_WORD_OFFSET(n,m)) + +#define KINETIS_MPU_RGD0_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD0_OFFSET) +#define KINETIS_MPU_RGD0_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD1_OFFSET) +#define KINETIS_MPU_RGD0_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD2_OFFSET) +#define KINETIS_MPU_RGD0_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD3_OFFSET) +#define KINETIS_MPU_RGD1_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD0_OFFSET) +#define KINETIS_MPU_RGD1_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD1_OFFSET) +#define KINETIS_MPU_RGD1_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD2_OFFSET) +#define KINETIS_MPU_RGD1_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD3_OFFSET) +#define KINETIS_MPU_RGD2_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD0_OFFSET) +#define KINETIS_MPU_RGD2_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD1_OFFSET) +#define KINETIS_MPU_RGD2_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD2_OFFSET) +#define KINETIS_MPU_RGD2_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD3_OFFSET) +#define KINETIS_MPU_RGD3_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD0_OFFSET) +#define KINETIS_MPU_RGD3_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD1_OFFSET) +#define KINETIS_MPU_RGD3_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD2_OFFSET) +#define KINETIS_MPU_RGD3_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD3_OFFSET) +#define KINETIS_MPU_RGD4_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD0_OFFSET) +#define KINETIS_MPU_RGD4_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD1_OFFSET) +#define KINETIS_MPU_RGD4_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD2_OFFSET) +#define KINETIS_MPU_RGD4_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD3_OFFSET) +#define KINETIS_MPU_RGD5_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD0_OFFSET) +#define KINETIS_MPU_RGD5_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD1_OFFSET) +#define KINETIS_MPU_RGD5_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD2_OFFSET) +#define KINETIS_MPU_RGD5_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD3_OFFSET) +#define KINETIS_MPU_RGD6_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD0_OFFSET) +#define KINETIS_MPU_RGD6_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD1_OFFSET) +#define KINETIS_MPU_RGD6_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD2_OFFSET) +#define KINETIS_MPU_RGD6_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD3_OFFSET) +#define KINETIS_MPU_RGD7_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD0_OFFSET) +#define KINETIS_MPU_RGD7_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD1_OFFSET) +#define KINETIS_MPU_RGD7_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD2_OFFSET) +#define KINETIS_MPU_RGD7_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD3_OFFSET) +#define KINETIS_MPU_RGD8_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD0_OFFSET) +#define KINETIS_MPU_RGD8_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD1_OFFSET) +#define KINETIS_MPU_RGD8_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD2_OFFSET) +#define KINETIS_MPU_RGD8_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD3_OFFSET) +#define KINETIS_MPU_RGD9_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD0_OFFSET) +#define KINETIS_MPU_RGD9_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD1_OFFSET) +#define KINETIS_MPU_RGD9_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD2_OFFSET) +#define KINETIS_MPU_RGD9_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD3_OFFSET) +#define KINETIS_MPU_RGD10_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD0_OFFSET) +#define KINETIS_MPU_RGD10_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD1_OFFSET) +#define KINETIS_MPU_RGD10_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD2_OFFSET) +#define KINETIS_MPU_RGD10_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD3_OFFSET) +#define KINETIS_MPU_RGD11_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD0_OFFSET) +#define KINETIS_MPU_RGD11_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD1_OFFSET) +#define KINETIS_MPU_RGD11_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD2_OFFSET) +#define KINETIS_MPU_RGD11_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD3_OFFSET) +#define KINETIS_MPU_RGD12_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD12_WORD0_OFFSET) +#define KINETIS_MPU_RGD12_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD12_WORD1_OFFSET) +#define KINETIS_MPU_RGD12_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD12_WORD2_OFFSET) +#define KINETIS_MPU_RGD12_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD12_WORD3_OFFSET) +#define KINETIS_MPU_RGD13_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD13_WORD0_OFFSET) +#define KINETIS_MPU_RGD13_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD13_WORD1_OFFSET) +#define KINETIS_MPU_RGD13_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD13_WORD2_OFFSET) +#define KINETIS_MPU_RGD13_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD13_WORD3_OFFSET) +#define KINETIS_MPU_RGD14_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD14_WORD0_OFFSET) +#define KINETIS_MPU_RGD14_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD14_WORD1_OFFSET) +#define KINETIS_MPU_RGD14_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD14_WORD2_OFFSET) +#define KINETIS_MPU_RGD14_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD14_WORD3_OFFSET) +#define KINETIS_MPU_RGD15_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD15_WORD0_OFFSET) +#define KINETIS_MPU_RGD15_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD15_WORD1_OFFSET) +#define KINETIS_MPU_RGD15_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD15_WORD2_OFFSET) +#define KINETIS_MPU_RGD15_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD15_WORD3_OFFSET) + +#define KINETIS_MPU_RGDAAC(n) (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC_OFFSET(n)) + +#define KINETIS_MPU_RGDAAC0 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC0_OFFSET) +#define KINETIS_MPU_RGDAAC1 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC1_OFFSET) +#define KINETIS_MPU_RGDAAC2 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC2_OFFSET) +#define KINETIS_MPU_RGDAAC3 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC3_OFFSET) +#define KINETIS_MPU_RGDAAC4 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC4_OFFSET) +#define KINETIS_MPU_RGDAAC5 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC5_OFFSET) +#define KINETIS_MPU_RGDAAC6 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC6_OFFSET) +#define KINETIS_MPU_RGDAAC7 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC7_OFFSET) +#define KINETIS_MPU_RGDAAC8 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC8_OFFSET) +#define KINETIS_MPU_RGDAAC9 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC9_OFFSET) +#define KINETIS_MPU_RGDAAC10 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC10_OFFSET) +#define KINETIS_MPU_RGDAAC11 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC11_OFFSET) +#define KINETIS_MPU_RGDAAC12 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC12_OFFSET) +#define KINETIS_MPU_RGDAAC13 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC13_OFFSET) +#define KINETIS_MPU_RGDAAC14 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC14_OFFSET) +#define KINETIS_MPU_RGDAAC15 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC15_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Control/Error Status Register */ + +#define MPU_CESR_VLD (1 << 0) /* Bit 0: Valid (global enable/disable for the MPU) */ + /* Bits 1-7: Reserved */ +#define MPU_CESR_NRGD_SHIFT (8) /* Bits 8-11: Number of region descriptors */ +#define MPU_CESR_NRGD_MASK (15 << MPU_CESR_NRGD_SHIFT) +# define MPU_CESR_NRGD_8DESC (0 << MPU_CESR_NRGD_SHIFT) /* 8 region descriptors */ +# define MPU_CESR_NRGD_12DESC (1 << MPU_CESR_NRGD_SHIFT) /* 12 region descriptors */ +# define MPU_CESR_NRGD_16DESC (2 << MPU_CESR_NRGD_SHIFT) /* 16 region descriptors */ +#define MPU_CESR_NSP_SHIFT (12) /* Bits 12-15: Number of slave ports */ +#define MPU_CESR_NSP_MASK (15 << MPU_CESR_NSP_SHIFT) +#define MPU_CESR_HRL_SHIFT (16) /* Bits 16-19: Hardware revision level */ +#define MPU_CESR_HRL_MASK (15 << MPU_CESR_HRL_SHIFT) + /* Bits 20-26: Reserved */ +#define MPU_CESR_SPERR_SHIFT (27) /* Bits 27-31: Slave port n error */ +#define MPU_CESR_SPERR_MASK (31 << MPU_CESR_SPERR_SHIFT) +# define MPU_CESR_SPERR_SPORT(n) ((1 << (4-(n))) << MPU_CESR_SPERR_SHIFT) /* Slave port nn */ +# define MPU_CESR_SPERR_SPORT0 (16 << MPU_CESR_SPERR_SHIFT) /* Slave port 0 */ +# define MPU_CESR_SPERR_SPORT1 (8 << MPU_CESR_SPERR_SHIFT) /* Slave port 1 */ +# define MPU_CESR_SPERR_SPORT2 (4 << MPU_CESR_SPERR_SHIFT) /* Slave port 2 */ +# define MPU_CESR_SPERR_SPORT3 (2 << MPU_CESR_SPERR_SHIFT) /* Slave port 3 */ +# define MPU_CESR_SPERR_SPORT4 (1 << MPU_CESR_SPERR_SHIFT) /* Slave port 4 */ + +/* Error Address Register, Slave Port n. 32-bit error address. */ + +/* Error Detail Register, Slave Port n */ + +#define MPU_EDR_ERW (1 << 0) /* Bit 0: Error read/write */ +#define MPU_EDR_EATTR_SHIFT (1) /* Bits 1-3: Error attributes */ +#define MPU_EDR_EATTR_MASK (7 << MPU_EDR_EATTR_SHIFT) +# define MPU_EDR_EATTR_USRINST (0 << MPU_EDR_EATTR_SHIFT) /* User mode, instruction access */ +# define MPU_EDR_EATTR_USRDATA (1 << MPU_EDR_EATTR_SHIFT) /* User mode, data access */ +# define MPU_EDR_EATTR_SUPINST (2 << MPU_EDR_EATTR_SHIFT) /* Supervisor mode, instruction access */ +# define MPU_EDR_EATTR_SUPDATA (3 << MPU_EDR_EATTR_SHIFT) /* Supervisor mode, data access */ +#define MPU_EDR_EMN_SHIFT (4) /* Bits 4-7: Error master number */ +#define MPU_EDR_EMN_MASK (15 << MPU_EDR_EMN_SHIFT) + /* Bits 8-15: Reserved */ +#define MPU_EDR_EACD_SHIFT (26) /* Bits 16-31: Error access control detail */ +#define MPU_EDR_EACD_MASK (0xffff << MPU_EDR_EACD_SHIFT) + +/* Region Descriptor n, Word 0 */ + /* Bits 0-4: Reserved */ +#define MPU_RGD_WORD0_SRTADDR_SHIFT (5) /* Bits 5-31: Start address */ +#define MPU_RGD_WORD0_SRTADDR_MASK (0xffffffe0) + +/* Region Descriptor n, Word 1 */ + /* Bits 0-4: Reserved */ +#define MPU_RGD_WORD1_ENDADDR_SHIFT (5) /* Bits 5-31: End address */ +#define MPU_RGD_WORD1_ENDADDR_MASK (0xffffffe0) + +/* Region Descriptor n, Word 2 */ + +#define MPU_RGD_MSM_RWX 0 /* R/W/X; read, write and execute allowed */ +#define MPU_RGD_MSM_RX 1 /* R/X; read and execute allowed, but no write */ +#define MPU_RGD_MSM_RW 2 /* R/W; read and write allowed, but no execute */ +#define MPU_RGD_MSM_UM 3 /* Same as user mode defined in MUM */ + +#define MPU_RGD_MUM_R 4 /* Read allowed */ +#define MPU_RGD_MUM_W 2 /* Write allowed */ +#define MPU_RGD_MUM_X 1 /* Execute allocated */ + +#define MPU_RGD_WORD2_M0UM_SHIFT (0) /* Bits 0-2: Bus master 0 user mode access control */ +#define MPU_RGD_WORD2_M0UM_MASK (7 << MPU_RGD_WORD2_M0UM_SHIFT) +#define MPU_RGD_WORD2_M0SM_SHIFT (3) /* Bits 3-4: Bus master 0 supervisor mode access control */ +#define MPU_RGD_WORD2_M0SM_MASK (3 << MPU_RGD_WORD2_M0SM_SHIFT) + /* Bit 5: Reserved */ +#define MPU_RGD_WORD2_M1UM_SHIFT (6) /* Bits 6-8: Bus master 1 user mode access control */ +#define MPU_RGD_WORD2_M1UM_MASK (7 << MPU_RGD_WORD2_M1UM_SHIFT) +#define MPU_RGD_WORD2_M1SM_SHIFT (9) /* Bits 9-10: Bus master 1 supervisor mode access control */ +#define MPU_RGD_WORD2_M1SM_MASK (3 << MPU_RGD_WORD2_M1SM_SHIFT) + /* Bit 11: Reserved */ +#define MPU_RGD_WORD2_M2UM_SHIFT (12) /* Bits 12-14: Bus master 2 user mode access control */ +#define MPU_RGD_WORD2_M2UM_MASK (7 << MPU_RGD_WORD2_M2UM_SHIFT) +#define MPU_RGD_WORD2_M2SM_SHIFT (15) /* Bits 15-16: Bus master 2 supervisor mode access control */ +#define MPU_RGD_WORD2_M2SM_MASK (3 << MPU_RGD_WORD2_M2SM_SHIFT) + /* Bit 17: Reserved */ +#define MPU_RGD_WORD2_M3UM_SHIFT (18) /* Bits 18-20: Bus master 3 user mode access control */ +#define MPU_RGD_WORD2_M3UM_MASK (7 << MPU_RGD_WORD2_M3UM_SHIFT) +#define MPU_RGD_WORD2_M3SM_SHIFT (21) /* Bits 21-22: Bus master 3 supervisor mode access control */ +#define MPU_RGD_WORD2_M3SM_MASK (3 << MPU_RGD_WORD2_M3SM_SHIFT) + /* Bit 23: Reserved */ +#define MPU_RGD_WORD2_M4WE (1 << 24) /* Bit 24: Bus master 4 write enable */ +#define MPU_RGD_WORD2_M4RE (1 << 25) /* Bit 25: Bus master 4 read enable */ +#define MPU_RGD_WORD2_M5WE (1 << 26) /* Bit 26: Bus master 5 write enable */ +#define MPU_RGD_WORD2_M5RE (1 << 27) /* Bit 27: Bus master 5 read enable */ +#define MPU_RGD_WORD2_M6WE (1 << 28) /* Bit 28: Bus master 6 write enable */ +#define MPU_RGD_WORD2_M6RE (1 << 29) /* Bit 29: Bus master 6 read enable */ +#define MPU_RGD_WORD2_M7WE (1 << 30) /* Bit 30: Bus master 7 write enable */ +#define MPU_RGD_WORD2_M7RE (1 << 31) /* Bit 31: Bus master 7 read enable */ + +/* Region Descriptor n, Word 3 */ + +#define MPU_RGD_WORD3_VLD (1 << 0) /* Bit 0: Valid */ + /* Bits 1-31: Reserved */ +/* Region Descriptor Alternate Access Control n */ + +#define MPU_RGD_RBDACC_M0UM_SHIFT (0) /* Bits 0-2: Bus master 0 user mode access control */ +#define MPU_RGD_RBDACC_M0UM_MASK (7 << MPU_RGD_RBDACC_M0UM_SHIFT) +#define MPU_RGD_RBDACC_M0SM_SHIFT (3) /* Bits 3-4: Bus master 0 supervisor mode access control */ +#define MPU_RGD_RBDACC_M0SM_MASK (3 << MPU_RGD_RBDACC_M0SM_SHIFT) + /* Bit 5: Reserved */ +#define MPU_RGD_RBDACC_M1UM_SHIFT (6) /* Bits 6-8: Bus master 1 user mode access control */ +#define MPU_RGD_RBDACC_M1UM_MASK (7 << MPU_RGD_RBDACC_M1UM_SHIFT) +#define MPU_RGD_RBDACC_M1SM_SHIFT (9) /* Bits 9-10: Bus master 1 supervisor mode access control */ +#define MPU_RGD_RBDACC_M1SM_MASK (3 << MPU_RGD_RBDACC_M1SM_SHIFT) + /* Bit 11: Reserved */ +#define MPU_RGD_RBDACC_M2UM_SHIFT (12) /* Bits 12-14: Bus master 2 user mode access control */ +#define MPU_RGD_RBDACC_M2UM_MASK (7 << MPU_RGD_RBDACC_M2UM_SHIFT) +#define MPU_RGD_RBDACC_M2SM_SHIFT (15) /* Bits 15-16: Bus master 2 supervisor mode access control */ +#define MPU_RGD_RBDACC_M2SM_MASK (3 << MPU_RGD_RBDACC_M2SM_SHIFT) + /* Bit 17: Reserved */ +#define MPU_RGD_RBDACC_M3UM_SHIFT (18) /* Bits 18-20: Bus master 3 user mode access control */ +#define MPU_RGD_RBDACC_M3UM_MASK (7 << MPU_RGD_RBDACC_M3UM_SHIFT) +#define MPU_RGD_RBDACC_M3SM_SHIFT (21) /* Bits 21-22: Bus master 3 supervisor mode access control */ +#define MPU_RGD_RBDACC_M3SM_MASK (3 << MPU_RGD_RBDACC_M3SM_SHIFT) + /* Bit 23: Reserved */ +#define MPU_RGD_RBDACC_M4WE (1 << 24) /* Bit 24: Bus master 4 write enable */ +#define MPU_RGD_RBDACC_M4RE (1 << 25) /* Bit 25: Bus master 4 read enable */ +#define MPU_RGD_RBDACC_M5WE (1 << 26) /* Bit 26: Bus master 5 write enable */ +#define MPU_RGD_RBDACC_M5RE (1 << 27) /* Bit 27: Bus master 5 read enable */ +#define MPU_RGD_RBDACC_M6WE (1 << 28) /* Bit 28: Bus master 6 write enable */ +#define MPU_RGD_RBDACC_M6RE (1 << 29) /* Bit 29: Bus master 6 read enable */ +#define MPU_RGD_RBDACC_M7WE (1 << 30) /* Bit 30: Bus master 7 write enable */ +#define MPU_RGD_RBDACC_M7RE (1 << 31) /* Bit 31: Bus master 7 read enable */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H */ diff --git a/arch/arm/src/kinetis/kinetis_mpuinit.c b/arch/arm/src/kinetis/kinetis_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..6c41f85bf4feae045c89f1a348ca20c892880c8c --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_mpuinit.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "kinetis_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void kinetis_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: kinetis_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void kinetis_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/kinetis/kinetis_mpuinit.h b/arch/arm/src/kinetis/kinetis_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..f3cf95370efc9addeb53f17871c50b370aa1239f --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_mpuinit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_mpuinit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MPUINIT_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: kinetis_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void kinetis_mpuinitialize(void); +#else +# define kinetis_mpuinitialize() +#endif + +/**************************************************************************** + * Name: kinetis_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void kinetis_mpu_uheap(uintptr_t start, size_t size); +#else +# define kinetis_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MPUINIT_H */ diff --git a/arch/arm/src/kinetis/kinetis_osc.h b/arch/arm/src/kinetis/kinetis_osc.h new file mode 100644 index 0000000000000000000000000000000000000000..16efcf328266055cf0ac411838a8b948dd520f93 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_osc.h @@ -0,0 +1,84 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_osc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_OSC_CR_OFFSET 0x0000 /* OSC Control Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_OSC_CR (KINETIS_OSC_BASE+KINETIS_OSC_CR_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* OSC Control Register (8-bit) */ + +#define OSC_CR_ERCLKEN (1 << 7) /* Bit 7: External Reference Enable */ + /* Bit 6: Reserved */ +#define OSC_CR_EREFSTEN (1 << 5) /* Bit 5: External Reference Stop Enable */ + /* Bit 4: Reserved */ +#define OSC_CR_SC2P (1 << 3) /* Bit 3: Oscillator 2 pF Capacitor Load Configure */ +#define OSC_CR_SC4P (1 << 2) /* Bit 2: Oscillator 4 pF Capacitor Load Configure */ +#define OSC_CR_SC8P (1 << 1) /* Bit 1: Oscillator 8 pF Capacitor Load Configure */ +#define OSC_CR_SC16P (1 << 0) /* Bit 0: Oscillator 16 pF Capacitor Load Configure */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H */ diff --git a/arch/arm/src/kinetis/kinetis_pdb.h b/arch/arm/src/kinetis/kinetis_pdb.h new file mode 100644 index 0000000000000000000000000000000000000000..9cfab9b99f187b3dbe0440f2c486d32c84784ce5 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pdb.h @@ -0,0 +1,255 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_pdb.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_PDB_SC_OFFSET 0x0000 /* Status and Control Register */ +#define KINETIS_PDB_MOD_OFFSET 0x0004 /* Modulus Register */ +#define KINETIS_PDB_CNT_OFFSET 0x0008 /* Counter Register */ +#define KINETIS_PDB_IDLY_OFFSET 0x000c /* Interrupt Delay Register */ + +#define KINETIS_PDB_CH_OFFSET(n) (0x0010+(0x28*(n)) /* Channel n */ +#define KINETIS_PDB_CHC1_OFFSET 0x0000 /* Channel n Control Register 1 */ +#define KINETIS_PDB_CHS_OFFSET 0x0004 /* Channel n Status Register */ +#define KINETIS_PDB_CHDLY0_OFFSET 0x0008 /* Channel n Delay 0 Register */ +#define KINETIS_PDB_CHDLY1_OFFSET 0x000c /* Channel n Delay 1 Register */ + +#define KINETIS_PDB_CH0C1_OFFSET 0x0010 /* Channel 0 Control Register 1 */ +#define KINETIS_PDB_CH0S_OFFSET 0x0014 /* Channel 0 Status Register */ +#define KINETIS_PDB_CH0DLY0_OFFSET 0x0018 /* Channel 0 Delay 0 Register */ +#define KINETIS_PDB_CH0DLY1_OFFSET 0x001c /* Channel 0 Delay 1 Register */ + +#define KINETIS_PDB_CH1C1_OFFSET 0x0038 /* Channel 1 Control Register 1 */ +#define KINETIS_PDB_CH1S_OFFSET 0x003c /* Channel 1 Status Register */ +#define KINETIS_PDB_CH1DLY0_OFFSET 0x0040 /* Channel 1 Delay 0 Register */ +#define KINETIS_PDB_CH1DLY1_OFFSET 0x0044 /* Channel 1 Delay 1 Register */ + +#define KINETIS_PDB_INT_OFFSET(n) (0x0150+((n)<<3) /* DAC Interval n offset */ +#define KINETIS_PDB_DACINTC_OFFSET 0x0000 /* DAC Interval Trigger n Control Register */ +#define KINETIS_PDB_DACINT_OFFSET 0x0004 /* DAC Interval n Register */ + +#define KINETIS_PDB_DACINTC0_OFFSET 0x0150 /* DAC Interval Trigger 0 Control Register */ +#define KINETIS_PDB_DACINT0_OFFSET 0x0154 /* DAC Interval 0 Register */ + +#define KINETIS_PDB_DACINTC1_OFFSET 0x0158 /* DAC Interval Trigger 1 Control Register */ +#define KINETIS_PDB_DACINT1_OFFSET 0x015c /* DAC Interval 1 Register */ + +#define KINETIS_PDB_PO0EN_OFFSET 0x0190 /* Pulse-Out 0 Enable Register */ +#define KINETIS_PDB_PO0DLY_OFFSET 0x0194 /* Pulse-Out 0 Delay Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_PDB0_SC (KINETIS_PDB0_BASE+KINETIS_PDB_SC_OFFSET) +#define KINETIS_PDB0_MOD (KINETIS_PDB0_BASE+KINETIS_PDB_MOD_OFFSET) +#define KINETIS_PDB0_CNT (KINETIS_PDB0_BASE+KINETIS_PDB_CNT_OFFSET) +#define KINETIS_PDB0_IDLY (KINETIS_PDB0_BASE+KINETIS_PDB_IDLY_OFFSET) + +#define KINETIS_PDB0_CH_BASE(n) (KINETIS_PDB0_BASE+KINETIS_PDB_CH_OFFSET(n)) +#define KINETIS_PDB0_CHC1(n) (KINETIS_PDB_CH_BASE(n)+KINETIS_PDB_CHC1_OFFSET) +#define KINETIS_PDB0_CHS(n) (KINETIS_PDB_CH_BASE(n)+KINETIS_PDB_CHS_OFFSET) +#define KINETIS_PDB0_CHDLY0(n) (KINETIS_PDB_CH_BASE(n)+KINETIS_PDB_CHDLY0_OFFSET) +#define KINETIS_PDB0_CHDLY1(n) (KINETIS_PDB_CH_BASE(n)+KINETIS_PDB_CHDLY1_OFFSET) + +#define KINETIS_PDB0_CH0C1 (KINETIS_PDB0_BASE+KINETIS_PDB_CH0C1_OFFSET) +#define KINETIS_PDB0_CH0S (KINETIS_PDB0_BASE+KINETIS_PDB_CH0S_OFFSET) +#define KINETIS_PDB0_CH0DLY0 (KINETIS_PDB0_BASE+KINETIS_PDB_CH0DLY0_OFFSET) +#define KINETIS_PDB0_CH0DLY1 (KINETIS_PDB0_BASE+KINETIS_PDB_CH0DLY1_OFFSET) + +#define KINETIS_PDB0_CH1C1 (KINETIS_PDB0_BASE+KINETIS_PDB_CH1C1_OFFSET) +#define KINETIS_PDB0_CH1S (KINETIS_PDB0_BASE+KINETIS_PDB_CH1S_OFFSET) +#define KINETIS_PDB0_CH1DLY0 (KINETIS_PDB0_BASE+KINETIS_PDB_CH1DLY0_OFFSET) +#define KINETIS_PDB0_CH1DLY1 (KINETIS_PDB0_BASE+KINETIS_PDB_CH1DLY1_OFFSET) + +#define KINETIS_PDB0_INT_BASE(n) (KINETIS_PDB0_BASE+KINETIS_PDB_INT_OFFSET(n)) +#define KINETIS_PDB0_DACINTC(n) (KINETIS_PDB_INT_BASE(n)+KINETIS_PDB_DACINTC_OFFSET) +#define KINETIS_PDB0_DACINT(n) (KINETIS_PDB_INT_BASE(n)+KINETIS_PDB_DACINT_OFFSET) + +#define KINETIS_PDB0_DACINTC0 (KINETIS_PDB0_BASE+KINETIS_PDB_DACINTC0_OFFSET) +#define KINETIS_PDB0_DACINT0 (KINETIS_PDB0_BASE+KINETIS_PDB_DACINT0_OFFSET) + +#define KINETIS_PDB0_DACINTC1 (KINETIS_PDB0_BASE+KINETIS_PDB_DACINTC1_OFFSET) +#define KINETIS_PDB0_DACINT1 (KINETIS_PDB0_BASE+KINETIS_PDB_DACINT1_OFFSET) + +#define KINETIS_PDB0_PO0EN (KINETIS_PDB0_BASE+KINETIS_PDB_PO0EN_OFFSET) +#define KINETIS_PDB0_PO0DLY (KINETIS_PDB0_BASE+KINETIS_PDB_PO0DLY_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* Status and Control Register */ + +#define PDB_SC_LDOK (1 << 0) /* Bit 0: Load OK */ +#define PDB_SC_CONT (1 << 1) /* Bit 1: Continuous Mode Enable */ +#define PDB_SC_MULT_SHIFT (2) /* Bits 2-3: Multiplication Factor Select for Prescaler */ +#define PDB_SC_MULT_MASK (3 << PDB_SC_MULT_SHIFT) +# define PDB_SC_MULT_1 (0 << PDB_SC_MULT_SHIFT) +# define PDB_SC_MULT_10 (1 << PDB_SC_MULT_SHIFT) +# define PDB_SC_MULT_20 (2 << PDB_SC_MULT_SHIFT) +# define PDB_SC_MULT_40 (3 << PDB_SC_MULT_SHIFT) + /* Bit 4: Reserved */ +#define PDB_SC_PDBIE (1 << 5) /* Bit 5: PDB Interrupt Enable */ +#define PDB_SC_PDBIF (1 << 6) /* Bit 6: PDB Interrupt Flag */ +#define PDB_SC_PDBEN (1 << 7) /* Bit 7: PDB Enable */ +#define PDB_SC_TRGSEL_SHIFT (8) /* Bits 8-11: Trigger Input Source Select */ +#define PDB_SC_TRGSEL_MASK (15 << PDB_SC_TRGSEL_SHIFT) +# define PDB_SC_TRGSEL_TRGIN0 (0 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 0 */ +# define PDB_SC_TRGSEL_TRGIN1 (1 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 1 */ +# define PDB_SC_TRGSEL_TRGIN2 (2 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 2 */ +# define PDB_SC_TRGSEL_TRGIN3 (3 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 3 */ +# define PDB_SC_TRGSEL_TRGIN4 (4 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 4 */ +# define PDB_SC_TRGSEL_TRGIN5 (5 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 5 */ +# define PDB_SC_TRGSEL_TRGIN6 (6 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 6 */ +# define PDB_SC_TRGSEL_TRGIN7 (7 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 7 */ +# define PDB_SC_TRGSEL_TRGIN8 (8 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 8 */ +# define PDB_SC_TRGSEL_TRGIN9 (9 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 9 */ +# define PDB_SC_TRGSEL_TRGIN10 (10 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 0 */ +# define PDB_SC_TRGSEL_TRGIN11 (11 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 1 */ +# define PDB_SC_TRGSEL_TRGIN12 (12 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 2 */ +# define PDB_SC_TRGSEL_TRGIN13 (13 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 3 */ +# define PDB_SC_TRGSEL_TRGIN14 (14 << PDB_SC_TRGSEL_SHIFT) /* Trigger-In 4 */ +# define PDB_SC_TRGSEL_TRGSW (15 << PDB_SC_TRGSEL_SHIFT) /* Software trigger */ +#define PDB_SC_PRESCALER_SHIFT (12) /* Bits 12-14: Prescaler Divider Select */ +#define PDB_SC_PRESCALER_MASK (7 << PDB_SC_PRESCALER_SHIFT) +# define PDB_SC_PRESCALER_DIVM (0 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / MULT */ +# define PDB_SC_PRESCALER_DIV2M (1 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 2*MULT */ +# define PDB_SC_PRESCALER_DIV4M (2 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 4*MULT */ +# define PDB_SC_PRESCALER_DIV8M (3 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 8*MULT */ +# define PDB_SC_PRESCALER_DIV16M (4 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 16*MULT */ +# define PDB_SC_PRESCALER_DIV32M (5 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 32*MULT */ +# define PDB_SC_PRESCALER_DIV64M (6 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 64*MULT */ +# define PDB_SC_PRESCALER_DIV128M (7 << PDB_SC_PRESCALER_SHIFT) /* Peripheral clock / 128*MULT */ +#define PDB_SC_DMAEN (1 << 15) /* Bit 15: DMA Enable */ +#define PDB_SC_SWTRIG (1 << 16) /* Bit 16: Software Trigger */ +#define PDB_SC_PDBEIE (1 << 17) /* Bit 17: PDB Sequence Error Interrupt Enable */ +#define PDB_SC_LDMOD_SHIFT (18) /* Bits 18-19: Load Mode Select */ +#define PDB_SC_LDMOD_MASK (3 << PDB_SC_LDMOD_SHIFT) +# define PDB_SC_LDMOD_LDOK (0 << PDB_SC_LDMOD_SHIFT) /* Load after 1 written to LDOK */ +# define PDB_SC_LDMOD_PDBCNT (1 << PDB_SC_LDMOD_SHIFT) /* Load when the PDB counter = MOD */ +# define PDB_SC_LDMOD_TRIGGER (2 << PDB_SC_LDMOD_SHIFT) /* Load when trigger input event */ +# define PDB_SC_LDMOD_EITHER (3 << PDB_SC_LDMOD_SHIFT) /* Load when either occurs */ + /* Bits 20-31: Reserved */ +/* Modulus Register */ + + /* Bits 16-31: Reserved */ +#define PDB_MOD_MASK (0xffff) /* Bits 0-15: PDB Modulus */ + +/* Counter Register */ + + /* Bits 16-31: Reserved */ +#define PDB_CNT_MASK (0xffff) /* Bits 0-15: PDB Counter */ + +/* Interrupt Delay Register */ + + /* Bits 16-31: Reserved */ +#define PDB_IDLY_MASK (0xffff) /* Bits 0-15: PDB Interrupt Delay */ + +/* Channel n Control Register 1 */ + +#define PDB_CHC1_EN_SHIFT (0) /* Bits 0-7: Pre-Trigger Enable */ +#define PDB_CHC1_EN_MASK (0xff << PDB_CHC1_EN_SHIFT) +# define PDB_CHC1_EN_CHAN(n) ((1 << (n)) << PDB_CHC1_EN_SHIFT) +#define PDB_CHC1_TOS_SHIFT (8) /* Bits 8-15: Pre-Trigger Output Select */ +#define PDB_CHC1_TOS_MASK (0xff << PDB_CHC1_TOS_SHIFT) +# define PDB_CHC1_TOS_CHAN(n) ((1 << (n)) << PDB_CHC1_TOS_SHIFT) +#define PDB_CHC1_BB_SHIFT (16) /* Bits 16-23: Pre-Trigger Back-to-Back Operation Enable */ +#define PDB_CHC1_BB_MASK (0xff << PDB_CHC1_BB_SHIFT) +# define PDB_CHC1_BB_CHAN(n) ((1 << (n)) << PDB_CHC1_BB_SHIFT) + /* Bits 24-31: Reserved */ +/* Channel n Status Register */ + +#define PDB_CHS_ERR_SHIFT (0) /* Bits 0-7: PDB Channel Sequence Error Flags */ +#define PDB_CHS_ERR_MASK (0xff << PDB_CHS_ERR_SHIFT) +# define PDB_CHS1_ERR_CHAN(n) ((1 << (n)) << PDB_CHS_ERR_SHIFT) + /* Bits 8-15: Reserved */ +#define PDB_CHS_CF_SHIFT (16) /* Bits 16-23: PDB Channel Flags */ +#define PDB_CHS_CF_MASK (0xff << PDB_CHS_CF_SHIFT) +# define PDB_CHS_CF_CHAN(n) ((1 << (n)) << PDB_CHS_CF_SHIFT) + /* Bits 24-31: Reserved */ +/* Channel n Delay 0 Register */ + /* Bits 16-31: Reserved */ +#define PDB_CHDLY0_MASK (0xffff) /* Bits 0-15: PDB Channel Delay */ + +/* Channel n Delay 1 Register */ + /* Bits 16-31: Reserved */ +#define PDB_CHDLY1_MASK (0xffff) /* Bits 0-15: PDB Channel Delay */ + +/* DAC Interval Trigger n Control Register */ + +#define PDB_DACINTC_TOE (1 << 0) /* Bit 0: DAC Interval Trigger Enable */ +#define PDB_DACINTC_EXT (1 << 1) /* Bit 1: DAC External Trigger Input Enable */ + /* Bits 2-31: Reserved */ +/* DAC Interval n Register */ + /* Bits 16-31: Reserved */ +#define PDB_DACINT_MASK (0xffff) /* Bits 0-15: DAC Interval */ + +/* Pulse-Out 0 Enable Register */ +#define PDB__ + /* Bits 6-31: Reserved */ +#define PDB_PO0EN_MASK (0xff) /* Bits 0-7: PDB Pulse-Out Enable */ + +/* Pulse-Out 0 Delay Register */ + +#define PDB_PO0DLY_DLY1_SHIFT (16) /* Bits 16-31: PDB Pulse-Out Delay 1 */ +#define PDB_PO0DLY_DLY1_MASK (0xffff << PDB_PO0DLY_DLY1_SHIFT) +#define PDB_PO0DLY_DLY2_SHIFT (0) /* Bits 0-15: PDB Pulse-Out Delay 2 */ +#define PDB_PO0DLY_DLY2_MASK (0xffff << PDB_PO0DLY_DLY2_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H */ diff --git a/arch/arm/src/kinetis/kinetis_pin.c b/arch/arm/src/kinetis/kinetis_pin.c new file mode 100644 index 0000000000000000000000000000000000000000..851d0c9d9cf885a9eab330d5d06502dc10535183 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pin.c @@ -0,0 +1,262 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_pin.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kinetis_memorymap.h" +#include "kinetis.h" +#include "kinetis_port.h" +#include "kinetis_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_pinconfig + * + * Description: + * Configure a PIN based on bit-encoded description of the pin. NOTE that + * DMA/interrupts are disabled at the initial PIN configuratin. + * + ****************************************************************************/ + +int kinetis_pinconfig(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + unsigned int mode; + + /* Get the port number and pin number */ + + port = (cfgset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (cfgset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Get the port mode */ + + mode = (cfgset & _PIN_MODE_MASK) >> _PIN_MODE_SHIFT; + + /* Special case analog port mode. In this case, not of the digital + * options are applicable. + */ + + if (mode == PIN_MODE_ANALOG) + { + /* Set the analog mode with all digital options zeroed */ + + regval = PORT_PCR_MUX_ANALOG | PORT_PCR_IRQC_DISABLED; + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + } + else + { + /* Configure the digital pin options */ + + regval = (mode << PORT_PCR_MUX_SHIFT); + if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) + { + /* Handle input-only digital options */ + /* Check for pull-up or pull-down */ + + if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLDOWN) + { + regval |= PORT_PCR_PE; + } + else if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLUP) + { + regval |= (PORT_PCR_PE | PORT_PCR_PS); + } + } + else + { + /* Handle output-only digital options */ + /* Check for slow slew rate setting */ + + if ((cfgset & _PIN_OUTPUT_SLEW_MASK) == _PIN_OUTPUT_SLOW) + { + regval |= PORT_PCR_SRE; + } + + /* Check for open drain output */ + + if ((cfgset & _PIN_OUTPUT_OD_MASK) == _PIN_OUTPUT_OPENDRAIN) + { + regval |= PORT_PCR_ODE; + } + + /* Check for high drive output */ + + if ((cfgset & _PIN_OUTPUT_DRIVE_MASK) == _PIN_OUTPUT_HIGHDRIVE) + { + regval |= PORT_PCR_DSE; + } + } + + /* Check for passive filter enable. Passive Filter configuration + * is valid in all digital pin muxing modes. + */ + + if ((cfgset & PIN_PASV_FILTER) != 0) + { + regval |= PORT_PCR_PFE; + } + + /* Set the digital mode with all of the selected options */ + + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + + /* Check for digital filter enable. Digital Filter configuration + * is valid in all digital pin muxing modes. + */ + + regval = getreg32(base + KINETIS_PORT_DFER_OFFSET); + if ((cfgset & PIN_DIG_FILTER) != 0) + { + regval |= (1 << pin); + } + else + { + regval &= ~(1 << pin); + } + putreg32(regval, base + KINETIS_PORT_DFER_OFFSET); + + /* Additional configuration for the case of Alternative 1 (GPIO) modes */ + + if (mode == PIN_MODE_GPIO) + { + /* Set the GPIO port direction */ + + base = KINETIS_GPIO_BASE(port); + regval = getreg32(base + KINETIS_GPIO_PDDR_OFFSET); + if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) + { + /* Select GPIO input */ + + regval &= ~(1 << pin); + putreg32(regval, base + KINETIS_GPIO_PDDR_OFFSET); + } + else /* if ((cfgset & _PIN_IO_MASK) == _PIN_OUTPUT) */ + { + /* Select GPIO input */ + + regval |= (1 << pin); + putreg32(regval, base + KINETIS_GPIO_PDDR_OFFSET); + + /* Set the initial value of the GPIO output */ + + kinetis_gpiowrite(cfgset, ((cfgset & GPIO_OUTPUT_ONE) != 0)); + } + } + } + + return OK; + } + + return -EINVAL; +} + +/************************************************************************************ + * Name: kinetis_pinfilter + * + * Description: + * Configure the digital filter associated with a port. The digital filter + * capabilities of the PORT module are available in all digital pin muxing modes. + * + * Input parmeters: + * port - Port number. See KINETIS_PORTn definitions in kinetis_port.h + * lpo - true: Digital Filters are clocked by the bus clock + * false: Digital Filters are clocked by the 1 kHz LPO clock + * width - Filter Length + * + ************************************************************************************/ + +int kinetis_pinfilter(unsigned int port, bool lpo, unsigned int width) +{ + uintptr_t base; + uint32_t regval; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Select clocking */ + + regval = (lpo ? PORT_DFCR_CS : 0); + putreg32(regval, base + KINETIS_PORT_DFCR_OFFSET); + + /* Select the filter width */ + + DEBUGASSERT(width < 32); + putreg32(width, base + KINETIS_PORT_DFWR_OFFSET); + return OK; + } + return -EINVAL; +} diff --git a/arch/arm/src/kinetis/kinetis_pindma.c b/arch/arm/src/kinetis/kinetis_pindma.c new file mode 100644 index 0000000000000000000000000000000000000000..40acdc036b58b07092851a87d490e610257ee698 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pindma.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_pindma.c + * + * Copyright (C) 201, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include "up_internal.h" + +#ifdef CONFIG_KINETIS_DMA + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: kinetis_pindmaenable + * + * Description: + * Enable DMA for specified pin + * + ************************************************************************************/ + +void kinetis_pindmaenable(uint32_t pinset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Modify the IRQC field of the port PCR register in order to enable DMA. */ + + regval = getreg32(base + KINETIS_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + + switch (pinset & _PIN_INT_MASK) + { + case PIN_DMA_RISING : /* DMA Request on rising edge */ + regval |= PORT_PCR_IRQC_DMARISING; + break; + + case PIN_DMA_FALLING : /* DMA Request on falling edge */ + regval |= PORT_PCR_IRQC_DMAFALLING; + break; + + case PIN_DMA_BOTH : /* DMA Request on either edge */ + regval |= PORT_PCR_IRQC_DMABOTH; + break; + + default: + return; + } + + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + } +} + +/************************************************************************************ + * Name: kinetis_pindmadisable + * + * Description: + * Disable DMA for specified pin + * + ************************************************************************************/ + +void kinetis_pindmadisable(uint32_t pinset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Clear the IRQC field of the port PCR register in order to disable DMA. */ + + regval = getreg32(base + KINETIS_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + } +} + +#endif + diff --git a/arch/arm/src/kinetis/kinetis_pingpio.c b/arch/arm/src/kinetis/kinetis_pingpio.c new file mode 100644 index 0000000000000000000000000000000000000000..3663a92399f8c58e6523394970d5285912889ba0 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pingpio.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_pingpio.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kinetis_memorymap.h" +#include "kinetis.h" +#include "kinetis_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void kinetis_gpiowrite(uint32_t pinset, bool value) +{ + uintptr_t base; + unsigned int port; + unsigned int pin; + + DEBUGASSERT((pinset & _PIN_MODE_MASK) == _PIN_MODE_GPIO); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_OUTPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of GPIO block for this port */ + + base = KINETIS_GPIO_BASE(port); + + /* Set or clear the output */ + + if (value) + { + putreg32((1 << pin), base + KINETIS_GPIO_PSOR_OFFSET); + } + else + { + putreg32((1 << pin), base + KINETIS_GPIO_PCOR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: kinetis_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool kinetis_gpioread(uint32_t pinset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + bool ret = false; + + DEBUGASSERT((pinset & _PIN_MODE_MASK) == _PIN_MODE_GPIO); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of GPIO block for this port */ + + base = KINETIS_GPIO_BASE(port); + + /* return the state of the pin */ + + regval = getreg32(base + KINETIS_GPIO_PDIR_OFFSET); + ret = ((regval & (1 << pin)) != 0); + } + return ret; +} + diff --git a/arch/arm/src/kinetis/kinetis_pinirq.c b/arch/arm/src/kinetis/kinetis_pinirq.c new file mode 100644 index 0000000000000000000000000000000000000000..3c4da9d3c74b123e4b274fe11335b01c4d33a2c6 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pinirq.c @@ -0,0 +1,441 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_pinirq.c + * + * Copyright (C) 2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kinetis.h" +#include "kinetis_port.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The Kinetis port interrupt logic is very flexible and will program interrupts on + * most all pin events. In order to keep the memory usage to a minimum, the NuttX + * port supports enabling interrupts on a per-port basis. + */ + +#if defined (CONFIG_KINETIS_PORTAINTS) || defined (CONFIG_KINETIS_PORTBINTS) || \ + defined (CONFIG_KINETIS_PORTCINTS) || defined (CONFIG_KINETIS_PORTDINTS) || \ + defined (CONFIG_KINETIS_PORTEINTS) +# define HAVE_PORTINTS 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Per pin port interrupt vectors. NOTE: Not all pins in each port + * correspond to externally available GPIOs. However, I believe that the + * Kinesis will support interrupts even if the pin is not available as + * a GPIO. Hence, we need to support all 32 pins for each port. To keep the + * memory usage at a minimum, the logic may be configure per port. + */ + +#ifdef CONFIG_KINETIS_PORTAINTS +static xcpt_t g_portaisrs[32]; +#endif +#ifdef CONFIG_KINETIS_PORTBINTS +static xcpt_t g_portbisrs[32]; +#endif +#ifdef CONFIG_KINETIS_PORTCINTS +static xcpt_t g_portcisrs[32]; +#endif +#ifdef CONFIG_KINETIS_PORTDINTS +static xcpt_t g_portdisrs[32]; +#endif +#ifdef CONFIG_KINETIS_PORTEINTS +static xcpt_t g_porteisrs[32]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_portinterrupt + * + * Description: + * Common port interrupt handling. + * + ****************************************************************************/ + +#ifdef HAVE_PORTINTS +static int kinetis_portinterrupt(int irq, FAR void *context, + uintptr_t addr, xcpt_t *isrtab) +{ + uint32_t isfr = getreg32(addr); + int i; + + /* Examine each pin in the port */ + + for (i = 0; i < 32 && isfr != 0; i++) + { + /* A bit set in the ISR means that an interrupt is pending for this + * pin. If the pin is programmed for level sensitive inputs, then + * the interrupt handling logic MUST disable the interrupt (or cause + * the level to change) to prevent infinite interrupts. + */ + + uint32_t bit = (1 << i); + if ((isfr & bit) != 0) + { + /* I think that bits may be set in the ISFR for DMA activities + * well. So, no error is declared if there is no registered + * interrupt handler for the pin. + */ + + if (isrtab[i]) + { + /* There is a registered interrupt handler... invoke it */ + + (void)isrtab[i](irq, context); + } + + /* Writing a one to the ISFR register will clear the pending + * interrupt. If pin is configured to generate a DMA request + * then the ISFR bit will be cleared automatically at the + * completion of the requested DMA transfer. If configured for + * a level sensitive interrupt and the pin remains asserted and + * the bit will set again immediately after it is cleared. + */ + + isfr &= ~bit; + putreg32(bit, addr); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: kinetis_portXinterrupt + * + * Description: + * Handle interrupts arriving on individual ports + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_PORTAINTS +static int kinetis_portainterrupt(int irq, FAR void *context) +{ + return kinetis_portinterrupt(irq, context, KINETIS_PORTA_ISFR, g_portaisrs); +} +#endif +#ifdef CONFIG_KINETIS_PORTBINTS +static int kinetis_portbinterrupt(int irq, FAR void *context) +{ + return kinetis_portinterrupt(irq, context, KINETIS_PORTB_ISFR, g_portbisrs); +} +#endif +#ifdef CONFIG_KINETIS_PORTCINTS +static int kinetis_portcinterrupt(int irq, FAR void *context) +{ + return kinetis_portinterrupt(irq, context, KINETIS_PORTC_ISFR, g_portcisrs); +} +#endif +#ifdef CONFIG_KINETIS_PORTDINTS +static int kinetis_portdinterrupt(int irq, FAR void *context) +{ + return kinetis_portinterrupt(irq, context, KINETIS_PORTD_ISFR, g_portdisrs); +} +#endif +#ifdef CONFIG_KINETIS_PORTEINTS +static int kinetis_porteinterrupt(int irq, FAR void *context) +{ + return kinetis_portinterrupt(irq, context, KINETIS_PORTE_ISFR, g_porteisrs); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_pinirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void kinetis_pinirqinitialize(void) +{ +#ifdef CONFIG_KINETIS_PORTAINTS + (void)irq_attach(KINETIS_IRQ_PORTA, kinetis_portainterrupt); + putreg32(0xffffffff, KINETIS_PORTA_ISFR); + up_enable_irq(KINETIS_IRQ_PORTA); +#endif +#ifdef CONFIG_KINETIS_PORTBINTS + (void)irq_attach(KINETIS_IRQ_PORTB, kinetis_portbinterrupt); + putreg32(0xffffffff, KINETIS_PORTB_ISFR); + up_enable_irq(KINETIS_IRQ_PORTB); +#endif +#ifdef CONFIG_KINETIS_PORTCINTS + (void)irq_attach(KINETIS_IRQ_PORTC, kinetis_portcinterrupt); + putreg32(0xffffffff, KINETIS_PORTC_ISFR); + up_enable_irq(KINETIS_IRQ_PORTC); +#endif +#ifdef CONFIG_KINETIS_PORTDINTS + (void)irq_attach(KINETIS_IRQ_PORTD, kinetis_portdinterrupt); + putreg32(0xffffffff, KINETIS_PORTD_ISFR); + up_enable_irq(KINETIS_IRQ_PORTD); +#endif +#ifdef CONFIG_KINETIS_PORTEINTS + (void)irq_attach(KINETIS_IRQ_PORTE, kinetis_porteinterrupt); + putreg32(0xffffffff, KINETIS_PORTE_ISFR); + up_enable_irq(KINETIS_IRQ_PORTE); +#endif +} + +/**************************************************************************** + * Name: kinetis_pinirqattach + * + * Description: + * Attach a pin interrupt handler. The normal initalization sequence is: + * + * 1. Call kinetis_pinconfig() to configure the interrupting pin (pin interrupts + * will be disabled. + * 2. Call kinetis_pinirqattach() to attach the pin interrupt handling function. + * 3. Call kinetis_pinirqenable() to enable interrupts on the pin. + * + * Parameters: + * - pinset: Pin configuration + * - pinisr: Pin interrupt service routine + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler whe + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t kinetis_pinirqattach(uint32_t pinset, xcpt_t pinisr) +{ +#ifdef HAVE_PORTINTS + xcpt_t *isrtab; + xcpt_t oldisr; + irqstate_t flags; + unsigned int port; + unsigned int pin; + + /* It only makes sense to call this function for input pins that are configured + * as interrupts. + */ + + DEBUGASSERT((pinset & _PIN_INTDMA_MASK) == _PIN_INTERRUPT); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + /* Get the table associated with this port */ + + DEBUGASSERT(port < KINETIS_NPORTS); + flags = enter_critical_section(); + switch (port) + { +#ifdef CONFIG_KINETIS_PORTAINTS + case KINETIS_PORTA : + isrtab = g_portaisrs; + break; +#endif +#ifdef CONFIG_KINETIS_PORTBINTS + case KINETIS_PORTB : + isrtab = g_portbisrs; + break; +#endif +#ifdef CONFIG_KINETIS_PORTCINTS + case KINETIS_PORTC : + isrtab = g_portcisrs; + break; +#endif +#ifdef CONFIG_KINETIS_PORTDINTS + case KINETIS_PORTD : + isrtab = g_portdisrs; + break; +#endif +#ifdef CONFIG_KINETIS_PORTEINTS + case KINETIS_PORTE : + isrtab = g_porteisrs; + break; +#endif + default: + leave_critical_section(flags); + return NULL; + } + + /* Get the old PIN ISR and set the new PIN ISR */ + + oldisr = isrtab[pin]; + isrtab[pin] = pinisr; + + /* And return the old PIN isr address */ + + leave_critical_section(flags); + return oldisr; +#else + return NULL; +#endif /* HAVE_PORTINTS */ +} + +/************************************************************************************ + * Name: kinetis_pinirqenable + * + * Description: + * Enable the interrupt for specified pin IRQ + * + ************************************************************************************/ + +void kinetis_pinirqenable(uint32_t pinset) +{ +#ifdef HAVE_PORTINTS + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Modify the IRQC field of the port PCR register in order to enable + * the interrupt. + */ + + regval = getreg32(base + KINETIS_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + + switch (pinset & _PIN_INT_MASK) + { + case PIN_INT_ZERO : /* Interrupt when logic zero */ + regval |= PORT_PCR_IRQC_ZERO; + break; + + case PIN_INT_RISING : /* Interrupt on rising edge */ + regval |= PORT_PCR_IRQC_RISING; + break; + + case PIN_INT_BOTH : /* Interrupt on falling edge */ + regval |= PORT_PCR_IRQC_FALLING; + break; + + case PIN_DMA_FALLING : /* nterrupt on either edge */ + regval |= PORT_PCR_IRQC_BOTH; + break; + + case PIN_INT_ONE : /* IInterrupt when logic one */ + regval |= PORT_PCR_IRQC_ONE; + break; + + default: + return; + } + + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + } +#endif /* HAVE_PORTINTS */ +} + +/************************************************************************************ + * Name: kinetis_pinirqdisable + * + * Description: + * Disable the interrupt for specified pin + * + ************************************************************************************/ + +void kinetis_pinirqdisable(uint32_t pinset) +{ +#ifdef HAVE_PORTINTS + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KINETIS_NPORTS); + if (port < KINETIS_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KINETIS_PORT_BASE(port); + + /* Clear the IRQC field of the port PCR register in order to disable + * the interrupt. + */ + + regval = getreg32(base + KINETIS_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + putreg32(regval, base + KINETIS_PORT_PCR_OFFSET(pin)); + } +#endif /* HAVE_PORTINTS */ +} +#endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/arm/src/kinetis/kinetis_pinmux.h b/arch/arm/src/kinetis/kinetis_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..589184ffdd2ceb507fa865da22fd9f0b37d54bb0 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pinmux.h @@ -0,0 +1,77 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_pinmux.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/* This file is just a wrapper around pin muxing header files for the Kinetis family selected + * by the logic in chip.h. + */ + +#if defined(KINETIS_K20) +# include "kinetis_k20pinmux.h" +#elif defined(KINETIS_K40) +# include "kinetis_k40pinmux.h" +#elif defined(KINETIS_K60) +# include "kinetis_k60pinmux.h" +#else +# error "No pin multiplexing for this Kinetis part" +#endif + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H */ diff --git a/arch/arm/src/kinetis/kinetis_pit.h b/arch/arm/src/kinetis/kinetis_pit.h new file mode 100644 index 0000000000000000000000000000000000000000..808508f8fedd17be9e6af540338c248095be02fc --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pit.h @@ -0,0 +1,124 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_pit.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_PIT_MCR_OFFSET 0x0000 /* PIT Module Control Register */ +#define KINETIS_PIT_LDVAL0_OFFSET 0x0100 /* Timer Load Value Register */ +#define KINETIS_PIT_CVAL0_OFFSET 0x0104 /* Current Timer Value Register */ +#define KINETIS_PIT_TCTRL0_OFFSET 0x0108 /* Timer Control Register */ +#define KINETIS_PIT_TFLG0_OFFSET 0x010c /* Timer Flag Register */ +#define KINETIS_PIT_LDVAL1_OFFSET 0x0110 /* Timer Load Value Register */ +#define KINETIS_PIT_CVAL1_OFFSET 0x0114 /* Current Timer Value Register */ +#define KINETIS_PIT_TCTRL1_OFFSET 0x0118 /* Timer Control Register */ +#define KINETIS_PIT_TFLG1_OFFSET 0x011c /* Timer Flag Register */ +#define KINETIS_PIT_LDVAL2_OFFSET 0x0120 /* Timer Load Value Register */ +#define KINETIS_PIT_CVAL2_OFFSET 0x0124 /* Current Timer Value Register */ +#define KINETIS_PIT_TCTRL2_OFFSET 0x0128 /* Timer Control Register */ +#define KINETIS_PIT_TFLG2_OFFSET 0x012c /* Timer Flag Register */ +#define KINETIS_PIT_LDVAL3_OFFSET 0x0130 /* Timer Load Value Register */ +#define KINETIS_PIT_CVAL3_OFFSET 0x0134 /* Current Timer Value Register */ +#define KINETIS_PIT_TCTRL3_OFFSET 0x0138 /* Timer Control Register */ +#define KINETIS_PIT_TFLG3_OFFSET 0x013c /* Timer Flag Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_PIT_MCR (KINETIS_PIT_BASE+KINETIS_PIT_MCR_OFFSET) +#define KINETIS_PIT_LDVAL0 (KINETIS_PIT_BASE+KINETIS_PIT_LDVAL0_OFFSET) +#define KINETIS_PIT_CVAL0 (KINETIS_PIT_BASE+KINETIS_PIT_CVAL0_OFFSET) +#define KINETIS_PIT_TCTRL0 (KINETIS_PIT_BASE+KINETIS_PIT_TCTRL0_OFFSET) +#define KINETIS_PIT_TFLG0 (KINETIS_PIT_BASE+KINETIS_PIT_TFLG0_OFFSET) +#define KINETIS_PIT_LDVAL1 (KINETIS_PIT_BASE+KINETIS_PIT_LDVAL1_OFFSET) +#define KINETIS_PIT_CVAL1 (KINETIS_PIT_BASE+KINETIS_PIT_CVAL1_OFFSET) +#define KINETIS_PIT_TCTRL1 (KINETIS_PIT_BASE+KINETIS_PIT_TCTRL1_OFFSET) +#define KINETIS_PIT_TFLG1 (KINETIS_PIT_BASE+KINETIS_PIT_TFLG1_OFFSET) +#define KINETIS_PIT_LDVAL2 (KINETIS_PIT_BASE+KINETIS_PIT_LDVAL2_OFFSET) +#define KINETIS_PIT_CVAL2 (KINETIS_PIT_BASE+KINETIS_PIT_CVAL2_OFFSET) +#define KINETIS_PIT_TCTRL2 (KINETIS_PIT_BASE+KINETIS_PIT_TCTRL2_OFFSET) +#define KINETIS_PIT_TFLG2 (KINETIS_PIT_BASE+KINETIS_PIT_TFLG2_OFFSET) +#define KINETIS_PIT_LDVAL3 (KINETIS_PIT_BASE+KINETIS_PIT_LDVAL3_OFFSET) +#define KINETIS_PIT_CVAL3 (KINETIS_PIT_BASE+KINETIS_PIT_CVAL3_OFFSET) +#define KINETIS_PIT_TCTRL3 (KINETIS_PIT_BASE+KINETIS_PIT_TCTRL3_OFFSET) +#define KINETIS_PIT_TFLG3 (KINETIS_PIT_BASE+KINETIS_PIT_TFLG3_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* PIT Module Control Register */ + +#define PIT_MCR_FRZ (1 << 0) /* Bit 0: Freeze */ +#define PIT_MCR_MDIS (1 << 1) /* Bit 1: Module Disable */ + /* Bits 2-31: Reserved */ + +/* Timer Load Value Register (32-bit Timer Start Value Bits) */ +/* Current Timer Value Register (32-bit Current Timer Value) */ + +/* Timer Control Register */ + +#define PIT_TCTRL_TEN (1 << 0) /* Bit 0: Timer Enable Bit */ +#define PIT_TCTRL_TIE (1 << 1) /* Bit 1: Timer Interrupt Enable Bit */ + /* Bits 2-31: Reserved */ +/* Timer Flag Register */ + +#define PIT_TFLG_TIF (1 << 0) /* Bit 0: Timer Interrupt Flag */ + /* Bits 1-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H */ diff --git a/arch/arm/src/kinetis/kinetis_pmc.h b/arch/arm/src/kinetis/kinetis_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..065847da3d5a6f5bc702e8f7f44b8b1d7273ccad --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_pmc.h @@ -0,0 +1,111 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_pmc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_PMC_LVDSC1_OFFSET 0x0000 /* Low Voltage Detect Status and Control 1 Register */ +#define KINETIS_PMC_LVDSC2_OFFSET 0x0001 /* Low Voltage Detect Status and Control 2 Register */ +#define KINETIS_PMC_REGSC_OFFSET 0x0002 /* Regulator Status and Control Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_PMC_LVDSC1 (KINETIS_PMC_BASE+KINETIS_PMC_LVDSC1_OFFSET) +#define KINETIS_PMC_LVDSC2 (KINETIS_PMC_BASE+KINETIS_PMC_LVDSC2_OFFSET) +#define KINETIS_PMC_REGSC (KINETIS_PMC_BASE+KINETIS_PMC_REGSC_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Low Voltage Detect Status and Control 1 Register */ + +#define PMC_LVDSC1_LVDV_SHIFT (0) /* Bits 0-1: Low-Voltage Detect Voltage Select */ +#define PMC_LVDSC1_LVDV_MASK (3 << PMC_LVDSC1_LVDV_SHIFT) +# define PMC_LVDSC1_LVDV_LOW (0 << PMC_LVDSC1_LVDV_SHIFT) /* Low trip point selected (VLVD = VLVDL) */ +# define PMC_LVDSC1_LVDV_HIGH (1 << PMC_LVDSC1_LVDV_SHIFT) /* High trip point selected (VLVD = VLVDH) */ + /* Bits 2-3: Reserved */ +#define PMC_LVDSC1_LVDRE (1 << 4) /* Bit 4: Low-Voltage Detect Reset Enable */ +#define PMC_LVDSC1_LVDIE (1 << 5) /* Bit 5: Low-Voltage Detect Interrupt Enable */ +#define PMC_LVDSC1_LVDACK (1 << 6) /* Bit 6: Low-Voltage Detect Acknowledge */ +#define PMC_LVDSC1_LVDF (1 << 7) /* Bit 7: Low-Voltage Detect Flag */ + +/* Low Voltage Detect Status and Control 2 Register */ + +#define PMC_LVDSC2_LVWV_SHIFT (0) /* Bits 0-1: Low-Voltage Warning Voltage Select */ +#define PMC_LVDSC2_LVWV_MASK (3 << PMC_LVDSC2_LVWV_SHIFT) +# define PMC_LVDSC2_LVWV_ LOW (0 << PMC_LVDSC2_LVWV_SHIFT) /* Low trip point selected (VLVW = VLVW1H/L) */ +# define PMC_LVDSC2_LVWV_ MID1 (1 << PMC_LVDSC2_LVWV_SHIFT) /* Mid 1 trip point selected (VLVW = VLVW2H/L) */ +# define PMC_LVDSC2_LVWV_ MID2 (2 << PMC_LVDSC2_LVWV_SHIFT) /* Mid 2 trip point selected (VLVW = VLVW3H/L) */ +# define PMC_LVDSC2_LVWV_ HIGH (3 << PMC_LVDSC2_LVWV_SHIFT) /* High trip point selected (VLVW = VLVW4H/L) */ + /* Bits 2-4: Reserved */ +#define PMC_LVDSC2_LVWIE (1 << 5) /* Bit 5: Low-Voltage Warning Interrupt Enable */ +#define PMC_LVDSC2_LVWACK (1 << 6) /* Bit 6: Low-Voltage Warning Acknowledge */ +#define PMC_LVDSC2_LVWF (1 << 7) /* Bit 7: Low-Voltage Warning Flag */ + +/* Regulator Status and Control Register */ + +#define PMC_REGSC_BGBE (1 << 0) /* Bit 0: Bandgap Buffer Enable */ + /* Bit 1: Reserved */ +#define PMC_REGSC_REGONS (1 << 2) /* Bit 2: Regulator in Run Regulation Status */ +#define PMC_REGSC_VLPRS (1 << 3) /* Bit 3: Very Low Power Run Status */ +#define PMC_REGSC_TRAMPO (1 << 4) /* Bit 4: For devices with FlexNVM: Traditional RAM Power Option */ + /* Bits 5-7: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H */ diff --git a/arch/arm/src/kinetis/kinetis_port.h b/arch/arm/src/kinetis/kinetis_port.h new file mode 100644 index 0000000000000000000000000000000000000000..5a568537b01ed8845c61eaa891734226a191ca2d --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_port.h @@ -0,0 +1,429 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_port.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* General Definitions **************************************************************/ + +#define KINETIS_PORTA (0) +#define KINETIS_PORTB (1) +#define KINETIS_PORTC (2) +#define KINETIS_PORTD (3) +#define KINETIS_PORTE (4) +#define KINETIS_NPORTS (5) + +/* Register Offsets *****************************************************************/ + +#define KINETIS_PORT_PCR_OFFSET(n) ((n) << 2) /* Pin Control Register n, n=0..31 */ +#define KINETIS_PORT_PCR0_OFFSET 0x0000 /* Pin Control Register 0 */ +#define KINETIS_PORT_PCR1_OFFSET 0x0004 /* Pin Control Register 1 */ +#define KINETIS_PORT_PCR2_OFFSET 0x0008 /* Pin Control Register 2 */ +#define KINETIS_PORT_PCR3_OFFSET 0x000C /* Pin Control Register 3 */ +#define KINETIS_PORT_PCR4_OFFSET 0x0010 /* Pin Control Register 4 */ +#define KINETIS_PORT_PCR5_OFFSET 0x0014 /* Pin Control Register 5 */ +#define KINETIS_PORT_PCR6_OFFSET 0x0018 /* Pin Control Register 6 */ +#define KINETIS_PORT_PCR7_OFFSET 0x001c /* Pin Control Register 7 */ +#define KINETIS_PORT_PCR8_OFFSET 0x0020 /* Pin Control Register 8 */ +#define KINETIS_PORT_PCR9_OFFSET 0x0024 /* Pin Control Register 9 */ +#define KINETIS_PORT_PCR10_OFFSET 0x0028 /* Pin Control Register 10 */ +#define KINETIS_PORT_PCR11_OFFSET 0x002c /* Pin Control Register 11 */ +#define KINETIS_PORT_PCR12_OFFSET 0x0030 /* Pin Control Register 12 */ +#define KINETIS_PORT_PCR13_OFFSET 0x0034 /* Pin Control Register 13 */ +#define KINETIS_PORT_PCR14_OFFSET 0x0038 /* Pin Control Register 14 */ +#define KINETIS_PORT_PCR15_OFFSET 0x003c /* Pin Control Register 15 */ +#define KINETIS_PORT_PCR16_OFFSET 0x0040 /* Pin Control Register 16 */ +#define KINETIS_PORT_PCR17_OFFSET 0x0044 /* Pin Control Register 17 */ +#define KINETIS_PORT_PCR18_OFFSET 0x0048 /* Pin Control Register 18 */ +#define KINETIS_PORT_PCR19_OFFSET 0x004c /* Pin Control Register 19 */ +#define KINETIS_PORT_PCR20_OFFSET 0x0050 /* Pin Control Register 20 */ +#define KINETIS_PORT_PCR21_OFFSET 0x0054 /* Pin Control Register 21 */ +#define KINETIS_PORT_PCR22_OFFSET 0x0058 /* Pin Control Register 22 */ +#define KINETIS_PORT_PCR23_OFFSET 0x005c /* Pin Control Register 23 */ +#define KINETIS_PORT_PCR24_OFFSET 0x0060 /* Pin Control Register 24 */ +#define KINETIS_PORT_PCR25_OFFSET 0x0064 /* Pin Control Register 25 */ +#define KINETIS_PORT_PCR26_OFFSET 0x0068 /* Pin Control Register 26 */ +#define KINETIS_PORT_PCR27_OFFSET 0x006c /* Pin Control Register 27 */ +#define KINETIS_PORT_PCR28_OFFSET 0x0070 /* Pin Control Register 28 */ +#define KINETIS_PORT_PCR29_OFFSET 0x0074 /* Pin Control Register 29 */ +#define KINETIS_PORT_PCR30_OFFSET 0x0078 /* Pin Control Register 30 */ +#define KINETIS_PORT_PCR31_OFFSET 0x007c /* Pin Control Register 31 */ +#define KINETIS_PORT_GPCLR_OFFSET 0x0080 /* Global Pin Control Low Register */ +#define KINETIS_PORT_GPCHR_OFFSET 0x0084 /* Global Pin Control High Register */ +#define KINETIS_PORT_ISFR_OFFSET 0x00a0 /* Interrupt Status Flag Register */ +#define KINETIS_PORT_DFER_OFFSET 0x00c0 /* Digital Filter Enable Register */ +#define KINETIS_PORT_DFCR_OFFSET 0x00c4 /* Digital Filter Clock Register */ +#define KINETIS_PORT_DFWR_OFFSET 0x00c8 /* Digital Filter Width Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_PORT_PCR(p,n) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORT_PCR0(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORT_PCR1(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORT_PCR2(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORT_PCR3(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORT_PCR4(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORT_PCR5(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORT_PCR6(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORT_PCR7(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORT_PCR8(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORT_PCR9(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORT_PCR10(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORT_PCR11(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORT_PCR12(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORT_PCR13(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORT_PCR14(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORT_PCR15(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORT_PCR16(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORT_PCR17(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORT_PCR18(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORT_PCR19(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORT_PCR20(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORT_PCR21(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORT_PCR22(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORT_PCR23(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORT_PCR24(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORT_PCR25(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORT_PCR26(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORT_PCR27(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORT_PCR28(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORT_PCR29(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORT_PCR30(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORT_PCR31(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORT_GPCLR(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORT_GPCHR(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORT_ISFR(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORT_DFER(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORT_DFCR(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORT_DFWR(p) (KINETIS_PORT_BASE(p)+KINETIS_PORT_DFWR_OFFSET) + +#define KINETIS_PORTA_PCR(n) (KINETIS_PORTA_BASE+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORTA_PCR0 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORTA_PCR1 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORTA_PCR2 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORTA_PCR3 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORTA_PCR4 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORTA_PCR5 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORTA_PCR6 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORTA_PCR7 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORTA_PCR8 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORTA_PCR9 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORTA_PCR10 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORTA_PCR11 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORTA_PCR12 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORTA_PCR13 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORTA_PCR14 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORTA_PCR15 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORTA_PCR16 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORTA_PCR17 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORTA_PCR18 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORTA_PCR19 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORTA_PCR20 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORTA_PCR21 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORTA_PCR22 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORTA_PCR23 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORTA_PCR24 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORTA_PCR25 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORTA_PCR26 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORTA_PCR27 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORTA_PCR28 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORTA_PCR29 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORTA_PCR30 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORTA_PCR31 (KINETIS_PORTA_BASE+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORTA_GPCLR (KINETIS_PORTA_BASE+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORTA_GPCHR (KINETIS_PORTA_BASE+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORTA_ISFR (KINETIS_PORTA_BASE+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORTA_DFER (KINETIS_PORTA_BASE+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORTA_DFCR (KINETIS_PORTA_BASE+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORTA_DFWR (KINETIS_PORTA_BASE+KINETIS_PORT_DFWR_OFFSET) + +#define KINETIS_PORTB_PCR(n) (KINETIS_PORTB_BASE+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORTB_PCR0 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORTB_PCR1 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORTB_PCR2 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORTB_PCR3 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORTB_PCR4 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORTB_PCR5 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORTB_PCR6 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORTB_PCR7 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORTB_PCR8 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORTB_PCR9 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORTB_PCR10 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORTB_PCR11 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORTB_PCR12 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORTB_PCR13 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORTB_PCR14 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORTB_PCR15 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORTB_PCR16 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORTB_PCR17 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORTB_PCR18 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORTB_PCR19 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORTB_PCR20 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORTB_PCR21 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORTB_PCR22 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORTB_PCR23 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORTB_PCR24 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORTB_PCR25 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORTB_PCR26 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORTB_PCR27 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORTB_PCR28 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORTB_PCR29 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORTB_PCR30 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORTB_PCR31 (KINETIS_PORTB_BASE+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORTB_GPCLR (KINETIS_PORTB_BASE+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORTB_GPCHR (KINETIS_PORTB_BASE+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORTB_ISFR (KINETIS_PORTB_BASE+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORTB_DFER (KINETIS_PORTB_BASE+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORTB_DFCR (KINETIS_PORTB_BASE+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORTB_DFWR (KINETIS_PORTB_BASE+KINETIS_PORT_DFWR_OFFSET) + +#define KINETIS_PORTC_PCR(n) (KINETIS_PORTC_BASE+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORTC_PCR0 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORTC_PCR1 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORTC_PCR2 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORTC_PCR3 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORTC_PCR4 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORTC_PCR5 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORTC_PCR6 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORTC_PCR7 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORTC_PCR8 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORTC_PCR9 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORTC_PCR10 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORTC_PCR11 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORTC_PCR12 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORTC_PCR13 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORTC_PCR14 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORTC_PCR15 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORTC_PCR16 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORTC_PCR17 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORTC_PCR18 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORTC_PCR19 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORTC_PCR20 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORTC_PCR21 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORTC_PCR22 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORTC_PCR23 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORTC_PCR24 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORTC_PCR25 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORTC_PCR26 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORTC_PCR27 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORTC_PCR28 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORTC_PCR29 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORTC_PCR30 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORTC_PCR31 (KINETIS_PORTC_BASE+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORTC_GPCLR (KINETIS_PORTC_BASE+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORTC_GPCHR (KINETIS_PORTC_BASE+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORTC_ISFR (KINETIS_PORTC_BASE+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORTC_DFER (KINETIS_PORTC_BASE+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORTC_DFCR (KINETIS_PORTC_BASE+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORTC_DFWR (KINETIS_PORTC_BASE+KINETIS_PORT_DFWR_OFFSET) + +#define KINETIS_PORTD_PCR(n) (KINETIS_PORTD_BASE+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORTD_PCR0 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORTD_PCR1 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORTD_PCR2 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORTD_PCR3 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORTD_PCR4 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORTD_PCR5 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORTD_PCR6 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORTD_PCR7 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORTD_PCR8 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORTD_PCR9 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORTD_PCR10 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORTD_PCR11 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORTD_PCR12 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORTD_PCR13 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORTD_PCR14 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORTD_PCR15 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORTD_PCR16 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORTD_PCR17 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORTD_PCR18 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORTD_PCR19 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORTD_PCR20 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORTD_PCR21 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORTD_PCR22 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORTD_PCR23 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORTD_PCR24 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORTD_PCR25 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORTD_PCR26 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORTD_PCR27 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORTD_PCR28 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORTD_PCR29 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORTD_PCR30 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORTD_PCR31 (KINETIS_PORTD_BASE+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORTD_GPCLR (KINETIS_PORTD_BASE+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORTD_GPCHR (KINETIS_PORTD_BASE+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORTD_ISFR (KINETIS_PORTD_BASE+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORTD_DFER (KINETIS_PORTD_BASE+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORTD_DFCR (KINETIS_PORTD_BASE+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORTD_DFWR (KINETIS_PORTD_BASE+KINETIS_PORT_DFWR_OFFSET) + +#define KINETIS_PORTE_PCR(n) (KINETIS_PORTE_BASE+KINETIS_PORT_PCR_OFFSET(n) +#define KINETIS_PORTE_PCR0 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR0_OFFSET) +#define KINETIS_PORTE_PCR1 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR1_OFFSET) +#define KINETIS_PORTE_PCR2 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR2_OFFSET) +#define KINETIS_PORTE_PCR3 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR3_OFFSET) +#define KINETIS_PORTE_PCR4 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR4_OFFSET) +#define KINETIS_PORTE_PCR5 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR5_OFFSET) +#define KINETIS_PORTE_PCR6 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR6_OFFSET) +#define KINETIS_PORTE_PCR7 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR7_OFFSET) +#define KINETIS_PORTE_PCR8 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR8_OFFSET) +#define KINETIS_PORTE_PCR9 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR9_OFFSET) +#define KINETIS_PORTE_PCR10 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR10_OFFSET) +#define KINETIS_PORTE_PCR11 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR11_OFFSET) +#define KINETIS_PORTE_PCR12 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR12_OFFSET) +#define KINETIS_PORTE_PCR13 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR13_OFFSET) +#define KINETIS_PORTE_PCR14 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR14_OFFSET) +#define KINETIS_PORTE_PCR15 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR15_OFFSET) +#define KINETIS_PORTE_PCR16 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR16_OFFSET) +#define KINETIS_PORTE_PCR17 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR17_OFFSET) +#define KINETIS_PORTE_PCR18 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR18_OFFSET) +#define KINETIS_PORTE_PCR19 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR19_OFFSET) +#define KINETIS_PORTE_PCR20 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR20_OFFSET) +#define KINETIS_PORTE_PCR21 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR21_OFFSET) +#define KINETIS_PORTE_PCR22 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR22_OFFSET) +#define KINETIS_PORTE_PCR23 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR23_OFFSET) +#define KINETIS_PORTE_PCR24 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR24_OFFSET) +#define KINETIS_PORTE_PCR25 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR25_OFFSET) +#define KINETIS_PORTE_PCR26 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR26_OFFSET) +#define KINETIS_PORTE_PCR27 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR27_OFFSET) +#define KINETIS_PORTE_PCR28 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR28_OFFSET) +#define KINETIS_PORTE_PCR29 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR29_OFFSET) +#define KINETIS_PORTE_PCR30 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR30_OFFSET) +#define KINETIS_PORTE_PCR31 (KINETIS_PORTE_BASE+KINETIS_PORT_PCR31_OFFSET) +#define KINETIS_PORTE_GPCLR (KINETIS_PORTE_BASE+KINETIS_PORT_GPCLR_OFFSET) +#define KINETIS_PORTE_GPCHR (KINETIS_PORTE_BASE+KINETIS_PORT_GPCHR_OFFSET) +#define KINETIS_PORTE_ISFR (KINETIS_PORTE_BASE+KINETIS_PORT_ISFR_OFFSET) +#define KINETIS_PORTE_DFER (KINETIS_PORTE_BASE+KINETIS_PORT_DFER_OFFSET) +#define KINETIS_PORTE_DFCR (KINETIS_PORTE_BASE+KINETIS_PORT_DFCR_OFFSET) +#define KINETIS_PORTE_DFWR (KINETIS_PORTE_BASE+KINETIS_PORT_DFWR_OFFSET) + +/* Register Bit Definitions *********************************************************/ +/* Pin Control Register n, n=0..31 */ + +#define PORT_PCR_PS (1 << 0) /* Bit 0: Pull Select */ +#define PORT_PCR_PE (1 << 1) /* Bit 1: Pull Enable */ +#define PORT_PCR_SRE (1 << 2) /* Bit 2: Slew Rate Enable */ + /* Bit 3: Reserved */ +#define PORT_PCR_PFE (1 << 4) /* Bit 4: Passive Filter Enable */ +#define PORT_PCR_ODE (1 << 5) /* Bit 5: Open Drain Enable */ +#define PORT_PCR_DSE (1 << 6) /* Bit 6: Drive Strength Enable */ + /* Bit 7: Reserved */ +#define PORT_PCR_MUX_SHIFT (8) /* Bits 8-10: Pin Mux Control */ +#define PORT_PCR_MUX_MASK (7 << PORT_PCR_MUX_SHIFT) +# define PORT_PCR_MUX_ANALOG (0 << PORT_PCR_MUX_SHIFT) /* Pin Disabled (Analog) */ +# define PORT_PCR_MUX_GPIO (1 << PORT_PCR_MUX_SHIFT) /* Alternative 1 (GPIO) */ +# define PORT_PCR_MUX_ALT1 (1 << PORT_PCR_MUX_SHIFT) /* Alternative 1 (GPIO) */ +# define PORT_PCR_MUX_ALT2 (2 << PORT_PCR_MUX_SHIFT) /* Alternative 2 (chip specific) */ +# define PORT_PCR_MUX_ALT3 (3 << PORT_PCR_MUX_SHIFT) /* Alternative 3 (chip specific) */ +# define PORT_PCR_MUX_ALT4 (4 << PORT_PCR_MUX_SHIFT) /* Alternative 4 (chip specific) */ +# define PORT_PCR_MUX_ALT5 (5 << PORT_PCR_MUX_SHIFT) /* Alternative 5 (chip specific) */ +# define PORT_PCR_MUX_ALT6 (6 << PORT_PCR_MUX_SHIFT) /* Alternative 6 (chip specific) */ +# define PORT_PCR_MUX_ALT7 (7 << PORT_PCR_MUX_SHIFT) /* Alternative 7 (chip specific / JTAG / NMI) */ + /* Bits 11-14: Reserved */ +#define PORT_PCR_LK (1 << 15) /* Bit 15: Lock Register */ +#define PORT_PCR_IRQC_SHIFT (16) /* Bits 16-19: Interrupt Configuration */ +#define PORT_PCR_IRQC_MASK (15 << PORT_PCR_IRQC_SHIFT) +# define PORT_PCR_IRQC_DISABLED (0 << PORT_PCR_IRQC_SHIFT) /* Interrupt/DMA Request disabled */ +# define PORT_PCR_IRQC_DMARISING (1 << PORT_PCR_IRQC_SHIFT) /* DMA Request on rising edge */ +# define PORT_PCR_IRQC_DMAFALLING (2 << PORT_PCR_IRQC_SHIFT) /* DMA Request on falling edge */ +# define PORT_PCR_IRQC_DMABOTH (3 << PORT_PCR_IRQC_SHIFT) /* DMA Request on either edge */ +# define PORT_PCR_IRQC_ZERO (8 << PORT_PCR_IRQC_SHIFT) /* Interrupt when logic zero */ +# define PORT_PCR_IRQC_RISING (9 << PORT_PCR_IRQC_SHIFT) /* Interrupt on rising edge */ +# define PORT_PCR_IRQC_FALLING (10 << PORT_PCR_IRQC_SHIFT) /* Interrupt on falling edge */ +# define PORT_PCR_IRQC_BOTH (11 << PORT_PCR_IRQC_SHIFT) /* Interrupt on either edge */ +# define PORT_PCR_IRQC_ONE (12 << PORT_PCR_IRQC_SHIFT) /* Interrupt when logic one */ + /* Bits 20-23: Reserved */ +#define PORT_PCR_ISF (1 << 24) /* Bit 24: Interrupt Status Flag */ + /* Bits 25-31: Reserved */ + +/* Global Pin Control Low Register */ + +#define PORT_GPCLR_GPWD_SHIFT (0) /* Bits 0-15: Global Pin Write Data */ +#define PORT_GPCLR_GPWD_MASK (0xffff << PORT_GPCLR_GPWD_SHIFT) +# define PORT_GPCLR_GPWD(n) ((1 << (n)) << PORT_GPCLR_GPWD_SHIFT) +#define PORT_GPCLR_GPWE_SHIFT (16) /* Bits 16-31: Global Pin Write Enable */ +#define PORT_GPCLR_GPWE_MASK (0xffff << PORT_GPCLR_GPWE_SHIFT) +# define PORT_GPCLR_GPWE(n) ((1 << (n)) << PORT_GPCLR_GPWE_SHIFT) + +/* Global Pin Control High Register */ + +#define PORT_GPCHR_GPWD_SHIFT (0) /* Bits 0-15: Global Pin Write Data */ +#define PORT_GPCHR_GPWD_MASK (0xffff << PORT_GPCHR_GPWD_SHIFT) +# define PORT_GPCHR_GPWD(n) ((1 << (n)) << PORT_GPCHR_GPWD_SHIFT) +#define PORT_GPCHR_GPWE_SHIFT (16) /* Bits 16-31: Global Pin Write Enable */ +#define PORT_GPCHR_GPWE_MASK (0xffff << PORT_GPCHR_GPWE_SHIFT) +# define PORT_GPCHR_GPWE(n) ((1 << (n)) << PORT_GPCHR_GPWE_SHIFT) + +/* Interrupt Status Flag Register */ + +#define PORT_ISFR(n) (1 << (n)) + +/* Digital Filter Enable Register */ + +#define PORT_DFER(n) (1 << (n)) + +/* Digital Filter Clock Register */ + +#define PORT_DFCR_CS (1 << 0) /* Bit 0: Clock Source */ + +/* Digital Filter Width Register */ + +#define PORT_DFWR_FILT_SHIFT (0) /* Bits 0-4: Filter Length */ +#define PORT_DFWR_FILT_MASK (31 << PORT_DFWR_FILT_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H */ diff --git a/arch/arm/src/kinetis/kinetis_rngb.h b/arch/arm/src/kinetis/kinetis_rngb.h new file mode 100644 index 0000000000000000000000000000000000000000..a4f677555030cd5be5f25fd5898407986aeeb40e --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_rngb.h @@ -0,0 +1,161 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_rngb.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(KINETIS_NRNG) && KINETIS_NRNG > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_RNG_VER_OFFSET 0x0000 /* RNGB Version ID Register */ +#define KINETIS_RNG_CMD_OFFSET 0x0004 /* RNGB Command Register */ +#define KINETIS_RNG_CR_OFFSET 0x0008 /* RNGB Control Register */ +#define KINETIS_RNG_SR_OFFSET 0x000c /* RNGB Status Register */ +#define KINETIS_RNG_ESR_OFFSET 0x0010 /* RNGB Error Status Register */ +#define KINETIS_RNG_OUT_OFFSET 0x0014 /* RNGB Output FIFO */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_RNG_VER (KINETIS_RNGB_BASE+KINETIS_RNG_VER_OFFSET) +#define KINETIS_RNG_CMD (KINETIS_RNGB_BASE+KINETIS_RNG_CMD_OFFSET) +#define KINETIS_RNG_CR (KINETIS_RNGB_BASE+KINETIS_RNG_CR_OFFSET) +#define KINETIS_RNG_SR (KINETIS_RNGB_BASE+KINETIS_RNG_SR_OFFSET) +#define KINETIS_RNG_ESR (KINETIS_RNGB_BASE+KINETIS_RNG_ESR_OFFSET) +#define KINETIS_RNG_OUT (KINETIS_RNGB_BASE+KINETIS_RNG_OUT_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* RNGB Version ID Register */ + +#define RNG_VER_MINOR_SHIFT (0) /* Bits 0-7: Minor version number */ +#define RNG_VER_MINOR_MASK (0xff << RNG_VER_MINOR_SHIFT) +#define RNG_VER_MAJOR_SHIFT (8) /* Bits 8-15: Major version number */ +#define RNG_VER_MAJOR_MASK (0xff << RNG_VER_MAJOR_SHIFT) + /* Bits 27–16: Reserved */ +#define RNG_VER_TYPE_SHIFT (28) /* Bits 28-31: Random number generator type */ +#define RNG_VER_TYPE_MASK (15 << RNG_VER_TYPE_SHIFT) +# define RNG_VER_TYPE_RNGA (0 << RNG_VER_TYPE_SHIFT) +# define RNG_VER_TYPE_RNGB (1 << RNG_VER_TYPE_SHIFT) +# define RNG_VER_TYPE_RNGC (2 << RNG_VER_TYPE_SHIFT) + +/* RNGB Command Register */ + +#define RNG_CMD_ST (1 << 0) /* Bit 0: Self test */ +#define RNG_CMD_GS (1 << 1) /* Bit 1: Generate seed */ + /* Bits 2-3: Reserved */ +#define RNG_CMD_CI (1 << 4) /* Bit 4: Clear interrupt */ +#define RNG_CMD_CE (1 << 5) /* Bit 5: Clear error */ +#define RNG_CMD_SR (1 << 6) /* Bit 6: Software reset */ + /* Bits 7-31: Reserved */ +/* RNGB Control Register */ + +#define RNG_CR_FUFMOD_SHIFT (0) /* Bits 0-1: FIFO underflow response mode */ +#define RNG_CR_FUFMOD_MASK (3 << RNG_CR_FUFMOD_SHIFT) +# define RNG_CR_FUFMOD_ZEROS (0 << RNG_CR_FUFMOD_SHIFT) /* Return zeros, set RNG_ESR[FUFE] */ +# define RNG_CR_FUFMOD_ERROR (2 << RNG_CR_FUFMOD_SHIFT) /* Generate bus transfer error */ +# define RNG_CR_FUFMOD_INT (3 << RNG_CR_FUFMOD_SHIFT) /* Generate interrupt, return zeros */ + /* Bits 2-3: Reserved */ +#define RNG_CR_AR (1 << 4) /* Bit 4: Auto-reseed */ +#define RNG_CR_MASKDONE (1 << 5) /* Bit 5: Mask done interrupt */ +#define RNG_CR_MASKERR (1 << 6) /* Bit 6: Mask error interrupt */ + /* Bits 7-31: Reserved */ +/* RNGB Status Register */ + /* Bit 0: Reserved */ +#define RNG_SR_BUSY (1 << 1) /* Bit 1: Busy */ +#define RNG_SR_SLP (1 << 2) /* Bit 2: Sleep */ +#define RNG_SR_RS (1 << 3) /* Bit 3: Reseed needed */ +#define RNG_SR_STDN (1 << 4) /* Bit 4: Self test done */ +#define RNG_SR_SDN (1 << 5) /* Bit 5: Seed done */ +#define RNG_SR_NSDN (1 << 6) /* Bit 6: New seed done */ + /* Bit 7: Reserved */ +#define RNG_SR_FIFO_LVL_SHIFT (8) /* Bits 8-11: FIFO level */ +#define RNG_SR_FIFO_LVL_MASK (15 << RNG_SR_FIFO_LVL_SHIFT) +#define RNG_SR_FIFO_SIZE_SHIFT (12) /* Bits 12-15: FIFO size */ +#define RNG_SR_FIFO_SIZE_MASK (15 << RNG_SR_FIFO_SIZE_SHIFT) +#define RNG_SR_ERR (1 << 16) /* Bit 16: Error */ + /* Bits 17-20: Reserved */ +#define RNG_SR_ST_PF_SHIFT (21) /* Bits 21-23: Self Test Pass Fail */ +#define RNG_SR_ST_PF_MASK (7 << RNG_SR_ST_PF_SHIFT) +# define RNG_SR_ST_PF_TRNG (4 << RNG_SR_ST_PF_SHIFT) /* TRNG self test pass/fail */ +# define RNG_SR_ST_PF_PRNG (2 << RNG_SR_ST_PF_SHIFT) /* PRNG self test pass/fail */ +# define RNG_SR_ST_PF_RESEED (1 << RNG_SR_ST_PF_SHIFT) /* RESEED self test pass/fail */ +#define RNG_SR_STATPF_SHIFT (24) /* Bits 24-31: Statistics test pass fail */ +#define RNG_SR_STATPF_MASK (0xff << RNG_SR_STATPF_SHIFT) +# define RNG_SR_STATPF_LONG (0x80 << RNG_SR_STATPF_SHIFT) /* Long run test (>34) */ +# define RNG_SR_STATPF_LEN6 (0x40 << RNG_SR_STATPF_SHIFT) /* Length 6+ run test */ +# define RNG_SR_STATPF_LEN5 (0x20 << RNG_SR_STATPF_SHIFT) /* Length 5 run test */ +# define RNG_SR_STATPF_LEN4 (0x10 << RNG_SR_STATPF_SHIFT) /* Length 4 run test */ +# define RNG_SR_STATPF_LEN3 (0x08 << RNG_SR_STATPF_SHIFT) /* Length 3 run test */ +# define RNG_SR_STATPF_LEN2 (0x04 << RNG_SR_STATPF_SHIFT) /* Length 2 run test */ +# define RNG_SR_STATPF_LEN1 (0x02 << RNG_SR_STATPF_SHIFT) /* Length 1 run test */ +# define RNG_SR_STATPF_MONO (0x01 << RNG_SR_STATPF_SHIFT) /* Monobit test */ + +/* RNGB Error Status Register */ + +#define RNG_ESR_LFE (1 << 0) /* Bit 0: Linear feedback shift register (LFSR) error */ +#define RNG_ESR_OSCE (1 << 1) /* Bit 1: Oscillator error */ +#define RNG_ESR_STE (1 << 2) /* Bit 2: Self test error */ +#define RNG_ESR_SATE (1 << 3) /* Bit 3: Statistical test error */ +#define RNG_ESR_FUFE (1 << 4) /* Bit 4: FIFO underflow error */ + /* Bits 5-31: Reserved */ +/* RNGB Output FIFO (32-bit random output) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* KINETIS_NRNG && KINETIS_NRNG > 0 */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H */ diff --git a/arch/arm/src/kinetis/kinetis_rtc.h b/arch/arm/src/kinetis/kinetis_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..69c097a7c950627992f577b40e61cede1480ccf4 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_rtc.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_rtc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(KINETIS_NRTC) && KINETIS_NRTC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_RTC_TSR_OFFSET 0x0000 /* RTC Time Seconds Register */ +#define KINETIS_RTC_TPR_OFFSET 0x0004 /* RTC Time Prescaler Register */ +#define KINETIS_RTC_TAR_OFFSET 0x0008 /* RTC Time Alarm Register */ +#define KINETIS_RTC_TCR_OFFSET 0x000c /* RTC Time Compensation Register */ +#define KINETIS_RTC_CR_OFFSET 0x0010 /* RTC Control Register */ +#define KINETIS_RTC_SR_OFFSET 0x0014 /* RTC Status Register */ +#define KINETIS_RTC_LR_OFFSET 0x0018 /* RTC Lock Register */ +#ifdef KINETIS_K40 +# define KINETIS_RTC_IER_OFFSET 0x001c /* RTC Interrupt Enable Register (K40) */ +#endif +#ifdef KINETIS_K60 +# define KINETIS_RTC_CCR_OFFSET 0x001c /* RTC Chip Configuration Register (K60) */ +#endif +#define KINETIS_RTC_WAR_OFFSET 0x0800 /* RTC Write Access Register */ +#define KINETIS_RTC_RAR_OFFSET 0x0804 /* RTC Read Access Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_RTC_TSR (KINETIS_RTC_BASE+KINETIS_RTC_TSR_OFFSET) +#define KINETIS_RTC_TPR (KINETIS_RTC_BASE+KINETIS_RTC_TPR_OFFSET) +#define KINETIS_RTC_TAR (KINETIS_RTC_BASE+KINETIS_RTC_TAR_OFFSET) +#define KINETIS_RTC_TCR (KINETIS_RTC_BASE+KINETIS_RTC_TCR_OFFSET) +#define KINETIS_RTC_CR (KINETIS_RTC_BASE+KINETIS_RTC_CR_OFFSET) +#define KINETIS_RTC_SR (KINETIS_RTC_BASE+KINETIS_RTC_SR_OFFSET) +#define KINETIS_RTC_LR (KINETIS_RTC_BASE+KINETIS_RTC_LR_OFFSET) +#ifdef KINETIS_K40 +# define KINETIS_RTC_IER (KINETIS_RTC_BASE+KINETIS_RTC_IER_OFFSET) +#endif +#ifdef KINETIS_K60 +# define KINETIS_CCR_IER (KINETIS_RTC_BASE+KINETIS_RTC_CCR_OFFSET) +#endif +#define KINETIS_RTC_WAR (KINETIS_RTC_BASE+KINETIS_RTC_WAR_OFFSET) +#define KINETIS_RTC_RAR (KINETIS_RTC_BASE+KINETIS_RTC_RAR_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* RTC Time Seconds Register (32-bits of time in seconds) */ + +/* RTC Time Prescaler Register */ + +#define RTC_TPR_SHIFT (0) /* Bits 0-15: Time Prescaler Register */ +#define RTC_TPR_MASK (0xffff << RTC_TPR_SHIFT) + /* Bits 16-31: Reserved */ +/* RTC Time Alarm Register (32-bits of time alarm) */ + +/* RTC Time Compensation Register (32-bits) */ + +#define RTC_TCR_TCR_SHIFT (0) /* Bits 0-7: Time Compensation Register */ +#define RTC_TCR_TCR_MASK (0xff << RTC_TCR_CIR_MASK) +#define RTC_TCR_CIR_SHIFT (8) /* Bits 8-15: Compensation Interval Register */ +#define RTC_TCR_CIR_MASK (0xff << RTC_TCR_CIR_SHIFT) +#define RTC_TCR_TCV_SHIFT (16) /* Bits 16-23: Time Compensation Value */ +#define RTC_TCR_TCV_MASK (0xff << RTC_TCR_TCV_SHIFT) +#define RTC_TCR_CIC_SHIFT (24) /* Bits 24-31: Compensation Interval Counter */ +#define RTC_TCR_CIC_MASK (0xff << RTC_TCR_CIC_SHIFT) + +/* RTC Control Register (32-bits) */ + +#define RTC_CR_SWR (1 << 0) /* Bit 0: Software Reset */ +#define RTC_CR_WPE (1 << 1) /* Bit 1: Wakeup Pin Enable */ +#define RTC_CR_SUP (1 << 2) /* Bit 2: Supervisor Access */ +#define RTC_CR_UM (1 << 3) /* Bit 3: Update Mode */ + /* Bits 4-7: Reserved */ +#define RTC_CR_OSCE (1 << 8) /* Bit 8: Oscillator Enable */ +#define RTC_CR_CLKO (1 << 9) /* Bit 9: Clock Output */ +#define RTC_CR_SC16P (1 << 10) /* Bit 10: Oscillator 16pF load configure */ +#define RTC_CR_SC8P (1 << 11) /* Bit 11: Oscillator 8pF load configure */ +#define RTC_CR_SC4P (1 << 12) /* Bit 12: Oscillator 4pF load configure */ +#define RTC_CR_SC2P (1 << 13) /* Bit 13: Oscillator 2pF load configure */ + /* Bits 14-31: Reserved */ +/* RTC Status Register (32-bits) */ + +#define RTC_SR_TIF (1 << 0) /* Bit 0: Time Invalid Flag */ +#define RTC_SR_TOF (1 << 1) /* Bit 1: Time Overflow Flag */ + /* Bit 3: Reserved */ +#define RTC_SR_TAF (1 << 2) /* Bit 2: Time Alarm Flag */ +#define RTC_SR_TCE (1 << 4) /* Bit 4: Time Counter Enable */ + /* Bits 5-31: Reserved */ +/* RTC Lock Register (32-bits) */ + /* Bits 0-2: Reserved */ +#define RTC_LR_TCL (1 << 3) /* Bit 3: Time Compensation Lock */ +#define RTC_LR_CRL (1 << 4) /* Bit 4: Control Register Lock */ +#define RTC_LR_SRL (1 << 5) /* Bit 5: Status Register Lock */ +#ifdef KINETIS_K40 +# define RTC_LR_LRL (1 << 6) /* Bit 6: Lock Register Lock (K40) */ +#endif + /* Bits 7-31: Reserved */ +/* RTC Interrupt Enable Register (32-bits, K40) */ + +#ifdef KINETIS_K40 +# define RTC_IER_TIIE (1 << 0) /* Bit 0: Time Invalid Interrupt Enable */ +# define RTC_IER_TOIE (1 << 1) /* Bit 1: Time Overflow Interrupt Enable */ +# define RTC_IER_TAIE (1 << 2) /* Bit 2: Time Alarm Interrupt Enable */ + /* Bit 3: Reserved */ +# define RTC_IER_TSIE (1 << 4) /* Bit 4: Time Seconds Interrupt Enable */ + /* Bits 5-31: Reserved */ +#endif + +/* RTC Chip Configuration Register (32-bits,K60) */ + +#ifdef KINETIS_K60 +# define RTC_CCR_CONFIG_SHIFT (0) /* Bits 0-7: Chip Configuration */ +# define RTC_CCR_CONFIG_MASK (0xff << RTC_CCR_CONFIG_SHIFT) + /* Bits 8-31: Reserved */ +#endif + +/* RTC Write Access Register (32-bits) */ + +#define RTC_WAR_TSRW (1 << 0) /* Bit 0: Time Seconds Register Write */ +#define RTC_WAR_TPRW (1 << 1) /* Bit 1: Time Prescaler Register Write */ +#define RTC_WAR_TARW (1 << 2) /* Bit 2: Time Alarm Register Write */ +#define RTC_WAR_TCRW (1 << 3) /* Bit 3: Time Compensation Register Write */ +#define RTC_WAR_CRW (1 << 4) /* Bit 4: Control Register Write */ +#define RTC_WAR_SRW (1 << 5) /* Bit 5: Status Register Write */ +#define RTC_WAR_LRW (1 << 6) /* Bit 6: Lock Register Write */ +#ifdef KINETIS_K40 +# define RTC_WAR_IERW (1 << 7) /* Bit 7: Interrupt Enable Register Write */ +#endif +#ifdef KINETIS_K60 +# define RTC_WAR_CCRW (1 << 7) /* Bit 7: Chip Config Register Write */ +#endif + /* Bits 8-31: Reserved */ +/* RTC Read Access Register */ + +#define RTC_RAR_TSRR (1 << 0) /* Bit 0: Time Seconds Register Read */ +#define RTC_RAR_TPRR (1 << 1) /* Bit 1: Time Prescaler Register Read */ +#define RTC_RAR_TARR (1 << 2) /* Bit 2: Time Alarm Register Read */ +#define RTC_RAR_TCRR (1 << 3) /* Bit 3: Time Compensation Register Read */ +#define RTC_RAR_CRR (1 << 4) /* Bit 4: Control Register Read */ +#define RTC_RAR_SRR (1 << 5) /* Bit 5: Status Register Read */ +#define RTC_RAR_LRR (1 << 6) /* Bit 6: Lock Register Read */ +#ifdef KINETIS_K40 +# define RTC_RAR_IERR (1 << 7) /* Bit 7: Interrupt Enable Register Read */ +#endif +#ifdef KINETIS_K60 +# define RTC_RAR_CCRR (1 << 7) /* Bit 7: Chip Config Register Read */ +#endif + /* Bits 8-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* KINETIS_NRTC && KINETIS_NRTC > 0 */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H */ diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c new file mode 100644 index 0000000000000000000000000000000000000000..5af56d50df817f366c2ae767cf70f79ceb3f82ec --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_sdhc.c @@ -0,0 +1,2943 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_sdhc.c + * + * Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "kinetis.h" +#include "kinetis_pinmux.h" +#include "kinetis_sim.h" +#include "kinetis_sdhc.h" + +#ifdef CONFIG_KINETIS_SDHC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_SDIO_DMA +# warning "Large Non-DMA transfer may result in RX overrun failures" +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_KINETIS_SDHC_PRIO +# define CONFIG_KINETIS_SDHC_PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_KINETIS_SDHC_DMAPRIO +# define CONFIG_KINETIS_SDHC_DMAPRIO DMA_CCR_PRIMED +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE) +# undef CONFIG_SDIO_XFRDEBUG +#endif + +/* SDCLK frequencies corresponding to various modes of operation. These + * values may be provided in either the NuttX configuration file or in + * the board.h file + * + * NOTE: These settings are not currently used. Since there are only four + * frequencies, it makes more sense to just "can" the fixed frequency prescaler + * and divider values. + */ + +#ifdef CONFIG_KINETIS_SDHC_ABSFREQ +# ifndef CONFIG_KINETIS_IDMODE_FREQ +# define CONFIG_KINETIS_IDMODE_FREQ 400000 /* 400 KHz, ID mode */ +# endif +# ifndef CONFIG_KINETIS_MMCXFR_FREQ +# define CONFIG_KINETIS_MMCXFR_FREQ 20000000 /* 20MHz MMC, normal clocking */ +# endif +# ifndef CONFIG_KINETIS_SD1BIT_FREQ +# define CONFIG_KINETIS_SD1BIT_FREQ 20000000 /* 20MHz SD 1-bit, normal clocking */ +# endif +# ifndef CONFIG_KINETIS_SD4BIT_FREQ +# define CONFIG_KINETIS_SD4BIT_FREQ 25000000 /* 25MHz SD 4-bit, normal clocking */ +# endif +#endif + +/* Timing */ + +#define SDHC_CMDTIMEOUT (100000) +#define SDHC_LONGTIMEOUT (0x7fffffff) + +/* Big DVS setting. Range is 0=SDCLK*213 through 14=SDCLK*227 */ + +#define SDHC_DVS_MAXTIMEOUT (14) +#define SDHC_DVS_DATATIMEOUT (14) + +/* Maximum watermark value */ + +#define SDHC_MAX_WATERMARK 128 + +/* Data transfer / Event waiting interrupt mask bits */ + +#define SDHC_RESPERR_INTS (SDHC_INT_CCE|SDHC_INT_CTOE|SDHC_INT_CEBE|SDHC_INT_CIE) +#define SDHC_RESPDONE_INTS (SDHC_RESPERR_INTS|SDHC_INT_CC) + +#define SCHC_XFRERR_INTS (SDHC_INT_DCE|SDHC_INT_DTOE|SDHC_INT_DEBE) +#define SDHC_RCVDONE_INTS (SCHC_XFRERR_INTS|SDHC_INT_BRR|SDHC_INT_TC) +#define SDHC_SNDDONE_INTS (SCHC_XFRERR_INTS|SDHC_INT_BWR|SDHC_INT_TC) +#define SDHC_XFRDONE_INTS (SCHC_XFRERR_INTS|SDHC_INT_BRR|SDHC_INT_BWR|SDHC_INT_TC) + +#define SCHC_DMAERR_INTS (SDHC_INT_DCE|SDHC_INT_DTOE|SDHC_INT_DEBE|SDHC_INT_DMAE) +#define SDHC_DMADONE_INTS (SCHC_DMAERR_INTS|SDHC_INT_DINT) + +#define SDHC_WAITALL_INTS (SDHC_RESPDONE_INTS|SDHC_XFRDONE_INTS|SDHC_DMADONE_INTS) + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define DEBUG_NSAMPLES 3 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure defines the state of the Kinetis SDIO interface */ + +struct kinetis_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* Kinetis-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t waitints; /* Interrupt enables for event waiting */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + size_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t xfrints; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + +#ifdef CONFIG_SDIO_DMA + volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */ +#endif +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +struct kinetis_sdhcregs_s +{ + /* All read-able SDHC registers */ + + uint32_t dsaddr; /* DMA System Address Register */ + uint32_t blkattr; /* Block Attributes Register */ + uint32_t cmdarg; /* Command Argument Register */ + uint32_t xferty; /* Transfer Type Register */ + uint32_t cmdrsp0; /* Command Response 0 */ + uint32_t cmdrsp1; /* Command Response 1 */ + uint32_t cmdrsp2; /* Command Response 2 */ + uint32_t cmdrsp3; /* Command Response 3 */ + uint32_t prsstat; /* Present State Register */ + uint32_t proctl; /* Protocol Control Register */ + uint32_t sysctl; /* System Control Register */ + uint32_t irqstat; /* Interrupt Status Register */ + uint32_t irqstaten; /* Interrupt Status Enable Register */ + uint32_t irqsigen; /* Interrupt Signal Enable Register */ + uint32_t ac12err; /* Auto CMD12 Error Status Register */ + uint32_t htcapblt; /* Host Controller Capabilities */ + uint32_t wml; /* Watermark Level Register */ + uint32_t admaes; /* ADMA Error Status Register */ + uint32_t adsaddr; /* ADMA System Address Register */ + uint32_t vendor; /* Vendor Specific Register */ + uint32_t mmcboot; /* MMC Boot Register */ + uint32_t hostver; /* Host Controller Version */ +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void kinetis_takesem(struct kinetis_dev_s *priv); +#define kinetis_givesem(priv) (sem_post(&priv->waitsem)) +static void kinetis_configwaitints(struct kinetis_dev_s *priv, uint32_t waitints, + sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void kinetis_configxfrints(struct kinetis_dev_s *priv, uint32_t xfrints); + +/* DMA Helpers **************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_sampleinit(void); +static void kinetis_sdhcsample(struct kinetis_sdhcregs_s *regs); +static void kinetis_sample(struct kinetis_dev_s *priv, int index); +static void kinetis_dumpsample(struct kinetis_dev_s *priv, + struct kinetis_sdhcregs_s *regs, const char *msg); +static void kinetis_dumpsamples(struct kinetis_dev_s *priv); +static void kinetis_showregs(struct kinetis_dev_s *priv, const char *msg); +#else +# define kinetis_sampleinit() +# define kinetis_sample(priv,index) +# define kinetis_dumpsamples(priv) +# define kinetis_showregs(priv,msg) +#endif + +/* Data Transfer Helpers ****************************************************/ + +static void kinetis_dataconfig(struct kinetis_dev_s *priv, bool bwrite, + unsigned int blocksize, unsigned int nblocks, + unsigned int timeout); +static void kinetis_datadisable(void); +#ifndef CONFIG_SDIO_DMA +static void kinetis_transmit(struct kinetis_dev_s *priv); +static void kinetis_receive(struct kinetis_dev_s *priv); +#endif +static void kinetis_eventtimeout(int argc, uint32_t arg); +static void kinetis_endwait(struct kinetis_dev_s *priv, sdio_eventset_t wkupevent); +static void kinetis_endtransfer(struct kinetis_dev_s *priv, sdio_eventset_t wkupevent); + +/* Interrupt Handling *******************************************************/ + +static int kinetis_interrupt(int irq, void *context); + +/* SDIO interface methods ***************************************************/ + +/* Mutual exclusion */ + +#ifdef CONFIG_SDIO_MUXBUS +static int kinetis_lock(FAR struct sdio_dev_s *dev, bool lock); +#endif + +/* Initialization/setup */ + +static void kinetis_reset(FAR struct sdio_dev_s *dev); +static uint8_t kinetis_status(FAR struct sdio_dev_s *dev); +static void kinetis_widebus(FAR struct sdio_dev_s *dev, bool enable); +#ifdef CONFIG_KINETIS_SDHC_ABSFREQ +static void kinetis_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency); +#endif +static void kinetis_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int kinetis_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int kinetis_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +#ifndef CONFIG_SDIO_DMA +static int kinetis_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int kinetis_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, uint32_t nbytes); +#endif +static int kinetis_cancel(FAR struct sdio_dev_s *dev); + +static int kinetis_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int kinetis_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int kinetis_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int kinetis_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int kinetis_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void kinetis_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + kinetis_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void kinetis_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int kinetis_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool kinetis_dmasupported(FAR struct sdio_dev_s *dev); +static int kinetis_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +static int kinetis_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void kinetis_callback(void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct kinetis_dev_s g_sdhcdev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = kinetis_lock, +#endif + .reset = kinetis_reset, + .status = kinetis_status, + .widebus = kinetis_widebus, + .clock = kinetis_clock, + .attach = kinetis_attach, + .sendcmd = kinetis_sendcmd, +#ifndef CONFIG_SDIO_DMA + .recvsetup = kinetis_recvsetup, + .sendsetup = kinetis_sendsetup, +#else + .recvsetup = kinetis_dmarecvsetup, + .sendsetup = kinetis_dmasendsetup, +#endif + .cancel = kinetis_cancel, + .waitresponse = kinetis_waitresponse, + .recvR1 = kinetis_recvshortcrc, + .recvR2 = kinetis_recvlong, + .recvR3 = kinetis_recvshort, + .recvR4 = kinetis_recvnotimpl, + .recvR5 = kinetis_recvnotimpl, + .recvR6 = kinetis_recvshortcrc, + .recvR7 = kinetis_recvshort, + .waitenable = kinetis_waitenable, + .eventwait = kinetis_eventwait, + .callbackenable = kinetis_callbackenable, + .registercallback = kinetis_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = kinetis_dmasupported, + .dmarecvsetup = kinetis_dmarecvsetup, + .dmasendsetup = kinetis_dmasendsetup, +#endif + }, +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +static struct kinetis_sdhcregs_s g_sampleregs[DEBUG_NSAMPLES]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: kinetis_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_takesem(struct kinetis_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: kinetis_configwaitints + * + * Description: + * Enable/disable SDIO interrupts needed to suport the wait function + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * waitints - The set of bits in the SDIO MASK register to set + * waitevents - Waited for events + * wkupevent - Wake-up events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_configwaitints(struct kinetis_dev_s *priv, uint32_t waitints, + sdio_eventset_t waitevents, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + + flags = enter_critical_section(); + priv->waitevents = waitevents; + priv->wkupevent = wkupevent; + priv->waitints = waitints; +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + putreg32(priv->xfrints | priv->waitints | SDHC_INT_CINT, + KINETIS_SDHC_IRQSIGEN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: kinetis_configxfrints + * + * Description: + * Enable SDIO interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * xfrints - The set of bits in the SDIO MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_configxfrints(struct kinetis_dev_s *priv, uint32_t xfrints) +{ + irqstate_t flags; + flags = enter_critical_section(); + priv->xfrints = xfrints; + putreg32(priv->xfrints | priv->waitints | SDHC_INT_CINT, + KINETIS_SDHC_IRQSIGEN); + leave_critical_section(flags); +} + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_sampleinit + * + * Description: + * Setup prior to collecting DMA samples + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_sampleinit(void) +{ + memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct kinetis_sdhcregs_s)); +} +#endif + +/**************************************************************************** + * Name: kinetis_sdhcsample + * + * Description: + * Sample SDIO registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_sdhcsample(struct kinetis_sdhcregs_s *regs) +{ + regs->dsaddr = getreg32(KINETIS_SDHC_DSADDR); /* DMA System Address Register */ + regs->blkattr = getreg32(KINETIS_SDHC_BLKATTR); /* Block Attributes Register */ + regs->cmdarg = getreg32(KINETIS_SDHC_CMDARG); /* Command Argument Register */ + regs->xferty = getreg32(KINETIS_SDHC_XFERTYP); /* Transfer Type Register */ + regs->cmdrsp0 = getreg32(KINETIS_SDHC_CMDRSP0); /* Command Response 0 */ + regs->cmdrsp1 = getreg32(KINETIS_SDHC_CMDRSP1); /* Command Response 1 */ + regs->cmdrsp2 = getreg32(KINETIS_SDHC_CMDRSP2); /* Command Response 2 */ + regs->cmdrsp3 = getreg32(KINETIS_SDHC_CMDRSP3); /* Command Response 3 */ + regs->prsstat = getreg32(KINETIS_SDHC_PRSSTAT); /* Present State Register */ + regs->proctl = getreg32(KINETIS_SDHC_PROCTL); /* Protocol Control Register */ + regs->sysctl = getreg32(KINETIS_SDHC_SYSCTL); /* System Control Register */ + regs->irqstat = getreg32(KINETIS_SDHC_IRQSTAT); /* Interrupt Status Register */ + regs->irqstaten = getreg32(KINETIS_SDHC_IRQSTATEN); /* Interrupt Status Enable Register */ + regs->irqsigen = getreg32(KINETIS_SDHC_IRQSIGEN); /* Interrupt Signal Enable Register */ + regs->ac12err = getreg32(KINETIS_SDHC_AC12ERR); /* Auto CMD12 Error Status Register */ + regs->htcapblt = getreg32(KINETIS_SDHC_HTCAPBLT); /* Host Controller Capabilities */ + regs->wml = getreg32(KINETIS_SDHC_WML); /* Watermark Level Register */ + regs->admaes = getreg32(KINETIS_SDHC_ADMAES); /* ADMA Error Status Register */ + regs->adsaddr = getreg32(KINETIS_SDHC_ADSADDR); /* ADMA System Address Register */ + regs->vendor = getreg32(KINETIS_SDHC_VENDOR); /* Vendor Specific Register */ + regs->mmcboot = getreg32(KINETIS_SDHC_MMCBOOT); /* MMC Boot Register */ + regs->hostver = getreg32(KINETIS_SDHC_HOSTVER); /* Host Controller Version */ +} +#endif + +/**************************************************************************** + * Name: kinetis_sample + * + * Description: + * Sample SDIO/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_sample(struct kinetis_dev_s *priv, int index) +{ + kinetis_sdhcsample(&g_sampleregs[index]); +} +#endif + +/**************************************************************************** + * Name: kinetis_dumpsample + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_dumpsample(struct kinetis_dev_s *priv, + struct kinetis_sdhcregs_s *regs, const char *msg) +{ + fdbg("SDHC Registers: %s\n", msg); + fdbg(" DSADDR[%08x]: %08x\n", KINETIS_SDHC_DSADDR, regs->dsaddr); + fdbg(" BLKATTR[%08x]: %08x\n", KINETIS_SDHC_BLKATTR, regs->blkattr); + fdbg(" CMDARG[%08x]: %08x\n", KINETIS_SDHC_CMDARG, regs->cmdarg); + fdbg(" XFERTY[%08x]: %08x\n", KINETIS_SDHC_XFERTYP, regs->xferty); + fdbg(" CMDRSP0[%08x]: %08x\n", KINETIS_SDHC_CMDRSP0, regs->cmdrsp0); + fdbg(" CMDRSP1[%08x]: %08x\n", KINETIS_SDHC_CMDRSP1, regs->cmdrsp1); + fdbg(" CMDRSP2[%08x]: %08x\n", KINETIS_SDHC_CMDRSP2, regs->cmdrsp2); + fdbg(" CMDRSP3[%08x]: %08x\n", KINETIS_SDHC_CMDRSP3, regs->cmdrsp3); + fdbg(" PRSSTAT[%08x]: %08x\n", KINETIS_SDHC_PRSSTAT, regs->prsstat); + fdbg(" PROCTL[%08x]: %08x\n", KINETIS_SDHC_PROCTL, regs->proctl); + fdbg(" SYSCTL[%08x]: %08x\n", KINETIS_SDHC_SYSCTL, regs->sysctl); + fdbg(" IRQSTAT[%08x]: %08x\n", KINETIS_SDHC_IRQSTAT, regs->irqstat); + fdbg("IRQSTATEN[%08x]: %08x\n", KINETIS_SDHC_IRQSTATEN, regs->irqstaten); + fdbg(" IRQSIGEN[%08x]: %08x\n", KINETIS_SDHC_IRQSIGEN, regs->irqsigen); + fdbg(" AC12ERR[%08x]: %08x\n", KINETIS_SDHC_AC12ERR, regs->ac12err); + fdbg(" HTCAPBLT[%08x]: %08x\n", KINETIS_SDHC_HTCAPBLT, regs->htcapblt); + fdbg(" WML[%08x]: %08x\n", KINETIS_SDHC_WML, regs->wml); + fdbg(" ADMAES[%08x]: %08x\n", KINETIS_SDHC_ADMAES, regs->admaes); + fdbg(" ADSADDR[%08x]: %08x\n", KINETIS_SDHC_ADSADDR, regs->adsaddr); + fdbg(" VENDOR[%08x]: %08x\n", KINETIS_SDHC_VENDOR, regs->vendor); + fdbg(" MMCBOOT[%08x]: %08x\n", KINETIS_SDHC_MMCBOOT, regs->mmcboot); + fdbg(" HOSTVER[%08x]: %08x\n", KINETIS_SDHC_HOSTVER, regs->hostver); +} +#endif + +/**************************************************************************** + * Name: kinetis_dumpsamples + * + * Description: + * Dump all sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_dumpsamples(struct kinetis_dev_s *priv) +{ + kinetis_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); + kinetis_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup"); + kinetis_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer"); +} +#endif + +/**************************************************************************** + * Name: kinetis_showregs + * + * Description: + * Dump the current state of all registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void kinetis_showregs(struct kinetis_dev_s *priv, const char *msg) +{ + struct kinetis_sdhcregs_s regs; + + kinetis_sdhcsample(®s); + kinetis_dumpsample(priv, ®s, msg); +} +#endif + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_dataconfig + * + * Description: + * Configure the SDIO data path for the next data transfer + * + ****************************************************************************/ + +static void kinetis_dataconfig(struct kinetis_dev_s *priv, bool bwrite, + unsigned int blocksize, unsigned int nblocks, + unsigned int timeout) +{ + unsigned int watermark; + uint32_t regval = 0; + + /* Set the data timeout value in the SDHC_SYSCTL field to the selected value */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval &= ~SDHC_SYSCTL_DVS_MASK; + regval |= timeout << SDHC_SYSCTL_DVS_SHIFT; + putreg32(regval, KINETIS_SDHC_SYSCTL); + + /* Set the block size and count in the SDHC_BLKATTR register. The block + * size is only valid for multiple block transfers. + */ + + regval = blocksize << SDHC_BLKATTR_SIZE_SHIFT | + nblocks << SDHC_BLKATTR_CNT_SHIFT; + putreg32(regval, KINETIS_SDHC_BLKATTR); + + /* Set the watermark level */ + +#ifdef CONFIG_SDIO_DMA + /* Set the Read Watermark Level to the blocksize to be read + * (limited to half of the maximum watermark value). BRR will be + * set when the number of queued words is greater than or equal + * to this value. + */ + + watermark = (blocksize + 3) >> 2; + if (watermark > (SDHC_MAX_WATERMARK / 2)) + { + watermark = (SDHC_MAX_WATERMARK / 2); + } + + /* When the watermark level requirement is met in data transfer, and the + * internal DMA is enabled, the data buffer block sends a DMA request to + * the crossbar switch interface. + */ + + if (bwrite) + { + /* The SDHC will not start data transmission until the number of + * words set in the WML register can be held in the buffer. If the + * buffer is empty and the host system does not write data in time, + * the SDHC will stop the SD_CLK to avoid the data buffer under-run + * situation. + */ + + putreg32(watermark << SDHC_WML_WR_SHIFT, KINETIS_SDHC_WML); + } + else + { + /* The SDHC will not start data transmission until the number of + * words set in the WML register are in the buffer. If the buffer + * is full and the Host System does not read data in time, the + * SDHC will stop the SDHC_DCLK to avoid the data buffer over-run + * situation. + */ + + putreg32(watermark << SDHC_WML_RD_SHIFT, KINETIS_SDHC_WML); + } +#else + if (bwrite) + { + /* Write Watermark Level = 0: BWR will be set when the number of + * queued words is less than or equal to 0. + */ + + putreg32(0, KINETIS_SDHC_WML); + } + else + { + /* Set the Read Watermark Level to the blocksize to be read + * (limited to half of the maximum watermark value). BRR will be + * set when the number of queued words is greater than or equal + * to this value. + */ + + watermark = (blocksize + 3) >> 2; + if (watermark > (SDHC_MAX_WATERMARK / 2)) + { + watermark = (SDHC_MAX_WATERMARK / 2); + } + + putreg32(watermark << SDHC_WML_RD_SHIFT, KINETIS_SDHC_WML); + } +#endif +} + +/**************************************************************************** + * Name: kinetis_datadisable + * + * Description: + * Disable the SDIO data path setup by kinetis_dataconfig() and + * disable DMA. + * + ****************************************************************************/ + +static void kinetis_datadisable(void) +{ + uint32_t regval; + + /* Set the data timeout value in the SDHC_SYSCTL field to the maximum value */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval &= ~SDHC_SYSCTL_DVS_MASK; + regval |= SDHC_DVS_MAXTIMEOUT << SDHC_SYSCTL_DVS_SHIFT; + putreg32(regval, KINETIS_SDHC_SYSCTL); + + /* Set the block size to zero (no transfer) */ + + putreg32(0, KINETIS_SDHC_BLKATTR); +} + +/**************************************************************************** + * Name: kinetis_transmit + * + * Description: + * Send SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SDIO_DMA +static void kinetis_transmit(struct kinetis_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is more data to be sent, waiting for buffer write + * ready (BWR) + */ + + fllvdbg("Entry: remaining: %d IRQSTAT: %08x\n", + priv->remaining, getreg32(KINETIS_SDHC_IRQSTAT)); + + while (priv->remaining > 0 && + (getreg32(KINETIS_SDHC_IRQSTAT) & SDHC_INT_BWR) != 0) + { + /* Clear BWR. If there is more data in the buffer, writing to the + * buffer should reset BRR. + */ + + putreg32(SDHC_INT_BWR, KINETIS_SDHC_IRQSTAT); + + /* Is there a full word remaining in the user buffer? */ + + if (priv->remaining >= sizeof(uint32_t)) + { + /* Yes, transfer the word to the TX FIFO */ + + data.w = *priv->buffer++; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer just the bytes remaining in the user buffer, + * padding with zero as necessary to extend to a full word. + */ + + uint8_t *ptr = (uint8_t *)priv->remaining; + int i; + + data.w = 0; + for (i = 0; i < priv->remaining; i++) + { + data.b[i] = *ptr++; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + + /* Put the word in the FIFO */ + + putreg32(data.w, KINETIS_SDHC_DATPORT); + } + + fllvdbg("Exit: remaining: %d IRQSTAT: %08x\n", + priv->remaining, getreg32(KINETIS_SDHC_IRQSTAT)); + +} +#endif + +/**************************************************************************** + * Name: kinetis_receive + * + * Description: + * Receive SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SDIO_DMA +static void kinetis_receive(struct kinetis_dev_s *priv) +{ + unsigned int watermark; + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Set the Read Watermark Level to 1: BRR will be set when the number of + * queued words is greater than or equal to 1. + */ + + putreg32(1 << SDHC_WML_RD_SHIFT, KINETIS_SDHC_WML); + + /* Loop while there is space to store the data, waiting for buffer read + * ready (BRR) + */ + + fllvdbg("Entry: remaining: %d IRQSTAT: %08x\n", + priv->remaining, getreg32(KINETIS_SDHC_IRQSTAT)); + + while (priv->remaining > 0 && + (getreg32(KINETIS_SDHC_IRQSTAT) & SDHC_INT_BRR) != 0) + { + /* Clear BRR. If there is more data in the buffer, reading from the + * buffer should reset BRR. + */ + + putreg32(SDHC_INT_BRR, KINETIS_SDHC_IRQSTAT); + + /* Read the next word from the RX buffer */ + + data.w = getreg32(KINETIS_SDHC_DATPORT); + if (priv->remaining >= sizeof(uint32_t)) + { + /* Transfer the whole word to the user buffer */ + + *priv->buffer++ = data.w; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* Transfer any trailing fractional word */ + + uint8_t *ptr = (uint8_t *)priv->buffer; + int i; + + for (i = 0; i < priv->remaining; i++) + { + *ptr++ = data.b[i]; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + } + + /* Set the Read Watermark Level either the number of remaining words to be + * read (limited to half of the maximum watermark value) + */ + + watermark = ((priv->remaining + 3) >> 2); + if (watermark > (SDHC_MAX_WATERMARK / 2)) + { + watermark = (SDHC_MAX_WATERMARK / 2); + } + + putreg32(watermark << SDHC_WML_RD_SHIFT, KINETIS_SDHC_WML); + + fllvdbg("Exit: remaining: %d IRQSTAT: %08x WML: %08x\n", + priv->remaining, getreg32(KINETIS_SDHC_IRQSTAT), + getreg32(KINETIS_SDHC_WML)); + +} +#endif + +/**************************************************************************** + * Name: kinetis_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void kinetis_eventtimeout(int argc, uint32_t arg) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)arg; + + DEBUGASSERT(argc == 1 && priv != NULL); + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0); + + /* Is a data transfer complete event expected? */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. Sample registers at the time of the timeout */ + + kinetis_sample(priv, SAMPLENDX_END_TRANSFER); + + /* Wake up any waiting threads */ + + kinetis_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("Timeout: remaining: %d\n", priv->remaining); + } +} + +/**************************************************************************** + * Name: kinetis_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void kinetis_endwait(struct kinetis_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts */ + + kinetis_configwaitints(priv, 0, 0, wkupevent); + + /* Wake up the waiting thread */ + + kinetis_givesem(priv); +} + +/**************************************************************************** + * Name: kinetis_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the SDIO interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void kinetis_endtransfer(struct kinetis_dev_s *priv, sdio_eventset_t wkupevent) +{ +#ifdef CONFIG_SDIO_DMA + uint32_t regval; +#endif + + /* Disable all transfer related interrupts */ + + kinetis_configxfrints(priv, 0); + + /* Clearing pending interrupt status on all transfer related interrupts */ + + putreg32(SDHC_XFRDONE_INTS, KINETIS_SDHC_IRQSTAT); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + /* Stop the DMA by resetting the data path */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval |= SDHC_SYSCTL_RSTD; + putreg32(regval, KINETIS_SDHC_SYSCTL); +#endif + + /* Mark the transfer finished */ + + priv->remaining = 0; + + /* Debug instrumentation */ + + kinetis_sample(priv, SAMPLENDX_END_TRANSFER); + + /* Is a thread wait for these data transfer complete events? */ + + if ((priv->waitevents & wkupevent) != 0) + { + /* Yes.. wake up any waiting threads */ + + kinetis_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_interrupt + * + * Description: + * SDIO interrupt handler + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int kinetis_interrupt(int irq, void *context) +{ + struct kinetis_dev_s *priv = &g_sdhcdev; + uint32_t enabled; + uint32_t pending; + uint32_t regval; + + /* Check the SDHC IRQSTAT register. Mask out all bits that don't + * correspond to enabled interrupts. (This depends on the fact that bits + * are ordered the same in both the IRQSTAT and IRQSIGEN registers). If + * there are non-zero bits remaining, then we have work to do here. + */ + + regval = getreg32(KINETIS_SDHC_IRQSIGEN); + enabled = getreg32(KINETIS_SDHC_IRQSTAT) & regval; + fllvdbg("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n", + getreg32(KINETIS_SDHC_IRQSTAT), regval, enabled); + + /* Disable card interrupts to clear the card interrupt to the host system. */ + + regval &= ~SDHC_INT_CINT; + putreg32(regval, KINETIS_SDHC_IRQSIGEN); + + /* Clear all pending interrupts */ + + putreg32(enabled, KINETIS_SDHC_IRQSTAT); + + /* Handle in progress, interrupt driven data transfers ********************/ + + pending = enabled & priv->xfrints; + if (pending != 0) + { +#ifndef CONFIG_SDIO_DMA + /* Is the RX buffer read ready? Is so then we must be processing a + * non-DMA receive transaction. + */ + + if ((pending & SDHC_INT_BRR) != 0) + { + /* Receive data from the RX buffer */ + + kinetis_receive(priv); + } + + /* Otherwise, Is the TX buffer write ready? If so we must + * be processing a non-DMA send transaction. NOTE: We can't be + * processing both! + */ + + else if ((pending & SDHC_INT_BWR) != 0) + { + /* Send data via the TX FIFO */ + + kinetis_transmit(priv); + } +#endif + + /* Handle transfer complete events */ + + if ((pending & SDHC_INT_TC) != 0) + { + /* Terminate the transfer */ + + kinetis_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + + /* Handle data block send/receive CRC failure */ + + else if ((pending & SDHC_INT_DCE) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining); + kinetis_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle data timeout error */ + + else if ((pending & SDHC_INT_DTOE) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data timeout, remaining: %d\n", priv->remaining); + kinetis_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + } + + /* Handle wait events *****************************************************/ + + pending = enabled & priv->waitints; + if (pending != 0) + { + /* Is this a response completion event? */ + + if ((pending & SDHC_RESPDONE_INTS) != 0) + { + /* Yes.. Is their a thread waiting for response done? */ + + if ((priv->waitevents & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0) + { + /* Yes.. mask further interrupts and wake the thread up */ + + regval = getreg32(KINETIS_SDHC_IRQSIGEN); + regval &= ~SDHC_RESPDONE_INTS; + putreg32(regval, KINETIS_SDHC_IRQSIGEN); + + kinetis_endwait(priv, SDIOWAIT_RESPONSEDONE); + } + } + } + + /* Re-enable card interrupts */ + + regval = getreg32(KINETIS_SDHC_IRQSIGEN); + regval |= SDHC_INT_CINT; + putreg32(regval, KINETIS_SDHC_IRQSIGEN); + + return OK; +} + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_lock + * + * Description: + * Locks the bus. Function calls low-level multiplexed bus routines to + * resolve bus requests and acknowledgement issues. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * lock - TRUE to lock, FALSE to unlock. + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_MUXBUS +static int kinetis_lock(FAR struct sdio_dev_s *dev, bool lock) +{ + /* Single SDIO instance so there is only one possibility. The multiplex + * bus is part of board support package. + */ + + kinetis_muxbus_sdio_lock(lock); + return OK; +} +#endif + +/**************************************************************************** + * Name: kinetis_reset + * + * Description: + * Reset the SDIO controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct kinetis_dev_s *priv = (FAR struct kinetis_dev_s *)dev; + uint32_t regval; + + /* Disable all interrupts so that nothing interferes with the following. */ + + putreg32(0, KINETIS_SDHC_IRQSIGEN); + + /* Reset the SDHC block, putting registers in their default, reset state. + * Initiate the reset by setting the RSTA bit in the SYSCTL register. + */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval |= SDHC_SYSCTL_RSTA; + putreg32(regval, KINETIS_SDHC_SYSCTL); + + /* The SDHC will reset the RSTA bit to 0 when the capabilities + * registers are valid and the host driver can read them. + */ + + while ((getreg32(KINETIS_SDHC_SYSCTL) & SDHC_SYSCTL_RSTA) != 0); + + /* Make sure that all clocking is disabled */ + + kinetis_clock(dev, CLOCK_SDIO_DISABLED); + + /* Enable all status bits (these could not all be potential sources of + * interrupts. + */ + + putreg32(SDHC_INT_ALL, KINETIS_SDHC_IRQSTATEN); + + fvdbg("SYSCTL: %08x PRSSTAT: %08x IRQSTATEN: %08x\n", + getreg32(KINETIS_SDHC_SYSCTL), getreg32(KINETIS_SDHC_PRSSTAT), + getreg32(KINETIS_SDHC_IRQSTATEN)); + + /* The next phase of the hardware reset would be to set the SYSCTRL INITA + * bit to send 80 clock ticks for card to power up and then reset the card + * with CMD0. This is done elsewhere. + */ + + /* Reset state data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitints = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; /* Used to synchronize SDIO and DMA completion events */ +#endif + + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->buffer = 0; /* Address of current R/W buffer */ + priv->remaining = 0; /* Number of bytes remaining in the transfer */ + priv->xfrints = 0; /* Interrupt enables for data transfer */ +} + +/**************************************************************************** + * Name: kinetis_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see kinetis_status_* defines) + * + ****************************************************************************/ + +static uint8_t kinetis_status(FAR struct sdio_dev_s *dev) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: kinetis_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + uint32_t regval; + + /* Set the Data Transfer Width (DTW) field in the PROCTL register */ + + regval = getreg32(KINETIS_SDHC_PROCTL); + regval &= ~SDHC_PROCTL_DTW_MASK; + if (wide) + { + regval |= SDHC_PROCTL_DTW_4BIT; + } + else + { + regval |= SDHC_PROCTL_DTW_1BIT; + } + putreg32(regval, KINETIS_SDHC_PROCTL); +} + +/**************************************************************************** + * Name: kinetis_frequency + * + * Description: + * Set the SD clock frequency + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * frequency - The frequency to use + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_SDHC_ABSFREQ +static void kinetis_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency) +{ + uint32_t sdclkfs; + uint32_t prescaled; + uint32_t regval; + unsigned int prescaler; + unsigned int divisor; + + /* The SDCLK frequency is determined by (1) the frequency of the base clock + * that was selected as the input clock, and (2) by a prescaler and a + * divisor that are selected here: + * + * SDCLK frequency = (base clock) / (prescaler * divisor) + * + * The prescaler is avalable only for the values: 2, 4, 8, 16, 32, 64, 128, + * and 256. Pick the smallest value of SDCLKFS that would result in an + * in-range frequency. + * + * For example, if the base clock frequency is 96 MHz, and the target + * frequency is 25 MHz, the following logic will select prescaler. + * + * 96MHz / 2 <= 25MHz <= 96MHz / 2 /16 -- YES, prescaler == 2 + * + * If the target frequency is 400 kHz, the following logic will select + * prescaler: + * + * 96MHz / 2 <= 400KHz <= 96MHz / 2 / 16 -- NO + * 96MHz / 4 <= 400KHz <= 96MHz / 4 / 16 -- NO + * 96MHz / 8 <= 400KHz <= 96MHz / 8 / 16 -- NO + * 96MHz / 16 <= 400KHz <= 96MHz / 16 / 16 -- YES, prescaler == 16 + */ + + if (/* frequency >= (BOARD_CORECLK_FREQ / 2) && */ + frequency <= (BOARD_CORECLK_FREQ / 2 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV2; + prescaler = 2; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 4) && + frequency <= (BOARD_CORECLK_FREQ / 4 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV4; + prescaler = 4; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 8) && + frequency <= (BOARD_CORECLK_FREQ / 8 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV8; + prescaler = 8; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 16) && + frequency <= (BOARD_CORECLK_FREQ / 16 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV16; + prescaler = 16; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 32) && + frequency <= (BOARD_CORECLK_FREQ / 32 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV32; + prescaler = 32; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 64) && + frequency <= (BOARD_CORECLK_FREQ / 64 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV64; + prescaler = 64; + } + else if (frequency >= (BOARD_CORECLK_FREQ / 128) && + frequency <= (BOARD_CORECLK_FREQ / 128 / 16)) + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV128; + prescaler = 128; + } + else /* if (frequency >= (BOARD_CORECLK_FREQ / 256) && + * frequency <= (BOARD_CORECLK_FREQ / 256 / 16)) */ + { + sdclkfs = SDHC_SYSCTL_SDCLKFS_DIV256; + prescaler = 256; + } + + /* The optimal divider can than be calculated. + * + * For example, if the base clock frequency is 96 MHz, the target + * frequency is 25 MHz, and the selected prescaler value is 2, then + * + * prescaled = 96MHz / 2 = 48MHz + * divisor = (48MHz + 12.5HMz/ 25MHz = 2 + * + * And the resulting frequency will be 24MHz. + * + * Or, for example, if the target frequency is 400 kHz and the selected + * prescaler is 16, the following* logic will select prescaler: + * + * prescaled = 96MHz / 16 = 6MHz + * divisor = (6MHz + 200KHz) / 400KHz = 15 + * + * And the restuling frequency will be exactly 400KHz. + */ + + prescaled = frequency / prescaler; + divisor = (prescaled + (frequency >> 1)) / frequency; + + /* Set the new divisor information and enable all clocks in the SYSCTRL + * register. + * + * TODO: Investigate using the automatically gated clocks to reduce power + * consumption. + */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval &= ~(SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK); + regval |= (sdclkfs | SDHC_SYSCTL_DVS_DIV(divisor)); + regval |= (SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN | + SDHC_SYSCTL_IPGEN); + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); +} +#endif + +/**************************************************************************** + * Name: kinetis_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_SDHC_ABSFREQ +static void kinetis_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t frequency; + uint32_t regval; + + /* The SDCLK must be disabled before its frequency can be changed: "SDCLK + * frequency can be changed when this bit is 0. Then, the host controller + * shall maintain the same clock frequency until SDCLK is stopped (stop at + * SDCLK = 0). + */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval &= ~SDHC_SYSCTL_SDCLKEN; + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); + + switch (rate) + { + default: + case CLOCK_SDIO_DISABLED : /* Clock is disabled */ + { + /* Clear the prescaler and divisor settings and other clock + * enables as well. + */ + + regval &= ~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN | + SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK); + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); + return; + } + + case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */ + frequency = CONFIG_KINETIS_IDMODE_FREQ; + break; + + case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */ + frequency = CONFIG_KINETIS_MMCXFR_FREQ; + break; + + case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow 1-bit mode) */ +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + frequency = CONFIG_KINETIS_SD1BIT_FREQ; + break; +#endif + + case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide 4-bit mode) */ + frequency = CONFIG_KINETIS_SD4BIT_FREQ; + break; + } + + /* Then set the selected frequency */ + + kinetis_frequency(dev, frequency); +} +#else +static void kinetis_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t regval; + + /* The SDCLK must be disabled before its frequency can be changed: "SDCLK + * frequency can be changed when this bit is 0. Then, the host controller + * shall maintain the same clock frequency until SDCLK is stopped (stop at + * SDCLK = 0). + */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval &= ~SDHC_SYSCTL_SDCLKEN; + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); + + /* Clear the old prescaler and divisor values so that new ones can be ORed + * in. + */ + + regval &= ~(SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK); + + /* Select the new prescaler and divisor values based on the requested mode + * and the settings from the board.h file. + * + * TODO: Investigate using the automatically gated clocks to reduce power + * consumption. + */ + + switch (rate) + { + default: + case CLOCK_SDIO_DISABLED : /* Clock is disabled */ + { + /* Clear the prescaler and divisor settings and other clock + * enables as well. + */ + + regval &= ~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN); + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); + return; + } + + case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */ + regval |= (BOARD_SDHC_IDMODE_PRESCALER | BOARD_SDHC_IDMODE_DIVISOR | + SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN | + SDHC_SYSCTL_IPGEN); + break; + + case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */ + regval |= (BOARD_SDHC_MMCMODE_PRESCALER | BOARD_SDHC_MMCMODE_DIVISOR | + SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN | + SDHC_SYSCTL_IPGEN); + break; + + case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow + * 1-bit mode) */ +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + regval |= (BOARD_SDHC_SD1MODE_PRESCALER | BOARD_SDHC_IDMODE_DIVISOR | + SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN | + SDHC_SYSCTL_IPGEN); + break; +#endif + + case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide + * 4-bit mode) */ + regval |= (BOARD_SDHC_SD4MODE_PRESCALER | BOARD_SDHC_SD4MODE_DIVISOR | + SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN | + SDHC_SYSCTL_IPGEN); + break; + } + + putreg32(regval, KINETIS_SDHC_SYSCTL); + fvdbg("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL)); +} +#endif + +/**************************************************************************** + * Name: kinetis_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int kinetis_attach(FAR struct sdio_dev_s *dev) +{ + int ret; + + /* Attach the SDIO interrupt handler */ + + ret = irq_attach(KINETIS_IRQ_SDHC, kinetis_interrupt); + if (ret == OK) + { + + /* Disable all interrupts at the SDIO controller and clear all pending + * interrupts. + */ + + putreg32(0, KINETIS_SDHC_IRQSIGEN); + putreg32(SDHC_INT_ALL, KINETIS_SDHC_IRQSTAT); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(KINETIS_IRQ_SDHC, CONFIG_KINETIS_SDHC_PRIO); +#endif + + /* Enable SDIO interrupts at the NVIC. They can now be enabled at + * the SDIO controller as needed. + */ + + up_enable_irq(KINETIS_IRQ_SDHC); + } + + return ret; +} + +/**************************************************************************** + * Name: kinetis_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int kinetis_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) +{ + uint32_t regval; + uint32_t cmdidx; + int32_t timeout; + + /* Initialize the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval = cmdidx << SDHC_XFERTYP_CMDINX_SHIFT; + + /* Does a data transfer accompany the command? */ + + if ((cmd & MMCSD_DATAXFR) != 0) + { + /* Yes.. Configure the data transfer */ + + switch (cmd & MMCSD_DATAXFR_MASK) + { + default: + case MMCSD_NODATAXFR : /* No.. no data transfer */ + break; + + /* The following two cases are probably missing some setup logic */ + + case MMCSD_RDSTREAM : /* Yes.. streaming read data transfer */ + regval |= (SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_DTDSEL); + break; + + case MMCSD_WRSTREAM : /* Yes.. streaming write data transfer */ + regval |= SDHC_XFERTYP_DPSEL; + break; + + case MMCSD_RDDATAXFR : /* Yes.. normal read data transfer */ + regval |= (SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_DTDSEL); + break; + + case MMCSD_WRDATAXFR : /* Yes.. normal write data transfer */ + regval |= SDHC_XFERTYP_DPSEL; + break; + } + + /* Is it a multi-block transfer? */ + + if ((cmd & MMCSD_MULTIBLOCK) != 0) + { + /* Yes.. should the transfer be stopped with ACMD12? */ + + if ((cmd & MMCSD_STOPXFR) != 0) + { + /* Yes.. Indefinite block transfer */ + + regval |= (SDHC_XFERTYP_MSBSEL | SDHC_XFERTYP_AC12EN); + } + else + { + /* No.. Fixed block transfer */ + + regval |= (SDHC_XFERTYP_MSBSEL | SDHC_XFERTYP_BCEN); + } + } + } + + /* Configure response type bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: /* No response */ + regval |= SDHC_XFERTYP_RSPTYP_NONE; + break; + + case MMCSD_R1B_RESPONSE: /* Response length 48, check busy & cmdindex */ + regval |= (SDHC_XFERTYP_RSPTYP_LEN48BSY | SDHC_XFERTYP_CICEN | + SDHC_XFERTYP_CCCEN); + break; + + case MMCSD_R1_RESPONSE: /* Response length 48, check cmdindex */ + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + regval |= (SDHC_XFERTYP_RSPTYP_LEN48 | SDHC_XFERTYP_CICEN | + SDHC_XFERTYP_CCCEN); + break; + + case MMCSD_R2_RESPONSE: /* Response length 136, check CRC */ + regval |= (SDHC_XFERTYP_RSPTYP_LEN136 | SDHC_XFERTYP_CCCEN); + break; + + case MMCSD_R3_RESPONSE: /* Response length 48 */ + case MMCSD_R4_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= SDHC_XFERTYP_RSPTYP_LEN48; + break; + } + + /* Enable DMA */ + +#ifdef CONFIG_SDIO_DMA + /* Internal DMA is used */ + + regval |= SDHC_XFERTYP_DMAEN; +#endif + + /* Other bits? What about CMDTYP? */ + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + + /* The Command Inhibit (CIHB) bit is set in the PRSSTAT bit immediately + * after the transfer type register is written. This bit is cleared when + * the command response is received. If this status bit is 0, it + * indicates that the CMD line is not in use and the SDHC can issue a + * SD/MMC Command using the CMD line. + * + * CIHB should always be set when this function is called. + */ + + timeout = SDHC_CMDTIMEOUT; + while ((getreg32(KINETIS_SDHC_PRSSTAT) & SDHC_PRSSTAT_CIHB) != 0) + { + if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x PRSSTAT: %08x\n", + cmd, getreg32(KINETIS_SDHC_PRSSTAT)); + + return -EBUSY; + } + } + + /* Set the SDHC Argument value */ + + putreg32(arg, KINETIS_SDHC_CMDARG); + + /* Clear interrupt status and write the SDHC CMD */ + + putreg32(SDHC_RESPDONE_INTS, KINETIS_SDHC_IRQSTAT); + putreg32(regval, KINETIS_SDHC_XFERTYP); + return OK; +} + +/**************************************************************************** + * Name: kinetis_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer in which to receive the data + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef CONFIG_SDIO_DMA +static int kinetis_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + kinetis_datadisable(); + kinetis_sampleinit(); + kinetis_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; + + /* Then set up the SDIO data path */ + + kinetis_dataconfig(priv, false, nbytes, 1, SDHC_DVS_DATATIMEOUT); + + /* And enable interrupts */ + + kinetis_configxfrints(priv, SDHC_RCVDONE_INTS); + kinetis_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} +#endif + +/**************************************************************************** + * Name: kinetis_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer containing the data to send + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef CONFIG_SDIO_DMA +static int kinetis_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + kinetis_datadisable(); + kinetis_sampleinit(); + kinetis_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; + + /* Then set up the SDIO data path */ + + kinetis_dataconfig(priv, true, nbytes, 1, SDHC_DVS_DATATIMEOUT); + + /* Enable TX interrupts */ + + kinetis_configxfrints(priv, SDHC_SNDDONE_INTS); + kinetis_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} +#endif + +/**************************************************************************** + * Name: kinetis_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int kinetis_cancel(FAR struct sdio_dev_s *dev) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; +#ifdef CONFIG_SDIO_DMA + uint32_t regval; +#endif + + /* Disable all transfer- and event- related interrupts */ + + kinetis_configxfrints(priv, 0); + kinetis_configwaitints(priv, 0, 0, 0); + + /* Clearing pending interrupt status on all transfer- and event- related + * interrupts + */ + + putreg32(SDHC_WAITALL_INTS, KINETIS_SDHC_IRQSTAT); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + /* Stop the DMA by resetting the data path */ + + regval = getreg32(KINETIS_SDHC_SYSCTL); + regval |= SDHC_SYSCTL_RSTD; + putreg32(regval, KINETIS_SDHC_SYSCTL); +#endif + + /* Mark no transfer in progress */ + + priv->remaining = 0; + return OK; +} + +/**************************************************************************** + * Name: kinetis_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. This + * function should be called even after sending commands that have no + * response (such as CMD0) to make sure that the hardware is ready to + * receive the next command. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int kinetis_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + uint32_t errors; + int32_t timeout; + int ret = OK; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + timeout = SDHC_CMDTIMEOUT; + errors = 0; + return OK; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + timeout = SDHC_LONGTIMEOUT; + errors = SDHC_RESPERR_INTS; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + timeout = SDHC_CMDTIMEOUT; + errors = SDHC_RESPERR_INTS; + break; + + default: + return -EINVAL; + } + + /* Then wait for the Command Complete (CC) indication (or timeout). The + * CC bit is set when the end bit of the command response is received + * (except Auto CMD12). + */ + + while ((getreg32(KINETIS_SDHC_IRQSTAT) & SDHC_INT_CC) == 0) + { + if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x IRQSTAT: %08x\n", + cmd, getreg32(KINETIS_SDHC_IRQSTAT)); + + return -ETIMEDOUT; + } + } + + /* Check for hardware detected errors */ + + if ((getreg32(KINETIS_SDHC_IRQSTAT) & errors) != 0) + { + fdbg("ERROR: cmd: %08x errors: %08x IRQSTAT: %08x\n", + cmd, errors, getreg32(KINETIS_SDHC_IRQSTAT)); + ret = -EIO; + } + + /* Clear the response wait status bits */ + + putreg32(SDHC_RESPDONE_INTS, KINETIS_SDHC_IRQSTAT); + return ret; +} + +/**************************************************************************** + * Name: kinetis_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a faiure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intacta and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int kinetis_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) +{ + uint32_t regval; + int ret = OK; + + /* R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signalling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + */ + + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(KINETIS_SDHC_IRQSTAT); + if ((regval & SDHC_INT_CTOE) != 0) + { + fdbg("ERROR: Command timeout: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if ((regval & SDHC_INT_CCE) != 0) + { + fdbg("ERROR: CRC failure: %08x\n", regval); + ret = -EIO; + } + } + + /* Return the R1/R1b/R6 response. These responses are returned in + * CDMRSP0. NOTE: This is not true for R1b (Auto CMD12 response) which + * is returned in CMDRSP3. + */ + + *rshort = getreg32(KINETIS_SDHC_CMDRSP0); + return ret; +} + +static int kinetis_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + uint32_t regval; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(KINETIS_SDHC_IRQSTAT); + if (regval & SDHC_INT_CTOE) + { + fdbg("ERROR: Timeout IRQSTAT: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if (regval & SDHC_INT_CCE) + { + fdbg("ERROR: CRC fail IRQSTAT: %08x\n", regval); + ret = -EIO; + } + } + + /* Return the long response in CMDRSP3..0 */ + + if (rlong) + { + rlong[0] = getreg32(KINETIS_SDHC_CMDRSP3); + rlong[1] = getreg32(KINETIS_SDHC_CMDRSP2); + rlong[2] = getreg32(KINETIS_SDHC_CMDRSP1); + rlong[3] = getreg32(KINETIS_SDHC_CMDRSP0); + } + return ret; +} + +static int kinetis_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ + uint32_t regval; + int ret = OK; + + /* R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + + /* Check that this is the correct response to this command */ + +#ifdef CONFIG_DEBUG + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout occurred (Apparently a CRC error can terminate + * a good response) + */ + + regval = getreg32(KINETIS_SDHC_IRQSTAT); + if (regval & SDHC_INT_CTOE) + { + fdbg("ERROR: Timeout IRQSTAT: %08x\n", regval); + ret = -ETIMEDOUT; + } + } + + /* Return the short response in CMDRSP0 */ + + if (rshort) + { + *rshort = getreg32(KINETIS_SDHC_CMDRSP0); + } + + return ret; +} + +/* MMC responses not supported */ + +static int kinetis_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl) +{ + /* Just return an error */ + + return -ENOSYS; +} + +/**************************************************************************** + * Name: kinetis_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling kinetis_eventwait. This is done in this way + * to help the driver to eliminate race conditions between the command + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + uint32_t waitints; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + kinetis_configwaitints(priv, 0, 0, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + + waitints = 0; + if ((eventset & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0) + { + waitints |= SDHC_RESPDONE_INTS; + } + + if ((eventset & SDIOWAIT_TRANSFERDONE) != 0) + { + waitints |= SDHC_XFRDONE_INTS; + } + + /* Enable event-related interrupts */ + + kinetis_configwaitints(priv, waitints, eventset, 0); +} + +/**************************************************************************** + * Name: kinetis_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when kinetis_eventwait + * returns. SDIO_WAITEVENTS must be called again before kinetis_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + int ret; + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevents will + * be non-zero (and, hopefully, the semaphore count will also be non-zero. + */ + + DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) || + (priv->waitevents == 0 && priv->wkupevent != 0)); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a corner case */ + + if (!timeout) + { + return SDIOWAIT_TIMEOUT; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)kinetis_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling kinetis_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + kinetis_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a non-zero value. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + /* Disable event-related interrupts */ + + kinetis_configwaitints(priv, 0, 0, 0); +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + + kinetis_dumpsamples(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: kinetis_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in kinetis_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this method. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void kinetis_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + kinetis_callback(priv); +} + +/**************************************************************************** + * Name: kinetis_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int kinetis_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: kinetis_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool kinetis_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: kinetis_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int kinetis_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + kinetis_datadisable(); + + /* Begin sampling register values */ + + kinetis_sampleinit(); + kinetis_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + + /* Then set up the SDIO data path */ + + kinetis_dataconfig(priv, false, buflen, 1, SDHC_DVS_DATATIMEOUT); + + /* Configure the RX DMA */ + + kinetis_configxfrints(priv, SDHC_DMADONE_INTS); + putreg32((uint32_t)buffer, KINETIS_SDHC_DSADDR); + + /* Sample the register state */ + + kinetis_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} +#endif + +/**************************************************************************** + * Name: kinetis_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int kinetis_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + kinetis_datadisable(); + + /* Begin sampling register values */ + + kinetis_sampleinit(); + kinetis_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + + /* Then set up the SDIO data path */ + + kinetis_dataconfig(priv, true, buflen, 1, SDHC_DVS_DATATIMEOUT); + + /* Configure the TX DMA */ + + putreg32((uint32_t)buffer, KINETIS_SDHC_DSADDR); + + /* Sample the register state */ + + kinetis_sample(priv, SAMPLENDX_AFTER_SETUP); + + /* Enable TX interrupts */ + + kinetis_configxfrints(priv, SDHC_DMADONE_INTS); + return OK; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: kinetis_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void kinetis_callback(void *arg) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)arg; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* Callbacks cannot be performed in the context of an interrupt handler. + * If we are in an interrupt handler, then queue the callback to be + * performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + fvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + } + else + { + /* No.. then just call the callback here */ + + fvdbg("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdhc_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdhc_initialize(int slotno) +{ + uint32_t regval; + + /* There is only one slot */ + + struct kinetis_dev_s *priv = &g_sdhcdev; + DEBUGASSERT(slotno == 0); + + /* Initialize the SDHC slot structure data structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + + /* Enable clocking to the SDHC module. Clocking is still diabled in + * the SYSCTRL register. + */ + + regval = getreg32(KINETIS_SIM_SCGC3); + regval |= SIM_SCGC3_SDHC; + putreg32(regval, KINETIS_SIM_SCGC3); + fvdbg("SIM_SCGC3: %08x\n", regval); + + /* In addition to the system clock, the SDHC module needs a clock for the + * base for the external card clock. There are four possible sources for + * this clock, selected by the SIM's SOPT2 register: + * + * - Core/system clock + * - MCGPLLCLK/MCGFLLCLK clock + * - OSCERCLK EXTAL clock + * - External bypass clock from off-chip (SCHC0_CLKINB) + */ + + regval = getreg32(KINETIS_SIM_SOPT2); + regval &= ~SIM_SOPT2_SDHCSRC_MASK; + regval |= SIM_SOPT2_SDHCSRC_CORE; + putreg32(regval, KINETIS_SIM_SOPT2); + fvdbg("SIM_SOPT2: %08x\n", regval); + + /* Configure pins for 1 or 4-bit, wide-bus operation (the chip is capable + * of 8-bit wide bus operation but D4-D7 are not configured). + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. + */ + +#ifndef CONFIG_SDIO_MUXBUS + /* Data width 1, 4 or 8 */ + + kinetis_pinconfig(PIN_SDHC0_D0); + + /* Data width 4 or 8 */ + +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + kinetis_pinconfig(PIN_SDHC0_D1); + kinetis_pinconfig(PIN_SDHC0_D2); + kinetis_pinconfig(PIN_SDHC0_D3); + + /* Data width 8 (not supported) */ + +#if 0 + kinetis_pinconfig(PIN_SDHC0_D4); + kinetis_pinconfig(PIN_SDHC0_D5); + kinetis_pinconfig(PIN_SDHC0_D6); + kinetis_pinconfig(PIN_SDHC0_D7); +#endif +#endif + + /* Clocking and CMD pins (all data widths) */ + + kinetis_pinconfig(PIN_SDHC0_DCLK); + kinetis_pinconfig(PIN_SDHC0_CMD); +#endif + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + kinetis_reset(&priv->dev); + kinetis_showregs(priv, "After reset"); + return &g_sdhcdev.dev; +} + +/**************************************************************************** + * Name: sdhc_mediachange + * + * Description: + * Called by board-specific logic -- possible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdhc_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + fvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + kinetis_callback(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdhc_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} +#endif /* CONFIG_KINETIS_SDHC */ diff --git a/arch/arm/src/kinetis/kinetis_sdhc.h b/arch/arm/src/kinetis/kinetis_sdhc.h new file mode 100644 index 0000000000000000000000000000000000000000..5d122315a9d2efa426865fd396748ac3e0372434 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_sdhc.h @@ -0,0 +1,388 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_sdhc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_SDHC_DSADDR_OFFSET 0x0000 /* DMA System Address Register */ +#define KINETIS_SDHC_BLKATTR_OFFSET 0x0004 /* Block Attributes Register */ +#define KINETIS_SDHC_CMDARG_OFFSET 0x0008 /* Command Argument Register */ +#define KINETIS_SDHC_XFERTYP_OFFSET 0x000c /* Transfer Type Register */ +#define KINETIS_SDHC_CMDRSP0_OFFSET 0x0010 /* Command Response 0 */ +#define KINETIS_SDHC_CMDRSP1_OFFSET 0x0014 /* Command Response 1 */ +#define KINETIS_SDHC_CMDRSP2_OFFSET 0x0018 /* Command Response 2 */ +#define KINETIS_SDHC_CMDRSP3_OFFSET 0x001c /* Command Response 3 */ +#define KINETIS_SDHC_DATPORT_OFFSET 0x0020 /* Buffer Data Port Register */ +#define KINETIS_SDHC_PRSSTAT_OFFSET 0x0024 /* Present State Register */ +#define KINETIS_SDHC_PROCTL_OFFSET 0x0028 /* Protocol Control Register */ +#define KINETIS_SDHC_SYSCTL_OFFSET 0x002c /* System Control Register */ +#define KINETIS_SDHC_IRQSTAT_OFFSET 0x0030 /* Interrupt Status Register */ +#define KINETIS_SDHC_IRQSTATEN_OFFSET 0x0034 /* Interrupt Status Enable Register */ +#define KINETIS_SDHC_IRQSIGEN_OFFSET 0x0038 /* Interrupt Signal Enable Register */ +#define KINETIS_SDHC_AC12ERR_OFFSET 0x003c /* Auto CMD12 Error Status Register */ +#define KINETIS_SDHC_HTCAPBLT_OFFSET 0x0040 /* Host Controller Capabilities */ +#define KINETIS_SDHC_WML_OFFSET 0x0044 /* Watermark Level Register */ +#define KINETIS_SDHC_FEVT_OFFSET 0x0050 /* Force Event Register */ +#define KINETIS_SDHC_ADMAES_OFFSET 0x0054 /* ADMA Error Status Register */ +#define KINETIS_SDHC_ADSADDR_OFFSET 0x0058 /* ADMA System Address Register */ +#define KINETIS_SDHC_VENDOR_OFFSET 0x00c0 /* Vendor Specific Register */ +#define KINETIS_SDHC_MMCBOOT_OFFSET 0x00c4 /* MMC Boot Register */ +#define KINETIS_SDHC_HOSTVER_OFFSET 0x00fc /* Host Controller Version */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_SDHC_DSADDR (KINETIS_SDHC_BASE+KINETIS_SDHC_DSADDR_OFFSET) +#define KINETIS_SDHC_BLKATTR (KINETIS_SDHC_BASE+KINETIS_SDHC_BLKATTR_OFFSET) +#define KINETIS_SDHC_CMDARG (KINETIS_SDHC_BASE+KINETIS_SDHC_CMDARG_OFFSET) +#define KINETIS_SDHC_XFERTYP (KINETIS_SDHC_BASE+KINETIS_SDHC_XFERTYP_OFFSET) +#define KINETIS_SDHC_CMDRSP0 (KINETIS_SDHC_BASE+KINETIS_SDHC_CMDRSP0_OFFSET) +#define KINETIS_SDHC_CMDRSP1 (KINETIS_SDHC_BASE+KINETIS_SDHC_CMDRSP1_OFFSET) +#define KINETIS_SDHC_CMDRSP2 (KINETIS_SDHC_BASE+KINETIS_SDHC_CMDRSP2_OFFSET) +#define KINETIS_SDHC_CMDRSP3 (KINETIS_SDHC_BASE+KINETIS_SDHC_CMDRSP3_OFFSET) +#define KINETIS_SDHC_DATPORT (KINETIS_SDHC_BASE+KINETIS_SDHC_DATPORT_OFFSET) +#define KINETIS_SDHC_PRSSTAT (KINETIS_SDHC_BASE+KINETIS_SDHC_PRSSTAT_OFFSET) +#define KINETIS_SDHC_PROCTL (KINETIS_SDHC_BASE+KINETIS_SDHC_PROCTL_OFFSET) +#define KINETIS_SDHC_SYSCTL (KINETIS_SDHC_BASE+KINETIS_SDHC_SYSCTL_OFFSET) +#define KINETIS_SDHC_IRQSTAT (KINETIS_SDHC_BASE+KINETIS_SDHC_IRQSTAT_OFFSET) +#define KINETIS_SDHC_IRQSTATEN (KINETIS_SDHC_BASE+KINETIS_SDHC_IRQSTATEN_OFFSET) +#define KINETIS_SDHC_IRQSIGEN (KINETIS_SDHC_BASE+KINETIS_SDHC_IRQSIGEN_OFFSET) +#define KINETIS_SDHC_AC12ERR (KINETIS_SDHC_BASE+KINETIS_SDHC_AC12ERR_OFFSET) +#define KINETIS_SDHC_HTCAPBLT (KINETIS_SDHC_BASE+KINETIS_SDHC_HTCAPBLT_OFFSET) +#define KINETIS_SDHC_WML (KINETIS_SDHC_BASE+KINETIS_SDHC_WML_OFFSET) +#define KINETIS_SDHC_FEVT (KINETIS_SDHC_BASE+KINETIS_SDHC_FEVT_OFFSET) +#define KINETIS_SDHC_ADMAES (KINETIS_SDHC_BASE+KINETIS_SDHC_ADMAES_OFFSET) +#define KINETIS_SDHC_ADSADDR (KINETIS_SDHC_BASE+KINETIS_SDHC_ADSADDR_OFFSET) +#define KINETIS_SDHC_VENDOR (KINETIS_SDHC_BASE+KINETIS_SDHC_VENDOR_OFFSET) +#define KINETIS_SDHC_MMCBOOT (KINETIS_SDHC_BASE+KINETIS_SDHC_MMCBOOT_OFFSET) +#define KINETIS_SDHC_HOSTVER (KINETIS_SDHC_BASE+KINETIS_SDHC_HOSTVER_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* DMA System Address Register */ + +#define SDHC_DSADDR_SHIFT (1) /* Bits 1-31: DMA System Address */ +#define SDHC_DSADDR_MASK (0xfffffffe) + /* Bits 0-1: Reserved */ +/* Block Attributes Register */ + +#define SDHC_BLKATTR_SIZE_SHIFT (0) /* Bits 0-12: Transfer Block Size */ +#define SDHC_BLKATTR_SIZE_MASK (0x1fff << SDHC_BLKATTR_BLKSIZE_SHIFT) + /* Bits 13-15: Reserved */ +#define SDHC_BLKATTR_CNT_SHIFT (16) /* Bits 16-31: Blocks Count For Current Transfer */ +#define SDHC_BLKATTR_CNT_MASK (0xffff << SDHC_BLKATTR_BLKCNT_SHIFT) + +/* Command Argument Register (32-bit cmd/arg data) */ + +/* Transfer Type Register */ + +#define SDHC_XFERTYP_DMAEN (1 << 0) /* Bit 0: DMA Enable */ +#define SDHC_XFERTYP_BCEN (1 << 1) /* Bit 1: Block Count Enable */ +#define SDHC_XFERTYP_AC12EN (1 << 2) /* Bit 2: Auto CMD12 Enable */ + /* Bit 3: Reserved */ +#define SDHC_XFERTYP_DTDSEL (1 << 4) /* Bit 4: Data Transfer Direction Select */ +#define SDHC_XFERTYP_MSBSEL (1 << 5) /* Bit 5: Multi/Single Block Select */ + /* Bits 6-15: Reserved */ +#define SDHC_XFERTYP_RSPTYP_SHIFT (16) /* Bits 16-17: Response Type Select */ +#define SDHC_XFERTYP_RSPTYP_MASK (3 << SDHC_XFERTYP_RSPTYP_SHIFT) +# define SDHC_XFERTYP_RSPTYP_NONE (0 << SDHC_XFERTYP_RSPTYP_SHIFT) /* No response */ +# define SDHC_XFERTYP_RSPTYP_LEN136 (1 << SDHC_XFERTYP_RSPTYP_SHIFT) /* Response length 136 */ +# define SDHC_XFERTYP_RSPTYP_LEN48 (2 << SDHC_XFERTYP_RSPTYP_SHIFT) /* Response length 48 */ +# define SDHC_XFERTYP_RSPTYP_LEN48BSY (3 << SDHC_XFERTYP_RSPTYP_SHIFT) /* Response length 48, check busy */ + /* Bit 18: Reserved */ +#define SDHC_XFERTYP_CCCEN (1 << 19) /* Bit 19: Command CRC Check Enable */ +#define SDHC_XFERTYP_CICEN (1 << 20) /* Bit 20: Command Index Check Enable */ +#define SDHC_XFERTYP_DPSEL (1 << 21) /* Bit 21: Data Present Select */ +#define SDHC_XFERTYP_CMDTYP_SHIFT (22) /* Bits 22-23: Command Type */ +#define SDHC_XFERTYP_CMDTYP_MASK (3 << SDHC_XFERTYP_CMDTYP_SHIFT) +# define SDHC_XFERTYP_CMDTYP_NORMAL (0 << SDHC_XFERTYP_CMDTYP_SHIFT) /* Normal other commands */ +# define SDHC_XFERTYP_CMDTYP_SUSPEND (1 << SDHC_XFERTYP_CMDTYP_SHIFT) /* Suspend CMD52 for writing bus suspend in CCCR */ +# define SDHC_XFERTYP_CMDTYP_RESUME (2 << SDHC_XFERTYP_CMDTYP_SHIFT) /* Resume CMD52 for writing function select in CCCR */ +# define SDHC_XFERTYP_CMDTYP_ABORT (3 << SDHC_XFERTYP_CMDTYP_SHIFT) /* Abort CMD12, CMD52 for writing I/O abort in CCCR */ +#define SDHC_XFERTYP_CMDINX_SHIFT (24) /* Bits 24-29: Command Index */ +#define SDHC_XFERTYP_CMDINX_MASK (63 << SDHC_XFERTYP_CMDINX_SHIFT) + /* Bits 30-31: Reserved */ +/* Command Response 0-3 (32-bit response data) */ + +/* Buffer Data Port Register (32-bit data content) */ + +/* Present State Register */ + +#define SDHC_PRSSTAT_CIHB (1 << 0) /* Bit 0: Command Inhibit (CMD) */ +#define SDHC_PRSSTAT_CDIHB (1 << 1) /* Bit 1: Command Inhibit (DAT) */ +#define SDHC_PRSSTAT_DLA (1 << 2) /* Bit 2: Data Line Active */ +#define SDHC_PRSSTAT_SDSTB (1 << 3) /* Bit 3: SD Clock Stable */ +#define SDHC_PRSSTAT_IPGOFF (1 << 4) /* Bit 4: Bus Clock */ +#define SDHC_PRSSTAT_HCKOFF (1 << 5) /* Bit 5: System Clock */ +#define SDHC_PRSSTAT_PEROFF (1 << 6) /* Bit 6: SDHC clock */ +#define SDHC_PRSSTAT_SDOFF (1 << 7) /* Bit 7: SD Clock Gated Off Internally */ +#define SDHC_PRSSTAT_WTA (1 << 8) /* Bit 8: Write Transfer Active */ +#define SDHC_PRSSTAT_RTA (1 << 9) /* Bit 9: Read Transfer Active */ +#define SDHC_PRSSTAT_BWEN (1 << 10) /* Bit 10: Buffer Write Enable */ +#define SDHC_PRSSTAT_BREN (1 << 11) /* Bit 11: Buffer Read Enable */ + /* Bits 12-15: Reserved */ +#define SDHC_PRSSTAT_CINS (1 << 16) /* Bit 16: Card Inserted */ + /* Bits 17-22: Reserved */ +#define SDHC_PRSSTAT_CLSL (1 << 23) /* Bit 23: CMD Line Signal Level */ +#define SDHC_PRSSTAT_DLSL_SHIFT (24) /* Bits 24-31: DAT Line Signal Level */ +#define SDHC_PRSSTAT_DLSL_MASK (0xff << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT0 (0x01 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT1 (0x02 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT2 (0x04 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT3 (0x08 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT4 (0x10 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT5 (0x20 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT6 (0x40 << SDHC_PRSSTAT_DLSL_SHIFT) +# define SDHC_PRSSTAT_DLSL_DAT7 (0x80 << SDHC_PRSSTAT_DLSL_SHIFT) + +/* Protocol Control Register */ + +#define SDHC_PROCTL_LCTL (1 << 0) /* Bit 0: LED Control */ +#define SDHC_PROCTL_DTW_SHIFT (1) /* Bits 1-2: Data Transfer Width */ +#define SDHC_PROCTL_DTW_MASK (3 << SDHC_PROCTL_DTW_SHIFT) +# define SDHC_PROCTL_DTW_1BIT (0 << SDHC_PROCTL_DTW_SHIFT) /* 1-bit mode */ +# define SDHC_PROCTL_DTW_4BIT (1 << SDHC_PROCTL_DTW_SHIFT) /* 4-bit mode */ +# define SDHC_PROCTL_DTW_8BIT (2 << SDHC_PROCTL_DTW_SHIFT) /* 8-bit mode */ +#define SDHC_PROCTL_D3CD (1 << 3) /* Bit nn: DAT3 as Card Detection Pin */ +#define SDHC_PROCTL_EMODE_SHIFT (4) /* Bits 4-5: Endian mode */ +#define SDHC_PROCTL_EMODE_MASK (3 << SDHC_PROCTL_EMODE_SHIFT) +# define SDHC_PROCTL_EMODE_BE (0 << SDHC_PROCTL_EMODE_SHIFT) /* Big endian mode */ +# define SDHC_PROCTL_EMODE_HWBE (1 << SDHC_PROCTL_EMODE_SHIFT) /* Half word big endian mode */ +# define SDHC_PROCTL_EMODE_LE (2 << SDHC_PROCTL_EMODE_SHIFT) /* Little endian mode */ +#define SDHC_PROCTL_CDTL (1 << 6) /* Bit 6: Card Detect Test Level */ +#define SDHC_PROCTL_CDSS (1 << 7) /* Bit 7: Card Detect Signal Selection */ +#define SDHC_PROCTL_DMAS_SHIFT (8) /* Bits 8-9: DMA Select */ +#define SDHC_PROCTL_DMAS_MASK (3 << SDHC_PROCTL_DMAS_SHIFT) +# define SDHC_PROCTL_DMAS_NODMA (0 << SDHC_PROCTL_DMAS_SHIFT) /* No DMA or simple DMA is selected */ +# define SDHC_PROCTL_DMAS_ADMA1 (1 << SDHC_PROCTL_DMAS_SHIFT) /* ADMA1 is selected */ +# define SDHC_PROCTL_DMAS_ADMA2 (2 << SDHC_PROCTL_DMAS_SHIFT) /* ADMA2 is selected */ + /* Bits 10-15: Reserved */ +#define SDHC_PROCTL_SABGREQ (1 << 16) /* Bit 16: Stop At Block Gap Request */ +#define SDHC_PROCTL_CREQ (1 << 17) /* Bit 17: Continue Request */ +#define SDHC_PROCTL_RWCTL (1 << 18) /* Bit 18: Read Wait Control */ +#define SDHC_PROCTL_IABG (1 << 19) /* Bit 19: Interrupt At Block Gap */ + /* Bits 20-23: Reserved */ +#define SDHC_PROCTL_WECINT (1 << 24) /* Bit 24: Wakeup Event Enable On Card Interrupt */ +#define SDHC_PROCTL_WECINS (1 << 25) /* Bit 25: Wakeup Event Enable On SD Card Insertion */ +#define SDHC_PROCTL_WECRM (1 << 26) /* Bit 26: Wakeup Event Enable On SD Card Removal */ + /* Bits 27-31: Reserved */ +/* System Control Register */ + +#define SDHC_SYSCTL_IPGEN (1 << 0) /* Bit 0: IPG Clock Enable */ +#define SDHC_SYSCTL_HCKEN (1 << 1) /* Bit 1: System Clock Enable */ +#define SDHC_SYSCTL_PEREN (1 << 2) /* Bit 2: Peripheral Clock Enable */ +#define SDHC_SYSCTL_SDCLKEN (1 << 3) /* Bit 3: SD Clock Enable */ +#define SDHC_SYSCTL_DVS_SHIFT (4) /* Bits 4-7: Divisor */ +#define SDHC_SYSCTL_DVS_MASK (15 << SDHC_SYSCTL_DVS_SHIFT) +# define SDHC_SYSCTL_DVS_DIV(n) (((n)-1) << SDHC_SYSCTL_DVS_SHIFT) /* Divide by n, n=1..16 */ +#define SDHC_SYSCTL_SDCLKFS_SHIFT (8) /* Bits 8-15: SDCLK Frequency Select */ +#define SDHC_SYSCTL_SDCLKFS_MASK (0xff << SDHC_SYSCTL_SDCLKFS_SHIFT) +# define SDHC_SYSCTL_SDCLKFS_BYPASS (0x00 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Bypass the prescaler */ +# define SDHC_SYSCTL_SDCLKFS_DIV2 (0x01 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 2 */ +# define SDHC_SYSCTL_SDCLKFS_DIV4 (0x02 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 4 */ +# define SDHC_SYSCTL_SDCLKFS_DIV8 (0x04 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 8 */ +# define SDHC_SYSCTL_SDCLKFS_DIV16 (0x08 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 16 */ +# define SDHC_SYSCTL_SDCLKFS_DIV32 (0x10 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 32 */ +# define SDHC_SYSCTL_SDCLKFS_DIV64 (0x20 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 64 */ +# define SDHC_SYSCTL_SDCLKFS_DIV128 (0x40 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 128 */ +# define SDHC_SYSCTL_SDCLKFS_DIV256 (0x80 << SDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 256 */ +#define SDHC_SYSCTL_DTOCV_SHIFT (16) /* Bits 16-19: Data Timeout Counter Value */ +#define SDHC_SYSCTL_DTOCV_MASK (15 << SDHC_SYSCTL_DTOCV_SHIFT) +# define SDHC_SYSCTL_DTOCV_MUL(n) (((n)-213) << SDHC_SYSCTL_DTOCV_SHIFT) /* SDCLK x n, n=213..227 */ + /* Bits 20-23: Reserved */ +#define SDHC_SYSCTL_RSTA (1 << 24) /* Bit 24: Software Reset For ALL */ +#define SDHC_SYSCTL_RSTC (1 << 25) /* Bit 25: Software Reset For CMD Line */ +#define SDHC_SYSCTL_RSTD (1 << 26) /* Bit 26: Software Reset For DAT Line */ +#define SDHC_SYSCTL_INITA (1 << 27) /* Bit 27: Initialization Active */ + /* Bits 28-31: Reserved */ +/* Interrupt Status Register, Interrupt Status Enable Register, and Interrupt Signal Enable Register + * Common interrupt bit definitions + */ + +#define SDHC_INT_CC (1 << 0) /* Bit 0: Command Complete */ +#define SDHC_INT_TC (1 << 1) /* Bit 1: Transfer Complete */ +#define SDHC_INT_BGE (1 << 2) /* Bit 2: Block Gap Event */ +#define SDHC_INT_DINT (1 << 3) /* Bit 3: DMA Interrupt */ +#define SDHC_INT_BWR (1 << 4) /* Bit 4: Buffer Write Ready */ +#define SDHC_INT_BRR (1 << 5) /* Bit 5: Buffer Read Ready */ +#define SDHC_INT_CINS (1 << 6) /* Bit 6: Card Insertion */ +#define SDHC_INT_CRM (1 << 7) /* Bit 7: Card Removal */ +#define SDHC_INT_CINT (1 << 8) /* Bit 8: Card Interrupt */ + /* Bits 9-15: Reserved */ +#define SDHC_INT_CTOE (1 << 16) /* Bit 16: Command Timeout Error */ +#define SDHC_INT_CCE (1 << 17) /* Bit 17: Command CRC Error */ +#define SDHC_INT_CEBE (1 << 18) /* Bit 18: Command End Bit Error */ +#define SDHC_INT_CIE (1 << 19) /* Bit 19: Command Index Error */ +#define SDHC_INT_DTOE (1 << 20) /* Bit 20: Data Timeout Error */ +#define SDHC_INT_DCE (1 << 21) /* Bit 21: Data CRC Error */ +#define SDHC_INT_DEBE (1 << 22) /* Bit 22: Data End Bit Error */ + /* Bit 23: Reserved */ +#define SDHC_INT_AC12E (1 << 24) /* Bit 24: Auto CMD12 Error */ + /* Bits 25-27: Reserved */ +#define SDHC_INT_DMAE (1 << 28) /* Bit 28: DMA Error */ + /* Bits 29-31: Reserved */ +#define SDHC_INT_ALL 0x117f01ff + +/* Auto CMD12 Error Status Register */ + +#define SDHC_AC12ERR_NE (1 << 0) /* Bit 0: Auto CMD12 Not Executed */ +#define SDHC_AC12ERR_TOE (1 << 1) /* Bit 1: Auto CMD12 Timeout Error */ +#define SDHC_AC12ERR_EBE (1 << 2) /* Bit 2: Auto CMD12 End Bit Error */ +#define SDHC_AC12ERR_CE (1 << 3) /* Bit 3: Auto CMD12 CRC Error */ +#define SDHC_AC12ERR_IE (1 << 4) /* Bit 4: Auto CMD12 Index Error */ + /* Bits 5-6: Reserved */ +#define SDHC_AC12ERR_CNI (1 << 7) /* Bit 7: Command Not Issued By Auto CMD12 Error */ + /* Bits 8-31: Reserved */ +/* Host Controller Capabilities */ + /* Bits 0-15: Reserved */ +#define SDHC_HTCAPBLT_MBL_SHIFT (16) /* Bits 16-18: Max Block Length */ +#define SDHC_HTCAPBLT_MBL_MASK (7 << SDHC_HTCAPBLT_MBL_SHIFT) +# define SDHC_HTCAPBLT_MBL_512BYTES (0 << SDHC_HTCAPBLT_MBL_SHIFT) +# define SDHC_HTCAPBLT_MBL_1KB (1 << SDHC_HTCAPBLT_MBL_SHIFT) +# define SDHC_HTCAPBLT_MBL_2KB (2 << SDHC_HTCAPBLT_MBL_SHIFT) +# define SDHC_HTCAPBLT_MBL_4KB (3 << SDHC_HTCAPBLT_MBL_SHIFT) + /* Bit 19: Reserved */ +#define SDHC_HTCAPBLT_ADMAS (1 << 20) /* Bit 20: ADMA Support */ +#define SDHC_HTCAPBLT_HSS (1 << 21) /* Bit 21: High Speed Support */ +#define SDHC_HTCAPBLT_DMAS (1 << 22) /* Bit 22: DMA Support */ +#define SDHC_HTCAPBLT_SRS (1 << 23) /* Bit 23: Suspend/Resume Support */ +#define SDHC_HTCAPBLT_VS33 (1 << 24) /* Bit 24: Voltage Support 3.3 V */ +#define SDHC_HTCAPBLT_VS30 (1 << 25) /* Bit 25: Voltage Support 3.0 V */ +#define SDHC_HTCAPBLT_VS18 (1 << 26) /* Bit 26: Voltage Support 1.8 */ + /* Bits 27-31: Reserved */ +/* Watermark Level Register */ + +#define SDHC_WML_RD_SHIFT (0) /* Bits 0-7: Read Watermark Level */ +#define SDHC_WML_RD_MASK (0xff << SDHC_WML_RDWML_SHIFT) + /* Bits 8-15: Reserved */ +#define SDHC_WML_WR_SHIFT (16) /* Bits 16-23: Write Watermark Level */ +#define SDHC_WML_WR_MASK (0xff << SDHC_WML_WRWML_SHIFT) + /* Bits 24-31: Reserved */ +/* Force Event Register */ + +#define SDHC_FEVT_AC12NE (1 << 0) /* Bit 0: Force Event Auto Command 12 Not Executed */ +#define SDHC_FEVT_AC12TOE (1 << 1) /* Bit 1: Force Event Auto Command 12 Time Out Error */ +#define SDHC_FEVT_AC12CE (1 << 2) /* Bit 2: Force Event Auto Command 12 CRC Error */ +#define SDHC_FEVT_AC12EBE (1 << 3) /* Bit 3: Force Event Auto Command 12 End Bit Error */ +#define SDHC_FEVT_AC12IE (1 << 4) /* Bit 4: Force Event Auto Command 12 Index Error */ + /* Bits 5-6: Reserved */ +#define SDHC_FEVT_CNIBAC12E (1 << 7) /* Bit 7: Force Event Command Not Executed By Auto Command 12 Error */ + /* Bits 8-15: Reserved */ +#define SDHC_FEVT_CTOE (1 << 16) /* Bit 16: Force Event Command Time Out Error */ +#define SDHC_FEVT_CCE (1 << 17) /* Bit 17: Force Event Command CRC Error */ +#define SDHC_FEVT_CEBE (1 << 18) /* Bit 18: Force Event Command End Bit Error */ +#define SDHC_FEVT_CIE (1 << 19) /* Bit 19: Force Event Command Index Error */ +#define SDHC_FEVT_DTOE (1 << 20) /* Bit 20: Force Event Data Time Out Error */ +#define SDHC_FEVT_DCE (1 << 21) /* Bit 21: Force Event Data CRC Error */ +#define SDHC_FEVT_DEBE (1 << 22) /* Bit 22: Force Event Data End Bit Error */ + /* Bit 23: Reserved */ +#define SDHC_FEVT_AC12E (1 << 24) /* Bit 24: Force Event Auto Command 12 Error */ + /* Bits 25-27: Reserved */ +#define SDHC_FEVT_DMAE (1 << 28) /* Bit 28: Force Event DMA Error */ + /* Bits 29-30: Reserved */ +#define SDHC_FEVT_CINT (1 << 31) /* Bit 31: Force Event Card Interrupt */ + +/* ADMA Error Status Register */ + +#define SDHC_ADMAES_SHIFT (0) /* Bits 0-1: ADMA Error State (when ADMA Error is occurred) */ +#define SDHC_ADMAES_MASK (3 << SDHC_ADMAES_ADMAES_SHIFT) +# define SDHC_ADMAES_STOP (0 << SDHC_ADMAES_ADMAES_SHIFT) /* Stop DMA */ +# define SDHC_ADMAES_FDS (1 << SDHC_ADMAES_ADMAES_SHIFT) /* Fetch descriptor */ +# define SDHC_ADMAES_CADR (2 << SDHC_ADMAES_ADMAES_SHIFT) /* Change address */ +# define SDHC_ADMAES_TFR (3 << SDHC_ADMAES_ADMAES_SHIFT) /* Transfer data */ +#define SDHC_ADMAES_LME (1 << 2) /* Bit 2: ADMA Length Mismatch Error */ +#define SDHC_ADMAES_DCE (1 << 3) /* Bit 3: ADMA Descriptor Error */ + /* Bits 4-31: Reserved */ +/* ADMA System Address Register */ + +#define SDHC_ADSADDR_SHIFT (1) /* Bits 1-31: ADMA System Address */ +#define SDHC_ADSADDR_MASK (0xfffffffe) + /* Bits 0-1: Reserved */ + +/* Vendor Specific Register */ + +#define SDHC_VENDOR_EXTDMAEN (1 << 0) /* Bit 0: External DMA Request Enable */ +#define SDHC_VENDOR_EXBLKNU (1 << 1) /* Bit 1: Exact block number block read enable for SDIO CMD53 */ + /* Bits 2-15: Reserved */ +#define SDHC_VENDOR_INTSTVAL_SHIFT (16) /* Bits 16-23: Internal State Value */ +#define SDHC_VENDOR_INTSTVAL_MASK (0xff << SDHC_VENDOR_INTSTVAL_SHIFT) + /* Bits 24-31: Reserved */ +/* MMC Boot Register */ + +#define SDHC_MMCBOOT_DTOCVACK_SHIFT (0) /* Bits 0-3: Boot ACK time out counter value */ +#define SDHC_MMCBOOT_DTOCVACK_MASK (15 << SDHC_MMCBOOT_DTOCVACK_SHIFT) +# define SDHC_MMCBOOT_DTOCVACK_MUL(n) ((n-8) << SDHC_MMCBOOT_DTOCVACK_SHIFT) /* SDCLK x 2^n, n=8..22 */ +#define SDHC_MMCBOOT_BOOTACK (1 << 4) /* Bit 4: Boot ack mode select */ +#define SDHC_MMCBOOT_BOOTMODE (1 << 5) /* Bit 5: Boot mode select */ +#define SDHC_MMCBOOT_BOOTEN (1 << 6) /* Bit 6: Boot mode enable */ +#define SDHC_MMCBOOT_AUTOSABGEN (1 << 7) /* Bit 7: Enable auto stop at block gap function */ + /* Bits 8-15: Reserved */ +#define SDHC_MMCBOOT_BOOTBLKCNT_SHIFT (16) /* Bits 16-31: Stop at block gap value of automatic mode */ +#define SDHC_MMCBOOT_BOOTBLKCNT_MASK (0xffff << SDHC_MMCBOOT_BOOTBLKCNT_SHIFT) + +/* Host Controller Version */ + +#define SDHC_HOSTVER_SVN_SHIFT (0) /* Bits 0-7: Specification Version Number */ +#define SDHC_HOSTVER_SVN_MASK (0xff << SDHC_HOSTVER_SVN_SHIFT) +#define SDHC_HOSTVER_VVN_SHIFT (8) /* Bits 8-15: Vendor Version Number */ +#define SDHC_HOSTVER_VVN_MASK (0xff << SDHC_HOSTVER_VVN_SHIFT) + /* Bits 16-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H */ diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..550ff55917d5a613f893164ea9a74ba147e4f219 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_serial.c @@ -0,0 +1,1356 @@ +/**************************************************************************** + * arch/mips/src/kinetis/kinetis_serial.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kinetis_config.h" +#include "chip.h" +#include "kinetis_uart.h" +#include "kinetis.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Is there at least one UART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_UART_DEVICE +# warning "No UARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-5 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART5 is console */ +# define TTYS5_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_KINETIS_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_KINETIS_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_KINETIS_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_KINETIS_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_KINETIS_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_KINETIS_UART5) +# define TTYS0_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-5 excluding the console UART. */ + +#if defined(CONFIG_KINETIS_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART5) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-5. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-5 could also be the + * console. + */ + +#if defined(CONFIG_KINETIS_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART5) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-5. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-5 could also be the console. + */ + +#if defined(CONFIG_KINETIS_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART5) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART3-5. It can't be UART0-2 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 3-5 could also be the console. + */ + +#if defined(CONFIG_KINETIS_UART3) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart3port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART5) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART4-5. It can't be UART0-3 because + * those have already been assigned to ttsyS0, 1, 2, 3 or 4. One of + * UART 4-5 could also be the console. + */ + +#if defined(CONFIG_KINETIS_UART4) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_KINETIS_UART5) && !defined(UART5_ASSIGNED) +# define TTYS5_DEV g_uart5port /* UART5 is ttyS5 */ +# define UART5_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t clock; /* Clocking frequency of the UART module */ +#ifdef CONFIG_DEBUG + uint8_t irqe; /* Error IRQ associated with this UART (for enable) */ +#endif + uint8_t irqs; /* Status IRQ associated with this UART (for enable) */ + uint8_t irqprio; /* Interrupt priority */ + uint8_t ie; /* Interrupts enabled */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +#ifdef CONFIG_DEBUG +static int up_interrupte(int irq, void *context); +#endif +static int up_interrupts(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +#ifdef CONFIG_KINETIS_UARTFIFOS +static bool up_txempty(struct uart_dev_s *dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, +#ifdef CONFIG_KINETIS_UARTFIFOS + .txempty = up_txempty, +#else + .txempty = up_txready, +#endif +}; + +/* I/O buffers */ + +#ifdef CONFIG_KINETIS_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_KINETIS_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_KINETIS_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_KINETIS_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_KINETIS_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#ifdef CONFIG_KINETIS_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif + +/* This describes the state of the Kinetis UART0 port. */ + +#ifdef CONFIG_KINETIS_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = KINETIS_UART0_BASE, + .clock = BOARD_CORECLK_FREQ, + .baud = CONFIG_UART0_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART0E, +#endif + .irqs = KINETIS_IRQ_UART0S, + .irqprio = CONFIG_KINETIS_UART0PRIO, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the Kinetis UART1 port. */ + +#ifdef CONFIG_KINETIS_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = KINETIS_UART1_BASE, + .clock = BOARD_CORECLK_FREQ, + .baud = CONFIG_UART1_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART1E, +#endif + .irqs = KINETIS_IRQ_UART1S, + .irqprio = CONFIG_KINETIS_UART1PRIO, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the Kinetis UART2 port. */ + +#ifdef CONFIG_KINETIS_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = KINETIS_UART2_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART2_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART2E, +#endif + .irqs = KINETIS_IRQ_UART2S, + .irqprio = CONFIG_KINETIS_UART2PRIO, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the Kinetis UART3 port. */ + +#ifdef CONFIG_KINETIS_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = KINETIS_UART3_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART3_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART3E, +#endif + .irqs = KINETIS_IRQ_UART3S, + .irqprio = CONFIG_KINETIS_UART3PRIO, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the Kinetis UART4 port. */ + +#ifdef CONFIG_KINETIS_UART4 +static struct up_dev_s g_uart4priv = +{ + .uartbase = KINETIS_UART4_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART4_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART4E, +#endif + .irqs = KINETIS_IRQ_UART4S, + .irqprio = CONFIG_KINETIS_UART4PRIO, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the Kinetis UART5 port. */ + +#ifdef CONFIG_KINETIS_UART5 +static struct up_dev_s g_uart5priv = +{ + .uartbase = KINETIS_UART5_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART5_BAUD, +#ifdef CONFIG_DEBUG + .irqe = KINETIS_IRQ_UART5E, +#endif + .irqs = KINETIS_IRQ_UART5S, + .irqprio = CONFIG_KINETIS_UART5PRIO, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, +}; + +static uart_dev_t g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_setuartint + ****************************************************************************/ + +static void up_setuartint(struct up_dev_s *priv) +{ + irqstate_t flags; + uint8_t regval; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ + + flags = enter_critical_section(); + regval = up_serialin(priv, KINETIS_UART_C2_OFFSET); + regval &= ~UART_C2_ALLINTS; + regval |= priv->ie; + up_serialout(priv, KINETIS_UART_C2_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint8_t ie) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ + + flags = enter_critical_section(); + priv->ie = ie & UART_C2_ALLINTS; + up_setuartint(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint8_t *ie) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ie) + { + *ie = priv->ie; + } + + up_restoreuartint(priv, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Configure the UART as an RS-232 UART */ + + kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock, + priv->parity, priv->bits); +#endif + + /* Make sure that all interrupts are disabled */ + + up_restoreuartint(priv, 0); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set up the interrupt priority */ + + up_prioritize_irq(priv->irqs, priv->irqprio); +#ifdef CONFIG_DEBUG + up_prioritize_irq(priv->irqe, priv->irqprio); +#endif +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); + + /* Reset hardware and disable Rx and Tx */ + + kinetis_uartreset(priv->uartbase); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(priv->irqs, up_interrupts); +#ifdef CONFIG_DEBUG + if (ret == OK) + { + ret = irq_attach(priv->irqe, up_interrupte); + } +#endif + + if (ret == OK) + { +#ifdef CONFIG_DEBUG + up_enable_irq(priv->irqe); +#endif + up_enable_irq(priv->irqs); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); +#ifdef CONFIG_DEBUG + up_disable_irq(priv->irqe); +#endif + up_disable_irq(priv->irqs); + + /* Detach from the interrupt(s) */ + + irq_detach(priv->irqs); +#ifdef CONFIG_DEBUG + irq_detach(priv->irqe); +#endif +} + +/**************************************************************************** + * Name: up_interrupte + * + * Description: + * This is the UART error interrupt handler. It will be invoked when an + * interrupt received on the 'irq' + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int up_interrupte(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint8_t regval; + +#ifdef CONFIG_KINETIS_UART0 + if (g_uart0priv.irqe == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART1 + if (g_uart1priv.irqe == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART2 + if (g_uart2priv.irqe == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART3 + if (g_uart3priv.irqe == irq) + { + dev = &g_uart3port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART4 + if (g_uart4priv.irqe == irq) + { + dev = &g_uart4port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART5 + if (g_uart5priv.irqe == irq) + { + dev = &g_uart5port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv); + + /* Handle error interrupts. This interrupt may be caused by: + * + * FE: Framing error. To clear FE, read S1 with FE set and then read the + * UART data register (D). + * NF: Noise flag. To clear NF, read S1 and then read the UART data + * register (D). + * PF: Parity error flag. To clear PF, read S1 and then read the UART data + * register (D). + */ + + regval = up_serialin(priv, KINETIS_UART_S1_OFFSET); + lldbg("S1: %02x\n", regval); + regval = up_serialin(priv, KINETIS_UART_D_OFFSET); + return OK; +} +#endif /* CONFIG_DEBUG */ + +/**************************************************************************** + * Name: up_interrupts + * + * Description: + * This is the UART status interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupts(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + int passes; +#ifdef CONFIG_KINETIS_UARTFIFOS + unsigned int count; +#else + uint8_t s1; +#endif + bool handled; + +#ifdef CONFIG_KINETIS_UART0 + if (g_uart0priv.irqs == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART1 + if (g_uart1priv.irqs == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART2 + if (g_uart2priv.irqs == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART3 + if (g_uart3priv.irqs == irq) + { + dev = &g_uart3port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART4 + if (g_uart4priv.irqs == irq) + { + dev = &g_uart4port; + } + else +#endif +#ifdef CONFIG_KINETIS_UART5 + if (g_uart5priv.irq == irqs) + { + dev = &g_uart5port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv); + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Read status register 1 */ + +#ifndef CONFIG_KINETIS_UARTFIFOS + s1 = up_serialin(priv, KINETIS_UART_S1_OFFSET); +#endif + + /* Handle incoming, receive bytes */ + +#ifdef CONFIG_KINETIS_UARTFIFOS + /* Check the count of bytes in the RX FIFO */ + + count = up_serialin(priv, KINETIS_UART_RCFIFO_OFFSET); + if (count > 0) +#else + /* Check if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + * + * The RDRF status indication is cleared when the data is read from + * the RX data register. + */ + + if ((s1 & UART_S1_RDRF) != 0) +#endif + { + /* Process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + +#ifdef CONFIG_KINETIS_UARTFIFOS + /* Read the number of bytes currently in the FIFO and compare that to + * the size of the FIFO. If there are fewer bytes in the FIFO than + * the size of the FIFO, then we are able to transmit. + */ + +# error "Missing logic" +#else + /* Check if the transmit data register is "empty." NOTE: If FIFOS + * are enabled, this does not mean that the FIFO is empty, rather, + * it means that the number of bytes in the TX FIFO is below the + * watermark setting. There could actually be space for additional TX + * data. + * + * The TDRE status indication is cleared when the data is written to + * the TX data register. + */ + + if ((s1 & UART_S1_TDRE) != 0) +#endif + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + struct inode *inode; + struct uart_dev_s *dev; + struct up_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct up_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint8_t s1; + + /* Get error status information: + * + * FE: Framing error. To clear FE, read S1 with FE set and then read + * read UART data register (D). + * NF: Noise flag. To clear NF, read S1 and then read the UART data + * register (D). + * PF: Parity error flag. To clear PF, read S1 and then read the UART + * data register (D). + */ + + s1 = up_serialin(priv, KINETIS_UART_S1_OFFSET); + + /* Return status information */ + + if (status) + { + *status = (uint32_t)s1; + } + + /* Then return the actual received byte. Reading S1 then D clears all + * RX errors. + */ + + return (int)up_serialin(priv, KINETIS_UART_D_OFFSET); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_RIE; + up_setuartint(priv); +#endif + } + else + { +#ifdef CONFIG_DEBUG +# warning "Revisit: How are errors enabled?" + priv->ie |= UART_C2_RIE; +#else + priv->ie |= UART_C2_RIE; +#endif + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#ifdef CONFIG_KINETIS_UARTFIFOS + unsigned int count; + + /* Return true if there are any bytes in the RX FIFO */ + + count = up_serialin(priv, KINETIS_UART_RCFIFO_OFFSET); + return count > 0; +#else + /* Return true if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + */ + + return (up_serialin(priv, KINETIS_UART_S1_OFFSET) & UART_S1_RDRF) != 0; +#endif +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, KINETIS_UART_D_OFFSET, (uint8_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_TIE; + up_setuartint(priv); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ie &= ~UART_C2_TIE; + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifdef CONFIG_KINETIS_UARTFIFOS + /* Read the number of bytes currently in the FIFO and compare that to the + * size of the FIFO. If there are fewer bytes in the FIFO than the size + * of the FIFO, then we are able to transmit. + */ + +# error "Missing logic" +#else + /* Return true if the transmit data register is "empty." NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is empty, + * rather, it means that the number of bytes in the TX FIFO is + * below the watermark setting. There may actually be space for + * additional TX data. + */ + + return (up_serialin(priv, KINETIS_UART_S1_OFFSET) & UART_S1_TDRE) != 0; +#endif +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_UARTFIFOS +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true if the transmit buffer/fifo is "empty." */ + + return (up_serialin(priv, KINETIS_UART_SFIFO_OFFSET) & UART_SFIFO_TXEMPT) != 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit() + */ + + up_restoreuartint(TTYS0_DEV.priv, 0); +#ifdef TTYS1_DEV + up_restoreuartint(TTYS1_DEV.priv, 0); +#endif +#ifdef TTYS2_DEV + up_restoreuartint(TTYS2_DEV.priv, 0); +#endif +#ifdef TTYS3_DEV + up_restoreuartint(TTYS3_DEV.priv, 0); +#endif +#ifdef TTYS4_DEV + up_restoreuartint(TTYS4_DEV.priv, 0); +#endif +#ifdef TTYS5_DEV + up_restoreuartint(TTYS5_DEV.priv, 0); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t ie; + + up_disableuartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreuartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/arm/src/kinetis/kinetis_sim.h b/arch/arm/src/kinetis/kinetis_sim.h new file mode 100644 index 0000000000000000000000000000000000000000..aad17e923e80c2bc7513fba4ff707c3825e2d5a3 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_sim.h @@ -0,0 +1,545 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_sim.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_SIM_SOPT1_OFFSET 0x0000 /* System Options Register 1 */ +#define KINETIS_SIM_SOPT2_OFFSET 0x0004 /* System Options Register 2 */ +#define KINETIS_SIM_SOPT4_OFFSET 0x000c /* System Options Register 4 */ +#define KINETIS_SIM_SOPT5_OFFSET 0x0010 /* System Options Register 5 */ +#define KINETIS_SIM_SOPT6_OFFSET 0x0014 /* System Options Register 6 */ +#define KINETIS_SIM_SOPT7_OFFSET 0x0018 /* System Options Register 7 */ +#define KINETIS_SIM_SDID_OFFSET 0x0024 /* System Device Identification Register */ +#define KINETIS_SIM_SCGC1_OFFSET 0x0028 /* System Clock Gating Control Register 1 */ +#define KINETIS_SIM_SCGC2_OFFSET 0x002c /* System Clock Gating Control Register 2 */ +#define KINETIS_SIM_SCGC3_OFFSET 0x0030 /* System Clock Gating Control Register 3 */ +#define KINETIS_SIM_SCGC4_OFFSET 0x0034 /* System Clock Gating Control Register 4 */ +#define KINETIS_SIM_SCGC5_OFFSET 0x0038 /* System Clock Gating Control Register 5 */ +#define KINETIS_SIM_SCGC6_OFFSET 0x003c /* System Clock Gating Control Register 6 */ +#define KINETIS_SIM_SCGC7_OFFSET 0x0040 /* System Clock Gating Control Register 7 */ +#define KINETIS_SIM_CLKDIV1_OFFSET 0x0044 /* System Clock Divider Register 1 */ +#define KINETIS_SIM_CLKDIV2_OFFSET 0x0048 /* System Clock Divider Register 2 */ +#define KINETIS_SIM_FCFG1_OFFSET 0x004c /* Flash Configuration Register 1 */ +#define KINETIS_SIM_FCFG2_OFFSET 0x0050 /* Flash Configuration Register 2 */ +#define KINETIS_SIM_UIDH_OFFSET 0x0054 /* Unique Identification Register High */ +#define KINETIS_SIM_UIDMH_OFFSET 0x0058 /* Unique Identification Register Mid-High */ +#define KINETIS_SIM_UIDML_OFFSET 0x005c /* Unique Identification Register Mid Low */ +#define KINETIS_SIM_UIDL_OFFSET 0x0060 /* Unique Identification Register Low */ + +/* Register Addresses ***************************************************************/ +/* NOTE: The SIM_SOPT1 register is located at a different base address than the + * other SIM registers. + */ + +#define KINETIS_SIM_SOPT1 (KINETIS_SIMLP_BASE+KINETIS_SIM_SOPT1_OFFSET) +#define KINETIS_SIM_SOPT2 (KINETIS_SIM_BASE+KINETIS_SIM_SOPT2_OFFSET) +#define KINETIS_SIM_SOPT4 (KINETIS_SIM_BASE+KINETIS_SIM_SOPT4_OFFSET) +#define KINETIS_SIM_SOPT5 (KINETIS_SIM_BASE+KINETIS_SIM_SOPT5_OFFSET) +#define KINETIS_SIM_SOPT6 (KINETIS_SIM_BASE+KINETIS_SIM_SOPT6_OFFSET) +#define KINETIS_SIM_SOPT7 (KINETIS_SIM_BASE+KINETIS_SIM_SOPT7_OFFSET) +#define KINETIS_SIM_SDID (KINETIS_SIM_BASE+KINETIS_SIM_SDID_OFFSET) +#define KINETIS_SIM_SCGC1 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC1_OFFSET) +#define KINETIS_SIM_SCGC2 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC2_OFFSET) +#define KINETIS_SIM_SCGC3 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC3_OFFSET) +#define KINETIS_SIM_SCGC4 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC4_OFFSET) +#define KINETIS_SIM_SCGC5 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC5_OFFSET) +#define KINETIS_SIM_SCGC6 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC6_OFFSET) +#define KINETIS_SIM_SCGC7 (KINETIS_SIM_BASE+KINETIS_SIM_SCGC7_OFFSET) +#define KINETIS_SIM_CLKDIV1 (KINETIS_SIM_BASE+KINETIS_SIM_CLKDIV1_OFFSET) +#define KINETIS_SIM_CLKDIV2 (KINETIS_SIM_BASE+KINETIS_SIM_CLKDIV2_OFFSET) +#define KINETIS_SIM_FCFG1 (KINETIS_SIM_BASE+KINETIS_SIM_FCFG1_OFFSET) +#define KINETIS_SIM_FCFG2 (KINETIS_SIM_BASE+KINETIS_SIM_FCFG2_OFFSET) +#define KINETIS_SIM_UIDH (KINETIS_SIM_BASE+KINETIS_SIM_UIDH_OFFSET) +#define KINETIS_SIM_UIDMH (KINETIS_SIM_BASE+KINETIS_SIM_UIDMH_OFFSET) +#define KINETIS_SIM_UIDML (KINETIS_SIM_BASE+KINETIS_SIM_UIDML_OFFSET) +#define KINETIS_SIM_UIDL (KINETIS_SIM_BASE+KINETIS_SIM_UIDL_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* System Options Register 1 */ + /* Bits 0-11: Reserved */ +#define SIM_SOPT1_RAMSIZE_SHIFT (12) /* Bits 12-15: RAM size */ +#define SIM_SOPT1_RAMSIZE_MASK (15 << SIM_SOPT1_RAMSIZE_SHIFT) +# define SIM_SOPT1_RAMSIZE_32KB (5 << SIM_SOPT1_RAMSIZE_SHIFT) /* 32 KBytes */ +# define SIM_SOPT1_RAMSIZE_64KB (7 << SIM_SOPT1_RAMSIZE_SHIFT) /* 64 KBytes */ +# define SIM_SOPT1_RAMSIZE_96KB (8 << SIM_SOPT1_RAMSIZE_SHIFT) /* 96 KBytes */ +# define SIM_SOPT1_RAMSIZE_128KB (9 << SIM_SOPT1_RAMSIZE_SHIFT) /* 128 KBytes */ + /* Bits 16-18: Reserved */ +#define SIM_SOPT1_OSC32KSEL (1 << 19) /* Bit 19: 32K oscillator clock select */ + /* Bits 20-22: Reserved */ +#define SIM_SOPT1_MS (1 << 23) /* Bit 23: EzPort chip select pin state */ + /* Bits 24-29: Reserved */ +#define SIM_SOPT1_USBSTBY (1 << 30) /* Bit 30: USB voltage regulator in standby mode */ +#define SIM_SOPT1_USBREGEN (1 << 31) /* Bit 31: USB voltage regulator enable */ + +/* System Options Register 2 */ + +#define SIM_SOPT2_MCGCLKSEL (1 << 0) /* Bit 0: MCG clock select */ + /* Bits 1-7: Reserved */ +#define SIM_SOPT2_FBSL_SHIFT (8) /* Bits 8-9: FlexBus security level */ +#define SIM_SOPT2_FBSL_MASK (3 << SIM_SOPT2_FBSL_SHIFT) +# define SIM_SOPT2_FBSL_NONE (0 << SIM_SOPT2_FBSL_SHIFT) /* All off-chip accesses disallowed */ +# define SIM_SOPT2_FBSL_DATA (2 << SIM_SOPT2_FBSL_SHIFT) /* Off-chip data accesses are allowed */ +# define SIM_SOPT2_FBSL_ALL (3 << SIM_SOPT2_FBSL_SHIFT) /* All Off-chip accesses allowed */ + /* Bit 10: Reserved */ +#define SIM_SOPT2_CMTUARTPAD (1 << 11) /* Bit 11: CMT/UART pad drive strength */ +#define SIM_SOPT2_TRACECLKSEL (1 << 12) /* Bit 12: Debug trace clock select */ + /* Bits 13-15: Reserved */ +#define SIM_SOPT2_PLLFLLSEL (1 << 16) /* Bit 16: PLL/FLL clock select */ + /* Bit 17: Reserved */ +#define SIM_SOPT2_USBSRC (1 << 18) /* Bit 18: USB clock source select */ + /* Bit 19: Reserved */ +#ifdef KINETIS_K60 +# define SIM_SOPT2_TIMESRC (1 << 20) /* Bit 20: IEEE 1588 timestamp clock source select (K60) */ +#endif + /* Bits 12-23: Reserved */ +#define SIM_SOPT2_I2SSRC_SHIFT (24) /* Bits 24-25: I2S master clock source select */ +#define SIM_SOPT2_I2SSRC_MASK (3 << SIM_SOPT2_I2SSRC_SHIFT) +# define SIM_SOPT2_I2SCSRC_CORE (0 << SIM_SOPT2_I2SSRC_SHIFT) /* Core/system clock / I2S fractional divider*/ +# define SIM_SOPT2_I2SCSRC_MCGCLK (1 << SIM_SOPT2_I2SSRC_SHIFT) /* MCGPLLCLK/MCGFLLCLK clock/ I2S fractional divider */ +# define SIM_SOPT2_I2SCSRC_OCSERCLK (2 << SIM_SOPT2_I2SSRC_SHIFT) /* OSCERCLK clock */ +# define SIM_SOPT2_I2SCSRC_EXTBYP (3 << SIM_SOPT2_I2SSRC_SHIFT) /* External bypass clock (I2S0_CLKIN) */ + /* Bits 26-27: Reserved */ +#define SIM_SOPT2_SDHCSRC_SHIFT (28) /* Bits 28-29: SDHC clock source select*/ +#define SIM_SOPT2_SDHCSRC_MASK (3 << SIM_SOPT2_SDHCSRC_SHIFT) +# define SIM_SOPT2_SDHCSRC_CORE (0 << SIM_SOPT2_SDHCSRC_SHIFT) /* Core/system clock */ +# define SIM_SOPT2_SDHCSRC_MCGCLK (1 << SIM_SOPT2_SDHCSRC_SHIFT) /* MCGPLLCLK/MCGFLLCLK clock */ +# define SIM_SOPT2_SDHCSRC_OCSERCLK (2 << SIM_SOPT2_SDHCSRC_SHIFT) /* OSCERCLK clock */ +# define SIM_SOPT2_SDHCSRC_EXTBYP (3 << SIM_SOPT2_SDHCSRC_SHIFT) /* External bypass clock (SDHC0_CLKIN) */ /* Bits 30-31: Reserved */ + +/* System Options Register 4 */ + +#define SIM_SOPT4_FTM0FLT0 (1 << 0) /* Bit 0: FTM0 Fault 0 Select */ +#define SIM_SOPT4_FTM0FLT1 (1 << 1) /* Bit 1: FTM0 Fault 1 Select */ +#define SIM_SOPT4_FTM0FLT2 (1 << 2) /* Bit 2: FTM0 Fault 2 Select */ + /* Bit 3: Reserved */ +#define SIM_SOPT4_FTM1FLT0 (1 << 4) /* Bit 4: FTM1 Fault 0 Select */ + /* Bits 5-7: Reserved */ +#define SIM_SOPT4_FTM2FLT0 (1 << 8) /* Bit 8: FTM2 Fault 0 Select */ + /* Bits 9-17: Reserved */ +#define SIM_SOPT4_FTM1CH0SRC_SHIFT (18) /* Bits 18-19: FTM1 channel 0 input capture source select */ +#define SIM_SOPT4_FTM1CH0SRC_MASK (3 << SIM_SOPT4_FTM1CH0SRC_SHIFT) +# define SIM_SOPT4_FTM1CH0SRC_CH0 (0 << SIM_SOPT4_FTM1CH0SRC_SHIFT) /* FTM1_CH0 signal */ +# define SIM_SOPT4_FTM1CH0SRC_CMP0 (1 << SIM_SOPT4_FTM1CH0SRC_SHIFT) /* CMP0 output */ +# define SIM_SOPT4_FTM1CH0SRC_CMP1 (2 << SIM_SOPT4_FTM1CH0SRC_SHIFT) /* CMP1 output */ +#define SIM_SOPT4_FTM2CH0SRC_SHIFT (20) /* Bits 20-21: FTM2 channel 0 input capture source select */ +#define SIM_SOPT4_FTM2CH0SRC_MASK (3 << SIM_SOPT4_FTM2CH0SRC_SHIFT) +# define SIM_SOPT4_FTM2CH0SRC_CH0 (0 << SIM_SOPT4_FTM2CH0SRC_SHIFT) /* FTM2_CH0 signal */ +# define SIM_SOPT4_FTM2CH0SRC_CMP0 (1 << SIM_SOPT4_FTM2CH0SRC_SHIFT) /* CMP0 output */ +# define SIM_SOPT4_FTM2CH0SRC_CMP1 (2 << SIM_SOPT4_FTM2CH0SRC_SHIFT) /* CMP1 output */ + /* Bits 22-23: Reserved */ +#define SIM_SOPT4_FTM0CLKSEL (1 << 24) /* Bit 24: FlexTimer 0 External Clock Pin Select */ +#define SIM_SOPT4_FTM1CLKSEL (1 << 25) /* Bit 25: FTM1 External Clock Pin Select */ +#define SIM_SOPT4_FTM2CLKSEL (1 << 26) /* Bit 26: FlexTimer 2 External Clock Pin Select */ + /* Bits 27-31: Reserved */ + +/* System Options Register 5 */ + +#define SIM_SOPT5_UART0TXSRC_SHIFT (0) /* Bits 0-1: UART 0 transmit data source select */ +#define SIM_SOPT5_UART0TXSRC_MASK (3 << SIM_SOPT5_UART0TXSRC_SHIFT) +# define SIM_SOPT5_UART0TXSRC_TX (0 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX pin */ +# define SIM_SOPT5_UART0TXSRC_FTM1 (1 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX modulated with FTM1 ch0 output */ +# define SIM_SOPT5_UART0TXSRC_FTM2 (2 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX modulated with FTM2 ch0 output */ +#define SIM_SOPT5_UART0RXSRC_SHIFT (2) /* Bits 2-3: UART 0 receive data source select */ +#define SIM_SOPT5_UART0RXSRC_MASK (3 << SIM_SOPT5_UART0RXSRC_SHIFT) +# define SIM_SOPT5_UART0RXSRC_RX (0 << SIM_SOPT5_UART0RXSRC_SHIFT) /* UART0_RX pin */ +# define SIM_SOPT5_UART0RXSRC_CMP0 (1 << SIM_SOPT5_UART0RXSRC_SHIFT) /* CMP0 */ +# define SIM_SOPT5_UART0RXSRC_CMP1 (2 << SIM_SOPT5_UART0RXSRC_SHIFT) /* CMP1 */ +#define SIM_SOPT5_UART1TXSRC_SHIFT (4) /* Bits 4-5: UART 1 transmit data source select */ +#define SIM_SOPT5_UART1TXSRC_MASK (3 << SIM_SOPT5_UART1TXSRC_SHIFT) +# define SIM_SOPT5_UART1TXSRC_TX (0 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX pin */ +# define SIM_SOPT5_UART1TXSRC_FTM1 (1 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX modulated with FTM1 ch0 output */ +# define SIM_SOPT5_UART1TXSRC_FTM2 (2 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX modulated with FTM2 ch0 output */ +#define SIM_SOPT5_UART1RXSRC_SHIFT (6) /* Bits 6-7: UART 1 receive data source select */ +#define SIM_SOPT5_UART1RXSRC_MASK (3 << SIM_SOPT5_UART1RXSRC_SHIFT) +# define SIM_SOPT5_UART1RXSRC_RX (0 << SIM_SOPT5_UART1RXSRC_SHIFT) /* UART1_RX pin */ +# define SIM_SOPT5_UART1RXSRC_CMP0 (1 << SIM_SOPT5_UART1RXSRC_SHIFT) /* CMP0 */ +# define SIM_SOPT5_UART1RXSRC_CMP1 (2 << SIM_SOPT5_UART1RXSRC_SHIFT) /* CMP1 */ + /* Bits 8-31: Reserved */ +/* System Options Register 6 */ + /* Bits 0-23: Reserved */ +#define SIM_SOPT6_RSTFLTSEL_SHIFT (24) /* Bits 24-28: Reset pin filter select */ +#define SIM_SOPT6_RSTFLTSEL_MASK (31 << SIM_SOPT6_RSTFLTSEL_SHIFT) +# define SIM_SOPT6_RSTFLTSEL(n) (((n)-1) << SIM_SOPT6_RSTFLTSEL_SHIFT) /* Bux clock filter count n, n=1..32 */ +#define SIM_SOPT6_RSTFLTEN_SHIFT (29) /* Bits 29-31: Reset pin filter enable */ +#define SIM_SOPT6_RSTFLTEN_MASK (7 << SIM_SOPT6_RSTFLTEN_SHIFT) +#define SIM_SOPT6_RSTFLTEN_DISABLED (0 << SIM_SOPT6_RSTFLTEN_SHIFT) /* All filtering disabled */ +# define SIM_SOPT6_RSTFLTEN_BUSCLK1 (1 << SIM_SOPT6_RSTFLTEN_SHIFT) /* Bus clock filter enabled (normal); LPO clock filter enabled (stop) */ +# define SIM_SOPT6_RSTFLTEN_LPO1 (2 << SIM_SOPT6_RSTFLTEN_SHIFT) /* LPO clock filter enabled */ +# define SIM_SOPT6_RSTFLTEN_BUSCLK2 (3 << SIM_SOPT6_RSTFLTEN_SHIFT) /* Bus clock filter enabled (normal); All filtering disabled (stop) */ +# define SIM_SOPT6_RSTFLTEN_LPO2 (4 << SIM_SOPT6_RSTFLTEN_SHIFT) /* PO clock filter enabled (normal); All filtering disabled (stop) */ + +/* System Options Register 7 */ + +#define SIM_SOPT7_ADC0TRGSEL_SHIFT (0) /* Bits 0-3: ADC0 trigger select */ +#define SIM_SOPT7_ADC0TRGSEL_MASK (15 << SIM_SOPT7_ADC0TRGSEL_SHIFT) +# define SIM_SOPT7_ADC0TRGSEL_PDB (0 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PDB external trigger (PDB0_EXTRG) */ +# define SIM_SOPT7_ADC0TRGSEL_CMP0 (1 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* High speed comparator 0 output */ +# define SIM_SOPT7_ADC0TRGSEL_CMP1 (2 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* High speed comparator 1 output */ +# define SIM_SOPT7_ADC0TRGSEL_CMP2 (3 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* High speed comparator 2 output */ +# define SIM_SOPT7_ADC0TRGSEL_PIT0 (4 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 0 */ +# define SIM_SOPT7_ADC0TRGSEL_PIT1 (5 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 1 */ +# define SIM_SOPT7_ADC0TRGSEL_PIT2 (6 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 2 */ +# define SIM_SOPT7_ADC0TRGSEL_PIT3 (7 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 3 */ +# define SIM_SOPT7_ADC0TRGSEL_FTM0 (8 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* FTM0 trigger */ +# define SIM_SOPT7_ADC0TRGSEL_FTM1 (9 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* FTM1 trigger */ +# define SIM_SOPT7_ADC0TRGSEL_FTM2 (10 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* FTM2 trigger */ +# define SIM_SOPT7_ADC0TRGSEL_ALARM (12 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* RTC alarm */ +# define SIM_SOPT7_ADC0TRGSEL_SECS (13 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* RTC seconds */ +# define SIM_SOPT7_ADC0TRGSEL_LPTMR (14 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* Low-power timer trigger */ +#define SIM_SOPT7_ADC0PRETRGSEL (1 << 4) /* Bit 4: ADC0 pretrigger select */ + /* Bits 5-6: Reserved */ +#define SIM_SOPT7_ADC0ALTTRGEN (1 << 7) /* Bit 7: ADC0 alternate trigger enable */ +#define SIM_SOPT7_ADC1TRGSEL_SHIFT (8) /* Bits 8-11: ADC1 trigger select */ +#define SIM_SOPT7_ADC1TRGSEL_MASK (15 << SIM_SOPT7_ADC1TRGSEL_SHIFT) +# define SIM_SOPT7_ADC1TRGSEL_PDB (0 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* PDB external trigger (PDB0_EXTRG) */ +# define SIM_SOPT7_ADC1TRGSEL_CMP0 (1 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* High speed comparator 0 output */ +# define SIM_SOPT7_ADC1TRGSEL_CMP1 (2 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* High speed comparator 1 output */ +# define SIM_SOPT7_ADC1TRGSEL_CMP2 (3 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* High speed comparator 2 output */ +# define SIM_SOPT7_ADC1TRGSEL_PIT0 (4 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* PIT trigger 0 */ +# define SIM_SOPT7_ADC1TRGSEL_PIT1 (5 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* PIT trigger 1 */ +# define SIM_SOPT7_ADC1TRGSEL_PIT2 (6 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* PIT trigger 2 */ +# define SIM_SOPT7_ADC1TRGSEL_PIT3 (7 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* PIT trigger 3 */ +# define SIM_SOPT7_ADC1TRGSEL_FTM0 (8 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* FTM0 trigger */ +# define SIM_SOPT7_ADC1TRGSEL_FTM1 (9 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* FTM1 trigger */ +# define SIM_SOPT7_ADC1TRGSEL_FTM2 (10 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* FTM2 trigger */ +# define SIM_SOPT7_ADC1TRGSEL_ALARM (12 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* RTC alarm */ +# define SIM_SOPT7_ADC1TRGSEL_SECS (13 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* RTC seconds */ +# define SIM_SOPT7_ADC1TRGSEL_LPTMR (14 << SIM_SOPT7_ADC1TRGSEL_SHIFT) /* Low-power timer trigger */ +#define SIM_SOPT7_ADC1PRETRGSEL (1 << 12) /* Bit 12: ADC1 pre-trigger select */ + /* Bits 13-14: Reserved */ +#define SIM_SOPT7_ADC1ALTTRGEN (1 << 15) /* Bit 15: ADC1 alternate trigger enable */ + /* Bits 16-31: Reserved */ +/* System Device Identification Register */ + +#define SIM_SDID_PINID_SHIFT (0) /* Bits 0-3: Pincount identification */ +#define SIM_SDID_PINID_MASK (15 << SIM_SDID_PINID_SHIFT) +# define SIM_SDID_PINID_32PIN (2 << SIM_SDID_PINID_SHIFT) /* 32-pin */ +# define SIM_SDID_PINID_48PIN (4 << SIM_SDID_PINID_SHIFT) /* 48-pin */ +# define SIM_SDID_PINID_64PIN (5 << SIM_SDID_PINID_SHIFT) /* 64-pin */ +# define SIM_SDID_PINID_80PIN (6 << SIM_SDID_PINID_SHIFT) /* 80-pin */ +# define SIM_SDID_PINID_81PIN (7 << SIM_SDID_PINID_SHIFT) /* 81-pin */ +# define SIM_SDID_PINID_100PIN (8 << SIM_SDID_PINID_SHIFT) /* 100-pin */ +# define SIM_SDID_PINID_121PIN (9 << SIM_SDID_PINID_SHIFT) /* 121-pin */ +# define SIM_SDID_PINID_144PIN (10 << SIM_SDID_PINID_SHIFT) /* 144-pin */ +# define SIM_SDID_PINID_196PIN (12 << SIM_SDID_PINID_SHIFT) /* 196-pin */ +# define SIM_SDID_PINID_256PIN (14 << SIM_SDID_PINID_SHIFT) /* 256-pin */ +#define SIM_SDID_FAMID_SHIFT (4) /* Bits 4-6: Kinetis family identification */ +#define SIM_SDID_FAMID_MASK (7 << SIM_SDID_FAMID_SHIFT) +# define SIM_SDID_FAMID_K10 (0 << SIM_SDID_FAMID_SHIFT) /* K10 */ +# define SIM_SDID_FAMID_K20 (1 << SIM_SDID_FAMID_SHIFT)) /* K20 */ +# define SIM_SDID_FAMID_K30 (2 << SIM_SDID_FAMID_SHIFT)) /* K30 */ +# define SIM_SDID_FAMID_K40 (3 << SIM_SDID_FAMID_SHIFT)) /* K40 */ +# define SIM_SDID_FAMID_K60 (4 << SIM_SDID_FAMID_SHIFT)) /* K60 */ +# define SIM_SDID_FAMID_K70 (5 << SIM_SDID_FAMID_SHIFT)) /* K70 */ +# define SIM_SDID_FAMID_K50 (6 << SIM_SDID_FAMID_SHIFT)) /* K50 and K52 */ +# define SIM_SDID_FAMID_K51 (7 << SIM_SDID_FAMID_SHIFT)) /* K51 and K53 */ + /* Bits 7-11: Reserved */ +#define SIM_SDID_REVID_SHIFT (12) /* Bits 12-15: Device revision number */ +#define SIM_SDID_REVID_MASK (15 << SIM_SDID_REVID_SHIFT) + /* Bits 16-31: Reserved */ +/* System Clock Gating Control Register 1 */ + /* Bits 0-9: Reserved */ +#define SIM_SCGC1_UART4 (1 << 10) /* Bit 10: UART4 Clock Gate Control */ +#define SIM_SCGC1_UART5 (1 << 11) /* Bit 11: UART5 Clock Gate Control */ + /* Bits 12-31: Reserved */ +/* System Clock Gating Control Register 2 */ + +#if defined(KINETIS_NENET) && KINETIS_NENET > 0 +# define SIM_SCGC2_ENET (1 << 0) /* Bit 0: ENET Clock Gate Control (K60) */ +#endif + /* Bits 1-11: Reserved */ +#define SIM_SCGC2_DAC0 (1 << 12) /* Bit 12: DAC0 Clock Gate Control */ +#define SIM_SCGC2_DAC1 (1 << 13) /* Bit 13: DAC1 Clock Gate Control */ + /* Bits 14-31: Reserved */ +/* System Clock Gating Control Register 3 */ + +#if defined(KINETIS_NRNG) && KINETIS_NRNG > 0 +# define SIM_SCGC3_RNGB (1 << 0) /* Bit 0: RNGB Clock Gate Control (K60) */ +#endif + /* Bits 1-3: Reserved */ +#define SIM_SCGC3_FLEXCAN1 (1 << 4) /* Bit 4: FlexCAN1 Clock Gate Control */ + /* Bits 5-11: Reserved */ +#define SIM_SCGC3_SPI2 (1 << 12) /* Bit 12: SPI2 Clock Gate Control */ + /* Bits 13-16: Reserved */ +#define SIM_SCGC3_SDHC (1 << 17) /* Bit 17: SDHC Clock Gate Control */ + /* Bits 18-23: Reserved */ +#define SIM_SCGC3_FTM2 (1 << 24) /* Bit 24: FTM2 Clock Gate Control */ + /* Bits 25-26: Reserved */ +#define SIM_SCGC3_ADC1 (1 << 27) /* Bit 27: ADC1 Clock Gate Control */ + /* Bits 28-29: Reserved */ +#if defined(KINETIS_NSLCD) && KINETIS_NSLCD > 0 +# define SIM_SCGC3_SLCD (1 << 30) /* Bit 30: Segment LCD Clock Gate Control (K40) */ +#endif + /* Bit 31: Reserved */ +/* System Clock Gating Control Register 4 */ + /* Bit 0: Reserved */ +#define SIM_SCGC4_EWM (1 << 1) /* Bit 1: EWM Clock Gate Control */ +#define SIM_SCGC4_CMT (1 << 2) /* Bit 2: CMT Clock Gate Control */ + /* Bits 3-5: Reserved */ +#define SIM_SCGC4_I2C0 (1 << 6) /* Bit 6: I2C0 Clock Gate Control */ +#define SIM_SCGC4_I2C1 (1 << 7) /* Bit 7: I2C1 Clock Gate Control */ + /* Bits 8-9: Reserved */ +#define SIM_SCGC4_UART0 (1 << 10) /* Bit 10: UART0 Clock Gate Control */ +#define SIM_SCGC4_UART1 (1 << 11) /* Bit 11: UART1 Clock Gate Control */ +#define SIM_SCGC4_UART2 (1 << 12) /* Bit 12: UART2 Clock Gate Control */ +#define SIM_SCGC4_UART3 (1 << 13) /* Bit 13: UART3 Clock Gate Control */ + /* Bits 14-17: Reserved */ +#define SIM_SCGC4_USBOTG (1 << 18) /* Bit 18: USB Clock Gate Control */ +#define SIM_SCGC4_CMP (1 << 19) /* Bit 19: Comparator Clock Gate Control */ +#define SIM_SCGC4_VREF (1 << 20) /* Bit 20: VREF Clock Gate Control */ + /* Bits 21-17: Reserved */ +#define SIM_SCGC4_LLWU (1 << 28) /* Bit 28: LLWU Clock Gate Control */ + /* Bits 29-31: Reserved */ +/* System Clock Gating Control Register 5 */ + +#define SIM_SCGC5_LPTIMER (1 << 0) /* Bit 0: Low Power Timer Clock Gate Control */ +#define SIM_SCGC5_REGFILE (1 << 1) /* Bit 1: Register File Clock Gate Control */ + /* Bits 2-4: Reserved */ +#define SIM_SCGC5_TSI (1 << 5) /* Bit 5: TSI Clock Gate Control */ + /* Bits 6-8: Reserved */ +#define SIM_SCGC5_PORTA (1 << 9) /* Bit 9: Port A Clock Gate Control */ +#define SIM_SCGC5_PORTB (1 << 10) /* Bit 10: Port B Clock Gate Control */ +#define SIM_SCGC5_PORTC (1 << 11) /* Bit 11: Port C Clock Gate Control */ +#define SIM_SCGC5_PORTD (1 << 12) /* Bit 12: Port D Clock Gate Control */ +#define SIM_SCGC5_PORTE (1 << 13) /* Bit 13: Port E Clock Gate Control */ + /* Bits 14-31: Reserved */ +/* System Clock Gating Control Register 6 */ + +#define SIM_SCGC6_FTFL (1 << 0) /* Bit 0: Flash Memory Clock Gate Control */ +#define SIM_SCGC6_DMAMUX (1 << 1) /* Bit 1: DMA Mux Clock Gate Control */ + /* Bits 2-3: Reserved */ +#define SIM_SCGC6_FLEXCAN0 (1 << 4) /* Bit 4: FlexCAN0 Clock Gate Control */ + /* Bits 5-11: Reserved */ +#define SIM_SCGC6_SPI0 (1 << 12) /* Bit 12: SPI0 Clock Gate Control */ +#define SIM_SCGC6_SPI1 (1 << 13) /* Bit 13: SPI1 Clock Gate Control */ + /* Bit 14: Reserved */ +#define SIM_SCGC6_I2S (1 << 15) /* Bit 15: I2S Clock Gate Control */ + /* Bits 16-17: Reserved */ +#define SIM_SCGC6_CRC (1 << 18) /* Bit 18: CRC Clock Gate Control */ + /* Bits 19-20: Reserved */ +#define SIM_SCGC6_USBDCD (1 << 21) /* Bit 21: USB DCD Clock Gate Control */ +#define SIM_SCGC6_PDB (1 << 22) /* Bit 22: PDB Clock Gate Control */ +#define SIM_SCGC6_PIT (1 << 23) /* Bit 23: PIT Clock Gate Control */ +#define SIM_SCGC6_FTM0 (1 << 24) /* Bit 24: FTM0 Clock Gate Control */ +#define SIM_SCGC6_FTM1 (1 << 25) /* Bit 25: FTM1 Clock Gate Control */ + /* Bit 26: Reserved */ +#define SIM_SCGC6_ADC0 (1 << 27) /* Bit 27: ADC0 Clock Gate Control */ + /* Bit 28: Reserved */ +#define SIM_SCGC6_RTC (1 << 29) /* Bit 29: RTC Clock Gate Control */ + /* Bits 30-31: Reserved */ +/* System Clock Gating Control Register 7 */ + +#define SIM_SCGC7_FLEXBUS (1 << 0) /* Bit 0: FlexBus Clock Gate Control */ +#define SIM_SCGC7_DMA (1 << 1) /* Bit 1: DMA Clock Gate Control */ +#define SIM_SCGC7_MPU (1 << 2) /* Bit 2: MPU Clock Gate Control */ + /* Bits 3-31: Reserved */ +/* System Clock Divider Register 1 */ + /* Bits 0-15: Reserved */ +#define SIM_CLKDIV1_OUTDIV4_SHIFT (16) /* Bits 16-19: Clock 4 output divider value */ +#define SIM_CLKDIV1_OUTDIV4_MASK (15 << SIM_CLKDIV1_OUTDIV4_SHIFT) +# define SIM_CLKDIV1_OUTDIV4(n) (((n)-1) << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV4_1 (0 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV4_2 (1 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV4_3 (2 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV4_4 (3 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV4_5 (4 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV4_6 (5 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV4_7 (6 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV4_8 (7 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 8 */ +# define SIM_CLKDIV1_OUTDIV4_9 (8 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 9 */ +# define SIM_CLKDIV1_OUTDIV4_10 (9 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 10 */ +# define SIM_CLKDIV1_OUTDIV4_11 (10 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 11 */ +# define SIM_CLKDIV1_OUTDIV4_12 (11 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 12 */ +# define SIM_CLKDIV1_OUTDIV4_13 (12 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 13 */ +# define SIM_CLKDIV1_OUTDIV4_14 (13 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 14 */ +# define SIM_CLKDIV1_OUTDIV4_15 (14 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 15 */ +# define SIM_CLKDIV1_OUTDIV4_16 (15 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 16 */ +#define SIM_CLKDIV1_OUTDIV3_SHIFT (20) /* Bits 20-23: Clock 3 output divider value */ +#define SIM_CLKDIV1_OUTDIV3_MASK (15 << SIM_CLKDIV1_OUTDIV3_SHIFT) +# define SIM_CLKDIV1_OUTDIV3(n) (((n)-1) << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV3_1 (0 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV3_2 (1 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV3_3 (2 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV3_4 (3 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV3_5 (4 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV3_6 (5 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV3_7 (6 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV3_8 (7 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 8 */ +# define SIM_CLKDIV1_OUTDIV3_9 (8 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 9 */ +# define SIM_CLKDIV1_OUTDIV3_10 (9 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 10 */ +# define SIM_CLKDIV1_OUTDIV3_11 (10 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 11 */ +# define SIM_CLKDIV1_OUTDIV3_12 (11 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 12 */ +# define SIM_CLKDIV1_OUTDIV3_13 (12 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 13 */ +# define SIM_CLKDIV1_OUTDIV3_14 (13 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 14 */ +# define SIM_CLKDIV1_OUTDIV3_15 (14 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 15 */ +# define SIM_CLKDIV1_OUTDIV3_16 (15 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 16 */ +#define SIM_CLKDIV1_OUTDIV2_SHIFT (24) /* Bits 24-27: Clock 2 output divider value */ +#define SIM_CLKDIV1_OUTDIV2_MASK (15 << SIM_CLKDIV1_OUTDIV2_SHIFT) +# define SIM_CLKDIV1_OUTDIV2(n) (((n)-1) << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV2_1 (0 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV2_2 (1 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV2_3 (2 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV2_4 (3 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV2_5 (4 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV2_6 (5 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV2_7 (6 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV2_8 (7 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 8 */ +# define SIM_CLKDIV1_OUTDIV2_9 (8 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 9 */ +# define SIM_CLKDIV1_OUTDIV2_10 (9 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 10 */ +# define SIM_CLKDIV1_OUTDIV2_11 (10 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 11 */ +# define SIM_CLKDIV1_OUTDIV2_12 (11 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 12 */ +# define SIM_CLKDIV1_OUTDIV2_13 (12 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 13 */ +# define SIM_CLKDIV1_OUTDIV2_14 (13 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 14 */ +# define SIM_CLKDIV1_OUTDIV2_15 (14 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 15 */ +# define SIM_CLKDIV1_OUTDIV2_16 (15 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 16 */ +#define SIM_CLKDIV1_OUTDIV1_SHIFT (28) /* Bits 28-31: Clock 1 output divider value */ +#define SIM_CLKDIV1_OUTDIV1_MASK (15 << SIM_CLKDIV1_OUTDIV1_SHIFT) +# define SIM_CLKDIV1_OUTDIV1(n) (((n)-1) << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV1_1 (0 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV1_2 (1 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV1_3 (2 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV1_4 (3 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV1_5 (4 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV1_6 (5 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV1_7 (6 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV1_8 (7 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 8 */ +# define SIM_CLKDIV1_OUTDIV1_9 (8 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 9 */ +# define SIM_CLKDIV1_OUTDIV1_10 (9 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 10 */ +# define SIM_CLKDIV1_OUTDIV1_11 (10 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 11 */ +# define SIM_CLKDIV1_OUTDIV1_12 (11 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 12 */ +# define SIM_CLKDIV1_OUTDIV1_13 (12 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 13 */ +# define SIM_CLKDIV1_OUTDIV1_14 (13 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 14 */ +# define SIM_CLKDIV1_OUTDIV1_15 (14 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 15 */ +# define SIM_CLKDIV1_OUTDIV1_16 (15 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 16 */ + +/* System Clock Divider Register 2 */ + +#define SIM_CLKDIV2_USBFRAC (1 << 0) /* Bit 0: USB clock divider fraction */ +#define SIM_CLKDIV2_USBDIV_SHIFT (1) /* Bits 1-3: USB clock divider divisor */ +#define SIM_CLKDIV2_USBDIV_MASK (7 << SIM_CLKDIV2_USBDIV_SHIFT) + /* Bits 4-7: Reserved */ +#define SIM_CLKDIV2_I2SFRAC_SHIFT (8) /* Bits 8-15: I2S clock divider fraction */ +#define SIM_CLKDIV2_I2SFRAC_MASK (0xff << SIM_CLKDIV2_I2SFRAC_SHIFT) + /* Bits 16-19: Reserved */ +#define SIM_CLKDIV2_I2SDIV_SHIFT (20) /* Bits 20-31: I2S clock divider value */ +#define SIM_CLKDIV2_I2SDIV_MASK (0xfff << SIM_CLKDIV2_I2SDIV_SHIFT) + +/* Flash Configuration Register 1 */ + /* Bits 0-7: Reserved */ +#define SIM_FCFG1_DEPART_SHIFT (8) /* Bits 8-11: FlexNVM partition */ +#define SIM_FCFG1_DEPART_MASK (15 << SIM_FCFG1_DEPART_SHIFT) + /* Bits 12-15: Reserved */ +#define SIM_FCFG1_EESIZE_SHIFT (16) /* Bits 16-19: EEPROM size*/ +#define SIM_FCFG1_EESIZE_MASK (15 << SIM_FCFG1_EESIZE_SHIFT) +# define SIM_FCFG1_EESIZE_4KB (2 << SIM_FCFG1_EESIZE_SHIFT) /* 4 KB */ +# define SIM_FCFG1_EESIZE_2KB (3 << SIM_FCFG1_EESIZE_SHIFT) /* 2 KB */ +# define SIM_FCFG1_EESIZE_1KB (4 << SIM_FCFG1_EESIZE_SHIFT) /* 1 KB */ +# define SIM_FCFG1_EESIZE_512B (5 << SIM_FCFG1_EESIZE_SHIFT) /* 512 Bytes */ +# define SIM_FCFG1_EESIZE_256B (6 << SIM_FCFG1_EESIZE_SHIFT) /* 256 Bytes */ +# define SIM_FCFG1_EESIZE_128B (7 << SIM_FCFG1_EESIZE_SHIFT) /* 128 Bytes */ +# define SIM_FCFG1_EESIZE_64B (8 << SIM_FCFG1_EESIZE_SHIFT) /* 64 Bytes */ +# define SIM_FCFG1_EESIZE_32B (9 << SIM_FCFG1_EESIZE_SHIFT) /* 32 Bytes */ +# define SIM_FCFG1_EESIZE_NONE (15 << SIM_FCFG1_EESIZE_SHIFT) /* 0 Bytes */ + /* Bits 20-23: Reserved */ +#ifdef KINETIS_K40 +#define SIM_FCFG1_PFSIZE_SHIFT (24) /* Bits 24-27: Program flash size (K40) */ +#define SIM_FCFG1_PFSIZE_MASK (15 << SIM_FCFG1_PFSIZE_SHIFT) +# define SIM_FCFG1_PFSIZE_128KB (7 << SIM_FCFG1_PFSIZE_SHIFT) /* 128KB program flash, 4KB protection region */ +# define SIM_FCFG1_PFSIZE_256KB (9 << SIM_FCFG1_PFSIZE_SHIFT) /* 256KB program flash, 8KB protection region */ +# define SIM_FCFG1_PFSIZE_512KB (11 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */ +# define SIM_FCFG1_PFSIZE_512KB2 (15 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */ +#define SIM_FCFG1_NVMSIZE_SHIFT (28) /* Bits 28-31: FlexNVM size (K40)*/ +#define SIM_FCFG1_NVMSIZE_MASK (15 << SIM_FCFG1_NVMSIZE_SHIFT) +# define SIM_FCFG1_NVMSIZE_NONE (0 << SIM_FCFG1_NVMSIZE_SHIFT) /* 0KB FlexNVM */ +# define SIM_FCFG1_NVMSIZE_128KB (7 << SIM_FCFG1_NVMSIZE_SHIFT) /* 128KB FlexNVM, 16KB protection region */ +# define SIM_FCFG1_NVMSIZE_256KB (9 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */ +# define SIM_FCFG1_NVMSIZE_256KB2 (15 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */ +#endif + +#ifdef KINETIS_K60 +#define SIM_FCFG1_FSIZE_SHIFT (24) /* Bits 24-31: Flash size (K60)*/ +#define SIM_FCFG1_FSIZE_MASK (0xff << SIM_FCFG1_FSIZE_SHIFT) +# define SIM_FCFG1_FSIZE_32KB (2 << SIM_FCFG1_FSIZE_SHIFT) /* 32KB program flash, 1KB protection region */ +# define SIM_FCFG1_FSIZE_64KB (4 << SIM_FCFG1_FSIZE_SHIFT) /* 64KB program flash, 2KB protection region */ +# define SIM_FCFG1_FSIZE_128KB (6 << SIM_FCFG1_FSIZE_SHIFT) /* 128KB program flash, 4KB protection region */ +# define SIM_FCFG1_FSIZE_256KB (8 << SIM_FCFG1_FSIZE_SHIFT) /* 256KB program flash, 8KB protection region */ +# define SIM_FCFG1_FSIZE_512KB (12 << SIM_FCFG1_FSIZE_SHIFT) /* 512KB program flash, 16KB protection region */ +#endif + +/* Flash Configuration Register 2 */ + /* Bits 0-15: Reserved */ +#define SIM_FCFG2_MAXADDR1_SHIFT (16) /* Bits 16-21: Max address block 1 */ +#define SIM_FCFG2_MAXADDR1_MASK (nn << SIM_FCFG2_MAXADDR1_SHIFT) + /* Bit 22: Reserved */ +#define SIM_FCFG2_PFLSH (1 << 23) /* Bit 23: Program flash */ +#define SIM_FCFG2_MAXADDR0_SHIFT (24) /* Bits 24-29: Max address block 0 */ +#define SIM_FCFG2_MAXADDR0_MASK (nn << SIM_FCFG2_MAXADDR0_SHIFT) + /* Bit 30: Reserved */ +#define SIM_FCFG2_SWAPPFLSH (1 << 31) /* Bit 31: Swap program flash */ + +/* Unique Identification Register High. 32-bit Unique Identification. */ +/* Unique Identification Register Mid-High. 32-bit Unique Identification. */ +/* Unique Identification Register Mid Low. 32-bit Unique Identification. */ +/* Unique Identification Register Low. 32-bit Unique Identification. */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H */ diff --git a/arch/arm/src/kinetis/kinetis_slcd.h b/arch/arm/src/kinetis/kinetis_slcd.h new file mode 100644 index 0000000000000000000000000000000000000000..d56ee5c41eac0e547aeb67874a94d8b76bf95d34 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_slcd.h @@ -0,0 +1,420 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_slcd.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_LCD_GCR_OFFSET 0x0000 /* LCD general control register */ +#define KINETIS_LCD_AR_OFFSET 0x0004 /* LCD auxiliary register */ +#define KINETIS_LCD_FDCR_OFFSET 0x0008 /* LCD fault detect control register */ +#define KINETIS_LCD_FDSR_OFFSET 0x000c /* LCD fault detect status register */ +#define KINETIS_LCD_PENL_OFFSET 0x0010 /* LCD pin enable register */ +#define KINETIS_LCD_PENH_OFFSET 0x0014 /* LCD pin enable register */ +#define KINETIS_LCD_BPENL_OFFSET 0x0018 /* LCD backplane enable register */ +#define KINETIS_LCD_BPENH_OFFSET 0x001c /* LCD backplane enable register */ +#define KINETIS_LCD_WF3TO0_OFFSET 0x0020 /* LCD waveform register */ +#define KINETIS_LCD_WF7TO4_OFFSET 0x0024 /* LCD waveform register */ +#define KINETIS_LCD_WF11TO8_OFFSET 0x0028 /* LCD waveform register */ +#define KINETIS_LCD_WF15TO12_OFFSET 0x002c /* LCD waveform register */ +#define KINETIS_LCD_WF19TO16_OFFSET 0x0030 /* LCD waveform register */ +#define KINETIS_LCD_WF23TO20_OFFSET 0x0034 /* LCD waveform register */ +#define KINETIS_LCD_WF27TO24_OFFSET 0x0038 /* LCD waveform register */ +#define KINETIS_LCD_WF31TO28_OFFSET 0x003c /* LCD waveform register */ +#define KINETIS_LCD_WF35TO32_OFFSET 0x0040 /* LCD waveform register */ +#define KINETIS_LCD_WF39TO36_OFFSET 0x0044 /* LCD waveform register */ +#define KINETIS_LCD_WF43TO40_OFFSET 0x0048 /* LCD waveform register */ +#define KINETIS_LCD_WF47TO44_OFFSET 0x004c /* LCD waveform register */ +#define KINETIS_LCD_WF51TO48_OFFSET 0x0050 /* LCD waveform register */ +#define KINETIS_LCD_WF55TO52_OFFSET 0x0054 /* LCD waveform register */ +#define KINETIS_LCD_WF59TO56_OFFSET 0x0058 /* LCD waveform register */ +#define KINETIS_LCD_WF63TO60_OFFSET 0x005C /* LCD waveform register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_LCD_GCR (KINETIS_SLCD_BASE+KINETIS_LCD_GCR_OFFSET) +#define KINETIS_LCD_AR (KINETIS_SLCD_BASE+KINETIS_LCD_AR_OFFSET) +#define KINETIS_LCD_FDCR (KINETIS_SLCD_BASE+KINETIS_LCD_FDCR_OFFSET) +#define KINETIS_LCD_FDSR (KINETIS_SLCD_BASE+KINETIS_LCD_FDSR_OFFSET) +#define KINETIS_LCD_PENL (KINETIS_SLCD_BASE+KINETIS_LCD_PENL_OFFSET) +#define KINETIS_LCD_PENH (KINETIS_SLCD_BASE+KINETIS_LCD_PENH_OFFSET) +#define KINETIS_LCD_BPENL (KINETIS_SLCD_BASE+KINETIS_LCD_BPENL_OFFSET) +#define KINETIS_LCD_BPENH (KINETIS_SLCD_BASE+KINETIS_LCD_BPENH_OFFSET) +#define KINETIS_LCD_WF3TO0 (KINETIS_SLCD_BASE+KINETIS_LCD_WF3TO0_OFFSET) +#define KINETIS_LCD_WF7TO4 (KINETIS_SLCD_BASE+KINETIS_LCD_WF7TO4_OFFSET) +#define KINETIS_LCD_WF11TO8 (KINETIS_SLCD_BASE+KINETIS_LCD_WF11TO8_OFFSET) +#define KINETIS_LCD_WF15TO12 (KINETIS_SLCD_BASE+KINETIS_LCD_WF15TO12_OFFSET) +#define KINETIS_LCD_WF19TO16 (KINETIS_SLCD_BASE+KINETIS_LCD_WF19TO16_OFFSET) +#define KINETIS_LCD_WF23TO20 (KINETIS_SLCD_BASE+KINETIS_LCD_WF23TO20_OFFSET) +#define KINETIS_LCD_WF27TO24 (KINETIS_SLCD_BASE+KINETIS_LCD_WF27TO24_OFFSET) +#define KINETIS_LCD_WF31TO28 (KINETIS_SLCD_BASE+KINETIS_LCD_WF31TO28_OFFSET) +#define KINETIS_LCD_WF35TO32 (KINETIS_SLCD_BASE+KINETIS_LCD_WF35TO32_OFFSET) +#define KINETIS_LCD_WF39TO36 (KINETIS_SLCD_BASE+KINETIS_LCD_WF39TO36_OFFSET) +#define KINETIS_LCD_WF43TO40 (KINETIS_SLCD_BASE+KINETIS_LCD_WF43TO40_OFFSET) +#define KINETIS_LCD_WF47TO44 (KINETIS_SLCD_BASE+KINETIS_LCD_WF47TO44_OFFSET) +#define KINETIS_LCD_WF51TO48 (KINETIS_SLCD_BASE+KINETIS_LCD_WF51TO48_OFFSET) +#define KINETIS_LCD_WF55TO52 (KINETIS_SLCD_BASE+KINETIS_LCD_WF55TO52_OFFSET) +#define KINETIS_LCD_WF59TO56 (KINETIS_SLCD_BASE+KINETIS_LCD_WF59TO56_OFFSET) +#define KINETIS_LCD_WF63TO60 (KINETIS_SLCD_BASE+KINETIS_LCD_WF63TO60_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* LCD general control register */ + +#define LCD_GCR_DUTYSHIFT (0) /* Bits 0-2: LCD duty select */ +#define LCD_GCR_DUTY_MASK (7 << LCD_GCR_DUTYSHIFT) +# define LCD_GCR_DUTY_BP(n) (((n)-1) << LCD_GCR_DUTYSHIFT) /* Use n BP (1/n duty cyle) */ +#define LCD_GCR_LCLK_SHIFT (3) /* Bits 3-5: LCD clock prescaler */ +#define LCD_GCR_LCLK_MASK (7 << LCD_GCR_LCLK_SHIFT) +#define LCD_GCR_SOURCE (1 << 6) /* Bit 6: LCD clock source select */ +#define LCD_GCR_LCDEN (1 << 7) /* Bit 7: LCD driver enable */ +#define LCD_GCR_LCDSTP (1 << 8) /* Bit 8: Stop mode */ +#define LCD_GCR_LCDWAIT (1 << 9) /* Bit 9: Wait mode */ + /* Bits 10-11: Reserved */ +#define LCD_GCR_ALTDIV_SHIFT (12) /* Bits 12-13: LCD alternate clock divider */ +#define LCD_GCR_ALTDIV_MASK (3 << LCD_GCR_ALTDIV_SHIFT) +# define LCD_GCR_ALTDIV_DIV (0 << LCD_GCR_ALTDIV_SHIFT) /* Divide factor = 1 (No divide) */ +# define LCD_GCR_ALTDIV_DIV (1 << LCD_GCR_ALTDIV_SHIFT) /* Divide factor = 8 */ +# define LCD_GCR_ALTDIV_DIV (2 << LCD_GCR_ALTDIV_SHIFT) /* Divide factor = 64 */ +# define LCD_GCR_ALTDIV_DIV (3 << LCD_GCR_ALTDIV_SHIFT) /* Divide factor = 512 */ +#define LCD_GCR_FDCIEN (1 << 14) /* Bit 14: LCD fault detection complete interrupt enable */ +#define LCD_GCR_LCDIEN (1 << 15) /* Bit 15: LCD frame frequency interrupt enable */ +#define LCD_GCR_VSUPPLY_SHIFT (16) /* Bits 16-17: Voltage supply control */ +#define LCD_GCR_VSUPPLY_MASK (3 << LCD_GCR_VSUPPLY_SHIFT) +#define LCD_GCR_VSUPPLY_INTVLL2 (0 << LCD_GCR_VSUPPLY_SHIFT) /* Drive VLL2 internally from VDD */ +#define LCD_GCR_VSUPPLY_INTVLL3 (1 << LCD_GCR_VSUPPLY_SHIFT) /* Drive VLL3 internally from VDD */ +#define LCD_GCR_VSUPPLY_EXTVLL3 (3 << LCD_GCR_VSUPPLY_SHIFT) /* Drive VLL3 externally from VDD */ +#define LCD_GCR_VSUPPLY_INTVLL1 (3 << LCD_GCR_VSUPPLY_SHIFT) /* Drive VLL1 internally from VIREG */ + /* Bits 18-19: Reserved */ +#define LCD_GCR_LADJ_SHIFT (20) /* Bits 20-21: Load adjust */ +#define LCD_GCR_LADJ_MASK (3 << LCD_GCR_LADJ_SHIFT) +# define LCD_GCR_LADJ_LOW (0 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=0, Low load <=2000pF */ +# define LCD_GCR_LADJ_MIDLOW (1 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=0, Low load <=2000pF */ +# define LCD_GCR_LADJ_MIDHIGH (2 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=0, High load <=8000pF */ +# define LCD_GCR_LADJ_HIGH (3 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=0, High load <=8000pF */ +# define LCD_GCR_LADJ_FAST (0 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=1, <=8000pF */ +# define LCD_GCR_LADJ_MIDFAST (1 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=1, <=6000pF */ +# define LCD_GCR_LADJ_MIDSLOW (2 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=1, <=4000pF */ +# define LCD_GCR_LADJ_SLOW (3 << LCD_GCR_LADJ_SHIFT) /* For CPSEL=1, <=2000pF */ +#define LCD_GCR_HREFSEL (1 << 22) /* Bit 22: High reference select */ +#define LCD_GCR_CPSEL (1 << 23) /* Bit 23: Charge pump or resistor bias select */ +#define LCD_GCR_RVTRIM_SHIFT (24) /* Bits 24-27: Regulated voltage trim */ +#define LCD_GCR_RVTRIM_MASK (15 << LCD_GCR_RVTRIM_SHIFT) + /* Bits 28-30: Reserved */ +#define LCD_GCR_RVEN (1 << 31) /* Bit 31: Regulated voltage enable */ + +/* LCD auxiliary register */ + +#define LCD_AR_BRATE_SHIFT (0) /* Bits 0-2: Blink-rate configuration */ +#define LCD_AR_BRATE_MASK (7 << LCD_AR_BRATE_SHIFT) +#define LCD_AR_BMODE (1 << 3) /* Bit 3: Blink mode */ + /* Bit 4: Reserved */ +#define LCD_AR_BLANK (1 << 5) /* Bit 5: Blank display mode +#define LCD_AR_ALT (1 << 6) /* Bit 6: Alternate display mode */ +#define LCD_AR_BLINK (1 << 7) /* Bit 7: Blink command */ + /* Bits 8-14: Reserved */ +#define LCD_AR_LCDIF (1 << 15) /* Bit 15: LCD frame frequency interrupt flag */ + /* Bits 16-31: Reserved */ +/* LCD fault detect control register */ + +#define LCD_FDCR_FDPINID_SHIFT (0) /* Bits 0-5: Fault detect pin ID */ +#define LCD_FDCR_FDPINID_MASK (63 << LCD_FDCR_FDPINID_SHIFT) +#define LCD_FDCR_FDBPEN (1 << 6) /* Bit 6: Fault detect backplane enable */ +#define LCD_FDCR_FDEN (1 << 7) /* Bit 7: Fault detect enable */ + /* Bit 8: Reserved */ +#define LCD_FDCR_FDSWW_SHIFT (9) /* Bits 9-11: Fault detect sample window width */ +#define LCD_FDCR_FDSWW_MASK (7 << LCD_FDCR_FDSWW_SHIFT) +#define LCD_FDCR_FDPRS_SHIFT (12) /* Bits 12-14: Fault detect clock prescaler */ +#define LCD_FDCR_FDPRS_MASK (7 << LCD_FDCR_FDPRS_SHIFT) +# define LCD_FDCR_FDPRS_DIV1 (0 << LCD_FDCR_FDPRS_SHIFT) /* Bus clock */ +# define LCD_FDCR_FDPRS_DIV2 (1 << LCD_FDCR_FDPRS_SHIFT) /* 1/2 bus clock */ +# define LCD_FDCR_FDPRS_DIV4 (2 << LCD_FDCR_FDPRS_SHIFT) /* 1/4 bus clock */ +# define LCD_FDCR_FDPRS_DIV8 (3 << LCD_FDCR_FDPRS_SHIFT) /* 1/8 bus clock */ +# define LCD_FDCR_FDPRS_DIV16 (4 << LCD_FDCR_FDPRS_SHIFT) /* 1/16 bus clock */ +# define LCD_FDCR_FDPRS_DIV32 (5 << LCD_FDCR_FDPRS_SHIFT) /* 1/32 bus clock */ +# define LCD_FDCR_FDPRS_DIV64 (6 << LCD_FDCR_FDPRS_SHIFT) /* 1/64 bus clock */ +# define LCD_FDCR_FDPRS_DIV128 (7 << LCD_FDCR_FDPRS_SHIFT) /* 1/128 bus clock */ + /* Bits 15-31: Reserved */ +/* LCD fault detect status register */ + +#define LCD_FDSR_FDCNT_SHIFT (0) /* Bits 0-7: Fault detect counter */ +#define LCD_FDSR_FDCNT_MASK (0xff << LCD_FDSR_FDCNT_SHIFT) + /* Bits 8-14: Reserved */ +#define LCD_FDSR_FDCF (1 << 15) /* Bit 15: Fault detection complete flag */ + /* Bits 16-31: Reserved */ +/* LCD pin enable register low/high (64 pin bits in two 32-bit registers) */ + + +/* LCD backplane enable register (64 pin bits in two 32-bit registers) */ + +#define LCD_BPENL(n) (1 << (n)) /* Bit n: Enable backplane operation pin n, n=0-31 */ +#define LCD_BPENH(n) (1 << ((n)-32)) /* Bit n-32: Enable backplane operation pin n, n=32-63 */ + +/* LCD waveform registers */ + +#define LCD_WF3TO0_WF0_SHIFT (0) /* Bits 0-7: Waveform control field 0 segment bits */ +#define LCD_WF3TO0_WF0_MASK (0xff << LCD_WF3TO0_WF0_SHIFT) +# define LCD_WF3TO0_WF0_SEGMENT(n) ((1 << (n)) << LCD_WF3TO0_WF0_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF3TO0_WF1_SHIFT (8) /* Bits 8-15: Waveform control field 1 segment bits */ +#define LCD_WF3TO0_WF1_MASK (0xff << LCD_WF3TO0_WF1_SHIFT) +# define LCD_WF3TO0_WF1_SEGMENT(n) ((1 << (n)) << LCD_WF3TO0_WF1_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF3TO0_WF2_SHIFT (16) /* Bits 16-23: Waveform control field 2 segment bits */ +#define LCD_WF3TO0_WF2_MASK (0xff << LCD_WF3TO0_WF2_SHIFT) +# define LCD_WF3TO0_WF2_SEGMENT(n) ((1 << (n)) << LCD_WF3TO0_WF2_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF3TO0_WF3_SHIFT (24) /* Bits 24-31: Waveform control field 3 segment bits */ +#define LCD_WF3TO0_WF3_MASK (0xff << LCD_WF3TO0_WF3_SHIFT) +# define LCD_WF3TO0_WF3_SEGMENT(n) ((1 << (n)) << LCD_WF3TO0_WF3_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF7TO4_WF4_SHIFT (0) /* Bits 0-7: Waveform control field 4 segment bits */ +#define LCD_WF7TO4_WF4_MASK (0xff << LCD_WF7TO4_WF4_SHIFT) +# define LCD_WF7TO4_WF4_SEGMENT(n) ((1 << (n)) << LCD_WF7TO4_WF4_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF7TO4_WF5_SHIFT (8) /* Bits 8-15: Waveform control field 5 segment bits */ +#define LCD_WF7TO4_WF5_MASK (0xff << LCD_WF7TO4_WF5_SHIFT) +# define LCD_WF7TO4_WF5_SEGMENT(n) ((1 << (n)) << LCD_WF7TO4_WF5_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF7TO4_WF6_SHIFT (16) /* Bits 16-23: Waveform control field 6 segment bits */ +#define LCD_WF7TO4_WF6_MASK (0xff << LCD_WF7TO4_WF6_SHIFT) +# define LCD_WF7TO4_WF6_SEGMENT(n) ((1 << (n)) << LCD_WF7TO4_WF6_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF7TO4_WF7_SHIFT (24) /* Bits 24-31: Waveform control field 7 segment bits */ +#define LCD_WF7TO4_WF7_MASK (0xff << LCD_WF7TO4_WF7_SHIFT) +# define LCD_WF7TO4_WF7_SEGMENT(n) ((1 << (n)) << LCD_WF7TO4_WF7_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF11TO8_WF8_SHIFT (0) /* Bits 0-7: Waveform control field 8 segment bits */ +#define LCD_WF11TO8_WF8_MASK (0xff << LCD_WF11TO8_WF8_SHIFT) +# define LCD_WF11TO8_WF8_SEGMENT(n) ((1 << (n)) << LCD_WF11TO8_WF8_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF11TO8_WF9_SHIFT (8) /* Bits 8-15: Waveform control field 9 segment bits */ +#define LCD_WF11TO8_WF9_MASK (0xff << LCD_WF11TO8_WF9_SHIFT) +# define LCD_WF11TO8_WF9_SEGMENT(n) ((1 << (n)) << LCD_WF11TO8_WF9_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF11TO8_WF10_SHIFT (16) /* Bits 16-23: Waveform control field 10 segment bits */ +#define LCD_WF11TO8_WF10_MASK (0xff << LCD_WF11TO8_WF10_SHIFT) +# define LCD_WF11TO8_WF10_SEGMENT(n) ((1 << (n)) << LCD_WF11TO8_WF10_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF11TO8_WF11_SHIFT (24) /* Bits 24-31: Waveform control field 11 segment bits */ +#define LCD_WF11TO8_WF11_MASK (0xff << LCD_WF11TO8_WF11_SHIFT) +# define LCD_WF11TO8_WF11_SEGMENT(n) ((1 << (n)) << LCD_WF11TO8_WF11_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF15TO12_WF12_SHIFT (0) /* Bits 0-7: Waveform control field 12 segment bits */ +#define LCD_WF15TO12_WF12_MASK (0xff << LCD_WF15TO12_WF12_SHIFT) +# define LCD_WF15TO12_WF12_SEGMENT(n) ((1 << (n)) << LCD_WF15TO12_WF12_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF15TO12_WF13_SHIFT (8) /* Bits 8-15: Waveform control field 13 segment bits */ +#define LCD_WF15TO12_WF13_MASK (0xff << LCD_WF15TO12_WF13_SHIFT) +# define LCD_WF15TO12_WF13_SEGMENT(n) ((1 << (n)) << LCD_WF15TO12_WF13_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF15TO12_WF14_SHIFT (16) /* Bits 16-23: Waveform control field 14 segment bits */ +#define LCD_WF15TO12_WF14_MASK (0xff << LCD_WF15TO12_WF14_SHIFT) +# define LCD_WF15TO12_WF14_SEGMENT(n) ((1 << (n)) << LCD_WF15TO12_WF14_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF15TO12_WF15_SHIFT (24) /* Bits 24-31: Waveform control field 15 segment bits */ +#define LCD_WF15TO12_WF15_MASK (0xff << LCD_WF15TO12_WF15_SHIFT) +# define LCD_WF15TO12_WF15_SEGMENT(n) ((1 << (n)) << LCD_WF15TO12_WF15_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF19TO16_WF16_SHIFT (0) /* Bits 0-7: Waveform control field 16 segment bits */ +#define LCD_WF19TO16_WF16_MASK (0xff << LCD_WF19TO16_WF16_SHIFT) +# define LCD_WF19TO16_WF16_SEGMENT(n) ((1 << (n)) << LCD_WF19TO16_WF16_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF19TO16_WF17_SHIFT (8) /* Bits 8-15: Waveform control field 17 segment bits */ +#define LCD_WF19TO16_WF17_MASK (0xff << LCD_WF19TO16_WF17_SHIFT) +# define LCD_WF19TO16_WF17_SEGMENT(n) ((1 << (n)) << LCD_WF19TO16_WF17_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF19TO16_WF18_SHIFT (16) /* Bits 16-23: Waveform control field 18 segment bits */ +#define LCD_WF19TO16_WF18_MASK (0xff << LCD_WF19TO16_WF18_SHIFT) +# define LCD_WF19TO16_WF18_SEGMENT(n) ((1 << (n)) << LCD_WF19TO16_WF18_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF19TO16_WF19_SHIFT (24) /* Bits 24-31: Waveform control field 19 segment bits */ +#define LCD_WF19TO16_WF19_MASK (0xff << LCD_WF19TO16_WF19_SHIFT) +# define LCD_WF19TO16_WF19_SEGMENT(n) ((1 << (n)) << LCD_WF19TO16_WF19_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF23TO20_WF20_SHIFT (0) /* Bits 0-7: Waveform control field 20 segment bits */ +#define LCD_WF23TO20_WF20_MASK (0xff << LCD_WF23TO20_WF20_SHIFT) +# define LCD_WF23TO20_WF20_SEGMENT(n) ((1 << (n)) << LCD_WF23TO20_WF20_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF23TO20_WF21_SHIFT (8) /* Bits 8-15: Waveform control field 21 segment bits */ +#define LCD_WF23TO20_WF21_MASK (0xff << LCD_WF23TO20_WF21_SHIFT) +# define LCD_WF23TO20_WF21_SEGMENT(n) ((1 << (n)) << LCD_WF23TO20_WF21_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF23TO20_WF22_SHIFT (16) /* Bits 16-23: Waveform control field 22 segment bits */ +#define LCD_WF23TO20_WF22_MASK (0xff << LCD_WF23TO20_WF22_SHIFT) +# define LCD_WF23TO20_WF22_SEGMENT(n) ((1 << (n)) << LCD_WF23TO20_WF22_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF23TO20_WF23_SHIFT (24) /* Bits 24-31: Waveform control field 23 segment bits */ +#define LCD_WF23TO20_WF23_MASK (0xff << LCD_WF23TO20_WF23_SHIFT) +# define LCD_WF23TO20_WF23_SEGMENT(n) ((1 << (n)) << LCD_WF23TO20_WF23_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF27TO24_WF24_SHIFT (0) /* Bits 0-7: Waveform control field 24 segment bits */ +#define LCD_WF27TO24_WF24_MASK (0xff << LCD_WF27TO24_WF24_SHIFT) +# define LCD_WF27TO24_WF24_SEGMENT(n) ((1 << (n)) << LCD_WF27TO24_WF24_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF27TO24_WF25_SHIFT (8) /* Bits 8-15: Waveform control field 25 segment bits */ +#define LCD_WF27TO24_WF25_MASK (0xff << LCD_WF27TO24_WF25_SHIFT) +# define LCD_WF27TO24_WF25_SEGMENT(n) ((1 << (n)) << LCD_WF27TO24_WF25_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF27TO24_WF26_SHIFT (16) /* Bits 16-23: Waveform control field 26 segment bits */ +#define LCD_WF27TO24_WF26_MASK (0xff << LCD_WF27TO24_WF26_SHIFT) +# define LCD_WF27TO24_WF26_SEGMENT(n) ((1 << (n)) << LCD_WF27TO24_WF26_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF27TO24_WF27_SHIFT (24) /* Bits 24-31: Waveform control field 27 segment bits */ +#define LCD_WF27TO24_WF27_MASK (0xff << LCD_WF27TO24_WF27_SHIFT) +# define LCD_WF27TO24_WF27_SEGMENT(n) ((1 << (n)) << LCD_WF27TO24_WF27_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF31TO28_WF28_SHIFT (0) /* Bits 0-7: Waveform control field 28 segment bits */ +#define LCD_WF31TO28_WF28_MASK (0xff << LCD_WF31TO28_WF28_SHIFT) +# define LCD_WF31TO28_WF28_SEGMENT(n) ((1 << (n)) << LCD_WF31TO28_WF28_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF31TO28_WF29_SHIFT (8) /* Bits 8-15: Waveform control field 29 segment bits */ +#define LCD_WF31TO28_WF29_MASK (0xff << LCD_WF31TO28_WF29_SHIFT) +# define LCD_WF31TO28_WF29_SEGMENT(n) ((1 << (n)) << LCD_WF31TO28_WF29_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF31TO28_WF30_SHIFT (16) /* Bits 16-23: Waveform control field 30 segment bits */ +#define LCD_WF31TO28_WF30_MASK (0xff << LCD_WF31TO28_WF30_SHIFT) +# define LCD_WF31TO28_WF30_SEGMENT(n) ((1 << (n)) << LCD_WF31TO28_WF30_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF31TO28_WF31_SHIFT (24) /* Bits 24-31: Waveform control field 31 segment bits */ +#define LCD_WF31TO28_WF31_MASK (0xff << LCD_WF31TO28_WF31_SHIFT) +# define LCD_WF31TO28_WF31_SEGMENT(n) ((1 << (n)) << LCD_WF31TO28_WF31_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF35TO32_WF32_SHIFT (0) /* Bits 0-7: Waveform control field 32 segment bits */ +#define LCD_WF35TO32_WF32_MASK (0xff << LCD_WF35TO32_WF32_SHIFT) +# define LCD_WF35TO32_WF32_SEGMENT(n) ((1 << (n)) << LCD_WF35TO32_WF32_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF35TO32_WF33_SHIFT (8) /* Bits 8-15: Waveform control field 33 segment bits */ +#define LCD_WF35TO32_WF33_MASK (0xff << LCD_WF35TO32_WF33_SHIFT) +# define LCD_WF35TO32_WF33_SEGMENT(n) ((1 << (n)) << LCD_WF35TO32_WF33_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF35TO32_WF34_SHIFT (16) /* Bits 16-23: Waveform control field 34 segment bits */ +#define LCD_WF35TO32_WF34_MASK (0xff << LCD_WF35TO32_WF34_SHIFT) +# define LCD_WF35TO32_WF34_SEGMENT(n) ((1 << (n)) << LCD_WF35TO32_WF34_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF35TO32_WF35_SHIFT (24) /* Bits 24-31: Waveform control field 35 segment bits */ +#define LCD_WF35TO32_WF35_MASK (0xff << LCD_WF35TO32_WF35_SHIFT) +# define LCD_WF35TO32_WF35_SEGMENT(n) ((1 << (n)) << LCD_WF35TO32_WF35_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF39TO36_WF36_SHIFT (0) /* Bits 0-7: Waveform control field 36 segment bits */ +#define LCD_WF39TO36_WF36_MASK (0xff << LCD_WF39TO36_WF36_SHIFT) +# define LCD_WF39TO36_WF36_SEGMENT(n) ((1 << (n)) << LCD_WF39TO36_WF36_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF39TO36_WF37_SHIFT (8) /* Bits 8-15: Waveform control field 37 segment bits */ +#define LCD_WF39TO36_WF37_MASK (0xff << LCD_WF39TO36_WF37_SHIFT) +# define LCD_WF39TO36_WF37_SEGMENT(n) ((1 << (n)) << LCD_WF39TO36_WF37_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF39TO36_WF38_SHIFT (16) /* Bits 16-23: Waveform control field 38 segment bits */ +#define LCD_WF39TO36_WF38_MASK (0xff << LCD_WF39TO36_WF38_SHIFT) +# define LCD_WF39TO36_WF38_SEGMENT(n) ((1 << (n)) << LCD_WF39TO36_WF38_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF39TO36_WF39_SHIFT (24) /* Bits 24-31: Waveform control field 39 segment bits */ +#define LCD_WF39TO36_WF39_MASK (0xff << LCD_WF39TO36_WF39_SHIFT) +# define LCD_WF39TO36_WF39_SEGMENT(n) ((1 << (n)) << LCD_WF39TO36_WF39_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF43TO40_WF40_SHIFT (0) /* Bits 0-7: Waveform control field 40 segment bits */ +#define LCD_WF43TO40_WF40_MASK (0xff << LCD_WF43TO40_WF40_SHIFT) +# define LCD_WF43TO40_WF40_SEGMENT(n) ((1 << (n)) << LCD_WF43TO40_WF40_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF43TO40_WF41_SHIFT (8) /* Bits 8-15: Waveform control field 41 segment bits */ +#define LCD_WF43TO40_WF41_MASK (0xff << LCD_WF43TO40_WF41_SHIFT) +# define LCD_WF43TO40_WF41_SEGMENT(n) ((1 << (n)) << LCD_WF43TO40_WF41_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF43TO40_WF42_SHIFT (16) /* Bits 16-23: Waveform control field 42 segment bits */ +#define LCD_WF43TO40_WF42_MASK (0xff << LCD_WF43TO40_WF42_SHIFT) +# define LCD_WF43TO40_WF42_SEGMENT(n) ((1 << (n)) << LCD_WF43TO40_WF42_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF43TO40_WF43_SHIFT (24) /* Bits 24-31: Waveform control field 43 segment bits */ +#define LCD_WF43TO40_WF43_MASK (0xff << LCD_WF43TO40_WF43_SHIFT) +# define LCD_WF43TO40_WF43_SEGMENT(n) ((1 << (n)) << LCD_WF43TO40_WF43_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF47TO44_WF44_SHIFT (0) /* Bits 0-7: Waveform control field 44 segment bits */ +#define LCD_WF47TO44_WF44_MASK (0xff << LCD_WF47TO44_WF44_SHIFT) +# define LCD_WF47TO44_WF44_SEGMENT(n) ((1 << (n)) << LCD_WF47TO44_WF44_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF47TO44_WF45_SHIFT (8) /* Bits 8-15: Waveform control field 45 segment bits */ +#define LCD_WF47TO44_WF45_MASK (0xff << LCD_WF47TO44_WF45_SHIFT) +# define LCD_WF47TO44_WF45_SEGMENT(n) ((1 << (n)) << LCD_WF47TO44_WF45_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF47TO44_WF46_SHIFT (16) /* Bits 16-23: Waveform control field 46 segment bits */ +#define LCD_WF47TO44_WF46_MASK (0xff << LCD_WF47TO44_WF46_SHIFT) +# define LCD_WF47TO44_WF46_SEGMENT(n) ((1 << (n)) << LCD_WF47TO44_WF46_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF47TO44_WF47_SHIFT (24) /* Bits 24-31: Waveform control field 47 segment bits */ +#define LCD_WF47TO44_WF47_MASK (0xff << LCD_WF47TO44_WF47_SHIFT) +# define LCD_WF47TO44_WF47_SEGMENT(n) ((1 << (n)) << LCD_WF47TO44_WF47_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF51TO48_WF48_SHIFT (0) /* Bits 0-7: Waveform control field 48 segment bits */ +#define LCD_WF51TO48_WF48_MASK (0xff << LCD_WF51TO48_WF48_SHIFT) +# define LCD_WF51TO48_WF48_SEGMENT(n) ((1 << (n)) << LCD_WF51TO48_WF48_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF51TO48_WF49_SHIFT (8) /* Bits 8-15: Waveform control field 49 segment bits */ +#define LCD_WF51TO48_WF49_MASK (0xff << LCD_WF51TO48_WF49_SHIFT) +# define LCD_WF51TO48_WF49_SEGMENT(n) ((1 << (n)) << LCD_WF51TO48_WF49_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF51TO48_WF50_SHIFT (16) /* Bits 16-23: Waveform control field 50 segment bits */ +#define LCD_WF51TO48_WF50_MASK (0xff << LCD_WF51TO48_WF50_SHIFT) +# define LCD_WF51TO48_WF50_SEGMENT(n) ((1 << (n)) << LCD_WF51TO48_WF50_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF51TO48_WF51_SHIFT (24) /* Bits 24-31: Waveform control field 51 segment bits */ +#define LCD_WF51TO48_WF51_MASK (0xff << LCD_WF51TO48_WF51_SHIFT) +# define LCD_WF51TO48_WF51_SEGMENT(n) ((1 << (n)) << LCD_WF51TO48_WF51_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF55TO52_WF52_SHIFT (0) /* Bits 0-7: Waveform control field 52 segment bits */ +#define LCD_WF55TO52_WF52_MASK (0xff << LCD_WF55TO52_WF52_SHIFT) +# define LCD_WF55TO52_WF52_SEGMENT(n) ((1 << (n)) << LCD_WF55TO52_WF52_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF55TO52_WF53_SHIFT (8) /* Bits 8-15: Waveform control field 53 segment bits */ +#define LCD_WF55TO52_WF53_MASK (0xff << LCD_WF55TO52_WF53_SHIFT) +# define LCD_WF55TO52_WF53_SEGMENT(n) ((1 << (n)) << LCD_WF55TO52_WF53_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF55TO52_WF54_SHIFT (16) /* Bits 16-23: Waveform control field 54 segment bits */ +#define LCD_WF55TO52_WF54_MASK (0xff << LCD_WF55TO52_WF54_SHIFT) +# define LCD_WF55TO52_WF54_SEGMENT(n) ((1 << (n)) << LCD_WF55TO52_WF54_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF55TO52_WF55_SHIFT (24) /* Bits 24-31: Waveform control field 55 segment bits */ +#define LCD_WF55TO52_WF55_MASK (0xff << LCD_WF55TO52_WF55_SHIFT) +# define LCD_WF55TO52_WF55_SEGMENT(n) ((1 << (n)) << LCD_WF55TO52_WF55_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF59TO56_WF56_SHIFT (0) /* Bits 0-7: Waveform control field 56 segment bits */ +#define LCD_WF59TO56_WF56_MASK (0xff << LCD_WF59TO56_WF56_SHIFT) +# define LCD_WF59TO56_WF56_SEGMENT(n) ((1 << (n)) << LCD_WF59TO56_WF56_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF59TO56_WF57_SHIFT (8) /* Bits 8-15: Waveform control field 57 segment bits */ +#define LCD_WF59TO56_WF57_MASK (0xff << LCD_WF59TO56_WF57_SHIFT) +# define LCD_WF59TO56_WF57_SEGMENT(n) ((1 << (n)) << LCD_WF59TO56_WF57_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF59TO56_WF58_SHIFT (16) /* Bits 16-23: Waveform control field 58 segment bits */ +#define LCD_WF59TO56_WF58_MASK (0xff << LCD_WF59TO56_WF58_SHIFT) +# define LCD_WF59TO56_WF58_SEGMENT(n) ((1 << (n)) << LCD_WF59TO56_WF58_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF59TO56_WF59_SHIFT (24) /* Bits 24-31: Waveform control field 59 segment bits */ +#define LCD_WF59TO56_WF59_MASK (0xff << LCD_WF59TO56_WF59_SHIFT) +# define LCD_WF59TO56_WF59_SEGMENT(n) ((1 << (n)) << LCD_WF59TO56_WF59_SHIFT) /* Segment n, n=0..7 */ + +#define LCD_WF63TO60_WF60_SHIFT (0) /* Bits 0-7: Waveform control field 60 segment bits */ +#define LCD_WF63TO60_WF60_MASK (0xff << LCD_WF63TO60_WF60_SHIFT) +# define LCD_WF63TO60_WF60_SEGMENT(n) ((1 << (n)) << LCD_WF63TO60_WF60_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF63TO60_WF61_SHIFT (8) /* Bits 8-15: Waveform control field 61 segment bits */ +#define LCD_WF63TO60_WF61_MASK (0xff << LCD_WF63TO60_WF61_SHIFT) +# define LCD_WF63TO60_WF61_SEGMENT(n) ((1 << (n)) << LCD_WF63TO60_WF61_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF63TO60_WF62_SHIFT (16) /* Bits 16-23: Waveform control field 62 segment bits */ +#define LCD_WF63TO60_WF62_MASK (0xff << LCD_WF63TO60_WF62_SHIFT) +# define LCD_WF63TO60_WF62_SEGMENT(n) ((1 << (n)) << LCD_WF63TO60_WF62_SHIFT) /* Segment n, n=0..7 */ +#define LCD_WF63TO60_WF63_SHIFT (24) /* Bits 24-31: Waveform control field 63 segment bits */ +#define LCD_WF63TO60_WF63_MASK (0xff << LCD_WF63TO60_WF63_SHIFT) +# define LCD_WF63TO60_WF63_SEGMENT(n) ((1 << (n)) << LCD_WF63TO60_WF63_SHIFT) /* Segment n, n=0..7 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H */ diff --git a/arch/arm/src/kinetis/kinetis_smc.h b/arch/arm/src/kinetis/kinetis_smc.h new file mode 100644 index 0000000000000000000000000000000000000000..213ea80775972d3f6537b77ec3b36e492b1a0e2d --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_smc.h @@ -0,0 +1,122 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_smc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_SMC_SRSH_OFFSET 0x0000 /* System Reset Status Register High */ +#define KINETIS_SMC_SRSL_OFFSET 0x0001 /* System Reset Status Register Low */ +#define KINETIS_SMC_PMPROT_OFFSET 0x0002 /* Power Mode Protection Register */ +#define KINETIS_SMC_PMCTRL_OFFSET 0x0003 /* Power Mode Control Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_SMC_SRSH (KINETIS_SMC_BASE+KINETIS_SMC_SRSH_OFFSET) +#define KINETIS_SMC_SRSL (KINETIS_SMC_BASE+KINETIS_SMC_SRSL_OFFSET) +#define KINETIS_SMC_PMPROT (KINETIS_SMC_BASE+KINETIS_SMC_PMPROT_OFFSET) +#define KINETIS_SMC_PMCTRL (KINETIS_SMC_BASE+KINETIS_SMC_PMCTRL_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* System Reset Status Register High */ + +#define SMC_SRSH_JTAG (1 << 0) /* Bit 0: JTAG generated reset */ +#define SMC_SRSH_LOCKUP (1 << 1) /* Bit 1: Core Lock-up */ +#define SMC_SRSH_SW (1 << 2) /* Bit 2: Software */ + /* Bits 3-7: Reserved */ + +/* System Reset Status Register Low */ + +#define SMC_SRSL_WAKEUP (1 << 0) /* Bit 0: Low-leakage wakeup reset */ +#define SMC_SRSL_LVD (1 << 1) /* Bit 1: Low-voltage detect reset */ +#define SMC_SRSL_LOC (1 << 2) /* Bit 2: Loss-of-clock reset */ + /* Bits 3-4: Reserved */ +#define SMC_SRSL_COP (1 << 5) /* Bit 5: Computer Operating Properly (COP) Watchdog */ +#define SMC_SRSL_PIN (1 << 6) /* Bit 6: External reset pin */ +#define SMC_SRSL_POR (1 << 7) /* Bit 7: Power-on reset */ + +/* Power Mode Protection Register */ + +#define SMC_PMPROT_AVLLS1 (1 << 0) /* Bit 0: Allow very low leakage stop 1 mod */ +#define SMC_PMPROT_AVLLS2 (1 << 1) /* Bit 1: Allow very low leakage stop 2 mode */ +#define SMC_PMPROT_AVLLS3 (1 << 2) /* Bit 2: Allow Very Low Leakage Stop 3 Mode */ + /* Bit 3: Reserved */ +#define SMC_PMPROT_ALLS (1 << 4) /* Bit 4: Allow low leakage stop mode */ +#define SMC_PMPROT_AVLP (1 << 5) /* Bit 5: Allow very low power modes */ + /* Bits 6-7: Reserved */ +/* Power Mode Control Register */ + +#define SMC_PMCTRL_LPLLSM_SHIFT (0) /* Bits 0-2: Low Power, Low Leakage Stop Mode */ +#define SMC_PMCTRL_LPLLSM_MASK (7 << SMC_PMCTRL_LPLLSM_SHIFT) +# define SMC_PMCTRL_LPLLSM_NORMAL (0 << SMC_PMCTRL_LPLLSM_SHIFT) /* Normal stop */ +# define SMC_PMCTRL_LPLLSM_VLPS (2 << SMC_PMCTRL_LPLLSM_SHIFT) /* Very low power stop */ +# define SMC_PMCTRL_LPLLSM_LLS (3 << SMC_PMCTRL_LPLLSM_SHIFT) /* Low leakage stop */ +# define SMC_PMCTRL_LPLLSM_VLLS3 (5 << SMC_PMCTRL_LPLLSM_SHIFT) /* Very low leakage stop 3 */ +# define SMC_PMCTRL_LPLLSM_VLLS2 (6 << SMC_PMCTRL_LPLLSM_SHIFT) /* Very low leakage stop 2 */ +# define SMC_PMCTRL_LPLLSM_VLLS1 (7 << SMC_PMCTRL_LPLLSM_SHIFT) /* Very low leakage stop 1 */ + /* Bits 3-4: Reserved */ +#define SMC_PMCTRL_RUNM_SHIFT (5) /* Bits 5-6: Run Mode Enable */ +#define SMC_PMCTRL_RUNM_MASK (3 << SMC_PMCTRL_RUNM_SHIFT) +# define SMC_PMCTRL_RUNM_NORMAL (0 << SMC_PMCTRL_RUNM_SHIFT) /* Normal run mode */ +# define SMC_PMCTRL_RUNM_VLP (2 << SMC_PMCTRL_RUNM_SHIFT) /* Very low power run mode */ +#define SMC_PMCTRL_LPWUI (1 << 7) /* Bit 7: Low Power Wake Up on Interrupt */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H */ diff --git a/arch/arm/src/kinetis/kinetis_start.c b/arch/arm/src/kinetis/kinetis_start.c new file mode 100644 index 0000000000000000000000000000000000000000..f686e77915cedb8a48cf085dbec960fe039c2b26 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_start.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_start.c + * arch/arm/src/chip/kinetis_start.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kinetis.h" +#include "kinetis_smc.h" +#include "kinetis_userspace.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Disable the watchdog timer */ + + kinetis_wddisable(); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } +#endif + + /* Perform clock and Kinetis module initialization (This depends on + * RAM functions having been copied to RAM). + */ + + kinetis_clockconfig(); + + /* Configure the uart and perform early serial initialization so that we + * can get debug output as soon as possible (This depends on clock + * configuration). + */ + + kinetis_lowsetup(); +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + kinetis_userspace(); +#endif + + /* Initialize other on-board resources */ + + kinetis_boardinitialize(); + + /* Show reset status */ + + dbg("Reset status: %02x:%02x\n", + getreg8(KINETIS_SMC_SRSH), getreg8(KINETIS_SMC_SRSL)); + + /* Then start NuttX */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/kinetis/kinetis_timerisr.c b/arch/arm/src/kinetis/kinetis_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..a418a5e82340105415d620e242a9b6f8235bc5b7 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_timerisr.c @@ -0,0 +1,157 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "kinetis.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The Clock Source: The System Tick Timer's clock source is always the core + * clock + */ + +#define SYSTICK_RELOAD ((BOARD_CORECLK_FREQ / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Note that is should not be neccesary to set the SYSTICK clock source: + * "The CLKSOURCE bit in SysTick Control and Status register is always set + * to select the core clock." + */ + +#if 0 + regval = getreg32(NVIC_SYSTICK_CTRL); + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(KINETIS_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), + NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(KINETIS_IRQ_SYSTICK); +} diff --git a/arch/arm/src/kinetis/kinetis_tsi.h b/arch/arm/src/kinetis/kinetis_tsi.h new file mode 100644 index 0000000000000000000000000000000000000000..ea52c0fd1db765848316645b2d9a5b9be5c1e56d --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_tsi.h @@ -0,0 +1,311 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_tsi.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_TSI_GENCS_OFFSET 0x0000 /* General Control and Status Register */ +#define KINETIS_TSI_SCANC_OFFSET 0x0004 /* SCAN control register */ +#define KINETIS_TSI_PEN_OFFSET 0x0008 /* Pin enable register */ +#define KINETIS_TSI_STATUS_OFFSET 0x000c /* Status Register */ + +#define KINETIS_TSI_CNTR_OFFSET(n) (0x0100+(((n)-1)<<1) /* Counter Register n */ +#define KINETIS_TSI_CNTR1_OFFSET 0x0100 /* Counter Register 1 */ +#define KINETIS_TSI_CNTR3_OFFSET 0x0104 /* Counter Register 3 */ +#define KINETIS_TSI_CNTR5_OFFSET 0x0108 /* Counter Register 5 */ +#define KINETIS_TSI_CNTR7_OFFSET 0x010c /* Counter Register 7 */ +#define KINETIS_TSI_CNTR9_OFFSET 0x0110 /* Counter Register 9 */ +#define KINETIS_TSI_CNTR11_OFFSET 0x0114 /* Counter Register 11 */ +#define KINETIS_TSI_CNTR13_OFFSET 0x0118 /* Counter Register 13 */ +#define KINETIS_TSI_CNTR15_OFFSET 0x011c /* Counter Register 15 */ + +#define KINETIS_TSI_THRESHLD_OFFSET(n) (0x0120+((n)<<2)) /* Channel n threshold register */ +#define KINETIS_TSI_THRESHLD0_OFFSET 0x0120 /* Channel 0 threshold register */ +#define KINETIS_TSI_THRESHLD1_OFFSET 0x0124 /* Channel 1 threshold register */ +#define KINETIS_TSI_THRESHLD2_OFFSET 0x0128 /* Channel 2 threshold register */ +#define KINETIS_TSI_THRESHLD3_OFFSET 0x012c /* Channel 3 threshold register */ +#define KINETIS_TSI_THRESHLD4_OFFSET 0x0130 /* Channel 4 threshold register */ +#define KINETIS_TSI_THRESHLD5_OFFSET 0x0134 /* Channel 5 threshold register */ +#define KINETIS_TSI_THRESHLD6_OFFSET 0x0138 /* Channel 6 threshold register */ +#define KINETIS_TSI_THRESHLD7_OFFSET 0x013c /* Channel 7 threshold register */ +#define KINETIS_TSI_THRESHLD8_OFFSET 0x0140 /* Channel 8 threshold register */ +#define KINETIS_TSI_THRESHLD9_OFFSET 0x0144 /* Channel 9 threshold register */ +#define KINETIS_TSI_THRESHLD10_OFFSET 0x0148 /* Channel 10 threshold register */ +#define KINETIS_TSI_THRESHLD11_OFFSET 0x014c /* Channel 11 threshold register */ +#define KINETIS_TSI_THRESHLD12_OFFSET 0x0150 /* Channel 12 threshold register */ +#define KINETIS_TSI_THRESHLD13_OFFSET 0x0154 /* Channel 13 threshold register */ +#define KINETIS_TSI_THRESHLD14_OFFSET 0x0158 /* Channel 14 threshold register */ +#define KINETIS_TSI_THRESHLD15_OFFSET 0x015c /* Channel 15 threshold register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_TSI0_GENCS (KINETIS_TSI0_BASE+KINETIS_TSI_GENCS_OFFSET) +#define KINETIS_TSI0_SCANC (KINETIS_TSI0_BASE+KINETIS_TSI_SCANC_OFFSET) +#define KINETIS_TSI0_PEN (KINETIS_TSI0_BASE+KINETIS_TSI_PEN_OFFSET) +#define KINETIS_TSI0_STATUS (KINETIS_TSI0_BASE+KINETIS_TSI_STATUS_OFFSET) + +#define KINETIS_TSI0_CNTR (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR_OFFSET(n)) +#define KINETIS_TSI0_CNTR1 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR1_OFFSET) +#define KINETIS_TSI0_CNTR3 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR3_OFFSET) +#define KINETIS_TSI0_CNTR5 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR5_OFFSET) +#define KINETIS_TSI0_CNTR7 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR7_OFFSET) +#define KINETIS_TSI0_CNTR9 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR9_OFFSET) +#define KINETIS_TSI0_CNTR11 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR11_OFFSET) +#define KINETIS_TSI0_CNTR13 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR13_OFFSET) +#define KINETIS_TSI0_CNTR15 (KINETIS_TSI0_BASE+KINETIS_TSI_CNTR15_OFFSET) + +#define KINETIS_TSI0_THRESHLD(n) (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD_OFFSET(n)) +#define KINETIS_TSI0_THRESHLD0 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD0_OFFSET) +#define KINETIS_TSI0_THRESHLD1 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD1_OFFSET) +#define KINETIS_TSI0_THRESHLD2 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD2_OFFSET) +#define KINETIS_TSI0_THRESHLD3 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD3_OFFSET) +#define KINETIS_TSI0_THRESHLD4 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD4_OFFSET) +#define KINETIS_TSI0_THRESHLD5 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD5_OFFSET) +#define KINETIS_TSI0_THRESHLD6 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD6_OFFSET) +#define KINETIS_TSI0_THRESHLD7 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD7_OFFSET) +#define KINETIS_TSI0_THRESHLD8 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD8_OFFSET) +#define KINETIS_TSI0_THRESHLD9 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD9_OFFSET) +#define KINETIS_TSI0_THRESHLD10 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD10_OFFSET) +#define KINETIS_TSI0_THRESHLD11 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD11_OFFSET) +#define KINETIS_TSI0_THRESHLD12 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD12_OFFSET) +#define KINETIS_TSI0_THRESHLD13 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD13_OFFSET) +#define KINETIS_TSI0_THRESHLD14 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD14_OFFSET) +#define KINETIS_TSI0_THRESHLD15 (KINETIS_TSI0_BASE+KINETIS_TSI_THRESHLD15_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* General Control and Status Register */ + +#define TSI_GENCS_STPE (1 << 0) /* Bit 0: TSI stop enable while in low-power modes */ +#define TSI_GENCS_STM (1 << 1) /* Bit 1: Scan trigger mode */ + /* Bits 2-3: Reserved */ +#define TSI_GENCS_ESOR (1 << 4) /* Bit 4: End-of-scan or out-of-range interrupt select */ +#define TSI_GENCS_ERIE (1 << 5) /* Bit 5: TSI error interrupt enable */ +#define TSI_GENCS_TSIIE (1 << 6) /* Bit 6: TSI interrupt enable */ +#define TSI_GENCS_TSIEN (1 << 7) /* Bit 7: TSI module enable */ +#define TSI_GENCS_SWTS (1 << 8) /* Bit 8: Software trigger start */ +#define TSI_GENCS_SCNIP (1 << 9) /* Bit 9: Scan-in-progress status */ + /* Bits 10-11: Reserved */ +#define TSI_GENCS_OVRF (1 << 12) /* Bit 12: Overrun error flag +#define TSI_GENCS_EXTERF (1 << 13) /* Bit 13: External electrode error occurred */ +#define TSI_GENCS_OUTRGF (1 << 14) /* Bit 14: Out of Range Flag */ +#define TSI_GENCS_EOSF (1 << 15) /* Bit 15: End of scan flag */ +#define TSI_GENCS_PS_SHIFT (16) /* Bits 16-18: Electrode oscillator prescaler */ +#define TSI_GENCS_PS_MASK (7 << TSI_GENCS_PS_SHIFT) +# define TSI_GENCS_PS_DIV1 (0 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 1 */ +# define TSI_GENCS_PS_DIV2 (1 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 2 */ +# define TSI_GENCS_PS_DIV4 (2 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 4 */ +# define TSI_GENCS_PS_DIV8 (3 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 8 */ +# define TSI_GENCS_PS_DIV16 (4 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 16 */ +# define TSI_GENCS_PS_DIV32 (5 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 32 */ +# define TSI_GENCS_PS_DIV64 (6 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 64 */ +# define TSI_GENCS_PS_DIV128 (7 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 128 */ +#define TSI_GENCS_NSCN_SHIFT (19) /* Bits 19-23: Number of Consecutive Scans per Electrode */ +#define TSI_GENCS_NSCN_MASK (31 << TSI_GENCS_NSCN_SHIFT) +# define TSI_GENCS_NSCN_TIMES(n) (((n)-1) << TSI_GENCS_NSCN_SHIFT) /* n times per electrode, n=1..32 */ +#define TSI_GENCS_LPSCNITV_SHIFT (24) /* Bits 24-27: TSI Low Power Mode Scan Interval */ +#define TSI_GENCS_LPSCNITV_MASK (15 << TSI_GENCS_LPSCNITV_SHIFT) +# define TSI_GENCS_LPSCNITV_1MS (0 << TSI_GENCS_LPSCNITV_SHIFT) /* 1 ms scan interval */ +# define TSI_GENCS_LPSCNITV_5MS (1 << TSI_GENCS_LPSCNITV_SHIFT) /* 5 ms scan interval */ +# define TSI_GENCS_LPSCNITV_10MS (2 << TSI_GENCS_LPSCNITV_SHIFT) /* 10 ms scan interval */ +# define TSI_GENCS_LPSCNITV_15MS (3 << TSI_GENCS_LPSCNITV_SHIFT) /* 15 ms scan interval */ +# define TSI_GENCS_LPSCNITV_20MS (4 << TSI_GENCS_LPSCNITV_SHIFT) /* 20 ms scan interval */ +# define TSI_GENCS_LPSCNITV_30MS (5 << TSI_GENCS_LPSCNITV_SHIFT) /* 30 ms scan interval */ +# define TSI_GENCS_LPSCNITV_40MS (6 << TSI_GENCS_LPSCNITV_SHIFT) /* 40 ms scan interval */ +# define TSI_GENCS_LPSCNITV_50MS (7 << TSI_GENCS_LPSCNITV_SHIFT) /* 50 ms scan interval */ +# define TSI_GENCS_LPSCNITV_60MS (8 << TSI_GENCS_LPSCNITV_SHIFT) /* 75 ms scan interval */ +# define TSI_GENCS_LPSCNITV_75MS (9 << TSI_GENCS_LPSCNITV_SHIFT) /* 100 ms scan interval */ +# define TSI_GENCS_LPSCNITV_100MS (10 << TSI_GENCS_LPSCNITV_SHIFT) /* 125 ms scan interval */ +# define TSI_GENCS_LPSCNITV_150MS (11 << TSI_GENCS_LPSCNITV_SHIFT) /* 150 ms scan interval */ +# define TSI_GENCS_LPSCNITV_200MS (12 << TSI_GENCS_LPSCNITV_SHIFT) /* 200 ms scan interval */ +# define TSI_GENCS_LPSCNITV_300MS (13 << TSI_GENCS_LPSCNITV_SHIFT) /* 300 ms scan interval */ +# define TSI_GENCS_LPSCNITV_400MS (14 << TSI_GENCS_LPSCNITV_SHIFT) /* 400 ms scan interval */ +# define TSI_GENCS_LPSCNITV_500MS (15 << TSI_GENCS_LPSCNITV_SHIFT) /* 500 ms scan interval */ +#define TSI_GENCS_LPCLKS (1 << 28) /* Bit 28: Low Power Mode Clock Source Selection */ + /* Bits 29-31: Reserved */ +/* SCAN control register */ + +#define TSI_SCANC_AMPSC_SHIFT (0) /* Bits 0-2: Active mode prescaler */ +#define TSI_SCANC_AMPSC_MASK (7 << TSI_SCANC_AMPSC_SHIFT) +# define TSI_SCANC_AMPSC_DIV1 (0 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 1 */ +# define TSI_SCANC_AMPSC_DIV2 (1 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 2 */ +# define TSI_SCANC_AMPSC_DIV4 (2 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 4 */ +# define TSI_SCANC_AMPSC_DIV8 (3 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 8 */ +# define TSI_SCANC_AMPSC_DIV16 (4 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 16 */ +# define TSI_SCANC_AMPSC_DIV32 (5 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 32 */ +# define TSI_SCANC_AMPSC_DIV64 (6 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 64 */ +# define TSI_SCANC_AMPSC_DIV128 (7 << TSI_SCANC_AMPSC_SHIFT) /* Input clock source / 128 */ +#define TSI_SCANC_AMCLKS_SHIFT (3) /* Bits 3-4: Active mode clock source */ +#define TSI_SCANC_AMCLKS_MASK (3 << TSI_SCANC_AMCLKS_SHIFT) +# define TSI_SCANC_AMCLKS_BUSCLK (0 << TSI_SCANC_AMCLKS_SHIFT) /* Bus Clock */ +# define TSI_SCANC_AMCLKS_MCGIRCLK (1 << TSI_SCANC_AMCLKS_SHIFT) /* MCGIRCLK */ +# define TSI_SCANC_AMCLKS_OSCERCLK (2 << TSI_SCANC_AMCLKS_SHIFT) /* OSCERCLK */ +#define TSI_SCANC_AMCLKDIV (1 << 5) /* Bit 5: Active mode clock divider */ + /* Bits 6-7: Reserved */ +#define TSI_SCANC_SMOD_SHIFT (8) /* Bits 8-15: Scan modulo */ +#define TSI_SCANC_SMOD_MASK (0xff << TSI_SCANC_SMOD_SHIFT) +# define TSI_SCANC_SMOD_CONTINUOUS (0 << TSI_SCANC_SMOD_SHIFT) +# define TSI_SCANC_SMOD(n) ((n) << TSI_SCANC_SMOD_SHIFT) +#define TSI_SCANC_DELVOL_SHIFT (16) /* Bits 16-18: Delta voltage select applied to analog oscillators */ +#define TSI_SCANC_DELVOL_MASK (7 << TSI_SCANC_DELVOL_SHIFT) +# define TSI_SCANC_DELVOL_100MV (0 << TSI_SCANC_DELVOL_SHIFT) /* 100 mV delta voltage */ +# define TSI_SCANC_DELVOL_150MV (1 << TSI_SCANC_DELVOL_SHIFT) /* 150 mV delta voltage */ +# define TSI_SCANC_DELVOL_200MV (2 << TSI_SCANC_DELVOL_SHIFT) /* 200 mV delta voltage */ +# define TSI_SCANC_DELVOL_250MV (3 << TSI_SCANC_DELVOL_SHIFT) /* 250 mV delta voltage */ +# define TSI_SCANC_DELVOL_300MV (4 << TSI_SCANC_DELVOL_SHIFT) /* 300 mV delta voltage */ +# define TSI_SCANC_DELVOL_400MV (5 << TSI_SCANC_DELVOL_SHIFT) /* 400 mV delta voltage */ +# define TSI_SCANC_DELVOL_500MV (6 << TSI_SCANC_DELVOL_SHIFT) /* 500 mV delta voltage */ +# define TSI_SCANC_DELVOL_600MV (7 << TSI_SCANC_DELVOL_SHIFT) /* 600 mV delta voltage */ +#define TSI_SCANC_EXTCHRG_SHIFT (19) /* Bits 19-23: External oscillator charge current select */ +#define TSI_SCANC_EXTCHRG_MASK (31 << TSI_SCANC_EXTCHRG_SHIFT) +# define TSI_SCANC_EXTCHRG_UA(n) (((n)-1) << TSI_SCANC_EXTCHRG_SHIFT) /* n µA charge current, n=1..32 */ +#define TSI_SCANC_CAPTRM_SHIFT (24) /* Bits 24-26: Internal capacitance trim value */ +#define TSI_SCANC_CAPTRM_MASK (7 << TSI_SCANC_CAPTRM_SHIFT) +#define TSI_SCANC_CAPTRM_0p5PF (0 << TSI_SCANC_CAPTRM_SHIFT) /* 0.5 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_0p6PF (1 << TSI_SCANC_CAPTRM_SHIFT) /* 0.6 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_0p7PF (2 << TSI_SCANC_CAPTRM_SHIFT) /* 0.7 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_0p8PF (3 << TSI_SCANC_CAPTRM_SHIFT) /* 0.8 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_0p9PF (4 << TSI_SCANC_CAPTRM_SHIFT) /* 0.9 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_1p0PF (5 << TSI_SCANC_CAPTRM_SHIFT) /* 1.0 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_1p1PF (6 << TSI_SCANC_CAPTRM_SHIFT) /* 1.1 pF internal reference capacitance */ +#define TSI_SCANC_CAPTRM_1p2PF (7 << TSI_SCANC_CAPTRM_SHIFT) /* 1.2 pF internal reference capacitance */ +#define TSI_SCANC_REFCHRG_SHIFT (27) /* Bits 27-31: Reference oscillator charge current select */ +#define TSI_SCANC_REFCHRG_MASK (31 << TSI_SCANC_REFCHRG_SHIFT) +# define TSI_SCANC_REFCHRG_UA(n) (((n)-1) << TSI_SCANC_REFCHRG_SHIFT) /* n µA charge current, n=1..32 */ + +/* Pin enable register */ + +#define TSI_PEN0 (1 << 0) /* Bit 0: TSI pin 0 enable */ +#define TSI_PEN1 (1 << 1) /* Bit 1: TSI pin 1 enable */ +#define TSI_PEN2 (1 << 2) /* Bit 2: TSI pin 2 enable */ +#define TSI_PEN3 (1 << 3) /* Bit 3: TSI pin 3 enable */ +#define TSI_PEN4 (1 << 4) /* Bit 4: TSI pin 4 enable */ +#define TSI_PEN5 (1 << 5) /* Bit 5: TSI pin 5 enable */ +#define TSI_PEN6 (1 << 6) /* Bit 6: TSI pin 6 enable */ +#define TSI_PEN7 (1 << 7) /* Bit 7: TSI pin 7 enable */ +#define TSI_PEN8 (1 << 8) /* Bit 8: TSI pin 8 enable */ +#define TSI_PEN9 (1 << 9) /* Bit 9: TSI pin 9 enable */ +#define TSI_PEN10 (1 << 10) /* Bit 10: TSI pin 10 enable */ +#define TSI_PEN11 (1 << 11) /* Bit 11: TSI pin 11 enable */ +#define TSI_PEN12 (1 << 12) /* Bit 12: TSI pin 11 enable */ +#define TSI_PEN13 (1 << 13) /* Bit 13: TSI pin 13 enable */ +#define TSI_PEN14 (1 << 14) /* Bit 14: TSI pin 14 enable */ +#define TSI_PEN15 (1 << 15) /* Bit 15: TSI pin 15 enable */ +#define TSI_PEN(n) (1 << (n)) /* Bit n: TSI pin n enable, n=0..15 */ +#define TSI_PEN_LPSP_SHIFT (16) /* Bits 16-19: Low-power scan pin */ +#define TSI_PEN_LPSP_MASK (15 << TSI_PEN_LPSP_SHIFT) +# define TSI_PEN_LPSP(n) ((n) << TSI_PEN_LPSP_SHIFT) /* TSI_IN[n] active in low power mode */ + /* Bits 20-31: Reserved */ +/* Status Register */ + +#define TSI_STATUS_ORNGF0 (1 << 0) /* Bit 0: Touch Sensing Electrode Out-of-Range Flag 0 */ +#define TSI_STATUS_ORNGF1 (1 << 1) /* Bit 1: Touch Sensing Electrode Out-of-Range Flag 1 */ +#define TSI_STATUS_ORNGF2 (1 << 2) /* Bit 2: Touch Sensing Electrode Out-of-Range Flag 2 */ +#define TSI_STATUS_ORNGF3 (1 << 3) /* Bit 3: Touch Sensing Electrode Out-of-Range Flag 3 */ +#define TSI_STATUS_ORNGF4 (1 << 4) /* Bit 4: Touch Sensing Electrode Out-of-Range Flag 4 */ +#define TSI_STATUS_ORNGF5 (1 << 5) /* Bit 5: Touch Sensing Electrode Out-of-Range Flag 5 */ +#define TSI_STATUS_ORNGF6 (1 << 6) /* Bit 6: Touch Sensing Electrode Out-of-Range Flag 6 */ +#define TSI_STATUS_ORNGF7 (1 << 7) /* Bit 7: Touch Sensing Electrode Out-of-Range Flag 7 */ +#define TSI_STATUS_ORNGF8 (1 << 8) /* Bit 8: Touch Sensing Electrode Out-of-Range Flag 8 */ +#define TSI_STATUS_ORNGF9 (1 << 9) /* Bit 9: Touch Sensing Electrode Out-of-Range Flag 9 */ +#define TSI_STATUS_ORNGF10 (1 << 10) /* Bit 10: Touch Sensing Electrode Out-of-Range Flag 10 */ +#define TSI_STATUS_ORNGF11 (1 << 11) /* Bit 11: Touch Sensing Electrode Out-of-Range Flag 11 */ +#define TSI_STATUS_ORNGF12 (1 << 12) /* Bit 12: Touch Sensing Electrode Out-of-Range Flag 12 */ +#define TSI_STATUS_ORNGF13 (1 << 13) /* Bit 13: Touch Sensing Electrode Out-of-Range Flag 13 */ +#define TSI_STATUS_ORNGF14 (1 << 14) /* Bit 14: Touch Sensing Electrode Out-of-Range Flag 14 */ +#define TSI_STATUS_ORNGF15 (1 << 15) /* Bit 15: Touch Sensing Electrode Out-of-Range Flag 15 */ +#define TSI_STATUS_ORNGF(n) (1 << (n)) /* Bits 0-15: Touch Sensing Electrode Out-of-Range Flag n, n=0..15 */ +#define TSI_STATUS_ERROF(n) (1 << ((n)+16)) /* Bits 16-31: TouchSensing Error Flag n, n=0..15 */ +#define TSI_STATUS_ERROF0 (1 << 16) /* Bit 16: TouchSensing Error Flag 0 */ +#define TSI_STATUS_ERROF1 (1 << 17) /* Bit 17: TouchSensing Error Flag 1 */ +#define TSI_STATUS_ERROF2 (1 << 18) /* Bit 18: TouchSensing Error Flag 2 */ +#define TSI_STATUS_ERROF3 (1 << 19) /* Bit 19: TouchSensing Error Flag 3 */ +#define TSI_STATUS_ERROF4 (1 << 20) /* Bit 20: TouchSensing Error Flag 4 */ +#define TSI_STATUS_ERROF5 (1 << 21) /* Bit 21: TouchSensing Error Flag 5 */ +#define TSI_STATUS_ERROF6 (1 << 22) /* Bit 22: TouchSensing Error Flag 6 */ +#define TSI_STATUS_ERROF7 (1 << 23) /* Bit 23: TouchSensing Error Flag 7 */ +#define TSI_STATUS_ERROF8 (1 << 24) /* Bit 24: TouchSensing Error Flag 8 */ +#define TSI_STATUS_ERROF9 (1 << 25) /* Bit 25: TouchSensing Error Flag 9 */ +#define TSI_STATUS_ERROF10 (1 << 26) /* Bit 26: TouchSensing Error Flag 10 */ +#define TSI_STATUS_ERROF11 (1 << 27) /* Bit 27: TouchSensing Error Flag 11 */ +#define TSI_STATUS_ERROF12 (1 << 28) /* Bit 28: TouchSensing Error Flag 12 */ +#define TSI_STATUS_ERROF13 (1 << 29) /* Bit 29: TouchSensing Error Flag 13 */ +#define TSI_STATUS_ERROF14 (1 << 30) /* Bit 30: TouchSensing Error Flag 14 */ +#define TSI_STATUS_ERROF15 (1 << 31) /* Bit 31: TouchSensing Error Flag 15 */ + +/* Counter Register n. Note: These values are reversed in the K40 and K60 + * documentation. In the K40/K60 header files, however, CNTN1 is always the + * the field in the most significant bits. Let's go with that. + */ + +#define TSI_CNTR_CNTN_SHIFT (0) /* Bits 0-15: TouchSensing channel n 16-bit counter value */ +#define TSI_CNTR_CNTN_MASK (0xffff << TSI_CNTR_CNTN_SHIFT) +#define TSI_CNTR_CNTN1_SHIFT (16) /* Bits 16-31: TouchSensing channel n-1 16-bit counter value */ +#define TSI_CNTR_CNTN1_MASK (0xffff << TSI_CNTR_CNTN1_SHIFT) + +/* Channel n threshold register */ + +#define TSI_THRESHLD_HTHH_SHIFT (0) /* Bits 0-15: High threshold value */ +#define TSI_THRESHLD_HTHH_MASK (0xffff << TSI_THRESHLD_HTHH_SHIFT) +#define TSI_THRESHLD_LTHH_SHIFT (16) /* Bits 16-31: Low threshold value */ +#define TSI_THRESHLD_LTHH_MASK (0xffff << TSI_THRESHLD_LTHH_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H */ diff --git a/arch/arm/src/kinetis/kinetis_uart.h b/arch/arm/src/kinetis/kinetis_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..fbdf7a3192a86cb4536100ef092b38beed3256a8 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_uart.h @@ -0,0 +1,511 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_uart.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "kinetis_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_UART_BDH_OFFSET 0x0000 /* UART Baud Rate Register High */ +#define KINETIS_UART_BDL_OFFSET 0x0001 /* UART Baud Rate Register Low */ +#define KINETIS_UART_C1_OFFSET 0x0002 /* UART Control Register 1 */ +#define KINETIS_UART_C2_OFFSET 0x0003 /* UART Control Register 2 */ +#define KINETIS_UART_S1_OFFSET 0x0004 /* UART Status Register 1 */ +#define KINETIS_UART_S2_OFFSET 0x0005 /* UART Status Register 2 */ +#define KINETIS_UART_C3_OFFSET 0x0006 /* UART Control Register 3 */ +#define KINETIS_UART_D_OFFSET 0x0007 /* UART Data Register */ +#define KINETIS_UART_MA1_OFFSET 0x0008 /* UART Match Address Registers 1 */ +#define KINETIS_UART_MA2_OFFSET 0x0009 /* UART Match Address Registers 2 */ +#define KINETIS_UART_C4_OFFSET 0x000a /* UART Control Register 4 */ +#define KINETIS_UART_C5_OFFSET 0x000b /* UART Control Register 5 */ +#define KINETIS_UART_ED_OFFSET 0x000c /* UART Extended Data Register */ +#define KINETIS_UART_MODEM_OFFSET 0x000d /* UART Modem Register */ +#define KINETIS_UART_IR_OFFSET 0x000e /* UART Infrared Register */ +#define KINETIS_UART_PFIFO_OFFSET 0x0010 /* UART FIFO Parameters */ +#define KINETIS_UART_CFIFO_OFFSET 0x0011 /* UART FIFO Control Register */ +#define KINETIS_UART_SFIFO_OFFSET 0x0012 /* UART FIFO Status Register */ +#define KINETIS_UART_TWFIFO_OFFSET 0x0013 /* UART FIFO Transmit Watermark */ +#define KINETIS_UART_TCFIFO_OFFSET 0x0014 /* UART FIFO Transmit Count */ +#define KINETIS_UART_RWFIFO_OFFSET 0x0015 /* UART FIFO Receive Watermark */ +#define KINETIS_UART_RCFIFO_OFFSET 0x0016 /* UART FIFO Receive Count */ +#define KINETIS_UART_C7816_OFFSET 0x0017 /* UART 7816 Control Register */ +#define KINETIS_UART_IE7816_OFFSET 0x0018 /* UART 7816 Interrupt Enable Register */ +#define KINETIS_UART_IS7816_OFFSET 0x0019 /* UART 7816 Interrupt Status Register */ +#define KINETIS_UART_WP7816T0_OFFSET 0x001a /* UART 7816 Wait Parameter Register */ +#define KINETIS_UART_WP7816T1_OFFSET 0x001b /* UART 7816 Wait Parameter Register */ +#define KINETIS_UART_WN7816_OFFSET 0x001c /* UART 7816 Wait N Register */ +#define KINETIS_UART_WF7816_OFFSET 0x001d /* UART 7816 Wait FD Register */ +#define KINETIS_UART_ET7816_OFFSET 0x001e /* UART 7816 Error Threshold Register */ +#define KINETIS_UART_TL7816_OFFSET 0x001f /* UART 7816 Transmit Length Register */ + +/* Register Addresses ***************************************************************/ + +#if (KINETIS_NISO7816+KINETIS_NUART) > 0 +# define KINETIS_UART0_BDH (KINETIS_UART0_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART0_BDL (KINETIS_UART0_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART0_C1 (KINETIS_UART0_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART0_C2 (KINETIS_UART0_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART0_S1 (KINETIS_UART0_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART0_S2 (KINETIS_UART0_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART0_C3 (KINETIS_UART0_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART0_D (KINETIS_UART0_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART0_MA1 (KINETIS_UART0_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART0_MA2 (KINETIS_UART0_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART0_C4 (KINETIS_UART0_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART0_C5 (KINETIS_UART0_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART0_ED (KINETIS_UART0_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART0_MODEM (KINETIS_UART0_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART0_IR (KINETIS_UART0_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART0_PFIFO (KINETIS_UART0_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART0_CFIFO (KINETIS_UART0_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART0_SFIFO (KINETIS_UART0_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART0_TWFIFO (KINETIS_UART0_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART0_TCFIFO (KINETIS_UART0_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART0_RWFIFO (KINETIS_UART0_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART0_RCFIFO (KINETIS_UART0_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART0_C7816 (KINETIS_UART0_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART0_IE7816 (KINETIS_UART0_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART0_IS7816 (KINETIS_UART0_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART0_WP7816T0 (KINETIS_UART0_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART0_WP7816T1 (KINETIS_UART0_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART0_WN7816 (KINETIS_UART0_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART0_WF7816 (KINETIS_UART0_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART0_ET7816 (KINETIS_UART0_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART0_TL7816 (KINETIS_UART0_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +#if (KINETIS_NISO7816+KINETIS_NUART) > 1 +# define KINETIS_UART1_BDH (KINETIS_UART1_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART1_BDL (KINETIS_UART1_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART1_C1 (KINETIS_UART1_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART1_C2 (KINETIS_UART1_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART1_S1 (KINETIS_UART1_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART1_S2 (KINETIS_UART1_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART1_C3 (KINETIS_UART1_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART1_D (KINETIS_UART1_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART1_MA1 (KINETIS_UART1_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART1_MA2 (KINETIS_UART1_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART1_C4 (KINETIS_UART1_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART1_C5 (KINETIS_UART1_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART1_ED (KINETIS_UART1_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART1_MODEM (KINETIS_UART1_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART1_IR (KINETIS_UART1_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART1_PFIFO (KINETIS_UART1_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART1_CFIFO (KINETIS_UART1_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART1_SFIFO (KINETIS_UART1_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART1_TWFIFO (KINETIS_UART1_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART1_TCFIFO (KINETIS_UART1_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART1_RWFIFO (KINETIS_UART1_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART1_RCFIFO (KINETIS_UART1_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART1_C7816 (KINETIS_UART1_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART1_IE7816 (KINETIS_UART1_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART1_IS7816 (KINETIS_UART1_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART1_WP7816T0 (KINETIS_UART1_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART1_WP7816T1 (KINETIS_UART1_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART1_WN7816 (KINETIS_UART1_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART1_WF7816 (KINETIS_UART1_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART1_ET7816 (KINETIS_UART1_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART1_TL7816 (KINETIS_UART1_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +#if (KINETIS_NISO7816+KINETIS_NUART) > 2 +# define KINETIS_UART2_BDH (KINETIS_UART2_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART2_BDL (KINETIS_UART2_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART2_C1 (KINETIS_UART2_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART2_C2 (KINETIS_UART2_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART2_S1 (KINETIS_UART2_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART2_S2 (KINETIS_UART2_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART2_C3 (KINETIS_UART2_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART2_D (KINETIS_UART2_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART2_MA1 (KINETIS_UART2_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART2_MA2 (KINETIS_UART2_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART2_C4 (KINETIS_UART2_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART2_C5 (KINETIS_UART2_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART2_ED (KINETIS_UART2_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART2_MODEM (KINETIS_UART2_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART2_IR (KINETIS_UART2_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART2_PFIFO (KINETIS_UART2_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART2_CFIFO (KINETIS_UART2_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART2_SFIFO (KINETIS_UART2_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART2_TWFIFO (KINETIS_UART2_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART2_TCFIFO (KINETIS_UART2_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART2_RWFIFO (KINETIS_UART2_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART2_RCFIFO (KINETIS_UART2_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART2_C7816 (KINETIS_UART2_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART2_IE7816 (KINETIS_UART2_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART2_IS7816 (KINETIS_UART2_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART2_WP7816T0 (KINETIS_UART2_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART2_WP7816T1 (KINETIS_UART2_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART2_WN7816 (KINETIS_UART2_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART2_WF7816 (KINETIS_UART2_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART2_ET7816 (KINETIS_UART2_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART2_TL7816 (KINETIS_UART2_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +#if (KINETIS_NISO7816+KINETIS_NUART) > 3 +# define KINETIS_UART3_BDH (KINETIS_UART3_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART3_BDL (KINETIS_UART3_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART3_C1 (KINETIS_UART3_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART3_C2 (KINETIS_UART3_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART3_S1 (KINETIS_UART3_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART3_S2 (KINETIS_UART3_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART3_C3 (KINETIS_UART3_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART3_D (KINETIS_UART3_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART3_MA1 (KINETIS_UART3_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART3_MA2 (KINETIS_UART3_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART3_C4 (KINETIS_UART3_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART3_C5 (KINETIS_UART3_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART3_ED (KINETIS_UART3_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART3_MODEM (KINETIS_UART3_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART3_IR (KINETIS_UART3_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART3_PFIFO (KINETIS_UART3_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART3_CFIFO (KINETIS_UART3_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART3_SFIFO (KINETIS_UART3_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART3_TWFIFO (KINETIS_UART3_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART3_TCFIFO (KINETIS_UART3_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART3_RWFIFO (KINETIS_UART3_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART3_RCFIFO (KINETIS_UART3_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART3_C7816 (KINETIS_UART3_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART3_IE7816 (KINETIS_UART3_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART3_IS7816 (KINETIS_UART3_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART3_WP7816T0 (KINETIS_UART3_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART3_WP7816T1 (KINETIS_UART3_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART3_WN7816 (KINETIS_UART3_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART3_WF7816 (KINETIS_UART3_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART3_ET7816 (KINETIS_UART3_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART3_TL7816 (KINETIS_UART3_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +#if (KINETIS_NISO7816+KINETIS_NUART) > 4 +# define KINETIS_UART4_BDH (KINETIS_UART4_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART4_BDL (KINETIS_UART4_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART4_C1 (KINETIS_UART4_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART4_C2 (KINETIS_UART4_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART4_S1 (KINETIS_UART4_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART4_S2 (KINETIS_UART4_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART4_C3 (KINETIS_UART4_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART4_D (KINETIS_UART4_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART4_MA1 (KINETIS_UART4_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART4_MA2 (KINETIS_UART4_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART4_C4 (KINETIS_UART4_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART4_C5 (KINETIS_UART4_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART4_ED (KINETIS_UART4_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART4_MODEM (KINETIS_UART4_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART4_IR (KINETIS_UART4_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART4_PFIFO (KINETIS_UART4_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART4_CFIFO (KINETIS_UART4_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART4_SFIFO (KINETIS_UART4_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART4_TWFIFO (KINETIS_UART4_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART4_TCFIFO (KINETIS_UART4_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART4_RWFIFO (KINETIS_UART4_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART4_RCFIFO (KINETIS_UART4_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART4_C7816 (KINETIS_UART4_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART4_IE7816 (KINETIS_UART4_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART4_IS7816 (KINETIS_UART4_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART4_WP7816T0 (KINETIS_UART4_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART4_WP7816T1 (KINETIS_UART4_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART4_WN7816 (KINETIS_UART4_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART4_WF7816 (KINETIS_UART4_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART4_ET7816 (KINETIS_UART4_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART4_TL7816 (KINETIS_UART4_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +#if (KINETIS_NISO7816+KINETIS_NUART) > 5 +# define KINETIS_UART5_BDH (KINETIS_UART5_BASE+KINETIS_UART_BDH_OFFSET) +# define KINETIS_UART5_BDL (KINETIS_UART5_BASE+KINETIS_UART_BDL_OFFSET) +# define KINETIS_UART5_C1 (KINETIS_UART5_BASE+KINETIS_UART_C1_OFFSET) +# define KINETIS_UART5_C2 (KINETIS_UART5_BASE+KINETIS_UART_C2_OFFSET) +# define KINETIS_UART5_S1 (KINETIS_UART5_BASE+KINETIS_UART_S1_OFFSET) +# define KINETIS_UART5_S2 (KINETIS_UART5_BASE+KINETIS_UART_S2_OFFSET) +# define KINETIS_UART5_C3 (KINETIS_UART5_BASE+KINETIS_UART_C3_OFFSET) +# define KINETIS_UART5_D (KINETIS_UART5_BASE+KINETIS_UART_D_OFFSET) +# define KINETIS_UART5_MA1 (KINETIS_UART5_BASE+KINETIS_UART_MA1_OFFSET) +# define KINETIS_UART5_MA2 (KINETIS_UART5_BASE+KINETIS_UART_MA2_OFFSET) +# define KINETIS_UART5_C4 (KINETIS_UART5_BASE+KINETIS_UART_C4_OFFSET) +# define KINETIS_UART5_C5 (KINETIS_UART5_BASE+KINETIS_UART_C5_OFFSET) +# define KINETIS_UART5_ED (KINETIS_UART5_BASE+KINETIS_UART_ED_OFFSET) +# define KINETIS_UART5_MODEM (KINETIS_UART5_BASE+KINETIS_UART_MODEM_OFFSET) +# define KINETIS_UART5_IR (KINETIS_UART5_BASE+KINETIS_UART_IR_OFFSET) +# define KINETIS_UART5_PFIFO (KINETIS_UART5_BASE+KINETIS_UART_PFIFO_OFFSET) +# define KINETIS_UART5_CFIFO (KINETIS_UART5_BASE+KINETIS_UART_CFIFO_OFFSET) +# define KINETIS_UART5_SFIFO (KINETIS_UART5_BASE+KINETIS_UART_SFIFO_OFFSET) +# define KINETIS_UART5_TWFIFO (KINETIS_UART5_BASE+KINETIS_UART_TWFIFO_OFFSET) +# define KINETIS_UART5_TCFIFO (KINETIS_UART5_BASE+KINETIS_UART_TCFIFO_OFFSET) +# define KINETIS_UART5_RWFIFO (KINETIS_UART5_BASE+KINETIS_UART_RWFIFO_OFFSET) +# define KINETIS_UART5_RCFIFO (KINETIS_UART5_BASE+KINETIS_UART_RCFIFO_OFFSET) +# define KINETIS_UART5_C7816 (KINETIS_UART5_BASE+KINETIS_UART_C7816_OFFSET) +# define KINETIS_UART5_IE7816 (KINETIS_UART5_BASE+KINETIS_UART_IE7816_OFFSET) +# define KINETIS_UART5_IS7816 (KINETIS_UART5_BASE+KINETIS_UART_IS7816_OFFSET) +# define KINETIS_UART5_WP7816T0 (KINETIS_UART5_BASE+KINETIS_UART_WP7816T0_OFFSET) +# define KINETIS_UART5_WP7816T1 (KINETIS_UART5_BASE+KINETIS_UART_WP7816T1_OFFSET) +# define KINETIS_UART5_WN7816 (KINETIS_UART5_BASE+KINETIS_UART_WN7816_OFFSET) +# define KINETIS_UART5_WF7816 (KINETIS_UART5_BASE+KINETIS_UART_WF7816_OFFSET) +# define KINETIS_UART5_ET7816 (KINETIS_UART5_BASE+KINETIS_UART_ET7816_OFFSET) +# define KINETIS_UART5_TL7816 (KINETIS_UART5_BASE+KINETIS_UART_TL7816_OFFSET) +#endif + +/* Register Bit Definitions *********************************************************/ +/* UART Baud Rate Register High */ + +#define UART_BDH_SBR_SHIFT (0) /* Bits 0-4: MS Bits 8-13 of the UART Baud Rate Bits */ +#define UART_BDH_SBR_MASK (31 << UART_BDH_SBR_SHIFT) + /* Bit 5: Reserved */ +#define UART_BDH_RXEDGIE (1 << 6) /* Bit 6: RxD Input Active Edge Interrupt Enable */ +#define UART_BDH_LBKDIE (1 << 7) /* Bit 7: LIN Break Detect Interrupt Enable */ + +/* UART Baud Rate Register Low. Bits 0-7 of the UART baud rate bits. */ + +/* UART Control Register 1 */ + +#define UART_C1_PT (1 << 0) /* Bit 0: Parity Type */ +#define UART_C1_PE (1 << 1) /* Bit 1: Parity Enable */ +#define UART_C1_ILT (1 << 2) /* Bit 2: Idle Line Type Select */ +#define UART_C1_WAKE (1 << 3) /* Bit 3: Receiver Wakeup Method Select */ +#define UART_C1_M (1 << 4) /* Bit 4: 9-bit or 8-bit Mode Select */ +#define UART_C1_RSRC (1 << 5) /* Bit 5: Receiver Source Select */ +#define UART_C1_UARTSWAI (1 << 6) /* Bit 6: UART Stops in Wait Mode */ +#define UART_C1_LOOPS (1 << 7) /* Bit 7: Loop Mode Select */ + +/* UART Control Register 2 */ + +#define UART_C2_SBK (1 << 0) /* Bit 0: Send Break */ +#define UART_C2_RWU (1 << 1) /* Bit 1: Receiver Wakeup Control */ +#define UART_C2_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define UART_C2_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define UART_C2_ILIE (1 << 4) /* Bit 4: Idle Line Interruptor Enable */ +#define UART_C2_RIE (1 << 5) /* Bit 5: Receiver Full Interrupt or DMA Transfer Enable */ +#define UART_C2_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define UART_C2_TIE (1 << 7) /* Bit 7: Transmitter Interrupt or DMA Transfer Enable */ +#define UART_C2_ALLINTS (0xf0) + +/* UART Status Register 1 */ + +#define UART_S1_PF (1 << 0) /* Bit 0: Parity Error Flag */ +#define UART_S1_FE (1 << 1) /* Bit 1: Framing Error Flag */ +#define UART_S1_NF (1 << 2) /* Bit 2: Noise Flag */ +#define UART_S1_OR (1 << 3) /* Bit 3: Receiver Overrun Flag */ +#define UART_S1_IDLE (1 << 4) /* Bit 4: Idle Line Flag */ +#define UART_S1_RDRF (1 << 5) /* Bit 5: Receive Data Register Full Flag */ +#define UART_S1_TC (1 << 6) /* Bit 6: Transmit Complete Flag */ +#define UART_S1_TDRE (1 << 7) /* Bit 7: Transmit Data Register Empty Flag */ + +/* UART Status Register 2 */ + +#define UART_S2_RAF (1 << 0) /* Bit 0: Receiver Active Flag */ +#define UART_S2_LBKDE (1 << 1) /* Bit 1: LIN Break Detection Enable */ +#define UART_S2_BRK13 (1 << 2) /* Bit 2: Break Transmit Character Length */ +#define UART_S2_RWUID (1 << 3) /* Bit 3: Receive Wakeup Idle Detect */ +#define UART_S2_RXINV (1 << 4) /* Bit 4: Receive Data Inversion */ +#define UART_S2_MSBF (1 << 5) /* Bit 5: Most Significant Bit First */ +#define UART_S2_RXEDGIF (1 << 6) /* Bit 6: RxD Pin Active Edge Interrupt Flag */ +#define UART_S2_LBKDIF (1 << 7) /* Bit 7: LIN Break Detect Interrupt Flag */ + +/* UART Control Register 3 */ + +#define UART_C3_PEIE (1 << 0) /* Bit 0: Parity Error Interrupt Enable */ +#define UART_C3_FEIE (1 << 1) /* Bit 1: Framing Error Interrupt Enable */ +#define UART_C3_NEIE (1 << 2) /* Bit 2: Noise Error Interrupt Enable */ +#define UART_C3_ORIE (1 << 3) /* Bit 3: Overrun Error Interrupt Enable */ +#define UART_C3_TXINV (1 << 4) /* Bit 4: Transmit Data Inversion */ +#define UART_C3_TXDIR (1 << 5) /* Bit 5: Transmitter Pin Data Direction in Single-Wire mode */ +#define UART_C3_T8 (1 << 6) /* Bit 6: Transmit Bit 8 */ +#define UART_C3_R8 (1 << 7) /* Bit 7: Received Bit 8 */ + +/* UART Data Register: 8-bit data register. */ +/* UART Match Address Registers 1 & 2: 8-bit address registers */ + +/* UART Control Register 4 */ + +#define UART_C4_BRFA_SHIFT (0) /* Bits 0-4: Baud Rate Fine Adjust */ +#define UART_C4_BRFA_MASK (31 << UART_C4_BRFA_SHIFT) +#define UART_C4_M10 (1 << 5) /* Bit 5: 10-bit Mode select */ +#define UART_C4_MAEN2 (1 << 6) /* Bit 6: Match Address Mode Enable 2 */ +#define UART_C4_MAEN1 (1 << 7) /* Bit 7: Match Address Mode Enable 1 */ + +/* UART Control Register 5 */ + + /* Bit 0-4: Reserved */ +#define UART_C5_RDMAS (1 << 5) /* Bit 5: Receiver Full DMA Select */ + /* Bit 6: Reserved */ +#define UART_C5_TDMAS (1 << 7) /* Bit 7: Transmitter DMA Select */ + +/* UART Extended Data Register */ + + /* Bit 0-5: Reserved */ +#define UART_ED_PARITYE (1 << 6) /* Bit 6: The current received dataword contained + * in D and C3[R8] was received with a parity error */ +#define UART_ED_NOISY (1 << 7) /* Bit 7: The current received dataword contained + * in D and C3[R8] was received with noise */ + +/* UART Modem Register */ + +#define UART_MODEM_TXCTSE (1 << 0) /* Bit 0: Transmitter clear-to-send enable */ +#define UART_MODEM_TXRTSE (1 << 1) /* Bit 1: Transmitter request-to-send enable */ +#define UART_MODEM_TXRTSPOL (1 << 2) /* Bit 2: Transmitter request-to-send polarity */ +#define UART_MODEM_RXRTSE (1 << 3) /* Bit 3: Receiver request-to-send enable */ + /* Bits 4-7: Reserved */ + +/* UART Infrared Register */ + +#define UART_IR_TNP_SHIFT (0) /* Bits 0-1: Transmitter narrow pulse */ +#define UART_IR_TNP_MASK (3 << UART_IR_TNP_SHIFT) +# define UART_IR_TNP_316THS (0 << UART_IR_TNP_SHIFT) /* 3/16 */ +# define UART_IR_TNP_16TH (1 << UART_IR_TNP_SHIFT) /* 1/16 */ +# define UART_IR_TNP_32ND (2 << UART_IR_TNP_SHIFT) /* 1/32 */ +# define UART_IR_TNP_4TH (3 << UART_IR_TNP_SHIFT) /* 1/4 */ +#define UART_IR_IREN (1 << 2) /* Bit 2: Infrared enable */ + /* Bits 3-7: Reserved */ + +/* UART FIFO Parameters */ + +#define UART_PFIFO_RXFIFOSIZE_SHIFT (0) /* Bits 0-2: Receive FIFO. Buffer Depth */ +#define UART_PFIFO_RXFIFOSIZE_MASK (7 << UART_PFIFO_RXFIFOSIZE_SHIFT) +# define UART_PFIFO_RXFIFOSIZE_1 (0 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 1 */ +# define UART_PFIFO_RXFIFOSIZE_4 (1 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 4 */ +# define UART_PFIFO_RXFIFOSIZE_8 (2 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 8 */ +# define UART_PFIFO_RXFIFOSIZE_16 (3 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 16 */ +# define UART_PFIFO_RXFIFOSIZE_32 (4 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 32 */ +# define UART_PFIFO_RXFIFOSIZE_64 (5 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 64 */ +# define UART_PFIFO_RXFIFOSIZE_128 (6 << UART_PFIFO_RXFIFOSIZE_SHIFT) /* 128 */ +#define UART_PFIFO_RXFE (1 << 3) /* Bit 3: Receive FIFO Enable */ +#define UART_PFIFO_TXFIFOSIZE_SHIFT (4) /* Bits 4-6: Transmit FIFO. Buffer Depth */ +#define UART_PFIFO_TXFIFOSIZE_MASK (7 << UART_PFIFO_TXFIFOSIZE_SHIFT) +# define UART_PFIFO_TXFIFOSIZE_1 (0 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 1 */ +# define UART_PFIFO_TXFIFOSIZE_4 (1 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 4 */ +# define UART_PFIFO_TXFIFOSIZE_8 (2 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 8 */ +# define UART_PFIFO_TXFIFOSIZE_16 (3 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 16 */ +# define UART_PFIFO_TXFIFOSIZE_32 (4 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 32 */ +# define UART_PFIFO_TXFIFOSIZE_64 (5 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 64 */ +# define UART_PFIFO_TXFIFOSIZE_128 (6 << UART_PFIFO_TXFIFOSIZE_SHIFT) /* 128 */ +#define UART_PFIFO_TXFE (1 << 7) /* Bit 7: Transmit FIFO Enable */ + +/* UART FIFO Control Register */ + +#define UART_CFIFO_RXUFE (1 << 0) /* Bit 0: Receive FIFO Underflow Interrupt Enable */ +#define UART_CFIFO_TXOFE (1 << 1) /* Bit 1: Transmit FIFO Overflow Interrupt Enable */ + /* Bits 2-5: Reserved */ +#define UART_CFIFO_RXFLUSH (1 << 6) /* Bit 6: Receive FIFO/Buffer Flush */ +#define UART_CFIFO_TXFLUSH (1 << 7) /* Bit 7: Transmit FIFO/Buffer Flush */ + +/* UART FIFO Status Register */ + +#define UART_SFIFO_RXUF (1 << 0) /* Bit 0: Receiver Buffer Underflow Flag */ +#define UART_SFIFO_TXOF (1 << 1) /* Bit 1: Transmitter Buffer Overflow Flag */ + /* Bits 2-5: Reserved */ +#define UART_SFIFO_RXEMPT (1 << 6) /* Bit 6: Receive Buffer/FIFO Empty */ +#define UART_SFIFO_TXEMPT (1 << 7) /* Bit 7: Transmit Buffer/FIFO Empty */ + +/* UART FIFO Transmit Watermark. 8-bit watermark value. */ +/* UART FIFO Transmit Count. 8-bit count value */ +/* UART FIFO Receive Watermark. 8-bit watermark value. */ +/* UART FIFO Receive Count. 8-bit count value */ + +/* UART 7816 Control Register */ + +#define UART_C7816_ISO7816E (1 << 0) /* Bit 0: ISO-7816 Functionality Enabled */ +#define UART_C7816_TTYPE (1 << 1) /* Bit 1: Transfer Type */ +#define UART_C7816_INIT (1 << 2) /* Bit 2: Detect Initial Character */ +#define UART_C7816_ANACK (1 << 3) /* Bit 3: Generate NACK on Error */ +#define UART_C7816_ONACK (1 << 4) /* Bit 4: Generate NACK on Overflow */ + /* Bits 5-7: Reserved */ + +/* UART 7816 Interrupt Enable Register */ + +#define UART_IE7816_RXTE (1 << 0) /* Bit 0: Receive Threshold Exceeded Interrupt Enable */ +#define UART_IE7816_TXTE (1 << 1) /* Bit 1: Transmit Threshold Exceeded Interrupt Enable */ +#define UART_IE7816_GTVE (1 << 2) /* Bit 2: Guard Timer Violated Interrupt Enable */ + /* Bit 3: Reserved */ +#define UART_IE7816_INITDE (1 << 4) /* Bit 4: Initial Character Detected Interrupt Enable */ +#define UART_IE7816_BWTE (1 << 5) /* Bit 5: Block Wait Timer Interrupt Enable */ +#define UART_IE7816_CWTE (1 << 6) /* Bit 6: Character Wait Timer Interrupt Enable */ +#define UART_IE7816_WTE (1 << 7) /* Bit 7: Wait Timer Interrupt Enable */ + +/* UART 7816 Interrupt Status Register */ + +#define UART_IS7816_RXT (1 << 0) /* Bit 0: Receive Threshold Exceeded Interrupt */ +#define UART_IS7816_TXT (1 << 1) /* Bit 1: Transmit Threshold Exceeded Interrupt */ +#define UART_IS7816_GTV (1 << 2) /* Bit 2: Guard Timer Violated Interrupt */ + /* Bit 3: Reserved */ +#define UART_IS7816_INITD (1 << 4) /* Bit 4: Initial Character Detected Interrupt */ +#define UART_IS7816_BWT (1 << 5) /* Bit 5: Block Wait Timer Interrupt */ +#define UART_IS7816_CWT (1 << 6) /* Bit 6: Character Wait Timer Interrupt */ +#define UART_IS7816_WT (1 << 7) /* Bit 7: Wait Timer Interrupt */ + +/* UART 7816 Wait Parameter Register. 8-bit Wait Timer Interrupt value. */ + +/* UART 7816 Wait Parameter Register */ + +#define UART_WP7816T1_BWI_SHIFT (0) /* Bit 0-3: Block Wait Time Integer(C7816[TTYPE] = 1) */ +#define UART_WP7816T1_BWI_MASK (15 << UART_WP7816T1_BWI_SHIFT) +#define UART_WP7816T1_CWI_SHIFT (4) /* Bits 4-7: Character Wait Time Integer (C7816[TTYPE] = 1) */ +#define UART_WP7816T1_CWI_MASK (15 << UART_WP7816T1_CWI_SHIFT) + +/* UART 7816 Wait N Register. 8-bit Guard Band value. */ +/* UART 7816 Wait FD Register. 8-bit FD Multiplier value. */ + +/* UART 7816 Error Threshold Register */ + +#define UART_ET7816_RXTHRESH_SHIFT (0) /* Bit 0-3: Receive NACK Threshold */ +#define UART_ET7816_RXTHRESH_MASK (15 << UART_ET7816_RXTHRESHOLD_SHIFT) +#define UART_ET7816_TXTHRESH_SHIFT (4) /* Bits 4-7: Transmit NACK Threshold */ +#define UART_ET7816_TXTHRESH_MASK (15 << UART_ET7816_TXTHRESHOLD_MASK) + +/* UART 7816 Transmit Length Register. 8-bit Transmit Length value */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H */ diff --git a/arch/arm/src/kinetis/kinetis_usbdcd.h b/arch/arm/src/kinetis/kinetis_usbdcd.h new file mode 100644 index 0000000000000000000000000000000000000000..fad76d1500e8771666c3dc123a676dd905d72712 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_usbdcd.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_usbdcd.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KINETIS_USBDCD_CONTROL_OFFSET 0x0000 /* Control Register */ +#define KINETIS_USBDCD_CLOCK_OFFSET 0x0004 /* Clock Register */ +#define KINETIS_USBDCD_STATUS_OFFSET 0x0008 /* Status Register */ +#define KINETIS_USBDCD_TIMER0_OFFSET 0x0010 /* TIMER0 Register */ +#define KINETIS_USBDCD_TIMER1_OFFSET 0x0014 /* TIMER1 Register */ +#define KINETIS_USBDCD_TIMER2_OFFSET 0x0018 /* TIMER2 Register */ + +/* Register Addresses ***************************************************************/ + +#define KINETIS_USBDCD_CONTROL (KINETIS_USBDCD_BASE+KINETIS_USBDCD_CONTROL_OFFSET) +#define KINETIS_USBDCD_CLOCK (KINETIS_USBDCD_BASE+KINETIS_USBDCD_CLOCK_OFFSET) +#define KINETIS_USBDCD_STATUS (KINETIS_USBDCD_BASE+KINETIS_USBDCD_STATUS_OFFSET) +#define KINETIS_USBDCD_TIMER0 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER0_OFFSET) +#define KINETIS_USBDCD_TIMER1 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER1_OFFSET) +#define KINETIS_USBDCD_TIMER2 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER2_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Control Register */ +#define USBDCD_CONTROL_IACK (1 << 0) /* Bit 0: Interrupt Acknowledge */ + /* Bits 1-7: Reserved */ +#define USBDCD_CONTROL_IF (1 << 8) /* Bit 8: Interrupt Flag */ + /* Bits 9-15: Reserved */ +#define USBDCD_CONTROL_IE (1 << 16) /* Bit 16: Interrupt Enable */ + /* Bits 17-23: Reserved */ +#define USBDCD_CONTROL_START (1 << 24) /* Bit 24: Start Change Detection Sequence */ +#define USBDCD_CONTROL_SR (1 << 25) /* Bit 25: Software Reset */ + /* Bits 26-31: Reserved */ +/* Clock Register */ +#define USBDCD_CLOCK_UNIT (1 << 0) /* Bit 0: Unit of measurement encoding for Clock Speed */ + /* Bit 1: Reserved */ +#define USBDCD_CLOCK_SPEED_SHIFT (2) /* Bits 2-11: Value of Clock Speed */ +#define USBDCD_CLOCK_SPEED_MASK (0x3ff << USBDCD_CLOCK_SPEED_SHIFT) + /* Bits 12-31: Reserved */ +/* Status Register */ + /* Bits 0-15: Reserved */ +#define USBDCD_STATUS_SEQ_RES_SHIFT (16) /* Bits 16-17: Charger Detection Sequence Results */ +#define USBDCD_STATUS_SEQ_RES_MASK (3 << USBDCD_STATUS_SEQ_RES_SHIFT) +# define USBDCD_STATUS_SEQ_RES_NONE (0 << USBDCD_STATUS_SEQ_RES_SHIFT) /* No results */ +# define USBDCD_STATUS_SEQ_RES_STD (1 << USBDCD_STATUS_SEQ_RES_SHIFT) /* Standard host */ +# define USBDCD_STATUS_SEQ_RES_CHGPORT (2 << USBDCD_STATUS_SEQ_RES_SHIFT) /* Charging port */ +# define USBDCD_STATUS_SEQ_RES_DEDCTD (3 << USBDCD_STATUS_SEQ_RES_SHIFT) /* Dedicated charge */ +#define USBDCD_STATUS_SEQ_STAT_SHIFT (18) /* Bits 18-19: Charger Detection Sequence Stat */ +#define USBDCD_STATUS_SEQ_STAT_MASK (3 << USBDCD_STATUS_SEQ_STAT_SHIFT) +# define USBDCD_STATUS_SEQ_STAT_DISAB (0 << USBDCD_STATUS_SEQ_STAT_SHIFT) /* Not enabled or data pins not detected */ +# define USBDCD_STATUS_SEQ_STAT_DATPIN (1 << USBDCD_STATUS_SEQ_STAT_SHIFT) /* Data pin contact detection complete */ +# define USBDCD_STATUS_SEQ_STAT_CHGDET (2 << USBDCD_STATUS_SEQ_STAT_SHIFT) /* Charger detection is complete */ +# define USBDCD_STATUS_SEQ_STAT_CHGTYPE (3 << USBDCD_STATUS_SEQ_STAT_SHIFT) /* Charger type detection complete */ +#define USBDCD_STATUS_ERR (1 << 20) /* Bit 20: Error Flag */ +#define USBDCD_STATUS_TO (1 << 21) /* Bit 21: Timeout Flag */ +#define USBDCD_STATUS_ACTIVE (1 << 22) /* Bit 22: Active Status Indicator */ + /* Bits 23-31: Reserved */ +/* TIMER0 Register */ + +#define USBDCD_TIMER0_TUNITCON_SHIFT (0) /* Bits 0-11: Unit Connection Timer Elapse (in ms) */ +#define USBDCD_TIMER0_TUNITCON_MASK (0xfff << USBDCD_TIMER0_TUNITCON_SHIFT) + /* Bits 12-15: Reserved */ +#define USBDCD_TIMER0_TSEQ_INIT_SHIFT (16) /* Bits 16-25: Sequence Initiation Time */ +#define USBDCD_TIMER0_TSEQ_INIT_MASK (0x3ff << USBDCD_TIMER0_TSEQ_INIT_SHIFT) + /* Bits 26-31: Reserved */ +/* TIMER1 Register */ + +#define USBDCD_TIMER1_TVDPSRC_ON_SHIFT (0) /* Bits 0-9: Time Period Comparator Enabled */ +#define USBDCD_TIMER1_TVDPSRC_ON_MASK (0x3ff << USBDCD_TIMER1_TVDPSRC_ON_SHIFT) + /* Bits 10-15: Reserved */ +#define USBDCD_TIMER1_TDCD_DBNC_SHIFT (16) /* Bits 16-25: Time Period to Debounce D+ Signal */ +#define USBDCD_TIMER1_TDCD_DBNC__MASK (0x3ff << USBDCD_TIMER1_TDCD_DBNC_SHIFT) + /* Bits 26-31: Reserved */ +/* TIMER2 Register */ + /* Bits 26-31: Reserved */ +#define USBDCD_TIMER2_TVDPSRC_CON_SHIFT (16) /* Bits 16-25: Time Period Before Enabling D+ Pullup */ +#define USBDCD_TIMER2_TVDPSRC_CON_MASK (0x3ff << USBDCD_TIMER2_TVDPSRC_CON_SHIFT) + /* Bits 4-15: Reserved */ +#define USBDCD_TIMER2_CHECK_DM_SHIFT (0) /* Bits 0-3: Time Before Check of D- Line */ +#define USBDCD_TIMER2_CHECK_DM_MASK (15 << USBDCD_TIMER2_CHECK_DM_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H */ diff --git a/arch/arm/src/kinetis/kinetis_usbotg.h b/arch/arm/src/kinetis/kinetis_usbotg.h new file mode 100644 index 0000000000000000000000000000000000000000..127c718312d629bc98bd5c45cb983f650a53f6e8 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_usbotg.h @@ -0,0 +1,328 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_usbotg.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_USBOTG_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_USBOTG_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_USB_PERID_OFFSET 0x0000 /* Peripheral ID Register */ +#define KINETIS_USB_IDCOMP_OFFSET 0x0004 /* Peripheral ID Complement Register */ +#define KINETIS_USB_REV_OFFSET 0x0008 /* Peripheral Revision Register */ +#define KINETIS_USB_ADDINFO_OFFSET 0x000c /* Peripheral Additional Info Register */ +#define KINETIS_USB_OTGISTAT_OFFSET 0x0010 /* OTG Interrupt Status Register */ +#define KINETIS_USB_OTGICR_OFFSET 0x0014 /* OTG Interrupt Control Register */ +#define KINETIS_USB_OTGSTAT_OFFSET 0x0018 /* OTG Status Register */ +#define KINETIS_USB_OTGCTL_OFFSET 0x001c /* OTG Control Register */ +#define KINETIS_USB_ISTAT_OFFSET 0x0080 /* Interrupt Status Register */ +#define KINETIS_USB_INTEN_OFFSET 0x0084 /* Interrupt Enable Register */ +#define KINETIS_USB_ERRSTAT_OFFSET 0x0088 /* Error Interrupt Status Register */ +#define KINETIS_USB_ERREN_OFFSET 0x008c /* Error Interrupt Enable Register */ +#define KINETIS_USB_STAT_OFFSET 0x0090 /* Status Register */ +#define KINETIS_USB_CTL_OFFSET 0x0094 /* Control Register */ +#define KINETIS_USB_ADDR_OFFSET 0x0098 /* Address Register */ +#define KINETIS_USB_BDTPAGE1_OFFSET 0x009c /* BDT Page Register 1 */ +#define KINETIS_USB_FRMNUML_OFFSET 0x00a0 /* Frame Number Register Low */ +#define KINETIS_USB_FRMNUMH_OFFSET 0x00a4 /* Frame Number Register High */ +#define KINETIS_USB_TOKEN_OFFSET 0x00a8 /* Token Register */ +#define KINETIS_USB_SOFTHLD_OFFSET 0x00ac /* SOF Threshold Register */ +#define KINETIS_USB_BDTPAGE2_OFFSET 0x00b0 /* BDT Page Register 2 */ +#define KINETIS_USB_BDTPAGE3_OFFSET 0x00b4 /* BDT Page Register 3 */ + +#define KINETIS_USB_ENDPT_OFFSET(n) (0x00c0+((n)<<2)) /* Endpoint n Control Register */ +#define KINETIS_USB_ENDPT0_OFFSET 0x00c0 /* Endpoint 0 Control Register */ +#define KINETIS_USB_ENDPT1_OFFSET 0x00c4 /* Endpoint 1 Control Register */ +#define KINETIS_USB_ENDPT2_OFFSET 0x00c8 /* Endpoint 2 Control Register */ +#define KINETIS_USB_ENDPT3_OFFSET 0x00cc /* Endpoint 3 Control Register */ +#define KINETIS_USB_ENDPT4_OFFSET 0x00d0 /* Endpoint 4 Control Register */ +#define KINETIS_USB_ENDPT5_OFFSET 0x00d4 /* Endpoint 5 Control Register */ +#define KINETIS_USB_ENDPT6_OFFSET 0x00d8 /* Endpoint 6 Control Register */ +#define KINETIS_USB_ENDPT7_OFFSET 0x00dc /* Endpoint 7 Control Register */ +#define KINETIS_USB_ENDPT8_OFFSET 0x00e0 /* Endpoint 8 Control Register */ +#define KINETIS_USB_ENDPT9_OFFSET 0x00e4 /* Endpoint 9 Control Register */ +#define KINETIS_USB_ENDPT10_OFFSET 0x00e8 /* Endpoint 10 Control Register */ +#define KINETIS_USB_ENDPT11_OFFSET 0x00ec /* Endpoint 11 Control Register */ +#define KINETIS_USB_ENDPT12_OFFSET 0x00f0 /* Endpoint 12 Control Register */ +#define KINETIS_USB_ENDPT13_OFFSET 0x00f4 /* Endpoint 13 Control Register */ +#define KINETIS_USB_ENDPT14_OFFSET 0x00f8 /* Endpoint 14 Control Register */ +#define KINETIS_USB_ENDPT15_OFFSET 0x00fc /* Endpoint 15 Control Register */ + +#define KINETIS_USB_USBCTRL_OFFSET 0x0100 /* USB Control Register */ +#define KINETIS_USB_OBSERVE_OFFSET 0x0104 /* USB OTG Observe Register */ +#define KINETIS_USB_CONTROL_OFFSET 0x0108 /* USB OTG Control Register */ +#define KINETIS_USB_USBTRC0_OFFSET 0x010c /* USB Transceiver Control Register 0 */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_USB0_PERID (KINETIS_USB0_BASE+KINETIS_USB_PERID_OFFSET) +#define KINETIS_USB0_IDCOMP (KINETIS_USB0_BASE+KINETIS_USB_IDCOMP_OFFSET) +#define KINETIS_USB0_REV (KINETIS_USB0_BASE+KINETIS_USB_REV_OFFSET) +#define KINETIS_USB0_ADDINFO (KINETIS_USB0_BASE+KINETIS_USB_ADDINFO_OFFSET) +#define KINETIS_USB0_OTGISTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGISTAT_OFFSET) +#define KINETIS_USB0_OTGICR (KINETIS_USB0_BASE+KINETIS_USB_OTGICR_OFFSET) +#define KINETIS_USB0_OTGSTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGSTAT_OFFSET) +#define KINETIS_USB0_OTGCTL (KINETIS_USB0_BASE+KINETIS_USB_OTGCTL_OFFSET) +#define KINETIS_USB0_ISTAT (KINETIS_USB0_BASE+KINETIS_USB_ISTAT_OFFSET) +#define KINETIS_USB0_INTEN (KINETIS_USB0_BASE+KINETIS_USB_INTEN_OFFSET) +#define KINETIS_USB0_ERRSTAT (KINETIS_USB0_BASE+KINETIS_USB_ERRSTAT_OFFSET) +#define KINETIS_USB0_ERREN (KINETIS_USB0_BASE+KINETIS_USB_ERREN_OFFSET) +#define KINETIS_USB0_STAT (KINETIS_USB0_BASE+KINETIS_USB_STAT_OFFSET) +#define KINETIS_USB0_CTL (KINETIS_USB0_BASE+KINETIS_USB_CTL_OFFSET) +#define KINETIS_USB0_ADDR (KINETIS_USB0_BASE+KINETIS_USB_ADDR_OFFSET) +#define KINETIS_USB0_BDTPAGE1 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE1_OFFSET) +#define KINETIS_USB0_FRMNUML (KINETIS_USB0_BASE+KINETIS_USB_FRMNUML_OFFSET) +#define KINETIS_USB0_FRMNUMH (KINETIS_USB0_BASE+KINETIS_USB_FRMNUMH_OFFSET) +#define KINETIS_USB0_TOKEN (KINETIS_USB0_BASE+KINETIS_USB_TOKEN_OFFSET) +#define KINETIS_USB0_SOFTHLD (KINETIS_USB0_BASE+KINETIS_USB_SOFTHLD_OFFSET) +#define KINETIS_USB0_BDTPAGE2 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE2_OFFSET) +#define KINETIS_USB0_BDTPAGE3 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE3_OFFSET) + +#define KINETIS_USB0_ENDPT(n) (KINETIS_USB0_BASE+KINETIS_USB_ENDPT_OFFSET(n)) +#define KINETIS_USB0_ENDPT0 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT0_OFFSET) +#define KINETIS_USB0_ENDPT1 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT1_OFFSET) +#define KINETIS_USB0_ENDPT2 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT2_OFFSET) +#define KINETIS_USB0_ENDPT3 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT3_OFFSET) +#define KINETIS_USB0_ENDPT4 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT4_OFFSET) +#define KINETIS_USB0_ENDPT5 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT5_OFFSET) +#define KINETIS_USB0_ENDPT6 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT6_OFFSET) +#define KINETIS_USB0_ENDPT7 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT7_OFFSET) +#define KINETIS_USB0_ENDPT8 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT8_OFFSET) +#define KINETIS_USB0_ENDPT9 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT9_OFFSET) +#define KINETIS_USB0_ENDPT10 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT10_OFFSET) +#define KINETIS_USB0_ENDPT11 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT11_OFFSET) +#define KINETIS_USB0_ENDPT12 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT12_OFFSET) +#define KINETIS_USB0_ENDPT13 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT13_OFFSET) +#define KINETIS_USB0_ENDPT14 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT14_OFFSET) +#define KINETIS_USB0_ENDPT15 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT15_OFFSET) + +#define KINETIS_USB0_USBCTRL (KINETIS_USB0_BASE+KINETIS_USB_USBCTRL_OFFSET) +#define KINETIS_USB0_OBSERVE (KINETIS_USB0_BASE+KINETIS_USB_OBSERVE_OFFSET) +#define KINETIS_USB0_CONTROL (KINETIS_USB0_BASE+KINETIS_USB_CONTROL_OFFSET) +#define KINETIS_USB0_USBTRC0 (KINETIS_USB0_BASE+KINETIS_USB_USBTRC0_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* Peripheral ID Register (8-bit) */ + /* Bits 6-7: Reserved */ +#define USB_PERID_MASK (0x3f) /* Bits 0-5: Peripheral identification bits */ + +/* Peripheral ID Complement Register (8-bit) */ +#define USB_IDCOMP_ + /* Bits 6-7: Reserved */ +#define USB_IDCOMP_MASK (0x3f) /* Bits 0-5: Ones complement of peripheral identification bits */ + +/* Peripheral Revision Register (8-bit revision number) */ + +/* Peripheral Additional Info Register (8-bit) */ + +#define USB_ADDINFO_IEHOST (1 << 0) /* Bit 0: This bit is set if host mode is enabled */ + /* Bits 1-2: Reserved */ +#define USB_ADDINFO_IRQNUM_SHIFT (3) /* Bits 3-7: Assigned Interrupt Request Number */ +#define USB_ADDINFO_IRQNUM_MASK (31 << USB_ADDINFO_IRQNUM_SHIFT) + +/* OTG Interrupt Status Register(8-bit) */ + +#define USB_OTGISTAT_AVBUSCHG (1 << 0) /* Bit 0: Change in VBUS is detected on an A device */ + /* Bit 1: Reserved */ +#define USB_OTGISTAT_B_SESS_CHG (1 << 2) /* Bit 2: Change in VBUS is detected on a B device */ +#define USB_OTGISTAT_SESSVLDCHG (1 << 3) /* Bit 3: Change in VBUS is detected */ + /* Bit 4: Reserved */ +#define USB_OTGISTAT_LINE_STATE_CHG (1 << 5) /* Bit 5: Change USB line state */ +#define USB_OTGISTAT_ONEMSEC (1 << 6) /* Bit 6: Set when the 1 millisecond timer expires */ +#define USB_OTGISTAT_IDCHG (1 << 7) /* Bit 7: Change in ID Signal from the USB connector */ + +/* OTG Interrupt Control Register (8-bit) */ + +#define USB_OTGICR_AVBUSEN (1 << 0) /* Bit 0: A VBUS Valid interrupt enable */ + /* Bit 1: Reserved */ +#define USB_OTGICR_BSESSEN (1 << 2) /* Bit 2: B Session END interrupt enable */ +#define USB_OTGICR_SESSVLDEN (1 << 3) /* Bit 3: Session valid interrupt enable */ + /* Bit 4: Reserved */ +#define USB_OTGICR_LINESTATEEN (1 << 5) /* Bit 5: Line State change interrupt enable */ +#define USB_OTGICR_ONEMSECEN (1 << 6) /* Bit 6: 1 millisecond interrupt enable */ +#define USB_OTGICR_IDEN (1 << 7) /* Bit 7: ID interrupt enable */ + +/* OTG Status Register (8-bit) */ + +#define USB_OTGSTAT_AVBUSVLD (1 << 0) /* Bit 0: A VBUS Valid */ + /* Bit 1: Reserved */ +#define USB_OTGSTAT_BSESSEND (1 << 2) /* Bit 2: B Session END */ +#define USB_OTGSTAT_SESS_VLD (1 << 3) /* Bit 3: Session valid */ + /* Bit 4: Reserved */ +#define USB_OTGSTAT_LINESTATESTABLE (1 << 5) /* Bit 5: OTGISTAT LINE_STATE_CHG bit stable */ +#define USB_OTGSTAT_ONEMSECEN (1 << 6) /* Bit 6: Reserved for the 1msec count */ +#define USB_OTGSTAT_ID (1 << 7) /* Bit 7: Current state of the ID pin on the USB connector */ + +/* OTG Control Register (8-bit) */ + /* Bits 0-1: Reserved */ +#define USB_OTGCTL_OTGEN (1 << 2) /* Bit 2: On-The-Go pullup/pulldown resistor enable */ + /* Bit 3: Reserved */ +#define USB_OTGCTL_DMLOW (1 << 4) /* Bit 4: D- Data Line pull-down resistor enable */ +#define USB_OTGCTL_DPLOW (1 << 5) /* Bit 5: D+ Data Line pull-down resistor enable */ + /* Bit 6: Reserved */ +#define USB_OTGCTL_DPHIGH (1 << 7) /* Bit 7: D+ Data Line pullup resistor enable */ + +/* Interrupt Status Register Interrupt Enable Register (8-bit) */ + +#define USB_INT_USBRST (1 << 0) /* Bit 0: USB Module has decoded a valid USB reset */ +#define USB_INT_ERROR (1 << 1) /* Bit 1: Any of the error conditions within the ERRSTAT register */ +#define USB_INT_SOFTOK (1 << 2) /* Bit 2: USB Module received a Start Of Frame (SOF) token */ +#define USB_INT_TOKDNE (1 << 3) /* Bit 3: Current token being processed has completed */ +#define USB_INT_SLEEP (1 << 4) /* Bit 4: Constant idle on the USB bus for 3 milliseconds */ +#define USB_INT_RESUME (1 << 5) /* Bit 5: Signal remote wake-up signaling */ +#define USB_INT_ATTACH (1 << 6) /* Bit 6: Attach Interrupt */ +#define USB_INT_STALL (1 << 7) /* Bit 7: Stall Interrupt */ + +/* Error Interrupt Status Register and Error Interrupt Enable Register (8-bit) */ + +#define USB_ERRSTAT_PIDERR (1 << 0) /* Bit 0: This bit is set when the PID check field fails */ +#define USB_ERRSTAT_CRC5EOF (1 << 1) /* Bit 1: Host data CRC error or End of frame errors */ +#define USB_ERRSTAT_CRC16 (1 << 2) /* Bit 2: Data packet is rejected due to a CRC16 error */ +#define USB_ERRSTAT_DFN8 (1 << 3) /* Bit 3: Data field received was not 8 bits in length */ +#define USB_ERRSTAT_BTOERR (1 << 4) /* Bit 4: Bus turnaround timeout error occurred */ +#define USB_ERRSTAT_DMAERR (1 << 5) /* Bit 5: DMA error */ + /* Bit 6: Reserved */ +#define USB_ERRSTAT_BTSERR (1 << 7) /* Bit 7: Bit stuff error is detected */ + +/* Status Register (8-bit) */ + + /* Bits 0-1: Reserved */ +#define USB_STAT_ODD (1 << 2) /* Bit 2: Last Buffer Descriptor was in the odd bank of the BDT */ +#define USB_STAT_TX (1 << 3) /* Bit 3: Transmit Indicator */ +#define USB_STAT_ENDP_SHIFT (4) /* Bits 4-7: Endpoint address that received or transmitted the token */ +#define USB_STAT_ENDP_MASK (15 << USB_STAT_ENDP_SHIFT) + +/* Control Register (8-bit) */ + +#define USB_CTL_USBENSOFEN (1 << 0) /* Bit 0: USB Enable */ +#define USB_CTL_ODDRST (1 << 1) /* Bit 1: Resets all the BDT ODD ping/pong bits to 0 */ +#define USB_CTL_RESUME (1 << 2) /* Bit 2: Enables the USB Module to execute resume signaling */ +#define USB_CTL_HOSTMODEEN (1 << 3) /* Bit 3: Enables the USB Module to operate in Host mode */ +#define USB_CTL_RESET (1 << 4) /* Bit 4: Enables the USB Module to generate USB reset signaling */ +#define USB_CTL_TXSUSPENDTOKENBUSY (1 << 5) /* Bit 5: USB Module is busy executing a USB token */ +#define USB_CTL_SE0 (1 << 6) /* Bit 6: Live USB Single Ended Zero signal */ +#define USB_CTL_JSTATE (1 << 7) /* Bit 7: Live USB differential receiver JSTATE signal */ + +/* Address Register (8-bit) */ + +#define USB_ADDR_LSEN (1 << 7) /* Bit 7: Low Speed Enable bit */ +#define USB_ADDR_SHIFT (0) /* Bits 0-6: USB address */ +#define USB_ADDR_MASK (0x7f << USB_ADDR_SHIFT) + +/* BDT Page Register 1 (8-bit) */ + /* Bit 0: Reserved */ +#define USB_BDTPAGE1_SHIFT (1) /* Bits 1-7: Address bits 9-15 of the BDT base address */ +#define USB_BDTPAGE1_MASK (0x7f << USB_BDTPAGE1_SHIFT) + +/* Frame Number Register Low (8-bit, bits 0-7 of the 11 bit frame number) */ +/* Frame Number Register High (8-bit) */ + /* Bits 3-7: Reserved */ +#define USB_FRMNUMH_SHIFT (0) /* Bits 0-2: Bits 8-10 of the 11-bit frame number */ +#define USB_FRMNUMH_MASK (7 << USB_FRMNUMH_SHIFT) + +/* Token Register (8-bit) */ + +#define USB_TOKEN_ENDPT_SHIFT (0) /* Bits 0-3: Endpoint address for the token command */ +#define USB_TOKEN_ENDPT_MASK (15 << USB_TOKEN_ENDPT_SHIFT) +#define USB_TOKEN_PID_SHIFT (4) /* Bits 4-7: Token type executed by the USB Module */ +#define USB_TOKEN_PID_MASK (15 << USB_TOKEN_PID_SHIFT) +# define USB_TOKEN_PID_OUT (1 << USB_TOKEN_PID_SHIFT) /* OUT Token */ +# define USB_TOKEN_PID_IN (9 << USB_TOKEN_PID_SHIFT) /* IN Token */ +# define USB_TOKEN_PID_SETUP (13 << USB_TOKEN_PID_SHIFT) /* SETUP Token */ + +/* SOF Threshold Register (8-bit count value) */ +/* BDT Page Register 2/3 (16 bit address in two 8-bit registers) */ + +/* Endpoint n Control Register (8-bit) */ + +#define USB_ENDPT_EPHSHK (1 << 0) /* Bit 0: Enable handshaking during a transaction to the endpoint */ +#define USB_ENDPT_EPSTALL (1 << 1) /* Bit 1: Endpoint is stalled */ +#define USB_ENDPT_EPTXEN (1 << 2) /* Bit 2: Enable the endpoint for TX transfers */ +#define USB_ENDPT_EPRXEN (1 << 3) /* Bit 3: Enable the endpoint for RX transfers */ +#define USB_ENDPT_EPCTLDIS (1 << 4) /* Bit 4: Disable control (SETUP) transfers */ + /* Bit 5: Reserved */ +#define USB_ENDPT_RETRYDIS (1 << 6) /* Bit 6: Disable host retry NAK'ed transactions (host EP0) */ +#define USB_ENDPT_HOSTWOHUB (1 << 7) /* Bit 7: Allows the host to communicate to a low speed device (host EP0) */ + +/* USB Control Register (8-bit) */ + /* Bits 0-5: Reserved */ +#define USB_USBCTRL_PDE (1 << 6) /* Bit 6: Enables the weak pulldowns on the USB transceiver */ +#define USB_USBCTRL_SUSP (1 << 7) /* Bit 7: Places the USB transceiver into the suspend state */ + +/* USB OTG Observe Register (8-bit) */ + /* Bits 0-3: Reserved */ +#define USB_OBSERVE_DMPD (1 << 4) /* Bit 4: D- Pull Down signal output from the USB OTG module */ + /* Bit 5: Reserved */ +#define USB_OBSERVE_DPPD (1 << 6) /* Bit 6: D+ Pull Down signal output from the USB OTG module */ +#define USB_OBSERVE_DPPU (1 << 7) /* Bit 7: D+ Pull Up signal output from the USB OTG module */ + +/* USB OTG Control Register (8-bit) */ + /* Bits 0-3: Reserved */ +#define USB_CONTROL_DPPULLUPNONOTG (1 << 4) /* Bit 4: Controls of the DP PULLUP in the USB OTG module */ + /* Bits 5-7: Reserved */ +/* USB Transceiver Control Register 0 (8-bit) */ + +#define USB_USBTRC0_USBRESET (1 << 7) /* Bit 7: USB reset */ + /* Bit 6: Reserved */ +#define USB_USBTRC0_USBRESMEN (1 << 5) /* Bit 5: Asynchronous Resume Interrupt Enable */ + /* Bits 2-4: Reserved */ +#define USB_USBTRC0_SYNC_DET (1 << 1) /* Bit 1: Synchronous USB Interrupt Detect */ +#define USB_USBTRC0_RESUME_INT (1 << 0) /* Bit 0: USB Asynchronous Interrupt */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_USBOTG_H */ diff --git a/arch/arm/src/kinetis/kinetis_userspace.c b/arch/arm/src/kinetis/kinetis_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..3e919536209e704f37f1785a3b37b2b541685b73 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_userspace.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "kinetis_mpuinit.h" +#include "kinetis_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void kinetis_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + kinetis_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/kinetis/kinetis_userspace.h b/arch/arm/src/kinetis/kinetis_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..39b4b6ef5417463f2302e0b1a4a321fc00246d85 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/kinetis/kinetis_userspace.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_USERSPACE_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: kinetis_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void kinetis_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_USERSPACE_H */ diff --git a/arch/arm/src/kinetis/kinetis_vectors.S b/arch/arm/src/kinetis/kinetis_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..75c295ae033342bc25f0f64c80aa99beee7e3372 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_vectors.S @@ -0,0 +1,1065 @@ +/************************************************************************************************ + * arch/arm/src/kinetis/kinetis_vectors.S + * arch/arm/src/chip/kinetis_vectors.S + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include + +#include "exc_return.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* Configuration ********************************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the + * stack pointer of the interrupted thread. If the interrupted thread was a privileged + * thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the + * value of the MSP will be invalid when the interrupt handler returns because it will be a + * pointer to an old position in the unprivileged stack. Then when the high priority + * interrupt occurs and uses this stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt handler will + * always set the the MSP to the interrupt stack. So when the high priority interrupt occurs, + * it will either use the MSP of the last privileged thread to run or, in the case of the + * nested interrupt, the interrupt stack if no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************************/ +/* + * 0x0000:0000 - Beginning of FLASH. Address of vectors + * 0x1800:0000 - Start of CPU SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap. NOTE + * that the ARM uses a decrement before store stack so that the correct initial + * value is the end of the stack + 4; + * - Heap ends at the configured end of SRAM. + */ + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************************ + * Public Symbols + ************************************************************************************************/ + + .syntax unified + .thumb + .file "kinetis_vectors.S" + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + .globl __start + +/************************************************************************************************ + * Macros + ************************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + + .macro HANDLER, label, irqno + .thumb_func +\label: + mov r0, #\irqno + b exception_common + .endm + +/************************************************************************************************ + * Vectors + ************************************************************************************************/ + + .section .vectors, "ax" + .code 16 + .align 2 + .globl _vectors + .type _vectors, function + +_vectors: + +/* Processor Exceptions *************************************************************************/ + + .word IDLE_STACK /* Vector 0: Reset stack pointer */ + .word __start /* Vector 1: Reset vector */ + .word kinetis_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + .word kinetis_hardfault /* Vector 3: Hard fault */ + .word kinetis_mpu /* Vector 4: Memory management (MPU) */ + .word kinetis_busfault /* Vector 5: Bus fault */ + .word kinetis_usagefault /* Vector 6: Usage fault */ + .word kinetis_reserved /* Vector 7: Reserved */ + .word kinetis_reserved /* Vector 8: Reserved */ + .word kinetis_reserved /* Vector 9: Reserved */ + .word kinetis_reserved /* Vector 10: Reserved */ + .word kinetis_svcall /* Vector 11: SVC call */ + .word kinetis_dbgmonitor /* Vector 12: Debug monitor */ + .word kinetis_reserved /* Vector 13: Reserved */ + .word kinetis_pendsv /* Vector 14: Pendable system service request */ + .word kinetis_systick /* Vector 15: System tick */ + +/* External Interrupts **************************************************************************/ +/* K20 Family *********************************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K20P64M72SF1RM + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) + .word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */ + .word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */ + .word kinetis_dmach2 /* Vector 18: DMA channel 2 transfer complete */ + .word kinetis_dmach3 /* Vector 19: DMA channel 3 transfer complete */ + .word kinetis_dmach4 /* Vector 20: DMA channel 4 transfer complete */ + .word kinetis_dmach5 /* Vector 21: DMA channel 5 transfer complete */ + .word kinetis_dmach6 /* Vector 22: DMA channel 6 transfer complete */ + .word kinetis_dmach7 /* Vector 23: DMA channel 7 transfer complete */ + .word kinetis_dmach8 /* Vector 24: DMA channel 8 transfer complete */ + .word kinetis_dmach9 /* Vector 25: DMA channel 9 transfer complete */ + .word kinetis_dmach10 /* Vector 26: DMA channel 10 transfer complete */ + .word kinetis_dmach11 /* Vector 27: DMA channel 11 transfer complete */ + .word kinetis_dmach12 /* Vector 28: DMA channel 12 transfer complete */ + .word kinetis_dmach13 /* Vector 29: DMA channel 13 transfer complete */ + .word kinetis_dmach14 /* Vector 30: DMA channel 14 transfer complete */ + .word kinetis_dmach15 /* Vector 31: DMA channel 15 transfer complete */ + .word kinetis_dmaerr /* Vector 32: DMA error interrupt channels 0-15 */ + .word kinetis_reserved /* Vector 33: Reserved */ + .word kinetis_flashcc /* Vector 34: Flash memory command complete */ + .word kinetis_flashrc /* Vector 35: Flash memory read collision */ + .word kinetis_smclvd /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + .word kinetis_llwu /* Vector 37: LLWU Normal Low Leakage Wakeup */ + .word kinetis_wdog /* Vector 38: Watchdog */ + .word kinetis_reserved /* Vector 39: Reserved */ + .word kinetis_i2c0 /* Vector 40: I2C0 */ + .word kinetis_i2c1 /* Vector 41: I2C1 */ + .word kinetis_spi0 /* Vector 42: SPI0 all sources */ + .word kinetis_spi1 /* Vector 43: SPI1 all sources */ + .word kinetis_reserved /* Vector 44: Reserved */ + .word kinetis_can0mb /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + .word kinetis_can0bo /* Vector 46: CAN0 Bus Off */ + .word kinetis_can0err /* Vector 47: CAN0 Error */ + .word kinetis_can0tw /* Vector 48: CAN0 Transmit Warning */ + .word kinetis_can0rw /* Vector 49: CAN0 Receive Warning */ + .word kinetis_can0wu /* Vector 50: CAN0 Wake UP */ + .word kinetis_reserved /* Vector 51: Reserved */ + .word kinetis_reserved /* Vector 52: Reserved */ + .word kinetis_reserved /* Vector 53: Reserved */ + .word kinetis_reserved /* Vector 54: Reserved */ + .word kinetis_reserved /* Vector 55: Reserved */ + .word kinetis_reserved /* Vector 56: Reserved */ + .word kinetis_reserved /* Vector 57: Reserved */ + .word kinetis_reserved /* Vector 58: Reserved */ + .word kinetis_reserved /* Vector 59: Reserved */ + .word kinetis_reserved /* Vector 60: Reserved */ + .word kinetis_uart0s /* Vector 61: UART0 status */ + .word kinetis_uart0e /* Vector 62: UART0 error */ + .word kinetis_uart1s /* Vector 63: UART1 status */ + .word kinetis_uart1e /* Vector 64: UART1 error */ + .word kinetis_uart2s /* Vector 65: UART2 status */ + .word kinetis_uart2e /* Vector 66: UART2 error */ + .word kinetis_reserved /* Vector 67: Reserved */ + .word kinetis_reserved /* Vector 68: Reserved */ + .word kinetis_reserved /* Vector 69: Reserved */ + .word kinetis_reserved /* Vector 70: Reserved */ + .word kinetis_reserved /* Vector 71: Reserved */ + .word kinetis_reserved /* Vector 72: Reserved */ + .word kinetis_adc0 /* Vector 73: ADC0 */ + .word kinetis_adc1 /* Vector 74: ADC1 */ + .word kinetis_cmp0 /* Vector 75: CMP0 */ + .word kinetis_cmp1 /* Vector 76: CMP1 */ + .word kinetis_cmp2 /* Vector 77: CMP2 */ + .word kinetis_ftm0 /* Vector 78: FTM0 all sources */ + .word kinetis_ftm1 /* Vector 79: FTM1 all sources */ + .word kinetis_ftm2 /* Vector 80: FTM2 all sources */ + .word kinetis_cmt /* Vector 81: CMT */ + .word kinetis_rtc /* Vector 82: RTC alarm interrupt */ + .word kinetis_reserved /* Vector 83: Reserved */ + .word kinetis_pitch0 /* Vector 84: PIT channel 0 */ + .word kinetis_pitch1 /* Vector 85: PIT channel 1 */ + .word kinetis_pitch2 /* Vector 86: PIT channel 2 */ + .word kinetis_pitch3 /* Vector 87: PIT channel 3 */ + .word kinetis_pdb /* Vector 88: PDB */ + .word kinetis_usbotg /* Vector 88: USB OTG */ + .word kinetis_usbcd /* Vector 90: USB charger detect */ + .word kinetis_reserved /* Vector 91: Reserved */ + .word kinetis_reserved /* Vector 92: Reserved */ + .word kinetis_reserved /* Vector 93: Reserved */ + .word kinetis_reserved /* Vector 94: Reserved */ + .word kinetis_reserved /* Vector 95: Reserved */ + .word kinetis_reserved /* Vector 96: Reserved */ + .word kinetis_dac0 /* Vector 97: DAC0 */ + .word kinetis_reserved /* Vector 98: Reserved */ + .word kinetis_tsi /* Vector 99: TSI all sources */ + .word kinetis_mcg /* Vector 100: MCG */ + .word kinetis_lpt /* Vector 101: Low power timer */ + .word kinetis_reserved /* Vector 102: Reserved */ + .word kinetis_porta /* Vector 103: Pin detect port A */ + .word kinetis_portb /* Vector 104: Pin detect port B */ + .word kinetis_portc /* Vector 105: Pin detect port C */ + .word kinetis_portd /* Vector 106: Pin detect port D */ + .word kinetis_porte /* Vector 107: Pin detect port E */ + .word kinetis_reserved /* Vector 108: Reserved */ + .word kinetis_reserved /* Vector 109: Reserved */ + .word kinetis_swi /* Vector 110: Software interrupt */ + +/* K40 Family *********************************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) + + .word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */ + .word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */ + .word kinetis_dmach2 /* Vector 18: DMA channel 2 transfer complete */ + .word kinetis_dmach3 /* Vector 19: DMA channel 3 transfer complete */ + .word kinetis_dmach4 /* Vector 20: DMA channel 4 transfer complete */ + .word kinetis_dmach5 /* Vector 21: DMA channel 5 transfer complete */ + .word kinetis_dmach6 /* Vector 22: DMA channel 6 transfer complete */ + .word kinetis_dmach7 /* Vector 23: DMA channel 7 transfer complete */ + .word kinetis_dmach8 /* Vector 24: DMA channel 8 transfer complete */ + .word kinetis_dmach9 /* Vector 25: DMA channel 9 transfer complete */ + .word kinetis_dmach10 /* Vector 26: DMA channel 10 transfer complete */ + .word kinetis_dmach11 /* Vector 27: DMA channel 11 transfer complete */ + .word kinetis_dmach12 /* Vector 28: DMA channel 12 transfer complete */ + .word kinetis_dmach13 /* Vector 29: DMA channel 13 transfer complete */ + .word kinetis_dmach14 /* Vector 30: DMA channel 14 transfer complete */ + .word kinetis_dmach15 /* Vector 31: DMA channel 15 transfer complete */ + .word kinetis_dmaerr /* Vector 32: DMA error interrupt channels 0-15 */ + .word kinetis_mcm /* Vector 33: MCM Normal interrupt */ + .word kinetis_flashcc /* Vector 34: Flash memory command complete */ + .word kinetis_flashrc /* Vector 35: Flash memory read collision */ + .word kinetis_smclvd /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + .word kinetis_llwu /* Vector 37: LLWU Normal Low Leakage Wakeup */ + .word kinetis_wdog /* Vector 38: Watchdog */ + .word kinetis_reserved /* Vector 39: Reserved */ + .word kinetis_i2c0 /* Vector 40: I2C0 */ + .word kinetis_i2c1 /* Vector 41: I2C1 */ + .word kinetis_spi0 /* Vector 42: SPI0 all sources */ + .word kinetis_spi1 /* Vector 43: SPI1 all sources */ + .word kinetis_spi2 /* Vector 44: SPI2 all sources */ + .word kinetis_can0mb /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + .word kinetis_can0bo /* Vector 46: CAN0 Bus Off */ + .word kinetis_can0err /* Vector 47: CAN0 Error */ + .word kinetis_can0tw /* Vector 48: CAN0 Transmit Warning */ + .word kinetis_can0rw /* Vector 49: CAN0 Receive Warning */ + .word kinetis_can0wu /* Vector 50: CAN0 Wake UP */ + .word kinetis_reserved /* Vector 51: Reserved */ + .word kinetis_reserved /* Vector 52: Reserved */ + .word kinetis_can1mb /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ + .word kinetis_can1bo /* Vector 54: CAN1 Bus Off */ + .word kinetis_can1err /* Vector 55: CAN1 Error */ + .word kinetis_can1tw /* Vector 56: CAN1 Transmit Warning */ + .word kinetis_can1rw /* Vector 57: CAN1 Receive Warning */ + .word kinetis_can1wu /* Vector 58: CAN1 Wake UP */ + .word kinetis_reserved /* Vector 59: Reserved */ + .word kinetis_reserved /* Vector 60: Reserved */ + .word kinetis_uart0s /* Vector 61: UART0 status */ + .word kinetis_uart0e /* Vector 62: UART0 error */ + .word kinetis_uart1s /* Vector 63: UART1 status */ + .word kinetis_uart1e /* Vector 64: UART1 error */ + .word kinetis_uart2s /* Vector 65: UART2 status */ + .word kinetis_uart2e /* Vector 66: UART2 error */ + .word kinetis_uart3s /* Vector 67: UART3 status */ + .word kinetis_uart3e /* Vector 68: UART3 error */ + .word kinetis_uart4s /* Vector 69: UART4 status */ + .word kinetis_uart4e /* Vector 70: UART4 error */ + .word kinetis_uart5s /* Vector 71: UART5 status */ + .word kinetis_uart5e /* Vector 72: UART5 error */ + .word kinetis_adc0 /* Vector 73: ADC0 */ + .word kinetis_adc1 /* Vector 74: ADC1 */ + .word kinetis_cmp0 /* Vector 75: CMP0 */ + .word kinetis_cmp1 /* Vector 76: CMP1 */ + .word kinetis_cmp2 /* Vector 77: CMP2 */ + .word kinetis_ftm0 /* Vector 78: FTM0 all sources */ + .word kinetis_ftm1 /* Vector 79: FTM1 all sources */ + .word kinetis_ftm2 /* Vector 80: FTM2 all sources */ + .word kinetis_cmt /* Vector 81: CMT */ + .word kinetis_rtc /* Vector 82: RTC alarm interrupt */ + .word kinetis_reserved /* Vector 83: Reserved */ + .word kinetis_pitch0 /* Vector 84: PIT channel 0 */ + .word kinetis_pitch1 /* Vector 85: PIT channel 1 */ + .word kinetis_pitch2 /* Vector 86: PIT channel 2 */ + .word kinetis_pitch3 /* Vector 87: PIT channel 3 */ + .word kinetis_pdb /* Vector 88: PDB */ + .word kinetis_usbotg /* Vector 88: USB OTG */ + .word kinetis_usbcd /* Vector 90: USB charger detect */ + .word kinetis_reserved /* Vector 91: Reserved */ + .word kinetis_reserved /* Vector 92: Reserved */ + .word kinetis_reserved /* Vector 93: Reserved */ + .word kinetis_reserved /* Vector 94: Reserved */ + .word kinetis_i2s0 /* Vector 95: I2S0 */ + .word kinetis_sdhc /* Vector 96: SDHC */ + .word kinetis_dac0 /* Vector 97: DAC0 */ + .word kinetis_dac1 /* Vector 98: DAC1 */ + .word kinetis_tsi /* Vector 97: TSI all sources */ + .word kinetis_mcg /* Vector 100: MCG */ + .word kinetis_lpt /* Vector 101: Low power timer */ + .word kinetis_slcd /* Vector 102: Segment LCD all sources */ + .word kinetis_porta /* Vector 103: Pin detect port A */ + .word kinetis_portb /* Vector 104: Pin detect port B */ + .word kinetis_portc /* Vector 105: Pin detect port C */ + .word kinetis_portd /* Vector 106: Pin detect port D */ + .word kinetis_porte /* Vector 107: Pin detect port E */ + .word kinetis_reserved /* Vector 108: Reserved */ + .word kinetis_reserved /* Vector 109: Reserved */ + .word kinetis_swi /* Vector 110: Software interrupt */ + +/* K60 Family *********************************************************************************** + * + * The memory map for the following parts is defined in Freescale document + * K60P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLL100) + + .word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */ + .word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */ + .word kinetis_dmach2 /* Vector 18: DMA channel 2 transfer complete */ + .word kinetis_dmach3 /* Vector 19: DMA channel 3 transfer complete */ + .word kinetis_dmach4 /* Vector 20: DMA channel 4 transfer complete */ + .word kinetis_dmach5 /* Vector 21: DMA channel 5 transfer complete */ + .word kinetis_dmach6 /* Vector 22: DMA channel 6 transfer complete */ + .word kinetis_dmach7 /* Vector 23: DMA channel 7 transfer complete */ + .word kinetis_dmach8 /* Vector 24: DMA channel 8 transfer complete */ + .word kinetis_dmach9 /* Vector 25: DMA channel 9 transfer complete */ + .word kinetis_dmach10 /* Vector 26: DMA channel 10 transfer complete */ + .word kinetis_dmach11 /* Vector 27: DMA channel 11 transfer complete */ + .word kinetis_dmach12 /* Vector 28: DMA channel 12 transfer complete */ + .word kinetis_dmach13 /* Vector 29: DMA channel 13 transfer complete */ + .word kinetis_dmach14 /* Vector 30: DMA channel 14 transfer complete */ + .word kinetis_dmach15 /* Vector 31: DMA channel 15 transfer complete */ + .word kinetis_dmaerr /* Vector 32: DMA error interrupt channels 0-15 */ + .word kinetis_mcm /* Vector 33: MCM Normal interrupt */ + .word kinetis_flashcc /* Vector 34: Flash memory command complete */ + .word kinetis_flashrc /* Vector 35: Flash memory read collision */ + .word kinetis_smclvd /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + .word kinetis_llwu /* Vector 37: LLWU Normal Low Leakage Wakeup */ + .word kinetis_wdog /* Vector 38: Watchdog */ + .word kinetis_rngb /* Vector 39: Random number generator */ + .word kinetis_i2c0 /* Vector 40: I2C0 */ + .word kinetis_i2c1 /* Vector 41: I2C1 */ + .word kinetis_spi0 /* Vector 42: SPI0 all sources */ + .word kinetis_spi1 /* Vector 43: SPI1 all sources */ + .word kinetis_spi2 /* Vector 44: SPI2 all sources */ + .word kinetis_can0mb /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + .word kinetis_can0bo /* Vector 46: CAN0 Bus Off */ + .word kinetis_can0err /* Vector 47: CAN0 Error */ + .word kinetis_can0tw /* Vector 48: CAN0 Transmit Warning */ + .word kinetis_can0rw /* Vector 49: CAN0 Receive Warning */ + .word kinetis_can0wu /* Vector 50: CAN0 Wake UP */ + .word kinetis_reserved /* Vector 51: Reserved */ + .word kinetis_reserved /* Vector 52: Reserved */ + .word kinetis_can1mb /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ + .word kinetis_can1bo /* Vector 54: CAN1 Bus Off */ + .word kinetis_can1err /* Vector 55: CAN1 Error */ + .word kinetis_can1tw /* Vector 56: CAN1 Transmit Warning */ + .word kinetis_can1rw /* Vector 57: CAN1 Receive Warning */ + .word kinetis_can1wu /* Vector 58: CAN1 Wake UP */ + .word kinetis_reserved /* Vector 59: Reserved */ + .word kinetis_reserved /* Vector 60: Reserved */ + .word kinetis_uart0s /* Vector 61: UART0 status */ + .word kinetis_uart0e /* Vector 62: UART0 error */ + .word kinetis_uart1s /* Vector 63: UART1 status */ + .word kinetis_uart1e /* Vector 64: UART1 error */ + .word kinetis_uart2s /* Vector 65: UART2 status */ + .word kinetis_uart2e /* Vector 66: UART2 error */ + .word kinetis_uart3s /* Vector 67: UART3 status */ + .word kinetis_uart3e /* Vector 68: UART3 error */ + .word kinetis_uart4s /* Vector 69: UART4 status */ + .word kinetis_uart4e /* Vector 70: UART4 error */ + .word kinetis_uart5s /* Vector 71: UART5 status */ + .word kinetis_uart5e /* Vector 72: UART5 error */ + .word kinetis_adc0 /* Vector 73: ADC0 */ + .word kinetis_adc1 /* Vector 74: ADC1 */ + .word kinetis_cmp0 /* Vector 75: CMP0 */ + .word kinetis_cmp1 /* Vector 76: CMP1 */ + .word kinetis_cmp2 /* Vector 77: CMP2 */ + .word kinetis_ftm0 /* Vector 78: FTM0 all sources */ + .word kinetis_ftm1 /* Vector 79: FTM1 all sources */ + .word kinetis_ftm2 /* Vector 80: FTM2 all sources */ + .word kinetis_cmt /* Vector 81: CMT */ + .word kinetis_rtc /* Vector 82: RTC alarm interrupt */ + .word kinetis_reserved /* Vector 83: Reserved */ + .word kinetis_pitch0 /* Vector 84: PIT channel 0 */ + .word kinetis_pitch1 /* Vector 85: PIT channel 1 */ + .word kinetis_pitch2 /* Vector 86: PIT channel 2 */ + .word kinetis_pitch3 /* Vector 87: PIT channel 3 */ + .word kinetis_pdb /* Vector 88: PDB */ + .word kinetis_usbotg /* Vector 88: USB OTG */ + .word kinetis_usbcd /* Vector 90: USB charger detect */ + .word kinetis_emactmr /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */ + .word kinetis_emactx /* Vector 92: Ethernet MAC transmit interrupt */ + .word kinetis_emacrx /* Vector 93: Ethernet MAC receive interrupt */ + .word kinetis_emacmisc /* Vector 94: Ethernet MAC error and misc interrupt */ + .word kinetis_i2s0 /* Vector 95: I2S0 */ + .word kinetis_sdhc /* Vector 96: SDHC */ + .word kinetis_dac0 /* Vector 97: DAC0 */ + .word kinetis_dac1 /* Vector 98: DAC1 */ + .word kinetis_tsi /* Vector 97: TSI all sources */ + .word kinetis_mcg /* Vector 100: MCG */ + .word kinetis_lpt /* Vector 101: Low power timer */ + .word kinetis_reserved /* Vector 102: Reserved */ + .word kinetis_porta /* Vector 103: Pin detect port A */ + .word kinetis_portb /* Vector 104: Pin detect port B */ + .word kinetis_portc /* Vector 105: Pin detect port C */ + .word kinetis_portd /* Vector 106: Pin detect port D */ + .word kinetis_porte /* Vector 107: Pin detect port E */ + .word kinetis_reserved /* Vector 108: Reserved */ + .word kinetis_reserved /* Vector 109: Reserved */ + .word kinetis_reserved /* Vector 110: Reserved */ + .word kinetis_reserved /* Vector 111: Reserved */ + .word kinetis_reserved /* Vector 112: Reserved */ + .word kinetis_reserved /* Vector 113: Reserved */ + .word kinetis_reserved /* Vector 114: Reserved */ + .word kinetis_reserved /* Vector 115: Reserved */ + .word kinetis_reserved /* Vector 116: Reserved */ + .word kinetis_reserved /* Vector 117: Reserved */ + .word kinetis_reserved /* Vector 118: Reserved */ + .word kinetis_reserved /* Vector 119: Reserved */ +#else +# error "No vectors for this Kinetis part" +#endif + +/************************************************************************************************ + * .text + ************************************************************************************************/ + + .text + .type handlers, function + .thumb_func +handlers: + +/* Processor Exceptions *************************************************************************/ + + HANDLER kinetis_reserved, KINETIS_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER kinetis_nmi, KINETIS_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER kinetis_hardfault, KINETIS_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER kinetis_mpu, KINETIS_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER kinetis_busfault, KINETIS_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER kinetis_usagefault, KINETIS_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER kinetis_svcall, KINETIS_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER kinetis_dbgmonitor, KINETIS_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER kinetis_pendsv, KINETIS_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER kinetis_systick, KINETIS_IRQ_SYSTICK /* Vector 15: System tick */ + +/* External Interrupts **************************************************************************/ +/* K40 Family *********************************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K20P64M72SF1RM + */ + +#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7) + + HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */ + HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */ + HANDLER kinetis_dmach2, KINETIS_IRQ_DMACH2 /* Vector 18: DMA channel 2 transfer complete */ + HANDLER kinetis_dmach3, KINETIS_IRQ_DMACH3 /* Vector 19: DMA channel 3 transfer complete */ + HANDLER kinetis_dmach4, KINETIS_IRQ_DMACH4 /* Vector 20: DMA channel 4 transfer complete */ + HANDLER kinetis_dmach5, KINETIS_IRQ_DMACH5 /* Vector 21: DMA channel 5 transfer complete */ + HANDLER kinetis_dmach6, KINETIS_IRQ_DMACH6 /* Vector 22: DMA channel 6 transfer complete */ + HANDLER kinetis_dmach7, KINETIS_IRQ_DMACH7 /* Vector 23: DMA channel 7 transfer complete */ + HANDLER kinetis_dmach8, KINETIS_IRQ_DMACH8 /* Vector 24: DMA channel 8 transfer complete */ + HANDLER kinetis_dmach9, KINETIS_IRQ_DMACH9 /* Vector 25: DMA channel 9 transfer complete */ + HANDLER kinetis_dmach10, KINETIS_IRQ_DMACH10 /* Vector 26: DMA channel 10 transfer complete */ + HANDLER kinetis_dmach11, KINETIS_IRQ_DMACH11 /* Vector 27: DMA channel 11 transfer complete */ + HANDLER kinetis_dmach12, KINETIS_IRQ_DMACH12 /* Vector 28: DMA channel 12 transfer complete */ + HANDLER kinetis_dmach13, KINETIS_IRQ_DMACH13 /* Vector 29: DMA channel 13 transfer complete */ + HANDLER kinetis_dmach14, KINETIS_IRQ_DMACH14 /* Vector 30: DMA channel 14 transfer complete */ + HANDLER kinetis_dmach15, KINETIS_IRQ_DMACH15 /* Vector 31: DMA channel 15 transfer complete */ + HANDLER kinetis_dmaerr, KINETIS_IRQ_DMAERR /* Vector 32: DMA error interrupt channels 0-15 */ + HANDLER kinetis_flashcc, KINETIS_IRQ_FLASHCC /* Vector 34: Flash memory command complete */ + HANDLER kinetis_flashrc, KINETIS_IRQ_FLASHRC /* Vector 35: Flash memory read collision */ + HANDLER kinetis_smclvd, KINETIS_IRQ_SMCLVD /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + HANDLER kinetis_llwu, KINETIS_IRQ_LLWU /* Vector 37: LLWU Normal Low Leakage Wakeup */ + HANDLER kinetis_wdog, KINETIS_IRQ_WDOG /* Vector 38: Watchdog */ + HANDLER kinetis_i2c0, KINETIS_IRQ_I2C0 /* Vector 40: I2C0 */ + HANDLER kinetis_i2c1, KINETIS_IRQ_I2C1 /* Vector 41: I2C1 */ + HANDLER kinetis_spi0, KINETIS_IRQ_SPI0 /* Vector 42: SPI0 all sources */ + HANDLER kinetis_spi1, KINETIS_IRQ_SPI1 /* Vector 43: SPI1 all sources */ + HANDLER kinetis_can0mb, KINETIS_IRQ_CAN0MB /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + HANDLER kinetis_can0bo, KINETIS_IRQ_CAN0BO /* Vector 46: CAN0 Bus Off */ + HANDLER kinetis_can0err, KINETIS_IRQ_CAN0ERR /* Vector 47: CAN0 Error */ + HANDLER kinetis_can0tw, KINETIS_IRQ_CAN0TW /* Vector 48: CAN0 Transmit Warning */ + HANDLER kinetis_can0rw, KINETIS_IRQ_CAN0RW /* Vector 49: CAN0 Receive Warning */ + HANDLER kinetis_can0wu, KINETIS_IRQ_CAN0WU /* Vector 50: CAN0 Wake UP */ + HANDLER kinetis_uart0s, KINETIS_IRQ_UART0S /* Vector 61: UART0 status */ + HANDLER kinetis_uart0e, KINETIS_IRQ_UART0E /* Vector 62: UART0 error */ + HANDLER kinetis_uart1s, KINETIS_IRQ_UART1S /* Vector 63: UART1 status */ + HANDLER kinetis_uart1e, KINETIS_IRQ_UART1E /* Vector 64: UART1 error */ + HANDLER kinetis_uart2s, KINETIS_IRQ_UART2S /* Vector 65: UART2 status */ + HANDLER kinetis_uart2e, KINETIS_IRQ_UART2E /* Vector 66: UART2 error */ + HANDLER kinetis_adc0, KINETIS_IRQ_ADC0 /* Vector 73: ADC0 */ + HANDLER kinetis_adc1, KINETIS_IRQ_ADC1 /* Vector 74: ADC1 */ + HANDLER kinetis_cmp0, KINETIS_IRQ_CMP0 /* Vector 75: CMP0 */ + HANDLER kinetis_cmp1, KINETIS_IRQ_CMP1 /* Vector 76: CMP1 */ + HANDLER kinetis_cmp2, KINETIS_IRQ_CMP2 /* Vector 77: CMP2 */ + HANDLER kinetis_ftm0, KINETIS_IRQ_FTM0 /* Vector 78: FTM0 all sources */ + HANDLER kinetis_ftm1, KINETIS_IRQ_FTM1 /* Vector 79: FTM1 all sources */ + HANDLER kinetis_ftm2, KINETIS_IRQ_FTM2 /* Vector 80: FTM2 all sources */ + HANDLER kinetis_cmt, KINETIS_IRQ_CMT /* Vector 81: CMT */ + HANDLER kinetis_rtc, KINETIS_IRQ_RTC /* Vector 82: RTC alarm interrupt */ + HANDLER kinetis_pitch0, KINETIS_IRQ_PITCH0 /* Vector 84: PIT channel 0 */ + HANDLER kinetis_pitch1, KINETIS_IRQ_PITCH1 /* Vector 85: PIT channel 1 */ + HANDLER kinetis_pitch2, KINETIS_IRQ_PITCH2 /* Vector 86: PIT channel 2 */ + HANDLER kinetis_pitch3, KINETIS_IRQ_PITCH3 /* Vector 87: PIT channel 3 */ + HANDLER kinetis_pdb, KINETIS_IRQ_PDB /* Vector 88: PDB */ + HANDLER kinetis_usbotg, KINETIS_IRQ_USBOTG /* Vector 88: USB OTG */ + HANDLER kinetis_usbcd, KINETIS_IRQ_USBCD /* Vector 90: USB charger detect */ + HANDLER kinetis_dac0, KINETIS_IRQ_DAC0 /* Vector 97: DAC0 */ + HANDLER kinetis_tsi, KINETIS_IRQ_TSI /* Vector 97: TSI all sources */ + HANDLER kinetis_mcg, KINETIS_IRQ_MCG /* Vector 100: MCG */ + HANDLER kinetis_lpt, KINETIS_IRQ_LPT /* Vector 101: Low power timer */ + HANDLER kinetis_porta, KINETIS_IRQ_PORTA /* Vector 103: Pin detect port A */ + HANDLER kinetis_portb, KINETIS_IRQ_PORTB /* Vector 104: Pin detect port B */ + HANDLER kinetis_portc, KINETIS_IRQ_PORTC /* Vector 105: Pin detect port C */ + HANDLER kinetis_portd, KINETIS_IRQ_PORTD /* Vector 106: Pin detect port D */ + HANDLER kinetis_porte, KINETIS_IRQ_PORTE /* Vector 107: Pin detect port E */ + HANDLER kinetis_swi, KINETIS_IRQ_SWI /* Vector 110: Software interrupt */ + +/* K40 Family *********************************************************************************** + * + * The interrupt vectors for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100) + + HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */ + HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */ + HANDLER kinetis_dmach2, KINETIS_IRQ_DMACH2 /* Vector 18: DMA channel 2 transfer complete */ + HANDLER kinetis_dmach3, KINETIS_IRQ_DMACH3 /* Vector 19: DMA channel 3 transfer complete */ + HANDLER kinetis_dmach4, KINETIS_IRQ_DMACH4 /* Vector 20: DMA channel 4 transfer complete */ + HANDLER kinetis_dmach5, KINETIS_IRQ_DMACH5 /* Vector 21: DMA channel 5 transfer complete */ + HANDLER kinetis_dmach6, KINETIS_IRQ_DMACH6 /* Vector 22: DMA channel 6 transfer complete */ + HANDLER kinetis_dmach7, KINETIS_IRQ_DMACH7 /* Vector 23: DMA channel 7 transfer complete */ + HANDLER kinetis_dmach8, KINETIS_IRQ_DMACH8 /* Vector 24: DMA channel 8 transfer complete */ + HANDLER kinetis_dmach9, KINETIS_IRQ_DMACH9 /* Vector 25: DMA channel 9 transfer complete */ + HANDLER kinetis_dmach10, KINETIS_IRQ_DMACH10 /* Vector 26: DMA channel 10 transfer complete */ + HANDLER kinetis_dmach11, KINETIS_IRQ_DMACH11 /* Vector 27: DMA channel 11 transfer complete */ + HANDLER kinetis_dmach12, KINETIS_IRQ_DMACH12 /* Vector 28: DMA channel 12 transfer complete */ + HANDLER kinetis_dmach13, KINETIS_IRQ_DMACH13 /* Vector 29: DMA channel 13 transfer complete */ + HANDLER kinetis_dmach14, KINETIS_IRQ_DMACH14 /* Vector 30: DMA channel 14 transfer complete */ + HANDLER kinetis_dmach15, KINETIS_IRQ_DMACH15 /* Vector 31: DMA channel 15 transfer complete */ + HANDLER kinetis_dmaerr, KINETIS_IRQ_DMAERR /* Vector 32: DMA error interrupt channels 0-15 */ + HANDLER kinetis_mcm, KINETIS_IRQ_MCM /* Vector 33: MCM Normal interrupt */ + HANDLER kinetis_flashcc, KINETIS_IRQ_FLASHCC /* Vector 34: Flash memory command complete */ + HANDLER kinetis_flashrc, KINETIS_IRQ_FLASHRC /* Vector 35: Flash memory read collision */ + HANDLER kinetis_smclvd, KINETIS_IRQ_SMCLVD /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + HANDLER kinetis_llwu, KINETIS_IRQ_LLWU /* Vector 37: LLWU Normal Low Leakage Wakeup */ + HANDLER kinetis_wdog, KINETIS_IRQ_WDOG /* Vector 38: Watchdog */ + HANDLER kinetis_i2c0, KINETIS_IRQ_I2C0 /* Vector 40: I2C0 */ + HANDLER kinetis_i2c1, KINETIS_IRQ_I2C1 /* Vector 41: I2C1 */ + HANDLER kinetis_spi0, KINETIS_IRQ_SPI0 /* Vector 42: SPI0 all sources */ + HANDLER kinetis_spi1, KINETIS_IRQ_SPI1 /* Vector 43: SPI1 all sources */ + HANDLER kinetis_spi2, KINETIS_IRQ_SPI2 /* Vector 44: SPI2 all sources */ + HANDLER kinetis_can0mb, KINETIS_IRQ_CAN0MB /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + HANDLER kinetis_can0bo, KINETIS_IRQ_CAN0BO /* Vector 46: CAN0 Bus Off */ + HANDLER kinetis_can0err, KINETIS_IRQ_CAN0ERR /* Vector 47: CAN0 Error */ + HANDLER kinetis_can0tw, KINETIS_IRQ_CAN0TW /* Vector 48: CAN0 Transmit Warning */ + HANDLER kinetis_can0rw, KINETIS_IRQ_CAN0RW /* Vector 49: CAN0 Receive Warning */ + HANDLER kinetis_can0wu, KINETIS_IRQ_CAN0WU /* Vector 50: CAN0 Wake UP */ + HANDLER kinetis_can1mb, KINETIS_IRQ_CAN1MB /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ + HANDLER kinetis_can1bo, KINETIS_IRQ_CAN1BO /* Vector 54: CAN1 Bus Off */ + HANDLER kinetis_can1err, KINETIS_IRQ_CAN1ERR /* Vector 55: CAN1 Error */ + HANDLER kinetis_can1tw, KINETIS_IRQ_CAN1TW /* Vector 56: CAN1 Transmit Warning */ + HANDLER kinetis_can1rw, KINETIS_IRQ_CAN1RW /* Vector 57: CAN1 Receive Warning */ + HANDLER kinetis_can1wu, KINETIS_IRQ_CAN1WU /* Vector 58: CAN1 Wake UP */ + HANDLER kinetis_uart0s, KINETIS_IRQ_UART0S /* Vector 61: UART0 status */ + HANDLER kinetis_uart0e, KINETIS_IRQ_UART0E /* Vector 62: UART0 error */ + HANDLER kinetis_uart1s, KINETIS_IRQ_UART1S /* Vector 63: UART1 status */ + HANDLER kinetis_uart1e, KINETIS_IRQ_UART1E /* Vector 64: UART1 error */ + HANDLER kinetis_uart2s, KINETIS_IRQ_UART2S /* Vector 65: UART2 status */ + HANDLER kinetis_uart2e, KINETIS_IRQ_UART2E /* Vector 66: UART2 error */ + HANDLER kinetis_uart3s, KINETIS_IRQ_UART3S /* Vector 67: UART3 status */ + HANDLER kinetis_uart3e, KINETIS_IRQ_UART3E /* Vector 68: UART3 error */ + HANDLER kinetis_uart4s, KINETIS_IRQ_UART4S /* Vector 69: UART4 status */ + HANDLER kinetis_uart4e, KINETIS_IRQ_UART4E /* Vector 70: UART4 error */ + HANDLER kinetis_uart5s, KINETIS_IRQ_UART5S /* Vector 71: UART5 status */ + HANDLER kinetis_uart5e, KINETIS_IRQ_UART5E /* Vector 72: UART5 error */ + HANDLER kinetis_adc0, KINETIS_IRQ_ADC0 /* Vector 73: ADC0 */ + HANDLER kinetis_adc1, KINETIS_IRQ_ADC1 /* Vector 74: ADC1 */ + HANDLER kinetis_cmp0, KINETIS_IRQ_CMP0 /* Vector 75: CMP0 */ + HANDLER kinetis_cmp1, KINETIS_IRQ_CMP1 /* Vector 76: CMP1 */ + HANDLER kinetis_cmp2, KINETIS_IRQ_CMP2 /* Vector 77: CMP2 */ + HANDLER kinetis_ftm0, KINETIS_IRQ_FTM0 /* Vector 78: FTM0 all sources */ + HANDLER kinetis_ftm1, KINETIS_IRQ_FTM1 /* Vector 79: FTM1 all sources */ + HANDLER kinetis_ftm2, KINETIS_IRQ_FTM2 /* Vector 80: FTM2 all sources */ + HANDLER kinetis_cmt, KINETIS_IRQ_CMT /* Vector 81: CMT */ + HANDLER kinetis_rtc, KINETIS_IRQ_RTC /* Vector 82: RTC alarm interrupt */ + HANDLER kinetis_pitch0, KINETIS_IRQ_PITCH0 /* Vector 84: PIT channel 0 */ + HANDLER kinetis_pitch1, KINETIS_IRQ_PITCH1 /* Vector 85: PIT channel 1 */ + HANDLER kinetis_pitch2, KINETIS_IRQ_PITCH2 /* Vector 86: PIT channel 2 */ + HANDLER kinetis_pitch3, KINETIS_IRQ_PITCH3 /* Vector 87: PIT channel 3 */ + HANDLER kinetis_pdb, KINETIS_IRQ_PDB /* Vector 88: PDB */ + HANDLER kinetis_usbotg, KINETIS_IRQ_USBOTG /* Vector 88: USB OTG */ + HANDLER kinetis_usbcd, KINETIS_IRQ_USBCD /* Vector 90: USB charger detect */ + HANDLER kinetis_i2s0, KINETIS_IRQ_I2S0 /* Vector 95: I2S0 */ + HANDLER kinetis_sdhc, KINETIS_IRQ_SDHC /* Vector 96: SDHC */ + HANDLER kinetis_dac0, KINETIS_IRQ_DAC0 /* Vector 97: DAC0 */ + HANDLER kinetis_dac1, KINETIS_IRQ_DAC1 /* Vector 98: DAC1 */ + HANDLER kinetis_tsi, KINETIS_IRQ_TSI /* Vector 97: TSI all sources */ + HANDLER kinetis_mcg, KINETIS_IRQ_MCG /* Vector 100: MCG */ + HANDLER kinetis_lpt, KINETIS_IRQ_LPT /* Vector 101: Low power timer */ + HANDLER kinetis_slcd, KINETIS_IRQ_SLCD /* Vector 102: Segment LCD all sources */ + HANDLER kinetis_porta, KINETIS_IRQ_PORTA /* Vector 103: Pin detect port A */ + HANDLER kinetis_portb, KINETIS_IRQ_PORTB /* Vector 104: Pin detect port B */ + HANDLER kinetis_portc, KINETIS_IRQ_PORTC /* Vector 105: Pin detect port C */ + HANDLER kinetis_portd, KINETIS_IRQ_PORTD /* Vector 106: Pin detect port D */ + HANDLER kinetis_porte, KINETIS_IRQ_PORTE /* Vector 107: Pin detect port E */ + HANDLER kinetis_swi, KINETIS_IRQ_SWI /* Vector 110: Software interrupt */ + +/* K60 Family *********************************************************************************** + * + * The memory map for the following parts is defined in Freescale document + * K60P144M100SF2RM + */ + +#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \ + defined(CONFIG_ARCH_CHIP_MK60N512VLL100) + + HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */ + HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */ + HANDLER kinetis_dmach2, KINETIS_IRQ_DMACH2 /* Vector 18: DMA channel 2 transfer complete */ + HANDLER kinetis_dmach3, KINETIS_IRQ_DMACH3 /* Vector 19: DMA channel 3 transfer complete */ + HANDLER kinetis_dmach4, KINETIS_IRQ_DMACH4 /* Vector 20: DMA channel 4 transfer complete */ + HANDLER kinetis_dmach5, KINETIS_IRQ_DMACH5 /* Vector 21: DMA channel 5 transfer complete */ + HANDLER kinetis_dmach6, KINETIS_IRQ_DMACH6 /* Vector 22: DMA channel 6 transfer complete */ + HANDLER kinetis_dmach7, KINETIS_IRQ_DMACH7 /* Vector 23: DMA channel 7 transfer complete */ + HANDLER kinetis_dmach8, KINETIS_IRQ_DMACH8 /* Vector 24: DMA channel 8 transfer complete */ + HANDLER kinetis_dmach9, KINETIS_IRQ_DMACH9 /* Vector 25: DMA channel 9 transfer complete */ + HANDLER kinetis_dmach10, KINETIS_IRQ_DMACH10 /* Vector 26: DMA channel 10 transfer complete */ + HANDLER kinetis_dmach11, KINETIS_IRQ_DMACH11 /* Vector 27: DMA channel 11 transfer complete */ + HANDLER kinetis_dmach12, KINETIS_IRQ_DMACH12 /* Vector 28: DMA channel 12 transfer complete */ + HANDLER kinetis_dmach13, KINETIS_IRQ_DMACH13 /* Vector 29: DMA channel 13 transfer complete */ + HANDLER kinetis_dmach14, KINETIS_IRQ_DMACH14 /* Vector 30: DMA channel 14 transfer complete */ + HANDLER kinetis_dmach15, KINETIS_IRQ_DMACH15 /* Vector 31: DMA channel 15 transfer complete */ + HANDLER kinetis_dmaerr, KINETIS_IRQ_DMAERR /* Vector 32: DMA error interrupt channels 0-15 */ + HANDLER kinetis_mcm, KINETIS_IRQ_MCM /* Vector 33: MCM Normal interrupt */ + HANDLER kinetis_flashcc, KINETIS_IRQ_FLASHCC /* Vector 34: Flash memory command complete */ + HANDLER kinetis_flashrc, KINETIS_IRQ_FLASHRC /* Vector 35: Flash memory read collision */ + HANDLER kinetis_smclvd, KINETIS_IRQ_SMCLVD /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */ + HANDLER kinetis_llwu, KINETIS_IRQ_LLWU /* Vector 37: LLWU Normal Low Leakage Wakeup */ + HANDLER kinetis_wdog, KINETIS_IRQ_WDOG /* Vector 38: Watchdog */ + HANDLER kinetis_rngb, KINETIS_IRQ_RNGB /* Vector 39: Random number generator */ + HANDLER kinetis_i2c0, KINETIS_IRQ_I2C0 /* Vector 40: I2C0 */ + HANDLER kinetis_i2c1, KINETIS_IRQ_I2C1 /* Vector 41: I2C1 */ + HANDLER kinetis_spi0, KINETIS_IRQ_SPI0 /* Vector 42: SPI0 all sources */ + HANDLER kinetis_spi1, KINETIS_IRQ_SPI1 /* Vector 43: SPI1 all sources */ + HANDLER kinetis_spi2, KINETIS_IRQ_SPI2 /* Vector 44: SPI2 all sources */ + HANDLER kinetis_can0mb, KINETIS_IRQ_CAN0MB /* Vector 45: CAN0 OR'ed Message buffer (0-15) */ + HANDLER kinetis_can0bo, KINETIS_IRQ_CAN0BO /* Vector 46: CAN0 Bus Off */ + HANDLER kinetis_can0err, KINETIS_IRQ_CAN0ERR /* Vector 47: CAN0 Error */ + HANDLER kinetis_can0tw, KINETIS_IRQ_CAN0TW /* Vector 48: CAN0 Transmit Warning */ + HANDLER kinetis_can0rw, KINETIS_IRQ_CAN0RW /* Vector 49: CAN0 Receive Warning */ + HANDLER kinetis_can0wu, KINETIS_IRQ_CAN0WU /* Vector 50: CAN0 Wake UP */ + HANDLER kinetis_can1mb, KINETIS_IRQ_CAN1MB /* Vector 53: CAN1 OR'ed Message buffer (0-15) */ + HANDLER kinetis_can1bo, KINETIS_IRQ_CAN1BO /* Vector 54: CAN1 Bus Off */ + HANDLER kinetis_can1err, KINETIS_IRQ_CAN1ERR /* Vector 55: CAN1 Error */ + HANDLER kinetis_can1tw, KINETIS_IRQ_CAN1TW /* Vector 56: CAN1 Transmit Warning */ + HANDLER kinetis_can1rw, KINETIS_IRQ_CAN1RW /* Vector 57: CAN1 Receive Warning */ + HANDLER kinetis_can1wu, KINETIS_IRQ_CAN1WU /* Vector 58: CAN1 Wake UP */ + HANDLER kinetis_uart0s, KINETIS_IRQ_UART0S /* Vector 61: UART0 status */ + HANDLER kinetis_uart0e, KINETIS_IRQ_UART0E /* Vector 62: UART0 error */ + HANDLER kinetis_uart1s, KINETIS_IRQ_UART1S /* Vector 63: UART1 status */ + HANDLER kinetis_uart1e, KINETIS_IRQ_UART1E /* Vector 64: UART1 error */ + HANDLER kinetis_uart2s, KINETIS_IRQ_UART2S /* Vector 65: UART2 status */ + HANDLER kinetis_uart2e, KINETIS_IRQ_UART2E /* Vector 66: UART2 error */ + HANDLER kinetis_uart3s, KINETIS_IRQ_UART3S /* Vector 67: UART3 status */ + HANDLER kinetis_uart3e, KINETIS_IRQ_UART3E /* Vector 68: UART3 error */ + HANDLER kinetis_uart4s, KINETIS_IRQ_UART4S /* Vector 69: UART4 status */ + HANDLER kinetis_uart4e, KINETIS_IRQ_UART4E /* Vector 70: UART4 error */ + HANDLER kinetis_uart5s, KINETIS_IRQ_UART5S /* Vector 71: UART5 status */ + HANDLER kinetis_uart5e, KINETIS_IRQ_UART5E /* Vector 72: UART5 error */ + HANDLER kinetis_adc0, KINETIS_IRQ_ADC0 /* Vector 73: ADC0 */ + HANDLER kinetis_adc1, KINETIS_IRQ_ADC1 /* Vector 74: ADC1 */ + HANDLER kinetis_cmp0, KINETIS_IRQ_CMP0 /* Vector 75: CMP0 */ + HANDLER kinetis_cmp1, KINETIS_IRQ_CMP1 /* Vector 76: CMP1 */ + HANDLER kinetis_cmp2, KINETIS_IRQ_CMP2 /* Vector 77: CMP2 */ + HANDLER kinetis_ftm0, KINETIS_IRQ_FTM0 /* Vector 78: FTM0 all sources */ + HANDLER kinetis_ftm1, KINETIS_IRQ_FTM1 /* Vector 79: FTM1 all sources */ + HANDLER kinetis_ftm2, KINETIS_IRQ_FTM2 /* Vector 80: FTM2 all sources */ + HANDLER kinetis_cmt, KINETIS_IRQ_CMT /* Vector 81: CMT */ + HANDLER kinetis_rtc, KINETIS_IRQ_RTC /* Vector 82: RTC alarm interrupt */ + HANDLER kinetis_pitch0, KINETIS_IRQ_PITCH0 /* Vector 84: PIT channel 0 */ + HANDLER kinetis_pitch1, KINETIS_IRQ_PITCH1 /* Vector 85: PIT channel 1 */ + HANDLER kinetis_pitch2, KINETIS_IRQ_PITCH2 /* Vector 86: PIT channel 2 */ + HANDLER kinetis_pitch3, KINETIS_IRQ_PITCH3 /* Vector 87: PIT channel 3 */ + HANDLER kinetis_pdb, KINETIS_IRQ_PDB /* Vector 88: PDB */ + HANDLER kinetis_usbotg, KINETIS_IRQ_USBOTG /* Vector 88: USB OTG */ + HANDLER kinetis_usbcd, KINETIS_IRQ_USBCD /* Vector 90: USB charger detect */ + HANDLER kinetis_emactmr, KINETIS_IRQ_EMACTMR /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */ + HANDLER kinetis_emactx, KINETIS_IRQ_EMACTX /* Vector 92: Ethernet MAC transmit interrupt */ + HANDLER kinetis_emacrx, KINETIS_IRQ_EMACRX /* Vector 93: Ethernet MAC receive interrupt */ + HANDLER kinetis_emacmisc, KINETIS_IRQ_EMACMISC /* Vector 94: Ethernet MAC error and misc interrupt */ + HANDLER kinetis_i2s0, KINETIS_IRQ_I2S0 /* Vector 95: I2S0 */ + HANDLER kinetis_sdhc, KINETIS_IRQ_SDHC /* Vector 96: SDHC */ + HANDLER kinetis_dac0, KINETIS_IRQ_DAC0 /* Vector 97: DAC0 */ + HANDLER kinetis_dac1, KINETIS_IRQ_DAC1 /* Vector 98: DAC1 */ + HANDLER kinetis_tsi, KINETIS_IRQ_TSI /* Vector 97: TSI all sources */ + HANDLER kinetis_mcg, KINETIS_IRQ_MCG /* Vector 100: MCG */ + HANDLER kinetis_lpt, KINETIS_IRQ_LPT /* Vector 101: Low power timer */ + HANDLER kinetis_porta, KINETIS_IRQ_PORTA /* Vector 103: Pin detect port A */ + HANDLER kinetis_portb, KINETIS_IRQ_PORTB /* Vector 104: Pin detect port B */ + HANDLER kinetis_portc, KINETIS_IRQ_PORTC /* Vector 105: Pin detect port C */ + HANDLER kinetis_portd, KINETIS_IRQ_PORTD /* Vector 106: Pin detect port D */ + HANDLER kinetis_porte, KINETIS_IRQ_PORTE /* Vector 107: Pin detect port E */ + +#else +# error "No handlers for this Kinetis part" +#endif + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .globl exception_common + .type exception_common, function + +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size handlers, .-handlers + +/************************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************************ + * .rodata + ************************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/kinetis/kinetis_vrefv1.h b/arch/arm/src/kinetis/kinetis_vrefv1.h new file mode 100644 index 0000000000000000000000000000000000000000..ed9a1ff95c5dc51779b89864f9ac29f5f73f371c --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_vrefv1.h @@ -0,0 +1,92 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_vrefv1.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_VREF_TRM_OFFSET 0x0000 /* VREF Trim Register */ +#define KINETIS_VREF_SC_OFFSET 0x0001 /* VREF Status and Control Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_VREF_TRM (KINETIS_VREF_BASE+KINETIS_VREF_TRM_OFFSET) +#define KINETIS_VREF_SC (KINETIS_VREF_BASE+KINETIS_VREF_SC_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* VREF Trim Register (8-bit) */ + +#define VREF_TRM_SHIFT (0) /* Bits 0-5: Trim bits */ +#define VREF_TRM_MASK (63 << VREF_TRM_SHIFT) + /* Bits 6-7: Reserved */ +/* VREF Status and Control Register (8-bit) */ + +#define VREF_SC_MODE_LV_SHIFT (0) /* Bits 0-1: Buffer Mode selection */ +#define VREF_SC_MODE_LV_MASK (3 << VREF_SC_MODE_LV_SHIFT) +# define VREF_SC_MODE_LV_BANDGAP (0 << VREF_SC_MODE_LV_SHIFT) /* Bandgap on only */ +# define VREF_SC_MODE_LV_LOWPWR (1 << VREF_SC_MODE_LV_SHIFT) /* Low-power buffer enabled */ +# define VREF_SC_MODE_LV_TIGHT (2 << VREF_SC_MODE_LV_SHIFT) /* Tight-regulation buffer enabled */ +#define VREF_SC_VREFST (1 << 2) /* Bit 2: Internal Voltage Reference stable */ + /* Bits 3-5: Reserved */ +#define VREF_SC_REGEN (1 << 6) /* Bit 6: Regulator enable */ +#define VREF_SC_VREFEN (1 << 7) /* Bit 7: Internal Voltage Reference enable */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H */ diff --git a/arch/arm/src/kinetis/kinetis_wdog.c b/arch/arm/src/kinetis/kinetis_wdog.c new file mode 100644 index 0000000000000000000000000000000000000000..9dc29b80d8963576c400758580b4fa4edecb5945 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_wdog.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_wdog.c + * arch/arm/src/chip/kinetis_wdog.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "kinetis.h" +#include "kinetis_wdog.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_wdunlock + * + * Description: + * Watchdog timer unlock routine. Writing 0xc520 followed by 0xd928 will + * unlock the write once registers in the WDOG so they are writable + * within the WCT period. + * + ****************************************************************************/ + +static void kinetis_wdunlock(void) +{ + irqstate_t flags; + + /* This sequence must execute within 20 clock cycles. Disable interrupts + * to assure that the following steps are atomic. + */ + + flags = enter_critical_section(); + + /* Write 0xC520 followed by 0xD928 to the unlock register */ + + putreg16(0xc520, KINETIS_WDOG_UNLOCK); + putreg16(0xd928, KINETIS_WDOG_UNLOCK); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_wddisable + * + * Description: + * Disable the watchdog timer + * + ****************************************************************************/ + +void kinetis_wddisable(void) +{ + uint16_t regval; + + /* Unlock the watchdog so that we can write to registers */ + + kinetis_wdunlock(); + + /* Clear the WDOGEN bit to disable the watchdog */ + + regval = getreg16(KINETIS_WDOG_STCTRLH); + regval &= ~WDOG_STCTRLH_WDOGEN; + putreg16(regval, KINETIS_WDOG_STCTRLH); +} diff --git a/arch/arm/src/kinetis/kinetis_wdog.h b/arch/arm/src/kinetis/kinetis_wdog.h new file mode 100644 index 0000000000000000000000000000000000000000..326c2cf628fe360fc904dc2f51ebe09008fd24ed --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_wdog.h @@ -0,0 +1,135 @@ +/******************************************************************************************** + * arch/arm/src/kinetis/kinetis_wdog.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KINETIS_WDOG_STCTRLH_OFFSET 0x0000 /* Watchdog Status and Control Register High */ +#define KINETIS_WDOG_STCTRLL_OFFSET 0x0002 /* Watchdog Status and Control Register Low */ +#define KINETIS_WDOG_TOVALH_OFFSET 0x0004 /* Watchdog Time-out Value Register High */ +#define KINETIS_WDOG_TOVALL_OFFSET 0x0006 /* Watchdog Time-out Value Register Low */ +#define KINETIS_WDOG_WINH_OFFSET 0x0008 /* Watchdog Window Register High */ +#define KINETIS_WDOG_WINL_OFFSET 0x000a /* Watchdog Window Register Low */ +#define KINETIS_WDOG_REFRESH_OFFSET 0x000c /* Watchdog Refresh Register */ +#define KINETIS_WDOG_UNLOCK_OFFSET 0x000e /* Watchdog Unlock Register */ +#define KINETIS_WDOG_TMROUTH_OFFSET 0x0010 /* Watchdog Timer Output Register High */ +#define KINETIS_WDOG_TMROUTL_OFFSET 0x0012 /* Watchdog Timer Output Register Low */ +#define KINETIS_WDOG_RSTCNT_OFFSET 0x0014 /* Watchdog Reset Count Register */ +#define KINETIS_WDOG_PRESC_OFFSET 0x0016 /* Watchdog Prescaler Register */ + +/* Register Addresses ***********************************************************************/ + +#define KINETIS_WDOG_STCTRLH (KINETIS_WDOG_BASE+KINETIS_WDOG_STCTRLH_OFFSET) +#define KINETIS_WDOG_STCTRLL (KINETIS_WDOG_BASE+KINETIS_WDOG_STCTRLL_OFFSET) +#define KINETIS_WDOG_TOVALH (KINETIS_WDOG_BASE+KINETIS_WDOG_TOVALH_OFFSET) +#define KINETIS_WDOG_TOVALL (KINETIS_WDOG_BASE+KINETIS_WDOG_TOVALL_OFFSET) +#define KINETIS_WDOG_WINH (KINETIS_WDOG_BASE+KINETIS_WDOG_WINH_OFFSET) +#define KINETIS_WDOG_WINL (KINETIS_WDOG_BASE+KINETIS_WDOG_WINL_OFFSET) +#define KINETIS_WDOG_REFRESH (KINETIS_WDOG_BASE+KINETIS_WDOG_REFRESH_OFFSET) +#define KINETIS_WDOG_UNLOCK (KINETIS_WDOG_BASE+KINETIS_WDOG_UNLOCK_OFFSET) +#define KINETIS_WDOG_TMROUTH (KINETIS_WDOG_BASE+KINETIS_WDOG_TMROUTH_OFFSET) +#define KINETIS_WDOG_TMROUTL (KINETIS_WDOG_BASE+KINETIS_WDOG_TMROUTL_OFFSET) +#define KINETIS_WDOG_RSTCNT (KINETIS_WDOG_BASE+KINETIS_WDOG_RSTCNT_OFFSET) +#define KINETIS_WDOG_PRESC (KINETIS_WDOG_BASE+KINETIS_WDOG_PRESC_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* Watchdog Status and Control Register High (16-bit) */ + +#define WDOG_STCTRLH_WDOGEN (1 << 0) /* Bit 0: Enables or disables the WDOG’s operation */ +#define WDOG_STCTRLH_CLKSRC (1 << 1) /* Bit 1: Selects clock source for the WDOG timer */ +#define WDOG_STCTRLH_IRQRSTEN (1 << 2) /* Bit 2: Enable the debug breadcrumbs feature */ +#define WDOG_STCTRLH_WINEN (1 << 3) /* Bit 3: Enable windowing mode */ +#define WDOG_STCTRLH_ALLOWUPDATE (1 << 4) /* Bit 4: Enables updates to watchdog */ +#define WDOG_STCTRLH_DBGEN (1 << 5) /* Bit 5: Enables or disables WDOG in Debug mode */ +#define WDOG_STCTRLH_STOPEN (1 << 6) /* Bit 6: Enables or disables WDOG in stop mode */ +#define WDOG_STCTRLH_WAITEN (1 << 7) /* Bit 7: Enables or disables WDOG in wait mode */ +#define WDOG_STCTRLH_STNDBYEN (1 << 8) /* Bit 8: Enables or disables WDOG in Standby mode */ + /* Bit 9: Reserved */ +#define WDOG_STCTRLH_TESTWDOG (1 << 10) /* Bit 10: Selects functional test mode */ +#define WDOG_STCTRLH_TESTSEL (1 << 11) /* Bit 11: Selects the test to be run */ +#define WDOG_STCTRLH_BYTESEL_SHIFT (12) /* Bits 12-13: Selects the byte in test mode */ +#define WDOG_STCTRLH_BYTESEL_MASK (3 << WDOG_STCTRLH_BYTESEL_SHIFT) +# define WDOG_STCTRLH_BYTESEL_BYTE0 (0 << WDOG_STCTRLH_BYTESEL_SHIFT) /* Byte 0 selected */ +# define WDOG_STCTRLH_BYTESEL_BYTE1 (1 << WDOG_STCTRLH_BYTESEL_SHIFT) /* Byte 1 selected */ +# define WDOG_STCTRLH_BYTESEL_BYTE2 (2 << WDOG_STCTRLH_BYTESEL_SHIFT) /* Byte 2 selected */ +# define WDOG_STCTRLH_BYTESEL_BYTE3 (3 << WDOG_STCTRLH_BYTESEL_SHIFT) /* Byte 3 selected */ +#define WDOG_STCTRLH_DISTESTWDOG (1 << 14) /* Bit 14: Disable WDOG’s functional test mode */ + /* Bit 15: Reserved */ +/* Watchdog Status and Control Register Low (16-bit) */ + +#define WDOG_STCTRLL_INTFLG (1 << 15) /* Bit 15: Interrupt flag */ + /* Bits 0-14: Reserved */ + +/* Watchdog Time-out Value Register High/Low (16-bit timeout values) */ +/* Watchdog Window Register High/Low (16-bit window values) */ +/* Watchdog Refresh Register (16-bit, 0xa602 followed by 0xb480) */ +/* Watchdog Unlock Register (16-bit, 0xc520 followed by 0xd928) */ +/* Watchdog Timer Output Register High/Low (16-bit timer values) */ +/* Watchdog Reset Count Register (16-bit reset count) */ + +/* Watchdog Prescaler Register (16-bit) */ + /* Bits 0-7: Reserved */ +#define WDOG_PRESC_PRESCVAL_SHIFT (8) /* Bits 8-10: Watchdog clock source prescaler */ +#define WDOG_PRESC_PRESCVAL_MASK (7 << WDOG_PRESC_PRESCVAL_SHIFT) + /* Bits 11-15: Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H */ diff --git a/arch/arm/src/kl/Kconfig b/arch/arm/src/kl/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4505fc3e67c2a4043baef2216fd2974891e2c832 --- /dev/null +++ b/arch/arm/src/kl/Kconfig @@ -0,0 +1,365 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Kinetis Configuration Options" + +choice + prompt "Kinetis Chip Selection" + default ARCH_CHIP_MKL25Z128 + depends on ARCH_CHIP_KL + +config ARCH_CHIP_MKL25Z64 + bool "MKL25Z64" + select ARCH_FAMILY_KL2X + +config ARCH_CHIP_MKL25Z128 + bool "MKL25Z128" + select ARCH_FAMILY_KL2X + +config ARCH_CHIP_MKL26Z128 + bool "MKL26Z128" + select ARCH_FAMILY_KL2X + +endchoice + +# Chip families + +config ARCH_FAMILY_KL2X + bool + default n + +menu "Kinetis Peripheral Support" + +config KL_TRACE + bool "Trace" + default n + ---help--- + Enable trace clocking on power up. + +config KL_FLEXBUS + bool "FlexBus" + default n + ---help--- + Enable flexbus clocking on power up. + +config KL_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + ---help--- + Support UART0 + +config KL_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + ---help--- + Support UART1 + +config KL_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + ---help--- + Support UART2 + +config KL_RNGB + bool "Random number generator" + default n + depends on ARCH_FAMILY_K60 + select ARCH_HAVE_RNG + ---help--- + Support the random number generator(K60 only) + +config KL_FLEXCAN0 + bool "FlexCAN0" + default n + ---help--- + Support FlexCAN0 + +config KL_FLEXCAN1 + bool "FlexCAN1" + default n + ---help--- + Support FlexCAN1 + +config KL_SPI0 + bool "SPI0" + default n + select SPI + select SPI_EXCHANGE + ---help--- + Support SPI0 + +config KL_SPI1 + bool "SPI1" + default n + select SPI + select SPI_EXCHANGE + ---help--- + Support SPI1 + +config KL_SPI2 + bool "SPI2" + default n + ---help--- + Support SPI2 + +config KL_I2C0 + bool "I2C0" + default n + ---help--- + Support I2C0 + +config KL_I2C1 + bool "I2C1" + default n + ---help--- + Support I2C1 + +config KL_I2S + bool "I2S" + default n + ---help--- + Support I2S + +config KL_DAC0 + bool "DAC0" + default n + ---help--- + Support DAC0 + +config KL_DAC1 + bool "DAC1" + default n + ---help--- + Support DAC1 + +config KL_ADC0 + bool "ADC0" + default n + ---help--- + Support ADC0 + +config KL_ADC1 + bool "ADC1" + default n + ---help--- + Support ADC1 + +config KL_CMP + bool "CMP" + default n + ---help--- + Support CMP + +config KL_VREF + bool "VREF" + default n + ---help--- + Support VREF + +config KL_TPM0 + bool "Timer/PWM Module 0" + default n + ---help--- + Support FlexTimer 0 + +config KL_TPM1 + bool "Timer/PWM Module 1" + default n + ---help--- + Support FlexTimer 1 + +config KL_TPM2 + bool "Timer/PWM Module 2" + default n + ---help--- + Support FlexTimer 2 + +config KL_LPTIMER + bool "Low power timer (LPTIMER)" + default n + ---help--- + Support the low power timer + +config KL_RTC + bool "RTC" + default n + ---help--- + Support RTC + +config KL_SLCD + bool "Segment LCD (SLCD)" + default n + depends on ARCH_FAMILY_K40 + ---help--- + Support the segment LCD (K40 only) + +config KL_EWM + bool "External watchdog (WVM)" + default n + ---help--- + Support the external watchdog + +config KL_CMT + bool "Carrier modulator transmitter (CMT)" + default n + ---help--- + Support Carrier Modulator Transmitter + +config KL_USBOTG + bool "USB OTG" + default n + ---help--- + Support USB OTG (see also USBHOST and USBDEV) + +config KL_USBDCD + bool "USB device controller" + default n + ---help--- + Support the USB Device Charger Detection module + +config KL_LLWU + bool "Low leakage wake-up unit (LLWU)" + default n + ---help--- + Support the Low Leakage Wake-Up Unit + +config KL_TSI + bool "Touchscreen interface (TSI)" + default n + ---help--- + Support the touch screeen interface + +config KL_FTFL + bool "FLASH (FTFL)" + default n + ---help--- + Support FLASH + +config KL_DMA + bool "DMA" + default n + ---help--- + Support DMA + +config KL_CRC + bool "CRC" + default n + ---help--- + Support CRC + +config KL_PDB + bool "Programmable delay block (PDB)" + default n + ---help--- + Support the Programmable Delay Block + +config KL_PIT + bool "Programmable interval timer (PIT)" + default n + ---help--- + Support Programmable Interval Timers + +endmenu + +choice + prompt "SysTick clock source" + default KL_SYSTICK_CORECLK + +config KL_SYSTICK_CORECLK + bool "Cortex-M0 core clock" + +config KL_SYSTICK_CORECLK_DIV16 + bool "Cortex-M0 core clock divided by 16" + +endchoice + +config KL_TPM0_PWM + bool "TPM0 PWM" + default n + depends on KL_TPM0 + ---help--- + Reserve timer 0 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If KL_TPM0 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +config KL_TPM0_CHANNEL + int "TPM0 PWM Output Channel" + default 0 + range 0 5 + depends on KL_TPM0_PWM + ---help--- + If TIM0 is enabled for PWM usage, you also need specifies the timer output + channel {0,..,5} + +config KL_TPM1_PWM + bool "TPM1 PWM" + default n + depends on KL_TPM1 + ---help--- + Reserve timer 1 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If KL_TPM1 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +config KL_TPM1_CHANNEL + int "TPM1 PWM Output Channel" + default 0 + range 0 1 if ARCH_CHIP_MKL25Z64 || ARCH_CHIP_MKL25Z128 || ARCH_CHIP_MKL26Z128 + range 0 5 if !ARCH_CHIP_MKL25Z64 && !ARCH_CHIP_MKL25Z128 && !ARCH_CHIP_MKL26Z128 + depends on KL_TPM1_PWM + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {0,..,5} + +config KL_TPM2_PWM + bool "TPM2 PWM" + default n + depends on KL_TPM2 + ---help--- + Reserve timer 2 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If KL_TPM2 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +config KL_TPM2_CHANNEL + int "TPM2 PWM Output Channel" + default 0 + range 0 1 if ARCH_CHIP_MKL25Z64 || ARCH_CHIP_MKL25Z128 || ARCH_CHIP_MKL26Z128 + range 0 5 if !ARCH_CHIP_MKL25Z64 && !ARCH_CHIP_MKL25Z128 && !ARCH_CHIP_MKL26Z128 + depends on KL_TPM2_PWM + ---help--- + If TIM2 is enabled for PWM usage, you also need specifies the timer output + channel {0,..,5} + +comment "Kinetis GPIO Interrupt Configuration" + +config GPIO_IRQ + bool "GPIO pin interrupts" + ---help--- + Enable support for interrupting GPIO pins + +if GPIO_IRQ + +config KL_PORTAINTS + bool "GPIOA interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port A pins + +config KL_PORTDINTS + bool "GPIOD interrupts" + ---help--- + Enable support for 32 interrupts from GPIO port D pins + +endif diff --git a/arch/arm/src/kl/Make.defs b/arch/arm/src/kl/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..68c58af802e470f8a565a0b55728c4d57087bfa1 --- /dev/null +++ b/arch/arm/src/kl/Make.defs @@ -0,0 +1,106 @@ +############################################################################ +# arch/arm/src/kl/Make.defs +# +# Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_ASRCS = up_exception.S up_saveusercontext.S up_fullcontextrestore.S +CMN_ASRCS += up_switchcontext.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_puts.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vectors.c up_vfork.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CMN_CSRCS += up_dumpnvic.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = kl_clockconfig.c kl_gpio.c kl_idle.c kl_irq.c kl_lowgetc.c +CHIP_CSRCS += kl_lowputc.c kl_serial.c kl_start.c kl_cfmconfig.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += kl_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += kl_userspace.c +endif + +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += kl_gpioirq.c +endif + +ifeq ($(CONFIG_ARCH_IRQPRIO),y) +CHIP_CSRCS += kl_irqprio.c +endif + +ifeq ($(CONFIG_KL_SPI0),y) +CHIP_CSRCS += kl_spi.c +else +ifeq ($(CONFIG_KL_SPI1),y) +CHIP_CSRCS += kl_spi.c +endif +endif + +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += kl_pwm.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += kl_dumpgpio.c +endif diff --git a/arch/arm/src/kl/chip.h b/arch/arm/src/kl/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..0f4df66c96af7c0336d6de2d1d9edfb0df65b1fd --- /dev/null +++ b/arch/arm/src/kl/chip.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/kl/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_CHIP_H +#define __ARCH_ARM_SRC_KL_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* Define the number of interrupt vectors that need to be supported for this chip */ + +#define ARMV6M_PERIPHERAL_INTERRUPTS 32 + +/* Include the memory map file. Other chip hardware files should then include + * this file for the proper setup. + */ + +#include "chip/kl_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_CHIP_H */ diff --git a/arch/arm/src/kl/chip/k25z128_pinmux.h b/arch/arm/src/kl/chip/k25z128_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..597b55581c2eb41a6bc691782f77793f38910d0d --- /dev/null +++ b/arch/arm/src/kl/chip/k25z128_pinmux.h @@ -0,0 +1,339 @@ +/******************************************************************************************** + * arch/arm/src/kl/k25z128_pinmux.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_KL25PINMUX_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_KL25PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Reference: Paragraph 10.3.1, p 227, of FreeScale document K40P144M100SF2RM + * + * In most cases, there are alternative configurations for various pins. Those alternative + * pins are labeled with a suffix like _1, _2, etc. in order to distinguish them. Logic in + * the board.h file must select the correct pin configuration for the board by defining a pin + * configuration (with no suffix) that maps to the correct alternative. + */ + +#define PIN_TSI0_CH1 (PIN_ANALOG | PIN_PORTA | PIN0) +#define PIN_TPM0_CH5_1 (PIN_ALT3 | PIN_PORTA | PIN0) +#define PIN_SWD_CLK (PIN_ALT7 | PIN_PORTA | PIN0) + +#define PIN_TSI0_CH2 (PIN_ANALOG | PIN_PORTA | PIN1) +#define PIN_UART0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN1) +#define PIN_TPM2_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN1) + +#define PIN_TSI0_CH3 (PIN_ANALOG | PIN_PORTA | PIN2) +#define PIN_UART0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN2) +#define PIN_TPM2_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN2) + +#define PIN_TSI0_CH4 (PIN_ANALOG | PIN_PORTA | PIN3) +#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTA | PIN3) +#define PIN_TPM0_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN3) +#define PIN_SWD_DIO (PIN_ALT7 | PIN_PORTA | PIN3) + +#define PIN_TSI0_CH5 (PIN_ANALOG | PIN_PORTA | PIN4) +#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTA | PIN4) +#define PIN_TPM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4) +#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4) + +#define PIN_USB_CLKIN (PIN_ALT2 | PIN_PORTA | PIN5) +#define PIN_TPM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5) + +/* pins PTA6 up to PTA11 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_TPM1_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN12) + +#define PIN_TPM1_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN12) + +#define PIN_SPI0_PCS0_1 (PIN_ALT2 | PIN_PORTA | PIN14) +#define PIN_UART0_TX_2 (PIN_ALT3 | PIN_PORTA | PIN14) + +#define PIN_SPI0_SCK_1 (PIN_ALT2 | PIN_PORTA | PIN15) +#define PIN_UART0_RX_2 (PIN_ALT3 | PIN_PORTA | PIN15) + +#define PIN_SPI0_MOSI_1 (PIN_ALT2 | PIN_PORTA | PIN16) +#define PIN_SPI0_MISO_1 (PIN_ALT5 | PIN_PORTA | PIN16) + +#define PIN_SPI0_MISO_2 (PIN_ALT2 | PIN_PORTA | PIN17) +#define PIN_SPI0_MOSI_2 (PIN_ALT5 | PIN_PORTA | PIN17) + +#define PIN_EXTAL0 (PIN_ANALOG | PIN_PORTA | PIN18) +#define PIN_UART1_RX_1 (PIN_ALT3 | PIN_PORTA | PIN18) +#define PIN_TPM_CLKIN0_1 (PIN_ALT4 | PIN_PORTA | PIN18) + +#define PIN_XTAL0 (PIN_ANALOG | PIN_PORTA | PIN19) +#define PIN_UART1_TX_1 (PIN_ALT3 | PIN_PORTA | PIN19) +#define PIN_TPM_CLKIN1_1 (PIN_ALT4 | PIN_PORTA | PIN19) +#define PIN_LPTMR0_ALT1 (PIN_ALT6 | PIN_PORTA | PIN19) + +/* pin PTA20 is RESET and pins PTA21 up to PTA31 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0) +#define PIN_LLWU_P5 (PIN_ALT1 | PIN_PORTB | PIN0) +#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0) +#define PIN_TPM1_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN0) + +#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_TSI0_CH6 (PIN_ANALOG | PIN_PORTB | PIN1) +#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1) +#define PIN_TPM1_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN1) + +#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_TSI0_CH7 (PIN_ANALOG | PIN_PORTB | PIN2) +#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2) +#define PIN_TPM2_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN2) + +#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_TSI0_CH8 (PIN_ANALOG | PIN_PORTB | PIN3) +#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3) +#define PIN_TPM2_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN3) + +/* pins PTB4 up to PTB7 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_EXTRG_IN_1 (PIN_ALT3 | PIN_PORTB | PIN8) + +#define PIN_SPI1_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN10) + +#define PIN_SPI1_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN11) + +#define PIN_TSI0_CH9 (PIN_ANALOG | PIN_PORTB | PIN16) +#define PIN_SPI1_MOSI_1 (PIN_ALT2 | PIN_PORTB | PIN16) +#define PIN_UART0_RX_3 (PIN_ALT3 | PIN_PORTB | PIN16) +#define PIN_TPM_CLKIN0_2 (PIN_ALT4 | PIN_PORTB | PIN16) +#define PIN_SPI1_MISO_1 (PIN_ALT5 | PIN_PORTB | PIN16) + +#define PIN_TSI0_CH10 (PIN_ANALOG | PIN_PORTB | PIN17) +#define PIN_SPI1_MISO_2 (PIN_ALT2 | PIN_PORTB | PIN17) +#define PIN_UART0_TX_3 (PIN_ALT3 | PIN_PORTB | PIN17) +#define PIN_TPM_CLKIN1_2 (PIN_ALT4 | PIN_PORTB | PIN17) +#define PIN_SPI1_MOSI_2 (PIN_ALT7 | PIN_PORTB | PIN17) + +#define PIN_TSI0_CH11 (PIN_ANALOG | PIN_PORTB | PIN18) +#define PIN_TPM2_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN18) + +#define PIN_TSI0_CH12 (PIN_ANALOG | PIN_PORTB | PIN19) +#define PIN_TPM2_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN19) + +/* pins PTB20 up to PTB31 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_ADC0_SE14 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_TSI0_CH13 (PIN_ANALOG | PIN_PORTC | PIN0) +#define PIN_EXTRG_IN_2 (PIN_ALT3 | PIN_PORTC | PIN0) +#define PIN_CPM0_OUT (PIN_ALT5 | PIN_PORTC | PIN0) + +#define PIN_ADC0_SE15 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_TSI0_CH14 (PIN_ANALOG | PIN_PORTC | PIN1) +#define PIN_LLWU_P6 (PIN_ALT1 | PIN_PORTC | PIN1) +#define PIN_RTC_CLKIN (PIN_ALT1 | PIN_PORTC | PIN1) +#define PIN_I2C1_SCL_2 (PIN_ALT2 | PIN_PORTC | PIN1) +#define PIN_TPM0_CH0_2 (PIN_ALT4 | PIN_PORTC | PIN1) + +#define PIN_ADC0_SE11 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_TSI0_CH15 (PIN_ANALOG | PIN_PORTC | PIN2) +#define PIN_I2C1_SDA_2 (PIN_ALT2 | PIN_PORTC | PIN2) +#define PIN_TPM0_CH1_2 (PIN_ALT4 | PIN_PORTC | PIN2) + +#define PIN_LLWU_P7 (PIN_ALT1 | PIN_PORTC | PIN3) +#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTC | PIN3) +#define PIN_TPM0_CH2_2 (PIN_ALT4 | PIN_PORTC | PIN3) +#define PIN_CLKOUT (PIN_ALT5 | PIN_PORTC | PIN3) + +#define PIN_LLWU_P8 (PIN_ALT1 | PIN_PORTC | PIN4) +#define PIN_SPI0_PCS0_2 (PIN_ALT2 | PIN_PORTC | PIN4) +#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTC | PIN4) +#define PIN_TPM0_CH3_1 (PIN_ALT4 | PIN_PORTC | PIN4) + +#define PIN_LLWU_P9 (PIN_ALT1 | PIN_PORTC | PIN5) +#define PIN_SPI0_SCK_2 (PIN_ALT2 | PIN_PORTC | PIN5) +#define PIN_LPTMR0_ALT2 (PIN_ALT4 | PIN_PORTC | PIN5) +#define PIN_CMP0_OUT_1 (PIN_ALT6 | PIN_PORTC | PIN5) + +#define PIN_CMP0_IN0 (PIN_ANALOG | PIN_PORTC | PIN6) +#define PIN_LLWU_P10 (PIN_ALT1 | PIN_PORTC | PIN6) +#define PIN_SPI0_MOSI_3 (PIN_ALT2 | PIN_PORTC | PIN6) +#define PIN_EXTRG_IN_3 (PIN_ALT3 | PIN_PORTC | PIN6) +#define PIN_SPI0_MISO_3 (PIN_ALT5 | PIN_PORTC | PIN6) + +#define PIN_CMP0_IN1 (PIN_ANALOG | PIN_PORTC | PIN7) +#define PIN_SPI0_MISO_4 (PIN_ALT2 | PIN_PORTC | PIN7) +#define PIN_SPI0_MOSI_4 (PIN_ALT5 | PIN_PORTC | PIN7) + +#define PIN_CMP0_IN2 (PIN_ANALOG | PIN_PORTC | PIN8) +#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTC | PIN8) +#define PIN_TPM0_CH4_1 (PIN_ALT3 | PIN_PORTC | PIN8) + +#define PIN_CMP0_IN3 (PIN_ANALOG | PIN_PORTC | PIN9) +#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTC | PIN9) +#define PIN_TPM0_CH5_2 (PIN_ALT3 | PIN_PORTC | PIN9) + +#define PIN_I2C1_SCL_3 (PIN_ALT2 | PIN_PORTC | PIN10) + +#define PIN_I2C1_SDA_3 (PIN_ALT2 | PIN_PORTC | PIN11) + +#define PIN_TPM_CLKIN0_3 (PIN_ALT4 | PIN_PORTC | PIN12) + +#define PIN_TPM_CLKIN1_3 (PIN_ALT4 | PIN_PORTC | PIN13) + +/* pins PTC18 up to PTC31 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_SPI0_PCS0_3 (PIN_ALT2 | PIN_PORTD | PIN0) +#define PIN_TPM0_CH0_3 (PIN_ALT4 | PIN_PORTD | PIN0) + +#define PIN_ADC0_SE5B (PIN_ANALOG | PIN_PORTD | PIN1) +#define PIN_SPI0_SCK_3 (PIN_ALT2 | PIN_PORTD | PIN1) +#define PIN_TPM0_CH1_3 (PIN_ALT4 | PIN_PORTD | PIN1) + +#define PIN_SPI0_MOSI_5 (PIN_ALT2 | PIN_PORTD | PIN2) +#define PIN_UART2_RX_1 (PIN_ALT3 | PIN_PORTD | PIN2) +#define PIN_TPM0_CH2_3 (PIN_ALT4 | PIN_PORTD | PIN2) +#define PIN_SPI0_MISO_5 (PIN_ALT5 | PIN_PORTD | PIN2) + +#define PIN_SPI0_MISO_6 (PIN_ALT2 | PIN_PORTD | PIN3) +#define PIN_UART2_TX_1 (PIN_ALT3 | PIN_PORTD | PIN3) +#define PIN_TPM0_CH3_2 (PIN_ALT4 | PIN_PORTD | PIN3) +#define PIN_SPI0_MOSI_6 (PIN_ALT5 | PIN_PORTD | PIN3) + +#define PIN_LLWU_P14 (PIN_ALT1 | PIN_PORTD | PIN4) +#define PIN_SPI0_PCS0_4 (PIN_ALT2 | PIN_PORTD | PIN4) +#define PIN_UART2_RX_2 (PIN_ALT3 | PIN_PORTD | PIN4) +#define PIN_TPM0_CH4_2 (PIN_ALT4 | PIN_PORTD | PIN4) + +#define PIN_ADC0_SE6B (PIN_ANALOG | PIN_PORTD | PIN5) +#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTD | PIN5) +#define PIN_UART2_TX_2 (PIN_ALT3 | PIN_PORTD | PIN5) +#define PIN_TPM0_CH5_3 (PIN_ALT4 | PIN_PORTD | PIN5) + +#define PIN_ADC0_SE7B (PIN_ANALOG | PIN_PORTD | PIN6) +#define PIN_LLWU_P15 (PIN_ALT1 | PIN_PORTD | PIN6) +#define PIN_SPI0_MOSI_7 (PIN_ALT2 | PIN_PORTD | PIN6) +#define PIN_UART0_RX_4 (PIN_ALT3 | PIN_PORTD | PIN6) +#define PIN_SPI0_MISO_7 (PIN_ALT5 | PIN_PORTD | PIN6) + +#define PIN_SPI1_MISO_3 (PIN_ALT2 | PIN_PORTD | PIN7) +#define PIN_UART0_TX_4 (PIN_ALT3 | PIN_PORTD | PIN7) +#define PIN_SPI1_MOSI_3 (PIN_ALT5 | PIN_PORTD | PIN7) + +/* pins PTD8 up to PTD31 are not define at + * 10.3.1 KL25 Signal Multiplexing and Pin Assignments + */ + +#define PIN_UART1_TX_3 (PIN_ALT3 | PIN_PORTE | PIN0) +#define PIN_RTC_CLKOUT (PIN_ALT4 | PIN_PORTE | PIN0) +#define PIN_CMP0_OUT_2 (PIN_ALT5 | PIN_PORTE | PIN0) +#define PIN_I2C1_SDA_4 (PIN_ALT6 | PIN_PORTE | PIN0) + +#define PIN_SPI1_MOSI_4 (PIN_ALT2 | PIN_PORTE | PIN1) +#define PIN_UART1_RX_3 (PIN_ALT3 | PIN_PORTE | PIN1) +#define PIN_SPI1_MISO_4 (PIN_ALT5 | PIN_PORTE | PIN1) +#define PIN_I2C1_SCL_4 (PIN_ALT6 | PIN_PORTE | PIN1) + +#define PIN_SPI1_SCK_3 (PIN_ALT2 | PIN_PORTE | PIN2) + +#define PIN_SPI1_MISO_5 (PIN_ALT2 | PIN_PORTE | PIN3) + +#define PIN_SPI1_PCS0_2 (PIN_ALT2 | PIN_PORTE | PIN4) + +#define PIN_ADC0_DP0 (PIN_ANALOG | PIN_PORTE | PIN20) +#define PIN_ADC0_SE0 (PIN_ANALOG | PIN_PORTE | PIN20) +#define PIN_TPM1_CH0_3 (PIN_ALT3 | PIN_PORTE | PIN20) +#define PIN_UART0_TX_5 (PIN_ALT4 | PIN_PORTE | PIN20) + +#define PIN_ADC0_DM0 (PIN_ANALOG | PIN_PORTE | PIN21) +#define PIN_ADC0_SE4A (PIN_ANALOG | PIN_PORTE | PIN21) +#define PIN_TPM1_CH1_3 (PIN_ALT3 | PIN_PORTE | PIN21) +#define PIN_UART0_RX_5 (PIN_ALT4 | PIN_PORTE | PIN21) + +#define PIN_ADC0_DP3 (PIN_ANALOG | PIN_PORTE | PIN22) +#define PIN_ADC0_SE3 (PIN_ANALOG | PIN_PORTE | PIN22) +#define PIN_TPM2_CH0_4 (PIN_ALT3 | PIN_PORTE | PIN22) +#define PIN_UART2_TX_3 (PIN_ALT4 | PIN_PORTE | PIN22) + +#define PIN_ADC0_DM3 (PIN_ANALOG | PIN_PORTE | PIN23) +#define PIN_ADC0_SE7A (PIN_ANALOG | PIN_PORTE | PIN23) +#define PIN_TPM2_CH1_4 (PIN_ALT3 | PIN_PORTE | PIN23) +#define PIN_UART2_RX_3 (PIN_ALT4 | PIN_PORTE | PIN23) + +#define PIN_TPM0_CH0_4 (PIN_ALT3 | PIN_PORTE | PIN24) +#define PIN_I2C0_SCL_4 (PIN_ALT5 | PIN_PORTE | PIN24) + +#define PIN_TPM0_CH1_4 (PIN_ALT3 | PIN_PORTE | PIN25) +#define PIN_I2C0_SDA_4 (PIN_ALT5 | PIN_PORTE | PIN25) + +#define PIN_CMP0_IN5 (PIN_ANALOG | PIN_PORTE | PIN29) +#define PIN_ADC0_SE4B (PIN_ANALOG | PIN_PORTE | PIN29) +#define PIN_TPM0_CH2_4 (PIN_ALT3 | PIN_PORTE | PIN29) +#define PIN_TPM_CLKIN0_4 (PIN_ALT4 | PIN_PORTE | PIN29) + +#define PIN_DAC0_OUT (PIN_ANALOG | PIN_PORTE | PIN30) +#define PIN_ADC0_SE23 (PIN_ANALOG | PIN_PORTE | PIN30) +#define PIN_CMP0_IN4 (PIN_ANALOG | PIN_PORTE | PIN30) +#define PIN_TPM0_CH3_3 (PIN_ALT3 | PIN_PORTE | PIN30) +#define PIN_TPM_CLKIN1_4 (PIN_ALT4 | PIN_PORTE | PIN30) + +#define PIN_TPM0_CH4_3 (PIN_ALT3 | PIN_PORTE | PIN31) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H */ diff --git a/arch/arm/src/kl/chip/kl_fmc.h b/arch/arm/src/kl/chip/kl_fmc.h new file mode 100644 index 0000000000000000000000000000000000000000..d11aedc6b1ac974efbfa487370d13191360dbb58 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_fmc.h @@ -0,0 +1,389 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_fmc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_FMC_H +#define __ARCH_ARM_SRC_KL_KL_FMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KL_FMC_PFAPR_OFFSET 0x0000 /* Flash Access Protection Register */ +#define KL_FMC_PFB0CR_OFFSET 0x0004 /* Flash Bank 0 Control Register */ +#define KL_FMC_PFB1CR_OFFSET 0x0008 /* Flash Bank 1 Control Register */ + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define KL_FMC_TAGVD_OFFSET(w,s) (0x100+((w)<<5)+((s)<<2)) + +#define KL_FMC_TAGVDW0S0_OFFSET 0x0100 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S1_OFFSET 0x0104 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S2_OFFSET 0x0108 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S3_OFFSET 0x010c /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S4_OFFSET 0x0110 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S5_OFFSET 0x0114 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S6_OFFSET 0x0118 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW0S7_OFFSET 0x011c /* Cache Directory Storage */ + +#define KL_FMC_TAGVDW1S0_OFFSET 0x0120 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S1_OFFSET 0x0124 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S2_OFFSET 0x0128 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S3_OFFSET 0x012c /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S4_OFFSET 0x0130 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S5_OFFSET 0x0134 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S6_OFFSET 0x0138 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW1S7_OFFSET 0x013c /* Cache Directory Storage */ + +#define KL_FMC_TAGVDW2S0_OFFSET 0x0140 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S1_OFFSET 0x0144 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S2_OFFSET 0x0148 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S3_OFFSET 0x014c /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S4_OFFSET 0x0150 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S5_OFFSET 0x0154 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S6_OFFSET 0x0158 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW2S7_OFFSET 0x015c /* Cache Directory Storage */ + +#define KL_FMC_TAGVDW3S0_OFFSET 0x0160 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S1_OFFSET 0x0164 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S2_OFFSET 0x0168 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S3_OFFSET 0x016c /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S4_OFFSET 0x0170 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S5_OFFSET 0x0174 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S6_OFFSET 0x0178 /* Cache Directory Storage */ +#define KL_FMC_TAGVDW3S7_OFFSET 0x017c /* Cache Directory Storage */ + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */ + +#define KL_FMC_DATAU_OFFSET(w,s) (0x200+((w)<<6)+((s)<<2)) +#define KL_FMC_DATAL_OFFSET(w,s) (0x204+((w)<<6)+((s)<<2)) + +#define KL_FMC_DATAW0S0U_OFFSET 0x0200 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S0L_OFFSET 0x0204 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S1U_OFFSET 0x0208 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S1L_OFFSET 0x020c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S2U_OFFSET 0x0210 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S2L_OFFSET 0x0214 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S3U_OFFSET 0x0218 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S3L_OFFSET 0x021c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S4U_OFFSET 0x0220 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S4L_OFFSET 0x0224 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S5U_OFFSET 0x0228 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S5L_OFFSET 0x022c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S6U_OFFSET 0x0230 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S6L_OFFSET 0x0234 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW0S7U_OFFSET 0x0238 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW0S7L_OFFSET 0x023c /* Cache Data Storage (lower word) */ + +#define KL_FMC_DATAW1S0U_OFFSET 0x0240 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S0L_OFFSET 0x0244 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S1U_OFFSET 0x0248 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S1L_OFFSET 0x024c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S2U_OFFSET 0x0250 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S2L_OFFSET 0x0254 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S3U_OFFSET 0x0258 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S3L_OFFSET 0x025c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S4U_OFFSET 0x0260 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S4L_OFFSET 0x0264 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S5U_OFFSET 0x0268 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S5L_OFFSET 0x026c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S6U_OFFSET 0x0270 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S6L_OFFSET 0x0274 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW1S7U_OFFSET 0x0278 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW1S7L_OFFSET 0x027c /* Cache Data Storage (lower word) */ + +#define KL_FMC_DATAW2S0U_OFFSET 0x0280 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S0L_OFFSET 0x0284 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S1U_OFFSET 0x0288 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S1L_OFFSET 0x028c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S2U_OFFSET 0x0290 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S2L_OFFSET 0x0294 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S3U_OFFSET 0x0298 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S3L_OFFSET 0x029c /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S4U_OFFSET 0x02a0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S4L_OFFSET 0x02a4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S5U_OFFSET 0x02a8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S5L_OFFSET 0x02ac /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S6U_OFFSET 0x02b0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S6L_OFFSET 0x02b4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW2S7U_OFFSET 0x02b8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW2S7L_OFFSET 0x02bc /* Cache Data Storage (lower word) */ + +#define KL_FMC_DATAW3S0U_OFFSET 0x02c0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S0L_OFFSET 0x02c4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S1U_OFFSET 0x02c8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S1L_OFFSET 0x02cc /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S2U_OFFSET 0x02d0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S2L_OFFSET 0x02d4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S3U_OFFSET 0x02d8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S3L_OFFSET 0x02dc /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S4U_OFFSET 0x02e0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S4L_OFFSET 0x02e4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S5U_OFFSET 0x02e8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S5L_OFFSET 0x02ec /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S6U_OFFSET 0x02f0 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S6L_OFFSET 0x02f4 /* Cache Data Storage (lower word) */ +#define KL_FMC_DATAW3S7U_OFFSET 0x02f8 /* Cache Data Storage (upper word) */ +#define KL_FMC_DATAW3S7L_OFFSET 0x02fc /* Cache Data Storage (lower word) */ + +/* Register Addresses ***************************************************************/ + +#define KL_FMC_PFAPR (KL_FMC_BASE+KL_FMC_PFAPR_OFFSET) +#define KL_FMC_PFB0CR (KL_FMC_BASE+KL_FMC_PFB0CR_OFFSET) +#define KL_FMC_PFB1CR (KL_FMC_BASE+KL_FMC_PFB1CR_OFFSET) + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define KL_FMC_TAGVD(w,s) (KL_FMC_BASE+KL_FMC_TAGVD_OFFSET(w,s)) + +#define KL_FMC_TAGVDW0S0 (KL_FMC_BASE+KL_FMC_TAGVDW0S0_OFFSET) +#define KL_FMC_TAGVDW0S1 (KL_FMC_BASE+KL_FMC_TAGVDW0S1_OFFSET) +#define KL_FMC_TAGVDW0S2 (KL_FMC_BASE+KL_FMC_TAGVDW0S2_OFFSET) +#define KL_FMC_TAGVDW0S3 (KL_FMC_BASE+KL_FMC_TAGVDW0S3_OFFSET) +#define KL_FMC_TAGVDW0S4 (KL_FMC_BASE+KL_FMC_TAGVDW0S4_OFFSET) +#define KL_FMC_TAGVDW0S5 (KL_FMC_BASE+KL_FMC_TAGVDW0S5_OFFSET) +#define KL_FMC_TAGVDW0S6 (KL_FMC_BASE+KL_FMC_TAGVDW0S6_OFFSET) +#define KL_FMC_TAGVDW0S7 (KL_FMC_BASE+KL_FMC_TAGVDW0S7_OFFSET) + +#define KL_FMC_TAGVDW1S0 (KL_FMC_BASE+KL_FMC_TAGVDW1S0_OFFSET) +#define KL_FMC_TAGVDW1S1 (KL_FMC_BASE+KL_FMC_TAGVDW1S1_OFFSET) +#define KL_FMC_TAGVDW1S2 (KL_FMC_BASE+KL_FMC_TAGVDW1S2_OFFSET) +#define KL_FMC_TAGVDW1S3 (KL_FMC_BASE+KL_FMC_TAGVDW1S3_OFFSET) +#define KL_FMC_TAGVDW1S4 (KL_FMC_BASE+KL_FMC_TAGVDW1S4_OFFSET) +#define KL_FMC_TAGVDW1S5 (KL_FMC_BASE+KL_FMC_TAGVDW1S5_OFFSET) +#define KL_FMC_TAGVDW1S6 (KL_FMC_BASE+KL_FMC_TAGVDW1S6_OFFSET) +#define KL_FMC_TAGVDW1S7 (KL_FMC_BASE+KL_FMC_TAGVDW1S7_OFFSET) + +#define KL_FMC_TAGVDW2S0 (KL_FMC_BASE+KL_FMC_TAGVDW2S0_OFFSET) +#define KL_FMC_TAGVDW2S1 (KL_FMC_BASE+KL_FMC_TAGVDW2S1_OFFSET) +#define KL_FMC_TAGVDW2S2 (KL_FMC_BASE+KL_FMC_TAGVDW2S2_OFFSET) +#define KL_FMC_TAGVDW2S3 (KL_FMC_BASE+KL_FMC_TAGVDW2S3_OFFSET) +#define KL_FMC_TAGVDW2S4 (KL_FMC_BASE+KL_FMC_TAGVDW2S4_OFFSET) +#define KL_FMC_TAGVDW2S5 (KL_FMC_BASE+KL_FMC_TAGVDW2S5_OFFSET) +#define KL_FMC_TAGVDW2S6 (KL_FMC_BASE+KL_FMC_TAGVDW2S6_OFFSET) +#define KL_FMC_TAGVDW2S7 (KL_FMC_BASE+KL_FMC_TAGVDW2S7_OFFSET) + +#define KL_FMC_TAGVDW3S0 (KL_FMC_BASE+KL_FMC_TAGVDW3S0_OFFSET) +#define KL_FMC_TAGVDW3S1 (KL_FMC_BASE+KL_FMC_TAGVDW3S1_OFFSET) +#define KL_FMC_TAGVDW3S2 (KL_FMC_BASE+KL_FMC_TAGVDW3S2_OFFSET) +#define KL_FMC_TAGVDW3S3 (KL_FMC_BASE+KL_FMC_TAGVDW3S3_OFFSET) +#define KL_FMC_TAGVDW3S4 (KL_FMC_BASE+KL_FMC_TAGVDW3S4_OFFSET) +#define KL_FMC_TAGVDW3S5 (KL_FMC_BASE+KL_FMC_TAGVDW3S5_OFFSET) +#define KL_FMC_TAGVDW3S6 (KL_FMC_BASE+KL_FMC_TAGVDW3S6_OFFSET) +#define KL_FMC_TAGVDW3S7 (KL_FMC_BASE+KL_FMC_TAGVDW3S7_OFFSET) + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */ + +#define KL_FMC_DATAU(w,s) (KL_FMC_BASE+KL_FMC_DATAU_OFFSET(w,s)) +#define KL_FMC_DATAL(w,s) (KL_FMC_BASE+KL_FMC_DATAL_OFFSET(w,s)) + +#define KL_FMC_DATAW0S0U (KL_FMC_BASE+KL_FMC_DATAW0S0U_OFFSET) +#define KL_FMC_DATAW0S0L (KL_FMC_BASE+KL_FMC_DATAW0S0L_OFFSET) +#define KL_FMC_DATAW0S1U (KL_FMC_BASE+KL_FMC_DATAW0S1U_OFFSET) +#define KL_FMC_DATAW0S1L (KL_FMC_BASE+KL_FMC_DATAW0S1L_OFFSET) +#define KL_FMC_DATAW0S2U (KL_FMC_BASE+KL_FMC_DATAW0S2U_OFFSET) +#define KL_FMC_DATAW0S2L (KL_FMC_BASE+KL_FMC_DATAW0S2L_OFFSET) +#define KL_FMC_DATAW0S3U (KL_FMC_BASE+KL_FMC_DATAW0S3U_OFFSET) +#define KL_FMC_DATAW0S3L (KL_FMC_BASE+KL_FMC_DATAW0S3L_OFFSET) +#define KL_FMC_DATAW0S4U (KL_FMC_BASE+KL_FMC_DATAW0S4U_OFFSET) +#define KL_FMC_DATAW0S4L (KL_FMC_BASE+KL_FMC_DATAW0S4L_OFFSET) +#define KL_FMC_DATAW0S5U (KL_FMC_BASE+KL_FMC_DATAW0S5U_OFFSET) +#define KL_FMC_DATAW0S5L (KL_FMC_BASE+KL_FMC_DATAW0S5L_OFFSET) +#define KL_FMC_DATAW0S6U (KL_FMC_BASE+KL_FMC_DATAW0S6U_OFFSET) +#define KL_FMC_DATAW0S6L (KL_FMC_BASE+KL_FMC_DATAW0S6L_OFFSET) +#define KL_FMC_DATAW0S7U (KL_FMC_BASE+KL_FMC_DATAW0S7U_OFFSET) +#define KL_FMC_DATAW0S7L (KL_FMC_BASE+KL_FMC_DATAW0S7L_OFFSET) + +#define KL_FMC_DATAW1S0U (KL_FMC_BASE+KL_FMC_DATAW1S0U_OFFSET) +#define KL_FMC_DATAW1S0L (KL_FMC_BASE+KL_FMC_DATAW1S0L_OFFSET) +#define KL_FMC_DATAW1S1U (KL_FMC_BASE+KL_FMC_DATAW1S1U_OFFSET) +#define KL_FMC_DATAW1S1L (KL_FMC_BASE+KL_FMC_DATAW1S1L_OFFSET) +#define KL_FMC_DATAW1S2U (KL_FMC_BASE+KL_FMC_DATAW1S2U_OFFSET) +#define KL_FMC_DATAW1S2L (KL_FMC_BASE+KL_FMC_DATAW1S2L_OFFSET) +#define KL_FMC_DATAW1S3U (KL_FMC_BASE+KL_FMC_DATAW1S3U_OFFSET) +#define KL_FMC_DATAW1S3L (KL_FMC_BASE+KL_FMC_DATAW1S3L_OFFSET) +#define KL_FMC_DATAW1S4U (KL_FMC_BASE+KL_FMC_DATAW1S4U_OFFSET) +#define KL_FMC_DATAW1S4L (KL_FMC_BASE+KL_FMC_DATAW1S4L_OFFSET) +#define KL_FMC_DATAW1S5U (KL_FMC_BASE+KL_FMC_DATAW1S5U_OFFSET) +#define KL_FMC_DATAW1S5L (KL_FMC_BASE+KL_FMC_DATAW1S5L_OFFSET) +#define KL_FMC_DATAW1S6U (KL_FMC_BASE+KL_FMC_DATAW1S6U_OFFSET) +#define KL_FMC_DATAW1S6L (KL_FMC_BASE+KL_FMC_DATAW1S6L_OFFSET) +#define KL_FMC_DATAW1S7U (KL_FMC_BASE+KL_FMC_DATAW1S7U_OFFSET) +#define KL_FMC_DATAW1S7L (KL_FMC_BASE+KL_FMC_DATAW1S7L_OFFSET) + +#define KL_FMC_DATAW2S0U (KL_FMC_BASE+KL_FMC_DATAW2S0U_OFFSET) +#define KL_FMC_DATAW2S0L (KL_FMC_BASE+KL_FMC_DATAW2S0L_OFFSET) +#define KL_FMC_DATAW2S1U (KL_FMC_BASE+KL_FMC_DATAW2S1U_OFFSET) +#define KL_FMC_DATAW2S1L (KL_FMC_BASE+KL_FMC_DATAW2S1L_OFFSET) +#define KL_FMC_DATAW2S2U (KL_FMC_BASE+KL_FMC_DATAW2S2U_OFFSET) +#define KL_FMC_DATAW2S2L (KL_FMC_BASE+KL_FMC_DATAW2S2L_OFFSET) +#define KL_FMC_DATAW2S3U (KL_FMC_BASE+KL_FMC_DATAW2S3U_OFFSET) +#define KL_FMC_DATAW2S3L (KL_FMC_BASE+KL_FMC_DATAW2S3L_OFFSET) +#define KL_FMC_DATAW2S4U (KL_FMC_BASE+KL_FMC_DATAW2S4U_OFFSET) +#define KL_FMC_DATAW2S4L (KL_FMC_BASE+KL_FMC_DATAW2S4L_OFFSET) +#define KL_FMC_DATAW2S5U (KL_FMC_BASE+KL_FMC_DATAW2S5U_OFFSET) +#define KL_FMC_DATAW2S5L (KL_FMC_BASE+KL_FMC_DATAW2S5L_OFFSET) +#define KL_FMC_DATAW2S6U (KL_FMC_BASE+KL_FMC_DATAW2S6U_OFFSET) +#define KL_FMC_DATAW2S6L (KL_FMC_BASE+KL_FMC_DATAW2S6L_OFFSET) +#define KL_FMC_DATAW2S7U (KL_FMC_BASE+KL_FMC_DATAW2S7U_OFFSET) +#define KL_FMC_DATAW2S7L (KL_FMC_BASE+KL_FMC_DATAW2S7L_OFFSET) + +#define KL_FMC_DATAW3S0U (KL_FMC_BASE+KL_FMC_DATAW3S0U_OFFSET) +#define KL_FMC_DATAW3S0L (KL_FMC_BASE+KL_FMC_DATAW3S0L_OFFSET) +#define KL_FMC_DATAW3S1U (KL_FMC_BASE+KL_FMC_DATAW3S1U_OFFSET) +#define KL_FMC_DATAW3S1L (KL_FMC_BASE+KL_FMC_DATAW3S1L_OFFSET) +#define KL_FMC_DATAW3S2U (KL_FMC_BASE+KL_FMC_DATAW3S2U_OFFSET) +#define KL_FMC_DATAW3S2L (KL_FMC_BASE+KL_FMC_DATAW3S2L_OFFSET) +#define KL_FMC_DATAW3S3U (KL_FMC_BASE+KL_FMC_DATAW3S3U_OFFSET) +#define KL_FMC_DATAW3S3L (KL_FMC_BASE+KL_FMC_DATAW3S3L_OFFSET) +#define KL_FMC_DATAW3S4U (KL_FMC_BASE+KL_FMC_DATAW3S4U_OFFSET) +#define KL_FMC_DATAW3S4L (KL_FMC_BASE+KL_FMC_DATAW3S4L_OFFSET) +#define KL_FMC_DATAW3S5U (KL_FMC_BASE+KL_FMC_DATAW3S5U_OFFSET) +#define KL_FMC_DATAW3S5L (KL_FMC_BASE+KL_FMC_DATAW3S5L_OFFSET) +#define KL_FMC_DATAW3S6U (KL_FMC_BASE+KL_FMC_DATAW3S6U_OFFSET) +#define KL_FMC_DATAW3S6L (KL_FMC_BASE+KL_FMC_DATAW3S6L_OFFSET) +#define KL_FMC_DATAW3S7U (KL_FMC_BASE+KL_FMC_DATAW3S7U_OFFSET) +#define KL_FMC_DATAW3S7L (KL_FMC_BASE+KL_FMC_DATAW3S7L_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Flash Access Protection Register */ +/* Access protection bits (all masters) */ + +#define FMC_PFAPR_NONE 0 /* No access may be performed by this master */ +#define FMC_PFAPR_RDONLY 1 /* Only read accesses may be performed by this master */ +#define FMC_PFAPR_WRONLY 2 /* Only write accesses may be performed by this master */ +#define FMC_PFAPR_RDWR 3 /* Both read and write accesses may be performed by this master */ + +#define FMC_PFAPR_M0AP_SHIFT (0) /* Bits 0-1: Master 0 Access Protection */ +#define FMC_PFAPR_M0AP_MASK (3 << FMC_PFAPR_M0AP_SHIFT) +#define FMC_PFAPR_M1AP_SHIFT (2) /* Bits 2-3: Master 1 Access Protection */ +#define FMC_PFAPR_M1AP_MASK (3 << FMC_PFAPR_M1AP_SHIFT) +#define FMC_PFAPR_M2AP_SHIFT (4) /* Bits 4-5: Master 2 Access Protection */ +#define FMC_PFAPR_M2AP_MASK (3 << FMC_PFAPR_M2AP_SHIFT) +#define FMC_PFAPR_M3AP_SHIFT (6) /* Bits 6-7: Master 3 Access Protection */ +#define FMC_PFAPR_M3AP_MASK (3 << FMC_PFAPR_M3AP_SHIFT) +#define FMC_PFAPR_M4AP_SHIFT (8) /* Bits 8-9: Master 4 Access Protection */ +#define FMC_PFAPR_M4AP_MASK (3 << FMC_PFAPR_M4AP_SHIFT) +#define FMC_PFAPR_M5AP_SHIFT (10) /* Bits 10-11: Master 5 Access Protection */ +#define FMC_PFAPR_M5AP_MASK (3 << FMC_PFAPR_M5AP_SHIFT) +#define FMC_PFAPR_M6AP_SHIFT (12) /* Bits 12-13: Master 6 Access Protection */ +#define FMC_PFAPR_M6AP_MASK (3 << FMC_PFAPR_M6AP_SHIFT) +#define FMC_PFAPR_M7AP_SHIFT (14) /* Bits 14-15: Master 7 Access Protection */ +#define FMC_PFAPR_M7AP_MASK (3 << FMC_PFAPR_M7AP_SHIFT) +#define FMC_PFAPR_M0PFD (1 << 16) /* Bit 16: Master 0 Prefetch Disable */ +#define FMC_PFAPR_M1PFD (1 << 17) /* Bit 17: Master 1 Prefetch Disable */ +#define FMC_PFAPR_M2PFD (1 << 18) /* Bit 18: Master 2 Prefetch Disable */ +#define FMC_PFAPR_M3PFD (1 << 19) /* Bit 19: Master 3 Prefetch Disable */ +#define FMC_PFAPR_M4PFD (1 << 20) /* Bit 20: Master 4 Prefetch Disable */ +#define FMC_PFAPR_M5PFD (1 << 21) /* Bit 21: Master 5 Prefetch Disable */ +#define FMC_PFAPR_M6PFD (1 << 22) /* Bit 22: Master 6 Prefetch Disable */ +#define FMC_PFAPR_M7PFD (1 << 23) /* Bit 23: Master 7 Prefetch Disable */ + /* Bits 24-31: Reserved */ +/* Flash Bank 0 Control Register */ + +#define FMC_PFB0CR_B0SEBE (1 << 0) /* Bit 0: Bank 0 Single Entry Buffer Enable */ +#define FMC_PFB0CR_B0IPE (1 << 1) /* Bit 1: Bank 0 Instruction Prefetch Enable */ +#define FMC_PFB0CR_B0DPE (1 << 2) /* Bit 2: Bank 0 Data Prefetch Enable */ +#define FMC_PFB0CR_B0ICE (1 << 3) /* Bit 3: Bank 0 Instruction Cache Enable */ +#define FMC_PFB0CR_B0DCE (1 << 4) /* Bit 4: Bank 0 Data Cache Enable */ +#define FMC_PFB0CR_CRC_SHIFT (5) /* Bits 5-7: Cache Replacement Control */ +#define FMC_PFB0CR_CRC_MASK (7 << FMC_PFB0CR_CRC_SHIFT) +# define FMC_PFB0CR_CRC_ALL (0 << FMC_PFB0CR_CRC_SHIFT) /* LRU all four ways */ +# define FMC_PFB0CR_CRC_I01D23 (2 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-1 data 2-3 */ +# define FMC_PFB0CR_CRC_I012D3 (3 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-3 data 3 */ + /* Bits 8-16: Reserved */ +#define FMC_PFB0CR_B0MW_SHIFT (17) /* Bits 17-18: Bank 0 Memory Width */ +#define FMC_PFB0CR_B0MW_MASK (3 << FMC_PFB0CR_B0MW_SHIFT) +# define FMC_PFB0CR_B0MW_32BITS (0 << FMC_PFB0CR_B0MW_SHIFT) /* 32 bits */ +# define FMC_PFB0CR_B0MW_64BITS (1 << FMC_PFB0CR_B0MW_SHIFT) /* 64 bits */ +#define FMC_PFB0CR_S_B_INV (1 << 19) /* Bit 19: Invalidate Prefetch Speculation Buffer */ +#define FMC_PFB0CR_CINV_WAY_SHIFT (20) /* Bits 20-23: Cache Invalidate Way x */ +#define FMC_PFB0CR_CINV_WAY_MASK (15 << FMC_PFB0CR_CINV_WAY_SHIFT) +#define FMC_PFB0CR_CLCK_WAY_SHIFT (24) /* Bits 24-27: Cache Lock Way x */ +#define FMC_PFB0CR_CLCK_WAY_MASK (15 << FMC_PFB0CR_CLCK_WAY_SHIFT) +#define FMC_PFB0CR_B0RWSC_SHIFT (28) /* Bits 28-31: Bank 0 Read Wait State Control */ +#define FMC_PFB0CR_B0RWSC_MASK (15 << FMC_PFB0CR_B0RWSC_SHIFT) + +/* Flash Bank 1 Control Register */ + +#define FMC_PFB1CR_B1SEBE (1 << 0) /* Bit 0: Bank 1 Single Entry Buffer Enable */ +#define FMC_PFB1CR_B1IPE (1 << 1) /* Bit 1: Bank 1 Instruction Prefetch Enable */ +#define FMC_PFB1CR_B1DPE (1 << 2) /* Bit 2: Bank 1 Data Prefetch Enable */ +#define FMC_PFB1CR_B1ICE (1 << 3) /* Bit 3: Bank 1 Instruction Cache Enable */ +#define FMC_PFB1CR_B1DCE (1 << 4) /* Bit 4: Bank 1 Data Cache Enable */ + /* Bits 5-16: Reserved */ +#define FMC_PFB1CR_B1MW_SHIFT (17) /* Bits 17-18: Bank 1 Memory Width */ +#define FMC_PFB1CR_B1MW_MASK (3 << FMC_PFB1CR_B1MW_SHIFT) +# define FMC_PFB1CR_B1MW_32BITS (0 << FMC_PFB1CR_B1MW_SHIFT) /* 32 bits */ +# define FMC_PFB1CR_B1MW_64BITS (1 << FMC_PFB1CR_B1MW_SHIFT) /* 64 bits */ + /* Bits 19-27: Reserved */ +#define FMC_PFB1CR_B1RWSC_SHIFT (28) /* Bits 28-31: Bank 1 Read Wait State Control */ +#define FMC_PFB1CR_B1RWSC_MASK (15 << FMC_PFB1CR_B0RWSC_SHIFT) + +/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */ + +#define FMC_TAGVD_VALID (1 << 0) /* Bit 0: 1-bit valid for cache entry */ + /* Bits 1-5: Reserved */ +#define FMC_TAGVD_TAG_SHIFT (6) /* Bits 6-18: 13-bit tag for cache entry */ +#define FMC_TAGVD_TAG_MASK (0x1fff << FMC_TAGVD_TAG_SHIFT) + /* Bits 19-31: Reserved */ + +/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7. + * 64-bit data in two 32-bit registers. + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_FMC_H */ diff --git a/arch/arm/src/kl/chip/kl_gpio.h b/arch/arm/src/kl/chip/kl_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..c2ea98ed25eaed4b7da75ba340865d265c2d69c9 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_gpio.h @@ -0,0 +1,162 @@ +/************************************************************************************ + * arch/arm/src/kl/chip/kl_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_CHIP_KL_GPIO_H +#define __ARCH_ARM_SRC_KL_CHIP_KL_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define KL_GPIO_NPORTS 5 + +/* Register Offsets *****************************************************************/ + +#define KL_GPIO_PDOR_OFFSET 0x0000 /* Port Data Output Register */ +#define KL_GPIO_PSOR_OFFSET 0x0004 /* Port Set Output Register */ +#define KL_GPIO_PCOR_OFFSET 0x0008 /* Port Clear Output Register */ +#define KL_GPIO_PTOR_OFFSET 0x000c /* Port Toggle Output Register */ +#define KL_GPIO_PDIR_OFFSET 0x0010 /* Port Data Input Register */ +#define KL_GPIO_PDDR_OFFSET 0x0014 /* Port Data Direction Register */ + +/* Register Addresses ***************************************************************/ + +#define KL_GPIO_PDOR(n) (KL_GPIO_BASE(n)+KL_GPIO_PDOR_OFFSET) +#define KL_GPIO_PSOR(n) (KL_GPIO_BASE(n)+KL_GPIO_PSOR_OFFSET) +#define KL_GPIO_PCOR(n) (KL_GPIO_BASE(n)+KL_GPIO_PCOR_OFFSET) +#define KL_GPIO_PTOR(n) (KL_GPIO_BASE(n)+KL_GPIO_PTOR_OFFSET) +#define KL_GPIO_PDIR(n) (KL_GPIO_BASE(n)+KL_GPIO_PDIR_OFFSET) +#define KL_GPIO_PDDR(n) (KL_GPIO_BASE(n)+KL_GPIO_PDDR_OFFSET) + +#define KL_GPIOA_PDOR (KL_GPIOA_BASE+KL_GPIO_PDOR_OFFSET) +#define KL_GPIOA_PSOR (KL_GPIOA_BASE+KL_GPIO_PSOR_OFFSET) +#define KL_GPIOA_PCOR (KL_GPIOA_BASE+KL_GPIO_PCOR_OFFSET) +#define KL_GPIOA_PTOR (KL_GPIOA_BASE+KL_GPIO_PTOR_OFFSET) +#define KL_GPIOA_PDIR (KL_GPIOA_BASE+KL_GPIO_PDIR_OFFSET) +#define KL_GPIOA_PDDR (KL_GPIOA_BASE+KL_GPIO_PDDR_OFFSET) + +#define KL_GPIOB_PDOR (KL_GPIOB_BASE+KL_GPIO_PDOR_OFFSET) +#define KL_GPIOB_PSOR (KL_GPIOB_BASE+KL_GPIO_PSOR_OFFSET) +#define KL_GPIOB_PCOR (KL_GPIOB_BASE+KL_GPIO_PCOR_OFFSET) +#define KL_GPIOB_PTOR (KL_GPIOB_BASE+KL_GPIO_PTOR_OFFSET) +#define KL_GPIOB_PDIR (KL_GPIOB_BASE+KL_GPIO_PDIR_OFFSET) +#define KL_GPIOB_PDDR (KL_GPIOB_BASE+KL_GPIO_PDDR_OFFSET) + +#define KL_GPIOC_PDOR (KL_GPIOC_BASE+KL_GPIO_PDOR_OFFSET) +#define KL_GPIOC_PSOR (KL_GPIOC_BASE+KL_GPIO_PSOR_OFFSET) +#define KL_GPIOC_PCOR (KL_GPIOC_BASE+KL_GPIO_PCOR_OFFSET) +#define KL_GPIOC_PTOR (KL_GPIOC_BASE+KL_GPIO_PTOR_OFFSET) +#define KL_GPIOC_PDIR (KL_GPIOC_BASE+KL_GPIO_PDIR_OFFSET) +#define KL_GPIOC_PDDR (KL_GPIOC_BASE+KL_GPIO_PDDR_OFFSET) + +#define KL_GPIOD_PDOR (KL_GPIOD_BASE+KL_GPIO_PDOR_OFFSET) +#define KL_GPIOD_PSOR (KL_GPIOD_BASE+KL_GPIO_PSOR_OFFSET) +#define KL_GPIOD_PCOR (KL_GPIOD_BASE+KL_GPIO_PCOR_OFFSET) +#define KL_GPIOD_PTOR (KL_GPIOD_BASE+KL_GPIO_PTOR_OFFSET) +#define KL_GPIOD_PDIR (KL_GPIOD_BASE+KL_GPIO_PDIR_OFFSET) +#define KL_GPIOD_PDDR (KL_GPIOD_BASE+KL_GPIO_PDDR_OFFSET) + +#define KL_GPIOE_PDOR (KL_GPIOE_BASE+KL_GPIO_PDOR_OFFSET) +#define KL_GPIOE_PSOR (KL_GPIOE_BASE+KL_GPIO_PSOR_OFFSET) +#define KL_GPIOE_PCOR (KL_GPIOE_BASE+KL_GPIO_PCOR_OFFSET) +#define KL_GPIOE_PTOR (KL_GPIOE_BASE+KL_GPIO_PTOR_OFFSET) +#define KL_GPIOE_PDIR (KL_GPIOE_BASE+KL_GPIO_PDIR_OFFSET) +#define KL_GPIOE_PDDR (KL_GPIOE_BASE+KL_GPIO_PDDR_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Port Data Output Register */ + +#define GPIO_PDOR(n) (1 << (n)) + +/* Port Set Output Register */ + +#define GPIO_PSOR(n) (1 << (n)) + +/* Port Clear Output Register */ + +#define GPIO_PCOR(n) (1 << (n)) + +/* Port Toggle Output Register */ + +#define GPIO_PTOR(n) (1 << (n)) + +/* Port Data Input Register */ + +#define GPIO_PDIR(n) (1 << (n)) + +/* Port Data Direction Register */ + +#define GPIO_PDDR(n) (1 << (n)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_CHIP_KL_GPIO_H */ diff --git a/arch/arm/src/kl/chip/kl_i2c.h b/arch/arm/src/kl/chip/kl_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..a2c1941ddabbf78221efe9d6c04ab0da6e9f1f72 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_i2c.h @@ -0,0 +1,188 @@ +/******************************************************************************************** + * arch/arm/src/kl/chip/kl_i2c.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_CHIP_KL_I2C_H +#define __ARCH_ARM_SRC_KL_CHIP_KL_I2C_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KL_I2C_A1_OFFSET 0x0000 /* I2C Address Register 1 */ +#define KL_I2C_F_OFFSET 0x0001 /* I2C Frequency Divider register */ +#define KL_I2C_C1_OFFSET 0x0002 /* I2C Control Register 1 */ +#define KL_I2C_S_OFFSET 0x0003 /* I2C Status Register */ +#define KL_I2C_D_OFFSET 0x0004 /* I2C Data I/O register */ +#define KL_I2C_C2_OFFSET 0x0005 /* I2C Control Register 2 */ +#define KL_I2C_FLT_OFFSET 0x0006 /* I2C Programmable Input Glitch Filter register */ +#define KL_I2C_RA_OFFSET 0x0007 /* I2C Range Address register */ +#define KL_I2C_SMB_OFFSET 0x0008 /* I2C SMBus Control and Status register */ +#define KL_I2C_A2_OFFSET 0x0009 /* I2C Address Register 2 */ +#define KL_I2C_SLTH_OFFSET 0x000a /* I2C SCL Low Timeout Register High */ +#define KL_I2C_SLTL_OFFSET 0x000b /* I2C SCL Low Timeout Register Low */ + +/* Register Addresses ***********************************************************************/ + +#define KL_I2C0_A1 (KL_I2C0_BASE+KL_I2C_A1_OFFSET) +#define KL_I2C0_F (KL_I2C0_BASE+KL_I2C_F_OFFSET) +#define KL_I2C0_C1 (KL_I2C0_BASE+KL_I2C_C1_OFFSET) +#define KL_I2C0_S (KL_I2C0_BASE+KL_I2C_S_OFFSET) +#define KL_I2C0_D (KL_I2C0_BASE+KL_I2C_D_OFFSET) +#define KL_I2C0_C2 (KL_I2C0_BASE+KL_I2C_C2_OFFSET) +#define KL_I2C0_FLT (KL_I2C0_BASE+KL_I2C_FLT_OFFSET) +#define KL_I2C0_RA (KL_I2C0_BASE+KL_I2C_RA_OFFSET) +#define KL_I2C0_SMB (KL_I2C0_BASE+KL_I2C_SMB_OFFSET) +#define KL_I2C0_A2 (KL_I2C0_BASE+KL_I2C_A2_OFFSET) +#define KL_I2C0_SLTH (KL_I2C0_BASE+KL_I2C_SLTH_OFFSET) +#define KL_I2C0_SLTL (KL_I2C0_BASE+KL_I2C_SLTL_OFFSET) + +#define KL_I2C1_A1 (KL_I2C1_BASE+KL_I2C_A1_OFFSET) +#define KL_I2C1_F (KL_I2C1_BASE+KL_I2C_F_OFFSET) +#define KL_I2C1_C1 (KL_I2C1_BASE+KL_I2C_C1_OFFSET) +#define KL_I2C1_S (KL_I2C1_BASE+KL_I2C_S_OFFSET) +#define KL_I2C1_D (KL_I2C1_BASE+KL_I2C_D_OFFSET) +#define KL_I2C1_C2 (KL_I2C1_BASE+KL_I2C_C2_OFFSET) +#define KL_I2C1_FLT (KL_I2C1_BASE+KL_I2C_FLT_OFFSET) +#define KL_I2C1_RA (KL_I2C1_BASE+KL_I2C_RA_OFFSET) +#define KL_I2C1_SMB (KL_I2C1_BASE+KL_I2C_SMB_OFFSET) +#define KL_I2C1_A2 (KL_I2C1_BASE+KL_I2C_A2_OFFSET) +#define KL_I2C1_SLTH (KL_I2C1_BASE+KL_I2C_SLTH_OFFSET) +#define KL_I2C1_SLTL (KL_I2C1_BASE+KL_I2C_SLTL_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* I2C Address Register 1 (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_A1_SHIFT (1) /* Bits 1-7: Address */ +#define I2C_A1_MASK (0x7f << I2C_A1_SHIFT) + +/* I2C Frequency Divider register (8-bit) */ + +#define I2C_F_ICR_SHIFT (0) /* Bits 0-5: Clock rate */ +#define I2C_F_ICR_MASK (0x3f << I2C_F_ICR_SHIFT) +#define I2C_F_MULT_SHIFT (6) /* Bits 6-7: Multiplier factor */ +#define I2C_F_MULT_MASK (3 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_1 (0 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_2 (1 << I2C_F_MULT_SHIFT) +# define I2C_F_MULT_4 (2 << I2C_F_MULT_SHIFT) + +/* I2C Control Register 1 (8-bit) */ + +#define I2C_C1_DMAEN (1 << 0) /* Bit 0: DMA enable */ +#define I2C_C1_WUEN (1 << 1) /* Bit 1: Wakeup enable */ +#define I2C_C1_RSTA (1 << 2) /* Bit 2: Repeat START */ +#define I2C_C1_TXAK (1 << 3) /* Bit 3: Transmit acknowledge enable */ +#define I2C_C1_TX (1 << 4) /* Bit 4: Transmit mode select */ +#define I2C_C1_MST (1 << 5) /* Bit 5: Master mode select */ +#define I2C_C1_IICIE (1 << 6) /* Bit 6: I2C interrupt enable */ +#define I2C_C1_IICEN (1 << 7) /* Bit 7: I2C enable */ + +/* I2C Status Register (8-bit) */ + +#define I2C_S_RXAK (1 << 0) /* Bit 0: Receive acknowledge */ +#define I2C_S_IICIF (1 << 1) /* Bit 1: Interrupt flag */ +#define I2C_S_SRW (1 << 2) /* Bit 2: Slave read/write */ +#define I2C_S_RAM (1 << 3) /* Bit 3: Range address match */ +#define I2C_S_ARBL (1 << 4) /* Bit 4: Arbitration lost */ +#define I2C_S_BUSY (1 << 5) /* Bit 5: Bus busy */ +#define I2C_S_IAAS (1 << 6) /* Bit 6: Addressed as a slave */ +#define I2C_S_TCF (1 << 7) /* Bit 7: Transfer complete flag */ + +/* I2C Data I/O register (8-bit data register) */ + +/* I2C Control Register 2 (8-bit) */ + +#define I2C_C2_AD_SHIFT (0) /* Bits 0-2: Slave address */ +#define I2C_C2_AD_MASK (7 << I2C_C2_AD_SHIFT) +#define I2C_C2_RMEN (1 << 3) /* Bit 3: Range address matching enable */ +#define I2C_C2_SBRC (1 << 4) /* Bit 4: Slave baud rate control */ +#define I2C_C2_HDRS (1 << 5) /* Bit 5: High drive select */ +#define I2C_C2_ADEXT (1 << 6) /* Bit 6: Address extension */ +#define I2C_C2_GCAEN (1 << 7) /* Bit 7: General call address enable */ + +/* I2C Programmable Input Glitch Filter register (8-bit) */ + /* Bits 5-7: Reserved */ +#define I2C_FLT_SHIFT (0) /* Bits 0-4: I2C programmable filter factor */ +#define I2C_FLT_MASK (0x1f << I2C_FLT_SHIFT) +#define I2C_FLT_STOPIE (1 << 5) /* Bit 5: Stop interrupt enable */ +#define I2C_FLT_STOPF (1 << 6) /* Bit 6: Stop detect flag */ +#define I2C_FLT_SHEN (1 << 7) /* Bit 7: Stop hold enable */ + +/* I2C Range Address register (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_RA_SHIFT (1) /* Bits 1-7: Range slave address */ +#define I2C_RA_MASK (0x7f << I2C_RA_SHIFT) + +/* I2C SMBus Control and Status register (8-bit) */ + +#define I2C_SMB_SHTF2IE (1 << 0) /* Bit 0: SHTF2 interrupt enable */ +#define I2C_SMB_SHTF2 (1 << 1) /* Bit 1: SCL high timeout flag 2 */ +#define I2C_SMB_SHTF1 (1 << 2) /* Bit 2: SCL high timeout flag 1 */ +#define I2C_SMB_SLTF (1 << 3) /* Bit 3: SCL low timeout flag */ +#define I2C_SMB_TCKSEL (1 << 4) /* Bit 4: Timeout counter clock select */ +#define I2C_SMB_SIICAEN (1 << 5) /* Bit 5: Second I2C address enable */ +#define I2C_SMB_ALERTEN (1 << 6) /* Bit 6: SMBus alert response address enable */ +#define I2C_SMB_FACK (1 << 7) /* Bit 7: Fast NACK/ACK enable */ + +/* I2C Address Register 2 (8-bit) */ + /* Bit 0: Reserved */ +#define I2C_A2_SAD_SHIFT (1) /* Bits 1-7: SMBus address */ +#define I2C_A2_SAD_MASK (0x7f << I2C_A2_SHIFT) + +/* I2C SCL Low Timeout Register High/Low (16-bit data in two 8-bit registers) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_CHIP_KL_I2C_H */ diff --git a/arch/arm/src/kl/chip/kl_llwu.h b/arch/arm/src/kl/chip/kl_llwu.h new file mode 100644 index 0000000000000000000000000000000000000000..d843689639ce291b222b54737ba918cdc8ddcc4d --- /dev/null +++ b/arch/arm/src/kl/chip/kl_llwu.h @@ -0,0 +1,252 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_llwu.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_LLWU_H +#define __ARCH_ARM_SRC_KL_KL_LLWU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KL_LLWU_PE1_OFFSET 0x0000 /* LLWU Pin Enable 1 Register */ +#define KL_LLWU_PE2_OFFSET 0x0001 /* LLWU Pin Enable 2 Register */ +#define KL_LLWU_PE3_OFFSET 0x0002 /* LLWU Pin Enable 3 Register */ +#define KL_LLWU_PE4_OFFSET 0x0003 /* LLWU Pin Enable 4 Register */ +#define KL_LLWU_ME_OFFSET 0x0004 /* LLWU Module Enable Register */ +#define KL_LLWU_F1_OFFSET 0x0005 /* LLWU Flag 1 Register */ +#define KL_LLWU_F2_OFFSET 0x0006 /* LLWU Flag 2 Register */ +#define KL_LLWU_F3_OFFSET 0x0007 /* LLWU Flag 3 Register */ +#define KL_LLWU_CS_OFFSET 0x0008 /* LLWU Control and Status Register */ + +/* Register Addresses ***************************************************************/ + +#define KL_LLWU_PE1 (KL_LLWU_BASE+KL_LLWU_PE1_OFFSET) +#define KL_LLWU_PE2 (KL_LLWU_BASE+KL_LLWU_PE2_OFFSET) +#define KL_LLWU_PE3 (KL_LLWU_BASE+KL_LLWU_PE3_OFFSET) +#define KL_LLWU_PE4 (KL_LLWU_BASE+KL_LLWU_PE4_OFFSET) +#define KL_LLWU_ME (KL_LLWU_BASE+KL_LLWU_ME_OFFSET) +#define KL_LLWU_F1 (KL_LLWU_BASE+KL_LLWU_F1_OFFSET) +#define KL_LLWU_F2 (KL_LLWU_BASE+KL_LLWU_F2_OFFSET) +#define KL_LLWU_F3 (KL_LLWU_BASE+KL_LLWU_F3_OFFSET) +#define KL_LLWU_CS (KL_LLWU_BASE+KL_LLWU_CS_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* LLWU Pin Enable 1 Register */ + +#define LLWU_PE1_WUPE0_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P0 */ +#define LLWU_PE1_WUPE0_MASK (3 << LLWU_PE1_WUPE0_SHIFT) +# define LLWU_PE1_WUPE0_DISABLED (0 << LLWU_PE1_WUPE0_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE0_RISING (1 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE0_FALLING (2 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE0_BOTH (3 << LLWU_PE1_WUPE0_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE1_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P1 */ +#define LLWU_PE1_WUPE1_MASK (3 << LLWU_PE1_WUPE1_SHIFT) +# define LLWU_PE1_WUPE1_DISABLED (0 << LLWU_PE1_WUPE1_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE1_RISING (1 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE1_FALLING (2 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE1_BOTH (3 << LLWU_PE1_WUPE1_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE2_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P2 */ +#define LLWU_PE1_WUPE2_MASK (3 << LLWU_PE1_WUPE2_SHIFT) +# define LLWU_PE1_WUPE2_DISABLED (0 << LLWU_PE1_WUPE2_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE2_RISING (1 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE2_FALLING (2 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE2_BOTH (3 << LLWU_PE1_WUPE2_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE1_WUPE3_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P3 */ +#define LLWU_PE1_WUPE3_MASK (3 << LLWU_PE1_WUPE3_SHIFT) +# define LLWU_PE1_WUPE3_DISABLED (0 << LLWU_PE1_WUPE3_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE1_WUPE3_RISING (1 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE1_WUPE3_FALLING (2 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE1_WUPE3_BOTH (3 << LLWU_PE1_WUPE3_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 2 Register */ + +#define LLWU_PE2_WUPE4_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P4 */ +#define LLWU_PE2_WUPE4_MASK (3 << LLWU_PE2_WUPE4_SHIFT) +# define LLWU_PE2_WUPE4_DISABLED (0 << LLWU_PE2_WUPE4_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE4_RISING (1 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE4_FALLING (2 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE4_BOTH (3 << LLWU_PE2_WUPE4_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE5_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P5 */ +#define LLWU_PE2_WUPE5_MASK (3 << LLWU_PE2_WUPE5_SHIFT) +# define LLWU_PE2_WUPE5_DISABLED (0 << LLWU_PE2_WUPE5_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE5_RISING (1 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE5_FALLING (2 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE5_BOTH (3 << LLWU_PE2_WUPE5_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE6_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P6 */ +#define LLWU_PE2_WUPE6_MASK (3 << LLWU_PE2_WUPE6_SHIFT) +# define LLWU_PE2_WUPE6_DISABLED (0 << LLWU_PE2_WUPE6_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE6_RISING (1 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE6_FALLING (2 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE6_BOTH (3 << LLWU_PE2_WUPE6_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE2_WUPE7_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P7 */ +#define LLWU_PE2_WUPE7_MASK (3 << LLWU_PE2_WUPE7_SHIFT) +# define LLWU_PE2_WUPE7_DISABLED (0 << LLWU_PE2_WUPE7_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE2_WUPE7_RISING (1 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE2_WUPE7_FALLING (2 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE2_WUPE7_BOTH (3 << LLWU_PE2_WUPE7_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 3 Register */ + +#define LLWU_PE3_WUPE8_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P8 */ +#define LLWU_PE3_WUPE8_MASK (3 << LLWU_PE3_WUPE8_SHIFT) +# define LLWU_PE3_WUPE8_DISABLED (0 << LLWU_PE3_WUPE8_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE8_RISING (1 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE8_FALLING (2 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE8_BOTH (3 << LLWU_PE3_WUPE8_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE9_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P9 */ +#define LLWU_PE3_WUPE9_MASK (3 << LLWU_PE3_WUPE9_SHIFT) +# define LLWU_PE3_WUPE9_DISABLED (0 << LLWU_PE3_WUPE9_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE9_RISING (1 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE9_FALLING (2 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE9_BOTH (3 << LLWU_PE3_WUPE9_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE10_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P10 */ +#define LLWU_PE3_WUPE10_MASK (3 << LLWU_PE3_WUPE10_SHIFT) +# define LLWU_PE3_WUPE10_DISABLED (0 << LLWU_PE3_WUPE10_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE10_RISING (1 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE10_FALLING (2 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE10_BOTH (3 << LLWU_PE3_WUPE10_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE3_WUPE11_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P11 */ +#define LLWU_PE3_WUPE11_MASK (3 << LLWU_PE3_WUPE11_SHIFT) +# define LLWU_PE3_WUPE11_DISABLED (0 << LLWU_PE3_WUPE11_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE3_WUPE11_RISING (1 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE3_WUPE11_FALLING (2 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE3_WUPE11_BOTH (3 << LLWU_PE3_WUPE11_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Pin Enable 4 Register */ + +#define LLWU_PE4_WUPE12_SHIFT (0) /* Bits 0-1: Wakeup Pin Enable for LLWU_P12 */ +#define LLWU_PE4_WUPE12_MASK (3 << LLWU_PE4_WUPE12_SHIFT) +# define LLWU_PE4_WUPE12_DISABLED (0 << LLWU_PE4_WUPE12_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE12_RISING (1 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE12_FALLING (2 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE12_BOTH (3 << LLWU_PE4_WUPE12_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE13_SHIFT (2) /* Bits 2-3: Wakeup Pin Enable for LLWU_P13 */ +#define LLWU_PE4_WUPE13_MASK (3 << LLWU_PE4_WUPE13_SHIFT) +# define LLWU_PE4_WUPE13_DISABLED (0 << LLWU_PE4_WUPE13_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE13_RISING (1 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE13_FALLING (2 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE13_BOTH (3 << LLWU_PE4_WUPE13_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE14_SHIFT (4) /* Bits 4-5: Wakeup Pin Enable for LLWU_P14 */ +#define LLWU_PE4_WUPE14_MASK (3 << LLWU_PE4_WUPE14_SHIFT) +# define LLWU_PE4_WUPE14_DISABLED (0 << LLWU_PE4_WUPE14_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE14_RISING (1 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE14_FALLING (2 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE14_BOTH (3 << LLWU_PE4_WUPE14_SHIFT) /* Ext input enabled for any change */ +#define LLWU_PE4_WUPE15_SHIFT (6) /* Bits 6-7: Wakeup Pin Enable for LLWU_P15 */ +#define LLWU_PE4_WUPE15_MASK (3 << LLWU_PE4_WUPE15_SHIFT) +# define LLWU_PE4_WUPE15_DISABLED (0 << LLWU_PE4_WUPE15_SHIFT) /* Ext input disabled as wakeup input */ +# define LLWU_PE4_WUPE15_RISING (1 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for rising edge */ +# define LLWU_PE4_WUPE15_FALLING (2 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for falling edge */ +# define LLWU_PE4_WUPE15_BOTH (3 << LLWU_PE4_WUPE15_SHIFT) /* Ext input enabled for any change */ + +/* LLWU Module Enable Register */ + +#define LLWU_ME_WUME(n) (1 << (n)) +#define LLWU_ME_WUME0 (1 << 0) /* Bit 0: Wakeup Module Enable for Module 0 */ +#define LLWU_ME_WUME1 (1 << 1) /* Bit 1: Wakeup Module Enable for Module 1 */ +#define LLWU_ME_WUME2 (1 << 2) /* Bit 2: Wakeup Module Enable for Module 2 */ +#define LLWU_ME_WUME3 (1 << 3) /* Bit 3: Wakeup Module Enable for Module 3 */ +#define LLWU_ME_WUME4 (1 << 4) /* Bit 4: Wakeup Module Enable for Module 4 */ +#define LLWU_ME_WUME5 (1 << 5) /* Bit 5: Wakeup Module Enable for Module 5 */ +#define LLWU_ME_WUME6 (1 << 6) /* Bit 6: Wakeup Module Enable for Module 6 */ +#define LLWU_ME_WUME7 (1 << 7) /* Bit 7: Wakeup Module Enable for Module 7 */ + +/* LLWU Flag 1 Register */ + +#define LLWU_F1_WUF(n) (1 << (n)) +#define LLWU_F1_WUF0 (1 << 0) /* Bit 0: Wakeup Flag for LLWU_P0 */ +#define LLWU_F1_WUF1 (1 << 1) /* Bit 1: Wakeup Flag for LLWU_P1 */ +#define LLWU_F1_WUF2 (1 << 2) /* Bit 2: Wakeup Flag for LLWU_P2 */ +#define LLWU_F1_WUF3 (1 << 3) /* Bit 3: Wakeup Flag for LLWU_P3 */ +#define LLWU_F1_WUF4 (1 << 4) /* Bit 4: Wakeup Flag for LLWU_P4 */ +#define LLWU_F1_WUF5 (1 << 5) /* Bit 5: Wakeup Flag for LLWU_P5 */ +#define LLWU_F1_WUF6 (1 << 6) /* Bit 6: Wakeup Flag for LLWU_P6 */ +#define LLWU_F1_WUF7 (1 << 7) /* Bit 7: Wakeup Flag for LLWU_P7 */ + +/* LLWU Flag 2 Register */ + +#define LLWU_F2_WUF(n) (1 << ((n)-8)) +#define LLWU_F2_WUF8 (1 << 8) /* Bit 0: Wakeup Flag for LLWU_P8 */ +#define LLWU_F2_WUF9 (1 << 9) /* Bit 1: Wakeup Flag for LLWU_P9 */ +#define LLWU_F2_WUF10 (1 << 10) /* Bit 2: Wakeup Flag for LLWU_P10 */ +#define LLWU_F2_WUF11 (1 << 11) /* Bit 3: Wakeup Flag for LLWU_P11 */ +#define LLWU_F2_WUF12 (1 << 12) /* Bit 4: Wakeup Flag for LLWU_P12 */ +#define LLWU_F2_WUF13 (1 << 13) /* Bit 5: Wakeup Flag for LLWU_P13 */ +#define LLWU_F2_WUF14 (1 << 14) /* Bit 6: Wakeup Flag for LLWU_P14 */ +#define LLWU_F2_WUF15 (1 << 15) /* Bit 7: Wakeup Flag for LLWU_P15 */ + +/* LLWU Flag 3 Register */ + +#define LLWU_F3_MWUF(n) (1 << (n)) +#define LLWU_F3_MWUF0 (1 << 0) /* Bit 0: Wakeup flag for module 0 */ +#define LLWU_F3_MWUF1 (1 << 1) /* Bit 1: Wakeup flag for module 1 */ +#define LLWU_F3_MWUF2 (1 << 2) /* Bit 2: Wakeup flag for module 2 */ +#define LLWU_F3_MWUF3 (1 << 3) /* Bit 3: Wakeup flag for module 3 */ +#define LLWU_F3_MWUF4 (1 << 4) /* Bit 4: Wakeup flag for module 4 */ +#define LLWU_F3_MWUF5 (1 << 5) /* Bit 5: Wakeup flag for module 5 */ +#define LLWU_F3_MWUF6 (1 << 6) /* Bit 6: Wakeup flag for module 6 */ +#define LLWU_F3_MWUF7 (1 << 7) /* Bit 7: Wakeup flag for module 7 */ + +/* LLWU Control and Status Register */ + +#define LLWU_CS_ACKISO (1 << 7) /* Bit 7: Acknowledge Isolation */ + /* Bits 2-6: Reserved */ +#define LLWU_CS_FLTEP (1 << 1) /* Bit 1: Digital Filter on External Pin */ +#define LLWU_CS_FLTR (1 << 0) /* Bit 0: Digital Filter on RESET Pin */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_LLWU_H */ diff --git a/arch/arm/src/kl/chip/kl_mcg.h b/arch/arm/src/kl/chip/kl_mcg.h new file mode 100644 index 0000000000000000000000000000000000000000..4e6f2d9dfeaf9188b5d33b43517b4dce3e7dbbb6 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_mcg.h @@ -0,0 +1,186 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_mcg.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_MCG_H +#define __ARCH_ARM_SRC_KL_KL_MCG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KL_MCG_C1_OFFSET 0x0000 /* MCG Control 1 Register */ +#define KL_MCG_C2_OFFSET 0x0001 /* MCG Control 2 Register */ +#define KL_MCG_C3_OFFSET 0x0002 /* MCG Control 3 Register */ +#define KL_MCG_C4_OFFSET 0x0003 /* MCG Control 4 Register */ +#define KL_MCG_C5_OFFSET 0x0004 /* MCG Control 5 Register */ +#define KL_MCG_C6_OFFSET 0x0005 /* MCG Control 6 Register */ +#define KL_MCG_S_OFFSET 0x0006 /* MCG Status Register */ +#define KL_MCG_ATC_OFFSET 0x0008 /* MCG Auto Trim Control Register */ +#define KL_MCG_ATCVH_OFFSET 0x000a /* MCG Auto Trim Compare Value High Register */ +#define KL_MCG_ATCVL_OFFSET 0x000b /* MCG Auto Trim Compare Value Low Register */ + +/* Register Addresses ***************************************************************/ + +#define KL_MCG_C1 (KL_MCG_BASE+KL_MCG_C1_OFFSET) +#define KL_MCG_C2 (KL_MCG_BASE+KL_MCG_C2_OFFSET) +#define KL_MCG_C3 (KL_MCG_BASE+KL_MCG_C3_OFFSET) +#define KL_MCG_C4 (KL_MCG_BASE+KL_MCG_C4_OFFSET) +#define KL_MCG_C5 (KL_MCG_BASE+KL_MCG_C5_OFFSET) +#define KL_MCG_C6 (KL_MCG_BASE+KL_MCG_C6_OFFSET) +#define KL_MCG_S (KL_MCG_BASE+KL_MCG_S_OFFSET) +#define KL_MCG_ATC (KL_MCG_BASE+KL_MCG_ATC_OFFSET) +#define KL_MCG_ATCVH (KL_MCG_BASE+KL_MCG_ATCVH_OFFSET) +#define KL_MCG_ATCVL (KL_MCG_BASE+KL_MCG_ATCVL_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* MCG Control 1 Register (8-bit) */ + +#define MCG_C1_IREFSTEN (1 << 0) /* Bit 0: Internal Reference Stop Enable */ +#define MCG_C1_IRCLKEN (1 << 1) /* Bit 1: Internal Reference Clock Enable */ +#define MCG_C1_IREFS (1 << 2) /* Bit 2: Internal Reference Select */ +#define MCG_C1_FRDIV_SHIFT (3) /* Bits 3-5: FLL External Reference Divider */ +#define MCG_C1_FRDIV_MASK (7 << MCG_C1_FRDIV_SHIFT) +# define MCG_C1_FRDIV_R0DIV1 (0 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=1 */ +# define MCG_C1_FRDIV_R0DIV2 (1 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=2 */ +# define MCG_C1_FRDIV_R0DIV4 (2 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=4 */ +# define MCG_C1_FRDIV_R0DIV8 (3 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=8 */ +# define MCG_C1_FRDIV_R0DIV16 (4 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=16 */ +# define MCG_C1_FRDIV_R0DIV32 (5 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=32 */ +# define MCG_C1_FRDIV_R0DIV64 (6 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=64 */ +# define MCG_C1_FRDIV_R0DIV128 (7 << MCG_C1_FRDIV_SHIFT) /* RANGE==0 divider=128 */ +# define MCG_C1_FRDIV_DIV32 (0 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=32 */ +# define MCG_C1_FRDIV_DIV64 (1 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=64 */ +# define MCG_C1_FRDIV_DIV128 (2 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=128 */ +# define MCG_C1_FRDIV_DIV256 (3 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=256 */ +# define MCG_C1_FRDIV_DIV512 (4 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=512 */ +# define MCG_C1_FRDIV_DIV1024 (5 << MCG_C1_FRDIV_SHIFT) /* RANGE!=0 divider=1024 */ +#define MCG_C1_CLKS_SHIFT (6) /* Bits 6-7: Clock Source Select */ +#define MCG_C1_CLKS_MASK (3 << MCG_C1_CLKS_SHIFT) +# define MCG_C1_CLKS_PLL (0 << MCG_C1_CLKS_SHIFT) /* FLL or PLL output */ +# define MCG_C1_CLKS_INTREF (1 << MCG_C1_CLKS_SHIFT) /* Internal reference clock */ +# define MCG_C1_CLKS_EXTREF (2 << MCG_C1_CLKS_SHIFT) /* External reference clock */ + +/* MCG Control 2 Register */ + +#define MCG_C2_IRCS (1 << 0) /* Bit 0: Internal Reference Clock Select */ +#define MCG_C2_LP (1 << 1) /* Bit 1: Low Power Select */ +#define MCG_C2_EREFS (1 << 2) /* Bit 2: External Reference Select */ +#define MCG_C2_HGO (1 << 3) /* Bit 3: High Gain Oscillator Select */ +#define MCG_C2_RANGE_SHIFT (4) /* Bits 4-5: Frequency Range Select */ +#define MCG_C2_RANGE_MASK (3 << MCG_C2_RANGE_SHIFT) +# define MCG_C2_RANGE_LOW (0 << MCG_C2_RANGE_SHIFT) /* Oscillator of 32 kHz to 40 kHz */ +# define MCG_C2_RANGE_HIGH (1 << MCG_C2_RANGE_SHIFT) /* Oscillator of 1 MHz to 8 MHz */ +# define MCG_C2_RANGE_VHIGH (2 << MCG_C2_RANGE_SHIFT) /* Oscillator of 8 MHz to 32 MHz */ + /* Bits 6-7: Reserved */ +/* MCG Control 3 Register (8-bit Slow Internal Reference Clock Trim Setting) */ + +/* MCG Control 4 Register (8-bit) */ + +#define MCG_C4_SCFTRIM (1 << 0) /* Bit 0: Slow Internal Reference Clock Fine Trim */ +#define MCG_C4_FCTRIM_SHIFT (1) /* Bits 1-4: Fast Internal Reference Clock Trim Setting */ +#define MCG_C4_FCTRIM_MASK (15 << MCG_C4_FCTRIM_SHIFT) +#define MCG_C4_DRST_DRS_SHIFT (5) /* Bits 5-6: DCO Range Select */ +#define MCG_C4_DRST_DRS_MASK (3 << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_LOW (0 << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_MID (1 << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_MIDHIGH (2 << MCG_C4_DRST_DRS_SHIFT) +# define MCG_C4_DRST_DRS_HIGH (3 << MCG_C4_DRST_DRS_SHIFT) +#define MCG_C4_DMX32 (1 << 7) /* Bit 7: DCO Maximum Frequency with 32.768 kHz Reference */ + +/* MCG Control 5 Register */ + +#define MCG_C5_PRDIV_SHIFT (0) /* Bits 0-4: PLL External Reference Divider */ +#define MCG_C5_PRDIV_MASK (31 << MCG_C5_PRDIV_SHIFT) +# define MCG_C5_PRDIV(n) (((n)-1) << MCG_C5_PRDIV_SHIFT) /* Divide factor n=1..25 */ +#define MCG_C5_PLLSTEN (1 << 5) /* Bit 5: PLL Stop Enable */ +#define MCG_C5_PLLCLKEN (1 << 6) /* Bit 6: PLL Clock Enable */ + /* Bit 7: Reserved */ + +/* MCG Control 6 Register */ + +#define MCG_C6_VDIV_SHIFT (0) /* Bits 0-4: VCO Divider */ +#define MCG_C6_VDIV_MASK (31 << MCG_C6_VDIV_SHIFT) +# define MCG_C6_VDIV(n) (((n)-24) << MCG_C6_VDIV_SHIFT) /* Divide factor n=24..55 */ +#define MCG_C6_CME (1 << 5) /* Bit 5: Clock Monitor Enable */ +#define MCG_C6_PLLS (1 << 6) /* Bit 6: PLL Select */ +#define MCG_C6_LOLIE (1 << 7) /* Bit 7: Loss of Lock Interrrupt Enable */ + +/* MCG Status Register */ + +#define MCG_S_IRCST (1 << 0) /* Bit 0: Internal Reference Clock Status */ +#define MCG_S_OSCINIT (1 << 1) /* Bit 1: OSC Initialization */ +#define MCG_S_CLKST_SHIFT (2) /* Bits 2-3: Clock Mode Status */ +#define MCG_S_CLKST_MASK (3 << MCG_S_CLKST_SHIFT) +# define MCG_S_CLKST_FLL (0 << MCG_S_CLKST_SHIFT) /* Output of the FLL */ +# define MCG_S_CLKST_INTREF (1 << MCG_S_CLKST_SHIFT) /* Internal reference clock */ +# define MCG_S_CLKST_EXTREF (2 << MCG_S_CLKST_SHIFT) /* External reference clock */ +# define MCG_S_CLKST_PLL (3 << MCG_S_CLKST_SHIFT) /* Output of the PLL */ +#define MCG_S_IREFST (1 << 4) /* Bit 4: Internal Reference Status */ +#define MCG_S_PLLST (1 << 5) /* Bit 5: PLL Select Status */ +#define MCG_S_LOCK (1 << 6) /* Bit 6: Lock Status */ +#define MCG_S_LOLS (1 << 7) /* Bit 7: Loss of Lock Status */ + +/* MCG Auto Trim Control Register */ + /* Bits 0-4: Reserved */ +#define MCG_ATC_ATMF (1 << 5) /* Bit 5: Automatic Trim machine Fail Flag */ +#define MCG_ATC_ATMS (1 << 6) /* Bit 6: Automatic Trim Machine Select */ +#define MCG_ATC_ATME (1 << 7) /* Bit 7: Automatic Trim Machine Enable */ + +/* MCG Auto Trim Compare Value High/Low Registers (8-bit compare value) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_MCG_H */ diff --git a/arch/arm/src/kl/chip/kl_memorymap.h b/arch/arm/src/kl/chip/kl_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..c89f70f7308e500131e9205bb2e61a4c479e770d --- /dev/null +++ b/arch/arm/src/kl/chip/kl_memorymap.h @@ -0,0 +1,140 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_MEMORYMAP_H +#define __ARCH_ARM_SRC_KL_KL_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ +/* K40 Family + * + * The memory map for the following parts is defined in Freescale document + * K40P144M100SF2RM + */ + +# define KL_FLASH_BASE 0x00000000 /* -0x0fffffff Program flash and read- + * only data (Includes exception + * vectors in first 1024 bytes) */ +# define KL_SRAML_BASE 0x18000000 /* -0x1fffffff SRAM_L: Lower SRAM + * (ICODE/DCODE) */ +# define KL_SRAMU_BASE 0x20000000 /* -0x200fffff SRAM_U: Upper SRAM bitband + * region */ + /* 0x20100000 * -0x3fffffff Reserved */ +# define KIP_AIPS_BASE 0x40000000 /* -0x4007ffff AIPS Peripherals */ + /* 0x40080000 * -0x400fffff Reserved */ +# define KL_GPIO_BASE(n) (0x400ff000 + ((n) << 6)) + /* 0x40100000 * -0x43ffffff Reserved */ +# define KL_BME_BASE 0x44000000 /* -0x5fffffff Bit Manipulation Engine (BME) access + * to AIPS Peripherals for slots 0-127 */ + /* 0x60000000 * -0xdfffffff Reserved */ +# define KL_PERIPH_BASE 0xe0000000 /* -0xe00fffff Private peripherals */ + /* 0xe0100000 * -0xefffffff Reserved */ +# define KL_MTB_BASE 0xf0000000 /* -0xffffffff Micro Trace Buffer (MTB) registers */ + +/* AIPS Memory Map ******************************************************************/ + +# define KL_DMAC_BASE 0x40008000 /* DMA controller */ +# define KL_AIPSGPIO_BASE 0x4000f000 /* GPIO controller (aliased to 0x400ff000) */ +# define KL_FTFL_BASE 0x40020000 /* Flash memory */ +# define KL_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */ +# define KL_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */ +# define KL_TPM0_BASE 0x40038000 /* Timer/PWM (TPM) 0 */ +# define KL_TPM1_BASE 0x40039000 /* Timer/PWM (TPM) 1 */ +# define KL_TPM2_BASE 0x4003a000 /* Timer/PWM (TPM) 2 */ +# define KL_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */ +# define KL_RTC_BASE 0x4003d000 /* Real time clock */ +# define KL_DAC0_BASE 0x4003f000 /* Digital-to-analog convert (DAC) 0 */ +# define KL_LPTMR_BASE 0x40040000 /* Low power timer */ +# define KL_TSI_BASE 0x40045000 /* Touch sense interface */ +# define KL_SIMLP_BASE 0x40047000 /* SIM low-power logic */ +# define KL_SIM_BASE 0x40048000 /* System integration module (SIM) */ +# define KL_PORT_BASE(n) (0x40049000 + ((n) << 12)) +# define KL_PORTA_BASE 0x40049000 /* Port A multiplexing control */ +# define KL_PORTB_BASE 0x4004a000 /* Port B multiplexing control */ +# define KL_PORTC_BASE 0x4004b000 /* Port C multiplexing control */ +# define KL_PORTD_BASE 0x4004c000 /* Port D multiplexing control */ +# define KL_PORTE_BASE 0x4004d000 /* Port E multiplexing control */ +# define KL_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */ +# define KL_OSC_BASE 0x40065000 /* System oscillator (OSC) */ +# define KL_I2C0_BASE 0x40066000 /* I2C 0 */ +# define KL_I2C1_BASE 0x40067000 /* I2C 1 */ +# define KL_UART0_BASE 0x4006a000 /* UART0 */ +# define KL_UART1_BASE 0x4006b000 /* UART1 */ +# define KL_UART2_BASE 0x4006c000 /* UART2 */ +# define KL_USB0_BASE 0x40072000 /* USB OTG FS/LS */ +# define KL_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */ +# define KL_SPI0_BASE 0x40076000 /* SPI 0 */ +# define KL_SPI1_BASE 0x40077000 /* SPI 1 */ +# define KL_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */ +# define KL_PMC_BASE 0x4007d000 /* Power management controller (PMC) */ +# define KL_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */ +# define KL_RCM_BASE 0x4007f000 /* Reset Control Module (RCM) */ + /* 0x400ff000 * GPIO Controller */ +# define KL_GPIOn_BASE(n) (0x400ff000 + ((n) << 6)) +# define KL_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */ +# define KL_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */ +# define KL_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */ +# define KL_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */ +# define KL_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */ + +/* Private Peripheral Bus (PPB) Memory Map ******************************************/ + +# define KL_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */ +# define KL_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_MEMORYMAP_H */ diff --git a/arch/arm/src/kl/chip/kl_osc.h b/arch/arm/src/kl/chip/kl_osc.h new file mode 100644 index 0000000000000000000000000000000000000000..8edef1e3cdfecaf0960126347a1ee0a289862144 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_osc.h @@ -0,0 +1,84 @@ +/******************************************************************************************** + * arch/arm/src/kl/kl_osc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_OSC_H +#define __ARCH_ARM_SRC_KL_KL_OSC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KL_OSC_CR_OFFSET 0x0000 /* OSC Control Register */ + +/* Register Addresses ***********************************************************************/ + +#define KL_OSC_CR (KL_OSC_BASE+KL_OSC_CR_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* OSC Control Register (8-bit) */ + +#define OSC_CR_ERCLKEN (1 << 7) /* Bit 7: External Reference Enable */ + /* Bit 6: Reserved */ +#define OSC_CR_EREFSTEN (1 << 5) /* Bit 5: External Reference Stop Enable */ + /* Bit 4: Reserved */ +#define OSC_CR_SC2P (1 << 3) /* Bit 3: Oscillator 2 pF Capacitor Load Configure */ +#define OSC_CR_SC4P (1 << 2) /* Bit 2: Oscillator 4 pF Capacitor Load Configure */ +#define OSC_CR_SC8P (1 << 1) /* Bit 1: Oscillator 8 pF Capacitor Load Configure */ +#define OSC_CR_SC16P (1 << 0) /* Bit 0: Oscillator 16 pF Capacitor Load Configure */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_OSC_H */ diff --git a/arch/arm/src/kl/chip/kl_pinmux.h b/arch/arm/src/kl/chip/kl_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..6f8e8cfc4a0784eabd869e64393ae8546a513c3d --- /dev/null +++ b/arch/arm/src/kl/chip/kl_pinmux.h @@ -0,0 +1,69 @@ +/******************************************************************************************** + * arch/arm/src/kl/kl_pinmux.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_PINMUX_H +#define __ARCH_ARM_SRC_KL_KL_PINMUX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/* This file is just a wrapper around pin muxing header files for the Kinetis family selected + * by the logic in chip.h. + */ + +#include "k25z128_pinmux.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_PINMUX_H */ diff --git a/arch/arm/src/kl/chip/kl_pit.h b/arch/arm/src/kl/chip/kl_pit.h new file mode 100644 index 0000000000000000000000000000000000000000..204ceb0c34c0e6a6924291e2f2f17679a1c85c72 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_pit.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_pit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_PIT_H +#define __ARCH_ARM_SRC_KL_KL_PIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "kl_config.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +#define PIT_MCR_OFFSET 0x0000 /* PIT Module Control Register offset */ +#define PIT_LTMR64H_OFFSET 0x00E0 /* PIT Upper Lifetime Timer Register offset */ +#define PIT_LTMR64L_OFFSET 0x00E4 /* PIT Lower Lifetime Timer Register offset */ +#define PIT_LDVAL0_OFFSET 0x0100 /* Timer Load Value Register offset */ +#define PIT_CVAL0_OFFSET 0x0104 /* Current Timer Value Register offset */ +#define PIT_TCTRL0_OFFSET 0x0108 /* Timer Control Register offset */ +#define PIT_TFLG0_OFFSET 0x010C /* Timer Flag Register offset */ +#define PIT_LDVAL1_OFFSET 0x0110 /* Timer Load Value Register offset */ +#define PIT_CVAL1_OFFSET 0x0114 /* Current Timer Value Register offset */ +#define PIT_TCTRL1_OFFSET 0x0118 /* Timer Control Register offset */ +#define PIT_TFLG1_OFFSET 0x011C /* Timer Flag Register offset */ + +#define PIT_MCR (KL_PIT_BASE + PIT_MCR_OFFSET) /* PIT Module Control Register */ +#define PIT_LTMR64H (KL_PIT_BASE + PIT_LTMR64H_OFFSET) /* PIT Upper Lifetime Timer Register */ +#define PIT_LTMR64L (KL_PIT_BASE + PIT_LTMR64L_OFFSET) /* PIT Lower Lifetime Timer Register */ +#define PIT_LDVAL0 (KL_PIT_BASE + PIT_LDVAL0_OFFSET) /* Timer Load Value Register */ +#define PIT_CVAL0 (KL_PIT_BASE + PIT_CVAL0_OFFSET) /* Current Timer Value Register */ +#define PIT_TCTRL0 (KL_PIT_BASE + PIT_TCTRL0_OFFSET) /* Timer Control Register */ +#define PIT_TFLG0 (KL_PIT_BASE + PIT_TFLG0_OFFSET) /* Timer Flag Register */ +#define PIT_LDVAL1 (KL_PIT_BASE + PIT_LDVAL1_OFFSET) /* Timer Load Value Register */ +#define PIT_CVAL1 (KL_PIT_BASE + PIT_CVAL1_OFFSET) /* Current Timer Value Register */ +#define PIT_TCTRL1 (KL_PIT_BASE + PIT_TCTRL1_OFFSET) /* Timer Control Register */ +#define PIT_TFLG1 (KL_PIT_BASE + PIT_TFLG1_OFFSET) /* Timer Flag Register */ + + /* MCR Bits 31-2: Reserved */ +#define PIT_MCR_MDIS (1 << 1) /* Module Disable */ +#define PIT_MCR_FRZ (1 << 0) /* Freeze when in debug mode */ + + /* TCTRLn Bits 0-28: Reserved */ +#define PIT_TCTRL_CHN (1 << 2) /* Chain Mode */ +#define PIT_TCTRL_TIE (1 << 1) /* Timer Interrupt Enable */ +#define PIT_TCTRL_TEN (1 << 0) /* Timer Enable */ + + /* TFLGn Bits 0-30: Reserved */ +#define PIT_TFLG_TIF (1 << 0) /* Timer Interrupt Flag */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_PIT_H */ diff --git a/arch/arm/src/kl/chip/kl_port.h b/arch/arm/src/kl/chip/kl_port.h new file mode 100644 index 0000000000000000000000000000000000000000..3311cd4e284ce78160188e165512c33237badaec --- /dev/null +++ b/arch/arm/src/kl/chip/kl_port.h @@ -0,0 +1,431 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_port.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_PORT_H +#define __ARCH_ARM_SRC_KL_KL_PORT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* General Definitions **************************************************************/ + +#define KL_PORTA (0) +#define KL_PORTB (1) +#define KL_PORTC (2) +#define KL_PORTD (3) +#define KL_PORTE (4) +#define KL_NPORTS (5) + +/* Register Offsets *****************************************************************/ + +#define KL_PORT_PCR_OFFSET(n) ((n) << 2) /* Pin Control Register n, n=0..31 */ +#define KL_PORT_PCR0_OFFSET 0x0000 /* Pin Control Register 0 */ +#define KL_PORT_PCR1_OFFSET 0x0004 /* Pin Control Register 1 */ +#define KL_PORT_PCR2_OFFSET 0x0008 /* Pin Control Register 2 */ +#define KL_PORT_PCR3_OFFSET 0x000C /* Pin Control Register 3 */ +#define KL_PORT_PCR4_OFFSET 0x0010 /* Pin Control Register 4 */ +#define KL_PORT_PCR5_OFFSET 0x0014 /* Pin Control Register 5 */ +#define KL_PORT_PCR6_OFFSET 0x0018 /* Pin Control Register 6 */ +#define KL_PORT_PCR7_OFFSET 0x001c /* Pin Control Register 7 */ +#define KL_PORT_PCR8_OFFSET 0x0020 /* Pin Control Register 8 */ +#define KL_PORT_PCR9_OFFSET 0x0024 /* Pin Control Register 9 */ +#define KL_PORT_PCR10_OFFSET 0x0028 /* Pin Control Register 10 */ +#define KL_PORT_PCR11_OFFSET 0x002c /* Pin Control Register 11 */ +#define KL_PORT_PCR12_OFFSET 0x0030 /* Pin Control Register 12 */ +#define KL_PORT_PCR13_OFFSET 0x0034 /* Pin Control Register 13 */ +#define KL_PORT_PCR14_OFFSET 0x0038 /* Pin Control Register 14 */ +#define KL_PORT_PCR15_OFFSET 0x003c /* Pin Control Register 15 */ +#define KL_PORT_PCR16_OFFSET 0x0040 /* Pin Control Register 16 */ +#define KL_PORT_PCR17_OFFSET 0x0044 /* Pin Control Register 17 */ +#define KL_PORT_PCR18_OFFSET 0x0048 /* Pin Control Register 18 */ +#define KL_PORT_PCR19_OFFSET 0x004c /* Pin Control Register 19 */ +#define KL_PORT_PCR20_OFFSET 0x0050 /* Pin Control Register 20 */ +#define KL_PORT_PCR21_OFFSET 0x0054 /* Pin Control Register 21 */ +#define KL_PORT_PCR22_OFFSET 0x0058 /* Pin Control Register 22 */ +#define KL_PORT_PCR23_OFFSET 0x005c /* Pin Control Register 23 */ +#define KL_PORT_PCR24_OFFSET 0x0060 /* Pin Control Register 24 */ +#define KL_PORT_PCR25_OFFSET 0x0064 /* Pin Control Register 25 */ +#define KL_PORT_PCR26_OFFSET 0x0068 /* Pin Control Register 26 */ +#define KL_PORT_PCR27_OFFSET 0x006c /* Pin Control Register 27 */ +#define KL_PORT_PCR28_OFFSET 0x0070 /* Pin Control Register 28 */ +#define KL_PORT_PCR29_OFFSET 0x0074 /* Pin Control Register 29 */ +#define KL_PORT_PCR30_OFFSET 0x0078 /* Pin Control Register 30 */ +#define KL_PORT_PCR31_OFFSET 0x007c /* Pin Control Register 31 */ +#define KL_PORT_GPCLR_OFFSET 0x0080 /* Global Pin Control Low Register */ +#define KL_PORT_GPCHR_OFFSET 0x0084 /* Global Pin Control High Register */ +#define KL_PORT_ISFR_OFFSET 0x00a0 /* Interrupt Status Flag Register */ +#define KL_PORT_DFER_OFFSET 0x00c0 /* Digital Filter Enable Register */ +#define KL_PORT_DFCR_OFFSET 0x00c4 /* Digital Filter Clock Register */ +#define KL_PORT_DFWR_OFFSET 0x00c8 /* Digital Filter Width Register */ + +/* Register Addresses ***************************************************************/ + +#define KL_PORT_PCR(p,n) (KL_PORT_BASE(p)+KL_PORT_PCR_OFFSET(n) +#define KL_PORT_PCR0(p) (KL_PORT_BASE(p)+KL_PORT_PCR0_OFFSET) +#define KL_PORT_PCR1(p) (KL_PORT_BASE(p)+KL_PORT_PCR1_OFFSET) +#define KL_PORT_PCR2(p) (KL_PORT_BASE(p)+KL_PORT_PCR2_OFFSET) +#define KL_PORT_PCR3(p) (KL_PORT_BASE(p)+KL_PORT_PCR3_OFFSET) +#define KL_PORT_PCR4(p) (KL_PORT_BASE(p)+KL_PORT_PCR4_OFFSET) +#define KL_PORT_PCR5(p) (KL_PORT_BASE(p)+KL_PORT_PCR5_OFFSET) +#define KL_PORT_PCR6(p) (KL_PORT_BASE(p)+KL_PORT_PCR6_OFFSET) +#define KL_PORT_PCR7(p) (KL_PORT_BASE(p)+KL_PORT_PCR7_OFFSET) +#define KL_PORT_PCR8(p) (KL_PORT_BASE(p)+KL_PORT_PCR8_OFFSET) +#define KL_PORT_PCR9(p) (KL_PORT_BASE(p)+KL_PORT_PCR9_OFFSET) +#define KL_PORT_PCR10(p) (KL_PORT_BASE(p)+KL_PORT_PCR10_OFFSET) +#define KL_PORT_PCR11(p) (KL_PORT_BASE(p)+KL_PORT_PCR11_OFFSET) +#define KL_PORT_PCR12(p) (KL_PORT_BASE(p)+KL_PORT_PCR12_OFFSET) +#define KL_PORT_PCR13(p) (KL_PORT_BASE(p)+KL_PORT_PCR13_OFFSET) +#define KL_PORT_PCR14(p) (KL_PORT_BASE(p)+KL_PORT_PCR14_OFFSET) +#define KL_PORT_PCR15(p) (KL_PORT_BASE(p)+KL_PORT_PCR15_OFFSET) +#define KL_PORT_PCR16(p) (KL_PORT_BASE(p)+KL_PORT_PCR16_OFFSET) +#define KL_PORT_PCR17(p) (KL_PORT_BASE(p)+KL_PORT_PCR17_OFFSET) +#define KL_PORT_PCR18(p) (KL_PORT_BASE(p)+KL_PORT_PCR18_OFFSET) +#define KL_PORT_PCR19(p) (KL_PORT_BASE(p)+KL_PORT_PCR19_OFFSET) +#define KL_PORT_PCR20(p) (KL_PORT_BASE(p)+KL_PORT_PCR20_OFFSET) +#define KL_PORT_PCR21(p) (KL_PORT_BASE(p)+KL_PORT_PCR21_OFFSET) +#define KL_PORT_PCR22(p) (KL_PORT_BASE(p)+KL_PORT_PCR22_OFFSET) +#define KL_PORT_PCR23(p) (KL_PORT_BASE(p)+KL_PORT_PCR23_OFFSET) +#define KL_PORT_PCR24(p) (KL_PORT_BASE(p)+KL_PORT_PCR24_OFFSET) +#define KL_PORT_PCR25(p) (KL_PORT_BASE(p)+KL_PORT_PCR25_OFFSET) +#define KL_PORT_PCR26(p) (KL_PORT_BASE(p)+KL_PORT_PCR26_OFFSET) +#define KL_PORT_PCR27(p) (KL_PORT_BASE(p)+KL_PORT_PCR27_OFFSET) +#define KL_PORT_PCR28(p) (KL_PORT_BASE(p)+KL_PORT_PCR28_OFFSET) +#define KL_PORT_PCR29(p) (KL_PORT_BASE(p)+KL_PORT_PCR29_OFFSET) +#define KL_PORT_PCR30(p) (KL_PORT_BASE(p)+KL_PORT_PCR30_OFFSET) +#define KL_PORT_PCR31(p) (KL_PORT_BASE(p)+KL_PORT_PCR31_OFFSET) +#define KL_PORT_GPCLR(p) (KL_PORT_BASE(p)+KL_PORT_GPCLR_OFFSET) +#define KL_PORT_GPCHR(p) (KL_PORT_BASE(p)+KL_PORT_GPCHR_OFFSET) +#define KL_PORT_ISFR(p) (KL_PORT_BASE(p)+KL_PORT_ISFR_OFFSET) +#define KL_PORT_DFER(p) (KL_PORT_BASE(p)+KL_PORT_DFER_OFFSET) +#define KL_PORT_DFCR(p) (KL_PORT_BASE(p)+KL_PORT_DFCR_OFFSET) +#define KL_PORT_DFWR(p) (KL_PORT_BASE(p)+KL_PORT_DFWR_OFFSET) + +#define KL_PORTA_PCR(n) (KL_PORTA_BASE+KL_PORT_PCR_OFFSET(n) +#define KL_PORTA_PCR0 (KL_PORTA_BASE+KL_PORT_PCR0_OFFSET) +#define KL_PORTA_PCR1 (KL_PORTA_BASE+KL_PORT_PCR1_OFFSET) +#define KL_PORTA_PCR2 (KL_PORTA_BASE+KL_PORT_PCR2_OFFSET) +#define KL_PORTA_PCR3 (KL_PORTA_BASE+KL_PORT_PCR3_OFFSET) +#define KL_PORTA_PCR4 (KL_PORTA_BASE+KL_PORT_PCR4_OFFSET) +#define KL_PORTA_PCR5 (KL_PORTA_BASE+KL_PORT_PCR5_OFFSET) +#define KL_PORTA_PCR6 (KL_PORTA_BASE+KL_PORT_PCR6_OFFSET) +#define KL_PORTA_PCR7 (KL_PORTA_BASE+KL_PORT_PCR7_OFFSET) +#define KL_PORTA_PCR8 (KL_PORTA_BASE+KL_PORT_PCR8_OFFSET) +#define KL_PORTA_PCR9 (KL_PORTA_BASE+KL_PORT_PCR9_OFFSET) +#define KL_PORTA_PCR10 (KL_PORTA_BASE+KL_PORT_PCR10_OFFSET) +#define KL_PORTA_PCR11 (KL_PORTA_BASE+KL_PORT_PCR11_OFFSET) +#define KL_PORTA_PCR12 (KL_PORTA_BASE+KL_PORT_PCR12_OFFSET) +#define KL_PORTA_PCR13 (KL_PORTA_BASE+KL_PORT_PCR13_OFFSET) +#define KL_PORTA_PCR14 (KL_PORTA_BASE+KL_PORT_PCR14_OFFSET) +#define KL_PORTA_PCR15 (KL_PORTA_BASE+KL_PORT_PCR15_OFFSET) +#define KL_PORTA_PCR16 (KL_PORTA_BASE+KL_PORT_PCR16_OFFSET) +#define KL_PORTA_PCR17 (KL_PORTA_BASE+KL_PORT_PCR17_OFFSET) +#define KL_PORTA_PCR18 (KL_PORTA_BASE+KL_PORT_PCR18_OFFSET) +#define KL_PORTA_PCR19 (KL_PORTA_BASE+KL_PORT_PCR19_OFFSET) +#define KL_PORTA_PCR20 (KL_PORTA_BASE+KL_PORT_PCR20_OFFSET) +#define KL_PORTA_PCR21 (KL_PORTA_BASE+KL_PORT_PCR21_OFFSET) +#define KL_PORTA_PCR22 (KL_PORTA_BASE+KL_PORT_PCR22_OFFSET) +#define KL_PORTA_PCR23 (KL_PORTA_BASE+KL_PORT_PCR23_OFFSET) +#define KL_PORTA_PCR24 (KL_PORTA_BASE+KL_PORT_PCR24_OFFSET) +#define KL_PORTA_PCR25 (KL_PORTA_BASE+KL_PORT_PCR25_OFFSET) +#define KL_PORTA_PCR26 (KL_PORTA_BASE+KL_PORT_PCR26_OFFSET) +#define KL_PORTA_PCR27 (KL_PORTA_BASE+KL_PORT_PCR27_OFFSET) +#define KL_PORTA_PCR28 (KL_PORTA_BASE+KL_PORT_PCR28_OFFSET) +#define KL_PORTA_PCR29 (KL_PORTA_BASE+KL_PORT_PCR29_OFFSET) +#define KL_PORTA_PCR30 (KL_PORTA_BASE+KL_PORT_PCR30_OFFSET) +#define KL_PORTA_PCR31 (KL_PORTA_BASE+KL_PORT_PCR31_OFFSET) +#define KL_PORTA_GPCLR (KL_PORTA_BASE+KL_PORT_GPCLR_OFFSET) +#define KL_PORTA_GPCHR (KL_PORTA_BASE+KL_PORT_GPCHR_OFFSET) +#define KL_PORTA_ISFR (KL_PORTA_BASE+KL_PORT_ISFR_OFFSET) +#define KL_PORTA_DFER (KL_PORTA_BASE+KL_PORT_DFER_OFFSET) +#define KL_PORTA_DFCR (KL_PORTA_BASE+KL_PORT_DFCR_OFFSET) +#define KL_PORTA_DFWR (KL_PORTA_BASE+KL_PORT_DFWR_OFFSET) + +#define KL_PORTB_PCR(n) (KL_PORTB_BASE+KL_PORT_PCR_OFFSET(n) +#define KL_PORTB_PCR0 (KL_PORTB_BASE+KL_PORT_PCR0_OFFSET) +#define KL_PORTB_PCR1 (KL_PORTB_BASE+KL_PORT_PCR1_OFFSET) +#define KL_PORTB_PCR2 (KL_PORTB_BASE+KL_PORT_PCR2_OFFSET) +#define KL_PORTB_PCR3 (KL_PORTB_BASE+KL_PORT_PCR3_OFFSET) +#define KL_PORTB_PCR4 (KL_PORTB_BASE+KL_PORT_PCR4_OFFSET) +#define KL_PORTB_PCR5 (KL_PORTB_BASE+KL_PORT_PCR5_OFFSET) +#define KL_PORTB_PCR6 (KL_PORTB_BASE+KL_PORT_PCR6_OFFSET) +#define KL_PORTB_PCR7 (KL_PORTB_BASE+KL_PORT_PCR7_OFFSET) +#define KL_PORTB_PCR8 (KL_PORTB_BASE+KL_PORT_PCR8_OFFSET) +#define KL_PORTB_PCR9 (KL_PORTB_BASE+KL_PORT_PCR9_OFFSET) +#define KL_PORTB_PCR10 (KL_PORTB_BASE+KL_PORT_PCR10_OFFSET) +#define KL_PORTB_PCR11 (KL_PORTB_BASE+KL_PORT_PCR11_OFFSET) +#define KL_PORTB_PCR12 (KL_PORTB_BASE+KL_PORT_PCR12_OFFSET) +#define KL_PORTB_PCR13 (KL_PORTB_BASE+KL_PORT_PCR13_OFFSET) +#define KL_PORTB_PCR14 (KL_PORTB_BASE+KL_PORT_PCR14_OFFSET) +#define KL_PORTB_PCR15 (KL_PORTB_BASE+KL_PORT_PCR15_OFFSET) +#define KL_PORTB_PCR16 (KL_PORTB_BASE+KL_PORT_PCR16_OFFSET) +#define KL_PORTB_PCR17 (KL_PORTB_BASE+KL_PORT_PCR17_OFFSET) +#define KL_PORTB_PCR18 (KL_PORTB_BASE+KL_PORT_PCR18_OFFSET) +#define KL_PORTB_PCR19 (KL_PORTB_BASE+KL_PORT_PCR19_OFFSET) +#define KL_PORTB_PCR20 (KL_PORTB_BASE+KL_PORT_PCR20_OFFSET) +#define KL_PORTB_PCR21 (KL_PORTB_BASE+KL_PORT_PCR21_OFFSET) +#define KL_PORTB_PCR22 (KL_PORTB_BASE+KL_PORT_PCR22_OFFSET) +#define KL_PORTB_PCR23 (KL_PORTB_BASE+KL_PORT_PCR23_OFFSET) +#define KL_PORTB_PCR24 (KL_PORTB_BASE+KL_PORT_PCR24_OFFSET) +#define KL_PORTB_PCR25 (KL_PORTB_BASE+KL_PORT_PCR25_OFFSET) +#define KL_PORTB_PCR26 (KL_PORTB_BASE+KL_PORT_PCR26_OFFSET) +#define KL_PORTB_PCR27 (KL_PORTB_BASE+KL_PORT_PCR27_OFFSET) +#define KL_PORTB_PCR28 (KL_PORTB_BASE+KL_PORT_PCR28_OFFSET) +#define KL_PORTB_PCR29 (KL_PORTB_BASE+KL_PORT_PCR29_OFFSET) +#define KL_PORTB_PCR30 (KL_PORTB_BASE+KL_PORT_PCR30_OFFSET) +#define KL_PORTB_PCR31 (KL_PORTB_BASE+KL_PORT_PCR31_OFFSET) +#define KL_PORTB_GPCLR (KL_PORTB_BASE+KL_PORT_GPCLR_OFFSET) +#define KL_PORTB_GPCHR (KL_PORTB_BASE+KL_PORT_GPCHR_OFFSET) +#define KL_PORTB_ISFR (KL_PORTB_BASE+KL_PORT_ISFR_OFFSET) +#define KL_PORTB_DFER (KL_PORTB_BASE+KL_PORT_DFER_OFFSET) +#define KL_PORTB_DFCR (KL_PORTB_BASE+KL_PORT_DFCR_OFFSET) +#define KL_PORTB_DFWR (KL_PORTB_BASE+KL_PORT_DFWR_OFFSET) + +#define KL_PORTC_PCR(n) (KL_PORTC_BASE+KL_PORT_PCR_OFFSET(n) +#define KL_PORTC_PCR0 (KL_PORTC_BASE+KL_PORT_PCR0_OFFSET) +#define KL_PORTC_PCR1 (KL_PORTC_BASE+KL_PORT_PCR1_OFFSET) +#define KL_PORTC_PCR2 (KL_PORTC_BASE+KL_PORT_PCR2_OFFSET) +#define KL_PORTC_PCR3 (KL_PORTC_BASE+KL_PORT_PCR3_OFFSET) +#define KL_PORTC_PCR4 (KL_PORTC_BASE+KL_PORT_PCR4_OFFSET) +#define KL_PORTC_PCR5 (KL_PORTC_BASE+KL_PORT_PCR5_OFFSET) +#define KL_PORTC_PCR6 (KL_PORTC_BASE+KL_PORT_PCR6_OFFSET) +#define KL_PORTC_PCR7 (KL_PORTC_BASE+KL_PORT_PCR7_OFFSET) +#define KL_PORTC_PCR8 (KL_PORTC_BASE+KL_PORT_PCR8_OFFSET) +#define KL_PORTC_PCR9 (KL_PORTC_BASE+KL_PORT_PCR9_OFFSET) +#define KL_PORTC_PCR10 (KL_PORTC_BASE+KL_PORT_PCR10_OFFSET) +#define KL_PORTC_PCR11 (KL_PORTC_BASE+KL_PORT_PCR11_OFFSET) +#define KL_PORTC_PCR12 (KL_PORTC_BASE+KL_PORT_PCR12_OFFSET) +#define KL_PORTC_PCR13 (KL_PORTC_BASE+KL_PORT_PCR13_OFFSET) +#define KL_PORTC_PCR14 (KL_PORTC_BASE+KL_PORT_PCR14_OFFSET) +#define KL_PORTC_PCR15 (KL_PORTC_BASE+KL_PORT_PCR15_OFFSET) +#define KL_PORTC_PCR16 (KL_PORTC_BASE+KL_PORT_PCR16_OFFSET) +#define KL_PORTC_PCR17 (KL_PORTC_BASE+KL_PORT_PCR17_OFFSET) +#define KL_PORTC_PCR18 (KL_PORTC_BASE+KL_PORT_PCR18_OFFSET) +#define KL_PORTC_PCR19 (KL_PORTC_BASE+KL_PORT_PCR19_OFFSET) +#define KL_PORTC_PCR20 (KL_PORTC_BASE+KL_PORT_PCR20_OFFSET) +#define KL_PORTC_PCR21 (KL_PORTC_BASE+KL_PORT_PCR21_OFFSET) +#define KL_PORTC_PCR22 (KL_PORTC_BASE+KL_PORT_PCR22_OFFSET) +#define KL_PORTC_PCR23 (KL_PORTC_BASE+KL_PORT_PCR23_OFFSET) +#define KL_PORTC_PCR24 (KL_PORTC_BASE+KL_PORT_PCR24_OFFSET) +#define KL_PORTC_PCR25 (KL_PORTC_BASE+KL_PORT_PCR25_OFFSET) +#define KL_PORTC_PCR26 (KL_PORTC_BASE+KL_PORT_PCR26_OFFSET) +#define KL_PORTC_PCR27 (KL_PORTC_BASE+KL_PORT_PCR27_OFFSET) +#define KL_PORTC_PCR28 (KL_PORTC_BASE+KL_PORT_PCR28_OFFSET) +#define KL_PORTC_PCR29 (KL_PORTC_BASE+KL_PORT_PCR29_OFFSET) +#define KL_PORTC_PCR30 (KL_PORTC_BASE+KL_PORT_PCR30_OFFSET) +#define KL_PORTC_PCR31 (KL_PORTC_BASE+KL_PORT_PCR31_OFFSET) +#define KL_PORTC_GPCLR (KL_PORTC_BASE+KL_PORT_GPCLR_OFFSET) +#define KL_PORTC_GPCHR (KL_PORTC_BASE+KL_PORT_GPCHR_OFFSET) +#define KL_PORTC_ISFR (KL_PORTC_BASE+KL_PORT_ISFR_OFFSET) +#define KL_PORTC_DFER (KL_PORTC_BASE+KL_PORT_DFER_OFFSET) +#define KL_PORTC_DFCR (KL_PORTC_BASE+KL_PORT_DFCR_OFFSET) +#define KL_PORTC_DFWR (KL_PORTC_BASE+KL_PORT_DFWR_OFFSET) + +#define KL_PORTD_PCR(n) (KL_PORTD_BASE+KL_PORT_PCR_OFFSET(n) +#define KL_PORTD_PCR0 (KL_PORTD_BASE+KL_PORT_PCR0_OFFSET) +#define KL_PORTD_PCR1 (KL_PORTD_BASE+KL_PORT_PCR1_OFFSET) +#define KL_PORTD_PCR2 (KL_PORTD_BASE+KL_PORT_PCR2_OFFSET) +#define KL_PORTD_PCR3 (KL_PORTD_BASE+KL_PORT_PCR3_OFFSET) +#define KL_PORTD_PCR4 (KL_PORTD_BASE+KL_PORT_PCR4_OFFSET) +#define KL_PORTD_PCR5 (KL_PORTD_BASE+KL_PORT_PCR5_OFFSET) +#define KL_PORTD_PCR6 (KL_PORTD_BASE+KL_PORT_PCR6_OFFSET) +#define KL_PORTD_PCR7 (KL_PORTD_BASE+KL_PORT_PCR7_OFFSET) +#define KL_PORTD_PCR8 (KL_PORTD_BASE+KL_PORT_PCR8_OFFSET) +#define KL_PORTD_PCR9 (KL_PORTD_BASE+KL_PORT_PCR9_OFFSET) +#define KL_PORTD_PCR10 (KL_PORTD_BASE+KL_PORT_PCR10_OFFSET) +#define KL_PORTD_PCR11 (KL_PORTD_BASE+KL_PORT_PCR11_OFFSET) +#define KL_PORTD_PCR12 (KL_PORTD_BASE+KL_PORT_PCR12_OFFSET) +#define KL_PORTD_PCR13 (KL_PORTD_BASE+KL_PORT_PCR13_OFFSET) +#define KL_PORTD_PCR14 (KL_PORTD_BASE+KL_PORT_PCR14_OFFSET) +#define KL_PORTD_PCR15 (KL_PORTD_BASE+KL_PORT_PCR15_OFFSET) +#define KL_PORTD_PCR16 (KL_PORTD_BASE+KL_PORT_PCR16_OFFSET) +#define KL_PORTD_PCR17 (KL_PORTD_BASE+KL_PORT_PCR17_OFFSET) +#define KL_PORTD_PCR18 (KL_PORTD_BASE+KL_PORT_PCR18_OFFSET) +#define KL_PORTD_PCR19 (KL_PORTD_BASE+KL_PORT_PCR19_OFFSET) +#define KL_PORTD_PCR20 (KL_PORTD_BASE+KL_PORT_PCR20_OFFSET) +#define KL_PORTD_PCR21 (KL_PORTD_BASE+KL_PORT_PCR21_OFFSET) +#define KL_PORTD_PCR22 (KL_PORTD_BASE+KL_PORT_PCR22_OFFSET) +#define KL_PORTD_PCR23 (KL_PORTD_BASE+KL_PORT_PCR23_OFFSET) +#define KL_PORTD_PCR24 (KL_PORTD_BASE+KL_PORT_PCR24_OFFSET) +#define KL_PORTD_PCR25 (KL_PORTD_BASE+KL_PORT_PCR25_OFFSET) +#define KL_PORTD_PCR26 (KL_PORTD_BASE+KL_PORT_PCR26_OFFSET) +#define KL_PORTD_PCR27 (KL_PORTD_BASE+KL_PORT_PCR27_OFFSET) +#define KL_PORTD_PCR28 (KL_PORTD_BASE+KL_PORT_PCR28_OFFSET) +#define KL_PORTD_PCR29 (KL_PORTD_BASE+KL_PORT_PCR29_OFFSET) +#define KL_PORTD_PCR30 (KL_PORTD_BASE+KL_PORT_PCR30_OFFSET) +#define KL_PORTD_PCR31 (KL_PORTD_BASE+KL_PORT_PCR31_OFFSET) +#define KL_PORTD_GPCLR (KL_PORTD_BASE+KL_PORT_GPCLR_OFFSET) +#define KL_PORTD_GPCHR (KL_PORTD_BASE+KL_PORT_GPCHR_OFFSET) +#define KL_PORTD_ISFR (KL_PORTD_BASE+KL_PORT_ISFR_OFFSET) +#define KL_PORTD_DFER (KL_PORTD_BASE+KL_PORT_DFER_OFFSET) +#define KL_PORTD_DFCR (KL_PORTD_BASE+KL_PORT_DFCR_OFFSET) +#define KL_PORTD_DFWR (KL_PORTD_BASE+KL_PORT_DFWR_OFFSET) + +#define KL_PORTE_PCR(n) (KL_PORTE_BASE+KL_PORT_PCR_OFFSET(n) +#define KL_PORTE_PCR0 (KL_PORTE_BASE+KL_PORT_PCR0_OFFSET) +#define KL_PORTE_PCR1 (KL_PORTE_BASE+KL_PORT_PCR1_OFFSET) +#define KL_PORTE_PCR2 (KL_PORTE_BASE+KL_PORT_PCR2_OFFSET) +#define KL_PORTE_PCR3 (KL_PORTE_BASE+KL_PORT_PCR3_OFFSET) +#define KL_PORTE_PCR4 (KL_PORTE_BASE+KL_PORT_PCR4_OFFSET) +#define KL_PORTE_PCR5 (KL_PORTE_BASE+KL_PORT_PCR5_OFFSET) +#define KL_PORTE_PCR6 (KL_PORTE_BASE+KL_PORT_PCR6_OFFSET) +#define KL_PORTE_PCR7 (KL_PORTE_BASE+KL_PORT_PCR7_OFFSET) +#define KL_PORTE_PCR8 (KL_PORTE_BASE+KL_PORT_PCR8_OFFSET) +#define KL_PORTE_PCR9 (KL_PORTE_BASE+KL_PORT_PCR9_OFFSET) +#define KL_PORTE_PCR10 (KL_PORTE_BASE+KL_PORT_PCR10_OFFSET) +#define KL_PORTE_PCR11 (KL_PORTE_BASE+KL_PORT_PCR11_OFFSET) +#define KL_PORTE_PCR12 (KL_PORTE_BASE+KL_PORT_PCR12_OFFSET) +#define KL_PORTE_PCR13 (KL_PORTE_BASE+KL_PORT_PCR13_OFFSET) +#define KL_PORTE_PCR14 (KL_PORTE_BASE+KL_PORT_PCR14_OFFSET) +#define KL_PORTE_PCR15 (KL_PORTE_BASE+KL_PORT_PCR15_OFFSET) +#define KL_PORTE_PCR16 (KL_PORTE_BASE+KL_PORT_PCR16_OFFSET) +#define KL_PORTE_PCR17 (KL_PORTE_BASE+KL_PORT_PCR17_OFFSET) +#define KL_PORTE_PCR18 (KL_PORTE_BASE+KL_PORT_PCR18_OFFSET) +#define KL_PORTE_PCR19 (KL_PORTE_BASE+KL_PORT_PCR19_OFFSET) +#define KL_PORTE_PCR20 (KL_PORTE_BASE+KL_PORT_PCR20_OFFSET) +#define KL_PORTE_PCR21 (KL_PORTE_BASE+KL_PORT_PCR21_OFFSET) +#define KL_PORTE_PCR22 (KL_PORTE_BASE+KL_PORT_PCR22_OFFSET) +#define KL_PORTE_PCR23 (KL_PORTE_BASE+KL_PORT_PCR23_OFFSET) +#define KL_PORTE_PCR24 (KL_PORTE_BASE+KL_PORT_PCR24_OFFSET) +#define KL_PORTE_PCR25 (KL_PORTE_BASE+KL_PORT_PCR25_OFFSET) +#define KL_PORTE_PCR26 (KL_PORTE_BASE+KL_PORT_PCR26_OFFSET) +#define KL_PORTE_PCR27 (KL_PORTE_BASE+KL_PORT_PCR27_OFFSET) +#define KL_PORTE_PCR28 (KL_PORTE_BASE+KL_PORT_PCR28_OFFSET) +#define KL_PORTE_PCR29 (KL_PORTE_BASE+KL_PORT_PCR29_OFFSET) +#define KL_PORTE_PCR30 (KL_PORTE_BASE+KL_PORT_PCR30_OFFSET) +#define KL_PORTE_PCR31 (KL_PORTE_BASE+KL_PORT_PCR31_OFFSET) +#define KL_PORTE_GPCLR (KL_PORTE_BASE+KL_PORT_GPCLR_OFFSET) +#define KL_PORTE_GPCHR (KL_PORTE_BASE+KL_PORT_GPCHR_OFFSET) +#define KL_PORTE_ISFR (KL_PORTE_BASE+KL_PORT_ISFR_OFFSET) +#define KL_PORTE_DFER (KL_PORTE_BASE+KL_PORT_DFER_OFFSET) +#define KL_PORTE_DFCR (KL_PORTE_BASE+KL_PORT_DFCR_OFFSET) +#define KL_PORTE_DFWR (KL_PORTE_BASE+KL_PORT_DFWR_OFFSET) + +/* Register Bit Definitions *********************************************************/ +/* Pin Control Register n, n=0..31 */ + +#define PORT_PCR_PS (1 << 0) /* Bit 0: Pull Select */ +#define PORT_PCR_PE (1 << 1) /* Bit 1: Pull Enable */ +#define PORT_PCR_SRE (1 << 2) /* Bit 2: Slew Rate Enable */ + /* Bit 3: Reserved */ +#define PORT_PCR_PFE (1 << 4) /* Bit 4: Passive Filter Enable */ +#define PORT_PCR_ODE (1 << 5) /* Bit 5: Open Drain Enable */ +#define PORT_PCR_DSE (1 << 6) /* Bit 6: Drive Strength Enable */ + /* Bit 7: Reserved */ +#define PORT_PCR_MUX_SHIFT (8) /* Bits 8-10: Pin Mux Control */ +#define PORT_PCR_MUX_MASK (7 << PORT_PCR_MUX_SHIFT) +# define PORT_PCR_MUX_ANALOG (0 << PORT_PCR_MUX_SHIFT) /* Pin Disabled (Analog) */ +# define PORT_PCR_MUX_GPIO (1 << PORT_PCR_MUX_SHIFT) /* Alternative 1 (GPIO) */ +# define PORT_PCR_MUX_ALT1 (1 << PORT_PCR_MUX_SHIFT) /* Alternative 1 (GPIO) */ +# define PORT_PCR_MUX_ALT2 (2 << PORT_PCR_MUX_SHIFT) /* Alternative 2 (chip specific) */ +# define PORT_PCR_MUX_ALT3 (3 << PORT_PCR_MUX_SHIFT) /* Alternative 3 (chip specific) */ +# define PORT_PCR_MUX_ALT4 (4 << PORT_PCR_MUX_SHIFT) /* Alternative 4 (chip specific) */ +# define PORT_PCR_MUX_ALT5 (5 << PORT_PCR_MUX_SHIFT) /* Alternative 5 (chip specific) */ +# define PORT_PCR_MUX_ALT6 (6 << PORT_PCR_MUX_SHIFT) /* Alternative 6 (chip specific) */ +# define PORT_PCR_MUX_ALT7 (7 << PORT_PCR_MUX_SHIFT) /* Alternative 7 (chip specific / JTAG / NMI) */ + /* Bits 11-14: Reserved */ +#define PORT_PCR_LK (1 << 15) /* Bit 15: Lock Register */ +#define PORT_PCR_IRQC_SHIFT (16) /* Bits 16-19: Interrupt Configuration */ +#define PORT_PCR_IRQC_MASK (15 << PORT_PCR_IRQC_SHIFT) +# define PORT_PCR_IRQC_DISABLED (0 << PORT_PCR_IRQC_SHIFT) /* Interrupt/DMA Request disabled */ +# define PORT_PCR_IRQC_DMARISING (1 << PORT_PCR_IRQC_SHIFT) /* DMA Request on rising edge */ +# define PORT_PCR_IRQC_DMAFALLING (2 << PORT_PCR_IRQC_SHIFT) /* DMA Request on falling edge */ +# define PORT_PCR_IRQC_DMABOTH (3 << PORT_PCR_IRQC_SHIFT) /* DMA Request on either edge */ +# define PORT_PCR_IRQC_ZERO (8 << PORT_PCR_IRQC_SHIFT) /* Interrupt when logic zero */ +# define PORT_PCR_IRQC_RISING (9 << PORT_PCR_IRQC_SHIFT) /* Interrupt on rising edge */ +# define PORT_PCR_IRQC_FALLING (10 << PORT_PCR_IRQC_SHIFT) /* Interrupt on falling edge */ +# define PORT_PCR_IRQC_BOTH (11 << PORT_PCR_IRQC_SHIFT) /* Interrupt on either edge */ +# define PORT_PCR_IRQC_ONE (12 << PORT_PCR_IRQC_SHIFT) /* Interrupt when logic one */ + /* Bits 20-23: Reserved */ +#define PORT_PCR_ISF (1 << 24) /* Bit 24: Interrupt Status Flag */ + /* Bits 25-31: Reserved */ + +/* Global Pin Control Low Register */ + +#define PORT_GPCLR_GPWD_SHIFT (0) /* Bits 0-15: Global Pin Write Data */ +#define PORT_GPCLR_GPWD_MASK (0xffff << PORT_GPCLR_GPWD_SHIFT) +# define PORT_GPCLR_GPWD(n) ((1 << (n)) << PORT_GPCLR_GPWD_SHIFT) +#define PORT_GPCLR_GPWE_SHIFT (16) /* Bits 16-31: Global Pin Write Enable */ +#define PORT_GPCLR_GPWE_MASK (0xffff << PORT_GPCLR_GPWE_SHIFT) +# define PORT_GPCLR_GPWE(n) ((1 << (n)) << PORT_GPCLR_GPWE_SHIFT) + +/* Global Pin Control High Register */ + +#define PORT_GPCHR_ + +#define PORT_GPCHR_GPWD_SHIFT (0) /* Bits 0-15: Global Pin Write Data */ +#define PORT_GPCHR_GPWD_MASK (0xffff << PORT_GPCHR_GPWD_SHIFT) +# define PORT_GPCHR_GPWD(n) ((1 << (n)) << PORT_GPCHR_GPWD_SHIFT) +#define PORT_GPCHR_GPWE_SHIFT (16) /* Bits 16-31: Global Pin Write Enable */ +#define PORT_GPCHR_GPWE_MASK (0xffff << PORT_GPCHR_GPWE_SHIFT) +# define PORT_GPCHR_GPWE(n) ((1 << (n)) << PORT_GPCHR_GPWE_SHIFT) + +/* Interrupt Status Flag Register */ + +#define PORT_ISFR(n) (1 << (n)) + +/* Digital Filter Enable Register */ + +#define PORT_DFER(n) (1 << (n)) + +/* Digital Filter Clock Register */ + +#define PORT_DFCR_CS (1 << 0) /* Bit 0: Clock Source */ + +/* Digital Filter Width Register */ + +#define PORT_DFWR_FILT_SHIFT (0) /* Bits 0-4: Filter Length */ +#define PORT_DFWR_FILT_MASK (31 << PORT_DFWR_FILT_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_PORT_H */ diff --git a/arch/arm/src/kl/chip/kl_sim.h b/arch/arm/src/kl/chip/kl_sim.h new file mode 100644 index 0000000000000000000000000000000000000000..001324eb4221aea1bece1026af7f0fe893ba6163 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_sim.h @@ -0,0 +1,390 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_sim.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_SIM_H +#define __ARCH_ARM_SRC_KL_KL_SIM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +/* Relative to KL_SIMLP_BASE */ + +#define KL_SIM_SOPT1_OFFSET 0x0000 /* System Options Register 1 */ +#define KL_SIM_SOPT1CFG_OFFSET 0x0004 /* SOPT1 Configuration Register */ + +/* Relative to KL_SIM_BASE */ + +#define KL_SIM_SOPT2_OFFSET 0x0004 /* System Options Register 2 */ +#define KL_SIM_SOPT4_OFFSET 0x000c /* System Options Register 4 */ +#define KL_SIM_SOPT5_OFFSET 0x0010 /* System Options Register 5 */ +#define KL_SIM_SOPT7_OFFSET 0x0018 /* System Options Register 7 */ +#define KL_SIM_SDID_OFFSET 0x0024 /* System Device Identification Register */ +#define KL_SIM_SCGC4_OFFSET 0x0034 /* System Clock Gating Control Register 4 */ +#define KL_SIM_SCGC5_OFFSET 0x0038 /* System Clock Gating Control Register 5 */ +#define KL_SIM_SCGC6_OFFSET 0x003c /* System Clock Gating Control Register 6 */ +#define KL_SIM_SCGC7_OFFSET 0x0040 /* System Clock Gating Control Register 7 */ +#define KL_SIM_CLKDIV1_OFFSET 0x0044 /* System Clock Divider Register 1 */ +#define KL_SIM_FCFG1_OFFSET 0x004c /* Flash Configuration Register 1 */ +#define KL_SIM_FCFG2_OFFSET 0x0050 /* Flash Configuration Register 2 */ +#define KL_SIM_UIDMH_OFFSET 0x0058 /* Unique Identification Register Mid-High */ +#define KL_SIM_UIDML_OFFSET 0x005c /* Unique Identification Register Mid Low */ +#define KL_SIM_UIDL_OFFSET 0x0060 /* Unique Identification Register Low */ +#define KL_SIM_COPC_OFFSET 0x0100 /* COP Control Register */ +#define KL_SIM_SRVCOP_OFFSET 0x0104 /* Service COP Register */ + +/* Register Addresses ***************************************************************/ +/* NOTE: The SIM_SOPT1 register is located at a different base address than the + * other SIM registers. + */ + +#define KL_SIM_SOPT1 (KL_SIMLP_BASE+KL_SIM_SOPT1_OFFSET) +#define KL_SIM_SOPT1CFG (KL_SIMLP_BASE+KL_SIM_SOPT1CFG_OFFSET) + +#define KL_SIM_SOPT2 (KL_SIM_BASE+KL_SIM_SOPT2_OFFSET) +#define KL_SIM_SOPT4 (KL_SIM_BASE+KL_SIM_SOPT4_OFFSET) +#define KL_SIM_SOPT5 (KL_SIM_BASE+KL_SIM_SOPT5_OFFSET) +#define KL_SIM_SOPT7 (KL_SIM_BASE+KL_SIM_SOPT7_OFFSET) +#define KL_SIM_SDID (KL_SIM_BASE+KL_SIM_SDID_OFFSET) +#define KL_SIM_SCGC4 (KL_SIM_BASE+KL_SIM_SCGC4_OFFSET) +#define KL_SIM_SCGC5 (KL_SIM_BASE+KL_SIM_SCGC5_OFFSET) +#define KL_SIM_SCGC6 (KL_SIM_BASE+KL_SIM_SCGC6_OFFSET) +#define KL_SIM_SCGC7 (KL_SIM_BASE+KL_SIM_SCGC7_OFFSET) +#define KL_SIM_CLKDIV1 (KL_SIM_BASE+KL_SIM_CLKDIV1_OFFSET) +#define KL_SIM_FCFG1 (KL_SIM_BASE+KL_SIM_FCFG1_OFFSET) +#define KL_SIM_FCFG2 (KL_SIM_BASE+KL_SIM_FCFG2_OFFSET) +#define KL_SIM_UIDMH (KL_SIM_BASE+KL_SIM_UIDMH_OFFSET) +#define KL_SIM_UIDML (KL_SIM_BASE+KL_SIM_UIDML_OFFSET) +#define KL_SIM_UIDL (KL_SIM_BASE+KL_SIM_UIDL_OFFSET) +#define KL_SIM_COPC (KL_SIM_BASE+KL_SIM_COPC_OFFSET) +#define KL_SIM_SRVCOP (KL_SIM_BASE+KL_SIM_SRVCOP_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* System Options Register 1 */ + /* Bits 0-17: Reserved */ +#define SIM_SOPT1_OSC32KSEL_SHIFT (18) /* Bit 18-19: 32K oscillator clock select */ +#define SIM_SOPT1_OSC32KSEL_MASK (3 << SIM_SOPT1_OSC32KSEL_SHIFT) +# define SIM_SOPT1_OSC32KSEL_SYS (1 << SIM_SOPT1_OSC32KSEL_SHIFT) /* System oscillator (OSC32KCLK) */ +# define SIM_SOPT1_OSC32KSEL_RTC (2 << SIM_SOPT1_OSC32KSEL_SHIFT) /* RTC_CLKIN */ +# define SIM_SOPT1_OSC32KSEL_LPO (3 << SIM_SOPT1_OSC32KSEL_SHIFT) /* LPO 1kHz */ + /* Bits 20-28: Reserved */ +#define SIM_SOPT1_USBSTBY (1 << 29) /* Bit 29: USB voltage regulator in + * standby mode (VLPR and VLPW modes) */ +#define SIM_SOPT1_USBSSTBY (1 << 30) /* Bit 30: USB voltage regulator in standb + * mode (Stop, VLPS, LLS and VLLS modes) */ +#define SIM_SOPT1_USBREGEN (1 << 31) /* Bit 31: USB voltage regulator enable */ + +/* SOPT1 Configuration Register */ + +#define SIM_SOPT1CFG_URWE (1 << 24) /* Bit 24: USB voltage regulator enable write enable */ +#define SIM_SOPT1CFG_UVSWE (1 << 25) /* Bit 25: USB voltage regulator VLP standby write enable */ +#define SIM_SOPT1CFG_USSWE (1 << 26) /* Bit 26: USB voltage regulator stop standby write enable */ + +/* To be provided */ + +/* System Options Register 2 */ + + /* Bits 0-3: Reserved */ +#define SIM_SOPT2_RTCCLKOUTSEL (1 << 4) /* Bit 0: MCG clock select */ +#define SIM_SOPT2_CLKOUTSEL_SHIFT (5) /* Bits 5-7: RTC clock out select */ +#define SIM_SOPT2_CLKOUTSEL_MASK (3 << SIM_SOPT2_CLKOUTSEL_SHIFT) +# define SIM_SOPT2_CLKOUTSEL_BUSCLK (2 << SIM_SOPT2_CLKOUTSEL_SHIFT) /* Bus clock */ +# define SIM_SOPT2_CLKOUTSEL_LPO (3 << SIM_SOPT2_CLKOUTSEL_SHIFT) /* LPO clock (1 kHz) */ +# define SIM_SOPT2_CLKOUTSEL_MCGIRCLK (4 << SIM_SOPT2_CLKOUTSEL_SHIFT) /* MCGIRCLK */ +# define SIM_SOPT2_CLKOUTSEL_OSCERCLK (6 << SIM_SOPT2_CLKOUTSEL_SHIFT) /* OSCERCLK */ +#define SIM_SOPT2_CMTUARTPAD (1 << 11) /* Bit 11: CMT/UART pad drive strength */ +#define SIM_SOPT2_TRACECLKSEL (1 << 12) /* Bit 12: Debug trace clock select */ + /* Bits 13-15: Reserved */ +#define SIM_SOPT2_PLLFLLSEL (1 << 16) /* Bit 16: PLL/FLL clock select */ + /* Bit 17: Reserved */ +#define SIM_SOPT2_USBSRC (1 << 18) /* Bit 18: USB clock source select */ + /* Bits 19-23: Reserved */ +#define SIM_SOPT2_TPMSRC_SHIFT (24) /* Bits 24-25: I2S master clock source select */ +#define SIM_SOPT2_TPMSRC_MASK (3 << SIM_SOPT2_TPMSRC_SHIFT) +# define SIM_SOPT2_TPMSRC_CLKDIS (0 << SIM_SOPT2_TPMSRC_SHIFT) /* Core/system clock / I2S fractional divider*/ +# define SIM_SOPT2_TPMSRC_MCGCLK (1 << SIM_SOPT2_TPMSRC_SHIFT) /* MCGFLLCLK clock or MCGPLLCLK/2 */ +# define SIM_SOPT2_TPMSRC_OCSERCLK (2 << SIM_SOPT2_TPMSRC_SHIFT) /* OSCERCLK clock */ +# define SIM_SOPT2_TPMSRC_MCGIRCLK (3 << SIM_SOPT2_TPMSRC_SHIFT) /* MCGIRCLK clock */ +#define SIM_SOPT2_UART0SRC_SHIFT (26) /* Bits 26-27: UART0 clock source select */ +#define SIM_SOPT2_UART0SRC_MASK (3 << SIM_SOPT2_UART0SRC_SHIFT) +# define SIM_SOPT2_UART0SRC_DIS (0 << SIM_SOPT2_UART0SRC_SHIFT) /* Clock disabled */ +# define SIM_SOPT2_UART0SRC_MCGCLK (1 << SIM_SOPT2_UART0SRC_SHIFT) /* MCGFLLCLK clock or MCGPLLCLK/2 clock */ +# define SIM_SOPT2_UART0SRC_OSCERCLK (2 << SIM_SOPT2_UART0SRC_SHIFT) /* OSCERCLK clock */ +# define SIM_SOPT2_UART0SRC_MCGIRCLK (3 << SIM_SOPT2_UART0SRC_SHIFT) /* MCGIRCLK clock */ + /* Bits 28-31: Reserved */ + +/* System Options Register 4 */ + + /* Bits 0-17: Reserved */ +#define SIM_SOPT4_TPM1CH0SRC (1 << 18) /* Bit 18: TPM1 channel 0 input capture source select */ + /* Bit 19: Reserved */ +#define SIM_SOPT4_TPM2CH0SRC (1 << 20) /* Bit 20: TPM2 channel 0 input capture source select */ + /* Bits 21-23: Reserved */ +#define SIM_SOPT4_TPM0CLKSEL (1 << 24) /* Bit 24: TPM0CLKSEL */ +#define SIM_SOPT4_TPM1CLKSEL (1 << 25) /* Bit 25: TPM1 External Clock Pin Select */ +#define SIM_SOPT4_TPM2CLKSEL (1 << 26) /* Bit 26: TPM2 External Clock Pin Select */ + /* Bits 27-31: Reserved */ + +/* System Options Register 5 */ + +#define SIM_SOPT5_UART0TXSRC_SHIFT (0) /* Bits 0-1: UART 0 transmit data source select */ +#define SIM_SOPT5_UART0TXSRC_MASK (3 << SIM_SOPT5_UART0TXSRC_SHIFT) +# define SIM_SOPT5_UART0TXSRC_TX (0 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX pin */ +# define SIM_SOPT5_UART0TXSRC_TPM1 (1 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX modulated with TPM1 ch0 output */ +# define SIM_SOPT5_UART0TXSRC_TPM2 (2 << SIM_SOPT5_UART0TXSRC_SHIFT) /* UART0_TX modulated with TPM2 ch0 output */ +#define SIM_SOPT5_UART0RXSRC (1 << 2) /* Bit 2: UART 0 receive data source select */ + /* Bit 3: Reserved */ +#define SIM_SOPT5_UART1TXSRC_SHIFT (4) /* Bits 4-5: UART 1 transmit data source select */ +#define SIM_SOPT5_UART1TXSRC_MASK (3 << SIM_SOPT5_UART1TXSRC_SHIFT) +# define SIM_SOPT5_UART1TXSRC_TX (0 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX pin */ +# define SIM_SOPT5_UART1TXSRC_TPM1 (1 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX modulated with TPM1 ch0 output */ +# define SIM_SOPT5_UART1TXSRC_TPM2 (2 << SIM_SOPT5_UART1TXSRC_SHIFT) /* UART1_TX modulated with TPM2 ch0 output */ +#define SIM_SOPT5_UART1RXSRC (1 << 6) /* Bit 6: UART 1 receive data source select */ +#define SIM_SOPT5_UART0ODE (1 << 16) /* Bit 16: UART0 Open Drain Enable */ +#define SIM_SOPT5_UART1ODE (1 << 17) /* Bit 17: UART1 Open Drain Enable */ +#define SIM_SOPT5_UART2ODE (1 << 18) /* Bit 18: UART2 Open Drain Enable */ + /* Bits 20-31: Reserved */ +/* System Options Register 7 */ + +#define SIM_SOPT7_ADC0TRGSEL_SHIFT (0) /* Bits 0-3: ADC0 trigger select */ +#define SIM_SOPT7_ADC0TRGSEL_MASK (15 << SIM_SOPT7_ADC0TRGSEL_SHIFT) +# define SIM_SOPT7_ADC0TRGSEL_EXT (0 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* External trigger pin input (EXTRG_IN)*/ +# define SIM_SOPT7_ADC0TRGSEL_CMP0 (1 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* CMP0 output */ +# define SIM_SOPT7_ADC0TRGSEL_PIT0 (4 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 0 */ +# define SIM_SOPT7_ADC0TRGSEL_PIT1 (5 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* PIT trigger 1 */ +# define SIM_SOPT7_ADC0TRGSEL_TPM0 (8 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* TPM0 overflow */ +# define SIM_SOPT7_ADC0TRGSEL_TPM1 (9 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* TPM1 overflow */ +# define SIM_SOPT7_ADC0TRGSEL_TPM2 (10 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* TPM2 overflow */ +# define SIM_SOPT7_ADC0TRGSEL_ALARM (12 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* RTC alarm */ +# define SIM_SOPT7_ADC0TRGSEL_SECS (13 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* RTC seconds */ +# define SIM_SOPT7_ADC0TRGSEL_LPTMR (14 << SIM_SOPT7_ADC0TRGSEL_SHIFT) /* LPTMR0 trigger */ +#define SIM_SOPT7_ADC0PRETRGSEL (1 << 4) /* Bit 4: ADC0 pretrigger select */ + /* Bits 5-6: Reserved */ +#define SIM_SOPT7_ADC0ALTTRGEN (1 << 7) /* Bit 7: ADC0 alternate trigger enable */ + /* Bits 8-31: Reserved */ +/* System Device Identification Register */ + +#define SIM_SDID_PINID_SHIFT (0) /* Bits 0-3: Pincount identification */ +#define SIM_SDID_PINID_MASK (15 << SIM_SDID_PINID_SHIFT) +# define SIM_SDID_PINID_16PIN (0 << SIM_SDID_PINID_SHIFT) /* 16-pin */ +# define SIM_SDID_PINID_24PIN (1 << SIM_SDID_PINID_SHIFT) /* 24-pin */ +# define SIM_SDID_PINID_32PIN (2 << SIM_SDID_PINID_SHIFT) /* 32-pin */ +# define SIM_SDID_PINID_48PIN (4 << SIM_SDID_PINID_SHIFT) /* 48-pin */ +# define SIM_SDID_PINID_64PIN (5 << SIM_SDID_PINID_SHIFT) /* 64-pin */ +# define SIM_SDID_PINID_80PIN (6 << SIM_SDID_PINID_SHIFT) /* 80-pin */ +# define SIM_SDID_PINID_100PIN (8 << SIM_SDID_PINID_SHIFT) /* 100-pin */ + /* Bits 406: Reserved */ +#define SIM_SDID_DIEID_SHIFT (7) /* Bits 7-1: Device die number */ +#define SIM_SDID_DIEID_MASK (15 << SIM_SDID_DIEID_SHIFT) +#define SIM_SDID_REVID_SHIFT (12) /* Bits 12-15: Device revision number */ +#define SIM_SDID_REVID_MASK (15 << SIM_SDID_REVID_SHIFT) +#define SIM_SDID_SRAMSIZE_SHIFT (16) /* Bits 16-19: System SRAM Size */ +#define SIM_SDID_SRAMSIZE_MASK (15 << SIM_SDID_SRAMSIZE_SHIFT) +# define SIM_SDID_SRAMSIZE_p5KB (0 << SIM_SDID_SRAMSIZE_SHIFT) /* 0.5 KB */ +# define SIM_SDID_SRAMSIZE_1KB (1 << SIM_SDID_SRAMSIZE_SHIFT) /* 1 KB */ +# define SIM_SDID_SRAMSIZE_2KB (2 << SIM_SDID_SRAMSIZE_SHIFT) /* 2 KB */ +# define SIM_SDID_SRAMSIZE_4KB (3 << SIM_SDID_SRAMSIZE_SHIFT) /* 4 KB */ +# define SIM_SDID_SRAMSIZE_8KB (4 << SIM_SDID_SRAMSIZE_SHIFT) /* 8 KB */ +# define SIM_SDID_SRAMSIZE_16KB (5 << SIM_SDID_SRAMSIZE_SHIFT) /* 16 KB */ +# define SIM_SDID_SRAMSIZE_32KB (6 << SIM_SDID_SRAMSIZE_SHIFT) /* 32 KB */ +# define SIM_SDID_SRAMSIZE_64KB (7 << SIM_SDID_SRAMSIZE_SHIFT) /* 64 KB */ +#define SIM_SDID_SERIESID_SHIFT (10) /* Bits 20-23: Kinetis Series ID */ +#define SIM_SDID_SERIESID_MASK (15 << SIM_SDID_SERIESID_SHIFT) +# define SIM_SDID_SERIESID_KL (1 << SIM_SDID_SERIESID_SHIFT) /* KL family */ +#define SIM_SDID_SUBFAMID_SHIFT (24) /* Bits 24-27: Kinetis Sub-Family ID */ +#define SIM_SDID_SUBFAMID_MASK (15 << SIM_SDID_SUBFAMID_SHIFT) +# define SIM_SDID_SUBFAMID_KLX2 (2 << SIM_SDID_SUBFAMID_SHIFT) /* KLx2 Subfamily (low end) */ +# define SIM_SDID_SUBFAMID_KLX4 (4 << SIM_SDID_SUBFAMID_SHIFT) /* KLx4 Subfamily (basic analog) */ +# define SIM_SDID_SUBFAMID_KLX5 (5 << SIM_SDID_SUBFAMID_SHIFT) /* KLx5 Subfamily (advanced analog) */ +# define SIM_SDID_SUBFAMID_KLX6 (6 << SIM_SDID_SUBFAMID_SHIFT) /* KL3x KLx6 Subfamily (advanced analog with I2S) */ +#define SIM_SDID_FAMID_SHIFT (28) /* Bits 28-31: Kinetis family ID */ +#define SIM_SDID_FAMID_MASK (15 << SIM_SDID_FAMID_SHIFT) +# define SIM_SDID_FAMID_KL0 (0 << SIM_SDID_FAMID_SHIFT) /* KL0x Family (low end) */ +# define SIM_SDID_FAMID_KL1 (1 << SIM_SDID_FAMID_SHIFT) /* KL1x Family (basic) */ +# define SIM_SDID_FAMID_KL2 (2 << SIM_SDID_FAMID_SHIFT) /* KL2x Family (USB) */ +# define SIM_SDID_FAMID_KL3 (3 << SIM_SDID_FAMID_SHIFT) /* KL3x Family (Segment LCD) */ +# define SIM_SDID_FAMID_KL4 (4 << SIM_SDID_FAMID_SHIFT) /* KL4x Family (USB and Segment LCD) */ + +/* System Clock Gating Control Register 4 */ + /* Bits 0-5: Reserved */ +#define SIM_SCGC4_I2C0 (1 << 6) /* Bit 6: I2C0 Clock Gate Control */ +#define SIM_SCGC4_I2C1 (1 << 7) /* Bit 7: I2C1 Clock Gate Control */ + /* Bits 8-9: Reserved */ +#define SIM_SCGC4_UART0 (1 << 10) /* Bit 10: UART0 Clock Gate Control */ +#define SIM_SCGC4_UART1 (1 << 11) /* Bit 11: UART1 Clock Gate Control */ +#define SIM_SCGC4_UART2 (1 << 12) /* Bit 12: UART2 Clock Gate Control */ + /* Bits 13-17: Reserved */ +#define SIM_SCGC4_USBOTG (1 << 18) /* Bit 18: USB Clock Gate Control */ +#define SIM_SCGC4_CMP (1 << 19) /* Bit 19: Comparator Clock Gate Control */ + /* Bits 20-21: Reserved */ +#define SIM_SCGC4_SPI0 (1 << 22) /* Bit 22: SPI0 Clock Gate Control */ +#define SIM_SCGC4_SPI1 (1 << 23) /* Bit 23: SPI1 Clock Gate Control */ + /* Bits 24-31: Reserved */ +/* System Clock Gating Control Register 5 */ + +#define SIM_SCGC5_LPTIMER (1 << 0) /* Bit 0: Low Power Timer Clock Gate Control */ + /* Bits 1-4: Reserved */ +#define SIM_SCGC5_TSI (1 << 5) /* Bit 5: TSI Clock Gate Control */ + /* Bits 6-8: Reserved */ +#define SIM_SCGC5_PORTA (1 << 9) /* Bit 9: Port A Clock Gate Control */ +#define SIM_SCGC5_PORTB (1 << 10) /* Bit 10: Port B Clock Gate Control */ +#define SIM_SCGC5_PORTC (1 << 11) /* Bit 11: Port C Clock Gate Control */ +#define SIM_SCGC5_PORTD (1 << 12) /* Bit 12: Port D Clock Gate Control */ +#define SIM_SCGC5_PORTE (1 << 13) /* Bit 13: Port E Clock Gate Control */ + /* Bits 14-31: Reserved */ +/* System Clock Gating Control Register 6 */ + +#define SIM_SCGC6_FTFL (1 << 0) /* Bit 0: Flash Memory Clock Gate Control */ +#define SIM_SCGC6_DMAMUX (1 << 1) /* Bit 1: DMA Mux Clock Gate Control */ + /* Bits 2-22: Reserved */ +#define SIM_SCGC6_PIT (1 << 23) /* Bit 23: PIT Clock Gate Control */ +#define SIM_SCGC6_TPM0 (1 << 24) /* Bit 24: TPM0 Clock Gate Control */ +#define SIM_SCGC6_TPM1 (1 << 25) /* Bit 25: TPM1 Clock Gate Control */ +#define SIM_SCGC6_TPM2 (1 << 26) /* Bit 25: TPM2 Clock Gate Control */ +#define SIM_SCGC6_ADC0 (1 << 27) /* Bit 27: ADC0 Clock Gate Control */ + /* Bit 28: Reserved */ +#define SIM_SCGC6_RTC (1 << 29) /* Bit 29: RTC Clock Gate Control */ + /* Bit 30: Reserved */ +#define SIM_SCGC6_DAC0 (1 << 31) /* Bit 29: DAC0 Clock Gate Control */ + +/* System Clock Gating Control Register 7 */ + + /* Bits 0-7: Reserved */ +#define SIM_SCGC7_DMA (1 << 8) /* Bit 8: DMA Clock Gate Control */ + /* Bits 9-31: Reserved */ +/* System Clock Divider Register 1 */ + /* Bits 0-15: Reserved */ +#define SIM_CLKDIV1_OUTDIV4_SHIFT (16) /* Bits 16-18: Clock 4 output divider value */ +#define SIM_CLKDIV1_OUTDIV4_MASK (7 << SIM_CLKDIV1_OUTDIV4_SHIFT) +# define SIM_CLKDIV1_OUTDIV4(n) (((n)-1) << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV4_1 (0 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV4_2 (1 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV4_3 (2 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV4_4 (3 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV4_5 (4 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV4_6 (5 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV4_7 (6 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV4_8 (7 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 8 */ + /* Bits 19-27: Reserved */ +#define SIM_CLKDIV1_OUTDIV1_SHIFT (28) /* Bits 28-31: Clock 1 output divider value */ +#define SIM_CLKDIV1_OUTDIV1_MASK (15 << SIM_CLKDIV1_OUTDIV1_SHIFT) +# define SIM_CLKDIV1_OUTDIV1(n) (((n)-1) << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by n, n=1..16 */ +# define SIM_CLKDIV1_OUTDIV1_1 (0 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 1 */ +# define SIM_CLKDIV1_OUTDIV1_2 (1 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 2 */ +# define SIM_CLKDIV1_OUTDIV1_3 (2 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 3 */ +# define SIM_CLKDIV1_OUTDIV1_4 (3 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 4 */ +# define SIM_CLKDIV1_OUTDIV1_5 (4 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 5 */ +# define SIM_CLKDIV1_OUTDIV1_6 (5 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 6 */ +# define SIM_CLKDIV1_OUTDIV1_7 (6 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 7 */ +# define SIM_CLKDIV1_OUTDIV1_8 (7 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 8 */ +# define SIM_CLKDIV1_OUTDIV1_9 (8 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 9 */ +# define SIM_CLKDIV1_OUTDIV1_10 (9 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 10 */ +# define SIM_CLKDIV1_OUTDIV1_11 (10 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 11 */ +# define SIM_CLKDIV1_OUTDIV1_12 (11 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 12 */ +# define SIM_CLKDIV1_OUTDIV1_13 (12 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 13 */ +# define SIM_CLKDIV1_OUTDIV1_14 (13 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 14 */ +# define SIM_CLKDIV1_OUTDIV1_15 (14 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 15 */ +# define SIM_CLKDIV1_OUTDIV1_16 (15 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 16 */ + +/* Flash Configuration Register 1 */ + +#define SIM_FCFG1_FLASHDIS (1 << 0) /* Bit 0: Flash Disable */ +#define SIM_FCFG1_FLASHDOZE (1 << 1) /* Bit 1: Flash Doze */ + /* Bits 2-23: Reserved */ +#define SIM_FCFG1_PFSIZE_SHIFT (24) /* Bits 24-27: Program flash size */ +#define SIM_FCFG1_PFSIZE_MASK (15 << SIM_FCFG1_PFSIZE_SHIFT) +# define SIM_FCFG1_PFSIZE_8KB (0 << SIM_FCFG1_PFSIZE_SHIFT) /* 8 KB of program flash memory, + * 0.25 KB protection region */ +# define SIM_FCFG1_PFSIZE_16KB (1 << SIM_FCFG1_PFSIZE_SHIFT) /* 16 KB of program flash memory, + * 0.5 KB protection region */ +# define SIM_FCFG1_PFSIZE_32KB (3 << SIM_FCFG1_PFSIZE_SHIFT) /* 32 KB of program flash memory, + * 1 KB protection region */ +# define SIM_FCFG1_PFSIZE_64KB (5 << SIM_FCFG1_PFSIZE_SHIFT) /* 64 KB of program flash memory, + * 2 KB protection region */ +# define SIM_FCFG1_PFSIZE_128KB (7 << SIM_FCFG1_PFSIZE_SHIFT) /* 128 KB of program flash memory, + * 4 KB protection region */ +# define SIM_FCFG1_PFSIZE_256KB (9 << SIM_FCFG1_PFSIZE_SHIFT) /* 256 KB of program flash memory, + * 8 KB protection region */ + /* Bits 28-31: Reserved */ +/* Flash Configuration Register 2 */ + /* Bits 0-15: Reserved */ +#define SIM_FCFG2_MAXADDR0_SHIFT (24) /* Bits 24-30: Max address block */ +#define SIM_FCFG2_MAXADDR0_MASK (0x7f << SIM_FCFG2_MAXADDR0_SHIFT) + /* Bit 31: Reserved */ + +/* Unique Identification Register High. 16-bit Unique Identification. */ +/* Unique Identification Register Mid-High. 32-bit Unique Identification. */ +/* Unique Identification Register Mid Low. 32-bit Unique Identification. */ +/* Unique Identification Register Low. 32-bit Unique Identification. */ + +/* COP Control Register */ + +#define SIM_COPC_COPW (1 << 0) /* Bit 2: COP windowed mode */ +#define SIM_COPC_COPCLKS (1 << 1) /* Bit 1: COP Clock Select */ +#define SIM_COPC_COPT_SHIFT (2) /* Bits 2-3: COP Watchdog Timeout */ +#define SIM_COPC_COPT_MASK (3 << SIM_COPC_COPT_SHIFT) +# define SIM_COPC_COPT_DISABLED (0 << SIM_COPC_COPT_SHIFT) /* COP disabled */ +# define SIM_COPC_COPT_TO13 (1 << SIM_COPC_COPT_SHIFT) /* COP timeout after 2^5 LPO cycles or + * 2^13 bus clock cycles */ +# define SIM_COPC_COPT_TO16 (2 << SIM_COPC_COPT_SHIFT) /* COP timeout after 2^8 LPO cycles or + * 2^16 bus clock cycles */ +# define SIM_COPC_COPT_TO18 (3 << SIM_COPC_COPT_SHIFT) /* COP timeout after 2^10 LPO cycles or + * 2^18 bus clock cycles */ + +/* Service COP Register. 8-bit value. */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +#endif /* __ARCH_ARM_SRC_KL_KL_SIM_H */ diff --git a/arch/arm/src/kl/chip/kl_spi.h b/arch/arm/src/kl/chip/kl_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..f24633457b799a01c3a9cff1c43c2ea1d8c0a379 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_spi.h @@ -0,0 +1,139 @@ +/******************************************************************************************** + * arch/arm/src/kl/kl_spi.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_CHIP_KL_SPI_H +#define __ARCH_ARM_SRC_KL_CHIP_KL_SPI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register Offsets *************************************************************************/ + +#define KL_SPI_C1_OFFSET 0x0000 /* SPI control register 1 */ +#define KL_SPI_C2_OFFSET 0x0001 /* SPI control register 2 */ +#define KL_SPI_BR_OFFSET 0x0002 /* SPI baud rate register */ +#define KL_SPI_S_OFFSET 0x0003 /* SPI status register */ +#define KL_SPI_D_OFFSET 0x0005 /* SPI data register */ +#define KL_SPI_M_OFFSET 0x0007 /* SPI match register */ + +/* Register Addresses ***********************************************************************/ + +#define KL_SPI0_C1 (KL_SPI0_BASE+KL_SPI_C1_OFFSET) +#define KL_SPI0_C2 (KL_SPI0_BASE+KL_SPI_C2_OFFSET) +#define KL_SPI0_BR (KL_SPI0_BASE+KL_SPI_BR_OFFSET) +#define KL_SPI0_S (KL_SPI0_BASE+KL_SPI_S_OFFSET) +#define KL_SPI0_D (KL_SPI0_BASE+KL_SPI_D_OFFSET) +#define KL_SPI0_M (KL_SPI0_BASE+KL_SPI_M_OFFSET) + +#define KL_SPI1_C1 (KL_SPI1_BASE+KL_SPI_C1_OFFSET) +#define KL_SPI1_C2 (KL_SPI1_BASE+KL_SPI_C2_OFFSET) +#define KL_SPI1_BR (KL_SPI1_BASE+KL_SPI_BR_OFFSET) +#define KL_SPI1_S (KL_SPI1_BASE+KL_SPI_S_OFFSET) +#define KL_SPI1_D (KL_SPI1_BASE+KL_SPI_D_OFFSET) +#define KL_SPI1_M (KL_SPI1_BASE+KL_SPI_M_OFFSET) + +/* Register Bit Definitions *****************************************************************/ + +/* SPI control register 1 */ + +#define SPI_C1_LSBFE (1 << 0) /* Bit 0: LSB first (shifter direction) */ +#define SPI_C1_SSOE (1 << 1) /* Bit 1: Slave select output enable */ +#define SPI_C1_CPHA (1 << 2) /* Bit 2: Clock phase */ +#define SPI_C1_CPOL (1 << 3) /* Bit 3: Clock polarity */ +#define SPI_C1_MSTR (1 << 4) /* Bit 4: Master/slave mode select */ +#define SPI_C1_SPTIE (1 << 5) /* Bit 5: SPI transmit interrupt enable */ +#define SPI_C1_SPE (1 << 6) /* Bit 6: SPI system enable */ +#define SPI_C1_SPIE (1 << 7) /* Bit 7: SPI interrupt enable: for SPRF and MODF */ + +/* SPI control register 2 */ + +#define SPI_C2_SPC0 (1 << 0) /* Bit 0: SPI pin control 0 */ +#define SPI_C2_SPISWAI (1 << 1) /* Bit 1: SPI stop in wait mode */ +#define SPI_C2_RXDMAE (1 << 2) /* Bit 2: Receive DMA enable */ +#define SPI_C2_BIDIROE (1 << 3) /* Bit 3: Bidirectional mode output enable */ +#define SPI_C2_MODFEN (1 << 4) /* Bit 4: Master mode-fault function enable */ +#define SPI_C2_TXDMAE (1 << 5) /* Bit 5: Transmit DMA enable */ +#define SPI_C2_SPMIE (1 << 7) /* Bit 7: SPI match interrupt enable */ + +/* SPI baud rate register */ + +#define SPI_BR_SPR_SHIFT (0) /* Bits 0-3: SPI baud rate divisor */ +#define SPI_BR_SPR_MASK (15 << SPI_BR_SPR_SHIFT) +# define SPI_BR_SPR_DIV(n) (((n)-1) << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 2^(n-1) */ +# define SPI_BR_SPR_DIV2 (0 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 2 */ +# define SPI_BR_SPR_DIV4 (1 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 4 */ +# define SPI_BR_SPR_DIV8 (2 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 8 */ +# define SPI_BR_SPR_DIV16 (3 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 16 */ +# define SPI_BR_SPR_DIV32 (4 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 32 */ +# define SPI_BR_SPR_DIV64 (5 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 64 */ +# define SPI_BR_SPR_DIV128 (6 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 128 */ +# define SPI_BR_SPR_DIV256 (7 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 256 */ +# define SPI_BR_SPR_DIV512 (8 << SPI_BR_SPR_SHIFT) /* Baud rate divisor is 512 */ +#define SPI_BR_SPPR_SHIFT (4) /* Bits 4-6: SPI baud rate prescale divisor */ +#define SPI_BR_SPPR_MASK (7 << SPI_BR_SPPR_SHIFT) +# define SPI_BR_SPPR(n) (((n)-1) << SPI_BR_SPPR_SHIFT) /* Prescaler=n, n=1-8 */ + /* Bit 7: Reserved */ +/* SPI status register */ + /* Bits 0-3: Reserved */ +#define SPI_S_MODF (1 << 4) /* Bit 4: Master mode fault flag */ +#define SPI_S_SPTEF (1 << 5) /* Bit 5: SPI transmit buffer empty flag */ +#define SPI_S_SPMF (1 << 6) /* Bit 6: SPI match flag */ +#define SPI_S_SPRF (1 << 7) /* Bit 7: SPI read buffer full flag */ + +/* SPI data register (8-bit data, low byte) */ +/* SPI match register (8-bit match value) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_CHIP_KL_SPI_H */ diff --git a/arch/arm/src/kl/chip/kl_tpm.h b/arch/arm/src/kl/chip/kl_tpm.h new file mode 100644 index 0000000000000000000000000000000000000000..9f898ba1feb58b6887a13bc9df8596eee1f83e78 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_tpm.h @@ -0,0 +1,211 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_tpm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_TPM_H +#define __ARCH_ARM_SRC_KL_KL_TPM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "kl_config.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +#define TPM_SC_OFFSET 0x0000 /* Status and Control offset*/ +#define TPM_CNT_OFFSET 0x0004 /* Counter offset */ +#define TPM_MOD_OFFSET 0x0008 /* Modulo offset */ +#define TPM_C0SC_OFFSET 0x000C /* Channel 0 Status and Control offset */ +#define TPM_C0V_OFFSET 0x0010 /* Channel 0 Value offset */ +#define TPM_C1SC_OFFSET 0x0014 /* Channel 1 Status and Control offset */ +#define TPM_C1V_OFFSET 0x0018 /* Channel 1 Value offset */ +#define TPM_C2SC_OFFSET 0x001C /* Channel 2 Status and Control offset */ +#define TPM_C2V_OFFSET 0x0020 /* Channel 2 Value offset */ +#define TPM_C3SC_OFFSET 0x0024 /* Channel 3 Status and Control offset */ +#define TPM_C3V_OFFSET 0x0028 /* Channel 3 Value offset */ +#define TPM_C4SC_OFFSET 0x002C /* Channel 4 Status and Control offset */ +#define TPM_C4V_OFFSET 0x0030 /* Channel 4 Value offset */ +#define TPM_C5SC_OFFSET 0x0034 /* Channel 5 Status and Control offset */ +#define TPM_C5V_OFFSET 0x0038 /* Channel 5 Value offset */ +#define TPM_STATUS_OFFSET 0x0050 /* Capture and Compare Status offset */ +#define TPM_CONF_OFFSET 0x0084 /* Configuration offset */ + +#define TPM0_SC (KL_TPM0_BASE + TPM_SC_OFFSET) /* TPM0 Status and Control */ +#define TPM0_CNT (KL_TPM0_BASE + TPM_CNT_OFFSET) /* TPM0 Counter */ +#define TPM0_MOD (KL_TPM0_BASE + TPM_MOD_OFFSET) /* TPM0 Modulo */ +#define TPM0_C0SC (KL_TPM0_BASE + TPM_C0SC_OFFSET) /* TPM0 Channel 0 Status and Control */ +#define TPM0_C0V (KL_TPM0_BASE + TPM_C0V_OFFSET) /* TPM0 Channel 0 Value */ +#define TPM0_C1SC (KL_TPM0_BASE + TPM_C1SC_OFFSET) /* TPM0 Channel 1 Status and Control */ +#define TPM0_C1V (KL_TPM0_BASE + TPM_C1V_OFFSET) /* TPM0 Channel 1 Value */ +#define TPM0_C2SC (KL_TPM0_BASE + TPM_C2SC_OFFSET) /* TPM0 Channel 2 Status and Control */ +#define TPM0_C2V (KL_TPM0_BASE + TPM_C2V_OFFSET) /* TPM0 Channel 2 Value */ +#define TPM0_C3SC (KL_TPM0_BASE + TPM_C3SC_OFFSET) /* TPM0 Channel 3 Status and Control */ +#define TPM0_C3V (KL_TPM0_BASE + TPM_C3V_OFFSET) /* TPM0 Channel 3 Value */ +#define TPM0_C4SC (KL_TPM0_BASE + TPM_C4SC_OFFSET) /* TPM0 Channel 4 Status and Control */ +#define TPM0_C4V (KL_TPM0_BASE + TPM_C4V_OFFSET) /* TPM0 Channel 4 Value */ +#define TPM0_C5SC (KL_TPM0_BASE + TPM_C5SC_OFFSET) /* TPM0 Channel 5 Status and Control */ +#define TPM0_C5V (KL_TPM0_BASE + TPM_C5V_OFFSET) /* TPM0 Channel 5 Value */ +#define TPM0_STATUS (KL_TPM0_BASE + TPM_STATUS_OFFSET) /* TPM0 Capture and Compare Status */ +#define TPM0_CONF (KL_TPM0_BASE + TPM_CONF_OFFSET) /* TPM0 Configuration */ + +#define TPM1_SC (KL_TPM1_BASE + TPM_SC_OFFSET) /* TPM1 Status and Control */ +#define TPM1_CNT (KL_TPM1_BASE + TPM_CNT_OFFSET) /* TPM1 Counter */ +#define TPM1_MOD (KL_TPM1_BASE + TPM_MOD_OFFSET) /* TPM1 Modulo */ +#define TPM1_C0SC (KL_TPM1_BASE + TPM_C0SC_OFFSET) /* TPM1 Channel 0 Status and Control */ +#define TPM1_C0V (KL_TPM1_BASE + TPM_C0V_OFFSET) /* TPM1 Channel 0 Value */ +#define TPM1_C1SC (KL_TPM1_BASE + TPM_C1SC_OFFSET) /* TPM1 Channel 1 Status and Control */ +#define TPM1_C1V (KL_TPM1_BASE + TPM_C1V_OFFSET) /* TPM1 Channel 1 Value */ +#define TPM1_C2SC (KL_TPM1_BASE + TPM_C2SC_OFFSET) /* TPM1 Channel 2 Status and Control */ +#define TPM1_C2V (KL_TPM1_BASE + TPM_C2V_OFFSET) /* TPM1 Channel 2 Value */ +#define TPM1_C3SC (KL_TPM1_BASE + TPM_C3SC_OFFSET) /* TPM1 Channel 3 Status and Control */ +#define TPM1_C3V (KL_TPM1_BASE + TPM_C3V_OFFSET) /* TPM1 Channel 3 Value */ +#define TPM1_C4SC (KL_TPM1_BASE + TPM_C4SC_OFFSET) /* TPM1 Channel 4 Status and Control */ +#define TPM1_C4V (KL_TPM1_BASE + TPM_C4V_OFFSET) /* TPM1 Channel 4 Value */ +#define TPM1_C5SC (KL_TPM1_BASE + TPM_C5SC_OFFSET) /* TPM1 Channel 5 Status and Control */ +#define TPM1_C5V (KL_TPM1_BASE + TPM_C5V_OFFSET) /* TPM1 Channel 5 Value */ +#define TPM1_STATUS (KL_TPM1_BASE + TPM_STATUS_OFFSET) /* TPM1 Capture and Compare Status */ +#define TPM1_CONF (KL_TPM1_BASE + TPM_CONF_OFFSET) /* TPM1 Configuration */ + +#define TPM2_SC (KL_TPM2_BASE + TPM_SC_OFFSET) /* TPM2 Status and Control */ +#define TPM2_CNT (KL_TPM2_BASE + TPM_CNT_OFFSET) /* TPM2 Counter */ +#define TPM2_MOD (KL_TPM2_BASE + TPM_MOD_OFFSET) /* TPM2 Modulo */ +#define TPM2_C0SC (KL_TPM2_BASE + TPM_C0SC_OFFSET) /* TPM2 Channel 0 Status and Control */ +#define TPM2_C0V (KL_TPM2_BASE + TPM_C0V_OFFSET) /* TPM2 Channel 0 Value */ +#define TPM2_C1SC (KL_TPM2_BASE + TPM_C1SC_OFFSET) /* TPM2 Channel 1 Status and Control */ +#define TPM2_C1V (KL_TPM2_BASE + TPM_C1V_OFFSET) /* TPM2 Channel 1 Value */ +#define TPM2_C2SC (KL_TPM2_BASE + TPM_C2SC_OFFSET) /* TPM2 Channel 2 Status and Control */ +#define TPM2_C2V (KL_TPM2_BASE + TPM_C2V_OFFSET) /* TPM2 Channel 2 Value */ +#define TPM2_C3SC (KL_TPM2_BASE + TPM_C3SC_OFFSET) /* TPM2 Channel 3 Status and Control */ +#define TPM2_C3V (KL_TPM2_BASE + TPM_C3V_OFFSET) /* TPM2 Channel 3 Value */ +#define TPM2_C4SC (KL_TPM2_BASE + TPM_C4SC_OFFSET) /* TPM2 Channel 4 Status and Control */ +#define TPM2_C4V (KL_TPM2_BASE + TPM_C4V_OFFSET) /* TPM2 Channel 4 Value */ +#define TPM2_C5SC (KL_TPM2_BASE + TPM_C5SC_OFFSET) /* TPM2 Channel 5 Status and Control */ +#define TPM2_C5V (KL_TPM2_BASE + TPM_C5V_OFFSET) /* TPM2 Channel 5 Value */ +#define TPM2_STATUS (KL_TPM2_BASE + TPM_STATUS_OFFSET) /* TPM2 Capture and Compare Status */ +#define TPM2_CONF (KL_TPM2_BASE + TPM_CONF_OFFSET) /* TPM2 Configuration */ + +#define TPM_SC_PS_SHIFT 0 /* Bits 0-2: Prescale Factor Selection */ + +#define TPM_SC_PS_MASK (7 << TPM_SC_PS_SHIFT) +# define TPM_SC_PS_DIV1 (0 << TPM_SC_PS_SHIFT) /* Divide Clock by 1 */ +# define TPM_SC_PS_DIV2 (1 << TPM_SC_PS_SHIFT) /* Divide Clock by 2 */ +# define TPM_SC_PS_DIV4 (2 << TPM_SC_PS_SHIFT) /* Divide Clock by 4 */ +# define TPM_SC_PS_DIV8 (3 << TPM_SC_PS_SHIFT) /* Divide Clock by 8 */ +# define TPM_SC_PS_DIV16 (4 << TPM_SC_PS_SHIFT) /* Divide Clock by 16 */ +# define TPM_SC_PS_DIV32 (5 << TPM_SC_PS_SHIFT) /* Divide Clock by 32 */ +# define TPM_SC_PS_DIV64 (6 << TPM_SC_PS_SHIFT) /* Divide Clock by 64 */ +# define TPM_SC_PS_DIV128 (7 << TPM_SC_PS_SHIFT) /* Divide Clock by 128 */ + +#define TPM_SC_CMOD_SHIFT 3 /* Bits 3-4: Clock Mode Selection */ + +#define TPM_SC_CMOD_MASK (3 << TPM_SC_CMOD_SHIFT) +# define TPM_SC_CMOD_DIS (0 << TPM_SC_CMOD_SHIFT) /* TPM counter is disabled */ +# define TPM_SC_CMOD_LPTPM_CLK (1 << TPM_SC_CMOD_SHIFT) /* TPM increments on every counter clock */ +# define TPM_SC_CMOD_LPTPM_EXTCLK (2 << TPM_SC_CMOD_SHIFT) /* TPM increments on rising edge of EXTCLK */ +# define TPM_SC_CMOD_RESERV (3 << TPM_SC_CMOD_SHIFT) /* Reserved */ + +#define TPM_SC_CPWMS (1 << 5) /* Bit 5: Center-aligned PWM Select */ +#define TPM_SC_TOIE (1 << 6) /* Bit 6: Timer Overflow Interrupt Enable */ +#define TPM_SC_TOF (1 << 7) /* Bit 7: Timer Overflow Flag*/ +#define TPM_SC_DMA (1 << 8) /* Bit 8: DMA Enable*/ + +#define TPM_CnSC_DMA (1 << 0) /* Bit 0: Enables DMA transfers for the channel */ + /* Bit 1: Reserved*/ +#define TPM_CnSC_ELSA (1 << 2) /* Bit 2: Edge or Level Select */ +#define TPM_CnSC_ELSB (1 << 3) /* Bit 3: Edge or Level Select */ +#define TPM_CnSC_MSA (1 << 4) /* Bit 4: Channel Mode Select */ +#define TPM_CnSC_MSB (1 << 5) /* Bit 5: Channel Mode Select */ +#define TPM_CnSC_CHIE (1 << 6) /* Bit 6: Channel Interrupt Enable */ +#define TPM_CnSC_CHF (1 << 7) /* Bit 7: Channel Flag */ + /* Bits 8-31: Reserved */ + +#define TPM_STATUS_CH0F (1 << 0) /* Bit 0: Channel 0 Flag */ +#define TPM_STATUS_CH1F (1 << 1) /* Bit 1: Channel 1 Flag */ +#define TPM_STATUS_CH2F (1 << 2) /* Bit 2: Channel 2 Flag */ +#define TPM_STATUS_CH3F (1 << 3) /* Bit 3: Channel 3 Flag */ +#define TPM_STATUS_CH4F (1 << 4) /* Bit 4: Channel 4 Flag */ +#define TPM_STATUS_CH5F (1 << 5) /* Bit 5: Channel 5 Flag */ + /* Bits 6-7: Reserved */ +#define TPM_STATUS_TOF (1 << 8) /* Bit 8: Timer Overflow Flag */ + + +#define TPM_CONF_DOZEEN 5 /* Bit 5: Doze Enable */ +#define TPM_CONF_DBGMODE_SHIFT 6 /* Bits 6-7: Debug Mode */ +#define TPM_CONF_DBGMODE_MASK (3 << TPM_DBGMODE_SHIFT) +# define TPM_CONF_DBGMODE_PAUSE (0 << TPM_DBGMODE_SHIFT) /* TPM counter will pause during DEBUG mode */ +# define TPM_CONF_DBGMODE_CONT (3 << TPM_DBGMODE_SHIFT) /* TPM counter continue working in DEBUG mode */ + /* Bit 8: Reserved */ +#define TPM_CONF_GTBEEN (1 << 9) /* Bit 9: Global Time Base Enable */ + /* Bits 10-15: Reserved */ +#define TPM_CONF_CSOT (1 << 16) /* Bit 16: Counter Start On Trigger */ +#define TPM_CONF_CSOO (1 << 17) /* Bit 17: Counter Stop On Overflow */ +#define TPM_CONF_CROT (1 << 18) /* Bit 18: Counter Reload On Trigger */ + /* Bits 19-23: Reserved */ +#define TPM_CONF_TRGSEL_SHIFT 24 +#define TPM_CONF_TRGSEL_MASK (15 << TPM_CONF_TRGSEL_SHIFT) +# define TPM_CONF_TRGSEL_EXTRG_IN (0 << TPM_CONF_TRGSEL_SHIFT) /* External trigger pin input */ +# define TPM_CONF_TRGSEL_CMP0 (1 << TPM_CONF_TRGSEL_SHIFT) /* CPM0 output */ + /*(2 << TPM_CONF_TRGSEL_SHIFT) Reserved */ + /*(3 << TPM_CONF_TRGSEL_SHIFT) Reserved */ +# define TPM_CONF_TRGSEL_PIT0 (4 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 0 */ +# define TPM_CONF_TRGSEL_PIT1 (5 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 1 */ + /*(6 << TPM_CONF_TRGSEL_SHIFT) Reserved */ + /*(7 << TPM_CONF_TRGSEL_SHIFT) Reserved */ +# define TPM_CONF_TRGSEL_TPM0 (8 << TPM_CONF_TRGSEL_SHIFT) /* TPM0 Overflow */ +# define TPM_CONF_TRGSEL_TPM1 (9 << TPM_CONF_TRGSEL_SHIFT) /* TPM1 Overflow */ +# define TPM_CONF_TRGSEL_TPM2 (10 << TPM_CONF_TRGSEL_SHIFT) /* TPM1 Overflow */ + /*(11 << TPM_CONF_TRGSEL_SHIFT) Reserved */ +# define TPM_CONF_TRGSEL_RTC_ALRM (12 << TPM_CONF_TRGSEL_SHIFT) /* RTC Alarm */ +# define TPM_CONF_TRGSEL_RTC_SECS (13 << TPM_CONF_TRGSEL_SHIFT) /* RTC Seconds */ +# define TPM_CONF_TRGSEL_LPTMR (14 << TPM_CONF_TRGSEL_SHIFT) /* LPTMR trigger */ + /*(15 << TPM_CONF_TRGSEL_SHIFT) Reserved */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_KL_TPM_H */ diff --git a/arch/arm/src/kl/chip/kl_tsi.h b/arch/arm/src/kl/chip/kl_tsi.h new file mode 100644 index 0000000000000000000000000000000000000000..8e0d87e905b4a39669963290ef40de50ca4780cf --- /dev/null +++ b/arch/arm/src/kl/chip/kl_tsi.h @@ -0,0 +1,154 @@ +/************************************************************************************ + * arch/arm/src/kl/chip/kl_tsi.h + * + * Copyright (C) 2013 Alan Carvalho de Assis + * Author: Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_CHIP_KL_TSI_H +#define __ARCH_ARM_SRC_KL_CHIP_KL_TSI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KL_TSI_GENCS_OFFSET 0x0000 /* General Control and Status Register */ +#define KL_TSI_DATA_OFFSET 0x0004 /* SCAN control register */ +#define KL_TSI_TSHD_OFFSET 0x0008 /* Pin enable register */ + +/* Register Addresses ***************************************************************/ + +#define KL_TSI_GENCS (KL_TSI_BASE+KL_TSI_GENCS_OFFSET) +#define KL_TSI_DATA (KL_TSI_BASE+KL_TSI_DATA_OFFSET) +#define KL_TSI_TSHD (KL_TSI_BASE+KL_TSI_TSHD_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* General Control and Status Register */ + /* Bit 0: Reserved */ +#define TSI_GENCS_CURSW (1 << 1) /* Bit 1: Current sources for oscillators swapped */ +#define TSI_GENCS_EOSF (1 << 2) /* Bit 2: End of scan flag */ +#define TSI_GENCS_SCNIP (1 << 3) /* Bit 3: Scan in progress status */ +#define TSI_GENCS_STM (1 << 4) /* Bit 4: Scan trigger mode */ +#define TSI_GENCS_STPE (1 << 5) /* Bit 5: TSI STOP enable */ +#define TSI_GENCS_TSIIEN (1 << 6) /* Bit 6: TSI module interrupt enable */ +#define TSI_GENCS_TSIEN (1 << 7) /* Bit 7: TSI module enable */ +#define TSI_GENCS_NSCN_SHIFT (8) /* Bits 8-12: Electrode oscillator count used in a scan */ +#define TSI_GENCS_NSCN_MASK (31 << TSI_GENCS_NSCN_SHIFT) +# define TSI_GENCS_NSCN_TIMES(n) (((n)-1) << TSI_GENCS_NSCN_SHIFT) /* n times per electrode,n=1..32 */ +#define TSI_GENCS_PS_SHIFT (13) /* Bits 13-15: Prescaler value */ +#define TSI_GENCS_PS_MASK (7 << TSI_GENCS_PS_SHIFT) +# define TSI_GENCS_PS_DIV1 (0 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 1 */ +# define TSI_GENCS_PS_DIV2 (1 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 2 */ +# define TSI_GENCS_PS_DIV4 (2 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 4 */ +# define TSI_GENCS_PS_DIV8 (3 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 8 */ +# define TSI_GENCS_PS_DIV16 (4 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 16 */ +# define TSI_GENCS_PS_DIV32 (5 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 32 */ +# define TSI_GENCS_PS_DIV64 (6 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 64 */ +# define TSI_GENCS_PS_DIV128 (7 << TSI_GENCS_PS_SHIFT) /* Electrode oscillator / 128 */ +#define TSI_GENCS_EXTCHRG_SHIFT (16) /* Bits 16-18: Electrode Osc charge/discharge value */ +#define TSI_GENCS_EXTCHRG_MASK (7 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_500NA (0 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_1UA (1 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_2UA (2 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_4UA (3 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_8UA (4 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_16UA (5 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_32UA (6 << TSI_GENCS_EXTCHRG_SHIFT) +# define TSI_GENCS_EXTCHRG_64A (7 << TSI_GENCS_EXTCHRG_SHIFT) +#define TSI_GENCS_DVOLT_SHIFT (19) /* Bits 19-20: Oscilattor voltage rails */ +#define TSI_GENCS_DVOLT_MASK (3 << TSI_GENCS_DVOLT_SHIFT) +# define TSI_GENCS_DVOLT_1p03V (0 << TSI_GENCS_DVOLT_SHIFT) +# define TSI_GENCS_DVOLT_0p73V (1 << TSI_GENCS_DVOLT_SHIFT) +# define TSI_GENCS_DVOLT_0p43V (2 << TSI_GENCS_DVOLT_SHIFT) +# define TSI_GENCS_DVOLT_0p29V (3 << TSI_GENCS_DVOLT_SHIFT) +#define TSI_GENCS_REFCHRG_SHIFT (21) /* Bits 21-23: Reference Osc charge/discharge value */ +#define TSI_GENCS_REFCHRG_MASK (7 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_500NA (0 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_1UA (1 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_2UA (2 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_4UA (3 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_8UA (4 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_16UA (5 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_32UA (6 << TSI_GENCS_REFCHRG_SHIFT) +# define TSI_GENCS_REFCHRG_64UA (7 << TSI_GENCS_REFCHRG_SHIFT) +#define TSI_GENCS_MODE_SHIFT (24) /* Bits 24-27: Analog mode setup and status bits */ +#define TSI_GENCS_MODE_MASK (15 << TSI_GENCS_MODE_SHIFT) +# define TSI_GENCS_MODE_CAPSENSING (0 << TSI_GENCS_MODE_SHIFT) +# define TSI_GENCS_MODE_SGTSHD_NOFREQ (4 << TSI_GENCS_MODE_SHIFT) +# define TSI_GENCS_MODE_SGTSHD_FRQLIM (8 << TSI_GENCS_MODE_SHIFT) +# define TSI_GENCS_MODE_AUTODETECT (12 << TSI_GENCS_MODE_SHIFT) +#define TSI_GENCS_ESOR (1 << 28) /* Bit 28: End/Out-of-range interrupt selection */ + /* Bits 29-30: Reserved */ +#define TSI_GENCS_OUTRFG (1 << 31) /* Bit 31: Out of range flag */ + +/* SCAN control register */ + +#define TSI_DATA_TSICNT_SHIFT (0) /* Bits 0-15: TSI Conversion counter value */ +#define TSI_DATA_TSICNT_MASK (0xffff << TSI_DATA_TSICNT_SHIFT) + /* Bits 16-21: Reserved */ +#define TSI_DATA_SWTS (1 << 22) /* Bit 22: Software trigger start */ +#define TSI_DATA_DMAEN (1 << 23) /* Bit 23: DMA Transfer enabled */ + /* Bits 24-27: Reserved */ +#define TSI_DATA_TSICH_SHIFT (28) /* Bits 28-31: Current channel to be measured */ +#define TSI_DATA_TSICH_MASK (15 << TSI_DATA_TSICH_SHIFT) +# define TSI_DATA_TSICH(n) (n << TSI_DATA_TSICH_SHIFT) /* Channel to measure, n=0..15 */ + +/* Channel n threshold register */ + +#define TSI_THRESHLD_HTHH_SHIFT (0) /* Bits 0-15: High threshold value */ +#define TSI_THRESHLD_HTHH_MASK (0xffff << TSI_THRESHLD_HTHH_SHIFT) +#define TSI_THRESHLD_LTHH_SHIFT (16) /* Bits 16-31: Low threshold value */ +#define TSI_THRESHLD_LTHH_MASK (0xffff << TSI_THRESHLD_LTHH_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KL_CHIP_KL_TSI_H */ diff --git a/arch/arm/src/kl/chip/kl_uart.h b/arch/arm/src/kl/chip/kl_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..9b0cf80bae5b5ebe779e243038010f5b4c741ab2 --- /dev/null +++ b/arch/arm/src/kl/chip/kl_uart.h @@ -0,0 +1,222 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_uart.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_UART_H +#define __ARCH_ARM_SRC_KL_KL_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "kl_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define KL_UART_BDH_OFFSET 0x0000 /* UART Baud Rate Register High */ +#define KL_UART_BDL_OFFSET 0x0001 /* UART Baud Rate Register Low */ +#define KL_UART_C1_OFFSET 0x0002 /* UART Control Register 1 */ +#define KL_UART_C2_OFFSET 0x0003 /* UART Control Register 2 */ +#define KL_UART_S1_OFFSET 0x0004 /* UART Status Register 1 */ +#define KL_UART_S2_OFFSET 0x0005 /* UART Status Register 2 */ +#define KL_UART_C3_OFFSET 0x0006 /* UART Control Register 3 */ +#define KL_UART_D_OFFSET 0x0007 /* UART Data Register */ +#define KL_UART_MA1_OFFSET 0x0008 /* UART Match Address Registers 1 (UART0)*/ +#define KL_UART_MA2_OFFSET 0x0009 /* UART Match Address Registers 2 (UART0)*/ +#define KL_UART_C4_OFFSET 0x000a /* UART Control Register 4 */ +#define KL_UART_C5_OFFSET 0x000b /* UART Control Register 5 (UART0) */ + +/* Register Addresses ***************************************************************/ + +#if (KL_NUART) > 0 +# define KL_UART0_BDH (KL_UART0_BASE+KL_UART_BDH_OFFSET) +# define KL_UART0_BDL (KL_UART0_BASE+KL_UART_BDL_OFFSET) +# define KL_UART0_C1 (KL_UART0_BASE+KL_UART_C1_OFFSET) +# define KL_UART0_C2 (KL_UART0_BASE+KL_UART_C2_OFFSET) +# define KL_UART0_S1 (KL_UART0_BASE+KL_UART_S1_OFFSET) +# define KL_UART0_S2 (KL_UART0_BASE+KL_UART_S2_OFFSET) +# define KL_UART0_C3 (KL_UART0_BASE+KL_UART_C3_OFFSET) +# define KL_UART0_D (KL_UART0_BASE+KL_UART_D_OFFSET) +# define KL_UART0_MA1 (KL_UART0_BASE+KL_UART_MA1_OFFSET) +# define KL_UART0_MA2 (KL_UART0_BASE+KL_UART_MA2_OFFSET) +# define KL_UART0_C4 (KL_UART0_BASE+KL_UART_C4_OFFSET) +# define KL_UART0_C5 (KL_UART0_BASE+KL_UART_C5_OFFSET) +#endif + +#if (KL_NUART) > 1 +# define KL_UART1_BDH (KL_UART1_BASE+KL_UART_BDH_OFFSET) +# define KL_UART1_BDL (KL_UART1_BASE+KL_UART_BDL_OFFSET) +# define KL_UART1_C1 (KL_UART1_BASE+KL_UART_C1_OFFSET) +# define KL_UART1_C2 (KL_UART1_BASE+KL_UART_C2_OFFSET) +# define KL_UART1_S1 (KL_UART1_BASE+KL_UART_S1_OFFSET) +# define KL_UART1_S2 (KL_UART1_BASE+KL_UART_S2_OFFSET) +# define KL_UART1_C3 (KL_UART1_BASE+KL_UART_C3_OFFSET) +# define KL_UART1_D (KL_UART1_BASE+KL_UART_D_OFFSET) +# define KL_UART1_C4 (KL_UART1_BASE+KL_UART_C4_OFFSET) +#endif + +#if (KL_NUART) > 2 +# define KL_UART2_BDH (KL_UART2_BASE+KL_UART_BDH_OFFSET) +# define KL_UART2_BDL (KL_UART2_BASE+KL_UART_BDL_OFFSET) +# define KL_UART2_C1 (KL_UART2_BASE+KL_UART_C1_OFFSET) +# define KL_UART2_C2 (KL_UART2_BASE+KL_UART_C2_OFFSET) +# define KL_UART2_S1 (KL_UART2_BASE+KL_UART_S1_OFFSET) +# define KL_UART2_S2 (KL_UART2_BASE+KL_UART_S2_OFFSET) +# define KL_UART2_C3 (KL_UART2_BASE+KL_UART_C3_OFFSET) +# define KL_UART2_D (KL_UART2_BASE+KL_UART_D_OFFSET) +# define KL_UART2_C4 (KL_UART2_BASE+KL_UART_C4_OFFSET) +#endif + +/* Register Bit Definitions *********************************************************/ +/* UART Baud Rate Register High */ + +#define UART_BDH_SBR_SHIFT (0) /* Bits 0-4: MS Bits 8-13 of the UART Baud Rate Bits */ +#define UART_BDH_SBR_MASK (31 << UART_BDH_SBR_SHIFT) +# define UART_BDH_SBR(x) (((uint8_t)(((uint8_t)(x))< + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uint8_t _cfmconfig[16] __attribute__((section(".cfmconfig"))) = +{ + 0xff, /* NV_BACKKEY3: KEY=0xff */ + 0xff, /* NV_BACKKEY2: KEY=0xff */ + 0xff, /* NV_BACKKEY1: KEY=0xff */ + 0xff, /* NV_BACKKEY0: KEY=0xff */ + 0xff, /* NV_BACKKEY7: KEY=0xff */ + 0xff, /* NV_BACKKEY6: KEY=0xff */ + 0xff, /* NV_BACKKEY5: KEY=0xff */ + 0xff, /* NV_BACKKEY4: KEY=0xff */ + 0xff, /* NV_FPROT3: PROT=0xff */ + 0xff, /* NV_FPROT2: PROT=0xff */ + 0xff, /* NV_FPROT1: PROT=0xff */ + 0xff, /* NV_FPROT0: PROT=0xff */ + 0x7E, /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */ + 0xff, /* NV_FOPT: ??=1,??=1,FAST_INIT=1,LPBOOT1=1,RESET_PIN_CFG=1, + * NMI_DIS=1,EZPORT_DIS=1,LPBOOT0=1 */ + 0xff, + 0xff +}; diff --git a/arch/arm/src/kl/kl_clockconfig.c b/arch/arm/src/kl/kl_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..b414500f2cd1febb8b71f988403964c26b28c11f --- /dev/null +++ b/arch/arm/src/kl/kl_clockconfig.c @@ -0,0 +1,245 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_clockconfig.c + * arch/arm/src/chip/kl_clockconfig.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "kl_gpio.h" +#include "chip/kl_mcg.h" +#include "chip/kl_sim.h" +#include "chip/kl_osc.h" +#include "chip/kl_fmc.h" +#include "chip/kl_llwu.h" +#include "chip/kl_pinmux.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_portclocks + * + * Description: + * Enable all of the port clocks + * + ****************************************************************************/ + +static inline void kl_portclocks(void) +{ + uint32_t regval; + + /* Enable all of the port clocks */ + + regval = getreg32(KL_SIM_SCGC5); + regval |= (SIM_SCGC5_PORTA | SIM_SCGC5_PORTB | SIM_SCGC5_PORTC | + SIM_SCGC5_PORTD | SIM_SCGC5_PORTE); + putreg32(regval, KL_SIM_SCGC5); +} + +/**************************************************************************** + * Name: kl_pllconfig + * + * Description: + * Initialize the PLL using the settings in board.h. This assumes that + * the MCG is in default FLL Engaged Internal (FEI mode) out of reset. + * + ****************************************************************************/ + +void kl_pllconfig(void) +{ + uint32_t regval32; + uint8_t regval8; + + /* Enable clock gate to Port A module to enable pin routing (PORTA=1) */ + + regval32 = getreg32(KL_SIM_SCGC5); + regval32 |= SIM_SCGC5_PORTA; + putreg32(regval32, KL_SIM_SCGC5); + + /* Divide-by-2 for clock 1 and clock 4. OUTDIV1 and OUTDIV4 determined by + * settings in the board.h header file. + */ + + regval32 = (SIM_CLKDIV1_OUTDIV1(BOARD_OUTDIV1) | SIM_CLKDIV1_OUTDIV4(BOARD_OUTDIV4)); + putreg32(regval32, KL_SIM_CLKDIV1); + + /* System oscillator drives 32 kHz clock for various peripherals (OSC32KSEL=0) */ + + regval32 = getreg32(KL_SIM_SOPT1); + regval32 &= ~(SIM_SOPT1_OSC32KSEL_MASK); + putreg32(regval32, KL_SIM_SOPT1); + + /* Select PLL as a clock source for various peripherals (PLLFLLSEL=1) + * Clock source for TPM counter clock is MCGFLLCLK or MCGPLLCLK/2 + */ + + regval32 = getreg32(KL_SIM_SOPT2); + regval32 |= SIM_SOPT2_PLLFLLSEL; + putreg32(regval32, KL_SIM_SOPT2); + + regval32 = (regval32 & ~(SIM_SOPT2_TPMSRC_OCSERCLK)) | SIM_SOPT2_TPMSRC_MCGCLK; + putreg32(regval32, KL_SIM_SOPT2); + + /* PORTA_PCR18: ISF=0, MUX=0 */ + /* PORTA_PCR19: ISF=0, MUX=0 */ + + regval32 = getreg32(KL_PORTA_PCR18); + regval32 &= ~(PORT_PCR_ISF | PORT_PCR_MUX_ALT7); + putreg32(regval32, KL_PORTA_PCR18); + + regval32 = getreg32(KL_PORTA_PCR19); + regval32 &= ~(PORT_PCR_ISF | PORT_PCR_MUX_ALT7); + putreg32(regval32, KL_PORTA_PCR19); + + /* Switch to FBE Mode */ + /* OSC0_CR: ERCLKEN=0, ??=0, EREFSTEN=0, ??=0, SC2P=0, SC4P=0, SC8P=0, SC16P=0 */ + + putreg8(0, KL_OSC_CR); + + /* MCG_C2: LOCRE0=0, ??=0, RANGE0=2, HGO0=0, EREFS0=1, LP=0, IRCS=0 */ + + regval8 = (MCG_C2_RANGE_VHIGH | MCG_C2_EREFS); + putreg8(regval8, KL_MCG_C2); + + /* MCG_C1: CLKS=2, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0 */ + + regval8 = (MCG_C1_CLKS_EXTREF | MCG_C1_FRDIV_R0DIV8); + putreg8(regval8, KL_MCG_C1); + + /* MCG_C4: DMX32=0, DRST_DRS=0 */ + + regval8 = getreg8(KL_MCG_C4); + regval8 &= ~(MCG_C4_DMX32 | MCG_C4_DRST_DRS_MASK); + putreg8(regval8, KL_MCG_C4); + + /* MCG_C5: ??=0, PLLCLKEN0=0, PLLSTEN0=0, PRDIV0 determined by board + * settings in the board.h header file. + */ + + regval8 = MCG_C5_PRDIV(BOARD_PRDIV0); + putreg8(regval8, KL_MCG_C5); + + /* MCG_C6: LOLIE0=0, PLLS=0, CME0=0, VDIV0 determined by board + * settings in the board.h header file. + */ + + putreg8(MCG_C6_VDIV(BOARD_VDIV0), KL_MCG_C6); + + /* Check that the source of the FLL reference clock is the external + * reference clock. + */ + + while ((getreg8(KL_MCG_S) & MCG_S_IREFST) != 0) + ; + + /* Wait until external reference */ + + while ((getreg8(KL_MCG_S) & MCG_S_CLKST_MASK) != 8) + ; + + /* Switch to PBE mode. + * Select PLL as MCG source (PLLS=1) + */ + + putreg8(MCG_C6_PLLS, KL_MCG_C6); + + /* Wait until PLL locked */ + + while ((getreg8(KL_MCG_S) & MCG_S_LOCK) == 0) + ; + + /* Switch to PEE mode + * Select PLL output (CLKS=0) + * FLL external reference divider (FRDIV=3) + * External reference clock for FLL (IREFS=0) + */ + + putreg8(MCG_C1_FRDIV_R0DIV8, KL_MCG_C1); + + /* Wait until PLL output */ + + while ((getreg8(KL_MCG_S) & MCG_S_CLKST_MASK) != 0x0C) + ; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_clockconfig + * + * Description: + * Called to initialize the Kinetis chip. This does whatever setup is + * needed to put the MCU in a usable state. This includes the + * initialization of clocking using the settings in board.h. + * + ****************************************************************************/ + +void kl_clockconfig(void) +{ + /* Enable all of the port clocks */ + + kl_portclocks(); + + /* Configure the PLL based on settings in the board.h file */ + + kl_pllconfig(); + + /* For debugging, we will normally want to enable the trace clock and/or + * the FlexBus clock. + */ + + //kl_traceconfig(); + //kl_fbconfig(); +} diff --git a/arch/arm/src/kl/kl_clockconfig.h b/arch/arm/src/kl/kl_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..45b70c9cbd3449505a5c73707ca3c087be3ae598 --- /dev/null +++ b/arch/arm/src/kl/kl_clockconfig.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_KL_KL_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "kl_config.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_clockconfig + * + * Description: + * Called to initialize the Kinetis chip. This does whatever setup is + * needed to put the MCU in a usable state. This includes the + * initialization of clocking using the settings in board.h. + * + ****************************************************************************/ + +void kl_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KL_CLOCKCONFIG_H */ diff --git a/arch/arm/src/kl/kl_config.h b/arch/arm/src/kl/kl_config.h new file mode 100644 index 0000000000000000000000000000000000000000..fd7cc592cfdd454b7b3480f4b134d690b8da673f --- /dev/null +++ b/arch/arm/src/kl/kl_config.h @@ -0,0 +1,116 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_config.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETISXX_KL_CONFIG_H +#define __ARCH_ARM_SRC_KINETISXX_KL_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ + +#if (KL_NUART) < 3 +# undef CONFIG_KL_UART2 +# if (KL_NUART) < 2 +# undef CONFIG_KL_UART1 +# if (KL_NUART) < 1 +# undef CONFIG_KL_UART0 +# endif +# endif +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_KL_UART0) || defined(CONFIG_KL_UART1) || defined(CONFIG_KL_UART2) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3,4,5 + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_KL_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_KL_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_KL_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Check UART flow control (Not yet supported) */ + +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART2_FLOWCONTROL + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_KINETISXX_KL_CONFIG_H */ diff --git a/arch/arm/src/kl/kl_dma.h b/arch/arm/src/kl/kl_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..3288ff7feae342c6e4ebeec6f5a18801285d4325 --- /dev/null +++ b/arch/arm/src/kl/kl_dma.h @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_DMA_H +#define __ARCH_ARM_SRC_KL_KL_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "kl_config.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct kl_dmaglobalregs_s +{ +#warning "Missing logic" + /* Global Registers */ +}; + +struct kl_dmachanregs_s +{ +#warning "Missing logic" + /* Channel Registers */ +}; + +struct kl_dmaregs_s +{ + /* Global Registers */ + + struct kl_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct kl_dmachanregs_s ch; +}; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +void kl_dmainitilaize(void); +#endif + +/**************************************************************************** + * Name: kl_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +DMA_HANDLE kl_dmachannel(void); +#endif + +/**************************************************************************** + * Name: kl_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until kl_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +void kl_dmafree(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: kl_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +int kl_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); +#endif + +/**************************************************************************** + * Name: kl_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +int kl_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); +#endif + +/**************************************************************************** + * Name: kl_dmastop + * + * Description: + * Cancel the DMA. After kl_dmastop() is called, the DMA channel is + * reset and kl_dmasetup() must be called before kl_dmastart() can be + * called again + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +void kl_dmastop(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: kl_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +#ifdef CONFIG_DEBUG_DMA +void kl_dmasample(DMA_HANDLE handle, struct kl_dmaregs_s *regs); +#else +# define kl_dmasample(handle,regs) +#endif +#endif + +/**************************************************************************** + * Name: kl_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_KL_DMA +#ifdef CONFIG_DEBUG_DMA +void kl_dmadump(DMA_HANDLE handle, const struct kl_dmaregs_s *regs, + const char *msg); +#else +# define kl_dmadump(handle,regs,msg) +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KL_DMA_H */ diff --git a/arch/arm/src/kl/kl_dumpgpio.c b/arch/arm/src/kl/kl_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..b6ea6de628318495dd17d2f5a53cd459290b736d --- /dev/null +++ b/arch/arm/src/kl/kl_dumpgpio.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_gpio.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include "up_arch.h" + +#include "chip.h" +#include "kl_gpio.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Port letters for prettier debug output */ + +#ifdef CONFIG_DEBUG +static const char g_portchar[KL_GPIO_NPORTS] = +{ +#if KL_GPIO_NPORTS > 9 +# error "Additional support required for this number of GPIOs" +#elif KL_GPIO_NPORTS > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif KL_GPIO_NPORTS > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif KL_GPIO_NPORTS > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif KL_GPIO_NPORTS > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif KL_GPIO_NPORTS > 4 + 'A', 'B', 'C', 'D', 'E' +#elif KL_GPIO_NPORTS > 3 + 'A', 'B', 'C', 'D' +#elif KL_GPIO_NPORTS > 2 + 'A', 'B', 'C' +#elif KL_GPIO_NPORTS > 1 + 'A', 'B' +#elif KL_GPIO_NPORTS > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: kl_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin description + * along with a descriptive messasge. + * + ****************************************************************************/ + +void kl_dumpgpio(gpio_cfgset_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + int port; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + DEBUGASSERT((unsigned)port < KL_GPIO_NPORTS); + base = KL_GPIO_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" PDOR: %08x PDIR: %08x PDDR: %08x\n", + getreg32(base + KL_GPIO_PDOR_OFFSET), + getreg32(base + KL_GPIO_PDIR_OFFSET), + getreg32(base + KL_GPIO_PDDR_OFFSET)); + + leave_critical_section(flags); +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/kl/kl_gpio.c b/arch/arm/src/kl/kl_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..78fba619ad791209b9583a8762cce4b22a38305f --- /dev/null +++ b/arch/arm/src/kl/kl_gpio.c @@ -0,0 +1,300 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_pin.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kl_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_configgpio + * + * Description: + * Configure a PIN based on bit-encoded description of the pin. NOTE that + * DMA/interrupts are disabled at the initial PIN configuratin. + * + ****************************************************************************/ + +int kl_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + unsigned int mode; + + /* Get the port number and pin number */ + + port = (cfgset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (cfgset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KL_NPORTS); + if (port < KL_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KL_PORT_BASE(port); + + /* Get the port mode */ + + mode = (cfgset & _PIN_MODE_MASK) >> _PIN_MODE_SHIFT; + + /* Special case analog port mode. In this case, not of the digital + * options are applicable. + */ + + if (mode == PIN_MODE_ANALOG) + { + /* Set the analog mode with all digital options zeroed */ + + regval = PORT_PCR_MUX_ANALOG | PORT_PCR_IRQC_DISABLED; + putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); + } + else + { + /* Configure the digital pin options */ + + regval = (mode << PORT_PCR_MUX_SHIFT); + if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) + { + /* Handle input-only digital options */ + /* Check for pull-up or pull-down */ + + if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLDOWN) + { + regval |= PORT_PCR_PE; + } + else if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLUP) + { + regval |= (PORT_PCR_PE | PORT_PCR_PS); + } + } + else + { + /* Handle output-only digital options */ + /* Check for slow slew rate setting */ + + if ((cfgset & _PIN_OUTPUT_SLEW_MASK) == _PIN_OUTPUT_SLOW) + { + regval |= PORT_PCR_SRE; + } + + /* Check for open drain output */ + + if ((cfgset & _PIN_OUTPUT_OD_MASK) == _PIN_OUTPUT_OPENDRAIN) + { + regval |= PORT_PCR_ODE; + } + + /* Check for high drive output */ + + if ((cfgset & _PIN_OUTPUT_DRIVE_MASK) == _PIN_OUTPUT_HIGHDRIVE) + { + regval |= PORT_PCR_DSE; + } + } + + /* Check for passive filter enable. Passive Filter configuration + * is valid in all digital pin muxing modes. + */ + + if ((cfgset & PIN_PASV_FILTER) != 0) + { + regval |= PORT_PCR_PFE; + } + + /* Set the digital mode with all of the selected options */ + + putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); + + /* Check for digital filter enable. Digital Filter configuration + * is valid in all digital pin muxing modes. + */ + + regval = getreg32(base + KL_PORT_DFER_OFFSET); + if ((cfgset & PIN_DIG_FILTER) != 0) + { + regval |= (1 << pin); + } + else + { + regval &= ~(1 << pin); + } + putreg32(regval, base + KL_PORT_DFER_OFFSET); + + /* Additional configuration for the case of Alternative 1 (GPIO) modes */ + + if (mode == PIN_MODE_GPIO) + { + /* Set the GPIO port direction */ + + base = KL_GPIO_BASE(port); + regval = getreg32(base + KL_GPIO_PDDR_OFFSET); + if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) + { + /* Select GPIO input */ + + regval &= ~(1 << pin); + putreg32(regval, base + KL_GPIO_PDDR_OFFSET); + } + else /* if ((cfgset & _PIN_IO_MASK) == _PIN_OUTPUT) */ + { + /* Select GPIO input */ + + regval |= (1 << pin); + putreg32(regval, base + KL_GPIO_PDDR_OFFSET); + + /* Set the initial value of the GPIO output */ + + kl_gpiowrite(cfgset, ((cfgset & GPIO_OUTPUT_ONE) != 0)); + } + } + } + + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: kl_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void kl_gpiowrite(uint32_t pinset, bool value) +{ + uintptr_t base; + unsigned int port; + unsigned int pin; + + DEBUGASSERT((pinset & _PIN_MODE_MASK) == _PIN_MODE_GPIO); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_OUTPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KL_NPORTS); + if (port < KL_NPORTS) + { + /* Get the base address of GPIO block for this port */ + + base = KL_GPIO_BASE(port); + + /* Set or clear the output */ + + if (value) + { + putreg32((1 << pin), base + KL_GPIO_PSOR_OFFSET); + } + else + { + putreg32((1 << pin), base + KL_GPIO_PCOR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: kl_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool kl_gpioread(uint32_t pinset) +{ + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + bool ret = false; + + DEBUGASSERT((pinset & _PIN_MODE_MASK) == _PIN_MODE_GPIO); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KL_NPORTS); + if (port < KL_NPORTS) + { + /* Get the base address of GPIO block for this port */ + + base = KL_GPIO_BASE(port); + + /* return the state of the pin */ + + regval = getreg32(base + KL_GPIO_PDIR_OFFSET); + ret = ((regval & (1 << pin)) != 0); + } + return ret; +} + diff --git a/arch/arm/src/kl/kl_gpio.h b/arch/arm/src/kl/kl_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..fc2cd7f37e99e6972ba01504f43146b3fd1f8d90 --- /dev/null +++ b/arch/arm/src/kl/kl_gpio.h @@ -0,0 +1,414 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_GPIO_H +#define __ARCH_ARM_SRC_KL_KINETIS_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "kl_config.h" +#include "chip/kl_gpio.h" +#include "chip/kl_port.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ +/* Bit-encoded input to kl_pinconfig() *****************************************/ +/* General form (32-bits, only 22 bits are unused in the encoding): + * + * oooo mmmv iiii ifd- ---- -ppp ---b bbbb + */ + +/* Bits 25-31: 7 bits are used to encode the basic pin configuration: + * + * oooo mmm- ---- ---- ---- ---- ---- ---- + * | `--- mmm: mode + * `------- oooo: options (may be combined) + */ + +#define _PIN_MODE_SHIFT (25) /* Bits 25-27: Pin mode */ +#define _PIN_MODE_MASK (7 << _PIN_MODE_SHIFT) +#define _PIN_OPTIONS_SHIFT (28) /* Bits 28-31: Pin mode options */ +#define _PIN_OPTIONS_MASK (15 << _PIN_OPTIONS_SHIFT) + +/* Port Modes */ + +#define PIN_MODE_ANALOG (0) /* 000 Pin Disabled (Analog) */ +#define PIN_MODE_GPIO (1) /* 001 Alternative 1 (GPIO) */ +#define PIN_MODE_ALT2 (2) /* 010 Alternative 2 */ +#define PIN_MODE_ALT3 (3) /* 011 Alternative 3 */ +#define PIN_MODE_ALT4 (4) /* 100 Alternative 4 */ +#define PIN_MODE_ALT5 (5) /* 101 Alternative 5 */ +#define PIN_MODE_ALT6 (6) /* 110 Alternative 6 */ +#define PIN_MODE_ALT7 (7) /* 111 Alternative 7 */ + +#define _PIN_MODE_ANALOG (0 << _PIN_MODE_SHIFT) /* 000 Pin Disabled (Analog) */ +#define _PIN_MODE_GPIO (1 << _PIN_MODE_SHIFT) /* 001 Alternative 1 (GPIO) */ +#define _PIN_MODE_ALT2 (2 << _PIN_MODE_SHIFT) /* 010 Alternative 2 */ +#define _PIN_MODE_ALT3 (3 << _PIN_MODE_SHIFT) /* 011 Alternative 3 */ +#define _PIN_MODE_ALT4 (4 << _PIN_MODE_SHIFT) /* 100 Alternative 4 */ +#define _PIN_MODE_ALT5 (5 << _PIN_MODE_SHIFT) /* 101 Alternative 5 */ +#define _PIN_MODE_ALT6 (6 << _PIN_MODE_SHIFT) /* 110 Alternative 6 */ +#define _PIN_MODE_ALT7 (7 << _PIN_MODE_SHIFT) /* 111 Alternative 7 */ + +/* Options for all digital modes (Alternatives 1-7). None of the digital + * options apply if the analog mode is selected. + */ + +#define _PIN_IO_MASK (1 << _PIN_OPTIONS_SHIFT) /* xxx1 Digital input/output mask */ +#define _PIN_INPUT (0 << _PIN_OPTIONS_SHIFT) /* xxx0 Digital input */ +#define _PIN_OUTPUT (1 << _PIN_OPTIONS_SHIFT) /* xxx1 Digital output */ + +#define _PIN_INPUT_PULLMASK (7 << _PIN_OPTIONS_SHIFT) /* x111 Mask for pull-up or -down bits */ +#define _PIN_INPUT_PULLDOWN (2 << _PIN_OPTIONS_SHIFT) /* x010 Input with internal pull-down resistor */ +#define _PIN_INPUT_PULLUP (6 << _PIN_OPTIONS_SHIFT) /* x110 Input with internal pull-up resistor */ + +#define _PIN_OUTPUT_SLEW_MASK (3 << _PIN_OPTIONS_SHIFT) /* xx11 Mask to test for slow slew rate */ +#define _PIN_OUTPUT_FAST (1 << _PIN_OPTIONS_SHIFT) /* xx01 Output with fast slew rate */ +#define _PIN_OUTPUT_SLOW (3 << _PIN_OPTIONS_SHIFT) /* xx11 Output with slow slew rate */ +#define _PIN_OUTPUT_OD_MASK (5 << _PIN_OPTIONS_SHIFT) /* x1x1 Mask to test for open drain */ +#define _PIN_OUTPUT_OPENDRAIN (5 << _PIN_OPTIONS_SHIFT) /* x1x1 Output with open drain enabled */ +#define _PIN_OUTPUT_DRIVE_MASK (9 << _PIN_OPTIONS_SHIFT) /* 1xx1 Mask to test for high drive strengh */ +#define _PIN_OUTPUT_LOWDRIVE (1 << _PIN_OPTIONS_SHIFT) /* 0xx1 Output with low drive strength */ +#define _PIN_OUTPUT_HIGHDRIVE (9 << _PIN_OPTIONS_SHIFT) /* 1xx1 Output with high drive strength */ + +/* End-user pin modes and configurations. Notes: (1) None of the digital options + * are available for the analog mode, (2) digital settings may be combined (OR'ed) + * provided that input-only and output-only options are not intermixed. + */ + +#define PIN_ANALOG _PIN_MODE_ANALOG + +#define GPIO_INPUT (_PIN_MODE_GPIO | _PIN_INPUT) +#define GPIO_PULLDOWN (_PIN_MODE_GPIO | _PIN_INPUT_PULLDOWN) +#define GPIO_PULLUP (_PIN_MODE_GPIO | _PIN_INPUT_PULLUP) +#define GPIO_OUTPUT (_PIN_MODE_GPIO | _PIN_OUTPUT) +#define GPIO_FAST (_PIN_MODE_GPIO | _PIN_OUTPUT_FAST) +#define GPIO_SLOW (_PIN_MODE_GPIO | _PIN_OUTPUT_SLOW) +#define GPIO_OPENDRAIN (_PIN_MODE_GPIO | _PIN_OUTPUT_LOWDRIVE) +#define GPIO_LOWDRIVE (_PIN_MODE_GPIO | _PIN_OUTPUT_OPENDRAIN) +#define GPIO_HIGHDRIVE (_PIN_MODE_GPIO | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT2 _PIN_MODE_ALT2 +#define PIN_ALT2_INPUT (_PIN_MODE_ALT2 | _PIN_INPUT) +#define PIN_ALT2_PULLDOWN (_PIN_MODE_ALT2 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT2_PULLUP (_PIN_MODE_ALT2 | _PIN_INPUT_PULLUP) +#define PIN_ALT2_OUTPUT (_PIN_MODE_ALT2 | _PIN_OUTPUT) +#define PIN_ALT2_FAST (_PIN_MODE_ALT2 | _PIN_OUTPUT_FAST) +#define PIN_ALT2_SLOW (_PIN_MODE_ALT2 | _PIN_OUTPUT_SLOW) +#define PIN_ALT2_OPENDRAIN (_PIN_MODE_ALT2 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT2_LOWDRIVE (_PIN_MODE_ALT2 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT2_HIGHDRIVE (_PIN_MODE_ALT2 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT3 _PIN_MODE_ALT3 +#define PIN_ALT3_INPUT (_PIN_MODE_ALT3 | _PIN_INPUT) +#define PIN_ALT3_PULLDOWN (_PIN_MODE_ALT3 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT3_PULLUP (_PIN_MODE_ALT3 | _PIN_INPUT_PULLUP) +#define PIN_ALT3_OUTPUT (_PIN_MODE_ALT3 | _PIN_OUTPUT) +#define PIN_ALT3_FAST (_PIN_MODE_ALT3 | _PIN_OUTPUT_FAST) +#define PIN_ALT3_SLOW (_PIN_MODE_ALT3 | _PIN_OUTPUT_SLOW) +#define PIN_ALT3_OPENDRAIN (_PIN_MODE_ALT3 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT3_LOWDRIVE (_PIN_MODE_ALT3 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT3_HIGHDRIVE (_PIN_MODE_ALT3 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT4 _PIN_MODE_ALT4 +#define PIN_ALT4_INPUT (_PIN_MODE_ALT4 | _PIN_INPUT) +#define PIN_ALT4_PULLDOWN (_PIN_MODE_ALT4 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT4_PULLUP (_PIN_MODE_ALT4 | _PIN_INPUT_PULLUP) +#define PIN_ALT4_OUTPUT (_PIN_MODE_ALT4 | _PIN_OUTPUT) +#define PIN_ALT4_FAST (_PIN_MODE_ALT4 | _PIN_OUTPUT_FAST) +#define PIN_ALT4_SLOW (_PIN_MODE_ALT4 | _PIN_OUTPUT_SLOW) +#define PIN_ALT4_OPENDRAIN (_PIN_MODE_ALT4 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT4_LOWDRIVE (_PIN_MODE_ALT4 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT4_HIGHDRIVE (_PIN_MODE_ALT4 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT5 _PIN_MODE_ALT5 +#define PIN_ALT5_INPUT (_PIN_MODE_ALT5 | _PIN_INPUT) +#define PIN_ALT5_PULLDOWN (_PIN_MODE_ALT5 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT5_PULLUP (_PIN_MODE_ALT5 | _PIN_INPUT_PULLUP) +#define PIN_ALT5_OUTPUT (_PIN_MODE_ALT5 | _PIN_OUTPUT) +#define PIN_ALT5_FAST (_PIN_MODE_ALT5 | _PIN_OUTPUT_FAST) +#define PIN_ALT5_SLOW (_PIN_MODE_ALT5 | _PIN_OUTPUT_SLOW) +#define PIN_ALT5_OPENDRAIN (_PIN_MODE_ALT5 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT5_LOWDRIVE (_PIN_MODE_ALT5 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT5_HIGHDRIVE (_PIN_MODE_ALT5 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT6 _PIN_MODE_ALT6 +#define PIN_ALT6_INPUT (_PIN_MODE_ALT6 | _PIN_INPUT) +#define PIN_ALT6_PULLDOWN (_PIN_MODE_ALT6 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT6_PULLUP (_PIN_MODE_ALT6 | _PIN_INPUT_PULLUP) +#define PIN_ALT6_OUTPUT (_PIN_MODE_ALT6 | _PIN_OUTPUT) +#define PIN_ALT6_FAST (_PIN_MODE_ALT6 | _PIN_OUTPUT_FAST) +#define PIN_ALT6_SLOW (_PIN_MODE_ALT6 | _PIN_OUTPUT_SLOW) +#define PIN_ALT6_OPENDRAIN (_PIN_MODE_ALT6 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT6_LOWDRIVE (_PIN_MODE_ALT6 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT6_HIGHDRIVE (_PIN_MODE_ALT6 | _PIN_OUTPUT_HIGHDRIVE) + +#define PIN_ALT7 _PIN_MODE_ALT7 +#define PIN_ALT7_INPUT (_PIN_MODE_ALT7 | _PIN_INPUT) +#define PIN_ALT7_PULLDOWN (_PIN_MODE_ALT7 | _PIN_INPUT_PULLDOWN) +#define PIN_ALT7_PULLUP (_PIN_MODE_ALT7 | _PIN_INPUT_PULLUP) +#define PIN_ALT7_OUTPUT (_PIN_MODE_ALT7 | _PIN_OUTPUT) +#define PIN_ALT7_FAST (_PIN_MODE_ALT7 | _PIN_OUTPUT_FAST) +#define PIN_ALT7_SLOW (_PIN_MODE_ALT7 | _PIN_OUTPUT_SLOW) +#define PIN_ALT7_OPENDRAIN (_PIN_MODE_ALT7 | _PIN_OUTPUT_LOWDRIVE) +#define PIN_ALT7_LOWDRIVE (_PIN_MODE_ALT7 | _PIN_OUTPUT_OPENDRAIN) +#define PIN_ALT7_HIGHDRIVE (_PIN_MODE_ALT7 | _PIN_OUTPUT_HIGHDRIVE) + +/* The initial value for GPIO (Alternative 1 outputs): + * + * ---- ---v ---- ---- ---- ---- ---- ---- + * + * Passive Filter and digital filter enable are valid in all digital pin + * muxing modes. + */ + +#define GPIO_OUTPUT_ONE (1 << 24) /* Bit 24: 1:Initial output value=1 */ +#define GPIO_OUTPUT_ZER0 (0) /* Bit 24: 0:Initial output value=0 */ + +/* Five bits are used to incode DMA/interrupt options: + * + * ---- ---- iiii i--- ---- ---- ---- ---- + * + * The pin interrupt configuration is valid in all digital pin muxing modes + * (restricted to inputs). + */ + +#define _PIN_INT_SHIFT (20) +#define _PIN_INT_MASK (31 << _PIN_INT_SHIFT) + +#define _PIN_INTDMA_MASK (3 << _PIN_INT_SHIFT) +#define _PIN_INTDMA_NONE (0 << _PIN_INT_SHIFT) +#define _PIN_DMA (1 << _PIN_INT_SHIFT) +#define _PIN_INTERRUPT (2 << _PIN_INT_SHIFT) + +#define PIN_DMA_RISING (5 << _PIN_INT_SHIFT) /* 00101 DMA Request on rising edge */ +#define PIN_DMA_FALLING (9 << _PIN_INT_SHIFT) /* 01001 DMA Request on falling edge */ +#define PIN_DMA_BOTH (13 << _PIN_INT_SHIFT) /* 01101 DMA Request on either edge */ +#define PIN_INT_ZERO (2 << _PIN_INT_SHIFT) /* 00010 Interrupt when logic zero */ +#define PIN_INT_RISING (6 << _PIN_INT_SHIFT) /* 00110 Interrupt on rising edge */ +#define PIN_INT_FALLING (10 << _PIN_INT_SHIFT) /* 01010 Interrupt on falling edge */ +#define PIN_INT_BOTH (14 << _PIN_INT_SHIFT) /* 01110 Interrupt on either edge */ +#define PIN_INT_ONE (18 << _PIN_INT_SHIFT) /* 10010 Interrupt when logic one */ + +/* Two bits is used to enable the filter options: + * + * ---- ---- ---- -fd- ---- ---- ---- ---- + * + * Passive Filter and digital filter enable are valid in all digital pin + * muxing modes. + */ + +#define PIN_PASV_FILTER (1 << 18) /* Bit 18: Enable passive filter */ +#define PIN_DIG_FILTER (1 << 17) /* Bit 17: Enable digital filter */ + +/* Three bits are used to define the port number: + * + * ---- ---- ---- ---- ---- -ppp ---- ---- + */ + +#define _PIN_PORT_SHIFT (8) /* Bits 8-10: port number */ +#define _PIN_PORT_MASK (7 << _PIN_PORT_SHIFT) + +#define PIN_PORTA (KL_PORTA << _PIN_PORT_SHIFT) +#define PIN_PORTB (KL_PORTB << _PIN_PORT_SHIFT) +#define PIN_PORTC (KL_PORTC << _PIN_PORT_SHIFT) +#define PIN_PORTD (KL_PORTD << _PIN_PORT_SHIFT) +#define PIN_PORTE (KL_PORTE << _PIN_PORT_SHIFT) + +/* Five bits are used to define the pin number: + * + * ---- ---- ---- ---- ---- ---- ---b bbbb + */ + +#define _PIN_SHIFT (0) /* Bits 0-4: port number */ +#define _PIN_MASK (31 << _PIN_SHIFT) + +#define PIN(n) ((n) << _PIN_SHIFT) +#define PIN0 (0 << _PIN_SHIFT) +#define PIN1 (1 << _PIN_SHIFT) +#define PIN2 (2 << _PIN_SHIFT) +#define PIN3 (3 << _PIN_SHIFT) +#define PIN4 (4 << _PIN_SHIFT) +#define PIN5 (5 << _PIN_SHIFT) +#define PIN6 (6 << _PIN_SHIFT) +#define PIN7 (7 << _PIN_SHIFT) +#define PIN8 (8 << _PIN_SHIFT) +#define PIN9 (9 << _PIN_SHIFT) +#define PIN10 (10 << _PIN_SHIFT) +#define PIN11 (11 << _PIN_SHIFT) +#define PIN12 (12 << _PIN_SHIFT) +#define PIN13 (13 << _PIN_SHIFT) +#define PIN14 (14 << _PIN_SHIFT) +#define PIN15 (15 << _PIN_SHIFT) +#define PIN16 (16 << _PIN_SHIFT) +#define PIN17 (17 << _PIN_SHIFT) +#define PIN18 (18 << _PIN_SHIFT) +#define PIN19 (19 << _PIN_SHIFT) +#define PIN20 (20 << _PIN_SHIFT) +#define PIN21 (21 << _PIN_SHIFT) +#define PIN22 (22 << _PIN_SHIFT) +#define PIN23 (23 << _PIN_SHIFT) +#define PIN24 (24 << _PIN_SHIFT) +#define PIN25 (25 << _PIN_SHIFT) +#define PIN26 (26 << _PIN_SHIFT) +#define PIN27 (27 << _PIN_SHIFT) +#define PIN28 (28 << _PIN_SHIFT) +#define PIN29 (29 << _PIN_SHIFT) +#define PIN30 (30 << _PIN_SHIFT) +#define PIN31 (31 << _PIN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef uint32_t gpio_cfgset_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_configgpio + * + * Description: + * Configure a PIN based on bit-encoded description of the pin. NOTE that + * DMA/interrupts are disabled at the initial PIN configuratin. + * + ****************************************************************************/ + +int kl_configgpio(uint32_t cfgset); + +/**************************************************************************** + * Name: kl_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void kl_gpiowrite(uint32_t pinset, bool value); + +/**************************************************************************** + * Name: kl_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool kl_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: kl_pinirqattach + * + * Description: + * Attach a pin interrupt handler. The normal initalization sequence is: + * + * 1. Call kl_configgpio() to configure the interrupting pin (pin interrupts + * will be disabled. + * 2. Call kl_gpioirqattach() to attach the pin interrupt handling function. + * 3. Call kl_gpioirqenable() to enable interrupts on the pin. + * + * Parameters: + * - pinset: Pin configuration + * - pinisr: Pin interrupt service routine + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t kl_gpioirqattach(uint32_t pinset, xcpt_t pinisr); + +/************************************************************************************ + * Name: kl_gpioirqenable + * + * Description: + * Enable the interrupt for specified pin IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void kl_gpioirqenable(uint32_t pinset); +#else +# define kl_gpioirqenable(pinset) +#endif + +/************************************************************************************ + * Name: kl_gpioirqdisable + * + * Description: + * Disable the interrupt for specified pin + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void kl_gpioirqdisable(uint32_t pinset); +#else +# define kl_gpioirqdisable(pinset) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KINETIS_GPIO_H */ diff --git a/arch/arm/src/kl/kl_gpioirq.c b/arch/arm/src/kl/kl_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..2b481bce3a22b7a58fe29266fafb824de1ed92f9 --- /dev/null +++ b/arch/arm/src/kl/kl_gpioirq.c @@ -0,0 +1,399 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_gpioirq.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/kl_port.h" +#include "kl_gpio.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The Kinetis port interrupt logic is very flexible and will program + * interrupts on most all pin events. In order to keep the memory usage to + * a minimum, the NuttX port supports enabling interrupts on a per-port + * basis. + */ + +#if defined(CONFIG_KL_PORTAINTS) || defined(CONFIG_KL_PORTDINTS) +# define HAVE_PORTINTS 1 +#endif + +#if defined(CONFIG_KL_PORTBINTS) || defined(CONFIG_KL_PORTCINTS) || \ + defined(CONFIG_KL_PORTEINTS) +# error Kinetis KL25 only supports interrupt on PORTA or PORTD +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Per pin port interrupt vectors. NOTE: Not all pins in each port + * correspond to externally available GPIOs. However, I believe that the + * Kinetis will support interrupts even if the pin is not available as + * a GPIO. Hence, we need to support all 32 pins for each port. To keep the + * memory usage at a minimum, the logic may be configure per port. + */ + +#ifdef CONFIG_KL_PORTAINTS +static xcpt_t g_portaisrs[32]; +#endif + +#ifdef CONFIG_KL_PORTDINTS +static xcpt_t g_portdisrs[32]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_portinterrupt + * + * Description: + * Common port interrupt handling. + * + ****************************************************************************/ + +#ifdef HAVE_PORTINTS +static int kl_portinterrupt(int irq, FAR void *context, + uintptr_t addr, xcpt_t *isrtab) +{ + uint32_t isfr = getreg32(addr); + int i; + + /* Examine each pin in the port */ + + for (i = 0; i < 32 && isfr != 0; i++) + { + /* A bit set in the ISR means that an interrupt is pending for this + * pin. If the pin is programmed for level sensitive inputs, then + * the interrupt handling logic MUST disable the interrupt (or cause + * the level to change) to prevent infinite interrupts. + */ + + uint32_t bit = (1 << i); + if ((isfr & bit) != 0) + { + /* I think that bits may be set in the ISFR for DMA activities + * well. So, no error is declared if there is no registered + * interrupt handler for the pin. + */ + + if (isrtab[i]) + { + /* There is a registered interrupt handler... invoke it */ + + (void)isrtab[i](irq, context); + } + + /* Writing a one to the ISFR register will clear the pending + * interrupt. If pin is configured to generate a DMA request + * then the ISFR bit will be cleared automatically at the + * completion of the requested DMA transfer. If configured for + * a level sensitive interrupt and the pin remains asserted and + * the bit will set again immediately after it is cleared. + */ + + isfr &= ~bit; + putreg32(bit, addr); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: kl_portXinterrupt + * + * Description: + * Handle interrupts arriving on individual ports + * + ****************************************************************************/ + +#ifdef CONFIG_KL_PORTAINTS +static int kl_portainterrupt(int irq, FAR void *context) +{ + return kl_portinterrupt(irq, context, KL_PORTA_ISFR, g_portaisrs); +} +#endif + +#ifdef CONFIG_KL_PORTDINTS +static int kl_portdinterrupt(int irq, FAR void *context) +{ + return kl_portinterrupt(irq, context, KL_PORTD_ISFR, g_portdisrs); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void kl_gpioirqinitialize(void) +{ +#ifdef CONFIG_KL_PORTAINTS + (void)irq_attach(KL_IRQ_PORTA, kl_portainterrupt); + putreg32(0xffffffff, KL_PORTA_ISFR); + up_enable_irq(KL_IRQ_PORTA); +#endif + +#ifdef CONFIG_KL_PORTDINTS + (void)irq_attach(KL_IRQ_PORTD, kl_portdinterrupt); + putreg32(0xffffffff, KL_PORTD_ISFR); + up_enable_irq(KL_IRQ_PORTD); +#endif +} + +/**************************************************************************** + * Name: kl_gpioirqattach + * + * Description: + * Attach a pin interrupt handler. The normal initialization sequence is: + * + * 1. Call kl_gpioconfig() to configure the interrupting pin (pin interrupts + * will be disabled. + * 2. Call kl_gpioirqattach() to attach the pin interrupt handling function. + * 3. Call kl_gpioirqenable() to enable interrupts on the pin. + * + * Parameters: + * - pinset: Pin configuration + * - pinisr: Pin interrupt service routine + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t kl_gpioirqattach(uint32_t pinset, xcpt_t pinisr) +{ +#ifdef HAVE_PORTINTS + xcpt_t *isrtab; + xcpt_t oldisr; + irqstate_t flags; + unsigned int port; + unsigned int pin; + + /* It only makes sense to call this function for input pins that are + * configured as interrupts. + */ + + DEBUGASSERT((pinset & _PIN_INTDMA_MASK) == _PIN_INTERRUPT); + DEBUGASSERT((pinset & _PIN_IO_MASK) == _PIN_INPUT); + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + /* Get the table associated with this port */ + + DEBUGASSERT(port < KL_NPORTS); + flags = enter_critical_section(); + switch (port) + { +#ifdef CONFIG_KL_PORTAINTS + case KL_PORTA : + isrtab = g_portaisrs; + break; +#endif +#ifdef CONFIG_KL_PORTDINTS + case KL_PORTD : + isrtab = g_portdisrs; + break; +#endif + default: + leave_critical_section(flags); + return NULL; + } + + /* Get the old PIN ISR and set the new PIN ISR */ + + oldisr = isrtab[pin]; + isrtab[pin] = pinisr; + + /* And return the old PIN isr address */ + + leave_critical_section(flags); + return oldisr; + +#else + return NULL; +#endif /* HAVE_PORTINTS */ +} + +/************************************************************************************ + * Name: kl_gpioirqenable + * + * Description: + * Enable the interrupt for specified pin IRQ + * + ************************************************************************************/ + +void kl_gpioirqenable(uint32_t pinset) +{ +#ifdef HAVE_PORTINTS + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KL_NPORTS); + if (port < KL_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KL_PORT_BASE(port); + + /* Modify the IRQC field of the port PCR register in order to enable + * the interrupt. + */ + + regval = getreg32(base + KL_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + + switch (pinset & _PIN_INT_MASK) + { + case PIN_INT_ZERO : /* Interrupt when logic zero */ + regval |= PORT_PCR_IRQC_ZERO; + break; + + case PIN_INT_RISING : /* Interrupt on rising edge */ + regval |= PORT_PCR_IRQC_RISING; + break; + + case PIN_INT_FALLING : /* Interrupt on falling edge */ + regval |= PORT_PCR_IRQC_FALLING; + break; + + case PIN_INT_BOTH : /* Interrupt on either edge */ + regval |= PORT_PCR_IRQC_BOTH; + break; + + case PIN_DMA_RISING : /* Interrupt on DMA rising */ + regval |= PORT_PCR_IRQC_DMARISING; + break; + + case PIN_DMA_FALLING : /* Interrupt on DMA falling */ + regval |= PORT_PCR_IRQC_DMAFALLING; + break; + + case PIN_INT_ONE : /* IInterrupt when logic one */ + regval |= PORT_PCR_IRQC_ONE; + break; + + default: + return; + } + + putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); + } +#endif /* HAVE_PORTINTS */ +} + +/************************************************************************************ + * Name: kl_gpioirqdisable + * + * Description: + * Disable the interrupt for specified pin + * + ************************************************************************************/ + +void kl_gpioirqdisable(uint32_t pinset) +{ +#ifdef HAVE_PORTINTS + uintptr_t base; + uint32_t regval; + unsigned int port; + unsigned int pin; + + /* Get the port number and pin number */ + + port = (pinset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; + pin = (pinset & _PIN_MASK) >> _PIN_SHIFT; + + DEBUGASSERT(port < KL_NPORTS); + if (port < KL_NPORTS) + { + /* Get the base address of PORT block for this port */ + + base = KL_PORT_BASE(port); + + /* Clear the IRQC field of the port PCR register in order to disable + * the interrupt. + */ + + regval = getreg32(base + KL_PORT_PCR_OFFSET(pin)); + regval &= ~PORT_PCR_IRQC_MASK; + putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); + } +#endif /* HAVE_PORTINTS */ +} +#endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/arm/src/kl/kl_idle.c b/arch/arm/src/kl/kl_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..e711b39e3c51d92765be3de3576e98aa29e5364e --- /dev/null +++ b/arch/arm/src/kl/kl_idle.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_idle.c + * + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + kl_pmstop(true); + break; + + case PM_SLEEP: + (void)kl_pmstandby(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/kl/kl_irq.c b/arch/arm/src/kl/kl_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..87d47ab35c0d9f2ce06874e42bdc131730332cde --- /dev/null +++ b/arch/arm/src/kl/kl_irq.c @@ -0,0 +1,344 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_irq.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "kl_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | NVIC_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void kl_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" ISER: %08x ICER: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); + lldbg(" ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), + getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), + getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); + + lldbg("SYSCON:\n"); + lldbg(" CPUID: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID)); + lldbg(" ICSR: %08x AIRCR: %08x\n", + getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); + lldbg(" SCR: %08x CCR: %08x\n", + getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); + lldbg(" SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#else +# define kl_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: kl_nmi, kl_busfault, kl_usagefault, kl_pendsv, + * kl_dbgmonitor, kl_pendsv, kl_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int kl_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int kl_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int kl_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: kl_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. + * + ****************************************************************************/ + +static inline void kl_clrpend(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= KL_IRQ_EXTINT && irq < (KL_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - KL_IRQ_EXTINT)), ARMV6M_NVIC_ICPR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int i; + + /* Disable all interrupts */ + + putreg32(0xffffffff, ARMV6M_NVIC_ICER); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR2); + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR3); + + /* Now set all of the interrupt lines to the default priority */ + + for (i = 0; i < 8; i++) + { + regaddr = ARMV6M_NVIC_IPR(i); + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(KL_IRQ_SVCALL, up_svcall); + irq_attach(KL_IRQ_HARDFAULT, up_hardfault); + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(KL_IRQ_NMI, kl_nmi); + irq_attach(KL_IRQ_PENDSV, kl_pendsv); + irq_attach(KL_IRQ_RESERVED, kl_reserved); +#endif + + kl_dumpnvic("initial", NR_IRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * configured pin interrupts. + */ + +#ifdef CONFIG_GPIO_IRQ + kl_gpioirqinitialize(); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= KL_IRQ_EXTINT && irq < (KL_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ICER register to disable the + * interrupt + */ + + putreg32((1 << (irq - KL_IRQ_EXTINT)), ARMV6M_NVIC_ICER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == KL_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, SYSTICK_CSR_ENABLE, 0); + } + + kl_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enabled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= KL_IRQ_EXTINT && irq < (KL_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - KL_IRQ_EXTINT)), ARMV6M_NVIC_ISER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == KL_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, 0, SYSTICK_CSR_ENABLE); + } + + kl_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + kl_clrpend(irq); +} diff --git a/arch/arm/src/kl/kl_irq.h b/arch/arm/src/kl/kl_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..150e032c72d4441616dd155dcc3580e057c39ee7 --- /dev/null +++ b/arch/arm/src/kl/kl_irq.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_IRQ_H +#define __ARCH_ARM_SRC_KL_KINETIS_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KINETIS_IRQ_H */ diff --git a/arch/arm/src/kl/kl_irqprio.c b/arch/arm/src/kl/kl_irqprio.c new file mode 100644 index 0000000000000000000000000000000000000000..b2dfe318f07fda4883470ed1dd347a2f7c5857d4 --- /dev/null +++ b/arch/arm/src/kl/kl_irqprio.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_irqprio.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" + +#include "kl_irq.h" + +#ifdef CONFIG_ARCH_IRQPRIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq == KL_IRQ_SVCALL || + irq == KL_IRQ_PENDSV || + irq == KL_IRQ_SYSTICK || + (irq >= KL_IRQ_EXTINT && irq < NR_IRQS)); + DEBUGASSERT(priority >= NVIC_SYSH_PRIORITY_MAX && + priority <= NVIC_SYSH_PRIORITY_MIN); + + /* Check for external interrupt */ + + if (irq >= KL_IRQ_EXTINT && irq < (KL_IRQ_EXTINT + 32)) + { + /* ARMV6M_NVIC_IPR() maps register IPR0-IPR7 with four settings per + * register. + */ + + regaddr = ARMV6M_NVIC_IPR(irq >> 2); + shift = (irq & 3) << 3; + } + + /* Handle processor exceptions. Only SVCall, PendSV, and SysTick can be + * reprioritized. And we will not permit modification of SVCall through + * this function. + */ + + else if (irq == KL_IRQ_PENDSV) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_14_SHIFT; + } + else if (irq == KL_IRQ_SYSTICK) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_15_SHIFT; + } + else + { + return ERROR; + } + + /* Set the priority */ + + regval = getreg32(regaddr); + regval &= ~((uint32_t)0xff << shift); + regval |= ((uint32_t)priority << shift); + putreg32(regval, regaddr); + return OK; +} +#endif diff --git a/arch/arm/src/kl/kl_lowgetc.c b/arch/arm/src/kl/kl_lowgetc.c new file mode 100644 index 0000000000000000000000000000000000000000..f1c02981d2cf95761b11cd37484f27e92fc2b8aa --- /dev/null +++ b/arch/arm/src/kl/kl_lowgetc.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_lowgetc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "kl_config.h" +#include "kl_lowgetc.h" + +#include "chip/kl_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART0_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART1_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART2_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowgetc + * + * Description: + * Input one byte from the serial console + * + ****************************************************************************/ + +int kl_lowgetc(void) +{ + uint8_t ch = 0; + +#if defined HAVE_UART_DEVICE && defined HAVE_SERIAL_CONSOLE + /* Wait while the receiver data buffer is "empty" (RDRF) to assure that + * we have data in the buffer to read. + */ + + while ((getreg8(CONSOLE_BASE+KL_UART_S1_OFFSET) & UART_S1_RDRF) == 0); + + /* Then read a character from the UART data register */ + + ch = getreg8(CONSOLE_BASE+KL_UART_D_OFFSET); +#endif + + return (int)ch; +} diff --git a/arch/arm/src/kl/kl_lowgetc.h b/arch/arm/src/kl/kl_lowgetc.h new file mode 100644 index 0000000000000000000000000000000000000000..4ed52365a2a4ba3f9304d273df12d8b9d6a64656 --- /dev/null +++ b/arch/arm/src/kl/kl_lowgetc.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_lowgetc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_LOWGETC_H +#define __ARCH_ARM_SRC_KL_KINETIS_LOWGETC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "kl_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +int kl_lowgetc(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KINETIS_LOWGETC_H */ diff --git a/arch/arm/src/kl/kl_lowputc.c b/arch/arm/src/kl/kl_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..669d18b34accff36ff59ba47ff49c7d015e094ce --- /dev/null +++ b/arch/arm/src/kl/kl_lowputc.c @@ -0,0 +1,335 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_lowputc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "kl_config.h" +#include "kl_lowputc.h" +#include "kl_gpio.h" + +#include "chip/kl_uart.h" +#include "chip/kl_sim.h" +#include "chip/kl_port.h" +#include "chip/kl_uart.h" +#include "chip/kl_pinmux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART0_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART1_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE KL_UART2_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +#endif + +#define OVER_SAMPLE 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void kl_lowputc(uint32_t ch) +{ +#if defined HAVE_UART_DEVICE && defined HAVE_SERIAL_CONSOLE + /* Wait until the transmit data register is "empty" (TDRE). This state + * depends on the TX watermark setting and may not mean that the transmit + * buffer is truly empty. It just means that we can now add another + * characterto the transmit buffer without exceeding the watermark. + * + * NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs + * (1-deep). There appears to be no way to know when the FIFO is not + * full (other than reading the FIFO length and comparing the FIFO count). + * Hence, the FIFOs are not used in this implementation and, as a result + * TDRE indeed mean that the single output buffer is available. + * + * Performance on UART0 could be improved by enabling the FIFO and by + * redesigning all of the FIFO status logic. + */ + + while ((getreg8(CONSOLE_BASE+KL_UART_S1_OFFSET) & UART_S1_TDRE) == 0); + + /* Then write the character to the UART data register */ + + putreg8((uint8_t)ch, CONSOLE_BASE+KL_UART_D_OFFSET); + +#endif +} + +/**************************************************************************** + * Name: kl_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ +void kl_lowsetup(void) +{ + uint32_t regval; + uint8_t regval8; + +#if 0 + regval = getreg32(KL_SIM_SOPT2); + regval |= SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_UART0SRC_MCGCLK ; + putreg32(regval, KL_SIM_SOPT2); +#endif + + regval = getreg32(KL_SIM_SCGC4); +#ifdef CONFIG_KL_UART0 + regval |= SIM_SCGC4_UART0; +#endif +#ifdef CONFIG_KL_UART1 + regval |= SIM_SCGC4_UART1; +#endif +#ifdef CONFIG_KL_UART2 + regval |= SIM_SCGC4_UART2; +#endif + putreg32(regval, KL_SIM_SCGC4); + + regval = getreg32(KL_SIM_SOPT2); + regval &= ~(SIM_SOPT2_UART0SRC_MASK); + putreg32(regval, KL_SIM_SOPT2); + + regval = getreg32(KL_SIM_SOPT2); + regval |= SIM_SOPT2_UART0SRC_MCGCLK; + putreg32(regval, KL_SIM_SOPT2); + + putreg32((PORT_PCR_MUX_ALT2), KL_PORTA_PCR1); + putreg32((PORT_PCR_MUX_ALT2), KL_PORTA_PCR2); + + /* Disable UART before changing registers */ + + putreg8(0, KL_UART0_C2); + putreg8(0, KL_UART0_C1); + putreg8(0, KL_UART0_C3); + putreg8(0, KL_UART0_S2); + + /* Set the baud rate divisor */ + + uint16_t divisor = (CONSOLE_FREQ / OVER_SAMPLE) / CONSOLE_BAUD; + regval8 = OVER_SAMPLE - 1; + putreg8(regval8, KL_UART0_C4); + + regval8 = (divisor >> 8) & UART_BDH_SBR_MASK; + putreg8(regval8, KL_UART0_BDH); + + regval8 = (divisor & UART_BDL_SBR_MASK); + putreg8(regval8, KL_UART0_BDL); + + /* Enable UART before changing registers */ + + regval8 = getreg8(KL_UART0_C2); + regval8 |= (UART_C2_RE | UART_C2_TE); + putreg8(regval8, KL_UART0_C2); + + /* Configure the console (only) now. Other UARTs will be configured + * when the serial driver is opened. + */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + kl_uartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, + CONSOLE_PARITY, CONSOLE_BITS); +#endif +} + +/**************************************************************************** + * Name: kl_uartreset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kl_uartreset(uintptr_t uart_base) +{ + uint8_t regval; + + /* Just disable the transmitter and receiver */ + + regval = getreg8(uart_base + KL_UART_C2_OFFSET); + regval &= ~(UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base + KL_UART_C2_OFFSET); +} +#endif + +/**************************************************************************** + * Name: kl_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kl_uartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock, + unsigned int parity, unsigned int nbits) +{ + uint32_t sbr; + uint32_t tmp; + uint8_t regval; + + /* Disable the transmitter and receiver throughout the reconfiguration */ + + regval = getreg8(uart_base+KL_UART_C2_OFFSET); + regval &= ~(UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base+KL_UART_C2_OFFSET); + + /* Configure number of bits, stop bits and parity */ + + regval = 0; + + /* Check for odd parity */ + + if (parity == 1) + { + regval |= (UART_C1_PE | UART_C1_PT); /* Enable + odd parity type */ + } + + /* Check for even parity */ + + else if (parity == 2) + { + regval |= UART_C1_PE; /* Enable (even parity default) */ + } + + /* The only other option is no parity */ + + else + { + DEBUGASSERT(parity == 0); + } + + /* Check for 9-bit operation */ + + if (nbits == 9) + { + regval |= UART_C1_M; + } + + /* The only other option is 8-bit operation */ + + else + { + DEBUGASSERT(nbits == 8); + } + + putreg8(regval, uart_base + KL_UART_C1_OFFSET); + + /* Calculate baud settings (truncating) */ + + sbr = clock / (baud << 4); + DEBUGASSERT(sbr < 0x2000); + + /* Save the new baud divisor, retaining other bits in the UARTx_BDH + * register. + */ + + regval = getreg8(uart_base + KL_UART_BDH_OFFSET) & UART_BDH_SBR_MASK; + tmp = sbr >> 8; + regval |= (((uint8_t)tmp) << UART_BDH_SBR_SHIFT) & UART_BDH_SBR_MASK; + putreg8(regval, uart_base + KL_UART_BDH_OFFSET); + + regval = sbr & 0xff; + putreg8(regval, uart_base + KL_UART_BDL_OFFSET); + + /* Now we can (re-)enable the transmitter and receiver */ + + regval = getreg8(uart_base + KL_UART_C2_OFFSET); + regval |= (UART_C2_RE | UART_C2_TE); + putreg8(regval, uart_base + KL_UART_C2_OFFSET); +} +#endif + + + diff --git a/arch/arm/src/kl/kl_lowputc.h b/arch/arm/src/kl/kl_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..ab9df0ce499ff8ebcf0d0ef2f94776e17323fddd --- /dev/null +++ b/arch/arm/src/kl/kl_lowputc.h @@ -0,0 +1,127 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_LOWPUTC_H +#define __ARCH_ARM_SRC_KL_KINETIS_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "kl_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: kl_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void kl_lowsetup(void); + +/************************************************************************************ + * Name: kl_uartreset + * + * Description: + * Reset a UART. + * + ************************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kl_uartreset(uintptr_t uart_base); +#endif + +/************************************************************************************ + * Name: kl_lowputc + * + * Description: + * Output one character to the UART using a simple polling method. + * + ************************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void kl_lowputc(uint32_t ch); +#endif + +/************************************************************************************ + * Name: kl_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ************************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void kl_uartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock, + unsigned int parity, unsigned int nbits); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KL_KINETIS_LOWPUTC_H */ diff --git a/arch/arm/src/kl/kl_pwm.c b/arch/arm/src/kl/kl_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..c4714178e4cb03dd65a17c42946ea661cf1b283b --- /dev/null +++ b/arch/arm/src/kl/kl_pwm.c @@ -0,0 +1,760 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_pwm.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "kl_pwm.h" +#include "kl_gpio.h" +#include "chip/kl_tpm.h" +#include "chip/kl_sim.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_KL_TPM0_PWM) || defined(CONFIG_KL_TPM1_PWM) || \ + defined(CONFIG_KL_TPM2_PWM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) kl_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct kl_pwmtimer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t tpmid; /* Timer/PWM Module ID {0,..,2} */ + uint8_t channel; /* Timer/PWM Module channel: {0,..5} */ + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t pwm_getreg(struct kl_pwmtimer_s *priv, int offset); +static void pwm_putreg(struct kl_pwmtimer_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct kl_pwmtimer_s *priv, FAR const char *msg); +#else +# define pwm_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int pwm_timer(FAR struct kl_pwmtimer_s *priv, + FAR const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +#ifdef CONFIG_KL_TPM0_PWM +static struct kl_pwmtimer_s g_pwm0dev = +{ + .ops = &g_pwmops, + .tpmid = 0, + .channel = CONFIG_KL_TPM0_CHANNEL, + .base = KL_TPM0_BASE, + .pincfg = PWM_TPM0_PINCFG, + .pclk = BOARD_CORECLK_FREQ, +}; +#endif + +#ifdef CONFIG_KL_TPM1_PWM +static struct kl_pwmtimer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .tpmid = 1, + .channel = CONFIG_KL_TPM1_CHANNEL, + .base = KL_TPM1_BASE, + .pincfg = PWM_TPM1_PINCFG, + .pclk = BOARD_CORECLK_FREQ, +}; +#endif + +#ifdef CONFIG_KL_TPM2_PWM +static struct kl_pwmtimer_s g_pwm2dev = +{ + .ops = &g_pwmops, + .tpmid = 2, + .channel = CONFIG_KL_TPM2_CHANNEL, + .base = KL_TPM2_BASE, + .pincfg = PWM_TPM2_PINCFG, + .pclk = BOARD_CORECLK_FREQ, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t pwm_getreg(struct kl_pwmtimer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_putreg(struct kl_pwmtimer_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct kl_pwmtimer_s *priv, FAR const char *msg) +{ + int nchannels = (priv->tpmid == 0) ? 6 : 2; + + pwmvdbg("%s:\n", msg); + pwmvdbg(" TPM%d_SC: %04x TPM%d_CNT: %04x TPM%d_MOD: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_CNT_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_MOD_OFFSET)); + pwmvdbg(" TPM%d_STATUS: %04x TPM%d_CONF: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_STATUS_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_CONF_OFFSET)); + pwmvdbg(" TPM%d_C0SC: %04x TPM%d_C0V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C0SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C0V_OFFSET)); + pwmvdbg(" TPM%d_C1SC: %04x TPM%d_C1V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C1SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C1V_OFFSET)); + + if (nchannels >= 3) + { + pwmvdbg(" TPM%d_C2SC: %04x TPM%d_C2V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C2SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C2V_OFFSET)); + } + + if (nchannels >= 4) + { + pwmvdbg(" TPM%d_C3SC: %04x TPM%d_C3V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C3SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C3V_OFFSET)); + } + + if (nchannels >= 5) + { + pwmvdbg(" TPM%d_C4SC: %04x TPM%d_C4V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C4SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C4V_OFFSET)); + } + + if (nchannels >= 6) + { + pwmvdbg(" TPM%d_C5SC: %04x TPM%d_C5V: %04x\n", + priv->tpmid, + pwm_getreg(priv, TPM_C5SC_OFFSET), + priv->tpmid, + pwm_getreg(priv, TPM_C5V_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: pwm_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_timer(FAR struct kl_pwmtimer_s *priv, + FAR const struct pwm_info_s *info) +{ + /* Calculated values */ + + uint32_t prescaler; + uint32_t tpmclk; + uint32_t modulo; + uint32_t regval; + uint32_t cv; + uint8_t i; + + static const uint8_t presc_values[8] = {1, 2, 4, 8, 16, 32, 64, 128}; + + /* Register contents */ + + DEBUGASSERT(priv != NULL && info != NULL); + + pwmvdbg("TPM%d channel: %d frequency: %d duty: %08x\n", + priv->tpmid, priv->channel, info->frequency, info->duty); + + DEBUGASSERT(info->frequency > 0 && info->duty > 0 && + info->duty < uitoub16(100)); + + /* Calculate optimal values for the timer prescaler and for the timer modulo + * register. If' frequency' is the desired frequency, then + * + * modulo = tpmclk / frequency + * tpmclk = pclk / presc + * + * Or, + * + * modulo = pclk / presc / frequency + * + * There are many solutions to do this, but the best solution will be the + * one that has the largest modulo value and the smallest prescaler value. + * That is the solution that should give us the most accuracy in the timer + * control. Subject to: + * + * 1 <= presc <= 128 (need to be 1, 2, 4, 8, 16, 32, 64, 128) + * 1 <= modulo <= 65535 + * + * So presc = pclk / 65535 / frequency would be optimal. + * + * Example: + * + * pclk = 24 MHz + * frequency = 100 Hz + * + * prescaler = 24,000,000 / 65,535 / 100 + * = 3.6 (or 4 -- taking the ceiling always) + * timclk = 24,000,000 / 4 + * = 6,000,000 + * modulo = 6,000,000 / 100 + * = 60,000 + */ + + prescaler = (priv->pclk / info->frequency + 65534) / 65535; + + for (i = 0; i < 7; i++) + { + if (prescaler <= presc_values[i]) + { + break; + } + } + + prescaler = i; + + tpmclk = priv->pclk / presc_values[prescaler]; + + modulo = tpmclk / info->frequency; + if (modulo < 1) + { + modulo = 1; + } + else if (modulo > 65535) + { + modulo = 65535; + } + + /* Duty cycle: + * + * duty cycle = cv / modulo (fractional value) + */ + + cv = b16toi(info->duty * modulo + b16HALF); + + pwmvdbg("TPM%d PCLK: %d frequency: %d TPMCLK: %d prescaler: %d modulo: %d c0v: %d\n", + priv->tpmid, priv->pclk, info->frequency, tpmclk, + presc_values[prescaler], modulo, cv); + + /* Disable TPM and reset CNT before writing MOD and PS */ + + pwm_putreg(priv, TPM_SC_OFFSET, TPM_SC_CMOD_DIS); + pwm_putreg(priv, TPM_CNT_OFFSET, 0); + + /* Set the modulo value */ + + pwm_putreg(priv, TPM_MOD_OFFSET, (uint16_t)modulo); + + /* Set the duty cycle for channel specific */ + + switch (priv->channel) + { + case 0: /* PWM Mode configuration: Channel 0 */ + { + pwm_putreg(priv, TPM_C0SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C0V_OFFSET, (uint16_t) cv); + } + break; + + case 1: /* PWM Mode configuration: Channel 1 */ + { + pwm_putreg(priv, TPM_C1SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C1V_OFFSET, (uint16_t) cv); + } + break; + + case 2: /* PWM Mode configuration: Channel 2 */ + { + pwm_putreg(priv, TPM_C2SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C2V_OFFSET, (uint16_t) cv); + } + break; + + case 3: /* PWM Mode configuration: Channel 3 */ + { + pwm_putreg(priv, TPM_C3SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C3V_OFFSET, (uint16_t) cv); + } + break; + + case 4: /* PWM Mode configuration: Channel 4 */ + { + pwm_putreg(priv, TPM_C4SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C4V_OFFSET, (uint16_t) cv); + } + break; + + case 5: /* PWM Mode configuration: Channel 5 */ + { + pwm_putreg(priv, TPM_C5SC_OFFSET, TPM_CnSC_MSB | TPM_CnSC_ELSB); + pwm_putreg(priv, TPM_C5V_OFFSET, (uint16_t) cv); + } + break; + + default: + pwmdbg("No such channel: %d\n", priv->channel); + return -EINVAL; + } + + /* Set prescaler and enable clock */ + + regval = pwm_getreg(priv, TPM_SC_OFFSET); + regval &= ~(TPM_SC_PS_MASK); + regval &= ~(TPM_SC_CMOD_MASK); + regval |= prescaler | TPM_SC_CMOD_LPTPM_CLK; + pwm_putreg(priv, TPM_SC_OFFSET, (uint16_t)regval); + + pwm_dumpregs(priv, "After starting"); + return OK; +} + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * AHB1 or 2 clocking for the GPIOs and timer has already been configured + * by the RCC logic at power up. + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + uint32_t regval; + FAR struct kl_pwmtimer_s *priv = (FAR struct kl_pwmtimer_s *)dev; + + /* Enable access to TPM modules */ + + regval = getreg32(KL_SIM_SCGC6); + regval |= SIM_SCGC6_TPM0 | SIM_SCGC6_TPM1 | SIM_SCGC6_TPM2; + putreg32(regval, KL_SIM_SCGC6); + + pwmvdbg("TPM%d pincfg: %08x\n", priv->tpmid, priv->pincfg); + pwm_dumpregs(priv, "Initially"); + + /* Configure the PWM output pin, but do not start the timer yet */ + + kl_configgpio(priv->pincfg); + pwm_dumpgpio(priv->pincfg, "PWM setup"); + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct kl_pwmtimer_s *priv = (FAR struct kl_pwmtimer_s *)dev; + uint32_t pincfg; + + pwmvdbg("TPM%d pincfg: %08x\n", priv->tpmid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + pwm_stop(dev); + + /* Then put the GPIO pin back to the default state */ + + pincfg = (priv->pincfg & ~(_PIN_MODE_MASK)); + pincfg |= GPIO_INPUT; + kl_configgpio(pincfg); + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct kl_pwmtimer_s *priv = (FAR struct kl_pwmtimer_s *)dev; + return pwm_timer(priv, info); +} + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct kl_pwmtimer_s *priv = (FAR struct kl_pwmtimer_s *)dev; + irqstate_t flags; + + pwmvdbg("TPM%d\n", priv->tpmid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + pwm_putreg(priv, TPM_SC_OFFSET, TPM_SC_CMOD_DIS); + pwm_putreg(priv, TPM_CNT_OFFSET, 0); + + /* Determine which timer channel to clear */ + + switch (priv->channel) + { + case 0: + pwm_putreg(priv, TPM_C0V_OFFSET, 0); + break; + + case 1: + pwm_putreg(priv, TPM_C1V_OFFSET, 0); + break; + + case 2: + pwm_putreg(priv, TPM_C2V_OFFSET, 0); + break; + + case 3: + pwm_putreg(priv, TPM_C3V_OFFSET, 0); + break; + + case 4: + pwm_putreg(priv, TPM_C4V_OFFSET, 0); + break; + + case 5: + pwm_putreg(priv, TPM_C5V_OFFSET, 0); + break; + + default: + pwmdbg("No such channel: %d\n", priv->channel); + return -EINVAL; + } + + leave_critical_section(flags); + + pwm_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct kl_pwmtimer_s *priv = (FAR struct kl_pwmtimer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("TPM%d\n", priv->tpmid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. + * + * Returned Value: + * On success, a pointer to the KL lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *kl_pwminitialize(int timer) +{ + FAR struct kl_pwmtimer_s *lower; + + pwmvdbg("TPM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_KL_TPM0_PWM + case 0: + lower = &g_pwm0dev; + + break; +#endif + +#ifdef CONFIG_KL_TPM1_PWM + case 1: + lower = &g_pwm1dev; + + break; +#endif + +#ifdef CONFIG_KL_TPM2_PWM + case 2: + lower = &g_pwm2dev; + + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_KL_TPMn_PWM, n = 0,...,2 */ diff --git a/arch/arm/src/kl/kl_pwm.h b/arch/arm/src/kl/kl_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..f9afbcd7800e602b7c695fcdb67992d71cff7d5d --- /dev/null +++ b/arch/arm/src/kl/kl_pwm.h @@ -0,0 +1,192 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_pwm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_PWM_H +#define __ARCH_ARM_SRC_KL_KINETIS_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is + * to generate modulated outputs for such things as motor control. If CONFIG_KL_TPMn + * is defined then the CONFIG_KL_TPMn_PWM must also be defined to indicate that + * timer "n" is intended to be used for pulsed output signal generation. + */ + +#ifndef CONFIG_KL_TPM0 +# undef CONFIG_KL_TPM0_PWM +#endif +#ifndef CONFIG_KL_TPM1 +# undef CONFIG_KL_TPM1_PWM +#endif +#ifndef CONFIG_KL_TPM2 +# undef CONFIG_KL_TPM2_PWM +#endif + +/* Check if PWM support for any channel is enabled. */ + +#if defined(CONFIG_KL_TPM0_PWM) || defined(CONFIG_KL_TPM1_PWM) || \ + defined(CONFIG_KL_TPM2_PWM) + +#include +#include "chip/kl_pinmux.h" + +/* For each timer that is enabled for PWM usage, we need the following additional + * configuration settings: + * + * CONFIG_KL_TPMx_CHANNEL - Specifies the timer output channel {1,..,4} + * PWM_TPMx_CHn - One of the values defined in chip/kl*_pinmap.h. In the case + * where there are multiple pin selections, the correct setting must be provided + * in the arch/board/board.h file. + */ + +#ifdef CONFIG_KL_TPM0_PWM +# if !defined(CONFIG_KL_TPM0_CHANNEL) +# error "CONFIG_KL_TPM0_CHANNEL must be provided" +# elif CONFIG_KL_TPM0_CHANNEL == 0 +# define PWM_TPM0_PINCFG GPIO_TPM0_CH0OUT +# elif CONFIG_KL_TPM0_CHANNEL == 1 +# define PWM_TPM0_PINCFG GPIO_TPM0_CH1OUT +# elif CONFIG_KL_TPM0_CHANNEL == 2 +# define PWM_TPM0_PINCFG GPIO_TPM1_CH2OUT +# elif CONFIG_KL_TPM0_CHANNEL == 3 +# define PWM_TPM0_PINCFG GPIO_TPM1_CH3OUT +# elif CONFIG_KL_TPM0_CHANNEL == 4 +# define PWM_TPM0_PINCFG GPIO_TPM1_CH4OUT +# elif CONFIG_KL_TPM0_CHANNEL == 5 +# define PWM_TPM0_PINCFG GPIO_TPM1_CH5OUT +# else +# error "Unsupported value of CONFIG_KL_TPM1_CHANNEL" +# endif +#endif + +#ifdef CONFIG_KL_TPM1_PWM +# if !defined(CONFIG_KL_TPM1_CHANNEL) +# error "CONFIG_KL_TPM1_CHANNEL must be provided" +# elif CONFIG_KL_TPM1_CHANNEL == 0 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH0OUT +# elif CONFIG_KL_TPM1_CHANNEL == 1 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH1OUT +# elif CONFIG_KL_TPM1_CHANNEL == 2 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH2OUT +# elif CONFIG_KL_TPM1_CHANNEL == 3 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH3OUT +# elif CONFIG_KL_TPM1_CHANNEL == 4 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH4OUT +# elif CONFIG_KL_TPM1_CHANNEL == 5 +# define PWM_TPM1_PINCFG GPIO_TPM1_CH5OUT +# else +# error "Unsupported value of CONFIG_KL_TPM2_CHANNEL" +# endif +#endif + +#ifdef CONFIG_KL_TPM2_PWM +# if !defined(CONFIG_KL_TPM2_CHANNEL) +# error "CONFIG_KL_TPM2_CHANNEL must be provided" +# elif CONFIG_KL_TPM2_CHANNEL == 0 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH0OUT +# elif CONFIG_KL_TPM2_CHANNEL == 1 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH1OUT +# elif CONFIG_KL_TPM2_CHANNEL == 2 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH2OUT +# elif CONFIG_KL_TPM2_CHANNEL == 3 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH3OUT +# elif CONFIG_KL_TPM2_CHANNEL == 4 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH4OUT +# elif CONFIG_KL_TPM2_CHANNEL == 5 +# define PWM_TPM2_PINCFG GPIO_TPM2_CH5OUT +# else +# error "Unsupported value of CONFIG_KL_TPM3_CHANNEL" +# endif +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: kl_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. + * + * Returned Value: + * On success, a pointer to the KL lower half PWM driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +FAR struct pwm_lowerhalf_s *kl_pwminitialize(int timer); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_KL_TPMx_PWM */ +#endif /* __ARCH_ARM_SRC_KL_KINETIS_PWM_H */ diff --git a/arch/arm/src/kl/kl_serial.c b/arch/arm/src/kl/kl_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..fb135ca79557b979872f8868c6bcc95db781a421 --- /dev/null +++ b/arch/arm/src/kl/kl_serial.c @@ -0,0 +1,975 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_serial.c + * + * Copyright (C) 2013-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "kl_config.h" +#include "kl_lowputc.h" +#include "kl_lowgetc.h" +#include "chip.h" +#include "kl_gpio.h" +#include "chip/kl_uart.h" + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Is there at least one UART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_UART_DEVICE +# warning "No UARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-5 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_KL_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_KL_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_KL_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-5 excluding the console UART. */ + +#if defined(CONFIG_KL_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_KL_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_KL_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-5. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-5 could also be the + * console. + */ + +#if defined(CONFIG_KL_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_KL_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-5. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-5 could also be the console. + */ + +#if defined(CONFIG_KL_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t clock; /* Clocking frequency of the UART module */ + uint8_t irq; /* IRQ associated with this UART (for enable) */ + uint8_t ie; /* Interrupts enabled */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupts(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; + +/* I/O buffers */ + +#ifdef CONFIG_KL_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_KL_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_KL_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +/* This describes the state of the Kinetis UART0 port. */ + +#ifdef CONFIG_KL_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = KL_UART0_BASE, + .clock = BOARD_CORECLK_FREQ, + .baud = CONFIG_UART0_BAUD, + .irq = KL_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the Kinetis UART1 port. */ + +#ifdef CONFIG_KL_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = KL_UART1_BASE, + .clock = BOARD_BUSCLK_FREQ, + .baud = CONFIG_UART1_BAUD, + .irq = KL_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the Kinetis UART2 port. */ + +#ifdef CONFIG_KL_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = KL_UART2_BASE, + .clock = BOARD_BUSCLK_FREQ, + .baud = CONFIG_UART2_BAUD, + .irq = KL_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_setuartint + ****************************************************************************/ + +static void up_setuartint(struct up_dev_s *priv) +{ + irqstate_t flags; + uint8_t regval; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ + + flags = enter_critical_section(); + regval = up_serialin(priv, KL_UART_C2_OFFSET); + regval &= ~UART_C2_ALLINTS; + regval |= priv->ie; + up_serialout(priv, KL_UART_C2_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint8_t ie) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ + + flags = enter_critical_section(); + priv->ie = ie & UART_C2_ALLINTS; + up_setuartint(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint8_t *ie) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ie) + { + *ie = priv->ie; + } + + up_restoreuartint(priv, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Configure the UART as an RS-232 UART */ + + kl_uartconfigure(priv->uartbase, priv->baud, priv->clock, + priv->parity, priv->bits); +#endif + + /* Make sure that all interrupts are disabled */ + + up_restoreuartint(priv, 0); + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); + + /* Reset hardware and disable Rx and Tx */ + + kl_uartreset(priv->uartbase); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(priv->irq, up_interrupts); + if (ret == OK) + { + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); + up_disable_irq(priv->irq); + + /* Detach from the interrupt(s) */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupts + * + * Description: + * This is the UART status interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupts(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + int passes; + uint8_t s1; + bool handled; + +#ifdef CONFIG_KL_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_KL_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_KL_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv); + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Read status register 1 */ + + s1 = up_serialin(priv, KL_UART_S1_OFFSET); + + /* Check if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + * + * The RDRF status indication is cleared when the data is read from + * the RX data register. + */ + + if ((s1 & UART_S1_RDRF) != 0) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + /* Check if the transmit data register is "empty." NOTE: If FIFOS + * are enabled, this does not mean that the FIFO is empty, rather, + * it means that the number of bytes in the TX FIFO is below the + * watermark setting. There could actually be space for additional TX + * data. + * + * The TDRE status indication is cleared when the data is written to + * the TX data register. + */ + + if ((s1 & UART_S1_TDRE) != 0) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + + /* Handle error interrupts. This interrupt may be caused by: + * + * FE: Framing error. To clear FE, write a logic one to the FE flag. + * NF: Noise flag. To clear NF, write logic one to the NF. + * PF: Parity error flag. To clear PF, write a logic one to the PF. + * OR: Receiver Overrun Flag. To clear OR, write a logic 1 to the OR flag. + */ + + if ((s1 & UART_S1_ERRORS) != 0) + { + up_serialout(priv, KL_UART_S1_OFFSET, (s1 & UART_S1_ERRORS)); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + struct inode *inode; + struct uart_dev_s *dev; + struct up_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct up_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint8_t s1; + + /* Get error status information: + * + * FE: Framing error. To clear FE, read S1 with FE set and then read + * read UART data register (D). + * NF: Noise flag. To clear NF, read S1 and then read the UART data + * register (D). + * PF: Parity error flag. To clear PF, read S1 and then read the UART + * data register (D). + */ + + s1 = up_serialin(priv, KL_UART_S1_OFFSET); + + /* Return status information */ + + if (status) + { + *status = (uint32_t)s1; + } + + /* Then return the actual received byte. Reading S1 then D clears all + * RX errors. + */ + + return (int)up_serialin(priv, KL_UART_D_OFFSET); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register + * (or an Rx timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_RIE; + up_setuartint(priv); +#endif + } + else + { + priv->ie &= ~UART_C2_RIE; + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + */ + + return (up_serialin(priv, KL_UART_S1_OFFSET) & UART_S1_RDRF) != 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, KL_UART_D_OFFSET, (uint8_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_TIE; + up_setuartint(priv); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ie &= ~UART_C2_TIE; + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true if the transmit data register is "empty." NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is empty, + * rather, it means that the number of bytes in the TX FIFO is + * below the watermark setting. There may actually be space for + * additional TX data. + */ + + return (up_serialin(priv, KL_UART_S1_OFFSET) & UART_S1_TDRE) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock + * initialization performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit() + */ + + up_restoreuartint(TTYS0_DEV.priv, 0); +#ifdef TTYS1_DEV + up_restoreuartint(TTYS1_DEV.priv, 0); +#endif +#ifdef TTYS2_DEV + up_restoreuartint(TTYS2_DEV.priv, 0); +#endif +#ifdef TTYS3_DEV + up_restoreuartint(TTYS3_DEV.priv, 0); +#endif +#ifdef TTYS4_DEV + up_restoreuartint(TTYS4_DEV.priv, 0); +#endif +#ifdef TTYS5_DEV + up_restoreuartint(TTYS5_DEV.priv, 0); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t ie; + + up_disableuartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + kl_lowputc('\r'); + } + + kl_lowputc(ch); + up_restoreuartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + kl_lowputc('\r'); + } + + kl_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: up_getc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_getc(void) +{ + /* Check for LF */ + + return kl_lowgetc(); +} +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/kl/kl_spi.c b/arch/arm/src/kl/kl_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..0b738aedf5ea7f135d36c638cd8959fe050ecff8 --- /dev/null +++ b/arch/arm/src/kl/kl_spi.c @@ -0,0 +1,719 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_spi.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "kl_spi.h" +#include "kl_gpio.h" +#include "chip/kl_memorymap.h" +#include "chip/kl_sim.h" +#include "chip/kl_spi.h" +#include "chip/kl_pinmux.h" + +#if defined(CONFIG_KL_SPI0) || defined(CONFIG_KL_SPI1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ +/* The following enable debug output from this file: + * + * CONFIG_DEBUG - Define to enable general debug features + * CONFIG_DEBUG_SPI - Define to enable basic SSP debug (needs CONFIG_DEBUG) + * CONFIG_DEBUG_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct kl_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* Base address of SPI registers */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* Helpers */ + +static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv, uint8_t offset); +static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset, + uint8_t value); + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_KL_SPI0 +static const struct spi_ops_s g_spi0ops = +{ + .lock = spi_lock, + .select = kl_spi0select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = kl_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = kl_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not supported */ +}; + +static struct kl_spidev_s g_spi0dev = +{ + .spidev = { &g_spi0ops }, + .spibase = KL_SPI0_BASE, +}; +#endif + +#ifdef CONFIG_KL_SPI1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = kl_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = kl_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = kl_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, +}; + +static struct kl_spidev_s g_spi1dev = +{ + .spidev = { &g_spi1ops }, + .spibase = KL_SPI1_BASE, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv, uint8_t offset) +{ + return getreg8(priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset, + uint8_t value) +{ + putreg8(value, priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ************************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/************************************************************************************ + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev; + uint32_t divisor; + uint32_t actual; + unsigned int spr; + unsigned int sppr; + + /* Check if the requested frequence is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* The clock source for the SPI baud rate generator is the bus clock. We + * need to pick a prescaler value 1, 2, 3, 4, 5, 6, 7, or 8 and then a + * divisor in the range {2, 4, 8, 16, 32, 64, 128, 256, or 512). + * + * + * BaudRateDivisor = (SPPR + 1) × 2^(SPR + 1) + * BaudRate = BusClock / BaudRateDivisor + * + * The strategy is to pick the smallest divisor that yields an in-range + * solution. I am not sure if this *always* results in an optimal solution. + * But consider, for example, with a 24Mhz bus clock and a target of 400KHz + * + * target divisor is 24,000,000 / 400,000 = 60 + * spr = 1 -> sppr = 60 / (1 << 1) = 30 -> out of range + * spr = 2 -> sppr = 60 / (1 << 2) = 15 -> out of range + * spr = 3 -> sppr = 60 / (1 << 3) = 7 -> actual = 24000000 / 7 * 8 = 428571 + * spr = 4 -> sppr = 60 / (1 << 4) = 3 -> actual = 24000000 / 3 * 16 = 500000 + * spr = 5 -> sppr = 60 / (1 << 5) = 1 -> actual = 24000000 / 1 * 32 = 750000 + */ + + divisor = BOARD_BUSCLK_FREQ / frequency; + for (spr = 1; spr < 10; spr++) + { + sppr = divisor / (1 << spr); + if (sppr < 9) + { + break; + } + } + + /* Handle failures to find a solution by forcing spr to the maximum value */ + + DEBUGASSERT(spr < 10); + if (spr > 9) + { + spr = 9; + sppr = divisor / 512; + } + + /* Write the new dividers to the BR register */ + + spi_putreg(priv, KL_SPI_BR_OFFSET, SPI_BR_SPR_DIV(spr) | SPI_BR_SPPR(sppr)); + + /* Calculate the actual divisor and frequency */ + + divisor = sppr * (1 << spr); + actual = BOARD_BUSCLK_FREQ / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/************************************************************************************ + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev; + uint8_t regval; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set C1 appropriately */ + + regval = spi_getreg(priv, KL_SPI_C1_OFFSET); + regval &= ~(SPI_C1_CPOL | SPI_C1_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_C1_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_C1_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_C1_CPOL | SPI_C1_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(priv, KL_SPI_C1_OFFSET, regval); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/************************************************************************************ + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + /* Only 8-bit mode is supported */ + + DEBUGASSERT(nbits == 8); +} + +/************************************************************************************ + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev; + + /* Make sure that the transmit buffer is empty */ + + while ((spi_getreg(priv, KL_SPI_S_OFFSET) & SPI_S_SPTEF) == 0); + + /* Write the data to transmitted to the SPI Data Register */ + + spi_putreg(priv, KL_SPI_D_OFFSET, (uint8_t)wd); + + /* Wait for the SPRF bit in the SPI Status Register to be set to 1. SPRF is set + * at the completion of an SPI transfer to indicate that received data may be read + * from the SPI data registr + */ + + while ((spi_getreg(priv, KL_SPI_S_OFFSET) & SPI_S_SPRF) == 0); + + /* Return the data */ + + return (uint16_t)spi_getreg(priv, KL_SPI_D_OFFSET); +} + +/************************************************************************************ + * Name: spi_exchange + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchaned in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev; + FAR uint8_t *rxptr = (FAR uint8_t *)rxbuffer; + FAR uint8_t *txptr = (FAR uint8_t *)txbuffer; + uint8_t data; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Loop, sending each word in the user-provied data buffer. */ + + for (; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source) */ + + if (txptr) + { + data = (uint8_t)*txptr++; + } + else + { + data = 0xff; + } + + /* Wait for any previous data written to the TDR to be transferred + * to the serializer. + */ + + while ((spi_getreg(priv, KL_SPI_S_OFFSET) & SPI_S_SPTEF) == 0); + + /* Write the data to transmitted to the Transmit Data Register (TDR) */ + + spi_putreg(priv, KL_SPI_D_OFFSET, data); + + /* Wait for the read data to be available in the data regiter */ + + while ((spi_getreg(priv, KL_SPI_S_OFFSET) & SPI_S_SPRF) == 0); + + /* Read the received data from the SPI Data Register.. + * TODO: The following only works if nbits <= 8. + */ + + data = spi_getreg(priv, KL_SPI_D_OFFSET); + if (rxptr) + { + *rxptr++ = (uint8_t)data; + } + } +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *kl_spibus_initialize(int port) +{ + FAR struct kl_spidev_s *priv; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select pins + * must be configured by board-specific logic. Most SPI pins multiple, + * alternative pin selection. Definitions in the board.h file must be\ + * provided to resolve the board-specific pin configuration like: + * + * #define PIN_SPI0_SCK PIN_SPI0_SCK_1 + */ + +#ifdef CONFIG_KL_SPI0 + if (port == 0) + { + priv = &g_spi0dev; + + /* Configure pins for SPI0 */ + + kl_configgpio(PIN_SPI0_SCK); + kl_configgpio(PIN_SPI0_MISO); + kl_configgpio(PIN_SPI0_MOSI); + + /* Enable clocking */ + + regval = getreg32(KL_SIM_SCGC4); + regval |= SIM_SCGC4_SPI0; + putreg32(regval, KL_SIM_SCGC4); + } + else +#endif +#ifdef CONFIG_KL_SPI1 + if (port == 1) + { + priv = &g_spi1dev; + + /* Configure pins for SPI1 */ + + kl_configgpio(PIN_SPI1_SCK); + kl_configgpio(PIN_SPI1_MISO); + kl_configgpio(PIN_SPI1_MOSI); + + /* Enable clocking */ + + regval = getreg32(KL_SIM_SCGC4); + regval |= SIM_SCGC4_SPI1; + putreg32(regval, KL_SIM_SCGC4); + } + else +#endif + { + spidbg("ERROR: Port %d not configured\n", port); + return NULL; + } + + /* Configure master mode, select mode 0, MSB first. Disable interrupts. */ + + spi_putreg(priv, KL_SPI_C1_OFFSET, SPI_C1_SPE | SPI_C1_MSTR); + + /* Disable interrupts, DMA, bidirectional mode, stop-in-wait mode, enable + * master mode fault detection + */ + + spi_putreg(priv, KL_SPI_C2_OFFSET, 0); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + return &priv->spidev; +} + +#endif /* CONFIG_KL_SPI0 || CONFIG_KL_SPI1 */ diff --git a/arch/arm/src/kl/kl_spi.h b/arch/arm/src/kl/kl_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..466ab832f8ed50b70eedd17442011e3e88ab89e9 --- /dev/null +++ b/arch/arm/src/kl/kl_spi.h @@ -0,0 +1,131 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KL_SPI_H +#define __ARCH_ARM_SRC_KL_KL_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_KL_SPI0) || defined(CONFIG_KL_SPI1) + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: kl_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *kl_spibus_initialize(int port); + +/************************************************************************************ + * Name: kl_spi[n]select, kl_spi[n]status, and kl_spi[n]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including kl_spibus_initialize()) are provided by common Kinetis logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in kl_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide kl_spi[n]select() and kl_spi[n]status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * kl_spi[n]cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to kl_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by kl_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_KL_SPI0 +void kl_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t kl_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int kl_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_KL_SPI1 +void kl_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t kl_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int kl_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_KL_SPI0 || CONFIG_KL_SPI1 */ +#endif /* __ARCH_ARM_SRC_KL_KL_SPI_H */ diff --git a/arch/arm/src/kl/kl_start.c b/arch/arm/src/kl/kl_start.c new file mode 100644 index 0000000000000000000000000000000000000000..63491ac74d70503d749dfb32f01c9d59e55f0173 --- /dev/null +++ b/arch/arm/src/kl/kl_start.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_start.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/kl_sim.h" + +#include "kl_config.h" +#include "kl_gpio.h" +#include "kl_lowputc.h" +#include "kl_userspace.h" +#include "kl_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map: + * + * 0x0000:0000 - Beginning of FLASH. Address of exception vectors. + * 0x0001:ffff - End of flash (assuming 128KB of FLASH) + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap + * 0x2000:3fff - End of SRAM and end of heap (assuming 16KB of SRAM) + */ + +#define IDLE_STACK ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uint32_t g_idle_topstack = IDLE_STACK; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) +# define showprogress(c) kl_lowputc((uint32_t)c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Disable the watchdog */ + + putreg32(0, KL_SIM_COPC); + + /* Configure the uart so that we can get debug output as soon as possible */ + + kl_clockconfig(); + kl_lowsetup(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + kl_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + kl_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +} + diff --git a/arch/arm/src/kl/kl_timerisr.c b/arch/arm/src/kl/kl_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..bcd17b0648527103b02094af8ef7070cfe45887f --- /dev/null +++ b/arch/arm/src/kl/kl_timerisr.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_timerisr.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* "The CLKSOURCE bit in SysTick Control and Status register selects either + * the core clock (when CLKSOURCE = 1) or a divide-by-16 of the core clock + * (when CLKSOURCE = 0). ..." + */ + +#if defined(CONFIG_KL_SYSTICK_CORECLK) +# define SYSTICK_CLOCK BOARD_CORECLK_FREQ /* Core clock */ +#elif defined(CONFIG_KL_SYSTICK_CORECLK_DIV16) +# define (SYSTICK_CLOCK BOARD_CORECLK_FREQ / 16) /* Core clock divided by 16 */ +#endif + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * Then, for example, if the external high speed crystal is the SysTick + * clock source and BOARD_XTALHI_FREQUENCY is 12MHz and CLK_TCK is 100, then + * the reload value would be: + * + * SYSTICK_RELOAD = (12,000,000 / 100) - 1 + * = 119,999 + * = 0x1d4bf + * + * Which fits within the maximum 24-bit reload value. + */ + +#define SYSTICK_RELOAD ((SYSTICK_CLOCK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(ARMV6M_SYSCON_SHPR3); + regval &= ~SYSCON_SHPR3_PRI_15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << SYSCON_SHPR3_PRI_15_SHIFT); + putreg32(regval, ARMV6M_SYSCON_SHPR3); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, ARMV6M_SYSTICK_RVR); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(KL_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts. "The CLKSOURCE bit in SysTick Control and + * Status register selects either the core clock (when CLKSOURCE = 1) or + * a divide-by-16 of the core clock (when CLKSOURCE = 0). ..." + */ + +#ifdef CONFIG_KL_SYSTICK_CORECLK + putreg32((SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), + ARMV6M_SYSTICK_CSR); +#else + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), ARMV6M_SYSTICK_CSR); +#endif + + /* And enable the timer interrupt */ + + up_enable_irq(KL_IRQ_SYSTICK); +} diff --git a/arch/arm/src/kl/kl_userspace.c b/arch/arm/src/kl/kl_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..d9ecdda4a4d9a97f2f62c0a873d3dfc74a1c7d31 --- /dev/null +++ b/arch/arm/src/kl/kl_userspace.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/src/kl/kl_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "kl_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kl_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void kl_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/kl/kl_userspace.h b/arch/arm/src/kl/kl_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..a87af46f7e03b53776828f39857ea6119b3e43ef --- /dev/null +++ b/arch/arm/src/kl/kl_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/kl/kl_userspace.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KL_KINETIS_USERSPACE_H +#define __ARCH_ARM_SRC_KL_KINETIS_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: kl_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void kl_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_KL_KINETIS_USERSPACE_H */ diff --git a/arch/arm/src/lpc11xx/Kconfig b/arch/arm/src/lpc11xx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..127f3f0db89c6bd72f5371950d6f4dafdb735840 --- /dev/null +++ b/arch/arm/src/lpc11xx/Kconfig @@ -0,0 +1,263 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC11xx Configuration Options" + +choice + prompt "NXP LPC11XX Chip Selection" + default ARCH_CHIP_LPC1115 + depends on ARCH_CHIP_LPC11XX + +config ARCH_CHIP_LPC1114 + bool "LPC1114" + select ARCH_FAMILY_LPC111X + +config ARCH_CHIP_LPC1115 + bool "LPC1115" + select ARCH_FAMILY_LPC111X + +endchoice + +config ARCH_FAMILY_LPC111X + bool + +menu "LPC11xx Peripheral Support" + +choice + prompt "System Clock:" + default LPC11_INTRCOSC + +config LPC11_INTRCOSC + bool "Internal RC" + +config LPC11_MAINOSC + bool "External Crystal" + +endchoice + +choice + prompt "SysTick clock source" + default LPC11_SYSTICK_CORECLK + +config LPC11_SYSTICK_CORECLK + bool "Cortex-M0 core clock" + +config LPC11_SYSTICK_CORECLK_DIV16 + bool "Cortex-M0 core clock divided by 16" + +endchoice + +config LPC11_PLL + bool "PLL" + default y + +config LPC11_UART0 + bool "UART0" + select ARCH_HAVE_UART0 + default y + +config LPC11_CAN0 + bool "CAN0" + default n + +config LPC11_SPI + bool "SPI" + default n + +config LPC11_SSP0 + bool "SSP0" + default n + +config LPC11_SSP1 + bool "SSP1" + default n + +config LPC11_I2C0 + bool "I2C0" + default n + +config LPC11_TMR0 + bool "Timer 0" + default n + +config LPC11_TMR1 + bool "Timer 1" + default n + +config LPC11_WDT + bool "WDT" + default n + +config LPC11_ADC + bool "ADC" + default n + +config LPC11_FLASH + bool "FLASH" + default n + +endmenu + +menu "Serial driver options" + depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3 || LPC11_UART4 + +config SERIAL_TERMIOS + bool "Serial driver TERMIOS supported" + depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3 + default n + ---help--- + Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). + If this is not defined, then the terminal settings (baud, parity, etc). + are not configurable at runtime; serial streams cannot be flushed, etc.. + +endmenu + +menu "ADC driver options" + depends on LPC11_ADC + +config ADC0_AVERAGE + int "ADC0 average" + default 200 + +config ADC0_MASK + int "ADC0 mask" + default 1 + +config ADC0_SPS + int "ADC0 SPS" + default 1000 + +config ADC_CHANLIST + bool "Use ADC channel list" + default n + ---help--- + The errata that states: "A/D Global Data register should not be used + with burst mode or hardware triggering". If this option is selected, + then the ADC driver will grab from the individual channel registers + rather than from the global data register as this is the stated + workaround in the errata. + + The ADC interrupt will trigger on conversion complete on the last + channel listed in the array g_adc_chanlist[] (as opposed to + triggering interrupt from the global DONE flag). + + If this option is enabled, then the platform specific code must do + two things: (1) define ADC_NCHANNELS in the configuration file and + (2) provide an array g_adc_chanlist[] with the channel numbers + matching the ADC0_MASK within the board-specific library. + +config ADC_BURSTMODE + bool "One interrupt at the end of all ADC cconversions" + default n + ---help--- + Select this if you want to generate only one interrupt once all selected channels has been converted by the ADC + +config ADC_NCHANNELS + int "ADC0 number of channels" + depends on ADC_CHANLIST + default 0 + ---help--- + If ADC_CHANLIST is enabled, then the platform specific code + must do two things: (1) define ADC_NCHANNELS in the configuration + file and (2) provide an array g_adc_chanlist[] with the channel + numbers matching the ADC0_MASK within the board-specific library. + +endmenu + +menu "CAN driver options" + depends on LPC11_CAN1 || LPC11_CAN2 + +config CAN_EXTID + bool "CAN extended IDs" + default n + ---help--- + Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. + +config CAN1_BAUD + int "CAN1 BAUD" + depends on LPC11_CAN1 + ---help--- + CAN1 BAUD rate. Required if LPC11_CAN1 is defined. + +config CAN2_BAUD + int "CAN2 BAUD" + depends on LPC11_CAN2 + ---help--- + CAN2 BAUD rate. Required if LPC11_CAN2 is defined. + +config CAN1_DIVISOR + int "CAN1 CCLK divisor" + depends on LPC11_CAN1 + default 4 + ---help--- + CAN1 is clocked at CCLK divided by this number. (the CCLK frequency is divided + by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + +config CAN2_DIVISOR + int "CAN2 CCLK divisor" + depends on LPC11_CAN2 + default 4 + ---help--- + CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided + by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + +config CAN_TSEG1 + int "TSEG1 quanta" + default 6 + ---help--- + The number of CAN time quanta in segment 1. Default: 6 + +config CAN_TSEG2 + int "TSEG2 quanta" + default 4 + ---help--- + The number of CAN time quanta in segment 2. Default: 7 + +config CAN_SAM + bool "CAN sampling" + default n + ---help--- + The bus is sampled 3 times (recommended for low to medium speed buses to spikes on the bus-line). + +config CAN_LOOPBACK + bool "CAN looopback mode" + default n + ---help--- + Enable CAN loopback mode + +config CAN_REGDEBUG + bool "Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level CAN debug information. Requires also DEBUG and DEBUG_CAN. + +endmenu + +config GPIO_IRQ + bool "GPIO interrupt support" + default n + ---help--- + Enable support for GPIO interrupts + +menu "I2C driver options" + depends on LPC11_I2C0 || LPC11_I2C1 || LPC11_I2C2 + +config LPC11_I2C0_FREQUENCY + int "I2C0 frequency" + depends on LPC11_I2C0 + default 100000 + +config LPC11_I2C1_FREQUENCY + int "I2C1 frequency" + depends on LPC11_I2C1 + default 100000 + +config LPC11_I2C2_FREQUENCY + int "I2C2 frequency" + depends on LPC11_I2C2 + default 100000 + +endmenu diff --git a/arch/arm/src/lpc11xx/Make.defs b/arch/arm/src/lpc11xx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..a40c14354551c34726aea625a64d500731fd607f --- /dev/null +++ b/arch/arm/src/lpc11xx/Make.defs @@ -0,0 +1,105 @@ +############################################################################ +# arch/arm/src/lpc11xx/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_ASRCS = up_exception.S up_saveusercontext.S up_fullcontextrestore.S +CMN_ASRCS += up_switchcontext.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_puts.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vectors.c up_vfork.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CMN_CSRCS += up_dumpnvic.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = lpc11_clockconfig.c lpc11_gpio.c lpc11_i2c.c lpc11_idle.c +CHIP_CSRCS += lpc11_irq.c lpc11_lowputc.c lpc11_lowgetc.c lpc11_serial.c +CHIP_CSRCS += lpc11_spi.c lpc11_ssp.c lpc11_start.c + +# Configuration-dependent LPC11xx files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc11_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += lpc11_userspace.c +endif + +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += lpc11_gpioint.c +endif + +ifeq ($(CONFIG_ARCH_IRQPRIO),y) +CHIP_CSRCS += lpc11_irqprio.c +endif + +ifeq ($(CONFIG_LPC11_SPI0),y) +CHIP_CSRCS += lpc11_spi.c +else +ifeq ($(CONFIG_LPC11_SPI1),y) +CHIP_CSRCS += lpc11_spi.c +endif +endif + +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += lpc11_pwm.c +endif diff --git a/arch/arm/src/lpc11xx/chip.h b/arch/arm/src/lpc11xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..5057045b71f19246df1322b46281962359bc3711 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip.h @@ -0,0 +1,74 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "nvic.h" + +/* Include the chip capabilities file */ + +#include + +#define ARMV6M_PERIPHERAL_INTERRUPTS 32 + +/* Include the memory map file. Other chip hardware files should then include + * this file for the proper setup. + */ + +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc111x_iocon.h b/arch/arm/src/lpc11xx/chip/lpc111x_iocon.h new file mode 100644 index 0000000000000000000000000000000000000000..61fc8877a1235a6ca49d81f6e6d6fc8e6a458748 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc111x_iocon.h @@ -0,0 +1,269 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc111x_iocon.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC111X_IOCON_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC111X_IOCON_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define IOCON_NPINS 12 + +/* Register offsets *****************************************************************/ +/* Note: The IOCON offset is not linear. See User manual UM10398 Page 74 */ + +#define LPC11_IOCON_P0_0_OFFSET 0x00c +#define LPC11_IOCON_P0_1_OFFSET 0x010 +#define LPC11_IOCON_P0_2_OFFSET 0x01c +#define LPC11_IOCON_P0_3_OFFSET 0x02C +#define LPC11_IOCON_P0_4_OFFSET 0x030 +#define LPC11_IOCON_P0_5_OFFSET 0x034 +#define LPC11_IOCON_P0_6_OFFSET 0x04c +#define LPC11_IOCON_P0_7_OFFSET 0x050 +#define LPC11_IOCON_P0_8_OFFSET 0x060 +#define LPC11_IOCON_P0_9_OFFSET 0x064 +#define LPC11_IOCON_P0_10_OFFSET 0x068 +#define LPC11_IOCON_P0_11_OFFSET 0x074 + +#define LPC11_IOCON_P1_0_OFFSET 0x078 +#define LPC11_IOCON_P1_1_OFFSET 0x07c +#define LPC11_IOCON_P1_2_OFFSET 0x080 +#define LPC11_IOCON_P1_3_OFFSET 0x090 +#define LPC11_IOCON_P1_4_OFFSET 0x094 +#define LPC11_IOCON_P1_5_OFFSET 0x0a0 +#define LPC11_IOCON_P1_6_OFFSET 0x0a4 +#define LPC11_IOCON_P1_7_OFFSET 0x0a8 +#define LPC11_IOCON_P1_8_OFFSET 0x014 +#define LPC11_IOCON_P1_9_OFFSET 0x038 +#define LPC11_IOCON_P1_10_OFFSET 0x06c +#define LPC11_IOCON_P1_11_OFFSET 0x098 + +#define LPC11_IOCON_P2_0_OFFSET 0x008 +#define LPC11_IOCON_P2_1_OFFSET 0x028 +#define LPC11_IOCON_P2_2_OFFSET 0x05c +#define LPC11_IOCON_P2_3_OFFSET 0x08c +#define LPC11_IOCON_P2_4_OFFSET 0x040 +#define LPC11_IOCON_P2_5_OFFSET 0x044 +#define LPC11_IOCON_P2_6_OFFSET 0x000 +#define LPC11_IOCON_P2_7_OFFSET 0x020 +#define LPC11_IOCON_P2_8_OFFSET 0x024 +#define LPC11_IOCON_P2_9_OFFSET 0x054 +#define LPC11_IOCON_P2_10_OFFSET 0x058 +#define LPC11_IOCON_P2_11_OFFSET 0x070 + +#define LPC11_IOCON_P3_0_OFFSET 0x084 +#define LPC11_IOCON_P3_1_OFFSET 0x088 +#define LPC11_IOCON_P3_2_OFFSET 0x09C +#define LPC11_IOCON_P3_3_OFFSET 0x0ac +#define LPC11_IOCON_P3_4_OFFSET 0x03c +#define LPC11_IOCON_P3_5_OFFSET 0x048 + +#define LPC11_IOCON_SCK_LOC_OFFSET 0x0b0 +#define LPC11_IOCON_DSR_LOC_OFFSET 0x0b4 +#define LPC11_IOCON_DCD_LOC_OFFSET 0x0b8 +#define LPC11_IOCON_RI_LOC_OFFSET 0x0bc + +/* Register addresses ***************************************************************/ +/* Note: The IOCON base is not linear. See User manual UM10398 Page 74 */ + +#define LPC11_IOCON_P0_0 (LPC11_IOCON_BASE + LPC11_IOCON_P0_0_OFFSET) +#define LPC11_IOCON_P0_1 (LPC11_IOCON_BASE + LPC11_IOCON_P0_1_OFFSET) +#define LPC11_IOCON_P0_2 (LPC11_IOCON_BASE + LPC11_IOCON_P0_2_OFFSET) +#define LPC11_IOCON_P0_3 (LPC11_IOCON_BASE + LPC11_IOCON_P0_3_OFFSET) +#define LPC11_IOCON_P0_4 (LPC11_IOCON_BASE + LPC11_IOCON_P0_4_OFFSET) +#define LPC11_IOCON_P0_5 (LPC11_IOCON_BASE + LPC11_IOCON_P0_5_OFFSET) +#define LPC11_IOCON_P0_6 (LPC11_IOCON_BASE + LPC11_IOCON_P0_6_OFFSET) +#define LPC11_IOCON_P0_7 (LPC11_IOCON_BASE + LPC11_IOCON_P0_7_OFFSET) +#define LPC11_IOCON_P0_8 (LPC11_IOCON_BASE + LPC11_IOCON_P0_8_OFFSET) +#define LPC11_IOCON_P0_9 (LPC11_IOCON_BASE + LPC11_IOCON_P0_9_OFFSET) +#define LPC11_IOCON_P0_10 (LPC11_IOCON_BASE + LPC11_IOCON_P0_10_OFFSET) +#define LPC11_IOCON_P0_11 (LPC11_IOCON_BASE + LPC11_IOCON_P0_11_OFFSET) + +#define LPC11_IOCON_P1_0 (LPC11_IOCON_BASE + LPC11_IOCON_P1_0_OFFSET) +#define LPC11_IOCON_P1_1 (LPC11_IOCON_BASE + LPC11_IOCON_P1_1_OFFSET) +#define LPC11_IOCON_P1_2 (LPC11_IOCON_BASE + LPC11_IOCON_P1_2_OFFSET) +#define LPC11_IOCON_P1_3 (LPC11_IOCON_BASE + LPC11_IOCON_P1_3_OFFSET) +#define LPC11_IOCON_P1_4 (LPC11_IOCON_BASE + LPC11_IOCON_P1_4_OFFSET) +#define LPC11_IOCON_P1_5 (LPC11_IOCON_BASE + LPC11_IOCON_P1_5_OFFSET) +#define LPC11_IOCON_P1_6 (LPC11_IOCON_BASE + LPC11_IOCON_P1_6_OFFSET) +#define LPC11_IOCON_P1_7 (LPC11_IOCON_BASE + LPC11_IOCON_P1_7_OFFSET) +#define LPC11_IOCON_P1_8 (LPC11_IOCON_BASE + LPC11_IOCON_P1_8_OFFSET) +#define LPC11_IOCON_P1_9 (LPC11_IOCON_BASE + LPC11_IOCON_P1_9_OFFSET) +#define LPC11_IOCON_P1_10 (LPC11_IOCON_BASE + LPC11_IOCON_P1_10_OFFSET) +#define LPC11_IOCON_P1_11 (LPC11_IOCON_BASE + LPC11_IOCON_P1_11_OFFSET) + +#define LPC11_IOCON_P2_0 (LPC11_IOCON_BASE + LPC11_IOCON_P2_0_OFFSET) +#define LPC11_IOCON_P2_1 (LPC11_IOCON_BASE + LPC11_IOCON_P2_1_OFFSET) +#define LPC11_IOCON_P2_2 (LPC11_IOCON_BASE + LPC11_IOCON_P2_2_OFFSET) +#define LPC11_IOCON_P2_3 (LPC11_IOCON_BASE + LPC11_IOCON_P2_3_OFFSET) +#define LPC11_IOCON_P2_4 (LPC11_IOCON_BASE + LPC11_IOCON_P2_4_OFFSET) +#define LPC11_IOCON_P2_5 (LPC11_IOCON_BASE + LPC11_IOCON_P2_5_OFFSET) +#define LPC11_IOCON_P2_6 (LPC11_IOCON_BASE + LPC11_IOCON_P2_6_OFFSET) +#define LPC11_IOCON_P2_7 (LPC11_IOCON_BASE + LPC11_IOCON_P2_7_OFFSET) +#define LPC11_IOCON_P2_8 (LPC11_IOCON_BASE + LPC11_IOCON_P2_8_OFFSET) +#define LPC11_IOCON_P2_9 (LPC11_IOCON_BASE + LPC11_IOCON_P2_9_OFFSET) +#define LPC11_IOCON_P2_10 (LPC11_IOCON_BASE + LPC11_IOCON_P2_10_OFFSET) +#define LPC11_IOCON_P2_11 (LPC11_IOCON_BASE + LPC11_IOCON_P2_11_OFFSET) + +#define LPC11_IOCON_P3_0 (LPC11_IOCON_BASE + LPC11_IOCON_P3_0_OFFSET) +#define LPC11_IOCON_P3_1 (LPC11_IOCON_BASE + LPC11_IOCON_P3_1_OFFSET) +#define LPC11_IOCON_P3_2 (LPC11_IOCON_BASE + LPC11_IOCON_P3_2_OFFSET) +#define LPC11_IOCON_P3_3 (LPC11_IOCON_BASE + LPC11_IOCON_P3_3_OFFSET) +#define LPC11_IOCON_P3_4 (LPC11_IOCON_BASE + LPC11_IOCON_P3_4_OFFSET) +#define LPC11_IOCON_P3_5 (LPC11_IOCON_BASE + LPC11_IOCON_P3_5_OFFSET) + +#define LPC11_IOCON_SCK_LOC (LPC11_IOCON_BASE + LPC11_IOCON_SCK_LOC_OFFSET) +#define LPC11_IOCON_DSR_LOC (LPC11_IOCON_BASE + LPC11_IOCON_DSR_LOC_OFFSET) +#define LPC11_IOCON_DCD_LOC (LPC11_IOCON_BASE + LPC11_IOCON_DCD_LOC_OFFSET) +#define LPC11_IOCON_RI_LOC (LPC11_IOCON_BASE + LPC11_IOCON_RI_LOC_OFFSET) + +/* Register bit definitions *********************************************************/ +/* IOCON pin function select */ + +#define IOCON_FUNC_GPIO (0) +#define IOCON_FUNC_ALT1 (1) +#define IOCON_FUNC_ALT2 (2) +#define IOCON_FUNC_ALT3 (3) +#define IOCON_FUNC_ALT4 (4) +#define IOCON_FUNC_ALT5 (5) +#define IOCON_FUNC_ALT6 (6) +#define IOCON_FUNC_ALT7 (7) + +#define IOCON_FUNC_SHIFT (0) /* Bits 0-2: All types */ +#define IOCON_FUNC_MASK (7 << IOCON_FUNC_SHIFT) +#define IOCON_MODE_SHIFT (3) /* Bits 3-4: Type D,A,W */ +#define IOCON_MODE_MASK (3 << IOCON_MODE_SHIFT ) +#define IOCON_HYS_SHIFT (5) /* Bit 5: Type D,W */ +#define IOCON_HYS_MASK (1 << IOCON_HYS_SHIFT) + /* Bit 6-9: Reserved */ +#define IOCON_OD_SHIFT (10) /* Bit 10: Type D,A,W */ +#define IOCON_OD_MASK (1 << IOCON_OD_SHIFT) + /* Bit 11-31: Reserved */ + +/* Pin modes */ + +#define IOCON_MODE_FLOAT (0) /* 00: pin has neither pull-up nor pull-down */ +#define IOCON_MODE_PD (1) /* 01: pin has a pull-down resistor enabled */ +#define IOCON_MODE_PU (2) /* 10: pin has a pull-up resistor enabled */ +#define IOCON_MODE_RM (3) /* 11: pin has repeater mode enabled */ + +/* Pin types */ + +#define IOCON_TYPE_D_MASK (0x0000067f) /* All ports except where ADC/DAC, USB, I2C is present */ +#define IOCON_TYPE_A_MASK (0x000105df) /* USB/ADC/DAC P0:12-13, P0:23-26, P1:30-31 */ +#define IOCON_TYPE_U_MASK (0x00000007) /* USB P0:29 to 31 */ +#define IOCON_TYPE_I_MASK (0x00000347) /* I2C/USB P0:27-28, P5:2-3 */ +#define IOCON_TYPE_W_MASK (0x000007ff) /* I2S P0:7-9 */ + +/* Analog/Digital mode */ + +#define IOCON_ADMODE_SHIFT (7) +#define IOCON_ADMODE_ANALOG (0 << IOCON_ADMODE_SHIFT) +#define IOCON_ADMODE_DIGITAL (1 << IOCON_ADMODE_SHIFT) + +/* I2C modes */ + +#define IOCON_I2CMODE_SHIFT (8) +#define IOCON_I2CMODE_MASK (3 << IOCON_I2CMODE_SHIFT) +# define IOCON_I2CMODE_STANDARD (0 << IOCON_I2CMODE_SHIFT) +# define IOCON_I2CMODE_STANDIO (1 << IOCON_I2CMODE_SHIFT) +# define IOCON_I2CMODE_FASTPLUS (2 << IOCON_I2CMODE_SHIFT) + /*(3 << IOCON_I2CMODE_SHIFT) Reserved */ + /* Bits 10-31: Reserved */ + +/* SCK location register */ + +#define IOCON_SCK_LOC_SHIFT (0) +#define IOCON_SCK_LOC_MASK (3 << IOCON_SCK_LOC_SHIFT) +# define IOCON_SCK_LOC_SWCLK (0 << IOCON_SCK_LOC_SHIFT) +# define IOCON_SCK_LOC_PIO2_11 (1 << IOCON_SCK_LOC_SHIFT) +# define IOCON_SCK_LOC_PIO0_6 (2 << IOCON_SCK_LOC_SHIFT) + /*(3 << IOCON_SCK_LOC_SHIFT) Reserved */ + /* Bits 2-31: Reserved */ + +/* DSR location register */ + +#define IOCON_DSR_LOC_SHIFT (0) +#define IOCON_DSR_LOC_MASK (3 << IOCON_DSR_LOC_SHIFT) +# define IOCON_DSR_LOC_PIO2_1 (0 << IOCON_DSR_LOC_SHIFT) +# define IOCON_DSR_LOC_PIO3_1 (1 << IOCON_DSR_LOC_SHIFT) + /*(2 << IOCON_DSR_LOC_SHIFT) Reserved */ + /*(3 << IOCON_DSR_LOC_SHIFT) Reserved */ + /* Bits 2-31: Reserved */ + +/* DCD location register */ + +#define IOCON_DCD_LOC_SHIFT (0) +#define IOCON_DCD_LOC_MASK (3 << IOCON_DCD_LOC_SHIFT) +# define IOCON_DCD_LOC_PIO2_2 (0 << IOCON_DCD_LOC_SHIFT) +# define IOCON_DCD_LOC_PIO3_2 (1 << IOCON_DCD_LOC_SHIFT) + /*(2 << IOCON_DCD_LOC_SHIFT) Reserved */ + /*(3 << IOCON_DCD_LOC_SHIFT) Reserved */ + /* Bits 2-31: Reserved */ + +/* RI location register */ + +#define IOCON_RI_LOC_SHIFT (0) +#define IOCON_RI_LOC_MASK (3 << IOCON_RI_LOC_SHIFT) +# define IOCON_RI_LOC_PIO2_3 (0 << IOCON_RI_LOC_SHIFT) +# define IOCON_RI_LOC_PIO3_3 (1 << IOCON_RI_LOC_SHIFT) + /*(2 << IOCON_RI_LOC_SHIFT) Reserved */ + /*(3 << IOCON_RI_LOC_SHIFT) Reserved */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC118X_IOCON_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc111x_memorymap.h b/arch/arm/src/lpc11xx/chip/lpc111x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..21c12d01b034fe2a57d72314ea564bbb5914d4c1 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc111x_memorymap.h @@ -0,0 +1,107 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc111x_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC111X_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC11XX_LPC111X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ + +#define LPC11_FLASH_BASE 0x00000000 /* -0x1fffffff: On-chip non-volatile memory */ +#define LPC11_SRAM_BASE 0x10000000 /* -0x10007fff: On-chip SRAM (devices <=16Kb) */ +#define LPC11_ROM_BASE 0x1fff0000 /* -0x1fffffff: 16Kb Boot ROM with flash services */ +#define LPC11_AHBSRAM_BASE 0x20000000 /* -0x3fffffff: On-chip AHB SRAM (devices >32Kb) */ +#define LPC11_GPIO_BASE 0x50000000 /* -0x2009ffff: GPIO at AHB Peripherals */ +#define LPC11_APB_BASE 0x40000000 /* -0x4007ffff: APB Peripherals */ +#define LPC11_AHB_BASE 0x50000000 /* -0x501fffff: AHB Peripherals */ +#define LPC11_CORTEXM3_BASE 0xe0000000 /* -0xe00fffff: (see armv7-m/nvic.h) */ +#define LPC11_SCS_BASE 0xe000e000 +#define LPC11_DEBUGMCU_BASE 0xe0042000 + +/* APB Peripherals *****************************************************************/ + +#define LPC11_I2C0_BASE 0x40000000 /* -0x40003fff: I2C-bus */ +#define LPC11_WDT_BASE 0x40004000 /* -0x40007fff: Watchdog timer */ +#define LPC11_UART0_BASE 0x40008000 /* -0x4000bfff: UART 0 */ +#define LPC11_TMR0_BASE 0x4000c000 /* -0x4000ffff: Timer 0 */ +#define LPC11_TMR1_BASE 0x40010000 /* -0x40013fff: Timer 1 */ +#define LPC11_TMR2_BASE 0x40014000 /* -0x40017fff: Timer 0 */ +#define LPC11_TMR3_BASE 0x40018000 /* -0x4001bfff: Timer 1 */ +#define LPC11_ADC_BASE 0x4001c000 /* -0x4001ffff: ADC */ + /* -0x40037fff: Reserved */ +#define LPC11_PMU_BASE 0x40038000 /* -0x4003bfff: PMU */ + /* -0x40017fff: Reserved */ +#define LPC11_FLASHC_BASE 0x4003c000 /* -0x4003ffff: Flash Controller */ +#define LPC11_SPI0_BASE 0x40040000 /* -0x40043fff: SPI0 */ +#define LPC11_IOCON_BASE 0x40044000 /* -0x40047fff: IOCONFIG */ +#define LPC11_SYSCON_BASE 0x40048000 /* -0x4004bfff: System Control */ + /* -0x4004ffff: Reserved */ +#define LPC11_CAN0_BASE 0x40050000 /* -0x40053fff: CAN0 */ + /* -0x40057ffff: Reserved */ +#define LPC11_SPI1_BASE 0x40058000 /* -0x4005bffff: SPI1 */ + /* -0x4007fffff: Reserved */ + +/* AHB Peripherals ******************************************************************/ + +#define LPC11_GPIO_PIO0 (LPC11_GPIO_BASE + 0) /* -0x5000ffff: GPIO PIO0 */ +#define LPC11_GPIO_PIO1 (LPC11_GPIO_BASE + 0x10000) /* -0x5001ffff: GPIO PIO1 */ +#define LPC11_GPIO_PIO2 (LPC11_GPIO_BASE + 0x20000) /* -0x5002ffff: GPIO PIO1 */ +#define LPC11_GPIO_PIO3 (LPC11_GPIO_BASE + 0x30000) /* -0x5003ffff: GPIO PIO1 */ + /* -0x501fffff: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC116X_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc111x_pinconfig.h b/arch/arm/src/lpc11xx/chip/lpc111x_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..0c40b08ac544d3ebc38e6e2025fc45ed1891b6df --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc111x_pinconfig.h @@ -0,0 +1,122 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc111x_pinconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC111X_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC111X_PINCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO pin definitions *************************************************************/ +/* NOTE that functions have a alternate pins that can be selected. These alternates + * are identified with a numeric suffix like _1, _2, or _3. Your board.h file + * should select the correct alternative for your board by including definitions + * such as: + * + * #define GPIO_UART1_RXD GPIO_UART1_RXD_1 + * + * (without the suffix) + */ + +#ifdef CONFIG_ARCH_CHIP_LPC1115 + +#define GPIO_CLKOUT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_CT32B0_MAT2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_SPI0_SSEL (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) +#define GPIO_CT16B0_CAP0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) +#define GPIO_I2C0_SCL (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_I2C0_SDA (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_SPI0_SCK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_UART0_CTS (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_SPI0_MISO (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_CT16B0_MAT0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_SPI0_MOSI (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_CT16B0_MAT1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_JTAG_SWCLK (GPIO_ALT0 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_PIO0_10 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_SPI0_SCK (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_CT16B0_MAT2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_PIO0_11 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_AD_inp0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_CT32B0_MAT3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_PIO1_0 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_AD_inp1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_CT32B1_CAP0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_PIO1_1 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_AD_inp2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_CT32B1_MAT0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_PIO1_2 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN2) +#define GPIO_AD_inp3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN2) +#define GPIO_CT32B1_MAT1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN2) +#define GPIO_JTAG_SWDIO (GPIO_ALT0 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_PIO1_3 (GPIO_ALT_GPIO | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_AD_inp4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_CT32B1_MAT2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_AD_inp5 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN4) +#define GPIO_CT32B1_MAT3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN4) +#define GPIO_UART0_RTS (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN5) +#define GPIO_CT32B0_CAP0 (GPIO_ALT2 | GPIO_PULLDN | GPIO_PORT1 | GPIO_PIN5) +#define GPIO_UART0_RXD (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN6) +#define GPIO_CT32B0_MAT0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN6) +#define GPIO_UART0_TXD (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN7) +#define GPIO_CT32B0_MAT1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN7) +#define GPIO_CT16B1_CAP0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN8) +#define GPIO_CT16B1_MAT0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN9) +#define GPIO_AD_inp6 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN10) +#define GPIO_CT16B1_MAT1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN10) +#define GPIO_AD_inp7 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN11) +#define GPIO_UART0_DTR (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN0) + +#endif /* CONFIG_ARCH_CHIP_LPC1115 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC116X_PINCONFIG_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_adc.h b/arch/arm/src/lpc11xx/chip/lpc11_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..1324bff6c22e509108def0a39585d83e13149312 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_adc.h @@ -0,0 +1,171 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_adc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_ADC_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_ADC_CR_OFFSET 0x0000 /* A/D Control Register */ +#define LPC11_ADC_GDR_OFFSET 0x0004 /* A/D Global Data Register */ +#define LPC11_ADC_INTEN_OFFSET 0x000c /* A/D Interrupt Enable Register */ + +#define LPC11_ADC_DR_OFFSET(n) (0x0010+((n) << 2)) +#define LPC11_ADC_DR0_OFFSET 0x0010 /* A/D Channel 0 Data Register */ +#define LPC11_ADC_DR1_OFFSET 0x0014 /* A/D Channel 1 Data Register */ +#define LPC11_ADC_DR2_OFFSET 0x0018 /* A/D Channel 2 Data Register */ +#define LPC11_ADC_DR3_OFFSET 0x001c /* A/D Channel 3 Data Register */ +#define LPC11_ADC_DR4_OFFSET 0x0020 /* A/D Channel 4 Data Register */ +#define LPC11_ADC_DR5_OFFSET 0x0024 /* A/D Channel 5 Data Register */ +#define LPC11_ADC_DR6_OFFSET 0x0028 /* A/D Channel 6 Data Register */ +#define LPC11_ADC_DR7_OFFSET 0x002c /* A/D Channel 7 Data Register */ + +#define LPC11_ADC_STAT_OFFSET 0x0030 /* A/D Status Register */ + +/* Register addresses ***************************************************************/ + +#define LPC11_ADC_CR (LPC11_ADC_BASE+LPC11_ADC_CR_OFFSET) +#define LPC11_ADC_GDR (LPC11_ADC_BASE+LPC11_ADC_GDR_OFFSET) +#define LPC11_ADC_INTEN (LPC11_ADC_BASE+LPC11_ADC_INTEN_OFFSET) + +#define LPC11_ADC_DR(n) (LPC11_ADC_BASE+LPC11_ADC_DR_OFFSET(n)) +#define LPC11_ADC_DR0 (LPC11_ADC_BASE+LPC11_ADC_DR0_OFFSET) +#define LPC11_ADC_DR1 (LPC11_ADC_BASE+LPC11_ADC_DR1_OFFSET) +#define LPC11_ADC_DR2 (LPC11_ADC_BASE+LPC11_ADC_DR2_OFFSET) +#define LPC11_ADC_DR3 (LPC11_ADC_BASE+LPC11_ADC_DR3_OFFSET) +#define LPC11_ADC_DR4 (LPC11_ADC_BASE+LPC11_ADC_DR4_OFFSET) +#define LPC11_ADC_DR5 (LPC11_ADC_BASE+LPC11_ADC_DR5_OFFSET) +#define LPC11_ADC_DR6 (LPC11_ADC_BASE+LPC11_ADC_DR6_OFFSET) +#define LPC11_ADC_DR7 (LPC11_ADC_BASE+LPC11_ADC_DR7_OFFSET) + +#define LPC11_ADC_STAT (LPC11_ADC_BASE+LPC11_ADC_STAT_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* A/D Control Register */ + +#define ADC_CR_SEL_SHIFT (0) /* Bits 0-7: Selects pins to be sampled */ +#define ADC_CR_SEL_MASK (0xff << ADC_CR_SEL_MASK) +#define ADC_CR_CLKDIV_SHIFT (8) /* Bits 8-15: APB clock (PCLK_ADC0) divisor */ +#define ADC_CR_CLKDIV_MASK (0xff << ADC_CR_CLKDIV_SHIFT) +#define ADC_CR_BURST (1 << 16) /* Bit 16: A/D Repeated conversions */ +#define ADC_CR_CLKS_SHIFT (17) /* Bits 17-19: Clocks used on burst mode conv. */ +#define ADC_CR_CLKS_MASK (3 << ADC_CR_CLKS_SHIFT) + /* Bits 20-23: Reserved */ +#define ADC_CR_START_SHIFT (24) /* Bits 24-26: Control A/D conversion start */ +#define ADC_CR_START_MASK (7 << ADC_CR_START_SHIFT) +# define ADC_CR_START_NOSTART (0 << ADC_CR_START_SHIFT) /* No start */ +# define ADC_CR_START_NOW (1 << ADC_CR_START_SHIFT) /* Start now */ +# define ADC_CR_START_P0p2 (2 << ADC_CR_START_SHIFT) /* Start edge on P0.2/SSEL/CT16B0_CAP0 */ +# define ADC_CR_START_P1p5 (3 << ADC_CR_START_SHIFT) /* Start edge on P1.5/DIR/CT32B0_CAP0 */ +# define ADC_CR_START_CT32B0MAT0 (4 << ADC_CR_START_SHIFT) /* Start edge on Counter/Timer32 MAT0 */ +# define ADC_CR_START_CT32B0MAT1 (5 << ADC_CR_START_SHIFT) /* Start edge on Counter/Timer32 MAT1 */ +# define ADC_CR_START_CT16B0MAT0 (6 << ADC_CR_START_SHIFT) /* Start edge on Counter/Timer16 MAT0 */ +# define ADC_CR_START_CT16B0MAT1 (7 << ADC_CR_START_SHIFT) /* Start edge on Counter/Timer16 MAT1 */ +#define ADC_CR_EDGE (1 << 27) /* Bit 27: Start on falling edge */ + /* Bits 28-31: Reserved */ +/* A/D Global Data Register AND Channel 0-7 Data Register */ + /* Bits 0-5: Reserved */ +#define ADC_DR_RESULT_SHIFT (5) /* Bits 6-15: Result of conversion (DONE==1) */ +#define ADC_DR_RESULT_MASK (0x3ff << ADC_DR_RESULT_SHIFT) + /* Bits 16-23: Reserved */ +#define ADC_DR_CHAN_SHIFT (24) /* Bits 24-26: Channel converted */ +#define ADC_DR_CHAN_MASK (3 << ADC_DR_CHN_SHIFT) + /* Bits 27-29: Reserved */ +#define ADC_DR_OVERRUN (1 << 30) /* Bit 30: Conversion(s) lost/overwritten*/ +#define ADC_DR_DONE (1 << 31) /* Bit 31: A/D conversion complete*/ + +/* A/D Interrupt Enable Register */ + +#define ADC_INTEN_CHAN(n) (1 << (n)) +#define ADC_INTEN_CHAN0 (1 << 0) /* Bit 0: Enable ADC chan 0 complete intterrupt */ +#define ADC_INTEN_CHAN1 (1 << 1) /* Bit 1: Enable ADC chan 1 complete interrupt */ +#define ADC_INTEN_CHAN2 (1 << 2) /* Bit 2: Enable ADC chan 2 complete interrupt */ +#define ADC_INTEN_CHAN3 (1 << 3) /* Bit 3: Enable ADC chan 3 complete interrupt */ +#define ADC_INTEN_CHAN4 (1 << 4) /* Bit 4: Enable ADC chan 4 complete interrupt */ +#define ADC_INTEN_CHAN5 (1 << 5) /* Bit 5: Enable ADC chan 5 complete interrupt */ +#define ADC_INTEN_CHAN6 (1 << 6) /* Bit 6: Enable ADC chan 6 complete interrupt */ +#define ADC_INTEN_CHAN7 (1 << 7) /* Bit 7: Enable ADC chan 7 complete interrupt */ +#define ADC_INTEN_GLOBAL (1 << 8) /* Bit 8: Only the global DONE generates interrupt */ + /* Bits 9-31: Reserved */ +/* A/D Status Register */ + +#define ADC_STAT_DONE(n) (1 << (n)) +#define ADC_STAT_DONE0 (1 << 0) /* Bit 0: A/D chan 0 DONE */ +#define ADC_STAT_DONE1 (1 << 1) /* Bit 1: A/D chan 1 DONE */ +#define ADC_STAT_DONE2 (1 << 2) /* Bit 2: A/D chan 2 DONE */ +#define ADC_STAT_DONE3 (1 << 3) /* Bit 3: A/D chan 3 DONE */ +#define ADC_STAT_DONE4 (1 << 4) /* Bit 4: A/D chan 4 DONE */ +#define ADC_STAT_DONE5 (1 << 5) /* Bit 5: A/D chan 5 DONE */ +#define ADC_STAT_DONE6 (1 << 6) /* Bit 6: A/D chan 6 DONE */ +#define ADC_STAT_DONE7 (1 << 7) /* Bit 7: A/D chan 7 DONE */ +#define ADC_STAT_OVERRUN(n) ((1 << (n)) + 8) +#define ADC_STAT_OVERRUN0 (1 << 8) /* Bit 8: A/D chan 0 OVERRUN */ +#define ADC_STAT_OVERRUN1 (1 << 9) /* Bit 9: A/D chan 1 OVERRUN */ +#define ADC_STAT_OVERRUN2 (1 << 10) /* Bit 10: A/D chan 2 OVERRUN */ +#define ADC_STAT_OVERRUN3 (1 << 11) /* Bit 11: A/D chan 3 OVERRUN */ +#define ADC_STAT_OVERRUN4 (1 << 12) /* Bit 12: A/D chan 4 OVERRUN */ +#define ADC_STAT_OVERRUN5 (1 << 13) /* Bit 13: A/D chan 5 OVERRUN */ +#define ADC_STAT_OVERRUN6 (1 << 14) /* Bit 14: A/D chan 6 OVERRUN */ +#define ADC_STAT_OVERRUN7 (1 << 15) /* Bit 15: A/D chan 7 OVERRUN */ +#define ADC_STAT_INT (1 << 16) /* Bit 15: A/D interrupt */ + /* Bits 17-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_ADC_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_gpio.h b/arch/arm/src/lpc11xx/chip/lpc11_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..99daa2445f7aac01bc34219826ca034c14cb6965 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_gpio.h @@ -0,0 +1,146 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_GPIO_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* GPIO block register offsets ******************************************************/ + +#define LPC11_GPIO0_OFFSET 0x00000 +#define LPC11_GPIO1_OFFSET 0x10000 +#define LPC11_GPIO2_OFFSET 0x20000 +#define LPC11_GPIO3_OFFSET 0x30000 +#define LPC11_GPIO_OFFSET(n) (0x10000*(n)) + +#define LPC11_GPIO_DATA_OFFSET 0x3FFC +#define LPC11_GPIO_DIR_OFFSET 0x8000 /* GPIO Port Direction control */ +#define LPC11_GPIO_IS_OFFSET 0x8004 /* Interrupt Sense register */ +#define LPC11_GPIO_IBE_OFFSET 0x8008 /* Interrupt Both Edges register */ +#define LPC11_GPIO_IEV_OFFSET 0x800c /* Interrupt Event register */ +#define LPC11_GPIO_IE_OFFSET 0x8010 /* Interrupt Mask register */ +#define LPC11_GPIO_RIS_OFFSET 0x8014 /* Raw interrupt status register */ +#define LPC11_GPIO_MIS_OFFSET 0x8018 /* Masked interrupt status register */ +#define LPC11_GPIO_IC_OFFSET 0x801c /* Interrupt clear register */ + +/* Register addresses ***************************************************************/ +/* GPIO block register addresses ****************************************************/ + +#define LPC11_GPIOn_BASE(n) (LPC11_GPIO_BASE+LPC11_GPIO_OFFSET(n)) +#define LPC11_GPIO0_BASE (LPC11_GPIO_BASE+LPC11_GPIO0_OFFSET) +#define LPC11_GPIO1_BASE (LPC11_GPIO_BASE+LPC11_GPIO1_OFFSET) +#define LPC11_GPIO2_BASE (LPC11_GPIO_BASE+LPC11_GPIO2_OFFSET) +#define LPC11_GPIO3_BASE (LPC11_GPIO_BASE+LPC11_GPIO3_OFFSET) + +#define LPC11_GPIO_DIR(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_DIR_OFFSET) /* GPIO Port Direction register */ +#define LPC11_GPIO_IS(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_IS_OFFSET) /* GPIO Interrupt Sense register */ +#define LPC11_GPIO_IBE(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_IBE_OFFSET) /* GPIO Interrupt Both Edges sense register */ +#define LPC11_GPIO_IEV(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_IVE_OFFSET) /* GPIO Interrupt Event register */ +#define LPC11_GPIO_IE(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_IE_OFFSET) /* GPIO Interrupt Mask register */ +#define LPC11_GPIO_RIS(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_RIS_OFFSET) /* GPIO Raw Interrupt Status register */ +#define LPC11_GPIO_MIS(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_MIS_OFFSET) /* GPIO Masked Interrupt Status register */ +#define LPC11_GPIO_IC(n) (LPC11_GPIO_BASE(n)+LPC11_GPIO_IC_OFFSET) /* GPIO Interrupt Clear register */ + +#define LPC11_GPIO0_DATA (LPC11_GPIO0_BASE+LPC11_GPIO_DATA_OFFSET) +#define LPC11_GPIO0_DIR (LPC11_GPIO0_BASE+LPC11_GPIO_DIR_OFFSET) +#define LPC11_GPIO0_IS (LPC11_GPIO0_BASE+LPC11_GPIO_IS_OFFSET) +#define LPC11_GPIO0_IBE (LPC11_GPIO0_BASE+LPC11_GPIO_IBE_OFFSET) +#define LPC11_GPIO0_IEV (LPC11_GPIO0_BASE+LPC11_GPIO_IVE_OFFSET) +#define LPC11_GPIO0_IE (LPC11_GPIO0_BASE+LPC11_GPIO_IE_OFFSET) +#define LPC11_GPIO0_RIS (LPC11_GPIO0_BASE+LPC11_GPIO_RIS_OFFSET) +#define LPC11_GPIO0_MIS (LPC11_GPIO0_BASE+LPC11_GPIO_MIS_OFFSET) +#define LPC11_GPIO0_IC (LPC11_GPIO0_BASE+LPC11_GPIO_IC_OFFSET) + +#define LPC11_GPIO1_DATA (LPC11_GPIO1_BASE+LPC11_GPIO_DATA_OFFSET) +#define LPC11_GPIO1_DIR (LPC11_GPIO1_BASE+LPC11_GPIO_DIR_OFFSET) +#define LPC11_GPIO1_IS (LPC11_GPIO1_BASE+LPC11_GPIO_IS_OFFSET) +#define LPC11_GPIO1_IBE (LPC11_GPIO1_BASE+LPC11_GPIO_IBE_OFFSET) +#define LPC11_GPIO1_IEV (LPC11_GPIO1_BASE+LPC11_GPIO_IVE_OFFSET) +#define LPC11_GPIO1_IE (LPC11_GPIO1_BASE+LPC11_GPIO_IE_OFFSET) +#define LPC11_GPIO1_RIS (LPC11_GPIO1_BASE+LPC11_GPIO_RIS_OFFSET) +#define LPC11_GPIO1_MIS (LPC11_GPIO1_BASE+LPC11_GPIO_MIS_OFFSET) +#define LPC11_GPIO1_IC (LPC11_GPIO1_BASE+LPC11_GPIO_IC_OFFSET) + +#define LPC11_GPIO2_DATA (LPC11_GPIO2_BASE+LPC11_GPIO_DATA_OFFSET) +#define LPC11_GPIO2_DIR (LPC11_GPIO2_BASE+LPC11_GPIO_DIR_OFFSET) +#define LPC11_GPIO2_IS (LPC11_GPIO2_BASE+LPC11_GPIO_IS_OFFSET) +#define LPC11_GPIO2_IBE (LPC11_GPIO2_BASE+LPC11_GPIO_IBE_OFFSET) +#define LPC11_GPIO2_IEV (LPC11_GPIO2_BASE+LPC11_GPIO_IVE_OFFSET) +#define LPC11_GPIO2_IE (LPC11_GPIO2_BASE+LPC11_GPIO_IE_OFFSET) +#define LPC11_GPIO2_RIS (LPC11_GPIO2_BASE+LPC11_GPIO_RIS_OFFSET) +#define LPC11_GPIO2_MIS (LPC11_GPIO2_BASE+LPC11_GPIO_MIS_OFFSET) +#define LPC11_GPIO2_IC (LPC11_GPIO2_BASE+LPC11_GPIO_IC_OFFSET) + +#define LPC11_GPIO3_DATA (LPC11_GPIO3_BASE+LPC11_GPIO_DATA_OFFSET) +#define LPC11_GPIO3_DIR (LPC11_GPIO3_BASE+LPC11_GPIO_DIR_OFFSET) +#define LPC11_GPIO3_IS (LPC11_GPIO3_BASE+LPC11_GPIO_IS_OFFSET) +#define LPC11_GPIO3_IBE (LPC11_GPIO3_BASE+LPC11_GPIO_IBE_OFFSET) +#define LPC11_GPIO3_IEV (LPC11_GPIO3_BASE+LPC11_GPIO_IVE_OFFSET) +#define LPC11_GPIO3_IE (LPC11_GPIO3_BASE+LPC11_GPIO_IE_OFFSET) +#define LPC11_GPIO3_RIS (LPC11_GPIO3_BASE+LPC11_GPIO_RIS_OFFSET) +#define LPC11_GPIO3_MIS (LPC11_GPIO3_BASE+LPC11_GPIO_MIS_OFFSET) +#define LPC11_GPIO3_IC (LPC11_GPIO3_BASE+LPC11_GPIO_IC_OFFSET) + +/* Register bit definitions *********************************************************/ +/* GPIO block register bit definitions **********************************************/ + +#define GPIO(n) (1 << (n)) /* n=0,1,..11 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_CHIP_GPIO_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_i2c.h b/arch/arm/src/lpc11xx/chip/lpc11_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..53c7089c6ee0d6d7d2ab3712da7f976b6f2da7a4 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_i2c.h @@ -0,0 +1,208 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_i2c.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_I2C_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_I2C_CONSET_OFFSET 0x0000 /* I2C Control Set Register */ +#define LPC11_I2C_STAT_OFFSET 0x0004 /* I2C Status Register */ +#define LPC11_I2C_DAT_OFFSET 0x0008 /* I2C Data Register */ +#define LPC11_I2C_ADR0_OFFSET 0x000c /* I2C Slave Address Register 0 */ +#define LPC11_I2C_SCLH_OFFSET 0x0010 /* SCH Duty Cycle Register High Half Word */ +#define LPC11_I2C_SCLL_OFFSET 0x0014 /* SCL Duty Cycle Register Low Half Word */ +#define LPC11_I2C_CONCLR_OFFSET 0x0018 /* I2C Control Clear Register */ +#define LPC11_I2C_MMCTRL_OFFSET 0x001c /* Monitor mode control register */ +#define LPC11_I2C_ADR1_OFFSET 0x0020 /* I2C Slave Address Register 1 */ +#define LPC11_I2C_ADR2_OFFSET 0x0024 /* I2C Slave Address Register 2 */ +#define LPC11_I2C_ADR3_OFFSET 0x0028 /* I2C Slave Address Register 3 */ +#define LPC11_I2C_BUFR_OFFSET 0x002c /* Data buffer register */ +#define LPC11_I2C_MASK0_OFFSET 0x0030 /* I2C Slave address mask register 0 */ +#define LPC11_I2C_MASK1_OFFSET 0x0034 /* I2C Slave address mask register 1 */ +#define LPC11_I2C_MASK2_OFFSET 0x0038 /* I2C Slave address mask register 2 */ +#define LPC11_I2C_MASK3_OFFSET 0x003c /* I2C Slave address mask register */ + +/* Register addresses ***************************************************************/ + +#define LPC11_I2C0_CONSET (LPC11_I2C0_BASE+LPC11_I2C_CONSET_OFFSET) +#define LPC11_I2C0_STAT (LPC11_I2C0_BASE+LPC11_I2C_STAT_OFFSET) +#define LPC11_I2C0_DAT (LPC11_I2C0_BASE+LPC11_I2C_DAT_OFFSET) +#define LPC11_I2C0_ADR0 (LPC11_I2C0_BASE+LPC11_I2C_ADR0_OFFSET) +#define LPC11_I2C0_SCLH (LPC11_I2C0_BASE+LPC11_I2C_SCLH_OFFSET) +#define LPC11_I2C0_SCLL (LPC11_I2C0_BASE+LPC11_I2C_SCLL_OFFSET) +#define LPC11_I2C0_CONCLR (LPC11_I2C0_BASE+LPC11_I2C_CONCLR_OFFSET) +#define LPC11_I2C0_MMCTRL (LPC11_I2C0_BASE+LPC11_I2C_MMCTRL_OFFSET) +#define LPC11_I2C0_ADR1 (LPC11_I2C0_BASE+LPC11_I2C_ADR1_OFFSET) +#define LPC11_I2C0_ADR2 (LPC11_I2C0_BASE+LPC11_I2C_ADR2_OFFSET) +#define LPC11_I2C0_ADR3 (LPC11_I2C0_BASE+LPC11_I2C_ADR3_OFFSET) +#define LPC11_I2C0_BUFR (LPC11_I2C0_BASE+LPC11_I2C_BUFR_OFFSET) +#define LPC11_I2C0_MASK0 (LPC11_I2C0_BASE+LPC11_I2C_MASK0_OFFSET) +#define LPC11_I2C0_MASK1 (LPC11_I2C0_BASE+LPC11_I2C_MASK1_OFFSET) +#define LPC11_I2C0_MASK2 (LPC11_I2C0_BASE+LPC11_I2C_MASK2_OFFSET) +#define LPC11_I2C0_MASK3 (LPC11_I2C0_BASE+LPC11_I2C_MASK3_OFFSET) + +#define LPC11_I2C1_CONSET (LPC11_I2C1_BASE+LPC11_I2C_CONSET_OFFSET) +#define LPC11_I2C1_STAT (LPC11_I2C1_BASE+LPC11_I2C_STAT_OFFSET) +#define LPC11_I2C1_DAT (LPC11_I2C1_BASE+LPC11_I2C_DAT_OFFSET) +#define LPC11_I2C1_ADR0 (LPC11_I2C1_BASE+LPC11_I2C_ADR0_OFFSET) +#define LPC11_I2C1_SCLH (LPC11_I2C1_BASE+LPC11_I2C_SCLH_OFFSET) +#define LPC11_I2C1_SCLL (LPC11_I2C1_BASE+LPC11_I2C_SCLL_OFFSET) +#define LPC11_I2C1_CONCLR (LPC11_I2C1_BASE+LPC11_I2C_CONCLR_OFFSET) +#define LPC11_I2C1_MMCTRL (LPC11_I2C1_BASE+LPC11_I2C_MMCTRL_OFFSET) +#define LPC11_I2C1_ADR1 (LPC11_I2C1_BASE+LPC11_I2C_ADR1_OFFSET) +#define LPC11_I2C1_ADR2 (LPC11_I2C1_BASE+LPC11_I2C_ADR2_OFFSET) +#define LPC11_I2C1_ADR3 (LPC11_I2C1_BASE+LPC11_I2C_ADR3_OFFSET) +#define LPC11_I2C1_BUFR (LPC11_I2C1_BASE+LPC11_I2C_BUFR_OFFSET) +#define LPC11_I2C1_MASK0 (LPC11_I2C1_BASE+LPC11_I2C_MASK0_OFFSET) +#define LPC11_I2C1_MASK1 (LPC11_I2C1_BASE+LPC11_I2C_MASK1_OFFSET) +#define LPC11_I2C1_MASK2 (LPC11_I2C1_BASE+LPC11_I2C_MASK2_OFFSET) +#define LPC11_I2C1_MASK3 (LPC11_I2C1_BASE+LPC11_I2C_MASK3_OFFSET) + +#define LPC11_I2C2_CONSET (LPC11_I2C2_BASE+LPC11_I2C_CONSET_OFFSET) +#define LPC11_I2C2_STAT (LPC11_I2C2_BASE+LPC11_I2C_STAT_OFFSET) +#define LPC11_I2C2_DAT (LPC11_I2C2_BASE+LPC11_I2C_DAT_OFFSET) +#define LPC11_I2C2_ADR0 (LPC11_I2C2_BASE+LPC11_I2C_ADR0_OFFSET) +#define LPC11_I2C2_SCLH (LPC11_I2C2_BASE+LPC11_I2C_SCLH_OFFSET) +#define LPC11_I2C2_SCLL (LPC11_I2C2_BASE+LPC11_I2C_SCLL_OFFSET) +#define LPC11_I2C2_CONCLR (LPC11_I2C2_BASE+LPC11_I2C_CONCLR_OFFSET) +#define LPC11_I2C2_MMCTRL (LPC11_I2C2_BASE+LPC11_I2C_MMCTRL_OFFSET) +#define LPC11_I2C2_ADR1 (LPC11_I2C2_BASE+LPC11_I2C_ADR1_OFFSET) +#define LPC11_I2C2_ADR2 (LPC11_I2C2_BASE+LPC11_I2C_ADR2_OFFSET) +#define LPC11_I2C2_ADR3 (LPC11_I2C2_BASE+LPC11_I2C_ADR3_OFFSET) +#define LPC11_I2C2_BUFR (LPC11_I2C2_BASE+LPC11_I2C_BUFR_OFFSET) +#define LPC11_I2C2_MASK0 (LPC11_I2C2_BASE+LPC11_I2C_MASK0_OFFSET) +#define LPC11_I2C2_MASK1 (LPC11_I2C2_BASE+LPC11_I2C_MASK1_OFFSET) +#define LPC11_I2C2_MASK2 (LPC11_I2C2_BASE+LPC11_I2C_MASK2_OFFSET) +#define LPC11_I2C2_MASK3 (LPC11_I2C2_BASE+LPC11_I2C_MASK3_OFFSET) + +/* Register bit definitions *********************************************************/ +/* I2C Control Set Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONSET_AA (1 << 2) /* Bit 2: Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* Bit 3: I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* Bit 4: STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* Bit 5: START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* Bit 6: I2C interface enable */ + /* Bits 7-31: Reserved */ +/* I2C Control Clear Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONCLR_AAC (1 << 2) /* Bit 2: Assert acknowledge Clear bit */ +#define I2C_CONCLR_SIC (1 << 3) /* Bit 3: I2C interrupt Clear bit */ + /* Bit 4: Reserved */ +#define I2C_CONCLR_STAC (1 << 5) /* Bit 5: START flag Clear bit */ +#define I2C_CONCLRT_I2ENC (1 << 6) /* Bit 6: I2C interface Disable bit */ + /* Bits 7-31: Reserved */ +/* I2C Status Register + * + * See tables 399-402 in the "LPC11xx User Manual" (UM10398), Rev. 01, 4 January + * 2010, NXP for definitions of status codes. + */ + +#define I2C_STAT_MASK (0xff) /* Bits 0-7: I2C interface status + * Bits 0-1 always zero */ + /* Bits 8-31: Reserved */ +/* I2C Data Register */ + +#define I2C_DAT_MASK (0xff) /* Bits 0-7: I2C data */ + /* Bits 8-31: Reserved */ +/* Monitor mode control register */ + +#define I2C_MMCTRL_MMENA (1 << 0) /* Bit 0: Monitor mode enable */ +#define I2C_MMCTRL_ENASCL (1 << 1) /* Bit 1: SCL output enable */ +#define I2C_MMCTRL_MATCHALL (1 << 2) /* Bit 2: Select interrupt register match */ + /* Bits 3-31: Reserved */ +/* Data buffer register */ + +#define I2C_BUFR_MASK (0xff) /* Bits 0-7: 8 MSBs of the I2DAT shift register */ + /* Bits 8-31: Reserved */ +/* I2C Slave address registers: + * + * I2C Slave Address Register 0 + * I2C Slave Address Register 1 + * I2C Slave Address Register 2 + * I2C Slave Address Register 3 + */ + +#define I2C_ADR_GC (1 << 0) /* Bit 0: GC General Call enable bit */ +#define I2C_ADR_ADDR_SHIFT (1) /* Bits 1-7: I2C slave address */ +#define I2C_ADR_ADDR_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Slave address mask registers: + * + * I2C Slave address mask register 0 + * I2C Slave address mask register 1 + * I2C Slave address mask register 2 + * I2C Slave address mask register 3 + */ + /* Bit 0: Reserved */ +#define I2C_MASK_SHIFT (1) /* Bits 1-7: I2C mask bits */ +#define I2C_MASK_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* SCH Duty Cycle Register High Half Word */ + +#define I2C_SCLH_MASK (0xffff) /* Bit 0-15: Count for SCL HIGH time period selection */ + /* Bits 16-31: Reserved */ +/* SCL Duty Cycle Register Low Half Word */ + +#define I2C_SCLL_MASK (0xffff) /* Bit 0-15: Count for SCL LOW time period selection */ + /* Bits 16-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_I2C_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_memorymap.h b/arch/arm/src/lpc11xx/chip/lpc11_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..c01a346c2694923bde8897c76dd6dbeda42a7d68 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_memorymap.h @@ -0,0 +1,73 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct memory map definitions + * for the selected LPC11xx family. + */ + +#include + +#if defined(LPC111x) +# include "chip/lpc111x_memorymap.h" +#else +# error "Unrecognized LPC11xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_pinconfig.h b/arch/arm/src/lpc11xx/chip/lpc11_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..c53b6b3d37e91207300d6d4a5b6607d8553a2c31 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_pinconfig.h @@ -0,0 +1,73 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_pinconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PINCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct pin configuration + * definitions for the selected LPC11xx family. + */ + +#include + +#if defined(LPC111x) +# include "chip/lpc111x_pinconfig.h" +#else +# error "Unrecognized LPC11xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PINCONFIG_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_pmu.h b/arch/arm/src/lpc11xx/chip/lpc11_pmu.h new file mode 100644 index 0000000000000000000000000000000000000000..6a8b5a6865e868f787b895327df08379474b4b82 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_pmu.h @@ -0,0 +1,106 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_pmu.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PMU_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PMU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_PMU_PCON_OFFSET 0x0000 /* Power control register */ +#define LPC11_PMU_GPREG0 0x0004 /* General purpose register 0 */ +#define LPC11_PMU_GPREG1 0x0008 /* General purpose register 1 */ +#define LPC11_PMU_GPREG2 0x000C /* General purpose register 2 */ +#define LPC11_PMU_GPREG3 0x0010 /* General purpose register 3 */ +#define LPC11_PMU_GPREG4 0x0014 /* General purpose register 0 */ + +/* Register addresses ***************************************************************/ + +#define LPC11_PMU_PCON (LPC11_PMU_BASE+LPC11_PMU_PCON_OFFSET) +#define LPC11_PMU_GPREG0 (LPC11_PMU_BASE+LPC11_PMU_GPREG0) +#define LPC11_PMU_GPREG1 (LPC11_PMU_BASE+LPC11_PMU_GPREG1) +#define LPC11_PMU_GPREG2 (LPC11_PMU_BASE+LPC11_PMU_GPREG2) +#define LPC11_PMU_GPREG3 (LPC11_PMU_BASE+LPC11_PMU_GPREG3) +#define LPC11_PMU_GPREG4 (LPC11_PMU_BASE+LPC11_PMU_GPREG4) + +/* Register bit definitions *********************************************************/ + +/* Power control register */ + /* Bit 0: Reserved. Do not write 1 to this bit */ +#define PMU_PCON_DPDEN (1 << 1) /* Deep power-down mode enable */ + /* Bits 2-7: Reserved. Do not write ones to this bit */ +#define PMU_PCON_SLEEPFLAG (1 << 8) /* Sleep mode flag */ + /* Bits 9-10: Reserved. Do not write ones to this bit */ +#define PMU_PCON_DPDFLAG (1 << 11) /* Deep power-down flag. */ + /* Bits 12-31: Reserved. Do not write ones to this bit */ + + +/* General Purpose REG */ + +#define PMU_GPREG03_GPDATA_MASK (0xffffffff) /* Bits 0-31: Data retained during Deep power-down mode */ + + +/* General Purpose REG4 Register */ + + /* Bits 0-9: Reserved. Do not write ones to this bit */ +#define PMU_GPREG4_WAKEUPHYS (1 << 10) /* WAKEUP pin hysteresis enable */ +#define PMU_GPREG4_GPDATA_SHIFT 11 /* Data retained during Deep power-down mode. */ +#define PMU_GPREG4_GPDATA_MASK (0x1fffff << PMU_GPREG4_GPDATA_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_PMU_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_ssp.h b/arch/arm/src/lpc11xx/chip/lpc11_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..1c67102c044418607b7cf677c69d5bcbf96e38b6 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_ssp.h @@ -0,0 +1,182 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_ssp.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SSP_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_SSP_CR0_OFFSET 0x0000 /* Control Register 0 */ +#define LPC11_SSP_CR1_OFFSET 0x0004 /* Control Register 1 */ +#define LPC11_SSP_DR_OFFSET 0x0008 /* Data Register */ +#define LPC11_SSP_SR_OFFSET 0x000c /* Status Register */ +#define LPC11_SSP_CPSR_OFFSET 0x0010 /* Clock Prescale Register */ +#define LPC11_SSP_IMSC_OFFSET 0x0014 /* Interrupt Mask Set/Clear Register */ +#define LPC11_SSP_RIS_OFFSET 0x0018 /* Raw Interrupt Status Register */ +#define LPC11_SSP_MIS_OFFSET 0x001c /* Masked Interrupt Status Register */ +#define LPC11_SSP_ICR_OFFSET 0x0020 /* Interrupt Clear Register */ + +/* Register addresses ***************************************************************/ +/* SPI 0 */ +#define LPC11_SSP0_CR0 (LPC11_SPI0_BASE+LPC11_SSP_CR0_OFFSET) +#define LPC11_SSP0_CR1 (LPC11_SPI0_BASE+LPC11_SSP_CR1_OFFSET) +#define LPC11_SSP0_DR (LPC11_SPI0_BASE+LPC11_SSP_DR_OFFSET) +#define LPC11_SSP0_SR (LPC11_SPI0_BASE+LPC11_SSP_SR_OFFSET) +#define LPC11_SSP0_CPSR (LPC11_SPI0_BASE+LPC11_SSP_CPSR_OFFSET) +#define LPC11_SSP0_IMSC (LPC11_SPI0_BASE+LPC11_SSP_IMSC_OFFSET) +#define LPC11_SSP0_RIS (LPC11_SPI0_BASE+LPC11_SSP_RIS_OFFSET) +#define LPC11_SSP0_MIS (LPC11_SPI0_BASE+LPC11_SSP_MIS_OFFSET) +#define LPC11_SSP0_ICR (LPC11_SPI0_BASE+LPC11_SSP_ICR_OFFSET) + +/* SPI 1 */ +#define LPC11_SSP1_CR0 (LPC11_SPI1_BASE+LPC11_SSP_CR0_OFFSET) +#define LPC11_SSP1_CR1 (LPC11_SPI1_BASE+LPC11_SSP_CR1_OFFSET) +#define LPC11_SSP1_DR (LPC11_SPI1_BASE+LPC11_SSP_DR_OFFSET) +#define LPC11_SSP1_SR (LPC11_SPI1_BASE+LPC11_SSP_SR_OFFSET) +#define LPC11_SSP1_CPSR (LPC11_SPI1_BASE+LPC11_SSP_CPSR_OFFSET) +#define LPC11_SSP1_IMSC (LPC11_SPI1_BASE+LPC11_SSP_IMSC_OFFSET) +#define LPC11_SSP1_RIS (LPC11_SPI1_BASE+LPC11_SSP_RIS_OFFSET) +#define LPC11_SSP1_MIS (LPC11_SPI1_BASE+LPC11_SSP_MIS_OFFSET) +#define LPC11_SSP1_ICR (LPC11_SPI1_BASE+LPC11_SSP_ICR_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* SPI/SSP Control Register 0 */ + +#define SSP_CR0_DSS_SHIFT (0) /* Data Size Select */ +#define SSP_CR0_DSS_MASK (15 << SSP_CR0_SHIFT) +# define SSP_CR0_DSS_4BITS (3 << SSP_CR0_DSS_SHIFT) /* 4 bits per transfer */ +# define SSP_CR0_DSS_5BITS (4 << SSP_CR0_DSS_SHIFT) /* 5 bits per transfer */ +# define SSP_CR0_DSS_6BITS (5 << SSP_CR0_DSS_SHIFT) /* 6 bits per transfer */ +# define SSP_CR0_DSS_7BITS (6 << SSP_CR0_DSS_SHIFT) /* 7 bits per transfer */ +# define SSP_CR0_DSS_8BITS (7 << SSP_CR0_DSS_SHIFT) /* 8 bits per transfer */ +# define SSP_CR0_DSS_9BITS (8 << SSP_CR0_DSS_SHIFT) /* 9 bits per transfer */ +# define SSP_CR0_DSS_10BITS (9 << SSP_CR0_DSS_SHIFT) /* 10 bits per transfer */ +# define SSP_CR0_DSS_11BITS (10 << SSP_CR0_DSS_SHIFT) /* 11 bits per transfer */ +# define SSP_CR0_DSS_12BITS (11 << SSP_CR0_DSS_SHIFT) /* 12 bits per transfer */ +# define SSP_CR0_DSS_13BITS (12 << SSP_CR0_DSS_SHIFT) /* 13 bits per transfer */ +# define SSP_CR0_DSS_14BITS (13 << SSP_CR0_DSS_SHIFT) /* 14 bits per transfer */ +# define SSP_CR0_DSS_15BITS (14 << SSP_CR0_DSS_SHIFT) /* 15 bits per transfer */ +# define SSP_CR0_DSS_16BITS (15 << SSP_CR0_DSS_SHIFT) /* 16 bits per transfer */ +#define SSP_CR0_FRF_SHIFT (4) /* Frame Format */ +#define SSP_CR0_FRF_MASK (3 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_SPI (0 << SSP_CR0_FRF_SHIFT) /* SPI Frame Format */ +# define SSP_CR0_FRF_TI (1 << SSP_CR0_FRF_SHIFT) /* TI Frame Format */ +# define SSP_CR0_FRF_MWIRE (2 << SSP_CR0_FRF_SHIFT) /* Microwire Frame Format */ + /* (3 << SSP_CR0_FRF_SHIFT) format is not supported */ +#define SSP_CR0_CPOL (1 << 6) /* Bit 6: Clock polarity control */ +#define SSP_CR0_CPHA (1 << 7) /* Bit 7: Clock phase control */ +#define SSP_CR0_SCR_SHIFT (8) /* Bit 8-15: Serial Clock Rate. PCLK/(CPSDVSR x [SCR + 1] */ +#define SSP_CR0_SCR_MASK (255 << SSP_CR0_SCR_SHIFT) + +/* SPI/SSP Control Register 1 */ + +#define SSP_CR1_LBM (1 << 0) /* Bit 0: Loop Back Mode */ +#define SSP_CR1_SSE (1 << 1) /* Bit 1: SPI Enable */ +#define SSP_CR1_MS (1 << 2) /* Bit 2: Master/Slave Mode */ +#define SSP_CR1_SOD (1 << 3) /* Bit 3: Slave Output Disable */ + /* Bits 4-31: Reserved */ + +/* SPI/SSP Data Register */ + +#define SSP_DR_MASK (0xffff) /* Bits 0-15: Data */ + /* Bits 16-31: Reserved */ +/* SPI/SSP Status Register */ + +#define SSP_SR_TFE (1 << 0) /* Bit 0: Transmit FIFO Empty */ +#define SSP_SR_TNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define SSP_SR_RNE (1 << 2) /* Bit 2: Receive FIFO Not Empty */ +#define SSP_SR_RFF (1 << 3) /* Bit 3: Receive FIFO Full */ +#define SSP_SR_BSY (1 << 4) /* Bit 4: Busy */ + /* Bits 5-31: Reserved */ +/* SPI/SSP Clock Prescale Register */ + +#define SSP_CPSR_DVSR_MASK (0xff) /* Even values between 2 and 254 */ + +/* SPI/SSP Interrupt Mask Set/Clear Register */ + +#define SSP_IMSC_RORIM (1 << 0) /* Bit 0: Enable Receive Overrun Interrupt */ +#define SSP_IMSC_RTIM (1 << 1) /* Bit 1: Enable Receive Timeout Interrupt */ +#define SSP_IMSC_RXIM (1 << 2) /* Bit 2: Enable Rx FIFO half full Interrupt */ +#define SSP_IMSC_TXIM (1 << 3) /* Bit 3: Enable Tx FIFO halt empty */ + /* Bits 4-31: Reserved */ + +/* SPI/SSP Raw Interrupt Status */ + +#define SSP_RIS_RORIS (1 << 0) /* Bit 0: An Overrun event occurred */ +#define SSP_RIS_RTRIS (1 << 1) /* Bit 1: Rx FIFO has data and MCU didn't read it */ +#define SSP_RIS_RXRIS (1 << 2) /* Bit 2: The Rx FIFO is at least half full */ +#define SSP_RIS_TXRIS (1 << 3) /* Bit 3: Tx FIFO is at least halt empty */ + /* Bits 4-31: Reserved */ + +/* SPI/SSP Masked Interrupt Status Register */ + +#define SSP_MIS_RORMIS (1 << 0) /* Bit 0: An Overrun occurred and this interrupt is enabled */ +#define SSP_MIS_RTMIS (1 << 1) /* Bit 1: An Rx FIFO timeout happened and this int is enabled */ +#define SSP_MIS_RXMIS (1 << 2) /* Bit 2: Rx FIFO is at least half empty and this int is enabled */ +#define SSP_MIS_TXMIS (1 << 3) /* Bit 3: Tx FIFO is at least halt full and this int is enabled */ + /* Bits 4-31: Reserved */ +/* SPI/SSP Interrupt Clear Register */ + +#define SSP_ICR_RORIC (1 << 0) /* Bit 0: Clear Rx FIFO Overrun Interrupt */ +#define SSP_ICR_RTIC (1 << 1) /* Bit 1: Clear Rx FIFO read timeout Interrupt */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SPI_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_syscon.h b/arch/arm/src/lpc11xx/chip/lpc11_syscon.h new file mode 100644 index 0000000000000000000000000000000000000000..62f486805359a43df1ab6be59d5e4a285decfcf2 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_syscon.h @@ -0,0 +1,449 @@ +/******************************************************************************************** + * arch/arm/src/lpc11xx/chip/lpc11_syscon.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SYSCON_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SYSCON_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register offsets *************************************************************************/ + +#define LPC11_SYSCON_SYSMEMREMAP_OFFSET 0x0000 /* System memory remap */ +#define LPC11_SYSCON_PRESETCTRL_OFFSET 0x0004 /* Pefipheral reset control */ +#define LPC11_SYSCON_SYSPLLCTRL_OFFSET 0x0008 /* System PLL control */ +#define LPC11_SYSCON_SYSPLLSTAT_OFFSET 0x000C /* System PLL status */ + /* 0x010 - 0x01c: Reserved */ + +#define LPC11_SYSCON_SYSOSCCTRL_OFFSET 0x0020 /* System oscillator control */ +#define LPC11_SYSCON_WDTOSCCTRL_OFFSET 0x0024 /* Watchdog oscillator control */ +#define LPC11_SYSCON_IRCCTRL_OFFSET 0x0028 /* IRC control */ + /* 0x02c: Reserved */ + +#define LPC11_SYSCON_SYSRSTSTAT_OFFSET 0x0030 /* System reset status register */ + /* 0x034 - 0x03c: Reserved */ + +#define LPC11_SYSCON_SYSPLLCLKSEL_OFFSET 0x0040 /* System PLL clock source select */ +#define LPC11_SYSCON_SYSPLLCLKUEN_OFFSET 0x0044 /* System PLL clock source update enable */ + /* 0x048 - 0x06c: Reserved */ + +#define LPC11_SYSCON_MAINCLKSEL_OFFSET 0x0070 /* Main clock source select */ +#define LPC11_SYSCON_MAINCLKUEN_OFFSET 0x0074 /* Main clock source update enable */ +#define LPC11_SYSCON_SYSAHBCLKDIV_OFFSET 0x0078 /* System AHB clock divider */ + /* 0x07c: Reserved */ + +#define LPC11_SYSCON_SYSAHBCLKCTRL_OFFSET 0x0080 /* System AHB clock control */ + /* 0x084 - 0x090: Reserved */ + +#define LPC11_SYSCON_SSP0CLKDIV_OFFSET 0x0094 /* SPI0 clock divider */ +#define LPC11_SYSCON_UARTCLKDIV_OFFSET 0x0098 /* UART clock divider */ +#define LPC11_SYSCON_SSP1CLKDIV_OFFSET 0x009c /* SPI1 clock divider */ + /* 0x0a0 - 0x0cc: Reserved */ + +#define LPC11_SYSCON_WDTCLKSEL_OFFSET 0x00d0 /* WDT clock source select */ +#define LPC11_SYSCON_WDTCLKUEN_OFFSET 0x00d4 /* WDT clock source update enable */ +#define LPC11_SYSCON_WDTCLKDIV_OFFSET 0x00d8 /* WDT clock divider */ + /* 0x0dc: Reserved */ + +#define LPC11_SYSCON_CLKOUTCLKSEL_OFFSET 0x00e0 /* CLKOUT clock source select */ +#define LPC11_SYSCON_CLKOUTUEN_OFFSET 0x00e4 /* CLKOUT clock source update enable */ +#define LPC11_SYSCON_CLKOUTCLKDIV_OFFSET 0x00e8 /* CLKOUT clock divider */ + /* 0x0ec - 0x0fc: Reserved */ + +#define LPC11_SYSCON_PIOPORCAP0_OFFSET 0x0100 /* POR captured PIO status 0 */ +#define LPC11_SYSCON_PIOPORCAP1_OFFSET 0x0104 /* POR captured PIO status 1 */ + /* 0x108 - 0x14c: Reserved */ + +#define LPC11_SYSCON_BODCTRL_OFFSET 0x0150 /* BOD control */ +#define LPC11_SYSCON_SYSTCKCAL_OFFSET 0x0154 /* System tick counter calibration */ + /* 0x158 - 0x16c: Reserved */ + +#define LPC11_SYSCON_IRQLATENCY_OFFSET 0x0170 /* IRQ delay */ +#define LPC11_SYSCON_NMISRC_OFFSET 0x0174 /* NMI source selection */ + /* 0x178 - 0x1fc: Reserved */ + +#define LPC11_SYSCON_STARTAPRP0_OFFSET 0x0200 /* Start logic edge control register 0 */ +#define LPC11_SYSCON_STARTERP0_OFFSET 0x0204 /* Start logic signal enable register 0 */ +#define LPC11_SYSCON_STARTRSRP0CLR_OFFSET 0x0208 /* Start logic reset register 0 */ +#define LPC11_SYSCON_STARTSRP0_OFFSET 0x020c /* Start logic status register 0 */ + /* 0x210 - 0x22c: Reserved */ + +#define LPC11_SYSCON_PDSLEEPCFG_OFFSET 0x0230 /* Power-down states in Deep-sleep mode */ +#define LPC11_SYSCON_PDAWAKECFG_OFFSET 0x0234 /* Power-down states after wake-up from Deep-sleep mode */ +#define LPC11_SYSCON_PDRUNCFG_OFFSET 0x0238 /* Power-down configuration register */ + /* 0x023c - 0x3f0: Reserved */ +#define LPC11_SYSCON_DEVICE_ID_OFFSET 0x03f4 /* Device ID register 0 for parts LPC1100, LPC1100C, LPC1100L */ + + +/* Register addresses ***********************************************************************/ + +#define LPC11_SYSCON_SYSMEMREMAP (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSMEMREMAP_OFFSET) + +#define LPC11_SYSCON_PRESETCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_PRESETCTRL_OFFSET) +#define LPC11_SYSCON_SYSPLLCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSPLLCTRL_OFFSET) +#define LPC11_SYSCON_SYSPLLSTAT (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSPLLSTAT_OFFSET) + +#define LPC11_SYSCON_SYSOSCCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSOSCCTRL_OFFSET) +#define LPC11_SYSCON_WDTOSCCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_WDTOSCCTRL_OFFSET) +#define LPC11_SYSCON_IRCCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_IRCCTRL_OFFSET) + +#define LPC11_SYSCON_SYSRSTSTAT (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSRSTSTAT_OFFSET) + +#define LPC11_SYSCON_SYSPLLCLKSEL (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSPLLCLKSEL_OFFSET) +#define LPC11_SYSCON_SYSPLLCLKUEN (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSPLLCLKUEN_OFFSET) + +#define LPC11_SYSCON_MAINCLKSEL (LPC11_SYSCON_BASE + LPC11_SYSCON_MAINCLKSEL_OFFSET) +#define LPC11_SYSCON_MAINCLKUEN (LPC11_SYSCON_BASE + LPC11_SYSCON_MAINCLKUEN_OFFSET) + +#define LPC11_SYSCON_SYSAHBCLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSAHBCLKDIV_OFFSET) +#define LPC11_SYSCON_SYSAHBCLKCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSAHBCLKCTRL_OFFSET) + +#define LPC11_SYSCON_SSP0CLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_SSP0CLKDIV_OFFSET) +#define LPC11_SYSCON_UARTCLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_UARTCLKDIV_OFFSET) +#define LPC11_SYSCON_SSP1CLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_SSP1CLKDIV_OFFSET) + +#define LPC11_SYSCON_WDTCLKSEL (LPC11_SYSCON_BASE + LPC11_SYSCON_WDTCLKSEL_OFFSET) +#define LPC11_SYSCON_WDTCLKUEN (LPC11_SYSCON_BASE + LPC11_SYSCON_WDTCLKUEN_OFFSET) +#define LPC11_SYSCON_WDTCLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_WDTCLKDIV_OFFSET) + +#define LPC11_SYSCON_CLKOUTCLKSEL (LPC11_SYSCON_BASE + LPC11_SYSCON_CLKOUTCLKSEL_OFFSET) +#define LPC11_SYSCON_CLKOUTUEN (LPC11_SYSCON_BASE + LPC11_SYSCON_CLKOUTUEN_OFFSET_OFFSET) +#define LPC11_SYSCON_CLKOUTCLKDIV (LPC11_SYSCON_BASE + LPC11_SYSCON_CLKOUTCLKDIV_OFFSET) + +#define LPC11_SYSCON_PIOPORCAP0 (LPC11_SYSCON_BASE + LPC11_SYSCON_PIOPORCAP0_OFFSET) +#define LPC11_SYSCON_PIOPORCAP1 (LPC11_SYSCON_BASE + LPC11_SYSCON_PIOPORCAP1_OFFSET) + +#define LPC11_SYSCON_BODCTRL (LPC11_SYSCON_BASE + LPC11_SYSCON_BODCTRL_OFFSET) +#define LPC11_SYSCON_SYSTCKCAL (LPC11_SYSCON_BASE + LPC11_SYSCON_SYSTCKCAL_OFFSET) + +#define LPC11_SYSCON_IRQLATENCY (LPC11_SYSCON_BASE + LPC11_SYSCON_IRQLATENCY_OFFSET) +#define LPC11_SYSCON_NMISRC (LPC11_SYSCON_BASE + LPC11_SYSCON_NMISRC_OFFSET) + +#define LPC11_SYSCON_STARTAPRP0 (LPC11_SYSCON_BASE + LPC11_SYSCON_STARTAPRP0_OFFSET) +#define LPC11_SYSCON_STARTERP0 (LPC11_SYSCON_BASE + LPC11_SYSCON_STARTERP0_OFFSET) +#define LPC11_SYSCON_STARTRSRP0CLR (LPC11_SYSCON_BASE + LPC11_SYSCON_STARTRSRP0CLR_OFFSET) +#define LPC11_SYSCON_STARTSRP0 (LPC11_SYSCON_BASE + LPC11_SYSCON_STARTSRP0_OFFSET) + +#define LPC11_SYSCON_PDSLEEPCFG (LPC11_SYSCON_BASE + LPC11_SYSCON_PDSLEEPCFG_OFFSET) +#define LPC11_SYSCON_PDAWAKECFG (LPC11_SYSCON_BASE + LPC11_SYSCON_PDAWAKECFG_OFFSET) +#define LPC11_SYSCON_PDRUNCFG (LPC11_SYSCON_BASE + LPC11_SYSCON_PDRUNCFG_OFFSET) + +#define LPC11_SYSCON_DEVICE_ID (LPC11_SYSCON_BASE + LPC11_SYSCON_DEVICE_ID_OFFSET) + +/* Register bit definitions *****************************************************************/ + +#define SYSCON_SYSMEMREMAP_MAP_SHIFT (0) /* Bits 0-1: System memory remap register */ +#define SYSCON_SYSMEMREMAP_MAP_MASK (3 << SYSCON_SYSMEMREMAP_MAP_SHIFT) +# define SYSCON_SYSMEMREMAP_MAP_BOOTLOADER (0 << SYSCON_SYSMEMREMAP_MAP_SHIFT) /* Interrupt vectors are re-mapped to Boot ROM */ +# define SYSCON_SYSMEMREMAP_MAP_RAM (1 << SYSCON_SYSMEMREMAP_MAP_SHIFT) /* Interrupt vectors are re-mapped to Static RAM */ +# define SYSCON_SYSMEMREMAP_MAP_FLASH (2 << SYSCON_SYSMEMREMAP_MAP_SHIFT) /* Interrupt vectors are keeped in flash */ + /* Bits 2-31: Reserved */ + +#define SYSCON_PRESETCTRL_SSP0_RST_N (1 << 0) /* SPI0 reset control */ +#define SYSCON_PRESETCTRL_I2C0_RST_N (1 << 1) /* I2C0 reset control */ +#define SYSCON_PRESETCTRL_SSP1_RST_N (1 << 2) /* SPI1 reset control */ +#define SYSCON_PRESETCTRL_CAN_RST_N (1 << 3) /* C_CAN reset control */ + /* Bits 4-31: Reserved */ + +#define SYSCON_SYSPLLCTRL_MSEL_SHIFT (0) /* Bits 0-4: Feedback divider value. */ +#define SYSCON_SYSPLLCTRL_MSEL_MASK (0x1f << SYSCON_SYSPLLCTRL_MSEL_SHIFT) +# define SYSCON_SYSPLLCTRL_MSEL_DIV(n) ((n-1) << SYSCON_SYSPLLCTRL_MSEL_SHIFT) /* n=1,2,3,..32 */ +#define SYSCON_SYSPLLCTRL_PSEL_SHIFT (5) /* Bits 5-6: Post divider ratio P. The division ratio is 2 x P */ +#define SYSCON_SYSPLLCTRL_PSEL_MASK (3 << SYSCON_SYSPLLCTRL_PSEL_SHIFT) +# define SYSCON_SYSPLLCTRL_PSEL_DIV1 (0 << SYSCON_SYSPLLCTRL_PSEL_SHIFT) +# define SYSCON_SYSPLLCTRL_PSEL_DIV2 (1 << SYSCON_SYSPLLCTRL_PSEL_SHIFT) +# define SYSCON_SYSPLLCTRL_PSEL_DIV4 (2 << SYSCON_SYSPLLCTRL_PSEL_SHIFT) +# define SYSCON_SYSPLLCTRL_PSEL_DIV8 (3 << SYSCON_SYSPLLCTRL_PSEL_SHIFT) + /* Bits 7-31: Reserved */ + +#define SYSCON_SYSPLLSTAT_LOCK (1 << 0) /* PLL lock status. 0 = PLL not locked, 1 = PLL locked */ + /* Bits 1-31: Reserved */ + +#define SYSCON_SYSOSCCTRL_BYPASS (1 << 0) /* Bypass system oscillator */ +#define SYSCON_SYSOSCCTRL_FREQRANGE (1 << 1) /* Determines freq. range for low-power oscillator */ + /* Bits 2-31: Reserved */ +#define SYSCON_WDTOSCCTRL_DIVSEL_SHIFT (0) /* Bits 0-4: Select divider for Fclkana. wdt_osc_clk = Fclkana/(2x(1+DIVSEL)) */ +#define SYSCON_WDTOSCCTRL_DIVSEL_MASK (0x1f << SYSCON_WDTOSCCTRL_DIVSEL_SHIFT) +# define SYSCON_WDTOSCCTRL_DIVSEL(n) (((n-2)/2) << SYSCON_WDTOSCCTRL_DIVSEL_SHIFT) /* n = 2,4,8,..64 */ +#define SYSCON_WDTOSCCTRL_FREQSEL_SHIFT (5) /* Bits 5-8: Select watchdog oscillator analog output frequency */ +#define SYSCON_WDTOSCCTRL_FREQSEL_MASK (15 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) +# define SYSCON_WDTOSCCTRL_FREQSEL_0p6Mhz (1 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 0.6 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_1p05Mhz (2 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 1.05 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_1p4Mhz (3 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 1.4 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_1p75Mhz (4 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 1.75 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_2p1Mhz (5 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 2.1 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_2p4Mhz (6 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 2.4 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_2p7Mhz (7 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 2.7 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_3Mhz (8 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 3.0 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_3p25Mhz (9 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 3.25 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_3p5Mhz (10 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 3.5 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_3p75Mhz (11 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 3.75 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_4Mhz (12 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 4 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_4p2Mhz (13 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 4.2 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_4p4Mhz (14 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 4.4 MHz */ +# define SYSCON_WDTOSCCTRL_FREQSEL_4p6Mhz (15 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* Select watchdog osc analog freq 4.6 MHz */ + /* Bits 9-31: Reserved */ + +#define SYSCON_IRCCTRL_TRIM_MASK (0xff) /* Bits 0-7: Trim value used to adjust on-chip 12 MHz oscillator */ + /* Bits 8-31: Reserved */ + +#define SYSCON_SYSRSTSTAT_POR (1 << 0) /* POR reset status */ +#define SYSCON_SYSRSTSTAT_EXTRST (1 << 1) /* Status of the external /RESET pin */ +#define SYSCON_SYSRSTSTAT_WDT (1 << 2) /* Status of the Watchdog reset */ +#define SYSCON_SYSRSTSTAT_BOD (1 << 3) /* Status of Brown-out detect reset */ +#define SYSCON_SYSRSTSTAT_SYSRST (1 << 4) /* Status of the software system reset */ + /* Bits 5-31: Reserved */ + +#define SYSCON_SYSPLLCLKSEL_SHIFT (0) /* Bits 0-1: System PLL clock source */ +#define SYSCON_SYSPLLCLKSEL_MASK (3 << SYSCON_SYSPLLCLKSEL_SHIFT) +# define SYSCON_SYSPLLCLKSEL_IRCOSC (0 << SYSCON_SYSPLLCLKSEL_SHIFT) +# define SYSCON_SYSPLLCLKSEL_SYSOSC (1 << SYSCON_SYSPLLCLKSEL_SHIFT) + /* Bits 2-31: Reserved */ + +#define SYSCON_SYSPLLCLKUEN_ENA (1 << 0) /* Bit 0: Enable system PLL clock source update */ + /* Bits 1-31: Reserved */ + +#define SYSCON_MAINCLKSEL_SHIFT (0) /* Bits 0-1: Clock source for main clock */ +#define SYSCON_MAINCLKSEL_MASK (3 << SYSCON_MAINCLKSEL_SHIFT) +# define SYSCON_MAINCLKSEL_IRCOSC (0 << SYSCON_MAINCLKSEL_SHIFT) /* IRC oscillator */ +# define SYSCON_MAINCLKSEL_PLLOSC (1 << SYSCON_MAINCLKSEL_SHIFT) /* Input clock to system PLL */ +# define SYSCON_MAINCLKSEL_WDTOSC (2 << SYSCON_MAINCLKSEL_SHIFT) /* WDT oscillator */ +# define SYSCON_MAINCLKSEL_SYSPLLCLKOUT (3 << SYSCON_MAINCLKSEL_SHIFT) /* System PLL clock out */ + /* Bits 2-31: Reserved */ + +#define SYSCON_MAINCLKUEN_ENA (1 << 0) /* Bit 0: Enable main clock source update */ + /* Bits 1-31: Reserved */ + +#define SYSCON_SYSAHBCLKDIV_SHIFT (0) /* Bits 0-7: 0=System clock disabled, 1=Divide by 1 ... 255 = Divide by 255 */ +#define SYSCON_SYSAHBCLKDIV_MASK (0xff << SYSCON_SYSAHBCLKDIV_SHIFT) + /* Bits 8-31: Reserved */ +//# define SYSCON_CCLKCFG_DIV(n) ((n-1) << SYSCON_CCLKCFG_SHIFT) /* n=2,3,..255 */ + +#define SYSCON_SYSAHBCLKCTRL_SYS (1 << 0) /* Bit 0: Enables clock for AHB to APB bridge */ +#define SYSCON_SYSAHBCLKCTRL_ROM (1 << 1) /* Bit 1: Enables clock for ROM */ +#define SYSCON_SYSAHBCLKCTRL_RAM (1 << 2) /* Bit 2: Enables clock for RAM */ +#define SYSCON_SYSAHBCLKCTRL_FLASHREG (1 << 3) /* Bit 3: Enables clock for flash register interface */ +#define SYSCON_SYSAHBCLKCTRL_FLASHARRAY (1 << 4) /* Bit 4: Enables clock for flash array access */ +#define SYSCON_SYSAHBCLKCTRL_I2C0 (1 << 5) /* Bit 5: Enables clock for I2C0 */ +#define SYSCON_SYSAHBCLKCTRL_GPIO (1 << 6) /* Bit 6: Enables clock for GPIO */ +#define SYSCON_SYSAHBCLKCTRL_CT16B0 (1 << 7) /* Bit 7: Enables clock for 16-bit counter/timer 0 */ +#define SYSCON_SYSAHBCLKCTRL_CT16B1 (1 << 8) /* Bit 8: Enables clock for 16-bit counter/timer 1 */ +#define SYSCON_SYSAHBCLKCTRL_CT32B0 (1 << 9) /* Bit 9: Enables clock for 32-bit counter/timer 0 */ +#define SYSCON_SYSAHBCLKCTRL_CT32B1 (1 << 10) /* Bit 10: Enables clock for 32-bit counter/timer 1 */ +#define SYSCON_SYSAHBCLKCTRL_SSP0 (1 << 11) /* Bit 11: Enables clock for SPI0 */ +#define SYSCON_SYSAHBCLKCTRL_UART (1 << 12) /* Bit 12: Enables clock for UART */ +#define SYSCON_SYSAHBCLKCTRL_ADC (1 << 13) /* Bit 13: Enables clock for ADC */ + /* Bit 14: Reserved */ +#define SYSCON_SYSAHBCLKCTRL_WDT (1 << 15) /* Bit 15: Enables clock for WDT */ +#define SYSCON_SYSAHBCLKCTRL_IOCON (1 << 16) /* Bit 16: Enables clock for I/O configuration block */ +#define SYSCON_SYSAHBCLKCTRL_CAN (1 << 17) /* Bit 17: Enables clock for C_CAN */ +#define SYSCON_SYSAHBCLKCTRL_SSP1 (1 << 18) /* Bit 18: Enables clock for SPI1 */ + /* Bits 19-31: Reserved */ + +#define SYSCON_SSP0CLKDIV_MASK (0xff) /* Bits 0-7: 0=Disable SPI0_PCLK, 1=Divide by 1 ... 255 = Divide by 255 */ + /* Bits 8-31: Reserved */ + +#define SYSCON_UARTCLKDIV_MASK (0xff) /* Bits 0-7: 0=Disable UART_PCLK, 1=Divide by 1 ... 255 = Divide by 255 */ + /* Bits 8-31: Reserved */ + +#define SYSCON_SSP1CLKDIV_MASK (0xff) /* Bits 0-7: 0=Disable SPI1_PCLK, 1=Divide by 1 ... 255 = Divide by 255 */ + /* Bits 8-31: Reserved */ + +#define SYSCON_WDTCLKSEL_SHIFT (0) /* Bits 0-1: WDT clock source */ +#define SYSCON_WDTCLKSEL_MASK (3 << SYSCON_WDTCLKSEL_SHIFT) +# define SYSCON_WDTCLKSEL_IRCOSC (0 << SYSCON_WDTCLKSEL_SHIFT) /* IRC oscillator */ +# define SYSCON_WDTCLKSEL_MAINCLK (1 << SYSCON_WDTCLKSEL_SHIFT) /* Main clock */ +# define SYSCON_WDTCLKSEL_WDTOSC (2 << SYSCON_WDTCLKSEL_SHIFT) /* Watchdog oscillator */ + /* Bits 2-31: reserved */ + +#define SYSCON_WDTCLKUEN_ENA (1 << 0) /* Bit 0: Enable WDT clock source update */ + /* Bits 1-31: Reserved */ + +#define SYSCON_WDTCLKDIV_MASK (0xff) /* Bits 0-7: 0=Disable WDCLK, 1=Divide by 1 ... 255 = Divide by 255 */ + /* Bits 8-31: Reserved */ + +#define SYSCON_CLKOUTCLKSEL_SHIFT (0) /* Bits 0-1: CLKOUT clock source */ +#define SYSCON_CLKOUTCLKSEL_MASK (3 << SYSCON_CLKOUTCLKSEL_SHIFT) +# define SYSCON_CLKOUTCLKSEL_IRCOSC (0 << SYSCON_CLKOUTCLKSEL_SHIFT) /* IRC oscillator */ +# define SYSCON_CLKOUTCLKSEL_SYSOSC (1 << SYSCON_CLKOUTCLKSEL_SHIFT) /* System oscillator */ +# define SYSCON_CLKOUTCLKSEL_WDTOSC (2 << SYSCON_CLKOUTCLKSEL_SHIFT) /* Watchdog oscillator */ +# define SYSCON_CLKOUTCLKSEL_MAINCLK (3 << SYSCON_CLKOUTCLKSEL_SHIFT) /* Main clock */ + /* Bits 2-31: Reserved */ + +#define SYSCON_CLKOUTUEN_ENA (1 << 0) /* Bit 0: Enable CLKOUT clock source update */ + /* Bits 1-31: Reserved */ + +#define SYSCON_CLKOUTCLKDIV_MASK (0xff) /* Bits 0-7: 0=Disable CLKOUT, 1=Divide by 1 ... 255 = Divide by 255 */ + /* Bits 1-31: Reserved */ + +#define SYSCON_PIOPORCAP0_CAPPIO0_SHIFT (0) /* Bits 0-11: Raw reset stats input PIO0_n: PIO0_11 to PIO0_0 */ +#define SYSCON_PIOPORCAP0_CAPPIO0_MASK (0xfff << SYSCON_PIOPORCAP0_CAPPIO0_SHIFT) +# define SYSCON_PIOPORCAP0_CAPPIO0_BIT(n) ((1 << n) << SYSCON_PIOPORCAP0_CAPPIO0_SHIFT) /* n = 0 to 11 */ + +#define SYSCON_PIOPORCAP0_CAPPIO1_SHIFT (12) /* Bits 12-23: Raw reset stats input PIO0_n: PIO1_11 to PIO1_0 */ +#define SYSCON_PIOPORCAP0_CAPPIO1_MASK (0xfff << SYSCON_PIOPORCAP0_CAPPIO1_SHIFT) +# define SYSCON_PIOPORCAP0_CAPPIO1_BIT(n) ((1 << n) << SYSCON_PIOPORCAP0_CAPPIO1_SHIFT) /* n = 0 to 11 */ + +#define SYSCON_PIOPORCAP0_CAPPIO2_SHIFT (24) /* Bits 24-31: Raw reset stats input PIO0_n: PIO2_11 to PIO2_0 */ +#define SYSCON_PIOPORCAP0_CAPPIO2_MASK (0xfff << SYSCON_PIOPORCAP0_CAPPIO2_SHIFT) +# define SYSCON_PIOPORCAP0_CAPPIO2_BIT(n) ((1 << n) << SYSCON_PIOPORCAP0_CAPPIO2_SHIFT) /* n = 0 to 11 */ + + +#define SYSCON_PIOPORCAP1_CAPPIO2_8 (1 << 0) /* Bit 0: Raw reset status input PIO2_8 */ +#define SYSCON_PIOPORCAP1_CAPPIO2_9 (1 << 1) /* Bit 1: Raw reset status input PIO2_9 */ +#define SYSCON_PIOPORCAP1_CAPPIO2_10 (1 << 2) /* Bit 2: Raw reset status input PIO2_10 */ +#define SYSCON_PIOPORCAP1_CAPPIO2_11 (1 << 3) /* Bit 3: Raw reset status input PIO2_11 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_0 (1 << 4) /* Bit 4: Raw reset status input PIO3_0 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_1 (1 << 5) /* Bit 5: Raw reset status input PIO3_1 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_2 (1 << 6) /* Bit 6: Raw reset status input PIO3_2 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_3 (1 << 7) /* Bit 7: Raw reset status input PIO3_3 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_4 (1 << 8) /* Bit 8: Raw reset status input PIO3_4 */ +#define SYSCON_PIOPORCAP1_CAPPIO3_5 (1 << 9) /* Bit 9: Raw reset status input PIO3_5 */ + /* Bits 10-31: Reserved */ + +#define SYSCON_BODCTRL_BODRSTLEV_SHIFT (0) /* Bits 0-1: BOD reset level */ +#define SYSCON_BODCTRL_BODRSTLEV_MASK (3 << SYSCON_BODCTRL_BODRSTLEV_SHIFT) +# define SYSCON_BODCTRL_BODRSTLEV_LEVEL0 (0 << SYSCON_BODCTRL_BODRSTLEV_SHIFT) /* Level 0: assert 1.46V, de-assert 1.63V */ +# define SYSCON_BODCTRL_BODRSTLEV_LEVEL1 (1 << SYSCON_BODCTRL_BODRSTLEV_SHIFT) /* Level 1: assert 2.06V, de-assert 2.15V */ +# define SYSCON_BODCTRL_BODRSTLEV_LEVEL2 (2 << SYSCON_BODCTRL_BODRSTLEV_SHIFT) /* Level 2: assert 2.35V, de-assert 2.43V */ +# define SYSCON_BODCTRL_BODRSTLEV_LEVEL3 (3 << SYSCON_BODCTRL_BODRSTLEV_SHIFT) /* Level 3: assert 2.63V, de-assert 2.71V */ +#define SYSCON_BODCTRL_BODINTVAL_SHIFT (2) /* Bits 2-3: BOD interrupt level */ +#define SYSCON_BODCTRL_BODINTVAL_MASK (3 << SYSCON_BODCTRL_BODRSTLEV_BODINTVAL_SHIFT) +# define SYSCON_BODCTRL_BODINTVAL_LEVEL0 (0 << SYSCON_BODCTRL_BODINTVAL_SHIFT) /* Level 0: Reserved */ +# define SYSCON_BODCTRL_BODINTVAL_LEVEL1 (1 << SYSCON_BODCTRL_BODINTVAL_SHIFT) /* Level 1: int. assert 2.22V,de-a. 2.35V */ +# define SYSCON_BODCTRL_BODINTVAL_LEVEL2 (2 << SYSCON_BODCTRL_BODINTVAL_SHIFT) /* Level 2: int. assert 2.52V,de-a. 2.66V */ +# define SYSCON_BODCTRL_BODINTVAL_LEVEL3 (3 << SYSCON_BODCTRL_BODINTVAL_SHIFT) /* Level 3: int. assert 2.80V,de-a. 2.90V */ +#define SYSCON_BODCTRL_BODRSTENA (1 << 4) /* BOD reset enable */ + /* Bits 5-31: Reserved */ + +#define SYSCON_SYSTCKCAL_CAL 0x3ffffff /* Bits 0-25: System tick timer calibration value */ + /* Bits 26-31: Reserved */ + +#define SYSCON_IRQLATENCY_LATENCY_MASK (0xff) /* Bits 0-7: 8-bit latency value */ + /* Bits 8-31: Reserved */ + +#define SYSCON_NMISRC_IRQNO_SHIFT (0) /* Bits 0-4: The IRQ number of interrupt that acts as NMI if bit 31 is 1 */ +#define SYSCON_NMISRC_IRQNO_MASK (31 << SYSCON_NMISRC_IRQNO_SHIFT) + /* Bits 5-30: Reserved */ +#define SYSCON_NMISRC_NMIEN (1 << 31) /* Write 1 to this bit to enable NMI source selected by bits 4:0 */ + +#define SYSCON_STARTAPRP0_APRPIO0_SHIFT (0) /* Bits 0-11: Edge select for start logic input PIO0_[0-11], 0=fall/1=rise */ +#define SYSCON_STARTAPRP0_APRPIO0_MASK (0xfff << SYSCON_STARTAPRP0_APRPIO0_SHIFT) +# define SYSCON_STARTAPRP0_APRPIO0_BIT(n) ((1 << n) << SYSCON_STARTAPRP0_APRPIO0_SHIFT) /* n = 0 to 11 */ +#define SYSCON_STARTAPRP0_APRPIO1_0 (1 << 12) /* Bit 12: Edge select start logic input PIO1_0, 0=falling/1=rising */ + /* Bits 13-31: Reserved */ + +#define SYSCON_STARTERP0_ERPIO0_SHIFT (0) /* Bits 0-11: Enable start signal for start logic input PIO0[0-11] */ +#define SYSCON_STARTERP0_ERPIO0_MASK (0xfff << SYSCON_STARTERP0_ERPIO0_SHIFT) +# define SYSCON_STARTERP0_ERPIO0_BIT(n) ((1 << n) << SYSCON_STARTERP0_ERPIO0_SHIFT) /* n = 0 to 11 */ +#define SYSCON_STARTERP0_ERPIO1_0 (1 << 12) /* Bit 12: Enable start signal for start logic input PIO1_0 */ + /* Bits 13-31: Reserved */ + +#define SYSCON_STARTRSRP0CLR_RSRPIO0_SHIFT (0) /* Bits 0-11: Start logic reset register 0 */ +#define SYSCON_STARTRSRP0CLR_RSRPIO0_MASK (0xfff << SYSCON_STARTRSRP0CLR_RSRPIO0_SHIFT) +# define SYSCON_STARTRSRP0CLR_RSRPIO0_BIT(n) ((1 << n) << SYSCON_STARTRSRP0CLR_RSRPIO0_SHIFT) /* n = 0 to 11 */ +#define SYSCON_STARTRSRP0CLR_RSRPIO1_0 (1 << 12) /* Bit 12: Start signal reset for start logic input PIO1_0 */ + /* Bits 13-31: Reserved */ + +#define SYSCON_STARTSRP0_SRPIO0_SHIFT (0) /* Bits 0-11: Start logic status register 0 */ +#define SYSCON_STARTSRP0_SRPIO0_MASK (0xfff << SYSCON_STARTSRP0_SRPIO0_SHIFT) +# define SYSCON_STARTSRP0_SRPIO0_BIT(n) ((1 << n) << SYSCON_STARTSRP0_SRPIO0_SHIFT) /* n = 0 to 11 */ +#define SYSCON_STARTSRP0_SRPIO1_0 (1 << 12) /* Bit 12: Start signal status for start logic input PIO1_0 */ + /* Bits 13-31: Reserved */ + + /* Bits 0-2: Reserved. NOTE: Always write these bits as 111 */ +#define SYSCON_PDSLEEPCFG_BOD_PD (1 << 3) /* BOD power-down control in Deep-sleep mode */ + /* Bits 4-5: Reserved. NOTE: Always write these bits as 11 */ +#define SYSCON_PDSLEEPCFG_WDTOSC_PD (1 << 6) /* Watchdog oscillator power control in Deep-sleep mode */ + /* Bit 7: Reserved. NOTE: Always write this bit as 1 */ + /* Bits 8-10: Reserved NOTE: Always write these bits as 000 */ + /* Bits 11-12: Reserved. NOTE: Always write these bits as 11 */ + /* Bits 13-31: Reserved */ + +#define SYSCON_PDAWAKECFG_IRCOUT_PD (1 << 0) /* Bit 0: IRC oscillator output wake-up configuration */ +#define SYSCON_PDAWAKECFG_IRC_PD (1 << 1) /* Bit 1: IRC oscillator wake-up configuration */ +#define SYSCON_PDAWAKECFG_FLASH_PD (1 << 2) /* Bit 2: Flash wake-up configuration */ +#define SYSCON_PDAWAKECFG_BOD_PD (1 << 3) /* Bit 3: Brownout Detection wake-up configuration */ +#define SYSCON_PDAWAKECFG_ADC_PD (1 << 4) /* Bit 4: ADC wake-up configuration */ +#define SYSCON_PDAWAKECFG_SYSOSC_PD (1 << 5) /* Bit 5: System oscillator wake-up configuration */ +#define SYSCON_PDAWAKECFG_WDTOSC_PD (1 << 6) /* Bit 6: Watchdog oscillator wake-up configuration */ +#define SYSCON_PDAWAKECFG_SYSPLL_PD (1 << 7) /* Bit 7: System PLL wake-up configuration */ + /* Bit 8: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 9: Reserved. NOTE: Always write this bit as 0 */ + /* Bit 10: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 11: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 12: Reserved. NOTE: Always write this bit as 0 */ + /* Bits 13-15: Reserved. NOTE: Always write these bits as 111 */ + /* Bits 16-31: Reserved */ + +#define SYSCON_PDRUNCFG_IRCOUT_PD (1 << 0) /* Bit 0: IRC oscillator output power-down */ +#define SYSCON_PDRUNCFG_IRC_PD (1 << 1) /* Bit 1: IRC oscillator power-down */ +#define SYSCON_PDRUNCFG_FLASH_PD (1 << 2) /* Bit 2: Flash power-down */ +#define SYSCON_PDRUNCFG_BOD_PD (1 << 3) /* Bit 3: Brownout Detection power-down */ +#define SYSCON_PDRUNCFG_ADC_PD (1 << 4) /* Bit 4: ADC power-down */ +#define SYSCON_PDRUNCFG_SYSOSC_PD (1 << 5) /* Bit 5: System oscillator power-down */ +#define SYSCON_PDRUNCFG_WDTOSC_PD (1 << 6) /* Bit 6: Watchdog oscillator power-down */ +#define SYSCON_PDRUNCFG_SYSPLL_PD (1 << 7) /* Bit 7: System PLL power-down */ + /* Bit 8: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 9: Reserved. NOTE: Always write this bit as 0 */ + /* Bit 10: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 11: Reserved. NOTE: Always write this bit as 1 */ + /* Bit 12: Reserved. NOTE: Always write this bit as 0 */ + /* Bits 13-15: Reserved. NOTE: Always write these bits as 111 */ + /* Bits 16-31: Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_SYSCON_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_timer.h b/arch/arm/src/lpc11xx/chip/lpc11_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..28e1122323be13fc764b468876e0d27d4496a793 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_timer.h @@ -0,0 +1,271 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_timer.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_TIMER_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_TMR_IR_OFFSET 0x0000 /* Interrupt Register */ +#define LPC11_TMR_TCR_OFFSET 0x0004 /* Timer Control Register */ +#define LPC11_TMR_TC_OFFSET 0x0008 /* Timer Counter */ +#define LPC11_TMR_PR_OFFSET 0x000c /* Prescale Register */ +#define LPC11_TMR_PC_OFFSET 0x0010 /* Prescale Counter */ +#define LPC11_TMR_MCR_OFFSET 0x0014 /* Match Control Register */ +#define LPC11_TMR_MR0_OFFSET 0x0018 /* Match Register 0 */ +#define LPC11_TMR_MR1_OFFSET 0x001c /* Match Register 1 */ +#define LPC11_TMR_MR2_OFFSET 0x0020 /* Match Register 2 */ +#define LPC11_TMR_MR3_OFFSET 0x0024 /* Match Register 3 */ +#define LPC11_TMR_CCR_OFFSET 0x0028 /* Capture Control Register */ +#define LPC11_TMR_CR0_OFFSET 0x002c /* Capture Register 0 */ +#define LPC11_TMR_CR1_OFFSET 0x0030 /* Capture Register 1 */ +#define LPC11_TMR_EMR_OFFSET 0x003c /* External Match Register */ +#define LPC11_TMR_CTCR_OFFSET 0x0070 /* Count Control Register */ +#define LPC11_TMR_PWMC_OFFSET 0x0074 /* PWM Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC11_TMR16B0IR (LPC11_TMR16B0_BASE+LPC11_TMR_IR_OFFSET) +#define LPC11_TMR16B0TCR (LPC11_TMR16B0_BASE+LPC11_TMR_TCR_OFFSET) +#define LPC11_TMR16B0TC (LPC11_TMR16B0_BASE+LPC11_TMR_TC_OFFSET) +#define LPC11_TMR16B0PR (LPC11_TMR16B0_BASE+LPC11_TMR_PR_OFFSET) +#define LPC11_TMR16B0PC (LPC11_TMR16B0_BASE+LPC11_TMR_PC_OFFSET) +#define LPC11_TMR16B0MCR (LPC11_TMR16B0_BASE+LPC11_TMR_MCR_OFFSET) +#define LPC11_TMR16B0MR0 (LPC11_TMR16B0_BASE+LPC11_TMR_MR0_OFFSET) +#define LPC11_TMR16B0MR1 (LPC11_TMR16B0_BASE+LPC11_TMR_MR1_OFFSET) +#define LPC11_TMR16B0MR2 (LPC11_TMR16B0_BASE+LPC11_TMR_MR2_OFFSET) +#define LPC11_TMR16B0MR3 (LPC11_TMR16B0_BASE+LPC11_TMR_MR3_OFFSET) +#define LPC11_TMR16B0CCR (LPC11_TMR16B0_BASE+LPC11_TMR_CCR_OFFSET) +#define LPC11_TMR16B0CR0 (LPC11_TMR16B0_BASE+LPC11_TMR_CR0_OFFSET) +#define LPC11_TMR16B0CR1 (LPC11_TMR16B0_BASE+LPC11_TMR_CR1_OFFSET) +#define LPC11_TMR16B0EMR (LPC11_TMR16B0_BASE+LPC11_TMR_EMR_OFFSET) +#define LPC11_TMR16B0CTCR (LPC11_TMR16B0_BASE+LPC11_TMR_CTCR_OFFSET) +#define LPC11_TMR16B0PWMC (LPC11_TMR16B0_BASE+LPC11_TMR_PWMC_OFFSET) + +#define LPC11_TMR16B1IR (LPC11_TMR16B1_BASE+LPC11_TMR_IR_OFFSET) +#define LPC11_TMR16B1TCR (LPC11_TMR16B1_BASE+LPC11_TMR_TCR_OFFSET) +#define LPC11_TMR16B1TC (LPC11_TMR16B1_BASE+LPC11_TMR_TC_OFFSET) +#define LPC11_TMR16B1PR (LPC11_TMR16B1_BASE+LPC11_TMR_PR_OFFSET) +#define LPC11_TMR16B1PC (LPC11_TMR16B1_BASE+LPC11_TMR_PC_OFFSET) +#define LPC11_TMR16B1MCR (LPC11_TMR16B1_BASE+LPC11_TMR_MCR_OFFSET) +#define LPC11_TMR16B1MR0 (LPC11_TMR16B1_BASE+LPC11_TMR_MR0_OFFSET) +#define LPC11_TMR16B1MR1 (LPC11_TMR16B1_BASE+LPC11_TMR_MR1_OFFSET) +#define LPC11_TMR16B1MR2 (LPC11_TMR16B1_BASE+LPC11_TMR_MR2_OFFSET) +#define LPC11_TMR16B1MR3 (LPC11_TMR16B1_BASE+LPC11_TMR_MR3_OFFSET) +#define LPC11_TMR16B1CCR (LPC11_TMR16B1_BASE+LPC11_TMR_CCR_OFFSET) +#define LPC11_TMR16B1CR0 (LPC11_TMR16B1_BASE+LPC11_TMR_CR0_OFFSET) +#define LPC11_TMR16B1CR1 (LPC11_TMR16B1_BASE+LPC11_TMR_CR1_OFFSET) +#define LPC11_TMR16B1EMR (LPC11_TMR16B1_BASE+LPC11_TMR_EMR_OFFSET) +#define LPC11_TMR16B1CTCR (LPC11_TMR16B1_BASE+LPC11_TMR_CTCR_OFFSET) +#define LPC11_TMR16B1PWMC (LPC11_TMR16B1_BASE+LPC11_TMR_PWMC_OFFSET) + +#define LPC11_TMR32B0IR (LPC11_TMR32B0_BASE+LPC11_TMR_IR_OFFSET) +#define LPC11_TMR32B0TCR (LPC11_TMR32B0_BASE+LPC11_TMR_TCR_OFFSET) +#define LPC11_TMR32B0TC (LPC11_TMR32B0_BASE+LPC11_TMR_TC_OFFSET) +#define LPC11_TMR32B0PR (LPC11_TMR32B0_BASE+LPC11_TMR_PR_OFFSET) +#define LPC11_TMR32B0PC (LPC11_TMR32B0_BASE+LPC11_TMR_PC_OFFSET) +#define LPC11_TMR32B0MCR (LPC11_TMR32B0_BASE+LPC11_TMR_MCR_OFFSET) +#define LPC11_TMR32B0MR0 (LPC11_TMR32B0_BASE+LPC11_TMR_MR0_OFFSET) +#define LPC11_TMR32B0MR1 (LPC11_TMR32B0_BASE+LPC11_TMR_MR1_OFFSET) +#define LPC11_TMR32B0MR2 (LPC11_TMR32B0_BASE+LPC11_TMR_MR2_OFFSET) +#define LPC11_TMR32B0MR3 (LPC11_TMR32B0_BASE+LPC11_TMR_MR3_OFFSET) +#define LPC11_TMR32B0CCR (LPC11_TMR32B0_BASE+LPC11_TMR_CCR_OFFSET) +#define LPC11_TMR32B0CR0 (LPC11_TMR32B0_BASE+LPC11_TMR_CR0_OFFSET) +#define LPC11_TMR32B0CR1 (LPC11_TMR32B0_BASE+LPC11_TMR_CR1_OFFSET) +#define LPC11_TMR32B0EMR (LPC11_TMR32B0_BASE+LPC11_TMR_EMR_OFFSET) +#define LPC11_TMR32B0CTCR (LPC11_TMR32B0_BASE+LPC11_TMR_CTCR_OFFSET) +#define LPC11_TMR32B0PWMC (LPC11_TMR32B0_BASE+LPC11_TMR_PWMC_OFFSET) + +#define LPC11_TMR32B1IR (LPC11_TMR32B1_BASE+LPC11_TMR_IR_OFFSET) +#define LPC11_TMR32B1TCR (LPC11_TMR32B1_BASE+LPC11_TMR_TCR_OFFSET) +#define LPC11_TMR32B1TC (LPC11_TMR32B1_BASE+LPC11_TMR_TC_OFFSET) +#define LPC11_TMR32B1PR (LPC11_TMR32B1_BASE+LPC11_TMR_PR_OFFSET) +#define LPC11_TMR32B1PC (LPC11_TMR32B1_BASE+LPC11_TMR_PC_OFFSET) +#define LPC11_TMR32B1MCR (LPC11_TMR32B1_BASE+LPC11_TMR_MCR_OFFSET) +#define LPC11_TMR32B1MR0 (LPC11_TMR32B1_BASE+LPC11_TMR_MR0_OFFSET) +#define LPC11_TMR32B1MR1 (LPC11_TMR32B1_BASE+LPC11_TMR_MR1_OFFSET) +#define LPC11_TMR32B1MR2 (LPC11_TMR32B1_BASE+LPC11_TMR_MR2_OFFSET) +#define LPC11_TMR32B1MR3 (LPC11_TMR32B1_BASE+LPC11_TMR_MR3_OFFSET) +#define LPC11_TMR32B1CCR (LPC11_TMR32B1_BASE+LPC11_TMR_CCR_OFFSET) +#define LPC11_TMR32B1CR0 (LPC11_TMR32B1_BASE+LPC11_TMR_CR0_OFFSET) +#define LPC11_TMR32B1CR1 (LPC11_TMR32B1_BASE+LPC11_TMR_CR1_OFFSET) +#define LPC11_TMR32B1EMR (LPC11_TMR32B1_BASE+LPC11_TMR_EMR_OFFSET) +#define LPC11_TMR32B1CTCR (LPC11_TMR32B1_BASE+LPC11_TMR_CTCR_OFFSET) +#define LPC11_TMR32B1PWMC (LPC11_TMR32B1_BASE+LPC11_TMR_PWMC_OFFSET) + + +/* Register bit definitions *********************************************************/ +/* Registers holding 32-bit numeric values (no bit field definitions): + * + * Timer Counter (TC) + * Prescale Register (PR) + * Prescale Counter (PC) + * Match Register 0 (MR0) + * Match Register 1 (MR1) + * Match Register 2 (MR2) + * Match Register 3 (MR3) + * Capture Register 0 (CR0) + * Capture Register 1 (CR1) + */ + +/* Interrupt Register */ + +#define TMR_MR0INT (1 << 0) /* Bit 0: Match channel 0 interrupt */ +#define TMR_MR1INT (1 << 1) /* Bit 1: Match channel 1 interrupt */ +#define TMR_MR2INT (1 << 2) /* Bit 2: Match channel 2 interrupt */ +#define TMR_MR3INT (1 << 3) /* Bit 3: Match channel 3 interrupt */ +#define TMR_CR0INT (1 << 4) /* Bit 4: Capture channel 0 interrupt */ +#define TMR_CR1INT (1 << 5) /* Bit 5: Capture channel 1 interrupt */ + /* Bits 6-31: Reserved */ +/* Timer Control Register */ + +#define TMR_TCR_CEN (1 << 0) /* Bit 0: Counter Enable */ +#define TMR_TCR_CRST (1 << 1) /* Bit 1: Counter Reset */ + /* Bits 2-31: Reserved */ +/* Match Control Register */ + +#define TMR_MCR_MR0I (1 << 0) /* Bit 0: Interrupt on MR0 */ +#define TMR_MCR_MR0R (1 << 1) /* Bit 1: Reset on MR0 */ +#define TMR_MCR_MR0S (1 << 2) /* Bit 2: Stop on MR0 */ +#define TMR_MCR_MR1I (1 << 3) /* Bit 3: Interrupt on MR1 */ +#define TMR_MCR_MR1R (1 << 4) /* Bit 4: Reset on MR1 */ +#define TMR_MCR_MR1S (1 << 5) /* Bit 5: Stop on MR1 */ +#define TMR_MCR_MR2I (1 << 6) /* Bit 6: Interrupt on MR2 */ +#define TMR_MCR_MR2R (1 << 7) /* Bit 7: Reset on MR2 */ +#define TMR_MCR_MR2S (1 << 8) /* Bit 8: Stop on MR2 */ +#define TMR_MCR_MR3I (1 << 9) /* Bit 9: Interrupt on MR3 */ +#define TMR_MCR_MR3R (1 << 10) /* Bit 10: Reset on MR3 */ +#define TMR_MCR_MR3S (1 << 11) /* Bit 11: Stop on MR3 */ + /* Bits 12-31: Reserved */ +/* Capture Control Register */ + +#define TMR_CCR_CAP0RE (1 << 0) /* Bit 0: Capture on CAPn.0 rising edge */ +#define TMR_CCR_CAP0FE (1 << 1) /* Bit 1: Capture on CAPn.0 falling edge */ +#define TMR_CCR_CAP0I (1 << 2) /* Bit 2: Interrupt on CAPn.0 */ +#define TMR_CCR_CAP1RE (1 << 3) /* Bit 3: Capture on CAPn.1 rising edge */ +#define TMR_CCR_CAP1FE (1 << 4) /* Bit 4: Capture on CAPn.1 falling edge */ +#define TMR_CCR_CAP1I (1 << 5) /* Bit 5: Interrupt on CAPn.1 */ + /* Bits 6-31: Reserved */ +/* External Match Register */ + +#define TMR_EMR_NOTHING (0) /* Do Nothing */ +#define TMR_EMR_CLEAR (1) /* Clear external match bit MATn.m */ +#define TMR_EMR_SET (2) /* Set external match bit MATn.m */ +#define TMR_EMR_TOGGLE (3) /* Toggle external match bit MATn.m */ + +#define TMR_EMR_EM0 (1 << 0) /* Bit 0: External Match 0 */ +#define TMR_EMR_EM1 (1 << 1) /* Bit 1: External Match 1 */ +#define TMR_EMR_EM2 (1 << 2) /* Bit 2: External Match 2 */ +#define TMR_EMR_EM3 (1 << 3) /* Bit 3: External Match 3 */ +#define TMR_EMR_EMC0_SHIFT (4) /* Bits 4-5: External Match Control 0 */ +#define TMR_EMR_EMC0_MASK (3 << TMR_EMR_EMC0_SHIFTy) +# define TMR_EMR_EMC0_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_SET (TMR_EMR_SET << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC0_SHIFT) +#define TMR_EMR_EMC1_SHIFT (6) /* Bits 6-7: External Match Control 1 */ +#define TMR_EMR_EMC1_MASK (3 << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_SET (TMR_EMR_SET << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC1_SHIFT) +#define TMR_EMR_EMC2_SHIFT (8) /* Bits 8-9: External Match Control 2 */ +#define TMR_EMR_EMC2_MASK (3 << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_SET (TMR_EMR_SET << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC2_SHIFT) +#define TMR_EMR_EMC3_SHIFT (10) /* Bits 10-11: External Match Control 3 */ +#define TMR_EMR_EMC3_MASK (3 << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_SET (TMR_EMR_SET << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC3_SHIFT) + /* Bits 12-31: Reserved */ +/* Count Control Register */ + +#define TMR_CTCR_MODE_SHIFT (0) /* Bits 0-1: Counter/Timer Mode */ +#define TMR_CTCR_MODE_MASK (3 << TMR_CTCR_MODE_SHIFT) +# define TMR_CTCR_MODE_TIMER (0 << TMR_CTCR_MODE_SHIFT) /* Timer Mode, prescale match */ +# define TMR_CTCR_MODE_CNTRRE (1 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP rising edge */ +# define TMR_CTCR_MODE_CNTRFE (2 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP falling edge */ +# define TMR_CTCR_MODE_CNTRBE (3 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP both edges */ +#define TMR_CTCR_INPSEL_SHIFT (2) /* Bits 2-3: Count Input Select */ +#define TMR_CTCR_INPSEL_MASK (3 << TMR_CTCR_INPSEL_SHIFT) +# define TMR_CTCR_INPSEL_CAPNp0 (0 << TMR_CTCR_INPSEL_SHIFT) /* CAPn.0 for TIMERn */ +# define TMR_CTCR_INPSEL_CAPNp1 (1 << TMR_CTCR_INPSEL_SHIFT) /* CAPn.1 for TIMERn */ +#define TMR_CTCR_ENCC (1 << 4) /* Enable Clear Timer/Prescale when capture event happens */ +#define TMR_CTCR_SELCC_SHIFT (5) /* Bits 5-7: Selects which capture event will clear Timer/Prescale */ +#define TMR_CTCR_SELCC_MASK (3 << TMR_CTCR_SELCC_SHIFT) +# define TMR_CTCR_SELCC_RECAP0 (0 << TMR_CTCR_SELCC_SHIFT) /* Rising edge CAP0 clears timer (if bit 4 is set) */ +# define TMR_CTCR_SELCC_FECAP0 (1 << TMR_CTCR_SELCC_SHIFT) /* Falling edge CAP0 clears timer (if bit 4 is set) */ +# define TMR_CTCR_SELCC_RECAP1 (2 << TMR_CTCR_SELCC_SHIFT) /* Rising edge CAP1 clears timer (if bit 4 is set) */ +# define TMR_CTCR_SELCC_FECAP1 (3 << TMR_CTCR_SELCC_SHIFT) /* Falling edge CAP1 clears timer (if bit 4 is set) */ + /* Bits 8-31: Reserved */ + +/* PWM Control register */ + +#define TMR_PWMC_PWMEN0 (1 << 0) /* PWM channel0 enable */ +#define TMR_PWMC_PWMEN1 (1 << 1) /* PWM channel1 enable */ +#define TMR_PWMC_PWMEN2 (1 << 2) /* PWM channel2 enable */ +#define TMR_PWMC_PWMEN3 (1 << 3) /* PWM channel3 enable */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_TIMER_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_uart.h b/arch/arm/src/lpc11xx/chip/lpc11_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..7d3dffd3b24a9082570d13279eb3ad5f19832f14 --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_uart.h @@ -0,0 +1,261 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_uart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_UART_H +#define __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_UART_RBR_OFFSET 0x0000 /* (DLAB =0) Receiver Buffer Register (all) */ +#define LPC11_UART_THR_OFFSET 0x0000 /* (DLAB =0) Transmit Holding Register (all) */ +#define LPC11_UART_DLL_OFFSET 0x0000 /* (DLAB =1) Divisor Latch LSB (all) */ +#define LPC11_UART_DLM_OFFSET 0x0004 /* (DLAB =1) Divisor Latch MSB (all) */ +#define LPC11_UART_IER_OFFSET 0x0004 /* (DLAB =0) Interrupt Enable Register (all) */ +#define LPC11_UART_IIR_OFFSET 0x0008 /* Interrupt ID Register (all) */ +#define LPC11_UART_FCR_OFFSET 0x0008 /* FIFO Control Register (all) */ +#define LPC11_UART_LCR_OFFSET 0x000c /* Line Control Register (all) */ +#define LPC11_UART_MCR_OFFSET 0x0010 /* Modem Control Register (UART1 only) */ +#define LPC11_UART_LSR_OFFSET 0x0014 /* Line Status Register (all) */ +#define LPC11_UART_MSR_OFFSET 0x0018 /* Modem Status Register (UART1 only) */ +#define LPC11_UART_SCR_OFFSET 0x001c /* Scratch Pad Register (all) */ +#define LPC11_UART_ACR_OFFSET 0x0020 /* Auto-baud Control Register (all) */ +#define LPC11_UART_FDR_OFFSET 0x0028 /* Fractional Divider Register (all) */ +#define LPC11_UART_TER_OFFSET 0x0030 /* Transmit Enable Register (all) */ +#define LPC11_UART_RS485CTRL_OFFSET 0x004c /* RS-485/EIA-485 Control (UART1 only) */ +#define LPC11_UART_ADRMATCH_OFFSET 0x0050 /* RS-485/EIA-485 address match (UART1 only) */ +#define LPC11_UART_RS485DLY_OFFSET 0x0054 /* RS-485/EIA-485 direction control delay (UART1 only) */ + +/* Register addresses ***************************************************************/ + +#define LPC11_UART0_RBR (LPC11_UART0_BASE+LPC11_UART_RBR_OFFSET) +#define LPC11_UART0_THR (LPC11_UART0_BASE+LPC11_UART_THR_OFFSET) +#define LPC11_UART0_DLL (LPC11_UART0_BASE+LPC11_UART_DLL_OFFSET) +#define LPC11_UART0_DLM (LPC11_UART0_BASE+LPC11_UART_DLM_OFFSET) +#define LPC11_UART0_IER (LPC11_UART0_BASE+LPC11_UART_IER_OFFSET) +#define LPC11_UART0_IIR (LPC11_UART0_BASE+LPC11_UART_IIR_OFFSET) +#define LPC11_UART0_FCR (LPC11_UART0_BASE+LPC11_UART_FCR_OFFSET) +#define LPC11_UART0_LCR (LPC11_UART0_BASE+LPC11_UART_LCR_OFFSET) +#define LPC11_UART0_MCR (LPC11_UART0_BASE+LPC11_UART_MCR_OFFSET) +#define LPC11_UART0_LSR (LPC11_UART0_BASE+LPC11_UART_LSR_OFFSET) +#define LPC11_UART0_SCR (LPC11_UART0_BASE+LPC11_UART_SCR_OFFSET) +#define LPC11_UART0_ACR (LPC11_UART0_BASE+LPC11_UART_ACR_OFFSET) +#define LPC11_UART0_ICR (LPC11_UART0_BASE+LPC11_UART_ICR_OFFSET) +#define LPC11_UART0_FDR (LPC11_UART0_BASE+LPC11_UART_FDR_OFFSET) +#define LPC11_UART0_TER (LPC11_UART0_BASE+LPC11_UART_TER_OFFSET) +#define LPC11_UART0_RS485CTRL (LPC11_UART0_BASE+LPC11_UART_RS485CTRL_OFFSET) +#define LPC11_UART0_ADRMATCH (LPC11_UART0_BASE+LPC11_UART_ADRMATCH_OFFSET) +#define LPC11_UART0_RS485DLY (LPC11_UART0_BASE+LPC11_UART_RS485DLY_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* RBR (DLAB =0) Receiver Buffer Register (all) */ + +#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */ + /* Bits 8-31: Reserved */ + +/* THR (DLAB =0) Transmit Holding Register (all) */ + +#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */ + /* Bits 8-31: Reserved */ + +/* DLL (DLAB =1) Divisor Latch LSB (all) */ + +#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */ + /* Bits 8-31: Reserved */ + +/* DLM (DLAB =1) Divisor Latch MSB (all) */ + +#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */ + /* Bits 8-31: Reserved */ + +/* IER (DLAB =0) Interrupt Enable Register (all) */ + +#define UART_IER_RBRIE (1 << 0) /* Bit 0: RBR Interrupt Enable */ +#define UART_IER_THREIE (1 << 1) /* Bit 1: THRE Interrupt Enable */ +#define UART_IER_RXLIE (1 << 2) /* Bit 2: RX Line Interrupt Enable */ + /* Bits 3-7: Reserved */ +#define UART_IER_ABEOINTEN (1 << 8) /* Bit 8: Enables the end of auto-baud interrupt */ +#define UART_IER_ABTOINTEN (1 << 9) /* Bit 9: Enables the auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +#define UART_IER_ALLIE (0x038f) + +/* IIR Interrupt ID Register (all) */ + +#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */ +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Interrupt */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THRE Interrupt */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* 2a - Receive Data Available (RDA) */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* 1 - Receive Line Status (RLS) */ +# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* 2b - Character Time-out Indicator (CTI) */ + /* Bits 4-5: Reserved */ +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: Copies of FCR bit 0 */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) +#define UART_IIR_ABEOINT (1 << 8) /* Bit 8: End of auto-baud interrupt */ +#define UART_IIR_ABTOINT (1 << 9) /* Bit 9: Auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +/* FCR FIFO Control Register (all) */ + +#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */ +#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */ + /* Bits 3-5: Reserved */ +#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */ +#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT) +# define UART_FCR_RXTRIGGER_0 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 character) */ +# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 characters) */ +# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 characters) */ +# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 characters) */ + /* Bits 8-31: Reserved */ +/* LCR Line Control Register (all) */ + +#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_STOP (1 << 2) /* Bit 2: Stop Bit Select */ +#define UART_LCR_PE (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_PS_SHIFT (4) /* Bits 4-5: Parity Select */ +#define UART_LCR_PS_MASK (3 << UART_LCR_PS_SHIFT) +# define UART_LCR_PS_ODD (0 << UART_LCR_PS_SHIFT) /* Odd parity */ +# define UART_LCR_PS_EVEN (1 << UART_LCR_PS_SHIFT) /* Even Parity */ +# define UART_LCR_PS_STICK1 (2 << UART_LCR_PS_SHIFT) /* Forced "1" stick parity */ +# define UART_LCR_PS_STICK0 (3 << UART_LCR_PS_SHIFT) /* Forced "0" stick parity */ +#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */ + /* Bits 8-31: Reserved */ +/* MCR Modem Control Register (UART1 only) */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */ + /* Bits 2-3: Reserved */ +#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */ + /* Bit 5: Reserved */ +#define UART_MCR_RTSEN (1 << 6) /* Bit 6: Enable auto-rts flow control */ +#define UART_MCR_CTSEN (1 << 7) /* Bit 7: Enable auto-cts flow control */ + /* Bits 8-31: Reserved */ +/* LSR Line Status Register (all) */ + +#define UART_LSR_RDR (1 << 0) /* Bit 0: Receiver Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */ + /* Bits 8-31: Reserved */ +/* MSR Modem Status Register (UART1 only) */ + +#define UART_MSR_DELTACTS (1 << 0) /* Bit 0: CTS state change */ +#define UART_MSR_DELTADSR (1 << 1) /* Bit 1: DSR state change */ +#define UART_MSR_RIEDGE (1 << 2) /* Bit 2: RI ow to high transition */ +#define UART_MSR_DELTADCD (1 << 3) /* Bit 3: DCD state change */ +#define UART_MSR_CTS (1 << 4) /* Bit 4: CTS State */ +#define UART_MSR_DSR (1 << 5) /* Bit 5: DSR State */ +#define UART_MSR_RI (1 << 6) /* Bit 6: Ring Indicator State */ +#define UART_MSR_DCD (1 << 7) /* Bit 7: Data Carrier Detect State */ + /* Bits 8-31: Reserved */ +/* SCR Scratch Pad Register (all) */ + +#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */ + /* Bits 8-31: Reserved */ +/* ACR Auto-baud Control Register (all) */ + +#define UART_ACR_START (1 << 0) /* Bit 0: Auto-baud start/running*/ +#define UART_ACR_MODE (1 << 1) /* Bit 1: Auto-baud mode select*/ +#define UART_ACR_AUTORESTART (1 << 2) /* Bit 2: Restart in case of time-out*/ + /* Bits 3-7: Reserved */ +#define UART_ACR_ABEOINTCLR (1 << 8) /* Bit 8: End of auto-baud interrupt clear */ +#define UART_ACR_ABTOINTCLRT (1 << 9) /* Bit 9: Auto-baud time-out interrupt clear */ + /* Bits 10-31: Reserved */ + +/* FDR Fractional Divider Register (all) */ + +#define UART_FDR_DIVADDVAL_SHIFT (0) /* Bits 0-3: Baud-rate generation pre-scaler divisor value */ +#define UART_FDR_DIVADDVAL_MASK (15 << UART_FDR_DIVADDVAL_SHIFT) +#define UART_FDR_MULVAL_SHIFT (4) /* Bits 4-7 Baud-rate pre-scaler multiplier value */ +#define UART_FDR_MULVAL_MASK (15 << UART_FDR_MULVAL_SHIFT) + /* Bits 8-31: Reserved */ +/* TER Transmit Enable Register (all) */ + /* Bits 0-6: Reserved */ +#define UART_TER_TXEN (1 << 7) /* Bit 7: TX Enable */ + /* Bits 8-31: Reserved */ +/* RS-485/EIA-485 Control */ + +#define UART_RS485CTRL_NMMEN (1 << 0) /* Bit 0: RS-485/EIA-485 Normal Multidrop Mode (NMM) enabled */ +#define UART_RS485CTRL_RXDIS (1 << 1) /* Bit 1: Receiver is disabled */ +#define UART_RS485CTRL_AADEN (1 << 2) /* Bit 2: Auto Address Detect (AAD) is enabled */ +#define UART_RS485CTRL_SEL (1 << 3) /* Bit 3: RTS/DTR used for direction control (DCTRL=1) */ +#define UART_RS485CTRL_DCTRL (1 << 4) /* Bit 4: Enable Auto Direction Control */ +#define UART_RS485CTRL_OINV (1 << 5) /* Bit 5: Polarity of the direction control signal on RTS/DTR */ + /* Bits 6-31: Reserved */ +/* RS-485/EIA-485 address match */ + +#define UART_ADRMATCH_MASK (0xff) /* Bits 0-7: Address match value */ + /* Bits 8-31: Reserved */ +/* RS-485/EIA-485 direction control delay (UART1 only) */ + +#define UART_RS485DLY_MASK (0xff) /* Bits 0-7: Direction control (RTS/DTR) delay */ + /* Bits 8-31: Reserved */ +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_CHIP_LPC11_UART_H */ diff --git a/arch/arm/src/lpc11xx/chip/lpc11_wdt.h b/arch/arm/src/lpc11xx/chip/lpc11_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..e17eb48048dc0251061c6c557986339f2282a58d --- /dev/null +++ b/arch/arm/src/lpc11xx/chip/lpc11_wdt.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/chip/lpc11_wdt.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc11_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC11_WDT_MOD_OFFSET 0x0000 /* Watchdog mode register */ +#define LPC11_WDT_TC_OFFSET 0x0004 /* Watchdog timer constant register */ +#define LPC11_WDT_FEED_OFFSET 0x0008 /* Watchdog feed sequence register */ +#define LPC11_WDT_TV_OFFSET 0x000c /* Watchdog timer value register */ + +/* Register addresses ***************************************************************/ + +#define LPC11_WDT_MOD (LPC11_WDT_BASE+LPC11_WDT_MOD_OFFSET) +#define LPC11_WDT_TC (LPC11_WDT_BASE+LPC11_WDT_TC_OFFSET) +#define LPC11_WDT_FEED (LPC11_WDT_BASE+LPC11_WDT_FEED_OFFSET) +#define LPC11_WDT_TV (LPC11_WDT_BASE+LPC11_WDT_TV_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Watchdog mode register */ + +#define WDT_MOD_WDEN (1 << 0) /* Bit 0: Watchdog enable */ +#define WDT_MOD_WDRESET (1 << 1) /* Bit 1: Watchdog reset enable */ +#define WDT_MOD_WDTOF (1 << 2) /* Bit 2: Watchdog time-out */ +#define WDT_MOD_WDINT (1 << 3) /* Bit 3: Watchdog interrupt */ + /* Bits 4-31: Reserved */ +/* Watchdog timer constant register */ + +#define WDT_TC (0x00ffffff) /* Bits 0-23: Watchdog time-out interval */ + /* Bits 24-31: Reserved */ + +/* Watchdog feed sequence register */ + +#define WDT_FEED_MASK (0xff) /* Bits 0-7: Feed value should be 0xaa + * followed by 0x55 */ + /* Bits 14-31: Reserved */ +/* Watchdog timer value register */ + +#define WDT_TV (0x00ffffff) /* Bits 0-23: Watchdog timer value */ + /* Bits 24-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H */ diff --git a/arch/arm/src/lpc11xx/lpc111x_gpio.c b/arch/arm/src/lpc11xx/lpc111x_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..6a0718e11d7c176a2a1e08736acf3d4d15746052 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc111x_gpio.c @@ -0,0 +1,725 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc111x_gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/lpc111x_iocon.h" +#include "lpc11_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Default input pin configuration */ + +#define DEFAULT_INPUT (GPIO_INPUT|GPIO_PULLUP) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* These tables have global scope because they are also used in + * lpc11_gpiodbg.c + */ + +/* We have to remember the configured interrupt setting.. PINs are not + * actually set up to interrupt until the interrupt is enabled. + */ + +#ifdef CONFIG_GPIO_IRQ +uint64_t g_intedge0; +uint64_t g_intedge2; +#endif + +/* GPIO register base addresses */ + +const uint32_t g_gpiobase[GPIO_NPORTS] = +{ + LPC11_GPIO0_BASE, + LPC11_GPIO1_BASE, + LPC11_GPIO2_BASE, + LPC11_GPIO3_BASE +}; + +/* Port 0 and Port 2 can provide a single interrupt for any combination of + * port pins + */ + +const uint32_t g_intbase[GPIO_NPORTS] = +{ +}; + +/* Note: The IOCON offset is not linear. See User manual UM10398 Page 74 */ +/* Note: The IOCON base is not linear. See User manual UM10398 Page 74 */ + +const uint8_t iocon_port0[IOCON_NPINS] = +{ + LPC11_IOCON_P0_0_OFFSET, + LPC11_IOCON_P0_1_OFFSET, + LPC11_IOCON_P0_2_OFFSET, + LPC11_IOCON_P0_3_OFFSET, + LPC11_IOCON_P0_4_OFFSET, + LPC11_IOCON_P0_5_OFFSET, + LPC11_IOCON_P0_6_OFFSET, + LPC11_IOCON_P0_7_OFFSET, + LPC11_IOCON_P0_8_OFFSET, + LPC11_IOCON_P0_9_OFFSET, + LPC11_IOCON_P0_10_OFFSET, + LPC11_IOCON_P0_11_OFFSET +}; + +const uint8_t iocon_port1[IOCON_NPINS] = +{ + LPC11_IOCON_P1_0_OFFSET, + LPC11_IOCON_P1_1_OFFSET, + LPC11_IOCON_P1_2_OFFSET, + LPC11_IOCON_P1_3_OFFSET, + LPC11_IOCON_P1_4_OFFSET, + LPC11_IOCON_P1_5_OFFSET, + LPC11_IOCON_P1_6_OFFSET, + LPC11_IOCON_P1_7_OFFSET, + LPC11_IOCON_P1_8_OFFSET, + LPC11_IOCON_P1_9_OFFSET, + LPC11_IOCON_P1_10_OFFSET, + LPC11_IOCON_P1_11_OFFSET +}; + +const uint8_t iocon_port2[IOCON_NPINS] = +{ + LPC11_IOCON_P2_0_OFFSET, + LPC11_IOCON_P2_1_OFFSET, + LPC11_IOCON_P2_2_OFFSET, + LPC11_IOCON_P2_3_OFFSET, + LPC11_IOCON_P2_4_OFFSET, + LPC11_IOCON_P2_5_OFFSET, + LPC11_IOCON_P2_6_OFFSET, + LPC11_IOCON_P2_7_OFFSET, + LPC11_IOCON_P2_8_OFFSET, + LPC11_IOCON_P2_9_OFFSET, + LPC11_IOCON_P2_10_OFFSET, + LPC11_IOCON_P2_11_OFFSET +}; + +/* There is only IOCON_P3_[0-5] */ +const uint8_t iocon_port3[IOCON_NPINS - 6] = +{ + LPC11_IOCON_P3_0_OFFSET, + LPC11_IOCON_P3_1_OFFSET, + LPC11_IOCON_P3_2_OFFSET, + LPC11_IOCON_P3_3_OFFSET, + LPC11_IOCON_P3_4_OFFSET, + LPC11_IOCON_P3_5_OFFSET +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_pinfunc + * + * Description: + * Set the PIN function in the IOCON register. + * + ****************************************************************************/ + +static int lpc11_pinfunc(unsigned int port, unsigned int pin, + unsigned int value) +{ + const uint8_t *table = NULL; + uint32_t regaddr; + uint32_t regval; + + switch (port) + { + case 0: + table = iocon_port0; + break; + case 1: + table = iocon_port1; + break; + case 2: + table = iocon_port2; + break; + case 3: + table = iocon_port3; + break; + } + + regaddr = LPC11_IOCON_BASE + table[pin]; + if (regaddr != 0) + { + /* Set the requested value in the IOCON register */ + + regval = getreg32(regaddr); + regval &= ~(IOCON_FUNC_MASK); + regval |= (value << IOCON_FUNC_SHIFT); + putreg32(regval, regaddr); + return OK; + + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc11_pullup + * + * Description: + * Get the address of the PINMODE register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +static int lpc11_pullup(lpc11_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + const uint8_t *table = NULL; + uint32_t regaddr; + uint32_t regval; + uint32_t value; + + switch (cfgset & GPIO_PUMODE_MASK) + { + default: + case GPIO_PULLUP: /* Pull-up resistor enabled */ + value = IOCON_MODE_PU; + break; + + case GPIO_REPEATER: /* Repeater mode enabled */ + value = IOCON_MODE_RM; + break; + + case GPIO_FLOAT: /* Neither pull-up nor -down */ + value = IOCON_MODE_FLOAT; + break; + + case GPIO_PULLDN: /* Pull-down resistor enabled */ + value = IOCON_MODE_PD; + break; + } + + switch (port) + { + case 0: + table = iocon_port0; + break; + case 1: + table = iocon_port1; + break; + case 2: + table = iocon_port2; + break; + case 3: + table = iocon_port3; + break; + } + + + /* Fetch the IOCON register address for this port/pin combination */ + + regaddr = LPC11_IOCON_BASE + table[pin]; + if (regaddr != 0) + { + /* Set the requested value in the IOCON register */ + + regval = getreg32(regaddr); + regval &= ~(IOCON_MODE_MASK); + regval |= (value << IOCON_MODE_SHIFT); + putreg32(regval, regaddr); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc11_setintedge + * + * Description: + * Remember the configured interrupt edge. We can't actually enable the + * the edge interrupts until the called calls IRQ enabled function. + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +static void lpc11_setintedge(unsigned int port, unsigned int pin, + unsigned int value) +{ + uint64_t *intedge; + unsigned int shift; + + /* Which word to we use? */ + + if (port == 0) + { + intedge = &g_intedge0; + } + else if (port == 2) + { + intedge = &g_intedge2; + } + else + { + return; + } + + /* Set the requested value in the IOCON register */ + + shift = pin << 1; + *intedge &= ~((uint64_t)3 << shift); + *intedge |= ((uint64_t)value << shift); +} +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Name: lpc11_setopendrain + * + * Description: + * Set the ODMODE register for open drain mode + * + ****************************************************************************/ + +static void lpc11_setopendrain(unsigned int port, unsigned int pin) +{ + const uint8_t *table = NULL; + uint32_t regaddr; + uint32_t regval; + + switch (port) + { + case 0: + table = iocon_port0; + break; + case 1: + table = iocon_port1; + break; + case 2: + table = iocon_port2; + break; + case 3: + table = iocon_port3; + break; + } + + regaddr = LPC11_IOCON_BASE + table[pin]; + if (regaddr != 0) + { + /* Set the requested value in the IOCON register */ + + regval = getreg32(regaddr); + regval &= ~(IOCON_OD_MASK); + regval |= (1 << IOCON_OD_SHIFT); + putreg32(regval, regaddr); + } +} + +/**************************************************************************** + * Name: lpc11_clropendrain + * + * Description: + * Reset the ODMODE register to disable open drain mode + * + ****************************************************************************/ + +static void lpc11_clropendrain(unsigned int port, unsigned int pin) +{ + const uint8_t *table = NULL; + uint32_t regaddr; + uint32_t regval; + + switch (port) + { + case 0: + table = iocon_port0; + break; + case 1: + table = iocon_port1; + break; + case 2: + table = iocon_port2; + break; + case 3: + table = iocon_port3; + break; + } + + regaddr = LPC11_IOCON_BASE + table[pin]; + if (regaddr != 0) + { + /* Set the requested value in the IOCON register */ + + regval = getreg32(regaddr); + regval &= ~(1 << IOCON_OD_SHIFT); + putreg32(regval, regaddr); + } +} + +/**************************************************************************** + * Name: lpc11_configinput + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc11_configinput(lpc11_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regval; + uint32_t gpiobase; + uint32_t intbase; + uint32_t pinmask = (1 << pin); + + /* Set up GPIO registers */ + + gpiobase = g_gpiobase[port]; + + /* Set as input */ + + regval = getreg32(gpiobase + LPC11_GPIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, gpiobase + LPC11_GPIO_DIR_OFFSET); + + /* Set up interrupt registers */ + + intbase = g_intbase[port]; + if (intbase != 0) + { + /* Disable any rising edge interrupts */ + + regval = getreg32(intbase + LPC11_GPIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC11_GPIO_DIR_OFFSET); + + /* Disable any falling edge interrupts */ + + regval = getreg32(intbase + LPC11_GPIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC11_GPIO_DIR_OFFSET); + + /* Forget about any falling/rising edge interrupt enabled */ + +#ifdef CONFIG_GPIO_IRQ + lpc11_setintedge(port, pin, 0); +#endif + } + + /* Set up IOCON registers */ + /* Configure as GPIO */ + + lpc11_pinfunc(port, pin, IOCON_FUNC_GPIO); + + /* Set pull-up mode */ + + lpc11_pullup(cfgset, port, pin); + + /* Open drain only applies to outputs */ + + lpc11_clropendrain(port, pin); + + return OK; +} + +/**************************************************************************** + * Name: lpc11_configinterrupt + * + * Description: + * Configure a GPIO interrupt pin based on bit-encoded description of the + * pin. + * + ****************************************************************************/ + +static inline int lpc11_configinterrupt(lpc11_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc11_configinput(cfgset, port, pin); + + /* Then just remember the rising/falling edge interrupt enabled */ + + DEBUGASSERT(port == 0 || port == 2); +#ifdef CONFIG_GPIO_IRQ + lpc11_setintedge(port, pin, (cfgset & GPIO_EDGE_MASK) >> GPIO_EDGE_SHIFT); +#endif + return OK; +} + +/**************************************************************************** + * Name: lpc11_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc11_configoutput(lpc11_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t gpiobase; + uint32_t regval; + + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc11_configinput(DEFAULT_INPUT, port, pin); + + /* Now, reconfigure the pin as an output */ + + gpiobase = g_gpiobase[port]; + regval = getreg32(gpiobase + LPC11_GPIO_DIR_OFFSET); + regval |= (1 << pin); + putreg32(regval, gpiobase + LPC11_GPIO_DIR_OFFSET); + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Set pull-up mode. This normally only applies to input pins, but does have + * meaning if the port is an open drain output. + */ + + lpc11_pullup(cfgset, port, pin); + + /* Select open drain output */ + + lpc11_setopendrain(port, pin); + } + + /* Set the initial value of the output */ + + lpc11_gpiowrite(cfgset, ((cfgset & GPIO_VALUE) != GPIO_VALUE_ZERO)); + + return OK; +} + +/**************************************************************************** + * Name: lpc11_configalternate + * + * Description: + * Configure a GPIO alternate function pin based on bit-encoded description + * of the pin. + * + ****************************************************************************/ + +static int lpc11_configalternate(lpc11_pinset_t cfgset, unsigned int port, + unsigned int pin, uint32_t alt) +{ + /* First, configure the port as an input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc11_configinput(DEFAULT_INPUT, port, pin); + + /* Set up IOCON registers */ + /* Configure as GPIO */ + + lpc11_pinfunc(port, pin, alt); + + /* Set pull-up mode */ + + lpc11_pullup(cfgset, port, pin); + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Select open drain output */ + + lpc11_setopendrain(port, pin); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int lpc11_configgpio(lpc11_pinset_t cfgset) +{ + unsigned int port; + unsigned int pin; + int ret = -EINVAL; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the pin number and select the port configuration register for + * that pin. + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Handle according to pin function */ + + switch (cfgset & GPIO_FUNC_MASK) + { + case GPIO_INPUT: /* GPIO input pin */ + ret = lpc11_configinput(cfgset, port, pin); + break; + + case GPIO_INTFE: /* GPIO interrupt falling edge */ + case GPIO_INTRE: /* GPIO interrupt rising edge */ + case GPIO_INTBOTH: /* GPIO interrupt both edges */ + ret = lpc11_configinterrupt(cfgset, port, pin); + break; + + case GPIO_OUTPUT: /* GPIO outpout pin */ + ret = lpc11_configoutput(cfgset, port, pin); + break; + + case GPIO_ALT1: /* Alternate function 1 */ + ret = lpc11_configalternate(cfgset, port, pin, IOCON_FUNC_ALT1); + break; + + case GPIO_ALT2: /* Alternate function 2 */ + ret = lpc11_configalternate(cfgset, port, pin, IOCON_FUNC_ALT2); + break; + + case GPIO_ALT3: /* Alternate function 3 */ + ret = lpc11_configalternate(cfgset, port, pin, IOCON_FUNC_ALT3); + break; + + default: + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: lpc11_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void lpc11_gpiowrite(lpc11_pinset_t pinset, bool value) +{ + uint32_t gpiobase; + uint32_t offset; + uint32_t regval; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + gpiobase = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + offset = LPC11_GPIO_DATA_OFFSET; + + regval = getreg32(gpiobase + offset); + regval &= ~(1 << pin); + regval |= (value << pin); + putreg32(regval, gpiobase + offset); + } +} + +/**************************************************************************** + * Name: lpc11_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool lpc11_gpioread(lpc11_pinset_t pinset) +{ + uint32_t gpiobase; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + gpiobase = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(gpiobase + LPC11_GPIO_DATA_OFFSET) & (1 << pin)) != 0); + } + + return false; +} diff --git a/arch/arm/src/lpc11xx/lpc111x_gpio.h b/arch/arm/src/lpc11xx/lpc111x_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..aec89ce4f73c559063ded4d7db90d8ba1f0615d6 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc111x_gpio.h @@ -0,0 +1,178 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc111x_gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC111X_GPIO_H +#define __ARCH_ARM_SRC_LPC11XX_LPC111X_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Bit-encoded input to lpc11_configgpio() ******************************************/ + +/* Encoding: FFFF xxMM OVPP NNNN + * + * Pin Function: FFF + * Pin Mode bits: MM + * Open drain: O (output pins) + * Initial value: V (output pins) + * Port number: PP (0-3) + * Pin number: NNNN (0-11) + */ + +/* Pin Function bits: FFF + * Only meaningful when the GPIO function is GPIO_PIN + */ + +#define GPIO_FUNC_SHIFT (12) /* Bits 12-15: GPIO mode */ +#define GPIO_FUNC_MASK (15 << GPIO_FUNC_SHIFT) +# define GPIO_INPUT (0 << GPIO_FUNC_SHIFT) /* 0000 GPIO input pin */ +# define GPIO_INTFE (1 << GPIO_FUNC_SHIFT) /* 0001 GPIO interrupt falling edge */ +# define GPIO_INTRE (2 << GPIO_FUNC_SHIFT) /* 0010 GPIO interrupt rising edge */ +# define GPIO_INTBOTH (3 << GPIO_FUNC_SHIFT) /* 0011 GPIO interrupt both edges */ +# define GPIO_OUTPUT (4 << GPIO_FUNC_SHIFT) /* 0100 GPIO output pin */ +# define GPIO_ALT_GPIO (5 << GPIO_FUNC_SHIFT) /* 0101 Alternate function is a GPIO */ +# define GPIO_ALT0 (5 << GPIO_FUNC_SHIFT) /* 1000 Alternate function 0 */ +# define GPIO_ALT1 (5 << GPIO_FUNC_SHIFT) /* 1001 Alternate function 1 */ +# define GPIO_ALT2 (6 << GPIO_FUNC_SHIFT) /* 1010 Alternate function 2 */ +# define GPIO_ALT3 (7 << GPIO_FUNC_SHIFT) /* 1011 Alternate function 3 */ + +#define GPIO_EDGE_SHIFT (13) /* Bits 13-14: Interrupt edge bits */ +#define GPIO_EDGE_MASK (3 << GPIO_EDGE_SHIFT) + +#define GPIO_INOUT_MASK GPIO_OUTPUT +#define GPIO_FE_MASK GPIO_INTFE +#define GPIO_RE_MASK GPIO_INTRE + +#define GPIO_ISGPIO(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) < GPIO_ALT0) +#define GPIO_ISALT(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) >= GPIO_ALT0) +#define GPIO_ISINPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_INPUT) +#define GPIO_ISOUTPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_OUTPUT) +#define GPIO_ISINORINT(ps) (((ps) & GPIO_INOUT_MASK) == 0) +#define GPIO_ISOUTORALT(ps) (((ps) & GPIO_INOUT_MASK) != 0) +#define GPIO_ISINTERRUPT(ps) (GPIO_ISOUTPUT(ps) && !GPIO_ISINPUT(ps)) +#define GPIO_ISFE(ps) (((ps) & GPIO_FE_MASK) != 0) +#define GPIO_ISRE(ps) (((ps) & GPIO_RE_MASK) != 0) + +/* Pin Mode: MM */ + +#define GPIO_PUMODE_SHIFT (8) /* Bits 8-9: Pin pull-up mode */ +#define GPIO_PUMODE_MASK (3 << GPIO_PUMODE_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUMODE_SHIFT) /* Neither pull-up nor -down */ +# define GPIO_PULLDN (1 << GPIO_PUMODE_SHIFT) /* Pull-down resistor enabled */ +# define GPIO_PULLUP (2 << GPIO_PUMODE_SHIFT) /* Pull-up resistor enabled */ +# define GPIO_REPEATER (3 << GPIO_PUMODE_SHIFT) /* Repeater mode enabled */ + +/* Open drain: O */ + +#define GPIO_OPEN_DRAIN (1 << 7) /* Bit 7: Open drain mode */ + +/* Initial value: V */ + +#define GPIO_VALUE (1 << 6) /* Bit 6: Initial GPIO output value */ +#define GPIO_VALUE_ONE GPIO_VALUE +#define GPIO_VALUE_ZERO (0) + +/* Port number: PP (0-3) */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-5: Port number */ +#define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT0 (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT1 (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT2 (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT3 (3 << GPIO_PORT_SHIFT) + +#define GPIO_NPORTS 4 + +/* Pin number: NNNN (0-11) */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-11 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef uint16_t lpc11_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* These tables have global scope only because they are shared between lpc11_gpio.c, + * lpc11_gpioint.c, and lpc11_gpiodbg.c + */ + +EXTERN const uint32_t g_lopinsel[GPIO_NPORTS]; +EXTERN const uint32_t g_hipinsel[GPIO_NPORTS]; +EXTERN const uint32_t g_lopinmode[GPIO_NPORTS]; +EXTERN const uint32_t g_hipinmode[GPIO_NPORTS]; +EXTERN const uint32_t g_odmode[GPIO_NPORTS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC111X_GPIO_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_clockconfig.c b/arch/arm/src/lpc11xx/lpc11_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..804b6d29610f838abdcf3b33d77ae2261c8e170f --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_clockconfig.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_clockconfig.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "lpc11_clockconfig.h" +#include "chip/lpc11_syscon.h" +#include "chip/lpc111x_iocon.h" +#include "chip/lpc11_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_clockconfig + * + * Description: + * Called to initialize the LPC11xx. This does whatever setup is needed + * to put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void lpc11_clockconfig(void) +{ + int regval; + + /* Enable the main oscillator (or not) and the frequency range of the main + * oscillator. + */ + +#ifdef CONFIG_LPC11_INTRCOSC + regval = SYSCON_SYSPLLCLKSEL_IRCOSC; +#else + regval = SYSCON_SYSPLLCLKSEL_SYSOSC; +#endif + putreg32(regval, LPC11_SYSCON_SYSPLLCLKSEL); + + /* MSEL = 3 , PSEL = 1 */ + + putreg32((SYSCON_SYSPLLCTRL_MSEL_DIV(4) | SYSCON_SYSPLLCTRL_PSEL_DIV2), + LPC11_SYSCON_SYSPLLCTRL); + + /* Power UP the PLL */ + + regval = getreg32(LPC11_SYSCON_PDRUNCFG); + regval &= ~(SYSCON_PDRUNCFG_SYSPLL_PD); + putreg32(regval, LPC11_SYSCON_PDRUNCFG); + + /* Inform the core to use PLL as clock */ + + putreg32(SYSCON_MAINCLKSEL_PLLOSC, LPC11_SYSCON_SYSPLLCLKUEN); + + /* Use PLL as main clock */ + + putreg32(SYSCON_MAINCLKSEL_SYSPLLCLKOUT, LPC11_SYSCON_MAINCLKSEL); + + /* Inform the core of clock update */ + + putreg32(SYSCON_MAINCLKUEN_ENA, LPC11_SYSCON_MAINCLKUEN); +} diff --git a/arch/arm/src/lpc11xx/lpc11_clockconfig.h b/arch/arm/src/lpc11xx/lpc11_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..ebec697945a06fbed08877b4b27f887a5b050258 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_clockconfig.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_clockconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc11_clockconfig + * + * Description: + * Called to initialize the LPC11XX. This does whatever setup is needed to put the + * MCU in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void lpc11_clockconfig(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_CLOCKCONFIG_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_gpio.c b/arch/arm/src/lpc11xx/lpc11_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..ef984351db51556a71798f6edfd79777a79e48ab --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_gpio.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct GPIO logic for + * the selected LPC17xx family. The correct file cannot be selected by the + * make system because it needs the intelligence that only exists in chip.h + * that can associate an LPC17xx part number with an LPC17xx family. + */ + +#include + +#if defined(LPC111x) +# include "lpc111x_gpio.c" +#elif defined(LPC11C) +# include "lpc11c_gpio.c" +#else +# error "Unrecognized LPC11xx family" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/lpc11xx/lpc11_gpio.h b/arch/arm/src/lpc11xx/lpc11_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..3bff062e073d7b4a1c89b0a8e3917223daaf6b5f --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_gpio.h @@ -0,0 +1,194 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_gpio.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_GPIO_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip/lpc11_gpio.h" +#include "chip/lpc11_pinconfig.h" + +/* Include the GPIO definitions for the selected LPC17xx family. */ + +#if defined(LPC111x) +# include "lpc111x_gpio.h" +#elif defined(LPC11C) +# include "lpc11c_gpio.h" +#else +# error "Unrecognized LPC11xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* These tables have global scope only because they are shared between lpc11_gpio.c, + * lpc11_gpioint.c, and lpc11_gpiodbg.c + */ + +#ifdef CONFIG_GPIO_IRQ +EXTERN uint64_t g_intedge0; +EXTERN uint64_t g_intedge2; +#endif + +EXTERN const uint32_t g_fiobase[GPIO_NPORTS]; +EXTERN const uint32_t g_intbase[GPIO_NPORTS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: lpc11_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc11_gpioirqinitialize(void); +#else +# define lpc11_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: lpc11_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int lpc11_configgpio(lpc11_pinset_t cfgset); + +/************************************************************************************ + * Name: lpc11_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void lpc11_gpiowrite(lpc11_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: lpc11_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool lpc11_gpioread(lpc11_pinset_t pinset); + +/************************************************************************************ + * Name: lpc11_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc11_gpioirqenable(int irq); +#else +# define lpc11_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: lpc11_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc11_gpioirqdisable(int irq); +#else +# define lpc11_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: lpc11_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int lpc11_dumpgpio(lpc11_pinset_t pinset, const char *msg); +#else +# define lpc11_dumpgpio(p,m) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_GPIO_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_gpiodbg.c b/arch/arm/src/lpc11xx/lpc11_gpiodbg.c new file mode 100644 index 0000000000000000000000000000000000000000..6be8d9c55fee4b6b11c0177cc31cdf6c17cf08f2 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_gpiodbg.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_gpiodbg.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc11_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#ifdef CONFIG_DEBUG_GPIO + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_pinsel + * + * Description: + * Get the address of the PINSEL register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +#ifdef LPC176x +static uint32_t lpc11_pinsel(unsigned int port, unsigned int pin) +{ + if (pin < 16) + { + return g_lopinsel[port]; + } + else + { + return g_hipinsel[port]; + } +} +#endif /* LPC176x */ + +/**************************************************************************** + * Name: lpc11_pinmode + * + * Description: + * Get the address of the PINMODE register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +#ifdef LPC176x +static uint32_t lpc11_pinmode(unsigned int port, unsigned int pin) +{ + if (pin < 16) + { + return g_lopinmode[port]; + } + else + { + return g_hipinmode[port]; + } +} +#endif /* LPC176x */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: lpc11_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int lpc11_dumpgpio(lpc11_pinset_t pinset, const char *msg) +{ + irqstate_t flags; + uint32_t base; +#if defined(LPC176x) + uint32_t pinsel; + uint32_t pinmode; +#elif defined(LPC178x) + uint32_t iocon; +#endif /* LPC176x */ + unsigned int port; + unsigned int pin; + + /* Get the base address associated with the GPIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + +#if defined(LPC176x) + pinsel = lpc11_pinsel(port, pin); + pinmode = lpc11_pinmode(port, pin); +#elif defined(LPC178x) + iocon = LPC11_IOCON_P(port, pin); +#endif /* LPC176x */ + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + lldbg("GPIO%c pin%d (pinset: %08x) -- %s\n", + port + '0', pin, pinset, msg); + +#if defined(LPC176x) + lldbg(" PINSEL[%08x]: %08x PINMODE[%08x]: %08x ODMODE[%08x]: %08x\n", + pinsel, pinsel ? getreg32(pinsel) : 0, + pinmode, pinmode ? getreg32(pinmode) : 0, + g_odmode[port], getreg32(g_odmode[port])); +#elif defined(LPC178x) + lldbg(" IOCON[%08x]: %08x\n", iocon, getreg32(iocon)); +#endif + + base = g_fiobase[port]; + lldbg(" FIODIR[%08x]: %08x FIOMASK[%08x]: %08x FIOPIN[%08x]: %08x\n", + base+LPC11_FIO_DIR_OFFSET, getreg32(base+LPC11_FIO_DIR_OFFSET), + base+LPC11_FIO_MASK_OFFSET, getreg32(base+LPC11_FIO_MASK_OFFSET), + base+LPC11_FIO_PIN_OFFSET, getreg32(base+LPC11_FIO_PIN_OFFSET)); + + base = g_intbase[port]; + lldbg(" IOINTSTATUS[%08x]: %08x INTSTATR[%08x]: %08x INSTATF[%08x]: %08x\n", + LPC11_GPIOINT_IOINTSTATUS, getreg32(LPC11_GPIOINT_IOINTSTATUS), + base+LPC11_GPIOINT_INTSTATR_OFFSET, getreg32(base+LPC11_GPIOINT_INTSTATR_OFFSET), + base+LPC11_GPIOINT_INTSTATF_OFFSET, getreg32(base+LPC11_GPIOINT_INTSTATF_OFFSET)); + lldbg(" INTENR[%08x]: %08x INTENF[%08x]: %08x\n", + base+LPC11_GPIOINT_INTENR_OFFSET, getreg32(base+LPC11_GPIOINT_INTENR_OFFSET), + base+LPC11_GPIOINT_INTENF_OFFSET, getreg32(base+LPC11_GPIOINT_INTENF_OFFSET)); + leave_critical_section(flags); + return OK; +} +#endif /* CONFIG_DEBUG_GPIO */ + diff --git a/arch/arm/src/lpc11xx/lpc11_gpioint.c b/arch/arm/src/lpc11xx/lpc11_gpioint.c new file mode 100644 index 0000000000000000000000000000000000000000..4ce6b48c9ed376f9f95b7b47fcbe1cd2a634bba7 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_gpioint.c @@ -0,0 +1,547 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_gpioint.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc11_gpio.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_getintedge + * + * Description: + * Get the stored interrupt edge configuration. + * + ****************************************************************************/ + +static unsigned int lpc11_getintedge(unsigned int port, unsigned int pin) +{ + uint64_t *intedge; + + /* Which word to we use? */ + + if (port == 0) + { + intedge = &g_intedge0; + } + else if (port == 2) + { + intedge = &g_intedge2; + } + else + { + return 0; + } + + /* Return the value for the PINSEL */ + + return (unsigned int)(((*intedge) >> (pin << 1)) & 3); +} + +/**************************************************************************** + * Name: lpc11_setintedge + * + * Description: + * Set the edge interrupt enabled bits for this pin. + * + ****************************************************************************/ + +static void lpc11_setintedge(uint32_t intbase, unsigned int pin, + unsigned int edges) +{ + irqstate_t flags; + int regval; + + /* These must be atomic */ + + flags = enter_critical_section(); + + /* Set/clear the rising edge enable bit */ + + regval = getreg32(intbase + LPC11_GPIOINT_INTENR_OFFSET); + if ((edges & 2) != 0) + { + regval |= GPIOINT(pin); + } + else + { + regval &= ~GPIOINT(pin); + } + + putreg32(regval, intbase + LPC11_GPIOINT_INTENR_OFFSET); + + /* Set/clear the falling edge enable bit */ + + regval = getreg32(intbase + LPC11_GPIOINT_INTENF_OFFSET); + if ((edges & 1) != 0) + { + regval |= GPIOINT(pin); + } + else + { + regval &= ~GPIOINT(pin); + } + + putreg32(regval, intbase + LPC11_GPIOINT_INTENF_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc11_irq2port + * + * Description: + * Given an IRQ number, return the GPIO port number (0 or 2) of the interrupt. + * + ****************************************************************************/ + +static int lpc11_irq2port(int irq) +{ + /* Set 1: + * LPC176x: 12 interrupts p0.0-p0.11 + * LPC178x: 16 interrupts p0.0-p0.15 + */ + + if (irq >= LPC11_VALID_FIRST0L && + irq < (LPC11_VALID_FIRST0L + LPC11_VALID_NIRQS0L)) + { + return 0; + } + + /* Set 2: + * LPC176x: 16 interrupts p0.15-p0.30 + * LPC178x: 16 interrupts p0.16-p0.31 + */ + + else if (irq >= LPC11_VALID_FIRST0H && + irq < (LPC11_VALID_FIRST0H + LPC11_VALID_NIRQS0H)) + { + return 0; + } + +#if defined (LPC176x) + /* Set 3: + * LPC17x: 14 interrupts p2.0-p2.13 + */ + + else if (irq >= LPC11_VALID_FIRST2 && + irq < (LPC11_VALID_FIRST2 + LPC11_VALID_NIRQS2)) + { + return 2; + } + +#elif defined (LPC178x) + /* Set 3: + * LPC18x: 16 interrupts p2.0-p2.15 + */ + + else if (irq >= LPC11_VALID_FIRST2L && + irq < (LPC11_VALID_FIRST2L + LPC11_VALID_NIRQS2L)) + { + return 2; + } + + /* Set 4: + * LPC178x: 16 interrupts p2.16-p2.31 + */ + + else if (irq >= LPC11_VALID_FIRST2H && + irq < (LPC11_VALID_FIRST2H + LPC11_VALID_NIRQS2H)) + { + return 2; + } + +#endif + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc11_irq2pin + * + * Description: + * Given an IRQ number, return the GPIO pin number (0..31) of the interrupt. + * + ****************************************************************************/ + +static int lpc11_irq2pin(int irq) +{ + /* Set 1: + * LPC17x: 12 interrupts p0.0-p0.11 + * LPC18x: 16 interrupts p0.0-p0.15 + * + * See arch/arm/include/lpc11xx/irq.h: + * LPC11_VALID_SHIFT0L 0 - Bit 0 is thre first bit in the group of + * 12/16 interrupts + * LPC11_VALID_FIRST0L irq - IRQ number associated with p0.0 + * LPC11_VALID_NIRQS0L 12/16 - Number of interrupt bits in the group + */ + + if (irq >= LPC11_VALID_FIRST0L && + irq < (LPC11_VALID_FIRST0L + LPC11_VALID_NIRQS0L)) + { + return irq - LPC11_VALID_FIRST0L + LPC11_VALID_SHIFT0L; + } + + /* Set 2: + * LPC176x: 16 interrupts p0.15-p0.30 + * LPC178x: 16 interrupts p0.16-p0.31 + * + * LPC11_VALID_SHIFT0H 15/16 - Bit number of the first bit in a group + * of 16 interrupts + * LPC11_VALID_FIRST0L irq - IRQ number associated with p0.15/16 + * LPC11_VALID_NIRQS0L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC11_VALID_FIRST0H && + irq < (LPC11_VALID_FIRST0H + LPC11_VALID_NIRQS0H)) + { + return irq - LPC11_VALID_FIRST0H + LPC11_VALID_SHIFT0H; + } + +#if defined(LPC176x) + /* Set 3: + * LPC17x: 14 interrupts p2.0-p2.13 + * + * LPC11_VALID_SHIFT2 0 - Bit 0 is the first bit in a group of 14 + * interrupts + * LPC11_VALID_FIRST2 irq - IRQ number associated with p2.0 + * LPC11_VALID_NIRQS2 14 - 14 interrupt bits in the group + */ + + else if (irq >= LPC11_VALID_FIRST2 && + irq < (LPC11_VALID_FIRST2 + LPC11_VALID_NIRQS2)) + { + return irq - LPC11_VALID_FIRST2 + LPC11_VALID_SHIFT2; + } + +#elif defined(LPC178x) + + /* Set 3: + * LPC18x: 16 interrupts p2.0-p2.15 + * + * LPC11_VALID_SHIFT2L 0 - Bit 0 is the first bit in a group of 16 + * interrupts + * LPC11_VALID_FIRST2L irq - IRQ number associated with p2.0 + * LPC11_VALID_NIRQS2L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC11_VALID_FIRST2L && + irq < (LPC11_VALID_FIRST2L + LPC11_VALID_NIRQS2L)) + { + return irq - LPC11_VALID_FIRST2L + LPC11_VALID_SHIFT2L; + } + + /* Set 3: + * LPC18x: 16 interrupts p2.16-p2.31 + * + * LPC11_VALID_SHIFT2L 16 - Bit 16 is the first bit in a group of 16 + * interrupts + * LPC11_VALID_FIRST2L irq - IRQ number associated with p2.0 + * LPC11_VALID_NIRQS2L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC11_VALID_FIRST2H && + irq < (LPC11_VALID_FIRST2H + LPC11_VALID_NIRQS2H)) + { + return irq - LPC11_VALID_FIRST2H + LPC11_VALID_SHIFT2H; + } + +#endif + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc11_gpiodemux + * + * Description: + * Demux all interrupts on one GPIO interrupt status register. + * + ****************************************************************************/ + +static void lpc11_gpiodemux(uint32_t intbase, uint32_t intmask, + int irqbase, void *context) +{ + uint32_t intstatr; + uint32_t intstatf; + uint32_t intstatus; + uint32_t bit; + int irq; + + /* Get the interrupt rising and falling edge status and mask out only the + * interrupts that are enabled. + */ + + intstatr = getreg32(intbase + LPC11_GPIOINT_INTSTATR_OFFSET); + intstatr &= getreg32(intbase + LPC11_GPIOINT_INTENR_OFFSET); + + intstatf = getreg32(intbase + LPC11_GPIOINT_INTSTATF_OFFSET); + intstatf &= getreg32(intbase + LPC11_GPIOINT_INTENF_OFFSET); + + /* And get the OR of the enabled interrupt sources. We do not make any + * distinction between rising and falling edges (but the hardware does support + * the ability to handle them differently if needed). + */ + + intstatus = intstatr | intstatf; + + /* Now march through the (valid) bits and dispatch each interrupt */ + + irq = irqbase; + bit = 1; + while (intstatus != 0) + { + /* Does this pin support an interrupt? If no, skip over it WITHOUT + * incrementing irq. + */ + + if ((intmask & bit) != 0) + { + /* This pin can support an interrupt. Is there an interrupt pending + * and enabled? + */ + + if ((intstatus & bit) != 0) + { + /* Clear the interrupt status */ + + putreg32(bit, intbase + LPC11_GPIOINT_INTCLR_OFFSET); + + /* And dispatch the interrupt */ + + irq_dispatch(irq, context); + } + + /* Increment the IRQ number on each interrupt pin */ + + irq++; + } + + /* Next bit */ + + intstatus &= ~bit; + bit <<= 1; + } +} + +/**************************************************************************** + * Name: lpc11_gpiointerrupt + * + * Description: + * Handle the GPIO interrupt. For the LPC176x family, that interrupt could + * also that also indicates that an EINT3 interrupt has occurred. NOTE: + * This logic would have to be extended if EINT3 is actually used for + * External Interrupt 3 on an LPC176x platform. + * + ****************************************************************************/ + +static int lpc11_gpiointerrupt(int irq, void *context) +{ + /* Get the GPIO interrupt status */ + + uint32_t intstatus = getreg32(LPC11_GPIOINT_IOINTSTATUS); + + /* Check for an interrupt on GPIO0 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P0INT) != 0) + { + lpc11_gpiodemux(LPC11_GPIOINT0_BASE, LPC11_VALID_GPIOINT0, + LPC11_VALID_FIRST0L, context); + } + +#if defined(LPC176x) + /* Check for an interrupt on GPIO2 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P2INT) != 0) + { + lpc11_gpiodemux(LPC11_GPIOINT2_BASE, LPC11_VALID_GPIOINT2, + LPC11_VALID_FIRST2, context); + } + +#elif defined(LPC178x) + /* Check for an interrupt on GPIO2 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P2INT) != 0) + { + lpc11_gpiodemux(LPC11_GPIOINT2_BASE, LPC11_VALID_GPIOINT2, + LPC11_VALID_FIRST2L, context); + } + +#endif + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void lpc11_gpioirqinitialize(void) +{ + /* Disable all GPIO interrupts */ + + putreg32(0, LPC11_GPIOINT0_INTENR); + putreg32(0, LPC11_GPIOINT0_INTENF); + putreg32(0, LPC11_GPIOINT2_INTENR); + putreg32(0, LPC11_GPIOINT2_INTENF); + + /* Attach and enable the GPIO IRQ. */ + +#if defined(LPC176x) + /* For the LPC176x family, GPIO0 and GPIO2 interrupts share the same + * position in the NVIC with External Interrupt 3 + */ + + (void)irq_attach(LPC11_IRQ_EINT3, lpc11_gpiointerrupt); + up_enable_irq(LPC11_IRQ_EINT3); + +#elif defined(LPC178x) + /* the LPC178x family has a single, dedicated interrupt for GPIO0 and + * GPIO2. + */ + + (void)irq_attach(LPC11_IRQ_GPIO, lpc11_gpiointerrupt); + up_enable_irq(LPC11_IRQ_GPIO); + +#endif +} + +/**************************************************************************** + * Name: lpc11_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void lpc11_gpioirqenable(int irq) +{ + /* Map the IRQ number to a port number */ + + int port = lpc11_irq2port(irq); + if (port >= 0) + { + /* The IRQ number does correspond to an interrupt port. Now get the base + * address of the GPIOINT registers for the port. + */ + + uint32_t intbase = g_intbase[port]; + if (intbase != 0) + { + /* And get the pin number associated with the port */ + + unsigned int pin = lpc11_irq2pin(irq); + unsigned int edges = lpc11_getintedge(port, pin); + lpc11_setintedge(intbase, pin, edges); + } + } +} + +/**************************************************************************** + * Name: lpc11_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void lpc11_gpioirqdisable(int irq) +{ + /* Map the IRQ number to a port number */ + + int port = lpc11_irq2port(irq); + if (port >= 0) + { + /* The IRQ number does correspond to an interrupt port. Now get the base + * address of the GPIOINT registers for the port. + */ + + uint32_t intbase = g_intbase[port]; + if (intbase != 0) + { + /* And get the pin number associated with the port */ + + unsigned int pin = lpc11_irq2pin(irq); + lpc11_setintedge(intbase, pin, 0); + } + } +} + +#endif /* CONFIG_GPIO_IRQ */ + diff --git a/arch/arm/src/lpc11xx/lpc11_i2c.c b/arch/arm/src/lpc11xx/lpc11_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..f838629fb2e50c6c217eac3f6cec0a44d4b88128 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_i2c.c @@ -0,0 +1,645 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_i2c.c + * + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi (Original author) + * + * Derived from arch/arm/src/lpc31xx/lpc31_i2c.c + * + * Author: David Hewson + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc11_syscon.h" +#include "lpc11_gpio.h" +#include "lpc11_i2c.h" + +#if defined(CONFIG_LPC11_I2C0) || defined(CONFIG_LPC11_I2C1) || defined(CONFIG_LPC11_I2C2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef GPIO_I2C1_SCL +# define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 +# define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 +#endif + +#ifndef CONFIG_LPC11_I2C0_FREQUENCY +# define CONFIG_LPC11_I2C0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC11_I2C1_FREQUENCY +# define CONFIG_LPC11_I2C1_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC11_I2C2_FREQUENCY +# define CONFIG_LPC11_I2C2_FREQUENCY 100000 +#endif + +#define I2C_TIMEOUT (20 * 1000/CONFIG_USEC_PER_TICK) /* 20 mS */ +#define LPC11_I2C1_FREQUENCY 400000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct lpc11_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* Watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* Remaining transfers - first one is in progress */ + unsigned int nmsg; /* Number of transfer remaining */ + + uint16_t wrcnt; /* Number of bytes sent to tx fifo */ + uint16_t rdcnt; /* Number of bytes read from rx fifo */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int lpc11_i2c_start(struct lpc11_i2cdev_s *priv); +static void lpc11_i2c_stop(struct lpc11_i2cdev_s *priv); +static int lpc11_i2c_interrupt(int irq, FAR void *context); +static void lpc11_i2c_timeout(int argc, uint32_t arg, ...); +static void lpc11_i2c_setfrequency(struct lpc11_i2cdev_s *priv, + uint32_t frequency); +static void lpc11_stopnext(struct lpc11_i2cdev_s *priv); + +/* I2C device operations */ + +static int lpc11_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int lpc11_i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC11_I2C0 +static struct lpc11_i2cdev_s g_i2c0dev; +#endif +#ifdef CONFIG_LPC11_I2C1 +static struct lpc11_i2cdev_s g_i2c1dev; +#endif +#ifdef CONFIG_LPC11_I2C2 +static struct lpc11_i2cdev_s g_i2c2dev; +#endif + +struct i2c_ops_s lpc11_i2c_ops = +{ + .transfer = lpc11_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = lpc11_i2c_reset +#endif +}; + +/**************************************************************************** + * Name: lpc11_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void lpc11_i2c_setfrequency(struct lpc11_i2cdev_s *priv, + uint32_t frequency) +{ + if (frequency != priv->frequency) + { + if (frequency > 100000) + { + /* Asymetric per 400Khz I2C spec */ + + putreg32(LPC11_MCLK / (83 + 47) * 47 / frequency, + priv->base + LPC11_I2C_SCLH_OFFSET); + putreg32(LPC11_MCLK / (83 + 47) * 83 / frequency, + priv->base + LPC11_I2C_SCLL_OFFSET); + } + else + { + /* 50/50 mark space ratio */ + + putreg32(LPC11_MCLK / 100 * 50 / frequency, + priv->base + LPC11_I2C_SCLH_OFFSET); + putreg32(LPC11_MCLK / 100 * 50 / frequency, + priv->base + LPC11_I2C_SCLL_OFFSET); + } + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: lpc11_i2c_start + * + * Description: + * Perform a I2C transfer start + * + ****************************************************************************/ + +static int lpc11_i2c_start(struct lpc11_i2cdev_s *priv) +{ + putreg32(I2C_CONCLR_STAC | I2C_CONCLR_SIC, + priv->base + LPC11_I2C_CONCLR_OFFSET); + putreg32(I2C_CONSET_STA, priv->base + LPC11_I2C_CONSET_OFFSET); + + wd_start(priv->timeout, I2C_TIMEOUT, lpc11_i2c_timeout, 1, (uint32_t)priv); + sem_wait(&priv->wait); + + wd_cancel(priv->timeout); + + return priv->nmsg; +} + +/**************************************************************************** + * Name: lpc11_i2c_stop + * + * Description: + * Perform a I2C transfer stop + * + ****************************************************************************/ + +static void lpc11_i2c_stop(struct lpc11_i2cdev_s *priv) +{ + if (priv->state != 0x38) + { + putreg32(I2C_CONSET_STO | I2C_CONSET_AA, + priv->base + LPC11_I2C_CONSET_OFFSET); + } + + sem_post(&priv->wait); +} + +/**************************************************************************** + * Name: lpc11_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void lpc11_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc11_i2cdev_s *priv = (struct lpc11_i2cdev_s *)arg; + + irqstate_t flags = enter_critical_section(); + priv->state = 0xff; + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc11_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int lpc11_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc11_i2cdev_s *priv = (struct lpc11_i2cdev_s *)dev; + int ret; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Set up for the transfer */ + + priv->wrcnt = 0; + priv->rdcnt = 0; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + lpc11_i2c_setfrequency(priv, msgs->frequency); + + /* Perform the transfer */ + + ret = lpc11_i2c_start(priv); + + sem_post(&priv->mutex); + return ret; +} + +/**************************************************************************** + * Name: lpc11_i2c_interrupt + * + * Description: + * Check if we need to issue STOP at the next message + * + ****************************************************************************/ + +static void lpc11_stopnext(struct lpc11_i2cdev_s *priv) +{ + priv->nmsg--; + + if (priv->nmsg > 0) + { + priv->msgs++; + putreg32(I2C_CONSET_STA, priv->base + LPC11_I2C_CONSET_OFFSET); + } + else + { + lpc11_i2c_stop(priv); + } +} + +/**************************************************************************** + * Name: lpc11_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int lpc11_i2c_interrupt(int irq, FAR void *context) +{ + struct lpc11_i2cdev_s *priv; + struct i2c_msg_s *msg; + uint32_t state; + +#ifdef CONFIG_LPC11_I2C0 + if (irq == LPC11_IRQ_I2C0) + { + priv = &g_i2c0dev; + } + else +#endif +#ifdef CONFIG_LPC11_I2C1 + if (irq == LPC11_IRQ_I2C1) + { + priv = &g_i2c1dev; + } + else +#endif +#ifdef CONFIG_LPC11_I2C2 + if (irq == LPC11_IRQ_I2C2) + { + priv = &g_i2c2dev; + } + else +#endif + { + PANIC(); + } + + /* Reference UM10360 19.10.5 */ + + state = getreg32(priv->base + LPC11_I2C_STAT_OFFSET); + msg = priv->msgs; + + priv->state = state; + state &= 0xf8; /* state mask, only 0xX8 is possible */ + switch (state) + { + + case 0x08: /* A START condition has been transmitted. */ + case 0x10: /* A Repeated START condition has been transmitted. */ + /* Set address */ + + putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ) ? + I2C_READADDR8(msg->addr) : + I2C_WRITEADDR8(msg->addr), priv->base + LPC11_I2C_DAT_OFFSET); + + /* Clear start bit */ + + putreg32(I2C_CONCLR_STAC, priv->base + LPC11_I2C_CONCLR_OFFSET); + break; + + /* Write cases */ + + case 0x18: /* SLA+W has been transmitted; ACK has been received */ + priv->wrcnt = 0; + putreg32(msg->buffer[0], priv->base + LPC11_I2C_DAT_OFFSET); /* put first byte */ + break; + + case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */ + priv->wrcnt++; + + if (priv->wrcnt < msg->length) + { + putreg32(msg->buffer[priv->wrcnt], priv->base + LPC11_I2C_DAT_OFFSET); /* Put next byte */ + } + else + { + lpc11_stopnext(priv); + } + break; + + /* Read cases */ + + case 0x40: /* SLA+R has been transmitted; ACK has been received */ + priv->rdcnt = 0; + if (msg->length > 1) + { + putreg32(I2C_CONSET_AA, priv->base + LPC11_I2C_CONSET_OFFSET); /* Set ACK next read */ + } + else + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC11_I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */ + } + break; + + case 0x50: /* Data byte has been received; ACK has been returned. */ + priv->rdcnt++; + msg->buffer[priv->rdcnt - 1] = getreg32(priv->base + LPC11_I2C_BUFR_OFFSET); + + if (priv->rdcnt >= (msg->length - 1)) + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC11_I2C_CONCLR_OFFSET); /* Do not ACK any more */ + } + break; + + case 0x58: /* Data byte has been received; NACK has been returned. */ + msg->buffer[priv->rdcnt] = getreg32(priv->base + LPC11_I2C_BUFR_OFFSET); + lpc11_stopnext(priv); + break; + + default: + lpc11_i2c_stop(priv); + break; + } + + putreg32(I2C_CONCLR_SIC, priv->base + LPC11_I2C_CONCLR_OFFSET); /* clear interrupt */ + + return OK; +} + +/************************************************************************************ + * Name: lpc11_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int lpc11_i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc11_i2cbus_initialize(int port) +{ + struct lpc11_i2cdev_s *priv; + + if (port > 1) + { + dbg("lpc I2C Only support 0,1\n"); + return NULL; + } + + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + +#ifdef CONFIG_LPC11_I2C0 + if (port == 0) + { + priv = &g_i2c0dev; + priv->base = LPC11_I2C0_BASE; + priv->irqid = LPC11_IRQ_I2C0; + + /* Enable clocking */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); + regval |= SYSCON_SYSAHBCLKCTRL_I2C0; + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + + /* Pin configuration */ + + lpc11_configgpio(GPIO_I2C0_SCL); + lpc11_configgpio(GPIO_I2C0_SDA); + + /* Set default frequency */ + + lpc11_i2c_setfrequency(priv, CONFIG_LPC11_I2C0_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC11_I2C1 + if (port == 1) + { + priv = &g_i2c1dev; + priv->base = LPC11_I2C1_BASE; + priv->irqid = LPC11_IRQ_I2C1; + + /* Enable clocking */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); + regval |= SYSCON_SYSAHBCLKCTRL_I2C1; + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + + regval = getreg32(LPC11_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_I2C1_MASK; + regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C1_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL1); + + /* Pin configuration */ + + lpc11_configgpio(GPIO_I2C1_SCL); + lpc11_configgpio(GPIO_I2C1_SDA); + + /* Set default frequency */ + + lpc11_i2c_setfrequency(priv, CONFIG_LPC11_I2C1_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC11_I2C2 + if (port == 2) + { + priv = &g_i2c2dev; + priv->base = LPC11_I2C2_BASE; + priv->irqid = LPC11_IRQ_I2C2; + + /* Enable clocking */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); + regval |= SYSCON_SYSAHBCLKCTRL_I2C2; + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + + regval = getreg32(LPC11_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_I2C2_MASK; + regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C2_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL1); + + /* Pin configuration */ + + lpc11_configgpio(GPIO_I2C2_SCL); + lpc11_configgpio(GPIO_I2C2_SDA); + + /* Set default frequency */ + + lpc11_i2c_setfrequency(priv, CONFIG_LPC11_I2C2_FREQUENCY); + } + else +#endif + { + return NULL; + } + + leave_critical_section(flags); + + putreg32(I2C_CONSET_I2EN, priv->base + LPC11_I2C_CONSET_OFFSET); + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, lpc11_i2c_interrupt); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc11_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc11_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc11_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct lpc11_i2cdev_s *priv = (struct lpc11_i2cdev_s *) dev; + + /* Disable I2C */ + + putreg32(I2C_CONCLRT_I2ENC, priv->base + LPC11_I2C_CONCLR_OFFSET); + + /* Reset data structures */ + + sem_destroy(&priv->mutex); + sem_destroy(&priv->wait); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Disable interrupts */ + + up_disable_irq(priv->irqid); + + /* Detach Interrupt Handler */ + + irq_detach(priv->irqid); + return OK; +} + +#endif /* CONFIG_LPC11_I2C0 || CONFIG_LPC11_I2C1 || CONFIG_LPC11_I2C2 */ diff --git a/arch/arm/src/lpc11xx/lpc11_i2c.h b/arch/arm/src/lpc11xx/lpc11_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..a9bc6fa3f75fd87660a3fb5d34fd84042a157ae4 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_i2c.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_i2c.h + * + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_I2C_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc11_i2c.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *lpc11_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: lpc11_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc11_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int lpc11_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_I2C_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_idle.c b/arch/arm/src/lpc11xx/lpc11_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..0a53daaca56a74302a6aa62ded02e521d972ec9d --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_idle.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/lpc11/lpc11_idle.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + +/* If the g_dma_inprogress is zero, then there is no DMA in progress. This + * value is needed in the IDLE loop to determine if the IDLE loop should + * go into lower power power consumption modes. According to the LPC17xx + * User Manual: "The DMA controller can continue to work in Sleep mode, and + * has access to the peripheral SRAMs and all peripheral registers. The + * flash memory and the Main SRAM are not available in Sleep mode, they are + * disabled in order to save power." + */ + +#ifdef CONFIG_LPC11_GPDMA + if (g_dma_inprogress == 0) +#endif + { + /* Sleep until an interrupt occurs in order to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); + } +#endif +} diff --git a/arch/arm/src/lpc11xx/lpc11_irq.c b/arch/arm/src/lpc11xx/lpc11_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..c6daaba380de3f4595ce7c7e7b304648c8746578 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_irq.c @@ -0,0 +1,340 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_irq.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" +#include "up_internal.h" + +//#include "lpc11_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | NVIC_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void lpc11_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" ISER: %08x ICER: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); + lldbg(" ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), + getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), + getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); + + lldbg("SYSCON:\n"); + lldbg(" CPUID: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID)); + lldbg(" ICSR: %08x AIRCR: %08x\n", + getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); + lldbg(" SCR: %08x CCR: %08x\n", + getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); + lldbg(" SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#else +# define lpc11_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: lpc11_nmi, lpc11_busfault, lpc11_usagefault, lpc11_pendsv, + * lpc11_dbgmonitor, lpc11_pendsv, lpc11_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int lpc11_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int lpc11_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int lpc11_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: lpc11_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. + * + ****************************************************************************/ + +static inline void lpc11_clrpend(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= LPC11_IRQ_EXTINT && irq < (LPC11_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - LPC11_IRQ_EXTINT)), ARMV6M_NVIC_ICPR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int i; + + /* Disable all interrupts */ + + putreg32(0xffffffff, ARMV6M_NVIC_ICER); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR2); + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR3); + + /* Now set all of the interrupt lines to the default priority */ + + for (i = 0; i < 8; i++) + { + regaddr = ARMV6M_NVIC_IPR(i); + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(LPC11_IRQ_SVCALL, up_svcall); + irq_attach(LPC11_IRQ_HARDFAULT, up_hardfault); + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(LPC11_IRQ_NMI, lpc11_nmi); + irq_attach(LPC11_IRQ_PENDSV, lpc11_pendsv); + irq_attach(LPC11_IRQ_RESERVED, lpc11_reserved); +#endif + + lpc11_dumpnvic("initial", NR_IRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * configured pin interrupts. + */ + +#ifdef CONFIG_GPIO_IRQ + lpc11_gpioirqinitialize(); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= LPC11_IRQ_EXTINT && irq < (LPC11_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ICER register to disable the + * interrupt + */ + + putreg32((1 << (irq - LPC11_IRQ_EXTINT)), ARMV6M_NVIC_ICER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == LPC11_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, SYSTICK_CSR_ENABLE, 0); + } + + lpc11_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enabled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= LPC11_IRQ_EXTINT && irq < (LPC11_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - LPC11_IRQ_EXTINT)), ARMV6M_NVIC_ISER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == LPC11_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, 0, SYSTICK_CSR_ENABLE); + } + + lpc11_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + lpc11_clrpend(irq); +} diff --git a/arch/arm/src/lpc11xx/lpc11_lowgetc.c b/arch/arm/src/lpc11xx/lpc11_lowgetc.c new file mode 100644 index 0000000000000000000000000000000000000000..a0a12b6108021f4ba2bf1cc1755e7d6375959985 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_lowgetc.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/arm/src/lpc11/lpc11_lowgetc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/lpc11_syscon.h" +#include "chip/lpc11_uart.h" + +#include "lpc11_gpio.h" +#include "lpc11_lowgetc.h" +#include "lpc11_serial.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC11_UART0_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC11_UART1_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC11_UART2_BASE +# define CONSOLE_FREQ BOARD_BUSCLK_FREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowgetc + * + * Description: + * Input one byte from the serial console + * + ****************************************************************************/ + +int lpc11_lowgetc(void) +{ + uint8_t ch = 0; + +#if defined HAVE_UART && defined HAVE_SERIAL_CONSOLE + /* Wait while the Receiver Data Ready (RDR) is indicating a "empty" FIFO to + * assure that we have data in the buffer to read. + */ + + while ((getreg32(CONSOLE_BASE+LPC11_UART_LSR_OFFSET) & UART_LSR_RDR) == 0); + + /* Then read a character from the UART data register */ + + ch = getreg8(CONSOLE_BASE+LPC11_UART_RBR_OFFSET); +#endif + + return (int)ch; +} diff --git a/arch/arm/src/lpc11xx/lpc11_lowgetc.h b/arch/arm/src/lpc11xx/lpc11_lowgetc.h new file mode 100644 index 0000000000000000000000000000000000000000..4c94f39b7844323d6e79196ac3a964d0f845e350 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_lowgetc.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/lpc11/lpc11_lowgetc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_LOWGETC_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_LOWGETC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "lpc11_serial.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +int lpc11_lowgetc(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_LOWGETC_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_lowputc.c b/arch/arm/src/lpc11xx/lpc11_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..dcba013127f70cf37cc6d9c5974c0ce4e9bf77f4 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_lowputc.c @@ -0,0 +1,306 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_lowputc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/lpc11_syscon.h" +#include "chip/lpc11_uart.h" + +#include "lpc11_gpio.h" +#include "lpc11_lowputc.h" +#include "lpc11_serial.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC11_UART0_BASE +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(HAVE_SERIAL_CONSOLE) +# error "No CONFIG_UART0_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS == 5 +# define CONSOLE_LCR_WLS UART_LCR_WLS_5BIT +#elif CONSOLE_BITS == 6 +# define CONSOLE_LCR_WLS UART_LCR_WLS_6BIT +#elif CONSOLE_BITS == 7 +# define CONSOLE_LCR_WLS UART_LCR_WLS_7BIT +#elif CONSOLE_BITS == 8 +# define CONSOLE_LCR_WLS UART_LCR_WLS_8BIT +#elif defined(HAVE_SERIAL_CONSOLE) +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) +#elif CONSOLE_PARITY == 3 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) +#elif CONSOLE_PARITY == 4 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) +#elif defined(HAVE_SERIAL_CONSOLE) +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and UART0-3 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP UART_LCR_STOP +#else +# define CONSOLE_LCR_STOP 0 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) +#define CONSOLE_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ + UART_FCR_RXRST | UART_FCR_FIFOEN) + +/**************************************************************************** + * This Baud Rate configuration is based on idea suggested at LPCWare: + * www.lpcware.com/content/blog/lpc17xx-uart-simpler-way-calculate-baudrate-timming + * + * The original code is for LPC17xx but with few modifications it worked + * fine in the LPC11xx as well. + * + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART && defined HAVE_SERIAL_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(CONSOLE_BASE+LPC11_UART_LSR_OFFSET) & UART_LSR_THRE) == 0); + + /* Send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE+LPC11_UART_THR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: lpc11_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + * The UART peripheral is configured using the following registers: + * 1. Pins: For the LPC111x/101/201/301 parts, the UART pins must be + * configured in the IOCONFIG register block before the UART clocks can + * be enabled in the SYSAHBCLKCTRL register. For all other parts, no + * special enabling sequence is required. + * 2. Power: In the SYSAHBCLKCTRL register, set bit 12. + * On reset, UART is disabled. + * 3. Peripheral clock: Enable the UART peripheral clock by writing to the + * UARTCLKDIV register. + * + ****************************************************************************/ + +void lpc11_lowsetup(void) +{ +#ifdef HAVE_UART + uint32_t regval; + uint32_t coreclk = LPC11_MCLK; + uint32_t rate16 = 16 * CONSOLE_BAUD; + uint32_t dval; + uint32_t mval; + uint32_t dl; + + /* Enable clock for GPIO and I/O block */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); + regval |= (SYSCON_SYSAHBCLKCTRL_GPIO | SYSCON_SYSAHBCLKCTRL_IOCON); + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + /* Step 1: Pins configuration */ + + lpc11_configgpio(GPIO_UART0_TXD); + lpc11_configgpio(GPIO_UART0_RXD); +#endif + + /* Step 2: Enable power for all console UART and disable power for + * other UARTs. + */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + regval |= SYSCON_SYSAHBCLKCTRL_UART; +#endif + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + + /* Step 3: Enable peripheral clocking for the console UART and disable + * clocking for all other UARTs + */ + + /* Don't divide the UART Clock it is be equal to Peripheral Clock */ + + putreg32(1, LPC11_SYSCON_UARTCLKDIV); + + /* Configure the console (only) */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* Clear fifos */ + + putreg32(UART_FCR_RXRST | UART_FCR_TXRST, + CONSOLE_BASE + LPC11_UART_FCR_OFFSET); + + /* Set trigger */ + + putreg32(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8, + CONSOLE_BASE + LPC11_UART_FCR_OFFSET); + + /* Set up the LCR and set DLAB=1 */ + + putreg32(CONSOLE_LCR_VALUE | UART_LCR_DLAB, + CONSOLE_BASE + LPC11_UART_LCR_OFFSET); + + /* Configure the Baud rate + * + * The fractional is calculated as + * (PCLK % (16 * Baudrate)) / (16 * Baudrate) + */ + + dval = coreclk % rate16; + + /* The PCLK / (16 * Baudrate) is fractional + * dval = pclk % rate16 + * mval = rate16 + * now normalize the ratio + * dval / mval = 1 / new_mval + * new_mval = mval / dval; + * new_dval = 1 + */ + + if (dval > 0) + { + mval = rate16 / dval; + dval = 1; + + if (mval > 12) + { + dval = 0; + } + } + + dval &= 0xf; + mval &= 0xf; + + dl = coreclk / (rate16 + rate16 * dval / mval); + + /* Set the BAUD divisor */ + + putreg32(dl & 0xff, CONSOLE_BASE + LPC11_UART_DLL_OFFSET); + putreg32(dl >> 8, CONSOLE_BASE + LPC11_UART_DLM_OFFSET); + + /* Set the BAUD fractional */ + + putreg32((mval << UART_FDR_MULVAL_SHIFT) | + (dval << UART_FDR_DIVADDVAL_SHIFT), + CONSOLE_BASE + LPC11_UART_FDR_OFFSET); + + /* Clear DLAB */ + + putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE + LPC11_UART_LCR_OFFSET); + + /* Configure the FIFOs */ + + putreg32(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN, + CONSOLE_BASE + LPC11_UART_FCR_OFFSET); +#endif +#endif /* HAVE_UART */ +} diff --git a/arch/arm/src/lpc11xx/lpc11_lowputc.h b/arch/arm/src/lpc11xx/lpc11_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..9bf68ec1151135f3998abbd7d718263a708e7557 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_lowputc.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_lowputc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_LOWPUTC_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc11_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void lpc11_lowsetup(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_LOWPUTC_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_serial.c b/arch/arm/src/lpc11xx/lpc11_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..6bbd488a3eeda0442442d4ff86c8410c9acf0077 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_serial.c @@ -0,0 +1,1059 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_serial.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc11_uart.h" +#include "lpc11_gpio.h" +#include "lpc11_lowgetc.h" +#include "lpc11_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART) + +/* Configuration ************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ +#ifdef LPC111x + uint8_t cclkdiv; /* Divisor needed to get PCLK from CCLK */ +#endif + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_LPC11_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +/* This describes the state of the LPC11xx uart0 port. */ + +#ifdef CONFIG_LPC11_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = LPC11_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = LPC11_IRQ_UART, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* Which UART with be tty0/console and which tty1? tty2? tty3? */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0=console */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +# endif +#else /* No console */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +#endif /* HAVE_SERIAL_CONSOLE */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + up_serialout(priv, LPC11_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + up_serialout(priv, LPC11_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, LPC11_UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + + up_serialout(priv, LPC11_UART_LCR_OFFSET, lcr); +} + +/************************************************************************************ + * Name: lpc11_uartcclkdiv + * + * Description: + * Select a CCLK divider to produce the UART PCLK. The strategy is to select the + * smallest divisor that results in an solution within range of the 16-bit + * DLM and DLL divisor: + * + * PCLK = MCLK / divisor + * BAUD = PCLK / (16 * DL) + * + * Ignoring the fractional divider for now. (If you want to extend this driver + * to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses + * the same peripheral and that logic could easily leveraged here). + * + * For the LPC111x the PCLK is determined by the UART-specific divisor in + * PCLKSEL0 or PCLKSEL1: + * + * PCLK = MCLK / divisor + * + * For the LPC111x, the PCLK is determined by the global divisor setting in + * the PLKSEL register (and, in that case, this function is not needed). + * + * NOTE: This is an inline function. If a typical optimization level is used and + * a constant is provided for the desired frequency, then most of the following + * logic will be optimized away. + * + ************************************************************************************/ + +#ifdef LPC111x +static inline uint32_t lpc11_uartcclkdiv(uint32_t baud) +{ + /* Ignoring the fractional divider, the BAUD is given by: + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Where for the LPC111x the PCLK is determined by the UART-specific divisor in + * : + * + * UART_PCLK = MAIN_CLOCK / divisor + * + */ + + /* Calculate and optimal PCLKSEL0/1 divisor. + * First, check divisor == 1. This works if the upper limit is met: + * + * DL < 0xffff, or + * PCLK / BAUD / 16 < 0xffff, or + * MCLK / BAUD / 16 < 0xffff, or + * MCLK < BAUD * 0xffff * 16 + * BAUD > MCLK / 0xffff / 16 + * + * And the lower limit is met (we can't allow DL to get very close to one). + * + * DL >= MinDL + * MCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 16 / MinDL + */ + + return 1; +} +#endif /* LPC111x */ + +/************************************************************************************ + * Name: lpc11_uart0config + * + * Description: + * Configure the UART. UART0 peripherals are configured using the following + * registers: + * + * 1. Power: In the PCONP register, set bits PCUART0. + * On reset, UART0 and UART 1 are enabled (PCUART0 = 1 and PCUART1 = 1) + * and UART2/3 are disabled (PCUART1 = 0 and PCUART3 = 0). + * 2. Peripheral clock: In the PCLKSEL0 register, select PCLK_UART0 and + * PCLK_UART1; in the PCLKSEL1 register, select PCLK_UART2 and PCLK_UART3. + * 3. Pins: Select UART pins through the PINSEL registers and pin modes + * through the PINMODE registers. UART receive pins should not have + * pull-down resistors enabled. + * + ************************************************************************************/ + +#ifdef CONFIG_LPC11_UART0 +static inline void lpc11_uart0config(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Step 1: Pins configuration */ + + flags = enter_critical_section(); + lpc11_configgpio(GPIO_UART0_TXD); + lpc11_configgpio(GPIO_UART0_RXD); + + /* Step 2: Enable power on UART0 */ + + regval = getreg32(LPC11_SYSCON_SYSAHBCLKCTRL); + regval |= SYSCON_SYSAHBCLKCTRL_UART; + putreg32(regval, LPC11_SYSCON_SYSAHBCLKCTRL); + + /* Step 3: Enable clocking UART */ + + putreg32(1, LPC11_SYSCON_UARTCLKDIV); + leave_critical_section(flags); +}; +#endif + +/************************************************************************************ + * Name: lpc11_uartdl + * + * Descrption: + * Select a divider to produce the BAUD from the UART PCLK. + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Ignoring the fractional divider for now. (If you want to extend this driver + * to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses + * the same peripheral and that logic could easily leveraged here). + * + ************************************************************************************/ + +#ifdef LPC111x +static inline uint32_t lpc11_uartdl(uint32_t baud, uint8_t divcode) +{ + /* TODO: Calculate DL automatically */ + + uint32_t num = 312; + + return num; +} +#else +static inline uint32_t lpc11_uartdl(uint32_t baud) +{ + return (uint32_t)BOARD_PCLK_FREQUENCY / (baud << 4); +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t dl; + uint32_t lcr; + + /* Clear fifos */ + + up_serialout(priv, LPC11_UART_FCR_OFFSET, (UART_FCR_RXRST | UART_FCR_TXRST)); + + /* Set trigger */ + + up_serialout(priv, LPC11_UART_FCR_OFFSET, (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, LPC11_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + if (priv->bits == 7) + { + lcr |= UART_LCR_WLS_7BIT; + } + else + { + lcr |= UART_LCR_WLS_8BIT; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STOP; + } + + if (priv->parity == 1) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_ODD); + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_EVEN); + } + + /* Enter DLAB=1 */ + + up_serialout(priv, LPC11_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + +#ifdef LPC111x + dl = lpc11_uartdl(priv->baud, priv->cclkdiv); +#else + dl = lpc11_uartdl(priv->baud); +#endif + up_serialout(priv, LPC11_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC11_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC11_UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, LPC11_UART_FCR_OFFSET, + (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN)); + +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the the setup() method is called, however, the serial console may + * operate in a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t status; + int passes; + +#ifdef CONFIG_LPC11_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif + { + PANIC(); + } + + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, LPC11_UART_IIR_OFFSET); + + /* The UART_IIR_INTSTATUS bit should be zero if there are pending + * interrupts + */ + + if ((status & UART_IIR_INTSTATUS) != 0) + { + /* Break out of the loop when there is no longer a + * pending interrupt + */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_INTID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_INTID_RDA: + case UART_IIR_INTID_CTI: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_INTID_THRE: + { + uart_xmitchars(dev); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_INTID_RLS: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, LPC11_UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + * Both cfset(i|o)speed() translate to cfsetspeed. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + uint32_t lcr; /* Holds current values of line control register */ + uint16_t dl; /* Divisor latch */ + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + /* Get the c_speed field in the termios struct */ + + priv->baud = cfgetispeed(termiosp); + + /* TODO: Re-calculate the optimal CCLK divisor for the new baud and + * and reset the divider in the CLKSEL0/1 register. + */ + +#ifdef LPC111x + priv->cclkdiv = lpc11_uartcclkdiv(priv->baud); +#endif + /* DLAB open latch */ + /* REVISIT: Shouldn't we just call up_setup() to do all of the following? */ + + lcr = getreg32(priv->uartbase + LPC11_UART_LCR_OFFSET); + up_serialout(priv, LPC11_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + +#ifdef LPC111x + dl = lpc11_uartdl(priv->baud, priv->cclkdiv); +#else + dl = lpc11_uartdl(priv->baud); +#endif + up_serialout(priv, LPC11_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC11_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC11_UART_LCR_OFFSET, lcr); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, LPC11_UART_LSR_OFFSET); + rbr = up_serialin(priv, LPC11_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_RBRIE; +#endif + } + else + { + priv->ier &= ~UART_IER_RBRIE; + } + + up_serialout(priv, LPC11_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC11_UART_LSR_OFFSET) & UART_LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, LPC11_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_THREIE; + up_serialout(priv, LPC11_UART_IER_OFFSET, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_IER_THREIE; + up_serialout(priv, LPC11_UART_IER_OFFSET, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC11_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC11_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */ + +#ifdef CONFIG_LPC11_UART0 +#ifdef LPC111x + g_uart0priv.cclkdiv = lpc11_uartcclkdiv(CONFIG_UART0_BAUD); +#endif +#ifndef CONFIG_UART0_SERIAL_CONSOLE + lpc11_uart0config(); +#endif + up_disableuartint(&g_uart0priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#ifdef HAVE_SERIAL_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: up_getc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_getc(void) +{ + /* Check for LF */ + + return lpc11_lowgetc(); +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc11xx/lpc11_serial.h b/arch/arm/src/lpc11xx/lpc11_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..59e6cc36f085f20caee4ee61d7bb638755037fbd --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_serial.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_serial.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_SERIAL_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_SERIAL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/lpc11_uart.h" +#include "chip/lpc11_syscon.h" + +#include "lpc11_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_LPC11_UART0) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3 + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_LPC11_UART0) +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* We cannot allow the DLM/DLL divisor to become to small or will will lose too + * much accuracy. This following is a "fudge factor" that represents the minimum + * value of the divisor that we will permit. + */ + +#define UART_MINDL 32 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_SERIAL_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_spi.c b/arch/arm/src/lpc11xx/lpc11_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..178bd77c3604f635383b8c4647f2e0150db39ff6 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_spi.c @@ -0,0 +1,606 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_spi.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc11_syscon.h" +#include "lpc11_gpio.h" +#include "lpc11_spi.h" + +#ifdef CONFIG_LPC11_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* This driver does not support the SPI exchange method. */ + +#ifdef CONFIG_SPI_EXCHANGE +# error "CONFIG_SPI_EXCHANGE must not be defined in the configuration" +#endif + +/* Debug ********************************************************************/ +/* The following enable debug output from this file: + * + * CONFIG_DEBUG - Define to enable general debug features + * CONFIG_DEBUG_SPI - Define to enable basic SSP debug (needs CONFIG_DEBUG) + * CONFIG_DEBUG_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/* SSP Clocking *************************************************************/ +/* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock (SPI_CLOCK). + * SPI_CLOCK may be further divided by 8-254 to get the SPI clock. If we + * want a usable range of 4KHz to 25MHz for the SPI, then: + * + * 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz), + * and + * 2. SPICLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SPI_CLOCK. + */ + +#define SPI_PCLKSET_DIV SYSCON_PCLKSEL_CCLK +#define SPI_CLOCK LPC11_CCLK + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of the SSP driver */ + +struct lpc11_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = lpc11_spiselect, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc11_spistatus, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc11_spicmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc11_spiregister, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc11_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc11_spidev_s *priv = (FAR struct lpc11_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency) +{ + FAR struct lpc11_spidev_s *priv = (FAR struct lpc11_spidev_s *)dev; + uint32_t divisor; + uint32_t actual; + + /* Check if the requested frequence is the same as the frequency selection */ + + DEBUGASSERT(priv && frequency <= SPI_CLOCK / 2); + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* frequency = SPI_CLOCK / divisor, or divisor = SPI_CLOCK / frequency */ + + divisor = SPI_CLOCK / frequency; + + /* The SPI CCR register must contain an even number greater than or equal + * to 8. + */ + + if (divisor < 8) + { + divisor = 8; + } + else if (divisor > 254) + { + divisor = 254; + } + + divisor = (divisor + 1) & ~1; + + /* Save the new divisor value */ + + putreg32(divisor, LPC11_SPI_CCR); + + /* Calculate the new actual */ + + actual = SPI_CLOCK / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc11_spidev_s *priv = (FAR struct lpc11_spidev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC11_SPI_CR); + regval &= ~(SPI_CR_CPOL | SPI_CR_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CR_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CR_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CR_CPOL | SPI_CR_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + putreg32(regval, LPC11_SPI_CR); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc11_spidev_s *priv = (FAR struct lpc11_spidev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC11_SPI_CR); + regval &= ~SPI_CR_BITS_MASK; + regval |= (nbits << SPI_CR_BITS_SHIFT) & SPI_CR_BITS_MASK; + regval |= SPI_CR_BITENABLE; + regval = getreg32(LPC11_SPI_CR); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + /* Write the data to transmitted to the SPI Data Register */ + + putreg32((uint32_t)wd, LPC11_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC11_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC11_SPI_SR); + return (uint16_t)getreg32(LPC11_SPI_DR); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + uint8_t data; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + data = *ptr++; + putreg32((uint32_t)data, LPC11_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. + * The SPIF bit will be set after the last sampling clock edge of + * the SPI data transfer. + */ + + while ((getreg32(LPC11_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC11_SPI_SR); + nwords--; + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write some dummy data to the SPI Data Register in order to clock the + * read data. + */ + + putreg32(0xff, LPC11_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC11_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC11_SPI_SR); + + /* Read the received data from the SPI Data Register */ + + *ptr++ = (uint8_t)getreg32(LPC11_SPI_DR); + nwords--; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc11_spibus_initialize(int port) +{ + FAR struct lpc11_spidev_s *priv = &g_spidev; + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SPI pins and + * one SPI1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SPI_SCK GPIO_SPI_SCK_1 + */ + + flags = enter_critical_section(); + lpc11_configgpio(GPIO_SPI_SCK); + lpc11_configgpio(GPIO_SPI_MISO); + lpc11_configgpio(GPIO_SPI_MOSI); + + /* Configure clocking */ + + regval = getreg32(LPC11_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SPI_MASK; + regval |= (SPI_PCLKSET_DIV << SYSCON_PCLKSEL0_SPI_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL0); + + /* Enable peripheral clocking to SPI and SPI1 */ + + regval = getreg32(LPC11_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSPI; + putreg32(regval, LPC11_SYSCON_PCONP); + leave_critical_section(flags); + + /* Configure 8-bit SPI mode and master mode */ + + putreg32(SPI_CR_BITS_8BITS | SPI_CR_BITENABLE | SPI_CR_MSTR, + LPC11_SPI_CR); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + return &priv->spidev; +} + +#endif /* CONFIG_LPC11_SPI */ diff --git a/arch/arm/src/lpc11xx/lpc11_spi.h b/arch/arm/src/lpc11xx/lpc11_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..dc8edfa904b7d8fcf5bc1c20dc29219758f523b1 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_spi.h @@ -0,0 +1,170 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_spi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_SPI_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip/lpc11_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifdef CONFIG_LPC11_SPI + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc11_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *lpc11_spibus_initialize(int port); + +/************************************************************************************ + * Name: lpc11_spiselect, lpc11_status, and lpc11_spicmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including lpc11_spibus_initialize()) are provided by common LPC11xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in lpc11_boardinitialize() to configure SPI chip select pins. + * 2. Provide lpc11_spiselect() and lpc11_spistatus() functions in your board- + * specific logic. These functions will perform chip selection and status + * operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc11_spicmddata() functions in your board-specific logic. This function + * will perform cmd/data selection operations using GPIOs in the way your + * board is configured. + * 3. Add a call to lpc11_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by lpc11_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +void lpc11_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc11_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc11_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: spi_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from spiselect after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ************************************************************************************/ + +void spi_flush(FAR struct spi_dev_s *dev); + +/************************************************************************************ + * Name: lpc11_spiregister + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD drvier when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function must + * must be implemented. These functions implements the registercallback + * method of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +int lpc11_spiregister(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC11_SPI */ +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_SPI_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_ssp.c b/arch/arm/src/lpc11xx/lpc11_ssp.c new file mode 100644 index 0000000000000000000000000000000000000000..c94eac7692d0198ff318afb9fbc950c2d9466331 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_ssp.c @@ -0,0 +1,1071 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_ssp.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc11_syscon.h" +#include "lpc11_gpio.h" +#include "lpc11_ssp.h" + +#if defined(CONFIG_LPC11_SSP0) || defined(CONFIG_LPC11_SSP1) || \ + defined(CONFIG_LPC11_SSP2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* This driver does not support the SPI exchange method. */ + +#ifdef CONFIG_SPI_EXCHANGE +# error "CONFIG_SPI_EXCHANGE must not be defined in the configuration" +#endif + +/* Debug ********************************************************************/ +/* The following enable debug output from this file: + * + * CONFIG_DEBUG - Define to enable general debug features + * CONFIG_DEBUG_SPI - Define to enable basic SSP debug (needs CONFIG_DEBUG) + * CONFIG_DEBUG_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_DEBUG_SPI +# define sspdbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define sspdbg(x...) +# define spivdbg(x...) +#endif + +/* SSP Clocking *************************************************************/ + +#if defined(LPC111x) +/* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock (SSP_CLOCK). + * SSP_CLOCK may be further divided by 2-254 to get the SSP clock. If we + * want a usable range of 4KHz to 25MHz for the SSP, then: + * + * 1. SSPCLK must be greater than (2*25MHz) = 50MHz, and + * 2. SSPCLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SSP_CLOCK. + */ + +# if LPC11_CCLK > 100000000 +# error "CCLK <= 100,000,000 assumed" +# endif + +# define SSP_PCLKSET_DIV SYSCON_PCLKSEL_CCLK +# define SSP_CLOCK LPC11_CCLK + +#elif defined(LPC111x) +/* All peripherals are clocked by the same peripheral clock in the LPC111x + * family. + */ + +# define SSP_CLOCK BOARD_PCLK_FREQUENCY + +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes the state of the SSP driver */ + +struct lpc11_sspdev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t sspbase; /* SPIn base address */ +#ifdef CONFIG_LPC11_SSP_INTERRUPTS + uint8_t sspirq; /* SPI IRQ number */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (4 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint32_t ssp_getreg(FAR struct lpc11_sspdev_s *priv, + uint8_t offset); +static inline void ssp_putreg(FAR struct lpc11_sspdev_s *priv, + uint8_t offset, uint32_t value); + +/* SPI methods */ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void ssp_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode); +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void ssp_sndblock(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); + +/* Initialization */ + +#ifdef CONFIG_LPC11_SSP0 +static inline FAR struct lpc11_sspdev_s *lpc11_ssp0initialize(void); +#endif +#ifdef CONFIG_LPC11_SSP1 +static inline FAR struct lpc11_sspdev_s *lpc11_ssp1initialize(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC11_SSP0 +static const struct spi_ops_s g_spi0ops = +{ + .lock = ssp_lock, + .select = lpc11_ssp0select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc11_ssp0status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc11_ssp0cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc11_ssp0register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc11_sspdev_s g_ssp0dev = +{ + .spidev = { &g_spi0ops }, + .sspbase = LPC11_SSP0_BASE, +#ifdef CONFIG_LPC11_SSP_INTERRUPTS + .sspirq = LPC11_IRQ_SSP0, +#endif +}; +#endif /* CONFIG_LPC11_SSP0 */ + +#ifdef CONFIG_LPC11_SSP1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = ssp_lock, + .select = lpc11_ssp1select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, + .status = lpc11_ssp1status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc11_ssp1cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc11_ssp1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc11_sspdev_s g_ssp1dev = +{ + .spidev = { &g_spi1ops }, + .sspbase = LPC11_SSP1_BASE, +#ifdef CONFIG_LPC11_SSP_INTERRUPTS + .sspirq = LPC11_IRQ_SSP1, +#endif +}; +#endif /* CONFIG_LPC11_SSP1 */ + +#ifdef CONFIG_LPC11_SSP2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = ssp_lock, + .select = lpc11_ssp2select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, + .status = lpc11_ssp2status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc11_ssp2cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc11_ssp2register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc11_sspdev_s g_ssp2dev = +{ + .spidev = { &g_spi2ops }, + .sspbase = LPC11_SSP2_BASE, +#ifdef CONFIG_LPC11_SSP_INTERRUPTS + .sspirq = LPC11_IRQ_SSP2, +#endif +}; +#endif /* CONFIG_LPC11_SSP2 */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssp_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static inline uint32_t ssp_getreg(FAR struct lpc11_sspdev_s *priv, + uint8_t offset) +{ + return getreg32(priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_putreg + * + * Description: + * Write a 32-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void ssp_putreg(FAR struct lpc11_sspdev_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: ssp_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + uint32_t cpsdvsr; + uint32_t scr; + uint32_t regval; + uint32_t actual; + + /* Check if the requested frequency is the same as the frequency selection */ + + DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2); + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* The SSP bit frequency is given by: + * + * frequency = SSP_CLOCK / (CPSDVSR * (SCR+1)). + * + * Let's try for a solution with the smallest value of SCR. NOTES: + * (1) In the calculations below, the value of the variable 'scr' is + * (SCR+1) in the above equation. (2) On slower LPC11xx parts, SCR + * will probably always be zero. + */ + + for (scr = 1; scr <= 256; scr++) + { + /* CPSDVSR = SSP_CLOCK / (SCR + 1) / frequency */ + + cpsdvsr = SSP_CLOCK / (scr * frequency); + + /* Break out on the first solution we find with the smallest value + * of SCR and with CPSDVSR within the maximum range or 254. + */ + + if (cpsdvsr < 255) + { + break; + } + } + + DEBUGASSERT(scr <= 256 && cpsdvsr <= 255); + + /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + + if (cpsdvsr < 2) + { + /* Clip to the minimum value. */ + + cpsdvsr = 2; + } + else if (cpsdvsr > 254) + { + /* This should never happen */ + + cpsdvsr = 254; + } + + /* Force even */ + + cpsdvsr = (cpsdvsr + 1) & ~1; + + /* Save the new CPSDVSR and SCR values */ + + ssp_putreg(priv, LPC11_SSP_CPSR_OFFSET, cpsdvsr); + + regval = ssp_getreg(priv, LPC11_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_SCR_MASK; + regval |= ((scr - 1) << SSP_CR0_SCR_SHIFT); + ssp_putreg(priv, LPC11_SSP_CR0_OFFSET, regval); + + /* Calculate the new actual */ + + actual = SSP_CLOCK / (cpsdvsr * scr); + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + sspdbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: ssp_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR0 appropriately */ + + regval = ssp_getreg(priv, LPC11_SSP_CR0_OFFSET); + regval &= ~(SSP_CR0_CPOL | SSP_CR0_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SSP_CR0_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SSP_CR0_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SSP_CR0_CPOL | SSP_CR0_CPHA); + break; + + default: + sspdbg("Bad mode: %d\n", mode); + DEBUGASSERT(FALSE); + return; + } + + ssp_putreg(priv, LPC11_SSP_CR0_OFFSET, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: ssp_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 3 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR1 appropriately */ + + regval = ssp_getreg(priv, LPC11_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_DSS_MASK; + regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT); + ssp_putreg(priv, LPC11_SSP_CR0_OFFSET, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: ssp_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + register uint32_t regval; + + /* Wait while the TX FIFO is full */ + + while (!(ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_TNF)); + + /* Write the byte to the TX FIFO */ + + ssp_putreg(priv, LPC11_SSP_DR_OFFSET, (uint32_t)wd); + + /* Wait for the RX FIFO not empty */ + + while (!(ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Get the value from the RX FIFO and return it */ + + regval = ssp_getreg(priv, LPC11_SSP_DR_OFFSET); + sspdbg("%04x->%04x\n", wd, regval); + return (uint16_t)regval; +} + +/**************************************************************************** + * Name: ssp_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + union + { + FAR const uint8_t *p8; + FAR const uint16_t *p16; + FAR const void *pv; + } u; + uint32_t data; + uint32_t sr; + + /* Loop while thre are bytes remaining to be sent */ + + sspdbg("nwords: %d\n", nwords); + u.pv = buffer; + while (nwords > 0) + { + /* While the TX FIFO is not full and there are bytes left to send */ + + while ((ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_TNF) && nwords) + { + /* Fetch the data to send */ + + if (priv->nbits > 8) + { + data = (uint32_t)*u.p16++; + } + else + { + data = (uint32_t)*u.p8++; + } + + /* Send the data */ + + ssp_putreg(priv, LPC11_SSP_DR_OFFSET, data); + nwords--; + } + } + + /* Then discard all card responses until the RX & TX FIFOs are emptied. */ + + sspdbg("discarding\n"); + do + { + /* Is there anything in the RX fifo? */ + + sr = ssp_getreg(priv, LPC11_SSP_SR_OFFSET); + if ((sr & SSP_SR_RNE) != 0) + { + /* Yes.. Read and discard */ + + (void)ssp_getreg(priv, LPC11_SSP_DR_OFFSET); + } + + /* There is a race condition where TFE may go true just before + * RNE goes true and this loop terminates prematurely. The nasty + * little delay in the following solves that (it could probably be + * tuned to improve performance). + */ + + else if ((sr & SSP_SR_TFE) != 0) + { + up_udelay(100); + sr = ssp_getreg(priv, LPC11_SSP_SR_OFFSET); + } + } + while ((sr & SSP_SR_RNE) != 0 || (sr & SSP_SR_TFE) == 0); +} + +/**************************************************************************** + * Name: ssp_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + union + { + FAR uint8_t *p8; + FAR uint16_t *p16; + FAR void *pv; + } u; + uint32_t data; + uint32_t rxpending = 0; + + /* While there is remaining to be sent (and no synchronization error has + * occurred). + */ + + sspdbg("nwords: %d\n", nwords); + u.pv = buffer; + while (nwords || rxpending) + { + /* Fill the transmit FIFO with 0xffff... + * Write 0xff to the data register while (1) the TX FIFO is + * not full, (2) we have not exceeded the depth of the TX FIFO, + * and (3) there are more bytes to be sent. + */ + + spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); + while ((ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_TNF) && + (rxpending < LPC11_SSP_FIFOSZ) && nwords) + { + ssp_putreg(priv, LPC11_SSP_DR_OFFSET, 0xffff); + nwords--; + rxpending++; + } + + /* Now, read the RX data from the RX FIFO while the RX FIFO is not + * empty. + */ + + spivdbg("RX: rxpending: %d\n", rxpending); + while (ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_RNE) + { + data = (uint8_t)ssp_getreg(priv, LPC11_SSP_DR_OFFSET); + if (priv->nbits > 8) + { + *u.p16++ = (uint16_t)data; + } + else + { + *u.p8++ = (uint8_t)data; + } + rxpending--; + } + } +} + +/**************************************************************************** + * Name: lpc11_ssp0initialize + * + * Description: + * Initialize the SSP0 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC11_SSP0 +static inline FAR struct lpc11_sspdev_s *lpc11_ssp0initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP0 pins and + * one SSP1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SSP0_SCK GPIO_SSP0_SCK_1 + */ + + flags = enter_critical_section(); + lpc11_configgpio(GPIO_SSP0_SCK); + lpc11_configgpio(GPIO_SSP0_MISO); + lpc11_configgpio(GPIO_SSP0_MOSI); + + /* Configure clocking */ + +#ifdef LPC111x + regval = getreg32(LPC11_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_SSP0_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL1_SSP0_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL1); +#endif + + /* Enable peripheral clocking to SSP0 */ + + regval = getreg32(LPC11_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP0; + putreg32(regval, LPC11_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp0dev; +} +#endif + +/**************************************************************************** + * Name: lpc11_ssp1initialize + * + * Description: + * Initialize the SSP1 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC11_SSP1 +static inline FAR struct lpc11_sspdev_s *lpc11_ssp1initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP0 pins and + * one SSP1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SSP0_SCK GPIO_SSP0_SCK_1 + */ + + flags = enter_critical_section(); + lpc11_configgpio(GPIO_SSP1_SCK); + lpc11_configgpio(GPIO_SSP1_MISO); + lpc11_configgpio(GPIO_SSP1_MOSI); + + /* Configure clocking */ + +#ifdef LPC111x + regval = getreg32(LPC11_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SSP1_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP1_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL0); +#endif + + /* Enable peripheral clocking to SSP0 and SSP1 */ + + regval = getreg32(LPC11_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP1; + putreg32(regval, LPC11_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp1dev; +} +#endif + +/**************************************************************************** + * Name: lpc11_ssp2initialize + * + * Description: + * Initialize the SSP2 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC11_SSP2 +static inline FAR struct lpc11_sspdev_s *lpc11_ssp2initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP2 pins have + * multiple, alternative pin selection. Definitions in the board.h file + * must be provided to resolve the board-specific pin configuration like: + * + * #define GPIO_SSP2_SCK GPIO_SSP2_SCK_1 + */ + + flags = enter_critical_section(); + lpc11_configgpio(GPIO_SSP2_SCK); + lpc11_configgpio(GPIO_SSP2_MISO); + lpc11_configgpio(GPIO_SSP2_MOSI); + + /* Configure clocking */ + +#ifdef LPC111x + regval = getreg32(LPC11_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SSP2_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP2_SHIFT); + putreg32(regval, LPC11_SYSCON_PCLKSEL0); +#endif + + /* Enable peripheral clocking to SSP0 and SSP1 */ + + regval = getreg32(LPC11_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP2; + putreg32(regval, LPC11_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp2dev; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_sspbus_initialize + * + * Description: + * Initialize the selected SSP port. + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc11_sspbus_initialize(int port) +{ + FAR struct lpc11_sspdev_s *priv; + uint32_t regval; + int i; + + /* Only the SSP0 and SSP1 interfaces are supported */ + + switch (port) + { +#ifdef CONFIG_LPC11_SSP0 + case 0: + priv = lpc11_ssp0initialize(); + break; +#endif +#ifdef CONFIG_LPC11_SSP1 + case 1: + priv = lpc11_ssp1initialize(); + break; +#endif +#ifdef CONFIG_LPC11_SSP2 + case 2: + priv = lpc11_ssp2initialize(); + break; +#endif + default: + return NULL; + } + + /* Configure 8-bit SPI mode */ + + ssp_putreg(priv, LPC11_SSP_CR0_OFFSET, SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI); + + /* Disable the SSP and all interrupts (we'll poll for all data) */ + + ssp_putreg(priv, LPC11_SSP_CR1_OFFSET, 0); + ssp_putreg(priv, LPC11_SSP_IMSC_OFFSET, 0); + + /* Set the initial SSP configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + ssp_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + /* Enable the SPI */ + + regval = ssp_getreg(priv, LPC11_SSP_CR1_OFFSET); + ssp_putreg(priv, LPC11_SSP_CR1_OFFSET, regval | SSP_CR1_SSE); + for (i = 0; i < LPC11_SSP_FIFOSZ; i++) + { + (void)ssp_getreg(priv, LPC11_SSP_DR_OFFSET); + } + + return &priv->spidev; +} + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be done + * after a device is deselected if you worry about such things. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void ssp_flush(FAR struct spi_dev_s *dev) +{ + FAR struct lpc11_sspdev_s *priv = (FAR struct lpc11_sspdev_s *)dev; + + /* Wait for the TX FIFO not full indication */ + + while (!(ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_TNF)); + ssp_putreg(priv, LPC11_SSP_DR_OFFSET, 0xff); + + /* Wait until TX FIFO and TX shift buffer are empty */ + + while (ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_BSY); + + /* Wait until RX FIFO is not empty */ + + while (!(ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Then read and discard bytes until the RX FIFO is empty */ + + do + { + (void)ssp_getreg(priv, LPC11_SSP_DR_OFFSET); + } + while (ssp_getreg(priv, LPC11_SSP_SR_OFFSET) & SSP_SR_RNE); +} + +#endif /* CONFIG_LPC11_SSP0/1 */ diff --git a/arch/arm/src/lpc11xx/lpc11_ssp.h b/arch/arm/src/lpc11xx/lpc11_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..9910650a300b79ea7957c5a3bad7bde14deaad81 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_ssp.h @@ -0,0 +1,189 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_ssp.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_SSP_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip/lpc11_ssp.h" + +#if defined(CONFIG_LPC11_SSP0) || defined(CONFIG_LPC11_SSP1) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc11_sspbus_initialize + * + * Description: + * Initialize the selected SSP port. + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *lpc11_sspbus_initialize(int port); + +/************************************************************************************ + * Name: lpc11_ssp0/ssp1select, lpc11_ssp0/ssp1status, and lpc11_ssp0/ssp1cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including lpc11_sspbus_initialize()) are provided by common LPC11xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in lpc11_boardinitialize() to configure SSP chip select pins. + * 2. Provide lpc11_ssp0/ssp1select() and lpc11_ssp0/ssp1status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc11_ssp0/ssp1cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to lpc11_sspbus_initialize() in your low level application + * initialization logic + * 4. The handle returned by lpc11_sspbus_initialize() may then be used to bind the + * SSP driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SSP driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_LPC11_SSP0 +void lpc11_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc11_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc11_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_LPC11_SSP1 +void lpc11_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc11_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc11_ssp1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/************************************************************************************ + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from ssp0/1select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_LPC11_SSP0) || defined(CONFIG_LPC11_SSP1) +void ssp_flush(FAR struct spi_dev_s *dev); +#endif + +/************************************************************************************ + * Name: lpc11_ssp0/1register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD drvier when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function(s) must + * must be implemented. These functiosn implements the registercallback + * method of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_LPC11_SSP0 +int lpc11_ssp0register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_LPC11_SSP1 +int lpc11_ssp1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC11_SSP0 || CONFIG_LPC11_SSP1 */ +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_SSP_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_start.c b/arch/arm/src/lpc11xx/lpc11_start.c new file mode 100644 index 0000000000000000000000000000000000000000..78429691490d69c6284c9e1adb74fb1133fff331 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_start.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_start.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc11_clockconfig.h" +#include "lpc11_lowputc.h" +#include "lpc11_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#define IDLE_STACK ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uint32_t g_idle_topstack = IDLE_STACK; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Configure the uart so that we can get debug output as soon as possible */ + + lpc11_clockconfig(); + lpc11_lowsetup(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + lpc11_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + lpc11_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/lpc11xx/lpc11_timer.c b/arch/arm/src/lpc11xx/lpc11_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..b9106becbcc016f8f4cd7876b470546d85746389 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_timer.c @@ -0,0 +1,634 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_timer.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc11_syscon.h" +#include "lpc11_timer.h" +#include "chip/lpc116x_pinconfig.h" +#include "lpc11_gpio.h" +#include "lpc116x_gpio.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the TIMER upper half driver. + */ + +#if defined(CONFIG_LPC11_TMR0) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4 */ +#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ +#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ + +#define TIMTYPE_TIM1 TIMTYPE_ADVANCED + + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct lpc11_timer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {0,...,7} */ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint8_t timtype; /* See the TIMTYPE_* definitions */ + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t timer_getreg(struct lpc11_timer_s *priv, int offset); +static void timer_putreg(struct lpc11_timer_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void timer_dumpregs(struct lpc11_timer_s *priv, FAR const char *msg); +#else +# define timer_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int timer_timer(FAR struct lpc11_timer_s *priv, + FAR const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int timer_setup(FAR struct pwm_lowerhalf_s *dev); +static int timer_shutdown(FAR struct pwm_lowerhalf_s *dev); + +static int timer_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); + +static int timer_stop(FAR struct pwm_lowerhalf_s *dev); +static int timer_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = timer_setup, + .shutdown = timer_shutdown, + .start = timer_start, + .stop = timer_stop, + .ioctl = timer_ioctl, +}; + +#ifdef CONFIG_LPC11_TMR0 +static struct lpc11_timer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channel = CONFIG_LPC11_MAT0_PIN, + .timtype = TIMTYPE_TIM1, + .base = LPC11_TMR1_BASE, + .pincfg = GPIO_MAT0p1_2, + .pclk = (0x1 << 12), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: timer_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t timer_getreg(struct lpc11_timer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: timer_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void timer_putreg(struct lpc11_timer_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: timer_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void timer_dumpregs(struct lpc11_timer_s *priv, FAR const char *msg) +{ + pwmdbg("%s:\n", msg); + pwmdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + timer_getreg(priv, LPC11_PWM_MR0_OFFSET), + timer_getreg(priv, LPC11_PWM_MR1_OFFSET), + timer_getreg(priv, LPC11_PWM_MR2_OFFSET), + timer_getreg(priv, LPC11_PWM_MR3_OFFSET)); +#if defined(CONFIG_LPC11_TMR0) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + timer_getreg(priv, LPC11_PWM_MR0_OFFSET), + timer_getreg(priv, LPC11_PWM_MR1_OFFSET), + timer_getreg(priv, LPC11_PWM_MR2_OFFSET), + timer_getreg(priv, LPC11_PWM_MR3_OFFSET)); + } + else +#endif + { + pwmdbg(" DCR: %04x DMAR: %04x\n", + timer_getreg(priv, LPC11_PWM_MR2_OFFSET), + timer_getreg(priv, LPC11_PWM_MR3_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: timer_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_timer(FAR struct lpc11_timer_s *priv, + FAR const struct pwm_info_s *info) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + putreg32(info->frequency, LPC11_TMR0_MR1); /* Set TIMER0 MR1 = number of counts */ + putreg32(info->frequency, LPC11_TMR1_MR0); /* Set TIMER1 MR0 = number of counts */ + + putreg32(1, LPC11_TMR0_TCR); /* Start timer0 */ + putreg32(1, LPC11_TMR1_TCR); /* Start timer1 */ + + leave_critical_section(flags); + timer_dumpregs(priv, "After starting"); + return OK; +} + +#ifdef XXXXX +/**************************************************************************** + * Name: timer_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_interrupt(struct lpc11_timer_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = timer_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + timer_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + return OK; +} + +/**************************************************************************** + * Name: timer_tim1/8interrupt + * + * Description: + * Handle timer 1 and 8 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_tim1interrupt(int irq, void *context) +{ + return timer_interrupt(&g_pwm1dev); +} + +#endif /* XXXXX */ + +/**************************************************************************** + * Name: timer_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int timer_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc11_timer_s *priv = (FAR struct lpc11_timer_s *)dev; + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Power on the timer peripherals */ + + regval = getreg32(LPC11_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCTIM0; + regval |= SYSCON_PCONP_PCTIM1; + regval |= SYSCON_PCONP_PCTIM2; + regval |= SYSCON_PCONP_PCTIM3; + putreg32(regval, LPC11_SYSCON_PCONP); + + /* Select clock for the timer peripheral */ + + regval = getreg32(LPC11_SYSCON_PCLKSEL0); + regval &= ~(0x3 << 2); + regval |= (0x1 << 2); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + regval &= ~(0x3 << 4); + regval |= (0x1 << 4); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + putreg32(regval, LPC11_SYSCON_PCLKSEL0); + regval = getreg32(LPC11_SYSCON_PCLKSEL1); + regval &= ~(0x3 << 12); + regval |= (0x1 << 12); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + regval &= ~(0x3 << 14); + regval |= (0x1 << 14); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + putreg32(regval, LPC11_SYSCON_PCLKSEL1); + priv->pclk = (0x1 << 12) | (0x1 << 4); + + putreg32(1000, LPC11_TMR0_MR1); /* Set TIMER0 MR1 = number of counts */ + + putreg32(1, LPC11_TMR0_PR); /* Prescaler count frequency: Fpclk/1 */ + putreg32(~(0x3 << 0), LPC11_TMR0_CCR); /* Prescaler count frequency: Fpclk/1 */ + putreg32(~(0x3 << 0), LPC11_TMR0_CTCR); /* Prescaler count frequency: Fpclk/1 */ + putreg32((2 << 3), LPC11_TMR0_MCR); /* Reset on match register MR1 */ + + /* Output bit toggle on external match event External match on MR1, Toggle + * external bit + */ + + putreg32(((1 << 1) | (3 << 6)), LPC11_TMR0_EMR); + putreg32((1 << 0), LPC11_TMR0_TCR); /* Start timer0 */ + + /* Configure the output pins GPIO3.26 */ + + lpc11_configgpio(GPIO_MAT0p1_2); + + putreg32(500, LPC11_TMR1_MR0); /* Set TIMER1 MR0 = number of counts */ + + putreg32(1, LPC11_TMR1_PR); /* Prescaler count frequency:Fpclk/1 */ + putreg32(~(0x3 << 0), LPC11_TMR1_CCR); /* Prescaler count frequency:Fpclk/1 */ + putreg32(~(0x3 << 0), LPC11_TMR1_CTCR); /* Prescaler count frequency:Fpclk/1 */ + putreg32((2 << 0), LPC11_TMR1_MCR); /* Reset on match register MR0 */ +// putreg32(((1 << 0) | (3 << 4)), LPC11_TMR1_EMR); /* Output bit toggle on external match event MAT0 */ + putreg32((1 << 0), LPC11_TMR1_TCR); /* Start timer1 */ + + /* configure the output pins GPIO3.26 */ +// lpc11_configgpio(GPIO_MAT0p1_2); + + leave_critical_section(flags); + pwm_dumpgpio(priv->pincfg, "TIMER setup"); + return OK; +} + +/**************************************************************************** + * Name: timer_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc11_timer_s *priv = (FAR struct lpc11_timer_s *)dev; + uint32_t pincfg; + + pwmdbg("TIM%d pincfg: %08x\n", priv->timid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + return OK; +} + +/**************************************************************************** + * Name: timer_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct lpc11_timer_s *priv = (FAR struct lpc11_timer_s *)dev; + return timer_timer(priv, info); +} + +/**************************************************************************** + * Name: timer_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int timer_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc11_timer_s *priv = (FAR struct lpc11_timer_s *)dev; + uint32_t resetbit; + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + pwmdbg("TIM%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC11_TMR0 + case 1: + break; +#endif + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where timer_start() can be called. + */ + + leave_critical_section(flags); + + pwmdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + timer_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: timer_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, + unsigned long arg) +{ +#ifdef CONFIG_DEBUG_TIMER + FAR struct lpc11_timer_s *priv = (FAR struct lpc11_timer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmdbg("TIM%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_timerinitialize + * + * Description: + * Initialize one timer for use with the upper_level TIMER driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half TIMER driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *lpc11_timerinitialize(int timer) +{ + FAR struct lpc11_timer_s *lower; + + pwmdbg("TIM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_LPC11_TMR0 + case 0: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_LPC11_TIMn_TIMER, n = 1,...,14 */ diff --git a/arch/arm/src/lpc11xx/lpc11_timer.h b/arch/arm/src/lpc11xx/lpc11_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..edfb621c169f13725e1f7ce416bc5a9bdf95da44 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_timer.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc11_timer.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_TIMER_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc11_timer.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_TIMER_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_timerisr.c b/arch/arm/src/lpc11xx/lpc11_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..6bbd6e0878d48b629d80a4644cb71a019eece7c2 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_timerisr.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* "The CLKSOURCE bit in SysTick Control and Status register selects either + * the core clock (when CLKSOURCE = 1) or a divide-by-16 of the core clock + * (when CLKSOURCE = 0). ..." + */ + +#if defined(CONFIG_LPC11_SYSTICK_CORECLK) +# define SYSTICK_CLOCK LPC11_MCLK /* Core clock */ +#elif defined(CONFIG_LPC11_SYSTICK_CORECLK_DIV16) +# define SYSTICK_CLOCK (LPC11_MCLK / 16) /* Core clock divided by 16 */ +#endif + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * Then, for example, if the external high speed crystal is the SysTick + * clock source and BOARD_XTALHI_FREQUENCY is 12MHz and CLK_TCK is 100, then + * the reload value would be: + * + * SYSTICK_RELOAD = (12,000,000 / 100) - 1 + * = 119,999 + * = 0x1d4bf + * + * Which fits within the maximum 24-bit reload value. + */ + +#define SYSTICK_RELOAD ((SYSTICK_CLOCK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(ARMV6M_SYSCON_SHPR3); + regval &= ~SYSCON_SHPR3_PRI_15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << SYSCON_SHPR3_PRI_15_SHIFT); + putreg32(regval, ARMV6M_SYSCON_SHPR3); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, ARMV6M_SYSTICK_RVR); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(LPC11_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts. "The CLKSOURCE bit in SysTick Control and + * Status register selects either the core clock (when CLKSOURCE = 1) or + * a divide-by-16 of the core clock (when CLKSOURCE = 0). ..." + */ + +#ifdef CONFIG_LPC11_SYSTICK_CORECLK + putreg32((SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), + ARMV6M_SYSTICK_CSR); +#else + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), ARMV6M_SYSTICK_CSR); +#endif + + /* And enable the timer interrupt */ + + up_enable_irq(LPC11_IRQ_SYSTICK); +} diff --git a/arch/arm/src/lpc11xx/lpc11_userspace.c b/arch/arm/src/lpc11xx/lpc11_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..6ee07ad6b517562e36d2068e2590584136bc5970 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_userspace.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/lpc11xx/lpc11_userspace.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "lpc11_mpuinit.h" +#include "lpc11_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc11_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void lpc11_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + lpc11_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/lpc11xx/lpc11_userspace.h b/arch/arm/src/lpc11xx/lpc11_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..a515654ce983a4a2eb15a566c1b88772b704092e --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc11_userspace.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_USERSPACE_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc11_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc11_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_USERSPACE_H */ diff --git a/arch/arm/src/lpc11xx/lpc11_wdt.h b/arch/arm/src/lpc11xx/lpc11_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..d963b4b064ec657c00c68b640e735a57a0338569 --- /dev/null +++ b/arch/arm/src/lpc11xx/lpc11_wdt.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc11xx/lpc11_wdt.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H +#define __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc11_wdt.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC11XX_LPC11_WDT_H */ diff --git a/arch/arm/src/lpc17xx/Kconfig b/arch/arm/src/lpc17xx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..e8ac3d3a22f78d80fecda4144875570eefe69859 --- /dev/null +++ b/arch/arm/src/lpc17xx/Kconfig @@ -0,0 +1,984 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC17xx Configuration Options" + +choice + prompt "NXP LPC17XX Chip Selection" + default ARCH_CHIP_LPC1768 + depends on ARCH_CHIP_LPC17XX + +config ARCH_CHIP_LPC1751 + bool "LPC1751" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1752 + bool "LPC1752" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1754 + bool "LPC1754" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1756 + bool "LPC1756" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1758 + bool "LPC1758" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1759 + bool "LPC1759" + select ARCH_FAMILY_LPC175X + +config ARCH_CHIP_LPC1764 + bool "LPC1764" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1765 + bool "LPC1765" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1766 + bool "LPC1766" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1767 + bool "LPC1767" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1768 + bool "LPC1768" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1769 + bool "LPC1769" + select ARCH_FAMILY_LPC176X + +config ARCH_CHIP_LPC1773 + bool "LPC1773" + select ARCH_FAMILY_LPC177X + select ARCH_HAVE_SPIFI + +config ARCH_CHIP_LPC1774 + bool "LPC1774" + select ARCH_FAMILY_LPC177X + +config ARCH_CHIP_LPC1776 + bool "LPC1776" + select ARCH_FAMILY_LPC177X + +config ARCH_CHIP_LPC1777 + bool "LPC1777" + select ARCH_FAMILY_LPC177X + +config ARCH_CHIP_LPC1778 + bool "LPC1778" + select ARCH_FAMILY_LPC177X + +config ARCH_CHIP_LPC1785 + bool "LPC1785" + select ARCH_FAMILY_LPC178X + +config ARCH_CHIP_LPC1786 + bool "LPC1786" + select ARCH_FAMILY_LPC178X + +config ARCH_CHIP_LPC1787 + bool "LPC1787" + select ARCH_FAMILY_LPC178X + +config ARCH_CHIP_LPC1788 + bool "LPC1788" + select ARCH_FAMILY_LPC178X + +endchoice + +config ARCH_FAMILY_LPC175X + bool + +config ARCH_FAMILY_LPC176X + bool + +config ARCH_FAMILY_LPC177X + bool + +config ARCH_FAMILY_LPC178X + bool + +config ARCH_HAVE_SPIFI + bool + +menu "LPC17xx Peripheral Support" + +config LPC17_MAINOSC + bool "Main oscillator" + default y + +config LPC17_PLL0 + bool "PLL0" + default y + +config LPC17_PLL1 + bool "PLL1" + default y + +config LPC17_EMC + bool "EMC" + default y + depends on ARCH_FAMILY_LPC178X + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTDRAM + select ARCH_HAVE_EXTNOR + +config LPC17_ETHERNET + bool "Ethernet" + select NETDEVICES + select ARCH_HAVE_PHY + select ARCH_HAVE_NETDEV_STATISTICS + default n + +config LPC17_LCD + bool "LCD controller" + default n + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X + +config LPC17_USBHOST + bool "USB host" + select USBHOST + select USBHOST_HAVE_ASYNCH + default n + +config LPC17_USBDEV + bool "USB Device" + select USBDEV + default n + +config LPC17_USBOTG + bool "USB OTG" + default n + depends on LPC17_USBHOST && LPC17_USBDEV + +config LPC17_SDCARD + bool "SD Card Interface" + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X + select ARCH_HAVE_SDIO + default n + +config LPC17_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC17_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC17_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC17_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC17_UART4 + bool "UART4" + default n + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC17_CAN1 + bool "CAN1" + select ARCH_HAVE_UART4 + default n + +config LPC17_CAN2 + bool "CAN2" + default n + +config LPC17_SPI + bool "SPI" + default n + depends on ARCH_FAMILY_LPC175X || ARCH_FAMILY_LPC176X + +config LPC17_SSP0 + bool "SSP0" + default n + +config LPC17_SSP1 + bool "SSP1" + default n + +config LPC17_SSP2 + bool "SSP1" + default n + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X + +config LPC17_SPIFI + bool "SPIFI Interface" + depends on ARCH_HAVE_SPIFI + default n + +config LPC17_I2C0 + bool "I2C0" + default n + +config LPC17_I2C1 + bool "I2C1" + default n + +config LPC17_I2C2 + bool "I2C2" + default n + +config LPC17_I2S + bool "I2S" + default n + +config LPC17_TMR0 + bool "Timer 0" + default n + +config LPC17_MAT0_PIN + int "TIM1 MAT0 Output Pin" + default 1 + range 1 4 + depends on LPC17_TMR0 + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config LPC17_TMR1 + bool "Timer 1" + default n + +config LPC17_TMR2 + bool "Timer 2" + default n + +config LPC17_TMR3 + bool "Timer 3" + default n + +config LPC17_RIT + bool "RIT" + default n + +config LPC17_PWM0 + bool "PWM0" + default n + +config LPC17_PWM1 + bool "PWM1" + default n + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X || ARCH_FAMILY_LPC176X + +config LPC17_PWM1_PIN + int "TIM1 PWM Output Pin" + default 1 + range 1 4 + depends on LPC17_PWM1 + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config LPC17_MCPWM + bool "MCPWM" + default n + depends on ARCH_FAMILY_LPC175X || ARCH_FAMILY_LPC176X + +config LPC17_MCPWM1_PIN + int "TIM1 MCPWM Output Pin" + default 1 + range 1 4 + depends on LPC17_MCPWM + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config LPC17_QEI + bool "QEI" + default n + +config LPC17_RTC + bool "RTC" + default n + +config LPC17_RTCEV + bool "RTC event monitor" + default n + depends on LPC17_RTC + +config LPC17_WDT + bool "WDT" + default n + +config LPC17_ADC + bool "ADC" + default n + +config LPC17_DAC + bool "DAC" + default n + +config LPC17_GPDMA + bool "GPDMA" + default n + select ARCH_DMA + +config LPC17_CRC + bool "CRC engine" + default n + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X + +config LPC17_FLASH + bool "FLASH" + default n + +config LPC17_EEPROM + bool "EEPROM" + default n + depends on ARCH_FAMILY_LPC177X || ARCH_FAMILY_LPC178X + +endmenu + +menu "External Memory Configuration" + +config ARCH_HAVE_EXTNAND + bool + +config ARCH_HAVE_EXTNOR + bool + +config ARCH_HAVE_EXTDRAM + bool + +config ARCH_HAVE_EXTSRAM0 + bool + +config LPC17_EXTNAND + bool "Configure external NAND" + default n + depends on ARCH_HAVE_EXTNAND + ---help--- + Configure external NAND memory and, if applicable, map then external + NAND into the memory map. + +if LPC17_EXTNAND + +config LPC17_EXTNANDSIZE + int "External NAND size" + default 0 + ---help--- + Size of the external NAND in bytes. + +endif + +config LPC17_EXTNOR + bool "Configure external NOR memory" + default n + depends on ARCH_HAVE_EXTNOR + ---help--- + Configure external NOR memory and, if applicable, map then external + NOR into the memory map. + +if LPC17_EXTNOR + +config LPC17_EXTNORSIZE + int "External NOR size" + default 0 + ---help--- + Size of the external NOR in bytes. + +endif + +config LPC17_EXTDRAM + bool "Configure external DRAM" + default n + depends on ARCH_HAVE_EXTDRAM + select ARCH_HAVE_SDRAM + ---help--- + Configure external DRAM memory and, if applicable, map then external + DRAM into the memory map. + +if LPC17_EXTDRAM + +config LPC17_EXTDRAMSIZE + int "External SDRAM size" + default 0 + ---help--- + Size of the external SDRAM in bytes. + +choice + prompt "SDRAM Width Selection" + default LPC17_SDRAM_16BIT + +config LPC17_SDRAM_8BIT + bool "8-bit" + +config LPC17_SDRAM_16BIT + bool "16-bit" + +config LPC17_SDRAM_32BIT + bool "32-bit" + +endchoice + +config LPC17_EXTDRAMHEAP + bool "Add external SDRAM to the heap" + default y + ---help--- + Add the external SDRAM into the heap. + +endif + +config LPC17_EXTSRAM0 + bool "Configure external SRAM (Bank 0)" + default n + depends on ARCH_HAVE_EXTSRAM0 + ---help--- + Configure external SRAM Bank 0 memory and, if applicable, map then + external SRAM Bank 0 into the memory map. + +if LPC17_EXTSRAM0 + +config LPC17_EXTSRAM0SIZE + int "External SRAM size" + default 0 + ---help--- + Size of the external SRAM Bank 0 in bytes. + +config LPC17_EXTSRAM0HEAP + bool "Add external SRAM (Bank 0) to the heap" + default y + ---help--- + Add external SRAM Bank 0 into the heap. + +endif +endmenu + +menu "Serial driver options" + depends on LPC17_UART0 || LPC17_UART1 || LPC17_UART2 || LPC17_UART3 || LPC17_UART4 + +config UART1_RINGINDICATOR + bool "UART1 ring indicator" + depends on LPC17_UART1 + default n + ---help--- + Enable UART1 ring indicator + +endmenu + +menu "ADC driver options" + depends on LPC17_ADC + +config ADC0_AVERAGE + int "ADC0 average" + default 200 + +config ADC0_MASK + int "ADC0 mask" + default 1 + +config ADC0_SPS + int "ADC0 SPS" + default 1000 + +config ADC_CHANLIST + bool "Use ADC channel list" + default n + ---help--- + The errata that states: "A/D Global Data register should not be used + with burst mode or hardware triggering". If this option is selected, + then the ADC driver will grab from the individual channel registers + rather than from the global data register as this is the stated + workaround in the errata. + + The ADC interrupt will trigger on conversion complete on the last + channel listed in the array g_adc_chanlist[] (as opposed to + triggering interrupt from the global DONE flag). + + If this option is enabled, then the platform specific code must do + two things: (1) define ADC_NCHANNELS in the configuration file and + (2) provide an array g_adc_chanlist[] with the channel numbers + matching the ADC0_MASK within the board-specific library. + +config ADC_BURSTMODE + bool "One interrupt at the end of all ADC cconversions" + default n + ---help--- + Select this if you want to generate only one interrupt once all selected channels has been converted by the ADC + +config ADC_NCHANNELS + int "ADC0 number of channels" + depends on ADC_CHANLIST + default 0 + ---help--- + If ADC_CHANLIST is enabled, then the platform specific code + must do two things: (1) define ADC_NCHANNELS in the configuration + file and (2) provide an array g_adc_chanlist[] with the channel + numbers matching the ADC0_MASK within the board-specific library. + +endmenu + +menu "CAN driver options" + depends on LPC17_CAN1 || LPC17_CAN2 + +config CAN_EXTID + bool "CAN extended IDs" + default n + ---help--- + Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. + +config CAN1_BAUD + int "CAN1 BAUD" + depends on LPC17_CAN1 + ---help--- + CAN1 BAUD rate. Required if LPC17_CAN1 is defined. + +config CAN2_BAUD + int "CAN2 BAUD" + depends on LPC17_CAN2 + ---help--- + CAN2 BAUD rate. Required if LPC17_CAN2 is defined. + +config CAN1_DIVISOR + int "CAN1 CCLK divisor" + depends on LPC17_CAN1 + default 4 + ---help--- + CAN1 is clocked at CCLK divided by this number. (the CCLK frequency is divided + by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + +config CAN2_DIVISOR + int "CAN2 CCLK divisor" + depends on LPC17_CAN2 + default 4 + ---help--- + CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided + by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + +config CAN_TSEG1 + int "TSEG1 quanta" + default 6 + ---help--- + The number of CAN time quanta in segment 1. Default: 6 + +config CAN_TSEG2 + int "TSEG2 quanta" + default 4 + ---help--- + The number of CAN time quanta in segment 2. Default: 7 + +config CAN_SAM + bool "CAN sampling" + default n + ---help--- + The bus is sampled 3 times (recommended for low to medium speed buses to spikes on the bus-line). + +config CAN_LOOPBACK + bool "CAN looopback mode" + default n + ---help--- + Enable CAN loopback mode + +config CAN_REGDEBUG + bool "Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level CAN debug information. Requires also DEBUG and DEBUG_CAN. + +endmenu + +config GPIO_IRQ + bool "GPIO interrupt support" + default n + ---help--- + Enable support for GPIO interrupts + +menu "I2C driver options" + depends on LPC17_I2C0 || LPC17_I2C1 || LPC17_I2C2 + +config LPC17_I2C0_FREQUENCY + int "I2C0 frequency" + depends on LPC17_I2C0 + default 100000 + +config LPC17_I2C1_FREQUENCY + int "I2C1 frequency" + depends on LPC17_I2C1 + default 100000 + +config LPC17_I2C2_FREQUENCY + int "I2C2 frequency" + depends on LPC17_I2C2 + default 100000 + +endmenu + +menu "SDIO Configuration" + depends on LPC17_SDCARD + +config SDIO_DMA + bool "Support DMA data transfers" + default y if LPC17_GPDMA + depends on LPC17_GPDMA + ---help--- + Support DMA data transfers. + Enable SD card DMA data transfers. This is a marginally optional. + For most usages, SD accesses will cause data overruns if used without + DMA. Requires LPC17_SDCARD and config LPC17_GPDMA. + +config SDIO_WIDTH_D1_ONLY + bool "Use D1 only" + default n + ---help--- + Select 1-bit transfer mode. This may be selected to force the driver + operate with only a single data line (the default is to use all + 4 SD data lines).Default: 4-bit transfer mode. + +endmenu + +menu "Ethernet driver options" + depends on LPC17_ETHERNET + +config PHY_AUTONEG + bool "Autonegiation" + ---help--- + Enable auto-negotion + +config PHY_SPEED100 + bool "100Mbit/Sec" + depends on !PHY_AUTONEG + ---help--- + Select 100Mbit vs. 10Mbit speed. + +config PHY_FDUPLEX + bool "Full duplex" + depends on !PHY_AUTONEG + ---help--- + Select full (vs. half) duplex + +config NET_EMACRAM_SIZE + int "EMAC RAM Size" + default 16384 + ---help--- + Size of EMAC RAM. Default: 16384 bytes + +config NET_NTXDESC + int "Number of Tx descriptors" + default 13 + ---help--- + Configured number of Tx descriptors. Default: 13 + +config NET_NRXDESC + int "Number of Rx descriptors" + default 13 + ---help--- + Configured number of Rx descriptors. Default: 13 + +config NET_PRIORITY + int "Ethernet interrupt priority" + default 128 + depends on ARCH_IRQPRIO && EXPERIMENTAL + ---help--- + Ethernet interrupt priority. The default is the default priority (128). + +config NET_WOL + bool "Wake-up on LAN" + default n + ---help--- + Enable Wake-up on Lan (not fully implemented). + +config NET_REGDEBUG + bool "Ethernet register-level debug" + depends on DEBUG + default n + ---help--- + Enable low level register debug. Also needs DEBUG. + +config NET_HASH + bool "Hashing" + default n + ---help--- + Enable receipt of near-perfect match frames. + +config LPC17_MULTICAST + bool "Multicast" + default y if NET_IGMP + default n if !NET_IGMP + ---help--- + Enable receipt of multicast (and unicast) frames. Automatically set + if NET_IGMP is selected. +endmenu + +menu "LCD device driver options" + depends on LPC17_LCD + +config LPC17_LCD_VRAMBASE + hex "Video RAM base address" + default 0xa0010000 + ---help--- + Base address of the video RAM frame buffer. The default is + (LPC17_EXTDRAM_CS0 + 0x00010000) + +config LPC17_LCD_REFRESH_FREQ + int "LCD refesh rate (Hz)" + default 50 + ---help--- + LCD refesh rate (Hz) + +config LPC17_LCD_BACKLIGHT + bool "Enable backlight" + default y + ---help--- + Enable backlight support. If LPC17_LCD_BACKLIGHT is selected, then + the board-specific logic must provide this lpc17_backlight() + interface so that the LCD driver can turn the backlight on and off + as necessary. You should select this option and implement + lpc17_backlight() if your board provides GPIO control over the + backlight. This interface provides only ON/OFF control of the + backlight. If you want finer control over the backlight level (for + example, using PWM), then this interface would need to be extended. + +config LPC17_LCD_TFTPANEL + bool "TFT Panel" + default y + ---help--- + TFT Panel vs. STN display. STN display panels require algorithmic + pixel pattern generation to provide pseudo gray scaling on + monochrome displays, or color creation on color displays. TFT + display panels require the digital color value of each pixel to be + applied to the display data inputs. + +config LPC17_LCD_MONOCHROME + bool "Monochrome LCD" + default n + depends on !LPC17_LCD_TFTPANEL + ---help--- + STN LCD monochrome/color selection. Selects monochrome LCD. This + selection has no meaning for a TFT panel. + +choice + prompt "Bits per pixel" + default LPC17_LCD_BPP24 if LPC17_LCD_TFTPANEL + default LPC17_LCD_BPP16_565 if !LPC17_LCD_TFTPANEL + +config LPC17_LCD_BPP1 + bool "1 bit per pixel" + +config LPC17_LCD_BPP2 + bool "2 bit per pixel" + +config LPC17_LCD_BPP4 + bool "4 bit per pixel" + +config LPC17_LCD_BPP8 + bool "8 bit per pixel" + +config LPC17_LCD_BPP16 + bool "16 bit per pixel" + depends on !LPC17_LCD_MONOCHROME + +config LPC17_LCD_BPP24 + bool "24 bit per pixel" + depends on LPC17_LCD_TFTPANEL + +config LPC17_LCD_BPP16_565 + bool "16 bpp, 5:6:5 mode" + depends on !LPC17_LCD_MONOCHROME + +config LPC17_LCD_BPP12_444 + bool "12 bpp, 4:4:4 mode" + depends on !LPC17_LCD_MONOCHROME + +endchoice + +config LPC17_LCD_BACKCOLOR + hex "Initial background color" + default 0x0 + ---help--- + Initial background color + +config LPC17_LCD_HWIDTH + int "Display width (pixels)" + default 480 + ---help--- + Horizontal width the display in pixels + +config LPC17_LCD_HPULSE + int "Horizontal pulse" + default 2 + +config LPC17_LCD_HFRONTPORCH + int "Horizontal front porch" + default 5 + +config LPC17_LCD_HBACKPORCH + int "Horizontal back porch" + default 40 + +config LPC17_LCD_VHEIGHT + int "Display height (rows)" + default 272 + ---help--- + Vertical height of the display in rows + +config LPC17_LCD_VPULSE + int "Vertical pulse" + default 2 + +config LPC17_LCD_VFRONTPORCH + int "Vertical front porch" + default 8 + +config LPC17_LCD_VBACKPORCH + int "Vertical back porch" + default 8 + +endmenu + +menu "USB device driver options" + depends on LPC17_USBDEV + +config LPC17_USBDEV_EP0_MAXSIZE + int "EP0 Max packet size" + default 64 + ---help--- + Endpoint 0 maximum packet size. Default: 64 + +config LPC17_USBDEV_FRAME_INTERRUPT + bool "USB frame interrupt" + default n + ---help--- + Handle USB Start-Of-Frame events. Enable reading SOF from interrupt + handler vs. simply reading on demand. Probably a bad idea... Unless + there is some issue with sampling the SOF from hardware asynchronously. + +config LPC17_USBDEV_EPFAST_INTERRUPT + bool "EP fast interrupt handling" + default n + ---help--- + Enable high priority interrupts. I have no idea why you might want to do that + +config LPC17_USBDEV_NDMADESCRIPTORS + int "Number of DMA descriptors" + default 8 + ---help--- + Number of DMA descriptors to allocate in SRAM. Default: 8 + +config LPC17_USBDEV_DMA + bool "Enable USB device DMA" + default n + ---help--- + Enable lpc17xx-specific DMA support + +config LPC17_USBDEV_NOVBUS + bool "Disable VBUS support" + default n + ---help--- + Define if the hardware implementation does not support the VBUS signal + +config LPC17_USBDEV_NOLED + bool "Disable USB device LCD support" + default n + ---help--- + Define if the hardware implementation does not support the LED output + +config LPC17_USBDEV_REGDEBUG + bool "Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level USB device debug information. Requires also DEBUG. + +endmenu + +menu "USB host driver options" + depends on LPC17_USBHOST + +config USBHOST_OHCIRAM_SIZE + int "OHCI RAM Size" + default 16384 + ---help--- + Total size of OHCI RAM (in AHB SRAM Bank 1). Default: 16384 + +config USBHOST_NEDS + int "Number of Endpoint Descriptors" + default 2 + ---help--- + Number of endpoint descriptors. Default: 2 + +config USBHOST_NTDS + int "Number of transfer descriptors" + default 3 + ---help--- + Number of transfer descriptors. Default: 3 + +config USBHOST_TDBUFFERS + int "Number of descriptor buffers" + default 2 + ---help--- + Number of transfer descriptor buffers. Default: 2 + +config USBHOST_TDBUFSIZE + int "Descriptor buffer size" + default 128 + ---help--- + Size of one transfer descriptor buffer. Default 128 + +config USBHOST_IOBUFSIZE + int "I/O buffer size" + default 512 + ---help--- + Size of one end-user I/O buffer. This can be zero if the application + can guarantee that all end-user I/O buffers reside in AHB SRAM. + +config LPC17_USBHOST_NPREALLOC + int "Max concurrent transfers" + default 8 if USBHOST_HUB + default 4 if !USBHOST_HUB + ---help--- + This number represents a number of pre-allocated structures to support + concurrent data transfers. This number limits that number of concurrent + asynchronous IN endpoint transfer that can be supported. + +config USBHOST_BULK_DISABLE + bool "Disable bulk EPs" + default n + ---help--- + Disable support for bulk endpoints. + +config USBHOST_INT_DISABLE + bool "Disable interrupt EPs" + default n + ---help--- + Disable support for interrupt endpoints. + +config USBHOST_ISOC_DISABLE + bool "Disable isochronous EPs" + default n + ---help--- + Disable support for isochronous endpoints. + +config LPC17_USBHOST_REGDEBUG + bool "Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level USB host debug information. Requires also DEBUG. + +endmenu diff --git a/arch/arm/src/lpc17xx/Make.defs b/arch/arm/src/lpc17xx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..2d6193a41d7625b116086e1e7d91e808fd4059ac --- /dev/null +++ b/arch/arm/src/lpc17xx/Make.defs @@ -0,0 +1,196 @@ +############################################################################ +# arch/arm/src/lpc17xx/Make.defs +# +# Copyright (C) 2010-2011, 2013-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +HEAD_ASRC = +else +HEAD_ASRC = lpc17_vectors.S +endif + +# Common ARM and Cortex-M3 files + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_checkstack.c up_vfork.c + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +# Use of common/up_etherstub.c is deprecated. The preferred mechanism is to +# use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in +# up_initialize(). Then this stub would not be needed. + +ifeq ($(CONFIG_NET),y) +ifneq ($(CONFIG_LPC17_ETHERNET),y) +CMN_CSRCS += up_etherstub.c +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +# Required LPC17xx files + +CHIP_ASRCS = + +CHIP_CSRCS = lpc17_allocateheap.c lpc17_clockconfig.c lpc17_clrpend.c +CHIP_CSRCS += lpc17_gpio.c lpc17_i2c.c lpc17_idle.c lpc17_irq.c lpc17_lowputc.c +CHIP_CSRCS += lpc17_serial.c lpc17_spi.c lpc17_ssp.c lpc17_start.c + +# Configuration-dependent LPC17xx files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc17_timerisr.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CHIP_ASRCS += lpc17_vectors.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += lpc17_userspace.c lpc17_mpuinit.c +endif + +ifeq ($(CONFIG_LPC17_EMC),y) +CHIP_CSRCS += lpc17_emc.c +endif + +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += lpc17_gpioint.c +endif + +ifeq ($(CONFIG_DEBUG_GPIO),y) +CHIP_CSRCS += lpc17_gpiodbg.c +endif + +ifeq ($(CONFIG_LPC17_LCD),y) +CHIP_CSRCS += lpc17_lcd.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += lpc17_usbdev.c +endif + +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += lpc17_usbhost.c +endif + +ifeq ($(CONFIG_LPC17_GPDMA),y) +CHIP_CSRCS += lpc17_gpdma.c +endif + +ifeq ($(CONFIG_LPC17_SDCARD),y) +CHIP_CSRCS += lpc17_sdcard.c +endif + +ifeq ($(CONFIG_NET),y) +ifeq ($(CONFIG_LPC17_ETHERNET),y) +CHIP_CSRCS += lpc17_ethernet.c +endif +endif + +ifeq ($(CONFIG_CAN),y) +CHIP_CSRCS += lpc17_can.c +endif + +ifeq ($(CONFIG_LPC17_ADC),y) +CHIP_CSRCS += lpc17_adc.c +endif + +ifeq ($(CONFIG_LPC17_DAC),y) +CHIP_CSRCS += lpc17_dac.c +endif + +ifeq ($(CONFIG_LPC17_RTC),y) +CHIP_CSRCS += lpc176x_rtc.c +endif + +ifeq ($(CONFIG_LPC17_PWM1),y) +CHIP_CSRCS += lpc17_pwm.c +endif + +ifeq ($(CONFIG_LPC17_MCPWM),y) +CHIP_CSRCS += lpc17_mcpwm.c +endif + +ifeq ($(CONFIG_LPC17_TMR0),y) +CHIP_CSRCS += lpc17_timer.c +endif diff --git a/arch/arm/src/lpc17xx/chip.h b/arch/arm/src/lpc17xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..6691ab8b00db93910fe94c84fe2d4a957ab7e595 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip.h @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "nvic.h" + +/* Include the chip capabilities file */ + +#include + +/* If the common ARMv7-M vector handling logic is used, then include the + * required vector definitions as well. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR +# if defined(LPC176x) +# include "chip/lpc176x_vectors.h" +# elif defined(LPC178x) +# include "chip/lpc178x_vectors.h" +# else +# error "No vector file for this LPC17xx family" +# endif +#endif + +/* Vector Table Offset Register (VECTAB). Redefine the mask defined in + * arch/arm/src/armv7-m/nvic.h; The LPC178x/7x User manual definitions + * do not match the ARMv7M field definitions. Any bits set above bit + * 29 would be an error and apparently the register wants 8- not 6-bit + * alignment. + */ + +#undef NVIC_VECTAB_TBLOFF_MASK +#define NVIC_VECTAB_TBLOFF_MASK (0x3fffff00) + +/* Include the memory map file. Other chip hardware files should then include + * this file for the proper setup. + */ + +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc176x_memorymap.h b/arch/arm/src/lpc17xx/chip/lpc176x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..094a47788fec81e6e009f323956838a44cac693a --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc176x_memorymap.h @@ -0,0 +1,136 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc176x_memorymap.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC176X_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC17XX_LPC176X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ + +#define LPC17_FLASH_BASE 0x00000000 /* -0x1fffffff: On-chip non-volatile memory */ +#define LPC17_SRAM_BASE 0x10000000 /* -0x10007fff: On-chip SRAM (devices <=32Kb) */ +#define LPC17_ROM_BASE 0x1fff0000 /* -0x1fffffff: 8Kb Boot ROM with flash services */ +#define LPC17_AHBSRAM_BASE 0x20000000 /* -0x3fffffff: On-chip AHB SRAM (devices >32Kb) */ +# define LPC17_SRAM_BANK0 0x2007c000 /* -0x2007ffff: On-chip AHB SRAM Bank0 (devices >=32Kb) */ +# define LPC17_SRAM_BANK1 0x20080000 /* -0x2008ffff: On-chip AHB SRAM Bank1 (devices 64Kb) */ +#define LPC17_GPIO_BASE 0x2009c000 /* -0x2009ffff: GPIO */ +#define LPC17_APB_BASE 0x40000000 /* -0x5fffffff: APB Peripherals */ +# define LPC17_APB0_BASE 0x40000000 /* -0x4007ffff: APB0 Peripherals */ +# define LPC17_APB1_BASE 0x40080000 /* -0x400fffff: APB1 Peripherals */ +# define LPC17_AHB_BASE 0x50000000 /* -0x501fffff: DMA Controller, Ethernet, and USB */ +#define LPC17_CORTEXM3_BASE 0xe0000000 /* -0xe00fffff: (see armv7-m/nvic.h) */ +#define LPC17_SCS_BASE 0xe000e000 +#define LPC17_DEBUGMCU_BASE 0xe0042000 + +/* AHB SRAM Bank sizes **************************************************************/ + +#define LPC17_BANK0_SIZE (16*1024) /* Size of AHB SRAM Bank0 (if present) */ +#define LPC17_BANK1_SIZE (16*1024) /* Size of AHB SRAM Bank1 (if present) */ + +/* APB0 Peripherals *****************************************************************/ + +#define LPC17_WDT_BASE 0x40000000 /* -0x40003fff: Watchdog timer */ +#define LPC17_TMR0_BASE 0x40004000 /* -0x40007fff: Timer 0 */ +#define LPC17_TMR1_BASE 0x40008000 /* -0x4000bfff: Timer 1 */ +#define LPC17_UART0_BASE 0x4000c000 /* -0x4000ffff: UART 0 */ +#define LPC17_UART1_BASE 0x40010000 /* -0x40013fff: UART 1 */ + /* -0x40017fff: Reserved */ +#define LPC17_PWM1_BASE 0x40018000 /* -0x4001bfff: PWM 1 */ +#define LPC17_I2C0_BASE 0x4001c000 /* -0x4001ffff: I2C 0 */ +#define LPC17_SPI_BASE 0x40020000 /* -0x40023fff: SPI */ +#define LPC17_RTC_BASE 0x40024000 /* -0x40027fff: RTC + backup registers */ +#define LPC17_GPIOINT_BASE 0x40028000 /* -0x4002bfff: GPIO interrupts */ +#define LPC17_PINCONN_BASE 0x4002c000 /* -0x4002ffff: Pin connect block */ +#define LPC17_SSP1_BASE 0x40030000 /* -0x40033fff: SSP 1 */ +#define LPC17_ADC_BASE 0x40034000 /* -0x40037fff: ADC */ +#define LPC17_CANAFRAM_BASE 0x40038000 /* -0x4003bfff: CAN acceptance filter (AF) RAM */ +#define LPC17_CANAF_BASE 0x4003c000 /* -0x4003ffff: CAN acceptance filter (AF) registers */ +#define LPC17_CAN_BASE 0x40040000 /* -0x40043fff: CAN common registers */ +#define LPC17_CAN1_BASE 0x40044000 /* -0x40047fff: CAN controller l */ +#define LPC17_CAN2_BASE 0x40048000 /* -0x4004bfff: CAN controller 2 */ + /* -0x4005bfff: Reserved */ +#define LPC17_I2C1_BASE 0x4005c000 /* -0x4005ffff: I2C 1 */ + /* -0x4007ffff: Reserved */ + +/* APB1 Peripherals *****************************************************************/ + + /* -0x40087fff: Reserved */ +#define LPC17_SSP0_BASE 0x40088000 /* -0x4008bfff: SSP 0 */ +#define LPC17_DAC_BASE 0x4008c000 /* -0x4008ffff: DAC */ +#define LPC17_TMR2_BASE 0x40090000 /* -0x40093fff: Timer 2 */ +#define LPC17_TMR3_BASE 0x40094000 /* -0x40097fff: Timer 3 */ +#define LPC17_UART2_BASE 0x40098000 /* -0x4009bfff: UART 2 */ +#define LPC17_UART3_BASE 0x4009c000 /* -0x4009ffff: UART 3 */ +#define LPC17_I2C2_BASE 0x400a0000 /* -0x400a3fff: I2C 2 */ + /* -0x400a7fff: Reserved */ +#define LPC17_I2S_BASE 0x400a8000 /* -0x400abfff: I2S */ + /* -0x400affff: Reserved */ +#define LPC17_RIT_BASE 0x400b0000 /* -0x400b3fff: Repetitive interrupt timer */ + /* -0x400b7fff: Reserved */ +#define LPC17_MCPWM_BASE 0x400b8000 /* -0x400bbfff: Motor control PWM */ +#define LPC17_QEI_BASE 0x400bc000 /* -0x400bffff: Quadrature encoder interface */ + /* -0x400fbfff: Reserved */ +#define LPC17_SYSCON_BASE 0x400fc000 /* -0x400fffff: System control */ + +/* AHB Peripherals ******************************************************************/ + +#define LPC17_ETH_BASE 0x50000000 /* -0x50003fff: Ethernet controller */ +#define LPC17_GPDMA_BASE 0x50004000 /* -0x50007fff: GPDMA controller */ +#define LPC17_USB_BASE 0x5000c000 /* -0x5000cfff: USB controller */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC176X_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc176x_pinconfig.h b/arch/arm/src/lpc17xx/chip/lpc176x_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..cd80c602a224d82fef60d8958d7d5a212eea61ae --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc176x_pinconfig.h @@ -0,0 +1,234 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc176x_pinconfig.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO pin definitions *************************************************************/ +/* NOTE that functions have a alternate pins that can be selected. These alternates + * are identified with a numerica suffix like _1, _2, or _3. Your board.h file + * should select the correct alternative for your board by including definitions + * such as: + * + * #define GPIO_UART1_RXD GPIO_UART1_RXD_1 + * + * (without the suffix) + */ + +#define GPIO_CAN1_RD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_UART3_TXD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_I2C1_SDA_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_CAN1_TD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_UART3_RXD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_I2C1_SCL_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_UART0_TXD (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) +#define GPIO_AD0p7 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) +#define GPIO_UART0_RXD (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN3) +#define GPIO_AD0p6 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN3) +#define GPIO_I2S_RXCLK_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_CAN2_RD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_CAP2p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_I2S_RXWS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_CAN2_TD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_CAP2p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_I2S_RXSDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_SSP1_SSEL (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_MAT2p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_I2S_TXCLK_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_SSP1_SCK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_MAT2p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_I2S_TXWS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_SSP1_MISO (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_MAT2p2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_I2S_TXSDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_SSP1_MOSI (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_MAT2p3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_UART2_TXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_MAT3p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_UART2_RXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_I2C2_SCL (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_MAT3p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_UART1_TXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) +#define GPIO_SSP0_SCK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) +#define GPIO_SPI_SCK (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) +#define GPIO_UART1_RXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) +#define GPIO_SSP0_SSEL_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) +#define GPIO_SPI_SSEL (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) +#define GPIO_UART1_CTS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_SSP0_MISO_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_SPI_MISO (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_UART1_DCD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_SSP0_MOSI_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_SPI_MOSI (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_UART1_DSR_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN19) +#define GPIO_I2C1_SDA_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN19) +#define GPIO_UART1_DTR_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN20) +#define GPIO_I2C1_SCL_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN20) +#define GPIO_UART1_RI_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_CAN1_RD_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_UART1_RTS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_CAN1_TD_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_AD0p0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN23) +#define GPIO_I2S_RXCLK_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN23) +#define GPIO_CAP3p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN23) +#define GPIO_AD0p1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN24) +#define GPIO_I2S_RXWS_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN24) +#define GPIO_CAP3p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN24) +#define GPIO_AD0p2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN25) +#define GPIO_I2S_RXSDA_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN25) +#define GPIO_UART3_TXD_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN25) +#define GPIO_AD0p3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN26) +#define GPIO_AOUT (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN26) +#define GPIO_UART3_RXD_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN26) +#define GPIO_I2C0_SDA (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN27) +#define GPIO_USB_SDA (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN27) +#define GPIO_I2C0_SCL (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN28) +#define GPIO_USB_SCL (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN28) +#define GPIO_USB_DP (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN29) +#define GPIO_USB_DM (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN30) +#define GPIO_ENET_TXD0 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_ENET_TXD1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_ENET_TXEN (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN4) +#define GPIO_ENET_CRS (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN8) +#define GPIO_ENET_RXD0 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN9) +#define GPIO_ENET_RXD1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN10) +#define GPIO_ENET_RXER (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN14) +#define GPIO_ENET_REFCLK (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN15) +#define GPIO_ENET_MDC_1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN16) +#define GPIO_ENET_MDIO_1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN17) +#define GPIO_USB_UPLED (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_PWM1p1_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_CAP1p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_MCPWM_MCOA0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_USB_PPWR (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_CAP1p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_MCPWM_MCI0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_PWM1p2_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_SSP0_SCK_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_MCPWM_MCABORT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_PWM1p3_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_SSP0_SSEL_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_MCPWM_MCOB0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_USB_PWRD (GPIO_ALT2 | GPIO_PULLDN | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_MAT1p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_MCPWM_MCI1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_PWM1p4_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_SSP0_MISO_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_MCPWM_MCI2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_PWM1p5_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_SSP0_MOSI_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_MCPWM_MCOA1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_MAT1p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_MCPWM_MCOB1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_PWM1p6_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_CAP0p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_CLKOUT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_USB_OVRCR (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_CAP0p1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_MCPWM_MCOA2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_PCAP1p0_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_MAT0p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_MCPWM_MCOB2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_PCAP1p1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_MAT0p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_USB_VBUS (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_AD0p4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_SSP1_SCK_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN31) +#define GPIO_AD0p5 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN31) +#define GPIO_PWM1p1_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN0) +#define GPIO_UART1_TXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN0) +#define GPIO_PWM1p2_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN1) +#define GPIO_UART1_RXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN1) +#define GPIO_PWM1p3_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_UART1_CTS_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_PWM1p4_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_UART1_DCD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_PWM1p5_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_UART1_DSR_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_PWM1p6_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_UART1_DTR_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_PCAP1p0_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_UART1_RI_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_CAN2_RD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_UART1_RTS_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_CAN2_TD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_UART2_TXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_ENET_MDC_2 (GPIO_ALT3 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_USB_CONNECT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_UART2_RXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_ENET_MDIO_2 (GPIO_ALT3 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_EINT0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN10) +#define GPIO_NMI (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN10) +#define GPIO_EINT1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN11) +#define GPIO_I2S_TXCLK_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN11) +#define GPIO_PEINT2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_I2S_TXWS_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_EINT3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_I2S_TXSDA_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_MAT0p0_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN25) +#define GPIO_PWM1p2_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN25) +#define GPIO_STCLK (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_MAT0p1_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_PWM1p3_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_RXMCLK (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_MAT2p0_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_UART3_TXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_TXMCLK (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_MAT2p1_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_UART3_RXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONFIG_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc176x_pinconn.h b/arch/arm/src/lpc17xx/chip/lpc176x_pinconn.h new file mode 100644 index 0000000000000000000000000000000000000000..6d5b05ba9e3b17ac43c3ce2dccd0663cc4df529d --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc176x_pinconn.h @@ -0,0 +1,635 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc176x_pinconn.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONN_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_PINCONN_PINSEL0_OFFSET 0x0000 /* Pin function select register 0 */ +#define LPC17_PINCONN_PINSEL1_OFFSET 0x0004 /* Pin function select register 1 */ +#define LPC17_PINCONN_PINSEL2_OFFSET 0x0008 /* Pin function select register 2 */ +#define LPC17_PINCONN_PINSEL3_OFFSET 0x000c /* Pin function select register 3 */ +#define LPC17_PINCONN_PINSEL4_OFFSET 0x0010 /* Pin function select register 4 */ +#define LPC17_PINCONN_PINSEL7_OFFSET 0x001c /* Pin function select register 7 */ +#define LPC17_PINCONN_PINSEL8_OFFSET 0x0020 /* Pin function select register 8 */ +#define LPC17_PINCONN_PINSEL9_OFFSET 0x0024 /* Pin function select register 9 */ +#define LPC17_PINCONN_PINSEL10_OFFSET 0x0028 /* Pin function select register 10 */ +#define LPC17_PINCONN_PINMODE0_OFFSET 0x0040 /* Pin mode select register 0 */ +#define LPC17_PINCONN_PINMODE1_OFFSET 0x0044 /* Pin mode select register 1 */ +#define LPC17_PINCONN_PINMODE2_OFFSET 0x0048 /* Pin mode select register 2 */ +#define LPC17_PINCONN_PINMODE3_OFFSET 0x004c /* Pin mode select register 3 */ +#define LPC17_PINCONN_PINMODE4_OFFSET 0x0050 /* Pin mode select register 4 */ +#define LPC17_PINCONN_PINMODE5_OFFSET 0x0054 /* Pin mode select register 5 */ +#define LPC17_PINCONN_PINMODE6_OFFSET 0x0058 /* Pin mode select register 6 */ +#define LPC17_PINCONN_PINMODE7_OFFSET 0x005c /* Pin mode select register 7 */ +#define LPC17_PINCONN_PINMODE9_OFFSET 0x0064 /* Pin mode select register 9 */ +#define LPC17_PINCONN_ODMODE0_OFFSET 0x0068 /* Open drain mode control register 0 */ +#define LPC17_PINCONN_ODMODE1_OFFSET 0x006c /* Open drain mode control register 1 */ +#define LPC17_PINCONN_ODMODE2_OFFSET 0x0070 /* Open drain mode control register 2 */ +#define LPC17_PINCONN_ODMODE3_OFFSET 0x0074 /* Open drain mode control register 3 */ +#define LPC17_PINCONN_ODMODE4_OFFSET 0x0078 /* Open drain mode control register 4 */ +#define LPC17_PINCONN_I2CPADCFG_OFFSET 0x007c /* I2C Pin Configuration register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_PINCONN_PINSEL0 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL0_OFFSET) +#define LPC17_PINCONN_PINSEL1 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL1_OFFSET) +#define LPC17_PINCONN_PINSEL2 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL2_OFFSET) +#define LPC17_PINCONN_PINSEL3 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL3_OFFSET) +#define LPC17_PINCONN_PINSEL4 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL4_OFFSET) +#define LPC17_PINCONN_PINSEL7 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL7_OFFSET) +#define LPC17_PINCONN_PINSEL8 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL8_OFFSET) +#define LPC17_PINCONN_PINSEL9 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL9_OFFSET) +#define LPC17_PINCONN_PINSEL10 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINSEL10_OFFSET) +#define LPC17_PINCONN_PINMODE0 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE0_OFFSET) +#define LPC17_PINCONN_PINMODE1 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE1_OFFSET) +#define LPC17_PINCONN_PINMODE2 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE2_OFFSET) +#define LPC17_PINCONN_PINMODE3 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE3_OFFSET) +#define LPC17_PINCONN_PINMODE4 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE4_OFFSET) +#define LPC17_PINCONN_PINMODE5 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE5_OFFSET) +#define LPC17_PINCONN_PINMODE6 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE6_OFFSET) +#define LPC17_PINCONN_PINMODE7 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE7_OFFSET) +#define LPC17_PINCONN_PINMODE9 (LPC17_PINCONN_BASE+LPC17_PINCONN_PINMODE9_OFFSET) +#define LPC17_PINCONN_ODMODE0 (LPC17_PINCONN_BASE+LPC17_PINCONN_ODMODE0_OFFSET) +#define LPC17_PINCONN_ODMODE1 (LPC17_PINCONN_BASE+LPC17_PINCONN_ODMODE1_OFFSET) +#define LPC17_PINCONN_ODMODE2 (LPC17_PINCONN_BASE+LPC17_PINCONN_ODMODE2_OFFSET) +#define LPC17_PINCONN_ODMODE3 (LPC17_PINCONN_BASE+LPC17_PINCONN_ODMODE3_OFFSET) +#define LPC17_PINCONN_ODMODE4 (LPC17_PINCONN_BASE+LPC17_PINCONN_ODMODE4_OFFSET) +#define LPC17_PINCONN_I2CPADCFG (LPC17_PINCONN_BASE+LPC17_PINCONN_I2CPADCFG_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Pin Function Select register 0 (PINSEL0: 0x4002c000) */ + +#define PINCONN_PINSEL_GPIO (0) +#define PINCONN_PINSEL_ALT1 (1) +#define PINCONN_PINSEL_ALT2 (2) +#define PINCONN_PINSEL_ALT3 (3) +#define PINCONN_PINSEL_MASK (3) + +#define PINCONN_PINSELL_SHIFT(n) ((n) << 1) /* n=0,1,..,15 */ +#define PINCONN_PINSELL_MASK(n) (3 << PINCONN_PINSELL_SHIFT(n)) +#define PINCONN_PINSELH_SHIFT(n) (((n)-16) << 1) /* n=16,17,..31 */ +#define PINCONN_PINSELH_MASK(n) (3 << PINCONN_PINSELH_SHIFT(n)) + +#define PINCONN_PINSEL0_P0_SHIFT(n) PINCONN_PINSELL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINSEL0_P0_MASK(n) PINCONN_PINSELL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINSEL0_P0p0_SHIFT (0) /* Bits 0-1: P0.0 00=GPIO 01=RD1 10=TXD3 11=SDA1 */ +#define PINCONN_PINSEL0_P0p0_MASK (3 << PINCONN_PINSEL0_P0p0_SHIFT) +#define PINCONN_PINSEL0_P0p1_SHIFT (2) /* Bits 2-3: P0.1 00=GPIO 01=TD1 10=RXD3 11=SCL1 */ +#define PINCONN_PINSEL0_P0p1_MASK (3 << PINCONN_PINSEL0_P0p1_SHIFT) +#define PINCONN_PINSEL0_P0p2_SHIFT (4) /* Bits 4-5: P0.2 00=GPIO 01=TXD0 10=AD0.7 11=Reserved */ +#define PINCONN_PINSEL0_P0p2_MASK (3 << PINCONN_PINSEL0_P0p2_SHIFT) +#define PINCONN_PINSEL0_P0p3_SHIFT (6) /* Bits 6-7: P0.3 00=GPIO 01=RXD0 10=AD0.6 11=Reserved */ +#define PINCONN_PINSEL0_P0p3_MASK (3 << PINCONN_PINSEL0_P0p3_SHIFT) +#define PINCONN_PINSEL0_P0p4_SHIFT (8) /* Bits 8-9: P0.4 00=GPIO 01=I2SRX_CLK 10=RD2 11=CAP2.0 */ +#define PINCONN_PINSEL0_P0p4_MASK (3 << PINCONN_PINSEL0_P0p4_SHIFT) +#define PINCONN_PINSEL0_P0p5_SHIFT (10) /* Bits 10-11: P0.5 00=GPIO 01=I2SRX_WS 10=TD2 11=CAP2.1 */ +#define PINCONN_PINSEL0_P0p5_MASK (3 << PINCONN_PINSEL0_P0p5_SHIFT) +#define PINCONN_PINSEL0_P0p6_SHIFT (12) /* Bits 12-13: P0.6 00=GPIO 01=I2SRX_SDA 10=SSEL1 11=MAT2.0 */ +#define PINCONN_PINSEL0_P0p6_MASK (3 << PINCONN_PINSEL0_P0p6_SHIFT) +#define PINCONN_PINSEL0_P0p7_SHIFT (14) /* Bits 14-15: P0.7 00=GPIO 01=I2STX_CLK 10=SCK1 11=MAT2.1 */ +#define PINCONN_PINSEL0_P0p7_MASK (3 << PINCONN_PINSEL0_P0p7_SHIFT) +#define PINCONN_PINSEL0_P0p8_SHIFT (16) /* Bits 16-17: P0.8 00=GPIO 01=I2STX_WS 10=MISO1 11=MAT2.2 */ +#define PINCONN_PINSEL0_P0p8_MASK (3 << PINCONN_PINSEL0_P0p8_SHIFT) +#define PINCONN_PINSEL0_P0p9_SHIFT (18) /* Bits 18-19: P0.9 00=GPIO 01=I2STX_SDA 10=MOSI1 11=MAT2.3 */ +#define PINCONN_PINSEL0_P0p9_MASK (3 << PINCONN_PINSEL0_P0p9_SHIFT) +#define PINCONN_PINSEL0_P0p10_SHIFT (20) /* Bits 20-21: P0.10 00=GPIO 01=TXD2 10=SDA2 11=MAT3.0 */ +#define PINCONN_PINSEL0_P0p10_MASK (3 << PINCONN_PINSEL0_P0p10_SHIFT) +#define PINCONN_PINSEL0_P0p11_SHIFT (22) /* Bits 22-23: P0.11 00=GPIO 01=RXD2 10=SCL2 11=MAT3.1 */ +#define PINCONN_PINSEL0_P0p11_MASK (3 << PINCONN_PINSEL0_P0p11_SHIFT) + /* Bits 24-29: Reserved */ +#define PINCONN_PINSEL0_P0p15_SHIFT (30) /* Bits 30-31: P0.15 00=GPIO 01=TXD1 10=SCK0 11=SCK */ +#define PINCONN_PINSEL0_P0p15_MASK (3 << PINCONN_PINSEL0_P0p15_SHIFT) + +/* Pin Function Select Register 1 (PINSEL1: 0x4002c004) */ + +#define PINCONN_PINSEL1_P0_SHIFT(n) PINCONN_PINSELH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINSEL1_P0_MASK(n) PINCONN_PINSELH_MASK(n) /* n=16,17,..31 */ + +#define PINCONN_PINSEL1_P0p16_SHIFT (0) /* Bits 0-1: P0.16 00=GPIO 01=RXD1 10=SSEL0 11=SSEL */ +#define PINCONN_PINSEL1_P0p16_MASK (3 << PINCONN_PINSEL1_P0p16_SHIFT) +#define PINCONN_PINSEL1_P0p17_SHIFT (2) /* Bits 2-3: P0.17 00=GPIO 01=CTS1 10=MISO0 11=MISO */ +#define PINCONN_PINSEL1_P0p17_MASK (3 << PINCONN_PINSEL1_P0p17_SHIFT) +#define PINCONN_PINSEL1_P0p18_SHIFT (4) /* Bits 4-5: P0.18 00=GPIO 01=DCD1 10=MOSI0 11=MOSI */ +#define PINCONN_PINSEL1_P0p18_MASK (3 << PINCONN_PINSEL1_P0p18_SHIFT) +#define PINCONN_PINSEL1_P0p19_SHIFT (6) /* Bits 6-7: P0.19 00=GPIO 01=DSR1 10=Reserved 11=SDA1 */ +#define PINCONN_PINSEL1_P0p19_MASK (3 << PINCONN_PINSEL1_P0p19_SHIFT) +#define PINCONN_PINSEL1_P0p20_SHIFT (8) /* Bits 8-9: P0.20 00=GPIO 01=DTR1 10=Reserved 11=SCL1 */ +#define PINCONN_PINSEL1_P0p20_MASK (3 << PINCONN_PINSEL1_P0p20_SHIFT) +#define PINCONN_PINSEL1_P0p21_SHIFT (10) /* Bits 10-11: P0.21 00=GPIO 01=RI1 10=Reserved 11=RD1 */ +#define PINCONN_PINSEL1_P0p21_MASK (3 << PINCONN_PINSEL1_P0p21_SHIFT) +#define PINCONN_PINSEL1_P0p22_SHIFT (12) /* Bits 12-13: P0.22 00=GPIO 01=RTS1 10=Reserved 11=TD1 */ +#define PINCONN_PINSEL1_P0p22_MASK (3 << PINCONN_PINSEL1_P0p22_SHIFT) +#define PINCONN_PINSEL1_P0p23_SHIFT (14) /* Bits 14-15: P0.23 00=GPIO 01=AD0.0 10=I2SRX_CLK 11=CAP3.0 */ +#define PINCONN_PINSEL1_P0p23_MASK (3 << PINCONN_PINSEL1_P0p23_SHIFT) +#define PINCONN_PINSEL1_P0p24_SHIFT (16) /* Bits 16-17: P0.24 00=GPIO 01=AD0.1 10=I2SRX_WS 11=CAP3.1 */ +#define PINCONN_PINSEL1_P0p24_MASK (3 << PINCONN_PINSEL1_P0p24_SHIFT) +#define PINCONN_PINSEL1_P0p25_SHIFT (18) /* Bits 18-19: P0.25 00=GPIO 01=AD0.2 10=I2SRX_SDA 11=TXD3 */ +#define PINCONN_PINSEL1_P0p25_MASK (3 << PINCONN_PINSEL1_P0p25_SHIFT) +#define PINCONN_PINSEL1_P0p26_SHIFT (20) /* Bits 20-21: P0.26 00=GPIO 01=AD0.3 10=AOUT 11=RXD3 */ +#define PINCONN_PINSEL1_P0p26_MASK (3 << PINCONN_PINSEL1_P0p26_SHIFT) +#define PINCONN_PINSEL1_P0p27_SHIFT (22) /* Bits 22-23: P0.27 00=GPIO 01=SDA0 10=USB_SDA 11=Reserved */ +#define PINCONN_PINSEL1_P0p27_MASK (3 << PINCONN_PINSEL1_P0p27_SHIFT) +#define PINCONN_PINSEL1_P0p28_SHIFT (24) /* Bits 24-25: P0.28 00=GPIO 01=SCL0 10=USB_SCL 11=Reserved */ +#define PINCONN_PINSEL1_P0p28_MASK (3 << PINCONN_PINSEL1_P0p28_SHIFT) +#define PINCONN_PINSEL1_P0p29_SHIFT (26) /* Bits 26-27: P0.29 00=GPIO 01=USB_D+ 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL1_P0p29_MASK (3 << PINCONN_PINSEL1_P0p29_SHIFT) +#define PINCONN_PINSEL1_P0p30_SHIFT (28) /* Bits 28-29: P0.30 00=GPIO 01=USB_D- 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL1_P0p30_MASK (3 << PINCONN_PINSEL1_P0p30_SHIFT) + /* Bits 30-31: Reserved */ +/* Pin Function Select register 2 (PINSEL2: 0x4002c008) */ + +#define PINCONN_PINSEL2_P1_SHIFT(n) PINCONN_PINSELL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINSEL2_P1_MASK(n) PINCONN_PINSELL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINSEL2_P1p0_SHIFT (0) /* Bits 0-1: P1.0 00=GPIO 01=ENET_TXD0 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p0_MASK (3 << PINCONN_PINSEL2_P1p0_SHIFT) +#define PINCONN_PINSEL2_P1p1_SHIFT (2) /* Bits 2-3: P1.1 00=GPIO 01=ENET_TXD1 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p1_MASK (3 << PINCONN_PINSEL2_P1p1_SHIFT) + /* Bits 4-7: Reserved */ +#define PINCONN_PINSEL2_P1p4_SHIFT (8) /* Bits 8-9: P1.4 00=GPIO 01=ENET_TX_EN 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p4_MASK (3 << PINCONN_PINSEL2_P1p4_SHIFT) + /* Bits 10-15: Reserved */ +#define PINCONN_PINSEL2_P1p8_SHIFT (16) /* Bits 16-17: P1.8 00=GPIO 01=ENET_CRS 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p8_MASK (3 << PINCONN_PINSEL2_P1p8_SHIFT) +#define PINCONN_PINSEL2_P1p9_SHIFT (18) /* Bits 18-19: P1.9 00=GPIO 01=ENET_RXD0 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p9_MASK (3 << PINCONN_PINSEL2_P1p9_SHIFT) +#define PINCONN_PINSEL2_P1p10_SHIFT (20) /* Bits 20-21: P1.10 00=GPIO 01=ENET_RXD1 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p10_MASK (3 << PINCONN_PINSEL2_P1p10_SHIFT) + /* Bits 22-27: Reserved */ +#define PINCONN_PINSEL2_P1p14_SHIFT (28) /* Bits 28-29: P1.14 00=GPIO 01=ENET_RX_ER 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p14_MASK (3 << PINCONN_PINSEL2_P1p14_SHIFT) +#define PINCONN_PINSEL2_P1p15_SHIFT (30) /* Bits 30-31: P1.15 00=GPIO 01=ENET_REF_CLK 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL2_P1p15_MASK (3 << PINCONN_PINSEL2_P1p15_SHIFT) + +/* Pin Function Select Register 3 (PINSEL3: 0x4002c00c) */ + +#define PINCONN_PINSEL3_P1_SHIFT(n) PINCONN_PINSELH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINSEL3_P1_MASK(n) PINCONN_PINSELH_MASK(n) /* n=16,17,..31 */ + +#define PINCONN_PINSEL3_P1p16_SHIFT (0) /* Bits 0-1: P1.16 00=GPIO 01=ENET_MDC 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL3_P1p16_MASK (3 << PINCONN_PINSEL3_P1p16_SHIFT) +#define PINCONN_PINSEL3_P1p17_SHIFT (2) /* Bits 2-3: P1.17 00=GPIO 01=ENET_MDIO 10=Reserved 11=Reserved */ +#define PINCONN_PINSEL3_P1p17_MASK (3 << PINCONN_PINSEL3_P1p17_SHIFT) +#define PINCONN_PINSEL3_P1p18_SHIFT (4) /* Bits 4-5: P1.18 00=GPIO 01=USB_UP_LED 10=PWM1.1 11=CAP1.0 */ +#define PINCONN_PINSEL3_P1p18_MASK (3 << PINCONN_PINSEL3_P1p18_SHIFT) +#define PINCONN_PINSEL3_P1p19_SHIFT (6) /* Bits 6-7: P1.19 00=GPIO 01=MCOA0 10=USB_PPWR 11=CAP1.1 */ +#define PINCONN_PINSEL3_P1p19_MASK (3 << PINCONN_PINSEL3_P1p19_SHIFT) +#define PINCONN_PINSEL3_P1p20_SHIFT (8) /* Bits 8-9: P1.20 00=GPIO 01=MCI0 10=PWM1.2 11=SCK0 */ +#define PINCONN_PINSEL3_P1p20_MASK (3 << PINCONN_PINSEL3_P1p20_SHIFT) +#define PINCONN_PINSEL3_P1p21_SHIFT (10) /* Bits 10-11: P1.21 00=GPIO 01=MCABORT 10=PWM1.3 11=SSEL0 */ +#define PINCONN_PINSEL3_P1p21_MASK (3 << PINCONN_PINSEL3_P1p21_SHIFT) +#define PINCONN_PINSEL3_P1p22_SHIFT (12) /* Bits 12-13: P1.22 00=GPIO 01=MCOB0 10=USB_PWRD 11=MAT1.0 */ +#define PINCONN_PINSEL3_P1p22_MASK (3 << PINCONN_PINSEL3_P1p22_SHIFT) +#define PINCONN_PINSEL3_P1p23_SHIFT (14) /* Bits 14-15: P1.23 00=GPIO 01=MCI1 10=PWM1.4 11=MISO0 */ +#define PINCONN_PINSEL3_P1p23_MASK (3 << PINCONN_PINSEL3_P1p23_SHIFT) +#define PINCONN_PINSEL3_P1p24_SHIFT (16) /* Bits 16-17: P1.24 00=GPIO 01=MCI2 10=PWM1.5 11=MOSI0 */ +#define PINCONN_PINSEL3_P1p24_MASK (3 << PINCONN_PINSEL3_P1p24_SHIFT) +#define PINCONN_PINSEL3_P1p25_SHIFT (18) /* Bits 18-19: P1.25 00=GPIO 01=MCOA1 10=Reserved 11=MAT1.1 */ +#define PINCONN_PINSEL3_P1p25_MASK (3 << PINCONN_PINSEL3_P1p25_SHIFT) +#define PINCONN_PINSEL3_P1p26_SHIFT (20) /* Bits 20-21: P1.26 00=GPIO 01=MCOB1 10=PWM1.6 11=CAP0.0 */ +#define PINCONN_PINSEL3_P1p26_MASK (3 << PINCONN_PINSEL3_P1p26_SHIFT) +#define PINCONN_PINSEL3_P1p27_SHIFT (22) /* Bits 22-23: P1.27 00=GPIO 01=CLKOUT 10=USB_OVRCR 11=CAP0.1 */ +#define PINCONN_PINSEL3_P1p27_MASK (3 << PINCONN_PINSEL3_P1p27_SHIFT) +#define PINCONN_PINSEL3_P1p28_SHIFT (24) /* Bits 24-25: P1.28 00=GPIO 01=MCOA2 10=PCAP1.0 11=MAT0.0 */ +#define PINCONN_PINSEL3_P1p28_MASK (3 << PINCONN_PINSEL3_P1p28_SHIFT) +#define PINCONN_PINSEL3_P1p29_SHIFT (26) /* Bits 26-27: P1.29 00=GPIO 01=MCOB2 10=PCAP1.1 11=MAT0.1 */ +#define PINCONN_PINSEL3_P1p29_MASK (3 << PINCONN_PINSEL3_P1p29_SHIFT) +#define PINCONN_PINSEL3_P1p30_SHIFT (28) /* Bits 28-29: P1.30 00=GPIO 01=Reserved 10=VBUS 11=AD0.4 */ +#define PINCONN_PINSEL3_P1p30_MASK (3 << PINCONN_PINSEL3_P1p30_SHIFT) +#define PINCONN_PINSEL3_P1p31_SHIFT (30) /* Bits 30-31: P1.31 00=GPIO 01=Reserved 10=SCK1 11=AD0.5 */ +#define PINCONN_PINSEL3_P1p31_MASK (3 << PINCONN_PINSEL3_P1p31_SHIFT) + +/* Pin Function Select Register 4 (PINSEL4: 0x4002c010) */ + +#define PINCONN_PINSEL4_P2_SHIFT(n) PINCONN_PINSELL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINSEL4_P2_MASK(n) PINCONN_PINSELL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINSEL4_P2p0_SHIFT (0) /* Bits 0-1: P2.0 00=GPIO 01=PWM1.1 10=TXD1 11=Reserved */ +#define PINCONN_PINSEL4_P2p0_MASK (3 << PINCONN_PINSEL4_P2p0_SHIFT) +#define PINCONN_PINSEL4_P2p1_SHIFT (2) /* Bits 2-3: P2.1 00=GPIO 01=PWM1.2 10=RXD1 11=Reserved */ +#define PINCONN_PINSEL4_P2p1_MASK (3 << PINCONN_PINSEL4_P2p1_SHIFT) +#define PINCONN_PINSEL4_P2p2_SHIFT (4) /* Bits 4-5: P2.2 00=GPIO 01=PWM1.3 10=CTS1 11=Reserved */ +#define PINCONN_PINSEL4_P2p2_MASK (3 << PINCONN_PINSEL4_P2p2_SHIFT) +#define PINCONN_PINSEL4_P2p3_SHIFT (6) /* Bits 6-7: P2.3 00=GPIO 01=PWM1.4 10=DCD1 11=Reserved */ +#define PINCONN_PINSEL4_P2p3_MASK (3 << PINCONN_PINSEL4_P2p3_SHIFT) +#define PINCONN_PINSEL4_P2p4_SHIFT (8) /* Bits 8-9: P2.4 00=GPIO 01=PWM1.5 10=DSR1 11=Reserved */ +#define PINCONN_PINSEL4_P2p4_MASK (3 << PINCONN_PINSEL4_P2p4_SHIFT) +#define PINCONN_PINSEL4_P2p5_SHIFT (10) /* Bits 10-11: P2.5 00=GPIO 01=PWM1.6 10=DTR1 11=Reserved */ +#define PINCONN_PINSEL4_P2p5_MASK (3 << PINCONN_PINSEL4_P2p5_SHIFT) +#define PINCONN_PINSEL4_P2p6_SHIFT (12) /* Bits 12-13: P2.6 00=GPIO 01=PCAP1.0 10=RI1 11=Reserved */ +#define PINCONN_PINSEL4_P2p6_MASK (3 << PINCONN_PINSEL4_P2p6_SHIFT) +#define PINCONN_PINSEL4_P2p7_SHIFT (14) /* Bits 14-15: P2.7 00=GPIO 01=RD2 10=RTS1 11=Reserved */ +#define PINCONN_PINSEL4_P2p7_MASK (3 << PINCONN_PINSEL4_P2p7_SHIFT) +#define PINCONN_PINSEL4_P2p8_SHIFT (16) /* Bits 16-17: P2.8 00=GPIO 01=TD2 10=TXD2 11=ENET_MDC */ +#define PINCONN_PINSEL4_P2p8_MASK (3 << PINCONN_PINSEL4_P2p8_SHIFT) +#define PINCONN_PINSEL4_P2p9_SHIFT (18) /* Bits 18-19: P2.9 00=GPIO 01=USB_CONNECT 10=RXD2 11=ENET_MDIO */ +#define PINCONN_PINSEL4_P2p9_MASK (3 << PINCONN_PINSEL4_P2p9_SHIFT) +#define PINCONN_PINSEL4_P2p10_SHIFT (20) /* Bits 20-21: P2.10 00=GPIO 01=EINT0 10=NMI 11=Reserved */ +#define PINCONN_PINSEL4_P2p10_MASK (3 << PINCONN_PINSEL4_P2p10_SHIFT) +#define PINCONN_PINSEL4_P2p11_SHIFT (22) /* Bits 22-23: P2.11 00=GPIO 01=EINT1 10=Reserved 11=I2STX_CLK */ +#define PINCONN_PINSEL4_P2p11_MASK (3 << PINCONN_PINSEL4_P2p11_SHIFT) +#define PINCONN_PINSEL4_P2p12_SHIFT (24) /* Bits 24-25: P2.12 00=GPIO 01=PEINT2 10=Reserved 11=I2STX_WS */ +#define PINCONN_PINSEL4_P2p12_MASK (3 << PINCONN_PINSEL4_P2p12_SHIFT) +#define PINCONN_PINSEL4_P2p13_SHIFT (26) /* Bits 26-27: P2.13 00=GPIO 01=EINT3 10=Reserved 11=I2STX_SDA */ +#define PINCONN_PINSEL4_P2p13_MASK (3 << PINCONN_PINSEL4_P2p13_SHIFT) + /* Bits 28-31: Reserved */ +/* Pin Function Select Register 7 (PINSEL7: 0x4002c01c) */ + +#define PINCONN_PINSEL7_P3_SHIFT(n) PINCONN_PINSELH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINSEL7_P3_MASK(n) PINCONN_PINSELH_MASK(n) /* n=16,17,..31 */ + + /* Bits 0-17: Reserved */ +#define PINCONN_PINSEL7_P3p25_SHIFT (18) /* Bits 18-19: P3.25 00=GPIO 01=Reserved 10=MAT0.0 11=PWM1.2 */ +#define PINCONN_PINSEL7_P3p25_MASK (3 << PINCONN_PINSEL7_P3p25_SHIFT) +#define PINCONN_PINSEL7_P3p26_SHIFT (20) /* Bits 20-21: P3.26 00=GPIO 01=STCLK 10=MAT0.1 11=PWM1.3 */ +#define PINCONN_PINSEL7_P3p26_MASK (3 << PINCONN_PINSEL7_P3p26_SHIFT) + /* Bits 22-31: Reserved */ + +/* Pin Function Select Register 8 (PINSEL8: 0x4002c020) */ +/* No description of bits -- Does this register exist? */ + +/* Pin Function Select Register 9 (PINSEL9: 0x4002c024) */ + +#define PINCONN_PINSEL9_P4_SHIFT(n) PINCONN_PINSELH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINSEL9_P4_MASK(n) PINCONN_PINSELH_MASK(n) /* n=16,17,..31 */ + + /* Bits 0-23: Reserved */ +#define PINCONN_PINSEL9_P4p28_SHIFT (24) /* Bits 24-25: P4.28 00=GPIO 01=RX_MCLK 10=MAT2.0 11=TXD3 */ +#define PINCONN_PINSEL9_P4p28_MASK (3 << PINCONN_PINSEL9_P4p28_SHIFT) +#define PINCONN_PINSEL9_P4p29_SHIFT (26) /* Bits 26-27: P4.29 00=GPIO 01=TX_MCLK 10=MAT2.1 11=RXD3 */ +#define PINCONN_PINSEL9_P4p29_MASK (3 << PINCONN_PINSEL9_P4p29_SHIFT) + /* Bits 28-31: Reserved */ +/* Pin Function Select Register 10 (PINSEL10: 0x4002c028) */ + /* Bits 0-2: Reserved */ +#define PINCONN_PINSEL10_TPIU (1 << 3) /* Bit 3: 0=TPIU interface disabled; 1=TPIU interface enabled */ + /* Bits 4-31: Reserved */ +/* Pin Mode select register 0 (PINMODE0: 0x4002c040) */ + +#define PINCONN_PINMODE_PU (0) /* 00: pin has a pull-up resistor enabled */ +#define PINCONN_PINMODE_RM (1) /* 01: pin has repeater mode enabled */ +#define PINCONN_PINMODE_FLOAT (2) /* 10: pin has neither pull-up nor pull-down */ +#define PINCONN_PINMODE_PD (3) /* 11: pin has a pull-down resistor enabled */ +#define PINCONN_PINMODE_MASK (3) + +#define PINCONN_PINMODEL_SHIFT(n) ((n) << 1) /* n=0,1,..,15 */ +#define PINCONN_PINMODEL_MASK(n) (3 << PINCONN_PINMODEL_SHIFT(n)) +#define PINCONN_PINMODEH_SHIFT(n) (((n)-16) << 1) /* n=16,17,..31 */ +#define PINCONN_PINMODEH_MASK(n) (3 << PINCONN_PINMODEH_SHIFT(n)) + +#define PINCONN_PINMODE0_P0_SHIFT(n) PINCONN_PINMODEL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINMODE0_P0_MASK(n) PINCONN_PINMODEL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINMODE0_P0p0_SHIFT (0) /* Bits 0-1: P0.0 mode control */ +#define PINCONN_PINMODE0_P0p0_MASK (3 << PINCONN_PINMODE0_P0p0_SHIFT) +#define PINCONN_PINMODE0_P0p1_SHIFT (2) /* Bits 2-3: P0.1 mode control */ +#define PINCONN_PINMODE0_P0p1_MASK (3 << PINCONN_PINMODE0_P0p1_SHIFT) +#define PINCONN_PINMODE0_P0p2_SHIFT (4) /* Bits 4-5: P0.2 mode control */ +#define PINCONN_PINMODE0_P0p2_MASK (3 << PINCONN_PINMODE0_P0p2_SHIFT) +#define PINCONN_PINMODE0_P0p3_SHIFT (6) /* Bits 6-7: P0.3 mode control */ +#define PINCONN_PINMODE0_P0p3_MASK (3 << PINCONN_PINMODE0_P0p3_SHIFT) +#define PINCONN_PINMODE0_P0p4_SHIFT (8) /* Bits 8-9: P0.4 mode control */ +#define PINCONN_PINMODE0_P0p4_MASK (3 << PINCONN_PINMODE0_P0p4_SHIFT) +#define PINCONN_PINMODE0_P0p5_SHIFT (10) /* Bits 10-11: P0.5 mode control */ +#define PINCONN_PINMODE0_P0p5_MASK (3 << PINCONN_PINMODE0_P0p5_SHIFT) +#define PINCONN_PINMODE0_P0p6_SHIFT (12) /* Bits 12-13: P0.6 mode control */ +#define PINCONN_PINMODE0_P0p6_MASK (3 << PINCONN_PINMODE0_P0p6_SHIFT) +#define PINCONN_PINMODE0_P0p7_SHIFT (14) /* Bits 14-15: P0.7 mode control */ +#define PINCONN_PINMODE0_P0p7_MASK (3 << PINCONN_PINMODE0_P0p7_SHIFT) +#define PINCONN_PINMODE0_P0p8_SHIFT (16) /* Bits 16-17: P0.8 mode control */ +#define PINCONN_PINMODE0_P0p8_MASK (3 << PINCONN_PINMODE0_P0p8_SHIFT) +#define PINCONN_PINMODE0_P0p9_SHIFT (18) /* Bits 18-19: P0.9 mode control */ +#define PINCONN_PINMODE0_P0p9_MASK (3 << PINCONN_PINMODE0_P0p9_SHIFT) +#define PINCONN_PINMODE0_P0p10_SHIFT (20) /* Bits 20-21: P0.10 mode control */ +#define PINCONN_PINMODE0_P0p10_MASK (3 << PINCONN_PINMODE0_P0p10_SHIFT) +#define PINCONN_PINMODE0_P0p11_SHIFT (22) /* Bits 22-23: P0.11 mode control */ +#define PINCONN_PINMODE0_P0p11_MASK (3 << PINCONN_PINMODE0_P0p11_SHIFT) + /* Bits 24-29: Reserved */ +#define PINCONN_PINMODE0_P0p15_SHIFT (30) /* Bits 30-31: P0.15 mode control */ +#define PINCONN_PINMODE0_P0p15_MASK (3 << PINCONN_PINMODE0_P0p15_SHIFT) + +/* Pin Mode select register 1 (PINMODE1: 0x4002c044) */ + +#define PINCONN_PINMODE1_P0_SHIFT(n) PINCONN_PINMODEH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINMODE1_P0_MASK(n) PINCONN_PINMODEH_MASK(n) /* n=16,17,..31 */ + +#define PINCONN_PINMODE1_P0p16_SHIFT (0) /* Bits 0-1: P0.16 mode control */ +#define PINCONN_PINMODE1_P0p16_MASK (3 << PINCONN_PINMODE1_P0p16_SHIFT) +#define PINCONN_PINMODE1_P0p17_SHIFT (2) /* Bits 2-3: P0.17 mode control */ +#define PINCONN_PINMODE1_P0p17_MASK (3 << PINCONN_PINMODE1_P0p17_SHIFT) +#define PINCONN_PINMODE1_P0p18_SHIFT (4) /* Bits 4-5: P0.18 mode control */ +#define PINCONN_PINMODE1_P0p18_MASK (3 << PINCONN_PINMODE1_P0p18_SHIFT) +#define PINCONN_PINMODE1_P0p19_SHIFT (6) /* Bits 6-7: P0.19 mode control */ +#define PINCONN_PINMODE1_P0p19_MASK (3 << PINCONN_PINMODE1_P0p19_SHIFT) +#define PINCONN_PINMODE1_P0p20_SHIFT (8) /* Bits 8-9: P0.20 mode control */ +#define PINCONN_PINMODE1_P0p20_MASK (3 << PINCONN_PINMODE1_P0p20_SHIFT) +#define PINCONN_PINMODE1_P0p21_SHIFT (10) /* Bits 10-11: P0.21 mode control */ +#define PINCONN_PINMODE1_P0p21_MASK (3 << PINCONN_PINMODE1_P0p21_SHIFT) +#define PINCONN_PINMODE1_P0p22_SHIFT (12) /* Bits 12-13: P0.22 mode control */ +#define PINCONN_PINMODE1_P0p22_MASK (3 << PINCONN_PINMODE1_P0p22_SHIFT) +#define PINCONN_PINMODE1_P0p23_SHIFT (14) /* Bits 14-15: P0.23 mode control */ +#define PINCONN_PINMODE1_P0p23_MASK (3 << PINCONN_PINMODE1_P0p23_SHIFT) +#define PINCONN_PINMODE1_P0p24_SHIFT (16) /* Bits 16-17: P0.24 mode control */ +#define PINCONN_PINMODE1_P0p24_MASK (3 << PINCONN_PINMODE1_P0p24_SHIFT) +#define PINCONN_PINMODE1_P0p25_SHIFT (18) /* Bits 18-19: P0.25 mode control */ +#define PINCONN_PINMODE1_P0p25_MASK (3 << PINCONN_PINMODE1_P0p25_SHIFT) +#define PINCONN_PINMODE1_P0p26_SHIFT (20) /* Bits 20-21: P0.26 mode control */ +#define PINCONN_PINMODE1_P0p26_MASK (3 << PINCONN_PINMODE1_P0p26_SHIFT) + /* Bits 22-31: Reserved */ + +/* Pin Mode select register 2 (PINMODE2: 0x4002c048) */ + +#define PINCONN_PINMODE2_P1_SHIFT(n) PINCONN_PINMODEL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINMODE2_P1_MASK(n) PINCONN_PINMODEL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINMODE2_P1p0_SHIFT (0) /* Bits 2-1: P1.0 mode control */ +#define PINCONN_PINMODE2_P1p0_MASK (3 << PINCONN_PINMODE2_P1p0_SHIFT) +#define PINCONN_PINMODE2_P1p1_SHIFT (2) /* Bits 2-3: P1.1 mode control */ +#define PINCONN_PINMODE2_P1p1_MASK (3 << PINCONN_PINMODE2_P1p1_SHIFT) + /* Bits 4-7: Reserved */ +#define PINCONN_PINMODE2_P1p4_SHIFT (8) /* Bits 8-9: P1.4 mode control */ +#define PINCONN_PINMODE2_P1p4_MASK (3 << PINCONN_PINMODE2_P1p4_SHIFT) + /* Bits 10-15: Reserved */ +#define PINCONN_PINMODE2_P1p8_SHIFT (16) /* Bits 16-17: P1.8 mode control */ +#define PINCONN_PINMODE2_P1p8_MASK (3 << PINCONN_PINMODE2_P1p8_SHIFT) +#define PINCONN_PINMODE2_P1p9_SHIFT (18) /* Bits 18-19: P1.9 mode control */ +#define PINCONN_PINMODE2_P1p9_MASK (3 << PINCONN_PINMODE2_P1p9_SHIFT) +#define PINCONN_PINMODE2_P1p10_SHIFT (20) /* Bits 20-21: P1.10 mode control */ +#define PINCONN_PINMODE2_P1p10_MASK (3 << PINCONN_PINMODE2_P1p10_SHIFT) + /* Bits 22-27: Reserved */ +#define PINCONN_PINMODE2_P1p14_SHIFT (28) /* Bits 28-29: P1.14 mode control */ +#define PINCONN_PINMODE2_P1p14_MASK (3 << PINCONN_PINMODE2_P1p14_SHIFT) +#define PINCONN_PINMODE2_P1p15_SHIFT (30) /* Bits 30-31: P1.15 mode control */ +#define PINCONN_PINMODE2_P1p15_MASK (3 << PINCONN_PINMODE2_P1p15_SHIFT) + +/* Pin Mode select register 3 (PINMODE3: 0x4002c04c) */ + +#define PINCONN_PINMODE3_P1_SHIFT(n) PINCONN_PINMODEH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINMODE3_P1_MASK(n) PINCONN_PINMODEH_MASK(n) /* n=16,17,..31 */ + +#define PINCONN_PINMODE3_P1p16_SHIFT (0) /* Bits 0-1: P1.16 mode control */ +#define PINCONN_PINMODE3_P1p16_MASK (3 << PINCONN_PINMODE3_P1p16_SHIFT) +#define PINCONN_PINMODE3_P1p17_SHIFT (2) /* Bits 2-3: P1.17 mode control */ +#define PINCONN_PINMODE3_P1p17_MASK (3 << PINCONN_PINMODE3_P1p17_SHIFT) +#define PINCONN_PINMODE3_P1p18_SHIFT (4) /* Bits 4-5: P1.18 mode control */ +#define PINCONN_PINMODE3_P1p18_MASK (3 << PINCONN_PINMODE3_P1p18_SHIFT) +#define PINCONN_PINMODE3_P1p19_SHIFT (6) /* Bits 6-7: P1.19 mode control */ +#define PINCONN_PINMODE3_P1p19_MASK (3 << PINCONN_PINMODE3_P1p19_SHIFT) +#define PINCONN_PINMODE3_P1p20_SHIFT (8) /* Bits 8-9: P1.20 mode control */ +#define PINCONN_PINMODE3_P1p20_MASK (3 << PINCONN_PINMODE3_P1p20_SHIFT) +#define PINCONN_PINMODE3_P1p21_SHIFT (10) /* Bits 10-11: P1.21 mode control */ +#define PINCONN_PINMODE3_P1p21_MASK (3 << PINCONN_PINMODE3_P1p21_SHIFT) +#define PINCONN_PINMODE3_P1p22_SHIFT (12) /* Bits 12-13: P1.22 mode control */ +#define PINCONN_PINMODE3_P1p22_MASK (3 << PINCONN_PINMODE3_P1p22_SHIFT) +#define PINCONN_PINMODE3_P1p23_SHIFT (14) /* Bits 14-15: P1.23 mode control */ +#define PINCONN_PINMODE3_P1p23_MASK (3 << PINCONN_PINMODE3_P1p23_SHIFT) +#define PINCONN_PINMODE3_P1p24_SHIFT (16) /* Bits 16-17: P1.24 mode control */ +#define PINCONN_PINMODE3_P1p24_MASK (3 << PINCONN_PINMODE3_P1p24_SHIFT) +#define PINCONN_PINMODE3_P1p25_SHIFT (18) /* Bits 18-19: P1.25 mode control */ +#define PINCONN_PINMODE3_P1p25_MASK (3 << PINCONN_PINMODE3_P1p25_SHIFT) +#define PINCONN_PINMODE3_P1p26_SHIFT (20) /* Bits 20-21: P1.26 mode control */ +#define PINCONN_PINMODE3_P1p26_MASK (3 << PINCONN_PINMODE3_P1p26_SHIFT) +#define PINCONN_PINMODE3_P1p27_SHIFT (22) /* Bits 22-23: P1.27 mode control */ +#define PINCONN_PINMODE3_P1p27_MASK (3 << PINCONN_PINMODE3_P1p27_SHIFT) +#define PINCONN_PINMODE3_P1p28_SHIFT (24) /* Bits 24-25: P1.28 mode control */ +#define PINCONN_PINMODE3_P1p28_MASK (3 << PINCONN_PINMODE3_P1p28_SHIFT) +#define PINCONN_PINMODE3_P1p29_SHIFT (26) /* Bits 26-27: P1.29 mode control */ +#define PINCONN_PINMODE3_P1p29_MASK (3 << PINCONN_PINMODE3_P1p29_SHIFT) +#define PINCONN_PINMODE3_P1p30_SHIFT (28) /* Bits 28-29: P1.30 mode control */ +#define PINCONN_PINMODE3_P1p30_MASK (3 << PINCONN_PINMODE3_P1p30_SHIFT) +#define PINCONN_PINMODE3_P1p31_SHIFT (30) /* Bits 30-31: P1.31 mode control */ +#define PINCONN_PINMODE3_P1p31_MASK (3 << PINCONN_PINMODE3_P1p31_SHIFT) + +/* Pin Mode select register 4 (PINMODE4: 0x4002c050) */ + +#define PINCONN_PINMODE4_P2_SHIFT(n) PINCONN_PINMODEL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINMODE4_P2_MASK(n) PINCONN_PINMODEL_MASK(n) /* n=0,1,..,15 */ + +#define PINCONN_PINMODE4_P2p0_SHIFT (0) /* Bits 0-1: P2.0 mode control */ +#define PINCONN_PINMODE4_P2p0_MASK (3 << PINCONN_PINMODE4_P2p0_SHIFT) +#define PINCONN_PINMODE4_P2p1_SHIFT (2) /* Bits 2-3: P2.1 mode control */ +#define PINCONN_PINMODE4_P2p1_MASK (3 << PINCONN_PINMODE4_P2p1_SHIFT) +#define PINCONN_PINMODE4_P2p2_SHIFT (4) /* Bits 4-5: P2.2 mode control */ +#define PINCONN_PINMODE4_P2p2_MASK (3 << PINCONN_PINMODE4_P2p2_SHIFT) +#define PINCONN_PINMODE4_P2p3_SHIFT (6) /* Bits 6-7: P2.3 mode control */ +#define PINCONN_PINMODE4_P2p3_MASK (3 << PINCONN_PINMODE4_P2p3_SHIFT) +#define PINCONN_PINMODE4_P2p4_SHIFT (8) /* Bits 8-9: P2.4 mode control */ +#define PINCONN_PINMODE4_P2p4_MASK (3 << PINCONN_PINMODE4_P2p4_SHIFT) +#define PINCONN_PINMODE4_P2p5_SHIFT (10) /* Bits 10-11: P2.5 mode control */ +#define PINCONN_PINMODE4_P2p5_MASK (3 << PINCONN_PINMODE4_P2p5_SHIFT) +#define PINCONN_PINMODE4_P2p6_SHIFT (12) /* Bits 12-13: P2.6 mode control */ +#define PINCONN_PINMODE4_P2p6_MASK (3 << PINCONN_PINMODE4_P2p6_SHIFT) +#define PINCONN_PINMODE4_P2p7_SHIFT (14) /* Bits 14-15: P2.7 mode control */ +#define PINCONN_PINMODE4_P2p7_MASK (3 << PINCONN_PINMODE4_P2p7_SHIFT) +#define PINCONN_PINMODE4_P2p8_SHIFT (16) /* Bits 16-17: P2.8 mode control */ +#define PINCONN_PINMODE4_P2p8_MASK (3 << PINCONN_PINMODE4_P2p8_SHIFT) +#define PINCONN_PINMODE4_P2p9_SHIFT (18) /* Bits 18-19: P2.9 mode control */ +#define PINCONN_PINMODE4_P2p9_MASK (3 << PINCONN_PINMODE4_P2p9_SHIFT) +#define PINCONN_PINMODE4_P2p10_SHIFT (20) /* Bits 20-21: P2.10 mode control */ +#define PINCONN_PINMODE4_P2p10_MASK (3 << PINCONN_PINMODE4_P2p10_SHIFT) +#define PINCONN_PINMODE4_P2p11_SHIFT (22) /* Bits 22-23: P2.11 mode control */ +#define PINCONN_PINMODE4_P2p11_MASK (3 << PINCONN_PINMODE4_P2p11_SHIFT) +#define PINCONN_PINMODE4_P2p12_SHIFT (24) /* Bits 24-25: P2.12 mode control */ +#define PINCONN_PINMODE4_P2p12_MASK (3 << PINCONN_PINMODE4_P2p12_SHIFT) +#define PINCONN_PINMODE4_P2p13_SHIFT (26) /* Bits 26-27: P2.13 mode control */ +#define PINCONN_PINMODE4_P2p13_MASK (3 << PINCONN_PINMODE4_P2p13_SHIFT) + /* Bits 28-31: Reserved */ +/* Pin Mode select register 5 (PINMODE5: 0x4002c054) + * Pin Mode select register 6 (PINMODE6: 0x4002c058) + * No bit definitions -- do these registers exist? + */ + +#define PINCONN_PINMODE5_P2_SHIFT(n) PINCONN_PINMODEH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINMODE5_P2_MASK(n) PINCONN_PINMODEH_MASK(n) /* n=16,17,..31 */ + +#define PINCONN_PINMODE6_P3_SHIFT(n) PINCONN_PINMODEL_SHIFT(n) /* n=0,1,..,15 */ +#define PINCONN_PINMODE6_P3_MASK(n) PINCONN_PINMODEL_MASK(n) /* n=0,1,..,15 */ + +/* Pin Mode select register 7 (PINMODE7: 0x4002c05c) */ + +#define PINCONN_PINMODE7_P3_SHIFT(n) PINCONN_PINMODEH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINMODE7_P3_MASK(n) PINCONN_PINMODEH_MASK(n) /* n=16,17,..31 */ + /* Bits 0-17: Reserved */ +#define PINCONN_PINMODE7_P3p25_SHIFT (18) /* Bits 18-19: P3.25 mode control */ +#define PINCONN_PINMODE7_P3p25_MASK (3 << PINCONN_PINMODE7_P3p25_SHIFT) +#define PINCONN_PINMODE7_P3p26_SHIFT (20) /* Bits 20-21: P3.26 mode control */ +#define PINCONN_PINMODE7_P3p26_MASK (3 << PINCONN_PINMODE7_P3p26_SHIFT) + /* Bits 22-31: Reserved */ +/* Pin Mode select register 9 (PINMODE9: 0x4002c064) */ + +#define PINCONN_PINMODE9_P4_SHIFT(n) PINCONN_PINMODEH_SHIFT(n) /* n=16,17,..31 */ +#define PINCONN_PINMODE9_P4_MASK(n) PINCONN_PINMODEH_MASK(n) /* n=16,17,..31 */ + /* Bits 0-23: Reserved */ +#define PINCONN_PINMODE9_P4p28_SHIFT (24) /* Bits 24-25: P4.28 mode control */ +#define PINCONN_PINMODE9_P4p28_MASK (3 << PINCONN_PINMODE9_P4p28_SHIFT) +#define PINCONN_PINMODE9_P4p29_SHIFT (26) /* Bits 26-27: P4.29 mode control */ +#define PINCONN_PINMODE9_P4p29_MASK (3 << PINCONN_PINMODE9_P4p29_SHIFT) + /* Bits 28-31: Reserved */ +/* Open Drain Pin Mode select register 0 (PINMODE_OD0: 0x4002c068) */ + +#define PINCONN_ODMODE0_P0(n) (1 << (n)) + +#define PINCONN_ODMODE0_P0p0 (1 << 0) /* Bit 0: P0.0 open drain mode */ +#define PINCONN_ODMODE0_P0p1 (1 << 1) /* Bit 1: P0.1 open drain mode */ +#define PINCONN_ODMODE0_P0p2 (1 << 2) /* Bit 2: P0.2 open drain mode */ +#define PINCONN_ODMODE0_P0p3 (1 << 3) /* Bit 3: P0.3 open drain mode */ +#define PINCONN_ODMODE0_P0p4 (1 << 4) /* Bit 4: P0.4 open drain mode */ +#define PINCONN_ODMODE0_P0p5 (1 << 5) /* Bit 5: P0.5 open drain mode */ +#define PINCONN_ODMODE0_P0p6 (1 << 6) /* Bit 6: P0.6 open drain mode */ +#define PINCONN_ODMODE0_P0p7 (1 << 7) /* Bit 7: P0.7 open drain mode */ +#define PINCONN_ODMODE0_P0p8 (1 << 8) /* Bit 8: P0.8 open drain mode */ +#define PINCONN_ODMODE0_P0p9 (1 << 9) /* Bit 9: P0.9 open drain mode */ +#define PINCONN_ODMODE0_P0p10 (1 << 10) /* Bit 10: P0.10 open drain mode */ +#define PINCONN_ODMODE0_P0p11 (1 << 11) /* Bit 11: P0.11 open drain mode */ + /* Bits 12-14: Reserved */ +#define PINCONN_ODMODE0_P0p15 (1 << 15) /* Bit 15: P0.15 open drain mode */ +#define PINCONN_ODMODE0_P0p16 (1 << 16) /* Bit 16: P0.16 open drain mode */ +#define PINCONN_ODMODE0_P0p17 (1 << 17) /* Bit 17: P0.17 open drain mode */ +#define PINCONN_ODMODE0_P0p18 (1 << 18) /* Bit 18: P0.18 open drain mode */ +#define PINCONN_ODMODE0_P0p19 (1 << 19) /* Bit 19: P0.19 open drain mode */ +#define PINCONN_ODMODE0_P0p20 (1 << 20) /* Bit 20: P0.20 open drain mode */ +#define PINCONN_ODMODE0_P0p21 (1 << 21) /* Bit 21: P0.21 open drain mode */ +#define PINCONN_ODMODE0_P0p22 (1 << 22) /* Bit 22: P0.22 open drain mode */ +#define PINCONN_ODMODE0_P0p23 (1 << 23) /* Bit 23: P0.23 open drain mode */ +#define PINCONN_ODMODE0_P0p24 (1 << 24) /* Bit 24: P0.24 open drain mode */ +#define PINCONN_ODMODE0_P0p25 (1 << 25) /* Bit 25: P0.25 open drain mode */ +#define PINCONN_ODMODE0_P0p26 (1 << 25) /* Bit 26: P0.26 open drain mode */ + /* Bits 27-28: Reserved */ +#define PINCONN_ODMODE0_P0p29 (1 << 29) /* Bit 29: P0.29 open drain mode */ +#define PINCONN_ODMODE0_P0p30 (1 << 30) /* Bit 30: P0.30 open drain mode */ + /* Bit 31: Reserved */ +/* Open Drain Pin Mode select register 1 (PINMODE_OD1: 0x4002c06c) */ + +#define PINCONN_ODMODE1_P1(n) (1 << (n)) + +#define PINCONN_ODMODE1_P1p0 (1 << 0) /* Bit 0: P1.0 open drain mode */ +#define PINCONN_ODMODE1_P1p1 (1 << 1) /* Bit 1: P1.1 open drain mode */ + /* Bits 2-3: Reserved */ +#define PINCONN_ODMODE1_P1p4 (1 << 4) /* Bit 4: P1.4 open drain mode */ + /* Bits 5-7: Reserved */ +#define PINCONN_ODMODE1_P1p8 (1 << 8) /* Bit 8: P1.8 open drain mode */ +#define PINCONN_ODMODE1_P1p9 (1 << 9) /* Bit 9: P1.9 open drain mode */ +#define PINCONN_ODMODE1_P1p10 (1 << 10) /* Bit 10: P1.10 open drain mode */ + /* Bits 11-13: Reserved */ +#define PINCONN_ODMODE1_P1p14 (1 << 14) /* Bit 14: P1.14 open drain mode */ +#define PINCONN_ODMODE1_P1p15 (1 << 15) /* Bit 15: P1.15 open drain mode */ +#define PINCONN_ODMODE1_P1p16 (1 << 16) /* Bit 16: P1.16 open drain mode */ +#define PINCONN_ODMODE1_P1p17 (1 << 17) /* Bit 17: P1.17 open drain mode */ +#define PINCONN_ODMODE1_P1p18 (1 << 18) /* Bit 18: P1.18 open drain mode */ +#define PINCONN_ODMODE1_P1p19 (1 << 19) /* Bit 19: P1.19 open drain mode */ +#define PINCONN_ODMODE1_P1p20 (1 << 20) /* Bit 20: P1.20 open drain mode */ +#define PINCONN_ODMODE1_P1p21 (1 << 21) /* Bit 21: P1.21 open drain mode */ +#define PINCONN_ODMODE1_P1p22 (1 << 22) /* Bit 22: P1.22 open drain mode */ +#define PINCONN_ODMODE1_P1p23 (1 << 23) /* Bit 23: P1.23 open drain mode */ +#define PINCONN_ODMODE1_P1p24 (1 << 24) /* Bit 24: P1.24 open drain mode */ +#define PINCONN_ODMODE1_P1p25 (1 << 25) /* Bit 25: P1.25 open drain mode */ +#define PINCONN_ODMODE1_P1p26 (1 << 25) /* Bit 26: P1.26 open drain mode */ +#define PINCONN_ODMODE1_P1p27 (1 << 27) /* Bit 27: P1.27 open drain mode */ +#define PINCONN_ODMODE1_P1p28 (1 << 28) /* Bit 28: P1.28 open drain mode */ +#define PINCONN_ODMODE1_P1p29 (1 << 29) /* Bit 29: P1.29 open drain mode */ +#define PINCONN_ODMODE1_P1p30 (1 << 30) /* Bit 30: P1.30 open drain mode */ +#define PINCONN_ODMODE1_P1p31 (1 << 31) /* Bit 31: P1.31 open drain mode */ + +/* Open Drain Pin Mode select register 2 (PINMODE_OD2: 0x4002c070) */ + +#define PINCONN_ODMODE2_P2(n) (1 << (n)) + +#define PINCONN_ODMODE2_P2p0 (1 << 0) /* Bit 0: P2.0 open drain mode */ +#define PINCONN_ODMODE2_P2p1 (1 << 1) /* Bit 1: P2.1 open drain mode */ +#define PINCONN_ODMODE2_P2p2 (1 << 2) /* Bit 2: P2.2 open drain mode */ +#define PINCONN_ODMODE2_P2p3 (1 << 3) /* Bit 3: P2.3 open drain mode */ +#define PINCONN_ODMODE2_P2p4 (1 << 4) /* Bit 4: P2.4 open drain mode */ +#define PINCONN_ODMODE2_P2p5 (1 << 5) /* Bit 5: P2.5 open drain mode */ +#define PINCONN_ODMODE2_P2p6 (1 << 6) /* Bit 6: P2.6 open drain mode */ +#define PINCONN_ODMODE2_P2p7 (1 << 7) /* Bit 7: P2.7 open drain mode */ +#define PINCONN_ODMODE2_P2p8 (1 << 8) /* Bit 8: P2.8 open drain mode */ +#define PINCONN_ODMODE2_P2p9 (1 << 9) /* Bit 9: P2.9 open drain mode */ +#define PINCONN_ODMODE2_P2p10 (1 << 10) /* Bit 10: P2.10 open drain mode */ +#define PINCONN_ODMODE2_P2p11 (1 << 11) /* Bit 11: P2.11 open drain mode */ +#define PINCONN_ODMODE2_P2p12 (1 << 12) /* Bit 12: P2.12 open drain mode */ +#define PINCONN_ODMODE2_P2p13 (1 << 13) /* Bit 13: P2.13 open drain mode */ + /* Bits 14-31: Reserved */ +/* Open Drain Pin Mode select register 3 (PINMODE_OD3: 0x4002c074) */ + +#define PINCONN_ODMODE3_P3(n) (1 << (n)) + /* Bits 0-24: Reserved */ +#define PINCONN_ODMODE3_P3p25 (1 << 25) /* Bit 25: P3.25 open drain mode */ +#define PINCONN_ODMODE3_P3p26 (1 << 25) /* Bit 26: P3.26 open drain mode */ + /* Bits 17-31: Reserved */ +/* Open Drain Pin Mode select register 4 (PINMODE_OD4: 0x4002c078) */ + +#define PINCONN_ODMODE4_P4(n) (1 << (n)) + /* Bits 0-27: Reserved */ +#define PINCONN_ODMODE4_P4p28 (1 << 28) /* Bit 28: P4.28 open drain mode */ +#define PINCONN_ODMODE4_P4p29 (1 << 29) /* Bit 29: P4.29 open drain mode */ + /* Bits 30-31: Reserved */ +/* I2C Pin Configuration register (I2CPADCFG: 0x4002c07c) */ + +#define PINCONN_I2CPADCFG_SDADRV0 (1 << 0) /* Bit 0: SDA0 pin, P0.27 in Fast Mode Plus */ +#define PINCONN_I2CPADCFG_SDAI2C0 (1 << 1) /* Bit 1: SDA0 pin, P0.27 I2C glitch + * filtering/slew rate control */ +#define PINCONN_I2CPADCFG_SCLDRV0 (1 << 2) /* Bit 2: SCL0 pin, P0.28 in Fast Mode Plus */ +#define PINCONN_I2CPADCFG_SCLI2C0 (1 << 3) /* Bit 3: SCL0 pin, P0.28 I2C glitch + * filtering/slew rate control */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_PINCONN_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc176x_syscon.h b/arch/arm/src/lpc17xx/chip/lpc176x_syscon.h new file mode 100644 index 0000000000000000000000000000000000000000..bc3ae3c92eb7c36b81e4bf6bad6ce1b6dc335f65 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc176x_syscon.h @@ -0,0 +1,494 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc176x_syscon.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_SYSCON_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_SYSCON_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* Flash accelerator module */ + +#define LPC17_SYSCON_FLASHCFG_OFFSET 0x0000 /* Flash Accelerator Configuration Register */ + +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define LPC17_SYSCON_MEMMAP_OFFSET 0x0040 /* Memory Mapping Control register */ + +/* Clocking and power control - Phase locked loops */ + +#define LPC17_SYSCON_PLL0CON_OFFSET 0x0080 /* PLL0 Control Register */ +#define LPC17_SYSCON_PLL0CFG_OFFSET 0x0084 /* PLL0 Configuration Register */ +#define LPC17_SYSCON_PLL0STAT_OFFSET 0x0088 /* PLL0 Status Register */ +#define LPC17_SYSCON_PLL0FEED_OFFSET 0x008c /* PLL0 Feed Register */ + +#define LPC17_SYSCON_PLL1CON_OFFSET 0x00a0 /* PLL1 Control Register */ +#define LPC17_SYSCON_PLL1CFG_OFFSET 0x00a4 /* PLL1 Configuration Register */ +#define LPC17_SYSCON_PLL1STAT_OFFSET 0x00a8 /* PLL1 Status Register */ +#define LPC17_SYSCON_PLL1FEED_OFFSET 0x00ac /* PLL1 Feed Register */ + +/* Clocking and power control - Peripheral power control registers */ + +#define LPC17_SYSCON_PCON_OFFSET 0x00c0 /* Power Control Register */ +#define LPC17_SYSCON_PCONP_OFFSET 0x00c4 /* Power Control for Peripherals Register */ + +/* Clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_CCLKCFG_OFFSET 0x0104 /* CPU Clock Configuration Register */ +#define LPC17_SYSCON_USBCLKCFG_OFFSET 0x0108 /* USB Clock Configuration Register */ + +/* 0x400f c110 - 0x400f c114: CAN Wake and Sleep Registers */ + +/* Clocking and power control -- Clock source selection */ + +#define LPC17_SYSCON_CLKSRCSEL_OFFSET 0x010c /* Clock Source Select Register */ + +/* System control registers -- External Interrupts */ + +#define LPC17_SYSCON_EXTINT_OFFSET 0x0140 /* External Interrupt Flag Register */ + +#define LPC17_SYSCON_EXTMODE_OFFSET 0x0148 /* External Interrupt Mode register */ +#define LPC17_SYSCON_EXTPOLAR_OFFSET 0x014c /* External Interrupt Polarity Register */ + +/* System control registers -- Reset */ + +#define LPC17_SYSCON_RSID_OFFSET 0x0180 /* Reset Source Identification Register */ + +/* System control registers -- Syscon Miscellaneous Registers */ + +#define LPC17_SYSCON_SCS_OFFSET 0x01a0 /* System Control and Status */ + +/* More clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_PCLKSEL0_OFFSET 0x01a8 /* Peripheral Clock Selection register 0 */ +#define LPC17_SYSCON_PCLKSEL1_OFFSET 0x01ac /* Peripheral Clock Selection register 1 */ + +/* Device Interrupt Registers (Might be a error in the User Manual, might be at 0x5000c1c0) */ + +#define LPC17_SYSCON_USBINTST_OFFSET 0x01c0 /* USB Interrupt Status */ + +/* DMA Request Select Register */ + +#define LPC17_SYSCON_DMAREQSEL_OFFSET 0x01c4 /* Selects between UART and timer DMA requests */ + +/* More clocking and power control -- Utility */ + +#define LPC17_SYSCON_CLKOUTCFG_OFFSET 0x01c8 /* Clock Output Configuration Register */ + +/* Register addresses ***************************************************************/ +/* Flash accelerator module */ + +#define LPC17_SYSCON_FLASHCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_FLASHCFG_OFFSET) + +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define LPC17_SYSCON_MEMMAP (LPC17_SYSCON_BASE+LPC17_SYSCON_MEMMAP_OFFSET) + +/* Clocking and power control - Phase locked loops */ + +#define LPC17_SYSCON_PLL0CON (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0CON_OFFSET) +#define LPC17_SYSCON_PLL0CFG (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0CFG_OFFSET) +#define LPC17_SYSCON_PLL0STAT (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0STAT_OFFSET) +#define LPC17_SYSCON_PLL0FEED (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0FEED_OFFSET) + +#define LPC17_SYSCON_PLL1CON (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1CON_OFFSET) +#define LPC17_SYSCON_PLL1CFG (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1CFG_OFFSET) +#define LPC17_SYSCON_PLL1STAT (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1STAT_OFFSET) +#define LPC17_SYSCON_PLL1FEED (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1FEED_OFFSET) + +/* Clocking and power control - Peripheral power control registers */ + +#define LPC17_SYSCON_PCON (LPC17_SYSCON_BASE+LPC17_SYSCON_PCON_OFFSET) +#define LPC17_SYSCON_PCONP (LPC17_SYSCON_BASE+LPC17_SYSCON_PCONP_OFFSET) + +/* Clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_CCLKCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_CCLKCFG_OFFSET) +#define LPC17_SYSCON_USBCLKCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_USBCLKCFG_OFFSET) + +/* 0x400f c110 - 0x400f c114: CAN Wake and Sleep Registers */ + +/* Clocking and power control -- Clock source selection */ + +#define LPC17_SYSCON_CLKSRCSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_CLKSRCSEL_OFFSET) + +/* System control registers -- External Interrupts */ + +#define LPC17_SYSCON_EXTINT (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTINT_OFFSET) + +#define LPC17_SYSCON_EXTMODE (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTMODE_OFFSET) +#define LPC17_SYSCON_EXTPOLAR (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTPOLAR_OFFSET) + +/* System control registers -- Reset */ + +#define LPC17_SYSCON_RSID (LPC17_SYSCON_BASE+LPC17_SYSCON_RSID_OFFSET) + +/* System control registers -- Syscon Miscellaneous Registers */ + +#define LPC17_SYSCON_SCS (LPC17_SYSCON_BASE+LPC17_SYSCON_SCS_OFFSET) + +/* More clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_PCLKSEL0 (LPC17_SYSCON_BASE+LPC17_SYSCON_PCLKSEL0_OFFSET) +#define LPC17_SYSCON_PCLKSEL1 (LPC17_SYSCON_BASE+LPC17_SYSCON_PCLKSEL1_OFFSET) + +/* Device Interrupt Registers (Might be a error in the User Manual, might be at 0x5000c1c0) */ + +#define LPC17_SYSCON_USBINTST (LPC17_SYSCON_BASE+LPC17_SYSCON_USBINTST_OFFSET) + +/* DMA Request Select Register */ + +#define LPC17_SYSCON_DMAREQSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_DMAREQSEL_OFFSET) + +/* More clocking and power control -- Utility */ + +#define LPC17_SYSCON_CLKOUTCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_CLKOUTCFG_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Flash accelerator module */ + /* Bits 0-11: Reserved */ +#define SYSCON_FLASHCFG_TIM_SHIFT (12) /* Bits 12-15: FLASHTIM Flash access time */ +#define SYSCON_FLASHCFG_TIM_MASK (15 << SYSCON_FLASHCFG_TIM_SHIFT) +# define SYSCON_FLASHCFG_TIM_1 (0 << SYSCON_FLASHCFG_TIM_SHIFT) /* 1 CPU clock <= 20 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_2 (1 << SYSCON_FLASHCFG_TIM_SHIFT) /* 2 CPU clock <= 40 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_3 (2 << SYSCON_FLASHCFG_TIM_SHIFT) /* 3 CPU clock <= 60 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_4 (3 << SYSCON_FLASHCFG_TIM_SHIFT) /* 4 CPU clock <= 80 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_5 (4 << SYSCON_FLASHCFG_TIM_SHIFT) /* 5 CPU clock <= 100 MHz CPU clock + * (Up to 120 Mhz for LPC1759/69 only */ +# define SYSCON_FLASHCFG_TIM_6 (5 << SYSCON_FLASHCFG_TIM_SHIFT) /* "safe" setting for any conditions */ + /* Bits 16-31: Reserved */ + +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define SYSCON_MEMMAP_MAP (1 << 0) /* Bit 0: + * 0:Boot mode. A portion of the Boot ROM is mapped to address 0. + * 1:User mode. The on-chip Flash memory is mapped to address 0 */ + /* Bits 1-31: Reserved */ + +/* Clocking and power control -- Clock source selection */ + +#define SYSCON_CLKSRCSEL_SHIFT (0) /* Bits 0-1: Clock selection */ +#define SYSCON_CLKSRCSEL_MASK (3 << SYSCON_CLKSRCSEL_SHIFT) +# define SYSCON_CLKSRCSEL_INTRC (0 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = internal RC oscillator */ +# define SYSCON_CLKSRCSEL_MAIN (1 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = main oscillator */ +# define SYSCON_CLKSRCSEL_RTC (2 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = RTC oscillator */ + /* Bits 2-31: Reserved */ + +/* Clocking and power control - Phase locked loops */ +/* PLL0/1 Control register */ + +#define SYSCON_PLLCON_PLLE (1 << 0) /* Bit 0: PLL0/1 Enable */ +#define SYSCON_PLLCON_PLLC (1 << 1) /* Bit 1: PLL0/1 Connect */ + /* Bits 2-31: Reserved */ +/* PLL0 Configuration register */ + +#define SYSCON_PLL0CFG_MSEL_SHIFT (0) /* Bit 0-14: PLL0 Multiplier value */ +#define SYSCON_PLL0CFG_MSEL_MASK (0x7fff << SYSCON_PLL0CFG_MSEL_SHIFT) + /* Bit 15: Reserved */ +#define SYSCON_PLL0CFG_NSEL_SHIFT (16) /* Bit 16-23: PLL0 Pre-Divider value */ +#define SYSCON_PLL0CFG_NSEL_MASK (0xff << SYSCON_PLL0CFG_NSEL_SHIFT) + /* Bits 24-31: Reserved */ +/* PLL1 Configuration register */ + +#define SYSCON_PLL1CFG_MSEL_SHIFT (0) /* Bit 0-4: PLL1 Multiplier value */ +#define SYSCON_PLL1CFG_MSEL_MASK (0x1f < SYSCON_PLL1CFG_MSEL_SHIFT) +#define SYSCON_PLL1CFG_NSEL_SHIFT (5) /* Bit 5-6: PLL1 Pre-Divider value */ +#define SYSCON_PLL1CFG_NSEL_MASK (3 << SYSCON_PLL1CFG_NSEL_SHIFT) + /* Bits 7-31: Reserved */ +/* PLL0 Status register */ + +#define SYSCON_PLL0STAT_MSEL_SHIFT (0) /* Bit 0-14: PLL0 Multiplier value readback */ +#define SYSCON_PLL0STAT_MSEL_MASK (0x7fff << SYSCON_PLL0STAT_MSEL_SHIFT) + /* Bit 15: Reserved */ +#define SYSCON_PLL0STAT_NSEL_SHIFT (16) /* Bit 16-23: PLL0 Pre-Divider value readback */ +#define SYSCON_PLL0STAT_NSEL_MASK (0xff << SYSCON_PLL0STAT_NSEL_SHIFT) +#define SYSCON_PLL0STAT_PLLE (1 << 24) /* Bit 24: PLL0 enable readback */ +#define SYSCON_PLL0STAT_PLLC (1 << 25) /* Bit 25: PLL0 connect readback */ +#define SYSCON_PLL0STAT_PLOCK (1 << 26) /* Bit 26: PLL0 lock status */ + /* Bits 27-31: Reserved */ +/* PLL1 Status register */ + +#define SYSCON_PLL1STAT_MSEL_SHIFT (0) /* Bit 0-4: PLL1 Multiplier value readback */ +#define SYSCON_PLL1STAT_MSEL_MASK (0x1f << SYSCON_PLL1STAT_MSEL_SHIFT) +#define SYSCON_PLL1STAT_NSEL_SHIFT (5) /* Bit 5-6: PLL1 Pre-Divider value readback */ +#define SYSCON_PLL1STAT_NSEL_MASK (3 << SYSCON_PLL1STAT_NSEL_SHIFT) + /* Bit 7: Reserved */ +#define SYSCON_PLL1STAT_PLLE (1 << 8) /* Bit 8: PLL1 enable readback */ +#define SYSCON_PLL1STAT_PLLC (1 << 9) /* Bit 9: PLL1 connect readback */ +#define SYSCON_PLL1STAT_PLOCK (1 << 10) /* Bit 10: PLL1 lock status */ + /* Bits 11-31: Reserved */ +/* PLL0/1 Feed register */ + +#define SYSCON_PLLFEED_SHIFT (0) /* Bit 0-7: PLL0/1 feed sequence */ +#define SYSCON_PLLFEED_MASK (0xff << SYSCON_PLLFEED_SHIFT) + /* Bits 8-31: Reserved */ +/* Clocking and power control -- Clock dividers */ +/* CPU Clock Configuration register */ + +#define SYSCON_CCLKCFG_SHIFT (0) /* 0-7: Divide value for CPU clock (CCLK) */ +#define SYSCON_CCLKCFG_MASK (0xff << SYSCON_CCLKCFG_SHIFT) +# define SYSCON_CCLKCFG_DIV(n) ((n-1) << SYSCON_CCLKCFG_SHIFT) /* n=2,3,..255 */ + /* Bits 8-31: Reserved */ +/* USB Clock Configuration register */ + +#define SYSCON_USBCLKCFG_SHIFT (0) /* Bits 0-3: PLL0 divide value USB clock */ +#define SYSCON_USBCLKCFG_MASK (15 << SYSCON_USBCLKCFG_SHIFT) +# define SYSCON_USBCLKCFG_DIV6 (5 << SYSCON_USBCLKCFG_SHIFT) /* PLL0/6 for PLL0=288 MHz */ +# define SYSCON_USBCLKCFG_DIV8 (7 << SYSCON_USBCLKCFG_SHIFT) /* PLL0/8 for PLL0=384 MHz */ +# define SYSCON_USBCLKCFG_DIV10 (9 << SYSCON_USBCLKCFG_SHIFT) /* PLL0/10 for PLL0=480 MHz */ + /* Bits 8-31: Reserved */ +/* Peripheral Clock Selection registers 0 and 1 */ + +#define SYSCON_PCLKSEL_CCLK4 (0) /* PCLK_peripheral = CCLK/4 */ +#define SYSCON_PCLKSEL_CCLK (1) /* PCLK_peripheral = CCLK */ +#define SYSCON_PCLKSEL_CCLK2 (2) /* PCLK_peripheral = CCLK/2 */ +#define SYSCON_PCLKSEL_CCLK8 (3) /* PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) */ +#define SYSCON_PCLKSEL_CCLK6 (3) /* PCLK_peripheral = CCLK/6 (CAN1, CAN2, and CAN) */ +#define SYSCON_PCLKSEL_MASK (3) + +#define SYSCON_PCLKSEL0_WDT_SHIFT (0) /* Bits 0-1: Peripheral clock WDT */ +#define SYSCON_PCLKSEL0_WDT_MASK (3 << SYSCON_PCLKSEL0_WDT_SHIFT) +#define SYSCON_PCLKSEL0_TMR0_SHIFT (2) /* Bits 2-3: Peripheral clock TIMER0 */ +#define SYSCON_PCLKSEL0_TMR0_MASK (3 << SYSCON_PCLKSEL0_TMR0_SHIFT) +#define SYSCON_PCLKSEL0_TMR1_SHIFT (4) /* Bits 4-5: Peripheral clock TIMER1 */ +#define SYSCON_PCLKSEL0_TMR1_MASK (3 << SYSCON_PCLKSEL0_TMR1_SHIFT) +#define SYSCON_PCLKSEL0_UART0_SHIFT (6) /* Bits 6-7: Peripheral clock UART0 */ +#define SYSCON_PCLKSEL0_UART0_MASK (3 << SYSCON_PCLKSEL0_UART0_SHIFT) +#define SYSCON_PCLKSEL0_UART1_SHIFT (8) /* Bits 8-9: Peripheral clock UART1 */ +#define SYSCON_PCLKSEL0_UART1_MASK (3 << SYSCON_PCLKSEL0_UART1_SHIFT) + /* Bits 10-11: Reserved */ +#define SYSCON_PCLKSEL0_PWM1_SHIFT (12) /* Bits 12-13: Peripheral clock PWM1 */ +#define SYSCON_PCLKSEL0_PWM1_MASK (3 << SYSCON_PCLKSEL0_PWM1_SHIFT) +#define SYSCON_PCLKSEL0_I2C0_SHIFT (14) /* Bits 14-15: Peripheral clock I2C0 */ +#define SYSCON_PCLKSEL0_I2C0_MASK (3 << SYSCON_PCLKSEL0_I2C0_SHIFT) +#define SYSCON_PCLKSEL0_SPI_SHIFT (16) /* Bits 16-17: Peripheral clock SPI */ +#define SYSCON_PCLKSEL0_SPI_MASK (3 << SYSCON_PCLKSEL0_SPI_SHIFT) + /* Bits 18-19: Reserved */ +#define SYSCON_PCLKSEL0_SSP1_SHIFT (20) /* Bits 20-21: Peripheral clock SSP1 */ +#define SYSCON_PCLKSEL0_SSP1_MASK (3 << SYSCON_PCLKSEL0_SSP1_SHIFT) +#define SYSCON_PCLKSEL0_DAC_SHIFT (22) /* Bits 22-23: Peripheral clock DAC */ +#define SYSCON_PCLKSEL0_DAC_MASK (3 << SYSCON_PCLKSEL0_DAC_SHIFT) +#define SYSCON_PCLKSEL0_ADC_SHIFT (24) /* Bits 24-25: Peripheral clock ADC */ +#define SYSCON_PCLKSEL0_ADC_MASK (3 << SYSCON_PCLKSEL0_ADC_SHIFT) +#define SYSCON_PCLKSEL0_CAN1_SHIFT (26) /* Bits 26-27: Peripheral clock CAN1 */ +#define SYSCON_PCLKSEL0_CAN1_MASK (3 << SYSCON_PCLKSEL0_CAN1_SHIFT) +#define SYSCON_PCLKSEL0_CAN2_SHIFT (28) /* Bits 28-29: Peripheral clock CAN2 */ +#define SYSCON_PCLKSEL0_CAN2_MASK (3 << SYSCON_PCLKSEL0_CAN2_SHIFT) +#define SYSCON_PCLKSEL0_ACF_SHIFT (30) /* Bits 30-31: Peripheral clock CAN AF */ +#define SYSCON_PCLKSEL0_ACF_MASK (3 << SYSCON_PCLKSEL0_ACF_SHIFT) + +#define SYSCON_PCLKSEL1_QEI_SHIFT (0) /* Bits 0-1: Peripheral clock Quadrature Encoder */ +#define SYSCON_PCLKSEL1_QEI_MASK (3 << SYSCON_PCLKSEL1_QEI_SHIFT) +#define SYSCON_PCLKSEL1_GPIOINT_SHIFT (2) /* Bits 2-3: Peripheral clock GPIO interrupts */ +#define SYSCON_PCLKSEL1_GPIOINT_MASK (3 << SYSCON_PCLKSEL1_GPIOINT_SHIFT) +#define SYSCON_PCLKSEL1_PCB_SHIFT (4) /* Bits 4-5: Peripheral clock the Pin Connect block */ +#define SYSCON_PCLKSEL1_PCB_MASK (3 << SYSCON_PCLKSEL1_PCB_SHIFT) +#define SYSCON_PCLKSEL1_I2C1_SHIFT (6) /* Bits 6-7: Peripheral clock I2C1 */ +#define SYSCON_PCLKSEL1_I2C1_MASK (3 << SYSCON_PCLKSEL1_I2C1_SHIFT) + /* Bits 8-9: Reserved */ +#define SYSCON_PCLKSEL1_SSP0_SHIFT (10) /* Bits 10-11: Peripheral clock SSP0 */ +#define SYSCON_PCLKSEL1_SSP0_MASK (3 << SYSCON_PCLKSEL1_SSP0_SHIFT) +#define SYSCON_PCLKSEL1_TMR2_SHIFT (12) /* Bits 12-13: Peripheral clock TIMER2 */ +#define SYSCON_PCLKSEL1_TMR2_MASK (3 << SYSCON_PCLKSEL1_TMR2_SHIFT) +#define SYSCON_PCLKSEL1_TMR3_SHIFT (14) /* Bits 14-15: Peripheral clock TIMER3 */ +#define SYSCON_PCLKSEL1_TMR3_MASK (3 << SYSCON_PCLKSEL1_TMR3_SHIFT) +#define SYSCON_PCLKSEL1_UART2_SHIFT (16) /* Bits 16-17: Peripheral clock UART2 */ +#define SYSCON_PCLKSEL1_UART2_MASK (3 << SYSCON_PCLKSEL1_UART2_SHIFT) +#define SYSCON_PCLKSEL1_UART3_SHIFT (18) /* Bits 18-19: Peripheral clock UART3 */ +#define SYSCON_PCLKSEL1_UART3_MASK (3 << SYSCON_PCLKSEL1_UART3_SHIFT) +#define SYSCON_PCLKSEL1_I2C2_SHIFT (20) /* Bits 20-21: Peripheral clock I2C2 */ +#define SYSCON_PCLKSEL1_I2C2_MASK (3 << SYSCON_PCLKSEL1_I2C2_SHIFT) +#define SYSCON_PCLKSEL1_I2S_SHIFT (22) /* Bits 22-23: Peripheral clock I2S */ +#define SYSCON_PCLKSEL1_I2S_MASK (3 << SYSCON_PCLKSEL1_I2S_SHIFT) + /* Bits 24-25: Reserved */ +#define SYSCON_PCLKSEL1_RIT_SHIFT (26) /* Bits 26-27: Peripheral clock Repetitive Interrupt Timer */ +#define SYSCON_PCLKSEL1_RIT_MASK (3 << SYSCON_PCLKSEL1_RIT_SHIFT) +#define SYSCON_PCLKSEL1_SYSCON_SHIFT (28) /* Bits 28-29: Peripheral clock the System Control block */ +#define SYSCON_PCLKSEL1_SYSCON_MASK (3 << SYSCON_PCLKSEL1_SYSCON_SHIFT) +#define SYSCON_PCLKSEL1_MC_SHIFT (30) /* Bits 30-31: Peripheral clock the Motor Control PWM */ +#define SYSCON_PCLKSEL1_MC_MASK (3 << SYSCON_PCLKSEL1_MC_SHIFT) + +/* Clocking and power control - Peripheral power control registers */ +/* Power Control Register */ + +#define SYSCON_PCON_PM0 (1 << 0) /* Bit 0: Power mode control bit 0 */ +#define SYSCON_PCON_PM1 (1 << 1) /* Bit 1: Power mode control bit 1 */ +#define SYSCON_PCON_BODRPM (1 << 2) /* Bit 2: Brown-Out Reduced Power Mode */ +#define SYSCON_PCON_BOGD (1 << 3) /* Bit 3: Brown-Out Global Disable */ +#define SYSCON_PCON_BORD (1 << 4) /* Bit 4: Brown-Out Reset Disable */ + /* Bits 5-7: Reserved */ +#define SYSCON_PCON_SMFLAG (1 << 8) /* Bit 8: Sleep Mode entry flag */ +#define SYSCON_PCON_DSFLAG (1 << 9) /* Bit 9: Deep Sleep entry flag */ +#define SYSCON_PCON_PDFLAG (1 << 10) /* Bit 10: Power-down entry flag */ +#define SYSCON_PCON_DPDFLAG (1 << 11) /* Bit 11: Deep Power-down entry flag */ + /* Bits 12-31: Reserved */ +/* Power Control for Peripherals Register */ + + /* Bit 0: Reserved */ +#define SYSCON_PCONP_PCTIM0 (1 << 1) /* Bit 1: Timer/Counter 0 power/clock control */ +#define SYSCON_PCONP_PCTIM1 (1 << 2) /* Bit 2: Timer/Counter 1 power/clock control */ +#define SYSCON_PCONP_PCUART0 (1 << 3) /* Bit 3: UART0 power/clock control */ +#define SYSCON_PCONP_PCUART1 (1 << 4) /* Bit 4: UART1 power/clock control */ + /* Bit 5: Reserved */ +#define SYSCON_PCONP_PCPWM1 (1 << 6) /* Bit 6: PWM1 power/clock control */ +#define SYSCON_PCONP_PCI2C0 (1 << 7) /* Bit 7: I2C0 power/clock control */ +#define SYSCON_PCONP_PCSPI (1 << 8) /* Bit 8: SPI power/clock control */ +#define SYSCON_PCONP_PCRTC (1 << 9) /* Bit 9: RTC power/clock control */ +#define SYSCON_PCONP_PCSSP1 (1 << 10) /* Bit 10: SSP 1 power/clock control */ + /* Bit 11: Reserved */ +#define SYSCON_PCONP_PCADC (1 << 12) /* Bit 12: A/D converter (ADC) power/clock control */ +#define SYSCON_PCONP_PCCAN1 (1 << 13) /* Bit 13: CAN Controller 1 power/clock control */ +#define SYSCON_PCONP_PCCAN2 (1 << 14) /* Bit 14: CAN Controller 2 power/clock control */ +#define SYSCON_PCONP_PCGPIO (1 << 15) /* Bit 15: GPIOs power/clock enable */ +#define SYSCON_PCONP_PCRIT (1 << 16) /* Bit 16: Repetitive Interrupt Timer power/clock control */ +#define SYSCON_PCONP_PCMCPWM (1 << 17) /* Bit 17: Motor Control PWM */ +#define SYSCON_PCONP_PCQEI (1 << 18) /* Bit 18: Quadrature Encoder power/clock control */ +#define SYSCON_PCONP_PCI2C1 (1 << 19) /* Bit 19: I2C1 power/clock control */ + /* Bit 20: Reserved */ +#define SYSCON_PCONP_PCSSP0 (1 << 21) /* Bit 21: SSP0 power/clock control */ +#define SYSCON_PCONP_PCTIM2 (1 << 22) /* Bit 22: Timer 2 power/clock control */ +#define SYSCON_PCONP_PCTIM3 (1 << 23) /* Bit 23: Timer 3 power/clock control */ +#define SYSCON_PCONP_PCUART2 (1 << 24) /* Bit 24: UART 2 power/clock control */ +#define SYSCON_PCONP_PCUART3 (1 << 25) /* Bit 25: UART 3 power/clock control */ +#define SYSCON_PCONP_PCI2C2 (1 << 26) /* Bit 26: I2C 2 power/clock control */ +#define SYSCON_PCONP_PCI2S (1 << 27) /* Bit 27: I2S power/clock control */ + /* Bit 28: Reserved */ +#define SYSCON_PCONP_PCGPDMA (1 << 29) /* Bit 29: GPDMA function power/clock control */ +#define SYSCON_PCONP_PCENET (1 << 30) /* Bit 30: Ethernet block power/clock control */ +#define SYSCON_PCONP_PCUSB (1 << 31) /* Bit 31: USB power/clock control */ + +/* More clocking and power control -- Utility */ + +#define SYSCON_CLKOUTCFG_SEL_SHIFT (0) /* Bits 0-3: Selects clock source for CLKOUT */ +#define SYSCON_CLKOUTCFG_SEL_MASK (15 << SYSCON_CLKOUTCFG_SEL_SHIFT) +# define SYSCON_CLKOUTCFG_SEL_CPU (0 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=CPU clock */ +# define SYSCON_CLKOUTCFG_SEL_MAIN (1 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=main osc */ +# define SYSCON_CLKOUTCFG_SEL_INTRC (2 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=internal RC osc */ +# define SYSCON_CLKOUTCFG_SEL_USB (3 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=USB clock */ +# define SYSCON_CLKOUTCFG_SEL_RTC (4 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=RTC osc */ +#define SYSCON_CLKOUTCFG_DIV_SHIFT (4) /* Bits 4-7: CLKOUT divisor */ +#define SYSCON_CLKOUTCFG_DIV_MASK (15 << SYSCON_CLKOUTCFG_DIV_SHIFT) +# define SYSCON_CLKOUTCFG_DIV(n) ((n-1) << SYSCON_CLKOUTCFG_DIV_SHIFT) /* n=1..16 */ +#define SYSCON_CLKOUTCFG_EN (1 << 8) /* Bit 8: CLKOUT enable control */ +#define SYSCON_CLKOUTCFG_ACT (1 << 9) /* Bit 9: CLKOUT activity indication */ + /* Bits 10-31: Reserved */ +/* System control registers -- External Interrupts */ +/* External Interrupt Flag register */ + +#define SYSCON_EXTINT_EINT0 (1 << 0) /* Bit 0: EINT0 */ +#define SYSCON_EXTINT_EINT1 (1 << 1) /* Bit 1: EINT1 */ +#define SYSCON_EXTINT_EINT2 (1 << 2) /* Bit 2: EINT2 */ +#define SYSCON_EXTINT_EINT3 (1 << 3) /* Bit 3: EINT3 */ + /* Bits 4-31: Reserved */ +/* External Interrupt Mode register */ + +#define SYSCON_EXTMODE_EINT0 (1 << 0) /* Bit 0: 1=EINT0 edge sensitive */ +#define SYSCON_EXTMODE_EINT1 (1 << 1) /* Bit 1: 1=EINT1 edge sensitive */ +#define SYSCON_EXTMODE_EINT2 (1 << 2) /* Bit 2: 1=EINT2 edge sensitive */ +#define SYSCON_EXTMODE_EINT3 (1 << 3) /* Bit 3: 1=EINT3 edge sensitive */ + /* Bits 4-31: Reserved */ +/* External Interrupt Polarity register */ + +#define SYSCON_EXTPOLAR_EINT0 (1 << 0) /* Bit 0: 1=EINT0 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT1 (1 << 1) /* Bit 1: 1=EINT1 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT2 (1 << 2) /* Bit 2: 1=EINT2 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT3 (1 << 3) /* Bit 3: 1=EINT3 high active/rising edge */ + /* Bits 4-31: Reserved */ +/* System control registers -- Reset */ +/* Reset Source Identification Register */ + +#define SYSCON_RSID_POR (1 << 0) /* Bit 0: Power on reset */ +#define SYSCON_RSID_EXTR (1 << 1) /* Bit 1: external RESET signal */ +#define SYSCON_RSID_WDTR (1 << 2) /* Bit 2: Watchdog Timer time out w/WDTRESET */ +#define SYSCON_RSID_BODR (1 << 3) /* Bit 3: Brown out detection */ + /* Bits 4-31: Reserved */ +/* System control registers -- Syscon Miscellaneous Registers */ + + /* Bits 0-3: Reserved */ +#define SYSCON_SCS_OSCRS (1 << 4) /* Bit 4: Main oscillator range select */ +#define SYSCON_SCS_OSCEN (1 << 5) /* Bit 5: Main oscillator enable */ +#define SYSCON_SCS_OSCSTAT (1 << 6) /* Bit 6: Main oscillator status */ + /* Bits 7-31: Reserved */ +/* Device Interrupt Registers */ +/* USB Interrupt Status register */ + +#define SYSCON_USBINTST_REQLP (1 << 0) /* Bit 0: Low priority interrupt line status */ +#define SYSCON_USBINTST_REQHP (1 << 1) /* Bit 1: High priority interrupt line status */ +#define SYSCON_USBINTST_REQDMA (1 << 2) /* Bit 2: DMA interrupt line status */ +#define SYSCON_USBINTST_HOSTINT (1 << 3) /* Bit 3: USB host interrupt line status */ +#define SYSCON_USBINTST_ATXINT (1 << 4) /* Bit 4: External ATX interrupt line status */ +#define SYSCON_USBINTST_OTGINT (1 << 5) /* Bit 5: OTG interrupt line status */ +#define SYSCON_USBINTST_I2CINT (1 << 6) /* Bit 6: I2C module interrupt line status */ + /* Bit 7: Reserved */ +#define SYSCON_USBINTST_NEEDCLK (1 << 8) /* Bit 8: USB need clock indicator */ + /* Bits 9-30: Reserved */ +#define SYSCON_USBINTST_ENINTS (1 << 31) /* Bit 31: Enable all USB interrupts */ + +/* DMA Request Select Register */ + +#define SYSCON_DMAREQSEL_INP8 (1 << 0) /* Bit 0: Input 8 0=UART0 TX 1=Timer 0 match 0 */ +#define SYSCON_DMAREQSEL_INP9 (1 << 1) /* Bit 1: Input 8 0=UART0 RX 1=Timer 0 match 1 */ +#define SYSCON_DMAREQSEL_INP10 (1 << 2) /* Bit 2: Input 8 0=UART1 TX 1=Timer 1 match 0 */ +#define SYSCON_DMAREQSEL_INP11 (1 << 3) /* Bit 3: Input 8 0=UART1 RX 1=Timer 1 match 1 */ +#define SYSCON_DMAREQSEL_INP12 (1 << 4) /* Bit 4: Input 8 0=UART2 TX 1=Timer 2 match 0 */ +#define SYSCON_DMAREQSEL_INP13 (1 << 5) /* Bit 5: Input 8 0=UART2 RX 1=Timer 2 match 1 */ +#define SYSCON_DMAREQSEL_INP14 (1 << 6) /* Bit 6: Input 8 0=UART3 TX 1=Timer 3 match 0 */ +#define SYSCON_DMAREQSEL_INP15 (1 << 7) /* Bit 7: Input 8 0=UART3 RX 1=Timer 3 match 1 */ + /* Bits 8-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC176X_SYSCON_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc176x_vectors.h b/arch/arm/src/lpc17xx/chip/lpc176x_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..58024f2b095d6c337d7a68e7ff00324499968b81 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc176x_vectors.h @@ -0,0 +1,110 @@ +/******************************************************************************** + * arch/arm/src/lpc17xx/chip/lpc176x_vectors.h + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ +/* This file is included by lpc17_vectors.S. It provides the macro VECTOR that + * supplies each LPC17xx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/lpc17/lpc17xx_irq.h. + * lpc17_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 35 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 35 + +#else + +VECTOR(lpc17_wdt, LPC17_IRQ_WDT) /* Vector 16+0: Watchdog timer */ +VECTOR(lpc17_tmr0, LPC17_IRQ_TMR0) /* Vector 16+1: Timer 0 */ +VECTOR(lpc17_tmr1, LPC17_IRQ_TMR1) /* Vector 16+2: Timer 1 */ +VECTOR(lpc17_tmr2, LPC17_IRQ_TMR2) /* Vector 16+3: Timer 2 */ +VECTOR(lpc17_tmr3, LPC17_IRQ_TMR3) /* Vector 16+4: Timer 3 */ +VECTOR(lpc17_uart0, LPC17_IRQ_UART0) /* Vector 16+5: UART 0 */ +VECTOR(lpc17_uart1, LPC17_IRQ_UART1) /* Vector 16+6: UART 1 */ +VECTOR(lpc17_uart2, LPC17_IRQ_UART2) /* Vector 16+7: UART 2 */ +VECTOR(lpc17_uart3, LPC17_IRQ_UART3) /* Vector 16+8: UART 3 */ +VECTOR(lpc17_pwm1, LPC17_IRQ_PWM1) /* Vector 16+9: PWM 1 */ +VECTOR(lpc17_i2c0, LPC17_IRQ_I2C0) /* Vector 16+10: I2C 0 */ +VECTOR(lpc17_i2c1, LPC17_IRQ_I2C1) /* Vector 16+11: I2C 1 */ +VECTOR(lpc17_i2c2, LPC17_IRQ_I2C2) /* Vector 16+12: I2C 2 */ +VECTOR(lpc17_spif, LPC17_IRQ_SPIF) /* Vector 16+13: SPI */ +VECTOR(lpc17_ssp0, LPC17_IRQ_SSP0) /* Vector 16+14: SSP 0 */ +VECTOR(lpc17_ssp1, LPC17_IRQ_SSP1) /* Vector 16+15: SSP 1 */ +VECTOR(lpc17_pll0, LPC17_IRQ_PLL0) /* Vector 16+16: PLL 0 */ +VECTOR(lpc17_rtc, LPC17_IRQ_RTC) /* Vector 16+17: Real time clock */ +VECTOR(lpc17_eint0, LPC17_IRQ_EINT0) /* Vector 16+18: External interrupt 0 */ +VECTOR(lpc17_eint1, LPC17_IRQ_EINT1) /* Vector 16+19: External interrupt 1 */ +VECTOR(lpc17_eint2, LPC17_IRQ_EINT2) /* Vector 16+20: External interrupt 2 */ +VECTOR(lpc17_eint3, LPC17_IRQ_EINT3) /* Vector 16+21: External interrupt 3 */ +VECTOR(lpc17_adc, LPC17_IRQ_ADC) /* Vector 16+22: A/D Converter */ +VECTOR(lpc17_bod, LPC17_IRQ_BOD) /* Vector 16+23: Brown Out detect */ +VECTOR(lpc17_usb, LPC17_IRQ_USB) /* Vector 16+24: USB */ +VECTOR(lpc17_can, LPC17_IRQ_CAN) /* Vector 16+25: CAN */ +VECTOR(lpc17_gpdma, LPC17_IRQ_GPDMA) /* Vector 16+26: GPDMA */ +VECTOR(lpc17_i2s, LPC17_IRQ_I2S) /* Vector 16+27: I2S */ +VECTOR(lpc17_eth, LPC17_IRQ_ETH) /* Vector 16+28: Ethernet */ +VECTOR(lpc17_ritint, LPC17_IRQ_RITINT) /* Vector 16+29: Repetitive Interrupt Timer */ +VECTOR(lpc17_mcpwm, LPC17_IRQ_MCPWM) /* Vector 16+30: Motor Control PWM */ +VECTOR(lpc17_qei, LPC17_IRQ_QEI) /* Vector 16+31: Quadrature Encoder */ +VECTOR(lpc17_pll1, LPC17_IRQ_PLL1) /* Vector 16+32: PLL 1 */ +VECTOR(lpc17_usbact, LPC17_IRQ_USBACT) /* Vector 16+33: USB Activity Interrupt */ +VECTOR(lpc17_canact, LPC17_IRQ_CANACT) /* Vector 16+34: CAN Activity Interrupt */ + +#endif + +/******************************************************************************** + * Public Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Public Function Prototypes + ********************************************************************************/ diff --git a/arch/arm/src/lpc17xx/chip/lpc178x_iocon.h b/arch/arm/src/lpc17xx/chip/lpc178x_iocon.h new file mode 100644 index 0000000000000000000000000000000000000000..690313f4db067dc0fdc307fcde21ba8f6d54b1a5 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc178x_iocon.h @@ -0,0 +1,375 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc178x_iocon.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_IOCON_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_IOCON_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_IOCON_PP_OFFSET(p) ((unsigned int)(p) << 2) +#define LPC17_IOCON_PP0_OFFSET (0x0000) /* IOCON Port(n) register 0 */ +#define LPC17_IOCON_PP1_OFFSET (0x0004) /* IOCON Port(n) register 1 */ +#define LPC17_IOCON_PP2_OFFSET (0x0008) /* IOCON Port(n) register 2 */ +#define LPC17_IOCON_PP3_OFFSET (0x000c) /* IOCON Port(n) register 3 */ +#define LPC17_IOCON_PP4_OFFSET (0x0010) /* IOCON Port(n) register 4 */ +#define LPC17_IOCON_PP5_OFFSET (0x0014) /* IOCON Port(n) register 5 */ +#define LPC17_IOCON_PP6_OFFSET (0x0018) /* IOCON Port(n) register 6 */ +#define LPC17_IOCON_PP7_OFFSET (0x001c) /* IOCON Port(n) register 7 */ +#define LPC17_IOCON_PP8_OFFSET (0x0020) /* IOCON Port(n) register 8 */ +#define LPC17_IOCON_PP9_OFFSET (0x0024) /* IOCON Port(n) register 9 */ +#define LPC17_IOCON_PP10_OFFSET (0x0028) /* IOCON Port(n) register 10 */ +#define LPC17_IOCON_PP11_OFFSET (0x002c) /* IOCON Port(n) register 11 */ +#define LPC17_IOCON_PP12_OFFSET (0x0030) /* IOCON Port(n) register 12 */ +#define LPC17_IOCON_PP13_OFFSET (0x0034) /* IOCON Port(n) register 13 */ +#define LPC17_IOCON_PP14_OFFSET (0x0038) /* IOCON Port(n) register 14 */ +#define LPC17_IOCON_PP15_OFFSET (0x003c) /* IOCON Port(n) register 15 */ +#define LPC17_IOCON_PP16_OFFSET (0x0040) /* IOCON Port(n) register 16 */ +#define LPC17_IOCON_PP17_OFFSET (0x0044) /* IOCON Port(n) register 17 */ +#define LPC17_IOCON_PP18_OFFSET (0x0048) /* IOCON Port(n) register 18 */ +#define LPC17_IOCON_PP19_OFFSET (0x004c) /* IOCON Port(n) register 19 */ +#define LPC17_IOCON_PP20_OFFSET (0x0050) /* IOCON Port(n) register 20 */ +#define LPC17_IOCON_PP21_OFFSET (0x0054) /* IOCON Port(n) register 21 */ +#define LPC17_IOCON_PP22_OFFSET (0x0058) /* IOCON Port(n) register 22 */ +#define LPC17_IOCON_PP23_OFFSET (0x005c) /* IOCON Port(n) register 23 */ +#define LPC17_IOCON_PP24_OFFSET (0x0060) /* IOCON Port(n) register 24 */ +#define LPC17_IOCON_PP25_OFFSET (0x0064) /* IOCON Port(n) register 25 */ +#define LPC17_IOCON_PP26_OFFSET (0x0068) /* IOCON Port(n) register 26 */ +#define LPC17_IOCON_PP27_OFFSET (0x006c) /* IOCON Port(n) register 27 */ +#define LPC17_IOCON_PP28_OFFSET (0x0070) /* IOCON Port(n) register 28 */ +#define LPC17_IOCON_PP29_OFFSET (0x0074) /* IOCON Port(n) register 29 */ +#define LPC17_IOCON_PP30_OFFSET (0x0078) /* IOCON Port(n) register 30 */ +#define LPC17_IOCON_PP31_OFFSET (0x007c) /* IOCON Port(n) register 31 */ + +/* Register addresses ***************************************************************/ + +#define LPC17_IOCON_P_BASE(b) (LPC17_IOCON_BASE + ((unsigned int)(b) << 7)) +#define LPC17_IOCON_P0_BASE (LPC17_IOCON_BASE + 0x0000) +#define LPC17_IOCON_P1_BASE (LPC17_IOCON_BASE + 0x0080) +#define LPC17_IOCON_P2_BASE (LPC17_IOCON_BASE + 0x0100) +#define LPC17_IOCON_P3_BASE (LPC17_IOCON_BASE + 0x0180) +#define LPC17_IOCON_P4_BASE (LPC17_IOCON_BASE + 0x0200) +#define LPC17_IOCON_P5_BASE (LPC17_IOCON_BASE + 0x0280) + +#define LPC17_IOCON_P(b,p) (LPC17_IOCON_P_BASE(b) + LPC17_IOCON_PP_OFFSET(p)) + +#define LPC17_IOCON_P0_0 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P0_1 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P0_2 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P0_3 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P0_4 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P0_5 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P0_6 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P0_7 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P0_8 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P0_9 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P0_10 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P0_11 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P0_12 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P0_13 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P0_14 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P0_15 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P0_16 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P0_17 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P0_18 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P0_19 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P0_20 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P0_21 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P0_22 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P0_23 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P0_24 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P0_25 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P0_26 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P0_27 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P0_28 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P0_29 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P0_30 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P0_31 (LPC17_IOCON_P0_BASE + LPC17_IOCON_PP31_OFFSET) + +#define LPC17_IOCON_P1_0 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P1_1 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P1_2 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P1_3 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P1_4 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P1_5 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P1_6 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P1_7 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P1_8 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P1_9 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P1_10 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P1_11 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P1_12 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P1_13 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P1_14 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P1_15 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P1_16 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P1_17 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P1_18 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P1_19 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P1_20 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P1_21 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P1_22 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P1_23 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P1_24 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P1_25 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P1_26 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P1_27 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P1_28 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P1_29 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P1_30 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P1_31 (LPC17_IOCON_P1_BASE + LPC17_IOCON_PP31_OFFSET) + +#define LPC17_IOCON_P2_0 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P2_1 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P2_2 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P2_3 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P2_4 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P2_5 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P2_6 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P2_7 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P2_8 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P2_9 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P2_10 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P2_11 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P2_12 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P2_13 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P2_14 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P2_15 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P2_16 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P2_17 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P2_18 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P2_19 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P2_20 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P2_21 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P2_22 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P2_23 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P2_24 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P2_25 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P2_26 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P2_27 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P2_28 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P2_29 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P2_30 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P2_31 (LPC17_IOCON_P2_BASE + LPC17_IOCON_PP31_OFFSET) + +#define LPC17_IOCON_P3_0 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P3_1 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P3_2 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P3_3 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P3_4 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P3_5 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P3_6 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P3_7 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P3_8 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P3_9 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P3_10 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P3_11 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P3_12 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P3_13 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P3_14 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P3_15 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P3_16 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P3_17 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P3_18 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P3_19 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P3_20 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P3_21 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P3_22 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P3_23 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P3_24 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P3_25 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P3_26 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P3_27 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P3_28 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P3_29 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P3_30 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P3_31 (LPC17_IOCON_P3_BASE + LPC17_IOCON_PP31_OFFSET) + +#define LPC17_IOCON_P4_0 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P4_1 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P4_2 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P4_3 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P4_4 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P4_5 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P4_6 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P4_7 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P4_8 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P4_9 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P4_10 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P4_11 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P4_12 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P4_13 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P4_14 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P4_15 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P4_16 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P4_17 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P4_18 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P4_19 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P4_20 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P4_21 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P4_22 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P4_23 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P4_24 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P4_25 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P4_26 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P4_27 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P4_28 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P4_29 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P4_30 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P4_31 (LPC17_IOCON_P4_BASE + LPC17_IOCON_PP31_OFFSET) + +#define LPC17_IOCON_P5_0 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP0_OFFSET) +#define LPC17_IOCON_P5_1 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP1_OFFSET) +#define LPC17_IOCON_P5_2 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP2_OFFSET) +#define LPC17_IOCON_P5_3 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP3_OFFSET) +#define LPC17_IOCON_P5_4 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP4_OFFSET) +#define LPC17_IOCON_P5_5 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP5_OFFSET) +#define LPC17_IOCON_P5_6 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP6_OFFSET) +#define LPC17_IOCON_P5_7 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP7_OFFSET) +#define LPC17_IOCON_P5_8 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP8_OFFSET) +#define LPC17_IOCON_P5_9 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP9_OFFSET) +#define LPC17_IOCON_P5_10 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP10_OFFSET) +#define LPC17_IOCON_P5_11 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP11_OFFSET) +#define LPC17_IOCON_P5_12 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP12_OFFSET) +#define LPC17_IOCON_P5_13 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP13_OFFSET) +#define LPC17_IOCON_P5_14 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP14_OFFSET) +#define LPC17_IOCON_P5_15 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP15_OFFSET) +#define LPC17_IOCON_P5_16 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP16_OFFSET) +#define LPC17_IOCON_P5_17 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP17_OFFSET) +#define LPC17_IOCON_P5_18 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP18_OFFSET) +#define LPC17_IOCON_P5_19 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP19_OFFSET) +#define LPC17_IOCON_P5_20 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP20_OFFSET) +#define LPC17_IOCON_P5_21 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP21_OFFSET) +#define LPC17_IOCON_P5_22 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP22_OFFSET) +#define LPC17_IOCON_P5_23 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP23_OFFSET) +#define LPC17_IOCON_P5_24 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP24_OFFSET) +#define LPC17_IOCON_P5_25 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP25_OFFSET) +#define LPC17_IOCON_P5_26 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP26_OFFSET) +#define LPC17_IOCON_P5_27 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP27_OFFSET) +#define LPC17_IOCON_P5_28 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP28_OFFSET) +#define LPC17_IOCON_P5_29 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP29_OFFSET) +#define LPC17_IOCON_P5_30 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP30_OFFSET) +#define LPC17_IOCON_P5_31 (LPC17_IOCON_P5_BASE + LPC17_IOCON_PP31_OFFSET) + +/* Register bit definitions *********************************************************/ +/* IOCON pin function select */ + +#define IOCON_FUNC_GPIO (0) +#define IOCON_FUNC_ALT1 (1) +#define IOCON_FUNC_ALT2 (2) +#define IOCON_FUNC_ALT3 (3) +#define IOCON_FUNC_ALT4 (4) +#define IOCON_FUNC_ALT5 (5) +#define IOCON_FUNC_ALT6 (6) +#define IOCON_FUNC_ALT7 (7) + +#define IOCON_FUNC_SHIFT (0) /* Bits 0-2: All types */ +#define IOCON_FUNC_MASK (7 << IOCON_FUNC_SHIFT) +#define IOCON_MODE_SHIFT (3) /* Bits 3-4: Type D,A,W */ +#define IOCON_MODE_MASK (3 << IOCON_MODE_SHIFT ) +#define IOCON_HYS_SHIFT (5) /* Bit 5: Type D,W */ +#define IOCON_HYS_MASK (1 << IOCON_HYS_SHIFT) +#define IOCON_INV_SHIFT (6) /* Bit 6: Type D,A,I,W */ +#define IOCON_INV_MASK (1 << IOCON_INV_SHIFT) +#define IOCON_ADMODE_SHIFT (7) /* Bit 7: Type A */ +#define IOCON_ADMODE_MASK (1 << IOCON_ADMODE_SHIFT) +#define IOCON_FILTER_SHIFT (8) /* Bit 8: Type A */ +#define IOCON_FILTER_MASK (1 << IOCON_FILTER_SHIFT) +#define IOCON_I2CHS_SHIFT (8) /* Bit 8: Type I */ +#define IOCON_I2CHS_MASK (1 << IOCON_I2CHS_SHIFT) +#define IOCON_SLEW_SHIFT (9) /* Bit 9: Type W */ +#define IOCON_SLEW_MASK (1 << IOCON_SLEW_SHIFT) +#define IOCON_HIDRIVE_SHIFT (9) /* Bit 9: Type I */ +#define IOCON_HIDRIVE_MASK (1 << IOCON_HIDRIVE_SHIFT) +#define IOCON_OD_SHIFT (10) /* Bit 10: Type D,A,W */ +#define IOCON_OD_MASK (1 << IOCON_OD_SHIFT) +#define IOCON_DACEN_SHIFT (16) /* Bit 16: Type A */ +#define IOCON_DACEN_MASK (1 << IOCON_DACEN_SHIFT) + +/* Pin modes */ + +#define IOCON_MODE_FLOAT (0) /* 00: pin has neither pull-up nor pull-down */ +#define IOCON_MODE_PD (1) /* 01: pin has a pull-down resistor enabled */ +#define IOCON_MODE_PU (2) /* 10: pin has a pull-up resistor enabled */ +#define IOCON_MODE_RM (3) /* 11: pin has repeater mode enabled */ + +/* Pin types */ + +#define IOCON_TYPE_D_MASK (0x0000067f) /* All ports except where ADC/DAC, USB, I2C is present */ +#define IOCON_TYPE_A_MASK (0x000105df) /* USB/ADC/DAC P0:12-13, P0:23-26, P1:30-31 */ +#define IOCON_TYPE_U_MASK (0x00000007) /* USB P0:29 to 31 */ +#define IOCON_TYPE_I_MASK (0x00000347) /* I2C/USB P0:27-28, P5:2-3 */ +#define IOCON_TYPE_W_MASK (0x000007ff) /* I2S P0:7-9 */ + +/* Slew rate modes */ + +#define IOCON_SLEWMODE_NORMAL (0 << IOCON_SLEW_SHIFT) +#define IOCON_SLEWMODE_FAST (1 << IOCON_SLEW_SHIFT) + +/* I2C modes */ + +#define IOCON_I2CMODE_SHIFT (IOCON_I2CHS_SHIFT) +#define IOCON_I2CMODE_MASK (3 << IOCON_I2CMODE_SHIFT) +# define IOCON_I2CMODE_FAST (0 << IOCON_I2CMODE_SHIFT) +# define IOCON_I2CMODE_FASTPLUS (1 << IOCON_I2CMODE_SHIFT)/* */ +# define IOCON_I2CMODE_HIOPENDRAIN (2 << IOCON_I2CMODE_SHIFT)/* */ +# define IOCON_I2CMODE_OPENDRAIN (3 << IOCON_I2CMODE_SHIFT)/* */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_IOCON_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc178x_memorymap.h b/arch/arm/src/lpc17xx/chip/lpc178x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..35c5186656208c7e2ffc8022131ada891ee35c9d --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc178x_memorymap.h @@ -0,0 +1,158 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc178x_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC178X_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC17XX_LPC178X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Memory Map ***********************************************************************/ + +#define LPC17_FLASH_BASE 0x00000000 /* -0x1fffffff: On-chip non-volatile memory */ +#define LPC17_SRAM_BASE 0x10000000 /* -0x10007fff: On-chip SRAM (devices <=32Kb) */ +#define LPC17_ROM_BASE 0x1fff0000 /* -0x1fffffff: 8Kb Boot ROM with flash services */ +#define LPC17_AHBSRAM_BASE 0x20000000 /* -0x3fffffff: On-chip Peripheral SRAM (devices >32Kb) */ +# define LPC17_SRAM_BANK0 0x20000000 /* -0x20003fff: On-chip Peripheral SRAM Bank0 (devices >=32Kb) */ +# define LPC17_SRAM_BANK1 0x20004000 /* -0x20007fff: On-chip Peripheral SRAM Bank1 (devices 64Kb) */ +#define LPC17_AHB_BASE 0x20080000 /* -0x2008ffff: DMA Controller, Ethernet, and USB */ +#define LPC17_SPIFI_BASE 0x28000000 +#define LPC17_APB_BASE 0x40000000 /* -0x5fffffff: APB Peripherals */ +# define LPC17_APB0_BASE 0x40000000 /* -0x4007ffff: APB0 Peripherals */ +# define LPC17_APB1_BASE 0x40080000 /* -0x400fffff: APB1 Peripherals */ + +/* Off chip Memory via External Memory Interface */ + +#define LPC17_EXTRAM_BASE 0x80000000 /* */ +# define LPC17_EXTSRAM_CS0 0x80000000 /* Chip select 0 /up to 64MB/ */ +# define LPC17_EXTSRAM_CS1 0x90000000 /* Chip select 1 /up to 64MB/ */ +# define LPC17_EXTSRAM_CS2 0x98000000 /* Chip select 2 /up to 64MB/ */ +# define LPC17_EXTSRAM_CS3 0x9c000000 /* Chip select 3 /up to 64MB/ */ + +# define LPC17_EXTDRAM_CS0 0xa0000000 /* Chip select 0 /up to 256MB/ */ +# define LPC17_EXTDRAM_CS1 0xb0000000 /* Chip select 1 /up to 256MB/ */ +# define LPC17_EXTDRAM_CS2 0xc0000000 /* Chip select 2 /up to 256MB/ */ +# define LPC17_EXTDRAM_CS3 0xd0000000 /* Chip select 3 /up to 256MB/ */ + +#define LPC17_CORTEXM3_BASE 0xe0000000 /* -0xe00fffff: (see armv7-m/nvic.h) */ +#define LPC17_SCS_BASE 0xe000e000 +#define LPC17_DEBUGMCU_BASE 0xe0042000 + +/* AHB SRAM Bank sizes **************************************************************/ + +#define LPC17_BANK0_SIZE (16*1024) /* Size of AHB SRAM Bank0 (if present) */ +#define LPC17_BANK1_SIZE (16*1024) /* Size of AHB SRAM Bank1 (if present) */ + +/* APB0 Peripherals *****************************************************************/ + +#define LPC17_WDT_BASE 0x40000000 /* -0x40003fff: Watchdog timer */ +#define LPC17_TMR0_BASE 0x40004000 /* -0x40007fff: Timer 0 */ +#define LPC17_TMR1_BASE 0x40008000 /* -0x4000bfff: Timer 1 */ +#define LPC17_UART0_BASE 0x4000c000 /* -0x4000ffff: UART 0 */ +#define LPC17_UART1_BASE 0x40010000 /* -0x40013fff: UART 1 */ +#define LPC17_PWM0_BASE 0x40014000 /* -0x40017fff: PWM 0 */ +#define LPC17_PWM1_BASE 0x40018000 /* -0x4001bfff: PWM 1 */ +#define LPC17_I2C0_BASE 0x4001c000 /* -0x4001ffff: I2C 0 */ + /* -0x40023fff: Reserved */ +#define LPC17_RTC_BASE 0x40024000 /* -0x40027fff: RTC + backup registers */ +#define LPC17_GPIOINT_BASE 0x40028000 /* -0x4002bfff: GPIO interrupts */ +#define LPC17_IOCON_BASE 0x4002c000 /* -0x4002ffff: Pin connect block */ +#define LPC17_SSP1_BASE 0x40030000 /* -0x40033fff: SSP 1 */ +#define LPC17_ADC_BASE 0x40034000 /* -0x40037fff: ADC */ +#define LPC17_CANAFRAM_BASE 0x40038000 /* -0x4003bfff: CAN acceptance filter (AF) RAM */ +#define LPC17_CANAF_BASE 0x4003c000 /* -0x4003ffff: CAN acceptance filter (AF) registers */ +#define LPC17_CAN_BASE 0x40040000 /* -0x40043fff: CAN common registers */ +#define LPC17_CAN1_BASE 0x40044000 /* -0x40047fff: CAN controller l */ +#define LPC17_CAN2_BASE 0x40048000 /* -0x4004bfff: CAN controller 2 */ + /* -0x4005bfff: Reserved */ +#define LPC17_I2C1_BASE 0x4005c000 /* -0x4005ffff: I2C 1 */ + /* -0x4007ffff: Reserved */ + +/* APB1 Peripherals *****************************************************************/ + + /* -0x40087fff: Reserved */ +#define LPC17_SSP0_BASE 0x40088000 /* -0x4008bfff: SSP 0 */ +#define LPC17_DAC_BASE 0x4008c000 /* -0x4008ffff: DAC */ +#define LPC17_TMR2_BASE 0x40090000 /* -0x40093fff: Timer 2 */ +#define LPC17_TMR3_BASE 0x40094000 /* -0x40097fff: Timer 3 */ +#define LPC17_UART2_BASE 0x40098000 /* -0x4009bfff: UART 2 */ +#define LPC17_UART3_BASE 0x4009c000 /* -0x4009ffff: UART 3 */ +#define LPC17_I2C2_BASE 0x400a0000 /* -0x400a3fff: I2C 2 */ +#define LPC17_UART4_BASE 0x400a4000 /* -0x400a7fff: UART4 */ +#define LPC17_I2S_BASE 0x400a8000 /* -0x400abfff: I2S */ +#define LPC17_SSP2_BASE 0x400ac000 /* -0x400affff: SSP2 */ + /* -0x400b3fff: Reserved */ + /* -0x400b7fff: Reserved */ +#define LPC17_MCPWM_BASE 0x400b8000 /* -0x400bbfff: Motor control PWM */ +#define LPC17_QEI_BASE 0x400bc000 /* -0x400bffff: Quadrature encoder interface */ +#define LPC17_MCI_BASE 0x400c0000 /* -0x400fbfff: SD interface */ +#define LPC17_SYSCON_BASE 0x400fc000 /* -0x400fffff: System control */ + +/* AHB Peripherals ******************************************************************/ + +#define LPC17_GPDMA_BASE 0x20080000 /* GPDMA controller */ +#define LPC17_ETH_BASE 0x20084000 /* Ethernet controller */ +#define LPC17_LCD_BASE 0x20088000 /* LCD controller */ +#define LPC17_USB_BASE 0x2008c000 /* USB controller */ +#define LPC17_CRC_BASE 0x20090000 /* CRC engine */ +#define LPC17_GPIO_BASE 0x20098000 /* GPIO */ +#define LPC17_EMC_BASE 0x2009c000 /* External Memory Controller */ + +/* EEPROM */ + +#define LPC17_EEPROM_BASE 0x00200000 /* EEPROM controller */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC178X_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc178x_pinconfig.h b/arch/arm/src/lpc17xx/chip/lpc178x_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..f4007a89c98ea3991f26e3f6d976432ab81d91e6 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc178x_pinconfig.h @@ -0,0 +1,659 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc178x_pinconfig.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_PINCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO pin definitions *************************************************************/ +/* NOTE that functions have a alternate pins that can be selected. These alternates + * are identified with a numerical suffix like _1, _2, or _3. Your board.h file + * should select the correct alternative for your board by including definitions + * such as: + * + * #define GPIO_UART1_RXD GPIO_UART1_RXD_1 + * + * (without the suffix) + */ + +#define GPIO_CAN1_RD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_UART3_TXD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_I2C1_SDA_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) +#define GPIO_UART0_TXD_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN0) + +#define GPIO_CAN1_TD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_UART3_RXD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_I2C1_SCL_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) +#define GPIO_UART0_RXD_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN1) + +#define GPIO_UART0_TXD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) +#define GPIO_UART3_TXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN2) + +#define GPIO_UART0_RXD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN3) +#define GPIO_UART3_RXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN3) + +#define GPIO_I2S_RXCLK_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_CAN2_RD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_CAP2p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN4) +#define GPIO_LCD_VD0_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN4) + +#define GPIO_I2S_RXWS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_CAN2_TD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_CAP2p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN5) +#define GPIO_LCD_VD1_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN5) + +#define GPIO_I2S_RXSDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_SSP1_SSEL_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_MAT2p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_UART1_RTS_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN6) +#define GPIO_LCD_VD8_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN6) + +#define GPIO_I2S_TXCLK_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_SSP1_SCK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_MAT2p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_RTC_EV0_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN7) +#define GPIO_LCD_VD9_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN7) + +#define GPIO_I2S_TXWS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_SSP1_MISO_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_MAT2p2_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_RTC_EV1_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN8) +#define GPIO_LCD_VD16 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN8) + +#define GPIO_I2S_TXSDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_SSP1_MOSI_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_MAT2p3_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_RTC_EV2_1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_LCD_VD17 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT0 | GPIO_PIN9) + +#define GPIO_UART2_TXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_I2C2_SDA_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) +#define GPIO_MAT3p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN10) + +#define GPIO_UART2_RXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_I2C2_SCL_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) +#define GPIO_MAT3p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN11) + +#define GPIO_USB_PPWR2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN12) +#define GPIO_SSP1_MISO_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN12) +#define GPIO_AD0p6 (GPIO_ALT3 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN12) + +#define GPIO_USB_LED2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN13) +#define GPIO_SSP1_MOSI_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN13) +#define GPIO_AD0p7 (GPIO_ALT3 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN13) + +#define GPIO_USB_HSTEN2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN14) +#define GPIO_SSP1_SSEL_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN14) +#define GPIO_USB_CONNECT2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN14) + +#define GPIO_UART1_TXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) +#define GPIO_SSP0_SCK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) +#define GPIO_SPIFI_IO2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN15) + +#define GPIO_UART1_RXD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) +#define GPIO_SSP0_SSEL_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) +#define GPIO_SPIFI_IO3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN16) + +#define GPIO_UART1_CTS_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_SSP0_MISO_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_SPIFI_IO1 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN17) + +#define GPIO_UART1_DCD_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_SSP0_MOSI_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_SPIFI_IO0 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN18) + +#define GPIO_UART1_DSR_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN19) +#define GPIO_SD_CLK_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN19) +#define GPIO_I2C1_SDA_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN19) + +#define GPIO_UART1_DTR_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN20) +#define GPIO_SD_CMD_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN20) +#define GPIO_I2C1_SCL_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN20) + +#define GPIO_UART1_RI_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_SD_PWR_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_UART4_OE_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_CAN1_RD_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) +#define GPIO_UART4_SCLK (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN21) + +#define GPIO_UART1_RTS_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_SD_DAT0_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_UART4_TXD_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_CAN1_TD_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) +#define GPIO_SPIFI_SCLK (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN22) + +#define GPIO_AD0p0 (GPIO_ALT1 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN23) +#define GPIO_I2S_RXCLK_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN23) +#define GPIO_CAP3p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN23) + +#define GPIO_AD0p1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN24) +#define GPIO_I2S_RXWS_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN24) +#define GPIO_CAP3p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN24) + +#define GPIO_AD0p2 (GPIO_ALT1 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN25) +#define GPIO_I2S_RXSDA_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN25) +#define GPIO_UART3_TXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN25) + +#define GPIO_AD0p3 (GPIO_ALT1 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN26) +#define GPIO_AOUT (GPIO_ALT2 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT0 | GPIO_PIN26) +#define GPIO_UART3_RXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN26) + +#define GPIO_I2C0_SDA_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN27) +#define GPIO_USB_SDA (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN27) + +#define GPIO_I2C0_SCL_1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN28) +#define GPIO_USB_SCL (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN28) + +#define GPIO_USB1DP (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN29) +#define GPIO_EINT0_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN29) + +#define GPIO_USB1DM (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN30) +#define GPIO_EINT1_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN30) + +#define GPIO_USB2_DP (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT0 | GPIO_PIN31) + +#define GPIO_ENET_TXD0 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_CAP3p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN0) +#define GPIO_SSP2_SCK (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN0) + +#define GPIO_ENET_TXD1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_MAT3p3_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN1) +#define GPIO_SSP2_MOSI (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN1) + +#define GPIO_ENET_TXD2 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN2) +#define GPIO_SD_CLK_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN2) +#define GPIO_PWM0p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN2) + +#define GPIO_ENET_TXD3 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_SD_CMD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) +#define GPIO_PWM0p2_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN3) + +#define GPIO_ENET_TXEN (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN4) +#define GPIO_MAT3p2_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN4) +#define GPIO_SSP2_MISO (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN4) + +#define GPIO_ENET_TX_ER (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN5) +#define GPIO_SD_PWR_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN5) +#define GPIO_PWM0p3_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN5) + +#define GPIO_ENET_TX_CLK (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN6) +#define GPIO_SD_DAT0_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN6) +#define GPIO_PWM0p4_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN6) + +#define GPIO_ENET_COL (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN7) +#define GPIO_SD_DAT1_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN7) +#define GPIO_PWM0p5_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN7) + +#define GPIO_ENET_CRSDV (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN8) +#define GPIO_MAT3p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN8) +#define GPIO_SSP2_SSEL (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN8) + +#define GPIO_ENET_RXD0 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN9) +#define GPIO_MAT3p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN9) + +#define GPIO_ENET_RXD1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN10) +#define GPIO_CAP3p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN10) + +#define GPIO_ENET_RXD2 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN11) +#define GPIO_SD_DAT2_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN11) +#define GPIO_PWM0p6_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN11) + +#define GPIO_ENET_RXD3 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN12) +#define GPIO_SD_DAT3_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN12) +#define GPIO_PWM0CAPp0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN12) + +#define GPIO_ENET_RX_DV (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN13) + +#define GPIO_ENET_RXER (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN14) +#define GPIO_CAP2p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN14) + +#define GPIO_ENET_REFCLK (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN15) +#define GPIO_I2C2_SDA_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN15) + +#define GPIO_ENET_MDC_1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN16) +#define GPIO_I2S_TXMCLK (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN16) + +#define GPIO_ENET_MDIO_1 (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN17) +#define GPIO_I2S_RXMCLK (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN17) + +#define GPIO_USB_UPLED (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_PWM1p1_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_CAP1p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) +#define GPIO_SSP1_MISO_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN18) + +#define GPIO_USB1_TXE (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_USB1_PPWR (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_CAP1p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_MCPWM_MC0A (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_SSP1_SCK_2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) +#define GPIO_UART2_OE_1 (GPIO_ALT6 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN19) + +#define GPIO_USB1_TXDP (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_PWM1p2_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_QEI_PHA (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_MCPWM_MCFB0 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_SSP0_SCK_2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_LCD_VD6_1 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN20) +#define GPIO_LCD_VD10_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN20) + +#define GPIO_USB1_TXDM (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_PWM1p3_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_SSP0_SSEL_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_MCPWM_ABORT (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_LCD_VD7_1 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN21) +#define GPIO_LCD_VD11_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN21) + +#define GPIO_USB1_RCV (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_USB1_PWRD (GPIO_ALT2 | GPIO_PULLDN | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_MAT1p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_MCPWM_MCOB (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_SSP1_MOSI_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_LCD_VD8_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_LCD_VD12_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN22) + +#define GPIO_USB1_RXDP (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_PWM1p4_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_QEI_PHB (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_MCPWM_MCFB1 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_SSP0_MOSI_2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_LCD_VD9_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN23) +#define GPIO_LCD_VD13_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN23) + +#define GPIO_USB1_RXDM (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_PWM1p5_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_QEI_IDX (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_MCPWM_MCFB2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_SSP0_MOSI_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_LCD_VD10_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN24) +#define GPIO_LCD_VD14_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN24) + +#define GPIO_USB1_LS (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_USB1_HSTEN (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_MAT1p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_MCPWM_MC1A (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_CLKOUT_ (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_LCD_VD11_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN25) +#define GPIO_LCD_VD15_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN25) + +#define GPIO_USB1_SSPND (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_PWM1p6_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_CAP0p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_MCPWM_MC1B (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_SSP1_SSEL_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_LCD_VD12_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN26) +#define GPIO_LCD_VD20 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN26) + +#define GPIO_USB1_INT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_USB1_OVRCR (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_CAP0p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_CLKOUT_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_LCD_VD13_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN27) +#define GPIO_LCD_VD21 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN27) + +#define GPIO_USB1_SCL (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_PCAP1p0_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_MAT0p0_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_MCPWM_MC2A (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_SSP0_SSEL_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_LCD_VD14_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN28) +#define GPIO_LCD_VD22 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN28) + +#define GPIO_USB1_SDA (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_PCAP1p1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_MAT0p1_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_MCPWM_MC2B (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_UART4_TXD_2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_LCD_VD15_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN29) +#define GPIO_LCD_VD23 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT1 | GPIO_PIN29) + +#define GPIO_USB2_PWRD (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_USB_VBUS (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_AD0p4 (GPIO_ALT3 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_I2C0_SDA_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN30) +#define GPIO_UART3_OE (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN30) + +#define GPIO_USB2_OVRCR (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN31) +#define GPIO_SSP1_SCK_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN31) +#define GPIO_AD0p5 (GPIO_ALT3 | GPIO_FLOAT | GPIO_MODE_ANALOG | GPIO_PORT1 | GPIO_PIN31) +#define GPIO_I2C0_SCL_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN31) + +#define GPIO_PWM1p1_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN0) +#define GPIO_UART1_TXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN0) +#define GPIO_LCD_PWR (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN0) + +#define GPIO_PWM1p2_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN1) +#define GPIO_UART1_RXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN1) +#define GPIO_LCD_LE (GPIO_ALT7 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN1) + +#define GPIO_PWM1p3_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_UART1_CTS_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_MAT2p3_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_TRACEDATA3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN2) +#define GPIO_LCD_DCLK (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN2 ) + +#define GPIO_PWM1p4_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_UART1_DCD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_MAT2p2_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_TRACEDATA2 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN3) +#define GPIO_LCD_FP (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN3) + +#define GPIO_PWM1p5_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_UART1_DSR_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_MAT2p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_TRACEDATA1 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN4) +#define GPIO_LCD_ENABM (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN4) + +#define GPIO_PWM1p6_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_UART1_DTR_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_MAT2p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_TRACEDATA0 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_LCD_LP (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN5) + +#define GPIO_PCAP1p0_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_UART1_RI_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_CAP2p0_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_UART2_OE_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_TRACECLK (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_LCD_VD0_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN6) +#define GPIO_LCD_VD4_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN6) + +#define GPIO_CAN2_RD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_UART1_RTS_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_SPIFI_CS (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_LCD_VD1_2 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN7) +#define GPIO_LCD_VD5_1 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN7) + +#define GPIO_CAN2_TD_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_UART2_TXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_UART1_CTS_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_ENET_MDC_2 (GPIO_ALT4 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_LCD_VD2_1 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN8) +#define GPIO_LCD_VD6_2 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN8) + +#define GPIO_USB1_CONNECT (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_UART2_RXD_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_UART4_RXD_1 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_ENET_MDIO_2 (GPIO_ALT4 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_LCD_VD3_1 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN9) +#define GPIO_LCD_VD7_2 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN9) + +#define GPIO_EINT0_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN10) +#define GPIO_NMI (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN10) + +#define GPIO_EINT1_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN11) +#define GPIO_SD_DAT1_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN11) +#define GPIO_I2S_TXCLK_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN11) +#define GPIO_LCD_CLKIN (GPIO_ALT7 | GPIO_FLOAT | GPIO_PORT2 | GPIO_PIN11) + +#define GPIO_EINT2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_SD_DAT2_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_I2S_TXWS_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_LCD_VD4_2 (GPIO_ALT4 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_LCD_VD3_2 (GPIO_ALT5 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_LCD_VD8_3 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN12) +#define GPIO_LCD_VD18 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN12) + +#define GPIO_EINT3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_SD_DAT3_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_I2S_TXSDA_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_LCD_VD5_2 (GPIO_ALT5 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_LCD_VD9_3 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN13) +#define GPIO_LCD_VD19 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT2 | GPIO_PIN13) + +#define GPIO_EMC_CS2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN14) +#define GPIO_I2C1_SDA_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN14) +#define GPIO_CAP2p0_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN14) + +#define GPIO_EMC_CS3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN15) +#define GPIO_I2C1_SCL (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN15) +#define GPIO_CAP2p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN15) + +#define GPIO_EMC_CAS (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN16) +#define GPIO_EMC_RAS (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN17) +#define GPIO_EMC_CLK0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN18) + +#define GPIO_EMC_CLK1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN19) +#define GPIO_EMC_DYCS0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN20) +#define GPIO_EMC_DYCS1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN21) + +#define GPIO_EMC_DYCS2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN22) +#define GPIO_SSP0_SCK_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN22) +#define GPIO_CAP3p0_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN22) + +#define GPIO_EMC_DYCS3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN23) +#define GPIO_SSP0_SSEL_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN23) +#define GPIO_CAP3p1_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN23) + +#define GPIO_EMC_CKE0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN24) +#define GPIO_EMC_CKE1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN25) + +#define GPIO_EMC_CKE2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN26) +#define GPIO_SSP0_MISO_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN26) +#define GPIO_MAT3p0_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN26) + +#define GPIO_EMC_CKE3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN27) +#define GPIO_SSP0_MOSI_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN27) +#define GPIO_MAT3p1_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN27) + +#define GPIO_EMC_DQM0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN28) +#define GPIO_EMC_DQM1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN29) + +#define GPIO_EMC_DQM2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN30) +#define GPIO_I2C2_SDA_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN30) +#define GPIO_MAT3p2_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN30) + +#define GPIO_EMC_DQM3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN31) +#define GPIO_I2C2_SCL_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN31) +#define GPIO_MAT3p3_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT2 | GPIO_PIN31) + +#define GPIO_EMC_D0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN0) +#define GPIO_EMC_D1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN1) +#define GPIO_EMC_D2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN2) +#define GPIO_EMC_D3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN3) +#define GPIO_EMC_D4 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN4) +#define GPIO_EMC_D5 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN5) +#define GPIO_EMC_D6 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN6) +#define GPIO_EMC_D7 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN7) +#define GPIO_EMC_D8 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN8) +#define GPIO_EMC_D9 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN9) +#define GPIO_EMC_D10 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN10) +#define GPIO_EMC_D11 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN11) +#define GPIO_EMC_D12 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN12) +#define GPIO_EMC_D13 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN13) +#define GPIO_EMC_D14 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN14) +#define GPIO_EMC_D15 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN15) + +#define GPIO_EMC_D16 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN16) +#define GPIO_PWM0p1_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN16) +#define GPIO_UART1_TXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN16) + +#define GPIO_EMC_D17 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN17) +#define GPIO_PWM0p2_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN17) +#define GPIO_UART1_RXD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN17) + +#define GPIO_EMC_D18 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN18) +#define GPIO_PWM0p3_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN18) +#define GPIO_UART1_CTS_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN18) + +#define GPIO_EMC_D19 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN19) +#define GPIO_PWM0p4_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN19) +#define GPIO_UART1_DCD_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN19) + +#define GPIO_EMC_D20 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN20) +#define GPIO_PWM0p5_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN20) +#define GPIO_UART1_DSR_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN20) + +#define GPIO_EMC_D21 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN21) +#define GPIO_PWM0p6_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN21) +#define GPIO_UART1_DTR_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN21) + +#define GPIO_EMC_D22 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN22) +#define GPIO_PWM0CAPp0_2 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN22) +#define GPIO_UART1_RI_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN22) + +#define GPIO_EMC_D23 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN23) +#define GPIO_PWM1CAPp0 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN23) +#define GPIO_CAP0p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN23) + +#define GPIO_EMC_D24 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN24) +#define GPIO_PWM1p1_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN24) +#define GPIO_CAP0p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN24) + +#define GPIO_EMC_D25 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN25) +#define GPIO_PWM1p2_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN25) +#define GPIO_MAT0p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN25) + +#define GPIO_EMC_D26 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_PWM1p3_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_MAT0p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) +#define GPIO_STCLK (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN26) + +#define GPIO_EMC_D27 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN27) +#define GPIO_PWM1p4_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN27) +#define GPIO_CAP1p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN27) + +#define GPIO_EMC_D28 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN28) +#define GPIO_PWM1p5_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN28) +#define GPIO_CAP1p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN28) + +#define GPIO_EMC_D29 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN29) +#define GPIO_PWM1p6_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN29) +#define GPIO_MAT1p0_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN29) + +#define GPIO_EMC_D30 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN30) +#define GPIO_UART1_RTS_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN30) +#define GPIO_MAT1p1_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN30) + +#define GPIO_EMC_D31 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN31) +#define GPIO_MAT1p2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT3 | GPIO_PIN31) + +#define GPIO_EMC_A0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN0) +#define GPIO_EMC_A1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN1) +#define GPIO_EMC_A2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN2) +#define GPIO_EMC_A3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN3) +#define GPIO_EMC_A4 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN4) +#define GPIO_EMC_A5 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN5) +#define GPIO_EMC_A6 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN6) +#define GPIO_EMC_A7 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN7) +#define GPIO_EMC_A8 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN8) +#define GPIO_EMC_A9 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN9) +#define GPIO_EMC_A10 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN10) +#define GPIO_EMC_A11 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN11) +#define GPIO_EMC_A12 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN12) +#define GPIO_EMC_A13 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN13) +#define GPIO_EMC_A14 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN14) +#define GPIO_EMC_A15 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN15) +#define GPIO_EMC_A16 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN16) +#define GPIO_EMC_A17 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN17) +#define GPIO_EMC_A18 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN18) +#define GPIO_EMC_A19 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN19) + +#define GPIO_EMC_A20 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN20) +#define GPIO_I2C2_SDA_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN20) +#define GPIO_SSP1_SCK_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN20) + +#define GPIO_EMC_A21 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN21) +#define GPIO_I2C2_SCL_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN21) +#define GPIO_SSP1_SSEL_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN21) + +#define GPIO_EMC_A22 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN22) +#define GPIO_UART2_TXD_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN22) +#define GPIO_SSP1_MISO_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN22) + +#define GPIO_EMC_A23 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN23) +#define GPIO_UART2_RXD_3 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN23) +#define GPIO_SSP1_MOSI_4 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN23) + +#define GPIO_EMC_OE (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN24) +#define GPIO_EMC_WE (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN25) +#define GPIO_EMC_BLS0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN26) +#define GPIO_EMC_BLS1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN27) + +#define GPIO_EMC_BLS2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_UART3_TXD_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_MAT2p0_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_LCD_VD6_3 (GPIO_ALT5 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_LCD_VD10_3 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN28) +#define GPIO_LCD_VD2_2 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN28) + +#define GPIO_EMC_BLS3 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_UART3_RXD_4 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_MAT2p1_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_I2C2_SCL_3 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_LCD_VD7_3 (GPIO_ALT5 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_LCD_VD11_3 (GPIO_ALT6 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN29) +#define GPIO_LCD_VD3_3 (GPIO_ALT7 | GPIO_FLOAT | GPIO_SLEW_FAST | GPIO_PORT4 | GPIO_PIN29) + +#define GPIO_EMC_CS0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN30) +#define GPIO_EMC_CS1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT4 | GPIO_PIN31) + +#define GPIO_EMC_A24 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN0) +#define GPIO_MAT2p2_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN0) + +#define GPIO_EMC_A25 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN1) +#define GPIO_MAT2p3_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN1) + +#define GPIO_MAT3p2_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN2) +#define GPIO_I2C0_SDA_3 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN2) + +#define GPIO_UART4_RXD_2 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN3) +#define GPIO_I2C0_SCL0 (GPIO_ALT5 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN3) + +#define GPIO_UART4_OE_2 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN4) +#define GPIO_MAT3p3_3 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN4) +#define GPIO_UART4_TXD_3 (GPIO_ALT4 | GPIO_PULLUP | GPIO_PORT5 | GPIO_PIN4) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_PINCONFIG_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc178x_syscon.h b/arch/arm/src/lpc17xx/chip/lpc178x_syscon.h new file mode 100644 index 0000000000000000000000000000000000000000..bf5186abcb7415823a01f6016002425e72fa3c3c --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc178x_syscon.h @@ -0,0 +1,636 @@ +/**************************************************************************************************** + * arch/arm/src/lpc17xx/chip/lpc178x_syscon.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_SYSCON_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_SYSCON_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register offsets *********************************************************************************/ +/* Flash accelerator module */ + +#define LPC17_SYSCON_FLASHCFG_OFFSET 0x0000 /* Flash Accelerator Configuration Register */ + +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define LPC17_SYSCON_MEMMAP_OFFSET 0x0040 /* Memory Mapping Control Register */ + +/* Clocking and power control - Phase locked loops */ + +#define LPC17_SYSCON_PLL0CON_OFFSET 0x0080 /* PLL0 Control Register */ +#define LPC17_SYSCON_PLL0CFG_OFFSET 0x0084 /* PLL0 Configuration Register */ +#define LPC17_SYSCON_PLL0STAT_OFFSET 0x0088 /* PLL0 Status Register */ +#define LPC17_SYSCON_PLL0FEED_OFFSET 0x008c /* PLL0 Feed Register */ + +#define LPC17_SYSCON_PLL1CON_OFFSET 0x00a0 /* PLL1 Control Register */ +#define LPC17_SYSCON_PLL1CFG_OFFSET 0x00a4 /* PLL1 Configuration Register */ +#define LPC17_SYSCON_PLL1STAT_OFFSET 0x00a8 /* PLL1 Status Register */ +#define LPC17_SYSCON_PLL1FEED_OFFSET 0x00ac /* PLL1 Feed Register */ + +/* Clocking and power control - Peripheral power control registers */ + +#define LPC17_SYSCON_PCON_OFFSET 0x00c0 /* Power Control Register */ +#define LPC17_SYSCON_PCONP_OFFSET 0x00c4 /* Power Control for Peripherals Register */ + +/* Clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_EMCCLKSEL_OFFSET 0x0100 /* EMC Clock Selection Register */ +#define LPC17_SYSCON_CCLKSEL_OFFSET 0x0104 /* CPU Clock Selection Register */ +#define LPC17_SYSCON_USBCLKSEL_OFFSET 0x0108 /* USB Clock Selection Register */ + +/* 0x400f c110 - 0x400f c114: CAN Wake and Sleep Registers */ + +/* Clocking and power control -- Clock source selection */ + +#define LPC17_SYSCON_CLKSRCSEL_OFFSET 0x010c /* Clock Source Select Register */ +#define LPC17_SYSCON_CANSLEEPCLR_OFFSET 0x0110 /* CAN Channel Sleep State Register */ +#define LPC17_SYSCON_CANWAKEFLAGS_OFFSET 0x0114 /* CAN Channel Wake-Up State Register */ + +/* System control registers -- External Interrupts */ + +#define LPC17_SYSCON_EXTINT_OFFSET 0x0140 /* External Interrupt Flag Register */ +#define LPC17_SYSCON_EXTMODE_OFFSET 0x0148 /* External Interrupt Mode register */ +#define LPC17_SYSCON_EXTPOLAR_OFFSET 0x014c /* External Interrupt Polarity Register */ + +/* System control registers -- Reset */ + +#define LPC17_SYSCON_RSID_OFFSET 0x0180 /* Reset Source Identification Register */ + +/* System control registers -- Syscon Miscellaneous Registers */ + +#define LPC17_SYSCON_MATRIXARB_OFFSET 0x0188 /* Matrix Arbitration Register */ +#define LPC17_SYSCON_SCS_OFFSET 0x01a0 /* System Control and Status */ +#define LPC17_SYSCON_PCLKSEL_OFFSET 0x01a8 /* Peripheral Clock Selection Register */ +#define LPC17_SYSCON_PBOOST_OFFSET 0x01b0 /* Power Boost Register */ +#define LPC17_SYSCON_SPIFICLKSEL_OFFSET 0x01b4 /* SPIFI Clock Selection Register */ +#define LPC17_SYSCON_LCDCFG_OFFSET 0x01b8 /* LCD Clock Configuration Register */ + +/* Device Interrupt Registers (Might be a error in the User Manual, might be at 0x5000c1c0) */ + +#define LPC17_SYSCON_USBINTST_OFFSET 0x01c0 /* USB Interrupt Status */ + +/* DMA Request Select Register */ + +#define LPC17_SYSCON_DMAREQSEL_OFFSET 0x01c4 /* Selects between UART and timer DMA requests */ + +/* More clocking and power control -- Utility */ + +#define LPC17_SYSCON_CLKOUTCFG_OFFSET 0x01c8 /* Clock Output Configuration Register */ + +/* Peripheral Reset Control */ + +#define LPC17_SYSCON_RSTCON0_OFFSET 0x01cc /* Individual Peripheral Reset Control Bits */ +#define LPC17_SYSCON_RSTCON1_OFFSET 0x01d0 /* Individual Peripheral Reset Control Bits */ + +/* EMC Clock Control and Calibration */ + +#define LPC17_SYSCON_EMCDLYCTL_OFFSET 0x01dc /* Programmable Delays for SDRAM Operation */ +#define LPC17_SYSCON_EMCCAL_OFFSET 0x01e0 /* Calibration Counter for EMCDLYCTL */ + + +/* Register addresses *******************************************************************************/ +/* Flash accelerator module */ + +#define LPC17_SYSCON_FLASHCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_FLASHCFG_OFFSET) + +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define LPC17_SYSCON_MEMMAP (LPC17_SYSCON_BASE+LPC17_SYSCON_MEMMAP_OFFSET) + +/* Clocking and power control - Phase locked loops */ + +#define LPC17_SYSCON_PLL0CON (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0CON_OFFSET) +#define LPC17_SYSCON_PLL0CFG (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0CFG_OFFSET) +#define LPC17_SYSCON_PLL0STAT (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0STAT_OFFSET) +#define LPC17_SYSCON_PLL0FEED (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL0FEED_OFFSET) + +#define LPC17_SYSCON_PLL1CON (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1CON_OFFSET) +#define LPC17_SYSCON_PLL1CFG (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1CFG_OFFSET) +#define LPC17_SYSCON_PLL1STAT (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1STAT_OFFSET) +#define LPC17_SYSCON_PLL1FEED (LPC17_SYSCON_BASE+LPC17_SYSCON_PLL1FEED_OFFSET) + +/* Clocking and power control - Peripheral power control registers */ + +#define LPC17_SYSCON_PCON (LPC17_SYSCON_BASE+LPC17_SYSCON_PCON_OFFSET) +#define LPC17_SYSCON_PCONP (LPC17_SYSCON_BASE+LPC17_SYSCON_PCONP_OFFSET) + +/* Clocking and power control -- Clock dividers */ + +#define LPC17_SYSCON_EMCCLKSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_EMCCLKSEL_OFFSET) +#define LPC17_SYSCON_CCLKSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_CCLKSEL_OFFSET) +#define LPC17_SYSCON_USBCLKSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_USBCLKSEL_OFFSET) + +/* 0x400f c110 - 0x400f c114: CAN Wake and Sleep Registers */ + +/* Clocking and power control -- Clock source selection */ + +#define LPC17_SYSCON_CLKSRCSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_CLKSRCSEL_OFFSET) +#define LPC17_SYSCON_CANSLEEPCLR (LPC17_SYSCON_BASE+LPC17_SYSCON_CANSLEEPCLR_OFFSET) +#define LPC17_SYSCON_CANWAKEFLAGS (LPC17_SYSCON_BASE+LPC17_SYSCON_CANWAKEFLAGS_OFFSET) + +/* System control registers -- External Interrupts */ + +#define LPC17_SYSCON_EXTINT (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTINT_OFFSET) + +#define LPC17_SYSCON_EXTMODE (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTMODE_OFFSET) +#define LPC17_SYSCON_EXTPOLAR (LPC17_SYSCON_BASE+LPC17_SYSCON_EXTPOLAR_OFFSET) + +/* System control registers -- Reset */ + +#define LPC17_SYSCON_RSID (LPC17_SYSCON_BASE+LPC17_SYSCON_RSID_OFFSET) + +/* System control registers -- Syscon Miscellaneous Registers */ + +#define LPC17_SYSCON_MATRIXARB (LPC17_SYSCON_BASE+LPC17_SYSCON_MATRIXARB_OFFSET) +#define LPC17_SYSCON_SCS (LPC17_SYSCON_BASE+LPC17_SYSCON_SCS_OFFSET) +#define LPC17_SYSCON_PCLKSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_PCLKSEL_OFFSET) +#define LPC17_SYSCON_PBOOST (LPC17_SYSCON_BASE+LPC17_SYSCON_PBOOST_OFFSET) +#define LPC17_SYSCON_SPIFICLKSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_SPIFICLKSEL_OFFSET) +#define LPC17_SYSCON_LCDCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_LCDCFG_OFFSET) + +/* Device Interrupt Registers (Might be a error in the User Manual, might be at 0x5000c1c0) */ + +#define LPC17_SYSCON_USBINTST (LPC17_SYSCON_BASE+LPC17_SYSCON_USBINTST_OFFSET) + +/* DMA Request Select Register */ + +#define LPC17_SYSCON_DMAREQSEL (LPC17_SYSCON_BASE+LPC17_SYSCON_DMAREQSEL_OFFSET) + +/* More clocking and power control -- Utility */ + +#define LPC17_SYSCON_CLKOUTCFG (LPC17_SYSCON_BASE+LPC17_SYSCON_CLKOUTCFG_OFFSET) + + +/* Peripheral Reset Control */ + +#define LPC17_SYSCON_RSTCON0 (LPC17_SYSCON_BASE+LPC17_SYSCON_RSTCON0_OFFSET) +#define LPC17_SYSCON_RSTCON1 (LPC17_SYSCON_BASE+LPC17_SYSCON_RSTCON1_OFFSET) + +/* EMC Clock Control and Calibration */ + +#define LPC17_SYSCON_EMCDLYCTL (LPC17_SYSCON_BASE+LPC17_SYSCON_EMCDLYCTL_OFFSET) +#define LPC17_SYSCON_EMCCAL (LPC17_SYSCON_BASE+LPC17_SYSCON_EMCCAL_OFFSET) + +/* Register bit definitions *************************************************************************/ +/* Flash accelerator module */ + /* Bits 0-11: Reserved */ +#define SYSCON_FLASHCFG_TIM_SHIFT (12) /* Bits 12-15: FLASHTIM Flash access time */ +#define SYSCON_FLASHCFG_TIM_MASK (15 << SYSCON_FLASHCFG_TIM_SHIFT) +# define SYSCON_FLASHCFG_TIM_0 (0) /* 1 CPU clock <= 20 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_1 (1 << SYSCON_FLASHCFG_TIM_SHIFT) /* 2 CPU clock <= 40 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_2 (2 << SYSCON_FLASHCFG_TIM_SHIFT) /* 3 CPU clock <= 60 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_3 (3 << SYSCON_FLASHCFG_TIM_SHIFT) /* 4 CPU clock <= 80 MHz CPU clock */ +# define SYSCON_FLASHCFG_TIM_4 (4 << SYSCON_FLASHCFG_TIM_SHIFT) /* 5 CPU clock <= 100 MHz CPU clock + * (Up to 120 Mhz for LPC1788x) */ +# define SYSCON_FLASHCFG_TIM_5 (5 << SYSCON_FLASHCFG_TIM_SHIFT) /* "safe" setting for any conditions */ + /* Bits 16-31: Reserved */ +/* Memory Mapping Control register (MEMMAP - 0x400F C040) */ + +#define SYSCON_MEMMAP_MAP (1 << 0) /* Bit 0: + * 0:Boot mode. A portion of the Boot ROM is mapped to address 0. + * 1:User mode. The on-chip Flash memory is mapped to address 0 */ + /* Bits 1-31: Reserved */ +/* Clocking and power control -- Clock source selection */ + +#define SYSCON_CLKSRCSEL_SHIFT (0) /* Bits 0: Clock selection */ +#define SYSCON_CLKSRCSEL_MASK (1 << SYSCON_CLKSRCSEL_SHIFT) +# define SYSCON_CLKSRCSEL_INTRC (0 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = internal RC oscillator */ +# define SYSCON_CLKSRCSEL_MAIN (1 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = main oscillator */ + /* Bits 1-31: Reserved */ +/* Clocking and power control - Phase locked loops */ +/* PLL0/1 Control register */ + +#define SYSCON_PLLCON_PLLE (1 << 0) /* Bit 0: PLL Enable */ + /* Bits 1-31: Reserved */ +/* PLL0/1 Configuration register */ + +#define SYSCON_PLLCFG_MSEL_SHIFT (0) /* Bit 0-4: PLL Multiplier value */ +#define SYSCON_PLLCFG_MSEL_MASK (0x1f << SYSCON_PLLCFG_MSEL_SHIFT) +#define SYSCON_PLLCFG_PSEL_SHIFT (5) /* Bit 5-6: PLL Pre-Divider value */ +#define SYSCON_PLLCFG_PSEL_MASK (3 << SYSCON_PLLCFG_PSEL_SHIFT) + +/* PLL0/1 Status register */ + +#define SYSCON_PLLSTAT_MSEL_SHIFT (0) /* Bit 0-4: PLLMultiplier value readback */ +#define SYSCON_PLLSTAT_MSEL_MASK (0x1f << SYSCON_PLLSTAT_MSEL_SHIFT) +#define SYSCON_PLLSTAT_PSEL_SHIFT (5) /* Bit 5-6: PLL Pre-Divider value readback */ +#define SYSCON_PLLSTAT_PSEL_MASK (3 << SYSCON_PLLSTAT_PSEL_SHIFT) + /* Bit 7: Reserved */ +#define SYSCON_PLLSTAT_PLLE (1 << 8) /* Bit 8: PLL enable readback */ +#define SYSCON_PLLSTAT_PLLC (1 << 9) /* Bit 9: PLL connect readback */ +#define SYSCON_PLLSTAT_PLOCK (1 << 10) /* Bit 10: PLL lock status */ + /* Bits 11-31: Reserved */ +/* PLL0/1 Feed register */ + +#define SYSCON_PLLFEED_SHIFT (0) /* Bit 0-7: PLL0/1 feed sequence */ +#define SYSCON_PLLFEED_MASK (0xff << SYSCON_PLLFEED_SHIFT) + /* Bits 8-31: Reserved */ +/* Clocking and power control -- Clock dividers */ + +/* EMC Clock Selection Register */ + +#define SYSCON_EMCDIV (1 << 0) /* Bit 0: EMC Clock rate relative to CPU */ + /* 0: EMC uses same clock as CPU */ + /* 1: EMC uses half the rate of CPU */ + /* Bits 1-31: Reserved */ +/* EMC Clock Selection Register */ + +#define SYSCON_EMCCLKSEL_CCLK_DIV2 (1 << 0) /* Bit 0: 1=EMC used CPU clock / 2 */ +#define SYSCON_EMCCLKSEL_CCLK_DIV1 (0) /* 0=EMC used CPU clock */ + +/* CPU Clock Selection Register */ + +#define SYSCON_CCLKSEL_CCLKDIV_SHIFT (0) /* 0-4: Divide value for CPU clock (CCLK) */ +#define SYSCON_CCLKSEL_CCLKDIV_MASK (0x1f << SYSCON_CCLKSEL_CCLKDIV_SHIFT) +# define SYSCON_CCLKSEL_CCLKDIV(n) ((n-1) << SYSCON_CCLKSEL_CCLKDIV_SHIFT) /* n = 2 - 31 */ + /* Bits 5-7: Reserved */ +#define SYSCON_CCLKSEL_CCLKSEL (1 << 8) /* Bit 8: Select input clock to CPU clock divider */ + /* 0: Sysclk used as input to CCLKDIV */ + /* 1: Main PLL used as input to CCLKDIV */ + /* Bits 9-31: Reserved */ +/* USB Clock Selection register */ + +#define SYSCON_USBCLKSEL_USBDIV_SHIFT (0) /* Bits 0-4: PLL0/1 divide value USB clock */ +#define SYSCON_USBCLKSEL_USBDIV_MASK (0x1f << SYSCON_USBCLKSEL_USBDIV_SHIFT) +# define SYSCON_USBCLKSEL_USBDIV_DIV1 (1 << SYSCON_USBCLKSEL_USBDIV_SHIFT) /* PLL0/1 output must be 48MHz */ +# define SYSCON_USBCLKSEL_USBDIV_DIV2 (2 << SYSCON_USBCLKSEL_USBDIV_SHIFT) /* PLL0/1 output must be 96MHz */ +# define SYSCON_USBCLKSEL_USBDIV_DIV3 (3 << SYSCON_USBCLKSEL_USBDIV_SHIFT) /* PLL0/1 output must be 144MHz */ + /* Bits 5-7: Reserved */ +#define SYSCON_USBCLKSEL_USBSEL_SHIFT (8) /* Bits 8-9: Input clock to USBDIV */ +#define SYSCON_USBCLKSEL_USBSEL_MASK (3 << SYSCON_USBCLKSEL_USBSEL_SHIFT) +#define SYSCON_USBCLKSEL_USBSEL_PLL0 (1 << SYSCON_USBCLKSEL_USBSEL_SHIFT) /* 01: PLL0 is used as input clock to USBDIV */ +#define SYSCON_USBCLKSEL_USBSEL_PLL1 (2 << SYSCON_USBCLKSEL_USBSEL_SHIFT) /* 10: PLL1 is used as input clock to USBDIV */ + /* 11: unused */ + /* Bits 10-31: Reserved */ +/* CAN0/1 Sleep Clear Register */ + /* Bit 0: Reserved */ +#define SYSCON_CANSLEEPCLR_SHIFT (1) /* Bits 1-2: CAN0/1 Sleep Status and Control */ +#define SYSCON_CANSLEEPCLR_MASK (3 << SYSCON_CANSLEEPCLR_SHIFT) /* */ +#define SYSCON_CANSLEEPCLR_CAN1 (1 << SYSCON_CANSLEEPCLR_SHIFT) /* CAN1 Sleep Status */ +#define SYSCON_CANSLEEPCLR_CAN2 (2 << SYSCON_CANSLEEPCLR_SHIFT) /* CAN2 Sleep Status */ + /* Read 1: CAN channel in sleep mode */ + /* Write 1: CAN channel clocks restored */ + /* Bits 3-31: Reserved */ +/* CAN0/1 WakeUp Flags Register */ + /* Bit 0: Reserved */ +#define SYSCON_CANWAKEFLAGS_SHIFT (1) /* Bits 1-2: CAN0/1 WakeUp Status */ +#define SYSCON_CANWAKEFLAGS_MASK (3 << SYSCON_CANWAKEFLAGS_SHIFT) /* */ +#define SYSCON_CANWAKEFLAGS_CAN1 (1 << SYSCON_CANWAKEFLAGS_SHIFT) /* CAN1 WakeUp Status */ +#define SYSCON_CANWAKEFLAGS_CAN2 (2 << SYSCON_CANWAKEFLAGS_SHIFT) /* CAN2 WakeUp Status */ + /* Read 1: CAN channel falling edge occur on receive line */ + /* Write 1: CAN channel clears wakeup flag bit */ + /* Bits 3-31: Reserved */ +/* Peripheral Clock Selection register */ +/* PCLK is common to all peripheral */ + +#define SYSCON_PCLKSEL_PCLKDIV_SHIFT (0) /* Bits 0-4: Clock divide value for all APB peripherals */ +#define SYSCON_PCLKSEL_PCLKDIV_MASK (0x1f << SYSCON_PCLKSEL_PCLKDIV_SHIFT) +# define SYSCON_PCLKSEL_PCLKDIV(n) ((n) & SYSCON_PCLKSEL_PCLKDIV_MASK) /* n = 1 - 31 */ + /* Bits 5-31: Reserved */ +/* Power Boost Control Register */ + +#define SYSCON_PBOOST_BOOST_SHIFT (0) /* Bits 0-1: Boost control bits */ +#define SYSCON_PBOOST_BOOST_MASK (3 << SYSCON_PBOOST_BOOST_SHIFT) +#define SYSCON_PBOOST_BOOST_OFF (0) /* Boost OFF, operation must be below 100MHz */ +#define SYSCON_PBOOST_BOOST_ON (3) /* Boost ON, operation upto 120MHz allowed */ + /* Bits 2-31: Reserved */ +/* SPIFI Clock Selection Register */ + +#define SYSCON_SPIFICLKSEL_SPIFIDIV_SHIFT (0) /* Bits 0-4: divide value for SPIFI clock */ +#define SYSCON_SPIFICLKSEL_SPIFIDIV_MASK (0x1f << SYSCON_SPIFICLKSEL_SPIFIDIV_SHIFT) +# define SYSCON_SPIFICLKSEL_SPIFIDIV(n) ((n-1) << SYSCON_SPIFICLKSEL_SPIFIDIV_SHIFT) /* n = 2 - 31 */ + /* Bits 5-7: Reserved */ +#define SYSCON_SPIFICLKSEL_SPIFISEL_SHIFT (8) /* Bits 8-9: Selects input clock for SPIFI clock divider */ +#define SYSCON_SPIFICLKSEL_SPIFISEL_MASK (3 << SYSCON_SPIFICLKSEL_SPIFISEL_SHIFT) +#define SYSCON_SPIFICLKSEL_SPIFISEL_SYSCLK (0) /* Sysclk used as input to SPIFIDIV */ +#define SYSCON_SPIFICLKSEL_SPIFISEL_PLL0 (1 << SYSCON_SPIFICLKSEL_SPIFISEL_SHIFT) /* Main PLL used as input to SPIFIDIV */ +#define SYSCON_SPIFICLKSEL_SPIFISEL_PLL1 (2 << SYSCON_SPIFICLKSEL_SPIFISEL_SHIFT) /* Alt PLL used as input to SPIFIDIV */ + /* Bits 10-31: Reserved */ +/* LCD Configuration Register */ + +#define SYSCON_LCDCFG_CLKDIV_SHIFT (0) /* Bits 0-4: LCD Panel clock prescaler */ +#define SYSCON_LCDCFG_CLKDIV_MASK (0x1f << SYSCON_LCDCFG_CLKDIV_SHIFT) +#define SYSCON_LCDCFG_CLKDIV(n) ((n-1) << SYSCON_LCDCFG_CLKDIV_SHIFT) /* n = 1 - 32 */ + /* Bits 5-31: Reserved */ +/* Clocking and power control - Peripheral power control registers */ +/* Power Control Register */ + +#define SYSCON_PCON_PM0 (1 << 0) /* Bit 0: Power mode control bit 0 */ +#define SYSCON_PCON_PM1 (1 << 1) /* Bit 1: Power mode control bit 1 */ +#define SYSCON_PCON_BODRPM (1 << 2) /* Bit 2: Brown-Out Reduced Power Mode */ +#define SYSCON_PCON_BOGD (1 << 3) /* Bit 3: Brown-Out Global Disable */ +#define SYSCON_PCON_BORD (1 << 4) /* Bit 4: Brown-Out Reset Disable */ + /* Bits 5-7: Reserved */ +#define SYSCON_PCON_SMFLAG (1 << 8) /* Bit 8: Sleep Mode entry flag */ +#define SYSCON_PCON_DSFLAG (1 << 9) /* Bit 9: Deep Sleep entry flag */ +#define SYSCON_PCON_PDFLAG (1 << 10) /* Bit 10: Power-down entry flag */ +#define SYSCON_PCON_DPDFLAG (1 << 11) /* Bit 11: Deep Power-down entry flag */ + /* Bits 12-31: Reserved */ +/* Power Control for Peripherals Register */ + +#define SYSCON_PCONP_PCLCD (1 << 0) /* Bit 0: LCD power/clock control */ +#define SYSCON_PCONP_PCTIM0 (1 << 1) /* Bit 1: Timer/Counter 0 power/clock control */ +#define SYSCON_PCONP_PCTIM1 (1 << 2) /* Bit 2: Timer/Counter 1 power/clock control */ +#define SYSCON_PCONP_PCUART0 (1 << 3) /* Bit 3: UART0 power/clock control */ +#define SYSCON_PCONP_PCUART1 (1 << 4) /* Bit 4: UART1 power/clock control */ +#define SYSCON_PCONP_PCPWM0 (1 << 5) /* Bit 5: PWM0 power/clock control */ +#define SYSCON_PCONP_PCPWM1 (1 << 6) /* Bit 6: PWM1 power/clock control */ +#define SYSCON_PCONP_PCI2C0 (1 << 7) /* Bit 7: I2C0 power/clock control */ +#define SYSCON_PCONP_PCSPI (1 << 8) /* Bit 8: SPI power/clock control */ +#define SYSCON_PCONP_PCRTC (1 << 9) /* Bit 9: RTC power/clock control */ +#define SYSCON_PCONP_PCSSP1 (1 << 10) /* Bit 10: SSP 1 power/clock control */ +#define SYSCON_PCONP_PCEMC (1 << 11) /* Bit 11: External Memory */ +#define SYSCON_PCONP_PCADC (1 << 12) /* Bit 12: A/D converter (ADC) power/clock control */ +#define SYSCON_PCONP_PCCAN1 (1 << 13) /* Bit 13: CAN Controller 1 power/clock control */ +#define SYSCON_PCONP_PCCAN2 (1 << 14) /* Bit 14: CAN Controller 2 power/clock control */ +#define SYSCON_PCONP_PCGPIO (1 << 15) /* Bit 15: GPIOs power/clock enable */ +#define SYSCON_PCONP_PCSPIFI (1 << 16) /* Bit 16: SPI Flash Interface power/clock control */ +#define SYSCON_PCONP_PCMCPWM (1 << 17) /* Bit 17: Motor Control PWM */ +#define SYSCON_PCONP_PCQEI (1 << 18) /* Bit 18: Quadrature Encoder power/clock control */ +#define SYSCON_PCONP_PCI2C1 (1 << 19) /* Bit 19: I2C1 power/clock control */ +#define SYSCON_PCONP_PCSSP2 (1 << 20) /* Bit 20: SSP2 power/clock control */ +#define SYSCON_PCONP_PCSSP0 (1 << 21) /* Bit 21: SSP0 power/clock control */ +#define SYSCON_PCONP_PCTIM2 (1 << 22) /* Bit 22: Timer 2 power/clock control */ +#define SYSCON_PCONP_PCTIM3 (1 << 23) /* Bit 23: Timer 3 power/clock control */ +#define SYSCON_PCONP_PCUART2 (1 << 24) /* Bit 24: UART 2 power/clock control */ +#define SYSCON_PCONP_PCUART3 (1 << 25) /* Bit 25: UART 3 power/clock control */ +#define SYSCON_PCONP_PCI2C2 (1 << 26) /* Bit 26: I2C 2 power/clock control */ +#define SYSCON_PCONP_PCI2S (1 << 27) /* Bit 27: I2S power/clock control */ +#define SYSCON_PCONP_PCSDC (1 << 28) /* Bit 28: SD Card power/clock control */ +#define SYSCON_PCONP_PCGPDMA (1 << 29) /* Bit 29: GPDMA function power/clock control */ +#define SYSCON_PCONP_PCENET (1 << 30) /* Bit 30: Ethernet block power/clock control */ +#define SYSCON_PCONP_PCUSB (1 << 31) /* Bit 31: USB power/clock control */ + +/* More clocking and power control -- Utility */ + +#define SYSCON_CLKOUTCFG_SEL_SHIFT (0) /* Bits 0-3: Selects clock source for CLKOUT */ +#define SYSCON_CLKOUTCFG_SEL_MASK (15 << SYSCON_CLKOUTCFG_SEL_SHIFT) +# define SYSCON_CLKOUTCFG_SEL_CPU (0 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=CPU clock */ +# define SYSCON_CLKOUTCFG_SEL_MAIN (1 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=main osc */ +# define SYSCON_CLKOUTCFG_SEL_INTRC (2 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=internal RC osc */ +# define SYSCON_CLKOUTCFG_SEL_USB (3 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=USB clock */ +# define SYSCON_CLKOUTCFG_SEL_RTC (4 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=RTC osc */ +# define SYSCON_CLKOUTCFG_SEL_SPIFI (5 << SYSCON_CLKOUTCFG_SEL_SHIFT) /* CLKOUT source=SPIFI osc */ +#define SYSCON_CLKOUTCFG_DIV_SHIFT (4) /* Bits 4-7: CLKOUT divisor */ +#define SYSCON_CLKOUTCFG_DIV_MASK (15 << SYSCON_CLKOUTCFG_DIV_SHIFT) +# define SYSCON_CLKOUTCFG_DIV(n) ((n-1) << SYSCON_CLKOUTCFG_DIV_SHIFT) /* n=1..16 */ +#define SYSCON_CLKOUTCFG_EN (1 << 8) /* Bit 8: CLKOUT enable control */ +#define SYSCON_CLKOUTCFG_ACT (1 << 9) /* Bit 9: CLKOUT activity indication */ + /* Bits 10-31: Reserved */ +/* System control registers -- External Interrupts */ +/* External Interrupt Flag register */ + +#define SYSCON_EXTINT_EINT0 (1 << 0) /* Bit 0: EINT0 */ +#define SYSCON_EXTINT_EINT1 (1 << 1) /* Bit 1: EINT1 */ +#define SYSCON_EXTINT_EINT2 (1 << 2) /* Bit 2: EINT2 */ +#define SYSCON_EXTINT_EINT3 (1 << 3) /* Bit 3: EINT3 */ + /* Bits 4-31: Reserved */ +/* External Interrupt Mode register */ + +#define SYSCON_EXTMODE_EINT0 (1 << 0) /* Bit 0: 1=EINT0 edge sensitive */ +#define SYSCON_EXTMODE_EINT1 (1 << 1) /* Bit 1: 1=EINT1 edge sensitive */ +#define SYSCON_EXTMODE_EINT2 (1 << 2) /* Bit 2: 1=EINT2 edge sensitive */ +#define SYSCON_EXTMODE_EINT3 (1 << 3) /* Bit 3: 1=EINT3 edge sensitive */ + /* Bits 4-31: Reserved */ +/* External Interrupt Polarity register */ + +#define SYSCON_EXTPOLAR_EINT0 (1 << 0) /* Bit 0: 1=EINT0 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT1 (1 << 1) /* Bit 1: 1=EINT1 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT2 (1 << 2) /* Bit 2: 1=EINT2 high active/rising edge */ +#define SYSCON_EXTPOLAR_EINT3 (1 << 3) /* Bit 3: 1=EINT3 high active/rising edge */ + /* Bits 4-31: Reserved */ +/* System control registers -- Reset */ +/* Reset Source Identification Register */ + +#define SYSCON_RSID_POR (1 << 0) /* Bit 0: Power on reset */ +#define SYSCON_RSID_EXTR (1 << 1) /* Bit 1: external RESET signal */ +#define SYSCON_RSID_WDTR (1 << 2) /* Bit 2: Watchdog Timer time out w/WDTRESET */ +#define SYSCON_RSID_BODR (1 << 3) /* Bit 3: Brown out detection */ +#define SYSCON_RSID_SYSRESET (1 << 4) /* Bit 4: System Reset */ +#define SYSCON_RSID_LOCKUP (1 << 5) /* Bit 5: Lockup Reset */ + /* Bits 6-31: Reserved */ +/* System control registers -- Matrix Arbitration Priorities */ + +# define SYSCON_MATRIXARB_PRI_LOWEST (0) +# define SYSCON_MATRIXARB_PRI_LOW (1) +# define SYSCON_MATRIXARB_PRI_HIGH (2) +# define SYSCON_MATRIXARB_PRI_HIGHEST (3) + +#define SYSCON_MATRIXARB_PRI_ICODE_SHIFT (0) /* Bits 0-1: I-Code bus priority (should be lower than D-Code) */ +#define SYSCON_MATRIXARB_PRI_ICODE_MASK (3 << SYSCON_MATRIXARB_PRI_ICODE_SHIFT) +# define SYSCON_MATRIXARB_PRI_ICODE(n) ((n) << SYSCON_MATRIXARB_PRI_ICODE_SHIFT) +#define SYSCON_MATRIXARB_PRI_DCODE_SHIFT (2) /* Bits 2-3: D-Code bus priority */ +#define SYSCON_MATRIXARB_PRI_DCODE_MASK (3 << SYSCON_MATRIXARB_PRI_DCODE_SHIFT) +# define SYSCON_MATRIXARB_PRI_DCODE(n) ((n) << SYSCON_MATRIXARB_PRI_DCODE_SHIFT) +#define SYSCON_MATRIXARB_PRI_SYS_SHIFT (4) /* Bits 4-5: System bus priority */ +#define SYSCON_MATRIXARB_PRI_SYS_MASK (3 << SYSCON_MATRIXARB_PRI_SYS_SHIFT) +# define SYSCON_MATRIXARB_PRI_SYS(n) ((n) << SYSCON_MATRIXARB_PRI_SYS_SHIFT) +#define SYSCON_MATRIXARB_PRI_GPDMA_SHIFT (6) /* Bits 6-7: General Purpose DMA priority */ +#define SYSCON_MATRIXARB_PRI_GPDMA_MASK (3 << SYSCON_MATRIXARB_PRI_GPDMA_SHIFT) +# define SYSCON_MATRIXARB_PRI_GPDMA(n) ((n) << SYSCON_MATRIXARB_PRI_GPDMA_SHIFT) +#define SYSCON_MATRIXARB_PRI_ETH_SHIFT (8) /* Bits 8-9: Ethernet DMA priority */ +#define SYSCON_MATRIXARB_PRI_ETH_MASK (3 << SYSCON_MATRIXARB_PRI_ETH_SHIFT) +# define SYSCON_MATRIXARB_PRI_ETH(n) ((n) << SYSCON_MATRIXARB_PRI_ETH_SHIFT) +#define SYSCON_MATRIXARB_PRI_LCD_SHIFT (10) /* Bits 10-11: LCD DMA priority */ +#define SYSCON_MATRIXARB_PRI_LCD_MASK (3 << SYSCON_MATRIXARB_PRI_LCD_SHIFT) +# define SYSCON_MATRIXARB_PRI_LCD(n) ((n) << SYSCON_MATRIXARB_PRI_LCD_SHIFT) +#define SYSCON_MATRIXARB_PRI_USB_SHIFT (12) /* Bits 12-13: USB DMA priority */ +#define SYSCON_MATRIXARB_PRI_USB_MASK (3 << SYSCON_MATRIXARB_PRI_USB_SHIFT) +# define SYSCON_MATRIXARB_PRI_USB(n) ((n) << SYSCON_MATRIXARB_PRI_USB_SHIFT) + /* Bits 14-15: Reserved */ +#define SYSCON_MATRIXARB_ROM_LAT_SHIFT (16) /* Bit 16: ROM Latency select (should always be zero) */ +#define SYSCON_MATRIXARB_ROM_LAT (1 << SYSCON_MATRIXARB_ROM_LAT_SHIFT) + /* Bits 17-31: Reserved */ + +#define SYSCON_MATRIXARB_PRI_MASK (0x00013fff) + +/* System control registers -- Syscon Miscellaneous Registers */ + +#define SYSCON_SCS_EMCSC (1 << 0) /* Bit 0: EMC shift control */ +#define SYSCON_SCS_EMCRD (1 << 1) /* Bit 1: EMC reset disable */ +#define SYSCON_SCS_EMCBC (1 << 2) /* Bit 2: EMC burst control */ +#define SYSCON_SCS_MCIPWRAL (1 << 3) /* Bit 3: MCI power active level */ +#define SYSCON_SCS_OSCRS (1 << 4) /* Bit 4: Main oscillator range select */ +#define SYSCON_SCS_OSCEN (1 << 5) /* Bit 5: Main oscillator enable */ +#define SYSCON_SCS_OSCSTAT (1 << 6) /* Bit 6: Main oscillator status */ + /* Bits 7-31: Reserved */ +/* Device Interrupt Registers */ +/* USB Interrupt Status register */ + +#define SYSCON_USBINTST_REQLP (1 << 0) /* Bit 0: Low priority interrupt line status */ +#define SYSCON_USBINTST_REQHP (1 << 1) /* Bit 1: High priority interrupt line status */ +#define SYSCON_USBINTST_REQDMA (1 << 2) /* Bit 2: DMA interrupt line status */ +#define SYSCON_USBINTST_HOSTINT (1 << 3) /* Bit 3: USB host interrupt line status */ +#define SYSCON_USBINTST_ATXINT (1 << 4) /* Bit 4: External ATX interrupt line status */ +#define SYSCON_USBINTST_OTGINT (1 << 5) /* Bit 5: OTG interrupt line status */ +#define SYSCON_USBINTST_I2CINT (1 << 6) /* Bit 6: I2C module interrupt line status */ + /* Bit 7: Reserved */ +#define SYSCON_USBINTST_NEEDCLK (1 << 8) /* Bit 8: USB need clock indicator */ + /* Bits 9-30: Reserved */ +#define SYSCON_USBINTST_ENINTS (1 << 31) /* Bit 31: Enable all USB interrupts */ + +/* DMA Request Select Register */ + +#define SYSCON_DMAREQSEL_INP0 (1 << 0) /* Bit 0: Input 0 0=unused 1=Timer 0 match 0 */ +#define SYSCON_DMAREQSEL_INP1 (1 << 1) /* Bit 1: Input 1 0=SD 1=Timer 0 match 1 */ +#define SYSCON_DMAREQSEL_INP2 (1 << 2) /* Bit 2: Input 2 0=SSP0 TX 1=Timer 1 match 0 */ +#define SYSCON_DMAREQSEL_INP3 (1 << 3) /* Bit 3: Input 3 0=SSP0 RX 1=Timer 1 match 1 */ +#define SYSCON_DMAREQSEL_INP4 (1 << 4) /* Bit 4: Input 4 0=SSP1 TX 1=Timer 2 match 0 */ +#define SYSCON_DMAREQSEL_INP5 (1 << 5) /* Bit 5: Input 5 0=SSP1 RX 1=Timer 2 match 1 */ +#define SYSCON_DMAREQSEL_INP6 (1 << 6) /* Bit 6: Input 6 0=SSP2 TX 1=I2S0 */ +#define SYSCON_DMAREQSEL_INP7 (1 << 7) /* Bit 7: Input 7 0=SSP2 RX 1=I2S1 */ + /* Bits 8-9: Reserved */ +#define SYSCON_DMAREQSEL_INP10 (1 << 10) /* Bit 10: Input 10 0=UART0 TX 1=UART3 TX */ +#define SYSCON_DMAREQSEL_INP11 (1 << 11) /* Bit 11: Input 11 0=UART0 RX 1=UART3 RX */ +#define SYSCON_DMAREQSEL_INP12 (1 << 12) /* Bit 12: Input 12 0=UART1 TX 1=UART4 TX */ +#define SYSCON_DMAREQSEL_INP13 (1 << 13) /* Bit 13: Input 13 0=UART1 RX 1=UART4 RX */ +#define SYSCON_DMAREQSEL_INP14 (1 << 14) /* Bit 14: Input 14 0=UART2 TX 1=Timer 3 match 0 */ +#define SYSCON_DMAREQSEL_INP15 (1 << 15) /* Bit 15: Input 15 0=UART2 RX 1=Timer 3 match 1 */ + /* Bits 16-31: Reserved */ +/* Reset Control Register 0 */ + +#define SYSCON_RSTCON0_RSTLCD (1 << 0) /* LCD controller reset control bit */ +#define SYSCON_RSTCON0_RSTTIM0 (1 << 1) /* Timer/Counter 0 reset control bit */ +#define SYSCON_RSTCON0_RSTTIM1 (1 << 2) /* Timer/Counter 1 reset control bit */ +#define SYSCON_RSTCON0_RSTUART0 (1 << 3) /* UART0 reset control bit */ +#define SYSCON_RSTCON0_RSTUART1 (1 << 4) /* UART1 reset control bit */ +#define SYSCON_RSTCON0_RSTPWM0 (1 << 5) /* PWM0 reset control bit */ +#define SYSCON_RSTCON0_RSTPWM1 (1 << 6) /* PWM1 reset control bit */ +#define SYSCON_RSTCON0_RSTI2C0 (1 << 7) /* The I2C0 interface reset control bit */ +#define SYSCON_RSTCON0_RSTUART4 (1 << 8) /* UART4 reset control bit */ +#define SYSCON_RSTCON0_RSTRTC (1 << 9) /* RTC and Event Monitor/Recorder reset control bit. RTC reset is limited */ +#define SYSCON_RSTCON0_RSTSSP1 (1 << 10) /* The SSP 1 interface reset control bit */ +#define SYSCON_RSTCON0_RSTEMC (1 << 11) /* External Memory Controller reset control bit */ +#define SYSCON_RSTCON0_RSTADC (1 << 12) /* A/D converter (ADC) reset control bit */ +#define SYSCON_RSTCON0_RSTCAN1 (1 << 13) /* CAN Controller 1 reset control bit */ + /* Note: The CAN acceptance filter may be reset by 0 + * a separate bit in the RSTCON1 register. */ +#define SYSCON_RSTCON0_RSTCAN2 (1 << 14) /* CAN Controller 2 reset control bit */ + /* Note: The CAN acceptance filter may be reset by 0 + * a separate bit in the RSTCON1 register */ +#define SYSCON_RSTCON0_RSTGPIO (1 << 15) /* Reset control bit for GPIO, and GPIO interrupts */ + /* Note: IOCON may be reset by a 0 + * separate bit in the RSTCON1 register */ +#define SYSCON_RSTCON0_RSTSPIFI (1 << 16) /* SPI Flash Interface reset control bit (LPC1773 only) */ +#define SYSCON_RSTCON0_RSTMCPWM (1 << 17) /* Motor Control PWM reset control bit */ +#define SYSCON_RSTCON0_RSTQEI (1 << 18) /* Quadrature Encoder Interface reset control bit */ +#define SYSCON_RSTCON0_RSTI2C1 (1 << 19) /* The I2C1 interface reset control bit */ +#define SYSCON_RSTCON0_RSTSSP2 (1 << 20) /* The SSP2 interface reset control bit */ +#define SYSCON_RSTCON0_RSTSSP0 (1 << 21) /* The SSP0 interface reset control bit */ +#define SYSCON_RSTCON0_RSTTIM2 (1 << 22) /* Timer 2 reset control bit */ +#define SYSCON_RSTCON0_RSTTIM3 (1 << 23) /* Timer 3 reset control bit */ +#define SYSCON_RSTCON0_RSTUART2 (1 << 24) /* UART 2 reset control bit */ +#define SYSCON_RSTCON0_RSTUART3 (1 << 25) /* UART 3 reset control bit */ +#define SYSCON_RSTCON0_RSTI2C2 (1 << 26) /* I2C2 interface reset control bit.*/ +#define SYSCON_RSTCON0_RSTI2S (1 << 27) /* I2S interface reset control bit */ +#define SYSCON_RSTCON0_RSTSDC (1 << 28) /* SD Card interface reset control bit */ +#define SYSCON_RSTCON0_RSTGPDMA (1 << 29) /* GPDMA function reset control bit */ + +#define SYSCON_RSTCON0_RSTENET (1 << 30) /* Ethernet block reset control bit */ +#define SYSCON_RSTCON0_RSTUSB (1 << 31) /* USB interface reset control bit */ + +/* Reset Control Register 1 */ + +#define SYSCON_RSTCON1_RSTIOCON (1 << 0) /* Reset control bit for the IOCON registers */ +#define SYSCON_RSTCON1_RSTDAC (1 << 1) /* D/A converter (DAC) reset control bit */ +#define SYSCON_RSTCON1_RSTCANACC (1 << 2) /* CAN acceptance filter reset control bit */ + /* Bits 3-31: Reserved */ +/* Delay Control Register - EMC */ + /* Delay values multiplied by 250 picoseconds */ +#define SYSCON_EMCDLYCTL_CMDDLY_SHIFT (0) /* Bits 0-4: Delay value for EMC outputs in command delayed mode */ +#define SYSCON_EMCDLYCTL_CMDDLY_MASK (0x1f << SYSCON_EMCDLYCTL_CMDDLY_SHIFT) +# define SYSCON_EMCDLYCTL_CMDDLY(n) ((n-1) << SYSCON_EMCDLYCTL_CMDDLY_SHIFT) /* n = 3 - 32 */ + /* Bits 5-7: Reserved */ +#define SYSCON_EMCDLYCTL_FBCLKDLY_SHIFT (8) /* Bits 8-12: Delay value for the feedback clock that controls input data sampling */ +#define SYSCON_EMCDLYCTL_FBCLKDLY_MASK (0x1f << SYSCON_EMCDLYCTL_FBCLKDLY_SHIFT) +#define SYSCON_EMCDLYCTL_FBCLKDLY(n) ((n-1)<< SYSCON_EMCDLYCTL_FBCLKDLY_SHIFT) /* n = 3 - 32 */ + /* Bits 13-15: Reserved */ +#define SYSCON_EMCDLYCTL_CLKOUT0DLY_SHIFT (16) /* Bits 16-20: Delay value for the CLKOUT0 output */ +#define SYSCON_EMCDLYCTL_CLKOUT0DLY_MASK (0x1f << SYSCON_EMCDLYCTL_CLKOUT0DLY_SHIFT) +# define SYSCON_EMCDLYCTL_CLKOUT0DLY(n) ((n-1) << SYSCON_EMCDLYCTL_CLKOUT0DLY_SHIFT) /* n = 3 - 32 */ + /* Bits 21-23: Reserved */ +#define SYSCON_EMCDLYCTL_CLKOUT1DLY_SHIFT (24) /* Bits 24-28: Delay value for the CLKOUT1 output */ +#define SYSCON_EMCDLYCTL_CLKOUT1DLY_MASK (0x1f << SYSCON_EMCDLYCTL_CLKOUT1DLY_SHIFT) +# define SYSCON_EMCDLYCTL_CLKOUT1DLY(n) ((n-1) << SYSCON_EMCDLYCTL_CLKOUT1DLY_SHIFT) /* n = 3 - 32 */ + /* Bits 29-31: Reserved */ +/* Calibration Register - EMC */ + +#define SYSCON_EMCCAL_CALVALUE_SHIFT (0) /* Bits 0-7: Ring oscillator count during 32 clocks of Internal RC */ +#define SYSCON_EMCCAL_CALVALUE_MASK (0xff << SYSCON_EMCCAL_CALVALUE_SHIFT) + /* Bits 8-13: Reserved */ +#define SYSCON_EMCCAL_START_SHIFT (14) /* Bit 14: Start control bit for EMC calibration counter */ +#define SYSCON_EMCCAL_START_MASK (1 << SYSCON_EMCCAL_START_SHIFT) +# define SYSCON_EMCCAL_START (1) /* Automatically cleared when measurement is done */ +#define SYSCON_EMCCAL_DONE_SHIFT (15) /* Bit 15: Measurement completetion flag bit */ +#define SYSCON_EMCCAL_DONE_MASK (1 << SYSCON_EMCCAL_DONE_SHIFT) + /* Automatically cleared when START bit is set */ + /* Bits 16-31: Reserved */ + +/* Compatibility Definitions ************************************************************************/ +/* Need in lpc17_clockconfig.h for compatibility with the LPC176x family: */ + +#define SYSCON_PLLCON_PLLC (0) /* Bit does not exist in LPC178x family */ +#define SYSCON_PLL0STAT_PLLE SYSCON_PLLSTAT_PLLE /* PLL enable readback */ +#define SYSCON_PLL0STAT_PLLC SYSCON_PLLSTAT_PLLC /* PLL connect readback */ +#define SYSCON_PLL0STAT_PLOCK SYSCON_PLLSTAT_PLOCK /* PLL lock status */ +#define SYSCON_PLL1STAT_PLLE SYSCON_PLLSTAT_PLLE /* PLL enable readback */ +#define SYSCON_PLL1STAT_PLLC SYSCON_PLLSTAT_PLLC /* PLL connect readback */ +#define SYSCON_PLL1STAT_PLOCK SYSCON_PLLSTAT_PLOCK /* PLL lock status */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC178X_SYSCON_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc178x_vectors.h b/arch/arm/src/lpc17xx/chip/lpc178x_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..4b53f1f368a98a681ae038a57f497eafa4497a60 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc178x_vectors.h @@ -0,0 +1,117 @@ +/************************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc178x_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Rommel Marcelo + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +/********************************************************************************* + * Pre-processor Definitions + ********************************************************************************/ +/* This file is included by lpc17_vectors.S. It provides the macro VECTOR that + * supplies each LPC17xx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/lpc17/lpc17xx_irq.h. + * lpc17_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 41 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 41 + +#else + +VECTOR(lpc17_wdt, LPC17_IRQ_WDT) /* Vector 16+0: Watchdog timer */ +VECTOR(lpc17_tmr0, LPC17_IRQ_TMR0) /* Vector 16+1: Timer 0 */ +VECTOR(lpc17_tmr1, LPC17_IRQ_TMR1) /* Vector 16+2: Timer 1 */ +VECTOR(lpc17_tmr2, LPC17_IRQ_TMR2) /* Vector 16+3: Timer 2 */ +VECTOR(lpc17_tmr3, LPC17_IRQ_TMR3) /* Vector 16+4: Timer 3 */ +VECTOR(lpc17_uart0, LPC17_IRQ_UART0) /* Vector 16+5: UART 0 */ +VECTOR(lpc17_uart1, LPC17_IRQ_UART1) /* Vector 16+6: UART 1 */ +VECTOR(lpc17_uart2, LPC17_IRQ_UART2) /* Vector 16+7: UART 2 */ +VECTOR(lpc17_uart3, LPC17_IRQ_UART3) /* Vector 16+8: UART 3 */ +VECTOR(lpc17_pwm1, LPC17_IRQ_PWM1) /* Vector 16+9: PWM 1 */ +VECTOR(lpc17_i2c0, LPC17_IRQ_I2C0) /* Vector 16+10: I2C 0 */ +VECTOR(lpc17_i2c1, LPC17_IRQ_I2C1) /* Vector 16+11: I2C 1 */ +VECTOR(lpc17_i2c2, LPC17_IRQ_I2C2) /* Vector 16+12: I2C 2 */ +UNUSED(LPC17_IRQ_RESERVED29) /* Vector 16+13: Reserved */ +VECTOR(lpc17_ssp0, LPC17_IRQ_SSP0) /* Vector 16+14: SSP 0 */ +VECTOR(lpc17_ssp1, LPC17_IRQ_SSP1) /* Vector 16+15: SSP 1 */ +VECTOR(lpc17_pll0, LPC17_IRQ_PLL0) /* Vector 16+16: PLL 0 */ +VECTOR(lpc17_rtc, LPC17_IRQ_RTC) /* Vector 16+17: Real time clock */ +VECTOR(lpc17_eint0, LPC17_IRQ_EINT0) /* Vector 16+18: External interrupt 0 */ +VECTOR(lpc17_eint1, LPC17_IRQ_EINT1) /* Vector 16+19: External interrupt 1 */ +VECTOR(lpc17_eint2, LPC17_IRQ_EINT2) /* Vector 16+20: External interrupt 2 */ +VECTOR(lpc17_eint3, LPC17_IRQ_EINT3) /* Vector 16+21: External interrupt 3 */ +VECTOR(lpc17_adc, LPC17_IRQ_ADC) /* Vector 16+22: A/D Converter */ +VECTOR(lpc17_bod, LPC17_IRQ_BOD) /* Vector 16+23: Brown Out detect */ +VECTOR(lpc17_usb, LPC17_IRQ_USB) /* Vector 16+24: USB */ +VECTOR(lpc17_can, LPC17_IRQ_CAN) /* Vector 16+25: CAN */ +VECTOR(lpc17_gpdma, LPC17_IRQ_GPDMA) /* Vector 16+26: GPDMA */ +VECTOR(lpc17_i2s, LPC17_IRQ_I2S) /* Vector 16+27: I2S */ +VECTOR(lpc17_eth, LPC17_IRQ_ETH) /* Vector 16+28: Ethernet */ +VECTOR(lpc17_mci, LPC17_IRQ_MCI) /* Vector 16+29: MMC/SD */ +VECTOR(lpc17_mcpwm, LPC17_IRQ_MCPWM) /* Vector 16+30: Motor Control PWM */ +VECTOR(lpc17_qei, LPC17_IRQ_QEI) /* Vector 16+31: Quadrature Encoder */ +VECTOR(lpc17_pll1, LPC17_IRQ_PLL1) /* Vector 16+32: PLL 1 */ +VECTOR(lpc17_usbact, LPC17_IRQ_USBACT) /* Vector 16+33: USB Activity Interrupt */ +VECTOR(lpc17_canact, LPC17_IRQ_CANACT) /* Vector 16+34: CAN Activity Interrupt */ +VECTOR(lpc17_uart4, LPC17_IRQ_UART4) /* Vector 16+35: UART 4 */ +VECTOR(lpc17_ssp2, LPC17_IRQ_SSP2) /* Vector 16+36: SSP 2 */ +VECTOR(lpc17_lcd, LPC17_IRQ_LCD) /* Vector 16+37: LCD */ +VECTOR(lpc17_gpio, LPC17_IRQ_GPIO) /* Vector 16+38: GPIO */ +VECTOR(lpc17_pwm0, LPC17_IRQ_PWM0) /* Vector 16+39: PWM0 */ +VECTOR(lpc17_eeprom, LPC17_IRQ_EEPROM) /* Vector 16+40: EEPROM */ + +#endif + +/******************************************************************************** + * Public Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Public Function Prototypes + ********************************************************************************/ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_adc.h b/arch/arm/src/lpc17xx/chip/lpc17_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..8cec0d3250f632b03b211f405abd5428b2c39f43 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_adc.h @@ -0,0 +1,180 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_adc.h + * + * Copyright (C) 2010, 2012, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_ADC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_ADC_CR_OFFSET 0x0000 /* A/D Control Register */ +#define LPC17_ADC_GDR_OFFSET 0x0004 /* A/D Global Data Register */ +#define LPC17_ADC_INTEN_OFFSET 0x000c /* A/D Interrupt Enable Register */ + +#define LPC17_ADC_DR_OFFSET(n) (0x0010+((n) << 2)) +#define LPC17_ADC_DR0_OFFSET 0x0010 /* A/D Channel 0 Data Register */ +#define LPC17_ADC_DR1_OFFSET 0x0014 /* A/D Channel 1 Data Register */ +#define LPC17_ADC_DR2_OFFSET 0x0018 /* A/D Channel 2 Data Register */ +#define LPC17_ADC_DR3_OFFSET 0x001c /* A/D Channel 3 Data Register */ +#define LPC17_ADC_DR4_OFFSET 0x0020 /* A/D Channel 4 Data Register */ +#define LPC17_ADC_DR5_OFFSET 0x0024 /* A/D Channel 5 Data Register */ +#define LPC17_ADC_DR6_OFFSET 0x0028 /* A/D Channel 6 Data Register */ +#define LPC17_ADC_DR7_OFFSET 0x002c /* A/D Channel 7 Data Register */ + +#define LPC17_ADC_STAT_OFFSET 0x0030 /* A/D Status Register */ +#define LPC17_ADC_TRM_OFFSET 0x0034 /* ADC trim register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_ADC_CR (LPC17_ADC_BASE+LPC17_ADC_CR_OFFSET) +#define LPC17_ADC_GDR (LPC17_ADC_BASE+LPC17_ADC_GDR_OFFSET) +#define LPC17_ADC_INTEN (LPC17_ADC_BASE+LPC17_ADC_INTEN_OFFSET) + +#define LPC17_ADC_DR(n) (LPC17_ADC_BASE+LPC17_ADC_DR_OFFSET(n)) +#define LPC17_ADC_DR0 (LPC17_ADC_BASE+LPC17_ADC_DR0_OFFSET) +#define LPC17_ADC_DR1 (LPC17_ADC_BASE+LPC17_ADC_DR1_OFFSET) +#define LPC17_ADC_DR2 (LPC17_ADC_BASE+LPC17_ADC_DR2_OFFSET) +#define LPC17_ADC_DR3 (LPC17_ADC_BASE+LPC17_ADC_DR3_OFFSET) +#define LPC17_ADC_DR4 (LPC17_ADC_BASE+LPC17_ADC_DR4_OFFSET) +#define LPC17_ADC_DR5 (LPC17_ADC_BASE+LPC17_ADC_DR5_OFFSET) +#define LPC17_ADC_DR6 (LPC17_ADC_BASE+LPC17_ADC_DR6_OFFSET) +#define LPC17_ADC_DR7 (LPC17_ADC_BASE+LPC17_ADC_DR7_OFFSET) + +#define LPC17_ADC_STAT (LPC17_ADC_BASE+LPC17_ADC_STAT_OFFSET) +#define LPC17_ADC_TRM (LPC17_ADC_BASE+LPC17_ADC_TRM_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* A/D Control Register */ + +#define ADC_CR_SEL_SHIFT (0) /* Bits 0-7: Selects pins to be sampled */ +#define ADC_CR_SEL_MASK (0xff << ADC_CR_SEL_MASK) +#define ADC_CR_CLKDIV_SHIFT (8) /* Bits 8-15: APB clock (PCLK_ADC0) divisor */ +#define ADC_CR_CLKDIV_MASK (0xff << ADC_CR_CLKDIV_SHIFT) +#define ADC_CR_BURST (1 << 16) /* Bit 16: A/D Repeated conversions */ + /* Bits 17-20: Reserved */ +#define ADC_CR_PDN (1 << 21) /* Bit 21: A/D converter power-down mode */ + /* Bits 22-23: Reserved */ +#define ADC_CR_START_SHIFT (24) /* Bits 24-26: Control A/D conversion start */ +#define ADC_CR_START_MASK (7 << ADC_CR_START_SHIFT) +# define ADC_CR_START_NOSTART (0 << ADC_CR_START_SHIFT) /* No start */ +# define ADC_CR_START_NOW (1 << ADC_CR_START_SHIFT) /* Start now */ +# define ADC_CR_START_P2p10 (2 << ADC_CR_START_SHIFT) /* Start edge on P2.10/EINT0/NMI */ +# define ADC_CR_START_P1p27 (3 << ADC_CR_START_SHIFT) /* Start edge on P1.27/CLKOUT/USB_OVRCRn/CAP0.1 */ +# define ADC_CR_START_MAT0p1 (4 << ADC_CR_START_SHIFT) /* Start edge on MAT0.1 */ +# define ADC_CR_START_MAT0p3 (5 << ADC_CR_START_SHIFT) /* Start edge on MAT0.3 */ +# define ADC_CR_START_MAT1p0 (6 << ADC_CR_START_SHIFT) /* Start edge on MAT1.0 */ +# define ADC_CR_START_MAT1p1 (7 << ADC_CR_START_SHIFT) /* Start edge on MAT1.1 */ +#define ADC_CR_EDGE (1 << 27) /* Bit 27: Start on falling edge */ + /* Bits 28-31: Reserved */ +/* A/D Global Data Register AND Channel 0-7 Data Register */ + /* Bits 0-3: Reserved */ +#define ADC_DR_RESULT_SHIFT (4) /* Bits 4-15: Result of conversion (DONE==1) */ +#define ADC_DR_RESULT_MASK (0x0fff << ADC_DR_RESULT_SHIFT) + /* Bits 16-23: Reserved */ +#define ADC_DR_CHAN_SHIFT (24) /* Bits 24-26: Channel converted */ +#define ADC_DR_CHAN_MASK (3 << ADC_DR_CHN_SHIFT) + /* Bits 27-29: Reserved */ +#define ADC_DR_OVERRUN (1 << 30) /* Bit 30: Conversion(s) lost/overwritten*/ +#define ADC_DR_DONE (1 << 31) /* Bit 31: A/D conversion complete*/ + +/* A/D Interrupt Enable Register */ + +#define ADC_INTEN_CHAN(n) (1 << (n)) +#define ADC_INTEN_CHAN0 (1 << 0) /* Bit 0: Enable ADC chan 0 complete intterrupt */ +#define ADC_INTEN_CHAN1 (1 << 1) /* Bit 1: Enable ADC chan 1 complete interrupt */ +#define ADC_INTEN_CHAN2 (1 << 2) /* Bit 2: Enable ADC chan 2 complete interrupt */ +#define ADC_INTEN_CHAN3 (1 << 3) /* Bit 3: Enable ADC chan 3 complete interrupt */ +#define ADC_INTEN_CHAN4 (1 << 4) /* Bit 4: Enable ADC chan 4 complete interrupt */ +#define ADC_INTEN_CHAN5 (1 << 5) /* Bit 5: Enable ADC chan 5 complete interrupt */ +#define ADC_INTEN_CHAN6 (1 << 6) /* Bit 6: Enable ADC chan 6 complete interrupt */ +#define ADC_INTEN_CHAN7 (1 << 7) /* Bit 7: Enable ADC chan 7 complete interrupt */ +#define ADC_INTEN_GLOBAL (1 << 8) /* Bit 8: Only the global DONE generates interrupt */ + /* Bits 9-31: Reserved */ +/* A/D Status Register */ + +#define ADC_STAT_DONE(n) (1 << (n)) +#define ADC_STAT_DONE0 (1 << 0) /* Bit 0: A/D chan 0 DONE */ +#define ADC_STAT_DONE1 (1 << 1) /* Bit 1: A/D chan 1 DONE */ +#define ADC_STAT_DONE2 (1 << 2) /* Bit 2: A/D chan 2 DONE */ +#define ADC_STAT_DONE3 (1 << 3) /* Bit 3: A/D chan 3 DONE */ +#define ADC_STAT_DONE4 (1 << 4) /* Bit 4: A/D chan 4 DONE */ +#define ADC_STAT_DONE5 (1 << 5) /* Bit 5: A/D chan 5 DONE */ +#define ADC_STAT_DONE6 (1 << 6) /* Bit 6: A/D chan 6 DONE */ +#define ADC_STAT_DONE7 (1 << 7) /* Bit 7: A/D chan 7 DONE */ +#define ADC_STAT_OVERRUN(n) ((1 << (n)) + 8) +#define ADC_STAT_OVERRUN0 (1 << 8) /* Bit 8: A/D chan 0 OVERRUN */ +#define ADC_STAT_OVERRUN1 (1 << 9) /* Bit 9: A/D chan 1 OVERRUN */ +#define ADC_STAT_OVERRUN2 (1 << 10) /* Bit 10: A/D chan 2 OVERRUN */ +#define ADC_STAT_OVERRUN3 (1 << 11) /* Bit 11: A/D chan 3 OVERRUN */ +#define ADC_STAT_OVERRUN4 (1 << 12) /* Bit 12: A/D chan 4 OVERRUN */ +#define ADC_STAT_OVERRUN5 (1 << 13) /* Bit 13: A/D chan 5 OVERRUN */ +#define ADC_STAT_OVERRUN6 (1 << 14) /* Bit 14: A/D chan 6 OVERRUN */ +#define ADC_STAT_OVERRUN7 (1 << 15) /* Bit 15: A/D chan 7 OVERRUN */ +#define ADC_STAT_INT (1 << 16) /* Bit 15: A/D interrupt */ + /* Bits 17-31: Reserved */ +/* ADC trim register */ + /* Bits 0-3: Reserved */ +#define ADC_TRM_ADCOFFS_SHIFT (4) /* Bits 4-7: A/D offset trim bits */ +#define ADC_TRM_ADCOFFS_MASK (15 << ADC_TRM_ADCOFFS_SHIFT) +#define ADC_TRM_TRIM_SHIFT (8) /* Bits 8-11: Written-to by boot code */ +#define ADC_TRM_TRIM_MASK (15 << ADC_TRM_TRIM_SHIFT) + /* Bits 12-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_ADC_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_can.h b/arch/arm/src/lpc17xx/chip/lpc17_can.h new file mode 100644 index 0000000000000000000000000000000000000000..74a21094421c4c5c121709324172ca7a9e831721 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_can.h @@ -0,0 +1,510 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_can.h + * + * Copyright (C) 2010-2012, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_CAN_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* CAN acceptance filter registers */ + +#define LPC17_CANAF_AFMR_OFFSET 0x0000 /* Acceptance Filter Register */ +#define LPC17_CANAF_SFFSA_OFFSET 0x0004 /* Standard Frame Individual Start Address Register */ +#define LPC17_CANAF_SFFGRPSA_OFFSET 0x0008 /* Standard Frame Group Start Address Register */ +#define LPC17_CANAF_EFFSA_OFFSET 0x000c /* Extended Frame Start Address Register */ +#define LPC17_CANAF_EFFGRPSA_OFFSET 0x0010 /* Extended Frame Group Start Address Register */ +#define LPC17_CANAF_EOT_OFFSET 0x0014 /* End of AF Tables register */ +#define LPC17_CANAF_LUTERRAD_OFFSET 0x0018 /* LUT Error Address register */ +#define LPC17_CANAF_LUTERR_OFFSET 0x001c /* LUT Error Register */ +#define LPC17_CANAF_FCANIE_OFFSET 0x0020 /* FullCAN interrupt enable register */ +#define LPC17_CANAF_FCANIC0_OFFSET 0x0024 /* FullCAN interrupt and capture register 0 */ +#define LPC17_CANAF_FCANIC1_OFFSET 0x0028 /* FullCAN interrupt and capture register 1 */ + +/* Central CAN registers */ + +#define LPC17_CAN_TXSR_OFFSET 0x0000 /* CAN Central Transmit Status Register */ +#define LPC17_CAN_RXSR_OFFSET 0x0004 /* CAN Central Receive Status Register */ +#define LPC17_CAN_MSR_OFFSET 0x0008 /* CAN Central Miscellaneous Register */ + +/* CAN1/2 registers */ + +#define LPC17_CAN_MOD_OFFSET 0x0000 /* CAN operating mode */ +#define LPC17_CAN_CMR_OFFSET 0x0004 /* Command bits */ +#define LPC17_CAN_GSR_OFFSET 0x0008 /* Controller Status and Error Counters */ +#define LPC17_CAN_ICR_OFFSET 0x000c /* Interrupt and capure register */ +#define LPC17_CAN_IER_OFFSET 0x0010 /* Interrupt Enable */ +#define LPC17_CAN_BTR_OFFSET 0x0014 /* Bus Timing */ +#define LPC17_CAN_EWL_OFFSET 0x0018 /* Error Warning Limit */ +#define LPC17_CAN_SR_OFFSET 0x001c /* Status Register */ +#define LPC17_CAN_RFS_OFFSET 0x0020 /* Receive frame status */ +#define LPC17_CAN_RID_OFFSET 0x0024 /* Received Identifier */ +#define LPC17_CAN_RDA_OFFSET 0x0028 /* Received data bytes 1-4 */ +#define LPC17_CAN_RDB_OFFSET 0x002c /* Received data bytes 5-8 */ +#define LPC17_CAN_TFI1_OFFSET 0x0030 /* Transmit frame info (Tx Buffer 1) */ +#define LPC17_CAN_TID1_OFFSET 0x0034 /* Transmit Identifier (Tx Buffer 1) */ +#define LPC17_CAN_TDA1_OFFSET 0x0038 /* Transmit data bytes 1-4 (Tx Buffer 1) */ +#define LPC17_CAN_TDB1_OFFSET 0x003c /* Transmit data bytes 5-8 (Tx Buffer 1) */ +#define LPC17_CAN_TFI2_OFFSET 0x0040 /* Transmit frame info (Tx Buffer 2) */ +#define LPC17_CAN_TID2_OFFSET 0x0044 /* Transmit Identifier (Tx Buffer 2) */ +#define LPC17_CAN_TDA2_OFFSET 0x0048 /* Transmit data bytes 1-4 (Tx Buffer 2) */ +#define LPC17_CAN_TDB2_OFFSET 0x004c /* Transmit data bytes 5-8 (Tx Buffer 2) */ +#define LPC17_CAN_TFI3_OFFSET 0x0050 /* Transmit frame info (Tx Buffer 3) */ +#define LPC17_CAN_TID3_OFFSET 0x0054 /* Transmit Identifier (Tx Buffer 3) */ +#define LPC17_CAN_TDA3_OFFSET 0x0058 /* Transmit data bytes 1-4 (Tx Buffer 3) */ +#define LPC17_CAN_TDB3_OFFSET 0x005c /* Transmit data bytes 5-8 (Tx Buffer 3) */ + +/* Register addresses ***************************************************************/ +/* CAN acceptance filter registers */ + +#define LPC17_CANAF_AFMR (LPC17_CANAF_BASE+LPC17_CANAF_AFMR_OFFSET) +#define LPC17_CANAF_SFFSA (LPC17_CANAF_BASE+LPC17_CANAF_SFFSA_OFFSET) +#define LPC17_CANAF_SFFGRPSA (LPC17_CANAF_BASE+LPC17_CANAF_SFFGRPSA_OFFSET) +#define LPC17_CANAF_EFFSA (LPC17_CANAF_BASE+LPC17_CANAF_EFFSA_OFFSET) +#define LPC17_CANAF_EFFGRPSA (LPC17_CANAF_BASE+LPC17_CANAF_EFFGRPSA_OFFSET) +#define LPC17_CANAF_EOT (LPC17_CANAF_BASE+LPC17_CANAF_EOT_OFFSET) +#define LPC17_CANAF_LUTERRAD (LPC17_CANAF_BASE+LPC17_CANAF_LUTERRAD_OFFSET) +#define LPC17_CANAF_LUTERR (LPC17_CANAF_BASE+LPC17_CANAF_LUTERR_OFFSET) +#define LPC17_CANAF_FCANIE (LPC17_CANAF_BASE+LPC17_CANAF_FCANIE_OFFSET) +#define LPC17_CANAF_FCANIC0 (LPC17_CANAF_BASE+LPC17_CANAF_FCANIC0_OFFSET) +#define LPC17_CANAF_FCANIC1 (LPC17_CANAF_BASE+LPC17_CANAF_FCANIC1_OFFSET) + +/* Central CAN registers */ + +#define LPC17_CAN_TXSR (LPC17_CAN_BASE+LPC17_CAN_TXSR_OFFSET) +#define LPC17_CAN_RXSR (LPC17_CAN_BASE+LPC17_CAN_RXSR_OFFSET) +#define LPC17_CAN_MSR (LPC17_CAN_BASE+LPC17_CAN_MSR_OFFSET) + +/* CAN1/2 registers */ + +#define LPC17_CAN1_MOD (LPC17_CAN1_BASE+LPC17_CAN_MOD_OFFSET) +#define LPC17_CAN1_CMR (LPC17_CAN1_BASE+LPC17_CAN_CMR_OFFSET) +#define LPC17_CAN1_GSR (LPC17_CAN1_BASE+LPC17_CAN_GSR_OFFSET) +#define LPC17_CAN1_ICR (LPC17_CAN1_BASE+LPC17_CAN_ICR_OFFSET) +#define LPC17_CAN1_IER (LPC17_CAN1_BASE+LPC17_CAN_IER_OFFSET) +#define LPC17_CAN1_BTR (LPC17_CAN1_BASE+LPC17_CAN_BTR_OFFSET) +#define LPC17_CAN1_EWL (LPC17_CAN1_BASE+LPC17_CAN_EWL_OFFSET) +#define LPC17_CAN1_SR (LPC17_CAN1_BASE+LPC17_CAN_SR_OFFSET) +#define LPC17_CAN1_RFS (LPC17_CAN1_BASE+LPC17_CAN_RFS_OFFSET) +#define LPC17_CAN1_RID (LPC17_CAN1_BASE+LPC17_CAN_RID_OFFSET) +#define LPC17_CAN1_RDA (LPC17_CAN1_BASE+LPC17_CAN_RDA_OFFSET) +#define LPC17_CAN1_RDB (LPC17_CAN1_BASE+LPC17_CAN_RDB_OFFSET) +#define LPC17_CAN1_TFI1 (LPC17_CAN1_BASE+LPC17_CAN_TFI1_OFFSET) +#define LPC17_CAN1_TID1 (LPC17_CAN1_BASE+LPC17_CAN_TID1_OFFSET) +#define LPC17_CAN1_TDA1 (LPC17_CAN1_BASE+LPC17_CAN_TDA1_OFFSET) +#define LPC17_CAN1_TDB1 (LPC17_CAN1_BASE+LPC17_CAN_TDB1_OFFSET) +#define LPC17_CAN1_TFI2 (LPC17_CAN1_BASE+LPC17_CAN_TFI2_OFFSET) +#define LPC17_CAN1_TID2 (LPC17_CAN1_BASE+LPC17_CAN_TID2_OFFSET) +#define LPC17_CAN1_TDA2 (LPC17_CAN1_BASE+LPC17_CAN_TDA2_OFFSET) +#define LPC17_CAN1_TDB2 (LPC17_CAN1_BASE+LPC17_CAN_TDB2_OFFSET) +#define LPC17_CAN1_TFI3 (LPC17_CAN1_BASE+LPC17_CAN_TFI3_OFFSET) +#define LPC17_CAN1_TID3 (LPC17_CAN1_BASE+LPC17_CAN_TID3_OFFSET) +#define LPC17_CAN1_TDA3 (LPC17_CAN1_BASE+LPC17_CAN_TDA3_OFFSET) +#define LPC17_CAN1_TDB3 (LPC17_CAN1_BASE+LPC17_CAN_TDB3_OFFSET) + +#define LPC17_CAN2_MOD (LPC17_CAN2_BASE+LPC17_CAN_MOD_OFFSET) +#define LPC17_CAN2_CMR (LPC17_CAN2_BASE+LPC17_CAN_CMR_OFFSET) +#define LPC17_CAN2_GSR (LPC17_CAN2_BASE+LPC17_CAN_GSR_OFFSET) +#define LPC17_CAN2_ICR (LPC17_CAN2_BASE+LPC17_CAN_ICR_OFFSET) +#define LPC17_CAN2_IER (LPC17_CAN2_BASE+LPC17_CAN_IER_OFFSET) +#define LPC17_CAN2_BTR (LPC17_CAN2_BASE+LPC17_CAN_BTR_OFFSET) +#define LPC17_CAN2_EWL (LPC17_CAN2_BASE+LPC17_CAN_EWL_OFFSET) +#define LPC17_CAN2_SR (LPC17_CAN2_BASE+LPC17_CAN_SR_OFFSET) +#define LPC17_CAN2_RFS (LPC17_CAN2_BASE+LPC17_CAN_RFS_OFFSET) +#define LPC17_CAN2_RID (LPC17_CAN2_BASE+LPC17_CAN_RID_OFFSET) +#define LPC17_CAN2_RDA (LPC17_CAN2_BASE+LPC17_CAN_RDA_OFFSET) +#define LPC17_CAN2_RDB (LPC17_CAN2_BASE+LPC17_CAN_RDB_OFFSET) +#define LPC17_CAN2_TFI1 (LPC17_CAN2_BASE+LPC17_CAN_TFI1_OFFSET) +#define LPC17_CAN2_TID1 (LPC17_CAN2_BASE+LPC17_CAN_TID1_OFFSET) +#define LPC17_CAN2_TDA1 (LPC17_CAN2_BASE+LPC17_CAN_TDA1_OFFSET) +#define LPC17_CAN2_TDB1 (LPC17_CAN2_BASE+LPC17_CAN_TDB1_OFFSET) +#define LPC17_CAN2_TFI2 (LPC17_CAN2_BASE+LPC17_CAN_TFI2_OFFSET) +#define LPC17_CAN2_TID2 (LPC17_CAN2_BASE+LPC17_CAN_TID2_OFFSET) +#define LPC17_CAN2_TDA2 (LPC17_CAN2_BASE+LPC17_CAN_TDA2_OFFSET) +#define LPC17_CAN2_TDB2 (LPC17_CAN2_BASE+LPC17_CAN_TDB2_OFFSET) +#define LPC17_CAN2_TFI3 (LPC17_CAN2_BASE+LPC17_CAN_TFI3_OFFSET) +#define LPC17_CAN2_TID3 (LPC17_CAN2_BASE+LPC17_CAN_TID3_OFFSET) +#define LPC17_CAN2_TDA3 (LPC17_CAN2_BASE+LPC17_CAN_TDA3_OFFSET) +#define LPC17_CAN2_TDB3 (LPC17_CAN2_BASE+LPC17_CAN_TDB3_OFFSET) + +/* Register bit definitions *********************************************************/ +/* CAN acceptance filter registers */ +/* Acceptance Filter Register */ + +#define CANAF_AFMR_ACCOFF (1 << 0) /* Bit 0: AF non-operational; All RX messages ignored */ +#define CANAF_AFMR_ACCBP (1 << 1) /* Bit 1: AF bypass: All RX messages accepted */ +#define CANAF_AFMR_EFCAN (1 << 2) /* Bit 2: Enable Full CAN mode */ + /* Bits 3-31: Reserved */ +/* Standard Frame Individual Start Address Register */ + /* Bits 0-1: Reserved */ +#define CANAF_SFFSA_SHIFT (2) /* Bits 2-10: Address of Standard Identifiers in AF Lookup RAM */ +#define CANAF_SFFSA_MASK (0x01ff << CANAF_SFFSA_SHIFT) + /* Bits 11-31: Reserved */ +/* Standard Frame Group Start Address Register */ + /* Bits 0-1: Reserved */ +#define CANAF_SFFGRPSA_SHIFT (2) /* Bits 2-10: Address of grouped Standard Identifiers in AF Lookup RAM */ +#define CANAF_SFFGRPSA_MASK (0x01ff << CANAF_SFFGRPSA_SHIFT) + /* Bits 11-31: Reserved */ +/* Extended Frame Start Address Register */ + /* Bits 0-1: Reserved */ +#define CANAF_EFFSA_SHIFT (2) /* Bits 2-10: Address of Extended Identifiers in AF Lookup RAM */ +#define CANAF_EFFSA_MASK (0x01ff << CANAF_EFFSA_SHIFT) + /* Bits 11-31: Reserved */ +/* Extended Frame Group Start Address Register */ + /* Bits 0-1: Reserved */ +#define CANAF_EFFGRPSA_SHIFT (2) /* Bits 2-10: Address of grouped Extended Identifiers in AF Lookup RAM */ +#define CANAF_EFFGRPSA_MASK (0x01ff << CANAF_EFFGRPSA_SHIFT) + /* Bits 11-31: Reserved */ +/* End of AF Tables register */ + /* Bits 0-1: Reserved */ +#define CANAF_EOT_SHIFT (2) /* Bits 2-10: Last active address in last active AF table */ +#define CANAF_EOT_MASK (0x01ff << CANAF_EOT_SHIFT) + /* Bits 11-31: Reserved */ +/* LUT Error Address register */ + /* Bits 0-1: Reserved */ +#define CANAF_LUTERRAD_SHIFT (2) /* Bits 2-10: Address in AF Lookup RAM of error */ +#define CANAF_LUTERRAD_MASK (0x01ff << CANAF_EOT_SHIFT) + /* Bits 11-31: Reserved */ +/* LUT Error Register */ + +#define CANAF_LUTERR_LUTERR (1 << 0) /* Bit 0: AF error in AF RAM tables */ + /* Bits 1-31: Reserved */ +/* FullCAN interrupt enable register */ + +#define CANAF_FCANIE_FCANIE (1 << 0) /* Bit 0: Global FullCAN Interrupt Enable */ + /* Bits 1-31: Reserved */ + +/* FullCAN interrupt and capture register 0 */ + +#define CANAF_FCANIC0_INTPND(n) (1 << (n)) /* n=0,1,2,... 31 */ + +/* FullCAN interrupt and capture register 1 */ + +#define CANAF_FCANIC1_INTPND(n) (1 << ((n)-32)) /* n=32,33,...63 */ + +/* Central CAN registers */ +/* CAN Central Transmit Status Register */ + +#define CAN_TXSR_TS1 (1 << 0) /* Bit 0: CAN1 sending */ +#define CAN_TXSR_TS2 (1 << 1) /* Bit 1: CAN2 sending */ + /* Bits 2-7: Reserved */ +#define CAN_TXSR_TBS1 (1 << 8) /* Bit 8: All 3 CAN1 TX buffers available */ +#define CAN_TXSR_TBS2 (1 << 9) /* Bit 9: All 3 CAN2 TX buffers available */ + /* Bits 10-15: Reserved */ +#define CAN_TXSR_TCS1 (1 << 16) /* Bit 16: All CAN1 xmissions completed */ +#define CAN_TXSR_TCS2 (1 << 17) /* Bit 17: All CAN2 xmissions completed */ + /* Bits 18-31: Reserved */ +/* CAN Central Receive Status Register */ + +#define CAN_RXSR_RS1 (1 << 0) /* Bit 0: CAN1 receiving */ +#define CAN_RXSR_RS2 (1 << 1) /* Bit 1: CAN2 receiving */ + /* Bits 2-7: Reserved */ +#define CAN_RXSR_RB1 (1 << 8) /* Bit 8: CAN1 received message available */ +#define CAN_RXSR_RB2 (1 << 9) /* Bit 9: CAN2 received message available */ + /* Bits 10-15: Reserved */ +#define CAN_RXSR_DOS1 (1 << 16) /* Bit 16: All CAN1 message lost */ +#define CAN_RXSR_DOS2 (1 << 17) /* Bit 17: All CAN2 message lost */ + /* Bits 18-31: Reserved */ +/* CAN Central Miscellaneous Register */ + +#define CAN_MSR_E1 (1 << 0) /* Bit 0: CAN1 error counters at limit */ +#define CAN_MSR_E2 (1 << 1) /* Bit 1: CAN2 error counters at limit */ + /* Bits 2-7: Reserved */ +#define CAN_MSR_BS1 (1 << 8) /* Bit 8: CAN1 busy */ +#define CAN_MSR_BS2 (1 << 9) /* Bit 7: CAN2 busy */ + /* Bits 10-31: Reserved */ +/* CAN1/2 registers */ +/* CAN operating mode */ + +#define CAN_MOD_RM (1 << 0) /* Bit 0: Reset Mode */ +#define CAN_MOD_LOM (1 << 1) /* Bit 1: Listen Only Mode */ +#define CAN_MOD_STM (1 << 2) /* Bit 2: Self Test Mode */ +#define CAN_MOD_TPM (1 << 3) /* Bit 3: Transmit Priority Mode */ +#define CAN_MOD_SM (1 << 4) /* Bit 4: Sleep Mode */ +#define CAN_MOD_RPM (1 << 5) /* Bit 5: Receive Polarity Mode */ + /* Bit 6: Reserved */ +#define CAN_MOD_TM (1 << 7) /* Bit 7: Test Mode */ + /* Bits 8-31: Reserved */ +/* Command bits */ + +#define CAN_CMR_TR (1 << 0) /* Bit 0: Transmission Request */ +#define CAN_CMR_AT (1 << 1) /* Bit 1: Abort Transmission */ +#define CAN_CMR_RRB (1 << 2) /* Bit 2: Release Receive Buffer */ +#define CAN_CMR_CDO (1 << 3) /* Bit 3: Clear Data Overrun */ +#define CAN_CMR_SRR (1 << 4) /* Bit 4: Self Reception Request */ +#define CAN_CMR_STB1 (1 << 5) /* Bit 5: Select Tx Buffer 1 */ +#define CAN_CMR_STB2 (1 << 6) /* Bit 6: Select Tx Buffer 2 */ +#define CAN_CMR_STB3 (1 << 7) /* Bit 7: Select Tx Buffer 3 */ + /* Bits 8-31: Reserved */ +/* Controller Status and Error Counters */ + +#define CAN_GSR_RBS (1 << 0) /* Bit 0: Receive Buffer Status */ +#define CAN_GSR_DOS (1 << 1) /* Bit 1: Data Overrun Status */ +#define CAN_GSR_TBS (1 << 2) /* Bit 2: Transmit Buffer Status */ +#define CAN_GSR_TCS (1 << 3) /* Bit 3: Transmit Complete Status */ +#define CAN_GSR_RS (1 << 4) /* Bit 4: Receive Status */ +#define CAN_GSR_TS (1 << 5) /* Bit 5: Transmit Status */ +#define CAN_GSR_ES (1 << 6) /* Bit 6: Error Status */ +#define CAN_GSR_BS (1 << 7) /* Bit 7: Bus Status */ + /* Bits 8-15: Reserved */ +#define CAN_GSR_RXERR_SHIFT (16) /* Bits 16-23: Rx Error Counter */ +#define CAN_GSR_RXERR_MASK (0xff << CAN_GSR_RXERR_SHIFT) +#define CAN_GSR_TXERR_SHIFT (24) /* Bits 24-31: Tx Error Counter */ +#define CAN_GSR_TXERR_MASK (0xff << CAN_GSR_TXERR_SHIFT) + +/* Interrupt and capture register */ + +#define CAN_ICR_RI (1 << 0) /* Bit 0: Receive Interrupt */ +#define CAN_ICR_TI1 (1 << 1) /* Bit 1: Transmit Interrupt 1 */ +#define CAN_ICR_EI (1 << 2) /* Bit 2: Error Warning Interrupt */ +#define CAN_ICR_DOI (1 << 3) /* Bit 3: Data Overrun Interrupt */ +#define CAN_ICR_WUI (1 << 4) /* Bit 4: Wake-Up Interrupt */ +#define CAN_ICR_EPI (1 << 5) /* Bit 5: Error Passive Interrupt */ +#define CAN_ICR_ALI (1 << 6) /* Bit 6: Arbitration Lost Interrupt */ +#define CAN_ICR_BEI (1 << 7) /* Bit 7: Bus Error Interrupt */ +#define CAN_ICR_IDI (1 << 8) /* Bit 8: ID Ready Interrupt */ +#define CAN_ICR_TI2 (1 << 9) /* Bit 9: Transmit Interrupt 2 */ +#define CAN_ICR_TI3 (1 << 10) /* Bit 10: Transmit Interrupt 3 */ + /* Bits 11-15: Reserved */ +#define CAN_ICR_ERRBIT_SHIFT (16) /* Bits 16-20: Error Code Capture */ +#define CAN_ICR_ERRBIT_MASK (0x1f << CAN_ICR_ERRBIT_SHIFT) +# define CAN_ICR_ERRBIT_SOF (3 << CAN_ICR_ERRBIT_SHIFT) /* Start of Frame */ +# define CAN_ICR_ERRBIT_ID28 (2 << CAN_ICR_ERRBIT_SHIFT) /* ID28 ... ID21 */ +# define CAN_ICR_ERRBIT_SRTR (4 << CAN_ICR_ERRBIT_SHIFT) /* SRTR Bit */ +# define CAN_ICR_ERRBIT_IDE (5 << CAN_ICR_ERRBIT_SHIFT) /* DE bit */ +# define CAN_ICR_ERRBIT_ID20 (6 << CAN_ICR_ERRBIT_SHIFT) /* ID20 ... ID18 */ +# define CAN_ICR_ERRBIT_ID17 (7 << CAN_ICR_ERRBIT_SHIFT) /* ID17 ... 13 */ +# define CAN_ICR_ERRBIT_CRC (8 << CAN_ICR_ERRBIT_SHIFT) /* CRC Sequence */ +# define CAN_ICR_ERRBIT_DATA (10 << CAN_ICR_ERRBIT_SHIFT) /* Data Field */ +# define CAN_ICR_ERRBIT_LEN (11 << CAN_ICR_ERRBIT_SHIFT) /* Data Length Code */ +# define CAN_ICR_ERRBIT_ RTR (12 << CAN_ICR_ERRBIT_SHIFT) /* RTR Bit */ +# define CAN_ICR_ERRBIT_ID4 (14 << CAN_ICR_ERRBIT_SHIFT) /* ID4 ... ID0 */ +# define CAN_ICR_ERRBIT_ID12 (15 << CAN_ICR_ERRBIT_SHIFT) /* ID12 ... ID5 */ +# define CAN_ICR_ERRBIT_AERR (17 << CAN_ICR_ERRBIT_SHIFT) /* Active Error Flag */ +# define CAN_ICR_ERRBIT_INTERMSN (18 << CAN_ICR_ERRBIT_SHIFT) /* Intermission */ +# define CAN_ICR_ERRBIT_DOM (19 << CAN_ICR_ERRBIT_SHIFT) /* Tolerate Dominant Bits */ +# define CAN_ICR_ERRBIT_PERR (22 << CAN_ICR_ERRBIT_SHIFT) /* Passive Error Flag */ +# define CAN_ICR_ERRBIT_ERRDLM (23 << CAN_ICR_ERRBIT_SHIFT) /* Error Delimiter */ +# define CAN_ICR_ERRBIT_CRCDLM (24 << CAN_ICR_ERRBIT_SHIFT) /* CRC Delimiter */ +# define CAN_ICR_ERRBIT_ACKSLT (25 << CAN_ICR_ERRBIT_SHIFT) /* Acknowledge Slot */ +# define CAN_ICR_ERRBIT_EOF (26 << CAN_ICR_ERRBIT_SHIFT) /* End of Frame */ +# define CAN_ICR_ERRBIT_ACKDLM (27 << CAN_ICR_ERRBIT_SHIFT) /* Acknowledge Delimiter */ +# define CAN_ICR_ERRBIT_OVLD (28 << CAN_ICR_ERRBIT_SHIFT) /* Overload flag */ +#define CAN_ICR_ERRDIR (1 << 21) /* Bit 21: Direction bit at time of error */ +#define CAN_ICR_ERRC_SHIFT (22) /* Bits 22-23: Type of error */ +#define CAN_ICR_ERRC_MASK (3 << CAN_ICR_ERRC_SHIFT) +# define CAN_ICR_ERRC_BIT (0 << CAN_ICR_ERRC_SHIFT) +# define CAN_ICR_ERRC_FORM (1 << CAN_ICR_ERRC_SHIFT) +# define CAN_ICR_ERRC_STUFF (2 << CAN_ICR_ERRC_SHIFT) +# define CAN_ICR_ERRC_OTHER (3 << CAN_ICR_ERRC_SHIFT) +#define CAN_ICR_ALCBIT_SHIFT (24) /* Bits 24-31: Bit number within frame */ +#define CAN_ICR_ALCBIT_MASK (0xff << CAN_ICR_ALCBIT_SHIFT) + +/* Interrupt Enable */ + +#define CAN_IER_RIE (1 << 0) /* Bit 0: Receiver Interrupt Enable */ +#define CAN_IER_TIE1 (1 << 1) /* Bit 1: Transmit Interrupt Enable for Buffer1 */ +#define CAN_IER_EIE (1 << 2) /* Bit 2: Error Warning Interrupt Enable */ +#define CAN_IER_DOIE (1 << 3) /* Bit 3: Data Overrun Interrupt Enable */ +#define CAN_IER_WUIE (1 << 4) /* Bit 4: Wake-Up Interrupt Enable */ +#define CAN_IER_EPIE (1 << 5) /* Bit 5: Error Passive Interrupt Enable */ +#define CAN_IER_ALIE (1 << 6) /* Bit 6: Arbitration Lost Interrupt Enable */ +#define CAN_IER_BEIE (1 << 7) /* Bit 7: Bus Error Interrupt */ +#define CAN_IER_IDIE (1 << 8) /* Bit 8: ID Ready Interrupt Enable */ +#define CAN_IER_TIE2 (1 << 9) /* Bit 9: Transmit Interrupt Enable for Buffer2 */ +#define CAN_IER_TIE3 (1 << 10) /* Bit 10: Transmit Interrupt Enable for Buffer3 */ + /* Bits 11-31: Reserved */ +/* Bus Timing */ + +#define CAN_BTR_BRP_SHIFT (0) /* Bits 0-9: Baud Rate Prescaler */ +#define CAN_BTR_BRP_MASK (0x3ff << CAN_BTR_BRP_SHIFT) + /* Bits 10-13: Reserved */ +#define CAN_BTR_SJW_SHIFT (14) /* Bits 14-15: Synchronization Jump Width */ +#define CAN_BTR_SJW_MASK (3 << CAN_BTR_SJW_SHIFT) +#define CAN_BTR_TSEG1_SHIFT (16) /* Bits 16-19: Sync to sample delay */ +#define CAN_BTR_TSEG1_MASK (15 << CAN_BTR_TSEG1_SHIFT) +#define CAN_BTR_TSEG2_SHIFT (20) /* Bits 20-22: smaple to next delay */ +#define CAN_BTR_TSEG2_MASK (7 << CAN_BTR_TSEG2_SHIFT) +#define CAN_BTR_SAM (1 << 23) /* Bit 23: Sampling */ + /* Bits 24-31: Reserved */ + +#define CAN_BTR_BRP_MAX (1024) /* Maximum BTR value (without decrement) */ +#define CAN_BTR_TSEG1_MAX (16) /* Maximum TSEG1 value (without decrement) */ +#define CAN_BTR_TSEG2_MAX (8) /* Maximum TSEG2 value (without decrement) */ + +/* Error Warning Limit */ + +#define CAN_EWL_SHIFT (0) /* Bits 0-7: Error warning limit */ +#define CAN_EWL_MASK (0xff << CAN_EWL_SHIFT) + /* Bits 8-31: Reserved */ +/* Status Register */ + +#define CAN_SR_RBS1 (1 << 0) /* Bit 0: Receive Buffer Status */ +#define CAN_SR_DOS1 (1 << 1) /* Bit 1: Data Overrun Status */ +#define CAN_SR_TBS1 (1 << 2) /* Bit 2: Transmit Buffer Status 1 */ +#define CAN_SR_TCS1 (1 << 3) /* Bit 3: Transmission Complete Status */ +#define CAN_SR_RS1 (1 << 4) /* Bit 4: Receive Status */ +#define CAN_SR_TS1 (1 << 5) /* Bit 5: Transmit Status 1 */ +#define CAN_SR_ES1 (1 << 6) /* Bit 6: Error Status */ +#define CAN_SR_BS1 (1 << 7) /* Bit 7: Bus Status */ +#define CAN_SR_RBS2 (1 << 8) /* Bit 8: Receive Buffer Status */ +#define CAN_SR_DOS2 (1 << 9) /* Bit 9: Data Overrun Status */ +#define CAN_SR_TBS2 (1 << 10) /* Bit 10: Transmit Buffer Status 2 */ +#define CAN_SR_TCS2 (1 << 11) /* Bit 11: Transmission Complete Status */ +#define CAN_SR_RS2 (1 << 12) /* Bit 12: Receive Status */ +#define CAN_SR_TS2 (1 << 13) /* Bit 13: Transmit Status 2 */ +#define CAN_SR_ES2 (1 << 14) /* Bit 14: Error Status */ +#define CAN_SR_BS2 (1 << 15) /* Bit 15: Bus Status */ +#define CAN_SR_RBS3 (1 << 16) /* Bit 16: Receive Buffer Status */ +#define CAN_SR_DOS3 (1 << 17) /* Bit 17: Data Overrun Status */ +#define CAN_SR_TBS3 (1 << 18) /* Bit 18: Transmit Buffer Status 3 */ +#define CAN_SR_TCS3 (1 << 19) /* Bit 19: Transmission Complete Status */ +#define CAN_SR_RS3 (1 << 20) /* Bit 20: Receive Status */ +#define CAN_SR_TS3 (1 << 21) /* Bit 21: Transmit Status 3 */ +#define CAN_SR_ES3 (1 << 22) /* Bit 22: Error Status */ +#define CAN_SR_BS3 (1 << 23) /* Bit 23: Bus Status */ + /* Bits 24-31: Reserved */ +/* Receive frame status */ + +#define CAN_RFS_ID_SHIFT (0) /* Bits 0-9: ID Index */ +#define CAN_RFS_ID_MASK (0x03ff << CAN_RFS_ID_SHIFT) +#define CAN_RFS_BP (1 << 10) /* Bit 10: Received in AF Bypass mode */ + /* Bits 11-15: Reserved */ +#define CAN_RFS_DLC_SHIFT (16) /* Bits 16-19: Message Data Length Code (DLC) */ +#define CAN_RFS_DLC_MASK (15 << CAN_RFS_DLC_SHIFT) + /* Bits 20-29: Reserved */ +#define CAN_RFS_RTR (1 << 30) /* Bit 30: Message Remote Transmission Request */ +#define CAN_RFS_FF (1 << 31) /* Bit 31: Message 29-bit vs 11-bit ID */ + +/* Received Identifier */ + +#define CAN_RID_ID11_MASK (0x7ff) /* Bits 0-10: 11-bit Identifier (FF=0) */ + /* Bits 11-31: Reserved */ +#define CAN_RID_ID29_MASK (0x1fffffff) /* Bits 0-28: 29-bit Identifiter (FF=1) */ + /* Bits 29-31: Reserved */ +/* Received data bytes 1-4 */ + +#define CAN_RDA_DATA1_SHIFT (0) /* Bits 0-7: If CANRFS >= 1 */ +#define CAN_RDA_DATA1_MASK (0x0ff << CAN_RDA_DATA1_SHIFT) +#define CAN_RDA_DATA2_SHIFT (8) /* Bits 8-15: If CANRFS >= 2 */ +#define CAN_RDA_DATA2_MASK (0x0ff << CAN_RDA_DATA2_SHIFT) +#define CAN_RDA_DATA3_SHIFT (16) /* Bits 16-23: If CANRFS >= 3 */ +#define CAN_RDA_DATA3_MASK (0x0ff << CAN_RDA_DATA3_SHIFT) +#define CAN_RDA_DATA4_SHIFT (24) /* Bits 24-31: If CANRFS >= 4 */ +#define CAN_RDA_DATA4_MASK (0x0ff << CAN_RDA_DATA4_SHIFT) + +/* Received data bytes 5-8 */ + +#define CAN_RDB_DATA5_SHIFT (0) /* Bits 0-7: If CANRFS >= 5 */ +#define CAN_RDB_DATA5_MASK (0x0ff << CAN_RDB_DATA5_SHIFT) +#define CAN_RDB_DATA6_SHIFT (8) /* Bits 8-15: If CANRFS >= 6 */ +#define CAN_RDB_DATA6_MASK (0x0ff << CAN_RDB_DATA6_SHIFT) +#define CAN_RDB_DATA7_SHIFT (16) /* Bits 16-23: If CANRFS >= 7 */ +#define CAN_RDB_DATA7_MASK (0x0ff << CAN_RDB_DATA7_SHIFT) +#define CAN_RDB_DATA8_SHIFT (24) /* Bits 24-31: If CANRFS >= 8 */ +#define CAN_RDB_DATA8_MASK (0x0ff << CAN_RDB_DATA8_SHIFT) + +/* Transmit frame info (Tx Buffer 1), Transmit frame info (Tx Buffer 2), and + * Transmit frame info (Tx Buffer 3) common bit field definitions + */ + +#define CAN_TFI_PRIO_SHIFT (0) /* Bits 0-7: TX buffer priority */ +#define CAN_TFI_PRIO_MASK (0xff << CAN_TFI_PRIO_SHIFT) + /* Bits 8-15: Reserved */ +#define CAN_TFI_DLC_SHIFT (16) /* Bits 16-19: TX Data Length Code */ +#define CAN_TFI_DLC_MASK (15 << CAN_TFI_DLC_SHIFT) + /* Bits 20-29: Reserved */ +#define CAN_TFI_RTR (1 << 30) /* Bit 30: TX RTR bit */ +#define CAN_TFI_FF (1 << 31) /* Bit 31: Message 29-bit vs 11-bit ID */ + +/* Transmit Identifier (Tx Buffer 1), Transmit Identifier (Tx Buffer 2), and + * Transmit Identifier (Tx Buffer 3) common bit field definitions. + */ + +#define CAN_TID_ID11_MASK (0x7ff) /* Bits 0-10: 11-bit Identifier (FF=0) */ + /* Bits 11-31: Reserved */ +#define CAN_TID_ID29_MASK (0x1fffffff) /* Bits 0-28: 29-bit Identifiter (FF=1) */ + /* Bits 29-31: Reserved */ + +/* Transmit data bytes 1-4 (Tx Buffer 1), Transmit data bytes 1-4 (Tx Buffer 2), and + * Transmit data bytes 1-4 (Tx Buffer 3) common bit field definitions. + */ + +#define CAN_TDA_DATA1_SHIFT (0) /* Bits 0-7: RTR=0 && DLC >= 1 */ +#define CAN_TDA_DATA1_MASK (0x0ff << CAN_TDA_DATA1_SHIFT) +#define CAN_TDA_DATA2_SHIFT (8) /* Bits 8-15: RTR=0 && DLC >= 2 */ +#define CAN_TDA_DATA2_MASK (0x0ff << CAN_TDA_DATA2_SHIFT) +#define CAN_TDA_DATA3_SHIFT (16) /* Bits 16-23: RTR=0 && DLC >= 3 */ +#define CAN_TDA_DATA3_MASK (0x0ff << CAN_TDA_DATA3_SHIFT) +#define CAN_TDA_DATA4_SHIFT (24) /* Bits 24-31: RTR=0 && DLC >= 4 */ +#define CAN_TDA_DATA4_MASK (0x0ff << CAN_TDA_DATA4_SHIFT) + +/* Transmit data bytes 5-8 (Tx Buffer 1), Transmit data bytes 5-8 (Tx Buffer 2), and + * Transmit data bytes 5-8 (Tx Buffer 3) common bit field definitions. + */ + +#define CAN_RDB_DATA5_SHIFT (0) /* Bits 0-7: RTR=0 && DLC >= 5 */ +#define CAN_RDB_DATA5_MASK (0x0ff << CAN_RDB_DATA5_SHIFT) +#define CAN_RDB_DATA6_SHIFT (8) /* Bits 8-15: RTR=0 && DLC >= 6 */ +#define CAN_RDB_DATA6_MASK (0x0ff << CAN_RDB_DATA6_SHIFT) +#define CAN_RDB_DATA7_SHIFT (16) /* Bits 16-23: RTR=0 && DLC >= 7 */ +#define CAN_RDB_DATA7_MASK (0x0ff << CAN_RDB_DATA7_SHIFT) +#define CAN_RDB_DATA8_SHIFT (24) /* Bits 24-31: RTR=0 && DLC >= 8 */ +#define CAN_RDB_DATA8_MASK (0x0ff << CAN_RDB_DATA8_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_CAN_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_dac.h b/arch/arm/src/lpc17xx/chip/lpc17_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..be78bef059b0c4a7f11b2af61c9beadf18ae3387 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_dac.h @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_dac.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_DAC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_DAC_CR_OFFSET 0x0000 /* D/A Converter Register */ +#define LPC17_DAC_CTRL_OFFSET 0x0004 /* DAC Control register */ +#define LPC17_DAC_CNTVAL_OFFSET 0x0008 /* DAC Counter Value register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_DAC_CR (LPC17_DAC_BASE+LPC17_DAC_CR_OFFSET) +#define LPC17_DAC_CTRL (LPC17_DAC_BASE+LPC17_DAC_CTRL_OFFSET) +#define LPC17_DAC_CNTVAL (LPC17_DAC_BASE+LPC17_DAC_CNTVAL_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* D/A Converter Register */ + /* Bits 0-5: Reserved */ +#define DAC_CR_VALUE_SHIFT (6) /* Bits 6-15: Controls voltage on the AOUT pin */ +#define DAC_CR_VALUE_MASK (0x3ff << DAC_CR_VALUE_SHIFT) +#define DAC_CR_BIAS (1 << 16) /* Bit 16: Controls DAC settling time */ + /* Bits 17-31: Reserved */ +/* DAC Control register */ + +#define DAC_CTRL_INTDMAREQ (1 << 0) /* Bit 0: Timer timed out */ +#define DAC_CTRL_DBLBUFEN (1 << 1) /* Bit 1: Enable DACR double-buffering */ +#define DAC_CTRL_CNTEN (1 << 2) /* Bit 2: Enable timeout counter */ +#define DAC_CTRL_DMAEN (1 << 3) /* Bit 3: Enable DMA access */ + /* Bits 4-31: Reserved */ +/* DAC Counter Value register */ + +#define DAC_CNTVAL_SHIFT (0) /* Bits 0-15: Reload value for DAC interrupt/DMA timer */ +#define DAC_CNTVAL_MASK (0xffff << DAC_CNTVAL_SHIFT) + /* Bits 8-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_DAC_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_eeprom.h b/arch/arm/src/lpc17xx/chip/lpc17_eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..7f14770431463c30d384bc675cab8d40bd8186c2 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_eeprom.h @@ -0,0 +1,186 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_eeprom.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EEPROM_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EEPROM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_EEPROM_EECMD_OFFSET 0x0080 /* Command register */ +#define LPC17_EEPROM_EEADDR_OFFSET 0x0084 /* Address register */ +#define LPC17_EEPROM_EEWDATA_OFFSET 0x0088 /* Write Data register */ +#define LPC17_EEPROM_EERDATA_OFFSET 0x008c /* Read Data register */ +#define LPC17_EEPROM_EEWSTATE_OFFSET 0x0090 /* Wait state register */ +#define LPC17_EEPROM_EECLKDIV_OFFSET 0x0094 /* Clock divider register */ +#define LPC17_EEPROM_EEPWRDWN_OFFSET 0x0098 /* Power down register */ + +#define LPC17_EEPROM_INTSTAT_OFFSET 0x0fe0 /* Interrupt status */ +#define LPC17_EEPROM_INTEN_OFFSET 0x0fe4 /* Interrupt enable */ +#define LPC17_EEPROM_INTSTATCLR_OFFSET 0x0fe8 /* Interrupt status clear */ +#define LPC17_EEPROM_INTENCLR_OFFSET 0x0fd8 /* Interrupt enable clear */ +#define LPC17_EEPROM_INTENSET_OFFSET 0x0fdc /* Interrupt enable set */ +#define LPC17_EEPROM_INTSTATSET_OFFSET 0x0fec /* Interrupt status set */ + +#define LPC17_EEPROM_EECMD (LPC17_EEPROM_BASE+LPC17_EEPROM_EECMD_OFFSET) +#define LPC17_EEPROM_EEADDR (LPC17_EEPROM_BASE+LPC17_EEPROM_EEADDR_OFFSET) +#define LPC17_EEPROM_EEWDATA (LPC17_EEPROM_BASE+LPC17_EEPROM_EEWDATA_OFFSET) +#define LPC17_EEPROM_EERDATA (LPC17_EEPROM_BASE+LPC17_EEPROM_EERDATA_OFFSET) +#define LPC17_EEPROM_EEWSTATE (LPC17_EEPROM_BASE+LPC17_EEPROM_EEWSTATE_OFFSET) +#define LPC17_EEPROM_EECLKDIV (LPC17_EEPROM_BASE+LPC17_EEPROM_EECLKDIV_OFFSET) +#define LPC17_EEPROM_EEPWRDWN (LPC17_EEPROM_BASE+LPC17_EEPROM_EEPWRDWN_OFFSET) + +#define LPC17_EEPROM_INTSTAT (LPC17_EEPROM_BASE+LPC17_EEPROM_INTSTAT_OFFSET) +#define LPC17_EEPROM_INTEN (LPC17_EEPROM_BASE+LPC17_EEPROM_INTEN_OFFSET) +#define LPC17_EEPROM_INTSTATCLR (LPC17_EEPROM_BASE+LPC17_EEPROM_INTSTATCLR_OFFSET) +#define LPC17_EEPROM_INTENCLR (LPC17_EEPROM_BASE+LPC17_EEPROM_INTENCLR_OFFSET) +#define LPC17_EEPROM_INTENSET (LPC17_EEPROM_BASE+LPC17_EEPROM_INTENSET_OFFSET) +#define LPC17_EEPROM_INTSTATSET (LPC17_EEPROM_BASE+LPC17_EEPROM_INTSTATSET_OFFSET) + +/* EECMD - EEPROM Command Register */ + +#define EEPROM_CMD_SHIFT (0) /* Bit 0-2: Command */ +#define EEPROM_CMD_MASK (7 << EEPROM_CMD_SHIFT) +# define EECMD_READ8 (0) /* 000: 8bit read */ +# define EECMD_READ16 (1) /* 001: 16bit read */ +# define EECMD_READ32 (2) /* 010: 32bit read */ +# define EECMD_WRITE8 (3) /* 011: 8bit write */ +# define EECMD_WRITE16 (4) /* 100: 16bit write */ +# define EECMD_WRITE32 (5) /* 101: 32bit write */ +# define EEMCD_ERASE (6) /* 110: erase/program page */ + /* 111: Reserved */ +#define EEPROM_RDPREFETCH (1 << 3) /* Bit 3: Read data prefetch bit */ + /* Bits 4-31: Reserved */ +/* EEADDR - EEPROM Address Register */ + +#define EEPROM_ADDR_SHIFT (0) /* Bits 0-11: Address */ +#define EEPROM_ADDR_MASK (0x7ff << EEPROM_EEADDR_ADDR_SHIFT) + /* Bits 12-31: Reserved */ +/* EEPROM Read/Write Data Registers */ +/* R/W registers has no bitfields, data read/write + * must conforms to the expected sizes + */ + +/* EEWSTATE - EEPROM Wait State Register */ + +#define EEPROM_WSTATE_PHASE3_SHIFT (0) /* Bits 0-7: Wait states 3 (minus 1 encoded) */ +#define EEPROM_WSTATE_PHASE3_MASK (0xff << EEWSTATE_PHASE3_SHIFT) +#define EEPROM_WSTATE_PHASE2_SHIFT (8) /* Bits 8-15: Wait states 2 (minus 1 encoded) */ +#define EEPROM_WSTATE_PHASE2_MASK (0xff << EEWSTATE_PHASE2_SHIFT) +#define EEPROM_WSTATE_PHASE1_SHIFT (16) /* Bits 16-23: Wait states 1 (minus 1 encoded) */ +#define EEPROM_WSTATE_PHASE1_MASK (0xff << EEWSTATE_PHASE1_SHIFT) + /* Bits 24-31: Reserved */ + +/* EECLKDIV - EEPROM Clock Divider Register */ + +#define EEPROM_CLKDIV_SHIFT (0) /* Bits 0-15: Division factor (minus 1 encoded) */ +#define EEPROM_CLKDIV_MASK (0xffff << EECLKDIV_CLKDIV_SHIFT) + /* Bits 16-31: Reserved */ + +/* EEPWRDWN - EEPROM Power Down Register */ + +#define EEPROM_PWRDWN (1) /* Bit 0: Power down mode bit */ + /* Bits 1-31: Reserved */ + +/* EEPROM Interrupt Registers ******************************************/ + +/* INTEN - Interrupt Enable Register */ + + /* Bits 0-25: Reserved */ +#define EEPROM_INTEN_RW_DONE (1 << 26) /* Bit 26: Read/Write finished interrupt bit */ + /* Bit 27: Reserved */ +#define EEPROM_INTEN_PROG_DONE (1 << 28) /* Bit 28: Program finished interrupt bit */ + /* Bits 29-31: Reserved */ + +/* INTENCLR - Interrupt Enable Clear Register */ + /* Bits 0-25: Reserved */ +#define EEPROM_INTENCLR_RWCLR_EN (1 << 26) /* Bit 26: Clear R/W interrupt enable bit */ + /* Bits27: Reserved */ +#define EEPROM_INTENCLR_PROG1CLR_EN (1 << 28) /* Bit 28: Clear program interrupt bit */ + /* Bits 29-31: Reserved */ + +/* INTENSET - Interrupt Enable Set Register */ + /* Bits 0-25: Reserved */ +#define EEPROM_INTENSET_RWSET_EN (1 << 26) /* Bit 26: Set Read/Write finished interrupt bit */ + /* Bit 27: Reserved */ +#define EEPROM_INTENSET_PROG1SET_EN (1 << 28) /* Bit 28: Set program interrupt bit */ + /* Bits 29-31: Reserved */ + +/* INTSTAT - Interrupt Status Register */ + /* Bits 0-25: Reserved */ +#define EEPROM_INTSTAT_RW_END (1 << 26) /* Bit 26: Read/Write done status bit */ + /* Bit 27: Reserved */ +#define EEPROM_INTSTAT_PROG1_END (1 << 28) /* Bit 28: Program done status bit */ + /* Bits 29-31: Reserved */ + +/* INTSTATCLR - Interrupt Status Clear Register */ + /* Bits 0-25: Reserved */ +#define EEPROM_INTSTATCLR_RW_CLR (1 << 26) /* Bit 26: Set Read/Write finished interrupt bit */ + /* Bit 27: Reserved */ +#define EEPROM_INTSTATCLR_PROG_1CLR (1 << 28) /* Bit 28: Set program interrupt bit */ + /* Bits 29-31: Reserved */ + +/* INTSTATSET - Interrupt Status Set Register */ + /* Bits 0-25: Reserved */ +#define EEPROM_INTSTATSET_RW_SET (1 << 26) /* Bit 26: Read/Write done status bit */ + /* Bit 27: Reserved */ +#define EEPROM_INTSTATSET_PROG1_SET (1 << 28) /* Bit 28: Program done status bit */ + /* Bits 29-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EEPROM_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_emc.h b/arch/arm/src/lpc17xx/chip/lpc17_emc.h new file mode 100644 index 0000000000000000000000000000000000000000..2454003a4e046a85449bf5d0281953be29928ca2 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_emc.h @@ -0,0 +1,350 @@ +/**************************************************************************************************** + * arch/arm/src/lpc17xx/chip/lpc17_emc + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EMC_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EMC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets */ + +#define LPC17_EMC_CONTROL_OFFSET 0x0000 /* EMC Control register */ +#define LPC17_EMC_STATUS_OFFSET 0x0004 /* EMC Status register */ +#define LPC17_EMC_CONFIG_OFFSET 0x0008 /* EMC Configuration register */ +#define LPC17_EMC_DYNAMICCONTROL_OFFSET 0x0020 /* Dynamic Memory Control register */ +#define LPC17_EMC_DYNAMICREFRESH_OFFSET 0x0024 /* Dynamic Memory Refresh Timer register */ +#define LPC17_EMC_DYNAMICREADCONFIG_OFFSET 0x0028 /* Dynamic Memory Read Configuration register */ +#define LPC17_EMC_DYNAMICRP_OFFSET 0x0030 /* Dynamic Memory Precharge Command Period register */ +#define LPC17_EMC_DYNAMICRAS_OFFSET 0x0034 /* Dynamic Memory Active to Precharge Command Period register */ +#define LPC17_EMC_DYNAMICSREX_OFFSET 0x0038 /* Dynamic Memory Self-refresh Exit Time register */ +#define LPC17_EMC_DYNAMICAPR_OFFSET 0x003c /* Dynamic Memory Last Data Out to Active Time register */ +#define LPC17_EMC_DYNAMICDAL_OFFSET 0x0040 /* Dynamic Memory Data-in to Active Command Time register */ +#define LPC17_EMC_DYNAMICWR_OFFSET 0x0044 /* Dynamic Memory Write Recovery Time register */ +#define LPC17_EMC_DYNAMICRC_OFFSET 0x0048 /* Dynamic Memory Active to Active Command Period register */ +#define LPC17_EMC_DYNAMICRFC_OFFSET 0x004c /* Dynamic Memory Auto-refresh Period register */ +#define LPC17_EMC_DYNAMICXSR_OFFSET 0x0050 /* Dynamic Memory Exit Self-refresh register */ +#define LPC17_EMC_DYNAMICRRD_OFFSET 0x0054 /* Dynamic Memory Active Bank A to Active Bank B Time register */ +#define LPC17_EMC_DYNAMICMRD_OFFSET 0x0058 /* Dynamic Memory Load Mode register to Active Command Time */ +#define LPC17_EMC_STATICEXTENDEDWAIT_OFFSET 0x0080 /* Static Memory Extended Wait register */ + +#define LPC17_EMC_DYNAMICCONFIG0_OFFSET 0x0100 /* Dynamic Memory Configuration register 0 */ +#define LPC17_EMC_DYNAMICRASCAS0_OFFSET 0x0104 /* Dynamic Memory RAS & CAS Delay register 0 */ + +#define LPC17_EMC_DYNAMICCONFIG1_OFFSET 0x0120 /* Dynamic Memory Configuration register 1 */ +#define LPC17_EMC_DYNAMICRASCAS1_OFFSET 0x0124 /* Dynamic Memory RAS & CAS Delay register 1 */ + +#define LPC17_EMC_DYNAMICCONFIG2_OFFSET 0x0140 /* Dynamic Memory Configuration register 2 */ +#define LPC17_EMC_DYNAMICRASCAS2_OFFSET 0x0144 /* Dynamic Memory RAS & CAS Delay register 2 */ + +#define LPC17_EMC_DYNAMICCONFIG3_OFFSET 0x0160 /* Dynamic Memory Configuration register 3 */ +#define LPC17_EMC_DYNAMICRASCAS3_OFFSET 0x0164 /* Dynamic Memory RAS & CAS Delay register 3 */ + +#define LPC17_EMC_STATICCONFIG0_OFFSET 0x0200 /* Static Memory Configuration register 0 */ +#define LPC17_EMC_STATICWAITWEN0_OFFSET 0x0204 /* Static Memory Write Enable Delay register 0 */ +#define LPC17_EMC_STATICWAITOEN0_OFFSET 0x0208 /* Static Memory Output Enable Delay registers 0 */ +#define LPC17_EMC_STATICWAITRD0_OFFSET 0x020c /* Static Memory Read Delay register 0 */ +#define LPC17_EMC_STATICWAITPAGE0_OFFSET 0x0210 /* Static Memory Page Mode Read Delay register 0*/ +#define LPC17_EMC_STATICWAITWR0_OFFSET 0x0214 /* Static Memory Write Delay register 0 */ +#define LPC17_EMC_STATICWAITTURN0_OFFSET 0x0218 /* Static Memory Turn Round Delay register 0 */ + +#define LPC17_EMC_STATICCONFIG1_OFFSET 0x0220 /* Static Memory Configuration register 1 */ +#define LPC17_EMC_STATICWAITWEN1_OFFSET 0x0224 /* Static Memory Write Enable Delay register 1 */ +#define LPC17_EMC_STATICWAITOEN1_OFFSET 0x0228 /* Static Memory Output Enable Delay register 1 */ +#define LPC17_EMC_STATICWAITRD1_OFFSET 0x022c /* Static Memory Read Delay register 1 */ +#define LPC17_EMC_STATICWAITPAGE1_OFFSET 0x0230 /* Static Memory Page Mode Read Delay register 1 */ +#define LPC17_EMC_STATICWAITWR1_OFFSET 0x0234 /* Static Memory Write Delay register 1 */ +#define LPC17_EMC_STATICWAITTURN1_OFFSET 0x0238 /* Static Memory Turn Round Delay register 1 */ + +#define LPC17_EMC_STATICCONFIG2_OFFSET 0x0240 /* Static Memory Configuration register 2 */ +#define LPC17_EMC_STATICWAITWEN2_OFFSET 0x0244 /* Static Memory Write Enable Delay register 2 */ +#define LPC17_EMC_STATICWAITOEN2_OFFSET 0x0248 /* Static Memory Output Enable Delay register 2 */ +#define LPC17_EMC_STATICWAITRD2_OFFSET 0x024c /* Static Memory Read Delay register 2 */ +#define LPC17_EMC_STATICWAITPAGE2_OFFSET 0x0250 /* Static Memory Page Mode Read Delay registers 3 */ +#define LPC17_EMC_STATICWAITWR2_OFFSET 0x0254 /* Static Memory Write Delay register 2 */ +#define LPC17_EMC_EMCSTATICWAITTURN2_OFFSET 0x0258 /* Static Memory Turn Round Delay register 2 */ + +#define LPC17_EMC_STATICCONFIG3_OFFSET 0x0260 /* Static Memory Configuration register 3 */ +#define LPC17_EMC_STATICWAITWEN3_OFFSET 0x0264 /* Static Memory Write Enable Delay register 3 */ +#define LPC17_EMC_STATICWAITOEN3_OFFSET 0x0268 /* Static Memory Output Enable Delay register 3 */ +#define LPC17_EMC_STATICWAITRD3_OFFSET 0x026c /* Static Memory Read Delay register 3 */ +#define LPC17_EMC_STATICWAITPAGE3_OFFSET 0x0270 /* Static Memory Page Mode Read Delay register 4 */ +#define LPC17_EMC_STATICWAITWR3_OFFSET 0x0274 /* Static Memory Write Delay register 3 */ +#define LPC17_EMC_STATICWAITTURN3_OFFSET 0x0278 /* Static Memory Turn Round Delay register 3 */ + +/* Register Addresses */ + +#define LPC17_EMC_CONTROL (LPC17_EMC_BASE+LPC17_EMC_CONTROL_OFFSET) +#define LPC17_EMC_STATUS (LPC17_EMC_BASE+LPC17_EMC_STATUS_OFFSET) +#define LPC17_EMC_CONFIG (LPC17_EMC_BASE+LPC17_EMC_CONFIG_OFFSET) +#define LPC17_EMC_DYNAMICCONTROL (LPC17_EMC_BASE+LPC17_EMC_DYNAMICCONTROL_OFFSET) +#define LPC17_EMC_DYNAMICREFRESH (LPC17_EMC_BASE+LPC17_EMC_DYNAMICREFRESH_OFFSET) +#define LPC17_EMC_DYNAMICREADCONFIG (LPC17_EMC_BASE+LPC17_EMC_DYNAMICREADCONFIG_OFFSET) +#define LPC17_EMC_DYNAMICRP (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRP_OFFSET) +#define LPC17_EMC_DYNAMICRAS (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRAS_OFFSET) +#define LPC17_EMC_DYNAMICSREX (LPC17_EMC_BASE+LPC17_EMC_DYNAMICSREX_OFFSET) +#define LPC17_EMC_DYNAMICAPR (LPC17_EMC_BASE+LPC17_EMC_DYNAMICAPR_OFFSET) +#define LPC17_EMC_DYNAMICDAL (LPC17_EMC_BASE+LPC17_EMC_DYNAMICDAL_OFFSET) +#define LPC17_EMC_DYNAMICWR (LPC17_EMC_BASE+LPC17_EMC_DYNAMICWR_OFFSET) +#define LPC17_EMC_DYNAMICRC (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRC_OFFSET) +#define LPC17_EMC_DYNAMICRFC (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRFC_OFFSET) +#define LPC17_EMC_DYNAMICXSR (LPC17_EMC_BASE+LPC17_EMC_DYNAMICXSR_OFFSET) +#define LPC17_EMC_DYNAMICRRD (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRRD_OFFSET) +#define LPC17_EMC_DYNAMICMRD (LPC17_EMC_BASE+LPC17_EMC_DYNAMICMRD_OFFSET) +#define LPC17_EMC_STATICEXTENDEDWAIT (LPC17_EMC_BASE+LPC17_EMC_STATICEXTENDEDWAIT_OFFSET) + +#define LPC17_EMC_DYNAMICCONFIG0 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICCONFIG0_OFFSET) +#define LPC17_EMC_DYNAMICRASCAS0 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRASCAS0_OFFSET) + +#define LPC17_EMC_DYNAMICCONFIG1 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICCONFIG1_OFFSET) +#define LPC17_EMC_DYNAMICRASCAS1 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRASCAS1_OFFSET) + +#define LPC17_EMC_DYNAMICCONFIG2 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICCONFIG2_OFFSET) +#define LPC17_EMC_DYNAMICRASCAS2 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRASCAS2_OFFSET) + +#define LPC17_EMC_DYNAMICCONFIG3 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICCONFIG3_OFFSET) +#define LPC17_EMC_DYNAMICRASCAS3 (LPC17_EMC_BASE+LPC17_EMC_DYNAMICRASCAS3_OFFSET) + +#define LPC17_EMC_STATICCONFIG0 (LPC17_EMC_BASE+LPC17_EMC_STATICCONFIG0_OFFSET) +#define LPC17_EMC_STATICWAITWEN0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWEN0_OFFSET) +#define LPC17_EMC_STATICWAITOEN0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITOEN0_OFFSET) +#define LPC17_EMC_STATICWAITRD0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITRD0_OFFSET) +#define LPC17_EMC_STATICWAITPAGE0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITPAGE0_OFFSET) +#define LPC17_EMC_STATICWAITWR0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWR0_OFFSET) +#define LPC17_EMC_STATICWAITTURN0 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITTURN0_OFFSET) + +#define LPC17_EMC_STATICCONFIG1 (LPC17_EMC_BASE+LPC17_EMC_STATICCONFIG1_OFFSET) +#define LPC17_EMC_STATICWAITWEN1 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWEN1_OFFSET) +#define LPC17_EMC_STATICWAITOEN1 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITOEN1_OFFSET) +#define LPC17_EMC_STATICWAITRD (LPC17_EMC_BASE+LPC17_EMC_STATICWAITRD1_OFFSET) +#define LPC17_EMC_STATICWAITPAGE1 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITPAGE1_OFFSET) +#define LPC17_EMC_STATICWAITWR1 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWR1_OFFSET) +#define LPC17_EMC_STATICWAITTURN1 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITTURN1_OFFSET) + +#define LPC17_EMC_STATICCONFIG2 (LPC17_EMC_BASE+LPC17_EMC_STATICCONFIG2_OFFSET) +#define LPC17_EMC_STATICWAITWEN2 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWEN2_OFFSET) +#define LPC17_EMC_STATICWAITOEN2 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITOEN2_OFFSET) +#define LPC17_EMC_STATICWAITRD2 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITRD2_OFFSET) +#define LPC17_EMC_STATICWAITPAGE2 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITPAGE2_OFFSET) +#define LPC17_EMC_STATICWAITWR2 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWR2_OFFSET) +#define LPC17_EMC_EMCSTATICWAITTURN2 (LPC17_EMC_BASE+LPC17_EMC_EMCSTATICWAITTURN2_OFFSET) + +#define LPC17_EMC_STATICCONFIG3 (LPC17_EMC_BASE+LPC17_EMC_STATICCONFIG3_OFFSET) +#define LPC17_EMC_STATICWAITWEN3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWEN3_OFFSET) +#define LPC17_EMC_STATICWAITOEN3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITOEN3_OFFSET) +#define LPC17_EMC_STATICWAITRD3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITRD3_OFFSET) +#define LPC17_EMC_STATICWAITPAGE3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITPAGE3_OFFSET) +#define LPC17_EMC_STATICWAITWR3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITWR3_OFFSET) +#define LPC17_EMC_STATICWAITTURN3 (LPC17_EMC_BASE+LPC17_EMC_STATICWAITTURN3_OFFSET) + +/* Register Bitfield Definitions */ + +/* EMC Control register */ + +#define EMC_CONTROL_E (1 << 0) /* Bit 0: EMC Enable */ +#define EMC_CONTROL_M (1 << 1) /* Bit 1: Address mirror */ +#define EMC_CONTROL_L (1 << 2) /* Bit 2: Low-power mode */ + +/* EMC Status register */ + +#define EMC_STATUS_B (1 << 0) /* Bit 0: Busy */ +#define EMC_STATUS_S (1 << 1) /* Bit 1: Write buffer status */ +#define EMC_STATUS_SA (1 << 2) /* Bit 2: Self-refresh acknowledge */ + +/* EMC Configuration register */ + +#define EMC_CONFIG_EM (1 << 0) /* Bit 0: Endian mode */ +#define EMC_CONFIG_CLKR (1 << 8) /* Bit 8: CCLK:CLKOUT ratio */ + +/* Dynamic Memory Control register */ + +#define EMC_DYNAMICCONTROL_CE (1 << 0) /* Bit 0: Dynamic memory clock enable */ +#define EMC_DYNAMICCONTROL_CS (1 << 1) /* Bit 1: Dynamic memory clock control */ +#define EMC_DYNAMICCONTROL_SR (1 << 2) /* Bit 2: Self-refresh request */ +#define EMC_DYNAMICCONTROL_MMC (1 << 5) /* Bit 5: Memory clock control */ +#define EMC_DYNAMICCONTROL_I_SHIFT (7) /* Bits 7-8: SDRAM initialization */ +#define EMC_DYNAMICCONTROL_I_MASK (3 << EMC_DYNAMICCONTROL_I_SHIFT) +# define EMC_DYNAMICCONTROL_I_NORMAL (0 << EMC_DYNAMICCONTROL_I_SHIFT) /* SDRAM NORMAL operation command */ +# define EMC_DYNAMICCONTROL_I_MODE (1 << EMC_DYNAMICCONTROL_I_SHIFT) /* SDRAM MODE command */ +# define EMC_DYNAMICCONTROL_I_PALL (2 << EMC_DYNAMICCONTROL_I_SHIFT) /* SDRAM PALL (precharge all) command */ +# define EMC_DYNAMICCONTROL_I_NOP (3 << EMC_DYNAMICCONTROL_I_SHIFT) /* SDRAM NOP (no operation) command) */ + +/* Dynamic Memory Refresh Timer register */ + +#define EMC_DYNAMICREFRESH_MASK (0x000007ff) /* Bits 0-10: REFRESH Refresh timer */ + +/* Dynamic Memory Read Configuration register */ + +#define EMC_DYNAMICREADCONFIG_RD_SHIFT (0) /* Bits 0-1: Read data strategy */ +#define EMC_DYNAMICREADCONFIG_RD_MASK (3 << EMC_DYNAMICREADCONFIG_RD_SHIFT) +# define EMC_DYNAMICREADCONFIG_RD_CLKOUT (0 << EMC_DYNAMICREADCONFIG_RD_SHIFT) /* Clock out delayed strategy */ +# define EMC_DYNAMICREADCONFIG_RD_CMD (1 << EMC_DYNAMICREADCONFIG_RD_SHIFT) /* Command delayed strategy */ +# define EMC_DYNAMICREADCONFIG_RD_CMD1 (2 << EMC_DYNAMICREADCONFIG_RD_SHIFT) /* Command delayed strategy + 1 cycle */ +# define EMC_DYNAMICREADCONFIG_RD_CMD2 (3 << EMC_DYNAMICREADCONFIG_RD_SHIFT) /* Command delayed strategy + 2 cycles */ + +/* Dynamic Memory Precharge Command Period register */ + +#define EMC_DYNAMICRP_TRP_MASK (0x0000000f) /* Bits 0-3: Precharge command period */ + +/* Dynamic Memory Active to Precharge Command Period register */ + +#define EMC_DYNAMICRAS_TRAS_MASK (0x0000000f) /* Bits 0-3: Active to precharge command period */ + +/* Dynamic Memory Self-refresh Exit Time register */ + +#define EMC_DYNAMICSREX_TSREX_MASK (0x0000000f) /* Bits 0-3: Self-refresh exit time */ + +/* Dynamic Memory Last Data Out to Active Time register */ + +#define EMC_DYNAMICAPR_TAPR_MASK (0x0000000f) /* Bits 0-3: Last-data-out to active command time */ + +/* Dynamic Memory Data-in to Active Command Time register */ + +#define EMC_DYNAMICDAL_TDAL_MASK (0x0000000f) /* Bits 0-3: Data-in to active command */ + +/* Dynamic Memory Write Recovery Time register */ + +#define EMC_DYNAMICWR_TWR_MASK (0x0000000f) /* Bits 0-3: Write recovery time */ + +/* Dynamic Memory Active to Active Command Period register */ + +#define EMC_DYNAMICRC_TRC_MASK (0x0000001f) /* Bits 0-4: Active to active command period */ + +/* Dynamic Memory Auto-refresh Period register */ + +#define EMC_DYNAMICRFC_TRFC_MASK (0x0000001f) /* Bits 0-4: Auto-refresh period and auto-refresh to active command period */ + +/* Dynamic Memory Exit Self-refresh register */ + +#define EMC_DYNAMICXSR_TXSR_MASK (0x0000001f) /* Bits 0-4: Exit self-refresh to active command time */ + +/* Dynamic Memory Active Bank A to Active Bank B Time register */ + +#define EMC_DYNAMICRRD_TRRD_MASK (0x0000000f) /* Bits 0-3: Active bank A to active bank B latency */ + +/* Dynamic Memory Load Mode register to Active Command Time */ + +#define EMC_DYNAMICMRD_TMRD_MASK (0x0000000f) /* Bits 0-3: Load mode register to active command time */ + +/* Static Memory Extended Wait register */ + +#define EMC_STATICEXTENDEDWAIT_MASK (0x000003ff) /* Bits 0-9: Extended wait time out */ + +/* Dynamic Memory Configuration registers (0-3) */ + +#define EMC_DYNAMICCONFIG_MD_SHIFT (3) /* Bits 3-4: Memory device */ +#define EMC_DYNAMICCONFIG_MD_MASK (3 << EMC_DYNAMICCONFIG_MD_SHIFT) +# define EMC_DYNAMICCONFIG_MD_SDRAM (0 << EMC_DYNAMICCONFIG_MD_SHIFT) /* SDRAM */ +# define EMC_DYNAMICCONFIG_MD_LOWPOWER (1 << EMC_DYNAMICCONFIG_MD_SHIFT) /* Low-power SDRAM */ +#define EMC_DYNAMICCONFIG_AM0_SHIFT (7) /* Bits 7-12: */ +#define EMC_DYNAMICCONFIG_AM0_MASK (63 << EMC_DYNAMICCONFIG_AM0_SHIFT) +# define EMC_DYNAMICCONFIG_AM0(n) ((n) << EMC_DYNAMICCONFIG_AM0_SHIFT) +#define EMC_DYNAMICCONFIG_AM1 (1 << 14) /* Bit 14: */ +#define EMC_DYNAMICCONFIG_B (1 << 19) /* Bit 19: Buffer enable */ +#define EMC_DYNAMICCONFIG_P (1 << 20) /* Bit 20: Write protect */ + +/* Dynamic Memory RAS & CAS Delay registers (0-3) */ + +#define EMC_DYNAMICRASCAS_RAS_SHIFT (0) /* Bits 0-1: RAS latency (active to read/write delay) */ +#define EMC_DYNAMICRASCAS_RAS_MASK (3 << EMC_DYNAMICRASCAS_RAS_SHIFT) +# define EMC_DYNAMICRASCAS_RAS_1CCLK (1 << EMC_DYNAMICRASCAS_RAS_SHIFT) /* One CCLK cycle */ +# define EMC_DYNAMICRASCAS_RAS_2CCLK (2 << EMC_DYNAMICRASCAS_RAS_SHIFT) /* Two CCLK cycles */ +# define EMC_DYNAMICRASCAS_RAS_3CCLK (3 << EMC_DYNAMICRASCAS_RAS_SHIFT) /* Three CCLK cycles */ +#define EMC_DYNAMICRASCAS_CAS_SHIFT (8) /* Bits 8-9: CAS latency */ +#define EMC_DYNAMICRASCAS_CAS_MASK (3 << EMC_DYNAMICRASCAS_CAS_SHIFT) +# define EMC_DYNAMICRASCAS_CAS_1CCLK (1 << EMC_DYNAMICRASCAS_CAS_SHIFT) /* One CCLK cycle */ +# define EMC_DYNAMICRASCAS_CAS_2CCLK (2 << EMC_DYNAMICRASCAS_CAS_SHIFT) /* Two CCLK cycles */ +# define EMC_DYNAMICRASCAS_CAS_3CCLK (3 << EMC_DYNAMICRASCAS_CAS_SHIFT) /* Three CCLK cycles */ + +/* Static Memory Configuration registers (0-3) */ + +#define EMC_STATICCONFIG_MW_SHIFT (0) /* Bits 0-1: Memory width */ +#define EMC_STATICCONFIG_MW_MASK (3 << EMC_STATICCONFIG_MW_SHIFT) +# define EMC_STATICCONFIG_MW_8BIT (0 << EMC_STATICCONFIG_MW_SHIFT) +# define EMC_STATICCONFIG_MW_16BIT (1 << EMC_STATICCONFIG_MW_SHIFT) +# define EMC_STATICCONFIG_MW_32BIT (2 << EMC_STATICCONFIG_MW_SHIFT) +#define EMC_STATICCONFIG_PM (1 << 3) /* Bit 3: Page mode */ +#define EMC_STATICCONFIG_PC (1 << 6) /* Bit 6: Chip select polarity */ +#define EMC_STATICCONFIG_PB (1 << 7) /* Bit 7: Byte lane state */ +#define EMC_STATICCONFIG_EW (1 << 8) /* Bit 8: Extended wait */ +#define EMC_STATICCONFIG_B (1 << 19) /* Bit 19: Buffer enable */ +#define EMC_STATICCONFIG_P (1 << 20) /* Bit 20: Write protect */ + +/* Static Memory Write Enable Delay registers (0-3) */ + +#define EMC_STATICWAITWEN_MASK (0x0000000f) /* Bits 0-3: Wait write enable */ + +/* Static Memory Output Enable Delay registers (0-3) */ + +#define EMC_STATICWAITOEN_MASK (0x0000000f) /* Bits 0-3: Wait output enable */ + +/* Static Memory Read Delay registers (0-3) */ + +#define EMC_STATICWAITRD_MASK (0x0000001f) /* Bits 0-4: Exit self-refresh to active command time */ + +/* Static Memory Page Mode Read Delay registers (0-3) */ + +#define EMC_STATICWAITPAGE_MASK (0x0000001f) /* Bits 0-4: Asynchronous page mode read after the first read wait states */ + +/* Static Memory Write Delay registers (0-3) */ + +#define EMC_STATICWAITWR_MASK (0x0000001f) /* Bits 0-4: Write wait states */ + +/* Static Memory Turn Round Delay registers (0-3) */ + +#define EMC_STATICWAITTURN_MASK (0x0000000f) /* Bits 0-3: Bus turn-around cycles */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_EMC_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_ethernet.h b/arch/arm/src/lpc17xx/chip/lpc17_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..b0791ced96ea42907d57bbd2a9a1cd3a6e399d6b --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_ethernet.h @@ -0,0 +1,597 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_ethernet.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_ETHERNET_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* MAC registers */ + +#define LPC17_ETH_MAC1_OFFSET 0x0000 /* MAC configuration register 1 */ +#define LPC17_ETH_MAC2_OFFSET 0x0004 /* MAC configuration register 2 */ +#define LPC17_ETH_IPGT_OFFSET 0x0008 /* Back-to-Back Inter-Packet-Gap register */ +#define LPC17_ETH_IPGR_OFFSET 0x000c /* Non Back-to-Back Inter-Packet-Gap register */ +#define LPC17_ETH_CLRT_OFFSET 0x0010 /* Collision window / Retry register */ +#define LPC17_ETH_MAXF_OFFSET 0x0014 /* Maximum Frame register */ +#define LPC17_ETH_SUPP_OFFSET 0x0018 /* PHY Support register */ +#define LPC17_ETH_TEST_OFFSET 0x001c /* Test register */ +#define LPC17_ETH_MCFG_OFFSET 0x0020 /* MII Mgmt Configuration register */ +#define LPC17_ETH_MCMD_OFFSET 0x0024 /* MII Mgmt Command register */ +#define LPC17_ETH_MADR_OFFSET 0x0028 /* MII Mgmt Address register */ +#define LPC17_ETH_MWTD_OFFSET 0x002c /* MII Mgmt Write Data register */ +#define LPC17_ETH_MRDD_OFFSET 0x0030 /* MII Mgmt Read Data register */ +#define LPC17_ETH_MIND_OFFSET 0x0034 /* MII Mgmt Indicators register */ +#define LPC17_ETH_SA0_OFFSET 0x0040 /* Station Address 0 register */ +#define LPC17_ETH_SA1_OFFSET 0x0044 /* Station Address 1 register */ +#define LPC17_ETH_SA2_OFFSET 0x0048 /* Station Address 2 register */ + +/* Control registers */ + +#define LPC17_ETH_CMD_OFFSET 0x0100 /* Command register */ +#define LPC17_ETH_STAT_OFFSET 0x0104 /* Status register */ +#define LPC17_ETH_RXDESC_OFFSET 0x0108 /* Receive descriptor base address register */ +#define LPC17_ETH_RXSTAT_OFFSET 0x010c /* Receive status base address register */ +#define LPC17_ETH_RXDESCNO_OFFSET 0x0110 /* Receive number of descriptors register */ +#define LPC17_ETH_RXPRODIDX_OFFSET 0x0114 /* Receive produce index register */ +#define LPC17_ETH_RXCONSIDX_OFFSET 0x0118 /* Receive consume index register */ +#define LPC17_ETH_TXDESC_OFFSET 0x011c /* Transmit descriptor base address register */ +#define LPC17_ETH_TXSTAT_OFFSET 0x0120 /* Transmit status base address register */ +#define LPC17_ETH_TXDESCRNO_OFFSET 0x0124 /* Transmit number of descriptors register */ +#define LPC17_ETH_TXPRODIDX_OFFSET 0x0128 /* Transmit produce index register */ +#define LPC17_ETH_TXCONSIDX_OFFSET 0x012c /* Transmit consume index register */ +#define LPC17_ETH_TSV0_OFFSET 0x0158 /* Transmit status vector 0 register */ +#define LPC17_ETH_TSV1_OFFSET 0x015c /* Transmit status vector 1 register */ +#define LPC17_ETH_RSV_OFFSET 0x0160 /* Receive status vector register */ +#define LPC17_ETH_FCCNTR_OFFSET 0x0170 /* Flow control counter register */ +#define LPC17_ETH_FCSTAT_OFFSET 0x0174 /* Flow control status register */ + +/* Rx filter registers */ + +#define LPC17_ETH_RXFLCTRL_OFFSET 0x0200 /* Receive filter control register */ +#define LPC17_ETH_RXFLWOLST_OFFSET 0x0204 /* Receive filter WoL status register */ +#define LPC17_ETH_RXFLWOLCLR_OFFSET 0x0208 /* Receive filter WoL clear register */ +#define LPC17_ETH_HASHFLL_OFFSET 0x0210 /* Hash filter table LSBs register */ +#define LPC17_ETH_HASHFLH_OFFSET 0x0214 /* Hash filter table MSBs register */ + +/* Module control registers */ + +#define LPC17_ETH_INTST_OFFSET 0x0fe0 /* Interrupt status register */ +#define LPC17_ETH_INTEN_OFFSET 0x0fe4 /* Interrupt enable register */ +#define LPC17_ETH_INTCLR_OFFSET 0x0fe8 /* Interrupt clear register */ +#define LPC17_ETH_INTSET_OFFSET 0x0fec /* Interrupt set register */ +#define LPC17_ETH_PWRDOWN_OFFSET 0x0ff4 /* Power-down register */ + +/* Register addresses ***************************************************************/ +/* MAC registers */ + +#define LPC17_ETH_MAC1 (LPC17_ETH_BASE+LPC17_ETH_MAC1_OFFSET) +#define LPC17_ETH_MAC2 (LPC17_ETH_BASE+LPC17_ETH_MAC2_OFFSET) +#define LPC17_ETH_IPGT (LPC17_ETH_BASE+LPC17_ETH_IPGT_OFFSET) +#define LPC17_ETH_IPGR (LPC17_ETH_BASE+LPC17_ETH_IPGR_OFFSET) +#define LPC17_ETH_CLRT (LPC17_ETH_BASE+LPC17_ETH_CLRT_OFFSET) +#define LPC17_ETH_MAXF (LPC17_ETH_BASE+LPC17_ETH_MAXF_OFFSET) +#define LPC17_ETH_SUPP (LPC17_ETH_BASE+LPC17_ETH_SUPP_OFFSET) +#define LPC17_ETH_TEST (LPC17_ETH_BASE+LPC17_ETH_TEST_OFFSET) +#define LPC17_ETH_MCFG (LPC17_ETH_BASE+LPC17_ETH_MCFG_OFFSET) +#define LPC17_ETH_MCMD (LPC17_ETH_BASE+LPC17_ETH_MCMD_OFFSET) +#define LPC17_ETH_MADR (LPC17_ETH_BASE+LPC17_ETH_MADR_OFFSET) +#define LPC17_ETH_MWTD (LPC17_ETH_BASE+LPC17_ETH_MWTD_OFFSET) +#define LPC17_ETH_MRDD (LPC17_ETH_BASE+LPC17_ETH_MRDD_OFFSET) +#define LPC17_ETH_MIND (LPC17_ETH_BASE+LPC17_ETH_MIND_OFFSET) +#define LPC17_ETH_SA0 (LPC17_ETH_BASE+LPC17_ETH_SA0_OFFSET) +#define LPC17_ETH_SA1 (LPC17_ETH_BASE+LPC17_ETH_SA1_OFFSET) +#define LPC17_ETH_SA2 (LPC17_ETH_BASE+LPC17_ETH_SA2_OFFSET) + +/* Control registers */ + +#define LPC17_ETH_CMD (LPC17_ETH_BASE+LPC17_ETH_CMD_OFFSET) +#define LPC17_ETH_STAT (LPC17_ETH_BASE+LPC17_ETH_STAT_OFFSET) +#define LPC17_ETH_RXDESC (LPC17_ETH_BASE+LPC17_ETH_RXDESC_OFFSET) +#define LPC17_ETH_RXSTAT (LPC17_ETH_BASE+LPC17_ETH_RXSTAT_OFFSET) +#define LPC17_ETH_RXDESCNO (LPC17_ETH_BASE+LPC17_ETH_RXDESCNO_OFFSET) +#define LPC17_ETH_RXPRODIDX (LPC17_ETH_BASE+LPC17_ETH_RXPRODIDX_OFFSET) +#define LPC17_ETH_RXCONSIDX (LPC17_ETH_BASE+LPC17_ETH_RXCONSIDX_OFFSET) +#define LPC17_ETH_TXDESC (LPC17_ETH_BASE+LPC17_ETH_TXDESC_OFFSET) +#define LPC17_ETH_TXSTAT (LPC17_ETH_BASE+LPC17_ETH_TXSTAT_OFFSET) +#define LPC17_ETH_TXDESCRNO (LPC17_ETH_BASE+LPC17_ETH_TXDESCRNO_OFFSET) +#define LPC17_ETH_TXPRODIDX (LPC17_ETH_BASE+LPC17_ETH_TXPRODIDX_OFFSET) +#define LPC17_ETH_TXCONSIDX (LPC17_ETH_BASE+LPC17_ETH_TXCONSIDX_OFFSET) +#define LPC17_ETH_TSV0 (LPC17_ETH_BASE+LPC17_ETH_TSV0_OFFSET) +#define LPC17_ETH_TSV1 (LPC17_ETH_BASE+LPC17_ETH_TSV1_OFFSET) +#define LPC17_ETH_RSV (LPC17_ETH_BASE+LPC17_ETH_RSV_OFFSET) +#define LPC17_ETH_FCCNTR (LPC17_ETH_BASE+LPC17_ETH_FCCNTR_OFFSET) +#define LPC17_ETH_FCSTAT (LPC17_ETH_BASE+LPC17_ETH_FCSTAT_OFFSET) + +/* Rx filter registers */ + +#define LPC17_ETH_RXFLCTRL (LPC17_ETH_BASE+LPC17_ETH_RXFLCTRL_OFFSET) +#define LPC17_ETH_RXFLWOLST (LPC17_ETH_BASE+LPC17_ETH_RXFLWOLST_OFFSET) +#define LPC17_ETH_RXFLWOLCLR (LPC17_ETH_BASE+LPC17_ETH_RXFLWOLCLR_OFFSET) +#define LPC17_ETH_HASHFLL (LPC17_ETH_BASE+LPC17_ETH_HASHFLL_OFFSET) +#define LPC17_ETH_HASHFLH (LPC17_ETH_BASE+LPC17_ETH_HASHFLH_OFFSET) + +/* Module control registers */ + +#define LPC17_ETH_INTST (LPC17_ETH_BASE+LPC17_ETH_INTST_OFFSET) +#define LPC17_ETH_INTEN (LPC17_ETH_BASE+LPC17_ETH_INTEN_OFFSET) +#define LPC17_ETH_INTCLR (LPC17_ETH_BASE+LPC17_ETH_INTCLR_OFFSET) +#define LPC17_ETH_INTSET (LPC17_ETH_BASE+LPC17_ETH_INTSET_OFFSET) +#define LPC17_ETH_PWRDOWN (LPC17_ETH_BASE+LPC17_ETH_PWRDOWN_OFFSET) + +/* Register bit definitions *********************************************************/ +/* MAC registers */ +/* MAC configuration register 1 (MAC1) */ + +#define ETH_MAC1_RE (1 << 0) /* Bit 0: Receive enable */ +#define ETH_MAC1_PARF (1 << 1) /* Bit 1: Passall all receive frames */ +#define ETH_MAC1_RFC (1 << 2) /* Bit 2: RX flow control */ +#define ETH_MAC1_TFC (1 << 3) /* Bit 3: TX flow control */ +#define ETH_MAC1_LPBK (1 << 4) /* Bit 4: Loopback */ + /* Bits 5-7: Reserved */ +#define ETH_MAC1_TXRST (1 << 8) /* Bit 8: Reset TX */ +#define ETH_MAC1_MCSTXRST (1 << 9) /* Bit 9: Reset MCS/TX */ +#define ETH_MAC1_RXRST (1 << 10) /* Bit 10: Reset RX */ +#define ETH_MAC1_MCSRXRST (1 << 11) /* Bit 11: Reset MCS/RX */ + /* Bits 12-13: Reserved */ +#define ETH_MAC1_SIMRST (1 << 14) /* Bit 14: Simulation reset */ +#define ETH_MAC1_SOFTRST (1 << 15) /* Bit 15: Soft reset */ + /* Bits 16-31: Reserved */ +/* MAC configuration register 2 (MAC2) */ + +#define ETH_MAC2_FD (1 << 0) /* Bit 0: Full duplex */ +#define ETH_MAC2_FLC (1 << 1) /* Bit 1: Frame length checking */ +#define ETH_MAC2_HFE (1 << 2) /* Bit 2: Huge frame enable */ +#define ETH_MAC2_DCRC (1 << 3) /* Bit 3: Delayed CRC */ +#define ETH_MAC2_CRCEN (1 << 4) /* Bit 4: CRC enable */ +#define ETH_MAC2_PADCRCEN (1 << 5) /* Bit 5: Pad/CRC enable */ +#define ETH_MAC2_VLANPADEN (1 << 6) /* Bit 6: VLAN pad enable */ +#define ETH_MAC2_AUTOPADEN (1 << 7) /* Bit 7: Auto detect pad enable */ +#define ETH_MAC2_PPE (1 << 8) /* Bit 8: Pure preamble enforcement */ +#define ETH_MAC2_LPE (1 << 9) /* Bit 9: Long preamble enforcement */ + /* Bits 10-11: Reserved */ +#define ETH_MAC2_NBKOFF (1 << 12) /* Bit 12: No backoff */ +#define ETH_MAC2_BPNBKOFF (1 << 13) /* Bit 13: Back pressure/no backoff */ +#define ETH_MAC2_EXDEF (1 << 14) /* Bit 14: Excess defer */ + /* Bits 15-31: Reserved */ +/* Back-to-Back Inter-Packet-Gap register (IPGT) */ + +#define ETH_IPGT_SHIFT (0) /* Bits 0-6 */ +#define ETH_IPGT_MASK (0x7f << ETH_IPGT_SHIFT) + /* Bits 7-31: Reserved */ +/* Non Back-to-Back Inter-Packet-Gap register (IPGR) */ + +#define ETH_IPGR_GAP2_SHIFT (0) /* Bits 0-6: Gap part 2 */ +#define ETH_IPGR_GAP2_MASK (0x7f << ETH_IPGR_GAP2_SHIFT) + /* Bit 7: Reserved */ +#define ETH_IPGR_GAP1_SHIFT (8) /* Bits 8-18: Gap part 1 */ +#define ETH_IPGR_GAP1_MASK (0x7f << ETH_IPGR_GAP2_SHIFT) + /* Bits 15-31: Reserved */ +/* Collision window / Retry register (CLRT) */ + +#define ETH_CLRT_RMAX_SHIFT (0) /* Bits 0-3: Retransmission maximum */ +#define ETH_CLRT_RMAX_MASK (15 << ETH_CLRT_RMAX_SHIFT) + /* Bits 4-7: Reserved */ +#define ETH_CLRT_COLWIN_SHIFT (8) /* Bits 8-13: Collision window */ +#define ETH_CLRT_COLWIN_MASK (0x3f << ETH_CLRT_COLWIN_SHIFT) + /* Bits 14-31: Reserved */ +/* Maximum Frame register (MAXF) */ + +#define ETH_MAXF_SHIFT (0) /* Bits 0-15 */ +#define ETH_MAXF_MASK (0xffff << ETH_MAXF_SHIFT) + /* Bits 16-31: Reserved */ +/* PHY Support register (SUPP) */ + /* Bits 0-7: Reserved */ +#define ETH_SUPP_SPEED (1 << 8) /* Bit 8: 0=10Bps 1=100Bps */ + /* Bits 9-31: Reserved */ +/* Test register (TEST) */ + +#define ETH_TEST_SPQ (1 << 0) /* Bit 0: Shortcut pause quanta */ +#define ETH_TEST_TP (1 << 1) /* Bit 1: Test pause */ +#define ETH_TEST_TBP (1 << 2) /* Bit 2: Test packpressure */ + /* Bits 3-31: Reserved */ +/* MII Mgmt Configuration register (MCFG) */ + +#define ETH_MCFG_SCANINC (1 << 0) /* Bit 0: Scan increment */ +#define ETH_MCFG_SUPPRE (1 << 1) /* Bit 1: Suppress preamble */ +#define ETH_MCFG_CLKSEL_SHIFT (2) /* Bits 2-5: Clock select */ +#define ETH_MCFG_CLKSEL_MASK (15 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV4 (0 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV6 (2 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV8 (3 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV10 (4 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV14 (5 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV20 (6 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV28 (7 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV36 (8 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV40 (9 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV44 (10 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV48 (11 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV52 (12 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV56 (13 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV60 (14 << ETH_MCFG_CLKSEL_SHIFT) +# define ETH_MCFG_CLKSEL_DIV64 (15 << ETH_MCFG_CLKSEL_SHIFT) + /* Bits 6-14: Reserved */ +#define ETH_MCFG_MIIRST (1 << 15) /* Bit 15: Reset MII mgmt */ + /* Bits 16-31: Reserved */ +/* MII Mgmt Command register (MCMD) */ + +#define ETH_MCMD_READ (1 << 0) /* Bit 0: Single read cycle */ +#define ETH_MCMD_SCAN (1 << 1) /* Bit 1: Continuous read cycles */ + /* Bits 2-31: Reserved */ +#define ETH_MCMD_WRITE (0) + +/* MII Mgmt Address register (MADR) */ + +#define ETH_MADR_REGADDR_SHIFT (0) /* Bits 0-4: Register address */ +#define ETH_MADR_REGADDR_MASK (31 << ETH_MADR_REGADDR_SHIFT) + /* Bits 7-5: Reserved */ +#define ETH_MADR_PHYADDR_SHIFT (8) /* Bits 8-12: PHY address */ +#define ETH_MADR_PHYADDR_MASK (31 << ETH_MADR_PHYADDR_SHIFT) + /* Bits 13-31: Reserved */ +/* MII Mgmt Write Data register (MWTD) */ + +#define ETH_MWTD_SHIFT (0) /* Bits 0-15 */ +#define ETH_MWTD_MASK (0xffff << ETH_MWTD_SHIFT) + /* Bits 16-31: Reserved */ +/* MII Mgmt Read Data register (MRDD) */ + +#define ETH_MRDD_SHIFT (0) /* Bits 0-15 */ +#define ETH_MRDD_MASK (0xffff << ETH_MRDD_SHIFT) + /* Bits 16-31: Reserved */ +/* MII Mgmt Indicators register (MIND) */ + +#define ETH_MIND_BUSY (1 << 0) /* Bit 0: Busy */ +#define ETH_MIND_SCANNING (1 << 1) /* Bit 1: Scanning */ +#define ETH_MIND_NVALID (1 << 2) /* Bit 2: Not valid */ +#define ETH_MIND_MIIFAIL (1 << 3) /* Bit 3: MII link fail */ + /* Bits 4-31: Reserved */ +/* Station Address 0 register (SA0) */ + +#define ETH_SA0_OCTET2_SHIFT (0) /* Bits 0-7: Station address 2nd octet */ +#define ETH_SA0_OCTET2_MASK (0xff << ETH_SA0_OCTET2_SHIFT) +#define ETH_SA0_OCTET1_SHIFT (8) /* Bits 8-15: Station address 1st octet */ +#define ETH_SA0_OCTET1_MASK (0xff << ETH_SA0_OCTET1_SHIFT) + /* Bits 16-31: Reserved */ +/* Station Address 1 register (SA1) */ + +#define ETH_SA1_OCTET4_SHIFT (0) /* Bits 0-7: Station address 4th octet */ +#define ETH_SA1_OCTET4_MASK (0xff << ETH_SA0_OCTET4_SHIFT) +#define ETH_SA1_OCTET3_SHIFT (8) /* Bits 8-15: Station address 3rd octet */ +#define ETH_SA1_OCTET3_MASK (0xff << ETH_SA0_OCTET3_SHIFT) + /* Bits 16-31: Reserved */ +/* Station Address 2 register (SA2) */ + +#define ETH_SA2_OCTET6_SHIFT (0) /* Bits 0-7: Station address 5th octet */ +#define ETH_SA2_OCTET6_MASK (0xff << ETH_SA0_OCTET6_SHIFT) +#define ETH_SA2_OCTET5_SHIFT (8) /* Bits 8-15: Station address 6th octet */ +#define ETH_SA2_OCTET5_MASK (0xff << ETH_SA0_OCTET5_SHIFT) + /* Bits 16-31: Reserved */ +/* Control registers */ +/* Command register (CMD) */ + +#define ETH_CMD_RXEN (1 << 0) /* Bit 0: Receive enable */ +#define ETH_CMD_TXEN (1 << 1) /* Bit 1: Transmit enable */ + /* Bit 2: Reserved */ +#define ETH_CMD_REGRST (1 << 3) /* Bit 3: Reset host registers */ +#define ETH_CMD_TXRST (1 << 4) /* Bit 4: Reset transmit datapath */ +#define ETH_CMD_RXRST (1 << 5) /* Bit 5: Reset receive datapath */ +#define ETH_CMD_PRFRAME (1 << 6) /* Bit 6: Pass run frame */ +#define ETH_CMD_PRFILTER (1 << 7) /* Bit 7: Pass RX filter */ +#define ETH_CMD_TXFC (1 << 8) /* Bit 8: TX flow control */ +#define ETH_CMD_RMII (1 << 9) /* Bit 9: RMII mode */ +#define ETH_CMD_FD (1 << 10) /* Bit 10: Full duplex */ + /* Bits 11-31: Reserved */ +/* Status register */ + +#define ETH_STAT_RX (1 << 0) /* Bit 0: RX status */ +#define ETH_STAT_TX (1 << 1) /* Bit 1: TX status */ + /* Bits 2-31: Reserved */ +/* Receive descriptor base address register (RXDESC) + * + * The receive descriptor base address is a byte address aligned to a word + * boundary i.e. LSB 1:0 are fixed to 00. The register contains the lowest + * address in the array of descriptors. + */ + +/* Receive status base address register (RXSTAT) + * + * The receive status base address is a byte address aligned to a double word + * boundary i.e. LSB 2:0 are fixed to 000. + */ + +/* Receive number of descriptors register (RXDESCNO) */ + +#define ETH_RXDESCNO_SHIFT (0) /* Bits 0-15 */ +#define ETH_RXDESCNO_MASK (0xffff << ETH_RXDESCNO_SHIFT) + /* Bits 16-31: Reserved */ +/* Receive produce index register (RXPRODIDX) */ + +#define ETH_RXPRODIDX_SHIFT (0) /* Bits 0-15 */ +#define ETH_RXPRODIDX_MASK (0xffff << ETH_RXPRODIDX_SHIFT) + /* Bits 16-31: Reserved */ +/* Receive consume index register (RXCONSIDX) */ + +#define ETH_RXCONSIDX_SHIFT (0) /* Bits 0-15 */ +#define ETH_RXCONSIDX_MASK (0xffff << ETH_RXPRODIDX_SHIFT) + /* Bits 16-31: Reserved */ +/* Transmit descriptor base address register (TXDESC) + * + * The transmit descriptor base address is a byte address aligned to a word + * boundary i.e. LSB 1:0 are fixed to 00. The register contains the lowest + * address in the array of descriptors. + */ + +/* Transmit status base address register (TXSTAT) + * + * The transmit status base address is a byte address aligned to a word + * boundary i.e. LSB1:0 are fixed to 00. The register contains the lowest + * address in the array of statuses. + */ + +/* Transmit number of descriptors register (TXDESCRNO) */ + +#define ETH_TXDESCRNO_SHIFT (0) /* Bits 0-15 */ +#define ETH_TXDESCRNO_MASK (0xffff << ETH_TXDESCRNO_SHIFT) + /* Bits 16-31: Reserved */ +/* Transmit produce index register (TXPRODIDX) */ + +#define ETH_TXPRODIDX_SHIFT (0) /* Bits 0-15 */ +#define ETH_TXPRODIDX_MASK (0xffff << ETH_TXPRODIDX_SHIFT) + /* Bits 16-31: Reserved */ +/* Transmit consume index register (TXCONSIDX) */ + +#define ETH_TXCONSIDX_SHIFT (0) /* Bits 0-15 */ +#define ETH_TXCONSIDX_MASK (0xffff << ETH_TXPRODIDX_SHIFT) + /* Bits 16-31: Reserved */ +/* Transmit status vector 0 register (TSV0) */ + +#define ETH_TSV0_CRCERR (1 << 0) /* Bit 0: CRC error */ +#define ETH_TSV0_LENCHKERR (1 << 1) /* Bit 1: Length check error */ +#define ETH_TSV0_LENOOR (1 << 2) /* Bit 2: Length out of range */ +#define ETH_TSV0_DONE (1 << 3) /* Bit 3: Done */ +#define ETH_TSV0_MCAST (1 << 4) /* Bit 4: Multicast */ +#define ETH_TSV0_BCAST (1 << 5) /* Bit 5: Broadcast */ +#define ETH_TSV0_PKTDEFER (1 << 6) /* Bit 6: Packet Defer */ +#define ETH_TSV0_EXCDEFER (1 << 7) /* Bit 7: Excessive Defer */ +#define ETH_TSV0_EXCCOL (1 << 8) /* Bit 8: Excessive Collision */ +#define ETH_TSV0_LATECOL (1 << 9) /* Bit 9: Late Collision */ +#define ETH_TSV0_GIANT (1 << 10) /* Bit 10: Giant */ +#define ETH_TSV0_UNDRUN (1 << 11) /* Bit 11: Underrun */ +#define ETH_TSV0_TOTBYTES_SHIFT (12) /* Bits 12-27:Total bytes */ +#define ETH_TSV0_TOTBYTES_MASK (0xffff << ETH_TSV0_TOTBYTES_SHIFT) +#define ETH_TSV0_CTLFRAME (1 << 28) /* Bit 28: Control frame */ +#define ETH_TSV0_PAUSE (1 << 29) /* Bit 29: Pause */ +#define ETH_TSV0_BP (1 << 30) /* Bit 30: Backpressure */ +#define ETH_TSV0_VLAN (1 << 31) /* Bit 31: VLAN */ + +/* Transmit status vector 1 register (TSV1) */ + +#define ETH_TSV1_TXCNT_SHIFT (0) /* Bits 0-15: Transmit byte count */ +#define ETH_TSV1_TXCNT_MASK (0xffff << ETH_TSV1_TXCNT_SHIFT) +#define ETH_TSV1_COLCNT_SHIFT (16) /* Bits 16-19: Transmit collision count */ +#define ETH_TSV1_COLCNT_MASK (15 << ETH_TSV1_COLCNT_SHIFT) + /* Bits 20-31: Reserved */ +/* Receive status vector register (RSV) */ + +#define ETH_RSV_RXCNT_SHIFT (0) /* Bits 0-15: Received byte count */ +#define ETH_RSV_RXCNT_MASK (0xffff << ETH_RSV_RXCNT_SHIFT) +#define ETH_RSV_PKTPI (1 << 16) /* Bit 16: Packet previously ignored */ +#define ETH_RSV_RXEPS (1 << 17) /* Bit 17: RXDV event previously seen */ +#define ETH_RSV_CEPS (1 << 18) /* Bit 18: Carrier event previously seen */ +#define ETH_RSV_RXCV (1 << 19) /* Bit 19: Receive code violation */ +#define ETH_RSV_CRCERR (1 << 20) /* Bit 20: CRC error */ +#define ETH_RSV_LENCHKERR (1 << 21) /* Bit 21: Length check error */ +#define ETH_RSV_LENOOR (1 << 22) /* Bit 22: Length out of range */ +#define ETH_RSV_RXOK (1 << 23) /* Bit 23: Receive OK */ +#define ETH_RSV_MCAST (1 << 24) /* Bit 24: Multicast */ +#define ETH_RSV_BCAST (1 << 25) /* Bit 25: Broadcast */ +#define ETH_RSV_DRIBNIB (1 << 26) /* Bit 26: Dribble Nibble */ +#define ETH_RSV_CTLFRAME (1 << 27) /* Bit 27: Control frame */ +#define ETH_RSV_PAUSE (1 << 28) /* Bit 28: Pause */ +#define ETH_RSV_UNSUPOP (1 << 29) /* Bit 29: Unsupported Opcode */ +#define ETH_RSV_VLAN (1 << 30) /* Bit 30: VLAN */ + /* Bit 31: Reserved */ +/* Flow control counter register (FCCNTR) */ + +#define ETH_FCCNTR_MCOUNT_SHIFT (0) /* Bits 0-15: Mirror count */ +#define ETH_FCCNTR_MCOUNT_MASK (0xffff << ETH_FCCNTR_MCOUNT_SHIFT) +#define ETH_FCCNTR_PTMR_SHIFT (16) /* Bits 16-31: Pause timer */ +#define ETH_FCCNTR_PTMR_MASK (0xffff << ETH_FCCNTR_PTMR_SHIFT) + +/* Flow control status register (FCSTAT) */ + +#define ETH_FCSTAT_MCOUNT_SHIFT (0) /* Bits 0-15: Current mirror count */ +#define ETH_FCSTAT_MCOUNT_MASK (0xffff << ETH_FCSTAT_MCOUNT_SHIFT) + /* Bits 16-31: Reserved */ +/* Rx filter registers */ +/* Receive filter control register (RXFLCTRL) */ + +#define ETH_RXFLCTRL_UCASTEN (1 << 0) /* Bit 0: Accept all unicast frames */ +#define ETH_RXFLCTRL_BCASTEN (1 << 1) /* Bit 1: Accept all broadcast frames */ +#define ETH_RXFLCTRL_MCASTEN (1 << 2) /* Bit 2: Accept all multicast frames */ +#define ETH_RXFLCTRL_UCASTHASHEN (1 << 3) /* Bit 3: Accept hashed unicast */ +#define ETH_RXFLCTRL_MCASTHASHEN (1 << 4) /* Bit 4: Accect hashed multicast */ +#define ETH_RXFLCTRL_PERFEN (1 << 5) /* Bit 5: Accept perfect dest match */ + /* Bits 6-11: Reserved */ +#define ETH_RXFLCTRL_MPKTEN (1 << 12) /* Bit 12: Magic pkt filter WoL int */ +#define ETH_RXFLCTRL_RXFILEN (1 << 13) /* Bit 13: Perfect match WoL interrupt */ + /* Bits 14-31: Reserved */ +/* Receive filter WoL status register (RXFLWOLST) AND + * Receive filter WoL clear register (RXFLWOLCLR) + */ + +#define ETH_RXFLWOL_UCAST (1 << 0) /* Bit 0: Unicast frame WoL */ +#define ETH_RXFLWOL_BCAST (1 << 1) /* Bit 1: Broadcast frame WoL */ +#define ETH_RXFLWOL_MCAST (1 << 2) /* Bit 2: Multicast frame WoL */ +#define ETH_RXFLWOL_UCASTHASH (1 << 3) /* Bit 3: Unicast hash filter WoL */ +#define ETH_RXFLWOL_MCASTHASH (1 << 4) /* Bit 4: Multiicast hash filter WoL */ +#define ETH_RXFLWOL_PERF (1 << 5) /* Bit 5: Perfect addr match WoL */ + /* Bit 6: Reserved */ +#define ETH_RXFLWOL_RXFIL (1 << 7) /* Bit 7: Receive filter WoL */ +#define ETH_RXFLWOL_MPKT (1 << 8) /* Bit 8: Magic pkt filter WoL */ + /* Bits 9-31: Reserved */ +/* Hash filter table LSBs register (HASHFLL) AND Hash filter table MSBs register +* (HASHFLH) Are registers containing a 32-bit value with no bitfield. + */ + +/* Module control registers */ +/* Interrupt status register (INTST), Interrupt enable register (INTEN), Interrupt + * clear register (INTCLR), and Interrupt set register (INTSET) common bit field + * definition: + */ + +#define ETH_INT_RXOVR (1 << 0) /* Bit 0: RX overrun interrupt */ +#define ETH_INT_RXERR (1 << 1) /* Bit 1: RX error interrupt */ +#define ETH_INT_RXFIN (1 << 2) /* Bit 2: RX finished interrupt */ +#define ETH_INT_RXDONE (1 << 3) /* Bit 3: RX done interrupt */ +#define ETH_INT_TXUNR (1 << 4) /* Bit 4: TX underrun interrupt */ +#define ETH_INT_TXERR (1 << 5) /* Bit 5: TX error interrupt */ +#define ETH_INT_TXFIN (1 << 6) /* Bit 6: TX finished interrupt */ +#define ETH_INT_TXDONE (1 << 7) /* Bit 7: TX done interrupt */ + /* Bits 8-11: Reserved */ +#define ETH_INT_SOFT (1 << 12) /* Bit 12: Soft interrupt */ +#define ETH_INT_WKUP (1 << 13) /* Bit 13: Wakeup interrupt */ + /* Bits 14-31: Reserved */ +/* Power-down register */ + /* Bits 0-30: Reserved */ +#define ETH_PWRDOWN_MACAHB (1 << 31) /* Power down MAC/AHB */ + +/* Descriptors Offsets **************************************************************/ + +/* Tx descriptor offsets */ + +#define LPC17_TXDESC_PACKET 0x00 /* Base address of the Tx data buffer */ +#define LPC17_TXDESC_CONTROL 0x04 /* Control Information */ +#define LPC17_TXDESC_SIZE 0x08 /* Size in bytes of one Tx descriptor */ + +/* Tx status offsets */ + +#define LPC17_TXSTAT_INFO 0x00 /* Transmit status return flags */ +#define LPC17_TXSTAT_SIZE 0x04 /* Size in bytes of one Tx status */ + +/* Rx descriptor offsets */ + +#define LPC17_RXDESC_PACKET 0x00 /* Base address of the Rx data buffer */ +#define LPC17_RXDESC_CONTROL 0x04 /* Control Information */ +#define LPC17_RXDESC_SIZE 0x08 /* Size in bytes of one Rx descriptor */ + +/* Rx status offsets */ + +#define LPC17_RXSTAT_INFO 0x00 /* Receive status return flags */ +#define LPC17_RXSTAT_HASHCRC 0x04 /* Dest and source hash CRC */ +#define LPC17_RXSTAT_SIZE 0x08 /* Size in bytes of one Rx status */ + +/* Descriptor Bit Definitions *******************************************************/ + +/* Tx descriptor bit definitions */ + +#define TXDESC_CONTROL_SIZE_SHIFT (0) /* Bits 0-10: Size of data buffer */ +#define TXDESC_CONTROL_SIZE_MASK (0x7ff << RXDESC_CONTROL_SIZE_SHIFT) + +#define TXDESC_CONTROL_OVERRIDE (1 << 26 /* Bit 26: Per-frame override */ +#define TXDESC_CONTROL_HUGE (1 << 27) /* Bit 27: Enable huge frame size */ +#define TXDESC_CONTROL_PAD (1 << 28) /* Bit 28: Pad short frames */ +#define TXDESC_CONTROL_CRC (1 << 29) /* Bit 29: Append CRC */ +#define TXDESC_CONTROL_LAST (1 << 30) /* Bit 30: Last descriptor of a fragment */ +#define TXDESC_CONTROL_INT (1 << 31) /* Bit 31: Generate TxDone interrupt */ + +/* Tx status bit definitions */ + +#define TXSTAT_INFO_COLCNT_SHIFT (21) /* Bits 21-24: Number of collisions */ +#define TXSTAT_INFO_COLCNT_MASK (15 << TXSTAT_INFO_COLCNT_SHIFT) +#define TXSTAT_INFO_DEFER (1 << 25) /* Bit 25: Packet deffered */ +#define TXSTAT_INFO_EXCESSDEFER (1 << 26) /* Bit 26: Excessive packet defferals */ +#define TXSTAT_INFO_EXCESSCOL (1 << 27) /* Bit 27: Excessive packet collisions */ +#define TXSTAT_INFO_LATECOL (1 << 28) /* Bit 28: Out of window collision */ +#define TXSTAT_INFO_UNDERRUN (1 << 29) /* Bit 29: Tx underrun */ +#define TXSTAT_INFO_NODESC (1 << 30) /* Bit 29: No Tx descriptor available */ +#define TXSTAT_INFO_ERROR (1 << 31) /* Bit 31: OR of other error conditions */ + +/* Rx descriptor bit definitions */ + +#define RXDESC_CONTROL_SIZE_SHIFT (0) /* Bits 0-10: Size of data buffer */ +#define RXDESC_CONTROL_SIZE_MASK (0x7ff << RXDESC_CONTROL_SIZE_SHIFT) +#define RXDESC_CONTROL_INT (1 << 31) /* Bit 31: Generate RxDone interrupt */ + +/* Rx status bit definitions */ + +#define RXSTAT_SAHASHCRC_SHIFT (0) /* Bits 0-8: Hash CRC calculated from the source address */ +#define RXSTAT_SAHASHCRC_MASK (0x1ff << RXSTAT_SAHASHCRC_SHIFT) +#define RXSTAT_DAHASHCRC_SHIFT (16) /* Bits 16-24: Hash CRC calculated from the dest address */ +#define RXSTAT_DAHASHCRC_MASK (0x1ff << RXSTAT_DAHASHCRC_SHIFT) + +#define RXSTAT_INFO_RXSIZE_SHIFT (0) /* Bits 0-10: Size of actual data transferred */ +#define RXSTAT_INFO_RXSIZE_MASK (0x7ff << RXSTAT_INFO_RXSIZE_SHIFT) +#define RXSTAT_INFO_CONTROL (1 << 18) /* Bit 18: This is a control frame */ +#define RXSTAT_INFO_VLAN (1 << 19) /* Bit 19: This is a VLAN frame */ +#define RXSTAT_INFO_FAILFILTER (1 << 20) /* Bit 20: Frame failed Rx filter */ +#define RXSTAT_INFO_MULTICAST (1 << 21) /* Bit 21: This is a multicast frame */ +#define RXSTAT_INFO_BROADCAST (1 << 22) /* Bit 22: This is a broadcast frame */ +#define RXSTAT_INFO_CRCERROR (1 << 23) /* Bit 23: Received frame had a CRC error */ +#define RXSTAT_INFO_SYMBOLERROR (1 << 24) /* Bit 24: PHY reported bit error */ +#define RXSTAT_INFO_LENGTHERROR (1 << 25) /* Bit 25: Invalid frame length */ +#define RXSTAT_INFO_RANGEERROR (1 << 26) /* Bit 26: Exceeds maximum packet size */ +#define RXSTAT_INFO_ALIGNERROR (1 << 27) /* Bit 27: Alignment error */ +#define RXSTAT_INFO_OVERRUN (1 << 28) /* Bit 28: Receive overrun error */ +#define RXSTAT_INFO_NODESC (1 << 29) /* Bit 29: No Rx descriptor available */ +#define RXSTAT_INFO_LASTFLAG (1 << 30) /* Bit 30: Last fragment of a frame */ +#define RXSTAT_INFO_ERROR (1 << 31) /* Bit 31: OR of other error conditions */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_ETHERNET_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_gpdma.h b/arch/arm/src/lpc17xx/chip/lpc17_gpdma.h new file mode 100644 index 0000000000000000000000000000000000000000..a915559b9689bbe014f1e56a08d50b974ba7d4df --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_gpdma.h @@ -0,0 +1,597 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_gpdma.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_GPDMA_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_GPDMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register offsets *****************************************************************/ + +/* General registers (see also LPC17_SYSCON_DMAREQSEL_OFFSET in lpc17_syscon.h) */ + +#define LPC17_DMA_INTST_OFFSET 0x0000 /* DMA Interrupt Status Register */ +#define LPC17_DMA_INTTCST_OFFSET 0x0004 /* DMA Interrupt Terminal Count Request Status Register */ +#define LPC17_DMA_INTTCCLR_OFFSET 0x0008 /* DMA Interrupt Terminal Count Request Clear Register */ +#define LPC17_DMA_INTERRST_OFFSET 0x000c /* DMA Interrupt Error Status Register */ +#define LPC17_DMA_INTERRCLR_OFFSET 0x0010 /* DMA Interrupt Error Clear Register */ +#define LPC17_DMA_RAWINTTCST_OFFSET 0x0014 /* DMA Raw Interrupt Terminal Count Status Register */ +#define LPC17_DMA_RAWINTERRST_OFFSET 0x0018 /* DMA Raw Error Interrupt Status Register */ +#define LPC17_DMA_ENBLDCHNS_OFFSET 0x001c /* DMA Enabled Channel Register */ +#define LPC17_DMA_SOFTBREQ_OFFSET 0x0020 /* DMA Software Burst Request Register */ +#define LPC17_DMA_SOFTSREQ_OFFSET 0x0024 /* DMA Software Single Request Register */ +#define LPC17_DMA_SOFTLBREQ_OFFSET 0x0028 /* DMA Software Last Burst Request Register */ +#define LPC17_DMA_SOFTLSREQ_OFFSET 0x002c /* DMA Software Last Single Request Register */ +#define LPC17_DMA_CONFIG_OFFSET 0x0030 /* DMA Configuration Register */ +#define LPC17_DMA_SYNC_OFFSET 0x0034 /* DMA Synchronization Register */ + +/* Channel Registers */ + +#define LPC17_NDMACH 8 /* Eight DMA channels */ +#define LPC17_DMA_CHAN_OFFSET(n) (0x0100 + ((n) << 5)) /* n=0,1,...,(LPC17_NDMACH-1) */ + +#define LPC17_DMACH_SRCADDR_OFFSET 0x0000 /* DMA Channel Source Address Register */ +#define LPC17_DMACH_DESTADDR_OFFSET 0x0004 /* DMA Channel Destination Address Register */ +#define LPC17_DMACH_LLI_OFFSET 0x0008 /* DMA Channel Linked List Item Register */ +#define LPC17_DMACH_CONTROL_OFFSET 0x000c /* DMA Channel Control Register */ +#define LPC17_DMACH_CONFIG_OFFSET 0x0010 /* DMA Channel Configuration Register */ + +#define LPC17_DMACH0_SRCADDR_OFFSET (0x100+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH0_DESTADDR_OFFSET (0x100+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH0_LLI_OFFSET (0x100+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH0_CONTROL_OFFSET (0x100+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH0_CONFIG_OFFSET (0x100+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH1_SRCADDR_OFFSET (0x120+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH1_DESTADDR_OFFSET (0x120+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH1_LLI_OFFSET (0x120+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH1_CONTROL_OFFSET (0x120+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH1_CONFIG_OFFSET (0x120+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH2_SRCADDR_OFFSET (0x140+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH2_DESTADDR_OFFSET (0x140+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH2_LLI_OFFSET (0x140+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH2_CONTROL_OFFSET (0x140+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH2_CONFIG_OFFSET (0x140+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH3_SRCADDR_OFFSET (0x160+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH3_DESTADDR_OFFSET (0x160+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH3_LLI_OFFSET (0x160+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH3_CONTROL_OFFSET (0x160+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH3_CONFIG_OFFSET (0x160+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH4_SRCADDR_OFFSET (0x180+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH4_DESTADDR_OFFSET (0x180+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH4_LLI_OFFSET (0x180+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH4_CONTROL_OFFSET (0x180+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH4_CONFIG_OFFSET (0x180+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH5_SRCADDR_OFFSET (0x1a0+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH5_DESTADDR_OFFSET (0x1a0+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH5_LLI_OFFSET (0x1a0+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH5_CONTROL_OFFSET (0x1a0+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH5_CONFIG_OFFSET (0x1a0+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH6_SRCADDR_OFFSET (0x1c0+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH6_DESTADDR_OFFSET (0x1c0+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH6_LLI_OFFSET (0x1c0+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH6_CONTROL_OFFSET (0x1c0+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH6_CONFIG_OFFSET (0x1c0+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH7_SRCADDR_OFFSET (0x1e0+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH7_DESTADDR_OFFSET (0x1e0+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH7_LLI_OFFSET (0x1e0+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH7_CONTROL_OFFSET (0x1e0+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH7_CONFIG_OFFSET (0x1e0+LPC17_DMACH_CONFIG_OFFSET) + +/* Register addresses ***************************************************************/ +/* General registers (see also LPC17_SYSCON_DMAREQSEL in lpc17_syscon.h) */ + +#define LPC17_DMA_INTST (LPC17_GPDMA_BASE+LPC17_DMA_INTST_OFFSET) +#define LPC17_DMA_INTTCST (LPC17_GPDMA_BASE+LPC17_DMA_INTTCST_OFFSET) +#define LPC17_DMA_INTTCCLR (LPC17_GPDMA_BASE+LPC17_DMA_INTTCCLR_OFFSET) +#define LPC17_DMA_INTERRST (LPC17_GPDMA_BASE+LPC17_DMA_INTERRST_OFFSET) +#define LPC17_DMA_INTERRCLR (LPC17_GPDMA_BASE+LPC17_DMA_INTERRCLR_OFFSET) +#define LPC17_DMA_RAWINTTCST (LPC17_GPDMA_BASE+LPC17_DMA_RAWINTTCST_OFFSET) +#define LPC17_DMA_RAWINTERRST (LPC17_GPDMA_BASE+LPC17_DMA_RAWINTERRST_OFFSET) +#define LPC17_DMA_ENBLDCHNS (LPC17_GPDMA_BASE+LPC17_DMA_ENBLDCHNS_OFFSET) +#define LPC17_DMA_SOFTBREQ (LPC17_GPDMA_BASE+LPC17_DMA_SOFTBREQ_OFFSET) +#define LPC17_DMA_SOFTSREQ (LPC17_GPDMA_BASE+LPC17_DMA_SOFTSREQ_OFFSET) +#define LPC17_DMA_SOFTLBREQ (LPC17_GPDMA_BASE+LPC17_DMA_SOFTLBREQ_OFFSET) +#define LPC17_DMA_SOFTLSREQ (LPC17_GPDMA_BASE+LPC17_DMA_SOFTLSREQ_OFFSET) +#define LPC17_DMA_CONFIG (LPC17_GPDMA_BASE+LPC17_DMA_CONFIG_OFFSET) +#define LPC17_DMA_SYNC (LPC17_GPDMA_BASE+LPC17_DMA_SYNC_OFFSET) + +/* Channel Registers */ + +#define LPC17_DMACH_BASE(n) (LPC17_GPDMA_BASE+LPC17_DMA_CHAN_OFFSET(n)) + +#define LPC17_DMACH_SRCADDR(n) (LPC17_DMACH_BASE(n)+LPC17_DMACH_SRCADDR_OFFSET) +#define LPC17_DMACH_DESTADDR(n) (LPC17_DMACH_BASE(n)+LPC17_DMACH_DESTADDR_OFFSET) +#define LPC17_DMACH_LLI(n) (LPC17_DMACH_BASE(n)+LPC17_DMACH_LLI_OFFSET) +#define LPC17_DMACH_CONTROL(n) (LPC17_DMACH_BASE(n)+LPC17_DMACH_CONTROL_OFFSET) +#define LPC17_DMACH_CONFIG(n) (LPC17_DMACH_BASE(n)+LPC17_DMACH_CONFIG_OFFSET) + +#define LPC17_DMACH0_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH0_SRCADDR_OFFSET) +#define LPC17_DMACH0_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH0_DESTADDR_OFFSET) +#define LPC17_DMACH0_LLI (LPC17_GPDMA_BASE+LPC17_DMACH0_LLI_OFFSET) +#define LPC17_DMACH0_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH0_CONTROL_OFFSET) +#define LPC17_DMACH0_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH0_CONFIG_OFFSET) + +#define LPC17_DMACH1_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH1_SRCADDR_OFFSET) +#define LPC17_DMACH1_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH1_DESTADDR_OFFSET) +#define LPC17_DMACH1_LLI (LPC17_GPDMA_BASE+LPC17_DMACH1_LLI_OFFSET) +#define LPC17_DMACH1_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH1_CONTROL_OFFSET) +#define LPC17_DMACH1_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH1_CONFIG_OFFSET) + +#define LPC17_DMACH2_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH2_SRCADDR_OFFSET) +#define LPC17_DMACH2_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH2_DESTADDR_OFFSET) +#define LPC17_DMACH2_LLI (LPC17_GPDMA_BASE+LPC17_DMACH2_LLI_OFFSET) +#define LPC17_DMACH2_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH2_CONTROL_OFFSET) +#define LPC17_DMACH2_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH2_CONFIG_OFFSET) + +#define LPC17_DMACH3_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH3_SRCADDR_OFFSET) +#define LPC17_DMACH3_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH3_DESTADDR_OFFSET) +#define LPC17_DMACH3_LLI (LPC17_GPDMA_BASE+LPC17_DMACH3_LLI_OFFSET) +#define LPC17_DMACH3_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH3_CONTROL_OFFSET) +#define LPC17_DMACH3_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH3_CONFIG_OFFSET) + +#define LPC17_DMACH4_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH4_SRCADDR_OFFSET) +#define LPC17_DMACH4_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH4_DESTADDR_OFFSET) +#define LPC17_DMACH4_LLI (LPC17_GPDMA_BASE+LPC17_DMACH4_LLI_OFFSET) +#define LPC17_DMACH4_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH4_CONTROL_OFFSET) +#define LPC17_DMACH4_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH4_CONFIG_OFFSET) + +#define LPC17_DMACH5_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH5_SRCADDR_OFFSET) +#define LPC17_DMACH5_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH5_DESTADDR_OFFSET) +#define LPC17_DMACH5_LLI (LPC17_GPDMA_BASE+LPC17_DMACH5_LLI_OFFSET) +#define LPC17_DMACH5_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH5_CONTROL_OFFSET) +#define LPC17_DMACH5_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH5_CONFIG_OFFSET) + +#define LPC17_DMACH6_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH6_SRCADDR_OFFSET) +#define LPC17_DMACH6_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH6_DESTADDR_OFFSET) +#define LPC17_DMACH6_LLI (LPC17_GPDMA_BASE+LPC17_DMACH6_LLI_OFFSET) +#define LPC17_DMACH6_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH6_CONTROL_OFFSET) +#define LPC17_DMACH6_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH6_CONFIG_OFFSET) + +#define LPC17_DMACH7_SRCADDR (LPC17_GPDMA_BASE+LPC17_DMACH7_SRCADDR_OFFSET) +#define LPC17_DMACH7_DESTADDR (LPC17_GPDMA_BASE+LPC17_DMACH7_DESTADDR_OFFSET) +#define LPC17_DMACH7_LLI (LPC17_GPDMA_BASE+LPC17_DMACH7_LLI_OFFSET) +#define LPC17_DMACH7_CONTROL (LPC17_GPDMA_BASE+LPC17_DMACH7_CONTROL_OFFSET) +#define LPC17_DMACH7_CONFIG (LPC17_GPDMA_BASE+LPC17_DMACH7_CONFIG_OFFSET) + +/* Register bit definitions *********************************************************/ +/* DMA Request Connections **********************************************************/ + +#define LPC17_NDMAREQ (16) /* The number of DMA requests */ +#if defined(LPC176x) +/* Request Numbers */ + +# define DMA_REQ_SSP0TX (0) +# define DMA_REQ_SSP0RX (1) +# define DMA_REQ_SSP1TX (2) +# define DMA_REQ_SSP1RX (3) + +# define DMA_REQ_ADC (4) + +# define DMA_REQ_I2SCH0 (5) +# define DMA_REQ_I2SCH1 (6) + +# define DMA_REQ_DAC (7) + +# define DMA_REQ_UART0TX (8) /* DMASEL08=0*/ +# define DMA_REQ_UART0RX (9) /* DMASEL09=0*/ +# define DMA_REQ_UART1TX (10) /* DMASEL010=0*/ +# define DMA_REQ_UART1RX (11) /* DMASEL011=0*/ +# define DMA_REQ_UART2TX (12) /* DMASEL012=0*/ +# define DMA_REQ_UART2RX (13) /* DMASEL013=0*/ +# define DMA_REQ_UART3TX (14) /* DMASEL014=0*/ +# define DMA_REQ_UART3RX (15) /* DMASEL015=0*/ + +# define DMA_REQ_MAT0p0 (8) /* DMASEL08=1 */ +# define DMA_REQ_MAT0p1 (9) /* DMASEL09=1 */ +# define DMA_REQ_MAT1p0 (10) /* DMASEL010=1 */ +# define DMA_REQ_MAT1p1 (11) /* DMASEL011=1 */ +# define DMA_REQ_MAT2p0 (12) /* DMASEL012=1 */ +# define DMA_REQ_MAT2p1 (13) /* DMASEL013=1 */ +# define DMA_REQ_MAT3p0 (14) /* DMASEL014=1 */ +# define DMA_REQ_MAT3p1 (15) /* DMASEL015=1 */ + +/* DMASEL values. For the LPC176x family, only request numbers 8-15 have + * DMASEL bits. + */ + +# define DMA_DMASEL_SSP0TX (0) /* Not applicable */ +# define DMA_DMASEL_SSP0RX (0) /* Not applicable */ +# define DMA_DMASEL_SSP1TX (0) /* Not applicable */ +# define DMA_DMASEL_SSP1RX (0) /* Not applicable */ + +# define DMA_DMASEL_ADC (0) /* Not applicable */ + +# define DMA_DMASEL_I2SCH0 (0) /* Not applicable */ +# define DMA_DMASEL_I2SCH1 (0) /* Not applicable */ + +# define DMA_DMASEL_DAC (0) /* Not applicable */ + +# define DMA_DMASEL_UART0TX (0) +# define DMA_DMASEL_UART0RX (0) +# define DMA_DMASEL_UART1TX (0) +# define DMA_DMASEL_UART1RX (0) +# define DMA_DMASEL_UART2TX (0) +# define DMA_DMASEL_UART2RX (0) +# define DMA_DMASEL_UART3TX (0) +# define DMA_DMASEL_UART3RX (0) + +# define DMA_DMASEL_MAT0p0 (1) +# define DMA_DMASEL_MAT0p1 (1) +# define DMA_DMASEL_MAT1p0 (1) +# define DMA_DMASEL_MAT1p1 (1) +# define DMA_DMASEL_MAT2p0 (1) +# define DMA_DMASEL_MAT2p1 (1) +# define DMA_DMASEL_MAT3p0 (1) +# define DMA_DMASEL_MAT3p1 (1) + +#elif defined(LPC178x) +/* Request Numbers */ + +# define DMA_REQ_SDCARD (1) /* DMASEL01=0 */ + +# define DMA_REQ_SSP0TX (2) /* DMASEL02=0 */ +# define DMA_REQ_SSP0RX (3) /* DMASEL03=0 */ +# define DMA_REQ_SSP1TX (4) /* DMASEL04=0 */ +# define DMA_REQ_SSP1RX (5) /* DMASEL05=0 */ +# define DMA_REQ_SSP2TX (6) /* DMASEL06=0 */ +# define DMA_REQ_SSP2RX (7) /* DMASEL07=0 */ + +# define DMA_REQ_MAT0p0 (0) /* DMASEL00=1 */ +# define DMA_REQ_MAT0p1 (1) /* DMASEL01=1 */ +# define DMA_REQ_MAT1p0 (2) /* DMASEL02=1 */ +# define DMA_REQ_MAT1p1 (3) /* DMASEL03=1 */ +# define DMA_REQ_MAT2p0 (4) /* DMASEL04=1 */ +# define DMA_REQ_MAT2p1 (5) /* DMASEL05=1 */ +# define DMA_REQ_MAT3p0 (14) /* DMASEL14=1 */ +# define DMA_REQ_MAT3p1 (15) /* DMASEL15=1 */ + +# define DMA_REQ_I2SCH0 (6) /* DMASEL06=1 */ +# define DMA_REQ_I2SCH1 (7) /* DMASEL07=1 */ + +# define DMA_REQ_ADC (8) /* Not applicable */ +# define DMA_REQ_DAC (9) /* Not applicable */ + +# define DMA_REQ_UART0TX (10) /* DMASEL10=0 */ +# define DMA_REQ_UART0RX (11) /* DMASEL11=0 */ +# define DMA_REQ_UART1TX (12) /* DMASEL12=0 */ +# define DMA_REQ_UART1RX (13) /* DMASEL13=0 */ +# define DMA_REQ_UART2TX (14) /* DMASEL14=0 */ +# define DMA_REQ_UART2RX (15) /* DMASEL15=0 */ +# define DMA_REQ_UART3TX (10) /* DMASEL10=1 */ +# define DMA_REQ_UART3RX (11) /* DMASEL11=1 */ +# define DMA_REQ_UART4TX (12) /* DMASEL12=1 */ +# define DMA_REQ_UART4RX (13) /* DMASEL13=1 */ + +/* DMASEL values */ + +# define DMA_DMASEL_SDCARD (0) + +# define DMA_DMASEL_SSP0TX (0) +# define DMA_DMASEL_SSP0RX (0) +# define DMA_DMASEL_SSP1TX (0) +# define DMA_DMASEL_SSP1RX (0) +# define DMA_DMASEL_SSP2TX (0) +# define DMA_DMASEL_SSP2RX (0) + +# define DMA_DMASEL_MAT0p0 (1) +# define DMA_DMASEL_MAT0p1 (1) +# define DMA_DMASEL_MAT1p0 (1) +# define DMA_DMASEL_MAT1p1 (1) +# define DMA_DMASEL_MAT2p0 (1) +# define DMA_DMASEL_MAT2p1 (1) +# define DMA_DMASEL_MAT3p0 (1) +# define DMA_DMASEL_MAT3p1 (1) + +# define DMA_DMASEL_I2SCH0 (1) +# define DMA_DMASEL_I2SCH1 (1) + +# define DMA_DMASEL_ADC (0) /* Not applicable */ +# define DMA_DMASEL_DAC (0) /* Not applicable */ + +# define DMA_DMASEL_UART0TX (0) +# define DMA_DMASEL_UART0RX (0) +# define DMA_DMASEL_UART1TX (0) +# define DMA_DMASEL_UART1RX (0) +# define DMA_DMASEL_UART2TX (0) +# define DMA_DMASEL_UART2RX (0) +# define DMA_DMASEL_UART3TX (1) +# define DMA_DMASEL_UART3RX (1) +# define DMA_DMASEL_UART4TX (1) +# define DMA_DMASEL_UART4RX (1) +#endif + +/* General registers (see also LPC17_SYSCON_DMAREQSEL in lpc17_syscon.h) */ +/* Fach of the following registers, bits 0-7 controls DMA channels 9-7, + * respectively. Bits 8-31 are reserved. + * + * DMA Interrupt Status Register + * DMA Interrupt Terminal Count Request Status Register + * DMA Interrupt Terminal Count Request Clear Register + * DMA Interrupt Error Status Register + * DMA Interrupt Error Clear Register + * DMA Raw Interrupt Terminal Count Status Register + * DMA Raw Error Interrupt Status Register + * DMA Enabled Channel Register + */ + +#define DMACH(n) (1 << (n)) /* n=0,1,...7 */ +#define DMACH_ALL (0xff) + +/* For each of the following registers, bits 0-15 represent a set of encoded + * DMA sources. Bits 16-31 are reserved in each case. + * + * DMA Software Burst Request Register + * DMA Software Single Request Register + * DMA Software Last Burst Request Register + * DMA Software Last Single Request Register + * DMA Synchronization Register + */ + +#if defined(LPC176x) +# define DMA_REQ_SSP0TX_BIT (1 << DMA_REQ_SSP0TX) +# define DMA_REQ_SSP0RX_BIT (1 << DMA_REQ_SSP0RX) +# define DMA_REQ_SSP1TX_BIT (1 << DMA_REQ_SSP1TX) +# define DMA_REQ_SSP1RX_BIT (1 << DMA_REQ_SSP0RX) +# define DMA_REQ_ADC_BIT (1 << DMA_REQ_ADC) +# define DMA_REQ_I2SCH0_BIT (1 << DMA_REQ_I2SCH0) +# define DMA_REQ_I2SCH1_BIT (1 << DMA_REQ_I2SCH1) +# define DMA_REQ_DAC_BIT (1 << DMA_REQ_DAC) + +# define DMA_REQ_UART0TX_BIT (1 << DMA_REQ_UART0TX) +# define DMA_REQ_UART0RX_BIT (1 << DMA_REQ_UART0RX) +# define DMA_REQ_UART1TX_BIT (1 << DMA_REQ_UART1TX) +# define DMA_REQ_UART1RX_BIT (1 << DMA_REQ_UART1RX) +# define DMA_REQ_UART2TX_BIT (1 << DMA_REQ_UART2TX) +# define DMA_REQ_UART2RX_BIT (1 << DMA_REQ_UART2RX) +# define DMA_REQ_UART3TX_BIT (1 << DMA_REQ_UART3TX) +# define DMA_REQ_UART3RX_BIT (1 << DMA_REQ_UART3RX) + +# define DMA_REQ_MAT0p0_BIT (1 << DMA_REQ_MAT0p0) +# define DMA_REQ_MAT0p1_BIT (1 << DMA_REQ_MAT0p1) +# define DMA_REQ_MAT1p0_BIT (1 << DMA_REQ_MAT1p0) +# define DMA_REQ_MAT1p1_BIT (1 << DMA_REQ_MAT1p1) +# define DMA_REQ_MAT2p0_BIT (1 << DMA_REQ_MAT2p0) +# define DMA_REQ_MAT2p1_BIT (1 << DMA_REQ_MAT2p1) +# define DMA_REQ_MAT3p0_BIT (1 << DMA_REQ_MAT3p0) +# define DMA_REQ_MAT3p1_BIT (1 << DMA_REQ_MAT3p1) +#elif defined(LPC178x) +# define DMA_REQ_SDCARD_BIT (1 << DMA_REQ_SDCARD) + +# define DMA_REQ_SSP0TX_BIT (1 << DMA_REQ_SSP0TX) +# define DMA_REQ_SSP0RX_BIT (1 << DMA_REQ_SSP0RX) +# define DMA_REQ_SSP1TX_BIT (1 << DMA_REQ_SSP1TX) +# define DMA_REQ_SSP1RX_BIT (1 << DMA_REQ_SSP1RX) +# define DMA_REQ_SSP2TX_BIT (1 << DMA_REQ_SSP2TX) +# define DMA_REQ_SSP2RX_BIT (1 << DMA_REQ_SSP2RX) + +# define DMA_REQ_MAT0p0_BIT (1 << DMA_REQ_MAT0p0) +# define DMA_REQ_MAT0p1_BIT (1 << DMA_REQ_MAT0p1) +# define DMA_REQ_MAT1p0_BIT (1 << DMA_REQ_MAT1p0) +# define DMA_REQ_MAT1p1_BIT (1 << DMA_REQ_MAT1p1) +# define DMA_REQ_MAT2p0_BIT (1 << DMA_REQ_MAT2p0) +# define DMA_REQ_MAT2p1_BIT (1 << DMA_REQ_MAT2p1) +# define DMA_REQ_MAT3p0_BIT (1 << DMA_REQ_MAT3p0) +# define DMA_REQ_MAT3p1_BIT (1 << DMA_REQ_MAT3p1) + +# define DMA_REQ_I2SCH0_BIT (1 << DMA_REQ_I2SCH0) +# define DMA_REQ_I2SCH1_BIT (1 << DMA_REQ_I2SCH1) + +# define DMA_REQ_ADC_BIT (1 << DMA_REQ_ADC) +# define DMA_REQ_DAC_BIT (1 << DMA_REQ_DAC) + +# define DMA_REQ_UART0TX_BIT (1 << DMA_REQ_UART0TX) +# define DMA_REQ_UART0RX_BIT (1 << DMA_REQ_UART0RX) +# define DMA_REQ_UART1TX_BIT (1 << DMA_REQ_UART1TX) +# define DMA_REQ_UART1RX_BIT (1 << DMA_REQ_UART1RX) +# define DMA_REQ_UART2TX_BIT (1 << DMA_REQ_UART2TX) +# define DMA_REQ_UART2RX_BIT (1 << DMA_REQ_UART2RX) +# define DMA_REQ_UART3TX_BIT (1 << DMA_REQ_UART3TX) +# define DMA_REQ_UART3RX_BIT (1 << DMA_REQ_UART3RX) +# define DMA_REQ_UART4TX_BIT (1 << DMA_REQ_UART4TX) +# define DMA_REQ_UART4RX_BIT (1 << DMA_REQ_UART4RX) +#endif + +/* DMA Configuration Register */ + +#define DMA_CONFIG_E (1 << 0) /* Bit 0: DMA Controller enable */ +#define DMA_CONFIG_M (1 << 1) /* Bit 1: AHB Master endianness configuration */ + /* Bits 2-31: Reserved */ +/* Channel Registers */ + +/* DMA Channel Source Address Register (Bits 0-31: Source Address) */ +/* DMA Channel Destination Address Register Bits 0-31: Destination Address) */ +/* DMA Channel Linked List Item Register (Bits 0-31: Address of next link list + * item. Bits 0-1 must be zero. + */ + +/* DMA Channel Control Register */ + +#define DMACH_CONTROL_XFRSIZE_SHIFT (0) /* Bits 0-11: Transfer size */ +#define DMACH_CONTROL_XFRSIZE_MASK (0x0fff << DMACH_CONTROL_XFRSIZE_SHIFT) +# define DMACH_CONTROL_XFRSIZE(n) ((n) << DMACH_CONTROL_XFRSIZE_SHIFT) +#define DMACH_CONTROL_SBSIZE_SHIFT (12) /* Bits 12-14: Source burst size */ +#define DMACH_CONTROL_SBSIZE_MASK (7 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_1 (0 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_4 (1 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_8 (2 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_16 (3 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_32 (4 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_64 (5 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_128 (6 << DMACH_CONTROL_SBSIZE_SHIFT) +# define DMACH_CONTROL_SBSIZE_256 (7 << DMACH_CONTROL_SBSIZE_SHIFT) +#define DMACH_CONTROL_DBSIZE_SHIFT (15) /* Bits 15-17: Destination burst size */ +#define DMACH_CONTROL_DBSIZE_MASK (7 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_1 (0 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_4 (1 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_8 (2 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_16 (3 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_32 (4 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_64 (5 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_128 (6 << DMACH_CONTROL_DBSIZE_SHIFT) +# define DMACH_CONTROL_DBSIZE_256 (7 << DMACH_CONTROL_DBSIZE_SHIFT) +#define DMACH_CONTROL_SWIDTH_SHIFT (18) /* Bits 18-20: Source transfer width */ +#define DMACH_CONTROL_SWIDTH_MASK (7 << DMACH_CONTROL_SWIDTH_SHIFT) +# define DMACH_CONTROL_SWIDTH_8BIT (0 << DMACH_CONTROL_SWIDTH_SHIFT) /* Byte (8-bit) */ +# define DMACH_CONTROL_SWIDTH_16BIT (1 << DMACH_CONTROL_SWIDTH_SHIFT) /* Halfword (16-bit) */ +# define DMACH_CONTROL_SWIDTH_32BIT (2 << DMACH_CONTROL_SWIDTH_SHIFT) /* Word (32-bit) */ +#define DMACH_CONTROL_DWIDTH_SHIFT (21) /* Bits 21-23: Destination transfer width */ +#define DMACH_CONTROL_DWIDTH_MASK (7 << DMACH_CONTROL_DWIDTH_SHIFT) +# define DMACH_CONTROL_DWIDTH_8BIT (0 << DMACH_CONTROL_DWIDTH_SHIFT) /* Byte (8-bit) */ +# define DMACH_CONTROL_DWIDTH_16BIT (1 << DMACH_CONTROL_DWIDTH_SHIFT) /* Halfword (16-bit) */ +# define DMACH_CONTROL_DWIDTH_32BIT (2 << DMACH_CONTROL_DWIDTH_SHIFT) /* Word (32-bit) */ +#define DMACH_CONTROL_SI (1 << 26) /* Bit 26: Source increment */ +#define DMACH_CONTROL_DI (1 << 27) /* Bit 27: Destination increment */ +#define DMACH_CONTROL_PROT1 (1 << 28) /* Bit 28: User/priviledged mode */ +#define DMACH_CONTROL_PROT2 (1 << 29) /* Bit 29: Bufferable */ +#define DMACH_CONTROL_PROT3 (1 << 30) /* Bit 30: Cacheable */ +#define DMACH_CONTROL_I (1 << 31) /* Bit 31: Terminal count interrupt enable */ + +/* DMA Channel Configuration Register */ + +#define DMACH_CONFIG_E (1 << 0) /* Bit 0: Channel enable */ +#define DMACH_CONFIG_SRCPER_SHIFT (1) /* Bits 1-5: Source peripheral */ +#define DMACH_CONFIG_SRCPER_MASK (31 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SDCARD (DMA_REQ_SDCARD << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP0TX (DMA_REQ_SSP0TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP0RX (DMA_REQ_SSP0RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP1TX (DMA_REQ_SSP1TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP1RX (DMA_REQ_SSP1RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP2TX (DMA_REQ_SSP2TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_SSP2RX (DMA_REQ_SSP2RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_I2SCH0 (DMA_REQ_I2SCH0 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_I2SCH1 (DMA_REQ_I2SCH1 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_ADC (DMA_REQ_ADC << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_DAC (DMA_REQ_DAC << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART0TX (DMA_REQ_UART0TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART0RX (DMA_REQ_UART0RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART1TX (DMA_REQ_UART1TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART1RX (DMA_REQ_UART1RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART2TX (DMA_REQ_UART2TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART2RX (DMA_REQ_UART2RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART3TX (DMA_REQ_UART3TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART3RX (DMA_REQ_UART3RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART4TX (DMA_REQ_UART4TX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_UART4RX (DMA_REQ_UART4RX << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT0p0 (DMA_REQ_MAT0p0 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT0p1 (DMA_REQ_MAT0p1 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT1p0 (DMA_REQ_MAT1p0 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT1p1 (DMA_REQ_MAT1p1 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT2p0 (DMA_REQ_MAT2p0 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT2p1 (DMA_REQ_MAT2p1 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT3p0 (DMA_REQ_MAT3p0 << DMACH_CONFIG_SRCPER_SHIFT) +# define DMACH_CONFIG_SRCPER_MAT3p1 (DMA_REQ_MAT3p1 << DMACH_CONFIG_SRCPER_SHIFT) +#define DMACH_CONFIG_DSTPER_SHIFT (6) /* Bits 6-10: Destination peripheral */ +#define DMACH_CONFIG_DSTPER_MASK (31 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SDCARD (DMA_REQ_SDCARD << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP0TX (DMA_REQ_SSP0TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP0RX (DMA_REQ_SSP0RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP1TX (DMA_REQ_SSP1TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP1RX (DMA_REQ_SSP1RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP2TX (DMA_REQ_SSP2TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_SSP2RX (DMA_REQ_SSP2RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_I2SCH0 (DMA_REQ_I2SCH0 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_I2SCH1 (DMA_REQ_I2SCH1 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_ADC (DMA_REQ_ADC << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_DAC (DMA_REQ_DAC << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART0TX (DMA_REQ_UART0TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART0RX (DMA_REQ_UART0RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART1TX (DMA_REQ_UART1TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART1RX (DMA_REQ_UART1RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART2TX (DMA_REQ_UART2TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART2RX (DMA_REQ_UART2RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART3TX (DMA_REQ_UART3TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART3RX (DMA_REQ_UART3RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART4TX (DMA_REQ_UART4TX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_UART4RX (DMA_REQ_UART4RX << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT0p0 (DMA_REQ_MAT0p0 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT0p1 (DMA_REQ_MAT0p1 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT1p0 (DMA_REQ_MAT1p0 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT1p1 (DMA_REQ_MAT1p1 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT2p0 (DMA_REQ_MAT2p0 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT2p1 (DMA_REQ_MAT2p1 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT3p0 (DMA_REQ_MAT3p0 << DMACH_CONFIG_DSTPER_SHIFT) +# define DMACH_CONFIG_DSTPER_MAT3p1 (DMA_REQ_MAT3p1 << DMACH_CONFIG_DSTPER_SHIFT) +#define DMACH_CONFIG_XFRTYPE_SHIFT (11) /* Bits 11-13: Type of transfer */ +#define DMACH_CONFIG_XFRTYPE_MASK (7 << DMACH_CONFIG_XFRTYPE_SHIFT) + /* Flow controller = DMA controller */ +# define DMACH_CONFIG_XFRTYPE_M2M (0 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to memory */ +# define DMACH_CONFIG_XFRTYPE_M2P (1 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to peripheral */ +# define DMACH_CONFIG_XFRTYPE_P2M (2 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to memory */ +# define DMACH_CONFIG_XFRTYPE_P2P (3 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to peripheral */ +#ifdef LPC178x + /* Flow controller = Dest peripheral */ +# define DMACH_CONFIG_XFRTYPE_M2M_DC (4 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to memory */ +# define DMACH_CONFIG_XFRTYPE_M2P_DC (5 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Memory to peripheral */ + /* Flow controller = Source peripheral */ +# define DMACH_CONFIG_XFRTYPE_P2M_SC (6 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to memory */ +# define DMACH_CONFIG_XFRTYPE_P2P_SC (7 << DMACH_CONFIG_XFRTYPE_SHIFT) /* Peripheral to peripheral */ +#endif +#define DMACH_CONFIG_IE (1 << 14) /* Bit 14: Interrupt error mask */ +#define DMACH_CONFIG_ITC (1 << 15) /* Bit 15: Terminal count interrupt mask */ +#define DMACH_CONFIG_L (1 << 16) /* Bit 16: Lock */ +#define DMACH_CONFIG_A (1 << 17) /* Bit 17: Active */ +#define DMACH_CONFIG_H (1 << 18) /* Bit 18: Halt */ + /* Bits 19-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_GPDMA_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_gpio.h b/arch/arm/src/lpc17xx/chip/lpc17_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..aa5c0f57b008bd2ddd989410a7789c9eb692e7ab --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_gpio.h @@ -0,0 +1,210 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_gpio.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_GPIO_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* GPIO block register offsets ******************************************************/ + +#define LPC17_FIO0_OFFSET 0x0000 +#define LPC17_FIO1_OFFSET 0x0020 +#define LPC17_FIO2_OFFSET 0x0040 +#define LPC17_FIO3_OFFSET 0x0060 +#define LPC17_FIO4_OFFSET 0x0080 +#ifdef LPC178x +# define LPC17_FIO5_OFFSET 0x00a0 +#endif + +#define LPC17_FIO_DIR_OFFSET 0x0000 /* Fast GPIO Port Direction control */ +#define LPC17_FIO_MASK_OFFSET 0x0010 /* Fast Mask register for ports */ +#define LPC17_FIO_PIN_OFFSET 0x0014 /* Fast Port Pin value registers */ +#define LPC17_FIO_SET_OFFSET 0x0018 /* Fast Port Output Set registers */ +#define LPC17_FIO_CLR_OFFSET 0x001c /* Fast Port Output Clear register */ + +/* GPIO interrupt block register offsets ********************************************/ + +#define LPC17_GPIOINT_OFFSET(n) (0x10*(n) + 0x80) +#define LPC17_GPIOINT0_OFFSET 0x0080 +#define LPC17_GPIOINT2_OFFSET 0x00a0 + +#define LPC17_GPIOINT_IOINTSTATUS_OFFSET 0x0000 /* GPIO overall Interrupt Status */ +#define LPC17_GPIOINT_INTSTATR_OFFSET 0x0004 /* GPIO Interrupt Status Rising edge */ +#define LPC17_GPIOINT_INTSTATF_OFFSET 0x0008 /* GPIO Interrupt Status Falling edge */ +#define LPC17_GPIOINT_INTCLR_OFFSET 0x000c /* GPIO Interrupt Clear */ +#define LPC17_GPIOINT_INTENR_OFFSET 0x0010 /* GPIO Interrupt Enable Rising edge */ +#define LPC17_GPIOINT_INTENF_OFFSET 0x0014 /* GPIO Interrupt Enable Falling edge */ + +/* Register addresses ***************************************************************/ +/* GPIO block register addresses ****************************************************/ + +#define LPC17_FIO_BASE(n) (LPC17_GPIO_BASE+LPC17_GPIOINT_OFFSET(n)) +#define LPC17_FIO0_BASE (LPC17_GPIO_BASE+LPC17_FIO0_OFFSET) +#define LPC17_FIO1_BASE (LPC17_GPIO_BASE+LPC17_FIO1_OFFSET) +#define LPC17_FIO2_BASE (LPC17_GPIO_BASE+LPC17_FIO2_OFFSET) +#define LPC17_FIO3_BASE (LPC17_GPIO_BASE+LPC17_FIO3_OFFSET) +#define LPC17_FIO4_BASE (LPC17_GPIO_BASE+LPC17_FIO4_OFFSET) +#ifdef LPC178x +# define LPC17_FIO5_BASE (LPC17_GPIO_BASE+LPC17_FIO5_OFFSET) +#endif + +#define LPC17_FIO_DIR(n) (LPC17_FIO_BASE(n)+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO_MASK(n) (LPC17_FIO_BASE(n)+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO_PIN(n) (LPC17_FIO_BASE(n)+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO_SET(n) (LPC17_FIO_BASE(n)+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO_CLR(n) (LPC17_FIO_BASE(n)+LPC17_FIO_CLR_OFFSET) + +#define LPC17_FIO0_DIR (LPC17_FIO0_BASE+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO0_MASK (LPC17_FIO0_BASE+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO0_PIN (LPC17_FIO0_BASE+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO0_SET (LPC17_FIO0_BASE+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO0_CLR (LPC17_FIO0_BASE+LPC17_FIO_CLR_OFFSET) + +#define LPC17_FIO1_DIR (LPC17_FIO1_BASE+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO1_MASK (LPC17_FIO1_BASE+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO1_PIN (LPC17_FIO1_BASE+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO1_SET (LPC17_FIO1_BASE+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO1_CLR (LPC17_FIO1_BASE+LPC17_FIO_CLR_OFFSET) + +#define LPC17_FIO2_DIR (LPC17_FIO2_BASE+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO2_MASK (LPC17_FIO2_BASE+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO2_PIN (LPC17_FIO2_BASE+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO2_SET (LPC17_FIO2_BASE+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO2_CLR (LPC17_FIO2_BASE+LPC17_FIO_CLR_OFFSET) + +#define LPC17_FIO3_DIR (LPC17_FIO3_BASE+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO3_MASK (LPC17_FIO3_BASE+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO3_PIN (LPC17_FIO3_BASE+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO3_SET (LPC17_FIO3_BASE+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO3_CLR (LPC17_FIO3_BASE+LPC17_FIO_CLR_OFFSET) + +#define LPC17_FIO4_DIR (LPC17_FIO4_BASE+LPC17_FIO_DIR_OFFSET) +#define LPC17_FIO4_MASK (LPC17_FIO4_BASE+LPC17_FIO_MASK_OFFSET) +#define LPC17_FIO4_PIN (LPC17_FIO4_BASE+LPC17_FIO_PIN_OFFSET) +#define LPC17_FIO4_SET (LPC17_FIO4_BASE+LPC17_FIO_SET_OFFSET) +#define LPC17_FIO4_CLR (LPC17_FIO4_BASE+LPC17_FIO_CLR_OFFSET) + +#ifdef LPC178x +# define LPC17_FIO5_DIR (LPC17_FIO5_BASE+LPC17_FIO_DIR_OFFSET) +# define LPC17_FIO5_MASK (LPC17_FIO5_BASE+LPC17_FIO_MASK_OFFSET) +# define LPC17_FIO5_PIN (LPC17_FIO5_BASE+LPC17_FIO_PIN_OFFSET) +# define LPC17_FIO5_SET (LPC17_FIO5_BASE+LPC17_FIO_SET_OFFSET) +# define LPC17_FIO5_CLR (LPC17_FIO5_BASE+LPC17_FIO_CLR_OFFSET) +#endif + +/* GPIO interrupt block register addresses ******************************************/ + +#define LPC17_GPIOINTn_BASE(n) (LPC17_GPIOINT_BASE+LPC17_GPIOINT_OFFSET(n)) +#define LPC17_GPIOINT0_BASE (LPC17_GPIOINT_BASE+LPC17_GPIOINT0_OFFSET) +#define LPC17_GPIOINT2_BASE (LPC17_GPIOINT_BASE+LPC17_GPIOINT2_OFFSET) + +#define LPC17_GPIOINT_IOINTSTATUS (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_IOINTSTATUS_OFFSET) + +#define LPC17_GPIOINT_INTSTATR(n) (LPC17_GPIOINTn_BASE(n)+LPC17_GPIOINT_INTSTATR_OFFSET) +#define LPC17_GPIOINT_INTSTATF(n) (LPC17_GPIOINTn_BASE(n)+LPC17_GPIOINT_INTSTATF_OFFSET) +#define LPC17_GPIOINT_INTCLR(n) (LPC17_GPIOINTn_BASE(n)+LPC17_GPIOINT_INTCLR_OFFSET) +#define LPC17_GPIOINT_INTENR(n) (LPC17_GPIOINTn_BASE(n)+LPC17_GPIOINT_INTENR_OFFSET) +#define LPC17_GPIOINT_INTENF(n) (LPC17_GPIOINTn_BASE(n)+LPC17_GPIOINT_INTENF_OFFSET) + +/* Pins P0.0-31 */ + +#define LPC17_GPIOINT0_INTSTATR (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_INTSTATR_OFFSET) +#define LPC17_GPIOINT0_INTSTATF (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_INTSTATF_OFFSET) +#define LPC17_GPIOINT0_INTCLR (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_INTCLR_OFFSET) +#define LPC17_GPIOINT0_INTENR (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_INTENR_OFFSET) +#define LPC17_GPIOINT0_INTENF (LPC17_GPIOINT0_BASE+LPC17_GPIOINT_INTENF_OFFSET) + +/* Pins P2.0-31 */ + +#define LPC17_GPIOINT2_INTSTATR (LPC17_GPIOINT2_BASE+LPC17_GPIOINT_INTSTATR_OFFSET) +#define LPC17_GPIOINT2_INTSTATF (LPC17_GPIOINT2_BASE+LPC17_GPIOINT_INTSTATF_OFFSET) +#define LPC17_GPIOINT2_INTCLR (LPC17_GPIOINT2_BASE+LPC17_GPIOINT_INTCLR_OFFSET) +#define LPC17_GPIOINT2_INTENR (LPC17_GPIOINT2_BASE+LPC17_GPIOINT_INTENR_OFFSET) +#define LPC17_GPIOINT2_INTENF (LPC17_GPIOINT2_BASE+LPC17_GPIOINT_INTENF_OFFSET) + +/* Register bit definitions *********************************************************/ +/* GPIO block register bit definitions **********************************************/ + +/* Fast GPIO Port Direction control registers (FIODIR) */ +/* Fast Mask register for ports (FIOMASK) */ +/* Fast Port Pin value registers using FIOMASK (FIOPIN) */ +/* Fast Port Output Set registers using FIOMASK (FIOSET) */ +/* Fast Port Output Clear register using FIOMASK (FIOCLR) */ + +#define FIO(n) (1 << (n)) /* n=0,1,..31 */ + +/* GPIO interrupt block register bit definitions ************************************/ + +/* GPIO overall Interrupt Status (IOINTSTATUS) */ +#define GPIOINT_IOINTSTATUS_P0INT (1 << 0) /* Bit 0: Port 0 GPIO interrupt pending */ + /* Bit 1: Reserved */ +#define GPIOINT_IOINTSTATUS_P2INT (1 << 2) /* Bit 2: Port 2 GPIO interrupt pending */ + /* Bits 3-31: Reserved */ + +/* GPIO Interrupt Status for Rising edge (INTSTATR) + * GPIO Interrupt Status for Falling edge (INTSTATF) + * GPIO Interrupt Clear (INTCLR) + * GPIO Interrupt Enable for Rising edge (INTENR) + * GPIO Interrupt Enable for Falling edge (INTENF) + */ + +#define GPIOINT(n) (1 << (n)) /* n=0,1,..31 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CHIP_GPIO_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_i2c.h b/arch/arm/src/lpc17xx/chip/lpc17_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..96b6f19b1abbb86344907c17ffeaf663fd7fd701 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_i2c.h @@ -0,0 +1,208 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_i2c.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2C_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_I2C_CONSET_OFFSET 0x0000 /* I2C Control Set Register */ +#define LPC17_I2C_STAT_OFFSET 0x0004 /* I2C Status Register */ +#define LPC17_I2C_DAT_OFFSET 0x0008 /* I2C Data Register */ +#define LPC17_I2C_ADR0_OFFSET 0x000c /* I2C Slave Address Register 0 */ +#define LPC17_I2C_SCLH_OFFSET 0x0010 /* SCH Duty Cycle Register High Half Word */ +#define LPC17_I2C_SCLL_OFFSET 0x0014 /* SCL Duty Cycle Register Low Half Word */ +#define LPC17_I2C_CONCLR_OFFSET 0x0018 /* I2C Control Clear Register */ +#define LPC17_I2C_MMCTRL_OFFSET 0x001c /* Monitor mode control register */ +#define LPC17_I2C_ADR1_OFFSET 0x0020 /* I2C Slave Address Register 1 */ +#define LPC17_I2C_ADR2_OFFSET 0x0024 /* I2C Slave Address Register 2 */ +#define LPC17_I2C_ADR3_OFFSET 0x0028 /* I2C Slave Address Register 3 */ +#define LPC17_I2C_BUFR_OFFSET 0x002c /* Data buffer register */ +#define LPC17_I2C_MASK0_OFFSET 0x0030 /* I2C Slave address mask register 0 */ +#define LPC17_I2C_MASK1_OFFSET 0x0034 /* I2C Slave address mask register 1 */ +#define LPC17_I2C_MASK2_OFFSET 0x0038 /* I2C Slave address mask register 2 */ +#define LPC17_I2C_MASK3_OFFSET 0x003c /* I2C Slave address mask register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_I2C0_CONSET (LPC17_I2C0_BASE+LPC17_I2C_CONSET_OFFSET) +#define LPC17_I2C0_STAT (LPC17_I2C0_BASE+LPC17_I2C_STAT_OFFSET) +#define LPC17_I2C0_DAT (LPC17_I2C0_BASE+LPC17_I2C_DAT_OFFSET) +#define LPC17_I2C0_ADR0 (LPC17_I2C0_BASE+LPC17_I2C_ADR0_OFFSET) +#define LPC17_I2C0_SCLH (LPC17_I2C0_BASE+LPC17_I2C_SCLH_OFFSET) +#define LPC17_I2C0_SCLL (LPC17_I2C0_BASE+LPC17_I2C_SCLL_OFFSET) +#define LPC17_I2C0_CONCLR (LPC17_I2C0_BASE+LPC17_I2C_CONCLR_OFFSET) +#define LPC17_I2C0_MMCTRL (LPC17_I2C0_BASE+LPC17_I2C_MMCTRL_OFFSET) +#define LPC17_I2C0_ADR1 (LPC17_I2C0_BASE+LPC17_I2C_ADR1_OFFSET) +#define LPC17_I2C0_ADR2 (LPC17_I2C0_BASE+LPC17_I2C_ADR2_OFFSET) +#define LPC17_I2C0_ADR3 (LPC17_I2C0_BASE+LPC17_I2C_ADR3_OFFSET) +#define LPC17_I2C0_BUFR (LPC17_I2C0_BASE+LPC17_I2C_BUFR_OFFSET) +#define LPC17_I2C0_MASK0 (LPC17_I2C0_BASE+LPC17_I2C_MASK0_OFFSET) +#define LPC17_I2C0_MASK1 (LPC17_I2C0_BASE+LPC17_I2C_MASK1_OFFSET) +#define LPC17_I2C0_MASK2 (LPC17_I2C0_BASE+LPC17_I2C_MASK2_OFFSET) +#define LPC17_I2C0_MASK3 (LPC17_I2C0_BASE+LPC17_I2C_MASK3_OFFSET) + +#define LPC17_I2C1_CONSET (LPC17_I2C1_BASE+LPC17_I2C_CONSET_OFFSET) +#define LPC17_I2C1_STAT (LPC17_I2C1_BASE+LPC17_I2C_STAT_OFFSET) +#define LPC17_I2C1_DAT (LPC17_I2C1_BASE+LPC17_I2C_DAT_OFFSET) +#define LPC17_I2C1_ADR0 (LPC17_I2C1_BASE+LPC17_I2C_ADR0_OFFSET) +#define LPC17_I2C1_SCLH (LPC17_I2C1_BASE+LPC17_I2C_SCLH_OFFSET) +#define LPC17_I2C1_SCLL (LPC17_I2C1_BASE+LPC17_I2C_SCLL_OFFSET) +#define LPC17_I2C1_CONCLR (LPC17_I2C1_BASE+LPC17_I2C_CONCLR_OFFSET) +#define LPC17_I2C1_MMCTRL (LPC17_I2C1_BASE+LPC17_I2C_MMCTRL_OFFSET) +#define LPC17_I2C1_ADR1 (LPC17_I2C1_BASE+LPC17_I2C_ADR1_OFFSET) +#define LPC17_I2C1_ADR2 (LPC17_I2C1_BASE+LPC17_I2C_ADR2_OFFSET) +#define LPC17_I2C1_ADR3 (LPC17_I2C1_BASE+LPC17_I2C_ADR3_OFFSET) +#define LPC17_I2C1_BUFR (LPC17_I2C1_BASE+LPC17_I2C_BUFR_OFFSET) +#define LPC17_I2C1_MASK0 (LPC17_I2C1_BASE+LPC17_I2C_MASK0_OFFSET) +#define LPC17_I2C1_MASK1 (LPC17_I2C1_BASE+LPC17_I2C_MASK1_OFFSET) +#define LPC17_I2C1_MASK2 (LPC17_I2C1_BASE+LPC17_I2C_MASK2_OFFSET) +#define LPC17_I2C1_MASK3 (LPC17_I2C1_BASE+LPC17_I2C_MASK3_OFFSET) + +#define LPC17_I2C2_CONSET (LPC17_I2C2_BASE+LPC17_I2C_CONSET_OFFSET) +#define LPC17_I2C2_STAT (LPC17_I2C2_BASE+LPC17_I2C_STAT_OFFSET) +#define LPC17_I2C2_DAT (LPC17_I2C2_BASE+LPC17_I2C_DAT_OFFSET) +#define LPC17_I2C2_ADR0 (LPC17_I2C2_BASE+LPC17_I2C_ADR0_OFFSET) +#define LPC17_I2C2_SCLH (LPC17_I2C2_BASE+LPC17_I2C_SCLH_OFFSET) +#define LPC17_I2C2_SCLL (LPC17_I2C2_BASE+LPC17_I2C_SCLL_OFFSET) +#define LPC17_I2C2_CONCLR (LPC17_I2C2_BASE+LPC17_I2C_CONCLR_OFFSET) +#define LPC17_I2C2_MMCTRL (LPC17_I2C2_BASE+LPC17_I2C_MMCTRL_OFFSET) +#define LPC17_I2C2_ADR1 (LPC17_I2C2_BASE+LPC17_I2C_ADR1_OFFSET) +#define LPC17_I2C2_ADR2 (LPC17_I2C2_BASE+LPC17_I2C_ADR2_OFFSET) +#define LPC17_I2C2_ADR3 (LPC17_I2C2_BASE+LPC17_I2C_ADR3_OFFSET) +#define LPC17_I2C2_BUFR (LPC17_I2C2_BASE+LPC17_I2C_BUFR_OFFSET) +#define LPC17_I2C2_MASK0 (LPC17_I2C2_BASE+LPC17_I2C_MASK0_OFFSET) +#define LPC17_I2C2_MASK1 (LPC17_I2C2_BASE+LPC17_I2C_MASK1_OFFSET) +#define LPC17_I2C2_MASK2 (LPC17_I2C2_BASE+LPC17_I2C_MASK2_OFFSET) +#define LPC17_I2C2_MASK3 (LPC17_I2C2_BASE+LPC17_I2C_MASK3_OFFSET) + +/* Register bit definitions *********************************************************/ +/* I2C Control Set Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONSET_AA (1 << 2) /* Bit 2: Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* Bit 3: I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* Bit 4: STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* Bit 5: START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* Bit 6: I2C interface enable */ + /* Bits 7-31: Reserved */ +/* I2C Control Clear Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONCLR_AAC (1 << 2) /* Bit 2: Assert acknowledge Clear bit */ +#define I2C_CONCLR_SIC (1 << 3) /* Bit 3: I2C interrupt Clear bit */ + /* Bit 4: Reserved */ +#define I2C_CONCLR_STAC (1 << 5) /* Bit 5: START flag Clear bit */ +#define I2C_CONCLRT_I2ENC (1 << 6) /* Bit 6: I2C interface Disable bit */ + /* Bits 7-31: Reserved */ +/* I2C Status Register + * + * See tables 399-402 in the "LPC17xx User Manual" (UM10360), Rev. 01, 4 January + * 2010, NXP for definitions of status codes. + */ + +#define I2C_STAT_MASK (0xff) /* Bits 0-7: I2C interface status + * Bits 0-1 always zero */ + /* Bits 8-31: Reserved */ +/* I2C Data Register */ + +#define I2C_DAT_MASK (0xff) /* Bits 0-7: I2C data */ + /* Bits 8-31: Reserved */ +/* Monitor mode control register */ + +#define I2C_MMCTRL_MMENA (1 << 0) /* Bit 0: Monitor mode enable */ +#define I2C_MMCTRL_ENASCL (1 << 1) /* Bit 1: SCL output enable */ +#define I2C_MMCTRL_MATCHALL (1 << 2) /* Bit 2: Select interrupt register match */ + /* Bits 3-31: Reserved */ +/* Data buffer register */ + +#define I2C_BUFR_MASK (0xff) /* Bits 0-7: 8 MSBs of the I2DAT shift register */ + /* Bits 8-31: Reserved */ +/* I2C Slave address registers: + * + * I2C Slave Address Register 0 + * I2C Slave Address Register 1 + * I2C Slave Address Register 2 + * I2C Slave Address Register 3 + */ + +#define I2C_ADR_GC (1 << 0) /* Bit 0: GC General Call enable bit */ +#define I2C_ADR_ADDR_SHIFT (1) /* Bits 1-7: I2C slave address */ +#define I2C_ADR_ADDR_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Slave address mask registers: + * + * I2C Slave address mask register 0 + * I2C Slave address mask register 1 + * I2C Slave address mask register 2 + * I2C Slave address mask register 3 + */ + /* Bit 0: Reserved */ +#define I2C_MASK_SHIFT (1) /* Bits 1-7: I2C mask bits */ +#define I2C_MASK_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* SCH Duty Cycle Register High Half Word */ + +#define I2C_SCLH_MASK (0xffff) /* Bit 0-15: Count for SCL HIGH time period selection */ + /* Bits 16-31: Reserved */ +/* SCL Duty Cycle Register Low Half Word */ + +#define I2C_SCLL_MASK (0xffff) /* Bit 0-15: Count for SCL LOW time period selection */ + /* Bits 16-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2C_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_i2s.h b/arch/arm/src/lpc17xx/chip/lpc17_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..100d2f39f1331d99ca7aa957b6198ef26ab7c7a0 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_i2s.h @@ -0,0 +1,190 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_i2s + * + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_I2S_DAO_OFFSET 0x0000 /* Digital Audio Output Register */ +#define LPC17_I2S_DAI_OFFSET 0x0004 /* Digital Audio Input Register */ +#define LPC17_I2S_TXFIFO_OFFSET 0x0008 /* Transmit FIFO */ +#define LPC17_I2S_RXFIFO_OFFSET 0x000c /* Receive FIFO */ +#define LPC17_I2S_STATE_OFFSET 0x0010 /* Status Feedback Register */ +#define LPC17_I2S_DMA1_OFFSET 0x0014 /* DMA Configuration Register 1 */ +#define LPC17_I2S_DMA2_OFFSET 0x0018 /* DMA Configuration Register 2 */ +#define LPC17_I2S_IRQ_OFFSET 0x001c /* Interrupt Request Control Register */ +#define LPC17_I2S_TXRATE_OFFSET 0x0020 /* Transmit MCLK divider */ +#define LPC17_I2S_RXRATE_OFFSET 0x0024 /* Receive MCLK divider */ +#define LPC17_I2S_TXBITRATE_OFFSET 0x0028 /* Transmit bit rate divider */ +#define LPC17_I2S_RXBITRATE_OFFSET 0x002c /* Receive bit rate divider */ +#define LPC17_I2S_TXMODE_OFFSET 0x0030 /* Transmit mode control */ +#define LPC17_I2S_RXMODE_OFFSET 0x0034 /* Receive mode control */ + +/* Register addresses ***************************************************************/ + +#define LPC17_I2S_DAO (LPC17_I2S_BASE+LPC17_I2S_DAO_OFFSET) +#define LPC17_I2S_DAI (LPC17_I2S_BASE+LPC17_I2S_DAI_OFFSET) +#define LPC17_I2S_TXFIFO (LPC17_I2S_BASE+LPC17_I2S_TXFIFO_OFFSET) +#define LPC17_I2S_RXFIFO (LPC17_I2S_BASE+LPC17_I2S_RXFIFO_OFFSET) +#define LPC17_I2S_STATE (LPC17_I2S_BASE+LPC17_I2S_STATE_OFFSET) +#define LPC17_I2S_DMA1 (LPC17_I2S_BASE+LPC17_I2S_DMA1_OFFSET) +#define LPC17_I2S_DMA2 (LPC17_I2S_BASE+LPC17_I2S_DMA2_OFFSET) +#define LPC17_I2S_IRQ (LPC17_I2S_BASE+LPC17_I2S_IRQ_OFFSET) +#define LPC17_I2S_TXRATE (LPC17_I2S_BASE+LPC17_I2S_TXRATE_OFFSET) +#define LPC17_I2S_RXRATE (LPC17_I2S_BASE+LPC17_I2S_RXRATE_OFFSET) +#define LPC17_I2S_TXBITRATE (LPC17_I2S_BASE+LPC17_I2S_TXBITRATE_OFFSET) +#define LPC17_I2S_RXBITRATE (LPC17_I2S_BASE+LPC17_I2S_RXBITRATE_OFFSET) +#define LPC17_I2S_TXMODE (LPC17_I2S_BASE+LPC17_I2S_TXMODE_OFFSET) +#define LPC17_I2S_RXMODE (LPC17_I2S_BASE+LPC17_I2S_RXMODE_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Digital Audio Output Register */ + +#define I2S_DAO_WDWID_SHIFT (0) /* Bits 0-1: Selects the number of bytes in data */ +#define I2S_DAO_WDWID_MASK (3 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_8BITS (0 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_16BITS (1 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_32BITS (3 << I2S_DAO_WDWID_SHIFT) +#define I2S_DAO_MONO (1 << 2) /* Bit 2: Mono format */ +#define I2S_DAO_STOP (1 << 3) /* Bit 3: Disable FIFOs / mute mode */ +#define I2S_DAO_RESET (1 << 4) /* Bit 4: Reset TX channel and FIFO */ +#define I2S_DAO_WSSEL (1 << 5) /* Bit 5: Slave mode select */ +#define I2S_DAO_WSHALFPER_SHIFT (6) /* Bits 6-14: Word select half period minus 1 */ +#define I2S_DAO_WSHALFPER_MASK (0x01ff << I2S_DAO_WSHALFPER_SHIFT) +#define I2S_DAO_MUTE (1 << 15) /* Bit 15: Send only zeros on channel */ + /* Bits 16-31: Reserved */ +/* Digital Audio Input Register */ + +#define I2S_DAI_WDWID_SHIFT (0) /* Bits 0-1: Selects the number of bytes in data */ +#define I2S_DAI_WDWID_MASK (3 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_8BITS (0 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_16BITS (1 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_32BITS (3 << I2S_DAI_WDWID_SHIFT) +#define I2S_DAI_MONO (1 << 2) /* Bit 2: Mono format */ +#define I2S_DAI_STOP (1 << 3) /* Bit 3: Disable FIFOs / mute mode */ +#define I2S_DAI_RESET (1 << 4) /* Bit 4: Reset TX channel and FIFO */ +#define I2S_DAI_WSSEL (1 << 5) /* Bit 5: Slave mode select */ +#define I2S_DAI_WSHALFPER_SHIFT (6) /* Bits 6-14: Word select half period minus 1 */ +#define I2S_DAI_WSHALFPER_MASK (0x01ff << I2S_DAI_WSHALFPER_SHIFT) + /* Bits 15-31: Reserved */ +/* Transmit FIFO: 8 × 32-bit transmit FIFO */ +/* Receive FIFO: 8 × 32-bit receive FIFO */ + +/* Status Feedback Register */ + +#define I2S_STATE_IRQ (1 << 0) /* Bit 0: Receive Transmit Interrupt */ +#define I2S_STATE_DMAREQ1 (1 << 1) /* Bit 1: Receive or Transmit DMA Request 1 */ +#define I2S_STATE_DMAREQ2 (1 << 2) /* Bit 2: Receive or Transmit DMA Request 2 */ + /* Bits 3-7: Reserved */ +#define I2S_STATE_RXLEVEL_SHIFT (8) /* Bits 8-11: Current level of the Receive FIFO */ +#define I2S_STATE_RXLEVEL_MASK (15 << I2S_STATE_RXLEVEL_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_STATE_TXLEVEL_SHIFT (16) /* Bits 16-19: Current level of the Transmit FIFO */ +#define I2S_STATE_TXLEVEL_MASK (15 << I2S_STATE_TXLEVEL_SHIFT) + /* Bits 20-31: Reserved */ +/* DMA Configuration Register 1 and 2 */ + +#define I2S_DMA_RXDMAEN (1 << 0) /* Bit 0: Enable DMA1 for I2S receive */ +#define I2S_DMA_TXDMAEN (1 << 1) /* Bit 1: Enable DMA1 for I2S transmit */ + /* Bits 2-7: Reserved */ +#define I2S_DMA_RXDEPTH_SHIFT (8) /* Bits 8-11: FIFO level that triggers RX request on DMA1 */ +#define I2S_DMA_RXDEPTH_MASK (15 << I2S_DMA_RXDEPTH_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_DMA_TXDEPTH_SHIFT (16) /* Bits 16-19: FIFO level that triggers a TX request on DMA1 */ +#define I2S_DMA_TXDEPTH_MASK (15 << I2S_DMA_TXDEPTH_SHIFT) + /* Bits 20-31: Reserved */ +/* Interrupt Request Control Register */ + +#define I2S_IRQ_RXEN (1 << 0) /* Bit 0: Enable I2S receive interrupt */ +#define I2S_IRQ_TXEN (1 << 1) /* Bit 1: Enable I2S transmit interrupt */ + /* Bits 2-7: Reserved */ +#define I2S_IRQ_RXDEPTH_SHIFT (8) /* Bits 8-11: Set FIFO level for irq request */ +#define I2S_IRQ_RXDEPTH_MASK (15 << I2S_IRQ_RXDEPTH_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_IRQ_TXDEPTH_SHIFT (16) /* Bits 16-19: Set FIFO level for irq request */ +#define I2S_IRQ_TXDEPTH_MASK (15 << I2S_IRQ_TXDEPTH_SHIFT) + /* Bits 20-31: Reserved */ +/* Transmit and Receive MCLK divider */ + +#define I2S_RATE_YDIV_SHIFT (0) /* Bits 0-7: I2S transmit MCLK rate denominator */ +#define I2S_RATE_YDIV_MASK (0xff << I2S_RATE_YDIV_SHIFT) +#define I2S_RATE_XDIV_SHIFT (8) /* Bits 8-15: I2S transmit MCLK rate numerator */ +#define I2S_RATE_XDIV_MASK (0xff << I2S_RATE_XDIV_SHIFT) + /* Bits 16-31: Reserved */ + +/* Transmit and received bit rate divider */ + +#define I2S_BITRATE_SHIFT (0) /* Bits 0-5: I2S transmit bit rate */ +#define I2S_BITRATE_MASK (0x3f << I2S_BITRATE_SHIFT) + /* Bits 6-31: Reserved */ +/* Transmit and Receive mode control */ + +#define I2S_MODE_CLKSEL_SHIFT (0) /* Bits 0-1: Clock source for bit clock divider */ +#define I2S_MODE_CLKSEL_MASK (3 << I2S_MODE_CLKSEL_SHIFT) +# define I2S_MODE_CLKSEL_FRACDIV (0 << I2S_MODE_CLKSEL_SHIFT) /* TX/RX fractional rate divider */ +# define I2S_MODE_CLKSEL_RXMCLK (2 << I2S_MODE_CLKSEL_SHIFT) /* RX_CLCK for TX_MCLK source */ +# define I2S_MODE_CLKSEL_TXMCLK (2 << I2S_MODE_CLKSEL_SHIFT) /* TX_CLCK for RX_MCLK source */ +#define I2S_MODE_4PIN (1 << 2) /* Bit 2: Transmit/Receive 4-pin mode selection */ +#define I2S_MODE_MCENA (1 << 3) /* Bit 3: Enable for the TX/RX_MCLK output */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_lcd.h b/arch/arm/src/lpc17xx/chip/lpc17_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..ef334a1a6723d778021a0132c13304d8fe56c175 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_lcd.h @@ -0,0 +1,346 @@ +/************************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_lcd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_LCD_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_LCD_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Register offsets *****************************************************************************/ + +#define LPC17_LCD_TIMH_OFFSET (0x0000) /* Horizontal Timing Control register */ +#define LPC17_LCD_TIMV_OFFSET (0x0004) /* Vertical Timing Control register */ +#define LPC17_LCD_POL_OFFSET (0x0008) /* Clock & Signal Polarity Control register */ +#define LPC17_LCD_LE_OFFSET (0x000c) /* Line End Control register */ +#define LPC17_LCD_UPBASE_OFFSET (0x0010) /* Upper Panel Frame Base Address register */ +#define LPC17_LCD_LPBASE_OFFSET (0x0014) /* Lower Panel Frame Base Address register */ +#define LPC17_LCD_CTRL_OFFSET (0x0018) /* LCD Control register */ +#define LPC17_LCD_INTMSK_OFFSET (0x001c) /* Interrupt Mask register */ +#define LPC17_LCD_INTRAW_OFFSET (0x0020) /* Raw Interrupt Status register */ +#define LPC17_LCD_INTSTAT_OFFSET (0x0024) /* Masked Interrupt Status register */ +#define LPC17_LCD_INTCLR_OFFSET (0x0028) /* Interrupt Clear register */ +#define LPC17_LCD_UPCURR_OFFSET (0x002c) /* Upper Panel Current Address Value register */ +#define LPC17_LCD_LPCURR_OFFSET (0x0030) /* Lower Panel Current Address Value register */ + +/* 256x16-bit Color Palette registers, n=0-127 */ + +#define LPC17_LCD_PAL_OFFSET(n) (0x0200 + ((n) << 2)) + +/* Cursor Image registers, n=0-255 */ + +#define LPC17_LCD_CRSR_IMG_OFFSET(n) (0x0800 + ((n) << 2)) + +#define LPC17_LCD_CRSR_CRTL_OFFSET (0x0c00) /* Cursor Control register */ +#define LPC17_LCD_CRSR_CFG_OFFSET (0x0c04) /* Cursor Configuration register */ +#define LPC17_LCD_CRSR_PAL0_OFFSET (0x0c08) /* Cursor Palette register 0 */ +#define LPC17_LCD_CRSR_PAL1_OFFSET (0x0c0c) /* Cursor Palette register 1 */ +#define LPC17_LCD_CRSR_XY_OFFSET (0x0c10) /* Cursor XY Position register */ +#define LPC17_LCD_CRSR_CLIP_OFFSET (0x0c14) /* Cursor Clip Position register */ +#define LPC17_LCD_CRSR_INTMSK_OFFSET (0x0c20) /* Cursor Interrupt Mask regsiter */ +#define LPC17_LCD_CRSR_INTCLR_OFFSET (0x0c24) /* Cursor Interrupt Clear register */ +#define LPC17_LCD_CRSR_INTRAW_OFFSET (0x0c28) /* Cursor Raw Interrupt Status register */ +#define LPC17_LCD_CRSR_INTSTAT_OFFSET (0x0c2c) /* Cursor Masked Interrupt Status register */ + +/* Register Addresses ***************************************************************************/ + +#define LPC17_LCD_TIMH (LPC17_LCD_BASE+LPC17_LCD_TIMH_OFFSET) +#define LPC17_LCD_TIMV (LPC17_LCD_BASE+LPC17_LCD_TIMV_OFFSET) +#define LPC17_LCD_POL (LPC17_LCD_BASE+LPC17_LCD_POL_OFFSET) +#define LPC17_LCD_LE (LPC17_LCD_BASE+LPC17_LCD_LE_OFFSET) +#define LPC17_LCD_UPBASE (LPC17_LCD_BASE+LPC17_LCD_UPBASE_OFFSET) +#define LPC17_LCD_LPBASE (LPC17_LCD_BASE+LPC17_LCD_LPBASE_OFFSET) +#define LPC17_LCD_CTRL (LPC17_LCD_BASE+LPC17_LCD_CTRL_OFFSET) +#define LPC17_LCD_INTMSK (LPC17_LCD_BASE+LPC17_LCD_INTMSK_OFFSET) +#define LPC17_LCD_INTRAW (LPC17_LCD_BASE+LPC17_LCD_INTRAW_OFFSET) +#define LPC17_LCD_INTSTAT (LPC17_LCD_BASE+LPC17_LCD_INTSTAT_OFFSET) +#define LPC17_LCD_INTCLR (LPC17_LCD_BASE+ LPC17_LCD_INTCLR_OFFSET) +#define LPC17_LCD_UPCURR (LPC17_LCD_BASE+LPC17_LCD_UPCURR_OFFSET) +#define LPC17_LCD_LPCURR (LPC17_LCD_BASE+LPC17_LCD_LPCURR_OFFSET) + +#define LPC17_LCD_PAL(n) (LPC17_LCD_BASE+LPC17_LCD_PAL_OFFSET(n)) +#define LPC17_LCD_CRSR_IMG(n) (LPC17_LCD_BASE+LPC17_LCD_CRSR_IMG_OFFSET(n)) + +#define LPC17_LCD_CRSR_CRTL (LPC17_LCD_BASE+LPC17_LCD_CRSR_CRTL_OFFSET) +#define LPC17_LCD_CRSR_CFG (LPC17_LCD_BASE+LPC17_LCD_CRSR_CFG_OFFSET) +#define LPC17_LCD_CRSR_PAL0 (LPC17_LCD_BASE+LPC17_LCD_CRSR_PAL0_OFFSET) +#define LPC17_LCD_CRSR_PAL1 (LPC17_LCD_BASE+LPC17_LCD_CRSR_PAL1_OFFSET) +#define LPC17_LCD_CRSR_XY (LPC17_LCD_BASE+LPC17_LCD_CRSR_XY_OFFSET) +#define LPC17_LCD_CRSR_CLIP (LPC17_LCD_BASE+LPC17_LCD_CRSR_CLIP_OFFSET) +#define LPC17_LCD_CRSR_INTMSK (LPC17_LCD_BASE+LPC17_LCD_CRSR_INTMSK_OFFSET) +#define LPC17_LCD_CRSR_INTCLR (LPC17_LCD_BASE+LPC17_LCD_CRSR_INTCLR_OFFSET) +#define LPC17_LCD_CRSR_INTRAW (LPC17_LCD_BASE+LPC17_LCD_CRSR_INTRAW_OFFSET) +#define LPC17_LCD_CRSR_INTSTAT (LPC17_LCD_BASE+LPC17_LCD_CRSR_INTSTAT_OFFSET) + +/* Register Bitfield Definitions ****************************************************************/ + +/* LCD_TIMH - Horizontal Timing Register */ + /* Bits 0-1: Reserved */ +#define LCD_TIMH_PPL_SHIFT (2) /* Bits 2-7: Pixels Per Line - 16-1024ppl */ +#define LCD_TIMH_PPL_MASK (0x3f << LCD_TIMH_PPL_SHIFT) +#define LCD_TIMH_HSW_SHIFT (8) /* Bits 8-15: Horizontal Sync Pulse Width */ +#define LCD_TIMH_HWS_MASK (0xff << LCD_TIMH_HSW_SHIFT) +#define LCD_TIMH_HFP_SHIFT (16) /* Bits 16-23: Horizontal Front Porch */ +#define LCD_TIMH_HFP_MASK (0xff << LCD_TIMH_HFP_SHIFT) +#define LCD_TIMH_HBP_SHIFT (24) /* Bits 24-31: Horizontal Back Porch */ +#define LCD_TIMH_HBP_MASK (0xff << LCD_TIMH_HBP_SHIFT) + +/* LCD_TIMV - Vertical Timing Register */ + +#define LCD_TIMV_LPP_SHIFT (0) /* Bits 0-9: Lines Per Panel 1-1024 lpp*/ +#define LCD_TIMV_LPP_MASK (0x3ff << LCD_TIMV_LPP_SHIFT) +#define LCD_TIMV_VSW_SHIFT (10) /* Bits 10-15: Vertical Synch Pulse Width */ +#define LCD_TIMV_VSW_MASK (0x3f << LCD_TIMV_VSW_SHIFT) +#define LCD_TIMV_VFP_SHIFT (16) /* Bits 16-23: Vertical Front Porch */ +#define LCD_TIMV_VFP_MASK (0xff << LCD_TIMV_VFP_SHIFT) +#define LCD_TIMV_VBP_SHIFT (24) /* Bits 24-31: Vertical Back Porch */ +#define LCD_TIMV_VBP_MASK (0xff << LCD_TIMV_VBP_SHIFT) + +/* LCD_POL - Clock and Signal Polarity Register */ + +#define LCD_POL_PCDLO_SHIFT (0) /* Bits 0-4: Lower 5 bits of panel clock divisor */ +#define LCD_POL_PCDLO_MASK (0x1f << LCD_POL_PCDLO_SHIFT) +#define LCD_POL_CLKSEL (1 << 5) /* Bit 5: Clock select- 0=PCLK, 1=LCD_CLKIN */ +#define LCD_POL_ACB_SHIFT (6) /* Bits 6-10: AC bias pin frequency */ +#define LCD_POL_ACB_MASK (0x1f << LCD_POL_ACB_SHIFT) +#define LCD_POL_IVS (1 << 11) /* Bit 11: Invert vertical sync */ +#define LCD_POL_IHS (1 << 12) /* Bit 12: Invert horizontal sync */ +#define LCD_POL_IPC (1 << 13) /* Bit 13: Invert panel clock */ +#define LCD_POL_IOE (1 << 14) /* Bit 14: Invert output enable */ + /* Bit 15: Reserved */ +#define LCD_POL_CPL_SHIFT (16) /* Bit 16-25: Clocks per line */ +#define LCD_POL_CPL_MASK (0x3ff << LCD_POL_CPL_SHIFT) +#define LCD_POL_BCD (1 << 26) /* Bit 26: Bypass pixel clock divider */ +#define LCD_POL_PCDHI_SHIFT (27) /* Bits 27-31: Upper 5 bits of panel clock divisor */ +#define LCD_POL_PCDHI_MASK (0x1f << LCD_POL_PCDHI_SHIFT) + +/* LCD_LE - Line End Control Register */ + +#define LCD_LE_LED_SHIFT (0) /* Bits 0-6: Line End delay */ +#define LCD_LE_LED_MASK (0x7f << LCD_LE_LED_SHIFT) + /* Bits 7-15: Reserved */ +#define LCD_LE_LEE (1 << 16) /* Bit 16: LCD line end enable */ + /* Bit 17-31: Reserved */ +/* LCD_UPBASE - Upper Panel Frame Base Address Register */ + /* Bits 0-2: Reserved */ +#define LCD_UPBASE_LCDUPBASE_SHIFT (3) /* Bits 3-31: LCD upper panel base address */ +#define LCD_UPBASE_LCDUPBASE_MASK (0x1FFFFFFF << LCD_UPBASE_LCDUPBASE_SHIFT) + +/* LCD_UPBASE - Lower Panel Frame Base Address Register */ + /* Bits 0-2: Reserved */ +#define LCD_UPBASE_LCDLPBASE_SHIFT (3) /* Bits 3-31: LCD lower panel base address */ +#define LCD_UPBASE_LCDLPBASE_MASK (0x1FFFFFFF << LCD_UPBASE_LCDUPBASE_SHIFT) + +/* LCD_CTRL - Controle Register */ + +#define LCD_CTRL_LCDEN (1 << 0) /* Bit 0: LCD enable control bit */ +#define LCD_CTRL_LCDBPP_SHIFT (1) /* Bits 1-3: LCD bits per pixel */ +#define LCD_CTRL_LCDBPP_MASK (7 << LCD_CTRL_LCDBPP_SHIFT) +# define LCD_CTRL_LCDBPP_1 (0 << LCD_CTRL_LCDBPP_SHIFT) /* 1 bpp */ +# define LCD_CTRL_LCDBPP_2 (1 << LCD_CTRL_LCDBPP_SHIFT) /* 2 bpp */ +# define LCD_CTRL_LCDBPP_4 (2 << LCD_CTRL_LCDBPP_SHIFT) /* 4 bpp */ +# define LCD_CTRL_LCDBPP_8 (3 << LCD_CTRL_LCDBPP_SHIFT) /* 8 bpp */ +# define LCD_CTRL_LCDBPP_16 (4 << LCD_CTRL_LCDBPP_SHIFT) /* 16 bpp */ +# define LCD_CTRL_LCDBPP_24 (5 << LCD_CTRL_LCDBPP_SHIFT) /* 24 bpp (TFT panel only) */ +# define LCD_CTRL_LCDBPP_565 (6 << LCD_CTRL_LCDBPP_SHIFT) /* 16 bpp, 5:6:5 mode */ +# define LCD_CTRL_LCDBPP_444 (7 << LCD_CTRL_LCDBPP_SHIFT) /* 12 bpp, 4:4:4 mode */ +#define LCD_CTRL_LCDBW (1 << 4) /* Bit 4: STN LCD monochrome/color selection */ +#define LCD_CTRL_LCDTFT (1 << 5) /* Bit 5: LCD TFT type selection */ +#define LCD_CTRL_LCDMONO8 (1 << 6) /* Bit 6: Monochrome LCD interface bit */ +#define LCD_CTRL_LCDDUAL (1 << 7) /* Bit 7: Single or Dual LCD panel selection */ +#define LCD_CTRL_BGR (1 << 8) /* Bit 8: Color format */ +#define LCD_CTRL_BEBO (1 << 9) /* Bit 9: Big-Endian Byte Order */ +#define LCD_CTRL_BEPO (1 << 10) /* Bit 10: Big-Endian Pixel Ordering */ +#define LCD_CTRL_LCDPWR (1 << 11) /* Bit 11: LCD Power enable */ +#define LCD_CTRL_LCDVCOMP_SHIFT (12) /* Bits 12-13: LCD Vertical compare interrupt */ +#define LCD_CTRL_LCDVCOMP_MASK (3 << LCD_CTRL_LCDVCOMP_SHIFT) + /* Bits 14-15: Reserved */ +#define LCD_CTRL_WATERMARK (1 << 16) /* Bit 16: LCD DMA FIFO watermark level */ + /* Bits 17-31: Reserved */ +/* LCD_INTMSK - Interrupt Mask Register */ + /* Bits 0: Reserved */ +#define LCD_INTMSK_FUFIM (1 << 1) /* Bit 1: FIFO underflow interrupt enable */ +#define LCD_INTMSK_LNBUIM (1 << 2) /* Bit 2: LCD next base address interrupt enable */ +#define LCD_INTMSK_VCOMPIM (1 << 3) /* Bit 3: Vertical compare interrupt enable */ +#define LCD_INTMSK_BERIM (1 << 4) /* Bit 4: AHB Master error interrupt enable */ + /* Bits 5-31: Reserved */ +#define LCD_INTMSK_ALL (0x1e) + +/* LCD_INTRAW - Raw Interrupt Status Register */ + /* Bits 0: Reserved */ +#define LCD_INTRAW_FUFRIS (1 << 1) /* Bit 1: FIFO Undeflow raw interrupt status */ +#define LCD_INTRAW_LNBURIS (1 << 2) /* Bit 2: LCD Next address base update intterupt */ +#define LCD_INTRAW_VCOMPRIS (1 << 3) /* Bit 3: Vertical compare interrupt status */ +#define LCD_INTRAW_BERRAW (1 << 4) /* Bit 4: AHB Master bus error interrupt status */ + /* Bits 5-31: Reserved */ +#define LCD_INTRAW_ALL (0x1e) + +/* LCD_INTSTAT - Masked Interrupt Status Register */ + /* Bits 0: Reserved */ +#define LCD_INTSTAT_FUFMIS (1 << 1) /* Bit 1: FIFO Undeflow raw interrupt status */ +#define LCD_INTSTAT_LNBUMIS (1 << 2) /* Bit 2: LCD Next address base update intterupt */ +#define LCD_INTSTAT_VCOMPMIS (1 << 3) /* Bit 3: Vertical compare interrupt status */ +#define LCD_INTSTAT_BERMIS (1 << 4) /* Bit 4: AHB Master bus error interrupt status */ + /* Bits 15-31: Reserved */ +#define LCD_INTSTAT_ALL (0x1e) + +/* LCD_INTCLR - Interrupt Clear Register */ + /* Bits 0: Reserved */ +#define LCD_INTCLR_FUFIC (1 << 1) /* Bit 1: FIFO Undeflow raw interrupt clear */ +#define LCD_INTCLR_LNBUIC (1 << 2) /* Bit 2: LCD Next address base update intterupt */ +#define LCD_INTCLR_VCOMPIC (1 << 3) /* Bit 3: Vertical compare interrupt clear */ +#define LCD_INTCLR_BERIC (1 << 4) /* Bit 4: AHB Master bus error interrupt clear */ + /* Bits 15-31: Reserved */ +#define LCD_INTCLR_ALL (0x1e) + +/* Upper and Lower Panel Address register has no bitfields */ +/* + * Upper Panel Current Address register (LCDUPCURR) + * Lower Panel Current Address register (LCDLPCURR) + */ + +/* LCD_PAL - Color Palette Registers */ + +#define LCD_PAL_R0_SHIFT (0) /* Bits 0-4: Red palette data */ +#define LCD_PAL_R0_MASK (0x1f << LCD_PAL_R0_SHIFT) +#define LCD_PAL_G0_SHIFT (5) /* Bits 5-9: Green palette data */ +#define LCD_PAL_G0_MASK (0x1f << LCD_PAL_G0_SHIFT) +#define LCD_PAL_B0_SHIFT (10) /* Bits 10-14: Blue paletted data */ +#define LCD_PAL_B0_MASK (0x1f << LCD_PAL_B0_SHIFT) +#define LCD_PAL_I0 (1 << 15) /* Bit 15: Intensity/Unused bit */ +#define LCD_PAL_R1_SHIFT (16) /* Bits 16-20: Red palette data */ +#define LCD_PAL_R1_MASK (0x1f << LCD_PAL_R1_SHIFT) +#define LCD_PAL_G1_SHIFT (21) /* Bits 21-25: Green palette data */ +#define LCD_PAL_G1_MASK (0x1f << LCD_PAL_G1_SHIFT) +#define LCD_PAL_B1_SHIFT (26) /* Bits 26-30: Blue palette data */ +#define LCD_PAL_B1_MASK (0x1f << LCD_PAL_B1_SHIFT) +#define LCD_PAL_I1 (1 << 31) /* Bit 31: Intensity/Unused bit */ + +/* LCD_CRSR_IMG - Cursor Image Register - has no bitfields */ +/* The 256 words of the cursor image register defines the appearance + * of either one 64x64 cursor, or 4 32x32 cursors. + */ + +/* LCD CRSR_CTRL - Cursor Control Register */ + +#define LCD_CRSR_CTRL_CRSON (1 << 0) /* Bit 0: Cursor enable */ + /* Bits 1-3: Reserved */ +#define LCD_CRSR_CTRL_CRSRNUM_SHIFT (4) /* Bits 4-5: Cursor image number */ +#define LCD_CRSR_CTRL_CRSRNUM_MASK (3 << LCD_CRSR_CTRL_CRSRNUM1_0_SHIFT) + /* Bits 6-31: Reserved */ +/* If the selected cursor is 32x32 */ + +#define LCD_CURSOR0 (0) +#define LCD_CURSOR1 (1) +#define LCD_CURSOR2 (2) +#define LCD_CURSOR3 (3) + +/* LCD CRSR_CFG - Cursor Configuration Register */ + +#define LCD_CRSR_CFG_CRSRSIZE (1 << 0) /* Bit 0: Cursor size selection */ +#define LCD_CRSR_CFG_FRAMESYNC (1 << 1) /* Bit 1: Cursor frame sync type */ + /* Bits 2-31: Reserved */ + +#define LCD_CURSOR_SIZE32 (0) /* 32x32 */ +#define LCD_CURSOR_SIZE64 (1) /* 64x64 */ +#define LCD_CURSOR_FRAMEASYNC (0) /* Cursor coordinates are asynchronous */ +#define LCD_CURSOR_FRAMESYNC (1) /* coordinates are synchronize to framesync pulse */ + +/* LCD CRSR_PAL0/1 - Cursor Palette Registers */ + +#define LCD_CRSR_PAL_RED_SHIFT (0) /* Bits 0-7: Red color componnent */ +#define LCD_CRSR_PAL_RED_MASK (0xff << LCD_CRSR_PAL0_RED_SHIFT) +#define LCD_CRSR_PAL_GREEN_SHIFT (8) /* Bits 8-15: Green color component */ +#define LCD_CRSR_PAL_GREEN_MASK (0xff << LCD_CRSR_PAL0_GREEN_SHIFT) +#define LCD_CRSR_PAL_BLUE_SHIFT (16) /* Bits 16-23: Blue color component */ +#define LCD_CRSR_PAL_BLUE_MASK (0xff << LCD_CRSR_PAL0_BLUE_SHIFT) + /* Bits 24-31: Reserved */ +/* LCD CRSR_XY - Cursor XY Position Register */ + +#define LCD_CRSR_CRSRX_SHIFT (0) /* Bits 0-9: X ordinate */ +#define LCD_CRSR_CRSRX_MASK (0x3ff << LCD_CRSR_CRSRX_SHIFT) + /* Bits 10-15: Reserved */ +#define LCD_CRSR_CRSRY_SHIFT (16) /* Bits 16-25: Y ordinate */ +#define LCD_CRSR_CRSRY_MASK (0x3ff << LCD_CRSR_CRSRY_SHIFT) + /* Bits 26-31: Reserved */ +/* LCD CRSR_CLIP - Cursor Clip Position Register */ + +#define LCD_CRSR_CRSRCLIPX_SHIFT (0) /* Bits 0-5: X clip position */ +#define LCD_CRSR_CRSRCLIPX_MASK (0x3f << LCD_CRSR_CRSRCLIPX_SHIFT) + /* Bits 6-7: Reserved */ +#define LCD_CRSR_CRSRCLIPY_SHIFT (8) /* Bits 8-13: Reserved */ +#define LCD_CRSR_CRSRCLIPY_MASK (0x3f << LCD_CRSR_CRSRCLIPY_SHIFT) + /* Bits 14-31: Reserved */ +/* LCD CRSR_INTMSK - Cursor Interrrupt Mask Register */ + +#define LCD_CRSR_INTMSK_CRSRIM (1 << 0) /* Bit 0: Cursor interrupt mask */ + /* Bits 1-31: Reserved */ +/* LCD CRSR_INTCLR - Cursor Interrrupt Clear Register */ + +#define LCD_CRSR_INTCLR_CRSRIC (1 << 0) /* Bit 0: Cursor interrupt clear */ + /* Bits 1-31: Reserved */ + +/* LCD CRSR_INTRAW - Cursor Raw Interrrupt Status Register */ + +#define LCD_CRSR_INTRAW_CRSRRIS (1 << 0) /* Bit 0: Cursor raw interrupt status */ + /* Bits 1-31: Reserved */ +/* LCD CRSR_INTSTAT - Mask Interrrupt Status Register */ + +#define LCD_CRSR_INTSTAT_CRSRMIS (1 << 0) /* Bit 0: Cursor mask interrupt status */ + /* Bits 1-31: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_LCD_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_mcpwm.h b/arch/arm/src/lpc17xx/chip/lpc17_mcpwm.h new file mode 100644 index 0000000000000000000000000000000000000000..16a21a162c00225d973cd8aaee74ff4c81bef50e --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_mcpwm.h @@ -0,0 +1,280 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_mcpwm.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MCPWM_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MCPWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_MCPWM_CON_OFFSET 0x0000 /* PWM Control read address */ +#define LPC17_MCPWM_CONSET_OFFSET 0x0004 /* PWM Control set address */ +#define LPC17_MCPWM_CONCLR_OFFSET 0x0008 /* PWM Control clear address */ +#define LPC17_MCPWM_CAPCON_OFFSET 0x000c /* Capture Control read address */ +#define LPC17_MCPWM_CAPCONSET_OFFSET 0x0010 /* Capture Control set address */ +#define LPC17_MCPWM_CAPCONCLR_OFFSET 0x0014 /* Event Control clear address */ +#define LPC17_MCPWM_TC0_OFFSET 0x0018 /* Timer Counter register, channel 0 */ +#define LPC17_MCPWM_TC1_OFFSET 0x001c /* Timer Counter register, channel 1 */ +#define LPC17_MCPWM_TC2_OFFSET 0x0020 /* Timer Counter register, channel 2 */ +#define LPC17_MCPWM_LIM0_OFFSET 0x0024 /* Limit register, channel 0 */ +#define LPC17_MCPWM_LIM1_OFFSET 0x0028 /* Limit register, channel 1 */ +#define LPC17_MCPWM_LIM2_OFFSET 0x002c /* Limit register, channel 2 */ +#define LPC17_MCPWM_MAT0_OFFSET 0x0030 /* Match register, channel 0 */ +#define LPC17_MCPWM_MAT1_OFFSET 0x0034 /* Match register, channel 1 */ +#define LPC17_MCPWM_MAT2_OFFSET 0x0038 /* Match register, channel 2 */ +#define LPC17_MCPWM_DT_OFFSET 0x003c /* Dead time register */ +#define LPC17_MCPWM_CP_OFFSET 0x0040 /* Commutation Pattern register */ +#define LPC17_MCPWM_CAP0_OFFSET 0x0044 /* Capture register, channel 0 */ +#define LPC17_MCPWM_CAP1_OFFSET 0x0048 /* Capture register, channel 1 */ +#define LPC17_MCPWM_CAP2_OFFSET 0x004c /* Capture register, channel 2 */ +#define LPC17_MCPWM_INTEN_OFFSET 0x0050 /* Interrupt Enable read address */ +#define LPC17_MCPWM_INTENSET_OFFSET 0x0054 /* Interrupt Enable set address */ +#define LPC17_MCPWM_INTENCLR_OFFSET 0x0058 /* Interrupt Enable clear address */ +#define LPC17_MCPWM_CNTCON_OFFSET 0x005c /* Count Control read address */ +#define LPC17_MCPWM_CNTCONSET_OFFSET 0x0060 /* Count Control set address */ +#define LPC17_MCPWM_CNTCONCLR_OFFSET 0x0064 /* Count Control clear address */ +#define LPC17_MCPWM_INTF_OFFSET 0x0068 /* Interrupt flags read address */ +#define LPC17_MCPWM_INTFSET_OFFSET 0x006c /* Interrupt flags set address */ +#define LPC17_MCPWM_INTFCLR_OFFSET 0x0070 /* Interrupt flags clear address */ +#define LPC17_MCPWM_CAPCLR_OFFSET 0x0074 /* Capture clear address */ + +/* Register addresses ***************************************************************/ + +#define LPC17_MCPWM_CON (LPC17_MCPWM_BASE+LPC17_MCPWM_CON_OFFSET) +#define LPC17_MCPWM_CONSET (LPC17_MCPWM_BASE+LPC17_MCPWM_CONSET_OFFSET) +#define LPC17_MCPWM_CONCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_CONCLR_OFFSET) +#define LPC17_MCPWM_CAPCON (LPC17_MCPWM_BASE+LPC17_MCPWM_CAPCON_OFFSET) +#define LPC17_MCPWM_CAPCONSET (LPC17_MCPWM_BASE+LPC17_MCPWM_CAPCONSET_OFFSET) +#define LPC17_MCPWM_CAPCONCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_CAPCONCLR_OFFSET) +#define LPC17_MCPWM_TC0 (LPC17_MCPWM_BASE+LPC17_MCPWM_TC0_OFFSET) +#define LPC17_MCPWM_TC1 (LPC17_MCPWM_BASE+LPC17_MCPWM_TC1_OFFSET) +#define LPC17_MCPWM_TC2 (LPC17_MCPWM_BASE+LPC17_MCPWM_TC2_OFFSET) +#define LPC17_MCPWM_LIM0 (LPC17_MCPWM_BASE+LPC17_MCPWM_LIM0_OFFSET) +#define LPC17_MCPWM_LIM1 (LPC17_MCPWM_BASE+LPC17_MCPWM_LIM1_OFFSET) +#define LPC17_MCPWM_LIM2 (LPC17_MCPWM_BASE+LPC17_MCPWM_LIM2_OFFSET) +#define LPC17_MCPWM_MAT0 (LPC17_MCPWM_BASE+LPC17_MCPWM_MAT0_OFFSET) +#define LPC17_MCPWM_MAT1 (LPC17_MCPWM_BASE+LPC17_MCPWM_MAT1_OFFSET) +#define LPC17_MCPWM_MAT2 (LPC17_MCPWM_BASE+LPC17_MCPWM_MAT2_OFFSET) +#define LPC17_MCPWM_DT (LPC17_MCPWM_BASE+LPC17_MCPWM_DT_OFFSET) +#define LPC17_MCPWM_CP (LPC17_MCPWM_BASE+LPC17_MCPWM_CP_OFFSET) +#define LPC17_MCPWM_CAP0 (LPC17_MCPWM_BASE+LPC17_MCPWM_CAP0_OFFSET) +#define LPC17_MCPWM_CAP1 (LPC17_MCPWM_BASE+LPC17_MCPWM_CAP1_OFFSET) +#define LPC17_MCPWM_CAP2 (LPC17_MCPWM_BASE+LPC17_MCPWM_CAP2_OFFSET) +#define LPC17_MCPWM_INTEN (LPC17_MCPWM_BASE+LPC17_MCPWM_INTEN_OFFSET) +#define LPC17_MCPWM_INTENSET (LPC17_MCPWM_BASE+LPC17_MCPWM_INTENSET_OFFSET) +#define LPC17_MCPWM_INTENCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_INTENCLR_OFFSET) +#define LPC17_MCPWM_CNTCON (LPC17_MCPWM_BASE+LPC17_MCPWM_CNTCON_OFFSET) +#define LPC17_MCPWM_CNTCONSET (LPC17_MCPWM_BASE+LPC17_MCPWM_CNTCONSET_OFFSET) +#define LPC17_MCPWM_CNTCONCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_CNTCONCLR_OFFSET) +#define LPC17_MCPWM_INTF (LPC17_MCPWM_BASE+LPC17_MCPWM_INTF_OFFSET) +#define LPC17_MCPWM_INTFSET (LPC17_MCPWM_BASE+LPC17_MCPWM_INTFSET_OFFSET) +#define LPC17_MCPWM_INTFCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_INTFCLR_OFFSET) +#define LPC17_MCPWM_CAPCLR (LPC17_MCPWM_BASE+LPC17_MCPWM_CAPCLR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* There are no bit field definitions for the following registers because they support + * 32-bit values: + * + * - Timer Counter register, channel 0 (TC0), Timer Counter register, channel 1 (TC1), + * and Timer Counter register, channel 2 (TC2): 32-bit Timer/Counter values for + * channels 0, 1, 2 (no bit field definitions) + * + * - Limit register, channel 0 (LIM0), Limit register, channel 1 (LIM1), and Limit + * register, channel 2 (LIM2): 32-bit Limit values for TC0, 1, 2 (no bit field + * definitions) + * + * - Match register, channel 0 MAT0), Match register, channel 1 (MAT1), and Match + * register, channel 2 (MAT2): 32-bit Match values for TC0, 1, 2 (no bit field + * definitions). + * + * - Capture register, channel 0 (CAP0), Capture register, channel 1 (CAP1), and + * Capture register, channel 2 (CAP2): 32-bit TC value at a capture event for + * channels 0, 1, 2 (no bit field definitions) + */ + +/* PWM Control read address (CON), PWM Control set address (CONSET), and PWM Control + * clear address (CONCLR) common regiser bit definitions. + */ + +#define MCPWM_CON_RUN0 (1 << 0) /* Bit 0: Stops/starts timer channel 0 */ +#define MCPWM_CON_CENTER0 (1 << 1) /* Bit 1: Chan 0 edge/center aligned operation */ +#define MCPWM_CON_POLA0 (1 << 2) /* Bit 2: Polarity of MCOA0 and MCOB0 */ +#define MCPWM_CON_DTE0 (1 << 3) /* Bit 3: Dead time feature control */ +#define MCPWM_CON_DISUP0 (1 << 4) /* Bit 4: Enable/disable register updates */ + /* Bits 5-7: Reserved */ +#define MCPWM_CON_RUN1 (1 << 8) /* Bit 8: Stops/starts timer channel 1 */ +#define MCPWM_CON_CENTER1 (1 << 9) /* Bit 9: Chan 1 edge/center aligned operation */ +#define MCPWM_CON_POLA1 (1 << 10) /* Bit 10: Polarity of MCOA1 and MCOB1 */ +#define MCPWM_CON_DTE1 (1 << 11) /* Bit 11: Dead time feature control */ +#define MCPWM_CON_DISUP1 (1 << 12) /* Bit 12: Enable/disable register updates */ + /* Bits 13-15: Reserved */ +#define MCPWM_CON_RUN2 (1 << 16) /* Bit 16: Stops/starts timer channel 2 */ +#define MCPWM_CON_CENTER2 (1 << 17) /* Bit 17: Chan 2 edge/center aligned operation */ +#define MCPWM_CON_POLA2 (1 << 18) /* Bit 18: Polarity of MCOA1 and MCOB1 */ +#define MCPWM_CON_DTE2 (1 << 19) /* Bit 19: Dead time feature control */ +#define MCPWM_CON_DISUP2 (1 << 20) /* Bit 20: Enable/disable register updates */ + /* Bits 21-28: Reserved */ +#define MCPWM_CON_INVBDC (1 << 29) /* Bit 29: Polarity of MCOB outputs (all channels) */ +#define MCPWM_CON_ACMODE (1 << 30) /* Bit 30: 3-phase AC mode select */ +#define MCPWM_CON_DCMODE (1 << 31) /* Bit 31: 3-phase DC mode select */ + +/* Capture Control read address (CAPCON), Capture Control set address (CAPCONSET), + * and Event Control clear address (CAPCONCLR) common register bit defintions + */ + +#define MCPWM_CAPCON_CAP0MCI0RE (1 << 0) /* Bit 0: Enable chan0 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP0MCI0FE (1 << 1) /* Bit 1: Enable chan 0 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP0MCI1RE (1 << 2) /* Bit 2: Enable chan 0 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP0MCI1FE (1 << 3) /* Bit 3: Enable chan 0 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP0MCI2RE (1 << 4) /* Bit 4: Enable chan 0 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP0MCI2FE (1 << 5) /* Bit 5: Enable chan 0 falling edge capture MCI2 */ +#define MCPWM_CAPCON_CAP1MCI0RE (1 << 6) /* Bit 6: Enable chan 1 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP1MCI0FE (1 << 7) /* Bit 7: Enable chan 1 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP1MCI1RE (1 << 8) /* Bit 8: Enable chan 1 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP1MCI1FE (1 << 9) /* Bit 9: Enable chan 1 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP1MCI2RE (1 << 10) /* Bit 10: Enable chan 1 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP1MCI2FE (1 << 11) /* Bit 11: Enable chan 1 falling edge capture MCI2 */ +#define MCPWM_CAPCON_CAP2MCI0RE (1 << 12) /* Bit 12: Enable chan 2 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP2MCI0FE (1 << 13) /* Bit 13: Enable chan 2 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP2MCI1RE (1 << 14) /* Bit 14: Enable chan 2 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP2MCI1FE (1 << 15) /* Bit 15: Enable chan 2 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP2MCI2RE (1 << 16) /* Bit 16: Enable chan 2 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP2MCI2FE (1 << 17) /* Bit 17: Enable chan 2 falling edge capture MCI2 */ +#define MCPWM_CAPCON_RT0 (1 << 18) /* Bit 18: TC0 reset by chan 0 capture event */ +#define MCPWM_CAPCON_RT1 (1 << 19) /* Bit 19: TC1 reset by chan 1 capture event */ +#define MCPWM_CAPCON_RT2 (1 << 20) /* Bit 20: TC2 reset by chan 2 capture event */ +#define MCPWM_CAPCON_HNFCAP0 (1 << 21) /* Bit 21: Hardware noise filter */ +#define MCPWM_CAPCON_HNFCAP1 (1 << 22) /* Bit 22: Hardware noise filter */ +#define MCPWM_CAPCON_HNFCAP2 (1 << 23) /* Bit 23: Hardware noise filter */ + /* Bits 24-31: Reserved */ +/* Dead time register */ + +#define MCPWM_DT_DT0_SHIFT (0) /* Bits 0-9: Dead time for channel 0 */ +#define MCPWM_DT_DT0_MASK (0x03ff << MCPWM_DT_DT0_SHIFT) +#define MCPWM_DT_DT1_SHIFT (10) /* Bits 10-19: Dead time for channel 1 */ +#define MCPWM_DT_DT1_MASK (0x03ff << MCPWM_DT_DT1_SHIFT) +#define MCPWM_DT_DT2_SHIFT (20) /* Bits 20-29: Dead time for channel 2 */ +#define MCPWM_DT_DT2_MASK (0x03ff << MCPWM_DT_DT2_SHIFT) + /* Bits 30-31: reserved */ +/* Commutation Pattern register */ + +#define MCPWM_CP_CCPA0 (1 << 0) /* Bit 0: Iinternal MCOA0 */ +#define MCPWM_CP_CCPB0 (1 << 1) /* Bit 1: MCOB0 tracks internal MCOA0 */ +#define MCPWM_CP_CCPA1 (1 << 2) /* Bit 2: MCOA1 tracks internal MCOA0 */ +#define MCPWM_CP_CCPB1 (1 << 3) /* Bit 3: MCOB1 tracks internal MCOA0 */ +#define MCPWM_CP_CCPA2 (1 << 4) /* Bit 4: MCOA2 tracks internal MCOA0 */ +#define MCPWM_CP_CCPB2 (1 << 5) /* Bit 5: MCOB2 tracks internal MCOA0 */ + /* Bits 6-31: reserved */ + +/* Interrupt Enable read address (INTEN), Interrupt Enable set address (INTENSET), + * Interrupt Enable clear address (INTENCLR), Interrupt flags read address (INTF), + * Interrupt flags set address (INTFSET), and Interrupt flags clear address (INTFCLR) + * common bit field definitions + */ + +#define MCPWM_INT_ILIM0 (1 << 0) /* Bit 0: Limit interrupts for channel 0 */ +#define MCPWM_INT_IMAT0 (1 << 1) /* Bit 1: Match interrupts for channel 0 */ +#define MCPWM_INT_ICAP0 (1 << 2) /* Bit 2: Capture interrupts for channel 0 */ + /* Bit 3: Reserved */ +#define MCPWM_INT_ILIM1 (1 << 4) /* Bit 4: Limit interrupts for channel 1 */ +#define MCPWM_INT_IMAT1 (1 << 5) /* Bit 5: Match interrupts for channel 1 */ +#define MCPWM_INT_ICAP1 (1 << 6) /* Bit 6: Capture interrupts for channel 1 */ + /* Bit 7: Reserved */ +#define MCPWM_INT_ILIM2 (1 << 8) /* Bit 8: Limit interrupts for channel 2 */ +#define MCPWM_INT_IMAT2 (1 << 9) /* Bit 9: Match interrupts for channel 2 */ +#define MCPWM_INT_ICAP2 (1 << 10) /* Bit 10: Capture interrupts for channel 2 */ + /* Bits 11-14: Reserved */ +#define MCPWM_INT_ABORT (1 << 15) /* Bit 15: Fast abort interrupt */ + /* Bits 16-31: Reserved */ + +/* Count Control read address (CNTCON), Count Control set address (CNTCONSET), and + * Count Control clear address (CNTCONCLR) common register bit definitions. + */ + +#define MCPWM_CNTCON_TC0MCI0RE (1 << 0) /* Bit 0: Counter 0 incr on rising edge MCI0 */ +#define MCPWM_CNTCON_TC0MCI0FE (1 << 1) /* Bit 1: Counter 0 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC0MCI1RE (1 << 2) /* Bit 2: Counter 0 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC0MCI1FE (1 << 3) /* Bit 3: Counter 0 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC0MCI2RE (1 << 4) /* Bit 4: Counter 0 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC0MCI2FE (1 << 5) /* Bit 5: Counter 0 incr onfalling edge MCI2 */ +#define MCPWM_CNTCON_TC1MCI0RE (1 << 6) /* Bit 6: Counter 1 incr onrising edge MCI0 */ +#define MCPWM_CNTCON_TC1MCI0FE (1 << 7) /* Bit 7: Counter 1 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC1MCI1RE (1 << 8) /* Bit 8: Counter 1 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC1MCI1FE (1 << 9) /* Bit 9: Counter 1 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC1MCI2RE (1 << 10) /* Bit 10: Counter 1 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC1MCI2FE (1 << 11) /* Bit 11: Counter 1 incr onfalling edge MCI2 */ +#define MCPWM_CNTCON_TC2MCI0RE (1 << 12) /* Bit 12: Counter 2 incr onrising edge MCI0 */ +#define MCPWM_CNTCON_TC2MCI0FE (1 << 13) /* Bit 13: Counter 2 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC2MCI1RE (1 << 14) /* Bit 14: Counter 2 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC2MCI1FE (1 << 15) /* Bit 15: Counter 2 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC2MCI2RE (1 << 16) /* Bit 16: Counter 2 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC2MCI2FE (1 << 17) /* Bit 17: Counter 2 incr onfalling edge MCI2 */ + /* Bits 28-28: Reserved */ +#define MCPWM_CNTCON_CNTR0 (1 << 29) /* Bit 29: Channel 0 counter mode */ +#define MCPWM_CNTCON_CNTR1 (1 << 30) /* Bit 30: Channel 1 counter mode */ +#define MCPWM_CNTCON_CNTR2 (1 << 31) /* Bit 31: Channel 2 counter mode */ + +/* Capture clear address */ + +#define MCPWM_CAPCLR_MCCLR0 (1 << 0) /* Bit 0: Clear MCCAP0 register */ +#define MCPWM_CAPCLR_MCCLR1 (1 << 1) /* Bit 1: Clear MCCAP1 register */ +#define MCPWM_CAPCLR_MCCLR2 (1 << 2) /* Bit 2: Clear MCCAP2 register */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MCPWM_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_memorymap.h b/arch/arm/src/lpc17xx/chip/lpc17_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..53214c8a5d900a9feb683be8151f2ef4d9a50104 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_memorymap.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_memorymap.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct memory map definitions + * for the selected LPC17xx family. + */ + +#include + +#if defined(LPC176x) +# include "chip/lpc176x_memorymap.h" +#elif defined(LPC178x) +# include "chip/lpc178x_memorymap.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_pinconfig.h b/arch/arm/src/lpc17xx/chip/lpc17_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..c0090dbc1a401e76d779506155404277d677e5dc --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_pinconfig.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_pinconfig.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct pin configuration + * definitions for the selected LPC17xx family. + */ + +#include + +#if defined(LPC176x) +# include "chip/lpc176x_pinconfig.h" +#elif defined(LPC178x) +# include "chip/lpc178x_pinconfig.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONFIG_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_pinconn.h b/arch/arm/src/lpc17xx/chip/lpc17_pinconn.h new file mode 100644 index 0000000000000000000000000000000000000000..8b6829f9ba6257aca27273d818c42b2f93599ccb --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_pinconn.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_pinconn.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONN_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct pin configuration + * register definitions for the selected LPC17xx family. + */ + +#include + +#if defined(LPC176x) +# include "chip/lpc176x_pinconn.h" +#elif defined(LPC178x) +# include "chip/lpc178x_iocon.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PINCONN_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_pwm.h b/arch/arm/src/lpc17xx/chip/lpc17_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..610215bc0269cb962e2e9a9de6c88e76f92697b4 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_pwm.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_pwm.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PWM_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_PWM_IR_OFFSET 0x0000 /* Interrupt Register */ +#define LPC17_PWM_TCR_OFFSET 0x0004 /* Timer Control Register */ +#define LPC17_PWM_TC_OFFSET 0x0008 /* Timer Counter */ +#define LPC17_PWM_PR_OFFSET 0x000c /* Prescale Register */ +#define LPC17_PWM_PC_OFFSET 0x0010 /* Prescale Counter */ +#define LPC17_PWM_MCR_OFFSET 0x0014 /* Match Control Register */ +#define LPC17_PWM_MR0_OFFSET 0x0018 /* Match Register 0 */ +#define LPC17_PWM_MR1_OFFSET 0x001c /* Match Register 1 */ +#define LPC17_PWM_MR2_OFFSET 0x0020 /* Match Register 2 */ +#define LPC17_PWM_MR3_OFFSET 0x0024 /* Match Register 3 */ +#define LPC17_PWM_CCR_OFFSET 0x0028 /* Capture Control Register */ +#define LPC17_PWM_CR0_OFFSET 0x002c /* Capture Register 0 */ +#define LPC17_PWM_CR1_OFFSET 0x0030 /* Capture Register 1 */ +#define LPC17_PWM_CR2_OFFSET 0x0034 /* Capture Register 2 */ +#define LPC17_PWM_CR3_OFFSET 0x0038 /* Capture Register 3 */ +#define LPC17_PWM_MR4_OFFSET 0x0040 /* Match Register 4 */ +#define LPC17_PWM_MR5_OFFSET 0x0044 /* Match Register 5 */ +#define LPC17_PWM_MR6_OFFSET 0x0048 /* Match Register 6 */ +#define LPC17_PWM_PCR_OFFSET 0x004c /* PWM Control Register */ +#define LPC17_PWM_LER_OFFSET 0x0050 /* Load Enable Register */ +#define LPC17_PWM_CTCR_OFFSET 0x0070 /* Counter/Timer Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_PWM1_IR (LPC17_PWM1_BASE+LPC17_PWM_IR_OFFSET) +#define LPC17_PWM1_TCR (LPC17_PWM1_BASE+LPC17_PWM_TCR_OFFSET) +#define LPC17_PWM1_TC (LPC17_PWM1_BASE+LPC17_PWM_TC_OFFSET) +#define LPC17_PWM1_PR (LPC17_PWM1_BASE+LPC17_PWM_PR_OFFSET) +#define LPC17_PWM1_PC (LPC17_PWM1_BASE+LPC17_PWM_PC_OFFSET) +#define LPC17_PWM1_MCR (LPC17_PWM1_BASE+LPC17_PWM_MCR_OFFSET) +#define LPC17_PWM1_MR0 (LPC17_PWM1_BASE+LPC17_PWM_MR0_OFFSET) +#define LPC17_PWM1_MR1 (LPC17_PWM1_BASE+LPC17_PWM_MR1_OFFSET) +#define LPC17_PWM1_MR2 (LPC17_PWM1_BASE+LPC17_PWM_MR2_OFFSET) +#define LPC17_PWM1_MR3 (LPC17_PWM1_BASE+LPC17_PWM_MR3_OFFSET) +#define LPC17_PWM1_MR4 (LPC17_PWM1_BASE+LPC17_PWM_MR4_OFFSET) +#define LPC17_PWM1_MR5 (LPC17_PWM1_BASE+LPC17_PWM_MR5_OFFSET) +#define LPC17_PWM1_MR6 (LPC17_PWM1_BASE+LPC17_PWM_MR6_OFFSET) +#define LPC17_PWM1_CCR (LPC17_PWM1_BASE+LPC17_PWM_CCR_OFFSET) +#define LPC17_PWM1_CR0 (LPC17_PWM1_BASE+LPC17_PWM_CR0_OFFSET) +#define LPC17_PWM1_CR1 (LPC17_PWM1_BASE+LPC17_PWM_CR1_OFFSET) +#define LPC17_PWM1_CR2 (LPC17_PWM1_BASE+LPC17_PWM_CR2_OFFSET) +#define LPC17_PWM1_CR3 (LPC17_PWM1_BASE+LPC17_PWM_CR3_OFFSET) +#define LPC17_PWM1_PCR (LPC17_PWM1_BASE+LPC17_PWM_PCR_OFFSET) +#define LPC17_PWM1_LER (LPC17_PWM1_BASE+LPC17_PWM_LER_OFFSET) +#define LPC17_PWM1_CTCR (LPC17_PWM1_BASE+LPC17_PWM_CTCR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Registers holding 32-bit numeric values (no bit field definitions): + * + * Timer Counter (TC) + * Prescale Register (PR) + * Prescale Counter (PC) + * Match Register 0 (MR0) + * Match Register 1 (MR1) + * Match Register 2 (MR2) + * Match Register 3 (MR3) + * Match Register 4 (MR3) + * Match Register 5 (MR3) + * Match Register 6 (MR3) + * Capture Register 0 (CR0) + * Capture Register 1 (CR1) + * Capture Register 1 (CR2) + * Capture Register 1 (CR3) + */ + +/* Interrupt Register */ + +#define PWM_IR_MR0 (1 << 0) /* Bit 0: PWM match channel 0 interrupt */ +#define PWM_IR_MR1 (1 << 1) /* Bit 1: PWM match channel 1 interrupt */ +#define PWM_IR_MR2 (1 << 2) /* Bit 2: PWM match channel 2 interrupt */ +#define PWM_IR_MR3 (1 << 3) /* Bit 3: PWM match channel 3 interrupt */ +#define PWM_IR_CAP0 (1 << 4) /* Bit 4: Capture input 0 interrupt */ +#define PWM_IR_CAP1 (1 << 5) /* Bit 5: Capture input 1 interrupt */ + /* Bits 6-7: Reserved */ +#define PWM_IR_MR4 (1 << 8) /* Bit 8: PWM match channel 4 interrupt */ +#define PWM_IR_MR5 (1 << 9) /* Bit 9: PWM match channel 5 interrupt */ +#define PWM_IR_MR6 (1 << 10) /* Bit 10: PWM match channel 6 interrupt */ + /* Bits 11-31: Reserved */ +/* Timer Control Register */ + +#define PWM_TCR_CNTREN (1 << 0) /* Bit 0: Counter Enable */ +#define PWM_TCR_CNTRRST (1 << 1) /* Bit 1: Counter Reset */ + /* Bit 2: Reserved */ +#define PWM_TCR_PWMEN (1 << 3) /* Bit 3: PWM Enable */ + /* Bits 4-31: Reserved */ +/* Match Control Register */ + +#define PWM_MCR_MR0I (1 << 0) /* Bit 0: Interrupt on MR0 */ +#define PWM_MCR_MR0R (1 << 1) /* Bit 1: Reset on MR0 */ +#define PWM_MCR_MR0S (1 << 2) /* Bit 2: Stop on MR0 */ +#define PWM_MCR_MR1I (1 << 3) /* Bit 3: Interrupt on MR1 */ +#define PWM_MCR_MR1R (1 << 4) /* Bit 4: Reset on MR1 */ +#define PWM_MCR_MR1S (1 << 5) /* Bit 5: Stop on MR1 */ +#define PWM_MCR_MR2I (1 << 6) /* Bit 6: Interrupt on MR2 */ +#define PWM_MCR_MR2R (1 << 7) /* Bit 7: Reset on MR2 */ +#define PWM_MCR_MR2S (1 << 8) /* Bit 8: Stop on MR2 */ +#define PWM_MCR_MR3I (1 << 9) /* Bit 9: Interrupt on MR3 */ +#define PWM_MCR_MR3R (1 << 10) /* Bit 10: Reset on MR3 */ +#define PWM_MCR_MR3S (1 << 11) /* Bit 11: Stop on MR3 */ +#define PWM_MCR_MR4I (1 << 12) /* Bit 12: Interrupt on MR4 */ +#define PWM_MCR_MR4R (1 << 13) /* Bit 13: Reset on MR4 */ +#define PWM_MCR_MR4S (1 << 14) /* Bit 14: Stop on MR4 */ +#define PWM_MCR_MR5I (1 << 15) /* Bit 15: Interrupt on MR5 */ +#define PWM_MCR_MR5R (1 << 16) /* Bit 16: Reset on MR5*/ +#define PWM_MCR_MR5S (1 << 17) /* Bit 17: Stop on MR5 */ +#define PWM_MCR_MR6I (1 << 18) /* Bit 18: Interrupt on MR6 */ +#define PWM_MCR_MR6R (1 << 19) /* Bit 19: Reset on MR6 */ +#define PWM_MCR_MR6S (1 << 20) /* Bit 20: Stop on MR6 */ + /* Bits 21-31: Reserved */ +/* Capture Control Register (Where are CAP2 and 3?) */ + +#define PWM_CCR_CAP0RE (1 << 0) /* Bit 0: Capture on CAPn.0 rising edge */ +#define PWM_CCR_CAP0FE (1 << 1) /* Bit 1: Capture on CAPn.0 falling edg */ +#define PWM_CCR_CAP0I (1 << 2) /* Bit 2: Interrupt on CAPn.0 */ +#define PWM_CCR_CAP1RE (1 << 3) /* Bit 3: Capture on CAPn.1 rising edge */ +#define PWM_CCR_CAP1FE (1 << 4) /* Bit 4: Capture on CAPn.1 falling edg */ +#define PWM_CCR_CAP1I (1 << 5) /* Bit 5: Interrupt on CAPn.1 */ + /* Bits 6-31: Reserved */ +/* PWM Control Register */ + /* Bits 0-1: Reserved */ +#define PWM_PCR_SEL2 (1 << 2) /* Bit 2: PWM2 single edge controlled mode */ +#define PWM_PCR_SEL3 (1 << 3) /* Bit 3: PWM3 single edge controlled mode */ +#define PWM_PCR_SEL4 (1 << 4) /* Bit 4: PWM4 single edge controlled mode */ +#define PWM_PCR_SEL5 (1 << 5) /* Bit 5: PWM5 single edge controlled mode */ +#define PWM_PCR_SEL6 (1 << 6) /* Bit 6: PWM6 single edge controlled mode */ + /* Bits 7-8: Reserved */ +#define PWM_PCR_ENA1 (1 << 9) /* Bit 9: Enable PWM1 output */ +#define PWM_PCR_ENA2 (1 << 10) /* Bit 10: Enable PWM2 output */ +#define PWM_PCR_ENA3 (1 << 11) /* Bit 11: Enable PWM3 output */ +#define PWM_PCR_ENA4 (1 << 12) /* Bit 12: Enable PWM4 output */ +#define PWM_PCR_ENA5 (1 << 13) /* Bit 13: Enable PWM5 output */ +#define PWM_PCR_ENA6 (1 << 14) /* Bit 14: Enable PWM6 output */ + /* Bits 15-31: Reserved */ +/* Load Enable Register */ + +#define PWM_LER_M0EN (1 << 0) /* Bit 0: Enable PWM Match 0 Latch */ +#define PWM_LER_M1EN (1 << 1) /* Bit 1: Enable PWM Match 1 Latch */ +#define PWM_LER_M2EN (1 << 2) /* Bit 2: Enable PWM Match 2 Latch */ +#define PWM_LER_M3EN (1 << 3) /* Bit 3: Enable PWM Match 3 Latch */ +#define PWM_LER_M4EN (1 << 4) /* Bit 4: Enable PWM Match 4 Latch */ +#define PWM_LER_M5EN (1 << 5) /* Bit 5: Enable PWM Match 5 Latch */ +#define PWM_LER_M6EN (1 << 6) /* Bit 6: Enable PWM Match 6 Latch */ + /* Bits 7-31: Reserved */ +/* Counter/Timer Control Register */ + +#define PWM_CTCR_MODE_SHIFT (0) /* Bits 0-1: Counter/Timer Mode */ +#define PWM_CTCR_MODE_MASK (3 << PWM_CTCR_MODE_SHIFT) +# define PWM_CTCR_MODE_TIMER (0 << PWM_CTCR_MODE_SHIFT) /* Timer Mode, prescal match */ +# define PWM_CTCR_MODE_CNTRRE (1 << PWM_CTCR_MODE_SHIFT) /* Counter Mode, CAP rising edge */ +# define PWM_CTCR_MODE_CNTRFE (2 << PWM_CTCR_MODE_SHIFT) /* Counter Mode, CAP falling edge */ +# define PWM_CTCR_MODE_CNTRBE (3 << PWM_CTCR_MODE_SHIFT) /* Counter Mode, CAP both edges */ +#define PWM_CTCR_INPSEL_SHIFT (2) /* Bits 2-3: Count Input Select */ +#define PWM_CTCR_INPSEL_MASK (3 << PWM_CTCR_INPSEL_SHIFT) +# define PWM_CTCR_INPSEL_CAPNp0 (0 << PWM_CTCR_INPSEL_SHIFT) /* CAPn.0 for TIMERn */ +# define PWM_CTCR_INPSEL_CAPNp1 (1 << PWM_CTCR_INPSEL_SHIFT) /* CAPn.0 for TIMERn */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_PWM_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_qei.h b/arch/arm/src/lpc17xx/chip/lpc17_qei.h new file mode 100644 index 0000000000000000000000000000000000000000..af0d69243910da09b3ea95e6feeb3339584b429b --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_qei.h @@ -0,0 +1,214 @@ +/******************************************************************************************** + * arch/arm/src/lpc17xx/chip/lpc17_qei.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_QEI_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_QEI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register offsets *************************************************************************/ +/* Control registers */ + +#define LPC17_QEI_CON_OFFSET 0x0000 /* Control register */ +#define LPC17_QEI_STAT_OFFSET 0x0004 /* Encoder status register */ +#define LPC17_QEI_CONF_OFFSET 0x0008 /* Configuration register */ + +/* Position, index, and timer registers */ + +#define LPC17_QEI_POS_OFFSET 0x000c /* Position register */ +#define LPC17_QEI_MAXPOS_OFFSET 0x0010 /* Maximum position register */ +#define LPC17_QEI_CMPOS0_OFFSET 0x0014 /* Position compare register */ +#define LPC17_QEI_CMPOS1_OFFSET 0x0018 /* Position compare register */ +#define LPC17_QEI_CMPOS2_OFFSET 0x001c /* Position compare register */ +#define LPC17_QEI_INXCNT_OFFSET 0x0020 /* Index count register */ +#define LPC17_QEI_INXCMP_OFFSET 0x0024 /* Index compare register */ +#define LPC17_QEI_LOAD_OFFSET 0x0028 /* Velocity timer reload register */ +#define LPC17_QEI_TIME_OFFSET 0x002c /* Velocity timer register */ +#define LPC17_QEI_VEL_OFFSET 0x0030 /* Velocity counter register */ +#define LPC17_QEI_CAP_OFFSET 0x0034 /* Velocity capture register */ +#define LPC17_QEI_VELCOMP_OFFSET 0x0038 /* Velocity compare register */ +#define LPC17_QEI_FILTER_OFFSET 0x003c /* Digital filter register */ + +#ifdef LPC178 +# define LPC17_QEI_INXCMP0_OFFSET 0x0024 /* Index compare0 register */ +# define LPC17_QEI_INXCMP1_OFFSET 0x004c /* Index compare1 register */ +# define LPC17_QEI_INXCMP2_OFFSET 0x0050 /* Index compare2 register */ +# define LPC17_QEI_FILTER_PHA_OFFSET 0x003c /* Digital filter register */ +# define LPC17_QEI_FILTER_PHB_OFFSET 0x0040 /* Digital filter register */ +# define LPC17_QEI_FILTER_INX_OFFSET 0x0044 /* Digital filter register */ +# define LPC17_QEI_WINDOW_OFFSET 0x0048 /* Index acceptance register */ +#endif + +/* Interrupt registers */ + +#define LPC17_QEI_IEC_OFFSET 0x0fd8 /* Interrupt enable clear register */ +#define LPC17_QEI_IES_OFFSET 0x0fdc /* Interrupt enable set register */ +#define LPC17_QEI_INTSTAT_OFFSET 0x0fe0 /* Interrupt status register */ +#define LPC17_QEI_IE_OFFSET 0x0fe4 /* Interrupt enable register */ +#define LPC17_QEI_CLR_OFFSET 0x0fe8 /* Interrupt status clear register */ +#define LPC17_QEI_SET_OFFSET 0x0fec /* Interrupt status set register */ + +/* Register addresses ***********************************************************************/ +/* Control registers */ + +#define LPC17_QEI_CON (LPC17_QEI_BASE+LPC17_QEI_CON_OFFSET) +#define LPC17_QEI_STAT (LPC17_QEI_BASE+LPC17_QEI_STAT_OFFSET) +#define LPC17_QEI_CONF (LPC17_QEI_BASE+LPC17_QEI_CONF_OFFSET) + +/* Position, index, and timer registers */ + +#define LPC17_QEI_POS (LPC17_QEI_BASE+LPC17_QEI_POS_OFFSET) +#define LPC17_QEI_MAXPOS (LPC17_QEI_BASE+LPC17_QEI_MAXPOS_OFFSET) +#define LPC17_QEI_CMPOS0 (LPC17_QEI_BASE+LPC17_QEI_CMPOS0_OFFSET) +#define LPC17_QEI_CMPOS1 (LPC17_QEI_BASE+LPC17_QEI_CMPOS1_OFFSET) +#define LPC17_QEI_CMPOS2 (LPC17_QEI_BASE+LPC17_QEI_CMPOS2_OFFSET) +#define LPC17_QEI_INXCNT (LPC17_QEI_BASE+LPC17_QEI_INXCNT_OFFSET) +#define LPC17_QEI_INXCMP (LPC17_QEI_BASE+LPC17_QEI_INXCMP_OFFSET) +#define LPC17_QEI_LOAD (LPC17_QEI_BASE+LPC17_QEI_LOAD_OFFSET) +#define LPC17_QEI_TIME (LPC17_QEI_BASE+LPC17_QEI_TIME_OFFSET) +#define LPC17_QEI_VEL (LPC17_QEI_BASE+LPC17_QEI_VEL_OFFSET) +#define LPC17_QEI_CAP (LPC17_QEI_BASE+LPC17_QEI_CAP_OFFSET) +#define LPC17_QEI_VELCOMP (LPC17_QEI_BASE+LPC17_QEI_VELCOMP_OFFSET) +#define LPC17_QEI_FILTER (LPC17_QEI_BASE+LPC17_QEI_FILTER_OFFSET) + +/* Interrupt registers */ + +#define LPC17_QEI_IEC (LPC17_QEI_BASE+LPC17_QEI_IEC_OFFSET) +#define LPC17_QEI_IES (LPC17_QEI_BASE+LPC17_QEI_IES_OFFSET) +#define LPC17_QEI_INTSTAT (LPC17_QEI_BASE+LPC17_QEI_INTSTAT_OFFSET) +#define LPC17_QEI_IE (LPC17_QEI_BASE+LPC17_QEI_IE_OFFSET) +#define LPC17_QEI_CLR (LPC17_QEI_BASE+LPC17_QEI_CLR_OFFSET) +#define LPC17_QEI_SET (LPC17_QEI_BASE+LPC17_QEI_SET_OFFSET) + +/* Register bit definitions *****************************************************************/ +/* The following registers hold 32-bit integer values and have no bit fields defined + * in this section: + * + * Position register (POS) + * Maximum position register (MAXPOS) + * Position compare register 0 (CMPOS0) + * Position compare register 1 (CMPOS) + * Position compare register 2 (CMPOS2) + * Index count register (INXCNT) + * Index compare register (INXCMP) + * Velocity timer reload register (LOAD) + * Velocity timer register (TIME) + * Velocity counter register (VEL) + * Velocity capture register (CAP) + * Velocity compare register (VELCOMP) + * Digital filter register (FILTER) + */ + +/* Control registers */ +/* Control register */ + +#define QEI_CON_RESP (1 << 0) /* Bit 0: Reset position counter */ +#define QEI_CON_RESPI (1 << 1) /* Bit 1: Reset position counter on index */ +#define QEI_CON_RESV (1 << 2) /* Bit 2: Reset velocity */ +#define QEI_CON_RESI (1 << 3) /* Bit 3: Reset index counter */ + /* Bits 4-31: reserved */ +/* Encoder status register */ + +#define QEI_STAT_DIR (1 << 0) /* Bit 0: Direction bit */ + /* Bits 1-31: reserved */ +/* Configuration register */ + +#define QEI_CONF_DIRINV (1 << 0) /* Bit 0: Direction invert */ +#define QEI_CONF_SIGMODE (1 << 1) /* Bit 1: Signal Mode */ +#define QEI_CONF_CAPMODE (1 << 2) /* Bit 2: Capture Mode */ +#define QEI_CONF_INVINX (1 << 3) /* Bit 3: Invert Index */ + +#ifdef LPC178x +# define QEI_CONF_CRESPI (1 << 4) /* Bit 4: Continuous Index reset */ + /* Bits 5-15: reserved */ +# define QEI_CONF_INXGATE_SHIFT (16) /* Bit 16:19 Index Gating */ +# define QEI_CONF_INXGATE_MASK (15 << QEI_CONF_INXGATE_SHIFT) +#endif + /* Bits 20-31: reserved */ + +/* Position, index, and timer registers (all 32-bit integer values with not bit fields */ + +/* Interrupt registers */ +/* Interrupt enable clear register (IEC), Interrupt enable set register (IES), + * Interrupt status register (INTSTAT), Interrupt enable register (IE), Interrupt + * status clear register (CLR), and Interrupt status set register (SET) common + * bit definitions. + */ + +#define QEI_INT_INX (1 << 0) /* Bit 0: Index pulse detected */ +#define QEI_INT_TIM (1 << 1) /* Bit 1: Velocity timer overflow occurred */ +#define QEI_INT_VELC (1 << 2) /* Bit 2: Captured velocity less than compare velocity */ +#define QEI_INT_DIR (1 << 3) /* Bit 3: Change of direction detected */ +#define QEI_INT_ERR (1 << 4) /* Bit 4: Encoder phase error detected */ +#define QEI_INT_ENCLK (1 << 5) /* Bit 5: Eencoder clock pulse detected */ +#define QEI_INT_POS0 (1 << 6) /* Bit 6: Position 0 compare equal to current position */ +#define QEI_INT_POS1 (1 << 7) /* Bit 7: Position 1 compare equal to current position */ +#define QEI_INT_POS2 (1 << 8) /* Bit 8: Position 2 compare equal to current position */ +#define QEI_INT_REV (1 << 9) /* Bit 9: Index compare value equal to current index count */ +#define QEI_INT_POS0REV (1 << 10) /* Bit 10: Combined position 0 and revolution count interrupt */ +#define QEI_INT_POS1REV (1 << 11) /* Bit 11: Position 1 and revolution count interrupt */ +#define QEI_INT_POS2REV (1 << 12) /* Bit 12: Position 2 and revolution count interrupt */ + +#ifdef LPC178x +# define QEI_INT_REV1 (1 << 13) /* Bit 13: Index compare1 value to current index interrupt */ +# define QEI_INT_REV2 (1 << 14) /* Bit 14: Index compare2 value to current index interrupt */ +# define QEI_INT_MAXPOS (1 << 15) /* Bit 15: Current position count interrupt */ +#endif + /* Bits 16-31: reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_QEI_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_rit.h b/arch/arm/src/lpc17xx/chip/lpc17_rit.h new file mode 100644 index 0000000000000000000000000000000000000000..00029f8fe7fd6eaa0f60fbbe0f392849342f6e6b --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_rit.h @@ -0,0 +1,92 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_rit.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RIT_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_RIT_COMPVAL_OFFSET 0x0000 /* Compare register */ +#define LPC17_RIT_MASK_OFFSET 0x0004 /* Mask register */ +#define LPC17_RIT_CTRL_OFFSET 0x0008 /* Control register */ +#define LPC17_RIT_COUNTER_OFFSET 0x000c /* 32-bit counter */ + +/* Register addresses ***************************************************************/ + +#define LPC17_RIT_COMPVAL (LPC17_RIT_BASE+LPC17_RIT_COMPVAL_OFFSET) +#define LPC17_RIT_MASK (LPC17_RIT_BASE+LPC17_RIT_MASK_OFFSET) +#define LPC17_RIT_CTRL (LPC17_RIT_BASE+LPC17_RIT_CTRL_OFFSET) +#define LPC17_RIT_COUNTER (LPC17_RIT_BASE+LPC17_RIT_COUNTER_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Compare register (Bits 0-31: value compared to the counter) */ + +/* Mask register (Bits 0-31: 32-bit mask value) */ + +/* Control register */ + +#define RIT_CTRL_INT (1 << 0) /* Bit 0: Interrupt flag */ +#define RIT_CTRL_ENCLR (1 << 1) /* Bit 1: Timer enable clear */ +#define RIT_CTRL_ENBR (1 << 2) /* Bit 2: Timer enable for debug */ +#define RIT_CTRL_EN (1 << 3) /* Bit 3: Timer enable */ + /* Bits 4-31: Reserved */ +/* 32-bit counter (Bits 0-31: 32-bit up counter) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RIT_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_rtc.h b/arch/arm/src/lpc17xx/chip/lpc17_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..56144c6cf261e6543c9bf20d80f6187cece617b8 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_rtc.h @@ -0,0 +1,277 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_rtc.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTC_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* Miscellaneous registers */ + +#define LPC17_RTC_ILR_OFFSET 0x0000 /* Interrupt Location Register */ +#define LPC17_RTC_CCR_OFFSET 0x0008 /* Clock Control Register */ +#define LPC17_RTC_CIIR_OFFSET 0x000c /* Counter Increment Interrupt Register */ +#define LPC17_RTC_AMR_OFFSET 0x0010 /* Alarm Mask Register */ +#define LPC17_RTC_AUXEN_OFFSET 0x0058 /* RTC Auxiliary Enable register */ +#define LPC17_RTC_AUX_OFFSET 0x005c /* RTC Auxiliary control register */ + +/* Consolidated time registers */ + +#define LPC17_RTC_CTIME0_OFFSET 0x0014 /* Consolidated Time Register 0 */ +#define LPC17_RTC_CTIME1_OFFSET 0x0018 /* Consolidated Time Register 1 */ +#define LPC17_RTC_CTIME2_OFFSET 0x001c /* Consolidated Time Register 2 */ + +/* Time counter registers */ + +#define LPC17_RTC_SEC_OFFSET 0x0020 /* Seconds Counter */ +#define LPC17_RTC_MIN_OFFSET 0x0024 /* Minutes Register */ +#define LPC17_RTC_HOUR_OFFSET 0x0028 /* Hours Register */ +#define LPC17_RTC_DOM_OFFSET 0x002c /* Day of Month Register */ +#define LPC17_RTC_DOW_OFFSET 0x0030 /* Day of Week Register */ +#define LPC17_RTC_DOY_OFFSET 0x0034 /* Day of Year Register */ +#define LPC17_RTC_MONTH_OFFSET 0x0038 /* Months Register */ +#define LPC17_RTC_YEAR_OFFSET 0x003c /* Years Register */ +#define LPC17_RTC_CALIB_OFFSET 0x0040 /* Calibration Value Register */ + +/* General purpose registers */ + +#define LPC17_RTC_GPREG0_OFFSET 0x0044 /* General Purpose Register 0 */ +#define LPC17_RTC_GPREG1_OFFSET 0x0048 /* General Purpose Register 1 */ +#define LPC17_RTC_GPREG2_OFFSET 0x004c /* General Purpose Register 2 */ +#define LPC17_RTC_GPREG3_OFFSET 0x0050 /* General Purpose Register 3 */ +#define LPC17_RTC_GPREG4_OFFSET 0x0054 /* General Purpose Register 4 */ + +/* Alarm register group */ + +#define LPC17_RTC_ALSEC_OFFSET 0x0060 /* Alarm value for Seconds */ +#define LPC17_RTC_ALMIN_OFFSET 0x0064 /* Alarm value for Minutes */ +#define LPC17_RTC_ALHOUR_OFFSET 0x0068 /* Alarm value for Hours */ +#define LPC17_RTC_ALDOM_OFFSET 0x006c /* Alarm value for Day of Month */ +#define LPC17_RTC_ALDOW_OFFSET 0x0070 /* Alarm value for Day of Week */ +#define LPC17_RTC_ALDOY_OFFSET 0x0074 /* Alarm value for Day of Year */ +#define LPC17_RTC_ALMON_OFFSET 0x0078 /* Alarm value for Months */ +#define LPC17_RTC_ALYEAR_OFFSET 0x007c /* Alarm value for Year */ + +/* Register addresses ***************************************************************/ +/* Miscellaneous registers */ + +#define LPC17_RTC_ILR (LPC17_RTC_BASE+LPC17_RTC_ILR_OFFSET) +#define LPC17_RTC_CCR (LPC17_RTC_BASE+LPC17_RTC_CCR_OFFSET) +#define LPC17_RTC_CIIR (LPC17_RTC_BASE+LPC17_RTC_CIIR_OFFSET) +#define LPC17_RTC_AMR (LPC17_RTC_BASE+LPC17_RTC_AMR_OFFSET) +#define LPC17_RTC_AUXEN (LPC17_RTC_BASE+LPC17_RTC_AUXEN_OFFSET) +#define LPC17_RTC_AUX (LPC17_RTC_BASE+LPC17_RTC_AUX_OFFSET) + +/* Consolidated time registers */ + +#define LPC17_RTC_CTIME0 (LPC17_RTC_BASE+LPC17_RTC_CTIME0_OFFSET) +#define LPC17_RTC_CTIME1 (LPC17_RTC_BASE+LPC17_RTC_CTIME1_OFFSET) +#define LPC17_RTC_CTIME2 (LPC17_RTC_BASE+LPC17_RTC_CTIME2_OFFSET) + +/* Time counter registers */ + +#define LPC17_RTC_SEC (LPC17_RTC_BASE+LPC17_RTC_SEC_OFFSET) +#define LPC17_RTC_MIN (LPC17_RTC_BASE+LPC17_RTC_MIN_OFFSET) +#define LPC17_RTC_HOUR (LPC17_RTC_BASE+LPC17_RTC_HOUR_OFFSET) +#define LPC17_RTC_DOM (LPC17_RTC_BASE+LPC17_RTC_DOM_OFFSET) +#define LPC17_RTC_DOW (LPC17_RTC_BASE+LPC17_RTC_DOW_OFFSET) +#define LPC17_RTC_DOY (LPC17_RTC_BASE+LPC17_RTC_DOY_OFFSET) +#define LPC17_RTC_MONTH (LPC17_RTC_BASE+LPC17_RTC_MONTH_OFFSET) +#define LPC17_RTC_YEAR (LPC17_RTC_BASE+LPC17_RTC_YEAR_OFFSET) +#define LPC17_RTC_CALIB (LPC17_RTC_BASE+LPC17_RTC_CALIB_OFFSET) + +/* General purpose registers */ + +#define LPC17_RTC_GPREG0 (LPC17_RTC_BASE+LPC17_RTC_GPREG0_OFFSET) +#define LPC17_RTC_GPREG1 (LPC17_RTC_BASE+LPC17_RTC_GPREG1_OFFSET) +#define LPC17_RTC_GPREG2 (LPC17_RTC_BASE+LPC17_RTC_GPREG2_OFFSET) +#define LPC17_RTC_GPREG3 (LPC17_RTC_BASE+LPC17_RTC_GPREG3_OFFSET) +#define LPC17_RTC_GPREG4 (LPC17_RTC_BASE+LPC17_RTC_GPREG4_OFFSET) + +/* Alarm register group */ + +#define LPC17_RTC_ALSEC (LPC17_RTC_BASE+LPC17_RTC_ALSEC_OFFSET) +#define LPC17_RTC_ALMIN (LPC17_RTC_BASE+LPC17_RTC_ALMIN_OFFSET) +#define LPC17_RTC_ALHOUR (LPC17_RTC_BASE+LPC17_RTC_ALHOUR_OFFSET) +#define LPC17_RTC_ALDOM (LPC17_RTC_BASE+LPC17_RTC_ALDOM_OFFSET) +#define LPC17_RTC_ALDOW (LPC17_RTC_BASE+LPC17_RTC_ALDOW_OFFSET) +#define LPC17_RTC_ALDOY (LPC17_RTC_BASE+LPC17_RTC_ALDOY_OFFSET) +#define LPC17_RTC_ALMON (LPC17_RTC_BASE+LPC17_RTC_ALMON_OFFSET) +#define LPC17_RTC_ALYEAR (LPC17_RTC_BASE+LPC17_RTC_ALYEAR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* The following registers hold 32-bit values and have no bit fields to be defined: + * + * General Purpose Register 0 + * General Purpose Register 1 + * General Purpose Register 2 + * General Purpose Register 3 + * General Purpose Register 4 + */ + +/* Miscellaneous registers */ +/* Interrupt Location Register */ + +#define RTC_ILR_RTCCIF (1 << 0) /* Bit 0: Counter Increment Interrupt */ +#define RTC_ILR_RTCALF (1 << 1) /* Bit 1: Alarm interrupt */ + /* Bits 2-31: Reserved */ +/* Clock Control Register */ + +#define RTC_CCR_CLKEN (1 << 0) /* Bit 0: Clock Enable */ +#define RTC_CCR_CTCRST (1 << 1) /* Bit 1: CTC Reset */ + /* Bits 2-3: Internal test mode controls */ +#define RTC_CCR_CCALEN (1 << 4) /* Bit 4: Calibration counter enable */ + /* Bits 5-31: Reserved */ +/* Counter Increment Interrupt Register */ + +#define RTC_CIIR_IMSEC (1 << 0) /* Bit 0: Second interrupt */ +#define RTC_CIIR_IMMIN (1 << 1) /* Bit 1: Minute interrupt */ +#define RTC_CIIR_IMHOUR (1 << 2) /* Bit 2: Hour interrupt */ +#define RTC_CIIR_IMDOM (1 << 3) /* Bit 3: Day of Month value interrupt */ +#define RTC_CIIR_IMDOW (1 << 4) /* Bit 4: Day of Week value interrupt */ +#define RTC_CIIR_IMDOY (1 << 5) /* Bit 5: Day of Year interrupt */ +#define RTC_CIIR_IMMON (1 << 6) /* Bit 6: Month interrupt */ +#define RTC_CIIR_IMYEAR (1 << 7) /* Bit 7: Yearinterrupt */ + /* Bits 8-31: Reserved */ +/* Alarm Mask Register */ + +#define RTC_AMR_SEC (1 << 0) /* Bit 0: Second not compared for alarm */ +#define RTC_AMR_MIN (1 << 1) /* Bit 1: Minutes not compared for alarm */ +#define RTC_AMR_HOUR (1 << 2) /* Bit 2: Hour not compared for alarm */ +#define RTC_AMR_DOM (1 << 3) /* Bit 3: Day of Monthnot compared for alarm */ +#define RTC_AMR_DOW (1 << 4) /* Bit 4: Day of Week not compared for alarm */ +#define RTC_AMR_DOY (1 << 5) /* Bit 5: Day of Year not compared for alarm */ +#define RTC_AMR_MON (1 << 6) /* Bit 6: Month not compared for alarm */ +#define RTC_AMR_YEAR (1 << 7) /* Bit 7: Year not compared for alarm */ + /* Bits 8-31: Reserved */ + +/* RTC Auxiliary Control Register */ + /* Bits 0-3: Reserved */ +#define RTC_AUXEN_RTCOSCF (1 << 4) /* Bit 4: RTC Oscillator Fail detect flag */ +#ifdef LPC178x + /* Bit 5: Reserved */ +# define RTC_AUXEN_RTCPDOUT (1 << 6) /* Bit 6: RTC power down mode flag */ + /* Bits 7-31: Reserved */ +#endif + +/* RTC Auxiliary Enable Register */ + /* Bits 0-3: Reserved */ +#define RTC_AUX_OSCFEN (1 << 4) /* Bit 4: Oscillator Fail Detect interrupt enable */ + /* Bits 5-31: Reserved */ + +/* Consolidated Time Registers */ +/* Consolidated Time Register 0 */ + +#define RTC_CTIME0_SEC_SHIFT (0) /* Bits 0-5: Seconds */ +#define RTC_CTIME0_SEC_MASK (63 << RTC_CTIME0_SEC_SHIFT) + /* Bits 6-7: Reserved */ +#define RTC_CTIME0_MIN_SHIFT (8) /* Bits 8-13: Minutes */ +#define RTC_CTIME0_MIN_MASK (63 << RTC_CTIME0_MIN_SHIFT) + /* Bits 14-15: Reserved */ +#define RTC_CTIME0_HOURS_SHIFT (16) /* Bits 16-20: Hours */ +#define RTC_CTIME0_HOURS_MASK (31 << RTC_CTIME0_HOURS_SHIFT) + /* Bits 21-23: Reserved */ +#define RTC_CTIME0_DOW_SHIFT (24) /* Bits 24-26: Day of Week */ +#define RTC_CTIME0_DOW_MASK (7 << RTC_CTIME0_DOW_SHIFT) + /* Bits 27-31: Reserved */ +/* Consolidated Time Register 1 */ + +#define RTC_CTIME1_DOM_SHIFT (0) /* Bits 0-4: Day of Month */ +#define RTC_CTIME1_DOM_MASK (31 << RTC_CTIME1_DOM_SHIFT) + /* Bits 5-7: Reserved */ +#define RTC_CTIME1_MON_SHIFT (8) /* Bits 8-11: Month */ +#define RTC_CTIME1_MON_MASK (15 << RTC_CTIME1_MON_SHIFT) + /* Bits 12-15: Reserved */ +#define RTC_CTIME1_YEAR_SHIFT (16) /* Bits 16-27: Year */ +#define RTC_CTIME1_YEAR_MASK (0x0fff << RTC_CTIME1_YEAR_SHIFT) + /* Bits 28-31: Reserved */ +/* Consolidated Time Register 2 */ + +#define RTC_CTIME2_DOY_SHIFT (0) /* Bits 0-11: Day of Year */ +#define RTC_CTIME2_DOY_MASK (0x0fff << RTC_CTIME2_DOY_SHIFT) + /* Bits 12-31: Reserved */ +/* Time counter registers */ + +#define RTC_SEC_MASK (0x003f) +#define RTC_MIN_MASK (0x003f) +#define RTC_HOUR_MASK (0x001f) +#define RTC_DOM_MASK (0x001f) +#define RTC_DOW_MASK (0x0007) +#define RTC_DOY_MASK (0x01ff) +#define RTC_MONTH_MASK (0x000f) +#define RTC_YEAR_MASK (0x0fff) + +/* Calibration Value Register */ + +#define RTC_CALIB_CALVAL_SHIFT (0) /* Bits 0-16: calibration counter counts to this value */ +#define RTC_CALIB_CALVAL_MASK (0xffff << RTC_CALIB_CALVAL_SHIFT) +#define RTC_CALIB_CALDIR (1 << 17) /* Bit 17: Calibration direction */ + /* Bits 18-31: Reserved */ +/* Alarm register group */ + +#define RTC_ALSEC_MASK (0x003f) +#define RTC_ALMIN_MASK (0x003f) +#define RTC_ALHOUR_MASK (0x001f) +#define RTC_ALDOM_MASK (0x001f) +#define RTC_ALDOW_MASK (0x0007) +#define RTC_ALDOY_MASK (0x01ff) +#define RTC_ALMON_MASK (0x000f) +#define RTC_ALYEAR_MASK (0x0fff) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTC_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_rtcevmr.h b/arch/arm/src/lpc17xx/chip/lpc17_rtcevmr.h new file mode 100644 index 0000000000000000000000000000000000000000..a16decd471ccab2a217457d530515cc3ac7bec3f --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_rtcevmr.h @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_rtcevmr.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTCEVMR_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTCEVMR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_RTCEV_ERCONTROL_OFFSET 0x0084 /* Monitor/Recorder Control register */ +#define LPC17_RTCEV_ERSTATUS_OFFSET 0x0080 /* Status register */ +#define LPC17_RTCEV_ERCOUNTERS_OFFSET 0x0088 /* Counters register */ +#define LPC17_RTCEV_ERFIRSTSTAMP0_OFFSET 0x0090 /* Channel 0 first Stamp register */ +#define LPC17_RTCEV_ERFIRSTSTAMP1_OFFSET 0x0090 /* Channel 1 first Stamp register */ +#define LPC17_RTCEV_ERFIRSTSTAMP2_OFFSET 0x0090 /* Channel 2 first Stamp register */ +#define LPC17_RTCEV_ERLASTSTAMP0_OFFSET 0x0098 /* Channel 0 last stamp register */ +#define LPC17_RTCEV_ERLASTSTAMP1_OFFSET 0x00a0 /* Channel 1 last stamp register */ +#define LPC17_RTCEV_ERLASTSTAMP2_OFFSET 0x00a8 /* Channel 2 last stamp register */ + +#define LPC17_RTCEV_ERCONTROL (LPC17_RTC_BASE+LPC17_RTCEV_ERCONTROL_OFFSET) +#define LPC17_RTCEV_ERSTATUS (LPC17_RTC_BASE+LPC17_RTCEV_ERSTATUS_OFFSET) +#define LPC17_RTCEV_ERCOUNTERS (LPC17_RTC_BASE+LPC17_RTCEV_ERCOUNTERS_OFFSET) +#define LPC17_RTCEV_ERFIRSTSTAMP0 (LPC17_RTC_BASE+LPC17_RTCEV_ERFIRSTSTAMP0_OFFSET) +#define LPC17_RTCEV_ERFIRSTSTAMP1 (LPC17_RTC_BASE+LPC17_RTCEV_ERFIRSTSTAMP1_OFFSET) +#define LPC17_RTCEV_ERFIRSTSTAMP2 (LPC17_RTC_BASE+LPC17_RTCEV_ERFIRSTSTAMP2_OFFSET) +#define LPC17_RTCEV_ERLASTSTAMP0 (LPC17_RTC_BASE+LPC17_RTCEV_ERLASTSTAMP0_OFFSET) +#define LPC17_RTCEV_ERLASTSTAMP1 (LPC17_RTC_BASE+LPC17_RTCEV_ERLASTSTAMP1_OFFSET) +#define LPC17_RTCEV_ERLASTSTAMP2 (LPC17_RTC_BASE+LPC17_RTCEV_ERLASTSTAMP2_OFFSET) + +/* RTCEV ERCONTROL Event Monitor/Recorder Control Register */ + +#define RTCEV_ERCONTROL_INTWAKE_EN0 (1) /* Bit 0: Interrupt/wakeup enable channel 0 */ +#define RTCEV_ERCONTROL_GPCLEAR_EN0 (1 << 1) /* Bit 1: Automatic clearing of RTC - channel 0 */ +#define RTCEV_ERCONTROL_POL0 (1 << 2) /* Bit 2: Edge polarity on RTC_EV0 pins */ +#define RTCEV_ERCONTROL_EV0_INPUT_EN (1 << 3) /* Bit 3: Event enable for channel 0 */ + /* Bits 4-9: Reserved */ +#define RTCEV_ERCONTROL_INTWAKE_EN1 (1 << 10) /* Bit 10: Interrupt/wakeup enable - channel 1 */ +#define RTCEV_ERCONTROL_GPCLEAR_EN1 (1 << 11) /* Bit 11: Automatic clearing of RTC - channel 1 */ +#define RTCEV_ERCONTROL_POL1 (1 << 12) /* Bit 12: Edge polarity on RTC_EV1 pins */ +#define RTCEV_ERCONTROL_EV1_INPUT_EN (1 << 13) /* Bit 13: Event enable for channel 1 */ + /* Bits 14-19: Reserved */ +#define RTCEV_ERCONTROL_INTWAKE_EN2 (1 << 20) /* Bit 20: Interrupt/wakeup enable - channel 2 */ +#define RTCEV_ERCONTROL_GPCLEAR_EN2 (1 << 21) /* Bit 21: Automatic clearing of RTC - channel 2 */ +#define RTCEV_ERCONTROL_POL2 (1 << 22) /* Bit 22: Edge polarity on RTC_EV2 pins */ +#define RTCEV_ERCONTROL_EV2_INPUT_EN (1 << 23) /* Bit 23: Event enable for channel 1 */ + /* Bits 24-29: Reserved */ +#define RTCEV_ERCONTROL_ERMODE_SHIFT (30) /* Bits 30-31: Event monitoring mode */ +#define RTCEV_ERCONTROL_ERMODE_MASK (3 << RTCEV_ERCONTROL_ERMODE_SHIFT) +# define ERMODE0 (0) /* monitor/clocks disabled */ +# define ERMODE1 (1) /* 16Hz sample clock */ +# define ERMODE2 (2) /* 64Hz sample clock */ +# define ERMODE3 (3) /* 1000Hz sample clock */ + +/* RTCEV ERSTATUS - Monitor/Recorder Status Register */ + +#define RTCEV_ERSTATUS_EV0 (1) /* Bit 0: Event flag - channel 0 */ +#define RTCEV_ERSTATUS_EV1 (1 << 1) /* Bit 1: Event flag - channel 1 */ +#define RTCEV_ERSTATUS_EV2 (1 << 2) /* Bit 2: Event flag - channel 2 */ +#define RTCEV_ERSTATUS_EV2 (1 << 3) /* Bit 3: GPReg async clear flag */ + /* Bits 4-30: Reserved */ +#define RTCEV_ERSTATUS_WAKEUP (1 << 31) /* Bit 31: Interrupt/Wakeup request flag */ + +/* RTCEV ERCOUNTERS - Monitor/Recorder Counters Register */ + +#define RTCEV_ERCOUNTER_COUNTER0_SHIFT (0) /* Bits 0-2: Value for event 0 */ +#define RTCEV_ERCOUNTER_COUNTER0_MASK (7 << RTCEV_ERCOUNTER_COUNTER0_SHIFT) + /* Bits 3-7: Reserved */ +#define RTCEV_ERCOUNTER_COUNTER1_SHIFT (8) i /* Bits 8-10: Value for event 1 */ +#define RTCEV_ERCOUNTER_COUNTER1_MASK (7 << RTCEV_ERCOUNTER_COUNTER1_SHIFT) + /* Bits 11-15: Reserved */ +#define RTCEV_ERCOUNTER_COUNTER2_SHIFT (16) /* Bits 16-18: Value for event 2 */ +#define RTCEV_ERCOUNTER_COUNTER2_MASK (7 << RTCEV_ERCOUNTER_COUNTER2_SHIFT) + /* Bits 19-31: Reserved */ + +/* RTCEV ERFIRSTSTAMP[0-2] - Monitor/Recorder First Stamp Registers */ +/* RTCEV ERLASTSTAMP[0-2] - Monitor/Recorder Last Stamp Registers */ + +#define RTCEV_TIMESTAMP_SEC_SHIFT (0) /* Bits 0-5: Seconds value 0-59 */ +#define RTCEV_TIMESTAMP_SEC_MASK (0x3f << RTCEV_TIMESTAMP_SEC_SHIFT) +#define RTCEV_TIMESTAMP_MIN_SHIFT (6) /* Bits 6-11: Minutes value 0-59 */ +#define RTCEV_TIMESTAMP_MIN_MASK (0x3f << RTCEV_TIMESTAMP_MIN_SHIFT) +#define RTCEV_TIMESTAMP_HOUR_SHIFT (12) /* Bits 12-16: Hours value 0-23 */ +#define RTCEV_TIMESTAMP_HOUR_MASK (0x1f << RTCEV_TIMESTAMP_HOUR_SHIFT) +#define RTCEV_TIMESTAMP_DOY_SHIFT (17) /* Bits 17-25: Day of the year value 1-366 */ +#define RTCEV_TIMESTAMP_DOY_MASK (0x1ff << RTCEV_TIMESTAMP_DOY_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_RTCEVMR_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_sdcard.h b/arch/arm/src/lpc17xx/chip/lpc17_sdcard.h new file mode 100644 index 0000000000000000000000000000000000000000..5e91435ef90485913f03582cd239fd1456011836 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_sdcard.h @@ -0,0 +1,272 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_sdcard.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SDCARD_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SDCARD_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define LPC17_SDCARD_PWR_OFFSET 0x0000 /* SD card power control register */ +#define LPC17_SDCARD_CLOCK_OFFSET 0x0004 /* SD card clock control register */ +#define LPC17_SDCARD_ARG_OFFSET 0x0008 /* SD card argument register */ +#define LPC17_SDCARD_CMD_OFFSET 0x000c /* SD card command register */ +#define LPC17_SDCARD_RESPCMD_OFFSET 0x0010 /* SD card command response register */ +#define LPC17_SDCARD_RESP_OFFSET(n) (0x0010+4*(n)) +# define LPC17_SDCARD_RESP0_OFFSET 0x0014 /* SD card response 1 register */ +# define LPC17_SDCARD_RESP1_OFFSET 0x0018 /* SD card response 2 register */ +# define LPC17_SDCARD_RESP2_OFFSET 0x001c /* SD card response 3 register */ +# define LPC17_SDCARD_RESP3_OFFSET 0x0020 /* SD card response 4 register */ +#define LPC17_SDCARD_DTIMER_OFFSET 0x0024 /* SD card data timer register */ +#define LPC17_SDCARD_DLEN_OFFSET 0x0028 /* SD card data length register */ +#define LPC17_SDCARD_DCTRL_OFFSET 0x002c /* SD card data control register */ +#define LPC17_SDCARD_DCOUNT_OFFSET 0x0030 /* SD card data counter register */ +#define LPC17_SDCARD_STATUS_OFFSET 0x0034 /* SD card status register */ +#define LPC17_SDCARD_CLEAR_OFFSET 0x0038 /* SD card interrupt clear register */ +#define LPC17_SDCARD_MASK0_OFFSET 0x003c /* SD card mask register */ +#define LPC17_SDCARD_FIFOCNT_OFFSET 0x0048 /* SD card FIFO counter register */ +#define LPC17_SDCARD_FIFO_OFFSET 0x0080 /* SD card data FIFO register */ + +/* Register Addresses ***************************************************************/ + +#define LPC17_SDCARD_PWR (LPC17_MCI_BASE+LPC17_SDCARD_PWR_OFFSET) +#define LPC17_SDCARD_CLOCK (LPC17_MCI_BASE+LPC17_SDCARD_CLOCK_OFFSET) +#define LPC17_SDCARD_ARG (LPC17_MCI_BASE+LPC17_SDCARD_ARG_OFFSET) +#define LPC17_SDCARD_CMD (LPC17_MCI_BASE+LPC17_SDCARD_CMD_OFFSET) +#define LPC17_SDCARD_RESPCMD (LPC17_MCI_BASE+LPC17_SDCARD_RESPCMD_OFFSET) +#define LPC17_SDCARD_RESP(n) (LPC17_MCI_BASE+LPC17_SDCARD_RESP_OFFSET(n)) +#define LPC17_SDCARD_RESP0 (LPC17_MCI_BASE+LPC17_SDCARD_RESP0_OFFSET) +#define LPC17_SDCARD_RESP1 (LPC17_MCI_BASE+LPC17_SDCARD_RESP1_OFFSET) +#define LPC17_SDCARD_RESP2 (LPC17_MCI_BASE+LPC17_SDCARD_RESP2_OFFSET) +#define LPC17_SDCARD_RESP3 (LPC17_MCI_BASE+LPC17_SDCARD_RESP3_OFFSET) +#define LPC17_SDCARD_DTIMER (LPC17_MCI_BASE+LPC17_SDCARD_DTIMER_OFFSET) +#define LPC17_SDCARD_DLEN (LPC17_MCI_BASE+LPC17_SDCARD_DLEN_OFFSET) +#define LPC17_SDCARD_DCTRL (LPC17_MCI_BASE+LPC17_SDCARD_DCTRL_OFFSET) +#define LPC17_SDCARD_DCOUNT (LPC17_MCI_BASE+LPC17_SDCARD_DCOUNT_OFFSET) +#define LPC17_SDCARD_STATUS (LPC17_MCI_BASE+LPC17_SDCARD_STATUS_OFFSET) +#define LPC17_SDCARD_CLEAR (LPC17_MCI_BASE+LPC17_SDCARD_CLEAR_OFFSET) +#define LPC17_SDCARD_MASK0 (LPC17_MCI_BASE+LPC17_SDCARD_MASK0_OFFSET) +#define LPC17_SDCARD_FIFOCNT (LPC17_MCI_BASE+LPC17_SDCARD_FIFOCNT_OFFSET) +#define LPC17_SDCARD_FIFO (LPC17_MCI_BASE+LPC17_SDCARD_FIFO_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* MCI Power Control Registers - PWR - 0x400c 0000*/ + +#define SDCARD_PWR_CTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ +#define SDCARD_PWR_CTRL_MASK (3 << SDCARD_PWR_CTRL_SHIFT) +# define SDCARD_PWR_CTRL_OFF (0 << SDCARD_PWR_CTRL_SHIFT) /* 00: Power-off: card clock stopped */ +# define SDCARD_PWR_CTRL_PWRUP (2 << SDCARD_PWR_CTRL_SHIFT) /* 10: Reserved power-up */ +# define SDCARD_PWR_CTRL_ON (3 << SDCARD_PWR_CTRL_SHIFT) /* 11: Power-on: card is clocked */ + /* Bits 2-5 Reserved */ +#define SDCARD_PWR_OPENDRAIN (1 << 6) /* SD_CMD Output Control */ +#define SDCARD_PWR_ROD (1 << 7) /* Rod Control */ + /* Bits 8-31: Reserved */ +#define SDCARD_PWR_RESET (0) /* Reset value */ + +/* MCI Clock Control Register - CLOCK - 0x400c 0004 */ + +#define SDCARD_CLOCK_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ +#define SDCARD_CLOCK_CLKDIV_MASK (0xff << SDCARD_CLOCK_CLKDIV_SHIFT) +#define SDCARD_CLOCK_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ +#define SDCARD_CLOCK_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ +#define SDCARD_CLOCK_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ +#define SDCARD_CLOCK_WIDBUS (1 << 11) /* Bit 11: Wide bus mode enable bit */ +# define SDCARD_CLOCK_WIDBUS_D1 (0) /* 0: Default (SDIO_D0) */ +# define SDCARD_CLOCK_WIDBUS_D4 (SDCARD_CLOCK_WIDBUS) /* 1: 4-wide (SDIO_D[3:0]) */ + /* Bits 12-31: Reserved */ + +#define SDCARD_CLOCK_RESET (0) /* Reset value */ + +/* MCI Argument Register - ARGUMENT - 0x400c 0008 has no bitfields */ + +#define SDCARD_ARG_RESET (0) /* Reset value */ + +/* MCI Command Register - COMMAND - 0x400c 000c */ + +#define SDCARD_CMD_INDEX_SHIFT (0) /* Bits 0-5: Command Index */ +#define SDCARD_CMD_INDEX_MASK (0x3f << SDCARD_CMD_INDEX_SHIFT) +#define SDCARD_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ +#define SDCARD_CMD_WAITRESP_MASK (3 << SDCARD_CMD_WAITRESP_SHIFT) +# define SDCARD_CMD_NORESPONSE (0 << SDCARD_CMD_WAITRESP_SHIFT) /* 00/01: No response */ +# define SDCARD_CMD_SHORTRESPONSE (1 << SDCARD_CMD_WAITRESP_SHIFT) /* 10: Short response */ +# define SDCARD_CMD_LONGRESPONSE (3 << SDCARD_CMD_WAITRESP_SHIFT) /* 11: Long response */ +#define SDCARD_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ +#define SDCARD_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ +#define SDCARD_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ + /* Bits 11-31: Reserved */ + +#define SDCARD_CMD_RESET (0) /* Reset value */ + +/* MCI Command Response Register - RESPCOMMAND - 0x400c 0010 */ + +#define SDCARD_RESPCMD_SHIFT (0) /* Bits 0-5: Resopnse Command index */ +#define SDCARD_RESPCMD_MASK (0x3f << SDCARD_RESPCMD_SHIFT) + /* Bits 6-31: Reserved */ + +/* MCI Response Registers RESPONSE0-3 - 0x400c 0014, 0x400c 0018, + No bitfields 0x400c 001c, 0x400c 0020 */ + + +/* MCI - Data Timer Register DATATIMER - 0x400c 0024 */ +/* No bitfields */ + +#define SDCARD_DTIMER_RESET (0) /* Reset value */ + +/* MCI - Data Length Register DATALENGTH - 0x400C 0028 */ + +#define SDCARD_DATALENGTH_SHIFT (0) /* Bits 0-15: Data length value */ +#define SDCARD_DATALENGTH_MASK (0xffff << SDCARD_DATALENGTH_SHIFT) + /* Bits 16-31: Reserved */ + +#define SDCARD_DLEN_RESET (0) /* Reset value */ + +/* MCI - Data Control Register - DATACTRL - 0x400c 002c */ + +#define SDCARD_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ +#define SDCARD_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ +#define SDCARD_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ +#define SDCARD_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ +#define SDCARD_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 4-7: Data block size */ +#define SDCARD_DCTRL_DBLOCKSIZE_MASK (15 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_1BYTE (0 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_2BYTES (1 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_4BYTES (2 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_8BYTES (3 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_16BYTES (4 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_32BYTES (5 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_64BYTES (6 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_128BYTES (7 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_256BYTES (8 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_512BYTES (9 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_1KBYTE (10 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) +# define SDCARD_DCTRL_2KBYTES (11 << SDCARD_DCTRL_DBLOCKSIZE_SHIFT) + /* Bits 8-31: Reserved */ + +#define SDCARD_DCTRL_RESET (0) /* Reset value */ + +/* MCI - Data Length Register DATALENGTH - 0x400c 0028 */ + +#define SDCARD_DATACOUNT_SHIFT (0) /* Bits 0-15: Remaining data */ +#define SDCARD_DATACOUNT_MASK (0xffff << SDCARD_DATACOUNT_SHIFT) + /* Bits 16-31: Reserved */ + +/* MCI - Status Register -Status - 0x400c 0034 */ + +#define SDCARD_STATUS_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ +#define SDCARD_STATUS_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ +#define SDCARD_STATUS_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ +#define SDCARD_STATUS_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ +#define SDCARD_STATUS_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ +#define SDCARD_STATUS_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ +#define SDCARD_STATUS_CMDREND (1 << 6) /* Bit 6: Command response received */ +#define SDCARD_STATUS_CMDSENT (1 << 7) /* Bit 7: Command sent */ +#define SDCARD_STATUS_DATAEND (1 << 8) /* Bit 8: Data end */ +#define SDCARD_STATUS_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ +#define SDCARD_STATUS_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ +#define SDCARD_STATUS_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ +#define SDCARD_STATUS_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ +#define SDCARD_STATUS_RXACT (1 << 13) /* Bit 13: Data receive in progress */ +#define SDCARD_STATUS_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ +#define SDCARD_STATUS_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ +#define SDCARD_STATUS_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ +#define SDCARD_STATUS_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ +#define SDCARD_STATUS_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ +#define SDCARD_STATUS_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ +#define SDCARD_STATUS_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ +#define SDCARD_STATUS_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ + /* Bits 22-31: Reserved */ + +/* MCI - Clear Register CLEAR - 0x400c 0038 */ + +#define SDCARD_CLEAR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ +#define SDCARD_CLEAR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ +#define SDCARD_CLEAR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ +#define SDCARD_CLEAR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ +#define SDCARD_CLEAR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ +#define SDCARD_CLEAR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ +#define SDCARD_CLEAR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ +#define SDCARD_CLEAR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ +#define SDCARD_CLEAR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ +#define SDCARD_CLEAR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ +#define SDCARD_CLEAR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ + /* Bits 11-31: Reserved */ + +#define SDCARD_CLEAR_RESET 0x000007ff +#define SDCARD_CLEAR_STATICFLAGS 0x000005ff + +/* MCI - Interrupt Mask Registers - MASK0 - 0x400c 003c */ + +#define SDCARD_MASK0_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ +#define SDCARD_MASK0_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ +#define SDCARD_MASK0_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ +#define SDCARD_MASK0_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ +#define SDCARD_MASK0_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ +#define SDCARD_MASK0_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ +#define SDCARD_MASK0_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ +#define SDCARD_MASK0_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ +#define SDCARD_MASK0_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ +#define SDCARD_MASK0_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ +#define SDCARD_MASK0_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ +#define SDCARD_MASK0_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ +#define SDCARD_MASK0_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ +#define SDCARD_MASK0_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ +#define SDCARD_MASK0_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ +#define SDCARD_MASK0_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ +#define SDCARD_MASK0_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ +#define SDCARD_MASK0_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ +#define SDCARD_MASK0_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ +#define SDCARD_MASK0_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ +#define SDCARD_MASK0_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ +#define SDCARD_MASK0_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ + /* Bits 22-31: Reserved */ +#define SDCARD_MASK0_RESET (0) + +/* MCI - FIFO Counter Register (FIFOCNT - 0x400c 0048 */ + +#define SDCARD_FIFOCNT_SHIFT (0) /* Bits 0-14: Remaining data */ +#define SDCARD_FIFOCNT_MASK (0x7fff << SDCARD_FIFOCNT_SHIFT) + /* Bits 15-31: Reserved */ + +/* MCI - Data FIFO Register - FIFO - 0x400c 0080 to 0x400c 00bc */ +/* The receive and transmit FIFOs can be read or written as 32 bit wide registers. + * The FIFOs contain 16 entries on 16 sequential addresses. + */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SDCARD_H */ + diff --git a/arch/arm/src/lpc17xx/chip/lpc17_spi.h b/arch/arm/src/lpc17xx/chip/lpc17_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..716e70cb541d87c95d469df6a807a08da66b68e8 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_spi.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_spi.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SPI_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_SPI_CR_OFFSET 0x0000 /* Control Register */ +#define LPC17_SPI_SR_OFFSET 0x0004 /* SPI Status Register */ +#define LPC17_SPI_DR_OFFSET 0x0008 /* SPI Data Register */ +#define LPC17_SPI_CCR_OFFSET 0x000c /* SPI Clock Counter Register */ +#define LPC17_SPI_TCR_OFFSET 0x0010 /* SPI Test Control Register */ +#define LPC17_SPI_TSR_OFFSET 0x0014 /* SPI Test Status Register */ +#define LPC17_SPI_INT_OFFSET 0x001c /* SPI Interrupt Register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_SPI_CR (LPC17_SPI_BASE+LPC17_SPI_CR_OFFSET) +#define LPC17_SPI_SR (LPC17_SPI_BASE+LPC17_SPI_SR_OFFSET) +#define LPC17_SPI_DR (LPC17_SPI_BASE+LPC17_SPI_DR_OFFSET) +#define LPC17_SPI_CCR (LPC17_SPI_BASE+LPC17_SPI_CCR_OFFSET) +#define LPC17_TCR_CCR (LPC17_SPI_BASE+LPC17_SPI_TCR_OFFSET) +#define LPC17_TSR_CCR (LPC17_SPI_BASE+LPC17_SPI_TSR_OFFSET) +#define LPC17_SPI_INT (LPC17_SPI_BASE+LPC17_SPI_INT_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Control Register */ + /* Bits 0-1: Reserved */ +#define SPI_CR_BITENABLE (1 << 2) /* Bit 2: Enable word size selected by BITS */ +#define SPI_CR_CPHA (1 << 3) /* Bit 3: Clock phase control */ +#define SPI_CR_CPOL (1 << 4) /* Bit 4: Clock polarity control */ +#define SPI_CR_MSTR (1 << 5) /* Bit 5: Master mode select */ +#define SPI_CR_LSBF (1 << 6) /* Bit 6: SPI data is transferred LSB first */ +#define SPI_CR_SPIE (1 << 7) /* Bit 7: Serial peripheral interrupt enable */ +#define SPI_CR_BITS_SHIFT (8) /* Bits 8-11: Number of bits per word (BITENABLE==1) */ +#define SPI_CR_BITS_MASK (15 << SPI_CR_BITS_SHIFT) +# define SPI_CR_BITS_8BITS (8 << SPI_CR_BITS_SHIFT) /* 8 bits per transfer */ +# define SPI_CR_BITS_9BITS (9 << SPI_CR_BITS_SHIFT) /* 9 bits per transfer */ +# define SPI_CR_BITS_10BITS (10 << SPI_CR_BITS_SHIFT) /* 10 bits per transfer */ +# define SPI_CR_BITS_11BITS (11 << SPI_CR_BITS_SHIFT) /* 11 bits per transfer */ +# define SPI_CR_BITS_12BITS (12 << SPI_CR_BITS_SHIFT) /* 12 bits per transfer */ +# define SPI_CR_BITS_13BITS (13 << SPI_CR_BITS_SHIFT) /* 13 bits per transfer */ +# define SPI_CR_BITS_14BITS (14 << SPI_CR_BITS_SHIFT) /* 14 bits per transfer */ +# define SPI_CR_BITS_15BITS (15 << SPI_CR_BITS_SHIFT) /* 15 bits per transfer */ +# define SPI_CR_BITS_16BITS (0 << SPI_CR_BITS_SHIFT) /* 16 bits per transfer */ + /* Bits 12-31: Reserved */ +/* SPI Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_SR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_SR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_SR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_SR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_SR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Data Register */ + +#define SPI_DR_MASK (0xff) /* Bits 0-15: SPI Bi-directional data port */ +#define SPI_DR_MASKWIDE (0xffff) /* Bits 0-15: If SPI_CR_BITENABLE != 0 */ + /* Bits 8-31: Reserved */ +/* SPI Clock Counter Register */ + +#define SPI_CCR_MASK (0xff) /* Bits 0-7: SPI Clock counter setting */ + /* Bits 8-31: Reserved */ +/* SPI Test Control Register */ + /* Bit 0: Reserved */ +#define SPI_TCR_TEST_SHIFT (1) /* Bits 1-7: SPI test mode */ +#define SPI_TCR_TEST_MASK (0x7f << SPI_TCR_TEST_SHIFT) + /* Bits 8-31: Reserved */ +/* SPI Test Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_TSR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_TSR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_TSR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_TSR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_TSR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Interrupt Register */ + +#define SPI_INT_SPIF (1 << 0) /* SPI interrupt */ + /* Bits 1-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SPI_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_ssp.h b/arch/arm/src/lpc17xx/chip/lpc17_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..dd791327fb153d1795a72f9338fec1ad2f7716af --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_ssp.h @@ -0,0 +1,185 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_ssp.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SSP_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* 8 frame FIFOs for both transmit and receive */ + +#define LPC17_SSP_FIFOSZ 8 + +/* Register offsets *****************************************************************/ + +#define LPC17_SSP_CR0_OFFSET 0x0000 /* Control Register 0 */ +#define LPC17_SSP_CR1_OFFSET 0x0004 /* Control Register 1 */ +#define LPC17_SSP_DR_OFFSET 0x0008 /* Data Register */ +#define LPC17_SSP_SR_OFFSET 0x000c /* Status Register */ +#define LPC17_SSP_CPSR_OFFSET 0x0010 /* Clock Prescale Register */ +#define LPC17_SSP_IMSC_OFFSET 0x0014 /* Interrupt Mask Set and Clear Register */ +#define LPC17_SSP_RIS_OFFSET 0x0018 /* Raw Interrupt Status Register */ +#define LPC17_SSP_MIS_OFFSET 0x001c /* Masked Interrupt Status Register */ +#define LPC17_SSP_ICR_OFFSET 0x0020 /* Interrupt Clear Register */ +#define LPC17_SSP_DMACR_OFFSET 0x0024 /* DMA Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_SSP0_CR0 (LPC17_SSP0_BASE+LPC17_SSP_CR0_OFFSET) +#define LPC17_SSP0_CR1 (LPC17_SSP0_BASE+LPC17_SSP_CR1_OFFSET) +#define LPC17_SSP0_DR (LPC17_SSP0_BASE+LPC17_SSP_DR_OFFSET) +#define LPC17_SSP0_SR (LPC17_SSP0_BASE+LPC17_SSP_SR_OFFSET) +#define LPC17_SSP0_CPSR (LPC17_SSP0_BASE+LPC17_SSP_CPSR_OFFSET) +#define LPC17_SSP0_IMSC (LPC17_SSP0_BASE+LPC17_SSP_IMSC_OFFSET) +#define LPC17_SSP0_RIS (LPC17_SSP0_BASE+LPC17_SSP_RIS_OFFSET) +#define LPC17_SSP0_MIS (LPC17_SSP0_BASE+LPC17_SSP_MIS_OFFSET) +#define LPC17_SSP0_ICR (LPC17_SSP0_BASE+LPC17_SSP_ICR_OFFSET) +#define LPC17_SSP0_DMACR (LPC17_SSP0_BASE+LPC17_SSP_DMACR_OFFSET) + +#define LPC17_SSP1_CR0 (LPC17_SSP1_BASE+LPC17_SSP_CR0_OFFSET) +#define LPC17_SSP1_CR1 (LPC17_SSP1_BASE+LPC17_SSP_CR1_OFFSET) +#define LPC17_SSP1_DR (LPC17_SSP1_BASE+LPC17_SSP_DR_OFFSET) +#define LPC17_SSP1_SR (LPC17_SSP1_BASE+LPC17_SSP_SR_OFFSET) +#define LPC17_SSP1_CPSR (LPC17_SSP1_BASE+LPC17_SSP_CPSR_OFFSET) +#define LPC17_SSP1_IMSC (LPC17_SSP1_BASE+LPC17_SSP_IMSC_OFFSET) +#define LPC17_SSP1_RIS (LPC17_SSP1_BASE+LPC17_SSP_RIS_OFFSET) +#define LPC17_SSP1_MIS (LPC17_SSP1_BASE+LPC17_SSP_MIS_OFFSET) +#define LPC17_SSP1_ICR (LPC17_SSP1_BASE+LPC17_SSP_ICR_OFFSET) +#define LPC17_SSP1_DMACR (LPC17_SSP1_BASE+LPC17_SSP_DMACR_OFFSET) + +#define LPC17_SSP2_CR0 (LPC17_SSP2_BASE+LPC17_SSP_CR0_OFFSET) +#define LPC17_SSP2_CR1 (LPC17_SSP2_BASE+LPC17_SSP_CR1_OFFSET) +#define LPC17_SSP2_DR (LPC17_SSP2_BASE+LPC17_SSP_DR_OFFSET) +#define LPC17_SSP2_SR (LPC17_SSP2_BASE+LPC17_SSP_SR_OFFSET) +#define LPC17_SSP2_CPSR (LPC17_SSP2_BASE+LPC17_SSP_CPSR_OFFSET) +#define LPC17_SSP2_IMSC (LPC17_SSP2_BASE+LPC17_SSP_IMSC_OFFSET) +#define LPC17_SSP2_RIS (LPC17_SSP2_BASE+LPC17_SSP_RIS_OFFSET) +#define LPC17_SSP2_MIS (LPC17_SSP2_BASE+LPC17_SSP_MIS_OFFSET) +#define LPC17_SSP2_ICR (LPC17_SSP2_BASE+LPC17_SSP_ICR_OFFSET) +#define LPC17_SSP2_DMACR (LPC17_SSP2_BASE+LPC17_SSP_DMACR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Control Register 0 */ + +#define SSP_CR0_DSS_SHIFT (0) /* Bits 0-3: DSS Data Size Select */ +#define SSP_CR0_DSS_MASK (15 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_4BIT (3 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_5BIT (4 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_6BIT (5 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_7BIT (6 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_8BIT (7 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_9BIT (8 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_10BIT (9 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_11BIT (10 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_12BIT (11 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_13BIT (12 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_14BIT (13 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_15BIT (14 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_16BIT (15 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_FRF_SHIFT (4) /* Bits 4-5: FRF Frame Format */ +#define SSP_CR0_FRF_MASK (3 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_SPI (0 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_TI (1 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_UWIRE (2 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_CPOL (1 << 6) /* Bit 6: Clock Out Polarity */ +#define SSP_CR0_CPHA (1 << 7) /* Bit 7: Clock Out Phase */ +#define SSP_CR0_SCR_SHIFT (8) /* Bits 8-15: Serial Clock Rate */ +#define SSP_CR0_SCR_MASK (0xff << SSP_CR0_SCR_SHIFT) + /* Bits 8-31: Reserved */ +/* Control Register 1 */ + +#define SSP_CR1_LBM (1 << 0) /* Bit 0: Loop Back Mode */ +#define SSP_CR1_SSE (1 << 1) /* Bit 1: SSP Enable */ +#define SSP_CR1_MS (1 << 2) /* Bit 2: Master/Slave Mode */ +#define SSP_CR1_SOD (1 << 3) /* Bit 3: Slave Output Disable */ + /* Bits 4-31: Reserved */ +/* Data Register */ + +#define SSP_DR_MASK (0xffff) /* Bits 0-15: Data */ + /* Bits 16-31: Reserved */ +/* Status Register */ + +#define SSP_SR_TFE (1 << 0) /* Bit 0: Transmit FIFO Empty */ +#define SSP_SR_TNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define SSP_SR_RNE (1 << 2) /* Bit 2: Receive FIFO Not Empty */ +#define SSP_SR_RFF (1 << 3) /* Bit 3: Receive FIFO Full */ +#define SSP_SR_BSY (1 << 4) /* Bit 4: Busy */ + /* Bits 5-31: Reserved */ +/* Clock Prescale Register */ + +#define SSP_CPSR_DVSR_MASK (0xff) /* Bits 0-7: clock = SSP_PCLK/DVSR */ + /* Bits 8-31: Reserved */ +/* Common format for interrupt control registers: + * + * Interrupt Mask Set and Clear Register (IMSC) + * Raw Interrupt Status Register (RIS) + * Masked Interrupt Status Register (MIS) + * Interrupt Clear Register (ICR) + */ + +#define SSP_INT_ROR (1 << 0) /* Bit 0: RX FIFO overrun */ +#define SSP_INT_RT (1 << 1) /* Bit 1: RX FIFO timeout */ +#define SSP_INT_RX (1 << 2) /* Bit 2: RX FIFO at least half full (not ICR) */ +#define SSP_INT_TX (1 << 3 ) /* Bit 3: TX FIFO at least half empy (not ICR) */ + /* Bits 4-31: Reserved */ +/* DMA Control Register */ + +#define SSP_DMACR_RXDMAE (1 << 0) /* Bit 0: Receive DMA Enable */ +#define SSP_DMACR_TXDMAE (1 << 1) /* Bit 1: Transmit DMA Enable */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SSP_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_syscon.h b/arch/arm/src/lpc17xx/chip/lpc17_syscon.h new file mode 100644 index 0000000000000000000000000000000000000000..ebab3a1be5c35ffdf61af1b114fbd5b8d6dfcb16 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_syscon.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_syscon.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SYSCON_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SYSCON_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct system controller + * register definitions for the selected LPC17xx family. + */ + +#include + +#if defined(LPC176x) +# include "chip/lpc176x_syscon.h" +#elif defined(LPC178x) +# include "chip/lpc178x_syscon.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_SYSCON_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_timer.h b/arch/arm/src/lpc17xx/chip/lpc17_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..455133ee7e8d20af7cb3f9f1230132c94df23086 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_timer.h @@ -0,0 +1,250 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_timer.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_TIMER_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_TMR_IR_OFFSET 0x0000 /* Interrupt Register */ +#define LPC17_TMR_TCR_OFFSET 0x0004 /* Timer Control Register */ +#define LPC17_TMR_TC_OFFSET 0x0008 /* Timer Counter */ +#define LPC17_TMR_PR_OFFSET 0x000c /* Prescale Register */ +#define LPC17_TMR_PC_OFFSET 0x0010 /* Prescale Counter */ +#define LPC17_TMR_MCR_OFFSET 0x0014 /* Match Control Register */ +#define LPC17_TMR_MR0_OFFSET 0x0018 /* Match Register 0 */ +#define LPC17_TMR_MR1_OFFSET 0x001c /* Match Register 1 */ +#define LPC17_TMR_MR2_OFFSET 0x0020 /* Match Register 2 */ +#define LPC17_TMR_MR3_OFFSET 0x0024 /* Match Register 3 */ +#define LPC17_TMR_CCR_OFFSET 0x0028 /* Capture Control Register */ +#define LPC17_TMR_CR0_OFFSET 0x002c /* Capture Register 0 */ +#define LPC17_TMR_CR1_OFFSET 0x0030 /* Capture Register 1 */ +#define LPC17_TMR_EMR_OFFSET 0x003c /* External Match Register */ +#define LPC17_TMR_CTCR_OFFSET 0x0070 /* Count Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC17_TMR0_IR (LPC17_TMR0_BASE+LPC17_TMR_IR_OFFSET) +#define LPC17_TMR0_TCR (LPC17_TMR0_BASE+LPC17_TMR_TCR_OFFSET) +#define LPC17_TMR0_TC (LPC17_TMR0_BASE+LPC17_TMR_TC_OFFSET) +#define LPC17_TMR0_PR (LPC17_TMR0_BASE+LPC17_TMR_PR_OFFSET) +#define LPC17_TMR0_PC (LPC17_TMR0_BASE+LPC17_TMR_PC_OFFSET) +#define LPC17_TMR0_MCR (LPC17_TMR0_BASE+LPC17_TMR_MCR_OFFSET) +#define LPC17_TMR0_MR0 (LPC17_TMR0_BASE+LPC17_TMR_MR0_OFFSET) +#define LPC17_TMR0_MR1 (LPC17_TMR0_BASE+LPC17_TMR_MR1_OFFSET) +#define LPC17_TMR0_MR2 (LPC17_TMR0_BASE+LPC17_TMR_MR2_OFFSET) +#define LPC17_TMR0_MR3 (LPC17_TMR0_BASE+LPC17_TMR_MR3_OFFSET) +#define LPC17_TMR0_CCR (LPC17_TMR0_BASE+LPC17_TMR_CCR_OFFSET) +#define LPC17_TMR0_CR0 (LPC17_TMR0_BASE+LPC17_TMR_CR0_OFFSET) +#define LPC17_TMR0_CR1 (LPC17_TMR0_BASE+LPC17_TMR_CR1_OFFSET) +#define LPC17_TMR0_EMR (LPC17_TMR0_BASE+LPC17_TMR_EMR_OFFSET) +#define LPC17_TMR0_CTCR (LPC17_TMR0_BASE+LPC17_TMR_CTCR_OFFSET) + +#define LPC17_TMR1_IR (LPC17_TMR1_BASE+LPC17_TMR_IR_OFFSET) +#define LPC17_TMR1_TCR (LPC17_TMR1_BASE+LPC17_TMR_TCR_OFFSET) +#define LPC17_TMR1_TC (LPC17_TMR1_BASE+LPC17_TMR_TC_OFFSET) +#define LPC17_TMR1_PR (LPC17_TMR1_BASE+LPC17_TMR_PR_OFFSET) +#define LPC17_TMR1_PC (LPC17_TMR1_BASE+LPC17_TMR_PC_OFFSET) +#define LPC17_TMR1_MCR (LPC17_TMR1_BASE+LPC17_TMR_MCR_OFFSET) +#define LPC17_TMR1_MR0 (LPC17_TMR1_BASE+LPC17_TMR_MR0_OFFSET) +#define LPC17_TMR1_MR1 (LPC17_TMR1_BASE+LPC17_TMR_MR1_OFFSET) +#define LPC17_TMR1_MR2 (LPC17_TMR1_BASE+LPC17_TMR_MR2_OFFSET) +#define LPC17_TMR1_MR3 (LPC17_TMR1_BASE+LPC17_TMR_MR3_OFFSET) +#define LPC17_TMR1_CCR (LPC17_TMR1_BASE+LPC17_TMR_CCR_OFFSET) +#define LPC17_TMR1_CR0 (LPC17_TMR1_BASE+LPC17_TMR_CR0_OFFSET) +#define LPC17_TMR1_CR1 (LPC17_TMR1_BASE+LPC17_TMR_CR1_OFFSET) +#define LPC17_TMR1_EMR (LPC17_TMR1_BASE+LPC17_TMR_EMR_OFFSET) +#define LPC17_TMR1_CTCR (LPC17_TMR1_BASE+LPC17_TMR_CTCR_OFFSET) + +#define LPC17_TMR2_IR (LPC17_TMR2_BASE+LPC17_TMR_IR_OFFSET) +#define LPC17_TMR2_TCR (LPC17_TMR2_BASE+LPC17_TMR_TCR_OFFSET) +#define LPC17_TMR2_TC (LPC17_TMR2_BASE+LPC17_TMR_TC_OFFSET) +#define LPC17_TMR2_PR (LPC17_TMR2_BASE+LPC17_TMR_PR_OFFSET) +#define LPC17_TMR2_PC (LPC17_TMR2_BASE+LPC17_TMR_PC_OFFSET) +#define LPC17_TMR2_MCR (LPC17_TMR2_BASE+LPC17_TMR_MCR_OFFSET) +#define LPC17_TMR2_MR0 (LPC17_TMR2_BASE+LPC17_TMR_MR0_OFFSET) +#define LPC17_TMR2_MR1 (LPC17_TMR2_BASE+LPC17_TMR_MR1_OFFSET) +#define LPC17_TMR2_MR2 (LPC17_TMR2_BASE+LPC17_TMR_MR2_OFFSET) +#define LPC17_TMR2_MR3 (LPC17_TMR2_BASE+LPC17_TMR_MR3_OFFSET) +#define LPC17_TMR2_CCR (LPC17_TMR2_BASE+LPC17_TMR_CCR_OFFSET) +#define LPC17_TMR2_CR0 (LPC17_TMR2_BASE+LPC17_TMR_CR0_OFFSET) +#define LPC17_TMR2_CR1 (LPC17_TMR2_BASE+LPC17_TMR_CR1_OFFSET) +#define LPC17_TMR2_EMR (LPC17_TMR2_BASE+LPC17_TMR_EMR_OFFSET) +#define LPC17_TMR2_CTCR (LPC17_TMR2_BASE+LPC17_TMR_CTCR_OFFSET) + +#define LPC17_TMR3_IR (LPC17_TMR3_BASE+LPC17_TMR_IR_OFFSET) +#define LPC17_TMR3_TCR (LPC17_TMR3_BASE+LPC17_TMR_TCR_OFFSET) +#define LPC17_TMR3_TC (LPC17_TMR3_BASE+LPC17_TMR_TC_OFFSET) +#define LPC17_TMR3_PR (LPC17_TMR3_BASE+LPC17_TMR_PR_OFFSET) +#define LPC17_TMR3_PC (LPC17_TMR3_BASE+LPC17_TMR_PC_OFFSET) +#define LPC17_TMR3_MCR (LPC17_TMR3_BASE+LPC17_TMR_MCR_OFFSET) +#define LPC17_TMR3_MR0 (LPC17_TMR3_BASE+LPC17_TMR_MR0_OFFSET) +#define LPC17_TMR3_MR1 (LPC17_TMR3_BASE+LPC17_TMR_MR1_OFFSET) +#define LPC17_TMR3_MR2 (LPC17_TMR3_BASE+LPC17_TMR_MR2_OFFSET) +#define LPC17_TMR3_MR3 (LPC17_TMR3_BASE+LPC17_TMR_MR3_OFFSET) +#define LPC17_TMR3_CCR (LPC17_TMR3_BASE+LPC17_TMR_CCR_OFFSET) +#define LPC17_TMR3_CR0 (LPC17_TMR3_BASE+LPC17_TMR_CR0_OFFSET) +#define LPC17_TMR3_CR1 (LPC17_TMR3_BASE+LPC17_TMR_CR1_OFFSET) +#define LPC17_TMR3_EMR (LPC17_TMR3_BASE+LPC17_TMR_EMR_OFFSET) +#define LPC17_TMR3_CTCR (LPC17_TMR3_BASE+LPC17_TMR_CTCR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Registers holding 32-bit numeric values (no bit field definitions): + * + * Timer Counter (TC) + * Prescale Register (PR) + * Prescale Counter (PC) + * Match Register 0 (MR0) + * Match Register 1 (MR1) + * Match Register 2 (MR2) + * Match Register 3 (MR3) + * Capture Register 0 (CR0) + * Capture Register 1 (CR1) + */ + +/* Interrupt Register */ + +#define TMR_IR_MR0 (1 << 0) /* Bit 0: Match channel 0 interrupt */ +#define TMR_IR_MR1 (1 << 1) /* Bit 1: Match channel 1 interrupt */ +#define TMR_IR_MR2 (1 << 2) /* Bit 2: Match channel 2 interrupt */ +#define TMR_IR_MR3 (1 << 3) /* Bit 3: Match channel 3 interrupt */ +#define TMR_IR_CR0 (1 << 4) /* Bit 4: Capture channel 0 interrupt */ +#define TMR_IR_CR1 (1 << 5) /* Bit 5: Capture channel 1 interrupt */ + /* Bits 6-31: Reserved */ +/* Timer Control Register */ + +#define TMR_TCR_EN (1 << 0) /* Bit 0: Counter Enable */ +#define TMR_TCR_RESET (1 << 1) /* Bit 1: Counter Reset */ + /* Bits 2-31: Reserved */ +/* Match Control Register */ + +#define TMR_MCR_MR0I (1 << 0) /* Bit 0: Interrupt on MR0 */ +#define TMR_MCR_MR0R (1 << 1) /* Bit 1: Reset on MR0 */ +#define TMR_MCR_MR0S (1 << 2) /* Bit 2: Stop on MR0 */ +#define TMR_MCR_MR1I (1 << 3) /* Bit 3: Interrupt on MR1 */ +#define TMR_MCR_MR1R (1 << 4) /* Bit 4: Reset on MR1 */ +#define TMR_MCR_MR1S (1 << 5) /* Bit 5: Stop on MR1 */ +#define TMR_MCR_MR2I (1 << 6) /* Bit 6: Interrupt on MR2 */ +#define TMR_MCR_MR2R (1 << 7) /* Bit 7: Reset on MR2 */ +#define TMR_MCR_MR2S (1 << 8) /* Bit 8: Stop on MR2 */ +#define TMR_MCR_MR3I (1 << 9) /* Bit 9: Interrupt on MR3 */ +#define TMR_MCR_MR3R (1 << 10) /* Bit 10: Reset on MR3 */ +#define TMR_MCR_MR3S (1 << 11) /* Bit 11: Stop on MR3 */ + /* Bits 12-31: Reserved */ +/* Capture Control Register */ + +#define TMR_CCR_CAP0RE (1 << 0) /* Bit 0: Capture on CAPn.0 rising edge */ +#define TMR_CCR_CAP0FE (1 << 1) /* Bit 1: Capture on CAPn.0 falling edge */ +#define TMR_CCR_CAP0I (1 << 2) /* Bit 2: Interrupt on CAPn.0 */ +#define TMR_CCR_CAP1RE (1 << 3) /* Bit 3: Capture on CAPn.1 rising edge */ +#define TMR_CCR_CAP1FE (1 << 4) /* Bit 4: Capture on CAPn.1 falling edge */ +#define TMR_CCR_CAP1I (1 << 5) /* Bit 5: Interrupt on CAPn.1 */ + /* Bits 6-31: Reserved */ +/* External Match Register */ + +#define TMR_EMR_NOTHING (0) /* Do Nothing */ +#define TMR_EMR_CLEAR (1) /* Clear external match bit MATn.m */ +#define TMR_EMR_SET (2) /* Set external match bit MATn.m */ +#define TMR_EMR_TOGGLE (3) /* Toggle external match bit MATn.m */ + +#define TMR_EMR_EM0 (1 << 0) /* Bit 0: External Match 0 */ +#define TMR_EMR_EM1 (1 << 1) /* Bit 1: External Match 1 */ +#define TMR_EMR_EM2 (1 << 2) /* Bit 2: External Match 2 */ +#define TMR_EMR_EM3 (1 << 3) /* Bit 3: External Match 3 */ +#define TMR_EMR_EMC0_SHIFT (4) /* Bits 4-5: External Match Control 0 */ +#define TMR_EMR_EMC0_MASK (3 << TMR_EMR_EMC0_SHIFTy) +# define TMR_EMR_EMC0_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_SET (TMR_EMR_SET << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC0_SHIFT) +#define TMR_EMR_EMC1_SHIFT (6) /* Bits 6-7: External Match Control 1 */ +#define TMR_EMR_EMC1_MASK (3 << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_SET (TMR_EMR_SET << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC1_SHIFT) +#define TMR_EMR_EMC2_SHIFT (8) /* Bits 8-9: External Match Control 2 */ +#define TMR_EMR_EMC2_MASK (3 << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_SET (TMR_EMR_SET << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC2_SHIFT) +#define TMR_EMR_EMC3_SHIFT (10) /* Bits 10-11: External Match Control 3 */ +#define TMR_EMR_EMC3_MASK (3 << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_SET (TMR_EMR_SET << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC3_SHIFT) + /* Bits 12-31: Reserved */ +/* Count Control Register */ + +#define TMR_CTCR_MODE_SHIFT (0) /* Bits 0-1: Counter/Timer Mode */ +#define TMR_CTCR_MODE_MASK (3 << TMR_CTCR_MODE_SHIFT) +# define TMR_CTCR_MODE_TIMER (0 << TMR_CTCR_MODE_SHIFT) /* Timer Mode, prescale match */ +# define TMR_CTCR_MODE_CNTRRE (1 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP rising edge */ +# define TMR_CTCR_MODE_CNTRFE (2 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP falling edge */ +# define TMR_CTCR_MODE_CNTRBE (3 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP both edges */ +#define TMR_CTCR_INPSEL_SHIFT (2) /* Bits 2-3: Count Input Select */ +#define TMR_CTCR_INPSEL_MASK (3 << TMR_CTCR_INPSEL_SHIFT) +# define TMR_CTCR_INPSEL_CAPNp0 (0 << TMR_CTCR_INPSEL_SHIFT) /* CAPn.0 for TIMERn */ +# define TMR_CTCR_INPSEL_CAPNp1 (1 << TMR_CTCR_INPSEL_SHIFT) /* CAPn.1 for TIMERn */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_TIMER_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_uart.h b/arch/arm/src/lpc17xx/chip/lpc17_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..d7706561cd8a31abf94b07c317582f00d1255041 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_uart.h @@ -0,0 +1,414 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_uart.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_UART_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_UART_RBR_OFFSET 0x0000 /* (DLAB =0) Receiver Buffer Register (all) */ +#define LPC17_UART_THR_OFFSET 0x0000 /* (DLAB =0) Transmit Holding Register (all) */ +#define LPC17_UART_DLL_OFFSET 0x0000 /* (DLAB =1) Divisor Latch LSB (all) */ +#define LPC17_UART_DLM_OFFSET 0x0004 /* (DLAB =1) Divisor Latch MSB (all) */ +#define LPC17_UART_IER_OFFSET 0x0004 /* (DLAB =0) Interrupt Enable Register (all) */ +#define LPC17_UART_IIR_OFFSET 0x0008 /* Interrupt ID Register (all) */ +#define LPC17_UART_FCR_OFFSET 0x0008 /* FIFO Control Register (all) */ +#define LPC17_UART_LCR_OFFSET 0x000c /* Line Control Register (all) */ +#define LPC17_UART_MCR_OFFSET 0x0010 /* Modem Control Register (UART1 only) */ +#define LPC17_UART_LSR_OFFSET 0x0014 /* Line Status Register (all) */ +#define LPC17_UART_MSR_OFFSET 0x0018 /* Modem Status Register (UART1 only) */ +#define LPC17_UART_SCR_OFFSET 0x001c /* Scratch Pad Register (all) */ +#define LPC17_UART_ACR_OFFSET 0x0020 /* Auto-baud Control Register (all) */ +#define LPC17_UART_ICR_OFFSET 0x0024 /* IrDA Control Register (UART0,2,3 only) */ +#define LPC17_UART_FDR_OFFSET 0x0028 /* Fractional Divider Register (all) */ +#define LPC17_UART_TER_OFFSET 0x0030 /* Transmit Enable Register (all) */ +#define LPC17_UART_RS485CTRL_OFFSET 0x004c /* RS-485/EIA-485 Control (UART1 only) */ +#define LPC17_UART_ADRMATCH_OFFSET 0x0050 /* RS-485/EIA-485 address match (UART1 only) */ +#define LPC17_UART_RS485DLY_OFFSET 0x0054 /* RS-485/EIA-485 direction control delay (UART1 only) */ +#define LPC17_UART_FIFOLVL_OFFSET 0x0058 /* FIFO Level register (all) */ + +#ifdef LPC178x +# define LPC17_UART_OSR_OFFSET 0x002c /* Oversampling Register (UART4 only) */ +# define LPC17_UART_SCICTRL_OFFSET 0x0048 /* Smart Card Interface Register (UART4 only) */ +# define LPC17_UART_SYNCCTRL_OFFSET 0x0058 /* Synchronous Mode Register (UART4 only) */ +#endif + +/* Register addresses ***************************************************************/ + +#define LPC17_UART0_RBR (LPC17_UART0_BASE+LPC17_UART_RBR_OFFSET) +#define LPC17_UART0_THR (LPC17_UART0_BASE+LPC17_UART_THR_OFFSET) +#define LPC17_UART0_DLL (LPC17_UART0_BASE+LPC17_UART_DLL_OFFSET) +#define LPC17_UART0_DLM (LPC17_UART0_BASE+LPC17_UART_DLM_OFFSET) +#define LPC17_UART0_IER (LPC17_UART0_BASE+LPC17_UART_IER_OFFSET) +#define LPC17_UART0_IIR (LPC17_UART0_BASE+LPC17_UART_IIR_OFFSET) +#define LPC17_UART0_FCR (LPC17_UART0_BASE+LPC17_UART_FCR_OFFSET) +#define LPC17_UART0_LCR (LPC17_UART0_BASE+LPC17_UART_LCR_OFFSET) +#define LPC17_UART0_LSR (LPC17_UART0_BASE+LPC17_UART_LSR_OFFSET) +#define LPC17_UART0_SCR (LPC17_UART0_BASE+LPC17_UART_SCR_OFFSET) +#define LPC17_UART0_ACR (LPC17_UART0_BASE+LPC17_UART_ACR_OFFSET) +#define LPC17_UART0_ICR (LPC17_UART0_BASE+LPC17_UART_ICR_OFFSET) +#define LPC17_UART0_FDR (LPC17_UART0_BASE+LPC17_UART_FDR_OFFSET) +#define LPC17_UART0_TER (LPC17_UART0_BASE+LPC17_UART_TER_OFFSET) + +#ifdef LPC178x +# define LPC17_UART0_RS485CTRL (LPC17_UART0_BASE+LPC17_UART_RS485CTRL_OFFSET) +# define LPC17_UART0_ADRMATCH (LPC17_UART0_BASE+LPC17_UART_ADRMATCH_OFFSET) +# define LPC17_UART0_RS485DLY (LPC17_UART0_BASE+LPC17_UART_RS485DLY_OFFSET) +#endif + +#define LPC17_UART0_FIFOLVL (LPC17_UART0_BASE+LPC17_UART_FIFOLVL_OFFSET) + +#define LPC17_UART1_RBR (LPC17_UART1_BASE+LPC17_UART_RBR_OFFSET) +#define LPC17_UART1_THR (LPC17_UART1_BASE+LPC17_UART_THR_OFFSET) +#define LPC17_UART1_DLL (LPC17_UART1_BASE+LPC17_UART_DLL_OFFSET) +#define LPC17_UART1_DLM (LPC17_UART1_BASE+LPC17_UART_DLM_OFFSET) +#define LPC17_UART1_IER (LPC17_UART1_BASE+LPC17_UART_IER_OFFSET) +#define LPC17_UART1_IIR (LPC17_UART1_BASE+LPC17_UART_IIR_OFFSET) +#define LPC17_UART1_FCR (LPC17_UART1_BASE+LPC17_UART_FCR_OFFSET) +#define LPC17_UART1_LCR (LPC17_UART1_BASE+LPC17_UART_LCR_OFFSET) +#define LPC17_UART1_MCR (LPC17_UART1_BASE+LPC17_UART_MCR_OFFSET) +#define LPC17_UART1_LSR (LPC17_UART1_BASE+LPC17_UART_LSR_OFFSET) +#define LPC17_UART1_MSR (LPC17_UART1_BASE+LPC17_UART_MSR_OFFSET) +#define LPC17_UART1_SCR (LPC17_UART1_BASE+LPC17_UART_SCR_OFFSET) +#define LPC17_UART1_ACR (LPC17_UART1_BASE+LPC17_UART_ACR_OFFSET) +#define LPC17_UART1_FDR (LPC17_UART1_BASE+LPC17_UART_FDR_OFFSET) +#define LPC17_UART1_TER (LPC17_UART1_BASE+LPC17_UART_TER_OFFSET) +#define LPC17_UART1_RS485CTRL (LPC17_UART1_BASE+LPC17_UART_RS485CTRL_OFFSET) +#define LPC17_UART1_ADRMATCH (LPC17_UART1_BASE+LPC17_UART_ADRMATCH_OFFSET) +#define LPC17_UART1_RS485DLY (LPC17_UART1_BASE+LPC17_UART_RS485DLY_OFFSET) +#define LPC17_UART1_FIFOLVL (LPC17_UART1_BASE+LPC17_UART_FIFOLVL_OFFSET) + +#define LPC17_UART2_RBR (LPC17_UART2_BASE+LPC17_UART_RBR_OFFSET) +#define LPC17_UART2_THR (LPC17_UART2_BASE+LPC17_UART_THR_OFFSET) +#define LPC17_UART2_DLL (LPC17_UART2_BASE+LPC17_UART_DLL_OFFSET) +#define LPC17_UART2_DLM (LPC17_UART2_BASE+LPC17_UART_DLM_OFFSET) +#define LPC17_UART2_IER (LPC17_UART2_BASE+LPC17_UART_IER_OFFSET) +#define LPC17_UART2_IIR (LPC17_UART2_BASE+LPC17_UART_IIR_OFFSET) +#define LPC17_UART2_FCR (LPC17_UART2_BASE+LPC17_UART_FCR_OFFSET) +#define LPC17_UART2_LCR (LPC17_UART2_BASE+LPC17_UART_LCR_OFFSET) +#define LPC17_UART2_LSR (LPC17_UART2_BASE+LPC17_UART_LSR_OFFSET) +#define LPC17_UART2_SCR (LPC17_UART2_BASE+LPC17_UART_SCR_OFFSET) +#define LPC17_UART2_ACR (LPC17_UART2_BASE+LPC17_UART_ACR_OFFSET) +#define LPC17_UART2_ICR (LPC17_UART2_BASE+LPC17_UART_ICR_OFFSET) +#define LPC17_UART2_FDR (LPC17_UART2_BASE+LPC17_UART_FDR_OFFSET) +#define LPC17_UART2_TER (LPC17_UART2_BASE+LPC17_UART_TER_OFFSET) + +#ifdef LPC178x +# define LPC17_UART2_RS485CTRL (LPC17_UART2_BASE+LPC17_UART_RS485CTRL_OFFSET) +# define LPC17_UART2_ADRMATCH (LPC17_UART2_BASE+LPC17_UART_ADRMATCH_OFFSET) +# define LPC17_UART2_RS485DLY (LPC17_UART2_BASE+LPC17_UART_RS485DLY_OFFSET) +#endif + +#define LPC17_UART2_FIFOLVL (LPC17_UART2_BASE+LPC17_UART_FIFOLVL_OFFSET) + +#define LPC17_UART3_RBR (LPC17_UART3_BASE+LPC17_UART_RBR_OFFSET) +#define LPC17_UART3_THR (LPC17_UART3_BASE+LPC17_UART_THR_OFFSET) +#define LPC17_UART3_DLL (LPC17_UART3_BASE+LPC17_UART_DLL_OFFSET) +#define LPC17_UART3_DLM (LPC17_UART3_BASE+LPC17_UART_DLM_OFFSET) +#define LPC17_UART3_IER (LPC17_UART3_BASE+LPC17_UART_IER_OFFSET) +#define LPC17_UART3_IIR (LPC17_UART3_BASE+LPC17_UART_IIR_OFFSET) +#define LPC17_UART3_FCR (LPC17_UART3_BASE+LPC17_UART_FCR_OFFSET) +#define LPC17_UART3_LCR (LPC17_UART3_BASE+LPC17_UART_LCR_OFFSET) +#define LPC17_UART3_LSR (LPC17_UART3_BASE+LPC17_UART_LSR_OFFSET) +#define LPC17_UART3_SCR (LPC17_UART3_BASE+LPC17_UART_SCR_OFFSET) +#define LPC17_UART3_ACR (LPC17_UART3_BASE+LPC17_UART_ACR_OFFSET) +#define LPC17_UART3_ICR (LPC17_UART3_BASE+LPC17_UART_ICR_OFFSET) +#define LPC17_UART3_FDR (LPC17_UART3_BASE+LPC17_UART_FDR_OFFSET) +#define LPC17_UART3_TER (LPC17_UART3_BASE+LPC17_UART_TER_OFFSET) + +#ifdef LPC178x +# define LPC17_UART3_RS485CTRL (LPC17_UART3_BASE+LPC17_UART_RS485CTRL_OFFSET) +# define LPC17_UART3_ADRMATCH (LPC17_UART3_BASE+LPC17_UART_ADRMATCH_OFFSET) +# define LPC17_UART3_RS485DLY (LPC17_UART3_BASE+LPC17_UART_RS485DLY_OFFSET) +#endif + +#define LPC17_UART3_FIFOLVL (LPC17_UART3_BASE+LPC17_UART_FIFOLVL_OFFSET) + +#ifdef LPC178x +# define LPC17_UART4_RBR (LPC17_UART4_BASE+LPC17_UART_RBR_OFFSET) +# define LPC17_UART4_THR (LPC17_UART4_BASE+LPC17_UART_THR_OFFSET) +# define LPC17_UART4_DLL (LPC17_UART4_BASE+LPC17_UART_DLL_OFFSET) +# define LPC17_UART4_DLM (LPC17_UART4_BASE+LPC17_UART_DLM_OFFSET) +# define LPC17_UART4_IER (LPC17_UART4_BASE+LPC17_UART_IER_OFFSET) +# define LPC17_UART4_IIR (LPC17_UART4_BASE+LPC17_UART_IIR_OFFSET) +# define LPC17_UART4_FCR (LPC17_UART4_BASE+LPC17_UART_FCR_OFFSET) +# define LPC17_UART4_LCR (LPC17_UART4_BASE+LPC17_UART_LCR_OFFSET) +# define LPC17_UART4_LSR (LPC17_UART4_BASE+LPC17_UART_LSR_OFFSET) +# define LPC17_UART4_SCR (LPC17_UART4_BASE+LPC17_UART_SCR_OFFSET) +# define LPC17_UART4_ACR (LPC17_UART4_BASE+LPC17_UART_ACR_OFFSET) +# define LPC17_UART4_ICR (LPC17_UART4_BASE+LPC17_UART_ICR_OFFSET) +# define LPC17_UART4_FDR (LPC17_UART4_BASE+LPC17_UART_FDR_OFFSET) +# define LPC17_UART4_TER (LPC17_UART4_BASE+LPC17_UART_TER_OFFSET) +# define LPC17_UART4_RS485CTRL (LPC17_UART4_BASE+LPC17_UART_RS485CTRL_OFFSET) +# define LPC17_UART4_ADRMATCH (LPC17_UART4_BASE+LPC17_UART_ADRMATCH_OFFSET) +# define LPC17_UART4_RS485DLY (LPC17_UART4_BASE+LPC17_UART_RS485DLY_OFFSET) +# define LPC17_UART4_FIFOLVL (LPC17_UART4_BASE+LPC17_UART_FIFOLVL_OFFSET) +# define LPC17_UART4_OSR (LPC17_UART4_BASE+LPC17_UART4_OSR_OFFSET) +# define LPC17_UART4_SCICTRL (LPC17_UART4_BASE+LPC17_UART4_SCICTRL_OFFSET) +# define LPC17_UART4_SYNCCTRL (LPC17_UART4_BASE+LPC17_UART4_SYNCCTRL_OFFSET) +#endif + +/* Register bit definitions *********************************************************/ + +/* RBR (DLAB =0) Receiver Buffer Register (all) */ + +#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */ + /* Bits 8-31: Reserved */ + +/* THR (DLAB =0) Transmit Holding Register (all) */ + +#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */ + /* Bits 8-31: Reserved */ + +/* DLL (DLAB =1) Divisor Latch LSB (all) */ + +#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */ + /* Bits 8-31: Reserved */ + +/* DLM (DLAB =1) Divisor Latch MSB (all) */ + +#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */ + /* Bits 8-31: Reserved */ + +/* IER (DLAB =0) Interrupt Enable Register (all) */ + +#define UART_IER_RBRIE (1 << 0) /* Bit 0: RBR Interrupt Enable */ +#define UART_IER_THREIE (1 << 1) /* Bit 1: THRE Interrupt Enable */ +#define UART_IER_RLSIE (1 << 2) /* Bit 2: RX Line Status Interrupt Enable */ +#define UART_IER_MSIE (1 << 3) /* Bit 3: Modem Status Interrupt Enable (UART1 only) */ + /* Bits 4-6: Reserved */ +#define UART_IER_CTSIE (1 << 7) /* Bit 7: CTS transition interrupt (UART1 only) */ +#define UART_IER_ABEOIE (1 << 8) /* Bit 8: Enables the end of auto-baud interrupt */ +#define UART_IER_ABTOIE (1 << 9) /* Bit 9: Enables the auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +#define UART_IER_ALLIE (0x038f) + +/* IIR Interrupt ID Register (all) */ + +#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */ +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status (UART1 only) */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THRE Interrupt */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* 2a - Receive Data Available (RDA) */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* 1 - Receive Line Status (RLS) */ +# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* 2b - Character Time-out Indicator (CTI) */ + /* Bits 4-5: Reserved */ +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: Copies of FCR bit 0 */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) +#define UART_IIR_ABEOINT (1 << 8) /* Bit 8: End of auto-baud interrupt */ +#define UART_IIR_ABTOINT (1 << 9) /* Bit 9: Auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +/* FCR FIFO Control Register (all) */ + +#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */ +#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */ +#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA Mode Select */ + /* Bits 4-5: Reserved */ +#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */ +#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT) +# define UART_FCR_RXTRIGGER_0 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 character) */ +# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 characters) */ +# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 characters) */ +# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 characters) */ + /* Bits 8-31: Reserved */ +/* LCR Line Control Register (all) */ + +#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_STOP (1 << 2) /* Bit 2: Stop Bit Select */ +#define UART_LCR_PE (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_PS_SHIFT (4) /* Bits 4-5: Parity Select */ +#define UART_LCR_PS_MASK (3 << UART_LCR_PS_SHIFT) +# define UART_LCR_PS_ODD (0 << UART_LCR_PS_SHIFT) /* Odd parity */ +# define UART_LCR_PS_EVEN (1 << UART_LCR_PS_SHIFT) /* Even Parity */ +# define UART_LCR_PS_STICK1 (2 << UART_LCR_PS_SHIFT) /* Forced "1" stick parity */ +# define UART_LCR_PS_STICK0 (3 << UART_LCR_PS_SHIFT) /* Forced "0" stick parity */ +#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */ + /* Bits 8-31: Reserved */ +/* MCR Modem Control Register (UART1 only) */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */ + /* Bits 2-3: Reserved */ +#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */ + /* Bit 5: Reserved */ +#define UART_MCR_RTSEN (1 << 6) /* Bit 6: Enable auto-rts flow control */ +#define UART_MCR_CTSEN (1 << 7) /* Bit 7: Enable auto-cts flow control */ + /* Bits 8-31: Reserved */ +/* LSR Line Status Register (all) */ + +#define UART_LSR_RDR (1 << 0) /* Bit 0: Receiver Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */ + /* Bits 8-31: Reserved */ +/* MSR Modem Status Register (UART1 only) */ + +#define UART_MSR_DELTACTS (1 << 0) /* Bit 0: CTS state change */ +#define UART_MSR_DELTADSR (1 << 1) /* Bit 1: DSR state change */ +#define UART_MSR_RIEDGE (1 << 2) /* Bit 2: RI ow to high transition */ +#define UART_MSR_DELTADCD (1 << 3) /* Bit 3: DCD state change */ +#define UART_MSR_CTS (1 << 4) /* Bit 4: CTS State */ +#define UART_MSR_DSR (1 << 5) /* Bit 5: DSR State */ +#define UART_MSR_RI (1 << 6) /* Bit 6: Ring Indicator State */ +#define UART_MSR_DCD (1 << 7) /* Bit 7: Data Carrier Detect State */ + /* Bits 8-31: Reserved */ +/* SCR Scratch Pad Register (all) */ + +#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */ + /* Bits 8-31: Reserved */ +/* ACR Auto-baud Control Register (all) */ + +#define UART_ACR_START (1 << 0) /* Bit 0: Auto-baud start/running*/ +#define UART_ACR_MODE (1 << 1) /* Bit 1: Auto-baud mode select*/ +#define UART_ACR_AUTORESTART (1 << 2) /* Bit 2: Restart in case of time-out*/ + /* Bits 3-7: Reserved */ +#define UART_ACR_ABEOINTCLR (1 << 8) /* Bit 8: End of auto-baud interrupt clear */ +#define UART_ACR_ABTOINTCLRT (1 << 9) /* Bit 9: Auto-baud time-out interrupt clear */ + /* Bits 10-31: Reserved */ +/* ICA IrDA Control Register (UART0,2,3 only) */ + +#define UART_ICR_IRDAEN (1 << 0) /* Bit 0: Enable IrDA mode */ +#define UART_ICR_IRDAINV (1 << 1) /* Bit 1: Invert serial input */ +#define UART_ICR_FIXPULSEEN (1 << 2) /* Bit 2: Enable IrDA fixed pulse width mode */ +#define UART_ICR_PULSEDIV_SHIFT (3) /* Bits 3-5: Configures the pulse when FixPulseEn = 1 */ +#define UART_ICR_PULSEDIV_MASK (7 << UART_ICR_PULSEDIV_SHIFT) +# define UART_ICR_PULSEDIV_2TPCLK (0 << UART_ICR_PULSEDIV_SHIFT) /* 2 x TPCLK */ +# define UART_ICR_PULSEDIV_4TPCLK (1 << UART_ICR_PULSEDIV_SHIFT) /* 4 x TPCLK */ +# define UART_ICR_PULSEDIV_8TPCLK (2 << UART_ICR_PULSEDIV_SHIFT) /* 8 x TPCLK */ +# define UART_ICR_PULSEDIV_16TPCLK (3 << UART_ICR_PULSEDIV_SHIFT) /* 16 x TPCLK */ +# define UART_ICR_PULSEDIV_32TPCLK (4 << UART_ICR_PULSEDIV_SHIFT) /* 32 x TPCLK */ +# define UART_ICR_PULSEDIV_64TPCLK (5 << UART_ICR_PULSEDIV_SHIFT) /* 64 x TPCLK */ +# define UART_ICR_PULSEDIV_128TPCLK (6 << UART_ICR_PULSEDIV_SHIFT) /* 128 x TPCLK */ +# define UART_ICR_PULSEDIV_256TPCLK (7 << UART_ICR_PULSEDIV_SHIFT) /* 246 x TPCLK */ + /* Bits 6-31: Reserved */ +/* FDR Fractional Divider Register (all) */ + +#define UART_FDR_DIVADDVAL_SHIFT (0) /* Bits 0-3: Baud-rate generation pre-scaler divisor value */ +#define UART_FDR_DIVADDVAL_MASK (15 << UART_FDR_DIVADDVAL_SHIFT) +#define UART_FDR_MULVAL_SHIFT (3) /* Bits 4-7 Baud-rate pre-scaler multiplier value */ +#define UART_FDR_MULVAL_MASK (15 << UART_FDR_MULVAL_SHIFT) + /* Bits 8-31: Reserved */ +/* TER Transmit Enable Register (all) */ + /* Bits 0-6: Reserved */ +#define UART_TER_TXEN (1 << 7) /* Bit 7: TX Enable */ + /* Bits 8-31: Reserved */ +/* RS-485/EIA-485 Control (UART1 only) */ + +#define UART_RS485CTRL_NMMEN (1 << 0) /* Bit 0: RS-485/EIA-485 Normal Multidrop Mode (NMM) enabled */ +#define UART_RS485CTRL_RXDIS (1 << 1) /* Bit 1: Receiver is disabled */ +#define UART_RS485CTRL_AADEN (1 << 2) /* Bit 2: Auto Address Detect (AAD) is enabled */ +#define UART_RS485CTRL_SEL (1 << 3) /* Bit 3: RTS/DTR used for direction control (DCTRL=1) */ +#define UART_RS485CTRL_DCTRL (1 << 4) /* Bit 4: Enable Auto Direction Control */ +#define UART_RS485CTRL_OINV (1 << 5) /* Bit 5: Polarity of the direction control signal on RTS/DTR */ + /* Bits 6-31: Reserved */ +/* RS-485/EIA-485 address match (UART1 only) */ + +#define UART_ADRMATCH_MASK (0xff) /* Bits 0-7: Address match value */ + /* Bits 8-31: Reserved */ +/* RS-485/EIA-485 direction control delay (UART1 only) */ + +#define UART_RS485DLY_MASK (0xff) /* Bits 0-7: Direction control (RTS/DTR) delay */ + /* Bits 8-31: Reserved */ +/* FIFOLVL FIFO Level register (all) */ + +#define UART_FIFOLVL_RX_SHIFT (0) /* Bits 0-3: Current level of the UART RX FIFO */ +#define UART_FIFOLVL_RX_MASK (15 << UART_FIFOLVL_RX_SHIFT) + /* Bits 4-7: Reserved */ +#define UART_FIFOLVL_TX_SHIFT (8) /* Bits 8-11: Current level of the UART TX FIFO */ +#define UART_FIFOLVL_TX_MASK (15 << UART_FIFOLVL_TX_SHIFT) + /* Bits 12-31: Reserved */ + +/* SCICTL Smart Card Interface (UART4 only) */ + +#ifdef LPC178x +# define UART_SCIEN (1 << 0) /* Bit 0: Smart Card Interface enable */ +# define UART_NACKDIS (1 << 1) /* Bit 1: NACK response disable.Applicable if PROTSEL=0 */ +# define UART_PROTSEL (1 << 2) /* Bit 2: Protocol Selection ISO7816-3 */ +# define UART_TXRETRY (7 << 5) /* Bits 5-7: Maximum number of Re-Transmission */ +# define UART_GUARDTIME_SHIFT (8) /* Bits 8-15: Extra guard time */ +# define UART_GUARDTIME_MASK (0xff << UART_GUARDTIME_SHIFT) + /* Bits 16-31: Reserved */ +#endif + +/* OSR Oversampling Register (UART4 only) */ + +#ifdef LPC178x + /* Bit 0: Reserved */ +# define UART_OSFRAC (7 << 1) /* Bits 1-3: Fractional part of Oversampling Ratio */ +# define UART_OSINT_SHIFT (4) /* Bits 4-7: Integer part of (Oversampling Ratio -1) */ +# define UART_OSINT_MASK (0x0f << UART_OSINT_SHIFT) +# define UART_FDINT_SHIFT (8) /* Bits 8-14: OSINT extension in Smart Card mode */ +# define UART_FDINT_MASK (0x7f << UART_FDINT_SHIFT) + /* Bits 15-31: Reserved */ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_UART_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_usb.h b/arch/arm/src/lpc17xx/chip/lpc17_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..32b02455c5868bf092a6c0f1369ab5d54cb2c2a9 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_usb.h @@ -0,0 +1,778 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_usb.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_USB_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_USB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* USB Host Controller (OHCI) *******************************************************/ +/* See include/nuttx/usb/ohci.h */ + +#define LPC17_USBHOST_MODID_OFFSET 0x00fc /* Module ID/Revision ID */ + +/* USB OTG Controller ***************************************************************/ +/* OTG registers */ + +#define LPC17_USBOTG_INTST_OFFSET 0x0100 /* OTG Interrupt Status */ +#define LPC17_USBOTG_INTEN_OFFSET 0x0104 /* OTG Interrupt Enable */ +#define LPC17_USBOTG_INTSET_OFFSET 0x0108 /* OTG Interrupt Set */ +#define LPC17_USBOTG_INTCLR_OFFSET 0x010c /* OTG Interrupt Clear */ +#define LPC17_USBOTG_STCTRL_OFFSET 0x0110 /* OTG Status and Control */ +#define LPC17_USBOTG_TMR_OFFSET 0x0114 /* OTG Timer */ + +/* USB Device Controller ************************************************************/ +/* Device interrupt registers. See also SYSCON_USBINTST in lpc17_syscon.h */ + +#define LPC17_USBDEV_INTST_OFFSET 0x0200 /* USB Device Interrupt Status */ +#define LPC17_USBDEV_INTEN_OFFSET 0x0204 /* USB Device Interrupt Enable */ +#define LPC17_USBDEV_INTCLR_OFFSET 0x0208 /* USB Device Interrupt Clear */ +#define LPC17_USBDEV_INTSET_OFFSET 0x020c /* USB Device Interrupt Set */ + +/* SIE Command registers */ + +#define LPC17_USBDEV_CMDCODE_OFFSET 0x0210 /* USB Command Code */ +#define LPC17_USBDEV_CMDDATA_OFFSET 0x0214 /* USB Command Data */ + +/* USB transfer registers */ + +#define LPC17_USBDEV_RXDATA_OFFSET 0x0218 /* USB Receive Data */ +#define LPC17_USBDEV_RXPLEN_OFFSET 0x0220 /* USB Receive Packet Length */ +#define LPC17_USBDEV_TXDATA_OFFSET 0x021c /* USB Transmit Data */ +#define LPC17_USBDEV_TXPLEN_OFFSET 0x0224 /* USB Transmit Packet Length */ +#define LPC17_USBDEV_CTRL_OFFSET 0x0228 /* USB Control */ + +/* More Device interrupt registers */ + +#define LPC17_USBDEV_INTPRI_OFFSET 0x022c /* USB Device Interrupt Priority */ + +/* Endpoint interrupt registers */ + +#define LPC17_USBDEV_EPINTST_OFFSET 0x0230 /* USB Endpoint Interrupt Status */ +#define LPC17_USBDEV_EPINTEN_OFFSET 0x0234 /* USB Endpoint Interrupt Enable */ +#define LPC17_USBDEV_EPINTCLR_OFFSET 0x0238 /* USB Endpoint Interrupt Clear */ +#define LPC17_USBDEV_EPINTSET_OFFSET 0x023c /* USB Endpoint Interrupt Set */ +#define LPC17_USBDEV_EPINTPRI_OFFSET 0x0240 /* USB Endpoint Priority */ + +/* Endpoint realization registers */ + +#define LPC17_USBDEV_REEP_OFFSET 0x0244 /* USB Realize Endpoint */ +#define LPC17_USBDEV_EPIND_OFFSET 0x0248 /* USB Endpoint Index */ +#define LPC17_USBDEV_MAXPSIZE_OFFSET 0x024c /* USB MaxPacketSize */ + +/* DMA registers */ + +#define LPC17_USBDEV_DMARST_OFFSET 0x0250 /* USB DMA Request Status */ +#define LPC17_USBDEV_DMARCLR_OFFSET 0x0254 /* USB DMA Request Clear */ +#define LPC17_USBDEV_DMARSET_OFFSET 0x0258 /* USB DMA Request Set */ +#define LPC17_USBDEV_UDCAH_OFFSET 0x0280 /* USB UDCA Head */ +#define LPC17_USBDEV_EPDMAST_OFFSET 0x0284 /* USB Endpoint DMA Status */ +#define LPC17_USBDEV_EPDMAEN_OFFSET 0x0288 /* USB Endpoint DMA Enable */ +#define LPC17_USBDEV_EPDMADIS_OFFSET 0x028c /* USB Endpoint DMA Disable */ +#define LPC17_USBDEV_DMAINTST_OFFSET 0x0290 /* USB DMA Interrupt Status */ +#define LPC17_USBDEV_DMAINTEN_OFFSET 0x0294 /* USB DMA Interrupt Enable */ +#define LPC17_USBDEV_EOTINTST_OFFSET 0x02a0 /* USB End of Transfer Interrupt Status */ +#define LPC17_USBDEV_EOTINTCLR_OFFSET 0x02a4 /* USB End of Transfer Interrupt Clear */ +#define LPC17_USBDEV_EOTINTSET_OFFSET 0x02a8 /* USB End of Transfer Interrupt Set */ +#define LPC17_USBDEV_NDDRINTST_OFFSET 0x02ac /* USB New DD Request Interrupt Status */ +#define LPC17_USBDEV_NDDRINTCLR_OFFSET 0x02b0 /* USB New DD Request Interrupt Clear */ +#define LPC17_USBDEV_NDDRINTSET_OFFSET 0x02b4 /* USB New DD Request Interrupt Set */ +#define LPC17_USBDEV_SYSERRINTST_OFFSET 0x02b8 /* USB System Error Interrupt Status */ +#define LPC17_USBDEV_SYSERRINTCLR_OFFSET 0x02bc /* USB System Error Interrupt Clear */ +#define LPC17_USBDEV_SYSERRINTSET_OFFSET 0x02c0 /* USB System Error Interrupt Set */ + +/* OTG I2C registers ****************************************************************/ + +#define LPC17_OTGI2C_RX_OFFSET 0x0300 /* I2C Receive */ +#define LPC17_OTGI2C_TX_OFFSET 0x0300 /* I2C Transmit */ +#define LPC17_OTGI2C_STS_OFFSET 0x0304 /* I2C Status */ +#define LPC17_OTGI2C_CTL_OFFSET 0x0308 /* I2C Control */ +#define LPC17_OTGI2C_CLKHI_OFFSET 0x030c /* I2C Clock High */ +#define LPC17_OTGI2C_CLKLO_OFFSET 0x0310 /* I2C Clock Low */ + +/* Clock control registers ***********************************************************/ + +#define LPC17_USBOTG_CLKCTRL_OFFSET 0x0ff4 /* OTG clock controller */ +#define LPC17_USBOTG_CLKST_OFFSET 0x0ff8 /* OTG clock status */ + +#define LPC17_USBDEV_CLKCTRL_OFFSET 0x0ff4 /* USB Clock Control */ +#define LPC17_USBDEV_CLKST_OFFSET 0x0ff8 /* USB Clock Status */ + +/* Register addresses ***************************************************************/ +/* USB Host Controller (OHCI) *******************************************************/ +/* Control and status registers (section 7.1) */ + +#define LPC17_USBHOST_HCIREV (LPC17_USB_BASE+OHCI_HCIREV_OFFSET) +#define LPC17_USBHOST_CTRL (LPC17_USB_BASE+OHCI_CTRL_OFFSET) +#define LPC17_USBHOST_CMDST (LPC17_USB_BASE+OHCI_CMDST_OFFSET) +#define LPC17_USBHOST_INTST (LPC17_USB_BASE+OHCI_INTST_OFFSET) +#define LPC17_USBHOST_INTEN (LPC17_USB_BASE+OHCI_INTEN_OFFSET) +#define LPC17_USBHOST_INTDIS (LPC17_USB_BASE+OHCI_INTDIS_OFFSET) + +/* Memory pointers (section 7.2) */ + +#define LPC17_USBHOST_HCCA (LPC17_USB_BASE+OHCI_HCCA_OFFSET) +#define LPC17_USBHOST_PERED (LPC17_USB_BASE+OHCI_PERED_OFFSET) +#define LPC17_USBHOST_CTRLHEADED (LPC17_USB_BASE+OHCI_CTRLHEADED_OFFSET) +#define LPC17_USBHOST_CTRLED (LPC17_USB_BASE+OHCI_CTRLED_OFFSET) +#define LPC17_USBHOST_BULKHEADED (LPC17_USB_BASE+OHCI_BULKHEADED_OFFSET) +#define LPC17_USBHOST_BULKED (LPC17_USB_BASE+OHCI_BULKED_OFFSET) +#define LPC17_USBHOST_DONEHEAD (LPC17_USB_BASE+OHCI_DONEHEAD_OFFSET) + +/* Frame counters (section 7.3) */ + +#define LPC17_USBHOST_FMINT (LPC17_USB_BASE+OHCI_FMINT_OFFSET) +#define LPC17_USBHOST_FMREM (LPC17_USB_BASE+OHCI_FMREM_OFFSET) +#define LPC17_USBHOST_FMNO (LPC17_USB_BASE+OHCI_FMNO_OFFSET) +#define LPC17_USBHOST_PERSTART (LPC17_USB_BASE+OHCI_PERSTART_OFFSET) + +/* Root hub ports (section 7.4) */ + +#define LPC17_USBHOST_LSTHRES (LPC17_USB_BASE+OHCI_LSTHRES_OFFSET) +#define LPC17_USBHOST_RHDESCA (LPC17_USB_BASE+OHCI_RHDESCA_OFFSET) +#define LPC17_USBHOST_RHDESCB (LPC17_USB_BASE+OHCI_RHDESCB_OFFSET) +#define LPC17_USBHOST_RHSTATUS (LPC17_USB_BASE+OHCI_RHSTATUS_OFFSET) +#define LPC17_USBHOST_RHPORTST1 (LPC17_USB_BASE+OHCI_RHPORTST1_OFFSET) +#define LPC17_USBHOST_RHPORTST2 (LPC17_USB_BASE+OHCI_RHPORTST2_OFFSET) +#define LPC17_USBHOST_MODID (LPC17_USB_BASE+LPC17_USBHOST_MODID_OFFSET) + +/* USB OTG Controller ***************************************************************/ +/* OTG registers */ + +#define LPC17_USBOTG_INTST (LPC17_USB_BASE+LPC17_USBOTG_INTST_OFFSET) +#define LPC17_USBOTG_INTEN (LPC17_USB_BASE+LPC17_USBOTG_INTEN_OFFSET) +#define LPC17_USBOTG_INTSET (LPC17_USB_BASE+LPC17_USBOTG_INTSET_OFFSET) +#define LPC17_USBOTG_INTCLR (LPC17_USB_BASE+LPC17_USBOTG_INTCLR_OFFSET) +#define LPC17_USBOTG_STCTRL (LPC17_USB_BASE+LPC17_USBOTG_STCTRL_OFFSET) +#define LPC17_USBOTG_TMR (LPC17_USB_BASE+LPC17_USBOTG_TMR_OFFSET) + +/* USB Device Controller ************************************************************/ +/* Device interrupt registers. See also SYSCON_USBINTST in lpc17_syscon.h */ + +#define LPC17_USBDEV_INTST (LPC17_USB_BASE+LPC17_USBDEV_INTST_OFFSET) +#define LPC17_USBDEV_INTEN (LPC17_USB_BASE+LPC17_USBDEV_INTEN_OFFSET) +#define LPC17_USBDEV_INTCLR (LPC17_USB_BASE+LPC17_USBDEV_INTCLR_OFFSET) +#define LPC17_USBDEV_INTSET (LPC17_USB_BASE+LPC17_USBDEV_INTSET_OFFSET) + +/* SIE Command registers */ + +#define LPC17_USBDEV_CMDCODE (LPC17_USB_BASE+LPC17_USBDEV_CMDCODE_OFFSET) +#define LPC17_USBDEV_CMDDATA (LPC17_USB_BASE+LPC17_USBDEV_CMDDATA_OFFSET) + +/* USB transfer registers */ + +#define LPC17_USBDEV_RXDATA (LPC17_USB_BASE+LPC17_USBDEV_RXDATA_OFFSET) +#define LPC17_USBDEV_RXPLEN (LPC17_USB_BASE+LPC17_USBDEV_RXPLEN_OFFSET) +#define LPC17_USBDEV_TXDATA (LPC17_USB_BASE+LPC17_USBDEV_TXDATA_OFFSET) +#define LPC17_USBDEV_TXPLEN (LPC17_USB_BASE+LPC17_USBDEV_TXPLEN_OFFSET) +#define LPC17_USBDEV_CTRL (LPC17_USB_BASE+LPC17_USBDEV_CTRL_OFFSET) + +/* More Device interrupt registers */ + +#define LPC17_USBDEV_INTPRI (LPC17_USB_BASE+LPC17_USBDEV_INTPRI_OFFSET) + +/* Endpoint interrupt registers */ + +#define LPC17_USBDEV_EPINTST (LPC17_USB_BASE+LPC17_USBDEV_EPINTST_OFFSET) +#define LPC17_USBDEV_EPINTEN (LPC17_USB_BASE+LPC17_USBDEV_EPINTEN_OFFSET) +#define LPC17_USBDEV_EPINTCLR (LPC17_USB_BASE+LPC17_USBDEV_EPINTCLR_OFFSET) +#define LPC17_USBDEV_EPINTSET (LPC17_USB_BASE+LPC17_USBDEV_EPINTSET_OFFSET) +#define LPC17_USBDEV_EPINTPRI (LPC17_USB_BASE+LPC17_USBDEV_EPINTPRI_OFFSET) + +/* Endpoint realization registers */ + +#define LPC17_USBDEV_REEP (LPC17_USB_BASE+LPC17_USBDEV_REEP_OFFSET) +#define LPC17_USBDEV_EPIND (LPC17_USB_BASE+LPC17_USBDEV_EPIND_OFFSET) +#define LPC17_USBDEV_MAXPSIZE (LPC17_USB_BASE+LPC17_USBDEV_MAXPSIZE_OFFSET) + +/* DMA registers */ + +#define LPC17_USBDEV_DMARST (LPC17_USB_BASE+LPC17_USBDEV_DMARST_OFFSET) +#define LPC17_USBDEV_DMARCLR (LPC17_USB_BASE+LPC17_USBDEV_DMARCLR_OFFSET) +#define LPC17_USBDEV_DMARSET (LPC17_USB_BASE+LPC17_USBDEV_DMARSET_OFFSET) +#define LPC17_USBDEV_UDCAH (LPC17_USB_BASE+LPC17_USBDEV_UDCAH_OFFSET) +#define LPC17_USBDEV_EPDMAST (LPC17_USB_BASE+LPC17_USBDEV_EPDMAST_OFFSET) +#define LPC17_USBDEV_EPDMAEN (LPC17_USB_BASE+LPC17_USBDEV_EPDMAEN_OFFSET) +#define LPC17_USBDEV_EPDMADIS (LPC17_USB_BASE+LPC17_USBDEV_EPDMADIS_OFFSET) +#define LPC17_USBDEV_DMAINTST (LPC17_USB_BASE+LPC17_USBDEV_DMAINTST_OFFSET) +#define LPC17_USBDEV_DMAINTEN (LPC17_USB_BASE+LPC17_USBDEV_DMAINTEN_OFFSET) +#define LPC17_USBDEV_EOTINTST (LPC17_USB_BASE+LPC17_USBDEV_EOTINTST_OFFSET) +#define LPC17_USBDEV_EOTINTCLR (LPC17_USB_BASE+LPC17_USBDEV_EOTINTCLR_OFFSET) +#define LPC17_USBDEV_EOTINTSET (LPC17_USB_BASE+LPC17_USBDEV_EOTINTSET_OFFSET) +#define LPC17_USBDEV_NDDRINTST (LPC17_USB_BASE+LPC17_USBDEV_NDDRINTST_OFFSET) +#define LPC17_USBDEV_NDDRINTCLR (LPC17_USB_BASE+LPC17_USBDEV_NDDRINTCLR_OFFSET) +#define LPC17_USBDEV_NDDRINTSET (LPC17_USB_BASE+LPC17_USBDEV_NDDRINTSET_OFFSET) +#define LPC17_USBDEV_SYSERRINTST (LPC17_USB_BASE+LPC17_USBDEV_SYSERRINTST_OFFSET) +#define LPC17_USBDEV_SYSERRINTCLR (LPC17_USB_BASE+LPC17_USBDEV_SYSERRINTCLR_OFFSET) +#define LPC17_USBDEV_SYSERRINTSET (LPC17_USB_BASE+LPC17_USBDEV_SYSERRINTSET_OFFSET) + +/* OTG I2C registers ****************************************************************/ + +#define LPC17_OTGI2C_RX (LPC17_USB_BASE+LPC17_OTGI2C_RX_OFFSET) +#define LPC17_OTGI2C_TX (LPC17_USB_BASE+LPC17_OTGI2C_TX_OFFSET) +#define LPC17_OTGI2C_STS (LPC17_USB_BASE+LPC17_OTGI2C_STS_OFFSET) +#define LPC17_OTGI2C_CTL (LPC17_USB_BASE+LPC17_OTGI2C_CTL_OFFSET) +#define LPC17_OTGI2C_CLKHI (LPC17_USB_BASE+LPC17_OTGI2C_CLKHI_OFFSET) +#define LPC17_OTGI2C_CLKLO (LPC17_USB_BASE+LPC17_OTGI2C_CLKLO_OFFSET) + +/* Clock control registers ***********************************************************/ + +#define LPC17_USBOTG_CLKCTRL (LPC17_USB_BASE+LPC17_USBOTG_CLKCTRL_OFFSET) +#define LPC17_USBOTG_CLKST (LPC17_USB_BASE+LPC17_USBOTG_CLKST_OFFSET) + +#define LPC17_USBDEV_CLKCTRL (LPC17_USB_BASE+LPC17_USBDEV_CLKCTRL_OFFSET) +#define LPC17_USBDEV_CLKST (LPC17_USB_BASE+LPC17_USBDEV_CLKST_OFFSET) + +/* Register bit definitions *********************************************************/ +/* USB Host Controller (OHCI) *******************************************************/ +/* See include/nuttx/usb/ohci.h */ + +/* Module ID/Revision ID */ + +#define USBHOST_MODID_VER_SHIFT (0) /* Bits 0-7: Unique version number */ +#define USBHOST_MODID_VER_MASK (0xff << USBHOST_MODID_VER_SHIFT) +#define USBHOST_MODID_REV_SHIFT (8) /* Bits 9-15: Unique revision number */ +#define USBHOST_MODID_REV_MASK (0xff << USBHOST_MODID_REV_SHIFT) +#define USBHOST_MODID_3505_SHIFT (16) /* Bits 16-31: 0x3505 */ +#define USBHOST_MODID_3505_MASK (0xffff << USBHOST_MODID_3505_SHIFT) +# define USBHOST_MODID_3505 (0x3505 << USBHOST_MODID_3505_SHIFT) + +/* USB OTG Controller ***************************************************************/ +/* OTG registers: + * + * OTG Interrupt Status, OTG Interrupt Enable, OTG Interrupt Set, AND OTG Interrupt + * Clear + */ + +#define USBOTG_INT_TMR (1 << 0) /* Bit 0: Timer time-out */ +#define USBOTG_INT_REMOVE_PU (1 << 1) /* Bit 1: Remove pull-up */ +#define USBOTG_INT_HNP_FAILURE (1 << 2) /* Bit 2: HNP failed */ +#define USBOTG_INT_HNP_SUCCESS (1 << 3) /* Bit 3: HNP succeeded */ + /* Bits 4-31: Reserved */ +/* OTG Status and Control */ + +#define USBOTG_STCTRL_PORTFUNC_SHIFT (0) /* Bits 0-1: Controls port function */ +#define USBOTG_STCTRL_PORTFUNC_MASK (3 << USBOTG_STCTRL_PORTFUNC_SHIFT) +# define USBOTG_STCTRL_PORTFUNC_HNPOK (1 << USBOTG_STCTRL_PORTFUNC_SHIFT) /* HNP suceeded */ +#define USBOTG_STCTRL_TMRSCALE_SHIFT (2) /* Bits 2-3: Timer scale selection */ +#define USBOTG_STCTRL_TMRSCALE_MASK (3 << USBOTG_STCTRL_TMR_SCALE_SHIFT) +# define USBOTG_STCTRL_TMRSCALE_10US (0 << USBOTG_STCTRL_TMR_SCALE_SHIFT) /* 10uS (100 KHz) */ +# define USBOTG_STCTRL_TMRSCALE_100US (1 << USBOTG_STCTRL_TMR_SCALE_SHIFT) /* 100uS (10 KHz) */ +# define USBOTG_STCTRL_TMRSCALE_1000US (2 << USBOTG_STCTRL_TMR_SCALE_SHIFT) /* 1000uS (1 KHz) */ +#define USBOTG_STCTRL_TMRMODE (1 << 4) /* Bit 4: Timer mode selection */ +#define USBOTG_STCTRL_TMREN (1 << 5) /* Bit 5: Timer enable */ +#define USBOTG_STCTRL_TMRRST (1 << 6) /* Bit 6: TTimer reset */ + /* Bit 7: Reserved */ +#define USBOTG_STCTRL_BHNPTRACK (1 << 8) /* Bit 8: Enable HNP tracking for B-device (peripheral) */ +#define USBOTG_STCTRL_AHNPTRACK (1 << 9) /* Bit 9: Enable HNP tracking for A-device (host) */ +#define USBOTG_STCTRL_PUREMOVED (1 << 10) /* Bit 10: Set when D+ pull-up removed */ + /* Bits 11-15: Reserved */ +#define USBOTG_STCTRL_TMRCNT_SHIFT (0) /* Bits 16-313: Timer scale selection */ +#define USBOTG_STCTRL_TMRCNT_MASK (0ffff << USBOTG_STCTRL_TMR_CNT_SHIFT) + +/* OTG Timer */ + +#define USBOTG_TMR_TIMEOUTCNT_SHIFT (0) /* Bits 0-15: Interrupt when CNT matches this */ +#define USBOTG_TMR_TIMEOUTCNT_MASK (0xffff << USBOTG_TMR_TIMEOUTCNT_SHIFT) + /* Bits 16-31: Reserved */ + +/* USB Device Controller ************************************************************/ +/* Device interrupt registers. See also SYSCON_USBINTST in lpc17_syscon.h */ +/* USB Device Interrupt Status, USB Device Interrupt Enable, USB Device Interrupt + * Clear, USB Device Interrupt Set, and USB Device Interrupt Priority + */ + +#define USBDEV_INT_FRAME (1 << 0) /* Bit 0: frame interrupt (every 1 ms) */ +#define USBDEV_INT_EPFAST (1 << 1) /* Bit 1: Fast endpoint interrupt */ +#define USBDEV_INT_EPSLOW (1 << 2) /* Bit 2: Slow endpoints interrupt */ +#define USBDEV_INT_DEVSTAT (1 << 3) /* Bit 3: Bus reset, suspend change or connect change */ +#define USBDEV_INT_CCEMPTY (1 << 4) /* Bit 4: Command code register empty */ +#define USBDEV_INT_CDFULL (1 << 5) /* Bit 5: Command data register full */ +#define USBDEV_INT_RXENDPKT (1 << 6) /* Bit 6: RX endpoint data transferred */ +#define USBDEV_INT_TXENDPKT (1 << 7) /* Bit 7: TX endpoint data tansferred */ +#define USBDEV_INT_EPRLZED (1 << 8) /* Bit 8: Endpoints realized */ +#define USBDEV_INT_ERRINT (1 << 9) /* Bit 9: Error Interrupt */ + /* Bits 10-31: Reserved */ +/* SIE Command registers: + * + * USB Command Code + */ + /* Bits 0-7: Reserved */ +#define USBDEV_CMDCODE_PHASE_SHIFT (8) /* Bits 8-15: Command phase */ +#define USBDEV_CMDCODE_PHASE_MASK (0xff << USBDEV_CMDCODE_PHASE_SHIFT) +# define USBDEV_CMDCODE_PHASE_READ (1 << USBDEV_CMDCODE_PHASE_SHIFT) +# define USBDEV_CMDCODE_PHASE_WRITE (2 << USBDEV_CMDCODE_PHASE_SHIFT) +# define USBDEV_CMDCODE_PHASE_COMMAND (5 << USBDEV_CMDCODE_PHASE_SHIFT) +#define USBDEV_CMDCODE_CMD_SHIFT (16) /* Bits 15-23: Command (READ/COMMAND phases) */ +#define USBDEV_CMDCODE_CMD_MASK (0xff << USBDEV_CMDCODE_CMD_SHIFT) +#define USBDEV_CMDCODE_WDATA_SHIFT (16) /* Bits 15-23: Write dagta (WRITE phase) */ +#define USBDEV_CMDCODE_WDATA_MASK (0xff << USBDEV_CMDCODE_CMD_SHIFT) + /* Bits 24-31: Reserved */ +/* USB Command Data */ + +#define USBDEV_CMDDATA_SHIFT (0) /* Bits 0-7: Command read data */ +#define USBDEV_CMDDATA_MASK (0xff << USBDEV_CMDDATA_SHIFT) + /* Bits 8-31: Reserved */ +/* USB transfer registers: + * + * USB Receive Data (Bits 0-31: Received data) + */ + +/* USB Receive Packet Length */ + +#define USBDEV_RXPLEN_SHIFT (0) /* Bits 0-9: Bytes remaining to be read */ +#define USBDEV_RXPLEN_MASK (0x3ff << USBDEV_RXPLEN_SHIFT) +#define USBDEV_RXPLEN_DV (1 << 10) /* Bit 10: DV Data valid */ +#define USBDEV_RXPLEN_PKTRDY (1 << 11) /* Bit 11: Packet ready for reading */ + /* Bits 12-31: Reserved */ +/* USB Transmit Data (Bits 0-31: Transmit data) */ + +/* USB Transmit Packet Length */ + +#define USBDEV_TXPLEN_SHIFT (0) /* Bits 0-9: Bytes remaining to be written */ +#define USBDEV_TXPLEN_MASK (0x3ff << USBDEV_TXPLEN_SHIFT) + /* Bits 10-31: Reserved */ +/* USB Control */ + +#define USBDEV_CTRL_RDEN (1 << 0) /* Bit 0: Read mode control */ +#define USBDEV_CTRL_WREN (1 << 1) /* Bit 1: Write mode control */ +#define USBDEV_CTRL_LOGEP_SHIFT (2) /* Bits 2-5: Logical Endpoint number */ +#define USBDEV_CTRL_LOGEP_MASK (15 << USBDEV_CTRL_LOGEP_SHIFT) + /* Bits 6-31: Reserved */ +/* Endpoint interrupt registers: + * + * USB Endpoint Interrupt Status, USB Endpoint Interrupt Enable, USB Endpoint Interrupt + * Clear, USB Endpoint Interrupt Set, and USB Endpoint Priority. Bits correspond + * to on RX or TX value for any of 15 logical endpoints). + */ + +#define USBDEV_LOGEPRX(n) (1 << ((n) << 1)) +#define USBDEV_LOGEPTX(n) ((1 << ((n) << 1)) + 1) +#define USBDEV_LOGEPRX0 (1 << 0) +#define USBDEV_LOGEPTX0 (1 << 1) +#define USBDEV_LOGEPRX1 (1 << 2) +#define USBDEV_LOGEPTX1 (1 << 3) +#define USBDEV_LOGEPRX2 (1 << 4) +#define USBDEV_LOGEPTX2 (1 << 5) +#define USBDEV_LOGEPRX3 (1 << 6) +#define USBDEV_LOGEPTX3 (1 << 7) +#define USBDEV_LOGEPRX4 (1 << 8) +#define USBDEV_LOGEPTX4 (1 << 9) +#define USBDEV_LOGEPRX5 (1 << 10) +#define USBDEV_LOGEPTX5 (1 << 11) +#define USBDEV_LOGEPRX6 (1 << 12) +#define USBDEV_LOGEPTX6 (1 << 13) +#define USBDEV_LOGEPRX7 (1 << 14) +#define USBDEV_LOGEPTX7 (1 << 15) +#define USBDEV_LOGEPRX8 (1 << 16) +#define USBDEV_LOGEPTX8 (1 << 17) +#define USBDEV_LOGEPRX9 (1 << 18) +#define USBDEV_LOGEPTX9 (1 << 19) +#define USBDEV_LOGEPRX10 (1 << 20) +#define USBDEV_LOGEPTX10 (1 << 21) +#define USBDEV_LOGEPRX11 (1 << 22) +#define USBDEV_LOGEPTX11 (1 << 23) +#define USBDEV_LOGEPRX12 (1 << 24) +#define USBDEV_LOGEPTX12 (1 << 25) +#define USBDEV_LOGEPRX13 (1 << 26) +#define USBDEV_LOGEPTX13 (1 << 27) +#define USBDEV_LOGEPRX14 (1 << 28) +#define USBDEV_LOGEPTX14 (1 << 29) +#define USBDEV_LOGEPRX15 (1 << 30) +#define USBDEV_LOGEPTX15 (1 << 31) + +/* Endpoint realization registers: + * + * USB Realize Endpoint (Bits correspond to 1 of 32 physical endpoints) + */ + +#define USBDEV_PHYEP(n) (1 << (n)) +#define USBDEV_PHYEP0 (1 << 0) +#define USBDEV_PHYEP1 (1 << 1) +#define USBDEV_PHYEP2 (1 << 2) +#define USBDEV_PHYEP3 (1 << 3) +#define USBDEV_PHYEP4 (1 << 4) +#define USBDEV_PHYEP5 (1 << 5) +#define USBDEV_PHYEP6 (1 << 6) +#define USBDEV_PHYEP7 (1 << 7) +#define USBDEV_PHYEP8 (1 << 8) +#define USBDEV_PHYEP9 (1 << 9) +#define USBDEV_PHYEP10 (1 << 10) +#define USBDEV_PHYEP11 (1 << 11) +#define USBDEV_PHYEP12 (1 << 12) +#define USBDEV_PHYEP13 (1 << 13) +#define USBDEV_PHYEP14 (1 << 14) +#define USBDEV_PHYEP15 (1 << 15) +#define USBDEV_PHYEP16 (1 << 16) +#define USBDEV_PHYEP17 (1 << 17) +#define USBDEV_PHYEP18 (1 << 18) +#define USBDEV_PHYEP19 (1 << 19) +#define USBDEV_PHYEP20 (1 << 20) +#define USBDEV_PHYEP21 (1 << 21) +#define USBDEV_PHYEP22 (1 << 22) +#define USBDEV_PHYEP23 (1 << 23) +#define USBDEV_PHYEP24 (1 << 24) +#define USBDEV_PHYEP25 (1 << 25) +#define USBDEV_PHYEP26 (1 << 26) +#define USBDEV_PHYEP27 (1 << 27) +#define USBDEV_PHYEP28 (1 << 28) +#define USBDEV_PHYEP29 (1 << 29) +#define USBDEV_PHYEP30 (1 << 30) +#define USBDEV_PHYEP31 (1 << 31) + +/* USB Endpoint Index */ + +#define USBDEV_EPIND_SHIFT (0) /* Bits 0-4: Physical endpoint number (0-31) */ +#define USBDEV_EPIND_MASK (31 << USBDEV_EPIND_SHIFT) + /* Bits 5-31: Reserved */ +/* USB MaxPacketSize */ + +#define USBDEV_MAXPSIZE_SHIFT (0) /* Bits 0-9: Maximum packet size value */ +#define USBDEV_MAXPSIZE_MASK (0x3ff << USBDEV_MAXPSIZE_SHIFT) + /* Bits 10-31: Reserved */ +/* DMA registers: + * + * USB DMA Request Status, USB DMA Request Clear, and USB DMA Request Set. Registers + * contain bits for each of 32 physical endpoints. Use the USBDEV_PHYEP* definitions + * above. PHYEP0-1 (bits 0-1) must be zero. + */ + +/* USB UDCA Head */ + /* Bits 0-6: Reserved */ +#define USBDEV_UDCAH_SHIFT (7) /* Bits 7-31: UDCA start address */ +#define USBDEV_UDCAH_MASK (0x01ffffff << USBDEV_UDCAH_SHIFT) + +/* USB Endpoint DMA Status, USB Endpoint DMA Enable, and USB Endpoint DMA Disable. + * Registers contain bits for physical endpoints 2-31. Use the USBDEV_PHYEP* + * definitions above. PHYEP0-1 (bits 0-1) must be zero. + */ + +/* USB DMA Interrupt Status and USB DMA Interrupt Enable */ + +#define USBDEV_DMAINT_EOT (1 << 0) /* Bit 0: End of Transfer Interrupt */ +#define USBDEV_DMAINT_NDDR (1 << 1) /* Bit 1: New DD Request Interrupt */ +#define USBDEV_DMAINT_ERR (1 << 2) /* Bit 2: System Error Interrupt */ + /* Bits 3-31: Reserved */ +/* USB End of Transfer Interrupt Status, USB End of Transfer Interrupt Clear, and USB + * End of Transfer Interrupt Set. Registers contain bits for physical endpoints 2-31. + * Use the USBDEV_PHYEP* definitions above. PHYEP0-1 (bits 0-1) must be zero. + */ + +/* USB New DD Request Interrupt Status, USB New DD Request Interrupt Clear, and USB + * New DD Request Interrupt Set. Registers contain bits for physical endpoints 2-31. + * Use the USBDEV_PHYEP* definitions above. PHYEP0-1 (bits 0-1) must be zero. + */ + +/* USB System Error Interrupt Status, USB System Error Interrupt Clear, USB System + * Error Interrupt Set. Registers contain bits for physical endpoints 2-31. Use + * the USBDEV_PHYEP* definitions above. PHYEP0-1 (bits 0-1) must be zero. + */ + +/* OTG I2C registers ****************************************************************/ + +/* I2C Receive */ + +#define OTGI2C_RX_DATA_SHIFT (0) /* Bits 0-7: RX data */ +#define OTGI2C_RX_DATA_MASK (0xff << OTGI2C_RX_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Transmit */ + +#define OTGI2C_TX_DATA_SHIFT (0) /* Bits 0-7: TX data */ +#define OTGI2C_TX_DATA_MASK (0xff << OTGI2C_TX_DATA_SHIFT) +#define OTGI2C_TX_DATA_START (1 << 8) /* Bit 8: Issue START before transmit */ +#define OTGI2C_TX_DATA_STOP (1 << 9) /* Bit 9: Issue STOP before transmit */ + /* Bits 3-31: Reserved */ +/* I2C Status */ + +#define OTGI2C_STS_TDI (1 << 0) /* Bit 0: Transaction Done Interrupt */ +#define OTGI2C_STS_AFI (1 << 1) /* Bit 1: Arbitration Failure Interrupt */ +#define OTGI2C_STS_NAI (1 << 2) /* Bit 2: No Acknowledge Interrupt */ +#define OTGI2C_STS_DRMI (1 << 3) /* Bit 3: Master Data Request Interrupt */ +#define OTGI2C_STS_DRSI (1 << 4) /* Bit 4: Slave Data Request Interrupt */ +#define OTGI2C_STS_ACTIVE (1 << 5) /* Bit 5: Indicates whether the bus is busy */ +#define OTGI2C_STS_SCL (1 << 6) /* Bit 6: The current value of the SCL signal */ +#define OTGI2C_STS_SDA (1 << 7) /* Bit 7: The current value of the SDA signal */ +#define OTGI2C_STS_RFF (1 << 8) /* Bit 8: Receive FIFO Full (RFF) */ +#define OTGI2C_STS_RFE (1 << 9) /* Bit 9: Receive FIFO Empty */ +#define OTGI2C_STS_TFF (1 << 10) /* Bit 10: Transmit FIFO Full */ +#define OTGI2C_STS_TFE (1 << 11) /* Bit 11: Transmit FIFO Empty */ + /* Bits 12-31: Reserved */ +/* I2C Control */ + +#define OTGI2C_CTL_TDIE (1 << 0) /* Bit 0: Transmit Done Interrupt Enable */ +#define OTGI2C_CTL_AFIE (1 << 1) /* Bit 1: Transmitter Arbitration Failure Interrupt Enable */ +#define OTGI2C_CTL_NAIE (1 << 2) /* Bit 2: Transmitter No Acknowledge Interrupt Enable */ +#define OTGI2C_CTL_DRMIE (1 << 3) /* Bit 3: Master Transmitter Data Request Interrupt Enable */ +#define OTGI2C_CTL_DRSIE (1 << 4) /* Bit 4: Slave Transmitter Data Request Interrupt Enable */ +#define OTGI2C_CTL_REFIE (1 << 5) /* Bit 5: Receive FIFO Full Interrupt Enable */ +#define OTGI2C_CTL_RFDAIE (1 << 6) /* Bit 6: Receive Data Available Interrupt Enable */ +#define OTGI2C_CTL_TFFIE (1 << 7) /* Bit 7: Transmit FIFO Not Full Interrupt Enable */ +#define OTGI2C_CTL_SRST (1 << 8) /* Bit 8: Soft reset */ + /* Bits 9-31: Reserved */ +/* I2C Clock High */ + +#define OTGI2C_CLKHI_SHIFT (0) /* Bits 0-7: Clock divisor high */ +#define OTGI2C_CLKHI_MASK (0xff << OTGI2C_CLKHI_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Clock Low */ + +#define OTGI2C_CLKLO_SHIFT (0) /* Bits 0-7: Clock divisor high */ +#define OTGI2C_CLLO_MASK (0xff << OTGI2C_CLKLO_SHIFT) + /* Bits 8-31: Reserved */ +/* Clock control registers ***********************************************************/ + +/* USB Clock Control (OTG clock controller) and USB Clock Status (OTG clock status) */ + +#define USBDEV_CLK_HOSTCLK (1 << 0) /* Bit 1: Host clock (OTG only) */ +#define USBDEV_CLK_DEVCLK (1 << 1) /* Bit 1: Device clock */ +#define USBDEV_CLK_I2CCLK (1 << 2) /* Bit 2: I2C clock (OTG only) */ +#define USBDEV_CLK_PORTSELCLK (1 << 3) /* Bit 3: Port select register clock (device only) */ +#define USBDEV_CLK_OTGCLK (1 << 3) /* Bit 3: OTG clock (OTG only) */ +#define USBDEV_CLK_AHBCLK (1 << 4) /* Bit 4: AHB clock */ + /* Bits 5-31: Reserved */ +/* Alternate naming */ + +#define USBOTG_CLK_HOSTCLK USBDEV_CLK_HOSTCLK +#define USBOTG_CLK_DEVCLK USBDEV_CLK_DEVCLK +#define USBOTG_CLK_I2CCLK USBDEV_CLK_I2CCLK +#define USBOTG_CLK_PORTSELCLK USBDEV_CLK_PORTSELCLK +#define USBOTG_CLK_OTGCLK USBDEV_CLK_OTGCLK +#define USBOTG_CLK_AHBCLK USBDEV_CLK_AHBCLK + +/* Endpoints *************************************************************************/ + +#define LPC17_EP0_OUT 0 +#define LPC17_EP0_IN 1 +#define LPC17_CTRLEP_OUT LPC17_EP0_OUT +#define LPC17_CTRLEP_IN LPC17_EP0_IN +#define LPC17_EP1_OUT 2 +#define LPC17_EP1_IN 3 +#define LPC17_EP2_OUT 4 +#define LPC17_EP2_IN 5 +#define LPC17_EP3_OUT 6 +#define LPC17_EP3_IN 7 +#define LPC17_EP4_OUT 8 +#define LPC17_EP4_IN 9 +#define LPC17_EP5_OUT 10 +#define LPC17_EP5_IN 11 +#define LPC17_EP6_OUT 12 +#define LPC17_EP6_IN 13 +#define LPC17_EP7_OUT 14 +#define LPC17_EP7_IN 15 +#define LPC17_EP8_OUT 16 +#define LPC17_EP8_IN 17 +#define LPC17_EP9_OUT 18 +#define LPC17_EP9_IN 19 +#define LPC17_EP10_OUT 20 +#define LPC17_EP10_IN 21 +#define LPC17_EP11_OUT 22 +#define LPC17_EP11_IN 23 +#define LPC17_EP12_OUT 24 +#define LPC17_EP12_IN 25 +#define LPC17_EP13_OUT 26 +#define LPC17_EP13_IN 27 +#define LPC17_EP14_OUT 28 +#define LPC17_EP14_IN 29 +#define LPC17_EP15_OUT 30 +#define LPC17_EP15_IN 31 +#define LPC17_NUMEPS 32 + +/* Commands *************************************************************************/ + +/* USB Command Code Register */ + +#define CMD_USBDEV_PHASESHIFT (8) /* Bits 8-15: Command phase value */ +#define CMD_USBDEV_PHASEMASK (0xff << CMD_USBDEV_PHASESHIFT) +# define CMD_USBDEV_DATAWR (1 << CMD_USBDEV_PHASESHIFT) +# define CMD_USBDEV_DATARD (2 << CMD_USBDEV_PHASESHIFT) +# define CMD_USBDEV_CMDWR (5 << CMD_USBDEV_PHASESHIFT) +#define CMD_USBDEV_CMDSHIFT (16) /* Bits 16-23: Device command/WDATA */ +#define CMD_USBDEV_CMDMASK (0xff << CMD_USBDEV_CMDSHIFT) +#define CMD_USBDEV_WDATASHIFT CMD_USBDEV_CMDSHIFT +#define CMD_USBDEV_WDATAMASK CMD_USBDEV_CMDMASK + +/* Device Commands */ + +#define CMD_USBDEV_SETADDRESS (0x00d0) +#define CMD_USBDEV_CONFIG (0x00d8) +#define CMD_USBDEV_SETMODE (0x00f3) +#define CMD_USBDEV_READFRAMENO (0x00f5) +#define CMD_USBDEV_READTESTREG (0x00fd) +#define CMD_USBDEV_SETSTATUS (0x01fe) /* Bit 8 set to distingish get from set */ +#define CMD_USBDEV_GETSTATUS (0x00fe) +#define CMD_USBDEV_GETERRORCODE (0x00ff) +#define CMD_USBDEV_READERRORSTATUS (0x00fb) + +/* Endpoint Commands */ + +#define CMD_USBDEV_EPSELECT (0x0000) +#define CMD_USBDEV_EPSELECTCLEAR (0x0040) +#define CMD_USBDEV_EPSETSTATUS (0x0140) /* Bit 8 set to distingish get from selectclear */ +#define CMD_USBDEV_EPCLRBUFFER (0x00f2) +#define CMD_USBDEV_EPVALIDATEBUFFER (0x00fa) + +/* Command/response bit definitions ********************************************/ +/* SETADDRESS (0xd0) command definitions */ + +#define CMD_USBDEV_SETADDRESS_MASK (0x7f) /* Bits 0-6: Device address */ +#define CMD_USBDEV_SETADDRESS_DEVEN (1 << 7) /* Bit 7: Device enable */ + +/* SETSTATUS (0xfe) and GETSTATUS (0xfe) response: */ + +#define CMD_STATUS_CONNECT (1 << 0) /* Bit 0: Connected */ +#define CMD_STATUS_CONNCHG (1 << 1) /* Bit 1: Connect change */ +#define CMD_STATUS_SUSPEND (1 << 2) /* Bit 2: Suspend */ +#define CMD_STATUS_SUSPCHG (1 << 3) /* Bit 3: Suspend change */ +#define CMD_STATUS_RESET (1 << 4) /* Bit 4: Bus reset bit */ + +/* EPSELECT (0x00) endpoint status response */ + +#define CMD_EPSELECT_FE (1 << 0) /* Bit 0: IN empty or OUT full */ +#define CMD_EPSELECT_ST (1 << 1) /* Bit 1: Endpoint is stalled */ +#define CMD_EPSELECT_STP (1 << 2) /* Bit 2: Last packet was setup */ +#define CMD_EPSELECT_PO (1 << 3) /* Bit 3: Previous packet was overwritten */ +#define CMD_EPSELECT_EPN (1 << 4) /* Bit 4: NAK sent */ +#define CMD_EPSELECT_B1FULL (1 << 5) /* Bit 5: Buffer 1 full */ +#define CMD_EPSELECT_B2FULL (1 << 6) /* Bit 6: Buffer 2 full */ + /* Bit 7: Reserved */ +/* EPSETSTATUS (0x40) command */ + +#define CMD_SETSTAUS_ST (1 << 0) /* Bit 0: Stalled endpoint bit */ + /* Bits 1-4: Reserved */ +#define CMD_SETSTAUS_DA (1 << 5) /* Bit 5: Disabled endpoint bit */ +#define CMD_SETSTAUS_RFMO (1 << 6) /* Bit 6: Rate feedback mode */ +#define CMD_SETSTAUS_CNDST (1 << 7) /* Bit 7: Conditional stall bit */ + +/* EPCLRBUFFER (0xf2) response */ + +#define CMD_USBDEV_CLRBUFFER_PO (0x00000001) + +/* SETMODE(0xf3) command */ + +#define CMD_SETMODE_APCLK (1 << 0) /* Bit 0: Always PLL Clock */ +#define CMD_SETMODE_INAKCI (1 << 1) /* Bit 1: Interrupt on NAK for Control IN endpoint */ +#define CMD_SETMODE_INAKCO (1 << 2) /* Bit 2: Interrupt on NAK for Control OUT endpoint */ +#define CMD_SETMODE_INAKII (1 << 3) /* Bit 3: Interrupt on NAK for Interrupt IN endpoint */ +#define CMD_SETMODE_INAKIO (1 << 4) /* Bit 4: Interrupt on NAK for Interrupt OUT endpoints */ +#define CMD_SETMODE_INAKBI (1 << 5) /* Bit 5: Interrupt on NAK for Bulk IN endpoints */ +#define CMD_SETMODE_INAKBO (1 << 6) /* Bit 6: Interrupt on NAK for Bulk OUT endpoints */ + +/* READERRORSTATUS (0xFb) command */ + +#define CMD_READERRORSTATUS_PIDERR (1 << 0) /* Bit 0: PID encoding/unknown or Token CRC */ +#define CMD_READERRORSTATUS_UEPKT (1 << 1) /* Bit 1: Unexpected Packet */ +#define CMD_READERRORSTATUS_DCRC (1 << 2) /* Bit 2: Data CRC error */ +#define CMD_READERRORSTATUS_TIMEOUT (1 << 3) /* Bit 3: Time out error */ +#define CMD_READERRORSTATUS_EOP (1 << 4) /* Bit 4: End of packet error */ +#define CMD_READERRORSTATUS_BOVRN (1 << 5) /* Bit 5: Buffer Overrun */ +#define CMD_READERRORSTATUS_BTSTF (1 << 6) /* Bit 6: Bit stuff error */ +#define CMD_READERRORSTATUS_TGLERR (1 << 7) /* Bit 7: Wrong toggle in data PID */ +#define CMD_READERRORSTATUS_ALLERRS (0xff) + +/* DMA ******************************************************************************/ +/* The DMA descriptor */ + +#define USB_DMADESC_NEXTDDPTR 0 /* Offset 0: Next USB descriptor in RAM */ +#define USB_DMADESC_CONFIG 1 /* Offset 1: DMA configuration info. */ +#define USB_DMADESC_STARTADDR 2 /* Offset 2: DMA start address */ +#define USB_DMADESC_STATUS 3 /* Offset 3: DMA status info (read only) */ +#define USB_DMADESC_ISOCSIZEADDR 4 /* Offset 4: Isoc. packet size address */ + +/* Bit settings for CONFIG (offset 1 )*/ + +#define USB_DMADESC_MODE_SHIFT (0) /* Bits 0-1: DMA mode */ +#define USB_DMADESC_MODE_MASK (3 << USB_DMADESC_MODE_SHIFT) +# define USB_DMADESC_MODENORMAL (0 << USB_DMADESC_MODE_SHIFT) /* Mode normal */ +# define USB_DMADESC_MODEATLE (1 << USB_DMADESC_MODE_SHIFT) /* ATLE normal */ +#define USB_DMADESC_NEXTDDVALID (1 << 2) /* Bit 2: Next descriptor valid */ + /* Bit 3: Reserved */ +#define USB_DMADESC_ISCOEP (1 << 4) /* Bit 4: ISOC endpoint */ +#define USB_DMADESC_PKTSIZE_SHIFT (5) /* Bits 5-15: Max packet size */ +#define USB_DMADESC_PKTSIZE_MASK (0x7ff << USB_DMADESC_PKTSIZE_SHIFT) +#define USB_DMADESC_BUFLEN_SHIFT (16) /* Bits 16-31: DMA buffer length */ +#define USB_DMADESC_BUFLEN_MASK (0xffff << USB_DMADESC_BUFLEN_SHIFT + +/* Bit settings for STATUS (offset 3). All must be initialized to zero. */ + +#define USB_DMADESC_STATUS_SHIFT (1) /* Bits 1-4: DMA status */ +#define USB_DMADESC_STATUS_MASK (15 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_NOTSERVICED (0 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_BEINGSERVICED (1 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_NORMALCOMPLETION (2 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_DATAUNDERRUN (3 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_DATAOVERRUN (8 << USB_DMADESC_STATUS_SHIFT) +# define USB_DMADESC_SYSTEMERROR (9 << USB_DMADESC_STATUS_SHIFT) +#define USB_DMADESC_PKTVALID (1 << 5) /* Bit 5: Packet valid */ +#define USB_DMADESC_LSBEXTRACTED (1 << 6) /* Bit 6: LS byte extracted */ +#define USB_DMADESC_MSBEXTRACTED (1 << 7) /* Bit 7: MS byte extracted */ +#define USB_DMADESC_MSGLENPOS_SHIFT (8) /* Bits 8-13: Message length position */ +#define USB_DMADESC_MSGLENPOS_MASK (0x3f << USB_DMADESC_MSGLENPOS_SHIFT) +#define USB_DMADESC_DMACOUNT_SHIFT (16) /* Bits 16-31: DMA count */ +#define USB_DMADESC_DMACOUNT_MASK (0xffff << USB_DMADESC_DMACOUNT_SHIFT) + +/* DMA packet size format */ + +#define USB_DMAPKTSIZE_PKTLEN_SHIFT (0) /* Bits 0-15: Packet length */ +#define USB_DMAPKTSIZE_PKTLEN_MASK (0xffff << USB_DMAPKTSIZE_PKTLEN_SHIFT) +#define USB_DMAPKTSIZE_PKTVALID (1 << 16) /* Bit 16: Packet valid */ +#define USB_DMAPKTSIZE_FRAMENO_SHIFT (17) /* Bit 17-31: Frame number */ +#define USB_DMAPKTSIZE_FRAMENO_MASK (0x7fff << USB_DMAPKTSIZE_FRAMENO_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_USB_H */ diff --git a/arch/arm/src/lpc17xx/chip/lpc17_wdt.h b/arch/arm/src/lpc17xx/chip/lpc17_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..d76ff176226045e5c821f63975f5f8ed5200c2b9 --- /dev/null +++ b/arch/arm/src/lpc17xx/chip/lpc17_wdt.h @@ -0,0 +1,156 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/chip/lpc17_wdt.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC17_WDT_MOD_OFFSET 0x0000 /* Watchdog mode register */ +#define LPC17_WDT_TC_OFFSET 0x0004 /* Watchdog timer constant register */ +#define LPC17_WDT_FEED_OFFSET 0x0008 /* Watchdog feed sequence register */ +#define LPC17_WDT_TV_OFFSET 0x000c /* Watchdog timer value register */ + +#ifdef LPC176x +# define LPC17_WDT_CLKSEL_OFFSET 0x0010 /* Watchdog clock source selection register */ +#endif + +#ifdef LPC178x +# define LPC17_WDT_WARNINT_OFFSET 0x0014 /* Watchdog warning interrupt */ +# define LPC17_WDT_WINDOW_OFFSET 0x0018 /* Watchdog window compare value */ +#endif + +/* Register addresses ***************************************************************/ + +#define LPC17_WDT_MOD (LPC17_WDT_BASE+LPC17_WDT_MOD_OFFSET) +#define LPC17_WDT_TC (LPC17_WDT_BASE+LPC17_WDT_TC_OFFSET) +#define LPC17_WDT_FEED (LPC17_WDT_BASE+LPC17_WDT_FEED_OFFSET) +#define LPC17_WDT_TV (LPC17_WDT_BASE+LPC17_WDT_TV_OFFSET) +#define LPC17_WDT_CLKSEL (LPC17_WDT_BASE+LPC17_WDT_CLKSEL_OFFSET) + +#ifdef LPC178x +# define LPC17_WDT_WARNINT (LPC17_WDT_BASE+LPC17_WDT_WARNINT_OFFSET) +# define LPC17_WDT_WINDOW (LPC17_WDT_BASE+LPC17_WDT_WINDOW_OFFSET) +#endif + +/* Register bit definitions *********************************************************/ + +/* Watchdog mode register */ + +#define WDT_MOD_WDEN (1 << 0) /* Bit 0: Watchdog enable */ +#define WDT_MOD_WDRESET (1 << 1) /* Bit 1: Watchdog reset enable */ +#define WDT_MOD_WDTOF (1 << 2) /* Bit 2: Watchdog time-out */ +#define WDT_MOD_WDINT (1 << 3) /* Bit 3: Watchdog interrupt */ +#ifdef LPC178x +# define WDT_MOD_WDPROTECT (1 << 4) /* Bit 4: Watchdog interrupt */ +#endif + /* Bits 5-31: Reserved */ +/* Watchdog timer constant register */ + +#ifdef LPC176x +# define WDT_TC (0xffffffff) /* Bits 0-31: Watchdog time-out interval */ +#endif +#ifdef LPC178x +# define WDT_TC (0x00ffffff) /* Bits 0-23: Watchdog time-out interval */ + /* Bits 24-31: Reserved */ +#endif + +/* Watchdog feed sequence register */ + +#define WDT_FEED_MASK (0xff) /* Bits 0-7: Feed value should be 0xaa + * followed by 0x55 */ + /* Bits 14-31: Reserved */ +/* Watchdog timer value register */ + +#ifdef LPC176x +# define WDT_TVT (0xffffffff) /* Bits 0-31: Watchdog timer value */ +#endif +#ifdef LPC178x +# define WDT_TVT (0xffffff) /* Bits 0-23: Watchdog timer value */ + /* Bits 24-31: Reserved */ +#endif + +/* Watchdog clock source selection register */ + +#ifdef LPC176x +# define WDT_CLKSEL_WDSEL_SHIFT (0) /* Bits 0-1: Clock source for the Watchdog timer */ +# define WDT_CLKSEL_WDSEL_MASK (3 << WDT_CLKSEL_WDSEL_SHIFT) +# define WDT_CLKSEL_WDSEL_INTRC (0 << WDT_CLKSEL_WDSEL_SHIFT) /* Internal RC osc */ +# define WDT_CLKSEL_WDSEL_APB (1 << WDT_CLKSEL_WDSEL_SHIFT) /* APB peripheral clock (watchdog pclk) */ +# define WDT_CLKSEL_WDSEL_RTC (2 << WDT_CLKSEL_WDSEL_SHIFT) /* RTC oscillator (rtc_clk) */ + /* Bits 2-30: Reserved */ +# define WDT_CLKSEL_WDLOCK (1 << 31) /* Bit 31: Lock WDT register bits if set */ +#endif + +/* Watchdog timer warning interrupt register */ + +#ifdef LPC178x +# define WDT_WARNINT (0x3ff) /* Bits 0-9: Warning Interrupt compare value */ + /* Bits 10-31: Reserved */ +#endif + +/* Watchdog timer value register */ + +#ifdef LPC178x +# define WDT_WINDOW (0xffffff) /* Bits 0-23: Watchdog window value */ + /* Bits 24-31: Reserved */ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H */ diff --git a/arch/arm/src/lpc17xx/lpc176x_clockconfig.c b/arch/arm/src/lpc17xx/lpc176x_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..d74e2b8dc836e1ba7b6e73570c4bb8e514c762d3 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc176x_clockconfig.c @@ -0,0 +1,220 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_clockconfig.c + * arch/arm/src/chip/lpc17_clockconfig.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "lpc17_clockconfig.h" +#include "chip/lpc17_syscon.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef LPC176x +# error "The logic in this file applies only to the LPC176x family" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: lpc17_clockconfig + * + * Description: + * Called to initialize the LPC176x. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + * The LPC176x and LPC178x system control block is *nearly* identical but we have + * found that the LPC178x is more sensitive to the ordering of certain operations. + * So, although the hardware seems very similar, the safer thing to do is to + * separate the LPC176x and LPC178x into separate files. + * + ************************************************************************************/ + +void lpc17_clockconfig(void) +{ + /* Enable the main oscillator (or not) and the frequency range of the main oscillator */ + + putreg32(BOARD_SCS_VALUE, LPC17_SYSCON_SCS); + + /* Wait for the main oscillator to be ready. */ + +#ifdef CONFIG_LPC17_MAINOSC + while ((getreg32(LPC17_SYSCON_SCS) & SYSCON_SCS_OSCSTAT) == 0); +#endif + + /* Setup up the divider value for the CPU clock. The output of the divider is CCLK. + * The input to the divider (PLLCLK) is equal to SYSCLK unless PLL0 is enabled. CCLK + * will be further divided to produce peripheral clocks, but that peripheral clock + * setup is performed in the peripheral device drivers. Here only CCLK is + * configured. + */ + + putreg32(BOARD_CCLKCFG_VALUE, LPC17_SYSCON_CCLKCFG); + + /* PLL0 is used to generate the CPU clock divider input (PLLCLK). */ + +#ifdef CONFIG_LPC17_PLL0 + /* Select the PLL0 source clock, multiplier, and pre-divider values. NOTE that + * a special "feed" sequence must be written to the PLL0FEED register in order + * for changes to the PLL0CFG register to take effect. + */ + + putreg32(BOARD_CLKSRCSEL_VALUE, LPC17_SYSCON_CLKSRCSEL); + putreg32(BOARD_PLL0CFG_VALUE, LPC17_SYSCON_PLL0CFG); + putreg32(0xaa, LPC17_SYSCON_PLL0FEED); + putreg32(0x55, LPC17_SYSCON_PLL0FEED); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL0FEED register in order for changes to the PLL0CON register to take effect. + */ + + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL0CON); + putreg32(0xaa, LPC17_SYSCON_PLL0FEED); + putreg32(0x55, LPC17_SYSCON_PLL0FEED); + + /* Wait for PLL0 to lock */ + + while ((getreg32(LPC17_SYSCON_PLL0STAT) & SYSCON_PLL0STAT_PLOCK) == 0); + + /* Enable and connect PLL0 */ + + putreg32(SYSCON_PLLCON_PLLE | SYSCON_PLLCON_PLLC, LPC17_SYSCON_PLL0CON); + putreg32(0xaa, LPC17_SYSCON_PLL0FEED); + putreg32(0x55, LPC17_SYSCON_PLL0FEED); + + /* Wait for PLL to report that it is connected and enabled */ + + while ((getreg32(LPC17_SYSCON_PLL0STAT) & (SYSCON_PLL0STAT_PLLE | SYSCON_PLL0STAT_PLLC)) + != (SYSCON_PLL0STAT_PLLE | SYSCON_PLL0STAT_PLLC)); + +#endif /* CONFIG_LPC17_PLL0 */ + + /* PLL1 receives its clock input from the main oscillator only and can be used to + * provide a fixed 48 MHz clock only to the USB subsystem (if that clock cannot be + * obtained from PLL0). + */ + +#ifdef CONFIG_LPC17_PLL1 + /* Select the PLL1 multiplier, and pre-divider values. NOTE that a special "feed" + * sequence must be written to the PLL1FEED register in order for changes to the + * PLL1CFG register to take effect. + */ + + putreg32(BOARD_PLL1CFG_VALUE, LPC17_SYSCON_PLL1CFG); + putreg32(0xaa, LPC17_SYSCON_PLL1FEED); + putreg32(0x55, LPC17_SYSCON_PLL1FEED); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL1FEED register in order for changes to the PLL1CON register to take effect. + */ + + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL1CON); + putreg32(0xaa, LPC17_SYSCON_PLL1FEED); + putreg32(0x55, LPC17_SYSCON_PLL1FEED); + + /* Wait for PLL1 to lock */ + + while ((getreg32(LPC17_SYSCON_PLL1STAT) & SYSCON_PLL1STAT_PLOCK) == 0); + + /* Enable and connect PLL1 */ + + putreg32(SYSCON_PLLCON_PLLE | SYSCON_PLLCON_PLLC, LPC17_SYSCON_PLL1CON); + putreg32(0xaa, LPC17_SYSCON_PLL1FEED); + putreg32(0x55, LPC17_SYSCON_PLL1FEED); + + /* Wait for PLL to report that it is connected and enabled */ + + while ((getreg32(LPC17_SYSCON_PLL1STAT) & (SYSCON_PLL1STAT_PLLE | SYSCON_PLL1STAT_PLLC)) + != (SYSCON_PLL1STAT_PLLE | SYSCON_PLL1STAT_PLLC)); + +#else /* CONFIG_LPC17_PLL1 */ + + /* Otherwise, setup up the USB clock divider to generate the USB clock from PLL0 */ + + putreg32(BOARD_USBCLKCFG_VALUE, LPC17_SYSCON_USBCLKCFG); + +#endif /* CONFIG_LPC17_PLL1 */ + + /* Disable all peripheral clocks. They must be configured by each device driver + * when the device driver is initialized. + */ + + putreg32(0, LPC17_SYSCON_PCLKSEL0); + putreg32(0, LPC17_SYSCON_PCLKSEL1); + + /* Disable power to all peripherals (execpt GPIO). Peripherals must be re-powered + * one at a time by each device driver when the driver is initialized. + */ + + putreg32(SYSCON_PCONP_PCGPIO, LPC17_SYSCON_PCONP); + + /* Disable CLKOUT */ + + putreg32(0, LPC17_SYSCON_CLKOUTCFG); + + /* Configure FLASH */ + +#ifdef CONFIG_LPC17_FLASH + putreg32(BOARD_FLASHCFG_VALUE, LPC17_SYSCON_FLASHCFG); +#endif +} diff --git a/arch/arm/src/lpc17xx/lpc176x_gpio.c b/arch/arm/src/lpc17xx/lpc176x_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..7de2fd04bcce93b7001a1a16e54951537170fd97 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc176x_gpio.c @@ -0,0 +1,685 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc176x_gpio.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc17_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Default input pin configuration */ + +#define DEFAULT_INPUT (GPIO_INPUT|GPIO_PULLUP) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* These tables have global scope because they are also used in + * lpc17_gpiodbg.c + */ + +/* We have to remember the configured interrupt setting.. PINs are not + * actually set up to interrupt until the interrupt is enabled. + */ + +#ifdef CONFIG_GPIO_IRQ +uint64_t g_intedge0; +uint64_t g_intedge2; +#endif + +/* FIO register base addresses */ + +const uint32_t g_fiobase[GPIO_NPORTS] = +{ + LPC17_FIO0_BASE, + LPC17_FIO1_BASE, + LPC17_FIO2_BASE, + LPC17_FIO3_BASE, + LPC17_FIO4_BASE +#if GPIO_NPORTS > 5 + , LPC17_FIO5_BASE +#endif +}; + +/* Port 0 and Port 2 can provide a single interrupt for any combination of + * port pins + */ + +const uint32_t g_intbase[GPIO_NPORTS] = +{ + LPC17_GPIOINT0_BASE, + 0, + LPC17_GPIOINT2_BASE, + 0, + 0 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +const uint32_t g_lopinsel[GPIO_NPORTS] = +{ + LPC17_PINCONN_PINSEL0, + LPC17_PINCONN_PINSEL2, + LPC17_PINCONN_PINSEL4, + 0, + 0 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +const uint32_t g_hipinsel[GPIO_NPORTS] = +{ + LPC17_PINCONN_PINSEL1, + LPC17_PINCONN_PINSEL3, + 0, + LPC17_PINCONN_PINSEL7, + LPC17_PINCONN_PINSEL9 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +const uint32_t g_lopinmode[GPIO_NPORTS] = +{ + LPC17_PINCONN_PINMODE0, + LPC17_PINCONN_PINMODE2, + LPC17_PINCONN_PINMODE4, + 0, + 0 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +const uint32_t g_hipinmode[GPIO_NPORTS] = +{ + LPC17_PINCONN_PINMODE1, + LPC17_PINCONN_PINMODE3, + 0, + LPC17_PINCONN_PINMODE7, + LPC17_PINCONN_PINMODE9 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +const uint32_t g_odmode[GPIO_NPORTS] = +{ + LPC17_PINCONN_ODMODE0, + LPC17_PINCONN_ODMODE1, + LPC17_PINCONN_ODMODE2, + LPC17_PINCONN_ODMODE3, + LPC17_PINCONN_ODMODE4 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_pinsel + * + * Description: + * Get the address of the PINSEL register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +static int lpc17_pinsel(unsigned int port, unsigned int pin, unsigned int value) +{ + const uint32_t *table; + uint32_t regaddr; + uint32_t regval; + unsigned int shift; + + /* Which table do we use */ + + if (pin < 16) + { + table = g_lopinsel; + shift = PINCONN_PINSELL_SHIFT(pin); + } + else + { + table = g_hipinsel; + shift = PINCONN_PINSELH_SHIFT(pin); + } + + /* Fetch the PINSEL register address for this port/pin combination */ + + regaddr = table[port]; + if (regaddr != 0) + { + /* Set the requested value in the PINSEL register */ + + regval = getreg32(regaddr); + regval &= ~(PINCONN_PINSEL_MASK << shift); + regval |= (value << shift); + putreg32(regval, regaddr); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_pullup + * + * Description: + * Get the address of the PINMODE register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +static int lpc17_pullup(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + const uint32_t *table; + uint32_t regaddr; + uint32_t regval; + uint32_t value; + unsigned int shift; + + switch (cfgset & GPIO_PUMODE_MASK) + { + default: + case GPIO_PULLUP: /* Pull-up resistor enabled */ + value = PINCONN_PINMODE_PU; + break; + + case GPIO_REPEATER: /* Repeater mode enabled */ + value = PINCONN_PINMODE_RM; + break; + + case GPIO_FLOAT: /* Neither pull-up nor -down */ + value = PINCONN_PINMODE_FLOAT; + break; + + case GPIO_PULLDN: /* Pull-down resistor enabled */ + value = PINCONN_PINMODE_PD; + break; + } + + /* Which table do we use */ + + if (pin < 16) + { + table = g_lopinmode; + shift = PINCONN_PINMODEL_SHIFT(pin); + } + else + { + table = g_hipinmode; + shift = PINCONN_PINMODEH_SHIFT(pin); + } + + /* Fetch the PINSEL register address for this port/pin combination */ + + regaddr = table[port]; + if (regaddr != 0) + { + /* Set the requested value in the PINSEL register */ + + regval = getreg32(regaddr); + regval &= ~(PINCONN_PINMODE_MASK << shift); + regval |= (value << shift); + putreg32(regval, regaddr); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_setintedge + * + * Description: + * Remember the configured interrupt edge. We can't actually enable the + * the edge interrupts until the called calls IRQ enabled function. + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +static void lpc17_setintedge(unsigned int port, unsigned int pin, + unsigned int value) +{ + uint64_t *intedge; + unsigned int shift; + + /* Which word to we use? */ + + if (port == 0) + { + intedge = &g_intedge0; + } + else if (port == 2) + { + intedge = &g_intedge2; + } + else + { + return; + } + + /* Set the requested value in the PINSEL register */ + + shift = pin << 1; + *intedge &= ~((uint64_t)3 << shift); + *intedge |= ((uint64_t)value << shift); +} +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Name: lpc17_setopendrain + * + * Description: + * Set the ODMODE register for open drain mode + * + ****************************************************************************/ + +static void lpc17_setopendrain(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = g_odmode[port]; + regval = getreg32(regaddr); + regval |= (1 << pin); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_clropendrain + * + * Description: + * Reset the ODMODE register to disable open drain mode + * + ****************************************************************************/ + +static void lpc17_clropendrain(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = g_odmode[port]; + regval = getreg32(regaddr); + regval &= ~(1 << pin); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_configinput + * + * Description: + * Configure a GPIO inpue pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configinput(lpc17_pinset_t cfgset, unsigned int port, unsigned int pin) +{ + uint32_t regval; + uint32_t fiobase; + uint32_t intbase; + uint32_t pinmask = (1 << pin); + + /* Set up FIO registers */ + + fiobase = g_fiobase[port]; + + /* Set as input */ + + regval = getreg32(fiobase + LPC17_FIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, fiobase + LPC17_FIO_DIR_OFFSET); + + /* Set up interrupt registers */ + + intbase = g_intbase[port]; + if (intbase != 0) + { + /* Disable any rising edge interrupts */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC17_GPIOINT_INTENR_OFFSET); + + /* Disable any falling edge interrupts */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC17_GPIOINT_INTENF_OFFSET); + + /* Forget about any falling/rising edge interrupt enabled */ + +#ifdef CONFIG_GPIO_IRQ + lpc17_setintedge(port, pin, 0); +#endif + } + + /* Set up PINSEL registers */ + /* Configure as GPIO */ + + lpc17_pinsel(port, pin, PINCONN_PINSEL_GPIO); + + /* Set pull-up mode */ + + lpc17_pullup(cfgset, port, pin); + + /* Open drain only applies to outputs */ + + lpc17_clropendrain(port, pin); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_configinterrupt + * + * Description: + * Configure a GPIO interrupt pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configinterrupt(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(cfgset, port, pin); + + /* Then just remember the rising/falling edge interrupt enabled */ + + DEBUGASSERT(port == 0 || port == 2); +#ifdef CONFIG_GPIO_IRQ + lpc17_setintedge(port, pin, (cfgset & GPIO_EDGE_MASK) >> GPIO_EDGE_SHIFT); +#endif + return OK; +} + +/**************************************************************************** + * Name: lpc17_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configoutput(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t fiobase; + uint32_t regval; + + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(DEFAULT_INPUT, port, pin); + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Set pull-up mode. This normally only applies to input pins, but does have + * meaning if the port is an open drain output. + */ + + lpc17_pullup(cfgset, port, pin); + + /* Select open drain output */ + + lpc17_setopendrain(port, pin); + } + + /* Set the initial value of the output */ + + lpc17_gpiowrite(cfgset, ((cfgset & GPIO_VALUE) != GPIO_VALUE_ZERO)); + + /* Now, reconfigure the pin as an output */ + + fiobase = g_fiobase[port]; + regval = getreg32(fiobase + LPC17_FIO_DIR_OFFSET); + regval |= (1 << pin); + putreg32(regval, fiobase + LPC17_FIO_DIR_OFFSET); + + + return OK; +} + +/**************************************************************************** + * Name: lpc17_configalternate + * + * Description: + * Configure a GPIO alternate function pin based on bit-encoded description + * of the pin. + * + ****************************************************************************/ + +static int lpc17_configalternate(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin, uint32_t alt) +{ + /* First, configure the port as an input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(DEFAULT_INPUT, port, pin); + + /* Set up PINSEL registers */ + /* Configure as GPIO */ + + lpc17_pinsel(port, pin, alt); + + /* Set pull-up mode */ + + lpc17_pullup(cfgset, port, pin); + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Select open drain output */ + + lpc17_setopendrain(port, pin); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int lpc17_configgpio(lpc17_pinset_t cfgset) +{ + unsigned int port; + unsigned int pin; + int ret = -EINVAL; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the pin number and select the port configuration register for that pin */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Handle according to pin function */ + + switch (cfgset & GPIO_FUNC_MASK) + { + case GPIO_INPUT: /* GPIO input pin */ + ret = lpc17_configinput(cfgset, port, pin); + break; + + case GPIO_INTFE: /* GPIO interrupt falling edge */ + case GPIO_INTRE: /* GPIO interrupt rising edge */ + case GPIO_INTBOTH: /* GPIO interrupt both edges */ + ret = lpc17_configinterrupt(cfgset, port, pin); + break; + + case GPIO_OUTPUT: /* GPIO outpout pin */ + ret = lpc17_configoutput(cfgset, port, pin); + break; + + case GPIO_ALT1: /* Alternate function 1 */ + ret = lpc17_configalternate(cfgset, port, pin, PINCONN_PINSEL_ALT1); + break; + + case GPIO_ALT2: /* Alternate function 2 */ + ret = lpc17_configalternate(cfgset, port, pin, PINCONN_PINSEL_ALT2); + break; + + case GPIO_ALT3: /* Alternate function 3 */ + ret = lpc17_configalternate(cfgset, port, pin, PINCONN_PINSEL_ALT3); + break; + + default: + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void lpc17_gpiowrite(lpc17_pinset_t pinset, bool value) +{ + uint32_t fiobase; + uint32_t offset; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + fiobase = g_fiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + offset = LPC17_FIO_SET_OFFSET; + } + else + { + offset = LPC17_FIO_CLR_OFFSET; + } + + putreg32((1 << pin), fiobase + offset); + } +} + +/**************************************************************************** + * Name: lpc17_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool lpc17_gpioread(lpc17_pinset_t pinset) +{ + uint32_t fiobase; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + fiobase = g_fiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(fiobase + LPC17_FIO_PIN_OFFSET) & (1 << pin)) != 0); + } + + return false; +} diff --git a/arch/arm/src/lpc17xx/lpc176x_gpio.h b/arch/arm/src/lpc17xx/lpc176x_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..acdd1dcf695c480edb61de6063ace6af4d24e1c5 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc176x_gpio.h @@ -0,0 +1,197 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc176x_gpio.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC176X_GPIO_H +#define __ARCH_ARM_SRC_LPC17XX_LPC176X_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Bit-encoded input to lpc17_configgpio() ******************************************/ + +/* Encoding: FFFx MMOV PPPN NNNN + * + * Pin Function: FFF + * Pin Mode bits: MM + * Open drain: O (output pins) + * Initial value: V (output pins) + * Port number: PPP (0-4) + * Pin number: NNNNN (0-31) + */ + +/* Pin Function bits: FFF + * Only meaningful when the GPIO function is GPIO_PIN + */ + +#define GPIO_FUNC_SHIFT (13) /* Bits 13-15: GPIO mode */ +#define GPIO_FUNC_MASK (7 << GPIO_FUNC_SHIFT) +# define GPIO_INPUT (0 << GPIO_FUNC_SHIFT) /* 000 GPIO input pin */ +# define GPIO_INTFE (1 << GPIO_FUNC_SHIFT) /* 001 GPIO interrupt falling edge */ +# define GPIO_INTRE (2 << GPIO_FUNC_SHIFT) /* 010 GPIO interrupt rising edge */ +# define GPIO_INTBOTH (3 << GPIO_FUNC_SHIFT) /* 011 GPIO interrupt both edges */ +# define GPIO_OUTPUT (4 << GPIO_FUNC_SHIFT) /* 100 GPIO outpout pin */ +# define GPIO_ALT1 (5 << GPIO_FUNC_SHIFT) /* 101 Alternate function 1 */ +# define GPIO_ALT2 (6 << GPIO_FUNC_SHIFT) /* 110 Alternate function 2 */ +# define GPIO_ALT3 (7 << GPIO_FUNC_SHIFT) /* 111 Alternate function 3 */ + +#define GPIO_EDGE_SHIFT (13) /* Bits 13-14: Interrupt edge bits */ +#define GPIO_EDGE_MASK (3 << GPIO_EDGE_SHIFT) + +#define GPIO_INOUT_MASK GPIO_OUTPUT +#define GPIO_FE_MASK GPIO_INTFE +#define GPIO_RE_MASK GPIO_INTRE + +#define GPIO_ISGPIO(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) <= GPIO_OUTPUT) +#define GPIO_ISALT(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) > GPIO_OUTPUT) +#define GPIO_ISINPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_INPUT) +#define GPIO_ISOUTPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_OUTPUT) +#define GPIO_ISINORINT(ps) (((ps) & GPIO_INOUT_MASK) == 0) +#define GPIO_ISOUTORALT(ps) (((ps) & GPIO_INOUT_MASK) != 0) +#define GPIO_ISINTERRUPT(ps) (GPIO_ISOUTPUT(ps) && !GPIO_ISINPUT(ps)) +#define GPIO_ISFE(ps) (((ps) & GPIO_FE_MASK) != 0) +#define GPIO_ISRE(ps) (((ps) & GPIO_RE_MASK) != 0) + +/* Pin Mode: MM */ + +#define GPIO_PUMODE_SHIFT (10) /* Bits 10-11: Pin pull-up mode */ +#define GPIO_PUMODE_MASK (3 << GPIO_PUMODE_SHIFT) +# define GPIO_PULLUP (0 << GPIO_PUMODE_SHIFT) /* Pull-up resistor enabled */ +# define GPIO_REPEATER (1 << GPIO_PUMODE_SHIFT) /* Repeater mode enabled */ +# define GPIO_FLOAT (2 << GPIO_PUMODE_SHIFT) /* Neither pull-up nor -down */ +# define GPIO_PULLDN (3 << GPIO_PUMODE_SHIFT) /* Pull-down resistor enabled */ + +/* Open drain: O */ + +#define GPIO_OPEN_DRAIN (1 << 9) /* Bit 9: Open drain mode */ + +/* Initial value: V */ + +#define GPIO_VALUE (1 << 8) /* Bit 8: Initial GPIO output value */ +#define GPIO_VALUE_ONE GPIO_VALUE +#define GPIO_VALUE_ZERO (0) + +/* Port number: PPP (0-4) */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT0 (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT1 (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT2 (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT3 (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT4 (4 << GPIO_PORT_SHIFT) + +#define GPIO_NPORTS 5 + +/* Pin number: NNNNN (0-31) */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef uint16_t lpc17_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* These tables have global scope only because they are shared between lpc17_gpio.c, + * lpc17_gpioint.c, and lpc17_gpiodbg.c + */ + +EXTERN const uint32_t g_lopinsel[GPIO_NPORTS]; +EXTERN const uint32_t g_hipinsel[GPIO_NPORTS]; +EXTERN const uint32_t g_lopinmode[GPIO_NPORTS]; +EXTERN const uint32_t g_hipinmode[GPIO_NPORTS]; +EXTERN const uint32_t g_odmode[GPIO_NPORTS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC176X_GPIO_H */ diff --git a/arch/arm/src/lpc17xx/lpc176x_rtc.c b/arch/arm/src/lpc17xx/lpc176x_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..a0aa525ff736ccd5d172ef4e8d5ac111a781014c --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc176x_rtc.c @@ -0,0 +1,444 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc176x_rtcc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" + +#include "lpc17_rtc.h" + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error "CONFIG_RTC_DATETIME must be set to use this driver" +#endif + +#ifdef CONFIG_RTC_HIRES +# error "CONFIG_RTC_HIRES must NOT be set with this driver" +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +/* Constants ************************************************************************/ + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" DOM : %08x\n", (getreg32(LPC17_RTC_DOM) & RTC_DOM_MASK)); + rtclldbg(" DOW : %08x\n", (getreg32(LPC17_RTC_DOW) & RTC_DOW_MASK)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_setup + * + * Description: + * Performs first time configuration of the RTC. A special value written into + * back-up register 0 will prevent this function from being called on sub-sequent + * resets or power up. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_setup(void) +{ + uint32_t regval; + + /* Clear all register to be default */ + + putreg32((uint32_t)0x00, LPC17_RTC_ILR); + putreg32((uint32_t)0x00, LPC17_RTC_CCR); + putreg32((uint32_t)0x00, LPC17_RTC_CIIR); + putreg32((uint32_t)0xff, LPC17_RTC_AMR); + putreg32((uint32_t)0x00, LPC17_RTC_CALIB); + + /* Enable power to the RTC module */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCRTC; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Enable counters */ + + putreg32((uint32_t)0x01, LPC17_RTC_CCR); + return OK; +} + +/************************************************************************************ + * Name: rtc_resume + * + * Description: + * Called when the RTC was already initialized on a previous power cycle. This + * just brings the RTC back into full operation. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_resume(void) +{ + /* Clear the RTC alarm flags */ + +#ifdef CONFIG_RTC_ALARM +#endif + return OK; +} + +/************************************************************************************ + * Name: rtc_interrupt + * + * Description: + * RTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_interrupt(int irq, void *context) +{ +#warning "Missing logic" + return OK; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + int ret; + + rtc_dumpregs("On reset"); + + /* Attach the RTC interrupt handler */ + +#ifdef CONFIG_RTC_ALARM + ret = irq_attach(LPC17_IRQ_RTC, rtc_interrupt); + if (ret == OK) + { + up_enable_irq(LPC17_IRQ_RTC); + } +#endif /* CONFIG_RTC_ALARM */ + + /* Perform the one-time setup of the RTC */ + + ret = rtc_setup(); + + /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are + * connected to the EXTI controller. To enable the RTC Alarm interrupt, the + * following sequence is required: + * + * 1. Configure and enable the EXTI Line 17 in interrupt mode and select the + * rising edge sensitivity. + * 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC. + * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B). + */ + + g_rtc_enabled = true; + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time to fields in struct tm format. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tp->tm_sec = ((getreg32(LPC17_RTC_SEC) & RTC_SEC_MASK)); + tp->tm_min = ((getreg32(LPC17_RTC_MIN) & RTC_MIN_MASK)); + tp->tm_hour = ((getreg32(LPC17_RTC_HOUR) & RTC_HOUR_MASK)); + + /* Now convert the RTC date to fields in struct tm format: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + tp->tm_mday = ((getreg32(LPC17_RTC_DOM) & RTC_DOM_MASK)); + tp->tm_mon = ((getreg32(LPC17_RTC_MONTH) & RTC_MONTH_MASK)) - 1; + tp->tm_year = ((getreg32(LPC17_RTC_YEAR) & RTC_YEAR_MASK)-1900); + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + + /* Break out the time values (not that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + rtc_dumptime(&newtime, "Setting time"); + + /* Then write the broken out values to the RTC */ + + putreg32(((newtime.tm_sec) & RTC_SEC_MASK), LPC17_RTC_SEC); + putreg32(((newtime.tm_min) & RTC_MIN_MASK), LPC17_RTC_MIN); + putreg32(((newtime.tm_hour) & RTC_HOUR_MASK), LPC17_RTC_HOUR); + putreg32(((newtime.tm_mday) & RTC_DOM_MASK), LPC17_RTC_DOM); + putreg32((((newtime.tm_mon)+1) & RTC_MONTH_MASK), LPC17_RTC_MONTH); + putreg32(((newtime.tm_year) & RTC_YEAR_MASK)+1900, LPC17_RTC_YEAR); + + return OK; +} + +/************************************************************************************ + * Name: lpc17_rtc_setalarm + * + * Description: + * Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B). + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int lpc17_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Break out the time values */ +#warning "Missing logic" + + /* The set the alarm */ +#warning "Missing logic" + + ret = OK; + } + return ret; +} +#endif + +#endif /* CONFIG_RTC */ diff --git a/arch/arm/src/lpc17xx/lpc178x_clockconfig.c b/arch/arm/src/lpc17xx/lpc178x_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..948c17d7f330be686a0b54ebd55b1639360a9a20 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc178x_clockconfig.c @@ -0,0 +1,233 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_clockconfig.c + * arch/arm/src/chip/lpc17_clockconfig.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "lpc17_clockconfig.h" +#include "chip/lpc17_syscon.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef LPC178x +# error "The logic in this file applies only to the LPC178x family" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: lpc17_clockconfig + * + * Description: + * Called to initialize the LPC17xx. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + * The LPC176x and LPC178x system control block is *nearly* identical but we have + * found that the LPC178x is more sensitive to the ordering of certain operations. + * So, although the hardware seems very similar, the safer thing to do is to + * separate the LPC176x and LPC178x into separate files. + * + ************************************************************************************/ + +void lpc17_clockconfig(void) +{ + /* TODO: + * + * (1) "Make sure that the PLL output is not already being used. The CCLKSEL, + * USBCLKSEL, and SPIFICLKSEL registers must not select the PLL being set up. + * Clock dividers included in these registers may also be set up at this time + * if writing to any of the noted registers." + * + * (2) "If the main PLL is being set up, and the main clock source is being changed + * (IRC versus main oscillator), change this first by writing the correct + * value to the CLKSRCSEL register." + * + * This is not an issue now because we only setup the clocks on power up, so the + * PLL cannot be the select source. However, this could be an issue at some point + * later when, for example, we may want to implement reduced power mode with other + * clocking. + */ + + /* Enable the main oscillator (or not) and the frequency range of the main oscillator */ + + putreg32(BOARD_SCS_VALUE, LPC17_SYSCON_SCS); + + /* Wait for the main oscillator to be ready. */ + +#ifdef CONFIG_LPC17_MAINOSC + while ((getreg32(LPC17_SYSCON_SCS) & SYSCON_SCS_OSCSTAT) == 0); +#endif + + /* PLL0 is used to generate the CPU clock divider input (PLLCLK). */ + +#ifdef CONFIG_LPC17_PLL0 + /* (3) "Write PLL new setup values to the PLLCFG register. Write a 1 to the + * PLLE bit in the PLLCON register. Perform a PLL feed sequence by writing + * first the value 0xAA, then the value 0x55 to the PLLFEED register" + * + * Select the PLL0 source clock, multiplier, and pre-divider values. NOTE that + * a special "feed" sequence must be written to the PLL0FEED register in order + * for changes to the PLL0CFG register to take effect. + */ + + putreg32(BOARD_CLKSRCSEL_VALUE, LPC17_SYSCON_CLKSRCSEL); + putreg32(BOARD_PLL0CFG_VALUE, LPC17_SYSCON_PLL0CFG); + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL0CON); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL0FEED register in order for changes to the PLL0CON register to take effect. + */ + + putreg32(0xaa, LPC17_SYSCON_PLL0FEED); + putreg32(0x55, LPC17_SYSCON_PLL0FEED); + + /* (4) "Set up the necessary clock dividers. These may include the CCLKSEL, + * PCLKSEL, EMCCLKSEL, USBCLKSEL, and the SPIFICLKSEL registers. + */ + + putreg32(BOARD_CCLKSEL_VALUE, LPC17_SYSCON_CCLKSEL); + putreg32(BOARD_PCLKDIV, LPC17_SYSCON_PCLKSEL); + +#ifdef CONFIG_LPC17_EMC + putreg32(BOARD_EMCCLKSEL_VALUE, LPC17_SYSCON_EMCCLKSEL); +#endif +#if defined(CONFIG_LPC17_USBDEV) || defined(CONFIG_LPC17_USBHOST) + putreg32(BOARD_USBCLKSEL_VALUE, LPC17_SYSCON_USBCLKSEL); +#endif +#ifdef CONFIG_LPC17_SPIFI + putreg32(BOARD_SPIFICLKSEL_VALUE, LPC17_SPIFICLKSEL_CCLKSEL); +#endif + + /* (5) "Wait for the PLL to lock. This may be accomplished by polling the + * PLLSTAT register and testing for PLOCK = 1, or by using the PLL lock + * interrupt.Wait for PLL0 to lock. + */ + + while ((getreg32(LPC17_SYSCON_PLL0STAT) & SYSCON_PLL0STAT_PLOCK) == 0); + + /* (6) "Connect the PLL by selecting its output in the appropriate places. This + * may include the CCLKSEL, USBCLKSEL, and SPIFICLKSEL registers. + */ + +#endif /* CONFIG_LPC17_PLL0 */ + + /* PLL1 receives its clock input from the main oscillator only and can be used to + * provide a fixed 48 MHz clock only to the USB subsystem (if that clock cannot be + * obtained from PLL0). + */ + +#ifdef CONFIG_LPC17_PLL1 + /* (3) "Write PLL new setup values to the PLLCFG register. Write a 1 to the + * PLLE bit in the PLLCON register. Perform a PLL feed sequence by writing + * first the value 0xAA, then the value 0x55 to the PLLFEED register" + * + * Select the PLL1 multiplier, and pre-divider values. NOTE that a special "feed" + * sequence must be written to the PLL1FEED register in order for changes to the + * PLL1CFG register to take effect. + */ + + putreg32(BOARD_PLL1CFG_VALUE, LPC17_SYSCON_PLL1CFG); + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL1CON); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL1FEED register in order for changes to the PLL1CON register to take effect. + */ + + putreg32(0xaa, LPC17_SYSCON_PLL1FEED); + putreg32(0x55, LPC17_SYSCON_PLL1FEED); + + /* (4) "Set up the necessary clock dividers. These may include the CCLKSEL, + * PCLKSEL, EMCCLKSEL, USBCLKSEL, and the SPIFICLKSEL registers. + */ + + /* (5) "Wait for the PLL to lock. This may be accomplished by polling the + * PLLSTAT register and testing for PLOCK = 1, or by using the PLL lock + * interrupt.Wait for PLL0 to lock. + */ + + while ((getreg32(LPC17_SYSCON_PLL1STAT) & SYSCON_PLL1STAT_PLOCK) == 0); + + /* (6) "Connect the PLL by selecting its output in the appropriate places. This + * may include the CCLKSEL, USBCLKSEL, and SPIFICLKSEL registers. + */ + +#endif /* CONFIG_LPC17_PLL1 */ + + /* Disable power to all peripherals (execpt GPIO). Peripherals must be re-powered + * one at a time by each device driver when the driver is initialized. + */ + + putreg32(SYSCON_PCONP_PCGPIO, LPC17_SYSCON_PCONP); + + /* Disable CLKOUT */ + + putreg32(0, LPC17_SYSCON_CLKOUTCFG); + + /* Configure FLASH */ + +#ifdef CONFIG_LPC17_FLASH + putreg32(BOARD_FLASHCFG_VALUE, LPC17_SYSCON_FLASHCFG); +#endif +} + diff --git a/arch/arm/src/lpc17xx/lpc178x_gpio.c b/arch/arm/src/lpc17xx/lpc178x_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..a30b7d425583a47695c00a8dcecb5b6f0cae56e9 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc178x_gpio.c @@ -0,0 +1,942 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc178x_gpio.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * With LPC178x extensions from Rommel Marcelo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc17_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Default input pin configuration */ + +#define DEFAULT_INPUT (GPIO_INPUT|GPIO_PULLUP) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* These tables have global scope because they are also used in + * lpc17_gpiodbg.c + */ + +/* We have to remember the configured interrupt setting.. PINs are not + * actually set up to interrupt until the interrupt is enabled. + */ + +#ifdef CONFIG_GPIO_IRQ +uint64_t g_intedge0; +uint64_t g_intedge2; +#endif + +/* FIO register base addresses */ + +const uint32_t g_fiobase[GPIO_NPORTS] = +{ + LPC17_FIO0_BASE, + LPC17_FIO1_BASE, + LPC17_FIO2_BASE, + LPC17_FIO3_BASE, + LPC17_FIO4_BASE +#if GPIO_NPORTS > 5 + , LPC17_FIO5_BASE +#endif +}; + +/* Port 0 and Port 2 can provide a single interrupt for any combination of + * port pins + */ + +const uint32_t g_intbase[GPIO_NPORTS] = +{ + LPC17_GPIOINT0_BASE, + 0, + LPC17_GPIOINT2_BASE, + 0, + 0 +#if GPIO_NPORTS > 5 + , 0 +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_getioconmask + * + * Description: + * Get the LPC178x IOCON register mask. + * + * Type D: FUNC, MODE, HYS, INV, SLEW, OD - + * Type A: FUNC, MODE, INV, ADMODE, FILTER, OD, DACEN -P0[12:13,23:26],P1[30:31] + * Type U: FUNC -P0[29:31] + * Type I: FUNC, INV, HS, HIDRIVE -P0[27:28], P5[2:3] + * Type W: FUNC, MODE, HYS, INV, FILTER, SLEW, OD -P0[7:9] + * + ****************************************************************************/ + +#if 0 /* Not used */ +static uint32_t lpc17_getioconmask(unsigned int port, unsigned int pin) +{ + uint32_t typemask = IOCON_TYPE_D_MASK; + + /* Select the mask based on pin usage */ + + switch (port) + { + case 0: + switch (pin) + { + case 7: + case 8: + case 9: + typemask = IOCON_TYPE_W_MASK; + break; + + case 12: + case 13: + case 23: + case 24: + case 25: + case 26: + typemask = IOCON_TYPE_A_MASK; + break; + + case 27: + case 28: + typemask = IOCON_TYPE_I_MASK; + break; + + case 29: + case 30: + case 31: + typemask = IOCON_TYPE_U_MASK; + break; + + default: + break; + } + break; + + case 1: + switch (pin) + { + case 30: + case 31: + typemask = IOCON_TYPE_A_MASK; + break; + + default: + break; + } + break; + + case 5: + switch (pin) + { + case 2: + case 3: + typemask = IOCON_TYPE_I_MASK; + break; + + default: + break; + } + break; + + default: + break; + } + + return typemask; +} +#endif + +/**************************************************************************** + * Name: lpc17_seti2cmode + * + * Description: + * Configure I2C pin drive mode. Applies to Type I pins + * + ****************************************************************************/ + +static void lpc17_seti2cmode(unsigned int port, unsigned int pin, + uint32_t value) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval &= ~IOCON_I2CMODE_MASK; + regval |= ((value << IOCON_I2CMODE_SHIFT) & IOCON_I2CMODE_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setpinfunction + * + * Description: + * Select pin function. + * + ****************************************************************************/ + +static void lpc17_setpinfunction(unsigned int port, unsigned int pin, + unsigned int value) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + + regval &= ~IOCON_FUNC_MASK; + regval |= ((value << IOCON_FUNC_SHIFT) & IOCON_FUNC_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setinvertinput + * + * Description: + * Configure pin input polarity. Applies to Type D, A, I and W pins. + * + ****************************************************************************/ + +static void lpc17_setinvertinput(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval |= IOCON_INV_MASK; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setslewfast + * + * Description: + * Configure pin mode slew rate drive. Applies to Type D and Type W pins + * + ****************************************************************************/ + +static void lpc17_setslewmode(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t value; + + /* Decode the request output slew rate */ + + value = ((cfgset & GPIO_SLEW_MASK) >> GPIO_SLEW_SHIFT); + + /* Get the current IOCON register contents */ + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + + /* Set the driver slew rate */ + + regval &= ~IOCON_SLEW_MASK; + regval |= ((value << IOCON_SLEW_SHIFT) & IOCON_SLEW_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setmodedigital + * + * Description: + * Configure pin mode as analog or digital IO. Applies to Type A pins + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc17_setmodedigital(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval |= IOCON_ADMODE_MASK; + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: lpc17_setmodeanalog + * + * Description: + * Configure pin mode as analog or digital IO. Applies to Type A pins + * + ****************************************************************************/ + +static void lpc17_setmodeanalog(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval &= ~IOCON_ADMODE_MASK; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setdacenable + * + * Description: + * Configure DAC output. Applies to Type A pins P0:26 only + * + ****************************************************************************/ + +static void lpc17_setdacenable(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval |= IOCON_DACEN_MASK; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setdacdisable + * + * Description: + * Configure DAC output. Applies to Type A pins P0:26 only + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc17_setdacdisable(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval &= ~IOCON_DACEN_MASK; + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: lpc17_setfilter + * + * Description: + * Configure analog pin's glitch filter. Applies to Type A and Type W pins + * + ****************************************************************************/ + +static void lpc17_setfilter(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t value; + + /* Decode the request input filter */ + + value = ((cfgset & GPIO_FILTER_MASK) >> GPIO_FILTER_SHIFT); + + /* Get the current IOCON register contents */ + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + + /* Set the input filter enable bit */ + + regval &= ~IOCON_FILTER_MASK; + regval |= ((value << IOCON_FILTER_SHIFT) & IOCON_FILTER_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setopendrain + * + * Description: + * Configure a GPIO's opendrain mode. Applies to Type A, Type D, and + * Type W pins. + * + ****************************************************************************/ + +static void lpc17_setopendrain(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval |= IOCON_OD_MASK; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_clropendrain + * + * Description: + * Configure a GPIO's opendrain mode. Applies to Type A, Type D, and + * Type W pins. + * + ****************************************************************************/ + +static void lpc17_clropendrain(unsigned int port, unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + regval &= ~IOCON_OD_MASK; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_sethysteresis + * + * Description: + * Configure a GPIO's hysteresis mode. Applies to Type D and Type W pins + * Default is enabled. + * + ****************************************************************************/ + +static void lpc17_sethysteresis(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t value; + + /* Decode the request input buffer */ + + value = ((cfgset & GPIO_HYSTERESIS) >> GPIO_INBUFF_SHIFT); + + /* Get the current IOCON register contents */ + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + + /* Set the input buffer enable bit */ + + regval &= ~IOCON_HYS_MASK; + regval |= ((value << IOCON_HYS_SHIFT) & IOCON_HYS_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_pullup + * + * Description: + * Clear and set the pin mode bits. Applies to Type A, Type D, and + * Type W pins. + * + ****************************************************************************/ + +static void lpc17_setpullup(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t pinmode; + + /* Decode the request pull-up mode */ + + pinmode = ((cfgset & GPIO_PUMODE_MASK) >> GPIO_PUMODE_SHIFT); + + /* Get the current IOCON register contents */ + + regaddr = LPC17_IOCON_P(port, pin); + regval = getreg32(regaddr); + + /* Set the new mode bits */ + + regval &= ~IOCON_MODE_MASK; + regval |= ((pinmode << IOCON_MODE_SHIFT) & IOCON_MODE_MASK); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: lpc17_setintedge + * + * Description: + * Remember the configured interrupt edge. We can't actually enable the + * the edge interrupts until the called calls IRQ enabled function. + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +static void lpc17_setintedge(unsigned int port, unsigned int pin, + unsigned int value) +{ + uint64_t *intedge; + unsigned int shift; + + /* Which word to we use? */ + + if (port == 0) + { + intedge = &g_intedge0; + } + else if (port == 2) + { + intedge = &g_intedge2; + } + else + { + return; + } + + /* Set the requested value in the PINSEL register */ + + shift = pin << 1; + *intedge &= ~((uint64_t)3 << shift); + *intedge |= ((uint64_t)value << shift); +} +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Name: lpc17_configinput + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configinput(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t regval; + uint32_t fiobase; + uint32_t intbase; + uint32_t pinmask = (1 << pin); + + /* Set up FIO registers */ + + fiobase = g_fiobase[port]; + + /* Set as input */ + + regval = getreg32(fiobase + LPC17_FIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, fiobase + LPC17_FIO_DIR_OFFSET); + + /* Set up interrupt registers */ + + intbase = g_intbase[port]; + if (intbase != 0) + { + /* Disable any rising edge interrupts */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC17_GPIOINT_INTENR_OFFSET); + + /* Disable any falling edge interrupts */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET); + regval &= ~pinmask; + putreg32(regval, intbase + LPC17_GPIOINT_INTENF_OFFSET); + + /* Forget about any falling/rising edge interrupt enabled */ + +#ifdef CONFIG_GPIO_IRQ + lpc17_setintedge(port, pin, 0); +#endif + } + + /* Set pull-up mode */ + + lpc17_setpullup(cfgset, port, pin); + + /* Clear opendrain */ + + lpc17_clropendrain(port, pin); + + /* Set input polarity */ + + if ((cfgset & GPIO_INVERT) != 0) + { + lpc17_setinvertinput(port, pin); + } + + /* Set input hysteresis */ + + lpc17_sethysteresis(cfgset, port, pin); + + /* Set input filtering */ + + lpc17_setfilter(cfgset, port, pin); + + /* Configure as GPIO */ + + lpc17_setpinfunction(port, pin, IOCON_FUNC_GPIO); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_configinterrupt + * + * Description: + * Configure a GPIO interrupt pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configinterrupt(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(cfgset, port, pin); + + /* Then just remember the rising/falling edge interrupt enabled */ + + DEBUGASSERT(port == 0 || port == 2); +#ifdef CONFIG_GPIO_IRQ + lpc17_setintedge(port, pin, (cfgset & GPIO_EDGE_MASK) >> GPIO_EDGE_SHIFT); +#endif + return OK; +} + +/**************************************************************************** + * Name: lpc17_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int lpc17_configoutput(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin) +{ + uint32_t fiobase; + uint32_t regval; + + /* First, configure the port as a generic input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(DEFAULT_INPUT, port, pin); + + /* Now, reconfigure the pin as an output */ + + fiobase = g_fiobase[port]; + regval = getreg32(fiobase + LPC17_FIO_DIR_OFFSET); + regval |= (1 << pin); + putreg32(regval, fiobase + LPC17_FIO_DIR_OFFSET); + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Set pull-up mode. This normally only applies to input pins, but does have + * meaning if the port is an open drain output. + */ + + lpc17_setpullup(cfgset, port, pin); + + /* Select open drain output */ + + lpc17_setopendrain(port, pin); + } + + /* Set output slew rate */ + + lpc17_setslewmode(cfgset, port, pin); + + /* Set the initial value of the output */ + + lpc17_gpiowrite(cfgset, ((cfgset & GPIO_VALUE) != GPIO_VALUE_ZERO)); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_configalternate + * + * Description: + * Configure a GPIO alternate function pin based on bit-encoded description + * of the pin. + * + ****************************************************************************/ + +static int lpc17_configalternate(lpc17_pinset_t cfgset, unsigned int port, + unsigned int pin, uint32_t alt) +{ + uint32_t i2cmode; + + /* First, configure the port as an input so that we have a known + * starting point and consistent behavior during the re-configuration. + */ + + (void)lpc17_configinput(DEFAULT_INPUT, port, pin); + + /* Set pull-up mode */ + + lpc17_setpullup(cfgset, port, pin); + + /* Check for analog mode */ + + if ((cfgset & GPIO_MODE_ANALOG) != 0) + { + lpc17_setmodeanalog(port, pin); + + /* Check for DAC output enable */ + + if ((cfgset & GPIO_DACEN) != 0) + { + lpc17_setdacenable(port, pin); + } + } + + /* Check for I2C modes */ + + if ((cfgset & (GPIO_I2CHS | GPIO_HIDRIVE)) != 0) + { + /* Isolate the I2C mode bits */ + + i2cmode = ((cfgset & GPIO_I2CMODE_MASK) >> GPIO_I2CMODE_SHIFT); + + /* Set I2C Modes */ + + lpc17_seti2cmode(port, pin, i2cmode); + } + + /* Check for open drain output */ + + if ((cfgset & GPIO_OPEN_DRAIN) != 0) + { + /* Select open drain output */ + + lpc17_setopendrain(port, pin); + } + + /* Set output slew rate */ + + lpc17_setslewmode(cfgset, port, pin); + + /* Select the alternate pin */ + + lpc17_setpinfunction(port, pin, alt); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int lpc17_configgpio(lpc17_pinset_t cfgset) +{ + unsigned int port; + unsigned int pin; + + int ret = -EINVAL; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the pin number and select the port configuration register for + * that pin. + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Handle according to pin function */ + + switch (cfgset & GPIO_FUNC_MASK) + { + case GPIO_INPUT: /* GPIO input pin */ + ret = lpc17_configinput(cfgset, port, pin); + break; + + case GPIO_INTFE: /* GPIO interrupt falling edge */ + case GPIO_INTRE: /* GPIO interrupt rising edge */ + case GPIO_INTBOTH: /* GPIO interrupt both edges */ + ret = lpc17_configinterrupt(cfgset, port, pin); + break; + + case GPIO_OUTPUT: /* GPIO outpout pin */ + ret = lpc17_configoutput(cfgset, port, pin); + break; + + case GPIO_ALT1: /* Alternate function 1 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT1); + break; + + case GPIO_ALT2: /* Alternate function 2 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT2); + break; + + case GPIO_ALT3: /* Alternate function 3 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT3); + break; + + case GPIO_ALT4: /* Alternate function 4 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT4); + break; + + case GPIO_ALT5: /* Alternate function 5 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT5); + break; + + case GPIO_ALT6: /* Alternate function 6 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT6); + break; + + case GPIO_ALT7: /* Alternate function 7 */ + ret = lpc17_configalternate(cfgset, port, pin, IOCON_FUNC_ALT7); + break; + + default: + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void lpc17_gpiowrite(lpc17_pinset_t pinset, bool value) +{ + uint32_t fiobase; + uint32_t offset; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + fiobase = g_fiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + offset = LPC17_FIO_SET_OFFSET; + } + else + { + offset = LPC17_FIO_CLR_OFFSET; + } + + putreg32((1 << pin), fiobase + offset); + } +} + +/**************************************************************************** + * Name: lpc17_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool lpc17_gpioread(lpc17_pinset_t pinset) +{ + uint32_t fiobase; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < GPIO_NPORTS) + { + /* Get the port base address */ + + fiobase = g_fiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(fiobase + LPC17_FIO_PIN_OFFSET) & (1 << pin)) != 0); + } + + return false; +} diff --git a/arch/arm/src/lpc17xx/lpc178x_gpio.h b/arch/arm/src/lpc17xx/lpc178x_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..2ddfd6ce6bcdc1b3b017760d4c65d8e1694eea6f --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc178x_gpio.h @@ -0,0 +1,225 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc178x_gpio.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC178X_GPIO_H +#define __ARCH_ARM_SRC_LPC17XX_LPC178X_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Bit-encoded input to lpc17_configgpio() ******************************************/ + +/* Encoding: TTTT TTTT FFFF MMOV PPPN NNNN + * + * Special Pin Functions: TTTT TTTT + * Pin Function: FFFF + * Pin Mode bits: MM + * Open drain: O (output pins) + * Initial value: V (output pins) + * Port number: PPP (0-4) + * Pin number: NNNNN (0-31) + */ + +/* Special Pin Functions + * For pins that have ADC/DAC, USB, I2C + */ + +#define GPIO_INBUFF_SHIFT (16) /* Bit 16: HYSTERESIS: 0-Disable, 1-Enabled */ +#define GPIO_INBUFF_MASK (1 << GPIO_INBUFF_SHIFT) +# define GPIO_HYSTERESIS (1 << GPIO_INBUFF_SHIFT) + +#define GPIO_INVERT (1 << 17) /* Bit 17: Input: 0-Not Inverted, 1-Inverted */ + +#define GPIO_SLEW_SHIFT (18) /* Bit 18: Rate Control: 0-Standard mode, 1-Fast mode */ +#define GPIO_SLEW_MASK (1 << GPIO_SLEW_SHIFT) +# define GPIO_SLEW_NORMAL (0 << GPIO_SLEW_SHIFT) +# define GPIO_SLEW_FAST (1 << GPIO_SLEW_SHIFT) + +#define GPIO_ADMODE_SHIFT (19) /* Bit 19: A/D Modes: 0-Analog, 1-Digital */ +#define GPIO_ADMODE_MASK (1 << GPIO_ADMODE_SHIFT) +# define GPIO_MODE_DIGITAL (0 << GPIO_ADMODE_SHIFT) +# define GPIO_MODE_ANALOG (1 << GPIO_ADMODE_SHIFT) + +#define GPIO_FILTER_SHIFT (20) /* Bit 20: Filter: 0-Off, 1-ON */ +#define GPIO_FILTER_MASK (1 << GPIO_FILTER_SHIFT) +# define GPIO_FILTER_OFF (0 << GPIO_FILTER_SHIFT) +# define GPIO_FILTER_ON (1 << GPIO_FILTER_SHIFT) + +#define GPIO_DACEN (1 << 21) /* Bit 21: DAC: 0-Disabled, 1-Enabled, P0:26 only */ + +#define GPIO_I2CMODE_SHIFT (22) /* Bits 22-23: I2C mode */ +#define GPIO_I2CMODE_MASK (3 << GPIO_I2CMODE_SHIFT) +# define GPIO_I2CHS (1 << 22) /* Bit 22: Filter and Rate Control: 0-Enabled, 1-Disabled */ +# define GPIO_HIDRIVE (1 << 23) /* Bit 23: Current Sink: 0-4mA, 1-20mA P5:2 and P5:3 only,*/ + +/* Pin Function bits: FFFF + * Only meaningful when the GPIO function is GPIO_PIN + */ + +#define GPIO_FUNC_SHIFT (12) /* Bits 12-15: GPIO mode */ +#define GPIO_FUNC_MASK (15 << GPIO_FUNC_SHIFT) +# define GPIO_INPUT (0 << GPIO_FUNC_SHIFT) /* 0000 GPIO input pin */ +# define GPIO_INTFE (1 << GPIO_FUNC_SHIFT) /* 0001 GPIO interrupt falling edge */ +# define GPIO_INTRE (2 << GPIO_FUNC_SHIFT) /* 0010 GPIO interrupt rising edge */ +# define GPIO_INTBOTH (3 << GPIO_FUNC_SHIFT) /* 0011 GPIO interrupt both edges */ +# define GPIO_OUTPUT (4 << GPIO_FUNC_SHIFT) /* 0100 GPIO outpout pin */ +# define GPIO_ALT1 (5 << GPIO_FUNC_SHIFT) /* 0101 Alternate function 1 */ +# define GPIO_ALT2 (6 << GPIO_FUNC_SHIFT) /* 0110 Alternate function 2 */ +# define GPIO_ALT3 (7 << GPIO_FUNC_SHIFT) /* 0111 Alternate function 3 */ +# define GPIO_ALT4 (8 << GPIO_FUNC_SHIFT) /* 1000 Alternate function 4 */ +# define GPIO_ALT5 (9 << GPIO_FUNC_SHIFT) /* 1001 Alternate function 5 */ +# define GPIO_ALT6 (10 << GPIO_FUNC_SHIFT) /* 1010 Alternate function 6 */ +# define GPIO_ALT7 (11 << GPIO_FUNC_SHIFT) /* 1011 Alternate function 7 */ + +#define GPIO_EDGE_SHIFT (12) /* Bits 12-13: Interrupt edge bits */ +#define GPIO_EDGE_MASK (3 << GPIO_EDGE_SHIFT) + +#define GPIO_INOUT_MASK GPIO_OUTPUT +#define GPIO_FE_MASK GPIO_INTFE +#define GPIO_RE_MASK GPIO_INTRE + +#define GPIO_ISGPIO(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) <= GPIO_OUTPUT) +#define GPIO_ISALT(ps) ((uint16_t(ps) & GPIO_FUNC_MASK) > GPIO_OUTPUT) +#define GPIO_ISINPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_INPUT) +#define GPIO_ISOUTPUT(ps) (((ps) & GPIO_FUNC_MASK) == GPIO_OUTPUT) +#define GPIO_ISINORINT(ps) (((ps) & GPIO_INOUT_MASK) == 0) +#define GPIO_ISOUTORALT(ps) (((ps) & GPIO_INOUT_MASK) != 0) +#define GPIO_ISINTERRUPT(ps) (GPIO_ISOUTPUT(ps) && !GPIO_ISINPUT(ps)) +#define GPIO_ISFE(ps) (((ps) & GPIO_FE_MASK) != 0) +#define GPIO_ISRE(ps) (((ps) & GPIO_RE_MASK) != 0) + +/* Pin Mode: MM */ + +#define GPIO_PUMODE_SHIFT (10) /* Bits 10-11: Pin pull-up mode */ +#define GPIO_PUMODE_MASK (3 << GPIO_PUMODE_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUMODE_SHIFT) /* Neither pull-up nor -down */ +# define GPIO_PULLDN (1 << GPIO_PUMODE_SHIFT) /* Pull-down resistor enabled */ +# define GPIO_PULLUP (2 << GPIO_PUMODE_SHIFT) /* Pull-up resistor enabled */ +# define GPIO_REPEATER (3 << GPIO_PUMODE_SHIFT) /* Repeater mode enabled */ + +/* Open drain: O */ + +#define GPIO_OPEN_DRAIN (1 << 9) /* Bit 9: Open drain mode */ + +/* Initial value: V */ + +#define GPIO_VALUE (1 << 8) /* Bit 8: Initial GPIO output value */ +# define GPIO_VALUE_ONE GPIO_VALUE +# define GPIO_VALUE_ZERO (0) + +/* Port number: PPP (0-5) */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT0 (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT1 (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT2 (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT3 (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT4 (4 << GPIO_PORT_SHIFT) +# define GPIO_PORT5 (5 << GPIO_PORT_SHIFT) + +#define GPIO_NPORTS 6 + +/* Pin number: NNNNN (0-31) */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef uint32_t lpc17_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC178X_GPIO_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_adc.c b/arch/arm/src/lpc17xx/lpc17_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..9d761c6afad7e0daeaf56c1599dc75d91c3e6580 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_adc.c @@ -0,0 +1,602 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_adc.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010, 2013, 2016 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_adc.h" + +#if defined(CONFIG_LPC17_ADC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ADC0_MASK +#define CONFIG_ADC0_MASK 0x01 +#endif +#ifndef CONFIG_ADC0_SPS +#define CONFIG_ADC0_SPS 1000 +#endif +#ifndef CONFIG_ADC0_AVERAGE +#define CONFIG_ADC0_AVERAGE 200 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint8_t mask; + uint32_t sps; + int irq; + int32_t buf[8]; + uint8_t count[8]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* ADC methods */ + +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); +static int adc_interrupt(int irq, void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset = adc_reset, + .ao_setup = adc_setup, + .ao_shutdown = adc_shutdown, + .ao_rxint = adc_rxint, + .ao_ioctl = adc_ioctl, +}; + +static struct up_dev_s g_adcpriv = +{ + .sps = CONFIG_ADC0_SPS, + .mask = CONFIG_ADC0_MASK, + .irq = LPC17_IRQ_ADC, +}; + +static struct adc_dev_s g_adcdev = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before adc_setup() and on error conditions. + * + ****************************************************************************/ + +static void adc_reset(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + irqstate_t flags; + uint32_t clkdiv; + uint32_t regval; + + flags = enter_critical_section(); + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCADC; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Power up before we access hardware */ + + putreg32(ADC_CR_PDN, LPC17_ADC_CR); + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_ADC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_ADC_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + +#ifdef CONFIG_ADC_BURSTMODE + clkdiv = LPC17_CCLK / 3 / 65 / priv->sps; + +//putreg32(0x04, LPC17_ADC_INTEN); /* Enable only last channel interrupt */ + putreg32(0x100, LPC17_ADC_INTEN); /* Enable only global interrupt */ + + putreg32((priv->mask) | /* Select channels 0 to 7 on ADC0 */ +// (clkdiv) << 8) | /* CLKDIV = divisor to make the samples +// * per second conversion rate */ + ((32) << 8) | /* CLKDIV = divisor to make the faster + * conversion rate */ + (0 << 16) | /* BURST = 0, BURST capture all selected + * channels */ + (1 << 17) | /* Reserved bit = 0 */ + (1 << 21) | /* PDN = 1, normal operation */ + (1 << 26) | (0 << 25) | (0 << 24) | /* START = at MAT0 signal */ + (1 << 27), /* EDGE = 1 (CAP/MAT signal rising + * trigger A/D conversion) */ + LPC17_ADC_CR); + +#else /* CONFIG_ADC_BURSTMODE */ + + clkdiv = LPC17_CCLK / 8 / 65 / priv->sps; + clkdiv <<= 8; + clkdiv &= 0xff00; + putreg32(ADC_CR_PDN | ADC_CR_BURST | clkdiv | priv->mask, LPC17_ADC_CR); + +#endif /* CONFIG_ADC_BURSTMODE */ + + if ((priv->mask & 0x01) != 0) + { + lpc17_configgpio(GPIO_AD0p0); + } + + if ((priv->mask & 0x02) != 0) + { + lpc17_configgpio(GPIO_AD0p1); + } + + if ((priv->mask & 0x04) != 0) + { + lpc17_configgpio(GPIO_AD0p2); + } + + if ((priv->mask & 0x08) != 0) + { + lpc17_configgpio(GPIO_AD0p3); + } + + if ((priv->mask & 0x10) != 0) + { + lpc17_configgpio(GPIO_AD0p4); + } + + if ((priv->mask & 0x20) != 0) + { + lpc17_configgpio(GPIO_AD0p5); + } + + if ((priv->mask & 0x40) != 0) + { + lpc17_configgpio(GPIO_AD0p6); + } + + if ((priv->mask & 0x80) != 0) + { + lpc17_configgpio(GPIO_AD0p7); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. Interrupts + * are all disabled upon return. + * + ****************************************************************************/ + +static int adc_setup(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + int i; + + int ret = irq_attach(priv->irq, adc_interrupt); + if (ret == OK) + { + for (i = 0; i < 8; i++) + { + priv->buf[i] = 0; + priv->count[i] = 0; + } + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + ****************************************************************************/ + +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + /* Disable ADC interrupts, both at the level of the ADC device and at the + * level of the NVIC. + */ + + putreg32(0, LPC17_ADC_INTEN); + up_disable_irq(priv->irq); + + /* Then detach the ADC interrupt handler. */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: adc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + if (enable) + { +#ifndef CONFIG_ADC_BURSTMODE +#ifdef CONFIG_ADC_CHANLIST + /* Trigger interrupt at the end of conversion on the last A/D channel + * in the channel list. + */ + + putreg32(ADC_INTEN_CHAN(g_adc_chanlist[CONFIG_ADC_NCHANNELS - 1]), + LPC17_ADC_INTEN); +#else + /* Trigger interrupt using the global DONE flag. */ + + putreg32(ADC_INTEN_GLOBAL, LPC17_ADC_INTEN); +#endif +#else /* CONFIG_ADC_BURSTMODE */ + /* Enable only global interrupt */ + + putreg32(0x100, LPC17_ADC_INTEN); +#endif /* CONFIG_ADC_BURSTMODE */ + } + else + { + putreg32(0, LPC17_ADC_INTEN); + } +} + +/**************************************************************************** + * Name: adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + /* No ioctl commands supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Name: adc_interrupt + * + * Description: + * ADC interrupt handler + * + ****************************************************************************/ + +static int adc_interrupt(int irq, void *context) +{ +#ifndef CONFIG_ADC_BURSTMODE +#ifdef CONFIG_ADC_CHANLIST + + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; + uint32_t regval; + unsigned char ch; + int32_t value; + int i; + + regval = getreg32(LPC17_ADC_GDR); + for (i = 0; i < CONFIG_ADC_NCHANNELS; i++) + { + ch = g_adc_chanlist[i]; + regval = getreg32(LPC17_ADC_DR(ch)); + + if (regval&ADC_DR_DONE) + { + priv->count[ch]++; + priv->buf[ch] += regval & 0xfff0; + + if (priv->count[ch] >= CONFIG_ADC0_AVERAGE) + { + value = priv->buf[ch] / priv->count[ch]; + value <<= 15; + adc_receive(&g_adcdev, ch, value); + priv->buf[ch] = 0; + priv->count[ch] = 0; + } + } + } + + return OK; + +#else + + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; + uint32_t regval; + unsigned char ch; + int32_t value; + + regval = getreg32(LPC17_ADC_GDR); + ch = (regval >> 24) & 0x07; + priv->buf[ch] += regval & 0xfff0; + + priv->count[ch]++; + if (priv->count[ch] >= CONFIG_ADC0_AVERAGE) + { + value = priv->buf[ch] / priv->count[ch]; + value <<= 15; + adc_receive(&g_adcdev, ch, value); + priv->buf[ch] = 0; + priv->count[ch] = 0; + } + + return OK; + +#endif +#else /* CONFIG_ADC_BURSTMODE */ + + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; + volatile uint32_t regVal, regVal2, regVal3; + + /* Verify that an interrupt has actually occured */ + + regVal2 = getreg32(LPC17_ADC_STAT); /* Read ADSTAT will clear the interrupt flag */ + if ((regVal2) & (1 << 16)) + { + if ((priv->mask & 0x01) != 0) + { + regVal = getreg32(LPC17_ADC_DR0); + +#ifdef CONFIG_ADC_DIRECT_ACCESS + /* Store the data value plus the status bits */ + + ADC0Buffer0[0] = regVal; + ADC0IntDone = 1; +#else /* CONFIG_ADC_DIRECT_ACCESS */ +#ifdef CONFIG_ADC_WORKER_THREAD + /* Store the data value plus the status bits */ + + ADC0Buffer0[0] = regVal; + ADC0IntDone = 1; + +#else /* CONFIG_ADC_WORKER_THREAD */ + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 0, (regVal >> 4) & 0xFFF); + } + +#endif /* CONFIG_ADC_WORKER_THREAD */ +#endif /* CONFIG_ADC_DIRECT_ACCESS */ + } + + if ((priv->mask & 0x02) != 0) + { + regVal = getreg32(LPC17_ADC_DR1); + +#ifdef CONFIG_ADC_DIRECT_ACCESS + /* Store the data value plus the status bits */ + + ADC1Buffer0[0] = regVal; + ADC0IntDone = 1; + +#else /* CONFIG_ADC_DIRECT_ACCESS */ +#ifdef CONFIG_ADC_WORKER_THREAD + /* Store the data value plus the status bits */ + + ADC1Buffer0[0] = regVal; + ADC0IntDone = 1; + +#else /* CONFIG_ADC_WORKER_THREAD */ + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 1, (regVal >> 4) & 0xFFF); + } + +#endif /* CONFIG_ADC_WORKER_THREAD */ +#endif /* CONFIG_ADC_DIRECT_ACCESS */ + } + + if ((priv->mask & 0x04) != 0) + { + regVal = getreg32(LPC17_ADC_DR2); + +#ifdef CONFIG_ADC_DIRECT_ACCESS + /* Store the data value plus the status bits */ + + ADC2Buffer0[0] = regVal; + ADC0IntDone = 1; + +#else /* CONFIG_ADC_DIRECT_ACCESS */ +#ifdef CONFIG_ADC_WORKER_THREAD + /* Store the data value plus the status bits */ + + ADC2Buffer0[0] = regVal; + ADC0IntDone = 1; + +#else /* CONFIG_ADC_WORKER_THREAD */ + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 2, (regVal >> 4) & 0xFFF); + } + +#endif /* CONFIG_ADC_WORKER_THREAD */ +#endif /* CONFIG_ADC_DIRECT_ACCESS */ + } + + if ((priv->mask & 0x08) != 0) + { + regVal = getreg32(LPC17_ADC_DR3); + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 3, (regVal >> 4) & 0xFFF); + } + } + + if ((priv->mask & 0x10) != 0) + { + regVal = getreg32(LPC17_ADC_DR4); + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 4, (regVal >> 4) & 0xFFF); + } + } + + if ((priv->mask & 0x20) != 0) + { + regVal = getreg32(LPC17_ADC_DR5); + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 5, (regVal >> 4) & 0xFFF); + } + } + + if ((priv->mask & 0x40) != 0) + { + regVal = getreg32(LPC17_ADC_DR6); + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 6, (regVal >> 4) & 0xFFF); + } + } + + if ((priv->mask & 0x80) != 0) + { + regVal = getreg32(LPC17_ADC_DR7); + if ((regVal) & (1 << 31)) + { + adc_receive(&g_adcdev, 7, (regVal >> 4) & 0xFFF); + } + } + +#ifdef CONFIG_ADC_WORKER_THREAD + if (ADC0IntDone == 1) + { + work_queue(HPWORK, &priv->irqwork, (worker_t)adc_irqworker, + (FAR void *)priv, 0); + } + +#endif /* CONFIG_ADC_WORKER_THREAD */ + } + + regVal3 = getreg32(LPC17_ADC_GDR); /* Read ADGDR clear the DONE and OVERRUN bits */ + putreg32((priv->mask) | /* Select channels 0 to 7 on ADC0 */ + (32 << 8) | /* CLKDIV = 16 */ + (0 << 16) | /* BURST = 1, BURST capture all selected channels */ + (1 << 17) | /* Reserved bit = 0 */ + (1 << 21) | /* PDN = 1, normal operation */ + (1 << 26) | (0 << 25) | (0 << 24) | /* START = at MAT0 signal */ + (1 << 27), /* EDGE = 1 (CAP/MAT signal rising trigger A/D + * conversion) */ + LPC17_ADC_CR); + +//lpc17_gpiowrite(LPCXPRESSO_GPIO0_21, 0); /* Reset pin P0.21 */ +//leave_critical_section(saved_state); + return OK; +#endif /* CONFIG_ADC_BURSTMODE */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_adcinitialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct adc_dev_s *lpc17_adcinitialize(void) +{ + return &g_adcdev; +} + +#endif /* CONFIG_LPC17_ADC */ diff --git a/arch/arm/src/lpc17xx/lpc17_adc.h b/arch/arm/src/lpc17xx/lpc17_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..d7736b97932aef4eec9e3cd1e3af89e10694c072 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_adc.h @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_adc.h + * + * Copyright (C) 2010, 2012, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_ADC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_ADC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc17_adc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If CONFIG_ADC_CHANLIST is enabled, then the platform specific code must do + * two things: (1) define CONFIG_ADC_NCHANNELS in the configuration file and + * (2) provide an array g_adc_chanlist[] with the channel numbers matching + * the ADC0_MASK within the board-specific library. + */ + +#ifdef CONFIG_ADC_CHANLIST +# if !defined(CONFIG_ADC_NCHANNELS) +# error "CONFIG_ADC_CHANLIST must defined in this configuration" +# elif CONFIG_ADC_NCHANNELS < 1 +# error "The value of CONFIG_ADC_NCHANNELS is invalid" +# endif +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + + +/* The errata that states: "A/D Global Data register should not be used with + * burst mode or hardware triggering". The configuration option + * CONFIG_ADC_CHANLIST is a workaround for this errata. If this option is + * selected, then the ADC driver will grab from the individual channel + * registers rather than from the global data register as this is the stated + * workaround in the errata. + * + * If this option is enabled, then the platform specific code must do two + * things: (1) define CONFIG_ADC_NCHANNELS in the configuration file and + * (2) provide an array g_adc_chanlist[] with the channel numbers matching + * the ADC0_MASK within the board-specific library. + */ + +#ifdef CONFIG_ADC_CHANLIST +EXTERN uint8_t g_adc_chanlist[CONFIG_ADC_NCHANNELS]; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_adcinitialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_ADC +FAR struct adc_dev_s *lpc17_adcinitialize(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_ADC_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_allocateheap.c b/arch/arm/src/lpc17xx/lpc17_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..20568f0457f7efa62315da17bca90be2222b56dc --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_allocateheap.c @@ -0,0 +1,363 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_allocateheap.c + * + * Copyright (C) 2010-2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/lpc17_memorymap.h" +#include "lpc17_emacram.h" +#include "lpc17_ohciram.h" +#include "lpc17_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* The configured RAM start address must be the beginning of CPU SRAM */ + +#if CONFIG_RAM_START != LPC17_SRAM_BASE +# warning "CONFIG_RAM_START is not at LPC17_SRAM_BASE" +# undef CONFIG_RAM_START +# undef CONFIG_RAM_END +# define CONFIG_RAM_START LPC17_SRAM_BASE +# define CONFIG_RAM_END (LPC17_SRAM_BASE+LPC17_CPUSRAM_SIZE) +#endif + +/* The configured RAM size must be less then or equal to the CPU SRAM size */ + +#if CONFIG_RAM_SIZE > LPC17_CPUSRAM_SIZE +# warning "CONFIG_RAM_SIZE is larger than the size of CPU SRAM" +# undef CONFIG_RAM_SIZE +# undef CONFIG_RAM_END +# define CONFIG_RAM_SIZE LPC17_CPUSRAM_SIZE +# define CONFIG_RAM_END (LPC17_SRAM_BASE+LPC17_CPUSRAM_SIZE) +#elif CONFIG_RAM_SIZE < LPC17_CPUSRAM_SIZE +# warning "CONFIG_RAM_END is before end of CPU SRAM... not all of CPU SRAM used" +#endif + +/* Figure out how much heap be have in AHB SRAM (if any). Complications: + * 1) AHB SRAM Bank 0 or 1 may on may not be supported in the hardware. + * 2) Some or all of Bank 0 may be used for Ethernet Packet buffering. + * Ethernet packet buffering is used from the beginning of Bank 0 and + * any free memory at the end of Bank 0 will be contiguous with any + * free memory at the beginning of Bank 1. + * 3) Some or all of Bank 1 may be used for OHCI descriptor memory. OCHI + * memory is used from the end of Bank 1 and any free memory at the + * beginning of Bank 1 will be contiguous with any free memory at the + * end of Bank 0. + */ + +#undef LPC17_AHB_HEAPBASE /* Assume that nothing is available */ +#undef LPC17_AHB_HEAPSIZE + +/* If we have Bank 0, then we may possibly also have Bank 1 */ + +#ifdef LPC17_HAVE_BANK0 + + /* We have BANK0 (and, hence, possibly Bank1). Is Bank0 all used for + * Ethernet packet buffering? Or is there any part of Bank0 available for + * the heap. + */ + +# ifdef LPC17_BANK0_HEAPSIZE + + /* Some or all of Bank0 is available for the heap. The heap will begin + * in bank 1. + */ + +# define LPC17_AHB_HEAPBASE LPC17_BANK0_HEAPBASE + + /* Is Bank1 present? Has there available heap memory in Bank 1? */ + +# if defined(LPC17_HAVE_BANK1) && defined(LPC17_BANK1_HEAPSIZE) + + /* Yes... the heap space available is the unused memory at the end + * of Bank0 plus the unused memory at the beginning of Bank 1. + */ + +# define LPC17_AHB_HEAPSIZE (LPC17_BANK0_HEAPSIZE + LPC17_BANK1_HEAPSIZE) +# else + + /* No... the heap space available is only the unused memory at the + * end of Bank 0. + */ + +# define LPC17_AHB_HEAPSIZE LPC17_BANK0_HEAPSIZE + +# endif /* LPC17_HAVE_BANK1 && LPC17_BANK1_HEAPSIZE */ +# else /* !LPC17_BANK0_HEAPSIZE */ + + /* We have Bnak 0, but no memory is available for the heap there. + * Do we have Bank 1? Is any heap memory available in Bank 1? + */ + +# if defined(LPC17_HAVE_BANK1) && defined(LPC17_BANK1_HEAPSIZE) + + /* Yes... the heap space available is the unused memory at the + * beginning of Bank1. + */ + +# define LPC17_AHB_HEAPBASE LPC17_BANK1_HEAPBASE +# define LPC17_AHB_HEAPSIZE LPC17_BANK1_HEAPSIZE + +# endif /* LPC17_HAVE_BANK1 && LPC17_BANK1_HEAPSIZE */ +# endif /* LPC17_BANK0_HEAPSIZE */ +#endif /* LPC17_HAVE_BANK0 */ + +/* Sanity checking */ + +#if !defined(CONFIG_LPC17_EXTDRAMHEAP) && !defined(CONFIG_LPC17_EXTSRAM0HEAP) +# define LPC17_EXT_MM_REGIONS 0 +#elif defined(CONFIG_LPC17_EXTDRAMHEAP) && defined(CONFIG_LPC17_EXTSRAM0HEAP) +# define LPC17_EXT_MM_REGIONS 2 +#else +# define LPC17_EXT_MM_REGIONS 1 +#endif + +#ifdef LPC17_AHB_HEAPBASE +# if CONFIG_MM_REGIONS < 2 + LPC17_EXT_MM_REGIONS +# warning "CONFIG_MM_REGIONS < 2: Available AHB SRAM Bank(s) not included in HEAP" +# endif +# if (CONFIG_MM_REGIONS > 2 + LPC17_EXT_MM_REGIONS) +# warning "CONFIG_MM_REGIONS > 2: Are additional regions handled by application?" +# endif +#else +# if CONFIG_MM_REGIONS > 1 + LPC17_EXT_MM_REGIONS +# warning "CONFIG_MM_REGIONS > 1: This configuration has no available AHB SRAM Bank0/1" +# warning "CONFIG_MM_REGIONS > 1: Are additional regions handled by application?" +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + lpc17_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + /* Banks 0 and 1 are each 16Kb. If both are present, they occupy a + * contiguous 32Kb memory region. + * + * If Ethernet is enabled, it will take some or all of bank 0 for packet + * buffering and descriptor tables; If USB host is enabled, it will take + * some or all of bank 1 for descriptor memory. The complex conditional + * compilation above should boil this all down to a very simple check + * here: + * + * Is any memory available in AHB SRAM for the heap? + */ + +#ifdef LPC17_AHB_HEAPBASE +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Yes.. allow user-mode access to the AHB SRAM user heap memory */ + + lpc17_mpu_uheap((uintptr_t)LPC17_AHB_HEAPBASE, LPC17_AHB_HEAPSIZE); + +#endif + + /* Add the AHB SRAM user heap region. */ + + kumm_addregion((FAR void *)LPC17_AHB_HEAPBASE, LPC17_AHB_HEAPSIZE); + +#endif + +#if CONFIG_MM_REGIONS >= 3 +#if defined(CONFIG_LPC17_EXTDRAM) && defined(CONFIG_LPC17_EXTDRAMHEAP) + kmm_addregion((FAR void *)LPC17_EXTDRAM_CS0, CONFIG_LPC17_EXTDRAMSIZE); +#endif +#if !defined(CONFIG_LPC17_EXTDRAMHEAP) || (CONFIG_MM_REGIONS >= 4) +#if defined(CONFIG_LPC17_EXTSRAM0) && defined(CONFIG_LPC17_EXTSRAM0HEAP) + kmm_addregion((FAR void *)LPC17_EXTSRAM_CS0, CONFIG_LPC17_EXTSRAM0SIZE); +#endif +#endif +#endif +} +#endif diff --git a/arch/arm/src/lpc17xx/lpc17_can.c b/arch/arm/src/lpc17xx/lpc17_can.c new file mode 100644 index 0000000000000000000000000000000000000000..c3949f2778e0427b0de7aae20582dd6e5ccf223f --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_can.c @@ -0,0 +1,1313 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_can.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Authors: + * Li Zhuoyi + * Gregory Nutt + * History: + * 2011-07-12: Initial version (Li Zhuoyi) + * 2011-08-03: Support CAN1/CAN2 (Li Zhuoyi) + * 2012-01-02: Add support for CAN loopback mode (Gregory Nutt) + * + * This file is a part of NuttX: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_can.h" + +#if defined(CONFIG_LPC17_CAN1) || defined(CONFIG_LPC17_CAN2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_LPC17_CAN1 + + /* A CAN bit rate must be provided */ + +# ifndef CONFIG_CAN1_BAUD +# error "CONFIG_CAN1_BAUD is not defined" +# endif + + /* If no divsor is provided, use a divisor of 4 */ + +# ifndef CONFIG_CAN1_DIVISOR +# define CONFIG_CAN1_DIVISOR 4 +# endif + + /* Get the SYSCON_PCLKSEL value for CAN1 the implements this divisor */ + +# if CONFIG_CAN1_DIVISOR == 1 +# define CAN1_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK +# elif CONFIG_CAN1_DIVISOR == 2 +# define CAN1_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK2 +# elif CONFIG_CAN1_DIVISOR == 4 +# define CAN1_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK4 +# elif CONFIG_CAN1_DIVISOR == 6 +# define CAN1_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK6 +# else +# error "Unsupported value of CONFIG_CAN1_DIVISOR" +# endif +#endif + +#ifdef CONFIG_LPC17_CAN2 + + /* A CAN bit rate must be provided */ + +# ifndef CONFIG_CAN2_BAUD +# error "CONFIG_CAN2_BAUD is not defined" +# endif + + /* If no divsor is provided, use a divisor of 4 */ + +# ifndef CONFIG_CAN2_DIVISOR +# define CONFIG_CAN2_DIVISOR 4 +# endif + + /* Get the SYSCON_PCLKSEL value for CAN2 the implements this divisor */ + +# if CONFIG_CAN2_DIVISOR == 1 +# define CAN2_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK +# elif CONFIG_CAN2_DIVISOR == 2 +# define CAN2_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK2 +# elif CONFIG_CAN2_DIVISOR == 4 +# define CAN2_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK4 +# elif CONFIG_CAN2_DIVISOR == 6 +# define CAN2_CCLK_DIVISOR SYSCON_PCLKSEL_CCLK6 +# else +# error "Unsupported value of CONFIG_CAN2_DIVISOR" +# endif +#endif + +/* User-defined TSEG1 and TSEG2 settings may be used. + * + * CONFIG_CAN_TSEG1 = the number of CAN time quanta in segment 1 + * CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2 + * CAN_BIT_QUANTA = The number of CAN time quanta in on bit time + */ + +#ifndef CONFIG_CAN_TSEG1 +# define CONFIG_CAN_TSEG1 6 +#endif + +#if CONFIG_CAN_TSEG1 < 1 || CONFIG_CAN_TSEG1 > CAN_BTR_TSEG1_MAX +# errror "CONFIG_CAN_TSEG1 is out of range" +#endif + +#ifndef CONFIG_CAN_TSEG2 +# define CONFIG_CAN_TSEG2 7 +#endif + +#if CONFIG_CAN_TSEG2 < 1 || CONFIG_CAN_TSEG2 > CAN_BTR_TSEG2_MAX +# errror "CONFIG_CAN_TSEG2 is out of range" +#endif + +#define CAN_BIT_QUANTA (CONFIG_CAN_TSEG1 + CONFIG_CAN_TSEG2 + 1) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing CAN */ + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_CAN) +# undef CONFIG_CAN_REGDEBUG +#endif + +#ifdef CONFIG_DEBUG_CAN +# ifdef CONFIG_CAN_REGDEBUG +# define candbg lldbg +# define canvdbg llvdbg +# else +# define candbg dbg +# define canvdbg vdbg +# endif +# define canlldbg lldbg +# define canllvdbg llvdbg +#else +# define candbg(x...) +# define canvdbg(x...) +# define canlldbg(x...) +# define canllvdbg(x...) +#endif + +/* Timing *******************************************************************/ +/* CAN clocking is provided at CCLK divided by the configured divisor */ + +#define CAN_CLOCK_FREQUENCY(d) ((uint32_t)LPC17_CCLK / (uint32_t)(d)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint8_t port; /* CAN port number */ + uint8_t divisor; /* CCLK divisor (numeric value) */ + uint32_t baud; /* Configured baud */ + uint32_t base; /* CAN register base address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* CAN Register access */ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_printreg(uint32_t addr, uint32_t value); +#endif + +static uint32_t can_getreg(struct up_dev_s *priv, int offset); +static void can_putreg(struct up_dev_s *priv, int offset, uint32_t value); + +#ifdef CONFIG_CAN_REGDEBUG +static uint32_t can_getcommon(uint32_t addr); +static void can_putcommon(uint32_t addr, uint32_t value); +#else +# define can_getcommon(addr) getreg32(addr) +# define can_putcommon(addr, value) putreg32(value, addr) +#endif + +/* CAN methods */ + +static void can_reset(FAR struct can_dev_s *dev); +static int can_setup(FAR struct can_dev_s *dev); +static void can_shutdown(FAR struct can_dev_s *dev); +static void can_rxint(FAR struct can_dev_s *dev, bool enable); +static void can_txint(FAR struct can_dev_s *dev, bool enable); +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg); +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id); +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg); +static bool can_txready(FAR struct can_dev_s *dev); +static bool can_txempty(FAR struct can_dev_s *dev); + +/* CAN interrupts */ + +static void can_interrupt(FAR struct can_dev_s *dev); +static int can12_interrupt(int irq, void *context); + +/* Initialization */ + +static int can_bittiming(struct up_dev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct can_ops_s g_canops = +{ + .co_reset = can_reset, + .co_setup = can_setup, + .co_shutdown = can_shutdown, + .co_rxint = can_rxint, + .co_txint = can_txint, + .co_ioctl = can_ioctl, + .co_remoterequest = can_remoterequest, + .co_send = can_send, + .co_txready = can_txready, + .co_txempty = can_txempty, +}; + +#ifdef CONFIG_LPC17_CAN1 +static struct up_dev_s g_can1priv = +{ + .port = 1, + .divisor = CONFIG_CAN1_DIVISOR, + .baud = CONFIG_CAN1_BAUD, + .base = LPC17_CAN1_BASE, +}; + +static struct can_dev_s g_can1dev = +{ + .cd_ops = &g_canops, + .cd_priv = &g_can1priv, +}; +#endif + +#ifdef CONFIG_LPC17_CAN2 +static struct up_dev_s g_can2priv = +{ + .port = 2, + .divisor = CONFIG_CAN2_DIVISOR, + .baud = CONFIG_CAN2_BAUD, + .base = LPC17_CAN2_BASE, +}; + +static struct can_dev_s g_can2dev = +{ + .cd_ops = &g_canops, + .cd_priv = &g_can2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: can_printreg + * + * Description: + * Print the value read from a register. + * + * Input Parameters: + * addr - The register address + * value - The register value + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_printreg(uint32_t addr, uint32_t value) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && value == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = value; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, value); +} +#endif + +/**************************************************************************** + * Name: can_getreg + * + * Description: + * Read the value of an CAN1/2 register. + * + * Input Parameters: + * priv - A reference to the CAN block status + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static uint32_t can_getreg(struct up_dev_s *priv, int offset) +{ + uint32_t addr; + uint32_t value; + + /* Read the value from the register */ + + addr = priv->base + offset; + value = getreg32(addr); + can_printreg(addr, value); + return value; +} +#else +static uint32_t can_getreg(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} +#endif + +/**************************************************************************** + * Name: can_putreg + * + * Description: + * Set the value of an CAN1/2 register. + * + * Input Parameters: + * priv - A reference to the CAN block status + * offset - The offset to the register to write + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_putreg(struct up_dev_s *priv, int offset, uint32_t value) +{ + uint32_t addr = priv->base + offset; + + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, value); + + /* Write the value */ + + putreg32(value, addr); +} +#else +static void can_putreg(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} +#endif + +/**************************************************************************** + * Name: can_getcommon + * + * Description: + * Get the value of common register. + * + * Input Parameters: + * addr - The address of the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static uint32_t can_getcommon(uint32_t addr) +{ + uint32_t value; + + /* Read the value from the register */ + + value = getreg32(addr); + can_printreg(addr, value); + return value; +} +#endif + +/**************************************************************************** + * Name: can_putcommon + * + * Description: + * Set the value of common register. + * + * Input Parameters: + * addr - The address of the register to write + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_putcommon(uint32_t addr, uint32_t value) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, value); + + /* Write the value */ + + putreg32(value, addr); +} +#endif + +/**************************************************************************** + * Name: can_reset + * + * Description: + * Reset the CAN device. Called early to initialize the hardware. This + * function is called, before can_setup() and on error conditions. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_reset(FAR struct can_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + irqstate_t flags; + int ret; + + canvdbg("CAN%d\n", priv->port); + + flags = enter_critical_section(); + + /* Disable the CAN and stop ongong transmissions */ + + can_putreg(priv, LPC17_CAN_MOD_OFFSET, CAN_MOD_RM); /* Enter Reset Mode */ + can_putreg(priv, LPC17_CAN_IER_OFFSET, 0); /* Disable interrupts */ + can_putreg(priv, LPC17_CAN_GSR_OFFSET, 0); /* Clear status bits */ + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_AT); /* Abort transmission */ + + /* Set bit timing */ + + ret = can_bittiming(priv); + if (ret != OK) + { + candbg("ERROR: Failed to set bit timing: %d\n", ret); + } + + /* Restart the CAN */ + +#ifdef CONFIG_CAN_LOOPBACK + can_putreg(priv, LPC17_CAN_MOD_OFFSET, CAN_MOD_STM); /* Leave Reset Mode, enter Test Mode */ +#else + can_putreg(priv, LPC17_CAN_MOD_OFFSET, 0); /* Leave Reset Mode */ +#endif + can_putcommon(LPC17_CANAF_AFMR, CANAF_AFMR_ACCBP); /* All RX messages accepted */ + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: can_setup + * + * Description: + * Configure the CAN. This method is called the first time that the CAN + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching CAN interrupts. + * All CAN interrupts are disabled upon return. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_setup(FAR struct can_dev_s *dev) +{ +#ifdef CONFIG_DEBUG_CAN + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; +#endif + int ret; + + canvdbg("CAN%d\n", priv->port); + + ret = irq_attach(LPC17_IRQ_CAN, can12_interrupt); + if (ret == OK) + { + up_enable_irq(LPC17_IRQ_CAN); + } + return ret; +} + +/**************************************************************************** + * Name: can_shutdown + * + * Description: + * Disable the CAN. This method is called when the CAN device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_shutdown(FAR struct can_dev_s *dev) +{ +#ifdef CONFIG_DEBUG_CAN + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + + canvdbg("CAN%d\n", priv->port); +#endif + + up_disable_irq(LPC17_IRQ_CAN); + irq_detach(LPC17_IRQ_CAN); +} + +/**************************************************************************** + * Name: can_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_rxint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + uint32_t regval; + irqstate_t flags; + + canvdbg("CAN%d enable: %d\n", priv->port, enable); + + /* The EIR register is also modifed from the interrupt handler, so we have + * to protect this code section. + */ + + flags = enter_critical_section(); + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + if (enable) + { + regval |= CAN_IER_RIE; + } + else + { + regval &= ~CAN_IER_RIE; + } + + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: can_txint + * + * Description: + * Call to enable or disable TX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_txint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + uint32_t regval; + irqstate_t flags; + + canvdbg("CAN%d enable: %d\n", priv->port, enable); + + /* Only disabling of the TX interrupt is supported here. The TX interrupt + * is automatically enabled just before a message is sent in order to avoid + * lost TX interrupts. + */ + + if (!enable) + { + /* TX interrupts are also disabled from the interrupt handler, so we have + * to protect this code section. + */ + + flags = enter_critical_section(); + + /* Disable all TX interrupts */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval &= ~(CAN_IER_TIE1 | CAN_IER_TIE2 | CAN_IER_TIE3); + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + leave_critical_section(flags); + } + +} + +/**************************************************************************** + * Name: can_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +/**************************************************************************** + * Name: can_remoterequest + * + * Description: + * Send a remote request + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +/**************************************************************************** + * Name: can_send + * + * Description: + * Send one can message. + * + * One CAN-message consists of a maximum of 10 bytes. A message is + * composed of at least the first 2 bytes (when there are no data bytes). + * + * Byte 0: Bits 0-7: Bits 3-10 of the 11-bit CAN identifier + * Byte 1: Bits 5-7: Bits 0-2 of the 11-bit CAN identifier + * Bit 4: Remote Tranmission Request (RTR) + * Bits 0-3: Data Length Code (DLC) + * Bytes 2-10: CAN data + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + uint32_t tid = (uint32_t)msg->cm_hdr.ch_id; + uint32_t tfi = (uint32_t)msg->cm_hdr.ch_dlc << 16; + uint32_t regval; + irqstate_t flags; + int ret = OK; + + canvdbg("CAN%d ID: %d DLC: %d\n", + priv->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc); + + if (msg->cm_hdr.ch_rtr) + { + tfi |= CAN_TFI_RTR; + } + + /* Set the FF bit in the TFI register if this message should be sent with + * the extended frame format (and 29-bit extened ID). + */ + +#ifdef CONFIG_CAN_EXTID + if (msg->cm_hdr.ch_extid) + { + /* The provided ID should be 29 bits */ + + DEBUGASSERT((tid & ~CAN_TID_ID29_MASK) == 0); + tfi |= CAN_TFI_FF; + } + else +#endif + { + /* The provided ID should be 11 bits */ + + DEBUGASSERT((tid & ~CAN_TID_ID11_MASK) == 0); + } + + flags = enter_critical_section(); + + /* Pick a transmit buffer */ + + regval = can_getreg(priv, LPC17_CAN_SR_OFFSET); + if ((regval & CAN_SR_TBS1) != 0) + { + /* Make sure that buffer 1 TX interrupts are enabled BEFORE sending the + * message. The TX interrupt is generated when the TBSn bit in CANxSR + * goes from 0 to 1 when the TIEn bit in CANxIER is 1. If we don't + * enable it now, we may miss the TIE1 interrupt. + * + * NOTE: The IER is also modified from the interrupt handler, but the + * following is safe because interrupts are disabled here. + */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval |= CAN_IER_TIE1; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Set up the transfer */ + + can_putreg(priv, LPC17_CAN_TFI1_OFFSET, tfi); + can_putreg(priv, LPC17_CAN_TID1_OFFSET, tid); + can_putreg(priv, LPC17_CAN_TDA1_OFFSET, *(uint32_t *)&msg->cm_data[0]); + can_putreg(priv, LPC17_CAN_TDB1_OFFSET, *(uint32_t *)&msg->cm_data[4]); + + /* Send the message */ + +#ifdef CONFIG_CAN_LOOPBACK + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB1 | CAN_CMR_SRR); +#else + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB1 | CAN_CMR_TR); +#endif + } + else if ((regval & CAN_SR_TBS2) != 0) + { + /* Make sure that buffer 2 TX interrupts are enabled BEFORE sending the + * message. The TX interrupt is generated when the TBSn bit in CANxSR + * goes from 0 to 1 when the TIEn bit in CANxIER is 1. If we don't + * enable it now, we may miss the TIE2 interrupt. + * + * NOTE: The IER is also modified from the interrupt handler, but the + * following is safe because interrupts are disabled here. + */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval |= CAN_IER_TIE2; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Set up the transfer */ + + can_putreg(priv, LPC17_CAN_TFI2_OFFSET, tfi); + can_putreg(priv, LPC17_CAN_TID2_OFFSET, tid); + can_putreg(priv, LPC17_CAN_TDA2_OFFSET, *(uint32_t *)&msg->cm_data[0]); + can_putreg(priv, LPC17_CAN_TDB2_OFFSET, *(uint32_t *)&msg->cm_data[4]); + + /* Send the message */ + +#ifdef CONFIG_CAN_LOOPBACK + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB2 | CAN_CMR_SRR); +#else + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB2 | CAN_CMR_TR); +#endif + } + else if ((regval & CAN_SR_TBS3) != 0) + { + /* Make sure that buffer 3 TX interrupts are enabled BEFORE sending the + * message. The TX interrupt is generated when the TBSn bit in CANxSR + * goes from 0 to 1 when the TIEn bit in CANxIER is 1. If we don't + * enable it now, we may miss the TIE3 interrupt. + * + * NOTE: The IER is also modified from the interrupt handler, but the + * following is safe because interrupts are disabled here. + */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval |= CAN_IER_TIE3; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Set up the transfer */ + + can_putreg(priv, LPC17_CAN_TFI3_OFFSET, tfi); + can_putreg(priv, LPC17_CAN_TID3_OFFSET, tid); + can_putreg(priv, LPC17_CAN_TDA3_OFFSET, *(uint32_t *)&msg->cm_data[0]); + can_putreg(priv, LPC17_CAN_TDB3_OFFSET, *(uint32_t *)&msg->cm_data[4]); + + /* Send the message */ + +#ifdef CONFIG_CAN_LOOPBACK + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB3 | CAN_CMR_SRR); +#else + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_STB3 | CAN_CMR_TR); +#endif + } + else + { + candbg("No available transmission buffer, SR: %08x\n", regval); + ret = -EBUSY; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: can_txready + * + * Description: + * Return true if the CAN hardware can accept another TX message. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if the CAN hardware is ready to accept another TX message. + * + ****************************************************************************/ + +static bool can_txready(FAR struct can_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + uint32_t regval = can_getreg(priv, LPC17_CAN_SR_OFFSET); + return ((regval & (CAN_SR_TBS1 | CAN_SR_TBS2 | CAN_SR_TBS3)) != 0); +} + +/**************************************************************************** + * Name: can_txempty + * + * Description: + * Return true if all message have been sent. If for example, the CAN + * hardware implements FIFOs, then this would mean the transmit FIFO is + * empty. This method is called when the driver needs to make sure that + * all characters are "drained" from the TX hardware before calling + * co_shutdown(). + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if there are no pending TX transfers in the CAN hardware. + * + ****************************************************************************/ + +static bool can_txempty(FAR struct can_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + uint32_t regval = can_getreg(priv, LPC17_CAN_GSR_OFFSET); + return ((regval & CAN_GSR_TBS) != 0); +} + +/**************************************************************************** + * Name: can_interrupt + * + * Description: + * CAN1/2 RX/TX interrupt handler + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static void can_interrupt(FAR struct can_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv; + struct can_hdr_s hdr; + uint32_t data[2]; + uint32_t rfs; + uint32_t rid; + uint32_t regval; + + /* Read the interrupt and capture register (also clearing most status bits) */ + + regval = can_getreg(priv, LPC17_CAN_ICR_OFFSET); + canllvdbg("CAN%d ICR: %08x\n", priv->port, regval); + + /* Check for a receive interrupt */ + + if ((regval & CAN_ICR_RI) != 0) + { + rfs = can_getreg(priv, LPC17_CAN_RFS_OFFSET); + rid = can_getreg(priv, LPC17_CAN_RID_OFFSET); + data[0] = can_getreg(priv, LPC17_CAN_RDA_OFFSET); + data[1] = can_getreg(priv, LPC17_CAN_RDB_OFFSET); + + /* Release the receive buffer */ + + can_putreg(priv, LPC17_CAN_CMR_OFFSET, CAN_CMR_RRB); + + /* Construct the CAN header */ + + hdr.ch_id = rid; + hdr.ch_rtr = ((rfs & CAN_RFS_RTR) != 0); + hdr.ch_dlc = (rfs & CAN_RFS_DLC_MASK) >> CAN_RFS_DLC_SHIFT; +#ifdef CONFIG_CAN_ERRORS + hdr.ch_error = 0; /* Error reporting not supported */ +#endif +#ifdef CONFIG_CAN_EXTID + hdr.ch_extid = ((rfs & CAN_RFS_FF) != 0); +#else + hdr.ch_unused = 0; + + if ((rfs & CAN_RFS_FF) != 0) + { + canlldbg("ERROR: Received message with extended identifier. Dropped\n"); + } + else +#endif + { + /* Process the received CAN packet */ + + can_receive(dev, &hdr, (uint8_t *)data); + } + } + + /* Check for TX buffer 1 complete */ + + if ((regval & CAN_ICR_TI1) != 0) + { + /* Disable all further TX buffer 1 interrupts */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval &= ~CAN_IER_TIE1; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Indicate that the TX is done and a new TX buffer is available */ + + can_txdone(dev); + } + + /* Check for TX buffer 2 complete */ + + if ((regval & CAN_ICR_TI2) != 0) + { + /* Disable all further TX buffer 2 interrupts */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval &= ~CAN_IER_TIE2; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Indicate that the TX is done and a new TX buffer is available */ + + can_txdone(dev); + } + + /* Check for TX buffer 3 complete */ + + if ((regval & CAN_ICR_TI3) != 0) + { + /* Disable all further TX buffer 3 interrupts */ + + regval = can_getreg(priv, LPC17_CAN_IER_OFFSET); + regval &= ~CAN_IER_TIE3; + can_putreg(priv, LPC17_CAN_IER_OFFSET, regval); + + /* Indicate that the TX is done and a new TX buffer is available */ + + can_txdone(dev); + } +} + +/**************************************************************************** + * Name: can12_interrupt + * + * Description: + * CAN interrupt handler. There is a single interrupt for both CAN1 and + * CAN2. + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can12_interrupt(int irq, void *context) +{ + /* Handle CAN1/2 interrupts */ + + canllvdbg("irq: %d\n", irq); + +#ifdef CONFIG_LPC17_CAN1 + can_interrupt(&g_can1dev); +#endif +#ifdef CONFIG_LPC17_CAN2 + can_interrupt(&g_can2dev); +#endif + + return OK; +} + +/**************************************************************************** + * Name: can_bittiming + * + * Description: + * Set the CAN bit timing register (BTR) based on the configured BAUD. + * + * The bit timing logic monitors the serial bus-line and performs sampling + * and adjustment of the sample point by synchronizing on the start-bit edge + * and resynchronizing on the following edges. + * + * Its operation may be explained simply by splitting nominal bit time into + * three segments as follows: + * + * 1. Synchronization segment (SYNC_SEG): a bit change is expected to occur + * within this time segment. It has a fixed length of one time quantum + * (1 x tCAN). + * 2. Bit segment 1 (BS1): defines the location of the sample point. It + * includes the PROP_SEG and PHASE_SEG1 of the CAN standard. Its duration + * is programmable between 1 and 16 time quanta but may be automatically + * lengthened to compensate for positive phase drifts due to differences + * in the frequency of the various nodes of the network. + * 3. Bit segment 2 (BS2): defines the location of the transmit point. It + * represents the PHASE_SEG2 of the CAN standard. Its duration is + * programmable between 1 and 8 time quanta but may also be automatically + * shortened to compensate for negative phase drifts. + * + * Pictorially: + * + * |<----------------- NOMINAL BIT TIME ----------------->| + * |<- SYNC_SEG ->|<------ BS1 ------>|<------ BS2 ------>| + * |<---- Tq ---->|<----- Tbs1 ------>|<----- Tbs2 ------>| + * + * Where + * Tbs1 is the duration of the BS1 segment + * Tbs2 is the duration of the BS2 segment + * Tq is the "Time Quantum" + * + * Relationships: + * + * baud = 1 / bit_time + * bit_time = Tq + Tbs1 + Tbs2 + * Tbs1 = Tq * ts1 + * Tbs2 = Tq * ts2 + * Tq = brp * Tcan + * + * Where: + * Tcan is the period of the APB clock (PCLK = CCLK / CONFIG_CAN1_DIVISOR). + * + * Input Parameter: + * priv - A reference to the CAN block status + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_bittiming(struct up_dev_s *priv) +{ + uint32_t btr; + uint32_t nclks; + uint32_t brp; + uint32_t ts1; + uint32_t ts2; + uint32_t sjw; + + canllvdbg("CAN%d PCLK: %d baud: %d\n", priv->port, + CAN_CLOCK_FREQUENCY(priv->divisor), priv->baud); + + /* Try to get CAN_BIT_QUANTA quanta in one bit_time. + * + * bit_time = Tq*(ts1 + ts2 + 1) + * nquanta = bit_time/Tq + * Tq = brp * Tcan + * nquanta = (ts1 + ts2 + 1) + * + * bit_time = brp * Tcan * (ts1 + ts2 + 1) + * nquanta = bit_time / brp / Tcan + * brp = Fcan / baud / nquanta; + * + * First, calculate the number of CAN clocks in one bit time: Fcan / baud + */ + + nclks = CAN_CLOCK_FREQUENCY(priv->divisor) / priv->baud; + if (nclks < CAN_BIT_QUANTA) + { + /* At the smallest brp value (1), there are already too few bit times + * (CAN_CLOCK / baud) to meet our goal. brp must be one and we need + * make some reasonable guesses about ts1 and ts2. + */ + + brp = 1; + + /* In this case, we have to guess a good value for ts1 and ts2 */ + + ts1 = (nclks - 1) >> 1; + ts2 = nclks - ts1 - 1; + if (ts1 == ts2 && ts1 > 1 && ts2 < CAN_BTR_TSEG2_MAX) + { + ts1--; + ts2++; + } + } + + /* Otherwise, nquanta is CAN_BIT_QUANTA, ts1 is CONFIG_CAN_TSEG1, ts2 is + * CONFIG_CAN_TSEG2 and we calculate brp to achieve CAN_BIT_QUANTA quanta + * in the bit time + */ + + else + { + ts1 = CONFIG_CAN_TSEG1; + ts2 = CONFIG_CAN_TSEG2; + brp = (nclks + (CAN_BIT_QUANTA / 2)) / CAN_BIT_QUANTA; + DEBUGASSERT(brp >=1 && brp <= CAN_BTR_BRP_MAX); + } + + sjw = 1; + + canllvdbg("TS1: %d TS2: %d BRP: %d SJW= %d\n", ts1, ts2, brp, sjw); + + /* Configure bit timing */ + + btr = (((brp - 1) << CAN_BTR_BRP_SHIFT) | + ((ts1 - 1) << CAN_BTR_TSEG1_SHIFT) | + ((ts2 - 1) << CAN_BTR_TSEG2_SHIFT) | + ((sjw - 1) << CAN_BTR_SJW_SHIFT)); + +#ifdef CONFIG_CAN_SAM + /* The bus is sampled 3 times (recommended for low to medium speed buses + * to spikes on the bus-line). + */ + + btr |= CAN_BTR_SAM; +#endif + + canllvdbg("Setting CANxBTR= 0x%08x\n", btr); + can_putreg(priv, LPC17_CAN_BTR_OFFSET, btr); /* Set bit timing */ + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc17_caninitialize + * + * Description: + * Initialize the selected can port + * + * Input Parameter: + * Port number (for hardware that has mutiple can interfaces) + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct can_dev_s *lpc17_caninitialize(int port) +{ + FAR struct can_dev_s *candev; + irqstate_t flags; + uint32_t regval; + + canllvdbg("CAN%d\n", port); + + flags = enter_critical_section(); + +#ifdef CONFIG_LPC17_CAN1 + if (port == 1) + { + /* Enable power to the CAN module */ + + regval = can_getcommon(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCCAN1; + can_putcommon(LPC17_SYSCON_PCONP, regval); + + /* Enable clocking to the CAN module (not necessary... already done + * in low level clock configuration logic). + */ + + regval = can_getcommon(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_CAN1_MASK; + regval |= (CAN1_CCLK_DIVISOR << SYSCON_PCLKSEL0_CAN1_SHIFT); + can_putcommon(LPC17_SYSCON_PCLKSEL0, regval); + + /* Configure CAN GPIO pins */ + + lpc17_configgpio(GPIO_CAN1_RD); + lpc17_configgpio(GPIO_CAN1_TD); + + candev = &g_can1dev; + } + else +#endif +#ifdef CONFIG_LPC17_CAN2 + if (port == 2) + { + /* Enable power to the CAN module */ + + regval = can_getcommon(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCCAN2; + can_putcommon(LPC17_SYSCON_PCONP, regval); + + /* Enable clocking to the CAN module (not necessary... already done + * in low level clock configuration logic). + */ + + regval = can_getcommon(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_CAN2_MASK; + regval |= (CAN2_CCLK_DIVISOR << SYSCON_PCLKSEL0_CAN2_SHIFT); + can_putcommon(LPC17_SYSCON_PCLKSEL0, regval); + + /* Configure CAN GPIO pins */ + + lpc17_configgpio(GPIO_CAN2_RD); + lpc17_configgpio(GPIO_CAN2_TD); + + candev = &g_can2dev; + } + else +#endif + { + candbg("Unsupported port: %d\n", port); + leave_critical_section(flags); + return NULL; + } + + /* Then just perform a CAN reset operation */ + + can_reset(candev); + leave_critical_section(flags); + return candev; +} +#endif diff --git a/arch/arm/src/lpc17xx/lpc17_can.h b/arch/arm/src/lpc17xx/lpc17_can.h new file mode 100644 index 0000000000000000000000000000000000000000..e15eaced5a5aa02cb8d9bf787523c9f2480be6d7 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_can.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_can.h + * + * Copyright (C) 2010-2012, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CAN_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc17_can.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_caninitialize + * + * Description: + * Initialize the selected can port + * + * Input Parameter: + * Port number (for hardware that has mutiple can interfaces) + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#if defined(CONFIG_CAN) && (defined(CONFIG_LPC17_CAN1) || defined(CONFIG_LPC17_CAN2)) +struct can_dev_s; +FAR struct can_dev_s *lpc17_caninitialize(int port); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CAN_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_clockconfig.c b/arch/arm/src/lpc17xx/lpc17_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..97ef496f0df5a102c1a3e47a41d23fc58d4ee33f --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_clockconfig.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_clockconfig.c + * arch/arm/src/chip/lpc17_clockconfig.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct clock + * configuration logic for the selected LPC17xx family. The correct file + * cannot be selected by the make system because it needs the intelligence + * that only exists in chip.h that can associate an LPC17xx part number with + * an LPC17xx family. + * + * The LPC176x and LPC178x system control block is *nearly* identical but + * we have found that the LPC178x is more sensitive to the ordering of + * certain operations. So, although the hardware seems very similar, the + * safer thing to do is to separate the LPC176x and LPC178x into separate + * files. + */ + +#include + +#if defined(LPC176x) +# include "chip/lpc176x_clockconfig.c" +#elif defined(LPC178x) +# include "chip/lpc178x_clockconfig.c" +#else +# error "Unrecognized LPC17xx family" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/lpc17xx/lpc17_clockconfig.h b/arch/arm/src/lpc17xx/lpc17_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..ffc9fa88dd5e702152ed45e5d826d2eaa828018b --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_clockconfig.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_clockconfig.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_clockconfig + * + * Description: + * Called to initialize the LPC17XX. This does whatever setup is needed to put the + * MCU in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void lpc17_clockconfig(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CLOCKCONFIG_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_clrpend.c b/arch/arm/src/lpc17xx/lpc17_clrpend.c new file mode 100644 index 0000000000000000000000000000000000000000..7a5552b3975c8b9b19ab1230e3dd3b843dfae61a --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_clrpend.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/src/lpc17/lpc17_clrpend.c + * arch/arm/src/chip/lpc17_clrpend.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nvic.h" +#include "up_arch.h" +#include "lpc17_clrpend.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. Don't know why... but the LPC1766 Ethernet EMAC + * interrupt definitely needs it! + * + * I keep it in a separate file so that it will not increase the footprint + * on LPC17xx platforms that do not need this function. + * + ****************************************************************************/ + +void lpc17_clrpend(int irq) +{ + /* Check for external interrupt */ + + if (irq >= LPC17_IRQ_EXTINT) + { + if (irq < (LPC17_IRQ_EXTINT+32)) + { + putreg32(1 << (irq - LPC17_IRQ_EXTINT), NVIC_IRQ0_31_CLRPEND); + } + else if (irq < LPC17_IRQ_NIRQS) + { + putreg32(1 << (irq - LPC17_IRQ_EXTINT - 32), NVIC_IRQ32_63_CLRPEND); + } + } +} diff --git a/arch/arm/src/lpc17xx/lpc17_clrpend.h b/arch/arm/src/lpc17xx/lpc17_clrpend.h new file mode 100644 index 0000000000000000000000000000000000000000..d7bf5b90dc5767df3d73e025a3ed4d7e84eaa201 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_clrpend.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_clrpend.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_CLRPEND_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_CLRPEND_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. Don't know why... but the LPC1766 Ethernet EMAC + * interrupt definitely needs it! + * + ************************************************************************************/ + +void lpc17_clrpend(int irq); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_CLRPEND_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_dac.c b/arch/arm/src/lpc17xx/lpc17_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..d5100c5e50a443eacd766e4b5508980de71201e3 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_dac.c @@ -0,0 +1,200 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_dac.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010, 2014, 2016 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "chip/lpc17_syscon.h" +#include "chip/lpc17_pinconfig.h" +#include "lpc17_gpio.h" +#include "lpc17_dac.h" + +#ifdef CONFIG_LPC17_DAC + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* DAC methods */ + +static void dac_reset(FAR struct dac_dev_s *dev); +static int dac_setup(FAR struct dac_dev_s *dev); +static void dac_shutdown(FAR struct dac_dev_s *dev); +static void dac_txint(FAR struct dac_dev_s *dev, bool enable); +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct dac_ops_s g_dacops = +{ + .ao_reset = dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, +}; + +static struct dac_dev_s g_dacdev = +{ + .ad_ops = &g_dacops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Reset the DAC device. Called early to initialize the hardware. This + * is called, before ao_setup() and on error conditions. + */ + +static void dac_reset(FAR struct dac_dev_s *dev) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_DAC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_DAC_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + //putreg32(DAC_CTRL_DBLBUFEN, LPC17_DAC_CTRL); ? + + lpc17_configgpio(GPIO_AOUT); + + leave_critical_section(flags); +} + +/* Configure the DAC. This method is called the first time that the DAC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching DAC interrupts. Interrupts + * are all disabled upon return. + */ + +static int dac_setup(FAR struct dac_dev_s *dev) +{ + return OK; +} + +/* Disable the DAC. This method is called when the DAC device is closed. + * This method reverses the operation the setup method. + */ + +static void dac_shutdown(FAR struct dac_dev_s *dev) +{ +} + +/* Call to enable or disable TX interrupts */ + +static void dac_txint(FAR struct dac_dev_s *dev, bool enable) +{ +} + +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) +{ + /* adjust the binary value to the lpc1768's register format (plus high + * speed profile in bit 16) + */ + + putreg32(((((msg->am_data) << 6) | 0x10000) & 0xffff), LPC17_DAC_CR); + dac_txdone(&g_dacdev); + return 0; +} + +/* All ioctl calls will be routed through this method */ + +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct dac_dev_s *lpc17_dacinitialize(void) +{ + return &g_dacdev; +} + +#endif /* CONFIG_LPC17_DAC */ + diff --git a/arch/arm/src/lpc17xx/lpc17_dac.h b/arch/arm/src/lpc17xx/lpc17_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..ac8477507ce8cbc1f55a9bf566bfabdeeac63f07 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_dac.h @@ -0,0 +1,88 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_dac.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_DAC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_dac.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc17_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_DAC +FAR struct dac_dev_s *lpc17_dacinitialize(void); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_DAC_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_emacram.h b/arch/arm/src/lpc17xx/lpc17_emacram.h new file mode 100644 index 0000000000000000000000000000000000000000..9d373e9d8f63dfb2032e20346c4beda56c889b6b --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_emacram.h @@ -0,0 +1,201 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_emacram.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_EMACRAM_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_EMACRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc17_ethernet.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Default, no-EMAC Case ************************************************************/ +/* Assume that all of AHB SRAM will be available for heap. If this is not true, then + * LPC17_BANK0_HEAPSIZE will be undefined and redefined below. + */ + +#undef LPC17_BANK0_HEAPBASE +#undef LPC17_BANK0_HEAPSIZE +#ifdef LPC17_HAVE_BANK0 +# define LPC17_BANK0_HEAPBASE LPC17_SRAM_BANK0 +# define LPC17_BANK0_HEAPSIZE LPC17_BANK0_SIZE +#endif + +/* Is networking enabled? Is the LPC17xx Ethernet device enabled? Does this chip have + * and Ethernet controller? Yes... then we will replace the above default definitions. + */ + +#if defined(CONFIG_NET) && defined(CONFIG_LPC17_ETHERNET) && LPC17_NETHCONTROLLERS > 0 + +/* EMAC RAM Configuration ***********************************************************/ +/* Is AHB SRAM available? */ + +#ifndef LPC17_HAVE_BANK0 +# error "AHB SRAM Bank0 is not available for EMAC RAM" +#endif + +/* Number of Tx descriptors */ + +#ifndef CONFIG_NET_NTXDESC +# define CONFIG_NET_NTXDESC 13 +#endif + +/* Number of Rx descriptors */ + +#ifndef CONFIG_NET_NRXDESC +# define CONFIG_NET_NRXDESC 13 +#endif + +/* Size of the region at the beginning of AHB SRAM 0 set set aside for the EMAC. + * This size must fit within AHB SRAM Bank 0 and also be a multiple of 32-bit + * words. + */ + +#ifndef CONFIG_NET_EMACRAM_SIZE +# define CONFIG_NET_EMACRAM_SIZE LPC17_BANK0_SIZE +#endif + +#if CONFIG_NET_EMACRAM_SIZE > LPC17_BANK0_SIZE +# error "EMAC RAM size cannot exceed the size of AHB SRAM Bank 0" +#endif + +#if (CONFIG_NET_EMACRAM_SIZE & 3) != 0 +# error "EMAC RAM size must be in multiples of 32-bit words" +#endif + +/* Determine is there is any meaningful space left at the end of AHB Bank 0 that + * could be added to the heap. + */ + +#undef LPC17_BANK0_HEAPBASE +#undef LPC17_BANK0_HEAPSIZE +#if CONFIG_NET_EMACRAM_SIZE < (LPC17_BANK0_SIZE-128) +# define LPC17_BANK0_HEAPBASE (LPC17_SRAM_BANK0 + CONFIG_NET_EMACRAM_SIZE) +# define LPC17_BANK0_HEAPSIZE (LPC17_BANK0_SIZE - CONFIG_NET_EMACRAM_SIZE) +#endif + +/* Memory at the beginning of AHB SRAM, Bank 0 is set aside for EMAC Tx and Rx + * descriptors. The position is not controllable, only the size of the region + * is controllable. + */ + +#define LPC17_EMACRAM_BASE LPC17_SRAM_BANK0 +#define LPC17_EMACRAM_SIZE CONFIG_NET_EMACRAM_SIZE + +/* Descriptor Memory Layout *********************************************************/ +/* EMAC DMA RAM and descriptor definitions. The configured number of descriptors + * will determine the organization and the size of the descriptor and status tables. + * There is a complex interaction between the maximum packet size (CONFIG_NET_ETH_MTU) + * and the number of Rx and Tx descriptors that can be supported (CONFIG_NET_NRXDESC + * and CONFIG_NET_NTXDESC): Small buffers -> more packets. This is something that + * needs to be tuned for you system. + * + * For a 16Kb SRAM region, here is the relationship: + * + * 16384 <= ntx * (pktsize + 8 + 4) + nrx * (pktsize + 8 + 8) + * + * If ntx == nrx and pktsize == 590+2, then you could have ntx = nrx = 13. In this + * case, you would need only 15,756 bytes of EMAC RAM (but be careful with alignment! + * 15,756 is not well aligned.). + */ + +#define LPC17_TXDESCTAB_SIZE (CONFIG_NET_NTXDESC*LPC17_TXDESC_SIZE) +#define LPC17_TXSTATTAB_SIZE (CONFIG_NET_NTXDESC*LPC17_TXSTAT_SIZE) +#define LPC17_TXTAB_SIZE (LPC17_TXDESCTAB_SIZE+LPC17_TXSTATTAB_SIZE) + +#define LPC17_RXDESCTAB_SIZE (CONFIG_NET_NRXDESC*LPC17_RXDESC_SIZE) +#define LPC17_RXSTATTAB_SIZE (CONFIG_NET_NRXDESC*LPC17_RXSTAT_SIZE) +#define LPC17_RXTAB_SIZE (LPC17_RXDESCTAB_SIZE+LPC17_RXSTATTAB_SIZE) + +#define LPC17_DESCTAB_SIZE (LPC17_TXTAB_SIZE+LPC17_RXTAB_SIZE) + +/* Descriptor table memory organization. Descriptor tables are packed at + * the end of AHB SRAM, Bank 0. The beginning of bank 0 is reserved for + * packet memory. + */ + +#define LPC17_DESC_BASE (LPC17_EMACRAM_BASE+LPC17_EMACRAM_SIZE-LPC17_DESCTAB_SIZE) +#define LPC17_TXDESC_BASE LPC17_DESC_BASE +#define LPC17_TXSTAT_BASE (LPC17_TXDESC_BASE+LPC17_TXDESCTAB_SIZE) +#define LPC17_RXDESC_BASE (LPC17_TXSTAT_BASE+LPC17_TXSTATTAB_SIZE) +#define LPC17_RXSTAT_BASE (LPC17_RXDESC_BASE + LPC17_RXDESCTAB_SIZE) + +/* Now carve up the beginning of SRAM for packet memory. The size of a + * packet buffer is related to the size of the MTU. We'll round sizes up + * to multiples of 256 bytes. + */ + +#define LPC17_PKTMEM_BASE LPC17_EMACRAM_BASE +#define LPC17_PKTMEM_SIZE (LPC17_EMACRAM_SIZE-LPC17_DESCTAB_SIZE) +#define LPC17_PKTMEM_END (LPC17_EMACRAM_BASE+LPC17_PKTMEM_SIZE) + +#define LPC17_MAXPACKET_SIZE ((CONFIG_NET_ETH_MTU + CONFIG_NET_GUARDSIZE + 3) & ~3) +#define LPC17_NTXPKTS CONFIG_NET_NTXDESC +#define LPC17_NRXPKTS CONFIG_NET_NRXDESC + +#define LPC17_TXBUFFER_SIZE (LPC17_NTXPKTS * LPC17_MAXPACKET_SIZE) +#define LPC17_RXBUFFER_SIZE (LPC17_NRXPKTS * LPC17_MAXPACKET_SIZE) +#define LPC17_BUFFER_SIZE (LPC17_TXBUFFER_SIZE + LPC17_RXBUFFER_SIZE) + +#define LPC17_BUFFER_BASE LPC17_PKTMEM_BASE +#define LPC17_TXBUFFER_BASE LPC17_BUFFER_BASE +#define LPC17_RXBUFFER_BASE (LPC17_TXBUFFER_BASE + LPC17_TXBUFFER_SIZE) +#define LPC17_BUFFER_END (LPC17_BUFFER_BASE + LPC17_BUFFER_SIZE) + +#if LPC17_BUFFER_END > LPC17_PKTMEM_END +# error "Packet memory overlaps descriptor tables" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* CONFIG_NET && CONFIG_LPC17_ETHERNET && LPC17_NETHCONTROLLERS > 0*/ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_EMACRAM_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_emc.c b/arch/arm/src/lpc17xx/lpc17_emc.c new file mode 100644 index 0000000000000000000000000000000000000000..c9773fad6d0ded4246bc4d3210c530d73758121c --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_emc.c @@ -0,0 +1,196 @@ +/**************************************************************************** + * arch/arm/src/lpc17/lpc17_emc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" + +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_emc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const lpc17_pinset_t g_emcctrl[] = +{ + GPIO_EMC_OE, GPIO_EMC_WE, + GPIO_EMC_BLS0, GPIO_EMC_BLS1, GPIO_EMC_BLS2, GPIO_EMC_BLS3, + GPIO_EMC_CS0, GPIO_EMC_CS1, GPIO_EMC_CS2, GPIO_EMC_CS3, + GPIO_EMC_CAS, GPIO_EMC_RAS, + GPIO_EMC_CLK0, GPIO_EMC_CLK1, + GPIO_EMC_DYCS0, GPIO_EMC_DYCS1, GPIO_EMC_DYCS2, GPIO_EMC_DYCS3, + GPIO_EMC_CKE0, GPIO_EMC_CKE1, GPIO_EMC_CKE2, GPIO_EMC_CKE3, + GPIO_EMC_DQM0, GPIO_EMC_DQM1, GPIO_EMC_DQM2, GPIO_EMC_DQM3, +}; +#define EMC_NCTRL (sizeof(g_emcctrl) / sizeof(lpc17_pinset_t)) + +static const lpc17_pinset_t g_emcdata[] = +{ + GPIO_EMC_D0, GPIO_EMC_D1, GPIO_EMC_D2, GPIO_EMC_D3, + GPIO_EMC_D4, GPIO_EMC_D5, GPIO_EMC_D6, GPIO_EMC_D7, + GPIO_EMC_D8, GPIO_EMC_D9, GPIO_EMC_D10, GPIO_EMC_D11, + GPIO_EMC_D12, GPIO_EMC_D13, GPIO_EMC_D14, GPIO_EMC_D15, + GPIO_EMC_D16, GPIO_EMC_D17, GPIO_EMC_D18, GPIO_EMC_D19, + GPIO_EMC_D20, GPIO_EMC_D21, GPIO_EMC_D22, GPIO_EMC_D23, + GPIO_EMC_D24, GPIO_EMC_D25, GPIO_EMC_D26, GPIO_EMC_D27, + GPIO_EMC_D28, GPIO_EMC_D29, GPIO_EMC_D30, GPIO_EMC_D31, +}; + +/* You can limit the number of data lines configured by defining + * BOARD_NDATA in your board.h header file. + */ + +#ifdef BOARD_NDATA +# define EMC_NDATA BOARD_NDATA +#else +# define EMC_NDATA (sizeof(g_emcdata) / sizeof(lpc17_pinset_t)) +#endif + +static const lpc17_pinset_t g_emcaddr[] = +{ + GPIO_EMC_A0, GPIO_EMC_A1, GPIO_EMC_A2, GPIO_EMC_A3, + GPIO_EMC_A4, GPIO_EMC_A5, GPIO_EMC_A6, GPIO_EMC_A7, + GPIO_EMC_A8, GPIO_EMC_A9, GPIO_EMC_A10, GPIO_EMC_A11, + GPIO_EMC_A12, GPIO_EMC_A13, GPIO_EMC_A14, GPIO_EMC_A15, + GPIO_EMC_A16, GPIO_EMC_A17, GPIO_EMC_A18, GPIO_EMC_A19, + GPIO_EMC_A20, GPIO_EMC_A21, GPIO_EMC_A22, GPIO_EMC_A23, + GPIO_EMC_A24, GPIO_EMC_A25 +}; + +/* You can limit the number of address lines configured by defining + * BOARD_NADDR in your board.h header file. + */ + +#ifdef BOARD_NADDR +# define EMC_NADDR BOARD_NADDR +#else +# define EMC_NADDR (sizeof(g_emcaddr) / sizeof(lpc17_pinset_t)) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_emcinitialize + * + * Description: + * Initialize EMC clocking and pin configuration. This function should be + * called once when the system first boots in order to make the EMC + * operational. + * + ****************************************************************************/ + +void lpc17_emcinitialize(void) +{ + uint32_t regval; + int i; + + /* Enable clocking for the EMC */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCEMC; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Set EMC delay values: + * + * CMDDLY: Programmable delay value for EMC outputs in command delayed + * mode. The delay amount is roughly CMDDLY * 250 picoseconds. + * FBCLKDLY: Programmable delay value for the feedback clock that controls + * input data sampling. The delay amount is roughly (FBCLKDLY+1) * 250 + * picoseconds. + * CLKOUT0DLY: Programmable delay value for the CLKOUT0 output. This would + * typically be used in clock delayed mode. The delay amount is roughly + * (CLKOUT0DLY+1) * 250 picoseconds. + * CLKOUT1DLY: Programmable delay value for the CLKOUT1 output. This would + * typically be used in clock delayed mode. The delay amount is roughly + * (CLKOUT1DLY+1) * 250 picoseconds. + */ + + regval = SYSCON_EMCDLYCTL_CMDDLY(BOARD_CMDDLY) | + SYSCON_EMCDLYCTL_FBCLKDLY(BOARD_FBCLKDLY) | + SYSCON_EMCDLYCTL_CLKOUT0DLY(BOARD_CLKOUT0DLY) | + SYSCON_EMCDLYCTL_CLKOUT1DLY(BOARD_CLKOUT1DLY); + putreg32(regval, LPC17_SYSCON_EMCDLYCTL); + + /* Enable the EMC */ + + putreg32(EMC_CONTROL_E, LPC17_EMC_CONTROL); + putreg32(0, LPC17_EMC_CONFIG); + + /* Configure EMC pins */ + /* Control signals */ + + for (i = 0; i < EMC_NCTRL; i++) + { + lpc17_configgpio(g_emcctrl[i]); + } + + /* Data lines */ + + for (i = 0; i < EMC_NDATA; i++) + { + lpc17_configgpio(g_emcdata[i]); + } + + /* Address lines */ + + for (i = 0; i < EMC_NADDR; i++) + { + lpc17_configgpio(g_emcaddr[i]); + } +} diff --git a/arch/arm/src/lpc17xx/lpc17_emc.h b/arch/arm/src/lpc17xx/lpc17_emc.h new file mode 100644 index 0000000000000000000000000000000000000000..b5a90100385b7f69265e0492156d0263ec9c6c4d --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_emc.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_emc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_EMC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_EMC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc17_emc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_emcinitialize + * + * Description: + * Initialize EMC clocking and pin configuration. This function should be + * called once when the system first boots in order to make the EMC + * operational. + * + ****************************************************************************/ + +void lpc17_emcinitialize(void); + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_EMC_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_ethernet.c b/arch/arm/src/lpc17xx/lpc17_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..4bc992d2ce9cf440c3a38deeb694361a504ba149 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_ethernet.c @@ -0,0 +1,3286 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_ethernet.c + * + * Copyright (C) 2010-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_LPC17_ETHERNET) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_ethernet.h" +#include "lpc17_emacram.h" +#include "lpc17_clrpend.h" + +#include + +/* Does this chip have and Ethernet controller? */ + +#if LPC17_NETHCONTROLLERS > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +/* CONFIG_LPC17_NINTERFACES determines the number of physical interfaces + * that will be supported -- unless it is more than actually supported by the + * hardware! + */ + +#if !defined(CONFIG_LPC17_NINTERFACES) || CONFIG_LPC17_NINTERFACES > LPC17_NETHCONTROLLERS +# undef CONFIG_LPC17_NINTERFACES +# define CONFIG_LPC17_NINTERFACES LPC17_NETHCONTROLLERS +#endif + +/* The logic here has a few hooks for support for multiple interfaces, but + * that capability is not yet in place (and I won't worry about it until I get + * the first multi-interface LPC17xx). + */ + +#if CONFIG_LPC17_NINTERFACES > 1 +# warning "Only a single ethernet controller is supported" +# undef CONFIG_LPC17_NINTERFACES +# define CONFIG_LPC17_NINTERFACES 1 +#endif + +/* If IGMP is enabled, then accept multi-cast frames. */ + +#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_LPC17_MULTICAST) +# define CONFIG_LPC17_MULTICAST 1 +#endif + +/* If the user did not specify a priority for Ethernet interrupts, set the + * interrupt priority to the default. + */ + +#ifndef CONFIG_NET_PRIORITY +# define CONFIG_NET_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Debug Configuration *****************************************************/ +/* Register debug -- can only happen of CONFIG_DEBUG is selected */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_REGDEBUG +#endif + +/* CONFIG_NET_DUMPPACKET will dump the contents of each packet to the + * console. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_DUMPPACKET +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define lpc17_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define lpc17_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define LPC17_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define LPC17_TXTIMEOUT (60*CLK_TCK) + +/* Interrupts ***************************************************************/ + +#define ETH_RXINTS (ETH_INT_RXOVR | ETH_INT_RXERR | \ + ETH_INT_RXFIN | ETH_INT_RXDONE) +#define ETH_TXINTS (ETH_INT_TXUNR | ETH_INT_TXERR | \ + ETH_INT_TXFIN | ETH_INT_TXDONE) + +/* Misc. Helpers ***********************************************************/ + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->lp_dev.d_buf) + +/* This is the number of ethernet GPIO pins that must be configured */ + +#define GPIO_NENET_PINS 10 + +/* PHYs *********************************************************************/ +/* Select PHY-specific values. Add more PHYs as needed. */ + +#if defined(CONFIG_ETH0_PHY_KS8721) +# define LPC17_PHYNAME "KS8721" +# define LPC17_PHYID1 MII_PHYID1_KS8721 +# define LPC17_PHYID2 MII_PHYID2_KS8721 +# define LPC17_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_KSZ8041) +# define LPC17_PHYNAME "KSZ8041" +# define LPC17_PHYID1 MII_PHYID1_KSZ8041 +# define LPC17_PHYID2 MII_PHYID2_KSZ8041 +# define LPC17_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_DP83848C) +# define LPC17_PHYNAME "DP83848C" +# define LPC17_PHYID1 MII_PHYID1_DP83848C +# define LPC17_PHYID2 MII_PHYID2_DP83848C +# define LPC17_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_LAN8720) +# define LPC17_PHYNAME "LAN8720" +# define LPC17_PHYID1 MII_PHYID1_LAN8720 +# define LPC17_PHYID2 MII_PHYID2_LAN8720 +# define LPC17_HAVE_PHY 1 +#else +# warning "No PHY specified!" +# undef LPC17_HAVE_PHY +#endif + +#define MII_BIG_TIMEOUT 666666 + +/* These definitions are used to remember the speed/duplex settings */ + +#define LPC17_SPEED_MASK 0x01 +#define LPC17_SPEED_100 0x01 +#define LPC17_SPEED_10 0x00 + +#define LPC17_DUPLEX_MASK 0x02 +#define LPC17_DUPLEX_FULL 0x02 +#define LPC17_DUPLEX_HALF 0x00 + +#define LPC17_10BASET_HD (LPC17_SPEED_10 | LPC17_DUPLEX_HALF) +#define LPC17_10BASET_FD (LPC17_SPEED_10 | LPC17_DUPLEX_FULL) +#define LPC17_100BASET_HD (LPC17_SPEED_100 | LPC17_DUPLEX_HALF) +#define LPC17_100BASET_FD (LPC17_SPEED_100 | LPC17_DUPLEX_FULL) + +#ifdef CONFIG_PHY_SPEED100 +# ifdef CONFIG_PHY_FDUPLEX +# define LPC17_MODE_DEFLT LPC17_100BASET_FD +# else +# define LPC17_MODE_DEFLT LPC17_100BASET_HD +# endif +#else +# ifdef CONFIG_PHY_FDUPLEX +# define LPC17_MODE_DEFLT LPC17_10BASET_FD +# else +# define LPC17_MODE_DEFLT LPC17_10BASET_HD +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The lpc17_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct lpc17_driver_s +{ + /* The following fields would only be necessary on chips that support + * multiple Ethernet controllers. + */ + +#if CONFIG_LPC17_NINTERFACES > 1 + uint32_t lp_base; /* Ethernet controller base address */ + int lp_irq; /* Ethernet controller IRQ */ +#endif + + bool lp_ifup; /* true:ifup false:ifdown */ + bool lp_mode; /* speed/duplex */ + bool lp_txpending; /* There is a pending Tx in lp_dev */ +#ifdef LPC17_HAVE_PHY + uint8_t lp_phyaddr; /* PHY device address */ +#endif + uint32_t lp_inten; /* Shadow copy of INTEN register */ + WDOG_ID lp_txpoll; /* TX poll timer */ + WDOG_ID lp_txtimeout; /* TX timeout timer */ + +#ifdef CONFIG_NET_NOINTS + struct work_s lp_txwork; /* TX work continuation */ + struct work_s lp_rxwork; /* RX work continuation */ + struct work_s lp_pollwork; /* Poll work continuation */ + uint32_t status; +#endif /* CONFIG_NET_NOINTS */ + + /* This holds the information visible to the NuttX networking layer */ + + struct net_driver_s lp_dev; /* Interface understood by the network layer */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Array of ethernet driver status structures */ + +static struct lpc17_driver_s g_ethdrvr[CONFIG_LPC17_NINTERFACES]; + +/* ENET pins are on P1[0,1,4,6,8,9,10,14,15] + MDC on P1[16] or P2[8] and + * MDIO on P1[17] or P2[9]. The board.h file will define GPIO_ENET_MDC and + * PGIO_ENET_MDIO to selec which pin setting to use. + * + * On older Rev '-' devices, P1[6] ENET-TX_CLK would also have be to configured. + */ + +static const uint16_t g_enetpins[GPIO_NENET_PINS] = +{ + GPIO_ENET_TXD0, GPIO_ENET_TXD1, GPIO_ENET_TXEN, GPIO_ENET_CRS, GPIO_ENET_RXD0, + GPIO_ENET_RXD1, GPIO_ENET_RXER, GPIO_ENET_REFCLK, GPIO_ENET_MDC, GPIO_ENET_MDIO +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations */ + +#ifdef CONFIG_NET_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t lpc17_getreg(uint32_t addr); +static void lpc17_putreg(uint32_t val, uint32_t addr); +#else +# define lpc17_getreg(addr) getreg32(addr) +# define lpc17_putreg(val,addr) putreg32(val,addr) +#endif + +/* Common TX logic */ + +static int lpc17_txdesc(struct lpc17_driver_s *priv); +static int lpc17_transmit(struct lpc17_driver_s *priv); +static int lpc17_txpoll(struct net_driver_s *dev); + +/* Interrupt handling */ + +static void lpc17_response(struct lpc17_driver_s *priv); +static void lpc17_rxdone_process(struct lpc17_driver_s *priv); +static void lpc17_txdone_process(struct lpc17_driver_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc17_txdone_work(FAR void *arg); +static void lpc17_rxdone_work(FAR void *arg); +#endif /* CONFIG_NET_NOINTS */ +static int lpc17_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void lpc17_txtimeout_process(FAR struct lpc17_driver_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc17_txtimeout_work(FAR void *arg); +#endif /* CONFIG_NET_NOINTS */ +static void lpc17_txtimeout_expiry(int argc, uint32_t arg, ...); + +static void lpc17_poll_process(FAR struct lpc17_driver_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc17_poll_work(FAR void *arg); +#endif /* CONFIG_NET_NOINTS */ +static void lpc17_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +#ifdef CONFIG_NET_ICMPv6 +static void lpc17_ipv6multicast(FAR struct lpc17_driver_s *priv); +#endif +static int lpc17_ifup(struct net_driver_s *dev); +static int lpc17_ifdown(struct net_driver_s *dev); + +static void lpc17_txavail_process(FAR struct lpc17_driver_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc17_txavail_work(FAR void *arg); +#endif +static int lpc17_txavail(struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t lpc17_calcethcrc(const uint8_t *data, size_t length); +static int lpc17_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int lpc17_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +/* Initialization functions */ + +#if defined(CONFIG_NET_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +static void lpc17_showpins(void); +#else +# define lpc17_showpins() +#endif + +/* PHY initialization functions */ + +#ifdef LPC17_HAVE_PHY +# ifdef CONFIG_NET_REGDEBUG +static void lpc17_showmii(uint8_t phyaddr, const char *msg); +# else +# define lpc17_showmii(phyaddr,msg) +# endif + +static void lpc17_phywrite(uint8_t phyaddr, uint8_t regaddr, + uint16_t phydata); +static uint16_t lpc17_phyread(uint8_t phyaddr, uint8_t regaddr); +static inline int lpc17_phyreset(uint8_t phyaddr); +# ifdef CONFIG_PHY_AUTONEG +static inline int lpc17_phyautoneg(uint8_t phyaddr); +# endif +static int lpc17_phymode(uint8_t phyaddr, uint8_t mode); +static inline int lpc17_phyinit(struct lpc17_driver_s *priv); +#else +# define lpc17_phyinit(priv) +#endif + +/* EMAC Initialization functions */ + +static inline void lpc17_txdescinit(struct lpc17_driver_s *priv); +static inline void lpc17_rxdescinit(struct lpc17_driver_s *priv); +static void lpc17_macmode(uint8_t mode); +static void lpc17_ethreset(struct lpc17_driver_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_printreg + * + * Description: + * Print the contents of an LPC17xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + dbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: lpc17_checkreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + lpc17_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + dbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + lpc17_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: lpc17_getreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static uint32_t lpc17_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc17_putreg + * + * Description: + * Set the contents of an LPC17xx register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void lpc17_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Function: lpc17_txdesc + * + * Description: + * Check if a free TX descriptor is available. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int lpc17_txdesc(struct lpc17_driver_s *priv) +{ + unsigned int prodidx; + unsigned int considx; + + /* Get the next producer index */ + + prodidx = lpc17_getreg(LPC17_ETH_TXPRODIDX) & ETH_TXPRODIDX_MASK; + if (++prodidx >= CONFIG_NET_NTXDESC) + { + /* Wrap back to index zero */ + + prodidx = 0; + } + + /* If the next producer index would overrun the consumer index, then there + * are no available Tx descriptors. + */ + + considx = lpc17_getreg(LPC17_ETH_TXCONSIDX) & ETH_TXCONSIDX_MASK; + return prodidx != considx ? OK : -EAGAIN; +} + +/**************************************************************************** + * Function: lpc17_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int lpc17_transmit(struct lpc17_driver_s *priv) +{ + uint32_t *txdesc; + void *txbuffer; + unsigned int prodidx; + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + DEBUGASSERT(lpc17_txdesc(priv) == OK); + + /* Increment statistics and dump the packet *if so configured) */ + + NETDEV_TXPACKETS(&priv->lp_dev); + lpc17_dumppacket("Transmit packet", + priv->lp_dev.d_buf, priv->lp_dev.d_len); + + /* Get the current producer index */ + + prodidx = lpc17_getreg(LPC17_ETH_TXPRODIDX) & ETH_TXPRODIDX_MASK; + + /* Get the packet address from the descriptor and set the descriptor control + * fields. + */ + + txdesc = (uint32_t *)(LPC17_TXDESC_BASE + (prodidx << 3)); + txbuffer = (void *)*txdesc++; + *txdesc = TXDESC_CONTROL_INT | TXDESC_CONTROL_LAST | TXDESC_CONTROL_CRC | + (priv->lp_dev.d_len - 1); + + /* Copy the packet data into the Tx buffer assignd to this descriptor. It + * should fit because each packet buffer is the MTU size and breaking up + * largerTCP messasges is handled by higher level logic. The hardware + * does, however, support breaking up larger messages into many fragments, + * however, that capability is not exploited here. + * + * This would be a great performance improvement: Remove the buffer from + * the lp_dev structure and replace it a pointer directly into the EMAC + * DMA memory. This could eliminate the following, costly memcpy. + */ + + DEBUGASSERT(priv->lp_dev.d_len <= LPC17_MAXPACKET_SIZE); + memcpy(txbuffer, priv->lp_dev.d_buf, priv->lp_dev.d_len); + + /* Bump the producer index, making the packet available for transmission. */ + + if (++prodidx >= CONFIG_NET_NTXDESC) + { + /* Wrap back to index zero */ + + prodidx = 0; + } + lpc17_putreg(prodidx, LPC17_ETH_TXPRODIDX); + + /* Enable Tx interrupts */ + + priv->lp_inten |= ETH_TXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->lp_txtimeout, LPC17_TXTIMEOUT, lpc17_txtimeout_expiry, + 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: lpc17_txpoll + * + * Description: + * The transmitter is available, check if the network layer has any + * outgoing packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int lpc17_txpoll(struct net_driver_s *dev) +{ + struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private; + int ret = OK; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->lp_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->lp_dev.d_flags)) +#endif + { + arp_out(&priv->lp_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->lp_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send this packet. In this context, we know that there is space for + * at least one more packet in the descriptor list. + */ + + lpc17_transmit(priv); + + /* Check if there is room in the device to hold another packet. If not, + * return any non-zero value to terminate the poll. + */ + + ret = lpc17_txdesc(priv); + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: lpc17_response + * + * Description: + * While processing an RxDone event, higher logic decides to send a packet, + * possibly a response to the incoming packet (but probably not, in reality). + * However, since the Rx and Tx operations are decoupled, there is no + * guarantee that there will be a Tx descriptor available at that time. + * This function will perform that check and, if no Tx descriptor is + * available, this function will (1) stop incoming Rx processing (bad), and + * (2) hold the outgoing packet in a pending state until the next Tx + * interrupt occurs. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc17_response(struct lpc17_driver_s *priv) +{ + int ret; + + /* Check if there is room in the device to hold another packet. */ + + ret = lpc17_txdesc(priv); + if (ret == OK) + { + /* Yes.. queue the packet now. */ + + lpc17_transmit(priv); + } + else + { + /* No.. mark the Tx as pending and halt further RX interrupts that + * could generate more TX activity. + */ + + DEBUGASSERT((priv->lp_inten & ETH_INT_TXDONE) != 0); + + priv->lp_txpending = true; + priv->lp_inten &= ~ETH_RXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + } +} + +/**************************************************************************** + * Function: lpc17_rxdone_process + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc17_rxdone_process(struct lpc17_driver_s *priv) +{ + uint32_t *rxstat; + bool fragment; + unsigned int prodidx; + unsigned int considx; + unsigned int pktlen; + + /* Get the current producer and consumer indices */ + + considx = lpc17_getreg(LPC17_ETH_RXCONSIDX) & ETH_RXCONSIDX_MASK; + prodidx = lpc17_getreg(LPC17_ETH_RXPRODIDX) & ETH_RXPRODIDX_MASK; + + /* Loop while there are incoming packets to be processed, that is, while + * the producer index is not equal to the consumer index. + */ + + fragment = false; + while (considx != prodidx) + { + /* Update statistics */ + + NETDEV_RXPACKETS(&priv->lp_dev); + + /* Get the Rx status and packet length (-4+1) */ + + rxstat = (uint32_t *)(LPC17_RXSTAT_BASE + (considx << 3)); + pktlen = (*rxstat & RXSTAT_INFO_RXSIZE_MASK) - 3; + + /* Check for errors. NOTE: The DMA engine reports bogus length errors, + * making this a pretty useless check. + */ + + if ((*rxstat & RXSTAT_INFO_ERROR) != 0) + { + nlldbg("Error. considx: %08x prodidx: %08x rxstat: %08x\n", + considx, prodidx, *rxstat); + NETDEV_RXERRORS(&priv->lp_dev); + } + + /* If the pktlen is greater then the buffer, then we cannot accept + * the packet. Also, since the DMA packet buffers are set up to + * be the same size as our max packet size, any fragments also + * imply that the packet is too big. + */ + + /* else */ if (pktlen > CONFIG_NET_ETH_MTU + CONFIG_NET_GUARDSIZE) + { + nlldbg("Too big. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + NETDEV_RXERRORS(&priv->lp_dev); + } + else if ((*rxstat & RXSTAT_INFO_LASTFLAG) == 0) + { + nlldbg("Fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + NETDEV_RXFRAGMENTS(&priv->lp_dev); + fragment = true; + } + else if (fragment) + { + nlldbg("Last fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + NETDEV_RXFRAGMENTS(&priv->lp_dev); + fragment = false; + } + else + { + uint32_t *rxdesc; + void *rxbuffer; + + /* Get the Rx buffer address from the Rx descriptor */ + + rxdesc = (uint32_t *)(LPC17_RXDESC_BASE + (considx << 3)); + rxbuffer = (void *)*rxdesc; + + /* Copy the data data from the EMAC DMA RAM to priv->lp_dev.d_buf. + * Set amount of data in priv->lp_dev.d_len + * + * Here would be a great performance improvement: Remove the + * buffer from the lp_dev structure and replace it with a pointer + * directly into the EMAC DMA memory. This could eliminate the + * following, costly memcpy. + */ + + memcpy(priv->lp_dev.d_buf, rxbuffer, pktlen); + priv->lp_dev.d_len = pktlen; + + lpc17_dumppacket("Received packet", + priv->lp_dev.d_buf, priv->lp_dev.d_len); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet + * tap. + */ + + pkt_input(&priv->lp_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->lp_dev); + + /* Handle ARP on input then give the IPv4 packet to the + * network layer + */ + + arp_ipin(&priv->lp_dev); + ipv4_input(&priv->lp_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->lp_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->lp_dev.d_flags)) +#endif + { + arp_out(&priv->lp_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->lp_dev); + } +#endif + + /* And send the packet */ + + lpc17_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->lp_dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->lp_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->lp_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->lp_dev.d_flags)) + { + arp_out(&priv->lp_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->lp_dev); + } +#endif + + /* And send the packet */ + + lpc17_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + NETDEV_RXARP(&priv->lp_dev); + arp_arpin(&priv->lp_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->lp_dev.d_len > 0) + { + lpc17_response(priv); + } + } + else +#endif + { + /* Unrecognized... drop it. */ + + NETDEV_RXDROPPED(&priv->lp_dev); + } + } + + /* Bump up the consumer index and resample the producer index (which + * might also have gotten bumped up by the hardware). + */ + + if (++considx >= CONFIG_NET_NRXDESC) + { + /* Wrap back to index zero */ + + considx = 0; + } + + lpc17_putreg(considx, LPC17_ETH_RXCONSIDX); + prodidx = lpc17_getreg(LPC17_ETH_RXPRODIDX) & ETH_RXPRODIDX_MASK; + } +} + +/**************************************************************************** + * Function: lpc17_txdone_process + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc17_txdone_process(struct lpc17_driver_s *priv) +{ + /* Verify that the hardware is ready to send another packet. Since a Tx + * just completed, this must be the case. + */ + + DEBUGASSERT(lpc17_txdesc(priv) == OK); + + /* Check if there is a pending Tx transfer that was scheduled by Rx handling + * while the Tx logic was busy. If so, processing that pending Tx now. + */ + + if (priv->lp_txpending) + { + /* Clear the pending condition, send the packet, and restore Rx interrupts */ + + priv->lp_txpending = false; + + lpc17_transmit(priv); + + priv->lp_inten |= ETH_RXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + } + + /* Otherwise poll the network layer for new XMIT data */ + + else + { + (void)devif_poll(&priv->lp_dev, lpc17_txpoll); + } +} + +/**************************************************************************** + * Function: lpc17_txdone_work and lpc17_rxdone_work + * + * Description: + * Perform interrupt handling logic outside of the interrupt handler (on + * the work queue thread). + * + * Parameters: + * arg - The reference to the driver structure (case to void*) + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc17_txdone_work(FAR void *arg) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Perform pending TX work. At this point TX interrupts are disable but + * may be re-enabled again depending on the actions of + * lpc17_txdone_process(). + */ + + state = net_lock(); + lpc17_txdone_process(priv); + net_unlock(state); +} + +static void lpc17_rxdone_work(FAR void *arg) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + irqstate_t flags; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Perform pending RX work. RX interrupts were disabled prior to + * scheduling this work to prevent work queue overruns. + */ + + state = net_lock(); + lpc17_rxdone_process(priv); + net_unlock(state); + + /* Re-enable RX interrupts (this must be atomic). Skip this step if the + * lp-txpending TX underrun state is in effect. + */ + + flags = enter_critical_section(); + if (!priv->lp_txpending) + { + priv->lp_inten |= ETH_RXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + } + + leave_critical_section(flags); +} +#endif /* CONFIG_NET_NOINTS */ + +/**************************************************************************** + * Function: lpc17_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc17_interrupt(int irq, void *context) +{ + register struct lpc17_driver_s *priv; + uint32_t status; + +#if CONFIG_LPC17_NINTERFACES > 1 +# error "A mechanism to associate and interface with an IRQ is needed" +#else + priv = &g_ethdrvr[0]; +#endif + + /* Get the interrupt status (zero means no interrupts pending). */ + + status = lpc17_getreg(LPC17_ETH_INTST); + if (status != 0) + { + /* Clear all pending interrupts */ + + lpc17_putreg(status, LPC17_ETH_INTCLR); + + /* Handle each pending interrupt **************************************/ + /* Check for Wake-Up on Lan *******************************************/ + +#ifdef CONFIG_NET_WOL + if ((status & ETH_INT_WKUP) != 0) + { +# warning "Missing logic" + } + else +#endif + /* Fatal Errors *******************************************************/ + /* RX OVERRUN -- Fatal overrun error in the receive queue. The fatal + * interrupt should be resolved by a Rx soft-reset. The bit is not + * set when there is a nonfatal overrun error. + * + * TX UNDERRUN -- Interrupt set on a fatal underrun error in the + * transmit queue. The fatal interrupt should be resolved by a Tx + * soft-reset. The bit is not set when there is a nonfatal underrun + * error. + */ + + if ((status & (ETH_INT_RXOVR | ETH_INT_TXUNR)) != 0) + { + if ((status & ETH_INT_RXOVR) != 0) + { + nlldbg("RX Overrun. status: %08x\n", status); + NETDEV_RXERRORS(&priv->lp_dev); + } + + if ((status & ETH_INT_TXUNR) != 0) + { + nlldbg("TX Underrun. status: %08x\n", status); + NETDEV_TXERRORS(&priv->lp_dev); + } + + /* ifup() will reset the EMAC and bring it back up */ + + (void)lpc17_ifup(&priv->lp_dev); + } + else + { + /* Check for receive events ***************************************/ + /* RX ERROR -- Triggered on receive errors: AlignmentError, + * RangeError, LengthError, SymbolError, CRCError or NoDescriptor + * or Overrun. NOTE: (1) We will still need to call lpc17_rxdone_process + * on RX errors to bump the considx over the bad packet. (2) The + * DMA engine reports bogus length errors, making this a pretty + * useless check anyway. + */ + + if ((status & ETH_INT_RXERR) != 0) + { + nlldbg("RX Error. status: %08x\n", status); + NETDEV_RXERRORS(&priv->lp_dev); + } + + /* RX FINISHED -- Triggered when all receive descriptors have + * been processed i.e. on the transition to the situation + * where ProduceIndex == ConsumeIndex. + * + * Treated as INT_RX_DONE if ProduceIndex != ConsumeIndex so the + * packets are processed anyway. + * + * RX DONE -- Triggered when a receive descriptor has been + * processed while the Interrupt bit in the Control field of + * the descriptor was set. + */ + + if ((status & ETH_INT_RXFIN) != 0 || (status & ETH_INT_RXDONE) != 0) + { + /* We have received at least one new incoming packet. */ + +#ifdef CONFIG_NET_NOINTS + /* Disable further TX interrupts for now. TX interrupts will + * be re-enabled after the work has been processed. + */ + + priv->lp_inten &= ~ETH_RXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + + /* Cancel any pending RX done work */ + + work_cancel(HPWORK, &priv->lp_rxwork); + + /* Schedule RX-related work to be performed on the work thread */ + + work_queue(HPWORK, &priv->lp_rxwork, (worker_t)lpc17_rxdone_work, + priv, 0); + +#else /* CONFIG_NET_NOINTS */ + lpc17_rxdone_process(priv); + +#endif /* CONFIG_NET_NOINTS */ + } + + /* Check for Tx events ********************************************/ + /* TX ERROR -- Triggered on transmit errors: LateCollision, + * ExcessiveCollision and ExcessiveDefer, NoDescriptor or Underrun. + * NOTE: We will still need to call lpc17_txdone_process() in order to + * clean up after the failed transmit. + */ + + if ((status & ETH_INT_TXERR) != 0) + { + nlldbg("TX Error. status: %08x\n", status); + NETDEV_TXERRORS(&priv->lp_dev); + } + +#if 0 + /* TX FINISHED -- Triggered when all transmit descriptors have + * been processed i.e. on the transition to the situation + * where ProduceIndex == ConsumeIndex. + */ + + if ((status & ETH_INT_TXFIN) != 0) + { + } +#endif + + /* TX DONE -- Triggered when a descriptor has been transmitted + * while the Interrupt bit in the Control field of the + * descriptor was set. + */ + + if ((status & ETH_INT_TXDONE) != 0) + { + NETDEV_TXDONE(&priv->lp_dev); + + /* A packet transmission just completed */ + /* Cancel the pending Tx timeout */ + + wd_cancel(priv->lp_txtimeout); + + /* Disable further Tx interrupts. Tx interrupts may be + * re-enabled again depending upon the actions of + * lpc17_txdone_process() + */ + + priv->lp_inten &= ~ETH_TXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + +#ifdef CONFIG_NET_NOINTS + /* Cancel any pending TX done work (to prevent overruns and also + * to avoid race conditions with the TX timeout work) + */ + + work_cancel(HPWORK, &priv->lp_txwork); + + /* Then make sure that the TX poll timer is running (if it is + * already running, the following would restart it). This is + * necessary to avoid certain race conditions where the polling + * sequence can be interrupted. + */ + + (void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_poll_expiry, + 1, priv); + + /* Schedule TX-related work to be performed on the work thread */ + + work_queue(HPWORK, &priv->lp_txwork, (worker_t)lpc17_txdone_work, + priv, 0); + +#else /* CONFIG_NET_NOINTS */ + /* Perform the TX work at the interrupt level */ + + lpc17_txdone_process(priv); + +#endif /* CONFIG_NET_NOINTS */ + } + } + } + + /* Clear the pending interrupt */ + +#if 0 /* Apparently not necessary */ +# if CONFIG_LPC17_NINTERFACES > 1 + lpc17_clrpend(priv->irq); +# else + lpc17_clrpend(LPC17_IRQ_ETH); +# endif +#endif + + return OK; +} + +/**************************************************************************** + * Function: lpc17_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_txtimeout_process(FAR struct lpc17_driver_s *priv) +{ + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(&priv->lp_dev); + if (priv->lp_ifup) + { + /* Then reset the hardware. ifup() will reset the interface, then bring + * it back up. + */ + + (void)lpc17_ifup(&priv->lp_dev); + + /* Then poll the network layer for new XMIT data */ + + (void)devif_poll(&priv->lp_dev, lpc17_txpoll); + } +} + +/**************************************************************************** + * Function: lpc17_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc17_txtimeout_work(FAR void *arg) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + lpc17_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: lpc17_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc17_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + struct lpc17_driver_s *priv = (struct lpc17_driver_s *)arg; + + /* Disable further Tx interrupts. Tx interrupts may be re-enabled again + * depending upon the actions of lpc17_poll_process() + */ + + priv->lp_inten &= ~ETH_TXINTS; + lpc17_putreg(priv->lp_inten, LPC17_ETH_INTEN); + +#ifdef CONFIG_NET_NOINTS + /* Is the single TX work structure available? If not, then there is + * pending TX work to be done this must be a false alarm TX timeout. + */ + + if (work_available(&priv->lp_txwork)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->lp_txwork, lpc17_txtimeout_work, priv, 0); + } + +#else + /* Process the timeout now */ + + lpc17_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: lpc17_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc17_poll_process(FAR struct lpc17_driver_s *priv) +{ + unsigned int prodidx; + unsigned int considx; + + /* Check if there is room in the send another TX packet. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ + + if (lpc17_txdesc(priv) == OK) + { + /* If so, update TCP timing states and poll the network layer for new + * XMIT data. Hmmm.. might be bug here. Does this mean if there is a + * transmit in progress, we will missing TCP time state updates? + */ + + (void)devif_timer(&priv->lp_dev, lpc17_txpoll); + } + + /* Simulate a fake receive to relaunch the data exchanges when a receive + * interrupt has been lost and all the receive buffers are used. + */ + + /* Get the current producer and consumer indices */ + + considx = lpc17_getreg(LPC17_ETH_RXCONSIDX) & ETH_RXCONSIDX_MASK; + prodidx = lpc17_getreg(LPC17_ETH_RXPRODIDX) & ETH_RXPRODIDX_MASK; + + if (considx != prodidx) + { +#ifdef CONFIG_NET_NOINTS + work_queue(HPWORK, &priv->lp_rxwork, (worker_t)lpc17_rxdone_work, + priv, 0); + +#else /* CONFIG_NET_NOINTS */ + lpc17_rxdone_process(priv); + +#endif /* CONFIG_NET_NOINTS */ + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_poll_expiry, + 1, priv); +} + +/**************************************************************************** + * Function: lpc17_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc17_poll_work(FAR void *arg) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + lpc17_poll_process(priv); + net_unlock(state); +} +#endif + + +/**************************************************************************** + * Function: lpc17_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc17_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + + DEBUGASSERT(arg); + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->lp_pollwork)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->lp_pollwork, lpc17_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_poll_expiry, 1, arg); + } + +#else + /* Process the interrupt now */ + + lpc17_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: lpc17_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void lpc17_ipv6multicast(FAR struct lpc17_driver_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->lp_dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)lpc17_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)lpc17_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)lpc17_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: lpc17_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc17_ifup(struct net_driver_s *dev) +{ + struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private; + uint32_t regval; + int ret; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Reset the Ethernet controller (again) */ + + lpc17_ethreset(priv); + + /* Initialize the PHY and wait for the link to be established */ + + ret = lpc17_phyinit(priv); + if (ret != 0) + { + ndbg("lpc17_phyinit failed: %d\n", ret); + return ret; + } + + /* Configure the MAC station address */ + + regval = (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[5] << 8 | + (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[4]; + lpc17_putreg(regval, LPC17_ETH_SA0); + + regval = (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[3] << 8 | + (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[2]; + lpc17_putreg(regval, LPC17_ETH_SA1); + + regval = (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[1] << 8 | + (uint32_t)priv->lp_dev.d_mac.ether_addr_octet[0]; + lpc17_putreg(regval, LPC17_ETH_SA2); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + lpc17_ipv6multicast(priv); +#endif + + /* Initialize Ethernet interface for the PHY setup */ + + lpc17_macmode(priv->lp_mode); + + /* Initialize EMAC DMA memory -- descriptors, status, packet buffers, etc. */ + + lpc17_txdescinit(priv); + lpc17_rxdescinit(priv); + + /* Configure to pass all received frames */ + + regval = lpc17_getreg(LPC17_ETH_MAC1); + regval |= ETH_MAC1_PARF; + lpc17_putreg(regval, LPC17_ETH_MAC1); + + /* Set up RX filter and configure to accept broadcast addresses, multicast + * addresses, and perfect station address matches. We should also accept + * perfect matches and, most likely, broadcast (for example, for ARP requests). + * Other RX filter options will only be enabled if so selected. NOTE: There + * is a selection CONFIG_NET_BROADCAST, but this enables receipt of UDP + * broadcast packets inside of the stack. + */ + + regval = ETH_RXFLCTRL_PERFEN | ETH_RXFLCTRL_BCASTEN; +#ifdef CONFIG_LPC17_MULTICAST + regval |= (ETH_RXFLCTRL_MCASTEN | ETH_RXFLCTRL_UCASTEN); +#endif +#ifdef CONFIG_NET_HASH + regval |= (ETH_RXFLCTRL_MCASTHASHEN | ETH_RXFLCTRL_UCASTHASHEN); +#endif + lpc17_putreg(regval, LPC17_ETH_RXFLCTRL); + + /* Clear any pending interrupts (shouldn't be any) */ + + lpc17_putreg(0xffffffff, LPC17_ETH_INTCLR); + + /* Configure interrupts. The Ethernet interrupt was attached during one-time + * initialization, so we only need to set the interrupt priority, configure + * interrupts, and enable them. + */ + + /* Set the interrupt to the highest priority */ + +#ifdef CONFIG_ARCH_IRQPRIO +#if CONFIG_LPC17_NINTERFACES > 1 + (void)up_prioritize_irq(priv->irq, CONFIG_NET_PRIORITY); +#else + (void)up_prioritize_irq(LPC17_IRQ_ETH, CONFIG_NET_PRIORITY); +#endif +#endif + + /* Enable Ethernet interrupts. The way we do this depends on whether or + * not Wakeup on Lan (WoL) has been configured. + */ + +#ifdef CONFIG_NET_WOL + /* Configure WoL: Clear all receive filter WoLs and enable the perfect + * match WoL interrupt. We will wait until the Wake-up to finish + * bringing things up. + */ + + lpc17_putreg(0xffffffff, LPC17_ETH_RXFLWOLCLR); + lpc17_putreg(ETH_RXFLCTRL_RXFILEN, LPC17_ETH_RXFLCTRL); + + priv->lp_inten = ETH_INT_WKUP; + lpc17_putreg(ETH_INT_WKUP, LPC17_ETH_INTEN); +#else + /* Otherwise, enable all Rx interrupts. Tx interrupts, SOFTINT and WoL are + * excluded. Tx interrupts will not be enabled until there is data to be + * sent. + */ + + priv->lp_inten = ETH_RXINTS; + lpc17_putreg(ETH_RXINTS, LPC17_ETH_INTEN); +#endif + + /* Enable Rx. "Enabling of the receive function is located in two places. + * The receive DMA manager needs to be enabled and the receive data path + * of the MAC needs to be enabled. To prevent overflow in the receive + * DMA engine the receive DMA engine should be enabled by setting the + * RxEnable bit in the Command register before enabling the receive data + * path in the MAC by setting the RECEIVE ENABLE bit in the MAC1 register." + */ + + regval = lpc17_getreg(LPC17_ETH_CMD); + regval |= ETH_CMD_RXEN; + lpc17_putreg(regval, LPC17_ETH_CMD); + + regval = lpc17_getreg(LPC17_ETH_MAC1); + regval |= ETH_MAC1_RE; + lpc17_putreg(regval, LPC17_ETH_MAC1); + + /* Enable Tx */ + + regval = lpc17_getreg(LPC17_ETH_CMD); + regval |= ETH_CMD_TXEN; + lpc17_putreg(regval, LPC17_ETH_CMD); + + /* Set and activate a timer process */ + + (void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_poll_expiry, 1, + (uint32_t)priv); + + /* Finally, make the interface up and enable the Ethernet interrupt at + * the interrupt controller + */ + + priv->lp_ifup = true; +#if CONFIG_LPC17_NINTERFACES > 1 + up_enable_irq(priv->irq); +#else + up_enable_irq(LPC17_IRQ_ETH); +#endif + return OK; +} + +/**************************************************************************** + * Function: lpc17_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc17_ifdown(struct net_driver_s *dev) +{ + struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(LPC17_IRQ_ETH); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->lp_txpoll); + wd_cancel(priv->lp_txtimeout); + + /* Reset the device and mark it as down. */ + + lpc17_ethreset(priv); + priv->lp_ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: lpc17_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void lpc17_txavail_process(FAR struct lpc17_driver_s *priv) +{ + net_lock_t state; + + /* Ignore the notification if the interface is not yet up */ + + state = net_lock(); + if (priv->lp_ifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ + + if (lpc17_txdesc(priv) == OK) + { + /* If so, then poll the network layer for new XMIT data */ + + (void)devif_poll(&priv->lp_dev, lpc17_txpoll); + } + } + + net_unlock(state); +} + +/**************************************************************************** + * Function: lpc17_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc17_txavail_work(FAR void *arg) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)arg; + + /* Perform the poll */ + + lpc17_txavail_process(priv); +} +#endif + +/**************************************************************************** + * Function: lpc17_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int lpc17_txavail(struct net_driver_s *dev) +{ + FAR struct lpc17_driver_s *priv = (FAR struct lpc17_driver_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single poll work structure available? It may not be if there + * are pending polling actions and we will have to ignore the Tx + * availability action (which is okay because all poll actions have, + * ultimately, the same effect. + */ + + if (work_available(&priv->lp_pollwork)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->lp_pollwork, lpc17_txavail_work, priv, 0); + } + +#else + + /* Perform the out-of-cycle poll now */ + + lpc17_txavail_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: lpc17_calcethcrc + * + * Description: + * Function to calculate the CRC used by LPC17 to check an Ethernet frame + * + * Algorithm adapted from LPC17xx sample code that contains this notice: + * + * 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. + * + * Parameters: + * data - the data to be checked + * length - length of the data + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t lpc17_calcethcrc(const uint8_t *data, size_t length) +{ + char byte; + int crc; + int q0; + int q1; + int q2; + int q3; + int i; + int j; + + crc = 0xffffffff; + for (i = 0; i < length; i++) + { + byte = *data++; + for (j = 0; j < 2; j++) + { + if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) + { + q3 = 0x04c11db7; + } + else + { + q3 = 0x00000000; + } + + if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) + { + q2 = 0x09823b6e; + } + else + { + q2 = 0x00000000; + } + + if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) + { + q1 = 0x130476dc; + } + else + { + q1 = 0x00000000; + } + + if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) + { + q0 = 0x2608EDB8; + } + else + { + q0 = 0x00000000; + } + + crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0; + byte >>= 4; + } + } + + return crc; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: lpc17_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lpc17_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t crc; + unsigned int ndx; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Hash function: + * + * The standard Ethernet cyclic redundancy check (CRC) function is + * calculated from the 6 byte MAC address. Bits [28:23] out of the 32-bit + * CRC result are taken to form the hash. The 6-bit hash is used to access + * the hash table: it is used as an index in the 64-bit HashFilter register + * that has been programmed with accept values. If the selected accept value + * is 1, the frame is accepted. + */ + + crc = lpc17_calcethcrc(mac, 6); + ndx = (crc >> 23) & 0x3f; + + /* Add the MAC address to the hardware multicast hash table */ + + if (ndx > 31) + { + regaddr = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */ + ndx -= 32; + } + else + { + regaddr = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */ + } + + regval = lpc17_getreg(regaddr); + regval |= 1 << ndx; + lpc17_putreg(regval, regaddr); + + /* Enabled multicast address filtering in the RxFilterControl register: + * + * AcceptUnicastHashEn: When set to ’1’, unicast frames that pass the + * imperfect hash filter are accepted. + * AcceptMulticastHashEn When set to ’1’, multicast frames that pass the + * imperfect hash filter are accepted. + */ + + regval = lpc17_getreg(LPC17_ETH_RXFLCTRL); + regval &= ~ETH_RXFLCTRL_UCASTHASHEN; + regval |= ETH_RXFLCTRL_MCASTHASHEN; + lpc17_putreg(regval, LPC17_ETH_RXFLCTRL); + + return OK; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: lpc17_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int lpc17_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + uintptr_t regaddr1; + uintptr_t regaddr2; + uint32_t regval; + uint32_t crc; + unsigned int ndx; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Hash function: + * + * The standard Ethernet cyclic redundancy check (CRC) function is + * calculated from the 6 byte MAC address. Bits [28:23] out of the 32-bit + * CRC result are taken to form the hash. The 6-bit hash is used to access + * the hash table: it is used as an index in the 64-bit HashFilter register + * that has been programmed with accept values. If the selected accept value + * is 1, the frame is accepted. + */ + + crc = lpc17_calcethcrc(mac, 6); + ndx = (crc >> 23) & 0x3f; + + /* Remove the MAC address to the hardware multicast hash table */ + + if (ndx > 31) + { + regaddr1 = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */ + regaddr2 = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */ + ndx -= 32; + } + else + { + regaddr1 = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */ + regaddr2 = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */ + } + + regval = lpc17_getreg(regaddr1); + regval &= ~(1 << ndx); + lpc17_putreg(regval, regaddr1); + + /* If there are no longer addresses being filtered , disable multicast + * filtering. + */ + + if (regval == 0 && lpc17_getreg(regaddr2) == 0) + { + /* AcceptUnicastHashEn: When set to ’1’, unicast frames that pass the + * imperfect hash filter are accepted. + * AcceptMulticastHashEn When set to ’1’, multicast frames that pass the + * imperfect hash filter are accepted. + */ + + regval = lpc17_getreg(LPC17_ETH_RXFLCTRL); + regval &= ~(ETH_RXFLCTRL_UCASTHASHEN | ETH_RXFLCTRL_MCASTHASHEN); + lpc17_putreg(regval, LPC17_ETH_RXFLCTRL); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc17_showpins + * + * Description: + * Dump GPIO registers + * + * Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +static void lpc17_showpins(void) +{ + lpc17_dumpgpio(GPIO_PORT1 | GPIO_PIN0, "P1[1-15]"); + lpc17_dumpgpio(GPIO_PORT1 | GPIO_PIN16, "P1[16-31]"); +} +#endif + +/**************************************************************************** + * Name: lpc17_showmii + * + * Description: + * Dump PHY MII registers + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(LPC17_HAVE_PHY) +static void lpc17_showmii(uint8_t phyaddr, const char *msg) +{ + dbg("PHY " LPC17_PHYNAME ": %s\n", msg); + dbg(" MCR: %04x\n", lpc17_phyread(phyaddr, MII_MCR)); + dbg(" MSR: %04x\n", lpc17_phyread(phyaddr, MII_MSR)); + dbg(" ADVERTISE: %04x\n", lpc17_phyread(phyaddr, MII_ADVERTISE)); + dbg(" LPA: %04x\n", lpc17_phyread(phyaddr, MII_LPA)); + dbg(" EXPANSION: %04x\n", lpc17_phyread(phyaddr, MII_EXPANSION)); +#ifdef CONFIG_ETH0_PHY_KS8721 + dbg(" 10BTCR: %04x\n", lpc17_phyread(phyaddr, MII_KS8721_10BTCR)); +#endif +} +#endif + +/**************************************************************************** + * Function: lpc17_phywrite + * + * Description: + * Write a value to an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * phydata - The data to write to the PHY register + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static void lpc17_phywrite(uint8_t phyaddr, uint8_t regaddr, uint16_t phydata) +{ + uint32_t regval; + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << ETH_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << ETH_MADR_REGADDR_SHIFT); + lpc17_putreg(regval, LPC17_ETH_MADR); + + /* Set up to write */ + + lpc17_putreg(ETH_MCMD_WRITE, LPC17_ETH_MCMD); + + /* Write the register data to the PHY */ + + lpc17_putreg((uint32_t)phydata, LPC17_ETH_MWTD); + + /* Wait for the PHY command to complete */ + + while ((lpc17_getreg(LPC17_ETH_MIND) & ETH_MIND_BUSY) != 0); +} +#endif + +/**************************************************************************** + * Function: lpc17_phyread + * + * Description: + * Read a value from an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * + * Returned Value: + * Data read from the PHY register + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static uint16_t lpc17_phyread(uint8_t phyaddr, uint8_t regaddr) +{ + uint32_t regval; + + lpc17_putreg(0, LPC17_ETH_MCMD); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << ETH_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << ETH_MADR_REGADDR_SHIFT); + lpc17_putreg(regval, LPC17_ETH_MADR); + + /* Set up to read */ + + lpc17_putreg(ETH_MCMD_READ, LPC17_ETH_MCMD); + + /* Wait for the PHY command to complete */ + + while ((lpc17_getreg(LPC17_ETH_MIND) & (ETH_MIND_BUSY | ETH_MIND_NVALID)) != 0); + lpc17_putreg(0, LPC17_ETH_MCMD); + + /* Return the PHY register data */ + + return (uint16_t)(lpc17_getreg(LPC17_ETH_MRDD) & ETH_MRDD_MASK); +} +#endif + +/**************************************************************************** + * Function: lpc17_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static inline int lpc17_phyreset(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Reset the PHY. Needs a minimal 50uS delay after reset. */ + + lpc17_phywrite(phyaddr, MII_MCR, MII_MCR_RESET); + + /* Wait for a minimum of 50uS no matter what */ + + up_udelay(50); + + /* The MCR reset bit is self-clearing. Wait for it to be clear indicating + * that the reset is complete. + */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { + phyreg = lpc17_phyread(phyaddr, MII_MCR); + if ((phyreg & MII_MCR_RESET) == 0) + { + return OK; + } + } + + ndbg("Reset failed. MCR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: lpc17_phyautoneg + * + * Description: + * Enable auto-negotiation. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * The adverisement regiser has already been configured. + * + ****************************************************************************/ + +#if defined(LPC17_HAVE_PHY) && defined(CONFIG_PHY_AUTONEG) +static inline int lpc17_phyautoneg(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Start auto-negotiation */ + + lpc17_phywrite(phyaddr, MII_MCR, MII_MCR_ANENABLE | MII_MCR_ANRESTART); + + /* Wait for autonegotiation to complete */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { + /* Check if auto-negotiation has completed */ + + phyreg = lpc17_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. return success */ + + return OK; + } + } + + ndbg("Auto-negotiation failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: lpc17_phymode + * + * Description: + * Set the PHY to operate at a selected speed/duplex mode. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static int lpc17_phymode(uint8_t phyaddr, uint8_t mode) +{ + int32_t timeout; + uint16_t phyreg; + + /* Disable auto-negotiation and set fixed Speed and Duplex settings: + * + * MII_MCR_UNIDIR 0=Disable unidirectional enable + * MII_MCR_SPEED1000 0=Reserved on 10/100 + * MII_MCR_CTST 0=Disable collision test + * MII_MCR_FULLDPLX ?=Full duplex + * MII_MCR_ANRESTART 0=Don't restart auto negotiation + * MII_MCR_ISOLATE 0=Don't electronically isolate PHY from MII + * MII_MCR_PDOWN 0=Don't powerdown the PHY + * MII_MCR_ANENABLE 0=Disable auto negotiation + * MII_MCR_SPEED100 ?=Select 100Mbps + * MII_MCR_LOOPBACK 0=Disable loopback mode + * MII_MCR_RESET 0=No PHY reset + */ + + phyreg = 0; + if ((mode & LPC17_SPEED_MASK) == LPC17_SPEED_100) + { + phyreg = MII_MCR_SPEED100; + } + + if ((mode & LPC17_DUPLEX_MASK) == LPC17_DUPLEX_FULL) + { + phyreg |= MII_MCR_FULLDPLX; + } + + lpc17_phywrite(phyaddr, MII_MCR, phyreg); + + /* Then wait for the link to be established */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { + /* REVISIT: This should not depend explicity on the board configuration. + * Rather, there should be some additional configuration option to + * suppress this DP83848C-specific behavior. + */ + +#if defined(CONFIG_ETH0_PHY_DP83848C) && !defined(CONFIG_ARCH_BOARD_MBED) + phyreg = lpc17_phyread(phyaddr, MII_DP83848C_STS); + if ((phyreg & 0x0001) != 0) + { + /* Yes.. return success */ + + return OK; + } +#else + phyreg = lpc17_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_LINKSTATUS) != 0) + { + /* Yes.. return success */ + + return OK; + } +#endif + } + + ndbg("Link failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: lpc17_phyinit + * + * Description: + * Initialize the PHY + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directly. As a side-effect, it will initialize priv->lp_phyaddr + * and priv->lp_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static inline int lpc17_phyinit(struct lpc17_driver_s *priv) +{ + unsigned int phyaddr; + uint16_t phyreg; + uint32_t regval; + int ret; + + /* MII configuration: host clocked divided per board.h, no suppress + * preamble, no scan increment. + */ + + lpc17_putreg(ETH_MCFG_CLKSEL_DIV, LPC17_ETH_MCFG); + lpc17_putreg(0, LPC17_ETH_MCMD); + + /* Enter RMII mode and select 100 MBPS support */ + + lpc17_putreg(ETH_CMD_RMII, LPC17_ETH_CMD); + lpc17_putreg(ETH_SUPP_SPEED, LPC17_ETH_SUPP); + + /* Find PHY Address. Because the controller has a pull-up and the + * PHY has pull-down resistors on RXD lines some times the PHY + * latches different at different addresses. + */ + + for (phyaddr = 1; phyaddr < 32; phyaddr++) + { + /* Check if we can see the selected device ID at this + * PHY address. + */ + + phyreg = (unsigned int)lpc17_phyread(phyaddr, MII_PHYID1); + nvdbg("Addr: %d PHY ID1: %04x\n", phyaddr, phyreg); + + /* Compare OUI bits 3-18 */ + + if (phyreg == LPC17_PHYID1) + { + phyreg = lpc17_phyread(phyaddr, MII_PHYID2); + nvdbg("Addr: %d PHY ID2: %04x\n", phyaddr, phyreg); + + /* Compare OUI bits 19-24 and the 6-bit model number (ignoring the + * 4-bit revision number). + */ + + if ((phyreg & 0xfff0) == LPC17_PHYID2) + { + break; + } + } + } + + /* Check if the PHY device address was found */ + + if (phyaddr > 31) + { + /* Failed to find PHY at any location */ + + ndbg("No PHY detected\n"); + return -ENODEV; + } + nvdbg("phyaddr: %d\n", phyaddr); + + /* Save the discovered PHY device address */ + + priv->lp_phyaddr = phyaddr; + + /* Reset the PHY */ + + ret = lpc17_phyreset(phyaddr); + if (ret < 0) + { + return ret; + } + lpc17_showmii(phyaddr, "After reset"); + + /* Check for preamble suppression support */ + + phyreg = lpc17_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_MFRAMESUPPRESS) != 0) + { + /* The PHY supports preamble suppression */ + + regval = lpc17_getreg(LPC17_ETH_MCFG); + regval |= ETH_MCFG_SUPPRE; + lpc17_putreg(regval, LPC17_ETH_MCFG); + } + + /* Are we configured to do auto-negotiation? */ + +#ifdef CONFIG_PHY_AUTONEG + /* Setup the Auto-negotiation advertisement: 100 or 10, and HD or FD */ + + lpc17_phywrite(phyaddr, MII_ADVERTISE, + (MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_CSMA)); + + /* Then perform the auto-negotiation */ + + ret = lpc17_phyautoneg(phyaddr); + if (ret < 0) + { + return ret; + } +#else + /* Set up the fixed PHY configuration */ + + ret = lpc17_phymode(phyaddr, LPC17_MODE_DEFLT); + if (ret < 0) + { + return ret; + } +#endif + + /* The link is established */ + + lpc17_showmii(phyaddr, "After link established"); + + /* Check configuration */ + +#if defined(CONFIG_ETH0_PHY_KS8721) + phyreg = lpc17_phyread(phyaddr, MII_KS8721_10BTCR); + + switch (phyreg & KS8721_10BTCR_MODE_MASK) + { + case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */ + priv->lp_mode = LPC17_10BASET_HD; + lpc17_putreg(0, LPC17_ETH_SUPP); + break; + + case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */ + priv->lp_mode = LPC17_100BASET_HD; + break; + + case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */ + priv->lp_mode = LPC17_10BASET_FD; + lpc17_putreg(0, LPC17_ETH_SUPP); + break; + + case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */ + priv->lp_mode = LPC17_100BASET_FD; + break; + + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + +#elif defined(CONFIG_ETH0_PHY_KSZ8041) + phyreg = lpc17_phyread(phyaddr, MII_KSZ8041_PHYCTRL2); + + switch (phyreg & MII_PHYCTRL2_MODE_MASK) + { + case MII_PHYCTRL2_MODE_10HDX: /* 10BASE-T half duplex */ + priv->lp_mode = LPC17_10BASET_HD; + lpc17_putreg(0, LPC17_ETH_SUPP); + break; + + case MII_PHYCTRL2_MODE_100HDX: /* 100BASE-T half duplex */ + priv->lp_mode = LPC17_100BASET_HD; + break; + + case MII_PHYCTRL2_MODE_10FDX: /* 10BASE-T full duplex */ + priv->lp_mode = LPC17_10BASET_FD; + lpc17_putreg(0, LPC17_ETH_SUPP); + break; + + case MII_PHYCTRL2_MODE_100FDX: /* 100BASE-T full duplex */ + priv->lp_mode = LPC17_100BASET_FD; + break; + + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + +#elif defined(CONFIG_ETH0_PHY_DP83848C) + phyreg = lpc17_phyread(phyaddr, MII_DP83848C_STS); + + /* Configure for full/half duplex mode and speed */ + + switch (phyreg & 0x0006) + { + case 0x0000: + priv->lp_mode = LPC17_100BASET_HD; + break; + + case 0x0002: + priv->lp_mode = LPC17_10BASET_HD; + break; + + case 0x0004: + priv->lp_mode = LPC17_100BASET_FD; + break; + + case 0x0006: + priv->lp_mode = LPC17_10BASET_FD; + break; + + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + +#elif defined(CONFIG_ETH0_PHY_LAN8720) + { + uint16_t advertise; + uint16_t lpa; + + up_udelay(500); + advertise = lpc17_phyread(phyaddr, MII_ADVERTISE); + lpa = lpc17_phyread(phyaddr, MII_LPA); + + /* Check for 100BASETX full duplex */ + + if ((advertise & MII_ADVERTISE_100BASETXFULL) != 0 && + (lpa & MII_LPA_100BASETXFULL) != 0) + { + priv->lp_mode = LPC17_100BASET_FD; + } + + /* Check for 100BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_100BASETXHALF) != 0 && + (lpa & MII_LPA_100BASETXHALF) != 0) + { + priv->lp_mode = LPC17_100BASET_HD; + } + + /* Check for 10BASETX full duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXFULL) != 0 && + (lpa & MII_LPA_10BASETXFULL) != 0) + { + priv->lp_mode = LPC17_10BASET_FD; + } + + /* Check for 10BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXHALF) != 0 && + (lpa & MII_LPA_10BASETXHALF) != 0) + { + priv->lp_mode = LPC17_10BASET_HD; + } + else + { + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + } + +#else +# warning "PHY Unknown: speed and duplex are bogus" +#endif + + ndbg("%dBase-T %s duplex\n", + (priv->lp_mode & LPC17_SPEED_MASK) == LPC17_SPEED_100 ? 100 : 10, + (priv->lp_mode & LPC17_DUPLEX_MASK) == LPC17_DUPLEX_FULL ?"full" : "half"); + + /* Disable auto-configuration. Set the fixed speed/duplex mode. + * (probably more than little redundant). + * + * REVISIT: Revisit the following CONFIG_PHY_CEMENT_DISABLE work-around. + * It is should not needed if CONFIG_PHY_AUTONEG is defined and is known + * cause a problem for at least one PHY (DP83848I PHY). It might be + * safe just to remove this elided coded for all PHYs. + */ + +#ifndef CONFIG_PHY_CEMENT_DISABLE + ret = lpc17_phymode(phyaddr, priv->lp_mode); +#endif + lpc17_showmii(phyaddr, "After final configuration"); + return ret; +} +#else +static inline int lpc17_phyinit(struct lpc17_driver_s *priv) +{ + priv->lp_mode = LPC17_MODE_DEFLT; + return OK; +} +#endif + +/**************************************************************************** + * Function: lpc17_txdescinit + * + * Description: + * Initialize the EMAC Tx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directory. + * As a side-effect, it will initialize priv->lp_phyaddr and + * priv->lp_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void lpc17_txdescinit(struct lpc17_driver_s *priv) +{ + uint32_t *txdesc; + uint32_t *txstat; + uint32_t pktaddr; + int i; + + /* Configure Tx descriptor and status tables */ + + lpc17_putreg(LPC17_TXDESC_BASE, LPC17_ETH_TXDESC); + lpc17_putreg(LPC17_TXSTAT_BASE, LPC17_ETH_TXSTAT); + lpc17_putreg(CONFIG_NET_NTXDESC-1, LPC17_ETH_TXDESCRNO); + + /* Initialize Tx descriptors and link to packet buffers */ + + txdesc = (uint32_t *)LPC17_TXDESC_BASE; + pktaddr = LPC17_TXBUFFER_BASE; + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + *txdesc++ = pktaddr; + *txdesc++ = (TXDESC_CONTROL_INT | (LPC17_MAXPACKET_SIZE - 1)); + pktaddr += LPC17_MAXPACKET_SIZE; + } + + /* Initialize Tx status */ + + txstat = (uint32_t *)LPC17_TXSTAT_BASE; + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + *txstat++ = 0; + } + + /* Point to first Tx descriptor */ + + lpc17_putreg(0, LPC17_ETH_TXPRODIDX); +} + +/**************************************************************************** + * Function: lpc17_rxdescinit + * + * Description: + * Initialize the EMAC Rx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directory. + * As a side-effect, it will initialize priv->lp_phyaddr and + * priv->lp_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void lpc17_rxdescinit(struct lpc17_driver_s *priv) +{ + uint32_t *rxdesc; + uint32_t *rxstat; + uint32_t pktaddr; + int i; + + /* Configure Rx descriptor and status tables */ + + lpc17_putreg(LPC17_RXDESC_BASE, LPC17_ETH_RXDESC); + lpc17_putreg(LPC17_RXSTAT_BASE, LPC17_ETH_RXSTAT); + lpc17_putreg(CONFIG_NET_NRXDESC-1, LPC17_ETH_RXDESCNO); + + /* Initialize Rx descriptors and link to packet buffers */ + + rxdesc = (uint32_t *)LPC17_RXDESC_BASE; + pktaddr = LPC17_RXBUFFER_BASE; + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + *rxdesc++ = pktaddr; + *rxdesc++ = (RXDESC_CONTROL_INT | (LPC17_MAXPACKET_SIZE - 1)); + pktaddr += LPC17_MAXPACKET_SIZE; + } + + /* Initialize Rx status */ + + rxstat = (uint32_t *)LPC17_RXSTAT_BASE; + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + *rxstat++ = 0; + *rxstat++ = 0; + } + + /* Point to first Rx descriptor */ + + lpc17_putreg(0, LPC17_ETH_RXCONSIDX); +} + +/**************************************************************************** + * Function: lpc17_macmode + * + * Description: + * Set the MAC to operate at a selected speed/duplex mode. + * + * Parameters: + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef LPC17_HAVE_PHY +static void lpc17_macmode(uint8_t mode) +{ + uint32_t regval; + + /* Set up for full or half duplex operation */ + + if ((mode & LPC17_DUPLEX_MASK) == LPC17_DUPLEX_FULL) + { + /* Set the back-to-back inter-packet gap */ + + lpc17_putreg(21, LPC17_ETH_IPGT); + + /* Set MAC to operate in full duplex mode with CRC and Pad enabled */ + + regval = lpc17_getreg(LPC17_ETH_MAC2); + regval |= (ETH_MAC2_FD | ETH_MAC2_CRCEN | ETH_MAC2_PADCRCEN); + lpc17_putreg(regval, LPC17_ETH_MAC2); + + /* Select full duplex operation for ethernet controller */ + + regval = lpc17_getreg(LPC17_ETH_CMD); + regval |= (ETH_CMD_FD | ETH_CMD_RMII | ETH_CMD_PRFRAME); + lpc17_putreg(regval, LPC17_ETH_CMD); + } + else + { + /* Set the back-to-back inter-packet gap */ + + lpc17_putreg(18, LPC17_ETH_IPGT); + + /* Set MAC to operate in half duplex mode with CRC and Pad enabled */ + + regval = lpc17_getreg(LPC17_ETH_MAC2); + regval &= ~ETH_MAC2_FD; + regval |= (ETH_MAC2_CRCEN | ETH_MAC2_PADCRCEN); + lpc17_putreg(regval, LPC17_ETH_MAC2); + + /* Select half duplex operation for ethernet controller */ + + regval = lpc17_getreg(LPC17_ETH_CMD); + regval &= ~ETH_CMD_FD; + regval |= (ETH_CMD_RMII | ETH_CMD_PRFRAME); + lpc17_putreg(regval, LPC17_ETH_CMD); + } + + /* This is currently done in lpc17_phyinit(). That doesn't + * seem like the right place. It should be done here. + */ + +#if 0 + regval = lpc17_getreg(LPC17_ETH_SUPP); + if ((mode & LPC17_SPEED_MASK) == LPC17_SPEED_100) + { + regval |= ETH_SUPP_SPEED; + } + else + { + regval &= ~ETH_SUPP_SPEED; + } + lpc17_putreg(regval, LPC17_ETH_SUPP); +#endif +} +#endif + +/**************************************************************************** + * Function: lpc17_ethreset + * + * Description: + * Configure and reset the Ethernet module, leaving it in a disabled state. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc17_ethreset(struct lpc17_driver_s *priv) +{ + irqstate_t flags; + + /* Reset the MAC */ + + flags = enter_critical_section(); + + /* Put the MAC into the reset state */ + + lpc17_putreg((ETH_MAC1_TXRST | ETH_MAC1_MCSTXRST | ETH_MAC1_RXRST | + ETH_MAC1_MCSRXRST | ETH_MAC1_SIMRST | ETH_MAC1_SOFTRST), + LPC17_ETH_MAC1); + + /* Disable RX/RX, clear modes, reset all control registers */ + + lpc17_putreg((ETH_CMD_REGRST | ETH_CMD_TXRST | ETH_CMD_RXRST), + LPC17_ETH_CMD); + + /* Take the MAC out of the reset state */ + + up_udelay(50); + lpc17_putreg(0, LPC17_ETH_MAC1); + + /* The RMII bit must be set on initialization (I'm not sure this needs + * to be done here but... oh well). + */ + + lpc17_putreg(ETH_CMD_RMII, LPC17_ETH_CMD); + + /* Set other misc configuration-related registers to default values */ + + lpc17_putreg(0, LPC17_ETH_MAC2); + lpc17_putreg(0, LPC17_ETH_SUPP); + lpc17_putreg(0, LPC17_ETH_TEST); + + lpc17_putreg(18, LPC17_ETH_IPGR); + lpc17_putreg(((15 << ETH_CLRT_RMAX_SHIFT) | (55 << ETH_CLRT_COLWIN_SHIFT)), + LPC17_ETH_CLRT); + + /* Set the Maximum Frame size register. "This field resets to the value + * 0x0600, which represents a maximum receive frame of 1536 octets. An + * untagged maximum size Ethernet frame is 1518 octets. A tagged frame adds + * four octets for a total of 1522 octets. If a shorter maximum length + * restriction is desired, program this 16-bit field." + */ + + lpc17_putreg(LPC17_MAXPACKET_SIZE, LPC17_ETH_MAXF); + + /* Disable all Ethernet controller interrupts */ + + lpc17_putreg(0, LPC17_ETH_INTEN); + + /* Clear any pending interrupts (shouldn't be any) */ + + lpc17_putreg(0xffffffff, LPC17_ETH_INTCLR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: lpc17_ethinitialize + * + * Description: + * Initialize one Ethernet controller and driver structure. + * + * Parameters: + * intf - Selects the interface to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if CONFIG_LPC17_NINTERFACES > 1 +int lpc17_ethinitialize(int intf) +#else +static inline int lpc17_ethinitialize(int intf) +#endif +{ + struct lpc17_driver_s *priv; + uint32_t regval; + int ret; + int i; + + DEBUGASSERT(intf < CONFIG_LPC17_NINTERFACES); + priv = &g_ethdrvr[intf]; + + /* Turn on the ethernet MAC clock */ + + regval = lpc17_getreg(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCENET; + lpc17_putreg(regval, LPC17_SYSCON_PCONP); + + /* Configure all GPIO pins needed by ENET */ + + for (i = 0; i < GPIO_NENET_PINS; i++) + { + (void)lpc17_configgpio(g_enetpins[i]); + } + lpc17_showpins(); + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct lpc17_driver_s)); + priv->lp_dev.d_ifup = lpc17_ifup; /* I/F down callback */ + priv->lp_dev.d_ifdown = lpc17_ifdown; /* I/F up (new IP address) callback */ + priv->lp_dev.d_txavail = lpc17_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->lp_dev.d_addmac = lpc17_addmac; /* Add multicast MAC address */ + priv->lp_dev.d_rmmac = lpc17_rmmac; /* Remove multicast MAC address */ +#endif + priv->lp_dev.d_private = (void *)priv; /* Used to recover private state from dev */ + +#if CONFIG_LPC17_NINTERFACES > 1 +# error "A mechanism to associate base address an IRQ with an interface is needed" + priv->lp_base = ??; /* Ethernet controller base address */ + priv->lp_irq = ??; /* Ethernet controller IRQ number */ +#endif + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->lp_txpoll = wd_create(); /* Create periodic poll timer */ + priv->lp_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Reset the Ethernet controller and leave in the ifdown statue. The + * Ethernet controller will be properly re-initialized each time + * lpc17_ifup() is called. + */ + + lpc17_ifdown(&priv->lp_dev); + + /* Attach the IRQ to the driver */ + +#if CONFIG_LPC17_NINTERFACES > 1 + ret = irq_attach(priv->irq, lpc17_interrupt); +#else + ret = irq_attach(LPC17_IRQ_ETH, lpc17_interrupt); +#endif + if (ret != 0) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->lp_dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one + * interface in the chip, then board-specific logic will have to provide + * this function to determine which, if any, Ethernet controllers should + * be initialized. + * + ****************************************************************************/ + +#if CONFIG_LPC17_NINTERFACES == 1 +void up_netinitialize(void) +{ + (void)lpc17_ethinitialize(0); +} +#endif +#endif /* LPC17_NETHCONTROLLERS > 0 */ +#endif /* CONFIG_NET && CONFIG_LPC17_ETHERNET */ diff --git a/arch/arm/src/lpc17xx/lpc17_ethernet.h b/arch/arm/src/lpc17xx/lpc17_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..77ce1cc0f448193d1fc4b168ee3db32b693e1c8d --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_ethernet.h @@ -0,0 +1,73 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_ethernet.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_ETHERNET_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_ethernet.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_ETHERNET_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_gpdma.c b/arch/arm/src/lpc17xx/lpc17_gpdma.c new file mode 100644 index 0000000000000000000000000000000000000000..4a93267718d60943963442a9b5722f2aad35327b --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpdma.c @@ -0,0 +1,755 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_gpdma.c + * + * Copyright (C) 2010, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "chip/lpc17_syscon.h" +#include "lpc17_gpdma.h" + +#ifdef CONFIG_LPC17_GPDMA + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one DMA channel */ + +struct lpc17_dmach_s +{ + uint8_t chn; /* The DMA channel number */ + bool inuse; /* True: The channel is in use */ + bool inprogress; /* True: DMA is in progress on this channel */ + uint16_t nxfrs; /* Number of transfers */ + dma_callback_t callback; /* DMA completion callback function */ + void *arg; /* Argument to pass to the callback function */ +}; + +/* This structure represents the state of the LPC17 DMA block */ + +struct lpc17_gpdma_s +{ + sem_t exclsem; /* For exclusive access to the DMA channel list */ + + /* This is the state of each DMA channel */ + + struct lpc17_dmach_s dmach[LPC17_NDMACH]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* The state of the LPC17 DMA block */ + +static struct lpc17_gpdma_s g_gpdma; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* If the following value is zero, then there is no DMA in progress. This + * value is needed in the IDLE loop to determine if the IDLE loop should + * go into lower power power consumption modes. According to the LPC17xx + * User Manual: "The DMA controller can continue to work in Sleep mode, and + * has access to the peripheral SRAMs and all peripheral registers. The + * flash memory and the Main SRAM are not available in Sleep mode, they are + * disabled in order to save power." + */ + +volatile uint8_t g_dma_inprogress; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_dmainprogress + * + * Description: + * Another DMA has started. Increment the g_dma_inprogress counter. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_dmainprogress(struct lpc17_dmach_s *dmach) +{ + irqstate_t flags; + + /* Increment the DMA in progress counter */ + + flags = enter_critical_section(); + DEBUGASSERT(!dmach->inprogress && g_dma_inprogress < LPC17_NDMACH); + g_dma_inprogress++; + dmach->inprogress = true; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_dmadone + * + * Description: + * A DMA has completed. Decrement the g_dma_inprogress counter. + * + * This function is called only from lpc17_dmastop which, in turn, will be + * called either by the user directly, by the user indirectly via + * lpc17_dmafree(), or from gpdma_interrupt when the transfer completes. + * + * NOTE: In the first two cases, we must be able to handle the case where + * there is no DMA in progress and gracefully ignore the call. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_dmadone(struct lpc17_dmach_s *dmach) +{ + irqstate_t flags; + + /* Increment the DMA in progress counter */ + + flags = enter_critical_section(); + if (dmach->inprogress) + { + DEBUGASSERT(g_dma_inprogress > 0); + dmach->inprogress = false; + g_dma_inprogress--; + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: gpdma_interrupt + * + * Description: + * The common GPDMA interrupt handler. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int gpdma_interrupt(int irq, FAR void *context) +{ + struct lpc17_dmach_s *dmach; + uint32_t regval; + uint32_t chbit; + int result; + int i; + + /* Check each DMA channel */ + + for (i = 0; i < LPC17_NDMACH; i++) + { + chbit = DMACH((uint32_t)i); + + /* Is there an interrupt pending for this channel? If the bit for + * this channel is set, that indicates that a specific DMA channel + * interrupt request is active. The request can be generated from + * either the error or terminal count interrupt requests. + */ + + regval = getreg32(LPC17_DMA_INTST); + if ((regval & chbit) != 0) + { + /* Yes.. Is this channel assigned? Is there a callback function? */ + + dmach = &g_gpdma.dmach[i]; + if (dmach->inuse && dmach->callback) + { + /* Yes.. did an error occur? */ + + regval = getreg32(LPC17_DMA_INTERRST); + if ((regval & chbit) != 0) + { + /* Yes.. report error status */ + + result = -EIO; + } + + /* Then this must be a terminal transfer event */ + + else + { + /* Let's make sure it is the terminal transfer event. */ + + regval = getreg32(LPC17_DMA_INTTCST); + if ((regval & chbit) != 0) + { + result = OK; + } + + /* This should not happen */ + + else + { + result = -EINVAL; + } + } + + /* Perform the callback */ + + dmach->callback((DMA_HANDLE)dmach, dmach->arg, result); + } + + /* Disable this channel, mask any further interrupts for + * this channel, and clear any pending interrupts. + */ + + lpc17_dmastop((DMA_HANDLE)dmach); + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * Zero on success; A negated errno value on failure. + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + uint32_t regval; + int ret; + int i; + + /* Enable clocking to the GPDMA block */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCGPDMA; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Reset all channel configurations */ + + for (i = 0; i < LPC17_NDMACH; i++) + { + putreg32(0, LPC17_DMACH_CONFIG(i)); + } + + /* Clear all DMA interrupts */ + + putreg32(DMACH_ALL, LPC17_DMA_INTTCCLR); + putreg32(DMACH_ALL, LPC17_DMA_INTERRCLR); + + /* Initialize the DMA state structure */ + + sem_init(&g_gpdma.exclsem, 0, 1); + + for (i = 0; i < LPC17_NDMACH; i++) + { + g_gpdma.dmach[i].chn = i; /* Channel number */ + g_gpdma.dmach[i].inuse = false; /* Channel is not in-use */ + } + + /* Attach and enable the common interrupt handler */ + + ret = irq_attach(LPC17_IRQ_GPDMA, gpdma_interrupt); + if (ret == OK) + { + up_enable_irq(LPC17_IRQ_GPDMA); + } + + /* Enable the DMA controller (for little endian operation) */ + + putreg32(DMA_CONFIG_E, LPC17_DMA_CONFIG); +} + +/**************************************************************************** + * Name: lpc17_dmaconfigure + * + * Description: + * Configure a DMA request. Each DMA request may have two different DMA + * request sources. This associates one of the sources with a DMA request. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc17_dmaconfigure(uint8_t dmarequest, bool alternate) +{ + uint32_t regval; + + DEBUGASSERT(dmarequest < LPC17_NDMAREQ); + +#ifdef LPC176x + /* For the LPC176x family, only request numbers 8-15 have DMASEL bits */ + + if (dmarequest < 8) + { + return; + } + + dmarequest -= 8; +#endif + + /* Set or clear the DMASEL bit corresponding to the request number */ + + regval = getreg32(LPC17_SYSCON_DMAREQSEL); + + if (alternate) + { + regval |= (1 << dmarequest); + } + else + { + regval &= ~(1 << dmarequest); + } + + putreg32(regval, LPC17_SYSCON_DMAREQSEL); +} + +/**************************************************************************** + * Name: lpc17_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +DMA_HANDLE lpc17_dmachannel(void) +{ + struct lpc17_dmach_s *dmach = NULL; + int ret; + int i; + + /* Get exclusive access to the GPDMA state structure */ + + do + { + ret = sem_wait(&g_gpdma.exclsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); + + /* Find an available DMA channel */ + + for (i = 0; i < LPC17_NDMACH; i++) + { + if (!g_gpdma.dmach[i].inuse) + { + /* Found one! */ + + dmach = &g_gpdma.dmach[i]; + g_gpdma.dmach[i].inuse = true; + break; + } + } + + /* Return what we found (or not) */ + + sem_post(&g_gpdma.exclsem); + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: lpc17_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until lpc17_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc17_dmafree(DMA_HANDLE handle) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + + DEBUGASSERT(dmach && dmach->inuse); + + /* Make sure that the DMA channel was properly stopped */ + + lpc17_dmastop(handle); + + /* Mark the channel available. This is an atomic operation and needs no + * special protection. + */ + + dmach->inuse = false; +} + +/**************************************************************************** + * Name: lpc17_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +int lpc17_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nxfrs) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + uint32_t chbit; + uint32_t regval; + uint32_t base; + + DEBUGASSERT(dmach && dmach->inuse && nxfrs < 4096); + + chbit = DMACH((uint32_t)dmach->chn); + base = LPC17_DMACH_BASE((uint32_t)dmach->chn); + + /* Put the channel in a known state. Zero disables everything */ + + putreg32(0, base + LPC17_DMACH_CONTROL_OFFSET); + putreg32(0, base + LPC17_DMACH_CONFIG_OFFSET); + + /* "Programming a DMA channel + * + * 1. "Choose a free DMA channel with the priority needed. DMA channel 0 + * has the highest priority and DMA channel 7 the lowest priority. + */ + + regval = getreg32(LPC17_DMA_ENBLDCHNS); + if ((regval & chbit) != 0) + { + /* There is an active DMA on this channel! */ + + return -EBUSY; + } + + /* 2. "Clear any pending interrupts on the channel to be used by writing + * to the DMACIntTCClear and DMACIntErrClear register. The previous + * channel operation might have left interrupt active. + */ + + putreg32(chbit, LPC17_DMA_INTTCCLR); + putreg32(chbit, LPC17_DMA_INTERRCLR); + + /* 3. "Write the source address into the DMACCxSrcAddr register. */ + + putreg32(srcaddr, base + LPC17_DMACH_SRCADDR_OFFSET); + + /* 4. "Write the destination address into the DMACCxDestAddr register. */ + + putreg32(destaddr, base + LPC17_DMACH_DESTADDR_OFFSET); + + /* 5. "Write the address of the next LLI into the DMACCxLLI register. If + * the transfer comprises of a single packet of data then 0 must be + * written into this register. + */ + + putreg32(0, base + LPC17_DMACH_LLI_OFFSET); + + /* 6. "Write the control information into the DMACCxControl register." + * + * The caller provides all CONTROL register fields except for the transfer + * size which is passed as a separate parameter and for the terminal count + * interrupt enable bit which is controlled by the driver. + */ + + regval = control & ~(DMACH_CONTROL_XFRSIZE_MASK | DMACH_CONTROL_I); + regval |= ((uint32_t)nxfrs << DMACH_CONTROL_XFRSIZE_SHIFT); + putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET); + + /* Save the number of transfer to perform for lpc17_dmastart */ + + dmach->nxfrs = (uint16_t)nxfrs; + + /* 7. "Write the channel configuration information into the DMACCxConfig + * register. If the enable bit is set then the DMA channel is + * automatically enabled." + * + * Only the SRCPER, DSTPER, and XFRTTYPE fields of the CONFIG register + * are provided by the caller. Little endian is assumed. + */ + + regval = config & (DMACH_CONFIG_SRCPER_MASK | DMACH_CONFIG_DSTPER_MASK | + DMACH_CONFIG_XFRTYPE_MASK); + putreg32(regval, base + LPC17_DMACH_CONFIG_OFFSET); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + uint32_t regval; + uint32_t chbit; + uint32_t base; + + DEBUGASSERT(dmach && dmach->inuse && callback); + + /* Save the callback information */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Increment the count of DMAs in-progress. This count will be + * decremented when lpc17_dmastop() is called, either by the user, + * indirectly via lpc17_dmafree(), or from gpdma_interrupt when the + * transfer completes. + */ + + lpc17_dmainprogress(dmach); + + /* Clear any pending DMA interrupts */ + + chbit = DMACH((uint32_t)dmach->chn); + putreg32(chbit, LPC17_DMA_INTTCCLR); + putreg32(chbit, LPC17_DMA_INTERRCLR); + + /* Enable terminal count interrupt. Note that we need to restore the + * number transfers. That is because the value has a different meaning + * when it is read. + */ + + base = LPC17_DMACH_BASE((uint32_t)dmach->chn); + regval = getreg32(base + LPC17_DMACH_CONTROL_OFFSET); + regval &= ~DMACH_CONTROL_XFRSIZE_MASK; + regval |= (DMACH_CONTROL_I | ((uint32_t)dmach->nxfrs << DMACH_CONTROL_XFRSIZE_SHIFT)); + putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET); + + /* Enable the channel and unmask terminal count and error interrupts. + * According to the user manual, zero masks and one unmasks (hence, + * these are really enables). + */ + + regval = getreg32(base + LPC17_DMACH_CONFIG_OFFSET); + regval |= (DMACH_CONFIG_E | DMACH_CONFIG_IE | DMACH_CONFIG_ITC); + putreg32(regval, base + LPC17_DMACH_CONFIG_OFFSET); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_dmastop + * + * Description: + * Cancel the DMA. After lpc17_dmastop() is called, the DMA channel is + * reset and lpc17_dmasetup() must be called before lpc17_dmastart() can be + * called again + * + * This function will be called either by the user directly, by the user + * indirectly via lpc17_dmafree(), or from gpdma_interrupt when the + * transfer completes. + * + ****************************************************************************/ + +void lpc17_dmastop(DMA_HANDLE handle) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + uint32_t regaddr; + uint32_t regval; + uint32_t chbit; + + DEBUGASSERT(dmach && dmach->inuse); + + /* Disable this channel and mask any further interrupts from the channel. + * this channel. The channel is disabled by clearning the channel + * enable bit. Any outstanding data in the FIFO’s is lost. + */ + + regaddr = LPC17_DMACH_CONFIG((uint32_t)dmach->chn); + regval = getreg32(regaddr); + regval &= ~(DMACH_CONFIG_E | DMACH_CONFIG_IE | DMACH_CONFIG_ITC); + putreg32(regval, regaddr); + + /* Clear any pending interrupts for this channel */ + + chbit = DMACH((uint32_t)dmach->chn); + putreg32(chbit, LPC17_DMA_INTTCCLR); + putreg32(chbit, LPC17_DMA_INTERRCLR); + + /* Decrement the count of DMAs in progress */ + + lpc17_dmadone(dmach); +} + +/**************************************************************************** + * Name: lpc17_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc17_dmasample(DMA_HANDLE handle, struct lpc17_dmaregs_s *regs) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + uint32_t base; + + DEBUGASSERT(dmach); + + /* Sample the global DMA registers */ + + regs->gbl.intst = getreg32(LPC17_DMA_INTST); + regs->gbl.inttcst = getreg32(LPC17_DMA_INTTCST); + regs->gbl.interrst = getreg32(LPC17_DMA_INTERRST); + regs->gbl.rawinttcst = getreg32(LPC17_DMA_RAWINTTCST); + regs->gbl.rawinterrst = getreg32(LPC17_DMA_RAWINTERRST); + regs->gbl.enbldchns = getreg32(LPC17_DMA_ENBLDCHNS); + regs->gbl.softbreq = getreg32(LPC17_DMA_SOFTBREQ); + regs->gbl.softsreq = getreg32(LPC17_DMA_SOFTSREQ); + regs->gbl.softlbreq = getreg32(LPC17_DMA_SOFTLBREQ); + regs->gbl.softlsreq = getreg32(LPC17_DMA_SOFTLSREQ); + regs->gbl.config = getreg32(LPC17_DMA_CONFIG); + regs->gbl.sync = getreg32(LPC17_DMA_SYNC); + + /* Sample the DMA channel registers */ + + base = LPC17_DMACH_BASE((uint32_t)dmach->chn); + regs->ch.srcaddr = getreg32(base + LPC17_DMACH_SRCADDR_OFFSET); + regs->ch.destaddr = getreg32(base + LPC17_DMACH_DESTADDR_OFFSET); + regs->ch.lli = getreg32(base + LPC17_DMACH_LLI_OFFSET); + regs->ch.control = getreg32(base + LPC17_DMACH_CONTROL_OFFSET); + regs->ch.config = getreg32(base + LPC17_DMACH_CONFIG_OFFSET); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: lpc17_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs, + const char *msg) +{ + struct lpc17_dmach_s *dmach = (DMA_HANDLE)handle; + uint32_t base; + + DEBUGASSERT(dmach); + + /* Dump the sampled global DMA registers */ + + dmadbg("Global GPDMA Registers: %s\n", msg); + dmadbg(" INTST[%08x]: %08x\n", + LPC17_DMA_INTST, regs->gbl.intst); + dmadbg(" INTTCST[%08x]: %08x\n", + LPC17_DMA_INTTCST, regs->gbl.inttcst); + dmadbg(" INTERRST[%08x]: %08x\n", + LPC17_DMA_INTERRST, regs->gbl.interrst); + dmadbg(" RAWINTTCST[%08x]: %08x\n", + LPC17_DMA_RAWINTTCST, regs->gbl.rawinttcst); + dmadbg(" RAWINTERRST[%08x]: %08x\n", + LPC17_DMA_RAWINTERRST, regs->gbl.rawinterrst); + dmadbg(" ENBLDCHNS[%08x]: %08x\n", + LPC17_DMA_ENBLDCHNS, regs->gbl.enbldchns); + dmadbg(" SOFTBREQ[%08x]: %08x\n", + LPC17_DMA_SOFTBREQ, regs->gbl.softbreq); + dmadbg(" SOFTSREQ[%08x]: %08x\n", + LPC17_DMA_SOFTSREQ, regs->gbl.softsreq); + dmadbg(" SOFTLBREQ[%08x]: %08x\n", + LPC17_DMA_SOFTLBREQ, regs->gbl.softlbreq); + dmadbg(" SOFTLSREQ[%08x]: %08x\n", + LPC17_DMA_SOFTLSREQ, regs->gbl.softlsreq); + dmadbg(" CONFIG[%08x]: %08x\n", + LPC17_DMA_CONFIG, regs->gbl.config); + dmadbg(" SYNC[%08x]: %08x\n", + LPC17_DMA_SYNC, regs->gbl.sync); + + /* Dump the DMA channel registers */ + + base = LPC17_DMACH_BASE((uint32_t)dmach->chn); + + dmadbg("Channel GPDMA Registers: %d\n", dmach->chn); + + dmadbg(" SRCADDR[%08x]: %08x\n", + base + LPC17_DMACH_SRCADDR_OFFSET, regs->ch.srcaddr); + dmadbg(" DESTADDR[%08x]: %08x\n", + base + LPC17_DMACH_DESTADDR_OFFSET, regs->ch.destaddr); + dmadbg(" LLI[%08x]: %08x\n", + base + LPC17_DMACH_LLI_OFFSET, regs->ch.lli); + dmadbg(" CONTROL[%08x]: %08x\n", + base + LPC17_DMACH_CONTROL_OFFSET, regs->ch.control); + dmadbg(" CONFIG[%08x]: %08x\n", + base + LPC17_DMACH_CONFIG_OFFSET, regs->ch.config); +} +#endif /* CONFIG_DEBUG_DMA */ + +#endif /* CONFIG_LPC17_GPDMA */ diff --git a/arch/arm/src/lpc17xx/lpc17_gpdma.h b/arch/arm/src/lpc17xx/lpc17_gpdma.h new file mode 100644 index 0000000000000000000000000000000000000000..4e1e499eb1c5e220e6083f40fe011e703c840ab1 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpdma.h @@ -0,0 +1,270 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_gpdma.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_GPDMA_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_GPDMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc17_gpdma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef CONFIG_LPC17_GPDMA +/* DMA_HANDLE is an opaque reference to an allocated DMA channel */ + +typedef FAR void *DMA_HANDLE; + +/* dma_callback_t a function pointer provided to lpc17_dmastart. This + * function is called at the completion of the DMA transfer. 'arg' is the + * same 'arg' value that was provided when lpc17_dmastart() was called and + * result indicates the result of the transfer: Zero indicates a successful + * transfers. On failure, a negated errno is returned indicating the general + * nature of the DMA faiure. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct lpc17_dmaglobalregs_s +{ + /* Global Registers */ + + uint32_t intst; /* DMA Interrupt Status Register */ + uint32_t inttcst; /* DMA Interrupt Terminal Count Request Status Register */ + uint32_t interrst; /* DMA Interrupt Error Status Register */ + uint32_t rawinttcst; /* DMA Raw Interrupt Terminal Count Status Register */ + uint32_t rawinterrst; /* DMA Raw Error Interrupt Status Register */ + uint32_t enbldchns; /* DMA Enabled Channel Register */ + uint32_t softbreq; /* DMA Software Burst Request Register */ + uint32_t softsreq; /* DMA Software Single Request Register */ + uint32_t softlbreq; /* DMA Software Last Burst Request Register */ + uint32_t softlsreq; /* DMA Software Last Single Request Register */ + uint32_t config; /* DMA Configuration Register */ + uint32_t sync; /* DMA Synchronization Register */ +}; + +struct lpc17_dmachanregs_s +{ + /* Channel Registers */ + + uint32_t srcaddr; /* DMA Channel Source Address Register */ + uint32_t destaddr; /* DMA Channel Destination Address Register */ + uint32_t lli; /* DMA Channel Linked List Item Register */ + uint32_t control; /* DMA Channel Control Register */ + uint32_t config; /* DMA Channel Configuration Register */ +}; + +struct lpc17_dmaregs_s +{ + /* Global Registers */ + + struct lpc17_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct lpc17_dmachanregs_s ch; +}; + +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* If the following value is zero, then there is no DMA in progress. This + * value is needed in the IDLE loop to determine if the IDLE loop should + * go into lower power power consumption modes. According to the LPC17xx + * User Manual: "The DMA controller can continue to work in Sleep mode, and + * has access to the peripheral SRAMs and all peripheral registers. The + * flash memory and the Main SRAM are not available in Sleep mode, they are + * disabled in order to save power." + */ + +EXTERN volatile uint8_t g_dma_inprogress; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem (also prototyped in up_internal.h). + * + * Returned Value: + * Zero on success; A negated errno value on failure. + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void); + +/**************************************************************************** + * Name: lpc17_dmaconfigure + * + * Description: + * Configure a DMA request. Each DMA request may have two different DMA + * request sources. This associates one of the sources with a DMA request. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc17_dmaconfigure(uint8_t dmarequest, bool alternate); + +/**************************************************************************** + * Name: lpc17_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +DMA_HANDLE lpc17_dmachannel(void); + +/**************************************************************************** + * Name: lpc17_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until lpc17_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc17_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: lpc17_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +int lpc17_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nxfrs); + +/**************************************************************************** + * Name: lpc17_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: lpc17_dmastop + * + * Description: + * Cancel the DMA. After lpc17_dmastop() is called, the DMA channel is + * reset and lpc17_dmasetup() must be called before lpc17_dmastart() can be + * called again + * + ****************************************************************************/ + +void lpc17_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: lpc17_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc17_dmasample(DMA_HANDLE handle, struct lpc17_dmaregs_s *regs); +#else +# define lpc17_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: lpc17_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs, + const char *msg); +#else +# define lpc17_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC17_GPDMA */ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_GPDMA_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_gpio.c b/arch/arm/src/lpc17xx/lpc17_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..34f0aefcd6a93ac6558d9c1db99b95ec3aaa1c83 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpio.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_gpio.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * With LPC178x extensions from Rommel Marcelo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* This file is only a thin shell that includes the correct GPIO logic for + * the selected LPC17xx family. The correct file cannot be selected by the + * make system because it needs the intelligence that only exists in chip.h + * that can associate an LPC17xx part number with an LPC17xx family. + */ + +#include + +#if defined(LPC176x) +# include "lpc176x_gpio.c" +#elif defined(LPC178x) +# include "lpc178x_gpio.c" +#else +# error "Unrecognized LPC17xx family" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/lpc17xx/lpc17_gpio.h b/arch/arm/src/lpc17xx/lpc17_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..e8ec13378992886ae53292bf0862d14e27274d23 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpio.h @@ -0,0 +1,195 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_gpio.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_GPIO_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip/lpc17_gpio.h" +#include "chip/lpc17_pinconn.h" +#include "chip/lpc17_pinconfig.h" + +/* Include the GPIO definitions for the selected LPC17xx family. */ + +#if defined(LPC176x) +# include "lpc176x_gpio.h" +#elif defined(LPC178x) +# include "lpc178x_gpio.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* These tables have global scope only because they are shared between lpc17_gpio.c, + * lpc17_gpioint.c, and lpc17_gpiodbg.c + */ + +#ifdef CONFIG_GPIO_IRQ +EXTERN uint64_t g_intedge0; +EXTERN uint64_t g_intedge2; +#endif + +EXTERN const uint32_t g_fiobase[GPIO_NPORTS]; +EXTERN const uint32_t g_intbase[GPIO_NPORTS]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: lpc17_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc17_gpioirqinitialize(void); +#else +# define lpc17_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: lpc17_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int lpc17_configgpio(lpc17_pinset_t cfgset); + +/************************************************************************************ + * Name: lpc17_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void lpc17_gpiowrite(lpc17_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: lpc17_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool lpc17_gpioread(lpc17_pinset_t pinset); + +/************************************************************************************ + * Name: lpc17_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc17_gpioirqenable(int irq); +#else +# define lpc17_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: lpc17_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void lpc17_gpioirqdisable(int irq); +#else +# define lpc17_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: lpc17_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int lpc17_dumpgpio(lpc17_pinset_t pinset, const char *msg); +#else +# define lpc17_dumpgpio(p,m) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_GPIO_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_gpiodbg.c b/arch/arm/src/lpc17xx/lpc17_gpiodbg.c new file mode 100644 index 0000000000000000000000000000000000000000..fc6ce33162bee1d163bfc36700c33bd38b848b74 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpiodbg.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_gpiodbg.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc17_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#ifdef CONFIG_DEBUG_GPIO + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_pinsel + * + * Description: + * Get the address of the PINSEL register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +#ifdef LPC176x +static uint32_t lpc17_pinsel(unsigned int port, unsigned int pin) +{ + if (pin < 16) + { + return g_lopinsel[port]; + } + else + { + return g_hipinsel[port]; + } +} +#endif /* LPC176x */ + +/**************************************************************************** + * Name: lpc17_pinmode + * + * Description: + * Get the address of the PINMODE register corresponding to this port and + * pin number. + * + ****************************************************************************/ + +#ifdef LPC176x +static uint32_t lpc17_pinmode(unsigned int port, unsigned int pin) +{ + if (pin < 16) + { + return g_lopinmode[port]; + } + else + { + return g_hipinmode[port]; + } +} +#endif /* LPC176x */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: lpc17_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int lpc17_dumpgpio(lpc17_pinset_t pinset, const char *msg) +{ + irqstate_t flags; + uint32_t base; +#if defined(LPC176x) + uint32_t pinsel; + uint32_t pinmode; +#elif defined(LPC178x) + uint32_t iocon; +#endif /* LPC176x */ + unsigned int port; + unsigned int pin; + + /* Get the base address associated with the GPIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + +#if defined(LPC176x) + pinsel = lpc17_pinsel(port, pin); + pinmode = lpc17_pinmode(port, pin); +#elif defined(LPC178x) + iocon = LPC17_IOCON_P(port, pin); +#endif /* LPC176x */ + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + lldbg("GPIO%c pin%d (pinset: %08x) -- %s\n", + port + '0', pin, pinset, msg); + +#if defined(LPC176x) + lldbg(" PINSEL[%08x]: %08x PINMODE[%08x]: %08x ODMODE[%08x]: %08x\n", + pinsel, pinsel ? getreg32(pinsel) : 0, + pinmode, pinmode ? getreg32(pinmode) : 0, + g_odmode[port], getreg32(g_odmode[port])); +#elif defined(LPC178x) + lldbg(" IOCON[%08x]: %08x\n", iocon, getreg32(iocon)); +#endif + + base = g_fiobase[port]; + lldbg(" FIODIR[%08x]: %08x FIOMASK[%08x]: %08x FIOPIN[%08x]: %08x\n", + base+LPC17_FIO_DIR_OFFSET, getreg32(base+LPC17_FIO_DIR_OFFSET), + base+LPC17_FIO_MASK_OFFSET, getreg32(base+LPC17_FIO_MASK_OFFSET), + base+LPC17_FIO_PIN_OFFSET, getreg32(base+LPC17_FIO_PIN_OFFSET)); + + base = g_intbase[port]; + lldbg(" IOINTSTATUS[%08x]: %08x INTSTATR[%08x]: %08x INSTATF[%08x]: %08x\n", + LPC17_GPIOINT_IOINTSTATUS, getreg32(LPC17_GPIOINT_IOINTSTATUS), + base+LPC17_GPIOINT_INTSTATR_OFFSET, getreg32(base+LPC17_GPIOINT_INTSTATR_OFFSET), + base+LPC17_GPIOINT_INTSTATF_OFFSET, getreg32(base+LPC17_GPIOINT_INTSTATF_OFFSET)); + lldbg(" INTENR[%08x]: %08x INTENF[%08x]: %08x\n", + base+LPC17_GPIOINT_INTENR_OFFSET, getreg32(base+LPC17_GPIOINT_INTENR_OFFSET), + base+LPC17_GPIOINT_INTENF_OFFSET, getreg32(base+LPC17_GPIOINT_INTENF_OFFSET)); + leave_critical_section(flags); + return OK; +} +#endif /* CONFIG_DEBUG_GPIO */ + diff --git a/arch/arm/src/lpc17xx/lpc17_gpioint.c b/arch/arm/src/lpc17xx/lpc17_gpioint.c new file mode 100644 index 0000000000000000000000000000000000000000..46acb05e6fa41ed16932e1b230f216fa449f0d0c --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_gpioint.c @@ -0,0 +1,546 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_gpioint.c + * + * Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "lpc17_gpio.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_getintedge + * + * Description: + * Get the stored interrupt edge configuration. + * + ****************************************************************************/ + +static unsigned int lpc17_getintedge(unsigned int port, unsigned int pin) +{ + uint64_t *intedge; + + /* Which word to we use? */ + + if (port == 0) + { + intedge = &g_intedge0; + } + else if (port == 2) + { + intedge = &g_intedge2; + } + else + { + return 0; + } + + /* Return the value for the PINSEL */ + + return (unsigned int)(((*intedge) >> (pin << 1)) & 3); +} + +/**************************************************************************** + * Name: lpc17_setintedge + * + * Description: + * Set the edge interrupt enabled bits for this pin. + * + ****************************************************************************/ + +static void lpc17_setintedge(uint32_t intbase, unsigned int pin, + unsigned int edges) +{ + irqstate_t flags; + int regval; + + /* These must be atomic */ + + flags = enter_critical_section(); + + /* Set/clear the rising edge enable bit */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET); + if ((edges & 2) != 0) + { + regval |= GPIOINT(pin); + } + else + { + regval &= ~GPIOINT(pin); + } + + putreg32(regval, intbase + LPC17_GPIOINT_INTENR_OFFSET); + + /* Set/clear the falling edge enable bit */ + + regval = getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET); + if ((edges & 1) != 0) + { + regval |= GPIOINT(pin); + } + else + { + regval &= ~GPIOINT(pin); + } + + putreg32(regval, intbase + LPC17_GPIOINT_INTENF_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_irq2port + * + * Description: + * Given an IRQ number, return the GPIO port number (0 or 2) of the interrupt. + * + ****************************************************************************/ + +static int lpc17_irq2port(int irq) +{ + /* Set 1: + * LPC176x: 12 interrupts p0.0-p0.11 + * LPC178x: 16 interrupts p0.0-p0.15 + */ + + if (irq >= LPC17_VALID_FIRST0L && + irq < (LPC17_VALID_FIRST0L + LPC17_VALID_NIRQS0L)) + { + return 0; + } + + /* Set 2: + * LPC176x: 16 interrupts p0.15-p0.30 + * LPC178x: 16 interrupts p0.16-p0.31 + */ + + else if (irq >= LPC17_VALID_FIRST0H && + irq < (LPC17_VALID_FIRST0H + LPC17_VALID_NIRQS0H)) + { + return 0; + } + +#if defined (LPC176x) + /* Set 3: + * LPC17x: 14 interrupts p2.0-p2.13 + */ + + else if (irq >= LPC17_VALID_FIRST2 && + irq < (LPC17_VALID_FIRST2 + LPC17_VALID_NIRQS2)) + { + return 2; + } + +#elif defined (LPC178x) + /* Set 3: + * LPC18x: 16 interrupts p2.0-p2.15 + */ + + else if (irq >= LPC17_VALID_FIRST2L && + irq < (LPC17_VALID_FIRST2L + LPC17_VALID_NIRQS2L)) + { + return 2; + } + + /* Set 4: + * LPC178x: 16 interrupts p2.16-p2.31 + */ + + else if (irq >= LPC17_VALID_FIRST2H && + irq < (LPC17_VALID_FIRST2H + LPC17_VALID_NIRQS2H)) + { + return 2; + } + +#endif + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_irq2pin + * + * Description: + * Given an IRQ number, return the GPIO pin number (0..31) of the interrupt. + * + ****************************************************************************/ + +static int lpc17_irq2pin(int irq) +{ + /* Set 1: + * LPC17x: 12 interrupts p0.0-p0.11 + * LPC18x: 16 interrupts p0.0-p0.15 + * + * See arch/arm/include/lpc17xx/irq.h: + * LPC17_VALID_SHIFT0L 0 - Bit 0 is thre first bit in the group of + * 12/16 interrupts + * LPC17_VALID_FIRST0L irq - IRQ number associated with p0.0 + * LPC17_VALID_NIRQS0L 12/16 - Number of interrupt bits in the group + */ + + if (irq >= LPC17_VALID_FIRST0L && + irq < (LPC17_VALID_FIRST0L + LPC17_VALID_NIRQS0L)) + { + return irq - LPC17_VALID_FIRST0L + LPC17_VALID_SHIFT0L; + } + + /* Set 2: + * LPC176x: 16 interrupts p0.15-p0.30 + * LPC178x: 16 interrupts p0.16-p0.31 + * + * LPC17_VALID_SHIFT0H 15/16 - Bit number of the first bit in a group + * of 16 interrupts + * LPC17_VALID_FIRST0L irq - IRQ number associated with p0.15/16 + * LPC17_VALID_NIRQS0L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC17_VALID_FIRST0H && + irq < (LPC17_VALID_FIRST0H + LPC17_VALID_NIRQS0H)) + { + return irq - LPC17_VALID_FIRST0H + LPC17_VALID_SHIFT0H; + } + +#if defined(LPC176x) + /* Set 3: + * LPC17x: 14 interrupts p2.0-p2.13 + * + * LPC17_VALID_SHIFT2 0 - Bit 0 is the first bit in a group of 14 + * interrupts + * LPC17_VALID_FIRST2 irq - IRQ number associated with p2.0 + * LPC17_VALID_NIRQS2 14 - 14 interrupt bits in the group + */ + + else if (irq >= LPC17_VALID_FIRST2 && + irq < (LPC17_VALID_FIRST2 + LPC17_VALID_NIRQS2)) + { + return irq - LPC17_VALID_FIRST2 + LPC17_VALID_SHIFT2; + } + +#elif defined(LPC178x) + + /* Set 3: + * LPC18x: 16 interrupts p2.0-p2.15 + * + * LPC17_VALID_SHIFT2L 0 - Bit 0 is the first bit in a group of 16 + * interrupts + * LPC17_VALID_FIRST2L irq - IRQ number associated with p2.0 + * LPC17_VALID_NIRQS2L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC17_VALID_FIRST2L && + irq < (LPC17_VALID_FIRST2L + LPC17_VALID_NIRQS2L)) + { + return irq - LPC17_VALID_FIRST2L + LPC17_VALID_SHIFT2L; + } + + /* Set 3: + * LPC18x: 16 interrupts p2.16-p2.31 + * + * LPC17_VALID_SHIFT2L 16 - Bit 16 is the first bit in a group of 16 + * interrupts + * LPC17_VALID_FIRST2L irq - IRQ number associated with p2.0 + * LPC17_VALID_NIRQS2L 16 - 16 interrupt bits in the group + */ + + else if (irq >= LPC17_VALID_FIRST2H && + irq < (LPC17_VALID_FIRST2H + LPC17_VALID_NIRQS2H)) + { + return irq - LPC17_VALID_FIRST2H + LPC17_VALID_SHIFT2H; + } + +#endif + + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_gpiodemux + * + * Description: + * Demux all interrupts on one GPIO interrupt status register. + * + ****************************************************************************/ + +static void lpc17_gpiodemux(uint32_t intbase, uint32_t intmask, + int irqbase, void *context) +{ + uint32_t intstatr; + uint32_t intstatf; + uint32_t intstatus; + uint32_t bit; + int irq; + + /* Get the interrupt rising and falling edge status and mask out only the + * interrupts that are enabled. + */ + + intstatr = getreg32(intbase + LPC17_GPIOINT_INTSTATR_OFFSET); + intstatr &= getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET); + + intstatf = getreg32(intbase + LPC17_GPIOINT_INTSTATF_OFFSET); + intstatf &= getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET); + + /* And get the OR of the enabled interrupt sources. We do not make any + * distinction between rising and falling edges (but the hardware does support + * the ability to handle them differently if needed). + */ + + intstatus = intstatr | intstatf; + + /* Now march through the (valid) bits and dispatch each interrupt */ + + irq = irqbase; + bit = 1; + while (intstatus != 0) + { + /* Does this pin support an interrupt? If no, skip over it WITHOUT + * incrementing irq. + */ + + if ((intmask & bit) != 0) + { + /* This pin can support an interrupt. Is there an interrupt pending + * and enabled? + */ + + if ((intstatus & bit) != 0) + { + /* Clear the interrupt status */ + + putreg32(bit, intbase + LPC17_GPIOINT_INTCLR_OFFSET); + + /* And dispatch the interrupt */ + + irq_dispatch(irq, context); + } + + /* Increment the IRQ number on each interrupt pin */ + + irq++; + } + + /* Next bit */ + + intstatus &= ~bit; + bit <<= 1; + } +} + +/**************************************************************************** + * Name: lpc17_gpiointerrupt + * + * Description: + * Handle the GPIO interrupt. For the LPC176x family, that interrupt could + * also that also indicates that an EINT3 interrupt has occurred. NOTE: + * This logic would have to be extended if EINT3 is actually used for + * External Interrupt 3 on an LPC176x platform. + * + ****************************************************************************/ + +static int lpc17_gpiointerrupt(int irq, void *context) +{ + /* Get the GPIO interrupt status */ + + uint32_t intstatus = getreg32(LPC17_GPIOINT_IOINTSTATUS); + + /* Check for an interrupt on GPIO0 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P0INT) != 0) + { + lpc17_gpiodemux(LPC17_GPIOINT0_BASE, LPC17_VALID_GPIOINT0, + LPC17_VALID_FIRST0L, context); + } + +#if defined(LPC176x) + /* Check for an interrupt on GPIO2 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P2INT) != 0) + { + lpc17_gpiodemux(LPC17_GPIOINT2_BASE, LPC17_VALID_GPIOINT2, + LPC17_VALID_FIRST2, context); + } + +#elif defined(LPC178x) + /* Check for an interrupt on GPIO2 */ + + if ((intstatus & GPIOINT_IOINTSTATUS_P2INT) != 0) + { + lpc17_gpiodemux(LPC17_GPIOINT2_BASE, LPC17_VALID_GPIOINT2, + LPC17_VALID_FIRST2L, context); + } + +#endif + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void lpc17_gpioirqinitialize(void) +{ + /* Disable all GPIO interrupts */ + + putreg32(0, LPC17_GPIOINT0_INTENR); + putreg32(0, LPC17_GPIOINT0_INTENF); + putreg32(0, LPC17_GPIOINT2_INTENR); + putreg32(0, LPC17_GPIOINT2_INTENF); + + /* Attach and enable the GPIO IRQ. */ + +#if defined(LPC176x) + /* For the LPC176x family, GPIO0 and GPIO2 interrupts share the same + * position in the NVIC with External Interrupt 3 + */ + + (void)irq_attach(LPC17_IRQ_EINT3, lpc17_gpiointerrupt); + up_enable_irq(LPC17_IRQ_EINT3); + +#elif defined(LPC178x) + /* the LPC178x family has a single, dedicated interrupt for GPIO0 and + * GPIO2. + */ + + (void)irq_attach(LPC17_IRQ_GPIO, lpc17_gpiointerrupt); + up_enable_irq(LPC17_IRQ_GPIO); + +#endif +} + +/**************************************************************************** + * Name: lpc17_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void lpc17_gpioirqenable(int irq) +{ + /* Map the IRQ number to a port number */ + + int port = lpc17_irq2port(irq); + if (port >= 0) + { + /* The IRQ number does correspond to an interrupt port. Now get the base + * address of the GPIOINT registers for the port. + */ + + uint32_t intbase = g_intbase[port]; + if (intbase != 0) + { + /* And get the pin number associated with the port */ + + unsigned int pin = lpc17_irq2pin(irq); + unsigned int edges = lpc17_getintedge(port, pin); + lpc17_setintedge(intbase, pin, edges); + } + } +} + +/**************************************************************************** + * Name: lpc17_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void lpc17_gpioirqdisable(int irq) +{ + /* Map the IRQ number to a port number */ + + int port = lpc17_irq2port(irq); + if (port >= 0) + { + /* The IRQ number does correspond to an interrupt port. Now get the base + * address of the GPIOINT registers for the port. + */ + + uint32_t intbase = g_intbase[port]; + if (intbase != 0) + { + /* And get the pin number associated with the port */ + + unsigned int pin = lpc17_irq2pin(irq); + lpc17_setintedge(intbase, pin, 0); + } + } +} + +#endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/arm/src/lpc17xx/lpc17_i2c.c b/arch/arm/src/lpc17xx/lpc17_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..9b106fdda4e813e2c237fdb1f4f491befa1fc228 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_i2c.c @@ -0,0 +1,650 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_i2c.c + * + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi (Original author) + * + * Derived from arch/arm/src/lpc31xx/lpc31_i2c.c + * + * Author: David Hewson + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_i2c.h" + +#if defined(CONFIG_LPC17_I2C0) || defined(CONFIG_LPC17_I2C1) || defined(CONFIG_LPC17_I2C2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef GPIO_I2C1_SCL +# define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 +# define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 +#endif + +#ifndef CONFIG_LPC17_I2C0_FREQUENCY +# define CONFIG_LPC17_I2C0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC17_I2C1_FREQUENCY +# define CONFIG_LPC17_I2C1_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC17_I2C2_FREQUENCY +# define CONFIG_LPC17_I2C2_FREQUENCY 100000 +#endif + +#define I2C_TIMEOUT (20 * 1000/CONFIG_USEC_PER_TICK) /* 20 mS */ +#define LPC17_I2C1_FREQUENCY 400000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct lpc17_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* Watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ + unsigned int nmsg; /* number of transfer remaining */ + + uint16_t wrcnt; /* number of bytes sent to tx fifo */ + uint16_t rdcnt; /* number of bytes read from rx fifo */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int lpc17_i2c_start(struct lpc17_i2cdev_s *priv); +static void lpc17_i2c_stop(struct lpc17_i2cdev_s *priv); +static int lpc17_i2c_interrupt(int irq, FAR void *context); +static void lpc17_i2c_timeout(int argc, uint32_t arg, ...); +static void lpc17_i2c_setfrequency(struct lpc17_i2cdev_s *priv, + uint32_t frequency); +static void lpc17_stopnext(struct lpc17_i2cdev_s *priv); + +/* I2C device operations */ + +static int lpc17_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int lpc17_i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC17_I2C0 +static struct lpc17_i2cdev_s g_i2c0dev; +#endif +#ifdef CONFIG_LPC17_I2C1 +static struct lpc17_i2cdev_s g_i2c1dev; +#endif +#ifdef CONFIG_LPC17_I2C2 +static struct lpc17_i2cdev_s g_i2c2dev; +#endif + +struct i2c_ops_s lpc17_i2c_ops = +{ + .transfer = lpc17_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = lpc17_i2c_reset +#endif +}; + +/**************************************************************************** + * Name: lpc17_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void lpc17_i2c_setfrequency(struct lpc17_i2cdev_s *priv, + uint32_t frequency) +{ + if (frequency != priv->frequency) + { + if (frequency > 100000) + { + /* Asymetric per 400Khz I2C spec */ + + putreg32(LPC17_CCLK / (83 + 47) * 47 / frequency, + priv->base + LPC17_I2C_SCLH_OFFSET); + putreg32(LPC17_CCLK / (83 + 47) * 83 / frequency, + priv->base + LPC17_I2C_SCLL_OFFSET); + } + else + { + /* 50/50 mark space ratio */ + + putreg32(LPC17_CCLK / 100 * 50 / frequency, + priv->base + LPC17_I2C_SCLH_OFFSET); + putreg32(LPC17_CCLK / 100 * 50 / frequency, + priv->base + LPC17_I2C_SCLL_OFFSET); + } + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: lpc17_i2c_start + * + * Description: + * Perform a I2C transfer start + * + ****************************************************************************/ + +static int lpc17_i2c_start(struct lpc17_i2cdev_s *priv) +{ + putreg32(I2C_CONCLR_STAC | I2C_CONCLR_SIC, + priv->base + LPC17_I2C_CONCLR_OFFSET); + putreg32(I2C_CONSET_STA, priv->base + LPC17_I2C_CONSET_OFFSET); + + wd_start(priv->timeout, I2C_TIMEOUT, lpc17_i2c_timeout, 1, (uint32_t)priv); + sem_wait(&priv->wait); + + wd_cancel(priv->timeout); + + return priv->nmsg; +} + +/**************************************************************************** + * Name: lpc17_i2c_stop + * + * Description: + * Perform a I2C transfer stop + * + ****************************************************************************/ + +static void lpc17_i2c_stop(struct lpc17_i2cdev_s *priv) +{ + if (priv->state != 0x38) + { + putreg32(I2C_CONSET_STO | I2C_CONSET_AA, + priv->base + LPC17_I2C_CONSET_OFFSET); + } + + sem_post(&priv->wait); +} + +/**************************************************************************** + * Name: lpc17_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void lpc17_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *)arg; + + irqstate_t flags = enter_critical_section(); + priv->state = 0xff; + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int lpc17_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *)dev; + int ret; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Set up for the transfer */ + + priv->wrcnt = 0; + priv->rdcnt = 0; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + lpc17_i2c_setfrequency(priv, msgs->frequency); + + /* Perform the transfer */ + + ret = lpc17_i2c_start(priv); + + sem_post(&priv->mutex); + return ret; +} + +/**************************************************************************** + * Name: lpc17_i2c_interrupt + * + * Description: + * Check if we need to issue STOP at the next message + * + ****************************************************************************/ + +static void lpc17_stopnext(struct lpc17_i2cdev_s *priv) +{ + priv->nmsg--; + + if (priv->nmsg > 0) + { + priv->msgs++; + putreg32(I2C_CONSET_STA, priv->base + LPC17_I2C_CONSET_OFFSET); + } + else + { + lpc17_i2c_stop(priv); + } +} + +/**************************************************************************** + * Name: lpc17_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int lpc17_i2c_interrupt(int irq, FAR void *context) +{ + struct lpc17_i2cdev_s *priv; + struct i2c_msg_s *msg; + uint32_t state; + +#ifdef CONFIG_LPC17_I2C0 + if (irq == LPC17_IRQ_I2C0) + { + priv = &g_i2c0dev; + } + else +#endif +#ifdef CONFIG_LPC17_I2C1 + if (irq == LPC17_IRQ_I2C1) + { + priv = &g_i2c1dev; + } + else +#endif +#ifdef CONFIG_LPC17_I2C2 + if (irq == LPC17_IRQ_I2C2) + { + priv = &g_i2c2dev; + } + else +#endif + { + PANIC(); + } + + /* Reference UM10360 19.10.5 */ + + state = getreg32(priv->base + LPC17_I2C_STAT_OFFSET); + msg = priv->msgs; + + priv->state = state; + state &= 0xf8; /* state mask, only 0xX8 is possible */ + switch (state) + { + + case 0x08: /* A START condition has been transmitted. */ + case 0x10: /* A Repeated START condition has been transmitted. */ + /* Set address */ + + putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ) ? + I2C_READADDR8(msg->addr) : + I2C_WRITEADDR8(msg->addr), priv->base + LPC17_I2C_DAT_OFFSET); + + /* Clear start bit */ + + putreg32(I2C_CONCLR_STAC, priv->base + LPC17_I2C_CONCLR_OFFSET); + break; + + /* Write cases */ + + case 0x18: /* SLA+W has been transmitted; ACK has been received */ + priv->wrcnt = 0; + putreg32(msg->buffer[0], priv->base + LPC17_I2C_DAT_OFFSET); /* put first byte */ + break; + + case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */ + priv->wrcnt++; + + if (priv->wrcnt < msg->length) + { + putreg32(msg->buffer[priv->wrcnt], priv->base + LPC17_I2C_DAT_OFFSET); /* Put next byte */ + } + else + { + lpc17_stopnext(priv); + } + break; + + /* Read cases */ + + case 0x40: /* SLA+R has been transmitted; ACK has been received */ + priv->rdcnt = 0; + if (msg->length > 1) + { + putreg32(I2C_CONSET_AA, priv->base + LPC17_I2C_CONSET_OFFSET); /* Set ACK next read */ + } + else + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC17_I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */ + } + break; + + case 0x50: /* Data byte has been received; ACK has been returned. */ + priv->rdcnt++; + msg->buffer[priv->rdcnt - 1] = getreg32(priv->base + LPC17_I2C_BUFR_OFFSET); + + if (priv->rdcnt >= (msg->length - 1)) + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC17_I2C_CONCLR_OFFSET); /* Do not ACK any more */ + } + break; + + case 0x58: /* Data byte has been received; NACK has been returned. */ + msg->buffer[priv->rdcnt] = getreg32(priv->base + LPC17_I2C_BUFR_OFFSET); + lpc17_stopnext(priv); + break; + + default: + lpc17_i2c_stop(priv); + break; + } + + putreg32(I2C_CONCLR_SIC, priv->base + LPC17_I2C_CONCLR_OFFSET); /* clear interrupt */ + + return OK; +} + +/************************************************************************************ + * Name: lpc17_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int lpc17_i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc17_i2cbus_initialize(int port) +{ + struct lpc17_i2cdev_s *priv; + + if (port > 1) + { + dbg("lpc I2C Only support 0,1\n"); + return NULL; + } + + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + +#ifdef CONFIG_LPC17_I2C0 + if (port == 0) + { + priv = &g_i2c0dev; + priv->base = LPC17_I2C0_BASE; + priv->irqid = LPC17_IRQ_I2C0; + + /* Enable clocking */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCI2C0; + putreg32(regval, LPC17_SYSCON_PCONP); + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_I2C0_MASK; + regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL0_I2C0_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + /* Pin configuration */ + + lpc17_configgpio(GPIO_I2C0_SCL); + lpc17_configgpio(GPIO_I2C0_SDA); + + /* Set default frequency */ + + lpc17_i2c_setfrequency(priv, CONFIG_LPC17_I2C0_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC17_I2C1 + if (port == 1) + { + priv = &g_i2c1dev; + priv->base = LPC17_I2C1_BASE; + priv->irqid = LPC17_IRQ_I2C1; + + /* Enable clocking */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCI2C1; + putreg32(regval, LPC17_SYSCON_PCONP); + + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_I2C1_MASK; + regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C1_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL1); + + /* Pin configuration */ + + lpc17_configgpio(GPIO_I2C1_SCL); + lpc17_configgpio(GPIO_I2C1_SDA); + + /* Set default frequency */ + + lpc17_i2c_setfrequency(priv, CONFIG_LPC17_I2C1_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC17_I2C2 + if (port == 2) + { + priv = &g_i2c2dev; + priv->base = LPC17_I2C2_BASE; + priv->irqid = LPC17_IRQ_I2C2; + + /* Enable clocking */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCI2C2; + putreg32(regval, LPC17_SYSCON_PCONP); + + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_I2C2_MASK; + regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C2_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL1); + + /* Pin configuration */ + + lpc17_configgpio(GPIO_I2C2_SCL); + lpc17_configgpio(GPIO_I2C2_SDA); + + /* Set default frequency */ + + lpc17_i2c_setfrequency(priv, CONFIG_LPC17_I2C2_FREQUENCY); + } + else +#endif + { + return NULL; + } + + leave_critical_section(flags); + + putreg32(I2C_CONSET_I2EN, priv->base + LPC17_I2C_CONSET_OFFSET); + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, lpc17_i2c_interrupt); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc17_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc17_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc17_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev; + + /* Disable I2C */ + + putreg32(I2C_CONCLRT_I2ENC, priv->base + LPC17_I2C_CONCLR_OFFSET); + + /* Reset data structures */ + + sem_destroy(&priv->mutex); + sem_destroy(&priv->wait); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Disable interrupts */ + + up_disable_irq(priv->irqid); + + /* Detach Interrupt Handler */ + + irq_detach(priv->irqid); + return OK; +} + +#endif /* CONFIG_LPC17_I2C0 || CONFIG_LPC17_I2C1 || CONFIG_LPC17_I2C2 */ diff --git a/arch/arm/src/lpc17xx/lpc17_i2c.h b/arch/arm/src/lpc17xx/lpc17_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..a7a6322461940cbcc88af415d024d38f12a82437 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_i2c.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_i2c.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_I2C_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc17_i2c.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *lpc17_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: lpc17_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc17_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int lpc17_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_I2C_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_i2s.h b/arch/arm/src/lpc17xx/lpc17_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..f6cbe0677511372d2cf94634249a16c674286275 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_i2s.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_i2s.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H +#define __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc17_i2s.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_CHIP_LPC17_I2S_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_idle.c b/arch/arm/src/lpc17xx/lpc17_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..71d940a6ab557c463999c36e8db3bd32db63f08e --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_idle.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/lpc17/lpc17_idle.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "lpc17_gpdma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + +/* If the g_dma_inprogress is zero, then there is no DMA in progress. This + * value is needed in the IDLE loop to determine if the IDLE loop should + * go into lower power power consumption modes. According to the LPC17xx + * User Manual: "The DMA controller can continue to work in Sleep mode, and + * has access to the peripheral SRAMs and all peripheral registers. The + * flash memory and the Main SRAM are not available in Sleep mode, they are + * disabled in order to save power." + */ + +#ifdef CONFIG_LPC17_GPDMA + if (g_dma_inprogress == 0) +#endif + { + /* Sleep until an interrupt occurs in order to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); + } +#endif +} + diff --git a/arch/arm/src/lpc17xx/lpc17_irq.c b/arch/arm/src/lpc17xx/lpc17_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..d1f72be399a9bdd1a7c93424e19fe7e50eca7ed1 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_irq.c @@ -0,0 +1,576 @@ +/**************************************************************************** + * arch/arm/src/lpc17/lpc17_irq.c + * + * Copyright (C) 2010-2011, 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc17_gpio.h" +#include "lpc17_clrpend.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void lpc17_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x\n", getreg32(NVIC_IRQ0_31_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + leave_critical_section(flags); +} +#else +# define lpc17_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: lpc17_nmi, lpc17_busfault, lpc17_usagefault, lpc17_pendsv, + * lpc17_dbgmonitor, lpc17_pendsv, lpc17_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int lpc17_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int lpc17_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int lpc17_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int lpc17_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int lpc17_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int lpc17_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: lpc17_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void lpc17_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: lpc17_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int lpc17_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= LPC17_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= LPC17_IRQ_EXTINT) + { + if (irq < (LPC17_IRQ_EXTINT+32)) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - LPC17_IRQ_EXTINT); + } + else if (irq < LPC17_IRQ_NIRQS) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - LPC17_IRQ_EXTINT - 32); + } + else + { + return ERROR; /* Invalid irq */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == LPC17_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == LPC17_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == LPC17_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == LPC17_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + * + * But even in this case NVIC_VECTAB has to point to the initial table + * because up_ramvec_initialize() initializes RAM table from table + * pointed by NVIC_VECTAB register. + */ + +#ifdef CONFIG_ARCH_RAMVECTORS + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(LPC17_IRQ_SVCALL, up_svcall); + irq_attach(LPC17_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(LPC17_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + lpc17_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(LPC17_IRQ_MEMFAULT, up_memfault); + up_enable_irq(LPC17_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(LPC17_IRQ_NMI, lpc17_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(LPC17_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(LPC17_IRQ_BUSFAULT, lpc17_busfault); + irq_attach(LPC17_IRQ_USAGEFAULT, lpc17_usagefault); + irq_attach(LPC17_IRQ_PENDSV, lpc17_pendsv); + irq_attach(LPC17_IRQ_DBGMONITOR, lpc17_dbgmonitor); + irq_attach(LPC17_IRQ_RESERVED, lpc17_reserved); +#endif + + lpc17_dumpnvic("initial", LPC17_IRQ_NIRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_GPIO_IRQ + lpc17_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (lpc17_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= LPC17_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_GPIO_IRQ + else if (irq >= LPC17_VALID_FIRST0L) + { + /* Maybe it is a (derived) GPIO IRQ */ + + lpc17_gpioirqdisable(irq); + } +#endif + + lpc17_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (lpc17_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= LPC17_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_GPIO_IRQ + else if (irq >= LPC17_VALID_FIRST0L) + { + /* Maybe it is a (derived) GPIO IRQ */ + + lpc17_gpioirqenable(irq); + } +#endif + + lpc17_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +#if 0 /* Does not appear to be necessary in most cases */ + lpc17_clrpend(irq); +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= LPC17_IRQ_MEMFAULT && irq < LPC17_IRQ_NIRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < LPC17_IRQ_EXTINT) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= LPC17_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + lpc17_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/lpc17xx/lpc17_lcd.c b/arch/arm/src/lpc17xx/lpc17_lcd.c new file mode 100644 index 0000000000000000000000000000000000000000..03f3e4e6b5ad3ff55e244151593057af12cf1432 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_lcd.c @@ -0,0 +1,801 @@ +/**************************************************************************** + * arch/arm/src//lpc17xx/lpc17_lcd.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_lcd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LPC17_LCD_CLK_PER_LINE \ + (CONFIG_LPC17_LCD_HWIDTH + CONFIG_LPC17_LCD_HPULSE + \ + CONFIG_LPC17_LCD_HFRONTPORCH + CONFIG_LPC17_LCD_HBACKPORCH) +#define LPC17_LCD_LINES_PER_FRAME \ + (CONFIG_LPC17_LCD_VHEIGHT + CONFIG_LPC17_LCD_VPULSE + \ + CONFIG_LPC17_LCD_VFRONTPORCH + CONFIG_LPC17_LCD_VBACKPORCH) +#define LPC17_LCD_PIXEL_CLOCK \ + (LPC17_LCD_CLK_PER_LINE * LPC17_LCD_LINES_PER_FRAME * \ + CONFIG_LPC17_LCD_REFRESH_FREQ) + +/* Framebuffer characteristics in bytes */ + +#if defined(CONFIG_LPC17_LCD_BPP1) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 1 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP2) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 2 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP4) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 4 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP8) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 8 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP16) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 16 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP24) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 32 + 7) / 8) +#elif defined(CONFIG_LPC17_LCD_BPP16_565) +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 16 + 7) / 8) +#else /* defined(CONFIG_LPC17_LCD_BPP12_444) */ +# define LPC17_STRIDE ((CONFIG_LPC17_LCD_HWIDTH * 16 + 7) / 8) +#endif + +#define LPC17_FBSIZE (LPC17_STRIDE * CONFIG_LPC17_LCD_VHEIGHT) + +/* Delays */ + +#define LPC17_LCD_PWRDIS_DELAY 10000 +#define LPC17_LCD_PWREN_DELAY 10000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Get information about the video controller configuration and the + * configuration of each color plane. + */ + +static int lpc17_getvideoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo); +static int lpc17_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo); + +/* The following is provided only if the video hardware supports RGB color + * mapping + */ + +#ifdef CONFIG_FB_CMAP +static int lpc17_getcmap(FAR struct fb_vtable_s *vtable, + FAR struct fb_cmap_s *cmap); +static int lpc17_putcmap(FAR struct fb_vtable_s *vtable, + FAR const struct fb_cmap_s *cmap); +#endif + +/* The following is provided only if the video hardware supports a hardware + * cursor + */ + +#ifdef CONFIG_FB_HWCURSOR +static int lpc17_getcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_cursorattrib_s *attrib); +static int lpc17_setcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_setcursor_s *setttings); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This structure describes the video controller */ + +static const struct fb_videoinfo_s g_videoinfo = +{ + .fmt = LPC17_COLOR_FMT, + .xres = CONFIG_LPC17_LCD_HWIDTH, + .yres = CONFIG_LPC17_LCD_VHEIGHT, + .nplanes = 1, +}; + +/* This structure describes the single color plane */ + +static const struct fb_planeinfo_s g_planeinfo = +{ + .fbmem = (FAR void *)CONFIG_LPC17_LCD_VRAMBASE, + .fblen = LPC17_FBSIZE, + .stride = LPC17_STRIDE, + .bpp = LPC17_BPP, +}; + +/* Current cursor position */ + +#ifdef CONFIG_FB_HWCURSOR +static struct fb_cursorpos_s g_cpos; + +/* Current cursor size */ + +#ifdef CONFIG_FB_HWCURSORSIZE +static struct fb_cursorsize_s g_csize; +#endif +#endif + +/* The framebuffer object -- There is no private state information in this + * framebuffer driver. + */ + +struct fb_vtable_s g_fbobject = +{ + .getvideoinfo = lpc17_getvideoinfo, + .getplaneinfo = lpc17_getplaneinfo, +#ifdef CONFIG_FB_CMAP + .getcmap = lpc17_getcmap, + .putcmap = lpc17_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + .getcursor = lpc17_getcursor, + .setcursor = lpc17_setcursor, +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_getvideoinfo + ****************************************************************************/ + +static int lpc17_getvideoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ + gvdbg("vtable=%p vinfo=%p\n", vtable, vinfo); + if (vtable && vinfo) + { + memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_getplaneinfo + ****************************************************************************/ + +static int lpc17_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ + gvdbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo); + if (vtable && planeno == 0 && pinfo) + { + memcpy(pinfo, &g_planeinfo, sizeof(struct fb_planeinfo_s)); + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: lpc17_getcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int lpc17_getcmap(FAR struct fb_vtable_s *vtable, + FAR struct fb_cmap_s *cmap) +{ + uint32_t *pal; + uint32_t rgb; + int last; + int i; + + gvdbg("vtable=%p cmap=%p first=%d len=%d\n", + vtable, cmap, cmap->first, cmap->len); + + DEBUGASSERT(vtable && cmap && + cmap->first < 256 && (cmap->first + cmap->len) < 256); + + pal = (uint32_t *)LPC17_LCD_PAL(cmap->first >> 1); + last = cmap->first + cmap->len; + + /* Handle the case where the first color starts on an odd boundary */ + + i = cmap->first; + if ((i & 1) != 0) + { + rgb = *pal++; + i++; + + /* Save the odd palette value */ + + cmap->red[i] = (rgb & LCD_PAL_R1_MASK) >> LCD_PAL_R1_SHIFT; + cmap->green[i] = (rgb & LCD_PAL_G1_MASK) >> LCD_PAL_G1_SHIFT; + cmap->blue[i] = (rgb & LCD_PAL_B1_MASK) >> LCD_PAL_B1_SHIFT; +#ifdef CONFIG_FB_TRANSPARENCY + cmap->transp[i] = 0; +#endif + } + + /* Handle even colors */ + + for (; i < last; i += 2) + { + rgb = *pal++; + + /* Save the even palette value */ + + cmap->red[i] = (rgb & LCD_PAL_R0_MASK) >> LCD_PAL_R0_SHIFT; + cmap->green[i] = (rgb & LCD_PAL_G0_MASK) >> LCD_PAL_G0_SHIFT; + cmap->blue[i] = (rgb & LCD_PAL_B0_MASK) >> LCD_PAL_B0_SHIFT; +#ifdef CONFIG_FB_TRANSPARENCY + cmap->transp[i] = 0; +#endif + + /* Handle the case where the len ends on an odd boudary */ + + if ((i + 1) < last) + { + /* Save the even palette value */ + + cmap->red[i+1] = (rgb & LCD_PAL_R1_MASK) >> LCD_PAL_R1_SHIFT; + cmap->green[i+1] = (rgb & LCD_PAL_G1_MASK) >> LCD_PAL_G1_SHIFT; + cmap->blue[i+1] = (rgb & LCD_PAL_B1_MASK) >> LCD_PAL_B1_SHIFT; +#ifdef CONFIG_FB_TRANSPARENCY + cmap->transp[i+1] = 0; +#endif + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc17_putcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int lpc17_putcmap(FAR struct fb_vtable_s *vtable, + FAR const struct fb_cmap_s *cmap) +{ + uint32_t *pal; + uint32_t rgb0; + uint32_t rgb1; + int last; + int i; + + gvdbg("vtable=%p cmap=%p first=%d len=%d\n", + vtable, cmap, cmap->first, cmap->len); + + DEBUGASSERT(vtable && cmap); + + pal = (uint32_t *)LPC17_LCD_PAL(cmap->first >> 1); + last = cmap->first + cmap->len; + + /* Handle the case where the first color starts on an odd boundary */ + + i = cmap->first; + if ((i & 1) != 0) + { + rgb0 = *pal; + rgb0 &= (LCD_PAL_R0_MASK | LCD_PAL_G0_MASK | LCD_PAL_B0_MASK | LCD_PAL_I0); + rgb1 |= ((uint32_t)cmap->red[i] << LCD_PAL_R0_SHIFT | + (uint32_t)cmap->green[i] << LCD_PAL_G0_SHIFT | + (uint32_t)cmap->blue[i] << LCD_PAL_B0_SHIFT); + + /* Save the new palette value */ + + *pal++ = (rgb0 | rgb1); + i++; + } + + /* Handle even colors */ + + for (; i < last; i += 2) + { + uint32_t rgb0 = ((uint32_t)cmap->red[i] << LCD_PAL_R0_SHIFT | + (uint32_t)cmap->green[i] << LCD_PAL_G0_SHIFT | + (uint32_t)cmap->blue[i] << LCD_PAL_B0_SHIFT); + + /* Handle the case where the len ends on an odd boudary */ + + if ((i + 1) >= last) + { + rgb1 = *pal; + rgb1 &= (LCD_PAL_R1_MASK | LCD_PAL_G1_MASK | LCD_PAL_B1_MASK | LCD_PAL_I1); + } + else + { + rgb1 = ((uint32_t)cmap->red[i+1] << LCD_PAL_R1_SHIFT | + (uint32_t)cmap->green[i+1] << LCD_PAL_G1_SHIFT | + (uint32_t)cmap->blue[i+1] << LCD_PAL_B1_SHIFT); + } + + /* Save the new pallete value */ + + *pal++ = (rgb0 | rgb1); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc17_getcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int lpc17_getcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_cursorattrib_s *attrib) +{ + gvdbg("vtable=%p attrib=%p\n", vtable, attrib); + if (vtable && attrib) + { +#ifdef CONFIG_FB_HWCURSORIMAGE + attrib->fmt = LPC17_COLOR_FMT; +#endif + + gvdbg("pos: (x=%d, y=%d)\n", g_cpos.x, g_cpos.y); + attrib->pos = g_cpos; + +#ifdef CONFIG_FB_HWCURSORSIZE + attrib->mxsize.h = CONFIG_LPC17_LCD_VHEIGHT; + attrib->mxsize.w = CONFIG_LPC17_LCD_HWIDTH; + + gvdbg("size: (h=%d, w=%d)\n", g_csize.h, g_csize.w); + attrib->size = g_csize; +#endif + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: lpc17_setcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int lpc17_setcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_setcursor_s *setttings) +{ + gvdbg("vtable=%p setttings=%p\n", vtable, setttings); + if (vtable && setttings) + { + gvdbg("flags: %02x\n", settings->flags); + if ((flags & FB_CUR_SETPOSITION) != 0) + { + g_cpos = settings->pos; + gvdbg("pos: (h:%d, w:%d)\n", g_cpos.x, g_cpos.y); + } +#ifdef CONFIG_FB_HWCURSORSIZE + if ((flags & FB_CUR_SETSIZE) != 0) + { + g_csize = settings->size; + gvdbg("size: (h:%d, w:%d)\n", g_csize.h, g_csize.w); + } +#endif +#ifdef CONFIG_FB_HWCURSORIMAGE + if ((flags & FB_CUR_SETIMAGE) != 0) + { + gvdbg("image: (h:%d, w:%d) @ %p\n", + settings->img.height, settings->img.width, + settings->img.image); + } +#endif + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fbinitialize + * + * Description: + * Initialize the framebuffer video hardware + * + ****************************************************************************/ + +int up_fbinitialize(void) +{ + uint32_t regval; + int i; + + gvdbg("Entry\n"); + + /* Give LCD bus priority */ + + regval = ((SYSCON_MATRIXARB_PRI_ICODE(SYSCON_MATRIXARB_PRI_LOW)) | + (SYSCON_MATRIXARB_PRI_DCODE(SYSCON_MATRIXARB_PRI_HIGHEST)) | + (SYSCON_MATRIXARB_PRI_LCD(SYSCON_MATRIXARB_PRI_HIGHEST))); + putreg32(regval, LPC17_SYSCON_MATRIXARB); + + /* Configure pins */ + /* Video data */ + + gvdbg("Configuring pins\n"); + + lpc17_configgpio(GPIO_LCD_VD0); + lpc17_configgpio(GPIO_LCD_VD1); + lpc17_configgpio(GPIO_LCD_VD2); + lpc17_configgpio(GPIO_LCD_VD3); + lpc17_configgpio(GPIO_LCD_VD4); + lpc17_configgpio(GPIO_LCD_VD5); + lpc17_configgpio(GPIO_LCD_VD6); + lpc17_configgpio(GPIO_LCD_VD7); + + lpc17_configgpio(GPIO_LCD_VD8); + lpc17_configgpio(GPIO_LCD_VD9); + lpc17_configgpio(GPIO_LCD_VD10); + lpc17_configgpio(GPIO_LCD_VD11); + lpc17_configgpio(GPIO_LCD_VD12); + lpc17_configgpio(GPIO_LCD_VD13); + lpc17_configgpio(GPIO_LCD_VD14); + lpc17_configgpio(GPIO_LCD_VD15); + +#if LPC17_BPP > 16 + lpc17_configgpio(GPIO_LCD_VD16); + lpc17_configgpio(GPIO_LCD_VD17); + lpc17_configgpio(GPIO_LCD_VD18); + lpc17_configgpio(GPIO_LCD_VD19); + lpc17_configgpio(GPIO_LCD_VD20); + lpc17_configgpio(GPIO_LCD_VD21); + lpc17_configgpio(GPIO_LCD_VD22); + lpc17_configgpio(GPIO_LCD_VD23); +#endif + + /* Other pins */ + + lpc17_configgpio(GPIO_LCD_DCLK); + lpc17_configgpio(GPIO_LCD_LP); + lpc17_configgpio(GPIO_LCD_FP); + lpc17_configgpio(GPIO_LCD_ENABM); + lpc17_configgpio(GPIO_LCD_PWR); + + /* Turn on LCD clock */ + + modifyreg32(LPC17_SYSCON_PCONP, 0, SYSCON_PCONP_PCLCD); + + gvdbg("Configuring the LCD controller\n"); + + /* Disable the cursor */ + + regval = getreg32(LPC17_LCD_CRSR_CRTL); + regval &= ~LCD_CRSR_CTRL_CRSON; + putreg32(regval, LPC17_LCD_CRSR_CRTL); + + /* Clear any pending interrupts */ + + putreg32(LCD_INTCLR_ALL, LPC17_LCD_INTCLR); + + /* Disable GLCD controller */ + + putreg32(0, LPC17_LCD_CTRL); + + /* Initialize pixel clock (assuming clock source is the peripheral clock) */ + + putreg32(((uint32_t)BOARD_PCLK_FREQUENCY / (uint32_t)LPC17_LCD_PIXEL_CLOCK)+1, + LPC17_SYSCON_LCDCFG); + + /* Set the bits per pixel */ + + regval = getreg32(LPC17_LCD_CTRL); + regval &= ~LCD_CTRL_LCDBPP_MASK; + +#if defined(CONFIG_LPC17_LCD_BPP1) + regval |= LCD_CTRL_LCDBPP_1; /* 1 bpp */ +#elif defined(CONFIG_LPC17_LCD_BPP2) + regval |= LCD_CTRL_LCDBPP_2; /* 2 bpp */ +#elif defined(CONFIG_LPC17_LCD_BPP4) + regval |= LCD_CTRL_LCDBPP_4; /* 4 bpp */ +#elif defined(CONFIG_LPC17_LCD_BPP8) + regval |= LCD_CTRL_LCDBPP_8; /* 8 bpp */ +#elif defined(CONFIG_LPC17_LCD_BPP16) + regval |= LCD_CTRL_LCDBPP_16; /* 16 bpp */ +#elif defined(CONFIG_LPC17_LCD_BPP24) + regval |= LCD_CTRL_LCDBPP_24; /* 24-bit TFT panel only */ +#elif defined(CONFIG_LPC17_LCD_BPP16_565) + regval |= LCD_CTRL_LCDBPP_565; /* 16 bpp, 5:6:5 mode */ +#else /* defined(CONFIG_LPC17_LCD_BPP12_444) */ + regval |= LCD_CTRL_LCDBPP_444; /* 12 bpp, 4:4:4 mode */ +#endif + + /* TFT panel */ + +#ifdef CONFIG_LPC17_LCD_TFTPANEL + regval |= LCD_CTRL_LCDTFT; +#endif + + /* Swap red and blue. The colors will be 0x00RRGGBB, not 0x00BBGGRR. */ + + regval |= LCD_CTRL_BGR; + + /* Single panel */ + + regval &= ~LCD_CTRL_LCDDUAL; + + /* Select monochrome or color LCD */ + +#ifdef CONFIG_LPC17_LCD_MONOCHROME + /* Select monochrome LCD */ + + regval &= ~LCD_CTRL_BGR; + + /* Select 4- or 8-bit monochrome interface */ + +# if LPC17_BPP > 4 + regval |= LCD_CTRL_LCDMONO8; +# else + regval &= ~LCD_CTRL_LCDMONO8; +# endif + +#else + /* Select color LCD */ + + regval &= ~(LCD_CTRL_LCDBW | LCD_CTRL_LCDMONO8); + +#endif /* CONFIG_LPC17_LCD_MONOCHROME */ + + /* Little endian byte order */ + + regval &= ~LCD_CTRL_BEBO; + + /* Little endian pixel order */ + + regval &= ~LCD_CTRL_BEPO; + putreg32(regval, LPC17_LCD_CTRL); + + /* Initialize horizontal timing */ + + putreg32(0, LPC17_LCD_TIMH); + + regval = (((CONFIG_LPC17_LCD_HWIDTH/16) - 1) << LCD_TIMH_PPL_SHIFT | + (CONFIG_LPC17_LCD_HPULSE - 1) << LCD_TIMH_HSW_SHIFT | + (CONFIG_LPC17_LCD_HFRONTPORCH - 1) << LCD_TIMH_HFP_SHIFT | + (CONFIG_LPC17_LCD_HBACKPORCH - 1) << LCD_TIMH_HBP_SHIFT); + putreg32(regval, LPC17_LCD_TIMH); + + /* Initialize vertical timing */ + + putreg32(0, LPC17_LCD_TIMV); + + regval = ((CONFIG_LPC17_LCD_VHEIGHT - 1) << LCD_TIMV_LPP_SHIFT | + (CONFIG_LPC17_LCD_VPULSE - 1) << LCD_TIMV_VSW_SHIFT | + (CONFIG_LPC17_LCD_VFRONTPORCH) << LCD_TIMV_VFP_SHIFT | + (CONFIG_LPC17_LCD_VBACKPORCH) << LCD_TIMV_VBP_SHIFT); + putreg32(regval, LPC17_LCD_TIMV); + + /* Initialize clock and signal polarity */ + + regval = getreg32(LPC17_LCD_POL); + + /* LCDFP pin is active LOW and inactive HIGH */ + + regval |= LCD_POL_IVS; + + /* LCDLP pin is active LOW and inactive HIGH */ + + regval |= LCD_POL_IHS; + + /* Data is driven out into the LCD on the falling edge */ + + regval &= ~LCD_POL_IPC; + + /* Set number of clocks per line */ + + regval |= ((CONFIG_LPC17_LCD_HWIDTH-1) << LCD_POL_CPL_SHIFT); + + /* Bypass internal pixel clock divider */ + + regval |= LCD_POL_BCD; + + /* LCD_ENAB_M is active high */ + + regval &= ~LCD_POL_IOE; + + /* Select CCLK for the LCD block clock source */ + + regval &= ~LCD_POL_CLKSEL; + putreg32(regval, LPC17_LCD_POL); + + /* Frame base address doubleword aligned */ + + putreg32(CONFIG_LPC17_LCD_VRAMBASE & ~7, LPC17_LCD_UPBASE); + putreg32(CONFIG_LPC17_LCD_VRAMBASE & ~7, LPC17_LCD_LPBASE); + + /* Clear the display */ + + lpc17_lcdclear(CONFIG_LPC17_LCD_BACKCOLOR); + +#ifdef CONFIG_LPC17_LCD_BACKLIGHT + /* Turn on the back light */ + + lpc17_backlight(true); +#endif + + putreg32(0, LPC17_LCD_INTMSK); + gvdbg("Enabling the display\n"); + + for (i = LPC17_LCD_PWREN_DELAY; i; i--); + + /* Enable LCD */ + + regval = getreg32(LPC17_LCD_CTRL); + regval |= LCD_CTRL_LCDEN; + putreg32(regval, LPC17_LCD_CTRL); + + /* Enable LCD power */ + + for (i = LPC17_LCD_PWREN_DELAY; i; i--); + + regval = getreg32(LPC17_LCD_CTRL); + regval |= LCD_CTRL_LCDPWR; + putreg32(regval, LPC17_LCD_CTRL); + + return OK; +} + +/**************************************************************************** + * Name: lpc17_fbgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video + * plane. + * + * Input parameters: + * None + * + * Returned value: + * Reference to the framebuffer object (NULL on failure) + * + ****************************************************************************/ + +FAR struct fb_vtable_s *up_fbgetvplane(int vplane) +{ + gvdbg("vplane: %d\n", vplane); + if (vplane == 0) + { + return &g_fbobject; + } + else + { + return NULL; + } +} + +/**************************************************************************** + * Name: fb_uninitialize + * + * Description: + * Unitialize the framebuffer support + * + ****************************************************************************/ + +void fb_uninitialize(void) +{ + uint32_t regval; + int i; + + /* We assume there is only one use of the LCD and so we do not need to + * worry about mutually exclusive access to the LCD hardware. + */ + +#ifdef CONFIG_LPC17_LCD_BACKLIGHT + /* Turn off the back light */ + + lpc17_backlight(false); +#endif + + /* Disable the LCD controller */ + + regval = getreg32(LPC17_LCD_CTRL); + regval &= ~LCD_CTRL_LCDPWR; + putreg32(regval, LPC17_LCD_CTRL); + + for (i = LPC17_LCD_PWRDIS_DELAY; i; i--); + + regval &= ~LCD_CTRL_LCDEN; + putreg32(regval, LPC17_LCD_CTRL); + + /* Turn off clocking to the LCD. modifyreg32() can do this atomically. */ + + modifyreg32(LPC17_SYSCON_PCONP, SYSCON_PCONP_PCLCD, 0); +} + +/************************************************************************************ + * Name: lpc17_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the LPC17xx. Clearing the display + * in the normal way by writing a sequences of runs that covers the entire display + * can be slow. Here the display is cleared by simply setting all VRAM memory to + * the specified color. + * + ************************************************************************************/ + +void lpc17_lcdclear(nxgl_mxpixel_t color) +{ + int i; +#if LPC17_BPP > 16 + uint32_t *dest = (uint32_t *)CONFIG_LPC17_LCD_VRAMBASE; + + gvdbg("Clearing display: color=%08x VRAM=%08x size=%d\n", + color, CONFIG_LPC17_LCD_VRAMBASE, + CONFIG_LPC17_LCD_HWIDTH * CONFIG_LPC17_LCD_VHEIGHT * sizeof(uint32_t)); + +#else + uint16_t *dest = (uint16_t *)CONFIG_LPC17_LCD_VRAMBASE; + + gvdbg("Clearing display: color=%08x VRAM=%08x size=%d\n", + color, CONFIG_LPC17_LCD_VRAMBASE, + CONFIG_LPC17_LCD_HWIDTH * CONFIG_LPC17_LCD_VHEIGHT * sizeof(uint16_t)); +#endif + + for (i = 0; i < (CONFIG_LPC17_LCD_HWIDTH * CONFIG_LPC17_LCD_VHEIGHT); i++) + { + *dest++ = color; + } +} diff --git a/arch/arm/src/lpc17xx/lpc17_lcd.h b/arch/arm/src/lpc17xx/lpc17_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..99daa200691efb482674379208c06a80c4e7cdc9 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_lcd.h @@ -0,0 +1,195 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_lcd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_LCD_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_LCD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include + +#include "chip/lpc17_lcd.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration */ + +/* Base address of the video RAM frame buffer */ + +#ifndef CONFIG_LPC17_LCD_VRAMBASE +# define CONFIG_LPC17_LCD_VRAMBASE ((uint32_t)LPC17_EXTDRAM_CS0 + 0x00010000) +#endif + +/* LCD refresh rate */ + +#ifndef CONFIG_LPC17_LCD_REFRESH_FREQ +# define CONFIG_LPC17_LCD_REFRESH_FREQ (50) /* Hz */ +#endif + +/* Bits per pixel / color format */ + +#undef LPC17_COLOR_FMT +#if defined(CONFIG_LPC17_LCD_BPP1) +# define LPC17_BPP 1 +# define LPC17_COLOR_FMT FB_FMT_Y1 +#elif defined(CONFIG_LPC17_LCD_BPP2) +# define LPC17_BPP 2 +# define LPC17_COLOR_FMT FB_FMT_Y2 +#elif defined(CONFIG_LPC17_LCD_BPP4) +# define LPC17_BPP 4 +# define LPC17_COLOR_FMT FB_FMT_Y4 +#elif defined(CONFIG_LPC17_LCD_BPP8) +# define LPC17_BPP 8 +# define LPC17_COLOR_FMT FB_FMT_Y8 +#elif defined(CONFIG_LPC17_LCD_BPP16) +# define LPC17_BPP 16 +# define LPC17_COLOR_FMT FB_FMT_Y16 +#elif defined(CONFIG_LPC17_LCD_BPP24) +# define LPC17_BPP 32 /* Only 24 of 32 bits used for RGB */ +# define LPC17_COLOR_FMT FB_FMT_RGB24 +# ifndef CONFIG_LPC17_LCD_TFTPANEL +# error "24 BPP is only available for a TFT panel" +# endif +#elif defined(CONFIG_LPC17_LCD_BPP16_565) +# define LPC17_BPP 16 +# define LPC17_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_LPC17_LCD_BPP12_444) +# define LPC17_BPP 1 2 +# define LPC17_COLOR_FMT FB_FMT_RGB12_444 +#else +# ifndef CONFIG_LPC17_LCD_TFTPANEL +# warning "Assuming 24 BPP" +# define LPC17_BPP 24 +# define CONFIG_LPC17_LCD_BPP24 1 +# define LPC17_COLOR_FMT FB_FMT_RGB24 +# else +# warning "Assuming 16 BPP 5:6:5" +# define LPC17_BPP 16 +# define CONFIG_LPC17_LCD_BPP16_565 1 +# define LPC17_COLOR_FMT FB_FMT_RGB16_565 +# endif +#endif + +/* Background color */ + +#ifndef CONFIG_LPC17_LCD_BACKCOLOR +# define CONFIG_LPC17_LCD_BACKCOLOR 0 /* Initial background color */ +#endif + +/* Horizontal video characteristics */ + +#ifndef CONFIG_LPC17_LCD_HWIDTH +# define CONFIG_LPC17_LCD_HWIDTH 480 /* Width in pixels */ +#endif + +#ifndef CONFIG_LPC17_LCD_HPULSE +# define CONFIG_LPC17_LCD_HPULSE 2 +#endif + +#ifndef CONFIG_LPC17_LCD_HFRONTPORCH +# define CONFIG_LPC17_LCD_HFRONTPORCH 5 +#endif + +#ifndef CONFIG_LPC17_LCD_HBACKPORCH +# define CONFIG_LPC17_LCD_HBACKPORCH 40 +#endif + +/* Vertical video characteristics */ + +#ifndef CONFIG_LPC17_LCD_VHEIGHT +# define CONFIG_LPC17_LCD_VHEIGHT 272 /* Height in rows */ +#endif + +#ifndef CONFIG_LPC17_LCD_VPULSE +# define CONFIG_LPC17_LCD_VPULSE 2 +#endif + +#ifndef CONFIG_LPC17_LCD_VFRONTPORCH +# define CONFIG_LPC17_LCD_VFRONTPORCH 8 +#endif + +#ifndef CONFIG_LPC17_LCD_VBACKPORCH +# define CONFIG_LPC17_LCD_VBACKPORCH 8 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/* The LPC17 LCD driver uses the common framebuffer interfaces declared in + * include/nuttx/video/fb.h. + */ + +/************************************************************************************ + * Name: lpc17_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the LPC17xx. Clearing the display + * in the normal way by writing a sequences of runs that covers the entire display + * can be slow. Here the dispaly is cleared by simply setting all VRAM memory to + * the specified color. + * + ************************************************************************************/ + +void lpc17_lcdclear(nxgl_mxpixel_t color); + +/************************************************************************************ + * Name: lpc17_backlight + * + * Description: + * If CONFIG_LPC17_LCD_BACKLIGHT is defined, then the board-specific logic must + * provide this interface to turn the backlight on and off. + * + ************************************************************************************/ + +#ifdef CONFIG_LPC17_LCD_BACKLIGHT +void lpc17_backlight(bool blon); +#endif + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_LCD_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_lowputc.c b/arch/arm/src/lpc17xx/lpc17_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..3670014588087c8175003b8407a837f871707969 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_lowputc.c @@ -0,0 +1,414 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_lowputc.c + * + * Copyright (C) 2010-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/lpc17_syscon.h" +#include "chip/lpc17_uart.h" + +#include "lpc17_gpio.h" +#include "lpc17_lowputc.h" +#include "lpc17_serial.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART0_BASE +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART1_BASE +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART2_BASE +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +# define CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART3_BASE +# define CONSOLE_BAUD CONFIG_UART3_BAUD +# define CONSOLE_BITS CONFIG_UART3_BITS +# define CONSOLE_PARITY CONFIG_UART3_PARITY +# define CONSOLE_2STOP CONFIG_UART3_2STOP +#elif defined(HAVE_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS == 5 +# define CONSOLE_LCR_WLS UART_LCR_WLS_5BIT +#elif CONSOLE_BITS == 6 +# define CONSOLE_LCR_WLS UART_LCR_WLS_6BIT +#elif CONSOLE_BITS == 7 +# define CONSOLE_LCR_WLS UART_LCR_WLS_7BIT +#elif CONSOLE_BITS == 8 +# define CONSOLE_LCR_WLS UART_LCR_WLS_8BIT +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) +#elif CONSOLE_PARITY == 3 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) +#elif CONSOLE_PARITY == 4 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and UART0-3 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP UART_LCR_STOP +#else +# define CONSOLE_LCR_STOP 0 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) +#define CONSOLE_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ + UART_FCR_RXRST | UART_FCR_FIFOEN) + +/* Select a CCLK divider to produce the UART PCLK. The strategy is to select the + * smallest divisor that results in an solution within range of the 16-bit + * DLM and DLL divisor: + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Where for the LPC176x the PCLK is determined by the UART-specific divisor in + * PCLKSEL0 or PCLKSEL1: + * + * PCLK = CCLK / divisor + * + * And for the LPC178x, the PCLK is determined by the global divisor setting in + * the PLKSEL register. + * + * Ignoring the fractional divider for now. (If you want to extend this driver + * to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses + * the same peripheral and that logic could easily leveraged here). + */ + +#ifdef LPC178x + /* Use the global PCLK frequency */ + +# define CONSOLE_NUMERATOR BOARD_PCLK_FREQUENCY + +#else + /* Calculate and optimal PCLKSEL0/1 divisor. + * First, check divisor == 1. This works if the upper limit is met: + * + * DL < 0xffff, or + * PCLK / BAUD / 16 < 0xffff, or + * CCLK / BAUD / 16 < 0xffff, or + * CCLK < BAUD * 0xffff * 16 + * BAUD > CCLK / 0xffff / 16 + * + * And the lower limit is met (we can't allow DL to get very close to one). + * + * DL >= MinDL + * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 16 / MinDL + */ + +# if CONSOLE_BAUD < (LPC17_CCLK / 16 / UART_MINDL) +# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK +# define CONSOLE_NUMERATOR (LPC17_CCLK) + + /* Check divisor == 2. This works if: + * + * 2 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 8 + * + * And + * + * 2 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 8 / MinDL + */ + +# elif CONSOLE_BAUD < (LPC17_CCLK / 8 / UART_MINDL) +# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK2 +# define CONSOLE_NUMERATOR (LPC17_CCLK / 2) + + /* Check divisor == 4. This works if: + * + * 4 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 4 + * + * And + * + * 4 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 4 / MinDL + */ + +# elif CONSOLE_BAUD < (LPC17_CCLK / 4 / UART_MINDL) +# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK4 +# define CONSOLE_NUMERATOR (LPC17_CCLK / 4) + + /* Check divisor == 8. This works if: + * + * 8 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 2 + * + * And + * + * 8 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 2 / MinDL + */ + +# else /* if CONSOLE_BAUD < (LPC17_CCLK / 2 / UART_MINDL) */ +# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK8 +# define CONSOLE_NUMERATOR (LPC17_CCLK / 8) +# endif +#endif /* LPC178x */ + +/* Then this is the value to use for the DLM and DLL registers */ + +#define CONSOLE_DL (CONSOLE_NUMERATOR / (CONSOLE_BAUD << 4)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART && defined HAVE_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(CONSOLE_BASE+LPC17_UART_LSR_OFFSET) & UART_LSR_THRE) == 0); + + /* Send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE+LPC17_UART_THR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: lpc17_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + * The UART0/1/2/3 peripherals are configured using the following registers: + * 1. Power: In the PCONP register, set bits PCUART0/1/2/3. + * On reset, UART0 and UART 1 are enabled (PCUART0 = 1 and PCUART1 = 1) + * and UART2/3 are disabled (PCUART1 = 0 and PCUART3 = 0). + * 2. Peripheral clock: In the PCLKSEL0 register, select PCLK_UART0 and + * PCLK_UART1; in the PCLKSEL1 register, select PCLK_UART2 and PCLK_UART3. + * 3. Baud rate: In the LCR register, set bit DLAB = 1. This enables access + * to registers DLL and DLM for setting the baud rate. Also, if needed, + * set the fractional baud rate in the fractional divider. + * 4. UART FIFO: Use bit FIFO enable (bit 0) in FCR register to + * enable FIFO. + * 5. Pins: Select UART pins through the PINSEL registers and pin modes + * through the PINMODE registers. UART receive pins should not have + * pull-down resistors enabled. + * 6. Interrupts: To enable UART interrupts set bit DLAB = 0 in the LCRF + * register. This enables access to IER. Interrupts are enabled + * in the NVIC using the appropriate Interrupt Set Enable register. + * 7. DMA: UART transmit and receive functions can operate with the + * GPDMA controller. + * + ****************************************************************************/ + +void lpc17_lowsetup(void) +{ +#ifdef HAVE_UART + uint32_t regval; + + /* Step 1: Enable power for all console UART and disable power for + * other UARTs + */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval &= ~(SYSCON_PCONP_PCUART0 | SYSCON_PCONP_PCUART1 | + SYSCON_PCONP_PCUART2 | SYSCON_PCONP_PCUART3); +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + regval |= SYSCON_PCONP_PCUART0; +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + regval |= SYSCON_PCONP_PCUART1; +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) + regval |= SYSCON_PCONP_PCUART2; +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) + regval |= SYSCON_PCONP_PCUART3; +#endif + putreg32(regval, LPC17_SYSCON_PCONP); + +/* Step 2: Enable peripheral clocking for the console UART and disable + * clocking for all other UARTs + */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~(SYSCON_PCLKSEL0_UART0_MASK | SYSCON_PCLKSEL0_UART1_MASK); +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + regval |= (CONSOLE_CCLKDIV << SYSCON_PCLKSEL0_UART0_SHIFT); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + regval |= (CONSOLE_CCLKDIV << SYSCON_PCLKSEL0_UART1_SHIFT); +#endif + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~(SYSCON_PCLKSEL1_UART2_MASK | SYSCON_PCLKSEL1_UART3_MASK); +#if defined(CONFIG_UART2_SERIAL_CONSOLE) + regval |= (CONSOLE_CCLKDIV << SYSCON_PCLKSEL1_UART2_SHIFT); +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) + regval |= (CONSOLE_CCLKDIV << SYSCON_PCLKSEL1_UART3_SHIFT); +#endif + putreg32(regval, LPC17_SYSCON_PCLKSEL1); +#endif + + /* Configure UART pins for the selected CONSOLE */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + lpc17_configgpio(GPIO_UART0_TXD); + lpc17_configgpio(GPIO_UART0_RXD); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + lpc17_configgpio(GPIO_UART1_TXD); + lpc17_configgpio(GPIO_UART1_RXD); +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) + lpc17_configgpio(GPIO_UART1_CTS); + lpc17_configgpio(GPIO_UART1_DCD); + lpc17_configgpio(GPIO_UART1_DSR); + lpc17_configgpio(GPIO_UART1_DTR); + lpc17_configgpio(GPIO_UART1_RI); + lpc17_configgpio(GPIO_UART1_RTS); +#endif +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) + lpc17_configgpio(GPIO_UART2_TXD); + lpc17_configgpio(GPIO_UART2_RXD); +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) + lpc17_configgpio(GPIO_UART3_TXD); + lpc17_configgpio(GPIO_UART3_RXD); +#endif + + /* Configure the console (only) */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* Clear fifos */ + + putreg32(UART_FCR_RXRST | UART_FCR_TXRST, + CONSOLE_BASE + LPC17_UART_FCR_OFFSET); + + /* Set trigger */ + + putreg32(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8, + CONSOLE_BASE + LPC17_UART_FCR_OFFSET); + + /* Set up the LCR and set DLAB=1 */ + + putreg32(CONSOLE_LCR_VALUE | UART_LCR_DLAB, + CONSOLE_BASE + LPC17_UART_LCR_OFFSET); + + /* Set the BAUD divisor */ + + putreg32(CONSOLE_DL >> 8, CONSOLE_BASE + LPC17_UART_DLM_OFFSET); + putreg32(CONSOLE_DL & 0xff, CONSOLE_BASE + LPC17_UART_DLL_OFFSET); + + /* Clear DLAB */ + + putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE + LPC17_UART_LCR_OFFSET); + + /* Configure the FIFOs */ + + putreg32(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN, + CONSOLE_BASE + LPC17_UART_FCR_OFFSET); +#endif +#endif /* HAVE_UART */ +} + diff --git a/arch/arm/src/lpc17xx/lpc17_lowputc.h b/arch/arm/src/lpc17xx/lpc17_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..b1b226e03533e053746e49cbad0a1a0a62598ec1 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_lowputc.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_LOWPUTC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void lpc17_lowsetup(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_LOWPUTC_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_mcpwm.c b/arch/arm/src/lpc17xx/lpc17_mcpwm.c new file mode 100644 index 0000000000000000000000000000000000000000..f8d552941b04a34992b0d2a9898ad0c1b16b08f0 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_mcpwm.c @@ -0,0 +1,684 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_mcpwm.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_pwm.h" +#include "chip/lpc176x_pinconfig.h" +#include "lpc17_gpio.h" +#include "lpc176x_gpio.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_LPC17_MCPWM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4 */ +#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ +#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ + +#define TIMTYPE_TIM1 TIMTYPE_ADVANCED + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct lpc17_mcpwmtimer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {0,...,7} */ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint8_t timtype; /* See the TIMTYPE_* definitions */ + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t mcpwm_getreg(struct lpc17_mcpwmtimer_s *priv, int offset); +static void mcpwm_putreg(struct lpc17_mcpwmtimer_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void mcpwm_dumpregs(struct lpc17_mcpwmtimer_s *priv, FAR const char *msg); +#else +# define mcpwm_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int mcpwm_timer(FAR struct lpc17_mcpwmtimer_s *priv, + FAR const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int mcpwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int mcpwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + +static int mcpwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); + +static int mcpwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int mcpwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half + * driver + */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = mcpwm_setup, + .shutdown = mcpwm_shutdown, + .start = mcpwm_start, + .stop = mcpwm_stop, + .ioctl = mcpwm_ioctl, +}; + +#ifdef CONFIG_LPC17_MCPWM +static struct lpc17_mcpwmtimer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channel = CONFIG_LPC17_MCPWM1_PIN, + .timtype = TIMTYPE_TIM1, + .base = LPC17_MCPWM_BASE, + .pincfg = GPIO_MCPWM_MCOA0, + .pclk = (1 << 12), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcpwm_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t mcpwm_getreg(struct lpc17_mcpwmtimer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: mcpwm_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcpwm_putreg(struct lpc17_mcpwmtimer_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: mcpwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void mcpwm_dumpregs(FAR struct lpc17_mcpwmtimer_s *priv, + FAR const char *msg) +{ + pwmvdbg("%s:\n", msg); + pwmvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + mcpwm_getreg(priv, LPC17_PWM_MR0_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR1_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); +#if defined(CONFIG_LPC17_MCPWM) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + mcpwm_getreg(priv, LPC17_PWM_MR0_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR1_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } + else +#endif + { + pwmvdbg(" DCR: %04x DMAR: %04x\n", + mcpwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + mcpwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: mcpwm_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_timer(FAR struct lpc17_mcpwmtimer_s *priv, + FAR const struct pwm_info_s *info) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + putreg32(info->frequency, LPC17_MCPWM_LIM0); /* Set PWMMR0 = number of counts */ + putreg32(info->duty, LPC17_MCPWM_MAT0); /* Set PWM cycle */ + + leave_critical_section(flags); + mcpwm_dumpregs(priv, "After starting"); + return OK; +} + +#ifdef XXXXX +/**************************************************************************** + * Name: mcpwm_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_interrupt(struct lpc17_mcpwmtimer_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = mcpwm_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + mcpwm_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + return OK; +} + +/**************************************************************************** + * Name: mcpwm_tim1/8interrupt + * + * Description: + * Handle timer 1 and 8 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_tim1interrupt(int irq, void *context) +{ + return mcpwm_interrupt(&g_pwm1dev); +} + +/**************************************************************************** + * Name: mcpwm_set_apb_clock + * + * Description: + * Enable or disable APB clock for the timer peripheral + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void mcpwm_set_apb_clock(FAR struct lpc17_mcpwmtimer_s *priv, bool on) +{ + uint32_t en_bit; + uint32_t regaddr; + + /* Determine which timer to configure */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC17_MCPWM + case 1: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM1EN; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for timer */ + + if (on) + { + modifyreg32(regaddr, 0, en_bit); + } + else + { + modifyreg32(regaddr, en_bit, 0); + } +} +#endif + +/**************************************************************************** + * Name: mcpwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int mcpwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_mcpwmtimer_s *priv = (FAR struct lpc17_mcpwmtimer_s *)dev; + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Power on the mcpwm peripheral */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCMCPWM; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Select clock for the mcpwm peripheral */ + + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~(0x3 << 30); + regval |= (0x2 << 30); /* PCLK_MC peripheral clk = CCLK/2 = 50 MHz */ + putreg32(regval, LPC17_SYSCON_PCLKSEL1); + priv->pclk = (0x1 << 12) | (0x1 << 4); + + putreg32((1 << 15), LPC17_MCPWM_INTENCLR); /* Disable MCABORT pin interrupt */ + putreg32((1 << 0), LPC17_MCPWM_INTENCLR); /* Disable ILIM0 interrupt */ + putreg32((1 << 1), LPC17_MCPWM_INTENCLR); /* Disable IMAT0 interrupt */ + putreg32((1 << 2), LPC17_MCPWM_INTENCLR); /* Disable ICAP0 interrupt */ + putreg32((1 << 4), LPC17_MCPWM_INTENCLR); /* Disable ILIM1 interrupt */ + putreg32((1 << 5), LPC17_MCPWM_INTENCLR); /* Disable IMAT1 interrupt */ + putreg32((1 << 6), LPC17_MCPWM_INTENCLR); /* Disable ICAP1 interrupt */ + putreg32((1 << 8), LPC17_MCPWM_INTENCLR); /* Disable ILIM2 interrupt */ + putreg32((1 << 9), LPC17_MCPWM_INTENCLR); /* Disable IMAT2 interrupt */ + putreg32((1 << 10), LPC17_MCPWM_INTENCLR); /* Disable ICAP2 interrupt */ + + putreg32((0xFFFFFFFF), LPC17_MCPWM_CAPCLR); /* Clear all event capture */ + + /* Configure the output pins */ + + lpc17_configgpio(GPIO_MCPWM_MCOA0); + lpc17_configgpio(GPIO_MCPWM_MCOB0); + + /* Program the timing registers */ + + putreg32((1 << 0), LPC17_MCPWM_CONCLR); /* Stop MCPWM timer0 */ + putreg32((1 << 8), LPC17_MCPWM_CONCLR); /* Stop MCPWM timer1 */ + putreg32((1 << 16), LPC17_MCPWM_CONCLR); /* Stop MCPWM timer2 */ + + putreg32((1 << 30), LPC17_MCPWM_CONCLR); /* MCPWM not in AC mode */ + + putreg32(1000, LPC17_MCPWM_TC0); /* Count frequency: Fpclk/1000 = 50 MHz/1000 = 50 KHz */ + putreg32(400, LPC17_MCPWM_LIM0); /* Set the starting duty cycle to 0.25 */ + putreg32(0, LPC17_MCPWM_MAT0); /* Reset the timer */ + + putreg32(100000, LPC17_MCPWM_TC1); /* Count frequency:Fpclk/100000 = 50 MHz/100000 = 500 Hz */ + putreg32(50000, LPC17_MCPWM_LIM1); /* Set the starting duty cycle to 0.5 */ + putreg32(0, LPC17_MCPWM_MAT1); /* Reset the timer */ + + putreg32(1000, LPC17_MCPWM_TC2); /* Count frequency:Fpclk/1000 = 50 MHz/1000 = 50 KHz */ + putreg32(400, LPC17_MCPWM_LIM2); /* Set the starting duty cycle to 0.25 */ + putreg32(0, LPC17_MCPWM_MAT2); /* Reset the timer */ + + putreg32((1 << 2), LPC17_MCPWM_CONCLR); /* Channel 0 polarity set to default */ + putreg32((1 << 10), LPC17_MCPWM_CONCLR); /* Channel 1 polarity set to default */ + putreg32((1 << 18), LPC17_MCPWM_CONCLR); /* Channel 2 polarity set to default */ + + putreg32((1 << 3), LPC17_MCPWM_CONCLR); /* Channel 0 dead time disabled */ + putreg32((1 << 11), LPC17_MCPWM_CONCLR); /* Channel 1 dead time disabled */ + putreg32((1 << 19), LPC17_MCPWM_CONCLR); /* Channel 2 dead time disabled */ + + putreg32((1 << 1), LPC17_MCPWM_CONCLR); /* Channel 0 edge aligned */ + putreg32((1 << 9), LPC17_MCPWM_CONCLR); /* Channel 1 edge aligned */ + putreg32((1 << 17), LPC17_MCPWM_CONCLR); /* Channel 2 edge aligned */ + + putreg32((0xFFFFFFFF), LPC17_MCPWM_CNTCONCLR); /* All channels in counter mode on PCLK */ + + putreg32((1 << 0), LPC17_MCPWM_CONSET); /* Start MCPWM timer0 */ + + leave_critical_section(flags); + pwm_dumpgpio(priv->pincfg, "PWM setup"); + return OK; +} + +/**************************************************************************** + * Name: mcpwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_mcpwmtimer_s *priv = (FAR struct lpc17_mcpwmtimer_s *)dev; + uint32_t pincfg; + + pwmvdbg("TIM%d pincfg: %08x\n", priv->timid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + return OK; +} + +/**************************************************************************** + * Name: mcpwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct lpc17_mcpwmtimer_s *priv = (FAR struct lpc17_mcpwmtimer_s *)dev; + return mcpwm_timer(priv, info); +} + +/**************************************************************************** + * Name: mcpwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int mcpwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_mcpwmtimer_s *priv = (FAR struct lpc17_mcpwmtimer_s *)dev; + uint32_t resetbit; + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + pwmvdbg("TIM%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC17_MCPWM + case 1: + break; +#endif + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where mcpwm_start() can be called. + */ + + leave_critical_section(flags); + + pwmvdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + mcpwm_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: mcpwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int mcpwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct lpc17_mcpwmtimer_s *priv = (FAR struct lpc17_mcpwmtimer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("TIM%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_mcpwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *lpc17_mcpwminitialize(int timer) +{ + FAR struct lpc17_mcpwmtimer_s *lower; + + pwmvdbg("TIM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_LPC17_MCPWM + case 0: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_LPC17_TIMn_PWM, n = 1,...,14 */ diff --git a/arch/arm/src/lpc17xx/lpc17_mpuinit.c b/arch/arm/src/lpc17xx/lpc17_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..9cf561fcf22db8e3bc8972c1835447f115ecbfd5 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_mpuinit.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "lpc17_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void lpc17_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: lpc17_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void lpc17_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/lpc17xx/lpc17_mpuinit.h b/arch/arm/src/lpc17xx/lpc17_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..145789532da7c7b9d2f9e5992edc974c4336a4ee --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_mpuinit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_mpuinit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_MPUINIT_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc17_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc17_mpuinitialize(void); +#else +# define lpc17_mpuinitialize() +#endif + +/**************************************************************************** + * Name: lpc17_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc17_mpu_uheap(uintptr_t start, size_t size); +#else +# define lpc17_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_MPUINIT_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_ohciram.h b/arch/arm/src/lpc17xx/lpc17_ohciram.h new file mode 100644 index 0000000000000000000000000000000000000000..5e039dad7c9afa4a864a757e43d45393cbe46f11 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_ohciram.h @@ -0,0 +1,263 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_ohciram.h + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_OHCIRAM_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_OHCIRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc17_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Default, no-OHCI Case ************************************************************/ +/* Assume that all of AHB SRAM will be available for heap. If this is not true, then + * LPC17_BANK1_HEAPSIZE will be undefined but redefined below. + */ + +#undef LPC17_BANK1_HEAPBASE +#undef LPC17_BANK1_HEAPSIZE +#ifdef LPC17_HAVE_BANK1 +# define LPC17_BANK1_HEAPBASE LPC17_SRAM_BANK1 +# define LPC17_BANK1_HEAPSIZE LPC17_BANK1_SIZE +#endif + +/* Is networking enabled? Is the LPC17xx Ethernet device enabled? Does this chip have + * and Ethernet controlloer? Yes... then we will replace the above default definitions. + */ + +#if defined(CONFIG_USBHOST) && defined(CONFIG_LPC17_USBHOST) && LPC17_NUSBHOST > 0 + +/* OHCI RAM Configuration ***********************************************************/ +/* Is AHB SRAM available? */ + +#ifndef LPC17_HAVE_BANK1 +# error "AHB SRAM Bank1 is not available for OHCI RAM" +#endif + +/* OHCI/Heap Memory Allocation ******************************************************/ +/* Configured Size of the region at the end of AHB SRAM BANK1 set set aside for the + * OHCI. This size must fit within AHB SRAM Bank 1 and also be a multiple of 256 + * bytes. + */ + +#ifndef CONFIG_USBHOST_OHCIRAM_SIZE +# define CONFIG_USBHOST_OHCIRAM_SIZE LPC17_BANK1_SIZE +#endif + +#if CONFIG_USBHOST_OHCIRAM_SIZE > LPC17_BANK1_SIZE +# error "OHCI RAM size cannot exceed the size of AHB SRAM Bank 1" +#endif + +#if (CONFIG_USBHOST_OHCIRAM_SIZE & 0xff) != 0 +# error "OHCI RAM size must be in multiples of 256 bytes" +#endif + +/* Then position the OHCI RAM at the end of AHB SRAM Bank 1 */ + +#define LPC17_OHCIRAM_END (LPC17_SRAM_BANK1 + LPC17_BANK1_SIZE) +#define LPC17_OHCIRAM_BASE (LPC17_OHCIRAM_END - CONFIG_USBHOST_OHCIRAM_SIZE) +#define LPC17_OHCIRAM_SIZE CONFIG_USBHOST_OHCIRAM_SIZE + +/* Determine is there is any meaningful space left at the beginning of AHB Bank 1 + * that could be added to the heap. + */ + +#undef LPC17_BANK1_HEAPBASE +#undef LPC17_BANK1_HEAPSIZE +#if LPC17_OHCIRAM_SIZE < (LPC17_BANK1_SIZE-128) +# define LPC17_BANK1_HEAPBASE LPC17_SRAM_BANK1 +# define LPC17_BANK1_HEAPSIZE (LPC17_BANK1_SIZE - LPC17_OHCIRAM_SIZE) +#endif + +/* Numbers and Sizes of Things ******************************************************/ +/* Fixed size of the OHCI control area */ + +#define LPC17_HCCA_SIZE 256 + +/* Fixed endpoint descriptor size. The actual size required by the hardware is only + * 16 bytes, however, we set aside an additional 16 bytes for for internal use by + * the OHCI host driver. 16-bytes is set aside because the EDs must still be + * aligned to 16-byte boundaries. + */ + +#define LPC17_ED_SIZE 32 + +/* Configurable number of user endpoint descriptors (EDs). This number excludes + * the control endpoint that is always allocated. + */ + +#ifndef CONFIG_USBHOST_NEDS +# define CONFIG_USBHOST_NEDS 2 +#endif + +/* Derived size of user endpoint descriptor (ED) memory. */ + +#define LPC17_EDFREE_SIZE (CONFIG_USBHOST_NEDS * LPC17_ED_SIZE) + +/* Fixed transfer descriptor size. The actual size required by the hardware is only + * 16 bytes, however, we set aside an additional 16 bytes for for internal use by + * the OHCI host driver. 16-bytes is set aside because the TDs must still be + * aligned to 16-byte boundaries. + */ + +#define LPC17_TD_SIZE 32 + +/* Configurable number of user transfer descriptors (TDs). */ + +#ifndef CONFIG_USBHOST_NTDS +# define CONFIG_USBHOST_NTDS 3 +#endif + +#if CONFIG_USBHOST_NTDS < 2 +# error "Insufficent TDs" +#endif + +/* Derived size of user trasnfer descriptor (TD) memory. */ + +#define LPC17_TDFREE_SIZE (CONFIG_USBHOST_NTDS * LPC17_TD_SIZE) + +/* Configurable number of request/descriptor buffers (TDBUFFER) */ + +#ifndef CONFIG_USBHOST_TDBUFFERS +# define CONFIG_USBHOST_TDBUFFERS 2 +#endif + +#if CONFIG_USBHOST_TDBUFFERS < 2 +# error "At least two TD buffers are required" +#endif + +/* Configurable size of a TD buffer */ + +#if CONFIG_USBHOST_TDBUFFERS > 0 && !defined(CONFIG_USBHOST_TDBUFSIZE) +# define CONFIG_USBHOST_TDBUFSIZE 128 +#endif + +#if (CONFIG_USBHOST_TDBUFSIZE & 3) != 0 +# error "TD buffer size must be an even number of 32-bit words" +#endif + +#define LPC17_TBFREE_SIZE (CONFIG_USBHOST_TDBUFFERS * CONFIG_USBHOST_TDBUFSIZE) + +/* Configurable size of an IO buffer. The number of IO buffers will be determined + * by what is left at the end of the BANK1 memory setup aside of OHCI RAM. + */ + +#ifndef CONFIG_USBHOST_IOBUFSIZE +# define CONFIG_USBHOST_IOBUFSIZE 512 +#endif + +#if (CONFIG_USBHOST_IOBUFSIZE & 3) != 0 +# error "IO buffer size must be an even number of 32-bit words" +#endif + +/* OHCI Memory Layout ***************************************************************/ +/* Example: + * Hardware: + * LPC17_SRAM_BANK1 0x20008000 + * LPC17_BANK1_SIZE 16384 + * + * Configuration: + * CONFIG_USBHOST_OHCIRAM_SIZE 1536 + * CONFIG_USBHOST_NEDS 2 + * CONFIG_USBHOST_NTDS 3 + * CONFIG_USBHOST_TDBUFFERS 3 + * CONFIG_USBHOST_TDBUFSIZE 128 + * CONFIG_USBHOST_IOBUFSIZE 512 + * + * Sizes of things + * LPC17_EDFREE_SIZE 64 0x00000040 + * LPC17_TDFREE_SIZE 96 0x00000060 + * LPC17_TBFREE_SIZE 384 0x00000100 + * LPC17_IOFREE_SIZE 512 0x00000200 + * + * Memory Layout + * LPC17_OHCIRAM_END (0x20008000 + 16384) = 0x20084000 + * LPC17_OHCIRAM_BASE (0x2000c000 - 1536) = 0x2000ba00 + * LPC17_OHCIRAM_SIZE 1280 + * LPC17_BANK1_HEAPBASE 0x20008000 + * LPC17_BANK1_HEAPSIZE (16384 - 1280) = 15104 + * + * LPC17_HCCA_BASE 0x20083a00 -- Communications area + * LPC17_TDTAIL_ADDR 0x20083b00 -- Common. pre-allocated tail TD + * LPC17_EDCTRL_ADDR 0x20083b20 -- Pre-allocated ED for EP0 + * LPC17_EDFREE_BASE 0x20083b40 -- Free EDs + * LPC17_TDFREE_BASE 0x20083b80 -- Free TDs + * LPC17_TBFREE_BASE 0x20083be0 -- Free request/descriptor buffers + * LPC17_IOFREE_BASE 0x20083d60 -- Free large I/O buffers + * LPC17_IOBUFFERS (0x20084000 - 0x20083d60) / 512 = 672/512 = 1 + * + * Wasted memory: 672-512 = 160 bytes + */ + +#define LPC17_HCCA_BASE (LPC17_OHCIRAM_BASE) +#define LPC17_TDTAIL_ADDR (LPC17_HCCA_BASE + LPC17_HCCA_SIZE) +#define LPC17_EDCTRL_ADDR (LPC17_TDTAIL_ADDR + LPC17_TD_SIZE) +#define LPC17_EDFREE_BASE (LPC17_EDCTRL_ADDR + LPC17_ED_SIZE) +#define LPC17_TDFREE_BASE (LPC17_EDFREE_BASE + LPC17_EDFREE_SIZE) +#define LPC17_TBFREE_BASE (LPC17_TDFREE_BASE + LPC17_TDFREE_SIZE) +#define LPC17_IOFREE_BASE (LPC17_TBFREE_BASE + LPC17_TBFREE_SIZE) + +#if LPC17_IOFREE_BASE > LPC17_OHCIRAM_END +# error "Insufficient OHCI RAM allocated" +#endif + +/* Finally, use the remainder of the allocated OHCI for IO buffers */ + +#if CONFIG_USBHOST_IOBUFSIZE > 0 +# define LPC17_IOBUFFERS ((LPC17_OHCIRAM_END - LPC17_IOFREE_BASE) / CONFIG_USBHOST_IOBUFSIZE) +#else +# define LPC17_IOBUFFERS 0 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* CONFIG_USBHOST && CONFIG_LPC17_USBHOST && LPC17_NUSBHOST > 0*/ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_OHCIRAM_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_pwm.c b/arch/arm/src/lpc17xx/lpc17_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..4f8c79315c607a6735ed60a78c710389a909f2fb --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_pwm.c @@ -0,0 +1,655 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_pwm.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_pwm.h" +#include "chip/lpc176x_pinconfig.h" +#include "lpc17_gpio.h" +#include "lpc176x_gpio.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_LPC17_PWM1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4 */ +#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ +#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ + +#define TIMTYPE_TIM1 TIMTYPE_ADVANCED + + +#define LER0_EN (1 << 0) +#define LER1_EN (1 << 1) +#define LER2_EN (1 << 2) +#define LER3_EN (1 << 3) +#define LER4_EN (1 << 4) +#define LER5_EN (1 << 5) +#define LER6_EN (1 << 6) +#define PWMENA1 (1 << 9) +#define PWMENA2 (1 << 10) +#define PWMENA3 (1 << 11) +#define PWMENA4 (1 << 12) +#define PWMENA5 (1 << 13) +#define PWMENA6 (1 << 14) +#define TCR_CNT_EN (0x00000001) +#define TCR_RESET (0x00000002) +#define TCR_PWM_EN (0x00000008) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct lpc17_pwmtimer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {0,...,7} */ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint8_t timtype; /* See the TIMTYPE_* definitions */ + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t pwm_getreg(struct lpc17_pwmtimer_s *priv, int offset); +static void pwm_putreg(struct lpc17_pwmtimer_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct lpc17_pwmtimer_s *priv, FAR const char *msg); +#else +# define pwm_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int pwm_timer(FAR struct lpc17_pwmtimer_s *priv, + FAR const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +#ifdef CONFIG_LPC17_PWM1 +static struct lpc17_pwmtimer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channel = CONFIG_LPC17_PWM1_PIN, + .timtype = TIMTYPE_TIM1, + .base = LPC17_PWM1_BASE, + .pincfg = GPIO_PWM1p1_1, + .pclk = (0x1 << 12), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t pwm_getreg(struct lpc17_pwmtimer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_putreg(struct lpc17_pwmtimer_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct lpc17_pwmtimer_s *priv, FAR const char *msg) +{ + pwmvdbg("%s:\n", msg); + pwmvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + pwm_getreg(priv, LPC17_PWM_MR0_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR1_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); +#if defined(CONFIG_LPC17_PWM1) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, LPC17_PWM_MR0_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR1_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } + else +#endif + { + pwmvdbg(" DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, LPC17_PWM_MR2_OFFSET), + pwm_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: pwm_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_timer(FAR struct lpc17_pwmtimer_s *priv, + FAR const struct pwm_info_s *info) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + putreg32(info->frequency, LPC17_PWM1_MR0); /* Set PWMMR0 = number of counts */ + putreg32(info->duty, LPC17_PWM1_MR1); /* Set PWM cycle */ + + putreg32(LER0_EN | LER3_EN, LPC17_PWM1_LER); /* Load Shadow register contents */ + putreg32(PWMENA1, LPC17_PWM1_PCR); /* Enable PWM outputs */ + putreg32(TCR_CNT_EN | TCR_PWM_EN, LPC17_PWM1_TCR); /* Enable PWM Timer */ + + leave_critical_section(flags); + pwm_dumpregs(priv, "After starting"); + return OK; +} + +#ifdef XXXXX +/**************************************************************************** + * Name: pwm_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_interrupt(struct lpc17_pwmtimer_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = pwm_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + pwm_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + return OK; +} + +/**************************************************************************** + * Name: pwm_tim1/8interrupt + * + * Description: + * Handle timer 1 and 8 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_tim1interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm1dev); +} + +/**************************************************************************** + * Name: pwm_set_apb_clock + * + * Description: + * Enable or disable APB clock for the timer peripheral + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void pwm_set_apb_clock(FAR struct lpc17_pwmtimer_s *priv, bool on) +{ + uint32_t en_bit; + uint32_t regaddr; + + /* Determine which timer to configure */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC17_PWM1 + case 1: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM1EN; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for timer */ + + if (on) + { + modifyreg32(regaddr, 0, en_bit); + } + else + { + modifyreg32(regaddr, en_bit, 0); + } +} +#endif + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_pwmtimer_s *priv = (FAR struct lpc17_pwmtimer_s *)dev; + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Power on the pwm peripheral */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCPWM1; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Select clock for the pwm peripheral */ + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~(0x3 << 12); /* PCLK_MC peripheral clk = CCLK = 12.5 MHz */ + regval |= (0x1 << 12); /* PCLK_MC peripheral clk = CCLK = 12.5 MHz */ + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + priv->pclk = (0x1 << 12); + + /* Configure the output pin */ + + lpc17_configgpio(GPIO_PWM1p1_1); + + putreg32(1, LPC17_PWM1_PR); /* Prescaler count frequency: Fpclk/1 */ + putreg32(1 << 1, LPC17_PWM1_MCR); /* Reset on match register MR0 */ + + leave_critical_section(flags); + pwm_dumpgpio(priv->pincfg, "PWM setup"); + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_pwmtimer_s *priv = (FAR struct lpc17_pwmtimer_s *)dev; + uint32_t pincfg; + + pwmvdbg("TIM%d pincfg: %08x\n", priv->timid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct lpc17_pwmtimer_s *priv = (FAR struct lpc17_pwmtimer_s *)dev; + return pwm_timer(priv, info); +} + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_pwmtimer_s *priv = (FAR struct lpc17_pwmtimer_s *)dev; + uint32_t resetbit; + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + pwmvdbg("TIM%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC17_PWM1 + case 1: + break; +#endif + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where pwm_start() can be called. + */ + + leave_critical_section(flags); + + pwmvdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + pwm_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct lpc17_pwmtimer_s *priv = (FAR struct lpc17_pwmtimer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("TIM%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *lpc17_pwminitialize(int timer) +{ + FAR struct lpc17_pwmtimer_s *lower; + + pwmvdbg("TIM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_LPC17_PWM1 + case 0: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_LPC17_TIMn_PWM, n = 1,...,14 */ diff --git a/arch/arm/src/lpc17xx/lpc17_pwm.h b/arch/arm/src/lpc17xx/lpc17_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f26cea099010c6bcdf5f81412c55cbc1dea886 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_pwm.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_pwm.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_PWM_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_pwm.h" +#include "chip/lpc17_mcpwm.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_PWM_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_qei.h b/arch/arm/src/lpc17xx/lpc17_qei.h new file mode 100644 index 0000000000000000000000000000000000000000..e2515b10286f7c8507db2507e4b6c2087ae8ec5e --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_qei.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_qei.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_QEI_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_QEI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_qei.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_QEI_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_rit.h b/arch/arm/src/lpc17xx/lpc17_rit.h new file mode 100644 index 0000000000000000000000000000000000000000..4c0949a467ec66020286104f3f67b0fdce37f697 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_rit.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_rit.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_RIT_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_RIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_rit.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_RIT_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_rtc.h b/arch/arm/src/lpc17xx/lpc17_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..1ee2ea91b2776e50103f7aed726d625dbb7e5d5d --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_rtc.h @@ -0,0 +1,86 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_rtc.h + * + * Copyright (C) 2010, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_RTC_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_rtc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* The form of an alarm callback */ + +typedef void (*alarmcb_t)(void); + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct timespec; +int lpc17_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); +#endif + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_RTC_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_sdcard.c b/arch/arm/src/lpc17xx/lpc17_sdcard.c new file mode 100644 index 0000000000000000000000000000000000000000..e6cb9fafd7e117537fe3b192aa14db5255c3601b --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_sdcard.c @@ -0,0 +1,2830 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_sdcard.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "lpc17_gpdma.h" +#include "lpc17_gpio.h" +#include "lpc17_sdcard.h" + +#include "chip/lpc17_syscon.h" +#include "chip/lpc17_pinconfig.h" + +#ifdef CONFIG_LPC17_SDCARD + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* Required system configuration options: + * + * CONFIG_ARCH_DMA - Enable architecture-specific DMA subsystem + * initialization. Required if CONFIG_SDIO_DMA is enabled. + * CONFIG_LPC17_GPDMA - Enable LPC17XX GPDMA support. Required if + * CONFIG_SDIO_DMA is enabled + * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. + * + * Driver-specific configuration options: + * + * CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking + * APIs to manage concurrent accesses on the SD card bus. This is not + * needed for the simple case of a single SD card, for example. + * CONFIG_SDIO_DMA - Enable SD card DMA. This is a marginally optional. + * For most usages, SD accesses will cause data overruns if used without DMA. + * NOTE the above system DMA configuration options. + * CONFIG_SDIO_WIDTH_D1_ONLY - This may be selected to force the driver + * operate with only a single data line (the default is to use all + * 4 SD data lines). + * CONFIG_DEBUG_SDIO - Enables some very low-level debug output + * This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_VERBOSE + */ + +#if defined(CONFIG_SDIO_DMA) && !defined(CONFIG_LPC17_GPDMA) +# warning "CONFIG_SDIO_DMA support requires CONFIG_LPC17_GPDMA" +#endif + +#ifndef CONFIG_SDIO_DMA +# warning "Large Non-DMA transfer may result in RX overrun failures" +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG) +# undef CONFIG_DEBUG_SDIO +#endif + +/* Friendly CLKCR bit re-definitions ****************************************/ + +/* Mode dependent settings. These depend on clock devisor settings that must + * be defined in the board-specific board.h header file: SDCARD_INIT_CLKDIV, + * SDCARD_MMCXFR_CLKDIV, and SDCARD_SDXFR_CLKDIV. + */ + +#define LPC17_CLCKCR_INIT (SDCARD_INIT_CLKDIV | SDCARD_CLOCK_WIDBUS_D1) +#define SDCARD_CLOCK_MMCXFR (SDCARD_MMCXFR_CLKDIV | SDCARD_CLOCK_WIDBUS_D1) +#define SDCARD_CLOCK_SDXFR (SDCARD_SDXFR_CLKDIV | SDCARD_CLOCK_WIDBUS_D1) +#define SDCARD_CLOCK_SDWIDEXFR (SDCARD_SDXFR_CLKDIV | SDCARD_CLOCK_WIDBUS_D4) + +/* Timing */ + +#define SDCARD_CMDTIMEOUT (100000) +#define SDCARD_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define SDCARD_DTIMER_DATATIMEOUT (0x000fffff) + +/* DMA channel/stream configuration register settings. The following + * must be selected. The DMA driver will select the remaining fields. + * + * - 32-bit DMA + * - Memory increment + * - Direction (memory-to-peripheral, peripheral-to-memory) + * - Memory burst size (F4 only) + */ + +/* DMA control register settings. All CONTROL register fields need to be + * specified except for the transfer size which is passed as a separate + * parameter and for the terminal count interrupt enable bit which is + * controlled by the driver. + */ + +#define SDCARD_RXDMA32_CONTROL (DMACH_CONTROL_SBSIZE_8 | DMACH_CONTROL_DBSIZE_8 | \ + DMACH_CONTROL_SWIDTH_32BIT | DMACH_CONTROL_DWIDTH_32BIT | \ + DMACH_CONTROL_DI) +#define SDCARD_TXDMA32_CONTROL (DMACH_CONTROL_SBSIZE_8 | DMACH_CONTROL_DBSIZE_8 | \ + DMACH_CONTROL_SWIDTH_32BIT | DMACH_CONTROL_DWIDTH_32BIT | \ + DMACH_CONTROL_SI) + +/* DMA configuration register settings. Only the SRCPER, DSTPER, and + * XFRTTYPE fields of the CONFIG register need be specified. + */ + +#define SDCARD_RXDMA32_CONFIG (DMACH_CONFIG_SRCPER_SDCARD | DMACH_CONFIG_XFRTYPE_P2M_SC) +#define SDCARD_TXDMA32_CONFIG (DMACH_CONFIG_DSTPER_SDCARD | DMACH_CONFIG_XFRTYPE_M2P_DC) + +/* FIFO sizes */ + +#define SDCARD_HALFFIFO_WORDS (8) +#define SDCARD_HALFFIFO_BYTES (8*4) + +/* Data transfer interrupt mask bits */ + +#define SDCARD_RECV_MASK (SDCARD_MASK0_DCRCFAILIE | SDCARD_MASK0_DTIMEOUTIE | \ + SDCARD_MASK0_DATAENDIE | SDCARD_MASK0_RXOVERRIE | \ + SDCARD_MASK0_RXFIFOHFIE | SDCARD_MASK0_STBITERRIE) +#define SDCARD_SEND_MASK (SDCARD_MASK0_DCRCFAILIE | SDCARD_MASK0_DTIMEOUTIE | \ + SDCARD_MASK0_DATAENDIE | SDCARD_MASK0_TXUNDERRIE | \ + SDCARD_MASK0_TXFIFOHEIE | SDCARD_MASK0_STBITERRIE) +#define SDCARD_DMARECV_MASK (SDCARD_MASK0_DCRCFAILIE | SDCARD_MASK0_DTIMEOUTIE | \ + SDCARD_MASK0_DATAENDIE | SDCARD_MASK0_RXOVERRIE | \ + SDCARD_MASK0_STBITERRIE) +#define SDCARD_DMASEND_MASK (SDCARD_MASK0_DCRCFAILIE | SDCARD_MASK0_DTIMEOUTIE | \ + SDCARD_MASK0_DATAENDIE | SDCARD_MASK0_TXUNDERRIE | \ + SDCARD_MASK0_STBITERRIE) + +/* Event waiting interrupt mask bits */ + +#define SDCARD_CMDDONE_STA (SDCARD_STATUS_CMDSENT) +#define SDCARD_RESPDONE_STA (SDCARD_STATUS_CTIMEOUT | SDCARD_STATUS_CCRCFAIL | \ + SDCARD_STATUS_CMDREND) +#define SDCARD_XFRDONE_STA (0) + +#define SDCARD_CMDDONE_MASK (SDCARD_MASK0_CMDSENTIE) +#define SDCARD_RESPDONE_MASK (SDCARD_MASK0_CCRCFAILIE | SDCARD_MASK0_CTIMEOUTIE | \ + SDCARD_MASK0_CMDRENDIE) +#define SDCARD_XFRDONE_MASK (0) + +#define SDCARD_CMDDONE_ICR (SDCARD_CLEAR_CMDSENTC) +#define SDCARD_RESPDONE_ICR (SDCARD_CLEAR_CTIMEOUTC | SDCARD_CLEAR_CCRCFAILC | \ + SDCARD_CLEAR_CMDRENDC) +#define SDCARD_XFRDONE_ICR (SDCARD_CLEAR_DATAENDC | SDCARD_CLEAR_DCRCFAILC | \ + SDCARD_CLEAR_DTIMEOUTC | SDCARD_CLEAR_RXOVERRC | \ + SDCARD_CLEAR_TXUNDERRC | SDCARD_CLEAR_STBITERRC) + +#define SDCARD_WAITALL_ICR (SDCARD_CMDDONE_ICR | SDCARD_RESPDONE_ICR | \ + SDCARD_XFRDONE_ICR) + +/* Let's wait until we have both SD card transfer complete and DMA complete. */ + +#define SDCARD_XFRDONE_FLAG (1) +#define SDCARD_DMADONE_FLAG (2) +#define SDCARD_ALLDONE (3) + +/* Register logging support */ + +#ifdef CONFIG_DEBUG_SDIO +# ifdef CONFIG_SDIO_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define DEBUG_NSAMPLES 5 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define DEBUG_NSAMPLES 3 +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure defines the state of the LPC17XX SD card interface */ + +struct lpc17_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SD card interface */ + + /* LPC17XX-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + size_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + volatile uint8_t xfrflags; /* Used to synchronize SD card and DMA completion events */ + bool dmamode; /* true: DMA mode transfer */ + DMA_HANDLE dma; /* Handle for DMA channel */ +#endif +}; + +/* Register logging support */ + +#ifdef CONFIG_DEBUG_SDIO +struct lpc17_sdcard_regs_s +{ + uint8_t pwr; + uint16_t clkcr; + uint16_t dctrl; + uint32_t dtimer; + uint32_t dlen; + uint32_t dcount; + uint32_t sta; + uint32_t mask; + uint32_t fifocnt; +}; + +struct lpc17_sampleregs_s +{ + struct lpc17_sdcard_regs_s sdcard; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + struct lpc17_dmaregs_s dma; +#endif +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void lpc17_takesem(struct lpc17_dev_s *priv); +#define lpc17_givesem(priv) (sem_post(&priv->waitsem)) +static inline void lpc17_setclock(uint32_t clkcr); +static void lpc17_configwaitints(struct lpc17_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void lpc17_configxfrints(struct lpc17_dev_s *priv, uint32_t xfrmask); +static void lpc17_setpwrctrl(uint32_t pwrctrl); +static inline uint32_t lpc17_getpwrctrl(void); + +/* DMA Helpers **************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_sampleinit(void); +static void lpc17_sdcard_sample(struct lpc17_sdcard_regs_s *regs); +static void lpc17_sample(struct lpc17_dev_s *priv, int index); +static void lpc17_sdcard_dump(struct lpc17_sdcard_regs_s *regs, const char *msg); +static void lpc17_dumpsample(struct lpc17_dev_s *priv, + struct lpc17_sampleregs_s *regs, const char *msg); +static void lpc17_dumpsamples(struct lpc17_dev_s *priv); +#else +# define lpc17_sampleinit() +# define lpc17_sample(priv,index) +# define lpc17_dumpsamples(priv) +#endif + +#ifdef CONFIG_SDIO_DMA +static void lpc17_dmacallback(DMA_HANDLE handle, void *arg, int status); +#endif + +/* Data Transfer Helpers ****************************************************/ + +static uint8_t lpc17_log2(uint16_t value); +static void lpc17_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl); +static void lpc17_datadisable(void); +static void lpc17_sendfifo(struct lpc17_dev_s *priv); +static void lpc17_recvfifo(struct lpc17_dev_s *priv); +static void lpc17_eventtimeout(int argc, uint32_t arg); +static void lpc17_endwait(struct lpc17_dev_s *priv, sdio_eventset_t wkupevent); +static void lpc17_endtransfer(struct lpc17_dev_s *priv, sdio_eventset_t wkupevent); + +/* Interrupt Handling *******************************************************/ + +static int lpc17_interrupt(int irq, void *context); + +/* SD Card Interface Methods ************************************************/ + +/* Mutual exclusion */ + +#ifdef CONFIG_SDIO_MUXBUS +static int lpc17_lock(FAR struct sdio_dev_s *dev, bool lock); +#endif + +/* Initialization/setup */ + +static void lpc17_reset(FAR struct sdio_dev_s *dev); +static uint8_t lpc17_status(FAR struct sdio_dev_s *dev); +static void lpc17_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void lpc17_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int lpc17_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int lpc17_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static int lpc17_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int lpc17_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, uint32_t nbytes); +static int lpc17_cancel(FAR struct sdio_dev_s *dev); + +static int lpc17_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int lpc17_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int lpc17_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int lpc17_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int lpc17_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void lpc17_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + lpc17_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void lpc17_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int lpc17_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool lpc17_dmasupported(FAR struct sdio_dev_s *dev); +static int lpc17_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +static int lpc17_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void lpc17_callback(void *arg); +static void lpc17_default(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct lpc17_dev_s g_scard_dev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = lpc17_lock, +#endif + .reset = lpc17_reset, + .status = lpc17_status, + .widebus = lpc17_widebus, + .clock = lpc17_clock, + .attach = lpc17_attach, + .sendcmd = lpc17_sendcmd, + .recvsetup = lpc17_recvsetup, + .sendsetup = lpc17_sendsetup, + .cancel = lpc17_cancel, + .waitresponse = lpc17_waitresponse, + .recvR1 = lpc17_recvshortcrc, + .recvR2 = lpc17_recvlong, + .recvR3 = lpc17_recvshort, + .recvR4 = lpc17_recvnotimpl, + .recvR5 = lpc17_recvnotimpl, + .recvR6 = lpc17_recvshortcrc, + .recvR7 = lpc17_recvshort, + .waitenable = lpc17_waitenable, + .eventwait = lpc17_eventwait, + .callbackenable = lpc17_callbackenable, + .registercallback = lpc17_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = lpc17_dmasupported, + .dmarecvsetup = lpc17_dmarecvsetup, + .dmasendsetup = lpc17_dmasendsetup, +#endif + }, +}; + +/* Register logging support */ + +#ifdef CONFIG_DEBUG_SDIO +static struct lpc17_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: lpc17_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SD card device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_takesem(struct lpc17_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: lpc17_setclock + * + * Description: + * Modify oft-changed bits in the CLKCR register. Only the following bit- + * fields are changed: + * + * CLKDIV, PWRSAV, BYPASS, and WIDBUS + * + * Input Parameters: + * clkcr - A new CLKCR setting for the above mentions bits (other bits + * are ignored. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void lpc17_setclock(uint32_t clkcr) +{ + uint32_t regval = getreg32(LPC17_SDCARD_CLOCK); + + /* Clear CLKDIV, PWRSAV, BYPASS, and WIDBUS bits */ + + regval &= ~(SDCARD_CLOCK_CLKDIV_MASK | SDCARD_CLOCK_PWRSAV | + SDCARD_CLOCK_BYPASS | SDCARD_CLOCK_WIDBUS | + SDCARD_CLOCK_CLKEN); + + /* Replace with user provided settings */ + + clkcr &= (SDCARD_CLOCK_CLKDIV_MASK | SDCARD_CLOCK_PWRSAV | + SDCARD_CLOCK_BYPASS | SDCARD_CLOCK_WIDBUS | + SDCARD_CLOCK_CLKEN); + + regval |= clkcr; + putreg32(regval, LPC17_SDCARD_CLOCK); + + fvdbg("CLKCR: %08x PWR: %08x\n", + getreg32(LPC17_SDCARD_CLOCK), getreg32(LPC17_SDCARD_PWR)); +} + +/**************************************************************************** + * Name: lpc17_configwaitints + * + * Description: + * Enable/disable SD card interrupts needed to suport the wait function + * + * Input Parameters: + * priv - A reference to the SD card device state structure + * waitmask - The set of bits in the SD card MASK register to set + * waitevents - Waited for events + * wkupevent - Wake-up events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_configwaitints(struct lpc17_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + + flags = enter_critical_section(); + priv->waitevents = waitevents; + priv->wkupevent = wkupevent; + priv->waitmask = waitmask; +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + putreg32(priv->xfrmask | priv->waitmask, LPC17_SDCARD_MASK0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_configxfrints + * + * Description: + * Enable SD card interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the SD card device state structure + * xfrmask - The set of bits in the SD card MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_configxfrints(struct lpc17_dev_s *priv, uint32_t xfrmask) +{ + irqstate_t flags; + flags = enter_critical_section(); + priv->xfrmask = xfrmask; + putreg32(priv->xfrmask | priv->waitmask, LPC17_SDCARD_MASK0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_setpwrctrl + * + * Description: + * Change the PWRCTRL field of the SD card POWER register to turn the SD card + * ON or OFF + * + * Input Parameters: + * clkcr - A new PWRCTRL setting + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_setpwrctrl(uint32_t pwrctrl) +{ + uint32_t regval; + + /* Set the new value of the PWRCTRL field of the PWR register. Also, as a + * side-effect, clear the OPENDRAIN and ROD bits as well. + */ + + regval = getreg32(LPC17_SDCARD_PWR); + regval &= ~(SDCARD_PWR_CTRL_MASK | SDCARD_PWR_OPENDRAIN | SDCARD_PWR_ROD); + regval |= pwrctrl; + putreg32(regval, LPC17_SDCARD_PWR); +} + +/**************************************************************************** + * Name: lpc17_getpwrctrl + * + * Description: + * Return the current value of the the PWRCTRL field of the SD card P + * register. This function can be used to see if the SD card is powered ON + * or OFF + * + * Input Parameters: + * None + * + * Returned Value: + * The current value of the the PWRCTRL field of the SD card PWR register. + * + ****************************************************************************/ + +static inline uint32_t lpc17_getpwrctrl(void) +{ + /* Extract and return the PWRCTRL field of the PWR register. */ + + return getreg32(LPC17_SDCARD_PWR) & SDCARD_PWR_CTRL_MASK; +} + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_sampleinit + * + * Description: + * Setup prior to collecting DMA samples + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_sampleinit(void) +{ + memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct lpc17_sampleregs_s)); +} +#endif + +/**************************************************************************** + * Name: lpc17_sdcard_sample + * + * Description: + * Sample SD card registers + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_sdcard_sample(struct lpc17_sdcard_regs_s *regs) +{ + regs->pwr = (uint8_t)getreg32(LPC17_SDCARD_PWR); + regs->clkcr = (uint16_t)getreg32(LPC17_SDCARD_CLOCK); + regs->dctrl = (uint16_t)getreg32(LPC17_SDCARD_DCTRL); + regs->dtimer = getreg32(LPC17_SDCARD_DTIMER); + regs->dlen = getreg32(LPC17_SDCARD_DLEN); + regs->dcount = getreg32(LPC17_SDCARD_DCOUNT); + regs->sta = getreg32(LPC17_SDCARD_STATUS); + regs->mask = getreg32(LPC17_SDCARD_MASK0); + regs->fifocnt = getreg32(LPC17_SDCARD_FIFOCNT); +} +#endif + +/**************************************************************************** + * Name: lpc17_sample + * + * Description: + * Sample SD card/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_sample(struct lpc17_dev_s *priv, int index) +{ + struct lpc17_sampleregs_s *regs = &g_sampleregs[index]; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + lpc17_dmasample(priv->dma, ®s->dma); + } +#endif + lpc17_sdcard_sample(®s->sdcard); +} +#endif + +/**************************************************************************** + * Name: lpc17_sdcard_dump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_sdcard_dump(struct lpc17_sdcard_regs_s *regs, const char *msg) +{ + fdbg("SD Card Registers: %s\n", msg); + fdbg(" POWER[%08x]: %08x\n", LPC17_SDCARD_PWR, regs->pwr); + fdbg(" CLKCR[%08x]: %08x\n", LPC17_SDCARD_CLOCK, regs->clkcr); + fdbg(" DCTRL[%08x]: %08x\n", LPC17_SDCARD_DCTRL, regs->dctrl); + fdbg(" DTIMER[%08x]: %08x\n", LPC17_SDCARD_DTIMER, regs->dtimer); + fdbg(" DLEN[%08x]: %08x\n", LPC17_SDCARD_DLEN, regs->dlen); + fdbg(" DCOUNT[%08x]: %08x\n", LPC17_SDCARD_DCOUNT, regs->dcount); + fdbg(" STA[%08x]: %08x\n", LPC17_SDCARD_STATUS, regs->sta); + fdbg(" MASK[%08x]: %08x\n", LPC17_SDCARD_MASK0, regs->mask); + fdbg("FIFOCNT[%08x]: %08x\n", LPC17_SDCARD_FIFOCNT, regs->fifocnt); +} +#endif + +/**************************************************************************** + * Name: lpc17_dumpsample + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_dumpsample(struct lpc17_dev_s *priv, + struct lpc17_sampleregs_s *regs, const char *msg) +{ +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + lpc17_dmadump(priv->dma, ®s->dma, msg); + } +#endif + lpc17_sdcard_dump(®s->sdcard, msg); +} +#endif + +/**************************************************************************** + * Name: lpc17_dumpsamples + * + * Description: + * Dump all sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SDIO +static void lpc17_dumpsamples(struct lpc17_dev_s *priv) +{ + lpc17_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + lpc17_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); + } +#endif + lpc17_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup"); + lpc17_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer"); +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + lpc17_dumpsample(priv, &g_sampleregs[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); + } +#endif +} +#endif + +/**************************************************************************** + * Name: lpc17_dmacallback + * + * Description: + * Called when SD card DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static void lpc17_dmacallback(DMA_HANDLE handle, void *arg, int status) +{ + FAR struct lpc17_dev_s *priv = (FAR struct lpc17_dev_s *)arg; + DEBUGASSERT(priv->dmamode); + sdio_eventset_t result; + + /* In the normal case, SD card appears to handle the End-Of-Transfer interrupt + * first with the End-Of-DMA event occurring significantly later. On + * transfer errors, however, the DMA error will occur before the End-of- + * Transfer. + */ + + lpc17_sample((struct lpc17_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); + + /* Get the result of the DMA transfer */ + + if (status < 0) + { + flldbg("DMA error %d, remaining: %d\n", status, priv->remaining); + result = SDIOWAIT_ERROR; + } + else + { + result = SDIOWAIT_TRANSFERDONE; + } + + /* Then terminate the transfer if this completes all of the steps in the + * transfer OR if a DMA error occurred. In the non-error case, we should + * already have the SD card transfer done interrupt. If not, the transfer + * will appropriately time out. + */ + + priv->xfrflags |= SDCARD_DMADONE_FLAG; + if (priv->xfrflags == SDCARD_ALLDONE || result == SDIOWAIT_ERROR) + { + lpc17_endtransfer(priv, result); + } +} +#endif + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_log2 + * + * Description: + * Take (approximate) log base 2 of the provided number (Only works if the + * provided number is a power of 2). + * + ****************************************************************************/ + +static uint8_t lpc17_log2(uint16_t value) +{ + uint8_t log2 = 0; + + /* 0000 0000 0000 0001 -> return 0, + * 0000 0000 0000 001x -> return 1, + * 0000 0000 0000 01xx -> return 2, + * 0000 0000 0000 1xxx -> return 3, + * ... + * 1xxx xxxx xxxx xxxx -> return 15, + */ + + DEBUGASSERT(value > 0); + while (value != 1) + { + value >>= 1; + log2++; + } + + return log2; +} + +/**************************************************************************** + * Name: lpc17_dataconfig + * + * Description: + * Configure the SD card data path for the next data transfer + * + ****************************************************************************/ + +static void lpc17_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) +{ + uint32_t regval = 0; + + /* Enable data path */ + + putreg32(timeout, LPC17_SDCARD_DTIMER); /* Set DTIMER */ + putreg32(dlen, LPC17_SDCARD_DLEN); /* Set DLEN */ + + /* Configure DCTRL DTDIR, DTMODE, and DBLOCKSIZE fields and set the DTEN + * field + */ + + regval = getreg32(LPC17_SDCARD_DCTRL); + regval &= ~(SDCARD_DCTRL_DTDIR | SDCARD_DCTRL_DTMODE | + SDCARD_DCTRL_DBLOCKSIZE_MASK); + dctrl &= (SDCARD_DCTRL_DTDIR | SDCARD_DCTRL_DTMODE | + SDCARD_DCTRL_DBLOCKSIZE_MASK); + regval |= (dctrl | SDCARD_DCTRL_DTEN); + putreg32(regval, LPC17_SDCARD_DCTRL); +} + +/**************************************************************************** + * Name: lpc17_datadisable + * + * Description: + * Disable the SD card data path setup by lpc17_dataconfig() and + * disable DMA. + * + ****************************************************************************/ + +static void lpc17_datadisable(void) +{ + uint32_t regval; + + /* Disable the data path */ + + putreg32(SDCARD_DTIMER_DATATIMEOUT, LPC17_SDCARD_DTIMER); /* Reset DTIMER */ + putreg32(0, LPC17_SDCARD_DLEN); /* Reset DLEN */ + + /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */ + + regval = getreg32(LPC17_SDCARD_DCTRL); + regval &= ~(SDCARD_DCTRL_DTEN | SDCARD_DCTRL_DTDIR | SDCARD_DCTRL_DTMODE | + SDCARD_DCTRL_DMAEN | SDCARD_DCTRL_DBLOCKSIZE_MASK); + putreg32(regval, LPC17_SDCARD_DCTRL); +} + +/**************************************************************************** + * Name: lpc17_sendfifo + * + * Description: + * Send SD card data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SD card device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_sendfifo(struct lpc17_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is more data to be sent and the RX FIFO is not full */ + + while (priv->remaining > 0 && + (getreg32(LPC17_SDCARD_STATUS) & SDCARD_STATUS_TXFIFOF) == 0) + { + /* Is there a full word remaining in the user buffer? */ + + if (priv->remaining >= sizeof(uint32_t)) + { + /* Yes, transfer the word to the TX FIFO */ + + data.w = *priv->buffer++; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer just the bytes remaining in the user buffer, + * padding with zero as necessary to extend to a full word. + */ + + uint8_t *ptr = (uint8_t *)priv->remaining; + int i; + + data.w = 0; + for (i = 0; i < priv->remaining; i++) + { + data.b[i] = *ptr++; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + + /* Put the word in the FIFO */ + + putreg32(data.w, LPC17_SDCARD_FIFO); + } +} + +/**************************************************************************** + * Name: lpc17_recvfifo + * + * Description: + * Receive SD card data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SD card device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_recvfifo(struct lpc17_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is space to store the data and there is more + * data available in the RX FIFO. + */ + + while (priv->remaining > 0 && + (getreg32(LPC17_SDCARD_STATUS) & SDCARD_STATUS_RXDAVL) != 0) + { + /* Read the next word from the RX FIFO */ + + data.w = getreg32(LPC17_SDCARD_FIFO); + if (priv->remaining >= sizeof(uint32_t)) + { + /* Transfer the whole word to the user buffer */ + + *priv->buffer++ = data.w; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* Transfer any trailing fractional word */ + + uint8_t *ptr = (uint8_t *)priv->buffer; + int i; + + for (i = 0; i < priv->remaining; i++) + { + *ptr++ = data.b[i]; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + } +} + +/**************************************************************************** + * Name: lpc17_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void lpc17_eventtimeout(int argc, uint32_t arg) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)arg; + + /* There is always race conditions with timer expirations. */ + + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + + /* Is a data transfer complete event expected? */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + lpc17_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("Timeout: remaining: %d\n", priv->remaining); + } +} + +/**************************************************************************** + * Name: lpc17_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the SD card device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void lpc17_endwait(struct lpc17_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts */ + + lpc17_configwaitints(priv, 0, 0, wkupevent); + + /* Wake up the waiting thread */ + + lpc17_givesem(priv); +} + +/**************************************************************************** + * Name: lpc17_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the SD card interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the SD card device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void lpc17_endtransfer(struct lpc17_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + lpc17_configxfrints(priv, 0); + + /* Clearing pending interrupt status on all transfer related interrupts */ + + putreg32(SDCARD_XFRDONE_ICR, LPC17_SDCARD_CLEAR); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* DMA debug instrumentation */ + + lpc17_sample(priv, SAMPLENDX_END_TRANSFER); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + lpc17_dmastop(priv->dma); + } +#endif + + /* Mark the transfer finished */ + + priv->remaining = 0; + + /* Is a thread wait for these data transfer complete events? */ + + if ((priv->waitevents & wkupevent) != 0) + { + /* Yes.. wake up any waiting threads */ + + lpc17_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Interrrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_interrupt + * + * Description: + * SD card interrupt handler + * + * Input Parameters: + * dev - An instance of the SD card device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int lpc17_interrupt(int irq, void *context) +{ + struct lpc17_dev_s *priv = &g_scard_dev; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. Check the SD card status + * register. Mask out all bits that don't correspond to enabled + * interrupts. (This depends on the fact that bits are ordered + * the same in both the STA and MASK register). If there are non-zero + * bits remaining, then we have work to do here. + */ + + while ((enabled = getreg32(LPC17_SDCARD_STATUS) & getreg32(LPC17_SDCARD_MASK0)) != 0) + { + /* Handle in progress, interrupt driven data transfers ****************/ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { +#ifdef CONFIG_SDIO_DMA + if (!priv->dmamode) +#endif + { + /* Is the RX FIFO half full or more? Is so then we must be + * processing a receive transaction. + */ + + if ((pending & SDCARD_STATUS_RXFIFOHF) != 0) + { + /* Receive data from the RX FIFO */ + + lpc17_recvfifo(priv); + } + + /* Otherwise, Is the transmit FIFO half empty or less? If so we must + * be processing a send transaction. NOTE: We can't be processing + * both! + */ + + else if ((pending & SDCARD_STATUS_TXFIFOHE) != 0) + { + /* Send data via the TX FIFO */ + + lpc17_sendfifo(priv); + } + } + + /* Handle data end events */ + + if ((pending & SDCARD_STATUS_DATAEND) != 0) + { + /* Handle any data remaining the RX FIFO. If the RX FIFO is + * less than half full at the end of the transfer, then no + * half-full interrupt will be received. + */ + + /* Was this transfer performed in DMA mode? */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Yes.. Terminate the transfers only if the DMA has also + * finished. + */ + + priv->xfrflags |= SDCARD_XFRDONE_FLAG; + if (priv->xfrflags == SDCARD_ALLDONE) + { + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + + /* Otherwise, just disable futher transfer interrupts and + * wait for the DMA complete event. + */ + + else + { + lpc17_configxfrints(priv, 0); + } + } + else +#endif + { + /* Receive data from the RX FIFO */ + + lpc17_recvfifo(priv); + + /* Then terminate the transfer */ + + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle data block send/receive CRC failure */ + + else if ((pending & SDCARD_STATUS_DCRCFAIL) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining); + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle data timeout error */ + + else if ((pending & SDCARD_STATUS_DTIMEOUT) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data timeout, remaining: %d\n", priv->remaining); + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + + /* Handle RX FIFO overrun error */ + + else if ((pending & SDCARD_STATUS_RXOVERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining); + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle TX FIFO underrun error */ + + else if ((pending & SDCARD_STATUS_TXUNDERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining); + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle start bit error */ + + else if ((pending & SDCARD_STATUS_STBITERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Start bit, remaining: %d\n", priv->remaining); + lpc17_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + + /* Handle wait events *************************************************/ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + /* Is this a response completion event? */ + + if ((pending & SDCARD_RESPDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for response done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + lpc17_endwait(priv, SDIOWAIT_RESPONSEDONE); + } + } + + /* Is this a command completion event? */ + + if ((pending & SDCARD_CMDDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for command done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + lpc17_endwait(priv, SDIOWAIT_CMDDONE); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * SD card Interface Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_lock + * + * Description: + * Locks the bus. Function calls low-level multiplexed bus routines to + * resolve bus requests and acknowledgment issues. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * lock - TRUE to lock, FALSE to unlock. + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_MUXBUS +static int lpc17_lock(FAR struct sdio_dev_s *dev, bool lock) +{ + /* Single SD card instance so there is only one possibility. The multiplex + * bus is part of board support package. + */ + + lpc17_muxbus_sdio_lock(lock); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc17_reset + * + * Description: + * Reset the SD card controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct lpc17_dev_s *priv = (FAR struct lpc17_dev_s *)dev; + irqstate_t flags; + uint32_t regval; + + /* Disable clocking */ + + flags = enter_critical_section(); + + /* Disable the SD Interface */ + + regval = getreg32(LPC17_SDCARD_CLOCK); + regval &= ~SDCARD_CLOCK_CLKEN; + putreg32(regval, LPC17_SDCARD_CLOCK); + + lpc17_setpwrctrl(SDCARD_PWR_CTRL_OFF); + + /* Put SD card registers in their default, reset state */ + + lpc17_default(); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; /* Used to synchronize SD card and DMA completion events */ +#endif + + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->buffer = 0; /* Address of current R/W buffer */ + priv->remaining = 0; /* Number of bytes remaining in the transfer */ + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; /* true: DMA mode transfer */ +#endif + + /* Configure and enable the SD card peripheral */ + + lpc17_setclock(LPC17_CLCKCR_INIT | SDCARD_CLOCK_CLKEN); + lpc17_setpwrctrl(SDCARD_PWR_CTRL_ON); + leave_critical_section(flags); + + fvdbg("CLCKR: %08x POWER: %08x\n", + getreg32(LPC17_SDCARD_CLOCK), getreg32(LPC17_SDCARD_PWR)); +} + +/**************************************************************************** + * Name: lpc17_status + * + * Description: + * Get SD card status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see lpc17_status_* defines) + * + ****************************************************************************/ + +static uint8_t lpc17_status(FAR struct sdio_dev_s *dev) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: lpc17_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + priv->widebus = wide; +} + +/**************************************************************************** + * Name: lpc17_clock + * + * Description: + * Enable/disable SD card clocking + * + * Input Parameters: + * dev - An instance of the SD card device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t clkcr; + + switch (rate) + { + /* Disable clocking (with default ID mode divisor) */ + + default: + case CLOCK_SDIO_DISABLED: + clkcr = LPC17_CLCKCR_INIT; + return; + + /* Enable in initial ID mode clocking (<400KHz) */ + + case CLOCK_IDMODE: + clkcr = (LPC17_CLCKCR_INIT | SDCARD_CLOCK_CLKEN); + break; + + /* Enable in MMC normal operation clocking */ + + case CLOCK_MMC_TRANSFER: + clkcr = (SDCARD_CLOCK_MMCXFR | SDCARD_CLOCK_CLKEN); + lpc17_setpwrctrl(SDCARD_PWR_OPENDRAIN); + break; + + /* SD normal operation clocking (wide 4-bit mode) */ + + case CLOCK_SD_TRANSFER_4BIT: +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + clkcr = (SDCARD_CLOCK_SDWIDEXFR | SDCARD_CLOCK_CLKEN); + break; +#endif + + /* SD normal operation clocking (narrow 1-bit mode) */ + + case CLOCK_SD_TRANSFER_1BIT: + clkcr = (SDCARD_CLOCK_SDXFR | SDCARD_CLOCK_CLKEN); + break; + } + + /* Set the new clock frequency along with the clock enable/disable bit */ + + lpc17_setclock(clkcr); +} + +/**************************************************************************** + * Name: lpc17_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SD card device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int lpc17_attach(FAR struct sdio_dev_s *dev) +{ + int ret; + + /* Attach the SD card interrupt handler */ + + ret = irq_attach(LPC17_IRQ_MCI, lpc17_interrupt); + if (ret == OK) + { + + /* Disable all interrupts at the SD card controller and clear static + * interrupt flags + */ + + putreg32(SDCARD_MASK0_RESET, LPC17_SDCARD_MASK0); + putreg32(SDCARD_CLEAR_STATICFLAGS, LPC17_SDCARD_CLEAR); + + /* Enable SD card interrupts at the NVIC. They can now be enabled at + * the SD card controller as needed. + */ + + up_enable_irq(LPC17_IRQ_MCI); + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_sendcmd + * + * Description: + * Send the SD card command + * + * Input Parameters: + * dev - An instance of the SD card device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int lpc17_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) +{ + uint32_t regval; + uint32_t cmdidx; + + /* Set the SD card Argument value */ + + putreg32(arg, LPC17_SDCARD_ARG); + + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, and CPSMEN bits */ + + regval = getreg32(LPC17_SDCARD_CMD); + regval &= ~(SDCARD_CMD_INDEX_MASK | SDCARD_CMD_WAITRESP_MASK | + SDCARD_CMD_WAITINT | SDCARD_CMD_WAITPEND | + SDCARD_CMD_CPSMEN); + + /* Set WAITRESP bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + regval |= SDCARD_CMD_NORESPONSE; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= SDCARD_CMD_SHORTRESPONSE; + break; + + case MMCSD_R2_RESPONSE: + regval |= SDCARD_CMD_LONGRESPONSE; + break; + } + + /* Set CPSMEN and the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval |= cmdidx | SDCARD_CMD_CPSMEN; + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + + /* Write the SD card CMD */ + + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + putreg32(regval, LPC17_SDCARD_CMD); + return OK; +} + +/**************************************************************************** + * Name: lpc17_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDCARD_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * buffer - Address of the buffer in which to receive the data + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int lpc17_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + lpc17_datadisable(); + lpc17_sampleinit(); + lpc17_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SD card data path */ + + dblocksize = lpc17_log2(nbytes) << SDCARD_DCTRL_DBLOCKSIZE_SHIFT; + lpc17_dataconfig(SDCARD_DTIMER_DATATIMEOUT, nbytes, + dblocksize | SDCARD_DCTRL_DTDIR); + + /* And enable interrupts */ + + lpc17_configxfrints(priv, SDCARD_RECV_MASK); + lpc17_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: lpc17_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDCARD_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * buffer - Address of the buffer containing the data to send + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int lpc17_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + lpc17_datadisable(); + lpc17_sampleinit(); + lpc17_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SD card data path */ + + dblocksize = lpc17_log2(nbytes) << SDCARD_DCTRL_DBLOCKSIZE_SHIFT; + lpc17_dataconfig(SDCARD_DTIMER_DATATIMEOUT, nbytes, dblocksize); + + /* Enable TX interrupts */ + + lpc17_configxfrints(priv, SDCARD_SEND_MASK); + lpc17_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: lpc17_cancel + * + * Description: + * Cancel the data transfer setup of SDCARD_RECVSETUP, SDCARD_SENDSETUP, + * SDCARD_DMARECVSETUP or SDCARD_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int lpc17_cancel(FAR struct sdio_dev_s *dev) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + lpc17_configxfrints(priv, 0); + lpc17_configwaitints(priv, 0, 0, 0); + + /* Clearing pending interrupt status on all transfer- and event- related + * interrupts + */ + + putreg32(SDCARD_WAITALL_ICR, LPC17_SDCARD_CLEAR); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + */ + + lpc17_dmastop(priv->dma); + } +#endif + + /* Mark no transfer in progress */ + + priv->remaining = 0; + return OK; +} + +/**************************************************************************** + * Name: lpc17_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int lpc17_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + int32_t timeout; + uint32_t events; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + events = SDCARD_CMDDONE_STA; + timeout = SDCARD_CMDTIMEOUT; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + events = SDCARD_RESPDONE_STA; + timeout = SDCARD_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + events = SDCARD_RESPDONE_STA; + timeout = SDCARD_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + while ((getreg32(LPC17_SDCARD_STATUS) & events) == 0) + { + if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n", + cmd, events, getreg32(LPC17_SDCARD_STATUS)); + + return -ETIMEDOUT; + } + } + + putreg32(SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + return OK; +} + +/**************************************************************************** + * Name: lpc17_recvRx + * + * Description: + * Receive response to SD card command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SD card device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a faiure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intacta and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int lpc17_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ +#ifdef CONFIG_DEBUG + uint32_t respcmd; +#endif + uint32_t regval; + int ret = OK; + + /* R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + */ + + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(LPC17_SDCARD_STATUS); + if ((regval & SDCARD_STATUS_CTIMEOUT) != 0) + { + fdbg("ERROR: Command timeout: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if ((regval & SDCARD_STATUS_CCRCFAIL) != 0) + { + fdbg("ERROR: CRC failure: %08x\n", regval); + ret = -EIO; + } +#ifdef CONFIG_DEBUG + else + { + /* Check response received is of desired command */ + + respcmd = getreg32(LPC17_SDCARD_RESPCMD); + if ((uint8_t)(respcmd & SDCARD_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK)) + { + fdbg("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd); + ret = -EINVAL; + } + } +#endif + } + + /* Clear all pending message completion events and return the R1/R6 response */ + + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + *rshort = getreg32(LPC17_SDCARD_RESP0); + return ret; +} + +static int lpc17_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + uint32_t regval; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(LPC17_SDCARD_STATUS); + if (regval & SDCARD_STATUS_CTIMEOUT) + { + fdbg("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if (regval & SDCARD_STATUS_CCRCFAIL) + { + fdbg("ERROR: CRC fail STA: %08x\n", regval); + ret = -EIO; + } + } + + /* Return the long response */ + + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + if (rlong) + { + rlong[0] = getreg32(LPC17_SDCARD_RESP0); + rlong[1] = getreg32(LPC17_SDCARD_RESP1); + rlong[2] = getreg32(LPC17_SDCARD_RESP2); + rlong[3] = getreg32(LPC17_SDCARD_RESP3); + } + return ret; +} + +static int lpc17_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ + uint32_t regval; + int ret = OK; + + /* R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + + /* Check that this is the correct response to this command */ + +#ifdef CONFIG_DEBUG + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout occurred (Apparently a CRC error can terminate + * a good response) + */ + + regval = getreg32(LPC17_SDCARD_STATUS); + if (regval & SDCARD_STATUS_CTIMEOUT) + { + fdbg("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + } + + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + if (rshort) + { + *rshort = getreg32(LPC17_SDCARD_RESP0); + } + return ret; +} + +/* MMC responses not supported */ + +static int lpc17_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl) +{ + putreg32(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC17_SDCARD_CLEAR); + return -ENOSYS; +} + +/**************************************************************************** + * Name: lpc17_waitenable + * + * Description: + * Enable/disable of a set of SD card wait events. This is part of the + * the SDCARD_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling lpc17_eventwait. This is done in this way + * to help the driver to eliminate race conditions between the command + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDCARD_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDCARD_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + lpc17_configwaitints(priv, 0, 0, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + + waitmask = 0; + if ((eventset & SDIOWAIT_CMDDONE) != 0) + { + waitmask |= SDCARD_CMDDONE_MASK; + } + + if ((eventset & SDIOWAIT_RESPONSEDONE) != 0) + { + waitmask |= SDCARD_RESPDONE_MASK; + } + + if ((eventset & SDIOWAIT_TRANSFERDONE) != 0) + { + waitmask |= SDCARD_XFRDONE_MASK; + } + + /* Enable event-related interrupts */ + + putreg32(SDCARD_WAITALL_ICR, LPC17_SDCARD_CLEAR); + lpc17_configwaitints(priv, waitmask, eventset, 0); +} + +/**************************************************************************** + * Name: lpc17_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDCARD_WAITEVENTS are disabled when lpc17_eventwait + * returns. SDCARD_WAITEVENTS must be called again before lpc17_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t lpc17_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + irqstate_t flags; + int ret; + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevents will + * be non-zero (and, hopefully, the semaphore count will also be non-zero. + */ + + flags = enter_critical_section(); + DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + /* Then just tell the caller that we already timed out */ + + wkupevent = SDIOWAIT_TIMEOUT; + goto errout; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)lpc17_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling lpc17_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + lpc17_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + /* Disable event-related interrupts */ + + lpc17_configwaitints(priv, 0, 0, 0); +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + +errout: + leave_critical_section(flags); + lpc17_dumpsamples(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: lpc17_callbackenable + * + * Description: + * Enable/disable of a set of SD card callback events. This is part of the + * the SD card callback sequence. The set of events is configured to enabled + * callbacks to the function provided in lpc17_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methos. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lpc17_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + lpc17_callback(priv); +} + +/**************************************************************************** + * Name: lpc17_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDCARD_CALLBACKENABLE + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int lpc17_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: lpc17_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SD card device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool lpc17_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: lpc17_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int lpc17_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint32_t dblocksize; + uint32_t regval; + int ret = -EINVAL; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + lpc17_datadisable(); + + /* Wide bus operation is required for DMA */ + + if (priv->widebus) + { + lpc17_sampleinit(); + lpc17_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SD card data path */ + + dblocksize = lpc17_log2(buflen) << SDCARD_DCTRL_DBLOCKSIZE_SHIFT; + lpc17_dataconfig(SDCARD_DTIMER_DATATIMEOUT, buflen, + dblocksize | SDCARD_DCTRL_DTDIR); + + /* Configure the RX DMA */ + + lpc17_configxfrints(priv, SDCARD_DMARECV_MASK); + + regval = getreg32(LPC17_SDCARD_DCTRL); + regval |= SDCARD_DCTRL_DMAEN; + putreg32(regval, LPC17_SDCARD_DCTRL); + + ret = lpc17_dmasetup(priv->dma, SDCARD_RXDMA32_CONTROL, + SDCARD_RXDMA32_CONFIG, LPC17_SDCARD_FIFO, + (uint32_t)buffer, (buflen + 3) >> 2); + if (ret == OK) + { + /* Start the DMA */ + + lpc17_sample(priv, SAMPLENDX_BEFORE_ENABLE); + lpc17_dmastart(priv->dma, lpc17_dmacallback, priv); + lpc17_sample(priv, SAMPLENDX_AFTER_SETUP); + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: lpc17_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SD card device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int lpc17_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint32_t dblocksize; + uint32_t regval; + int ret = -EINVAL; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + lpc17_datadisable(); + + /* Wide bus operation is required for DMA */ + + if (priv->widebus) + { + lpc17_sampleinit(); + lpc17_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SD card data path */ + + dblocksize = lpc17_log2(buflen) << SDCARD_DCTRL_DBLOCKSIZE_SHIFT; + lpc17_dataconfig(SDCARD_DTIMER_DATATIMEOUT, buflen, dblocksize); + + /* Configure the TX DMA */ + + ret = lpc17_dmasetup(priv->dma, SDCARD_TXDMA32_CONTROL, + SDCARD_TXDMA32_CONFIG, (uint32_t)buffer, + LPC17_SDCARD_FIFO, (buflen + 3) >> 2); + if (ret == OK) + { + lpc17_sample(priv, SAMPLENDX_BEFORE_ENABLE); + + regval = getreg32(LPC17_SDCARD_DCTRL); + regval |= SDCARD_DCTRL_DMAEN; + putreg32(regval, LPC17_SDCARD_DCTRL); + + /* Start the DMA */ + + lpc17_dmastart(priv->dma, lpc17_dmacallback, priv); + lpc17_sample(priv, SAMPLENDX_AFTER_SETUP); + + /* Enable TX interrupts */ + + lpc17_configxfrints(priv, SDCARD_DMASEND_MASK); + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: lpc17_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void lpc17_callback(void *arg) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)arg; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* Callbacks cannot be performed in the context of an interrupt handler. + * If we are in an interrupt handler, then queue the callback to be + * performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + fvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + } + else + { + /* No.. then just call the callback here */ + + fvdbg("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } + } +} + +/**************************************************************************** + * Name: lpc17_default + * + * Description: + * Restore SD card registers to their default, reset values + * + ****************************************************************************/ + +static void lpc17_default(void) +{ + putreg32(SDCARD_PWR_RESET, LPC17_SDCARD_PWR); + putreg32(SDCARD_CLOCK_RESET, LPC17_SDCARD_CLOCK); + putreg32(SDCARD_ARG_RESET, LPC17_SDCARD_ARG); + putreg32(SDCARD_CMD_RESET, LPC17_SDCARD_CMD); + putreg32(SDCARD_DTIMER_RESET, LPC17_SDCARD_DTIMER); + putreg32(SDCARD_DLEN_RESET, LPC17_SDCARD_DLEN); + putreg32(SDCARD_DCTRL_RESET, LPC17_SDCARD_DCTRL); + putreg32(SDCARD_CLEAR_RESET, LPC17_SDCARD_CLEAR); + putreg32(SDCARD_MASK0_RESET, LPC17_SDCARD_MASK0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SD card for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SD card interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + uint32_t regval; + + /* There is only one slot */ + + struct lpc17_dev_s *priv = &g_scard_dev; + + /* Enable power on SD Interface */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSDC; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Initialize the SD card slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + +#ifdef CONFIG_SDIO_DMA + /* Configure the SDCARD DMA request */ + + lpc17_dmaconfigure(DMA_REQ_SDCARD, DMA_DMASEL_SDCARD); + + /* Allocate a DMA channel for SDCARD DMA */ + + priv->dma = lpc17_dmachannel(); + DEBUGASSERT(priv->dma); +#endif + + /* Configure GPIOs for 4-bit, wide-bus operation. + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. + */ + +#ifndef CONFIG_SDIO_MUXBUS + lpc17_configgpio(GPIO_SD_DAT0); +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + lpc17_configgpio(GPIO_SD_DAT1); + lpc17_configgpio(GPIO_SD_DAT2); + lpc17_configgpio(GPIO_SD_DAT3); +#endif + lpc17_configgpio(GPIO_SD_CLK); + lpc17_configgpio(GPIO_SD_CMD); +#endif + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + lpc17_reset(&priv->dev); + + return &g_scard_dev.dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SD card driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + fvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + lpc17_callback(priv); + } + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SD card driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct lpc17_dev_s *priv = (struct lpc17_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} +#endif /* CONFIG_LPC17_SDCARD */ diff --git a/arch/arm/src/lpc17xx/lpc17_sdcard.h b/arch/arm/src/lpc17xx/lpc17_sdcard.h new file mode 100644 index 0000000000000000000000000000000000000000..520175ec25c08347e5f7fe6e948102cb7f136e54 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_sdcard.h @@ -0,0 +1,127 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_sdcard.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_SDCARD_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_SDCARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/lpc17_sdcard.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_SDCARD_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_serial.c b/arch/arm/src/lpc17xx/lpc17_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..d0e2ceeecf93c6379e7850339d11e8d4ee0dccac --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_serial.c @@ -0,0 +1,1589 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_serial.c + * + * Copyright (C) 2010-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc17_uart.h" +#include "lpc17_gpio.h" +#include "lpc17_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART) + +/* Configuration ************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ +#ifdef LPC176x + uint8_t cclkdiv; /* Divisor needed to get PCLK from CCLK */ +#endif + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_LPC17_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_LPC17_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_LPC17_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_LPC17_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif + +/* This describes the state of the LPC17xx uart0 port. */ + +#ifdef CONFIG_LPC17_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = LPC17_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = LPC17_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the LPC17xx uart1 port. */ + +#ifdef CONFIG_LPC17_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = LPC17_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = LPC17_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the LPC17xx uart1 port. */ + +#ifdef CONFIG_LPC17_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = LPC17_UART2_BASE, + .baud = CONFIG_UART2_BAUD, + .irq = LPC17_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the LPC17xx uart1 port. */ + +#ifdef CONFIG_LPC17_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = LPC17_UART3_BASE, + .baud = CONFIG_UART3_BAUD, + .irq = LPC17_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* Which UART with be tty0/console and which tty1? tty2? tty3? */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0=console */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +# ifdef CONFIG_LPC17_UART1 +# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ +# else +# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART2 +# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1=console */ +# define TTYS0_DEV g_uart1port /* UART1=ttyS0 */ +# ifdef CONFIG_LPC17_UART0 +# define TTYS1_DEV g_uart0port /* UART1=ttyS0;UART0=ttyS1 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS2_DEV g_uart2port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS3_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2;UART3=ttyS3 */ +# else +# undef TTYS3_DEV /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART1=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART2 +# define TTYS1_DEV g_uart2port /* UART1=ttyS0;UART2=ttyS1 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART1=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS1_DEV g_uart3port /* UART1=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART1=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2=console */ +# define TTYS0_DEV g_uart2port /* UART2=ttyS0 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS1_DEV g_uart0port /* UART2=ttyS0;UART0=ttyS1 */ +# ifdef CONFIG_LPC17_UART1 +# define TTYS2_DEV g_uart1port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS3_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2;UART3=ttyS3 */ +# else +# undef TTYS3_DEV /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART2=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART1 +# define TTYS1_DEV g_uart1port /* UART2=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART1=ttyS1;UART3=ttyS2 */ +# else +# undef TTYS2_DEV /* UART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS1_DEV g_uart3port /* UART2=ttyS0;UART3=ttyS1;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3=console */ +# define TTYS0_DEV g_uart3port /* UART3=ttyS0 */ +# ifdef CONFIG_LPC17_UART0 +# define TTYS1_DEV g_uart0port /* UART3=ttyS0;UART0=ttyS1 */ +# ifdef CONFIG_LPC17_UART1 +# define TTYS2_DEV g_uart1port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS3_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2;UART2=ttyS3 */ +# else +# undef TTYS3_DEV /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART2 +# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART2=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART3=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART1 +# define TTYS1_DEV g_uart1port /* UART3=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART1=ttyS1;UART2=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART3=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC17_UART2 +# define TTYS1_DEV g_uart2port /* UART3=ttyS0;UART2=ttyS1;No ttyS3;No ttyS3 */ +# undef TTYS3_DEV /* UART3=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# endif +#else /* No console */ +# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */ +# ifdef CONFIG_LPC17_UART1 +# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC17_UART2 +# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */ +# else +# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC17_UART2 +# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */ +# ifdef CONFIG_LPC17_UART3 +# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC17_UART3 +# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +#endif /* HAVE_CONSOLE */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, LPC17_UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + + up_serialout(priv, LPC17_UART_LCR_OFFSET, lcr); +} + +/************************************************************************************ + * Name: lpc17_uartcclkdiv + * + * Descrption: + * Select a CCLK divider to produce the UART PCLK. The stratey is to select the + * smallest divisor that results in an solution within range of the 16-bit + * DLM and DLL divisor: + * + * PCLK = CCLK / divisor + * BAUD = PCLK / (16 * DL) + * + * Ignoring the fractional divider for now. (If you want to extend this driver + * to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses + * the same peripheral and that logic could easily leveraged here). + * + * For the LPC176x the PCLK is determined by the UART-specific divisor in + * PCLKSEL0 or PCLKSEL1: + * + * PCLK = CCLK / divisor + * + * For the LPC178x, the PCLK is determined by the global divisor setting in + * the PLKSEL register (and, in that case, this function is not needed). + * + * NOTE: This is an inline function. If a typical optimization level is used and + * a constant is provided for the desired frequency, then most of the following + * logic will be optimized away. + * + ************************************************************************************/ + +#ifdef LPC176x +static inline uint32_t lpc17_uartcclkdiv(uint32_t baud) +{ + /* Ignoring the fractional divider, the BAUD is given by: + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Where for the LPC176x the PCLK is determined by the UART-specific divisor in + * PCLKSEL0 or PCLKSEL1: + * + * PCLK = CCLK / divisor + * + * And for the LPC178x, the PCLK is determined by the global divisor setting in + * the PLKSEL register (and, in that case, this function is not needed). + */ + + /* Calculate and optimal PCLKSEL0/1 divisor. + * First, check divisor == 1. This works if the upper limit is met: + * + * DL < 0xffff, or + * PCLK / BAUD / 16 < 0xffff, or + * CCLK / BAUD / 16 < 0xffff, or + * CCLK < BAUD * 0xffff * 16 + * BAUD > CCLK / 0xffff / 16 + * + * And the lower limit is met (we can't allow DL to get very close to one). + * + * DL >= MinDL + * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 16 / MinDL + */ + + if (baud < (LPC17_CCLK / 16 / UART_MINDL)) + { + return SYSCON_PCLKSEL_CCLK; + } + + /* Check divisor == 2. This works if: + * + * 2 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 8 + * + * And + * + * 2 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 8 / MinDL + */ + + else if (baud < (LPC17_CCLK / 8 / UART_MINDL)) + { + return SYSCON_PCLKSEL_CCLK2; + } + + /* Check divisor == 4. This works if: + * + * 4 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 4 + * + * And + * + * 4 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 4 / MinDL + */ + + else if (baud < (LPC17_CCLK / 4 / UART_MINDL)) + { + return SYSCON_PCLKSEL_CCLK4; + } + + /* Check divisor == 8. This works if: + * + * 8 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 2 + * + * And + * + * 8 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 2 / MinDL + */ + + else /* if (baud < (LPC17_CCLK / 2 / UART_MINDL)) */ + { + return SYSCON_PCLKSEL_CCLK8; + } +} +#endif /* LPC176x */ + +/************************************************************************************ + * Name: lpc17_uart0config, uart1config, uart2config, and uart3config + * + * Descrption: + * Configure the UART. UART0/1/2/3 peripherals are configured using the following + * registers: + * + * 1. Power: In the PCONP register, set bits PCUART0/1/2/3. + * On reset, UART0 and UART 1 are enabled (PCUART0 = 1 and PCUART1 = 1) + * and UART2/3 are disabled (PCUART1 = 0 and PCUART3 = 0). + * 2. Peripheral clock: In the PCLKSEL0 register, select PCLK_UART0 and + * PCLK_UART1; in the PCLKSEL1 register, select PCLK_UART2 and PCLK_UART3. + * 3. Pins: Select UART pins through the PINSEL registers and pin modes + * through the PINMODE registers. UART receive pins should not have + * pull-down resistors enabled. + * + ************************************************************************************/ + +#ifdef CONFIG_LPC17_UART0 +static inline void lpc17_uart0config(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Step 1: Enable power on UART0 */ + + flags = enter_critical_section(); + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUART0; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking on UART */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_UART0_MASK; + regval |= ((uint32_t)g_uart0priv.cclkdiv << SYSCON_PCLKSEL0_UART0_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); +#endif + + /* Step 3: Configure I/O pins */ + + lpc17_configgpio(GPIO_UART0_TXD); + lpc17_configgpio(GPIO_UART0_RXD); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC17_UART1 +static inline void lpc17_uart1config(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Step 1: Enable power on UART1 */ + + flags = enter_critical_section(); + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUART1; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking on UART */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_UART1_MASK; + regval |= ((uint32_t)g_uart1priv.cclkdiv << SYSCON_PCLKSEL0_UART1_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); +#endif + + /* Step 3: Configure I/O pins */ + + lpc17_configgpio(GPIO_UART1_TXD); + lpc17_configgpio(GPIO_UART1_RXD); +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) + lpc17_configgpio(GPIO_UART1_CTS); + lpc17_configgpio(GPIO_UART1_RTS); + lpc17_configgpio(GPIO_UART1_DCD); + lpc17_configgpio(GPIO_UART1_DSR); + lpc17_configgpio(GPIO_UART1_DTR); +#ifdef CONFIG_UART1_RINGINDICATOR + lpc17_configgpio(GPIO_UART1_RI); +#endif +#endif + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC17_UART2 +static inline void lpc17_uart2config(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Step 1: Enable power on UART2 */ + + flags = enter_critical_section(); + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUART2; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking on UART */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_UART2_MASK; + regval |= ((uint32_t)g_uart2priv.cclkdiv << SYSCON_PCLKSEL1_UART2_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL1); +#endif + + /* Step 3: Configure I/O pins */ + + lpc17_configgpio(GPIO_UART2_TXD); + lpc17_configgpio(GPIO_UART2_RXD); + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC17_UART3 +static inline void lpc17_uart3config(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Step 1: Enable power on UART3 */ + + flags = enter_critical_section(); + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUART3; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking on UART */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_UART3_MASK; + regval |= ((uint32_t)g_uart3priv.cclkdiv << SYSCON_PCLKSEL1_UART3_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL1); +#endif + + /* Step 3: Configure I/O pins */ + + lpc17_configgpio(GPIO_UART3_TXD); + lpc17_configgpio(GPIO_UART3_RXD); + leave_critical_section(flags); +}; +#endif + +/************************************************************************************ + * Name: lpc17_uartdl + * + * Descrption: + * Select a divider to produce the BAUD from the UART PCLK. + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Ignoring the fractional divider for now. (If you want to extend this driver + * to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses + * the same peripheral and that logic could easily leveraged here). + * + ************************************************************************************/ + +#ifdef LPC176x +static inline uint32_t lpc17_uartdl(uint32_t baud, uint8_t divcode) +{ + uint32_t num; + + switch (divcode) + { + case SYSCON_PCLKSEL_CCLK4: /* PCLK_peripheral = CCLK/4 */ + num = (LPC17_CCLK / 4); + break; + + case SYSCON_PCLKSEL_CCLK: /* PCLK_peripheral = CCLK */ + num = LPC17_CCLK; + break; + + case SYSCON_PCLKSEL_CCLK2: /* PCLK_peripheral = CCLK/2 */ + num = (LPC17_CCLK / 2); + break; + + case SYSCON_PCLKSEL_CCLK8: /* PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) */ + default: + num = (LPC17_CCLK / 8); + break; + } + + return num / (baud << 4); +} +#else +static inline uint32_t lpc17_uartdl(uint32_t baud) +{ + return (uint32_t)BOARD_PCLK_FREQUENCY / (baud << 4); +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t dl; + uint32_t lcr; + + /* Clear fifos */ + + up_serialout(priv, LPC17_UART_FCR_OFFSET, (UART_FCR_RXRST | UART_FCR_TXRST)); + + /* Set trigger */ + + up_serialout(priv, LPC17_UART_FCR_OFFSET, (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, LPC17_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + if (priv->bits == 7) + { + lcr |= UART_LCR_WLS_7BIT; + } + else + { + lcr |= UART_LCR_WLS_8BIT; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STOP; + } + + if (priv->parity == 1) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_ODD); + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_EVEN); + } + + /* Enter DLAB=1 */ + + up_serialout(priv, LPC17_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + +#ifdef LPC176x + dl = lpc17_uartdl(priv->baud, priv->cclkdiv); +#else + dl = lpc17_uartdl(priv->baud); +#endif + up_serialout(priv, LPC17_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC17_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC17_UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, LPC17_UART_FCR_OFFSET, + (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN)); + + /* Enable Auto-RTS and Auto-CS Flow Control in the Modem Control Register */ + +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) + if (priv->uartbase == LPC17_UART1_BASE) + { +#if defined(CONFIG_UART1_IFLOWCONTROL) && defined(CONFIG_UART1_OFLOWCONTROL) + up_serialout(priv, LPC17_UART_MCR_OFFSET, (UART_MCR_RTSEN | UART_MCR_CTSEN)); +#elif defined(CONFIG_UART1_IFLOWCONTROL) + up_serialout(priv, LPC17_UART_MCR_OFFSET, UART_MCR_RTSEN); +#else + up_serialout(priv, LPC17_UART_MCR_OFFSET, UART_MCR_CTSEN); +#endif + } +#endif + +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t status; + int passes; + +#ifdef CONFIG_LPC17_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_LPC17_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_LPC17_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_LPC17_UART3 + if (g_uart3priv.irq == irq) + { + dev = &g_uart3port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, LPC17_UART_IIR_OFFSET); + + /* The UART_IIR_INTSTATUS bit should be zero if there are pending + * interrupts + */ + + if ((status & UART_IIR_INTSTATUS) != 0) + { + /* Break out of the loop when there is no longer a + * pending interrupt + */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_INTID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_INTID_RDA: + case UART_IIR_INTID_CTI: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_INTID_THRE: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts (UART1 only) */ + + case UART_IIR_INTID_MSI: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, LPC17_UART_MSR_OFFSET); + vdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_INTID_RLS: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, LPC17_UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + * Both cfset(i|o)speed() translate to cfsetspeed. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + uint32_t lcr; /* Holds current values of line control register */ + uint16_t dl; /* Divisor latch */ + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + /* Get the c_speed field in the termios struct */ + + priv->baud = cfgetispeed(termiosp); + + /* TODO: Re-calculate the optimal CCLK divisor for the new baud and + * and reset the divider in the CLKSEL0/1 register. + */ + +#if 0 /* ifdef LPC176x */ + priv->cclkdiv = lpc17_uartcclkdiv(priv->baud); +#endif + /* DLAB open latch */ + /* REVISIT: Shouldn't we just call up_setup() to do all of the following? */ + + lcr = getreg32(priv->uartbase + LPC17_UART_LCR_OFFSET); + up_serialout(priv, LPC17_UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + +#ifdef LPC176x + dl = lpc17_uartdl(priv->baud, priv->cclkdiv); +#else + dl = lpc17_uartdl(priv->baud); +#endif + up_serialout(priv, LPC17_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC17_UART_DLL_OFFSET, dl & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC17_UART_LCR_OFFSET, lcr); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, LPC17_UART_LSR_OFFSET); + rbr = up_serialin(priv, LPC17_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_RBRIE; +#endif + } + else + { + priv->ier &= ~UART_IER_RBRIE; + } + + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC17_UART_LSR_OFFSET) & UART_LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, LPC17_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_THREIE; + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_IER_THREIE; + up_serialout(priv, LPC17_UART_IER_OFFSET, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC17_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC17_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */ + +#ifdef CONFIG_LPC17_UART0 +#ifdef LPC176x + g_uart0priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART0_BAUD); +#endif +#ifndef CONFIG_UART0_SERIAL_CONSOLE + lpc17_uart0config(); +#endif + up_disableuartint(&g_uart0priv, NULL); +#endif + +#ifdef CONFIG_LPC17_UART1 +#ifdef LPC176x + g_uart1priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART1_BAUD); +#endif +#ifndef CONFIG_UART1_SERIAL_CONSOLE + lpc17_uart1config(); +#else +#endif + up_disableuartint(&g_uart1priv, NULL); +#endif + +#ifdef CONFIG_LPC17_UART2 +#ifdef LPC176x + g_uart2priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART2_BAUD); +#endif +#ifndef CONFIG_UART2_SERIAL_CONSOLE + lpc17_uart2config(); +#endif + up_disableuartint(&g_uart2priv, NULL); +#endif + +#ifdef CONFIG_LPC17_UART3 +#ifdef LPC176x + g_uart3priv.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART3_BAUD); +#endif +#ifndef CONFIG_UART3_SERIAL_CONSOLE + lpc17_uart3config(); +#endif + up_disableuartint(&g_uart3priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#ifdef HAVE_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc17xx/lpc17_serial.h b/arch/arm/src/lpc17xx/lpc17_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..3db62f7f8a0fd64b87122a704b9f0abcbd375b58 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_serial.h @@ -0,0 +1,133 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_serial.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_SERIAL_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_SERIAL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/lpc17_uart.h" +#include "chip/lpc17_syscon.h" + +#include "lpc17_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_LPC17_UART0) || defined(CONFIG_LPC17_UART1) || \ + defined(CONFIG_LPC17_UART2) || defined(CONFIG_LPC17_UART3) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3 + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_LPC17_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_LPC17_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_LPC17_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_LPC17_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef HAVE_CONSOLE +#endif + +/* Check UART flow control (Only supported by UART1) */ + +# undef CONFIG_UART0_IFLOWCONTROL +# undef CONFIG_UART0_OFLOWCONTROL +# undef CONFIG_UART2_IFLOWCONTROL +# undef CONFIG_UART2_OFLOWCONTROL +# undef CONFIG_UART3_IFLOWCONTROL +# undef CONFIG_UART3_OFLOWCONTROL +#ifndef CONFIG_LPC17_UART1 +# undef CONFIG_UART1_IFLOWCONTROL +# undef CONFIG_UART1_OFLOWCONTROL +#endif + +/* We cannot allow the DLM/DLL divisor to become to small or will will lose too + * much accuracy. This following is a "fudge factor" that represents the minimum + * value of the divisor that we will permit. + */ + +#define UART_MINDL 32 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_SERIAL_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_spi.c b/arch/arm/src/lpc17xx/lpc17_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..c915d1dfc2328944b2967d684523ff9c35abf9d2 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_spi.c @@ -0,0 +1,597 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_spi.c + * + * Copyright (C) 2010, 2012-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_spi.h" + +#ifdef CONFIG_LPC17_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* This driver does not support the SPI exchange method. */ + +#ifdef CONFIG_SPI_EXCHANGE +# error "CONFIG_SPI_EXCHANGE must not be defined in the configuration" +#endif + +/* Debug ********************************************************************/ +/* The following enable debug output from this file: + * + * CONFIG_DEBUG - Define to enable general debug features + * CONFIG_DEBUG_SPI - Define to enable basic SSP debug (needs CONFIG_DEBUG) + * CONFIG_DEBUG_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/* SSP Clocking *************************************************************/ +/* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock (SPI_CLOCK). + * SPI_CLOCK may be further divided by 8-254 to get the SPI clock. If we + * want a usable range of 4KHz to 25MHz for the SPI, then: + * + * 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz), + * and + * 2. SPICLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SPI_CLOCK. + */ + +#define SPI_PCLKSET_DIV SYSCON_PCLKSEL_CCLK +#define SPI_CLOCK LPC17_CCLK + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes the state of the SSP driver */ + +struct lpc17_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = lpc17_spiselect, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc17_spistatus, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc17_spicmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc17_spiregister, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc17_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc17_spidev_s *priv = (FAR struct lpc17_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc17_spidev_s *priv = (FAR struct lpc17_spidev_s *)dev; + uint32_t divisor; + uint32_t actual; + + /* Check if the requested frequence is the same as the frequency selection */ + + DEBUGASSERT(priv && frequency <= SPI_CLOCK / 2); + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* frequency = SPI_CLOCK / divisor, or divisor = SPI_CLOCK / frequency */ + + divisor = SPI_CLOCK / frequency; + + /* The SPI CCR register must contain an even number greater than or equal + * to 8. + */ + + if (divisor < 8) + { + divisor = 8; + } + else if (divisor > 254) + { + divisor = 254; + } + + divisor = (divisor + 1) & ~1; + + /* Save the new divisor value */ + + putreg32(divisor, LPC17_SPI_CCR); + + /* Calculate the new actual */ + + actual = SPI_CLOCK / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc17_spidev_s *priv = (FAR struct lpc17_spidev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC17_SPI_CR); + regval &= ~(SPI_CR_CPOL | SPI_CR_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CR_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CR_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CR_CPOL | SPI_CR_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + putreg32(regval, LPC17_SPI_CR); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc17_spidev_s *priv = (FAR struct lpc17_spidev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC17_SPI_CR); + regval &= ~SPI_CR_BITS_MASK; + regval |= (nbits << SPI_CR_BITS_SHIFT) & SPI_CR_BITS_MASK; + regval |= SPI_CR_BITENABLE; + regval = getreg32(LPC17_SPI_CR); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + /* Write the data to transmitted to the SPI Data Register */ + + putreg32((uint32_t)wd, LPC17_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC17_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC17_SPI_SR); + return (uint16_t)getreg32(LPC17_SPI_DR); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + uint8_t data; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + data = *ptr++; + putreg32((uint32_t)data, LPC17_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC17_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC17_SPI_SR); + nwords--; + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write some dummy data to the SPI Data Register in order to clock the + * read data. + */ + + putreg32(0xff, LPC17_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC17_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC17_SPI_SR); + + /* Read the received data from the SPI Data Register */ + + *ptr++ = (uint8_t)getreg32(LPC17_SPI_DR); + nwords--; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc17_spibus_initialize(int port) +{ + FAR struct lpc17_spidev_s *priv = &g_spidev; + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SPI pins and + * one SPI1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SPI_SCK GPIO_SPI_SCK_1 + */ + + flags = enter_critical_section(); + lpc17_configgpio(GPIO_SPI_SCK); + lpc17_configgpio(GPIO_SPI_MISO); + lpc17_configgpio(GPIO_SPI_MOSI); + + /* Configure clocking */ + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SPI_MASK; + regval |= (SPI_PCLKSET_DIV << SYSCON_PCLKSEL0_SPI_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + + /* Enable peripheral clocking to SPI and SPI1 */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSPI; + putreg32(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); + + /* Configure 8-bit SPI mode and master mode */ + + putreg32(SPI_CR_BITS_8BITS | SPI_CR_BITENABLE | SPI_CR_MSTR, + LPC17_SPI_CR); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + return &priv->spidev; +} + +#endif /* CONFIG_LPC17_SPI */ diff --git a/arch/arm/src/lpc17xx/lpc17_spi.h b/arch/arm/src/lpc17xx/lpc17_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..c2eeea58f9e0e419b750aa7bcd986b37ab67233e --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_spi.h @@ -0,0 +1,173 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_spi.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_SPI_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip/lpc17_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifdef CONFIG_LPC17_SPI + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/************************************************************************************ + * Name: lpc17_spibus_initialize + * + * Description: + * Initialize the selected SPI port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *lpc17_spibus_initialize(int port); + +/************************************************************************************ + * Name: lpc17_spiselect, lpc17_status, and lpc17_spicmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including lpc17_spibus_initialize()) are provided by common LPC17xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in lpc17_boardinitialize() to configure SPI chip select pins. + * 2. Provide lpc17_spiselect() and lpc17_spistatus() functions in your board- + * specific logic. These functions will perform chip selection and status + * operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc17_spicmddata() functions in your board-specific logic. This function + * will perform cmd/data selection operations using GPIOs in the way your + * board is configured. + * 3. Add a call to lpc17_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by lpc17_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +void lpc17_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc17_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc17_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from spiselect after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void spi_flush(FAR struct spi_dev_s *dev); + +/**************************************************************************** + * Name: lpc17_spiregister + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD drvier when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function must + * must be implemented. These functions implements the registercallback + * method of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +int lpc17_spiregister(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC17_SPI */ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_SPI_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_ssp.c b/arch/arm/src/lpc17xx/lpc17_ssp.c new file mode 100644 index 0000000000000000000000000000000000000000..9cdee092423c8c8320d84242a56a8b5c8f7d5b58 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_ssp.c @@ -0,0 +1,1060 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_ssp.c + * + * Copyright (C) 2010-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_ssp.h" + +#if defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1) || \ + defined(CONFIG_LPC17_SSP2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* This driver does not support the SPI exchange method. */ + +#ifdef CONFIG_SPI_EXCHANGE +# error "CONFIG_SPI_EXCHANGE must not be defined in the configuration" +#endif + +/* Debug ********************************************************************/ +/* The following enable debug output from this file: + * + * CONFIG_DEBUG - Define to enable general debug features + * CONFIG_DEBUG_SPI - Define to enable basic SSP debug (needs CONFIG_DEBUG) + * CONFIG_DEBUG_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_DEBUG_SPI +# define sspdbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define sspdbg(x...) +# define spivdbg(x...) +#endif + +/* SSP Clocking *************************************************************/ + +#if defined(LPC176x) +/* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock (SSP_CLOCK). + * SSP_CLOCK may be further divided by 2-254 to get the SSP clock. If we + * want a usable range of 4KHz to 25MHz for the SSP, then: + * + * 1. SSPCLK must be greater than (2*25MHz) = 50MHz, and + * 2. SSPCLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SSP_CLOCK. + */ + +# if LPC17_CCLK > 100000000 +# error "CCLK <= 100,000,000 assumed" +# endif + +# define SSP_PCLKSET_DIV SYSCON_PCLKSEL_CCLK +# define SSP_CLOCK LPC17_CCLK + +#elif defined(LPC178x) +/* All peripherals are clocked by the same peripheral clock in the LPC178x + * family. + */ + +# define SSP_CLOCK BOARD_PCLK_FREQUENCY + +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes the state of the SSP driver */ + +struct lpc17_sspdev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t sspbase; /* SPIn base address */ +#ifdef CONFIG_LPC17_SSP_INTERRUPTS + uint8_t sspirq; /* SPI IRQ number */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (4 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint32_t ssp_getreg(FAR struct lpc17_sspdev_s *priv, uint8_t offset); +static inline void ssp_putreg(FAR struct lpc17_sspdev_s *priv, uint8_t offset, + uint32_t value); + +/* SPI methods */ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/* Initialization */ + +#ifdef CONFIG_LPC17_SSP0 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp0initialize(void); +#endif +#ifdef CONFIG_LPC17_SSP1 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp1initialize(void); +#endif +#ifdef CONFIG_LPC17_SSP2 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp2initialize(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC17_SSP0 +static const struct spi_ops_s g_spi0ops = +{ + .lock = ssp_lock, + .select = lpc17_ssp0select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc17_ssp0status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc17_ssp0cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc17_ssp0register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc17_sspdev_s g_ssp0dev = +{ + .spidev = { &g_spi0ops }, + .sspbase = LPC17_SSP0_BASE, +#ifdef CONFIG_LPC17_SSP_INTERRUPTS + .sspirq = LPC17_IRQ_SSP0, +#endif +}; +#endif /* CONFIG_LPC17_SSP0 */ + +#ifdef CONFIG_LPC17_SSP1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = ssp_lock, + .select = lpc17_ssp1select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, + .status = lpc17_ssp1status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc17_ssp1cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc17_ssp1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc17_sspdev_s g_ssp1dev = +{ + .spidev = { &g_spi1ops }, + .sspbase = LPC17_SSP1_BASE, +#ifdef CONFIG_LPC17_SSP_INTERRUPTS + .sspirq = LPC17_IRQ_SSP1, +#endif +}; +#endif /* CONFIG_LPC17_SSP1 */ + +#ifdef CONFIG_LPC17_SSP2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = ssp_lock, + .select = lpc17_ssp2select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, + .status = lpc17_ssp2status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc17_ssp2cmddata, /* Provided externally */ +#endif + .send = ssp_send, + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc17_ssp2register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc17_sspdev_s g_ssp2dev = +{ + .spidev = { &g_spi2ops }, + .sspbase = LPC17_SSP2_BASE, +#ifdef CONFIG_LPC17_SSP_INTERRUPTS + .sspirq = LPC17_IRQ_SSP2, +#endif +}; +#endif /* CONFIG_LPC17_SSP2 */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssp_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static inline uint32_t ssp_getreg(FAR struct lpc17_sspdev_s *priv, uint8_t offset) +{ + return getreg32(priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_putreg + * + * Description: + * Write a 32-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void ssp_putreg(FAR struct lpc17_sspdev_s *priv, uint8_t offset, uint32_t value) +{ + putreg32(value, priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: ssp_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + uint32_t cpsdvsr; + uint32_t scr; + uint32_t regval; + uint32_t actual; + + /* Check if the requested frequency is the same as the frequency selection */ + + DEBUGASSERT(priv && frequency <= SSP_CLOCK / 2); + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* The SSP bit frequency is given by: + * + * frequency = SSP_CLOCK / (CPSDVSR * (SCR+1)). + * + * Let's try for a solution with the smallest value of SCR. NOTES: + * (1) In the calculations below, the value of the variable 'scr' is + * (SCR+1) in the above equation. (2) On slower LPC17xx parts, SCR + * will probably always be zero. + */ + + for (scr = 1; scr <= 256; scr++) + { + /* CPSDVSR = SSP_CLOCK / (SCR + 1) / frequency */ + + cpsdvsr = SSP_CLOCK / (scr * frequency); + + /* Break out on the first solution we find with the smallest value + * of SCR and with CPSDVSR within the maximum range or 254. + */ + + if (cpsdvsr < 255) + { + break; + } + } + + DEBUGASSERT(scr <= 256 && cpsdvsr <= 255); + + /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + + if (cpsdvsr < 2) + { + /* Clip to the minimum value. */ + + cpsdvsr = 2; + } + else if (cpsdvsr > 254) + { + /* This should never happen */ + + cpsdvsr = 254; + } + + /* Force even */ + + cpsdvsr = (cpsdvsr + 1) & ~1; + + /* Save the new CPSDVSR and SCR values */ + + ssp_putreg(priv, LPC17_SSP_CPSR_OFFSET, cpsdvsr); + + regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_SCR_MASK; + regval |= ((scr - 1) << SSP_CR0_SCR_SHIFT); + ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, regval); + + /* Calculate the new actual */ + + actual = SSP_CLOCK / (cpsdvsr * scr); + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + sspdbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: ssp_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR0 appropriately */ + + regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET); + regval &= ~(SSP_CR0_CPOL | SSP_CR0_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SSP_CR0_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SSP_CR0_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SSP_CR0_CPOL | SSP_CR0_CPHA); + break; + + default: + sspdbg("Bad mode: %d\n", mode); + DEBUGASSERT(FALSE); + return; + } + + ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: ssp_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 3 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR1 appropriately */ + + regval = ssp_getreg(priv, LPC17_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_DSS_MASK; + regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT); + ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: ssp_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + register uint32_t regval; + + /* Wait while the TX FIFO is full */ + + while (!(ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF)); + + /* Write the byte to the TX FIFO */ + + ssp_putreg(priv, LPC17_SSP_DR_OFFSET, (uint32_t)wd); + + /* Wait for the RX FIFO not empty */ + + while (!(ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Get the value from the RX FIFO and return it */ + + regval = ssp_getreg(priv, LPC17_SSP_DR_OFFSET); + sspdbg("%04x->%04x\n", wd, regval); + return (uint16_t)regval; +} + +/**************************************************************************** + * Name: ssp_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + union + { + FAR const uint8_t *p8; + FAR const uint16_t *p16; + FAR const void *pv; + } u; + uint32_t data; + uint32_t sr; + + /* Loop while thre are bytes remaining to be sent */ + + sspdbg("nwords: %d\n", nwords); + u.pv = buffer; + while (nwords > 0) + { + /* While the TX FIFO is not full and there are bytes left to send */ + + while ((ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF) && nwords) + { + /* Fetch the data to send */ + + if (priv->nbits > 8) + { + data = (uint32_t)*u.p16++; + } + else + { + data = (uint32_t)*u.p8++; + } + + /* Send the data */ + + ssp_putreg(priv, LPC17_SSP_DR_OFFSET, data); + nwords--; + } + } + + /* Then discard all card responses until the RX & TX FIFOs are emptied. */ + + sspdbg("discarding\n"); + do + { + /* Is there anything in the RX fifo? */ + + sr = ssp_getreg(priv, LPC17_SSP_SR_OFFSET); + if ((sr & SSP_SR_RNE) != 0) + { + /* Yes.. Read and discard */ + + (void)ssp_getreg(priv, LPC17_SSP_DR_OFFSET); + } + + /* There is a race condition where TFE may go true just before + * RNE goes true and this loop terminates prematurely. The nasty little + * delay in the following solves that (it could probably be tuned + * to improve performance). + */ + + else if ((sr & SSP_SR_TFE) != 0) + { + up_udelay(100); + sr = ssp_getreg(priv, LPC17_SSP_SR_OFFSET); + } + } + while ((sr & SSP_SR_RNE) != 0 || (sr & SSP_SR_TFE) == 0); +} + +/**************************************************************************** + * Name: ssp_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + union + { + FAR uint8_t *p8; + FAR uint16_t *p16; + FAR void *pv; + } u; + uint32_t data; + uint32_t rxpending = 0; + + /* While there is remaining to be sent (and no synchronization error has occurred) */ + + sspdbg("nwords: %d\n", nwords); + u.pv = buffer; + while (nwords || rxpending) + { + /* Fill the transmit FIFO with 0xffff... + * Write 0xff to the data register while (1) the TX FIFO is + * not full, (2) we have not exceeded the depth of the TX FIFO, + * and (3) there are more bytes to be sent. + */ + + spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); + while ((ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF) && + (rxpending < LPC17_SSP_FIFOSZ) && nwords) + { + ssp_putreg(priv, LPC17_SSP_DR_OFFSET, 0xffff); + nwords--; + rxpending++; + } + + /* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */ + + spivdbg("RX: rxpending: %d\n", rxpending); + while (ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_RNE) + { + data = (uint8_t)ssp_getreg(priv, LPC17_SSP_DR_OFFSET); + if (priv->nbits > 8) + { + *u.p16++ = (uint16_t)data; + } + else + { + *u.p8++ = (uint8_t)data; + } + rxpending--; + } + } +} + +/**************************************************************************** + * Name: lpc17_ssp0initialize + * + * Description: + * Initialize the SSP0 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_SSP0 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp0initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP0 pins and + * one SSP1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SSP0_SCK GPIO_SSP0_SCK_1 + */ + + flags = enter_critical_section(); + lpc17_configgpio(GPIO_SSP0_SCK); + lpc17_configgpio(GPIO_SSP0_MISO); + lpc17_configgpio(GPIO_SSP0_MOSI); + + /* Configure clocking */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~SYSCON_PCLKSEL1_SSP0_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL1_SSP0_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL1); +#endif + + /* Enable peripheral clocking to SSP0 */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP0; + putreg32(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp0dev; +} +#endif + +/**************************************************************************** + * Name: lpc17_ssp1initialize + * + * Description: + * Initialize the SSP1 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_SSP1 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp1initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP0 pins and + * one SSP1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SSP0_SCK GPIO_SSP0_SCK_1 + */ + + flags = enter_critical_section(); + lpc17_configgpio(GPIO_SSP1_SCK); + lpc17_configgpio(GPIO_SSP1_MISO); + lpc17_configgpio(GPIO_SSP1_MOSI); + + /* Configure clocking */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SSP1_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP1_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); +#endif + + /* Enable peripheral clocking to SSP0 and SSP1 */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP1; + putreg32(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp1dev; +} +#endif + +/**************************************************************************** + * Name: lpc17_ssp2initialize + * + * Description: + * Initialize the SSP2 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_SSP2 +static inline FAR struct lpc17_sspdev_s *lpc17_ssp2initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SSP2 pins have + * multiple, alternative pin selection. Definitions in the board.h file + * must be provided to resolve the board-specific pin configuration like: + * + * #define GPIO_SSP2_SCK GPIO_SSP2_SCK_1 + */ + + flags = enter_critical_section(); + lpc17_configgpio(GPIO_SSP2_SCK); + lpc17_configgpio(GPIO_SSP2_MISO); + lpc17_configgpio(GPIO_SSP2_MOSI); + + /* Configure clocking */ + +#ifdef LPC176x + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_SSP2_MASK; + regval |= (SSP_PCLKSET_DIV << SYSCON_PCLKSEL0_SSP2_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); +#endif + + /* Enable peripheral clocking to SSP0 and SSP1 */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCSSP2; + putreg32(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); + + return &g_ssp2dev; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_sspbus_initialize + * + * Description: + * Initialize the selected SSP port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc17_sspbus_initialize(int port) +{ + FAR struct lpc17_sspdev_s *priv; + uint32_t regval; + int i; + + /* Only the SSP0 and SSP1 interfaces are supported */ + + switch (port) + { +#ifdef CONFIG_LPC17_SSP0 + case 0: + priv = lpc17_ssp0initialize(); + break; +#endif +#ifdef CONFIG_LPC17_SSP1 + case 1: + priv = lpc17_ssp1initialize(); + break; +#endif +#ifdef CONFIG_LPC17_SSP2 + case 2: + priv = lpc17_ssp2initialize(); + break; +#endif + default: + return NULL; + } + + /* Configure 8-bit SPI mode */ + + ssp_putreg(priv, LPC17_SSP_CR0_OFFSET, SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI); + + /* Disable the SSP and all interrupts (we'll poll for all data) */ + + ssp_putreg(priv, LPC17_SSP_CR1_OFFSET, 0); + ssp_putreg(priv, LPC17_SSP_IMSC_OFFSET, 0); + + /* Set the initial SSP configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + ssp_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + /* Enable the SPI */ + + regval = ssp_getreg(priv, LPC17_SSP_CR1_OFFSET); + ssp_putreg(priv, LPC17_SSP_CR1_OFFSET, regval | SSP_CR1_SSE); + for (i = 0; i < LPC17_SSP_FIFOSZ; i++) + { + (void)ssp_getreg(priv, LPC17_SSP_DR_OFFSET); + } + + return &priv->spidev; +} + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be done + * after a device is deselected if you worry about such things. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void ssp_flush(FAR struct spi_dev_s *dev) +{ + FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev; + + /* Wait for the TX FIFO not full indication */ + + while (!(ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF)); + ssp_putreg(priv, LPC17_SSP_DR_OFFSET, 0xff); + + /* Wait until TX FIFO and TX shift buffer are empty */ + + while (ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_BSY); + + /* Wait until RX FIFO is not empty */ + + while (!(ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Then read and discard bytes until the RX FIFO is empty */ + + do + { + (void)ssp_getreg(priv, LPC17_SSP_DR_OFFSET); + } + while (ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_RNE); +} + +#endif /* CONFIG_LPC17_SSP0/1 */ diff --git a/arch/arm/src/lpc17xx/lpc17_ssp.h b/arch/arm/src/lpc17xx/lpc17_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..6ea6375b131374aa6dee3047eafe7070b5467b12 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_ssp.h @@ -0,0 +1,189 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_ssp.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_SSP_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip/lpc17_ssp.h" + +#if defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_sspbus_initialize + * + * Description: + * Initialize the selected SSP port. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *lpc17_sspbus_initialize(int port); + +/************************************************************************************ + * Name: lpc17_ssp0/ssp1select, lpc17_ssp0/ssp1status, and lpc17_ssp0/ssp1cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including lpc17_sspbus_initialize()) are provided by common LPC17xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in lpc17_boardinitialize() to configure SSP chip select pins. + * 2. Provide lpc17_ssp0/ssp1select() and lpc17_ssp0/ssp1status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc17_ssp0/ssp1cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to lpc17_sspbus_initialize() in your low level application + * initialization logic + * 4. The handle returned by lpc17_sspbus_initialize() may then be used to bind the + * SSP driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SSP driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_LPC17_SSP0 +void lpc17_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc17_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc17_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_LPC17_SSP1 +void lpc17_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc17_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc17_ssp1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from ssp0/1select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_LPC17_SSP0) || defined(CONFIG_LPC17_SSP1) +void ssp_flush(FAR struct spi_dev_s *dev); +#endif + +/**************************************************************************** + * Name: lpc17_ssp0/1register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD drvier when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function(s) must + * must be implemented. These functiosn implements the registercallback + * method of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_LPC17_SSP0 +int lpc17_ssp0register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_LPC17_SSP1 +int lpc17_ssp1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC17_SSP0 || CONFIG_LPC17_SSP1 */ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_SSP_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_start.c b/arch/arm/src/lpc17xx/lpc17_start.c new file mode 100644 index 0000000000000000000000000000000000000000..8d95518d02d3db2e930b93ff0e956cb4e8eba1e2 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_start.c @@ -0,0 +1,261 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_start.c + * arch/arm/src/chip/lpc17_start.c + * + * Copyright (C) 2010, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc17_clockconfig.h" +#include "lpc17_lowputc.h" +#include "lpc17_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Name: lpc17_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void lpc17_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void lpc17_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define lpc17_fpuconfig() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Configure the uart so that we can get debug output as soon as possible */ + + lpc17_clockconfig(); + lpc17_fpuconfig(); + lpc17_lowsetup(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + lpc17_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + lpc17_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/lpc17xx/lpc17_timer.c b/arch/arm/src/lpc17xx/lpc17_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..b4a821ffc0b97e507b807ef877fc715e54b22249 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_timer.c @@ -0,0 +1,633 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_timer.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_timer.h" +#include "chip/lpc176x_pinconfig.h" +#include "lpc17_gpio.h" +#include "lpc176x_gpio.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the TIMER upper half driver. + */ + +#if defined(CONFIG_LPC17_TMR0) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4 */ +#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ +#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ + +#define TIMTYPE_TIM1 TIMTYPE_ADVANCED + + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure represents the state of one PWM timer */ + +struct lpc17_timer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {0,...,7} */ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint8_t timtype; /* See the TIMTYPE_* definitions */ + uint32_t base; /* The base address of the timer */ + uint32_t pincfg; /* Output pin configuration */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint32_t timer_getreg(struct lpc17_timer_s *priv, int offset); +static void timer_putreg(struct lpc17_timer_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void timer_dumpregs(struct lpc17_timer_s *priv, FAR const char *msg); +#else +# define timer_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int timer_timer(FAR struct lpc17_timer_s *priv, + FAR const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int timer_setup(FAR struct pwm_lowerhalf_s *dev); +static int timer_shutdown(FAR struct pwm_lowerhalf_s *dev); + +static int timer_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); + +static int timer_stop(FAR struct pwm_lowerhalf_s *dev); +static int timer_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = timer_setup, + .shutdown = timer_shutdown, + .start = timer_start, + .stop = timer_stop, + .ioctl = timer_ioctl, +}; + +#ifdef CONFIG_LPC17_TMR0 +static struct lpc17_timer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channel = CONFIG_LPC17_MAT0_PIN, + .timtype = TIMTYPE_TIM1, + .base = LPC17_TMR1_BASE, + .pincfg = GPIO_MAT0p1_2, + .pclk = (0x1 << 12), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: timer_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t timer_getreg(struct lpc17_timer_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: timer_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void timer_putreg(struct lpc17_timer_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: timer_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void timer_dumpregs(struct lpc17_timer_s *priv, FAR const char *msg) +{ + pwmdbg("%s:\n", msg); + pwmdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + timer_getreg(priv, LPC17_PWM_MR0_OFFSET), + timer_getreg(priv, LPC17_PWM_MR1_OFFSET), + timer_getreg(priv, LPC17_PWM_MR2_OFFSET), + timer_getreg(priv, LPC17_PWM_MR3_OFFSET)); +#if defined(CONFIG_LPC17_TMR0) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + timer_getreg(priv, LPC17_PWM_MR0_OFFSET), + timer_getreg(priv, LPC17_PWM_MR1_OFFSET), + timer_getreg(priv, LPC17_PWM_MR2_OFFSET), + timer_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } + else +#endif + { + pwmdbg(" DCR: %04x DMAR: %04x\n", + timer_getreg(priv, LPC17_PWM_MR2_OFFSET), + timer_getreg(priv, LPC17_PWM_MR3_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: timer_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_timer(FAR struct lpc17_timer_s *priv, + FAR const struct pwm_info_s *info) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + putreg32(info->frequency, LPC17_TMR0_MR1); /* Set TIMER0 MR1 = number of counts */ + putreg32(info->frequency, LPC17_TMR1_MR0); /* Set TIMER1 MR0 = number of counts */ + + putreg32(1, LPC17_TMR0_TCR); /* Start timer0 */ + putreg32(1, LPC17_TMR1_TCR); /* Start timer1 */ + + leave_critical_section(flags); + timer_dumpregs(priv, "After starting"); + return OK; +} + +#ifdef XXXXX +/**************************************************************************** + * Name: timer_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_interrupt(struct lpc17_timer_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = timer_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + timer_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + return OK; +} + +/**************************************************************************** + * Name: timer_tim1/8interrupt + * + * Description: + * Handle timer 1 and 8 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_tim1interrupt(int irq, void *context) +{ + return timer_interrupt(&g_pwm1dev); +} + +#endif /* XXXXX */ + +/**************************************************************************** + * Name: timer_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int timer_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_timer_s *priv = (FAR struct lpc17_timer_s *)dev; + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Power on the timer peripherals */ + + regval = getreg32(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCTIM0; + regval |= SYSCON_PCONP_PCTIM1; + regval |= SYSCON_PCONP_PCTIM2; + regval |= SYSCON_PCONP_PCTIM3; + putreg32(regval, LPC17_SYSCON_PCONP); + + /* Select clock for the timer peripheral */ + + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~(0x3 << 2); + regval |= (0x1 << 2); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + regval &= ~(0x3 << 4); + regval |= (0x1 << 4); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + putreg32(regval, LPC17_SYSCON_PCLKSEL0); + regval = getreg32(LPC17_SYSCON_PCLKSEL1); + regval &= ~(0x3 << 12); + regval |= (0x1 << 12); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + regval &= ~(0x3 << 14); + regval |= (0x1 << 14); /* PCLK_MC peripheral clk=CCLK=12.5 MHz */ + putreg32(regval, LPC17_SYSCON_PCLKSEL1); + priv->pclk = (0x1 << 12) | (0x1 << 4); + + putreg32(1000, LPC17_TMR0_MR1); /* Set TIMER0 MR1 = number of counts */ + + putreg32(1, LPC17_TMR0_PR); /* Prescaler count frequency: Fpclk/1 */ + putreg32(~(0x3 << 0), LPC17_TMR0_CCR); /* Prescaler count frequency: Fpclk/1 */ + putreg32(~(0x3 << 0), LPC17_TMR0_CTCR); /* Prescaler count frequency: Fpclk/1 */ + putreg32((2 << 3), LPC17_TMR0_MCR); /* Reset on match register MR1 */ + + /* Output bit toggle on external match event External match on MR1, Toggle + * external bit + */ + + putreg32(((1 << 1) | (3 << 6)), LPC17_TMR0_EMR); + putreg32((1 << 0), LPC17_TMR0_TCR); /* Start timer0 */ + + /* Configure the output pins GPIO3.26 */ + + lpc17_configgpio(GPIO_MAT0p1_2); + + putreg32(500, LPC17_TMR1_MR0); /* Set TIMER1 MR0 = number of counts */ + + putreg32(1, LPC17_TMR1_PR); /* Prescaler count frequency:Fpclk/1 */ + putreg32(~(0x3 << 0), LPC17_TMR1_CCR); /* Prescaler count frequency:Fpclk/1 */ + putreg32(~(0x3 << 0), LPC17_TMR1_CTCR); /* Prescaler count frequency:Fpclk/1 */ + putreg32((2 << 0), LPC17_TMR1_MCR); /* Reset on match register MR0 */ +// putreg32(((1 << 0 )| (3 << 4)), LPC17_TMR1_EMR); /* Output bit toggle on external match event MAT0 */ + putreg32((1 << 0), LPC17_TMR1_TCR); /* Start timer1 */ + + /* configure the output pins GPIO3.26 */ +// lpc17_configgpio(GPIO_MAT0p1_2); + + leave_critical_section(flags); + pwm_dumpgpio(priv->pincfg, "TIMER setup"); + return OK; +} + +/**************************************************************************** + * Name: timer_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_timer_s *priv = (FAR struct lpc17_timer_s *)dev; + uint32_t pincfg; + + pwmdbg("TIM%d pincfg: %08x\n", priv->timid, priv->pincfg); + + /* Make sure that the output has been stopped */ + + return OK; +} + +/**************************************************************************** + * Name: timer_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct lpc17_timer_s *priv = (FAR struct lpc17_timer_s *)dev; + return timer_timer(priv, info); +} + +/**************************************************************************** + * Name: timer_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int timer_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct lpc17_timer_s *priv = (FAR struct lpc17_timer_s *)dev; + uint32_t resetbit; + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + pwmdbg("TIM%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_LPC17_TMR0 + case 1: + break; +#endif + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where timer_start() can be called. + */ + + leave_critical_section(flags); + + pwmdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + timer_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: timer_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half TIMER driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int timer_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_TIMER + FAR struct lpc17_timer_s *priv = (FAR struct lpc17_timer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmdbg("TIM%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_timerinitialize + * + * Description: + * Initialize one timer for use with the upper_level TIMER driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half TIMER driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *lpc17_timerinitialize(int timer) +{ + FAR struct lpc17_timer_s *lower; + + pwmdbg("TIM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_LPC17_TMR0 + case 0: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_LPC17_TIMn_TIMER, n = 1,...,14 */ diff --git a/arch/arm/src/lpc17xx/lpc17_timer.h b/arch/arm/src/lpc17xx/lpc17_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..d548fada516c1834a838ab43d9443325a0316129 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_timer.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_timer.h + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_TIMER_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_timer.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_TIMER_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_timerisr.c b/arch/arm/src/lpc17xx/lpc17_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..d0f48a57d1d2ce63d76eb9bfeae9457a53533eb3 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_timerisr.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_timerisr.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The Clock Source: Either the internal CCLK or external STCLK (P3.26) clock + * as the source in the STCTRL register. This file alwyays configures the + * timer to use CCLK as its source. + */ + +#define SYSTICK_RELOAD ((LPC17_CCLK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set to use the LPC17xx CCLK */ + + regval = getreg32(NVIC_SYSTICK_CTRL); + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(LPC17_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(LPC17_IRQ_SYSTICK); +} diff --git a/arch/arm/src/lpc17xx/lpc17_usbdev.c b/arch/arm/src/lpc17xx/lpc17_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..9995e03cdaddbe25fae2b6051b41edeb0fe8cfc9 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_usbdev.c @@ -0,0 +1,3479 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_usbdev.c + * + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc17_usb.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_gpdma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ + +#ifndef CONFIG_LPC17_USBDEV_EP0_MAXSIZE +# define CONFIG_LPC17_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +#define USB_SLOW_INT USBDEV_INT_EPSLOW +#define USB_DEVSTATUS_INT USBDEV_INT_DEVSTAT + +#ifdef CONFIG_LPC17_USBDEV_EPFAST_INTERRUPT +# define USB_FAST_INT USBDEV_INT_EPFAST +#else +# define USB_FAST_INT 0 +#endif + +/* Enable reading SOF from interrupt handler vs. simply reading on demand. Probably + * a bad idea... Unless there is some issue with sampling the SOF from hardware + * asynchronously. + */ + +#ifdef CONFIG_LPC17_USBDEV_FRAME_INTERRUPT +# define USB_FRAME_INT USBDEV_INT_FRAME +#else +# define USB_FRAME_INT 0 +#endif + +#ifdef CONFIG_DEBUG +# define USB_ERROR_INT USBDEV_INT_ERRINT +#else +# undef CONFIG_LPC17_USBDEV_REGDEBUG +# define USB_ERROR_INT 0 +#endif + +/* CLKCTRL enable bits */ + +#define LPC17_CLKCTRL_ENABLES (USBDEV_CLK_DEVCLK|USBDEV_CLK_AHBCLK) + +/* Dump GPIO registers */ + +#if defined(CONFIG_LPC17_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +# define usbdev_dumpgpio() \ + do { \ + lpc17_dumpgpio(GPIO_USB_DP, "D+ P0.29; D- P0.30"); \ + lpc17_dumpgpio(GPIO_USB_VBUS, "LED P1:18; VBUS P1:30"); \ + lpc17_dumpgpio(GPIO_USB_CONNECT, "CONNECT P2:9"); \ + } while (0); +#else +# define usbdev_dumpgpio() +#endif + +/* Number of DMA descriptors */ + +#ifdef CONFIG_LPC17_USBDEV_DMA +# error DMA SUPPORT NOT YET FULLY IMPLEMENTED +# ifndef CONFIG_LPC17_USBDEV_NDMADESCRIPTORS +# define CONFIG_LPC17_USBDEV_NDMADESCRIPTORS 8 +# elif CONFIG_LPC17_USBDEV_NDMADESCRIPTORS > 30 +# define CONFIG_LPC17_USBDEV_NDMADESCRIPTORS 30 +# endif +#endif + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define LPC17_TRACEERR_ALLOCFAIL 0x0001 +#define LPC17_TRACEERR_BADCLEARFEATURE 0x0002 +#define LPC17_TRACEERR_BADDEVGETSTATUS 0x0003 +#define LPC17_TRACEERR_BADEPNO 0x0004 +#define LPC17_TRACEERR_BADEPGETSTATUS 0x0005 +#define LPC17_TRACEERR_BADEPTYPE 0x0006 +#define LPC17_TRACEERR_BADGETCONFIG 0x0007 +#define LPC17_TRACEERR_BADGETSETDESC 0x0008 +#define LPC17_TRACEERR_BADGETSTATUS 0x0009 +#define LPC17_TRACEERR_BADSETADDRESS 0x000a +#define LPC17_TRACEERR_BADSETCONFIG 0x000b +#define LPC17_TRACEERR_BADSETFEATURE 0x000c +#define LPC17_TRACEERR_BINDFAILED 0x000d +#define LPC17_TRACEERR_DISPATCHSTALL 0x000e +#define LPC17_TRACEERR_DMABUSY 0x000f +#define LPC17_TRACEERR_DRIVER 0x0010 +#define LPC17_TRACEERR_DRIVERREGISTERED 0x0011 +#define LPC17_TRACEERR_EP0INSTALLED 0x0012 +#define LPC17_TRACEERR_EP0OUTSTALLED 0x0013 +#define LPC17_TRACEERR_EP0SETUPSTALLED 0x0014 +#define LPC17_TRACEERR_EPINNULLPACKET 0x0015 +#define LPC17_TRACEERR_EPOUTNULLPACKET 0x0016 +#define LPC17_TRACEERR_EPREAD 0x0017 +#define LPC17_TRACEERR_INVALIDCMD 0x0018 +#define LPC17_TRACEERR_INVALIDCTRLREQ 0x0019 +#define LPC17_TRACEERR_INVALIDPARMS 0x001a +#define LPC17_TRACEERR_IRQREGISTRATION 0x001b +#define LPC17_TRACEERR_NODMADESC 0x001c +#define LPC17_TRACEERR_NOEP 0x001d +#define LPC17_TRACEERR_NOTCONFIGURED 0x001e +#define LPC17_TRACEERR_REQABORTED 0x001f + +/* Trace interrupt codes */ + +#define LPC17_TRACEINTID_USB 0x0001 +#define LPC17_TRACEINTID_CLEARFEATURE 0x0002 +#define LPC17_TRACEINTID_CONNECTCHG 0x0003 +#define LPC17_TRACEINTID_CONNECTED 0x0004 +#define LPC17_TRACEINTID_DEVGETSTATUS 0x0005 +#define LPC17_TRACEINTID_DEVRESET 0x0006 +#define LPC17_TRACEINTID_DEVSTAT 0x0007 +#define LPC17_TRACEINTID_DISCONNECTED 0x0008 +#define LPC17_TRACEINTID_DISPATCH 0x0009 +#define LPC17_TRACEINTID_EP0IN 0x000a +#define LPC17_TRACEINTID_EP0OUT 0x000b +#define LPC17_TRACEINTID_EP0SETUP 0x000c +#define LPC17_TRACEINTID_EPDMA 0x000d +#define LPC17_TRACEINTID_EPFAST 0x000e +#define LPC17_TRACEINTID_EPGETSTATUS 0x000f +#define LPC17_TRACEINTID_EPIN 0x0010 +#define LPC17_TRACEINTID_EPINQEMPTY 0x0011 +#define LPC17_TRACEINTID_EP0INSETADDRESS 0x0012 +#define LPC17_TRACEINTID_EPOUT 0x0013 +#define LPC17_TRACEINTID_EPOUTQEMPTY 0x0014 +#define LPC17_TRACEINTID_EP0SETUPSETADDRESS 0x0015 +#define LPC17_TRACEINTID_ERRINT 0x0016 +#define LPC17_TRACEINTID_EPSLOW 0x0017 +#define LPC17_TRACEINTID_FRAME 0x0018 +#define LPC17_TRACEINTID_GETCONFIG 0x0019 +#define LPC17_TRACEINTID_GETSETDESC 0x001a +#define LPC17_TRACEINTID_GETSETIF 0x001b +#define LPC17_TRACEINTID_GETSTATUS 0x001c +#define LPC17_TRACEINTID_IFGETSTATUS 0x001d +#define LPC17_TRACEINTID_SETCONFIG 0x001e +#define LPC17_TRACEINTID_SETFEATURE 0x001f +#define LPC17_TRACEINTID_SUSPENDCHG 0x0020 +#define LPC17_TRACEINTID_SYNCHFRAME 0x0021 + +/* Hardware interface **********************************************************/ + +/* Macros for testing the device status response */ + +#define DEVSTATUS_CONNECT(s) (((s)&CMD_STATUS_CONNECT)!=0) +#define DEVSTATUS_CONNCHG(s) (((s)&CMD_STATUS_CONNCHG)!=0) +#define DEVSTATUS_SUSPEND(s) (((s)&CMD_STATUS_SUSPEND)!=0) +#define DEVSTATUS_SUSPCHG(s) (((s)&CMD_STATUS_SUSPCHG)!=0) +#define DEVSTATUS_RESET(s) (((s)&CMD_STATUS_RESET)!=0) + +/* If this bit is set in the lpc17_epread response, it means that the + * recevied packet was overwritten by a later setup packet (ep0 only). + */ + +#define LPC17_READOVERRUN_BIT (0x80000000) +#define LPC17_READOVERRUN(s) (((s) & LPC17_READOVERRUN_BIT) != 0) + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define LPC17_NLOGENDPOINTS (16) /* ep0-15 */ +#define LPC17_NPHYSENDPOINTS (32) /* x2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are out */ + +#define LPC17_EPPHYIN(epphy) (((epphy)&1)!=0) +#define LPC17_EPPHYOUT(epphy) (((epphy)&1)==0) + +#define LPC17_EPPHYIN2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_IN) +#define LPC17_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_OUT) + +/* Each endpoint has somewhat different characteristics */ + +#define LPC17_EPALLSET (0xffffffff) /* All endpoints */ +#define LPC17_EPOUTSET (0x55555555) /* Even phy endpoint numbers are OUT EPs */ +#define LPC17_EPINSET (0xaaaaaaaa) /* Odd endpoint numbers are IN EPs */ +#define LPC17_EPCTRLSET (0x00000003) /* EP0 IN/OUT are control endpoints */ +#define LPC17_EPINTRSET (0x0c30c30c) /* Interrupt endpoints */ +#define LPC17_EPBULKSET (0xf0c30c30) /* Bulk endpoints */ +#define LPC17_EPISOCSET (0x030c30c0) /* Isochronous endpoints */ +#define LPC17_EPDBLBUFFER (0xf3cf3cf0) /* Double buffered endpoints */ + +#define LPC17_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ +#define LPC17_BULKMAXPACKET (64) /* Bulk endpoint max packet (8/16/32/64) */ +#define LPC17_INTRMAXPACKET (64) /* Interrupt endpoint max packet (1 to 64) */ +#define LPC17_ISOCMAXPACKET (512) /* Acutally 1..1023 */ + +/* EP0 status. EP0 transfers occur in a number of different contexts. A + * simple state machine is required to handle the various transfer complete + * interrupt responses. The following values are the various states: + */ + /*** INTERRUPT CAUSE ***/ +#define LPC17_EP0REQUEST (0) /* Normal request handling */ +#define LPC17_EP0STATUSIN (1) /* Status sent */ +#define LPC17_EP0STATUSOUT (2) /* Status received */ +#define LPC17_EP0SHORTWRITE (3) /* Short data sent with no request */ +#define LPC17_EP0SHORTWRSENT (4) /* Short data write complete */ +#define LPC17_EP0SETADDRESS (5) /* Set address received */ +#define LPC17_EP0WRITEREQUEST (6) /* EP0 write request sent */ + +/* Request queue operations ****************************************************/ + +#define lpc17_rqempty(ep) ((ep)->head == NULL) +#define lpc17_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request make be retained in a list */ + +struct lpc17_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct lpc17_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct lpc17_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct lpc17_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* LPC17xx-specific fields */ + + struct lpc17_usbdev_s *dev; /* Reference to private driver data */ + struct lpc17_req_s *head; /* Request list for this endpoint */ + struct lpc17_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t halted:1; /* 1: Endpoint feature halted */ + uint8_t txbusy:1; /* 1: TX endpoint FIFO full */ + uint8_t txnullpkt:1; /* Null packet needed at end of transfer */ +}; + +/* This represents a DMA descriptor */ + +#ifdef CONFIG_LPC17_USBDEV_DMA +struct lpc17_dmadesc_s +{ + uint32_t nextdesc; /* Address of the next DMA descriptor in RAM */ + uint32_t config; /* Misc. bit encoded configuration information */ + uint32_t start; /* DMA start address */ + uint32_t status; /* Misc. bit encoded status inforamation */ +#ifdef CONFIG_USBDEV_ISOCHRONOUS + uint32_t size; /* Isochronous packet size address */ +#endif +}; +#endif + +/* This structure retains the state of the USB device controller */ + +struct lpc17_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structlpc17_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* LPC17xx-specific fields */ + + uint8_t devstatus; /* Last response to device status command */ + uint8_t ep0state; /* State of certain EP0 operations */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t rxpending:1; /* 1: RX pending */ + uint32_t softprio; /* Bitset of high priority interrupts */ + uint32_t epavail; /* Bitset of available endpoints */ +#ifdef CONFIG_LPC17_USBDEV_FRAME_INTERRUPT + uint32_t sof; /* Last start-of-frame */ +#endif + + /* Allocated DMA descriptor */ + +#ifdef CONFIG_LPC17_USBDEV_DMA + struct lpc17_dmadesc_s *dmadesc; +#endif + + /* The endpoint list */ + + struct lpc17_ep_s eplist[LPC17_NPHYSENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t lpc17_getreg(uint32_t addr); +static void lpc17_putreg(uint32_t val, uint32_t addr); +#else +# define lpc17_getreg(addr) getreg32(addr) +# define lpc17_putreg(val,addr) putreg32(val,addr) +#endif + +/* Command operations **********************************************************/ + +static uint32_t lpc17_usbcmd(uint16_t cmd, uint8_t data); + +/* Request queue operations ****************************************************/ + +static FAR struct lpc17_req_s *lpc17_rqdequeue(FAR struct lpc17_ep_s *privep); +static void lpc17_rqenqueue(FAR struct lpc17_ep_s *privep, + FAR struct lpc17_req_s *req); + +/* Low level data transfers and request operations *****************************/ + +static void lpc17_epwrite(uint8_t epphy, const uint8_t *data, uint32_t nbytes); +static int lpc17_epread(uint8_t epphy, uint8_t *data, uint32_t nbytes); +static inline void lpc17_abortrequest(struct lpc17_ep_s *privep, + struct lpc17_req_s *privreq, int16_t result); +static void lpc17_reqcomplete(struct lpc17_ep_s *privep, int16_t result); +static int lpc17_wrrequest(struct lpc17_ep_s *privep); +static int lpc17_rdrequest(struct lpc17_ep_s *privep); +static void lpc17_cancelrequests(struct lpc17_ep_s *privep); + +/* Interrupt handling **********************************************************/ + +static struct lpc17_ep_s *lpc17_epfindbyaddr(struct lpc17_usbdev_s *priv, + uint16_t eplog); +static void lpc17_eprealize(struct lpc17_ep_s *privep, bool prio, + uint32_t packetsize); +static uint8_t lpc17_epclrinterrupt(uint8_t epphy); +static inline void lpc17_ep0configure(struct lpc17_usbdev_s *priv); +#ifdef CONFIG_LPC17_USBDEV_DMA +static inline void lpc17_dmareset(uint32_t enable); +#endif +static void lpc17_usbreset(struct lpc17_usbdev_s *priv); +static void lpc17_dispatchrequest(struct lpc17_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static inline void lpc17_ep0setup(struct lpc17_usbdev_s *priv); +static inline void lpc17_ep0dataoutinterrupt(struct lpc17_usbdev_s *priv); +static inline void lpc17_ep0dataininterrupt(struct lpc17_usbdev_s *priv); +static int lpc17_usbinterrupt(int irq, FAR void *context); + +#ifdef CONFIG_LPC17_USBDEV_DMA +static int lpc17_dmasetup(struct lpc17_usbdev_s *priv, uint8_t epphy, + uint32_t epmaxsize, uint32_t nbytes, uint32_t *isocpacket, + bool isochronous); +static void lpc17_dmarestart(uint8_t epphy, uint32_t descndx); +static void lpc17_dmadisable(uint8_t epphy); +#endif /* CONFIG_LPC17_USBDEV_DMA */ + +/* Endpoint operations *********************************************************/ + +static int lpc17_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int lpc17_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *lpc17_epallocreq(FAR struct usbdev_ep_s *ep); +static void lpc17_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static FAR void *lpc17_epallocbuffer(FAR struct usbdev_ep_s *ep, + uint16_t nbytes); +static void lpc17_epfreebuffer(FAR struct usbdev_ep_s *ep, void *buf); +#endif +static int lpc17_epsubmit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc17_epcancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc17_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations ********************************************/ + +static FAR struct usbdev_ep_s *lpc17_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void lpc17_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int lpc17_getframe(struct usbdev_s *dev); +static int lpc17_wakeup(struct usbdev_s *dev); +static int lpc17_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int lpc17_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct lpc17_usbdev_s g_usbdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = lpc17_epconfigure, + .disable = lpc17_epdisable, + .allocreq = lpc17_epallocreq, + .freereq = lpc17_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = lpc17_epallocbuffer, + .freebuffer = lpc17_epfreebuffer, +#endif + .submit = lpc17_epsubmit, + .cancel = lpc17_epcancel, + .stall = lpc17_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = lpc17_allocep, + .freeep = lpc17_freeep, + .getframe = lpc17_getframe, + .wakeup = lpc17_wakeup, + .selfpowered = lpc17_selfpowered, + .pullup = lpc17_pullup, +}; + +/* USB Device Communication Area *********************************************** + * + * The CPU and DMA controller communicate through a common area of memory, called + * the USB Device Communication Area, or UDCA. The UDCA is a 32-word array of DMA + * Descriptor Pointers (DDPs), each of which corresponds to a physical endpoint. + * Each DDP points to the start address of a DMA Descriptor, if one is defined for + * the endpoint. DDPs for unrealized endpoints and endpoints disabled for DMA + * operation are ignored and can be set to a NULL (0x0) value. + * + * The start address of the UDCA is stored in the USBUDCAH register. The UDCA can + * reside at any 128-byte boundary of RAM that is accessible to both the CPU and DMA + * controller (on other MCU's like the LPC2148, the UDCA lies in a specialized + * 8Kb memory region). + */ + +#ifdef CONFIG_LPC17_USBDEV_DMA +static uint32_t g_udca[LPC17_NPHYSENDPOINTS] __attribute__ ((aligned (128))); +static struct lpc17_dmadesc_s g_usbddesc[CONFIG_LPC17_USBDEV_NDMADESCRIPTORS]; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_printreg + * + * Description: + * Print the contents of an LPC17xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: lpc17_checkreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_REGDEBUG +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + lpc17_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + lpc17_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: lpc17_getreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_REGDEBUG +static uint32_t lpc17_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc17_putreg + * + * Description: + * Set the contents of an LPC17xx register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_REGDEBUG +static void lpc17_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc17_usbcmd + * + * Description: + * Transmit commands to the USB engine + * + ****************************************************************************/ + +static uint32_t lpc17_usbcmd(uint16_t cmd, uint8_t data) +{ + irqstate_t flags; + uint32_t cmd32; + uint32_t data32; + uint32_t tmp = 0; + + /* Disable interrupt and clear CDFULL and CCEMPTY interrupt status */ + + flags = enter_critical_section(); + lpc17_putreg(USBDEV_INT_CDFULL | USBDEV_INT_CCEMPTY, LPC17_USBDEV_INTCLR); + + /* Shift the command in position and mask out extra bits */ + + cmd32 = ((uint32_t)cmd << CMD_USBDEV_CMDSHIFT) & CMD_USBDEV_CMDMASK; + + /* Load command + WR in command code register */ + + lpc17_putreg(cmd32 | CMD_USBDEV_CMDWR, LPC17_USBDEV_CMDCODE); + + /* Wait until the command register is empty (CCEMPTY != 0, command is accepted) */ + + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CCEMPTY) == 0); + + /* Clear command register empty (CCEMPTY) interrupt */ + + lpc17_putreg(USBDEV_INT_CCEMPTY, LPC17_USBDEV_INTCLR); + + /* Determine next phase of the command */ + + switch (cmd) + { + /* Write operations (1 byte of data) */ + + case CMD_USBDEV_SETADDRESS: + case CMD_USBDEV_CONFIG: + case CMD_USBDEV_SETMODE: + case CMD_USBDEV_SETSTATUS: + { + /* Send data + WR and wait for CCEMPTY */ + + data32 = (uint32_t)data << CMD_USBDEV_WDATASHIFT; + lpc17_putreg(data32 | CMD_USBDEV_DATAWR, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CCEMPTY) == 0); + } + break; + + /* 16 bit read operations */ + + case CMD_USBDEV_READFRAMENO: + case CMD_USBDEV_READTESTREG: + { + /* Send command code + RD and wait for CDFULL */ + + lpc17_putreg(cmd32 | CMD_USBDEV_DATARD, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CDFULL) == 0); + + /* Clear CDFULL and read LS data */ + + lpc17_putreg(USBDEV_INT_CDFULL, LPC17_USBDEV_INTCLR); + tmp = lpc17_getreg(LPC17_USBDEV_CMDDATA); + + /* Send command code + RD and wait for CDFULL */ + + lpc17_putreg(cmd32 | CMD_USBDEV_DATARD, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CDFULL) == 0); + + /* Read MS data */ + + tmp |= lpc17_getreg(LPC17_USBDEV_CMDDATA) << 8; + } + break; + + /* 8-bit read operations */ + + case CMD_USBDEV_GETSTATUS: + case CMD_USBDEV_GETERRORCODE: + case CMD_USBDEV_READERRORSTATUS: + case CMD_USBDEV_EPCLRBUFFER: + { + /* Send command code + RD and wait for CDFULL */ + + lpc17_putreg(cmd32 | CMD_USBDEV_DATARD, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CDFULL) == 0); + + /* Read data */ + + tmp = lpc17_getreg(LPC17_USBDEV_CMDDATA); + } + break; + + /* No data transfer */ + + case CMD_USBDEV_EPVALIDATEBUFFER: + break; + + default: + switch (cmd & 0x1e0) + { + case CMD_USBDEV_EPSELECT: + case CMD_USBDEV_EPSELECTCLEAR: + { + /* Send command code + RD and wait for CDFULL */ + + lpc17_putreg(cmd32 | CMD_USBDEV_DATARD, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CDFULL) == 0); + + /* Read data */ + + tmp = lpc17_getreg(LPC17_USBDEV_CMDDATA); + } + break; + + case CMD_USBDEV_EPSETSTATUS: + { + /* Send data + RD and wait for CCEMPTY */ + + data32 = (uint32_t)data << CMD_USBDEV_WDATASHIFT; + lpc17_putreg(data32 | CMD_USBDEV_DATAWR, LPC17_USBDEV_CMDCODE); + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CCEMPTY) == 0); + } + break; + + default: + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDCMD), 0); + break; + } + break; + } + + /* Restore the interrupt flags */ + + leave_critical_section(flags); + return tmp; +} + +/**************************************************************************** + * Name: lpc17_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct lpc17_req_s *lpc17_rqdequeue(FAR struct lpc17_ep_s *privep) +{ + FAR struct lpc17_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static void lpc17_rqenqueue(FAR struct lpc17_ep_s *privep, + FAR struct lpc17_req_s *req) +{ + req->flink = NULL; + if (!privep->head) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } +} + +/**************************************************************************** + * Name: lpc17_epwrite + * + * Description: + * Endpoint write (IN) + * + ****************************************************************************/ + +static void lpc17_epwrite(uint8_t epphy, const uint8_t *data, uint32_t nbytes) +{ + uint32_t value; + bool aligned = (((uint32_t)data & 3) == 0); + + /* Set the write enable bit for this physical EP address. Bits 2-5 are + * the logical endpoint number (0-15) + */ + + lpc17_putreg(((epphy << 1) & USBDEV_CTRL_LOGEP_MASK) | USBDEV_CTRL_WREN, + LPC17_USBDEV_CTRL); + + /* Set the transmit packet length (nbytes must be less than 2048) */ + + lpc17_putreg(nbytes, LPC17_USBDEV_TXPLEN); + + /* Transfer the packet data */ + + do + { + /* Zero length packets are a special case */ + + if (nbytes) + { + if (aligned) + { + value = *(uint32_t *)data; + } + else + { + value = (uint32_t)data[0] | ((uint32_t)data[1] << 8) | + ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24); + } + + lpc17_putreg(value, LPC17_USBDEV_TXDATA); + data += 4; + } + else + { + /* Zero length packet */ + + lpc17_putreg(0, LPC17_USBDEV_TXDATA); + } + } + while ((lpc17_getreg(LPC17_USBDEV_CTRL) & USBDEV_CTRL_WREN) != 0); + + /* Done */ + + lpc17_putreg(0, LPC17_USBDEV_CTRL); + (void)lpc17_usbcmd(CMD_USBDEV_EPSELECT | epphy, 0); + (void)lpc17_usbcmd(CMD_USBDEV_EPVALIDATEBUFFER, 0); +} + +/**************************************************************************** + * Name: lpc17_epread + * + * Description: + * Endpoint read (OUT) + * + ****************************************************************************/ + +static int lpc17_epread(uint8_t epphy, uint8_t *data, uint32_t nbytes) +{ + uint32_t pktlen; + uint32_t result; + uint32_t value; + uint8_t aligned = 0; + + /* If data is NULL, then we are being asked to read but discard the data. + * For most cases, the resulting buffer will be aligned and we will be + * able to do faster 32-bit transfers. + */ + + if (data) + { + if (((uint32_t)data & 3) == 0) + { + aligned = 1; + } + else + { + aligned = 2; + } + } + + /* Set the read enable bit for this physical EP address. Bits 2-5 are + * the logical endpoint number (0-15). + */ + + lpc17_putreg(((epphy << 1) & USBDEV_CTRL_LOGEP_MASK) | USBDEV_CTRL_RDEN, + LPC17_USBDEV_CTRL); + + /* Wait for packet buffer ready for reading */ + + while ((lpc17_getreg(LPC17_USBDEV_RXPLEN) & USBDEV_RXPLEN_PKTRDY) == 0); + + /* Get the number of bytes of data to be read */ + + pktlen = lpc17_getreg(LPC17_USBDEV_RXPLEN) & USBDEV_RXPLEN_MASK; + + /* Read data from input buffer while read data is valid (DV) */ + + while ((lpc17_getreg(LPC17_USBDEV_RXPLEN) & USBDEV_RXPLEN_DV) != 0) + { + value = lpc17_getreg(LPC17_USBDEV_RXDATA); + if (aligned == 1) + { + *(uint32_t *)data = value; + data += 4; + } + else if (aligned == 2) + { + *data++ = (uint8_t)value; + *data++ = (uint8_t)(value >> 8); + *data++ = (uint8_t)(value >> 16); + *data++ = (uint8_t)(value >> 24); + } + } + + /* Done */ + + lpc17_putreg(0, LPC17_USBDEV_CTRL); + (void)lpc17_usbcmd(CMD_USBDEV_EPSELECT | epphy, 0); + result = lpc17_usbcmd(CMD_USBDEV_EPCLRBUFFER, 0); + + /* The packet overrun bit in the clear buffer response is applicable only + * on EP0 transfers. If set it means that the recevied packet was overwritten + * by a later setup packet. + */ + + if (epphy == LPC17_EP0_OUT && (result & CMD_USBDEV_CLRBUFFER_PO) != 0) + { + /* Pass this information in bit 31 */ + + pktlen |= LPC17_READOVERRUN_BIT; + } + return pktlen; +} + +/**************************************************************************** + * Name: lpc17_abortrequest + * + * Description: + * Discard a request + * + ****************************************************************************/ + +static inline void lpc17_abortrequest(struct lpc17_ep_s *privep, + struct lpc17_req_s *privreq, + int16_t result) +{ + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_REQABORTED), (uint16_t)privep->epphy); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: lpc17_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void lpc17_reqcomplete(struct lpc17_ep_s *privep, int16_t result) +{ + struct lpc17_req_s *privreq; + int stalled = privep->stalled; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = lpc17_rqdequeue(privep); + leave_critical_section(flags); + + if (privreq) + { + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + if (privep->epphy == LPC17_EP0_IN) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; + } +} + +/**************************************************************************** + * Name: lpc17_wrrequest + * + * Description: + * Send from the next queued write request + * + ****************************************************************************/ + +static int lpc17_wrrequest(struct lpc17_ep_s *privep) +{ + struct lpc17_req_s *privreq; + uint8_t *buf; + int nbytes; + int bytesleft; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc17_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPINQEMPTY), 0); + return OK; + } + + ullvdbg("epphy=%d req=%p: len=%d xfrd=%d nullpkt=%d\n", + privep->epphy, privreq, privreq->req.len, privreq->req.xfrd, privep->txnullpkt); + + /* Ignore any attempt to send a zero length packet on anything but EP0IN */ + + if (privreq->req.len == 0) + { + if (privep->epphy == LPC17_EP0_IN) + { + lpc17_epwrite(LPC17_EP0_IN, NULL, 0); + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EPINNULLPACKET), 0); + } + + /* In any event, the request is complete */ + + lpc17_reqcomplete(privep, OK); + return OK; + } + + /* Otherwise send the data in the packet (in the DMA on case, we + * may be resuming transfer already in progress. + */ +#warning REVISIT... If the EP supports double buffering, then we can do better + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + + /* Send the next packet if (1) there are more bytes to be sent, or + * (2) the last packet sent was exactly maxpacketsize (bytesleft == 0) + */ + + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + if (bytesleft > 0 || privep->txnullpkt) + { + /* Indicate that there is data in the TX FIFO. This will be cleared + * when the EPIN interrupt is received + */ + + privep->txbusy = 1; + + /* Try to send maxpacketsize -- unless we don't have that many + * bytes to send. + */ + + privep->txnullpkt = 0; + if (bytesleft > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + else + { + nbytes = bytesleft; + if ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + privep->txnullpkt = (bytesleft == privep->ep.maxpacket); + } + } + + /* Send the largest number of bytes that we can in this packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + lpc17_epwrite(privep->epphy, buf, nbytes); + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* If all of the bytes were sent (including any final null packet) + * then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->txnullpkt) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + privep->txnullpkt = 0; + lpc17_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc17_rdrequest + * + * Description: + * Receive to the next queued read request + * + ****************************************************************************/ + +static int lpc17_rdrequest(struct lpc17_ep_s *privep) +{ + struct lpc17_req_s *privreq; + uint8_t *buf; + int nbytesread; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc17_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPOUTQEMPTY), 0); + return OK; + } + + ullvdbg("len=%d xfrd=%d nullpkt=%d\n", + privreq->req.len, privreq->req.xfrd, privep->txnullpkt); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EPOUTNULLPACKET), 0); + lpc17_reqcomplete(privep, OK); + return OK; + } + + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + + /* Receive the next packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + nbytesread = lpc17_epread(privep->epphy, buf, privep->ep.maxpacket); + if (nbytesread < 0) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EPREAD), nbytesread); + return ERROR; + } + + /* If the receive buffer is full or if the last packet was not full + * then we are finished with the transfer. + */ + + privreq->req.xfrd += nbytesread; + if (privreq->req.xfrd >= privreq->req.len || nbytesread < privep->ep.maxpacket) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + lpc17_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc17_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void lpc17_cancelrequests(struct lpc17_ep_s *privep) +{ + while (!lpc17_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (lpc17_rqpeek(privep))->req.xfrd); + lpc17_reqcomplete(privep, -ESHUTDOWN); + } +} + +/**************************************************************************** + * Name: lpc17_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct lpc17_ep_s *lpc17_epfindbyaddr(struct lpc17_usbdev_s *priv, + uint16_t eplog) +{ + struct lpc17_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < LPC17_NPHYSENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: lpc17_eprealize + * + * Description: + * Enable or disable an endpoint + * + ****************************************************************************/ + +static void lpc17_eprealize(struct lpc17_ep_s *privep, bool prio, uint32_t packetsize) +{ + struct lpc17_usbdev_s *priv = privep->dev; + uint32_t mask; + uint32_t regval; + + /* Initialize endpoint software priority */ + + mask = 1 << privep->epphy; + if (prio) + { + priv->softprio = priv->softprio | mask; + } + else + { + priv->softprio = priv->softprio & ~mask; + } + + /* Clear realize interrupt bit */ + + lpc17_putreg(USBDEV_INT_EPRLZED, LPC17_USBDEV_INTCLR); + + /* Realize the endpoint */ + + regval = lpc17_getreg(LPC17_USBDEV_REEP); + regval |= (1 << privep->epphy); + lpc17_putreg(regval, LPC17_USBDEV_REEP); + + /* Set endpoint maximum packet size */ + + lpc17_putreg(privep->epphy, LPC17_USBDEV_EPIND); + lpc17_putreg(packetsize, LPC17_USBDEV_MAXPSIZE); + + /* Wait for Realize complete */ + + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_EPRLZED) == 0); + + /* Clear realize interrupt bit */ + + lpc17_putreg(USBDEV_INT_EPRLZED, LPC17_USBDEV_INTCLR); +} + +/**************************************************************************** + * Name: lpc17_epclrinterrupt + * + * Description: + * Clear the EP interrupt flag and return the current EP status + * + ****************************************************************************/ + +static uint8_t lpc17_epclrinterrupt(uint8_t epphy) +{ + /* Clear the endpoint interrupt */ + + lpc17_putreg(1 << epphy, LPC17_USBDEV_EPINTCLR); + + /* Wait for data in the command data register */ + + while ((lpc17_getreg(LPC17_USBDEV_INTST) & USBDEV_INT_CDFULL) == 0); + + /* Return the value of the command data register */ + + return lpc17_getreg(LPC17_USBDEV_CMDDATA); +} + +/**************************************************************************** + * Name: lpc17_ep0configure + * + * Description: + * Configure endpoint 0 + * + ****************************************************************************/ + +static inline void lpc17_ep0configure(struct lpc17_usbdev_s *priv) +{ + uint32_t inten; + + /* EndPoint 0 initialization */ + + lpc17_eprealize(&priv->eplist[LPC17_CTRLEP_OUT], 0, CONFIG_LPC17_USBDEV_EP0_MAXSIZE); + lpc17_eprealize(&priv->eplist[LPC17_CTRLEP_IN], 1, CONFIG_LPC17_USBDEV_EP0_MAXSIZE); + + /* Enable EP0 interrupts (not DMA) */ + + inten = lpc17_getreg(LPC17_USBDEV_EPINTEN); + inten |= 3; /* EP0 Rx and Tx */ + lpc17_putreg(inten, LPC17_USBDEV_EPINTEN); +} + +/**************************************************************************** + * Name: lpc17_dmareset + * + * Description: Reset USB DMA + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_DMA +static inline void lpc17_dmareset(uint32_t enable) +{ + int i; + + /* Disable All DMA interrupts */ + + lpc17_putreg(0, LPC17_USBDEV_DMAINTEN); + + /* DMA Disable */ + + lpc17_putreg(0xffffffff, LPC17_USBDEV_EPDMADIS); + + /* DMA Request clear */ + + putreq32(0xffffffff, LPC17_USBDEV_DMARCLR); + + /* End of Transfer Interrupt Clear */ + + putreq32(0xffffffff, LPC17_USBDEV_EOTINTCLR); + + /* New DD Request Interrupt Clear */ + + putreq32(0xffffffff, LPC17_USBDEV_NDDRINTCLR); + + /* System Error Interrupt Clear */ + + putreq32(0xffffffff, LPC17_USBDEV_SYSERRINTCLR); + + /* Nullify all pointers in the UDCA */ + + for (i = 0; i < LPC17_NPHYSENDPOINTS; ++i) + { + g_udca[i] = NULL; + } + + /* Set USB UDCA Head register */ + + lpc17_putreg((uint32_t)g_udca, LPC17_USBDEV_UDCAH); + + /* Invalidate all DMA descriptors */ + + for (i = 0; i < CONFIG_LPC17_USBDEV_NDMADESCRIPTORS; ++i) + { + memset(&g_usbddesc[i], 0, sizeof(struct lpc17_dmadesc_s)); + } + + /* Enable DMA interrupts */ + + lpc17_putreg(enable, LPC17_USBDEV_DMAINTEN); +} +#endif + +/**************************************************************************** + * Name: lpc17_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc17_usbreset(struct lpc17_usbdev_s *priv) +{ + /* Disable all endpoint interrupts */ + + lpc17_putreg(0, LPC17_USBDEV_EPINTEN); + + /* Frame is Hp interrupt */ + + lpc17_putreg(USBDEV_INT_FRAME, LPC17_USBDEV_INTPRI); + + /* Clear all pending interrupts */ + + lpc17_putreg(0xffffffff, LPC17_USBDEV_EPINTCLR); + lpc17_putreg(0xffffffff, LPC17_USBDEV_INTCLR); + + /* Periperhal address is needed */ + + priv->paddrset = 0; + + /* Endpoints not yet configured */ + + lpc17_usbcmd(CMD_USBDEV_CONFIG, 0); + + /* EndPoint 0 initialization */ + + lpc17_ep0configure(priv); + +#ifdef CONFIG_LPC17_USBDEV_DMA + /* Enable End_of_Transfer_Interrupt and System_Error_Interrupt USB DMA + * interrupts + */ + + lpc17_dmareset(CONFIG_LPC17_USBDEV_DMAINT_MASK); + +#endif + + /* Enable Device interrupts */ + + lpc17_putreg(USB_SLOW_INT | USB_DEVSTATUS_INT | USB_FAST_INT | + USB_FRAME_INT | USB_ERROR_INT, + LPC17_USBDEV_INTEN); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: lpc17_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static void lpc17_dispatchrequest(struct lpc17_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret; + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = 1; + } + } +} + +/**************************************************************************** + * Name: lpc17_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void lpc17_ep0setup(struct lpc17_usbdev_s *priv) +{ + struct lpc17_ep_s *ep0 = &priv->eplist[LPC17_EP0_OUT]; + struct lpc17_ep_s *privep; + struct lpc17_req_s *privreq = lpc17_rqpeek(ep0); + struct usb_ctrlreq_s ctrl; + uint16_t value; + uint16_t index; + uint16_t len; + uint8_t response[2]; + int ret; + + /* Starting a control request? */ + + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + lpc17_usbcmd(CMD_USBDEV_CONFIG, 1); + } + + /* Terminate any pending requests */ + + while (!lpc17_rqempty(ep0)) + { + int16_t result = OK; + if (privreq->req.xfrd != privreq->req.len) + { + result = -EPROTO; + } + + usbtrace(TRACE_COMPLETE(ep0->epphy), privreq->req.xfrd); + lpc17_reqcomplete(ep0, result); + } + + /* Assume NOT stalled */ + + ep0->stalled = 0; + priv->stalled = 0; + + /* Read EP0 data */ + + ret = lpc17_epread(LPC17_EP0_OUT, (uint8_t *)&ctrl, USB_SIZEOF_CTRLREQ); + if (ret <= 0) + { + return; + } + + /* And extract the little-endian 16-bit values to host order */ + + value = GETUINT16(ctrl.value); + index = GETUINT16(ctrl.index); + len = GETUINT16(ctrl.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl.type, ctrl.req, value, index, len); + + /* Dispatch any non-standard requests */ + + if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + lpc17_dispatchrequest(priv, &ctrl); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_GETSTATUS), 0); + if (!priv->paddrset || len != 2 || + (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) + { + priv->stalled = 1; + } + else + { + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPGETSTATUS), 0); + privep = lpc17_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = 1; + } + else + { + if ((lpc17_usbcmd(CMD_USBDEV_EPSELECT | privep->epphy, 0) & + CMD_EPSELECT_ST) != 0) + { + response[0] = 1; /* Stalled */ + } + else + { + response[0] = 0; /* Not stalled */ + } + response[1] = 0; + lpc17_epwrite(LPC17_EP0_IN, response, 2); + priv->ep0state = LPC17_EP0SHORTWRITE; + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + response[1] = 0; + lpc17_epwrite(LPC17_EP0_IN, response, 2); + priv->ep0state = LPC17_EP0SHORTWRITE; + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_IFGETSTATUS), 0); + response[0] = 0; + response[1] = 0; + lpc17_epwrite(LPC17_EP0_IN, response, 2); + priv->ep0state = LPC17_EP0SHORTWRITE; + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADGETSTATUS), 0); + priv->stalled = 1; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_CLEARFEATURE), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc17_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc17_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 0; + (void)lpc17_epstall(&privep->ep, true); + lpc17_epwrite(LPC17_EP0_IN, NULL, 0); + priv->ep0state = LPC17_EP0STATUSIN; + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_SETFEATURE), 0); + if (((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value == USB_FEATURE_TESTMODE) + { + ullvdbg("test mode: %d\n", index); + } + else if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc17_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc17_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 1; + lpc17_epwrite(LPC17_EP0_IN, NULL, 0); + priv->ep0state = LPC17_EP0STATUSIN; + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADSETFEATURE), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EP0SETUPSETADDRESS), value); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0 && value < 128) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + priv->paddr = ctrl.value[0]; + + /* Note that if we send the SETADDRESS command twice, that will force the + * address change. Otherwise, the hardware will automatically set the + * address at the end of the status phase. + */ + + lpc17_usbcmd(CMD_USBDEV_SETADDRESS, CMD_USBDEV_SETADDRESS_DEVEN | priv->paddr); + + /* Send a NULL packet. The status phase completes when the null packet has + * been sent successfully. + */ + + lpc17_epwrite(LPC17_EP0_IN, NULL, 0); + priv->ep0state = LPC17_EP0SETADDRESS; + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADSETADDRESS), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_GETSETDESC), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + lpc17_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADGETSETDESC), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_GETCONFIG), 0); + if (priv->paddrset && (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value == 0 && index == 0 && len == 1) + { + lpc17_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADGETCONFIG), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_SETCONFIG), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0) + { + lpc17_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADSETCONFIG), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_GETSETIF), 0); + lpc17_dispatchrequest(priv, &ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = 1; + } + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false); + lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc17_ep0dataoutinterrupt + * + * Description: + * USB Ctrl EP Data OUT Event. This is logically part of the USB interrupt + * handler. Each non-isochronous OUT endpoint gives an interrupt when they + * receive a packet without error. + * + ****************************************************************************/ + +static inline void lpc17_ep0dataoutinterrupt(struct lpc17_usbdev_s *priv) +{ + uint32_t pktlen; + + /* Copy new setup packet into setup buffer */ + + switch (priv->ep0state) + { + case LPC17_EP0SHORTWRITE: + { + priv->ep0state = LPC17_EP0STATUSOUT; + pktlen = lpc17_epread(LPC17_EP0_OUT, NULL, CONFIG_LPC17_USBDEV_EP0_MAXSIZE); + if (LPC17_READOVERRUN(pktlen)) + { + lpc17_ep0setup(priv); + } + } + break; + + case LPC17_EP0SHORTWRSENT: + { + priv->ep0state = LPC17_EP0REQUEST; + pktlen = lpc17_epread(LPC17_EP0_OUT, NULL, CONFIG_LPC17_USBDEV_EP0_MAXSIZE); + if (LPC17_READOVERRUN(pktlen)) + { + lpc17_ep0setup(priv); + } + } + break; + + case LPC17_EP0REQUEST: + { + /* Process the next request action (if any) */ + + lpc17_rdrequest(&priv->eplist[LPC17_EP0_OUT]); + } + break; + + default: + priv->stalled = 1; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0OUTSTALLED), priv->ep0state); + lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false); + lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc17_ep0dataininterrupt + * + * Description: + * USB Ctrl EP Data IN Event. This is logically part of the USB interrupt + * handler. All non-isochronous IN endpoints give this interrupt when a + * packet is successfully transmitted (OR a NAK handshake is sent on the bus + * provided that the interrupt on NAK feature is enabled). + * + ****************************************************************************/ + +static inline void lpc17_ep0dataininterrupt(struct lpc17_usbdev_s *priv) +{ + struct lpc17_ep_s *ep0; + + switch (priv->ep0state) + { + case LPC17_EP0STATUSOUT: + case LPC17_EP0STATUSIN: + priv->ep0state = LPC17_EP0REQUEST; + break; + + case LPC17_EP0SHORTWRITE: + priv->ep0state = LPC17_EP0SHORTWRSENT; + break; + + case LPC17_EP0SETADDRESS: + { + /* If the address was set to a non-zero value, then thiscompletes the + * default phase, and begins the address phase (still not fully configured) + */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr); + lpc17_usbcmd(CMD_USBDEV_CONFIG, 0); + if (priv->paddr) + { + priv->paddrset = 1; + priv->ep0state = LPC17_EP0REQUEST; + } + } + break; + + case LPC17_EP0REQUEST: + { + /* Process the next request action (if any) */ + + ep0 = &priv->eplist[LPC17_EP0_IN]; + ep0->txbusy = 0; + lpc17_wrrequest(ep0); + } + break; + + default: + priv->stalled = 1; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0INSTALLED), priv->ep0state); + lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false); + lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc17_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int lpc17_usbinterrupt(int irq, FAR void *context) +{ + struct lpc17_usbdev_s *priv = &g_usbdev; + struct lpc17_ep_s *privep ; + + uint32_t devintstatus; /* Sampled state of the device interrupt status register */ + uint32_t epintstatus; /* Sampled state of the endpoint interrupt status register */ +#ifdef CONFIG_LPC17_USBDEV_DMA + uint32_t usbintstatus; /* Sampled state is SYSCON USB interrupt status */ + uint32_t dmaintstatus; /* Sampled state of dma interrupt status register */ +#endif + uint32_t softprio; /* Current priority interrupt bitset */ + uint32_t pending; /* Pending subset of priority interrupt bitset */ + uint8_t epphy; /* Physical endpoint number being processed */ + int i; + + /* Read the device interrupt status register */ + + devintstatus = lpc17_getreg(LPC17_USBDEV_INTST); + usbtrace(TRACE_INTENTRY(LPC17_TRACEINTID_USB), (uint16_t)devintstatus); + +#ifdef CONFIG_LPC17_USBDEV_DMA + /* Check for low priority and high priority (non-DMA) interrupts */ + + usbintstatus = lpc17_getreg(LPC17_SYSCON_USBINTST); + if ((usbintstatus & (SYSCON_USBINTST_REQLP | SYSCON_USBINTST_REQHP)) != 0) + { +#endif +#ifdef CONFIG_LPC17_USBDEV_EPFAST_INTERRUPT + /* Fast EP interrupt */ + + if ((devintstatus & USBDEV_INT_EPFAST) != 0) + { + /* Clear Fast EP interrupt */ + + lpc17_putreg(USBDEV_INT_EPFAST, LPC17_USBDEV_INTCLR); + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPFAST), 0); + + /* Do what? */ + } + +#endif + +#ifdef CONFIG_DEBUG + /* USB engine error interrupt */ + + if ((devintstatus & USBDEV_INT_ERRINT) != 0) + { + uint8_t errcode; + + /* Clear the error interrupt */ + + lpc17_putreg(USBDEV_INT_ERRINT, LPC17_USBDEV_INTCLR); + + /* And show what error occurred */ + + errcode = (uint8_t)lpc17_usbcmd(CMD_USBDEV_READERRORSTATUS, 0) & CMD_READERRORSTATUS_ALLERRS; + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_ERRINT), (uint16_t)errcode); + } +#endif + +#ifdef CONFIG_LPC17_USBDEV_FRAME_INTERRUPT + /* Frame interrupt */ + + if ((devintstatus & USBDEV_INT_FRAME) != 0) + { + /* Clear the frame interrupt */ + + lpc17_putreg(USBDEV_INT_FRAME, LPC17_USBDEV_INTCLR); + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_FRAME), 0); + + /* Then read the start of frame value */ + + priv->sof = (uint16_t)lpc17_usbcmd(CMD_USBDEV_READFRAMENO, 0); + } +#endif + + /* Device Status interrupt */ + + if ((devintstatus & USBDEV_INT_DEVSTAT) != 0) + { + /* Clear Device status interrupt */ + + lpc17_putreg(USBDEV_INT_DEVSTAT, LPC17_USBDEV_INTCLR); + + /* Get device status */ + + g_usbdev.devstatus = (uint8_t)lpc17_usbcmd(CMD_USBDEV_GETSTATUS, 0); + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_DEVSTAT), (uint16_t)g_usbdev.devstatus); + + /* Device connection status */ + + if (DEVSTATUS_CONNCHG(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_CONNECTCHG), + (uint16_t)g_usbdev.devstatus); + if (DEVSTATUS_CONNECT(g_usbdev.devstatus)) + { + /* Host is connected */ + + if (!priv->attached) + { + /* We have a transition from unattached to attached */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_CONNECTED), + (uint16_t)g_usbdev.devstatus); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc17_usbcmd(CMD_USBDEV_CONFIG, 0); + priv->attached = 1; + } + } + + /* Otherwise the host is not attached */ + + else if (priv->attached) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_DISCONNECTED), + (uint16_t)g_usbdev.devstatus); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc17_usbcmd(CMD_USBDEV_CONFIG, 0); + priv->attached = 0; + priv->paddrset = 0; + } + } + + /* Device suspend status */ + + if (DEVSTATUS_SUSPCHG(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_SUSPENDCHG), + (uint16_t)g_usbdev.devstatus); + + /* Inform the Class driver of the change */ + + if (priv->driver) + { + if (DEVSTATUS_SUSPEND(g_usbdev.devstatus)) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + else + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + } + + /* TODO: Perform power management operations here. */ + } + + /* Device reset */ + + if (DEVSTATUS_RESET(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_DEVRESET), + (uint16_t)g_usbdev.devstatus); + lpc17_usbreset(priv); + } + } + + /* Slow EP interrupt */ + + if ((devintstatus & USBDEV_INT_EPSLOW) != 0) + { + /* Clear Slow EP interrupt */ + + lpc17_putreg(USBDEV_INT_EPSLOW, LPC17_USBDEV_INTCLR); + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPSLOW), 0); + + do + { + /* Read the endpoint interrupt status register */ + + epintstatus = lpc17_getreg(LPC17_USBDEV_EPINTST); + + /* Loop twice: Process software high priority interrupts + * on the first pass and low priority interrupts on the + * second. + */ + + softprio = priv->softprio; + for (i = 0; i < 2; i++, softprio = ~softprio) + { + /* On the first time through the loop, pending will be + * the bitset of high priority pending interrupts; on the + * second time throught it will be the bitset of low + * priority interrupts. + */ + + pending = epintstatus & softprio; + + /* EP0 OUT interrupt indicated by bit0 == 1 */ + + if ((pending & 1) != 0) + { + /* Clear the endpoint interrupt */ + + uint32_t result = lpc17_epclrinterrupt(LPC17_CTRLEP_OUT); + if (result & CMD_EPSELECT_STP) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EP0SETUP), (uint16_t)result); + lpc17_ep0setup(priv); + } + else + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EP0OUT), priv->ep0state); + lpc17_ep0dataoutinterrupt(priv); + } + break; + } + + /* EP0 IN interrupt indicated by bit1 == 1 */ + + if ((pending & 2) != 0) + { + /* Clear the endpoint interrupt */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EP0IN), priv->ep0state); + (void)lpc17_epclrinterrupt(LPC17_CTRLEP_IN); + lpc17_ep0dataininterrupt(priv); + } + pending >>= 2; + + /* All other endpoints EP 1-31 */ + + for (epphy = 2; pending; epphy++, pending >>= 1) + { + /* Is the endpoint interrupt pending? */ + + if ((pending & 1) != 0) + { + /* Yes.. clear the endpoint interrupt */ + + (void)lpc17_epclrinterrupt(epphy); + + /* Get the endpoint sructure corresponding to the physical + * endpoint number. + */ + + privep = &priv->eplist[epphy]; + + /* Check for complete on IN or OUT endpoint. Odd physical + * endpoint addresses are IN endpoints. + */ + + if ((epphy & 1) != 0) + { + /* IN: device-to-host */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPOUT), (uint16_t)epphy); + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + lpc17_usbcmd(CMD_USBDEV_CONFIG, 1); + } + + /* Write host data from the current write request (if any) */ + + privep->txbusy = 0; + lpc17_wrrequest(privep); + } + else + { + /* OUT: host-to-device */ + + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPIN), (uint16_t)epphy); + + /* Read host data into the current read request */ + + if (!lpc17_rqempty(privep)) + { + lpc17_rdrequest(privep); + } + else + { + ullvdbg("Pending data on OUT endpoint\n"); + priv->rxpending = 1; + } + } + } + } + } + } + while (epintstatus); + } +#ifdef CONFIG_LPC17_USBDEV_DMA + } + + /* Check for DMA interrupts */ + + if (usbintstatus & SYSCON_USBINTST_REQDMA) != 0) + { + /* First Software High priority and then low priority */ + + uint32_t tmp; + + /* Collect the DMA interrupt sources */ + + dmaintstatus = 0; + tmp = lpc17_getreg(LPC17_USBDEV_EOTINTST); + if (lpc17_getreg(LPC17_USBDEV_DMAINTEN) & 1) + { + dmaintstatus |= tmp; + } + lpc17_putreg(tmp, LPC17_USBDEV_EOTINTCLR); + + tmp = lpc17_getreg(LPC17_USBDEV_NDDRINTST); + if (lpc17_getreg(LPC17_USBDEV_DMAINTEN) & 2) + { + dmaintstatus |= tmp; + } + lpc17_putreg(tmp, LPC17_USBDEV_NDDRINTCLR); + + tmp = lpc17_getreg(LPC17_USBDEV_SYSERRINTST); + if (lpc17_getreg(LPC17_USBDEV_DMAINTEN) & 4) + { + dmaintstatus |= tmp; + } + lpc17_putreg(tmp, LPC17_USBDEV_SYSERRINTCLR); + + /* Loop twice: Process software high priority interrupts on the + * first pass and low priority interrupts on the second. + */ + + softprio = priv->softprio; + for (i = 0; i < 2; i++, softprio = ~softprio) + { + /* On the first time through the loop, pending will be + * the bitset of high priority pending interrupts; on the + * second time throught it will be the bitset of low + * priority interrupts. Note that EP0 IN and OUT are + * omitted. + */ + + pending = (dmaintstatus & softprio) >> 2; + for (epphy = 2; pending; epphy++, pending >>= 1) + { + if ((pending & 1) != 0) + { + usbtrace(TRACE_INTDECODE(LPC17_TRACEINTID_EPDMA), (uint16_t)epphy); +#warning DO WHAT? + } + } + } + } +#endif + usbtrace(TRACE_INTEXIT(LPC17_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Name: lpc17_dmasetup + * + * Description: + * Setup for DMA Transfer + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_DMA +static int lpc17_dmasetup(struct lpc17_usbdev_s *priv, uint8_t epphy, + uint32_t epmaxsize, uint32_t nbytes, uint32_t *isocpacket, + bool isochronous); +{ + struct lpc17_dmadesc_s *dmadesc = priv; + uint32_t regval; + +#ifdef CONFIG_DEBUG + if (!priv || epphy < 2) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Check if a DMA descriptor has been assigned. If not, than that indicates + * that we will have to do parallel I/O + */ + + if (!dmadesc) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_NODMADESC), 0); + return -EBUSY; + } + + /* Verify that the DMA descriptor is available */ + + if ((dmadesc->status & USB_DMADESC_STATUS_MASK) == USB_DMADESC_BEINGSERVICED) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_DMABUSY), 0); + return -EBUSY; /* Shouldn't happen */ + } + + /* Init DMA Descriptor */ + + dmadesc->nexdesc = 0; + dmadesc->config = USB_DMADESC_MODENORMAL | + ((epmaxsize << USB_DMADESC_PKTSIZE_SHIFT) & USB_DMADESC_PKTSIZE_MASK) | + ((nbytes << USB_DMADESC_BUFLEN_SHIFT) & USB_DMADESC_BUFLEN_MASK); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (isochronous) + { + dmadesc->config |= USB_DMADESC_ISCOEP; + } +#endif + + dmadesc->start = (uint32_t)&dmadesc->buffer; + dmadesc->status = 0; + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + dmadesc->size = (uint32_t)packet; +#endif + + /* Enable DMA transfer for this endpoint */ + + putreq32(1 << epphy, LPC17_USBDEV_EPDMAEN); + + /* Check state of IN/OUT Ep buffer */ + + regval = lpc17_usbcmd(CMD_USBDEV_EPSELECT | epphy, 0); + + if ((LPC17_EPPHYIN(epphy) && (regval & 0x60) == 0) || + (LPC17_EPPHYOUT(epphy) && (regval & 0x60) == 0x60)) + { + /* DMA should be "being serviced" */ + + if ((dmadesc->status & USB_DMADESC_STATUS_MASK) != USB_DMADESC_BEINGSERVICED)) + { + /* Re-trigger the DMA Transfer */ + + putreq32(1 << epphy, LPC17_USBDEV_DMARCLR); + putreq32(1 << epphy, LPC17_USBDEV_EPDMAEN); + } + } + return OK; +} +#endif /* CONFIG_LPC17_USBDEV_DMA */ + +/**************************************************************************** + * Name: lpc17_dmarestart + * + * Description: + * Restart DMA Transfer + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_DMA +static void lpc17_dmarestart(uint8_t epphy, uint32_t descndx) +{ + uint32_t regval; + + /* Clear DMA descriptor status */ + + USB_DmaDesc[descndx].status = 0; + + /* Enable DMA transfer on the endpoint */ + + lpc17_putreg(1 << epph, LPC17_USBDEV_EPDMAEN); + + /* Check the state of IN/OUT EP buffer */ + + uint32_t regval = lpc17_usbcmd(CMD_USBDEV_EPSELECT | epphy, 0); + if ((LPC17_EPPHYIN(epphy) && (regval & 0x60) == 0) || + (LPC17_EPPHYIN(epphy) && (regval & 0x60) == 0x60)) + { + /* Re-trigger the DMA Transfer */ + + putreq32(1 << epphy, LPC17_USBDEV_DMARCLR); + putreq32(1 << epphy, LPC17_USBDEV_EPDMAEN); + } +} +#endif /* CONFIG_LPC17_USBDEV_DMA */ + +/**************************************************************************** + * Name: lpc17_dmadisable + * + * Description: + * Disable DMA transfer for the EP + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBDEV_DMA +static void lpc17_dmadisable(uint8_t epphy) +{ + EPDMADIS = 1 << epphy; +} +#endif /* CONFIG_LPC17_USBDEV_DMA */ + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int lpc17_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + uint32_t inten; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Realize the endpoint */ + + lpc17_eprealize(privep, 1, GETUINT16(desc->mxpacketsize)); + + /* Enable and reset EP -- twice */ + + lpc17_usbcmd(CMD_USBDEV_EPSETSTATUS | privep->epphy, 0); + lpc17_usbcmd(CMD_USBDEV_EPSETSTATUS | privep->epphy, 0); + +#ifdef CONFIG_LPC17_USBDEV_DMA + /* Enable DMA Ep interrupt (WO) */ + + lpc17_putreg(1 << privep->epphy, LPC17_USBDEV_EPDMAEN); +#else + /* Enable Ep interrupt (R/W) */ + + inten = lpc17_getreg(LPC17_USBDEV_EPINTEN); + inten |= (1 << privep->epphy); + lpc17_putreg(inten, LPC17_USBDEV_EPINTEN); +#endif + + /* If all of the endpoints have been configured, then tell the USB controller + * to enable normal activity on all realized endpoints. + */ + + if (last) + { + lpc17_usbcmd(CMD_USBDEV_CONFIG, 1); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc17_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int lpc17_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + irqstate_t flags; + uint32_t mask = (1 << privep->epphy); + uint32_t regval; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Cancel any ongoing activity */ + + flags = enter_critical_section(); + lpc17_cancelrequests(privep); + + /* Disable endpoint and interrupt */ + + regval = lpc17_getreg(LPC17_USBDEV_REEP); + regval &= ~mask; + lpc17_putreg(regval, LPC17_USBDEV_REEP); + + lpc17_putreg(mask, LPC17_USBDEV_EPDMADIS); + + regval = lpc17_getreg(LPC17_USBDEV_EPINTEN); + regval &= ~mask; + lpc17_putreg(regval, LPC17_USBDEV_EPINTEN); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc17_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *lpc17_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc17_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct lpc17_ep_s *)ep)->epphy); + + privreq = (FAR struct lpc17_req_s *)kmm_malloc(sizeof(struct lpc17_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct lpc17_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: lpc17_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void lpc17_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc17_req_s *privreq = (FAR struct lpc17_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, ((FAR struct lpc17_ep_s *)ep)->epphy); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: lpc17_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static FAR void *lpc17_epallocbuffer(FAR struct usbdev_ep_s *ep, uint16_t nbytes) +{ +#if defined(CONFIG_LPC17_USBDEV_DMA) + + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + int descndx; + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + + /* Find a free DMA description */ + +#error "LOGIC INCOMPLETE" + + /* Set UDCA to the allocated DMA descriptor for this endpoint */ + + g_udca[privep->epphy] = &g_usbddesc[descndx]; + return &g_usbddesc[descndx] + +#elif defined(CONFIG_USBDEV_DMAMEMORY) + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + return usbdev_dma_alloc(bytes); + +#else + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + return kmm_malloc(bytes); + +#endif +} +#endif + +/**************************************************************************** + * Name: lpc17_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void lpc17_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ +#if defined(CONFIG_LPC17_USBDEV_DMA) + + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + + /* Indicate that there is no DMA descriptor associated with this endpoint */ + + g_udca[privep->epphy] = NULL; + + /* Mark the DMA descriptor as free for re-allocation */ + +# error "LOGIC INCOMPLETE" + +#elif defined(CONFIG_USBDEV_DMAMEMORY) + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + usbdev_dma_free(buf); + +#else + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + kmm_free(buf); + +#endif +} +#endif + +/**************************************************************************** + * Name: lpc17_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int lpc17_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc17_req_s *privreq = (FAR struct lpc17_req_s *)req; + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + FAR struct lpc17_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + lpc17_abortrequest(privep, privreq, -EBUSY); + ret = -EBUSY; + } + + /* Handle IN (device-to-host) requests */ + + else if (LPC17_EPPHYIN(privep->epphy)) + { + /* Add the new request to the request queue for the IN endpoint */ + + lpc17_rqenqueue(privep, privreq); + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the IN endpoint FIFO is available, then transfer the data now */ + + if (privep->txbusy == 0) + { + ret = lpc17_wrrequest(privep); + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + privep->txnullpkt = 0; + lpc17_rqenqueue(privep, privreq); + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + + /* This there a incoming data pending the availability of a request? */ + + if (priv->rxpending) + { + ret = lpc17_rdrequest(privep); + priv->rxpending = 0; + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc17_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int lpc17_epcancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + lpc17_cancelrequests(privep); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc17_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int lpc17_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy); + lpc17_usbcmd(CMD_USBDEV_EPSETSTATUS | privep->epphy, (resume ? 0 : CMD_SETSTAUS_ST)); + + /* If the endpoint of was resumed, then restart any queue write requests */ + + if (resume) + { + (void)lpc17_wrrequest(privep); + } + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *lpc17_allocep(FAR struct usbdev_s *dev, uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct lpc17_usbdev_s *priv = (FAR struct lpc17_usbdev_s *)dev; + uint32_t epset = LPC17_EPALLSET & ~LPC17_EPCTRLSET; + irqstate_t flags; + int epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* A logical address of 0 means that any endpoint will do */ + + if (eplog > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (eplog >= LPC17_NLOGENDPOINTS) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADEPNO), (uint16_t)eplog); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset &= 3 << (eplog << 1); + } + + /* Get the subset matching the requested direction */ + + if (in) + { + epset &= LPC17_EPINSET; + } + else + { + epset &= LPC17_EPOUTSET; + } + + /* Get the subset matching the requested type */ + + switch (eptype) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + epset &= LPC17_EPINTRSET; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + epset &= LPC17_EPBULKSET; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + epset &= LPC17_EPISOCSET; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ + default: + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BADEPTYPE), (uint16_t)eptype); + return NULL; + } + + /* Is the resulting endpoint supported by the LPC17xx? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints */ + + for (epndx = 2; epndx < LPC17_NPHYSENDPOINTS; epndx++) + { + uint32_t bit = 1 << epndx; + if ((epset & bit) != 0) + { + /* Mark the IN/OUT endpoint no longer available */ + + priv->epavail &= ~(3 << (bit & ~1)); + leave_critical_section(flags); + + /* And return the pointer to the standard endpoint structure */ + + return &priv->eplist[epndx].ep; + } + } + /* Shouldn't get here */ + } + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_NOEP), (uint16_t)eplog); + return NULL; +} + +/**************************************************************************** + * Name: lpc17_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void lpc17_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc17_usbdev_s *priv = (FAR struct lpc17_usbdev_s *)dev; + FAR struct lpc17_ep_s *privep = (FAR struct lpc17_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: lpc17_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int lpc17_getframe(struct usbdev_s *dev) +{ +#ifdef CONFIG_LPC17_USBDEV_FRAME_INTERRUPT + FAR struct lpc17_usbdev_s *priv = (FAR struct lpc17_usbdev_s *)dev; + + /* Return last valid value of SOF read by the interrupt handler */ + + usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof); + return priv->sof; +#else + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, 0); + return (int)lpc17_usbcmd(CMD_USBDEV_READFRAMENO, 0); +#endif +} + +/**************************************************************************** + * Name: lpc17_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int lpc17_wakeup(struct usbdev_s *dev) +{ + uint8_t arg = CMD_STATUS_SUSPEND; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, (uint16_t)g_usbdev.devstatus); + + flags = enter_critical_section(); + if (DEVSTATUS_CONNECT(g_usbdev.devstatus)) + { + arg |= CMD_STATUS_CONNECT; + } + + lpc17_usbcmd(CMD_USBDEV_SETSTATUS, arg); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc17_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int lpc17_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct lpc17_usbdev_s *priv = (FAR struct lpc17_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: lpc17_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int lpc17_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + /* The CMD_STATUS_CONNECT bit in the CMD_USBDEV_SETSTATUS command + * controls the LPC17xx SoftConnect_N output pin that is used for SoftConnect. + */ + + lpc17_usbcmd(CMD_USBDEV_SETSTATUS, (enable ? CMD_STATUS_CONNECT : 0)); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * This function is called very early in the initialization sequence in order + * to initialize the USB device functionality. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + struct lpc17_usbdev_s *priv = &g_usbdev; + uint32_t regval; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVINIT, 0); + + /* Step 1: Enable power by setting PCUSB in the PCONP register */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUSB; + lpc17_putreg(regval, LPC17_SYSCON_PCONP); + + /* Step 2: Enable clocking on USB (USB PLL clocking was initialized in + * in very low-level clock setup logic (see lpc17_clockconfig.c)). We + * do still need to set up USBCLKCTRL to enable device and AHB clocking. + */ + + lpc17_putreg(LPC17_CLKCTRL_ENABLES, LPC17_USBDEV_CLKCTRL); + + /* Then wait for the clocks to be reported as "ON" */ + + do + { + regval = lpc17_getreg(LPC17_USBDEV_CLKST); + } + while ((regval & LPC17_CLKCTRL_ENABLES) != LPC17_CLKCTRL_ENABLES); + + /* Step 3: Configure I/O pins */ + + usbdev_dumpgpio(); +#ifndef CONFIG_LPC17_USBDEV_NOVBUS + lpc17_configgpio(GPIO_USB_VBUS); /* VBUS status input */ +#endif + lpc17_configgpio(GPIO_USB_CONNECT); /* SoftConnect control signal */ +#ifndef CONFIG_LPC17_USBDEV_NOLED + lpc17_configgpio(GPIO_USB_UPLED); /* GoodLink LED control signal */ +#endif + lpc17_configgpio(GPIO_USB_DP); /* Positive differential data */ + lpc17_configgpio(GPIO_USB_DM); /* Negative differential data */ + usbdev_dumpgpio(); + + /* Disable USB interrupts */ + + regval = lpc17_getreg(LPC17_SYSCON_USBINTST); + regval &= ~SYSCON_USBINTST_ENINTS; + lpc17_putreg(regval, LPC17_SYSCON_USBINTST); + leave_critical_section(flags); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct lpc17_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[LPC17_EP0_IN].ep; + priv->epavail = LPC17_EPALLSET; + + /* Initialize the endpoint list */ + + for (i = 0; i < LPC17_NPHYSENDPOINTS; i++) + { + uint32_t bit = 1 << i; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + priv->eplist[i].ep.ops = &g_epops; + priv->eplist[i].dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + priv->eplist[i].epphy = i; + if (LPC17_EPPHYIN(i)) + { + priv->eplist[i].ep.eplog = LPC17_EPPHYIN2LOG(i); + } + else + { + priv->eplist[i].ep.eplog = LPC17_EPPHYOUT2LOG(i); + } + + /* The maximum packet size may depend on the type of endpoint */ + + if ((LPC17_EPCTRLSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC17_EP0MAXPACKET; + } + else if ((LPC17_EPINTRSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC17_INTRMAXPACKET; + } + else if ((LPC17_EPBULKSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC17_BULKMAXPACKET; + } + else /* if ((LPC17_EPISOCSET & bit) != 0) */ + { + priv->eplist[i].ep.maxpacket = LPC17_ISOCMAXPACKET; + } + } + + /* Make sure all USB interrupts are disabled and cleared */ + + lpc17_putreg(0, LPC17_USBDEV_INTEN); + lpc17_putreg(0xffffffff, LPC17_USBDEV_INTCLR); + lpc17_putreg(0, LPC17_USBDEV_INTPRI); + + lpc17_putreg(0, LPC17_USBDEV_EPINTEN); + lpc17_putreg(0xffffffff, LPC17_USBDEV_EPINTCLR); + lpc17_putreg(0, LPC17_USBDEV_EPINTPRI); + + /* Interrupt only on ACKs */ + + lpc17_usbcmd(CMD_USBDEV_SETMODE, 0); + + /* Attach USB controller interrupt handler */ + + if (irq_attach(LPC17_IRQ_USB, lpc17_usbinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_IRQREGISTRATION), + (uint16_t)LPC17_IRQ_USB); + goto errout; + } + + /* Enable USB interrupts at the controller -- but do not enable + * the ARM interrupt until the device is bound to the class + * driver + */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_SYSCON_USBINTST); + regval |= SYSCON_USBINTST_ENINTS; + lpc17_putreg(regval, LPC17_SYSCON_USBINTST); + leave_critical_section(flags); + + /* Disconnect device */ + + lpc17_pullup(&priv->usbdev, false); + + /* Enable EP0 for OUT (host-to-device) */ + + lpc17_usbcmd(CMD_USBDEV_SETADDRESS, CMD_USBDEV_SETADDRESS_DEVEN | 0); + lpc17_usbcmd(CMD_USBDEV_SETADDRESS, CMD_USBDEV_SETADDRESS_DEVEN | 0); + + /* Reset/Re-initialize the USB hardware */ + + lpc17_usbreset(priv); + + /* Init Device state structure */ + + priv->devstatus = lpc17_usbcmd(CMD_USBDEV_GETSTATUS, 0); + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct lpc17_usbdev_s *priv = &g_usbdev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + lpc17_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc17_usbcmd(CMD_USBDEV_CONFIG, 0); + + /* Disable and detach IRQs */ + + up_disable_irq(LPC17_IRQ_USB); + irq_detach(LPC17_IRQ_USB); + + /* Turn off USB power and clocking */ + + regval = lpc17_getreg(LPC17_SYSCON_PCONP); + regval &= ~SYSCON_PCONP_PCUSB; + lpc17_putreg(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(LPC17_IRQ_USB); + } + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable USB controller interrupts */ + + up_disable_irq(LPC17_IRQ_USB); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c new file mode 100644 index 0000000000000000000000000000000000000000..94003be06d79178b5eb5ebb2299039e2c9e15713 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -0,0 +1,3857 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_usbhost.c + * + * Copyright (C) 2010-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Authors: Rafael Noronha + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include /* May redefine GPIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/lpc17_usb.h" +#include "chip/lpc17_syscon.h" +#include "lpc17_gpio.h" +#include "lpc17_ohciram.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ + +/* All I/O buffers must lie in AHB SRAM because of the OHCI DMA. It might be + * okay if no I/O buffers are used *IF* the application can guarantee that all + * end-user I/O buffers reside in AHB SRAM. + */ + +#if LPC17_IOBUFFERS < 1 +# warning "No IO buffers allocated" +#endif + +#ifndef CONFIG_LPC17_USBHOST_NPREALLOC +# define CONFIG_LPC17_USBHOST_NPREALLOC 8 +#endif + +/* OHCI Setup ******************************************************************/ +/* Frame Interval / Periodic Start */ + +#define BITS_PER_FRAME 12000 +#define FI (BITS_PER_FRAME-1) +#define FSMPS ((6 * (FI - 210)) / 7) +#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI) +#define DEFAULT_PERSTART (((9 * BITS_PER_FRAME) / 10) - 1) + +/* CLKCTRL enable bits */ + +#define LPC17_CLKCTRL_ENABLES (USBOTG_CLK_HOSTCLK|USBOTG_CLK_PORTSELCLK|USBOTG_CLK_AHBCLK) + +/* Interrupt enable bits */ + +#ifdef CONFIG_DEBUG_USB +# define LPC17_DEBUG_INTS (OHCI_INT_SO|OHCI_INT_RD|OHCI_INT_UE|OHCI_INT_OC) +#else +# define LPC17_DEBUG_INTS 0 +#endif + +#define LPC17_NORMAL_INTS (OHCI_INT_WDH|OHCI_INT_RHSC) +#define LPC17_ALL_INTS (LPC17_NORMAL_INTS|LPC17_DEBUG_INTS) + +/* Dump GPIO registers */ + +#if defined(CONFIG_LPC17_USBHOST_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +# define usbhost_dumpgpio() \ + do { \ + lpc17_dumpgpio(GPIO_USB_DP, "D+ P0.29; D- P0.30"); \ + lpc17_dumpgpio(GPIO_USB_UPLED, "LED P1:18; PPWR P1:19 PWRD P1:22 PVRCR P1:27"); \ + } while (0); +#else +# define usbhost_dumpgpio() +#endif + +/* USB Host Memory *************************************************************/ + +/* Helper definitions */ + +#define HCCA ((struct ohci_hcca_s *)LPC17_HCCA_BASE) +#define TDTAIL ((struct lpc17_gtd_s *)LPC17_TDTAIL_ADDR) +#define EDCTRL ((struct lpc17_ed_s *)LPC17_EDCTRL_ADDR) + +/* Periodic intervals 2, 4, 8, 16,and 32 supported */ + +#define MIN_PERINTERVAL 2 +#define MAX_PERINTERVAL 32 + +/* Descriptors *****************************************************************/ + +/* TD delay interrupt value */ + +#define TD_DELAY(n) (uint32_t)((n) << GTD_STATUS_DI_SHIFT) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure retains the state of the USB host controller */ + +struct lpc17_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to structlpc17_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Driver status */ + + volatile bool change; /* Connection change */ + volatile bool connected; /* Connected to device */ + volatile bool pscwait; /* TRUE: Thread is waiting for a port status change */ + +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t ininterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ + uint8_t outinterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ +#endif + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait Writeback Done Head event */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif +}; + +/* This structure describes one asynchronous transfer */ + +struct lpc17_xfrinfo_s +{ + volatile bool wdhwait; /* Thread is waiting for WDH interrupt */ + volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */ + uint8_t *buffer; /* Transfer buffer start */ + uint16_t buflen; /* Buffer length */ + uint16_t xfrd; /* Number of bytes transferred */ + +#ifdef CONFIG_USBHOST_ASYNCH +#if LPC17_IOBUFFERS > 0 + /* Remember the allocated DMA buffer address so that it can be freed when + * the transfer completes. + */ + + uint8_t *alloc; /* Allocated buffer */ +#endif + + /* Retain the callback information for the asynchronous transfer + * completion. + */ + + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* The OCHI expects the size of an endpoint descriptor to be 16 bytes. + * However, the size allocated for an endpoint descriptor is 32 bytes in + * lpc17_ohciram.h. This extra 16-bytes is used by the OHCI host driver in + * order to maintain additional endpoint-specific data. + */ + +struct lpc17_ed_s +{ + /* Hardware specific fields */ + + struct ohci_ed_s hw; /* 0-15 */ + + /* Software specific fields */ + + uint8_t xfrtype; /* 16: Transfer type. See SB_EP_ATTR_XFER_* in usb.h */ + uint8_t interval; /* 17: Periodic EP polling interval: 2, 4, 6, 16, or 32 */ + sem_t wdhsem; /* 18: Semaphore used to wait for Writeback Done Head event */ + /* Unused bytes may follow, depending on the size of sem_t */ + /* Pointer to structure that manages asynchronous transfers on this pipe */ + + struct lpc17_xfrinfo_s *xfrinfo; +}; + +/* The OCHI expects the size of an transfer descriptor to be 16 bytes. + * However, the size allocated for an endpoint descriptor is 32 bytes in + * lpc17_ohciram.h. This extra 16-bytes is used by the OHCI host driver in + * order to maintain additional endpoint-specific data. + */ + +struct lpc17_gtd_s +{ + /* Hardware specific fields */ + + struct ohci_gtd_s hw; + + /* Software specific fields */ + + struct lpc17_ed_s *ed; /* Pointer to parent ED */ + uint8_t pad[12]; +}; + +/* The following is used to manage lists of free EDs, TDs, and TD buffers */ + +struct lpc17_list_s +{ + struct lpc17_list_s *flink; /* Link to next buffer in the list */ + /* Variable length buffer data follows */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_LPC17_USBHOST_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t lpc17_getreg(uint32_t addr); +static void lpc17_putreg(uint32_t val, uint32_t addr); +#else +# define lpc17_getreg(addr) getreg32(addr) +# define lpc17_putreg(val,addr) putreg32(val,addr) +#endif + +/* Semaphores ******************************************************************/ + +static void lpc17_takesem(sem_t *sem); +#define lpc17_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t lpc17_getle16(const uint8_t *val); +#if 0 /* Not used */ +static void lpc17_putle16(uint8_t *dest, uint16_t val); +#endif + +/* OHCI memory pool helper functions *******************************************/ + +static inline void lpc17_edfree(struct lpc17_ed_s *ed); +static struct lpc17_gtd_s *lpc17_tdalloc(void); +static void lpc17_tdfree(struct lpc17_gtd_s *buffer); +static uint8_t *lpc17_tballoc(void); +static void lpc17_tbfree(uint8_t *buffer); +#if LPC17_IOBUFFERS > 0 +static uint8_t *lpc17_allocio(void); +static void lpc17_freeio(uint8_t *buffer); +#endif +static struct lpc17_xfrinfo_s *lpc17_alloc_xfrinfo(void); +static void lpc17_free_xfrinfo(struct lpc17_xfrinfo_s *xfrinfo); + +/* ED list helper functions ****************************************************/ + +static inline int lpc17_addctrled(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); +static inline int lpc17_remctrled(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); + +static inline int lpc17_addbulked(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); +static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static unsigned int lpc17_getinterval(uint8_t interval); +static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int offset); +#endif + +static inline int lpc17_addinted(struct lpc17_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + struct lpc17_ed_s *ed); +static inline int lpc17_reminted(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); + +static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + struct lpc17_ed_s *ed); +static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); + +/* Descriptor helper functions *************************************************/ + +static int lpc17_enqueuetd(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint32_t dirpid, + uint32_t toggle, volatile uint8_t *buffer, + size_t buflen); +static int lpc17_ctrltd(struct lpc17_usbhost_s *priv, struct lpc17_ed_s *ed, + uint32_t dirpid, uint8_t *buffer, size_t buflen); + +/* Interrupt handling **********************************************************/ + +static int lpc17_usbinterrupt(int irq, void *context); + +/* USB host controller operations **********************************************/ + +static int lpc17_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport); +static int lpc17_rh_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); +static int lpc17_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); + +static int lpc17_ep0configure(struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int lpc17_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int lpc17_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int lpc17_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen); +static int lpc17_free(struct usbhost_driver_s *drvr, uint8_t *buffer); +static int lpc17_ioalloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t buflen); +static int lpc17_iofree(struct usbhost_driver_s *drvr, uint8_t *buffer); +static int lpc17_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer); +static int lpc17_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer); +static int lpc17_transfer_common(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *buffer, + size_t buflen); +#if LPC17_IOBUFFERS > 0 +static int lpc17_dma_alloc(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *userbuffer, + size_t buflen, uint8_t **alloc); +static void lpc17_dma_free(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *userbuffer, + size_t buflen, uint8_t *alloc); +#endif +static ssize_t lpc17_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void lpc17_asynch_completion(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed); +static int lpc17_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int lpc17_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected); +#endif +static void lpc17_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static inline void lpc17_ep0init(struct lpc17_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct lpc17_usbhost_s g_usbhost; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = lpc17_wait, + .enumerate = lpc17_enumerate, +}; + +/* This is a free list of EDs and TD buffers */ + +static struct lpc17_list_s *g_edfree; /* List of unused EDs */ +static struct lpc17_list_s *g_tdfree; /* List of unused TDs */ +static struct lpc17_list_s *g_tbfree; /* List of unused transfer buffers */ +#if LPC17_IOBUFFERS > 0 +static struct lpc17_list_s *g_iofree; /* List of unused I/O buffers */ +#endif + +/* Pool and freelist of transfer structures */ + +static struct lpc17_list_s *g_xfrfree; +static struct lpc17_xfrinfo_s g_xfrbuffers[CONFIG_LPC17_USBHOST_NPREALLOC]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_printreg + * + * Description: + * Print the contents of an LPC17xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBHOST_REGDEBUG +static void lpc17_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: lpc17_checkreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBHOST_REGDEBUG +static void lpc17_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + lpc17_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + lpc17_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: lpc17_getreg + * + * Description: + * Get the contents of an LPC17xx register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBHOST_REGDEBUG +static uint32_t lpc17_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc17_putreg + * + * Description: + * Set the contents of an LPC17xx register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_USBHOST_REGDEBUG +static void lpc17_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + lpc17_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc17_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void lpc17_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: lpc17_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t lpc17_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: lpc17_putle16 + * + * Description: + * Put a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc17_putle16(uint8_t *dest, uint16_t val) +{ + dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */ + dest[1] = val >> 8; +} +#endif + +/**************************************************************************** + * Name: lpc17_edfree + * + * Description: + * Return an endpoint descriptor to the free list + * + ****************************************************************************/ + +static inline void lpc17_edfree(struct lpc17_ed_s *ed) +{ + struct lpc17_list_s *entry = (struct lpc17_list_s *)ed; + + /* Put the ED back into the free list */ + + entry->flink = g_edfree; + g_edfree = entry; +} + +/**************************************************************************** + * Name: lpc17_tdalloc + * + * Description: + * Allocate an transfer descriptor from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protected from conconcurrent access to the TD pool by the interrupt + * handler + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +static struct lpc17_gtd_s *lpc17_tdalloc(void) +{ + struct lpc17_gtd_s *ret; + irqstate_t flags; + + /* Disable interrupts momentarily so that lpc17_tdfree is not called from the + * interrupt handler. + */ + + flags = enter_critical_section(); + ret = (struct lpc17_gtd_s *)g_tdfree; + if (ret) + { + g_tdfree = ((struct lpc17_list_s *)ret)->flink; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc17_tdfree + * + * Description: + * Return an transfer descriptor to the free list + * + * Assumptions: + * - Only called from the WDH interrupt handler (and during initialization). + * - Interrupts are disabled in any case. + * + ****************************************************************************/ + +static void lpc17_tdfree(struct lpc17_gtd_s *td) +{ + struct lpc17_list_s *tdfree = (struct lpc17_list_s *)td; + + /* This should not happen but just to be safe, don't free the common, pre- + * allocated tail TD. + */ + + if (tdfree != NULL && td != TDTAIL) + { + tdfree->flink = g_tdfree; + g_tdfree = tdfree; + } +} + +/**************************************************************************** + * Name: lpc17_tballoc + * + * Description: + * Allocate an request/descriptor transfer buffer from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +static uint8_t *lpc17_tballoc(void) +{ + uint8_t *ret = (uint8_t *)g_tbfree; + if (ret) + { + g_tbfree = ((struct lpc17_list_s *)ret)->flink; + } + return ret; +} + +/**************************************************************************** + * Name: lpc17_tbfree + * + * Description: + * Return an request/descriptor transfer buffer to the free list + * + ****************************************************************************/ + +static void lpc17_tbfree(uint8_t *buffer) +{ + struct lpc17_list_s *tbfree = (struct lpc17_list_s *)buffer; + + if (tbfree) + { + tbfree->flink = g_tbfree; + g_tbfree = tbfree; + } +} + +/**************************************************************************** + * Name: lpc17_allocio + * + * Description: + * Allocate an IO buffer from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +#if LPC17_IOBUFFERS > 0 +static uint8_t *lpc17_allocio(void) +{ + uint8_t *ret; + irqstate_t flags; + + /* lpc17_freeio() may be called from the interrupt level */ + + flags = enter_critical_section(); + ret = (uint8_t *)g_iofree; + if (ret) + { + g_iofree = ((struct lpc17_list_s *)ret)->flink; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: lpc17_freeio + * + * Description: + * Return an TD buffer to the free list + * + ****************************************************************************/ + +#if LPC17_IOBUFFERS > 0 +static void lpc17_freeio(uint8_t *buffer) +{ + struct lpc17_list_s *iofree; + irqstate_t flags; + + /* Could be called from the interrupt level */ + + flags = enter_critical_section(); + iofree = (struct lpc17_list_s *)buffer; + iofree->flink = g_iofree; + g_iofree = iofree; + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: lpc17_alloc_xfrinfo + * + * Description: + * Allocate an asynchronous data structure from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +static struct lpc17_xfrinfo_s *lpc17_alloc_xfrinfo(void) +{ + struct lpc17_xfrinfo_s *ret; + irqstate_t flags; + + /* lpc17_free_xfrinfo() may be called from the interrupt level */ + + flags = enter_critical_section(); + ret = (struct lpc17_xfrinfo_s *)g_xfrfree; + if (ret) + { + g_xfrfree = ((struct lpc17_list_s *)ret)->flink; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc17_freeio + * + * Description: + * Return an TD buffer to the free list + * + ****************************************************************************/ + +static void lpc17_free_xfrinfo(struct lpc17_xfrinfo_s *xfrinfo) +{ + struct lpc17_list_s *node; + irqstate_t flags; + + /* Could be called from the interrupt level */ + + flags = enter_critical_section(); + node = (struct lpc17_list_s *)xfrinfo; + node->flink = g_xfrfree; + g_xfrfree = node; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc17_addctrled + * + * Description: + * Helper function to add an ED to the control list. + * + ****************************************************************************/ + +static inline int lpc17_addctrled(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ + irqstate_t flags; + uint32_t regval; + + /* Disable control list processing while we modify the list */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Add the new bulk ED to the head of the bulk list */ + + ed->hw.nexted = lpc17_getreg(LPC17_USBHOST_CTRLHEADED); + lpc17_putreg((uint32_t)ed, LPC17_USBHOST_CTRLHEADED); + + /* Re-enable control list processing. */ + + lpc17_putreg(0, LPC17_USBHOST_CTRLED); + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval |= OHCI_CTRL_CLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc17_remctrled + * + * Description: + * Helper function remove an ED from the control list. + * + ****************************************************************************/ + +static inline int lpc17_remctrled(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ + struct lpc17_ed_s *curr; + struct lpc17_ed_s *prev; + struct lpc17_ed_s *head; + irqstate_t flags; + uint32_t regval; + + /* Disable control list processing while we modify the list */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Find the ED in the control list. */ + + head = (struct lpc17_ed_s *)lpc17_getreg(LPC17_USBHOST_CTRLHEADED); + for (prev = NULL, curr = head; + curr && curr != ed; + prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted); + + /* It would be a bug if we do not find the ED in the control list. */ + + DEBUGASSERT(curr != NULL); + + /* Remove the ED from the control list */ + + if (curr != NULL) + { + /* Is this ED the first on in the control list? */ + + if (prev == NULL) + { + /* Yes... set the head of the control list to skip over this ED */ + + head = (struct lpc17_ed_s *)ed->hw.nexted; + lpc17_putreg((uint32_t)head, LPC17_USBHOST_CTRLHEADED); + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + } + + /* Just in case the hardware happens to be processing this ed now... + * it should go back to the control list head. + */ + + ed->hw.nexted = 0; + } + + /* Re-enable control list processing if the control list is still non-empty + * after removing the ED node. + */ + + lpc17_putreg(0, LPC17_USBHOST_CTRLED); + if (lpc17_getreg(LPC17_USBHOST_CTRLHEADED) != 0) + { + /* If the control list is now empty, then disable it */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc17_addbulked + * + * Description: + * Helper function to add an ED to the bulk list. + * + ****************************************************************************/ + +static inline int lpc17_addbulked(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_BULK_DISABLE + irqstate_t flags; + uint32_t regval; + + /* Disable bulk list processing while we modify the list */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_BLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Add the new bulk ED to the head of the bulk list */ + + ed->hw.nexted = lpc17_getreg(LPC17_USBHOST_BULKHEADED); + lpc17_putreg((uint32_t)ed, LPC17_USBHOST_BULKHEADED); + + /* Re-enable bulk list processing. */ + + lpc17_putreg(0, LPC17_USBHOST_BULKED); + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval |= OHCI_CTRL_BLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: lpc17_rembulked + * + * Description: + * Helper function remove an ED from the bulk list. + * + ****************************************************************************/ + +static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_BULK_DISABLE + struct lpc17_ed_s *curr; + struct lpc17_ed_s *prev; + struct lpc17_ed_s *head; + irqstate_t flags; + uint32_t regval; + + /* Disable bulk list processing while we modify the list */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_BLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Find the ED in the bulk list. */ + + head = (struct lpc17_ed_s *)lpc17_getreg(LPC17_USBHOST_BULKHEADED); + for (prev = NULL, curr = head; + curr && curr != ed; + prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted); + + /* It would be a bug if we do not find the ED in the bulk list. */ + + DEBUGASSERT(curr != NULL); + + /* Remove the ED from the bulk list */ + + if (curr != NULL) + { + /* Is this ED the first on in the bulk list? */ + + if (prev == NULL) + { + /* Yes... set the head of the bulk list to skip over this ED */ + + head = (struct lpc17_ed_s *)ed->hw.nexted; + lpc17_putreg((uint32_t)head, LPC17_USBHOST_BULKHEADED); + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + } + } + + /* Re-enable bulk list processing if the bulk list is still non-empty + * after removing the ED node. + */ + + lpc17_putreg(0, LPC17_USBHOST_BULKED); + if (lpc17_getreg(LPC17_USBHOST_BULKHEADED) != 0) + { + /* If the bulk list is now empty, then disable it */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval |= OHCI_CTRL_BLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + } + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: lpc17_getinterval + * + * Description: + * Convert the endpoint polling interval into a HCCA table increment + * + ****************************************************************************/ + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static unsigned int lpc17_getinterval(uint8_t interval) +{ + /* The bInterval field of the endpoint descriptor contains the polling interval + * for interrupt and isochronous endpoints. For other types of endpoint, this + * value should be ignored. bInterval is provided in units of 1MS frames. + */ + + if (interval < 3) + { + return 2; + } + else if (interval < 7) + { + return 4; + } + else if (interval < 15) + { + return 8; + } + else if (interval < 31) + { + return 16; + } + else + { + return 32; + } +} +#endif + +/**************************************************************************** + * Name: lpc17_setinttab + * + * Description: + * Set the interrupt table to the selected value using the provided interval + * and offset. + * + ****************************************************************************/ + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int offset) +{ + unsigned int i; + for (i = offset; i < HCCA_INTTBL_WSIZE; i += interval) + { + HCCA->inttbl[i] = value; + } +} +#endif + +/**************************************************************************** + * Name: lpc17_addinted + * + * Description: + * Helper function to add an ED to the HCCA interrupt table. + * + * To avoid reshuffling the table so much and to keep life simple in general, + * the following rules are applied: + * + * 1. IN EDs get the even entries, OUT EDs get the odd entries. + * 2. Add IN/OUT EDs are scheduled together at the minimum interval of all + * IN/OUT EDs. + * + * This has the following consequences: + * + * 1. The minimum support polling rate is 2MS, and + * 2. Some devices may get polled at a much higher rate than they request. + * + ****************************************************************************/ + +static inline int lpc17_addinted(struct lpc17_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_INT_DISABLE + unsigned int interval; + unsigned int offset; + uint32_t head; + uint32_t regval; + + /* Disable periodic list processing. Does this take effect immediately? Or + * at the next SOF... need to check. + */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_PLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Get the quantized interval value associated with this ED and save it + * in the ED. + */ + + interval = lpc17_getinterval(epdesc->interval); + ed->interval = interval; + uvdbg("interval: %d->%d\n", epdesc->interval, interval); + + /* Get the offset associated with the ED direction. IN EDs get the even + * entries, OUT EDs get the odd entries. + * + * Get the new, minimum interval. Add IN/OUT EDs are scheduled together + * at the minimum interval of all IN/OUT EDs. + */ + + if (epdesc->in) + { + offset = 0; + if (priv->ininterval > interval) + { + priv->ininterval = interval; + } + else + { + interval = priv->ininterval; + } + } + else + { + offset = 1; + if (priv->outinterval > interval) + { + priv->outinterval = interval; + } + else + { + interval = priv->outinterval; + } + } + uvdbg("min interval: %d offset: %d\n", interval, offset); + + /* Get the head of the first of the duplicated entries. The first offset + * entry is always guaranteed to contain the common ED list head. + */ + + head = HCCA->inttbl[offset]; + + /* Clear all current entries in the interrupt table for this direction */ + + lpc17_setinttab(0, 2, offset); + + /* Add the new ED before the old head of the periodic ED list and set the + * new ED as the head ED in all of the appropriate entries of the HCCA + * interrupt table. + */ + + ed->hw.nexted = head; + lpc17_setinttab((uint32_t)ed, interval, offset); + uvdbg("head: %08x next: %08x\n", ed, head); + + /* Re-enabled periodic list processing */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval |= OHCI_CTRL_PLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: lpc17_reminted + * + * Description: + * Helper function to remove an ED from the HCCA interrupt table. + * + * To avoid reshuffling the table so much and to keep life simple in general, + * the following rules are applied: + * + * 1. IN EDs get the even entries, OUT EDs get the odd entries. + * 2. Add IN/OUT EDs are scheduled together at the minimum interval of all + * IN/OUT EDs. + * + * This has the following consequences: + * + * 1. The minimum support polling rate is 2MS, and + * 2. Some devices may get polled at a much higher rate than they request. + * + ****************************************************************************/ + +static inline int lpc17_reminted(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_INT_DISABLE + struct lpc17_ed_s *head; + struct lpc17_ed_s *curr; + struct lpc17_ed_s *prev; + unsigned int interval; + unsigned int offset; + uint32_t regval; + + /* Disable periodic list processing. Does this take effect immediately? Or + * at the next SOF... need to check. + */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_PLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Get the offset associated with the ED direction. IN EDs get the even + * entries, OUT EDs get the odd entries. + */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + offset = 0; + } + else + { + offset = 1; + } + + /* Get the head of the first of the duplicated entries. The first offset + * entry is always guaranteed to contain the common ED list head. + */ + + head = (struct lpc17_ed_s *)HCCA->inttbl[offset]; + uvdbg("ed: %08x head: %08x next: %08x offset: %d\n", + ed, head, head ? head->hw.nexted : 0, offset); + + /* Find the ED to be removed in the ED list */ + + for (curr = head, prev = NULL; + curr && curr != ed; + prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted); + + /* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */ + + DEBUGASSERT(curr != NULL); + if (curr != NULL) + { + /* Clear all current entries in the interrupt table for this direction */ + + lpc17_setinttab(0, 2, offset); + + /* Remove the ED from the list.. Is this ED the first on in the list? */ + + if (prev == NULL) + { + /* Yes... set the head of the bulk list to skip over this ED */ + + head = (struct lpc17_ed_s *)ed->hw.nexted; + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + } + + uvdbg("ed: %08x head: %08x next: %08x\n", + ed, head, head ? head->hw.nexted : 0); + + /* Calculate the new minimum interval for this list */ + + interval = MAX_PERINTERVAL; + for (curr = head; curr; curr = (struct lpc17_ed_s *)curr->hw.nexted) + { + if (curr->interval < interval) + { + interval = curr->interval; + } + } + + uvdbg("min interval: %d offset: %d\n", interval, offset); + + /* Save the new minimum interval */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + priv->ininterval = interval; + } + else + { + priv->outinterval = interval; + } + + /* Set the head ED in all of the appropriate entries of the HCCA interrupt + * table (head might be NULL). + */ + + lpc17_setinttab((uint32_t)head, interval, offset); + } + + /* Re-enabled periodic list processing */ + + if (head != NULL) + { + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval |= OHCI_CTRL_PLE; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + } + + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: lpc17_addisoced + * + * Description: + * Helper functions to add an ED to the periodic table. + * + ****************************************************************************/ + +static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_ISOC_DISABLE +# warning "Isochronous endpoints not yet supported" +#endif + return -ENOSYS; +} + +/**************************************************************************** + * Name: lpc17_remisoced + * + * Description: + * Helper functions to remove an ED from the periodic table. + * + ****************************************************************************/ + +static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_ISOC_DISABLE +# warning "Isochronous endpoints not yet supported" +#endif + return -ENOSYS; +} + +/**************************************************************************** + * Name: lpc17_enqueuetd + * + * Description: + * Enqueue a transfer descriptor. Notice that this function only supports + * queue on TD per ED. + * + ****************************************************************************/ + +static int lpc17_enqueuetd(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint32_t dirpid, + uint32_t toggle, volatile uint8_t *buffer, size_t buflen) +{ + struct lpc17_gtd_s *td; + int ret = -ENOMEM; + + /* Allocate a TD from the free list */ + + td = lpc17_tdalloc(); + if (td != NULL) + { + /* Initialize the allocated TD and link it before the common tail TD. */ + + td->hw.ctrl = (GTD_STATUS_R | dirpid | TD_DELAY(0) | toggle | GTD_STATUS_CC_MASK); + TDTAIL->hw.ctrl = 0; + td->hw.cbp = (uint32_t)buffer; + TDTAIL->hw.cbp = 0; + td->hw.nexttd = (uint32_t)TDTAIL; + TDTAIL->hw.nexttd = 0; + td->hw.be = (uint32_t)(buffer + (buflen - 1)); + TDTAIL->hw.be = 0; + + /* Configure driver-only fields in the extended TD structure */ + + td->ed = ed; + + /* Link the td to the head of the ED's TD list */ + + ed->hw.headp = (uint32_t)td | ((ed->hw.headp) & ED_HEADP_C); + ed->hw.tailp = (uint32_t)TDTAIL; + + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_wdhwait + * + * Description: + * Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + ****************************************************************************/ + +static int lpc17_wdhwait(struct lpc17_usbhost_s *priv, struct lpc17_ed_s *ed) +{ + struct lpc17_xfrinfo_s *xfrinfo; + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + DEBUGASSERT(ed && ed->xfrinfo); + xfrinfo = ed->xfrinfo; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set wdhwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + xfrinfo->wdhwait = true; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc17_ctrltd + * + * Description: + * Process a IN or OUT request on the control endpoint. This function + * will enqueue the request and wait for it to complete. Only one transfer + * may be queued; Neither these methods nor the transfer() method can be + * called again until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + ****************************************************************************/ + +static int lpc17_ctrltd(struct lpc17_usbhost_s *priv, struct lpc17_ed_s *ed, + uint32_t dirpid, uint8_t *buffer, size_t buflen) +{ + struct lpc17_xfrinfo_s *xfrinfo; + uint32_t toggle; + uint32_t regval; + int ret; + + /* Allocate a structure to retain the information needed when the transfer + * completes. + */ + + DEBUGASSERT(ed->xfrinfo == NULL); + + xfrinfo = lpc17_alloc_xfrinfo(); + if (xfrinfo == NULL) + { + udbg("ERROR: lpc17_alloc_xfrinfo failed\n"); + return -ENOMEM; + } + + /* Initialize the transfer structure */ + + memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); + xfrinfo->buffer = buffer; + xfrinfo->buflen = buflen; + + ed->xfrinfo = xfrinfo; + + /* Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer. + */ + + ret = lpc17_wdhwait(priv, ed); + if (ret < 0) + { + udbg("ERROR: Device disconnected\n"); + goto errout_with_xfrinfo; + } + + /* Configure the toggle field in the TD */ + + if (dirpid == GTD_STATUS_DP_SETUP) + { + toggle = GTD_STATUS_T_DATA0; + } + else + { + toggle = GTD_STATUS_T_DATA1; + } + + /* Then enqueue the transfer */ + + xfrinfo->tdstatus = TD_CC_NOERROR; + ret = lpc17_enqueuetd(priv, ed, dirpid, toggle, buffer, buflen); + if (ret == OK) + { + /* Set ControlListFilled. This bit is used to indicate whether there are + * TDs on the Control list. + */ + + regval = lpc17_getreg(LPC17_USBHOST_CMDST); + regval |= OHCI_CMDST_CLF; + lpc17_putreg(regval, LPC17_USBHOST_CMDST); + + /* Wait for the Writeback Done Head interrupt */ + + lpc17_takesem(&ed->wdhsem); + + /* Check the TD completion status bits */ + + if (xfrinfo->tdstatus == TD_CC_NOERROR) + { + ret = OK; + } + else + { + udbg("ERROR: Bad TD completion status: %d\n", xfrinfo->tdstatus); + ret = xfrinfo->tdstatus == TD_CC_STALL ? -EPERM : -EIO; + } + } + + /* Make sure that there is no outstanding request on this endpoint */ + +errout_with_xfrinfo: + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + return ret; +} + +/**************************************************************************** + * Name: lpc17_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int lpc17_usbinterrupt(int irq, void *context) +{ + struct lpc17_usbhost_s *priv = &g_usbhost; + struct lpc17_ed_s *ed; + struct lpc17_xfrinfo_s *xfrinfo; + uintptr_t tmp; + uint32_t intst; + uint32_t pending; + uint32_t regval; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + intst = lpc17_getreg(LPC17_USBHOST_INTST); + regval = lpc17_getreg(LPC17_USBHOST_INTEN); + ullvdbg("INST: %08x INTEN: %08x\n", intst, regval); + + pending = intst & regval; + if (pending != 0) + { + /* Root hub status change interrupt */ + + if ((pending & OHCI_INT_RHSC) != 0) + { + uint32_t rhportst1 = lpc17_getreg(LPC17_USBHOST_RHPORTST1); + ullvdbg("Root Hub Status Change, RHPORTST1: %08x\n", rhportst1); + + if ((rhportst1 & OHCI_RHPORTST_CSC) != 0) + { + uint32_t rhstatus = lpc17_getreg(LPC17_USBHOST_RHSTATUS); + ullvdbg("Connect Status Change, RHSTATUS: %08x\n", rhstatus); + + /* If DRWE is set, Connect Status Change indicates a remote wake-up event */ + + if (rhstatus & OHCI_RHSTATUS_DRWE) + { + ullvdbg("DRWE: Remote wake-up\n"); + } + + /* Otherwise... Not a remote wake-up event */ + + else + { + /* Check current connect status */ + + if ((rhportst1 & OHCI_RHPORTST_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!priv->connected) + { + /* Yes.. connected. */ + + ullvdbg("Connected\n"); + priv->connected = true; + priv->change = true; + + /* Notify any waiters */ + + if (priv->pscwait) + { + lpc17_givesem(&priv->pscsem); + priv->pscwait = false; + } + } + else + { + ulldbg("Spurious status change (connected)\n"); + } + + /* The LSDA (Low speed device attached) bit is valid + * when CCS == 1. + */ + + if ((rhportst1 & OHCI_RHPORTST_LSDA) != 0) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + ullvdbg("Speed:%d\n", priv->rhport.hport.speed); + } + + /* Check if we are now disconnected */ + + else if (priv->connected) + { + /* Yes.. disconnect the device */ + + ullvdbg("Disconnected\n"); + priv->connected = false; + priv->change = true; + + /* Set the port speed to the default (FULL). We cannot + * yet free the function address. That has to be done + * by the class when responds to the disconnection. + */ + + priv->rhport.hport.speed = USB_SPEED_FULL; + + /* Are we bound to a class instance? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change event */ + + if (priv->pscwait) + { + lpc17_givesem(&priv->pscsem); + priv->pscwait = false; + } + } + else + { + ulldbg("Spurious status change (disconnected)\n"); + } + } + + /* Clear the status change interrupt */ + + lpc17_putreg(OHCI_RHPORTST_CSC, LPC17_USBHOST_RHPORTST1); + } + + /* Check for port reset status change */ + + if ((rhportst1 & OHCI_RHPORTST_PRSC) != 0) + { + /* Release the RH port from reset */ + + lpc17_putreg(OHCI_RHPORTST_PRSC, LPC17_USBHOST_RHPORTST1); + } + } + + /* Writeback Done Head interrupt */ + + if ((pending & OHCI_INT_WDH) != 0) + { + struct lpc17_gtd_s *td; + struct lpc17_gtd_s *next; + + /* The host controller just wrote the list of finished TDs into the HCCA + * done head. This may include multiple packets that were transferred + * in the preceding frame. + * + * Remove the TD(s) from the Writeback Done Head in the HCCA and return + * them to the free list. Note that this is safe because the hardware + * will not modify the writeback done head again until the WDH bit is + * cleared in the interrupt status register. + */ + + td = (struct lpc17_gtd_s *)(HCCA->donehead & HCCA_DONEHEAD_MASK); + HCCA->donehead = 0; + next = NULL; + + /* Process each TD in the write done list */ + + for (; td; td = next) + { + /* REVISIT: I have encountered bad TDs in the done list linked + * after at least one good TD. This is some consequence of how + * transfers are being cancelled. But for now, I have only + * this work-around. + */ + + if ((uintptr_t)td < LPC17_TDFREE_BASE || + (uintptr_t)td >= (LPC17_TDFREE_BASE + LPC17_TD_SIZE*CONFIG_USBHOST_NTDS)) + { + break; + } + + /* Get the ED in which this TD was enqueued */ + + ed = td->ed; + DEBUGASSERT(ed != NULL); + + /* If there is a transfer in progress, then the xfrinfo pointer will be + * non-NULL. But it appears that a NULL pointer may be received with a + * spurious interrupt such as may occur after a transfer is cancelled. + */ + + xfrinfo = ed->xfrinfo; + if (xfrinfo) + { + /* Save the condition code from the (single) TD status/control + * word. + */ + + xfrinfo->tdstatus = (td->hw.ctrl & GTD_STATUS_CC_MASK) >> GTD_STATUS_CC_SHIFT; + +#ifdef CONFIG_DEBUG_USB + if (xfrinfo->tdstatus != TD_CC_NOERROR) + { + /* The transfer failed for some reason... dump some diagnostic info. */ + + ulldbg("ERROR: ED xfrtype:%d TD CTRL:%08x/CC:%d RHPORTST1:%08x\n", + ed->xfrtype, td->hw.ctrl, xfrinfo->tdstatus, + lpc17_getreg(LPC17_USBHOST_RHPORTST1)); + } +#endif + + /* Determine the number of bytes actually transfer by + * subtracting the buffer start address from the CBP. A + * value of zero means that all bytes were transferred. + */ + + tmp = (uintptr_t)td->hw.cbp; + if (tmp == 0) + { + /* Set the (fake) CBP to the end of the buffer + 1 */ + + tmp = xfrinfo->buflen; + } + else + { + DEBUGASSERT(tmp >= (uintptr_t)xfrinfo->buffer); + + /* Determine the size of the transfer by subtracting + * the current buffer pointer (CBP) from the initial + * buffer pointer (on packet receipt only). + */ + + tmp -= (uintptr_t)xfrinfo->buffer; + DEBUGASSERT(tmp < UINT16_MAX); + } + + xfrinfo->xfrd = (uint16_t)tmp; + + /* Return the TD to the free list */ + + next = (struct lpc17_gtd_s *)td->hw.nexttd; + lpc17_tdfree(td); + + if (xfrinfo->wdhwait) + { + /* Wake up the thread waiting for the WDH event */ + + lpc17_givesem(&ed->wdhsem); + xfrinfo->wdhwait = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* Perform any pending callbacks for the case of + * asynchronous transfers. + */ + + else if (xfrinfo->callback) + { + DEBUGASSERT(xfrinfo->wdhwait == false); + lpc17_asynch_completion(priv, ed); + } +#endif + } + } + } + +#ifdef CONFIG_DEBUG_USB + if ((pending & LPC17_DEBUG_INTS) != 0) + { + ulldbg("ERROR: Unhandled interrupts INTST:%08x\n", intst); + } +#endif + + /* Clear interrupt status register */ + + lpc17_putreg(intst, LPC17_USBHOST_INTST); + } + + return OK; +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)&g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + priv->change = false; + + /* Yes.. check for false alarms */ + + if (priv->connected != connport->connected) + { + /* Not a false alarm.. Remember the new state */ + + connport->connected = priv->connected; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + udbg("RHport Connected: %s\n", + connport->connected ? "YES" : "NO"); + + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + udbg("Hub port Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + lpc17_takesem(&priv->pscsem); + } +} + +/**************************************************************************** + * Name: lpc17_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_rh_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)&g_usbhost; + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + udbg("Not connected\n"); + return -ENODEV; + } + + /* USB 2.0 spec says at least 50ms delay before port reset */ + + (void)usleep(100*1000); + + /* Put RH port 1 in reset (the LPC176x supports only a single downstream port) */ + + lpc17_putreg(OHCI_RHPORTST_PRS, LPC17_USBHOST_RHPORTST1); + + /* Wait for the port reset to complete */ + + while ((lpc17_getreg(LPC17_USBHOST_RHPORTST1) & OHCI_RHPORTST_PRS) != 0); + + /* Release RH port 1 from reset and wait a bit */ + + lpc17_putreg(OHCI_RHPORTST_PRSC, LPC17_USBHOST_RHPORTST1); + (void)usleep(200*1000); + return OK; +} + +static int lpc17_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = lpc17_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uvdbg("Enumerate the device\n"); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + udbg("ERROR: Enumeration failed: %d\n", ret); + } + + return ret; +} + +/************************************************************************************ + * Name: lpc17_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * mps (maxpacketsize) - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc17_ep0configure(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed; + uint32_t hwctrl; + + DEBUGASSERT(drvr != NULL && ep0 != NULL && funcaddr < 128 && maxpacketsize < 2048); + ed = (struct lpc17_ed_s *)ep0; + + /* We must have exclusive access to EP0 and the control list */ + + lpc17_takesem(&priv->exclsem); + + /* Set the EP0 ED control word */ + + hwctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | + (uint32_t)ED_CONTROL_D_TD1 | + (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + + if (speed == USB_SPEED_LOW) + { + hwctrl |= ED_CONTROL_S; + } + + ed->hw.ctrl = hwctrl; + + lpc17_givesem(&priv->exclsem); + + uvdbg("EP0 CTRL:%08x\n", ed->hw.ctrl); + return OK; +} + +/************************************************************************************ + * Name: lpc17_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc17_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct usbhost_hubport_s *hport; + struct lpc17_ed_s *ed; + int ret = -ENOMEM; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(priv && epdesc && ep && priv->connected); + + /* We must have exclusive access to the ED pool, the bulk list, the periodic list + * and the interrupt table. + */ + + lpc17_takesem(&priv->exclsem); + + /* Take the next ED from the beginning of the free list */ + + ed = (struct lpc17_ed_s *)g_edfree; + if (ed) + { + /* Remove the ED from the freelist */ + + g_edfree = ((struct lpc17_list_s *)ed)->flink; + + /* Configure the endpoint descriptor. */ + + memset((void *)ed, 0, sizeof(struct lpc17_ed_s)); + + hport = epdesc->hport; + ed->hw.ctrl = (uint32_t)(hport->funcaddr) << ED_CONTROL_FA_SHIFT | + (uint32_t)(epdesc->addr) << ED_CONTROL_EN_SHIFT | + (uint32_t)(epdesc->mxpacketsize) << ED_CONTROL_MPS_SHIFT; + + /* Get the direction of the endpoint. For control endpoints, the + * direction is in the TD. + */ + + if (epdesc->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + ed->hw.ctrl |= ED_CONTROL_D_TD1; + } + else if (epdesc->in) + { + ed->hw.ctrl |= ED_CONTROL_D_IN; + } + else + { + ed->hw.ctrl |= ED_CONTROL_D_OUT; + } + + /* Check for a low-speed device */ + + if (hport->speed == USB_SPEED_LOW) + { + ed->hw.ctrl |= ED_CONTROL_S; + } + + /* Set the transfer type */ + + ed->xfrtype = epdesc->xfrtype; + + /* Special Case isochronous transfer types */ + +#if 0 /* Isochronous transfers not yet supported */ + if (ed->xfrtype == USB_EP_ATTR_XFER_ISOC) + { + ed->hw.ctrl |= ED_CONTROL_F; + } +#endif + uvdbg("EP%d CTRL:%08x\n", epdesc->addr, ed->hw.ctrl); + + /* Initialize the semaphore that is used to wait for the endpoint + * WDH event. + */ + + sem_init(&ed->wdhsem, 0, 0); + + /* Link the common tail TD to the ED's TD list */ + + ed->hw.headp = (uint32_t)TDTAIL; + ed->hw.tailp = (uint32_t)TDTAIL; + + /* Now add the endpoint descriptor to the appropriate list */ + + switch (ed->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + ret = lpc17_addctrled(priv, ed); + break; + + case USB_EP_ATTR_XFER_BULK: + ret = lpc17_addbulked(priv, ed); + break; + + case USB_EP_ATTR_XFER_INT: + ret = lpc17_addinted(priv, epdesc, ed); + break; + + case USB_EP_ATTR_XFER_ISOC: + ret = lpc17_addisoced(priv, epdesc, ed); + break; + + default: + ret = -EINVAL; + break; + } + + /* Was the ED successfully added? */ + + if (ret < 0) + { + /* No.. destroy it and report the error */ + + udbg("ERROR: Failed to queue ED for transfer type: %d\n", ed->xfrtype); + sem_destroy(&ed->wdhsem); + lpc17_edfree(ed); + } + else + { + /* Yes.. return an opaque reference to the ED */ + + *ep = (usbhost_ep_t)ed; + } + } + + lpc17_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: lpc17_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc17_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep; + int ret; + + /* There should not be any pending, real TDs linked to this ED */ + + DEBUGASSERT(ed && (ed->hw.headp & ED_HEADP_ADDR_MASK) == LPC17_TDTAIL_ADDR); + + /* We must have exclusive access to the ED pool, the bulk list, the periodic list + * and the interrupt table. + */ + + lpc17_takesem(&priv->exclsem); + + /* Remove the ED to the correct list depending on the trasfer type */ + + switch (ed->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + ret = lpc17_remctrled(priv, ed); + break; + + case USB_EP_ATTR_XFER_BULK: + ret = lpc17_rembulked(priv, ed); + break; + + case USB_EP_ATTR_XFER_INT: + ret = lpc17_reminted(priv, ed); + break; + + case USB_EP_ATTR_XFER_ISOC: + ret = lpc17_remisoced(priv, ed); + break; + + default: + ret = -EINVAL; + break; + } + + /* Destroy the semaphore */ + + sem_destroy(&ed->wdhsem); + + /* Put the ED back into the free list */ + + lpc17_edfree(ed); + lpc17_givesem(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * Name: lpc17_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + DEBUGASSERT(priv && buffer && maxlen); + int ret = -ENOMEM; + + /* We must have exclusive access to the transfer buffer pool */ + + lpc17_takesem(&priv->exclsem); + + *buffer = lpc17_tballoc(); + if (*buffer) + { + *maxlen = CONFIG_USBHOST_TDBUFSIZE; + ret = OK; + } + + lpc17_givesem(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * Name: lpc17_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to free that + * request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_free(struct usbhost_driver_s *drvr, uint8_t *buffer) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + DEBUGASSERT(buffer); + + /* We must have exclusive access to the transfer buffer pool */ + + lpc17_takesem(&priv->exclsem); + lpc17_tbfree(buffer); + lpc17_givesem(&priv->exclsem); + return OK; +} + +/************************************************************************************ + * Name: lpc17_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc17_ioalloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t buflen) +{ + DEBUGASSERT(drvr && buffer); + +#if LPC17_IOBUFFERS > 0 + if (buflen <= CONFIG_USBHOST_IOBUFSIZE) + { + uint8_t *alloc = lpc17_allocio(); + if (alloc) + { + *buffer = alloc; + return OK; + } + } + + return -ENOMEM; +#else + return -ENOSYS; +#endif +} + +/************************************************************************************ + * Name: lpc17_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc17_iofree(struct usbhost_driver_s *drvr, uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + +#if LPC17_IOBUFFERS > 0 + lpc17_freeio(buffer); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: lpc17_ctrlin and lpc17_ctrlout + * + * Description: + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep0; + uint16_t len; + int ret; + + DEBUGASSERT(priv != NULL && ed != NULL && req != NULL); + + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* We must have exclusive access to EP0 and the control list */ + + lpc17_takesem(&priv->exclsem); + + len = lpc17_getle16(req->len); + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_SETUP, (uint8_t *)req, USB_SIZEOF_CTRLREQ); + if (ret == OK) + { + if (len) + { + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_IN, buffer, len); + } + + if (ret == OK) + { + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_OUT, NULL, 0); + } + } + + lpc17_givesem(&priv->exclsem); + return ret; +} + +static int lpc17_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep0; + uint16_t len; + int ret; + + DEBUGASSERT(priv != NULL && ed != NULL && req != NULL); + + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* We must have exclusive access to EP0 and the control list */ + + lpc17_takesem(&priv->exclsem); + + len = lpc17_getle16(req->len); + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_SETUP, (uint8_t *)req, USB_SIZEOF_CTRLREQ); + if (ret == OK) + { + if (len) + { + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_OUT, (uint8_t *)buffer, len); + } + + if (ret == OK) + { + ret = lpc17_ctrltd(priv, ed, GTD_STATUS_DP_IN, NULL, 0); + } + } + + lpc17_givesem(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * Name: lpc17_transfer_common + * + * Description: + * Initiate a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately + * + * Input Parameters: + * priv - Internal driver state structure. + * ed - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc17_transfer_common(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *buffer, + size_t buflen) +{ + struct lpc17_xfrinfo_s *xfrinfo; + uint32_t dirpid; + uint32_t regval; + bool in; + int ret; + + xfrinfo = ed->xfrinfo; + in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN; + + uvdbg("EP%u %s toggle:%u maxpacket:%u buflen:%lu\n", + (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT, + in ? "IN" : "OUT", + (ed->hw.headp & ED_HEADP_C) != 0 ? 1 : 0, + (ed->hw.ctrl & ED_CONTROL_MPS_MASK) >> ED_CONTROL_MPS_SHIFT, + (unsigned long)buflen); + + /* Get the direction of the endpoint */ + + if (in) + { + dirpid = GTD_STATUS_DP_IN; + } + else + { + dirpid = GTD_STATUS_DP_OUT; + } + + /* Then enqueue the transfer */ + + xfrinfo->tdstatus = TD_CC_NOERROR; + ret = lpc17_enqueuetd(priv, ed, dirpid, GTD_STATUS_T_TOGGLE, buffer, buflen); + if (ret == OK) + { + /* BulkListFilled. This bit is used to indicate whether there are any + * TDs on the Bulk list. + */ + + if (ed->xfrtype == USB_EP_ATTR_XFER_BULK) + { + regval = lpc17_getreg(LPC17_USBHOST_CMDST); + regval |= OHCI_CMDST_BLF; + lpc17_putreg(regval, LPC17_USBHOST_CMDST); + } + } + + return ret; +} + +/**************************************************************************** + * Name: lpc17_dma_alloc + * + * Description: + * Allocate DMA memory to perform a transfer, copying user data as necessary + * + * Input Parameters: + * priv - Internal driver state structure. + * ed - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * userbuffer - The user buffer containing the data to be sent (OUT endpoint) + * or received (IN endpoint). + * buflen - The length of the data to be sent or received. + * alloc - The location to return the allocated DMA buffer. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#if LPC17_IOBUFFERS > 0 +static int lpc17_dma_alloc(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *userbuffer, + size_t buflen, uint8_t **alloc) +{ + uint8_t *newbuffer; + + if ((uintptr_t)userbuffer < LPC17_SRAM_BANK0 || + (uintptr_t)userbuffer >= (LPC17_SRAM_BANK0 + LPC17_BANK0_SIZE + LPC17_BANK1_SIZE)) + { + /* Will the transfer fit in an IO buffer? */ + + if (buflen > CONFIG_USBHOST_IOBUFSIZE) + { + uvdbg("buflen (%d) > IO buffer size (%d)\n", + buflen, CONFIG_USBHOST_IOBUFSIZE); + return -ENOMEM; + } + + /* Allocate an IO buffer in AHB SRAM */ + + newbuffer = lpc17_allocio(); + if (!newbuffer) + { + uvdbg("IO buffer allocation failed\n"); + return -ENOMEM; + } + + /* If this is an OUT transaction, copy the user data into the AHB + * SRAM IO buffer. Sad... so inefficient. But without exposing + * the AHB SRAM to the final, end-user client I don't know of any + * way around this copy. + */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) != ED_CONTROL_D_IN) + { + memcpy(newbuffer, userbuffer, buflen); + } + + /* Return the allocated buffer */ + + *alloc = newbuffer; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc17_dma_free + * + * Description: + * Free allocated DMA memory. + * + * Input Parameters: + * priv - Internal driver state structure. + * ed - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * userbuffer - The user buffer containing the data to be sent (OUT endpoint) + * or received (IN endpoint). + * buflen - The length of the data to be sent or received. + * alloc - The allocated DMA buffer to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void lpc17_dma_free(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed, uint8_t *userbuffer, + size_t buflen, uint8_t *newbuffer) +{ + irqstate_t flags; + + /* Could be called from the interrupt level */ + + flags = enter_critical_section(); + if (userbuffer && newbuffer) + { + /* If this is an IN transaction, get the user data from the AHB + * SRAM IO buffer. Sad... so inefficient. But without exposing + * the AHB SRAM to the final, end-user client I don't know of any + * way around this copy. + */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + memcpy(userbuffer, newbuffer, buflen); + } + + /* Then free the temporary I/O buffer */ + + lpc17_freeio(newbuffer); + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: lpc17_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t lpc17_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep; + struct lpc17_xfrinfo_s *xfrinfo; +#if LPC17_IOBUFFERS > 0 + uint8_t *alloc = NULL; + uint8_t *userbuffer = NULL; +#endif + ssize_t nbytes; + int ret; + + DEBUGASSERT(priv && ed && buffer && buflen > 0); + + /* We must have exclusive access to the endpoint, the TD pool, the I/O buffer + * pool, the bulk and interrupt lists, and the HCCA interrupt table. + */ + + lpc17_takesem(&priv->exclsem); + + /* Allocate a structure to retain the information needed when the transfer + * completes. + */ + + DEBUGASSERT(ed->xfrinfo == NULL); + + xfrinfo = lpc17_alloc_xfrinfo(); + if (xfrinfo == NULL) + { + udbg("ERROR: lpc17_alloc_xfrinfo failed\n"); + nbytes = -ENOMEM; + goto errout_with_sem; + } + + /* Initialize the transfer structure */ + + memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); + xfrinfo->buffer = buffer; + xfrinfo->buflen = buflen; + + ed->xfrinfo = xfrinfo; + +#if LPC17_IOBUFFERS > 0 + /* Allocate an IO buffer if the user buffer does not lie in AHB SRAM */ + + ret = lpc17_dma_alloc(priv, ed, buffer, buflen, &alloc); + if (ret < 0) + { + udbg("ERROR: lpc17_dma_alloc failed: %d\n", ret); + nbytes = (ssize_t)ret; + goto errout_with_xfrinfo; + } + + /* If a buffer was allocated, then use it instead of the callers buffer */ + + if (alloc) + { + userbuffer = buffer; + buffer = alloc; + } +#endif + + /* Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer. + */ + + ret = lpc17_wdhwait(priv, ed); + if (ret < 0) + { + udbg("ERROR: Device disconnected\n"); + nbytes = (ssize_t)ret; + goto errout_with_buffers; + } + + /* Set up the transfer */ + + ret = lpc17_transfer_common(priv, ed, buffer, buflen); + if (ret < 0) + { + udbg("ERROR: lpc17_transfer_common failed: %d\n", ret); + nbytes = (ssize_t)ret; + goto errout_with_wdhwait; + } + + /* Wait for the Writeback Done Head interrupt */ + + lpc17_takesem(&ed->wdhsem); + + /* Check the TD completion status bits */ + + if (xfrinfo->tdstatus == TD_CC_NOERROR) + { + /* Return the number of bytes successfully transferred */ + + nbytes = xfrinfo->xfrd; + DEBUGASSERT(nbytes >= 0 && nbytes <= buflen); + } + else + { + /* Map the bad completion status to something that a class driver + * might understand. + */ + + udbg("ERROR: Bad TD completion status: %d\n", xfrinfo->tdstatus); + + switch (xfrinfo->tdstatus) + { + case TD_CC_STALL: + nbytes = -EPERM; + break; + + case TD_CC_USER: + nbytes = -ESHUTDOWN; + break; + + default: + nbytes = -EIO; + break; + } + } + +errout_with_wdhwait: + /* Make sure that there is no outstanding request on this endpoint */ + + xfrinfo->wdhwait = false; + +errout_with_buffers: +#if LPC17_IOBUFFERS > 0 + /* Free any temporary IO buffers */ + + lpc17_dma_free(priv, ed, userbuffer, buflen, alloc); +#endif + +errout_with_xfrinfo: + /* Make sure that there is no outstanding request on this endpoint */ + + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + +errout_with_sem: + lpc17_givesem(&priv->exclsem); + return nbytes; +} + +/**************************************************************************** + * Name: lpc17_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * priv - Internal driver state structure. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which the + * transfer was performed. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void lpc17_asynch_completion(struct lpc17_usbhost_s *priv, + struct lpc17_ed_s *ed) +{ + struct lpc17_xfrinfo_s *xfrinfo; + usbhost_asynch_t callback; + void *arg; + ssize_t nbytes; + + DEBUGASSERT(ed != NULL && ed->xfrinfo != NULL); + xfrinfo = ed->xfrinfo; + + DEBUGASSERT(xfrinfo->wdhwait == false && xfrinfo->callback != NULL && + xfrinfo->buffer != NULL && xfrinfo->buflen > 0); + + /* Check the TD completion status bits */ + + if (xfrinfo->tdstatus == TD_CC_NOERROR) + { + /* Provide the number of bytes successfully transferred */ + + nbytes = xfrinfo->xfrd; + } + else + { + /* Map the bad completion status to something that a class driver + * might understand. + */ + + udbg("ERROR: Bad TD completion status: %d\n", xfrinfo->tdstatus); + + switch (xfrinfo->tdstatus) + { + case TD_CC_STALL: + nbytes = -EPERM; + break; + + case TD_CC_USER: + nbytes = -ESHUTDOWN; + break; + + default: + nbytes = -EIO; + break; + } + } + +#if LPC17_IOBUFFERS > 0 + /* Free any temporary IO buffers */ + + lpc17_dma_free(priv, ed, xfrinfo->buffer, xfrinfo->buflen, xfrinfo->alloc); +#endif + + /* Extract the callback information before freeing the buffer */ + + callback = xfrinfo->callback; + arg = xfrinfo->arg; + + /* Make sure that there is no outstanding request on this endpoint */ + + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + + /* Then perform the callback */ + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: lpc17_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc17_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep; + struct lpc17_xfrinfo_s *xfrinfo; + int ret; + + DEBUGASSERT(priv && ed && ed->xfrinfo == NULL && buffer && buflen > 0 && callback); + + /* We must have exclusive access to the endpoint, the TD pool, the I/O buffer + * pool, the bulk and interrupt lists, and the HCCA interrupt table. + */ + + lpc17_takesem(&priv->exclsem); + + /* Allocate a structure to retain the information needed when the asynchronous + * transfer completes. + */ + + DEBUGASSERT(ed->xfrinfo == NULL); + + xfrinfo = lpc17_alloc_xfrinfo(); + if (xfrinfo == NULL) + { + udbg("ERROR: lpc17_alloc_xfrinfo failed\n"); + ret = -ENOMEM; + goto errout_with_sem; + } + + /* Initialize the transfer structure */ + + memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); + xfrinfo->buffer = buffer; + xfrinfo->buflen = buflen; + xfrinfo->callback = callback; + xfrinfo->arg = arg; + + ed->xfrinfo = xfrinfo; + +#if LPC17_IOBUFFERS > 0 + /* Allocate an IO buffer if the user buffer does not lie in AHB SRAM */ + + ret = lpc17_dma_alloc(priv, ed, buffer, buflen, &xfrinfo->alloc); + if (ret < 0) + { + udbg("ERROR: lpc17_dma_alloc failed: %d\n", ret); + goto errout_with_sem; + } + + /* If a buffer was allocated, then use it instead of the callers buffer */ + + if (xfrinfo->alloc) + { + buffer = xfrinfo->alloc; + } +#endif + + /* Set up the transfer */ + + ret = lpc17_transfer_common(priv, ed, buffer, buflen); + if (ret < 0) + { + udbg("ERROR: lpc17_transfer_common failed: %d\n", ret); + goto errout_with_asynch; + } + + /* And return now. The callback will be invoked when the transfer + * completes. + */ + + lpc17_givesem(&priv->exclsem); + return OK; + +errout_with_asynch: +#if LPC17_IOBUFFERS > 0 + /* Free any temporary IO buffers */ + + lpc17_dma_free(priv, ed, buffer, buflen, xfrinfo->alloc); +#endif + + /* Free the transfer structure */ + + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + +errout_with_sem: + lpc17_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: lpc17_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep; + struct lpc17_gtd_s *td; + struct lpc17_gtd_s *next; + struct lpc17_xfrinfo_s *xfrinfo; + uint32_t ctrl; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && ed != NULL); + + /* These first steps must be atomic as possible */ + + flags = enter_critical_section(); + + /* It is possible there there is no transfer to be in progress */ + + xfrinfo = ed->xfrinfo; + if (xfrinfo) + { + /* It might be possible for no transfer to be in progress (callback == NULL + * and wdhwait == false) + */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (xfrinfo->callback || xfrinfo->wdhwait) +#else + if (xfrinfo->wdhwait) +#endif + { + /* Control endpoints should not come through this path and + * isochronous endpoints are not yet implemented. So we only have + * to distinguish bulk and interrupt endpoints. + */ + + if (ed->xfrtype == USB_EP_ATTR_XFER_BULK) + { + /* Disable bulk list processing while we modify the list */ + + ctrl = lpc17_getreg(LPC17_USBHOST_CTRL); + lpc17_putreg(ctrl & ~OHCI_CTRL_BLE, LPC17_USBHOST_CTRL); + + /* Remove the TDs attached to the ED, keeping the ED in the list */ + + td = (struct lpc17_gtd_s *)(ed->hw.headp & ED_HEADP_ADDR_MASK); + ed->hw.headp = LPC17_TDTAIL_ADDR; + ed->xfrinfo = NULL; + + /* Re-enable bulk list processing, if it was enabled before */ + + lpc17_putreg(0, LPC17_USBHOST_BULKED); + lpc17_putreg(ctrl, LPC17_USBHOST_CTRL); + } + else + { + /* Remove the TDs attached to the ED, keeping the Ed in the list */ + + td = (struct lpc17_gtd_s *)(ed->hw.headp & ED_HEADP_ADDR_MASK); + ed->hw.headp = LPC17_TDTAIL_ADDR; + ed->xfrinfo = NULL; + } + + /* Free all transfer descriptors that were connected to the ED. In + * some race conditions with the hardware, this might be none. + */ + + while (td != (struct lpc17_gtd_s *)LPC17_TDTAIL_ADDR) + { + next = (struct lpc17_gtd_s *)td->hw.nexttd; + lpc17_tdfree(td); + td = next; + } + + xfrinfo->tdstatus = TD_CC_USER; + + /* If there is a thread waiting for the transfer to complete, then + * wake up the thread. + */ + + if (xfrinfo->wdhwait) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(xfrinfo->callback == NULL); +#endif + + /* Wake up the waiting thread */ + + lpc17_givesem(&ed->wdhsem); + xfrinfo->wdhwait = false; + + /* And free the transfer structure */ + + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + } +#ifdef CONFIG_USBHOST_ASYNCH + else + { + /* Otherwise, perform the callback and free the transfer structure */ + + lpc17_asynch_completion(priv, ed); + } +#endif + } + else + { + /* Just free the transfer structure */ + + lpc17_free_xfrinfo(xfrinfo); + ed->xfrinfo = NULL; + } + } + + /* Determine the return value */ + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: lpc17_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int lpc17_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + DEBUGASSERT(priv != NULL && hport != NULL); + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + lpc17_givesem(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc17_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void lpc17_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: lpc17_ep0init + * + * Description: + * Initialize ED for EP0, add it to the control ED list, and enable control + * transfers. + * + * Input Parameters: + * priv - private driver state instance. + * + * Returned Values: + * None + * + ****************************************************************************/ + +static inline void lpc17_ep0init(struct lpc17_usbhost_s *priv) +{ + /* Initialize the common tail TD. */ + + memset(TDTAIL, 0, sizeof(struct lpc17_gtd_s)); + TDTAIL->ed = EDCTRL; + + /* Link the common tail TD to the ED's TD list */ + + memset(EDCTRL, 0, sizeof(struct lpc17_ed_s)); + EDCTRL->hw.headp = (uint32_t)TDTAIL; + EDCTRL->hw.tailp = (uint32_t)TDTAIL; + EDCTRL->xfrtype = USB_EP_ATTR_XFER_CONTROL; + + /* Set the head of the control list to the NULL (for now). */ + + lpc17_putreg(0, LPC17_USBHOST_CTRLHEADED); + + /* Then add EP0 to the empty Control List */ + + lpc17_addctrled(priv, EDCTRL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_usbhost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +struct usbhost_connection_s *lpc17_usbhost_initialize(int controller) +{ + struct lpc17_usbhost_s *priv = &g_usbhost; + struct usbhost_driver_s *drvr; + struct usbhost_hubport_s *hport; + struct lpc17_xfrinfo_s *xfrinfo; + uint32_t regval; + uint8_t *buffer; + irqstate_t flags; + int i; + + /* Sanity checks. NOTE: If certain OS features are enabled, it may be + * necessary to increase the size of LPC17_ED/TD_SIZE in lpc17_ohciram.h + */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(sizeof(struct lpc17_ed_s) <= LPC17_ED_SIZE); + DEBUGASSERT(sizeof(struct lpc17_gtd_s) <= LPC17_TD_SIZE); + + /* Initialize the state data structure */ + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = lpc17_ep0configure; + drvr->epalloc = lpc17_epalloc; + drvr->epfree = lpc17_epfree; + drvr->alloc = lpc17_alloc; + drvr->free = lpc17_free; + drvr->ioalloc = lpc17_ioalloc; + drvr->iofree = lpc17_iofree; + drvr->ctrlin = lpc17_ctrlin; + drvr->ctrlout = lpc17_ctrlout; + drvr->transfer = lpc17_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = lpc17_asynch; +#endif + drvr->cancel = lpc17_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = lpc17_connect; +#endif + drvr->disconnect = lpc17_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = EDCTRL; + hport->speed = USB_SPEED_FULL; + hport->funcaddr = 0; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->rhport); + + /* Initialize semaphores */ + + sem_init(&priv->pscsem, 0, 0); + sem_init(&priv->exclsem, 0, 1); + +#ifndef CONFIG_USBHOST_INT_DISABLE + priv->ininterval = MAX_PERINTERVAL; + priv->outinterval = MAX_PERINTERVAL; +#endif + + /* Enable power by setting PCUSB in the PCONP register. Disable interrupts + * because this register may be shared with other drivers. + */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCUSB; + lpc17_putreg(regval, LPC17_SYSCON_PCONP); + leave_critical_section(flags); + + /* Enable clocking on USB (USB PLL clocking was initialized in very low- + * evel clock setup logic (see lpc17_clockconfig.c)). We do still need + * to set up USBOTG CLKCTRL to enable clocking. + * + * NOTE: The PORTSEL clock needs to be enabled only when accessing OTGSTCTRL + */ + + lpc17_putreg(LPC17_CLKCTRL_ENABLES, LPC17_USBOTG_CLKCTRL); + + /* Then wait for the clocks to be reported as "ON" */ + + do + { + regval = lpc17_getreg(LPC17_USBOTG_CLKST); + } + while ((regval & LPC17_CLKCTRL_ENABLES) != LPC17_CLKCTRL_ENABLES); + + /* Set the OTG status and control register. Bits 0:1 apparently mean: + * + * 00: U1=device, U2=host + * 01: U1=host, U2=host + * 10: reserved + * 11: U1=host, U2=device + * + * We need only select U1=host (Bit 0=1, Bit 1 is not used on LPC176x); + * NOTE: The PORTSEL clock needs to be enabled when accessing OTGSTCTRL + */ + + lpc17_putreg(1, LPC17_USBOTG_STCTRL); + + /* Now we can turn off the PORTSEL clock */ + + lpc17_putreg((LPC17_CLKCTRL_ENABLES & ~USBOTG_CLK_PORTSELCLK), LPC17_USBOTG_CLKCTRL); + + /* Configure I/O pins */ + + usbhost_dumpgpio(); + lpc17_configgpio(GPIO_USB_DP); /* Positive differential data */ + lpc17_configgpio(GPIO_USB_DM); /* Negative differential data */ + lpc17_configgpio(GPIO_USB_UPLED); /* GoodLink LED control signal */ + lpc17_configgpio(GPIO_USB_PPWR); /* Port Power enable signal for USB port */ + lpc17_configgpio(GPIO_USB_PWRD); /* Power Status for USB port (host power switch) */ + lpc17_configgpio(GPIO_USB_OVRCR); /* USB port Over-Current status */ + usbhost_dumpgpio(); + + udbg("Initializing Host Stack\n"); + + /* Show AHB SRAM memory map */ + +#if 0 /* Useful if you have doubts about the layout */ + uvdbg("AHB SRAM:\n"); + uvdbg(" HCCA: %08x %d\n", LPC17_HCCA_BASE, LPC17_HCCA_SIZE); + uvdbg(" TDTAIL: %08x %d\n", LPC17_TDTAIL_ADDR, LPC17_TD_SIZE); + uvdbg(" EDCTRL: %08x %d\n", LPC17_EDCTRL_ADDR, LPC17_ED_SIZE); + uvdbg(" EDFREE: %08x %d\n", LPC17_EDFREE_BASE, LPC17_ED_SIZE); + uvdbg(" TDFREE: %08x %d\n", LPC17_TDFREE_BASE, LPC17_EDFREE_SIZE); + uvdbg(" TBFREE: %08x %d\n", LPC17_TBFREE_BASE, LPC17_TBFREE_SIZE); + uvdbg(" IOFREE: %08x %d\n", LPC17_IOFREE_BASE, LPC17_IOBUFFERS * CONFIG_USBHOST_IOBUFSIZE); +#endif + + /* Initialize all the TDs, EDs and HCCA to 0 */ + + memset((void *)HCCA, 0, sizeof(struct ohci_hcca_s)); + memset((void *)TDTAIL, 0, sizeof(struct ohci_gtd_s)); + memset((void *)EDCTRL, 0, sizeof(struct lpc17_ed_s)); + sem_init(&EDCTRL->wdhsem, 0, 0); + + /* Initialize user-configurable EDs */ + + buffer = (uint8_t *)LPC17_EDFREE_BASE; + for (i = 0; i < CONFIG_USBHOST_NEDS; i++) + { + /* Put the ED in a free list */ + + lpc17_edfree((struct lpc17_ed_s *)buffer); + buffer += LPC17_ED_SIZE; + } + + /* Initialize user-configurable TDs */ + + buffer = (uint8_t *)LPC17_TDFREE_BASE; + for (i = 0; i < CONFIG_USBHOST_NTDS; i++) + { + /* Put the TD in a free list */ + + lpc17_tdfree((struct lpc17_gtd_s *)buffer); + buffer += LPC17_TD_SIZE; + } + + /* Initialize user-configurable request/descriptor transfer buffers */ + + buffer = (uint8_t *)LPC17_TBFREE_BASE; + for (i = 0; i < CONFIG_USBHOST_TDBUFFERS; i++) + { + /* Put the TD buffer in a free list */ + + lpc17_tbfree(buffer); + buffer += CONFIG_USBHOST_TDBUFSIZE; + } + +#if LPC17_IOBUFFERS > 0 + /* Initialize user-configurable IO buffers */ + + buffer = (uint8_t *)LPC17_IOFREE_BASE; + for (i = 0; i < LPC17_IOBUFFERS; i++) + { + /* Put the IO buffer in a free list */ + + lpc17_freeio(buffer); + buffer += CONFIG_USBHOST_IOBUFSIZE; + } +#endif + + /* Initialize transfer structures */ + + for (i = 0, xfrinfo = g_xfrbuffers; + i < CONFIG_LPC17_USBHOST_NPREALLOC; + i++, xfrinfo++) + { + /* Put the transfer structure in a free list */ + + lpc17_free_xfrinfo(xfrinfo); + } + + /* Wait 50MS then perform hardware reset */ + + up_mdelay(50); + + lpc17_putreg(0, LPC17_USBHOST_CTRL); /* Hardware reset */ + lpc17_putreg(0, LPC17_USBHOST_CTRLHEADED); /* Initialize control list head to Zero */ + lpc17_putreg(0, LPC17_USBHOST_BULKHEADED); /* Initialize bulk list head to Zero */ + + /* Software reset */ + + lpc17_putreg(OHCI_CMDST_HCR, LPC17_USBHOST_CMDST); + + /* Write Fm interval (FI), largest data packet counter (FSMPS), and + * periodic start. + */ + + lpc17_putreg(DEFAULT_FMINTERVAL, LPC17_USBHOST_FMINT); + lpc17_putreg(DEFAULT_PERSTART, LPC17_USBHOST_PERSTART); + + /* Put HC in operational state */ + + regval = lpc17_getreg(LPC17_USBHOST_CTRL); + regval &= ~OHCI_CTRL_HCFS_MASK; + regval |= OHCI_CTRL_HCFS_OPER; + lpc17_putreg(regval, LPC17_USBHOST_CTRL); + + /* Set global power in HcRhStatus */ + + lpc17_putreg(OHCI_RHSTATUS_SGP, LPC17_USBHOST_RHSTATUS); + + /* Set HCCA base address */ + + lpc17_putreg((uint32_t)HCCA, LPC17_USBHOST_HCCA); + + /* Set up the root hub port EP0 */ + + lpc17_ep0init(priv); + + /* Clear pending interrupts */ + + regval = lpc17_getreg(LPC17_USBHOST_INTST); + lpc17_putreg(regval, LPC17_USBHOST_INTST); + + /* Enable OHCI interrupts */ + + lpc17_putreg((LPC17_ALL_INTS | OHCI_INT_MIE), LPC17_USBHOST_INTEN); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(LPC17_IRQ_USB, lpc17_usbinterrupt) != 0) + { + udbg("Failed to attach IRQ\n"); + return NULL; + } + + /* Enable USB interrupts at the SYCON controller. Disable interrupts + * because this register may be shared with other drivers. + */ + + flags = enter_critical_section(); + regval = lpc17_getreg(LPC17_SYSCON_USBINTST); + regval |= SYSCON_USBINTST_ENINTS; + lpc17_putreg(regval, LPC17_SYSCON_USBINTST); + leave_critical_section(flags); + + /* If there is a USB device in the slot at power up, then we will not + * get the status change interrupt to signal us that the device is + * connected. We need to set the initial connected state accordingly. + */ + + regval = lpc17_getreg(LPC17_USBHOST_RHPORTST1); + priv->connected = ((regval & OHCI_RHPORTST_CCS) != 0); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(LPC17_IRQ_USB); /* enable USB interrupt */ + udbg("USB host Initialized, Device connected:%s\n", + priv->connected ? "YES" : "NO"); + + return &g_usbconn; +} diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.h b/arch/arm/src/lpc17xx/lpc17_usbhost.h new file mode 100644 index 0000000000000000000000000000000000000000..5efec074f9691d3f564cbafaf60bb66403e23461 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.h @@ -0,0 +1,108 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_usbhost.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: lpc17_usbhost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +FAR struct usbhost_connection_s *lpc17_usbhost_initialize(int controller); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_userspace.c b/arch/arm/src/lpc17xx/lpc17_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..ed433eab7ed13148843ad1eed3e607a437f39165 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_userspace.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "lpc17_mpuinit.h" +#include "lpc17_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc17_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void lpc17_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + lpc17_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/lpc17xx/lpc17_userspace.h b/arch/arm/src/lpc17xx/lpc17_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..5adb8771cb69f1353c5bb1bc6ad80b1e37b82848 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_userspace.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_USERSPACE_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc17_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc17_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_USERSPACE_H */ diff --git a/arch/arm/src/lpc17xx/lpc17_vectors.S b/arch/arm/src/lpc17xx/lpc17_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..6cee7d973163b2f574f5dffd2a2ffa8cdbf7b9f0 --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_vectors.S @@ -0,0 +1,497 @@ +/************************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_vectors.S + * + * Copyright (C) 2010-2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "exc_return.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* Configuration ********************************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the + * stack pointer of the interrupted thread. If the interrupted thread was a privileged + * thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the + * value of the MSP will be invalid when the interrupt handler returns because it will be a + * pointer to an old position in the unprivileged stack. Then when the high priority + * interrupt occurs and uses this stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt handler will + * always set the the MSP to the interrupt stack. So when the high priority interrupt occurs, + * it will either use the MSP of the last privileged thread to run or, in the case of the + * nested interrupt, the interrupt stack if no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************************/ +/* + * 0x0000:0000 - Beginning of FLASH. Address of vectors + * 0x0003:ffff - End of flash + * 0x1000:0000 - Start of CPU SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap. NOTE + * that the ARM uses a decrement before store stack so that the correct initial + * value is the end of the stack + 4; + * 0x1000:7fff - End of CPU SRAM and end of heap (1st region) + */ + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************************ + * Public Symbols + ************************************************************************************************/ + + .syntax unified + .thumb + .file "lpc17_vectors.S" + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + .globl __start + +/************************************************************************************************ + * Macros + ************************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + + .macro HANDLER, label, irqno + .thumb_func +\label: + mov r0, #\irqno + b exception_common + .endm + +/************************************************************************************************ + * Vectors + ************************************************************************************************/ + + .section .vectors, "ax" + .code 16 + .align 2 + .globl _vectors + .type _vectors, function + +_vectors: + +/* Processor Exceptions */ + + .word IDLE_STACK /* Vector 0: Reset stack pointer */ + .word __start /* Vector 1: Reset vector */ + .word lpc17_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + .word lpc17_hardfault /* Vector 3: Hard fault */ + .word lpc17_mpu /* Vector 4: Memory management (MPU) */ + .word lpc17_busfault /* Vector 5: Bus fault */ + .word lpc17_usagefault /* Vector 6: Usage fault */ + .word lpc17_reserved /* Vector 7: Reserved */ + .word lpc17_reserved /* Vector 8: Reserved */ + .word lpc17_reserved /* Vector 9: Reserved */ + .word lpc17_reserved /* Vector 10: Reserved */ + .word lpc17_svcall /* Vector 11: SVC call */ + .word lpc17_dbgmonitor /* Vector 12: Debug monitor */ + .word lpc17_reserved /* Vector 13: Reserved */ + .word lpc17_pendsv /* Vector 14: Pendable system service request */ + .word lpc17_systick /* Vector 15: System tick */ + +/* External Interrupts */ + +#undef VECTOR +#define VECTOR(l,i) .word l + +#undef UNUSED +#define UNUSED(i) .word lpc17_reserved + +#if defined(LPC176x) +# include "chip/lpc176x_vectors.h" +#elif defined(LPC178x) +# include "chip/lpc178x_vectors.h" +#else +# error "Unrecognized LPC17xx family" +#endif + + .size _vectors, .-_vectors + +/************************************************************************************************ + * .text + ************************************************************************************************/ + + .text + .type handlers, function + .thumb_func +handlers: + HANDLER lpc17_reserved, LPC17_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER lpc17_nmi, LPC17_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER lpc17_hardfault, LPC17_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER lpc17_mpu, LPC17_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER lpc17_busfault, LPC17_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER lpc17_usagefault, LPC17_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER lpc17_svcall, LPC17_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER lpc17_dbgmonitor, LPC17_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER lpc17_pendsv, LPC17_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER lpc17_systick, LPC17_IRQ_SYSTICK /* Vector 15: System tick */ + +/* External Interrupts */ + +#undef VECTOR +#define VECTOR(l,i) HANDLER l, i + +#undef UNUSED +#define UNUSED(i) + +#if defined(LPC176x) +# include "chip/lpc176x_vectors.h" +#elif defined(LPC178x) +# include "chip/lpc178x_vectors.h" +#else +# error "Unrecognized LPC17xx family" +#endif + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .globl exception_common + .type exception_common, function + +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size handlers, .-handlers + +/************************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************************ + * .rodata + ************************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/lpc17xx/lpc17_wdt.h b/arch/arm/src/lpc17xx/lpc17_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..b9ef49fc35f194261725a6726b8708ef086f2fea --- /dev/null +++ b/arch/arm/src/lpc17xx/lpc17_wdt.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc17xx/lpc17_wdt.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H +#define __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/lpc17_wdt.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_WDT_H */ diff --git a/arch/arm/src/lpc214x/Kconfig b/arch/arm/src/lpc214x/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..857b5f54d0e3c610b17dd9672ae8232b540f6941 --- /dev/null +++ b/arch/arm/src/lpc214x/Kconfig @@ -0,0 +1,147 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC214x Configuration Options" + +# Fragments of LPC214x chip selection logic. The LPC2148 is the only chip +# supported for now. + +config ARCH_CHIP_LPC2148 + bool + default y + +comment "LPC214x Initialization Options" + +choice + prompt "Memory Execution Mode" + default DEFAULT_MODE + +config EXTMEM_MODE + bool "External Memory Mode" + ---help--- + Code executes from external memory starting at address 0x8000:0000. + +config RAM_MODE + bool "RAM Memory Mode" + ---help--- + Code executes from on-chip RAM at address 0x4000:0000. + +config DEFAULT_MODE + bool "Default Memory Mode" + ---help--- + Executes from 0x0000:0000. In non-default modes, the MEMAP register + is set override the settings of the CPU configuration pins. + +endchoice + +config CODE_BASE + hex "Execution Base Address" + default 0x00000000 + ---help--- + This must match the expected address for the selected "Memory + Execution Address": + + EXTMEM_MODE: 0x8000:0000 + RAM_MODE: 0x4000:0000 + DEFAULT_MODE: 0x0000:0000 + +config PLL_SETUP + bool "Configure the PLL" + default y + +config MAM_SETUP + bool "Configure the Memory Accelerator Module (MAM)" + default y + +config APBDIV_SETUP + bool "Configure the APB Divider" + default y + +config APBDIV_VALUE + int "APB Divisor" + default 1 + +config EMC_SETUP + bool "Configure EMC" + default n + +config BCFG0_SETUP + bool "Configure BCFG0" + default n + +config BCFG1_SETUP + bool "Configure BCFG1" + default n + +config BCFG2_SETUP + bool "Configure BCFG2" + default n + +config BCFG3_SETUP + bool "Configure BCFG3" + default n + +config ADC_SETUP + bool "Configure ADC" + default y + +menu "LPC214x Peripheral Support" + +config LPC214X_UART0 + bool + default y + select ARCH_HAVE_UART0 + +config LPC214X_UART1 + bool + default y + select ARCH_HAVE_UART1 + +config LPC214X_USBDEV + bool "USB Device" + default y + depends on USBDEV + +endmenu + +config LPC214x_FIO + bool "Fast GPIO" + default n + +if LPC214X_USBDEV +menu "LPC214x USB Device Configuration" + +config LPC214X_USBDEV_DMA + bool "USB Device DMA Support" + default n + +if LPC214X_USBDEV_DMA + +config LPC214X_USBDEV_DMAINTMASK + hex "DMA interrupt mask" + default 0 + +config LPC214X_USBDEV_NDMADESCRIPTORS + int "Number of USB DMA Descriptors" + default 8 + +endif # LPC214X_USBDEV_DMA + +config LPC214X_USBDEV_EPFAST_INTERRUPT + bool "USB Device Fast Endpoint Interrupts" + default n + +config LPC214X_USBDEV_FRAME_INTERRUPT + bool "USB Device Frame Interrupts" + default n + +config LPC214X_USBDEV_REGDEBUG + bool "USB Device Register-Level Debug Output" + default n + depends on DEBUG + +endmenu +endif + diff --git a/arch/arm/src/lpc214x/Make.defs b/arch/arm/src/lpc214x/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..ea9bc404490995922f052d84e9bd094fe85f0e76 --- /dev/null +++ b/arch/arm/src/lpc214x/Make.defs @@ -0,0 +1,72 @@ +############################################################################## +# lpc214x/Make.defs +# +# Copyright (C) 2007, 2008, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +HEAD_ASRC = lpc214x_head.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S +CMN_ASRCS += vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c +CMN_CSRCS += up_exit.c up_idle.c up_initialize.c up_initialstate.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_stackframe.c +CMN_CSRCS += up_syscall.c up_unblocktask.c up_undefinedinsn.c up_usestack.c +CMN_CSRCS += up_lowputs.c up_vfork.c + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = lpc214x_lowputc.S +CHIP_CSRCS = lpc214x_decodeirq.c lpc214x_irq.c lpc214x_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc214x_timerisr.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += lpc214x_usbdev.c +endif diff --git a/arch/arm/src/lpc214x/README.txt b/arch/arm/src/lpc214x/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..752060c051a60d7b1991c6612b1cf680c4ea75be --- /dev/null +++ b/arch/arm/src/lpc214x/README.txt @@ -0,0 +1,61 @@ +General Description +^^^^^^^^^^^^^^^^^^^ + +http://www.nxp.com/pip/LPC2141FBD64.html: + +The LPC2141/42/44/46/48 microcontrollers are based on a 16-bit/32-bit ARM7TDMI-S +CPU with real-time emulation and embedded trace support, that combine +microcontroller with embedded high-speed flash memory ranging from 32 kB to +512 kB. A 128-bit wide memory interface and a unique accelerator architecture +enable 32-bit code execution at the maximum clock rate. For critical code size +applications, the alternative 16-bit Thumb mode reduces code by more than 30 pct +with minimal performance penalty. + +Due to their tiny size and low power consumption, LPC2141/42/44/46/48 are ideal +for applications where miniaturization is a key requirement, such as access +control and point-of-sale. Serial communications interfaces ranging from a USB 2.0 +Full-speed device, multiple UARTs, SPI, SSP to I2C-bus and on-chip SRAM of 8 kB +up to 40 kB, make these devices very well suited for communication gateways and +protocol converters, soft modems, voice recognition and low end imaging, providing +both large buffer size and high processing power. Various 32-bit timers, single +or dual 10-bit ADC(s), 10-bit DAC, PWM channels and 45 fast GPIO lines with up +to nine edge or level sensitive external interrupt pins make these microcontrollers +suitable for industrial control and medical systems. + + +Features +^^^^^^^^ + +o 16-bit/32-bit ARM7TDMI-S microcontroller in a tiny LQFP64 package. +o 8 kB to 40 kB of on-chip static RAM and 32 kB to 512 kB of on-chip flash memory. + 128-bit wide interface/accelerator enables high-speed 60 MHz operation. +o In-System Programming/In-Application Programming (ISP/IAP) via on-chip boot + loader software. Single flash sector or full chip erase in 400 ms and programming + of 256 B in 1 ms. +o EmbeddedICE RT and Embedded Trace interfaces offer real-time debugging with the + on-chip RealMonitor software and high-speed tracing of instruction execution. +o USB 2.0 Full-speed compliant device controller with 2 kB of endpoint RAM. In addition, + the LPC2146/48 provides 8 kB of on-chip RAM accessible to USB by DMA. +o One or two (LPC2141/42 vs. LPC2144/46/48) 10-bit ADCs provide a total of 6/14 analog + inputs, with conversion times as low as 2.44 us per channel. +o Single 10-bit DAC provides variable analog output (LPC2142/44/46/48 only). +o Two 32-bit timers/external event counters (with four capture and four compare + channels each), PWM unit (six outputs) and watchdog. +o Low power Real-Time Clock (RTC) with independent power and 32 kHz clock input. +o Multiple serial interfaces including two UARTs (16C550), two Fast I2C-bus (400 + kbit/s), SPI and SSP with buffering and variable data length capabilities. +o Vectored Interrupt Controller (VIC) with configurable priorities and vector addresses. +o Up to 45 of 5 V tolerant fast general purpose I/O pins in a tiny LQFP64 package. +o Up to 21 external interrupt pins available. +o 60 MHz maximum CPU clock available from programmable on-chip PLL with settling + time of 100 us. +o On-chip integrated oscillator operates with an external crystal from 1 MHz to 25 MHz. +o Power saving modes include Idle and Power-down. +o Individual enable/disable of peripheral functions as well as peripheral clock scaling + for additional power optimization. +o Processor wake-up from Power-down mode via external interrupt or BOD. +o Single power supply chip with POR and BOD circuits: +o CPU operating voltage range of 3.0 V to 3.6 V (3.3 V +- 10 pct) with 5 V tolerant + I/O pads. + + diff --git a/arch/arm/src/lpc214x/chip.h b/arch/arm/src/lpc214x/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..c0af01c4475e4fe62e74a518da5bb37f1c0f1031 --- /dev/null +++ b/arch/arm/src/lpc214x/chip.h @@ -0,0 +1,349 @@ +/**************************************************************************************************** + * arch/arm/src/lpc214x/chip.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __LPC214X_CHIP_H +#define __LPC214X_CHIP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Memory Map ***************************************************************************************/ + +#define LPC214X_FLASH_BASE 0x00000000 +#define LPC214X_FIO_BASE 0x3fffc000 +#define LPC214X_ONCHIP_RAM_BASE 0x40000000 +#define LPC214X_USBDMA_RAM_BASE 0x7fd00000 +#define LPC214X_BOOT_BLOCK 0x7fffd000 +#define LPC214X_EXTMEM_BASE 0x80000000 +#define LPC214X_APB_BASE 0xe0000000 +#define LPC214X_AHB_BASE 0xf0000000 + +/* Peripheral Registers ****************************************************************************/ + +/* FIO Register block base addresses */ + +#define LPC214X_FIO0_BASE 0x3fffc000 /* Fast I/O 0 base address */ +#define LPC214X_FIO1_BASE 0x3fffc020 /* Fast I/O 1 base address */ + +/* APB Register block base addresses */ + +#define LPC214X_WD_BASE 0xe0000000 /* Watchdog base address */ +#define LPC214X_TMR0_BASE 0xe0004000 /* Timer 0 base address*/ +#define LPC214X_TMR1_BASE 0xe0008000 /* Timer 1 base address */ +#define LPC214X_UART0_BASE 0xe000c000 /* UART0 base address */ +#define LPC214X_UART1_BASE 0xe0010000 /* UART1 base address */ +#define LPC214X_PWM_BASE 0xe0014000 /* Pulse width modulator (PWM) base address */ +#define LPC214X_I2C0_BASE 0xe001c000 /* I2C0 base address */ +#define LPC214X_SPI0_BASE 0xe0020000 /* Serial Peripheral Interface 0 (SPI0) base */ +#define LPC214X_RTC_BASE 0xe0024000 /* Real Time Clock (RTC) base address */ +#define LPC214X_GPIO0_BASE 0xe0028000 /* General Purpose I/O (GPIO) 0 base address */ +#define LPC214X_GPIO1_BASE 0xe0028010 /* General Purpose I/O (GPIO) 0 base address */ +#define LPC214X_PINSEL_BASE 0xe002c000 /* Pin function select registers */ +#define LPC214X_AD0_BASE 0xe0034000 /* Analog to Digital Converter 0 base address*/ +#define LPC214X_I2C1_BASE 0xe005c000 /* I2C1 base address */ +#define LPC214X_AD1_BASE 0xe0060000 /* Analog to Digital Converter 1 base address */ +#define LPC214X_SPI1_BASE 0xe0068000 /* Serial Peripheral Interface 1 (SPI1) base */ +#define LPC214X_DAC_BASE 0xe0090000 /* DAC base address */ +#define LPC214X_USB_BASE 0xe0090000 /* USB base address */ + +#define LPC214X_SCB_BASE 0xe01fc000 /* System Control Block (SBC) base address */ +#define LPC214X_MAM_BASE 0xe01fc000 /* Memory Accelerator Module (MAM) base address */ +#define LPC214X_SCS 0xe01fc1a0 /* System Control and Status flags (SCS) */ +#define LPC214X_MEMMAP 0xe01fc040 /* Memory Mapping Control */ +#define LPC214X_PLL_BASE 0xe01fc080 /* Phase Locked Loop (PLL) base address */ +#define LPC214X_PCON_BASE 0xe01fc0c0 /* Power Control (PCON) base address */ +#define LPC214X_APBDIV 0xe01fc100 /* APBDIV Address */ +#define LPC214X_EXT_BASE 0xe01fc140 /* External Interrupt base address */ + +/* AHB Register block base addresses */ + +#define LPC214X_EMC_BASE 0xffe00000 /* External Memory Controller (EMC) base address */ +#define LPC214X_VIC_BASE 0xfffff000 /* Vectored Interrupt Controller (VIC) Base */ + +/* Watchdog Register Offsets */ + +#define LPC214X_WD_MOD_OFFSET 0x00 /* Watchdog Mode Register */ +#define LPC214X_WD_TC_OFFSET 0x04 /* Watchdog Time Constant Register */ +#define LPC214X_WD_FEED_OFFSET 0x08 /* Watchdog Feed Register */ +#define LPC214X_WD_TV_OFFSET 0x0C /* Watchdog Time Value Register */ + +/* Timer 0/1 register offsets */ + +#define LPC214X_TMR_IR_OFFSET 0x00 /* RW:Interrupt Register */ +#define LPC214X_TMR_TCR_OFFSET 0x04 /* RW: Timer Control Register */ +#define LPC214X_TMR_TC_OFFSET 0x08 /* RW: Timer Counter */ +#define LPC214X_TMR_PR_OFFSET 0x0c /* RW: Prescale Register */ +#define LPC214X_TMR_PC_OFFSET 0x10 /* RW: Prescale Counter Register */ +#define LPC214X_TMR_MCR_OFFSET 0x14 /* RW: Match Control Register */ +#define LPC214X_TMR_MR0_OFFSET 0x18 /* RW: Match Register 0 */ +#define LPC214X_TMR_MR1_OFFSET 0x1c /* RW: Match Register 1 */ +#define LPC214X_TMR_MR2_OFFSET 0x20 /* RW: Match Register 2 */ +#define LPC214X_TMR_MR3_OFFSET 0x24 /* RW: Match Register 3 */ +#define LPC214X_TMR_CCR_OFFSET 0x28 /* RW: Capture Control Register */ +#define LPC214X_TMR_CR0_OFFSET 0x2c /* R: Capture Register 0 */ +#define LPC214X_TMR_CR1_OFFSET 0x30 /* R: Capture Register 1 */ +#define LPC214X_TMR_CR2_OFFSET 0x34 /* R: Capture Register 2 */ +#define LPC214X_TMR_CR3_OFFSET 0x38 /* RW: Capture Register 3 */ +#define LPC214X_TMR_EMR_OFFSET 0x3c /* RW: External Match Register */ + +#define LPC214X_TMR_CTCR_OFFSET 0x70 /* RW: Count Control Register */ + +/* UART0/1 Register Offsets */ + +#define LPC214X_UART_RBR_OFFSET 0x00 /* R: Receive Buffer Register (DLAB=0) */ +#define LPC214X_UART_THR_OFFSET 0x00 /* W: Transmit Holding Register (DLAB=0) */ +#define LPC214X_UART_DLL_OFFSET 0x00 /* W: Divisor Latch Register (LSB, DLAB=1) */ +#define LPC214X_UART_IER_OFFSET 0x04 /* W: Interrupt Enable Register (DLAB=0) */ +#define LPC214X_UART_DLM_OFFSET 0x04 /* RW: Divisor Latch Register (MSB, DLAB=1) */ +#define LPC214X_UART_IIR_OFFSET 0x08 /* R: Interrupt ID Register */ +#define LPC214X_UART_FCR_OFFSET 0x08 /* W: FIFO Control Register */ +#define LPC214X_UART_LCR_OFFSET 0x0c /* RW: Line Control Register */ +#define LPC214X_UART_MCR_OFFSET 0x10 /* RW: Modem Control REgister (2146/6/8 UART1 Only) */ +#define LPC214X_UART_LSR_OFFSET 0x14 /* R: Scratch Pad Register */ +#define LPC214X_UART_MSR_OFFSET 0x18 /* RW: MODEM Status Register (2146/6/8 UART1 Only) */ +#define LPC214X_UART_SCR_OFFSET 0x1c /* RW: Line Status Register */ +#define LPC214X_UART_ACR_OFFSET 0x20 /* RW: Autobaud Control Register */ +#define LPC214X_UART_FDR_OFFSET 0x28 /* RW: Fractional Divider Register */ +#define LPC214X_UART_TER_OFFSET 0x30 /* RW: Transmit Enable Register */ + +/* PWM register offsets */ + +#define LPC214X_PWM_IR_OFFSET 0x00 /* Interrupt Register */ +#define LPC214X_PWM_TCR_OFFSET 0x04 /* Timer Control Register */ +#define LPC214X_PWM_TC_OFFSET 0x08 /* Timer Counter */ +#define LPC214X_PWM_PR_OFFSET 0x0c /* Prescale Register */ +#define LPC214X_PWM_PC_OFFSET 0x10 /* Prescale Counter Register */ +#define LPC214X_PWM_MCR_OFFSET 0x14 /* Match Control Register */ +#define LPC214X_PWM_MR0_OFFSET 0x18 /* Match Register 0 */ +#define LPC214X_PWM_MR1_OFFSET 0x1c /* Match Register 1 */ +#define LPC214X_PWM_MR2_OFFSET 0x20 /* Match Register 2 */ +#define LPC214X_PWM_MR3_OFFSET 0x24 /* Match Register 3 */ +#define LPC214X_PWM_MR4_OFFSET 0x40 /* Match Register 4 */ +#define LPC214X_PWM_MR5_OFFSET 0x44 /* Match Register 5 */ +#define LPC214X_PWM_MR6_OFFSET 0x48 /* Match Register 6 */ +#define LPC214X_PWM_PCR_OFFSET 0x4c /* Control Register */ +#define LPC214X_PWM_LER_OFFSET 0x50 /* Latch Enable Register */ + +/* I2C register offsets */ + +#define LPC214X_I2C_CONSET_OFFSET 0x00 /* Control Set Register */ +#define LPC214X_I2C_STAT_OFFSET 0x04 /* Status Register */ +#define LPC214X_I2C_DAT_OFFSET 0x08 /* Data Register */ +#define LPC214X_I2C_ADR_OFFSET 0x0c /* Slave Address Register */ +#define LPC214X_I2C_SCLH_OFFSET 0x10 /* SCL Duty Cycle Register (high half word) */ +#define LPC214X_I2C_SCLL_OFFSET 0x14 /* SCL Duty Cycle Register (low half word) */ +#define LPC214X_I2C_CONCLR_OFFSET 0x18 /* Control Clear Register */ + +/* Pin function select register offsets */ + +#define LPC214X_PINSEL0_OFFSET 0x00 /* Pin function select register 0 */ +#define LPC214X_PINSEL1_OFFSET 0x04 /* Pin function select register 1 */ +#define LPC214X_PINSEL2_OFFSET 0x14 /* Pin function select register 2 */ + +/* Analog to Digital (AD) Converter registger offsets */ + +#define LPC214X_AD_ADCR_OFFSET 0x00 /* A/D Control Register */ +#define LPC214X_AD_ADGDR_OFFSET 0x04 /* A/D Global Data Register (only one common register!) */ +#define LPC214X_AD_ADGSR_OFFSET 0x08 /* A/D Global Start Register */ +#define LPC214X_AD_ADINTEN_OFFSET 0x0c /* A/D Interrupt Enable Register */ +#define LPC214X_AD_ADDR0_OFFSET 0x10 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR1_OFFSET 0x14 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR2_OFFSET 0x18 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR3_OFFSET 0x1c /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR4_OFFSET 0x20 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR5_OFFSET 0x24 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR6_OFFSET 0x28 /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADDR7_OFFSET 0x2c /* A/D Chanel 0 Data Register */ +#define LPC214X_AD_ADSTAT_OFFSET 0x30 /* A/D Status Register */ + +/* SPI0 register offsets */ + +#define LPC214X_SPI0_CR_OFFSET 0x00 /* Control Register 0 */ +#define LPC214X_SPI0_SR_OFFSET 0x04 /* Control Register 1 */ +#define LPC214X_SPI0_DR_OFFSET 0x08 /* Data Register */ +#define LPC214X_SPI0_CCR_OFFSET 0x0c /* Status Register */ +#define LPC214X_SPI0_INT_OFFSET 0x1c /* Clock Pre-Scale Regisrer */ + +/* SPI1 register offsets */ + +#define LPC214X_SPI1_CR0_OFFSET 0x00 /* Control Register 0 */ +#define LPC214X_SPI1_CR1_OFFSET 0x04 /* Control Register 1 */ +#define LPC214X_SPI1_DR_OFFSET 0x08 /* Data Register */ +#define LPC214X_SPI1_SR_OFFSET 0x0c /* Status Register */ +#define LPC214X_SPI1_CPSR_OFFSET 0x10 /* Clock Pre-Scale Regisrer */ +#define LPC214X_SPI1_IMSC_OFFSET 0x14 /* Interrupt Mask Set and Clear Register */ +#define LPC214X_SPI1_RIS_OFFSET 0x18 /* Raw Interrupt Status Register */ +#define LPC214X_SPI1_MIS_OFFSET 0x1c /* Masked Interrupt Status Register */ +#define LPC214X_SPI1_ICR_OFFSET 0x20 /* Interrupt Clear Register */ + +/* RTC register offsets */ + +#define LPC214X_RTC_ILR_OFFSET 0x00 /* Interrupt Location Register */ +#define LPC214X_RTC_CTC_OFFSET 0x04 /* Clock Tick Counter */ +#define LPC214X_RTC_CCR_OFFSET 0x08 /* Clock Control Register */ +#define LPC214X_RTC_CIIR_OFFSET 0x0c /* Counter Increment Interrupt Register */ +#define LPC214X_RTC_AMR_OFFSET 0x10 /* Alarm Mask Register */ +#define LPC214X_RTC_CTIME0_OFFSET 0x14 /* Consolidated Time Register 0 */ +#define LPC214X_RTC_CTIME1_OFFSET 0x18 /* Consolidated Time Register 1 */ +#define LPC214X_RTC_CTIME2_OFFSET 0x1c /* Consolidated Time Register 2 */ +#define LPC214X_RTC_SEC_OFFSET 0x20 /* Seconds Register */ +#define LPC214X_RTC_MIN_OFFSET 0x24 /* Minutes Register */ +#define LPC214X_RTC_HOUR_OFFSET 0x28 /* Hours Register */ +#define LPC214X_RTC_DOM_OFFSET 0x2c /* Day Of Month Register */ +#define LPC214X_RTC_DOW_OFFSET 0x30 /* Day Of Week Register */ +#define LPC214X_RTC_DOY_OFFSET 0x34 /* Day Of Year Register */ +#define LPC214X_RTC_MONTH_OFFSET 0x38 /* Months Register */ +#define LPC214X_RTC_YEAR_OFFSET 0x3c /* Years Register */ + +#define LPC214X_RTC_ALSEC_OFFSET 0x60 /* Alarm Seconds Register */ +#define LPC214X_RTC_ALMIN_OFFSET 0x64 /* Alarm Minutes Register */ +#define LPC214X_RTC_ALHOUR_OFFSET 0x68 /* Alarm Hours Register */ +#define LPC214X_RTC_ALDOM_OFFSET 0x6c /* Alarm Day Of Month Register */ +#define LPC214X_RTC_ALDOW_OFFSET 0x70 /* Alarm Day Of Week Register */ +#define LPC214X_RTC_ALDOY_OFFSET 0x74 /* Alarm Day Of Year Register */ +#define LPC214X_RTC_ALMON_OFFSET 0x78 /* Alarm Months Register */ +#define LPC214X_RTC_ALYEAR_OFFSET 0x7c /* Alarm Years Register */ +#define LPC214X_RTC_PREINT_OFFSET 0x80 /* Prescale Value Register (integer) */ +#define LPC214X_RTC_PREFRAC_OFFSET 0x84 /* Prescale Value Register (fraction) */ + +/* GPIO register offsets */ + +#define LPC214X_GPIO_PIN_OFFSET 0x00 /* Pin Value Register */ +#define LPC214X_GPIO_SET_OFFSET 0x04 /* Pin Output Set Register */ +#define LPC214X_GPIO_DIR_OFFSET 0x08 /* Pin Direction Register */ +#define LPC214X_GPIO_CLR_OFFSET 0x0c /* Pin Output Clear Register */ + +/* FIO register offsets */ + +#define LPC214X_FIO_DIR_OFFSET 0x00 /* Fast GPIO Port Direction Register */ +#define LPC214X_FIO_MASK_OFFSET 0x10 /* Fast GPIO Mask Register */ +#define LPC214X_FIO_PIN_OFFSET 0x14 /* Fast GPIO Pin Value Register */ +#define LPC214X_FIO_SET_OFFSET 0x18 /* Fast GPIO Port Output Set Register */ +#define LPC214X_FIO_CLR_OFFSET 0x1c /* Fast GPIO Port Output Clear Register */ + +/* Memory Accelerator Module (MAM) Regiser Offsets */ + +#define LPC214X_MAM_CR_OFFSET 0x00 /* MAM Control Offset*/ +#define LPC214x_MAM_TIM_OFFSET 0x04 /* MAM Timing Offset */ + +/* Phase Locked Loop (PLL) Register Offsets */ + +#define LPC214X_PLL_CON_OFFSET 0x00 /* PLL Control Offset*/ +#define LPC214X_PLL_CFG_OFFSET 0x04 /* PLL Configuration Offset */ +#define LPC214X_PLL_STAT_OFFSET 0x08 /* PLL Status Offset */ +#define LPC214X_PLL_FEED_OFFSET 0x0c /* PLL Feed Offset */ + +/* Power Control register offsets */ + +#define LPC214X_PCON_OFFSET 0x00 /* Control Register */ +#define LPC214X_PCONP_OFFSET 0x04 /* Peripherals Register */ + +/* External Interrupt register offsets */ + +#define LPC214X_EXT_INT_OFFSET 0x00 /* Flag Register */ +#define LPC214X_EXT_WAKE_OFFSET 0x04 /* Wakeup Register */ +#define LPC214X_EXT_MODE_OFFSET 0x08 /* Mode Register */ +#define LPC214X_EXT_POLAR_OFFSET 0x0c /* Polarity Register */ + +/* External Memory Controller (EMC) definitions */ + +#define LPC214X_BCFG0_OFFSET 0x00 /* BCFG0 Offset */ +#define LPC214X_BCFG1_OFFSET 0x04 /* BCFG1 Offset */ +#define LPC214X_BCFG2_OFFSET 0x08 /* BCFG2 Offset */ +#define LPC214X_BCFG3_OFFSET 0x0c /* BCFG3 Offset */ + +/* Vectored Interrupt Controller (VIC) register offsets */ + +#define LPC214X_VIC_IRQSTATUS_OFFSET 0x00 /* R: IRQ Status Register */ +#define LPC214X_VIC_FIQSTATUS_OFFSET 0x04 /* R: FIQ Status Register */ +#define LPC214X_VIC_RAWINTR_OFFSET 0x08 /* R: Raw Interrupt Status Register */ +#define LPC214X_VIC_INTSELECT_OFFSET 0x0c /* RW: Interrupt Select Register */ +#define LPC214X_VIC_INTENABLE_OFFSET 0x10 /* RW: Interrupt Enable Register */ +#define LPC214X_VIC_INTENCLEAR_OFFSET 0x14 /* W: Interrupt Enable Clear Register */ +#define LPC214X_VIC_SOFTINT_OFFSET 0x18 /* RW: Software Interrupt Register */ +#define LPC214X_VIC_SOFTINTCLEAR_OFFSET 0x1c /* W: Software Interrupt Clear Register */ +#define LPC214X_VIC_PROTECTION_OFFSET 0x20 /* Protection Enable Register */ + +#define LPC214X_VIC_VECTADDR_OFFSET 0x30 /* RW: Vector Address Register */ +#define LPC214X_VIC_DEFVECTADDR_OFFSET 0x34 /* RW: Default Vector Address Register */ + +#define LPC214X_VIC_VECTADDR0_OFFSET 0x100 /* RW: Vector Address 0 Register */ +#define LPC214X_VIC_VECTADDR1_OFFSET 0x104 /* RW: Vector Address 1 Register */ +#define LPC214X_VIC_VECTADDR2_OFFSET 0x108 /* RW: Vector Address 2 Register */ +#define LPC214X_VIC_VECTADDR3_OFFSET 0x10c /* RW: Vector Address 3 Register */ +#define LPC214X_VIC_VECTADDR4_OFFSET 0x110 /* RW: Vector Address 4 Register */ +#define LPC214X_VIC_VECTADDR5_OFFSET 0x114 /* RW: Vector Address 5 Register */ +#define LPC214X_VIC_VECTADDR6_OFFSET 0x118 /* RW: Vector Address 6 Register */ +#define LPC214X_VIC_VECTADDR7_OFFSET 0x11c /* RW: Vector Address 7 Register */ +#define LPC214X_VIC_VECTADDR8_OFFSET 0x120 /* RW: Vector Address 8 Register */ +#define LPC214X_VIC_VECTADDR9_OFFSET 0x124 /* RW: Vector Address 9 Register */ +#define LPC214X_VIC_VECTADDR10_OFFSET 0x128 /* RW: Vector Address 10 Register */ +#define LPC214X_VIC_VECTADDR11_OFFSET 0x12c /* RW: Vector Address 11 Register */ +#define LPC214X_VIC_VECTADDR12_OFFSET 0x130 /* RW: Vector Address 12 Register */ +#define LPC214X_VIC_VECTADDR13_OFFSET 0x134 /* RW: Vector Address 13 Register */ +#define LPC214X_VIC_VECTADDR14_OFFSET 0x138 /* RW: Vector Address 14 Register */ +#define LPC214X_VIC_VECTADDR15_OFFSET 0x13c /* RW: Vector Address 15 Register */ + +#define LPC214X_VIC_VECTCNTL0_OFFSET 0x200 /* RW: Vector Control 0 Register */ +#define LPC214X_VIC_VECTCNTL1_OFFSET 0x204 /* RW: Vector Control 1 Register */ +#define LPC214X_VIC_VECTCNTL2_OFFSET 0x208 /* RW: Vector Control 2 Register */ +#define LPC214X_VIC_VECTCNTL3_OFFSET 0x20c /* RW: Vector Control 3 Register */ +#define LPC214X_VIC_VECTCNTL4_OFFSET 0x210 /* RW: Vector Control 4 Register */ +#define LPC214X_VIC_VECTCNTL5_OFFSET 0x214 /* RW: Vector Control 5 Register */ +#define LPC214X_VIC_VECTCNTL6_OFFSET 0x218 /* RW: Vector Control 6 Register */ +#define LPC214X_VIC_VECTCNTL7_OFFSET 0x21c /* RW: Vector Control 7 Register */ +#define LPC214X_VIC_VECTCNTL8_OFFSET 0x220 /* RW: Vector Control 8 Register */ +#define LPC214X_VIC_VECTCNTL9_OFFSET 0x224 /* RW: Vector Control 9 Register */ +#define LPC214X_VIC_VECTCNTL10_OFFSET 0x228 /* RW: Vector Control 10 Register */ +#define LPC214X_VIC_VECTCNTL11_OFFSET 0x22c /* RW: Vector Control 11 Register */ +#define LPC214X_VIC_VECTCNTL12_OFFSET 0x230 /* RW: Vector Control 12 Register */ +#define LPC214X_VIC_VECTCNTL13_OFFSET 0x234 /* RW: Vector Control 13 Register */ +#define LPC214X_VIC_VECTCNTL14_OFFSET 0x238 /* RW: Vector Control 14 Register */ +#define LPC214X_VIC_VECTCNTL15_OFFSET 0x23c /* RW: Vector Control 15 Register */ + +/**************************************************************************************************** + * Inline Functions + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __LPC214X_CHIP_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_apb.h b/arch/arm/src/lpc214x/lpc214x_apb.h new file mode 100644 index 0000000000000000000000000000000000000000..e76fa5754a635b8604bafe0fcc1459aa6361ee48 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_apb.h @@ -0,0 +1,72 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_apb.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_APB_H +#define _ARCH_ARM_SRC_LPC214X_APB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register address definitions *****************************************************/ + +#define LPC214X_APB_APBDIV (0xe01fc100) /* 8-bit R/W APB divider register */ + +/* Register bit definitions *********************************************************/ + +/* APB divider register */ + +#define LPC214X_APBDIV_MASK (0x03) /* Bit 0:1: APB divider value */ +#define LPC214X_APBDIV_DIV4 (0x00) /* Bit 0:1=00: APB=PCLK/4 */ +#define LPC214X_APBDIV_DIV1 (0x01) /* Bit 0:1=01: APB=PCLK */ +#define LPC214X_APBDIV_DIV2 (0x02) /* Bit 0:1=10: APB=PCLK/2 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC214X_APB_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_decodeirq.c b/arch/arm/src/lpc214x/lpc214x_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..382c0bba022a949b9b37ce894b4073f13d821580 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_decodeirq.c @@ -0,0 +1,176 @@ +/******************************************************************************** + * arch/arm/src/lpc214x/lpc214x_decodeirq.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc214x_vic.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Private Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/* This array maps 4 bits into the bit number of the lowest bit that it set */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS +static uint8_t g_nibblemap[16] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; +#endif + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Funstions + ********************************************************************************/ + +/******************************************************************************** + * up_decodeirq() and/or lpc214x_decodeirq() + * + * Description: + * The vectored interrupt controller (VIC) takes 32 interrupt request inputs + * and programmatically assigns them into 3 categories: FIQ, vectored IRQ, + * and non-vectored IRQ. + * + * - FIQs have the highest priority. There is a single FIQ vector, but multiple + * interrupt sources can be ORed to this FIQ vector. + * + * - Vectored IRQs have the middle priority. Any 16 of the 32 interrupt sources + * can be assigned to vectored IRQs. + * + * - Non-vectored IRQs have the lowest priority. + * + * The general flow of IRQ processing is to simply read the VIC vector address + * and jump to the address of the vector provided in the register. The VIC will + * provide the address of the highest priority vectored IRQ. If a non-vectored + * IRQ is requesting, the address of a default handler is provided. + * + ********************************************************************************/ + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_decodeirq(uint32_t *regs) +#else +static void lpc214x_decodeirq(uint32_t *regs) +#endif +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + + /* Decode the interrupt. We have to do this by search for the lowest numbered + * non-zero bit in the interrupt status register. + */ + + uint32_t pending = vic_getreg(LPC214X_VIC_IRQSTATUS_OFFSET) & 0x007fffff; + unsigned int nibble; + unsigned int irq_base; + unsigned int irq = NR_IRQS; + + /* Search in groups of four bits. For 22 sources, this is at most six + * times through the loop. + */ + + for (nibble = pending & 0x0f, irq_base = 0; + pending && irq_base < NR_IRQS; + pending >>= 4, nibble = pending & 0x0f, irq_base += 4) + { + if (nibble) + { + irq = irq_base + g_nibblemap[nibble]; + break; + } + } + + /* Verify that the resulting IRQ number is valid */ + + if (irq < NR_IRQS) + { + uint32_t *savestate; + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + } +#endif +} + +#ifdef CONFIG_VECTORED_INTERRUPTS +void up_decodeirq(uint32_t *regs) +{ + vic_vector_t vector = (vic_vector_t)vic_getreg(LPC214X_VIC_VECTADDR_OFFSET); + vector(regs); +} +#endif diff --git a/arch/arm/src/lpc214x/lpc214x_head.S b/arch/arm/src/lpc214x/lpc214x_head.S new file mode 100644 index 0000000000000000000000000000000000000000..8db27f29ebde0131b6debe98baf61c91b2c28949 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_head.S @@ -0,0 +1,634 @@ +/***************************************************************************** + * arch/arm/src/lpc214x/lpc214x_head.S + * + * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include + +#include + +#include "arm.h" +#include "chip.h" +#include "lpc214x_pll.h" +#include "lpc214x_apb.h" +#include "lpc214x_pinsel.h" +#include "up_internal.h" +#include "up_arch.h" + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +/* This file holds the NuttX start logic that runs when the LPC2148 + * is reset. This logic must be located at address 0x0000:0000 in + * flash but may be linked to run at different locations based on + * the selected mode: + * + * default: Executes from 0x0000:0000. In non-default modes, the + * MEMAP register is set override the settings of the CPU configuration + * pins. + * + * CONFIG_EXTMEM_MODE: Code executes from external memory starting at + * address 0x8000:0000. + * + * CONFIG_RAM_MODE: Code executes from on-chip RAM at address + * 0x4000:0000. + * + * Starupt Code must be linked to run at the correct address + * corresponding to the selected mode. + */ + +#if defined(CONFIG_EXTMEM_MODE) +# if CONFIG_CODE_BASE != LPC214X_EXTMEM_BASE +# error "CONFIG_CODE_BASE must be 0x80000000 in EXTMEM mode" +# endif +#elif defined(CONFIG_RAM_MODE) +# if CONFIG_CODE_BASE != LPC214X_ONCHIP_RAM_BASE +# error "CONFIG_CODE_BASE must be 0x40000000 in EXTMEM mode" +# endif +#else +# if CONFIG_CODE_BASE != LPC214X_FLASH_BASE +# error "CONFIG_CODE_BASE must be 0x00000000 in default mode" +# endif +#endif + +/* Phase Locked Loop (PLL) initialization values + * + * Bit 0:4 MSEL: PLL Multiplier "M" Value + * CCLK = M * Fosc + * Bit 5:6 PSEL: PLL Divider "P" Value + * Fcco = CCLK * 2 * P + * 156MHz <= Fcco <= 320MHz + */ + +/* PLL0 provides CCLK and must always be configured */ + +#ifndef CONFIG_PLLCFG_VALUE /* board.h values can be supeceded config file */ +# ifdef LPC214X_PLL_M +# define CONFIG_PLLCFG_MSEL (LPC214X_PLL_M-1) +# else +# warning "PLL_M not specified" +# define CONFIG_PLLCFG_MSEL (5-1) +# endif +# ifdef LPC214X_PLL_P +# if LPC214X_PLL_P == 1 +# define CONFIG_PLLCFG_PSEL LPC214X_PLL_CFG_PSEL1 +# elif LPC214X_PLL_P == 2 +# define CONFIG_PLLCFG_PSEL LPC214X_PLL_CFG_PSEL2 +# elif LPC214X_PLL_P == 4 +# define CONFIG_PLLCFG_PSEL LPC214X_PLL_CFG_PSEL4 +# elif LPC214X_PLL_P == 8 +# define CONFIG_PLLCFG_PSEL LPC214X_PLL_CFG_PSEL8 +# else +# error "Unrecognized value for PLL_P" +# endif +# else +# warning "PLL_P not specified" +# define CONFIG_PLLCFG_PSEL LPC214X_PLL_CFG_PSEL2 +# endif +# define CONFIG_PLLCFG_VALUE (CONFIG_PLLCFG_PSEL|CONFIG_PLLCFG_MSEL) +#endif + +/* If USB is enabled, PLL1 must be configured for 48MHz to provide USB clocking */ + +#ifdef CONFIG_USBDEV +# ifndef CONFIG_USBPLLCFG_VALUE /* board.h values can be supeceded config file */ +# ifdef LPC214X_USBPLL_M +# define LPC214X_USBPLLCFG_MSEL (LPC214X_USBPLL_M-1) +# else +# warning "PLL_M not specified" +# define LPC214X_USBPLLCFG_MSEL 0x00000004 +# endif +# ifdef LPC214X_USBPLL_P +# if LPC214X_USBPLL_P == 1 +# define LPC214X_USBPLLCFG_PSEL 0x00000000 +# elif LPC214X_USBPLL_P == 2 +# define LPC214X_USBPLLCFG_PSEL 0x00000020 +# elif LPC214X_USBPLL_P == 4 +# define LPC214X_USBPLLCFG_PSEL 0x00000040 +# elif LPC214X_USBPLL_P == 8 +# define LPC214X_USBPLLCFG_PSEL 0x00000060 +# else +# error "Unrecognized value for PLL_P" +# endif +# endif +# define CONFIG_USBPLLCFG_VALUE (LPC214X_USBPLLCFG_PSEL|LPC214X_USBPLLCFG_MSEL) +# endif +#endif + +/* Memory Accelerator Module (MAM) initialization values + * + * MAM Control Register + * Bit 0:1 Mode + * 0 = Disabled + * 1 = Partially Enabled + * 2 = Fully Enabled + * MAM Timing Register + * Bit 0:2 Fetch Cycles + * 0 = Reserved + * 1 = 1 + * 2 = 2 + * 3 = 3 + * 4 = 4 + * 5 = 5 + * 6 = 6 + * 7 = 7 + */ + +#ifndef CONFIG_MAMCR_VALUE /* Can be selected from config file */ +# define CONFIG_MAMCR_VALUE 0x00000002 +#endif + +#ifndef CONFIG_MAMTIM_VALUE /* Can be selected from config file */ +# define CONFIG_MAMTIM_VALUE 0x00000004 +#endif + +/* APBDIV initialization values + * + * Bits 0:1 APB Peripheral Bus Clock Rate + * 0 = APB Clock = CPU Clock / 4 + * 1 = APB Clock = CPU Clock + * 2 = APB Clock = CPU Clock / 2 + */ + +#ifndef CONFIG_APBDIV_VALUE /* Can be selected from config file */ +# ifdef LPC214X_APB_DIV +# if LPC214X_APB_DIV == 1 +# define CONFIG_APBDIV_VALUE LPC214X_APBDIV_DIV1 +# elif LPC214X_APB_DIV == 2 +# define CONFIG_APBDIV_VALUE LPC214X_APBDIV_DIV2 +# elif LPC214X_APB_DIV == 4 +# define CONFIG_APBDIV_VALUE LPC214X_APBDIV_DIV4 +# else +# error "Unrecognized value for APBDIV" +# endif +# else +# define CONFIG_APBDIV_VALUE LPC214X_APBDIV_DIV1 +# endif +#endif + +/* External Memory Controller (EMC) initialization values + * + * Bank Configuration n (BCFG0..3) + * Bit 0:3 IDCY: Idle Cycles (0-15) + * Bit 5:9 WST1: Wait States 1 (0-31) + * Bit 11:15 WST2: Wait States 2 (0-31) + * Bit 10 RBLE: Read Byte Lane Enable + * Bit 26 WP: Write Protect + * Bit 27 BM: Burst ROM + * Bit 28:29 MW: Memory Width (0=8-bit 1=16-bit 2=32-bit 3=Reserved) + */ + +#ifndef CONFIG_BCFG0_VALUE /* Can be selected from config file */ +# define CONFIG_BCFG0_VALUE 0x0000fbef +#endif + +#ifndef CONFIG_BCFG1_VALUE /* Can be selected from config file */ +# define CONFIG_BCFG1_VALUE 0x0000fbef +#endif + +#ifndef CONFIG_BCFG2_VALUE /* Can be selected from config file */ +# define CONFIG_BCFG2_VALUE 0x0000fbef +#endif + +#ifndef CONFIG_BCFG3_VALUE /* Can be selected from config file */ +# define CONFIG_BCFG3_VALUE 0x0000fbef +#endif + +/* The following are used to configure the ADC/DAC */ +#ifndef CONFIG_AD0CR_VALUE +# define CONFIG_AD0CR_VALUE 0x00200402; /* Setup A/D: 10-bit AIN0 @ 3MHz */ +#endif + +/* GIO Pin Selection Register settings + * + * PINSEL0 configures GPIO 0.0 through 0.15 + */ + +#ifndef CONFIG_PINSEL0_VALUE /* Can be selected from config file */ +# define CONFIG_PINSEL0_VALUE 0x00000000 /* Reset value */ +#endif + +/* PINSEL1 configures GPIO 0.16 through 0.30 and GPO */ + +#ifndef CONFIG_PINSEL1_VALUE /* Can be selected from the config file */ +# ifdef CONFIG_ADC_SETUP +# define CONFIG_PINSEL1_ADC 0x01000000 /* Enable DAC */ +# else +# define CONFIG_PINSEL1_ADC 0x00000000 /* Reset value */ +# endif +# ifdef CONFIG_USBDEV +# define CONFIG_PINSEL1_USBDEV 0x80004000 /* Enable Vbus and Connect LED */ +# else +# define CONFIG_PINSEL1_USBDEV 0x00000000 /* Reset value */ +# endif +# define CONFIG_PINSEL1_VALUE (CONFIG_PINSEL1_ADC|CONFIG_PINSEL1_USBDEV) +#endif + +/* External Memory Pins definitions + * Bit 0:1 Reserved + * Bit 2 GPIO/DEBUG + * Bit 3 GPIO/TRACE + * Bit 31:4 Reserved + * CS0..3, OE, WE, BLS0..3, D0..31, A2..23, JTAG Pins + */ + +#ifndef CONFIG_PINSEL2_VALUE /* Can be selected from config file */ +# define CONFIG_PINSEL2_VALUE 0x0e6149e4 +#endif + +/***************************************************************************** + * Macros + *****************************************************************************/ + +/* Print a character on the UART to show boot status. This macro will + * modify r0, r1, r2 and r14 + */ + + .macro showprogress, code +#ifdef CONFIG_DEBUG + mov r0, #\code + bl up_lowputc +#endif + .endm + +/* Configured the PINSEL2 register if EXTMEM mode is selected */ + + .macro configpinsel2, base, val +#ifdef CONFIG_EXTMEM_MODE + ldr \base, =LPC214X_PINSEL2 + ldr \val, =CONFIG_PINSEL2_VALUE + str \val, [\base] +#endif + .endm + +/* Configure the external memory controller */ + + .macro configemc, base, val +#ifdef CONFIG_EMC_SETUP + ldr \base, =LPC214X_EMC_BASE + +#ifdef CONFIG_BCFG0_SETUP + ldr \val, =CONFIG_BCFG0_VALUE + str \val, [\base, #LPC214X_BCFG0_OFFSET] +#endif + +#ifdef CONFIG_BCFG1_SETUP + ldr \val, =CONFIG_BCFG1_VALUE + str \val, [\base, #LPC214X_BCFG1_OFFSET] +#endif + +#ifdef CONFIG_BCFG2_SETUP + ldr \val, =CONFIG_BCFG2_VALUE + str \val, [\base, #LPC214X_BCFG2_OFFSET] +#endif + +#ifdef CONFIG_BCFG3_SETUP + ldr \val, =CONFIG_BCFG3_VALUE + str \val, [\base, #LPC214X_BCFG3_OFFSET] +#endif +#endif + .endm + +/* Configure APBDIV */ + + .macro configapbdiv, base, val +#ifdef CONFIG_APBDIV_SETUP + ldr \base, =LPC214X_APBDIV + ldr \val, =CONFIG_APBDIV_VALUE + strb \val, [\base] +#endif + .endm + +/* Configure the PLL */ + + .macro configpll, base, val1, val2, val3 +#ifdef CONFIG_PLL_SETUP + ldr \base, =LPC214X_PLL0_BASE + mov \val1, #LPC214X_PLL_FEED1 + mov \val2, #LPC214X_PLL_FEED2 + + /* Configure and Enable PLL */ + + mov \val3, #CONFIG_PLLCFG_VALUE + str \val3, [\base, #LPC214X_PLL_CFG_OFFSET] + mov \val3, #LPC214X_PLL_CON_PLLE + str \val3, [\base, #LPC214X_PLL_CON_OFFSET] + str \val1, [\base, #LPC214X_PLL_FEED_OFFSET] + str \val2, [\base, #LPC214X_PLL_FEED_OFFSET] + + /* Wait until PLL Locked */ +1: + ldr \val3, [\base, #LPC214X_PLL_STAT_OFFSET] + ands \val3, \val3, #LPC214X_PLL_STAT_PLOCK + beq 1b + + /* Switch to PLL Clock */ + + mov \val3, #(LPC214X_PLL_CON_PLLE | LPC214X_PLL_CON_PLLC) + str \val3, [\base, #LPC214X_PLL_CON_OFFSET] + str \val1, [\base, #LPC214X_PLL_FEED_OFFSET] + str \val2, [\base, #LPC214X_PLL_FEED_OFFSET] +#endif + .endm + + .macro configusbpll, base, val1, val2, val3 +#ifdef CONFIG_USBDEV + ldr \base, =LPC214X_PLL1_BASE + mov \val1, #LPC214X_PLL_FEED1 + mov \val2, #LPC214X_PLL_FEED2 + + /* Configure and Enable PLL */ + + mov \val3, #CONFIG_USBPLLCFG_VALUE + str \val3, [\base, #LPC214X_PLL_CFG_OFFSET] + mov \val3, #LPC214X_PLL_CON_PLLE + str \val3, [\base, #LPC214X_PLL_CON_OFFSET] + str \val1, [\base, #LPC214X_PLL_FEED_OFFSET] + str \val2, [\base, #LPC214X_PLL_FEED_OFFSET] + + /* Wait until PLL Locked */ +1: + ldr \val3, [\base, #LPC214X_PLL_STAT_OFFSET] + ands \val3, \val3, #LPC214X_PLL_STAT_PLOCK + beq 1b + + /* Switch to PLL Clock */ + + mov \val3, #(LPC214X_PLL_CON_PLLE | LPC214X_PLL_CON_PLLC) + str \val3, [\base, #LPC214X_PLL_CON_OFFSET] + str \val1, [\base, #LPC214X_PLL_FEED_OFFSET] + str \val2, [\base, #LPC214X_PLL_FEED_OFFSET] +#endif + .endm + + +/* Configure the Memory Accelerator Module (MAM) */ + + .macro configmam, base, val +#ifdef CONFIG_MAM_SETUP + ldr \base, =LPC214X_MAM_BASE + mov \val, #CONFIG_MAMTIM_VALUE + str \val, [\base, #LPC214x_MAM_TIM_OFFSET] + mov \val, #CONFIG_MAMCR_VALUE + str \val, [\base, #LPC214X_MAM_CR_OFFSET] +#endif + .endm + +/* Setup MEMMAP for the selected mode of operation */ + + .macro configmemmap, base, val + ldr \base, =LPC214X_MEMMAP +#if defined(CONFIG_EXTMEM_MODE) + mov \val, #3 +#elif defined(CONFIG_RAM_MODE) + mov \val, #2 +#else /* Setting the default should not be necessary */ + mov \val, #1 +#endif + str \val, [\base] + .endm + + .macro configdac, base, tmp +#ifdef CONFIG_ADC_SETUP + ldr \base, =LPC214X_AD0_BASE + ldr \tmp, =CONFIG_AD0CR_VALUE + str \tmp, [\base, #LPC214X_AD_ADCR_OFFSET] + + ldr \base,=LPC214X_PINSEL1 + ldr \tmp, =CONFIG_PINSEL1_VALUE + str \tmp, [\base] +#endif + .endm + + .macro configfastport, base, tmp +#ifdef CONFIG_LPC214x_FIO + ldr \base, =LPC214X_SCS + mov \tmp, #0x03 + str \tmp,[\base] +#endif + .endm + +/***************************************************************************** + * Text + *****************************************************************************/ + + .text + +/***************************************************************************** + * Name: _vector_table + * + * Description: + * Interrrupt vector table. This must be located at the beginning + * of the memory space (at CONFIG_CODE_BASE). The first entry in + * the vector table is the reset vector and this is the code that + * will execute whn the processor is reset. + * + *****************************************************************************/ + + .globl _vector_table + .type _vector_table, %function +_vector_table: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lswihandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + .long 0 /* 0x14: Vector checksum */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl up_vectorundefinsn + .globl up_vectorswi + .globl up_vectorprefetch + .globl up_vectordata + .globl up_vectorirq + .globl up_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long up_vectorundefinsn +.Lswihandler: + .long up_vectorswi +.Lprefetchaborthandler: + .long up_vectorprefetch +.Ldataaborthandler: + .long up_vectordata +.Lirqhandler: + .long up_vectorirq +.Lfiqhandler: + .long up_vectorfiq + .size _vector_table, . - _vector_table + +/***************************************************************************** + * Name: __start + * + * Description: + * Reset entry point. This is the first function to execute when + * the processor is reset. It initializes hardware and then gives + * control to NuttX. + * + *****************************************************************************/ + + .global __start + .type __start, #function + +__start: + /* Setup the initial processor mode */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT ) + msr cpsr, r0 + + /* Set up external memory mode (if so selected) */ + + configpinsel2 r0, r1 + + /* Setup the External Memory Controllor (EMC) as configured */ + + configemc r0, r1 + + /* Configure APBDIV */ + + configapbdiv r0, r1 + + /* Configure the PLL(s) */ + + configpll r0, r1, r2, r3 + configusbpll r0, r1, r2, r3 + + /* Configure the Memory Accelerator Module (MAM) */ + + configmam r0, r1 + + /* Setup MEMMAP for the selected mode of operation */ + + configmemmap r0, r1 + + /* Configure the DAC and ADC */ + + configdac r0, r1 + + /* Configure Fast GPIO Port */ + + configfastport r0, r1 + + /* Configure the uart so that we can get debug output as soon + * as possible. Modifies r0, r1, r2, and r14. + */ + + bl up_lowsetup + showprogress 'A' + + /* Setup system stack (and get the BSS range) */ + + adr r0, LC0 + ldmia r0, {r4, r5, sp} + + /* Clear system BSS section */ + + mov r0, #0 +1: cmp r4, r5 + strcc r0, [r4], #4 + bcc 1b + + showprogress 'B' + + /* Copy system .data sections to new home in RAM. */ + + adr r3, LC2 + ldmia r3, {r0, r1, r2} + +1: ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 1b + + /* Perform early serial initialization */ + + mov fp, #0 +#ifdef USE_EARLYSERIALINIT + bl up_earlyserialinit +#endif + + showprogress 'C' + showprogress '\n' + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + bl board_autoled_initialize +#endif + + /* Then jump to OS entry */ + + b os_start + + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_IDLETHREAD_STACKSIZE. The heap continues + * from there until the end of memory. See g_idle_topstack + * below. + */ + +LC0: .long _sbss + .long _ebss + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +LC2: .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata + .size __start, .-__start + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to LCO + * above. + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + + .end + diff --git a/arch/arm/src/lpc214x/lpc214x_i2c.h b/arch/arm/src/lpc214x/lpc214x_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..35fcc00f7ea4e900473ee44c5533fb06f7df4b10 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_i2c.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_i2c.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_I2C_H +#define _ARCH_ARM_SRC_LPC214X_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register address Offsets *********************************************************/ + +/* Defined in chip.h */ + +/* Register Address Definitions *****************************************************/ + +#define LPC214X_I2C0_CONSET (LPC214X_I2C0_BASE + LPC214X_I2C_ONSET_OFFSET) +#define LPC214X_I2C0_STAT (LPC214X_I2C0_BASE + LPC214X_I2C_STAT_OFFSET) +#define LPC214X_I2C0_DAT (LPC214X_I2C0_BASE + LPC214X_I2C_DAT_OFFSET) +#define LPC214X_I2C0_ADR (LPC214X_I2C0_BASE + LPC214X_I2C_ADR_OFFSET) +#define LPC214X_I2C0_SCLH (LPC214X_I2C0_BASE + LPC214X_I2C_SCLH_OFFSET) +#define LPC214X_I2C0_SCLL (LPC214X_I2C0_BASE + LPC214X_I2C_SCLL_OFFSET) +#define LPC214X_I2C0_CONCLR (LPC214X_I2C0_BASE + LPC214X_I2C_ONCLR_OFFSET) + +#define LPC214X_I2C1_CONSET (LPC214X_I2C1_BASE + LPC214X_I2C_ONSET_OFFSET) +#define LPC214X_I2C1_STAT (LPC214X_I2C1_BASE + LPC214X_I2C_STAT_OFFSET) +#define LPC214X_I2C1_DAT (LPC214X_I2C1_BASE + LPC214X_I2C_DAT_OFFSET) +#define LPC214X_I2C1_ADR (LPC214X_I2C1_BASE + LPC214X_I2C_ADR_OFFSET) +#define LPC214X_I2C1_SCLH (LPC214X_I2C1_BASE + LPC214X_I2C_SCLH_OFFSET) +#define LPC214X_I2C1_SCLL (LPC214X_I2C1_BASE + LPC214X_I2C_SCLL_OFFSET) +#define LPC214X_I2C1_CONCLR (LPC214X_I2C1_BASE + LPC214X_I2C_ONCLR_OFFSET) + +/* I2C register bit definitions *****************************************************/ + +/* Control Set Register (CONSET) */ + +#define I2C_CONSET_AA (1 << 2) /* Bit 2: Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* Bit 3: I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* Bit 4: STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* Bit 5: START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* Bit 6: I2C interface enable */ + +/* Control Clear Register (CONCLR) */ + +#define I2C_CONCLR_AAC (1 << 2) /* Bit 2: Assert acknowledge Clear bit */ +#define I2C_CONCLR_SIC (1 << 3) /* Bit 3: I2C interrupt Clear bit */ +#define I2C_CONCLR_STAC (1 << 5) /* Bit 5: START flag Clear bit */ +#define I2C_CONCLR_I2ENC (1 << 6) /* Bit 6: I2C interface Disable bit */ + +/* Status Register (STAT) */ + +#define I2C_STAT_SHIFT (1 << 3) /* Bits 3-7: Status bits */ +#define I2C_STAT_MASK (0xff << I2C_STAT_SHIFT) + +/* Master transmit mode */ + +# define I2C_STAT_MXSTART (0 << I2C_STAT_SHIFT) /* Start transmitted */ +# define I2C_STAT_MXRSTART (2 << I2C_STAT_SHIFT) /* Repeated start transmitted */ +# define I2C_STAT_MXSLAWACK (3 << I2C_STAT_SHIFT) /* SLA+W tranmitted + ACK received */ +# define I2C_STAT_MXSLAWNAK (4 << I2C_STAT_SHIFT) /* SLA+W tranmitted + NAK received */ +# define I2C_STAT_MXDATAACK (5 << I2C_STAT_SHIFT) /* Data tranmitted + ACK received */ +# define I2C_STAT_MXDATANAK (6 << I2C_STAT_SHIFT) /* Data tranmitted + NAK received */ +# define I2C_STAT_MXARBLOST (7 << I2C_STAT_SHIFT) /* Abritration lost in SLA+W or data */ + +/* Master receive mode */ + +# define I2C_STAT_MRSTART (0 << I2C_STAT_SHIFT) /* Start transmitted */ +# define I2C_STAT_MRRSTART (2 << I2C_STAT_SHIFT) /* Repeated start transmitted */ +# define I2C_STAT_MRARBLOST (7 << I2C_STAT_SHIFT) /* Abritration lost in NAK bit */ +# define I2C_STAT_MRSLARACK (8 << I2C_STAT_SHIFT) /* SLA+R tranmitted + ACK received */ +# define I2C_STAT_MRSLARNAK (9 << I2C_STAT_SHIFT) /* SLA+R tranmitted + NAK received */ +# define I2C_STAT_MRDATAACK (10 << I2C_STAT_SHIFT) /* Data received + send ACK */ +# define I2C_STAT_MRDATANAK (11 << I2C_STAT_SHIFT) /* Data received + send NAK */ + +/* Slave receive mode -- to be provided */ + +/* Slave receive mode -- to be provided */ + +/* Data Register (DAT) -- 8-bits of data */ + +/* Slave Address Register (ADR) */ + +#define I2C_ADR_GCA (1 << 0) /* Bit 0: General call enable */ +#define I2C_ADR_SHIFT 1 /* Bits 7-1: address */ +#define I2C_ADR_MASK (0x7f << I2C_ADR_SHIFT) + +/* SCL Duty Cycle Register (high half word - SCLH) - 16-bits of data */ + +/* SCL Duty Cycle Register (low half word - SCLL) - 16-bits of data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC214X_I2C_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_irq.c b/arch/arm/src/lpc214x/lpc214x_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..a28854c1764662cd85dc72ea840364ab78b10a0a --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_irq.c @@ -0,0 +1,229 @@ +/**************************************************************************** + * arch/arm/src/lpc214x/lpc214x_irq.c + * + * Copyright (C) 2007-2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc214x_vic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int reg; + + /* Disable all interrupts. We do this by writing zero to the IntEnable + * register. This is equivalent to writing all ones to the IntClearEnable + * register. + */ + + vic_putreg(0, LPC214X_VIC_INTENABLE_OFFSET); + + /* Select all IRQs, no FIQs */ + + vic_putreg(0, LPC214X_VIC_INTSELECT_OFFSET); + + /* Set the default vector */ + + vic_putreg((uint32_t)up_decodeirq, LPC214X_VIC_DEFVECTADDR_OFFSET); + + /* Disable all vectored interrupts */ + + for (reg = LPC214X_VIC_VECTCNTL0_OFFSET; + reg <= LPC214X_VIC_VECTCNTL15_OFFSET; + reg += 4) + { + vic_putreg(0, reg); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* Verify that the IRQ number is within range */ + + if (irq < NR_IRQS) + { + /* Disable the irq by setting the corresponding bit in the VIC + * Interrupt Enable Clear register. + */ + + vic_putreg((1 << irq), LPC214X_VIC_INTENCLEAR_OFFSET); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* Verify that the IRQ number is within range */ + + if (irq < NR_IRQS) + { + /* Disable all interrupts */ + + irqstate_t flags = enter_critical_section(); + + /* Enable the irq by setting the corresponding bit in the VIC + * Interrupt Enable register. + */ + + uint32_t val = vic_getreg(LPC214X_VIC_INTENABLE_OFFSET); + vic_putreg(val | (1 << irq), LPC214X_VIC_INTENABLE_OFFSET); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: up_attach_vector + * + * Description: + * Attach a user-supplied handler to a vectored interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_attach_vector(int irq, int vector, vic_vector_t handler) +{ + /* Verify that the IRQ number and vector number are within range */ + + if (irq < NR_IRQS && vector < 16 && handler) + { + int offset = vector << 2; + + /* Disable all interrupts */ + + irqstate_t flags = enter_critical_section(); + + /* Save the vector address */ + + vic_putreg((uint32_t)handler, LPC214X_VIC_VECTADDR0_OFFSET + offset); + + /* Enable the vectored interrupt */ + + vic_putreg(((irq << LPC214X_VECTCNTL_IRQSHIFT) | LPC214X_VECTCNTL_ENABLE), + LPC214X_VIC_VECTCNTL0_OFFSET + offset); + leave_critical_section(flags); + } +} +#endif + +/**************************************************************************** + * Name: up_detach_vector + * + * Description: + * Detach a user-supplied handler from a vectored interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_detach_vector(int vector) +{ + /* Verify that the vector number is within range */ + + if (vector < 16) + { + /* Disable the vectored interrupt */ + + int offset = vector << 2; + vic_putreg(0, LPC214X_VIC_VECTCNTL0_OFFSET + offset); + } +} +#endif diff --git a/arch/arm/src/lpc214x/lpc214x_lowputc.S b/arch/arm/src/lpc214x/lpc214x_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..179f440b4bbae3fa19fbf4936fd0bf4418048d98 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_lowputc.S @@ -0,0 +1,209 @@ +/************************************************************************** + * arch/arm/src/lpc214x/lpc214X_lowputc.S + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc214x_pinsel.h" +#include "lpc214x_uart.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define LPC214X_UART_BASE LPC214X_UART0_BASE +# define LPC214X_UART_PINSEL LPC214X_UART0_PINSEL +# define LPC214X_UART_PINMASK LPC214X_UART0_PINMASK +# define LPC214X_UART_BAUD CONFIG_UART0_BAUD +# define LPC214X_UART_BITS CONFIG_UART0_BITS +# define LPC214X_UART_PARITY CONFIG_UART0_PARITY +# define LPC214X_UART_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define LPC214X_UART_BASE LPC214X_UART1_BASE +# define LPC214X_UART_PINSEL LPC214X_UART1_PINSEL +# define LPC214X_UART_PINMASK LPC214X_UART1_PINMASK +# define LPC214X_UART_BAUD CONFIG_UART1_BAUD +# define LPC214X_UART_BITS CONFIG_UART1_BITS +# define LPC214X_UART_PARITY CONFIG_UART1_PARITY +# define LPC214X_UART_2STOP CONFIG_UART1_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +#if LPC214X_UART_BITS == 5 +# define LPC214X_LCR_CHAR LPC214X_LCR_CHAR_5 +#elif LPC214X_UART_BITS == 6 +# define LPC214X_LCR_CHAR LPC214X_LCR_CHAR_6 +#elif LPC214X_UART_BITS == 7 +# define LPC214X_LCR_CHAR LPC214X_LCR_CHAR_7 +#elif LPC214X_UART_BITS == 8 +# define LPC214X_LCR_CHAR LPC214X_LCR_CHAR_8 +#else +# error "No CONFIG_UARTn_BITS Setting" +#endif + +#if LPC214X_UART_PARITY == 0 +# define LPC214X_LCR_PAR LPC214X_LCR_PAR_NONE +#elif LPC214X_UART_PARITY == 1 +# define LPC214X_LCR_PAR LPC214X_LCR_PAR_ODD +#elif LPC214X_UART_PARITY == 2 +# define LPC214X_LCR_PAR LPC214X_LCR_PAR_EVEN +#elif LPC214X_UART_PARITY == 3 +# define LPC214X_LCR_PAR LPC214X_LCR_PAR_MARK +#elif LPC214X_UART_PARITY == 4 +# define LPC214X_LCR_PAR LPC214X_LCR_PAR_SPACE +#else +# error "No CONFIG_UARTn_PARITY Setting" +#endif + +#if LPC214X_UART_2STOP != 0 +# define LPC214X_LCR_STOP LPC214X_LCR_STOP_2 +#else +# define LPC214X_LCR_STOP LPC214X_LCR_STOP_1 +#endif + +#define LPC214X_LCR_VALUE (LPC214X_LCR_CHAR | LPC214X_LCR_PAR | LPC214X_LCR_STOP) +#define LPC214X_FCR_VALUE (LPC214X_FCR_FIFO_TRIG8 | LPC214X_FCR_TX_FIFO_RESET |\ + LPC214X_FCR_RX_FIFO_RESET | LPC214X_FCR_FIFO_ENABLE) + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + + ldr r1, =LPC214X_UART_BASE + strb r0, [r1, #LPC214X_UART_THR_OFFSET] + + /* Wait for the byte to be transferred */ + +1: ldr r0, [r1, #LPC214X_UART_LSR_OFFSET] + ands r0, #LPC214X_LSR_TEMT /* Transmitter empty */ + beq 1b + + /* And return */ + + mov pc, lr + .size up_lowputc, . - up_lowputc + +/* This performs basic initialization of the UART. This can be called very + * early in initialization because it does not depend on having a stack. It + * modifies r0-r2 and r14. + */ + + .text + .globl up_lowsetup + .type up_lowsetup, function +up_lowsetup: + /* Configure PINSEL0 */ + + ldr r0, =LPC214X_PINSEL0 + ldr r1, [r0] + ldr r2, =~LPC214X_UART_PINMASK + and r1, r2 + ldr r2, =LPC214X_UART_PINSEL + orr r1, r2 + str r1, [r0] + + /* Configure parity, data bits, stop bits and set DLAB=1 */ + + ldr r0, =LPC214X_UART_BASE + mov r1, #(LPC214X_LCR_VALUE | LPC214X_LCR_DLAB_ENABLE) + strb r1, [r0, #LPC214X_UART_LCR_OFFSET] + + /* Set the BAUD divisor */ + + mov r1, #(UART_BAUD(LPC214X_UART_BAUD) >> 8) + strb r1, [r0, #LPC214X_UART_DLM_OFFSET] + + mov r1, #(UART_BAUD(LPC214X_UART_BAUD) & 0xff) + strb r1, [r0, #LPC214X_UART_DLL_OFFSET] + + /* Clear DLAB */ + + mov r1, #LPC214X_LCR_VALUE + strb r1, [r0, #LPC214X_UART_LCR_OFFSET] + + /* Configure the FIFOs */ + + mov r1, #LPC214X_FCR_VALUE + strb r1, [r0, #LPC214X_UART_FCR_OFFSET] + + /* And return */ + + mov pc, lr + .size up_lowsetup, . - up_lowsetup + .end diff --git a/arch/arm/src/lpc214x/lpc214x_pinsel.h b/arch/arm/src/lpc214x/lpc214x_pinsel.h new file mode 100644 index 0000000000000000000000000000000000000000..21c6c2f9db58fed41931f2087fd67d02605853d5 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_pinsel.h @@ -0,0 +1,259 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_pinsl.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_PINSEL_H +#define _ARCH_ARM_SRC_LPC214X_PINSEL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register address definitions *****************************************************/ + +#define LPC214X_PINSEL0 (LPC214X_PINSEL_BASE + LPC214X_PINSEL0_OFFSET) +#define LPC214X_PINSEL1 (LPC214X_PINSEL_BASE + LPC214X_PINSEL1_OFFSET) +#define LPC214X_PINSEL2 (LPC214X_PINSEL_BASE + LPC214X_PINSEL2_OFFSET) + +/* Register bit definitions *********************************************************/ + +#define LPC214X_PINSEL0_P00_GPIO (0x00000000) +#define LPC214X_PINSEL0_P00_TXD0 (0x00000001) +#define LPC214X_PINSEL0_P00_PWM1 (0x00000002) +#define LPC214X_PINSEL0_P00_RSVD3 (0x00000003) +#define LPC214X_PINSEL0_P00_MASK (0x00000003) + +#define LPC214X_PINSEL0_P01_GPIO (0x00000000) +#define LPC214X_PINSEL0_P01_RXD0 (0x00000004) +#define LPC214X_PINSEL0_P01_PWM3 (0x00000008) +#define LPC214X_PINSEL0_P01_EINT0 (0x0000000c) +#define LPC214X_PINSEL0_P01_MASK (0x0000000c) + +#define LPC214X_PINSEL0_P02_GPIO (0x00000000) +#define LPC214X_PINSEL0_P02_SCL0 (0x00000010) +#define LPC214X_PINSEL0_P02_CAP00 (0x00000020) +#define LPC214X_PINSEL0_P02_RSVD3 (0x00000030) +#define LPC214X_PINSEL0_P02_MASK (0x00000030) + +#define LPC214X_PINSEL0_P03_GPIO (0x00000000) +#define LPC214X_PINSEL0_P03_SDA0 (0x00000040) +#define LPC214X_PINSEL0_P03_MAT00 (0x00000080) +#define LPC214X_PINSEL0_P03_EINT1 (0x000000c0) +#define LPC214X_PINSEL0_P03_MASK (0x000000c0) + +#define LPC214X_PINSEL0_P04_GPIO (0x00000000) +#define LPC214X_PINSEL0_P04_SCK0 (0x00000100) +#define LPC214X_PINSEL0_P04_CAP01 (0x00000200) +#define LPC214X_PINSEL0_P04_RSVD3 (0x00000300) +#define LPC214X_PINSEL0_P04_MASK (0x00000300) + +#define LPC214X_PINSEL0_P05_GPIO (0x00000000) +#define LPC214X_PINSEL0_P05_MISO0 (0x00000400) +#define LPC214X_PINSEL0_P05_MAT01 (0x00000800) +#define LPC214X_PINSEL0_P05_AD06 (0x00000c00) +#define LPC214X_PINSEL0_P05_MASK (0x00000c00) + +#define LPC214X_PINSEL0_P06_GPIO (0x00000000) +#define LPC214X_PINSEL0_P06_MOSI0 (0x00001000) +#define LPC214X_PINSEL0_P06_CAP02 (0x00002000) +#define LPC214X_PINSEL0_P06_AD10 (0x00003000) +#define LPC214X_PINSEL0_P06_MASK (0x00003000) + +#define LPC214X_PINSEL0_P07_GPIO (0x00000000) +#define LPC214X_PINSEL0_P07_SSEL0 (0x00004000) +#define LPC214X_PINSEL0_P07_PWM2 (0x00008000) +#define LPC214X_PINSEL0_P07_EINT2 (0x0000c000) +#define LPC214X_PINSEL0_P07_MASK (0x0000c000) + +#define LPC214X_PINSEL0_P08_GPIO (0x00000000) +#define LPC214X_PINSEL0_P08_TXD1 (0x00010000) +#define LPC214X_PINSEL0_P08_PWM4 (0x00020000) +#define LPC214X_PINSEL0_P08_AD11 (0x00030000) +#define LPC214X_PINSEL0_P08_MASK (0x00030000) + +#define LPC214X_PINSEL0_P09_GPIO (0x00000000) +#define LPC214X_PINSEL0_P09_RXD1 (0x00040000) +#define LPC214X_PINSEL0_P09_PWM6 (0x00080000) +#define LPC214X_PINSEL0_P09_EINT3 (0x000c0000) +#define LPC214X_PINSEL0_P09_MASK (0x000c0000) + +#define LPC214X_PINSEL0_P010_GPIO (0x00000000) +#define LPC214X_PINSEL0_P010_RTS1 (0x00100000) +#define LPC214X_PINSEL0_P010_CAP10 (0x00200000) +#define LPC214X_PINSEL0_P010_AD12 (0x00300000) +#define LPC214X_PINSEL0_P010_MASK (0x00300000) + +#define LPC214X_PINSEL0_P011_GPIO (0x00000000) +#define LPC214X_PINSEL0_P011_CTS1 (0x00400000) +#define LPC214X_PINSEL0_P011_CAP11 (0x00800000) +#define LPC214X_PINSEL0_P011_SCL1 (0x00c00000) +#define LPC214X_PINSEL0_P011_MASK (0x00c00000) + +#define LPC214X_PINSEL0_P012_GPIO (0x00000000) +#define LPC214X_PINSEL0_P012_DSR1 (0x01000000) +#define LPC214X_PINSEL0_P012_MAT10 (0x02000000) +#define LPC214X_PINSEL0_P012_AD13 (0x03000000) +#define LPC214X_PINSEL0_P012_MASK (0x03000000) + +#define LPC214X_PINSEL0_P013_GPIO (0x00000000) +#define LPC214X_PINSEL0_P013_DTR1 (0x04000000) +#define LPC214X_PINSEL0_P013_MAT11 (0x08000000) +#define LPC214X_PINSEL0_P013_AD14 (0x0c000000) +#define LPC214X_PINSEL0_P013_MASK (0x0c000000) + +#define LPC214X_PINSEL0_P014_GPIO (0x00000000) +#define LPC214X_PINSEL0_P014_DCD1 (0x10000000) +#define LPC214X_PINSEL0_P014_EINT1 (0x20000000) +#define LPC214X_PINSEL0_P014_SDA1 (0x30000000) +#define LPC214X_PINSEL0_P014_MASK (0x30000000) + +#define LPC214X_PINSEL0_P015_GPIO (0x00000000) +#define LPC214X_PINSEL0_P015_RI1 (0x40000000) +#define LPC214X_PINSEL0_P015_EINT2 (0x80000000) +#define LPC214X_PINSEL0_P015_AD15 (0xc0000000) +#define LPC214X_PINSEL0_P015_MASK (0xc0000000) + +#define LPC214X_PINSEL1_P016_GPIO (0x00000000) +#define LPC214X_PINSEL1_P016_EINT0 (0x00000001) +#define LPC214X_PINSEL1_P016_MAT02 (0x00000002) +#define LPC214X_PINSEL1_P016_CAP02 (0x00000003) +#define LPC214X_PINSEL1_P016_MASK (0x00000003) + +#define LPC214X_PINSEL1_P017_GPIO (0x00000000) +#define LPC214X_PINSEL1_P017_CAP12 (0x00000004) +#define LPC214X_PINSEL1_P017_SCK1 (0x00000008) +#define LPC214X_PINSEL1_P017_MAT12 (0x0000000c) +#define LPC214X_PINSEL1_P017_MASK (0x0000000c) + +#define LPC214X_PINSEL1_P018_GPIO (0x00000000) +#define LPC214X_PINSEL1_P018_CAP13 (0x00000010) +#define LPC214X_PINSEL1_P018_MISO1 (0x00000020) +#define LPC214X_PINSEL1_P018_MAT13 (0x00000030) +#define LPC214X_PINSEL1_P018_MASK (0x00000030) + +#define LPC214X_PINSEL1_P019_GPIO (0x00000000) +#define LPC214X_PINSEL1_P019_MAT12 (0x00000040) +#define LPC214X_PINSEL1_P019_MOSI1 (0x00000080) +#define LPC214X_PINSEL1_P019_CAP12 (0x000000c0) +#define LPC214X_PINSEL1_P019_MASK (0x000000c0) + +#define LPC214X_PINSEL1_P020_GPIO (0x00000000) +#define LPC214X_PINSEL1_P020_MAT13 (0x00000100) +#define LPC214X_PINSEL1_P020_SSEL1 (0x00000200) +#define LPC214X_PINSEL1_P020_EINT3 (0x00000300) +#define LPC214X_PINSEL1_P020_MASK (0x00000300) + +#define LPC214X_PINSEL1_P021_GPIO (0x00000000) +#define LPC214X_PINSEL1_P021_PWM5 (0x00000400) +#define LPC214X_PINSEL1_P021_AD16 (0x00000800) +#define LPC214X_PINSEL1_P021_CAP13 (0x00000c00) +#define LPC214X_PINSEL1_P021_MASK (0x00000c00) + +#define LPC214X_PINSEL1_P022_GPIO (0x00000000) +#define LPC214X_PINSEL1_P022_AD17 (0x00001000) +#define LPC214X_PINSEL1_P022_CAP00 (0x00002000) +#define LPC214X_PINSEL1_P022_MAT00 (0x00003000) +#define LPC214X_PINSEL1_P022_MASK (0x00003000) + +#define LPC214X_PINSEL1_P023_GPIO (0x00000000) +#define LPC214X_PINSEL1_P023_VBUS (0x00004000) +#define LPC214X_PINSEL1_P023_RSVD2 (0x00008000) +#define LPC214X_PINSEL1_P023_RSVD3 (0x0000c000) +#define LPC214X_PINSEL1_P023_MASK (0x0000c000) + +#define LPC214X_PINSEL1_P024_RSVD0 (0x00000000) +#define LPC214X_PINSEL1_P024_RSVD1 (0x00010000) +#define LPC214X_PINSEL1_P024_RSVD2 (0x00020000) +#define LPC214X_PINSEL1_P024_RSVD3 (0x00030000) +#define LPC214X_PINSEL1_P024_MASK (0x00030000) + +#define LPC214X_PINSEL1_P025_GPIO (0x00000000) +#define LPC214X_PINSEL1_P025_AD04 (0x00040000) +#define LPC214X_PINSEL1_P025_AOUT (0x00080000) +#define LPC214X_PINSEL1_P025_RSVD3 (0x000c0000) +#define LPC214X_PINSEL1_P025_MASK (0x000c0000) + +#define LPC214X_PINSEL1_P026_RSVD0 (0x00000000) +#define LPC214X_PINSEL1_P026_RSVD1 (0x00100000) +#define LPC214X_PINSEL1_P026_RSVD2 (0x00200000) +#define LPC214X_PINSEL1_P026_RSVD3 (0x00300000) +#define LPC214X_PINSEL1_P026_MASK (0x00300000) + +#define LPC214X_PINSEL1_P027_RSVD0 (0x00000000) +#define LPC214X_PINSEL1_P027_RSVD1 (0x00400000) +#define LPC214X_PINSEL1_P027_RSVD2 (0x00800000) +#define LPC214X_PINSEL1_P027_RSVD3 (0x00c00000) +#define LPC214X_PINSEL1_P027_MASK (0x00c00000) + +#define LPC214X_PINSEL1_P028_GPIO (0x00000000) +#define LPC214X_PINSEL1_P028_AD01 (0x01000000) +#define LPC214X_PINSEL1_P028_CAP02 (0x02000000) +#define LPC214X_PINSEL1_P028_MAT02 (0x03000000) +#define LPC214X_PINSEL1_P028_MASK (0x03000000) + +#define LPC214X_PINSEL1_P029_GPIO (0x00000000) +#define LPC214X_PINSEL1_P029_AD02 (0x04000000) +#define LPC214X_PINSEL1_P029_CAP03 (0x08000000) +#define LPC214X_PINSEL1_P029_MAT03 (0x0c000000) +#define LPC214X_PINSEL1_P029_MASK (0x0c000000) + +#define LPC214X_PINSEL1_P030_GPIO (0x00000000) +#define LPC214X_PINSEL1_P030_AD03 (0x10000000) +#define LPC214X_PINSEL1_P030_EINT3 (0x20000000) +#define LPC214X_PINSEL1_P030_CAP00 (0x30000000) +#define LPC214X_PINSEL1_P030_MASK (0x30000000) + +#define LPC214X_PINSEL1_P031_GPIO (0x00000000) +#define LPC214X_PINSEL1_P031_UPLED (0x40000000) +#define LPC214X_PINSEL1_P031_CONNECT (0x80000000) +#define LPC214X_PINSEL1_P031_RSVD3 (0xc0000000) +#define LPC214X_PINSEL1_P031_MASK (0xc0000000) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC214X_PINSEL_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_pll.h b/arch/arm/src/lpc214x/lpc214x_pll.h new file mode 100644 index 0000000000000000000000000000000000000000..4e19bcdc11c05a89df0bbff9bc798181fa48a18d --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_pll.h @@ -0,0 +1,105 @@ +/**************************************************************************************************** + * arch/arm/src/lpc214x/lpc214x_pll.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_PLL_H +#define _ARCH_ARM_SRC_LPC214X_PLL_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* PLL bass addresses *******************************************************************************/ + +/* There are two PLLs: PLL0 generates CCLK and PLL1 is configured to provide the 48MHx USB clock */ + +#define LPC214X_PLL0_BASE (LPC214X_PLL_BASE) +#define LPC214X_PLL1_BASE (LPC214X_PLL_BASE + 0x00000020) + +/* PLL registers ************************************************************************************/ + +#define LPC214x_PLL0_CON (LPC214X_PLL0_BASE+LPC214X_PLL_CON_OFFSET) +#define LPC214x_PLL0_CFG (LPC214X_PLL0_BASE+LPC214X_PLL_CFG_OFFSET) +#define LPC214x_PLL0_STAT (LPC214X_PLL0_BASE+LPC214X_PLL_STAT_OFFSET) +#define LPC214x_PLL0_FEED (LPC214X_PLL0_BASE+LPC214X_PLL_FEED_OFFSET) + +#define LPC214x_PLL1_CON (LPC214X_PLL1_BASE+LPC214X_PLL_CON_OFFSET) +#define LPC214x_PLL1_CFG (LPC214X_PLL1_BASE+LPC214X_PLL_CFG_OFFSET) +#define LPC214x_PLL1_STAT (LPC214X_PLL1_BASE+LPC214X_PLL_STAT_OFFSET) +#define LPC214x_PLL1_FEED (LPC214X_PLL1_BASE+LPC214X_PLL_FEED_OFFSET) + +/* Register bit settings ****************************************************************************/ + +/* PLL Control Register Bit Settings */ + +#define LPC214X_PLL_CON_PLLE (1 << 0) /* PLL Enable */ +#define LPC214X_PLL_CON_PLLC (1 << 1) /* PLL Connect */ + +/* PLL Configuration Register Bit Settings */ + +#define LPC214X_PLL_CFG_MSEL (0x1f << 0) /* PLL Multiplier (minus 1) */ +#define LPC214X_PLL_CFG_PSEL (0x03 << 5) /* PLL Divider (encoded) */ +#define LPC214X_PLL_CFG_PSEL1 (0x00 << 5) +#define LPC214X_PLL_CFG_PSEL2 (0x01 << 5) +#define LPC214X_PLL_CFG_PSEL4 (0x02 << 5) +#define LPC214X_PLL_CFG_PSEL8 (0x03 << 5) + +/* PLL Status Register Bit Settings */ + +#define LPC214X_PLL_STAT_MSEL (0x1f << 0) /* PLL Multiplier Readback */ +#define LPC214X_PLL_STAT_PSEL (0x03 << 5) /* PLL Divider Readback */ +#define LPC214X_PLL_STAT_PLLE (1 << 8) /* PLL Enable Readback */ +#define LPC214X_PLL_STAT_PLLC (1 << 9) /* PLL Connect Readback */ +#define LPC214X_PLL_STAT_PLOCK (1 << 10) /* PLL Lock Status */ + +/* PLL Feed Register values */ + +#define LPC214X_PLL_FEED1 0xaa +#define LPC214X_PLL_FEED2 0x55 + +/**************************************************************************************************** + * Inline Functions + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC214X_PLL_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_power.h b/arch/arm/src/lpc214x/lpc214x_power.h new file mode 100644 index 0000000000000000000000000000000000000000..699af8d59053d3551edfc0467fc732343238f61b --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_power.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_power.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_POWER_H +#define _ARCH_ARM_SRC_LPC214X_POWER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register address definitions *****************************************************/ + +#define LPC214X_PCON_PCON (0xe01fc0c0) /* Power control register */ +#define LPC214X_PCON_PCONP (0xe01fc0c4) /* Power controls for peripherals register */ + +/* Register bit definitions *********************************************************/ + +/* Power control register */ + +#define LPC214X_PCON_IDL (0x01) /* Bit 0=1: Idle mode ON */ +#define LPC214X_PCON_PD (0x02) /* Bit 1=1: Power down mode ON */ +#define LPC214X_PCON_BODPDM (0x04) /* Bit 2=1: Brown out power down mode ON */ +#define LPC214X_PCON_BOGD (0x08) /* Bit 3=1: Brown out global disable */ +#define LPC214X_PCON_BORD (0x10) /* Bit 4=1: Brown out reset disable */ + +/* Peripheral power control register */ + +#define LPC214X_PCONP_PCTIM0 (0x00000002) /* Bit 1=1: Timer/counter0 control */ +#define LPC214X_PCONP_PCTIM1 (0x00000004) /* Bit 2=1: Timer/counter1 control */ +#define LPC214X_PCONP_PCUART0 (0x00000008) /* Bit 3=1: UART0 control */ +#define LPC214X_PCONP_PCUART1 (0x00000010) /* Bit 4=1: UART1 control */ +#define LPC214X_PCONP_PCWM0 (0x00000020) /* Bit 5=1: PWM0 control */ +#define LPC214X_PCONP_PCI2C0 (0x00000080) /* Bit 7=1: I2C0 control */ +#define LPC214X_PCONP_PCSPI0 (0x00000100) /* Bit 8=1: SPI0 control */ +#define LPC214X_PCONP_PCRTC (0x00000200) /* Bit 9=1: RTCcontrol */ +#define LPC214X_PCONP_PCSPI1 (0x00000400) /* Bit 10=1: SPI1 control */ +#define LPC214X_PCONP_PCAD0 (0x00001000) /* Bit 12=1: A/C converter 0 control */ +#define LPC214X_PCONP_PCI2C1 (0x00080000) /* Bit 19=1: I2C1 control */ +#define LPC214X_PCONP_PCAD1 (0x00100000) /* Bit 20=1: A/C converter 1 control */ +#define LPC214X_PCONP_PCUSB (0x80000000) /* Bit 31=1: USB power/clock control */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC214X_POWER_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_serial.c b/arch/arm/src/lpc214x/lpc214x_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..041f9b8c0594f32ca407ad35de124e6676eab28f --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_serial.c @@ -0,0 +1,847 @@ +/**************************************************************************** + * arch/arm/src/lpc214x/lpc214x_serial.c + * + * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc214x_pinsel.h" +#include "lpc214x_uart.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; + +/* This describes the state of the LPC214X uart0 port. */ + +static struct up_dev_s g_uart0priv = +{ + .uartbase = LPC214X_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = LPC214X_UART0_IRQ, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; + +/* This describes the state of the LPC214X uart1 port. */ + +static struct up_dev_s g_uart1priv = +{ + .uartbase = LPC214X_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = LPC214X_UART1_IRQ, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; + +/* Now, which one with be tty0/console and which tty1? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port +# define TTYS0_DEV g_uart0port +# define TTYS1_DEV g_uart1port +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port +# define TTYS0_DEV g_uart1port +# define TTYS1_DEV g_uart0port +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint8_t *ier) +{ + if (ier) + { + *ier = priv->ier & LPC214X_IER_ALLIE; + } + + priv->ier &= ~LPC214X_IER_ALLIE; + up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint8_t ier) +{ + priv->ier |= ier & LPC214X_IER_ALLIE; + up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TX available condition */ + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check if the tranmitter holding register (THR) is empty */ + if ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_THRE) != 0) + { + /* The THR is empty, return */ + break; + } + } +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint8_t lcr = up_serialin(priv, LPC214X_UART_LCR_OFFSET); + if (enable) + { + lcr |= LPC214X_LCR_BREAK_ENABLE; + } + else + { + lcr &= ~LPC214X_LCR_BREAK_ENABLE; + } + up_serialout(priv, LPC214X_UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t baud; + uint8_t lcr; + + /* Clear fifos */ + + up_serialout(priv, LPC214X_UART_FCR_OFFSET, + (LPC214X_FCR_RX_FIFO_RESET | LPC214X_FCR_TX_FIFO_RESET)); + + /* Set trigger */ + + up_serialout(priv, LPC214X_UART_FCR_OFFSET, + (LPC214X_FCR_FIFO_ENABLE | LPC214X_FCR_FIFO_TRIG14)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, LPC214X_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + if (priv->bits == 7) + { + lcr |= LPC214X_LCR_CHAR_7; + } + else + { + lcr |= LPC214X_LCR_CHAR_8; + } + + if (priv->stopbits2) + { + lcr |= LPC214X_LCR_STOP_2; + } + + if (priv->parity == 1) + { + lcr |= LPC214X_LCR_PAR_ODD; + } + else if (priv->parity == 2) + { + lcr |= LPC214X_LCR_PAR_EVEN; + } + + /* Enter DLAB=1 */ + + up_serialout(priv, LPC214X_UART_LCR_OFFSET, + (lcr | LPC214X_LCR_DLAB_ENABLE)); + + /* Set the BAUD divisor */ + + baud = UART_BAUD(priv->baud); + up_serialout(priv, LPC214X_UART_DLM_OFFSET, baud >> 8); + up_serialout(priv, LPC214X_UART_DLL_OFFSET, baud & 0xff); + + /* Clear DLAB */ + + up_serialout(priv, LPC214X_UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, LPC214X_UART_FCR_OFFSET, + (LPC214X_FCR_FIFO_TRIG8 | LPC214X_FCR_TX_FIFO_RESET | + LPC214X_FCR_RX_FIFO_RESET | LPC214X_FCR_FIFO_ENABLE)); + + /* The NuttX serial driver waits for the first THRE interrupt before + * sending serial data... However, it appears that the lpc214x hardware + * does not generate that interrupt until a transition from not-empty + * to empty. So, the current kludge here is to send one NULL at + * startup to kick things off. + */ + + up_serialout(priv, LPC214X_UART_THR_OFFSET, '\0'); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint8_t status; + int passes; + + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, LPC214X_UART_IIR_OFFSET); + + /* The NO INTERRUPT should be zero if there are pending + * interrupts + */ + + if ((status & LPC214X_IIR_NO_INT) != 0) + { + /* Break out of the loop when there is no longer a + * pending interrupt + */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & LPC214X_IIR_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case LPC214X_IIR_RDA_INT: + case LPC214X_IIR_CTI_INT: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case LPC214X_IIR_THRE_INT: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts (UART1 only) */ + + case LPC214X_IIR_MS_INT: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, LPC214X_UART_MSR_OFFSET); + vdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case LPC214X_IIR_RLS_INT: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, LPC214X_UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint8_t rbr; + + *status = up_serialin(priv, LPC214X_UART_LSR_OFFSET); + rbr = up_serialin(priv, LPC214X_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= LPC214X_IER_ERBFI; +#endif + } + else + { + priv->ier &= ~LPC214X_IER_ERBFI; + } + up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, LPC214X_UART_THR_OFFSET, (uint8_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= LPC214X_IER_ETBEI; +#endif + } + else + { + priv->ier &= ~LPC214X_IER_ETBEI; + } + up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Enable UART0 and 1 */ + + uint32_t pinsel = getreg32(LPC214X_PINSEL0); + pinsel &= ~(LPC214X_UART0_PINMASK | LPC214X_UART1_PINMASK); + pinsel |= (LPC214X_UART0_PINSEL | LPC214X_UART1_PINSEL); + putreg32(pinsel, LPC214X_PINSEL0); + + /* Disable both UARTS */ + + up_disableuartint(TTYS0_DEV.priv, NULL); + up_disableuartint(TTYS1_DEV.priv, NULL); + + /* Configuration whichever one is the console */ + + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + up_serialout(priv, LPC214X_UART_THR_OFFSET, (uint8_t)ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, LPC214X_UART_THR_OFFSET, '\r'); + } + + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc214x/lpc214x_spi.h b/arch/arm/src/lpc214x/lpc214x_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..97e2fc7a58fce645de655604c7fef40cf0aede53 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_spi.h @@ -0,0 +1,184 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_spi.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC214X_SPI_H +#define _ARCH_ARM_SRC_LPC214X_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register address definitions *****************************************************/ + +/* SPI absolute register addresses */ + +#define LPC214X_SPI0_CR (LPC214X_SPI0_BASE+LPC214X_SPI0_CR_OFFSET) /* 16-bits wide */ +#define LPC214X_SPI0_SR (LPC214X_SPI0_BASE+LPC214X_SPI0_SR_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI0_DR (LPC214X_SPI0_BASE+LPC214X_SPI0_DR_OFFSET) /* 16-bits wide */ +#define LPC214X_SPI0_CCR (LPC214X_SPI0_BASE+LPC214X_SPI0_CCR_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI0_INT (LPC214X_SPI0_BASE+LPC214X_SPI0_INT_OFFSET) /* 8-bits wide */ + +#define LPC214X_SPI1_CR0 (LPC214X_SPI1_BASE+LPC214X_SPI1_CR0_OFFSET) /* 16-bits wide */ +#define LPC214X_SPI1_CR1 (LPC214X_SPI1_BASE+LPC214X_SPI1_CR1_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_DR (LPC214X_SPI1_BASE+LPC214X_SPI1_DR_OFFSET) /* 16-bits wide */ +#define LPC214X_SPI1_SR (LPC214X_SPI1_BASE+LPC214X_SPI1_SR_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_CPSR (LPC214X_SPI1_BASE+LPC214X_SPI1_IMSC_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_IMSC (LPC214X_SPI1_BASE+LPC214X_SPI1_IMSC_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_RIS (LPC214X_SPI1_BASE+LPC214X_SPI1_RIS_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_MIS (LPC214X_SPI1_BASE+LPC214X_SPI1_ICR_OFFSET) /* 8-bits wide */ +#define LPC214X_SPI1_ICR (LPC214X_SPI1_BASE+LPC214X_SPI1_ICR_OFFSET) /* 8-bits wide */ + +/* SPI0 register bit definitions ****************************************************/ + +/* Control Register (CR) for SPI0 */ + +#define LPC214X_SPI0CR0_BITSENB (0x0004) /* Bit 2=0: 8-bits, else see bits 8-11 */ +#define LPC214X_SPI0CR0_CPHA (0x0008) /* Bit 3: Clock phase control */ +#define LPC214X_SPI0CR0_CPOL (0x0010) /* Bit 4: Clock polarity control */ +#define LPC214X_SPI0CR0_MSTR (0x0020) /* Bit 5=1: Master 0: Slave */ +#define LPC214X_SPI0CR0_LSBF (0x0040) /* Bit 6=1: Shift LSB first */ +#define LPC214X_SPI0CR0_SPIE (0x0080) /* Bit 7=1: SPI interrupt enable */ +#define LPC214X_SPI0CR0_BITSMASK (0x0f00) /* Bits 8-11: Number of bits per transfer */ +#define LPC214X_SPI0CR0_BITS8 (0x0800) /* 8-bits per transfer */ +#define LPC214X_SPI0CR0_BITS9 (0x0900) /* 9-bits per transfer */ +#define LPC214X_SPI0CR0_BITS10 (0x0a00) /* 10-bits per transfer */ +#define LPC214X_SPI0CR0_BITS11 (0x0b00) /* 11-bits per transfer */ +#define LPC214X_SPI0CR0_BITS12 (0x0c00) /* 12-bits per transfer */ +#define LPC214X_SPI0CR0_BITS13 (0x0d00) /* 13-bits per transfer */ +#define LPC214X_SPI0CR0_BITS14 (0x0e00) /* 14-bits per transfer */ +#define LPC214X_SPI0CR0_BITS15 (0x0f00) /* 15-bits per transfer */ +#define LPC214X_SPI0CR0_BITS16 (0x0000) /* 16-bits per transfer */ + +/* Status Regiser (SR) for SPI0 */ + +#define LPC214X_SPI0SR_ABRT (0x08) /* Bit 3=1: Slave abort */ +#define LPC214X_SPI0SR_MODF (0x10) /* Bit 4=1: Mode fault */ +#define LPC214X_SPI0SR_ROVR (0x20) /* Bit 5=1: Read overrun */ +#define LPC214X_SPI0SR_WCOL (0x40) /* Bit 6=1: Write collision */ +#define LPC214X_SPI0SR_SPIF (0x80) /* Bit 7=1: SPI transfer complete */ + +/* Interrupt Register for SPI0 */ + +#define LPC214X_SPO0INT_SPI (0x01) /* Bit 0=1: SPI interrupt */ + +/* SPI1 register bit definitions ****************************************************/ + +/* Control Register 0 (CR0) for SPI1 */ + +#define LPC214X_SPI1CR0_DSSMASK (0x000f) /* Bits 0-3: Data size select mask */ +#define LPC214X_SPI1CR0_DSS4BIT (0x0003) /* 4-bit transfer */ +#define LPC214X_SPI1CR0_DSS5BIT (0x0004) /* 5-bit transfer */ +#define LPC214X_SPI1CR0_DSS6BIT (0x0005) /* 6-bit transfer */ +#define LPC214X_SPI1CR0_DSS7BIT (0x0006) /* 7-bit transfer */ +#define LPC214X_SPI1CR0_DSS8BIT (0x0007) /* 8-bit transfer */ +#define LPC214X_SPI1CR0_DSS9BIT (0x0008) /* 9-bit transfer */ +#define LPC214X_SPI1CR0_DSS10BIT (0x0009) /* 10-bit transfer */ +#define LPC214X_SPI1CR0_DSS11BIT (0x000a) /* 11-bit transfer */ +#define LPC214X_SPI1CR0_DSS12BIT (0x000b) /* 12-bit transfer */ +#define LPC214X_SPI1CR0_DSS13BIT (0x000c) /* 13-bit transfer */ +#define LPC214X_SPI1CR0_DSS14BIT (0x000d) /* 14-bit transfer */ +#define LPC214X_SPI1CR0_DSS15BIT (0x000e) /* 15-bit transfer */ +#define LPC214X_SPI1CR0_DSS16BIT (0x000f) /* 16-bit transfer */ +#define LPC214X_SPI1CR0_FRFMASK (0x0030) /* Bits 4-5: Frame format mask */ +#define LPC214X_SPI1CR0_FRFSPI (0x0000) /* SPI */ +#define LPC214X_SPI1CR0_FRFSSI (0x0010) /* SSI */ +#define LPC214X_SPI1CR0_FRFMW (0x0020) /* Microwire */ +#define LPC214X_SPI1CR0_CPOL (0x0040) /* Bit 6: Clock polarity control */ +#define LPC214X_SPI1CR0_CPHA (0x0080) /* Bit 7: Clock phase control */ +#define LPC214X_SPI1CR0_SCR (0xff00) /* Bits 8-15: Serial clock reate */ + +/* Control Register 1 (CR1) */ + +#define LPC214X_SPI1CR1_LBM (0x01) /* Bit 0: 1=Loopback mode */ +#define LPC214X_SPI1CR1_SSE (0x02) /* Bit 1: 1=SSP enable */ +#define LPC214X_SPI1CR1_MS (0x04) /* Bit 2: 1=Controller is slave */ +#define LPC214X_SPI1CR1_SOD (0x08) /* Bit 3: 1=Slave output disable */ + +/* SSP Status Register (SR) */ + +#define LPC214X_SPI1SR_TFE (0x01) /* Bit 0: 1=Transmit FIFO Empty */ +#define LPC214X_SPI1SR_TNF (0x02) /* Bit 1: 1=Transmit FIFO not full */ +#define LPC214X_SPI1SR_RNE (0x04) /* Bit 2: 1=Receive FIFO not empty */ +#define LPC214X_SPI1SR_RFF (0x08) /* Bit 3: 1=Receive FIFO full */ +#define LPC214X_SPI1SR_BSY (0x10) /* Bit 4: 1=Busy */ + +/* Interrupt set/clear/status/mask registers (can't clear RXIM or TXIM) */ + +#define LPC214X_SP1INT_ROR (0x01) /* Bit 0: 1=Recieve Overrun */ +#define LPC214X_SP1INT_RTIM (0x02) /* Bit 1: 1=Recieve Timeout */ +#define LPC214X_SP1INT_RXIM (0x04) /* Bit 2: 1=RX FIFO at least half full */ +#define LPC214X_SP1INT_TXIM (0x08) /* Bit 3: 1=TX FIFO at least half empty */ + +/* SPI1 supports an 8-frame FIFO */ + +#define LPC214X_SPI1_FIFOSZ (8) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ + +/**************************************************************************** + * Name: lpc214x_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc214x_spibus_initialize(int port); + +#endif /* _ARCH_ARM_SRC_LPC214X_SPI_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_timer.h b/arch/arm/src/lpc214x/lpc214x_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..224e608f3e96948a1e402a03ae03df9691411ceb --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_timer.h @@ -0,0 +1,152 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_timer.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __LPC214X_TIMER_H +#define __LPC214X_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Timer registers are 8-, 16-bit and 32-bits wide */ + +/* Timer Interrupt Register Bit Definitions (8-bit) */ + +#define LPC214X_TMR_IR_MR0I (1 << 0) /* Interrupt flag for match channel 0 */ +#define LPC214X_TMR_IR_MR1I (1 << 1) /* Interrupt flag for match channel 1 */ +#define LPC214X_TMR_IR_MR2I (1 << 2) /* Interrupt flag for match channel 2 */ +#define LPC214X_TMR_IR_MR3I (1 << 3) /* Interrupt flag for match channel 3 */ +#define LPC214X_TMR_IR_CR0I (1 << 4) /* Interrupt flag for capture channel 0 event */ +#define LPC214X_TMR_IR_CR1I (1 << 5) /* Interrupt flag for capture channel 1 event */ +#define LPC214X_TMR_IR_CR2I (1 << 6) /* Interrupt flag for capture channel 2 event */ +#define LPC214X_TMR_IR_CR3I (1 << 7) /* Interrupt flag for capture channel 3 event */ +#define LPC214X_TMR_IR_ALLI (0xff) /* All timer interrupts */ + +/* Timer Control Register Bit Definitions (8-bits) */ + +#define LPC214X_TMR_CR_ENABLE (1 << 0) /* Counter Enable */ +#define LPC214X_TMR_CR_RESET (1 << 1) /* Countger Reset */ + +/* Timer Counter (32-bits, no bit fields) */ + +/* Timer Prescale Register Bit Definitions (32-bits, no bit fields) */ + +/* Timer Prescale Counter Register Bit Definitions */ + +/* Timer Match Control Register Bit Definitions (16-bit) */ + +#define LPC214X_TMR_MCR_MR0I (1 << 0) /* Enable Interrupt when MR0 matches TC */ +#define LPC214X_TMR_MCR_MR0R (1 << 1) /* Enable Reset of TC upon MR0 match */ +#define LPC214X_TMR_MCR_MR0S (1 << 2) /* Enable Stop of TC upon MR0 match */ +#define LPC214X_TMR_MCR_MR1I (1 << 3) /* Enable Interrupt when MR1 matches TC */ +#define LPC214X_TMR_MCR_MR1R (1 << 4) /* Enable Reset of TC upon MR1 match */ +#define LPC214X_TMR_MCR_MR1S (1 << 5) /* Enable Stop of TC upon MR1 match */ +#define LPC214X_TMR_MCR_MR2I (1 << 6) /* Enable Interrupt when MR2 matches TC */ +#define LPC214X_TMR_MCR_MR2R (1 << 7) /* Enable Reset of TC upon MR2 match */ +#define LPC214X_TMR_MCR_MR2S (1 << 8) /* Enable Stop of TC upon MR2 match */ +#define LPC214X_TMR_MCR_MR3I (1 << 9) /* Enable Interrupt when MR3 matches TC */ +#define LPC214X_TMR_MCR_MR3R (1 << 10) /* Enable Reset of TC upon MR3 match */ +#define LPC214X_TMR_MCR_MR3S (1 << 11) /* Enable Stop of TC upon MR3 match */ + +/* Timer Match Register 0/1/2/3 (32-bits, no bit fields) */ + +/* Timer Capture Control Register Bit Definitions */ + +#define LPC214X_TMR_CCR_CAP0RE (1 << 0) /* Enable Rising edge on CAPn.0 will load TC to CR0 */ +#define LPC214X_TMR_CCR_CAP0FE (1 << 1) /* Enable Falling edge on CAPn.0 will load TC to CR0 */ +#define LPC214X_TMR_CCR_CAP0I (1 << 2) /* Enable Interrupt on load of CR0 */ +#define LPC214X_TMR_CCR_CAP1RE (1 << 3) /* Enable Rising edge on CAPn.1 will load TC to CR1 */ +#define LPC214X_TMR_CCR_CAP1FE (1 << 4) /* Enable Falling edge on CAPn.1 will load TC to CR1 */ +#define LPC214X_TMR_CCR_CAP1I (1 << 5) /* Enable Interrupt on load of CR1 */ +#define LPC214X_TMR_CCR_CAP2RE (1 << 6) /* Enable Rising edge on CAPn.2 will load TC to CR2 */ +#define LPC214X_TMR_CCR_CAP2FE (1 << 7) /* Enable Falling edge on CAPn.2 will load TC to CR2 */ +#define LPC214X_TMR_CCR_CAP2I (1 << 8) /* Enable Interrupt on load of CR2 */ +#define LPC214X_TMR_CCR_CAP3RE (1 << 9) /* Enable Rising edge on CAPn.3 will load TC to CR3 */ +#define LPC214X_TMR_CCR_CAP3FE (1 << 10) /* Enable Falling edge on CAPn.3 will load TC to CR3 */ +#define LPC214X_TMR_CCR_CAP3I (1 << 11) /* Enable Interrupt on load of CR3 */ + +/* Timer Capture Register 0/1/2/3 (32-bits, no bit fields) */ + +/* Timer External Match Register Bit Definitions */ + +#define LPC214X_TMR_EMR_EM0 (1 << 0) /* External Match 0 */ +#define LPC214X_TMR_EMR_EM1 (1 << 1) /* External Match 1 */ +#define LPC214X_TMR_EMR_EM2 (1 << 2) /* External Match 2 */ +#define LPC214X_TMR_EMR_EM3 (1 << 3) /* External Match 3 */ + +#define LPC214X_TMR_EMR_EMC0(b) ((b) << 4) /* External match control 0 (see below) */ +#define LPC214X_TMR_EMR_EMC1(b) ((b) << 6) /* External match control 1 (see below) */ +#define LPC214X_TMR_EMR_EMC2(b) ((b) << 8) /* External match control 2 (see below) */ +#define LPC214X_TMR_EMR_EMC3(b) ((b) << 10) /* External match control 3 (see below) */ + +/* EMR External Match Control (EMCn) Field Falues */ + +#define LPC214X_TMR_EMR_MASK (3) /* Mask for all bits */ +#define LPC214X_TMR_EMR_NOOP (0) /* Do nothing */ +#define LPC214X_TMR_EMR_CLEAR (1) /* Clear corresponding EMn bit/output to 0 */ +#define LPC214X_TMR_EMR_SET (2) /* Set corresponding EMn bit/output to 1 */ +#define LPC214X_TMR_EMR_TOGGLE (3) /* Toggle corresponding EMn bit/output */ + +/* Timer Count Control Register Bit Definitions (8-bit) */ + +#define LPC214X_TMR_ +#define LPC214X_TMR_CTCR_MODE_MASK (3 << 0) /* Counter/Timer Mode */ +#define LPC214X_TMR_CTCR_PCLK (0 << 0) /* Rising edge of PCLK */ +#define LPC214X_TMR_CTCR_RISING (1 << 0) /* Rising edge of CAP input */ +#define LPC214X_TMR_CTDR_FALLING (2 << 0) /* Failing edge of CAP input */ +#define LPC214X_TMR_CTCR_BOTH (3 << 0) /* Both edges of CAP input */ +#define LPC214X_TMR_CTCR_INPUT_MASK (3 << 2) /* Counter Input Select */ +#define LPC214X_TMR_CTCR_CR0 (0 << 2) /* CAPn.0 */ +#define LPC214X_TMR_CTCR_CR1 (1 << 2) /* CAPn.1 */ +#define LPC214X_TMR_CTCR_CR2 (2 << 2) /* CAPn.2 */ +#define LPC214X_TMR_CTCR_CR3 (3 << 2) /* CAPn.3 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __LPC214X_TIMER_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_timerisr.c b/arch/arm/src/lpc214x/lpc214x_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..24defd5a52db90233cf812e9b051bece1ef5ba1f --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_timerisr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/lpc214x/lpc214x_timerisr.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "clock/clock.h" +#include "up_internal.h" + +#include "lpc214x_timer.h" +#include "lpc214x_vic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The timers count at the rate of PCLK which is determined by PLL_M and + * and APBDIV: + */ + +#define LPC214X_CCLKFREQ (LPC214X_FOSC*LPC214X_PLL_M) +#define LPC214X_PCLKFREQ (LPC214X_CCLKFREQ/LPC214X_APB_DIV) + +#define tmr_getreg8(o) getreg8(LPC214X_TMR0_BASE+(o)) +#define tmr_getreg16(o) getreg16(LPC214X_TMR0_BASE+(o)) +#define tmr_getreg32(o) getreg32(LPC214X_TMR0_BASE+(o)) + +#define tmr_putreg8(v,o) putreg8((v), LPC214X_TMR0_BASE+(o)) +#define tmr_putreg16(v,o) putreg16((v), LPC214X_TMR0_BASE+(o)) +#define tmr_putreg32(v,o) putreg32((v), LPC214X_TMR0_BASE+(o)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for + * various portions of the systems. + * + ****************************************************************************/ + +#ifdef CONFIG_VECTORED_INTERRUPTS +int up_timerisr(uint32_t *regs) +#else +int up_timerisr(int irq, uint32_t *regs) +#endif +{ + /* Process timer interrupt */ + + sched_process_timer(); + + /* Clear the MR0 match interrupt */ + + tmr_putreg8(LPC214X_TMR_IR_MR0I, LPC214X_TMR_IR_OFFSET); + + /* Reset the VIC as well */ + +#ifdef CONFIG_VECTORED_INTERRUPTS + vic_putreg(0, LPC214X_VIC_VECTADDR_OFFSET); +#endif + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint16_t mcr; + + /* Clear all match and capture event interrupts */ + + tmr_putreg8(LPC214X_TMR_IR_ALLI, LPC214X_TMR_IR_OFFSET); + + /* Clear the timer counter */ + + tmr_putreg32(0, LPC214X_TMR_TC_OFFSET); + + /* No pre-scaler */ + + tmr_putreg32(0, LPC214X_TMR_PR_OFFSET); + + /* Set timer match registger to get a TICK_PER_SEC rate + */ + + tmr_putreg32(LPC214X_PCLKFREQ/TICK_PER_SEC, LPC214X_TMR_MR0_OFFSET); + + /* Reset timer counter regiser and interrupt on match */ + + mcr = tmr_getreg16(LPC214X_TMR_MCR_OFFSET); + mcr &= ~LPC214X_TMR_MCR_MR1I; + mcr |= (LPC214X_TMR_MCR_MR0I | LPC214X_TMR_MCR_MR0R); + tmr_putreg16(mcr, LPC214X_TMR_MCR_OFFSET); + + /* Enable counting */ + + tmr_putreg8(LPC214X_TMR_CR_ENABLE, LPC214X_TMR_TCR_OFFSET); + + /* Attach the timer interrupt vector */ + +#ifdef CONFIG_VECTORED_INTERRUPTS + up_attach_vector(LPC214X_IRQ_SYSTIMER, LPC214X_SYSTIMER_VEC, (vic_vector_t)up_timerisr); +#else + (void)irq_attach(LPC214X_IRQ_SYSTIMER, (xcpt_t)up_timerisr); +#endif + + /* And enable the timer interrupt */ + + up_enable_irq(LPC214X_IRQ_SYSTIMER); +} diff --git a/arch/arm/src/lpc214x/lpc214x_uart.h b/arch/arm/src/lpc214x/lpc214x_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..c4c90c166926ef02998d8128b0d3865ab17d2b6d --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_uart.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/uart.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __LPC214X_UART_H +#define __LPC214X_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include /* For clock settings */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* PINSEL0 bit definitions for UART0/1 */ + +#define LPC214X_UART0_PINSEL 0x00000005 /* PINSEL0 value for UART0 */ +#define LPC214X_UART0_PINMASK 0x0000000f /* PINSEL0 mask for UART0 */ + +#define LPC214X_UART1_PINSEL 0x00050000 /* PINSEL0 value for UART1 */ +#define LPC214X_UART1_PINMASK 0x000f0000 /* PINSEL0 mask for UART1 */ + +/* Derive baud divisor setting from clock settings (see board.h) */ + +#define UART_BAUD(baud) ((LPC214X_FOSC * LPC214X_PLL_M) / (baud * 16)) + +/* Interrupt Enable Register (IER) bit definitions */ + +#define LPC214X_IER_ERBFI (1 << 0) /* Enable receive data available int */ +#define LPC214X_IER_ETBEI (1 << 1) /* Enable THR empty Interrupt */ +#define LPC214X_IER_ELSI (1 << 2) /* Enable receive line status int */ +#define LPC214X_IER_EDSSI (1 << 3) /* Enable MODEM atatus interrupt (2146/6/8 UART1 Only) */ +#define LPC214X_IER_ALLIE 0x0f /* All interrupts */ + +/* Interrupt ID Register(IIR) bit definitions */ + +#define LPC214X_IIR_NO_INT (1 << 0) /* No interrupts pending */ +#define LPC214X_IIR_MS_INT (0 << 1) /* MODEM Status (UART1 only) */ +#define LPC214X_IIR_THRE_INT (1 << 1) /* Transmit Holding Register Empty */ +#define LPC214X_IIR_RDA_INT (2 << 1) /* Receive Data Available */ +#define LPC214X_IIR_RLS_INT (3 << 1) /* Receive Line Status */ +#define LPC214X_IIR_CTI_INT (6 << 1) /* Character Timeout Indicator */ +#define LPC214X_IIR_MASK 0x0e + +/* FIFO Control Register (FCR) bit definitions */ + +#define LPC214X_FCR_FIFO_ENABLE (1 << 0) /* FIFO enable */ +#define LPC214X_FCR_RX_FIFO_RESET (1 << 1) /* Reset receive FIFO */ +#define LPC214X_FCR_TX_FIFO_RESET (1 << 2) /* Reset transmit FIFO */ +#define LPC214X_FCR_FIFO_TRIG1 (0 << 6) /* Trigger @1 character in FIFO */ +#define LPC214X_FCR_FIFO_TRIG4 (1 << 6) /* Trigger @4 characters in FIFO */ +#define LPC214X_FCR_FIFO_TRIG8 (2 << 6) /* Trigger @8 characters in FIFO */ +#define LPC214X_FCR_FIFO_TRIG14 (3 << 6) /* Trigger @14 characters in FIFO */ + +/* Line Control Register (LCR) bit definitions */ + +#define LPC214X_LCR_CHAR_5 (0 << 0) /* 5-bit character length */ +#define LPC214X_LCR_CHAR_6 (1 << 0) /* 6-bit character length */ +#define LPC214X_LCR_CHAR_7 (2 << 0) /* 7-bit character length */ +#define LPC214X_LCR_CHAR_8 (3 << 0) /* 8-bit character length */ +#define LPC214X_LCR_STOP_1 (0 << 2) /* 1 stop bit */ +#define LPC214X_LCR_STOP_2 (1 << 2) /* 2 stop bits */ +#define LPC214X_LCR_PAR_NONE (0 << 3) /* No parity */ +#define LPC214X_LCR_PAR_ODD (1 << 3) /* Odd parity */ +#define LPC214X_LCR_PAR_EVEN (3 << 3) /* Even parity */ +#define LPC214X_LCR_PAR_MARK (5 << 3) /* Mark "1" parity */ +#define LPC214X_LCR_PAR_SPACE (7 << 3) /* Space "0" parity */ +#define LPC214X_LCR_BREAK_ENABLE (1 << 6) /* Output BREAK */ +#define LPC214X_LCR_DLAB_ENABLE (1 << 7) /* Enable divisor latch access */ + +/* Modem Control Register (MCR) bit definitions */ + +#define LPC214X_MCR_DTR (1 << 0) /* Data terminal ready */ +#define LPC214X_MCR_RTS (1 << 1) /* Request to send */ +#define LPC214X_MCR_LB (1 << 4) /* Loopback */ + +/* Line Status Register (LSR) bit definitions */ + +#define LPC214X_LSR_RDR (1 << 0) /* Receive data ready */ +#define LPC214X_LSR_OE (1 << 1) /* Overrun error */ +#define LPC214X_LSR_PE (1 << 2) /* Parity error */ +#define LPC214X_LSR_FE (1 << 3) /* Framing error */ +#define LPC214X_LSR_BI (1 << 4) /* Break interrupt */ +#define LPC214X_LSR_THRE (1 << 5) /* THR empty */ +#define LPC214X_LSR_TEMT (1 << 6) /* Transmitter empty */ +#define LPC214X_LSR_RXFE (1 << 7) /* Error in receive FIFO */ +#define LPC214X_LSR_ERR_MASK 0x1e + +/* Modem Status Register (MSR) bit definitions */ + +#define LPC214X_MSR_DCTS (1 << 0) /* Delta clear to send */ +#define LPC214X_MSR_DDSR (1 << 1) /* Delta data set ready */ +#define LPC214X_MSR_TERI (1 << 2) /* Trailing edge ring indicator */ +#define LPC214X_MSR_DDCD (1 << 3) /* Delta data carrier detect */ +#define LPC214X_MSR_CTS (1 << 4) /* Clear to send */ +#define LPC214X_MSR_DSR (1 << 5) /* Data set ready */ +#define LPC214X_MSR_RI (1 << 6) /* Ring indicator */ +#define LPC214X_MSR_DCD (1 << 7) /* Data carrier detect */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __LPC214X_UART_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_usbdev.c b/arch/arm/src/lpc214x/lpc214x_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..5c058a6bc3b297353ab3cfd76311a76ca3ca6b98 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_usbdev.c @@ -0,0 +1,3395 @@ +/**************************************************************************** + * arch/arm/src/lpc214x/lpc214x_usbdev.c + * + * Copyright (C) 2008-2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc214x_usbdev.h" +#include "lpc214x_pll.h" +#include "lpc214x_power.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +#define USB_SLOW_INT USBDEV_DEVINT_EPSLOW +#define USB_DEVSTATUS_INT USBDEV_DEVINT_DEVSTAT + +#ifdef CONFIG_LPC214X_USBDEV_EPFAST_INTERRUPT +# define USB_FAST_INT USBDEV_DEVINT_EPFAST +#else +# define USB_FAST_INT 0 +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#undef CONFIG_LPC214X_USBDEV_REGDEBUG + +/* Enable reading SOF from interrupt handler vs. simply reading on demand. Probably + * a bad idea... Unless there is some issue with sampling the SOF from hardware + * asynchronously. + */ + +#ifdef CONFIG_LPC214X_USBDEV_FRAME_INTERRUPT +# define USB_FRAME_INT USBDEV_DEVINT_FRAME +#else +# define USB_FRAME_INT 0 +#endif + +#ifdef CONFIG_DEBUG +# define USB_ERROR_INT USBDEV_DEVINT_EPRINT +#else +# define USB_ERROR_INT 0 +#endif + +/* Number of DMA descriptors */ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +# error DMA SUPPORT NOT YET FULLY IMPLEMENTED +# ifndef CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS +# define CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS 8 +# elif CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS > 30 +# define CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS 30 +# endif +#endif + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define LPC214X_TRACEERR_ALLOCFAIL 0x0001 +#define LPC214X_TRACEERR_BADCLEARFEATURE 0x0002 +#define LPC214X_TRACEERR_BADDEVGETSTATUS 0x0003 +#define LPC214X_TRACEERR_BADEPNO 0x0004 +#define LPC214X_TRACEERR_BADEPGETSTATUS 0x0005 +#define LPC214X_TRACEERR_BADEPTYPE 0x0006 +#define LPC214X_TRACEERR_BADGETCONFIG 0x0007 +#define LPC214X_TRACEERR_BADGETSETDESC 0x0008 +#define LPC214X_TRACEERR_BADGETSTATUS 0x0009 +#define LPC214X_TRACEERR_BADSETADDRESS 0x000a +#define LPC214X_TRACEERR_BADSETCONFIG 0x000b +#define LPC214X_TRACEERR_BADSETFEATURE 0x000c +#define LPC214X_TRACEERR_BINDFAILED 0x000d +#define LPC214X_TRACEERR_DISPATCHSTALL 0x000e +#define LPC214X_TRACEERR_DMABUSY 0x000f +#define LPC214X_TRACEERR_DRIVER 0x0010 +#define LPC214X_TRACEERR_DRIVERREGISTERED 0x0011 +#define LPC214X_TRACEERR_EP0INSTALLED 0x0012 +#define LPC214X_TRACEERR_EP0OUTSTALLED 0x0013 +#define LPC214X_TRACEERR_EP0SETUPSTALLED 0x0014 +#define LPC214X_TRACEERR_EPINNULLPACKET 0x0015 +#define LPC214X_TRACEERR_EPOUTNULLPACKET 0x0016 +#define LPC214X_TRACEERR_EPREAD 0x0017 +#define LPC214X_TRACEERR_INVALIDCMD 0x0018 +#define LPC214X_TRACEERR_INVALIDCTRLREQ 0x0019 +#define LPC214X_TRACEERR_INVALIDPARMS 0x001a +#define LPC214X_TRACEERR_IRQREGISTRATION 0x001b +#define LPC214X_TRACEERR_NODMADESC 0x001c +#define LPC214X_TRACEERR_NOEP 0x001d +#define LPC214X_TRACEERR_NOTCONFIGURED 0x001e +#define LPC214X_TRACEERR_REQABORTED 0x001f + +/* Trace interrupt codes */ + +#define LPC214X_TRACEINTID_USB 0x0001 +#define LPC214X_TRACEINTID_CLEARFEATURE 0x0002 +#define LPC214X_TRACEINTID_CONNECTCHG 0x0003 +#define LPC214X_TRACEINTID_CONNECTED 0x0004 +#define LPC214X_TRACEINTID_DEVGETSTATUS 0x0005 +#define LPC214X_TRACEINTID_DEVRESET 0x0006 +#define LPC214X_TRACEINTID_DEVSTAT 0x0007 +#define LPC214X_TRACEINTID_DISCONNECTED 0x0008 +#define LPC214X_TRACEINTID_DISPATCH 0x0009 +#define LPC214X_TRACEINTID_EP0IN 0x000a +#define LPC214X_TRACEINTID_EP0OUT 0x000b +#define LPC214X_TRACEINTID_EP0SETUP 0x000c +#define LPC214X_TRACEINTID_EPDMA 0x000d +#define LPC214X_TRACEINTID_EPFAST 0x000e +#define LPC214X_TRACEINTID_EPGETSTATUS 0x000f +#define LPC214X_TRACEINTID_EPIN 0x0010 +#define LPC214X_TRACEINTID_EPINQEMPTY 0x0011 +#define LPC214X_TRACEINTID_EP0INSETADDRESS 0x0012 +#define LPC214X_TRACEINTID_EPOUT 0x0013 +#define LPC214X_TRACEINTID_EPOUTQEMPTY 0x0014 +#define LPC214X_TRACEINTID_EP0SETUPSETADDRESS 0x0015 +#define LPC214X_TRACEINTID_EPRINT 0x0016 +#define LPC214X_TRACEINTID_EPSLOW 0x0017 +#define LPC214X_TRACEINTID_FRAME 0x0018 +#define LPC214X_TRACEINTID_GETCONFIG 0x0019 +#define LPC214X_TRACEINTID_GETSETDESC 0x001a +#define LPC214X_TRACEINTID_GETSETIF 0x001b +#define LPC214X_TRACEINTID_GETSTATUS 0x001c +#define LPC214X_TRACEINTID_IFGETSTATUS 0x001d +#define LPC214X_TRACEINTID_SETCONFIG 0x001e +#define LPC214X_TRACEINTID_SETFEATURE 0x001f +#define LPC214X_TRACEINTID_SUSPENDCHG 0x0020 +#define LPC214X_TRACEINTID_SYNCHFRAME 0x0021 + +/* Hardware interface **********************************************************/ + +/* Macros for testing the device status response */ + +#define DEVSTATUS_CONNECT(s) (((s)&USBDEV_DEVSTATUS_CONNECT)!=0) +#define DEVSTATUS_CONNCHG(s) (((s)&USBDEV_DEVSTATUS_CONNCHG)!=0) +#define DEVSTATUS_SUSPEND(s) (((s)&USBDEV_DEVSTATUS_SUSPEND)!=0) +#define DEVSTATUS_SUSPCHG(s) (((s)&USBDEV_DEVSTATUS_SUSPCHG)!=0) +#define DEVSTATUS_RESET(s) (((s)&USBDEV_DEVSTATUS_RESET)!=0) + +/* If this bit is set in the lpc214x_epread response, it means that the + * recevied packet was overwritten by a later setup packet (ep0 only). + */ + +#define LPC214X_READOVERRUN_BIT (0x80000000) +#define LPC214X_READOVERRUN(s) (((s) & LPC214X_READOVERRUN_BIT) != 0) + +/* USB RAM ******************************************************************** + * + * UBS_UDCA is is list of 32 pointers to DMA descriptors located at the + * beginning of USB RAM. Each pointer points to a DMA descriptor with + * assocated DMA buffer. + */ + +#define USB_UDCA (uint32_t *)LPC214X_USBDEV_RAMBASE) +#define USB_USCASIZE (LPC214X_NPHYSENDPOINTS*sizeof(uint32_t)) + +/* Each descriptor must be aligned to a 128 address boundary */ + +#define USB_DDALIGNDOWN(a) ((a)&~0x7f) +#define USB_DDALIGNUP(a) USB_DDALIGNDOWN((a)+0x7f) + +#define USB_DDSIZE USB_DDALIGNDOWN((LPC214X_USBDEV_RAMSIZE-USB_USCASIZE)/CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS) +#define USB_DDESC ((struct lpc214x_dmadesc_s*)(LPC214X_USBDEV_RAMBASE+USB_USCASIZE)) + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +# define USB_DDESCSIZE (5*sizeof(uint32_t)) +#else +# define USB_DDESCSIZE (4*sizeof(uint32_t)) +#endif + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define LPC214X_NLOGENDPOINTS (16) /* ep0-15 */ +#define LPC214X_NPHYSENDPOINTS (32) /* x2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are out */ + +#define LPC214X_EPPHYIN(epphy) (((epphy)&1)!=0) +#define LPC214X_EPPHYOUT(epphy) (((epphy)&1)==0) + +#define LPC214X_EPPHYIN2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_IN) +#define LPC214X_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_OUT) + +/* Each endpoint has somewhat different characteristics */ + +#define LPC214X_EPALLSET (0xffffffff) /* All endpoints */ +#define LPC214X_EPOUTSET (0x55555555) /* Even phy endpoint numbers are OUT EPs */ +#define LPC214X_EPINSET (0xaaaaaaaa) /* Odd endpoint numbers are IN EPs */ +#define LPC214X_EPCTRLSET (0x00000003) /* EP0 IN/OUT are control endpoints */ +#define LPC214X_EPINTRSET (0x0c30c30c) /* Interrupt endpoints */ +#define LPC214X_EPBULKSET (0xf0c30c30) /* Bulk endpoints */ +#define LPC214X_EPISOCSET (0x030c30c0) /* Isochronous endpoints */ +#define LPC214X_EPDBLBUFFER (0xf3cf3cf0) /* Double buffered endpoints */ + +#define LPC214X_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ +#define LPC214X_BULKMAXPACKET (64) /* Bulk endpoint max packet (8/16/32/64) */ +#define LPC214X_INTRMAXPACKET (64) /* Interrupt endpoint max packet (1 to 64) */ +#define LPC214X_ISOCMAXPACKET (512) /* Acutally 1..1023 */ + +/* EP0 status. EP0 transfers occur in a number of different contexts. A + * simple state machine is required to handle the various transfer complete + * interrupt responses. The following values are the various states: + */ + /*** INTERRUPT CAUSE ***/ +#define LPC214X_EP0REQUEST (0) /* Normal request handling */ +#define LPC214X_EP0STATUSIN (1) /* Status sent */ +#define LPC214X_EP0STATUSOUT (2) /* Status received */ +#define LPC214X_EP0SHORTWRITE (3) /* Short data sent with no request */ +#define LPC214X_EP0SHORTWRSENT (4) /* Short data write complete */ +#define LPC214X_EP0SETADDRESS (5) /* Set address received */ +#define LPC214X_EP0WRITEREQUEST (6) /* EP0 write request sent */ + +/* Request queue operations ****************************************************/ + +#define lpc214x_rqempty(ep) ((ep)->head == NULL) +#define lpc214x_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request make be retained in a list */ + +struct lpc214x_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct lpc214x_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct lpc214x_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct lpc214x_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* LPC214X-specific fields */ + + struct lpc214x_usbdev_s *dev; /* Reference to private driver data */ + struct lpc214x_req_s *head; /* Request list for this endpoint */ + struct lpc214x_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t halted:1; /* 1: Endpoint feature halted */ + uint8_t txbusy:1; /* 1: TX endpoint FIFO full */ + uint8_t txnullpkt:1; /* Null packet needed at end of transfer */ +}; + +/* This represents a DMA descriptor */ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +struct lpc214x_dmadesc_s +{ + uint32_t nextdesc; /* Address of the next DMA descripto in RAM */ + uint32_t config; /* Misc. bit encoded configuration information */ + uint32_t start; /* DMA start address */ + uint32_t status; /* Misc. bit encoded status inforamation */ +#ifdef CONFIG_USBDEV_ISOCHRONOUS + uint32_t size; /* Isochronous packet size address */ +#endif + uint8_t buffer[USB_DDSIZE-USB_DDESCSIZE]; +}; +#endif + +/* This structure retains the state of the USB device controller */ + +struct lpc214x_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structlpc214x_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* LPC214X-specific fields */ + + uint8_t devstatus; /* Last response to device status command */ + uint8_t ep0state; /* State of certain EP0 operations */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t rxpending:1; /* 1: RX pending */ + uint32_t softprio; /* Bitset of high priority interrupts */ + uint32_t epavail; /* Bitset of available endpoints */ +#ifdef CONFIG_LPC214X_USBDEV_FRAME_INTERRUPT + uint32_t sof; /* Last start-of-frame */ +#endif + + /* Allocated DMA descriptor */ + +#ifdef CONFIG_LPC214X_USBDEV_DMA + struct lpc214x_dmadesc_s *dmadesc; +#endif + + /* The endpoint list */ + + struct lpc214x_ep_s eplist[LPC214X_NPHYSENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_LPC214X_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc214x_getreg(uint32_t addr); +static void lpc214x_putreg(uint32_t val, uint32_t addr); +#else +# define lpc214x_getreg(addr) getreg32(addr) +# define lpc214x_putreg(val,addr) putreg32(val,addr) +#endif + +/* Command operations **********************************************************/ + +static uint32_t lpc214x_usbcmd(uint16_t cmd, uint8_t data); + +/* Request queue operations ****************************************************/ + +static FAR struct lpc214x_req_s *lpc214x_rqdequeue(FAR struct lpc214x_ep_s *privep); +static void lpc214x_rqenqueue(FAR struct lpc214x_ep_s *privep, + FAR struct lpc214x_req_s *req); + +/* Low level data transfers and request operations *****************************/ + +static void lpc214x_epwrite(uint8_t epphy, const uint8_t *data, uint32_t nbytes); +static int lpc214x_epread(uint8_t epphy, uint8_t *data, uint32_t nbytes); +static inline void lpc214x_abortrequest(struct lpc214x_ep_s *privep, + struct lpc214x_req_s *privreq, int16_t result); +static void lpc214x_reqcomplete(struct lpc214x_ep_s *privep, int16_t result); +static int lpc214x_wrrequest(struct lpc214x_ep_s *privep); +static int lpc214x_rdrequest(struct lpc214x_ep_s *privep); +static void lpc214x_cancelrequests(struct lpc214x_ep_s *privep); + +/* Interrupt handling **********************************************************/ + +static struct lpc214x_ep_s *lpc214x_epfindbyaddr(struct lpc214x_usbdev_s *priv, + uint16_t eplog); +static void lpc214x_eprealize(struct lpc214x_ep_s *privep, bool prio, + uint32_t packetsize); +static uint8_t lpc214x_epclrinterrupt(uint8_t epphy); +static inline void lpc214x_ep0configure(struct lpc214x_usbdev_s *priv); +#ifdef CONFIG_LPC214X_USBDEV_DMA +static inline void lpc214x_dmareset(uint32_t enable); +#endif +static void lpc214x_usbreset(struct lpc214x_usbdev_s *priv); +static void lpc214x_dispatchrequest(struct lpc214x_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv); +static inline void lpc214x_ep0dataoutinterrupt(struct lpc214x_usbdev_s *priv); +static inline void lpc214x_ep0dataininterrupt(struct lpc214x_usbdev_s *priv); +static int lpc214x_usbinterrupt(int irq, FAR void *context); + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static int lpc214x_dmasetup(struct lpc214x_usbdev_s *priv, uint8_t epphy, + uint32_t epmaxsize, uint32_t nbytes, uint32_t *isocpacket, + bool isochronous); +static void lpc214x_dmarestart(uint8_t epphy, uint32_t descndx); +static void lpc214x_dmadisable(uint8_t epphy); +#endif /* CONFIG_LPC214X_USBDEV_DMA */ + +/* Endpoint operations *********************************************************/ + +static int lpc214x_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int lpc214x_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *lpc214x_epallocreq(FAR struct usbdev_ep_s *ep); +static void lpc214x_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static FAR void *lpc214x_epallocbuffer(FAR struct usbdev_ep_s *ep, + uint16_t nbytes); +static void lpc214x_epfreebuffer(FAR struct usbdev_ep_s *ep, void *buf); +#endif +static int lpc214x_epsubmit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc214x_epcancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc214x_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations ********************************************/ + +static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void lpc214x_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int lpc214x_getframe(struct usbdev_s *dev); +static int lpc214x_wakeup(struct usbdev_s *dev); +static int lpc214x_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int lpc214x_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct lpc214x_usbdev_s g_usbdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = lpc214x_epconfigure, + .disable = lpc214x_epdisable, + .allocreq = lpc214x_epallocreq, + .freereq = lpc214x_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = lpc214x_epallocbuffer, + .freebuffer = lpc214x_epfreebuffer, +#endif + .submit = lpc214x_epsubmit, + .cancel = lpc214x_epcancel, + .stall = lpc214x_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = lcp214x_allocep, + .freeep = lpc214x_freeep, + .getframe = lpc214x_getframe, + .wakeup = lpc214x_wakeup, + .selfpowered = lpc214x_selfpowered, + .pullup = lpc214x_pullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc214x_getreg + * + * Description: + * Get the contents of an LPC214x register + * + ****************************************************************************/ + +#if defined(CONFIG_LPC214X_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc214x_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc214x_putreg + * + * Description: + * Set the contents of an LPC214x register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_LPC214X_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void lpc214x_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc214x_usbcmd + * + * Description: + * Transmit commands to the USB engine + * + ****************************************************************************/ + +static uint32_t lpc214x_usbcmd(uint16_t cmd, uint8_t data) +{ + irqstate_t flags; + uint32_t tmp = 0; + + /* Disable interrupt and clear CDFULL and CCEMPTY interrupt status */ + + flags = enter_critical_section(); + lpc214x_putreg(USBDEV_DEVINT_CDFULL | USBDEV_DEVINT_CCEMTY, + LPC214X_USBDEV_DEVINTCLR); + + /* Load command + WR in command code register */ + + lpc214x_putreg(((cmd & 0xff) << 16) + CMD_USB_CMDWR, LPC214X_USBDEV_CMDCODE); + + /* Wait until the command register is empty (CCEMPTY != 0, command is accepted) */ + + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CCEMTY) == 0); + + /* Clear command register empty (CCEMPTY) interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_CCEMTY, LPC214X_USBDEV_DEVINTCLR); + + /* Determine next phase of the command */ + + switch (cmd) + { + /* Write operations (1 byte of data) */ + + case CMD_USB_DEV_SETADDRESS: + case CMD_USB_DEV_CONFIG: + case CMD_USB_DEV_SETMODE: + case CMD_USB_DEV_SETSTATUS: + { + /* Send data + WR and wait for CCEMPTY */ + + lpc214x_putreg((data << 16) + CMD_USB_DATAWR, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CCEMTY) == 0); + } + break; + + /* 16 bit read operations */ + + case CMD_USB_DEV_READFRAMENO: + case CMD_USB_DEV_READTESTREG: + { + /* Send command code + RD and wait for CDFULL */ + + lpc214x_putreg((cmd << 16) + CMD_USB_DATARD, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CDFULL) == 0); + + /* Clear CDFULL and read LS data */ + + lpc214x_putreg(USBDEV_DEVINT_CDFULL, LPC214X_USBDEV_DEVINTCLR); + tmp = lpc214x_getreg(LPC214X_USBDEV_CMDDATA); + + /* Send command code + RD and wait for CDFULL */ + + lpc214x_putreg((cmd << 16) + CMD_USB_DATARD, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CDFULL) == 0); + + /* Read MS data */ + + tmp |= lpc214x_getreg(LPC214X_USBDEV_CMDDATA) << 8; + } + break; + + /* 8-bit read operations */ + + case CMD_USB_DEV_GETSTATUS: + case CMD_USB_DEV_GETERRORCODE: + case CMD_USB_DEV_READERRORSTATUS: + case CMD_USB_EP_CLRBUFFER: + { + /* Send command code + RD and wait for CDFULL */ + + lpc214x_putreg((cmd << 16) + CMD_USB_DATARD, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CDFULL) == 0); + + /* Read data */ + + tmp = lpc214x_getreg(LPC214X_USBDEV_CMDDATA); + } + break; + + /* No data transfer */ + + case CMD_USB_EP_VALIDATEBUFFER: + break; + + default: + switch (cmd & 0x1e0) + { + case CMD_USB_EP_SELECT: + case CMD_USB_EP_SELECTCLEAR: + { + /* Send command code + RD and wait for CDFULL */ + + lpc214x_putreg((cmd << 16) + CMD_USB_DATARD, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CDFULL) == 0); + + /* Read data */ + + tmp = lpc214x_getreg(LPC214X_USBDEV_CMDDATA); + } + break; + + case CMD_USB_EP_SETSTATUS: + { + /* Send data + RD and wait for CCEMPTY */ + + lpc214x_putreg((data << 16) + CMD_USB_DATAWR, LPC214X_USBDEV_CMDCODE); + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CCEMTY) == 0); + } + break; + + default: + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDCMD), 0); + break; + } + break; + } + + /* Restore the interrupt flags */ + + leave_critical_section(flags); + return tmp; +} + +/**************************************************************************** + * Name: lpc214x_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct lpc214x_req_s *lpc214x_rqdequeue(FAR struct lpc214x_ep_s *privep) +{ + FAR struct lpc214x_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc214x_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static void lpc214x_rqenqueue(FAR struct lpc214x_ep_s *privep, + FAR struct lpc214x_req_s *req) +{ + req->flink = NULL; + if (!privep->head) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } +} + +/**************************************************************************** + * Name: lpc214x_epwrite + * + * Description: + * Endpoint write (IN) + * + ****************************************************************************/ + +static void lpc214x_epwrite(uint8_t epphy, const uint8_t *data, uint32_t nbytes) +{ + uint32_t value; + bool aligned = (((uint32_t)data & 3) == 0); + + /* Set the write enable bit for this physical EP address. Bits 2-5 are + * the logical endpoint number (0-15) + */ + + lpc214x_putreg(((epphy << 1) & LPC214X_USBCTRL_EPMASK) | LPC214X_USBCTRL_WREN, + LPC214X_USBDEV_CTRL); + + /* Set the transmit packet length (nbytes must be less than 2048) */ + + lpc214x_putreg(nbytes, LPC214X_USBDEV_TXPLEN); + + /* Transfer the packet data */ + + do + { + /* Zero length packets are a special case */ + + if (nbytes) + { + if (aligned) + { + value = *(uint32_t *)data; + } + else + { + value = (uint32_t)data[0] | ((uint32_t)data[1] << 8) | + ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24); + } + + lpc214x_putreg(value, LPC214X_USBDEV_TXDATA); + data += 4; + } + else + { + /* Zero length packet */ + + lpc214x_putreg(0, LPC214X_USBDEV_TXDATA); + } + } + while ((lpc214x_getreg(LPC214X_USBDEV_CTRL) & LPC214X_USBCTRL_WREN) != 0); + + /* Done */ + + lpc214x_putreg(0, LPC214X_USBDEV_CTRL); + (void)lpc214x_usbcmd(CMD_USB_EP_SELECT | epphy, 0); + (void)lpc214x_usbcmd(CMD_USB_EP_VALIDATEBUFFER, 0); +} + +/**************************************************************************** + * Name: lpc214x_epread + * + * Description: + * Endpoint read (OUT) + * + ****************************************************************************/ + +static int lpc214x_epread(uint8_t epphy, uint8_t *data, uint32_t nbytes) +{ + uint32_t pktlen; + uint32_t result; + uint32_t value; + uint8_t aligned = 0; + + /* If data is NULL, then we are being asked to read but discard the data. + * For most cases, the resulting buffer will be aligned and we will be + * able to do faster 32-bit transfers. + */ + + if (data) + { + if (((uint32_t)data & 3) == 0) + { + aligned = 1; + } + else + { + aligned = 2; + } + } + + /* Set the read enable bit for this physical EP address. Bits 2-5 are + * the logical endpoint number (0-15). + */ + + lpc214x_putreg(((epphy << 1) & LPC214X_USBCTRL_EPMASK) | LPC214X_USBCTRL_RDEN, + LPC214X_USBDEV_CTRL); + + /* Wait for packet buffer ready for reading */ + + while ((lpc214x_getreg(LPC214X_USBDEV_RXPLEN) & USBDEV_RXPLEN_PKTRDY) == 0); + + /* Get the number of bytes of data to be read */ + + pktlen = lpc214x_getreg(LPC214X_USBDEV_RXPLEN) & USBDEV_RXPLEN_PKTLENGTH; + + /* Read data from input buffer while read data is valid (DV) */ + + while ((lpc214x_getreg(LPC214X_USBDEV_RXPLEN) & USBDEV_RXPLEN_DV) != 0) + { + value = lpc214x_getreg(LPC214X_USBDEV_RXDATA); + if (aligned == 1) + { + *(uint32_t *)data = value; + data += 4; + } + else if (aligned == 2) + { + *data++ = (uint8_t)value; + *data++ = (uint8_t)(value >> 8); + *data++ = (uint8_t)(value >> 16); + *data++ = (uint8_t)(value >> 24); + } + } + + /* Done */ + + lpc214x_putreg(0, LPC214X_USBDEV_CTRL); + (void)lpc214x_usbcmd(CMD_USB_EP_SELECT | epphy, 0); + result = lpc214x_usbcmd(CMD_USB_EP_CLRBUFFER, 0); + + /* The packet overrun bit in the clear buffer response is applicable only + * on EP0 transfers. If set it means that the recevied packet was overwritten + * by a later setup packet. + */ + + if (epphy == LPC214X_EP0_OUT && (result & CMD_USB_CLRBUFFER_PO) != 0) + { + /* Pass this information in bit 31 */ + + pktlen |= LPC214X_READOVERRUN_BIT; + } + return pktlen; +} + +/**************************************************************************** + * Name: lpc214x_abortrequest + * + * Description: + * Discard a request + * + ****************************************************************************/ + +static inline void lpc214x_abortrequest(struct lpc214x_ep_s *privep, + struct lpc214x_req_s *privreq, + int16_t result) +{ + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_REQABORTED), (uint16_t)privep->epphy); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: lpc214x_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void lpc214x_reqcomplete(struct lpc214x_ep_s *privep, int16_t result) +{ + struct lpc214x_req_s *privreq; + int stalled = privep->stalled; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = lpc214x_rqdequeue(privep); + leave_critical_section(flags); + + if (privreq) + { + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + if (privep->epphy == LPC214X_EP0_IN) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; + } +} + +/**************************************************************************** + * Name: lpc214x_wrrequest + * + * Description: + * Send from the next queued write request + * + ****************************************************************************/ + +static int lpc214x_wrrequest(struct lpc214x_ep_s *privep) +{ + struct lpc214x_req_s *privreq; + uint8_t *buf; + int nbytes; + int bytesleft; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc214x_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPINQEMPTY), 0); + return OK; + } + + ullvdbg("epphy=%d req=%p: len=%d xfrd=%d nullpkt=%d\n", + privep->epphy, privreq, privreq->req.len, privreq->req.xfrd, privep->txnullpkt); + + /* Ignore any attempt to send a zero length packet on anything but EP0IN */ + + if (privreq->req.len == 0) + { + if (privep->epphy == LPC214X_EP0_IN) + { + lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EPINNULLPACKET), 0); + } + + /* In any event, the request is complete */ + + lpc214x_reqcomplete(privep, OK); + return OK; + } + + /* Otherwise send the data in the packet (in the DMA on case, we + * may be resuming transfer already in progress. + */ +#warning REVISIT... If the EP supports double buffering, then we can do better + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + + /* Send the next packet if (1) there are more bytes to be sent, or + * (2) the last packet sent was exactly maxpacketsize (bytesleft == 0) + */ + + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + if (bytesleft > 0 || privep->txnullpkt) + { + /* Indicate that there is data in the TX FIFO. This will be cleared + * when the EPIN interrupt is received + */ + + privep->txbusy = 1; + + /* Try to send maxpacketsize -- unless we don't have that many + * bytes to send. + */ + + privep->txnullpkt = 0; + if (bytesleft > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + else + { + nbytes = bytesleft; + if ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + privep->txnullpkt = (bytesleft == privep->ep.maxpacket); + } + } + + /* Send the largest number of bytes that we can in this packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + lpc214x_epwrite(privep->epphy, buf, nbytes); + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* If all of the bytes were sent (including any final null packet) + * then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->txnullpkt) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + privep->txnullpkt = 0; + lpc214x_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc214x_rdrequest + * + * Description: + * Receive to the next queued read request + * + ****************************************************************************/ + +static int lpc214x_rdrequest(struct lpc214x_ep_s *privep) +{ + struct lpc214x_req_s *privreq; + uint8_t *buf; + int nbytesread; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc214x_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPOUTQEMPTY), 0); + return OK; + } + + ullvdbg("len=%d xfrd=%d nullpkt=%d\n", + privreq->req.len, privreq->req.xfrd, privep->txnullpkt); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EPOUTNULLPACKET), 0); + lpc214x_reqcomplete(privep, OK); + return OK; + } + + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + + /* Receive the next packet */ + + buf = privreq->req.buf + privreq->req.xfrd; + nbytesread = lpc214x_epread(privep->epphy, buf, privep->ep.maxpacket); + if (nbytesread < 0) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EPREAD), nbytesread); + return ERROR; + } + + /* If the receive buffer is full or if the last packet was not full + * then we are finished with the transfer. + */ + + privreq->req.xfrd += nbytesread; + if (privreq->req.xfrd >= privreq->req.len || nbytesread < privep->ep.maxpacket) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + lpc214x_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc214x_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void lpc214x_cancelrequests(struct lpc214x_ep_s *privep) +{ + while (!lpc214x_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (lpc214x_rqpeek(privep))->req.xfrd); + lpc214x_reqcomplete(privep, -ESHUTDOWN); + } +} + +/**************************************************************************** + * Name: lpc214x_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct lpc214x_ep_s *lpc214x_epfindbyaddr(struct lpc214x_usbdev_s *priv, + uint16_t eplog) +{ + struct lpc214x_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < LPC214X_NPHYSENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: lpc214x_eprealize + * + * Description: + * Enable or disable an endpoint + * + ****************************************************************************/ + +static void lpc214x_eprealize(struct lpc214x_ep_s *privep, bool prio, uint32_t packetsize) +{ + struct lpc214x_usbdev_s *priv = privep->dev; + uint32_t mask; + uint32_t reg; + + /* Initialize endpoint software priority */ + + mask = 1 << privep->epphy; + if (prio) + { + priv->softprio = priv->softprio | mask; + } + else + { + priv->softprio = priv->softprio & ~mask; + } + + /* Clear realize interrupt bit */ + + lpc214x_putreg(USBDEV_DEVINT_EPRLZED, LPC214X_USBDEV_DEVINTCLR); + + /* Realize the endpoint */ + + reg = lpc214x_getreg(LPC214X_USBDEV_REEP); + reg |= (1 << privep->epphy); + lpc214x_putreg(reg, LPC214X_USBDEV_REEP); + + /* Set endpoint maximum packet size */ + + lpc214x_putreg(privep->epphy, LPC214X_USBDEV_EPIND); + lpc214x_putreg(packetsize, LPC214X_USBDEV_MAXPSIZE); + + /* Wait for Realize complete */ + + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_EPRLZED) == 0); + + /* Clear realize interrupt bit */ + + lpc214x_putreg(USBDEV_DEVINT_EPRLZED, LPC214X_USBDEV_DEVINTCLR); +} + +/**************************************************************************** + * Name: lpc214x_epclrinterrupt + * + * Description: + * Clear the EP interrupt flag and return the current EP status + * + ****************************************************************************/ + +static uint8_t lpc214x_epclrinterrupt(uint8_t epphy) +{ + /* Clear the endpoint interrupt */ + + lpc214x_putreg(1 << epphy, LPC214X_USBDEV_EPINTCLR); + + /* Wait for data in the command data register */ + + while ((lpc214x_getreg(LPC214X_USBDEV_DEVINTST) & USBDEV_DEVINT_CDFULL) == 0); + + /* Return the value of the command data register */ + + return lpc214x_getreg(LPC214X_USBDEV_CMDDATA); +} + +/**************************************************************************** + * Name: lpc214x_ep0configure + * + * Description: + * Configure endpoint 0 + * + ****************************************************************************/ + +static inline void lpc214x_ep0configure(struct lpc214x_usbdev_s *priv) +{ + uint32_t inten; + + /* EndPoint 0 initialization */ + + lpc214x_eprealize(&priv->eplist[LPC214X_CTRLEP_OUT], 0, CONFIG_USBDEV_EP0_MAXSIZE); + lpc214x_eprealize(&priv->eplist[LPC214X_CTRLEP_IN], 1, CONFIG_USBDEV_EP0_MAXSIZE); + + /* Enable EP0 interrupts (not DMA) */ + + inten = lpc214x_getreg(LPC214X_USBDEV_EPINTEN); + inten |= 3; /* EP0 Rx and Tx */ + lpc214x_putreg(inten, LPC214X_USBDEV_EPINTEN); +} + +/**************************************************************************** + * Name: lpc214x_dmareset + * + * Description: Reset USB DMA + * + ****************************************************************************/ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static inline void lpc214x_dmareset(uint32_t enable) +{ + int i; + + /* Disable All DMA interrupts */ + + lpc214x_putreg(0, LPC214X_USBDEV_DMAINTEN); + + /* DMA Disable */ + + lpc214x_putreg(0xffffffff, LPC214X_USBDEV_EPDMADIS); + + /* DMA Request clear */ + + putreq32(0xffffffff, LPC214X_USBDEV_DMARCLR); + + /* End of Transfer Interrupt Clear */ + + putreq32(0xffffffff, LPC214X_USBDEV_EOTINTCLR); + + /* New DD Request Interrupt Clear */ + + putreq32(0xffffffff, LPC214X_USBDEV_NDDRINTCLR); + + /* System Error Interrupt Clear */ + + putreq32(0xffffffff, LPC214X_USBDEV_SYSERRINTCLR); + + /* Nullify all pointers in the UDCA */ + + for (i = 0; i < LPC214X_NPHYSENDPOINTS; ++i) + { + USB_UDCA[i] = NULL; + } + + /* Set USB UDCA Head register */ + + lpc214x_putreg((uint32_t)USB_UDCA, LPC214X_USBDEV_UDCAH); + + /* Invalidate all DMA descriptors */ + + for (i = 0; i < CONFIG_LPC214X_USBDEV_NDMADESCRIPTORS; ++i) + { + memset(&USB_DDESC[i], 0, USB_DDESCSIZE); + } + + /* Enable DMA interrupts */ + + lpc214x_putreg(enable, LPC214X_USBDEV_DMAINTEN); +} +#endif + +/**************************************************************************** + * Name: lpc214x_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc214x_usbreset(struct lpc214x_usbdev_s *priv) +{ + int epphy; + + /* Disable all endpoint interrupts */ + + lpc214x_putreg(0, LPC214X_USBDEV_EPINTEN); + + /* Frame is Hp interrupt */ + + lpc214x_putreg(1, LPC214X_USBDEV_DEVINTPRI); + + /* Clear all pending interrupts */ + + lpc214x_putreg(0xffffffff, LPC214X_USBDEV_EPINTCLR); + lpc214x_putreg(0xffffffff, LPC214X_USBDEV_DEVINTCLR); + + /* Periperhal address is needed */ + + priv->paddrset = 0; + + /* Reset endpoints */ + + for (epphy = 0; epphy < LPC214X_NPHYSENDPOINTS; epphy++) + { + struct lpc214x_ep_s *privep = &priv->eplist[epphy]; + + lpc214x_cancelrequests(privep); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Endpoints not yet configured */ + + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 0); + + /* EndPoint 0 initialization */ + + lpc214x_ep0configure(priv); + + /* Enable End_of_Transfer_Interrupt and System_Error_Interrupt USB DMA + * interrupts + */ + +#ifdef CONFIG_LPC214X_USBDEV_DMA + lpc214x_dmareset(CONFIG_LPC214X_USBDEV_DMAINTMASK); +#endif + + /* Enable Device interrupts */ + + lpc214x_putreg(USB_SLOW_INT | USB_DEVSTATUS_INT | USB_FAST_INT | + USB_FRAME_INT | USB_ERROR_INT, + LPC214X_USBDEV_DEVINTEN); +} + +/**************************************************************************** + * Name: lpc214x_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static void lpc214x_dispatchrequest(struct lpc214x_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret; + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = 1; + } + } +} + +/**************************************************************************** + * Name: lpc214x_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv) +{ + struct lpc214x_ep_s *ep0 = &priv->eplist[LPC214X_EP0_OUT]; + struct lpc214x_ep_s *privep; + struct lpc214x_req_s *privreq = lpc214x_rqpeek(ep0); + struct usb_ctrlreq_s ctrl; + uint16_t value; + uint16_t index; + uint16_t len; + uint8_t response[2]; + int ret; + + /* Starting a control request? */ + + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 1); + } + + /* Terminate any pending requests */ + + while (!lpc214x_rqempty(ep0)) + { + int16_t result = OK; + if (privreq->req.xfrd != privreq->req.len) + { + result = -EPROTO; + } + + usbtrace(TRACE_COMPLETE(ep0->epphy), privreq->req.xfrd); + lpc214x_reqcomplete(ep0, result); + } + + /* Assume NOT stalled */ + + ep0->stalled = 0; + priv->stalled = 0; + + /* Read EP0 data */ + + ret = lpc214x_epread(LPC214X_EP0_OUT, (uint8_t *)&ctrl, USB_SIZEOF_CTRLREQ); + if (ret <= 0) + { + return; + } + + /* And extract the little-endian 16-bit values to host order */ + + value = GETUINT16(ctrl.value); + index = GETUINT16(ctrl.index); + len = GETUINT16(ctrl.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl.type, ctrl.req, value, index, len); + + /* Dispatch any non-standard requests */ + + if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + lpc214x_dispatchrequest(priv, &ctrl); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETSTATUS), 0); + if (!priv->paddrset || len != 2 || + (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) + { + priv->stalled = 1; + } + else + { + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPGETSTATUS), 0); + privep = lpc214x_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = 1; + } + else + { + if ((lpc214x_usbcmd(CMD_USB_EP_SELECT | privep->epphy, 0) & CMD_USB_EPSELECT_ST) != 0) + { + response[0] = 1; /* Stalled */ + } + else + { + response[0] = 0; /* Not stalled */ + } + response[1] = 0; + lpc214x_epwrite(LPC214X_EP0_IN, response, 2); + priv->ep0state = LPC214X_EP0SHORTWRITE; + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + response[1] = 0; + lpc214x_epwrite(LPC214X_EP0_IN, response, 2); + priv->ep0state = LPC214X_EP0SHORTWRITE; + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_IFGETSTATUS), 0); + response[0] = 0; + response[1] = 0; + lpc214x_epwrite(LPC214X_EP0_IN, response, 2); + priv->ep0state = LPC214X_EP0SHORTWRITE; + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADGETSTATUS), 0); + priv->stalled = 1; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_CLEARFEATURE), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc214x_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc214x_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 0; + (void)lpc214x_epstall(&privep->ep, true); + lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); + priv->ep0state = LPC214X_EP0STATUSIN; + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETFEATURE), 0); + if (((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value == USB_FEATURE_TESTMODE) + { + ullvdbg("test mode: %d\n", index); + } + else if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc214x_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc214x_epfindbyaddr(priv, index)) != NULL) + { + privep->halted = 1; + lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); + priv->ep0state = LPC214X_EP0STATUSIN; + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADSETFEATURE), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0SETUPSETADDRESS), value); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0 && value < 128) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + priv->paddr = ctrl.value[0]; + + /* Note that if we send the SETADDRESS command twice, that will force the + * address change. Otherwise, the hardware will automatically set the + * address at the end of the status phase. + */ + + lpc214x_usbcmd(CMD_USB_DEV_SETADDRESS, CMD_USB_SETADDRESS_DEVEN | priv->paddr); + + /* Send a NULL packet. The status phase completes when the null packet has + * been sent successfully. + */ + + lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); + priv->ep0state = LPC214X_EP0SETADDRESS; + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADSETADDRESS), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETSETDESC), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + lpc214x_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADGETSETDESC), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETCONFIG), 0); + if (priv->paddrset && (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value == 0 && index == 0 && len == 1) + { + lpc214x_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADGETCONFIG), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETCONFIG), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0) + { + lpc214x_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADSETCONFIG), 0); + priv->stalled = 1; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETSETIF), 0); + lpc214x_dispatchrequest(priv, &ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = 1; + } + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + ep0 = &priv->eplist[LPC214X_EP0_OUT]; + lpc214x_epstall(&ep0->ep, false); + ep0 = &priv->eplist[LPC214X_EP0_IN]; + lpc214x_epstall(&ep0->ep, false); + } +} + +/**************************************************************************** + * Name: lpc214x_ep0dataoutinterrupt + * + * Description: + * USB Ctrl EP Data OUT Event. This is logically part of the USB interrupt + * handler. Each non-isochronous OUT endpoint gives an interrupt when they + * receive a packet without error. + * + ****************************************************************************/ + +static inline void lpc214x_ep0dataoutinterrupt(struct lpc214x_usbdev_s *priv) +{ + struct lpc214x_ep_s *ep0; + uint32_t pktlen; + + /* Copy new setup packet into setup buffer */ + + switch (priv->ep0state) + { + case LPC214X_EP0SHORTWRITE: + { + priv->ep0state = LPC214X_EP0STATUSOUT; + pktlen = lpc214x_epread(LPC214X_EP0_OUT, NULL, CONFIG_USBDEV_EP0_MAXSIZE); + if (LPC214X_READOVERRUN(pktlen)) + { + lpc214x_ep0setup(priv); + } + } + break; + + case LPC214X_EP0SHORTWRSENT: + { + priv->ep0state = LPC214X_EP0REQUEST; + pktlen = lpc214x_epread(LPC214X_EP0_OUT, NULL, CONFIG_USBDEV_EP0_MAXSIZE); + if (LPC214X_READOVERRUN(pktlen)) + { + lpc214x_ep0setup(priv); + } + } + break; + + case LPC214X_EP0REQUEST: + { + /* Process the next request action (if any) */ + + lpc214x_rdrequest(&priv->eplist[LPC214X_EP0_OUT]); + } + break; + + default: + priv->stalled = 1; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EP0OUTSTALLED), priv->ep0state); + ep0 = &priv->eplist[LPC214X_EP0_OUT]; + lpc214x_epstall(&ep0->ep, false); + ep0 = &priv->eplist[LPC214X_EP0_IN]; + lpc214x_epstall(&ep0->ep, false); + } + return; +} + +/**************************************************************************** + * Name: lpc214x_ep0dataininterrupt + * + * Description: + * USB Ctrl EP Data IN Event. This is logically part of the USB interrupt + * handler. All non-isochronous IN endpoints give this interrupt when a + * packet is successfully transmitted (OR a NAK handshake is sent on the bus + * provided that the interrupt on NAK feature is enabled). + * + ****************************************************************************/ + +static inline void lpc214x_ep0dataininterrupt(struct lpc214x_usbdev_s *priv) +{ + struct lpc214x_ep_s *ep0; + + switch (priv->ep0state) + { + case LPC214X_EP0STATUSOUT: + case LPC214X_EP0STATUSIN: + priv->ep0state = LPC214X_EP0REQUEST; + break; + + case LPC214X_EP0SHORTWRITE: + priv->ep0state = LPC214X_EP0SHORTWRSENT; + break; + + case LPC214X_EP0SETADDRESS: + { + /* If the address was set to a non-zero value, then thiscompletes the + * default phase, and begins the address phase (still not fully configured) + */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr); + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 0); + if (priv->paddr) + { + priv->paddrset = 1; + priv->ep0state = LPC214X_EP0REQUEST; + } + } + break; + + case LPC214X_EP0REQUEST: + { + /* Process the next request action (if any) */ + + ep0 = &priv->eplist[LPC214X_EP0_IN]; + ep0->txbusy = 0; + lpc214x_wrrequest(ep0); + } + break; + + default: + priv->stalled = 1; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EP0INSTALLED), priv->ep0state); + ep0 = &priv->eplist[LPC214X_EP0_OUT]; + lpc214x_epstall(&ep0->ep, false); + ep0 = &priv->eplist[LPC214X_EP0_IN]; + lpc214x_epstall(&ep0->ep, false); + } +} + +/**************************************************************************** + * Name: lpc214x_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int lpc214x_usbinterrupt(int irq, FAR void *context) +{ + struct lpc214x_usbdev_s *priv = &g_usbdev; + struct lpc214x_ep_s *privep ; + + uint32_t devintstatus; /* Sampled state of the device interrupt status register */ + uint32_t epintstatus; /* Sampled state of the endpoint interrupt status register */ +#ifdef CONFIG_LPC214X_USBDEV_DMA + uint32_t dmaintstatus; /* Sampled state of dma interrupt status register */ +#endif + uint32_t softprio; /* Current priority interrupt bitset */ + uint32_t pending; /* Pending subset of priority interrupt bitset */ + uint8_t epphy; /* Physical endpoint number being processed */ + int i; + + usbtrace(TRACE_INTENTRY(LPC214X_TRACEINTID_USB), 0); + + /* Read the device interrupt status register */ + + devintstatus = lpc214x_getreg(LPC214X_USBDEV_DEVINTST); + +#ifdef CONFIG_LPC214X_USBDEV_DMA + /* Check for low priority and high priority (non-DMA) interrupts */ + + if ((lpc214x_getreg(LPC214X_USBDEV_INTST) & (USBDEV_INTST_REQLP | USBDEV_INTST_REQHP)) != 0) + { +#endif +#ifdef CONFIG_LPC214X_USBDEV_EPFAST_INTERRUPT + /* Fast EP interrupt */ + + if ((devintstatus & USBDEV_DEVINT_EPFAST) != 0) + { + /* Clear Fast EP interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_EPFAST, LPC214X_USBDEV_DEVINTCLR); + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPFAST), 0); + + /* Do what? */ + } + +#endif + +#ifdef CONFIG_DEBUG + /* USB engine error interrupt */ + + if ((devintstatus & USBDEV_DEVINT_EPRINT)) + { + uint8_t errcode; + + /* Clear the error interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_EPRINT, LPC214X_USBDEV_DEVINTCLR); + + /* And show what error occurred */ + + errcode = (uint8_t)lpc214x_usbcmd(CMD_USB_DEV_READERRORSTATUS, 0) & 0x0f; + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPRINT), (uint16_t)errcode); + UNUSED(errcode); + } +#endif + +#ifdef CONFIG_LPC214X_USBDEV_FRAME_INTERRUPT + /* Frame interrupt */ + + if ((devintstatus & USBDEV_DEVINT_FRAME) != 0) + { + /* Clear the frame interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_FRAME, LPC214X_USBDEV_DEVINTCLR); + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_FRAME), 0); + + /* Then read the start of frame value */ + + priv->sof = (uint16_t)lpc214x_usbcmd(CMD_USB_DEV_READFRAMENO, 0); + } +#endif + + /* Device Status interrupt */ + + if ((devintstatus & USBDEV_DEVINT_DEVSTAT) != 0) + { + /* Clear Device status interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_DEVSTAT, LPC214X_USBDEV_DEVINTCLR); + + /* Get device status */ + + g_usbdev.devstatus = (uint8_t)lpc214x_usbcmd(CMD_USB_DEV_GETSTATUS, 0); + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DEVSTAT), (uint16_t)g_usbdev.devstatus); + + /* Device connection status */ + + if (DEVSTATUS_CONNCHG(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_CONNECTCHG), + (uint16_t)g_usbdev.devstatus); + if (DEVSTATUS_CONNECT(g_usbdev.devstatus)) + { + /* Host is connected */ + + if (!priv->attached) + { + /* We have a transition from unattached to attached */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_CONNECTED), + (uint16_t)g_usbdev.devstatus); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 0); + priv->attached = 1; + } + } + + /* Otherwise the host is not attached */ + + else if (priv->attached) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DISCONNECTED), + (uint16_t)g_usbdev.devstatus); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 0); + priv->attached = 0; + priv->paddrset = 0; + } + } + + /* Device suspend status */ + + if (DEVSTATUS_SUSPCHG(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SUSPENDCHG), + (uint16_t)g_usbdev.devstatus); + + /* Inform the Class driver of the change */ + + if (priv->driver) + { + if (DEVSTATUS_SUSPEND(g_usbdev.devstatus)) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + else + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + } + + /* TODO: Perform power management operations here. */ + } + + /* Device reset */ + + if (DEVSTATUS_RESET(g_usbdev.devstatus)) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DEVRESET), + (uint16_t)g_usbdev.devstatus); + lpc214x_usbreset(priv); + } + } + + /* Slow EP interrupt */ + + if ((devintstatus & USBDEV_DEVINT_EPSLOW) != 0) + { + /* Clear Slow EP interrupt */ + + lpc214x_putreg(USBDEV_DEVINT_EPSLOW, LPC214X_USBDEV_DEVINTCLR); + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPSLOW), 0); + + do + { + /* Read the endpoint interrupt status register */ + + epintstatus = lpc214x_getreg(LPC214X_USBDEV_EPINTST); + + /* Loop twice: Process software high priority interrupts + * on the first pass and low priority interrupts on the + * second. + */ + + softprio = priv->softprio; + for (i = 0; i < 2; i++, softprio = ~softprio) + { + /* On the first time through the loop, pending will be + * the bitset of high priority pending interrupts; on the + * second time throught it will be the bitset of low + * priority interrupts. + */ + + pending = epintstatus & softprio; + + /* EP0 OUT interrupt indicated by bit0 == 1 */ + + if ((pending & 1) != 0) + { + /* Clear the endpoint interrupt */ + + uint32_t result = lpc214x_epclrinterrupt(LPC214X_CTRLEP_OUT); + if (result & USBDEV_EPSETUPPACKET) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0SETUP), (uint16_t)result); + lpc214x_ep0setup(priv); + } + else + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0OUT), priv->ep0state); + lpc214x_ep0dataoutinterrupt(priv); + } + break; + } + + /* EP0 IN interrupt indicated by bit1 == 1 */ + + if ((pending & 2) != 0) + { + /* Clear the endpoint interrupt */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0IN), priv->ep0state); + (void)lpc214x_epclrinterrupt(LPC214X_CTRLEP_IN); + lpc214x_ep0dataininterrupt(priv); + } + pending >>= 2; + + /* All other endpoints EP 1-31 */ + + for (epphy = 2; pending; epphy++, pending >>= 1) + { + /* Is the endpoint interrupt pending? */ + + if ((pending & 1) != 0) + { + /* Yes.. clear the endpoint interrupt */ + + (void)lpc214x_epclrinterrupt(epphy); + + /* Get the endpoint sructure corresponding to the physical + * endpoint number. + */ + + privep = &priv->eplist[epphy]; + + /* Check for complete on IN or OUT endpoint. Odd physical + * endpoint addresses are IN endpoints. + */ + + if ((epphy & 1) != 0) + { + /* IN: device-to-host */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPOUT), (uint16_t)epphy); + if (priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + priv->usbdev.speed = USB_SPEED_FULL; + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 1); + } + + /* Write host data from the current write request (if any) */ + + privep->txbusy = 0; + lpc214x_wrrequest(privep); + } + else + { + /* OUT: host-to-device */ + + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPIN), (uint16_t)epphy); + + /* Read host data into the current read request */ + + if (!lpc214x_rqempty(privep)) + { + lpc214x_rdrequest(privep); + } + else + { + ullvdbg("Pending data on OUT endpoint\n"); + priv->rxpending = 1; + } + } + } + } + } + } + while (epintstatus); + } +#ifdef CONFIG_LPC214X_USBDEV_DMA + } + + /* Check for DMA interrupts */ + + if ((lpc214x_getreg(LPC214X_USBDEV_INTST) & USBDEV_INTST_REQDMA) != 0) + { + /* First Software High priority and then low priority */ + + uint32_t tmp; + + /* Collect the DMA interrupt sources */ + + dmaintstatus = 0; + tmp = lpc214x_getreg(LPC214X_USBDEV_EOTINTST); + if (lpc214x_getreg(LPC214X_USBDEV_DMAINTEN) & 1) + { + dmaintstatus |= tmp; + } + lpc214x_putreg(tmp, LPC214X_USBDEV_EOTINTCLR); + + tmp = lpc214x_getreg(LPC214X_USBDEV_NDDRINTST); + if (lpc214x_getreg(LPC214X_USBDEV_DMAINTEN) & 2) + { + dmaintstatus |= tmp; + } + lpc214x_putreg(tmp, LPC214X_USBDEV_NDDRINTCLR); + + tmp = lpc214x_getreg(LPC214X_USBDEV_SYSERRINTST); + if (lpc214x_getreg(LPC214X_USBDEV_DMAINTEN) & 4) + { + dmaintstatus |= tmp; + } + lpc214x_putreg(tmp, LPC214X_USBDEV_SYSERRINTCLR); + + /* Loop twice: Process software high priority interrupts on the + * first pass and low priority interrupts on the second. + */ + + softprio = priv->softprio; + for (i = 0; i < 2; i++, softprio = ~softprio) + { + /* On the first time through the loop, pending will be + * the bitset of high priority pending interrupts; on the + * second time throught it will be the bitset of low + * priority interrupts. Note that EP0 IN and OUT are + * omitted. + */ + + pending = (dmaintstatus & softprio) >> 2; + for (epphy = 2; pending; epphy++, pending >>= 1) + { + if ((pending & 1) != 0) + { + usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPDMA), (uint16_t)epphy); +#warning DO WHAT? + } + } + } + } +#endif + usbtrace(TRACE_INTEXIT(LPC214X_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Name: lpc214x_dmasetup + * + * Description: + * Setup for DMA Transfer + * + ****************************************************************************/ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static int lpc214x_dmasetup(struct lpc214x_usbdev_s *priv, uint8_t epphy, + uint32_t epmaxsize, uint32_t nbytes, uint32_t *isocpacket, + bool isochronous); +{ + struct lpc214x_dmadesc_s *dmadesc = priv; + uint32_t reg; + +#ifdef CONFIG_DEBUG + if (!priv || epphy < 2) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Check if a DMA descriptor has been assigned. If not, than that indicates + * that we will have to do parallel I/O + */ + + if (!dmadesc) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_NODMADESC), 0); + return -EBUSY; + } + + /* Verify that the DMA descriptor is available */ + + if ((dmadesc->status & USB_DMADESC_STATUSMASK) == USB_DMADESC_BEINGSERVICED) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_DMABUSY), 0); + return -EBUSY; /* Shouldn't happen */ + } + + /* Init DMA Descriptor */ + + dmadesc->nexdesc = 0; + dmadesc->config = USB_DMADESC_MODENORMAL | + ((epmaxsize << USB_DMADESC_PKTSIZESHIFT) & USB_DMADESC_PKTSIZEMASK) | + ((nbytes << USB_DMADESC_BULENSHIFT) & USB_DMADESC_BUFLENMASK); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (isochronous) + { + dmadesc->config |= USB_DMADESC_ISCOEP; + } +#endif + + dmadesc->start = (uint32_t)&dmadesc->buffer; + dmadesc->status = 0; + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + dmadesc->size = (uint32_t)packet; +#endif + + /* Enable DMA transfer for this endpoint */ + + putreq32(1 << epphy, LPC214X_USBDEV_EPDMAEN); + + /* Check state of IN/OUT Ep buffer */ + + reg = lpc214x_usbcmd(CMD_USB_EP_SELECT | epphy, 0); + + if ((LPC214X_EPPHYIN(epphy) && (reg & 0x60) == 0) || + (LPC214X_EPPHYOUT(epphy) && (reg & 0x60) == 0x60)) + { + /* DMA should be "being serviced" */ + + if ((dmadesc->status & USB_DMADESC_STATUSMASK) != USB_DMADESC_BEINGSERVICED)) + { + /* Re-trigger the DMA Transfer */ + + putreq21(1 << epphy, LPC214X_USBDEV_DMARCLR); + putreq32(1 << epphy, LPC214X_USBDEV_EPDMAEN); + } + } + return OK; +} +#endif /* CONFIG_LPC214X_USBDEV_DMA */ + +/**************************************************************************** + * Name: lpc214x_dmarestart + * + * Description: + * Restart DMA Transfer + * + ****************************************************************************/ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static void lpc214x_dmarestart(uint8_t epphy, uint32_t descndx) +{ + uint32_t reg; + + /* Clear DMA descriptor status */ + + USB_DmaDesc[descndx].status = 0; + + /* Enable DMA transfer on the endpoint */ + + lpc214x_putreg(1 << epph, LPC214X_USBDEV_EPDMAEN); + + /* Check the state of IN/OUT EP buffer */ + + uint32_t reg = lpc214x_usbcmd(CMD_USB_EP_SELECT | epphy, 0); + if ((LPC214X_EPPHYIN(epphy) && (reg & 0x60) == 0) || + (LPC214X_EPPHYIN(epphy) && (reg & 0x60) == 0x60)) + { + /* Re-trigger the DMA Transfer */ + + putreq21(1 << epphy, LPC214X_USBDEV_DMARCLR); + putreq32(1 << epphy, LPC214X_USBDEV_EPDMAEN); + } +} +#endif /* CONFIG_LPC214X_USBDEV_DMA */ + +/**************************************************************************** + * Name: lpc214x_dmadisable + * + * Description: + * Disable DMA transfer for the EP + * + ****************************************************************************/ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static void lpc214x_dmadisable(uint8_t epphy) +{ + EPDMADIS = 1 << epphy; +} +#endif /* CONFIG_LPC214X_USBDEV_DMA */ + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc214x_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int lpc214x_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + uint32_t inten; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Realize the endpoint */ + + lpc214x_eprealize(privep, 1, GETUINT16(desc->mxpacketsize)); + + /* Enable and reset EP -- twice */ + + lpc214x_usbcmd(CMD_USB_EP_SETSTATUS | privep->epphy, 0); + lpc214x_usbcmd(CMD_USB_EP_SETSTATUS | privep->epphy, 0); + +#ifdef CONFIG_LPC214X_USBDEV_DMA + /* Enable DMA Ep interrupt (WO) */ + + lpc214x_putreg(1 << privep->epphy, LPC214X_USBDEV_EPDMAEN); +#else + /* Enable Ep interrupt (R/W) */ + + inten = lpc214x_getreg(LPC214X_USBDEV_EPINTEN); + inten |= (1 << privep->epphy); + lpc214x_putreg(inten, LPC214X_USBDEV_EPINTEN); +#endif + + /* If all of the endpoints have been configured, then tell the USB controller + * to enabled normal activity on all realized endpoints. + */ + + if (last) + { + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 1); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc214x_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int lpc214x_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + irqstate_t flags; + uint32_t mask = (1 << privep->epphy); + uint32_t reg; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Cancel any ongoing activity */ + + flags = enter_critical_section(); + lpc214x_cancelrequests(privep); + + /* Disable endpoint and interrupt */ + + reg = lpc214x_getreg(LPC214X_USBDEV_REEP); + reg &= ~mask; + lpc214x_putreg(reg, LPC214X_USBDEV_REEP); + + lpc214x_putreg(mask, LPC214X_USBDEV_EPDMADIS); + + reg = lpc214x_getreg(LPC214X_USBDEV_EPINTEN); + reg &= ~mask; + lpc214x_putreg(reg, LPC214X_USBDEV_EPINTEN); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc214x_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *lpc214x_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc214x_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct lpc214x_ep_s *)ep)->epphy); + + privreq = (FAR struct lpc214x_req_s *)kmm_malloc(sizeof(struct lpc214x_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct lpc214x_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: lpc214x_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void lpc214x_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc214x_req_s *privreq = (FAR struct lpc214x_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, ((FAR struct lpc214x_ep_s *)ep)->epphy); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: lpc214x_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_LPC214X_USBDEV_DMA +static FAR void *lpc214x_epallocbuffer(FAR struct usbdev_ep_s *ep, uint16_t nbytes) +{ +#ifdef CONFIG_USBDEV_DMA + + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + int descndx; + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + + /* Find a free DMA description */ + +#error "LOGIC INCOMPLETE" + + /* Set UDCA to the allocated DMA descriptor for this endpoint */ + + USB_UDCA[privep->epphy] = &USB_DDESC[descndx]; + return &USB_DDESC[descndx] + +#elif defined(CONFIG_USBDEV_DMAMEMORY) + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + return usbdev_dma_alloc(bytes); + +#else + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + return kmm_malloc(bytes); + +#endif +} +#endif + +/**************************************************************************** + * Name: lpc214x_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA + +static void lpc214x_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ +#ifdef CONFIG_LPC214X_USBDEV_DMA + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + + /* Indicate that there is no DMA descriptor associated with this endpoint */ + + USB_UDCA[privep->epphy] = NULL; + + /* Mark the DMA descriptor as free for re-allocation */ + +# error "LOGIC INCOMPLETE" + +#elif defined(CONFIG_USBDEV_DMAMEMORY) + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + usbdev_dma_free(buf); + +#else + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + kmm_free(buf); + +#endif +} +#endif + +/**************************************************************************** + * Name: lpc214x_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int lpc214x_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc214x_req_s *privreq = (FAR struct lpc214x_req_s *)req; + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + FAR struct lpc214x_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + lpc214x_abortrequest(privep, privreq, -EBUSY); + ret = -EBUSY; + } + + /* Handle IN (device-to-host) requests */ + + else if (LPC214X_EPPHYIN(privep->epphy)) + { + /* Add the new request to the request queue for the IN endpoint */ + + lpc214x_rqenqueue(privep, privreq); + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the IN endpoint FIFO is available, then transfer the data now */ + + if (privep->txbusy == 0) + { + ret = lpc214x_wrrequest(privep); + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + privep->txnullpkt = 0; + lpc214x_rqenqueue(privep, privreq); + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + + /* This there a incoming data pending the availability of a request? */ + + if (priv->rxpending) + { + ret = lpc214x_rdrequest(privep); + priv->rxpending = 0; + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc214x_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int lpc214x_epcancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + lpc214x_cancelrequests(privep); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc214x_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int lpc214x_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy); + lpc214x_usbcmd(CMD_USB_EP_SETSTATUS | privep->epphy, (resume ? 0 : USBDEV_EPSTALL)); + + /* If the endpoint of was resumed, then restart any queue write requests */ + + if (resume) + { + (void)lpc214x_wrrequest(privep); + } + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lcp214x_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct lpc214x_usbdev_s *priv = (FAR struct lpc214x_usbdev_s *)dev; + uint32_t epset = LPC214X_EPALLSET & ~LPC214X_EPCTRLSET; + irqstate_t flags; + int epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* A logical address of 0 means that any endpoint will do */ + + if (eplog > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (eplog >= LPC214X_NLOGENDPOINTS) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADEPNO), (uint16_t)eplog); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset &= 3 << (eplog << 1); + } + + /* Get the subset matching the requested direction */ + + if (in) + { + epset &= LPC214X_EPINSET; + } + else + { + epset &= LPC214X_EPOUTSET; + } + + /* Get the subset matching the requested type */ + + switch (eptype) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + epset &= LPC214X_EPINTRSET; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + epset &= LPC214X_EPBULKSET; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + epset &= LPC214X_EPISOCSET; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ + default: + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADEPTYPE), (uint16_t)eptype); + return NULL; + } + + /* Is the resulting endpoint supported by the LPC214x? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints */ + + for (epndx = 2; epndx < LPC214X_NPHYSENDPOINTS; epndx++) + { + uint32_t bit = 1 << epndx; + if ((epset & bit) != 0) + { + /* Mark the IN/OUT endpoint no longer available */ + + priv->epavail &= ~(3 << (bit & ~1)); + leave_critical_section(flags); + + /* And return the pointer to the standard endpoint structure */ + + return &priv->eplist[epndx].ep; + } + } + /* Shouldn't get here */ + } + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_NOEP), (uint16_t)eplog); + return NULL; +} + +/**************************************************************************** + * Name: lpc214x_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void lpc214x_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc214x_usbdev_s *priv = (FAR struct lpc214x_usbdev_s *)dev; + FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: lpc214x_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int lpc214x_getframe(struct usbdev_s *dev) +{ +#ifdef CONFIG_LPC214X_USBDEV_FRAME_INTERRUPT + FAR struct lpc214x_usbdev_s *priv = (FAR struct lpc214x_usbdev_s *)dev; + + /* Return last valid value of SOF read by the interrupt handler */ + + usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof); + return priv->sof; +#else + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, 0); + return (int)lpc214x_usbcmd(CMD_USB_DEV_READFRAMENO, 0); +#endif +} + +/**************************************************************************** + * Name: lpc214x_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int lpc214x_wakeup(struct usbdev_s *dev) +{ + uint8_t arg = USBDEV_DEVSTATUS_SUSPEND; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, (uint16_t)g_usbdev.devstatus); + + flags = enter_critical_section(); + if (DEVSTATUS_CONNECT(g_usbdev.devstatus)) + { + arg |= USBDEV_DEVSTATUS_CONNECT; + } + + lpc214x_usbcmd(CMD_USB_DEV_SETSTATUS, arg); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc214x_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int lpc214x_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct lpc214x_usbdev_s *priv = (FAR struct lpc214x_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: lpc214x_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int lpc214x_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + /* The USBDEV_DEVSTATUS_CONNECT bit in the CMD_USB_DEV_SETSTATUS command + * controls the LPC214x SoftConnect_N output pin that is used for SoftConnect. + */ + + lpc214x_usbcmd(CMD_USB_DEV_SETSTATUS, (enable ? USBDEV_DEVSTATUS_CONNECT : 0)); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + struct lpc214x_usbdev_s *priv = &g_usbdev; + uint32_t reg; + int i; + + usbtrace(TRACE_DEVINIT, 0); + + /* Disable USB interrupts */ + + lpc214x_putreg(0, LPC214X_USBDEV_INTST); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct lpc214x_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[LPC214X_EP0_IN].ep; + priv->epavail = LPC214X_EPALLSET; + + /* Initialize the endpoint list */ + + for (i = 0; i < LPC214X_NPHYSENDPOINTS; i++) + { + uint32_t bit = 1 << i; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + priv->eplist[i].ep.ops = &g_epops; + priv->eplist[i].dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + priv->eplist[i].epphy = i; + if (LPC214X_EPPHYIN(i)) + { + priv->eplist[i].ep.eplog = LPC214X_EPPHYIN2LOG(i); + } + else + { + priv->eplist[i].ep.eplog = LPC214X_EPPHYOUT2LOG(i); + } + + /* The maximum packet size may depend on the type of endpoint */ + + if ((LPC214X_EPCTRLSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC214X_EP0MAXPACKET; + } + else if ((LPC214X_EPINTRSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC214X_INTRMAXPACKET; + } + else if ((LPC214X_EPBULKSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC214X_BULKMAXPACKET; + } + else /* if ((LPC214X_EPISOCSET & bit) != 0) */ + { + priv->eplist[i].ep.maxpacket = LPC214X_ISOCMAXPACKET; + } + } + + /* Turn on USB power and clocking */ + + reg = lpc214x_getreg(LPC214X_PCON_PCONP); + reg |= LPC214X_PCONP_PCUSB; + lpc214x_putreg(reg, LPC214X_PCON_PCONP); + + /* Attach USB controller interrupt handler */ + + if (irq_attach(LPC214X_USB_IRQ, lpc214x_usbinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_IRQREGISTRATION), + (uint16_t)LPC214X_USB_IRQ); + goto errout; + } + + /* Enable USB inerrupts at the controller -- but do not disable + * the ARM interrupt until the device is bound to the class + * driver + */ + + lpc214x_putreg(USBDEV_INTST_ENUSBINTS, LPC214X_USBDEV_INTST); + + /* Disconnect device */ + + lpc214x_pullup(&priv->usbdev, false); + + /* Enable EP0 for OUT (host-to-device) */ + + lpc214x_usbcmd(CMD_USB_DEV_SETADDRESS, CMD_USB_SETADDRESS_DEVEN | 0); + lpc214x_usbcmd(CMD_USB_DEV_SETADDRESS, CMD_USB_SETADDRESS_DEVEN | 0); + + /* Reset/Re-initialize the USB hardware */ + + lpc214x_usbreset(priv); + + /* Init Device state structure */ + + priv->devstatus = lpc214x_usbcmd(CMD_USB_DEV_GETSTATUS, 0); + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct lpc214x_usbdev_s *priv = &g_usbdev; + uint32_t reg; + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + lpc214x_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 0); + + /* Disable and detach IRQs */ + + up_disable_irq(LPC214X_USB_IRQ); + irq_detach(LPC214X_USB_IRQ); + + /* Turn off USB power and clocking */ + + reg = lpc214x_getreg(LPC214X_PCON_PCONP); + reg &= ~LPC214X_PCONP_PCUSB; + lpc214x_putreg(reg, LPC214X_PCON_PCONP); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(LPC214X_USB_IRQ); + } + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable USB controller interrupts */ + + up_disable_irq(LPC214X_USB_IRQ); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} diff --git a/arch/arm/src/lpc214x/lpc214x_usbdev.h b/arch/arm/src/lpc214x/lpc214x_usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..df2d3195f52f952e657f183289a19cdd09301755 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_usbdev.h @@ -0,0 +1,346 @@ +/**************************************************************************** + * arch/arm/src/lpc214x/lpc214x_usbdev.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC214X_LPC214X_USBDEV_H +#define __ARCH_ARM_SRC_LPC214X_LPC214X_USBDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* PINSEL1 bit definitions for UART0/1: + * + * P0.23 = 01 to enable VBus sense (bits 14-15) + * P0.31 = 10 to enable CONNECT (bits 30-31) + */ + +#define LPC214X_USBDEV_PINSEL (0x80004000) /* PINSEL1 value for USB */ +#define LPC214X_USBDEV_PINMASK (0xc000c000) /* PINSEL1 mask for USB */ + +/* USB RAM ********************************************************************/ + +#define LPC214X_USBDEV_RAMBASE (0x7fd00000) +#define LPC214X_USBDEV_RAMSIZE (8*1024) + +/* USB register address definitions ********************************************/ + +#define LPC214X_USBDEV_PLLCON (0xe01fc0a0) +#define LPC214X_USBDEV_PLLCFG (0xe01fc0a4) +#define LPC214X_USBDEV_PLLSTAT (0xe01fc0a8) +#define LPC214X_USBDEV_PLLFEED (0xe01fc0ac) + +#define LPC214X_USBDEV_INTST (0xe01fc1c0) + +#define LPC214X_USBDEV_DEVINTST (0xe0090000) +#define LPC214X_USBDEV_DEVINTEN (0xe0090004) +#define LPC214X_USBDEV_DEVINTCLR (0xe0090008) +#define LPC214X_USBDEV_DEVINTSET (0xe009000c) +#define LPC214X_USBDEV_CMDCODE (0xe0090010) +#define LPC214X_USBDEV_CMDDATA (0xe0090014) +#define LPC214X_USBDEV_RXDATA (0xe0090018) +#define LPC214X_USBDEV_TXDATA (0xe009001c) +#define LPC214X_USBDEV_RXPLEN (0xe0090020) +#define LPC214X_USBDEV_TXPLEN (0xe0090024) +#define LPC214X_USBDEV_CTRL (0xe0090028) +#define LPC214X_USBDEV_DEVINTPRI (0xe009002c) +#define LPC214X_USBDEV_EPINTST (0xe0090030) +#define LPC214X_USBDEV_EPINTEN (0xe0090034) +#define LPC214X_USBDEV_EPINTCLR (0xe0090038) +#define LPC214X_USBDEV_EPINTSET (0xe009003c) +#define LPC214X_USBDEV_EPINTPRI (0xe0090040) +#define LPC214X_USBDEV_REEP (0xe0090044) +#define LPC214X_USBDEV_EPIND (0xe0090048) +#define LPC214X_USBDEV_MAXPSIZE (0xe009004c) +#define LPC214X_USBDEV_DMARST (0xe0090050) +#define LPC214X_USBDEV_DMARCLR (0xe0090054) +#define LPC214X_USBDEV_DMARSET (0xe0090058) + +#define LPC214X_USBDEV_UDCAH (0xe0090080) +#define LPC214X_USBDEV_EPDMAST (0xe0090084) +#define LPC214X_USBDEV_EPDMAEN (0xe0090088) +#define LPC214X_USBDEV_EPDMADIS (0xe009008c) +#define LPC214X_USBDEV_DMAINTST (0xe0090090) +#define LPC214X_USBDEV_DMAINTEN (0xe0090094) + +#define LPC214X_USBDEV_EOTINTST (0xe00900a0) +#define LPC214X_USBDEV_EOTINTCLR (0xe00900a4) +#define LPC214X_USBDEV_EOTINTSET (0xe00900a8) +#define LPC214X_USBDEV_NDDRINTST (0xe00900ac) +#define LPC214X_USBDEV_NDDRINTCLR (0xe00900b0) +#define LPC214X_USBDEV_NDDRINTSET (0xe00900b4) +#define LPC214X_USBDEV_SYSERRINTST (0xe00900b8) +#define LPC214X_USBDEV_SYSERRINTCLR (0xe00900bc) +#define LPC214X_USBDEV_SYSERRINTSET (0xe00900c0) + +/* USB register bit definitions ************************************************/ + +/* INTST bit definitions */ + +#define USBDEV_INTST_REQLP (0x00000001) +#define USBDEV_INTST_REQHP (0x00000002) +#define USBDEV_INTST_REQDMA (0x00000004) +#define USBDEV_INTST_NEEDCLOCK (0x00000100) +#define USBDEV_INTST_ENUSBINTS (0x80000000) +#define USBDEV_INTST_MASK (0x80000107) + +/* DEVINTST/DEVINTEN/DEVINTCLR/DEVINTSET bit definitions */ + +#define USBDEV_DEVINT_FRAME (0x00000001) +#define USBDEV_DEVINT_EPFAST (0x00000002) +#define USBDEV_DEVINT_EPSLOW (0x00000004) +#define USBDEV_DEVINT_DEVSTAT (0x00000008) +#define USBDEV_DEVINT_CCEMTY (0x00000010) +#define USBDEV_DEVINT_CDFULL (0x00000020) +#define USBDEV_DEVINT_RXENDPKT (0x00000040) +#define USBDEV_DEVINT_TXENDPKT (0x00000080) +#define USBDEV_DEVINT_EPRLZED (0x00000100) +#define USBDEV_DEVINT_EPRINT (0x00000200) +#define USBDEV_DEVINT_MASK (0x000003ff) + +/* DEVINTPRI bit definitions */ + +#define USBDEV_DEVINTPRI_FRAME (0x00000001) +#define USBDEV_DEVINTPRI_EPFAST (0x00000002) +#define USBDEV_DEVINTPRI_MASK (0x00000003) + +/* RXPLEN bit definitions */ + +#define USBDEV_RXPLEN_PKTLENGTH (0x000003ff) +#define USBDEV_RXPLEN_PKTLENGTH_MASK (0x000003ff) +#define USBDEV_RXPLEN_DV (0x00000400) +#define USBDEV_RXPLEN_PKTRDY (0x00000800) +#define USBDEV_RXPLEN_MASK (0x00000fff) + +/* TXPLEN bit definitions */ + +#define USBDEV_TXPLEN_PKTLENGTH (0x000003ff) +#define USBDEV_TXPLEN_MASK (0x000003ff) + +/* USBCTRL bit definitions */ + +#define USBDEV_CTRL_RDEN (0x00000001) +#define USBDEV_CTRL_WREN (0x00000002) +#define USBDEV_CTRL_LOGENDPOINT (0x0000003c) +#define USBDEV_CTRL_MASK (0x0000003f) + +/* CMDCODE bit definitions */ + +#define USBDEV_CMDCODE_CMDPHASE (0x0000ff00) +#define USBDEV_CMDCODE_CMDCODE (0x00ff0000) +#define USBDEV_CMDCODE_MASK (0x00ffff00) + +/* DMAINSTST/DMAINSTEN bit defintions */ + +#define USBDEV_DMAINST_EOT (0x00000001) +#define USBDEV_DMAINST_NDDR (0x00000002) +#define USBDEV_DMAINST_SE (0x00000004) +#define USBDEV_DMAINST_MASK (0x00000007) + +/* Device Status Bits */ + +#define USBDEV_EPSTALL (0x00000001) +#define USBDEV_EPSTALLSTATUS (0x00000002) +#define USBDEV_EPSETUPPACKET (0x00000004) +#define USBDEV_EPPOSSTATUS (0x00000010) +#define USBDEV_EPCONDSTALL (0x00000080) + +/* USB Control register bit definitions */ + +#define LPC214X_USBCTRL_RDEN (0x00000001) /* Bit 0=1: Read is enabled */ +#define LPC214X_USBCTRL_WREN (0x00000002) /* Bit 0=1: Write is enabled */ +#define LPC214X_USBCTRL_EPMASK (0x0000003c) /* Bits 2:5: Logical endpoint 0-15 */ + +/* Endpoints *******************************************************************/ + +#define LPC214X_EP0_OUT 0 +#define LPC214X_EP0_IN 1 +#define LPC214X_CTRLEP_OUT LPC214X_EP0_OUT +#define LPC214X_CTRLEP_IN LPC214X_EP0_IN +#define LPC214X_EP1_OUT 2 +#define LPC214X_EP1_IN 3 +#define LPC214X_EP2_OUT 4 +#define LPC214X_EP2_IN 5 +#define LPC214X_EP3_OUT 6 +#define LPC214X_EP3_IN 7 +#define LPC214X_EP4_OUT 8 +#define LPC214X_EP4_IN 9 +#define LPC214X_EP5_OUT 10 +#define LPC214X_EP5_IN 11 +#define LPC214X_EP6_OUT 12 +#define LPC214X_EP6_IN 13 +#define LPC214X_EP7_OUT 14 +#define LPC214X_EP7_IN 15 +#define LPC214X_EP8_OUT 16 +#define LPC214X_EP8_IN 17 +#define LPC214X_EP9_OUT 18 +#define LPC214X_EP9_IN 19 +#define LPC214X_EP10_OUT 20 +#define LPC214X_EP10_IN 21 +#define LPC214X_EP11_OUT 22 +#define LPC214X_EP11_IN 23 +#define LPC214X_EP12_OUT 24 +#define LPC214X_EP12_IN 25 +#define LPC214X_EP13_OUT 26 +#define LPC214X_EP13_IN 27 +#define LPC214X_EP14_OUT 28 +#define LPC214X_EP14_IN 29 +#define LPC214X_EP15_OUT 30 +#define LPC214X_EP15_IN 31 +#define LPC214X_NUMEPS 32 + +/* Commands ********************************************************************/ + +/* USB Command Code Register -- Command phase values */ + +#define CMD_USB_CMDWR (0x00000500) +#define CMD_USB_DATAWR (0x00000100) +#define CMD_USB_DATARD (0x00000200) + +/* Device Commands */ + +#define CMD_USB_DEV_SETADDRESS (0x00d0) +#define CMD_USB_DEV_CONFIG (0x00d8) +#define CMD_USB_DEV_SETMODE (0x00f3) +#define CMD_USB_DEV_READFRAMENO (0x00f5) +#define CMD_USB_DEV_READTESTREG (0x00fd) +#define CMD_USB_DEV_SETSTATUS (0x01fe) +#define CMD_USB_DEV_GETSTATUS (0x00fe) +#define CMD_USB_DEV_GETERRORCODE (0x00ff) +#define CMD_USB_DEV_READERRORSTATUS (0x00fb) + +/* Endpoint Commands */ + +#define CMD_USB_EP_SELECT (0x0000) +#define CMD_USB_EP_SELECTCLEAR (0x0040) +#define CMD_USB_EP_SETSTATUS (0x0140) +#define CMD_USB_EP_CLRBUFFER (0x00f2) +#define CMD_USB_EP_VALIDATEBUFFER (0x00fa) + +/* Command Data ****************************************************************/ + +/* DEV SETADDRESS command bits */ + +#define CMD_USB_SETADDRESS_DEVEN (0x80) + +/* Command Responses ***********************************************************/ + +/* Device Status Bits (8-bits) */ + +#define USBDEV_DEVSTATUS_CONNECT (0x01) /* Bit 0: Connected */ +#define USBDEV_DEVSTATUS_CONNCHG (0x02) /* Bit 1: Connect change */ +#define USBDEV_DEVSTATUS_SUSPEND (0x04) /* Bit 2: Suspend */ +#define USBDEV_DEVSTATUS_SUSPCHG (0x08) /* Bit 3: Suspend change */ +#define USBDEV_DEVSTATUS_RESET (0x10) /* Bit 4: Bus reset bit */ + +/* EP Select response */ + +#define CMD_USB_EPSELECT_FE (0x01) /* Bit 0=1: IN empty or OUT full */ +#define CMD_USB_EPSELECT_ST (0x02) /* Bit 1=1: Endpoint is stalled */ +#define CMD_USB_EPSELECT_STP (0x04) /* Bit 2=1: Last packet was setup */ +#define CMD_USB_EPSELECT_PO (0x05) /* Bit 3=1: Previous packet was overwritten */ +#define CMD_USB_EPSELECT_EPN (0x10) /* Bit 4=1: NAK sent */ +#define CMD_USB_EPSELECT_B1FULL (0x20) /* Bit 5=1: Buffer 1 full */ +#define CMD_USB_EPSELECT_B2FULL (0x40) /* Bit 6=1: Buffer 2 full */ + +/* EP CLRBUFFER response */ + +#define CMD_USB_CLRBUFFER_PO (0x00000001) + +/* DMA *************************************************************************/ + +/* The DMA descriptor */ + +#define USB_DMADESC_NEXTDDPTR 0 /* Offset 0: Next USB descriptor in RAM */ +#define USB_DMADESC_CONFIG 1 /* Offset 1: DMA configuration info. */ +#define USB_DMADESC_STARTADDR 2 /* Offset 2: DMA start address */ +#define USB_DMADESC_STATUS 3 /* Offset 3: DMA status info (read only) */ +#define USB_DMADESC_ISOCSIZEADDR 4 /* Offset 4: Isoc. packet size address */ + +/* Bit settings for offset 1 */ + +#define USB_DMADESC_MODENORMAL (0x00000000) /* Bits 0-1=00: Mode normal */ +#define USB_DMADESC_MODEATLE (0x00000001) /* Bits 0-1=01: ATLE normal */ +#define USB_DMADESC_NEXTDDVALID (0x00000004) /* Bit 2=1: next descriptor valid */ +#define USB_DMADESC_ISCOEP (0x00000010) /* Bit 4=1: isoc endpoint */ +#define USB_DMADESC_PKTSIZEMASK (0x0000ffe0) /* Bits 5-15: packet size */ +#define USB_DMADESC_PKTSIZESHIFT (5) /* Bits 5-15: packet size */ +#define USB_DMADESC_BUFLENMASK (0xffff0000) /* Bits 16-31: buffer length */ +#define USB_DMADESC_BULENSHIFT (16) /* Bits 16-31: buffer length */ + +/* Bit settings for offset 3 (all must be initialized to zero) */ + +#define USB_DMADESC_STATUSMASK (0x0000001e) /* Bits 1-4: DMA status */ +#define USB_DMADESC_NOTSERVICED (0x00000000) +#define USB_DMADESC_BEINGSERVICED (0x00000002) +#define USB_DMADESC_NORMALCOMPLETION (0x00000004) +#define USB_DMADESC_DATAUNDERRUN (0x00000006) +#define USB_DMADESC_DATAOVERRUN (0x00000010) +#define USB_DMADESC_SYSTEMERROR (0x00000012) +#define USB_DMADESC_PKTVALID (0x00000020) /* Bit 5=1: Packet valid */ +#define USB_DMADESC_LSBEXTRACTED (0x00000040) /* Bit 6=1: LS byte extracted */ +#define USB_DMADESC_MSBEXTRACTED (0x00000080) /* Bit 7=1: MS byte extracted */ +#define USB_DMADESC_MSGLENPOSMASK (0x00003f00) /* Bits 8-13: Message length position */ +#define USB_DMADESC_MSGLENPOSSHIFT (8) /* Bits 8-13: Message length position */ +#define USB_DMADESC_DMACOUNTMASK (0xffff0000) /* Bits 16-31: DMA count */ +#define USB_DMADESC_DMACOUNTSHIFT (16) /* Bits 16-31: DMA count */ + +/* DMA packet size format */ + +#define USB_DMAPKTSIZE_PKTLENMASK (0x0000ffff) /* Bits 0-15: Packet length */ +#define USB_DMAPKTSIZE_PKTLENSHIFT (0) /* Bits 0-15: Packet length */ +#define USB_DMAPKTSIZE_PKTVALID (0x00010000) /* Bit 16=1: Packet valid */ +#define USB_DMAPKTSIZE_FRAMENOMASK (0xfffe0000) /* Bit 17-31: Frame number */ +#define USB_DMAPKTSIZE_FRAMENOSHIFT (17) /* Bit 17-31: Frame number */ + + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC214X_LPC214X_USBDEV_H */ diff --git a/arch/arm/src/lpc214x/lpc214x_vic.h b/arch/arm/src/lpc214x/lpc214x_vic.h new file mode 100644 index 0000000000000000000000000000000000000000..89a5f7b13f8200175d115bacd5e8fdd71d2528e9 --- /dev/null +++ b/arch/arm/src/lpc214x/lpc214x_vic.h @@ -0,0 +1,70 @@ +/************************************************************************************ + * arch/arm/src/lpc214x/lpc214x_vic.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __LPC214X_VIC_H +#define __LPC214X_VIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* All VIC registers are 32-bits wide */ + +#define vic_getreg(o) getreg32(LPC214X_VIC_BASE+(o)) +#define vic_putreg(v,o) putreg32((v),LPC214X_VIC_BASE+(o)) + +/* Vector Control Register bit definitions */ + +#define LPC214X_VECTCNTL_IRQMASK (0x0000001f) +#define LPC214X_VECTCNTL_IRQSHIFT (0) +#define LPC214X_VECTCNTL_ENABLE (1 << 5) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __LPC214X_VIC_H */ diff --git a/arch/arm/src/lpc2378/Kconfig b/arch/arm/src/lpc2378/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4e153df4013901b50fc4a49938c0871973c2f25a --- /dev/null +++ b/arch/arm/src/lpc2378/Kconfig @@ -0,0 +1,191 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC2378 Configuration Options" + +choice + prompt "Memory Execution Mode" + default LPC2378_DEFAULT_MODE + +config LPC2378_EXTMEM_MODE + bool "External Memory Mode" + depends on EXPERIMENTAL # Not used + ---help--- + Code executes from external memory starting at address 0x8000:0000. + +config LPC2378_RAM_MODE + bool "RAM Memory Mode" + depends on EXPERIMENTAL # Not used + ---help--- + Code executes from on-chip RAM at address 0x4000:0000. + +config LPC2378_DEFAULT_MODE + bool "Default Memory Mode" + ---help--- + Executes from 0x0000:0000. In non-default modes, the MEMAP register + is set override the settings of the CPU configuration pins. + +endchoice + +config LPC2378_CODE_BASE + hex "Execution Base Address" + default 0x00000000 + ---help--- + This must match the expected address for the selected "Memory + Execution Address": + + LPC2378_EXTMEM_MODE: 0x8000:0000 + LPC2378_RAM_MODE: 0x4000:0000 + LPC2378_DEFAULT_MODE: 0x0000:0000 + +config LPC2378_PLL_SETUP + bool "Configure the PLL" + default y + +config LPC2378_PLL_CLKSRC + int "PLL clock source" + default 1 + range 0 2 + depends on LPC2378_PLL_SETUP + ---help--- + PLL clock source + +config LPC2378_MAM_SETUP + bool "Configure the Memory Accelerator Module (MAM)" + default y + +config LPC2378_MAMCR_VALUE + int "Memory accelerator mode" + default 1 + range 0 2 + ---help--- + Memory accelerator mode: + + OFF 0 + PART 1 + FULL 2 + +config LPC2378_MAMTIM_VALUE + int "Memory accelerator timing value" + default 3 + ---help--- + Memory accelerator timing value + +config LPC2378_APBDIV_SETUP + bool "Configure the APB Divider" + default y + depends on EXPERIMENTAL # Not used + +config LPC2378_APBDIV_VALUE + int "APB Divisor" + default 1 + depends on EXPERIMENTAL # Not used + +config LPC2378_EMC_SETUP + bool "Configure EMC" + default n + depends on EXPERIMENTAL # Not used + +config LPC2378_BCFG0_SETUP + bool "Configure BCFG0" + default n + depends on EXPERIMENTAL # Not used + +config LPC2378_BCFG1_SETUP + bool "Configure BCFG1" + default n + depends on EXPERIMENTAL # Not used + +config LPC2378_BCFG2_SETUP + bool "Configure BCFG2" + default n + depends on EXPERIMENTAL # Not used + +config BCFG3_SETUP + bool "Configure BCFG3" + default n + depends on EXPERIMENTAL # Not used + +config LPC2378_ADC_SETUP + bool "Configure ADC" + default y + depends on EXPERIMENTAL # Not used + +menu "LPC2378 Peripheral Support" + +config LPC2378_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + +config LPC2378_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + +config LPC2378_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + +config LPC2378_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + +config LPC2378_USBDEV + bool "USB Device" + default n + depends on USBDEV + +config LPC2378_I2C0 + bool "I2C0" + default n + select I2C + +config LPC2378_I2C1 + bool "I2C1" + default n + select I2C + +config LPC2378_I2C2 + bool "I2C2" + default n + select I2C + +config LPC2378_SPI + bool "SPI" + default n + select SPI + +endmenu + +if LPC2378_USBDEV +menu "LPC2378 USB Device Configuration" + +config LPC2378_USBDEV_DMA + bool "USB Device DMA Support" + default n + +config LPC2378_USBDEV_NDMADESCRIPTORS + int "Number of USB DMA Descriptors" + default 8 + depends on LPC2378_USBDEV_DMA + +config LPC2378_USBDEV_EPFAST_INTERRUPT + bool "USB Device Fast Endpoint Interrupts" + default n + +config LPC2378_USBDEV_FRAME_INTERRUPT + bool "USB Device Frame Interrupts" + default n + +config LPC2378_USBDEV_REGDEBUG + bool "USB Device Register-Level Debug Output" + default n + depends on DEBUG + +endmenu +endif diff --git a/arch/arm/src/lpc2378/Make.defs b/arch/arm/src/lpc2378/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..a79ce91ddd92c3b2e9797118277d5d1ed796249a --- /dev/null +++ b/arch/arm/src/lpc2378/Make.defs @@ -0,0 +1,85 @@ +############################################################################## +# lpc23xx/Make.defs +# +# Copyright (C) 2010 Rommel Marcelo. All rights reserved. +# Author: Rommel Marcelo +# +# This file is part of the NuttX RTOS and based on the lpc2148 port: +# +# Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +HEAD_ASRC = lpc23xx_head.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S +CMN_ASRCS += vfork.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c +CMN_CSRCS += up_exit.c up_idle.c up_initialize.c up_initialstate.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_stackframe.c +CMN_CSRCS += up_syscall.c up_unblocktask.c up_undefinedinsn.c +CMN_CSRCS += up_usestack.c up_lowputs.c up_vfork.c + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = lpc23xx_lowputc.S +CHIP_CSRCS += lpc23xx_pllsetup.c lpc23xx_decodeirq.c lpc23xx_irq.c +CHIP_CSRCS += lpc23xx_serial.c lpc23xx_io.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc23xx_timerisr.c +endif + +ifeq ($(CONFIG_LPC2378_SPI),y) +CHIP_CSRCS += lpc23xx_spi.c +endif + +ifeq ($(CONFIG_I2C),y) +CHIP_CSRCS += lpc23xx_i2c.c +endif + +ifeq ($(CONFIG_USBDEV),y) +#CHIP_CSRCS += lpc23xx_usbdev.c +endif diff --git a/arch/arm/src/lpc2378/chip.h b/arch/arm/src/lpc2378/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..b8b8b70c85a38bf51a1d98602ca31f0aad4806d7 --- /dev/null +++ b/arch/arm/src/lpc2378/chip.h @@ -0,0 +1,1006 @@ +/**************************************************************************************************** + * arch/arm/src/lpc2378/chip.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC2378_CHIP_H +#define _ARCH_ARM_SRC_LPC2378_CHIP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Memory Map ***************************************************************************************/ + +#define LPC23XX_FLASH_BASE 0x00000000 +#define LPC23XX_FIO_BASE 0x3fffc000 +#define LPC23XX_ONCHIP_RAM_BASE 0x40000000 +#define LPC23XX_USBDMA_RAM_BASE 0x7fd00000 +#define LPC23XX_ETHERNET_RAM_BASE 0x7fe00000 +#define LPC23XX_BOOT_BLOCK 0x7fffd000 +#define LPC23XX_EXTMEM_BASE 0x80000000 +#define LPC23XX_APB_BASE 0xe0000000 +#define LPC23XX_AHB_BASE 0xf0000000 + +/* Peripheral Registers ****************************************************************************/ + +/* APB Register block base addresses */ + +#define LPC23XX_WD_BASE 0xe0000000 /* Watchdog base address */ +#define LPC23XX_TMR0_BASE 0xE0004000 /* Timer 0 base address*/ +#define LPC23XX_TMR1_BASE 0xe0008000 /* Timer 1 base address */ +#define LPC23XX_UART0_BASE 0xe000c000 /* UART0 base address */ +#define LPC23XX_UART1_BASE 0xe0010000 /* UART1 base address */ +#define LPC23XX_PWM_BASE 0xe0018000 /* Pulse width modulator (PWM) base address */ +#define LPC23XX_I2C0_BASE 0xe001c000 /* I2C0 base address */ +#define LPC23XX_SPI0_BASE 0xe0020000 /* Serial Peripheral Interface 0 (SPI0) base */ +#define LPC23XX_RTC_BASE 0xe0024000 /* Real Time Clock (RTC) base address */ +#define LPC23XX_GPIO0_BASE 0xe0028000 /* General Purpose I/O (GPIO) 0 base address */ +#define LPC23XX_GPIO1_BASE 0xe0028010 /* General Purpose I/O (GPIO) 1 base address */ +#define LPC23XX_PINSEL_BASE 0xe002c000 /* Pin function select registers */ +#define LPC23XX_SSP1_BASE 0xe0030000 /* Synchronous Serial Port 1 base address */ +#define LPC23XX_AD0_BASE 0xe0034000 /* Analog to Digital Converter 0 base address*/ +//~ #define LPC23XX_CAN_ACCEPT_RAM_BASE 0xe0038000 /* CAN Acceptance Filter RAM base address*/ +#define LPC23XX_CAN_ACCEPT_BASE 0xE003C000 /* CAN Acceptance Filter Register base address*/ +#define LPC23XX_CAN_COMMON_BASE 0xe0040000 /* CAN Common Register base address*/ +#define LPC23XX_CAN1_BASE 0xe0044000 /* CAN 1 Controller base address*/ +#define LPC23XX_CAN2_BASE 0xe0048000 /* CAN 2 Controller base address*/ +#define LPC23XX_I2C1_BASE 0xe005c000 /* I2C1 base address */ +#define LPC23XX_SSP0_BASE 0xE0068000 /* Synchronous Serial Port 0 base address */ +#define LPC23XX_DAC_BASE 0xE006C000 /* DAC base address */ +#define LPC23XX_TMR2_BASE 0xE0070000 /* Timer 2 base address */ +#define LPC23XX_TMR3_BASE 0xE0074000 /* Timer 3 base address */ +#define LPC23XX_UART2_BASE 0xE0078000 /* UART2 base address */ +#define LPC23XX_UART3_BASE 0xE007C000 /* UART3 base address */ +#define LPC23XX_I2C2_BASE 0xE0080000 /* I2C2 base address */ +#define LPC23XX_BATT_RAM_BASE 0xE0084000 /* Battery RAM base address */ +#define LPC23XX_I2S_BASE 0xE0088000 /* I2S base address */ +#define LPC23XX_MCI_BASE 0xE008C000 /* SD/MMC Card Interface base address */ +//~ #define LPC23XX_SPI1_BASE 0xe0068000 /* Serial Peripheral Interface 1 (SPI1) base */ +#define LPC23XX_EMAC_BASE 0xFFE00000 /* Ethernet MAC base address */ +#define LPC23XX_USB_BASE 0xFFE0C200 /* USB base address */ +#define LPC23XX_SCB_BASE 0xE01FC000 /* System Control Block (SBC) base address */ +#define LPC23XX_EXT_BASE 0xe01fc140 /* External Interrupt base address */ + +/* AHB Register block base addresses */ + +#define LPC23XX_EMC_BASE 0xFFE08000 /* External Memory Controller (EMC) base address */ +#define LPC23XX_VIC_BASE 0xFFFFF000 /* Vectored Interrupt Controller (VIC) Base */ +#define LPC23XX_GPDMA_BASE 0xFFE04000 /* General Purpose DMA */ + + +/* Watchdog Register Offsets */ +#define WD_MOD_OFFSET 0x00 /* Watchdog Mode Register */ +#define WD_TC_OFFSET 0x04 /* Watchdog Time Constant Register */ +#define WD_FEED_OFFSET 0x08 /* Watchdog Feed Register */ +#define WD_TV_OFFSET 0x0C /* Watchdog Time Value Register */ + +/* Timers Base Addresses */ +#define TMR0_BASE_ADDR 0xE0004000 +#define TMR1_BASE_ADDR 0xE0008000 +#define TMR2_BASE_ADDR 0xE0070000 +#define TMR3_BASE_ADDR 0xE0074000 + +/* Timer 0/1/2/3 register offsets */ + +#define TMR_IR_OFFSET 0x00 /* RW:Interrupt Register */ +#define TMR_TCR_OFFSET 0x04 /* RW: Timer Control Register */ +#define TMR_TC_OFFSET 0x08 /* RW: Timer Counter */ +#define TMR_PR_OFFSET 0x0c /* RW: Prescale Register */ +#define TMR_PC_OFFSET 0x10 /* RW: Prescale Counter Register */ +#define TMR_MCR_OFFSET 0x14 /* RW: Match Control Register */ +#define TMR_MR0_OFFSET 0x18 /* RW: Match Register 0 */ +#define TMR_MR1_OFFSET 0x1c /* RW: Match Register 1 */ +#define TMR_MR2_OFFSET 0x20 /* RW: Match Register 2 */ +#define TMR_MR3_OFFSET 0x24 /* RW: Match Register 3 */ +#define TMR_CCR_OFFSET 0x28 /* RW: Capture Control Register */ +#define TMR_CR0_OFFSET 0x2c /* R: Capture Register 0 */ +#define TMR_CR1_OFFSET 0x30 /* R: Capture Register 1 */ +#define TMR_CR2_OFFSET 0x34 /* R: Capture Register 2 */ +#define TMR_CR3_OFFSET 0x38 /* RW: Capture Register 3 */ +#define TMR_EMR_OFFSET 0x3c /* RW: External Match Register */ +#define TMR_CTCR_OFFSET 0x70 /* RW: Count Control Register */ + +/* Universal Asynchronous Receiver Transmitter Base Addresses */ + +#define UART0_BASE_ADDR 0xE000C000 +#define UART1_BASE_ADDR 0xE0010000 +#define UART2_BASE_ADDR 0xE0078000 +#define UART3_BASE_ADDR 0xE007C000 + +/* UART 0/1/2/3 Register Offsets */ + +#define UART_RBR_OFFSET 0x00 /* R: Receive Buffer Register (DLAB=0) */ +#define UART_THR_OFFSET 0x00 /* W: Transmit Holding Register (DLAB=0) */ +#define UART_DLL_OFFSET 0x00 /* W: Divisor Latch Register (LSB, DLAB=1) */ +#define UART_IER_OFFSET 0x04 /* W: Interrupt Enable Register (DLAB=0) */ +#define UART_DLM_OFFSET 0x04 /* RW: Divisor Latch Register (MSB, DLAB=1) */ +#define UART_IIR_OFFSET 0x08 /* R: Interrupt ID Register */ +#define UART_FCR_OFFSET 0x08 /* W: FIFO Control Register */ +#define UART_LCR_OFFSET 0x0c /* RW: Line Control Register */ +#define UART_MCR_OFFSET 0x10 /* RW: Modem Control REgister (2146/6/8 UART1 Only) */ +#define UART_LSR_OFFSET 0x14 /* R: Scratch Pad Register */ +#define UART_MSR_OFFSET 0x18 /* RW: MODEM Status Register (2146/6/8 UART1 Only) */ +#define UART_SCR_OFFSET 0x1c /* RW: Line Status Register */ +#define UART_ACR_OFFSET 0x20 /* RW: Autobaud Control Register */ +#define UART_FDR_OFFSET 0x28 /* RW: Fractional Divider Register */ +#define UART_TER_OFFSET 0x30 /* RW: Transmit Enable Register */ + +/* Pulse Width Modulation Base Address */ + +#define PWM1_BASE_ADDR 0xE0018000 + +/* PWM register offsets */ + +#define PWM_IR_OFFSET 0x00 /* Interrupt Register */ +#define PWM_TCR_OFFSET 0x04 /* Timer Control Register */ +#define PWM_TC_OFFSET 0x08 /* Timer Counter */ +#define PWM_PR_OFFSET 0x0c /* Prescale Register */ +#define PWM_PC_OFFSET 0x10 /* Prescale Counter Register */ +#define PWM_MCR_OFFSET 0x14 /* Match Control Register */ +#define PWM_MR0_OFFSET 0x18 /* Match Register 0 */ +#define PWM_MR1_OFFSET 0x1c /* Match Register 1 */ +#define PWM_MR2_OFFSET 0x20 /* Match Register 2 */ +#define PWM_MR3_OFFSET 0x24 /* Match Register 3 */ +#define PWM_CCR_OFFSET 0x28 /* Capture Control Register*/ +#define PWM_CCR0_OFFSET 0x2C /* Capture Register 0 */ +#define PWM_CCR1_OFFSET 0x30 /* Capture Register 1 */ +#define PWM_CCR2_OFFSET 0x34 /* Capture Register 2 */ +#define PWM_CCR3_OFFSET 0x38 /* Capture Register 3 */ +#define PWM_EMR_OFFSET 0x3C /* */ +#define PWM_MR4_OFFSET 0x40 /* Match Register 4 */ +#define PWM_MR5_OFFSET 0x44 /* Match Register 5 */ +#define PWM_MR6_OFFSET 0x48 /* Match Register 6 */ +#define PWM_PCR_OFFSET 0x4c /* Control Register */ +#define PWM_LER_OFFSET 0x50 /* Latch Enable Register */ +#define PWM_CTCR_OFFSET 0x70 + +/* I2C Base Addresses */ + +#define I2C0_BASE_ADDR 0xE001C000 +#define I2C1_BASE_ADDR 0xE005C000 +#define I2C2_BASE_ADDR 0xE0080000 + +/* I2C 0/1/2 register offsets */ + +#define I2C_CONSET_OFFSET 0x00 /* Control Set Register */ +#define I2C_STAT_OFFSET 0x04 /* Status Register */ +#define I2C_DAT_OFFSET 0x08 /* Data Register */ +#define I2C_ADR_OFFSET 0x0c /* Slave Address Register */ +#define I2C_SCLH_OFFSET 0x10 /* SCL Duty Cycle Register (high half word) */ +#define I2C_SCLL_OFFSET 0x14 /* SCL Duty Cycle Register (low half word) */ +#define I2C_CONCLR_OFFSET 0x18 /* Control Clear Register */ + +/* Pin function select register offsets */ + +#define PINSEL0_OFFSET 0x00 /* Pin function select register 0 */ +#define PINSEL1_OFFSET 0x04 /* Pin function select register 1 */ +#define PINSEL2_OFFSET 0x08 /* Pin function select register 2 */ +#define PINSEL3_OFFSET 0x0C /* Pin function select register 3 */ +#define PINSEL4_OFFSET 0x10 /* Pin function select register 4 */ +#define PINSEL5_OFFSET 0x14 /* Pin function select register 5 */ +#define PINSEL6_OFFSET 0x18 /* Pin function select register 6 */ +#define PINSEL7_OFFSET 0x1C /* Pin function select register 7 */ +#define PINSEL8_OFFSET 0x20 /* Pin function select register 8 */ +#define PINSEL9_OFFSET 0x24 /* Pin function select register 9 */ +#define PINSEL10_OFFSET 0x28 /* Pin function select register 10 */ + +/* Analog to Digital (AD) Base Address */ + +#define ADC0_BASE_ADDR 0xE0034000 + +/* Analog to Digital (AD) Converter register offsets */ + +#define AD_ADCR_OFFSET 0x00 /* A/D Control Register */ +#define AD_ADGDR_OFFSET 0x04 /* A/D Global Data Register (only one common register!) */ +//~ #define AD_ADGSR_OFFSET 0x08 /* A/D Global Start Register */ +#define AD_ADINTEN_OFFSET 0x0c /* A/D Interrupt Enable Register */ +#define AD_ADDR0_OFFSET 0x10 /* A/D Chanel 0 Data Register */ +#define AD_ADDR1_OFFSET 0x14 /* A/D Chanel 0 Data Register */ +#define AD_ADDR2_OFFSET 0x18 /* A/D Chanel 0 Data Register */ +#define AD_ADDR3_OFFSET 0x1c /* A/D Chanel 0 Data Register */ +#define AD_ADDR4_OFFSET 0x20 /* A/D Chanel 0 Data Register */ +#define AD_ADDR5_OFFSET 0x24 /* A/D Chanel 0 Data Register */ +#define AD_ADDR6_OFFSET 0x28 /* A/D Chanel 0 Data Register */ +#define AD_ADDR7_OFFSET 0x2c /* A/D Chanel 0 Data Register */ +#define AD_ADSTAT_OFFSET 0x30 /* A/D Status Register */ + +/* Digital to Analog (DAC) Base Address */ + +#define DAC_BASE_ADDR 0xE006C000 + +/* Digital to Analog (DAC) reister offset */ + +//#define DACR_OFFSET 0x00 + +/* SPI0 register offsets */ + +#define SPI0_BASE_ADDR 0xE0020000 + +#define SPI0_CR_OFFSET 0x00 /* Control Register */ +#define SPI0_SR_OFFSET 0x04 /* Status Register */ +#define SPI0_DR_OFFSET 0x08 /* Data Register */ +#define SPI0_CCR_OFFSET 0x0c /* Clock Counter Register */ +#define SPI0_INTF_OFFSET 0x1c /* Interrupt Flag Register */ + +/* SPI1 register offsets */ + +//~ #define SPI1_CR0_OFFSET 0x00 /* Control Register 0 */ +//~ #define SPI1_CR1_OFFSET 0x04 /* Control Register 1 */ +//~ #define SPI1_DR_OFFSET 0x08 /* Data Register */ +//~ #define SPI1_SR_OFFSET 0x0c /* Status Register */ +//~ #define SPI1_CPSR_OFFSET 0x10 /* Clock Pre-Scale Regisrer */ +//~ #define SPI1_IMSC_OFFSET 0x14 /* Interrupt Mask Set and Clear Register */ +//~ #define SPI1_RIS_OFFSET 0x18 /* Raw Interrupt Status Register */ +//~ #define SPI1_MIS_OFFSET 0x1c /* Masked Interrupt Status Register */ +//~ #define SPI1_ICR_OFFSET 0x20 /* Interrupt Clear Register */ + +/* SSP Base Addresses */ + +#define SSP0_BASE_ADDR 0xE0068000 +#define SSP1_BASE_ADDR 0xE0030000 + +/* SSP 0/1 register offsets */ + +#define SSP_CR0_OFFSET 0x00 /* Control Register 0 */ +#define SSP_CR1_OFFSET 0x04 /* Control Register 1 */ +#define SSP_DR_OFFSET 0x08 /* Data Register */ +#define SSP_SR_OFFSET 0x0C /* Status Register*/ +#define SSP_CPSR_OFFSET 0x10 /* Clock Prescale Register */ +#define SSP_IMSC_OFFSET 0x14 /* Interrupt Mask Set/Clear Register */ +#define SSP_RIS_OFFSET 0x18 /* Raw Interrupt Register */ +#define SSP_MIS_OFFSET 0x1C /* Masked Interrupt Status Register */ +#define SSP_ICR_OFFSET 0x20 /* Interrupt Clear Register */ +#define SSP_DMACR_OFFSET 0x24 /* DMA Control Register */ + +/* Real Time Clock Base Address */ + +#define RTC_BASE_ADDR 0xE0024000 + +/* RTC register offsets */ + +#define RTC_ILR_OFFSET 0x00 /* Interrupt Location Register */ +#define RTC_CTC_OFFSET 0x04 /* Clock Tick Counter */ +#define RTC_CCR_OFFSET 0x08 /* Clock Control Register */ +#define RTC_CIIR_OFFSET 0x0c /* Counter Increment Interrupt Register */ +#define RTC_AMR_OFFSET 0x10 /* Alarm Mask Register */ +#define RTC_CTIME0_OFFSET 0x14 /* Consolidated Time Register 0 */ +#define RTC_CTIME1_OFFSET 0x18 /* Consolidated Time Register 1 */ +#define RTC_CTIME2_OFFSET 0x1c /* Consolidated Time Register 2 */ +#define RTC_SEC_OFFSET 0x20 /* Seconds Register */ +#define RTC_MIN_OFFSET 0x24 /* Minutes Register */ +#define RTC_HOUR_OFFSET 0x28 /* Hours Register */ +#define RTC_DOM_OFFSET 0x2c /* Day Of Month Register */ +#define RTC_DOW_OFFSET 0x30 /* Day Of Week Register */ +#define RTC_DOY_OFFSET 0x34 /* Day Of Year Register */ +#define RTC_MONTH_OFFSET 0x38 /* Months Register */ +#define RTC_YEAR_OFFSET 0x3c /* Years Register */ + +#define RTC_ALSEC_OFFSET 0x60 /* Alarm Seconds Register */ +#define RTC_ALMIN_OFFSET 0x64 /* Alarm Minutes Register */ +#define RTC_ALHOUR_OFFSET 0x68 /* Alarm Hours Register */ +#define RTC_ALDOM_OFFSET 0x6c /* Alarm Day Of Month Register */ +#define RTC_ALDOW_OFFSET 0x70 /* Alarm Day Of Week Register */ +#define RTC_ALDOY_OFFSET 0x74 /* Alarm Day Of Year Register */ +#define RTC_ALMON_OFFSET 0x78 /* Alarm Months Register */ +#define RTC_ALYEAR_OFFSET 0x7c /* Alarm Years Register */ +#define RTC_PREINT_OFFSET 0x80 /* Prescale Value Register (integer) */ +#define RTC_PREFRAC_OFFSET 0x84 /* Prescale Value Register (fraction) */ + +/* Watchdog */ +//~ WDG_BASE_ADDR 0xE0000000 + +#define WDMOD_OFFSET 0x00 +#define WDTC_OFFSET 0x04 +#define WDFEED_OFFSET 0x08 +#define WDTV_OFFSET 0x0C +#define WDCLKSEL_OFFSET 0x10 + +/* CAN CONTROLLERS AND ACCEPTANCE FILTER */ +//~ CAN_ACCEPT_BASE_ADDR 0xE003C000 + +#define CAN_AFMR_OFFSET 0x00 +#define CAN_SFF_SA_OFFSET 0x04 +#define CAN_SFF_GRP_SA_OFFSET 0x08 +#define CAN_EFF_SA_OFFSET 0x0C +#define CAN_EFF_GRP_SA_OFFSET 0x10 +#define CAN_EOT_OFFSET 0x14 +#define CAN_LUT_ERR_ADR_OFFSET 0x18 +#define CAN_LUT_ERR_OFFSET 0x1C + +//~ CAN_COMMON_BASE_ADDR 0xE0040000 +#define CAN_TX_SR_OFFSET 0x00 +#define CAN_RX_SR_OFFSET 0x04 +#define CAN_MSR_OFFSET 0x08 + +//~ CAN1_BASE_ADDR 0xE0044000 +#define CAN1MOD_OFFSET 0x00 +#define CAN1CMR_OFFSET 0x04 +#define CAN1GSR_OFFSET 0x08 +#define CAN1ICR_OFFSET 0x0C +#define CAN1IER_OFFSET 0x10 +#define CAN1BTR_OFFSET 0x14 +#define CAN1EWL_OFFSET 0x18 +#define CAN1SR_OFFSET 0x1C +#define CAN1RFS_OFFSET 0x20 +#define CAN1RID_OFFSET 0x24 +#define CAN1RDA_OFFSET 0x28 +#define CAN1RDB_OFFSET 0x2C + +#define CAN1TFI1_OFFSET 0x30 +#define CAN1TID1_OFFSET 0x34 +#define CAN1TDA1_OFFSET 0x38 +#define CAN1TDB1_OFFSET 0x3C +#define CAN1TFI2_OFFSET 0x40 +#define CAN1TID2_OFFSET 0x44 +#define CAN1TDA2_OFFSET 0x48 +#define CAN1TDB2_OFFSET 0x4C +#define CAN1TFI3_OFFSET 0x50 +#define CAN1TID3_OFFSET 0x54 +#define CAN1TDA3_OFFSET 0x58 +#define CAN1TDB3_OFFSET 0x5C + +//~ CAN2_BASE_ADDR 0xE0048000 +#define CAN2MOD_OFFSET 0x00 +#define CAN2CMR_OFFSET 0x04 +#define CAN2GSR_OFFSET 0x08 +#define CAN2ICR_OFFSET 0x0C +#define CAN2IER_OFFSET 0x10 +#define CAN2BTR_OFFSET 0x14 +#define CAN2EWL_OFFSET 0x18 +#define CAN2SR_OFFSET 0x1C +#define CAN2RFS_OFFSET 0x20 +#define CAN2RID_OFFSET 0x24 +#define CAN2RDA_OFFSET 0x28 +#define CAN2RDB_OFFSET 0x2C + +#define CAN2TFI1_OFFSET 0x30 +#define CAN2TID1_OFFSET 0x34 +#define CAN2TDA1_OFFSET 0x38 +#define CAN2TDB1_OFFSET 0x3C +#define CAN2TFI2_OFFSET 0x40 +#define CAN2TID2_OFFSET 0x44 +#define CAN2TDA2_OFFSET 0x48 +#define CAN2TDB2_OFFSET 0x4C +#define CAN2TFI3_OFFSET 0x50 +#define CAN2TID3_OFFSET 0x54 +#define CAN2TDA3_OFFSET 0x58 +#define CAN2TDB3_OFFSET 0x5C + + +/* MultiMedia Card Interface(MCI) ontroller */ +//~ MCI_BASE_ADDR 0xE008C000 + +#define MCI_POWER_OFFSET 0x00 +#define MCI_CLOCK_OFFSET 0x04 +#define MCI_ARGUMENT_OFFSET 0x08 +#define MCI_COMMAND_OFFSET 0x0C +#define MCI_RESP_CMD_OFFSET 0x10 +#define MCI_RESP0_OFFSET 0x14 +#define MCI_RESP1_OFFSET 0x18 +#define MCI_RESP2_OFFSET 0x1C +#define MCI_RESP3_OFFSET 0x20 +#define MCI_DATA_TMR_OFFSET 0x24 +#define MCI_DATA_LEN_OFFSET 0x28 +#define MCI_DATA_CTRL_OFFSET 0x2C +#define MCI_DATA_CNT_OFFSET 0x30 +#define MCI_STATUS_OFFSET 0x34 +#define MCI_CLEAR_OFFSET 0x38 +#define MCI_MASK0_OFFSET 0x3C +#define MCI_MASK1_OFFSET 0x40 +#define MCI_FIFO_CNT_OFFSET 0x48 +#define MCI_FIFO_OFFSET 0x80 + + +/* I2S Interface Controller (I2S) */ +//~ I2S_BASE_ADDR 0xE0088000 +#define I2S_DAO_OFFSET 0x00 +#define I2S_DAI_OFFSET 0x04 +#define I2S_TX_FIFO_OFFSET 0x08 +#define I2S_RX_FIFO_OFFSET 0x0C +#define I2S_STATE_OFFSET 0x10 +#define I2S_DMA1_OFFSET 0x14 +#define I2S_DMA2_OFFSET 0x18 +#define I2S_IRQ_OFFSET 0x1C +#define I2S_TXRATE_OFFSET 0x20 +#define I2S_RXRATE_OFFSET 0x24 + +/* General-purpose DMA Controller */ +/* DMA_BASE_ADDR 0xFFE04000 */ + +#define GPDMA_INT_STAT_OFFSET 0x4000 +#define GPDMA_INT_TCSTAT_OFFSET 0x4004 +#define GPDMA_INT_TCCLR_OFFSET 0x4008 +#define GPDMA_INT_ERR_STAT_OFFSET 0x400C +#define GPDMA_INT_ERR_CLR_OFFSET 0x4010 +#define GPDMA_RAW_INT_TCSTAT_OFFSET 0x4014 +#define GPDMA_RAW_INT_ERR_STAT_OFFSET 0x4018 +#define GPDMA_ENABLED_CHNS_OFFSET 0x401C +#define GPDMA_SOFT_BREQ_OFFSET 0x4020 +#define GPDMA_SOFT_SREQ_OFFSET 0x4024 +#define GPDMA_SOFT_LBREQ_OFFSET 0x4028 +#define GPDMA_SOFT_LSREQ_OFFSET 0x402C +#define GPDMA_CONFIG_OFFSET 0x4030 +#define GPDMA_SYNC_OFFSET 0x0x4034 + +/* DMA channel 0 registers */ + +#define GPDMA_CH0_SRC_OFFSET 0x4100 +#define GPDMA_CH0_DEST_OFFSET 0x4104 +#define GPDMA_CH0_LLI_OFFSET 0x4108 +#define GPDMA_CH0_CTRL_OFFSET 0x410C +#define GPDMA_CH0_CFG_OFFSET 0x4110 + +/* DMA channel 1 registers */ + +#define GPDMA_CH1_SRC_OFFSET 0x4120 +#define GPDMA_CH1_DEST_OFFSET 0x4124 +#define GPDMA_CH1_LLI_OFFSET 0x4128 +#define GPDMA_CH1_CTRL_OFFSET 0x412C +#define GPDMA_CH1_CFG_OFFSET 0x4130 + +/* USB Controller */ + +#define USB_INT_BASE_ADDR 0xE01FC1C0 +#define USB_BASE_ADDR 0xFFE0C200 /* USB Base Address */ + +/* USB Device Interrupt Registers */ + +#define USB_INT_STAT_OFFSET 0x00 +#define USB_INT_EN_OFFSET 0x04 +#define USB_INT_CLR_OFFSET 0x08 +#define USB_INT_SET_OFFSET 0x0C +#define USB_INT_PRIO_OFFSET 0x2C + +/* USB Device Endpoint Interrupt Registers */ +#define USB_EP_INT_STAT_OFFSET 0x30 +#define USB_EP_INT_EN_OFFSET 0x34 +#define USB_EP_INT_CLR_OFFSET 0x38 +#define USB_EP_INT_SET_OFFSET 0x3C +#define USB_EP_INT_PRIO_OFFSET 0x40 + +/* USB Device Endpoint Realization Registers */ + +#define USB_REALIZE_EP_OFFSET 0x44 +#define USB_EP_INDEX_OFFSET 0x48 +#define USB_MAXPACKET_SIZE_OFFSET 0x4C + +/* USB Device Command Reagisters */ + +#define USB_CMD_CODE_OFFSET 0x10 +#define USB_CMD_DATA_OFFSET 0x14 + +/* USB Device Data Transfer Registers */ + +#define USB_RX_DATA_OFFSET 0x18 +#define USB_TX_DATA_OFFSET 0x1C +#define USB_RX_PLENGTH_OFFSET 0x20 +#define USB_TX_PLENGTH_OFFSET 0x24 +#define USB_USB_CTRL_OFFSET 0x28 + +/* USB Device DMA Registers */ + +#define USB_DMA_REQ_STAT_OFFSET 0x50 +#define USB_DMA_REQ_CLR_OFFSET 0x54 +#define USB_DMA_REQ_SET_OFFSET 0x58 +#define USB_UDCA_HEAD_OFFSET 0x80 +#define USB_EP_DMA_STAT_OFFSET 0x84 +#define USB_EP_DMA_EN_OFFSET 0x88 +#define USB_EP_DMA_DIS_OFFSET 0x8C +#define USB_DMA_INT_STAT_OFFSET 0x90 +#define USB_DMA_INT_EN_OFFSET 0x94 +#define USB_EOT_INT_STAT_OFFSET 0xA0 +#define USB_EOT_INT_CLR_OFFSET 0xA4 +#define USB_EOT_INT_SET_OFFSET 0xA8 +#define USB_NDD_REQ_INT_STAT_OFFSET 0xAC +#define USB_NDD_REQ_INT_CLR_OFFSET 0xB0 +#define USB_NDD_REQ_INT_SET_OFFSET 0xB4 +#define USB_SYS_ERR_INT_STAT_OFFSET 0xB8 +#define USB_SYS_ERR_INT_CLR_OFFSET 0xBC +#define USB_SYS_ERR_INT_SET_OFFSET 0xC0 + +/* System Control Block(SCB) modules include Memory Accelerator Module, + * Phase Locked Loop, VPB divider, Power Control, External Interrupt, + * Reset, and Code Security/Debugging + */ + +#define SCB_BASE_ADDR 0xE01FC000 + +/* Memory Accelerator Module (MAM) Regiser */ + +#define SCB_MAMCR (*(volatile uint32_t*)(0xE01FC000)) +#define SCB_MAMTIM (*(volatile uint32_t*)(0xE01FC004)) +#define SCB_MEMMAP (*(volatile uint32_t*)(0xE01FC040)) + +/* Phase Locked Loop (PLL) Register */ + +#define SCB_PLLCON (*(volatile uint32_t*)(0xE01FC080)) +#define SCB_PLLCFG (*(volatile uint32_t*)(0xE01FC084)) +#define SCB_PLLSTAT (*(volatile uint32_t*)(0xE01FC088)) +#define SCB_PLLFEED (*(volatile uint32_t*)(0xE01FC08C)) + +/* Power Control register */ + +#define SCB_PCON (*(volatile uint32_t*)(0xE01FC0C0)) +#define SCB_PCONP (*(volatile uint32_t*)(0xE01FC0C4)) +#define SCB_PCONP_OFFSET 0x0C4 + +/* Clock Divider Register */ + +#define SCB_CCLKCFG (*(volatile uint32_t*)(0xE01FC104)) +#define SCB_USBCLKCFG (*(volatile uint32_t*)(0xE01FC108)) +#define SCB_CLKSRCSEL (*(volatile uint32_t*)(0xE01FC10C)) +#define SCB_PCLKSEL0 (*(volatile uint32_t*)(0xE01FC1A8)) +#define SCB_PCLKSEL1 (*(volatile uint32_t*)(0xE01FC1AC)) +#define SCB_PCLKSEL0_OFFSET (0x1A8) +#define SCB_PCLKSEL1_OFFSET (0x1AC) + +/* External Interrupt register */ + +#define SCB_EXTINT (*(volatile uint32_t*)(0xE01FC140)) +#define SCB_INTWAKE (*(volatile uint32_t*)(0xE01FC144)) +#define SCB_EXTMODE (*(volatile uint32_t*)(0xE01FC148)) +#define SCB_EXTPOLAR (*(volatile uint32_t*)(0xE01FC14C)) + +/* Reser Source Identification register */ + +#define SCB_RSIR (*(volatile uint32_t*)(0xE01FC180)) + +/* RSID, code security protection */ + +#define SCB_CSPR (*(volatile uint32_t*)(0xE01FC184)) + +#define SCB_AHBCFG1 (*(volatile uint32_t*)(0xE01FC188)) +#define SCB_AHBCFG2 (*(volatile uint32_t*)(0xE01FC18C)) + +/* System Controls and Status Register */ + +#define SCB_SCS (*(volatile uint32_t*)(0xE01FC1A0)) + +//~ /* External Memory Controller (EMC) definitions */ + +/* MPMC(EMC) registers, note: all the external memory controller(EMC) registers +are for LPC24xx only. */ +#define STATIC_MEM0_BASE 0x80000000 +#define STATIC_MEM1_BASE 0x81000000 +#define STATIC_MEM2_BASE 0x82000000 +#define STATIC_MEM3_BASE 0x83000000 + +#define DYNAMIC_MEM0_BASE 0xA0000000 +#define DYNAMIC_MEM1_BASE 0xB0000000 +#define DYNAMIC_MEM2_BASE 0xC0000000 +#define DYNAMIC_MEM3_BASE 0xD0000000 + +/* External Memory Controller (EMC) */ +//~ #define EMC_BASE_ADDR 0xFFE08000 + +#define EMC_CTRL_OFFSET 0x000 +#define EMC_STAT_OFFSET 0x004 +#define EMC_CONFIG_OFFSET 0x008 + +/* Dynamic RAM access registers */ +#define EMC_DYN_CTRL_OFFSET 0x020 +#define EMC_DYN_RFSH_OFFSET 0x024 +#define EMC_DYN_RD_CFG_OFFSET 0x028 +#define EMC_DYN_RP_OFFSET 0x030 +#define EMC_DYN_RAS_OFFSET 0x034 +#define EMC_DYN_SREX_OFFSET 0x038 +#define EMC_DYN_APR_OFFSET 0x03C +#define EMC_DYN_DAL_OFFSET 0x040 +#define EMC_DYN_WR_OFFSET 0x044 +#define EMC_DYN_RC_OFFSET 0x048 +#define EMC_DYN_RFC_OFFSET 0x04C +#define EMC_DYN_XSR_OFFSET 0x050 +#define EMC_DYN_RRD_OFFSET 0x054 +#define EMC_DYN_MRD_OFFSET 0x058 + +#define EMC_DYN_CFG0_OFFSET 0x100 +#define EMC_DYN_RASCAS0_OFFSET 0x104 +#define EMC_DYN_CFG1_OFFSET 0x140 +#define EMC_DYN_RASCAS1_OFFSET 0x144 +#define EMC_DYN_CFG2_OFFSET 0x160 +#define EMC_DYN_RASCAS2_OFFSET 0x164 +#define EMC_DYN_CFG3_OFFSET 0x180 +#define EMC_DYN_RASCAS3_OFFSET 0x184 + +/* static RAM access registers */ + +#define EMC_STA_CFG0_OFFSET 0x200 +#define EMC_STA_WAITWEN0_OFFSET 0x204 +#define EMC_STA_WAITOEN0_OFFSET 0x208 +#define EMC_STA_WAITRD0_OFFSET 0x20C +#define EMC_STA_WAITPAGE0_OFFSET 0x210 +#define EMC_STA_WAITWR0_OFFSET 0x214 +#define EMC_STA_WAITTURN0_OFFSET 0x218 + +#define EMC_STA_CFG1_OFFSET 0x220 +#define EMC_STA_WAITWEN1_OFFSET 0x224 +#define EMC_STA_WAITOEN1_OFFSET 0x228 +#define EMC_STA_WAITRD1_OFFSET 0x22C +#define EMC_STA_WAITPAGE1_OFFSET 0x230 +#define EMC_STA_WAITWR1_OFFSET 0x234 +#define EMC_STA_WAITTURN1_OFFSET 0x238 + +#define EMC_STA_CFG2_OFFSET 0x240 +#define EMC_STA_WAITWEN2_OFFSET 0x244 +#define EMC_STA_WAITOEN2_OFFSET 0x248 +#define EMC_STA_WAITRD2_OFFSET 0x24C +#define EMC_STA_WAITPAGE2_OFFSET 0x250 +#define EMC_STA_WAITWR2_OFFSET 0x254 +#define EMC_STA_WAITTURN2_OFFSET 0x258 + +#define EMC_STA_CFG3_OFFSET 0x260 +#define EMC_STA_WAITWEN3_OFFSET 0x264 +#define EMC_STA_WAITOEN3_OFFSET 0x268 +#define EMC_STA_WAITRD3_OFFSET 0x26C +#define EMC_STA_WAITPAGE3_OFFSET 0x270 +#define EMC_STA_WAITWR3_OFFSET 0x274 +#define EMC_STA_WAITTURN3_OFFSET 0x278 + +#define EMC_STA_EXT_WAIT_OFFSET 0x880 + +/* GPIO register offsets WORD access */ + +#define GPIO0_PIN_OFFSET 0x00 /* Pin Value Register */ +#define GPIO0_SET_OFFSET 0x04 /* Pin Output Set Register */ +#define GPIO0_DIR_OFFSET 0x08 /* Pin Direction Register */ +#define GPIO0_CLR_OFFSET 0x0c /* Pin Output Clear Register */ +#define GPIO1_PIN_OFFSET 0x10 /* Pin Value Register */ +#define GPIO1_SET_OFFSET 0x14 /* Pin Output Set Register */ +#define GPIO1_DIR_OFFSET 0x18 /* Pin Direction Register */ +#define GPIO1_CLR_OFFSET 0x1c /* Pin Output Clear Register */ + +/* Fast I0 Base Address */ + +#define FIO_BASE_ADDR 0x3FFFC000 + +/* FIO register offsets WORD access */ + +#define FIO0_DIR_OFFSET 0x00 /* Fast GPIO Port Direction Register */ +#define FIO0_MASK_OFFSET 0x10 /* Fast GPIO Mask Register */ +#define FIO0_PIN_OFFSET 0x14 /* Fast GPIO Pin Value Register */ +#define FIO0_SET_OFFSET 0x18 /* Fast GPIO Port Output Set Register */ +#define FIO0_CLR_OFFSET 0x1c /* Fast GPIO Port Output Clear Register */ + +#define FIO1_DIR_OFFSET 0x20 /* Fast GPIO Port Direction Register */ +#define FIO1_MASK_OFFSET 0x30 /* Fast GPIO Mask Register */ +#define FIO1_PIN_OFFSET 0x34 /* Fast GPIO Pin Value Register */ +#define FIO1_SET_OFFSET 0x38 /* Fast GPIO Port Output Set Register */ +#define FIO1_CLR_OFFSET 0x3c /* Fast GPIO Port Output Clear Register */ + +#define FIO2_DIR_OFFSET 0x40 /* Fast GPIO Port Direction Register */ +#define FIO2_MASK_OFFSET 0x50 /* Fast GPIO Mask Register */ +#define FIO2_PIN_OFFSET 0x54 /* Fast GPIO Pin Value Register */ +#define FIO2_SET_OFFSET 0x58 /* Fast GPIO Port Output Set Register */ +#define FIO2_CLR_OFFSET 0x5c /* Fast GPIO Port Output Clear Register */ + +#define FIO3_DIR_OFFSET 0x60 /* Fast GPIO Port Direction Register */ +#define FIO3_MASK_OFFSET 0x70 /* Fast GPIO Mask Register */ +#define FIO3_PIN_OFFSET 0x74 /* Fast GPIO Pin Value Register */ +#define FIO3_SET_OFFSET 0x78 /* Fast GPIO Port Output Set Register */ +#define FIO3_CLR_OFFSET 0x7c /* Fast GPIO Port Output Clear Register */ + +#define FIO4_DIR_OFFSET 0x80 /* Fast GPIO Port Direction Register */ +#define FIO4_MASK_OFFSET 0x90 /* Fast GPIO Mask Register */ +#define FIO4_PIN_OFFSET 0x94 /* Fast GPIO Pin Value Register */ +#define FIO4_SET_OFFSET 0x98 /* Fast GPIO Port Output Set Register */ +#define FIO4_CLR_OFFSET 0x9c /* Fast GPIO Port Output Clear Register */ + +/* FIO register offsets HALF-WORD access */ + +#define FIO0MASKL_OFFSET 0x10 /* Fast IO Mask Lower HALF-WORD */ +#define FIO1MASKL_OFFSET 0x30 +#define FIO2MASKL_OFFSET 0x50 +#define FIO3MASKL_OFFSET 0x70 +#define FIO4MASKL_OFFSET 0x90 + +#define FIO0MASKU_OFFSET 0x12 /* Fast IO Mask Upper HALF-WORD */ +#define FIO1MASKU_OFFSET 0x32 +#define FIO2MASKU_OFFSET 0x52 +#define FIO3MASKU_OFFSET 0x72 +#define FIO4MASKU_OFFSET 0x92 + +#define FIO0PINL_OFFSET 0x14 /* Fast IOPIN Lower HALF-WORD */ +#define FIO1PINL_OFFSET 0x34 +#define FIO2PINL_OFFSET 0x54 +#define FIO3PINL_OFFSET 0x74 +#define FIO4PINL_OFFSET 0x94 + +#define FIO0PINU_OFFSET 0x16 /* Fast IOPIN Upper HALF-WORD */ +#define FIO1PINU_OFFSET 0x36 +#define FIO2PINU_OFFSET 0x56 +#define FIO3PINU_OFFSET 0x76 +#define FIO4PINU_OFFSET 0x96 + +#define FIO0SETL_OFFSET 0x18 /* Fast IOSET Lower HALF-WORD */ +#define FIO1SETL_OFFSET 0x38 +#define FIO2SETL_OFFSET 0x58 +#define FIO3SETL_OFFSET 0x78 +#define FIO4SETL_OFFSET 0x98 + +#define FIO0SETU_OFFSET 0x1A /* Fast IOSET Upper HALF-WORD */ +#define FIO1SETU_OFFSET 0x3A +#define FIO2SETU_OFFSET 0x5A +#define FIO3SETU_OFFSET 0x7A +#define FIO4SETU_OFFSET 0x9A + +#define FIO0CLRL_OFFSET 0x1C /* Fast IOCLR Lower HALF-WORD */ +#define FIO1CLRL_OFFSET 0x3C +#define FIO2CLRL_OFFSET 0x5C +#define FIO3CLRL_OFFSET 0x7C +#define FIO4CLRL_OFFSET 0x9C + +#define FIO0CLRU_OFFSET 0x1E /* Fast IOCLR Upper HALF-WORD */ +#define FIO1CLRU_OFFSET 0x3E +#define FIO2CLRU_OFFSET 0x5E +#define FIO3CLRU_OFFSET 0x7E +#define FIO4CLRU_OFFSET 0x9E + +#define FIO0DIRL_OFFSET 0x00 /* Fast IODIR Lower HALF-WORD */ +#define FIO1DIRL_OFFSET 0x20 +#define FIO2DIRL_OFFSET 0x40 +#define FIO3DIRL_OFFSET 0x60 +#define FIO4DIRL_OFFSET 0x80 + +#define FIO0DIRU_OFFSET 0x02 /* Fast IODIR Upper HALF-WORD */ +#define FIO1DIRU_OFFSET 0x22 +#define FIO2DIRU_OFFSET 0x42 +#define FIO3DIRU_OFFSET 0x62 +#define FIO4DIRU_OFFSET 0x82 + +/* FIO register offsets BYTE access */ + +#define FIO0DIR0_OFFSET 0x00 +#define FIO1DIR0_OFFSET 0x20 +#define FIO2DIR0_OFFSET 0x40 +#define FIO3DIR0_OFFSET 0x60 +#define FIO4DIR0_OFFSET 0x80 + +#define FIO0DIR1_OFFSET 0x01 +#define FIO1DIR1_OFFSET 0x21 +#define FIO2DIR1_OFFSET 0x41 +#define FIO3DIR1_OFFSET 0x61 +#define FIO4DIR1_OFFSET 0x81 + +#define FIO0DIR2_OFFSET 0x02 +#define FIO1DIR2_OFFSET 0x22 +#define FIO2DIR2_OFFSET 0x42 +#define FIO3DIR2_OFFSET 0x62 +#define FIO4DIR2_OFFSET 0x82 + +#define FIO0DIR3_OFFSET 0x03 +#define FIO1DIR3_OFFSET 0x23 +#define FIO2DIR3_OFFSET 0x43 +#define FIO3DIR3_OFFSET 0x63 +#define FIO4DIR3_OFFSET 0x83 + +#define FIO0MASK0_OFFSET 0x10 +#define FIO1MASK0_OFFSET 0x30 +#define FIO2MASK0_OFFSET 0x50 +#define FIO3MASK0_OFFSET 0x70 +#define FIO4MASK0_OFFSET 0x90 + +#define FIO0MASK1_OFFSET 0x11 +#define FIO1MASK1_OFFSET 0x21 +#define FIO2MASK1_OFFSET 0x51 +#define FIO3MASK1_OFFSET 0x71 +#define FIO4MASK1_OFFSET 0x91 + +#define FIO0MASK2_OFFSET 0x12 +#define FIO1MASK2_OFFSET 0x32 +#define FIO2MASK2_OFFSET 0x52 +#define FIO3MASK2_OFFSET 0x72 +#define FIO4MASK2_OFFSET 0x92 + +#define FIO0MASK3_OFFSET 0x13 +#define FIO1MASK3_OFFSET 0x33 +#define FIO2MASK3_OFFSET 0x53 +#define FIO3MASK3_OFFSET 0x73 +#define FIO4MASK3_OFFSET 0x93 + +#define FIO0PIN0_OFFSET 0x14 +#define FIO1PIN0_OFFSET 0x34 +#define FIO2PIN0_OFFSET 0x54 +#define FIO3PIN0_OFFSET 0x74 +#define FIO4PIN0_OFFSET 0x94 + +#define FIO0PIN1_OFFSET 0x15 +#define FIO1PIN1_OFFSET 0x25 +#define FIO2PIN1_OFFSET 0x55 +#define FIO3PIN1_OFFSET 0x75 +#define FIO4PIN1_OFFSET 0x95 + +#define FIO0PIN2_OFFSET 0x16 +#define FIO1PIN2_OFFSET 0x36 +#define FIO2PIN2_OFFSET 0x56 +#define FIO3PIN2_OFFSET 0x76 +#define FIO4PIN2_OFFSET 0x96 + +#define FIO0PIN3_OFFSET 0x17 +#define FIO1PIN3_OFFSET 0x37 +#define FIO2PIN3_OFFSET 0x57 +#define FIO3PIN3_OFFSET 0x77 +#define FIO4PIN3_OFFSET 0x97 + +#define FIO0SET0_OFFSET 0x18 +#define FIO1SET0_OFFSET 0x38 +#define FIO2SET0_OFFSET 0x58 +#define FIO3SET0_OFFSET 0x78 +#define FIO4SET0_OFFSET 0x98 + +#define FIO0SET1_OFFSET 0x19 +#define FIO1SET1_OFFSET 0x29 +#define FIO2SET1_OFFSET 0x59 +#define FIO3SET1_OFFSET 0x79 +#define FIO4SET1_OFFSET 0x99 + +#define FIO0SET2_OFFSET 0x1A +#define FIO1SET2_OFFSET 0x3A +#define FIO2SET2_OFFSET 0x5A +#define FIO3SET2_OFFSET 0x7A +#define FIO4SET2_OFFSET 0x9A + +#define FIO0SET3_OFFSET 0x1B +#define FIO1SET3_OFFSET 0x3B +#define FIO2SET3_OFFSET 0x5B +#define FIO3SET3_OFFSET 0x7B +#define FIO4SET3_OFFSET 0x9B + +#define FIO0CLR0_OFFSET 0x1C +#define FIO1CLR0_OFFSET 0x3C +#define FIO2CLR0_OFFSET 0x5C +#define FIO3CLR0_OFFSET 0x7C +#define FIO4CLR0_OFFSET 0x9C + +#define FIO0CLR1_OFFSET 0x1D +#define FIO1CLR1_OFFSET 0x2D +#define FIO2CLR1_OFFSET 0x5D +#define FIO3CLR1_OFFSET 0x7D +#define FIO4CLR1_OFFSET 0x9D + +#define FIO0CLR2_OFFSET 0x1E +#define FIO1CLR2_OFFSET 0x3E +#define FIO2CLR2_OFFSET 0x5E +#define FIO3CLR2_OFFSET 0x7E +#define FIO4CLR2_OFFSET 0x9E + +#define FIO0CLR3_OFFSET 0x1F +#define FIO1CLR3_OFFSET 0x3F +#define FIO2CLR3_OFFSET 0x5F +#define FIO3CLR3_OFFSET 0x7F +#define FIO4CLR3_OFFSET 0x9F + +/* Vectored Interrupt Controller (VIC) register offsets */ + +#define VIC_IRQSTATUS_OFFSET 0x000 /* R: IRQ Status Register */ +#define VIC_FIQSTATUS_OFFSET 0x004 /* R: FIQ Status Register */ +#define VIC_RAWINTR_OFFSET 0x008 /* R: Raw Interrupt Status Register */ +#define VIC_INTSELECT_OFFSET 0x00c /* RW: Interrupt Select Register */ +#define VIC_INTENABLE_OFFSET 0x010 /* RW: Interrupt Enable Register */ +#define VIC_INTENCLEAR_OFFSET 0x014 /* W: Interrupt Enable Clear Register */ +#define VIC_SOFTINT_OFFSET 0x018 /* RW: Software Interrupt Register */ +#define VIC_SOFTINTCLEAR_OFFSET 0x01c /* W: Software Interrupt Clear Register */ +#define VIC_PROTECTION_OFFSET 0x020 /* Protection Enable Register */ +#define VIC_PRIORITY_MASK_OFFSET 0x024 /* Priority Mask Register */ + +//~ #define LPC23XX_VIC_BASE 0xfffff000 /* Vectored Interrupt Controller (VIC) Base */ +#define VIC_ADDRESS_OFFSET 0xF00 /* RW: Vector Address Register */ + +#define VIC_VECTADDR0_OFFSET 0x100 /* RW: Vector Address 0 Register */ +#define VIC_VECTADDR1_OFFSET 0x104 /* RW: Vector Address 1 Register */ +#define VIC_VECTADDR2_OFFSET 0x108 /* RW: Vector Address 2 Register */ +#define VIC_VECTADDR3_OFFSET 0x10c /* RW: Vector Address 3 Register */ +#define VIC_VECTADDR4_OFFSET 0x110 /* RW: Vector Address 4 Register */ +#define VIC_VECTADDR5_OFFSET 0x114 /* RW: Vector Address 5 Register */ +#define VIC_VECTADDR6_OFFSET 0x118 /* RW: Vector Address 6 Register */ +#define VIC_VECTADDR7_OFFSET 0x11c /* RW: Vector Address 7 Register */ +#define VIC_VECTADDR8_OFFSET 0x120 /* RW: Vector Address 8 Register */ +#define VIC_VECTADDR9_OFFSET 0x124 /* RW: Vector Address 9 Register */ +#define VIC_VECTADDR10_OFFSET 0x128 /* RW: Vector Address 10 Register */ +#define VIC_VECTADDR11_OFFSET 0x12c /* RW: Vector Address 11 Register */ +#define VIC_VECTADDR12_OFFSET 0x130 /* RW: Vector Address 12 Register */ +#define VIC_VECTADDR13_OFFSET 0x134 /* RW: Vector Address 13 Register */ +#define VIC_VECTADDR14_OFFSET 0x138 /* RW: Vector Address 14 Register */ +#define VIC_VECTADDR15_OFFSET 0x13c /* RW: Vector Address 15 Register */ +#define VIC_VECTADDR16_OFFSET 0x140 /* RW: Vector Address 16 Register */ +#define VIC_VECTADDR17_OFFSET 0x144 /* RW: Vector Address 17 Register */ +#define VIC_VECTADDR18_OFFSET 0x148 /* RW: Vector Address 18 Register */ +#define VIC_VECTADDR19_OFFSET 0x14c /* RW: Vector Address 19 Register */ +#define VIC_VECTADDR20_OFFSET 0x150 /* RW: Vector Address 20 Register */ +#define VIC_VECTADDR21_OFFSET 0x154 /* RW: Vector Address 21 Register */ +#define VIC_VECTADDR22_OFFSET 0x158 /* RW: Vector Address 22 Register */ +#define VIC_VECTADDR23_OFFSET 0x15c /* RW: Vector Address 23 Register */ +#define VIC_VECTADDR24_OFFSET 0x160 /* RW: Vector Address 24 Register */ +#define VIC_VECTADDR25_OFFSET 0x164 /* RW: Vector Address 25 Register */ +#define VIC_VECTADDR26_OFFSET 0x168 /* RW: Vector Address 26 Register */ +#define VIC_VECTADDR27_OFFSET 0x16c /* RW: Vector Address 27 Register */ +#define VIC_VECTADDR28_OFFSET 0x170 /* RW: Vector Address 28 Register */ +#define VIC_VECTADDR29_OFFSET 0x174 /* RW: Vector Address 29 Register */ +#define VIC_VECTADDR30_OFFSET 0x178 /* RW: Vector Address 30 Register */ +#define VIC_VECTADDR31_OFFSET 0x17c /* RW: Vector Address 31 Register */ + +/*VICVectPriority */ + +#define VIC_VECTPRIORITY0_OFFSET 0x200 /* RW: Vector Control 0 Register */ +#define VIC_VECTPRIORITY1_OFFSET 0x204 /* RW: Vector Control 1 Register */ +#define VIC_VECTPRIORITY2_OFFSET 0x208 /* RW: Vector Control 2 Register */ +#define VIC_VECTPRIORITY3_OFFSET 0x20c /* RW: Vector Control 3 Register */ +#define VIC_VECTPRIORITY4_OFFSET 0x210 /* RW: Vector Control 4 Register */ +#define VIC_VECTPRIORITY5_OFFSET 0x214 /* RW: Vector Control 5 Register */ +#define VIC_VECTPRIORITY6_OFFSET 0x218 /* RW: Vector Control 6 Register */ +#define VIC_VECTPRIORITY7_OFFSET 0x21c /* RW: Vector Control 7 Register */ +#define VIC_VECTPRIORITY8_OFFSET 0x220 /* RW: Vector Control 8 Register */ +#define VIC_VECTPRIORITY9_OFFSET 0x224 /* RW: Vector Control 9 Register */ +#define VIC_VECTPRIORITY10_OFFSET 0x228 /* RW: Vector Control 10 Register */ +#define VIC_VECTPRIORITY11_OFFSET 0x22c /* RW: Vector Control 11 Register */ +#define VIC_VECTPRIORITY12_OFFSET 0x230 /* RW: Vector Control 12 Register */ +#define VIC_VECTPRIORITY13_OFFSET 0x234 /* RW: Vector Control 13 Register */ +#define VIC_VECTPRIORITY14_OFFSET 0x238 /* RW: Vector Control 14 Register */ +#define VIC_VECTPRIORITY15_OFFSET 0x23c /* RW: Vector Control 15 Register */ +#define VIC_VECTPRIORITY16_OFFSET 0x240 /* RW: Vector Control 16 Register */ +#define VIC_VECTPRIORITY17_OFFSET 0x244 /* RW: Vector Control 17 Register */ +#define VIC_VECTPRIORITY18_OFFSET 0x248 /* RW: Vector Control 18 Register */ +#define VIC_VECTPRIORITY19_OFFSET 0x24c /* RW: Vector Control 19 Register */ +#define VIC_VECTPRIORITY20_OFFSET 0x250 /* RW: Vector Control 20 Register */ +#define VIC_VECTPRIORITY21_OFFSET 0x254 /* RW: Vector Control 21 Register */ +#define VIC_VECTPRIORITY22_OFFSET 0x258 /* RW: Vector Control 22 Register */ +#define VIC_VECTPRIORITY23_OFFSET 0x25c /* RW: Vector Control 23 Register */ +#define VIC_VECTPRIORITY24_OFFSET 0x260 /* RW: Vector Control 24 Register */ +#define VIC_VECTPRIORITY25_OFFSET 0x264 /* RW: Vector Control 25 Register */ +#define VIC_VECTPRIORITY26_OFFSET 0x268 /* RW: Vector Control 26 Register */ +#define VIC_VECTPRIORITY27_OFFSET 0x26c /* RW: Vector Control 27 Register */ +#define VIC_VECTPRIORITY28_OFFSET 0x270 /* RW: Vector Control 28 Register */ +#define VIC_VECTPRIORITY29_OFFSET 0x274 /* RW: Vector Control 29 Register */ +#define VIC_VECTPRIORITY30_OFFSET 0x278 /* RW: Vector Control 30 Register */ +#define VIC_VECTPRIORITY31_OFFSET 0x27c /* RW: Vector Control 31 Register */ + +/**************************************************************************************************** + * Inline Functions + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC2378_CHIP_H */ diff --git a/arch/arm/src/lpc2378/lpc2378.h b/arch/arm/src/lpc2378/lpc2378.h new file mode 100644 index 0000000000000000000000000000000000000000..0c7fccede9152d9922905f75ec11ac6ddc87c918 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc2378.h @@ -0,0 +1,70 @@ +/**************************************************************************************************** + * arch/arm/src/lpc2378/chip.h + * + * Copyright (C) 2010, 2015 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC2378_INTERNAL_H +#define _ARCH_ARM_SRC_LPC2378_INTERNAL_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +//~ #define CONFIG_VECTORED_INTERRUPTS + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ARCH_LEDS +void lpc2378_statledoff(void); +void lpc2378_statledon(void); +#endif + +#endif + +#endif /* _ARCH_ARM_SRC_LPC2378_INTERNAL_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_decodeirq.c b/arch/arm/src/lpc2378/lpc23xx_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..aca536e6651cbfdc90d61faea9ef5ff466d99a69 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_decodeirq.c @@ -0,0 +1,177 @@ +/******************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_decodeirq.c + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "lpc2378.h" +#include "lpc23xx_vic.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Private Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * up_decodeirq() and/or lpc23xx_decodeirq() + * + * Description: + * The vectored interrupt controller (VIC) takes 32 interrupt request inputs + * and programmatically assigns them into 2 categories: FIQ, vectored IRQ. + * + * - FIQs have the highest priority. There is a single FIQ vector, but multiple + * interrupt sources can be ORed to this FIQ vector. + * + * - Vectored IRQs have the middle priority. Any of the 32 interrupt sources + * can be assigned to vectored IRQs. + * + * - Non-vectored IRQs have the lowest priority. + * + * The general flow of IRQ processing is to simply read the VICAddress + * and jump to the address of the vector provided in the register. The VIC will + * provide the address of the highest priority vectored IRQ. If a non-vectored + * IRQ is requesting, the address of a default handler is provided. + * + ********************************************************************************/ + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_decodeirq(uint32_t *regs) +#else +static void lpc23xx_decodeirq(uint32_t *regs) +#endif +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + + /* Check which IRQ fires */ + + uint32_t irqbits = vic_getreg(VIC_IRQSTATUS_OFFSET) & 0xFFFFFFFF; + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; irq++) + { + if (irqbits & (uint32_t) (1 << irq)) + break; + } + + /* Verify that the resulting IRQ number is valid */ + + if (irq < NR_IRQS) /* redundant check ?? */ + { + uint32_t *savestate; + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + } + +#endif +} + +#ifdef CONFIG_VECTORED_INTERRUPTS +void up_decodeirq(uint32_t *regs) +{ + vic_vector_t vector = (vic_vector_t) vic_getreg(VIC_ADDRESS_OFFSET); + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Valid Interrupt */ + + if (vector != NULL) + { + (vector)(regs); + } +} +#endif diff --git a/arch/arm/src/lpc2378/lpc23xx_gpio.h b/arch/arm/src/lpc2378/lpc23xx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..fc920be4e96528bb6de16c59f8d0d61f8618b05a --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_gpio.h @@ -0,0 +1,71 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc231x_gpio.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC2378_LPC23XX_GPIO_H +#define _ARCH_ARM_SRC_LPC2378_LPC23XX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ +#include "chip.h" +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +#define io_getreg8(o) getreg8(LPC23XX_FIO_BASE+(o)) +#define io_getreg(r) getreg32(LPC23XX_FIO_BASE+ (r)) +#define dir_getreg8(o) getreg8(LPC23XX_FIO_BASE+(o)) +#define dir_getreg(r) getreg32(LPC23XX_FIO_BASE+ (r)) +#define dir_putreg8(v,o) putreg8((v), LPC23XX_FIO_BASE+(o)) +#define dir_putreg(v,r) putreg32((v),LPC23XX_FIO_BASE+ (r)) +#define fio_putreg8(v,o) putreg8((v), LPC23XX_FIO_BASE+(o)) +#define fio_getreg8(o) getreg8(LPC23XX_FIO_BASE+(o)) +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC2378_LPC23XX_GPIO_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_head.S b/arch/arm/src/lpc2378/lpc23xx_head.S new file mode 100644 index 0000000000000000000000000000000000000000..179b390271c02226308150de9ae423983f223189 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_head.S @@ -0,0 +1,234 @@ +/**************************************************************************** + * arch/arm/src/arm/lpc2378/lpc23xx_head.S + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010, 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arm.h" +#include "lpc2378.h" +#include "up_arch.h" +#include "lpc23xx_uart.h" +#include "lpc23xx_scb.h" +#include "lpc23xx_pinsel.h" + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Print a character on the UART to show boot status. This macro will + * modify r0, r1, r2 and r14 + */ + +#ifdef CONFIG_DEBUG + .macro showprogress, code + mov r0, #\code + bl up_lowputc + .endm +#else + .macro showprogress, code + .endm +#endif + +/***************************************************************************** + * Text + *****************************************************************************/ + + .text + +/***************************************************************************** + * Name: _vector_table + * + * Description: + * Interrrupt vector table. This must be located at the beginning + * of the memory space (at CONFIG_LPC2378_CODE_BASE). The first entry in + * the vector table is the reset vector and this is the code that + * will execute whn the processor is reset. + * + *****************************************************************************/ + + .globl _vector_table + .type _vector_table, %function +_vector_table: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lswihandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + .long 0xB8A06F58 /* 0x14: Vector checksum */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl up_vectorundefinsn + .globl up_vectorswi + .globl up_vectorprefetch + .globl up_vectordata + .globl up_vectorirq + .globl up_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long up_vectorundefinsn +.Lswihandler: + .long up_vectorswi +.Lprefetchaborthandler: + .long up_vectorprefetch +.Ldataaborthandler: + .long up_vectordata +.Lirqhandler: + .long up_vectorirq +.Lfiqhandler: + .long up_vectorfiq + .size _vector_table, . - _vector_table + +/**************************************************************************** + * OS Entry Point + ****************************************************************************/ + +/* We assume the bootloader has already initialized most of the h/w for + * us and that only leaves us having to do some os specific things + * below. + */ + .text + .globl __start + .type __start, #function +__start: + + /* Call lowlevel init C-function */ + + .extern ConfigurePLL + ldr r0, =ConfigurePLL + mov lr, pc + bx r0 + + /* First, setup initial processor mode */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT ) + msr cpsr, r0 + +/* Configure the uart so that we can get debug output as soon + * as possible. Modifies r0, r1, r2, and r14. + */ + bl up_lowsetup + + showprogress 'A' + + /* Setup system stack (and get the BSS range) */ + + adr r0, LC0 + ldmia r0, {r4, r5, sp} + + /* Clear system BSS section (Initialize with 0) */ + + mov r0, #0 +1: cmp r4, r5 + strcc r0, [r4], #4 + bcc 1b + + showprogress 'B' + + /* Copy system .data sections to new home in RAM. */ + + adr r3, LC2 + ldmia r3, {r0, r1, r2} + +2: ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 2b + + /* Perform early serial initialization */ + + mov fp, #0 +#ifdef USE_EARLYSERIALINIT + bl up_earlyserialinit + showprogress 'S' +#endif + + showprogress 'C' + showprogress '\n' + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + bl board_autoled_initialize +#endif + + /* Then jump to OS entry */ + + b os_start + + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_IDLETHREAD_STACKSIZE. The heap continues + * from there until the end of memory. See g_idle_topstack + * below. + */ + +LC0: .long _sbss + .long _ebss + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +LC2: .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata + .size __start, .-__start + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to LCO + * above. + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/lpc2378/lpc23xx_i2c.c b/arch/arm/src/lpc2378/lpc23xx_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..54efbc52c00e04c480665578692c786d0a6521c5 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_i2c.c @@ -0,0 +1,661 @@ +/**************************************************************************** + * arch/arm/src/lpc23xx/lpc23xx_i2c.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derived from arch/arm/src/lpc17xx/lpc17xx_i2c.c + * + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi (Original author) + * + * Derived from arch/arm/src/lpc31xx/lpc31_i2c.c + * + * Author: David Hewson + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc23xx_pinsel.h" +#include "lpc23xx_scb.h" +#include "lpc23xx_i2c.h" + +#if defined(CONFIG_LPC2378_I2C0) || defined(CONFIG_LPC2378_I2C1) || \ + defined(CONFIG_LPC2378_I2C2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef GPIO_I2C1_SCL +# define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 +# define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 +#endif + +#ifndef CONFIG_LPC2378_I2C0_FREQUENCY +# define CONFIG_LPC2378_I2C0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC2378_I2C1_FREQUENCY +# define CONFIG_LPC2378_I2C1_FREQUENCY 100000 +#endif + +#ifndef CONFIG_LPC2378_I2C2_FREQUENCY +# define CONFIG_LPC2378_I2C2_FREQUENCY 100000 +#endif + +#define I2C_TIMEOUT (20 * 1000/CONFIG_USEC_PER_TICK) /* 20 mS */ +#define LPC2378_I2C1_FREQUENCY 400000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct lpc2378_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* Watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ + unsigned int nmsg; /* number of transfer remaining */ + + uint16_t wrcnt; /* number of bytes sent to tx fifo */ + uint16_t rdcnt; /* number of bytes read from rx fifo */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int lpc2378_i2c_start(struct lpc2378_i2cdev_s *priv); +static void lpc2378_i2c_stop(struct lpc2378_i2cdev_s *priv); +static int lpc2378_i2c_interrupt(int irq, FAR void *context); +static void lpc2378_i2c_timeout(int argc, uint32_t arg, ...); +static void lpc2378_i2c_setfrequency(struct lpc2378_i2cdev_s *priv, + uint32_t frequency); +static void lpc2378_stopnext(struct lpc2378_i2cdev_s *priv); + +/* I2C device operations */ + +static int lpc2378_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int lpc2378_i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC2378_I2C0 +static struct lpc2378_i2cdev_s g_i2c0dev; +#endif +#ifdef CONFIG_LPC2378_I2C1 +static struct lpc2378_i2cdev_s g_i2c1dev; +#endif +#ifdef CONFIG_LPC2378_I2C2 +static struct lpc2378_i2cdev_s g_i2c2dev; +#endif + +struct i2c_ops_s lpc2378_i2c_ops = +{ + .transfer = lpc2378_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = lpc2378_i2c_reset +#endif +}; + +/**************************************************************************** + * Name: lpc2378_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void lpc2378_i2c_setfrequency(struct lpc2378_i2cdev_s *priv, + uint32_t frequency) +{ + if (frequency != priv->frequency) + { + if (frequency > 100000) + { + /* Asymetric per 400Khz I2C spec */ + + putreg32(LPC23XX_CCLK / (83 + 47) * 47 / frequency, + priv->base + I2C_SCLH_OFFSET); + putreg32(LPC23XX_CCLK / (83 + 47) * 83 / frequency, + priv->base + I2C_SCLL_OFFSET); + } + else + { + /* 50/50 mark space ratio */ + + putreg32(LPC23XX_CCLK / 100 * 50 / frequency, + priv->base + I2C_SCLH_OFFSET); + putreg32(LPC23XX_CCLK / 100 * 50 / frequency, + priv->base + I2C_SCLL_OFFSET); + } + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: lpc2378_i2c_start + * + * Description: + * Perform a I2C transfer start + * + ****************************************************************************/ + +static int lpc2378_i2c_start(struct lpc2378_i2cdev_s *priv) +{ + putreg32(I2C_CONCLR_STAC | I2C_CONCLR_SIC, + priv->base + I2C_CONCLR_OFFSET); + putreg32(I2C_CONSET_STA, priv->base + I2C_CONSET_OFFSET); + + wd_start(priv->timeout, I2C_TIMEOUT, lpc2378_i2c_timeout, 1, (uint32_t)priv); + sem_wait(&priv->wait); + + wd_cancel(priv->timeout); + + return priv->nmsg; +} + +/**************************************************************************** + * Name: lpc2378_i2c_stop + * + * Description: + * Perform a I2C transfer stop + * + ****************************************************************************/ + +static void lpc2378_i2c_stop(struct lpc2378_i2cdev_s *priv) +{ + if (priv->state != 0x38) + { + putreg32(I2C_CONSET_STO | I2C_CONSET_AA, + priv->base + I2C_CONSET_OFFSET); + } + + sem_post(&priv->wait); +} + +/**************************************************************************** + * Name: lpc2378_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void lpc2378_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc2378_i2cdev_s *priv = (struct lpc2378_i2cdev_s *)arg; + + irqstate_t flags = enter_critical_section(); + priv->state = 0xff; + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc2378_stopnext + * + * Description: + * Check if we need to issue STOP at the next message + * + ****************************************************************************/ + +static void lpc2378_stopnext(struct lpc2378_i2cdev_s *priv) +{ + priv->nmsg--; + + if (priv->nmsg > 0) + { + priv->msgs++; + putreg32(I2C_CONSET_STA, priv->base + I2C_CONSET_OFFSET); + } + else + { + lpc2378_i2c_stop(priv); + } +} + +/**************************************************************************** + * Name: lpc2378_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int lpc2378_i2c_interrupt(int irq, FAR void *context) +{ + struct lpc2378_i2cdev_s *priv; + struct i2c_msg_s *msg; + uint32_t state; + +#ifdef CONFIG_LPC2378_I2C0 + if (irq == I2C0_IRQ) + { + priv = &g_i2c0dev; + } + else +#endif +#ifdef CONFIG_LPC2378_I2C1 + if (irq == I2C1_IRQ) + { + priv = &g_i2c1dev; + } + else +#endif +#ifdef CONFIG_LPC2378_I2C2 + if (irq == I2C2_IRQ) + { + priv = &g_i2c2dev; + } + else +#endif + { + PANIC(); + } + + /* Reference UM10360 19.10.5 */ + + state = getreg32(priv->base + I2C_STAT_OFFSET); + msg = priv->msgs; + + priv->state = state; + state &= 0xf8; /* state mask, only 0xX8 is possible */ + switch (state) + { + + case 0x08: /* A START condition has been transmitted. */ + case 0x10: /* A Repeated START condition has been transmitted. */ + /* Set address */ + + putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ) ? + I2C_READADDR8(msg->addr) : + I2C_WRITEADDR8(msg->addr), priv->base + I2C_DAT_OFFSET); + + /* Clear start bit */ + + putreg32(I2C_CONCLR_STAC, priv->base + I2C_CONCLR_OFFSET); + break; + + /* Write cases */ + + case 0x18: /* SLA+W has been transmitted; ACK has been received */ + priv->wrcnt = 0; + putreg32(msg->buffer[0], priv->base + I2C_DAT_OFFSET); /* put first byte */ + break; + + case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */ + priv->wrcnt++; + + if (priv->wrcnt < msg->length) + { + putreg32(msg->buffer[priv->wrcnt], priv->base + I2C_DAT_OFFSET); /* Put next byte */ + } + else + { + lpc2378_stopnext(priv); + } + break; + + /* Read cases */ + + case 0x40: /* SLA+R has been transmitted; ACK has been received */ + priv->rdcnt = 0; + if (msg->length > 1) + { + putreg32(I2C_CONSET_AA, priv->base + I2C_CONSET_OFFSET); /* Set ACK next read */ + } + else + { + putreg32(I2C_CONCLR_AAC, priv->base + I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */ + } + break; + + case 0x50: /* Data byte has been received; ACK has been returned. */ + priv->rdcnt++; + msg->buffer[priv->rdcnt - 1] = getreg32(priv->base + I2C_DAT_OFFSET); + + if (priv->rdcnt >= (msg->length - 1)) + { + putreg32(I2C_CONCLR_AAC, priv->base + I2C_CONCLR_OFFSET); /* Do not ACK any more */ + } + break; + + case 0x58: /* Data byte has been received; NACK has been returned. */ + msg->buffer[priv->rdcnt] = getreg32(priv->base + I2C_DAT_OFFSET); + lpc2378_stopnext(priv); + break; + + default: + lpc2378_i2c_stop(priv); + break; + } + + putreg32(I2C_CONCLR_SIC, priv->base + I2C_CONCLR_OFFSET); /* clear interrupt */ + + return OK; +} + +/**************************************************************************** + * Name: lpc2378_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int lpc2378_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc2378_i2cdev_s *priv = (struct lpc2378_i2cdev_s *)dev; + int ret; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Set up for the transfer */ + + priv->wrcnt = 0; + priv->rdcnt = 0; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + lpc2378_i2c_setfrequency(priv, msgs->frequency); + + /* Perform the transfer */ + + ret = lpc2378_i2c_start(priv); + + sem_post(&priv->mutex); + return ret; +} + +/************************************************************************************ + * Name: lpc2378_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int lpc2378_i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc2378_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc2378_i2cbus_initialize(int port) +{ + struct lpc2378_i2cdev_s *priv; + + if (port > 1) + { + dbg("lpc I2C Only support 0,1\n"); + return NULL; + } + + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + +#ifdef CONFIG_LPC2378_I2C0 + if (port == 0) + { + priv = &g_i2c0dev; + priv->base = I2C0_BASE_ADDR; + priv->irqid = I2C0_IRQ; + + /* Enable clocking */ + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + regval |= PCI2C0; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCLKSEL0_OFFSET); + regval &= ~I2C0_PCLKSEL_MASK; + regval |= I2C0_PCLKSEL; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCLKSEL0_OFFSET); + + /* Pin configuration */ + + regval = getreg32(LPC23XX_PINSEL1); + regval &= ~I2C0_PINSEL_MASK ; + regval |= I2C0_PINSEL; + putreg32(regval, LPC23XX_PINSEL1); + + /* Set default frequency */ + + lpc2378_i2c_setfrequency(priv, CONFIG_LPC2378_I2C0_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC2378_I2C1 + if (port == 1) + { + priv = &g_i2c1dev; + priv->base = I2C1_BASE_ADDR; + priv->irqid = I2C1_IRQ; + + /* Enable clocking */ + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + regval |= PCI2C1; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCLKSEL1_OFFSET); + regval &= ~I2C1_PCLKSEL_MASK; + regval |= I2C1_PCLKSEL; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCLKSEL1_OFFSET); + + /* Pin configuration */ + + regval = getreg32(LPC23XX_PINSEL0); + regval &= ~I2C1_PINSEL_MASK ; + regval |= I2C1_PINSEL; + putreg32(regval, LPC23XX_PINSEL0); + + /* Set default frequency */ + + lpc2378_i2c_setfrequency(priv, CONFIG_LPC2378_I2C1_FREQUENCY); + } + else +#endif +#ifdef CONFIG_LPC2378_I2C2 + if (port == 2) + { + priv = &g_i2c2dev; + priv->base = I2C2_BASE_ADDR; + priv->irqid = I2C2_IRQ; + + /* Enable clocking */ + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + regval |= PCI2C2; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCONP_OFFSET); + + regval = getreg32(LPC23XX_SCB_BASE + SCB_PCLKSEL1_OFFSET); + regval &= ~I2C2_PCLKSEL_MASK; + regval |= I2C2_PCLKSEL; + putreg32(regval, LPC23XX_SCB_BASE + SCB_PCLKSEL1_OFFSET); + + /* Pin configuration */ + + regval = getreg32(LPC23XX_PINSEL0); + regval &= ~I2C2_PINSEL_MASK ; + regval |= I2C2_PINSEL; + putreg32(regval, LPC23XX_PINSEL0); + + /* Set default frequency */ + + lpc2378_i2c_setfrequency(priv, CONFIG_LPC2378_I2C2_FREQUENCY); + } + else +#endif + { + return NULL; + } + + leave_critical_section(flags); + + putreg32(I2C_CONSET_I2EN, priv->base + I2C_CONSET_OFFSET); + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, lpc2378_i2c_interrupt); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc2378_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc2378_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc2378_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct lpc2378_i2cdev_s *priv = (struct lpc2378_i2cdev_s *) dev; + + /* Disable I2C */ + + putreg32(I2C_CONCLRT_I2ENC, priv->base + I2C_CONCLR_OFFSET); + + /* Reset data structures */ + + sem_destroy(&priv->mutex); + sem_destroy(&priv->wait); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Disable interrupts */ + + up_disable_irq(priv->irqid); + + /* Detach Interrupt Handler */ + + irq_detach(priv->irqid); + return OK; +} + +#endif /* CONFIG_LPC2378_I2C0 || CONFIG_LPC2378_I2C1 || CONFIG_LPC2378_I2C2 */ diff --git a/arch/arm/src/lpc2378/lpc23xx_i2c.h b/arch/arm/src/lpc2378/lpc23xx_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..5658269f20ae834b3c7837825e6bee9d2a07e43d --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_i2c.h @@ -0,0 +1,193 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc23xx_i2c.h + * + * Copyright (C) 2013 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * + * Derived arch/arm/src/lpc17xx/lpc17_i2c.h + * + * Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_I2C_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* I2C Pin Configuration ************************************************************/ + +#define I2C0_PCLKSEL_MASK (0x03 << 14) +#define I2C1_PCLKSEL_MASK (0x03 << 6) +#define I2C2_PCLKSEL_MASK (0x03 << 20) +#define I2C0_PCLKSEL (0x01 << 14) +#define I2C1_PCLKSEL (0x01 << 6) +#define I2C2_PCLKSEL (0x01 << 20) + +#define I2C0_PINSEL_MASK (0x0f << 22) /* P0.27 P0.28 PINSEL1 */ +#define I2C1_PINSEL_MASK (0x0f) /* P0.0 P0.1 PINSEL0 */ +#define I2C2_PINSEL_MASK (0x0f << 22) /* P0.10 P0.11 PINSEL0 */ +#define I2C0_PINSEL (0x05 << 22) +#define I2C1_PINSEL (0x0f) +#define I2C2_PINSEL (0x0a << 22) + +/* I2C Register addresses ***********************************************************/ + +#define I2C0_CONSET (I2C0_BASE_ADDR+I2C_CONSET_OFFSET) +#define I2C0_STAT (I2C0_BASE_ADDR+I2C_STAT_OFFSET) +#define I2C0_DAT (I2C0_BASE_ADDR+I2C_DAT_OFFSET) +#define I2C0_ADR0 (I2C0_BASE_ADDR+I2C_ADR0_OFFSET) +#define I2C0_SCLH (I2C0_BASE_ADDR+I2C_SCLH_OFFSET) +#define I2C0_SCLL (I2C0_BASE_ADDR+I2C_SCLL_OFFSET) +#define I2C0_CONCLR (I2C0_BASE_ADDR+I2C_CONCLR_OFFSET) + +#define I2C1_CONSET (I2C1_BASE_ADDR+I2C_CONSET_OFFSET) +#define I2C1_STAT (I2C1_BASE_ADDR+I2C_STAT_OFFSET) +#define I2C1_DAT (I2C1_BASE_ADDR+I2C_DAT_OFFSET) +#define I2C1_ADR0 (I2C1_BASE_ADDR+I2C_ADR0_OFFSET) +#define I2C1_SCLH (I2C1_BASE_ADDR+I2C_SCLH_OFFSET) +#define I2C1_SCLL (I2C1_BASE_ADDR+I2C_SCLL_OFFSET) +#define I2C1_CONCLR (I2C1_BASE_ADDR+I2C_CONCLR_OFFSET) + +#define I2C2_CONSET (I2C2_BASE_ADDR+I2C_CONSET_OFFSET) +#define I2C2_STAT (I2C2_BASE_ADDR+I2C_STAT_OFFSET) +#define I2C2_DAT (I2C2_BASE_ADDR+I2C_DAT_OFFSET) +#define I2C2_ADR0 (I2C2_BASE_ADDR+I2C_ADR0_OFFSET) +#define I2C2_SCLH (I2C2_BASE_ADDR+I2C_SCLH_OFFSET) +#define I2C2_SCLL (I2C2_BASE_ADDR+I2C_SCLL_OFFSET) +#define I2C2_CONCLR (I2C2_BASE_ADDR+I2C_CONCLR_OFFSET) + +/* I2C Register bit definitions *****************************************************/ +/* I2C Control Set Register */ + + /* Bits 0-1: Reserved */ +#define I2C_CONSET_AA (1 << 2) /* Bit 2: Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* Bit 3: I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* Bit 4: STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* Bit 5: START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* Bit 6: I2C interface enable */ + /* Bits 7-31: Reserved */ +/* I2C Control Clear Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONCLR_AAC (1 << 2) /* Bit 2: Assert acknowledge Clear bit */ +#define I2C_CONCLR_SIC (1 << 3) /* Bit 3: I2C interrupt Clear bit */ + /* Bit 4: Reserved */ +#define I2C_CONCLR_STAC (1 << 5) /* Bit 5: START flag Clear bit */ +#define I2C_CONCLRT_I2ENC (1 << 6) /* Bit 6: I2C interface Disable bit */ + /* Bits 7-31: Reserved */ +/* I2C Status Register + * + * See tables 399-402 in the "LPC17xx User Manual" (UM10360), Rev. 01, 4 January + * 2010, NXP for definitions of status codes. + */ + +#define I2C_STAT_MASK (0xff) /* Bits 0-7: I2C interface status + * Bits 0-1 always zero */ + /* Bits 8-31: Reserved */ +/* I2C Data Register */ + +#define I2C_DAT_MASK (0xff) /* Bits 0-7: I2C data */ + /* Bits 8-31: Reserved */ + +#define I2C_ADR_GC (1 << 0) /* Bit 0: GC General Call enable bit */ +#define I2C_ADR_ADDR_SHIFT (1) /* Bits 1-7: I2C slave address */ +#define I2C_ADR_ADDR_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Slave address mask registers: + * + * I2C Slave address mask register 0 + * I2C Slave address mask register 1 + * I2C Slave address mask register 2 + * I2C Slave address mask register 3 + */ + /* Bit 0: Reserved */ +#define I2C_MASK_SHIFT (1) /* Bits 1-7: I2C mask bits */ +#define I2C_MASK_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* SCH Duty Cycle Register High Half Word */ + +#define I2C_SCLH_MASK (0xffff) /* Bit 0-15: Count for SCL HIGH time period selection */ + /* Bits 16-31: Reserved */ +/* SCL Duty Cycle Register Low Half Word */ + +#define I2C_SCLL_MASK (0xffff) /* Bit 0-15: Count for SCL LOW time period selection */ + /* Bits 16-31: Reserved */ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc2378_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct i2c_master_s *lpc2378_i2cbus_initialize(int port); + +/************************************************************************************ + * Name: lpc2378_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc2378_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ************************************************************************************/ + +int lpc2378_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_I2C_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_io.c b/arch/arm/src/lpc2378/lpc23xx_io.c new file mode 100644 index 0000000000000000000000000000000000000000..94e7f99c548f23651f09a01c0a4ccde18a39c3c9 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_io.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/arm/lpc2378/lpc23xx_head.S + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included files + ****************************************************************************/ + +#include "up_arch.h" +#include +#include "lpc23xx_scb.h" +#include "lpc23xx_pinsel.h" +#include "lpc23xx_uart.h" +#include "lpc23xx_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: IO_Init() + * + * Descriptions: Initialize the target board before running the main() + * + ****************************************************************************/ + +void IO_Init(void) +{ + uint32_t regval; + + /* Reset all GPIO pins to default */ + + pinsel_putreg(0, PINSEL0_OFFSET); + pinsel_putreg(0, PINSEL1_OFFSET); + pinsel_putreg(0, PINSEL2_OFFSET); + pinsel_putreg(0, PINSEL3_OFFSET); + pinsel_putreg(0, PINSEL4_OFFSET); + pinsel_putreg(0, PINSEL5_OFFSET); + pinsel_putreg(0, PINSEL6_OFFSET); + pinsel_putreg(0, PINSEL7_OFFSET); + pinsel_putreg(0, PINSEL8_OFFSET); + pinsel_putreg(0, PINSEL9_OFFSET); + pinsel_putreg(0, PINSEL10_OFFSET); + +#if 0 + regval = scb_getreg(SCB_PCONP_OFFSET) & ~(PCSDC | PCUART1 | PCI2C0 | PCSSP1 | PCEMC); + scb_getreg(regval, SCB_PCONP_OFFSET); +#endif + + /* Turn off all peripheral power */ + + scb_putreg(0, SCB_PCONP_OFFSET); + + /* Turn on UART0/2 / Timer0 */ + /* regval = PCUART0 | PCUART2 | PCTIM0 | PCRTC ; */ + + regval = PCUART0 | PCUART2 | PCTIM0 ; + scb_putreg(regval , SCB_PCONP_OFFSET); + + /* Status LED P1.19 */ + + dir_putreg8((1 << 3), FIO1DIR2_OFFSET); + + /* other io setup here */ + + return; +} diff --git a/arch/arm/src/lpc2378/lpc23xx_irq.c b/arch/arm/src/lpc2378/lpc23xx_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..ba82aaf3b877b835cdab6f0da7b9386d818fdc1c --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_irq.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_irq.c + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "lpc2378.h" +#include "lpc23xx_vic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int reg; + + /* Disable all interrupts. We do this by writing ones to the IntClearEnable + * register. + */ + + vic_putreg(0xffffffff, VIC_INTENCLEAR_OFFSET); + + /* Select all IRQs, FIQs are not used */ + + vic_putreg(0, VIC_INTSELECT_OFFSET); + + /* Clear priority interrupts */ + + for (reg = 0; reg < NR_IRQS; reg++) + { + vic_putreg(0, VIC_VECTADDR0_OFFSET + (reg << 2)); + vic_putreg(0x0F, VIC_VECTPRIORITY0_OFFSET + (reg << 2)); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Enable global ARM interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_enable_irq_protect + * VIC registers can be accessed in User or privileged mode + ****************************************************************************/ + +#if 0 /* Not used */ +static void up_enable_irq_protect(void) +{ + vic_putreg(0x01, VIC_PROTECTION_OFFSET); +} +#endif + +/**************************************************************************** + * Name: up_disable_irq_protect + * VIC registers can only be accessed in privileged mode + ****************************************************************************/ + +#if 0 /* Not used */ +static void up_disable_irq_protect(void) +{ + vic_putreg(0, VIC_PROTECTION_OFFSET); +} +#endif + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* Verify that the IRQ number is within range */ + + if (irq < NR_IRQS) + { + /* Disable the irq by setting the corresponding bit in the VIC Interrupt + * Enable Clear register. + */ + + vic_putreg((1 << irq), VIC_INTENCLEAR_OFFSET); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* Verify that the IRQ number is within range */ + + if (irq < NR_IRQS) + { + /* Disable all interrupts */ + + irqstate_t flags = enter_critical_section(); + + /* Enable the irq by setting the corresponding bit in the VIC Interrupt + * Enable register. + */ + + uint32_t val = vic_getreg(VIC_INTENABLE_OFFSET); + vic_putreg(val | (1 << irq), VIC_INTENABLE_OFFSET); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + uint32_t reg32; + + if ((unsigned)irq < NR_IRQS) + { + /* Mask the IRQ by clearing the associated bit in Software Priority Mask + * register + */ + + reg32 = vic_getreg(VIC_PRIORITY_MASK_OFFSET); + reg32 &= ~(1 << irq); + vic_putreg(reg32, VIC_PRIORITY_MASK_OFFSET); + } + + /* Clear interrupt */ + + vic_putreg((1 << irq), VIC_SOFTINTCLEAR_OFFSET); +#ifdef CONFIG_VECTORED_INTERRUPTS + vic_putreg(0, VIC_ADDRESS_OFFSET); /* dummy write to clear VICADDRESS */ +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * set interrupt priority + * MOD + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + /* The default priority on reset is 16 */ + + if (irq < NR_IRQS && priority > 0 && priority < 16) + { + int offset = irq << 2; + vic_putreg(priority, VIC_VECTPRIORITY0_OFFSET + offset); + return OK; + } + + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: up_attach_vector + * + * Description: + * Attach a user-supplied handler to a vectored interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_VECTORED_INTERRUPTS +void up_attach_vector(int irq, int vector, vic_vector_t handler) +{ + /* Verify that the IRQ number and vector number are within range */ + + if (irq < NR_IRQS && vector < 32 && handler) + { + int offset = vector << 2; + + /* Disable all interrupts */ + + irqstate_t flags = enter_critical_section(); + + /* Save the vector address */ + + vic_putreg((uint32_t)handler, VIC_VECTADDR0_OFFSET + offset); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(irq, PRIORITY_HIGHEST); +#endif + + /* Enable the vectored interrupt */ + + uint32_t val = vic_getreg(VIC_INTENABLE_OFFSET); + vic_putreg(val | (1 << irq), VIC_INTENABLE_OFFSET); + + leave_critical_section(flags); + } +} +#endif + +/**************************************************************************** + * Name: up_detach_vector + * + * Description: + * Detach a user-supplied handler from a vectored interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_VECTORED_INTERRUPTS +void up_detach_vector(int vector) +{ + /* Verify that the vector number is within range */ + + if (vector < 32) + { + /* Disable the vectored interrupt */ + + int offset = vector << 2; + vic_putreg(0, (VIC_VECTADDR0_OFFSET + offset)); + } +} +#endif diff --git a/arch/arm/src/lpc2378/lpc23xx_lowputc.S b/arch/arm/src/lpc2378/lpc23xx_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..d9d4c455d12c42f76212bc1e4bfbea396e7fbdef --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_lowputc.S @@ -0,0 +1,262 @@ +/************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_lowputc.S + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include "up_internal.h" +#include "up_arch.h" +#include "lpc23xx_pinsel.h" +#include "lpc23xx_scb.h" +#include "lpc23xx_uart.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ +@ //-- Pins +@ PINSEL0 |= (0x01<<4) | //-- P0.2 TXD0 +@ (0x01<<6); //-- P0.3 RXD0 +@PCLKSEL0 |= (0x01 << 6); //-- bit 7:6 =01-> Clock div = 1 for UART0 + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define UARTxBASE UART0_BASE_ADDR +# define PINSELECT LPC23XX_PINSEL0 +# define UARTxPCLKSEL 0xE01FC1A8 +# define PCLKSEL_MASK U0_PCLKSEL_MASK +# define UARTxPINSEL UART0_PINSEL +# define UARTxPINMASK UART0_PINMASK +# define UARTxBAUD CONFIG_UART0_BAUD +# define UARTxBITS CONFIG_UART0_BITS +# define UARTxPARITY CONFIG_UART0_PARITY +# define UARTx2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define UARTxBASE UART1_BASE_ADDR +/* # define PINSELECT LPC23XX_PINSEL1 only Uart0/Uart2 share same Pinsel */ +# define UARTxPCLKSEL 0xE01FC1A8 +# define PCLKSEL_MASK U1_PCLKSEL_MASK +# define UARTxPINSEL UART1_PINSEL +# define UARTxPINMASK UART1_PINMASK +# define UARTxBAUD CONFIG_UART1_BAUD +# define UARTxBITS CONFIG_UART1_BITS +# define UARTxPARITY CONFIG_UART1_PARITY +# define UARTx2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define UARTxBASE UART2_BASE_ADDR +# define PINSELECT LPC23XX_PINSEL0 +# define UARTxPCLKSEL 0xE01FC1AC +# define PCLKSEL_MASK U2_PCLKSEL_MASK +# define UARTxPINSEL UART2_PINSEL +# define UARTxPINMASK UART2_PINMASK +# define UARTxBAUD CONFIG_UART2_BAUD +# define UARTxBITS CONFIG_UART2_BITS +# define UARTxPARITY CONFIG_UART2_PARITY +# define UARTx2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define PINSELECT LPC23XX_PINSEL0 +# define UARTxBASE UART3_BASE_ADDR +# define UARTxPCLKSEL 0xE01FC1AC +# define PCLKSEL_MASK U2_PCLKSEL_MASK +# define UARTxPINSEL UART3_PINSEL +# define UARTxPINMASK UART3_PINMASK +# define UARTxBAUD CONFIG_UART3_BAUD +# define UARTxBITS CONFIG_UART3_BITS +# define UARTxPARITY CONFIG_UART3_PARITY +# define UARTx2STOP CONFIG_UART3_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +#if UARTxBITS == 5 +# define LCR_CHAR LCR_CHAR_5 +#elif UARTxBITS == 6 +# define LCR_CHAR LCR_CHAR_6 +#elif UARTxBITS == 7 +# define LCR_CHAR LCR_CHAR_7 +#elif UARTxBITS == 8 +# define LCR_CHAR LCR_CHAR_8 +#else +# error "No CONFIG_UARTn_BITS Setting" +#endif + +#if UARTxPARITY == 0 +# define LCR_PAR LCR_PAR_NONE +#elif UARTxPARITY == 1 +# define LCR_PAR LCR_PAR_ODD +#elif UARTxPARITY == 2 +# define LCR_PAR LCR_PAR_EVEN +#elif UARTxPARITY == 3 +# define LCR_PAR LCR_PAR_MARK +#elif UARTxPARITY == 4 +# define LCR_PAR LCR_PAR_SPACE +#else +# error "No CONFIG_UARTn_PARITY Setting" +#endif + +#if UARTx2STOP != 0 +# define LCR_STOP LCR_STOP_2 +#else +# define LCR_STOP LCR_STOP_1 +#endif + +#define LCR_VALUE (LCR_CHAR | LCR_PAR | LCR_STOP) +#define FCR_VALUE (FCR_FIFO_TRIG8 | FCR_TX_FIFO_RESET | \ + FCR_RX_FIFO_RESET | FCR_FIFO_ENABLE) +@#define MULVAL (12 << 4) +@#define DIVADDVAL 3 +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + + ldr r1, =UARTxBASE + strb r0, [r1, #UART_THR_OFFSET] + + /* Wait for the byte to be transferred */ + +1: ldr r0, [r1, #UART_LSR_OFFSET] + ands r0, #LSR_TEMT /* Transmitter empty */ + beq 1b + + /* And return */ + + mov pc, lr + .size up_lowputc, . - up_lowputc + +/* This performs basic initialization of the UART. This can be called very + * early in initialization because it does not depend on having a stack. It + * modifies r0-r2 and r14. + */ + + .text + .globl up_lowsetup + .type up_lowsetup, function +up_lowsetup: + /* Configure PINSEL0 */ + + ldr r0, =PINSELECT /* TODO: generalize this for different uart pins */ + ldr r1, [r0] + ldr r2, =(~UARTxPINMASK) + and r1, r2 + + ldr r2, =(UARTxPINSEL) + orr r1, r2 + str r1, [r0] + + /* Power Up Uart0 */ + ldr r0, =UARTxPCLKSEL /* PCLKSEL0 address */ + ldr r1, [r0] + ldr r2, =(~PCLKSEL_MASK) + and r1, r2 + + ldr r2, =(U0_PCLKSEL) + orr r1, r2 + str r1, [r0] + +/* Configure parity, data bits, stop bits and set DLAB=1 */ + + ldr r0, =UARTxBASE + mov r1, #(LCR_VALUE | LCR_DLAB_ENABLE) + strb r1, [r0, #UART_LCR_OFFSET] + +/* Set the BAUD divisor */ + + mov r1, #((MULVAL << 4) | DIVADDVAL) + strb r1, [r0, #UART_FDR_OFFSET] + + mov r1, #DLMVAL + strb r1, [r0, #UART_DLM_OFFSET] + + mov r1, #DLLVAL + strb r1, [r0, #UART_DLL_OFFSET] + +/* Clear DLAB and Set format 8N1 */ + + mov r1, #LCR_VALUE + strb r1, [r0, #UART_LCR_OFFSET] + +/* Configure the FIFOs */ + + mov r1, #FCR_VALUE + strb r1, [r0, #UART_FCR_OFFSET] + + mov r1, #LCR_VALUE + strb r1, [r0, #UART_LCR_OFFSET] + +/* And return */ + + mov pc, lr + .size up_lowsetup, . - up_lowsetup + .end diff --git a/arch/arm/src/lpc2378/lpc23xx_pinsel.h b/arch/arm/src/lpc2378/lpc23xx_pinsel.h new file mode 100644 index 0000000000000000000000000000000000000000..69ad1b749042405b9db94895a2ea233874740ad2 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_pinsel.h @@ -0,0 +1,792 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc23xx_pinsel.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef _ARCH_ARM_SRC_LPC23XX_PINSEL_H +#define _ARCH_ARM_SRC_LPC23XX_PINSEL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ +#include "chip.h" +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define PINSEL_BASE 0xE002C000 + +#define pinsel_putreg8(v,o) putreg8( (v), LPC23XX_PINSEL_BASE+(o) ) +#define pinsel_putreg(v,r) putreg32( (v),LPC23XX_PINSEL_BASE+ (r) ) +#define pinsel_getreg(o) getreg32( PINSEL_BASE+(o) ) + +/* Register address definitions *****************************************************/ +#define LPC23XX_PINSEL0 (PINSEL_BASE + PINSEL0_OFFSET) +#define LPC23XX_PINSEL1 (PINSEL_BASE + PINSEL1_OFFSET) +#define LPC23XX_PINSEL2 (PINSEL_BASE + PINSEL2_OFFSET) +#define LPC23XX_PINSEL3 (PINSEL_BASE + PINSEL3_OFFSET) +#define LPC23XX_PINSEL4 (PINSEL_BASE + PINSEL4_OFFSET) +#define LPC23XX_PINSEL5 (PINSEL_BASE + PINSEL5_OFFSET) +#define LPC23XX_PINSEL6 (PINSEL_BASE + PINSEL6_OFFSET) +#define LPC23XX_PINSEL7 (PINSEL_BASE + PINSEL7_OFFSET) +#define LPC23XX_PINSEL8 (PINSEL_BASE + PINSEL8_OFFSET) +#define LPC23XX_PINSEL9 (PINSEL_BASE + PINSEL9_OFFSET) +#define LPC23XX_PINSEL10 (PINSEL_BASE + PINSEL10_OFFSET) + +/* PINSEL 0 */ +#define PSEL0_P00_GPIO (0x00000000) +#define PSEL0_P00_RD1 (0x00000001) +#define PSEL0_P00_TXD3 (0x00000002) +#define PSEL0_P00_SDA1 (0x00000003) +#define PSEL0_P00_MASK (0x00000003) + +#define PSEL0_P0_1_GPIO (0x00000000) +#define PSEL0_P0_1_TD1 (0x00000004) +#define PSEL0_P0_1_RXD3 (0x00000008) +#define PSEL0_P0_1_SCL1 (0x0000000c) +#define PSEL0_P0_1_MASK (0x0000000c) + +#define PSEL0_P0_2_GPIO (0x00000000) +#define PSEL0_P0_2_TXD0 (0x00000010) +#define PSEL0_P0_2_RSVD2 (0x00000020) +#define PSEL0_P0_2_RSVD3 (0x00000030) +#define PSEL0_P0_2_MASK (0x00000030) + +#define PSEL0_P0_3_GPIO (0x00000000) +#define PSEL0_P0_3_RXD0 (0x00000040) +#define PSEL0_P0_3_RSVD2 (0x00000080) +#define PSEL0_P0_3_RSVD3 (0x000000c0) +#define PSEL0_P0_3_MASK (0x000000c0) + +#define PSEL0_P0_4_GPIO (0x00000000) +#define PSEL0_P0_4_I2SRX_CLK (0x00000100) +#define PSEL0_P0_4_RD2 (0x00000200) +#define PSEL0_P0_4_CAP20 (0x00000300) +#define PSEL0_P0_4_MASK (0x00000400) + +#define PSEL0_P0_5_GPIO (0x00000000) +#define PSEL0_P0_5_I2SRX_WS (0x00000400) +#define PSEL0_P0_5_TD2 (0x00000800) +#define PSEL0_P0_5_CAP21 (0x00000c00) +#define PSEL0_P0_5_MASK (0x00000c00) + +#define PSEL0_P0_6_GPIO (0x00000000) +#define PSEL0_P0_6_I2SRX_SDA (0x00001000) +#define PSEL0_P0_6_SSEL1 (0x00002000) +#define PSEL0_P0_6_MAT20 (0x00003000) +#define PSEL0_P0_6_MASK (0x00003000) + +#define PSEL0_P0_7_GPIO (0x00000000) +#define PSEL0_P0_7_I2STX_CLK (0x00004000) +#define PSEL0_P0_7_SCK1 (0x00008000) +#define PSEL0_P0_7_MAT21 (0x0000c000) +#define PSEL0_P0_7_MASK (0x0000c000) + +#define PSEL0_P0_8_GPIO (0x00000000) +#define PSEL0_P0_8_I2STX_WS (0x00010000) +#define PSEL0_P0_8_MISO1 (0x00020000) +#define PSEL0_P0_8_MAT22 (0x00030000) +#define PSEL0_P0_8_MASK (0x00030000) + +#define PSEL0_P0_9_GPIO (0x00000000) +#define PSEL0_P0_9_I2STX_SDA (0x00040000) +#define PSEL0_P0_9_MOSI1 (0x00080000) +#define PSEL0_P0_9_MAT23 (0x000c0000) +#define PSEL0_P0_9_MASK (0x000c0000) + +#define PSEL0_P0_10_GPIO (0x00000000) +#define PSEL0_P0_10_TXD2 (0x00100000) +#define PSEL0_P0_10_SDA2 (0x00200000) +#define PSEL0_P0_10_MAT30 (0x00300000) +#define PSEL0_P0_10_MASK (0x00300000) + +#define PSEL0_P0_11_GPIO (0x00000000) +#define PSEL0_P0_11_RXD2 (0x00400000) +#define PSEL0_P0_11_SCL2 (0x00800000) +#define PSEL0_P0_11_MAT31 (0x00c00000) +#define PSEL0_P0_11_MASK (0x00c00000) + +#define PSEL0_P0_12_GPIO (0x00000000) +#define PSEL0_P0_12_RSVD1 (0x01000000) +#define PSEL0_P0_12_MISO1 (0x02000000) +#define PSEL0_P0_12_AD06 (0x03000000) +#define PSEL0_P0_12_MASK (0x03000000) + +#define PSEL0_P0_13_GPIO (0x00000000) +#define PSEL0_P0_13_USB_UPLED2 (0x04000000) +#define PSEL0_P0_13_MOSI1 (0x08000000) +#define PSEL0_P0_13_AD07 (0x0c000000) +#define PSEL0_P0_13_MASK (0x0c000000) + +#define PSEL0_P0_14_GPIO (0x00000000) +#define PSEL0_P0_14_RSVD1 (0x10000000) +#define PSEL0_P0_14_USB_CONNECT2 (0x20000000) +#define PSEL0_P0_14_SSEL1 (0x30000000) +#define PSEL0_P0_14_MASK (0x30000000) + +#define PSEL0_P0_15_GPIO (0x00000000) +#define PSEL0_P0_15_TXD1 (0x40000000) +#define PSEL0_P0_15_SCK0 (0x80000000) +#define PSEL0_P0_15_SCK (0xc0000000) +#define PSEL0_P0_15_MASK (0xc0000000) + +/* PINSEL 1 */ +#define PSEL1_P0_16_GPIO (0x00000000) +#define PSEL1_P0_16_RXD1 (0x00000001) +#define PSEL1_P0_16_SSEL0 (0x00000002) +#define PSEL1_P0_16_SSEL (0x00000003) +#define PSEL1_P0_16_MASK (0x00000003) + +#define PSEL1_P0_17_GPIO (0x00000000) +#define PSEL1_P0_17_CTS1 (0x00000004) +#define PSEL1_P0_17_MISO0 (0x00000008) +#define PSEL1_P0_17_MISO (0x0000000c) +#define PSEL1_P0_17_MASK (0x0000000c) + +#define PSEL1_P0_18_GPIO (0x00000000) +#define PSEL1_P0_18_DCD1 (0x00000010) +#define PSEL1_P0_18_MOSI0 (0x00000020) +#define PSEL1_P0_18_MOSI (0x00000030) +#define PSEL1_P0_18_MASK (0x00000030) + +#define PSEL1_P0_19_GPIO (0x00000000) +#define PSEL1_P0_19_DSR1 (0x00000040) +#define PSEL1_P0_19_MCICLK (0x00000080) +#define PSEL1_P0_19_SDA1 (0x000000c0) +#define PSEL1_P0_19_MASK (0x000000c0) + +#define PSEL1_P0_20_GPIO (0x00000000) +#define PSEL1_P0_20_DTR1 (0x00000100) +#define PSEL1_P0_20_MCICMD (0x00000200) +#define PSEL1_P0_20_SCL1 (0x00000300) +#define PSEL1_P0_20_MASK (0x00000300) + +#define PSEL1_P0_21_GPIO (0x00000000) +#define PSEL1_P0_21_RI1 (0x00000400) +#define PSEL1_P0_21_MCIPWR (0x00000800) +#define PSEL1_P0_21_RD1 (0x00000c00) +#define PSEL1_P0_21_MASK (0x00000c00) + +#define PSEL1_P0_22_GPIO (0x00000000) +#define PSEL1_P0_22_RTS1 (0x00001000) +#define PSEL1_P0_22_MCIDA0 (0x00002000) +#define PSEL1_P0_22_TD1 (0x00003000) +#define PSEL1_P0_22_MASK (0x00003000) + +#define PSEL1_P0_23_GPIO (0x00000000) +#define PSEL1_P0_23_AD00 (0x00004000) +#define PSEL1_P0_23_I2SRX_CLK (0x00008000) +#define PSEL1_P0_23_CAP30 (0x0000c000) +#define PSEL1_P0_23_MASK (0x0000c000) + +#define PSEL1_P0_24_GPIO (0x00000000) +#define PSEL1_P0_24_AD01 (0x00010000) +#define PSEL1_P0_24_I2SRX_WS (0x00020000) +#define PSEL1_P0_24_CAP31 (0x00030000) +#define PSEL1_P0_24_MASK (0x00030000) + +#define PSEL1_P0_25_GPIO (0x00000000) +#define PSEL1_P0_25_AD02 (0x00040000) +#define PSEL1_P0_25_I2SRX_SDA (0x00080000) +#define PSEL1_P0_25_TXD3 (0x000c0000) +#define PSEL1_P0_25_MASK (0x000c0000) + +#define PSEL1_P0_26_GPI0 (0x00000000) +#define PSEL1_P0_26_AD031 (0x00100000) +#define PSEL1_P0_26_AOUT (0x00200000) +#define PSEL1_P0_26_RXD3 (0x00300000) +#define PSEL1_P0_26_MASK (0x00300000) + +#define PSEL1_P0_27_GPI0 (0x00000000) +#define PSEL1_P0_27_SDA0 (0x00400000) +#define PSEL1_P0_27_RSVD2 (0x00800000) +#define PSEL1_P0_27_RSVD3 (0x00c00000) +#define PSEL1_P0_27_MASK (0x00c00000) + +#define PSEL1_P0_28_GPIO (0x00000000) +#define PSEL1_P0_28_SCL0 (0x01000000) +#define PSEL1_P0_28_RSVD2 (0x02000000) +#define PSEL1_P0_28_RSVD3 (0x03000000) +#define PSEL1_P0_28_MASK (0x03000000) + +#define PSEL1_P0_29_GPIO (0x00000000) +#define PSEL1_P0_29_USB_DPOS1 (0x04000000) +#define PSEL1_P0_29_RSVD2 (0x08000000) +#define PSEL1_P0_29_RSVD3 (0x0c000000) +#define PSEL1_P0_29_MASK (0x0c000000) + +#define PSEL1_P0_30_GPIO (0x00000000) +#define PSEL1_P0_30_USB_DNEG1 (0x10000000) +#define PSEL1_P0_30_RSVD2 (0x20000000) +#define PSEL1_P0_30_RSVD3 (0x30000000) +#define PSEL1_P0_30_MASK (0x30000000) + +#define PSEL1_P0_31_GPIO (0x00000000) +#define PSEL1_P0_31_USB_DPOS2 (0x40000000) +#define PSEL1_P0_31_RSVD2 (0x80000000) +#define PSEL1_P0_31_RSVD3 (0xc0000000) +#define PSEL1_P0_31_MASK (0xc0000000) + + +/* PINSEL 2 */ +#define PSEL2_P1_0_GPIO (0x00000000) +#define PSEL2_P1_0_ENET_TXD0 (0x00000001) +#define PSEL2_P1_0_RSVD2 (0x00000002) +#define PSEL2_P1_0_RSVD3 (0x00000003) +#define PSEL2_P1_0_MASK (0x00000003) + +#define PSEL2_P1_1_GPIO (0x00000000) +#define PSEL2_P1_1_ENET_TXD1 (0x00000004) +#define PSEL2_P1_1_RSVD2 (0x00000008) +#define PSEL2_P1_1_RSVD3 (0x0000000c) +#define PSEL2_P1_1_MASK (0x0000000c) + +#define PSEL2_P1_2_RSVD0 (0x00000000) +#define PSEL2_P1_2_RSVD1 (0x00000010) +#define PSEL2_P1_2_RSVD2 (0x00000020) +#define PSEL2_P1_2_RSVD3 (0x00000030) +#define PSEL2_P1_2_MASK (0x00000030) + +#define PSEL2_P1_3_RSVD0 (0x00000000) +#define PSEL2_P1_3_RSVD1 (0x00000040) +#define PSEL2_P1_3_RSVD2 (0x00000080) +#define PSEL2_P1_3_RSVD3 (0x000000c0) +#define PSEL2_P1_3_MASK (0x000000c0) + +#define PSEL2_P1_4_GPIO (0x00000000) +#define PSEL2_P1_4_ENET_TX_EN (0x00000100) +#define PSEL2_P1_4_RSVD2 (0x00000200) +#define PSEL2_P1_4_RSVD3 (0x00000300) +#define PSEL2_P1_4_MASK (0x00000300) + +#define PSEL2_P1_5_RSVDO (0x00000000) +#define PSEL2_P1_5_RSVD1 (0x00000400) +#define PSEL2_P1_5_RSVD2 (0x00000800) +#define PSEL2_P1_5_RSVD3 (0x00000c00) +#define PSEL2_P1_5_MASK (0x00000c00) + +#define PSEL2_P1_6_RSVD0 (0x00000000) +#define PSEL2_P1_6_RSVD1 (0x00001000) +#define PSEL2_P1_6_RSVD2 (0x00002000) +#define PSEL2_P1_6_RSVD3 (0x00003000) +#define PSEL2_P1_6_MASK (0x00003000) + +#define PSEL2_P1_7_RSVD0 (0x00000000) +#define PSEL2_P1_7_RSVD1 (0x00004000) +#define PSEL2_P1_7_RSVD2 (0x00008000) +#define PSEL2_P1_7_RSVD3 (0x0000c000) +#define PSEL2_P1_7_MASK (0x0000c000) + +#define PSEL2_P1_8_GPIO (0x00000000) +#define PSEL2_P1_8_ENET_CRS (0x00010000) +#define PSEL2_P1_8_RSVD2 (0x00020000) +#define PSEL2_P1_8_RSVD3 (0x00030000) +#define PSEL2_P1_8_MASK (0x00030000) + +#define PSEL2_P1_9_GPIO (0x00000000) +#define PSEL2_P1_9_ENET_RXD0 (0x00040000) +#define PSEL2_P1_9_RSVD2 (0x00080000) +#define PSEL2_P1_9_RSVD3 (0x000c0000) +#define PSEL2_P1_9_MASK (0x000c0000) + +#define PSEL2_P1_10_GPI0 (0x00000000) +#define PSEL2_P1_10_ENET_RXD1 (0x00100000) +#define PSEL2_P1_10_RSVD2 (0x00200000) +#define PSEL2_P1_10_RSVD3 (0x00300000) +#define PSEL2_P1_10_MASK (0x00300000) + +#define PSEL2_P1_11_RSVD0 (0x00000000) +#define PSEL2_P1_11_RSVD1 (0x00400000) +#define PSEL2_P1_11_RSVD2 (0x00800000) +#define PSEL2_P1_11_RSVD3 (0x00c00000) +#define PSEL2_P1_11_MASK (0x00c00000) + +#define PSEL2_P1_12_RSVD0 (0x00000000) +#define PSEL2_P1_12_RSVD1 (0x01000000) +#define PSEL2_P1_12_RSVD2 (0x02000000) +#define PSEL2_P1_12_RSVD3 (0x03000000) +#define PSEL2_P1_12_MASK (0x03000000) + +#define PSEL2_P1_13_RSVD0 (0x00000000) +#define PSEL2_P1_13_RSVD1 (0x04000000) +#define PSEL2_P1_13_RSVD2 (0x08000000) +#define PSEL2_P1_13_RSVD3 (0x0c000000) +#define PSEL2_P1_13_MASK (0x0c000000) + +#define PSEL2_P1_14_GPIO (0x00000000) +#define PSEL2_P1_14_ENET_RX_ER (0x10000000) +#define PSEL2_P1_14_RSVD2 (0x20000000) +#define PSEL2_P1_14_RSVD3 (0x30000000) +#define PSEL2_P1_14_MASK (0x30000000) + +#define PSEL2_P1_15_GPIO (0x00000000) +#define PSEL2_P1_15_ENET_REF_CLK (0x40000000) +#define PSEL2_P1_15_RSVD2 (0x80000000) +#define PSEL2_P1_15_RSVD3 (0xc0000000) +#define PSEL2_P1_15_MASK (0xc0000000) + + +/* PINSEL 3 */ +#define PSEL3_P1_16_GPIO (0x00000000) +#define PSEL3_P1_16_ENET_MDC (0x00000001) +#define PSEL3_P1_16_RSVD2 (0x00000002) +#define PSEL3_P1_16_RSVD3 (0x00000003) +#define PSEL3_P1_16_MASK (0x00000003) + +#define PSEL3_P1_17_GPIO (0x00000000) +#define PSEL3_P1_17_ENET_MDIO (0x00000004) +#define PSEL3_P1_17_RSVD2 (0x00000008) +#define PSEL3_P1_17_RSVD3 (0x0000000c) +#define PSEL3_P1_17_MASK (0x0000000c) + +#define PSEL3_P1_18_GPIO (0x00000000) +#define PSEL3_P1_18_USB_UP_LED1 (0x00000010) +#define PSEL3_P1_18_PWM1_1 (0x00000020) +#define PSEL3_P1_18_CAP1_0 (0x00000030) +#define PSEL3_P1_18_MASK (0x00000030) + +#define PSEL3_P1_19_GPIO (0x00000000) +#define PSEL3_P1_19_USB_TX_E1 (0x00000040) /* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_19_USB_PPWR1 (0x00000080) /* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_19_CAP1_1 (0x000000c0) +#define PSEL3_P1_19_MASK (0x000000c0) + +#define PSEL3_P1_20_GPIO (0x00000000) +#define PSEL3_P1_20_USB_TX_DP1 (0x00000100)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_20_PWM1_2 (0x00000200) +#define PSEL3_P1_20_SCK0 (0x00000300) +#define PSEL3_P1_20_MASK (0x00000300) + +#define PSEL3_P1_21_GPIO (0x00000000) +#define PSEL3_P1_21_USB_TX_DM1 (0x00000400)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_21_PWM1_3 (0x00000800) +#define PSEL3_P1_21_SSEL0 (0x00000c00) +#define PSEL3_P1_21_MASK (0x00000c00) + +#define PSEL3_P1_22_GPIO (0x00000000) +#define PSEL3_P1_22_USB_RCV1 (0x00001000) /* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_22_USB_PWRD1 (0x00002000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_22_MAT1_0 (0x00003000) +#define PSEL3_P1_22_MASK (0x00003000) + +#define PSEL3_P1_23_GPIO (0x00000000) +#define PSEL3_P1_23_USB_RX_DP1 (0x00004000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_23_PWM1_4 (0x00008000) +#define PSEL3_P1_23_MISO0 (0x0000c000) +#define PSEL3_P1_23_MASK (0x0000c000) + +#define PSEL3_P1_24_GPIO (0x00000000) +#define PSEL3_P1_24_USB_RX_DM1 (0x00010000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_24_PWM1_5 (0x00020000) +#define PSEL3_P1_24_MOSI0 (0x00030000) +#define PSEL3_P1_24_MASK (0x00030000) + +#define PSEL3_P1_25_GPIO (0x00000000) +#define PSEL3_P1_25_USB_LS1 (0x00040000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_25_USB_HSTEN1 (0x00080000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_25_MAT1_1 (0x000c0000) +#define PSEL3_P1_25_MASK (0x000c0000) + +#define PSEL3_P1_26_GPI0 (0x00000000) +#define PSEL3_P1_26_USB_SSPND1 (0x00100000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_26_PWM1_6 (0x00200000) +#define PSEL3_P1_26_CAP0_0 (0x00300000) +#define PSEL3_P1_26_MASK (0x00300000) + +#define PSEL3_P1_27_GPIO (0x00000000) +#define PSEL3_P1_27_USB_INT1 (0x00400000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_27_USB_OVRCR1 (0x00800000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_27_CAP0_1 (0x00c00000) +#define PSEL3_P1_27_MASK (0x00c00000) + +#define PSEL3_P1_28_GPIO (0x00000000) +#define PSEL3_P1_28_USB_SCL1 (0x01000000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_28_PCAP1_0 (0x02000000) +#define PSEL3_P1_28_MAT0_0 (0x03000000) +#define PSEL3_P1_28_MASK (0x03000000) + +#define PSEL3_P1_29_GPIO (0x00000000) +#define PSEL3_P1_29_USB_SDA1 (0x04000000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_29_PCAP1_1 (0x08000000) +#define PSEL3_P1_29_MAT0_1 (0x0c000000) +#define PSEL3_P1_29_MASK (0x0c000000) + +#define PSEL3_P1_30_GPIO (0x00000000) +#define PSEL3_P1_30_USB_PWRD2 (0x10000000) +#define PSEL3_P1_30_VBUS (0x20000000) +#define PSEL3_P1_30_AD0_4 (0x30000000) +#define PSEL3_P1_30_MASK (0x30000000) + +#define PSEL3_P1_31_GPIO (0x00000000) +#define PSEL3_P1_31_USB_OVRCR2 (0x40000000)/* 2388 only Reserved on 2377/78 */ +#define PSEL3_P1_31_SCK1 (0x80000000) +#define PSEL3_P1_31_AD0_5 (0xc0000000) +#define PSEL3_P1_31_MASK (0xc0000000) + +/* PINSEL 4 */ +#define PSEL4_P2_0_GPIO (0x00000000) +#define PSEL4_P2_0_PWM1_1 (0x00000001) +#define PSEL4_P2_0_TXD1 (0x00000002) +#define PSEL4_P2_0_TRACECLK (0x00000003) +#define PSEL4_P2_0_MASK (0x00000003) + +#define PSEL4_P2_1_GPIO (0x00000000) +#define PSEL4_P2_1_PWM1_2 (0x00000004) +#define PSEL4_P2_1_RXD1 (0x00000008) +#define PSEL4_P2_1_PIPESTAT0 (0x0000000c) +#define PSEL4_P2_1_MASK (0x0000000c) + +#define PSEL4_P2_2_GPIO (0x00000000) +#define PSEL4_P2_2_PWM1_3 (0x00000010) +#define PSEL4_P2_2_CTS1 (0x00000020) +#define PSEL4_P2_2_PIPESTAT1 (0x00000030) +#define PSEL4_P2_2_MASK (0x00000030) + +#define PSEL4_P2_3_GPIO (0x00000000) +#define PSEL4_P2_3_PWM1_4 (0x00000040) +#define PSEL4_P2_3_DCD1 (0x00000080) +#define PSEL4_P2_3_PIPESTAT2 (0x000000c0) +#define PSEL4_P2_3_MASK (0x000000c0) + +#define PSEL4_P2_4_GPIO (0x00000000) +#define PSEL4_P2_4_PWM1_5 (0x00000100) +#define PSEL4_P2_4_DSR1 (0x00000200) +#define PSEL4_P2_4_TRACESYNC (0x00000300) +#define PSEL4_P2_4_MASK (0x00000300) + +#define PSEL4_P2_5_GPIO (0x00000000) +#define PSEL4_P2_5_PWM1_6 (0x00000400) +#define PSEL4_P2_5_DTR1 (0x00000800) +#define PSEL4_P2_5_TRACEPKT0 (0x00000c00) +#define PSEL4_P2_5_MASK (0x00000c00) + +#define PSEL4_P2_6_GPIO (0x00000000) +#define PSEL4_P2_6_PCAP1_0 (0x00001000) +#define PSEL4_P2_6_RI1 (0x00002000) +#define PSEL4_P2_6_TRACEPKT1 (0x00003000) +#define PSEL4_P2_6_MASK (0x00003000) + +#define PSEL4_P2_7_GPIO (0x00000000) +#define PSEL4_P2_7_RD2 (0x00004000) +#define PSEL4_P2_7_RTS1 (0x00008000) +#define PSEL4_P2_7_TRACEPKT2 (0x0000c000) +#define PSEL4_P2_7_MASK (0x0000c000) + +#define PSEL4_P2_8_GPIO (0x00000000) +#define PSEL4_P2_8_TD2 (0x00010000) +#define PSEL4_P2_8_TXD2 (0x00020000) +#define PSEL4_P2_8_TRACEPKT3 (0x00030000) +#define PSEL4_P2_8_MASK (0x00030000) + +#define PSEL4_P2_9_GPIO (0x00000000) +#define PSEL4_P2_9_USB_CONNECT1 (0x00040000) +#define PSEL4_P2_9_RXD2 (0x00080000) +#define PSEL4_P2_9_EXTIN0 (0x000c0000) +#define PSEL4_P2_9_MASK (0x000c0000) + +#define PSEL4_P2_10_GPI0 (0x00000000) +#define PSEL4_P2_10_EINT0 (0x00100000) +#define PSEL4_P2_10_RSVD2 (0x00200000) +#define PSEL4_P2_10_RSVD3 (0x00300000) +#define PSEL4_P2_10_MASK (0x00300000) + +#define PSEL4_P2_11_GPIO (0x00000000) +#define PSEL4_P2_11_EINT1 (0x00400000) +#define PSEL4_P2_11_MCIDAT1 (0x00800000) +#define PSEL4_P2_11_I2STX_CLK (0x00c00000) +#define PSEL4_P2_11_MASK (0x00c00000) + +#define PSEL4_P2_12_GPIO (0x00000000) +#define PSEL4_P2_12_EINT2 (0x01000000) +#define PSEL4_P2_12_MCIDAT2 (0x02000000) +#define PSEL4_P2_12_I2STX_WS (0x03000000) +#define PSEL4_P2_12_MASK (0x03000000) + +#define PSEL4_P2_13_GPIO (0x00000000) +#define PSEL4_P2_13_EINT3 (0x04000000) +#define PSEL4_P2_13_MCIDAT3 (0x08000000) +#define PSEL4_P2_13_I2STX_SDA (0x0c000000) +#define PSEL4_P2_13_MASK (0x0c000000) + +#define PSEL4_P2_14_RSVD0 (0x00000000) +#define PSEL4_P2_14_RSVD1 (0x10000000) +#define PSEL4_P2_14_RSVD2 (0x20000000) +#define PSEL4_P2_14_RSVD3 (0x30000000) +#define PSEL4_P2_14_MASK (0x30000000) + +#define PSEL4_P2_15_RSVD0 (0x00000000) +#define PSEL4_P2_15_RSVD1 (0x40000000) +#define PSEL4_P2_15_RSVD2 (0x80000000) +#define PSEL4_P2_15_RSVD3 (0xc0000000) +#define PSEL4_P2_15_MASK (0xc0000000) + +/* PINSEL 5 All reserved */ + + +/* PINSEL 6 */ +#define PSEL6_P3_0_GPIO (0x00000000) +#define PSEL6_P3_0_D0 (0x00000001) +#define PSEL6_P3_0_RSVD2 (0x00000002) +#define PSEL6_P3_0_RSVD3 (0x00000003) +#define PSEL6_P3_0_MASK (0x00000003) + +#define PSEL6_P3_1_GPIO (0x00000000) +#define PSEL6_P3_1_D1 (0x00000004) +#define PSEL6_P3_1_RSVD2 (0x00000008) +#define PSEL6_P3_1_RSVD3 (0x0000000c) +#define PSEL6_P3_1_MASK (0x0000000c) + +#define PSEL6_P3_2_GPIO (0x00000000) +#define PSEL6_P3_2_D2 (0x00000010) +#define PSEL6_P3_2_RSVD2 (0x00000020) +#define PSEL6_P3_2_RSVD3 (0x00000030) +#define PSEL6_P3_2_MASK (0x00000030) + +#define PSEL6_P3_3_GPIO (0x00000000) +#define PSEL6_P3_3_D3 (0x00000040) +#define PSEL6_P3_3_RSVD2 (0x00000080) +#define PSEL6_P3_3_RSVD3 (0x000000c0) +#define PSEL6_P3_3_MASK (0x000000c0) + +#define PSEL6_P3_4_GPIO (0x00000000) +#define PSEL6_P3_4_D4 (0x00000100) +#define PSEL6_P3_4_RSVD2 (0x00000200) +#define PSEL6_P3_4_RSVD3 (0x00000300) +#define PSEL6_P3_4_MASK (0x00000400) + +#define PSEL6_P3_5_GPIO (0x00000000) +#define PSEL6_P3_5_D5 (0x00000400) +#define PSEL6_P3_5_RSVD2 (0x00000800) +#define PSEL6_P3_5_RSVD3 (0x00000c00) +#define PSEL6_P3_5_MASK (0x00000c00) + +#define PSEL6_P3_6_GPIO (0x00000000) +#define PSEL6_P3_6_D6 (0x00001000) +#define PSEL6_P3_6_RSVD2 (0x00002000) +#define PSEL6_P3_6_RSVD3 (0x00003000) +#define PSEL6_P3_6_MASK (0x00003000) + +#define PSEL6_P3_7_GPIO (0x00000000) +#define PSEL6_P3_7_D7 (0x00004000) +#define PSEL6_P3_7_RSVD2 (0x00008000) +#define PSEL6_P3_7_RSVD3 (0x0000c000) +#define PSEL6_P3_7_MASK (0x0000c000) +/* Rest of PSEL 6 are reserved */ + +/* PINSEL 7 */ +/* PINSEL 7 bit 0:13 are reserved */ +#define PSEL7_P3_23_GPIO (0x00000000) +#define PSEL7_P3_23_RSVD1 (0x00004000) +#define PSEL7_P3_23_CAP0_0 (0x00008000) +#define PSEL7_P3_23_PCAP1_0 (0x0000c000) +#define PSEL7_P3_23_MASK (0x0000c000) + +#define PSEL7_P3_24_GPIO (0x00000000) +#define PSEL7_P3_24_RSVD1 (0x00010000) +#define PSEL7_P3_24_CAP0_1 (0x00020000) +#define PSEL7_P3_24_PWM1_1 (0x00030000) +#define PSEL7_P3_24_MASK (0x00030000) + +#define PSEL7_P3_25_GPIO (0x00000000) +#define PSEL7_P3_25_RSVD1 (0x00040000) +#define PSEL7_P3_25_MAT0_0 (0x00080000) +#define PSEL7_P3_25_PWM1_2 (0x000c0000) +#define PSEL7_P3_25_MASK (0x000c0000) + +#define PSEL7_P3_26_GPI0 (0x00000000) +#define PSEL7_P3_26_RSVD1 (0x00100000) +#define PSEL7_P3_26_MAT0_1 (0x00200000) +#define PSEL7_P3_26_PWM1_3 (0x00300000) +#define PSEL7_P3_26_MASK (0x00300000) +/* PINSEL 7 rest are reserved */ + + +/* PINSEL 8 */ +#define PSEL8_P4_0_GPIO (0x00000000) +#define PSEL8_P4_0_A0 (0x00000001) +#define PSEL8_P4_0_RSVD2 (0x00000002) +#define PSEL8_P4_0_RSVD3 (0x00000003) +#define PSEL8_P4_0_MASK (0x00000003) + +#define PSEL8_P4_1_GPIO (0x00000000) +#define PSEL8_P4_1_A1 (0x00000004) +#define PSEL8_P4_1_RXD3 (0x00000008) +#define PSEL8_P4_1_SCL1 (0x0000000c) +#define PSEL8_P4_1_MASK (0x0000000c) + +#define PSEL8_P4_2_GPIO (0x00000000) +#define PSEL8_P4_2_A2 (0x00000010) +#define PSEL8_P4_2_RSVD2 (0x00000020) +#define PSEL8_P4_2_RSVD3 (0x00000030) +#define PSEL8_P4_2_MASK (0x00000030) + +#define PSEL8_P4_3_GPIO (0x00000000) +#define PSEL8_P4_3_A3 (0x00000040) +#define PSEL8_P4_3_RSVD2 (0x00000080) +#define PSEL8_P4_3_RSVD3 (0x000000c0) +#define PSEL8_P4_3_MASK (0x000000c0) + +#define PSEL8_P4_4_GPIO (0x00000000) +#define PSEL8_P4_4_A4 (0x00000100) +#define PSEL8_P4_4_RSVD2 (0x00000200) +#define PSEL8_P4_4_RSVD3 (0x00000300) +#define PSEL8_P4_4_MASK (0x00000400) + +#define PSEL8_P4_5_GPIO (0x00000000) +#define PSEL8_P4_5_A5 (0x00000400) +#define PSEL8_P4_5_RSVD2 (0x00000800) +#define PSEL8_P4_5_RSVD3 (0x00000c00) +#define PSEL8_P4_5_MASK (0x00000c00) + +#define PSEL8_P4_6_GPIO (0x00000000) +#define PSEL8_P4_6_A6 (0x00001000) +#define PSEL8_P4_6_RSVD2 (0x00002000) +#define PSEL8_P4_6_RSVD3 (0x00003000) +#define PSEL8_P4_6_MASK (0x00003000) + +#define PSEL8_P4_7_GPIO (0x00000000) +#define PSEL8_P4_7_A7 (0x00004000) +#define PSEL8_P4_7_RSVD2 (0x00008000) +#define PSEL8_P4_7_RSVD3 (0x0000c000) +#define PSEL8_P4_7_MASK (0x0000c000) + +#define PSEL8_P4_8_GPIO (0x00000000) +#define PSEL8_P4_8_A8 (0x00010000) +#define PSEL8_P4_8_RSVD2 (0x00020000) +#define PSEL8_P4_8_RSVD3 (0x00030000) +#define PSEL8_P4_8_MASK (0x00030000) + +#define PSEL8_P4_9_GPIO (0x00000000) +#define PSEL8_P4_9_A9 (0x00040000) +#define PSEL8_P4_9_RSVD2 (0x00080000) +#define PSEL8_P4_9_RSVD3 (0x000c0000) +#define PSEL8_P4_9_MASK (0x000c0000) + +#define PSEL8_P4_10_GPIO (0x00000000) +#define PSEL8_P4_10_A10 (0x00100000) +#define PSEL8_P4_10_RSVD2 (0x00200000) +#define PSEL8_P4_10_RSVD3 (0x00300000) +#define PSEL8_P4_10_MASK (0x00300000) + +#define PSEL8_P4_11_GPIO (0x00000000) +#define PSEL8_P4_11_A11 (0x00400000) +#define PSEL8_P4_11_RSVD2 (0x00800000) +#define PSEL8_P4_11_RSVD3 (0x00c00000) +#define PSEL8_P4_11_MASK (0x00c00000) + +#define PSEL8_P4_12_GPIO (0x00000000) +#define PSEL8_P4_12_A12 (0x01000000) +#define PSEL8_P4_12_RSVD2 (0x02000000) +#define PSEL8_P4_12_RSVD3 (0x03000000) +#define PSEL8_P4_12_MASK (0x03000000) + +#define PSEL8_P4_13_GPIO (0x00000000) +#define PSEL8_P4_13_A13 (0x04000000) +#define PSEL8_P4_13_RSVD2 (0x08000000) +#define PSEL8_P4_13_RSVD3 (0x0c000000) +#define PSEL8_P4_13_MASK (0x0c000000) + +#define PSEL8_P4_14_GPIO (0x00000000) +#define PSEL8_P4_14_A14 (0x10000000) +#define PSEL8_P4_14_RSVD2 (0x20000000) +#define PSEL8_P4_14_RSVD3 (0x30000000) +#define PSEL8_P4_14_MASK (0x30000000) + +#define PSEL8_P4_15_GPIO (0x00000000) +#define PSEL8_P4_15_A15 (0x40000000) +#define PSEL8_P4_15_RSVD2 (0x80000000) +#define PSEL8_P4_15_RSVD3 (0xc0000000) +#define PSEL8_P4_15_MASK (0xc0000000) + +/* PINSEL 9 */ +/* PINSEL 9 bit 0:15 are reserved */ +#define PSEL9_P4_24_GPIO (0x00000000) +#define PSEL9_P4_24_OE (0x00010000) +#define PSEL9_P4_24_RSVD2 (0x00020000) +#define PSEL9_P4_24_RSVD3 (0x00030000) +#define PSEL9_P4_24_MASK (0x00030000) + +#define PSEL9_P4_25_GPIO (0x00000000) +#define PSEL9_P4_25_ (0x00040000) +#define PSEL9_P4_25_BLS0 (0x00080000) +#define PSEL9_P4_25_RSVD3 (0x000c0000) +#define PSEL9_P4_25_MASK (0x000c0000) + +/* PINSEL 9 bit 26:27 are reserved */ + +#define PSEL9_P4_28_GPIO (0x00000000) +#define PSEL9_P4_28_RSVD1 (0x01000000) +#define PSEL9_P4_28_MAT2_0 (0x02000000) +#define PSEL9_P4_28_TXD3 (0x03000000) +#define PSEL9_P4_28_MASK (0x03000000) + +#define PSEL9_P4_29_GPIO (0x00000000) +#define PSEL9_P4_29_RSVD1 (0x04000000) +#define PSEL9_P4_29_MAT2_1 (0x08000000) +#define PSEL9_P4_29_RXD3 (0x0c000000) +#define PSEL9_P4_29_MASK (0x0c000000) + +#define PSEL9_P4_30_GPIO (0x00000000) +#define PSEL9_P4_30_CS0 (0x10000000) +#define PSEL9_P4_30_RSVD2 (0x20000000) +#define PSEL9_P4_30_RSVD3 (0x30000000) +#define PSEL9_P4_30_MASK (0x30000000) + +#define PSEL9_P4_31_GPIO (0x00000000) +#define PSEL9_P4_31_CS1 (0x40000000) +#define PSEL9_P4_31_RSVD2 (0x80000000) +#define PSEL9_P4_31_RSVD3 (0xc0000000) +#define PSEL9_P4_31_MASK (0xc0000000) + +/* PINSEL 10 */ +#define PSEL10_ETM (0x00000002) + +/* TODO PINMODE pullup/pulldown resistor configuration */ +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_LPC23XX_PINSEL_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_pllsetup.c b/arch/arm/src/lpc2378/lpc23xx_pllsetup.c new file mode 100644 index 0000000000000000000000000000000000000000..77b43079615155a74daabdede60771cd36892603 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_pllsetup.c @@ -0,0 +1,260 @@ +/**************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_irq.c + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file holds the NuttX start logic that runs when the LPC2378 + * is reset. This logic must be located at address 0x0000:0000 in + * flash but may be linked to run at different locations based on + * the selected mode: + * + * default: Executes from 0x0000:0000. In non-default modes, the + * MEMAP register is set override the settings of the CPU configuration + * pins. + * + * CONFIG_LPC2378_EXTMEM_MODE: Code executes from external memory starting at + * address 0x8000:0000. + * + * CONFIG_LPC2378_RAM_MODE: Code executes from on-chip RAM at address + * 0x4000:0000. + * + * Start-up Code must be linked to run at the correct address + * corresponding to the selected mode. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "arm.h" +#include "up_arch.h" +#include "lpc2378.h" +#include "lpc23xx_pinsel.h" +#include "lpc23xx_scb.h" + +void IO_Init(void); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if ((FOSC < 32000) || (FOSC > 50000000)) +# error Fosc out of range (32KHz-50MHz) +# error correct and recompile +#endif + +#if ((CCLK < 10000000) || (CCLK > 72000000)) +# error cclk out of range (10MHz-72MHz) +# error correct PLL MULTIPLIER and recompile +#endif + +#if ((FCCO < 275000000) || (FCCO > 550000000)) +# error Fcco out of range (275MHz-550MHz) +# error internal algorithm error +#endif + +/* Phase Locked Loop (PLL) initialization values + * + * Bit 0:14 MSEL: PLL Multiplier "M" Value + * CCLK = 57 600 000 Hz + * Bit 16:23 NSEL: PLL Divider "N" Value + * Fcco = (2 * M * F_in) / N + * 275MHz <= Fcco <= 550MHz + * + * PLL clock sources: + * Internal RC 0 default on reset + * Main Oscillator 1 + * RTC 2 + */ + +#ifdef CONFIG_LPC2378_PLL_CLKSRC +# if ((CONFIG_LPC2378_PLL_CLKSRC < 0) || (CONFIG_LPC2378_PLL_CLKSRC > 2)) +# error "PLL clock source not valid, check configuration " +# endif +#else +# error "PLL clock source not defined, check configuration file" +#endif + +/* PLL provides CCLK and must always be configured */ + +#define PLL (PLL_M | (PLL_N << 16)) + +/* Memory Accelerator Module (MAM) initialization values + * + * MAM Control Register + * Bit 0:1 Mode + * 0 = Disabled + * 1 = Partially Enabled + * 2 = Fully Enabled + * MAM Timing Register + * Bit 0:2 Fetch Cycles + * 0 = Reserved + * 1 = 1 CCLK + * 2 = 2 CCLK + * 3 = 3 CCLK + * 4 = 4 CCLK + * 5 = 5 CCLK + * 6 = 6 CCLK + * 7 = 7 CCLK + */ + +/* LPC2378 Rev. '-' errata MAM may not work if fully enabled */ + +#ifdef CONFIG_LPC2378_MAM_SETUP +# ifndef CONFIG_LPC2378_MAMCR_VALUE /* Can be selected from config file */ +# define CONFIG_LPC2378_MAMCR_VALUE (MAMCR_PART) +# endif + +# ifndef CONFIG_LPC2378_MAMTIM_VALUE /* Can be selected from config file */ +# define CONFIG_LPC2378_MAMTIM_VALUE (0x00000003) +# endif +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_scbpllfeed + ****************************************************************************/ + +static inline void up_scbpllfeed(void) +{ + SCB_PLLFEED = 0xAA; + SCB_PLLFEED = 0x55; +} + +/**************************************************************************** + * Name: ConfigurePLL + ****************************************************************************/ + +void ConfigurePLL(void) +{ + uint32_t MSel, NSel; + + /* LPC2378 Rev.'-' errata Enable the Ethernet block to enable 16k EnetRAM */ + + SCB_PCONP |= PCENET; + + /* Vectors are remapped to Flash */ + + SCB_MEMMAP = MEMMAP2FLASH; + + /* Enable PLL, disconnected */ + + if (SCB_PLLSTAT & (1 << 25)) + { + SCB_PLLCON = 0x01; + up_scbpllfeed(); + } + + /* Disable PLL, disconnected */ + + SCB_PLLCON = 0; + up_scbpllfeed(); + + /* Enable main OSC */ + + SCB_SCS |= 0x20; + + /* Wait until main OSC is usable */ + + while (!(SCB_SCS & 0x40)); + + /* select main OSC, 12MHz, as the PLL clock source */ + + SCB_CLKSRCSEL = CONFIG_LPC2378_PLL_CLKSRC; + + /* Reconfigure PLL */ + + SCB_PLLCFG = PLL; + up_scbpllfeed(); + + /* Enable PLL */ + + SCB_PLLCON = 0x01; + up_scbpllfeed(); + + /* Set clock divider */ + + SCB_CCLKCFG = CCLK_DIV; + +#ifdef CONFIG_USBDEV + /* usbclk = 288 MHz/6 = 48 MHz */ + + SCB_USBCLKCFG = USBCLK_DIV; + + /* Turn On USB PCLK */ + + SCB_PCONP |= PCUSB; +#endif + + /* Wait for PLL to lock */ + + while ((SCB_PLLSTAT & (1 << 26)) == 0); + + MSel = SCB_PLLSTAT & 0x00007FFF; + NSel = (SCB_PLLSTAT & 0x00FF0000) >> 16; + while ((MSel != PLL_M) && (NSel != PLL_N)); + + /* Enable and connect */ + + SCB_PLLCON = 0x03; + up_scbpllfeed(); + + /* Check connect bit status */ + + while ((SCB_PLLSTAT & (1 << 25)) == 0); + + /* Set memory accelerater module */ + + SCB_MAMCR = 0; + SCB_MAMTIM = CONFIG_LPC2378_MAMTIM_VALUE; + SCB_MAMCR = CONFIG_LPC2378_MAMCR_VALUE; + + /* Enable FastIO on P0:P1 */ + + SCB_SCS |= 0x01; + + IO_Init(); + + return; +} diff --git a/arch/arm/src/lpc2378/lpc23xx_scb.h b/arch/arm/src/lpc2378/lpc23xx_scb.h new file mode 100644 index 0000000000000000000000000000000000000000..09004f3f26ce0ad7215076bf2026dd065459f3da --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_scb.h @@ -0,0 +1,134 @@ +/**************************************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_scb.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_SCB_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_SCB_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "lpc23xx_vic.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#define scb_getreg(o) getreg32(LPC23XX_SCB_BASE + (o)) +#define scb_putreg(v,o) putreg32((v),LPC23XX_SCB_BASE + (o)) + +/* Memory Accelerator Mode */ + +#define MAMCR_OFF 0 +#define MAMCR_PART 1 +#define MAMCR_FULL 2 + +/* Memory Mapping */ + +#define MEMMAP2BBLK 0 /* Interrupt Vectors in Boot Block */ +#define MEMMAP2FLASH 1 /* Interrupt Vectors in FLASH */ +#define MEMMAP2SRAM 2 /* Interrupt Vectors in RAM */ + +/* Register bit settings */ + +/* PLL Control Register Bit Settings */ + +#define PLLCON_PLLE (1 << 0) /* PLL Enable */ +#define PLLCON_PLLC (1 << 1) /* PLL Connect */ + +/* PLL Configuration Register Bit Settings */ + +#define PLLCFG_MSEL (0x0000ffff << 0) /* PLL Multiplier (minus 1) */ +#define PLLCFG_NSEL (0x000000ff << 16) /* PLL Divider */ + +/* PLL Status Register Bit Settings */ + +#define PLLSTAT_MSEL (0x7fff << 0) /* PLL Multiplier Readback */ +#define PLLSTAT_NSEL (0xff << 16) /* PLL Divider Readback */ +#define PLLSTAT_PLLE (1 << 24) /* PLL Enable Readback */ +#define PLLSTAT_PLLC (1 << 25) /* PLL Connect Readback */ +#define PLLSTAT_PLOCK (1 << 26) /* PLL Lock Status */ + +/* PLL Feed Register values */ + +#define PLLFEED1 0xaa +#define PLLFEED2 0x55 + +/* Peripheral Power Control (PCONP) Register 0xE01FC0C4 */ + +#define PCTIM0 (1 << 1) /* Timer/Counter 0 */ +#define PCTIM1 (1 << 2) /* Timer/Counter 1 */ +#define PCUART0 (1 << 3) /* UART0 power/clock */ +#define PCUART1 (1 << 4) /* UART1 power/clock */ +#define PCPWM1 (1 << 5) /* Unused, always 0 */ +#define PWM1 (1 << 6) /* Pulse Width Modulation 1 */ +#define PCI2C0 (1 << 7) /* I2C0 interface */ +#define PCSPI (1 << 8) /* SPI */ +#define PCRTC (1 << 9) /* Real Time Clock*/ +#define PCSSP1 (1 << 10) /* SSP1 */ +#define PCEMC (1 << 11) /* External Memory Controller */ +#define PCAD (1 << 12) /* A/D converter (ADC) Note: Clear the PDN + * bit in the AD0CR before clearing this bit, + * and set this bit before setting PDN */ +#define PCAN1 (1 << 13) /* CAN Controller 1 */ +#define PCAN2 (1 << 14) /* CAN Controller 2 */ +#define PCI2C1 (1 << 19) /* The I2C1 interface power/clock control bit */ +#define PCSSP0 (1 << 21) /* The SSP0 interface power/clock control bit */ +#define PCTIM2 (1 << 22) /* Timer 2 */ +#define PCTIM3 (1 << 23) /* Timer 3 */ +#define PCUART2 (1 << 24) /* UART 2 */ +#define PCUART3 (1 << 25) /* UART 3 */ +#define PCI2C2 (1 << 26) /* I2C interface 2 */ +#define PCI2S (1 << 27) /* I2S interface */ +#define PCSDC (1 << 28) /* SD card interface */ +#define PCGPDMA (1 << 29) /* GP DMA function */ +#define PCENET (1 << 30) /* Ethernet block */ +#define PCUSB (1 << 31) /* USB interface */ + +/**************************************************************************************************** + * Inline Functions + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_SCB_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_serial.c b/arch/arm/src/lpc2378/lpc23xx_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..389d713284b3bea29a3e509678beffe266ae453d --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_serial.c @@ -0,0 +1,973 @@ +/**************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_serial.c + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * With updates by: Gregory Nutt + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "lpc2378.h" +#include "lpc23xx_scb.h" +#include "lpc23xx_pinsel.h" +#include "lpc23xx_uart.h" +#include "lpc23xx_vic.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t * status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; + +/* This describes the state of the LPC214X uart0 port. */ + +#ifdef CONFIG_LPC2378_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = UART0_BASE_ADDR, + .baud = CONFIG_UART0_BAUD, + .irq = UART0_IRQ, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +#ifdef CONFIG_LPC2378_UART2 + +/* This describes the state of the LPC23XX uart2 port. */ + +static struct up_dev_s g_uart2priv = +{ + .uartbase = UART2_BASE_ADDR, + .baud = CONFIG_UART2_BAUD, + .irq = UART2_IRQ, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, + +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; + +#endif + +/* Now, which one with be tty0/console and which tty1? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port +# define TTYS0_DEV g_uart0port +# define TTYS1_DEV g_uart2port +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port +# define TTYS0_DEV g_uart2port +# define TTYS1_DEV g_uart0port +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint8_t * ier) +{ + if (ier) + { + *ier = priv->ier & IER_ALLIE; + } + + priv->ier &= ~IER_ALLIE; + up_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint8_t ier) +{ + priv->ier |= ier & IER_ALLIE; + up_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TX available condition */ + + for (tmp = 1000; tmp > 0; tmp--) + { + /* Check if the tranmitter holding register (THR) is empty */ + + if ((up_serialin(priv, UART_LSR_OFFSET) & LSR_THRE) != 0) + { + /* The THR is empty, return */ + + break; + } + } +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint8_t lcr = up_serialin(priv, UART_LCR_OFFSET); + if (enable) + { + lcr |= LCR_BREAK_ENABLE; + } + else + { + lcr &= ~LCR_BREAK_ENABLE; + } + up_serialout(priv, UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Name: up_configbaud + ****************************************************************************/ +static inline void up_configbaud(struct up_dev_s *priv) +{ + + /* In a buckled-up, embedded system, there is no reason to constantly + * calculate the following. The calculation can be skipped if the MULVAL, + * DIVADDVAL, and DIVISOR values are provided in the configuration file. + */ + +#ifndef CONFIG_UART_MULVAL + uint32_t qtrclk; + + /* Test values calculated for every multiplier/divisor combination */ + + uint32_t tdiv; + uint32_t terr; + int tmulval; + int tdivaddval; + + /* Optimal multiplier/divider values */ + + uint32_t div = 0; + uint32_t err = 100000; + int mulval = 1; + int divaddval = 0; + + /* Baud is generated using FDR and DLL-DLM registers + * + * baud = clock * (mulval/(mulval+divaddval) / (16 * div) + * + * Or + * + * div = (clock/16) * (mulval/(mulval+divaddval) / baud + * + * Where mulval = Fractional divider multiplier + * divaddval = Fractional divider pre-scale div + * div = DLL-DLM divisor + */ + + /* Get UART block clock divided by 16 */ + + qtrclk = U0_PCLK >> 4; /* TODO: Different Uart port with different clocking */ + + /* Try every valid multiplier, tmulval (or until a perfect match is found). */ + + for (tmulval = 1; tmulval <= 15 && err > 0; tmulval++) + { + /* Try every valid pre-scale div, tdivaddval (or until a perfect match is + * found). + */ + + for (tdivaddval = 0; tdivaddval <= 15 && err > 0; tdivaddval++) + { + /* Calculate the divisor with these fractional divider settings */ + + uint32_t tmp = (tmulval * qtrclk) / ((tmulval + tdivaddval)); + tdiv = (tmp + (priv->baud >> 1)) / priv->baud; + + /* Check if this candidate divisor is within a valid range */ + + if (tdiv > 2 && tdiv < 0x10000) + { + /* Calculate the actual baud and the error */ + + uint32_t actualbaud = tmp / tdiv; + + if (actualbaud <= priv->baud) + { + terr = priv->baud - actualbaud; + } + else + { + terr = actualbaud - priv->baud; + } + + /* Is this the smallest error we have encountered? */ + + if (terr < err) + { + /* Yes, save these settings as the new, candidate optimal + * settings + */ + + mulval = tmulval; + divaddval = tdivaddval; + div = tdiv; + err = terr; + } + } + } + } + + /* Configure the MS and LS DLAB registers */ + + up_serialout(priv, UART_DLM_OFFSET, div >> 8); + up_serialout(priv, UART_DLL_OFFSET, div & 0xff); + + /* Configure the Fractional Divider Register (FDR) */ + + up_serialout(priv, UART_FDR_OFFSET, ((mulval << 4) | divaddval)); + +#else + + /* Configure the MS and LS DLAB registers */ + up_serialout(priv, UART_DLM_OFFSET, DLMVAL >> 8); + up_serialout(priv, UART_DLL_OFFSET, DLLVAL & 0xff); + + /* Configure the Fractional Divider Register (FDR) */ + + up_serialout(priv, UART_FDR_OFFSET, ((MULVAL << 4) | DIVADDVAL)); + +#endif +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint8_t lcr; + + /* Clear fifos */ + + up_serialout(priv, UART_FCR_OFFSET, (FCR_RX_FIFO_RESET | FCR_TX_FIFO_RESET)); + + /* Set trigger */ + + up_serialout(priv, UART_FCR_OFFSET, (FCR_FIFO_ENABLE | FCR_FIFO_TRIG14)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, UART_IER_OFFSET); + + /* Set up the Line Control Register */ + + lcr = 0; + + lcr |= (priv->bits == 7) ? LCR_CHAR_7 : LCR_CHAR_8; + + if (priv->stopbits2) + { + lcr |= LCR_STOP_2; + } + + if (priv->parity == 1) + { + lcr |= LCR_PAR_ODD; + } + else if (priv->parity == 2) + { + lcr |= LCR_PAR_EVEN; + } + + /* Enable access to latch divisor DLAB=1 */ + + up_serialout(priv, UART_LCR_OFFSET, (lcr | LCR_DLAB_ENABLE)); + + /* find values for DLL, DLM, DIVADDVAL, MULVAL */ + + up_configbaud(priv); + + /* Disable access to latch divisor Clear DLAB */ + + up_serialout(priv, UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + up_serialout(priv, UART_FCR_OFFSET, + (FCR_FIFO_TRIG8 | FCR_TX_FIFO_RESET | + FCR_RX_FIFO_RESET | FCR_FIFO_ENABLE)); + + /* The NuttX serial driver waits for the first THRE interrupt before sending + * serial data... However, it appears that the LPC2378 hardware too does not + * generate that interrupt until a transition from not-empty to empty. So, + * the current kludge here is to send one NULL at startup to kick things off. + */ + + up_serialout(priv, UART_THR_OFFSET, '\0'); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled in the + * UART */ + + up_enable_irq(priv->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the UART interrupt priority */ + + up_prioritize_irq(priv->irq, PRIORITY_HIGHEST); +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint8_t status; + int passes; + + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop termination conditions */ + + status = up_serialin(priv, UART_IIR_OFFSET); + + /* The NO INTERRUPT should be zero if there are pending interrupts */ + + if ((status & IIR_NO_INT) != 0) + { + /* Break out of the loop when there is no longer a pending interrupt */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & IIR_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case IIR_RDA_INT: + case IIR_CTI_INT: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case IIR_THRE_INT: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts (UART1 only) */ + + case IIR_MS_INT: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, UART_MSR_OFFSET); + vdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case IIR_RLS_INT: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, + * unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, + * unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t * status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint8_t rbr; + + *status = up_serialin(priv, UART_LSR_OFFSET); + rbr = up_serialin(priv, UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= IER_ERBFI; +#endif + } + else + { + priv->ier &= ~IER_ERBFI; + } + up_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_LSR_OFFSET) & LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_THR_OFFSET, (uint8_t) ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= IER_ETBEI; +#endif + } + else + { + priv->ier &= ~IER_ETBEI; + } + up_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_LSR_OFFSET) & LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, UART_LSR_OFFSET) & LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Enable UART0 and 2 */ + + uint32_t pinsel = getreg32(LPC23XX_PINSEL0); + + pinsel &= ~(UART0_PINMASK | UART2_PINMASK); + pinsel |= (UART0_PINSEL | UART2_PINSEL); + + putreg32(pinsel, LPC23XX_PINSEL0); + + /* Set Uart PCLK divider */ + + SCB_PCLKSEL0 = (SCB_PCLKSEL0 & ~U0_PCLKSEL_MASK) | U0_PCLKSEL; + SCB_PCLKSEL1 = (SCB_PCLKSEL1 & ~U2_PCLKSEL_MASK) | U2_PCLKSEL; + + /* Disable both UARTS */ + + up_disableuartint(TTYS0_DEV.priv, NULL); + up_disableuartint(TTYS1_DEV.priv, NULL); + + /* Configuration whichever one is the console */ + + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t ier; + + up_disableuartint(priv, &ier); + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFSET, (uint8_t) ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, UART_THR_OFFSET, '\r'); + } + + up_waittxready(priv); + up_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + return ch; +} +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc2378/lpc23xx_spi.c b/arch/arm/src/lpc2378/lpc23xx_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..42c951c9540eafdca16df6aaef7c56be38da5ab6 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_spi.c @@ -0,0 +1,604 @@ +/**************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_spi.c + * + * Copyright (C) 2013 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * + * Derived from arch/arm/src/lpc17xx/lpc17_spi.c + * + * Copyright (C) 2010, 2012, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc23xx_pinsel.h" +#include "lpc23xx_scb.h" +#include "lpc23xx_spi.h" + +#ifdef CONFIG_LPC2378_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_SPI_EXCHANGE +# error CONFIG_SPI_EXCHANGE is not supported by this driver +#endif + +/* Debug ********************************************************************/ +/* CONFIG_DEBUG_SPI enables debug output from this file */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/* SPI Clocking. + * + * The CPU clock is divided by by 1, 2, 4, or 8 to get the SPI peripheral + * clock (SPI_CLOCK). SPI_CLOCK may be further divided by 8-254 to get the + * SPI clock. If we want a usable range of 4KHz to 25MHz for the SPI, then: + * + * 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz), + * and + * 2. SPICLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SPI_CLOCK. + * + * NOTE: CCLK must be defined in the board.h header file. + */ + +#define SPI_PCLKSET_DIV SYSCON_PCLKSEL_CCLK +#define SPI_CLOCK CCLK + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of the SSP driver */ + +struct lpc23xx_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = lpc23xx_spiselect, /* Provided externally */ + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc23xx_spistatus, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc23xx_spicmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc23xx_spiregister, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc23xx_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc23xx_spidev_s *priv = (FAR struct lpc23xx_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc23xx_spidev_s *priv = (FAR struct lpc23xx_spidev_s *)dev; + uint32_t divisor; + uint32_t actual; + + DEBUGASSERT(frequency <= SPI_CLOCK / 2); + + /* Check if the requested frequency is the same as the frequency selection */ + + DEBUGASSERT(priv != NULL); + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* frequency = SPI_CLOCK / divisor, or divisor = SPI_CLOCK / frequency */ + + divisor = SPI_CLOCK / frequency; + + /* The SPI CCR register must contain an even number greater than or equal to 8. */ + + if (divisor < 8) + { + divisor = 8; + } + else if (divisor > 254) + { + divisor = 254; + } + + divisor = (divisor + 1) & ~1; + + /* Save the new divisor value */ + + putreg32(divisor, SPI_CCR); + + /* Calculate the new actual */ + + actual = SPI_CLOCK / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc23xx_spidev_s *priv = (FAR struct lpc23xx_spidev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + DEBUGASSERT(priv != NULL); + if (mode != priv->mode) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(SPI_CR); + regval &= ~(SPI_CR_CPOL | SPI_CR_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CR_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CR_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CR_CPOL | SPI_CR_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + putreg32(regval, SPI_CR); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc23xx_spidev_s *priv = (FAR struct lpc23xx_spidev_s *)dev; + uint32_t regval; + + DEBUGASSERT(nbits > 7 && nbits < 17); + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv != NULL); + if (nbits != priv->nbits) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(SPI_CR); + regval &= ~SPI_CR_BITS_MASK; + regval |= (nbits << SPI_CR_BITS_SHIFT) & SPI_CR_BITS_MASK; + regval |= SPI_CR_BITENABLE; + putreg32(regval, SPI_CR); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + /* Write the data to transmitted to the SPI Data Register */ + + putreg32((uint32_t)wd, SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(SPI_SR); + return (uint16_t)getreg32(SPI_DR); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + uint8_t data; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + data = *ptr++; + putreg32((uint32_t)data, SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(SPI_SR); + nwords--; + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write some dummy data to the SPI Data Register in order to clock the + * read data. + */ + + putreg32(0xff, SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(SPI_SR); + + /* Read the received data from the SPI Data Register */ + + *ptr++ = (uint8_t)getreg32(SPI_DR); + nwords--; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc23_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc23_spibus_initialize(int port) +{ + FAR struct lpc23xx_spidev_s *priv = &g_spidev; + irqstate_t flags; + uint32_t regval; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SPI pins and + * one SPI1 pin (SCK) have multiple, alternative pin selection. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define GPIO_SPI_SCK GPIO_SPI_SCK_1 + */ + + flags = enter_critical_section(); + + regval = getreg32(LPC23XX_SCB_BASE+SCB_PCONP_OFFSET); + regval |= PCSPI; + putreg32(regval, LPC23XX_SCB_BASE+SCB_PCONP_OFFSET); + + regval = getreg32(LPC23XX_SCB_BASE+SCB_PCLKSEL0_OFFSET); + regval &= ~SPI_PCLKSEL_MASK; + regval |= SPI_PCLKSEL; + putreg32(regval, LPC23XX_SCB_BASE+SCB_PCLKSEL0_OFFSET); + + regval = getreg32(LPC23XX_PINSEL0); + regval &= ~SPI_PINSEL0_MASK ; + regval |= SPI_PINSEL0; + putreg32(regval, LPC23XX_PINSEL0); + + regval = getreg32(LPC23XX_PINSEL1); + regval &= ~SPI_PINSEL1_MASK ; + regval |= SPI_PINSEL1; + putreg32(regval, LPC23XX_PINSEL1); + + leave_critical_section(flags); + + /* Configure 8-bit SPI mode and master mode */ + + putreg32(SPI_CR_BITS_8BITS | SPI_CR_BITENABLE | SPI_CR_MSTR, SPI_CR); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + return &priv->spidev; +} + +#endif /* CONFIG_LPC2378_SPI */ diff --git a/arch/arm/src/lpc2378/lpc23xx_spi.h b/arch/arm/src/lpc2378/lpc23xx_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..f701c9e1f98b4ca79c60abc9aefbde8851dee2db --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_spi.h @@ -0,0 +1,184 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc23xx_spi.h + * + * Copyright (C) 2013 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * + * Derived arch/arm/src/lpc17xx/lpc17_spi.h + * + * Copyright (C) 2010, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_SPI_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* SPI Pin Configuration ************************************************************/ + +#define SPI_BASE SPI0_BASE_ADDR + +#define SPI_PCLKSEL_MASK (0x03 << 16) +#define SPI_PCLKSEL (0x01 << 16) + +#define SPI_PINSEL0_MASK (0x03 << 30) /* P0.15 SCK PINSEL0 */ +#define SPI_PINSEL1_MASK (0x0f << 2) /* P0.17 P0.18 PINSEL1 */ +#define SPI_PINSEL0 (0x03 << 30) +#define SPI_PINSEL1 (0x0f << 2) + +/* SPI PRegister offsets ************************************************************/ + +#define SPI_CR_OFFSET 0x0000 /* Control Register */ +#define SPI_SR_OFFSET 0x0004 /* SPI Status Register */ +#define SPI_DR_OFFSET 0x0008 /* SPI Data Register */ +#define SPI_CCR_OFFSET 0x000c /* SPI Clock Counter Register */ +#define SPI_TCR_OFFSET 0x0010 /* SPI Test Control Register */ +#define SPI_TSR_OFFSET 0x0014 /* SPI Test Status Register */ +#define SPI_INT_OFFSET 0x001c /* SPI Interrupt Register */ + +/* SPI Register addresses ***********************************************************/ + +#define SPI_CR (SPI_BASE+SPI_CR_OFFSET) +#define SPI_SR (SPI_BASE+SPI_SR_OFFSET) +#define SPI_DR (SPI_BASE+SPI_DR_OFFSET) +#define SPI_CCR (SPI_BASE+SPI_CCR_OFFSET) +#define TCR_CCR (SPI_BASE+SPI_TCR_OFFSET) +#define TSR_CCR (SPI_BASE+SPI_TSR_OFFSET) +#define SPI_INT (SPI_BASE+SPI_INT_OFFSET) + +/* SPI Register bit definitions *****************************************************/ + +/* Control Register */ + /* Bits 0-1: Reserved */ +#define SPI_CR_BITENABLE (1 << 2) /* Bit 2: Enable word size selected by BITS */ +#define SPI_CR_CPHA (1 << 3) /* Bit 3: Clock phase control */ +#define SPI_CR_CPOL (1 << 4) /* Bit 4: Clock polarity control */ +#define SPI_CR_MSTR (1 << 5) /* Bit 5: Master mode select */ +#define SPI_CR_LSBF (1 << 6) /* Bit 6: SPI data is transferred LSB first */ +#define SPI_CR_SPIE (1 << 7) /* Bit 7: Serial peripheral interrupt enable */ +#define SPI_CR_BITS_SHIFT (8) /* Bits 8-11: Number of bits per word (BITENABLE==1) */ +#define SPI_CR_BITS_MASK (15 << SPI_CR_BITS_SHIFT) +# define SPI_CR_BITS_8BITS (8 << SPI_CR_BITS_SHIFT) /* 8 bits per transfer */ +# define SPI_CR_BITS_9BITS (9 << SPI_CR_BITS_SHIFT) /* 9 bits per transfer */ +# define SPI_CR_BITS_10BITS (10 << SPI_CR_BITS_SHIFT) /* 10 bits per transfer */ +# define SPI_CR_BITS_11BITS (11 << SPI_CR_BITS_SHIFT) /* 11 bits per transfer */ +# define SPI_CR_BITS_12BITS (12 << SPI_CR_BITS_SHIFT) /* 12 bits per transfer */ +# define SPI_CR_BITS_13BITS (13 << SPI_CR_BITS_SHIFT) /* 13 bits per transfer */ +# define SPI_CR_BITS_14BITS (14 << SPI_CR_BITS_SHIFT) /* 14 bits per transfer */ +# define SPI_CR_BITS_15BITS (15 << SPI_CR_BITS_SHIFT) /* 15 bits per transfer */ +# define SPI_CR_BITS_16BITS (0 << SPI_CR_BITS_SHIFT) /* 16 bits per transfer */ + /* Bits 12-31: Reserved */ +/* SPI Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_SR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_SR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_SR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_SR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_SR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Data Register */ + +#define SPI_DR_MASK (0xff) /* Bits 0-15: SPI Bi-directional data port */ +#define SPI_DR_MASKWIDE (0xffff) /* Bits 0-15: If SPI_CR_BITENABLE != 0 */ + /* Bits 8-31: Reserved */ +/* SPI Clock Counter Register */ + +#define SPI_CCR_MASK (0xff) /* Bits 0-7: SPI Clock counter setting */ + /* Bits 8-31: Reserved */ +/* SPI Test Control Register */ + /* Bit 0: Reserved */ +#define SPI_TCR_TEST_SHIFT (1) /* Bits 1-7: SPI test mode */ +#define SPI_TCR_TEST_MASK (0x7f << SPI_TCR_TEST_SHIFT) + /* Bits 8-31: Reserved */ +/* SPI Test Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_TSR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_TSR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_TSR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_TSR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_TSR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Interrupt Register */ + +#define SPI_INT_SPIF (1 << 0) /* SPI interrupt */ + /* Bits 1-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: lpc23_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc23_spibus_initialize(int port); + +/**************************************************************************** + * These functions must be provided by the board specific logic that has knowledge + * the chip select and card detect GPIO configuration of the board. + * + ****************************************************************************/ + +void lpc23xx_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc23xx_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_SPI_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_timer.h b/arch/arm/src/lpc2378/lpc23xx_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..fe30b6b358d47255927d664ac2e0e3e25640314f --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_timer.h @@ -0,0 +1,163 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc23xx_timer.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_TIMER_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define tmr_getreg8(o) getreg8(LPC23XX_TMR0_BASE+(o)) +#define tmr_getreg16(o) getreg16(LPC23XX_TMR0_BASE+(o)) +#define tmr_getreg32(o) getreg32(LPC23XX_TMR0_BASE+(o)) + +#define tmr_putreg8(v,o) putreg8((v), LPC23XX_TMR0_BASE+(o)) +#define tmr_putreg16(v,o) putreg16((v), LPC23XX_TMR0_BASE+(o)) +#define tmr_putreg32(v,o) putreg32((v), LPC23XX_TMR0_BASE+(o)) +/* Timer registers are 8, 16-bit and 32-bits wide */ + +/* Timer Interrupt Register Bit Definitions (8-bit) */ + +#define TMR_IR_MR0I (1 << 0) /* Interrupt flag for match channel 0 */ +#define TMR_IR_MR1I (1 << 1) /* Interrupt flag for match channel 1 */ +#define TMR_IR_MR2I (1 << 2) /* Interrupt flag for match channel 2 */ +#define TMR_IR_MR3I (1 << 3) /* Interrupt flag for match channel 3 */ +#define TMR_IR_CR0I (1 << 4) /* Interrupt flag for capture channel 0 event */ +#define TMR_IR_CR1I (1 << 5) /* Interrupt flag for capture channel 1 event */ +#define TMR_IR_CR2I (1 << 6) /* Interrupt flag for capture channel 2 event */ +#define TMR_IR_CR3I (1 << 7) /* Interrupt flag for capture channel 3 event */ +#define TMR_IR_ALLI (0xff) /* All timer interrupts */ + +/* Timer Control Register Bit Definitions (8-bits) */ + +#define TMR_CR_ENABLE (1 << 0) /* Counter Enable */ +#define TMR_CR_RESET (1 << 1) /* Countger Reset */ + +/* Timer Counter (32-bits, no bit fields) */ + +/* Timer Prescale Register Bit Definitions (32-bits, no bit fields) */ + +/* Timer Prescale Counter Register Bit Definitions */ + +/* Timer Match Control Register Bit Definitions (16-bit) */ + +#define TMR_MCR_MR0I (1 << 0) /* Enable Interrupt when MR0 matches TC */ +#define TMR_MCR_MR0R (1 << 1) /* Enable Reset of TC upon MR0 match */ +#define TMR_MCR_MR0S (1 << 2) /* Enable Stop of TC upon MR0 match */ +#define TMR_MCR_MR1I (1 << 3) /* Enable Interrupt when MR1 matches TC */ +#define TMR_MCR_MR1R (1 << 4) /* Enable Reset of TC upon MR1 match */ +#define TMR_MCR_MR1S (1 << 5) /* Enable Stop of TC upon MR1 match */ +#define TMR_MCR_MR2I (1 << 6) /* Enable Interrupt when MR2 matches TC */ +#define TMR_MCR_MR2R (1 << 7) /* Enable Reset of TC upon MR2 match */ +#define TMR_MCR_MR2S (1 << 8) /* Enable Stop of TC upon MR2 match */ +#define TMR_MCR_MR3I (1 << 9) /* Enable Interrupt when MR3 matches TC */ +#define TMR_MCR_MR3R (1 << 10) /* Enable Reset of TC upon MR3 match */ +#define TMR_MCR_MR3S (1 << 11) /* Enable Stop of TC upon MR3 match */ + +/* Timer Match Register 0/1/2/3 (32-bits, no bit fields) */ + +/* Timer Capture Control Register Bit Definitions */ + +#define TMR_CCR_CAP0RE (1 << 0) /* Enable Rising edge on CAPn.0 will load TC to CR0 */ +#define TMR_CCR_CAP0FE (1 << 1) /* Enable Falling edge on CAPn.0 will load TC to CR0 */ +#define TMR_CCR_CAP0I (1 << 2) /* Enable Interrupt on load of CR0 */ +#define TMR_CCR_CAP1RE (1 << 3) /* Enable Rising edge on CAPn.1 will load TC to CR1 */ +#define TMR_CCR_CAP1FE (1 << 4) /* Enable Falling edge on CAPn.1 will load TC to CR1 */ +#define TMR_CCR_CAP1I (1 << 5) /* Enable Interrupt on load of CR1 */ +//~ #define TMR_CCR_CAP2RE (1 << 6) /* Enable Rising edge on CAPn.2 will load TC to CR2 */ +//~ #define TMR_CCR_CAP2FE (1 << 7) /* Enable Falling edge on CAPn.2 will load TC to CR2 */ +//~ #define TMR_CCR_CAP2I (1 << 8) /* Enable Interrupt on load of CR2 */ +//~ #define TMR_CCR_CAP3RE (1 << 9) /* Enable Rising edge on CAPn.3 will load TC to CR3 */ +//~ #define TMR_CCR_CAP3FE (1 << 10) /* Enable Falling edge on CAPn.3 will load TC to CR3 */ +//~ #define TMR_CCR_CAP3I (1 << 11) /* Enable Interrupt on load of CR3 */ + +/* Timer Capture Register 0/1/2/3 (32-bits, no bit fields) */ + +/* Timer External Match Register Bit Definitions */ + +#define TMR_EMR_EM0 (1 << 0) /* External Match 0 */ +#define TMR_EMR_EM1 (1 << 1) /* External Match 1 */ +#define TMR_EMR_EM2 (1 << 2) /* External Match 2 */ +#define TMR_EMR_EM3 (1 << 3) /* External Match 3 */ + +#define TMR_EMR_EMC0(b) ((b) << 4) /* External match control 0 (see below) */ +#define TMR_EMR_EMC1(b) ((b) << 6) /* External match control 1 (see below) */ +#define TMR_EMR_EMC2(b) ((b) << 8) /* External match control 2 (see below) */ +#define TMR_EMR_EMC3(b) ((b) << 10) /* External match control 3 (see below) */ + +/* EMR External Match Control (EMCn) Field Falues */ + +#define TMR_EMR_MASK (3) /* Mask for all bits */ +#define TMR_EMR_NOOP (0) /* Do nothing */ +#define TMR_EMR_CLEAR (1) /* Clear corresponding EMn bit/output to 0 */ +#define TMR_EMR_SET (2) /* Set corresponding EMn bit/output to 1 */ +#define TMR_EMR_TOGGLE (3) /* Toggle corresponding EMn bit/output */ + +/* Timer Count Control Register Bit Definitions (8-bit) */ + +#define TMR_CTCR_MODE_MASK (3 << 0) /* Counter/Timer Mode */ +#define TMR_CTCR_PCLK (0 << 0) /* Rising edge of PCLK */ +#define TMR_CTCR_RISING (1 << 0) /* Rising edge of CAP input */ +#define TMR_CTDR_FALLING (2 << 0) /* Failing edge of CAP input */ +#define TMR_CTCR_BOTH (3 << 0) /* Both edges of CAP input */ +#define TMR_CTCR_INPUT_MASK (3 << 2) /* Counter Input Select */ +#define TMR_CTCR_CR0 (0 << 2) /* CAPn.0 */ +#define TMR_CTCR_CR1 (1 << 2) /* CAPn.1 */ +#define TMR_CTCR_CR2 (2 << 2) /* CAPn.2 */ +#define TMR_CTCR_CR3 (3 << 2) /* CAPn.3 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_TIMER_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_timerisr.c b/arch/arm/src/lpc2378/lpc23xx_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..9ff6cf862a03e8113221f5ce7e9c3acf348c87ee --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_timerisr.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/arm/src/lpc2378/lpc23xx_timerisr.c + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "clock/clock.h" +#include "lpc2378.h" +#include "up_arch.h" + +#include "lpc23xx_scb.h" +#include "lpc23xx_vic.h" +#include "lpc23xx_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* T0_PCLKDIV valid values are 1,2,4 */ + +#define T0_PCLK_DIV 1 + +/* PCKLSEL0 bits 3:2, 00=CCLK/4, 01=CCLK/1 , 10=CCLK/2 */ + +#ifdef T0_PCLK_DIV +# if T0_PCLK_DIV == 1 +# define TIMER0_PCLKSEL (0x00000004) +# elif T0_PCLK_DIV == 2 +# define TIMER0_PCLKSEL (0x00000008) +# elif T0_PCLK_DIV == 4 +# define TIMER0_PCLKSEL (0x00000000) +# endif +#endif + +#define T0_PCLKSEL_MASK (0x0000000C) + +#define T0_TICKS_COUNT ((CCLK / T0_PCLK_DIV) / TICK_PER_SEC) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for + * various portions of the systems. + * + ****************************************************************************/ + +#ifdef CONFIG_VECTORED_INTERRUPTS +int up_timerisr(uint32_t * regs) +#else +int up_timerisr(int irq, uint32_t * regs) +#endif +{ + static uint32_t tick; + + /* Process timer interrupt */ + + sched_process_timer(); + + /* Clear the MR0 match interrupt */ + + tmr_putreg8(TMR_IR_MR0I, TMR_IR_OFFSET); + + /* Reset the VIC as well */ + +#ifdef CONFIG_VECTORED_INTERRUPTS + /* write any value to VICAddress to acknowledge the interrupt */ + vic_putreg(0, VIC_ADDRESS_OFFSET); +#endif + + if (tick++ > 100) + { + tick = 0; + lpc2378_statledoff(); + } + else + { + lpc2378_statledon(); + } + + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the system timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint16_t mcr; + + /* Power up Timer0 */ + + SCB_PCONP |= PCTIM0; + + /* Timer0 clock input frequency = CCLK / TO_PCLKDIV */ + + SCB_PCLKSEL0 = (SCB_PCLKSEL0 & ~T0_PCLKSEL_MASK) | TIMER0_PCLKSEL; + + /* Clear all match and capture event interrupts */ + + tmr_putreg8(TMR_IR_ALLI, TMR_IR_OFFSET); + + /* Clear the timer counter */ + + tmr_putreg32(0, TMR_TC_OFFSET); + + /* No pre-scaler */ + + tmr_putreg32(0, TMR_PR_OFFSET); + tmr_putreg32(0, TMR_PC_OFFSET); + + /* Set timer match register to get a TICK_PER_SEC rate See arch/board.h and + */ + + tmr_putreg32(T0_TICKS_COUNT, TMR_MR0_OFFSET); /* 10ms Intterrupt */ + + /* Reset timer counter register and interrupt on match */ + + mcr = tmr_getreg16(TMR_MCR_OFFSET); + mcr &= ~TMR_MCR_MR1I; + mcr |= (TMR_MCR_MR0I | TMR_MCR_MR0R); + tmr_putreg16(mcr, TMR_MCR_OFFSET); /* -- bit 0=1 -int on MR0, bit 1=1 - Reset on MR0 */ + + /* Enable counting */ + /* ~ tmr_putreg32(1, TMR_TCR_OFFSET); */ + + tmr_putreg8(TMR_CR_ENABLE, TMR_TCR_OFFSET); + + /* Attach the timer interrupt vector */ + +#ifdef CONFIG_VECTORED_INTERRUPTS + up_attach_vector(IRQ_SYSTIMER, ???, (vic_vector_t) up_timerisr); +#else + (void)irq_attach(IRQ_SYSTIMER, (xcpt_t) up_timerisr); +#ifdef CONFIG_ARCH_IRQPRIO + up_prioritize_irq(IRQ_SYSTIMER, PRIORITY_HIGHEST); +#endif +#endif + + /* And enable the system timer interrupt */ + + up_enable_irq(IRQ_SYSTIMER); +} diff --git a/arch/arm/src/lpc2378/lpc23xx_uart.h b/arch/arm/src/lpc2378/lpc23xx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..ccdd26f9e6417b98815a2deadf140d5062420b82 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_uart.h @@ -0,0 +1,231 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc2378/uart.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_UART_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include /* For clock settings */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Derive baud divisor setting from clock settings (see board.h) */ +//--F_in = 57 600 000 Hz U0DLM=0, U0DLL=25, DIVADDVAL=3, MULVAL=12, baudrate=115200, err = 0.000000 % +//--F_in = 57 600 000 Hz U0DLM=1, U0DLL=119, DIVADDVAL=0, MULVAL=1, baudrate=9600, err = 0.000000 % +/* Used only if CONFIG_UART_MULVAL is not defined */ +#define DIVADDVAL 0 +#define MULVAL 1 +#define DLMVAL 1 +#define DLLVAL 119 + +/* UARTx PCLK divider valid values are 1,2,4 */ +#define U0_PCLKDIV 1 +//~ #define U1_PCLKDIV 1 +#define U2_PCLKDIV 1 +//~ #define U3_PCLKDIV 1 + + +#define U0_PCLK (CCLK / U0_PCLKDIV) +//~ #define U1_PCLK (CCLK / U1_PCLKDIV) +#define U2_PCLK (CCLK / U2_PCLKDIV) +//~ #define U3_PCLK (CCLK / U3_PCLKDIV) + +#define U0_PCLKSEL_MASK (0x000000C0) +#define U2_PCLKSEL_MASK (0x00030000) + +/* PCKLSEL0 bits 7:6, 00=CCLK/4, 01=CCLK/1 , 10=CCLK/2 */ +#ifdef U0_PCLKDIV +# if U0_PCLKDIV == 1 +# define U0_PCLKSEL (0x00000040) +# elif U0_PCLKDIV == 2 +# define U0_PCLKSEL (0x00000080) +# elif U0_PCLKDIV == 4 +# define U0_PCLKSEL (0x00000000) +# endif +#else +# error "UART0 PCLK divider not set" +#endif + +/* PCKLSEL1 bits 17:16, 00=CCLK/4, 01=CCLK/1 , 10=CCLK/2 */ +#ifdef U2_PCLKDIV +# if U2_PCLKDIV == 1 +# define U2_PCLKSEL (0x00010000) +# elif U2_PCLKDIV == 2 +# define U2_PCLKSEL (0x00020000) +# elif U2_PCLKDIV == 4 +# define U2_PCLKSEL (0x00000000) +# endif +#else +# error "UART2 PCLK divider not set" +#endif + + + + +/* Universal Asynchronous Receiver Transmitter Base Addresses */ +#define UART0_BASE_ADDR 0xE000C000 +#define UART1_BASE_ADDR 0xE0010000 +#define UART2_BASE_ADDR 0xE0078000 +#define UART3_BASE_ADDR 0xE007C000 + +/* UART 0/1/2/3 Register Offsets */ +#define UART_RBR_OFFSET 0x00 /* R: Receive Buffer Register (DLAB=0) */ +#define UART_THR_OFFSET 0x00 /* W: Transmit Holding Register (DLAB=0) */ +#define UART_DLL_OFFSET 0x00 /* W: Divisor Latch Register (LSB, DLAB=1) */ +#define UART_IER_OFFSET 0x04 /* W: Interrupt Enable Register (DLAB=0) */ +#define UART_DLM_OFFSET 0x04 /* RW: Divisor Latch Register (MSB, DLAB=1) */ +#define UART_IIR_OFFSET 0x08 /* R: Interrupt ID Register */ +#define UART_FCR_OFFSET 0x08 /* W: FIFO Control Register */ +#define UART_LCR_OFFSET 0x0c /* RW: Line Control Register */ +#define UART_MCR_OFFSET 0x10 /* RW: Modem Control REgister (2146/6/8 UART1 Only) */ +#define UART_LSR_OFFSET 0x14 /* R: Scratch Pad Register */ +#define UART_MSR_OFFSET 0x18 /* RW: MODEM Status Register (2146/6/8 UART1 Only) */ +#define UART_SCR_OFFSET 0x1c /* RW: Line Status Register */ +#define UART_ACR_OFFSET 0x20 /* RW: Autobaud Control Register */ +#define UART_FDR_OFFSET 0x28 /* RW: Fractional Divider Register */ +#define UART_TER_OFFSET 0x30 /* RW: Transmit Enable Register */ + +/* PINSEL0 bit definitions for UART0/2 */ + +#define UART0_PINSEL 0x00000050 /* PINSEL0 value for UART0 */ +#define UART0_PINMASK 0x000000F0 /* PINSEL0 mask for UART0 */ + +#define UART1_TX_PINSEL 0x40000000 /* PINSEL0 value for UART1 Tx */ +#define UART1_TXPINMASK 0xC0000000 /* PINSEL0 mask for UART1 Tx */ +#define UART1_RX_PINSEL 0x00000001 /* PINSEL1 value for UART1 Rx */ +#define UART1_RX_PINMASK 0x00000003 /* PINSEL1 mask for UART1 Rx */ +#define UART1_MODEM_PINSEL 0x00001555 /* PINSEL1 mask for UART1 Modem Interface */ +#define UART1_CTS_PINMASK 0x00003FFF /* PINSEL1 mask for UART1 Modem Interface */ +//~ #define UART1_CTS_PINSEL 0x00000004 /* PINSEL1 mask for UART1 CTS */ +//~ #define UART1_CTS_PINMASK 0x0000000C /* PINSEL1 mask for UART1 CTS */ +//~ #define UART1_CTS_PINSEL 0x00000010 /* PINSEL1 mask for UART1 Rx */ +//~ #define UART1_CTS_PINMASK 0x00000030 /* PINSEL1 mask for UART1 Rx */ +#define UART2_PINSEL 0x00500000 /* PINSEL0 value for UART2 */ +#define UART2_PINMASK 0x00F00000 /* PINSEL0 mask for UART2 */ + +#define UART3_PINSEL 0x0F000000 /* PINSEL9 value for UART3 */ +#define UART3_PINMASK 0x0F000000 /* PINSEL9 mask for UART3 */ + +/* Interrupt Enable Register (IER) bit definitions */ + +#define IER_ERBFI (1 << 0) /* Enable receive data available int */ +#define IER_ETBEI (1 << 1) /* Enable THR empty Interrupt */ +#define IER_ELSI (1 << 2) /* Enable receive line status int */ +#define IER_EDSSI (1 << 3) /* Enable MODEM atatus interrupt (2146/6/8 UART1 Only) */ +#define IER_ALLIE 0x0f /* All interrupts */ + +/* Interrupt ID Register(IIR) bit definitions */ + +#define IIR_NO_INT (1 << 0) /* No interrupts pending */ +#define IIR_MS_INT (0 << 1) /* MODEM Status (UART1 only) */ +#define IIR_THRE_INT (1 << 1) /* Transmit Holding Register Empty */ +#define IIR_RDA_INT (2 << 1) /* Receive Data Available */ +#define IIR_RLS_INT (3 << 1) /* Receive Line Status */ +#define IIR_CTI_INT (6 << 1) /* Character Timeout Indicator */ +#define IIR_MASK 0x0e + +/* FIFO Control Register (FCR) bit definitions */ + +#define FCR_FIFO_ENABLE (1 << 0) /* FIFO enable */ +#define FCR_RX_FIFO_RESET (1 << 1) /* Reset receive FIFO */ +#define FCR_TX_FIFO_RESET (1 << 2) /* Reset transmit FIFO */ +#define FCR_FIFO_TRIG1 (0 << 6) /* Trigger @1 character in FIFO */ +#define FCR_FIFO_TRIG4 (1 << 6) /* Trigger @4 characters in FIFO */ +#define FCR_FIFO_TRIG8 (2 << 6) /* Trigger @8 characters in FIFO */ +#define FCR_FIFO_TRIG14 (3 << 6) /* Trigger @14 characters in FIFO */ + +/* Line Control Register (LCR) bit definitions */ + +#define LCR_CHAR_5 (0 << 0) /* 5-bit character length */ +#define LCR_CHAR_6 (1 << 0) /* 6-bit character length */ +#define LCR_CHAR_7 (2 << 0) /* 7-bit character length */ +#define LCR_CHAR_8 (3 << 0) /* 8-bit character length */ +#define LCR_STOP_1 (0 << 2) /* 1 stop bit */ +#define LCR_STOP_2 (1 << 2) /* 2 stop bits */ +#define LCR_PAR_NONE (0 << 3) /* No parity */ +#define LCR_PAR_ODD (1 << 3) /* Odd parity */ +#define LCR_PAR_EVEN (3 << 3) /* Even parity */ +#define LCR_PAR_MARK (5 << 3) /* Mark "1" parity */ +#define LCR_PAR_SPACE (7 << 3) /* Space "0" parity */ +#define LCR_BREAK_ENABLE (1 << 6) /* Output BREAK */ +#define LCR_DLAB_ENABLE (1 << 7) /* Enable divisor latch access */ + +/* Modem Control Register (MCR) bit definitions */ + +#define MCR_DTR (1 << 0) /* Data terminal ready */ +#define MCR_RTS (1 << 1) /* Request to send */ +#define MCR_LB (1 << 4) /* Loopback */ + +/* Line Status Register (LSR) bit definitions */ + +#define LSR_RDR (1 << 0) /* Receive data ready */ +#define LSR_OE (1 << 1) /* Overrun error */ +#define LSR_PE (1 << 2) /* Parity error */ +#define LSR_FE (1 << 3) /* Framing error */ +#define LSR_BI (1 << 4) /* Break interrupt */ +#define LSR_THRE (1 << 5) /* THR empty */ +#define LSR_TEMT (1 << 6) /* Transmitter empty */ +#define LSR_RXFE (1 << 7) /* Error in receive FIFO */ +#define LSR_ERR_MASK 0x1e + +/* Modem Status Register (MSR) bit definitions */ + +#define MSR_DCTS (1 << 0) /* Delta clear to send */ +#define MSR_DDSR (1 << 1) /* Delta data set ready */ +#define MSR_TERI (1 << 2) /* Trailing edge ring indicator */ +#define MSR_DDCD (1 << 3) /* Delta data carrier detect */ +#define MSR_CTS (1 << 4) /* Clear to send */ +#define MSR_DSR (1 << 5) /* Data set ready */ +#define MSR_RI (1 << 6) /* Ring indicator */ +#define MSR_DCD (1 << 7) /* Data carrier detect */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_UART_H */ diff --git a/arch/arm/src/lpc2378/lpc23xx_vic.h b/arch/arm/src/lpc2378/lpc23xx_vic.h new file mode 100644 index 0000000000000000000000000000000000000000..82a7995fbeb76fead50031feab786401d477ec35 --- /dev/null +++ b/arch/arm/src/lpc2378/lpc23xx_vic.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/lpc2378/lpc23xx_vic.h + * + * Copyright (C) 2010 Rommel Marcelo. All rights reserved. + * Author: Rommel Marcelo + * + * This file is part of the NuttX RTOS and based on the lpc2148 port: + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC2378_LPC23XX_VIC_H +#define __ARCH_ARM_SRC_LPC2378_LPC23XX_VIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* All VIC registers are 32-bits wide */ + +#define vic_getreg(o) getreg32(LPC23XX_VIC_BASE + (o)) +#define vic_putreg(v,o) putreg32((v),LPC23XX_VIC_BASE + (o)) + +/* Vector Control Register bit definitions */ + +//~ #define LPC23XX_VECTPRIORITY_IRQMASK (0x0000001f) +//~ #define VECTPRIORITY_IRQMASK (0x0000FFFF) +//~ #define LPC23XX_VECTPRIORITY_IRQSHIFT (0) +//~ #define LPC23XX_VECTPRIORITY_ENABLE (1 << 5) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC2378_LPC23XX_VIC_H */ diff --git a/arch/arm/src/lpc31xx/Kconfig b/arch/arm/src/lpc31xx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bb3f94350689f1038ea12e5da24196f835656293 --- /dev/null +++ b/arch/arm/src/lpc31xx/Kconfig @@ -0,0 +1,317 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC31xx Configuration Options" + +choice + prompt "LPC31 Chip Selection" + default ARCH_CHIP_LPC3131 + depends on ARCH_CHIP_LPC31XX + +config ARCH_CHIP_LPC3130 + bool "LPC3130" + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + select ARCH_HAVE_EXTDRAM + +config ARCH_CHIP_LPC3131 + bool "LPC3131" + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + select ARCH_HAVE_EXTDRAM + +config ARCH_CHIP_LPC3152 + bool "LPC3152" + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + select ARCH_HAVE_EXTDRAM + +config ARCH_CHIP_LPC3154 + bool "LPC3154" + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + select ARCH_HAVE_EXTDRAM + +endchoice # LPC31xx Configuration Options + +config LPC31_SDRAMHCLK + int "External SDRAM HCLK" + depends on LPC31_EXTSDRAM + ---help--- + The SDRAM HCLK may be specified here (if not, it will be calculated). + +menu "LPC31xx Peripheral Support" + +config LPC31_UART + bool "UART" + default n + select ARCH_HAVE_UART + +config LPC31_SPI + bool "SPI" + default n + +config LPC31_USBOTG + bool "USB OTG" + default n + select USBHOST_HAVE_ASYNCH + +config LPC31_MCI + bool "MCI" + default n + select ARCH_HAVE_SDIO + +endmenu # LPC31xx Peripheral Support + +menu "External Memory Configuration" + +config ARCH_HAVE_EXTNAND + bool + +config ARCH_HAVE_EXTDRAM + bool + +config ARCH_HAVE_EXTSRAM0 + bool + +config ARCH_HAVE_EXTSRAM1 + bool + +config LPC31_EXTNAND + bool "Configure external NAND" + default n + depends on ARCH_HAVE_EXTNAND + ---help--- + Configure external NAND memory and, if applicable, map then external + NAND into the memory map. + +if LPC31_EXTNAND + +config LPC31_EXTNANDSIZE + int "External NAND size" + default 0 + ---help--- + Size of the external NAND in bytes. + +endif # LPC31_EXTNAND + +config LPC31_EXTDRAM + bool "Configure external DRAM" + default n + depends on ARCH_HAVE_EXTDRAM + select ARCH_HAVE_SDRAM + ---help--- + Configure external DRAM memory and, if applicable, map then external + DRAM into the memory map. + +if LPC31_EXTDRAM + +config LPC31_EXTDRAMSIZE + int "External SDRAM size" + default 0 + ---help--- + Size of the external SDRAM in bytes. + +choice + prompt "SDRAM Width Selection" + default LPC31_SDRAM_16BIT + +config LPC31_SDRAM_8BIT + bool "8-bit" + +config LPC31_SDRAM_16BIT + bool "16-bit" + +config LPC31_SDRAM_32BIT + bool "32-bit" + +endchoice # SDRAM Width Selection + +config LPC31_EXTDRAMHEAP + bool "Add external SDRAM to the heap" + default y + ---help--- + Add the external SDRAM into the heap. + +endif # LPC31_EXTDRAM + +config LPC31_EXTSRAM0 + bool "Configure external SRAM (Bank 0)" + default n + depends on ARCH_HAVE_EXTSRAM0 + ---help--- + Configure external SRAM Bank 0 memory and, if applicable, map then + external SRAM Bank 0 into the memory map. + +if LPC31_EXTSRAM0 + +config LPC31_EXTSRAM0SIZE + int "External SRAM size" + default 0 + ---help--- + Size of the external SRAM Bank 0 in bytes. + +config LPC31_EXTSRAM0HEAP + bool "Add external SRAM (Bank 0) to the heap" + default y + ---help--- + Add external SRAM Bank 0 into the heap. + +endif # LPC31_EXTSRAM0 + +config LPC31_EXTSRAM1 + bool "Configure external SRAM (Bank 1)" + default n + depends on ARCH_HAVE_EXTSRAM1 + ---help--- + Configure external SRAM Bank 1 memory and, if applicable, map then + external SRAM Bank 1 into the memory map. + +if LPC31_EXTSRAM1 + +config LPC31_EXTSRAM1SIZE + int "External SRAM1 size" + default 0 + ---help--- + Size of the external SRAM Bank 1 in bytes. + +config LPC31_EXTSRAM1HEAP + bool "Add external SRAM (Bank 1) to the heap" + default y + ---help--- + Add external SRAM Bank 1 into the heap. + +endif # LPC31_EXTSRAM1 +endmenu # External Memory Configuration + +menu "LPC31xx UART Configuration" + depends on LPC31_UART + +config LPC31_UART_PRECALCULATED + bool "Use pre-calculated BAD configuration" + default n + +if LPC31_UART_PRECALCULATED + +config LPC31_UART_DIVADDVAL + int "BAUD pre-scaler divisor" + ---help--- + BAUD pre-scaler divisor + +config LPC31_UART_DIVISOR + int "BAUD divisor" + ---help--- + BAUD divisor + +config LPC31_UART_MULVAL + int "BAUD multiplier" + ---help--- + BAUD multiplier + +endif # LPC31_UART_PRECALCULATED +endmenu # LPC31xx UART Configuration + +if LPC31_USBOTG && USBDEV + +menu "USB device controller driver (DCD) options" + +config LPC31_USBDEV_EP0_MAXSIZE + int "EP0 Max packet size" + default 64 + ---help--- + Endpoint 0 maximum packet size. Default: 64 + +config LPC31_USBDEV_FRAME_INTERRUPT + bool "USB frame interrupt" + default n + ---help--- + Handle USB Start-Of-Frame events. Enable reading SOF from interrupt + handler vs. simply reading on demand. Probably a bad idea... Unless + there is some issue with sampling the SOF from hardware asynchronously. + +config LPC31_USBDEV_DMA + bool "Enable USB device DMA" + default n + ---help--- + Enable lpc31xx-specific DMA support + +config LPC31_USBDEV_REGDEBUG + bool "Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level USB device debug information. Requires also DEBUG. + +endmenu # USB device driver controller (DCD) options +endif # LPC31_USBOTG && USBDEV + +if LPC31_USBOTG && USBHOST + +menu "USB host controller driver (HCD) options" + +config LPC31_EHCI_SDIS + bool "Stream disable" + default n + ---help--- + Selecting this option ensures that overruns/underruns of the latency + FIFO are eliminated for low bandwidth systems where the RX and TX + buffers are sufficient to contain the entire packet. Enabling stream + disable also has the effect of ensuring the the TX latency is filled + to capacity before the packet is launched onto the USB. + + Note: Time duration to pre-fill the FIFO becomes significant when stream disable is active. + +config LPC31_EHCI_NQHS + int "Number of Queue Head (QH) structures" + default 4 + ---help--- + Configurable number of Queue Head (QH) structures. The default is + one per Root hub port plus one for EP0 (4). + +config LPC31_EHCI_NQTDS + int "Number of Queue Element Transfer Descriptor (qTDs)" + default 6 + ---help--- + Configurable number of Queue Element Transfer Descriptor (qTDs). + The default is one per root hub plus three from EP0 (6). + +config LPC31_EHCI_BUFSIZE + int "Size of one request/descriptor buffer" + default 128 + ---help--- + The size of one request/descriptor buffer in bytes. The TD buffe + size must be an even number of 32-bit words and must be large enough + to hangle the largest transfer via a SETUP request. + +config LPC31_EHCI_PREALLOCATE + bool "Preallocate descriptor pool" + default y + ---help--- + Select this option to pre-allocate EHCI queue and descriptor + structure pools in .bss. Otherwise, these pools will be + dynamically allocated using kmm_memalign(). + +config LPC31_EHCI_REGDEBUG + bool "Enable low-level EHCI register debug" + default n + depends on DEBUG + +endmenu # USB host controller driver (HCD) options +endif # LPC31_USBOTG && USBHOST + +menu "SPI device driver options" + +config LPC31_SPI_REGDEBUG + bool "SPI Register level debug" + depends on LPC31_SPI && DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. Requires also DEBUG. + +endmenu # SPI device driver options diff --git a/arch/arm/src/lpc31xx/Make.defs b/arch/arm/src/lpc31xx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..03c6c0bef6ed87f7a8133cc1e6750d68afd2e82f --- /dev/null +++ b/arch/arm/src/lpc31xx/Make.defs @@ -0,0 +1,89 @@ +############################################################################ +# arch/arm/lpc31xx/Make.defs +# +# Copyright (C) 2009-2011, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = up_head.S + +CMN_ASRCS = up_cache.S up_fullcontextrestore.S up_saveusercontext.S +CMN_ASRCS += up_vectors.S up_vectoraddrexcptn.S up_vectortab.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_dataabort.c up_mdelay.c up_udelay.c up_exit.c up_idle.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_prefetchabort.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c + +ifeq ($(CONFIG_PAGING),y) +CMN_CSRCS += up_pginitialize.c up_checkmapping.c up_allocpage.c up_va2pte.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CGU_ASRCS = + +CGU_CSRCS = lpc31_bcrndx.c lpc31_clkdomain.c lpc31_clkexten.c +CGU_CSRCS += lpc31_clkfreq.c lpc31_clkinit.c lpc31_defclk.c +CGU_CSRCS += lpc31_esrndx.c lpc31_fdcndx.c lpc31_fdivinit.c +CGU_CSRCS += lpc31_freqin.c lpc31_pllconfig.c lpc31_resetclks.c +CGU_CSRCS += lpc31_setfreqin.c lpc31_setfdiv.c lpc31_softreset.c + +CHIP_ASRCS = $(CGU_ASRCS) + +CHIP_CSRCS = lpc31_allocateheap.c lpc31_boot.c lpc31_decodeirq.c +CHIP_CSRCS += lpc31_irq.c lpc31_lowputc.c lpc31_serial.c lpc31_i2c.c +CHIP_CSRCS += lpc31_spi.c $(CGU_CSRCS) + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc31_timerisr.c +endif + +ifeq ($(CONFIG_LPC31_USBOTG),y) +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += lpc31_ehci.c +endif +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += lpc31_usbdev.c +endif +endif diff --git a/arch/arm/src/lpc31xx/chip.h b/arch/arm/src/lpc31xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..7fcc5f0f2601a1c12d0b0328bda9b12735a4e10b --- /dev/null +++ b/arch/arm/src/lpc31xx/chip.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/lpc31xx/chip.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_CHIP_H +#define __ARCH_ARM_SRC_LPC31XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LPC3130) +# undef HAVE_INTSRAM1 /* 96Kb internal SRAM */ +# define LPC31_NDMACH 12 /* 12 DMA channels */ +# undef HAVE_AESENGINE /* No AES engine */ +#elif defined(CONFIG_ARCH_CHIP_LPC3131) +# define HAVE_INTSRAM1 1 /* 192Kb internal SRAM */ +# define LPC31_NDMACH 12 /* 12 DMA channels */ +# undef HAVE_AESENGINE /* No AES engine */ +#elif defined(CONFIG_ARCH_CHIP_LPC3152) +# define HAVE_INTSRAM1 1 /* 192Kb internal SRAM */ +# define LPC31_NDMACH 12 /* 12 DMA channels */ +# undef HAVE_AESENGINE /* No AES engine */ +#elif defined(CONFIG_ARCH_CHIP_LPC3154) +# define HAVE_INTSRAM1 1 /* 192Kb internal SRAM */ +# define LPC31_NDMACH 12 /* 12 DMA channels */ +# define HAVE_AESENGINE 1 /* AES engine */ +#else +# error "Unsupported LPC31XX architecture" +# undef HAVE_INTSRAM1 /* No INTSRAM1 */ +# define LPC31_NDMACH 0 /* No DMA channels */ +# undef HAVE_AESENGINE /* No AES engine */ +#endif + +/* Cache line sizes (in bytes)for the SAVA5Dx */ + +#define ARM_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARM_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_CHIP_H */ diff --git a/arch/arm/src/lpc31xx/lpc31.h b/arch/arm/src/lpc31xx/lpc31.h new file mode 100644 index 0000000000000000000000000000000000000000..d16058a35cf1395189ae62a92c61702a7ff139b6 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31.h @@ -0,0 +1,373 @@ +/************************************************************************************ + * arch/arm/src/lpc31xx/lpc31.h + * + * Copyright (C) 2009-2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "chip.h" +#include "lpc31_ioconfig.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +/* NVIC priority levels *************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/* Configure a pin as an input */ + +static inline void gpio_configinput(uint32_t ioconfig, uint32_t bit) +{ + uint32_t regaddr; + + regaddr = ioconfig + LPC31_IOCONFIG_MODE0RESET_OFFSET; + putreg32(bit, regaddr); + + regaddr = ioconfig + LPC31_IOCONFIG_MODE1RESET_OFFSET; + putreg32(bit, regaddr); +} + +/* Return the current state of an input GPIO pin */ + +static inline bool lpc31_gpioread(uint32_t ioconfig, uint32_t bit) +{ + uint32_t regaddr = ioconfig + LPC31_IOCONFIG_PINS_OFFSET; + return (getreg32(regaddr) & bit) != 0; +} + +/* Configure the pin so that it is driven by the device */ + +static inline void gpio_configdev(uint32_t ioconfig, uint32_t bit) +{ + uint32_t regaddr; + + regaddr = ioconfig + LPC31_IOCONFIG_MODE1RESET_OFFSET; + putreg32(bit, regaddr); + + regaddr = ioconfig + LPC31_IOCONFIG_MODE0SET_OFFSET; + putreg32(bit, regaddr); +} + +/* Configure a pin as a low output */ + +static inline void gpio_outputlow(uint32_t ioconfig, uint32_t bit) +{ + uint32_t regaddr; + + regaddr = ioconfig + LPC31_IOCONFIG_MODE1SET_OFFSET; + putreg32(bit, regaddr); + + regaddr = ioconfig + LPC31_IOCONFIG_MODE0RESET_OFFSET; + putreg32(bit, regaddr); +} + +/* Configure a pin as a high output */ + +static inline void gpio_outputhigh(uint32_t ioconfig, uint32_t bit) +{ + uint32_t regaddr; + + regaddr = ioconfig + LPC31_IOCONFIG_MODE1SET_OFFSET; + putreg32(bit, regaddr); + + regaddr = ioconfig + LPC31_IOCONFIG_MODE0SET_OFFSET; + putreg32(bit, regaddr); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_lowsetup + * + * Description: + * Called early in up_boot. Performs chip-common low level initialization. + * + ************************************************************************************/ + +void lpc31_lowsetup(void); + +/************************************************************************************ + * Name: lpc31_clockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + ************************************************************************************/ + +void lpc31_clockconfig(void); + +/************************************************************************************ + * Name: lpc31_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +FAR struct spi_dev_s *lpc31_spibus_initialize(int port); + +/************************************************************************************ + * Name: lpc31_spiselect and lpc31_spistatus + * + * Description: + * The external functions, lpc31_spiselect, lpc31_spistatus, and + * lpc31_spicmddata must be provided by board-specific logic. These are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * (including lpc31_spibus_initialize()) are provided by common LPC31XX logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in lpc31_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide lpc31_spiselect() and lpc31_spistatus() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is selected in your NuttX configuration, provide + * the lpc31_spicmddata() function in your board-specific logic. This + * function will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Add a calls to lpc31_spibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by lpc31_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +void lpc31_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc31_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc31_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: lpc31_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide lpc31_pullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * Alternatively, if no pull-up GPIO the following EXTERN can be redefined to be + * NULL. + * + ************************************************************************************/ + +#if defined(CONFIG_LPC31_USBOTG) && defined(CONFIG_USBDEV) +struct usbdev_s; +int lpc31_usbpullup(FAR struct usbdev_s *dev, bool enable); +#endif + +/************************************************************************************ + * Name: lpc31_usbsuspend + * + * Description: + * Board logic must provide the lpc31_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +#if defined(CONFIG_LPC31_USBOTG) && defined(CONFIG_USBDEV) +struct usbdev_s; +void lpc31_usbsuspend(FAR struct usbdev_s *dev, bool resume); +#endif + +/**************************************************************************** + * Name: lpc31_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#if defined(CONFIG_LPC31_USBOTG) && defined(CONFIG_USBHOST) +struct usbhost_connection_s; +FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller); +#endif + +/*********************************************************************************** + * Name: lpc31_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be provided by + * each platform that implements the EHCI host interface + * + * Input Parameters: + * rhport - Selects root hub port to be powered host interface. This is not used + * with the LPC31 since it supports only a single root hub port. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ***********************************************************************************/ + +#if defined(CONFIG_LPC31_USBOTG) && defined(CONFIG_USBHOST) +void lpc31_usbhost_vbusdrive(int rhport, bool enable); +#endif + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_adc.h b/arch/arm/src/lpc31xx/lpc31_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..c5edeef78ea185c1136ae640afb1ee663fd1eda6 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_adc.h @@ -0,0 +1,132 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_adc.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_ADC_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_ADC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* ADC register base address offset into the APB0 domain ****************************************/ + +#define LPC31_ADC_VBASE (LPC31_APB0_VADDR+LPC31_APB0_ADC_OFFSET) +#define LPC31_ADC_PBASE (LPC31_APB0_PADDR+LPC31_APB0_ADC_OFFSET) + +/* ADC register offsets (with respect to the ADC base) ******************************************/ + +#define LPC31_ADC_R0_OFFSET 0x000 /* Data for analog input channel 0 */ +#define LPC31_ADC_R1_OFFSET 0x004 /* Data for analog input channel 1 */ +#define LPC31_ADC_R2_OFFSET 0x008 /* Data for analog input channel 2 */ +#define LPC31_ADC_R3_OFFSET 0x00c /* Data for analog input channel 3 */ + /* 0x010-0x01c: Reserved */ +#define LPC31_ADC_CON_OFFSET 0x020 /* ADC control register */ +#define LPC31_ADC_CSEL_OFFSET 0x024 /* Configure and select analog input channels */ +#define LPC31_ADC_INTEN_OFFSET 0x028 /* Enable ADC interrupts */ +#define LPC31_ADC_INTST_OFFSET 0x02C /* ADC interrupt status */ +#define LPC31_ADC_INTCLR_OFFSET 0x030 /* Clear ADC interrupt status */ + /* 0x034-: Reserved */ + +/* ADC register (virtual) addresses *************************************************************/ + +#define LPC31_ADC_R0 (LPC31_ADC_VBASE+LPC31_ADC_R0_OFFSET) +#define LPC31_ADC_R1 (LPC31_ADC_VBASE+LPC31_ADC_R1_OFFSET) +#define LPC31_ADC_R2 (LPC31_ADC_VBASE+LPC31_ADC_R2_OFFSET) +#define LPC31_ADC_R3 (LPC31_ADC_VBASE+LPC31_ADC_R3_OFFSET) +#define LPC31_ADC_CON (LPC31_ADC_VBASE+LPC31_ADC_CON_OFFSET) +#define LPC31_ADC_CSEL (LPC31_ADC_VBASE+LPC31_ADC_CSEL_OFFSET) +#define LPC31_ADC_INTEN (LPC31_ADC_VBASE+LPC31_ADC_INTEN_OFFSET) +#define LPC31_ADC_INTST (LPC31_ADC_VBASE+LPC31_ADC_INTST_OFFSET) +#define LPC31_ADC_INTCLR (LPC31_ADC_VBASE+LPC31_ADC_INTCLR_OFFSET) + +/* ADC register bit definitions *****************************************************************/ + +/* ADC_Rx (ADC_R0, address 0x13002000; ADC_R1, address 0x13002004, ADC_R2, address 0x13002008; + * ADC_R3, address 0x1300200c) + */ + +#define ADC_RX_SHIFT (0) /* Bits 0-9: Digital conversion data */ +#define ADC_RX_MASK (0x3ff << ADC_RX_SHIFT) + +/* ADC_CON, address 0x13002020 */ + +#define ADC_CON_STATUS (1 << 4) /* Bit 4: ADC Status */ +#define ADC_CON_START (1 << 3) /* Bit 3: Start command */ +#define ADC_CON_CSCAN (1 << 2) /* Bit 2: Continuous scan */ +#define ADC_CON_ENABLE (1 << 1) /* Bit 1: ADC enable */ + +/* ADC_CSEL, address 0x13002024 */ + +#define ADC_CSEL_CHAN3_SHIFT (12) /* Bits 12-15: Select and configure channel 3*/ +#define ADC_CSEL_CHAN3_MASK (15 << ADC_CSEL_CHAN3_SHIFT) +#define ADC_CSEL_CHAN2_SHIFT (8) /* Bits 8-10: Select and configure channel 2*/ +#define ADC_CSEL_CHAN2_MASK (15 << ADC_CSEL_CHAN2_SHIFT) +#define ADC_CSEL_CHAN1_SHIFT (4) /* Bits 4-7: Select and configure channel 1*/ +#define ADC_CSEL_CHAN1_MASK (15 << ADC_CSEL_CHAN1_SHIFT) +#define ADC_CSEL_CHAN0_SHIFT (0) /* Bits 0-3: Select and configure channel 0*/ +#define ADC_CSEL_CHAN0_MASK (15 << ADC_CSEL_CHAN0_SHIFT) + +/* ADC_INTEN, address 0x13002028 */ + +#define ADC_INTEN_ENABLE (1 << 0) + +/* ADC_INTST, address 0x1300202c */ + +#define ADC_INTST_PENDING (1 << 0) + +/* ADC_INTCLR, address 0x13002030 */ + +#define ADC_INTCLR_CLEAR (1 << 0) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_ADC_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_allocateheap.c b/arch/arm/src/lpc31xx/lpc31_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..9c54871eaf73cf9dc3385047cf67524f38c2441e --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_allocateheap.c @@ -0,0 +1,212 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_allocateheap.c + * + * Copyright (C) 2009-2010, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "lpc31_memorymap.h" + +#ifdef CONFIG_PAGING +# include +# include "pg_macros.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ********************************************************/ + +/* Some sanity checking. If external memory regions are defined, verify + * that CONFIG_MM_REGIONS is set to match, exactly, the number of external + * memory regions that we have been asked to add to the heap. + */ + +#if defined(CONFIG_LPC31_EXTSRAM0) && defined(CONFIG_LPC31_EXTSRAM0HEAP) +# if defined(CONFIG_LPC31_EXTSRAM1) && defined(CONFIG_LPC31_EXTSRAM1HEAP) +# if defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) +# /* SRAM+EXTSRAM0+EXTSRAM1+EXTSDRAM */ +# define LPC31_NEXT_REGIONS 4 +# else +# /* SRAM+EXTSRAM0+EXTSRAM1 */ +# define LPC31_NEXT_REGIONS 3 +# endif +# elif defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) +# /* SRAM+EXTSRAM0+EXTSDRAM */ +# define LPC31_NEXT_REGIONS 3 +# else +# /* SRAM+EXTSRAM0 */ +# define LPC31_NEXT_REGIONS 2 +# endif +#elif defined(CONFIG_LPC31_EXTSRAM1) && defined(CONFIG_LPC31_EXTSRAM1HEAP) +# if defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) +# /* SRAM+EXTSRAM1+EXTSDRAM */ +# define LPC31_NEXT_REGIONS 3 +# else +# /* SRAM+EXTSRAM1 */ +# define LPC31_NEXT_REGIONS 2 +# endif +#elif defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) +# /* SRAM+EXTSDRAM */ +# define LPC31_NEXT_REGIONS 2 +#else +# /* SRAM */ +# define LPC31_NEXT_REGIONS 1 +#endif + +#if CONFIG_MM_REGIONS != LPC31_NEXT_REGIONS +# if CONFIG_MM_REGIONS < LPC31_NEXT_REGIONS +# error "CONFIG_MM_REGIONS is large enough for the selected memory regions" +# else +# error "CONFIG_MM_REGIONS is too large for the selected memory regions" +# endif +# if defined(CONFIG_LPC31_EXTSRAM0) && defined(CONFIG_LPC31_EXTSRAM0HEAP) +# error "External SRAM0 is selected for heap" +# endif +# if defined(CONFIG_LPC31_EXTSRAM1) && defined(CONFIG_LPC31_EXTSRAM1HEAP) +# error "External SRAM1 is selected for heap" +# endif +# if defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) +# error "External DRAM is selected for heap" +# endif +#endif + +/* The following determines the end+1 address the heap (in SRAM0 or SRAM1) + * and that, in turn, determines the size of the heap. Specifically, this + * logic it checks if a page table has been allocated at the end of SRAM + * and, if so, subtracts that the size of the page table from the end+1 + * address of heap. + * + * If the page table was not allocated at the end of SRAM, then this logic + * will let the heap run all the way to the end of SRAM. + */ + +#ifdef CONFIG_PAGING +# ifdef PGTABLE_IN_HIGHSRAM +# define LPC31_HEAP_VEND (PG_LOCKED_VBASE + PG_TOTAL_VSIZE - PGTABLE_SIZE) +# else +# define LPC31_HEAP_VEND (PG_LOCKED_VBASE + PG_TOTAL_VSIZE) +# endif +#else +# ifdef PGTABLE_IN_HIGHSRAM +# define LPC31_HEAP_VEND (LPC31_INTSRAM_VSECTION + LPC31_ISRAM_SIZE - PGTABLE_SIZE) +# else +# define LPC31_HEAP_VEND (LPC31_INTSRAM_VSECTION + LPC31_ISRAM_SIZE) +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * SRAM layout: + * Start of SRAM: .data + * .bss + * IDLE thread stack + * End of SRAm: heap + * + * NOTE: Ignore the erroneous nomenclature DRAM and SDRAM. That names + * date back to an earlier platform that had SDRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = LPC31_HEAP_VEND - g_idle_topstack; +} + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#if defined(CONFIG_LPC31_EXTSRAM0) && defined(CONFIG_LPC31_EXTSRAM0HEAP) + kmm_addregion((FAR void *)LPC31_EXTSRAM0_VSECTION, CONFIG_LPC31_EXTSRAM0SIZE); +#endif + +#if defined(CONFIG_LPC31_EXTSRAM1) && defined(CONFIG_LPC31_EXTSRAM1HEAP) + kmm_addregion((FAR void *)LPC31_EXTSRAM1_VSECTION, CONFIG_LPC31_EXTSRAM1SIZE); +#endif + +#if defined(CONFIG_LPC31_EXTDRAM) && defined(CONFIG_LPC31_EXTDRAMHEAP) + kmm_addregion((FAR void *)LPC31_EXTSDRAM_VSECTION, CONFIG_LPC31_EXTDRAMSIZE); +#endif +} +#endif diff --git a/arch/arm/src/lpc31xx/lpc31_analogdie.h b/arch/arm/src/lpc31xx/lpc31_analogdie.h new file mode 100644 index 0000000000000000000000000000000000000000..9daf5c34f8d02c9d94904fdd311dfb5c91fe3058 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_analogdie.h @@ -0,0 +1,421 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_analogdie.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_ANALOGDIE_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_ANALOGDIE_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* I2C slave address ****************************************************************************/ +/* "The analog die has its own register set which is accessed through the I2C1 interface. The + * analog block has one device slave address 0001100. All blocks in the analog die behave + * like one I2C slave device to the I2C1 interface." + */ + +#define LPC31_ANALOG_I2CADDR 0x0c + +/* I2C register base addresses ******************************************************************/ + +#define LPC31_ANALOG_CHARGER_BASE 0x0000 +#define LPC31_ANALOG_CHARGER_SIZE 0x0010 + +#define LPC31_ANALOG_CODEC_BASE 0x0010 +#define LPC31_ANALOG_CODEC_SIZE 0x0010 + +#define LPC31_ANALOG_RTC_BASE 0x0020 +#define LPC31_ANALOG_RTC_SIZE 0x0010 + +/* Charger register addresses *******************************************************************/ + +#define LPC31_CHARGER_OTGDCLIC 0x0000 /* PSU and Li-ion charger control register */ +#define LPC31_CHARGER_DCDCLIC 0x0001 /* PSU and Li-ion charger status register */ +#define LPC31_CHARGER_CGU_ANALOG 0x0002 /* Analog die CGU control register */ + +/* Audio CODEC register addresses ***************************************************************/ + +#define LPC31_CODEC_AIN0 0x0010 /* Analog input PGA control */ +#define LPC31_CODEC_AIN1 0x0011 /* Analog input control */ +#define LPC31_CODEC_AOUT 0x0012 /* Analog output control */ +#define LPC31_CODEC_DEC 0x0013 /* Decimator control */ +#define LPC31_CODEC_INT0 0x0014 /* Interpolator control */ +#define LPC31_CODEC_INT1 0x0015 /* Interpolator volume control */ +#define LPC31_CODEC_I2S1MUX 0x0016 /* I2S1 digital audio multiplexer control */ +#define LPC31_CODEC_AOUTDECINT 0x0017 /* Analog out status */ + +/* RTC register addresses ***********************************************************************/ + +#define LPC31_RTC_TIME 0x0020 /* RTC time shadow register */ +#define LPC31_RTC_ALARMTIME 0x0021 /* RTC alarm time register */ +#define LPC31_RTC_STATUS 0x0022 /* RTC status register */ +#define LPC31_RTC_SETENASTAT 0x0023 /* RTC set/enable register */ +#define LPC31_RTC_CLRENASTAT 0x0024 /* RTC clear register */ + +/* Charger register bit definitions *************************************************************/ + +/* PSU and Li-ion charger control register */ + +#define CHARGER_LIC_PONTBAT (1 << 0) /* Bit 0: Enable temperature sensing for Li-ion battery */ +#define CHARGER_LIC_PONTLIM (1 << 1) /* Bit 1: Power for chip temperature control loop */ +#define CHARGER_LIC_TT_SHIFT (2) /* Bits 2-4: Chip temperature control loop threshold */ +#define CHARGER_LIC_TT_MASK (7 << CHARGER_LIC_TT_SHIFT) +#define CHARGER_LIC_G_SHIFT (5) /* Bits 5-7: Chip temperature control loop gain */ +#define CHARGER_LIC_G_MASK (7 << CHARGER_LIC_G_SHIFT) +#define CHARGER_LIC_CS_SHIFT (8) /* Bits 8-11: Compensation setting */ +#define CHARGER_LIC_CS_MASK (15 << CHARGER_LIC_CS_SHIFT) +#define CHARGER_LIC_CHARGEENABLE (1 << 12) /* Bit 12: Start charger */ +#define CHARGER_DCDC_SEL1V8 (1 << 16) /* Bit 16: LDO3 settings */ +#define CHARGER_DCDC2_ADJUST_SHIFT (17) /* Bits 17-19: DCDC2 voltage setting */ +#define CHARGER_DCDC2_ADJUST_MASK (7 << CHARGER_DCDC2_ADJUST_SHIFT) +# define CHARGER_DCDC2_ADJUST_1p4V (0 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.40 */ +# define CHARGER_DCDC2_ADJUST_1p33V (1 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.33 */ +# define CHARGER_DCDC2_ADJUST_1p26V (2 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.26 */ +# define CHARGER_DCDC2_ADJUST_1p19V (3 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.19 */ +# define CHARGER_DCDC2_ADJUST_1p11V (4 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.11 */ +# define CHARGER_DCDC2_ADJUST_1p04V (5 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 1.04 */ +# define CHARGER_DCDC2_ADJUST_p97V (6 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 0.97 */ +# define CHARGER_DCDC2_ADJUST_p9V (7 << CHARGER_DCDC2_ADJUST_SHIFT) /* Output voltage 0.90 */ +#define CHARGER_DCDC1_ADJUST_SHIFT (20) /* Bits 20-22: DCDC1 voltage setting */ +#define CHARGER_DCDC1_ADJUST_MASK (7 << CHARGER_DCDC1_ADJUST_SHIFT) +# define CHARGER_DCDC1_ADJUST_3p2V (0 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 3.2 */ +# define CHARGER_DCDC1_ADJUST_3p09V (1 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 3.09 */ +# define CHARGER_DCDC1_ADJUST_2p97V (2 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.97 */ +# define CHARGER_DCDC1_ADJUST_2p86V (3 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.86 */ +# define CHARGER_DCDC1_ADJUST_2p74V (4 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.74 */ +# define CHARGER_DCDC1_ADJUST_2p63V (5 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.63 */ +# define CHARGER_DCDC1_ADJUST_2p51V (6 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.51 */ +# define CHARGER_DCDC1_ADJUST_2p4V (7 << CHARGER_DCDC1_ADJUST_SHIFT) /* Output voltage 2.40 */ +#define CHARGER_DCDC_LDOON (1 << 23) /* Bit 23: LDO on/off control */ +#define CHARGER_DCDC_CLKSTABLE (1 << 24) /* Bit 24: DCDC clock control */ +#define CHARGER_USBOTG (1 << 28) /* Bit 28: USBOTG charge pump control */ + +/* PSU and Li-ion charger status register */ + +#define CHARGER_LIC_TEMPBATOK (1 << 0) /* Bit 0: Battery temperature OK indicator */ +#define CHARGER_LIC_NONTC (1 << 1) /* Bit 1: No NTC indicator */ +#define CHARGER_LIC_CVCHARGE (1 << 2) /* Bit 2: Constant-voltage charge indicator */ +#define CHARGER_LIC_FASTCHARGE (1 << 3) /* Bit 3: Fast-charge indicator (100% current) */ +#define CHARGER_LIC_TRICKLECHARGE (1 << 4) /* Bit 4: Trickle-charge indicator (10% current) */ +#define CHARGER_LIC_BATTERYFULL (1 << 5) /* Bit 5: Battery full indicator */ +#define CHARGER_LIC_CHARGERON (1 << 6) /* Bit 6: charger on indicator */ +#define CHARGER_DCDC_INVRAMP_3V3 (1 << 16) /* Bit 16: DCDC1 mode status 4 */ +#define CHARGER_DCDC_INVRAMP_1V2 (1 << 17) /* Bit 17: DCDC2 mode status 4 */ +#define CHARGER_DCDC_INVINIT_3V3 (1 << 18) /* Bit 18: DCDC1 mode status 3 */ +#define CHARGER_DCDC_INVINIT_1V2 (1 << 19) /* Bit 19: DCDC2 mode status 3 */ +#define CHARGER_DCDC_INVDISC_3V3 (1 << 20) /* Bit 20: DCDC1 mode status 2 */ +#define CHARGER_DCDC_INVDISC_1V2 (1 << 21) /* Bit 21: DCDC2 mode status 2 */ +#define CHARGER_DCDC_INVCONT_3V3 (1 << 22) /* Bit 22: DCDC1 mode status 1 */ +#define CHARGER_DCDC_INVCONT_1V2 (1 << 23) /* Bit 23: DCDC2 mode status 1 */ +#define CHARGER_DCDC_USBDETECT (1 << 24) /* Bit 24: USB VBUS supply detect */ + +/* Analog die CGU control register */ + +#define CHARGER_PD_I2C_CLK256FS (1 << 0) /* Bit 0: Power-down for I2C clock I2C_CLK_256FS */ +#define CHARGER_PD_INT_CLKDSP (1 << 1) /* Bit 1: Power-down for interpolator clock INT_CLK_DSP */ +#define CHARGER_PD_INT_CLKNS (1 << 2) /* Bit 2: Power-down for interpolator clock INT_CLK_NS */ +#define CHARGER_PD_DEC_CLK (1 << 3) /* Bit 3: Power-down for decimator clock DEC_CLK */ +#define CHARGER_PD_I2STX_BITCLK (1 << 4) /* Bit 4: Power down I2STX_BCK */ +#define CHARGER_PD_I2STX_SYSCLK (1 << 5) /* Bit 5: Power-down for I2STX_SYSCLK */ +#define CHARGER_PD_I2SRX_BITCLK (1 << 6) /* Bit 6: Power-down I2SRX_BCK */ +#define CHARGER_PD_I2SRX_SYSCLK (1 << 7) /* Bit 7: Power-down for I2SRX_SYSCLK */ +#define CHARGER_PD_LIC_CLK (1 << 8) /* Bit 8: Power-down for the Li-ion charger controller clock LIC_CLK */ +#define CHARGER_PD_AOUT_DAC (1 << 11) /* Bit 11: Power-down for the DAC clock AOUT_CLK_DAC */ +#define CHARGER_PD_AIN_ADC2 (1 << 12) /* Bit 12: Power-down for the SADC clock AIN_CLK_ADC2 */ +#define CHARGER_PD_AIN_ADC1 (1 << 13) /* Bit 13: Power-down for the SADC clock AIN_CLK_ADC1 */ +#define CHARGER_PD_AIN_ADCSYS (1 << 14) /* Bit 14: Power-down for SADC clock AIN_CLK_ADCSYS */ +#define CHARGER_INT_CLKNS256FS (1 << 16) /* Bit 16: Select clock INT_CLK_NS for interpolator */ +#define CHARGER_AOUT_CLKDAC256FS (1 << 17) /* Bit 17: Select DAC clock */ +#define CHARGER_AIN_ADC2128FS (1 << 18) /* Bit 18: 128fs */ +#define CHARGER_AIN_ADC1OFF_1 (1 << 19) /* Bit 19: Tied to '1' */ +#define CHARGER_AIN_ADCSYS256FS (1 << 20) /* Bit 20: Select sampling clock for the SADC AIN_CLK_ADCSYS */ +#define CHARGER_I2C_CLK (1 << 21) /* Bit 21: Select clock for the analog die I2C block */ +#define CHARGER_CGU_LSOFF (1 << 22) /* Bit 22: Level shifter RTC off */ +#define CHARGER_CLKDAC_SAMEPHASE (1 << 23) /* Bit 23: Clock phase DA not inverted */ + +/* Audio CODEC register bit definitions *********************************************************/ + +/* Analog input PGA control */ + +#define CODEC_AIN0_0DB 0 +#define CODEC_AIN0_3DB 1 +#define CODEC_AIN0_6DB 2 +#define CODEC_AIN0_9DB 3 +#define CODEC_AIN0_12DB 4 +#define CODEC_AIN0_15DB 5 +#define CODEC_AIN0_18DB 6 +#define CODEC_AIN0_21DB 7 +#define CODEC_AIN0_24DB 8 + +#define CODEC_AIN0_PGA3_SHIFT (0) /* Bits 0-3: Gain of PGA3 (right channel) */ +#define CODEC_AIN0_PGA3_MASK (15 << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_0DB (CODEC_AIN0_0DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_3DB (CODEC_AIN0_3DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_6DB (CODEC_AIN0_6DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_9DB (CODEC_AIN0_9DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_12DB (CODEC_AIN0_12DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_15DB (CODEC_AIN0_15DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_18DB (CODEC_AIN0_18DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_21DB (CODEC_AIN0_21DB << CODEC_AIN0_PGA3_SHIFT) +# define CODEC_AIN0_PGA3_24DB (CODEC_AIN0_24DB << CODEC_AIN0_PGA3_SHIFT) +#define CODEC_AIN0_PGA2_SHIFT (4) /* Bits 4-7: Gain of PGA2 (microphone input) */ +#define CODEC_AIN0_PGA2_MASK (0xff << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_0DB (CODEC_AIN0_0DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_3DB (CODEC_AIN0_3DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_6DB (CODEC_AIN0_6DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_9DB (CODEC_AIN0_9DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_12DB (CODEC_AIN0_12DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_15DB (CODEC_AIN0_15DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_18DB (CODEC_AIN0_18DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_21DB (CODEC_AIN0_21DB << CODEC_AIN0_PGA2_SHIFT) +# define CODEC_AIN0_PGA2_24DB (CODEC_AIN0_24DB << CODEC_AIN0_PGA2_SHIFT) +#define CODEC_AIN0_PGA1_SHIFT (8) /* Bits 8-11: Gain of PGA1 (left channel) */ +#define CODEC_AIN0_PGA1_MASK (0xff << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_0DB (CODEC_AIN0_0DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_3DB (CODEC_AIN0_3DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_6DB (CODEC_AIN0_6DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_9DB (CODEC_AIN0_9DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_12DB (CODEC_AIN0_12DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_15DB (CODEC_AIN0_15DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_18DB (CODEC_AIN0_18DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_21DB (CODEC_AIN0_21DB << CODEC_AIN0_PGA1_SHIFT) +# define CODEC_AIN0_PGA1_24DB (CODEC_AIN0_24DB << CODEC_AIN0_PGA1_SHIFT) + +/* Analog input control */ + +#define CODEC_AIN1_XFBAD2 (1 << 0) /* Bit 0: ADC enable feedback in loopfilter (right channel) */ +#define CODEC_AIN1_XFBAD1 (1 << 1) /* Bit 1: ADC enable feedback in loopfilter (left channel) */ +#define CODEC_AIN1_DITHER2 (1 << 2) /* Bit 2: ADC dither input (right channel) */ +#define CODEC_AIN1_DITHER1 (1 << 3) /* Bit 3: ADC dither input (left channel) */ +#define CODEC_AIN1_PD_VCOM_VREF1 (1 << 4) /* Bit 4: ADC_VREF power down */ +#define CODEC_AIN1_PD_SDC3 (1 << 5) /* Bit 5: BIAS1 power down */ +#define CODEC_AIN1_PD_SDC2 (1 << 9) /* Bit 9: SDC2 (microphone input) power down */ +#define CODEC_AIN1_PD_SDC1 (1 << 10) /* Bit 10: SDC1 (left channel) power down */ +#define CODEC_AIN1_PD_PGA3 (1 << 11) /* Bit 11: PGA3 (right channel) power down */ +#define CODEC_AIN1_PD_PGA2 (1 << 12) /* Bit 12: PGA2 (microphone input) power down */ +#define CODEC_AIN1_PD_PGA1 (1 << 13) /* Bit 13: PGA1 (left channel) power down */ +#define CODEC_AIN1_PD_LNA1 (1 << 14) /* Bit 14: LNA power down */ +#define CODEC_AIN1_MUXR_SHIFT (15) /* Bits 15-16: MUX0 & MUX1 input selection for right channel */ +#define CODEC_AIN1_MUXR_MASK (3 << CODEC_AIN1_MUXR_SHIFT) +# define CODEC_AIN1_MUXR_TUNER (0 << CODEC_AIN1_MUXR_SHIFT) /* Tuner input */ +# define CODEC_AIN1_MUXR_LINE (1 << CODEC_AIN1_MUXR_SHIFT) /* Line input */ +# define CODEC_AIN1_MUXR_MICTBYP (2 << CODEC_AIN1_MUXR_SHIFT) /* Mic input tuner by-pass */ +# define CODEC_AIN1_MUXR_MICLBYP (3 << CODEC_AIN1_MUXR_SHIFT) /* Mic input Line-in by-pass */ +#define CODEC_AIN1_MUXL_SHIFT (17) /* Bits 17-18: MUX0 & MUX1 input selection for left channel */ +#define CODEC_AIN1_MUXL_MASK (3 << CODEC_AIN1_MUXL_SHIFT) +# define CODEC_AIN1_MUXL_TUNER (0 << CODEC_AIN1_MUXL_SHIFT) /* Tuner input */ +# define CODEC_AIN1_MUXL_LINE (1 << CODEC_AIN1_MUXL_SHIFT) /* Line input */ +# define CODEC_AIN1_MUXL_MICTBYP (2 << CODEC_AIN1_MUXL_SHIFT) /* Mic input tuner by-pass */ +# define CODEC_AIN1_MUXL_MICLBYP (3 << CODEC_AIN1_MUXL_SHIFT) /* Mic input Line-in by-pass */ + +/* Analog output control */ + +#define CODEC_AOUT_PD_ANVC_R (1 << 0) /* Bit 0: Power down the Analog Volume Control (AVC) Right */ +#define CODEC_AOUT_PD_ANVC_L (1 << 1) /* Bit 1: Power down the Analog Volume Control (AVC) Left */ +#define CODEC_AOUT_PD_SET_DWA (1 << 2) /* Bit 2: Data Weight Algorithm */ +#define CODEC_AOUT_PD_SET_FORMAT (1 << 3) /* Bit 3: Input format of the I2S bus */ +#define CODEC_AOUT_PD_SDAC_R (1 << 4) /* Bit 4: Power down the SDAC Right */ +#define CODEC_AOUT_PD_SDAC_L (1 << 5) /* Bit 5: Power down the SDAC Left */ +#define CODEC_AOUT_LIMITERR_SHIFT (6) /* Bit 6-7: Current limiter setting (short-circuit protection) right channel */ +#define CODEC_AOUT_LIMITERR_MASK (3 << CODEC_AOUT_LIMITERR_SHIFT) +# define CODEC_AOUT_LIMITERR_OFF (0 << CODEC_AOUT_LIMITERR_SHIFT) /* Max current: off */ +# define CODEC_AOUT_LIMITERR_100MA (1 << CODEC_AOUT_LIMITERR_SHIFT) /* Max current: 100 mA */ +# define CODEC_AOUT_LIMITERR_120MA (2 << CODEC_AOUT_LIMITERR_SHIFT) /* Max current: 120 mA */ +# define CODEC_AOUT_LIMITERR_140MA (3 << CODEC_AOUT_LIMITERR_SHIFT) /* Max current: 140 mA */ +#define CODEC_AOUT_LIMITERC_SHIFT (8) /* Bit 8-9: Current limiter setting (short-circuit protection) common ground channel */ +#define CODEC_AOUT_LIMITERC_MASK (3 << CODEC_AOUT_LIMITERC_SHIFT) +# define CODEC_AOUT_LIMITERC_OFF (0 << CODEC_AOUT_LIMITERC_SHIFT) /* Max current: off */ +# define CODEC_AOUT_LIMITERC_200MA (1 << CODEC_AOUT_LIMITERC_SHIFT) /* Max current: 200 mA */ +# define CODEC_AOUT_LIMITERC_240MA (2 << CODEC_AOUT_LIMITERC_SHIFT) /* Max current: 240 mA */ +# define CODEC_AOUT_LIMITERC_280MA (3 << CODEC_AOUT_LIMITERC_SHIFT) /* Max current: 280 mA */ +#define CODEC_AOUT_LIMITERL_SHIFT (10) /* Bit 10-11: Current limiter setting (short-circuit protection) left channel */ +#define CODEC_AOUT_LIMITERL_MASK (3 << CODEC_AOUT_LIMITERL_SHIFT) +# define CODEC_AOUT_LIMITERL_OFF (0 << CODEC_AOUT_LIMITERL_SHIFT) /* Max current: off */ +# define CODEC_AOUT_LIMITERL_100MA (1 << CODEC_AOUT_LIMITERL_SHIFT) /* Max current: 100 mA */ +# define CODEC_AOUT_LIMITERL_120MA (2 << CODEC_AOUT_LIMITERL_SHIFT) /* Max current: 120 mA */ +# define CODEC_AOUT_LIMITERL_140MA (3 << CODEC_AOUT_LIMITERL_SHIFT) /* Max current: 140 mA */ +#define CODEC_AOUT_PD_HP_R (1 << 12) /* Bit 12: Power down the right headphone amplifier */ +#define CODEC_AOUT_PD_HP_C (1 << 13) /* Bit 13: Power down the common ground headphone amplifier */ +#define CODEC_AOUT_PD_HP_L (1 << 14) /* Bit 14: Power down the left headphone amplifier */ +#define CODEC_AOUT_PD_VREF_SLOW (1 << 15) /* Bit 15: Power down the reference */ +#define CODEC_AOUT_GAIN_AVC_SHIFT (16) /* Bit 16-29: Gain of the Analog Volume Control (AVC) */ +#define CODEC_AOUT_GAIN_AVC_MASK (0x3fff << CODEC_AOUT_GAIN_AVC_SHIFT) +#define CODEC_AOUT_VREF_SLOW_UP (1 << 30) /* Bit 30: Control for slow reference voltage */ +#define CODEC_AOUT_SWDAC_ON (1 << 31) /* Bit 31: Control the AVC switches of SDAC */ + +/* Decimator control */ + +#define CODEC_DEC_AGCTIM_SHIFT (25) /* Bits 25-27: AGC Time Constant */ +#define CODEC_DEC_AGCTIM_MASK (7 << CODEC_DEC_AGCTIM_SHIFT) +#define CODEC_DEC_AGCLVL_SHIFT (23) /* Bits 23-24: AGC Level */ +#define CODEC_DEC_AGCLVL_MASK (3 << CODEC_DEC_AGCLVL_SHIFT) +# define CODEC_DEC_AGCLVL_M5p5DBFS (0 << CODEC_DEC_AGCLVL_SHIFT) /* AGC Target level -5.5 dBFS */ +# define CODEC_DEC_AGCLVL_M8P0DBFS (1 << CODEC_DEC_AGCLVL_SHIFT) /* AGC Target level -8.0 dBFS */ +# define CODEC_DEC_AGCLVL_M11P5DBFS (2 << CODEC_DEC_AGCLVL_SHIFT) /* AGC Target level -11.5 dBFS */ +# define CODEC_DEC_AGCLVL_M14p0DBFS (3 << CODEC_DEC_AGCLVL_SHIFT) /* AGC Target level -14.0 dBFS */ +#define CODEC_DEC_AGCEN (1 << 22) /* Bit 22: AGC Enable */ +#define CODEC_DEC_MUTE (1 << 21) /* Bit 21: Enable mute */ +#define CODEC_DEC_POLINV (1 << 20) /* Bit 20: Enable polarity inversion */ +#define CODEC_DEC_DCFILTI (1 << 19) /* Bit 19: Enable input DC blocking filter */ +#define CODEC_DEC_DCFILTO (1 << 18) /* Bit 18: Enable DC blocking filter after decimation filters */ +#define CODEC_DEC_DBLIN (1 << 17) /* Bit 17: Enable soft start-up after a reset */ +#define CODEC_DEC_DELAY_DBLIN (1 << 16) /* Bit 16: Enable delay timer after a reset */ +#define CODEC_DEC_GAINL_SHIFT (8) /* Bits 8-15: Gain settings, LEFT channel (2’s compliment format 0.5dB/bit) */ +#define CODEC_DEC_GAINL_MASK (0xff << CODEC_DEC_GAINL_SHIFT) +#define CODEC_DEC_GAINR_SHIFT (0) /* Bits 0-7: Gain settings RIGHT channel (2’s compliment format 0.5dB/bit) */ +#define CODEC_DEC_GAINR_MASK (0xff << CODEC_DEC_GAINR_SHIFT) + +/* Interpolator control */ + +#define CODEC_INT0_DEEM_CHAN1_SHIFT (0) /* Bits 0-2: Set de-emphasis channel 1 */ +#define CODEC_INT0_DEEM_CHAN1_MASK (7 << CODEC_INT0_DEEM_CHAN1_SHIFT) +# define CODEC_INT0_DEEM_CHAN1_NONE (0 << CODEC_INT0_DEEM_CHAN1_SHIFT) /* No digital de-emphasis */ +# define CODEC_INT0_DEEM_CHAN1_32KHZ (1 << CODEC_INT0_DEEM_CHAN1_SHIFT) /* De-emphasis for fs = 32 kHz */ +# define CODEC_INT0_DEEM_CHAN1_44p1KHz (2 << CODEC_INT0_DEEM_CHAN1_SHIFT) /* De-emphasis for fs = 44.1 kHz */ +# define CODEC_INT0_DEEM_CHAN1_48KHz (3 << CODEC_INT0_DEEM_CHAN1_SHIFT) /* De-emphasis for fs = 48 kHz */ +# define CODEC_INT0_DEEM_CHAN1_96KHz (4 << CODEC_INT0_DEEM_CHAN1_SHIFT) /* De-emphasis for fs = 96 kHz */ +#define CODEC_INT0_SET_SILENCE (1 << 3) /* Bit 3: overruling silence switch input */ +#define CODEC_INT0_SD_VALUE_SHIFT (4) /* Bits 4-5: Silence detection time window */ +#define CODEC_INT0_SD_VALUE_MASK (3 << CODEC_INT0_SD_VALUE_SHIFT) +# define CODEC_INT0_SD_VALUE_3200 (0 << CODEC_INT0_SD_VALUE_SHIFT) /* 3200 fs samples */ +# define CODEC_INT0_SD_VALUE_4800 (1 << CODEC_INT0_SD_VALUE_SHIFT) /* 4800 fs samples */ +# define CODEC_INT0_SD_VALUE_9600 (2 << CODEC_INT0_SD_VALUE_SHIFT) /* 9600 fs samples */ +# define CODEC_INT0_SD_VALUE_19200 (3 << CODEC_INT0_SD_VALUE_SHIFT) /* 19200 fs samples */ +#define CODEC_INT0_SD (1 << 6) /* Bit 6: Silence detection enable */ +#define CODEC_INT0_PD_DAC (1 << 7) /* Bit 7: Enable power down sequence interpolator */ +#define CODEC_INT0_PD_SLOPE (1 << 8) /* Bit 8: DC ramp up/down slope setting */ +#define CODEC_INT0_NS_SHIFT (9) /* Bits 9-10: Noise shaper settings (1-bit, 4-bit, 5-bit or 6-bit) */ +#define CODEC_INT0_NS_MASK (3 << CODEC_INT0_NS_SHIFT) +# define CODEC_INT0_NS_1BIT (0 << CODEC_INT0_NS_SHIFT) /* 1-bit noise shaped output */ +# define CODEC_INT0_NS_4BIT (1 << CODEC_INT0_NS_SHIFT) /* 4-bit noise shaped output */ +# define CODEC_INT0_NS_5BIT (2 << CODEC_INT0_NS_SHIFT) /* 5-bit noise shaped output */ +# define CODEC_INT0_NS_6BIT (3 << CODEC_INT0_NS_SHIFT) /* 6-bit noise shaped output */ +#define CODEC_INT0_SPEED_MODE_SHIFT (11) /* Bits 11-12: Input data rate settings (1fs or 8 fs) */ +#define CODEC_INT0_SPEED_MODE_MASK (3 << CODEC_INT0_SPEED_MODE_SHIFT) +# define CODEC_INT0_SPEED_MODE_1FS (0 << CODEC_INT0_SPEED_MODE_SHIFT) /* 1fs (normal) speed mode */ +# define CODEC_INT0_SPEED_MODE_2FS (1 << CODEC_INT0_SPEED_MODE_SHIFT) /* 2fs (double) speed mode */ +# define CODEC_INT0_SPEED_MODE_8FS (3 << CODEC_INT0_SPEED_MODE_SHIFT) /* 8fs speed mode */ +#define CODEC_INT0_FILTER_SHIFT (13) /* Bits 13-14: Filter coefficient settings for sharp/slow roll-off */ +#define CODEC_INT0_FILTER_MASK (3 << CODEC_INT0_FILTER_SHIFT) +# define CODEC_INT0_FILTER_SLOWEST (0 << CODEC_INT0_FILTER_SHIFT) /* Slow roll-off */ +# define CODEC_INT0_FILTER_SLOWER (1 << CODEC_INT0_FILTER_SHIFT) /* Slow roll-off */ +# define CODEC_INT0_FILTER_SLOW (2 << CODEC_INT0_FILTER_SHIFT) /* Slow roll-off */ +# define CODEC_INT0_FILTER_SHARP (3 << CODEC_INT0_FILTER_SHIFT) /* Sharp roll-off */ +#define CODEC_INT0_POLINV (1 << 15) /* Bit 15: Enable polarity inversion */ + +/* Interpolator volume control */ + +#define CODEC_INT1_MUTE (1 << 16) /* Bit 16: Mute interpolator */ +#define CODEC_INT1_MASTERVOLR_SHIFT (8) /* Bits 8-15: Set volume right channel */ +#define CODEC_INT1_MASTERVOLR_MASK (0xff << CODEC_INT1_MASTERVOLR_SHIFT) +#define CODEC_INT1_MASTERVOLL_SHIFT (0) /* Bits 0-7: Set volume left channel */ +#define CODEC_INT1_MASTERVOLL_MASK (0xff << CODEC_INT1_MASTERVOLL_SHIFT) + +/* I2S1 digital audio multiplexer control */ + +#define CODEC_I2S1MUX_TXCTRL_SHIFT (0) /* Bit 0-2: Serial interface mode I2STX interface */ +#define CODEC_I2S1MUX_TXCTRL_MASK (7 << CODEC_I2S1MUX_TXCTRL_SHIFT) +# define CODEC_I2S1MUX_TXCTRL_NXPI2S (3 << CODEC_I2S1MUX_TXCTRL_SHIFT) /* NXP I2S */ +# define CODEC_I2S1MUX_TXCTRL_LJ16 (4 << CODEC_I2S1MUX_TXCTRL_SHIFT) /* LSB justified 16 bits */ +# define CODEC_I2S1MUX_TXCTRL_LJ18 (5 << CODEC_I2S1MUX_TXCTRL_SHIFT) /* LSB justified 18 bits */ +# define CODEC_I2S1MUX_TXCTRL_LJ20 (6 << CODEC_I2S1MUX_TXCTRL_SHIFT) /* LSB justified 20 bits */ +# define CODEC_I2S1MUX_TXCTRL_LJ24 (7 << CODEC_I2S1MUX_TXCTRL_SHIFT) /* LSB justified 24 bits */ +#define CODEC_I2S1MUX_RXCTRL_SHIFT (8) /* Bit 8-10: Serial interface mode I2SRX interface */ +#define CODEC_I2S1MUX_RXCTRL_MASK (7 << CODEC_I2S1MUX_RXCTRL_SHIFT) +# define CODEC_I2S1MUX_RXCTRL_DIL (0 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* DAD/ISN/LIRS */ +# define CODEC_I2S1MUX_RXCTRL_SPD3 (1 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* SPD3 format */ +# define CODEC_I2S1MUX_RXCTRL_NXPI2S (3 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* NXP I2S */ +# define CODEC_I2S1MUX_RXCTRL_LJ16 (4 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* LSB justified 16 bits */ +# define CODEC_I2S1MUX_RXCTRL_LJ18 (5 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* LSB justified 18 bits */ +# define CODEC_I2S1MUX_RXCTRL_LJ20 (6 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* LSB justified 20 bits */ +# define CODEC_I2S1MUX_RXCTRL_LJ24 (7 << CODEC_I2S1MUX_RXCTRL_SHIFT) /* LSB justified 24 bits */ +#define CODEC_I2S1MUX_BYPASS (1 << 16) /* Bit 16: Selection for Digital Mux */ + +/* Analog out status */ + +#define CODEC_INT_FSPULSE (1 << 0) /* Bit 0: One interpolator DSP clock cycle pulse at 1fs frequency */ +#define CODEC_INT_DACPC_SHIFT (1) /* Bits 1-7: Program counter on the CLKIN_DSP clock for interpolator */ +#define CODEC_INT_DACPC_MASK (0x7f << CODEC_INT_DACPC_SHIFT) +#define CODEC_INT_SDETECTEDR1 (1 << 8) /* Bit 8: Silence detection output channel 1 RIGHT */ +#define CODEC_INT_SDETECTEDL1 (1 << 9) /* Bit 9: Silence detection ouput channel 1 LEFT */ +#define CODEC_INT_MUTESTATEM (1 << 10) /* Bit 10: Mute status of master channel */ +#define CODEC_INT_INVNDAC (1 << 11) /* Bit 11: Control signal to invert neg. channel data for differential application */ +#define CODEC_INT_DSR (1 << 12) /* Bit 12: DAC silence switch control signal RIGHT */ +#define CODEC_INT_DSL (1 << 13) /* Bit 13: DAC silence switch control signal LEFT */ +#define CODEC_INT_PDREADY (1 << 14) /* Bit 14: Power down sequence completed; actual power down signal for DAC */ +#define CODEC_DEC_OVERFLOW (1 << 16) /* Bit 16: Overflow indicator */ +#define CODEC_DEC_MUTESTATE (1 << 17) /* Bit 17: Output muted status indicator */ +#define CODEC_DEC_AGCSTAT (1 << 18) /* Bit 18: T.B.F. */ +#define CODEC_AOUT_CLIPR (1 << 24) /* Bit 24: Output of right headphone amplifier is clipped */ +#define CODEC_AOUT_CLIPC (1 << 25) /* Bit 25: Output of common ground headphone amplifier is clipped */ +#define CODEC_AOUT_CLIPL (1 << 26) /* Bit 26: Output of left headphone amplifier is clipped */ + +/* RTC register bit definitions *****************************************************************/ + +/* RTC time shadow register -- 32-bit time in seconds since epoch */ +/* RTC alarm time register -- 32-bit time in seconds since epoch */ + +/* RTC status register (See also common interrupt bits below) */ + +#define RTC_STATUS_RST (1 << 12) /* Bit 12: RTC is in reset */ +#define RTC_STATUS_PENDING (1 << 16) /* Bit 16: Time in RTC_TIME has not yet been updated */ +#define RTC_STATUS_LSENA (1 << 13) /* Bit 13: Software access (via level shifters) is enabled */ + +/* RTC status register, RTC set/enable register, and RTC clear register common interrupt bits */ + +#define RTC_INT_ALARM (1 << 0) /* Bit 0: RTC time counter matched alarm time */ +#define RTC_INT_UNSET (1 << 1) /* Bit 1: Time undefined */ +#define RTC_INT_ADENA (1 << 8) /* Bit 8: Alarm to the event router */ +#define RTC_INT_RTCENA (1 << 9) /* Bit 9: Alarm assertion to RTC_INT disabled */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_ANALOGDIE_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_bcrndx.c b/arch/arm/src/lpc31xx/lpc31_bcrndx.c new file mode 100644 index 0000000000000000000000000000000000000000..078f2c99f9bd5ce5f3f39ec3f5867646b11874d1 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_bcrndx.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_bcrndx.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_bcrndx + * + * Description: + * Only 5 of the 12 domains have an associated BCR register. This + * function returns the index to the associated BCR register (if any) + * or BCRNDX_INVALID otherwise. + * + ****************************************************************************/ + +int lpc31_bcrndx(enum lpc31_domainid_e dmnid) +{ + switch (dmnid) + { + /* BCR0-3 correspond directly to domains 0-3 */ + + case DOMAINID_SYS: /* Domain 0: SYS_BASE */ + case DOMAINID_AHB0APB0: /* Domain 1: AHB0APB0_BASE */ + case DOMAINID_AHB0APB1: /* Domain 2: AHB0APB1_BASE */ + case DOMAINID_AHB0APB2: /* Domain 3: AHB0APB2_BASE */ + return (int)dmnid; + + /* There is a BCR register corresponding to domain 7, but it is at + * index 4 + */ + + case DOMAINID_CLK1024FS: /* Domain 7: CLK1024FS_BASE */ + return 4; + + default: /* There is no BCR register for the other + * domains. */ + break; + } + return BCRNDX_INVALID; +} diff --git a/arch/arm/src/lpc31xx/lpc31_boot.c b/arch/arm/src/lpc31xx/lpc31_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..1932b8fee7d644b2c71216258001ba502d728eef --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_boot.c @@ -0,0 +1,397 @@ +/************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_boot.c + * + * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include + +#include "chip.h" +#include "arm.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "lpc31_syscreg.h" +#include "lpc31_cgudrvr.h" +#include "lpc31.h" + +#ifdef CONFIG_PAGING +# include +# include "pg_macros.h" +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct section_mapping_s +{ + uint32_t physbase; /* Physical address of the region to be mapped */ + uint32_t virtbase; /* Virtual address of the region to be mapped */ + uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ + uint32_t nsections; /* Number of mappings in the region */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical address + * space of the LPCD313x. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static const struct section_mapping_s section_mapping[] = +{ + { LPC31_SHADOWSPACE_PSECTION, LPC31_SHADOWSPACE_VSECTION, + LPC31_SHADOWSPACE_MMUFLAGS, LPC31_SHADOWSPACE_NSECTIONS}, +#ifndef CONFIG_PAGING /* SRAM is already fully mapped */ + { LPC31_INTSRAM_PSECTION, LPC31_INTSRAM_VSECTION, + LPC31_INTSRAM_MMUFLAGS, LPC31_INTSRAM_NSECTIONS}, +#endif +#ifdef CONFIG_ARCH_ROMPGTABLE + { LPC31_INTSROM0_PSECTION, LPC31_INTSROM0_VSECTION, + LPC31_INTSROM_MMUFLAGS, LPC31_INTSROM0_NSECTIONS}, +#endif + { LPC31_APB01_PSECTION, LPC31_APB01_VSECTION, + LPC31_APB01_MMUFLAGS, LPC31_APB01_NSECTIONS}, + { LPC31_APB2_PSECTION, LPC31_APB2_VSECTION, + LPC31_APB2_MMUFLAGS, LPC31_APB2_NSECTIONS}, + { LPC31_APB3_PSECTION, LPC31_APB3_VSECTION, + LPC31_APB3_MMUFLAGS, LPC31_APB3_NSECTIONS}, + { LPC31_APB4MPMC_PSECTION, LPC31_APB4MPMC_VSECTION, + LPC31_APB4MPMC_MMUFLAGS, LPC31_APB4MPMC_NSECTIONS}, + { LPC31_MCI_PSECTION, LPC31_MCI_VSECTION, + LPC31_MCI_MMUFLAGS, LPC31_MCI_NSECTIONS}, + { LPC31_USBOTG_PSECTION, LPC31_USBOTG_VSECTION, + LPC31_USBOTG_MMUFLAGS, LPC31_USBOTG_NSECTIONS}, +#if defined(CONFIG_LPC31_EXTSRAM0) && CONFIG_LPC31_EXTSRAM0SIZE > 0 + { LPC31_EXTSRAM_PSECTION, LPC31_EXTSRAM_VSECTION, + LPC31_EXTSDRAM_MMUFLAGS, LPC31_EXTSRAM_NSECTIONS}, +#endif +#if defined(CONFIG_LPC31_EXTDRAM) && CONFIG_LPC31_EXTDRAMSIZE > 0 + { LPC31_EXTSDRAM0_PSECTION, LPC31_EXTSDRAM0_VSECTION, + LPC31_EXTSDRAM_MMUFLAGS, LPC31_EXTSDRAM0_NSECTIONS}, +#endif + { LPC31_INTC_PSECTION, LPC31_INTC_VSECTION, + LPC31_INTC_MMUFLAGS, LPC31_INTC_NSECTIONS}, +#ifdef CONFIG_LPC31_EXTNAND + { LPC31_NAND_PSECTION, LPC31_NAND_VSECTION + LPC31_NAND_MMUFLAGS, LPC31_NAND_NSECTIONS}, +#endif +}; +#define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s)) +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_setlevel1entry + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline void up_setlevel1entry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *pgtable = (uint32_t *)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + pgtable[index] = (paddr | mmuflags); +} +#endif + +/************************************************************************************ + * Name: up_setlevel2coarseentry + ************************************************************************************/ + +static inline void up_setlevel2coarseentry(uint32_t ctabvaddr, uint32_t paddr, + uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *ctable = (uint32_t *)ctabvaddr; + uint32_t index; + + /* The coarse table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The coarse page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the coarse table entry */ + + ctable[index] = (paddr | mmuflags); +} + +/************************************************************************************ + * Name: up_setupmappings + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static void up_setupmappings(void) +{ + int i, j; + + for (i = 0; i < NMAPPINGS; i++) + { + uint32_t sect_paddr = section_mapping[i].physbase; + uint32_t sect_vaddr = section_mapping[i].virtbase; + uint32_t mmuflags = section_mapping[i].mmuflags; + + for (j = 0; j < section_mapping[i].nsections; j++) + { + up_setlevel1entry(sect_paddr, sect_vaddr, mmuflags); + sect_paddr += SECTION_SIZE; + sect_vaddr += SECTION_SIZE; + } + } +} +#endif + +/************************************************************************************ + * Name: up_vectorpermissions + * + * Description: + * Set permissions on the vector mapping. + * + ************************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) +static void up_vectorpermissions(uint32_t mmuflags) +{ + /* The PTE for the beginning of ISRAM is at the base of the L2 page table */ + + uint32_t *ptr = (uint32_t *)PG_L2_VECT_VADDR; + uint32_t pte; + + /* The pte might be zero the first time this function is called. */ + + pte = *ptr; + if (pte == 0) + { + pte = PG_VECT_PBASE; + } + else + { + pte &= PG_L1_PADDRMASK; + } + + /* Update the MMU flags and save */ + + *ptr = pte | mmuflags; + + /* Invalid the TLB for this address */ + + tlb_invalidate_single(PG_L2_VECT_VADDR); +} +#endif + +/************************************************************************************ + * Name: up_vectormapping + * + * Description: + * Setup a special mapping for the interrupt vectors when (1) the interrupt + * vectors are not positioned in ROM, and when (2) the interrupt vectors are + * located at the high address, 0xffff0000. When the interrupt vectors are located + * in ROM, we just have to assume that they were set up correctly; When vectors + * are located in low memory, 0x00000000, the shadow memory region will be mapped + * to support them. + * + ************************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS) +static void up_vectormapping(void) +{ + uint32_t vector_paddr = LPC31_VECTOR_PADDR; + uint32_t vector_vaddr = LPC31_VECTOR_VADDR; + uint32_t end_paddr = vector_paddr + VECTOR_TABLE_SIZE; + + /* We want to keep our interrupt vectors and interrupt-related logic in zero-wait + * state internal RAM (IRAM). The DM320 has 16Kb of IRAM positioned at physical + * address 0x0000:0000; we need to map this to 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + up_setlevel2coarseentry(PGTABLE_L2_COARSE_VBASE, vector_paddr, + vector_vaddr, MMU_L2_VECTORFLAGS); + vector_paddr += 4096; + vector_vaddr += 4096; + } + + /* Now set the level 1 descriptor to refer to the level 2 coarse page table. */ + + up_setlevel1entry(PGTABLE_L2_COARSE_PBASE, LPC31_VECTOR_VCOARSE, + MMU_L1_VECTORFLAGS); +} +#endif + +/************************************************************************************ + * Name: up_copyvectorblock + * + * Description: + * Copy the interrupt block to its final destination. + * + ************************************************************************************/ + +static void up_copyvectorblock(void) +{ + uint32_t *src; + uint32_t *end; + uint32_t *dest; + + /* If we are using vectors in low memory but RAM in that area has been marked + * read only, then temparily mark the mapping write-able (non-buffered). + */ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + up_vectorpermissions(MMU_L2_VECTRWFLAGS); +#endif + + /* Copy the vectors into ISRAM at the address that will be mapped to the vector + * address: + * + * LPC31_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * LPC31_VECTOR_VSRAM - Virtual address of vector table in SRAM + * LPC31_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + + src = (uint32_t *)&_vector_start; + end = (uint32_t *)&_vector_end; + dest = (uint32_t *)LPC31_VECTOR_VSRAM; + + while (src < end) + { + *dest++ = *src++; + } + + /* Make the vectors read-only, cacheable again */ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + up_vectorpermissions(MMU_L2_VECTROFLAGS); +#endif + + /* Then set the LPC313x shadow register, LPC31_SYSCREG_ARM926SHADOWPTR, so that + * the vector table is mapped to address 0x0000:0000 - NOTE: that there is not yet + * full support for the vector table at address 0xffff0000. + */ + + putreg32(LPC31_VECTOR_PADDR, LPC31_SYSCREG_ARM926SHADOWPTR); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_boot + * + * Description: + * Complete boot operations started in up_head.S + * + ************************************************************************************/ + +void up_boot(void) +{ + /* __start provided the basic MMU mappings for SRAM. Now provide mappings for all + * IO regions (Including the vector region). + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + up_setupmappings(); + + /* Provide a special mapping for the IRAM interrupt vector positioned in high + * memory. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + up_vectormapping(); +#endif +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* Setup up vector block. _vector_start and _vector_end are exported from + * up_vector.S + */ + + up_copyvectorblock(); + + /* Reset all clocks */ + + lpc31_resetclks(); + + /* Initialize the PLLs */ + + lpc31_hp1pllconfig(); + lpc31_hp0pllconfig(); + + /* Initialize clocking to settings provided by board-specific logic */ + + lpc31_clkinit(&g_boardclks); + + /* Map first 4KB of ARM space to ISRAM area */ + + putreg32(LPC31_INTSRAM0_PADDR, LPC31_SYSCREG_ARM926SHADOWPTR); + + /* Perform common, low-level chip initialization (might do nothing) */ + + lpc31_lowsetup(); + + /* Perform early serial initialization if we are going to use the serial driver */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-specific initialization */ + + lpc31_boardinitialize(); +} diff --git a/arch/arm/src/lpc31xx/lpc31_cgu.h b/arch/arm/src/lpc31xx/lpc31_cgu.h new file mode 100644 index 0000000000000000000000000000000000000000..15c16e8a8ed84e1a0dd4b0ed124bee24ca920ef1 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_cgu.h @@ -0,0 +1,1631 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_cgu.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_CGU_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_CGU_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* CGU register base address offset into the APB0 domain ****************************************/ + +/* APB0 offsets to Clock Switch Box (CSB) and CGU Configuration (CFG) register groups */ + +#define LPC31_APB0_GCU_CSB_OFFSET (LPC31_APB0_GCU_OFFSET) +#define LPC31_APB0_GCU_CFG_OFFSET (LPC31_APB0_GCU_OFFSET+0x0c00) + +/* Virtual and physical base address of the CGU block and CSB and CFG register groups */ + +#define LPC31_CGU_VBASE (LPC31_APB0_VADDR+LPC31_APB0_CGU_OFFSET) +#define LPC31_CGU_PBASE (LPC31_APB0_PADDR+LPC31_APB0_CGU_OFFSET) + +#define LPC31_CGU_CSB_VBASE (LPC31_APB0_VADDR+LPC31_APB0_GCU_CSB_OFFSET) +#define LPC31_CGU_CSB_PBASE (LPC31_APB0_PADDR+LPC31_APB0_GCU_CSB_OFFSET) + +#define LPC31_CGU_CFG_VBASE (LPC31_APB0_VADDR+LPC31_APB0_GCU_CFG_OFFSET) +#define LPC31_CGU_CFG_PBASE (LPC31_APB0_PADDR+LPC31_APB0_GCU_CFG_OFFSET) + +/* CGU register offsets *************************************************************************/ +/* CGU clock switchbox register offsets (with respect to the CGU CSB register base) *************/ +/* Switch configuration registers (SCR) for base clocks */ + +#define LPC31_CGU_SCR_OFFSET(n) (0x000+((n)<<2)) +#define LPC31_CGU_SCR0_OFFSET 0x000 /* SYS base */ +#define LPC31_CGU_SCR1_OFFSET 0x004 /* AHB0_APB0 base */ +#define LPC31_CGU_SCR2_OFFSET 0x008 /* AHB0_APB1 base */ +#define LPC31_CGU_SCR3_OFFSET 0x00c /* AHB0_APB2 base */ +#define LPC31_CGU_SCR4_OFFSET 0x010 /* AHB0_APB3 base */ +#define LPC31_CGU_SCR5_OFFSET 0x014 /* PCM base */ +#define LPC31_CGU_SCR6_OFFSET 0x018 /* UART base */ +#define LPC31_CGU_SCR7_OFFSET 0x01c /* CLK1024FS base */ +#define LPC31_CGU_SCR8_OFFSET 0x020 /* I2SRX_BCK0 base */ +#define LPC31_CGU_SCR9_OFFSET 0x024 /* I2SRX_BCK1 base */ +#define LPC31_CGU_SCR10_OFFSET 0x028 /* SPI_CLK base */ +#define LPC31_CGU_SCR11_OFFSET 0x02c /* SYSCLK_O base */ + +/* Frequency select (FS) registers 1 for base clocks */ + +#define LPC31_CGU_FS1_OFFSET(n) (0x030+((n)<<2)) +#define LPC31_CGU_FS1_0_OFFSET 0x030 /* SYS base */ +#define LPC31_CGU_FS1_1_OFFSET 0x034 /* AHB0_APB0 base */ +#define LPC31_CGU_FS1_2_OFFSET 0x038 /* AHB0_APB1 base */ +#define LPC31_CGU_FS1_3_OFFSET 0x03c /* AHB0_APB2 base */ +#define LPC31_CGU_FS1_4_OFFSET 0x040 /* AHB0_APB3 base */ +#define LPC31_CGU_FS1_5_OFFSET 0x044 /* PCM base */ +#define LPC31_CGU_FS1_6_OFFSET 0x048 /* UART base */ +#define LPC31_CGU_FS1_7_OFFSET 0x04c /* CLK1024FS base */ +#define LPC31_CGU_FS1_8_OFFSET 0x050 /* I2SRX_BCK0 base */ +#define LPC31_CGU_FS1_9_OFFSET 0x054 /* I2SRX_BCK1 base */ +#define LPC31_CGU_FS1_10_OFFSET 0x058 /* SPI_CLK base */ +#define LPC31_CGU_FS1_11_OFFSET 0x05c /* SYSCLK_O base */ + +/* Frequency select (FS) registers 2 for base clocks */ + +#define LPC31_CGU_FS2_OFFSET(n) (0x060+((n)<<2)) +#define LPC31_CGU_FS2_0_OFFSET 0x060 /* SYS base */ +#define LPC31_CGU_FS2_1_OFFSET 0x064 /* AHB0_APB0 base */ +#define LPC31_CGU_FS2_2_OFFSET 0x068 /* AHB0_APB1 base */ +#define LPC31_CGU_FS2_3_OFFSET 0x06c /* AHB0_APB2 base */ +#define LPC31_CGU_FS2_4_OFFSET 0x070 /* AHB0_APB3 base */ +#define LPC31_CGU_FS2_5_OFFSET 0x074 /* PCM base */ +#define LPC31_CGU_FS2_6_OFFSET 0x078 /* UART base */ +#define LPC31_CGU_FS2_7_OFFSET 0x07c /* CLK1024FS base */ +#define LPC31_CGU_FS2_8_OFFSET 0x080 /* I2SRX_BCK0 base */ +#define LPC31_CGU_FS2_9_OFFSET 0x084 /* I2SRX_BCK1 base */ +#define LPC31_CGU_FS2_10_OFFSET 0x088 /* SPI_CLK base */ +#define LPC31_CGU_FS2_11_OFFSET 0x08c /* SYSCLK_O base */ + +/* Switch status registers (SSR) for base clocks */ + +#define LPC31_CGU_SSR_OFFSET(n) (0x090+((n)<<2)) +#define LPC31_CGU_SSR0_OFFSET 0x090 /* SYS base */ +#define LPC31_CGU_SSR1_OFFSET 0x094 /* AHB0_APB0 base */ +#define LPC31_CGU_SSR2_OFFSET 0x098 /* AHB0_APB1 base */ +#define LPC31_CGU_SSR3_OFFSET 0x09c /* AHB0_APB2 base */ +#define LPC31_CGU_SSR4_OFFSET 0x0a0 /* AHB0_APB3 base */ +#define LPC31_CGU_SSR5_OFFSET 0x0a4 /* PCM base */ +#define LPC31_CGU_SSR6_OFFSET 0x0a8 /* UART base */ +#define LPC31_CGU_SSR7_OFFSET 0x0ac /* CLK1024FS base */ +#define LPC31_CGU_SSR8_OFFSET 0x0b0 /* I2SRX_BCK0 base */ +#define LPC31_CGU_SSR9_OFFSET 0x0b4 /* I2SRX_BCK1 base */ +#define LPC31_CGU_SSR10_OFFSET 0x0b8 /* SPI_CLK base */ +#define LPC31_CGU_SSR11_OFFSET 0x0bc /* SYSCLK_O base */ + +/* Power control registers (PCR), spreading stage */ + +#define LPC31_CGU_PCR_OFFSET(n) (0x0c0+((n)<<2)) +#define LPC31_CGU_PCR0_OFFSET 0x0c0 /* APB0_CLK */ +#define LPC31_CGU_PCR1_OFFSET 0x0c4 /* APB1_CLK */ +#define LPC31_CGU_PCR2_OFFSET 0x0c8 /* APB2_CLK */ +#define LPC31_CGU_PCR3_OFFSET 0x0cc /* APB3_CLK */ +#define LPC31_CGU_PCR4_OFFSET 0x0d0 /* APB4_CLK */ +#define LPC31_CGU_PCR5_OFFSET 0x0d4 /* AHB_TO_INTC_CLK */ +#define LPC31_CGU_PCR6_OFFSET 0x0d8 /* AHB0_CLK */ +#define LPC31_CGU_PCR7_OFFSET 0x0dc /* EBI_CLK */ +#define LPC31_CGU_PCR8_OFFSET 0x0e0 /* DMA_PCLK */ +#define LPC31_CGU_PCR9_OFFSET 0x0e4 /* DMA_CLK_GATED */ +#define LPC31_CGU_PCR10_OFFSET 0x0e8 /* NANDFLASH_S0_CLK */ +#define LPC31_CGU_PCR11_OFFSET 0x0ec /* NANDFLASH_ECC_CLK */ +#define LPC31_CGU_PCR12_OFFSET 0x0f0 /* Reserved */ +#define LPC31_CGU_PCR13_OFFSET 0x0f4 /* NANDFLASH_NAND_CLK */ +#define LPC31_CGU_PCR14_OFFSET 0x0f8 /* NANDFLASH_PCLK */ +#define LPC31_CGU_PCR15_OFFSET 0x0fc /* CLOCK_OUT */ +#define LPC31_CGU_PCR16_OFFSET 0x100 /* ARM926_CORE_CLK */ +#define LPC31_CGU_PCR17_OFFSET 0x104 /* ARM926_BUSIF_CLK */ +#define LPC31_CGU_PCR18_OFFSET 0x108 /* ARM926_RETIME_CLK */ +#define LPC31_CGU_PCR19_OFFSET 0x10c /* SD_MMC_HCLK */ +#define LPC31_CGU_PCR20_OFFSET 0x110 /* SD_MMC_CCLK_IN */ +#define LPC31_CGU_PCR21_OFFSET 0x114 /* USB_OTG_AHB_CLK */ +#define LPC31_CGU_PCR22_OFFSET 0x118 /* ISRAM0_CLK */ +#define LPC31_CGU_PCR23_OFFSET 0x11c /* RED_CTL_RSCLK */ +#define LPC31_CGU_PCR24_OFFSET 0x120 /* ISRAM1_CLK (LPC313x only) */ +#define LPC31_CGU_PCR25_OFFSET 0x124 /* ISROM_CLK */ +#define LPC31_CGU_PCR26_OFFSET 0x128 /* MPMC_CFG_CLK */ +#define LPC31_CGU_PCR27_OFFSET 0x12c /* MPMC_CFG_CLK2 */ +#define LPC31_CGU_PCR28_OFFSET 0x130 /* MPMC_CFG_CLK3 */ +#define LPC31_CGU_PCR29_OFFSET 0x134 /* INTC_CLK */ +#define LPC31_CGU_PCR30_OFFSET 0x138 /* AHB_TO_APB0_PCLK */ +#define LPC31_CGU_PCR31_OFFSET 0x13c /* EVENT_ROUTER_PCLK */ +#define LPC31_CGU_PCR32_OFFSET 0x140 /* ADC_PCLK */ +#define LPC31_CGU_PCR33_OFFSET 0x144 /* ADC_CLK */ +#define LPC31_CGU_PCR34_OFFSET 0x148 /* WDOG_PCLK */ +#define LPC31_CGU_PCR35_OFFSET 0x14c /* IOCONF_PCLK */ +#define LPC31_CGU_PCR36_OFFSET 0x150 /* CGU_PCLK */ +#define LPC31_CGU_PCR37_OFFSET 0x154 /* SYSCREG_PCLK */ +#define LPC31_CGU_PCR38_OFFSET 0x158 /* Reserved */ +#define LPC31_CGU_PCR39_OFFSET 0x15c /* RNG_PCLK */ +#define LPC31_CGU_PCR40_OFFSET 0x160 /* AHB_TO_APB1_PCLK */ +#define LPC31_CGU_PCR41_OFFSET 0x164 /* TIMER0_PCLK */ +#define LPC31_CGU_PCR42_OFFSET 0x168 /* TIMER1_PCLK */ +#define LPC31_CGU_PCR43_OFFSET 0x16c /* TIMER2_PCLK */ +#define LPC31_CGU_PCR44_OFFSET 0x170 /* TIMER3_PCLK */ +#define LPC31_CGU_PCR45_OFFSET 0x174 /* PWM_PCLK */ +#define LPC31_CGU_PCR46_OFFSET 0x178 /* PWM_PCLK_REGS */ +#define LPC31_CGU_PCR47_OFFSET 0x17c /* PWM_CLK */ +#define LPC31_CGU_PCR48_OFFSET 0x180 /* I2C0_PCLK */ +#define LPC31_CGU_PCR49_OFFSET 0x184 /* I2C1_PCLK */ +#define LPC31_CGU_PCR50_OFFSET 0x188 /* AHB_TO_APB2_PCLK */ +#define LPC31_CGU_PCR51_OFFSET 0x18c /* PCM_PCLK */ +#define LPC31_CGU_PCR52_OFFSET 0x190 /* PCM_APB_PCLK */ +#define LPC31_CGU_PCR53_OFFSET 0x194 /* UART_APB_CLK */ +#define LPC31_CGU_PCR54_OFFSET 0x198 /* LCD_PCLK */ +#define LPC31_CGU_PCR55_OFFSET 0x19c /* LCD_CLK */ +#define LPC31_CGU_PCR56_OFFSET 0x1a0 /* SPI_PCLK */ +#define LPC31_CGU_PCR57_OFFSET 0x1a4 /* SPI_PCLK_GATED */ +#define LPC31_CGU_PCR58_OFFSET 0x1a8 /* AHB_TO_APB3_PCLK */ +#define LPC31_CGU_PCR59_OFFSET 0x1ac /* I2S_CFG_PCLK */ +#define LPC31_CGU_PCR60_OFFSET 0x1b0 /* EDGE_DET_PCLK */ +#define LPC31_CGU_PCR61_OFFSET 0x1b4 /* I2STX_FIFO_0_PCLK */ +#define LPC31_CGU_PCR62_OFFSET 0x1b8 /* I2STX_IF_0_PCLK */ +#define LPC31_CGU_PCR63_OFFSET 0x1bc /* I2STX_FIFO_1_PCLK */ +#define LPC31_CGU_PCR64_OFFSET 0x1c0 /* I2STX_IF_1_PCLK */ +#define LPC31_CGU_PCR65_OFFSET 0x1c4 /* I2SRX_FIFO_0_PCLK */ +#define LPC31_CGU_PCR66_OFFSET 0x1c8 /* I2SRX_IF_0_PCLK */ +#define LPC31_CGU_PCR67_OFFSET 0x1cc /* I2SRX_FIFO_1_PCLK */ +#define LPC31_CGU_PCR68_OFFSET 0x1d0 /* I2SRX_IF_1_PCLK */ +#define LPC31_CGU_PCR69_OFFSET 0x1d4 /* Reserved */ +#define LPC31_CGU_PCR70_OFFSET 0x1d8 /* Reserved */ +#define LPC31_CGU_PCR71_OFFSET 0x1dc /* PCM_CLK_IP */ +#define LPC31_CGU_PCR72_OFFSET 0x1e0 /* UART_U_CLK */ +#define LPC31_CGU_PCR73_OFFSET 0x1e4 /* I2S_EDGE_DETECT_CLK */ +#define LPC31_CGU_PCR74_OFFSET 0x1e8 /* I2STX_BCK0_N */ +#define LPC31_CGU_PCR75_OFFSET 0x1ec /* I2STX_WS0 */ +#define LPC31_CGU_PCR76_OFFSET 0x1f0 /* I2STX_CLK0 */ +#define LPC31_CGU_PCR77_OFFSET 0x1f4 /* I2STX_BCK1_N */ +#define LPC31_CGU_PCR78_OFFSET 0x1f8 /* I2STX_WS1 */ +#define LPC31_CGU_PCR79_OFFSET 0x1fc /* CLK_256FS */ +#define LPC31_CGU_PCR80_OFFSET 0x200 /* I2SRX_BCK0_N */ +#define LPC31_CGU_PCR81_OFFSET 0x204 /* I2SRX_WS0 */ +#define LPC31_CGU_PCR82_OFFSET 0x208 /* I2SRX_BCK1_N */ +#define LPC31_CGU_PCR83_OFFSET 0x20c /* I2SRX_WS1 */ +#define LPC31_CGU_PCR84_OFFSET 0x210 /* Reserved */ +#define LPC31_CGU_PCR85_OFFSET 0x214 /* Reserved */ +#define LPC31_CGU_PCR86_OFFSET 0x218 /* Reserved */ +#define LPC31_CGU_PCR87_OFFSET 0x21c /* I2SRX_BCK0 */ +#define LPC31_CGU_PCR88_OFFSET 0x220 /* I2SRX_BCK1 */ +#define LPC31_CGU_PCR89_OFFSET 0x224 /* SPI_CLK */ +#define LPC31_CGU_PCR90_OFFSET 0x228 /* SPI_CLK_GATED */ +#define LPC31_CGU_PCR91_OFFSET 0x22c /* SYSCLK_O */ + +/* Power status registers (PSR), spreading stage */ + +#define LPC31_CGU_PSR_OFFSET(n) (0x230+((n)<<2)) +#define LPC31_CGU_PSR0_OFFSET 0x230 /* PB0_CLK */ +#define LPC31_CGU_PSR1_OFFSET 0x234 /* PB1_CLK */ +#define LPC31_CGU_PSR2_OFFSET 0x238 /* PB2_CLK */ +#define LPC31_CGU_PSR3_OFFSET 0x23c /* PB3_CLK */ +#define LPC31_CGU_PSR4_OFFSET 0x240 /* PB4_CLK */ +#define LPC31_CGU_PSR5_OFFSET 0x244 /* HB_TO_INTC_CLK */ +#define LPC31_CGU_PSR6_OFFSET 0x248 /* HB0_CLK */ +#define LPC31_CGU_PSR7_OFFSET 0x24c /* EBI_CLK */ +#define LPC31_CGU_PSR8_OFFSET 0x250 /* DMA_PCLK */ +#define LPC31_CGU_PSR9_OFFSET 0x254 /* DMA_CLK_GATED */ +#define LPC31_CGU_PSR10_OFFSET 0x258 /* NANDFLASH_S0_CLK */ +#define LPC31_CGU_PSR11_OFFSET 0x25c /* NANDFLASH_ECC_CLK */ +#define LPC31_CGU_PSR12_OFFSET 0x260 /* Reserved */ +#define LPC31_CGU_PSR13_OFFSET 0x264 /* NANDFLASH_NAND_CLK */ +#define LPC31_CGU_PSR14_OFFSET 0x268 /* NANDFLASH_PCLK */ +#define LPC31_CGU_PSR15_OFFSET 0x26c /* CLOCK_OUT */ +#define LPC31_CGU_PSR16_OFFSET 0x270 /* RM926_CORE_CLK */ +#define LPC31_CGU_PSR17_OFFSET 0x274 /* RM926_BUSIF_CLK */ +#define LPC31_CGU_PSR18_OFFSET 0x278 /* RM926_RETIME_CLK */ +#define LPC31_CGU_PSR19_OFFSET 0x27c /* SD_MMC_HCLK */ +#define LPC31_CGU_PSR20_OFFSET 0x280 /* SD_MMC_CCLK_IN */ +#define LPC31_CGU_PSR21_OFFSET 0x284 /* USB_OTG_AHB_CLK */ +#define LPC31_CGU_PSR22_OFFSET 0x288 /* ISRAM0_CLK */ +#define LPC31_CGU_PSR23_OFFSET 0x28c /* RED_CTL_RSCLK */ +#define LPC31_CGU_PSR24_OFFSET 0x290 /* ISRAM1_CLK */ +#define LPC31_CGU_PSR25_OFFSET 0x294 /* ISROM_CLK */ +#define LPC31_CGU_PSR26_OFFSET 0x298 /* MPMC_CFG_CLK */ +#define LPC31_CGU_PSR27_OFFSET 0x29c /* MPMC_CFG_CLK2 */ +#define LPC31_CGU_PSR28_OFFSET 0x2a0 /* MPMC_CFG_CLK3 */ +#define LPC31_CGU_PSR29_OFFSET 0x2a4 /* INTC_CLK */ +#define LPC31_CGU_PSR30_OFFSET 0x2a8 /* HB_TO_APB0_PCLK */ +#define LPC31_CGU_PSR31_OFFSET 0x2ac /* EVENT_ROUTER_PCLK */ +#define LPC31_CGU_PSR32_OFFSET 0x2b0 /* DC_PCLK */ +#define LPC31_CGU_PSR33_OFFSET 0x2b4 /* DC_CLK */ +#define LPC31_CGU_PSR34_OFFSET 0x2b8 /* WDOG_PCLK */ +#define LPC31_CGU_PSR35_OFFSET 0x2bc /* IOCONF_PCLK */ +#define LPC31_CGU_PSR36_OFFSET 0x2c0 /* CGU_PCLK */ +#define LPC31_CGU_PSR37_OFFSET 0x2c4 /* SYSCREG_PCLK */ +#define LPC31_CGU_PSR38_OFFSET 0x2c8 /* Reserved */ +#define LPC31_CGU_PSR39_OFFSET 0x2cc /* RNG_PCLK */ +#define LPC31_CGU_PSR40_OFFSET 0x2d0 /* HB_TO_APB1_PCLK */ +#define LPC31_CGU_PSR41_OFFSET 0x2d4 /* TIMER0_PCLK */ +#define LPC31_CGU_PSR42_OFFSET 0x2d8 /* TIMER1_PCLK */ +#define LPC31_CGU_PSR43_OFFSET 0x2dc /* TIMER2_PCLK */ +#define LPC31_CGU_PSR44_OFFSET 0x2e0 /* TIMER3_PCLK */ +#define LPC31_CGU_PSR45_OFFSET 0x2e4 /* PWM_PCLK */ +#define LPC31_CGU_PSR46_OFFSET 0x2e8 /* PWM_PCLK_REGS */ +#define LPC31_CGU_PSR47_OFFSET 0x2ec /* PWM_CLK */ +#define LPC31_CGU_PSR48_OFFSET 0x2f0 /* I2C0_PCLK */ +#define LPC31_CGU_PSR49_OFFSET 0x2f4 /* I2C1_PCLK */ +#define LPC31_CGU_PSR50_OFFSET 0x2f8 /* HB_TO_APB2_PCLK */ +#define LPC31_CGU_PSR51_OFFSET 0x2fc /* PCM_PCLK */ +#define LPC31_CGU_PSR52_OFFSET 0x300 /* PCM_APB_PCLK */ +#define LPC31_CGU_PSR53_OFFSET 0x304 /* UART_APB_CLK */ +#define LPC31_CGU_PSR54_OFFSET 0x308 /* LCD_PCLK */ +#define LPC31_CGU_PSR55_OFFSET 0x30c /* LCD_CLK */ +#define LPC31_CGU_PSR56_OFFSET 0x310 /* SPI_PCLK */ +#define LPC31_CGU_PSR57_OFFSET 0x314 /* SPI_PCLK_GATED */ +#define LPC31_CGU_PSR58_OFFSET 0x318 /* HB_TO_APB3_PCLK */ +#define LPC31_CGU_PSR59_OFFSET 0x31c /* I2S_CFG_PCLK */ +#define LPC31_CGU_PSR60_OFFSET 0x320 /* EDGE_DET_PCLK */ +#define LPC31_CGU_PSR61_OFFSET 0x324 /* I2STX_FIFO_0_PCLK */ +#define LPC31_CGU_PSR62_OFFSET 0x328 /* I2STX_IF_0_PCLK */ +#define LPC31_CGU_PSR63_OFFSET 0x32c /* I2STX_FIFO_1_PCLK */ +#define LPC31_CGU_PSR64_OFFSET 0x330 /* I2STX_IF_1_PCLK */ +#define LPC31_CGU_PSR65_OFFSET 0x334 /* I2SRX_FIFO_0_PCLK */ +#define LPC31_CGU_PSR66_OFFSET 0x338 /* I2SRX_IF_0_PCLK */ +#define LPC31_CGU_PSR67_OFFSET 0x33c /* I2SRX_FIFO_1_PCLK */ +#define LPC31_CGU_PSR68_OFFSET 0x340 /* I2SRX_IF_1_PCLK */ +#define LPC31_CGU_PSR69_OFFSET 0x344 /* Reserved */ +#define LPC31_CGU_PSR70_OFFSET 0x348 /* Reserved */ +#define LPC31_CGU_PSR71_OFFSET 0x34c /* PCM_CLK_IP */ +#define LPC31_CGU_PSR72_OFFSET 0x350 /* UART_U_CLK */ +#define LPC31_CGU_PSR73_OFFSET 0x354 /* I2S_EDGE_DETECT_CLK */ +#define LPC31_CGU_PSR74_OFFSET 0x358 /* I2STX_BCK0_N */ +#define LPC31_CGU_PSR75_OFFSET 0x35c /* I2STX_WS0 */ +#define LPC31_CGU_PSR76_OFFSET 0x360 /* I2STX_CLK0 */ +#define LPC31_CGU_PSR77_OFFSET 0x364 /* I2STX_BCK1_N */ +#define LPC31_CGU_PSR78_OFFSET 0x368 /* I2STX_WS1 */ +#define LPC31_CGU_PSR79_OFFSET 0x36c /* CLK_256FS */ +#define LPC31_CGU_PSR80_OFFSET 0x370 /* I2SRX_BCK0_N */ +#define LPC31_CGU_PSR81_OFFSET 0x374 /* I2SRX_WS0 */ +#define LPC31_CGU_PSR82_OFFSET 0x378 /* I2SRX_BCK1_N */ +#define LPC31_CGU_PSR83_OFFSET 0x37c /* I2SRX_WS1 */ +#define LPC31_CGU_PSR84_OFFSET 0x380 /* Reserved */ +#define LPC31_CGU_PSR85_OFFSET 0x384 /* Reserved */ +#define LPC31_CGU_PSR86_OFFSET 0x388 /* Reserved */ +#define LPC31_CGU_PSR87_OFFSET 0x38c /* I2SRX_BCK0 */ +#define LPC31_CGU_PSR88_OFFSET 0x390 /* I2SRX_BCK1 */ +#define LPC31_CGU_PSR89_OFFSET 0x394 /* SPI_CLK */ +#define LPC31_CGU_PSR90_OFFSET 0x398 /* SPI_CLK_GATED */ +#define LPC31_CGU_PSR91_OFFSET 0x39c /* SYSCLK_O */ + +/* Enable select registers (ESR), spreading stage */ + +#define LPC31_CGU_ESR_OFFSET(n) (0x3a0+((n)<<2)) +#define LPC31_CGU_ESR0_OFFSET 0x3a0 /* APB0_CLK */ +#define LPC31_CGU_ESR1_OFFSET 0x3a4 /* APB1_CLK */ +#define LPC31_CGU_ESR2_OFFSET 0x3A8 /* APB2_CLK */ +#define LPC31_CGU_ESR3_OFFSET 0x3ac /* APB3_CLK */ +#define LPC31_CGU_ESR4_OFFSET 0x3b0 /* APB4_CLK */ +#define LPC31_CGU_ESR5_OFFSET 0x3b4 /* AHB_TO_INTC_CLK */ +#define LPC31_CGU_ESR6_OFFSET 0x3b8 /* AHB0_CLK */ +#define LPC31_CGU_ESR7_OFFSET 0x3bc /* EBI_CLK */ +#define LPC31_CGU_ESR8_OFFSET 0x3c0 /* DMA_PCLK */ +#define LPC31_CGU_ESR9_OFFSET 0x3c4 /* DMA_CLK_GATED */ +#define LPC31_CGU_ESR10_OFFSET 0x3c8 /* NANDFLASH_S0_CLK */ +#define LPC31_CGU_ESR11_OFFSET 0x3cc /* NANDFLASH_ECC_CLK */ +#define LPC31_CGU_ESR12_OFFSET 0x3d0 /* Reserved */ +#define LPC31_CGU_ESR13_OFFSET 0x3d4 /* NANDFLASH_NAND_CLK */ +#define LPC31_CGU_ESR14_OFFSET 0x3d8 /* NANDFLASH_PCLK */ +#define LPC31_CGU_ESR15_OFFSET 0x3dc /* CLOCK_OUT */ +#define LPC31_CGU_ESR16_OFFSET 0x3e0 /* ARM926_CORE_CLK */ +#define LPC31_CGU_ESR17_OFFSET 0x3e4 /* ARM926_BUSIF_CLK */ +#define LPC31_CGU_ESR18_OFFSET 0x3e8 /* ARM926_RETIME_CLK */ +#define LPC31_CGU_ESR19_OFFSET 0x3ec /* SD_MMC_HCLK */ +#define LPC31_CGU_ESR20_OFFSET 0x3f0 /* SD_MMC_CCLK_IN */ +#define LPC31_CGU_ESR21_OFFSET 0x3f4 /* USB_OTG_AHB_CLK */ +#define LPC31_CGU_ESR22_OFFSET 0x3f8 /* ISRAM0_CLK */ +#define LPC31_CGU_ESR23_OFFSET 0x3fc /* RED_CTL_RSCLK */ +#define LPC31_CGU_ESR24_OFFSET 0x400 /* ISRAM1_CLK */ +#define LPC31_CGU_ESR25_OFFSET 0x404 /* ISROM_CLK */ +#define LPC31_CGU_ESR26_OFFSET 0x408 /* MPMC_CFG_CLK */ +#define LPC31_CGU_ESR27_OFFSET 0x40c /* MPMC_CFG_CLK2 */ +#define LPC31_CGU_ESR28_OFFSET 0x410 /* MPMC_CFG_CLK3 */ +#define LPC31_CGU_ESR29_OFFSET 0x414 /* INTC_CLK */ +#define LPC31_CGU_ESR30_OFFSET 0x418 /* AHB_TO_APB0_PCLK */ +#define LPC31_CGU_ESR31_OFFSET 0x41c /* EVENT_ROUTER_PCLK */ +#define LPC31_CGU_ESR32_OFFSET 0x420 /* ADC_PCLK */ +#define LPC31_CGU_ESR33_OFFSET 0x424 /* ADC_CLK */ +#define LPC31_CGU_ESR34_OFFSET 0x428 /* WDOG_PCLK */ +#define LPC31_CGU_ESR35_OFFSET 0x42c /* IOCONF_PCLK */ +#define LPC31_CGU_ESR36_OFFSET 0x430 /* CGU_PCLK */ +#define LPC31_CGU_ESR37_OFFSET 0x434 /* SYSCREG_PCLK */ +#define LPC31_CGU_ESR38_OFFSET 0x438 /* Reserved */ +#define LPC31_CGU_ESR39_OFFSET 0x43c /* RNG_PCLK */ +#define LPC31_CGU_ESR40_OFFSET 0x440 /* AHB_TO_APB1_PCLK */ +#define LPC31_CGU_ESR41_OFFSET 0x444 /* TIMER0_PCLK */ +#define LPC31_CGU_ESR42_OFFSET 0x448 /* TIMER1_PCLK */ +#define LPC31_CGU_ESR43_OFFSET 0x44c /* TIMER2_PCLK */ +#define LPC31_CGU_ESR44_OFFSET 0x450 /* TIMER3_PCLK */ +#define LPC31_CGU_ESR45_OFFSET 0x454 /* PWM_PCLK */ +#define LPC31_CGU_ESR46_OFFSET 0x458 /* PWM_PCLK_REGS */ +#define LPC31_CGU_ESR47_OFFSET 0x45c /* PWM_CLK */ +#define LPC31_CGU_ESR48_OFFSET 0x460 /* I2C0_PCLK */ +#define LPC31_CGU_ESR49_OFFSET 0x464 /* I2C1_PCLK */ +#define LPC31_CGU_ESR50_OFFSET 0x468 /* AHB_TO_APB2_PCLK */ +#define LPC31_CGU_ESR51_OFFSET 0x46c /* PCM_PCLK */ +#define LPC31_CGU_ESR52_OFFSET 0x470 /* PCM_APB_PCLK */ +#define LPC31_CGU_ESR53_OFFSET 0x474 /* UART_APB_CLK */ +#define LPC31_CGU_ESR54_OFFSET 0x478 /* LCD_PCLK */ +#define LPC31_CGU_ESR55_OFFSET 0x47c /* LCD_CLK */ +#define LPC31_CGU_ESR56_OFFSET 0x480 /* SPI_PCLK */ +#define LPC31_CGU_ESR57_OFFSET 0x484 /* SPI_PCLK_GATED */ +#define LPC31_CGU_ESR58_OFFSET 0x488 /* AHB_TO_APB3_PCLK */ +#define LPC31_CGU_ESR59_OFFSET 0x48c /* I2S_CFG_PCLK */ +#define LPC31_CGU_ESR60_OFFSET 0x490 /* EDGE_DET_PCLK */ +#define LPC31_CGU_ESR61_OFFSET 0x494 /* I2STX_FIFO_0_PCLK */ +#define LPC31_CGU_ESR62_OFFSET 0x498 /* I2STX_IF_0_PCLK */ +#define LPC31_CGU_ESR63_OFFSET 0x49c /* I2STX_FIFO_1_PCLK */ +#define LPC31_CGU_ESR64_OFFSET 0x4a0 /* I2STX_IF_1_PCLK */ +#define LPC31_CGU_ESR65_OFFSET 0x4a4 /* I2SRX_FIFO_0_PCLK */ +#define LPC31_CGU_ESR66_OFFSET 0x4a8 /* I2SRX_IF_0_PCLK */ +#define LPC31_CGU_ESR67_OFFSET 0x4ac /* I2SRX_FIFO_1_PCLK */ +#define LPC31_CGU_ESR68_OFFSET 0x4b0 /* I2SRX_IF_1_PCLK */ +#define LPC31_CGU_ESR69_OFFSET 0x4b4 /* Reserved */ +#define LPC31_CGU_ESR70_OFFSET 0x4b8 /* Reserved */ +#define LPC31_CGU_ESR71_OFFSET 0x4bc /* PCM_CLK_IP */ +#define LPC31_CGU_ESR72_OFFSET 0x4c0 /* UART_U_CLK */ +#define LPC31_CGU_ESR73_OFFSET 0x4c4 /* I2S_EDGE_DETECT_CLK */ +#define LPC31_CGU_ESR74_OFFSET 0x4c8 /* R_I2STX_BCK0_N */ +#define LPC31_CGU_ESR75_OFFSET 0x4cc /* I2STX_WS0 */ +#define LPC31_CGU_ESR76_OFFSET 0x4d0 /* I2STX_CLK0 */ +#define LPC31_CGU_ESR77_OFFSET 0x4d4 /* I2STX_IF_BCK1_N */ +#define LPC31_CGU_ESR78_OFFSET 0x4d8 /* I2STX_WS1 */ +#define LPC31_CGU_ESR79_OFFSET 0x4dc /* CLK_256FS */ +#define LPC31_CGU_ESR80_OFFSET 0x4e0 /* I2SRX_BCK0_N */ +#define LPC31_CGU_ESR81_OFFSET 0x4e4 /* I2SRX_WS0 */ +#define LPC31_CGU_ESR82_OFFSET 0x4e8 /* I2SRX_BCK1_N */ +#define LPC31_CGU_ESR83_OFFSET 0x4ec /* I2SRX_WS1 */ +#define LPC31_CGU_ESR84_OFFSET 0x4f0 /* Reserved */ +#define LPC31_CGU_ESR85_OFFSET 0x4f4 /* Reserved */ +#define LPC31_CGU_ESR86_OFFSET 0x4f8 /* Reserved */ +#define LPC31_CGU_ESR87_OFFSET 0x4fc /* SPI_CLK */ +#define LPC31_CGU_ESR88_OFFSET 0x500 /* SPI_CLK_GATED */ + +/* Base control registers (BCR) for SYS base */ + +#define LPC31_CGU_BCR_OFFSET(n) (0x504+((n)<<2)) +#define LPC31_CGU_BCR0_OFFSET 0x504 /* SYS base */ +#define LPC31_CGU_BCR1_OFFSET 0x508 /* AHB0_APB0 base */ +#define LPC31_CGU_BCR2_OFFSET 0x50c /* AHB0_APB1 base */ +#define LPC31_CGU_BCR3_OFFSET 0x510 /* AHB0_APB2 base */ +#define LPC31_CGU_BCR7_OFFSET 0x514 /* CLK1024FS base */ + +/* Fractional divider configuration (FDC) registers */ + +#define LPC31_CGU_FDC_OFFSET(n) (0x518+((n)<<2)) +#define LPC31_CGU_FDC0_OFFSET 0x518 /* Fractional Divider 0 (SYS base) */ +#define LPC31_CGU_FDC1_OFFSET 0x51c /* Fractional Divider 1 (SYS base) */ +#define LPC31_CGU_FDC2_OFFSET 0x520 /* Fractional Divider 2 (SYS base) */ +#define LPC31_CGU_FDC3_OFFSET 0x524 /* Fractional Divider 3 (SYS base) */ +#define LPC31_CGU_FDC4_OFFSET 0x528 /* Fractional Divider 4 (SYS base) */ +#define LPC31_CGU_FDC5_OFFSET 0x52c /* Fractional Divider 5 (SYS base) */ +#define LPC31_CGU_FDC6_OFFSET 0x530 /* Fractional Divider 6 (SYS base) */ +#define LPC31_CGU_FDC7_OFFSET 0x534 /* Fractional Divider 7 (AHB0_APB0 base) */ +#define LPC31_CGU_FDC8_OFFSET 0x538 /* Fractional Divider 8 (AHB0_APB0 base) */ +#define LPC31_CGU_FDC9_OFFSET 0x53c /* Fractional Divider 9 (AHB0_APB1 base) */ +#define LPC31_CGU_FDC10_OFFSET 0x540 /* Fractional Divider 10 (AHB0_APB1 base) */ +#define LPC31_CGU_FDC11_OFFSET 0x544 /* Fractional Divider 11 (AHB0_APB2 base) */ +#define LPC31_CGU_FDC12_OFFSET 0x548 /* Fractional Divider 12 (AHB0_APB2 base) */ +#define LPC31_CGU_FDC13_OFFSET 0x54c /* Fractional Divider 13 (AHB0_APB2 base) */ +#define LPC31_CGU_FDC14_OFFSET 0x550 /* Fractional Divider 14 (AHB0_APB3 base) */ +#define LPC31_CGU_FDC15_OFFSET 0x554 /* Fractional Divider 15 (PCM base) */ +#define LPC31_CGU_FDC16_OFFSET 0x558 /* Fractional Divider 16 (UART base) */ +#define LPC31_CGU_FDC17_OFFSET 0x55c /* Fractional Divider 17 (CLK1024FS base) */ +#define LPC31_CGU_FDC18_OFFSET 0x560 /* Fractional Divider 18 (CLK1024FS base) */ +#define LPC31_CGU_FDC19_OFFSET 0x564 /* Fractional Divider 19 (CLK1024FS base) */ +#define LPC31_CGU_FDC20_OFFSET 0x568 /* Fractional Divider 20 (CLK1024FS base) */ +#define LPC31_CGU_FDC21_OFFSET 0x56c /* Fractional Divider 21 (CLK1024FS base) */ +#define LPC31_CGU_FDC22_OFFSET 0x570 /* Fractional Divider 22 (CLK1024FS base) */ +#define LPC31_CGU_FDC23_OFFSET 0x574 /* Fractional Divider 23 (SPI_CLK base) */ + +/* Dynamic fractional divider configuration (DYNFDC) registers (SYS base only) */ + +#define LPC31_CGU_DYNFDC_OFFSET(n) (0x578+((n)<<2)) +#define LPC31_CGU_DYNFDC0_OFFSET 0x578 /* Fractional Divider 0 (SYS base) */ +#define LPC31_CGU_DYNFDC1_OFFSET 0x57c /* Fractional Divider 1 (SYS base) */ +#define LPC31_CGU_DYNFDC2_OFFSET 0x580 /* Fractional Divider 2 (SYS base) */ +#define LPC31_CGU_DYNFDC3_OFFSET 0x584 /* Fractional Divider 3 (SYS base) */ +#define LPC31_CGU_DYNFDC4_OFFSET 0x588 /* Fractional Divider 4 (SYS base) */ +#define LPC31_CGU_DYNFDC5_OFFSET 0x58c /* Fractional Divider 5 (SYS base) */ +#define LPC31_CGU_DYNFDC6_OFFSET 0x590 /* Fractional Divider 6 (SYS base) */ + +/* Dynamic fractional divider selection (DYNSEL) registers (SYS base only) */ + +#define LPC31_CGU_DYNSEL_OFFSET(n) (0x594+((n)<<2)) +#define LPC31_CGU_DYNSEL0_OFFSET 0x594 /* Fractional Divider 0 (SYS base) */ +#define LPC31_CGU_DYNSEL1_OFFSET 0x598 /* Fractional Divider 1 (SYS base) */ +#define LPC31_CGU_DYNSEL2_OFFSET 0x59c /* Fractional Divider 2 (SYS base) */ +#define LPC31_CGU_DYNSEL3_OFFSET 0x5a0 /* Fractional Divider 3 (SYS base) */ +#define LPC31_CGU_DYNSEL4_OFFSET 0x5a4 /* Fractional Divider 4 (SYS base) */ +#define LPC31_CGU_DYNSEL5_OFFSET 0x5a8 /* Fractional Divider 5 (SYS base) */ +#define LPC31_CGU_DYNSEL6_OFFSET 0x5ac /* Fractional Divider 6 (SYS base) */ + +/* CGU configuration register offsets (with respect to the CGU CFG register base) ***************/ +/* Power and oscillator control */ + +#define LPC31_CGU_POWERMODE_OFFSET 0x000 /* Power mode register */ +#define LPC31_CGU_WDBARK_OFFSET 0x004 /* Watch dog bark register */ +#define LPC31_CGU_FFASTON_OFFSET 0x008 /* Activate fast oscillator register */ +#define LPC31_CGU_FFASTBYP_OFFSET 0x00c /* Bypass comparator register fast oscillator reset */ + +/* Reset control */ + +#define LPC31_CGU_SOFTRST_OFFSET(n) (0x010+((n)<<2)) +#define LPC31_CGU_APB0RST_OFFSET 0x010 /* Reset AHB part of AHB_TO_APB0 bridge */ +#define LPC31_CGU_AHB2APB0RST_OFFSET 0x014 /* Reset APB part of AHB_TO_APB0 bridge */ +#define LPC31_CGU_APB1RST_OFFSET 0x018 /* Reset AHB part of AHB_TO_APB1 bridge */ +#define LPC31_CGU_AHB2PB1RST_OFFSET 0x01c /* Reset APB part of AHB_TO_APB1 bridge */ +#define LPC31_CGU_APB2RST_OFFSET 0x020 /* Reset AHB part of AHB_TO_APB2 bridge */ +#define LPC31_CGU_AHB2APB2RST_OFFSET 0x024 /* Reset APB part of AHB_TO_APB2 bridge */ +#define LPC31_CGU_APB3RST_OFFSET 0x028 /* Reset AHB part of AHB_TO_APB3 bridge */ +#define LPC31_CGU_AHB2APB3RST_OFFSET 0x02c /* Reset APB part of AHB_TO_APB3 bridge */ +#define LPC31_CGU_APB4RST_OFFSET 0x030 /* Reset AHB_TO_APB4 bridge */ +#define LPC31_CGU_AHB2INTCRST_OFFSET 0x034 /* Reset AHB_TO_INTC */ +#define LPC31_CGU_AHB0RST_OFFSET 0x038 /* Reset AHB0 */ +#define LPC31_CGU_EBIRST_OFFSET 0x03c /* Reset EBI */ +#define LPC31_CGU_PCMAPBRST_OFFSET 0x040 /* Reset APB domain of PCM */ +#define LPC31_CGU_PCMCLKIPRST_OFFSET 0x044 /* Reset synchronous clk_ip domain of PCM */ +#define LPC31_CGU_PCMRSTASYNC_OFFSET 0x048 /* Reset asynchronous clk_ip domain of PCM */ +#define LPC31_CGU_TIMER0RST_OFFSET 0x04c /* Reset Timer0 */ +#define LPC31_CGU_TIMER1RST_OFFSET 0x050 /* Reset Timer1 */ +#define LPC31_CGU_TIMER2RST_OFFSET 0x054 /* Reset Timer2 */ +#define LPC31_CGU_TIMER3RST_OFFSET 0x058 /* Reset Timer3 */ +#define LPC31_CGU_ADCPRST_OFFSET 0x05c /* Reset controller of 10 bit ADC Interface */ +#define LPC31_CGU_ADCRST_OFFSET 0x060 /* Reset A/D converter of ADC Interface */ +#define LPC31_CGU_PWMRST_OFFSET 0x064 /* Reset PWM */ +#define LPC31_CGU_UARTRST_OFFSET 0x068 /* Reset UART/IrDA */ +#define LPC31_CGU_I2C0RST_OFFSET 0x06c /* Reset I2C0 */ +#define LPC31_CGU_I2C1RST_OFFSET 0x070 /* Reset I2C1 */ +#define LPC31_CGU_I2SCFGRST_OFFSET 0x074 /* Reset I2S_Config */ +#define LPC31_CGU_I2SNSOFRST_OFFSET 0x078 /* Reset NSOF counter of I2S_CONFIG */ +#define LPC31_CGU_EDGEDETRST_OFFSET 0x07c /* Reset Edge_det */ +#define LPC31_CGU_I2STXFF0RST_OFFSET 0x080 /* Reset I2STX_FIFO_0 */ +#define LPC31_CGU_I2STXIF0RST_OFFSET 0x084 /* Reset I2STX_IF_0 */ +#define LPC31_CGU_I2STXFF1RST_OFFSET 0x088 /* Reset I2STX_FIFO_1 */ +#define LPC31_CGU_I2STXIF1RST_OFFSET 0x08c /* Reset I2STX_IF_1 */ +#define LPC31_CGU_I2SRXFF0RST_OFFSET 0x090 /* Reset I2SRX_FIFO_0 */ +#define LPC31_CGU_I2SRXIF0RST_OFFSET 0x094 /* Reset I2SRX_IF_0 */ +#define LPC31_CGU_I2SRXFF1RST_OFFSET 0x098 /* Reset I2SRX_FIFO_1 */ +#define LPC31_CGU_I2SRXIF1RST_OFFSET 0x09c /* Reset I2SRX_IF_1 */ + /* 0x0a0 to 0x0b0: Reserved */ +#define LPC31_CGU_LCDRST_OFFSET 0x0b4 /* Reset LCD Interface */ +#define LPC31_CGU_SPIRSTAPB_OFFSET 0x0b8 /* Reset apb_clk domain of SPI */ +#define LPC31_CGU_SPIRSTIP_OFFSET 0x0bc /* Reset ip_clk domain of SPI */ +#define LPC31_CGU_DMARST_OFFSET 0x0c0 /* Reset DMA */ +#define LPC31_CGU_NANDECCRST_OFFSET 0x0c4 /* Reset Nandflash Controller ECC clock */ + /* 0x0c8: Reserved */ +#define LPC31_CGU_NANDCTRLRST_OFFSET 0x0cc /* Reset of Nandflash Controller */ +#define LPC31_CGU_RNGRST_OFFSET 0x0d0 /* Reset of RNG */ +#define LPC31_CGU_SDMMCRST_OFFSET 0x0d4 /* Reset MCI (on AHB clock) */ +#define LPC31_CGU_SDMMCRSTCKIN_OFFSET 0x0d8 /* Reset MCI synchronous (on IP clock) */ +#define LPC31_CGU_USBOTGAHBRST_OFFSET 0x0dc /* Reset USB_OTG */ +#define LPC31_CGU_REDCTLRST_OFFSET 0x0e0 /* Reset Redundancy Controller */ +#define LPC31_CGU_AHBMPMCHRST_OFFSET 0x0e4 /* Reset MPMC */ +#define LPC31_CGU_AHBMPMCRFRST_OFFSET 0x0e8 /* Reset refresh generator used for MPMC */ +#define LPC31_CGU_INTCRST_OFFSET 0x0ec /* Reset Interrupt Controller */ + +/* HP PLL controls */ + +#define LPC313x_CGU_HP0PLL_OFFSET 0x0f0 /* Base offset to HP0 PLL registers */ +#define LPC313x_CGU_HP1PLL_OFFSET 0x128 /* Base offset to HP1 PLL registers */ +#define CGU_HP0PLL 0 /* HP0 PLL selector */ +#define CGU_HP1PLL 1 /* HP1 PLL selector */ +#define LPC313x_CGU_HPPLL_OFFSET(n) ((n) ? LPC313x_CGU_HP1PLL_OFFSET : LPC313x_CGU_HP0PLL_OFFSET) + +#define LPC31_CGU_HPFINSEL_OFFSET 0x000 /* Register for selecting input to high HPPLL0/1 */ +#define LPC31_CGU_HPMDEC_OFFSET 0x004 /* M-divider register of HP0/1 PLL */ +#define LPC31_CGU_HPNDEC_OFFSET 0x008 /* N-divider register of HP0/1 PLL */ +#define LPC31_CGU_HPPDEC_OFFSET 0x00c /* P-divider register of HP0/1 PLL */ +#define LPC31_CGU_HPMODE_OFFSET 0x010 /* Mode register of HP0/1 PLL */ +#define LPC31_CGU_HPSTATUS_OFFSET 0x014 /* Status register of HP0/1 PLL */ +#define LPC31_CGU_HPACK_OFFSET 0x018 /* Ratio change acknowledge register of HP0/1 PLL */ +#define LPC31_CGU_HPREQ_OFFSET 0x01c /* Ratio change request register of HP0/1 PLL */ +#define LPC31_CGU_HPINSELR_OFFSET 0x020 /* Bandwidth selection register of HP0/1 PLL */ +#define LPC31_CGU_HPINSELI_OFFSET 0x024 /* Bandwidth selection register of HP0/1 PLL */ +#define LPC31_CGU_HPINSELP_OFFSET 0x028 /* Bandwidth selection register of HP0/1 PLL */ +#define LPC31_CGU_HPSELR_OFFSET 0x02c /* Bandwidth selection register of HP0/1 PLL */ +#define LPC31_CGU_HPSELI_OFFSET 0x030 /* Bandwidth selection register of HP0/1 PLL */ +#define LPC31_CGU_HPSELP_OFFSET 0x034 /* Bandwidth selection register of HP0/1 PLL */ + +/* HP0 PLL control (audio PLL) */ + +#define LPC31_CGU_HP0FINSEL_OFFSET 0x0f0 /* Register for selecting input to high HPPLL0 */ +#define LPC31_CGU_HP0MDEC_OFFSET 0x0f4 /* M-divider register of HP0 PLL */ +#define LPC31_CGU_HP0NDEC_OFFSET 0x0f8 /* N-divider register of HP0 PLL */ +#define LPC31_CGU_HP0PDEC_OFFSET 0x0fc /* P-divider register of HP0 PLL */ +#define LPC31_CGU_HP0MODE_OFFSET 0x100 /* Mode register of HP0 PLL */ +#define LPC31_CGU_HP0STATUS_OFFSET 0x104 /* Status register of HP0 PLL */ +#define LPC31_CGU_HP0ACK_OFFSET 0x108 /* Ratio change acknowledge register of HP0 PLL */ +#define LPC31_CGU_HP0REQ_OFFSET 0x10c /* Ratio change request register of HP0 PLL */ +#define LPC31_CGU_HP0INSELR_OFFSET 0x110 /* Bandwidth selection register of HP0 PLL */ +#define LPC31_CGU_HP0INSELI_OFFSET 0x114 /* Bandwidth selection register of HP0 PLL */ +#define LPC31_CGU_HP0INSELP_OFFSET 0x118 /* Bandwidth selection register of HP0 PLL */ +#define LPC31_CGU_HP0SELR_OFFSET 0x11c /* Bandwidth selection register of HP0 PLL */ +#define LPC31_CGU_HP0SELI_OFFSET 0x120 /* Bandwidth selection register of HP0 PLL */ +#define LPC31_CGU_HP0SELP_OFFSET 0x124 /* Bandwidth selection register of HP0 PLL */ + +/* HP1 PLL control (system PLL) */ + +#define LPC31_CGU_HP1FINSEL_OFFSET 0x128 /* Register for selecting input to high HP1 PLL */ +#define LPC31_CGU_HP1MDEC_OFFSET 0x12c /* M-divider register of HP1 PLL */ +#define LPC31_CGU_HP1NDEC_OFFSET 0x130 /* N-divider register of HP1 PLL */ +#define LPC31_CGU_HP1PDEC_OFFSET 0x134 /* P-divider register of HP1 PLL */ +#define LPC31_CGU_HP1MODE_OFFSET 0x138 /* Mode register of HP1 PLL */ +#define LPC31_CGU_HP1STATUS_OFFSET 0x13c /* Status register of HP1 PLL */ +#define LPC31_CGU_HP1ACK_OFFSET 0x140 /* Ratio change acknowledge register of HP1 PLL */ +#define LPC31_CGU_HP1REQ_OFFSET 0x144 /* Ratio change request register of HP1 PLL */ +#define LPC31_CGU_HP1INSELR_OFFSET 0x148 /* Bandwidth selection register of HP1 PLL */ +#define LPC31_CGU_HP1INSELI_OFFSET 0x14c /* Bandwidth selection register of HP1 PLL */ +#define LPC31_CGU_HP1INSELP_OFFSET 0x150 /* Bandwidth selection register of HP1 PLL */ +#define LPC31_CGU_HP1SELR_OFFSET 0x154 /* Bandwidth selection register of HP1 PLL */ +#define LPC31_CGU_HP1SELI_OFFSET 0x158 /* Bandwidth selection register of HP1 PLL */ +#define LPC31_CGU_HP1SELP_OFFSET 0x15c /* Bandwidth selection register of HP1 PLL */ + +/* CGU register (virtual) addresses *************************************************************/ +/* CGU clock switchbox (virtual) register addresses *********************************************/ +/* Switch configuration registers (SCR) for base clocks */ + +#define LPC31_CGU_SCR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR_OFFSET(n)) +#define LPC31_CGU_SCR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR0_OFFSET) +#define LPC31_CGU_SCR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR1_OFFSET) +#define LPC31_CGU_SCR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR2_OFFSET) +#define LPC31_CGU_SCR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR3_OFFSET) +#define LPC31_CGU_SCR4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR4_OFFSET) +#define LPC31_CGU_SCR5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR5_OFFSET) +#define LPC31_CGU_SCR6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR6_OFFSET) +#define LPC31_CGU_SCR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR7_OFFSET) +#define LPC31_CGU_SCR8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR8_OFFSET) +#define LPC31_CGU_SCR9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR9_OFFSET) +#define LPC31_CGU_SCR10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR10_OFFSET) +#define LPC31_CGU_SCR11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SCR11_OFFSET) + +/* Frequency select (FS) registers 1 for base clocks */ + +#define LPC31_CGU_FS1(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_OFFSET(n)) +#define LPC31_CGU_FS1_0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_0_OFFSET) +#define LPC31_CGU_FS1_1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_1_OFFSET) +#define LPC31_CGU_FS1_2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_2_OFFSET) +#define LPC31_CGU_FS1_3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_3_OFFSET) +#define LPC31_CGU_FS1_4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_4_OFFSET) +#define LPC31_CGU_FS1_5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_5_OFFSET) +#define LPC31_CGU_FS1_6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_6_OFFSET) +#define LPC31_CGU_FS1_7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_7_OFFSET) +#define LPC31_CGU_FS1_8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_8_OFFSET) +#define LPC31_CGU_FS1_9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_9_OFFSET) +#define LPC31_CGU_FS1_10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_10_OFFSET) +#define LPC31_CGU_FS1_11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS1_11_OFFSET) + +/* Frequency select (FS) registers 2 for base clocks */ + +#define LPC31_CGU_FS2(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_OFFSET(n)) +#define LPC31_CGU_FS2_0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_0_OFFSET) +#define LPC31_CGU_FS2_1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_1_OFFSET) +#define LPC31_CGU_FS2_2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_2_OFFSET) +#define LPC31_CGU_FS2_3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_3_OFFSET) +#define LPC31_CGU_FS2_4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_4_OFFSET) +#define LPC31_CGU_FS2_5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_5_OFFSET) +#define LPC31_CGU_FS2_6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_6_OFFSET) +#define LPC31_CGU_FS2_7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_7_OFFSET) +#define LPC31_CGU_FS2_8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_8_OFFSET) +#define LPC31_CGU_FS2_9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_9_OFFSET) +#define LPC31_CGU_FS2_10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_10_OFFSET) +#define LPC31_CGU_FS2_11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FS2_11_OFFSET) + +/* Switch status registers (SSR) for base clocks */ + +#define LPC31_CGU_SSR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR_OFFSET(n)) +#define LPC31_CGU_SSR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR0_OFFSET) +#define LPC31_CGU_SSR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR1_OFFSET) +#define LPC31_CGU_SSR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR2_OFFSET) +#define LPC31_CGU_SSR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR3_OFFSET) +#define LPC31_CGU_SSR4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR4_OFFSET) +#define LPC31_CGU_SSR5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR5_OFFSET) +#define LPC31_CGU_SSR6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR6_OFFSET) +#define LPC31_CGU_SSR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR7_OFFSET) +#define LPC31_CGU_SSR8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR8_OFFSET) +#define LPC31_CGU_SSR9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR9_OFFSET) +#define LPC31_CGU_SSR10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR10_OFFSET) +#define LPC31_CGU_SSR11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_SSR11_OFFSET) + +/* Power control registers (PCR), spreading stage */ + +#define LPC31_CGU_PCR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR_OFFSET(n)) +#define LPC31_CGU_PCR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR0_OFFSET) +#define LPC31_CGU_PCR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR1_OFFSET) +#define LPC31_CGU_PCR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR2_OFFSET) +#define LPC31_CGU_PCR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR3_OFFSET) +#define LPC31_CGU_PCR4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR4_OFFSET) +#define LPC31_CGU_PCR5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR5_OFFSET) +#define LPC31_CGU_PCR6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR6_OFFSET) +#define LPC31_CGU_PCR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR7_OFFSET) +#define LPC31_CGU_PCR8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR8_OFFSET) +#define LPC31_CGU_PCR9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR9_OFFSET) +#define LPC31_CGU_PCR10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR10_OFFSET) +#define LPC31_CGU_PCR11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR11_OFFSET) +#define LPC31_CGU_PCR12 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR12_OFFSET) +#define LPC31_CGU_PCR13 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR13_OFFSET) +#define LPC31_CGU_PCR14 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR14_OFFSET) +#define LPC31_CGU_PCR15 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR15_OFFSET) +#define LPC31_CGU_PCR16 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR16_OFFSET) +#define LPC31_CGU_PCR17 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR17_OFFSET) +#define LPC31_CGU_PCR18 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR18_OFFSET) +#define LPC31_CGU_PCR19 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR19_OFFSET) +#define LPC31_CGU_PCR20 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR20_OFFSET) +#define LPC31_CGU_PCR21 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR21_OFFSET) +#define LPC31_CGU_PCR22 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR22_OFFSET) +#define LPC31_CGU_PCR23 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR23_OFFSET) +#define LPC31_CGU_PCR24 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR24_OFFSET) +#define LPC31_CGU_PCR25 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR25_OFFSET) +#define LPC31_CGU_PCR26 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR26_OFFSET) +#define LPC31_CGU_PCR27 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR27_OFFSET) +#define LPC31_CGU_PCR28 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR28_OFFSET) +#define LPC31_CGU_PCR29 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR29_OFFSET) +#define LPC31_CGU_PCR30 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR30_OFFSET) +#define LPC31_CGU_PCR31 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR31_OFFSET) +#define LPC31_CGU_PCR32 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR32_OFFSET) +#define LPC31_CGU_PCR33 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR33_OFFSET) +#define LPC31_CGU_PCR34 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR34_OFFSET) +#define LPC31_CGU_PCR35 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR35_OFFSET) +#define LPC31_CGU_PCR36 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR36_OFFSET) +#define LPC31_CGU_PCR37 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR37_OFFSET) +#define LPC31_CGU_PCR38 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR38_OFFSET) +#define LPC31_CGU_PCR39 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR39_OFFSET) +#define LPC31_CGU_PCR40 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR40_OFFSET) +#define LPC31_CGU_PCR41 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR41_OFFSET) +#define LPC31_CGU_PCR42 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR42_OFFSET) +#define LPC31_CGU_PCR43 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR43_OFFSET) +#define LPC31_CGU_PCR44 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR44_OFFSET) +#define LPC31_CGU_PCR45 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR45_OFFSET) +#define LPC31_CGU_PCR46 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR46_OFFSET) +#define LPC31_CGU_PCR47 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR47_OFFSET) +#define LPC31_CGU_PCR48 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR48_OFFSET) +#define LPC31_CGU_PCR49 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR49_OFFSET) +#define LPC31_CGU_PCR50 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR50_OFFSET) +#define LPC31_CGU_PCR51 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR51_OFFSET) +#define LPC31_CGU_PCR52 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR52_OFFSET) +#define LPC31_CGU_PCR53 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR53_OFFSET) +#define LPC31_CGU_PCR54 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR54_OFFSET) +#define LPC31_CGU_PCR55 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR55_OFFSET) +#define LPC31_CGU_PCR56 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR56_OFFSET) +#define LPC31_CGU_PCR57 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR57_OFFSET) +#define LPC31_CGU_PCR58 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR58_OFFSET) +#define LPC31_CGU_PCR59 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR59_OFFSET) +#define LPC31_CGU_PCR60 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR60_OFFSET) +#define LPC31_CGU_PCR61 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR61_OFFSET) +#define LPC31_CGU_PCR62 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR62_OFFSET) +#define LPC31_CGU_PCR63 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR63_OFFSET) +#define LPC31_CGU_PCR64 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR64_OFFSET) +#define LPC31_CGU_PCR65 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR65_OFFSET) +#define LPC31_CGU_PCR66 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR66_OFFSET) +#define LPC31_CGU_PCR67 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR67_OFFSET) +#define LPC31_CGU_PCR68 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR68_OFFSET) +#define LPC31_CGU_PCR69 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR69_OFFSET) +#define LPC31_CGU_PCR70 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR70_OFFSET) +#define LPC31_CGU_PCR71 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR71_OFFSET) +#define LPC31_CGU_PCR72 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR72_OFFSET) +#define LPC31_CGU_PCR73 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR73_OFFSET) +#define LPC31_CGU_PCR74 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR74_OFFSET) +#define LPC31_CGU_PCR75 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR75_OFFSET) +#define LPC31_CGU_PCR76 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR76_OFFSET) +#define LPC31_CGU_PCR77 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR77_OFFSET) +#define LPC31_CGU_PCR78 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR78_OFFSET) +#define LPC31_CGU_PCR79 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR79_OFFSET) +#define LPC31_CGU_PCR80 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR80_OFFSET) +#define LPC31_CGU_PCR81 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR81_OFFSET) +#define LPC31_CGU_PCR82 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR82_OFFSET) +#define LPC31_CGU_PCR83 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR83_OFFSET) +#define LPC31_CGU_PCR84 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR84_OFFSET) +#define LPC31_CGU_PCR85 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR85_OFFSET) +#define LPC31_CGU_PCR86 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR86_OFFSET) +#define LPC31_CGU_PCR87 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR87_OFFSET) +#define LPC31_CGU_PCR88 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR88_OFFSET) +#define LPC31_CGU_PCR89 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR89_OFFSET) +#define LPC31_CGU_PCR90 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR90_OFFSET) +#define LPC31_CGU_PCR91 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PCR91_OFFSET) + +/* Power status registers (PSR), spreading stage */ + +#define LPC31_CGU_PSR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR_OFFSET(n)) +#define LPC31_CGU_PSR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR0_OFFSET) +#define LPC31_CGU_PSR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR1_OFFSET) +#define LPC31_CGU_PSR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR2_OFFSET) +#define LPC31_CGU_PSR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR3_OFFSET) +#define LPC31_CGU_PSR4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR4_OFFSET) +#define LPC31_CGU_PSR5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR5_OFFSET) +#define LPC31_CGU_PSR6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR6_OFFSET) +#define LPC31_CGU_PSR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR7_OFFSET) +#define LPC31_CGU_PSR8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR8_OFFSET) +#define LPC31_CGU_PSR9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR9_OFFSET) +#define LPC31_CGU_PSR10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR10_OFFSET) +#define LPC31_CGU_PSR11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR11_OFFSET) +#define LPC31_CGU_PSR12 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR12_OFFSET) +#define LPC31_CGU_PSR13 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR13_OFFSET) +#define LPC31_CGU_PSR14 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR14_OFFSET) +#define LPC31_CGU_PSR15 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR15_OFFSET) +#define LPC31_CGU_PSR16 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR16_OFFSET) +#define LPC31_CGU_PSR17 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR17_OFFSET) +#define LPC31_CGU_PSR18 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR18_OFFSET) +#define LPC31_CGU_PSR19 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR19_OFFSET) +#define LPC31_CGU_PSR20 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR20_OFFSET) +#define LPC31_CGU_PSR21 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR21_OFFSET) +#define LPC31_CGU_PSR22 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR22_OFFSET) +#define LPC31_CGU_PSR23 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR23_OFFSET) +#define LPC31_CGU_PSR24 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR24_OFFSET) +#define LPC31_CGU_PSR25 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR25_OFFSET) +#define LPC31_CGU_PSR26 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR26_OFFSET) +#define LPC31_CGU_PSR27 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR27_OFFSET) +#define LPC31_CGU_PSR28 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR28_OFFSET) +#define LPC31_CGU_PSR29 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR29_OFFSET) +#define LPC31_CGU_PSR30 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR30_OFFSET) +#define LPC31_CGU_PSR31 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR31_OFFSET) +#define LPC31_CGU_PSR32 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR32_OFFSET) +#define LPC31_CGU_PSR33 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR33_OFFSET) +#define LPC31_CGU_PSR34 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR34_OFFSET) +#define LPC31_CGU_PSR35 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR35_OFFSET) +#define LPC31_CGU_PSR36 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR36_OFFSET) +#define LPC31_CGU_PSR37 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR37_OFFSET) +#define LPC31_CGU_PSR38 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR38_OFFSET) +#define LPC31_CGU_PSR39 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR39_OFFSET) +#define LPC31_CGU_PSR40 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR40_OFFSET) +#define LPC31_CGU_PSR41 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR41_OFFSET) +#define LPC31_CGU_PSR42 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR42_OFFSET) +#define LPC31_CGU_PSR43 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR43_OFFSET) +#define LPC31_CGU_PSR44 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR44_OFFSET) +#define LPC31_CGU_PSR45 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR45_OFFSET) +#define LPC31_CGU_PSR46 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR46_OFFSET) +#define LPC31_CGU_PSR47 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR47_OFFSET) +#define LPC31_CGU_PSR48 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR48_OFFSET) +#define LPC31_CGU_PSR49 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR49_OFFSET) +#define LPC31_CGU_PSR50 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR50_OFFSET) +#define LPC31_CGU_PSR51 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR51_OFFSET) +#define LPC31_CGU_PSR52 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR52_OFFSET) +#define LPC31_CGU_PSR53 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR53_OFFSET) +#define LPC31_CGU_PSR54 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR54_OFFSET) +#define LPC31_CGU_PSR55 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR55_OFFSET) +#define LPC31_CGU_PSR56 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR56_OFFSET) +#define LPC31_CGU_PSR57 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR57_OFFSET) +#define LPC31_CGU_PSR58 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR58_OFFSET) +#define LPC31_CGU_PSR59 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR59_OFFSET) +#define LPC31_CGU_PSR60 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR60_OFFSET) +#define LPC31_CGU_PSR61 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR61_OFFSET) +#define LPC31_CGU_PSR62 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR62_OFFSET) +#define LPC31_CGU_PSR63 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR63_OFFSET) +#define LPC31_CGU_PSR64 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR64_OFFSET) +#define LPC31_CGU_PSR65 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR65_OFFSET) +#define LPC31_CGU_PSR66 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR66_OFFSET) +#define LPC31_CGU_PSR67 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR67_OFFSET) +#define LPC31_CGU_PSR68 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR68_OFFSET) +#define LPC31_CGU_PSR69 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR69_OFFSET) +#define LPC31_CGU_PSR70 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR70_OFFSET) +#define LPC31_CGU_PSR71 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR71_OFFSET) +#define LPC31_CGU_PSR72 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR72_OFFSET) +#define LPC31_CGU_PSR73 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR73_OFFSET) +#define LPC31_CGU_PSR74 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR74_OFFSET) +#define LPC31_CGU_PSR75 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR75_OFFSET) +#define LPC31_CGU_PSR76 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR76_OFFSET) +#define LPC31_CGU_PSR77 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR77_OFFSET) +#define LPC31_CGU_PSR78 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR78_OFFSET) +#define LPC31_CGU_PSR79 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR79_OFFSET) +#define LPC31_CGU_PSR80 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR80_OFFSET) +#define LPC31_CGU_PSR81 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR81_OFFSET) +#define LPC31_CGU_PSR82 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR82_OFFSET) +#define LPC31_CGU_PSR83 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR83_OFFSET) +#define LPC31_CGU_PSR84 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR84_OFFSET) +#define LPC31_CGU_PSR85 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR85_OFFSET) +#define LPC31_CGU_PSR86 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR86_OFFSET) +#define LPC31_CGU_PSR87 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR87_OFFSET) +#define LPC31_CGU_PSR88 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR88_OFFSET) +#define LPC31_CGU_PSR89 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR89_OFFSET) +#define LPC31_CGU_PSR90 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR90_OFFSET) +#define LPC31_CGU_PSR91 (LPC31_CGU_CSB_VBASE+LPC31_CGU_PSR91_OFFSET) + +/* Enable select registers (ESR), spreading stage */ + +#define LPC31_CGU_ESR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR_OFFSET(n)) +#define LPC31_CGU_ESR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR0_OFFSET) +#define LPC31_CGU_ESR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR1_OFFSET) +#define LPC31_CGU_ESR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR2_OFFSET) +#define LPC31_CGU_ESR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR3_OFFSET) +#define LPC31_CGU_ESR4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR4_OFFSET) +#define LPC31_CGU_ESR5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR5_OFFSET) +#define LPC31_CGU_ESR6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR6_OFFSET) +#define LPC31_CGU_ESR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR7_OFFSET) +#define LPC31_CGU_ESR8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR8_OFFSET) +#define LPC31_CGU_ESR9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR9_OFFSET) +#define LPC31_CGU_ESR10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR10_OFFSET) +#define LPC31_CGU_ESR11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR11_OFFSET) +#define LPC31_CGU_ESR12 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR12_OFFSET) +#define LPC31_CGU_ESR13 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR13_OFFSET) +#define LPC31_CGU_ESR14 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR14_OFFSET) +#define LPC31_CGU_ESR15 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR15_OFFSET) +#define LPC31_CGU_ESR16 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR16_OFFSET) +#define LPC31_CGU_ESR17 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR17_OFFSET) +#define LPC31_CGU_ESR18 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR18_OFFSET) +#define LPC31_CGU_ESR19 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR19_OFFSET) +#define LPC31_CGU_ESR20 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR20_OFFSET) +#define LPC31_CGU_ESR21 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR21_OFFSET) +#define LPC31_CGU_ESR22 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR22_OFFSET) +#define LPC31_CGU_ESR23 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR23_OFFSET) +#define LPC31_CGU_ESR24 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR24_OFFSET) +#define LPC31_CGU_ESR25 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR25_OFFSET) +#define LPC31_CGU_ESR26 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR26_OFFSET) +#define LPC31_CGU_ESR27 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR27_OFFSET) +#define LPC31_CGU_ESR28 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR28_OFFSET) +#define LPC31_CGU_ESR29 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR29_OFFSET) +#define LPC31_CGU_ESR30 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR30_OFFSET) +#define LPC31_CGU_ESR31 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR31_OFFSET) +#define LPC31_CGU_ESR32 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR32_OFFSET) +#define LPC31_CGU_ESR33 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR33_OFFSET) +#define LPC31_CGU_ESR34 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR34_OFFSET) +#define LPC31_CGU_ESR35 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR35_OFFSET) +#define LPC31_CGU_ESR36 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR36_OFFSET) +#define LPC31_CGU_ESR37 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR37_OFFSET) +#define LPC31_CGU_ESR38 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR38_OFFSET) +#define LPC31_CGU_ESR39 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR39_OFFSET) +#define LPC31_CGU_ESR40 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR40_OFFSET) +#define LPC31_CGU_ESR41 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR41_OFFSET) +#define LPC31_CGU_ESR42 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR42_OFFSET) +#define LPC31_CGU_ESR43 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR43_OFFSET) +#define LPC31_CGU_ESR44 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR44_OFFSET) +#define LPC31_CGU_ESR45 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR45_OFFSET) +#define LPC31_CGU_ESR46 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR46_OFFSET) +#define LPC31_CGU_ESR47 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR47_OFFSET) +#define LPC31_CGU_ESR48 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR48_OFFSET) +#define LPC31_CGU_ESR49 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR49_OFFSET) +#define LPC31_CGU_ESR50 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR50_OFFSET) +#define LPC31_CGU_ESR51 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR51_OFFSET) +#define LPC31_CGU_ESR52 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR52_OFFSET) +#define LPC31_CGU_ESR53 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR53_OFFSET) +#define LPC31_CGU_ESR54 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR54_OFFSET) +#define LPC31_CGU_ESR55 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR55_OFFSET) +#define LPC31_CGU_ESR56 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR56_OFFSET) +#define LPC31_CGU_ESR57 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR57_OFFSET) +#define LPC31_CGU_ESR58 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR58_OFFSET) +#define LPC31_CGU_ESR59 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR59_OFFSET) +#define LPC31_CGU_ESR60 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR60_OFFSET) +#define LPC31_CGU_ESR61 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR61_OFFSET) +#define LPC31_CGU_ESR62 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR62_OFFSET) +#define LPC31_CGU_ESR63 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR63_OFFSET) +#define LPC31_CGU_ESR64 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR64_OFFSET) +#define LPC31_CGU_ESR65 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR65_OFFSET) +#define LPC31_CGU_ESR66 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR66_OFFSET) +#define LPC31_CGU_ESR67 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR67_OFFSET) +#define LPC31_CGU_ESR68 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR68_OFFSET) +#define LPC31_CGU_ESR69 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR69_OFFSET) +#define LPC31_CGU_ESR70 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR70_OFFSET) +#define LPC31_CGU_ESR71 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR71_OFFSET) +#define LPC31_CGU_ESR72 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR72_OFFSET) +#define LPC31_CGU_ESR73 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR73_OFFSET) +#define LPC31_CGU_ESR74 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR74_OFFSET) +#define LPC31_CGU_ESR75 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR75_OFFSET) +#define LPC31_CGU_ESR76 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR76_OFFSET) +#define LPC31_CGU_ESR77 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR77_OFFSET) +#define LPC31_CGU_ESR78 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR78_OFFSET) +#define LPC31_CGU_ESR79 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR79_OFFSET) +#define LPC31_CGU_ESR80 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR80_OFFSET) +#define LPC31_CGU_ESR81 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR81_OFFSET) +#define LPC31_CGU_ESR82 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR82_OFFSET) +#define LPC31_CGU_ESR83 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR83_OFFSET) +#define LPC31_CGU_ESR84 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR84_OFFSET) +#define LPC31_CGU_ESR85 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR85_OFFSET) +#define LPC31_CGU_ESR86 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR86_OFFSET) +#define LPC31_CGU_ESR87 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR87_OFFSET) +#define LPC31_CGU_ESR88 (LPC31_CGU_CSB_VBASE+LPC31_CGU_ESR88_OFFSET) + +/* Base control registers (BCR) for SYS base */ + +#define LPC31_CGU_BCR(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR_OFFSET(n)) +#define LPC31_CGU_BCR0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR0_OFFSET) +#define LPC31_CGU_BCR1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR1_OFFSET) +#define LPC31_CGU_BCR2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR2_OFFSET) +#define LPC31_CGU_BCR3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR3_OFFSET) +#define LPC31_CGU_BCR7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_BCR7_OFFSET) + +/* Fractional divider configuration (FDC) registers */ + +#define LPC31_CGU_FDC(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC_OFFSET(n)) +#define LPC31_CGU_FDC0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC0_OFFSET) +#define LPC31_CGU_FDC1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC1_OFFSET) +#define LPC31_CGU_FDC2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC2_OFFSET) +#define LPC31_CGU_FDC3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC3_OFFSET) +#define LPC31_CGU_FDC4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC4_OFFSET) +#define LPC31_CGU_FDC5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC5_OFFSET) +#define LPC31_CGU_FDC6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC6_OFFSET) +#define LPC31_CGU_FDC7 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC7_OFFSET) +#define LPC31_CGU_FDC8 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC8_OFFSET) +#define LPC31_CGU_FDC9 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC9_OFFSET) +#define LPC31_CGU_FDC10 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC10_OFFSET) +#define LPC31_CGU_FDC11 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC11_OFFSET) +#define LPC31_CGU_FDC12 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC12_OFFSET) +#define LPC31_CGU_FDC13 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC13_OFFSET) +#define LPC31_CGU_FDC14 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC14_OFFSET) +#define LPC31_CGU_FDC15 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC15_OFFSET) +#define LPC31_CGU_FDC16 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC16_OFFSET) +#define LPC31_CGU_FDC17 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC17_OFFSET) +#define LPC31_CGU_FDC18 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC18_OFFSET) +#define LPC31_CGU_FDC19 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC19_OFFSET) +#define LPC31_CGU_FDC20 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC20_OFFSET) +#define LPC31_CGU_FDC21 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC21_OFFSET) +#define LPC31_CGU_FDC22 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC22_OFFSET) +#define LPC31_CGU_FDC23 (LPC31_CGU_CSB_VBASE+LPC31_CGU_FDC23_OFFSET) + +/* Dynamic fractional divider configuration (DYNFDC) registers (SYS base only) */ + +#define LPC31_CGU_DYNFDC(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC_OFFSET(n)) +#define LPC31_CGU_DYNFDC0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC0_OFFSET) +#define LPC31_CGU_DYNFDC1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC1_OFFSET) +#define LPC31_CGU_DYNFDC2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC2_OFFSET) +#define LPC31_CGU_DYNFDC3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC3_OFFSET) +#define LPC31_CGU_DYNFDC4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC4_OFFSET) +#define LPC31_CGU_DYNFDC5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC5_OFFSET) +#define LPC31_CGU_DYNFDC6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNFDC6_OFFSET) + +/* Dynamic fractional divider selection (DYNSEL) registers (SYS base only) */ + +#define LPC31_CGU_DYNSEL(n) (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL_OFFSET(n)) +#define LPC31_CGU_DYNSEL0 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL0_OFFSET) +#define LPC31_CGU_DYNSEL1 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL1_OFFSET) +#define LPC31_CGU_DYNSEL2 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL2_OFFSET) +#define LPC31_CGU_DYNSEL3 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL3_OFFSET) +#define LPC31_CGU_DYNSEL4 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL4_OFFSET) +#define LPC31_CGU_DYNSEL5 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL5_OFFSET) +#define LPC31_CGU_DYNSEL6 (LPC31_CGU_CSB_VBASE+LPC31_CGU_DYNSEL6_OFFSET) + +/* CGU configuration (virtural) register address ************************************************/ +/* Power and oscillator control */ + +#define LPC31_CGU_POWERMODE (LPC31_CGU_CFG_VBASE+LPC31_CGU_POWERMODE_OFFSET) +#define LPC31_CGU_WDBARK (LPC31_CGU_CFG_VBASE+LPC31_CGU_WDBARK_OFFSET) +#define LPC31_CGU_FFASTON (LPC31_CGU_CFG_VBASE+LPC31_CGU_FFASTON_OFFSET) +#define LPC31_CGU_FFASTBYP (LPC31_CGU_CFG_VBASE+LPC31_CGU_FFASTBYP_OFFSET) + +/* Reset control */ + +#define LPC31_CGU_SOFTRST(n) (LPC31_CGU_CFG_VBASE+LPC31_CGU_SOFTRST_OFFSET(n)) +#define LPC31_CGU_APB0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_APB0RST_OFFSET) +#define LPC31_CGU_AHB2APB0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB2APB0RST_OFFSET) +#define LPC31_CGU_APB1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_APB1RST_OFFSET) +#define LPC31_CGU_AHB2PB1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB2PB1RST_OFFSET) +#define LPC31_CGU_APB2RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_APB2RST_OFFSET) +#define LPC31_CGU_AHB2APB2RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB2APB2RST_OFFSET) +#define LPC31_CGU_APB3RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_APB3RST_OFFSET) +#define LPC31_CGU_AHB2APB3RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB2APB3RST_OFFSET) +#define LPC31_CGU_APB4RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_APB4RST_OFFSET) +#define LPC31_CGU_AHB2INTCRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB2INTCRST_OFFSET) +#define LPC31_CGU_AHB0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHB0RST_OFFSET) +#define LPC31_CGU_EBIRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_EBIRST_OFFSET) +#define LPC31_CGU_PCMAPBRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_PCMAPBRST_OFFSET) +#define LPC31_CGU_PCMCLKIPRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_PCMCLKIPRST_OFFSET) +#define LPC31_CGU_PCMRSTASYNC (LPC31_CGU_CFG_VBASE+LPC31_CGU_PCMRSTASYNC_OFFSET) +#define LPC31_CGU_TIMER0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_TIMER0RST_OFFSET) +#define LPC31_CGU_TIMER1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_TIMER1RST_OFFSET) +#define LPC31_CGU_TIMER2RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_TIMER2RST_OFFSET) +#define LPC31_CGU_TIMER3RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_TIMER3RST_OFFSET) +#define LPC31_CGU_ADCPRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_ADCPRST_OFFSET) +#define LPC31_CGU_ADCRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_ADCRST_OFFSET) +#define LPC31_CGU_PWMRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_PWMRST_OFFSET) +#define LPC31_CGU_UARTRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_UARTRST_OFFSET) +#define LPC31_CGU_I2C0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2C0RST_OFFSET) +#define LPC31_CGU_I2C1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2C1RST_OFFSET) +#define LPC31_CGU_I2SCFGRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SCFGRST_OFFSET) +#define LPC31_CGU_I2SNSOFRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SNSOFRST_OFFSET) +#define LPC31_CGU_EDGEDETRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_EDGEDETRST_OFFSET) +#define LPC31_CGU_I2STXFF0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2STXFF0RST_OFFSET) +#define LPC31_CGU_I2STXIF0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2STXIF0RST_OFFSET) +#define LPC31_CGU_I2STXFF1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2STXFF1RST_OFFSET) +#define LPC31_CGU_I2STXIF1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2STXIF1RST_OFFSET) +#define LPC31_CGU_I2SRXFF0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SRXFF0RST_OFFSET) +#define LPC31_CGU_I2SRXIF0RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SRXIF0RST_OFFSET) +#define LPC31_CGU_I2SRXFF1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SRXFF1RST_OFFSET) +#define LPC31_CGU_I2SRXIF1RST (LPC31_CGU_CFG_VBASE+LPC31_CGU_I2SRXIF1RST_OFFSET) +#define LPC31_CGU_LCDRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_LCDRST_OFFSET) +#define LPC31_CGU_SPIRSTAPB (LPC31_CGU_CFG_VBASE+LPC31_CGU_SPIRSTAPB_OFFSET) +#define LPC31_CGU_SPIRSTIP (LPC31_CGU_CFG_VBASE+LPC31_CGU_SPIRSTIP_OFFSET) +#define LPC31_CGU_DMARST (LPC31_CGU_CFG_VBASE+LPC31_CGU_DMARST_OFFSET) +#define LPC31_CGU_NANDECCRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_NANDECCRST_OFFSET) +#define LPC31_CGU_NANDCTRLRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_NANDCTRLRST_OFFSET) +#define LPC31_CGU_SDMMCRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_SDMMCRST_OFFSET) +#define LPC31_CGU_SDMMCRSTCKIN (LPC31_CGU_CFG_VBASE+LPC31_CGU_SDMMCRSTCKIN_OFFSET) +#define LPC31_CGU_USBOTGAHBRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_USBOTGAHBRST_OFFSET) +#define LPC31_CGU_REDCTLRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_REDCTLRST_OFFSET) +#define LPC31_CGU_AHBMPMCHRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHBMPMCHRST_OFFSET) +#define LPC31_CGU_AHBMPMCRFRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_AHBMPMCRFRST_OFFSET) +#define LPC31_CGU_INTCRST (LPC31_CGU_CFG_VBASE+LPC31_CGU_INTCRST_OFFSET) + +/* HP PLL controls */ + +#define LPC313x_CGU_HP0PLL (LPC31_CGU_CFG_VBASE+LPC313x_CGU_HP0PLL_OFFSET) +#define LPC313x_CGU_HP1PLL (LPC31_CGU_CFG_VBASE+LPC313x_CGU_HP1PLL_OFFSET) +#define LPC313x_CGU_HPPLL(n) ((n) ? LPC313x_CGU_HP1PLL : LPC313x_CGU_HP0PLL) + +/* HPO PLL control (audio PLL) */ + +#define LPC31_CGU_HP0FINSEL (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0FINSEL_OFFSET) +#define LPC31_CGU_HP0MDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0MDEC_OFFSET) +#define LPC31_CGU_HP0NDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0NDEC_OFFSET) +#define LPC31_CGU_HP0PDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0PDEC_OFFSET) +#define LPC31_CGU_HP0MODE (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0MODE_OFFSET) +#define LPC31_CGU_HP0STATUS (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0STATUS_OFFSET) +#define LPC31_CGU_HP0ACK (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0ACK_OFFSET) +#define LPC31_CGU_HP0REQ (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0REQ_OFFSET) +#define LPC31_CGU_HP0INSELR (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0INSELR_OFFSET) +#define LPC31_CGU_HP0INSELI (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0INSELI_OFFSET) +#define LPC31_CGU_HP0INSELP (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0INSELP_OFFSET) +#define LPC31_CGU_HP0SELR (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0SELR_OFFSET) +#define LPC31_CGU_HP0SELI (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0SELI_OFFSET) +#define LPC31_CGU_HP0SELP (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP0SELP_OFFSET) + +/* HP1 PLL control (system PLL) */ + +#define LPC31_CGU_HP1FINSEL (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1FINSEL_OFFSET) +#define LPC31_CGU_HP1MDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1MDEC_OFFSET) +#define LPC31_CGU_HP1NDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1NDEC_OFFSET) +#define LPC31_CGU_HP1PDEC (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1PDEC_OFFSET) +#define LPC31_CGU_HP1MODE (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1MODE_OFFSET) +#define LPC31_CGU_HP1STATUS (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1STATUS_OFFSET) +#define LPC31_CGU_HP1ACK (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1ACK_OFFSET) +#define LPC31_CGU_HP1REQ (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1REQ_OFFSET) +#define LPC31_CGU_HP1INSELR (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1INSELR_OFFSET) +#define LPC31_CGU_HP1INSELI (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1INSELI_OFFSET) +#define LPC31_CGU_HP1INSELP (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1INSELP_OFFSET) +#define LPC31_CGU_HP1SELR (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1SELR_OFFSET) +#define LPC31_CGU_HP1SELI (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1SELI_OFFSET) +#define LPC31_CGU_HP1SELP (LPC31_CGU_CFG_VBASE+LPC31_CGU_HP1SELP_OFFSET) + +/* CGU register bit definitions *****************************************************************/ + +/* Frequency inputs */ + +#define CGU_FREQIN_FFAST 0 /* ffast 12 MHz */ +#define CGU_FREQIN_I2SRXBCK0 1 /* I2SRX_BCK0 */ +#define CGU_FREQIN_I2SRXWS0 2 /* I2SRX_WS0 */ +#define CGU_FREQIN_I2SRXBCK1 3 /* I2SRX_BCK1 */ +#define CGU_FREQIN_I2SRXWS1 4 /* I2SRX_WS1 */ +#define CGU_FREQIN_HPPLL0 5 /* HPPLL0 (Audio/I2S PLL) */ +#define CGU_FREQIN_HPPLL1 6 /* HPPLL1 (System PLL) */ +#define CGU_NFREQIN 7 + +/* CGU clock switchbox register bit definitions *************************************************/ + +/* Switch configuration register SCR0 to SCR11, addresses 0x13004000 to 0x1300402c */ + +#define CGU_SCR_STOP (1 << 3) /* Bit 3: Forces switch in disable mode */ +#define CGU_SCR_RESET (1 << 2) /* Bit 2: Asynchronous reset of both switches */ +#define CGU_SCR_ENF2 (1 << 1) /* Bit 1: Enable side #2 of switch */ +#define CGU_SCR_ENF1 (1 << 0) /* Bit 0: Enable side #1 of switch */ + +/* Frequency select register 1 FS1_0 to FS1_11, addresses 0x13004030 to 0x1300405c, + * Frequency Select register 2 FS2_0 to FS2_11, addresses 0x13004060 to 0x1300408c + */ + +#define CGU_FS_SHIFT (0) /* Bits 0-2: Selects input frequency for either side of frequency switch */ +#define CGU_FS_MASK (7 << CGU_FS_SHIFT) +# define CGU_FS_FFAST (CGU_FREQIN_FFAST << CGU_FS_SHIFT) /* ffast 12 MHz */ +# define CGU_FS_I2SRXBCK0 (CGU_FREQIN_I2SRXBCK0 << CGU_FS_SHIFT) /* I2SRX_BCK0 */ +# define CGU_FS_I2SRXWS0 (CGU_FREQIN_I2SRXWS0 << CGU_FS_SHIFT) /* I2SRX_WS0 */ +# define CGU_FS_I2SRXBCK1 (CGU_FREQIN_I2SRXBCK1 << CGU_FS_SHIFT) /* I2SRX_BCK1 */ +# define CGU_FS_I2SRXWS1 (CGU_FREQIN_I2SRXWS1 << CGU_FS_SHIFT) /* I2SRX_WS1 */ +# define CGU_FS_HPPLL0 (CGU_FREQIN_HPPLL0 << CGU_FS_SHIFT) /* HPPLL0 (Audio/I2S PLL) */ +# define CGU_FS_HPPLL1 (CGU_FREQIN_HPPLL1 << CGU_FS_SHIFT) /* HPPLL1 (System PLL) */ + +/* Switch Status register SSR0 to SSR11, addresses 0x13004090 to 0x1300 40bc */ + +#define CGU_SSR_FS_SHIFT (2) /* Bits 2-4: Feedback of current frequency selection */ +#define CGU_SSR_FS_MASK (7 << CGU_SSR_FS_SHIFT) +# define CGU_SSR_FFAST (CGU_FREQIN_FFAST << CGU_SSR_FS_SHIFT) /* ffast 12 MHz */ +# define CGU_SSR_I2SRXBCK0 (CGU_FREQIN_I2SRXBCK0 << CGU_SSR_FS_SHIFT) /* I2SRX_BCK0 */ +# define CGU_SSR_I2SRXWS0 (CGU_FREQIN_I2SRXWS0 << CGU_SSR_FS_SHIFT) /* I2SRX_WS0 */ +# define CGU_SSR_I2SRXBCK1 (CGU_FREQIN_I2SRXBCK1 << CGU_SSR_FS_SHIFT) /* I2SRX_BCK1 */ +# define CGU_SSR_I2SRXWS1 (CGU_FREQIN_I2SRXWS1 << CGU_SSR_FS_SHIFT) /* I2SRX_WS1 */ +# define CGU_SSR_HPPLL0 (CGU_FREQIN_HPPLL0 << CGU_SSR_FS_SHIFT) /* HPPLL0 (Audio/I2S PLL) */ +# define CGU_SSR_HPPLL1 (CGU_FREQIN_HPPLL1 << CGU_SSR_FS_SHIFT) /* HPPLL1 (System PLL) */ +#define CGU_SSR_FS2STAT (1 << 1) /* Bit 1: Enable side #2 of the frequency switch */ +#define CGU_SSR_FS1STAT (1 << 0) /* Bit 0: Enable side #1 of the frequency switch */ + +/* Power Control register PCR0 to PCR91, addresses 0x130040c0 to 0x1300422c */ + +#define CGU_PCR_ENOUTEN (1 << 4) /* Bit 4: Enable clock preview signal */ +#define CGU_PCR_EXTENEN (1 << 3) /* Bit 3: Enable external enabling */ +#define CGU_PCR_WAKEEN (1 << 2) /* Bit 2: Enable central wakeup */ +#define CGU_PCR_AUTO (1 << 1) /* Bit 1: Enable wakeup and external enable */ +#define CGU_PCR_RUN (1 << 0) /* Bit 0: Enable clocks */ + +/* Power Status register PSR0 to PSR91, addresses 0x13004230 to 0x1300439c */ + +#define CGU_PSR_WAKEUP (1 << 1) /* Bit 1: Clock wakeup condition */ +#define CGU_PSR_ACTIVE (1 << 0) /* Bit 0: Indicates clock is active */ + +/* Enable Select register ESR0 to ESR88, addresses 0x130043a0 to 0x13004500 */ +/* The ESR_SEL varies according to the selected clock */ + +#define CGU_ESR_ESRSEL_SHIFT (1) /* Bits 1-n: Common shift value */ +#define CGU_ESR0_29_ESRSEL_SHIFT (1) /* Bits 1-3: Selection of fractional dividers */ +#define CGU_ESR0_29_ESRSEL_MASK (7 << CGU_ESR0_29_ESRSEL_SHIFT) +# define CGU_ESR0_29_ESRSEL_FDC0 (0 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC0 */ +# define CGU_ESR0_29_ESRSEL_FDC1 (1 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC1 */ +# define CGU_ESR0_29_ESRSEL_FDC2 (2 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC2 */ +# define CGU_ESR0_29_ESRSEL_FDC3 (3 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC3 */ +# define CGU_ESR0_29_ESRSEL_FDC4 (4 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC4 */ +# define CGU_ESR0_29_ESRSEL_FDC5 (5 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC5 */ +# define CGU_ESR0_29_ESRSEL_FDC6 (6 << CGU_ESR0_29_ESRSEL_SHIFT) /* Selects FDC6 */ + +#define CGU_ESR30_39_ESRSEL_FDC7 (0) /* Bit 1=0 selects FDC7 */ +#define CGU_ESR30_39_ESRSEL_FDC8 (1 << 1) /* Bit 1=1 selects FDC8 */ + +#define CGU_ESR40_49_ESRSEL_FDC9 (0) /* Bit 1=0 selects FDC9 */ +#define CGU_ESR40_49_ESRSEL_FDC10 (1 << 1) /* Bit 1=1 selects FDC10 */ + +#define CGU_ESR50_57_ESRSEL_SHIFT (1) /* Bits 1-3: Selection of fractional dividers */ +#define CGU_ESR50_57_ESRSEL_MASK (3 << CGU_ESR50_57_ESRSEL_SHIFT) +# define CGU_ESR50_57_ESRSEL_FDC11 (0 << CGU_ESR50_57_ESRSEL_SHIFT) /* Selects FDC11 */ +# define CGU_ESR50_57_ESRSEL_FDC12 (1 << CGU_ESR50_57_ESRSEL_SHIFT) /* Selects FDC12 */ +# define CGU_ESR50_57_ESRSEL_FDC13 (2 << CGU_ESR50_57_ESRSEL_SHIFT) /* Selects FDC13 */ + +#define CGU_ESR58_70_ESRSEL_FDC14 (0) /* Only option */ +#define CGU_ESR71_ESRSEL_FDC15 (0) /* Only option */ +#define CGU_ESR72_ESRSEL_FDC16 (0) /* Only option */ + +#define CGU_ESR73_86_ESRSEL_SHIFT (1) /* Bits 1-3: Selection of fractional dividers */ +#define CGU_ESR73_86_ESRSEL_MASK (7 << CGU_ESR73_86_ESRSEL_SHIFT) +# define CGU_ESR73_86_ESRSEL_FDC17 (0 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC17 */ +# define CGU_ESR73_86_ESRSEL_FDC18 (1 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC18 */ +# define CGU_ESR73_86_ESRSEL_FDC19 (2 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC19 */ +# define CGU_ESR73_86_ESRSEL_FDC20 (3 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC20 */ +# define CGU_ESR73_86_ESRSEL_FDC21 (4 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC21 */ +# define CGU_ESR73_86_ESRSEL_FDC22 (5 << CGU_ESR73_86_ESRSEL_SHIFT) /* Selects FDC22 */ + +#define CGU_ESR87_88_ESRSEL_FDC23 (0) /* Only option */ + +#define CGU_ESR_ESREN (1 << 0) /* Bit 0: Enable from FD selected by ESRSEL */ + +/* Base control registers 0 BCR0 to BCR7, addresses 0x13004504 to 0x13004514 */ + +#define CGU_BCR_FDRUN (1 << 0) /* Bit 0: Enable fractional dividers */ + +/* Fractional divider register 0 to 23 FDC0 to FDC23 (except FDC17) addresses 0x13004518 to 0x13004574 */ + +#define CGU_FDC_MSUB_SHIFT (11) /* Bits 11-18: Modulo subtraction value */ +#define CGU_FDC_MSUB_MASK (0x000000ff << CGU_FDC_MSUB_SHIFT) +#define CGU_FDC_MSUB_EXTEND (0xffffff00) +#define CGU_FDC_MADD_SHIFT (3) /* Bits 3-10: Modulo addition value */ +#define CGU_FDC_MADD_MASK (0x000000ff << CGU_FDC_MADD_SHIFT) +#define CGU_FDC_STRETCH (1 << 2) /* Bit 2: Enables the stretching option */ +#define CGU_FDC_RESET (1 << 1) /* Bit 1: Reset fractional divider */ +#define CGU_FDC_RUN (1 << 0) /* Bit 0: Enable fractional divider */ + +#define CGU_FDC17_MSUB_SHIFT (16) /* Bits 16-28: Modulo subtraction value */ +#define CGU_FDC17_MSUB_MASK (0x00001fff << CGU_FDC17_MSUB_SHIFT) +#define CGU_FDC17_MSUB_EXTEND (0xffffe000) +#define CGU_FDC17_MADD_SHIFT (3) /* Bits 3-15: Modulo addition value */ +#define CGU_FDC17_MADD_MASK (0x00001fff << CGU_FDC17_MADD_SHIFT) +#define CGU_FDC17_STRETCH (1 << 2) /* Bit 2: Enables the stretching option */ +#define CGU_FDC17_RESET (1 << 1) /* Bit 1: Reset fractional divider */ +#define CGU_FDC17_RUN (1 << 0) /* Bit 0: Enable fractional divider */ + +#define CGU_FDC_FIELDWIDTH 8 /* MSUB and MADD fields are 8-bits in width */ +#define CGU_FDC17_FIELDWIDTH 13 /* Exept for FDC17 which is 13-bits in width */ + +/* Dynamic Fractional Divider registers DYNFDC0 to DYNFDC6, addresses 0x13004578 to 0x13004590 */ + +#define CGU_DYNFDC_STOPAUTORST (1 << 19) /* Bit 19: Disable auto reset of fractional divider */ +#define CGU_DYNFDC_MSUB_SHIFT (11) /* Bits 11-18: Modulo subtraction value */ +#define CGU_DYNFDC_MSUB_MASK (255 << CGU_DYNFDC_MSUB_SHIFT) +#define CGU_DYNFDC_MADD_SHIFT (3) /* Bits 3-10: Modulo addition value */ +#define CGU_DYNFDC_MADD_MASK (255 << CGU_DYNFDC_MADD_SHIFT) +#define CGU_DYNFDC_STRETCH (1 << 2) /* Bit 2: Enables the stretching option */ +#define CGU_DYNFDC_ALLOW (1 << 1) /* Bit 1: Enable dynamic fractional divider */ +#define CGU_DYNFDC_RUN (1 << 0) /* Bit 0: Enable the fractional divider during low speeds */ + +/* Dynamic Fractional Divider Selection register DYNSEL0 to DYNSEL6, addresses 0x13004594 to 0x130045ac */ + +#define CGU_DYNSEL_MPMCREFRESHREQ (1 << 8) /* Bit 8: Ext SDRAM refresh can enable high speed */ +#define CGU_DYNSEL_ECCRAMBUSY (1 << 7) /* Bit 7: Hispeed mode during NAND ECC */ +#define CGU_DYNSEL_USBOTGMSTTRANS (1 << 6) /* Bit 6: USB OTG transfers can enable high speed */ +#define CGU_DYNSEL_ARM926LPDREADY (1 << 5) /* Bit 5: ARM926 data transfers can enable high-speed */ +#define CGU_DYNSEL_ARM926LPDTRANS (1 << 4) /* Bit 4: ARM926 data transfers can enable high-speed */ +#define CGU_DYNSEL_ARM926LPIREADY (1 << 3) /* Bit 3: ARM926 instr last transfers can enable high-speed */ +#define CGU_DYNSEL_ARM926LPITRANS (1 << 2) /* Bit 2: ARM926 instr transfers can enable high-speed */ +#define CGU_DYNSEL_DMAREADY (1 << 1) /* Bit 1: dma last transfers can enable high-speed */ +#define CGU_DYNSEL_DMATRANS (1 << 0) /* Bit 0: dma transfers can enable high-speed */ +#define CGU_DYNSEL_ALLBITS (0x1ff) + +/* CGU configuration register bit definitions ***************************************************/ +/* Power and oscillator control registers */ +/* Powermode register POWERMODE, address 0x13004c00 */ + +#define CGU_POWERMODE_SHIFT (0) /* Bits 0-1: Powermode */ +#define CGU_POWERMODE_MASK (3 << bb) +#define CGU_POWERMODE_NORMAL (1 << bb) /* Normal operational mode */ +#define CGU_POWERMODE_WAKEUP (3 << bb) /* Wakeup clocks disabled until wakeup event */ + +/* Watchdog Bark register WDBARK, address 0x13004c04 */ + +#define CGU_WDBARK_RESET (1 << 0) /* Bit 0: Set when a watchdog reset has occurred */ + +/* Fast Oscillator activate register FFASTON, 0x13004c08 */ + +#define CGU_FFASTON_ACTIVATE (1 << 0) /* Bit 0: Activate fast oscillator */ + +/* Fast Oscillator Bypass comparator register FFASTBYP, 0x13004c0c */ + +#define CGU_FFASTBYP_TESTMODE (1 << 0) /* Bit 0: Oscillator test mode */ + +/* Reset control registers */ + +#define CGU_SOFTRESET (1 << 0) /* Bit 0: in all of the reset control registers */ + +/* APB0_RESETN_SOFT register, address 0x13004c10 */ + +#define CGU_APB0RST_RESET (1 << 0) /* Bit 0: Reserved */ + +/* AHB_TO_APB0_PNRES_SOFT register, address 0x13004c14 */ + +#define CGU_AHB2APB0RST_RESET (1 << 0) /* Bit 0: Reserved */ + +/* APB1_RESETN_SOFT register, address 0x13004c18 */ + +#define CGU_APB1RST_RESET (1 << 0) /* Bit 0: Reset for AHB part of AHB_TO_APB1 bridge */ + +/* AHB_TO_APB1_PNRES_SOFT register, address 0x13004c1c */ + +#define CGU_AHB2PB1RST_RESET (1 << 0) /* Bit 0: Reset for APB part of AHB_TO_APB1 bridge */ + +/* APB2_RESETN_SOFT register, address 0x13004c20 */ + +#define CGU_APB2RST_RESET (1 << 0) /* Bit 0: Reset for AHB part of AHB_TO_APB2 bridge */ + +/* AHB_TO_APB2_PNRES_SOFT register, address 0x13004c24 */ + +#define CGU_AHB2APB2RST_RESET (1 << 0) /* Bit 0: Reset for APB part of AHB_TO_APB2 bridge */ + +/* APB3_RESETN_SOFT register, address 0x13004c28 */ + +#define CGU_APB3RST_RESET (1 << 0) /* Bit 0: Reset for AHB part of AHB_TO_APB3 bridge */ + +/* AHB_TO_APB3_PNRES_SOFT register, address 0x13004c2c */ + +#define CGU_AHB2APB3RST_RESET (1 << 0) /* Bit 0: Reset for APB part of AHB_TO_APB3 bridge */ + +/* APB4_RESETN_SOFT register, address 0x13004c30 */ + +#define CGU_APB4RST_RESET (1 << 0) /* Bit 0: Reset for AHB part of AHB_TO_APB4 bridge */ + +/* AHB_TO_INTC_RESETN_SOFT register, address 0x13004c34 */ + +#define CGU_AHB2INTCRST_RESET (1 << 0) /* Bit 0: Reset for AHB_TO_INTC */ + +/* AHB0_RESETN_SOFT register, address 0x13004c38 */ + +#define CGU_AHB0RST_RESET (1 << 0) /* Bit 0: Reserved */ + +/* EBI_RESETN_SOFT register, address 0x13004c2c */ + +#define CGU_EBIRST_RESET (1 << 0) /* Bit 0: Reset for EBI */ + +/* PCM_PNRES_SOFT UNIT register, address 0x13004c40 */ + +#define CGU_PCMAPBRST_RESET (1 << 0) /* Bit 0: Reset for APB domain of PCM */ + +/* PCM_RESET_N_SOFT register, address 0x13004c44 */ + +#define CGU_PCMCLKIPRST_RESET (1 << 0) /* Bit 0: Reset for synchronous clk_ip domain of PCM */ + +/* PCM_RESET_ASYNC_N_SOFT register, address 0x13004c48 */ + +#define CGU_PCMRSTASYNC_RESET (1 << 0) /* Bit 0: Reset for asynchronous clk_ip domain of PCM */ + +/* TIMER0_PNRES_SOFT register, address 0x13004c4c */ + +#define CGU_TIMER0RST_RESET (1 << 0) /* Bit 0: Reset for Timer0 */ + +/* TIMER1_PNRES_SOFT register, address 0x13004c50 */ + +#define CGU_TIMER1RST_RESET (1 << 0) /* Bit 0: Reset for Timer1 */ + +/* TIMER2_PNRES_SOFT register, address 0x13004c54 */ + +#define CGU_TIMER2RST_RESET (1 << 0) /* Bit 0: Reset for Timer2 */ + +/* TIMER3_PNRES_SOFT register, address 0x13004c58 */ + +#define CGU_TIMER3RST_RESET (1 << 0) /* Bit 0: Reset for Timer3 */ + +/* ADC_PRESETN_SOFT register, address 0x13004c5c */ + +#define CGU_ADCPRST_RESET (1 << 0) /* Bit 0: Reset for controller of 10 bit ADC Interface */ + +/* ADC_RESETN_ADC10BITS_SOFT register, address 0x1300 4c60 */ + +#define CGU_ADCRST_RESET (1 << 0) /* Bit 0: Reset for A/D converter of ADC Interface */ + +/* PWM_RESET_AN_SOFT register, address 0x13004c64 */ + +#define CGU_PWMRST_RESET (1 << 0) /* Bit 0: Reset for PWM */ + +/* UART_SYS_RST_AN_SOFT register, address 0x13004c68 */ + +#define CGU_UARTRST_RESET (1 << 0) /* Bit 0: Reset for UART/IrDA */ + +/* I2C0_PNRES_SOFT register, address 0x13004c6c */ + +#define CGU_I2C0RST_RESET (1 << 0) /* Bit 0: Reset for I2C0 */ + +/* I2C1_PNRES_SOFT register, address 0x13004c70 */ + +#define CGU_I2C1RST_RESET (1 << 0) /* Bit 0: Reset for I2C1 */ + +/* I2S_CFG_RST_N_SOFT register, address 0x13004c74 */ + +#define CGU_I2SCFGRST_RESET (1 << 0) /* Bit 0: Reset for I2S_Config */ + +/* I2S_NSOF_RST_N_SOFT register, address 0x13004c78 */ + +#define CGU_I2SNSOFRST_RESET (1 << 0) /* Bit 0: Reset for NSOF counter of I2S_CONFIG */ + +/* EDGE_DET_RST_N_SOFT register, address 0x13004c7c */ + +#define CGU_EDGEDETRST_RESET (1 << 0) /* Bit 0: Reset for Edge_det */ + +/* I2STX_FIFO_0_RST_N_SOFT register, address 0x13004c80 */ + +#define CGU_I2STXFF0RST_RESET (1 << 0) /* Bit 0: Reset for I2STX_FIFO_0 */ + +/* I2STX_IF_0_RST_N_SOFT register, address 0x13004c84 */ + +#define CGU_I2STXIF0RST_RESET (1 << 0) /* Bit 0: Reset for I2STX_IF_0 */ + +/* I2STX_FIFO_1_RST_N_SOFT register, address 0x13004c88 */ + +#define CGU_I2STXFF1RST_RESET (1 << 0) /* Bit 0: Reset for I2STX_FIFO_1 */ + +/* I2STX_IF_1_RST_N_SOFT register, address 0x13004c8c */ + +#define CGU_I2STXIF1RST_RESET (1 << 0) /* Bit 0: Reset for I2STX_IF_1 */ + +/* I2SRX_FIFO_0_RST_N_SOFT register, address 0x13004c90 */ + +#define CGU_I2SRXFF0RST_RESET (1 << 0) /* Bit 0: Reset for I2SRX_FIFO_0 */ + +/* I2SRX_IF_0_RST_N_SOFT register, address 0x13004c94 */ + +#define CGU_I2SRXIF0RST_RESET (1 << 0) /* Bit 0: Reset for I2SRX_IF_0 */ + +/* I2SRX_FIFO_1_RST_N_SOFT register, address 0x13004c98 */ + +#define CGU_I2SRXFF1RST_RESET (1 << 0) /* Bit 0: Reset for I2SRX_FIFO_1 */ + +/* I2SRX_IF_1_RST_N_SOFT register, address 0x13004c9c */ + +#define CGU_I2SRXIF1RST_RESET (1 << 0) /* Bit 0: Reset for I2SRX_IF_1 */ + +/* LCD_PNRES_SOFT register, address 0x13004cB4 */ + +#define CGU_LCDRST_RESET (1 << 0) /* Bit 0: Reset for LCD Interface */ + +/* SPI_PNRES_APB_SOFT register, address 0x13004cb8 */ + +#define CGU_SPIRSTAPB_RESET (1 << 0) /* Bit 0: Reset register for apb_clk domain of SPI */ + +/* SPI_PNRES_IP_SOFT register, address 0x13004cbc */ + +#define CGU_SPIRSTIP_RESET (1 << 0) /* Bit 0: Reset for ip_clk domain of SPI */ + +/* DMA_PNRES_SOFT register, address 0x13004cc0 */ + +#define CGU_DMARST_RESET (1 << 0) /* Bit 0: Reset for DMA */ + +/* NANDFLASH_CTRL_ECC_RESET_N_SOFT register, address 0x13004cc4 */ + +#define CGU_NANDECCRST_RESET (1 << 0) /* Bit 0: Reset for ECC clock domain of Nandflash Controller */ + +/* NANDFLASH_CTRL_AES_RESET_N_SOFT register, address 0x13004cc8 (LPC3154 only) */ + +#define CGU_NANDAECRST_RESET (1 << 0) /* Bit 0: Reset for AES clock domain of +Nandflash Controller */ + +/* NANDFLASH_CTRL_NAND_RESET_N_SOFT register, address 0x13004ccc */ + +#define CGU_NANDCTRLRST_RESET (1 << 0) /* Bit 0: Reset for Nandflash Controller */ + +/* SD_MMC_PNRES_SOFT register, address 0x13004cd4 */ + +#define CGU_SDMMCRST_RESET (1 << 0) /* Bit 0: Reset for MCI synchronous with AHB clock */ + +/* SD_MMC_NRES_CCLK_IN_SOFT register, address 0x1300 4cd8 */ + +#define CGU_SDMMCRSTCKIN_RESET (1 << 0) /* Bit 0: Reset register for MCI synchronous with IP clock */ + +/* USB_OTG_AHB_RST_N_SOFT, address 0x13004cdc */ + +#define CGU_USBOTGAHBRST_RESET (1 << 0) /* Bit 0: Reset for USB_OTG */ + +/* RED_CTL_RESET_N_SOFT, address 0x13004ce0 */ + +#define CGU_REDCTLRST_RESET (1 << 0) /* Bit 0: Reset for Redundancy Controller */ + +/* AHB_MPMC_HRESETN_SOFT, address 0x13004ce4 */ + +#define CGU_AHBMPMCHRST_RESET (1 << 0) /* Bit 0: Reset for MPMC */ + +/* AHB_MPMC_REFRESH_RESETN_SOFT, address 0x13004ce8 */ + +#define CGU_AHBMPMCRFRST_RESET (1 << 0) /* Bit 0: Reset for refresh generator used for MPMC */ + +/* INTC_RESETN_SOFT, address 0x13004cec */ + +#define CGU_INTCRST_RESET (1 << 0) /* Bit 0: Reset for Interrupt Controller */ + +/* PLL control registers */ +/* HP0 Frequency Input Select register HP0_FIN_SELECT, address 0x13004cf0, + * HP1 Frequency Input Select register HP1_FIN_SELECT, address 0x13004d28 + */ + +#define CGU_HPFINSEL_SHIFT (0) /* Bits 0-3: Select input to high HPPLL0 */ +#define CGU_HPFINSEL_MASK (15 << CGU_HPFINSEL_SHIFT) +# define CGU_HPFINSEL_FFAST (CGU_FREQIN_FFAST << CGU_HPFINSEL_SHIFT) /* ffast (12 Mhz) */ +# define CGU_HPFINSEL_I2SRXBCK0 (CGU_FREQIN_I2SRXBCK0 << CGU_HPFINSEL_SHIFT) /* I2SRX_BCK0 */ +# define CGU_HPFINSEL_I2SRXWS0 (CGU_FREQIN_I2SRXWS0 << CGU_HPFINSEL_SHIFT) /* I2SRX_WS0 */ +# define CGU_HPFINSEL_I2SRXBCK1 (CGU_FREQIN_I2SRXBCK1 << CGU_HPFINSEL_SHIFT) /* I2SRX_BCK1 */ +# define CGU_HPFINSEL_I2SRXWS1 (CGU_FREQIN_I2SRXWS1 << CGU_HPFINSEL_SHIFT) /* I2SRX_WS1 */ +# define CGU_HPFINSEL_HP0FOUT (CGU_FREQIN_HPPLL0 << CGU_HPFINSEL_SHIFT) /* HP0_FOUT */ +# define CGU_HPFINSEL_HP1FOUT (CGU_FREQIN_HPPLL1 << CGU_HPFINSEL_SHIFT) /* HP1_FOUT */ + +/* HP0 M-divider register HP0_MDEC, address 0x13004cF4, + * HP1 M-divider register HP1_MDEC, address 0x13004d2C + */ + +#define CGU_HPMDEC_SHIFT (0) /* Bits 0-16: Decoded divider ratio for M-divider */ +#define CGU_HPMDEC_MASK (0x1ffff << CGU_HPMDEC_SHIFT) + +/* HP0 N-divider register HP0_NDEC, address 0x13004cf8, + * HP1 N-divider register HP1_NDEC, address 0x13004D30 + */ + +#define CGU_HPNDEC_SHIFT (0) /* Bits 0-9: Decoded divider ratio for N-divider */ +#define CGU_HPNDEC_MASK (0x3ff << CGU_HPNDEC_SHIFT) + +/* HP0 P-divider register HP0_PDEC, address 0x13004cfc. + * HP1 P-divider register HP1_PDEC, address 0x13004D34 + */ + +#define CGU_HPPDEC_SHIFT (0) /* Bits 0-6: Decoded divider ratio for P-divider */ +#define CGU_HPPDEC_MASK (0x7F << CGU_HPPDEC_SHIFT) + +/* HP0 Mode register HP0_MODE, address 0x13004d00, + * HP1 Mode register HP1_MODE, address 0x13004d38 + */ + +#define CGU_HPMODE_BYPASS (1 << 8) /* Bit 8: Bypass mode */ +#define CGU_HPMODE_LIMUPOFF (1 << 7) /* Bit 7: Up limiter */ +#define CGU_HPMODE_BANDSEL (1 << 6) /* Bit 6: Bandwidth adjustment pin */ +#define CGU_HPMODE_FRM (1 << 5) /* Bit 5: Free Running Mode */ +#define CGU_HPMODE_DIRECTI (1 << 4) /* Bit 4: Normal operation with DIRECTO */ +#define CGU_HPMODE_DIRECTO (1 << 3) /* Bit 3: Normal operation with DIRECTI */ +#define CGU_HPMODE_PD (1 << 2) /* Bit 2: Power down mode */ +#define CGU_HPMODE_SKEWEN (1 << 1) /* Bit 1: Skew mode */ +#define CGU_HPMODE_CLKEN (1 << 0) /* Bit 0: Enable mode */ + +/* HP0 Status register HP0_STATUS, address 0x13004d04, + * HP1 Status register HP1_STATUS, address 0x13004d3c + */ + +#define CGU_HPSTATUS_FR (1 << 1) /* Bit 1: Free running detector */ +#define CGU_HPSTATUS_LOCK (1 << 0) /* Bit 0: Lock detector */ + +/* HP0 Acknowledge register HP0_ACK, address 0x13004d08, + * HP1 Acknowledge register HP1_ACK, address 0x13004d40 + */ + +#define CGU_HPACK_P (1 << 2) /* Bit 2: Post-divider ratio change acknowledge */ +#define CGU_HPACK_N (1 << 1) /* Bit 1: Pre-divider ratio change acknowledge */ +#define CGU_HPACK_M (1 << 0) /* Bit 0: Feedback divider ratio change acknowledge */ + +/* HP0 request register HP0_REQ, address 0x13004d0c, + * HP1 Request register HP1_REQ, address 0x13004d44 + */ + +#define CGU_HPREQ_P (1 << 2) /* Bit 2: Post-divider ratio change request */ +#define CGU_HPREQ_N (1 << 1) /* Bit 1: Pre-divider ratio change request */ +#define CGU_HPREQ_M (1 << 0) /* Bit 0: Feedback divider ratio change request */ + +/* HP0 Bandwith Selection register HP0_INSELR, address 0x13004d10, + * HP1 bandwith Selection register HP1_INSELR, address 0x13004d48 + */ + +#define CGU_HPINSELR_SHIFT (0) /* Bits 0-3: Pins to select the bandwidth */ +#define CGU_HPINSELR_MASK (15 << CGU_HPINSELR_SHIFT) + +/* HP0 Bandwith Selection register HP0_INSELI, address 0x13004d14, + * HP1 bandwith Selection register HP1_INSELI, address 0x13004d4c + */ + +#define CGU_HPINSELI_SHIFT (0) /* Bits 0-5: Bandwidth selection register of HP0/1 PLL */ +#define CGU_HPINSELI_MASK (63 << CGU_HPINSELI_SHIFT) + + +/* HP0 Bandwith Selection register HP0_INSELP, address 0x13004d18, + * HP1 bandwith Selection register HP1_INSELP, address 0x13004d50 + */ + +#define CGU_HPINSELP_SHIFT (0) /* Bits 0-4: Bandwidth selection register of HP0/1 PLL */ +#define CGU_HPINSELP_MASK (31 << CGU_HPINSELP_SHIFT) + +/* HP0 Bandwith Selection register HP0_SELR, address 0x13004d1c, + * HP1 bandwith Selection register HP1_SELR, address 0x13004d54 + */ + +#define CGU_HPSELR_SHIFT (0) /* Bits 0-3: Bandwidth selection register of HP0/1 PLL */ +#define CGU_HPSELR_MASK (15 << CGU_HPSELR_SHIFT) + +/* HP0 Bandwith Selection register HP0_SELI, address 0x13004d20 + * HP1 bandwith Selection register HP1_SELI, address 0x13004d58 + */ + +#define CGU_HPSELI_SHIFT (0) /* Bits 0-5: Bandwidth selection register of HP0/1 PLL */ +#define CGU_HPSELI_MASK (63 << CGU_HPSELI_SHIFT) + +/* HP0 Bandwith Selection register HP0_SELP, address 0x13004d24, + * HP1 bandwith Selection register HP1_SELP, address 0x13004d5c + */ + +#define CGU_HPSELP_SHIFT (0) /* Bits 0-4: Bandwidth selection register of HP0/1 PLL */ +#define CGU_HPIELP_MASK (31 << CGU_HPSELP_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Inline Functions + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_CGU_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_cgudrvr.h b/arch/arm/src/lpc31xx/lpc31_cgudrvr.h new file mode 100644 index 0000000000000000000000000000000000000000..47a2e3917facff4cc17035eed122866235f42b70 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_cgudrvr.h @@ -0,0 +1,807 @@ +/********************************************************************************************** + * arch/arm/src/lpc31xx/lpc31_cgudrvr.h + * + * Copyright (C) 2009-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - NXP UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - NXP lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H + +/********************************************************************************************** + * Included Files + **********************************************************************************************/ + +#include + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgu.h" + +/********************************************************************************************** + * Pre-processor Definitions + **********************************************************************************************/ + +/* Maps a valid, x, relative to a base value, b, and converts that to a bit position */ + +#define _RBIT(x,b) (1<<((x)-(b))) + +/* Clock ID ranges (see enum lpc31_clockid_e) *************************************************/ + +#define CLKID_FIRST CLKID_APB0CLK +#define CLKID_SYSBASE_FIRST CLKID_APB0CLK /* Domain 0: SYS_BASE */ +#define CLKID_SYSBASE_LAST CLKID_INTCCLK +#define _D0B(id) _RBIT(id,CLKID_SYSBASE_FIRST) + +#define CLKID_AHB0APB0_FIRST CLKID_AHB2APB0PCLK /* Domain 1: AHB0APB0_BASE */ +#define CLKID_AHB0APB0_LAST CLKID_RNGPCLK +#define _D1B(id) _RBIT(id,CLKID_AHB0APB0_FIRST) + +#define CLKID_AHB0APB1_FIRST CLKID_AHB2APB1PCLK /* Domain 2: AHB0APB1_BASE */ +#define CLKID_AHB0APB1_LAST CLKID_I2C1PCLK +#define _D2B(id) _RBIT(id,CLKID_AHB0APB1_FIRST) + +#define CLKID_AHB0APB2_FIRST CLKID_AHB2APB2PCLK /* Domain 3: AHB0APB2_BASE */ +#define CLKID_AHB0APB2_LAST CLKID_SPIPCLKGATED +#define _D3B(id) _RBIT(id,CLKID_AHB0APB2_FIRST) + +#define CLKID_AHB0APB3_FIRST CLKID_AHB2APB3PCLK /* Domain 4: AHB0APB3_BASE */ +#define CLKID_AHB0APB3_LAST CLKID_RESERVED70 +#define _D4B(id) _RBIT(id,CLKID_AHB0APB3_FIRST) + +#define CLKID_PCM_FIRST CLKID_PCMCLKIP /* Domain 5: PCM_BASE */ +#define CLKID_PCM_LAST CLKID_PCMCLKIP +#define _D5B(id) _RBIT(id,CLKID_PCM_FIRST) + +#define CLKID_UART_FIRST CLKID_UARTUCLK /* Domain 6: UART_BASE */ +#define CLKID_UART_LAST CLKID_UARTUCLK +#define _D6B(id) _RBIT(id,CLKID_UART_FIRST) + +#define CLKID_CLK1024FS_FIRST CLKID_I2SEDGEDETECTCLK /* Domain 7: CLK1024FS_BASE */ +#define CLKID_CLK1024FS_LAST CLKID_RESERVED86 +#define _D7B(id) _RBIT(id,CLKID_CLK1024FS_FIRST) + +#define CLKID_I2SRXBCK0_FIRST CLKID_I2SRXBCK0 /* Domain 8: BCK0_BASE */ +#define CLKID_I2SRXBCK0_LAST CLKID_I2SRXBCK0 +#define _D8B(id) _RBIT(id,CLKID_I2SRXBCK0_FIRST) + +#define CLKID_I2SRXBCK1_FIRST CLKID_I2SRXBCK1 /* Domain 9: BCK1_BASE */ +#define CLKID_I2SRXBCK1_LAST CLKID_I2SRXBCK1 +#define _D9B(id) _RBIT(id,CLKID_SYSBASE_FIRST) + +#define CLKID_SPI_FIRST CLKID_SPICLK /* Domain 10: SPI_BASE */ +#define CLKID_SPI_LAST CLKID_SPICLKGATED +#define _D10B(id) _RBIT(id,CLKID_I2SRXBCK1_FIRST) + +#define CLKID_SYSCLKO_FIRST CLKID_SYSCLKO /* Domain 11: SYSCLKO_BASE */ +#define CLKID_SYSCLKO_LAST CLKID_SYSCLKO +#define _D11B(id) _RBIT(id,CLKID_SYSCLKO_FIRST) +#define CLKID_LAST CLKID_SYSCLKO + +#define CGU_NDOMAINS 12 /* The number of clock domains */ +#define CLKID_INVALIDCLK -1 /* Indicates and invalid clock ID */ +#define DOMAINID_INVALID -1 /* Indicates an invalid domain ID */ +#define ESRNDX_INVALID -1 /* Indicates an invalid ESR register index */ +#define BCRNDX_INVALID -1 /* Indicates an invalid BCR register index */ + +/* There are 24 fractional dividers, indexed 0 to 23. The following definitions + * provide (1) the number of fractional dividers available for each base frequency, + * (2) start and end indices, and (3) extraction info for sub elements from the + * fractional divider configuration register + */ + +#define FRACDIV_BASE0_CNT 7 /* 7 fractional dividers available */ +#define FRACDIV_BASE0_LOW 0 /* First is index 0 */ +#define FRACDIV_BASE0_HIGH 6 /* Last is index 6 */ +#define FRACDIV_BASE0_FDIV0W 8 + +#define FRACDIV_BASE1_CNT 2 /* 2 fractional dividers available */ +#define FRACDIV_BASE1_LOW 7 /* First is index 7 */ +#define FRACDIV_BASE1_HIGH 8 /* Last is index 8 */ +#define FRACDIV_BASE1_FDIV0W 8 + +#define FRACDIV_BASE2_CNT 2 /* 2 fractional dividers available */ +#define FRACDIV_BASE2_LOW 9 /* First is index 9 */ +#define FRACDIV_BASE2_HIGH 10 /* Last is index 10 */ +#define FRACDIV_BASE2_FDIV0W 8 + +#define FRACDIV_BASE3_CNT 3 /* 3 fractional dividers available */ +#define FRACDIV_BASE3_LOW 11 /* First is index 11 */ +#define FRACDIV_BASE3_HIGH 13 /* Last is index 12 */ +#define FRACDIV_BASE3_FDIV0W 8 + +#define FRACDIV_BASE4_CNT 1 /* 1 fractional divider available */ +#define FRACDIV_BASE4_LOW 14 /* First is index 14 */ +#define FRACDIV_BASE4_HIGH 14 /* Last is index 14 */ +#define FRACDIV_BASE4_FDIV0W 8 + +#define FRACDIV_BASE5_CNT 1 /* 1 fractional divider available */ +#define FRACDIV_BASE5_LOW 15 /* First is index 15 */ +#define FRACDIV_BASE5_HIGH 15 /* Last is index 15 */ +#define FRACDIV_BASE5_FDIV0W 8 + +#define FRACDIV_BASE6_CNT 1 /* 1 fractional divider available */ +#define FRACDIV_BASE6_LOW 16 /* First is index 16 */ +#define FRACDIV_BASE6_HIGH 16 /* Last is index 16 */ +#define FRACDIV_BASE6_FDIV0W 8 + +#define FRACDIV_BASE7_CNT 6 /* 6 fractional dividers available */ +#define FRACDIV_BASE7_LOW 17 /* First is index 17 */ +#define FRACDIV_BASE7_HIGH 22 /* Last is index 22 */ +#define FRACDIV_BASE7_FDIV0W 13 + +#define FRACDIV_BASE8_CNT 0 /* No fractional divider available */ +#define FRACDIV_BASE9_CNT 0 /* No fractional divider available */ + +#define FRACDIV_BASE10_CNT 1 /* 1 fractional divider available */ +#define FRACDIV_BASE10_LOW 23 /* First is index 23 */ +#define FRACDIV_BASE10_HIGH 23 /* Last is index 23 */ +#define FRACDIV_BASE10_FDIV0W 8 + +#define FRACDIV_BASE11_CNT 0 /* No fractional divider available */ + +#define CGU_NFRACDIV 24 /* Number of fractional dividers: 0-23 */ +#define CGU_NDYNFRACDIV 7 /* Number of dynamic fractional dividers: 0-6 */ +#define FDCNDX_INVALID -1 /* Indicates an invalid fractional + * divider index */ + +/********************************************************************************************** + * Public Types + **********************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Clock domains */ + +enum lpc31_domainid_e +{ + DOMAINID_SYS = 0, /* Domain 0: SYS_BASE */ + DOMAINID_AHB0APB0, /* Domain 1: AHB0APB0_BASE */ + DOMAINID_AHB0APB1, /* Domain 2: AHB0APB1_BASE */ + DOMAINID_AHB0APB2, /* Domain 3: AHB0APB2_BASE */ + DOMAINID_AHB0APB3, /* Domain 4: AHB0APB3_BASE */ + DOMAINID_PCM, /* Domain 5: PCM_BASE */ + DOMAINID_UART, /* Domain 6: UART_BASE */ + DOMAINID_CLK1024FS, /* Domain 7: CLK1024FS_BASE */ + DOMAINID_BCK0, /* Domain 8: BCK0_BASE */ + DOMAINID_BCK1, /* Domain 9: BCK1_BASE */ + DOMAINID_SPI, /* Domain 10: SPI_BASE */ + DOMAINID_SYSCLKO /* Domain 11: SYSCLKO_BASE */ +}; + +/* Clock IDs -- These are indices must correspond to the register + * offsets in lpc31_cgu.h + */ + +enum lpc31_clockid_e +{ + /* Domain 0: SYS_BASE */ + + CLKID_APB0CLK = 0, /* 0 APB0_CLK */ + CLKID_APB1CLK, /* 1 APB1_CLK */ + CLKID_APB2CLK, /* 2 APB2_CLK */ + CLKID_APB3CLK, /* 3 APB3_CLK */ + CLKID_APB4CLK, /* 4 APB4_CLK */ + CLKID_AHB2INTCCLK, /* 5 AHB_TO_INTC_CLK */ + CLKID_AHB0CLK, /* 6 AHB0_CLK */ + CLKID_EBICLK, /* 7 EBI_CLK */ + CLKID_DMAPCLK, /* 8 DMA_PCLK */ + CLKID_DMACLKGATED, /* 9 DMA_CLK_GATED */ + CLKID_NANDFLASHS0CLK, /* 10 NANDFLASH_S0_CLK */ + CLKID_NANDFLASHECCCLK, /* 11 NANDFLASH_ECC_CLK */ + CLKID_NANDFLASHAESCLK, /* 12 NANDFLASH_AES_CLK (Reserved on LPC313x) */ + CLKID_NANDFLASHNANDCLK, /* 13 NANDFLASH_NAND_CLK */ + CLKID_NANDFLASHPCLK, /* 14 NANDFLASH_PCLK */ + CLKID_CLOCKOUT, /* 15 CLOCK_OUT */ + CLKID_ARM926CORECLK, /* 16 ARM926_CORE_CLK */ + CLKID_ARM926BUSIFCLK, /* 17 ARM926_BUSIF_CLK */ + CLKID_ARM926RETIMECLK, /* 18 ARM926_RETIME_CLK */ + CLKID_SDMMCHCLK, /* 19 SD_MMC_HCLK */ + CLKID_SDMMCCCLKIN, /* 20 SD_MMC_CCLK_IN */ + CLKID_USBOTGAHBCLK, /* 21 USB_OTG_AHB_CLK */ + CLKID_ISRAM0CLK, /* 22 ISRAM0_CLK */ + CLKID_REDCTLRSCLK, /* 23 RED_CTL_RSCLK */ + CLKID_ISRAM1CLK, /* 24 ISRAM1_CLK (LPC313x only) */ + CLKID_ISROMCLK, /* 25 ISROM_CLK */ + CLKID_MPMCCFGCLK, /* 26 MPMC_CFG_CLK */ + CLKID_MPMCCFGCLK2, /* 27 MPMC_CFG_CLK2 */ + CLKID_MPMCCFGCLK3, /* 28 MPMC_CFG_CLK3 */ + CLKID_INTCCLK, /* 29 INTC_CLK */ + + /* Domain 1: AHB0APB0_BASE */ + + CLKID_AHB2APB0PCLK, /* 30 AHB_TO_APB0_PCLK */ + CLKID_EVENTROUTERPCLK, /* 31 EVENT_ROUTER_PCLK */ + CLKID_ADCPCLK, /* 32 ADC_PCLK */ + CLKID_ADCCLK, /* 33 ADC_CLK */ + CLKID_WDOGPCLK, /* 34 WDOG_PCLK */ + CLKID_IOCONFPCLK, /* 35 IOCONF_PCLK */ + CLKID_CGUPCLK, /* 36 CGU_PCLK */ + CLKID_SYSCREGPCLK, /* 37 SYSCREG_PCLK */ + CLKID_OTPPCLK, /* 38 OTP_PCLK (Reserved on LPC313X) */ + CLKID_RNGPCLK, /* 39 RNG_PCLK */ + + /* Domain 2: AHB0APB1_BASE */ + + CLKID_AHB2APB1PCLK, /* 40 AHB_TO_APB1_PCLK */ + CLKID_TIMER0PCLK, /* 41 TIMER0_PCLK */ + CLKID_TIMER1PCLK, /* 42 TIMER1_PCLK */ + CLKID_TIMER2PCLK, /* 43 TIMER2_PCLK */ + CLKID_TIMER3PCLK, /* 44 TIMER3_PCLK */ + CLKID_PWMPCLK, /* 45 PWM_PCLK */ + CLKID_PWMPCLKREGS, /* 46 PWM_PCLK_REGS */ + CLKID_PWMCLK, /* 47 PWM_CLK */ + CLKID_I2C0PCLK, /* 48 I2C0_PCLK */ + CLKID_I2C1PCLK, /* 49 I2C1_PCLK */ + + /* Domain 3: AHB0APB2_BASE */ + + CLKID_AHB2APB2PCLK, /* 50 AHB_TO_APB2_PCLK */ + CLKID_PCMPCLK, /* 51 PCM_PCLK */ + CLKID_PCMAPBPCLK, /* 52 PCM_APB_PCLK */ + CLKID_UARTAPBCLK, /* 53 UART_APB_CLK */ + CLKID_LCDPCLK, /* 54 LCD_PCLK */ + CLKID_LCDCLK, /* 55 LCD_CLK */ + CLKID_SPIPCLK, /* 56 SPI_PCLK */ + CLKID_SPIPCLKGATED, /* 57 SPI_PCLK_GATED */ + + /* Domain 4: AHB0APB3BASE */ + CLKID_AHB2APB3PCLK, /* 58 AHB_TO_APB3_PCLK */ + CLKID_I2SCFGPCLK, /* 59 I2S_CFG_PCLK */ + CLKID_EDGEDETPCLK, /* 60 EDGE_DET_PCLK */ + CLKID_I2STXFIFO0PCLK, /* 61 I2STX_FIFO_0_PCLK */ + CLKID_I2STXIF0PCLK, /* 62 I2STX_IF_0_PCLK */ + CLKID_I2STXFIFO1PCLK, /* 63 I2STX_FIFO_1_PCLK */ + CLKID_I2STXIF1PCLK, /* 64 I2STX_IF_1_PCLK */ + CLKID_I2SRXFIFO0PCLK, /* 65 I2SRX_FIFO_0_PCLK */ + CLKID_I2SRXIF0PCLK, /* 66 I2SRX_IF_0_PCLK */ + CLKID_I2SRXFIFO1PCLK, /* 67 I2SRX_FIFO_1_PCLK */ + CLKID_I2SRXIF1PCLK, /* 68 I2SRX_IF_1_PCLK */ + CLKID_RESERVED69, /* 69 Reserved */ + CLKID_RESERVED70, /* 70 Reserved */ + + /* Domain 5: PCM_BASE */ + + CLKID_PCMCLKIP, /* 71 PCM_CLK_IP */ + + /* Domain 6: UART_BASE */ + + CLKID_UARTUCLK, /* 72 UART_U_CLK */ + + /* Domain 7: CLK1024FS_BASE */ + + CLKID_I2SEDGEDETECTCLK, /* 73 I2S_EDGE_DETECT_CLK */ + CLKID_I2STXBCK0N, /* 74 I2STX_BCK0_N */ + CLKID_I2STXWS0, /* 75 I2STX_WS0 */ + CLKID_I2STXCLK0, /* 76 I2STX_CLK0 */ + CLKID_I2STXBCK1N, /* 77 I2STX_BCK1_N */ + CLKID_I2STXWS1, /* 78 I2STX_WS1 */ + CLKID_CLK256FS, /* 79 CLK_256FS */ + CLKID_I2SRXBCK0N, /* 80 I2SRX_BCK0_N */ + CLKID_I2SRXWS0, /* 81 I2SRX_WS0 */ + CLKID_I2SRXBCK1N, /* 82 I2SRX_BCK1_N */ + CLKID_I2SRXWS1, /* 83 I2SRX_WS1 */ + CLKID_RESERVED84, /* 84 Reserved */ + CLKID_RESERVED85, /* 85 Reserved */ + CLKID_RESERVED86, /* 86 Reserved */ + + /* Domain 8: BCK0_BASE */ + + CLKID_I2SRXBCK0, /* 87 I2SRX_BCK0 */ + + /* Domain 9: BCK1_BASE */ + + CLKID_I2SRXBCK1, /* 88 I2SRX_BCK1 */ + + /* Domain 10: SPI_BASE */ + + CLKID_SPICLK, /* 89 SPI_CLK */ + CLKID_SPICLKGATED, /* 90 SPI_CLK_GATED */ + + /* Domain 11: SYSCLKO_BASE */ + + CLKID_SYSCLKO /* 91 SYSCLK_O */ +}; + +/* Indices into the CGU configuration reset control registers */ + +enum lpc31_resetid_e +{ + RESETID_APB0RST, /* 0 AHB part of AHB_TO_APB0 bridge (Reserved) */ + RESETID_AHB2APB0RST, /* 1 APB part of AHB_TO_APB0 bridge (Reserved) */ + RESETID_APB1RST, /* 2 AHB part of AHB_TO_APB1 bridge */ + RESETID_AHB2PB1RST, /* 3 APB part of AHB_TO_APB1 bridge */ + RESETID_APB2RST, /* 4 AHB part of AHB_TO_APB2 bridge */ + RESETID_AHB2APB2RST, /* 5 APB part of AHB_TO_APB2 bridge */ + RESETID_APB3RST, /* 6 AHB part of AHB_TO_APB3 bridge */ + RESETID_AHB2APB3RST, /* 7 APB part of AHB_TO_APB3 bridge */ + RESETID_APB4RST, /* 8 AHB_TO_APB4 bridge */ + RESETID_AHB2INTCRST, /* 9 AHB_TO_INTC */ + RESETID_AHB0RST, /* 10 AHB0 */ + RESETID_EBIRST, /* 11 EBI */ + RESETID_PCMAPBRST, /* 12 APB domain of PCM */ + RESETID_PCMCLKIPRST, /* 13 synchronous clk_ip domain of PCM */ + RESETID_PCMRSTASYNC, /* 14 asynchronous clk_ip domain of PCM */ + RESETID_TIMER0RST, /* 15 Timer0 */ + RESETID_TIMER1RST, /* 16 Timer1 */ + RESETID_TIMER2RST, /* 17 Timer2 */ + RESETID_TIMER3RST, /* 18 Timer3 */ + RESETID_ADCPRST, /* 19 controller of 10 bit ADC Interface */ + RESETID_ADCRST, /* 20 A/D converter of ADC Interface */ + RESETID_PWMRST, /* 21 PWM */ + RESETID_UARTRST, /* 22 UART/IrDA */ + RESETID_I2C0RST, /* 23 I2C0 */ + RESETID_I2C1RST, /* 24 I2C1 */ + RESETID_I2SCFGRST, /* 25 I2S_Config */ + RESETID_I2SNSOFRST, /* 26 NSOF counter of I2S_CONFIG */ + RESETID_EDGEDETRST, /* 27 Edge_det */ + RESETID_I2STXFF0RST, /* 28 I2STX_FIFO_0 */ + RESETID_I2STXIF0RST, /* 29 I2STX_IF_0 */ + RESETID_I2STXFF1RST, /* 30 I2STX_FIFO_1 */ + RESETID_I2STXIF1RST, /* 31 I2STX_IF_1 */ + RESETID_I2SRXFF0RST, /* 32 I2SRX_FIFO_0 */ + RESETID_I2SRXIF0RST, /* 33 I2SRX_IF_0 */ + RESETID_I2SRXFF1RST, /* 34 I2SRX_FIFO_1 */ + RESETID_I2SRXIF1RST, /* 35 I2SRX_IF_1 */ + RESETID_RESERVED40, /* 36 Reserved */ + RESETID_RESERVED41, /* 37 Reserved */ + RESETID_RESERVED42, /* 38 Reserved */ + RESETID_RESERVED43, /* 39 Reserved */ + RESETID_RESERVED44, /* 40 Reserved */ + RESETID_LCDRST, /* 41 LCD Interface */ + RESETID_SPIRSTAPB, /* 42 apb_clk domain of SPI */ + RESETID_SPIRSTIP, /* 43 ip_clk domain of SPI */ + RESETID_DMARST, /* 44 DMA */ + RESETID_NANDECCRST, /* 45 Nandflash Controller ECC clock */ + RESETID_NANDAESRST, /* 46 Nandflash Controller AES clock (reserved for lpc313x) */ + RESETID_NANDCTRLRST, /* 47 Nandflash Controller */ + RESETID_RNG, /* 48 RNG */ + RESETID_SDMMCRST, /* 49 MCI (on AHB clock) */ + RESETID_SDMMCRSTCKIN, /* 50 CI synchronous (on IP clock) */ + RESETID_USBOTGAHBRST, /* 51 USB_OTG */ + RESETID_REDCTLRST, /* 52 Redundancy Controller */ + RESETID_AHBMPMCHRST, /* 53 MPMC */ + RESETID_AHBMPMCRFRST, /* 54 refresh generator used for MPMC */ + RESETID_INTCRST, /* 55 Interrupt Controller */ +}; + +/* This structure describes one CGU fractional divider configuration */ + +struct lpc31_fdivconfig_s +{ + uint8_t stretch; /* Fractional divider stretch enable. */ + uint8_t n; /* Fractional divider nominal nominator */ + uint16_t m; /* Fractional divider nominal denominator */ +}; + +/* The structure describes the configuration of one CGU sub-domain */ + +struct lpc31_subdomainconfig_s +{ + struct lpc31_fdivconfig_s fdiv; /* Fractional divider settings */ + uint32_t clkset; /* Bitset of all clocks in the sub-domain */ +}; + +/* CGU clock initialization structure. Describes the platform-specific + * configuration of every clock domain. + */ + +struct lpc31_clkinit_s +{ + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE0_CNT]; + } domain0; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE1_CNT]; + } domain1; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE2_CNT]; + } domain2; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE3_CNT]; + } domain3; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE4_CNT]; + } domain4; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE5_CNT]; + } domain5; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE6_CNT]; + } domain6; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE7_CNT]; + } domain7; + + struct + { + uint8_t finsel; + } domain8; + + struct + { + uint8_t finsel; + } domain9; + + struct + { + uint8_t finsel; + struct lpc31_subdomainconfig_s sub[FRACDIV_BASE10_CNT]; + } domain10; + + struct + { + uint8_t finsel; + } domain11; + +#if 0 /* Dynamic fractional divider initialization not implemented */ + struct + { + uint16_t sel; + struct lpc31_fdivconfig_s cfg; + } dynfdiv[CGU_NDYNFRACDIV]; +#endif +}; + +/* This structure is used to pass PLL configuration data to + * lpc31_pllconfig() + */ + +struct lpc31_pllconfig_s +{ + uint8_t hppll; /* PLL selection: 0=HPLL0 1=HPLL1 */ + uint8_t pdec; /* PLL P-divider value: 0-0x7f */ + uint8_t selr; /* SELR bandwidth selection: 0-15 */ + uint8_t seli; /* SELI bandwidth selection: 0-63 */ + uint8_t selp; /* SELP bandwidth selection: 0-31 */ + uint16_t ndec; /* PLL N-divider value: 0-0x3ff */ + uint16_t mode; /* PLL mode: 9-bits */ + uint32_t freq; /* Frequency of the PLL in MHz */ + uint32_t finsel; /* Frequency input selection: CGU_HPFINSEL_* */ + uint32_t mdec; /* PLL M-divider value: 0-0x1ffff */ +}; + +/********************************************************************************************** + * Public Data + **********************************************************************************************/ + +/* This array is managed by the chip-specific logic and provides the programmed frequency of + * every input source + */ + +EXTERN uint32_t g_boardfreqin[CGU_NFREQIN]; + +/* This instance of the lpc31_clkinit_s structure provides the initial, default clock + * configuration for the board. Every board must provide an implementation of g_boardclks. + * This rather complex structure is used by the boot-up logic to configure initial lpc31xx + * clocking. + */ + +EXTERN const struct lpc31_clkinit_s g_boardclks; + +/********************************************************************************************** + * Inline Functions + **********************************************************************************************/ + +/********************************************************************************************** + * Name: lpc31_getbasefreq + * + * Description: + * Return the base frequency associated with a clock domain + * + **********************************************************************************************/ + +static inline uint32_t lpc31_getbasefreq(enum lpc31_domainid_e dmnid) +{ + uint32_t regval; + int ndx; + + /* Fetch the SSR register associated with this clock domain */ + + regval = getreg32(LPC31_CGU_SSR((int)dmnid)); + + /* Extract the last frequency input selection */ + + ndx = (regval & CGU_SSR_FS_MASK) >> CGU_SSR_FS_SHIFT; + + /* And return the user-supplied value for that frequency input */ + + return g_boardfreqin[ndx]; +} + +/********************************************************************************************** + * Name: lpc31_enableclock + * + * Description: + * Enable the specified clock + * + **********************************************************************************************/ + +static inline void lpc31_enableclock(enum lpc31_clockid_e clkid) +{ + uint32_t address = LPC31_CGU_PCR((int)clkid); + uint32_t regval = getreg32(address); + + regval |= CGU_PCR_RUN; + putreg32(regval, address); +} + +/********************************************************************************************** + * Name: lpc31_disableclock + * + * Description: + * Disable the specified clock + * + **********************************************************************************************/ + +static inline void lpc31_disableclock(enum lpc31_clockid_e clkid) +{ + uint32_t address = LPC31_CGU_PCR((int)clkid); + uint32_t regval = getreg32(address); + + regval &= ~CGU_PCR_RUN; + putreg32(regval, address); +} + +/********************************************************************************************** + * Public Functions + **********************************************************************************************/ + +/************************************************************************************************** + * Name: lpc31_defclk + * + * Description: + * Enable the specified clock if it is one of the default clocks needed by the board. + * + **************************************************************************************************/ + +bool lpc31_defclk(enum lpc31_clockid_e clkid); + +/************************************************************************************************** + * Name: lpc31_resetclks + * + * Description: + * Put all clocks into a known, initial state + * + **************************************************************************************************/ + +void lpc31_resetclks(void); + +/********************************************************************************************** + * Name: lpc31_clkinit + * + * Description: + * Initialize all clock domains based on board-specific clock configuration data + * + **********************************************************************************************/ + +void lpc31_clkinit(const struct lpc31_clkinit_s* cfg); + +/********************************************************************************************** + * Name: lpc31_fdivinit + * + * Description: + * Enable and configure (or disable) a fractional divider. For internal us only... see + * lpc31_setfdiv() the externally usable function. + * + **********************************************************************************************/ + +uint32_t lpc31_fdivinit(int fdcndx, const struct lpc31_fdivconfig_s *fdiv, bool enable); + +/********************************************************************************************** + * Name: lpc31_setfdiv + * + * Description: + * Set/reset subdomain frequency containing the specified clock using the provided divider + * settings + * + **********************************************************************************************/ + +void lpc31_setfdiv(enum lpc31_domainid_e dmnid, enum lpc31_clockid_e clkid, + const struct lpc31_fdivconfig_s *fdiv); + +/************************************************************************************************** + * Name: lpc31_pllconfig + * + * Description: + * Re-onfigure the PLL according to the provided selections. + * + **************************************************************************************************/ + +void lpc31_pllconfig(const struct lpc31_pllconfig_s * const cfg); + +/********************************************************************************************** + * Name: lpc31_hp0pllconfig + * + * Description: + * Configure the HP0 PLL according to the board.h default selections. + * + **********************************************************************************************/ + +void lpc31_hp0pllconfig(void); + +/********************************************************************************************** + * Name: lpc31_hp1pllconfig + * + * Description: + * Configure the HP1 PLL according to the board.h default selections. + * + **********************************************************************************************/ + +void lpc31_hp1pllconfig(void); + +/********************************************************************************************** + * Name: lpc31_softreset + * + * Description: + * Perform a soft reset on the specified module. + * + **********************************************************************************************/ + +void lpc31_softreset(enum lpc31_resetid_e resetid); + +/********************************************************************************************** + * Name: lpc31_clkdomain + * + * Description: + * Given a clock ID, return the ID of the domain in which the clock resides. + * + **********************************************************************************************/ + +enum lpc31_domainid_e lpc31_clkdomain(enum lpc31_clockid_e clkid); + +/********************************************************************************************** + * Name: lpc31_esrndx + * + * Description: + * Given a clock ID, return the index of the corresponding ESR register (or ESRNDX_INVALID + * if there is no ESR associated with this clock ID). Indexing of ESRs differs slightly + * from the clock ID: There are 92 clock IDs but only 89 ESR regisers. There are no ESR + * registers for : + * + * + * CLKID_I2SRXBCK0 Clock ID 87: I2SRX_BCK0 + * CLKID_I2SRXBCK1, Clock ID 88: I2SRX_BCK1 + * + * and + * + * CLKID_SYSCLKO Clock ID 91: SYSCLK_O + * + **********************************************************************************************/ + +int lpc31_esrndx(enum lpc31_clockid_e clkid); + +/********************************************************************************************** + * Name: lpc31_bcrndx + * + * Description: + * Only 5 of the 12 domains have an associated BCR register. This function returns the + * index to the associated BCR register (if any) or BCRNDX_INVALID otherwise. + * + **********************************************************************************************/ + +int lpc31_bcrndx(enum lpc31_domainid_e dmnid); + +/********************************************************************************************** + * Name: lpc31_fdcndx + * + * Description: + * Given a clock ID and its domain ID, return the index of the corresponding fractional + * divider register (or FDCNDX_INVALID if there is no fractional divider associated with + * this clock). + * + **********************************************************************************************/ + +int lpc31_fdcndx(enum lpc31_clockid_e clkid, enum lpc31_domainid_e dmnid); + +/********************************************************************************************** + * Name: lpc31_selectfreqin + * + * Description: + * Set the base frequency source selection for with a clock domain + * + **********************************************************************************************/ + +void lpc31_selectfreqin(enum lpc31_domainid_e dmnid, uint32_t finsel); + +/********************************************************************************************** + * Name: lpc31_clkfreq + * + * Description: + * Given a clock ID and its domain ID, return the frequency of the clock. + * + **********************************************************************************************/ + +uint32_t lpc31_clkfreq(enum lpc31_clockid_e clkid, enum lpc31_domainid_e dmnid); + +/********************************************************************************************** + * Name: lpc31_enableexten + * + * Description: + * Enable external enabling for the specified possible clocks. + * + **********************************************************************************************/ + +void lpc31_enableexten(enum lpc31_clockid_e clkid); + +/********************************************************************************************** + * Name: lpc31_disableexten + * + * Description: + * Disable external enabling for the specified possible clocks. + * + **********************************************************************************************/ + +void lpc31_disableexten(enum lpc31_clockid_e clkid); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_clkdomain.c b/arch/arm/src/lpc31xx/lpc31_clkdomain.c new file mode 100644 index 0000000000000000000000000000000000000000..cdb2fc9ca7d8c0d4713bbd072bd1a19a92bc124d --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_clkdomain.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_clkdomain.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_clkdomain + * + * Description: + * Given a clock ID, return the ID of the domain in which the clock + * resides. + * + ****************************************************************************/ + +enum lpc31_domainid_e lpc31_clkdomain(enum lpc31_clockid_e clkid) +{ + if (clkid <= CLKID_SYSBASE_LAST) /* Domain 0: SYS_BASE */ + { + return DOMAINID_SYS; + } + else if (clkid <= CLKID_AHB0APB0_LAST) /* Domain 1: AHB0APB0_BASE */ + { + return DOMAINID_AHB0APB0; + } + else if (clkid <= CLKID_AHB0APB1_LAST) /* Domain 2: AHB0APB1_BASE */ + { + return DOMAINID_AHB0APB1; + } + else if (clkid <= CLKID_AHB0APB2_LAST) /* Domain 3: AHB0APB2_BASE */ + { + return DOMAINID_AHB0APB2; + } + else if (clkid <= CLKID_AHB0APB3_LAST) /* Domain 4: AHB0APB3_BASE */ + { + return DOMAINID_AHB0APB3; + } + else if (clkid <= CLKID_PCM_LAST) /* Domain 5: PCM_BASE */ + { + return DOMAINID_PCM; + } + else if (clkid <= CLKID_UART_LAST) /* Domain 6: UART_BASE */ + { + return DOMAINID_UART; + } + else if (clkid <= CLKID_CLK1024FS_LAST) /* Domain 7: CLK1024FS_BASE */ + { + return DOMAINID_CLK1024FS; + } + else if (clkid <= CLKID_I2SRXBCK0_LAST) /* Domain 8: BCK0_BASE */ + { + return DOMAINID_BCK0; + } + else if (clkid <= CLKID_I2SRXBCK1_LAST) /* Domain 9: BCK1_BASE */ + { + return DOMAINID_BCK1; + } + else if (clkid <= CLKID_SPI_LAST) /* Domain 10: SPI_BASE */ + { + return DOMAINID_SPI; + } + else /* if (clkid <= CLKID_SYSCLKO_LAST) */ /* Domain 11: SYSCLKO_BASE */ + { + return DOMAINID_SYSCLKO; + } +} diff --git a/arch/arm/src/lpc31xx/lpc31_clkexten.c b/arch/arm/src/lpc31xx/lpc31_clkexten.c new file mode 100644 index 0000000000000000000000000000000000000000..770bfb6a85cc3dc45588cf4801063f272c9fc3e5 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_clkexten.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_exten.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_enableexten + * + * Description: + * Enable external enabling for the specified possible clocks. + * + ****************************************************************************/ + +void lpc31_enableexten(enum lpc31_clockid_e clkid) +{ + uint32_t regaddr; + uint32_t regval; + + switch (clkid) + { + case CLKID_DMACLKGATED: /* 9 DMA_CLK_GATED */ + case CLKID_EVENTROUTERPCLK: /* 31 EVENT_ROUTER_PCLK */ + case CLKID_ADCPCLK: /* 32 ADC_PCLK */ + case CLKID_IOCONFPCLK: /* 35 IOCONF_PCLK */ + case CLKID_CGUPCLK: /* 36 CGU_PCLK */ + case CLKID_SYSCREGPCLK: /* 37 SYSCREG_PCLK */ + case CLKID_OTPPCLK: /* 38 OTP_PCLK (Reserved on LPC313X) */ + case CLKID_PWMPCLKREGS: /* 46 PWM_PCLK_REGS */ + case CLKID_PCMAPBPCLK: /* 52 PCM_APB_PCLK */ + case CLKID_SPIPCLKGATED: /* 57 SPI_PCLK_GATED */ + case CLKID_SPICLKGATED: /* 90 SPI_CLK_GATED */ + case CLKID_PCMCLKIP: /* 71 PCM_CLK_IP */ + regaddr = LPC31_CGU_PCR(clkid); + regval = getreg32(regaddr); + regval |= CGU_PCR_EXTENEN; + putreg32(regval, regaddr); + break; + + /* Otherwise, force disable for the clocks. NOTE that a larger set will + * be disabled than will be enabled. + */ + + default: + lpc31_disableexten(clkid); + break; + } +} + +/**************************************************************************** + * Name: lpc31_disableexten + * + * Description: + * Disable external enabling for the specified possible clocks. + * + ****************************************************************************/ + +void lpc31_disableexten(enum lpc31_clockid_e clkid) +{ + uint32_t regaddr; + uint32_t regval; + + switch (clkid) + { + case CLKID_DMACLKGATED: /* 9 DMA_CLK_GATED */ + case CLKID_EVENTROUTERPCLK: /* 31 EVENT_ROUTER_PCLK */ + case CLKID_ADCPCLK: /* 32 ADC_PCLK */ + case CLKID_WDOGPCLK: /* 34 WDOG_PCLK */ + case CLKID_IOCONFPCLK: /* 35 IOCONF_PCLK */ + case CLKID_CGUPCLK: /* 36 CGU_PCLK */ + case CLKID_SYSCREGPCLK: /* 37 SYSCREG_PCLK */ + case CLKID_OTPPCLK: /* 38 OTP_PCLK (Reserved on LPC313X) */ + case CLKID_PWMPCLKREGS: /* 46 PWM_PCLK_REGS */ + case CLKID_I2C0PCLK: /* 48 I2C0_PCLK */ + case CLKID_I2C1PCLK: /* 49 I2C1_PCLK */ + case CLKID_PCMAPBPCLK: /* 52 PCM_APB_PCLK */ + case CLKID_UARTAPBCLK: /* 53 UART_APB_CLK */ + case CLKID_SPIPCLKGATED: /* 57 SPI_PCLK_GATED */ + case CLKID_SPICLKGATED: /* 90 SPI_CLK_GATED */ + case CLKID_PCMCLKIP: /* 71 PCM_CLK_IP */ + case CLKID_LCDPCLK: /* 54 LCD_PCLK */ + regaddr = LPC31_CGU_PCR(clkid); + regval = getreg32(regaddr); + regval &= ~CGU_PCR_EXTENEN; + putreg32(regval, regaddr); + break; + + default: + break; + } +} diff --git a/arch/arm/src/lpc31xx/lpc31_clkfreq.c b/arch/arm/src/lpc31xx/lpc31_clkfreq.c new file mode 100644 index 0000000000000000000000000000000000000000..0273bca72be40c63c2bac9d374fd098c34653b0d --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_clkfreq.c @@ -0,0 +1,176 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_clkfreq.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_fdcndx + * + * Description: + * Given a clock ID and its domain ID, return the frequency of the + * clock. + * + ****************************************************************************/ + +uint32_t lpc31_clkfreq(enum lpc31_clockid_e clkid, + enum lpc31_domainid_e dmnid) +{ + uint32_t freq = 0; + uint32_t fdcndx; + uint32_t regval; + + /* Get then fractional divider register index for this clock */ + + fdcndx = lpc31_fdcndx(clkid, dmnid); + + /* Get base frequency for the domain */ + + freq = lpc31_getbasefreq(dmnid); + + /* If there is no fractional divider associated with the clodk, then the + * connection is directo and we just return the base frequency. + */ + + if (fdcndx == FDCNDX_INVALID) + { + return freq; + } + + /* Read fractional divider control (FDC) register value and double check that + * it is enabled (not necessary since lpc31_fdcndx() also does this check + */ + + regval = getreg32(LPC31_CGU_FDC(fdcndx)); + if ((regval & CGU_ESR_ESREN) != 0) + { + int32_t msub; + int32_t madd; + int32_t n; + int32_t m; + + /* Yes, extract modulo subtraction and addition values, msub and madd. + * Fractional divider 17 is a special case because its msub and madd + * fields have greater range. + */ + + if (fdcndx == 17) + { + /* Range is 0-0x1fff for both */ + + msub = ((regval & CGU_FDC17_MSUB_MASK) >> CGU_FDC17_MSUB_SHIFT) | CGU_FDC17_MSUB_EXTEND; + madd = (regval & CGU_FDC17_MADD_MASK) >> CGU_FDC17_MADD_SHIFT; + } + else + { + /* Range is 0-255 for both */ + + msub = ((regval & CGU_FDC_MSUB_MASK) >> CGU_FDC_MSUB_SHIFT) | CGU_FDC_MSUB_EXTEND; + madd = (regval & CGU_FDC_MADD_MASK) >> CGU_FDC_MADD_SHIFT; + } + + /* Handle a corner case that would result in an infinite loop below */ + + if (msub == 0 && madd == 0) + { + return 0; + } + + /* Reduce to the greatest common power-of-2 denominator. To minimize + * power consumption, the lpc313x user manual recommends that madd and msub + * be shifted right to have as many trailing zero's as possible. The + * following undoes that shift. + */ + + while ((msub & 1) == 0 && (madd & 1) == 0) + { + madd = madd >> 1; + msub = msub >> 1; + } + + /* Then compute n and m values: + * + * fout = n/m * fin + * + * where + * + * madd = m - n + * msub = -n + */ + + n = -msub; + m = madd + n; + + /* Check that both m and n are non-zero values */ + + if ((n == 0) || (m == 0)) + { + return 0; + } + + /* Finally, calculate the frequency based on m and n values */ + + freq = (freq * n) / m ; + } + + return freq; +} diff --git a/arch/arm/src/lpc31xx/lpc31_clkinit.c b/arch/arm/src/lpc31xx/lpc31_clkinit.c new file mode 100644 index 0000000000000000000000000000000000000000..39bab98db31e5d0984b5f71678e47b86e97f9efb --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_clkinit.c @@ -0,0 +1,298 @@ +/************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_clkinit.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgu.h" +#include "lpc31_cgudrvr.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* This structure describes the configuration of one domain */ + +struct lpc31_domainconfig_s +{ + enum lpc31_domainid_e dmnid; /* Domain ID */ + uint32_t finsel; /* Frequency input selection */ + uint32_t clk1; /* ID of first clock in the domain */ + uint32_t nclks; /* Number of clocks in the domain */ + uint32_t fdiv1; /* First frequency divider in the domain */ + uint32_t nfdiv; /* Number of frequency dividers in the domain */ + const struct lpc31_subdomainconfig_s *sub; /* Sub=domain array */ +}; + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_domaininit + * + * Description: + * Initialize one clock domain based on board-specific clock configuration data + * + ************************************************************************************/ + +static void lpc31_domaininit(struct lpc31_domainconfig_s *dmn) +{ + const struct lpc31_subdomainconfig_s * sub = dmn->sub; + uint32_t fdivcfg; + uint32_t regaddr; + uint32_t regval; + int fdndx; + int clkndx; + int bcrndx = lpc31_bcrndx(dmn->dmnid); + int esrndx; + + if (bcrndx != BCRNDX_INVALID) + { + /* Disable BCR for domain */ + + regaddr = LPC31_CGU_BCR(bcrndx); + putreg32(0, regaddr); + } + + /* Configure the fractional dividers in this domain */ + + for (fdndx = 0; fdndx < dmn->nfdiv; fdndx++, sub++) + { + /* Set fractional divider confiruation but don't enable it yet */ + + fdivcfg = lpc31_fdivinit(fdndx + dmn->fdiv1, &sub->fdiv, false); + + /* Enable frac divider only if it has valid settings */ + + if (fdivcfg != 0) + { + /* Select the fractional dividir for each clock in this + * sub domain. + */ + + for (clkndx = 0; clkndx <= dmn->nclks; clkndx++) + { + /* Does this clock have an ESR register? */ + + esrndx = lpc31_esrndx((enum lpc31_clockid_e)(clkndx + dmn->clk1)); + if (esrndx != ESRNDX_INVALID) + { + /* Yes.. Check if this clock belongs to this sub-domain */ + + if (sub->clkset & (1 << clkndx)) + { + /* Yes.. configure the clock to use this fractional divider */ + + regaddr = LPC31_CGU_ESR(esrndx); + putreg32((fdndx << CGU_ESR_ESRSEL_SHIFT) | CGU_ESR_ESREN, regaddr); + } + } + } + + /* Enable the fractional divider */ + + regaddr = LPC31_CGU_FDC(fdndx + dmn->fdiv1); + regval = getreg32(regaddr); + regval |= CGU_FDC_RUN; + putreg32(regval, regaddr); + } + } + + if (bcrndx != BCRNDX_INVALID) + { + /* Enable the BCR for domain */ + + regaddr = LPC31_CGU_BCR(bcrndx); + putreg32(CGU_BCR_FDRUN, regaddr); + } + + /* Select input base clock for domain */ + + lpc31_selectfreqin(dmn->dmnid, dmn->finsel); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_clkinit + * + * Description: + * Initialize all clock domains based on board-specific clock configuration data + * + ************************************************************************************/ + +void lpc31_clkinit(const struct lpc31_clkinit_s *cfg) +{ + struct lpc31_domainconfig_s domain; + + /* Reset all clocks and connect them to FFAST */ + + lpc31_resetclks(); + + /* Initialize Domain0 = SYS_BASE clocks */ + + domain.dmnid = DOMAINID_SYS; + domain.finsel = cfg->domain0.finsel; + domain.clk1 = CLKID_SYSBASE_FIRST; + domain.nclks = (CLKID_SYSBASE_LAST - CLKID_SYSBASE_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE0_LOW; + domain.nfdiv = FRACDIV_BASE0_CNT; + domain.sub = cfg->domain0.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain1 = AHB0APB0_BASE clocks */ + + domain.dmnid = DOMAINID_AHB0APB0; + domain.finsel = cfg->domain1.finsel; + domain.clk1 = CLKID_AHB0APB0_FIRST; + domain.nclks = (CLKID_AHB0APB0_LAST - CLKID_AHB0APB0_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE1_LOW; + domain.nfdiv = FRACDIV_BASE1_CNT; + domain.sub = cfg->domain1.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain2 = AHB0APB1_BASE clocks */ + + domain.dmnid = DOMAINID_AHB0APB1; + domain.finsel = cfg->domain2.finsel; + domain.clk1 = CLKID_AHB0APB1_FIRST; + domain.nclks = (CLKID_AHB0APB1_LAST - CLKID_AHB0APB1_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE2_LOW; + domain.nfdiv = FRACDIV_BASE2_CNT; + domain.sub = cfg->domain2.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain3 = AHB0APB2_BASE clocks */ + + domain.dmnid = DOMAINID_AHB0APB2; + domain.finsel = cfg->domain3.finsel; + domain.clk1 = CLKID_AHB0APB2_FIRST; + domain.nclks = (CLKID_AHB0APB2_LAST - CLKID_AHB0APB2_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE3_LOW; + domain.nfdiv = FRACDIV_BASE3_CNT; + domain.sub = cfg->domain3.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain4 = AHB0APB3_BASE clocks */ + + domain.dmnid = DOMAINID_AHB0APB3; + domain.finsel = cfg->domain4.finsel; + domain.clk1 = CLKID_AHB0APB3_FIRST; + domain.nclks = (CLKID_AHB0APB3_LAST - CLKID_AHB0APB3_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE4_LOW; + domain.nfdiv = FRACDIV_BASE4_CNT; + domain.sub = cfg->domain4.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain5 = PCM_BASE clocks */ + + domain.dmnid = DOMAINID_PCM; + domain.finsel = cfg->domain5.finsel; + domain.clk1 = CLKID_PCM_FIRST; + domain.nclks = 1; + domain.fdiv1 = FRACDIV_BASE5_LOW; + domain.nfdiv = FRACDIV_BASE5_CNT; + domain.sub = cfg->domain5.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain6 = UART_BASE clocks */ + + domain.dmnid = DOMAINID_UART; + domain.finsel = cfg->domain6.finsel; + domain.clk1 = CLKID_UART_FIRST; + domain.nclks = 1; + domain.fdiv1 = FRACDIV_BASE6_LOW; + domain.nfdiv = FRACDIV_BASE6_CNT; + domain.sub = cfg->domain6.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain7 = CLK1024FS_BASE clocks */ + + domain.dmnid = DOMAINID_CLK1024FS; + domain.finsel = cfg->domain7.finsel; + domain.clk1 = CLKID_CLK1024FS_FIRST; + domain.nclks = (CLKID_CLK1024FS_LAST - CLKID_CLK1024FS_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE7_LOW; + domain.nfdiv = FRACDIV_BASE7_CNT; + domain.sub = cfg->domain7.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain8 = I2SRX_BCK0_BASE clocks */ + + lpc31_selectfreqin(DOMAINID_BCK0, cfg->domain8.finsel); + + /* Initialize Domain9 = I2SRX_BCK1_BASE clocks */ + + lpc31_selectfreqin(DOMAINID_BCK1, cfg->domain9.finsel); + + /* Initialize Domain10 = SPI_BASE clocks */ + + domain.dmnid = DOMAINID_SPI; + domain.finsel = cfg->domain10.finsel; + domain.clk1 = CLKID_SPI_FIRST; + domain.nclks = (CLKID_SPI_LAST - CLKID_SPI_FIRST) + 1; + domain.fdiv1 = FRACDIV_BASE10_LOW; + domain.nfdiv = FRACDIV_BASE10_CNT; + domain.sub = cfg->domain10.sub; + lpc31_domaininit(&domain); + + /* Initialize Domain11 = SYSCLK_O_BASE clocks */ + + lpc31_selectfreqin(DOMAINID_SYSCLKO, cfg->domain11.finsel); + + /* Initialize Dynamic fractional dividers -- to be provided */ +} diff --git a/arch/arm/src/lpc31xx/lpc31_decodeirq.c b/arch/arm/src/lpc31xx/lpc31_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..9cfcd3f44353ad25f65f716c4265b823d89e7134 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_decodeirq.c @@ -0,0 +1,156 @@ +/******************************************************************************** + * arch/arm/src/lpc31xx/lpc31_decodeirq.c + * + * Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "up_internal.h" +#include "group/group.h" + +#include "lpc31_intc.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + int index; + int irq; + + /* Read the IRQ vector status register. Bits 3-10 provide the IRQ number + * of the interrupt (the TABLE_ADDR was initialized to zero, so the + * following masking should be unnecessary) + */ + + index = getreg32(LPC31_INTC_VECTOR0) & INTC_VECTOR_INDEX_MASK; + if (index != 0) + { + /* Shift the index so that the range of IRQ numbers are in bits 0-7 (values + * 1-127) and back off the IRQ number by 1 so that the numbering is zero-based + */ + + irq = (index >> INTC_VECTOR_INDEX_SHIFT) -1; + + /* Verify that the resulting IRQ number is valid */ + + if ((unsigned)irq < NR_IRQS) + { + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(CURRENT_REGS == NULL); + CURRENT_REGS = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * CURRENT_REGS will have a different value than it did on entry. + * If an interrupt level context switch has occurred, then restore + * the floating point state and the establish the correct address + * environment before returning from the interrupt. + */ + + if (regs != CURRENT_REGS) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)CURRENT_REGS); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + /* Set CURRENT_REGS to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + CURRENT_REGS = NULL; + } + } +#endif +} diff --git a/arch/arm/src/lpc31xx/lpc31_defclk.c b/arch/arm/src/lpc31xx/lpc31_defclk.c new file mode 100644 index 0000000000000000000000000000000000000000..4670253f4ec8575e47f90bc29f7d048175d29aa3 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_defclk.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_defclk.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_defclk + * + * Description: + * Enable the specified clock if it is one of the default clocks needed + * by the board. + * + ****************************************************************************/ + +bool lpc31_defclk(enum lpc31_clockid_e clkid) +{ + + uint32_t regaddr; + uint32_t regval; + bool enable; + + /* Check if this clock should be enabled. This is determined by + * 3 bitsets provided by board-specific logic in board/board.h. + */ + + if ((int)clkid < 32) + { + enable = ((BOARD_CLKS_0_31 & (1 << (int)clkid)) != 0); + } + else if ((int)clkid < 64) + { + enable = ((BOARD_CLKS_32_63 & (1 << ((int)clkid - 32))) != 0); + } + else + { + enable = ((BOARD_CLKS_64_92 & (1 << ((int)clkid - 64))) != 0); + } + + /* Then set/clear the RUN bit in the PCR register for this clock + * accordingly. + */ + + regaddr = LPC31_CGU_PCR((int)clkid); + regval = getreg32(regaddr); + if (enable) + { + regval |= CGU_PCR_RUN; + } + else + { + regval &= ~CGU_PCR_RUN; + } + putreg32(regval, regaddr); + return enable; +} + diff --git a/arch/arm/src/lpc31xx/lpc31_dma.h b/arch/arm/src/lpc31xx/lpc31_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..8bfac39d3c56930606c9c3559b095aa83d846aad --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_dma.h @@ -0,0 +1,425 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_dma.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_DMA_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_DMA_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* DMA register base address offset into the APB4 domain ****************************************/ + +#define LPC31_DMA_VBASE (LPC31_APB4_VADDR+LPC31_APB4_DMA_OFFSET) +#define LPC31_DMA_PBASE (LPC31_APB4_PADDR+LPC31_APB4_DMA_OFFSET) + +/* DMA channel offsets (with respect to the DMA register base address) **************************/ + +#define LPC31_DMACHAN_OFFSET(n) ((n)*0x020) +#define LPC31_DMACHAN0_OFFSET 0x000 +#define LPC31_DMACHAN1_OFFSET 0x020 +#define LPC31_DMACHAN2_OFFSET 0x040 +#define LPC31_DMACHAN3_OFFSET 0x060 +#define LPC31_DMACHAN4_OFFSET 0x080 +#define LPC31_DMACHAN5_OFFSET 0x0a0 +#define LPC31_DMACHAN6_OFFSET 0x0c0 +#define LPC31_DMACHAN7_OFFSET 0x0e0 +#define LPC31_DMACHAN8_OFFSET 0x100 +#define LPC31_DMACHAN9_OFFSET 0x120 +#define LPC31_DMACHAN10_OFFSET 0x140 +#define LPC31_DMACHAN11_OFFSET 0x160 + +#define LPC31_DMACHAN_ALT_OFFSET(n) (0x200+((n)*0x010)) +#define LPC31_DMACHAN0_ALT_OFFSET 0x200 +#define LPC31_DMACHAN1_ALT_OFFSET 0x210 +#define LPC31_DMACHAN2_ALT_OFFSET 0x220 +#define LPC31_DMACHAN3_ALT_OFFSET 0x230 +#define LPC31_DMACHAN4_ALT_OFFSET 0x240 +#define LPC31_DMACHAN5_ALT_OFFSET 0x250 +#define LPC31_DMACHAN6_ALT_OFFSET 0x260 +#define LPC31_DMACHAN7_ALT_OFFSET 0x270 +#define LPC31_DMACHAN8_ALT_OFFSET 0x280 +#define LPC31_DMACHAN9_ALT_OFFSET 0x290 +#define LPC31_DMACHAN10_ALT_OFFSET 0x2a0 +#define LPC31_DMACHAN11_ALT_OFFSET 0x2b0 + +/* DMA channel virtual base addresses ***********************************************************/ + +#define LPC31_DMACHAN_VBASE(n) (LPC31_DMA_VBASE+LPC31_DMACHAN_OFFSET(n)) +#define LPC31_DMACHAN0_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN0_OFFSET) +#define LPC31_DMACHAN1_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN1_OFFSET) +#define LPC31_DMACHAN2_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN2_OFFSET) +#define LPC31_DMACHAN3_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN3_OFFSET) +#define LPC31_DMACHAN4_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN4_OFFSET) +#define LPC31_DMACHAN5_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN5_OFFSET) +#define LPC31_DMACHAN6_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN6_OFFSET) +#define LPC31_DMACHAN7_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN7_OFFSET) +#define LPC31_DMACHAN8_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN8_OFFSET) +#define LPC31_DMACHAN9_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN9_OFFSET) +#define LPC31_DMACHAN10_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN10_OFFSET) +#define LPC31_DMACHAN11_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN11_OFFSET) + +#define LPC31_DMACHAN_ALT_VBASE(n) (LPC31_DMA_VBASE+LPC31_DMACHAN_ALT_OFFSET(n)) +#define LPC31_DMACHAN0_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN0_ALT_OFFSET) +#define LPC31_DMACHAN1_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN1_ALT_OFFSET) +#define LPC31_DMACHAN2_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN2_ALT_OFFSET) +#define LPC31_DMACHAN3_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN3_ALT_OFFSET) +#define LPC31_DMACHAN4_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN4_ALT_OFFSET) +#define LPC31_DMACHAN5_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN5_ALT_OFFSET) +#define LPC31_DMACHAN6_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN6_ALT_OFFSET) +#define LPC31_DMACHAN7_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN7_ALT_OFFSET) +#define LPC31_DMACHAN8_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN8_ALT_OFFSET) +#define LPC31_DMACHAN9_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN9_ALT_OFFSET) +#define LPC31_DMACHAN10_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN10_ALT_OFFSET) +#define LPC31_DMACHAN11_VBASE (LPC31_DMA_VBASE+LPC31_DMACHAN11_ALT_OFFSET) + +/* DMA channel register offsets (with respect to the DMA channel register base) *****************/ + +#define LPC31_DMACHAN_SRCADDR_OFFSET 0x000 /* Source address register of DMA channel */ +#define LPC31_DMACHAN_DESTADDR_OFFSET 0X004 /* Destination address register of DMA channel */ +#define LPC31_DMACHAN_XFERLEN_OFFSET 0X008 /* Transfer length register for DMA channel */ +#define LPC31_DMACHAN_CONFIG_OFFSET 0x00c /* Configuration register for DMA channel */ +#define LPC31_DMACHAN_ENABLE_OFFSET 0x010 /* Enable register for DMA channel */ +#define LPC31_DMACHAN_XFERCOUNT_OFFSET 0x01c /* Transfer counter register for DMA channel */ + +/* DMA global register offsets (with respect to the DMA register base) *************************/ + +#define LPC31_DMA_ALTENABLE_OFFSET 0x400 /* Alternative enable register */ +#define LPC31_DMA_IRQSTATUSCLR_OFFSET 0x404 /* IRQ status clear register */ +#define LPC31_DMA_IRQMASK_OFFSET 0x408 /* IRQ mask register */ +#define LPC31_DMA_TESTSTATUS_OFFSET 0x40c /* Test FIFO response status register */ +#define LPC31_DMA_SOFTINT_OFFSET 0x410 /* Software interrupt register */ + +/* DMA channel register (virtual) addresses *****************************************************/ + +#define LPC31_DMACHAN_SRCADDR(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN_DESTADDR(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN_XFERLEN(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN_CONFIG(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN_ENABLE(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN_XFERCOUNT(n) (LPC31_DMACHAN_VBASE(n)+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN0_SRCADDR (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN0_DESTADDR (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN0_XFERLEN (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN0_CONFIG (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN0_ENABLE (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN0_XFERCOUNT (LPC31_DMACHAN0_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN1_SRCADDR (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN1_DESTADDR (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN1_XFERLEN (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN1_CONFIG (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN1_ENABLE (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN1_XFERCOUNT (LPC31_DMACHAN1_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN2_SRCADDR (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN2_DESTADDR (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN2_XFERLEN (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN2_CONFIG (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN2_ENABLE (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN2_XFERCOUNT (LPC31_DMACHAN2_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN3_SRCADDR (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN3_DESTADDR (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN3_XFERLEN (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN3_CONFIG (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN3_ENABLE (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN3_XFERCOUNT (LPC31_DMACHAN3_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN4_SRCADDR (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN4_DESTADDR (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN4_XFERLEN (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN4_CONFIG (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN4_ENABLE (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN4_XFERCOUNT (LPC31_DMACHAN4_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN5_SRCADDR (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN5_DESTADDR (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN5_XFERLEN (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN5_CONFIG (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN5_ENABLE (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN5_XFERCOUNT (LPC31_DMACHAN5_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN6_SRCADDR (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN6_DESTADDR (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN6_XFERLEN (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN6_CONFIG (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN6_ENABLE (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN6_XFERCOUNT (LPC31_DMACHAN6_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN7_SRCADDR (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN7_DESTADDR (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN7_XFERLEN (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN7_CONFIG (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN7_ENABLE (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN7_XFERCOUNT (LPC31_DMACHAN7_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET)7 + +#define LPC31_DMACHAN8_SRCADDR (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN8_DESTADDR (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN8_XFERLEN (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN8_CONFIG (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN8_ENABLE (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN8_XFERCOUNT (LPC31_DMACHAN8_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN9_SRCADDR (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN9_DESTADDR (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN9_XFERLEN (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN9_CONFIG (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN9_ENABLE (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN9_XFERCOUNT (LPC31_DMACHAN9_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN10_SRCADDR (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN10_DESTADDR (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN10_XFERLEN (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN10_CONFIG (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN10_ENABLE (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN10_XFERCOUNT (LPC31_DMACHAN10_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN11_SRCADDR (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN11_DESTADDR (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN11_XFERLEN (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN11_CONFIG (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) +#define LPC31_DMACHAN11_ENABLE (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_ENABLE_OFFSET) +#define LPC31_DMACHAN11_XFERCOUNT (LPC31_DMACHAN11_VBASE+LPC31_DMACHAN_XFERCOUNT_OFFSET) + +#define LPC31_DMACHAN_ALT_SRCADDR(n) (LPC31_DMACHAN_ALT_VBASE(n)+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN_ALT_DESTADDR(n) (LPC31_DMACHAN_ALT_VBASE(n)+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN_ALT_XFERLEN(n) (LPC31_DMACHAN_ALT_VBASE(n)+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN_ALT_CONFIG(n) (LPC31_DMACHAN_ALT_VBASE(n)+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN0_ALT_SRCADDR (LPC31_DMACHAN0_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN0_ALT_DESTADDR (LPC31_DMACHAN0_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN0_ALT_XFERLEN (LPC31_DMACHAN0_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN0_ALT_CONFIG (LPC31_DMACHAN0_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN1_ALT_SRCADDR (LPC31_DMACHAN1_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN1_ALT_DESTADDR (LPC31_DMACHAN1_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN1_ALT_XFERLEN (LPC31_DMACHAN1_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN1_ALT_CONFIG (LPC31_DMACHAN1_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN2_ALT_SRCADDR (LPC31_DMACHAN2_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN2_ALT_DESTADDR (LPC31_DMACHAN2_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN2_ALT_XFERLEN (LPC31_DMACHAN2_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN2_ALT_CONFIG (LPC31_DMACHAN2_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN3_ALT_SRCADDR (LPC31_DMACHAN3_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN3_ALT_DESTADDR (LPC31_DMACHAN3_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN3_ALT_XFERLEN (LPC31_DMACHAN3_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN3_ALT_CONFIG (LPC31_DMACHAN3_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN4_ALT_SRCADDR (LPC31_DMACHAN4_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN4_ALT_DESTADDR (LPC31_DMACHAN4_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN4_ALT_XFERLEN (LPC31_DMACHAN4_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN4_ALT_CONFIG (LPC31_DMACHAN4_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN5_ALT_SRCADDR (LPC31_DMACHAN5_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN5_ALT_DESTADDR (LPC31_DMACHAN5_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN5_ALT_XFERLEN (LPC31_DMACHAN5_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN5_ALT_CONFIG (LPC31_DMACHAN5_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN6_ALT_SRCADDR (LPC31_DMACHAN6_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN6_ALT_DESTADDR (LPC31_DMACHAN6_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN6_ALT_XFERLEN (LPC31_DMACHAN6_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN6_ALT_CONFIG (LPC31_DMACHAN6_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN7_ALT_SRCADDR (LPC31_DMACHAN7_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN7_ALT_DESTADDR (LPC31_DMACHAN7_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN7_ALT_XFERLEN (LPC31_DMACHAN7_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN7_ALT_CONFIG (LPC31_DMACHAN7_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN8_ALT_SRCADDR (LPC31_DMACHAN8_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN8_ALT_DESTADDR (LPC31_DMACHAN8_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN8_ALT_XFERLEN (LPC31_DMACHAN8_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN8_ALT_CONFIG (LPC31_DMACHAN8_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN9_ALT_SRCADDR (LPC31_DMACHAN9_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN9_ALT_DESTADDR (LPC31_DMACHAN9_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN9_ALT_XFERLEN (LPC31_DMACHAN9_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN9_ALT_CONFIG (LPC31_DMACHAN9_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN10_ALT_SRCADDR (LPC31_DMACHAN10_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN10_ALT_DESTADDR (LPC31_DMACHAN10_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN10_ALT_XFERLEN (LPC31_DMACHAN10_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN10_ALT_CONFIG (LPC31_DMACHAN10_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +#define LPC31_DMACHAN11_ALT_SRCADDR (LPC31_DMACHAN11_ALT_VBASE+LPC31_DMACHAN_SRCADDR_OFFSET) +#define LPC31_DMACHAN11_ALT_DESTADDR (LPC31_DMACHAN11_ALT_VBASE+LPC31_DMACHAN_DESTADDR_OFFSET) +#define LPC31_DMACHAN11_ALT_XFERLEN (LPC31_DMACHAN11_ALT_VBASE+LPC31_DMACHAN_XFERLEN_OFFSET) +#define LPC31_DMACHAN11_ALT_CONFIG (LPC31_DMACHAN11_ALT_VBASE+LPC31_DMACHAN_CONFIG_OFFSET) + +/* DMA global register (virtual) addresses ******************************************************/ + +#define LPC31_DMA_ALTENABLE (LPC31_DMA_VBASE+LPC31_DMA_ALTENABLE_OFFSET) +#define LPC31_DMA_IRQSTATUSCLR (LPC31_DMA_VBASE+LPC31_DMA_IRQSTATUSCLR_OFFSET) +#define LPC31_DMA_IRQMASK (LPC31_DMA_VBASE+LPC31_DMA_IRQMASK_OFFSET) +#define LPC31_DMA_TESTSTATUS (LPC31_DMA_VBASE+LPC31_DMA_TESTSTATUS_OFFSET) +#define LPC31_DMA_SOFTINT (LPC31_DMA_VBASE+LPC31_DMA_SOFTINT_OFFSET) + +/* DMA channel register bit definitions *********************************************************/ + +/* TRANSFER_LENGTH (addresses 0x17000008 (channel 0) to 0x17000168 (channel 11)) */ + +#define DMACHAN_XFRLEN_SHIFT (0) /* Bits 0-20: Transfer length */ +#define DMACHAN_XFRLEN_MASK (0x001fffff << DMACHAN_XFRLEN_SHIFT) + +/* CONFIGURATION (addresses 0x1700000c (channel 0) to 0x1700016c (channel 11)) */ + +#define DMACHAN_CONFIG_CIRC (1 << 18) /* Bit 18: Enable circular buffer */ +#define DMACHAN_CONFIG_COMPCHENABLE (1 << 17) /* Bit 17: Enable companion channel */ +#define DMACHAN_CONFIG_COMPCHNR_SHIFT (13) /* Bits 13-15: Companion channel number */ +#define DMACHAN_CONFIG_COMPCHNR_MASK (7 << DMACHAN_CONFIG_COMPCHNR_SHIFT) +#define DMACHAN_CONFIG_INVENDIAN (1 << 12) /* Bit 12: Invert endian-ness */ +#define DMACHAN_CONFIG_XFERSIZE_SHIFT (10) /* Bits 10-11: Transfer size */ +#define DMACHAN_CONFIG_XFERSIZE_MASK (3 << DMACHAN_CONFIG_XFERSIZE_SHIFT) +# define DMACHAN_CONFIG_XFERSIZE_WORDS (0 << DMACHAN_CONFIG_XFERSIZE_SHIFT) /* Transfer words */ +# define DMACHAN_CONFIG_XFERSIZE_HWORDS (1 << DMACHAN_CONFIG_XFERSIZE_SHIFT) /* Transfer half-words */ +# define DMACHAN_CONFIG_XFERSIZE_BYTES (2 << DMACHAN_CONFIG_XFERSIZE_SHIFT) /* Transfer bytes */ +# define DMACHAN_CONFIG_XFERSIZE_BURSTS (3 << DMACHAN_CONFIG_XFERSIZE_SHIFT) /* Transfer bursts */ +#define DMACHAN_CONFIG_RDSLAVENR_SHIFT (5) /* Bits 5-9: Read slave enable */ +#define DMACHAN_CONFIG_RDSLAVENR_MASK (31 << DMACHAN_CONFIG_RDSLAVENR_SHIFT) +#define DMACHAN_CONFIG_WRSLAVENR_SHIFT (0) /* Bits 0-4: Write slave enable */ +#define DMACHAN_CONFIG_WRSLAVENR_MASK (31 << DMACHAN_CONFIG_WRSLAVENR_SHIFT) + +/* ENABLE (addresses 0x17000010 (channel 0) to 0x17000170 (channel 11)) */ + +#define DMACHAN_ENABLE_BIT (1 << 0) /* Bit 0: Enable */ + +/* TRANSFER_COUNTER (addresses 0x1700001v (channel 0) to 0x1700017c (channel 11)) */ + +#define DMACHAN_XFRCOUNT_SHIFT (0) /* Bits 0-20: Transfer count */ +#define DMACHAN_XFRCOUNT_MASK (0x001fffff << DMACHAN_XFRCOUNT_SHIFT) + +/* DMA global register bit definitions **********************************************************/ + +/* ALT_ENABLE (address 0x17000400) */ + +#define DMA_ALTENABLE_CHAN11 (1 << 11) /* Bit 11: Enable channel 11 */ +#define DMA_ALTENABLE_CHAN10 (1 << 10) /* Bit 10: Enable channel 10 */ +#define DMA_ALTENABLE_CHAN9 (1 << 9) /* Bit 9: Enable channel 9 */ +#define DMA_ALTENABLE_CHAN8 (1 << 8) /* Bit 8: Enable channel 8 */ +#define DMA_ALTENABLE_CHAN7 (1 << 7) /* Bit 7: Enable channel 7 */ +#define DMA_ALTENABLE_CHAN6 (1 << 6) /* Bit 6: Enable channel 6 */ +#define DMA_ALTENABLE_CHAN5 (1 << 5) /* Bit 5: Enable channel 5 */ +#define DMA_ALTENABLE_CHAN4 (1 << 4) /* Bit 4: Enable channel 4 */ +#define DMA_ALTENABLE_CHAN3 (1 << 3) /* Bit 3: Enable channel 3 */ +#define DMA_ALTENABLE_CHAN2 (1 << 2) /* Bit 2: Enable channel 2 */ +#define DMA_ALTENABLE_CHAN1 (1 << 1) /* Bit 1: Enable channel 1 */ +#define DMA_ALTENABLE_CHAN0 (1 << 0) /* Bit 0: Enable channel 0 */ + +/* IRQ_STATUS_CLR (address 0x17000404) */ + +#define DMA_IRQSTATUSCLR_DMAABORT (1 << 31) /* Bit 31: DMA abort */ +#define DMA_IRQSTATUSCLR_SOFTINT (1 << 30) /* Bit 30: Soft interrupt, scatter gather */ +#define DMA_IRQSTATUSCLR_HALFWAY11 (1 << 23) /* Bit 23: Chan 11 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED11 (1 << 22) /* Bit 22: Chan 11 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY10 (1 << 21) /* Bit 21: Chan 10 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED10 (1 << 20) /* Bit 20: Chan 10 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY9 (1 << 19) /* Bit 19: Chan 9 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED9 (1 << 18) /* Bit 18: Chan 9 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY8 (1 << 17) /* Bit 17: Chan 8 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED8 (1 << 16) /* Bit 16: Chan 8 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY7 (1 << 15) /* Bit 15: Chan 7 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED7 (1 << 14) /* Bit 14: Chan 7 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY6 (1 << 13) /* Bit 13: Chan 6 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED6 (1 << 12) /* Bit 12: Chan 6 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY5 (1 << 11) /* Bit 11: Chan 5 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED5 (1 << 10) /* Bit 10: Chan 5 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY4 (1 << 9) /* Bit 9: Chan 4 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED4 (1 << 8) /* Bit 8: Chan 4 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY3 (1 << 7) /* Bit 7: Chan 3 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED3 (1 << 6) /* Bit 6: Chan 3 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY2 (1 << 5) /* Bit 5: Chan 2 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED2 (1 << 4) /* Bit 4: Chan 2 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY1 (1 << 3) /* Bit 3: Chan 1 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED1 (1 << 2) /* Bit 2: Chan 1 finished */ +#define DMA_IRQSTATUSCLR_HALFWAY0 (1 << 1) /* Bit 1: Chan 0 more than half finished */ +#define DMA_IRQSTATUSCLR_FINISHED0 (1 << 0) /* Bit 0: Chan 0 finished */ + +/* IRQ_MASK (address 0x17000404) */ + +#define DMA_IRQMASK_DMAABORT (1 << 31) /* Bit 31: DMA abort */ +#define DMA_IRQMASK_SOFTINT (1 << 30) /* Bit 30: Soft interrupt, scatter gather */ +#define DMA_IRQMASK_HALFWAY11 (1 << 23) /* Bit 23: Chan 11 more than half finished */ +#define DMA_IRQMASK_FINISHED11 (1 << 22) /* Bit 22: Chan 11 finished */ +#define DMA_IRQMASK_HALFWAY10 (1 << 21) /* Bit 21: Chan 10 more than half finished */ +#define DMA_IRQMASK_FINISHED10 (1 << 20) /* Bit 20: Chan 10 finished */ +#define DMA_IRQMASK_HALFWAY9 (1 << 19) /* Bit 19: Chan 9 more than half finished */ +#define DMA_IRQMASK_FINISHED9 (1 << 18) /* Bit 18: Chan 9 finished */ +#define DMA_IRQMASK_HALFWAY8 (1 << 17) /* Bit 17: Chan 8 more than half finished */ +#define DMA_IRQMASK_FINISHED8 (1 << 16) /* Bit 16: Chan 8 finished */ +#define DMA_IRQMASK_HALFWAY7 (1 << 15) /* Bit 15: Chan 7 more than half finished */ +#define DMA_IRQMASK_FINISHED7 (1 << 14) /* Bit 14: Chan 7 finished */ +#define DMA_IRQMASK_HALFWAY6 (1 << 13) /* Bit 13: Chan 6 more than half finished */ +#define DMA_IRQMASK_FINISHED6 (1 << 12) /* Bit 12: Chan 6 finished */ +#define DMA_IRQMASK_HALFWAY5 (1 << 11) /* Bit 11: Chan 5 more than half finished */ +#define DMA_IRQMASK_FINISHED5 (1 << 10) /* Bit 10: Chan 5 finished */ +#define DMA_IRQMASK_HALFWAY4 (1 << 9) /* Bit 9: Chan 4 more than half finished */ +#define DMA_IRQMASK_FINISHED4 (1 << 8) /* Bit 8: Chan 4 finished */ +#define DMA_IRQMASK_HALFWAY3 (1 << 7) /* Bit 7: Chan 3 more than half finished */ +#define DMA_IRQMASK_FINISHED3 (1 << 6) /* Bit 6: Chan 3 finished */ +#define DMA_IRQMASK_HALFWAY2 (1 << 5) /* Bit 5: Chan 2 more than half finished */ +#define DMA_IRQMASK_FINISHED2 (1 << 4) /* Bit 4: Chan 2 finished */ +#define DMA_IRQMASK_HALFWAY1 (1 << 3) /* Bit 3: Chan 1 more than half finished */ +#define DMA_IRQMASK_FINISHED1 (1 << 2) /* Bit 2: Chan 1 finished */ +#define DMA_IRQMASK_HALFWAY0 (1 << 1) /* Bit 1: Chan 0 more than half finished */ +#define DMA_IRQMASK_FINISHED0 (1 << 0) /* Bit 0: Chan 0 finished */ + +/* SOFT_INT (address 0x1700040c) */ + +#define DMA_SOFTINT_ENABLE (1 << 0) /* Bit 0: Enable soft interrupt */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_DMA_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_ehci.c b/arch/arm/src/lpc31xx/lpc31_ehci.c new file mode 100644 index 0000000000000000000000000000000000000000..67ef095f2d39e3ba0267c926646f284587319c97 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_ehci.c @@ -0,0 +1,5378 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_ehci.c + * + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "lpc31.h" +#include "lpc31_cgudrvr.h" +#include "lpc31_syscreg.h" +#include "lpc31_evntrtr.h" +#include "lpc31_usbotg.h" + +#if defined(CONFIG_LPC31_USBOTG) && defined(CONFIG_USBHOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* Pre-requisites */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#elif !defined(CONFIG_SCHED_HPWORK) +# error Hi-priority work queue support is required (CONFIG_SCHED_HPWORK) +#endif + +/* Configurable number of Queue Head (QH) structures. The default is one per + * Root hub port plus one for EP0. + */ + +#ifndef CONFIG_LPC31_EHCI_NQHS +# define CONFIG_LPC31_EHCI_NQHS (LPC31_EHCI_NRHPORT + 1) +#endif + +/* Configurable number of Queue Element Transfer Descriptor (qTDs). The default + * is one per root hub plus three from EP0. + */ + +#ifndef CONFIG_LPC31_EHCI_NQTDS +# define CONFIG_LPC31_EHCI_NQTDS (LPC31_EHCI_NRHPORT + 3) +#endif + +/* Buffers must be aligned to the cache line size */ + +#define DCACHE_LINEMASK (ARM_DCACHE_LINESIZE -1) + +/* Configurable size of a request/descriptor buffers */ + +#ifndef CONFIG_LPC31_EHCI_BUFSIZE +# define CONFIG_LPC31_EHCI_BUFSIZE 128 +#endif + +#define LPC31_EHCI_BUFSIZE \ + ((CONFIG_LPC31_EHCI_BUFSIZE + DCACHE_LINEMASK) & ~DCACHE_LINEMASK) + +/* Debug options */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_LPC31_EHCI_REGDEBUG +#endif + +/* Isochronous transfers are not currently supported */ + +#undef CONFIG_USBHOST_ISOC_DISABLE +#define CONFIG_USBHOST_ISOC_DISABLE 1 + +/* Simplify DEBUG checks */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_USB +#endif + +/* Registers *******************************************************************/ +/* Traditionally, NuttX specifies register locations using individual + * register offsets from a base address. That tradition is broken here and, + * instead, register blocks are represented as structures. This is done here + * because, in principle, EHCI operational register address may not be known + * at compile time; the operational registers lie at an offset specified in + * the 'caplength' byte of the Host Controller Capability Registers. + * + * However, for the case of the LPC31 EHCI, we know apriori that locations + * of these register blocks. + */ + +/* Host Controller Capability Registers */ + +#define HCCR ((struct ehci_hccr_s *)LPC31_USBOTG_HCCR_BASE) + +/* Host Controller Operational Registers */ + +#define HCOR ((volatile struct ehci_hcor_s *)LPC31_USBOTG_HCOR_BASE) + +/* Interrupts ******************************************************************/ +/* This is the set of interrupts handled by this driver */ + +#define EHCI_HANDLED_INTS (EHCI_INT_USBINT | EHCI_INT_USBERRINT | \ + EHCI_INT_PORTSC | EHCI_INT_SYSERROR | \ + EHCI_INT_AAINT) + +/* The periodic frame list is a 4K-page aligned array of Frame List Link + * pointers. The length of the frame list may be programmable. The programmability + * of the periodic frame list is exported to system software via the HCCPARAMS + * register. If non-programmable, the length is 1024 elements. If programmable, + * the length can be selected by system software as one of 256, 512, or 1024 + * elements. + */ + +#define FRAME_LIST_SIZE 1024 + +/* DMA *************************************************************************/ +/* For now, we are assuming an identity mapping between physical and virtual + * address spaces. + */ + +#define lpc31_physramaddr(a) (a) +#define lpc31_virtramaddr(a) (a) + +/* USB trace *******************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +# define TR_FMT1 false +# define TR_FMT2 true + +# define TRENTRY(id,fmt1,string) {string} + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) +#endif + +/* Port numbers */ + +#define RHPNDX(rh) ((rh)->hport.hport.port) +#define RHPORT(rh) (RHPNDX(rh)+1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Internal representation of the EHCI Queue Head (QH) */ + +struct lpc31_epinfo_s; +struct lpc31_qh_s +{ + /* Fields visible to hardware */ + + struct ehci_qh_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ + + struct lpc31_epinfo_s *epinfo; /* Endpoint used for the transfer */ + uint32_t fqp; /* First qTD in the list (physical address) */ + uint8_t pad[8]; /* Padding to assure 32-byte alignment */ +}; + +/* Internal representation of the EHCI Queue Element Transfer Descriptor (qTD) */ + +struct lpc31_qtd_s +{ + /* Fields visible to hardware */ + + struct ehci_qtd_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ +}; + +/* The following is used to manage lists of free QHs and qTDs */ + +struct lpc31_list_s +{ + struct lpc31_list_s *flink; /* Link to next entry in the list */ + /* Variable length entry data follows */ +}; + +/* List traversal callout functions */ + +typedef int (*foreach_qh_t)(struct lpc31_qh_s *qh, uint32_t **bp, void *arg); +typedef int (*foreach_qtd_t)(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); + +/* This structure describes one endpoint. */ + +struct lpc31_epinfo_s +{ + uint8_t epno:7; /* Endpoint number */ + uint8_t dirin:1; /* 1:IN endpoint 0:OUT endpoint */ + uint8_t devaddr:7; /* Device address */ + uint8_t toggle:1; /* Next data toggle */ +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t interval; /* Polling interval */ +#endif + uint8_t status; /* Retained token status bits (for debug purposes) */ + volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */ + uint16_t maxpacket:11; /* Maximum packet size */ + uint16_t xfrtype:2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */ + uint16_t speed:2; /* See USB_*_SPEED definitions in ehci.h */ + int result; /* The result of the transfer */ + uint32_t xfrd; /* On completion, will hold the number of bytes transferred */ + sem_t iocsem; /* Semaphore used to wait for transfer completion */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* This structure retains the state of one root hub port */ + +struct lpc31_rhport_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct lpc31_rhport_s. + */ + + struct usbhost_driver_s drvr; + + /* Root hub port status */ + + volatile bool connected; /* Connected to device */ + volatile bool lowspeed; /* Low speed device attached */ + struct lpc31_epinfo_s ep0; /* EP0 endpoint info */ + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s hport; +}; + +/* This structure retains the overall state of the USB host controller */ + +struct lpc31_ehci_s +{ + volatile bool pscwait; /* TRUE: Thread is waiting for port status change event */ + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for port status change events */ + + struct lpc31_epinfo_s ep0; /* Endpoint 0 */ + struct lpc31_list_s *qhfree; /* List of free Queue Head (QH) structures */ + struct lpc31_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */ + struct work_s work; /* Supports interrupt bottom half */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* Root hub ports */ + + struct lpc31_rhport_s rhport[LPC31_EHCI_NRHPORT]; +}; + +#ifdef HAVE_USBHOST_TRACE +/* USB trace codes */ + +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + EHCI_TRACE1_SYSTEMERROR, /* EHCI ERROR: System error */ + EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: lpc31_qtd_foreach failed */ + EHCI_TRACE1_QHALLOC_FAILED, /* EHCI ERROR: Failed to allocate a QH */ + EHCI_TRACE1_BUFTOOBIG, /* EHCI ERROR: Buffer too big */ + EHCI_TRACE1_REQQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate request qTD */ + EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: lpc31_qtd_addbpl failed */ + EHCI_TRACE1_DATAQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate data buffer qTD */ + EHCI_TRACE1_DEVDISCONNECTED, /* EHCI ERROR: Device disconnected */ + EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: lpc31_qh_create failed */ + EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: lpc31_qtd_setupphase failed */ + + EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: lpc31_qtd_dataphase failed */ + EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: lpc31_qtd_statusphase failed */ + EHCI_TRACE1_TRANSFER_FAILED, /* EHCI ERROR: Transfer failed */ + EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: lpc31_qh_foreach failed: */ + EHCI_TRACE1_SYSERR_INTR, /* EHCI: Host System Error Interrup */ + EHCI_TRACE1_USBERR_INTR, /* EHCI: USB Error Interrupt (USBERRINT) Interrupt */ + EHCI_TRACE1_EPALLOC_FAILED, /* EHCI ERROR: Failed to allocate EP info structure */ + EHCI_TRACE1_BADXFRTYPE, /* EHCI ERROR: Support for transfer type not implemented */ + EHCI_TRACE1_HCHALTED_TIMEOUT, /* EHCI ERROR: Timed out waiting for HCHalted */ + EHCI_TRACE1_QHPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the QH pool */ + + EHCI_TRACE1_QTDPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the qTD pool */ + EHCI_TRACE1_PERFLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the periodic frame list */ + EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: lpc31_reset failed */ + EHCI_TRACE1_RUN_FAILED, /* EHCI ERROR: EHCI Failed to run */ + EHCI_TRACE1_IRQATTACH_FAILED, /* EHCI ERROR: Failed to attach IRQ */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE1_PORTSC_CSC, /* EHCI Connect Status Change */ + EHCI_VTRACE1_PORTSC_CONNALREADY, /* EHCI Already connected */ + EHCI_VTRACE1_PORTSC_DISCALREADY, /* EHCI Already disconnected */ + EHCI_VTRACE1_TOPHALF, /* EHCI Interrupt top half */ + EHCI_VTRACE1_AAINTR, /* EHCI Async Advance Interrupt */ + + EHCI_VTRACE1_CLASSENUM, /* EHCI Hub port CLASS enumeration */ + EHCI_VTRACE1_USBINTR, /* EHCI USB Interrupt (USBINT) Interrupt */ + EHCI_VTRACE1_ENUM_DISCONN, /* EHCI Enumeration not connected */ + EHCI_VTRACE1_INITIALIZING, /* EHCI Initializing EHCI Stack */ + EHCI_VTRACE1_HCCPARAMS, /* EHCI HCCPARAMS */ + EHCI_VTRACE1_INIITIALIZED, /* EHCI USB EHCI Initialized */ +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + EHCI_TRACE2_EPSTALLED, /* EHCI EP Stalled */ + EHCI_TRACE2_EPIOERROR, /* EHCI ERROR: EP TOKEN */ + EHCI_TRACE2_CLASSENUM_FAILED, /* EHCI usbhost_enumerate() failed */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE2_ASYNCXFR, /* EHCI Async transfer */ + EHCI_VTRACE2_INTRXFR, /* EHCI Interrupt Transfer */ + EHCI_VTRACE2_IOCCHECK, /* EHCI IOC */ + EHCI_VTRACE2_PORTSC, /* EHCI PORTSC */ + EHCI_VTRACE2_PORTSC_CONNECTED, /* EHCI RHPort connected */ + EHCI_VTRACE2_PORTSC_DISCONND, /* EHCI RHport disconnected */ + EHCI_VTRACE2_MONWAKEUP, /* EHCI RHPort connected wakeup */ + + EHCI_VTRACE2_EPALLOC, /* EHCI EPALLOC */ + EHCI_VTRACE2_CTRLINOUT, /* EHCI CTRLIN/OUT */ + EHCI_VTRACE2_HCIVERSION, /* EHCI HCIVERSION */ + EHCI_VTRACE2_HCSPARAMS, /* EHCI HCSPARAMS */ +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +/* USB trace data structure */ + +struct lpc31_ehci_trace_s +{ +#if 0 + uint16_t id; + bool fmt2; +#endif + FAR const char *string; +}; + +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +static uint16_t lpc31_read16(const uint8_t *addr); +static uint32_t lpc31_read32(const uint8_t *addr); +#if 0 /* Not used */ +static void lpc31_write16(uint16_t memval, uint8_t *addr); +static void lpc31_write32(uint32_t memval, uint8_t *addr); +#endif + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t lpc31_swap16(uint16_t value); +static uint32_t lpc31_swap32(uint32_t value); +#else +# define lpc31_swap16(value) (value) +# define lpc31_swap32(value) (value) +#endif + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static void lpc31_checkreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static uint32_t lpc31_getreg(volatile uint32_t *regaddr); +static void lpc31_putreg(uint32_t regval, volatile uint32_t *regaddr); +#else +static inline uint32_t lpc31_getreg(volatile uint32_t *regaddr); +static inline void lpc31_putreg(uint32_t regval, volatile uint32_t *regaddr); +#endif +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay); + +/* Semaphores ******************************************************************/ + +static void lpc31_takesem(sem_t *sem); +#define lpc31_givesem(s) sem_post(s); + +/* Allocators ******************************************************************/ + +static struct lpc31_qh_s *lpc31_qh_alloc(void); +static void lpc31_qh_free(struct lpc31_qh_s *qh); +static struct lpc31_qtd_s *lpc31_qtd_alloc(void); +static void lpc31_qtd_free(struct lpc31_qtd_s *qtd); + +/* List Management *************************************************************/ + +static int lpc31_qh_foreach(struct lpc31_qh_s *qh, uint32_t **bp, + foreach_qh_t handler, void *arg); +static int lpc31_qtd_foreach(struct lpc31_qh_s *qh, foreach_qtd_t handler, + void *arg); +static int lpc31_qtd_discard(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_discard(struct lpc31_qh_s *qh); + +/* Cache Operations ************************************************************/ + +#if 0 /* Not used */ +static int lpc31_qtd_invalidate(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_invalidate(struct lpc31_qh_s *qh); +#endif +static int lpc31_qtd_flush(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_flush(struct lpc31_qh_s *qh); + +/* Endpoint Transfer Handling **************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_qtd_print(struct lpc31_qtd_s *qtd); +static void lpc31_qh_print(struct lpc31_qh_s *qh); +static int lpc31_qtd_dump(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_dump(struct lpc31_qh_s *qh, uint32_t **bp, void *arg); +#else +# define lpc31_qtd_print(qtd) +# define lpc31_qh_print(qh) +# define lpc31_qtd_dump(qtd, bp, arg) OK +# define lpc31_qh_dump(qh, bp, arg) OK +#endif + +static inline uint8_t lpc31_ehci_speed(uint8_t usbspeed); +static int lpc31_ioc_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo); +static int lpc31_ioc_wait(struct lpc31_epinfo_s *epinfo); +static void lpc31_qh_enqueue(struct lpc31_qh_s *qhead, + struct lpc31_qh_s *qh); +static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo); +static int lpc31_qtd_addbpl(struct lpc31_qtd_s *qtd, const void *buffer, + size_t buflen); +static struct lpc31_qtd_s *lpc31_qtd_setupphase(struct lpc31_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req); +static struct lpc31_qtd_s *lpc31_qtd_dataphase(struct lpc31_epinfo_s *epinfo, + void *buffer, int buflen, uint32_t tokenbits); +static struct lpc31_qtd_s *lpc31_qtd_statusphase(uint32_t tokenbits); +static ssize_t lpc31_async_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen); +#ifndef CONFIG_USBHOST_INT_DISABLE +static int lpc31_intr_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, uint8_t *buffer, size_t buflen); +#endif +static ssize_t lpc31_transfer_wait(struct lpc31_epinfo_s *epinfo); +#ifdef CONFIG_USBHOST_ASYNCH +static inline int lpc31_ioc_async_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, usbhost_asynch_t callback, + FAR void *arg); +static void lpc31_asynch_completion(struct lpc31_epinfo_s *epinfo); +#endif + +/* Interrupt Handling **********************************************************/ + +static int lpc31_qtd_ioccheck(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_ioccheck(struct lpc31_qh_s *qh, uint32_t **bp, void *arg); +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc31_qtd_cancel(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc31_qh_cancel(struct lpc31_qh_s *qh, uint32_t **bp, void *arg); +#endif +static inline void lpc31_ioc_bottomhalf(void); +static inline void lpc31_portsc_bottomhalf(void); +static inline void lpc31_syserr_bottomhalf(void); +static inline void lpc31_async_advance_bottomhalf(void); +static void lpc31_ehci_bottomhalf(FAR void *arg); +static int lpc31_ehci_interrupt(int irq, FAR void *context); + +/* USB Host Controller Operations **********************************************/ + +static int lpc31_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int lpc31_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); +static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int lpc31_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int lpc31_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int lpc31_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int lpc31_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer); +static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer); +static ssize_t lpc31_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc31_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback, + FAR void *arg); +#endif +static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int lpc31_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, bool connected); +#endif +static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static int lpc31_reset(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct lpc31_ehci_s g_ehci; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_ehciconn; + +/* Maps USB chapter 9 speed to EHCI speed */ + +static const uint8_t g_ehci_speed[4] = +{ + 0, EHCI_LOW_SPEED, EHCI_FULL_SPEED, EHCI_HIGH_SPEED +}; + +/* The head of the asynchronous queue */ + +static struct lpc31_qh_s g_asynchead __attribute__ ((aligned(32))); + +#ifndef CONFIG_USBHOST_INT_DISABLE +/* The head of the periodic queue */ + +static struct lpc31_qh_s g_intrhead __attribute__ ((aligned(32))); + +/* The frame list */ + +#ifdef CONFIG_LPC31_EHCI_PREALLOCATE +static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__ ((aligned(4096))); +#else +static uint32_t *g_framelist; +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +#ifdef CONFIG_LPC31_EHCI_PREALLOCATE +/* Pools of pre-allocated data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct lpc31_qh_s g_qhpool[CONFIG_LPC31_EHCI_NQHS] + __attribute__ ((aligned(32))); + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct lpc31_qtd_s g_qtdpool[CONFIG_LPC31_EHCI_NQTDS] + __attribute__ ((aligned(32))); + +#else +/* Pools of dynamically data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct lpc31_qh_s *g_qhpool; + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct lpc31_qtd_s *g_qtdpool; + +#endif + +#ifdef HAVE_USBHOST_TRACE +/* USB trace strings */ + +static const struct lpc31_ehci_trace_s g_trace1[TRACE1_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE1_SYSTEMERROR, TR_FMT1, "EHCI ERROR: System error: %06x\n"), + TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_QHALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate a QH\n"), + TRENTRY(EHCI_TRACE1_BUFTOOBIG, TR_FMT1, "EHCI ERROR: Buffer too big. Remaining %d\n"), + TRENTRY(EHCI_TRACE1_REQQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate request qTD"), + TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_addbpl failed: %d\n"), + TRENTRY(EHCI_TRACE1_DATAQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate data buffer qTD, 0"), + TRENTRY(EHCI_TRACE1_DEVDISCONNECTED, TR_FMT1, "EHCI ERROR: Device disconnected %d\n"), + TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qh_create failed\n"), + TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_setupphase failed\n"), + + TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_dataphase failed\n"), + TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_statusphase failed\n"), + TRENTRY(EHCI_TRACE1_TRANSFER_FAILED, TR_FMT1, "EHCI ERROR: Transfer failed %d\n"), + TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qh_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_SYSERR_INTR, TR_FMT1, "EHCI: Host System Error Interrupt\n"), + TRENTRY(EHCI_TRACE1_USBERR_INTR, TR_FMT1, "EHCI: USB Error Interrupt (USBERRINT) Interrupt: %06x\n"), + TRENTRY(EHCI_TRACE1_EPALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate EP info structure\n"), + TRENTRY(EHCI_TRACE1_BADXFRTYPE, TR_FMT1, "EHCI ERROR: Support for transfer type %d not implemented\n"), + TRENTRY(EHCI_TRACE1_HCHALTED_TIMEOUT, TR_FMT1, "EHCI ERROR: Timed out waiting for HCHalted. USBSTS: %06x\n"), + TRENTRY(EHCI_TRACE1_QHPOOLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the QH pool\n"), + + TRENTRY(EHCI_TRACE1_QTDPOOLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the qTD pool\n"), + TRENTRY(EHCI_TRACE1_PERFLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the periodic frame list\n"), + TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_FMT1, "EHCI ERROR: lpc31_reset failed: %d\n"), + TRENTRY(EHCI_TRACE1_RUN_FAILED, TR_FMT1, "EHCI ERROR: EHCI Failed to run: USBSTS=%06x\n"), + TRENTRY(EHCI_TRACE1_IRQATTACH_FAILED, TR_FMT1, "EHCI ERROR: Failed to attach IRQ%d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE1_PORTSC_CSC, TR_FMT1, "EHCI Connect Status Change: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_CONNALREADY, TR_FMT1, "EHCI Already connected: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_DISCALREADY, TR_FMT1, "EHCI Already disconnected: %06x\n"), + TRENTRY(EHCI_VTRACE1_TOPHALF, TR_FMT1, "EHCI Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_AAINTR, TR_FMT1, "EHCI Async Advance Interrupt\n"), + + TRENTRY(EHCI_VTRACE1_CLASSENUM, TR_FMT1, "EHCI Hub port %d: Enumerate the device\n"), + TRENTRY(EHCI_VTRACE1_USBINTR, TR_FMT1, "EHCI USB Interrupt (USBINT) Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_ENUM_DISCONN, TR_FMT1, "EHCI Enumeration not connected\n"), + TRENTRY(EHCI_VTRACE1_INITIALIZING, TR_FMT1, "EHCI Initializing EHCI Stack\n"), + TRENTRY(EHCI_VTRACE1_HCCPARAMS, TR_FMT1, "EHCI HCCPARAMS=%06x\n"), + TRENTRY(EHCI_VTRACE1_INIITIALIZED, TR_FMT1, "EHCI USB EHCI Initialized\n"), +#endif +}; + +static const struct lpc31_ehci_trace_s g_trace2[TRACE2_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE2_EPSTALLED, TR_FMT2, "EHCI EP%d Stalled: TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_EPIOERROR, TR_FMT2, "EHCI ERROR: EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_CLASSENUM_FAILED, TR_FMT2, "EHCI Hub port %d usbhost_enumerate() failed: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE2_ASYNCXFR, TR_FMT2, "EHCI Async transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_INTRXFR, TR_FMT2, "EHCI Intr Transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_IOCCHECK, TR_FMT2, "EHCI IOC EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC, TR_FMT2, "EHCI PORTSC%d: %04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_CONNECTED, TR_FMT2, "EHCI RHPort%d connected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_DISCONND, TR_FMT2, "EHCI RHport%d disconnected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_MONWAKEUP, TR_FMT2, "EHCI RHPort%d connected: %d\n"), + + TRENTRY(EHCI_VTRACE2_EPALLOC, TR_FMT2, "EHCI EPALLOC: EP%d TYPE=%d\n"), + TRENTRY(EHCI_VTRACE2_CTRLINOUT, TR_FMT2, "EHCI CTRLIN/OUT: RHPort%d req: %02x\n"), + TRENTRY(EHCI_VTRACE2_HCIVERSION, TR_FMT2, "EHCI HCIVERSION %x.%02x\n"), + TRENTRY(EHCI_VTRACE2_HCSPARAMS, TR_FMT2, "EHCI nports=%d, HCSPARAMS=%04x\n"), +#endif +}; +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_read16 + * + * Description: + * Read 16-bit little endian data + * + ****************************************************************************/ + +static uint16_t lpc31_read16(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint16_t)addr[0] << 8 | (uint16_t)addr[1]; +#else + return (uint16_t)addr[1] << 8 | (uint16_t)addr[0]; +#endif +} + +/**************************************************************************** + * Name: lpc31_read32 + * + * Description: + * Read 32-bit little endian data + * + ****************************************************************************/ + +static inline uint32_t lpc31_read32(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint32_t)lpc31_read16(&addr[0]) << 16 | + (uint32_t)lpc31_read16(&addr[2]); +#else + return (uint32_t)lpc31_read16(&addr[2]) << 16 | + (uint32_t)lpc31_read16(&addr[0]); +#endif +} + +/**************************************************************************** + * Name: lpc31_write16 + * + * Description: + * Write 16-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc31_write16(uint16_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + addr[0] = memval & 0xff; + addr[1] = memval >> 8; +#else + addr[0] = memval >> 8; + addr[1] = memval & 0xff; +#endif +} +#endif + +/**************************************************************************** + * Name: lpc31_write32 + * + * Description: + * Write 32-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc31_write32(uint32_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + lpc31_write16(memval >> 16, &addr[0]); + lpc31_write16(memval & 0xffff, &addr[2]); +#else + lpc31_write16(memval & 0xffff, &addr[0]); + lpc31_write16(memval >> 16, &addr[2]); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc31_swap16 + * + * Description: + * Swap bytes on a 16-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t lpc31_swap16(uint16_t value) +{ + return ((value >> 8) & 0xff) | ((value & 0xff) << 8); +} +#endif + +/**************************************************************************** + * Name: lpc31_swap32 + * + * Description: + * Swap bytes on a 32-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint32_t lpc31_swap32(uint32_t value) +{ + return (uint32_t)lpc31_swap16((uint16_t)((value >> 16) & 0xffff)) | + (uint32_t)lpc31_swap16((uint16_t)(value & 0xffff)) << 16; +} +#endif + +/**************************************************************************** + * Name: lpc31_printreg + * + * Description: + * Print the contents of a LPC31 EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite) +{ + lldbg("%08x%s%08x\n", (uintptr_t)regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: lpc31_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a LPC31 + * EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_checkreg(volatile uint32_t *regaddr, uint32_t regval, bool iswrite) +{ + static uint32_t *prevaddr = NULL; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + lpc31_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = (uint32_t *)regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + lpc31_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: lpc31_getreg + * + * Description: + * Get the contents of an LPC31 register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static uint32_t lpc31_getreg(volatile uint32_t *regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = *regaddr; + + /* Check if we need to print this value */ + + lpc31_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t lpc31_getreg(volatile uint32_t *regaddr) +{ + return *regaddr; +} +#endif + +/**************************************************************************** + * Name: lpc31_putreg + * + * Description: + * Set the contents of an LPC31 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + /* Check if we need to print this value */ + + lpc31_checkreg(regaddr, regval, true); + + /* Write the value */ + + *regaddr = regval; +} +#else +static inline void lpc31_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + *regaddr = regval; +} +#endif + +/**************************************************************************** + * Name: ehci_wait_usbsts + * + * Description: + * Wait for either (1) a field in the USBSTS register to take a specific + * value, (2) for a timeout to occur, or (3) a error to occur. Return + * a value to indicate which terminated the wait. + * + ****************************************************************************/ + +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay) +{ + uint32_t regval; + unsigned int timeout; + + timeout = 0; + do + { + /* Wait 5usec before trying again */ + + up_udelay(5); + timeout += 5; + + /* Read the USBSTS register and check for a system error */ + + regval = lpc31_getreg(&HCOR->usbsts); + if ((regval & EHCI_INT_SYSERROR) != 0) + { + usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval); + return -EIO; + } + + /* Mask out the bits of interest */ + + regval &= maskbits; + + /* Loop until the masked bits take the specified value or until a + * timeout occurs. + */ + } + while (regval != donebits && timeout < delay); + + /* We got here because either the waited for condition or a timeout + * occurred. Return a value to indicate which. + */ + + return (regval == donebits) ? OK : -ETIMEDOUT; +} + +/**************************************************************************** + * Semaphores + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void lpc31_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Allocators + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_qh_alloc + * + * Description: + * Allocate a Queue Head (QH) structure by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct lpc31_qh_s *lpc31_qh_alloc(void) +{ + struct lpc31_qh_s *qh; + + /* Remove the QH structure from the freelist */ + + qh = (struct lpc31_qh_s *)g_ehci.qhfree; + if (qh) + { + g_ehci.qhfree = ((struct lpc31_list_s *)qh)->flink; + memset(qh, 0, sizeof(struct lpc31_qh_s)); + } + + return qh; +} + +/**************************************************************************** + * Name: lpc31_qh_free + * + * Description: + * Free a Queue Head (QH) structure by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void lpc31_qh_free(struct lpc31_qh_s *qh) +{ + struct lpc31_list_s *entry = (struct lpc31_list_s *)qh; + + /* Put the QH structure back into the free list */ + + entry->flink = g_ehci.qhfree; + g_ehci.qhfree = entry; +} + +/**************************************************************************** + * Name: lpc31_qtd_alloc + * + * Description: + * Allocate a Queue Element Transfer Descriptor (qTD) by removing it from the + * free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct lpc31_qtd_s *lpc31_qtd_alloc(void) +{ + struct lpc31_qtd_s *qtd; + + /* Remove the qTD from the freelist */ + + qtd = (struct lpc31_qtd_s *)g_ehci.qtdfree; + if (qtd) + { + g_ehci.qtdfree = ((struct lpc31_list_s *)qtd)->flink; + memset(qtd, 0, sizeof(struct lpc31_qtd_s)); + } + + return qtd; +} + +/**************************************************************************** + * Name: lpc31_qtd_free + * + * Description: + * Free a Queue Element Transfer Descriptor (qTD) by returning it to the free + * list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void lpc31_qtd_free(struct lpc31_qtd_s *qtd) +{ + struct lpc31_list_s *entry = (struct lpc31_list_s *)qtd; + + /* Put the qTD back into the free list */ + + entry->flink = g_ehci.qtdfree; + g_ehci.qtdfree = entry; +} + +/**************************************************************************** + * List Management + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_qh_foreach + * + * Description: + * Give the first entry in a list of Queue Head (QH) structures, call the + * handler for each QH structure in the list (including the one at the head + * of the list). + * + ****************************************************************************/ + +static int lpc31_qh_foreach(struct lpc31_qh_s *qh, uint32_t **bp, foreach_qh_t handler, + void *arg) +{ + struct lpc31_qh_s *next; + uintptr_t physaddr; + int ret; + + DEBUGASSERT(qh && handler); + while (qh) + { + /* Is this the end of the list? Check the horizontal link pointer (HLP) + * terminate (T) bit. If T==1, then the HLP address is not valid. + */ + + physaddr = lpc31_swap32(qh->hw.hlp); + if ((physaddr & QH_HLP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + + /* Is the next QH the asynchronous list head which will always be at + * the end of the asynchronous queue? + */ + + else if (lpc31_virtramaddr(physaddr & QH_HLP_MASK) == (uintptr_t)&g_asynchead) + { + /* That will also terminate the loop */ + + next = NULL; + } + + /* Otherwise, there is a QH structure after this one that describes + * another transaction. + */ + + else + { + physaddr = lpc31_swap32(qh->hw.hlp) & QH_HLP_MASK; + next = (struct lpc31_qh_s *)lpc31_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next QH pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qh, bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qh = next; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc31_qtd_foreach + * + * Description: + * Give a Queue Head (QH) instance, call the handler for each qTD structure + * in the queue. + * + ****************************************************************************/ + +static int lpc31_qtd_foreach(struct lpc31_qh_s *qh, foreach_qtd_t handler, void *arg) +{ + struct lpc31_qtd_s *qtd; + struct lpc31_qtd_s *next; + uintptr_t physaddr; + uint32_t *bp; + int ret; + + DEBUGASSERT(qh && handler); + + /* Handle the special case where the queue is empty */ + + bp = &qh->fqp; /* Start of qTDs in original list */ + physaddr = lpc31_swap32(*bp); /* Physical address of first qTD in CPU order */ + + if ((physaddr & QTD_NQP_T) != 0) + { + return 0; + } + + /* Start with the first qTD in the list */ + + qtd = (struct lpc31_qtd_s *)lpc31_virtramaddr(physaddr); + next = NULL; + + /* And loop until we encounter the end of the qTD list */ + + while (qtd) + { + /* Is this the end of the list? Check the next qTD pointer (NQP) + * terminate (T) bit. If T==1, then the NQP address is not valid. + */ + + if ((lpc31_swap32(qtd->hw.nqp) & QTD_NQP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + else + { + physaddr = lpc31_swap32(qtd->hw.nqp) & QTD_NQP_NTEP_MASK; + next = (struct lpc31_qtd_s *)lpc31_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next qTD pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qtd, &bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qtd = next; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc31_qtd_discard + * + * Description: + * This is a lpc31_qtd_foreach callback. It simply unlinks the QTD, updates + * the back pointer, and frees the QTD structure. + * + ****************************************************************************/ + +static int lpc31_qtd_discard(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd && bp && *bp); + + /* Remove the qTD from the list by updating the forward pointer to skip + * around this qTD. We do not change that pointer because are repeatedly + * removing the aTD at the head of the QH list. + */ + + **bp = qtd->hw.nqp; + + /* Then free the qTD */ + + lpc31_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: lpc31_qh_discard + * + * Description: + * Free the Queue Head (QH) and all qTD's attached to the QH. + * + * Assumptions: + * The QH structure itself has already been unlinked from whatever list it + * may have been in. + * + ****************************************************************************/ + +static int lpc31_qh_discard(struct lpc31_qh_s *qh) +{ + int ret; + + DEBUGASSERT(qh); + + /* Free all of the qTD's attached to the QH */ + + ret = lpc31_qtd_foreach(qh, lpc31_qtd_discard, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then free the QH itself */ + + lpc31_qh_free(qh); + return ret; +} + +/**************************************************************************** + * Cache Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_qtd_invalidate + * + * Description: + * This is a callback from lpc31_qtd_foreach. It simply invalidates D-cache for + * address range of the qTD entry. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int lpc31_qtd_invalidate(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Invalidate the D-Cache, i.e., force reloading of the D-Cache from memory + * memory over the specified address range. + */ + + cp15_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc31_qh_invalidate + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int lpc31_qh_invalidate(struct lpc31_qh_s *qh) +{ + /* Invalidate the QH first so that we reload the qTD list head */ + + cp15_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + + /* Then invalidate all of the qTD entries in the queue */ + + return lpc31_qtd_foreach(qh, lpc31_qtd_invalidate, NULL); +} +#endif + +/**************************************************************************** + * Name: lpc31_qtd_flush + * + * Description: + * This is a callback from lpc31_qtd_foreach. It simply flushes D-cache for + * address range of the qTD entry. + * + ****************************************************************************/ + +static int lpc31_qtd_flush(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Flush the D-Cache, i.e., make the contents of the memory match the contents + * of the D-Cache in the specified address range and invalidate the D-Cache + * to force re-loading of the data from memory when next accessed. + */ + + cp15_flush_idcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + cp15_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + + return OK; +} + +/**************************************************************************** + * Name: lpc31_qh_flush + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +static int lpc31_qh_flush(struct lpc31_qh_s *qh) +{ + /* Flush the QH first. This will write the contents of the D-cache to RAM and + * invalidate the contents of the D-cache so that the next access will be + * reloaded from D-Cache. + */ + + cp15_flush_idcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + cp15_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + + /* Then flush all of the qTD entries in the queue */ + + return lpc31_qtd_foreach(qh, lpc31_qtd_flush, NULL); +} + +/**************************************************************************** + * Endpoint Transfer Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_qtd_print + * + * Description: + * Print the context of one qTD + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_qtd_print(struct lpc31_qtd_s *qtd) +{ + udbg(" QTD[%p]:\n", qtd); + udbg(" hw:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + qtd->hw.nqp, qtd->hw.alt, qtd->hw.token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + qtd->hw.bpl[0], qtd->hw.bpl[1], qtd->hw.bpl[2], + qtd->hw.bpl[3], qtd->hw.bpl[4]); +} +#endif + +/**************************************************************************** + * Name: lpc31_qh_print + * + * Description: + * Print the context of one QH + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static void lpc31_qh_print(struct lpc31_qh_s *qh) +{ + struct lpc31_epinfo_s *epinfo; + struct ehci_overlay_s *overlay; + + udbg("QH[%p]:\n", qh); + udbg(" hw:\n"); + udbg(" hlp: %08x epchar: %08x epcaps: %08x cqp: %08x\n", + qh->hw.hlp, qh->hw.epchar, qh->hw.epcaps, qh->hw.cqp); + + overlay = &qh->hw.overlay; + udbg(" overlay:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + overlay->nqp, overlay->alt, overlay->token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + overlay->bpl[0], overlay->bpl[1], overlay->bpl[2], + overlay->bpl[3], overlay->bpl[4]); + + udbg(" fqp:\n", qh->fqp); + + epinfo = qh->epinfo; + udbg(" epinfo[%p]:\n", epinfo); + if (epinfo) + { + udbg(" EP%d DIR=%s FA=%08x TYPE=%d MaxPacket=%d\n", + epinfo->epno, epinfo->dirin ? "IN" : "OUT", epinfo->devaddr, + epinfo->xfrtype, epinfo->maxpacket); + udbg(" Toggle=%d iocwait=%d speed=%d result=%d\n", + epinfo->toggle, epinfo->iocwait, epinfo->speed, epinfo->result); + } +} +#endif + +/**************************************************************************** + * Name: lpc31_qtd_dump + * + * Description: + * This is a lpc31_qtd_foreach callout function. It dumps the context of one + * qTD + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static int lpc31_qtd_dump(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + lpc31_qtd_print(qtd); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc31_qh_dump + * + * Description: + * This is a lpc31_qh_foreach callout function. It dumps a QH structure and + * all of the qTD structures linked to the QH. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_EHCI_REGDEBUG +static int lpc31_qh_dump(struct lpc31_qh_s *qh, uint32_t **bp, void *arg) +{ + lpc31_qh_print(qh); + return lpc31_qtd_foreach(qh, lpc31_qtd_dump, NULL); +} +#endif + +/**************************************************************************** + * Name: lpc31_ehci_speed + * + * Description: + * Map a speed enumeration value per Chapter 9 of the USB specification to the + * speed enumeration required in the EHCI queue head. + * + ****************************************************************************/ + +static inline uint8_t lpc31_ehci_speed(uint8_t usbspeed) +{ + DEBUGASSERT(usbspeed >= USB_SPEED_LOW && usbspeed <= USB_SPEED_HIGH); + return g_ehci_speed[usbspeed]; +} + +/**************************************************************************** + * Name: lpc31_ioc_setup + * + * Description: + * Set the request for the IOC event well BEFORE enabling the transfer (as + * soon as we are absolutely committed to the to avoid transfer). We do this + * to minimize race conditions. This logic would have to be expanded if we + * want to have more than one packet in flight at a time! + * + * Assumption: The caller holds tex EHCI exclsem + * + ****************************************************************************/ + +static int lpc31_ioc_setup(struct lpc31_rhport_s *rhport, struct lpc31_epinfo_s *epinfo) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait); +#ifdef CONFIG_USBHOST_ASYNCH + DEBUGASSERT(epinfo->callback == NULL); +#endif + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then set iocwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + epinfo->iocwait = true; /* We want to be awakened by IOC interrupt */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; /* No asynchronous callback */ + epinfo->arg = NULL; +#endif + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc31_ioc_wait + * + * Description: + * Wait for the IOC event. + * + * Assumption: The caller does *NOT* hold the EHCI exclsem. That would cause + * a deadlock when the bottom-half, worker thread needs to take the semaphore. + * + ****************************************************************************/ + +static int lpc31_ioc_wait(struct lpc31_epinfo_s *epinfo) +{ + /* Wait for the IOC event. Loop to handle any false alarm semaphore counts. */ + + while (epinfo->iocwait) + { + lpc31_takesem(&epinfo->iocsem); + } + + return epinfo->result; +} + +/**************************************************************************** + * Name: lpc31_qh_enqueue + * + * Description: + * Add a new, ready-to-go QH w/attached qTDs to the asynchonous queue. + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static void lpc31_qh_enqueue(struct lpc31_qh_s *qhead, struct lpc31_qh_s *qh) +{ + uintptr_t physaddr; + + /* Set the internal fqp field. When we transverse the QH list later, + * we need to know the correct place to start because the overlay may no + * longer point to the first qTD entry. + */ + + qh->fqp = qh->hw.overlay.nqp; + (void)lpc31_qh_dump(qh, NULL, NULL); + + /* Add the new QH to the head of the asynchronous queue list. + * + * First, attach the old head as the new QH HLP and flush the new QH and its + * attached qTDs to RAM. + */ + + qh->hw.hlp = qhead->hw.hlp; + lpc31_qh_flush(qh); + + /* Then set the new QH as the first QH in the asychronous queue and flush the + * modified head to RAM. + */ + + physaddr = (uintptr_t)lpc31_physramaddr((uintptr_t)qh); + qhead->hw.hlp = lpc31_swap32(physaddr | QH_HLP_TYP_QH); + cp15_flush_idcache((uintptr_t)&qhead->hw, + (uintptr_t)&qhead->hw + sizeof(struct ehci_qh_s)); +} + +/**************************************************************************** + * Name: lpc31_qh_create + * + * Description: + * Create a new Queue Head (QH) + * + ****************************************************************************/ + +static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo) +{ + struct lpc31_qh_s *qh; + uint32_t rhpndx; + uint32_t regval; + uint8_t hubaddr; + uint8_t hubport; + + /* Allocate a new queue head structure */ + + qh = lpc31_qh_alloc(); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0); + return NULL; + } + + /* Save the endpoint information with the QH itself */ + + qh->epinfo = epinfo; + + /* Write QH endpoint characteristics: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * DEVADDR Device address Endpoint structure + * I Inactivate on Next Transaction 0 + * ENDPT Endpoint number Endpoint structure + * EPS Endpoint speed Endpoint structure + * DTC Data toggle control 1 + * MAXPKT Max packet size Endpoint structure + * C Control endpoint Calculated + * RL NAK count reloaded 8 + */ + + regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) | + ((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) | + ((uint32_t)lpc31_ehci_speed(epinfo->speed) << QH_EPCHAR_EPS_SHIFT) | + QH_EPCHAR_DTC | + ((uint32_t)epinfo->maxpacket << QH_EPCHAR_MAXPKT_SHIFT) | + ((uint32_t)8 << QH_EPCHAR_RL_SHIFT); + + /* Paragraph 3.6.3: "Control Endpoint Flag (C). If the QH.EPS field + * indicates the endpoint is not a high-speed device, and the endpoint + * is an control endpoint, then software must set this bit to a one. + * Otherwise it should always set this bit to a zero." + */ + + if (epinfo->speed != USB_SPEED_HIGH && + epinfo->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + regval |= QH_EPCHAR_C; + } + + /* Save the endpoint characteristics word with the correct byte order */ + + qh->hw.epchar = lpc31_swap32(regval); + + /* Write QH endpoint capabilities + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * SSMASK Interrupt Schedule Mask Depends on epinfo->xfrtype + * SCMASK Split Completion Mask 0 + * HUBADDR Hub Address Always 0 for now + * PORT Port number RH port index + 1 + * MULT High band width multiplier 1 + */ + + rhpndx = RHPNDX(rhport); + +#ifdef CONFIG_USBHOST_HUB + /* REVISIT: Future HUB support will require the HUB port number + * and HUB device address to be included here: + * + * - The HUB device address is the USB device address of the USB 2.0 Hub + * below which a full- or low-speed device is attached. + * - The HUB port number is the port number on the above USB 2.0 Hub + * + * These fields are used in the split-transaction protocol. The kludge + * below should work for hubs connected directly to a root hub port, + * but would not work for devices connected to downstream hubs. + */ + +#warning Missing logic + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#else + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#endif + + regval = ((uint32_t)hubaddr << QH_EPCAPS_HUBADDR_SHIFT) | + ((uint32_t)hubport << QH_EPCAPS_PORT_SHIFT) | + ((uint32_t)1 << QH_EPCAPS_MULT_SHIFT); + +#ifndef CONFIG_USBHOST_INT_DISABLE + if (epinfo->xfrtype == USB_EP_ATTR_XFER_INT) + { + /* Here, the S-Mask field in the queue head is set to 1, indicating + * that the transaction for the endpoint should be executed on the bus + * during micro-frame 0 of the frame. + * + * REVISIT: The polling interval should be controlled by the which + * entry is the framelist holds the QH pointer for a given micro-frame + * and the QH pointer should be replicated for different polling rates. + * This implementation currently just sets all frame_list entry to + * all the same interrupt queue. That should work but will not give + * any control over polling rates. + */ +#warning REVISIT + + regval |= ((uint32_t)1 << QH_EPCAPS_SSMASK_SHIFT); + } +#endif + + qh->hw.epcaps = lpc31_swap32(regval); + + /* Mark this as the end of this list. This will be overwritten if/when the + * next qTD is added to the queue. + */ + + qh->hw.hlp = lpc31_swap32(QH_HLP_T); + qh->hw.overlay.nqp = lpc31_swap32(QH_NQP_T); + qh->hw.overlay.alt = lpc31_swap32(QH_AQP_T); + return qh; +} + +/**************************************************************************** + * Name: lpc31_qtd_addbpl + * + * Description: + * Add a buffer pointer list to a qTD. + * + ****************************************************************************/ + +static int lpc31_qtd_addbpl(struct lpc31_qtd_s *qtd, const void *buffer, size_t buflen) +{ + uint32_t physaddr; + uint32_t nbytes; + uint32_t next; + int ndx; + + /* Flush the contents of the data buffer to RAM so that the correct contents + * will be accessed for an OUT DMA. + */ + + cp15_flush_idcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + cp15_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + + /* Loop, adding the aligned physical addresses of the buffer to the buffer page + * list. Only the first entry need not be aligned (because only the first + * entry has the offset field). The subsequent entries must begin on 4KB + * address boundaries. + */ + + physaddr = (uint32_t)lpc31_physramaddr((uintptr_t)buffer); + + for (ndx = 0; ndx < 5; ndx++) + { + /* Write the physical address of the buffer into the qTD buffer pointer + * list. + */ + + qtd->hw.bpl[ndx] = lpc31_swap32(physaddr); + + /* Get the next buffer pointer (in the case where we will have to transfer + * more then one chunk). This buffer must be aligned to a 4KB address + * boundary. + */ + + next = (physaddr + 4096) & ~4095; + + /* How many bytes were included in the last buffer? Was it the whole + * thing? + */ + + nbytes = next - physaddr; + if (nbytes >= buflen) + { + /* Yes... it was the whole thing. Break out of the loop early. */ + + break; + } + + /* Adjust the buffer length and physical address for the next time + * through the loop. + */ + + buflen -= nbytes; + physaddr = next; + } + + /* Handle the case of a huge buffer > 4*4KB = 16KB */ + + if (ndx >= 5) + { + usbhost_trace1(EHCI_TRACE1_BUFTOOBIG, buflen); + return -EFBIG; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc31_qtd_setupphase + * + * Description: + * Create a SETUP phase request qTD. + * + ****************************************************************************/ + +static struct lpc31_qtd_s *lpc31_qtd_setupphase(struct lpc31_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req) +{ + struct lpc31_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc31_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc31_swap32(QTD_NQP_T); + qtd->hw.alt = lpc31_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code QTD_TOKEN_PID_SETUP + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete 0 + * NBYTES Total Bytes to Transfer USB_SIZEOF_CTRLREQ + * TOGGLE Data Toggle 0 + */ + + regval = QTD_TOKEN_ACTIVE | QTD_TOKEN_PID_SETUP | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)USB_SIZEOF_CTRLREQ << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = lpc31_swap32(regval); + + /* Add the buffer data */ + + ret = lpc31_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + lpc31_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += USB_SIZEOF_CTRLREQ; + + return qtd; +} + +/**************************************************************************** + * Name: lpc31_qtd_dataphase + * + * Description: + * Create a data transfer or SET data phase qTD. + * + ****************************************************************************/ + +static struct lpc31_qtd_s *lpc31_qtd_dataphase(struct lpc31_epinfo_s *epinfo, + void *buffer, int buflen, + uint32_t tokenbits) +{ + struct lpc31_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc31_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc31_swap32(QTD_NQP_T); + qtd->hw.alt = lpc31_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete Contained in tokenbits + * NBYTES Total Bytes to Transfer buflen + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)buflen << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = lpc31_swap32(regval); + + /* Add the buffer information to the bufffer pointer list */ + + ret = lpc31_qtd_addbpl(qtd, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + lpc31_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += buflen; + + return qtd; +} + +/**************************************************************************** + * Name: lpc31_qtd_statusphase + * + * Description: + * Create a STATUS phase request qTD. + * + ****************************************************************************/ + +static struct lpc31_qtd_s *lpc31_qtd_statusphase(uint32_t tokenbits) +{ + struct lpc31_qtd_s *qtd; + uint32_t regval; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc31_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc31_swap32(QTD_NQP_T); + qtd->hw.alt = lpc31_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete QTD_TOKEN_IOC + * NBYTES Total Bytes to Transfer 0 + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | QTD_TOKEN_IOC | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT); + + qtd->hw.token = lpc31_swap32(regval); + return qtd; +} + +/**************************************************************************** + * Name: lpc31_async_setup + * + * Description: + * Process a IN or OUT request on any asynchronous endpoint (bulk or control). + * This function will enqueue the request and wait for it to complete. Bulk + * data transfers differ in that req == NULL and there are not SETUP or STATUS + * phases. + * + * This is a blocking function; it will not return until the control transfer + * has completed. + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +static int lpc31_async_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen) +{ + struct lpc31_qh_s *qh; + struct lpc31_qtd_s *qtd; + uintptr_t physaddr; + uint32_t *flink; + uint32_t *alt; + uint32_t toggle; + uint32_t regval; + bool dirin = false; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_ASYNCXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d, req=%p\n", + RHPORT(rhport), epinfo->epno, buffer, buflen, req); +#endif + + DEBUGASSERT(rhport && epinfo); + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + DEBUGASSERT(req || (buffer && buflen > 0)); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = lpc31_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the QH link and get the next data toggle (not used for SETUP + * transfers) + */ + + flink = &qh->hw.overlay.nqp; + toggle = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + ret = -EIO; + + /* Is the an EP0 SETUP request? If so, req will be non-NULL and we will + * queue two or three qTDs: + * + * 1) One for the SETUP phase, + * 2) One for the DATA phase (if there is data), and + * 3) One for the STATUS phase. + * + * If this is not an EP0 SETUP request, then only a data transfer will be + * enqueued. + */ + + if (req != NULL) + { + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the SETUP + * phase of the request sequence. + */ + + qtd = lpc31_qtd_setupphase(epinfo, req); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to the QH head. */ + + physaddr = lpc31_physramaddr((uintptr_t)qtd); + *flink = lpc31_swap32(physaddr); + + /* Get the new forward link pointer and data toggle */ + + flink = &qtd->hw.nqp; + toggle = QTD_TOKEN_TOGGLE; + } + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + alt = NULL; + if (buffer != NULL && buflen > 0) + { + uint32_t tokenbits; + + /* Extra TOKEN bits include the data toggle, the data PID, and if + * there is no request, an indication to interrupt at the end of this + * transfer. + */ + + tokenbits = toggle; + + /* Get the data token direction. + * + * If this is a SETUP request, use the direction contained in the + * request. The IOC bit is not set. + */ + + if (req) + { + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_IN; + dirin = true; + } + else + { + tokenbits |= QTD_TOKEN_PID_OUT; + dirin = false; + } + } + + /* Otherwise, the endpoint is uni-directional. Get the direction from + * the epinfo structure. Since this is not an EP0 SETUP request, + * nothing follows the data and we want the IOC interrupt when the + * data transfer completes. + */ + + else if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + dirin = true; + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + dirin = false; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = lpc31_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either QH head of the SETUP qTD. */ + + physaddr = lpc31_physramaddr((uintptr_t)qtd); + *flink = lpc31_swap32(physaddr); + + /* Set the forward link pointer to this new qTD */ + + flink = &qtd->hw.nqp; + + /* If this was an IN transfer, then setup a pointer alternate link. + * The EHCI hardware will use this link if a short packet is received. + */ + + if (dirin) + { + alt = &qtd->hw.alt; + } + } + + /* If this is an EP0 SETUP request, then enqueue one more qTD for the + * STATUS phase transfer. + */ + + if (req != NULL) + { + /* Extra TOKEN bits include the data toggle and the correct data PID. */ + + uint32_t tokenbits = toggle; + + /* The status phase direction is the opposite of the data phase. If + * this is an IN request, then we received the buffer and we will send + * the zero length packet handshake. + */ + + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_OUT; + } + + /* Otherwise, this in an OUT request. We send the buffer and we expect + * to receive the NULL packet handshake. + */ + + else + { + tokenbits |= QTD_TOKEN_PID_IN; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the status */ + + qtd = lpc31_qtd_statusphase(tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either the SETUP or data qTD. */ + + physaddr = lpc31_physramaddr((uintptr_t)qtd); + *flink = lpc31_swap32(physaddr); + + /* In an IN data qTD was also enqueued, then linke the data qTD's + * alternate pointer to this STATUS phase qTD in order to handle short + * transfers. + */ + + if (alt) + { + *alt = lpc31_swap32(physaddr); + } + } + + /* Add the new QH to the head of the asynchronous queue list */ + + lpc31_qh_enqueue(&g_asynchead, qh); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + lpc31_qh_discard(qh); + return ret; +} + +/**************************************************************************** + * Name: lpc31_intr_setup + * + * Description: + * Process a IN or OUT request on any interrupt endpoint by inserting a qTD + * into the periodic frame list. + * + * Paragraph 4.10.7 "Adding Interrupt Queue Heads to the Periodic Schedule" + * "The link path(s) from the periodic frame list to a queue head establishes + * in which frames a transaction can be executed for the queue head. Queue + * heads are linked into the periodic schedule so they are polled at + * the appropriate rate. System software sets a bit in a queue head's + * S-Mask to indicate which micro-frame with-in a 1 millisecond period a + * transaction should be executed for the queue head. Software must ensure + * that all queue heads in the periodic schedule have S-Mask set to a non- + * zero value. An S-mask with a zero value in the context of the periodic + * schedule yields undefined results. + * + * "If the desired poll rate is greater than one frame, system software can + * use a combination of queue head linking and S-Mask values to spread + * interrupts of equal poll rates through the schedule so that the + * periodic bandwidth is allocated and managed in the most efficient + * manner possible." + * + * Paragraph 4.6 "Periodic Schedule" + * + * "The periodic schedule is used to manage all isochronous and interrupt + * transfer streams. The base of the periodic schedule is the periodic + * frame list. Software links schedule data structures to the periodic + * frame list to produce a graph of scheduled data structures. The graph + * represents an appropriate sequence of transactions on the USB. ... + * isochronous transfers (using iTDs and siTDs) with a period of one are + * linked directly to the periodic frame list. Interrupt transfers (are + * managed with queue heads) and isochronous streams with periods other + * than one are linked following the period-one iTD/siTDs. Interrupt + * queue heads are linked into the frame list ordered by poll rate. + * Longer poll rates are linked first (e.g. closest to the periodic + * frame list), followed by shorter poll rates, with queue heads with a + * poll rate of one, on the very end." + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +#ifndef CONFIG_USBHOST_INT_DISABLE +static int lpc31_intr_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, + uint8_t *buffer, size_t buflen) +{ + struct lpc31_qh_s *qh; + struct lpc31_qtd_s *qtd; + uintptr_t physaddr; + uint32_t tokenbits; + uint32_t regval; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_INTRXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d\n", + RHPORT(rhport), epinfo->epno, buffer, buflen); +#endif + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = lpc31_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Extra TOKEN bits include the data toggle, the data PID, and an + * indication to interrupt at the end of this transfer. + */ + + tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + + /* Get the data token direction. */ + + if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = lpc31_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + ret = -ENOMEM; + goto errout_with_qh; + } + + /* Link the new qTD to the QH. */ + + physaddr = lpc31_physramaddr((uintptr_t)qtd); + qh->hw.overlay.nqp = lpc31_swap32(physaddr); + + /* Disable the periodic schedule */ + + regval = lpc31_getreg(&HCOR->usbcmd); + regval &= ~EHCI_USBCMD_PSEN; + lpc31_putreg(regval, &HCOR->usbcmd); + + /* Add the new QH to the head of the interrupt transfer list */ + + lpc31_qh_enqueue(&g_intrhead, qh); + + /* Re-enable the periodic schedule */ + + regval |= EHCI_USBCMD_PSEN; + lpc31_putreg(regval, &HCOR->usbcmd); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + lpc31_qh_discard(qh); + return ret; +} +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +/**************************************************************************** + * Name: lpc31_transfer_wait + * + * Description: + * Wait for an IN or OUT transfer to complete. + * + * Assumption: The caller holds the EHCI exclsem. The caller must be aware + * that the EHCI exclsem will released while waiting for the transfer to + * complete, but will be re-acquired when before returning. The state of + * EHCI resources could be very different upon return. + * + * Returned value: + * On success, this function returns the number of bytes actually transferred. + * For control transfers, this size includes the size of the control request + * plus the size of the data (which could be short); For bulk transfers, this + * will be the number of data bytes transfers (which could be short). + * + ****************************************************************************/ + +static ssize_t lpc31_transfer_wait(struct lpc31_epinfo_s *epinfo) +{ + int ret; + + /* Release the EHCI semaphore while we wait. Other threads need the + * opportunity to access the EHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not EHCI common) until + * the transfer is complete. But we can't use the common EHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ +#warning REVISIT + lpc31_givesem(&g_ehci.exclsem); + + /* Wait for the IOC completion event */ + + ret = lpc31_ioc_wait(epinfo); + + /* Re-acquire the EHCI semaphore. The caller expects to be holding + * this upon return. + */ + + lpc31_takesem(&g_ehci.exclsem); + +#if 0 /* Does not seem to be needed */ + /* Was there a data buffer? Was this an OUT transfer? */ + + if (buffer != NULL && buflen > 0 && !dirin) + { + /* We have received data from the host -- unless there was an error. + * in any event, we will invalidate the data buffer so that we will + * reload any new data freshly DMAed into the user buffer. + * + * NOTE: This might be un-necessary. We cleaned and invalidated the + * D-Cache prior to starting the DMA so the D-Cache should still be + * invalid in this memory region. + */ + + cp15_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + } +#endif + + /* Did lpc31_ioc_wait() report an error? */ + + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_TRANSFER_FAILED, -ret); + epinfo->iocwait = false; + return (ssize_t)ret; + } + + /* Transfer completed successfully. Return the number of bytes + * transferred. + */ + + return epinfo->xfrd; +} + +/**************************************************************************** + * Name: lpc31_ioc_async_setup + * + * Description: + * Setup to receive an asynchronous notification when a transfer completes. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer will be performed. + * callback - The function to be called when the completes + * arg - An arbitrary argument that will be provided with the callback. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static inline int lpc31_ioc_async_setup(struct lpc31_rhport_s *rhport, + struct lpc31_epinfo_s *epinfo, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait && + callback != NULL && epinfo->callback == NULL); + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then save callback information to used when either (1) the + * device is disconnected, or (2) the transfer completes. + */ + + epinfo->iocwait = false; /* No synchronous wakeup */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ + epinfo->callback = callback; /* Asynchronous callback */ + epinfo->arg = arg; /* Argument that accompanies the callback */ + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: lpc31_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer was performed. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void lpc31_asynch_completion(struct lpc31_epinfo_s *epinfo) +{ + usbhost_asynch_t callback; + ssize_t nbytes; + void *arg; + int result; + + DEBUGASSERT(epinfo != NULL && epinfo->iocwait == false && + epinfo->callback != NULL); + + /* Extract and reset the callback info */ + + callback = epinfo->callback; + arg = epinfo->arg; + result = epinfo->result; + nbytes = epinfo->xfrd; + + epinfo->callback = NULL; + epinfo->arg = NULL; + epinfo->result = OK; + epinfo->iocwait = false; + + /* Then perform the callback. Provide the number of bytes successfully + * transferred or the negated errno value in the event of a failure. + */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * EHCI Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_qtd_ioccheck + * + * Description: + * This function is a lpc31_qtd_foreach() callback function. It services one + * qTD in the asynchronous queue. It removes all of the qTD structures that + * are no longer active. + * + ****************************************************************************/ + +static int lpc31_qtd_ioccheck(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)arg; + DEBUGASSERT(qtd && epinfo); + + /* Make sure we reload the QH from memory */ + + cp15_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + lpc31_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + */ + + **bp = qtd->hw.nqp; + + /* Subtract the number of bytes left untransferred. The epinfo->xfrd + * field is initialized to the total number of bytes to be transferred + * (all qTDs in the list). We subtract out the number of untransferred + * bytes on each transfer and the final result will be the number of bytes + * actually transferred. + */ + + epinfo->xfrd -= (lpc31_swap32(qtd->hw.token) & QTD_TOKEN_NBYTES_MASK) >> + QTD_TOKEN_NBYTES_SHIFT; + + /* Release this QH by returning it to the free list */ + + lpc31_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: lpc31_qh_ioccheck + * + * Description: + * This function is a lpc31_qh_foreach() callback function. It services one + * QH in the asynchronous queue. It check all attached qTD structures and + * remove all of the structures that are no longer active. if all of the + * qTD structures are removed, then QH itself will also be removed. + * + ****************************************************************************/ + +static int lpc31_qh_ioccheck(struct lpc31_qh_s *qh, uint32_t **bp, void *arg) +{ + struct lpc31_epinfo_s *epinfo; + uint32_t token; + int ret; + + DEBUGASSERT(qh && bp); + + /* Make sure we reload the QH from memory */ + + cp15_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + lpc31_qh_print(qh); + + /* Get the endpoint info pointer from the extended QH data. Only the + * g_asynchead QH can have a NULL epinfo field. + */ + + epinfo = qh->epinfo; + DEBUGASSERT(epinfo); + + /* Paragraph 3.6.3: "The nine DWords in [the Transfer Overlay] area represent + * a transaction working space for the host controller. The general + * operational model is that the host controller can detect whether the + * overlay area contains a description of an active transfer. If it does + * not contain an active transfer, then it follows the Queue Head Horizontal + * Link Pointer to the next queue head. The host controller will never follow + * the Next Transfer Queue Element or Alternate Queue Element pointers unless + * it is actively attempting to advance the queue ..." + */ + + /* Is the qTD still active? */ + + token = lpc31_swap32(qh->hw.overlay.token); + usbhost_vtrace2(EHCI_VTRACE2_IOCCHECK, epinfo->epno, token); + + if ((token & QH_TOKEN_ACTIVE) != 0) + { + /* Yes... we cannot process the QH while it is still active. Return + * zero to visit the next QH in the list. + */ + *bp = &qh->hw.hlp; + return OK; + } + + /* Remove all active, attached qTD structures from the inactive QH */ + + ret = lpc31_qtd_foreach(qh, lpc31_qtd_ioccheck, (void *)qh->epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* If there is no longer anything attached to the QH, then remove it from + * the asynchronous queue. + */ + + if ((lpc31_swap32(qh->fqp) & QTD_NQP_T) != 0) + { + /* Set the forward link of the previous QH to point to the next + * QH in the list. + */ + + **bp = qh->hw.hlp; + cp15_flush_idcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Check for errors, update the data toggle */ + + if ((token & QH_TOKEN_ERRORS) == 0) + { + /* No errors.. Save the last data toggle value */ + + epinfo->toggle = (token >> QTD_TOKEN_TOGGLE_SHIFT) & 1; + + /* Report success */ + + epinfo->status = 0; + epinfo->result = OK; + } + else + { + /* An error occurred */ + + epinfo->status = (token & QH_TOKEN_STATUS_MASK) >> QH_TOKEN_STATUS_SHIFT; + + /* The HALT condition is set on a variety of conditions: babble, error + * counter countdown to zero, or a STALL. If we can rule out babble + * (babble bit not set) and if the error counter is non-zero, then we can + * assume a STALL. In this case, we return -PERM to inform the class + * driver of the stall condition. + */ + + if ((token & (QH_TOKEN_BABBLE | QH_TOKEN_HALTED)) == QH_TOKEN_HALTED && + (token & QH_TOKEN_CERR_MASK) != 0) + { + /* It is a stall, Note the that the data toggle is reset + * after the stall. + */ + + usbhost_trace2(EHCI_TRACE2_EPSTALLED, epinfo->epno, token); + epinfo->result = -EPERM; + epinfo->toggle = 0; + } + else + { + /* Otherwise, it is some kind of data transfer error */ + + usbhost_trace2(EHCI_TRACE2_EPIOERROR, epinfo->epno, token); + epinfo->result = -EIO; + } + } + + /* Is there a thread waiting for this transfer to complete? */ + + if (epinfo->iocwait) + { + /* Yes... wake it up */ + + lpc31_givesem(&epinfo->iocsem); + epinfo->iocwait = 0; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. Is there a pending asynchronous transfer? */ + + else if (epinfo->callback != NULL) + { + /* Yes.. perform the callback */ + + lpc31_asynch_completion(epinfo); + } +#endif + + /* Then release this QH by returning it to the free list */ + + lpc31_qh_free(qh); + } + else + { + /* Otherwise, the horizontal link pointer of this QH will become the next back pointer. + */ + + *bp = &qh->hw.hlp; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc31_qtd_cancel + * + * Description: + * This function is a lpc31_qtd_foreach() callback function. It removes each + * qTD attached to a QH. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc31_qtd_cancel(struct lpc31_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd != NULL && bp != NULL); + + /* Make sure we reload the QH from memory */ + + cp15_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + lpc31_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qtd->hw.nqp; + + /* Release this QH by returning it to the free list */ + + lpc31_qtd_free(qtd); + return OK; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: lpc31_qh_cancel + * + * Description: + * This function is a lpc31_qh_foreach() callback function. It cancels one + * QH in the asynchronous queue. It will remove all attached qTD structures + * and remove all of the structures that are no longer active. Then QH + * itself will also be removed. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc31_qh_cancel(struct lpc31_qh_s *qh, uint32_t **bp, void *arg) +{ + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)arg; + uint32_t regval; + int ret; + + DEBUGASSERT(qh != NULL && bp != NULL && epinfo != NULL); + + /* Make sure we reload the QH from memory */ + + cp15_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + lpc31_qh_print(qh); + + /* Check if this is the QH that we are looking for */ + + if (qh->epinfo == epinfo) + { + /* No... keep looking */ + + return OK; + } + + /* Disable both the asynchronous and period schedules */ + + regval = lpc31_getreg(&HCOR->usbcmd); + lpc31_putreg(regval & ~(EHCI_USBCMD_ASEN | EHCI_USBCMD_PSEN), + &HCOR->usbcmd); + + /* Remove the QH from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qh->hw.hlp; + cp15_flush_idcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Re-enable the schedules (if they were enabled before. */ + + lpc31_putreg(regval, &HCOR->usbcmd); + + /* Remove all active, attached qTD structures from the removed QH */ + + ret = lpc31_qtd_foreach(qh, lpc31_qtd_cancel, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then release this QH by returning it to the free list. Return 1 + * to stop the traverse without an error. + */ + + lpc31_qh_free(qh); + return 1; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: lpc31_ioc_bottomhalf + * + * Description: + * EHCI USB Interrupt (USBINT) "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor that + * had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is detected + * (actual number of bytes received was less than the expected number of + * bytes)." + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static inline void lpc31_ioc_bottomhalf(void) +{ + struct lpc31_qh_s *qh; + uint32_t *bp; + int ret; + + /* Check the Asynchronous Queue */ + /* Make sure that the head of the asynchronous queue is invalidated */ + + cp15_invalidate_dcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward QH pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct lpc31_qh_s *)lpc31_virtramaddr(lpc31_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in the + * asynchronous queue head will point back to the the queue head. + */ + + if (qh && qh != &g_asynchead) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue + */ + + ret = lpc31_qh_foreach(qh, &bp, lpc31_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Check the Interrupt Queue */ + /* Make sure that the head of the interrupt queue is invalidated */ + + cp15_invalidate_dcache((uintptr_t)&g_intrhead.hw, + (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward qTD pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct lpc31_qh_s *)lpc31_virtramaddr(lpc31_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue. + */ + + ret = lpc31_qh_foreach(qh, &bp, lpc31_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } +#endif +} + +/**************************************************************************** + * Name: lpc31_portsc_bottomhalf + * + * Description: + * EHCI Port Change Detect "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to a one when any port for which the Port + * Owner bit is set to zero ... has a change bit transition from a zero to a + * one or a Force Port Resume bit transition from a zero to a one as a result + * of a J-K transition detected on a suspended port. This bit will also be set + * as a result of the Connect Status Change being set to a one after system + * software has relinquished ownership of a connected port by writing a one + * to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition of the + * EHCI HC device, this bit is loaded with the OR of all of the PORTSC change + * bits (including: Force port resume, over-current change, enable/disable + * change and connect status change)." + * + ****************************************************************************/ + +static inline void lpc31_portsc_bottomhalf(void) +{ + struct lpc31_rhport_s *rhport; + struct usbhost_hubport_s *hport; + uint32_t portsc; + int rhpndx; + + /* Handle root hub status change on each root port */ + + for (rhpndx = 0; rhpndx < LPC31_EHCI_NRHPORT; rhpndx++) + { + rhport = &g_ehci.rhport[rhpndx]; + portsc = lpc31_getreg(&HCOR->portsc[rhpndx]); + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc); + + /* Handle port connection status change (CSC) events */ + + if ((portsc & EHCI_PORTSC_CSC) != 0) + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CSC, portsc); + + /* Check current connect status */ + + if ((portsc & EHCI_PORTSC_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!rhport->connected) + { + /* Yes.. connected. */ + + rhport->connected = true; + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_CONNECTED, + rhpndx + 1, g_ehci.pscwait); + + /* Notify any waiters */ + + if (g_ehci.pscwait) + { + lpc31_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CONNALREADY, portsc); + } + } + else + { + /* Disconnected... Did we just become disconnected? */ + + if (rhport->connected) + { + /* Yes.. disconnect the device */ + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_DISCONND, + rhpndx+1, g_ehci.pscwait); + + rhport->connected = false; + rhport->lowspeed = false; + + /* Are we bound to a class instance? */ + + hport = &rhport->hport.hport; + if (hport->devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(hport->devclass); + hport->devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change + * event. + */ + + if (g_ehci.pscwait) + { + lpc31_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_DISCALREADY, portsc); + } + } + } + + /* Clear all pending port interrupt sources by writing a '1' to the + * corresponding bit in the PORTSC register. In addition, we need + * to preserve the values of all R/W bits (RO bits don't matter) + */ + + lpc31_putreg(portsc, &HCOR->portsc[rhpndx]); + } +} + +/**************************************************************************** + * Name: lpc31_syserr_bottomhalf + * + * Description: + * EHCI Host System Error "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 when a serious error occurs during a + * host system access involving the Host Controller module. ... When this + * error occurs, the Host Controller clears the Run/Stop bit in the Command + * register to prevent further execution of the scheduled TDs." + * + ****************************************************************************/ + +static inline void lpc31_syserr_bottomhalf(void) +{ + usbhost_trace1(EHCI_TRACE1_SYSERR_INTR, 0); + PANIC(); +} + +/**************************************************************************** + * Name: lpc31_async_advance_bottomhalf + * + * Description: + * EHCI Async Advance "Bottom Half" interrupt handler + * + * "System software can force the host controller to issue an interrupt the + * next time the host controller advances the asynchronous schedule by writing + * a one to the Interrupt on Async Advance Doorbell bit in the USBCMD + * register. This status bit indicates the assertion of that interrupt + * source." + * + ****************************************************************************/ + +static inline void lpc31_async_advance_bottomhalf(void) +{ + usbhost_vtrace1(EHCI_VTRACE1_AAINTR, 0); + + /* REVISIT: Could remove all tagged QH entries here */ +} + +/**************************************************************************** + * Name: lpc31_ehci_bottomhalf + * + * Description: + * EHCI "Bottom Half" interrupt handler + * + ****************************************************************************/ + +static void lpc31_ehci_bottomhalf(FAR void *arg) +{ + uint32_t pending = (uint32_t)arg; + + /* We need to have exclusive access to the EHCI data structures. Waiting here + * is not a good thing to do on the worker thread, but there is no real option + * (other than to reschedule and delay). + */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Handle all unmasked interrupt sources */ + /* USB Interrupt (USBINT) + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * USB Error Interrupt (USBERRINT) + * + * "The Host Controller sets this bit to 1 when completion of a USB + * transaction results in an error condition (e.g., error counter + * underflow). If the TD on which the error interrupt occurred also + * had its IOC bit set, both this bit and USBINT bit are set. ..." + * + * We do the same thing in either case: Traverse the asynchonous queue + * and remove all of the transfers that are no longer active. + */ + + if ((pending & (EHCI_INT_USBINT | EHCI_INT_USBERRINT)) != 0) + { + if ((pending & EHCI_INT_USBERRINT) != 0) + { + usbhost_trace1(EHCI_TRACE1_USBERR_INTR, pending); + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending); + } + + lpc31_ioc_bottomhalf(); + } + + /* Port Change Detect + * + * "The Host Controller sets this bit to a one when any port for which + * the Port Owner bit is set to zero ... has a change bit transition + * from a zero to a one or a Force Port Resume bit transition from a zero + * to a one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership + * of a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition + * of the EHCI HC device, this bit is loaded with the OR of all of the + * PORTSC change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + */ + + if ((pending & EHCI_INT_PORTSC) != 0) + { + lpc31_portsc_bottomhalf(); + } + + /* Frame List Rollover + * + * "The Host Controller sets this bit to a one when the Frame List Index ... + * rolls over from its maximum value to zero. The exact value at which + * the rollover occurs depends on the frame list size. For example, if + * the frame list size (as programmed in the Frame List Size field of the + * USBCMD register) is 1024, the Frame Index Register rolls over every + * time FRINDEX[13] toggles. Similarly, if the size is 512, the Host + * Controller sets this bit to a one every time FRINDEX[12] toggles." + */ + +#if 0 /* Not used */ + if ((pending & EHCI_INT_FLROLL) != 0) + { + lpc31_flroll_bottomhalf(); + } +#endif + + /* Host System Error + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit + * in the Command register to prevent further execution of the scheduled + * TDs." + */ + + if ((pending & EHCI_INT_SYSERROR) != 0) + { + lpc31_syserr_bottomhalf(); + } + + /* Interrupt on Async Advance + * + * "System software can force the host controller to issue an interrupt + * the next time the host controller advances the asynchronous schedule + * by writing a one to the Interrupt on Async Advance Doorbell bit in + * the USBCMD register. This status bit indicates the assertion of that + * interrupt source." + */ + + if ((pending & EHCI_INT_AAINT) != 0) + { + lpc31_async_advance_bottomhalf(); + } + + /* We are done with the EHCI structures */ + + lpc31_givesem(&g_ehci.exclsem); + + /* Re-enable relevant EHCI interrupts. Interrupts should still be enabled + * at the level of the interrupt controller. + */ + + lpc31_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); +} + +/**************************************************************************** + * Name: lpc31_ehci_interrupt + * + * Description: + * EHCI "Top Half" interrupt handler + * + ****************************************************************************/ + +static int lpc31_ehci_interrupt(int irq, FAR void *context) +{ + uint32_t usbsts; + uint32_t pending; + uint32_t regval; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + usbsts = lpc31_getreg(&HCOR->usbsts); + regval = lpc31_getreg(&HCOR->usbintr); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(EHCI_VTRACE1_TOPHALF, usbsts & regval); +#else + ullvdbg("USBSTS: %08x USBINTR: %08x\n", usbsts, regval); +#endif + + /* Handle all unmasked interrupt sources */ + + pending = usbsts & regval; + if (pending != 0) + { + /* Schedule interrupt handling work for the high priority worker thread + * so that we are not pressed for time and so that we can interrupt with + * other USB threads gracefully. + * + * The worker should be available now because we implement a handshake + * by controlling the EHCI interrupts. + */ + + DEBUGASSERT(work_available(&g_ehci.work)); + DEBUGVERIFY(work_queue(HPWORK, &g_ehci.work, lpc31_ehci_bottomhalf, + (FAR void *)pending, 0)); + + /* Disable further EHCI interrupts so that we do not overrun the work + * queue. + */ + + lpc31_putreg(0, &HCOR->usbintr); + + /* Clear all pending status bits by writing the value of the pending + * interrupt bits back to the status register. + */ + + lpc31_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR->usbsts); + } + + return OK; +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc31_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + irqstate_t flags; + int rhpndx; + + /* Loop until a change in the connection state changes on one of the root hub + * ports or until an error occurs. + */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < LPC31_EHCI_NRHPORT; rhpndx++) + { + struct lpc31_rhport_s *rhport; + struct usbhost_hubport_s *connport; + + /* Has the connection state changed on the RH port? */ + + rhport = &g_ehci.rhport[rhpndx]; + connport = &rhport->hport.hport; + if (rhport->connected != connport->connected) + { + /* Yes.. Return the RH port to inform the caller which + * port has the connection change. + */ + + connport->connected = rhport->connected; + *hport = connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + rhpndx + 1, rhport->connected); + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (g_ehci.hport) + { + volatile struct usbhost_hubport_s *connport; + + /* Yes.. return the external hub port */ + + connport = g_ehci.hport; + g_ehci.hport = NULL; + + *hport = (struct usbhost_hubport_s *)connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + connport->port + 1, connport->connected); + return OK; + } +#endif + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + + g_ehci.pscwait = true; + lpc31_takesem(&g_ehci.pscsem); + } +} + +/**************************************************************************** + * Name: lpc31_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc31_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + struct lpc31_rhport_s *rhport; + volatile uint32_t *regaddr; + uint32_t regval; + int rhpndx; + + DEBUGASSERT(conn != NULL && hport != NULL); + rhpndx = hport->port; + + DEBUGASSERT(rhpndx >= 0 && rhpndx < LPC31_EHCI_NRHPORT); + rhport = &g_ehci.rhport[rhpndx]; + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!rhport->connected) + { + /* No, return an error */ + + usbhost_vtrace1(EHCI_VTRACE1_ENUM_DISCONN, 0); + return -ENODEV; + } + + /* USB 2.0 spec says at least 50ms delay before port reset. + * REVISIT: I think this is wrong. It needs to hold the port in + * reset for 50Msec, not wait 50Msec before resetting. + */ + + usleep(100*1000); + + /* Paragraph 2.3.9: + * + * "Line Status ... These bits reflect the current logical levels of the + * D+ (bit 11) and D- (bit 10) signal lines. These bits are used for + * detection of low-speed USB devices prior to the port reset and enable + * sequence. This field is valid only when the port enable bit is zero + * and the current connect status bit is set to a one." + * + * Bits[11:10] USB State Interpretation + * ----------- --------- -------------- + * 00b SE0 Not Low-speed device, perform EHCI reset + * 10b J-state Not Low-speed device, perform EHCI reset + * 01b K-state Low-speed device, release ownership of port + * + * NOTE: Low-speed devices could be detected by examining the PORTSC PSPD + * field after resetting the device. The more convential way here, however, + * also appears to work. + */ + + regval = lpc31_getreg(&HCOR->portsc[rhpndx]); + if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE) + { + /* EHCI Paragraph 2.3.9: + * + * "Port Owner ... This bit unconditionally goes to a 0b when the + * Configured bit in the CONFIGFLAG register makes a 0b to 1b + * transition. This bit unconditionally goes to 1b whenever the + * Configured bit is zero. + * + * "System software uses this field to release ownership of the + * port to a selected host controller (in the event that the + * attached device is not a high-speed device). Software writes + * a one to this bit when the attached device is not a high-speed + * device. A one in this bit means that a companion host + * controller owns and controls the port. .... + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + hport->speed = USB_SPEED_LOW; + +#if 0 /* The LPC31xx does not support a companion host controller */ + regval |= EHCI_PORTSC_OWNER; + lpc31_putreg(regval, &HCOR->portsc[rhpndx]); + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; +#endif + } + else + { + /* Assume full-speed for now */ + + hport->speed = USB_SPEED_FULL; + } + + /* Put the root hub port in reset. + * + * Paragraph 2.3.9: + * + * "The HCHalted bit in the USBSTS register should be a zero before + * software attempts to use [the Port Reset] bit. The host controller + * may hold Port Reset asserted to a one when the HCHalted bit is a one. + */ + + DEBUGASSERT((lpc31_getreg(&HCOR->usbsts) & EHCI_USBSTS_HALTED) == 0); + + /* EHCI paragraph 2.3.9: + * + * "When software writes a one to [the Port Reset] bit (from a zero), the + * bus reset sequence as defined in the USB Specification Revision 2.0 is + * started. Software writes a zero to this bit to terminate the bus reset + * sequence. Software must keep this bit at a one long enough to ensure + * the reset sequence, as specified in the USB Specification Revision 2.0, + * completes. Note: when software writes this bit to a one, it must also + * write a zero to the Port Enable bit." + */ + + regaddr = &HCOR->portsc[RHPNDX(rhport)]; + regval = lpc31_getreg(regaddr); + regval &= ~EHCI_PORTSC_PE; + regval |= EHCI_PORTSC_RESET; + lpc31_putreg(regval, regaddr); + + /* USB 2.0 "Root hubs must provide an aggregate reset period of at least + * 50 ms." + */ + + usleep(50*1000); + + regval = lpc31_getreg(regaddr); + regval &= ~EHCI_PORTSC_RESET; + lpc31_putreg(regval, regaddr); + + /* Wait for the port reset to complete + * + * EHCI Paragraph 2.3.9: + * + * "Note that when software writes a zero to this bit there may be a + * delay before the bit status changes to a zero. The bit status will + * not read as a zero until after the reset has completed. If the port + * is in high-speed mode after reset is complete, the host controller + * will automatically enable this port (e.g. set the Port Enable bit + * to a one). A host controller must terminate the reset and stabilize + * the state of the port within 2 milliseconds of software transitioning + * this bit from a one to a zero ..." + */ + + while ((lpc31_getreg(regaddr) & EHCI_PORTSC_RESET) != 0); + usleep(200*1000); + + /* EHCI Paragraph 4.2.2: + * + * "... The reset process is actually complete when software reads a zero + * in the PortReset bit. The EHCI Driver checks the PortEnable bit in the + * PORTSC register. If set to a one, the connected device is a high-speed + * device and EHCI Driver (root hub emulator) issues a change report to the + * hub driver and the hub driver continues to enumerate the attached device." + * + * "At the time the EHCI Driver receives the port reset and enable request + * the LineStatus bits might indicate a low-speed device. Additionally, + * when the port reset process is complete, the PortEnable field may + * indicate that a full-speed device is attached. In either case the EHCI + * driver sets the PortOwner bit in the PORTSC register to a one to + * release port ownership to a companion host controller." + * + * LPC31xx User Manual Paragraph 6.1.3: + * + * "In a standard EHCI controller design, the EHCI host controller driver + * detects a Full speed (FS) or Low speed (LS) device by noting if the + * port enable bit is set after the port reset operation. The port enable + * will only be set in a standard EHCI controller implementation after the + * port reset operation and when the host and device negotiate a High-Speed + * connection (i.e. Chirp completes successfully). Since this controller has + * an embedded Transaction Translator, the port enable will always be set + * after the port reset operation regardless of the result of the host device + * chirp result and the resulting port speed will be indicated by the PSPD + * field in PORTSC1. + */ + + regval = lpc31_getreg(&HCOR->portsc[rhpndx]); + +#if 0 /* LPC31xx detects high- vs full-speed devices using the PSPD field */ + if ((regval & EHCI_PORTSC_PE) != 0) +#else + if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_HS) +#endif + { + /* High speed device */ + + hport->speed = USB_SPEED_HIGH; + } + else if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_FS) + { + /* Low- or Full- speed device. Set the port ownership bit. + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + DEBUGASSERT(hport->speed == USB_SPEED_FULL); + +#if 0 /* The LPC31xx does not support a companion host controller */ + regval |= EHCI_PORTSC_OWNER; + lpc31_putreg(regval, &HCOR->portsc[rhpndx]); + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; +#endif + } + + /* Otherwise it must be a low speed device */ + + else + { + DEBUGASSERT(hport->speed == USB_SPEED_LOW); + DEBUGASSERT((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_LS); + } + + return OK; +} + +static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + int ret; + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + + DEBUGASSERT(hport); +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = lpc31_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + usbhost_vtrace1(EHCI_VTRACE1_CLASSENUM, hport->port); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + /* Failed to enumerate */ + + usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, hport->port + 1, -ret); + + /* If this is a root hub port, then marking the hub port not connected will + * cause lpc31_wait() to return and we will try the connection again. + */ + + hport->connected = false; + } + + return ret; +} + +/************************************************************************************ + * Name: lpc31_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls. A funcaddr of zero will be received if no address is yet assigned + * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) +{ + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep0; + + DEBUGASSERT(drvr != NULL && epinfo != NULL && maxpacketsize < 2048); + + /* We must have exclusive access to the EHCI data structures. */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Remember the new device address and max packet size */ + + epinfo->devaddr = funcaddr; + epinfo->speed = speed; + epinfo->maxpacket = maxpacketsize; + + lpc31_givesem(&g_ehci.exclsem); + return OK; +} + +/************************************************************************************ + * Name: lpc31_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep) +{ + struct lpc31_epinfo_s *epinfo; + struct usbhost_hubport_s *hport; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && epdesc->hport != NULL && ep != NULL); + hport = epdesc->hport; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_EPALLOC, epdesc->addr, epdesc->xfrtype); +#else + uvdbg("EP%d DIR=%s FA=%08x TYPE=%d Interval=%d MaxPacket=%d\n", + epdesc->addr, epdesc->in ? "IN" : "OUT", hport->funcaddr, + epdesc->xfrtype, epdesc->interval, epdesc->mxpacketsize); +#endif + + /* Allocate a endpoint information structure */ + + epinfo = (struct lpc31_epinfo_s *)kmm_zalloc(sizeof(struct lpc31_epinfo_s)); + if (!epinfo) + { + usbhost_trace1(EHCI_TRACE1_EPALLOC_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the endpoint container (which is really just another form of + * 'struct usbhost_epdesc_s', packed differently and with additional + * information. A cleaner design might just embed struct usbhost_epdesc_s + * inside of struct lpc31_epinfo_s and just memcpy here. + */ + + epinfo->epno = epdesc->addr; + epinfo->dirin = epdesc->in; + epinfo->devaddr = hport->funcaddr; +#ifndef CONFIG_USBHOST_INT_DISABLE + epinfo->interval = epdesc->interval; +#endif + epinfo->maxpacket = epdesc->mxpacketsize; + epinfo->xfrtype = epdesc->xfrtype; + epinfo->speed = hport->speed; + sem_init(&epinfo->iocsem, 0, 0); + + /* Success.. return an opaque reference to the endpoint information structure + * instance + */ + + *ep = (usbhost_ep_t)epinfo; + return OK; +} + +/************************************************************************************ + * Name: lpc31_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc31_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep; + + /* There should not be any pending, transfers */ + + DEBUGASSERT(drvr && epinfo && epinfo->iocwait == 0); + + /* Free the container */ + + kmm_free(epinfo); + return OK; +} + +/**************************************************************************** + * Name: lpc31_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * allocate the request/descriptor memory. If the underlying hardware does + * not support such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was + * assumed that the driver maintains a pool of small, pre-allocated buffers + * for descriptor traffic. NOTE that size is not an input, but an output: + * The size of the pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of a memory location provided by the caller in which + * to return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which + * to return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc31_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + int ret = -ENOMEM; + DEBUGASSERT(drvr && buffer && maxlen); + + /* The only special requirements for transfer/descriptor buffers are that (1) + * they be aligned to a cache line boundary and (2) they are a multiple of the + * cache line size in length. + */ + + *buffer = (FAR uint8_t *)kmm_memalign(ARM_DCACHE_LINESIZE, LPC31_EHCI_BUFSIZE); + if (*buffer) + { + *maxlen = LPC31_EHCI_BUFSIZE; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc31_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * free that request/descriptor memory. If the underlying hardware does not + * support such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc31_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the transfer/descriptor buffer memory */ + + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: lpc31_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kumm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc31_ioalloc(FAR struct usbhost_driver_s *drvr, FAR uint8_t **buffer, + size_t buflen) +{ + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* The only special requirements for I/O buffers are that (1) they be aligned to a + * cache line boundary, (2) they are a multiple of the cache line size in length, + * and (3) they might need to be user accessible (depending on how the class driver + * implements its buffering). + */ + + buflen = (buflen + DCACHE_LINEMASK) & ~DCACHE_LINEMASK; + *buffer = (FAR uint8_t *)kumm_memalign(ARM_DCACHE_LINESIZE, buflen); + return *buffer ? OK : -ENOMEM; +} + +/************************************************************************************ + * Name: lpc31_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kumm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the I/O buffer memory */ + + kumm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: lpc31_ctrlin and lpc31_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer + * may be queued; Neither these methods nor the transfer() method can be + * called again until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using + * DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr; + struct lpc31_epinfo_s *ep0info = (struct lpc31_epinfo_s *)ep0; + uint16_t len; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport != NULL && ep0info != NULL && req != NULL); + + len = lpc31_read16(req->len); + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, RHPORT(rhport), req->req); +#else + uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %04x\n", + RHPORT(rhport), req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], len); +#endif + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = lpc31_ioc_setup(rhport, ep0info); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Now initiate the transfer */ + + ret = lpc31_async_setup(rhport, ep0info, req, buffer, len); + if (ret < 0) + { + udbg("ERROR: lpc31_async_setup failed: %d\n", ret); + goto errout_with_iocwait; + } + + /* And wait for the transfer to complete */ + + nbytes = lpc31_transfer_wait(ep0info); + lpc31_givesem(&g_ehci.exclsem); + return nbytes >= 0 ? OK : (int)nbytes; + +errout_with_iocwait: + ep0info->iocwait = false; +errout_with_sem: + lpc31_givesem(&g_ehci.exclsem); + return ret; +} + +static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + /* lpc31_ctrlin can handle both directions. We just need to work around the + * differences in the function signatures. + */ + + return lpc31_ctrlin(drvr, ep0, req, (uint8_t *)buffer); +} + +/**************************************************************************** + * Name: lpc31_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t lpc31_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr; + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = lpc31_ioc_setup(rhport, epinfo); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = lpc31_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = lpc31_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_iocwait; + } + + /* Then wait for the transfer to complete */ + + nbytes = lpc31_transfer_wait(epinfo); + lpc31_givesem(&g_ehci.exclsem); + return nbytes; + +errout_with_iocwait: + epinfo->iocwait = false; +errout_with_sem: + lpc31_givesem(&g_ehci.exclsem); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: lpc31_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc31_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr; + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Set the request for the callback well BEFORE initiating the transfer. */ + + ret = lpc31_ioc_async_setup(rhport, epinfo, callback, arg); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = lpc31_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = lpc31_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_callback; + } + + /* The transfer is in progress */ + + lpc31_givesem(&g_ehci.exclsem); + return OK; + +errout_with_callback: + epinfo->callback = NULL; + epinfo->arg = NULL; +errout_with_sem: + lpc31_givesem(&g_ehci.exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: lpc31_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep; + struct lpc31_qh_s *qh; +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; + void *arg; +#endif + uint32_t *bp; + irqstate_t flags; + bool iocwait; + int ret; + + DEBUGASSERT(epinfo); + + /* We must have exclusive access to the EHCI hardware and data structures. This + * will prevent servicing any transfer completion events while we perform the + * the cancellation, but will not prevent DMA-related race conditions. + * + * REVISIT: This won't work. This function must be callable from the interrupt + * level. + */ + + lpc31_takesem(&g_ehci.exclsem); + + /* Sample and reset all transfer termination information. This will prevent any + * callbacks from occurring while are performing the cancellation. The transfer + * may still be in progress, however, so this does not eliminate other DMA- + * related race conditions. + */ + + flags = enter_critical_section(); +#ifdef CONFIG_USBHOST_ASYNCH + callback = epinfo->callback; + arg = epinfo->arg; +#endif + iocwait = epinfo->iocwait; + +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; + epinfo->arg = NULL; +#endif + epinfo->iocwait = false; + + /* This will prevent any callbacks from occurring while are performing + * the cancellation. The transfer may still be in progress, however, so + * this does not eliminate other DMA-related race conditions. + */ + + epinfo->callback = NULL; + epinfo->arg = NULL; + leave_critical_section(flags); + + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + + /* Handle the cancellation according to the type of the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + case USB_EP_ATTR_XFER_BULK: + { + /* Get the horizontal pointer from the head of the asynchronous + * queue. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct lpc31_qh_s *)lpc31_virtramaddr(lpc31_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in + * the asynchronous queue head will point back to the the queue + * head. + */ + + if (qh && qh != &g_asynchead) + { + /* Claim that we successfully cancelled the transfer */ + + ret = OK; + goto exit_terminate; + } + } + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + { + /* Get the horizontal pointer from the head of the interrupt + * queue. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct lpc31_qh_s *)lpc31_virtramaddr(lpc31_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* if the queue is empty, then just claim that we successfully + * cancelled the transfer. + */ + + ret = OK; + goto exit_terminate; + } + } + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + goto errout_with_sem; + } + + /* Find and remove the QH. There are four possibilities: + * + * 1) The transfer has already completed and the QH is no longer in the list. In + * this case, lpc31_hq_foreach will return zero + * 2a) The transfer is not active and still pending. It was removed from the list + * and lpc31_hq_foreach will return one. + * 2b) The is active but not yet complete. This is currently handled the same as + * 2a). REVISIT: This needs to be fixed. + * 3) Some bad happened and lpc31_hq_foreach returned an error code < 0. + */ + + ret = lpc31_qh_foreach(qh, &bp, lpc31_qh_cancel, epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Was there a pending synchronous transfer? */ + +exit_terminate: + epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH + if (iocwait) + { + /* Yes... wake it up */ + + DEBUGASSERT(callback == NULL); + lpc31_givesem(&epinfo->iocsem); + } + + /* No.. Is there a pending asynchronous transfer? */ + + else /* if (callback != NULL) */ + { + /* Yes.. perform the callback */ + + callback(arg, -ESHUTDOWN); + } + +#else + /* Wake up the waiting thread */ + + sam_givesem(&epinfo->iocsem); +#endif + +errout_with_sem: + lpc31_givesem(&g_ehci.exclsem); + return ret; +} + +/************************************************************************************ + * Name: lpc31_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int lpc31_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */ + + g_ehci.hport = hport; + if (g_ehci.pscwait) + { + g_ehci.pscwait = false; + lpc31_givesem(&g_ehci.pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc31_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_reset + * + * Description: + * Set the HCRESET bit in the USBCMD register to reset the EHCI hardware. + * + * Table 2-9. USBCMD - USB Command Register Bit Definitions + * + * "Host Controller Reset (HCRESET) ... This control bit is used by software + * to reset the host controller. The effects of this on Root Hub registers + * are similar to a Chip Hardware Reset. + * + * "When software writes a one to this bit, the Host Controller resets its + * internal pipelines, timers, counters, state machines, etc. to their + * initial value. Any transaction currently in progress on USB is + * immediately terminated. A USB reset is not driven on downstream + * ports. + * + * "PCI Configuration registers are not affected by this reset. All + * operational registers, including port registers and port state machines + * are set to their initial values. Port ownership reverts to the companion + * host controller(s)... Software must reinitialize the host controller ... + * in order to return the host controller to an operational state. + * + * "This bit is set to zero by the Host Controller when the reset process is + * complete. Software cannot terminate the reset process early by writing a + * zero to this register. Software should not set this bit to a one when + * the HCHalted bit in the USBSTS register is a zero. Attempting to reset + * an actively running host controller will result in undefined behavior." + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + * Assumptions: + * - Called during the initialization of the EHCI. + * + ****************************************************************************/ + +static int lpc31_reset(void) +{ + uint32_t regval; + unsigned int timeout; + + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to 0, + * the Host Controller completes the current transaction on the USB and then + * halts. The HC Halted bit in the status register indicates when the Hos + * Controller has finished the transaction and has entered the stopped state..." + */ + + lpc31_putreg(0, &HCOR->usbcmd); + + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in + * the USBSTS register is a zero. Attempting to reset an actively running + * host controller will result in undefined behavior." + */ + + timeout = 0; + do + { + /* Wait one microsecond and update the timeout counter */ + + up_udelay(1); + timeout++; + + /* Get the current value of the USBSTS register. This loop will terminate + * when either the timeout exceeds one millisecond or when the HCHalted + * bit is no longer set in the USBSTS register. + */ + + regval = lpc31_getreg(&HCOR->usbsts); + } + while (((regval & EHCI_USBSTS_HALTED) == 0) && (timeout < 1000)); + + /* Is the EHCI still running? Did we timeout? */ + + if ((regval & EHCI_USBSTS_HALTED) == 0) + { + usbhost_trace1(EHCI_TRACE1_HCHALTED_TIMEOUT, regval); + return -ETIMEDOUT; + } + + /* Now we can set the HCReset bit in the USBCMD register to initiate the reset */ + + regval = lpc31_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_HCRESET; + lpc31_putreg(regval, &HCOR->usbcmd); + + /* Wait for the HCReset bit to become clear */ + + do + { + /* Wait five microsecondw and update the timeout counter */ + + up_udelay(5); + timeout += 5; + + /* Get the current value of the USBCMD register. This loop will terminate + * when either the timeout exceeds one second or when the HCReset + * bit is no longer set in the USBSTS register. + */ + + regval = lpc31_getreg(&HCOR->usbcmd); + } + while (((regval & EHCI_USBCMD_HCRESET) != 0) && (timeout < 1000000)); + + /* Return either success or a timeout */ + + return (regval & EHCI_USBCMD_HCRESET) != 0 ? -ETIMEDOUT : OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) +{ + FAR struct usbhost_hubport_s *hport; + uint32_t regval; +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + uint16_t regval16; + unsigned int nports; +#endif + uintptr_t physaddr; + int ret; + int i; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(((uintptr_t)&g_asynchead & 0x1f) == 0); + DEBUGASSERT((sizeof(struct lpc31_qh_s) & 0x1f) == 0); + DEBUGASSERT((sizeof(struct lpc31_qtd_s) & 0x1f) == 0); + +#ifdef CONFIG_LPC31_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0); + DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0); +#endif + +#ifndef CONFIG_USBHOST_INT_DISABLE + DEBUGASSERT(((uintptr_t)&g_intrhead & 0x1f) == 0); +#ifdef CONFIG_LPC31_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)g_framelist & 0xfff) == 0); +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + + /* Software Configuration ****************************************************/ + + usbhost_vtrace1(EHCI_VTRACE1_INITIALIZING, 0); + + /* Initialize the EHCI state data structure */ + + sem_init(&g_ehci.exclsem, 0, 1); + sem_init(&g_ehci.pscsem, 0, 0); + + /* Initialize EP0 */ + + sem_init(&g_ehci.ep0.iocsem, 0, 1); + + /* Initialize the root hub port structures */ + + for (i = 0; i < LPC31_EHCI_NRHPORT; i++) + { + struct lpc31_rhport_s *rhport = &g_ehci.rhport[i]; + + /* Initialize the device operations */ + + rhport->drvr.ep0configure = lpc31_ep0configure; + rhport->drvr.epalloc = lpc31_epalloc; + rhport->drvr.epfree = lpc31_epfree; + rhport->drvr.alloc = lpc31_alloc; + rhport->drvr.free = lpc31_free; + rhport->drvr.ioalloc = lpc31_ioalloc; + rhport->drvr.iofree = lpc31_iofree; + rhport->drvr.ctrlin = lpc31_ctrlin; + rhport->drvr.ctrlout = lpc31_ctrlout; + rhport->drvr.transfer = lpc31_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + rhport->drvr.asynch = lpc31_asynch; +#endif + rhport->drvr.cancel = lpc31_cancel; +#ifdef CONFIG_USBHOST_HUB + rhport->drvr.connect = lpc31_connect; +#endif + rhport->drvr.disconnect = lpc31_disconnect; + + /* Initialize EP0 */ + + rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; + rhport->ep0.speed = USB_SPEED_FULL; + rhport->ep0.maxpacket = 8; + sem_init(&rhport->ep0.iocsem, 0, 0); + + /* Initialize the public port representation */ + + hport = &rhport->hport.hport; + hport->drvr = &rhport->drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = &rhport->ep0; + hport->port = i; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&rhport->hport); + } + +#ifndef CONFIG_LPC31_EHCI_PREALLOCATE + /* Allocate a pool of free Queue Head (QH) structures */ + + g_qhpool = (struct lpc31_qh_s *) + kmm_memalign(32, CONFIG_LPC31_EHCI_NQHS * sizeof(struct lpc31_qh_s)); + if (!g_qhpool) + { + usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0); + return NULL; + } +#endif + + /* Initialize the list of free Queue Head (QH) structures */ + + for (i = 0; i < CONFIG_LPC31_EHCI_NQHS; i++) + { + /* Put the QH structure in a free list */ + + lpc31_qh_free(&g_qhpool[i]); + } + +#ifndef CONFIG_LPC31_EHCI_PREALLOCATE + /* Allocate a pool of free Transfer Descriptor (qTD) structures */ + + g_qtdpool = (struct lpc31_qtd_s *) + kmm_memalign(32, CONFIG_LPC31_EHCI_NQTDS * sizeof(struct lpc31_qtd_s)); + if (!g_qtdpool) + { + usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0); + kmm_free(g_qhpool); + return NULL; + } +#endif + +#if !defined(CONFIG_LPC31_EHCI_PREALLOCATE) && !defined(CONFIG_USBHOST_INT_DISABLE) + /* Allocate the periodic framelist */ + + g_framelist = (uint32_t *) + kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t)); + if (!g_framelist) + { + usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0); + kmm_free(g_qhpool); + kmm_free(g_qtdpool); + return NULL; + } +#endif + + /* Initialize the list of free Transfer Descriptor (qTD) structures */ + + for (i = 0; i < CONFIG_LPC31_EHCI_NQTDS; i++) + { + /* Put the TD in a free list */ + + lpc31_qtd_free(&g_qtdpool[i]); + } + + /* EHCI Hardware Configuration ***********************************************/ + /* Enable USB to AHB clock and to Event router */ + + lpc31_enableclock(CLKID_USBOTGAHBCLK); + lpc31_enableclock(CLKID_EVENTROUTERPCLK); + + /* Reset USB block */ + + lpc31_softreset(RESETID_USBOTGAHBRST); + + /* Enable USB OTG PLL and wait for lock */ + + putreg32(0, LPC31_SYSCREG_USB_ATXPLLPDREG); + + uint32_t bank = EVNTRTR_BANK(EVENTRTR_USBATXPLLLOCK); + uint32_t bit = EVNTRTR_BIT(EVENTRTR_USBATXPLLLOCK); + + while ((getreg32(LPC31_EVNTRTR_RSR(bank)) & (1 << bit)) == 0) + ; + + /* Enable USB AHB clock */ + + lpc31_enableclock (CLKID_USBOTGAHBCLK); + + /* Reset the controller from the OTG peripheral */ + + putreg32(USBDEV_USBCMD_RST, LPC31_USBDEV_USBCMD); + while ((getreg32(LPC31_USBDEV_USBCMD) & USBDEV_USBCMD_RST) != 0) + ; + + /* Program the controller to be the USB host controller + * + * Fixed selections: + * + * CM = Host mode + * ES = 0, Little endian mode. + * SLOM Not used in host mode. + * VBPS = 1, off-chip power source + * + * Configurable selections: + * + * SDIS = 1, Stream disable mode. Eliminates overruns/underruns at + * the expense of some performance. + */ + +#ifdef CONFIG_LPC31_EHCI_SDIS + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | USBHOST_USBMODE_VBPS, + LPC31_USBDEV_USBMODE); +#else + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS, LPC31_USBDEV_USBMODE); +#endif + + /* Host Controller Initialization. Paragraph 4.1 */ + /* Reset the EHCI hardware */ + + ret = lpc31_reset(); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); + return NULL; + } + + /* Re-program the USB host controller. As implemented, lpc31_reset() + * requires the host mode setup in order to work. However, we lose the + * host configuration in the reset. + */ + + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | USBHOST_USBMODE_VBPS, + LPC31_USBDEV_USBMODE); + + /* "In order to initialize the host controller, software should perform the + * following steps: + * + * - "Program the CTRLDSSEGMENT register with 4-Gigabyte segment where all + * of the interface data structures are allocated. [64-bit mode] + * - "Write the appropriate value to the USBINTR register to enable the + * appropriate interrupts. + * - "Write the base address of the Periodic Frame List to the PERIODICLIST + * BASE register. If there are no work items in the periodic schedule, + * all elements of the Periodic Frame List should have their T-Bits set + * to a one. + * - "Write the USBCMD register to set the desired interrupt threshold, + * frame list size (if applicable) and turn the host controller ON via + * setting the Run/Stop bit. + * - Write a 1 to CONFIGFLAG register to route all ports to the EHCI controller + * ... + * + * "At this point, the host controller is up and running and the port registers + * will begin reporting device connects, etc. System software can enumerate a + * port through the reset process (where the port is in the enabled state). At + * this point, the port is active with SOFs occurring down the enabled por + * enabled Highspeed ports, but the schedules have not yet been enabled. The + * EHCI Host controller will not transmit SOFs to enabled Full- or Low-speed + * ports. + */ + + /* Disable all interrupts */ + + lpc31_putreg(0, &HCOR->usbintr); + + /* Clear pending interrupts. Bits in the USBSTS register are cleared by + * writing a '1' to the corresponding bit. + */ + + lpc31_putreg(EHCI_INT_ALLINTS, &HCOR->usbsts); + +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + /* Show the EHCI version */ + + regval16 = lpc31_swap16(HCCR->hciversion); + usbhost_vtrace2(EHCI_VTRACE2_HCIVERSION, regval16 >> 8, regval16 & 0xff); + + /* Verify that the correct number of ports is reported */ + + regval = lpc31_getreg(&HCCR->hcsparams); + nports = (regval & EHCI_HCSPARAMS_NPORTS_MASK) >> EHCI_HCSPARAMS_NPORTS_SHIFT; + + usbhost_vtrace2(EHCI_VTRACE2_HCSPARAMS, nports, regval); + DEBUGASSERT(nports == LPC31_EHCI_NRHPORT); + + /* Show the HCCPARAMS register */ + + regval = lpc31_getreg(&HCCR->hccparams); + usbhost_vtrace1(EHCI_VTRACE1_HCCPARAMS, regval); +#endif + + /* Initialize the head of the asynchronous queue/reclamation list. + * + * "In order to communicate with devices via the asynchronous schedule, + * system software must write the ASYNDLISTADDR register with the address + * of a control or bulk queue head. Software must then enable the + * asynchronous schedule by writing a one to the Asynchronous Schedule + * Enable bit in the USBCMD register. In order to communicate with devices + * via the periodic schedule, system software must enable the periodic + * schedule by writing a one to the Periodic Schedule Enable bit in the + * USBCMD register. Note that the schedules can be turned on before the + * first port is reset (and enabled)." + */ + + memset(&g_asynchead, 0, sizeof(struct lpc31_qh_s)); + physaddr = lpc31_physramaddr((uintptr_t)&g_asynchead); + g_asynchead.hw.hlp = lpc31_swap32(physaddr | QH_HLP_TYP_QH); + g_asynchead.hw.epchar = lpc31_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL); + g_asynchead.hw.overlay.nqp = lpc31_swap32(QH_NQP_T); + g_asynchead.hw.overlay.alt = lpc31_swap32(QH_NQP_T); + g_asynchead.hw.overlay.token = lpc31_swap32(QH_TOKEN_HALTED); + g_asynchead.fqp = lpc31_swap32(QTD_NQP_T); + + cp15_flush_idcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s)); + + /* Set the Current Asynchronous List Address. */ + + lpc31_putreg(lpc31_swap32(physaddr), &HCOR->asynclistaddr); + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Initialize the head of the periodic list. Since Isochronous + * endpoints are not not yet supported, each element of the + * frame list is initialized to point to the Interrupt Queue + * Head (g_intrhead). + */ + + memset(&g_intrhead, 0, sizeof(struct lpc31_qh_s)); + g_intrhead.hw.hlp = lpc31_swap32(QH_HLP_T); + g_intrhead.hw.overlay.nqp = lpc31_swap32(QH_NQP_T); + g_intrhead.hw.overlay.alt = lpc31_swap32(QH_NQP_T); + g_intrhead.hw.overlay.token = lpc31_swap32(QH_TOKEN_HALTED); + g_intrhead.hw.epcaps = lpc31_swap32(QH_EPCAPS_SSMASK(1)); + + /* Attach the periodic QH to Period Frame List */ + + physaddr = lpc31_physramaddr((uintptr_t)&g_intrhead); + for (i = 0; i < FRAME_LIST_SIZE; i++) + { + g_framelist[i] = lpc31_swap32(physaddr) | PFL_TYP_QH; + } + + /* Set the Periodic Frame List Base Address. */ + + cp15_flush_idcache((uintptr_t)&g_intrhead.hw, + (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s)); + cp15_flush_idcache((uintptr_t)g_framelist, + (uintptr_t)g_framelist + FRAME_LIST_SIZE * sizeof(uint32_t)); + + physaddr = lpc31_physramaddr((uintptr_t)g_framelist); + lpc31_putreg(lpc31_swap32(physaddr), &HCOR->periodiclistbase); +#endif + + /* Enable the asynchronous schedule and, possibly enable the periodic + * schedule and set the frame list size. + */ + + regval = lpc31_getreg(&HCOR->usbcmd); + regval &= ~(EHCI_USBCMD_HCRESET | EHCI_USBCMD_FLSIZE_MASK | + EHCI_USBCMD_FLSIZE_MASK | EHCI_USBCMD_PSEN | + EHCI_USBCMD_IAADB | EHCI_USBCMD_LRESET); + regval |= EHCI_USBCMD_ASEN; + +#ifndef CONFIG_USBHOST_INT_DISABLE + regval |= EHCI_USBCMD_PSEN; +# if FRAME_LIST_SIZE == 1024 + regval |= EHCI_USBCMD_FLSIZE_1024; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_512; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_256; +# else +# error Unsupported frame size list size +# endif +#endif + + lpc31_putreg(regval, &HCOR->usbcmd); + + /* Start the host controller by setting the RUN bit in the USBCMD regsiter. */ + + regval = lpc31_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_RUN; + lpc31_putreg(regval, &HCOR->usbcmd); + + /* Route all ports to this host controller by setting the CONFIG flag. */ + + regval = lpc31_getreg(&HCOR->configflag); + regval |= EHCI_CONFIGFLAG; + lpc31_putreg(regval, &HCOR->configflag); + + /* Wait for the EHCI to run (i.e., no longer report halted) */ + + ret = ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100*1000); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RUN_FAILED, lpc31_getreg(&HCOR->usbsts)); + return NULL; + } + + /* Interrupt Configuration ***************************************************/ + + ret = irq_attach(LPC31_IRQ_USBOTG, lpc31_ehci_interrupt); + if (ret != 0) + { + usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, LPC31_IRQ_USBOTG); + return NULL; + } + + /* Enable EHCI interrupts. Interrupts are still disabled at the level of + * the interrupt controller. + */ + + lpc31_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); + + /* Drive Vbus +5V (the smoke test) + * + * REVISIT: + * - Should be done elsewhere in OTG mode. + * - Can we postpone enabling VBUS to save power? I think it can be + * done in lpc31_enumerate() and can probably be disabled when the + * port is disconnected. + * - Some EHCI implementations require setting the power bit in the + * PORTSC register to enable power. + */ + + /* Handle root hub status change on each root port */ + + for (i = 0; i < LPC31_EHCI_NRHPORT; i++) + { + /* Enable VBUS power for the port */ + + lpc31_usbhost_vbusdrive(i, true); + up_mdelay(25); + + /* Power up the power. REVISIT: Is this necessary? The PP bit never + * gets set unless I explicitly set it here. + */ + + regval = lpc31_getreg(&HCOR->portsc[i]); + regval |= EHCI_PORTSC_PP; + lpc31_putreg(regval, &HCOR->portsc[i]); + up_mdelay(25); + } + + /* If there is a USB device in the slot at power up, then we will not + * get the status change interrupt to signal us that the device is + * connected. We need to set the initial connected state accordingly. + */ + + for (i = 0; i < LPC31_EHCI_NRHPORT; i++) + { + g_ehci.rhport[i].connected = + ((lpc31_getreg(&HCOR->portsc[i]) & EHCI_PORTSC_CCS) != 0); + } + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(LPC31_IRQ_USBOTG); /* enable USB interrupt */ + usbhost_vtrace1(EHCI_VTRACE1_INIITIALIZED, 0); + + /* Initialize and return the connection interface */ + + g_ehciconn.wait = lpc31_wait; + g_ehciconn.enumerate = lpc31_enumerate; + return &g_ehciconn; +} + +/******************************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ********************************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +FAR const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +FAR const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} +#endif /* HAVE_USBHOST_TRACE */ + +#endif /* CONFIG_LPC31_USBOTG && CONFIG_USBHOST */ diff --git a/arch/arm/src/lpc31xx/lpc31_esrndx.c b/arch/arm/src/lpc31xx/lpc31_esrndx.c new file mode 100644 index 0000000000000000000000000000000000000000..55ffd0d4db1cc709c450b973783e6591867d3724 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_esrndx.c @@ -0,0 +1,134 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_esrndx.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_esrndx + * + * Description: + * Given a clock ID, return the index of the corresponding ESR + * register (or ESRNDX_INVALID if there is no ESR associated with + * this clock ID). Indexing of ESRs differs slightly from the clock + * ID: There are 92 clock IDs but only 89 ESR regisers. There are no + * ESR registers for : + * + * + * CLKID_I2SRXBCK0 Clock ID 87: I2SRX_BCK0 + * CLKID_I2SRXBCK1, Clock ID 88: I2SRX_BCK1 + * + * and + * + * CLKID_SYSCLKO Clock ID 91: SYSCLK_O + * + ****************************************************************************/ + +int lpc31_esrndx(enum lpc31_clockid_e clkid) +{ + int esrndx = (int)clkid; + + /* There ar 89 Enable Select Registers (ESR). Indexing for these + * registers is identical to indexing to other registers (like PCR), + * except that there are no ESR registers for + * + * + * CLKID_I2SRXBCK0 Clock ID 87: I2SRX_BCK0 + * CLKID_I2SRXBCK1, Clock ID 88: I2SRX_BCK1 + * + * and + * + * CLKID_SYSCLKO Clock ID 91: SYSCLK_O + */ + + switch (clkid) + { + /* There are no ESR registers corresponding to the following + * three clocks: + */ + + case CLKID_I2SRXBCK0: + case CLKID_I2SRXBCK1: + case CLKID_SYSCLKO: + esrndx = ESRNDX_INVALID; + break; + + /* These clock IDs are a special case and need to be adjusted + * by two: + * + * CLKID_SPICLK Clock ID 89, ESR index 87 + * CLKID_SPICLKGATED Clock ID 90, ESR index 88 + */ + + case CLKID_SPICLK: + case CLKID_SPICLKGATED: + esrndx = esrndx - 2; + break; + + /* The rest of the indices match up and we don't have to do anything. */ + + default: + break; + } + + return esrndx; +} diff --git a/arch/arm/src/lpc31xx/lpc31_evntrtr.h b/arch/arm/src/lpc31xx/lpc31_evntrtr.h new file mode 100644 index 0000000000000000000000000000000000000000..6ebc46e3b3e4ceea8f5561c630999f0e635f2a9c --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_evntrtr.h @@ -0,0 +1,264 @@ +/******************************************************************************************************** + * arch/arm/src/lpc31xx/lpc31_evntrtr.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_EVNTRTR_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_EVNTRTR_H + +/******************************************************************************************************** + * Included Files + ********************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/******************************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************************/ + +/* EVNTRTR register base address offset into the APB0 domain ********************************************/ + +#define LPC31_EVNTRTR_VBASE (LPC31_APB0_VADDR+LPC31_APB0_EVNTRTR_OFFSET) +#define LPC31_EVNTRTR_PBASE (LPC31_APB0_PADDR+LPC31_APB0_EVNTRTR_OFFSET) + +/* Sizes of things */ + +#define LPC31_EVNTRTR_NBANKS 4 /* Banks b=0-3 */ +#define LPC31_EVNTRTR_NOUTPUTS 5 /* Outputs o=0-4 (incl CGU Wakeup) */ +#define LPC31_EVNTRTR_NEVENTS (32*LPC31_EVNTRTR_NBANKS) + +#define _B(b) ((b)<<2) /* Maps bank number 0-3 to word offset */ +#define _O(o) ((o)<<5) /* Maps output to bank group offset */ +#define _OB(o,b) (_O(o)+_B(b)) /* Mqpw output and bank to word offset */ + +#define EVNTRTR_EVENT(bank,bit) ((bank)<<5|bit) /* Makes a event number from a bank and bit */ +#define EVNTRTR_BANK(e) ((e)>>5) /* Maps a event to a bank */ +#define EVNTRTR_BIT(e) ((e)&0x1f) /* Maps a event to a bit */ + +/* EVNTRTR register offsets (with respect to the EVNTRTR base) ******************************************/ + + /* 0x0000-0x0bff: Reserved */ +#define LPC31_EVNTRTR_PEND_OFFSET(b) (0x0c00+_B(b)) /* Input event pending */ +#define LPC31_EVNTRTR_INTCLR_OFFSET(b) (0x0c20+_B(b)) /* Input event clear */ +#define LPC31_EVNTRTR_INTSET_OFFSET(b) (0x0c40+_B(b)) /* Input event set */ +#define LPC31_EVNTRTR_MASK_OFFSET(b) (0x0c60+_B(b)) /* Input event mask */ +#define LPC31_EVNTRTR_MASKCLR_OFFSET(b) (0x0c80+_B(b)) /* Input event mask clear */ +#define LPC31_EVNTRTR_MASKSET_OFFSET(b) (0x0ca0+_B(b)) /* Input event mask set */ +#define LPC31_EVNTRTR_APR_OFFSET(b) (0x0cc0+_B(b)) /* Input event activation polarity */ +#define LPC31_EVNTRTR_ATR_OFFSET(b) (0x0ce0+_B(b)) /* Input event activation type */ +#define LPC31_EVNTRTR_RSR_OFFSET(b) (0x0d20+_B(b)) /* Input event raw status */ +#define LPC31_EVNTRTR_INTOUT_OFFSET 0x0d40 /* State of interrupt output pins */ + /* 0x0e00-0x0ffc: Reserved */ +#define LPC31_EVNTRTR_INTOUTPEND_OFFSET(o,b) (0x1000+_OB(o,b)) /* Interrupt output 'o' pending */ +#define LPC31_EVNTRTR_CGUWKUPPEND_OFFSET(b) (0x1000+_OB(4,b)) /* cgu_wakeup pending */ +#define LPC31_EVNTRTR_INTOUTMASK_OFFSET(o,b) (0x1400+_OB(o,b)) /* Interrupt output 'o' mask */ +#define LPC31_EVNTRTR_CGUWKUPMASK_OFFSET(b) (0x1400+_OB(4,b)) /* cgu_wakeup mask */ +#define LPC31_EVNTRTR_INTOUTMASKCLR_OFFSET(o,b) (0x1800+_OB(o,b)) /* Interrupt output 'o' mask clear */ +#define LPC31_EVNTRTR_CGUWKUPMASKCLR_OFFSET(b) (0x1800+_OB(4,b)) /* cgu_wakeup mask clear */ +#define LPC31_EVNTRTR_INTOUTMASKSET_OFFSET(o,b) (0x1c00+_OB(o,b)) /* Interrupt output 'o' mask set */ +#define LPC31_EVNTRTR_CGUWKUPMASKSET_OFFSET(b) (0x1c00+_OB(4,b)) /* cgu_wakeup mask set */ + +/* EVNTRTR register (virtual) addresses *********************************************************************/ + +#define LPC31_EVNTRTR_PEND(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_PEND_OFFSET(b)) +#define LPC31_EVNTRTR_INTCLR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTCLR_OFFSET(b)) +#define LPC31_EVNTRTR_INTSET(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTSET_OFFSET(b)) +#define LPC31_EVNTRTR_MASK(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_MASK_OFFSET(b)) +#define LPC31_EVNTRTR_MASKCLR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_MASKCLR_OFFSET(b)) +#define LPC31_EVNTRTR_MASKSET(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_MASKSET_OFFSET(b)) +#define LPC31_EVNTRTR_APR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_APR_OFFSET(b)) +#define LPC31_EVNTRTR_ATR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_ATR_OFFSET(b)) +#define LPC31_EVNTRTR_RSR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_RSR_OFFSET(b)) +#define LPC31_EVNTRTR_INTOUT (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTOUT_OFFSET) +#define LPC31_EVNTRTR_INTOUTPEND(o,b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTOUTPEND_OFFSET(o,b)) +#define LPC31_EVNTRTR_CGUWKUPPEND(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_CGUWKUPPEND_OFFSET(b)) +#define LPC31_EVNTRTR_INTOUTMASK(o,b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTOUTMASK_OFFSET(o,b)) +#define LPC31_EVNTRTR_CGUWKUPMASK(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_CGUWKUPMASK_OFFSET(b)) +#define LPC31_EVNTRTR_INTOUTMASKCLR(o,b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTOUTMASKCLR_OFFSET(o,b)) +#define LPC31_EVNTRTR_CGUWKUPMASKCLR(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_CGUWKUPMASKCLR_OFFSET(b)) +#define LPC31_EVNTRTR_INTOUTMASKSET(o,b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_INTOUTMASKSET_OFFSET(o,b)) +#define LPC31_EVNTRTR_CGUWKUPMASKSET(b) (LPC31_EVNTRTR_VBASE+LPC31_EVNTRTR_CGUWKUPMASKSET_OFFSET(b) + +/* EVNTRTR event definitions ********************************************************************************/ +/* Bank 0 */ + +#define EVENTRTR_EBID6 EVNTRTR_EVENT(0,31) /* Input event from GPIO pin */ +#define EVENTRTR_EBID5 EVNTRTR_EVENT(0,30) /* Input event from GPIO pin */ +#define EVENTRTR_EBID4 EVNTRTR_EVENT(0,29) /* Input event from GPIO pin */ +#define EVENTRTR_EBID3 EVNTRTR_EVENT(0,28) /* Input event from GPIO pin */ +#define EVENTRTR_EBID2 EVNTRTR_EVENT(0,27) /* Input event from GPIO pin */ +#define EVENTRTR_EBID1 EVNTRTR_EVENT(0,26) /* Input event from GPIO pin */ +#define EVENTRTR_EBID0 EVNTRTR_EVENT(0,25) /* Input event from GPIO pin */ +#define EVENTRTR_MNANDRYBN3 EVNTRTR_EVENT(0,24) /* Input event from GPIO pin */ +#define EVENTRTR_MNANDRYBN2 EVNTRTR_EVENT(0,23) /* Input event from GPIO pin */ +#define EVENTRTR_MNANDRYBN1 EVNTRTR_EVENT(0,22) /* Input event from GPIO pin */ +#define EVENTRTR_MNANDRYBN0 EVNTRTR_EVENT(0,21) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDRWWR EVNTRTR_EVENT(0,20) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDERD EVNTRTR_EVENT(0,19) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDCSB EVNTRTR_EVENT(0,18) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDRS EVNTRTR_EVENT(0,17) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB15 EVNTRTR_EVENT(0,16) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB14 EVNTRTR_EVENT(0,15) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB13 EVNTRTR_EVENT(0,14) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB12 EVNTRTR_EVENT(0,13) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB11 EVNTRTR_EVENT(0,12) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB10 EVNTRTR_EVENT(0,11) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB9 EVNTRTR_EVENT(0,10) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB8 EVNTRTR_EVENT(0,9) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB7 EVNTRTR_EVENT(0,8) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB6 EVNTRTR_EVENT(0,7) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB5 EVNTRTR_EVENT(0,6) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB4 EVNTRTR_EVENT(0,5) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB3 EVNTRTR_EVENT(0,4) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB2 EVNTRTR_EVENT(0,3) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB1 EVNTRTR_EVENT(0,2) /* Input event from GPIO pin */ +#define EVENTRTR_MLCDDB0 EVNTRTR_EVENT(0,1) /* Input event from GPIO pin */ +#define EVENTRTR_PCMINT EVNTRTR_EVENT(0,0) /* Input event from PCM */ + +/* Bank 1 */ + +#define EVENTRTR_GPIO16 EVNTRTR_EVENT(1,31) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO15 EVNTRTR_EVENT(1,30) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO14 EVNTRTR_EVENT(1,29) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO13 EVNTRTR_EVENT(1,28) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO12 EVNTRTR_EVENT(1,27) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO11 EVNTRTR_EVENT(1,26) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO10 EVNTRTR_EVENT(1,25) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO9 EVNTRTR_EVENT(1,24) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO8 EVNTRTR_EVENT(1,23) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO7 EVNTRTR_EVENT(1,22) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO6 EVNTRTR_EVENT(1,21) /* Input event from GPIO pin */ +#define EVENTRTR_MGPIO5 EVNTRTR_EVENT(1,20) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO4 EVNTRTR_EVENT(1,19) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO3 EVNTRTR_EVENT(1,18) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO2 EVNTRTR_EVENT(1,17) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO1 EVNTRTR_EVENT(1,16) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO0 EVNTRTR_EVENT(1,15) /* Input event from GPIO pin */ +#define EVENTRTR_EBINRASBLOUT1 EVNTRTR_EVENT(1,14) /* Input event from GPIO pin */ +#define EVENTRTR_EBINCASBLOUT0 EVNTRTR_EVENT(1,13) /* Input event from GPIO pin */ +#define EVENTRTR_EBIDQM0NOE EVNTRTR_EVENT(1,12) /* Input event from GPIO pin */ +#define EVENTRTR_EBIA1CLE EVNTRTR_EVENT(1,11) /* Input event from GPIO pin */ +#define EVENTRTR_EBIA0ALE EVNTRTR_EVENT(1,10) /* Input event from GPIO pin */ +#define EVENTRTR_EBINWE EVNTRTR_EVENT(1,9) /* Input event from GPIO pin */ +#define EVENTRTR_EBID15 EVNTRTR_EVENT(1,8) /* Input event from GPIO pin */ +#define EVENTRTR_EBID14 EVNTRTR_EVENT(1,7) /* Input event from GPIO pin */ +#define EVENTRTR_EBID13 EVNTRTR_EVENT(1,6) /* Input event from GPIO pin */ +#define EVENTRTR_EBID12 EVNTRTR_EVENT(1,5) /* Input event from GPIO pin */ +#define EVENTRTR_EBID11 EVNTRTR_EVENT(1,4) /* Input event from GPIO pin */ +#define EVENTRTR_EBID10 EVNTRTR_EVENT(1,3) /* Input event from GPIO pin */ +#define EVENTRTR_EBID9 EVNTRTR_EVENT(1,2) /* Input event from GPIO pin */ +#define EVENTRTR_EBID8 EVNTRTR_EVENT(1,1) /* Input event from GPIO pin */ +#define EVENTRTR_EBID7 EVNTRTR_EVENT(1,0) /* Input event from GPIO pin */ + +/* Bank 2 */ + +#define EVENTRTR_PWMDATA EVNTRTR_EVENT(2,31) /* Input event from GPIO pin */ +#define EVENTRTR_I2CSCL1 EVNTRTR_EVENT(2,30) /* Input event from GPIO pin */ +#define EVENTRTR_I2CSDA1 EVNTRTR_EVENT(2,29) /* Input event from GPIO pin */ +#define EVENTRTR_CLK256FSO EVNTRTR_EVENT(2,28) /* Input event from GPIO pin */ +#define EVENTRTR_I2STXWS1 EVNTRTR_EVENT(2,27) /* Input event from GPIO pin */ +#define EVENTRTR_I2STXBCK1 EVNTRTR_EVENT(2,26) /* Input event from GPIO pin */ +#define EVENTRTR_I2STXDATA1 EVNTRTR_EVENT(2,25) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXWS1 EVNTRTR_EVENT(2,24) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXBCK1 EVNTRTR_EVENT(2,23) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXDATA1 EVNTRTR_EVENT(2,22) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXWS0 EVNTRTR_EVENT(2,21) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXDATA0 EVNTRTR_EVENT(2,20) /* Input event from GPIO pin */ +#define EVENTRTR_I2SRXBCK0 EVNTRTR_EVENT(2,19) /* Input event from GPIO pin */ +#define EVENTRTR_MI2STXWS0 EVNTRTR_EVENT(2,18) /* Input event from GPIO pin */ +#define EVENTRTR_MI2STXDATA0 EVNTRTR_EVENT(2,17) /* Input event from GPIO pin */ +#define EVENTRTR_MI2STXBCK0 EVNTRTR_EVENT(2,16) /* Input event from GPIO pin */ +#define EVENTRTR_MI2STXCLK0 EVNTRTR_EVENT(2,15) /* Input event from GPIO pin */ +#define EVENTRTR_MUARTRTSN EVNTRTR_EVENT(2,14) /* Input event from GPIO pin */ +#define EVENTRTR_MUARTCTSN EVNTRTR_EVENT(2,13) /* Input event from GPIO pin */ +#define EVENTRTR_UARTTXD EVNTRTR_EVENT(2,12) /* Input event from GPIO pin */ +#define EVENTRTR_UARTRXD EVNTRTR_EVENT(2,11) /* Input event from GPIO pin */ +#define EVENTRTR_SPICSOUT0 EVNTRTR_EVENT(2,10) /* Input event from GPIO pin */ +#define EVENTRTR_SPISCK EVNTRTR_EVENT(2,9) /* Input event from GPIO pin */ +#define EVENTRTR_SPICSIN EVNTRTR_EVENT(2,8) /* Input event from GPIO pin */ +#define EVENTRTR_SPIMOSI EVNTRTR_EVENT(2,7) /* Input event from GPIO pin */ +#define EVENTRTR_SPIMISO EVNTRTR_EVENT(2,6) /* Input event from GPIO pin */ +#define EVENTRTR_NANDNCS3 EVNTRTR_EVENT(2,5) /* Input event from GPIO pin */ +#define EVENTRTR_NANDNCS2 EVNTRTR_EVENT(2,4) /* Input event from GPIO pin */ +#define EVENTRTR_NANDNCS1 EVNTRTR_EVENT(2,3) /* Input event from GPIO pin */ +#define EVENTRTR_NANDNCS0 EVNTRTR_EVENT(2,2) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO18 EVNTRTR_EVENT(2,1) /* Input event from GPIO pin */ +#define EVENTRTR_GPIO17 EVNTRTR_EVENT(2,0) /* Input event from GPIO pin */ + +/* Bank 3 */ + /* 30-31: Reserved */ +#define EVENTRTR_ISRAM1MRCFINISHED EVNTRTR_EVENT(3,29) /* ISRAM1 redundancy controller event */ +#define EVENTRTR_ISRAM0MRCFINISHED EVNTRTR_EVENT(3,28) /* ISRAM0 redundancy controller event */ +#define EVENTRTR_USBID EVNTRTR_EVENT(3,27) /* Input event from GPIO pin */ +#define EVENTRTR_USBOTGVBUSPWREN EVNTRTR_EVENT(3,26) /* Input event from USB */ +#define EVENTRTR_USBATXPLLLOCK EVNTRTR_EVENT(3,25) /* USB PLL lock event */ +#define EVENTRTR_USBOTGAHBNEEDCLK EVNTRTR_EVENT(3,24) /* Input event from USB */ +#define EVENTRTR_USBVBUS EVNTRTR_EVENT(3,23) /* Input event from USB VBUS pin */ +#define EVENTRTR_MCICLK EVNTRTR_EVENT(3,22) /* Input event from GPIO pin */ +#define EVENTRTR_MCICMD EVNTRTR_EVENT(3,21) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT7 EVNTRTR_EVENT(3,20) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT6 EVNTRTR_EVENT(3,19) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT5 EVNTRTR_EVENT(3,18) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT4 EVNTRTR_EVENT(3,17) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT3 EVNTRTR_EVENT(3,16) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT2 EVNTRTR_EVENT(3,15) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT1 EVNTRTR_EVENT(3,14) /* Input event from GPIO pin */ +#define EVENTRTR_MCIDAT0 EVNTRTR_EVENT(3,13) /* Input event from GPIO pin */ +#define EVENTRTR_ARM926LPNIRQ EVNTRTR_EVENT(3,12) /* Reflects nIRQ signal to ARM core */ +#define EVENTRTR_ARM926LPNFIQ EVNTRTR_EVENT(3,11) /* Reflects nFIQ signal to ARM core */ +#define EVENTRTR_I2C1SCLN EVNTRTR_EVENT(3,10) /* Input event from I2C1 */ +#define EVENTRTR_I2C0SCLN EVNTRTR_EVENT(3,9) /* Input event from I2C0 */ +#define EVENTRTR_UART EVNTRTR_EVENT(3,8) /* Input event from UART */ +#define EVENTRTR_WDOGM0 EVNTRTR_EVENT(3,7) /* Input event from Watchdog Timer */ +#define EVENTRTR_ADCINT EVNTRTR_EVENT(3,6) /* Input event from ADC */ +#define EVENTRTR_TIMER3INTCT1 EVNTRTR_EVENT(3,5) /* Input event from Timer 3 */ +#define EVENTRTR_TIMER2INTCT1 EVNTRTR_EVENT(3,4) /* Input event from Timer 2 */ +#define EVENTRTR_TIMER1INTCT1 EVNTRTR_EVENT(3,3) /* Input event from Timer 1 */ +#define EVENTRTR_TIMER0INTCT1 EVNTRTR_EVENT(3,2) /* Input event from Timer 0 */ +#define EVENTRTR_GPIO20 EVNTRTR_EVENT(3,1) /* Input event from GPIO20 */ +#define EVENTRTR_GPIO19 EVNTRTR_EVENT(3,0) /* Input event from GPIO19 */ + +/******************************************************************************************************** + * Public Types + ********************************************************************************************************/ + +/******************************************************************************************************** + * Public Data + ********************************************************************************************************/ + +/******************************************************************************************************** + * Public Functions + ********************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_EVNTRTR_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_fdcndx.c b/arch/arm/src/lpc31xx/lpc31_fdcndx.c new file mode 100644 index 0000000000000000000000000000000000000000..0bc9c3a5560584a91c60fa53f85478cbf3f0ba98 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_fdcndx.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_fdcndx.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The select register in the ESR registers vary in width from 1-3 bits. + * Below is a macro to select the widest case (which is OK because the + * undefined bits will be read as zero). Within the field, bits 0-7 to + * indicate the offset from the base FDC index. + */ + +#define CGU_ESRSEL(n) (((n)>>1)&7) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_fdcbase[CGU_NDOMAINS] = +{ + FRACDIV_BASE0_LOW, /* Domain 0: SYS_BASE */ + FRACDIV_BASE1_LOW, /* Domain 1: AHB0APB0_BASE */ + FRACDIV_BASE2_LOW, /* Domain 2: AHB0APB1_BASE */ + FRACDIV_BASE3_LOW, /* Domain 3: AHB0APB2_BASE */ + FRACDIV_BASE4_LOW, /* Domain 4: AHB0APB3_BASE */ + FRACDIV_BASE5_LOW, /* Domain 5: PCM_BASE */ + FRACDIV_BASE6_LOW, /* Domain 6: UART_BASE */ + FRACDIV_BASE7_LOW, /* Domain 7: CLK1024FS_BASE */ + 0, /* Domain 8: BCK0_BASE (no ESR register) */ + 0, /* Domain 9: BCK1_BASE (no ESR register) */ + FRACDIV_BASE10_LOW, /* Domain 10: SPI_BASE */ + 0, /* Domain 11: SYSCLKO_BASE (no ESR register) */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_fdcndx + * + * Description: + * Given a clock ID and its domain ID, return the index of the + * corresponding fractional divider register (or FDCNDX_INVALID if + * there is no fractional divider associated with this clock). + * + ****************************************************************************/ + +int lpc31_fdcndx(enum lpc31_clockid_e clkid, enum lpc31_domainid_e dmnid) +{ + int esrndx; + int fdcndx = FDCNDX_INVALID; + + /* Check if there is an ESR register associate with this clock ID */ + + esrndx = lpc31_esrndx(clkid); + if (esrndx != ESRNDX_INVALID) + { + /* Read the clock's ESR to get the fractional divider */ + + uint32_t regval = getreg32(LPC31_CGU_ESR(esrndx)); + + /* Check if any fractional divider is enabled for this clock. */ + + if ((regval & CGU_ESR_ESREN) != 0) + { + /* Yes.. The FDC index is an offset from this fractional + * divider base for this domain. + */ + + fdcndx = CGU_ESRSEL(regval) + (int)g_fdcbase[dmnid]; + } + } + + return fdcndx; +} diff --git a/arch/arm/src/lpc31xx/lpc31_fdivinit.c b/arch/arm/src/lpc31xx/lpc31_fdivinit.c new file mode 100644 index 0000000000000000000000000000000000000000..488a802f901cdeb42a838c198a35583de7108cf0 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_fdivinit.c @@ -0,0 +1,204 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_fdivinit.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgu.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_bitwidth + * + * Description: + * Find the bit width of a msub or madd value. This will be use to + * extend the msub or madd values. To minimize power consumption, the + * lpc313x user manual recommends that madd and msub be shifted right + * to have as many trailing zero's as possible. This function detmines + * the pre-shifted with of one of the msub or madd values. + * + * EXAMPLE: + * + * Say an input frequency of 13 MHz is given while a frequency of 12 + * MHz is required. In this case we want a frequency + * + * f’ = 12/13 × f + * + * So n = 12 and m = 13. This then gives + * + * madd = m - n = 13 - 12 = 1 + * msub = -n = -12 + * + * In order to minimize power consumption madd and msub must be as + * large as possible. The limit of their values is determined by the + * madd/msub bit width. In this case msub is the largest value, + * in order to express -12, five bits are required. However since msub is + * always negative the fractional divider does not need the sign bit, leaving + * 4 bits. If madd/msub bit width has been set to say 8 bits, it is allowed + * to shift 4 bits, giving: + * + * msub’ = -(12<<4)= -12 × 24 = -12 × 16 = -192 + * madd’ = 1<<4 = 24 = 16 + * + ****************************************************************************/ + +static inline unsigned int +lpc31_bitwidth(unsigned int value, unsigned int fdwid) +{ + unsigned int width = 0; + int bit; + + /* Examine bits from the most significant down */ + + for (bit = fdwid-1; bit >= 0; bit--) + { + /* Is this bit set? If so, then the width of the value is 0 to bit, + * or bit+1. + */ + + if ((value & (1 << bit)) != 0) + { + width = bit + 1; + break; + } + } + return width; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_fdivinit + * + * Description: + * Enable and configure (or disable) a fractional divider. + * + ****************************************************************************/ + +uint32_t lpc31_fdivinit(int fdcndx, + const struct lpc31_fdivconfig_s *fdiv, bool enable) +{ + uint32_t regaddr; + uint32_t regval; + unsigned int fdshift; + unsigned int fdwid; + unsigned int fdmask; + unsigned int maddshift; + unsigned int msubshift; + int madd; + int msub; + + /* Calculating the (unshifted) divider values.To minimize power + * consumption, the lpc313x user manual recommends that madd and msub + * be shifted right to have as many trailing zero's as possible. + */ + + madd = fdiv->m - fdiv->n; + msub = -fdiv->n; + + /* Determine the width of the madd and msub fields in the fractional divider + * register. They are all 8-bits in width except for fractional divider 17. + */ + + fdwid = CGU_FDC_FIELDWIDTH; + maddshift = CGU_FDC_MADD_SHIFT; + msubshift = CGU_FDC_MSUB_SHIFT; + + if (fdcndx == 17) + { + /* For fractional divider 17, the msub/madd field width is 13 */ + + fdwid = CGU_FDC17_FIELDWIDTH; + maddshift = CGU_FDC17_MADD_SHIFT; + msubshift = CGU_FDC17_MSUB_SHIFT; + } + + /* Find maximum bit width of madd & msub. Here we calculate the width of the OR + * of the two values. The width of the OR will be the width of the wider value + */ + + fdshift = fdwid - lpc31_bitwidth((unsigned int)madd | (unsigned int)fdiv->n, fdwid); + + /* Calculate the fractional divider register values */ + + fdmask = (1 << fdwid) - 1; + madd = (madd << fdshift) & fdmask; + msub = (msub << fdshift) & fdmask; + regval = (madd << maddshift) | (msub << msubshift); + + /* Check if 50% duty cycle is needed for this divider */ + + if (fdiv->stretch) + { + regval |= CGU_FDC_STRETCH; + } + + /* Check if we should enable the divider immediately */ + + if (enable) + { + regval |= CGU_FDC_RUN; + } + + /* Finally configure the divider */ + + regaddr = LPC31_CGU_FDC(fdcndx); + putreg32(regval, regaddr); + return regval; +} diff --git a/arch/arm/src/lpc31xx/lpc31_freqin.c b/arch/arm/src/lpc31xx/lpc31_freqin.c new file mode 100644 index 0000000000000000000000000000000000000000..3540592ac5e68e76ec5e2a287cc6b2a6f1fb0be7 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_freqin.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_freqin.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This array provides the programmed frequency of every input source. The + * board FFAST input crystal frequency is the only value known initially. + * Additional frequencies will be added to the table as they are determined + */ + +uint32_t g_boardfreqin[CGU_NFREQIN] = +{ + BOARD_FREQIN_FFAST, /* Index=CGU_FREQIN_FFAST */ + 0, /* Index=CGU_FREQIN_I2SRXBCK0 */ + 0, /* Index=CGU_FREQIN_I2SRXWS0 */ + 0, /* Index=CGU_FREQIN_I2SRXBCK1 */ + 0, /* Index=CGU_FREQIN_I2SRXWS1 */ + 0, /* Index=CGU_FREQIN_HPPLL0 (Audio/I2S PLL) */ + 0 /* Index=CGU_FREQIN_HPPLL1 (System PLL) */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/lpc31xx/lpc31_i2c.c b/arch/arm/src/lpc31xx/lpc31_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..79d9667a9df9a96a4d3b23fcdef6eefc7f5983c1 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_i2c.c @@ -0,0 +1,619 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_i2c.c + * + * Author: David Hewson + * + * Copyright (C) 2010-2011, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc31_i2c.h" +#include "lpc31_evntrtr.h" +#include "lpc31_syscreg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define I2C_TIMEOUT ((20 * CLK_TCK) / 1000) /* 20 mS */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +struct lpc31_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t clkid; /* Clock for this device */ + uint16_t rstid; /* Reset for this device */ + uint16_t irqid; /* IRQ for this device */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* Watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ + unsigned int nmsg; /* number of transfer remaining */ + + uint16_t header[3]; /* I2C address header */ + uint16_t hdrcnt; /* number of bytes of header */ + uint16_t wrcnt; /* number of bytes sent to tx fifo */ + uint16_t rdcnt; /* number of bytes read from rx fifo */ +}; + +#define I2C_STATE_DONE 0 +#define I2C_STATE_START 1 +#define I2C_STATE_HEADER 2 +#define I2C_STATE_TRANSFER 3 + +static struct lpc31_i2cdev_s i2cdevices[2]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int i2c_interrupt(int irq, FAR void *context); +static void i2c_progress(struct lpc31_i2cdev_s *priv); +static void i2c_timeout(int argc, uint32_t arg, ...); +static void i2c_hwreset(struct lpc31_i2cdev_s *priv); +static void i2c_setfrequency(struct lpc31_i2cdev_s *priv, uint32_t frequency); +static int i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct i2c_ops_s lpc31_i2c_ops = +{ + .transfer = i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = i2c_reset +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void i2c_setfrequency(struct lpc31_i2cdev_s *priv, uint32_t frequency) +{ + if (frequency != priv->frequency) + { + uint32_t freq = lpc31_clkfreq(priv->clkid, DOMAINID_AHB0APB1); + + if (freq > 100000) + { + /* asymetric per 400Khz I2C spec */ + + putreg32(((47 * freq) / (83 + 47)) / frequency, + priv->base + LPC31_I2C_CLKHI_OFFSET); + putreg32(((83 * freq) / (83 + 47)) / frequency, + priv->base + LPC31_I2C_CLKLO_OFFSET); + } + else + { + /* 50/50 mark space ratio */ + + putreg32(((50 * freq) / 100) / frequency, + priv->base + LPC31_I2C_CLKLO_OFFSET); + putreg32(((50 * freq) / 100) / frequency, + priv->base + LPC31_I2C_CLKHI_OFFSET); + } + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int i2c_interrupt(int irq, FAR void *context) +{ + if (irq == LPC31_IRQ_I2C0) + { + i2c_progress(&i2cdevices[0]); + } + + if (irq == LPC31_IRQ_I2C1) + { + i2c_progress(&i2cdevices[1]); + } + + return OK; +} + +/**************************************************************************** + * Name: i2c_progress + * + * Description: + * Progress any remaining I2C transfers + * + ****************************************************************************/ + +static void i2c_progress(struct lpc31_i2cdev_s *priv) +{ + struct i2c_msg_s *msg; + uint32_t stat, ctrl; + + stat = getreg32(priv->base + LPC31_I2C_STAT_OFFSET); + + /* Were there arbitration problems? */ + + if ((stat & I2C_STAT_AFI) != 0) + { + /* Perform a soft reset */ + + i2c_hwreset(priv); + + /* FIXME: automatic retry? */ + + priv->state = I2C_STATE_DONE; + sem_post(&priv->wait); + return; + } + + while (priv->nmsg > 0) + { + ctrl = I2C_CTRL_NAIE | I2C_CTRL_AFIE | I2C_CTRL_TDIE; + msg = priv->msgs; + + switch (priv->state) + { + case I2C_STATE_START: + if ((msg->flags & I2C_M_TEN) != 0) + { + priv->header[0] = I2C_TX_START | 0xF0 | ((msg->addr & 0x300) >> 7); + priv->header[1] = msg->addr & 0xFF; + priv->hdrcnt = 2; + if (msg->flags & I2C_M_READ) + { + priv->header[2] = priv->header[0] | 1; + priv->hdrcnt++; + } + } + else + { + priv->header[0] = I2C_TX_START | (msg->addr << 1) | (msg->flags & I2C_M_READ); + priv->hdrcnt = 1; + } + + putreg32(ctrl, priv->base + LPC31_I2C_CTRL_OFFSET); + + priv->state = I2C_STATE_HEADER; + priv->wrcnt = 0; + /* DROP THROUGH */ + + case I2C_STATE_HEADER: + while ((priv->wrcnt != priv->hdrcnt) && (stat & I2C_STAT_TFF) == 0) + { + putreg32(priv->header[priv->wrcnt], priv->base + LPC31_I2C_TX_OFFSET); + priv->wrcnt++; + + stat = getreg32(priv->base + LPC31_I2C_STAT_OFFSET); + } + + if (priv->wrcnt < priv->hdrcnt) + { + /* Enable Tx FIFO Not Full Interrupt */ + + putreg32(ctrl | I2C_CTRL_TFFIE, priv->base + LPC31_I2C_CTRL_OFFSET); + goto out; + } + + priv->state = I2C_STATE_TRANSFER; + priv->wrcnt = 0; + priv->rdcnt = 0; + /* DROP THROUGH */ + + case I2C_STATE_TRANSFER: + if (msg->flags & I2C_M_READ) + { + while ((priv->rdcnt != msg->length) && (stat & I2C_STAT_RFE) == 0) + { + msg->buffer[priv->rdcnt] = getreg32 (priv->base + LPC31_I2C_RX_OFFSET); + priv->rdcnt++; + + stat = getreg32(priv->base + LPC31_I2C_STAT_OFFSET); + } + + if (priv->rdcnt < msg->length) + { + /* Not all data received, fill the Tx FIFO with more dummies */ + + while ((priv->wrcnt != msg->length) && (stat & I2C_STAT_TFF) == 0) + { + if ((priv->wrcnt + 1) == msg->length && priv->nmsg == 1) + { + putreg32(I2C_TX_STOP, priv->base + LPC31_I2C_TX_OFFSET); + } + else + { + putreg32(0, priv->base + LPC31_I2C_TX_OFFSET); + } + + priv->wrcnt++; + + stat = getreg32(priv->base + LPC31_I2C_STAT_OFFSET); + } + + if (priv->wrcnt < msg->length) + { + /* Enable Tx FIFO not full and Rx Fifo Avail Interrupts */ + + putreg32(ctrl | I2C_CTRL_TFFIE | I2C_CTRL_RFDAIE, priv->base + LPC31_I2C_CTRL_OFFSET); + } + else + { + /* Enable Rx Fifo Avail Interrupts */ + + putreg32(ctrl | I2C_CTRL_RFDAIE, priv->base + LPC31_I2C_CTRL_OFFSET); + } + goto out; + } + } + else /* WRITE */ + { + while ((priv->wrcnt != msg->length) && (stat & I2C_STAT_TFF) == 0) + { + if ((priv->wrcnt + 1) == msg->length && priv->nmsg == 1) + { + putreg32(I2C_TX_STOP | msg->buffer[priv->wrcnt], priv->base + LPC31_I2C_TX_OFFSET); + } + else + { + putreg32(msg->buffer[priv->wrcnt], priv->base + LPC31_I2C_TX_OFFSET); + } + + priv->wrcnt++; + + stat = getreg32(priv->base + LPC31_I2C_STAT_OFFSET); + } + + if (priv->wrcnt < msg->length) + { + /* Enable Tx Fifo not full Interrupt */ + + putreg32(ctrl | I2C_CTRL_TFFIE, priv->base + LPC31_I2C_CTRL_OFFSET); + goto out; + } + } + + /* Transfer completed, move onto the next one */ + + priv->state = I2C_STATE_START; + + if (--priv->nmsg == 0) + { + /* Final transfer, wait for Transmit Done Interrupt */ + + putreg32(ctrl, priv->base + LPC31_I2C_CTRL_OFFSET); + goto out; + } + + priv->msgs++; + break; + } + } + +out: + if (stat & I2C_STAT_TDI) + { + putreg32(I2C_STAT_TDI, priv->base + LPC31_I2C_STAT_OFFSET); + + /* You'd expect the NAI bit to be set when no acknowledge was + * received - but it gets cleared whenever a write it done to + * the TXFIFO - so we've gone and cleared it while priming the + * rest of the transfer! + */ + + if ((stat = getreg32(priv->base + LPC31_I2C_TXFL_OFFSET)) != 0) + { + if (priv->nmsg == 0) + { + priv->nmsg++; + } + + i2c_hwreset(priv); + } + + priv->state = I2C_STATE_DONE; + sem_post(&priv->wait); + } +} + +/**************************************************************************** + * Name: i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) arg; + + irqstate_t flags = enter_critical_section(); + + if (priv->state != I2C_STATE_DONE) + { + /* If there's data remaining in the TXFIFO, then ensure at least + * one transfer has failed to complete. + */ + + if (getreg32(priv->base + LPC31_I2C_TXFL_OFFSET) != 0) + { + if (priv->nmsg == 0) + { + priv->nmsg++; + } + } + + /* Soft reset the USB controller */ + + i2c_hwreset(priv); + + /* Mark the transfer as finished */ + + priv->state = I2C_STATE_DONE; + sem_post(&priv->wait); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: i2c_hwreset + * + * Description: + * Perform a soft reset of the I2C controller + * + ****************************************************************************/ + +static void i2c_hwreset(struct lpc31_i2cdev_s *priv) +{ + putreg32(I2C_CTRL_RESET, priv->base + LPC31_I2C_CTRL_OFFSET); + + /* Wait for Reset to complete */ + + while ((getreg32(priv->base + LPC31_I2C_CTRL_OFFSET) & I2C_CTRL_RESET) != 0) + ; +} + +/**************************************************************************** + * Name: i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev; + irqstate_t flags; + int ret; + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + flags = enter_critical_section(); + + /* Set up for the transfer */ + + priv->state = I2C_STATE_START; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + i2c_setfrequency(priv, msgs->frequency); + + /* Start the transfer */ + + i2c_progress(priv); + + /* Start a watchdog to timeout the transfer if the bus is locked up... */ + + wd_start(priv->timeout, I2C_TIMEOUT, i2c_timeout, 1, (uint32_t)priv); + + /* Wait for the transfer to complete */ + + while (priv->state != I2C_STATE_DONE) + { + sem_wait(&priv->wait); + } + + wd_cancel(priv->timeout); + ret = count - priv->nmsg; + + leave_critical_section(flags); + sem_post(&priv->mutex); + return ret; +} + +/************************************************************************************ + * Name: i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc31_i2cbus_initialize(int port) +{ + struct lpc31_i2cdev_s *priv = &i2cdevices[port]; + + priv->base = (port == 0) ? LPC31_I2C0_VBASE : LPC31_I2C1_VBASE; + priv->clkid = (port == 0) ? CLKID_I2C0PCLK : CLKID_I2C1PCLK; + priv->rstid = (port == 0) ? RESETID_I2C0RST : RESETID_I2C1RST; + priv->irqid = (port == 0) ? LPC31_IRQ_I2C0 : LPC31_IRQ_I2C1; + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + /* Enable I2C system clocks */ + + lpc31_enableclock(priv->clkid); + + /* Reset I2C blocks */ + + lpc31_softreset(priv->rstid); + + /* Soft reset the device */ + + i2c_hwreset(priv); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, i2c_interrupt); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc31_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc31_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc31_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *)dev; + + /* Disable All Interrupts, soft reset the device */ + + i2c_hwreset(priv); + + /* Detach Interrupt Handler */ + + irq_detach(priv->irqid); + + /* Reset I2C blocks */ + + lpc31_softreset(priv->rstid); + + /* Disable I2C system clocks */ + + lpc31_disableclock(priv->clkid); + return OK; +} diff --git a/arch/arm/src/lpc31xx/lpc31_i2c.h b/arch/arm/src/lpc31xx/lpc31_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..10280a577311f83d04b8875b43a37175ca793e2f --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_i2c.h @@ -0,0 +1,236 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_i2c.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_I2C_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_I2C_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* I2C register base address offset into the APB1 domain ****************************************/ + +#define LPC31_I2C0_VBASE (LPC31_APB1_VADDR+LPC31_APB1_I2C0_OFFSET) +#define LPC31_I2C0_PBASE (LPC31_APB1_PADDR+LPC31_APB1_I2C0_OFFSET) + +#define LPC31_I2C1_VBASE (LPC31_APB1_VADDR+LPC31_APB1_I2C1_OFFSET) +#define LPC31_I2C1_PBASE (LPC31_APB1_PADDR+LPC31_APB1_I2C1_OFFSET) + +/* I2C register offsets (with respect to the I2C base) ******************************************/ + +#define LPC31_I2C_RX_OFFSET 0x00 /* I2C RX Data FIFO */ +#define LPC31_I2C_TX_OFFSET 0x00 /* I2C TX Data FIFO */ +#define LPC31_I2C_STAT_OFFSET 0x04 /* I2C Status Register */ +#define LPC31_I2C_CTRL_OFFSET 0x08 /* I2C Control Register */ +#define LPC31_I2C_CLKHI_OFFSET 0x0c /* I2C Clock Divider high */ +#define LPC31_I2C_CLKLO_OFFSET 0x10 /* I2C Clock Divider low */ +#define LPC31_I2C_ADR_OFFSET 0x14 /* I2C Slave Address */ +#define LPC31_I2C_RXFL_OFFSET 0x18 /* I2C Rx FIFO level */ +#define LPC31_I2C_TXFL_OFFSET 0x1c /* I2C Tx FIFO level */ +#define LPC31_I2C_RXB_OFFSET 0x20 /* I2C Number of bytes received */ +#define LPC31_I2C_TXB_OFFSET 0x24 /* I2C Number of bytes transmitted */ +#define LPC31_I2C_STX_OFFSET 0x28 /* Slave Transmit FIFO */ +#define LPC31_I2C_STXFL_OFFSET 0x2c /* Slave Transmit FIFO level */ + +/* I2C register (virtual) addresses *************************************************************/ + +#define LPC31_I2C0_RX (LPC31_I2C0_VBASE+LPC31_I2C_RX_OFFSET) +#define LPC31_I2C0_TX (LPC31_I2C0_VBASE+LPC31_I2C_TX_OFFSET) +#define LPC31_I2C0_STAT (LPC31_I2C0_VBASE+LPC31_I2C_STAT_OFFSET) +#define LPC31_I2C0_CTRL (LPC31_I2C0_VBASE+LPC31_I2C_CTRL_OFFSET) +#define LPC31_I2C0_CLKHI (LPC31_I2C0_VBASE+LPC31_I2C_CLKHI_OFFSET) +#define LPC31_I2C0_CLKLO (LPC31_I2C0_VBASE+LPC31_I2C_CLKLO_OFFSET) +#define LPC31_I2C0_ADR (LPC31_I2C0_VBASE+LPC31_I2C_ADR_OFFSET) +#define LPC31_I2C0_RXFL (LPC31_I2C0_VBASE+LPC31_I2C_RXFL_OFFSET) +#define LPC31_I2C0_TXFL (LPC31_I2C0_VBASE+LPC31_I2C_TXFL_OFFSET) +#define LPC31_I2C0_RXB (LPC31_I2C0_VBASE+LPC31_I2C_RXB_OFFSET) +#define LPC31_I2C0_TXB (LPC31_I2C0_VBASE+LPC31_I2C_TXB_OFFSET) +#define LPC31_I2C0_STX (LPC31_I2C0_VBASE+LPC31_I2C_STX_OFFSET) +#define LPC31_I2C0_STXFL (LPC31_I2C0_VBASE+LPC31_I2C_STXFL_OFFSET) + +#define LPC31_I2C1_RX (LPC31_I2C1_VBASE+LPC31_I2C_RX_OFFSET) +#define LPC31_I2C1_TX (LPC31_I2C1_VBASE+LPC31_I2C_TX_OFFSET) +#define LPC31_I2C1_STAT (LPC31_I2C1_VBASE+LPC31_I2C_STAT_OFFSET) +#define LPC31_I2C1_CTRL (LPC31_I2C1_VBASE+LPC31_I2C_CTRL_OFFSET) +#define LPC31_I2C1_CLKHI (LPC31_I2C1_VBASE+LPC31_I2C_CLKHI_OFFSET) +#define LPC31_I2C1_CLKLO (LPC31_I2C1_VBASE+LPC31_I2C_CLKLO_OFFSET) +#define LPC31_I2C1_ADR (LPC31_I2C1_VBASE+LPC31_I2C_ADR_OFFSET) +#define LPC31_I2C1_RXFL (LPC31_I2C1_VBASE+LPC31_I2C_RXFL_OFFSET) +#define LPC31_I2C1_TXFL (LPC31_I2C1_VBASE+LPC31_I2C_TXFL_OFFSET) +#define LPC31_I2C1_RXB (LPC31_I2C1_VBASE+LPC31_I2C_RXB_OFFSET) +#define LPC31_I2C1_TXB (LPC31_I2C1_VBASE+LPC31_I2C_TXB_OFFSET) +#define LPC31_I2C1_STX (LPC31_I2C1_VBASE+LPC31_I2C_STX_OFFSET) +#define LPC31_I2C1_STXFL (LPC31_I2C1_VBASE+LPC31_I2C_STXFL_OFFSET) + +/* I2C register bit definitions *****************************************************************/ + +/* I2Cn RX Data FIFO I2C0_RX, address 0x1300a000, I2C1_RX, address 0x1300a400 */ + +#define I2C_RX_DATA_SHIFT (0) /* Bits 0-7: RxData Receive FIFO data bits */ +#define I2C_RX_DATA_MASK (0xff << I2C_RX_DATA_HIFT) + +/* I2Cn TX Data FIFO I2C0_TX, 0x1300a000, I2C1_TX, address 0x1300a400 */ + +#define I2C_TX_STOP (1 << 9) /* Bit 9: Issue STOP condition after transmitting byte */ +#define I2C_TX_START (1 << 8) /* Bit 8: Issue START condition before transmitting byte */ +#define I2C_TX_DATA_SHIFT (0) /* Bits 0-7: TxData Transmit FIFO data bits */ +#define I2C_TX_DATA_MASK (0xff << I2C_TX_DATA_SHIFT) + +/* I2Cn Status register I2C0_STAT, address 0x1300a004, I2C1_STAT, address 0x1300a404 */ + +#define I2C_STAT_TFES (1 << 13) /* Bit 13: Slave Transmit FIFO Empty */ +#define I2C_STAT_TFFS (1 << 12) /* Bit 12: Slave Transmit FIFO Full */ +#define I2C_STAT_TFE (1 << 11) /* Bit 11: Transmit FIFO Empty */ +#define I2C_STAT_TFF (1 << 10) /* Bit 10: Transmit FIFO Full */ +#define I2C_STAT_RFE (1 << 9) /* Bit 9: Receive FIFO Empty */ +#define I2C_STAT_RFF (1 << 8) /* Bit 8: Receive FIFO Full */ +#define I2C_STAT_SDA (1 << 7) /* Bit 7: The current value of the SDA signal */ +#define I2C_STAT_SCL (1 << 6) /* Bit 6: The current value of the SCL signal */ +#define I2C_STAT_ACTIVE (1 << 5) /* Bit 5: Indicates whether the bus is busy */ +#define I2C_STAT_DRSI (1 << 4) /* Bit 4: Slave Data Request Interrupt */ +#define I2C_STAT_DRMI (1 << 3) /* Bit 3: Master Data Request Interrupt */ +#define I2C_STAT_NAI (1 << 2) /* Bit 2: No Acknowledge Interrupt */ +#define I2C_STAT_AFI (1 << 1) /* Bit 1: Arbitration Failure Interrupt */ +#define I2C_STAT_TDI (1 << 0) /* Bit 0: Transaction Done Interrupt */ + +/* I2Cn Control register I2C0_CTRL, address 0x1300a008, I2C1_CTRL, address 0x1300a408 */ + +#define I2C_CTRL_TFFSIE (1 << 10) /* Bit 10: Slave Transmit FIFO Not Full Interrupt Enable */ +#define I2C_CTRL_SEVEN (1 << 9) /* Bit 9: Seven-bit slave address */ +#define I2C_CTRL_RESET (1 << 8) /* Bit 8: Soft Reset */ +#define I2C_CTRL_TFFIE (1 << 7) /* Bit 7: Transmit FIFO Not Full Interrupt Enable */ +#define I2C_CTRL_RFDAIE (1 << 6) /* Bit 6: Receive FIFO Data Available Interrupt Enable */ +#define I2C_CTRL_RFFIE (1 << 5) /* Bit 5: Receive FIFO Full Interrupt Enable */ +#define I2C_CTRL_DRSIE (1 << 4) /* Bit 4: Data Request Slave Transmitter Interrupt Enable */ +#define I2C_CTRL_DRMIE (1 << 3) /* Bit 3: Data Request Master Transmitter Interrupt Enable */ +#define I2C_CTRL_NAIE (1 << 2) /* Bit 2: Transmitter No Acknowledge Interrupt Enable */ +#define I2C_CTRL_AFIE (1 << 1) /* Bit 1: Transmitter Arbitration Failure Interrupt Enable */ +#define I2C_CTRL_TDIE (1 << 0) /* Bit 0: Transmit Done Interrupt Enable */ + +/* I2Cn Clock Divider High I2C0_CLKHI, address 0x1300a00c, I2C1_CLKHI, address 0x1300a40c */ + +#define I2C_CLKHI_SHIFT (0) /* Bits 0-9: Clock Divisor High */ +#define I2C_CLKHI_MASK (0x3ff << I2C_CLKHI_SHIFT) + +/* I2Cn Clock Divider Low I2C0_CLKLO, address 0x1300a010, I2C1_CLKLO, address 0x1300a410 */ + +#define I2C_CLKLO_SHIFT (0) /* Bits 0-9: Clock Divisor Low */ +#define I2C_CLKLO_MASK (0x3ff << I2C_CLKLO_SHIFT) + + +/* I2Cn Slave Addres I2C0_ADDR, address 0x1300a014, I2C1_ADDR, address 0x1300a414 */ + +#define I2C_ADR_SHIFT (0) /* Bits 0-9: I2C bus slave address */ +#define I2C_ADR_MASK (0x3ff << I2C_ADR_SHIFT) + +/* I2Cn RX FIFO level I2C0_RXFL, address 0x1300a018, I2C1_RXFL, address 0x1300a018 */ + +#define I2C_RXFL_SHIFT (0) /* Bits 0-1: Receive FIFO level */ +#define I2C_RXFL_MASK (3 << I2C_RXFL_SHIFT) + +/* I2Cn TX FIFO level I2C0_TXFL, address 0x1300a01c, I2C1_TXFL, address 0x1300a01c */ + +#define I2C_TXFL_SHIFT (0) /* Bits 0-1: Receive FIFO level */ +#define I2C_TXFL_MASK (3 << I2C_TXFL_SHIFT) + +/* I2Cn RX byte count I2C0_RXB, address 0x1300a020, I2C1_RXB, address 0x1300a420 */ + +#define I2C_RXB_SHIFT (0) /* Bits 0-15: Number of bytes received */ +#define I2C_RXB_MASK (0xffff << I2C_RXB_SHIFT) + +/* I2Cn TX byte count I2C0_TXB, address 0x1300a024, I2C1_TXB, address 0x1300a424 */ + +#define I2C_TXB_SHIFT (0) /* Bits 0-15: Number of bytes sent */ +#define I2C_TXB_MASK (0xffff << I2C_TXB_SHIFT) + +/* I2Cn Slave TX Data FIFO I2C0_STX, address 0x1300a028, I2C1_STX, 0x1300a428 */ + +#define I2C_STX_SHIFT (0) /* Bits 0-7: Slave Transmit FIFO data */ +#define I2C_STX_MASK (0xff << I2C_STX_SHIFT) + +/* I2Cn Slave TX FIFO level I2C0_STXFL, address 0x1300a02c, I2C1_STXFL, address 0x1300a42c */ + +#define I2C_STXFL_SHIFT (0) /* Bits 0-1: Slave Transmit FIFO level */ +#define I2C_STXFL_MASK (3 << I2C_STXFL_SHIFT) + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct i2c_master_s *lpc31_i2cbus_initialize(int port); + +/************************************************************************************ + * Name: lpc31_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc31_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ************************************************************************************/ + +int lpc31_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_I2C_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_i2s.h b/arch/arm/src/lpc31xx/lpc31_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..5ad4413f051c2c8156d71a6ea46bb373e39185de --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_i2s.h @@ -0,0 +1,315 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_i2s.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_I2S_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_I2S_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* I2S register base address offset into the APB3 domain ****************************************/ + +#define LPC31_I2SCONFIG_VBASE (LPC31_APB3_VSECTION+LPC31_APB3_I2SCONFIG_OFFSET) +#define LPC31_I2SCONFIG_PBASE (LPC31_APB3_PSECTION+LPC31_APB3_I2SCONFIG_OFFSET) + +#define LPC31_I2STX0_VBASE (LPC31_APB3_VSECTION+LPC31_APB3_I2STX0_OFFSET) +#define LPC31_I2STX0_PBASE (LPC31_APB3_PSECTION+LPC31_APB3_I2STX0_OFFSET) + +#define LPC31_I2STX1_VBASE (LPC31_APB3_VSECTION+LPC31_APB3_I2STX1_OFFSET) +#define LPC31_I2STX1_PBASE (LPC31_APB3_PSECTION+LPC31_APB3_I2STX1_OFFSET) + +#define LPC31_I2SRX0_VBASE (LPC31_APB3_VSECTION+LPC31_APB3_I2SRX0_OFFSET) +#define LPC31_I2SRX0_PBASE (LPC31_APB3_PSECTION+LPC31_APB3_I2SRX0_OFFSET) + +#define LPC31_I2SRX1_VBASE (LPC31_APB3_VSECTION+LPC31_APB3_I2SRX1_OFFSET) +#define LPC31_I2SRX1_PBASE (LPC31_APB3_PSECTION+LPC31_APB3_I2SRX1_OFFSET) + +/* I2S register offsets (with respect to the I2S base) ******************************************/ +/* I2S configuration module offset */ + +#define LPC31_I2SCONFIG_FORMAT_OFFSET 0x000 /* I2S formats */ +#define LPC31_I2SCONFIG_CFGMUX_OFFSET 0x004 /* Misc controls */ + /* 0x008-0x00c: Reserved */ +#define LPC31_I2SCONFIG_NSOFCNTR_OFFSET 0x010 /* NSOF counter control */ + +/* I2STX0, I2STX1, I2SRX0, and I2SRX1 module offsets */ + +#define LPC31_I2S_L16BIT_OFFSET 0x000 /* 16 bits left channel data */ +#define LPC31_I2S_R16BIT_OFFSET 0x004 /* 16 bits right channel data */ +#define LPC31_I2S_L24BIT_OFFSET 0x008 /* 24 bits left channel data */ +#define LPC31_I2S_R24BIT_OFFSET 0x00c /* 24 bits right channel data */ +#define LPC31_I2S_INTSTATUS_OFFSET 0x010 /* FIFO status register */ +#define LPC31_I2S_INTMASK_OFFSET 0x014 /* Interrupt Mask register */ +#define LPC31_I2S_L32BIT_OFFSET(n) (0x020+((n)<<2)) +#define LPC31_I2S_L32BIT0_OFFSET 0x020 /* 2x16 bits left channel data */ +#define LPC31_I2S_L32BIT1_OFFSET 0x024 /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT2_OFFSET 0x028 /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT3_OFFSET 0x02c /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT4_OFFSET 0x030 /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT5_OFFSET 0x034 /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT6_OFFSET 0x038 /* " " " " " " " " " " */ +#define LPC31_I2S_L32BIT7_OFFSET 0x03c /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT_OFFSET(n) (0x040+((n)<<2)) +#define LPC31_I2S_R32BIT0_OFFSET 0x040 /* 2x16 bits right channel data */ +#define LPC31_I2S_R32BIT1_OFFSET 0x044 /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT2_OFFSET 0x048 /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT3_OFFSET 0x04c /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT4_OFFSET 0x050 /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT5_OFFSET 0x054 /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT6_OFFSET 0x058 /* " " " " " " " " " " */ +#define LPC31_I2S_R32BIT7_OFFSET 0x05c /* " " " " " " " " " " */ +#define LPC31_I2S_ILVD_OFFSET(n) (0x060+((n)<<2)) +#define LPC31_I2S_ILVD0_OFFSET 0x060 /* Interleaved data */ +#define LPC31_I2S_ILVD1_OFFSET 0x064 /* " " " " */ +#define LPC31_I2S_ILVD2_OFFSET 0x068 /* " " " " */ +#define LPC31_I2S_ILVD3_OFFSET 0x06c /* " " " " */ +#define LPC31_I2S_ILVD4_OFFSET 0x070 /* " " " " */ +#define LPC31_I2S_ILVD5_OFFSET 0x074 /* " " " " */ +#define LPC31_I2S_ILVD6_OFFSET 0x078 /* " " " " */ +#define LPC31_I2S_ILVD7_OFFSET 0x07c /* " " " " */ + +/* I2S register (virtual) addresses *************************************************************/ +/* I2S configuration module registers */ + +#define LPC31_I2SCONFIG_FORMAT (LPC31_I2SCONFIG_VBASE+lPC313X_I2SCONFIG_FORMAT_OFFSET) +#define LPC31_I2SCONFIG_CFGMUX (LPC31_I2SCONFIG_VBASE+LPC31_I2SCONFIG_CFGMUX_OFFSET) +#define LPC31_I2SCONFIG_NSOFCNTR (LPC31_I2SCONFIG_VBASE+LPC31_I2SCONFIG_NSOFCNTR_OFFSET) + +/* I2STX0 module registers */ + +#define LPC31_I2STX0_L16BIT (LPC31_I2STX0_VBASE+LPC31_I2S_L16BIT_OFFSET) +#define LPC31_I2STX0_R16BIT (LPC31_I2STX0_VBASE+LPC31_I2S_R16BIT_OFFSET) +#define LPC31_I2STX0_L24BIT (LPC31_I2STX0_VBASE+LPC31_I2S_L24BIT_OFFSET) +#define LPC31_I2STX0_R24BIT (LPC31_I2STX0_VBASE+LPC31_I2S_R24BIT_OFFSET) +#define LPC31_I2STX0_INTSTATUS (LPC31_I2STX0_VBASE+LPC31_I2S_INTSTATUS_OFFSET) +#define LPC31_I2STX0_INTMASK (LPC31_I2STX0_VBASE+LPC31_I2S_INTMASK_OFFSET) +#define LPC31_I2STX0_L32BIT(n) (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT_OFFSET(n)) +#define LPC31_I2STX0_L32BIT0 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT0_OFFSET) +#define LPC31_I2STX0_L32BIT1 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT1_OFFSET) +#define LPC31_I2STX0_L32BIT2 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT2_OFFSET) +#define LPC31_I2STX0_L32BIT3 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT3_OFFSET) +#define LPC31_I2STX0_L32BIT4 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT4_OFFSET) +#define LPC31_I2STX0_L32BIT5 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT5_OFFSET) +#define LPC31_I2STX0_L32BIT6 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT6_OFFSET) +#define LPC31_I2STX0_L32BIT7 (LPC31_I2STX0_VBASE+LPC31_I2S_L32BIT7_OFFSET) +#define LPC31_I2STX0_R32BIT(n) (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT_OFFSET(n)) +#define LPC31_I2STX0_R32BIT0 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT0_OFFSET) +#define LPC31_I2STX0_R32BIT1 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT1_OFFSET) +#define LPC31_I2STX0_R32BIT2 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT2_OFFSET) +#define LPC31_I2STX0_R32BIT3 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT3_OFFSET) +#define LPC31_I2STX0_R32BIT4 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT4_OFFSET) +#define LPC31_I2STX0_R32BIT5 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT5_OFFSET) +#define LPC31_I2STX0_R32BIT6 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT6_OFFSET) +#define LPC31_I2STX0_R32BIT7 (LPC31_I2STX0_VBASE+LPC31_I2S_R32BIT7_OFFSET) +#define LPC31_I2STX0_ILVD(n) (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD_OFFSET(n)) +#define LPC31_I2STX0_ILVD0 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD0_OFFSET) +#define LPC31_I2STX0_ILVD1 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD1_OFFSET) +#define LPC31_I2STX0_ILVD2 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD2_OFFSET) +#define LPC31_I2STX0_ILVD3 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD3_OFFSET) +#define LPC31_I2STX0_ILVD4 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD4_OFFSET) +#define LPC31_I2STX0_ILVD5 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD5_OFFSET) +#define LPC31_I2STX0_ILVD6 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD6_OFFSET) +#define LPC31_I2STX0_ILVD7 (LPC31_I2STX0_VBASE+LPC31_I2S_ILVD7_OFFSET) + +/* I2STX1 module registers */ + +#define LPC31_I2STX1_L16BIT (LPC31_I2STX1_VBASE+LPC31_I2S_L16BIT_OFFSET) +#define LPC31_I2STX1_R16BIT (LPC31_I2STX1_VBASE+LPC31_I2S_R16BIT_OFFSET) +#define LPC31_I2STX1_L24BIT (LPC31_I2STX1_VBASE+LPC31_I2S_L24BIT_OFFSET) +#define LPC31_I2STX1_R24BIT (LPC31_I2STX1_VBASE+LPC31_I2S_R24BIT_OFFSET) +#define LPC31_I2STX1_INTSTATUS (LPC31_I2STX1_VBASE+LPC31_I2S_INTSTATUS_OFFSET) +#define LPC31_I2STX1_INTMASK (LPC31_I2STX1_VBASE+LPC31_I2S_INTMASK_OFFSET) +#define LPC31_I2STX1_L32BIT(n) (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT_OFFSET(n)) +#define LPC31_I2STX1_L32BIT0 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT0_OFFSET) +#define LPC31_I2STX1_L32BIT1 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT1_OFFSET) +#define LPC31_I2STX1_L32BIT2 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT2_OFFSET) +#define LPC31_I2STX1_L32BIT3 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT3_OFFSET) +#define LPC31_I2STX1_L32BIT4 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT4_OFFSET) +#define LPC31_I2STX1_L32BIT5 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT5_OFFSET) +#define LPC31_I2STX1_L32BIT6 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT6_OFFSET) +#define LPC31_I2STX1_L32BIT7 (LPC31_I2STX1_VBASE+LPC31_I2S_L32BIT7_OFFSET) +#define LPC31_I2STX1_R32BIT(n) (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT_OFFSET(n)) +#define LPC31_I2STX1_R32BIT0 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT0_OFFSET) +#define LPC31_I2STX1_R32BIT1 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT1_OFFSET) +#define LPC31_I2STX1_R32BIT2 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT2_OFFSET) +#define LPC31_I2STX1_R32BIT3 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT3_OFFSET) +#define LPC31_I2STX1_R32BIT4 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT4_OFFSET) +#define LPC31_I2STX1_R32BIT5 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT5_OFFSET) +#define LPC31_I2STX1_R32BIT6 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT6_OFFSET) +#define LPC31_I2STX1_R32BIT7 (LPC31_I2STX1_VBASE+LPC31_I2S_R32BIT7_OFFSET) +#define LPC31_I2STX1_ILVD(n) (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD_OFFSET(n)) +#define LPC31_I2STX1_ILVD0 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD0_OFFSET) +#define LPC31_I2STX1_ILVD1 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD1_OFFSET) +#define LPC31_I2STX1_ILVD2 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD2_OFFSET) +#define LPC31_I2STX1_ILVD3 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD3_OFFSET) +#define LPC31_I2STX1_ILVD4 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD4_OFFSET) +#define LPC31_I2STX1_ILVD5 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD5_OFFSET) +#define LPC31_I2STX1_ILVD6 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD6_OFFSET) +#define LPC31_I2STX1_ILVD7 (LPC31_I2STX1_VBASE+LPC31_I2S_ILVD7_OFFSET) + +/* I2SRX0 module registers */ + +#define LPC31_I2SRX0_L16BIT (LPC31_I2SRX0_VBASE+LPC31_I2S_L16BIT_OFFSET) +#define LPC31_I2SRX0_R16BIT (LPC31_I2SRX0_VBASE+LPC31_I2S_R16BIT_OFFSET) +#define LPC31_I2SRX0_L24BIT (LPC31_I2SRX0_VBASE+LPC31_I2S_L24BIT_OFFSET) +#define LPC31_I2SRX0_R24BIT (LPC31_I2SRX0_VBASE+LPC31_I2S_R24BIT_OFFSET) +#define LPC31_I2SRX0_INTSTATUS (LPC31_I2SRX0_VBASE+LPC31_I2S_INTSTATUS_OFFSET) +#define LPC31_I2SRX0_INTMASK (LPC31_I2SRX0_VBASE+LPC31_I2S_INTMASK_OFFSET) +#define LPC31_I2SRX0_L32BIT(n) (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT_OFFSET(n)) +#define LPC31_I2SRX0_L32BIT0 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT0_OFFSET) +#define LPC31_I2SRX0_L32BIT1 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT1_OFFSET) +#define LPC31_I2SRX0_L32BIT2 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT2_OFFSET) +#define LPC31_I2SRX0_L32BIT3 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT3_OFFSET) +#define LPC31_I2SRX0_L32BIT4 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT4_OFFSET) +#define LPC31_I2SRX0_L32BIT5 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT5_OFFSET) +#define LPC31_I2SRX0_L32BIT6 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT6_OFFSET) +#define LPC31_I2SRX0_L32BIT7 (LPC31_I2SRX0_VBASE+LPC31_I2S_L32BIT7_OFFSET) +#define LPC31_I2SRX0_R32BIT(n) (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT_OFFSET(n)) +#define LPC31_I2SRX0_R32BIT0 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT0_OFFSET) +#define LPC31_I2SRX0_R32BIT1 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT1_OFFSET) +#define LPC31_I2SRX0_R32BIT2 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT2_OFFSET) +#define LPC31_I2SRX0_R32BIT3 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT3_OFFSET) +#define LPC31_I2SRX0_R32BIT4 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT4_OFFSET) +#define LPC31_I2SRX0_R32BIT5 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT5_OFFSET) +#define LPC31_I2SRX0_R32BIT6 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT6_OFFSET) +#define LPC31_I2SRX0_R32BIT7 (LPC31_I2SRX0_VBASE+LPC31_I2S_R32BIT7_OFFSET) +#define LPC31_I2SRX0_ILVD(n) (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD_OFFSET(n)) +#define LPC31_I2SRX0_ILVD0 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD0_OFFSET) +#define LPC31_I2SRX0_ILVD1 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD1_OFFSET) +#define LPC31_I2SRX0_ILVD2 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD2_OFFSET) +#define LPC31_I2SRX0_ILVD3 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD3_OFFSET) +#define LPC31_I2SRX0_ILVD4 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD4_OFFSET) +#define LPC31_I2SRX0_ILVD5 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD5_OFFSET) +#define LPC31_I2SRX0_ILVD6 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD6_OFFSET) +#define LPC31_I2SRX0_ILVD7 (LPC31_I2SRX0_VBASE+LPC31_I2S_ILVD7_OFFSET) + +/* I2SRX1 module registers */ + +#define LPC31_I2SRX1_L16BIT (LPC31_I2SRX1_VBASE+LPC31_I2S_L16BIT_OFFSET) +#define LPC31_I2SRX1_R16BIT (LPC31_I2SRX1_VBASE+LPC31_I2S_R16BIT_OFFSET) +#define LPC31_I2SRX1_L24BIT (LPC31_I2SRX1_VBASE+LPC31_I2S_L24BIT_OFFSET) +#define LPC31_I2SRX1_R24BIT (LPC31_I2SRX1_VBASE+LPC31_I2S_R24BIT_OFFSET) +#define LPC31_I2SRX1_INTSTATUS (LPC31_I2SRX1_VBASE+LPC31_I2S_INTSTATUS_OFFSET) +#define LPC31_I2SRX1_INTMASK (LPC31_I2SRX1_VBASE+LPC31_I2S_INTMASK_OFFSET) +#define LPC31_I2SRX1_L32BIT(n) (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT_OFFSET(n)) +#define LPC31_I2SRX1_L32BIT0 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT0_OFFSET) +#define LPC31_I2SRX1_L32BIT1 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT1_OFFSET) +#define LPC31_I2SRX1_L32BIT2 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT2_OFFSET) +#define LPC31_I2SRX1_L32BIT3 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT3_OFFSET) +#define LPC31_I2SRX1_L32BIT4 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT4_OFFSET) +#define LPC31_I2SRX1_L32BIT5 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT5_OFFSET) +#define LPC31_I2SRX1_L32BIT6 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT6_OFFSET) +#define LPC31_I2SRX1_L32BIT7 (LPC31_I2SRX1_VBASE+LPC31_I2S_L32BIT7_OFFSET) +#define LPC31_I2SRX1_R32BIT(n) (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT_OFFSET(n)) +#define LPC31_I2SRX1_R32BIT0 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT0_OFFSET) +#define LPC31_I2SRX1_R32BIT1 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT1_OFFSET) +#define LPC31_I2SRX1_R32BIT2 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT2_OFFSET) +#define LPC31_I2SRX1_R32BIT3 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT3_OFFSET) +#define LPC31_I2SRX1_R32BIT4 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT4_OFFSET) +#define LPC31_I2SRX1_R32BIT5 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT5_OFFSET) +#define LPC31_I2SRX1_R32BIT6 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT6_OFFSET) +#define LPC31_I2SRX1_R32BIT7 (LPC31_I2SRX1_VBASE+LPC31_I2S_R32BIT7_OFFSET) +#define LPC31_I2SRX1_ILVD(n) (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD_OFFSET(n)) +#define LPC31_I2SRX1_ILVD0 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD0_OFFSET) +#define LPC31_I2SRX1_ILVD1 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD1_OFFSET) +#define LPC31_I2SRX1_ILVD2 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD2_OFFSET) +#define LPC31_I2SRX1_ILVD3 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD3_OFFSET) +#define LPC31_I2SRX1_ILVD4 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD4_OFFSET) +#define LPC31_I2SRX1_ILVD5 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD5_OFFSET) +#define LPC31_I2SRX1_ILVD6 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD6_OFFSET) +#define LPC31_I2SRX1_ILVD7 (LPC31_I2SRX1_VBASE+LPC31_I2S_ILVD7_OFFSET) + +/* I2S register bit definitions *****************************************************************/ +/* I2S configuration module offset */ + +/* I2SCONFIG_FORMAT address 0x16000000 */ + +#define I2SCONFIG_FORMAT_I2SRX1_SHIFT (9) /* Bits 9-11: I2SRX1 I2S output format */ +#define I2SCONFIG_FORMAT_I2SRX1_MASK (7 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) +# define I2SCONFIG_FORMAT_I2SRX1_I2S (3 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) /* I2S */ +# define I2SCONFIG_FORMAT_I2SRX1_16BIT (4 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) /* LSB justified 16 bits */ +# define I2SCONFIG_FORMAT_I2SRX1_18BIT (5 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) /* LSB justified 18 bits */ +# define I2SCONFIG_FORMAT_I2SRX1_20BIT (6 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) /* LSB justified 20 bits */ +# define I2SCONFIG_FORMAT_I2SRX1_24BIT (7 << I2SCONFIG_FORMAT_I2SRX1_SHIFT) /* LSB justified 24 bits */ +#define I2SCONFIG_FORMAT_I2SRX0_SHIFT (6) /* Bits 6-8: I2SRX0 I2S output format */ +#define I2SCONFIG_FORMAT_I2SRX0_MASK (7 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) +# define I2SCONFIG_FORMAT_I2SRX0_I2S (3 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) /* I2S */ +# define I2SCONFIG_FORMAT_I2SRX0_16BIT (4 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) /* LSB justified 16 bits */ +# define I2SCONFIG_FORMAT_I2SRX0_18BIT (5 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) /* LSB justified 18 bits */ +# define I2SCONFIG_FORMAT_I2SRX0_20BIT (6 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) /* LSB justified 20 bits */ +# define I2SCONFIG_FORMAT_I2SRX0_24BIT (7 << I2SCONFIG_FORMAT_I2SRX0_SHIFT) /* LSB justified 24 bits */ +#define I2SCONFIG_FORMAT_I2STX1_SHIFT (3) /* Bits 3-5: 2STX1 I2S input format */ +#define I2SCONFIG_FORMAT_I2STX1_MASK (7 << I2SCONFIG_FORMAT_I2STX1_SHIFT) +# define I2SCONFIG_FORMAT_I2STX1_I2S (3 << I2SCONFIG_FORMAT_I2STX1_SHIFT) /* I2S */ +# define I2SCONFIG_FORMAT_I2STX1_16BIT (4 << I2SCONFIG_FORMAT_I2STX1_SHIFT) /* LSB justified 16 bits */ +# define I2SCONFIG_FORMAT_I2STX1_18BIT (5 << I2SCONFIG_FORMAT_I2STX1_SHIFT) /* LSB justified 18 bits */ +# define I2SCONFIG_FORMAT_I2STX1_20BIT (6 << I2SCONFIG_FORMAT_I2STX1_SHIFT) /* LSB justified 20 bits */ +# define I2SCONFIG_FORMAT_I2STX1_24BIT (7 << I2SCONFIG_FORMAT_I2STX1_SHIFT) /* LSB justified 24 bits */ +#define I2SCONFIG_FORMAT_I2STX0_SHIFT (0) /* Bits 0-2: I2STX0 I2S input format */ +#define I2SCONFIG_FORMAT_I2STX0_MASK (7 << I2SCONFIG_FORMAT_I2STX0_SHIFT) +# define I2SCONFIG_FORMAT_I2STX0_I2S (3 << I2SCONFIG_FORMAT_I2STX0_SHIFT) /* I2S */ +# define I2SCONFIG_FORMAT_I2STX0_16BIT (4 << I2SCONFIG_FORMAT_I2STX0_SHIFT) /* LSB justified 16 bits */ +# define I2SCONFIG_FORMAT_I2STX0_18BIT (5 << I2SCONFIG_FORMAT_I2STX0_SHIFT) /* LSB justified 18 bits */ +# define I2SCONFIG_FORMAT_I2STX0_20BIT (6 << I2SCONFIG_FORMAT_I2STX0_SHIFT) /* LSB justified 20 bits */ +# define I2SCONFIG_FORMAT_I2STX0_24BIT (7 << I2SCONFIG_FORMAT_I2STX0_SHIFT) /* LSB justified 24 bits */ + +/* II2SCONFIG_CFGMUX address 0x16000004 */ + +#define I2SCONFIG_CFGMUX_I2SRX1OEN (1 << 2) /* Bit 2: Selects faster mode for I2SRX1 */ +#define I2SCONFIG_CFGMUX_I2SRX0OEN (1 << 1) /* Bit 1: Slects master mode for I2SRX0 */ + +/* I2SCONFIG_NSOFCNT address 0x16000010 */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_I2S_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_intc.h b/arch/arm/src/lpc31xx/lpc31_intc.h new file mode 100644 index 0000000000000000000000000000000000000000..e6dabded8869f68ee1f06b3f666b7a9fd13bdd27 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_intc.h @@ -0,0 +1,198 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_intc.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_INTC_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_INTC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* INTC register base address *******************************************************************/ + +#define LPC31_INTC_VBASE (LPC31_INTC_VSECTION) +#define LPC31_INTC_PBASE (LPC31_INTC_PSECTION) + +/* INTC register offsets (with respect to the base of the INTC domain) **************************/ + +#define LPC31_INTC_PRIORITYMASK0_OFFSET 0x000 /* Interrupt target 0 priority threshold */ +#define LPC31_INTC_PRIORITYMASK1_OFFSET 0x004 /* Interrupt target 0 priority threshold */ +#define LPC31_INTC_VECTOR0_OFFSET 0x100 /* Vector register for target 0 => nIRQ */ +#define LPC31_INTC_VECTOR1_OFFSET 0x104 /* Vector register for target 1 => nFIQ */ +#define LPC31_INTC_PENDING_OFFSET 0x200 /* Status of interrupt request 1..29 */ +#define LPC31_INTC_FEATURES_OFFSET 0x300 /* Interrupt controller configuration */ +#define LPC31_INTC_REQUEST_OFFSET(n) (0x400+((n) << 2)) +#define LPC31_INTC_REQUEST1_OFFSET 0x404 /* Interrupt request 1 configuration */ +#define LPC31_INTC_REQUEST2_OFFSET 0x408 /* Interrupt request 2 configuration */ +#define LPC31_INTC_REQUEST3_OFFSET 0x40c /* Interrupt request 3 configuration */ +#define LPC31_INTC_REQUEST4_OFFSET 0x410 /* Interrupt request 4 configuration */ +#define LPC31_INTC_REQUEST5_OFFSET 0x414 /* Interrupt request 5 configuration */ +#define LPC31_INTC_REQUEST6_OFFSET 0x418 /* Interrupt request 6 configuration */ +#define LPC31_INTC_REQUEST7_OFFSET 0x41c /* Interrupt request 7 configuration */ +#define LPC31_INTC_REQUEST8_OFFSET 0x420 /* Interrupt request 8 configuration */ +#define LPC31_INTC_REQUEST9_OFFSET 0x424 /* Interrupt request 9 configuration */ +#define LPC31_INTC_REQUEST10_OFFSET 0x428 /* Interrupt request 10 configuration */ +#define LPC31_INTC_REQUEST11_OFFSET 0x42c /* Interrupt request 11 configuration */ +#define LPC31_INTC_REQUEST12_OFFSET 0x430 /* Interrupt request 12 configuration */ +#define LPC31_INTC_REQUEST13_OFFSET 0x434 /* Interrupt request 13 configuration */ +#define LPC31_INTC_REQUEST14_OFFSET 0x438 /* Interrupt request 14 configuration */ +#define LPC31_INTC_REQUEST15_OFFSET 0x43c /* Interrupt request 15 configuration */ +#define LPC31_INTC_REQUEST16_OFFSET 0x440 /* Interrupt request 16 configuration */ +#define LPC31_INTC_REQUEST17_OFFSET 0x444 /* Interrupt request 17 configuration */ +#define LPC31_INTC_REQUEST18_OFFSET 0x448 /* Interrupt request 18 configuration */ +#define LPC31_INTC_REQUEST19_OFFSET 0x44c /* Interrupt request 19 configuration */ +#define LPC31_INTC_REQUEST20_OFFSET 0x450 /* Interrupt request 20 configuration */ +#define LPC31_INTC_REQUEST21_OFFSET 0x454 /* Interrupt request 21 configuration */ +#define LPC31_INTC_REQUEST22_OFFSET 0x458 /* Interrupt request 22 configuration */ +#define LPC31_INTC_REQUEST23_OFFSET 0x45c /* Interrupt request 23 configuration */ +#define LPC31_INTC_REQUEST24_OFFSET 0x460 /* Interrupt request 24 configuration */ +#define LPC31_INTC_REQUEST25_OFFSET 0x464 /* Interrupt request 25 configuration */ +#define LPC31_INTC_REQUEST26_OFFSET 0x468 /* Interrupt request 26 configuration */ +#define LPC31_INTC_REQUEST27_OFFSET 0x46c /* Interrupt request 27 configuration */ +#define LPC31_INTC_REQUEST28_OFFSET 0x470 /* Interrupt request 28 configuration */ +#define LPC31_INTC_REQUEST29_OFFSET 0x474 /* Interrupt request 29 configuration */ + +/* INTC register (virtual) addresses ************************************************************/ + +#define LPC31_INTC_PRIORITYMASK0 (LPC31_INTC_VBASE+LPC31_INTC_PRIORITYMASK0_OFFSET) +#define LPC31_INTC_PRIORITYMASK1 (LPC31_INTC_VBASE+LPC31_INTC_PRIORITYMASK1_OFFSET) +#define LPC31_INTC_VECTOR0 (LPC31_INTC_VBASE+LPC31_INTC_VECTOR0_OFFSET) +#define LPC31_INTC_VECTOR1 (LPC31_INTC_VBASE+LPC31_INTC_VECTOR1_OFFSET) +#define LPC31_INTC_PENDING (LPC31_INTC_VBASE+LPC31_INTC_PENDING_OFFSET) +#define LPC31_INTC_FEATURES (LPC31_INTC_VBASE+LPC31_INTC_FEATURES_OFFSET) +#define LPC31_INTC_REQUEST(n) (LPC31_INTC_VBASE+LPC31_INTC_REQUEST_OFFSET(n)) +#define LPC31_INTC_REQUEST1 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST1_OFFSET) +#define LPC31_INTC_REQUEST2 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST2_OFFSET) +#define LPC31_INTC_REQUEST3 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST3_OFFSET) +#define LPC31_INTC_REQUEST4 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST4_OFFSET) +#define LPC31_INTC_REQUEST5 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST5_OFFSET) +#define LPC31_INTC_REQUEST6 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST6_OFFSET) +#define LPC31_INTC_REQUEST7 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST7_OFFSET) +#define LPC31_INTC_REQUEST8 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST8_OFFSET) +#define LPC31_INTC_REQUEST9 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST9_OFFSET) +#define LPC31_INTC_REQUEST10 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST10_OFFSET) +#define LPC31_INTC_REQUEST11 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST11_OFFSET) +#define LPC31_INTC_REQUEST12 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST12_OFFSET) +#define LPC31_INTC_REQUEST13 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST13_OFFSET) +#define LPC31_INTC_REQUEST14 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST14_OFFSET) +#define LPC31_INTC_REQUEST15 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST15_OFFSET) +#define LPC31_INTC_REQUEST16 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST16_OFFSET) +#define LPC31_INTC_REQUEST17 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST17_OFFSET) +#define LPC31_INTC_REQUEST18 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST18_OFFSET) +#define LPC31_INTC_REQUEST19 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST19_OFFSET) +#define LPC31_INTC_REQUEST20 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST20_OFFSET) +#define LPC31_INTC_REQUEST21 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST21_OFFSET) +#define LPC31_INTC_REQUEST22 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST22_OFFSET) +#define LPC31_INTC_REQUEST23 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST23_OFFSET) +#define LPC31_INTC_REQUEST24 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST24_OFFSET) +#define LPC31_INTC_REQUEST25 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST25_OFFSET) +#define LPC31_INTC_REQUEST26 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST26_OFFSET) +#define LPC31_INTC_REQUEST27 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST27_OFFSET) +#define LPC31_INTC_REQUEST28 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST28_OFFSET) +#define LPC31_INTC_REQUEST29 (LPC31_INTC_VBASE+LPC31_INTC_REQUEST29_OFFSET) + +/* INTC register bit definitions ****************************************************************/ + +/* Interrupt priority mask register (INT_PRIORITYMASK0 address 0x60000000 and + * INTC_PRIORITYMASK1 address 0x60000004) + */ + +#define INTC_PRIORITYMASK_PRIOLIMIT_SHIFT (0) /* Bits 0-7: Priority threshold for interrupts */ +#define INTC_PRIORITYMASK_PRIOLIMIT_MASK (255 << INTC_PRIORITYMASK_PRIOLIMIT_MASK) + +/* Interrupt vector registers (INTC_VECTOR0 address 0x60000100 and INTC_VECTOR1 address + * 0x60000104) + */ + +#define INTC_VECTOR_TABLEADDR_SHIFT (11) /* Bits 11-31: Table start address */ +#define INTC_VECTOR_TABLEADDR_MASK (0x001fffff << INTC_VECTOR_TABLEADDR_SHIFT) +#define INTC_VECTOR_INDEX_SHIFT (3) /* Bits 3-10: IRQ number of interrupt */ +#define INTC_VECTOR_INDEX_MASK (255 << INTC_VECTOR_INDEX_SHIFT) + +/* Interrupt pending register (INT_PENDING1_31, address 0x60000200) */ + +#define INTC_PENDING_SHIFT (1) /* Bits 1-29: Pending interrupt request */ +#define INTC_PENDING_MASK (0x1fffffff << INTC_PENDING_SHIFT) + +/* Interrupt controller features register (INT_FEATURES, address 0x60000300) */ + +#define INTC_FEATURES_T_SHIFT (16) /* Bits 16-21: Number interrupt targets supported (+1) */ +#define INTC_FEATURES_T_MASK (63 << INTC_FEATURES_T_SHIFT) +#define INTC_FEATURES_P_SHIFT (8) /* Bits 8-15: Number priority levels supported */ +#define INTC_FEATURES_P_MASK (255 << INTC_FEATURES_P_SHIFT) +#define INTC_FEATURES_N_SHIFT (0) /* Bits 0-7: Number interrupt request inputs */ +#define INTC_FEATURES_N_MASK (255 << INTC_FEATURES_N_SHIFT) + +/* Interrupt request registers (INT_REQUEST1 address 0x60000404 to INTC_REQUEST29 address + * 0x60000474) + */ + +#define INTC_REQUEST_PENDING (1 << 31) /* Bit 31: Pending interrupt request */ +#define INTC_REQUEST_SETSWINT (1 << 30) /* Bit 30: Set software interrupt request */ +#define INTC_REQUEST_CLRSWINT (1 << 29) /* Bit 29: Clear software interrupt request */ +#define INTC_REQUEST_WEPRIO (1 << 28) /* Bit 28: Write Enable PRIORITY_LEVEL */ +#define INTC_REQUEST_WETARGET (1 << 27) /* Bit 27: Write Enable TARGET */ +#define INTC_REQUEST_WEENABLE (1 << 26) /* Bit 26: Write Enable ENABLE */ +#define INTC_REQUEST_WEACTLOW (1 << 25) /* Bit 25: Write Enable ACTIVE_LOW */ +#define INTC_REQUEST_ACTLOW (1 << 17) /* Bit 17: Active Low */ +#define INTC_REQUEST_ENABLE (1 << 16) /* Bit 16: Enable interrupt request */ +#define INTC_REQUEST_TARGET_SHIFT (8) /* Bits 8-13: Interrupt target */ +#define INTC_REQUEST_TARGET_MASK (63 << INTC_REQUEST_TARGET_SHIFT) +# define INTC_REQUEST_TARGET_IRQ (INTC_REQUEST_WETARGET | (0 << INTC_REQUEST_TARGET_SHIFT)) /* Proc interrupt request 0: IRQ */ +# define INTC_REQUEST_TARGET_FIQ (INTC_REQUEST_WETARGET | (1 << INTC_REQUEST_TARGET_SHIFT)) /* Proc interrupt request 1: FIQ */ +#define INTC_REQUEST_PRIOLEVEL_SHIFT (0) /* Bits 0-7: Priority level */ +#define INTC_REQUEST_PRIOLEVEL_MASK (255 << INTC_REQUEST_PRIOLEVEL_SHIFT) +# define INTC_REQUEST_PRIOLEVEL(n) (((n) << INTC_REQUEST_PRIOLEVEL_SHIFT) & INTC_REQUEST_PRIOLEVEL_MASK) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_INTC_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_ioconfig.h b/arch/arm/src/lpc31xx/lpc31_ioconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..2cf5e0c90adb80d01e31166f5aa29bd3759294d9 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_ioconfig.h @@ -0,0 +1,357 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_ioconfig.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_IOCONFIG_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_IOCONFIG_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* IOCONFIG register base address offset into the APB0 domain ***********************************/ + +#define LPC31_IOCONFIG_VBASE (LPC31_APB0_VADDR+LPC31_APB0_IOCONFIG_OFFSET) +#define LPC31_IOCONFIG_PBASE (LPC31_APB0_PADDR+LPC31_APB0_IOCONFIG_OFFSET) + +/* IOCONFIG function block offsets (with respect to the IOCONFIG register base address) *********/ + +#define LPC31_IOCONFIG_EBIMCI_OFFSET 0x000 /* First set of 32 multiplexed pads */ +#define LPC31_IOCONFIG_EBII2STX0_OFFSET 0X040 /* Second set of 32 of multiplexed pads */ +#define LPC31_IOCONFIG_CGU_OFFSET 0X080 /* Clock Generation Unit function block */ +#define LPC31_IOCONFIG_I2SRX0_OFFSET 0x0c0 /* I2SRX function block 0 */ +#define LPC31_IOCONFIG_I2SRX1_OFFSET 0x100 /* I2SRX function block 1 */ +#define LPC31_IOCONFIG_I2STX1_OFFSET 0x140 /* I2STX function block 1 */ +#define LPC31_IOCONFIG_EBI_OFFSET 0x180 /* External Bus Interface function block */ +#define LPC31_IOCONFIG_GPIO_OFFSET 0x1c0 /* General purpose IO */ +#define LPC31_IOCONFIG_I2C1_OFFSET 0x200 /* I2C function block */ +#define LPC31_IOCONFIG_SPI_OFFSET 0x240 /* SPI function block */ +#define LPC31_IOCONFIG_NAND_OFFSET 0x280 /* NANDFLASH function block */ +#define LPC31_IOCONFIG_PWM_OFFSET 0x2c0 /* PWM function block */ +#define LPC31_IOCONFIG_UART_OFFSET 0x300 /* UART function block */ + +/* IOCONFIG register offsets (with respect to any funcion block base address) *******************/ + +#define LPC31_IOCONFIG_PINS_OFFSET 0x000 /* WR: RD: Input pin state */ + /* 0x004-0x00c: Reserved */ +#define LPC31_IOCONFIG_MODE0_OFFSET 0x010 /* WR:Load RD: */ +#define LPC31_IOCONFIG_MODE0SET_OFFSET 0x014 /* WR:Set Bits RD:Read Mode 0 */ +#define LPC31_IOCONFIG_MODE0RESET_OFFSET 0x018 /* WR:Reset Bits RD: */ + /* 0x01c: Reserved */ +#define LPC31_IOCONFIG_MODE1_OFFSET 0x020 /* WR:Load RD: */ +#define LPC31_IOCONFIG_MODE1SET_OFFSET 0x024 /* WR:Set Bits RD:Read Mode 1 */ +#define LPC31_IOCONFIG_MODE1RESET_OFFSET 0x028 /* WR:Reset Bits RD: */ + /* 0x02c-0x3c: Reserved */ + +/* IOCONFIG function block (virtual) base addresses *********************************************/ + +#define LPC31_IOCONFIG_EBIMCI (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_EBIMCI_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0 (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_EBII2STX0_OFFSET) +#define LPC31_IOCONFIG_CGU (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_CGU_OFFSET) +#define LPC31_IOCONFIG_I2SRX0 (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_I2SRX0_OFFSET) +#define LPC31_IOCONFIG_I2SRX1 (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_I2SRX1_OFFSET) +#define LPC31_IOCONFIG_I2STX1 (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_I2STX1_OFFSET) +#define LPC31_IOCONFIG_EBI (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_EBI_OFFSET) +#define LPC31_IOCONFIG_GPIO (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_GPIO_OFFSET) +#define LPC31_IOCONFIG_I2C1 (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_I2C1_OFFSET) +#define LPC31_IOCONFIG_SPI (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_SPI_OFFSET) +#define LPC31_IOCONFIG_NAND (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_NAND_OFFSET) +#define LPC31_IOCONFIG_PWM (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_PWM_OFFSET) +#define LPC31_IOCONFIG_UART (LPC31_IOCONFIG_VBASE+LPC31_IOCONFIG_UART_OFFSET) + +/* IOCONFIG register (virtual) addresses ********************************************************/ + +#define LPC31_IOCONFIG_EBIMCI_PINS (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE0 (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE0SET (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE0RESET (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE1 (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE1SET (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_EBIMCI_MODE1RESET (LPC31_IOCONFIG_EBIMCI+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_EBII2STX0_PINS (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE0 (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE0SET (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE0RESET (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE1 (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE1SET (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_EBII2STX0_MODE1RESET (LPC31_IOCONFIG_EBII2STX0+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_CGU_PINS (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE0 (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE0SET (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE0RESET (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE1 (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE1SET (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_CGU_MODE1RESET (LPC31_IOCONFIG_CGU+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_I2SRX0_PINS (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE0 (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE0SET (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE0RESET (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE1 (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE1SET (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_I2SRX0_MODE1RESET (LPC31_IOCONFIG_I2SRX0+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_I2SRX1_PINS (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE0 (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE0SET (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE0RESET (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE1 (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE1SET (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_I2SRX1_MODE1RESET (LPC31_IOCONFIG_I2SRX1+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_I2STX1_PINS (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE0 (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE0SET (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE0RESET (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE1 (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE1SET (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_I2STX1_MODE1RESET (LPC31_IOCONFIG_I2STX1+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_EBI_PINS (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE0 (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE0SET (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE0RESET (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE1 (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE1SET (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_EBI_MODE1RESET (LPC31_IOCONFIG_EBI+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_GPIO_PINS (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE0 (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE0SET (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE0RESET (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE1 (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE1SET (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_GPIO_MODE1RESET (LPC31_IOCONFIG_GPIO+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_I2C1_PINS (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE0 (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE0SET (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE0RESET (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE1 (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE1SET (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_I2C1_MODE1RESET (LPC31_IOCONFIG_I2C1+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_SPI_PINS (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE0 (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE0SET (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE0RESET (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE1 (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE1SET (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_SPI_MODE1RESET (LPC31_IOCONFIG_SPI+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_NAND_PINS (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE0 (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE0SET (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE0RESET (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE1 (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE1SET (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_NAND_MODE1RESET (LPC31_IOCONFIG_NAND+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_PWM_PINS (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE0 (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE0SET (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE0RESET (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE1 (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE1SET (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_PWM_MODE1RESET (LPC31_IOCONFIG_PWM+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +#define LPC31_IOCONFIG_UART_PINS (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_PINS_OFFSET) +#define LPC31_IOCONFIG_UART_MODE0 (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE0_OFFSET) +#define LPC31_IOCONFIG_UART_MODE0SET (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE0SET_OFFSET) +#define LPC31_IOCONFIG_UART_MODE0RESET (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE0RESET_OFFSET) +#define LPC31_IOCONFIG_UART_MODE1 (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE1_OFFSET) +#define LPC31_IOCONFIG_UART_MODE1SET (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE1SET_OFFSET) +#define LPC31_IOCONFIG_UART_MODE1RESET (LPC31_IOCONFIG_UART+LPC31_IOCONFIG_MODE1RESET_OFFSET) + +/* IOCONFIG register bit definitions ************************************************************/ +/* EBI_MCI register bit definitions (all registers) */ + + +#define IOCONFIG_EBIMCI_MGPIO9 (1 << 0) +#define IOCONFIG_EBIMCI_MGPIO6 (1 << 1) +#define IOCONFIG_EBIMCI_MLCDDB7 (1 << 2) +#define IOCONFIG_EBIMCI_MLCDDB4 (1 << 3) +#define IOCONFIG_EBIMCI_MLCDDB2 (1 << 4) +#define IOCONFIG_EBIMCI_MNANDRYBN0 (1 << 5) +#define IOCONFIG_EBIMCI_MI2STXCLK0 (1 << 6) +#define IOCONFIG_EBIMCI_MI2STXBCK0 (1 << 7) +#define IOCONFIG_EBIMCI_EBIA1CLE (1 << 8) +#define IOCONFIG_EBIMCI_EBINCASBLOUT0 (1 << 9) +#define IOCONFIG_EBIMCI_MLCDDB0 (1 << 10) +#define IOCONFIG_EBIMCI_EBIDQM0NOE (1 << 11) +#define IOCONFIG_EBIMCI_MLCDCSB (1 << 12) +#define IOCONFIG_EBIMCI_MLCDDB1 (1 << 13) +#define IOCONFIG_EBIMCI_MLCDERD (1 << 14) +#define IOCONFIG_EBIMCI_MLCDRS (1 << 15) +#define IOCONFIG_EBIMCI_MLCDRWWR (1 << 16) +#define IOCONFIG_EBIMCI_MLCDDB3 (1 << 17) +#define IOCONFIG_EBIMCI_MLCDDB5 (1 << 18) +#define IOCONFIG_EBIMCI_MLCDDB6 (1 << 19) +#define IOCONFIG_EBIMCI_MLCDDB8 (1 << 20) +#define IOCONFIG_EBIMCI_MLCDDB9 (1 << 21) +#define IOCONFIG_EBIMCI_MLCDDB10 (1 << 22) +#define IOCONFIG_EBIMCI_MLCDDB11 (1 << 23) +#define IOCONFIG_EBIMCI_MLCDDB12 (1 << 24) +#define IOCONFIG_EBIMCI_MLCDDB13 (1 << 25) +#define IOCONFIG_EBIMCI_MLCDDB14 (1 << 26) +#define IOCONFIG_EBIMCI_MLCDDB15 (1 << 27) +#define IOCONFIG_EBIMCI_MGPIO5 (1 << 28) +#define IOCONFIG_EBIMCI_MGPIO7 (1 << 29) +#define IOCONFIG_EBIMCI_MGPIO8 (1 << 30) +#define IOCONFIG_EBIMCI_MGPIO10 (1 << 31) + +/* EBI_I2STX_0 register bit definitions (all registers) */ + +#define IOCONFIG_EBII2STX0_MNANDRYBN1 (1 << 0) +#define IOCONFIG_EBII2STX0_MNANDRYBN2 (1 << 1) +#define IOCONFIG_EBII2STX0_MNANDRYBN3 (1 << 2) +#define IOCONFIG_EBII2STX0_MUARTCTSN (1 << 3) +#define IOCONFIG_EBII2STX0_MUARTRTSN (1 << 4) +#define IOCONFIG_EBII2STX0_MI2STXDATA0 (1 << 5) +#define IOCONFIG_EBII2STX0_MI2STXWS0 (1 << 6) +#define IOCONFIG_EBII2STX0_EBINRASBLOUT1 (1 << 7) +#define IOCONFIG_EBII2STX0_EBIA0ALE (1 << 8) +#define IOCONFIG_EBII2STX0_EBINWE (1 << 9) + +/* CGU register bit definitions (all registers) */ + +#define IOCONFIG_CGU_SYSCLKO (1 << 0) + +/* I2SRX_0 register bit definitions (all registers) */ + +#define IOCONFIG_I2SRX0_BCK (1 << 0) +#define IOCONFIG_I2SRX0_DATA (1 << 1) +#define IOCONFIG_I2SRX0_WS (1 << 2) + +/* I2SRX_1 register bit definitions (all registers) */ + +#define IOCONFIG_I2SRX1_DATA (1 << 0) +#define IOCONFIG_I2SRX1_BCK (1 << 1) +#define IOCONFIG_I2SRX1_WS (1 << 2) + +/* I2STX_1 register bit definitions (all registers) */ + +#define IOCONFIG_I2STX1_DATA (1 << 0) +#define IOCONFIG_I2STX1_BCK (1 << 1) +#define IOCONFIG_I2STX1_WS (1 << 2) +#define IOCONFIG_I2STX1_256FSO (1 << 3) + +/* EBI register bit definitions (all registers) */ + +#define IOCONFIG_EBI_D9 (1 << 0) +#define IOCONFIG_EBI_D10 (1 << 1) +#define IOCONFIG_EBI_D11 (1 << 2) +#define IOCONFIG_EBI_D12 (1 << 3) +#define IOCONFIG_EBI_D13 (1 << 4) +#define IOCONFIG_EBI_D14 (1 << 5) +#define IOCONFIG_EBI_D4 (1 << 6) +#define IOCONFIG_EBI_D0 (1 << 7) +#define IOCONFIG_EBI_D1 (1 << 8) +#define IOCONFIG_EBI_D2 (1 << 9) +#define IOCONFIG_EBI_D3 (1 << 10) +#define IOCONFIG_EBI_D5 (1 << 11) +#define IOCONFIG_EBI_D6 (1 << 12) +#define IOCONFIG_EBI_D7 (1 << 13) +#define IOCONFIG_EBI_D8 (1 << 14) +#define IOCONFIG_EBI_D15 (1 << 15) + +/* GPIO register bit definitions (all registers) */ + +#define IOCONFIG_GPIO_GPIO1 (1 << 0) +#define IOCONFIG_GPIO_GPIO0 (1 << 1) +#define IOCONFIG_GPIO_GPIO2 (1 << 2) +#define IOCONFIG_GPIO_GPIO3 (1 << 3) +#define IOCONFIG_GPIO_GPIO4 (1 << 4) +#define IOCONFIG_GPIO_GPIO11 (1 << 5) +#define IOCONFIG_GPIO_GPIO12 (1 << 6) +#define IOCONFIG_GPIO_GPIO13 (1 << 7) +#define IOCONFIG_GPIO_GPIO14 (1 << 8) +#define IOCONFIG_GPIO_GPIO15 (1 << 9) +#define IOCONFIG_GPIO_GPIO16 (1 << 10) +#define IOCONFIG_GPIO_GPIO17 (1 << 11) +#define IOCONFIG_GPIO_GPIO18 (1 << 12) +#define IOCONFIG_GPIO_GPIO19 (1 << 13) +#define IOCONFIG_GPIO_GPIO20 (1 << 14) + +/* I2C1 register bit definitions (all registers) */ + +#define IOCONFIG_I2C1_SDA1 (1 << 0) +#define IOCONFIG_I2C1_SCL1 (1 << 1) + +/* SPI register bit definitions (all registers) */ + +#define IOCONFIG_SPI_MISO (1 << 0) +#define IOCONFIG_SPI_MOSI (1 << 1) +#define IOCONFIG_SPI_CSIN (1 << 2) +#define IOCONFIG_SPI_SCK (1 << 3) +#define IOCONFIG_SPI_CSOUT0 (1 << 4) + +/* NAND register bit definitions (all registers) */ + +#define IOCONFIG_NAND_NCS3 (1 << 0) +#define IOCONFIG_NAND_NCS0 (1 << 1) +#define IOCONFIG_NAND_NCS1 (1 << 2) +#define IOCONFIG_NAND_NCS2 (1 << 3) + +/* PWM register bit definitions (all registers) */ + +#define IOCONFIG_PWM_DATA (1 << 0) + +/* UART register bit definitions (all registers) */ + +#define IOCONFIG_UART_RXD (1 << 0) +#define IOCONFIG_UART_TXD (1 << 1) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_IOCONFIG_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_irq.c b/arch/arm/src/lpc31xx/lpc31_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..6e390e124e6a5c2751506eed1a2950a8eb332cab --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_irq.c @@ -0,0 +1,225 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_irq.c + * arch/arm/src/chip/lpc31_irq.c + * + * Copyright (C) 2009-2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "arm.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc31_intc.h" +#include "lpc31_cgudrvr.h" +#include "lpc31.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int irq; + + /* Enable clock to interrupt controller */ + + lpc31_enableclock(CLKID_AHB2INTCCLK); /* AHB_TO_INTC_CLK */ + lpc31_enableclock(CLKID_INTCCLK); /* INTC_CLK */ + + /* Set the vector base. We don't use direct vectoring, so these are set to 0. */ + + putreg32(0, LPC31_INTC_VECTOR0); + putreg32(0, LPC31_INTC_VECTOR1); + + /* Set the priority treshold to 0, i.e. don't mask any interrupt on the + * basis of priority level, for both targets (IRQ/FIQ) + */ + + putreg32(0, LPC31_INTC_PRIORITYMASK0); /* Proc interrupt request 0: IRQ */ + putreg32(0, LPC31_INTC_PRIORITYMASK1); /* Proc interrupt request 1: FIQ */ + + /* Disable all interrupts. Start from index 1 since 0 is unused. */ + + for (irq = 0; irq < NR_IRQS; irq++) + { + /* Initialize as high-active, disable the interrupt, set target to IRQ, + * Set priority level to 1 (= lowest) for all the interrupt lines + */ + + uint32_t address = LPC31_INTC_REQUEST(irq+1); + putreg32(INTC_REQUEST_WEACTLOW | INTC_REQUEST_WEENABLE | + INTC_REQUEST_TARGET_IRQ | INTC_REQUEST_PRIOLEVEL(1) | + INTC_REQUEST_WEPRIO, address); + + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* Get the address of the request register corresponding to this + * interrupt source + */ + + uint32_t address = LPC31_INTC_REQUEST(irq+1); + + /* Clear the ENABLE bit with WE_ENABLE=1. Configuration settings will be + * preserved because WE_TARGET is zero. + */ + + putreg32(INTC_REQUEST_WEENABLE, address); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* Get the address of the request register corresponding to this + * interrupt source + */ + + uint32_t address = LPC31_INTC_REQUEST(irq+1); + + /* Set the ENABLE bit with WE_ENABLE=1. Configuration settings will be + * preserved because WE_TARGET is zero. + */ + + putreg32(INTC_REQUEST_ENABLE | INTC_REQUEST_WEENABLE, address); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + /* Get the address of the request register corresponding to this + * interrupt source + */ + + uint32_t address = LPC31_INTC_REQUEST(irq+1); + + /* Clear the pending interrupt (INTC_REQUEST_CLRSWINT=1) while keeping + * interrupts enabled (ENABLE=1 && WE_ENABLE=1). Configuration settings + * will be preserved because WE_TARGET is zero. + */ + + putreg32(INTC_REQUEST_CLRSWINT | INTC_REQUEST_ENABLE | + INTC_REQUEST_WEENABLE, address); +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ +#warning "Not implemented" + return OK; +} +#endif diff --git a/arch/arm/src/lpc31xx/lpc31_lcd.h b/arch/arm/src/lpc31xx/lpc31_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..34aa6fc6e2a019a77f4b59975a2a1f03d051ec7b --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_lcd.h @@ -0,0 +1,161 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_lcd.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_LCD_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_LCD_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* LCD register base address offset into the APB2 domain ****************************************/ + +#define LPC31_LCD_VBASE (LPC31_APB2_VSECTION+LPC31_APB2_LCD_OFFSET) +#define LPC31_LCD_PBASE (LPC31_APB2_PSECTION+LPC31_APB2_LCD_OFFSET) + +/* LCD register offsets (with respect to the LCD base) ******************************************/ + +#define LPC31_LCD_STATUS_OFFSET 0x000 /* Status register */ +#define LPC31_LCD_CONTROL_OFFSET 0x004 /* Control register */ +#define LPC31_LCD_INTRAW_OFFSET 0x008 /* Interrupt Raw register */ +#define LPC31_LCD_INTCLEAR_OFFSET 0x00c /* Interrupt Clear register */ +#define LPC31_LCD_INTMASK_OFFSET 0x010 /* Interrupt Mask Register */ +#define LPC31_LCD_READCMD_OFFSET 0x014 /* Read Command register */ +#define LPC31_LCD_INSTBYTE_OFFSET 0x020 /* Instruction Byte Register */ +#define LPC31_LCD_DATABYTE_OFFSET 0x030 /* Data Byte Register */ +#define LPC31_LCD_INSTWORD_OFFSET 0x040 /* Instruction Word register */ +#define LPC31_LCD_DATAWORD_OFFSET 0x080 /* Data Word register */ + +/* LCD register (virtual) addresses *************************************************************/ + +#define LPC31_LCD_STATUS (LPC31_LCD_VBASE+LPC31_LCD_STATUS_OFFSET) +#define LPC31_LCD_CONTROL (LPC31_LCD_VBASE+LPC31_LCD_CONTROL_OFFSET) +#define LPC31_LCD_INTRAW (LPC31_LCD_VBASE+LPC31_LCD_INTRAW_OFFSET) +#define LPC31_LCD_INTCLEAR (LPC31_LCD_VBASE+LPC31_LCD_INTCLEAR_OFFSET) +#define LPC31_LCD_INTMASK (LPC31_LCD_VBASE+LPC31_LCD_INTMASK_OFFSET) +#define LPC31_LCD_READCMD (LPC31_LCD_VBASE+LPC31_LCD_READCMD_OFFSET) +#define LPC31_LCD_INSTBYTE (LPC31_LCD_VBASE+LPC31_LCD_INSTBYTE_OFFSET) +#define LPC31_LCD_DATABYTE (LPC31_LCD_VBASE+LPC31_LCD_DATABYTE_OFFSET) +#define LPC31_LCD_INSTWORD (LPC31_LCD_VBASE+LPC31_LCD_INSTWORD_OFFSET) +#define LPC31_LCD_DATAWORD (LPC31_LCD_VBASE+LPC31_LCD_DATAWORD_OFFSET) + +/* LCD register bit definitions *****************************************************************/ +/* LCD interface Status Register LCD_STATUS, address 0x15000400 */ + +#define LCD_STATUS_COUNTER_SHIFT (5) /* Bits 5-9: Current value of the FIFO counter */ +#define LCD_STATUS_COUNTER_MASK (0x1f << LCD_STATUS_COUNTER_SHIFT) +#define LCD_STATUS_INTERFACEBUSY (1 << 4) /* Bit 4: LCD interface still reading value */ +#define LCD_STATUS_INTREADVALID (1 << 3) /* Bit 3: Value read from the LCD controller is valid */ +#define LCD_STATUS_INTFIFOOVERRUN (1 << 2) /* Bit 2: Value written is larger than the FIFO can hold */ +#define LCD_STATUS_INTFIFOHALFEMPTY (1 << 1) /* Bit 1: FIFO is less then half full */ +#define LCD_STATUS_INTFIFOEMPTY (1 << 0) /* Bit 0: FIFO is empty */ + +/* LCD interface Control register LCD_CONTROL, address 0x15000404 */ + +#define LCD_CONTROL_BYASYNCRELCLK (1 << 20) /* Bit 20: Bypass PCLK & LCDLCOK asynch logic */ +#define LCD_CONTROL_IF16 (1 << 19) /* Bit 19: Interface to 16 bit LCD-Controller*/ +#define LCD_CONTROL_LOOPBACK (1 << 18) /* Bit 18: LCD Interface in Loopback mode*/ +#define LCD_CONTROL_MSBFIRST (1 << 17) /* Bit 17: Send multi-byte data MSB first*/ +#define LCD_CONTROL_INVERTERD (1 << 16) /* Bit 16: Invert polarity of E_RD*/ +#define LCD_CONTROL_INVERTCS (1 << 15) /* Bit 15: Invert CS*/ +#define LCD_CONTROL_BUSYRSVALUE (1 << 14) /* Bit 14: Busy check on RS=1*/ +#define LCD_CONTROL_BUSYBITNR_SHIFT (10) /* Bits 10-13: Bit that represents busy flag*/ +#define LCD_CONTROL_BUSYBITNR_MASK (15 << LCD_CONTROL_BUSYBITNR_SHIFT) +#define LCD_CONTROL_BUSYVALUE (1 << 9) /* Bit 9: LCD controller is busy if bit=1*/ +#define LCD_CONTROL_BUSYFLAGCHECK (1 << 8) /* Bit 8: Enable the busy-flag-checking*/ +#define LCD_CONTROL_SERRDPOSS_SHIFT (9) /* Bits 6-7: 7:6 Serial sample mode*/ +#define LCD_CONTROL_SERRDPOSS_MASK (3 << LCD_CONTROL_SERRDPOSS_SHIFT) +# define LCD_CONTROL_SERRDPOSS_START (0 << LCD_CONTROL_SERRDPOSS_SHIFT) /* Sample at beginning of cycle*/ +# define LCD_CONTROL_SERRDPOSS_FOURTH (1 << LCD_CONTROL_SERRDPOSS_SHIFT) /* Sample at 0.25 * cycle*/ +# define LCD_CONTROL_SERRDPOSS_HALF (2 << LCD_CONTROL_SERRDPOSS_SHIFT) /* Sample at 0.5 * cycle*/ +# define LCD_CONTROL_SERRDPOSS_3FOURTHS (3 << LCD_CONTROL_SERRDPOSS_SHIFT) /* Sample at 0.75 * cycle*/ +#define LCD_CONTROL_SERCLKSHIFT_SHIFT (4) /* Bits 4-5: Serial clock mode*/ +#define LCD_CONTROL_SERCLKSHIFT_MASK (3 << LCD_CONTROL_SERCLKSHIFT_SHIFT) +# define LCD_CONTROL_SERCLKSHIFT_MODE0 (0 << LCD_CONTROL_SERCLKSHIFT_SHIFT) /* Clock mode 0*/ +# define LCD_CONTROL_SERCLKSHIFT_MODE1 (1 << LCD_CONTROL_SERCLKSHIFT_SHIFT) /* Clock mode 1*/ +# define LCD_CONTROL_SERCLKSHIFT_MODE2 (2 << LCD_CONTROL_SERCLKSHIFT_SHIFT) /* Clock mode 2*/ +# define LCD_CONTROL_SERCLKSHIFT_MODE3 (3 << LCD_CONTROL_SERCLKSHIFT_SHIFT) /* Clock mode 3*/ +#define LCD_CONTROL_4BIT (1 << 3) /* Bit 2: LCD interface 4 bit mode (vs 8)*/ +#define LCD_CONTROL_MI (1 << 2) /* Bit 2: LCD interface 6800 mode (vs 8080 mode)*/ +#define LCD_CONTROL_PS (1 << 1) /* Bit 1: LCD interface serial mode (vs parallel)*/ + +/* LCD interface Interrupt Raw register LCD_INTRAW, address 0x15000408 + * LCD interface Interrupt Clear register LCD_INTCLEAR, address 0x1500040c + * LCD interface Interrupt Mask register LCD_INTMASK, address 0x15000410 + */ + +#define LCD_INT_READVALID (1 << 3) /* Bit 3: Value that has been read from the LCD controller */ +#define LCD_INT_OVERRUN (1 << 2) /* Bit 2: FIFO overrun */ +#define LCD_INT_FIFOHALFEMPTY (1 << 1) /* Bit 1: FIFO is less then half full */ +#define LCD_INT_FIFO_EMPTY (1 << 0) /* Bit 0: FIFO is empty */ + +/* LCD interface Read Command register LCD_READCMD, address 0x15000414 */ + +#define LCD_READCMD_DATABYTE (1 << 0) /* Bit 0: Read in DATA byte (vs INST) */ + +/* LCD interface Instruction Byte register LCD_INSTBYTE, address 0x15000420 */ + +#define LCD_INSTBYTE_WORD_SHIFT (0) /* Bits 0-15: 16 bit mode = 15:0 Instruction */ +#define LCD_INSTBYTE_WORD_MASK (0xffff << LCD_INSTBYTE_WORD_SHIFT) +#define LCD_INSTBYTE_BYTE_SHIFT (0) /* Bits 0-7: 8 bit mode = 7:0 Instruction */ +#define LCD_INSTBYTE_BYTE_MASK (0xff << LCD_INSTBYTE_BYTE_SHIFT) + +/* LCD interface Data Byte register LCD_DATABYTE, address 0x15000430 */ + +#define LCD_DATABYTE_WORD_SHIFT (0) /* Bits 0-15: 16 bit mode = 15:0 Instruction */ +#define LCD_DATABYTE_WORD_MASK (0xffff << LCD_IDATABYTE_WORD_SHIFT) +#define LCD_DATABYTE_BYTE_SHIFT (0) /* Bits 0-7: 8 bit mode = 7:0 Instruction */ +#define LCD_DATABYTE_BYTE_MASK (0xff << LCD_IDATABYTE_BYTE_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_LCD_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_lowputc.c b/arch/arm/src/lpc31xx/lpc31_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..189ad0b9c73c8d86b932f7ae3044fccaa1646098 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_lowputc.c @@ -0,0 +1,356 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_lowputc.c + * + * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc31_cgudrvr.h" +#include "lpc31_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Is the UART enabled? */ + +#ifdef CONFIG_LPC31_UART +# define HAVE_UART 1 + +/* Is it a serial console? */ + +# ifdef CONFIG_UART_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 + +/* Is initialization performed by up_earlyserialinit()? Or is UART + * initialization suppressed? + */ + +# if defined(USE_EARLYSERIALINIT) || defined(CONFIG_SUPPRESS_UART_CONFIG) +# undef NEED_LOWSETUP +# else +# define NEED_LOWSETUP 1 +# endif +# else +# undef HAVE_CONSOLE +# undef NEED_LOWSETUP +# endif + +#else +# undef HAVE_UART +# undef HAVE_CONSOLE +# undef NEED_LOWSETUP +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +#ifdef HAVE_CONSOLE +static inline void up_waittxready(void) +{ + int tmp; + + /* Limit how long we will wait for the TX available condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check if the tranmitter holding register (THR) is empty */ + + if ((getreg32(LPC31_UART_LSR) & UART_LSR_THRE) != 0) + { + /* The THR is empty, return */ + + break; + } + } +} +#endif + +/**************************************************************************** + * Name: up_configbaud + ****************************************************************************/ + +#ifdef NEED_LOWSETUP +static inline void up_configbaud(void) +{ + /* In a buckled-up, embedded system, there is no reason to constantly + * calculate the following. The calculation can be skipped if the + * MULVAL, DIVADDVAL, and DIVISOR values are provided in the configuration + * file. + */ + +#ifndef CONFIG_LPC31_UART_MULVAL + uint32_t qtrclk; + uint32_t regval; + + /* Test values calculated for every multiplier/divisor combination */ + + uint32_t tdiv; + uint32_t terr; + int tmulval; + int tdivaddval; + + /* Optimal multiplier/divider values */ + + uint32_t div = 0; + uint32_t err = 100000; + int mulval = 1; + int divaddval = 0; + + /* Baud is generated using FDR and DLL-DLM registers + * + * baud = clock * (mulval/(mulval+divaddval) / (16 * div) + * + * Or + * + * div = (clock/16) * (mulval/(mulval+divaddval) / baud + * + * Where mulval = Fractional divider multiplier + * divaddval = Fractional divider pre-scale div + * div = DLL-DLM divisor + */ + + /* Get UART block clock divided by 16 */ + + qtrclk = lpc31_clkfreq(CLKID_UARTUCLK, DOMAINID_UART) >> 4; + + /* Try every valid multiplier, tmulval (or until a perfect + * match is found). + */ + + for (tmulval = 1 ; tmulval <= 15 && err > 0; tmulval++) + { + /* Try every valid pre-scale div, tdivaddval (or until a perfect + * match is found). + */ + + for (tdivaddval = 0 ; tdivaddval <= 15 && err > 0; tdivaddval++) + { + /* Calculate the divisor with these fractional divider settings */ + + uint32_t tmp = (tmulval * qtrclk) / ((tmulval + tdivaddval)); + tdiv = (tmp + (CONFIG_UART_BAUD >> 1)) / CONFIG_UART_BAUD; + + /* Check if this candidate divisor is within a valid range */ + + if (tdiv > 2 && tdiv < 0x10000) + { + /* Calculate the actual baud and the error */ + + uint32_t actualbaud = tmp / tdiv; + + if (actualbaud <= CONFIG_UART_BAUD) + { + terr = CONFIG_UART_BAUD - actualbaud; + } + else + { + terr = actualbaud - CONFIG_UART_BAUD; + } + + /* Is this the smallest error we have encountered? */ + + if (terr < err) + { + /* Yes, save these settings as the new, candidate optimal settings */ + + mulval = tmulval ; + divaddval = tdivaddval; + div = tdiv; + err = terr; + } + } + } + } + + /* Set the Divisor Latch Access Bit (DLAB) to enable DLL/DLM access */ + + regval = getreg32(LPC31_UART_LCR); + regval |= UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the MS and LS DLAB registers */ + + putreg32(div & UART_DLL_MASK, LPC31_UART_DLL); + putreg32((div >> 8) & UART_DLL_MASK, LPC31_UART_DLM); + + regval &= ~UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the Fractional Divider Register (FDR) */ + + putreg32((mulval << UART_FDR_MULVAL_SHIFT) | + (divaddval << UART_FDR_DIVADDVAL_SHIFT), + LPC31_UART_FDR); +#else + /* Set the Divisor Latch Access Bit (DLAB) to enable DLL/DLM access */ + + regval = getreg32(LPC31_UART_LCR); + regval |= UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the MS and LS DLAB registers */ + + putreg32(CONFIG_LPC31_UART_DIVISOR & UART_DLL_MASK, LPC31_UART_DLL); + putreg32((CONFIG_LPC31_UART_DIVISOR >> 8) & UART_DLL_MASK, LPC31_UART_DLM); + + regval &= ~UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the Fractional Divider Register (FDR) */ + + putreg32((CONFIG_LPC31_UART_MULVAL << UART_FDR_MULVAL_SHIFT) | + (CONFIG_LPC31_UART_DIVADDVAL << UART_FDR_DIVADDVAL_SHIFT), + LPC31_UART_FDR); +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc31_lowsetup + * + * Description: + * Called early in up_boot. Performs chip-common low level initialization. + * + ****************************************************************************/ + +void lpc31_lowsetup(void) +{ +#ifdef NEED_LOWSETUP + uint32_t regval; + + /* Enable UART system clock */ + + lpc31_enableclock(CLKID_UARTAPBCLK); + lpc31_enableclock(CLKID_UARTUCLK); + + /* Clear fifos */ + + putreg32((UART_FCR_RXFIFORST | UART_FCR_TXFIFORST), LPC31_UART_FCR); + + /* Set trigger */ + + putreg32((UART_FCR_FIFOENABLE | UART_FCR_RXTRIGLEVEL_16), LPC31_UART_FCR); + + /* Set up the LCR */ + + regval = 0; + +#if CONFIG_UART_BITS == 5 + regval |= UART_LCR_WDLENSEL_5BITS; +#elif CONFIG_UART_BITS == 6 + regval |= UART_LCR_WDLENSEL_6BITS; +#elif CONFIG_UART_BITS == 7 + regval |= UART_LCR_WDLENSEL_7BITS; +#else + regval |= UART_LCR_WDLENSEL_8BITS; +#endif + +#if CONFIG_UART_2STOP > 0 + regval |= UART_LCR_NSTOPBITS; +#endif + +#if CONFIG_UART_PARITY == 1 + regval |= UART_LCR_PAREN; +#elif CONFIG_UART_PARITY == 2 + regval |= (UART_LCR_PAREVEN | UART_LCR_PAREN); +#endif + putreg32(regval, LPC31_UART_LCR); + + /* Set the BAUD divisor */ + + up_configbaud(); + + /* Configure the FIFOs */ + + putreg32((UART_FCR_RXTRIGLEVEL_16 | UART_FCR_TXFIFORST | + UART_FCR_RXFIFORST | UART_FCR_FIFOENABLE), + LPC31_UART_FCR); + + /* The NuttX serial driver waits for the first THRE interrupt before + * sending serial data... However, it appears that the lpc313x hardware + * does not generate that interrupt until a transition from not-empty + * to empty. So, the current kludge here is to send one NULL at + * startup to kick things off. + */ + + putreg32('\0', LPC31_UART_THR); +#endif +} + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + up_waittxready(); + putreg32((uint32_t)ch, LPC31_UART_THR); +#endif +} diff --git a/arch/arm/src/lpc31xx/lpc31_mci.h b/arch/arm/src/lpc31xx/lpc31_mci.h new file mode 100644 index 0000000000000000000000000000000000000000..8314db414d9c44b776e865de6d59cee6564d9e11 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_mci.h @@ -0,0 +1,270 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_mci.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_MCI_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_MCI_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* MCI register base address offset into the MCI domain *****************************************/ + +#define LPC31_MCI_VBASE (LPC31_MCI_VSECTION) +#define LPC31_MCI_PBASE (LPC31_MCI_PSECTION) + +/* MCI register offsets (with respect to the MCI base) ******************************************/ + +#define LPC31_MCI_CTRL_OFFSET 0x000 /* Control register */ +#define LPC31_MCI_PWREN_OFFSET 0x004 /* Reserved */ +#define LPC31_MCI_CLKDIV_OFFSET 0x008 /* Clock-divider register */ +#define LPC31_MCI_CLKSRC_OFFSET 0x00c /* Clock-source register */ +#define LPC31_MCI_CLKENA_OFFSET 0x010 /* Clock-enable register */ +#define LPC31_MCI_TMOUT_OFFSET 0x014 /* Time-out register */ +#define LPC31_MCI_CTYPE_OFFSET 0x018 /* Card-type register */ +#define LPC31_MCI_BLKSIZ_OFFSET 0x01c /* Block-size register */ +#define LPC31_MCI_BYTCNT_OFFSET 0x020 /* Byte-count register */ +#define LPC31_MCI_INTMASK_OFFSET 0x024 /* Interrupt-mask register */ +#define LPC31_MCI_CMDARG_OFFSET 0x028 /* Command-argument register */ +#define LPC31_MCI_CMD_OFFSET 0x02c /* Command register */ +#define LPC31_MCI_RESP0_OFFSET 0x030 /* Response-0 register */ +#define LPC31_MCI_RESP1_OFFSET 0x034 /* Response-1register */ +#define LPC31_MCI_RESP2_OFFSET 0x038 /* Response-2 register */ +#define LPC31_MCI_RESP3_OFFSET 0x03c /* Response-3 register */ +#define LPC31_MCI_MINTSTS_OFFSET 0x040 /* Masked interrupt-status register */ +#define LPC31_MCI_RINTSTS_OFFSET 0x044 /* Raw interrupt-status register */ +#define LPC31_MCI_STATUS_OFFSET 0x048 /* Status register */ +#define LPC31_MCI_FIFOTH_OFFSET 0x04c /* FIFO threshold register */ +#define LPC31_MCI_CDETECT_OFFSET 0x050 /* Card-detect register value */ +#define LPC31_MCI_WRTPRT_OFFSET 0x054 /* Write-protect register */ + /* 0x58: Reserved */ +#define LPC31_MCI_TCBCNT_OFFSET 0x05c /* Transferred CIU card byte count */ +#define LPC31_MCI_TBBCNT_OFFSET 0x060 /* Transferred cpu/DMA to/from BIU-FIFO byte count */ + /* 0x064-0x0ff: Reserved */ +#define LPC31_MCI_DATA_OFFSET 0x100 /* Data FIFO read/write (>=) */ + +/* MCI register (virtual) addresses *************************************************************/ + +#define LPC31_MCI_CTRL (LPC31_MCI_VBASE+LPC31_MCI_CTRL_OFFSET) +#define LPC31_MCI_PWREN (LPC31_MCI_VBASE+LPC31_MCI_PWREN_OFFSET) +#define LPC31_MCI_CLKDIV (LPC31_MCI_VBASE+LPC31_MCI_CLKDIV_OFFSET) +#define LPC31_MCI_CLKSRC (LPC31_MCI_VBASE+LPC31_MCI_CLKSRC_OFFSET) +#define LPC31_MCI_CLKENA (LPC31_MCI_VBASE+LPC31_MCI_CLKENA_OFFSET) +#define LPC31_MCI_TMOUT (LPC31_MCI_VBASE+LPC31_MCI_TMOUT_OFFSET) +#define LPC31_MCI_CTYPE (LPC31_MCI_VBASE+LPC31_MCI_CTYPE_OFFSET) +#define LPC31_MCI_BLKSIZ (LPC31_MCI_VBASE+LPC31_MCI_BLKSIZ_OFFSET) +#define LPC31_MCI_BYTCNT (LPC31_MCI_VBASE+LPC31_MCI_BYTCNT_OFFSET) +#define LPC31_MCI_INTMASK (LPC31_MCI_VBASE+LPC31_MCI_INTMASK_OFFSET) +#define LPC31_MCI_CMDARG (LPC31_MCI_VBASE+LPC31_MCI_CMDARG_OFFSET) +#define LPC31_MCI_CMD (LPC31_MCI_VBASE+LPC31_MCI_CMD_OFFSET) +#define LPC31_MCI_RESP0 (LPC31_MCI_VBASE+LPC31_MCI_RESP0_OFFSET) +#define LPC31_MCI_RESP1 (LPC31_MCI_VBASE+LPC31_MCI_RESP1_OFFSET) +#define LPC31_MCI_RESP2 (LPC31_MCI_VBASE+LPC31_MCI_RESP2_OFFSET) +#define LPC31_MCI_RESP3 (LPC31_MCI_VBASE+LPC31_MCI_RESP3_OFFSET) +#define LPC31_MCI_MINTSTS (LPC31_MCI_VBASE+LPC31_MCI_MINTSTS_OFFSET) +#define LPC31_MCI_RINTSTS (LPC31_MCI_VBASE+LPC31_MCI_RINTSTS_OFFSET) +#define LPC31_MCI_STATUS (LPC31_MCI_VBASE+LPC31_MCI_STATUS_OFFSET) +#define LPC31_MCI_FIFOTH (LPC31_MCI_VBASE+LPC31_MCI_FIFOTH_OFFSET) +#define LPC31_MCI_CDETECT (LPC31_MCI_VBASE+LPC31_MCI_CDETECT_OFFSET) +#define LPC31_MCI_WRTPRT (LPC31_MCI_VBASE+LPC31_MCI_WRTPRT_OFFSET) +#define LPC31_MCI_TCBCNT (LPC31_MCI_VBASE+LPC31_MCI_TCBCNT_OFFSET) +#define LPC31_MCI_TBBCNT (LPC31_MCI_VBASE+LPC31_MCI_TBBCNT_OFFSET) +#define LPC31_MCI_DATA (LPC31_MCI_VBASE+LPC31_MCI_DATA_OFFSET) + +/* MCI register bit definitions *****************************************************************/ + +/* Control register CTRL, address 0x18000000 */ + +#define MCI_CTRL_CEATAINT (1 << 11) /* Bit 11: CE-ATA device interrupts enabled */ +#define MCI_CTRL_AUTOSTOP (1 << 10) /* Bit 10: Send STOP after CCSD to CE-ATA device */ +#define MCI_CTRL_SENDCCSD (1 << 9) /* Bit 9: Send CCSD to CE-ATA device */ +#define MCI_CTRL_ABORTREAD (1 << 8) /* Bit 8: Reset data state-machine (suspend sequence) */ +#define MCI_CTRL_SENDIRQRESP (1 << 7) /* Bit 7: Send auto IRQ response */ +#define MCI_CTRL_READWAIT (1 << 6) /* Bit 6: Assert read wait */ +#define MCI_CTRL_DMAENABLE (1 << 5) /* Bit 5: Enable DMA transfer mode */ +#define MCI_CTRL_INTENABLE (1 << 4) /* Bit 4: Enable interrupts */ +#define MCI_CTRL_DMARESET (1 << 2) /* Bit 2: Reset internal DMA interface control logic */ +#define MCI_CTRL_FIFORESET (1 << 1) /* Bit 1: Reset to data FIFO To reset FIFO pointers */ +#define MCI_CTRL_CNTLRRESET (1 << 0) /* Bit 0: Reset Module controller */ + +/* Clock divider register CLKDIV, address 0x18000008 */ + +#define MCI_CLKDIV_SHIFT (0) /* Bits 0-7: Clock divider */ +#define MCI_CLKDIV_MASK (255 << MCI_CLKDIV_SHIFT) + +/* Clock source register CLKSRC, address 0x1800000c */ + +#define MCI_CLKSRC_SHIFT (0) /* Bits 0-1: Must be zero */ +#define MCI_CLKSRC_MASK (3 << MCI_CLKSRC_SHIFT) + +/* Clock enable register CLKENA, address 0x18000010 */ + +#define MCI_CLKENA_LOWPOWER (1 << 16) /* Bit 16: Low-power mode */ +#define MCI_CLKENA_EMABLE (1 << 0) /* Bit 0: Clock enable */ + +/*Timeout register TMOUT, address 0x18000014 */ + +#define MCI_TMOUT_DATA_SHIFT (8) /* Bits 8-31: Data Read Timeout value */ +#define MCI_TMOUT_DATA_MASK (0x00ffffff << MCI_TMOUT_DATA_SHIFT) +#define MCI_TMOUT_RESPONSE_SHIFT (0) /* Bits 0-7: Response timeout value */ +#define MCI_TMOUT_RESPONSE_MASK (255 << MCI_TMOUT_RESPONSE_SHIFT) + +/* Card type register CTYPE, address 0x18000018 */ + +#define MCI_CTYPE_WIDTH8 (1 << 16) /* Bit 16: 8-bit mode */ +#define MCI_CTYPE_WIDTH4 (1 << 0) /* Bit 0: 4-bit mode */ + +/* Blocksize register BLKSIZ, address 0x1800001c */ + +#define MCI_BLKSIZ_SHIFT (0) /* Bits 0-15: Block size */ +#define MCI_BLKSIZ_MASK (0xffff << MCI_BLKSIZ_SHIFT) + +/* Interrupt mask register INTMASK, address 0x18000024 + * Masked interrupt status register MINTSTS, address 0x18000040 + * Raw interrupt status register RINTSTS, address 0x18000044 + */ + +#define MCI_INT_SDIO (1 << 16) /* Bit 16: Mask SDIO interrupt */ +#define MCI_INT_EBE (1 << 15) /* Bit 15: End-bit error (read)/Write no CRC */ +#define MCI_INT_ACD (1 << 14) /* Bit 14: Auto command done */ +#define MCI_INT_SBE (1 << 13) /* Bit 13: Start-bit error */ +#define MCI_INT_HLE (1 << 12) /* Bit 12: Hardware locked write error */ +#define MCI_INT_FRUN (1 << 11) /* Bit 11: FIFO underrun/overrun error */ +#define MCI_INT_HTO (1 << 10) /* Bit 10: Data starvation-by-cpu timeout */ +#define MCI_INT_DRTO (1 << 9) /* Bit 9: Data read timeout */ +#define MCI_INT_RTO (1 << 8) /* Bit 8: Response timeout */ +#define MCI_INT_DCRC (1 << 7) /* Bit 7: Data CRC error */ +#define MCI_INT_RCRC (1 << 6) /* Bit 6: Response CRC error */ +#define MCI_INT_RXDR (1 << 5) /* Bit 5: Receive FIFO data request */ +#define MCI_INT_TXDR (1 << 4) /* Bit 4: Transmit FIFO data request */ +#define MCI_INT_DTO (1 << 3) /* Bit 3: Data transfer over */ +#define MCI_INT_CD (1 << 2) /* Bit 2: Command done */ +#define MCI_INT_RE (1 << 1) /* Bit 1: Response error */ +#define MCI_INT_CD (1 << 0) /* Bit 0: Card detect */ +#define MCI_INT_ALL (0x1ffff) + +/* Command register CMD, address 0x1800002c */ + +#define MCI_CMD_STARTCMD (1 << 31) /* Bit 31: Start command */ +#define MCI_CMD_CCSEXPTD (1 << 23) /* Bit 23: Expect command completion from CE-ATA device */ +#define MCI_CMD_READCEATA (1 << 22) /* Bit 22: Performing read access on CE-ATA device */ +#define MCI_CMD_UPDCLOCK (1 << 21) /* Bit 21: Update clock register value (no command) */ +#define MCI_CMD_SENDINIT (1 << 15) /* Bit 15: Send initialization sequence before command */ +#define MCI_CMD_STOPABORT (1 << 14) /* Bit 14: Stop current data transfer */ +#define MCI_CMD_WAITPREV (1 << 13) /* Bit 13: Wait previous transfer complete before sending */ +#define MCI_CMD_AUTOSTOP (1 << 12) /* Bit 12: Send stop command at end of data transfer */ +#define MCI_CMD_XFRMODE (1 << 11) /* Bit 11: Stream data transfer command */ +#define MCI_CMD_WRITE (1 << 10) /* Bit 10: Write to card */ +#define MCI_CMD_DATAXFREXPTD (1 << 9) /* Bit 9: Data transfer expected (read/write) */ +#define MCI_CMD_RESPCRC (1 << 8) /* Bit 8: Check response CRC */ +#define MCI_CMD_LONGRESP (1 << 7) /* Bit 7: Long response expected from card */ +#define MCI_CMD_RESPONSE (1 << 6) /* Bit 6: Response expected from card */ +#define MCI_CMD_CMDINDEX_SHIFT (0) /* Bits 0-5: 5:0 Command index */ +#define MCI_CMD_CMDINDEX_MASK (63 << MCI_CMD_CMDINDEX_SHIFT) + +/* Status register STATUS, address 0x18000048 */ + +#define MCI_STATUS_DMAREQ (1 << 31) /* Bit 31: DMA request signal state */ +#define MCI_STATUS_DMAACK (1 << 30) /* Bit 30: DMA acknowledge signal state */ +#define MCI_STATUS_FIFOCOUNT_SHIFT (17) /* Bits 17-29: FIFO count */ +#define MCI_STATUS_FIFOCOUNT_MASK (0x1fff << MCI_STATUS_FIFOCOUNT_SHIFT) +#define MCI_STATUS_RESPINDEX_SHIFT (11) /* Bits 11-16: Index of previous response */ +#define MCI_STATUS_RESPINDEX_MASK (63 << MCI_STATUS_RESPINDEX_SHIFT) +#define MCI_STATUS_MCBUSY (1 << 10) /* Bit 10: Data transmit/receive state machine busy */ +#define MCI_STATUS_DATABUSY (1 << 9) /* Bit 9: Card data busy */ +#define MCI_STATUS_DAT3 (1 << 8) /* Bit 8: DAT3=1: Card present */ +#define MCI_STATUS_FSMSTATE_SHIFT (4) /* Bits 4-7: 7:4 Command FSM states */ +#define MCI_STATUS_FSMSTATE_MASK (15 << MCI_STATUS_FSMSTATE_SHIFT) +# define MCI_STATUS_FSMSTATE_IDLE (0 << MCI_STATUS_FSMSTATE_SHIFT) /* Idle */ +# define MCI_STATUS_FSMSTATE_INIT (1 << MCI_STATUS_FSMSTATE_SHIFT) /* Send init sequence */ +# define MCI_STATUS_FSMSTATE_TXSTART (2 << MCI_STATUS_FSMSTATE_SHIFT) /* Tx cmd start bit */ +# define MCI_STATUS_FSMSTATE_TXTXBIT (3 << MCI_STATUS_FSMSTATE_SHIFT) /* Tx cmd tx bit */ +# define MCI_STATUS_FSMSTATE_TXCMDARG (4 << MCI_STATUS_FSMSTATE_SHIFT) /* Tx cmd index + arg */ +# define MCI_STATUS_FSMSTATE_TXCMDCRC (5 << MCI_STATUS_FSMSTATE_SHIFT) /* Tx cmd crc7 */ +# define MCI_STATUS_FSMSTATE_TXEND (6 << MCI_STATUS_FSMSTATE_SHIFT) /* Tx cmd end bit */ +# define MCI_STATUS_FSMSTATE_RXSTART (7 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp start bit */ +# define MCI_STATUS_FSMSTATE_RXIRQ (8 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp IRQ response */ +# define MCI_STATUS_FSMSTATE_RXTXBIT (9 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp tx bit */ +# define MCI_STATUS_FSMSTATE_RXCMD (10 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp cmd idx */ +# define MCI_STATUS_FSMSTATE_RXRESP (11 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp data */ +# define MCI_STATUS_FSMSTATE_RXRESPCRC (12 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp crc7 */ +# define MCI_STATUS_FSMSTATE_RXEND (13 << MCI_STATUS_FSMSTATE_SHIFT) /* Rx resp end bit */ +# define MCI_STATUS_FSMSTATE_WAITNCC (14 << MCI_STATUS_FSMSTATE_SHIFT) /* Cmd path wait NCC */ +# define MCI_STATUS_FSMSTATE_WAITTURN (15 << MCI_STATUS_FSMSTATE_SHIFT) /* Wait; CMD-to-response turnaround */ +#define MCI_STATUS_FIFOFULL (1 << 3) /* Bit 3: FIFO is full */ +#define MCI_STATUS_FIFOEMPTY (1 << 2) /* Bit 2: FIFO is empty */ +#define MCI_STATUS_TXWMARK (1 << 1) /* Bit 1: FIFO reached Transmit watermark level */ +#define MCI_STATUS_RXWMARK (1 << 0) /* Bit 0: FIFO reached Receive watermark level */ + +/* FIFO threshold register FIFOTH, address 0x1800004c */ + +#define MCI_FIFOTH_DMABURST_SHIFT (28) /* Bits 28-30: Burst size for multiple transaction */ +#define MCI_FIFOTH_DMABURST_MASK (7 << MCI_FIFOTH_DMABURST_SHIFT) + define MCI_FIFOTH_DMABURST_1XFR (0 << MCI_FIFOTH_DMABURST_SHIFT) /* 1 transfer */ +# define MCI_FIFOTH_DMABURST_4XFRS (1 << MCI_FIFOTH_DMABURST_SHIFT) /* 4 transfers */ +# define MCI_FIFOTH_DMABURST_8XFRS (2 << MCI_FIFOTH_DMABURST_SHIFT) /* 8 transfers */ +#define MCI_FIFOTH_RXWMARK_SHIFT (16) /* Bits 16-27: FIFO threshold level when receiving */ +#define MCI_FIFOTH_RXWMARK_MASK (0xfff << MCI_FIFOTH_RXWMARK_SHIFT) +#define MCI_FIFOTH_TXWMARK_SHIFT (0) /* Bits 0-11: FIFO threshold level when transmitting */ +#define MCI_FIFOTH_TXWMARK_MASK (0xfff << MCI_FIFOTH_TXWMARK_SHIFT) + +/* Card detect register CDETECT, address 0x18000050 */ + +#define MCI_CDETECT_NOTPRESENT (1 << 0) + +/* Write protect register WRTPRT, address 0x18000054 */ + +#define MCI_WRTPRT_PROTECTED (1 << 0) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_MCI_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_memorymap.h b/arch/arm/src/lpc31xx/lpc31_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..aa5ac8178881ee9bd1784aa2e444903b27eb1ab0 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_memorymap.h @@ -0,0 +1,419 @@ +/************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_memorymap.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* LPC31XX Physical (unmapped) Memory Map */ + +#define LPC31_FIRST_PSECTION 0x00000000 /* Beginning of the physical address space */ +#define LPC31_SHADOWSPACE_PSECTION 0x00000000 /* 0x00000000-0x00000fff: Shadow Area 4Kb */ + /* 0x00001000-0xff027fff: Reserved */ +#define LPC31_INTSRAM_PSECTION 0x11028000 /* Internal SRAM 0+1 192Kb */ +# define LPC31_INTSRAM0_PADDR 0x11028000 /* 0x11028000-0x1103ffff: Internal SRAM 0 96Kb */ +# define LPC31_INTSRAM1_PADDR 0x11040000 /* 0x11040000-0x11057fff: Internal SRAM 1 96Kb */ + /* 0x11058000-11ffffffff: Reserved */ +#define LPC31_INTSROM0_PSECTION 0x12000000 /* 0x12000000-0x1201ffff: Internal SROM 0 128Kb */ + /* 0x12020000-0x12ffffff: Reserved */ +#define LPC31_APB01_PSECTION 0x13000000 /* 0x13000000-0x1300bfff: APB0 32Kb APB1 16Kb */ +# define LPC31_APB0_PADDR 0x13000000 /* 0x13000000-0x13007fff: APB0 32Kb */ +# define LPC31_APB1_PADDR 0x13008000 /* 0x13008000-0x1300bfff: APB1 16Kb */ + /* 0x1300c000-0x14ffffff: Reserved */ +#define LPC31_APB2_PSECTION 0x15000000 /* 0x15000000-0x15003fff: APB2 16Kb */ +#define LPC31_APB3_PSECTION 0x16000000 /* 0x16000000-0x160003ff: APB3 1Kb */ +#define LPC31_APB4MPMC_PSECTION 0x17000000 /* 8Kb */ +# define LPC31_APB4_PADDR 0x17000000 /* 0x17000000-0x17000fff: APB4 4Kb */ +# define LPC31_MPMC_PADDR 0x17008000 /* 0x17008000-0x17008fff: MPMC cfg 4Kb */ + /* 0x17009000-0x17ffffff: Reserved */ +#define LPC31_MCI_PSECTION 0x18000000 /* 0x18000000 0x180003ff: MCI/SD/SDIO 1Kb */ + /* 0x18000900-0x18ffffff: Reserved */ +#define LPC31_USBOTG_PSECTION 0x19000000 /* 0x19000000-0x19000fff: USB OTG 4Kb */ + /* 0x19001000-0x1fffffff: Reserved */ +#define LPC31_EXTSRAM_PSECTION 0x20000000 /* 64-128Kb */ +# define LPC31_EXTSRAM0_PADDR 0x20000000 /* 0x20000000-0x2001ffff: External SRAM 0 64-128Kb */ +# define LPC31_EXTSRAM1_PADDR 0x20020000 /* 0x20020000-0x2003ffff: External SRAM 1 64-128Kb */ +#define LPC31_EXTSDRAM0_PSECTION 0x30000000 /* 0x30000000-0x37ffffff: External SDRAM 0 128Mb */ + /* 0x40000000-0x5fffffff: Reserved */ +#define LPC31_INTC_PSECTION 0x60000000 /* 0x60000000-0x60000fff: Interrupt controller 4Kb */ + /* 0x60001000-0x6fffffff: Reserved */ +#define LPC31_NAND_PSECTION 0x70000000 /* 0x70000000-0x700007ff: NANDFLASH Ctrl 2Kb */ + /* 0x70000800-0xffffffff: Reserved */ +#ifdef CONFIG_LPC31_EXTNAND /* End of the physical address space */ +# define LPC31_LAST_PSECTION (LPC31_NAND_PSECTION + (1 << 20)) +#else +# define LPC31_LAST_PSECTION (LPC31_INTC_PSECTION + (1 << 20)) +#endif + +/* APB0-4 Domain Offsets */ + +#define LPC31_APB0_EVNTRTR_OFFSET 0x00000000 /* Event Router */ +#define LPC31_APB0_ADC_OFFSET 0x00002000 /* ADC 10-bit */ +#define LPC31_APB0_WDT_OFFSET 0x00002400 /* WDT */ +#define LPC31_APB0_SYSCREG_OFFSET 0x00002800 /* SYSCREG block */ +#define LPC31_APB0_IOCONFIG_OFFSET 0x00003000 /* IOCONFIG */ +#define LPC31_APB0_GCU_OFFSET 0x00004000 /* GCU */ +#define LPC31_APB0_OTP_OFFSET 0x00005000 /* USB OTP (LPC315x only) */ +#define LPC31_APB0_RNG_OFFSET 0x00006000 /* RNG */ + +#define LPC31_APB1_TIMER0_OFFSET 0x00000000 /* TIMER0 */ +#define LPC31_APB1_TIMER1_OFFSET 0x00000400 /* TIMER1 */ +#define LPC31_APB1_TIMER2_OFFSET 0x00000800 /* TIMER2 */ +#define LPC31_APB1_TIMER3_OFFSET 0x00000c00 /* TIMER3 */ +#define LPC31_APB1_PWM_OFFSET 0x00001000 /* PWM */ +#define LPC31_APB1_I2C0_OFFSET 0x00002000 /* I2C0 */ +#define LPC31_APB1_I2C1_OFFSET 0x00002400 /* I2C1 */ + +#define LPC31_APB2_PCM_OFFSET 0x00000000 /* PCM */ +#define LPC31_APB2_LCD_OFFSET 0x00000400 /* LCD */ + /* 0x00000800 Reserved */ +#define LPC31_APB2_UART_OFFSET 0x00001000 /* UART */ +#define LPC31_APB2_SPI_OFFSET 0x00002000 /* SPI */ + /* 0x00003000 Reserved */ + +#define LPC31_APB3_I2SCONFIG_OFFSET 0x00000000 /* I2S System Configuration */ +#define LPC31_APB3_I2STX0_OFFSET 0x00000080 /* I2S TX0 */ +#define LPC31_APB3_I2STX1_OFFSET 0x00000100 /* I2S TX1 */ +#define LPC31_APB3_I2SRX0_OFFSET 0x00000180 /* I2S RX0 */ +#define LPC31_APB3_I2SRX1_OFFSET 0x00000200 /* I2S RX1 */ + /* 0x00000280 Reserved */ + +#define LPC31_APB4_DMA_OFFSET 0x00000000 /* DMA */ +#define LPC31_APB4_NAND_OFFSET 0x00000800 /* NAND FLASH Controller */ + /* 0x00001000 Reserved */ + +/* Sizes of memory regions in bytes */ + +#define LPC31_SHADOWSPACE_SIZE (4*1024) +#define LPC31_INTSRAM0_SIZE (96*1024) +#define LPC31_INTSRAM1_SIZE (96*1024) +#define LPC31_INTSROM0_SIZE (128*1024) +#define LPC31_APB0_SIZE (32*1024) +#define LPC31_APB1_SIZE (16*1024) +#define LPC31_APB2_SIZE (16*1024) +#define LPC31_APB3_SIZE (1*1024) +#define LPC31_APB4_SIZE (4*1024) +#define LPC31_MPMC_SIZE (4*1024) +#define LPC31_APB4MPMC_SIZE (LPC31_APB4_SIZE+LPC31_MPMC_SIZE) +#define LPC31_MCI_SIZE (1*1024) +#define LPC31_USBOTG_SIZE (4*1024) +#define LPC31_INTC_SIZE (4*1024) +#define LPC31_NAND_SIZE (2*1024) + +#ifdef HAVE_INTSRAM1 +# define LPC31_ISRAM_SIZE (LPC31_INTSRAM0_SIZE+LPC31_INTSRAM1_SIZE) +#else +# define LPC31_ISRAM_SIZE LPC31_INTSRAM0_SIZE +#endif + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of sections/regions. The boot logic in lpc31_boot.c, will select + * 1Mb level 1 MMU mappings to span the entire physical address space. + * The definitions below specify the number of 1Mb entries that are + * required to span a particular address region. + */ + +#define LPC31_SHADOWSPACE_NSECTIONS 1 /* 4Kb - <1 section */ +#define LPC31_INTSRAM_NSECTIONS 1 /* 96 or 192Kb - <1 section */ +#define LPC31_APB01_NSECTIONS 1 /* 32Kb - <1 section */ +#define LPC31_INTSROM0_NSECTIONS 1 /* 128Kb - <1 section */ +#define LPC31_APB1_NSECTIONS 1 /* 16Kb - <1 section */ +#define LPC31_APB2_NSECTIONS 1 /* 16Kb - <1 section */ +#define LPC31_APB3_NSECTIONS 1 /* 1Kb - <1 section */ +#define LPC31_APB4MPMC_NSECTIONS 1 /* 8Kb - <1 section */ +#define LPC31_MCI_NSECTIONS 1 /* 1Kb - <1 section */ +#define LPC31_USBOTG_NSECTIONS 1 /* 4Kb - <1 section */ +#define LPC31_EXTSRAM_NSECTIONS 1 /* 64-128Kb - <1 section */ +#define LPC31_INTC_NSECTIONS 1 /* 4Kb - <1 section */ +#define LPC31_NAND_NSECTIONS 1 /* 2Kb - <1 section */ + +/* External SDRAM is a special case -- the number of sections depends upon + * the size of the SDRAM installed. + */ + +#if defined(CONFIG_LPC31_EXTDRAM) && CONFIG_LPC31_EXTDRAMSIZE > 0 +# define LPC31_EXTSDRAM0_NSECTIONS _NSECTIONS(CONFIG_LPC31_EXTDRAMSIZE) +#endif + +/* Section MMU Flags */ + +#define LPC31_SHADOWSPACE_MMUFLAGS MMU_ROMFLAGS +#define LPC31_INTSRAM_MMUFLAGS MMU_MEMFLAGS +#define LPC31_INTSROM_MMUFLAGS MMU_MEMFLAGS +#define LPC31_APB01_MMUFLAGS MMU_IOFLAGS +#define LPC31_APB2_MMUFLAGS MMU_IOFLAGS +#define LPC31_APB3_MMUFLAGS MMU_IOFLAGS +#define LPC31_APB4MPMC_MMUFLAGS MMU_IOFLAGS +#define LPC31_MCI_MMUFLAGS MMU_IOFLAGS +#define LPC31_USBOTG_MMUFLAGS MMU_IOFLAGS +#define LPC31_EXTSRAM_MMUFLAGS MMU_MEMFLAGS +#define LPC31_EXTSDRAM_MMUFLAGS MMU_MEMFLAGS +#define LPC31_INTC_MMUFLAGS MMU_IOFLAGS +#define LPC31_NAND_MMUFLAGS MMU_IOFLAGS + +/* board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* LPC31XX Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +# define LPC31_FIRST_VSECTION 0x00000000 /* Beginning of the virtual address space */ +# define LPC31_SHADOWSPACE_VSECTION 0x00000000 /* 0x00000000-0x00000fff: Shadow Area 4Kb */ +# define LPC31_INTSRAM_VSECTION 0x11028000 /* Internal SRAM 96Kb-192Kb */ +# define LPC31_INTSRAM0_VADDR 0x11028000 /* 0x11028000-0x1103ffff: Internal SRAM 0 96Kb */ +# define LPC31_INTSRAM1_VADDR 0x11040000 /* 0x11040000-0x11057fff: Internal SRAM 1 96Kb */ +# define LPC31_INTSROM0_VSECTION 0x12000000 /* 0x12000000-0x1201ffff: Internal SROM 0 128Kb */ +# define LPC31_APB01_VSECTION 0x13000000 /* 0x13000000-0x1300bfff: APB0 32Kb APB0 32Kb */ +# define LPC31_APB0_VADDR 0x13000000 /* 0x13000000-0x13007fff: APB0 32Kb */ +# define LPC31_APB1_VADDR 0x13008000 /* 0x13008000-0x1300bfff: APB1 16Kb */ +# define LPC31_APB2_VSECTION 0x15000000 /* 0x15000000-0x15003fff: APB2 16Kb */ +# define LPC31_APB3_VSECTION 0x16000000 /* 0x16000000-0x160003ff: APB3 1Kb */ +# define LPC31_APB4MPMC_VSECTION 0x17000000 /* 8Kb */ +# define LPC31_APB4_VADDR 0x17000000 /* 0x17000000-0x17000fff: APB4 4Kb */ +# define LPC31_MPMC_VADDR 0x17008000 /* 0x17008000-0x17008fff: MPMC cfg 4Kb */ +# define LPC31_MCI_VSECTION 0x18000000 /* 0x18000000 0x180003ff: MCI/SD/SDIO 1Kb */ +# define LPC31_USBOTG_VSECTION 0x19000000 /* 0x19000000-0x19000fff: USB OTG 4Kb */ +# define LPC31_EXTSRAM_VSECTION 0x20020000 /* 64-128Kb */ +# define LPC31_EXTSRAM0_VADDR 0x20000000 /* 0x20000000-0x2001ffff: External SRAM 0 64-128Kb */ +# define LPC31_EXTSRAM1_VADDR 0x20020000 /* 0x20020000-0x2003ffff: External SRAM 1 64-128Kb */ +# define LPC31_EXTSDRAM0_VSECTION 0x30000000 /* 0x30000000-0x37ffffff: External SDRAM 0 128Mb */ +# define LPC31_INTC_VSECTION 0x60000000 /* 0x60000000-0x60000fff: Interrupt controller 4Kb */ +# define LPC31_NAND_VSECTION 0x70000000 /* 0x70000000-0x700007ff: NANDFLASH Ctrl 2Kb */ +# +# ifdef CONFIG_LPC31_EXTNAND /* End of the virtual address space */ +# define LPC31_LAST_VSECTION (LPC31_NAND_VSECTION + (1 << 20)) +# else +# define LPC31_LAST_VSECTION (LPC31_INTC_VSECTION + (1 << 20)) +# endif +#endif + +/* The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX could be running from NOR FLASH, + * SDRAM, external SRAM, or ISRAM. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) +# define NUTTX_START_VADDR LPC31_MPMC_VADDR +# define NUTTX_START_PADDR LPC31_MPMC_PADDR +#elif defined(CONFIG_BOOT_RUNFROMSDRAM) +# define NUTTX_START_VADDR LPC31_EXTSDRAM0_VSECTION +# define NUTTX_START_PADDR LPC31_EXTSDRAM0_PSECTION +#elif defined(CONFIG_BOOT_RUNFROMEXTSRAM) +# define NUTTX_START_VADDR LPC31_EXTSRAM0_VADDR +# define NUTTX_START_PADDR LPC31_EXTSRAM0_PADDR +#else /* CONFIG_BOOT_RUNFROMISRAM, CONFIG_PAGING */ +# define NUTTX_START_VADDR LPC31_INTSRAM0_VADDR +# define NUTTX_START_PADDR LPC31_INTSRAM0_PADDR +#endif + +/* Determine the address of the MMU page table. We will try to place that page + * table at the beginng of ISRAM0 if the vectors are at the high address, 0xffff:0000 + * or at the end of ISRAM1 (or ISRAM0 if ISRAM1 is not available in this architecture) + * if the vectors are at 0x0000:0000 + * + * Or... the user may specify the address of the page table explicitly be defining + * PGTABLE_BASE_VADDR and PGTABLE_BASE_PADDR in the board.h file. + */ + +#undef PGTABLE_IN_HIGHSRAM +#undef PGTABLE_IN_LOWSRAM + +#if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# else + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. + * + * We work around this header file interdependency by (1) insisting that + * pg_macros.h be included AFTER this header file, then (2) allowing the + * pg_macros.h header file to redefine PGTABLE_BASE_VADDR. + */ + +# if defined(CONFIG_PAGING) && defined(__ARCH_ARM_SRC_ARM_PG_MACROS_H) +# error "pg_macros.h must be included AFTER this header file" +# endif + + + /* We must declare the page table in ISRAM0 or 1. We decide depending upon + * where the vector table was place. + */ + +# ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + + /* In this case, ISRAM0 will be shadowed at address 0x0000:0000. The page + * table must lie at the top 16Kb of ISRAM1 (or ISRAM0 if this is a ISRAM1 is + * not available in this architecture) + */ + +# ifdef HAVE_INTSRAM1 +# define PGTABLE_BASE_PADDR (LPC31_INTSRAM1_PADDR+LPC31_INTSRAM1_SIZE-PGTABLE_SIZE) +# define PGTABLE_BASE_VADDR (LPC31_INTSRAM1_VADDR+LPC31_INTSRAM1_SIZE-PGTABLE_SIZE) +# else +# define PGTABLE_BASE_PADDR (LPC31_INTSRAM0_PADDR+LPC31_INTSRAM0_SIZE-PGTABLE_SIZE) +# define PGTABLE_BASE_VADDR (LPC31_INTSRAM0_VADDR+LPC31_INTSRAM0_SIZE-PGTABLE_SIZE) +# endif +# define PGTABLE_IN_HIGHSRAM 1 + + /* If CONFIG_PAGING is defined, insist that pg_macros.h assign the virtual + * address of the page table. + */ + +# ifdef CONFIG_PAGING +# undef PGTABLE_BASE_VADDR +# endif +# else + + /* Otherwise, ISRAM1 (or ISRAM0 for the is ISRAM1 is not available in this + * architecture) will be mapped so that the end of the SRAM region will + * provide memory for the vectors. The page table will then be places at + * the first 16Kb of ISRAM0 (which will be in the shadow memory region). + */ + +# define PGTABLE_BASE_PADDR LPC31_SHADOWSPACE_PSECTION +# define PGTABLE_BASE_VADDR LPC31_SHADOWSPACE_VSECTION +# define PGTABLE_IN_LOWSRAM 1 +# endif +# endif +#endif + +/* Page table start addresses: + * + * 16Kb of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation). We will reuse this memory for coarse page tables as follows: + * + * NOTE: If CONFIG_PAGING is defined, pg_macros.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_COARSE_OFFSET ((((LPC31_LAST_PSECTION >> 20) + 255) & ~255) << 2) +#define PGTABLE_L2_COARSE_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_COARSE_OFFSET) +#define PGTABLE_L2_COARSE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_COARSE_OFFSET) + +#define PGTABLE_L2_FINE_OFFSET ((((LPC31_LAST_PSECTION >> 20) + 1023) & ~1023) << 2) +#define PGTABLE_L2_FINE_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_FINE_OFFSET) +#define PGTABLE_L2_FINE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_FINE_OFFSET) + +/* Page table end addresses: */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_BASE_PADDR+PGTABLE_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_BASE_VADDR+PGTABLE_SIZE) + +/* Page table sizes */ + +#define PGTABLE_L2_COARSE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_COARSE_VBASE) +#define PGTABLE_COARSE_TABLE_SIZE (4*256) +#define PGTABLE_NCOARSE_TABLES (PGTABLE_L2_COARSE_ALLOC / PGTABLE_COARSE_TABLE_SIZE) + +#define PGTABLE_L2_FINE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_FINE_VBASE) +#define PGTABLE_FINE_TABLE_SIZE (4*1024) +#define PGTABLE_NFINE_TABLES (PGTABLE_L2_FINE_ALLOC / PGTABLE_FINE_TABLE_SIZE) + +/* Determine the base address of the vector table: + * + * LPC31_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * LPC31_VECTOR_VSRAM - Virtual address of vector table in SRAM + * LPC31_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + +#define VECTOR_TABLE_SIZE 0x00010000 +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ +# define LPC31_VECTOR_PADDR LPC31_INTSRAM0_PADDR +# define LPC31_VECTOR_VSRAM LPC31_INTSRAM0_VADDR +# define LPC31_VECTOR_VADDR 0x00000000 +# define LPC31_VECTOR_VCOARSE 0x00000000 +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ +# ifdef HAVE_INTSRAM1 +# define LPC31_VECTOR_PADDR (LPC31_INTSRAM1_PADDR+LPC31_INTSRAM1_SIZE-VECTOR_TABLE_SIZE) +# define LPC31_VECTOR_VSRAM (LPC31_INTSRAM1_VADDR+LPC31_INTSRAM1_SIZE-VECTOR_TABLE_SIZE) +# else +# define LPC31_VECTOR_PADDR (LPC31_INTSRAM0_PADDR+LPC31_INTSRAM0_SIZE-VECTOR_TABLE_SIZE) +# define LPC31_VECTOR_VSRAM (LPC31_INTSRAM0_VADDR+LPC31_INTSRAM0_SIZE-VECTOR_TABLE_SIZE) +# endif +# define LPC31_VECTOR_VADDR 0xffff0000 +# define LPC31_VECTOR_VCOARSE 0xfff00000 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_mpmc.h b/arch/arm/src/lpc31xx/lpc31_mpmc.h new file mode 100644 index 0000000000000000000000000000000000000000..5c2b8761a6b0f6de35a44fc2eafbf299694502b1 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_mpmc.h @@ -0,0 +1,340 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_mpmc.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_MPMC_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_MPMC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* MPMC register base address offset into the MPMC domain ***************************************/ + +#define LPC31_MPMC_VBASE (LPC31_MPMC_VADDR) +#define LPC31_MPMC_PBASE (LPC31_MPMC_PADDR) + +/* MPMC register offsets (with respect to the base of the MPMC domain) **************************/ + +#define LPC31_MPMC_CONTROL_OFFSET 0x000 /* Control Register */ +#define LPC31_MPMC_STATUS_OFFSET 0x004 /* Status Register */ +#define LPC31_MPMC_CONFIG_OFFSET 0x008 /* Configuration register */ +#define LPC31_MPMC_DYNCONTROL_OFFSET 0x020 /* Dynamic Memory Control Register */ +#define LPC31_MPMC_DYNREFRESH_OFFSET 0x024 /* Dynamic Memory Refresh Timer Register */ +#define LPC31_MPMC_DYNREADCONFIG_OFFSET 0x028 /* Dynamic Memory Read Configuration Register */ +#define LPC31_MPMC_DYNTRP_OFFSET 0x030 /* Dynamic Memory Precharge Command Period Register */ +#define LPC31_MPMC_DYNTRAS_OFFSET 0x034 /* Dynamic Memory Active To Precharge Command Period Register */ +#define LPC31_MPMC_DYNTSREX_OFFSET 0x038 /* Dynamic Memory Self-refresh Exit Time Register */ +#define LPC31_MPMC_DYNTAPR_OFFSET 0x03c /* Dynamic Memory Last Data Out To Active Time Register */ +#define LPC31_MPMC_DYNTDAL_OFFSET 0x040 /* Dynamic Memory Data-in To Active Command Time Register */ +#define LPC31_MPMC_DYNTWR_OFFSET 0x044 /* Dynamic Memory Write Recovery Time Register */ +#define LPC31_MPMC_DYNTRC_OFFSET 0x048 /* Dynamic Memory Active To Active Command Period Register */ +#define LPC31_MPMC_DYNTRFC_OFFSET 0x04c /* Dynamic Memory Auto-refresh Period Register */ +#define LPC31_MPMC_DYNTXSR_OFFSET 0x050 /* Dynamic Memory Exit Self-refresh Register */ +#define LPC31_MPMC_DYNTRRD_OFFSET 0x054 /* Dynamic Memory Active Bank A to Active Bank B Time Register */ +#define LPC31_MPMC_DYNTMRD_OFFSET 0x058 /* Dynamic Memory Load Mode Register To Active Command Time Register */ +#define LPC31_MPMC_STEXTWAIT_OFFSET 0x080 /* Static Memory Extended Wait Register */ +#define LPC31_MPMC_DYNCONFIG0_OFFSET 0x100 /* Dynamic Memory Configuration Registers 0 */ +#define LPC31_MPMC_DYNRASCAS0_OFFSET 0x104 /* Dynamic Memory RAS and CAS Delay Registers 0 */ + /* 0x120-0x164: reserved */ +#define LPC31_MPMC_STCONFIG0_OFFSET 0x200 /* Static Memory Configuration Registers 0 */ +#define LPC31_MPMC_STWAITWEN0_OFFSET 0x204 /* Static Memory Write Enable Delay Registers 0 */ +#define LPC31_MPMC_STWAITOEN0_OFFSET 0x208 /* Static Memory Output Enable Delay Registers 0 */ +#define LPC31_MPMC_STWAITRD0_OFFSET 0x20c /* Static Memory Read Delay Registers 0 */ +#define LPC31_MPMC_STWAITPAGE0_OFFSET 0x210 /* Static Memory Page Mode Read Delay Registers 0 */ +#define LPC31_MPMC_STWAITWR0_OFFSET 0x214 /* Static Memory Write Delay Registers 0 */ +#define LPC31_MPMC_STWAITTURN0_OFFSET 0x218 /* Static Memory Turn Round Delay Registers 0 */ +#define LPC31_MPMC_STCONFIG1_OFFSET 0x220 /* tatic Memory Configuration Registers 1 */ +#define LPC31_MPMC_STWAITWEN1_OFFSET 0x224 /* Static Memory Write Enable Delay Registers 1 */ +#define LPC31_MPMC_STWAITOEN1_OFFSET 0x228 /* Static Memory Output Enable Delay Registers 1 */ +#define LPC31_MPMC_STWAITRD1_OFFSET 0x22c /* Static Memory Read Delay Registers 1 */ +#define LPC31_MPMC_STWAITPAGE1_OFFSET 0x230 /* Static Memory Page Mode Read Delay Registers 1 */ +#define LPC31_MPMC_STWAITWR1_OFFSET 0x234 /* Static Memory Write Delay Registers 1 */ +#define LPC31_MPMC_STWAITTURN1_OFFSET 0x238 /* Static Memory Turn Round Delay Registers 1 */ + /* 0x240-0x278: Reserverd */ + +/* MPMC register (virtual) addresses ************************************************************/ + +#define LPC31_MPMC_CONTROL (LPC31_MPMC_VBASE+LPC31_MPMC_CONTROL_OFFSET) +#define LPC31_MPMC_STATUS (LPC31_MPMC_VBASE+LPC31_MPMC_STATUS_OFFSET) +#define LPC31_MPMC_CONFIG (LPC31_MPMC_VBASE+LPC31_MPMC_CONFIG_OFFSET) +#define LPC31_MPMC_DYNCONTROL (LPC31_MPMC_VBASE+LPC31_MPMC_DYNCONTROL_OFFSET) +#define LPC31_MPMC_DYNREFRESH (LPC31_MPMC_VBASE+LPC31_MPMC_DYNREFRESH_OFFSET) +#define LPC31_MPMC_DYNREADCONFIG (LPC31_MPMC_VBASE+LPC31_MPMC_DYNREADCONFIG_OFFSET) +#define LPC31_MPMC_DYNTRP (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTRP_OFFSET) +#define LPC31_MPMC_DYNTRAS (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTRAS_OFFSET) +#define LPC31_MPMC_DYNTSREX (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTSREX_OFFSET) +#define LPC31_MPMC_DYNTAPR (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTAPR_OFFSET) +#define LPC31_MPMC_DYNTDAL (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTDAL_OFFSET) +#define LPC31_MPMC_DYNTWR (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTWR_OFFSET) +#define LPC31_MPMC_DYNTRC (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTRC_OFFSET) +#define LPC31_MPMC_DYNTRFC (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTRFC_OFFSET) +#define LPC31_MPMC_DYNTXSR (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTXSR_OFFSET) +#define LPC31_MPMC_DYNTRRD (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTRRD_OFFSET) +#define LPC31_MPMC_DYNTMRD (LPC31_MPMC_VBASE+LPC31_MPMC_DYNTMRD_OFFSET) +#define LPC31_MPMC_STEXTWAIT (LPC31_MPMC_VBASE+LPC31_MPMC_STEXTWAIT_OFFSET) +#define LPC31_MPMC_DYNCONFIG0 (LPC31_MPMC_VBASE+LPC31_MPMC_DYNCONFIG0_OFFSET) +#define LPC31_MPMC_DYNRASCAS0 (LPC31_MPMC_VBASE+LPC31_MPMC_DYNRASCAS0_OFFSET) +#define LPC31_MPMC_STCONFIG0 (LPC31_MPMC_VBASE+LPC31_MPMC_STCONFIG0_OFFSET) +#define LPC31_MPMC_STWAITWEN0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITWEN0_OFFSET) +#define LPC31_MPMC_STWAITOEN0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITOEN0_OFFSET) +#define LPC31_MPMC_STWAITRD0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITRD0_OFFSET) +#define LPC31_MPMC_STWAITPAGE0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITPAGE0_OFFSET) +#define LPC31_MPMC_STWAITWR0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITWR0_OFFSET) +#define LPC31_MPMC_STWAITTURN0 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITTURN0_OFFSET) +#define LPC31_MPMC_STCONFIG1 (LPC31_MPMC_VBASE+LPC31_MPMC_STCONFIG1_OFFSET) +#define LPC31_MPMC_STWAITWEN1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITWEN1_OFFSET) +#define LPC31_MPMC_STWAITOEN1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITOEN1_OFFSET) +#define LPC31_MPMC_STWAITRD1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITRD1_OFFSET) +#define LPC31_MPMC_STWAITPAGE1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITPAGE1_OFFSET) +#define LPC31_MPMC_STWAITWR1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITWR1_OFFSET) +#define LPC31_MPMC_STWAITTURN1 (LPC31_MPMC_VBASE+LPC31_MPMC_STWAITTURN1_OFFSET) + +/* MPMC register bit definitions ****************************************************************/ +/* MPMCControl (address 0x17008000) */ + +#define MPMC_CONTROL_L (1 << 2) /* Bit 2: Indicates normal or low-power mode */ +#define MPMC_CONTROL_M (1 << 1) /* Bit 1: Indicates normal or reset memory map */ +#define MPMC_CONTROL_E (1 << 0) /* Bit 0: Indicates when the MPMC is enabled or disabled */ + +/* MPMCStatus (address 0x17008004) */ + +#define MPMC_STATUS_SA (1 << 2) /* Bit 2: Indicates the operating self-refresh mode */ +#define MPMC_STATUS_S (1 << 1) /* Bit 1: Write buffer status */ +#define MPMC_STATUS_B (1 << 0) /* Bit 0: MPMC is busy performing memory transactions */ + +/* MPMCConfig (address 0x17008008) */ + +#define MPMC_CONFIG_CLK (1 << 8) /* Bit 8: Indicates Clock ratio 1:2 */ +#define MPMC_CONFIG_N (1 << 0) /* Bit 0: Indicates big-endian mode */ + +/* MPMCDynamicControl (address 0x17008020) */ + +#define MPMC_DYNCONTROL_DP (1 << 13) /* Bit 13: Low-power SDRAM deep-sleep mode */ +#define MPMC_DYNCONTROL_I_SHIFT (8) /* Bits 7-8: I SDRAM initialization */ +#define MPMC_DYNCONTROL_I_MASK (3 << MPMC_DYNCONTROL_I_SHIFT) +# define MPMC_DYNCONTROL_INORMAL (0 << MPMC_DYNCONTROL_I_SHIFT) /* SDRAM NORMAL operation command */ +# define MPMC_DYNCONTROL_IMODE (1 << MPMC_DYNCONTROL_I_SHIFT) /* SDRAM MODE command */ +# define MPMC_DYNCONTROL_IPALL (2 << MPMC_DYNCONTROL_I_SHIFT) /* SDRAM PALL (pre charge all) */ +# define MPMC_DYNCONTROL_INOP (3 << MPMC_DYNCONTROL_I_SHIFT) /* SDRAM NOP (no operation) */ +#define MPMC_DYNCONTROL_MMC (1 << 5) /* Bit 5: Memory clock control */ +#define MPMC_DYNCONTROL_SR (1 << 2) /* Bit 2: Self-refresh request */ +#define MPMC_DYNCONTROL_CS (1 << 1) /* Bit 1: Dynamic-memory clock control */ +#define MPMC_DYNCONTROL_CE (1 << 0) /* Bit 0: Dynamic-memory clock enable */ + +/* MPMCDynamicRefresh (address 0x17008024) */ + +#define MPMC_DYNREFRESH_TIMER_SHIFT (0) /* Bits 0-10: Refresh timer */ +#define MPMC_DYNREFRESH_TIMER_MASK (0x07ff << MPMC_DYNREFRESH_TIMER_SHIFT) + +/* MPMCDynamicReadConfig (address 0x17008028) */ + +#define MPMC_DYNREADCONFIG_RD_SHIFT (0) /* Bits 0-1: Read data strategy */ +#define MPMC_DYNREADCONFIG_RD_MASK (2 << MPMC_DYNREADCONFIG_RD_SHIFT) +# define MPMC_DYNREADCONFIG_CLKOUTDEL (0 << MPMC_DYNREADCONFIG_RD_SHIFT) /* Clock out delay */ +# define MPMC_DYNREADCONFIG_CMDDEL (1 << MPMC_DYNREADCONFIG_RD_SHIFT) /* Command delay */ +# define MPMC_DYNREADCONFIG_CMDDELP1 (2 << MPMC_DYNREADCONFIG_RD_SHIFT) /* Command delay plus 1*/ +# define MPMC_DYNREADCONFIG_CMDDELP2 (3 << MPMC_DYNREADCONFIG_RD_SHIFT) /* Command delay plus 2 */ + +/* MPMCDynamictRP (address 0x17008030) */ + +#define MPMC_DYNTRP_SHIFT (0) /* Bits 0-3: Precharge command period */ +#define MPMC_DYNTRP_MASK (15 << MPMC_DYNTRP_SHIFT) + +/* MPMCDynamictRAS (address 0x17008034) */ + +#define MPMC_DYNTRAS_SHIFT (0) /* Bits 0-3: Active to pre charge command period */ +#define MPMC_DYNTRAS_MASK (15 << MPMC_DYNTRAS_SHIFT) + +/* MPMCDynamictSREX (address 0x17008038) */ + +#define MPMC_DYNTSREX_SHIFT (0) /* Bits 0-3: Self-refresh exit time */ +#define MPMC_DYNTSREX_MASK (15 << MPMC_DYNTSREX_SHIFT) + +/* MPMCDynamictAPR (address 0x1700803c) */ + +#define MPMC_DYNTAPR_SHIFT (0) /* Bits 0-3: Last-data-out to active command time */ +#define MPMC_DYNTAPR_MASK (15 << MPMC_DYNTAPR_SHIFT) + +/* MPMCDynamictDAL (address 0x17008040) */ + +#define MPMC_DYNTDAL_SHIFT (0) /* Bits 0-3: Data-in to active command */ +#define MPMC_DYNTDAL_MASK (15 << MPMC_DYNTDAL_SHIFT) + +/* MPMCDynamictWR (address 0x17008044) */ + +#define MPMC_DYNTWR_SHIFT (0) /* Bits 0-3: Write recovery time */ +#define MPMC_DYNTWR_MASK (15 << MPMC_DYNTWR_SHIFT) + +/* MPMCDynamictRC (address 0x17008048) */ + +#define MPMC_DYNTRC_SHIFT (0) /* Bits 0-4: Active to active command period */ +#define MPMC_DYNTRC_MASK (31 << MPMC_DYNTRC_SHIFT) + +/* MPMCDynamictRFC (address 0x1700804c) */ + +#define MPMC_DYNTRFC_SHIFT (0) /* Bits 0-4: Auto-refresh period and auto-refresh to active command period, */ +#define MPMC_DYNTRFC_MASK (31 << MPMC_DYNTRFC_SHIFT) + +/* MPMCDynamictXSR (address 0x1700804c) */ + +#define MPMC_DYNTXSR_SHIFT (0) /* Bits 0-4: Exit self-refresh to active command time */ +#define MPMC_DYNTXSR_MASK (31 << MPMC_DYNTXSR_SHIFT) + +/* MPMCDynamictRRD (address 0x17008050) */ + +#define MPMC_DYNTRRD_SHIFT (0) /* Bits 0-3: Active bank A to active bank B latency */ +#define MPMC_DYNTRRD_MASK (15 << MPMC_DYNTRRD_SHIFT) + +/* MPMCDynamictMRD (address 0x17008054) */ + +#define MPMC_DYNTMRD_SHIFT (0) /* Bits 0-3: Load mode register to active command time */ +#define MPMC_DYNTMRD_MASK (15 << MPMC_DYNTMRD_SHIFT) + +/* MPMCStaticExtendedWait (address 0x17008080) */ + +#define MPMC_DYNSTEXTWAIT_SHIFT (0) /* Bits 0-9: External wait time out */ +#define MPMC_DYNSTEXTWAIT_MASK (0x03ff << MPMC_DYNSTEXTWAIT_SHIFT) + +/* MPMCDynamicConfig0 (address 0x17008100) */ + +#define MPMC_DYNCONFIG0_P (1 << 20) /* Bit 20: Write protect */ +#define MPMC_DYNCONFIG0_B (1 << 19) /* Bit 19: Buffer enable */ +#define MPMC_DYNCONFIG0_AM (1 << 14) /* Bit 14: Address mapping */ +#define MPMC_DYNCONFIG0_AM_SHIFT (7) /* Bits 7-12: Address mapping */ +#define MPMC_DYNCONFIG0_AM_MASK (0x3c << MPMC_DYNCONFIG0_AM_SHIFT) + /* 16-bit external bus high-performance address mapping */ +# define MPMC_DYNCONFIG_HP16_2MX8 (0x00 << MPMC_DYNCONFIG0_AM_SHIFT) /* 16Mb (2Mx8), 2 banks, row length=11, column length=9 */ +# define MPMC_DYNCONFIG_HP16_1MX16 (0x01 << MPMC_DYNCONFIG0_AM_SHIFT) /* 16Mb (1Mx16), 2 banks, row length=11, column length=8 */ +# define MPMC_DYNCONFIG_HP16_8MX8 (0x04 << MPMC_DYNCONFIG0_AM_SHIFT) /* 64Mb (8Mx8), 4 banks, row length=12, column length=9 */ +# define MPMC_DYNCONFIG_HP16_4MX16 (0x05 << MPMC_DYNCONFIG0_AM_SHIFT) /* 64Mb (4Mx16), 4 banks, row length=12, column length=8 */ +# define MPMC_DYNCONFIG_HP16_16MX8 (0x08 << MPMC_DYNCONFIG0_AM_SHIFT) /* 128Mb (16Mx8), 4 banks, row length=12, column length=10 */ +# define MPMC_DYNCONFIG_HP16_8MX16 (0x09 << MPMC_DYNCONFIG0_AM_SHIFT) /* 128Mb (8Mx16), 4 banks, row length=12, column length=9 */ +# define MPMC_DYNCONFIG_HP16_32MX8 (0x0c << MPMC_DYNCONFIG0_AM_SHIFT) /* 256Mb (32Mx8), 4 banks, row length=13, column length=10 */ +# define MPMC_DYNCONFIG_HP16_16MX16 (0x0d << MPMC_DYNCONFIG0_AM_SHIFT) /* 256Mb (16Mx16), 4 banks, row length=13, column length=9 */ +# define MPMC_DYNCONFIG_HP16_64MX8 (0x10 << MPMC_DYNCONFIG0_AM_SHIFT) /* 512Mb (64Mx8), 4 banks, row length=13, column length=11 */ +# define MPMC_DYNCONFIG_HP16_32MX16 (0x11 << MPMC_DYNCONFIG0_AM_SHIFT) /* 512Mb (32Mx16), 4 banks, row length=13, column length=10 */ + /* 16-bit external bus low power SDRAM address mapping */ +# define MPMC_DYNCONFIG_LP16_2MX8 (0x20 << MPMC_DYNCONFIG0_AM_SHIFT) /* 6Mb (2Mx8), 2 banks, row length=11, column length=9 */ +# define MPMC_DYNCONFIG_LP16_1MX16 (0x21 << MPMC_DYNCONFIG0_AM_SHIFT) /* 16Mb (1Mx16), 2 banks, row length=11, column length=8 */ +# define MPMC_DYNCONFIG_LP16_8MX8 (0x24 << MPMC_DYNCONFIG0_AM_SHIFT) /* 64Mb (8Mx8), 4 banks, row length=12, column length=9 */ +# define MPMC_DYNCONFIG_LP16_4MX16 (0x25 << MPMC_DYNCONFIG0_AM_SHIFT) /* 64Mb (4Mx16), 4 banks, row length=12, column length=8 */ +# define MPMC_DYNCONFIG_LP16_16MX8 (0x28 << MPMC_DYNCONFIG0_AM_SHIFT) /* 128Mb (16Mx8), 4 banks, row length=12, column length=10 */ +# define MPMC_DYNCONFIG_LP16_8MX16 (0x29 << MPMC_DYNCONFIG0_AM_SHIFT) /* 128Mb (8Mx16), 4 banks, row length=12, column length=9 */ +# define MPMC_DYNCONFIG_LP16_32MX8 (0x2c << MPMC_DYNCONFIG0_AM_SHIFT) /* 256Mb (32Mx8), 4 banks, row length=13, column length=10 */ +# define MPMC_DYNCONFIG_LP16_16MX16 (0x2d << MPMC_DYNCONFIG0_AM_SHIFT) /* 256Mb (16Mx16), 4 banks, row length=13, column length=9 */ +# define MPMC_DYNCONFIG_LP16_64MX8 (0x30 << MPMC_DYNCONFIG0_AM_SHIFT) /* 512Mb (64Mx8), 4 banks, row length=13, column length=11 */ +# define MPMC_DYNCONFIG_LP16_32MX16 (0x31 << MPMC_DYNCONFIG0_AM_SHIFT) /* 512Mb (32Mx16), 4 banks, row length=13, column length=10 */ +#define MPMC_DYNCONFIG0_MD_SHIFT (3) /* Bits 3-4: Memory device */ +#define MPMC_DYNCONFIG0_MD_MASK (3 << MPMC_DYNCONFIG0_MD_SHIFT) +# define MPMC_DYNCONFIG0_MDSDRAM (0 << MPMC_DYNCONFIG0_MD_SHIFT) /* SDRAM */ +# define MPMC_DYNCONFIG0_MDLPSDRAM (1 << MPMC_DYNCONFIG0_MD_SHIFT) /* low-power SDRAM */ +# define MPMC_DYNCONFIG0_MDMSF (2 << MPMC_DYNCONFIG0_MD_SHIFT) /* Micron SyncFlash */ + +/* MPMCDynamicRasCas0 (address 0x17008104) */ + +#define MPMC_DYNRASCAS0_CAS_SHIFT (8) /* Bits 8-9: CAS latency */ +#define MPMC_DYNRASCAS0_CAS_MASK (3 << MPMC_DYNRASCAS0_CAS_SHIFT) +# define MPMC_DYNRASCAS0_CAS1CLK (1 << MPMC_DYNRASCAS0_CAS_SHIFT) /* one clock cycle */ +# define MPMC_DYNRASCAS0_CAS2CLK (2 << MPMC_DYNRASCAS0_CAS_SHIFT) /* two clock cycles */ +# define MPMC_DYNRASCAS0_CAS3CLK (3 << MPMC_DYNRASCAS0_CAS_SHIFT) /* three clock cycles */ +#define MPMC_DYNRASCAS0_RAS_SHIFT (0) /* Bits 0-1: RAS latency */ +#define MPMC_DYNRASCAS0_RAS_MASK (3 << MPMC_DYNRASCAS0_RAS_SHIFT) +# define MPMC_DYNRASCAS0_RAS1CLK (1 << MPMC_DYNRASCAS0_RAS_SHIFT) /* one clock cycle */ +# define MPMC_DYNRASCAS0_RAS2CLK (2 << MPMC_DYNRASCAS0_RAS_SHIFT) /* two clock cycles */ +# define MPMC_DYNRASCAS0_RAS3CLK (3 << MPMC_DYNRASCAS0_RAS_SHIFT) /* three clock cycles */ + +/* MPMCStaticConfig0 (address 0x17008120) and MPMCStaticConfig1 (address 0x17008220) */ + +#define MPMC_STCONFIG_WP (1 << 20) /* Bit 20: Write protect */ +#define MPMC_STCONFIG_B (1 << 19) /* Bit 19: Buffer enable */ +#define MPMC_STCONFIG_EW (1 << 8) /* Bit 8: Extended wait */ +#define MPMC_STCONFIG_BLS (1 << 7) /* Bit 7: BLS EBI_NCAS_BLOUT_0/1 EBI_nWE config */ +#define MPMC_STCONFIG_PC (1 << 6) /* Bit 6: Chip select polarity */ +#define MPMC_STCONFIG_PM (1 << 63 /* Bit 3: Page mode */ +#define MPMC_STCONFIG_MW_SHIFT (0) /* Bits 0-1: Memory width */ +#define MPMC_STCONFIG_MW_MASK (3 << MPMC_STCONFIG_MW_SHIFT) +# define MPMC_STCONFIG_MW8BIT (0 << MPMC_STCONFIG_MW_SHIFT) /* 8-bit */ +# define MPMC_STCONFIG_MW16BIT (1 << MPMC_STCONFIG_MW_SHIFT) /* 16-bit */ + +/* MPMCStaticWaitWen0 (address 0x17008204) and MPMCStaticWaitWen1 (address 0x17008224) */ + +#define MPMC_STWAITWEN_SHIFT (0) /* WAITWEN Delay from chip select to write enable */ +#define MPMC_STWAITWEN_MASK (15 << MPMC_STWAITWEN_SHIFT) + +/* MPMCStaticWaitOen (address 0x17008208) and MPMCStaticWaitOen1 (address 0x17008228) */ + +#define MPMC_STWAITOEN_SHIFT (0) /* WAITOEN Delay from chip select to output enable */ +#define MPMC_STWAITOEN_MASK (15 << MPMC_STWAITOEN_SHIFT) + +/* MPMCStaticWaitRd0 (address 0x1700820c) and MPMCStaticWaitRd1 (address 0x17008022c) */ + +#define MPMC_STWAITRD_SHIFT (0) /* Read first access wait state */ +#define MPMC_STWAITRD_MASK (31 << MPMC_STWAITRD_SHIFT) + +/* MPMCStaticWaitPage0 (address 0x17008210) and MPMCStaticWaitPage1 (address 0x17008230) */ + +#define MPMC_STWAITPAGE_SHIFT (0) /* Read after the first read wait states */ +#define MPMC_STWAITPAGE_MASK (31 << MPMC_STWAITPAGE_SHIFT) + +/* MPMCStaticWaitWr0 (address 0x17008214) and MPMCStaticWaitWr1 (address 0x17008234) */ + +#define MPMC_STWAITWR_SHIFT (0) /* Time for write accesses after the first read */ +#define MPMC_STWAITWR_MASK (31 << MPMC_STWAITWR_SHIFT) + +/* MPMCStaticWaitTurn0 (address 0x17008218) and MPMCStaticWaitTurn1 (address 0x17008238) */ + +#define MPMC_STWAITTURN_SHIFT (0) /* Bus turnaround cycles */ +#define MPMC_STWAITTURN_MASK (15 << MPMC_STWAITTURN_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_MPMC_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_nand.h b/arch/arm/src/lpc31xx/lpc31_nand.h new file mode 100644 index 0000000000000000000000000000000000000000..52f22bdc2b4c58906200cf2450f2c0477dad3b9a --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_nand.h @@ -0,0 +1,424 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_nand.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_NAND_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_NAND_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* NAND FLASH controller register base address offset into the APB4 domain **********************/ + +#define LPC31_NAND_VBASE (LPC31_APB4_VADDR+LPC31_APB4_NAND_OFFSET) +#define LPC31_NAND_PBASE (LPC31_APB4_PADDR+LPC31_APB4_NAND_OFFSET) + +/* NAND FLASH controller register offsets (with respect to the base of the APB4 domain) *********/ + +#define LPC31_NAND_IRQSTATUS1_OFFSET 0x00 /* Interrrupt status register (first 32-bits) */ +#define LPC31_NAND_IRQMASK1_OFFSET 0x04 /* Interrupt mask register (first 32-bits) */ +#define LPC31_NAND_IRQSTATUSRAW1_OFFSET 0x08 /* Unmasked register status (first 32-bits) */ +#define LPC31_NAND_CONFIG_OFFSET 0x0c /* NAND Flash controller configuration register */ +#define LPC31_NAND_IOCONFIG_OFFSET 0x10 /* Default value settings for IO signals */ +#define LPC31_NAND_TIMING1_OFFSET 0x14 /* First NAND FLASH controller timing register */ +#define LPC31_NAND_TIMING2_OFFSET 0x18 /* Second NAND FLASH controller timing register */ +#define LPC31_NAND_SETCMD_OFFSET 0x20 /* NAND FLASH device command register */ +#define LPC31_NAND_SETADDR_OFFSET 0x24 /* NAND FLASH device address register */ +#define LPC31_NAND_WRITEDATA_OFFSET 0x28 /* NAND FLASH device write data register */ +#define LPC31_NAND_SETCE_OFFSET 0x2c /* Set all CE and WP_n signals */ +#define LPC31_NAND_READDATA_OFFSET 0x30 /* NAND FLASH device read data register */ +#define LPC31_NAND_CHECKSTS_OFFSET 0x34 /* Check status of interrupts */ +#define LPC31_NAND_CONTROLFLOW_OFFSET 0x38 /* Commands to read and write pages */ +#define LPC31_NAND_GPIO1_OFFSET 0x40 /* Program IO pins that can be used as GPIO */ +#define LPC31_NAND_GPIO2_OFFSET 0x44 /* Program IO pins that can be used as GPIO */ +#define LPC31_NAND_IRQSTATUS2_OFFSET 0x48 /* Interrrupt status register (second 32-bits) */ +#define LPC31_NAND_IRQMASK3_OFFSET 0x4c /* Interrupt mask register (second 32-bits) */ +#define LPC31_NAND_IRQSTATUSRAW2_OFFSET 0x50 /* Unmasked register status (second 32-bits) */ +#define LPC31_NAND_AESKEY1_OFFSET 0x54 /* First word of 128-bit AES key (LPC3154 only) */ +#define LPC31_NAND_AESKEY2_OFFSET 0x58 /* Second word of 128-bit AES key (LPC3154 only) */ +#define LPC31_NAND_AESKEY3_OFFSET 0x5c /* Third word of 128-bit AES key (LPC3154 only) */ +#define LPC31_NAND_AESKEY4_OFFSET 0x60 /* Fourth word of 128-bit AES key (LPC3154 only) */ +#define LPC31_NAND_AESIV1_OFFSET 0x64 /* First word of 128-bit initial AES value (LPC3154 only) */ +#define LPC31_NAND_AESIV2_OFFSET 0x68 /* Second word of 128-bit initial AES value (LPC3154 only) */ +#define LPC31_NAND_AESIV3_OFFSET 0x6c /* Third word of 128-bit initial AES value (LPC3154 only) */ +#define LPC31_NAND_AESIV4_OFFSET 0x70 /* Fourth word of 128-bit initial AES value (LPC3154 only) */ +#define LPC31_NAND_AESSTATE_OFFSET 0x74 /* Register to display AES state (LPC3154 only) */ +#define LPC31_NAND_ECCERRSTATUS_OFFSET 0x78 /* ECC error status register */ +#define LPC31_NAND_AESFROMAHB_OFFSET 0x7c /* Enable AES engine from AHB */ + +/* NAND FLASH controller register (virtual) addresses *******************************************/ + +#define LPC31_NAND_IRQSTATUS1 (LPC31_NAND_VBASE+LPC31_NAND_IRQSTATUS1_OFFSET) +#define LPC31_NAND_IRQMASK1 (LPC31_NAND_VBASE+LPC31_NAND_IRQMASK1_OFFSET) +#define LPC31_NAND_IRQSTATUSRAW1 (LPC31_NAND_VBASE+LPC31_NAND_IRQSTATUSRAW1_OFFSET) +#define LPC31_NAND_CONFIG (LPC31_NAND_VBASE+LPC31_NAND_CONFIG_OFFSET) +#define LPC31_NAND_IOCONFIG (LPC31_NAND_VBASE+LPC31_NAND_IOCONFIG_OFFSET) +#define LPC31_NAND_TIMING1 (LPC31_NAND_VBASE+LPC31_NAND_TIMING1_OFFSET) +#define LPC31_NAND_TIMING2 (LPC31_NAND_VBASE+LPC31_NAND_TIMING2_OFFSET) +#define LPC31_NAND_SETCMD (LPC31_NAND_VBASE+LPC31_NAND_SETCMD_OFFSET) +#define LPC31_NAND_SETADDR (LPC31_NAND_VBASE+LPC31_NAND_SETADDR_OFFSET) +#define LPC31_NAND_WRITEDATA (LPC31_NAND_VBASE+LPC31_NAND_WRITEDATA_OFFSET) +#define LPC31_NAND_SETCE (LPC31_NAND_VBASE+LPC31_NAND_SETCE_OFFSET) +#define LPC31_NAND_READDATA (LPC31_NAND_VBASE+LPC31_NAND_READDATA_OFFSET) +#define LPC31_NAND_CHECKSTS (LPC31_NAND_VBASE+LPC31_NAND_CHECKSTS_OFFSET) +#define LPC31_NAND_CONTROLFLOW (LPC31_NAND_VBASE+LPC31_NAND_CONTROLFLOW_OFFSET) +#define LPC31_NAND_GPIO1 (LPC31_NAND_VBASE+LPC31_NAND_GPIO1_OFFSET) +#define LPC31_NAND_GPIO2 (LPC31_NAND_VBASE+LPC31_NAND_GPIO2_OFFSET) +#define LPC31_NAND_IRQSTATUS2 (LPC31_NAND_VBASE+LPC31_NAND_IRQSTATUS2_OFFSET) +#define LPC31_NAND_IRQMASK3 (LPC31_NAND_VBASE+LPC31_NAND_IRQMASK3_OFFSET) +#define LPC31_NAND_IRQSTATUSRAW2 (LPC31_NAND_VBASE+LPC31_NAND_IRQSTATUSRAW2_OFFSET) +#define LPC31_NAND_AESKEY1 (LPC31_NAND_VBASE+LPC31_NAND_AESKEY1_OFFSET) +#define LPC31_NAND_AESKEY2 (LPC31_NAND_VBASE+LPC31_NAND_AESKEY2_OFFSET) +#define LPC31_NAND_AESKEY3 (LPC31_NAND_VBASE+LPC31_NAND_AESKEY3_OFFSET) +#define LPC31_NAND_AESKEY4 (LPC31_NAND_VBASE+LPC31_NAND_AESKEY4_OFFSET) +#define LPC31_NAND_AESIV1 (LPC31_NAND_VBASE+LPC31_NAND_AESIV1_OFFSET) +#define LPC31_NAND_AESIV2 (LPC31_NAND_VBASE+LPC31_NAND_AESIV2_OFFSET) +#define LPC31_NAND_AESIV3 (LPC31_NAND_VBASE+LPC31_NAND_AESIV3_OFFSET) +#define LPC31_NAND_AESIV4 (LPC31_NAND_VBASE+LPC31_NAND_AESIV4_OFFSET) +#define LPC31_NAND_AESSTATE (LPC31_NAND_VBASE+LPC31_NAND_AESSTATE_OFFSET) +#define LPC31_NAND_ECCERRSTATUS (LPC31_NAND_VBASE+LPC31_NAND_ECCERRSTATUS_OFFSET) +#define LPC31_NAND_AESFROMAHB (LPC31_NAND_VBASE+LPC31_NAND_AESFROMAHB_OFFSET) + +/* NAND FLASH controller register bit definitions ***********************************************/ +/* NandIRQStatus1 register description (NandIRQStatus1, address 0x17000800) */ + +#define NAND_IRQSTATUS1_MNANDRYBN3 (1 << 31) /* Bit 31: mNAND_RYBN3 positive edge */ +#define NAND_IRQSTATUS1_MNANDRYBN2 (1 << 30) /* Bit 30: mNAND_RYBN2 positive edge */ +#define NAND_IRQSTATUS1_MNANDRYBN1 (1 << 29) /* Bit 29: mNAND_RYBN1 positive edge */ +#define NAND_IRQSTATUS1_MNANDRYBN0 (1 << 28) /* Bit 28: mNAND_RYBN0 positive edge */ +#define NAND_IRQSTATUS1_RAM1ERASED (1 << 27) /* Bit 27: RAM 1 erased */ +#define NAND_IRQSTATUS1_RAM0ERASED (1 << 26) /* Bit 26: RAM 0 erased */ +#define NAND_IRQSTATUS1_WRPG1DONE (1 << 25) /* Bit 25: Write page 1 done */ +#define NAND_IRQSTATUS1_WRPG0DONE (1 << 24) /* Bit 24: Write page 0 done */ +#define NAND_IRQSTATUS1_RDPG1DONE (1 << 23) /* Bit 23: Read page 1 done */ +#define NAND_IRQSTATUS1_RDPG0DONE (1 << 22) /* Bit 22: Read page 0 done */ +#define NAND_IRQSTATUS1_RAM0DECODE (1 << 21) /* Bit 21: RAM 0 decoded */ +#define NAND_IRQSTATUS1_RAM0ENCODE (1 << 20) /* Bit 20: RAM 0 encoded */ +#define NAND_IRQSTATUS1_RAM1DECODE (1 << 19) /* Bit 19: RAM 1 decoded */ +#define NAND_IRQSTATUS1_RAM1ENCODE (1 << 18) /* Bit 18: RAM 1 encoded */ +#define NAND_IRQSTATUS1_RAM00ERRS (1 << 17) /* Bit 17: RAM 0 decoded with 0 errors */ +#define NAND_IRQSTATUS1_RAM01ERR (1 << 16) /* Bit 16: RAM 0 decoded with 1 error (depends on mode) */ +#define NAND_IRQSTATUS1_RAM02ERR (1 << 15) /* Bit 15: RAM 0 decoded with 2 error */ +#define NAND_IRQSTATUS1_RAM03ERR (1 << 14) /* Bit 14: RAM 0 decoded with 3 error */ +#define NAND_IRQSTATUS1_RAM04ERR (1 << 13) /* Bit 13: RAM 0 decoded with 4 error */ +#define NAND_IRQSTATUS1_RAM05ERR (1 << 12) /* Bit 12: RAM 0 decoded with 5 error */ +#define NAND_IRQSTATUS1_RAM0UNCORR (1 << 11) /* Bit 11: RAM 0 uncorrectable */ +#define NAND_IRQSTATUS1_RAM10ERR (1 << 10) /* Bit 10: RAM 1 decoded with 0 errors */ +#define NAND_IRQSTATUS1_RAM11ERR (1 << 9) /* Bit 9: RAM 1 decoded with 1 error (depends on mode) */ +#define NAND_IRQSTATUS1_RAM12ERR (1 << 8) /* Bit 8: RAM 1 decoded with 2 error */ +#define NAND_IRQSTATUS1_RAM13ERR (1 << 7) /* Bit 7: RAM 1 decoded with 3 error */ +#define NAND_IRQSTATUS1_RAM14ERR (1 << 6) /* Bit 6: RAM 1 decoded with 4 error */ +#define NAND_IRQSTATUS1_RAM15ERR (1 << 5) /* Bit 5: RAM 1 decoded with 5 error */ +#define NAND_IRQSTATUS1_RAM1UNCORR (1 << 4) /* Bit 4: RAM 1 uncorrectable */ + +#define NAND_IRQSTATUS1_RAM1AESDONE (1 << 1) /* Bit 1: RAM 1 AES done (LPC3154 only) */ +#define NAND_IRQSTATUS1_RAM0AESDONE (1 << 0) /* Bit 0: RAM 0 AES done (LPC3154 only) */ + +/* NandIRQMask1 register description (NandIRQMask1, address 0x17000804) */ + +#define NAND_IRQIRQMASK1_MNANDRYBN3 (1 << 31) /* Bit 31: mNAND_RYBN3 positive edge */ +#define NAND_IRQIRQMASK1_MNANDRYBN2 (1 << 30) /* Bit 30: mNAND_RYBN2 positive edge */ +#define NAND_IRQIRQMASK1_MNANDRYBN1 (1 << 29) /* Bit 29: mNAND_RYBN1 positive edge */ +#define NAND_IRQIRQMASK1_MNANDRYBN0 (1 << 28) /* Bit 28: mNAND_RYBN0 positive edge */ +#define NAND_IRQIRQMASK1_RAM1ERASED (1 << 27) /* Bit 27: RAM 1 erased */ +#define NAND_IRQIRQMASK1_RAM0ERASED (1 << 26) /* Bit 26: RAM 0 erased */ +#define NAND_IRQIRQMASK1_WRPG1DONE (1 << 25) /* Bit 25: Write page 1 done */ +#define NAND_IRQIRQMASK1_WRPG0DONE (1 << 24) /* Bit 24: Write page 0 done */ +#define NAND_IRQIRQMASK1_RDPG1DONE (1 << 23) /* Bit 23: Read page 1 done */ +#define NAND_IRQIRQMASK1_RDPG0DONE (1 << 22) /* Bit 22: Read page 0 done */ +#define NAND_IRQIRQMASK1_RAM0DECODE (1 << 21) /* Bit 21: RAM 0 decoded */ +#define NAND_IRQIRQMASK1_RAM0ENCODE (1 << 20) /* Bit 20: RAM 0 encoded */ +#define NAND_IRQIRQMASK1_RAM1DECODE (1 << 19) /* Bit 19: RAM 1 decoded */ +#define NAND_IRQIRQMASK1_RAM1ENCODE (1 << 18) /* Bit 18: RAM 1 encoded */ +#define NAND_IRQIRQMASK1_RAM00ERRS (1 << 17) /* Bit 17: RAM 0 decoded with 0 errors */ +#define NAND_IRQIRQMASK1_RAM01ERR (1 << 16) /* Bit 16: RAM 0 decoded with 1 error (depends on mode) */ +#define NAND_IRQIRQMASK1_RAM02ERR (1 << 15) /* Bit 15: RAM 0 decoded with 2 error */ +#define NAND_IRQIRQMASK1_RAM03ERR (1 << 14) /* Bit 14: RAM 0 decoded with 3 error */ +#define NAND_IRQIRQMASK1_RAM04ERR (1 << 13) /* Bit 13: RAM 0 decoded with 4 error */ +#define NAND_IRQIRQMASK1_RAM05ERR (1 << 12) /* Bit 12: RAM 0 decoded with 5 error */ +#define NAND_IRQIRQMASK1_RAM0UNCORR (1 << 11) /* Bit 11: RAM 0 uncorrectable */ +#define NAND_IRQIRQMASK1_RAM10ERR (1 << 10) /* Bit 10: RAM 1 decoded with 0 errors */ +#define NAND_IRQIRQMASK1_RAM11ERR (1 << 9) /* Bit 9: RAM 1 decoded with 1 error (depends on mode) */ +#define NAND_IRQIRQMASK1_RAM12ERR (1 << 8) /* Bit 8: RAM 1 decoded with 2 error */ +#define NAND_IRQIRQMASK1_RAM13ERR (1 << 7) /* Bit 7: RAM 1 decoded with 3 error */ +#define NAND_IRQIRQMASK1_RAM14ERR (1 << 6) /* Bit 6: RAM 1 decoded with 4 error */ +#define NAND_IRQIRQMASK1_RAM15ERR (1 << 5) /* Bit 5: RAM 1 decoded with 5 error */ +#define NAND_IRQIRQMASK1_RAM1UNCORR (1 << 4) /* Bit 4: RAM 1 uncorrectable */ + +#define NAND_IRQIRQMASK1_RAM1AESDONE (1 << 1) /* Bit 1: RAM 1 AES done (LPC3154 only) */ +#define NAND_IRQIRQMASK1_RAM0AESDONE (1 << 0) /* Bit 0: RAM 0 AES done (LPC3154 only) */ + +/* NandIRQStatusRaw1 register description (NandIRQStatusRaw1, address 0x17000808) */ + +#define NAND_IRQSTATUSRAW1_MNANDRYBN3 (1 << 31) /* Bit 31: mNAND_RYBN3 positive edge */ +#define NAND_IRQSTATUSRAW1_MNANDRYBN2 (1 << 30) /* Bit 30: mNAND_RYBN2 positive edge */ +#define NAND_IRQSTATUSRAW1_MNANDRYBN1 (1 << 29) /* Bit 29: mNAND_RYBN1 positive edge */ +#define NAND_IRQSTATUSRAW1_MNANDRYBN0 (1 << 28) /* Bit 28: mNAND_RYBN0 positive edge */ +#define NAND_IRQSTATUSRAW1_RAM1ERASED (1 << 27) /* Bit 27: RAM 1 erased */ +#define NAND_IRQSTATUSRAW1_RAM0ERASED (1 << 26) /* Bit 26: RAM 0 erased */ +#define NAND_IRQSTATUSRAW1_WRPG1DONE (1 << 25) /* Bit 25: Write page 1 done */ +#define NAND_IRQSTATUSRAW1_WRPG0DONE (1 << 24) /* Bit 24: Write page 0 done */ +#define NAND_IRQSTATUSRAW1_RDPG1DONE (1 << 23) /* Bit 23: Read page 1 done */ +#define NAND_IRQSTATUSRAW1_RDPG0DONE (1 << 22) /* Bit 22: Read page 0 done */ +#define NAND_IRQSTATUSRAW1_RAM0DECODE (1 << 21) /* Bit 21: RAM 0 decoded */ +#define NAND_IRQSTATUSRAW1_RAM0ENCODE (1 << 20) /* Bit 20: RAM 0 encoded */ +#define NAND_IRQSTATUSRAW1_RAM1DECODE (1 << 19) /* Bit 19: RAM 1 decoded */ +#define NAND_IRQSTATUSRAW1_RAM1ENCODE (1 << 18) /* Bit 18: RAM 1 encoded */ +#define NAND_IRQSTATUSRAW1_RAM00ERRS (1 << 17) /* Bit 17: RAM 0 decoded with 0 errors */ +#define NAND_IRQSTATUSRAW1_RAM01ERR (1 << 16) /* Bit 16: RAM 0 decoded with 1 error (depends on mode) */ +#define NAND_IRQSTATUSRAW1_RAM02ERR (1 << 15) /* Bit 15: RAM 0 decoded with 2 error */ +#define NAND_IRQSTATUSRAW1_RAM03ERR (1 << 14) /* Bit 14: RAM 0 decoded with 3 error */ +#define NAND_IRQSTATUSRAW1_RAM04ERR (1 << 13) /* Bit 13: RAM 0 decoded with 4 error */ +#define NAND_IRQSTATUSRAW1_RAM05ERR (1 << 12) /* Bit 12: RAM 0 decoded with 5 error */ +#define NAND_IRQSTATUSRAW1_RAM0UNCORR (1 << 11) /* Bit 11: RAM 0 uncorrectable */ +#define NAND_IRQSTATUSRAW1_RAM10ERR (1 << 10) /* Bit 10: RAM 1 decoded with 0 errors */ +#define NAND_IRQSTATUSRAW1_RAM11ERR (1 << 9) /* Bit 9: RAM 1 decoded with 1 error (depends on mode) */ +#define NAND_IRQSTATUSRAW1_RAM12ERR (1 << 8) /* Bit 8: RAM 1 decoded with 2 error */ +#define NAND_IRQSTATUSRAW1_RAM13ERR (1 << 7) /* Bit 7: RAM 1 decoded with 3 error */ +#define NAND_IRQSTATUSRAW1_RAM14ERR (1 << 6) /* Bit 6: RAM 1 decoded with 4 error */ +#define NAND_IRQSTATUSRAW1_RAM15ERR (1 << 5) /* Bit 5: RAM 1 decoded with 5 error */ +#define NAND_IRQSTATUSRAW1_RAM1UNCORR (1 << 4) /* Bit 4: RAM 1 uncorrectable */ + +#define NAND_IRQSTATUSRAW1_RAM1AESDONE (1 << 1) /* Bit 1: RAM 1 AES done (LPC3154 only) */ +#define NAND_IRQSTATUSRAW1_RAM0AESDONE (1 << 0) /* Bit 0: RAM 0 AES done (LPC3154 only) */ + +/* NandConfig register description (NandConfig, address 0x1700080c) */ + +#define NAND_CONFIG_ECC_MODE (1 << 12) /* Bit 12: ECC mode 0 */ +#define NAND_CONFIG_TL_SHIFT (10) /* Bits 10-11: Transfer limit */ +#define NAND_CONFIG_TL_MASK (3 < + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_OTP_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_OTP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Virtual and physical base address of the OTG register group **********************************/ + +#define LPC31_OTG_VBASE (LPC31_APB0_VADDR+LPC31_APB0_OTP_OFFSET) +#define LPC31_OTG_PBASE (LPC31_APB0_PADDR+LPC31_APB0_OTP_OFFSET) + +/* OTP register offsets (with respect to the RNG base) ******************************************/ + +#define LPC31_OTP_CON_OFFSET 0x000 /* Control Register */ +#define LPC31_OTP_RPROT_OFFSET 0x004 /* Read-protect Register */ +#define LPC31_OTP_WPROT_OFFSET 0x008 /* Write-protect Register */ +#define LPC31_OTP_DATA_OFFSET(n) (0x00c + ((n) << 2) +#define LPC31_OTP_DATA0_OFFSET 0x00c /* Fuse-output data register 0 */ +#define LPC31_OTP_DATA1_OFFSET 0x010 /* Fuse-output data register 1 */ +#define LPC31_OTP_DATA2_OFFSET 0x014 /* Fuse-output data register 2 */ +#define LPC31_OTP_DATA3_OFFSET 0x018 /* Fuse-output data register 3 */ +#define LPC31_OTP_DATA4_OFFSET 0x01c /* Fuse-output data register 4 */ +#define LPC31_OTP_DATA5_OFFSET 0x020 /* Fuse-output data register 5 */ +#define LPC31_OTP_DATA6_OFFSET 0x024 /* Fuse-output data register 6 */ +#define LPC31_OTP_DATA7_OFFSET 0x028 /* Fuse-output data register 7 */ +#define LPC31_OTP_DATA8_OFFSET 0x02c /* Fuse-output data register 8 */ +#define LPC31_OTP_DATA9_OFFSET 0x030 /* Fuse-output data register 9 */ +#define LPC31_OTP_DATA10_OFFSET 0x034 /* Fuse-output data register 10 */ +#define LPC31_OTP_DATA11_OFFSET 0x038 /* Fuse-output data register 11 */ +#define LPC31_OTP_DATA12_OFFSET 0x03c /* Fuse-output data register 12 */ +#define LPC31_OTP_DATA13_OFFSET 0x040 /* Fuse-output data register 13 */ +#define LPC31_OTP_DATA14_OFFSET 0x044 /* Fuse-output data register 14 */ +#define LPC31_OTP_DATA15_OFFSET 0x048 /* Fuse-output data register 15 */ + +/* OTP register (virtual) addresses *************************************************************/ + +#define LPC31_OTP_CON (LPC31_OTG_VBASE+LPC31_OTP_CON_OFFSET) +#define LPC31_OTP_RPROT (LPC31_OTG_VBASE+LPC31_OTP_RPROT_OFFSET) +#define LPC31_OTP_WPROT (LPC31_OTG_VBASE+LPC31_OTP_WPROT_OFFSET) +#define LPC31_OTP_DATA(n) (LPC31_OTG_VBASE+LPC31_OTP_DATA_OFFSET(n)) +#define LPC31_OTP_DATA0 (LPC31_OTG_VBASE+LPC31_OTP_DATA0_OFFSET) +#define LPC31_OTP_DATA1 (LPC31_OTG_VBASE+LPC31_OTP_DATA1_OFFSET) +#define LPC31_OTP_DATA2 (LPC31_OTG_VBASE+LPC31_OTP_DATA2_OFFSET) +#define LPC31_OTP_DATA3 (LPC31_OTG_VBASE+LPC31_OTP_DATA3_OFFSET) +#define LPC31_OTP_DATA4 (LPC31_OTG_VBASE+LPC31_OTP_DATA4_OFFSET) +#define LPC31_OTP_DATA5 (LPC31_OTG_VBASE+LPC31_OTP_DATA5_OFFSET) +#define LPC31_OTP_DATA6 (LPC31_OTG_VBASE+LPC31_OTP_DATA6_OFFSET) +#define LPC31_OTP_DATA7 (LPC31_OTG_VBASE+LPC31_OTP_DATA7_OFFSET) +#define LPC31_OTP_DATA8 (LPC31_OTG_VBASE+LPC31_OTP_DATA8_OFFSET) +#define LPC31_OTP_DATA9 (LPC31_OTG_VBASE+LPC31_OTP_DATA9_OFFSET) +#define LPC31_OTP_DATA10 (LPC31_OTG_VBASE+LPC31_OTP_DATA10_OFFSET) +#define LPC31_OTP_DATA11 (LPC31_OTG_VBASE+LPC31_OTP_DATA11_OFFSET) +#define LPC31_OTP_DATA12 (LPC31_OTG_VBASE+LPC31_OTP_DATA12_OFFSET) +#define LPC31_OTP_DATA13 (LPC31_OTG_VBASE+LPC31_OTP_DATA13_OFFSET) +#define LPC31_OTP_DATA14 (LPC31_OTG_VBASE+LPC31_OTP_DATA14_OFFSET) +#define LPC31_OTP_DATA15 (LPC31_OTG_VBASE+LPC31_OTP_DATA15_OFFSET) + +/* RNG register bit definitions *****************************************************************/ + +/* Control Register */ + +#define OTP_CON_ADRS_SHIFT (0) /* Bits 0-8: Address bits for accessing fuse data */ +#define OTP_CON_ADRS_MASK (0x1ff << OTP_CON_ADRS_SHIFT) +#define OTP_CON_MODE_SHIFT (16) /* Bits 16-17: Selects: Idle, Copy and Write mode */ +#define OTP_CON_MODE_MASK (3 << OTP_CON_MODE_SHIFT) +#define OTP_CON_JTAGEN (1 << 31) /* Bit 31: Enable ARM_JTAG clock */ + +/* Read-protect Register */ + +#define OTP_RPROT_PROT_SHIFT (0) /* Bits 0-15: Indicates which data registers are read-protected */ +#define OTP_RPROT_PROT_MASK (0xffff << OTP_RPROT_PROT_SHIFT) +# define OTP_RPROT_PROT(n) ((1 << (n)) << TP_RPROT_PROT_SHIFT) +#define OTP_RPROT_LOCK (1 << 31) /* Bit 31: Register values are 'sticky' */ + +/* Write-protect Register */ + +#define OTP_WPROT_PROT_SHIFT (0) /* Bits 0-15: Indicates which data registers are write-protected */ +#define OTP_WPROT_PROT_MASK (0xffff << OTP_RPROT_PROT_SHIFT) +# define OTP_WPROT_PROT(n) ((1 << (n)) << TP_RPROT_PROT_SHIFT) +#define OTP_WPROT_LOCK (1 << 31) /* Bit 31: Register values are 'sticky' */ + +/* Fuse-output data register 0-15: Fuse output 0-511 (32 per data register, 32*16 = 512) */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_OTP_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_pcm.h b/arch/arm/src/lpc31xx/lpc31_pcm.h new file mode 100644 index 0000000000000000000000000000000000000000..0be577aefc2ce7eb7fdf188fec8c25f3800bb326 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_pcm.h @@ -0,0 +1,174 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_pcm.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_PCM_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_PCM_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* PCM register base address offset into the APB2 domain ****************************************/ + +#define LPC31_PCM_VBASE (LPC31_APB2_VSECTION+LPC31_APB2_PCM_OFFSET) +#define LPC31_PCM_PBASE (LPC31_APB2_PSECTION+LPC31_APB2_PCM_OFFSET) + +/* PCM register offsets (with respect to the PCM base) ******************************************/ + +#define LPC31_PCM_GLOBAL_OFFSET 0x000 /* Global register */ +#define LPC31_PCM_CNTL0_OFFSET 0x004 /* Control register 0 */ +#define LPC31_PCM_CNTL1_OFFSET 0x008 /* Control register 1 */ +#define LPC31_PCM_HPOUT_OFFSET(n) (0x00c+((n)<<2)) /* Transmit data register n */ +#define LPC31_PCM_HPOUT0_OFFSET 0x00c /* Transmit data register 0 */ +#define LPC31_PCM_HPOUT1_OFFSET 0x010 /* Transmit data register 1 */ +#define LPC31_PCM_HPOUT2_OFFSET 0x014 /* Transmit data register 2 */ +#define LPC31_PCM_HPOUT3_OFFSET 0x018 /* Transmit data register 3 */ +#define LPC31_PCM_HPOUT4_OFFSET 0x01c /* Transmit data register 4 */ +#define LPC31_PCM_HPOUT5_OFFSET 0x020 /* Transmit data register 5 */ +#define LPC31_PCM_HPIN_OFFSET(n) (0x024+((n)<<2)) /* Transmit data register n */ +#define LPC31_PCM_HPIN0_OFFSET 0x024 /* Receive data register 0 */ +#define LPC31_PCM_HPIN1_OFFSET 0x028 /* Receive data register 1 */ +#define LPC31_PCM_HPIN2_OFFSET 0x02c /* Receive data register 2 */ +#define LPC31_PCM_HPIN3_OFFSET 0x030 /* Receive data register 3 */ +#define LPC31_PCM_HPIN4_OFFSET 0x034 /* Receive data register 4 */ +#define LPC31_PCM_HPIN5_OFFSET 0x038 /* Receive data register 5 */ +#define LPC31_PCM_CNTL2_OFFSET 0x03c /* Control register 2 */ + +/* PCM register (virtual) addresses *************************************************************/ + +#define LPC31_PCM_GLOBAL (LPC31_PCM_VBASE+LPC31_PCM_GLOBAL_OFFSET) +#define LPC31_PCM_CNTL0 (LPC31_PCM_VBASE+LPC31_PCM_CNTL0_OFFSET) +#define LPC31_PCM_CNTL1 (LPC31_PCM_VBASE+LPC31_PCM_CNTL1_OFFSET) +#define LPC31_PCM_HPOUT(n) (LPC31_PCM_VBASE+LPC31_PCM_HPOUT_OFFSET(n)) +#define LPC31_PCM_HPOUT0 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT0_OFFSET) +#define LPC31_PCM_HPOUT1 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT1_OFFSET) +#define LPC31_PCM_HPOUT2 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT2_OFFSET) +#define LPC31_PCM_HPOUT3 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT3_OFFSET) +#define LPC31_PCM_HPOUT4 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT4_OFFSET) +#define LPC31_PCM_HPOUT5 (LPC31_PCM_VBASE+LPC31_PCM_HPOUT5_OFFSET) +#define LPC31_PCM_HPIN(n) (LPC31_PCM_VBASE+LPC31_PCM_HPIN_OFFSET(n)) +#define LPC31_PCM_HPIN0 (LPC31_PCM_VBASE+LPC31_PCM_HPIN0_OFFSET) +#define LPC31_PCM_HPIN1 (LPC31_PCM_VBASE+LPC31_PCM_HPIN1_OFFSET) +#define LPC31_PCM_HPIN2 (LPC31_PCM_VBASE+LPC31_PCM_HPIN2_OFFSET) +#define LPC31_PCM_HPIN3 (LPC31_PCM_VBASE+LPC31_PCM_HPIN3_OFFSET) +#define LPC31_PCM_HPIN4 (LPC31_PCM_VBASE+LPC31_PCM_HPIN4_OFFSET) +#define LPC31_PCM_HPIN5 (LPC31_PCM_VBASE+LPC31_PCM_HPIN5_OFFSET) +#define LPC31_PCM_CNTL2 (LPC31_PCM_VBASE+LPC31_PCM_CNTL2_OFFSET) + +/* PCM register bit definitions *****************************************************************/ + +/* GLOBAL register, address 0x15000000 */ + +#define PCM_GLOBAL_DMARXENABLE (1 << 4) /* Bit 4: Enable DMA RX */ +#define PCM_GLOBAL_DMATXENABLE (1 << 3) /* Bit 3: Enable DMA TX */ +#define PCM_GLOBAL_NORMAL (1 << 2) /* Bit 2: Slave/Normal mode */ +#define PCM_GLOBAL_ONOFF (1 << 0) /* Bit 0: IPINT active */ + +/* CNTL0 register, address 0x15000004 */ + +#define PCM_CNTL0_MASTER (1 << 14) /* Bit 14: PCM/IOM master mode */ +#define PCM_CNTL0_LOOPBACK (1 << 11) /* Bit 11: Internal loop-back mode */ +#define PCM_CNTL0_TYPOD (1 << 10) /* Bit 10: Type of PCM_FCS and PCM_DCLK output port */ +#define PCM_CNTL0_TYPDOIP_SHIFT (8) /* Bits 8-9: Type of PCM/IOM data output ports */ +#define PCM_CNTL0_TYPDOIP_MASK (3 << PCM_CNTL0_TYPDOIP_SHIFT) +#define PCM_CNTL0_TYPFRMSYNC_SHIFT (6) /* Bits 6-7: Shape of frame synchronization signal */ +#define PCM_CNTL0_TYPFRMSYNC_MASK (3 << PCM_CNTL0_TYPFRMSYNC_SHIFT) +#define PCM_CNTL0_CLKSPD_SHIFT (3) /* Bits 3-5: Port frequency selection */ +#define PCM_CNTL0_CLKSPD_MASK (7 << PCM_CNTL0_CLKSPD_SHIFT) + +/* CNTL1 register, address 0x15000008 */ + +#define PCM_CNTL1_ENSLT_SHIFT (0) /* Bits 0-11: Enable PCM/IOM Slots, one per slot */ +#define PCM_CNTL1_ENSLT_MASK (0xfff << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT0 (0x001 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT1 (0x002 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT2 (0x004 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT3 (0x008 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT4 (0x010 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT5 (0x020 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT6 (0x040 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT7 (0x080 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT8 (0x100 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT9 (0x200 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT10 (0x400 << PCM_CNTL1_ENSLT_SHIFT) +# define PCM_CNTL1_ENSLT11 (0x800 << PCM_CNTL1_ENSLT_SHIFT) + +/* HPOUTn registers, addresses 0x1500000c to 0x15000020 (two per slot) */ + +#define PCM_HPOUT_SHIFT (0) /* Bits 0-15: Transmit data register */ +#define PCM_HPOUT_MASK (0xffff << PCM_HPOUT_SHIFT) + +/* HPINn registers, addresses 0x15000024 to 0x15000038 (two per slot) */ + +#define PCM_HPIN_SHIFT (0) /* Bits 0-15: Receive data register */ +#define PCM_HPIN_MASK (0xffff << PCM_HPIN_SHIFT) + +/* CNTL2 register, address 0x1500003c */ + +#define PCM_CNTL2_SLOTDIRINV_SHIFT (0) /* Bits 0-11: PCM A/B port configuration, one per slot */ +#define PCM_CNTL2_SLOTDIRINV_MASK (0xfff << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV0 (0x001 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV1 (0x002 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV2 (0x004 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV3 (0x008 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV4 (0x010 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV5 (0x020 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV6 (0x040 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV7 (0x080 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV8 (0x100 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV9 (0x200 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV10 (0x400 << PCM_CNTL2_SLOTDIRINV_SHIFT) +# define PCM_CNTL2_SLOTDIRINV11 (0x800 << PCM_CNTL2_SLOTDIRINV_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_PCM_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_pllconfig.c b/arch/arm/src/lpc31xx/lpc31_pllconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..1ab391a446c4a86563983cafe5455e2539009080 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_pllconfig.c @@ -0,0 +1,267 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_pllconfig.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - NXP UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - NXP lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_switchdomains + * + * Description: + * Temporarily switch the referemce clock of all domains whose selected + * input is the PLL-to-be configured . + * + ****************************************************************************/ + +static inline uint16_t +lpc31_switchdomains(const struct lpc31_pllconfig_s * const cfg) +{ + uint32_t hppll = (cfg->hppll ? CGU_SSR_HPPLL1 : CGU_SSR_HPPLL0); + uint32_t address; + uint32_t regval; + uint16_t dmnset = 0; + int i; + + /* Check each domain */ + + for (i = 0; i < CGU_NDOMAINS; i++) + { + /* Get the switch status registers (SSR) for this frequency input domain */ + + address = LPC31_CGU_SSR(i); + regval = getreg32(address); + + /* Check if the current frequency selection is the PLL-to-be-configured */ + + if ((regval & CGU_SSR_FS_MASK) == hppll) + { + /* Yes.. switch reference clock in to FFAST */ + + lpc31_selectfreqin((enum lpc31_domainid_e)i, CGU_FS_FFAST); + + /* Add the domain to the set to be restored after the PLL is configured */ + + dmnset |= (1 << i); + } + } + + return dmnset; +} + +/**************************************************************************** + * Name: lpc31_restoredomains + * + * Description: + * Restore the PLL reference clock to the domains that were temporarily + * switched to FFAST by lpc31_switchdomains. + * + ****************************************************************************/ + +static inline void +lpc31_restoredomains(const struct lpc31_pllconfig_s * const cfg, + uint16_t dmnset) +{ + uint32_t finsel = (cfg->hppll ? CGU_FS_HPPLL1 : CGU_FS_HPPLL0); + int i; + + /* Check each domain */ + + for (i = 0; i < CGU_NDOMAINS; i++) + { + /* Was this one switched? */ + + if ((dmnset & (1 << i)) != 0) + { + /* Switch input reference clock to newly configured HPLL */ + + lpc31_selectfreqin((enum lpc31_domainid_e)i, finsel); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_pllconfig + * + * Description: + * Configure the PLL according to the provided selections. + * + ****************************************************************************/ + +void lpc31_pllconfig(const struct lpc31_pllconfig_s * const cfg) +{ + uint32_t pllbase; + uint16_t dmnset = 0; + + /* Switch domains connected to HPLL to FFAST */ + + dmnset = lpc31_switchdomains(cfg); + + /* Get the PLL register base address */ + + pllbase = LPC313x_CGU_HPPLL(cfg->hppll); + + /* Disable clock, disable skew enable, power down pll, (dis/en)able post + * divider, (dis/en)able pre-divider, disable free running mode, disable bandsel, + * enable up limmiter, disable bypass + */ + + putreg32(CGU_HPMODE_PD, pllbase + LPC31_CGU_HPMODE_OFFSET); + + /* Select PLL input frequency source */ + + putreg32(cfg->finsel, pllbase + LPC31_CGU_HPFINSEL_OFFSET); + + /* Set M divider */ + + putreg32(cfg->mdec & CGU_HPMDEC_MASK, pllbase + LPC31_CGU_HPMDEC_OFFSET); + + /* Set N divider */ + + putreg32(cfg->ndec & CGU_HPNDEC_MASK, pllbase + LPC31_CGU_HPNDEC_OFFSET); + + /* Set P divider */ + + putreg32(cfg->pdec & CGU_HPPDEC_MASK, pllbase + LPC31_CGU_HPPDEC_OFFSET); + + /* Set bandwidth */ + + putreg32(cfg->selr, pllbase + LPC31_CGU_HPSELR_OFFSET); + putreg32(cfg->seli, pllbase + LPC31_CGU_HPSELI_OFFSET); + putreg32(cfg->selp, pllbase + LPC31_CGU_HPSELP_OFFSET); + + /* Power up pll */ + + putreg32((cfg->mode & ~CGU_HPMODE_PD) | CGU_HPMODE_CLKEN, pllbase + LPC31_CGU_HPMODE_OFFSET); + + /* Save the estimated freq in driver data for future clk calcs */ + + g_boardfreqin[CGU_FREQIN_HPPLL0 + cfg->hppll] = cfg->freq; + + /* Wait for PLL to lock */ + + while ((getreg32(pllbase + LPC31_CGU_HPSTATUS_OFFSET) & CGU_HPSTATUS_LOCK) == 0); + + /* Switch the domains that were temporarily switched to FFAST back to the HPPLL */ + + lpc31_restoredomains(cfg, dmnset); +} + +/**************************************************************************** + * Name: lpc31_hp0pllconfig + * + * Description: + * Configure the HP0 PLL according to the board.h selections. + * + ****************************************************************************/ + +void lpc31_hp0pllconfig(void) +{ + struct lpc31_pllconfig_s cfg = + { + .hppll = CGU_HP0PLL, + .finsel = BOARD_HPLL0_FINSEL, + .ndec = BOARD_HPLL0_NDEC, + .mdec = BOARD_HPLL0_MDEC, + .pdec = BOARD_HPLL0_PDEC, + .selr = BOARD_HPLL0_SELR, + .seli = BOARD_HPLL0_SELI, + .selp = BOARD_HPLL0_SELP, + .mode = BOARD_HPLL0_MODE, + .freq = BOARD_HPLL0_FREQ + }; + + lpc31_pllconfig(&cfg); +} + +/**************************************************************************** + * Name: lpc31_hp1pllconfig + * + * Description: + * Configure the HP1 PLL according to the board.h selections. + * + ****************************************************************************/ + +void lpc31_hp1pllconfig(void) +{ + struct lpc31_pllconfig_s cfg = + { + .hppll = CGU_HP1PLL, + .finsel = BOARD_HPLL1_FINSEL, + .ndec = BOARD_HPLL1_NDEC, + .mdec = BOARD_HPLL1_MDEC, + .pdec = BOARD_HPLL1_PDEC, + .selr = BOARD_HPLL1_SELR, + .seli = BOARD_HPLL1_SELI, + .selp = BOARD_HPLL1_SELP, + .mode = BOARD_HPLL1_MODE, + .freq = BOARD_HPLL1_FREQ + }; + + lpc31_pllconfig(&cfg); +} + diff --git a/arch/arm/src/lpc31xx/lpc31_pwm.h b/arch/arm/src/lpc31xx/lpc31_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..042cd79d9c6dd449e59f0dd6d4f9bbbf302b124f --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_pwm.h @@ -0,0 +1,97 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_pwm.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_PWM_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_PWM_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* PWM register base address offset into the APB1 domain ****************************************/ + +#define LPC31_PWM_VBASE (LPC31_APB1_VADDR+LPC31_APB1_PWM_OFFSET) +#define LPC31_PWM_PBASE (LPC31_APB1_PADDR+LPC31_APB1_PWM_OFFSET) + +/* PWM register offsets (with respect to the PWM base) ******************************************/ + +#define LPC31_PWM_TMR_OFFSET 0x000 /* Timer Register */ +#define LPC31_PWM_CNTL_OFFSET 0x004 /* Control Register */ + +/* PWM register (virtual) addresses *************************************************************/ + +#define LPC31_PWM_TMR (LPC31_PWM_VBASE+LPC31_PWM_TMR_OFFSET) +#define LPC31_PWM_CNTL (LPC31_PWM_VBASE+LPC31_PWM_CNTL_OFFSET) + +/* PWM register bit definitions *****************************************************************/ + +/* Timer register TMR, address 0x13009000 */ + +#define PWM_TMR_SHIFT (0) /* Bits 0-11: Timer used for PWM and PDM */ +#define PWM_TMR_MASK (0xfff << PWM_TMR_SHIFT) + +/* Control register CNTL, address 0x13009004 */ + +#define PWM_CNTL_PDM (1 << 7) /* Bit 7: PDM Select PDM mode */ +#define PWM_CNTL_LOOP (1 << 6) /* Bit 6: Output inverted with top 4 TMR bits */ +#define PWM_CNTL_HI (1 << 4) /* Bit 4: PWM output forced high */ + /* Bits 2-3: Reserved */ +#define PWM_CNTL_CLK_SHIFT (0) /* Bits 0-1: Configure PWM_CLK for output pulses */ +#define PWM_CNTL_CLK_MASK (3 << PWM_CNTL_CLK_SHIFT) +# define PWM_CNTL_CLKDIV1 (0 << PWM_CNTL_CLK_SHIFT) /* PWM_CLK */ +# define PWM_CNTL_CLKDIV2 (1 << PWM_CNTL_CLK_SHIFT) /* PWM_CLK/2 */ +# define PWM_CNTL_CLKDIV4 (2 << PWM_CNTL_CLK_SHIFT) /* PWM_CLK/4 */ +# define PWM_CNTL_CLKDIV8 (3 << PWM_CNTL_CLK_SHIFT) /* PWM_CLK/8 */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_PWM_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_resetclks.c b/arch/arm/src/lpc31xx/lpc31_resetclks.c new file mode 100644 index 0000000000000000000000000000000000000000..4631f1474892da293afd19e314ee2453ab48c3aa --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_resetclks.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_resetclks.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_resetclks + * + * Description: + * Put all clocks into a known, initial state + * + ****************************************************************************/ + +void lpc31_resetclks(void) +{ + uint32_t regaddr; + uint32_t regval; + int bcrndx; + int esrndx; + int i; + + /* Switch all domain reference clocks to FFAST */ + + for (i = 0; i < CGU_NDOMAINS; i++) + { + /* Switch reference clock in to FFAST */ + + lpc31_selectfreqin((enum lpc31_domainid_e)i, CGU_FS_FFAST); + + /* Check if the domain has a BCR */ + + bcrndx = lpc31_bcrndx((enum lpc31_domainid_e)i); + if (bcrndx != BCRNDX_INVALID) + { + /* Yes.. disable all BCRs */ + + putreg32(0, LPC31_CGU_BCR(bcrndx)); + } + } + + /* Disable all clocks except those that are necessary */ + + for (i = CLKID_FIRST; i <= CLKID_LAST; i++) + { + /* Check if this clock has an ESR register */ + + esrndx = lpc31_esrndx((enum lpc31_clockid_e)i); + if (esrndx != ESRNDX_INVALID) + { + /* Yes.. Clear the clocks ESR to deselect fractional divider */ + + putreg32(0, LPC31_CGU_ESR(esrndx)); + } + + /* Enable external enabling for all possible clocks to conserve power */ + + lpc31_enableexten((enum lpc31_clockid_e)i); + + /* Set enable-out's for only the following clocks */ + + regaddr = LPC31_CGU_PCR(i); + regval = getreg32(regaddr); + if (i == (int)CLKID_ARM926BUSIFCLK || i == (int)CLKID_MPMCCFGCLK) + { + regval |= CGU_PCR_ENOUTEN; + } + else + { + regval &= ~CGU_PCR_ENOUTEN; + } + + putreg32(regval, regaddr); + + /* Set/clear the RUN bit in the PCR regiser of all clocks, depending + * upon if the clock is needed by the board logic or not + */ + + (void)lpc31_defclk((enum lpc31_clockid_e)i); + } + + /* Disable all fractional dividers */ + + for (i = 0; i < CGU_NFRACDIV; i++) + { + regaddr = LPC31_CGU_FDC(i); + regval = getreg32(regaddr); + regval &= ~CGU_FDC_RUN; + putreg32(regval, regaddr); + } +} diff --git a/arch/arm/src/lpc31xx/lpc31_rng.h b/arch/arm/src/lpc31xx/lpc31_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..e0539f96aa72844fa4c6bb333f40c10e86f617c9 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_rng.h @@ -0,0 +1,85 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_rng.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_RNG_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_RNG_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* RNG register base address offset into the APB0 domain ****************************************/ + +#define LPC31_RNG_VBASE (LPC31_APB0_VADDR+LPC31_APB0_RNG_OFFSET) +#define LPC31_RNG_PBASE (LPC31_APB0_PADDR+LPC31_APB0_RNG_OFFSET) + +/* RNG register offsets (with respect to the RNG base) ******************************************/ + +#define LPC31_RNG_RAND_OFFSET 0x0000 /* Random number */ +#define LPC31_RNG_PWRDWN_OFFSET 0x0ff4 /* Power-down mode */ + +/* RNG register (virtual) addresses *************************************************************/ + +#define LPC31_RNG_RAND (LPC31_RNG_VBASE+LPC31_RNG_RAND_OFFSET) +#define LPC31_RNG_PWRDWN (LPC31_RNG_VBASE+LPC31_RNG_PWRDWN_OFFSET) + +/* RNG register bit definitions *****************************************************************/ + +/* POWERDOWN, address 0x13006ff4 */ + +#define RNG_PWRDWN_PWRDWN (1 << 2) /* Block all accesses to standard registers */ +#define RNG_PWRDWN_FORCERST (1 << 1) /* With SOFTRST forces immediate RNG reset */ +#define RNG_PWRDWN_SOFTRST (1 << 0) /* Software RNG reset (delayed) */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_RNG_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_serial.c b/arch/arm/src/lpc31xx/lpc31_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..6567ce267e15179d51e23a4e16265e876d27c61d --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_serial.c @@ -0,0 +1,862 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_serial.c + * + * Copyright (C) 2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc31_cgudrvr.h" +#include "lpc31_uart.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint8_t ier; /* Saved IER value */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint8_t *ier); +static inline void up_restoreuartint(struct up_dev_s *priv, uint8_t ier); +static inline void up_enablebreaks(void); +static inline void up_disablebreaks(void); +static inline void up_configbaud(void); + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +static char g_rxbuffer[CONFIG_UART_RXBUFSIZE]; +static char g_txbuffer[CONFIG_UART_TXBUFSIZE]; + +/* This describes the state of the single LPC313XX uart port. */ + +static struct up_dev_s g_uartpriv; +static uart_dev_t g_uartport = +{ + .recv = + { + .size = CONFIG_UART_RXBUFSIZE, + .buffer = g_rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART_TXBUFSIZE, + .buffer = g_txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uartpriv, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint8_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLINTS; + } + + priv->ier &= ~UART_IER_ALLINTS; + putreg32((uint32_t)priv->ier, LPC31_UART_IER); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint8_t ier) +{ + priv->ier |= ier & UART_IER_ALLINTS; + putreg32((uint32_t)priv->ier, LPC31_UART_IER); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(void) +{ + uint32_t lcr = getreg32(LPC31_UART_LCR); + lcr |= UART_LCR_BRKCTRL; + putreg32(lcr, LPC31_UART_LCR); +} + +/**************************************************************************** + * Name: up_disablebreaks + ****************************************************************************/ + +static inline void up_disablebreaks(void) +{ + uint32_t lcr = getreg32(LPC31_UART_LCR); + lcr &= ~UART_LCR_BRKCTRL; + putreg32(lcr, LPC31_UART_LCR); +} + +/**************************************************************************** + * Name: up_configbaud + ****************************************************************************/ + +static inline void up_configbaud(void) +{ + /* In a buckled-up, embedded system, there is no reason to constantly + * calculate the following. The calculation can be skipped if the + * MULVAL, DIVADDVAL, and DIVISOR values are provided in the configuration + * file. + */ + +#ifndef CONFIG_LPC31_UART_MULVAL + uint32_t qtrclk; + uint32_t regval; + + /* Test values calculated for every multiplier/divisor combination */ + + uint32_t tdiv; + uint32_t terr; + int tmulval; + int tdivaddval; + + /* Optimal multiplier/divider values */ + + uint32_t div = 0; + uint32_t err = 100000; + int mulval = 1; + int divaddval = 0; + + /* Baud is generated using FDR and DLL-DLM registers + * + * baud = clock * (mulval/(mulval+divaddval) / (16 * div) + * + * Or + * + * div = (clock/16) * (mulval/(mulval+divaddval) / baud + * + * Where mulval = Fractional divider multiplier + * divaddval = Fractional divider pre-scale div + * div = DLL-DLM divisor + */ + + /* Get UART block clock divided by 16 */ + + qtrclk = lpc31_clkfreq(CLKID_UARTUCLK, DOMAINID_UART) >> 4; + + /* Try every valid multiplier, tmulval (or until a perfect + * match is found). + */ + + for (tmulval = 1 ; tmulval <= 15 && err > 0; tmulval++) + { + /* Try every valid pre-scale div, tdivaddval (or until a perfect + * match is found). + */ + + for (tdivaddval = 0 ; tdivaddval <= 15 && err > 0; tdivaddval++) + { + /* Calculate the divisor with these fractional divider settings */ + + uint32_t tmp = (tmulval * qtrclk) / ((tmulval + tdivaddval)); + tdiv = (tmp + (CONFIG_UART_BAUD >> 1)) / CONFIG_UART_BAUD; + + /* Check if this candidate divisor is within a valid range */ + + if (tdiv > 2 && tdiv < 0x10000) + { + /* Calculate the actual baud and the error */ + + uint32_t actualbaud = tmp / tdiv; + + if (actualbaud <= CONFIG_UART_BAUD) + { + terr = CONFIG_UART_BAUD - actualbaud; + } + else + { + terr = actualbaud - CONFIG_UART_BAUD; + } + + /* Is this the smallest error we have encountered? */ + + if (terr < err) + { + /* Yes, save these settings as the new, candidate optimal settings */ + + mulval = tmulval ; + divaddval = tdivaddval; + div = tdiv; + err = terr; + } + } + } + } + + /* Set the Divisor Latch Access Bit (DLAB) to enable DLL/DLM access */ + + regval = getreg32(LPC31_UART_LCR); + regval |= UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the MS and LS DLAB registers */ + + putreg32(div & UART_DLL_MASK, LPC31_UART_DLL); + putreg32((div >> 8) & UART_DLL_MASK, LPC31_UART_DLM); + + regval &= ~UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the Fractional Divider Register (FDR) */ + + putreg32((mulval << UART_FDR_MULVAL_SHIFT) | + (divaddval << UART_FDR_DIVADDVAL_SHIFT), + LPC31_UART_FDR); +#else + /* Set the Divisor Latch Access Bit (DLAB) to enable DLL/DLM access */ + + regval = getreg32(LPC31_UART_LCR); + regval |= UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the MS and LS DLAB registers */ + + putreg32(CONFIG_LPC31_UART_DIVISOR & UART_DLL_MASK, LPC31_UART_DLL); + putreg32((CONFIG_LPC31_UART_DIVISOR >> 8) & UART_DLL_MASK, LPC31_UART_DLM); + + regval &= ~UART_LCR_DLAB; + putreg32(regval, LPC31_UART_LCR); + + /* Configure the Fractional Divider Register (FDR) */ + + putreg32((CONFIG_LPC31_UART_MULVAL << UART_FDR_MULVAL_SHIFT) | + (CONFIG_LPC31_UART_DIVADDVAL << UART_FDR_DIVADDVAL_SHIFT), + LPC31_UART_FDR); +#endif +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is called + * the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Clear fifos */ + + putreg32((UART_FCR_RXFIFORST | UART_FCR_TXFIFORST), LPC31_UART_FCR); + + /* Set trigger */ + + putreg32((UART_FCR_FIFOENABLE | UART_FCR_RXTRIGLEVEL_16), LPC31_UART_FCR); + + /* Set up the IER */ + + priv->ier = getreg32(LPC31_UART_IER); + + /* Set up the LCR */ + + regval = 0; + +#if CONFIG_UART_BITS == 5 + regval |= UART_LCR_WDLENSEL_5BITS; +#elif CONFIG_UART_BITS == 6 + regval |= UART_LCR_WDLENSEL_6BITS; +#elif CONFIG_UART_BITS == 7 + regval |= UART_LCR_WDLENSEL_7BITS; +#else + regval |= UART_LCR_WDLENSEL_8BITS; +#endif + +#if CONFIG_UART_2STOP > 0 + regval |= UART_LCR_NSTOPBITS; +#endif + +#if CONFIG_UART_PARITY == 1 + regval |= UART_LCR_PAREN; +#elif CONFIG_UART_PARITY == 2 + regval |= (UART_LCR_PAREVEN | UART_LCR_PAREN); +#endif + putreg32(regval, LPC31_UART_LCR); + + /* Set the BAUD divisor */ + + up_configbaud(); + + /* Configure the FIFOs */ + + putreg32((UART_FCR_RXTRIGLEVEL_16 | UART_FCR_TXFIFORST | + UART_FCR_RXFIFORST | UART_FCR_FIFOENABLE), + LPC31_UART_FCR); + + /* The NuttX serial driver waits for the first THRE interrupt before + * sending serial data... However, it appears that the lpc313x hardware + * does not generate that interrupt until a transition from not-empty + * to empty. So, the current kludge here is to send one NULL at + * startup to kick things off. + */ + + putreg32('\0', LPC31_UART_THR); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * he the setup() method is called, however, the serial console may operate in + * in a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX and TX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(LPC31_IRQ_UART, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(LPC31_IRQ_UART); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + up_disable_irq(LPC31_IRQ_UART); + irq_detach(LPC31_IRQ_UART); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the UART irq. It should call uart_transmitchars + * or uart_receivechar to perform the appropriate data transfers. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = &g_uartport; + uint8_t status; + int passes; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = getreg32(LPC31_UART_IIR); + + /* The NO INTERRUPT should be zero if there are pending + * interrupts + */ + + if ((status & UART_IIR_NOINT) != 0) + { + /* Break out of the loop when there is no longer a pending + * interrupt + */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_INTID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_INTID_RDA: /* Received Data Available */ + case UART_IIR_INTID_TIMEOUT: /* Character time-out */ + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_INTID_THRE: /* Transmitter Holding Register empty */ + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts */ + + case UART_IIR_INTID_MS: /* Modem status */ + { + /* Read the modem status register (MSR) to clear */ + + status = getreg32(LPC31_UART_MSR); + fvdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_INTID_RLS: /* Receiver Line Status */ + { + /* Read the line status register (LSR) to clear */ + + status = getreg32(LPC31_UART_LSR); + fvdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_disablebreaks(); + leave_critical_section(flags); + } + break; + + default: + errno = ENOTTY; + ret = ERROR; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + uint32_t rbr; + + *status = getreg32(LPC31_UART_LSR); + rbr = getreg32(LPC31_UART_RBR); + return rbr & 0xff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_RDAINTEN; +#endif + } + else + { + priv->ier &= ~UART_IER_RDAINTEN; + } + putreg32(priv->ier, LPC31_UART_IER); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + return ((getreg32(LPC31_UART_LSR) & UART_LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + putreg32((uint32_t)ch, LPC31_UART_THR); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_THREINTEN; +#endif + } + else + { + priv->ier &= ~UART_IER_THREINTEN; + } + putreg32(priv->ier, LPC31_UART_IER); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + return ((getreg32(LPC31_UART_LSR) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + return ((getreg32(LPC31_UART_LSR) & UART_LSR_TEMT) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup (via up_putc). This must + * be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Enable UART system clock */ + + lpc31_enableclock(CLKID_UARTAPBCLK); + lpc31_enableclock(CLKID_UARTUCLK); + + /* Disable UART interrupts */ + + up_disableuartint(g_uartport.priv, NULL); + + /* Configuration the serial console */ + +#if defined(CONFIG_UART_SERIAL_CONSOLE) + g_uartport.isconsole = true; + up_setup(&g_uartport); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#if defined(CONFIG_UART_SERIAL_CONSOLE) + (void)uart_register("/dev/console", &g_uartport); +#endif + (void)uart_register("/dev/ttyS0", &g_uartport); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + struct up_dev_s *priv = &g_uartpriv; + uint8_t ier; + + /* Keep UART interrupts disabled so that we do not interfere with the + * serial driver. + */ + + up_disableuartint(priv, &ier); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + /* Output the character */ + + up_lowputc(ch); + up_restoreuartint(priv, ier); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + /* Output the character */ + + up_lowputc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc31xx/lpc31_setfdiv.c b/arch/arm/src/lpc31xx/lpc31_setfdiv.c new file mode 100644 index 0000000000000000000000000000000000000000..c532dcf97c582bb15c96b7aea2986e3aafd14fb0 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_setfdiv.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_setfdiv.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "lpc31_cgu.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_setfdiv + * + * Description: + * Set/reset subdomain frequency containing the specified clock using the + * provided divider settings + * + ****************************************************************************/ + +void lpc31_setfdiv(enum lpc31_domainid_e dmnid, + enum lpc31_clockid_e clkid, + const struct lpc31_fdivconfig_s *fdiv) +{ + uint32_t regaddr; + unsigned int basefreq; + int fdcndx; + int bcrndx; + + /* Get the frequency divider associated with this clock */ + + fdcndx = lpc31_fdcndx(clkid, dmnid); + + /* Does this clock have a frequency divicer? */ + + if (fdcndx != FDCNDX_INVALID) + { + /* Yes.. Save the current reference frequency selection */ + + regaddr = LPC31_CGU_SSR((int)dmnid); + basefreq = (getreg32(regaddr) & CGU_SSR_FS_MASK) >> CGU_SSR_FS_SHIFT; + + /* Switch domain to FFAST input */ + + lpc31_selectfreqin(dmnid, CGU_FS_FFAST); + + /* Get the index of the associated BCR register. Does this domain + * have a BCR? + */ + + bcrndx = lpc31_bcrndx(dmnid); + if (bcrndx != BCRNDX_INVALID) + { + + /* Yes... Disable the BCR */ + + regaddr = LPC31_CGU_BCR(bcrndx); + putreg32(0, regaddr); + } + + /* Change fractional divider to the provided settings */ + + lpc31_fdivinit(fdcndx, fdiv, true); + + /* Re-enable the BCR (if one is associated with this domain) */ + + if (bcrndx != BCRNDX_INVALID) + { + regaddr = LPC31_CGU_BCR(bcrndx); + putreg32(CGU_BCR_FDRUN, regaddr); + } + + /* Switch the domain back to its original base frequency */ + + lpc31_selectfreqin(dmnid, basefreq); + } +} diff --git a/arch/arm/src/lpc31xx/lpc31_setfreqin.c b/arch/arm/src/lpc31xx/lpc31_setfreqin.c new file mode 100644 index 0000000000000000000000000000000000000000..e70e08acc6d435b1d70bd9cbb98357d70a291229 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_setfreqin.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_setfreqin.c + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - NXP UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - NXP lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_selectfreqin + * + * Description: + * Set the base frequency source selection for with a clock domain + * + ****************************************************************************/ + +void lpc31_selectfreqin(enum lpc31_domainid_e dmnid, uint32_t finsel) +{ + uint32_t scraddr = LPC31_CGU_SCR(dmnid); + uint32_t fs1addr = LPC31_CGU_FS1(dmnid); + uint32_t fs2addr = LPC31_CGU_FS2(dmnid); + uint32_t scrbits; + + /* Get the frequency selection from the switch configuration register (SCR) + * for this domain. + */ + + scrbits = getreg32(scraddr) & ~(CGU_SCR_ENF1 | CGU_SCR_ENF2); + + /* If FS1 is currently enabled set the reference clock to FS2 and enable FS2 */ + + if ((getreg32(LPC31_CGU_SSR(dmnid)) & CGU_SSR_FS1STAT) != 0) + { + /* Check if the selected frequency, FS1, is same as requested */ + + if ((getreg32(fs1addr) & CGU_FS_MASK) != finsel) + { + /* No.. Set up FS2 */ + + putreg32(finsel, fs2addr); + putreg32(scrbits | CGU_SCR_ENF2, scraddr); + } + } + + /* FS1 is not currently enabled, check if the selected frequency, FS2, + * is same as requested + */ + + else if ((getreg32(fs2addr) & CGU_FS_MASK) != finsel) + { + /* No.. Set up FS1 */ + + putreg32(finsel, fs1addr); + putreg32(scrbits | CGU_SCR_ENF1, scraddr); + } +} diff --git a/arch/arm/src/lpc31xx/lpc31_softreset.c b/arch/arm/src/lpc31xx/lpc31_softreset.c new file mode 100644 index 0000000000000000000000000000000000000000..b3d32e548b41338162479b869f5605ac5f2754e9 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_softreset.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_softreset.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_arch.h" +#include "lpc31_cgudrvr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_softreset + * + * Description: + * Perform a soft reset on the specified module. + * + ****************************************************************************/ + +void lpc31_softreset(enum lpc31_resetid_e resetid) +{ + uint32_t address = LPC31_CGU_SOFTRST(resetid); + volatile int i; + + /* Clear and set the register */ + + putreg32(0, address); + + /* Delay a bit */ + + for (i = 0; i < 1000; i++); + + /* Then set the soft reset bit */ + + putreg32(CGU_SOFTRESET, address); +} diff --git a/arch/arm/src/lpc31xx/lpc31_spi.c b/arch/arm/src/lpc31xx/lpc31_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..f750ca0792db960e6025838e5975bacabfb70076 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_spi.c @@ -0,0 +1,971 @@ +/************************************************************************************ + * arm/arm/src/lpc31xx/lpc31_spi.c + * + * Copyright (C) 2009-2010, 2012, 2016 Gregory Nutt. All rights reserved. + * Author: David Hewson, deriving in part from other SPI drivers originally by + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "lpc31_spi.h" +#include "lpc31_ioconfig.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +/* Debug ****************************************************************************/ +/* CONFIG_LPC31_SPI_REGDEBUG enabled very low, register-level debug output. + * CONFIG_DEBUG must also be defined + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_LPC31_SPI_REGDEBUG +#endif + +/* FIFOs ****************************************************************************/ + +#define SPI_FIFO_DEPTH 64 /* 64 words deep (8- or 16-bit words) */ + +/* Timing ***************************************************************************/ + +#define SPI_MAX_DIVIDER 65024 /* = 254 * (255 + 1) */ +#define SPI_MIN_DIVIDER 2 + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct lpc31_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of work in bits (8 or 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ + + uint32_t slv1; + uint32_t slv2; +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +#ifdef CONFIG_LPC31_SPI_REGDEBUG +static bool spi_checkreg(bool wr, uint32_t value, uint32_t address); +static void spi_putreg(uint32_t value, uint32_t address); +static uint32_t spi_getreg(uint32_t address); +#else +# define spi_putreg(v,a) putreg32(v,a) +# define spi_getreg(a) getreg32(a) +#endif + +static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave, uint8_t val); +static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t slave); +static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv); +static inline void spi_writeword(FAR struct lpc31_spidev_s *priv, uint16_t word); + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = spi_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc31_spicmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not supported */ +}; + +static struct lpc31_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +#ifdef CONFIG_LPC31_SPI_REGDEBUG +static bool g_wrlast; +static uint32_t g_addresslast; +static uint32_t g_valuelast; +static int g_ntimes; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_SPI_REGDEBUG +static bool spi_checkreg(bool wr, uint32_t value, uint32_t address) +{ + if (wr == g_wrlast && value == g_valuelast && address == g_addresslast) + { + g_ntimes++; + return false; + } + else + { + if (g_ntimes > 0) + { + lldbg("...[Repeats %d times]...\n", g_ntimes); + } + + g_wrlast = wr; + g_valuelast = value; + g_addresslast = address; + g_ntimes = 0; + } + return true; +} +#endif + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a 32-bit value to an SPI register + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_SPI_REGDEBUG +static void spi_putreg(uint32_t value, uint32_t address) +{ + if (spi_checkreg(true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } + putreg32(value, address); +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read a 32-bit value from an SPI register + * + * Input Parameters: + * address - The address of the register to read from + * + * Returned Value: + * The value read from the register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC31_SPI_REGDEBUG +static uint32_t spi_getreg(uint32_t address) +{ + uint32_t value = getreg32(address); + if (spi_checkreg(false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } + return value; +} +#endif + +/**************************************************************************** + * Name: spi_drive_cs + * + * Description: + * Drive the chip select signal for this slave + * + * Input Parameters: + * dev - Device-specific state data + * slave - slave id + * value - value (0 for assert) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave, uint8_t val) +{ + switch (slave) + { + case 0: + if (val == 0) + { + spi_putreg(IOCONFIG_SPI_CSOUT0, LPC31_IOCONFIG_SPI_MODE0RESET); + } + else + { + spi_putreg(IOCONFIG_SPI_CSOUT0, LPC31_IOCONFIG_SPI_MODE0SET); + } + spi_putreg(IOCONFIG_SPI_CSOUT0, LPC31_IOCONFIG_SPI_MODE1SET); + break; + + case 1: + if (val == 0) + { + spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE0RESET); + } + else + { + spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE0SET); + } + spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE1SET); + break; + + case 2: + if (val == 0) + { + spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE0RESET); + } + else + { + spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE0SET); + } + spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE1SET); + break; + } +} + +/**************************************************************************** + * Name: spi_select_slave + * + * Description: + * Select the slave device for the next transfer + * + * Input Parameters: + * dev - Device-specific state data + * slave - slave id + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t slave) +{ + switch (slave) + { + case 0: + spi_putreg(priv->slv1, LPC31_SPI_SLV0_1); + spi_putreg(priv->slv2, LPC31_SPI_SLV0_2); + spi_putreg(SPI_SLVENABLE1_ENABLED, LPC31_SPI_SLVENABLE); + break; + + case 1: + spi_putreg(priv->slv1, LPC31_SPI_SLV1_1); + spi_putreg(priv->slv2, LPC31_SPI_SLV1_2); + spi_putreg(SPI_SLVENABLE2_ENABLED, LPC31_SPI_SLVENABLE); + break; + + case 2: + spi_putreg(priv->slv1, LPC31_SPI_SLV2_1); + spi_putreg(priv->slv2, LPC31_SPI_SLV2_2); + spi_putreg(SPI_SLVENABLE3_ENABLED, LPC31_SPI_SLVENABLE); + break; + } +} + +/************************************************************************************ + * Name: spi_readword + * + * Description: + * Read one word from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ************************************************************************************/ + +static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv) +{ + /* Wait until the RX FIFO is not empty */ + + while ((spi_getreg(LPC31_SPI_STATUS) & SPI_STATUS_RXFIFOEMPTY) != 0); + + /* Then return the received word */ + + return (uint16_t)spi_getreg(LPC31_SPI_FIFODATA); +} + +/************************************************************************************ + * Name: spi_writeword + * + * Description: + * Write one word to SPI + * + * Input Parameters: + * priv - Device-specific state data + * word - Word to send + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void spi_writeword(FAR struct lpc31_spidev_s *priv, uint16_t word) +{ + /* Wait until the TX FIFO is not full */ + + while ((spi_getreg(LPC31_SPI_STATUS) & SPI_STATUS_TXFIFOFULL) != 0); + + /* Then send the word */ + + spi_putreg(word, LPC31_SPI_FIFODATA); +} + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_select + * + * Description: + * Enable/disable the SPI slave select. The implementation of this method + * must include handshaking: If a device is selected, it must hold off + * all other attempts to select the device until the device is deselecte. + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - true: slave selected, false: slave de-selected + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) +{ + struct lpc31_spidev_s *priv = (struct lpc31_spidev_s *) dev; + uint8_t slave = 0; + + /* FIXME: map the devid to the SPI slave - this should really + * be in board specific code..... */ + switch (devid) + { + case SPIDEV_FLASH: + slave = 0; + break; + + case SPIDEV_MMCSD: + slave = 1; + break; + + case SPIDEV_ETHERNET: + slave = 2; + break; + + default: + return; + } + + /* Since we don't use sequential multi-slave mode, but rather + * perform the transfer piecemeal by consecutive calls to + * SPI_SEND, then we must manually assert the chip select + * across the whole transfer + */ + + if (selected) + { + spi_drive_cs(priv, slave, 0); + spi_select_slave(priv, slave); + + /* Enable SPI as master and notify of slave enables change */ + + spi_putreg((1 << SPI_CONFIG_INTERSLVDELAY_SHIFT) | SPI_CONFIG_UPDENABLE | SPI_CONFIG_SPIENABLE, LPC31_SPI_CONFIG); + } + else + { + spi_drive_cs(priv, slave, 1); + + /* Disable all slaves */ + + spi_putreg(0, LPC31_SPI_SLVENABLE); + + /* Disable SPI as master */ + + spi_putreg(SPI_CONFIG_UPDENABLE, LPC31_SPI_CONFIG); + } +} + +/************************************************************************************ + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + uint32_t spi_clk, div, div1, div2; + + if (priv->frequency != frequency) + { + /* The SPI clock is derived from the (main system oscillator / 2), + * so compute the best divider from that clock */ + + spi_clk = lpc31_clkfreq(CLKID_SPICLK, DOMAINID_SPI); + + /* Find closest divider to get at or under the target frequency */ + + div = (spi_clk + frequency / 2) / frequency; + + if (div > SPI_MAX_DIVIDER) + { + div = SPI_MAX_DIVIDER; + } + else if (div < SPI_MIN_DIVIDER) + { + div = SPI_MIN_DIVIDER; + } + + div2 = (((div-1) / 512) + 2) * 2; + div1 = ((((div + div2 / 2) / div2) - 1)); + + priv->slv1 = (priv->slv1 & ~(SPI_SLV_1_CLKDIV2_MASK | SPI_SLV_1_CLKDIV1_MASK)) | (div2 << SPI_SLV_1_CLKDIV2_SHIFT) | (div1 << SPI_SLV_1_CLKDIV1_SHIFT); + + priv->frequency = frequency; + priv->actual = frequency; /* FIXME */ + } + + return priv->actual; +} + +/************************************************************************************ + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + uint16_t setbits; + uint16_t clrbits; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR1 appropriately */ + + switch (mode) + { + case SPIDEV_MODE0: /* SPO=0; SPH=0 */ + setbits = 0; + clrbits = SPI_SLV_2_SPO | SPI_SLV_2_SPH; + break; + + case SPIDEV_MODE1: /* SPO=0; SPH=1 */ + setbits = SPI_SLV_2_SPH; + clrbits = SPI_SLV_2_SPO; + break; + + case SPIDEV_MODE2: /* SPO=1; SPH=0 */ + setbits = SPI_SLV_2_SPO; + clrbits = SPI_SLV_2_SPH; + break; + + case SPIDEV_MODE3: /* SPO=1; SPH=1 */ + setbits = SPI_SLV_2_SPO | SPI_SLV_2_SPH; + clrbits = 0; + break; + + default: + return; + } + + priv->slv2 = (priv->slv2 & ~clrbits) | setbits; + priv->mode = mode; + } +} + +/************************************************************************************ + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + priv->slv2 = (priv->slv2 & ~SPI_SLV_2_WDSIZE_MASK) | ((nbits-1) << SPI_SLV_2_WDSIZE_SHIFT); + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_status + * + * Description: + * Get SPI/MMC status + * + * Input Parameters: + * dev - Device-specific state data + * devid - Identifies the device to report status on + * + * Returned Value: + * Returns a bitset of status values (see SPI_STATUS_* defines + * + ****************************************************************************/ + +static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) +{ + /* FIXME: is there anyway to determine this + * it should probably be board dependant anyway */ + + return SPI_STATUS_PRESENT; +} + +/************************************************************************************ + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * word - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + DEBUGASSERT(priv); + + spi_writeword(priv, word); + return spi_readword(priv); +} + +/**************************************************************************** + * Name: spi_exchange + * + * Description: + * Exchange a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchaned in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev; + unsigned int maxtx; + unsigned int ntx; + + DEBUGASSERT(priv); + + /* 8- or 16-bit mode? */ + + if (priv->nbits == 16) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + while (nwords > 0) + { + /* Fill up the TX FIFO */ + + maxtx = nwords > SPI_FIFO_DEPTH ? SPI_FIFO_DEPTH : nwords; + for (ntx = 0; ntx < maxtx; ntx++) + { + /* Get the next word to write. Is there a source buffer? */ + + word = src ? *src++ : 0xffff; + + /* Then send the word */ + + spi_writeword(priv, word); + } + nwords -= maxtx; + + /* Then empty the RX FIFO */ + + while (ntx-- > 0) + { + word = spi_readword(priv); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + while (nwords > 0) + { + /* Fill up the TX FIFO */ + + maxtx = nwords > SPI_FIFO_DEPTH ? SPI_FIFO_DEPTH : nwords; + for (ntx = 0; ntx < maxtx; ntx++) + { + /* Get the next word to write. Is there a source buffer? */ + + word = src ? *src++ : 0xff; + + /* Then send the word */ + + spi_writeword(priv, (uint16_t)word); + } + nwords -= maxtx; + + /* Then empty the RX FIFO */ + + while (ntx-- > 0) + { + word = (uint8_t)spi_readword(priv); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + } +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords) +{ + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords) +{ + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *lpc31_spibus_initialize(int port) +{ + FAR struct lpc31_spidev_s *priv = &g_spidev; + + /* Only the SPI0 interface is supported */ + + if (port != 0) + { + return NULL; + } + + /* Configure SPI pins. Nothing needs to be done here because the SPI pins + * default to "driven-by-IP" on reset. + */ + +#ifdef CONFIG_LPC31_SPI_REGDEBUG + lldbg("PINS: %08x MODE0: %08x MODE1: %08x\n", + spi_getreg(LPC31_IOCONFIG_SPI_PINS), + spi_getreg(LPC31_IOCONFIG_SPI_MODE0), + spi_getreg(LPC31_IOCONFIG_SPI_MODE1)); +#endif + + /* Enable SPI clocks */ + + lpc31_enableclock(CLKID_SPIPCLK); + lpc31_enableclock(CLKID_SPIPCLKGATED); + lpc31_enableclock(CLKID_SPICLK); + lpc31_enableclock(CLKID_SPICLKGATED); + + /* Soft Reset the module */ + + lpc31_softreset(RESETID_SPIRSTAPB); + lpc31_softreset(RESETID_SPIRSTIP); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + /* Reset the SPI block */ + + spi_putreg(SPI_CONFIG_SOFTRST, LPC31_SPI_CONFIG); + + /* Initialise Slave 0 settings registers */ + + priv->slv1 = 0; + priv->slv2 = 0; + + /* Configure initial default mode */ + + priv->mode = SPIDEV_MODE1; + spi_setmode(&priv->spidev, SPIDEV_MODE0); + + /* Configure word width */ + + priv->nbits = 0; + spi_setbits(&priv->spidev, 8); + + /* Select a default frequency of approx. 400KHz */ + + priv->frequency = 0; + spi_setfrequency(&priv->spidev, 400000); + + return (FAR struct spi_dev_s *)priv; +} diff --git a/arch/arm/src/lpc31xx/lpc31_spi.h b/arch/arm/src/lpc31xx/lpc31_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..e1cd2eae85fea64d8a2e7f2625628755cb7bf9e2 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_spi.h @@ -0,0 +1,252 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_spi.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_SPI_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_SPI_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* SPI register base address offset into the APB2 domain ****************************************/ + +#define LPC31_SPI_VBASE (LPC31_APB2_VSECTION+LPC31_APB2_SPI_OFFSET) +#define LPC31_SPI_PBASE (LPC31_APB2_PSECTION+LPC31_APB2_SPI_OFFSET) + +/* SPI register offsets (with respect to the SPI base) ******************************************/ +/* SPI configuration registers */ + +#define LPC31_SPI_CONFIG_OFFSET 0x000 /* Configuration register */ +#define LPC31_SPI_SLVENABLE_OFFSET 0x004 /* Slave enable register */ +#define LPC31_SPI_TXFIFO_OFFSET 0x008 /* Transmit FIFO flush register */ +#define LPC31_SPI_FIFODATA_OFFSET 0x00C /* FIFO data register */ +#define LPC31_SPI_NHPPOP_OFFSET 0x010 /* NHP pop register */ +#define LPC31_SPI_NHPMODE_OFFSET 0x014 /* NHP mode selection register */ +#define LPC31_SPI_DMA_OFFSET 0x018 /* DMA settings register */ +#define LPC31_SPI_STATUS_OFFSET 0x01c /* Status register */ +#define LPC31_SPI_HWINFO_OFFSET 0x020 /* Hardware information register */ + +/* SPI slave registers */ + +#define LPC31_SPI_SLV0_1_OFFSET 0x024 /* Slave settings register 1 (for slave 0) */ +#define LPC31_SPI_SLV0_2_OFFSET 0x028 /* Slave settings register 2 (for slave 0) */ +#define LPC31_SPI_SLV1_1_OFFSET 0x02c /* Slave settings register 1 (for slave 1) */ +#define LPC31_SPI_SLV1_2_OFFSET 0x030 /* Slave settings register 2 (for slave 1) */ +#define LPC31_SPI_SLV2_1_OFFSET 0x034 /* Slave settings register 1 (for slave 2) */ +#define LPC31_SPI_SLV2_2_OFFSET 0x038 /* Slave settings register 2 (for slave 2) */ + /* 0x03c-0xfd0: Reserved */ +/* SPI interrupt registers */ + +#define LPC31_SPI_INTTHR_OFFSET 0xfd4 /* Tx/Rx threshold interrupt levels */ +#define LPC31_SPI_INTCLRENABLE_OFFSET 0xfd8 /* INT_ENABLE bits clear register */ +#define LPC31_SPI_INTSETENABLE_OFFSET 0xfdc /* INT_ENABLE bits set register */ +#define LPC31_SPI_INTSTATUS_OFFSET 0xfe0 /* Interrupt status register */ +#define LPC31_SPI_INTENABLE_OFFSET 0xfe4 /* Interrupt enable register */ +#define LPC31_SPI_INTCLRSTATUS_OFFSET 0xfe8 /* INT_STATUS bits clear register */ +#define LPC31_SPI_INTSETSTATUS_OFFSET 0xfec /* INT_STATUS bits set register */ + /* 0xff0-0xff8: Reserved */ + +/* SPI register (virtual) addresses *************************************************************/ + +/* SPI configuration registers */ + +#define LPC31_SPI_CONFIG (LPC31_SPI_VBASE+LPC31_SPI_CONFIG_OFFSET) +#define LPC31_SPI_SLVENABLE (LPC31_SPI_VBASE+LPC31_SPI_SLVENABLE_OFFSET) +#define LPC31_SPI_TXFIFO (LPC31_SPI_VBASE+LPC31_SPI_TXFIFO_OFFSET) +#define LPC31_SPI_FIFODATA (LPC31_SPI_VBASE+LPC31_SPI_FIFODATA_OFFSET) +#define LPC31_SPI_NHPPOP (LPC31_SPI_VBASE+LPC31_SPI_NHPPOP_OFFSET) +#define LPC31_SPI_NHPMODE (LPC31_SPI_VBASE+LPC31_SPI_NHPMODE_OFFSET) +#define LPC31_SPI_DMA (LPC31_SPI_VBASE+LPC31_SPI_DMA_OFFSET) +#define LPC31_SPI_STATUS (LPC31_SPI_VBASE+LPC31_SPI_STATUS_OFFSET) +#define LPC31_SPI_HWINFO (LPC31_SPI_VBASE+LPC31_SPI_HWINFO_OFFSET) + +/* SPI slave registers */ + +#define LPC31_SPI_SLV0_1 (LPC31_SPI_VBASE+LPC31_SPI_SLV0_1_OFFSET) +#define LPC31_SPI_SLV0_2 (LPC31_SPI_VBASE+LPC31_SPI_SLV0_2_OFFSET) +#define LPC31_SPI_SLV1_1 (LPC31_SPI_VBASE+LPC31_SPI_SLV1_1_OFFSET) +#define LPC31_SPI_SLV1_2 (LPC31_SPI_VBASE+LPC31_SPI_SLV1_2_OFFSET) +#define LPC31_SPI_SLV2_1 (LPC31_SPI_VBASE+LPC31_SPI_SLV2_1_OFFSET) +#define LPC31_SPI_SLV2_2 (LPC31_SPI_VBASE+LPC31_SPI_SLV2_2_OFFSET) + +/* SPI interrupt registers */ + +#define LPC31_SPI_INTTHR (LPC31_SPI_VBASE+LPC31_SPI_INTTHR_OFFSET) +#define LPC31_SPI_INTCLRENABLE (LPC31_SPI_VBASE+LPC31_SPI_INTCLRENABLE_OFFSET) +#define LPC31_SPI_INTSETENABLE (LPC31_SPI_VBASE+LPC31_SPI_INTSETENABLE_OFFSET) +#define LPC31_SPI_INTSTATUS (LPC31_SPI_VBASE+LPC31_SPI_INTSTATUS_OFFSET) +#define LPC31_SPI_INTENABLE (LPC31_SPI_VBASE+LPC31_SPI_INTENABLE_OFFSET) +#define LPC31_SPI_INTCLRSTATUS (LPC31_SPI_VBASE+LPC31_SPI_INTCLRSTATUS_OFFSET) +#define LPC31_SPI_INTSETSTATUS (LPC31_SPI_VBASE+LPC31_SPI_INTSETSTATUS_OFFSET) + +/* SPI register bit definitions *****************************************************************/ +/* SPI Configuration register CONFIG, address 0x15002000 */ + +#define SPI_CONFIG_INTERSLVDELAY_SHIFT (16) /* Bits 16-31: Delay between xfrs to different slaves */ +#define SPI_CONFIG_NTERSLVDELAY_MASK (0xffff << SPI_CONFIG_INTERSLVDELAY_SHIFT) +#define SPI_CONFIG_UPDENABLE (1 << 7) /* Bit 7: 7 Update enable bit */ +#define SPI_CONFIG_SOFTRST (1 << 6) /* Bit 6: 6 Software reset bit */ +#define SPI_CONFIG_SLVDISABLE (1 << 4) /* Bit 4: 4 Slave output disable (slave mode) */ +#define SPI_CONFIG_XMITMODE (1 << 3) /* Bit 3: 3 Transmit mode */ +#define SPI_CONFIG_LOOPBACK (1 << 2) /* Bit 2: 2 Loopback mode bit */ +#define SPI_CONFIG_MS (1 << 1) /* Bit 1: 1 Master/slave mode bit */ +#define SPI_CONFIG_SPIENABLE (1 << 0) /* Bit 0: 0 SPI enable bit */ + +/* Slave Enable register SLVENABLE, address 0x15002004 */ + +#define SPI_SLVENABLE3_SHIFT (4) /* Bits 4-5: Slave 3 enable bits */ +#define SPI_SLVENABLE3_MASK (3 << SPI_SLVENABLE3_SHIFT) +# define SPI_SLVENABLE3_DISABLED (0 << SPI_SLVENABLE3_SHIFT) /* Disabled */ +# define SPI_SLVENABLE3_ENABLED (1 << SPI_SLVENABLE3_SHIFT) /* Enabled */ +# define SPI_SLVENABLE3_SUSPENDED (3 << SPI_SLVENABLE3_SHIFT) /* Suspended */ +#define SPI_SLVENABLE2_SHIFT (2) /* Bits 2-3: Slave 2 enable bits */ +#define SPI_SLVENABLE2_MASK (3 << SPI_SLVENABLE2_SHIFT) +# define SPI_SLVENABLE2_DISABLED (0 << SPI_SLVENABLE2_SHIFT) /* Disabled */ +# define SPI_SLVENABLE2_ENABLED (1 << SPI_SLVENABLE2_SHIFT) /* Enabled */ +# define SPI_SLVENABLE2_SUSPENDED (3 << SPI_SLVENABLE2_SHIFT) /* Suspended */ +#define SPI_SLVENABLE1_SHIFT (0) /* Bits 0-1: Slave 1 enable bits */ +#define SPI_SLVENABLE1_MASK (3 << SPI_SLVENABLE1_SHIFT) +# define SPI_SLVENABLE1_DISABLED (0 << SPI_SLVENABLE1_SHIFT) /* Disabled */ +# define SPI_SLVENABLE1_ENABLED (1 << SPI_SLVENABLE1_SHIFT) /* Enabled */ +# define SPI_SLVENABLE1_SUSPENDED (3 << SPI_SLVENABLE1_SHIFT) /* Suspended */ + +/* Transmit FIFO flush register TXFIFO, address 0x15002008 */ + +#define SPI_TXFIFO_FLUSH (1 << 0) /* Bit 0: Transmit FIFO flush bit */ + +/* FIFO data register FIFODATA, address 0x1500200c */ + +#define SPI_FIFODATA_SHIFT (0) /* Bits 0-15: FIFO data */ +#define SPI_FIFODATA_MASK (0xffff << SPI_FIFODATA_SHIFT) + +/* NHP POP register NHPPOP, address 0x15002010 */ + +#define SPI_NHPPOP (1 << 0) /* Bit 0: NHP pop bit */ + +/* NHP mode register NHPMODE, address 0x15002014 */ + +#define SPI_NHPMODE (1 << 0) /* Bit 0: NHP mode bit */ + +/* DMA setting register DMA, address 0x15002018 */ + +#define SPI_DMA_TXENABLE (1 << 1) /* Bit 1: Tx DMA enable bit */ +#define SPI_DMA_RXEMABLE (1 << 0) /* Bit 0: Rx DMA enable bit */ + +/* Status register STATUS, address 0x1500201c */ + +#define SPI_STATUS_SMSBUSY (1 << 5) /* Bit 5: Sequential multi-slave mode busy */ +#define SPI_STATUS_BUSY (1 << 4) /* Bit 4: SPI busy flag */ +#define SPI_STATUS_RXFIFOFULL (1 << 3) /* Bit 3: Receive FIFO full bit */ +#define SPI_STATUS_RXFIFOEMPTY (1 << 2) /* Bit 2: Receive FIFO empty bit */ +#define SPI_STATUS_TXFIFOFULL (1 << 1) /* Bit 1: Transmit FIFO full bit */ +#define SPI_STATUS_TXFIFOEMPTY (1 << 0) /* Bit 0: Transmit FIFO empty bit */ + +/* Hardware information register HWINFO, address 0x15002020 */ + +#define SPI_HWINFO_FIFOIMPLT (1 << 30) /* Bit 30: FIFO memory implementation */ +#define SPI_HWINFO_NSLAVES_SHIFT (26) /* Bits 26-29: Maximum number of slaves (minus 1) */ +#define SPI_HWINFO_NSLAVES_MASK (0x0f << SPI_HWINFO_NSLAVES_SHIFT) +#define SPI_HWINFO_TXFIFOWIDTH_SHIFT (21) /* Bits 21-25: Width transmit FIFO (minus 1) */ +#define SPI_HWINFO_TXFIFOWIDTH_MASK (0x1f << SPI_HWINFO_TXFIFOWIDTH_SHIFT) +#define SPI_HWINFO_RXFIFOWIDTH_SHIFT (16) /* Bits 16-20: Width receive FIFO (minus 1) */ +#define SPI_HWINFO_RXFIFOWIDTH_MASK (0x1f << SPI_HWINFO_RXFIFOWIDTH_SHIFT) +#define SPI_HWINFO_TXFIFODEPTH_SHIFT (8) /* Bits 8-15: 64 */ +#define SPI_HWINFO_TXFIFODEPTH_MASK (0x0ff << SPI_HWINFO_TXFIFODEPTH_SHIFT) +#define SPI_HWINFO_RXFIFODEPTH_SHIFT (0) /* Bits 0-7: 64 */ +#define SPI_HWINFO_RXFIFODEPTH_MASK (0xff << SPI_HWINFO_RXFIFODEPTH_SHIFT) + +/* Slave settings 1 SLV0-2_1, addresses 0x15002024, 0x1500202c, and 0x15002034 */ + +#define SPI_SLV_1_INTERXFRDLY_SHIFT (24) /* Bits 24-31: Delay between slave xfrs (master mode) */ +#define SPI_SLV_1_INTERXFRDLY_MASK (0xff << SPI_SLV_1_INTERXFRDLY_SHIFT) +#define SPI_SLV_1_NWORDS_SHIFT (16) /* Bits 16-23: Number words to send in SMS mode (master mode) */ +#define SPI_SLV_1_NWORDS_MASK (0xff << SPI_SLV_1_NWORDS_SHIFT) +#define SPI_SLV_1_CLKDIV2_SHIFT (8) /* Bits 8-15: Serial clock divisor 2 */ +#define SPI_SLV_1_CLKDIV2_MASK (0xff << SPI_SLV_1_CLKDIV2_SHIFT) +#define SPI_SLV_1_CLKDIV1_SHIFT (0) /* Bits 0-7: Serial clock rate divisor 1 */ +#define SPI_SLV_1_CLKDIV1_MASK (0xff << SPI_SLV_1_CLKDIV1_SHIFT) + +/* Slave settings 2 SLV0-2_2, addresses 0x15002028, 0x15002030, and0x15002038 */ + +#define SPI_SLV_2_DELAY_SHIFT (9) /* Bits 9-16: Programmable delay */ +#define SPI_SLV_2_DELAY_MASK (0xff << SPI_SLV_2_DELAY_SHIFT) +#define SPI_SLV_2_CSVAL (1 << 8) /* Bit 8: Chip select value between transfers */ +#define SPI_SLV_2_XFRFMT (1 << 7) /* Bit 7: Format of transfer */ +#define SPI_SLV_2_SPO (1 << 6) /* Bit 6: Serial clock polarity */ +#define SPI_SLV_2_SPH (1 << 5) /* Bit 5: Serial clock phase */ +#define SPI_SLV_2_WDSIZE_SHIFT (0) /* Bits 0-4: Word size of transfers slave (minus 1) */ +#define SPI_SLV_2_WDSIZE_MASK (0x1f << SPI_SLV_2_WDSIZE_SHIFT) + +/* Interrupt threshold register INTTHR, address 0x15002fd4 */ + +#define SPI_INTTHR_TX_SHIFT (8) /* Bits 8-15: Interrupt when less than this in TX FIFO */ +#define SPI_INTTHR_TX_MASK (0xff << SPI_INTTHR_TX_SHIFT) +#define SPI_INTTHR_RX_SHIFT (0) /* Bits 0-7: Interrupt when more than this in RX FIFO */ +#define SPI_INTTHR_RX_MASK (0xff << SPI_INTTHR_TX_SHIFT) + +/* Interrupt clear enable register INTCLRENABLE, address 0x15002fd8, + * Interrupt set enable register INTSETENABLE, address 0x15002fdc, + * Interrupt status register INTSTATUS, address 0x15002fe0, + * Interrupt enable register INTENABLE, address 0x15002fe4, + * Interrupt clear status register INTCLRSTATUS, address 0x15002fe8, + * Interrupt set status register INTSETSTATUS, address 0x15002fec + */ + +#define SPI_INT_SMS (1 << 4) /* Bit 4: Sequential multi-slave mode ready interrupt bit */ +#define SPI_INT_TX (1 << 3) /* Bit 3: Transmit threshold level interrupt bit */ +#define SPI_INT_RX (1 << 2) /* Bit 3: Receive threshold level interrupt bit */ +#define SPI_INT_TO (1 << 1) /* Bit 1: Receive timeout interrupt bit */ +#define SPI_INT_OV (1 << 0) /* Bit 0: Receive overrtun interrupt bit */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_SPI_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_syscreg.h b/arch/arm/src/lpc31xx/lpc31_syscreg.h new file mode 100644 index 0000000000000000000000000000000000000000..72b08c9d9bbe01a2e54ecc398765bcf1784428aa --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_syscreg.h @@ -0,0 +1,611 @@ +/******************************************************************************************************** + * arch/arm/src/lpc31xx/lpc31_syscreg.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_SYSCREG_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_SYSCREG_H + +/******************************************************************************************************** + * Included Files + ********************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/******************************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************************/ + +/* SYSCREG register base address offset into the APB0 domain ********************************************/ + +#define LPC31_SYSCREG_VBASE (LPC31_APB0_VADDR+LPC31_APB0_SYSCREG_OFFSET) +#define LPC31_SYSCREG_PBASE (LPC31_APB0_PADDR+LPC31_APB0_SYSCREG_OFFSET) + +/* SYSCREG register offsets (with respect to the SYSCREG base) ******************************************/ +/* Miscellaneous system configuration registers, part1 */ + /* 0x000-0x004: Reserved */ +#define LPC31_SYSCREG_EBIMPMCPRIO_OFFSET 0x008 /* Priority of MPMC channel for EBI interface */ +#define LPC31_SYSCREG_EBNANDCPRIO_OFFSET 0x00c /* Priority of NAND controller channel for EBI interface */ +#define LPC31_SYSCREG_EBIUNUSEDPRIO_OFFSET 0x010 /* Priority of unused channel */ +#define LPC31_SYSCREG_RINGOSCCFG_OFFSET 0x014 /* RING oscillator configuration register */ +#define LPC31_SYSCREG_ADCPDADC10BITS_OFFSET 0x018 /* Powerdown register of ADC 10bits */ +#define LPC31_SYSCREG_CGUDYNHP0_OFFSET 0x01c /* reserved */ +#define LPC31_SYSCREG_CGUDYNHP1_OFFSET 0x020 /* reserved */ +#define LPC31_SYSCREG_ABCCFG_OFFSET 0x024 /* AHB burst control register */ +#define LPC31_SYSCREG_SDMMCCFG_OFFSET 0x028 /* SD_MMC (MCI) configuration register */ +#define LPC31_SYSCREG_MCIDELAYMODES_OFFSET 0x02c /* Delay register for the SD_MMC (MCI) clocks */ + +/* USB configuration registers */ + +#define LPC31_SYSCREG_USB_ATXPLLPDREG_OFFSET 0x030 /* Power down register of USB ATX PLL */ +#define LPC31_SYSCREG_USB_OTGCFG_OFFSET 0x034 /* USB OTG configuration register */ +#define LPC31_SYSCREG_USB_OTGPORTINDCTL_OFFSET 0x038 /* USB OTG port indicator LED control outputs */ + /* 0x03c: Reserved */ +#define LPC31_SYSCREG_USB_PLLNDEC_OFFSET 0x040 /* USB OTG PLL configuration register NOEC */ +#define LPC31_SYSCREG_USB_PLLMDEC_OFFSET 0x044 /* USB OTG PLL configuration register MDEC */ +#define LPC31_SYSCREG_USB_PLLPDEC_OFFSET 0x048 /* USB OTG PLL configuration register PDEC */ +#define LPC31_SYSCREG_USB_PLLSELR_OFFSET 0x04c /* USB OTG PLL configuration register SELR */ +#define LPC31_SYSCREG_USB_PLLSELI_OFFSET 0x050 /* USB OTG PLL configuration register SELI */ +#define LPC31_SYSCREG_USB_PLLSELP_OFFSET 0x054 /* USB OTG PLL configuration register SELP */ + +/* ISRAM/ISROM configuration registers */ + +#define LPC31_SYSCREG_ISRAM0_LATENCYCFG_OFFSET 0x058 /* Internal SRAM 0 latency configuration register */ +#define LPC31_SYSCREG_ISRAM1_LATENCYCFG_OFFSET 0x05c /* Internal SRAM 1 latency configuration register */ +#define LPC31_SYSCREG_ISROM_LATENCYCFG_OFFSET 0x060 /* Internal SROM latency configuration register */ + +/* MPMC configuration registers */ + +#define LPC31_SYSCREG_MPMC_AHBMISC_OFFSET 0x064 /* Configuration register of MPMC */ +#define LPC31_SYSCREG_MPMC_DELAYMODES_OFFSET 0x068 /* Configuration of MPMC clock delay */ +#define LPC31_SYSCREG_MPMC_WAITRD0_OFFSET 0x06c /* Configuration of the wait cycles for read transfers */ +#define LPC31_SYSCREG_MPMC_WAITRD1_OFFSET 0x070 /* Configuration of the wait cycles for read transfers */ +#define LPC31_SYSCREG_MPMC_WIREEBIMSZ_OFFSET 0x074 /* Configuration of the memory width for MPMC */ +#define LPC31_SYSCREG_MPMC_TESTMODE0_OFFSET 0x078 /* Configuration for refresh generation of MPMC */ +#define LPC31_SYSCREG_MPMC_TESTMODE1_OFFSET 0x07c /* Configuration for refresh generation of MPMC */ + +/* Miscellaneous system configuration registers, part 2 */ + +#define LPC31_SYSCREG_AHB0EXTPRIO_OFFSET 0x080 /* Priority of the AHB masters */ +#define LPC31_SYSCREG_ARM926SHADOWPTR_OFFSET 0x084 /* Memory mapping */ + /* 0x088-0x08c reserved */ +/* Pin multiplexing control registers */ + +#define LPC31_SYSCREG_MUX_LCDEBISEL_OFFSET 0x090 /* Selects between lcd_interface and EBI pins */ +#define LPC31_SYSCREG_MUX_GPIOMCISEL_OFFSET 0x094 /* Selects between GPIO and MCI pins */ +#define LPC31_SYSCREG_MUX_NANDMCISEL_OFFSET 0x098 /* Selects between NAND flash controller and MCI pins */ +#define LPC31_SYSCREG_MUX_UARTSPISEL_OFFSET 0x09c /* Selects between UART and SPI pins */ +#define LPC31_SYSCREG_MUX_I2STXPCMSEL_OFFSET 0x0a0 /* Selects between I2STX and PCM pins */ + +/* Pad configuration registers */ + +#define LPC31_SYSCREG_PAD_EBID9_OFFSET 0x0a4 /* Control pad EBI_D_9 */ +#define LPC31_SYSCREG_PAD_EBID10_OFFSET 0x0a8 /* Control pad EBI_D_10 */ +#define LPC31_SYSCREG_PAD_EBID11_OFFSET 0x0ac /* Control pad EBI_D_11 */ +#define LPC31_SYSCREG_PAD_EBID12_OFFSET 0x0b0 /* Control pad EBI_D_12 */ +#define LPC31_SYSCREG_PAD_EBID13_OFFSET 0x0b4 /* Control pad EBI_D_13 */ +#define LPC31_SYSCREG_PAD_EBID14_OFFSET 0x0b8 /* Control pad EBI_D_14 */ +#define LPC31_SYSCREG_PAD_I2SRXBCK0_OFFSET 0x0bc /* Control pad I2SRX_BCK0 */ +#define LPC31_SYSCREG_PAD_MGPIO9_OFFSET 0x0c0 /* Control pad MGPIO9 */ +#define LPC31_SYSCREG_PAD_MGPIO6_OFFSET 0x0c4 /* Control pad MGPIO6 */ +#define LPC31_SYSCREG_PAD_MLCDDB7_OFFSET 0x0c8 /* Control pad MLCD_DB_7 */ +#define LPC31_SYSCREG_PAD_MLCDDB4_OFFSET 0x0cc /* Control pad MLCD_DB_4 */ +#define LPC31_SYSCREG_PAD_MLCDDB2_OFFSET 0x0d0 /* Control pad MLCD_DB_2 */ +#define LPC31_SYSCREG_PAD_MNANDRYBN0_OFFSET 0x0d4 /* Control pad MNAND_RYBN0 */ +#define LPC31_SYSCREG_PAD_GPIO1_OFFSET 0x0d8 /* Control pad GPIO1 */ +#define LPC31_SYSCREG_PAD_EBID4_OFFSET 0x0dc /* Control pad EBI_D_4 */ +#define LPC31_SYSCREG_PAD_MI2STXCLK0_OFFSET 0x0e0 /* Control pad MI2STX_CLK0 */ +#define LPC31_SYSCREG_PAD_MI2STXBCK0_OFFSET 0x0e4 /* Control pad MI2STX_BCK0 */ +#define LPC31_SYSCREG_PAD_EBIA1CLE_OFFSET 0x0e8 /* Control pad EBI_A_1_CLE */ +#define LPC31_SYSCREG_PAD_EBINCASBLOUT0_OFFSET 0x0ec /* Control pad EBI_NCAS_BLOUT_0 */ +#define LPC31_SYSCREG_PAD_NANDNCS3_OFFSET 0x0f0 /* Control pad NAND_NCS_3 */ +#define LPC31_SYSCREG_PAD_MLCDDB0_OFFSET 0x0f4 /* Control pad MLCD_DB_0 */ +#define LPC31_SYSCREG_PAD_EBIDQM0NOE_OFFSET 0x0f8 /* Control pad EBI_DQM_0_NOE */ +#define LPC31_SYSCREG_PAD_EBID0_OFFSET 0x0fc /* Control pad EBI_D_0 */ +#define LPC31_SYSCREG_PAD_EBID1_OFFSET 0x100 /* Control pad EBI_D_1 */ +#define LPC31_SYSCREG_PAD_EBID2_OFFSET 0x104 /* Control pad EBI_D_2 */ +#define LPC31_SYSCREG_PAD_EBID3_OFFSET 0x108 /* Control pad EBI_D_3 */ +#define LPC31_SYSCREG_PAD_EBID5_OFFSET 0x10c /* Control pad EBI_D_5 */ +#define LPC31_SYSCREG_PAD_EBID6_OFFSET 0x110 /* Control pad EBI_D_6 */ +#define LPC31_SYSCREG_PAD_EBID7_OFFSET 0x114 /* Control pad EBI_D_7 */ +#define LPC31_SYSCREG_PAD_EBID8_OFFSET 0x118 /* Control pad EBI_D_8 */ +#define LPC31_SYSCREG_PAD_EBID15_OFFSET 0x11c /* Control pad EBI_D_15 */ +#define LPC31_SYSCREG_PAD_I2STXDATA1_OFFSET 0x120 /* Control pad I2STX_DATA1 */ +#define LPC31_SYSCREG_PAD_I2STXBCK1_OFFSET 0x124 /* Control pad I2STX_BCK1 */ +#define LPC31_SYSCREG_PAD_I2STXWS1_OFFSET 0x128 /* Control pad I2STX_WS1 */ +#define LPC31_SYSCREG_PAD_I2SRXDATA0_OFFSET 0x12c /* Control pad I2SRX_DATA0 */ +#define LPC31_SYSCREG_PAD_I2SRXWS0_OFFSET 0x130 /* Control pad I2SRX_WS0 */ +#define LPC31_SYSCREG_PAD_I2SRXDATA1_OFFSET 0x134 /* Control pad I2SRX_DATA1 */ +#define LPC31_SYSCREG_PAD_I2SRXBCK1_OFFSET 0x138 /* Control pad I2SRX_BCK1 */ +#define LPC31_SYSCREG_PAD_I2SRXWS1_OFFSET 0x13c /* Control pad I2SRX_WS1 */ +#define LPC31_SYSCREG_PAD_SYSCLKO_OFFSET 0x140 /* Control pad SYSCLK_O */ +#define LPC31_SYSCREG_PAD_PWMDATA_OFFSET 0x144 /* Control pad PWM_DATA */ +#define LPC31_SYSCREG_PAD_UARTRXD_OFFSET 0x148 /* Control pad UART_RXD */ +#define LPC31_SYSCREG_PAD_UARTTXD_OFFSET 0x14c /* Control pad UART_TXD */ +#define LPC31_SYSCREG_PAD_I2CSDA1_OFFSET 0x150 /* Control pad I2C_SDA1 */ +#define LPC31_SYSCREG_PAD_I2CSCL1_OFFSET 0x154 /* Control pad I2C_SCL1 */ +#define LPC31_SYSCREG_PAD_CLK256FSO_OFFSET 0x158 /* Control pad CLK_256FS_O */ +#define LPC31_SYSCREG_PAD_GPIO0_OFFSET 0x15c /* Control pad GPIO0 */ +#define LPC31_SYSCREG_PAD_GPIO2_OFFSET 0x160 /* Control pad GPIO2 */ +#define LPC31_SYSCREG_PAD_GPIO3_OFFSET 0x164 /* Control pad GPIO3 */ +#define LPC31_SYSCREG_PAD_GPIO4_OFFSET 0x168 /* Control pad GPIO4 */ +#define LPC31_SYSCREG_PAD_GPIO11_OFFSET 0x16c /* Control pad GPIO11 */ +#define LPC31_SYSCREG_PAD_GPIO12_OFFSET 0x170 /* Control pad GPIO12 */ +#define LPC31_SYSCREG_PAD_GPIO13_OFFSET 0x174 /* Control pad GPIO13 */ +#define LPC31_SYSCREG_PAD_GPIO14_OFFSET 0x178 /* Control pad GPIO14 */ +#define LPC31_SYSCREG_PAD_GPIO15_OFFSET 0x17c /* Control pad GPIO15 */ +#define LPC31_SYSCREG_PAD_GPIO16_OFFSET 0x180 /* Control pad GPIO16 */ +#define LPC31_SYSCREG_PAD_GPIO17_OFFSET 0x184 /* Control pad GPIO17 */ +#define LPC31_SYSCREG_PAD_GPIO18_OFFSET 0x188 /* Control pad GPIO18 */ +#define LPC31_SYSCREG_PAD_GPIO19_OFFSET 0x18c /* Control pad GPIO19 */ +#define LPC31_SYSCREG_PAD_GPIO20_OFFSET 0x190 /* Control pad GPIO20 */ +#define LPC31_SYSCREG_PAD_SPIMISO_OFFSET 0x194 /* Control pad SPI_MISO */ +#define LPC31_SYSCREG_PAD_SPIMOSI_OFFSET 0x198 /* Control pad SPI_MOSI */ +#define LPC31_SYSCREG_PAD_SPICSIN_OFFSET 0x19c /* Control pad SPI_CS_IN */ +#define LPC31_SYSCREG_PAD_SPISCK_OFFSET 0x1a0 /* Control pad SPI_SCK */ +#define LPC31_SYSCREG_PAD_SPICSOUT0_OFFSET 0x1a4 /* Control pad SPI_CS_OUT0 */ +#define LPC31_SYSCREG_PAD_NANDNCS0_OFFSET 0x1a8 /* Control pad NAND_NCS_0 */ +#define LPC31_SYSCREG_PAD_NANDNCS1_OFFSET 0x1ac /* Control pad NAND_NCS_1 */ +#define LPC31_SYSCREG_PAD_NANDNCS2_OFFSET 0x1b0 /* Control pad NAND_NCS_2 */ +#define LPC31_SYSCREG_PAD_MLCDCSB_OFFSET 0x1b4 /* Control pad MLCD_CSB */ +#define LPC31_SYSCREG_PAD_MLCDDB1_OFFSET 0x1b8 /* Control pad MLCD_DB_1 */ +#define LPC31_SYSCREG_PAD_MLCDERD_OFFSET 0x1bc /* Control pad MLCD_E_RD */ +#define LPC31_SYSCREG_PAD_MLCDRS_OFFSET 0x1c0 /* Control pad MLCD_RS */ +#define LPC31_SYSCREG_PAD_MLCDRWWR_OFFSET 0x1c4 /* Control pad MLCD_RW_WR */ +#define LPC31_SYSCREG_PAD_MLCDDB3_OFFSET 0x1c8 /* Control pad MLCD_DB_3 */ +#define LPC31_SYSCREG_PAD_MLCDDB5_OFFSET 0x1cc /* Control pad MLCD_DB_5 */ +#define LPC31_SYSCREG_PAD_MLCDDB6_OFFSET 0x1d0 /* Control pad MLCD_DB_6 */ +#define LPC31_SYSCREG_PAD_MLCDDB8_OFFSET 0x1d4 /* Control pad MLCD_DB_8 */ +#define LPC31_SYSCREG_PAD_MLCDDB9_OFFSET 0x1d8 /* Control pad MLCD_DB_9 */ +#define LPC31_SYSCREG_PAD_MLCDDB10_OFFSET 0x1dc /* Control pad MLCD_DB_10 */ +#define LPC31_SYSCREG_PAD_MLCDDB11_OFFSET 0x1e0 /* Control pad MLCD_DB_11 */ +#define LPC31_SYSCREG_PAD_MLCDDB12_OFFSET 0x1e4 /* Control pad MLCD_DB_12 */ +#define LPC31_SYSCREG_PAD_MLCDDB13_OFFSET 0x1e8 /* Control pad MLCD_DB_13 */ +#define LPC31_SYSCREG_PAD_MLCDDB14_OFFSET 0x1ec /* Control pad MLCD_DB_14 */ +#define LPC31_SYSCREG_PAD_MLCDDB15_OFFSET 0x1f0 /* Control pad MLCD_DB_15 */ +#define LPC31_SYSCREG_PAD_MGPIO5_OFFSET 0x1f4 /* Control pad MGPIO5 */ +#define LPC31_SYSCREG_PAD_MGPIO7_OFFSET 0x1f8 /* Control pad MGPIO5 */ +#define LPC31_SYSCREG_PAD_MGPIO8_OFFSET 0x1fc /* Control pad MGPIO8 */ +#define LPC31_SYSCREG_PAD_MGPIO10_OFFSET 0x200 /* Control pad MGPIO10 */ +#define LPC31_SYSCREG_PAD_MNANDRYBN1_OFFSET 0x204 /* Control pad MNAND_RYBN1 */ +#define LPC31_SYSCREG_PAD_MNANDRYBN2_OFFSET 0x208 /* Control pad MNAND_RYBN2 */ +#define LPC31_SYSCREG_PAD_MNANDRYBN3_OFFSET 0x20c /* Control pad MNAND_RYBN3 */ +#define LPC31_SYSCREG_PAD_MUARTCTSN_OFFSET 0x210 /* Control pad MUART_CTS_N */ +#define LPC31_SYSCREG_PAD_MI2STXDATA0_OFFSET 0x218 /* Control pad MI2STX_DATA0 */ +#define LPC31_SYSCREG_PAD_MI2STXWS0_OFFSET 0x21c /* Control pad MI2STX_WS0 */ +#define LPC31_SYSCREG_PAD_EBINRASBLOUT1_OFFSET 0x220 /* Control pad EBI_NRAS_BLOUT_1 */ +#define LPC31_SYSCREG_PAD_EBIA0ALE_OFFSET 0x224 /* Control pad EBI_A_0_ALE */ +#define LPC31_SYSCREG_PAD_EBINWE_OFFSET 0x228 /* Control pad EBI_NWE */ +#define LPC31_SYSCREG_PAD_ESHCTRLSUP4_OFFSET 0x22c /* Control pad at 1.8 and 3.3V (Nandflash/EBI pads) */ +#define LPC31_SYSCREG_PAD_ESHCTRLSUP8_OFFSET 0x230 /* Control pad at 1.8 and 3.3V (LCD interface/SDRAM pads) */ + +/* SYSCREG register (virtual) addresses *****************************************************************/ +/* Miscellaneous system configuration registers, part1 */ + +#define LPC31_SYSCREG_EBIMPMCPRIO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_EBIMPMCPRIO_OFFSET) +#define LPC31_SYSCREG_EBNANDCPRIO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_EBNANDCPRIO_OFFSET) +#define LPC31_SYSCREG_EBIUNUSEDPRIO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_EBIUNUSEDPRIO_OFFSET) +#define LPC31_SYSCREG_RINGOSCCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_RINGOSCCFG_OFFSET) +#define LPC31_SYSCREG_ADCPDADC10BITS (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ADCPDADC10BITS_OFFSET) +#define LPC31_SYSCREG_ABCCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ABCCFG_OFFSET) +#define LPC31_SYSCREG_SDMMCCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_SDMMCCFG_OFFSET) +#define LPC31_SYSCREG_MCIDELAYMODES (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MCIDELAYMODES_OFFSET) + +/* USB configuration registers */ + +#define LPC31_SYSCREG_USB_ATXPLLPDREG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_ATXPLLPDREG_OFFSET) +#define LPC31_SYSCREG_USB_OTGCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_OTGCFG_OFFSET) +#define LPC31_SYSCREG_USB_OTGPORTINDCTL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_OTGPORTINDCTL_OFFSET) +#define LPC31_SYSCREG_USB_PLLNDEC (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLNDEC_OFFSET) +#define LPC31_SYSCREG_USB_PLLMDEC (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLMDEC_OFFSET) +#define LPC31_SYSCREG_USB_PLLPDEC (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLPDEC_OFFSET) +#define LPC31_SYSCREG_USB_PLLSELR (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLSELR_OFFSET) +#define LPC31_SYSCREG_USB_PLLSELI (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLSELI_OFFSET) +#define LPC31_SYSCREG_USB_PLLSELP (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_USB_PLLSELP_OFFSET) + +/* ISRAM/ISROM configuration registers */ + +#define LPC31_SYSCREG_ISRAM0_LATENCYCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ISRAM0_LATENCYCFG_OFFSET) +#define LPC31_SYSCREG_ISRAM1_LATENCYCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ISRAM1_LATENCYCFG_OFFSET) +#define LPC31_SYSCREG_ISROM_LATENCYCFG (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ISROM_LATENCYCFG_OFFSET) + +/* MPMC configuration registers */ + +#define LPC31_SYSCREG_MPMC_AHBMISC (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_AHBMISC_OFFSET) +#define LPC31_SYSCREG_MPMC_DELAYMODES (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_DELAYMODES_OFFSET) +#define LPC31_SYSCREG_MPMC_WAITRD0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_WAITRD0_OFFSET) +#define LPC31_SYSCREG_MPMC_WAITRD1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_WAITRD1_OFFSET) +#define LPC31_SYSCREG_MPMC_WIREEBIMSZ (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_WIREEBIMSZ_OFFSET) +#define LPC31_SYSCREG_MPMC_TESTMODE0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_TESTMODE0_OFFSET) +#define LPC31_SYSCREG_MPMC_TESTMODE1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MPMC_TESTMODE1_OFFSET) + +/* Miscellaneous system configuration registers, part 2 */ + +#define LPC31_SYSCREG_AHB0EXTPRIO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_AHB0EXTPRIO_OFFSET) +#define LPC31_SYSCREG_ARM926SHADOWPTR (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_ARM926SHADOWPTR_OFFSET) + +/* Pin multiplexing control registers */ + +#define LPC31_SYSCREG_MUX_LCDEBISEL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MUX_LCDEBISEL_OFFSET) +#define LPC31_SYSCREG_MUX_GPIOMCISEL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MUX_GPIOMCISEL_OFFSET) +#define LPC31_SYSCREG_MUX_NANDMCISEL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MUX_NANDMCISEL_OFFSET) +#define LPC31_SYSCREG_MUX_UARTSPISEL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MUX_UARTSPISEL_OFFSET) +#define LPC31_SYSCREG_MUX_I2STXPCMSEL (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_MUX_I2STXPCMSEL_OFFSET) + +/* Pad configuration registers */ + +#define LPC31_SYSCREG_PAD_EBID9 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID9_OFFSET) +#define LPC31_SYSCREG_PAD_EBID10 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID10_OFFSET) +#define LPC31_SYSCREG_PAD_EBID11 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID11_OFFSET) +#define LPC31_SYSCREG_PAD_EBID12 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID12_OFFSET) +#define LPC31_SYSCREG_PAD_EBID13 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID13_OFFSET) +#define LPC31_SYSCREG_PAD_EBID14 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID14_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXBCK0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXBCK0_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO9 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO9_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO6 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO6_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB7 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB7_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB4 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB4_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB2 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB2_OFFSET) +#define LPC31_SYSCREG_PAD_MNANDRYBN0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MNANDRYBN0_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO1_OFFSET) +#define LPC31_SYSCREG_PAD_EBID4 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID4_OFFSET) +#define LPC31_SYSCREG_PAD_MI2STXCLK0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MI2STXCLK0_OFFSET) +#define LPC31_SYSCREG_PAD_MI2STXBCK0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MI2STXBCK0_OFFSET) +#define LPC31_SYSCREG_PAD_EBIA1CLE (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBIA1CLE_OFFSET) +#define LPC31_SYSCREG_PAD_EBINCASBLOUT0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBINCASBLOUT0_OFFSET) +#define LPC31_SYSCREG_PAD_NANDNCS3 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_NANDNCS3_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB0_OFFSET) +#define LPC31_SYSCREG_PAD_EBIDQM0NOE (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBIDQM0NOE_OFFSET) +#define LPC31_SYSCREG_PAD_EBID0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID0_OFFSET) +#define LPC31_SYSCREG_PAD_EBID1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID1_OFFSET) +#define LPC31_SYSCREG_PAD_EBID2 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID2_OFFSET) +#define LPC31_SYSCREG_PAD_EBID3 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID3_OFFSET) +#define LPC31_SYSCREG_PAD_EBID5 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID5_OFFSET) +#define LPC31_SYSCREG_PAD_EBID6 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID6_OFFSET) +#define LPC31_SYSCREG_PAD_EBID7 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID7_OFFSET) +#define LPC31_SYSCREG_PAD_EBID8 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID8_OFFSET) +#define LPC31_SYSCREG_PAD_EBID15 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBID15_OFFSET) +#define LPC31_SYSCREG_PAD_I2STXDATA1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2STXDATA1_OFFSET) +#define LPC31_SYSCREG_PAD_I2STXBCK1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2STXBCK1_OFFSET) +#define LPC31_SYSCREG_PAD_I2STXWS1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2STXWS1_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXDATA0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXDATA0_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXWS0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXWS0_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXDATA1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXDATA1_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXBCK1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXBCK1_OFFSET) +#define LPC31_SYSCREG_PAD_I2SRXWS1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2SRXWS1_OFFSET) +#define LPC31_SYSCREG_PAD_SYSCLKO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SYSCLKO_OFFSET) +#define LPC31_SYSCREG_PAD_PWMDATA (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_PWMDATA_OFFSET) +#define LPC31_SYSCREG_PAD_UARTRXD (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_UARTRXD_OFFSET) +#define LPC31_SYSCREG_PAD_UARTTXD (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_UARTTXD_OFFSET) +#define LPC31_SYSCREG_PAD_I2CSDA1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2CSDA1_OFFSET) +#define LPC31_SYSCREG_PAD_I2CSCL1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_I2CSCL1_OFFSET) +#define LPC31_SYSCREG_PAD_CLK256FSO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_CLK256FSO_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO0_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO2 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO2_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO3 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO3_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO4 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO4_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO11 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO11_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO12 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO12_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO13 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO13_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO14 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO14_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO15 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO15_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO16 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO16_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO17 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO17_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO18 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO18_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO19 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO19_OFFSET) +#define LPC31_SYSCREG_PAD_GPIO20 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_GPIO20_OFFSET) +#define LPC31_SYSCREG_PAD_SPIMISO (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SPIMISO_OFFSET) +#define LPC31_SYSCREG_PAD_SPIMOSI (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SPIMOSI_OFFSET) +#define LPC31_SYSCREG_PAD_SPICSIN (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SPICSIN_OFFSET) +#define LPC31_SYSCREG_PAD_SPISCK (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SPISCK_OFFSET) +#define LPC31_SYSCREG_PAD_SPICSOUT0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_SPICSOUT0_OFFSET) +#define LPC31_SYSCREG_PAD_NANDNCS0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_NANDNCS0_OFFSET) +#define LPC31_SYSCREG_PAD_NANDNCS1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_NANDNCS1_OFFSET) +#define LPC31_SYSCREG_PAD_NANDNCS2 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_NANDNCS2_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDCSB (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDCSB_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB1_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDERD (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDERD_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDRS (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDRS_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDRWWR (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDRWWR_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB3 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB3_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB5 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB5_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB6 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB6_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB8 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB8_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB9 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB9_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB10 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB10_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB11 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB11_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB12 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB12_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB13 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB13_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB14 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB14_OFFSET) +#define LPC31_SYSCREG_PAD_MLCDDB15 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MLCDDB15_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO5 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO5_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO7 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO7_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO8 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO8_OFFSET) +#define LPC31_SYSCREG_PAD_MGPIO10 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MGPIO10_OFFSET) +#define LPC31_SYSCREG_PAD_MNANDRYBN1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MNANDRYBN1_OFFSET) +#define LPC31_SYSCREG_PAD_MNANDRYBN2 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MNANDRYBN2_OFFSET) +#define LPC31_SYSCREG_PAD_MNANDRYBN3 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MNANDRYBN3_OFFSET) +#define LPC31_SYSCREG_PAD_MUARTCTSN (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MUARTCTSN_OFFSET) +#define LPC31_SYSCREG_PAD_MI2STXDATA0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MI2STXDATA0_OFFSET) +#define LPC31_SYSCREG_PAD_MI2STXWS0 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_MI2STXWS0_OFFSET) +#define LPC31_SYSCREG_PAD_EBINRASBLOUT1 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBINRASBLOUT1_OFFSET) +#define LPC31_SYSCREG_PAD_EBIA0ALE (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBIA0ALE_OFFSET) +#define LPC31_SYSCREG_PAD_EBINWE (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_EBINWE_OFFSET) +#define LPC31_SYSCREG_PAD_ESHCTRLSUP4 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_ESHCTRLSUP4_OFFSET) +#define LPC31_SYSCREG_PAD_ESHCTRLSUP8 (LPC31_SYSCREG_VBASE+LPC31_SYSCREG_PAD_ESHCTRLSUP8_OFFSET) + +/* SYSCREG register bit definitions *********************************************************************/ +/* Miscellaneous system configuration registers, part1 */ + +/* SYSCREG_EBIMPMCPRIO, address 0x13002808 + * SYSCREG_EBINANDCPRIO address 0x1300280c + * SYSCREG_EBIUNUSEDPRIO address 0x13002810 + */ + +#define SYSCREG_EBI_TIMEOUT_SHIFT (0) /* Bits 0-9: Time MPMC, NAND or unused channel */ +#define SYSCREG_EBI_TIMEOUT_MASK (0x3ff << SYSCREG_EBI_TIMEOUT_SHIFT) + +/* RINGOSCCFG address 0x13002814 */ + +#define SYSCREG_RINGOSCCFG_OSC1EN (1 << 1) /* Bit 1: Enable ring oscillator 1 */ +#define SYSCREG_RINGOSCCFG_OSC0EN (1 << 0) /* Bit 0: Enable oscillator 0 */ + +/* SYSCREG_ADCPDADC10BITS address 0x13002818 */ + +#define SYSCREG_ADCPDADC10BITS_PWRDOWN (1 << 0) /* Bit 0: Power down ADC */ + +/* SYSCREG_ABCCFG address 0x13002824 */ + +#define SYSCREG_ABCCFG_USBOTG_SHIFT (9) /* Bits 9-11: USB_OTG AHB bus bandwidth control */ +#define SYSCREG_ABCCFG_USBOTG_MASK (7 << SYSCREG_ABCCFG_USBOTG_SHIFT) +# define SYSCREG_ABCCFG_USBOTG_NORMAL (0 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Normal mode */ +# define SYSCREG_ABCCFG_USBOTG_NONSEQ (1 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Make non-sequential */ +# define SYSCREG_ABCCFG_USBOTG_SPLIT4 (2 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_USBOTG_SPLIT8 (3 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Split to 8-beat */ +# define SYSCREG_ABCCFG_USBOTG_EXT8 (4 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Extend to 8-beat */ +# define SYSCREG_ABCCFG_USBOTG_EXT16 (5 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Extend to 16-beat */ +# define SYSCREG_ABCCFG_USBOTG_SPLIT4W (6 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_USBOTG_EXT32 (7 << SYSCREG_ABCCFG_USBOTG_SHIFT) /* extend to 32-beat */ +#define SYSCREG_ABCCFG_ARM926EJSI_SHIFT (6) /* Bits 6-8: ARM926EJS instruction AHB bus bandwidth control */ +#define SYSCREG_ABCCFG_ARM926EJSI_MASK (7 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) +# define SYSCREG_ABCCFG_ARM926EJSI_NORMAL (0 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Normal mode */ +# define SYSCREG_ABCCFG_ARM926EJSI_NONSEQ (1 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Make non-sequential */ +# define SYSCREG_ABCCFG_ARM926EJSI_SPLIT4 (2 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_ARM926EJSI_SPLIT8 (3 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Split to 8-beat */ +# define SYSCREG_ABCCFG_ARM926EJSI_EXT8 (4 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Extend to 8-beat */ +# define SYSCREG_ABCCFG_ARM926EJSI_EXT16 (5 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Extend to 16-beat */ +# define SYSCREG_ABCCFG_ARM926EJSI_SPLIT4W (6 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_ARM926EJSI_EXT32 (7 << SYSCREG_ABCCFG_ARM926EJSI_SHIFT) /* extend to 32-beat */ +#define SYSCREG_ABCCFG_ARM926EJSD_SHIFT (3) /* Bits 3-5: ARM926EJS data AHB bus bandwidth control */ +#define SYSCREG_ABCCFG_ARM926EJSD_MASK (7 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) +# define SYSCREG_ABCCFG_ARM926EJSD_NORMAL (0 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Normal mode */ +# define SYSCREG_ABCCFG_ARM926EJSD_NONSEQ (1 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Make non-sequential */ +# define SYSCREG_ABCCFG_ARM926EJSD_SPLIT4 (2 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_ARM926EJSD_SPLIT8 (3 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Split to 8-beat */ +# define SYSCREG_ABCCFG_ARM926EJSD_EXT8 (4 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Extend to 8-beat */ +# define SYSCREG_ABCCFG_ARM926EJSD_EXT16 (5 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Extend to 16-beat */ +# define SYSCREG_ABCCFG_ARM926EJSD_SPLIT4W (6 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_ARM926EJSD_EXT32 (7 << SYSCREG_ABCCFG_ARM926EJSD_SHIFT) /* extend to 32-beat */ +#define SYSCREG_ABCCFG_DMA_SHIFT (0) /* Bits 0-2: 2:0 DMA AHB bus bandwidth control */ +#define SYSCREG_ABCCFG_DMA_MASK (7 << SYSCREG_ABCCFG_DMA_SHIFT) +# define SYSCREG_ABCCFG_DMA_NORMAL (0 << SYSCREG_ABCCFG_DMA_SHIFT) /* Normal mode */ +# define SYSCREG_ABCCFG_DMA_NONSEQ (1 << SYSCREG_ABCCFG_DMA_SHIFT) /* Make non-sequential */ +# define SYSCREG_ABCCFG_DMA_SPLIT4 (2 << SYSCREG_ABCCFG_DMA_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_DMA_SPLIT8 (3 << SYSCREG_ABCCFG_DMA_SHIFT) /* Split to 8-beat */ +# define SYSCREG_ABCCFG_DMA_EXT8 (4 << SYSCREG_ABCCFG_DMA_SHIFT) /* Extend to 8-beat */ +# define SYSCREG_ABCCFG_DMA_EXT16 (5 << SYSCREG_ABCCFG_DMA_SHIFT) /* Extend to 16-beat */ +# define SYSCREG_ABCCFG_DMA_SPLIT4W (6 << SYSCREG_ABCCFG_DMA_SHIFT) /* Split to 4-beat */ +# define SYSCREG_ABCCFG_DMA_EXT32 (7 << SYSCREG_ABCCFG_DMA_SHIFT) /* extend to 32-beat */ + +/* SYSCREG_SDMMCCFG address 0x13002828 */ + +#define SYSCREG_SDMMCCFG_CARDDETECT (1 << 1) /* Bit 1: Card detect signal */ +#define SYSCREG_SDMMCCFG_CARDWRITEPRT (1 << 0) /* Bit 0: Card write protect signal for SD cards */ + +/* SYSCREG_MCIDELAYMODES address 0x1300282c */ + +#define SYSCREG_MCIDELAYMODES_DELAYENABLE (1 << 4) /* Bit 4: Enable delay cells */ +#define SYSCREG_MCIDELAYMODES_DELAYCELLS_SHIFT (0) /* Bits 0-3: Number of delay cells needed */ +#define SYSCREG_MCIDELAYMODES_DELAYCELLS_MASK (15 << SYSCREG_MCIDELAYMODES_DELAYCELLS_SHIFT) + +/* USB configuration registers */ +/* USB_ATXPLLPDREG address 0x13002830 */ + +#define SYSCREG_USB_ATXPLLPDREG_PWRDOWN (1 << 0) /* Bit 0: Powerdown */ + +/* USB_OTGCFG address 0x13002834 */ + +#define SYSCREG_USB_OTGCFG_VBUSPWRFAULT (1 << 3) /* Bit 3: Charge pump overcurrent */ +#define SYSCREG_USB_OTGCFG_DEVWAKEUP (1 << 2) /* Bit 2: External wakeup (device mode) */ +#define SYSCREG_USB_OTGCFG_HOSTWAKEUP (1 << 1) /* Bit 1: External wake-up (host mode) */ + +/* USB_OTGPORTINDCTL address 0x1300 2838 */ + +#define SYSCREG_USB_OTGPORTINDCTL_SHIFT (0) /* Bits 0-1: Status bits for USB connector LEDs */ +#define SYSCREG_USB_OTGPORTINDCTL_MASK (3 << SYSCREG_USB_OTGPORTINDCTL_SHIFT) +# define SYSCREG_USB_OTGPORTINDCTL_OFF (0 << SYSCREG_USB_OTGPORTINDCTL_SHIFT) /* off */ +# define SYSCREG_USB_OTGPORTINDCTL_AMBER (1 << SYSCREG_USB_OTGPORTINDCTL_SHIFT) /* amber */ +# define SYSCREG_USB_OTGPORTINDCTL_GREEN (2 << SYSCREG_USB_OTGPORTINDCTL_SHIFT) /* green */ + +/* USB_PLLNDEC address 0x13002840 */ + +#define SYSCREG_USB_PLLNDEC_SHIFT (0) /* Bits 0-9: Pre-divider for the USB pll */ +#define SYSCREG_USB_PLLNDEC_MASK (0x3ff << SYSCREG_USB_PLLNDEC_SHIFT) + +/* USB_PLLMDEC address 0x13002844 */ + +#define SYSCREG_USB_PLLMDEC_SHIFT (0) /* Bits 0-16: Feedback-divider for the USB pll */ +#define SYSCREG_USB_PLLMDEC_MASK (0x1ffff << SYSCREG_USB_PLLMDEC_SHIFT) + +/* USB_PLLPDEC address 0x13002848 */ + +#define SYSCREG_USB_PLLPDEC_SHIFT (0) /* Bits 0-3: Feedback-divider for the USB pll */ +#define SYSCREG_USB_PLLPDEC_MASK (15 << SYSCREG_USB_PLLPDEC_SHIFT) + +/* USB_PLLSELR address 0x1300284c */ + +#define SYSCREG_USB_PLLSELR_SHIFT (0) /* Bits 0-3: Bandwidth selection */ +#define SYSCREG_USB_PLLSELR_MASK (15 << SYSCREG_USB_PLLSELR_SHIFT) + +/* USB_PLLSELI address 0x13002850 */ + +#define SYSCREG_USB_PLLSELI_SHIFT (0) /* Bits 0-3: Bandwidth selection */ +#define SYSCREG_USB_PLLSELI_MASK (15 << SYSCREG_USB_PLLSELI_SHIFT) + +/* USB_PLLSELP address 0x13002854 */ + +#define SYSCREG_USB_PLLSELP_SHIFT (0) /* Bits 0-3: Bandwidth selection */ +#define SYSCREG_USB_PLLSELP_MASK (15 << SYSCREG_USB_PLLSELP_SHIFT) + +/* ISRAM/ISROM configuration registers */ +/* SYSCREG_ISRAM0_LATENCYCFG address 0x13002858 */ + +#define SYSCREG_ISRAM0_LATENCYCFG_SHIFT (0) /* Bits 0-1: Number of waitstates */ +#define SYSCREG_ISRAM0_LATENCYCFG_MASK (3 << SYSCREG_ISRAM0_LATENCYCFG_SHIFT) + +/* SYSCREG_ISRAM1_LATENCYCFG address 0x1300285c */ + +#define SYSCREG_ISRAM1_LATENCYCFG_SHIFT (0) /* Bits 0-1: Number of waitstates */ +#define SYSCREG_ISRAM1_LATENCYCFG_MASK (3 << SYSCREG_ISRAM1_LATENCYCFG_SHIFT) + +/* SYSCREG_ISROM_LATENCYCFG address 0x13002860 */ + +#define SYSCREG_ISROM_LATENCYCFG_SHIFT (0) /* Bits 0-1: Number of waitstates */ +#define SYSCREG_ISROM_LATENCYCFG_MASK (3 << SYSCREG_ISROM_LATENCYCFG_SHIFT) + +/* MPMC configuration registers */ +/* SYSCREG_AHB_MPMC_MISC (address 0x13002864 */ + +#define SYSCREG_MPMC_MISC_REL1CONFIG (1 << 8) /* Bit 8: Static memory address mode select */ +#define SYSCREG_MPMC_MISC_STCS1PB (1 << 7) /* Bit 7: Polarity of byte lane select for static memory CS1 */ +#define SYSCREG_MPMC_MISC_STCS1POL (1 << 4) /* Bit 4: Polarity of static memory CS1 */ +#define SYSCREG_MPMC_MISC_STCS0POL (1 << 3) /* Bit 3: Polarity of static memory CS0 */ +#define SYSCREG_MPMC_MISC_SREFREQ (1 << 0) /* Bit 0: Self refresh request */ + +/* SYSCREG_MPMC_DELAYMODES address 0x13002868 */ + +#define SYSCREG_MPMC_DELAYMODES_DEL1_SHIFT (12) /* Bits 12-17: Delay cells for MPMCCLKOUT */ +#define SYSCREG_MPMC_DELAYMODES_DEL1_MASK (63 << SYSCREG_MPMC_DELAYMODES_DEL1_SHIFT) +#define SYSCREG_MPMC_DELAYMODES_DEL2_SHIFT (6) /* Bits 6-11: Delay cells between MPMCCLK and MPMCCLKDELAY */ +#define SYSCREG_MPMC_DELAYMODES_DEL2_MASK (63 << SYSCREG_MPMC_DELAYMODES_DEL2_SHIFT) +#define SYSCREG_MPMC_DELAYMODES_DEL3_SHIFT (0) /* Bits 0-5: Delay cells between MPMCCLK and MPMCFBCLKIN */ +#define SYSCREG_MPMC_DELAYMODES_DEL3_MASK (63 << SYSCREG_MPMC_DELAYMODES_DEL3_SHIFT) + +/* SYSCREG_MPMC_WAITRD0 address 0x1300286c */ + +#define SYSCREG_MPMC_WAITRD0_EXTRAOE (1 << 5) /* Bit 5: Enable the extra inactive OE cycle */ +#define SYSCREG_MPMC_WAITRD0_SHIFT (0) /* Bits 0-4: Value for MPMCStaticWaitRd0 */ +#define SYSCREG_MPMC_WAITRD0_MASK (31 << SYSCREG_MPMC_WAITRD0_SHIFT) + +/* SYSCREG_MPMC_WAITRD1 address 0x13002870 */ + +#define SYSCREG_MPMC_WAITRD1_EXTRAOE (1 << 5) /* Bit 5: Enable the extra inactive OE cycle */ +#define SYSCREG_MPMC_WAITRD1_SHIFT (0) /* Bits 0-4: Value for MPMCStaticWaitRd1 */ +#define SYSCREG_MPMC_WAITRD1_MASK (31 << SYSCREG_MPMC_WAITRD1_SHIFT) + +/* SYSCREG_WIR_EBIMSINIT address 0x13002874 */ + +#define SYSCREG_MPMC_WIREEBIMSZ_SHIFT (0) /* Bits 0-1: Memory width of CS1 */ +#define SYSCREG_MPMC_WIREEBIMSZ_MASK (3 << SYSCREG_MPMC_WIREEBIMSZ_SHIFT) + +/* MPMC_TESTMODE0 address 0x13002878 */ + +#define SYSCREG_MPMC_TESTMODE0_EXTREFENABLE (1 << 12) /* Bit 13: External refresh of MPMC */ +#define SYSCREG_MPMC_TESTMODE0_EXTREFCNT_SHIFT (0) /* Bits 0-11: Period of external refresh */ +#define SYSCREG_MPMC_TESTMODE0_EXTREFCNT_MASK (0xfff << SYSCREG_MPMC_TESTMODE0_EXTREFCNT_SHIFT) + +/* MPMC_TESTMODE1 address 0x1300287c */ + +#define SYSCREG_MPMC_TESTMODE1_HSENABLE_SHIFT (0) /* Bits 0-7: Allows AHB to run faster while refreshing */ +#define SYSCREG_MPMC_TESTMODE1_HSENABLE_MASK (0xff << SYSCREG_MPMC_TESTMODE1_HSENABLE_SHIFT) + +/* Miscellaneous system configuration registers, part 2 */ +/* AHB0EXTPRIO address 0x13002880 */ + +#define SYSCREG_AHB0EXTPRIO_USBOTG (1 << 3) /* Bit 3: USBOTG has higher priority */ +#define SYSCREG_AHB0EXTPRIO_ARM926DATA (1 << 2) /* Bit 2: ARM926 Data has higher priority */ +#define SYSCREG_AHB0EXTPRIO_ARM926NSTR (1 << 1) /* Bit 1: ARM926 Instruction has higher priority */ +#define SYSCREG_AHB0EXTPRIO_DMA (1 << 0) /* Bit 0: DMA has higher priority */ + +/* Pin multiplexing control registers */ +/* SYSCREG_MUX_LCDEBISEL address 0x13002890 */ + +#define SYSCREG_MUX_LCDEBISEL_EBIMPMC (1 << 0) /* Bit 0: Selects between LCD and EBI/MPMC pins */ + +/* SYSCREG_MUX_GPIOMCISEL address 0x13002894 */ + +#define SYSCREG_MUX_GPIOMCISEL_MCI (1 << 0) /* Bit 0: Selects between GPIO and MCI pins */ + +/* SYSCREG_MUX_NANDMCISEL address 0x13002898 */ + +#define SYSCREG_MUX_NANDMCISEL_MCI (1 << 0) /* Bit 0: Selects between NAND and MCI pins */ + +/* SYSCREG_MUX_UARTSPISEL address 0x1300289c */ + +#define SYSCREG_MUX_UARTSPISEL_SPI (1 << 0) /* Bit 0: Selects between SPI and UART pins */ + +/* SYSCREG_MUX_I2STXIPCMSEL address 0x130028a0 */ + +#define SYSCREG_MUX_I2STXPCMSEL_PCM (1 << 0) /* Bit 0: Selects between I2STX_0 and IPINT_1 pins */ + +/* Pad configuration registers */ +/* SYSCREG_PAD_padname addresses 0x130028a4 to 0x13002a28 */ + +#define SYSCREG_PAD_P2 (1 << 1) /* Bit 1: The logic pin p2 of the pad */ +#define SYSCREG_PAD_P1 (1 << 0) /* Bit 0: The logic pin p1 of the pad */ +#define SYSCREG_PAD_PULLUP (0) +#define SYSCREG_PAD_INPUT (SYSCREG_PAD_P2) +#define SYSCREG_PAD_REPEATER (SYSCREG_PAD_P1) +#define SYSCREG_PAD_WEAKPULLUP (SYSCREG_PAD_P1|SYSCREG_PAD_P2) + +/* SYSCREG_ESHCTRLSUP4 address 0x13002a2c */ + +#define SYSCREG_PAD_ESHCTRLSUP4_LESS (1 << 0) /* Bit 0: Domain SUP4 less switching noise */ + +/* SYSCREG_ESHCTRLSUP8 address 0x13002a2c */ + +#define SYSCREG_PAD_ESHCTRLSUP8_LESS (1 << 0) /* Bit 0: Domain SUP8 switching less noise */ +/******************************************************************************************************** + * Public Types + ********************************************************************************************************/ + +/******************************************************************************************************** + * Public Data + ********************************************************************************************************/ + +/******************************************************************************************************** + * Public Functions + ********************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_SYSCREG_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_timer.h b/arch/arm/src/lpc31xx/lpc31_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..b3d580ab6716b391ce2812048290e99a6c436542 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_timer.h @@ -0,0 +1,119 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_timer.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_TIMER_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_TIMER_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* TIMER register base address offset into the APB1 domain **************************************/ + +#define LPC31_TIMER0_VBASE (LPC31_APB1_VADDR+LPC31_APB1_TIMER0_OFFSET) +#define LPC31_TIMER0_PBASE (LPC31_APB1_PADDR+LPC31_APB1_TIMER0_OFFSET) + +#define LPC31_TIMER1_VBASE (LPC31_APB1_VADDR+LPC31_APB1_TIMER1_OFFSET) +#define LPC31_TIMER1_PBASE (LPC31_APB1_PADDR+LPC31_APB1_TIMER1_OFFSET) + +#define LPC31_TIMER2_VBASE (LPC31_APB1_VADDR+LPC31_APB1_TIMER2_OFFSET) +#define LPC31_TIMER2_PBASE (LPC31_APB1_PADDR+LPC31_APB1_TIMER2_OFFSET) + +#define LPC31_TIMER3_VBASE (LPC31_APB1_VADDR+LPC31_APB1_TIMER3_OFFSET) +#define LPC31_TIMER3_PBASE (LPC31_APB1_PADDR+LPC31_APB1_TIMER3_OFFSET) + +/* TIMER register offsets (with respect to the TIMERn base) *************************************/ + +#define LPC31_TIMER_LOAD_OFFSET 0x00 /* Timer reload value */ +#define LPC31_TIMER_VALUE_OFFSET 0x04 /* Current timer value */ +#define LPC31_TIMER_CTRL_OFFSET 0x08 /* Timer nable/disable and pre-scale */ +#define LPC31_TIMER_CLEAR_OFFSET 0x0c /* Clear timer interrupt */ + +/* TIMER register (virtual) addresses ***********************************************************/ + +#define LPC31_TIMER0_LOAD (LPC31_TIMER0_VBASE+LPC31_TIMER_LOAD_OFFSET) +#define LPC31_TIMER0_VALUE (LPC31_TIMER0_VBASE+LPC31_TIMER_VALUE_OFFSET) +#define LPC31_TIMER0_CTRL (LPC31_TIMER0_VBASE+LPC31_TIMER_CTRL_OFFSET) +#define LPC31_TIMER0_CLEAR (LPC31_TIMER0_VBASE+LPC31_TIMER_CLEAR_OFFSET) + +#define LPC31_TIMER1_LOAD (LPC31_TIMER1_VBASE+LPC31_TIMER_LOAD_OFFSET) +#define LPC31_TIMER1_VALUE (LPC31_TIMER1_VBASE+LPC31_TIMER_VALUE_OFFSET) +#define LPC31_TIMER1_CTRL (LPC31_TIMER1_VBASE+LPC31_TIMER_CTRL_OFFSET) +#define LPC31_TIMER1_CLEAR (LPC31_TIMER1_VBASE+LPC31_TIMER_CLEAR_OFFSET) + +#define LPC31_TIMER2_LOAD (LPC31_TIMER2_VBASE+LPC31_TIMER_LOAD_OFFSET) +#define LPC31_TIMER2_VALUE (LPC31_TIMER2_VBASE+LPC31_TIMER_VALUE_OFFSET) +#define LPC31_TIMER2_CTRL (LPC31_TIMER2_VBASE+LPC31_TIMER_CTRL_OFFSET) +#define LPC31_TIMER2_CLEAR (LPC31_TIMER2_VBASE+LPC31_TIMER_CLEAR_OFFSET) + +#define LPC31_TIMER3_LOAD (LPC31_TIMER3_VBASE+LPC31_TIMER_LOAD_OFFSET) +#define LPC31_TIMER3_VALUE (LPC31_TIMER3_VBASE+LPC31_TIMER_VALUE_OFFSET) +#define LPC31_TIMER3_CTRL (LPC31_TIMER3_VBASE+LPC31_TIMER_CTRL_OFFSET) +#define LPC31_TIMER3_CLEAR (LPC31_TIMER3_VBASE+LPC31_TIMER_CLEAR_OFFSET) + +/* TIMER register bit definitions ***************************************************************/ + +/* Timer Control register TIMER0_CTRL, address 0x13008008 TIMER1_CTRL, address 0x13008408 + * TIMER2_CTRL, address 0x13008808 TIMER3_CTRL, adddress 0x13008c08 + */ + +#define TIMER_CTRL_ENABLE (1 << 7) /* Bit 7: Timer enable */ +#define TIMER_CTRL_PERIODIC (1 << 6) /* Bit 6: Periodic timer mode */ +#define TIMER_CTRL_PRESCALE_SHIFT (2) /* Bits 2-3: Timer pre-scale */ +#define TIMER_CTRL_PRESCALE_MASK (3 << TIMER_CTRL_PRESCALE_SHIFT) +# define TIMER_CTRL_PRESCALE_DIV1 (0 << TIMER_CTRL_PRESCALE_SHIFT) /* Divider=1 Stages=0 */ +# define TIMER_CTRL_PRESCALE_DIV16 (1 << TIMER_CTRL_PRESCALE_SHIFT) /* Divider=16 Stages4 */ +# define TIMER_CTRL_PRESCALE_DIV256 (2 << TIMER_CTRL_PRESCALE_SHIFT) /* Divider=256 Stages=8 */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_TIMER_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_timerisr.c b/arch/arm/src/lpc31xx/lpc31_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..a2607f626683bcc13035866d50d1cabfd143ebee --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_timerisr.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "lpc31_timer.h" +#include "lpc31.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Clear the lattched timer interrupt (Writing any value to the CLEAR register + * clears the interrupt generated by the counter timer + */ + + putreg32(1, LPC31_TIMER0_CLEAR); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + uint64_t load; + uint64_t freq; + + /* Enable the timer0 system clock */ + + lpc31_enableclock(CLKID_TIMER0PCLK); + + /* Soft reset the timer0 module so that we start in a known state */ + + lpc31_softreset(RESETID_TIMER0RST); + + /* Set timer load register to 10mS (100Hz). First, get the frequency + * of the timer0 module clock (in the AHB0APB1_BASE domain (2)). + */ + + freq = (uint64_t)lpc31_clkfreq(CLKID_TIMER0PCLK, DOMAINID_AHB0APB1); + + /* If the clock is >1MHz, use pre-dividers */ + + regval = getreg32(LPC31_TIMER0_CTRL); + if (freq > 1000000) + { + /* Use the divide by 16 pre-divider */ + + regval &= ~TIMER_CTRL_PRESCALE_MASK; + regval |= TIMER_CTRL_PRESCALE_DIV16; + freq >>= 4; + } + + load = ((freq * (uint64_t)10000) / 1000000); + putreg32((uint32_t)load, LPC31_TIMER0_LOAD); + + /* Set periodic mode */ + + regval |= TIMER_CTRL_PERIODIC; + putreg32(regval, LPC31_TIMER0_CTRL); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(LPC31_IRQ_TMR0, (xcpt_t)up_timerisr); + + /* Clear any latched timer interrupt (Writing any value to the CLEAR register + * clears the latched interrupt generated by the counter timer) + */ + + putreg32(1, LPC31_TIMER0_CLEAR); + + /* Enable timers (starts counting) */ + + regval |= TIMER_CTRL_ENABLE; + putreg32(regval, LPC31_TIMER0_CTRL); + + /* Enable timer match interrupts in the interrupt controller */ + + up_enable_irq(LPC31_IRQ_TMR0); +} diff --git a/arch/arm/src/lpc31xx/lpc31_uart.h b/arch/arm/src/lpc31xx/lpc31_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..d612e0308e0fcafd806eb6141e3db7711a2d9fda --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_uart.h @@ -0,0 +1,263 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_uart.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_UART_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_UART_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* UART register base address offset into the APB2 domain ***************************************/ + +#define LPC31_UART_VBASE (LPC31_APB2_VSECTION+LPC31_APB2_UART_OFFSET) +#define LPC31_UART_PBASE (LPC31_APB2_PSECTION+LPC31_APB2_UART_OFFSET) + +/* UART register offsets (with respect to the UART base) ****************************************/ + +#define LPC31_UART_RBR_OFFSET 0x000 /* Receiver Buffer Register */ +#define LPC31_UART_THR_OFFSET 0x000 /* Transmitter Holding Register */ +#define LPC31_UART_DLL_OFFSET 0x000 /* Divisor Latch LSB */ +#define LPC31_UART_DLM_OFFSET 0x004 /* Divisor Latch MSB */ +#define LPC31_UART_IER_OFFSET 0x004 /* Interrupt Enable Register */ +#define LPC31_UART_IIR_OFFSET 0x008 /* Interrupt Identification Register */ +#define LPC31_UART_FCR_OFFSET 0x008 /* FIFO Control Register */ +#define LPC31_UART_LCR_OFFSET 0x00c /* Line Control Register */ +#define LPC31_UART_MCR_OFFSET 0x010 /* Modem Control Register */ +#define LPC31_UART_LSR_OFFSET 0x014 /* Line Status Register */ +#define LPC31_UART_MSR_OFFSET 0x018 /* Modem status Register */ +#define LPC31_UART_SCR_OFFSET 0x01c /* Scratch Register */ + /* 0x020: Reserved */ +#define LPC31_UART_ICR_OFFSET 0x024 /* IrDA Control Register */ +#define LPC31_UART_FDR_OFFSET 0x028 /* Fractional Divider Register */ + /* 0x02c: Reserved */ +#define LPC31_UART_POP_OFFSET 0x030 /* NHP Pop Register */ +#define LPC31_UART_MODE_OFFSET 0x034 /* NHP Mode Selection Register */ + /* 0x038-0xfd4: Reserved */ +#define LPC31_UART_INTCE_OFFSET 0xfd8 /* Interrupt Clear Enable Register */ +#define LPC31_UART_INTSE_OFFSET 0xfdc /* Interrupt Set Enable Register */ +#define LPC31_UART_INTS_OFFSET 0xfe0 /* Interrupt Status Register */ +#define LPC31_UART_INTE_OFFSET 0xfe4 /* Interrupt Enable Register */ +#define LPC31_UART_INTCS_OFFSET 0xfe8 /* Interrupt Clear Status Register */ +#define LPC31_UART_INTSS_OFFSET 0xfec /* Interrupt Set Status Register */ + /* 0xff0-0xff8: Reserved */ + +/* UART register (virtual) addresses ************************************************************/ + +#define LPC31_UART_RBR (LPC31_UART_VBASE+LPC31_UART_RBR_OFFSET) +#define LPC31_UART_THR (LPC31_UART_VBASE+LPC31_UART_THR_OFFSET) +#define LPC31_UART_DLL (LPC31_UART_VBASE+LPC31_UART_DLL_OFFSET) +#define LPC31_UART_DLM (LPC31_UART_VBASE+LPC31_UART_DLM_OFFSET) +#define LPC31_UART_IER (LPC31_UART_VBASE+LPC31_UART_IER_OFFSET) +#define LPC31_UART_IIR (LPC31_UART_VBASE+LPC31_UART_IIR_OFFSET) +#define LPC31_UART_FCR (LPC31_UART_VBASE+LPC31_UART_FCR_OFFSET) +#define LPC31_UART_LCR (LPC31_UART_VBASE+LPC31_UART_LCR_OFFSET) +#define LPC31_UART_MCR (LPC31_UART_VBASE+LPC31_UART_MCR_OFFSET) +#define LPC31_UART_LSR (LPC31_UART_VBASE+LPC31_UART_LSR_OFFSET) +#define LPC31_UART_MSR (LPC31_UART_VBASE+LPC31_UART_MSR_OFFSET) +#define LPC31_UART_SCR (LPC31_UART_VBASE+LPC31_UART_SCR_OFFSET) +#define LPC31_UART_ICR (LPC31_UART_VBASE+LPC31_UART_ICR_OFFSET) +#define LPC31_UART_FDR (LPC31_UART_VBASE+LPC31_UART_FDR_OFFSET) +#define LPC31_UART_POP (LPC31_UART_VBASE+LPC31_UART_POP_OFFSET) +#define LPC31_UART_MODE (LPC31_UART_VBASE+LPC31_UART_MODE_OFFSET) +#define LPC31_UART_INTCE (LPC31_UART_VBASE+LPC31_UART_INTCE_OFFSET) +#define LPC31_UART_INTSE (LPC31_UART_VBASE+LPC31_UART_INTSE_OFFSET) +#define LPC31_UART_INTS (LPC31_UART_VBASE+LPC31_UART_INTS_OFFSET) +#define LPC31_UART_INTE (LPC31_UART_VBASE+LPC31_UART_INTE_OFFSET) +#define LPC31_UART_INTCS (LPC31_UART_VBASE+LPC31_UART_INTCS_OFFSET) +#define LPC31_UART_INTSS (LPC31_UART_VBASE+LPC31_UART_INTSS_OFFSET) + +/* UART register bit definitions ****************************************************************/ +/* Receive Buffer Register RBR, address 0x15001000 */ + +#define UART_RBR_SHIFT (0) /* Bits 0-7 */ +#define UART_RBR_MASK (0xff << UART_RBR_SHIFT) + +/* Transmitter Holding Register THR, address 0x15001000 */ + +#define UART_THR_SHIFT (0) /* Bits 0-7 */ +#define UART_THR_MASK (0xff << UART_THR_SHIFT) + +/* Divisor register Latch LSB DLL, address 0x15001000 */ + +#define UART_DLL_SHIFT (0) /* Bits 0-7 */ +#define UART_DLL_MASK (0xff << UART_DLL_SHIFT) + +/* Divisor latch register MSB DLM, address 0x15001004 */ + +#define UART_DLM_SHIFT (0) /* Bits 0-7 */ +#define UART_DLM_MASK (0xff << UART_DLM_SHIFT) + +/* Interrupt Enable Register IER, address 0x15001004 */ + +#define UART_IER_CTSINTEN (1 << 7) /* Bit 7: Enable modem status interrupt on CTS transition */ +#define UART_IER_MSINTEN (1 << 3) /* Bit 3: Enable Modem Status interrupt */ +#define UART_IER_RLSINTEN (1 << 2) /* Bit 2: Receiver Line Status interrupt enable */ +#define UART_IER_THREINTEN (1 << 1) /* Bit 1: Transmitter Holding Register Empty interrupt enable */ +#define UART_IER_RDAINTEN (1 << 0) /* Bit 0: Receive Data Available interrupt enable */ +#define UART_IER_ALLINTS (0x1f) + +/* Interrupt Identification Register IIR, address 0x15001008 */ + +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: Copies of FCR[0] */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MS (0 << UART_IIR_INTID_SHIFT) /* Modem status */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* Transmitter Holding Register empty */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* Received Data Available */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* Receiver Line Status */ +# define UART_IIR_INTID_TIMEOUT (6 << UART_IIR_INTID_SHIFT) /* Character time-out */ +#define UART_IIR_NOINT (1 << 0) /* Bit 0: Interrupt status, 1=no interrupt */ + +/* FIFO Control Register FCR, address 0x15001008 */ + +#define UART_FCR_RXTRIGLEVEL_SHIFT (6) /* Bits 6-7: 7:6 Receiver trigger level selection */ +#define UART_FCR_RXTRIGLEVEL_MASK (3 << UART_FCR_RXTRIGLEVEL_SHIFT) +# define UART_FCR_RXTRIGLEVEL_1 (0 << UART_FCR_RXTRIGLEVEL_SHIFT) /* Rx trigger at character 1 */ +# define UART_FCR_RXTRIGLEVEL_16 (1 << UART_FCR_RXTRIGLEVEL_SHIFT) /* Rx trigger at character 16 */ +# define UART_FCR_RXTRIGLEVEL_32 (2 << UART_FCR_RXTRIGLEVEL_SHIFT) /* Rx trigger at character 32 */ +# define UART_FCR_RXTRIGLEVEL_56 (3 << UART_FCR_RXTRIGLEVEL_SHIFT) /* Rx trigger at character 56 */ +#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA mode select */ +#define UART_FCR_TXFIFORST (1 << 2) /* Bit 2: Transmitter FIFO reset */ +#define UART_FCR_RXFIFORST (1 << 1) /* Bit 1: Receiver FIFO reset */ +#define UART_FCR_FIFOENABLE (1 << 0) /* Bit 0: Transmit and receive FIFO enable */ + +/* Line Control Register LCR, address 0x1500100c */ + +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access bit */ +#define UART_LCR_BRKCTRL (1 << 6) /* Bit 6: Break control bit */ +#define UART_LCR_PARSTICK (1 << 5) /* Bit 5: Enable sticky parity mode */ +#define UART_LCR_PAREVEN (1 << 4) /* Bit 4: Select even parity */ +#define UART_LCR_PAREN (1 << 3) /* Bit 3: Parity enable */ +#define UART_LCR_NSTOPBITS (1 << 2) /* Bit 2: Number of stop bits selector */ +#define UART_LCR_WDLENSEL_SHIFT (0) /* Bits 0-1: Word length selector */ +#define UART_LCR_WDLENSEL_MASK (3 << UART_LCR_WDLENSEL_SHIFT) +# define UART_LCR_WDLENSEL_5BITS (0 << UART_LCR_WDLENSEL_SHIFT) /* Char length=5 stopbits=1 or 1.5*/ +# define UART_LCR_WDLENSEL_6BITS (1 << UART_LCR_WDLENSEL_SHIFT) /* Char length=6 stopbits=1 or 2 */ +# define UART_LCR_WDLENSEL_7BITS (2 << UART_LCR_WDLENSEL_SHIFT) /* Char length=7 stopbits=1 or 2 */ +# define UART_LCR_WDLENSEL_8BITS (3 << UART_LCR_WDLENSEL_SHIFT) /* Char length=8 stopbits=1 or 2 */ + +/* Modem Control Register MCR, address 0x15001010 */ + +#define UART_MCR_AUTOCTSEN (1 << 7) /* Bit 7: Auto-cts flow control enable */ +#define UART_MCR_AUTORTSEN (1 << 6) /* Bit 6: Auto-rts flow control enable */ +#define UART_MCR_LOOPEN (1 << 4) /* Bit 4: Loop-back mode enable */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Request To Send */ + +/* Line Status Register LSR, address 0x15001014 */ + +#define UART_LSR_RXER (1 << 7) /* Bit 7: Error in receiver FIFO */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter empty (TSR and THR) */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register empty */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break indication */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity error */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun error */ +#define UART_LSR_RDR (1 << 0) /* Bit 0: Read Data ready */ + +/* Modem Status Register MSR, address 0x15001018 */ + +#define UART_MSR_CTS (1 << 4) /* Bit 4: CTS is modem flow control signal */ +#define UART_MSR_DCTS (1 << 0) /* Bit 0: Delta Clear To Send */ + +/* Scratch Register SCR, address 0x1500101c */ + +#define UART_SCR_SCRVAL_SHIFT (0) /* Bits 0-7: Scratch Value */ +#define UART_SCR_SCRVAL_MASK (0xff << bb) + +/* IrDA Control Register ICR, address 0x15001024 */ + +#define UART_ICR_PULSEDIV_SHIFT (3) /* Bits 3-5: Configures fixed pulse width mode */ +#define UART_ICR_PULSEDIV_MASK (7 << UART_ICR_PULSEDIV_SHIFT) +#define UART_ICR_FIXPULSEEN (1 << 2) /* Bit 2: Enables IrDA fixed pulse width mode */ +#define UART_ICR_IRDAINV (1 << 1) /* Bit 1: Serial input is inverted */ +#define UART_ICR_IRDAEN (1 << 0) /* Bit 0: Enable IrDA */ + +/* Fractional Divider Register FDR, address 0x15001028 */ + +#define UART_FDR_MULVAL_SHIFT (4) /* Bits 4-7: Baud pre-scaler multiplier value */ +#define UART_FDR_MULVAL_MASK (15 << UART_FDR_MULVAL_SHIFT) +#define UART_FDR_DIVADDVAL_SHIFT (0) /* Bits 0-3: Baud pre-scaler divisor value */ +#define UART_FDR_DIVADDVAL_MASK (15 << UART_FDR_DIVADDVAL_SHIFT) + +/* NHP POP Register POP, address 0x15001030 */ + +#define UART_POP_POPRBR (1 << 0) /* Bit 0: Pop from RBR as if RBR read in non-NHP mode */ + +/* Mode Selection Register MODE, 0x15001034 */ + +#define UART_MODE_NHP (1 << 0) /* Bit 0: Enable UART NHP mode */ + +/* Interrupt Clear Enable Register INTCE, address 0x15001fd8 + * Interrupt Set Enable Register INTSE, address 0x15001fdc + * Interrupt Status Register INTS, address 0x15001fe0 + * Interrupt Enable Register INTE, address 0x15001fe4 + * Interrupt Clear Status Register INTCS, address 0x15001fe8 + * Interrupt Set Status Register INTSS, address 0x15001fec + */ + +#define UART_OEINT (1 << 15) /* Bit 15: Overrun Error Interrupt */ +#define UART_PEINT (1 << 14) /* Bit 14: Parity Error Interrupt (not INTSS) */ +#define UART_FEINT (1 << 13) /* Bit 13: Frame Error Interrupt (not INTSS) */ +#define UART_BIINT (1 << 12) /* Bit 12: Break Indication Interrupt (not INTSS) */ +#define UART_ABTOINT (1 << 9) /* Bit 9: Auto-Baud Time-Out Interrupt */ +#define UART_ABEOINT (1 << 8) /* Bit 8: End of Auto-Baud Interrupt */ +#define UART_RXDAINT (1 << 6) /* Bit 6: Receiver Data Available Interrupt (not INTSS) */ +#define UART_RXTOINT (1 << 5) /* Bit 5: Receiver Time-Out Interrupt (not INTCE) */ +#define UART_THREINT (1 << 4) /* Bit 4: Transmitter Holding Register Empty Interrupt */ +#define UART_DCTSINT (1 << 0) /* Bit 0: Delta Clear To Send Interrupt */ + + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_UART_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_usbdev.c b/arch/arm/src/lpc31xx/lpc31_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..c1ece00bf6f37f36e4293690ca5bfcb640f5d61e --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_usbdev.c @@ -0,0 +1,2739 @@ +/**************************************************************************** + * arch/arm/src/lpc31xx/lpc31_usbdev.c + * + * Authors: David Hewson + * Gregory Nutt + * + * Part of the NuttX OS and based, in part, on the LPC2148 USB driver: + * + * Copyright (C) 2010-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc31_usbotg.h" +#include "lpc31_evntrtr.h" +#include "lpc31_syscreg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ + +#ifndef CONFIG_LPC31_USBDEV_EP0_MAXSIZE +# define CONFIG_LPC31_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#undef CONFIG_LPC31_USBDEV_REGDEBUG + +/* Enable reading SOF from interrupt handler vs. simply reading on demand. Probably + * a bad idea... Unless there is some issue with sampling the SOF from hardware + * asynchronously. + */ + +#ifdef CONFIG_LPC31_USBDEV_FRAME_INTERRUPT +# define USB_FRAME_INT USBDEV_USBINTR_SRE +#else +# define USB_FRAME_INT 0 +#endif + +#ifdef CONFIG_DEBUG +# define USB_ERROR_INT USBDEV_USBINTR_UEE +#else +# define USB_ERROR_INT 0 +#endif + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define LPC31_TRACEERR_ALLOCFAIL 0x0001 +#define LPC31_TRACEERR_BADCLEARFEATURE 0x0002 +#define LPC31_TRACEERR_BADDEVGETSTATUS 0x0003 +#define LPC31_TRACEERR_BADEPNO 0x0004 +#define LPC31_TRACEERR_BADEPGETSTATUS 0x0005 +#define LPC31_TRACEERR_BADEPTYPE 0x0006 +#define LPC31_TRACEERR_BADGETCONFIG 0x0007 +#define LPC31_TRACEERR_BADGETSETDESC 0x0008 +#define LPC31_TRACEERR_BADGETSTATUS 0x0009 +#define LPC31_TRACEERR_BADSETADDRESS 0x000a +#define LPC31_TRACEERR_BADSETCONFIG 0x000b +#define LPC31_TRACEERR_BADSETFEATURE 0x000c +#define LPC31_TRACEERR_BINDFAILED 0x000d +#define LPC31_TRACEERR_DISPATCHSTALL 0x000e +#define LPC31_TRACEERR_DRIVER 0x000f +#define LPC31_TRACEERR_DRIVERREGISTERED 0x0010 +#define LPC31_TRACEERR_EP0SETUPSTALLED 0x0011 +#define LPC31_TRACEERR_EPINNULLPACKET 0x0012 +#define LPC31_TRACEERR_EPOUTNULLPACKET 0x0013 +#define LPC31_TRACEERR_INVALIDCTRLREQ 0x0014 +#define LPC31_TRACEERR_INVALIDPARMS 0x0015 +#define LPC31_TRACEERR_IRQREGISTRATION 0x0016 +#define LPC31_TRACEERR_NOEP 0x0017 +#define LPC31_TRACEERR_NOTCONFIGURED 0x0018 +#define LPC31_TRACEERR_REQABORTED 0x0019 + +/* Trace interrupt codes */ + +#define LPC31_TRACEINTID_USB 0x0001 +#define LPC31_TRACEINTID_CLEARFEATURE 0x0002 +#define LPC31_TRACEINTID_DEVGETSTATUS 0x0003 +#define LPC31_TRACEINTID_DEVRESET 0x0004 +#define LPC31_TRACEINTID_DISPATCH 0x0005 +#define LPC31_TRACEINTID_EP0COMPLETE 0x0006 +#define LPC31_TRACEINTID_EP0NAK 0x0007 +#define LPC31_TRACEINTID_EP0SETUP 0x0008 +#define LPC31_TRACEINTID_EPGETSTATUS 0x0009 +#define LPC31_TRACEINTID_EPIN 0x000a +#define LPC31_TRACEINTID_EPINQEMPTY 0x000b +#define LPC31_TRACEINTID_EP0INSETADDRESS 0x000c +#define LPC31_TRACEINTID_EPOUT 0x000d +#define LPC31_TRACEINTID_EPOUTQEMPTY 0x000e +#define LPC31_TRACEINTID_EP0SETUPSETADDRESS 0x000f +#define LPC31_TRACEINTID_FRAME 0x0010 +#define LPC31_TRACEINTID_GETCONFIG 0x0011 +#define LPC31_TRACEINTID_GETSETDESC 0x0012 +#define LPC31_TRACEINTID_GETSETIF 0x0013 +#define LPC31_TRACEINTID_GETSTATUS 0x0014 +#define LPC31_TRACEINTID_IFGETSTATUS 0x0015 +#define LPC31_TRACEINTID_SETCONFIG 0x0016 +#define LPC31_TRACEINTID_SETFEATURE 0x0017 +#define LPC31_TRACEINTID_SUSPENDED 0x0018 +#define LPC31_TRACEINTID_RESUMED 0x0019 +#define LPC31_TRACEINTID_SYNCHFRAME 0x001a + +/* Hardware interface **********************************************************/ + +/* This represents a Endpoint Transfer Descriptor - note these must be 32 byte + * aligned + */ + +struct lpc31_dtd_s +{ + volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */ + volatile uint32_t config; /* Misc. bit encoded configuration information */ + uint32_t buffer0; /* Buffer start address */ + uint32_t buffer1; /* Buffer start address */ + uint32_t buffer2; /* Buffer start address */ + uint32_t buffer3; /* Buffer start address */ + uint32_t buffer4; /* Buffer start address */ + uint32_t xfer_len; /* Software only - transfer len that was queued */ +}; + +/* DTD nextdesc field */ + +#define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid */ + +/* DTD config field */ +#define DTD_CONFIG_LENGTH(n) ((n) << 16) /* Bits 16-31 : Total bytes to transfer */ +#define DTD_CONFIG_IOC (1 << 15) /* Bit 15 : Interrupt on Completion */ +#define DTD_CONFIG_MULT_VARIABLE (0 << 10) /* Bits 10-11 : Number of packets executed per transacation descriptor (override) */ +#define DTD_CONFIG_MULT_NUM(n) ((n) << 10) +#define DTD_CONFIG_ACTIVE (1 << 7) /* Bit 7 : Status Active */ +#define DTD_CONFIG_HALTED (1 << 6) /* Bit 6 : Status Halted */ +#define DTD_CONFIG_BUFFER_ERROR (1 << 5) /* Bit 6 : Status Buffer Error */ +#define DTD_CONFIG_TRANSACTION_ERROR (1 << 3) /* Bit 3 : Status Transaction Error */ + +/* This represents a queue head - not these must be aligned to a 2048 byte boundary */ +struct lpc31_dqh_s +{ + uint32_t capability; /* Endpoint capability */ + uint32_t currdesc; /* Current dTD pointer */ + struct lpc31_dtd_s overlay; /* DTD overlay */ + volatile uint32_t setup[2]; /* Set-up buffer */ + uint32_t gap[4]; /* align to 64 bytes */ +}; + +/* DQH capability field */ +#define DQH_CAPABILITY_MULT_VARIABLE (0 << 30) /* Bits 30-31 : Number of packets executed per transaction descriptor */ +#define DQH_CAPABILITY_MULT_NUM(n) ((n) << 30) +#define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */ +#define DQH_CAPABILITY_MAX_PACKET(n) ((n) << 16) /* Bits 16-29 : Maximum packet size of associated endpoint (<1024) */ +#define DQH_CAPABILITY_IOS (1 << 15) /* Bit 15 : Interrupt on Setup */ + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ +#define LPC31_NLOGENDPOINTS (4) /* ep0-3 */ +#define LPC31_NPHYSENDPOINTS (8) /* x2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ +#define LPC31_EPPHYIN(epphy) (((epphy)&1)!=0) +#define LPC31_EPPHYOUT(epphy) (((epphy)&1)==0) + +#define LPC31_EPPHYIN2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_IN) +#define LPC31_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy)>>1)|USB_DIR_OUT) + +/* Endpoint 0 is special... */ +#define LPC31_EP0_OUT (0) +#define LPC31_EP0_IN (1) + +/* Each endpoint has somewhat different characteristics */ +#define LPC31_EPALLSET (0xff) /* All endpoints */ +#define LPC31_EPOUTSET (0x55) /* Even phy endpoint numbers are OUT EPs */ +#define LPC31_EPINSET (0xaa) /* Odd endpoint numbers are IN EPs */ +#define LPC31_EPCTRLSET (0x03) /* EP0 IN/OUT are control endpoints */ +#define LPC31_EPINTRSET (0xa8) /* Interrupt endpoints */ +#define LPC31_EPBULKSET (0xfc) /* Bulk endpoints */ +#define LPC31_EPISOCSET (0xfc) /* Isochronous endpoints */ + +/* Maximum packet sizes for endpoints */ +#define LPC31_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ +#define LPC31_BULKMAXPACKET (512) /* Bulk endpoint max packet (8/16/32/64/512) */ +#define LPC31_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */ +#define LPC31_ISOCMAXPACKET (512) /* Acutally 1..1023 */ + +/* The address of the endpoint control register */ +#define LPC31_USBDEV_ENDPTCTRL(epphy) (LPC31_USBDEV_ENDPTCTRL0 + ((epphy)>>1)*4) + +/* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE registers */ +#define LPC31_ENDPTSHIFT(epphy) (LPC31_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1)) +#define LPC31_ENDPTMASK(epphy) (1 << LPC31_ENDPTSHIFT(epphy)) +#define LPC31_ENDPTMASK_ALL 0x000f000f + +/* Request queue operations ****************************************************/ + +#define lpc31_rqempty(ep) ((ep)->head == NULL) +#define lpc31_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request may be retained in a list */ + +struct lpc31_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct lpc31_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct lpc31_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct lpc31_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* LPC31XX-specific fields */ + + struct lpc31_usbdev_s *dev; /* Reference to private driver data */ + struct lpc31_req_s *head; /* Request list for this endpoint */ + struct lpc31_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ +}; + +/* This structure retains the state of the USB device controller */ + +struct lpc31_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct lpc31_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* LPC31XX-specific fields */ + + uint8_t ep0state; /* State of certain EP0 operations */ + uint8_t ep0buf[64]; /* buffer for EP0 short transfers */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t suspended:1; /* 1: Suspended */ + uint32_t softprio; /* Bitset of high priority interrupts */ + uint32_t epavail; /* Bitset of available endpoints */ +#ifdef CONFIG_LPC31_USBDEV_FRAME_INTERRUPT + uint32_t sof; /* Last start-of-frame */ +#endif + + /* The endpoint list */ + struct lpc31_ep_s eplist[LPC31_NPHYSENDPOINTS]; +}; + +#define EP0STATE_IDLE 0 /* Idle State, leave on receiving a setup packet or epsubmit */ +#define EP0STATE_SETUP_OUT 1 /* Setup Packet received - SET/CLEAR */ +#define EP0STATE_SETUP_IN 2 /* Setup Packet received - GET */ +#define EP0STATE_SHORTWRITE 3 /* Short write without a usb_request */ +#define EP0STATE_WAIT_NAK_OUT 4 /* Waiting for Host to illicit status phase (GET) */ +#define EP0STATE_WAIT_NAK_IN 5 /* Waiting for Host to illicit status phase (SET/CLEAR) */ +#define EP0STATE_WAIT_STATUS_OUT 6 /* Wait for status phase to complete */ +#define EP0STATE_WAIT_STATUS_IN 7 /* Wait for status phase to complete */ +#define EP0STATE_DATA_IN 8 +#define EP0STATE_DATA_OUT 9 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_LPC31_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc31_getreg(uint32_t addr); +static void lpc31_putreg(uint32_t val, uint32_t addr); +#else +# define lpc31_getreg(addr) getreg32(addr) +# define lpc31_putreg(val,addr) putreg32(val,addr) +#endif + +static inline void lpc31_clrbits(uint32_t mask, uint32_t addr); +static inline void lpc31_setbits(uint32_t mask, uint32_t addr); +static inline void lpc31_chgbits(uint32_t mask, uint32_t val, uint32_t addr); + +/* Request queue operations ****************************************************/ + +static FAR struct lpc31_req_s *lpc31_rqdequeue(FAR struct lpc31_ep_s *privep); +static bool lpc31_rqenqueue(FAR struct lpc31_ep_s *privep, + FAR struct lpc31_req_s *req); + +/* Low level data transfers and request operations *****************************/ + +static inline void lpc31_writedtd(struct lpc31_dtd_s *dtd, const uint8_t *data, + uint32_t nbytes); +static inline void lpc31_queuedtd(uint8_t epphy, struct lpc31_dtd_s *dtd); +static inline void lpc31_ep0xfer(uint8_t epphy, uint8_t *data, uint32_t nbytes); +static void lpc31_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl); + +static inline void lpc31_set_address(struct lpc31_usbdev_s *priv, uint16_t address); + +static void lpc31_flushep(struct lpc31_ep_s *privep); + +static int lpc31_progressep(struct lpc31_ep_s *privep); +static inline void lpc31_abortrequest(struct lpc31_ep_s *privep, + struct lpc31_req_s *privreq, int16_t result); +static void lpc31_reqcomplete(struct lpc31_ep_s *privep, + struct lpc31_req_s *privreq, int16_t result); + +static void lpc31_cancelrequests(struct lpc31_ep_s *privep, int16_t status); + +/* Interrupt handling **********************************************************/ +static struct lpc31_ep_s *lpc31_epfindbyaddr(struct lpc31_usbdev_s *priv, + uint16_t eplog); +static void lpc31_dispatchrequest(struct lpc31_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static void lpc31_ep0configure(struct lpc31_usbdev_s *priv); +static void lpc31_usbreset(struct lpc31_usbdev_s *priv); + +static inline void lpc31_ep0state(struct lpc31_usbdev_s *priv, uint16_t state); +static void lpc31_ep0setup(struct lpc31_usbdev_s *priv); + +static void lpc31_ep0complete(struct lpc31_usbdev_s *priv, uint8_t epphy); +static void lpc31_ep0nak(struct lpc31_usbdev_s *priv, uint8_t epphy); +static bool lpc31_epcomplete(struct lpc31_usbdev_s *priv, uint8_t epphy); + +static int lpc31_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ + +/* USB device controller operations ********************************************/ + +static int lpc31_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int lpc31_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *lpc31_epallocreq(FAR struct usbdev_ep_s *ep); +static void lpc31_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *lpc31_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void lpc31_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif +static int lpc31_epsubmit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc31_epcancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc31_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +static FAR struct usbdev_ep_s *lpc31_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void lpc31_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int lpc31_getframe(struct usbdev_s *dev); +static int lpc31_wakeup(struct usbdev_s *dev); +static int lpc31_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int lpc31_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct lpc31_usbdev_s g_usbdev; + +static struct lpc31_dqh_s __attribute__((aligned(2048))) g_qh[LPC31_NPHYSENDPOINTS]; +static struct lpc31_dtd_s __attribute__((aligned(32))) g_td[LPC31_NPHYSENDPOINTS]; + +static const struct usbdev_epops_s g_epops = +{ + .configure = lpc31_epconfigure, + .disable = lpc31_epdisable, + .allocreq = lpc31_epallocreq, + .freereq = lpc31_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = lpc31_epallocbuffer, + .freebuffer = lpc31_epfreebuffer, +#endif + .submit = lpc31_epsubmit, + .cancel = lpc31_epcancel, + .stall = lpc31_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = lpc31_allocep, + .freeep = lpc31_freeep, + .getframe = lpc31_getframe, + .wakeup = lpc31_wakeup, + .selfpowered = lpc31_selfpowered, + .pullup = lpc31_pullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_getreg + * + * Description: + * Get the contents of an LPC313x register + * + ****************************************************************************/ + +#if defined(CONFIG_LPC31_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc31_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc31_putreg + * + * Description: + * Set the contents of an LPC313x register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_LPC31_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void lpc31_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc31_clrbits + * + * Description: + * Clear bits in a register + * + ****************************************************************************/ + +static inline void lpc31_clrbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = lpc31_getreg(addr); + reg &= ~mask; + lpc31_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc31_setbits + * + * Description: + * Set bits in a register + * + ****************************************************************************/ + +static inline void lpc31_setbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = lpc31_getreg(addr); + reg |= mask; + lpc31_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc31_chgbits + * + * Description: + * Change bits in a register + * + ****************************************************************************/ + +static inline void lpc31_chgbits(uint32_t mask, uint32_t val, uint32_t addr) +{ + uint32_t reg = lpc31_getreg(addr); + reg &= ~mask; + reg |= val; + lpc31_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc31_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct lpc31_req_s *lpc31_rqdequeue(FAR struct lpc31_ep_s *privep) +{ + FAR struct lpc31_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc31_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static bool lpc31_rqenqueue(FAR struct lpc31_ep_s *privep, + FAR struct lpc31_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + return is_empty; +} + +/**************************************************************************** + * Name: lpc31_writedtd + * + * Description: + * Initialise a DTD to transfer the data + * + ****************************************************************************/ + +static inline void lpc31_writedtd(struct lpc31_dtd_s *dtd, const uint8_t *data, uint32_t nbytes) +{ + dtd->nextdesc = DTD_NEXTDESC_INVALID; + dtd->config = DTD_CONFIG_LENGTH(nbytes) | DTD_CONFIG_IOC | DTD_CONFIG_ACTIVE; + dtd->buffer0 = ((uint32_t) data); + dtd->buffer1 = (((uint32_t) data) + 0x1000) & 0xfffff000; + dtd->buffer2 = (((uint32_t) data) + 0x2000) & 0xfffff000; + dtd->buffer3 = (((uint32_t) data) + 0x3000) & 0xfffff000; + dtd->buffer4 = (((uint32_t) data) + 0x4000) & 0xfffff000; + dtd->xfer_len = nbytes; +} + +/**************************************************************************** + * Name: lpc31_queuedtd + * + * Description: + * Add the DTD to the device list + * + ****************************************************************************/ + +static void lpc31_queuedtd(uint8_t epphy, struct lpc31_dtd_s *dtd) +{ + /* Queue the DTD onto the Endpoint */ + /* NOTE - this only works when no DTD is currently queued */ + + g_qh[epphy].overlay.nextdesc = (uint32_t) dtd; + g_qh[epphy].overlay.config &= ~(DTD_CONFIG_ACTIVE | DTD_CONFIG_HALTED); + + uint32_t bit = LPC31_ENDPTMASK(epphy); + + lpc31_setbits (bit, LPC31_USBDEV_ENDPTPRIME); + + while (lpc31_getreg (LPC31_USBDEV_ENDPTPRIME) & bit) + ; +} + +/**************************************************************************** + * Name: lpc31_ep0xfer + * + * Description: + * Schedule a short transfer for Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static inline void lpc31_ep0xfer(uint8_t epphy, uint8_t *buf, uint32_t nbytes) +{ + struct lpc31_dtd_s *dtd = &g_td[epphy]; + + lpc31_writedtd(dtd, buf, nbytes); + + lpc31_queuedtd(epphy, dtd); +} + +/**************************************************************************** + * Name: lpc31_readsetup + * + * Description: + * Read a Setup packet from the DTD. + * + ****************************************************************************/ + +static void lpc31_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl) +{ + struct lpc31_dqh_s *dqh = &g_qh[epphy]; + int i; + + do + { + /* Set the trip wire */ + + lpc31_setbits(USBDEV_USBCMD_SUTW, LPC31_USBDEV_USBCMD); + + /* copy the request... */ + + for (i = 0; i < 8; i++) + { + ((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i]; + } + } + while (!(lpc31_getreg(LPC31_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW)); + + /* Clear the trip wire */ + + lpc31_clrbits(USBDEV_USBCMD_SUTW, LPC31_USBDEV_USBCMD); + + /* Clear the Setup Interrupt */ + + lpc31_putreg (LPC31_ENDPTMASK(LPC31_EP0_OUT), LPC31_USBDEV_ENDPTSETUPSTAT); +} + +/**************************************************************************** + * Name: lpc31_set_address + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static inline void lpc31_set_address(struct lpc31_usbdev_s *priv, uint16_t address) +{ + priv->paddr = address; + priv->paddrset = address != 0; + + lpc31_chgbits(USBDEV_DEVICEADDR_MASK, priv->paddr << USBDEV_DEVICEADDR_SHIFT, + LPC31_USBDEV_DEVICEADDR); +} + +/**************************************************************************** + * Name: lpc31_flushep + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void lpc31_flushep(struct lpc31_ep_s *privep) +{ + uint32_t mask = LPC31_ENDPTMASK(privep->epphy); + do + { + lpc31_putreg (mask, LPC31_USBDEV_ENDPTFLUSH); + while ((lpc31_getreg(LPC31_USBDEV_ENDPTFLUSH) & mask) != 0) + ; + } + while ((lpc31_getreg(LPC31_USBDEV_ENDPTSTATUS) & mask) != 0); +} + + +/**************************************************************************** + * Name: lpc31_progressep + * + * Description: + * Progress the Endpoint by priming the first request into the queue head + * + ****************************************************************************/ + +static int lpc31_progressep(struct lpc31_ep_s *privep) +{ + struct lpc31_dtd_s *dtd = &g_td[privep->epphy]; + struct lpc31_req_s *privreq; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc31_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPINQEMPTY), 0); + return OK; + } + + /* Ignore any attempt to send a zero length packet */ + + if (privreq->req.len == 0) + { + /* If the class driver is responding to a setup packet, then wait for the + * host to illicit thr response */ + + if (privep->epphy == LPC31_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT) + { + lpc31_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN); + } + else + { + if (LPC31_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_EPINNULLPACKET), 0); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_EPOUTNULLPACKET), 0); + } + } + + lpc31_reqcomplete(privep, lpc31_rqdequeue(privep), OK); + return OK; + } + + if (privep->epphy == LPC31_EP0_IN) + lpc31_ep0state (privep->dev, EP0STATE_DATA_IN); + else if (privep->epphy == LPC31_EP0_OUT) + lpc31_ep0state (privep->dev, EP0STATE_DATA_OUT); + + int bytesleft = privreq->req.len - privreq->req.xfrd; + + if (LPC31_EPPHYIN(privep->epphy)) + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + else + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + + /* Initialise the DTD to transfer the next chunk */ + + lpc31_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft); + + /* then queue onto the DQH */ + lpc31_queuedtd(privep->epphy, dtd); + + return OK; +} + +/**************************************************************************** + * Name: lpc31_abortrequest + * + * Description: + * Discard a request + * + ****************************************************************************/ + +static inline void lpc31_abortrequest(struct lpc31_ep_s *privep, + struct lpc31_req_s *privreq, + int16_t result) +{ + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_REQABORTED), (uint16_t)privep->epphy); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: lpc31_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void lpc31_reqcomplete(struct lpc31_ep_s *privep, + struct lpc31_req_s *privreq, int16_t result) +{ + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == LPC31_EP0_IN) + privep->stalled = privep->dev->stalled; + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: lpc31_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void lpc31_cancelrequests(struct lpc31_ep_s *privep, int16_t status) +{ + if (!lpc31_rqempty(privep)) + { + lpc31_flushep(privep); + } + + while (!lpc31_rqempty(privep)) + { + /* FIXME: the entry at the head should be sync'd with the DTD + * FIXME: only report the error status if the transfer hasn't completed + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), + (lpc31_rqpeek(privep))->req.xfrd); + lpc31_reqcomplete(privep, lpc31_rqdequeue(privep), status); + } +} + +/**************************************************************************** + * Name: lpc31_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct lpc31_ep_s *lpc31_epfindbyaddr(struct lpc31_usbdev_s *priv, + uint16_t eplog) +{ + struct lpc31_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < LPC31_NPHYSENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: lpc31_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static void lpc31_dispatchrequest(struct lpc31_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, NULL, 0); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } +} + +/**************************************************************************** + * Name: lpc31_ep0configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc31_ep0configure(struct lpc31_usbdev_s *priv) +{ + /* Enable ep0 IN and ep0 OUT */ + g_qh[LPC31_EP0_OUT].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_LPC31_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | + DQH_CAPABILITY_ZLT); + + g_qh[LPC31_EP0_IN].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_LPC31_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | + DQH_CAPABILITY_ZLT); + + g_qh[LPC31_EP0_OUT].currdesc = DTD_NEXTDESC_INVALID; + g_qh[LPC31_EP0_IN].currdesc = DTD_NEXTDESC_INVALID; + + /* Enable EP0 */ + lpc31_setbits (USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE, LPC31_USBDEV_ENDPTCTRL0); +} + +/**************************************************************************** + * Name: lpc31_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc31_usbreset(struct lpc31_usbdev_s *priv) +{ + int epphy; + + /* Disable all endpoints */ + + lpc31_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL0); + lpc31_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL1); + lpc31_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL2); + lpc31_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL3); + + /* Clear all pending interrupts */ + + lpc31_putreg (lpc31_getreg(LPC31_USBDEV_ENDPTNAK), LPC31_USBDEV_ENDPTNAK); + lpc31_putreg (lpc31_getreg(LPC31_USBDEV_ENDPTSETUPSTAT), LPC31_USBDEV_ENDPTSETUPSTAT); + lpc31_putreg (lpc31_getreg(LPC31_USBDEV_ENDPTCOMPLETE), LPC31_USBDEV_ENDPTCOMPLETE); + + /* Wait for all prime operations to have completed and then flush all DTDs */ + while (lpc31_getreg (LPC31_USBDEV_ENDPTPRIME) != 0) + ; + lpc31_putreg (LPC31_ENDPTMASK_ALL, LPC31_USBDEV_ENDPTFLUSH); + while (lpc31_getreg (LPC31_USBDEV_ENDPTFLUSH)) + ; + + /* Reset endpoints */ + for (epphy = 0; epphy < LPC31_NPHYSENDPOINTS; epphy++) + { + struct lpc31_ep_s *privep = &priv->eplist[epphy]; + + lpc31_cancelrequests (privep, -ESHUTDOWN); + + /* Reset endpoint status */ + privep->stalled = false; + } + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Set the interrupt Threshold control interval to 0 */ + lpc31_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC31_USBDEV_USBCMD); + + /* Zero out the Endpoint queue heads */ + memset ((void *) g_qh, 0, sizeof (g_qh)); + memset ((void *) g_td, 0, sizeof (g_td)); + + /* Set USB address to 0 */ + lpc31_set_address (priv, 0); + + /* Initialise the Enpoint List Address */ + lpc31_putreg ((uint32_t)g_qh, LPC31_USBDEV_ENDPOINTLIST); + + /* EndPoint 0 initialization */ + lpc31_ep0configure(priv); + + /* Enable Device interrupts */ + lpc31_putreg(USB_FRAME_INT | USB_ERROR_INT | + USBDEV_USBINTR_NAKE | USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | USBDEV_USBINTR_UE, + LPC31_USBDEV_USBINTR); +} + +/**************************************************************************** + * Name: lpc31_setstate + * + * Description: + * Sets the EP0 state and manages the NAK interrupts + * + ****************************************************************************/ + +static inline void lpc31_ep0state(struct lpc31_usbdev_s *priv, uint16_t state) +{ + priv->ep0state = state; + + switch (state) + { + case EP0STATE_WAIT_NAK_IN: + lpc31_putreg (LPC31_ENDPTMASK(LPC31_EP0_IN), LPC31_USBDEV_ENDPTNAKEN); + break; + case EP0STATE_WAIT_NAK_OUT: + lpc31_putreg (LPC31_ENDPTMASK(LPC31_EP0_OUT), LPC31_USBDEV_ENDPTNAKEN); + break; + default: + lpc31_putreg(0, LPC31_USBDEV_ENDPTNAKEN); + break; + } +} + +/**************************************************************************** + * Name: lpc31_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void lpc31_ep0setup(struct lpc31_usbdev_s *priv) +{ + struct lpc31_ep_s *privep; + struct usb_ctrlreq_s ctrl; + uint16_t value; + uint16_t index; + uint16_t len; + + /* Terminate any pending requests - since all DTDs will have been retired + * because of the setup packet */ + + lpc31_cancelrequests(&priv->eplist[LPC31_EP0_OUT], -EPROTO); + lpc31_cancelrequests(&priv->eplist[LPC31_EP0_IN], -EPROTO); + + /* Assume NOT stalled */ + + priv->eplist[LPC31_EP0_OUT].stalled = false; + priv->eplist[LPC31_EP0_IN].stalled = false; + priv->stalled = false; + + /* Read EP0 setup data */ + lpc31_readsetup(LPC31_EP0_OUT, &ctrl); + + /* Starting a control request - update state */ + lpc31_ep0state (priv, (ctrl.type & USB_REQ_DIR_IN) ? EP0STATE_SETUP_IN : EP0STATE_SETUP_OUT); + + /* And extract the little-endian 16-bit values to host order */ + value = GETUINT16(ctrl.value); + index = GETUINT16(ctrl.index); + len = GETUINT16(ctrl.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl.type, ctrl.req, value, index, len); + + /* Dispatch any non-standard requests */ + if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + lpc31_dispatchrequest(priv, &ctrl); + else + { + /* Handle standard request. Pick off the things of interest to the USB + * device controller driver; pass what is left to the class driver + */ + + switch (ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_GETSTATUS), 0); + if (!priv->paddrset || len != 2 || + (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPGETSTATUS), 0); + privep = lpc31_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + priv->ep0buf[0] = 1; /* Stalled */ + else + priv->ep0buf[0] = 0; /* Not stalled */ + + priv->ep0buf[1] = 0; + + lpc31_ep0xfer (LPC31_EP0_IN, priv->ep0buf, 2); + lpc31_ep0state (priv, EP0STATE_SHORTWRITE); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + priv->ep0buf[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + priv->ep0buf[1] = 0; + + lpc31_ep0xfer(LPC31_EP0_IN, priv->ep0buf, 2); + lpc31_ep0state (priv, EP0STATE_SHORTWRITE); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_IFGETSTATUS), 0); + priv->ep0buf[0] = 0; + priv->ep0buf[1] = 0; + + lpc31_ep0xfer(LPC31_EP0_IN, priv->ep0buf, 2); + lpc31_ep0state (priv, EP0STATE_SHORTWRITE); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_CLEARFEATURE), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc31_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc31_epfindbyaddr(priv, index)) != NULL) + { + lpc31_epstall(&privep->ep, true); + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SETFEATURE), 0); + if (((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value == USB_FEATURE_TESTMODE) + { + ullvdbg("test mode: %d\n", index); + } + else if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc31_dispatchrequest(priv, &ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc31_epfindbyaddr(priv, index)) != NULL) + { + lpc31_epstall(&privep->ep, false); + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EP0SETUPSETADDRESS), value); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0 && value < 128) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. */ + + priv->paddr = ctrl.value[0]; + priv->paddrset = false; + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_GETSETDESC), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + lpc31_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_GETCONFIG), 0); + if (priv->paddrset && (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value == 0 && index == 0 && len == 1) + { + lpc31_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SETCONFIG), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0) + { + lpc31_dispatchrequest(priv, &ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_GETSETIF), 0); + lpc31_dispatchrequest(priv, &ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc31_epstall(&priv->eplist[LPC31_EP0_IN].ep, false); + lpc31_epstall(&priv->eplist[LPC31_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc31_ep0complete + * + * Description: + * Transfer complete handler for Endpoint 0 + * + ****************************************************************************/ + +static void lpc31_ep0complete(struct lpc31_usbdev_s *priv, uint8_t epphy) +{ + struct lpc31_ep_s *privep = &priv->eplist[epphy]; + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EP0COMPLETE), (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_DATA_IN: + if (lpc31_rqempty(privep)) + return; + + if (lpc31_epcomplete (priv, epphy)) + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + break; + + case EP0STATE_DATA_OUT: + if (lpc31_rqempty(privep)) + return; + + if (lpc31_epcomplete (priv, epphy)) + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_IN); + break; + + case EP0STATE_SHORTWRITE: + lpc31_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + break; + + case EP0STATE_WAIT_STATUS_IN: + lpc31_ep0state (priv, EP0STATE_IDLE); + + /* If we've received a SETADDRESS packet, then we set the address + * now that the status phase has completed */ + if (! priv->paddrset && priv->paddr != 0) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr); + lpc31_set_address (priv, priv->paddr); + } + break; + + case EP0STATE_WAIT_STATUS_OUT: + lpc31_ep0state (priv, EP0STATE_IDLE); + break; + + default: +#ifdef CONFIG_DEBUG + DEBUGASSERT(priv->ep0state != EP0STATE_DATA_IN && + priv->ep0state != EP0STATE_DATA_OUT && + priv->ep0state != EP0STATE_SHORTWRITE && + priv->ep0state != EP0STATE_WAIT_STATUS_IN && + priv->ep0state != EP0STATE_WAIT_STATUS_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc31_epstall(&priv->eplist[LPC31_EP0_IN].ep, false); + lpc31_epstall(&priv->eplist[LPC31_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc31_ep0nak + * + * Description: + * Handle a NAK interrupt on EP0 + * + ****************************************************************************/ + +static void lpc31_ep0nak(struct lpc31_usbdev_s *priv, uint8_t epphy) +{ + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EP0NAK), (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_WAIT_NAK_IN: + lpc31_ep0xfer (LPC31_EP0_IN, NULL, 0); + lpc31_ep0state (priv, EP0STATE_WAIT_STATUS_IN); + break; + case EP0STATE_WAIT_NAK_OUT: + lpc31_ep0xfer (LPC31_EP0_OUT, NULL, 0); + lpc31_ep0state (priv, EP0STATE_WAIT_STATUS_OUT); + break; + default: +#ifdef CONFIG_DEBUG + DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN && + priv->ep0state != EP0STATE_WAIT_NAK_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc31_epstall(&priv->eplist[LPC31_EP0_IN].ep, false); + lpc31_epstall(&priv->eplist[LPC31_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc31_epcomplete + * + * Description: + * Transfer complete handler for Endpoints other than 0 + * returns whether the request at the head has completed + * + ****************************************************************************/ + +bool lpc31_epcomplete(struct lpc31_usbdev_s *priv, uint8_t epphy) +{ + struct lpc31_ep_s *privep = &priv->eplist[epphy]; + struct lpc31_req_s *privreq = privep->head; + struct lpc31_dtd_s *dtd = &g_td[epphy]; + + if (privreq == NULL) /* This shouldn't really happen */ + { + if (LPC31_EPPHYOUT(privep->epphy)) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPINQEMPTY), 0); + } + else + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPOUTQEMPTY), 0); + } + + return true; + } + + int xfrd = dtd->xfer_len - (dtd->config >> 16); + + privreq->req.xfrd += xfrd; + + bool complete = true; + if (LPC31_EPPHYOUT(privep->epphy)) + { + /* read(OUT) completes when request filled, or a short transfer is received */ + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPIN), complete); + } + else + { + /* write(IN) completes when request finished, unless we need to terminate with a ZLP */ + + bool need_zlp = (xfrd == privep->ep.maxpacket) && ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + + complete = (privreq->req.xfrd >= privreq->req.len && !need_zlp); + + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EPOUT), complete); + } + + /* If the transfer is complete, then dequeue and progress any further queued requests */ + + if (complete) + { + privreq = lpc31_rqdequeue (privep); + } + + if (!lpc31_rqempty(privep)) + { + lpc31_progressep(privep); + } + + /* Now it's safe to call the completion callback as it may well submit a new request */ + + if (complete) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + lpc31_reqcomplete(privep, privreq, OK); + } + + return complete; +} + + +/**************************************************************************** + * Name: lpc31_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int lpc31_usbinterrupt(int irq, FAR void *context) +{ + struct lpc31_usbdev_s *priv = &g_usbdev; + uint32_t disr, portsc1, n; + + usbtrace(TRACE_INTENTRY(LPC31_TRACEINTID_USB), 0); + + /* Read the interrupts and then clear them */ + + disr = lpc31_getreg(LPC31_USBDEV_USBSTS); + lpc31_putreg(disr, LPC31_USBDEV_USBSTS); + + if (disr & USBDEV_USBSTS_URI) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_DEVRESET), 0); + + lpc31_usbreset(priv); + + usbtrace(TRACE_INTEXIT(LPC31_TRACEINTID_USB), 0); + return OK; + } + + /* When the device controller enters a suspend state from an active state, + * the SLI bit will be set to a one. + */ + + if (!priv->suspended && (disr & USBDEV_USBSTS_SLI) != 0) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SUSPENDED), 0); + + /* Inform the Class driver of the suspend event */ + + priv->suspended = 1; + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + /* The device controller clears the SLI bit upon exiting from a suspend + * state. This bit can also be cleared by software writing a one to it. + */ + + else if (priv->suspended && (disr & USBDEV_USBSTS_SLI) == 0) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_RESUMED), 0); + + /* Inform the Class driver of the resume event */ + + priv->suspended = 0; + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + if (disr & USBDEV_USBSTS_PCI) + { + portsc1 = lpc31_getreg(LPC31_USBDEV_PORTSC1); + + if (portsc1 & USBDEV_PRTSC1_HSP) + priv->usbdev.speed = USB_SPEED_HIGH; + else + priv->usbdev.speed = USB_SPEED_FULL; + + if (portsc1 & USBDEV_PRTSC1_FPR) + { + /* FIXME: this occurs because of a J-to-K transition detected + * while the port is in SUSPEND state - presumambly this + * is where the host is resuming the device? + * + * - but do we need to "ack" the interrupt + */ + } + } + +#ifdef CONFIG_LPC31_USBDEV_FRAME_INTERRUPT + if (disr & USBDEV_USBSTT_SRI) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_FRAME), 0); + + priv->sof = (int)lpc31_getreg(LPC31_USBDEV_FRINDEX_OFFSET); + } +#endif + + if (disr & USBDEV_USBSTS_UEI) + { + /* FIXME: these occur when a transfer results in an error condition + * it is set alongside USBINT if the DTD also had its IOC + * bit set. */ + } + + if (disr & USBDEV_USBSTS_UI) + { + /* Handle completion interrupts */ + uint32_t mask = lpc31_getreg (LPC31_USBDEV_ENDPTCOMPLETE); + + if (mask) + { + /* Clear any NAK interrupt and completion interrupts */ + lpc31_putreg (mask, LPC31_USBDEV_ENDPTNAK); + lpc31_putreg (mask, LPC31_USBDEV_ENDPTCOMPLETE); + + if (mask & LPC31_ENDPTMASK(0)) + lpc31_ep0complete(priv, 0); + if (mask & LPC31_ENDPTMASK(1)) + lpc31_ep0complete(priv, 1); + + for (n = 1; n < LPC31_NLOGENDPOINTS; n++) + { + if (mask & LPC31_ENDPTMASK((n << 1))) + { + lpc31_epcomplete (priv, (n << 1)); + } + + if (mask & LPC31_ENDPTMASK((n << 1) + 1)) + { + lpc31_epcomplete(priv, (n << 1) + 1); + } + } + } + + /* Handle setup interrupts */ + uint32_t setupstat = lpc31_getreg(LPC31_USBDEV_ENDPTSETUPSTAT); + if (setupstat) + { + /* Clear the endpoint complete CTRL OUT and IN when a Setup is received */ + lpc31_putreg(LPC31_ENDPTMASK(LPC31_EP0_IN) | LPC31_ENDPTMASK(LPC31_EP0_OUT), + LPC31_USBDEV_ENDPTCOMPLETE); + + if (setupstat & LPC31_ENDPTMASK(LPC31_EP0_OUT)) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_EP0SETUP), setupstat); + lpc31_ep0setup(priv); + } + } + } + + if (disr & USBDEV_USBSTS_NAKI) + { + uint32_t pending = lpc31_getreg(LPC31_USBDEV_ENDPTNAK) & lpc31_getreg(LPC31_USBDEV_ENDPTNAKEN); + if (pending) + { + /* We shouldn't see NAK interrupts except on Endpoint 0 */ + if (pending & LPC31_ENDPTMASK(0)) + lpc31_ep0nak(priv, 0); + if (pending & LPC31_ENDPTMASK(1)) + lpc31_ep0nak(priv, 1); + } + + /* Clear the interrupts */ + lpc31_putreg(pending, LPC31_USBDEV_ENDPTNAK); + } + + usbtrace(TRACE_INTEXIT(LPC31_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int lpc31_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialise EP capabilities */ + + uint16_t maxsize = GETUINT16(desc->mxpacketsize); + if ((desc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_ISOC) + { + g_qh[privep->epphy].capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_IOS | + DQH_CAPABILITY_ZLT); + } + else + { + g_qh[privep->epphy].capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_ZLT); + } + + /* Setup Endpoint Control Register */ + + if (LPC31_EPPHYIN(privep->epphy)) + { + /* Reset the data toggles */ + uint32_t cfg = USBDEV_ENDPTCTRL_TXR; + + /* Set the endpoint type */ + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_TXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_TXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_TXT_BULK; break; + case USB_EP_ATTR_XFER_INT: cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break; + } + lpc31_chgbits (0xFFFF0000, cfg, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + } + else + { + /* Reset the data toggles */ + uint32_t cfg = USBDEV_ENDPTCTRL_RXR; + + /* Set the endpoint type */ + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_RXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_RXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_RXT_BULK; break; + } + lpc31_chgbits (0x0000FFFF, cfg, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + } + + /* Reset endpoint status */ + privep->stalled = false; + + /* Enable the endpoint */ + if (LPC31_EPPHYIN(privep->epphy)) + lpc31_setbits (USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + else + lpc31_setbits (USBDEV_ENDPTCTRL_RXE, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + + return OK; +} + +/**************************************************************************** + * Name: lpc31_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int lpc31_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->epphy); + + flags = enter_critical_section(); + + /* Disable Endpoint */ + if (LPC31_EPPHYIN(privep->epphy)) + lpc31_clrbits (USBDEV_ENDPTCTRL_TXE, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + else + lpc31_clrbits (USBDEV_ENDPTCTRL_RXE, LPC31_USBDEV_ENDPTCTRL(privep->epphy)); + + privep->stalled = true; + + /* Cancel any ongoing activity */ + lpc31_cancelrequests(privep, -ESHUTDOWN); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc31_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *lpc31_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc31_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct lpc31_ep_s *)ep)->epphy); + + privreq = (FAR struct lpc31_req_s *)kmm_malloc(sizeof(struct lpc31_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct lpc31_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: lpc31_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void lpc31_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc31_req_s *privreq = (FAR struct lpc31_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct lpc31_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: lpc31_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *lpc31_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc31_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void lpc31_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc31_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int lpc31_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc31_req_s *privreq = (FAR struct lpc31_req_s *)req; + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + FAR struct lpc31_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint */ + + if (LPC31_EPPHYIN(privep->epphy)) + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + else + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + + if (lpc31_rqenqueue(privep, privreq)) + { + lpc31_progressep(privep); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc31_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int lpc31_epcancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + lpc31_cancelrequests(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc31_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int lpc31_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy); + + uint32_t addr = LPC31_USBDEV_ENDPTCTRL(privep->epphy); + uint32_t ctrl_xs = LPC31_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXS : USBDEV_ENDPTCTRL_RXS; + uint32_t ctrl_xr = LPC31_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXR : USBDEV_ENDPTCTRL_RXR; + + if (resume) + { + privep->stalled = false; + + /* Clear stall and reset the data toggle */ + + lpc31_chgbits (ctrl_xs | ctrl_xr, ctrl_xr, addr); + } + else + { + privep->stalled = true; + + lpc31_setbits (ctrl_xs, addr); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *lpc31_allocep(FAR struct usbdev_s *dev, uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct lpc31_usbdev_s *priv = (FAR struct lpc31_usbdev_s *)dev; + uint32_t epset = LPC31_EPALLSET & ~LPC31_EPCTRLSET; + irqstate_t flags; + int epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* A logical address of 0 means that any endpoint will do */ + + if (eplog > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (eplog >= LPC31_NLOGENDPOINTS) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADEPNO), (uint16_t)eplog); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset &= 3 << (eplog << 1); + } + + /* Get the subset matching the requested direction */ + + if (in) + { + epset &= LPC31_EPINSET; + } + else + { + epset &= LPC31_EPOUTSET; + } + + /* Get the subset matching the requested type */ + + switch (eptype) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + epset &= LPC31_EPINTRSET; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + epset &= LPC31_EPBULKSET; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + epset &= LPC31_EPISOCSET; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ + default: + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BADEPTYPE), (uint16_t)eptype); + return NULL; + } + + /* Is the resulting endpoint supported by the LPC313x? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints */ + + for (epndx = 2; epndx < LPC31_NPHYSENDPOINTS; epndx++) + { + uint32_t bit = 1 << epndx; + if ((epset & bit) != 0) + { + /* Mark the IN/OUT endpoint no longer available */ + + priv->epavail &= ~(3 << (bit & ~1)); + leave_critical_section(flags); + + /* And return the pointer to the standard endpoint structure */ + + return &priv->eplist[epndx].ep; + } + } + /* Shouldn't get here */ + } + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_NOEP), (uint16_t)eplog); + return NULL; +} + +/**************************************************************************** + * Name: lpc31_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void lpc31_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc31_usbdev_s *priv = (FAR struct lpc31_usbdev_s *)dev; + FAR struct lpc31_ep_s *privep = (FAR struct lpc31_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: lpc31_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int lpc31_getframe(struct usbdev_s *dev) +{ +#ifdef CONFIG_LPC31_USBDEV_FRAME_INTERRUPT + FAR struct lpc31_usbdev_s *priv = (FAR struct lpc31_usbdev_s *)dev; + + /* Return last valid value of SOF read by the interrupt handler */ + + usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof); + return priv->sof; +#else + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* FIXME: this actually returns the micro frame number! */ + return (int)lpc31_getreg(LPC31_USBDEV_FRINDEX_OFFSET); +#endif +} + +/**************************************************************************** + * Name: lpc31_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int lpc31_wakeup(struct usbdev_s *dev) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + flags = enter_critical_section(); + lpc31_setbits(USBDEV_PRTSC1_FPR, LPC31_USBDEV_PORTSC1); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc31_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int lpc31_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct lpc31_usbdev_s *priv = (FAR struct lpc31_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: lpc31_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int lpc31_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + if (enable) + lpc31_setbits (USBDEV_USBCMD_RS, LPC31_USBDEV_USBCMD); + else + lpc31_clrbits (USBDEV_USBCMD_RS, LPC31_USBDEV_USBCMD); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + struct lpc31_usbdev_s *priv = &g_usbdev; + int i; + + usbtrace(TRACE_DEVINIT, 0); + + /* Disable USB interrupts */ + + lpc31_putreg(0, LPC31_USBDEV_USBINTR); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct lpc31_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[LPC31_EP0_IN].ep; + priv->epavail = LPC31_EPALLSET; + + /* Initialize the endpoint list */ + + for (i = 0; i < LPC31_NPHYSENDPOINTS; i++) + { + uint32_t bit = 1 << i; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + priv->eplist[i].ep.ops = &g_epops; + priv->eplist[i].dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + priv->eplist[i].epphy = i; + if (LPC31_EPPHYIN(i)) + { + priv->eplist[i].ep.eplog = LPC31_EPPHYIN2LOG(i); + } + else + { + priv->eplist[i].ep.eplog = LPC31_EPPHYOUT2LOG(i); + } + + /* The maximum packet size may depend on the type of endpoint */ + + if ((LPC31_EPCTRLSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC31_EP0MAXPACKET; + } + else if ((LPC31_EPINTRSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC31_INTRMAXPACKET; + } + else if ((LPC31_EPBULKSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC31_BULKMAXPACKET; + } + else /* if ((LPC31_EPISOCSET & bit) != 0) */ + { + priv->eplist[i].ep.maxpacket = LPC31_ISOCMAXPACKET; + } + } + + /* Enable USB to AHB clock and to Event router */ + + lpc31_enableclock (CLKID_USBOTGAHBCLK); + lpc31_enableclock (CLKID_EVENTROUTERPCLK); + + /* Reset USB block */ + + lpc31_softreset (RESETID_USBOTGAHBRST); + + /* Enable USB OTG PLL and wait for lock */ + + lpc31_putreg (0, LPC31_SYSCREG_USB_ATXPLLPDREG); + + uint32_t bank = EVNTRTR_BANK(EVENTRTR_USBATXPLLLOCK); + uint32_t bit = EVNTRTR_BIT(EVENTRTR_USBATXPLLLOCK); + + while (! (lpc31_getreg(LPC31_EVNTRTR_RSR(bank)) & (1 << bit))) + ; + + /* Enable USB AHB clock */ + + lpc31_enableclock (CLKID_USBOTGAHBCLK); + + /* Reset the controller */ + + lpc31_putreg (USBDEV_USBCMD_RST, LPC31_USBDEV_USBCMD); + while (lpc31_getreg (LPC31_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Attach USB controller interrupt handler */ + + if (irq_attach(LPC31_IRQ_USBOTG, lpc31_usbinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_IRQREGISTRATION), + (uint16_t)LPC31_IRQ_USBOTG); + goto errout; + } + + /* Program the controller to be the USB device controller */ + + lpc31_putreg (USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM | USBDEV_USBMODE_CM_DEVICE, + LPC31_USBDEV_USBMODE); + + /* Disconnect device */ + + lpc31_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + lpc31_usbreset(priv); + + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct lpc31_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + lpc31_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(LPC31_IRQ_USBOTG); + irq_detach(LPC31_IRQ_USBOTG); + + /* Reset the controller */ + + lpc31_putreg (USBDEV_USBCMD_RST, LPC31_USBDEV_USBCMD); + while (lpc31_getreg (LPC31_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Turn off USB power and clocking */ + + lpc31_disableclock (CLKID_USBOTGAHBCLK); + lpc31_disableclock (CLKID_EVENTROUTERPCLK); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(LPC31_IRQ_USBOTG); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + lpc31_pullup(&g_usbdev.usbdev, true); + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC31_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable USB controller interrupts */ + + up_disable_irq(LPC31_IRQ_USBOTG); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} diff --git a/arch/arm/src/lpc31xx/lpc31_usbotg.h b/arch/arm/src/lpc31xx/lpc31_usbotg.h new file mode 100644 index 0000000000000000000000000000000000000000..d63e3d4d49d15a4c568d6ac837d1e8850166ca34 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_usbotg.h @@ -0,0 +1,662 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_usbotg.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_USBOTG_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_USBOTG_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +#define LPC31_EHCI_NRHPORT 1 /* There is only a single root hub port */ + +/* USBOTG register base address offset into the USBOTG domain ***********************************/ + +#define LPC31_USBOTG_VBASE (LPC31_USBOTG_VSECTION) +#define LPC31_USBOTG_PBASE (LPC31_USBOTG_PSECTION) + +/* USBOTG register offsets (with respect to the base of the USBOTG domain) **********************/ + /* 0x000 - 0x0ff: Reserved */ +/* Device/host capability registers */ + +#define LPC31_USBOTG_HCCR_OFFSET 0x100 /* Offset to EHCI Host Controller Capabiliy registers */ +#define LPC31_USBOTG_CAPLENGTH_OFFSET 0x100 /* Capability register length (8-bit) */ +#define LPC31_USBHOST_HCIVERSION_OFFSET 0x102 /* Host interface version number (16-bit) */ +#define LPC31_USBHOST_HCSPARAMS_OFFSET 0x104 /* Host controller structural parameters */ +#define LPC31_USBHOST_HCCPARAMS_OFFSET 0x108 /* Host controller capability parameters */ +#define LPC31_USBDEV_DCIVERSION_OFFSET 0x120 /* Device interface version number */ +#define LPC31_USBDEV_DCCPARAMS_OFFSET 0x124 /* Device controller capability parameters */ + +/* Device/host/OTG operational registers */ + +#define LPC31_USBOTG_HCOR_OFFSET 0x140 /* Offset to EHCI Host Controller Operational Registers */ +#define LPC31_USBOTG_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define LPC31_USBOTG_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define LPC31_USBOTG_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define LPC31_USBOTG_FRINDEX_OFFSET 0x14C /* USB frame index (both) */ + /* EHCI 4G Segment Selector (not supported) */ +#define LPC31_USBOTG_PERIODICLIST_OFFSET 0x154 /* Frame list base address (host) */ +#define LPC31_USBOTG_DEVICEADDR_OFFSET 0x154 /* USB device address (device) */ +#define LPC31_USBOTG_ASYNCLISTADDR_OFFSET 0x158 /* Next asynchronous list address (host) */ +#define LPC31_USBOTG_ENDPOINTLIST_OFFSET 0x158 /* Address of endpoint list in memory (device) */ +#define LPC31_USBOTG_TTCTRL_OFFSET 0x15C /* Asynchronous buffer status for embedded TT (host) */ +#define LPC31_USBOTG_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define LPC31_USBOTG_TXFILLTUNING_OFFSET 0x164 /* Host transmit pre-buffer packet tuning (host) */ +#define LPC31_USBOTG_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define LPC31_USBOTG_ENDPTNAK_OFFSET 0x178 /* Endpoint NAK (device) */ +#define LPC31_USBOTG_ENDPTNAKEN_OFFSET 0x17C /* Endpoint NAK Enable (device) */ +#define LPC31_USBOTG_CONFIGFLAG_OFFSET 0x180 /* Configured flag register (not used in lpc313x) */ +#define LPC31_USBOTG_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define LPC31_USBOTG_OTGSC_OFFSET 0x1A4 /* OTG status and control (otg) */ +#define LPC31_USBOTG_USBMODE_OFFSET 0x1A8 /* USB device mode (both) */ + +#define LPC31_USBDEV_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define LPC31_USBDEV_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define LPC31_USBDEV_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define LPC31_USBDEV_FRINDEX_OFFSET 0x14C /* USB frame index (both) */ +#define LPC31_USBDEV_DEVICEADDR_OFFSET 0x154 /* USB device address (device) */ +#define LPC31_USBDEV_ENDPOINTLIST_OFFSET 0x158 /* Address of endpoint list in memory (device) */ +#define LPC31_USBDEV_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define LPC31_USBDEV_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define LPC31_USBDEV_ENDPTNAK_OFFSET 0x178 /* Endpoint NAK (device) */ +#define LPC31_USBDEV_ENDPTNAKEN_OFFSET 0x17C /* Endpoint NAK Enable (device) */ +#define LPC31_USBDEV_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define LPC31_USBDEV_USBMODE_OFFSET 0x1A8 /* USB device mode (both) */ + +#define LPC31_USBHOST_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define LPC31_USBHOST_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define LPC31_USBHOST_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define LPC31_USBHOST_FRINDEX_OFFSET 0x14C /* USB frame index (both) */ +#define LPC31_USBHOST_PERIODICLIST_OFFSET 0x154 /* Frame list base address (host) */ +#define LPC31_USBHOST_ASYNCLISTADDR_OFFSET 0x158 /* Next asynchronous list address (host) */ +#define LPC31_USBHOST_TTCTRL_OFFSET 0x15C /* Asynchronous buffer status for embedded TT (host) */ +#define LPC31_USBHOST_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define LPC31_USBHOST_TXFILLTUNING_OFFSET 0x164 /* Host transmit pre-buffer packet tuning (host) */ +#define LPC31_USBHOST_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define LPC31_USBHOST_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define LPC31_USBHOST_USBMODE_OFFSET 0x1A8 /* USB device mode (both) */ + +/* Device endpoint registers */ + +#define LPC31_USBDEV_ENDPTSETUPSTAT_OFFSET 0x1AC /* Endpoint setup status */ +#define LPC31_USBDEV_ENDPTPRIME_OFFSET 0x1B0 /* Endpoint initialization */ +#define LPC31_USBDEV_ENDPTFLUSH_OFFSET 0x1B4 /* Endpoint de-initialization */ +#define LPC31_USBDEV_ENDPTSTATUS_OFFSET 0x1B8 /* Endpoint status */ +#define LPC31_USBDEV_ENDPTCOMPLETE_OFFSET 0x1BC /* Endpoint complete */ +#define LPC31_USBDEV_ENDPTCTRL0_OFFSET 0x1C0 /* Endpoint control 0 */ +#define LPC31_USBDEV_ENDPTCTRL1_OFFSET 0x1C4 /* Endpoint control 1 */ +#define LPC31_USBDEV_ENDPTCTRL2_OFFSET 0x1C8 /* Endpoint control 2 */ +#define LPC31_USBDEV_ENDPTCTRL3_OFFSET 0x1CC /* Endpoint control 3 */ + +/* USBOTG register (virtual) addresses **********************************************************/ + +/* Device/host capability registers */ + +#define LPC31_USBOTG_HCCR_BASE (LPC31_USBOTG_VBASE+LPC31_USBOTG_HCCR_OFFSET) +#define LPC31_USBOTG_CAPLENGTH (LPC31_USBOTG_VBASE+LPC31_USBOTG_CAPLENGTH_OFFSET) +#define LPC31_USBHOST_HCIVERSION (LPC31_USBOTG_VBASE+LPC31_USBHOST_HCIVERSION_OFFSET) +#define LPC31_USBHOST_HCSPARAMS (LPC31_USBOTG_VBASE+LPC31_USBHOST_HCSPARAMS_OFFSET) +#define LPC31_USBHOST_HCCPARAMS (LPC31_USBOTG_VBASE+LPC31_USBHOST_HCCPARAMS_OFFSET) +#define LPC31_USBDEV_DCIVERSION (LPC31_USBOTG_VBASE+LPC31_USBDEV_DCIVERSION_OFFSET) +#define LPC31_USBDEV_DCCPARAMS (LPC31_USBOTG_VBASE+LPC31_USBDEV_DCCPARAMS_OFFSET) + +/* Device/host operational registers */ + +#define LPC31_USBOTG_HCOR_BASE (LPC31_USBOTG_VBASE+LPC31_USBOTG_HCOR_OFFSET) +#define LPC31_USBOTG_USBCMD (LPC31_USBOTG_VBASE+LPC31_USBOTG_USBCMD_OFFSET) +#define LPC31_USBOTG_USBSTS (LPC31_USBOTG_VBASE+LPC31_USBOTG_USBSTS_OFFSET) +#define LPC31_USBOTG_USBINTR (LPC31_USBOTG_VBASE+LPC31_USBOTG_USBINTR_OFFSET) +#define LPC31_USBOTG_FRINDEX (LPC31_USBOTG_VBASE+LPC31_USBOTG_FRINDEX_OFFSET) +#define LPC31_USBOTG_PERIODICLIST (LPC31_USBOTG_VBASE+LPC31_USBOTG_PERIODICLIST_OFFSET) +#define LPC31_USBOTG_DEVICEADDR (LPC31_USBOTG_VBASE+LPC31_USBOTG_DEVICEADDR_OFFSET) +#define LPC31_USBOTG_ASYNCLISTADDR (LPC31_USBOTG_VBASE+LPC31_USBOTG_ASYNCLISTADDR_OFFSET) +#define LPC31_USBOTG_ENDPOINTLIST (LPC31_USBOTG_VBASE+LPC31_USBOTG_ENDPOINTLIST_OFFSET) +#define LPC31_USBOTG_TTCTRL (LPC31_USBOTG_VBASE+LPC31_USBOTG_TTCTRL_OFFSET) +#define LPC31_USBOTG_BURSTSIZE (LPC31_USBOTG_VBASE+LPC31_USBOTG_BURSTSIZE_OFFSET) +#define LPC31_USBOTG_TXFILLTUNING (LPC31_USBOTG_VBASE+LPC31_USBOTG_TXFILLTUNING_OFFSET) +#define LPC31_USBOTG_BINTERVAL (LPC31_USBOTG_VBASE+LPC31_USBOTG_BINTERVAL_OFFSET) +#define LPC31_USBOTG_ENDPTNAK (LPC31_USBOTG_VBASE+LPC31_USBOTG_ENDPTNAK_OFFSET) +#define LPC31_USBOTG_ENDPTNAKEN (LPC31_USBOTG_VBASE+LPC31_USBOTG_ENDPTNAKEN_OFFSET) +#define LPC31_USBOTG_PORTSC1 (LPC31_USBOTG_VBASE+LPC31_USBOTG_PORTSC1_OFFSET) +#define LPC31_USBOTG_OTGSC (LPC31_USBOTG_VBASE+LPC31_USBOTG_OTGSC_OFFSET) +#define LPC31_USBOTG_USBMODE (LPC31_USBOTG_VBASE+LPC31_USBOTG_USBMODE_OFFSET) + +#define LPC31_USBDEV_USBCMD (LPC31_USBOTG_VBASE+LPC31_USBDEV_USBCMD_OFFSET) +#define LPC31_USBDEV_USBSTS (LPC31_USBOTG_VBASE+LPC31_USBDEV_USBSTS_OFFSET) +#define LPC31_USBDEV_USBINTR (LPC31_USBOTG_VBASE+LPC31_USBDEV_USBINTR_OFFSET) +#define LPC31_USBDEV_FRINDEX (LPC31_USBOTG_VBASE+LPC31_USBDEV_FRINDEX_OFFSET) +#define LPC31_USBDEV_DEVICEADDR (LPC31_USBOTG_VBASE+LPC31_USBDEV_DEVICEADDR_OFFSET) +#define LPC31_USBDEV_ENDPOINTLIST (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPOINTLIST_OFFSET) +#define LPC31_USBDEV_BURSTSIZE (LPC31_USBOTG_VBASE+LPC31_USBDEV_BURSTSIZE_OFFSET) +#define LPC31_USBDEV_BINTERVAL (LPC31_USBOTG_VBASE+LPC31_USBDEV_BINTERVAL_OFFSET) +#define LPC31_USBDEV_ENDPTNAK (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTNAK_OFFSET) +#define LPC31_USBDEV_ENDPTNAKEN (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTNAKEN_OFFSET) +#define LPC31_USBDEV_PORTSC1 (LPC31_USBOTG_VBASE+LPC31_USBDEV_PORTSC1_OFFSET) +#define LPC31_USBDEV_USBMODE (LPC31_USBOTG_VBASE+LPC31_USBDEV_USBMODE_OFFSET) + +#define LPC31_USBHOST_USBCMD (LPC31_USBOTG_VBASE+LPC31_USBHOST_USBCMD_OFFSET) +#define LPC31_USBHOST_USBSTS (LPC31_USBOTG_VBASE+LPC31_USBHOST_USBSTS_OFFSET) +#define LPC31_USBHOST_USBINTR (LPC31_USBOTG_VBASE+LPC31_USBHOST_USBINTR_OFFSET) +#define LPC31_USBHOST_FRINDEX (LPC31_USBOTG_VBASE+LPC31_USBHOST_FRINDEX_OFFSET) +#define LPC31_USBHOST_PERIODICLIST (LPC31_USBOTG_VBASE+LPC31_USBHOST_PERIODICLIST_OFFSET) +#define LPC31_USBHOST_ASYNCLISTADDR (LPC31_USBOTG_VBASE+LPC31_USBHOST_ASYNCLISTADDR_OFFSET) +#define LPC31_USBHOST_TTCTRL (LPC31_USBOTG_VBASE+LPC31_USBHOST_TTCTRL_OFFSET) +#define LPC31_USBHOST_BURSTSIZE (LPC31_USBOTG_VBASE+LPC31_USBHOST_BURSTSIZE_OFFSET) +#define LPC31_USBHOST_TXFILLTUNING (LPC31_USBOTG_VBASE+LPC31_USBHOST_TXFILLTUNING_OFFSET) +#define LPC31_USBHOST_BINTERVAL (LPC31_USBOTG_VBASE+LPC31_USBHOST_BINTERVAL_OFFSET) +#define LPC31_USBHOST_PORTSC1 (LPC31_USBOTG_VBASE+LPC31_USBHOST_PORTSC1_OFFSET) +#define LPC31_USBHOST_USBMODE (LPC31_USBOTG_VBASE+LPC31_USBHOST_USBMODE_OFFSET) + +/* Device endpoint registers */ + +#define LPC31_USBDEV_ENDPTSETUPSTAT (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTSETUPSTAT_OFFSET) +#define LPC31_USBDEV_ENDPTPRIME (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTPRIME_OFFSET) +#define LPC31_USBDEV_ENDPTFLUSH (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTFLUSH_OFFSET) +#define LPC31_USBDEV_ENDPTSTATUS (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTSTATUS_OFFSET) +#define LPC31_USBDEV_ENDPTCOMPLETE (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTCOMPLETE_OFFSET) +#define LPC31_USBDEV_ENDPTCTRL0 (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTCTRL0_OFFSET) +#define LPC31_USBDEV_ENDPTCTRL1 (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTCTRL1_OFFSET) +#define LPC31_USBDEV_ENDPTCTRL2 (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTCTRL2_OFFSET) +#define LPC31_USBDEV_ENDPTCTRL3 (LPC31_USBOTG_VBASE+LPC31_USBDEV_ENDPTCTRL3_OFFSET) + +/* USBOTG register bit definitions **************************************************************/ + +/* Device/host capability registers */ +/* CAPLENGTH (address 0x19000100) */ + +#define USBOTG_CAPLENGTH_SHIFT (0) /* Bits 0-7: Offset from register base to operational regs */ +#define USBOTG_CAPLENGTH_MASK (0xff << USBOTG_CAPLENGTH_SHIFT) + +/* HCIVERSION (address 0x19000102) */ + +#define USBHOST_HCIVERSION_SHIFT (0) /* Bits 0-15: BCD encoding of the EHCI revision number */ +#define USBHOST_HCIVERSION_MASK (0xffff << USBHOST_HCIVERSION_SHIFT) + +/* HCSPARAMS (address 0x19000104) */ + +#define USBHOST_HCSPARAMS_NTT_SHIFT (24) /* Bits 24-27: Number of Transaction Translators */ +#define USBHOST_HCSPARAMS_NTT_MASK (15 << USBHOST_HCSPARAMS_NTT_SHIFT) +#define USBHOST_HCSPARAMS_NPTT_SHIFT (20) /* Bits 20-23: Number of Ports per Transaction Translator */ +#define USBHOST_HCSPARAMS_NPTT_MASK (15 << USBHOST_HCSPARAMS_NPTT_SHIFT) +#define USBHOST_HCSPARAMS_PI (1 >> 16) /* Bit 16: Port indicators */ +#define USBHOST_HCSPARAMS_NCC_SHIFT (15) /* Bits 12-15: Number of Companion Controller */ +#define USBHOST_HCSPARAMS_NCC_MASK (15 << USBHOST_HCSPARAMS_NCC_SHIFT) +#define USBHOST_HCSPARAMS_NPCC_SHIFT (8) /* Bits 8-11: Number of Ports per Companion Controller */ +#define USBHOST_HCSPARAMS_NPCC_MASK (15 << USBHOST_HCSPARAMS_NPCC_SHIFT) +#define USBHOST_HCSPARAMS_PPC (1 >> 4) /* Bit 4: Port Power Control */ +#define USBHOST_HCSPARAMS_NPORTS_SHIF (0) /* Bits 0-3: Number of downstream ports */ +#define USBHOST_HCSPARAMS_NPORTS_MASK (15 << USBHOST_HCSPARAMS_NPORTS_SHIFT) + +/* HCCPARAMS (address 0x19000108) */ + +#define USBHOST_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ +#define USBHOST_HCCPARAMS_EECP_MASK (255 << USBHOST_HCCPARAMS_EECP_SHIFT) +#define USBHOST_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ +#define USBHOST_HCCPARAMS_IST_MASK (15 << USBHOST_HCCPARAMS_IST_SHIFT) +#define USBHOST_HCCPARAMS_ASP (1 >> 2) /* Bit 2: Asynchronous Schedule Park Capability */ +#define USBHOST_HCCPARAMS_PFL (1 >> 1) /* Bit 1: Programmable Frame List Flag */ +#define USBHOST_HCCPARAMS_ADC (1 >> 0) /* Bit 0: 64-bit Addressing Capability */ + +/* DCIVERSION (address 0x19000120) */ + +#define USBDEV_DCIVERSION_SHIFT (0) /* Bits 0-15: BCD encoding of the device interface */ +#define USBDEV_DCIVERSION_MASK (0xffff << USBDEV_DCIVERSION_SHIFT) + +/* DCCPARAMS (address 0x19000124) */ + +#define USBDEV_DCCPARAMS_HC (1 >> 8) /* Bit 8: Host Capable */ +#define USBDEV_DCCPARAMS_DC (1 >> 7) /* Bit 7: Device Capable */ +#define USBDEV_DCCPARAMS_DEN_SHIFT (0) /* Bits 0-4: DEN Device Endpoint Number */ +#define USBDEV_DCCPARAMS_DEN_MASK (31 << USBDEV_DCCPARAMS_DEN_SHIFT) + +/* Device/host operational registers */ +/* USB Command register USBCMD (address 0x19000140) -- Device Mode */ + +#define USBDEV_USBCMD_ITC_SHIFT (16) /* Bits 16-23: Interrupt threshold control */ +#define USBDEV_USBCMD_ITC_MASK (255 << USBDEV_USBCMD_ITC_SHIFT) +# define USBDEV_USBCMD_ITCIMME (0 << USBDEV_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBDEV_USBCMD_ITC1UF (1 << USBDEV_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBDEV_USBCMD_ITC2UF (2 << USBDEV_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBDEV_USBCMD_ITC4UF (4 << USBDEV_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBDEV_USBCMD_ITC8UF (8 << USBDEV_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBDEV_USBCMD_ITC16UF (16 << USBDEV_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBDEV_USBCMD_ITC32UF (32 << USBDEV_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBDEV_USBCMD_ITC64UF (64 << USBDEV_USBCMD_ITC_SHIFT) /* 64 micro frames */ +#define USBDEV_USBCMD_ATDTW (1 << 14) /* Bit 14: Add dTD trip wire */ +#define USBDEV_USBCMD_SUTW (1 << 13) /* Bit 13: Setup trip wire */ +#define USBDEV_USBCMD_RST (1 << 1) /* Bit 1: 1 Controller reset */ +#define USBDEV_USBCMD_RS (1 << 0) /* Bit 0: 0 Run/Stop */ + +/* USB Command register USBCMD (address 0x19000140) -- Host Mode */ + +#define USBHOST_USBCMD_ITC_SHIFT (16) /* Bits 16-13: Interrupt threshold control */ +#define USBHOST_USBCMD_ITC_MASK (255 << USBHOST_USBCMD_ITC_SHIFT) +# define USBHOST_USBCMD_ITCIMMED (0 << USBHOST_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBHOST_USBCMD_ITC1UF (1 << USBHOST_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBHOST_USBCMD_ITC2UF (2 << USBHOST_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBHOST_USBCMD_ITC4UF (4 << USBHOST_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBHOST_USBCMD_ITC8UF (8 << USBHOST_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBHOST_USBCMD_ITC16UF (16 << USBHOST_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBHOST_USBCMD_ITC32UF (32 << USBHOST_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBHOST_USBCMD_ITC64UF (64 << USBHOST_USBCMD_ITC_SHIFT) /* 64 micro frames */ +#define USBHOST_USBCMD_FS2 (1 << 15) /* Bit 15: Bit 2 of the Frame List Size bits */ +#define USBHOST_USBCMD_ASPE (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ +#define USBHOST_USBCMD_ASP_SHIFT (8) /* Bits 8-9: Asynchronous schedule park mode */ +#define USBHOST_USBCMD_ASP_MASK (3 << USBHOST_USBCMD_ASP_SHIFT) +#define USBHOST_USBCMD_IAA (1 << 6) /* Bit 6: Interrupt next asynchronous schedule */ +#define USBHOST_USBCMD_ASE (1 << 5) /* Bit 5: Skips processing asynchronous schedule */ +#define USBHOST_USBCMD_PSE (1 << 4) /* Bit 4: Skips processing periodic schedule */ +#define USBHOST_USBCMD_FS1 (1 << 3) /* Bit 3: Bit 1 of the Frame List Size bits */ +#define USBHOST_USBCMD_FS0 (1 << 2) /* Bit 2: Bit 0 of the Frame List Size bits */ +#define USBHOST_USBCMD_RST (1 << 1) /* Bit 1: Controller reset */ +#define USBHOST_USBCMD_RS (1 << 0) /* Bit 0: Run/Stop */ + +/* USB Status register USBSTS (address 0x19000144) -- Device Mode */ + +#define USBDEV_USBSTS_NAKI (1 << 16) /* Bit 16: NAK interrupt bit */ +#define USBDEV_USBSTS_SLI (1 << 8) /* Bit 8: DCSuspend */ +#define USBDEV_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ +#define USBDEV_USBSTS_URI (1 << 6) /* Bit 6: USB reset received */ +#define USBDEV_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ +#define USBDEV_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBDEV_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ + +/* USB Status register USBSTS (address 0x19000144) -- Host Mode */ + +#define USBHOST_USBSTS_UPI (1 << 19) /* Bit 19: USB host periodic interrupt */ +#define USBHOST_USBSTS_UAI (1 << 18) /* Bit 18: USB host asynchronous interrupt */ +#define USBHOST_USBSTS_AS (1 << 15) /* Bit 15: Asynchronous schedule status */ +#define USBHOST_USBSTS_PS (1 << 14) /* Bit 14: Periodic schedule status */ +#define USBHOST_USBSTS_RCL (1 << 13) /* Bit 13: Reclamation */ +#define USBHOST_USBSTS_HCH (1 << 12) /* Bit 12: HCHalted */ +#define USBHOST_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ +#define USBHOST_USBSTS_AAI (1 << 5) /* Bit 5: Interrupt on async advance */ +#define USBHOST_USBSTS_FRI (1 << 3) /* Bit 3: Frame list roll-over */ +#define USBHOST_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ +#define USBHOST_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBHOST_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ + +/* USB interrupt register USBINTR (address 0x19000148) -- Device Mode */ + +#define USBDEV_USBINTR_NAKE (1 << 16) /* Bit 16: NAK interrupt enable */ +#define USBDEV_USBINTR_SLE (1 << 8) /* Bit 8: Sleep enable */ +#define USBDEV_USBINTR_SRE (1 << 7) /* Bit 7: SOF received enable */ +#define USBDEV_USBINTR_URE (1 << 6) /* Bit 6: USB reset enable */ +#define USBDEV_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ +#define USBDEV_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBDEV_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ + +/* USB interrupt register USBINTR (address 0x19000148) -- Host Mode */ + +#define USBHOST_USBINTR_UPIA (1 << 19) /* Bit 19: USB host periodic interrupt enable */ +#define USBHOST_USBINTR_UAIE (1 << 18) /* Bit 18: USB host asynchronous interrupt enable */ +#define USBHOST_USBINTR_SRE (1 << 7) /* Bit 7: SOF timer interrupt enable */ +#define USBHOST_USBINTR_AAE (1 << 5) /* Bit 5: Interrupt on asynchronous advance enable */ +#define USBHOST_USBINTR_FRE (1 << 3) /* Bit 3: Frame list rollover enable */ +#define USBHOST_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ +#define USBHOST_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBHOST_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ + +/* Frame index register FRINDEX (address 0x1900014c) -- Device Mode */ + +#define USBDEV_FRINDEX_LFN_SHIFT (3) /* Bits 3-13: Frame number of last frame transmitted */ +#define USBDEV_FRINDEX_LFN_MASK (0x7ff << USBDEV_FRINDEX_LFN_SHIFT) +#define USBDEV_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBDEV_FRINDEX_CUFN_MASK (7 << USBDEV_FRINDEX_CUFN_SHIFT) + +/* Frame index register FRINDEX (address 0x1900014c) -- Host Mode */ + +#define USBHOST_FRINDEX_FLI_SHIFT (3) /* Bits 3-13: Frame list current index */ +#define USBHOST_FRINDEX_FLI_MASK(n) (0x7ff << ((n)+USBHOST_FRINDEX_FLI_SHIFT-1) +#define USBHOST_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBHOST_FRINDEX_CUFN_MASK (7 << USBHOST_FRINDEX_CUFN_SHIFT) + +/* USB Device Address register DEVICEADDR (address 0x19000154) -- Device Mode */ + +#define USBDEV_DEVICEADDR_SHIFT (25) /* Bits 25-31: USBADR USB device address */ +#define USBDEV_DEVICEADDR_MASK (0x3c << USBDEV_DEVICEADDR_SHIFT) +#define USBDEV_DEVICEADDR_USBADRA (1 << 24) /* Bit 24: Device address advance */ + +/* USB Periodic List Base register PERIODICLIST (address 0x19000154) -- Host Mode */ + +#define USBHOST_PERIODICLIST_PERBASE_SHIFT (12) /* Bits 12-31: Base Address (Low) */ +#define USBHOST_PERIODICLIST_PERBASE_MASK (0x000fffff << USBHOST_PERIODICLIST_PERBASE_SHIFT) + +/* USB Endpoint List Address register ENDPOINTLISTADDR (address 0x19000158) -- Device Mode */ + +#define USBDEV_ENDPOINTLIST_EPBASE_SHIFT (11) /* Bits 11-31: Endpoint list pointer (low) */ +#define USBDEV_ENDPOINTLIST_EPBASE_MASK (0x001fffff << USBDEV_ENDPOINTLIST_EPBASE_SHIFT) + +/* USB Asynchronous List Address register ASYNCLISTADDR- (address 0x19000158) -- Host Mode */ + +#define USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT (5) /* Bits 5-31: Link pointer (Low) LPL */ +#define USBHOST_ASYNCLISTADDR_ASYBASE_MASK (0x07ffffff << USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT) + +/* USB TT Control register TTCTRL (address 0x1900015c) -- Host Mode */ + +#define USBHOST_TTCTRL_TTHA_SHIFT (24) /* Bits 24-30: Hub address */ +#define USBHOST_TTCTRL_TTHA_MASK (0x7f << USBHOST_TTCTRL_TTHA_SHIFT) + +/* USB burst size register BURSTSIZE (address 0x19000160) -- Device/Host Mode */ + +#define USBDEV_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBDEV_BURSTSIZE_TXPBURST_MASK (255 << USBDEV_BURSTSIZE_TXPBURST_SHIFT) +#define USBDEV_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBDEV_BURSTSIZE_RXPBURST_MASK (255 << USBDEV_BURSTSIZE_RXPBURST_SHIFT) + +#define USBHOST_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBHOST_BURSTSIZE_TXPBURST_MASK (255 << USBHOST_BURSTSIZE_TXPBURST_SHIFT) +#define USBHOST_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBHOST_BURSTSIZE_RXPBURST_MASK (255 << USBHOST_BURSTSIZE_RXPBURST_SHIFT) + +/* USB Transfer buffer Fill Tuning register TXFIFOFILLTUNING (address 0x19000164) -- Host Mode */ + +#define USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT (16) /* Bits 16-21: Scheduler overhead */ +#define USBHOST_TXFILLTUNING_FIFOTHRES_MASK (0x3c << USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT) +#define USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT (8) /* Bits 8-12: Scheduler health counter */ +#define USBHOST_TXFILLTUNING_SCHEATLTH_MASK (0x1f << USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT) +#define USBHOST_TXFILLTUNING_SCHOH_SHIFT (0) /* Bits 0-7: FIFO burst threshold */ +#define USBHOST_TXFILLTUNING_SCHOH_MASK (0xff << USBHOST_TXFILLTUNING_SCHOH_SHIFT) + +/* USB BINTERVAL register BINTERVAL (address 0x19000174) -- Device/Host Mode */ + +#define USBDEV_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBDEV_BINTERVAL_MASK (15 << USBDEV_BINTERVAL_SHIFT) + +#define USBHOST_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBHOST_BINTERVAL_MASK (15 << USBHOST_BINTERVAL_SHIFT) + +/* USB endpoint NAK register ENDPTNAK (address 0x19000178) -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPTN_SHIFT (16) /* Bits 16-19: Tx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPTN_MASK (15 << USBDEV_ENDPTNAK_EPTN_SHIFT) +#define USBDEV_ENDPTNAK_EPRN_SHIFT (0) /* Bits 0-3: Rx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPRN_MASK (15 << USBDEV_ENDPTNAK_EPRN_SHIFT) + +/* USB Endpoint NAK Enable register ENDPTNAKEN (address 0x1900017c) -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPTNE_SHIFT (16) /* Bits 16-19: Tx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPTNE_MASK (15 << USBDEV_ENDPTNAK_EPTNE_SHIFT) +#define USBDEV_ENDPTNAK_EPRNE_SHIFT (0) /* Bits 0-3: Rx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPRNE_MASK (15 << USBDEV_ENDPTNAK_EPRNE_SHIFT) + +/* Port Status and Control register PRTSC1 (address 0x19000184) -- Device Mode */ + +#define USBDEV_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBDEV_PRTSC1_PSPD_MASK (3 << USBDEV_PRTSC1_PSPD_SHIFT) +# define USBDEV_PRTSC1_PSPD_FS (0 << USBDEV_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBDEV_PRTSC1_PSPD_LS (1 << USBDEV_PRTSC1_PSPD_SHIFT) /* Low-speed */ +# define USBDEV_PRTSC1_PSPD_HS (2 << USBDEV_PRTSC1_PSPD_SHIFT) /* High-speed */ +#define USBDEV_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ +#define USBDEV_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +#define USBDEV_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: 19: Port test control */ +#define USBDEV_PRTSC1_PTC_MASK (15 << USBDEV_PRTSC1_PTC_SHIFT) +# define USBDEV_PRTSC1_PTC_DISABLE (0 << USBDEV_PRTSC1_PTC_SHIFT) /* TEST_MODE_DISABLE */ +# define USBDEV_PRTSC1_PTC_JSTATE (1 << USBDEV_PRTSC1_PTC_SHIFT) /* J_STATE */ +# define USBDEV_PRTSC1_PTC_KSTATE (2 << USBDEV_PRTSC1_PTC_SHIFT) /* K_STATE */ +# define USBDEV_PRTSC1_PTC_SE0 (3 << USBDEV_PRTSC1_PTC_SHIFT) /* SE0 (host)/NAK (device) */ +# define USBDEV_PRTSC1_PTC_PACKET (4 << USBDEV_PRTSC1_PTC_SHIFT) /* Packet */ +# define USBDEV_PRTSC1_PTC_HS (5 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_HS */ +# define USBDEV_PRTSC1_PTC_FS (6 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_FS */ +#define USBDEV_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBDEV_PRTSC1_PIC_MASK (3 << USBDEV_PRTSC1_PIC_SHIFT) +# define USBDEV_PRTSC1_PIC_OFF (0 << USBDEV_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBDEV_PRTSC1_PIC_AMBER (1 << USBDEV_PRTSC1_PIC_SHIFT) /* 01 amber */ +# define USBDEV_PRTSC1_PIC_GREEN (2 << USBDEV_PRTSC1_PIC_SHIFT) /* 10 green */ +#define USBDEV_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ +#define USBDEV_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBDEV_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBDEV_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBDEV_PRTSC1_PEC (1 << 3) /* Bit 3: Port enable/disable change */ +#define USBDEV_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBDEV_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ + +/* Port Status and Control register PRTSC1 (address 0x19000184) -- Host Mode */ + +#define USBHOST_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBHOST_PRTSC1_PSPD_MASK (3 << USBHOST_PRTSC1_PSPD_SHIFT) +# define USBHOST_PRTSC1_PSPD_FS (0 << USBHOST_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBHOST_PRTSC1_PSPD_LS (1 << USBHOST_PRTSC1_PSPD_SHIFT) /* Low-speed */ +# define USBHOST_PRTSC1_PSPD_HS (2 << USBHOST_PRTSC1_PSPD_SHIFT) /* High-speed */ +#define USBHOST_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ +#define USBHOST_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +#define USBHOST_PRTSC1_WKOC (1 << 22) /* Bit 22: Wake on over-current enable (WKOC_E) */ +#define USBHOST_PRTSC1_WKDC (1 << 21) /* Bit 21: Wake on disconnect enable (WKDSCNNT_E) */ +#define USBHOST_PRTSC1_WKCN (1 << 20) /* Bit 20: Wake on connect enable (WKCNNT_E) */ +#define USBHOST_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: Port test control */ +#define USBHOST_PRTSC1_PTC_MASK (15 << USBHOST_PRTSC1_PTC_SHIFT) +# define USBHOST_PRTSC1_PTC_DISABLE (0 << USBHOST_PRTSC1_PTC_SHIFT) /* 0000 TEST_MODE_DISABLE */ +# define USBHOST_PRTSC1_PTC_JSTATE (1 << USBHOST_PRTSC1_PTC_SHIFT) /* 0001 J_STATE */ +# define USBHOST_PRTSC1_PTC_KSTATE (2 << USBHOST_PRTSC1_PTC_SHIFT) /* 0010 K_STATE */ +# define USBHOST_PRTSC1_PTC_SE0 (3 << USBHOST_PRTSC1_PTC_SHIFT) /* 0011 SE0 (host)/NAK (device) */ +# define USBHOST_PRTSC1_PTC_PACKET (4 << USBHOST_PRTSC1_PTC_SHIFT) /* 0100 Packet */ +# define USBHOST_PRTSC1_PTC_HS (5 << USBHOST_PRTSC1_PTC_SHIFT) /* 0101 FORCE_ENABLE_HS */ +# define USBHOST_PRTSC1_PTC_FS (6 << USBHOST_PRTSC1_PTC_SHIFT) /* 0110 FORCE_ENABLE_FS */ +# define USBHOST_PRTSC1_PTC_LS (7 << USBHOST_PRTSC1_PTC_SHIFT) /* 0111 FORCE_ENABLE_LS */ +#define USBHOST_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBHOST_PRTSC1_PIC_MASK (3 << USBHOST_PRTSC1_PIC_SHIFT) +# define USBHOST_PRTSC1_PIC_OFF (0 << USBHOST_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBHOST_PRTSC1_PIC_AMBER (1 << USBHOST_PRTSC1_PIC_SHIFT) /* 01 Amber */ +# define USBHOST_PRTSC1_PIC_GREEN (2 << USBHOST_PRTSC1_PIC_SHIFT) /* 10 Green */ +#define USBHOST_PRTSC1_PP (1 << 12) /* Bit 12: Port power control */ +#define USBHOST_PRTSC1_LS_SHIFT (10) /* Bits 10-11: Line status */ +#define USBHOST_PRTSC1_LS_MASK (3 << USBHOST_PRTSC1_LS_SHIFT) +# define USBHOST_PRTSC1_LS_SE0 (0 << USBHOST_PRTSC1_LS_SHIFT) /* SE0 (USB_DP and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_JSTATE (2 << USBHOST_PRTSC1_LS_SHIFT) /* J-state (USB_DP HIGH and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_KSTATE (1 << USBHOST_PRTSC1_LS_SHIFT) /* K-state (USB_DP LOW and USB_DM HIGH) */ +#define USBHOST_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ +#define USBHOST_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBHOST_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBHOST_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBHOST_PRTSC1_OCC (1 << 5) /* Bit 5: Over-current change */ +#define USBHOST_PRTSC1_OCA (1 << 4) /* Bit 4: Over-current active */ +#define USBHOST_PRTSC1_PEC (1 << 3) /* Bit 3: Port disable/enable change */ +#define USBHOST_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBHOST_PRTSC1_CSC (1 << 1) /* Bit 1: Connect status change */ +#define USBHOST_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ + +/* OTG Status and Control register (OTGSC - address 0x190001a4) */ + +/* OTG interrupt enable */ + +#define USBOTG_OTGSC_DPIE (1 << 30) /* Bit 30: Data pulse interrupt enable */ +#define USBOTG_OTGSC_1MSE (1 << 29) /* Bit 29: 1 millisecond timer interrupt enable */ +#define USBOTG_OTGSC_BSEIE (1 << 28) /* Bit 28: B-session end interrupt enable */ +#define USBOTG_OTGSC_BSVIE (1 << 27) /* Bit 27: B-session valid interrupt enable */ +#define USBOTG_OTGSC_ASVIE (1 << 26) /* Bit 26: A-session valid interrupt enable */ +#define USBOTG_OTGSC_AVVIE (1 << 25) /* Bit 25: A-VBUS valid interrupt enable */ +#define USBOTG_OTGSC_IDIE (1 << 24) /* Bit 24: USB ID interrupt enable */ + +/* OTG interrupt status */ + +#define USBOTG_OTGSC_DPIS (1 << 22) /* Bit 22: Data pulse interrupt status */ +#define USBOTG_OTGSC_1MSS (1 << 21) /* Bit 21: 1 millisecond timer interrupt status */ +#define USBOTG_OTGSC_BSEIS (1 << 20) /* Bit 20: B-Session end interrupt status */ +#define USBOTG_OTGSC_BSVIS (1 << 19) /* Bit 19: B-Session valid interrupt status */ +#define USBOTG_OTGSC_ASVIS (1 << 18) /* Bit 18: A-Session valid interrupt status */ +#define USBOTG_OTGSC_AVVIS (1 << 17) /* Bit 17: A-VBUS valid interrupt status */ +#define USBOTG_OTGSC_IDIS (1 << 16) /* Bit 16: USB ID interrupt status */ + +/* OTG status inputs */ + +#define USBOTG_OTGSC_DPS (1 << 14) /* Bit 14: Data bus pulsing status */ +#define USBOTG_OTGSC_1MST (1 << 13) /* Bit 13: 1 millisecond timer toggle */ +#define USBOTG_OTGSC_BSE (1 << 12) /* Bit 12: B-session end */ +#define USBOTG_OTGSC_BSV (1 << 11) /* Bit 11: B-session valid */ +#define USBOTG_OTGSC_ASV (1 << 10) /* Bit 10: A-session valid */ +#define USBOTG_OTGSC_AVV (1 << 9) /* Bit 9: A-VBUS valid */ +#define USBOTG_OTGSC_ID (1 << 8) /* Bit 8: USB ID */ + +/* OTG controls */ + +#define USBOTG_OTGSC_HABA (1 << 7) /* Bit 7: Hardware assist B-disconnect to A-connect */ +#define USBOTG_OTGSC_HADP (1 << 6) /* Bit 6: Hardware assist data pulse */ +#define USBOTG_OTGSC_IDPU (1 << 5) /* Bit 5: ID pull-up */ +#define USBOTG_OTGSC_DP (1 << 4) /* Bit 4: Data pulsing */ +#define USBOTG_OTGSC_OT (1 << 3) /* Bit 3: OTG termination */ +#define USBOTG_OTGSC_HAAR (1 << 2) /* Bit 2: Hardware assist auto_reset */ +#define USBOTG_OTGSC_VC (1 << 1) /* Bit 1: VBUS_Charge */ +#define USBOTG_OTGSC_VD (1 << 0) /* Bit 0: VBUS_Discharge */ + +/* USB Mode register USBMODE (address 0x190001a8) -- Device Mode */ + +#define USBDEV_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ +#define USBDEV_USBMODE_SLOM (1 << 3) /* Bit 3: Setup Lockout mode */ +#define USBDEV_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ +#define USBDEV_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBDEV_USBMODE_CM_MASK (3 << USBDEV_USBMODE_CM_SHIFT) +# define USBDEV_USBMODE_CM_IDLE (0 << USBDEV_USBMODE_CM_SHIFT) /* Idle */ +# define USBDEV_USBMODE_CM_DEVICE (2 << USBDEV_USBMODE_CM_SHIFT) /* Device controller */ +# define USBDEV_USBMODE_CM_HOST (3 << USBDEV_USBMODE_CM_SHIFT) /* Host controller */ + +/* USB Mode register USBMODE (address 0x190001a8) -- Device Mode */ + +#define USBHOST_USBMODE_VBPS (1 << 5) /* Bit 5: VBUS power select */ +#define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ +#define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ +#define USBHOST_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBHOST_USBMODE_CM_MASK (3 << USBHOST_USBMODE_CM_SHIFT) +# define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */ +# define USBHOST_USBMODE_CM_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */ +# define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */ + +/* Device endpoint registers */ + +/* USB Endpoint Setup Status register ENDPTSETUPSTAT (address 0x190001ac) */ + +#define USBDEV_ENDPTSETSTAT_STAT3 (1 << 3) /* Bit 3: Setup EP status for logical EP 3 */ +#define USBDEV_ENDPTSETSTAT_STAT2 (1 << 2) /* Bit 2: Setup EP status for logical EP 2 */ +#define USBDEV_ENDPTSETSTAT_STAT1 (1 << 1) /* Bit 1: Setup EP status for logical EP 1 */ +#define USBDEV_ENDPTSETSTAT_STAT0 (1 << 0) /* Bit 0: Setup EP status for logical EP 0 */ + +/* USB Endpoint Prime register ENDPTPRIME (address 0x190001b0) */ + +#define USBDEV_ENDPTPRIM_PETB3 (1 << 19) /* Bit 19: Prime EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTPRIM_PETB2 (1 << 18) /* Bit 18: Prime EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTPRIM_PETB1 (1 << 17) /* Bit 17: Prime EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTPRIM_PETB0 (1 << 16) /* Bit 16: Prime EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTPRIM_PERB3 (1 << 3) /* Bit 3: Prime EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTPRIM_PERB2 (1 << 2) /* Bit 2: Prime EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTPRIM_PERB1 (1 << 1) /* Bit 1: Prime EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTPRIM_PERB0 (1 << 0) /* Bit 0: Prime EP recv buffer for physical OUT EP 0 */ + +/* USB Endpoint Flush register ENDPTFLUSH(address 0x190001b4) */ + +#define USBDEV_ENDPTFLUSH_FETB3 (1 << 19) /* Bit 19: Flush EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTFLUSH_FETB2 (1 << 18) /* Bit 18: Flush EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTFLUSH_FETB1 (1 << 17) /* Bit 17: Flush EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTFLUSH_FETB0 (1 << 16) /* Bit 16: Flush EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTFLUSH_FERB3 (1 << 3) /* Bit 3: Flush EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTFLUSH_FERB2 (1 << 2) /* Bit 2: Flush EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTFLUSH_FERB1 (1 << 1) /* Bit 1: Flush EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTFLUSH_FERB0 (1 << 0) /* Bit 0: Flush EP recv buffer for physical OUT EP 0 */ + +/* USB Endpoint Status register ENDPTSTATUS (address 0x190001b8) */ + +#define USBDEV_ENDPTSTATUS_ETBR3 (1 << 19) /* Bit 19: EP xmt buffer ready for physical IN EP 3 */ +#define USBDEV_ENDPTSTATUS_ETBR2 (1 << 18) /* Bit 18: EP xmt buffer ready for physical IN EP 2 */ +#define USBDEV_ENDPTSTATUS_ETBR1 (1 << 17) /* Bit 17: EP xmt buffer ready for physical IN EP 1 */ +#define USBDEV_ENDPTSTATUS_ETBR0 (1 << 16) /* Bit 16: EP xmt buffer ready for physical IN EP 0 */ +#define USBDEV_ENDPTSTATUS_ERBR3 (1 << 3) /* Bit 3: EP recv buffer ready for physical OUT EP 3 */ +#define USBDEV_ENDPTSTATUS_ERBR2 (1 << 2) /* Bit 2: EP recv buffer ready for physical OUT EP 2 */ +#define USBDEV_ENDPTSTATUS_ERBR1 (1 << 1) /* Bit 1: EP recv buffer ready for physical OUT EP 1 */ +#define USBDEV_ENDPTSTATUS_ERBR0 (1 << 0) /* Bit 0: EP recv buffer ready for physical OUT EP 0 */ + +/* USB Endpoint Complete register ENDPTCOMPLETE (address 0x190001bc) */ + +#define USBDEV_ENDPTCOMPLETE_ETCE3 (1 << 19) /* Bit 19: EP xmt complete event for physical IN EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ETCE2 (1 << 18) /* Bit 18: EP xmt complete event for physical IN EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ETCE1 (1 << 17) /* Bit 17: EP xmt complete event for physical IN EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ETCE0 (1 << 16) /* Bit 16: EP xmt complete event for physical IN EP 0 */ +#define USBDEV_ENDPTCOMPLETE_ERCE3 (1 << 3) /* Bit 3: EP recv complete event for physical OUT EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ERCE2 (1 << 2) /* Bit 2: EP recv complete event for physical OUT EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ERCE1 (1 << 1) /* Bit 1: EP recv complete event for physical OUT EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ERCE0 (1 << 0) /* Bit 0: EP recv complete event for physical OUT EP 0 */ + +/* USB Endpoint 0 Control register ENDPTCTRL0 (address 0x190001c0) */ + +#define USBDEV_ENDPTCTRL0_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ +#define USBDEV_ENDPTCTRL0_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL0_TXT_MASK (3 << USBDEV_ENDPTCTRL0_TXT_SHIFT) +# define USBDEV_ENDPTCTRL0_TXT_CTRL (0 << USBDEV_ENDPTCTRL0_TXT_SHIFT) /* Control */ +#define USBDEV_ENDPTCTRL0_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ +#define USBDEV_ENDPTCTRL0_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ +#define USBDEV_ENDPTCTRL0_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTR0L_RXT_MASK (3 << USBDEV_ENDPTCTRL0_RXT_SHIFT) +# define USBDEV_ENDPTCTRL0_RXT_CTRL (0 << USBDEV_ENDPTCTRL0_RXT_SHIFT) /* Control */ +#define USBDEV_ENDPTCTRL0_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + +/* USB Endpoint 1-3 control registers ENDPTCTRL1-ENDPPTCTRL3 (address 0x190001c4-0x190001cc) */ + +#define USBDEV_ENDPTCTRL_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ +#define USBDEV_ENDPTCTRL_TXR (1 << 22) /* Bit 22: Tx data toggle reset */ +#define USBDEV_ENDPTCTRL_TXI (1 << 21) /* Bit 21: Tx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL_TXT_MASK (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) +# define USBDEV_ENDPTCTRL_TXT_CTRL (0 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_TXT_ISOC (1 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_TXT_BULK (2 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Bulk */ +# define USBDEV_ENDPTCTRL_TXT_INTR (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Interrupt */ +#define USBDEV_ENDPTCTRL_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ +#define USBDEV_ENDPTCTRL_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ +#define USBDEV_ENDPTCTRL_RXR (1 << 6) /* Bit 6: Rx data toggle reset */ +#define USBDEV_ENDPTCTRL_RXI (1 << 5) /* Bit 5: Rx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTRL_RXT_MASK (3 << USBDEV_ENDPTCTRL_RXT_SHIFT) +# define USBDEV_ENDPTCTRL_RXT_CTRL (0 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_RXT_ISOC (1 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_RXT_BULK (2 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Bulk */ +#define USBDEV_ENDPTCTRL_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_USBOTG_H */ diff --git a/arch/arm/src/lpc31xx/lpc31_wdt.h b/arch/arm/src/lpc31xx/lpc31_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..2840b67e446b23f678846eb6327c18791fccdc14 --- /dev/null +++ b/arch/arm/src/lpc31xx/lpc31_wdt.h @@ -0,0 +1,130 @@ +/************************************************************************************************ + * arch/arm/src/lpc31xx/lpc31_wdt.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_WDT_H +#define __ARCH_ARM_SRC_LPC31XX_LPC31_WDT_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "lpc31_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* WDT register base address offset into the APB0 domain ****************************************/ + +#define LPC31_WDT_VBASE (LPC31_APB0_VADDR+LPC31_APB0_WDT_OFFSET) +#define LPC31_WDT_PBASE (LPC31_APB0_PADDR+LPC31_APB0_WDT_OFFSET) + +/* WDT register offsets (with respect to the WDT base) ******************************************/ + +#define LPC31_WDT_IR_OFFSET 0x000 /* Interrupt Register */ +#define LPC31_WDT_TCR_OFFSET 0x004 /* Timer Control Register */ +#define LPC31_WDT_TC_OFFSET 0x008 /* Timer Counter */ +#define LPC31_WDT_PR_OFFSET 0x00c /* Timer Prescale Register */ +#define LPC31_WDT_PC_OFFSET 0x010 /* Prescale Counter */ +#define LPC31_WDT_MCR_OFFSET 0x014 /* Match Control Register */ +#define LPC31_WDT_MR0_OFFSET 0x018 /* Match Register 0 */ +#define LPC31_WDT_MR1_OFFSET 0x01c /* Match Register 1 */ + /* 0x020-0x038: Reserved */ +#define LPC31_WDT_EMR_OFFSET 0x03c /* External Match Register */ + +/* WDT register (virtual) addresses *************************************************************/ + +#define LPC31_WDT_IR (LPC31_WDT_VBASE+LPC31_WDT_IR_OFFSET) +#define LPC31_WDT_TCR (LPC31_WDT_VBASE+LPC31_WDT_TCR_OFFSET) +#define LPC31_WDT_TC (LPC31_WDT_VBASE+LPC31_WDT_TC_OFFSET) +#define LPC31_WDT_PR (LPC31_WDT_VBASE+LPC31_WDT_PR_OFFSET) +#define LPC31_WDT_PC (LPC31_WDT_VBASE+LPC31_WDT_PC_OFFSET) +#define LPC31_WDT_MCR (LPC31_WDT_VBASE+LPC31_WDT_MCR_OFFSET) +#define LPC31_WDT_MR0 (LPC31_WDT_VBASE+LPC31_WDT_MR0_OFFSET) +#define LPC31_WDT_MR1 (LPC31_WDT_VBASE+LPC31_WDT_MR1_OFFSET) +#define LPC31_WDT_EMR (LPC31_WDT_VBASE+LPC31_WDT_EMR_OFFSET) + +/* WDT register bit definitions *****************************************************************/ + +/* Interrupt Register (IR), address 0x13002400 */ + +#define WDT_IR_INTRM1 (1 << 1) /* Bit 1: MR1 and TC match interrupt */ +#define WDT_IR_INTRM0 (1 << 0) /* Bit 0: MR0 and TC match interrupt */ + +/* Timer Control Register (TCR), address 0x13002404 */ + +#define WDT_TCR_RESET (1 << 1) /* Bit 1: Reset on the next WDOG_PCLK */ +#define WDT_TCR_ENABLE (1 << 0) /* Bit 0: Enable */ + +/* Match Control Register (MCR), address 0x1300 2414 */ + +#define WDT_MCR_MR1STOP (1 << 5) /* Bit 5: Stop counting when MR1=TC */ +#define WDT_MCR_MR1RESET (1 << 4) /* Bit 4: Reset TC if MR1=TC */ +#define WDT_MCR_MR1INT (1 << 3) /* Bit 3: System reset when MR1=TC */ +#define WDT_MCR_MR0STOP (1 << 2) /* Bit 2: Stop counting when MR0=TC */ +#define WDT_MCR_MR0RESET (1 << 1) /* Bit 1: Reset TC if MR0=TC */ +#define WDT_MCR_MR0INT (1 << 0) /* Bit 0: System reset when MR0=TC */ + +/* External Match Registers (EMR), address 0x1300 243c */ + +#define WDT_EMR_EXTMATCHCTRL1_SHIFT (6) /* Bits 6-7: Controls EXTMATCH1 when MR1=TC */ +#define WDT_EMR_EXTMATCHCTRL1_MASK (3 << WDT_EMR_EXTMATCHCTRL1_SHIFT) +# define WDT_EMR_EXTMATCHCTRL1_NOTHING (0 << WDT_EMR_EXTMATCHCTRL1_SHIFT) /* Do Nothing */ +# define WDT_EMR_EXTMATCHCTRL1_SETLOW (1 << WDT_EMR_EXTMATCHCTRL1_SHIFT) /* Set LOW */ +# define WDT_EMR_EXTMATCHCTRL1_SETHIGH (2 << WDT_EMR_EXTMATCHCTRL1_SHIFT) /* Set HIGH */ +# define WDT_EMR_EXTMATCHCTRL1_TOGGLE (3 << WDT_EMR_EXTMATCHCTRL1_SHIFT) /* Toggle */ +#define WDT_EMR_EXTMATCHCTRL0_SHIFT (4) /* Bits 4-5: Controls EXTMATCH0 when MR0=TC */ +#define WDT_EMR_EXTMATCHCTRL0_MASK (3 << WDT_EMR_EXTMATCHCTRL0_SHIFT) +# define WDT_EMR_EXTMATCHCTRL0_NOTHING (0 << WDT_EMR_EXTMATCHCTRL0_SHIFT) /* Do Nothing */ +# define WDT_EMR_EXTMATCHCTRL0_SETLOW (1 << WDT_EMR_EXTMATCHCTRL0_SHIFT) /* Set LOW */ +# define WDT_EMR_EXTMATCHCTRL0_SETHIGH (2 << WDT_EMR_EXTMATCHCTRL0_SHIFT) /* Set HIGH */ +# define WDT_EMR_EXTMATCHCTRL0_TOGGLE (3 << WDT_EMR_EXTMATCHCTRL0_SHIFT) /* Toggle */ +#define WDT_EMR_EXTMATCH1 (1 << 1) /* Bit 1: EXTMATCHCTRL1 controls behavior */ +#define WDT_EMR_EXTMATCH0 (1 << 0) /* Bit 0: EXTMATCHCTRL1 controls behavior */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_WDT_H */ diff --git a/arch/arm/src/lpc43xx/Kconfig b/arch/arm/src/lpc43xx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..b0385a9d3c351575265a2d3d43eb6e4b6ca0fc86 --- /dev/null +++ b/arch/arm/src/lpc43xx/Kconfig @@ -0,0 +1,628 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "LPC43xx Configuration Options" + +choice + prompt "LPC43XX Chip Selection" + default ARCH_CHIP_LPC4330FET100 + depends on ARCH_CHIP_LPC43XX + +config ARCH_CHIP_LPC4310FBD144 + bool "LPC4310FBD144" + +config ARCH_CHIP_LPC4310FET100 + bool "LPC4310FET100" + +config ARCH_CHIP_LPC4320FBD144 + bool "LPC4320FBD144" + +config ARCH_CHIP_LPC4320FET100 + bool "LPC4320FET100" + +config ARCH_CHIP_LPC4330FBD144 + bool "LPC4330FBD144" + +config ARCH_CHIP_LPC4330FET100 + bool "LPC4330FET100" + +config ARCH_CHIP_LPC4330FET180 + bool "LPC4330FET180" + +config ARCH_CHIP_LPC4330FET256 + bool "LPC4330FET256" + +config ARCH_CHIP_LPC4337JBD144 + bool "LPC4337JBD144" + +config ARCH_CHIP_LPC4350FBD208 + bool "LPC4350FBD208" + +config ARCH_CHIP_LPC4350FET180 + bool "LPC4350FET180" + +config ARCH_CHIP_LPC4350FET256 + bool "LPC4350FET256" + +config ARCH_CHIP_LPC4353FBD208 + bool "LPC4353FBD208" + +config ARCH_CHIP_LPC4353FET180 + bool "LPC4353FET180" + +config ARCH_CHIP_LPC4353FET256 + bool "LPC4353FET256" + +config ARCH_CHIP_LPC4357FET180 + bool "LPC4357FET180" + +config ARCH_CHIP_LPC4357FBD208 + bool "LPC4357FBD208" + +config ARCH_CHIP_LPC4357FET256 + bool "LPC4357FET256" + +config ARCH_CHIP_LPC4370FET100 + bool "LPC4370FET100" + +endchoice # LPC43XX Chip Selection + +config ARCH_FAMILY_LPC4310 + bool + default y if ARCH_CHIP_LPC4310FBD144 || ARCH_CHIP_LPC4310FET100 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4320 + bool + default y if ARCH_CHIP_LPC4320FBD144 || ARCH_CHIP_LPC4320FET100 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4330 + bool + default y if ARCH_CHIP_LPC4330FBD144 || ARCH_CHIP_LPC4330FET100 || ARCH_CHIP_LPC4330FET180 || ARCH_CHIP_LPC4330FET256 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4337 + bool + default y if ARCH_CHIP_LPC4337JBD144 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4350 + bool + default y if ARCH_CHIP_LPC4350FBD208 || ARCH_CHIP_LPC4350FET180 || ARCH_CHIP_LPC4350FET256 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4353 + bool + default y if ARCH_CHIP_LPC4353FBD208 || ARCH_CHIP_LPC4353FET180 || ARCH_CHIP_LPC4353FET256 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4357 + bool + default y if ARCH_CHIP_LPC4357FET180 || ARCH_CHIP_LPC4357FBD208 || ARCH_CHIP_LPC4357FET256 + select ARCH_HAVE_TICKLESS + +config ARCH_FAMILY_LPC4370 + bool + default y if ARCH_CHIP_LPC4370FET100 + select ARCH_HAVE_TICKLESS + +choice + prompt "LPC43XX Boot Configuration" + default LPC43_BOOT_SRAM + depends on ARCH_CHIP_LPC43XX + ---help--- + The startup code needs to know if the code is running from internal FLASH, + external FLASH, SPIFI, or SRAM in order to initialize properly. Note that + a boot device is not specified for cases where the code is copied into SRAM; + those cases are all covered by LPC43_BOOT_SRAM. + +config LPC43_BOOT_SRAM + bool "Running from SRAM" + +config LPC43_BOOT_SPIFI + bool "Running from QuadFLASH" + +config LPC43_BOOT_FLASHA + bool "Running in internal FLASHA" + +config LPC43_BOOT_FLASHB + bool "Running in internal FLASHA" + +config LPC43_BOOT_CS0FLASH + bool "Running in external FLASH CS0" + +config LPC43_BOOT_CS1FLASH + bool "Running in external FLASH CS1" + +config LPC43_BOOT_CS2FLASH + bool "Running in external FLASH CS2" + +config LPC43_BOOT_CS3FLASH + bool "Running in external FLASH CS3" + +endchoice # LPC43XX Boot Configuration + +menu "LPC43xx Peripheral Support" + +config LPC43_ADC0 + bool "ADC0" + default n + +config LPC43_ADC1 + bool "ADC1" + default n + +config LPC43_ATIMER + bool "Alarm timer" + default n + +config LPC43_CAN1 + bool "C_CAN1" + default n + +config LPC43_CAN2 + bool "C_CAN1" + default n + +config LPC43_DAC + bool "DAC" + default n + +config LPC43_EMC + bool "External Memory Controller (EMC)" + default n + +config LPC43_ETHERNET + bool "Ethernet" + default n + +config LPC43_EVNTMNTR + bool "Event Monitor" + default n + +config LPC43_GPDMA + bool "GPDMA" + default n + +config LPC43_I2C0 + bool "I2C0" + default n + +config LPC43_I2C1 + bool "I2C1" + default n + +config LPC43_I2S0 + bool "I2S0" + default n + +config LPC43_I2S1 + bool "I2S1" + default n + +config LPC43_LCD + bool "LCD" + default n + +config LPC43_MCPWM + bool "Motor Control PWM (MCPWM)" + default n + +config LPC43_QEI + bool "Quadrature Controller Interface (QEI)" + default n + +config LPC43_RIT + bool "Repetitive Interrupt Timer (RIT)" + default n + +config LPC43_RIT_RES + int "Interrupt schedule resolution (nS)" + default 250 + depends on LPC43_RIT + +config LPC43_RTC + bool "Real Time Clock (RTC)" + default n + +config LPC43_SCT + bool "State Configurable Timer (SCT)" + default n + +config LPC43_SDMMC + bool "SD/MMC" + default n + +config LPC43_SPI + bool "SPI" + default n + +config LPC43_SPIFI + bool "SPI Flash Interface (SPIFI)" + default n + +config LPC43_SSP0 + bool "SSP0" + default n + +config LPC43_SSP1 + bool "SSP1" + default n + +config LPC43_TMR0 + bool "ADC1" + default n + +config LPC43_TMR1 + bool "Timer 1" + default n + +config LPC43_TMR2 + bool "Timer 2" + default n + +config LPC43_TMR3 + bool "Timer 3" + default n + +config LPC43_USART0 + bool "USART0" + default n + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC43_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC43_USART2 + bool "USART2" + default n + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC43_USART3 + bool "USART3" + default n + select ARCH_HAVE_USART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config LPC43_USBOTG + bool "USB EHCI" + default n + select USBHOST_HAVE_ASYNCH + +config LPC43_USB0 + bool "USB0" + default n + +config LPC43_USB1 + bool "USB1" + default n + +config LPC43_WWDT + bool "Windowing Watchdog Timer (WWDT)" + default n + +endmenu # LPC43xx Peripheral Support + +if LPC43_ETHERNET +menu "Ethernet MAC configuration" + +config LPC43_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config LPC43_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + LPC43_PHYINIT is defined in the configuration then the board specific logic must + provide lpc43_phyinitialize(); The LPC43 Ethernet driver will call this function + one time before it first uses the PHY. + +config LPC43_MII + bool "Use MII interface" + default n + ---help--- + Support Ethernet MII interface. + +config LPC43_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config LPC43_ETHFD + bool "Full duplex" + default n + depends on !LPC43_AUTONEG + ---help--- + If LPC43_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config LPC43_ETH100MBPS + bool "100 Mbps" + default n + depends on !LPC43_AUTONEG + ---help--- + If LPC43_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config LPC43_PHYSR + int "PHY Status Register Address (decimal)" + depends on LPC43_AUTONEG + ---help--- + This must be provided if LPC43_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config LPC43_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on LPC43_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +config LPC43_PHYSR_SPEED + hex "PHY Speed Mask" + depends on LPC43_AUTONEG && !LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config LPC43_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + depends on LPC43_AUTONEG && !LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config LPC43_PHYSR_MODE + hex "PHY Mode Mask" + depends on LPC43_AUTONEG && !LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config LPC43_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + depends on LPC43_AUTONEG && !LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +config LPC43_PHYSR_ALTMODE + hex "PHY Mode Mask" + depends on LPC43_AUTONEG && LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config LPC43_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + depends on LPC43_AUTONEG && LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config LPC43_PHYSR_100HD + hex "100Base-T Half Duplex Value" + depends on LPC43_AUTONEG && LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config LPC43_PHYSR_10FD + hex "10Base-T Full Duplex Value" + depends on LPC43_AUTONEG && LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config LPC43_PHYSR_100FD + hex "100Base-T Full Duplex Value" + depends on LPC43_AUTONEG && LPC43_PHYSR_ALTCONFIG + ---help--- + This must be provided if LPC43_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +config LPC43_RMII + bool + default y if !LPC43_MII + +config LPC43_ETHERNET_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # Ethernet MAC configuration +endif # LPC43_ETHERNET + +menu "RS-485 Configuration" +if LPC43_USART0 + +config USART0_RS485MODE + bool "RS-485 on USART0" + default n + ---help--- + Enable RS-485 interface on USART0. + +config USART0_RS485_DTRDIR + bool "USART0 DTR for DIR" + default n + ---help--- + Use the USART DTR pin for the DIR pin + +endif # LPC43_USART0 + +if LPC43_UART1 + +config UART1_RS485MODE + bool "RS-485 on UART1" + default n + ---help--- + Enable RS-485 interface on USRT1. + +config UART1_RS485_DTRDIR + bool "UART1 DTR for DIR" + default n + ---help--- + Use the UART DTR pin for the DIR pin + +endif # LPC43_USART0 + +if LPC43_USART2 + +config USART2_RS485MODE + bool "RS-485 on USART2" + default n + ---help--- + Enable RS-485 interface on USART2. + +config USART2_RS485_DTRDIR + bool "USART2 DTR for DIR" + default n + ---help--- + Use the USART DTR pin for the DIR pin + +endif # LPC43_USART2 + +if LPC43_USART3 + +config USART3_RS485MODE + bool "RS-485 on USART3" + default n + ---help--- + Enable RS-485 interface on USART3. + +config USART3_RS485_DTRDIR + bool "USART3 DTR for DIR" + default n + ---help--- + Use the USART DTR pin for the DIR pin + +endif # LPC43_USART3 +endmenu # RS-485 Configuration + +if LPC43_I2C0 +menu "I2C Configution" + +config LPC43_I2C0_SUPERFAST + bool "I2C0 super fast mode" + default n + depends on LPC43_I2C0 + +endmenu # I2C Configution +endif # LPC43_I2C0 + +if LPC43_USBOTG && USBHOST +menu "USB host controller driver (HCD) options" + +config LPC43_EHCI_NQHS + int "Number of Queue Head (QH) structures" + default 4 + ---help--- + Configurable number of Queue Head (QH) structures. The default is + one per Root hub port plus one for EP0 (4). + +config LPC43_EHCI_NQTDS + int "Number of Queue Element Transfer Descriptor (qTDs)" + default 6 + ---help--- + Configurable number of Queue Element Transfer Descriptor (qTDs). + The default is one per root hub plus three from EP0 (6). + +config LPC43_EHCI_BUFSIZE + int "Size of one request/descriptor buffer" + default 128 + ---help--- + The size of one request/descriptor buffer in bytes. The TD buffe + size must be an even number of 32-bit words and must be large enough + to hangle the largest transfer via a SETUP request. + +config LPC43_EHCI_PREALLOCATE + bool "Preallocate descriptor pool" + default y + ---help--- + Select this option to pre-allocate EHCI queue and descriptor + structure pools in .bss. Otherwise, these pools will be + dynamically allocated using kmm_memalign(). + +endmenu # USB host controller driver (HCD) options +endif # LPC43_USBOTG && USBHOST + +if LPC43_USBOTG && USBHOST + +menu "USB host controller driver (HCD) options" + +config LPC43_EHCI_NQHS + int "Number of Queue Head (QH) structures" + default 4 + ---help--- + Configurable number of Queue Head (QH) structures. The default is + one per Root hub port plus one for EP0 (4). + +config LPC43_EHCI_NQTDS + int "Number of Queue Element Transfer Descriptor (qTDs)" + default 6 + ---help--- + Configurable number of Queue Element Transfer Descriptor (qTDs). + The default is one per root hub plus three from EP0 (6). + +config LPC43_EHCI_BUFSIZE + int "Size of one request/descriptor buffer" + default 128 + ---help--- + The size of one request/descriptor buffer in bytes. The TD buffe + size must be an even number of 32-bit words and must be large enough + to hangle the largest transfer via a SETUP request. + +config LPC43_EHCI_PREALLOCATE + bool "Preallocate descriptor pool" + default y + ---help--- + Select this option to pre-allocate EHCI queue and descriptor + structure pools in .bss. Otherwise, these pools will be + dynamically allocated using kmm_memalign(). + +endmenu # USB host controller driver (HCD) options +endif # LPC43_USBOTG && USBHOST + +if LPC43_USB0 || LPC43_USB1 + +menu "USB device controller driver (DCD) options" + +config LPC43_USB0DEV_NOVBUS + bool "No USB0 VBUS sensing" + default n + depends on LPC43_USB0 && USBDEV + +config LPC43_USB1_ULPI + bool "USB1 with ULPI" + default n + depends on LPC43_USB1 + +config LPC43_USB1DEV_NOVBUS + bool "No USB1 VBUS sensing" + default n + depends on LPC43_USB1 && USBDEV + +endmenu # USB device controller driver (DCD) options +endif # LPC43_USB0 || LPC43_USB1 diff --git a/arch/arm/src/lpc43xx/Make.defs b/arch/arm/src/lpc43xx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..2ec9699554535345ba5d93231f271eaf47c89cd5 --- /dev/null +++ b/arch/arm/src/lpc43xx/Make.defs @@ -0,0 +1,191 @@ +############################################################################ +# arch/arm/src/lpc43xx/Make.defs +# +# Copyright (C) 2012-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c +CMN_CSRCS += up_svcall.c up_vfork.c + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +CHIP_ASRCS = +CHIP_CSRCS = lpc43_allocateheap.c lpc43_cgu.c lpc43_clrpend.c lpc43_gpio.c +CHIP_CSRCS += lpc43_irq.c lpc43_pinconfig.c lpc43_rgu.c lpc43_serial.c +CHIP_CSRCS += lpc43_start.c lpc43_uart.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += lpc43_timerisr.c +else +CHIP_CSRCS += lpc43_tickless_rit.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += lpc43_userspace.c lpc43_mpuinit.c +endif + +ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += lpc43_idle.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += lpc43_debug.c +endif + +ifeq ($(CONFIG_LPC43_GPDMA),y) +CHIP_CSRCS += lpc43_gpdma.c +endif + +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += lpc43_gpioint.c +endif + +ifeq ($(CONFIG_LPC43_ETHERNET),y) +CHIP_CSRCS += lpc43_ethernet.c +endif + +ifeq ($(CONFIG_LPC43_SPI),y) +CHIP_CSRCS += lpc43_spi.c +else +ifeq ($(CONFIG_LPC43_SSP0),y) +CHIP_CSRCS += lpc43_spi.c +else +ifeq ($(CONFIG_LPC43_SSP1),y) +CHIP_CSRCS += lpc43_spi.c +endif +endif +endif + +ifeq ($(CONFIG_LPC43_SPIFI),y) +CHIP_CSRCS += lpc43_spifi.c +endif + +ifeq ($(CONFIG_LPC43_SSP0),y) +CHIP_CSRCS += lpc43_ssp.c +else +ifeq ($(CONFIG_LPC43_SSP1),y) +CHIP_CSRCS += lpc43_ssp.c +endif +endif + +ifeq ($(CONFIG_LPC43_RIT),y) +CHIP_CSRCS += lpc43_rit.c +endif + +ifeq ($(CONFIG_LPC43_I2C0),y) +CHIP_CSRCS += lpc43_i2c.c +else +ifeq ($(CONFIG_LPC43_I2C1),y) +CHIP_CSRCS += lpc43_i2c.c +endif +endif + +ifeq ($(CONFIG_LPC43_ADC0),y) +CHIP_CSRCS += lpc43_adc.c +else +ifeq ($(CONFIG_LPC43_ADC1),y) +CHIP_CSRCS += lpc43_adc.c +endif +endif + +ifeq ($(CONFIG_LPC43_DAC),y) +CHIP_CSRCS += lpc43_adc.c +else +ifeq ($(CONFIG_LPC43_DAC),y) +CHIP_CSRCS += lpc43_adc.c +endif +endif + +ifeq ($(CONFIG_LPC43_USBOTG),y) +CHIP_CSRCS += lpc43_ehci.c +endif + +ifeq ($(CONFIG_LPC43_USB0),y) +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += lpc43_usb0dev.c +endif +endif + +-include chip/spifi/src/Make.defs \ No newline at end of file diff --git a/arch/arm/src/lpc43xx/chip.h b/arch/arm/src/lpc43xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..08ef7217a5297f5c6f53262b4086b368afac922c --- /dev/null +++ b/arch/arm/src/lpc43xx/chip.h @@ -0,0 +1,164 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip.h + * + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* For each chip supported in chip.h, the following are provided to customize the + * environment for the specific LPC43XX chip: + * + * Define ARMV7M_PERIPHERAL_INTERRUPTS - This is needed by common/up_vectors.c. This + * definition provides the number of "external" interrupt vectors supported by + * the specific LPC43 chip. + * + * For the Cortex-M3 core, this should always be equal to the value + * LPC43M4_IRQ_NEXTINT defined in include/lpc43xx/irq.h. For the Cortex-M0 + * core, this should always be equal to the value LPC43M0_IRQ_NEXTINT defined + * in include/lpc43xx/irq.h (At present, only the Cortex-M4 core is supported) + * + * Include the chip-specific memory map header file, and + * Include the chip-specific pin configuration. + * + * These header files may or may not be shared between different chips. That decisions + * depends on the similarity of the chip peripheral. + */ + +#if defined(CONFIG_ARCH_CHIP_LPC4310FBD144) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4310FET100) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4320FBD144) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4320FET100) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4330FBD144) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET100) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET180) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4330FET256) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4337JBD144) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4357fet256_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4350FBD208) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4350FET180) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4350FET256) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc4310203050_memorymap.h" +# include "chip/lpc4310203050_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4353FBD208) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4353fbd208_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4353FET180) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4353fet180_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4353FET256) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4353fet256_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4357FET180) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4357fet180_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4357FBD208) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4357fbd208_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4357FET256) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4357fet256_pinconfig.h" +#elif defined(CONFIG_ARCH_CHIP_LPC4370FET100) +# define ARMV7M_PERIPHERAL_INTERRUPTS 53 +# include "chip/lpc435357_memorymap.h" +# include "chip/lpc4357fet256_pinconfig.h" +#else +# error "Unsupported LPC43xx chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h b/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..33de4577d275ca7aa1a068314e3e7eb1d7c51372 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h @@ -0,0 +1,196 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc4310203050_memorymap.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ +/* See arch/arm/include/lpc43xx/chip.h for the actual sizes of FLASH and SRAM + * regions + */ + +#define LPC43_SHADOW_BASE 0x00000000 /* -0x0fffffff: 256Mb shadow area */ +#define LPC43_LOCSRAM_BASE 0x10000000 /* -0x1fffffff: Local SRAM and external memory */ +#define LPC43_AHBSRAM_BASE 0x20000000 /* -0x27ffffff: AHB SRAM */ +#define LPC43_DYCS0_BASE 0x28000000 /* -0x2fffffff: 128Mb dynamic external memory */ +#define LPC43_DYCS1_BASE 0x30000000 /* -0x2fffffff: 256Mb dynamic external memory */ +#define LPC43_PERIPH_BASE 0x40000000 /* -0x5fffffff: Peripherals */ +#define LPC43_DYCS2_BASE 0x60000000 /* -0x6fffffff: 256Mb dynamic external memory */ +#define LPC43_DYCS3_BASE 0x70000000 /* -0x7fffffff: 256Mb dynamic external memory */ +#define LPC43_SPIFI_DATA_BASE 0x80000000 /* -0x87ffffff: 256Mb dynamic external memory */ +#define LPC43_ARM_BASE 0xe0000000 /* -0xe00fffff: ARM private */ + +/* Local SRAM Banks and external memory */ + +#define LPC43_LOCSRAM_BANK0_BASE (LPC43_LOCSRAM_BASE + 0x00000000) +#define LPC43_LOCSRAM_BANK1_BASE (LPC43_LOCSRAM_BASE + 0x00080000) +#define LPC43_ROM_BASE (LPC43_LOCSRAM_BASE + 0x00400000) +#define LPC43_LOCSRAM_SPIFI_BASE (LPC43_LOCSRAM_BASE + 0x04000000) +#define LPC43_EXTMEM_CS0_BASE (LPC43_LOCSRAM_BASE + 0x0c000000) +#define LPC43_EXTMEM_CS1_BASE (LPC43_LOCSRAM_BASE + 0x0d000000) +#define LPC43_EXTMEM_CS2_BASE (LPC43_LOCSRAM_BASE + 0x0e000000) +#define LPC43_EXTMEM_CS3_BASE (LPC43_LOCSRAM_BASE + 0x0f000000) + +/* ROM Driver Table */ + +#define LPC43_ROM_DRIVER_TABLE (LPC43_ROM_BASE+0x00000100) +#define LPC43_ROM_DRIVER_TABLE0 (LPC43_ROM_DRIVER_TABLE+0x0000) +#define LPC43_ROM_DRIVER_TABLE1 (LPC43_ROM_DRIVER_TABLE+0x0004) +#define LPC43_ROM_DRIVER_TABLE2 (LPC43_ROM_DRIVER_TABLE+0x0008) +#define LPC43_ROM_DRIVER_TABLE3 (LPC43_ROM_DRIVER_TABLE+0x000c) +#define LPC43_ROM_DRIVER_TABLE4 (LPC43_ROM_DRIVER_TABLE+0x0010) +#define LPC43_ROM_DRIVER_TABLE5 (LPC43_ROM_DRIVER_TABLE+0x0014) +#define LPC43_ROM_DRIVER_TABLE6 (LPC43_ROM_DRIVER_TABLE+0x0018) +#define LPC43_ROM_DRIVER_TABLE7 (LPC43_ROM_DRIVER_TABLE+0x001c) + +/* AHB SRAM */ + +#define LPC43_AHBSRAM_BANK0_BASE (LPC43_AHBSRAM_BASE) +#define LPC43_AHBSRAM_BANK1_BASE (LPC43_AHBSRAM_BASE + 0x00008000) +#define LPC43_AHBSRAM_BANK2_BASE (LPC43_AHBSRAM_BASE + 0x0000c000) +#define LPC43_AHBSRAM_BITBAND_BASE (LPC43_AHBSRAM_BASE + 0x0000c000) + +/* Peripherals */ + +#define LPC43_AHBPERIPH_BASE (LPC43_PERIPH_BASE + 0x00000000) +#define LPC43_RTCPERIPH_BASE (LPC43_PERIPH_BASE + 0x00040000) +#define LPC43_CLKPERIPH_BASE (LPC43_PERIPH_BASE + 0x00050000) +#define LPC43_APB0PERIPH_BASE (LPC43_PERIPH_BASE + 0x00080000) +#define LPC43_APB1PERIPH_BASE (LPC43_PERIPH_BASE + 0x000a0000) +#define LPC43_APB2PERIPH_BASE (LPC43_PERIPH_BASE + 0x000c0000) +#define LPC43_APB3PERIPH_BASE (LPC43_PERIPH_BASE + 0x000e0000) +#define LPC43_GPIO_BASE (LPC43_PERIPH_BASE + 0x000f4000) +#define LPC43_SPI_BASE (LPC43_PERIPH_BASE + 0x00100000) +#define LPC43_SGPIO_BASE (LPC43_PERIPH_BASE + 0x00101000) +#define LPC43_PERIPH_BITBAND_BASE (LPC43_PERIPH_BASE + 0x02000000) + +/* AHB Peripherals */ + +#define LPC43_SCT_BASE (LPC43_AHBPERIPH_BASE + 0x00000000) +#define LPC43_DMA_BASE (LPC43_AHBPERIPH_BASE + 0x00002000) +#define LPC43_SPIFI_BASE (LPC43_AHBPERIPH_BASE + 0x00003000) +#define LPC43_SDMMC_BASE (LPC43_AHBPERIPH_BASE + 0x00004000) +#define LPC43_EMC_BASE (LPC43_AHBPERIPH_BASE + 0x00005000) +#define LPC43_USB0_BASE (LPC43_AHBPERIPH_BASE + 0x00006000) +#define LPC43_USB1_BASE (LPC43_AHBPERIPH_BASE + 0x00007000) +#define LPC43_LCD_BASE (LPC43_AHBPERIPH_BASE + 0x00008000) +#define LPC43_ETHERNET_BASE (LPC43_AHBPERIPH_BASE + 0x00010000) + +/* RTC Domain Peripherals */ + +#define LPC43_ATIMER_BASE (LPC43_RTCPERIPH_BASE + 0x00000000) +#define LPC43_BACKUP_BASE (LPC43_RTCPERIPH_BASE + 0x00001000) +#define LPC43_PMC_BASE (LPC43_RTCPERIPH_BASE + 0x00002000) +#define LPC43_CREG_BASE (LPC43_RTCPERIPH_BASE + 0x00003000) +#define LPC43_EVNTRTR_BASE (LPC43_RTCPERIPH_BASE + 0x00004000) +#define LPC43_OTPC_BASE (LPC43_RTCPERIPH_BASE + 0x00005000) +#define LPC43_RTC_BASE (LPC43_RTCPERIPH_BASE + 0x00006000) +#define LPC43_EVNTMNTR_BASE (LPC43_RTC_BASE + 0x00000080) + +/* Clocking and Reset Peripherals */ + +#define LPC43_CGU_BASE (LPC43_CLKPERIPH_BASE + 0x00000000) +#define LPC43_CCU1_BASE (LPC43_CLKPERIPH_BASE + 0x00001000) +#define LPC43_CCU2_BASE (LPC43_CLKPERIPH_BASE + 0x00002000) +#define LPC43_RGU_BASE (LPC43_CLKPERIPH_BASE + 0x00003000) + +/* APB0 Peripherals */ + +#define LPC43_WWDT_BASE (LPC43_APB0PERIPH_BASE + 0x00000000) +#define LPC43_USART0_BASE (LPC43_APB0PERIPH_BASE + 0x00001000) +#define LPC43_UART1_BASE (LPC43_APB0PERIPH_BASE + 0x00002000) +#define LPC43_SSP0_BASE (LPC43_APB0PERIPH_BASE + 0x00003000) +#define LPC43_TIMER0_BASE (LPC43_APB0PERIPH_BASE + 0x00004000) +#define LPC43_TIMER1_BASE (LPC43_APB0PERIPH_BASE + 0x00005000) +#define LPC43_SCU_BASE (LPC43_APB0PERIPH_BASE + 0x00006000) +#define LPC43_GPIOINT_BASE (LPC43_APB0PERIPH_BASE + 0x00007000) +#define LPC43_GRP0INT_BASE (LPC43_APB0PERIPH_BASE + 0x00008000) +#define LPC43_GRP1INT_BASE (LPC43_APB0PERIPH_BASE + 0x00009000) + +/* APB1 Peripherals */ + +#define LPC43_MCPWM_BASE (LPC43_APB1PERIPH_BASE + 0x00000000) +#define LPC43_I2C0_BASE (LPC43_APB1PERIPH_BASE + 0x00001000) +#define LPC43_I2S0_BASE (LPC43_APB1PERIPH_BASE + 0x00002000) +#define LPC43_I2S1_BASE (LPC43_APB1PERIPH_BASE + 0x00003000) +#define LPC43_CAN1_BASE (LPC43_APB1PERIPH_BASE + 0x00004000) + +/* APB2 Peripherals */ + +#define LPC43_RIT_BASE (LPC43_APB2PERIPH_BASE + 0x00000000) +#define LPC43_USART2_BASE (LPC43_APB2PERIPH_BASE + 0x00001000) +#define LPC43_USART3_BASE (LPC43_APB2PERIPH_BASE + 0x00002000) +#define LPC43_TIMER2_BASE (LPC43_APB2PERIPH_BASE + 0x00003000) +#define LPC43_TIMER3_BASE (LPC43_APB2PERIPH_BASE + 0x00004000) +#define LPC43_SSP1_BASE (LPC43_APB2PERIPH_BASE + 0x00005000) +#define LPC43_QEI_BASE (LPC43_APB2PERIPH_BASE + 0x00006000) +#define LPC43_GIMA_BASE (LPC43_APB2PERIPH_BASE + 0x00007000) + +/* APB3 Peripherals */ + +#define LPC43_I2C1_BASE (LPC43_APB3PERIPH_BASE + 0x00000000) +#define LPC43_DAC_BASE (LPC43_APB3PERIPH_BASE + 0x00001000) +#define LPC43_CAN0_BASE (LPC43_APB3PERIPH_BASE + 0x00002000) +#define LPC43_ADC0_BASE (LPC43_APB3PERIPH_BASE + 0x00003000) +#define LPC43_ADC1_BASE (LPC43_APB3PERIPH_BASE + 0x00004000) + +/* ARM Private */ + +#define LPC43_SCS_BASE (LPC43_ARM_BASE + 0x0000e000) +#define LPC43_DEBUGMCU_BASE (LPC43_ARM_BASE + 0x00042000) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h b/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..708ecfa8624c05f05d5485d019e9de28691828c0 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h @@ -0,0 +1,984 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_PINCONF_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_PINCONF_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* NOTES: + * + * 1. These settings were taken from the LPC43_10_20_30_50 data sheet and may not be applicable to + * any other family members. + * + * 2. Settings taken from the data sheet include only function, pin set, and pin number. Additional + * settings must be verfied before using these pin configurations (like pull-ups, open-drain, + * drive strength, input buffering, etc.). + * + * 3. Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, + * however, will use the pin selection without the numeric suffix. Additional definitions are + * required in the board.h file to select between the alternative pins. For example, if CAN1_RD + * connects via Pins1[18], then the following definition should appear inthe board.h header file + * for that board: + * + * 4. For ADC pins (PINCONF_ADCNpM), the pin must first be configured configured as a GPIO input. + * Then SCU's ADC function select register can be used to select the ADC. + * + * #define PINCONF_CAN1_RD PINCONF_CAN1_RD_1 + * + * The driver will then automatically configre Pins1[18] as the CAN1 RD pin. + */ + +#define PINCONF_ADC0p0 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_ADC0p1 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_ADC0p2 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_ADC0p3 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_ADC0p4 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_ADC0p5 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_ADC0p6 (PINCONF_FUNC0|PINCONF_PINSB|PINCONF_PIN_6) + +#define PINCONF_ADC1p0 (PINCONF_FUNC4|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_ADC1p1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_ADC1p2 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_ADC1p3 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_ADC1p4 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_ADC1p5 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_ADC1p6 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_ADC1p7 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_7) + +#define PINCONF_ADCTRIG0 (PINCONF_FUNC0|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_ADCTRIG1_1 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_ADCTRIG1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_5) + +#define PINCONF_CAN0_RD_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_CAN0_RD_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_CAN0_TD_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_CAN0_TD_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_2) + +#define PINCONF_CAN1_RD_1 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_CAN1_RD_2 (PINCONF_FUNC5|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_CAN1_RD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_CAN1_TD_1 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_CAN1_TD_2 (PINCONF_FUNC5|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_CAN1_TD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_8) + +#define PINCONF_CGU_OUT0 (PINCONF_FUNC6|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_CGU_OUT1_1 (PINCONF_FUNC4|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_CGU_OUT1_2 (PINCONF_FUNC6|PINCONF_PINSA|PINCONF_PIN_0) + +#define PINCONF_CLKOUT (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_19) + +#define PINCONF_CTIN0_1 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_CTIN0_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_CTIN1_1 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_CTIN1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_CTIN2_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_CTIN2_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_CTIN2_3 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_CTIN3_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_CTIN3_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_CTIN3_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_CTIN4_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_CTIN4_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_CTIN4_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_CTIN5_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_CTIN5_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_CTIN5_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_CTIN5_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_CTIN6_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_CTIN6_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_CTIN6_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_CTIN6_4 (PINCONF_FUNC5|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_CTIN6_5 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_CTIN7_1 (PINCONF_FUNC5|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_CTIN7_2 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_5) + +#define PINCONF_CTOUT0_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_CTOUT0_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_CTOUT0_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_CTOUT1_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_CTOUT1_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_CTOUT1_3 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_CTOUT2_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_CTOUT2_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_CTOUT2_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_CTOUT3_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_CTOUT3_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_CTOUT3_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_CTOUT4_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_CTOUT4_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_CTOUT4_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_CTOUT5_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_CTOUT5_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_CTOUT5_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_CTOUT6_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_CTOUT6_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_CTOUT6_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_CTOUT6_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_CTOUT7_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_CTOUT7_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_CTOUT7_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_CTOUT7_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_CTOUT8_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_CTOUT8_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_CTOUT8_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_CTOUT8_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_CTOUT8_5 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_CTOUT9_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_CTOUT9_2 (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_CTOUT9_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_CTOUT10_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_CTOUT10_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_CTOUT10_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_CTOUT10_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_CTOUT11_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_CTOUT11_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_CTOUT11_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_CTOUT11_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_CTOUT12_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_CTOUT12_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_CTOUT12_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_CTOUT12_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_CTOUT13_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_CTOUT13_2 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_CTOUT13_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_CTOUT13_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_CTOUT14_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_CTOUT14_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_CTOUT14_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_CTOUT14_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_CTOUT15_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_CTOUT15_2 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_CTOUT15_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_11) + +#define PINCONF_EMC_A0 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_EMC_A1 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_EMC_A2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_EMC_A3 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_EMC_A4 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_EMC_A5 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_EMC_A6 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_EMC_A7 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_EMC_A8 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_EMC_A9 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_EMC_A10 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_EMC_A11 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_EMC_A12 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_EMC_A13 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_EMC_A14 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_EMC_A15 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_EMC_A16 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_EMC_A17 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_EMC_A18 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_EMC_A19 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_EMC_A20 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_EMC_A21 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_EMC_A22 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_EMC_A23 (PINCONF_FUNC3|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_EMC_BLS0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_EMC_BLS1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_EMC_BLS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_EMC_BLS3 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_EMC_CAS (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_EMC_CKEOUT0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_11) +#define PINCONF_EMC_CKEOUT1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_EMC_CKEOUT2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_EMC_CKEOUT3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_EMC_CS0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_EMC_CS1 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_EMC_CS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_EMC_CS3 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_EMC_D0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_EMC_D1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_EMC_D2 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_EMC_D3 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_EMC_D4 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_EMC_D5 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_EMC_D6 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_EMC_D7 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_EMC_D8 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_EMC_D9 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_EMC_D10 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_EMC_D11 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_EMC_D12 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_EMC_D13 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_EMC_D14 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_EMC_D15 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_EMC_D16 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_EMC_D17 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_EMC_D18 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_EMC_D19 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_EMC_D20 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_EMC_D21 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_EMC_D22 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_EMC_D23 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_EMC_D24 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_EMC_D25 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_EMC_D26 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_EMC_D27 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_EMC_D28 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_EMC_D29 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_EMC_D30 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_EMC_D31 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_EMC_DQMOUT0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_EMC_DQMOUT1 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_EMC_DQMOUT2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_EMC_DQMOUT3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_EMC_DYCS0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_EMC_DYCS1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_EMC_DYCS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_EMC_DYCS3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_14) +#define PINCONF_EMC_OE (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_EMC_RAS (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_EMC_WE (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_6) + +#define PINCONF_ENET_COL_1 (PINCONF_FUNC2|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_ENET_COL_2 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_ENET_COL_3 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_ENET_CRS_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_ENET_CRS_2 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_ENET_MDC_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_ENET_MDC_2 (PINCONF_FUNC6|PINCONF_SLEW_FAST|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_ENET_MDC_3 (PINCONF_FUNC7|PINCONF_SLEW_FAST|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_ENET_MDIO (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_ENET_REF_CLK (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_ENET_RXD0 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_ENET_RXD1 (PINCONF_FUNC2|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_ENET_RXD2_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_ENET_RXD2_2 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_ENET_RXD3_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_ENET_RXD3_2 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_ENET_RX_CLK (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_ENET_RX_DV_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_ENET_RX_DV_2 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_ENET_RX_ER_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_ENET_RX_ER_2 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_ENET_TXD0 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_ENET_TXD1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_ENET_TXD2_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_ENET_TXD2_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_ENET_TXD3_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_ENET_TXD3_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_ENET_TXEN (PINCONF_FUNC6|PINCONF_SLEW_FAST|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_ENET_TX_CLK (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_ENET_TX_EN (PINCONF_FUNC3|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_ENET_TX_ER_1 (PINCONF_FUNC3|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_ENET_TX_ER_2 (PINCONF_FUNC6|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_SLEW_FAST|PINCONF_PINSC|PINCONF_PIN_14) + +#define PINCONF_GPIO0p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_GPIO0p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_GPIO0p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_GPIO0p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_GPIO0p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_GPIO0p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_GPIO0p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_GPIO0p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_GPIO0p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_GPIO0p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_GPIO0p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_GPIO0p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_GPIO0p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_GPIO0p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_GPIO0p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_GPIO0p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_GPIO1p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_GPIO1p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_GPIO1p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_GPIO1p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_GPIO1p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_GPIO1p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_GPIO1p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_GPIO1p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_GPIO1p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_GPIO1p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_GPIO1p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_GPIO1p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_GPIO1p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_GPIO1p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_GPIO1p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_GPIO1p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_GPIO2p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_GPIO2p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_GPIO2p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_GPIO2p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_GPIO2p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_GPIO2p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_GPIO2p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_GPIO2p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_GPIO2p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_GPIO2p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_GPIO2p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_GPIO2p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_GPIO2p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_GPIO2p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_GPIO2p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_GPIO2p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_GPIO3p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_GPIO3p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_GPIO3p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_GPIO3p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_GPIO3p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_GPIO3p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_GPIO3p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_GPIO3p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_11) +#define PINCONF_GPIO3p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_GPIO3p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_GPIO3p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_GPIO3p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_GPIO3p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_GPIO3p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_GPIO3p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_GPIO3p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_GPIO4p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_GPIO4p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_GPIO4p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_GPIO4p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_GPIO4p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_GPIO4p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_GPIO4p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_GPIO4p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_GPIO4p8 (PINCONF_FUNC0|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_GPIO4p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_2) +#define PINCONF_GPIO4p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_3) +#define PINCONF_GPIO4p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_GPIO4p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_GPIO4p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_GPIO4p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_GPIO4p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_GPIO5p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_GPIO5p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_GPIO5p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_GPIO5p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_GPIO5p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_GPIO5p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_GPIO5p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_GPIO5p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_GPIO5p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_GPIO5p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_GPIO5p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_GPIO5p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_GPIO5p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_GPIO5p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_GPIO5p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_GPIO5p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_GPIO5p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_GPIO5p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_GPIO5p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_GPIO5p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_GPIO5p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_GPIO5p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_GPIO5p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_GPIO5p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_GPIO5p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_GPIO5p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_GPIO5p26 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_GPIO6p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_GPIO6p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_GPIO6p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_GPIO6p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_GPIO6p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_GPIO6p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_GPIO6p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_GPIO6p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_GPIO6p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_GPIO6p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_GPIO6p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_GPIO6p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_GPIO6p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_GPIO6p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_GPIO6p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_GPIO6p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_GPIO6p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_GPIO6p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_GPIO6p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_GPIO6p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_GPIO6p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_GPIO6p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_GPIO6p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_GPIO6p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_GPIO6p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_GPIO6p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_GPIO6p26 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_GPIO6p27 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_GPIO6p28 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_GPIO6p29 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_GPIO6p30 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_GPIO7p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_GPIO7p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_GPIO7p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_GPIO7p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_GPIO7p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_GPIO7p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_GPIO7p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_GPIO7p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_GPIO7p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_GPIO7p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_GPIO7p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_GPIO7p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_GPIO7p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_GPIO7p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_GPIO7p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_14) +#define PINCONF_GPIO7p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_GPIO7p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_GPIO7p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_GPIO7p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_GPIO7p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_GPIO7p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_GPIO7p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_GPIO7p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_GPIO7p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_GPIO7p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_GPIO7p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_11) + +#define PINCONF_GP_CLKIN_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_GP_CLKIN_2 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_GP_CLKIN_3 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_4) + +#define PINCONF_I2C1_SCL_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_I2C1_SCL_2 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_I2C1_SDA_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_I2C1_SDA_2 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_13) + +#define PINCONF_I2S0_RX_MCLK_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_MCLK_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_MCLK_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_I2S0_RX_SCK_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_SCK_2 (PINCONF_FUNC4|PINCONF_PINS6|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_SCK_3 (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_I2S0_RX_SDA_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_I2S0_RX_SDA_2 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_I2S0_RX_WS_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_I2S0_RX_WS_2 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_I2S0_TXWS (PINCONF_FUNC6|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_MCLK_1 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_MCLK_2 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_I2S0_TX_MCLK_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_I2S0_TX_SCK_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_SCK_2 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_I2S0_TX_SDA_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_2 (PINCONF_FUNC2|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_3 (PINCONF_FUNC4|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_I2S0_TX_SDA_5 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_I2S0_TX_WS_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_2 (PINCONF_FUNC2|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_3 (PINCONF_FUNC4|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_I2S0_TX_WS_5 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_13) + +#define PINCONF_I2S1_RX_MCLK (PINCONF_FUNC5|PINCONF_PINSA|PINCONF_PIN_0) +#define PINCONF_I2S1_RX_SDA (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_I2S1_RX_WS (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_I2S1_TXSDA (PINCONF_FUNC7|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_I2S1_TXWS (PINCONF_FUNC7|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_I2S1_TX_MCLK_1 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_I2S1_TX_MCLK_2 (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_I2S1_TX_SCK_1 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_I2S1_TX_SCK_2 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_I2S1_TX_SCK_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_I2S1_TX_SDA (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_I2S1_TX_WS (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_7) + +#define PINCONF_LCD_DCLK_1 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_LCD_DCLK_2 (PINCONF_FUNC4|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_LCD_ENAB (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_LCD_FP (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_LCD_LCDM (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_LCD_LE (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_LCD_LP_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_LCD_LP_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_LCD_PWR_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_LCD_PWR_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_LCD_PWR_3 (PINCONF_FUNC6|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_LCD_VD0 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_LCD_VD1 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_LCD_VD2 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_LCD_VD3 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_LCD_VD4_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_LCD_VD4_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_LCD_VD5_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_LCD_VD5_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_LCD_VD6_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_LCD_VD6_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_LCD_VD7_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_LCD_VD7_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_LCD_VD8_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_LCD_VD8_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_LCD_VD9 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_LCD_VD10 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_LCD_VD11 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_LCD_VD12_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_LCD_VD12_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_LCD_VD12_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_LCD_VD13_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_LCD_VD13_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_LCD_VD13_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_LCD_VD14_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_LCD_VD14_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_LCD_VD14_3 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_LCD_VD15_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_LCD_VD15_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_LCD_VD15_3 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_LCD_VD16_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_LCD_VD16_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_LCD_VD17 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_LCD_VD18 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_LCD_VD19_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_LCD_VD19_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_LCD_VD19_3 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_LCD_VD19_4 (PINCONF_FUNC6|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_LCD_VD20_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_LCD_VD20_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_LCD_VD21_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_LCD_VD21_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_LCD_VD22_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_LCD_VD22_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_LCD_VD23_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_LCD_VD23_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_5) + +#define PINCONF_MCABORT_1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_MCABORT_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_MCI0_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_MCI0_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_MCI1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_MCI1_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_MCI2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_MCI2_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_MCOA0_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_MCOA0_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_MCOA1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_MCOA1_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_MCOA2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_MCOA2_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_MCOB0_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_MCOB0_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_MCOB1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_MCOB1_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_MCOB2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_MCOB2_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_2) + +#define PINCONF_NMI_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_NMI_2 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_0) + +#define PINCONF_QEI_IDX (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_QEI_PHA (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_3) +#define PINCONF_QEI_PHB (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_2) + +#define PINCONF_SD_CD_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_SD_CD_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_SD_CLK (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_SD_CMD_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_SD_CMD_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_SD_DAT0_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_SD_DAT0_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_SD_DAT1_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_SD_DAT1_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_SD_DAT2_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_SD_DAT2_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_SD_DAT3_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_SD_DAT3_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_SD_DAT4 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_SD_DAT5 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_SD_DAT6 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_SD_DAT7 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_SD_POW_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_SD_POW_2 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_SD_POW_3 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_SD_RST_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SD_RST_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_SD_VOLT0_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_SD_VOLT0_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_SD_VOLT1_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SD_VOLT1_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_SD_VOLT2_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_SD_VOLT2_2 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_SD_WP_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_SD_WP_2 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_10) + +#define PINCONF_SGPIO0_1 (PINCONF_FUNC3|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_SGPIO0_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_SGPIO0_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_SGPIO1_1 (PINCONF_FUNC3|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_SGPIO1_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_SGPIO1_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_SGPIO2_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_SGPIO2_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_SGPIO2_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_SGPIO3_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_SGPIO3_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_SGPIO3_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_SGPIO4_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_SGPIO4_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_SGPIO4_3 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_SGPIO4_4 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_SGPIO4_5 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_SGPIO4_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_SGPIO5_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_SGPIO5_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_SGPIO5_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_SGPIO5_4 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_SGPIO5_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_SGPIO6_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_SGPIO6_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_SGPIO6_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_SGPIO6_4 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_SGPIO6_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_SGPIO7_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_SGPIO7_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_SGPIO7_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_SGPIO7_4 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_SGPIO7_5 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_SGPIO7_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_SGPIO8_1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_SGPIO8_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_SGPIO8_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_SGPIO8_4 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_SGPIO8_5 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_SGPIO8_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_SGPIO9_1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_SGPIO9_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_SGPIO9_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_SGPIO9_4 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_SGPIO9_5 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_SGPIO9_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_SGPIO10_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SGPIO10_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_SGPIO10_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_SGPIO10_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_SGPIO10_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_SGPIO11_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SGPIO11_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_SGPIO11_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_SGPIO11_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_SGPIO11_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_SGPIO12_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_SGPIO12_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_SGPIO12_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_SGPIO12_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_SGPIO12_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_SGPIO13_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_SGPIO13_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_SGPIO13_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_SGPIO13_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_SGPIO13_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_SGPIO14_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_SGPIO14_2 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_SGPIO14_3 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_SGPIO15_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_SGPIO15_2 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_SGPIO15_3 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_10) + +#define PINCONF_SPIFI_CS (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SPIFI_MISO (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SPIFI_MOSI (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SPIFI_SCK (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SPIFI_SIO2 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_SPIFI_SIO3 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_4) + +#define PINCONF_SPI_MISO (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SPI_MOSI (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SPI_SCK (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SPI_SSEL (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_8) + +#define PINCONF_SSP0_MISO_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SSP0_MISO_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_SSP0_MISO_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_SSP0_MISO_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SSP0_MISO_5 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_SSP0_MOSI_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SSP0_MOSI_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_SSP0_MOSI_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_SSP0_MOSI_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SSP0_MOSI_5 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_SSP0_SCK_1 (PINCONF_FUNC0|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_SSP0_SCK_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SSP0_SCK_3 (PINCONF_FUNC4|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_SSP0_SSEL_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SSP0_SSEL_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_SSP0_SSEL_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_SSP0_SSEL_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SSP0_SSEL_5 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_0) + +#define PINCONF_SSP1_MISO_1 (PINCONF_FUNC1|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_SSP1_MISO_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_SSP1_MISO_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SSP1_MOSI_1 (PINCONF_FUNC1|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_SSP1_MOSI_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_SSP1_MOSI_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SSP1_SCK_1 (PINCONF_FUNC0|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_SSP1_SCK_2 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_SSP1_SSEL_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_SSP1_SSEL_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_SSP1_SSEL_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_5) + +#define PINCONF_T0_CAP0_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_T0_CAP0_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_T0_CAP1_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_T0_CAP1_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_T0_CAP2_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_T0_CAP2_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_T0_CAP3_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_T0_CAP3_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_T0_MAT0_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_T0_MAT0_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_T0_MAT1_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_T0_MAT1_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_T0_MAT2_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_T0_MAT2_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_T0_MAT3_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_T0_MAT3_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_3) + +#define PINCONF_T1_CAP0 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_T1_CAP1 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_T1_CAP2 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_T1_CAP3 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_T1_MAT0 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_T1_MAT1 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_T1_MAT2 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_T1_MAT3 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_7) + +#define PINCONF_T2_CAP0 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_T2_CAP1 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_T2_CAP2 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_T2_CAP3 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_T2_MAT0 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_T2_MAT1 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_T2_MAT2 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_T2_MAT3 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_11) + +#define PINCONF_T3_CAP0_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_T3_CAP0_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_T3_CAP1_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_T3_CAP1_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_T3_CAP2_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_T3_CAP2_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_T3_CAP3_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_T3_CAP3_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_T3_MAT0_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_T3_MAT0_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_T3_MAT1_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_T3_MAT1_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_T3_MAT2_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_T3_MAT2_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_T3_MAT3_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_T3_MAT3_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_10) + +/* The hardware ETM pins will not toggle unless the SLEW FAST bit is set */ + +#define PINCONF_TRACECLK (PINCONF_FUNC2|PINCONF_SLEW_FAST|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_TRACEDATA0_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_TRACEDATA0_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_TRACEDATA1_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_TRACEDATA1_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_TRACEDATA2_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_TRACEDATA2_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_TRACEDATA3_1 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_TRACEDATA3_2 (PINCONF_FUNC5|PINCONF_SLEW_FAST|PINCONF_PINS7|PINCONF_PIN_7) + +#define PINCONF_U0_DIR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_U0_DIR_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_U0_DIR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_U0_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_U0_RXD_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_U0_RXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_U0_RXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_U0_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_U0_TXD_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_U0_TXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_U0_TXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_U0_UCLK_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_U0_UCLK_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_U0_UCLK_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_1) + +#define PINCONF_U1_CTS_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_U1_CTS_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_U1_CTS_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_U1_CTS_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_U1_DCD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_U1_DCD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_U1_DCD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_U1_DCD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_U1_DSR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_U1_DSR_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_U1_DSR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_U1_DSR_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_U1_DTR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_U1_DTR_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_U1_DTR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_U1_DTR_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_U1_RI_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_U1_RI_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_U1_RI_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_U1_RI_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_U1_RTS_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_U1_RTS_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_U1_RTS_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_U1_RTS_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_U1_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_U1_RXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_U1_RXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_U1_RXD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_U1_RXD_5 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_U1_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_U1_TXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_U1_TXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_U1_TXD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_U1_TXD_5 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_PINS5|PINCONF_PIN_6) + +#define PINCONF_U2_DIR_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_U2_DIR_2 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_U2_RXD_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_U2_RXD_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_U2_RXD_3 (PINCONF_FUNC3|PINCONF_PINSA|PINCONF_PIN_2) +#define PINCONF_U2_RXD_4 (PINCONF_FUNC6|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_U2_TXD_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_U2_TXD_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_U2_TXD_3 (PINCONF_FUNC3|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_U2_TXD_4 (PINCONF_FUNC6|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_U2_UCLK_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_U2_UCLK_2 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_12) + +#define PINCONF_U3_BAUD_1 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_U3_BAUD_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_U3_BAUD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_U3_DIR_1 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_U3_DIR_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_U3_DIR_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_U3_RXD_1 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_U3_RXD_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_U3_RXD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_U3_RXD_4 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_U3_TXD_1 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_U3_TXD_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_U3_TXD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_U3_TXD_4 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_U3_UCLK_1 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_U3_UCLK_2 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_U3_UCLK_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_0) + +#define PINCONF_USB0_IND0_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_USB0_IND0_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_USB0_IND0_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_USB0_IND0_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_USB0_IND0_5 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_USB0_IND1_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_USB0_IND1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_USB0_IND1_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_USB0_IND1_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_USB0_PPWR_1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_USB0_PPWR_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_USB0_PPWR_3 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_USB0_PPWR_4 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_USB0_PWR_FAULT_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_USB0_PWR_FAULT_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_USB0_PWR_FAULT_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_USB0_PWR_FAULT_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_USB0_PWR_FAULT_5 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_4) + +#define PINCONF_USB1_IND0_1 (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_USB1_IND0_2 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_USB1_IND1_1 (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_USB1_IND1_2 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_USB1_PPWR (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_USB1_PWR_FAULT (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_CLK_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_USB1_ULPI_CLK_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_USB1_ULPI_D0_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D0_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_USB1_ULPI_D0_3 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_USB1_ULPI_D1_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D1_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_USB1_ULPI_D2_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D2_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_D3_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_D3_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D4_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D4_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D5_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D5_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D6_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_USB1_ULPI_D6_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D7_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_USB1_ULPI_D7_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_USB1_ULPI_DIR_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_USB1_ULPI_DIR_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_USB1_ULPI_NXT_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_NXT_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_USB1_ULPI_STP_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_USB1_ULPI_STP_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_USB1_VBUS (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_5) + +#define CLKCONF_CGU_OUT0 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK1) +#define CLKCONF_CGU_OUT1 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK3) +#define CLKCONF_CLKOUT_1 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK0) +#define CLKCONF_CLKOUT_2 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK1) +#define CLKCONF_CLKOUT_3 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK2) +#define CLKCONF_CLKOUT_4 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK3) +#define CLKCONF_EMC_CLK0 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK0) +#define CLKCONF_EMC_CLK01 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK0) +#define CLKCONF_EMC_CLK1 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK1) +#define CLKCONF_EMC_CLK2 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK3) +#define CLKCONF_EMC_CLK23 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK2) +#define CLKCONF_EMC_CLK3 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK2) +#define CLKCONF_ENET_REF_CLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK0) +#define CLKCONF_ENET_TX_CLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK0) +#define CLKCONF_I2S0_TX_MCLK (PINCONFIG_DIGITAL|PINCONF_FUNC6|PINCONF_CLK2) +#define CLKCONF_I2S1_RX_SCK_1 (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK2) +#define CLKCONF_I2S1_RX_SCK_2 (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK3) +#define CLKCONF_I2S1_TX_MCLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK1) +#define CLKCONF_SD_CLK_1 (PINCONFIG_DIGITAL|PINCONF_FUNC4|PINCONF_CLK0) +#define CLKCONF_SD_CLK_2 (PINCONFIG_DIGITAL|PINCONF_FUNC4|PINCONF_CLK2) +#define CLKCONF_SSP1_SCK (PINCONFIG_DIGITAL|PINCONF_FUNC6|PINCONF_CLK0) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4310203050_PINCONF_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h b/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..1b8312c965f79e505f4d7313be9d4b3f84074e89 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h @@ -0,0 +1,200 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc435357_memorymap.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC435357_MEMORYMAP_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC435357_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ +/* See arch/arm/include/lpc43xx/chip.h for the actual sizes of FLASH and SRAM + * regions + */ + +#define LPC43_SHADOW_BASE 0x00000000 /* -0x0fffffff: 256Mb shadow area */ +#define LPC43_LOCSRAM_BASE 0x10000000 /* -0x1fffffff: Local SRAM and external memory */ +#define LPC43_AHBSRAM_BASE 0x20000000 /* -0x27ffffff: AHB SRAM */ +#define LPC43_DYCS0_BASE 0x28000000 /* -0x2fffffff: 128Mb dynamic external memory */ +#define LPC43_DYCS1_BASE 0x30000000 /* -0x2fffffff: 256Mb dynamic external memory */ +#define LPC43_PERIPH_BASE 0x40000000 /* -0x5fffffff: Peripherals */ +#define LPC43_DYCS2_BASE 0x60000000 /* -0x6fffffff: 256Mb dynamic external memory */ +#define LPC43_DYCS3_BASE 0x70000000 /* -0x7fffffff: 256Mb dynamic external memory */ +#define LPC43_SPIFI_DATA_BASE 0x80000000 /* -0x87ffffff: 256Mb dynamic external memory */ +#define LPC43_ARM_BASE 0xe0000000 /* -0xe00fffff: ARM private */ + +/* Local SRAM Banks and external memory */ + +#define LPC43_LOCSRAM_BANK0_BASE (LPC43_LOCSRAM_BASE + 0x00000000) +#define LPC43_LOCSRAM_BANK1_BASE (LPC43_LOCSRAM_BASE + 0x00080000) +#define LPC43_ROM_BASE (LPC43_LOCSRAM_BASE + 0x00400000) +#define LPC43_LOCSRAM_SPIFI_BASE (LPC43_LOCSRAM_BASE + 0x04000000) +#define LPC43_LOCSRAM_FLASHA_BASE (LPC43_LOCSRAM_BASE + 0x0a000000) +#define LPC43_LOCSRAM_FLASHB_BASE (LPC43_LOCSRAM_BASE + 0x0b000000) +#define LPC43_EXTMEM_CS0_BASE (LPC43_LOCSRAM_BASE + 0x0c000000) +#define LPC43_EXTMEM_CS1_BASE (LPC43_LOCSRAM_BASE + 0x0d000000) +#define LPC43_EXTMEM_CS2_BASE (LPC43_LOCSRAM_BASE + 0x0e000000) +#define LPC43_EXTMEM_CS3_BASE (LPC43_LOCSRAM_BASE + 0x0f000000) + +/* ROM Driver Table */ + +#define LPC43_ROM_DRIVER_TABLE (LPC43_ROM_BASE+0x00000100) +#define LPC43_ROM_DRIVER_TABLE0 (LPC43_ROM_DRIVER_TABLE+0x0000) +#define LPC43_ROM_DRIVER_TABLE1 (LPC43_ROM_DRIVER_TABLE+0x0004) +#define LPC43_ROM_DRIVER_TABLE2 (LPC43_ROM_DRIVER_TABLE+0x0008) +#define LPC43_ROM_DRIVER_TABLE3 (LPC43_ROM_DRIVER_TABLE+0x000c) +#define LPC43_ROM_DRIVER_TABLE4 (LPC43_ROM_DRIVER_TABLE+0x0010) +#define LPC43_ROM_DRIVER_TABLE5 (LPC43_ROM_DRIVER_TABLE+0x0014) +#define LPC43_ROM_DRIVER_TABLE6 (LPC43_ROM_DRIVER_TABLE+0x0018) +#define LPC43_ROM_DRIVER_TABLE7 (LPC43_ROM_DRIVER_TABLE+0x001c) + +/* AHB SRAM */ + +#define LPC43_AHBSRAM_BANK0_BASE (LPC43_AHBSRAM_BASE) +#define LPC43_EEPROM_BASE (LPC43_AHBSRAM_BASE + 0x00004000) +#define LPC43_AHBSRAM_BITBAND_BASE (LPC43_AHBSRAM_BASE + 0x02000000) + +/* Peripherals */ + +#define LPC43_AHBPERIPH_BASE (LPC43_PERIPH_BASE + 0x00000000) +#define LPC43_RTCPERIPH_BASE (LPC43_PERIPH_BASE + 0x00040000) +#define LPC43_CLKPERIPH_BASE (LPC43_PERIPH_BASE + 0x00050000) +#define LPC43_APB0PERIPH_BASE (LPC43_PERIPH_BASE + 0x00080000) +#define LPC43_APB1PERIPH_BASE (LPC43_PERIPH_BASE + 0x000a0000) +#define LPC43_APB2PERIPH_BASE (LPC43_PERIPH_BASE + 0x000c0000) +#define LPC43_APB3PERIPH_BASE (LPC43_PERIPH_BASE + 0x000e0000) +#define LPC43_GPIO_BASE (LPC43_PERIPH_BASE + 0x000f4000) +#define LPC43_SPI_BASE (LPC43_PERIPH_BASE + 0x00100000) +#define LPC43_SGPIO_BASE (LPC43_PERIPH_BASE + 0x00101000) +#define LPC43_PERIPH_BITBAND_BASE (LPC43_PERIPH_BASE + 0x02000000) + +/* AHB Peripherals */ + +#define LPC43_SCT_BASE (LPC43_AHBPERIPH_BASE + 0x00000000) +#define LPC43_DMA_BASE (LPC43_AHBPERIPH_BASE + 0x00002000) +#define LPC43_SPIFI_BASE (LPC43_AHBPERIPH_BASE + 0x00003000) +#define LPC43_SDMMC_BASE (LPC43_AHBPERIPH_BASE + 0x00004000) +#define LPC43_EMC_BASE (LPC43_AHBPERIPH_BASE + 0x00005000) +#define LPC43_USB0_BASE (LPC43_AHBPERIPH_BASE + 0x00006000) +#define LPC43_USB1_BASE (LPC43_AHBPERIPH_BASE + 0x00007000) +#define LPC43_LCD_BASE (LPC43_AHBPERIPH_BASE + 0x00008000) +#define LPC43_FLASHA_BASE (LPC43_AHBPERIPH_BASE + 0x0000c000) +#define LPC43_FLASHB_BASE (LPC43_AHBPERIPH_BASE + 0x0000d000) +#define LPC43_EEPROMC_BASE (LPC43_AHBPERIPH_BASE + 0x0000e000) +#define LPC43_ETHERNET_BASE (LPC43_AHBPERIPH_BASE + 0x00010000) + +/* RTC Domain Peripherals */ + +#define LPC43_ATIMER_BASE (LPC43_RTCPERIPH_BASE + 0x00000000) +#define LPC43_BACKUP_BASE (LPC43_RTCPERIPH_BASE + 0x00001000) +#define LPC43_PMC_BASE (LPC43_RTCPERIPH_BASE + 0x00002000) +#define LPC43_CREG_BASE (LPC43_RTCPERIPH_BASE + 0x00003000) +#define LPC43_EVNTRTR_BASE (LPC43_RTCPERIPH_BASE + 0x00004000) +#define LPC43_OTPC_BASE (LPC43_RTCPERIPH_BASE + 0x00005000) +#define LPC43_RTC_BASE (LPC43_RTCPERIPH_BASE + 0x00006000) +#define LPC43_EVNTMNTR_BASE (LPC43_RTC_BASE + 0x00000080) + +/* Clocking and Reset Peripherals */ + +#define LPC43_CGU_BASE (LPC43_CLKPERIPH_BASE + 0x00000000) +#define LPC43_CCU1_BASE (LPC43_CLKPERIPH_BASE + 0x00001000) +#define LPC43_CCU2_BASE (LPC43_CLKPERIPH_BASE + 0x00002000) +#define LPC43_RGU_BASE (LPC43_CLKPERIPH_BASE + 0x00003000) + +/* APB0 Peripherals */ + +#define LPC43_WWDT_BASE (LPC43_APB0PERIPH_BASE + 0x00000000) +#define LPC43_USART0_BASE (LPC43_APB0PERIPH_BASE + 0x00001000) +#define LPC43_UART1_BASE (LPC43_APB0PERIPH_BASE + 0x00002000) +#define LPC43_SSP0_BASE (LPC43_APB0PERIPH_BASE + 0x00003000) +#define LPC43_TIMER0_BASE (LPC43_APB0PERIPH_BASE + 0x00004000) +#define LPC43_TIMER1_BASE (LPC43_APB0PERIPH_BASE + 0x00005000) +#define LPC43_SCU_BASE (LPC43_APB0PERIPH_BASE + 0x00006000) +#define LPC43_GPIOINT_BASE (LPC43_APB0PERIPH_BASE + 0x00007000) +#define LPC43_GRP0INT_BASE (LPC43_APB0PERIPH_BASE + 0x00008000) +#define LPC43_GRP1INT_BASE (LPC43_APB0PERIPH_BASE + 0x00009000) + +/* APB1 Peripherals */ + +#define LPC43_MCPWM_BASE (LPC43_APB1PERIPH_BASE + 0x00000000) +#define LPC43_I2C0_BASE (LPC43_APB1PERIPH_BASE + 0x00001000) +#define LPC43_I2S0_BASE (LPC43_APB1PERIPH_BASE + 0x00002000) +#define LPC43_I2S1_BASE (LPC43_APB1PERIPH_BASE + 0x00003000) +#define LPC43_CAN1_BASE (LPC43_APB1PERIPH_BASE + 0x00004000) + +/* APB2 Peripherals */ + +#define LPC43_RIT_BASE (LPC43_APB2PERIPH_BASE + 0x00000000) +#define LPC43_USART2_BASE (LPC43_APB2PERIPH_BASE + 0x00001000) +#define LPC43_USART3_BASE (LPC43_APB2PERIPH_BASE + 0x00002000) +#define LPC43_TIMER2_BASE (LPC43_APB2PERIPH_BASE + 0x00003000) +#define LPC43_TIMER3_BASE (LPC43_APB2PERIPH_BASE + 0x00004000) +#define LPC43_SSP1_BASE (LPC43_APB2PERIPH_BASE + 0x00005000) +#define LPC43_QEI_BASE (LPC43_APB2PERIPH_BASE + 0x00006000) +#define LPC43_GIMA_BASE (LPC43_APB2PERIPH_BASE + 0x00007000) + +/* APB3 Peripherals */ + +#define LPC43_I2C1_BASE (LPC43_APB3PERIPH_BASE + 0x00000000) +#define LPC43_DAC_BASE (LPC43_APB3PERIPH_BASE + 0x00001000) +#define LPC43_CAN0_BASE (LPC43_APB3PERIPH_BASE + 0x00002000) +#define LPC43_ADC0_BASE (LPC43_APB3PERIPH_BASE + 0x00003000) +#define LPC43_ADC1_BASE (LPC43_APB3PERIPH_BASE + 0x00004000) + +/* ARM Private */ + +#define LPC43_SCS_BASE (LPC43_ARM_BASE + 0x0000e000) +#define LPC43_DEBUGMCU_BASE (LPC43_ARM_BASE + 0x00042000) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC435357_MEMORYMAP_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc4357fet256_pinconfig.h b/arch/arm/src/lpc43xx/chip/lpc4357fet256_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..6be507c1ce0d90d6bff211a7c013f25cd3be974c --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc4357fet256_pinconfig.h @@ -0,0 +1,982 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc4310203050_pinconfig.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4357FET256_PINCONF_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4357FET256_PINCONF_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* NOTES: + * + * 1. These settings were taken from the LPC43_10_20_30_50 data sheet and may not be applicable to + * any other family members. + * + * 2. Settings taken from the data sheet include only function, pin set, and pin number. Additional + * settings must be verified before using these pin configurations (like pull-ups, open-drain, + * drive strength, input buffering, etc.). + * + * 3. Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, + * however, will use the pin selection without the numeric suffix. Additional definitions are + * required in the board.h file to select between the alternative pins. For example, if CAN1_RD + * connects via Pins1[18], then the following definition should appear in the board.h header file + * for that board: + * + * 4. For ADC pins (PINCONF_ADCNpM), the pin must first be configured configured as a GPIO input. + * Then SCU's ADC function select register can be used to select the ADC. + * + * #define PINCONF_CAN1_RD PINCONF_CAN1_RD_1 + * + * The driver will then automatically configre Pins1[18] as the CAN1 RD pin. + */ + +#define PINCONF_ADC0p0 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_ADC0p1 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_ADC0p2 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_ADC0p3 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_ADC0p4 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_ADC0p5 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_ADC0p6 (PINCONF_FUNC0|PINCONF_PINSB|PINCONF_PIN_6) + +#define PINCONF_ADC1p0 (PINCONF_FUNC4|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_ADC1p1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_ADC1p2 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_ADC1p3 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_ADC1p4 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_ADC1p5 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_ADC1p6 (PINCONF_FUNC0|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_ADC1p7 (PINCONF_FUNC4|PINCONF_PINSF|PINCONF_PIN_7) + +#define PINCONF_ADCTRIG0 (PINCONF_FUNC0|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_ADCTRIG1_1 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_ADCTRIG1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_5) + +#define PINCONF_CAN0_RD_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_CAN0_RD_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_CAN0_TD_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_CAN0_TD_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_2) + +#define PINCONF_CAN1_RD_1 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_CAN1_RD_2 (PINCONF_FUNC5|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_CAN1_RD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_CAN1_TD_1 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_CAN1_TD_2 (PINCONF_FUNC5|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_CAN1_TD_3 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_8) + +#define PINCONF_CGU_OUT0 (PINCONF_FUNC6|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_CGU_OUT1_1 (PINCONF_FUNC4|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_CGU_OUT1_2 (PINCONF_FUNC6|PINCONF_PINSA|PINCONF_PIN_0) + +#define PINCONF_CLKOUT (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_19) + +#define PINCONF_CTIN0_1 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_CTIN0_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_CTIN1_1 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_CTIN1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_CTIN2_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_CTIN2_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_CTIN2_3 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_CTIN3_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_CTIN3_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_CTIN3_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_CTIN4_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_CTIN4_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_CTIN4_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_CTIN5_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_CTIN5_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_CTIN5_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_CTIN5_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_CTIN6_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_CTIN6_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_CTIN6_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_CTIN6_4 (PINCONF_FUNC5|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_CTIN6_5 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_CTIN7_1 (PINCONF_FUNC5|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_CTIN7_2 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_5) + +#define PINCONF_CTOUT0_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_CTOUT0_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_CTOUT0_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_CTOUT1_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_CTOUT1_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_CTOUT1_3 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_CTOUT2_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_CTOUT2_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_CTOUT2_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_CTOUT3_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_CTOUT3_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_CTOUT3_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_CTOUT4_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_CTOUT4_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_CTOUT4_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_CTOUT5_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_CTOUT5_2 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_CTOUT5_3 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_CTOUT6_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_CTOUT6_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_CTOUT6_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_CTOUT6_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_CTOUT7_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_CTOUT7_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_CTOUT7_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_CTOUT7_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_CTOUT8_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_CTOUT8_2 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_CTOUT8_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_CTOUT8_4 (PINCONF_FUNC5|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_CTOUT8_5 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_CTOUT9_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_CTOUT9_2 (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_CTOUT9_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_CTOUT10_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_CTOUT10_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_CTOUT10_3 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_CTOUT10_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_CTOUT11_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_CTOUT11_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_CTOUT11_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_CTOUT11_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_CTOUT12_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_CTOUT12_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_CTOUT12_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_CTOUT12_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_CTOUT13_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_CTOUT13_2 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_CTOUT13_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_CTOUT13_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_CTOUT14_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_CTOUT14_2 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_CTOUT14_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_CTOUT14_4 (PINCONF_FUNC6|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_CTOUT15_1 (PINCONF_FUNC1|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_CTOUT15_2 (PINCONF_FUNC1|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_CTOUT15_3 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_11) + +#define PINCONF_EMC_A0 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_EMC_A1 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_EMC_A2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_EMC_A3 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_EMC_A4 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_EMC_A5 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_EMC_A6 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_EMC_A7 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_EMC_A8 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_EMC_A9 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_EMC_A10 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_EMC_A11 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_EMC_A12 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_EMC_A13 (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_EMC_A14 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_EMC_A15 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_EMC_A16 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_EMC_A17 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_EMC_A18 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_EMC_A19 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_EMC_A20 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_EMC_A21 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_EMC_A22 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_EMC_A23 (PINCONF_FUNC3|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_EMC_BLS0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_EMC_BLS1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_EMC_BLS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_EMC_BLS3 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_EMC_CAS (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_EMC_CKEOUT0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_11) +#define PINCONF_EMC_CKEOUT1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_EMC_CKEOUT2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_EMC_CKEOUT3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_EMC_CS0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_EMC_CS1 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_EMC_CS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_EMC_CS3 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_EMC_D0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_EMC_D1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_EMC_D2 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_EMC_D3 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_EMC_D4 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_EMC_D5 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_EMC_D6 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_EMC_D7 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_EMC_D8 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_EMC_D9 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_EMC_D10 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_EMC_D11 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_EMC_D12 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_EMC_D13 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_EMC_D14 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_EMC_D15 (PINCONF_FUNC2|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_EMC_D16 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_EMC_D17 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_EMC_D18 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_EMC_D19 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_EMC_D20 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_EMC_D21 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_EMC_D22 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_EMC_D23 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_EMC_D24 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_EMC_D25 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_EMC_D26 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_EMC_D27 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_EMC_D28 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_EMC_D29 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_EMC_D30 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_EMC_D31 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_EMC_DQMOUT0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_EMC_DQMOUT1 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_EMC_DQMOUT2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_EMC_DQMOUT3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_EMC_DYCS0 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_EMC_DYCS1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_EMC_DYCS2 (PINCONF_FUNC2|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_EMC_DYCS3 (PINCONF_FUNC3|PINCONF_PINSE|PINCONF_PIN_14) +#define PINCONF_EMC_OE (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_EMC_RAS (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_EMC_WE (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_6) + +#define PINCONF_ENET_COL_1 (PINCONF_FUNC2|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_ENET_COL_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_ENET_COL_3 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_ENET_CRS_1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_ENET_CRS_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_ENET_MDC_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_ENET_MDC_2 (PINCONF_FUNC6|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_ENET_MDC_3 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_ENET_MDIO (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_ENET_REF_CLK (PINCONF_FUNC0|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_ENET_RXD0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_ENET_RXD1 (PINCONF_FUNC2|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_ENET_RXD2_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_ENET_RXD2_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_ENET_RXD3_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_ENET_RXD3_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_ENET_RX_CLK (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_ENET_RX_DV_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_ENET_RX_DV_2 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_ENET_RX_ER_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_ENET_RX_ER_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_ENET_TXD0 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_ENET_TXD1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_ENET_TXD2_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_ENET_TXD2_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_ENET_TXD3_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_ENET_TXD3_2 (PINCONF_FUNC5|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_ENET_TXEN (PINCONF_FUNC6|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_ENET_TX_CLK (PINCONF_FUNC0|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_ENET_TX_EN (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_ENET_TX_ER_1 (PINCONF_FUNC3|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_ENET_TX_ER_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_14) + +#define PINCONF_GPIO0p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_GPIO0p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_GPIO0p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_GPIO0p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_GPIO0p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_GPIO0p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_GPIO0p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_GPIO0p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_GPIO0p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_GPIO0p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_GPIO0p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_GPIO0p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_GPIO0p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_GPIO0p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_GPIO0p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_GPIO0p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_GPIO1p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_GPIO1p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_GPIO1p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_GPIO1p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_GPIO1p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_GPIO1p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_GPIO1p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_GPIO1p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_GPIO1p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_GPIO1p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_GPIO1p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_GPIO1p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_GPIO1p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_12) +#define PINCONF_GPIO1p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_GPIO1p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_GPIO1p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_GPIO2p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_GPIO2p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_GPIO2p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_GPIO2p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_GPIO2p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_GPIO2p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_GPIO2p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_GPIO2p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_GPIO2p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_12) +#define PINCONF_GPIO2p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_GPIO2p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_GPIO2p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_GPIO2p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_GPIO2p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_GPIO2p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_GPIO2p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_GPIO3p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_GPIO3p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_GPIO3p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_GPIO3p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_GPIO3p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_GPIO3p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_GPIO3p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_GPIO3p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_11) +#define PINCONF_GPIO3p8 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_GPIO3p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_GPIO3p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_GPIO3p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_GPIO3p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_GPIO3p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_GPIO3p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_GPIO3p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_GPIO4p0 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_GPIO4p1 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_GPIO4p2 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_GPIO4p3 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_GPIO4p4 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_GPIO4p5 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_GPIO4p6 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_GPIO4p7 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_GPIO4p8 (PINCONF_FUNC0|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_GPIO4p9 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_2) +#define PINCONF_GPIO4p10 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_3) +#define PINCONF_GPIO4p11 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_GPIO4p12 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_GPIO4p13 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_GPIO4p14 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_GPIO4p15 (PINCONF_FUNC0|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_GPIO5p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_GPIO5p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_GPIO5p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_GPIO5p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_GPIO5p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_GPIO5p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_GPIO5p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_GPIO5p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_GPIO5p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_GPIO5p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_GPIO5p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_GPIO5p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_GPIO5p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_GPIO5p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_GPIO5p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_GPIO5p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_GPIO5p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_GPIO5p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_GPIO5p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_GPIO5p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_4) +#define PINCONF_GPIO5p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_GPIO5p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_GPIO5p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_GPIO5p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_GPIO5p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_GPIO5p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_GPIO5p26 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_GPIO6p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_GPIO6p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_GPIO6p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_GPIO6p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_GPIO6p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_GPIO6p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_GPIO6p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_GPIO6p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_GPIO6p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_GPIO6p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_GPIO6p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_GPIO6p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_GPIO6p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_GPIO6p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_GPIO6p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_GPIO6p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_GPIO6p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_GPIO6p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_GPIO6p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_GPIO6p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_GPIO6p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_GPIO6p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_GPIO6p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_GPIO6p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_GPIO6p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_10) +#define PINCONF_GPIO6p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_GPIO6p26 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_12) +#define PINCONF_GPIO6p27 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_13) +#define PINCONF_GPIO6p28 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_14) +#define PINCONF_GPIO6p29 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_GPIO6p30 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_GPIO7p0 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_0) +#define PINCONF_GPIO7p1 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_1) +#define PINCONF_GPIO7p2 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_2) +#define PINCONF_GPIO7p3 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_3) +#define PINCONF_GPIO7p4 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_GPIO7p5 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_GPIO7p6 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_GPIO7p7 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_GPIO7p8 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_GPIO7p9 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_GPIO7p10 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_GPIO7p11 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_GPIO7p12 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_GPIO7p13 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_13) +#define PINCONF_GPIO7p14 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_14) +#define PINCONF_GPIO7p15 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_GPIO7p16 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_GPIO7p17 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_GPIO7p18 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_GPIO7p19 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_GPIO7p20 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_GPIO7p21 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_GPIO7p22 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_GPIO7p23 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_GPIO7p24 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_GPIO7p25 (PINCONF_FUNC4|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_11) + +#define PINCONF_GP_CLKIN_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_GP_CLKIN_2 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_GP_CLKIN_3 (PINCONF_FUNC1|PINCONF_PINSF|PINCONF_PIN_4) + +#define PINCONF_I2C1_SCL_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_I2C1_SCL_2 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_15) +#define PINCONF_I2C1_SDA_1 (PINCONF_FUNC1|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_I2C1_SDA_2 (PINCONF_FUNC2|PINCONF_PINSE|PINCONF_PIN_13) + +#define PINCONF_I2S0_RX_MCLK_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_MCLK_2 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_MCLK_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_I2S0_RX_SCK_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_SCK_2 (PINCONF_FUNC4|PINCONF_PINS6|PINCONF_PIN_0) +#define PINCONF_I2S0_RX_SCK_3 (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_I2S0_RX_SDA_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_I2S0_RX_SDA_2 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_I2S0_RX_WS_1 (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_I2S0_RX_WS_2 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_I2S0_TXWS (PINCONF_FUNC6|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_MCLK_1 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_MCLK_2 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_I2S0_TX_MCLK_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_I2S0_TX_SCK_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_I2S0_TX_SCK_2 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_I2S0_TX_SDA_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_2 (PINCONF_FUNC2|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_3 (PINCONF_FUNC4|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_I2S0_TX_SDA_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_I2S0_TX_SDA_5 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_I2S0_TX_WS_1 (PINCONF_FUNC0|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_2 (PINCONF_FUNC2|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_3 (PINCONF_FUNC4|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_I2S0_TX_WS_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_I2S0_TX_WS_5 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_13) + +#define PINCONF_I2S1_RX_MCLK (PINCONF_FUNC5|PINCONF_PINSA|PINCONF_PIN_0) +#define PINCONF_I2S1_RX_SDA (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_I2S1_RX_WS (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_I2S1_TXSDA (PINCONF_FUNC7|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_I2S1_TXWS (PINCONF_FUNC7|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_I2S1_TX_MCLK_1 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_I2S1_TX_MCLK_2 (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_I2S1_TX_SCK_1 (PINCONF_FUNC6|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_I2S1_TX_SCK_2 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_I2S1_TX_SCK_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_I2S1_TX_SDA (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_I2S1_TX_WS (PINCONF_FUNC7|PINCONF_PINSF|PINCONF_PIN_7) + +#define PINCONF_LCD_DCLK_1 (PINCONF_FUNC0|PINCONF_PINS4|PINCONF_PIN_7) +#define PINCONF_LCD_DCLK_2 (PINCONF_FUNC4|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_LCD_ENAB (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_LCD_FP (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_LCD_LCDM (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_LCD_LE (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_LCD_LP_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_LCD_LP_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_LCD_PWR_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_LCD_PWR_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_LCD_PWR_3 (PINCONF_FUNC6|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_LCD_VD0 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_LCD_VD1 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_LCD_VD2 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_LCD_VD3 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_LCD_VD4_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_LCD_VD4_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_LCD_VD5_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_LCD_VD5_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_LCD_VD6_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_LCD_VD6_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_LCD_VD7_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_LCD_VD7_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_LCD_VD8_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_LCD_VD8_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_LCD_VD9 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_LCD_VD10 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_LCD_VD11 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_LCD_VD12_1 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_LCD_VD12_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_LCD_VD12_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_LCD_VD13_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_LCD_VD13_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_LCD_VD13_3 (PINCONF_FUNC7|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_LCD_VD14_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_LCD_VD14_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_10) +#define PINCONF_LCD_VD14_3 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_LCD_VD15_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_LCD_VD15_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_LCD_VD15_3 (PINCONF_FUNC6|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_LCD_VD16_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_LCD_VD16_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_LCD_VD17 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_3) +#define PINCONF_LCD_VD18 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_LCD_VD19_1 (PINCONF_FUNC3|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_LCD_VD19_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_LCD_VD19_3 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_LCD_VD19_4 (PINCONF_FUNC6|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_LCD_VD20_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_LCD_VD20_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_LCD_VD21_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_LCD_VD21_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_LCD_VD22_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_LCD_VD22_2 (PINCONF_FUNC5|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_LCD_VD23_1 (PINCONF_FUNC2|PINCONF_PINSB|PINCONF_PIN_0) +#define PINCONF_LCD_VD23_2 (PINCONF_FUNC4|PINCONF_PINS7|PINCONF_PIN_5) + +#define PINCONF_MCABORT_1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_10) +#define PINCONF_MCABORT_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_MCI0_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_MCI0_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_MCI1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_MCI1_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_MCI2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_MCI2_2 (PINCONF_FUNC3|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_MCOA0_1 (PINCONF_FUNC1|PINCONF_PINS4|PINCONF_PIN_0) +#define PINCONF_MCOA0_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_MCOA1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_MCOA1_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_MCOA2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_MCOA2_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_MCOB0_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_MCOB0_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_MCOB1_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_MCOB1_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_MCOB2_1 (PINCONF_FUNC1|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_MCOB2_2 (PINCONF_FUNC1|PINCONF_PINS9|PINCONF_PIN_2) + +#define PINCONF_NMI_1 (PINCONF_FUNC1|PINCONF_PINSE|PINCONF_PIN_4) +#define PINCONF_NMI_2 (PINCONF_FUNC2|PINCONF_PINS4|PINCONF_PIN_0) + +#define PINCONF_QEI_IDX (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_QEI_PHA (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_3) +#define PINCONF_QEI_PHB (PINCONF_FUNC1|PINCONF_PINSA|PINCONF_PIN_2) + +#define PINCONF_SD_CD_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_SD_CD_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_SD_CLK (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_SD_CMD_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_SD_CMD_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_SD_DAT0_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_SD_DAT0_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_SD_DAT1_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_SD_DAT1_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_SD_DAT2_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_SD_DAT2_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_SD_DAT3_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_SD_DAT3_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_SD_DAT4 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_SD_DAT5 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_SD_DAT6 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_SD_DAT7 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_SD_POW_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_SD_POW_2 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_SD_POW_3 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_SD_RST_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SD_RST_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_SD_VOLT0_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_SD_VOLT0_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_SD_VOLT1_1 (PINCONF_FUNC7|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SD_VOLT1_2 (PINCONF_FUNC7|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_SD_VOLT2_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_16) +#define PINCONF_SD_VOLT2_2 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_SD_WP_1 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_15) +#define PINCONF_SD_WP_2 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_10) + +#define PINCONF_SGPIO0_1 (PINCONF_FUNC3|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_SGPIO0_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_0) +#define PINCONF_SGPIO0_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_SGPIO1_1 (PINCONF_FUNC3|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_SGPIO1_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_SGPIO1_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_SGPIO2_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_SGPIO2_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_SGPIO2_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_SGPIO3_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_SGPIO3_2 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_SGPIO3_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_SGPIO4_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_SGPIO4_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_SGPIO4_3 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_SGPIO4_4 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_SGPIO4_5 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_0) +#define PINCONF_SGPIO4_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_0) +#define PINCONF_SGPIO5_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_SGPIO5_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_SGPIO5_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_SGPIO5_4 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_SGPIO5_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_1) +#define PINCONF_SGPIO6_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_SGPIO6_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_SGPIO6_3 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_SGPIO6_4 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_SGPIO6_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_2) +#define PINCONF_SGPIO7_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_SGPIO7_2 (PINCONF_FUNC2|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_SGPIO7_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_SGPIO7_4 (PINCONF_FUNC6|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_SGPIO7_5 (PINCONF_FUNC7|PINCONF_PINS7|PINCONF_PIN_7) +#define PINCONF_SGPIO7_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_3) +#define PINCONF_SGPIO8_1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_SGPIO8_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_SGPIO8_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_SGPIO8_4 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_SGPIO8_5 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_SGPIO8_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_4) +#define PINCONF_SGPIO9_1 (PINCONF_FUNC3|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_SGPIO9_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_SGPIO9_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_SGPIO9_4 (PINCONF_FUNC6|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_SGPIO9_5 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_SGPIO9_6 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_5) +#define PINCONF_SGPIO10_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SGPIO10_2 (PINCONF_FUNC4|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_SGPIO10_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_SGPIO10_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_SGPIO10_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_6) +#define PINCONF_SGPIO11_1 (PINCONF_FUNC2|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SGPIO11_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_SGPIO11_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_SGPIO11_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_5) +#define PINCONF_SGPIO11_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_7) +#define PINCONF_SGPIO12_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_SGPIO12_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_SGPIO12_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_SGPIO12_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_6) +#define PINCONF_SGPIO12_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_8) +#define PINCONF_SGPIO13_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_SGPIO13_2 (PINCONF_FUNC5|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_SGPIO13_3 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_SGPIO13_4 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_8) +#define PINCONF_SGPIO13_5 (PINCONF_FUNC7|PINCONF_PINSD|PINCONF_PIN_9) +#define PINCONF_SGPIO14_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_SGPIO14_2 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_6) +#define PINCONF_SGPIO14_3 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_9) +#define PINCONF_SGPIO15_1 (PINCONF_FUNC0|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_SGPIO15_2 (PINCONF_FUNC6|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_SGPIO15_3 (PINCONF_FUNC7|PINCONF_PINS4|PINCONF_PIN_10) + +#define PINCONF_SPIFI_CS (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SPIFI_MISO (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SPIFI_MOSI (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SPIFI_SCK (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SPIFI_SIO2 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_SPIFI_SIO3 (PINCONF_FUNC3|PINCONF_SLEW_FAST|PINCONF_INBUFFER|PINCONF_GLITCH|PINCONF_PINS3|PINCONF_PIN_4) + +#define PINCONF_SPI_MISO (PINCONF_FUNC1|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SPI_MOSI (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SPI_SCK (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SPI_SSEL (PINCONF_FUNC1|PINCONF_PINS3|PINCONF_PIN_8) + +#define PINCONF_SSP0_MISO_1 (PINCONF_FUNC2|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SSP0_MISO_2 (PINCONF_FUNC2|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_SSP0_MISO_3 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_1) +#define PINCONF_SSP0_MISO_4 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SSP0_MISO_5 (PINCONF_FUNC7|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_1) +#define PINCONF_SSP0_MOSI_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SSP0_MOSI_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_SSP0_MOSI_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_2) +#define PINCONF_SSP0_MOSI_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_7) +#define PINCONF_SSP0_MOSI_5 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_2) +#define PINCONF_SSP0_SCK_1 (PINCONF_FUNC0|PINCONF_PINSF|PINCONF_PIN_0) +#define PINCONF_SSP0_SCK_2 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_3) +#define PINCONF_SSP0_SCK_3 (PINCONF_FUNC4|PINCONF_PINS3|PINCONF_PIN_0) +#define PINCONF_SSP0_SSEL_1 (PINCONF_FUNC2|PINCONF_PINS3|PINCONF_PIN_6) +#define PINCONF_SSP0_SSEL_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_1) +#define PINCONF_SSP0_SSEL_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_0) +#define PINCONF_SSP0_SSEL_4 (PINCONF_FUNC5|PINCONF_PINS3|PINCONF_PIN_8) +#define PINCONF_SSP0_SSEL_5 (PINCONF_FUNC7|PINCONF_PINS9|PINCONF_PIN_0) + +#define PINCONF_SSP1_MISO_1 (PINCONF_FUNC1|PINCONF_INBUFFER|PINCONF_PINS0|PINCONF_PIN_0) +#define PINCONF_SSP1_MISO_2 (PINCONF_FUNC2|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_SSP1_MISO_3 (PINCONF_FUNC5|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_SSP1_MOSI_1 (PINCONF_FUNC1|PINCONF_PINS0|PINCONF_PIN_1) +#define PINCONF_SSP1_MOSI_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_SSP1_MOSI_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_SSP1_SCK_1 (PINCONF_FUNC0|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_SSP1_SCK_2 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_19) +#define PINCONF_SSP1_SSEL_1 (PINCONF_FUNC1|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_SSP1_SSEL_2 (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_SSP1_SSEL_3 (PINCONF_FUNC5|PINCONF_PINS1|PINCONF_PIN_5) + +#define PINCONF_T0_CAP0_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_T0_CAP0_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_T0_CAP1_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_T0_CAP1_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_T0_CAP2_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_20) +#define PINCONF_T0_CAP2_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_T0_CAP3_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_T0_CAP3_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_T0_MAT0_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_T0_MAT0_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_T0_MAT1_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_T0_MAT1_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_T0_MAT2_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_T0_MAT2_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_T0_MAT3_1 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_T0_MAT3_2 (PINCONF_FUNC7|PINCONF_PINS8|PINCONF_PIN_3) + +#define PINCONF_T1_CAP0 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_T1_CAP1 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_T1_CAP2 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_T1_CAP3 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_T1_MAT0 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_T1_MAT1 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_T1_MAT2 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_6) +#define PINCONF_T1_MAT3 (PINCONF_FUNC5|PINCONF_PINS5|PINCONF_PIN_7) + +#define PINCONF_T2_CAP0 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_1) +#define PINCONF_T2_CAP1 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_T2_CAP2 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_T2_CAP3 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_T2_MAT0 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_T2_MAT1 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_T2_MAT2 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_9) +#define PINCONF_T2_MAT3 (PINCONF_FUNC5|PINCONF_PINS6|PINCONF_PIN_11) + +#define PINCONF_T3_CAP0_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_T3_CAP0_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_T3_CAP1_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_T3_CAP1_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_T3_CAP2_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_T3_CAP2_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_T3_CAP3_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_T3_CAP3_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_T3_MAT0_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_T3_MAT0_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_T3_MAT1_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_T3_MAT1_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_T3_MAT2_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_T3_MAT2_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_T3_MAT3_1 (PINCONF_FUNC6|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_T3_MAT3_2 (PINCONF_FUNC6|PINCONF_PINSC|PINCONF_PIN_10) + +#define PINCONF_TRACECLK (PINCONF_FUNC2|PINCONF_PINSF|PINCONF_PIN_4) +#define PINCONF_TRACEDATA0_1 (PINCONF_FUNC3|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_TRACEDATA0_2 (PINCONF_FUNC5|PINCONF_PINS7|PINCONF_PIN_4) +#define PINCONF_TRACEDATA1_1 (PINCONF_FUNC3|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_TRACEDATA1_2 (PINCONF_FUNC5|PINCONF_PINS7|PINCONF_PIN_5) +#define PINCONF_TRACEDATA2_1 (PINCONF_FUNC3|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_TRACEDATA2_2 (PINCONF_FUNC5|PINCONF_PINS7|PINCONF_PIN_6) +#define PINCONF_TRACEDATA3_1 (PINCONF_FUNC3|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_TRACEDATA3_2 (PINCONF_FUNC5|PINCONF_PINS7|PINCONF_PIN_7) + +#define PINCONF_U0_DIR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_U0_DIR_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_9) +#define PINCONF_U0_DIR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_2) +#define PINCONF_U0_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_U0_RXD_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_11) +#define PINCONF_U0_RXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_5) +#define PINCONF_U0_RXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_U0_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_U0_TXD_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_10) +#define PINCONF_U0_TXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_4) +#define PINCONF_U0_TXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_U0_UCLK_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_U0_UCLK_2 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_8) +#define PINCONF_U0_UCLK_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS6|PINCONF_PIN_1) + +#define PINCONF_U1_CTS_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_11) +#define PINCONF_U1_CTS_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_U1_CTS_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_7) +#define PINCONF_U1_CTS_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_4) +#define PINCONF_U1_DCD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_12) +#define PINCONF_U1_DCD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_U1_DCD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_9) +#define PINCONF_U1_DCD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_5) +#define PINCONF_U1_DSR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_U1_DSR_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_U1_DSR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_8) +#define PINCONF_U1_DSR_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_0) +#define PINCONF_U1_DTR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_8) +#define PINCONF_U1_DTR_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_12) +#define PINCONF_U1_DTR_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_10) +#define PINCONF_U1_DTR_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_1) +#define PINCONF_U1_RI_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_10) +#define PINCONF_U1_RI_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_U1_RI_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_6) +#define PINCONF_U1_RI_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_3) +#define PINCONF_U1_RTS_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_9) +#define PINCONF_U1_RTS_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_U1_RTS_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_5) +#define PINCONF_U1_RTS_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_2) +#define PINCONF_U1_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_14) +#define PINCONF_U1_RXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_14) +#define PINCONF_U1_RXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_12) +#define PINCONF_U1_RXD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_5) +#define PINCONF_U1_RXD_5 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_7) +#define PINCONF_U1_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_13) +#define PINCONF_U1_TXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSC|PINCONF_PIN_13) +#define PINCONF_U1_TXD_3 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSE|PINCONF_PIN_11) +#define PINCONF_U1_TXD_4 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS3|PINCONF_PIN_4) +#define PINCONF_U1_TXD_5 (PINCONF_FUNC4|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS5|PINCONF_PIN_6) + +#define PINCONF_U2_DIR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_18) +#define PINCONF_U2_DIR_2 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_13) +#define PINCONF_U2_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_16) +#define PINCONF_U2_RXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_11) +#define PINCONF_U2_RXD_3 (PINCONF_FUNC3|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_2) +#define PINCONF_U2_RXD_4 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_2) +#define PINCONF_U2_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_15) +#define PINCONF_U2_TXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_10) +#define PINCONF_U2_TXD_3 (PINCONF_FUNC3|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSA|PINCONF_PIN_1) +#define PINCONF_U2_TXD_4 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS7|PINCONF_PIN_1) +#define PINCONF_U2_UCLK_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS1|PINCONF_PIN_17) +#define PINCONF_U2_UCLK_2 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_12) + +#define PINCONF_U3_BAUD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_7) +#define PINCONF_U3_BAUD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_9) +#define PINCONF_U3_BAUD_3 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_3) +#define PINCONF_U3_DIR_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_6) +#define PINCONF_U3_DIR_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_8) +#define PINCONF_U3_DIR_3 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_4) +#define PINCONF_U3_RXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_3) +#define PINCONF_U3_RXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_4) +#define PINCONF_U3_RXD_3 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_2) +#define PINCONF_U3_RXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_U3_TXD_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_2) +#define PINCONF_U3_TXD_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_U3_TXD_3 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_1) +#define PINCONF_U3_TXD_4 (PINCONF_FUNC7|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_U3_UCLK_1 (PINCONF_FUNC1|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINSF|PINCONF_PIN_5) +#define PINCONF_U3_UCLK_2 (PINCONF_FUNC2|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS2|PINCONF_PIN_7) +#define PINCONF_U3_UCLK_3 (PINCONF_FUNC6|PINCONF_PULLUP|PINCONF_INBUFFER|PINCONF_PINS4|PINCONF_PIN_0) + +#define PINCONF_USB0_IND0_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_2) +#define PINCONF_USB0_IND0_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_6) +#define PINCONF_USB0_IND0_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_8) +#define PINCONF_USB0_IND0_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_4) +#define PINCONF_USB0_IND0_5 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_5) +#define PINCONF_USB0_IND1_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_1) +#define PINCONF_USB0_IND1_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_2) +#define PINCONF_USB0_IND1_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_7) +#define PINCONF_USB0_IND1_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_3) +#define PINCONF_USB0_PPWR_1 (PINCONF_FUNC1|PINCONF_PINS6|PINCONF_PIN_3) +#define PINCONF_USB0_PPWR_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_0) +#define PINCONF_USB0_PPWR_3 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_7) +#define PINCONF_USB0_PPWR_4 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_3) +#define PINCONF_USB0_PWR_FAULT_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_0) +#define PINCONF_USB0_PWR_FAULT_2 (PINCONF_FUNC3|PINCONF_PINS2|PINCONF_PIN_1) +#define PINCONF_USB0_PWR_FAULT_3 (PINCONF_FUNC3|PINCONF_PINS6|PINCONF_PIN_6) +#define PINCONF_USB0_PWR_FAULT_4 (PINCONF_FUNC4|PINCONF_PINS1|PINCONF_PIN_5) +#define PINCONF_USB0_PWR_FAULT_5 (PINCONF_FUNC7|PINCONF_PINS2|PINCONF_PIN_4) + +#define PINCONF_USB1_IND0_1 (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_4) +#define PINCONF_USB1_IND0_2 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_2) +#define PINCONF_USB1_IND1_1 (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_3) +#define PINCONF_USB1_IND1_2 (PINCONF_FUNC3|PINCONF_PINS3|PINCONF_PIN_1) +#define PINCONF_USB1_PPWR (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_5) +#define PINCONF_USB1_PWR_FAULT (PINCONF_FUNC2|PINCONF_PINS9|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_CLK_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_8) +#define PINCONF_USB1_ULPI_CLK_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_0) +#define PINCONF_USB1_ULPI_D0_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D0_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_8) +#define PINCONF_USB1_ULPI_D0_3 (PINCONF_FUNC5|PINCONF_PINSD|PINCONF_PIN_11) +#define PINCONF_USB1_ULPI_D1_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D1_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_7) +#define PINCONF_USB1_ULPI_D2_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D2_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_D3_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_D3_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D4_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_5) +#define PINCONF_USB1_ULPI_D4_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D5_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D5_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_4) +#define PINCONF_USB1_ULPI_D6_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_2) +#define PINCONF_USB1_ULPI_D6_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_3) +#define PINCONF_USB1_ULPI_D7_1 (PINCONF_FUNC0|PINCONF_PINSC|PINCONF_PIN_1) +#define PINCONF_USB1_ULPI_D7_2 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_2) +#define PINCONF_USB1_ULPI_DIR_1 (PINCONF_FUNC1|PINCONF_PINSB|PINCONF_PIN_1) +#define PINCONF_USB1_ULPI_DIR_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_11) +#define PINCONF_USB1_ULPI_NXT_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_6) +#define PINCONF_USB1_ULPI_NXT_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_9) +#define PINCONF_USB1_ULPI_STP_1 (PINCONF_FUNC1|PINCONF_PINS8|PINCONF_PIN_7) +#define PINCONF_USB1_ULPI_STP_2 (PINCONF_FUNC1|PINCONF_PINSC|PINCONF_PIN_10) +#define PINCONF_USB1_VBUS (PINCONF_FUNC2|PINCONF_PINS2|PINCONF_PIN_5) + +#define CLKCONF_CGU_OUT0 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK1) +#define CLKCONF_CGU_OUT1 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK3) +#define CLKCONF_CLKOUT_1 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK0) +#define CLKCONF_CLKOUT_2 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK1) +#define CLKCONF_CLKOUT_3 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK2) +#define CLKCONF_CLKOUT_4 (PINCONFIG_DIGITAL|PINCONF_FUNC1|PINCONF_CLK3) +#define CLKCONF_EMC_CLK0 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK0) +#define CLKCONF_EMC_CLK01 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK0) +#define CLKCONF_EMC_CLK1 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK1) +#define CLKCONF_EMC_CLK2 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK3) +#define CLKCONF_EMC_CLK23 (PINCONFIG_DIGITAL|PINCONF_FUNC5|PINCONF_CLK2) +#define CLKCONF_EMC_CLK3 (PINCONFIG_DIGITAL|PINCONF_FUNC0|PINCONF_CLK2) +#define CLKCONF_ENET_REF_CLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK0) +#define CLKCONF_ENET_TX_CLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK0) +#define CLKCONF_I2S0_TX_MCLK (PINCONFIG_DIGITAL|PINCONF_FUNC6|PINCONF_CLK2) +#define CLKCONF_I2S1_RX_SCK_1 (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK2) +#define CLKCONF_I2S1_RX_SCK_2 (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK3) +#define CLKCONF_I2S1_TX_MCLK (PINCONFIG_DIGITAL|PINCONF_FUNC7|PINCONF_CLK1) +#define CLKCONF_SD_CLK_1 (PINCONFIG_DIGITAL|PINCONF_FUNC4|PINCONF_CLK0) +#define CLKCONF_SD_CLK_2 (PINCONFIG_DIGITAL|PINCONF_FUNC4|PINCONF_CLK2) +#define CLKCONF_SSP1_SCK (PINCONFIG_DIGITAL|PINCONF_FUNC6|PINCONF_CLK0) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC4357FET256_PINCONF_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_adc.h b/arch/arm/src/lpc43xx/chip/lpc43_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..523cbcb45c9174f597c1bc8d949ebaeff8d2e4be --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_adc.h @@ -0,0 +1,198 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_adc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ADC_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_ADC_CR_OFFSET 0x0000 /* A/D Control Register */ +#define LPC43_ADC_GDR_OFFSET 0x0004 /* A/D Global Data Register */ +#define LPC43_ADC_INTEN_OFFSET 0x000c /* A/D Interrupt Enable Register */ + +#define LPC43_ADC_DR_OFFSET(n) (0x0010+((n) << 2)) +#define LPC43_ADC_DR0_OFFSET 0x0010 /* A/D Channel 0 Data Register */ +#define LPC43_ADC_DR1_OFFSET 0x0014 /* A/D Channel 1 Data Register */ +#define LPC43_ADC_DR2_OFFSET 0x0018 /* A/D Channel 2 Data Register */ +#define LPC43_ADC_DR3_OFFSET 0x001c /* A/D Channel 3 Data Register */ +#define LPC43_ADC_DR4_OFFSET 0x0020 /* A/D Channel 4 Data Register */ +#define LPC43_ADC_DR5_OFFSET 0x0024 /* A/D Channel 5 Data Register */ +#define LPC43_ADC_DR6_OFFSET 0x0028 /* A/D Channel 6 Data Register */ +#define LPC43_ADC_DR7_OFFSET 0x002c /* A/D Channel 7 Data Register */ + +#define LPC43_ADC_STAT_OFFSET 0x0030 /* A/D Status Register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_ADC0_CR (LPC43_ADC0_BASE+LPC43_ADC_CR_OFFSET) +#define LPC43_ADC0_GDR (LPC43_ADC0_BASE+LPC43_ADC_GDR_OFFSET) +#define LPC43_ADC0_INTEN (LPC43_ADC0_BASE+LPC43_ADC_INTEN_OFFSET) +#define LPC43_ADC0_DR(n) (LPC43_ADC0_BASE+LPC43_ADC_DR_OFFSET(n)) +#define LPC43_ADC0_DR0 (LPC43_ADC0_BASE+LPC43_ADC_DR0_OFFSET) +#define LPC43_ADC0_DR1 (LPC43_ADC0_BASE+LPC43_ADC_DR1_OFFSET) +#define LPC43_ADC0_DR2 (LPC43_ADC0_BASE+LPC43_ADC_DR2_OFFSET) +#define LPC43_ADC0_DR3 (LPC43_ADC0_BASE+LPC43_ADC_DR3_OFFSET) +#define LPC43_ADC0_DR4 (LPC43_ADC0_BASE+LPC43_ADC_DR4_OFFSET) +#define LPC43_ADC0_DR5 (LPC43_ADC0_BASE+LPC43_ADC_DR5_OFFSET) +#define LPC43_ADC0_DR6 (LPC43_ADC0_BASE+LPC43_ADC_DR6_OFFSET) +#define LPC43_ADC0_DR7 (LPC43_ADC0_BASE+LPC43_ADC_DR7_OFFSET) +#define LPC43_ADC0_STAT (LPC43_ADC0_BASE+LPC43_ADC_STAT_OFFSET) + +#define LPC43_ADC1_CR (LPC43_ADC1_BASE+LPC43_ADC_CR_OFFSET) +#define LPC43_ADC1_GDR (LPC43_ADC1_BASE+LPC43_ADC_GDR_OFFSET) +#define LPC43_ADC1_INTEN (LPC43_ADC1_BASE+LPC43_ADC_INTEN_OFFSET) +#define LPC43_ADC1_DR(n) (LPC43_ADC1_BASE+LPC43_ADC_DR_OFFSET(n)) +#define LPC43_ADC1_DR0 (LPC43_ADC1_BASE+LPC43_ADC_DR0_OFFSET) +#define LPC43_ADC1_DR1 (LPC43_ADC1_BASE+LPC43_ADC_DR1_OFFSET) +#define LPC43_ADC1_DR2 (LPC43_ADC1_BASE+LPC43_ADC_DR2_OFFSET) +#define LPC43_ADC1_DR3 (LPC43_ADC1_BASE+LPC43_ADC_DR3_OFFSET) +#define LPC43_ADC1_DR4 (LPC43_ADC1_BASE+LPC43_ADC_DR4_OFFSET) +#define LPC43_ADC1_DR5 (LPC43_ADC1_BASE+LPC43_ADC_DR5_OFFSET) +#define LPC43_ADC1_DR6 (LPC43_ADC1_BASE+LPC43_ADC_DR6_OFFSET) +#define LPC43_ADC1_DR7 (LPC43_ADC1_BASE+LPC43_ADC_DR7_OFFSET) +#define LPC43_ADC1_STAT (LPC43_ADC1_BASE+LPC43_ADC_STAT_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* A/D Control Register */ + +#define ADC_CR_SEL_SHIFT (0) /* Bits 0-7: Selects pins to be sampled */ +#define ADC_CR_SEL_MASK (0xff << ADC_CR_SEL_MASK) +#define ADC_CR_CLKDIV_SHIFT (8) /* Bits 8-15: APB clock (PCLK_ADC0) divisor */ +#define ADC_CR_CLKDIV_MASK (0xff << ADC_CR_CLKDIV_SHIFT) +#define ADC_CR_BURST (1 << 16) /* Bit 16: A/D Repeated conversions */ + +#define ADC_CR_CLKS_SHIFT (17) /* Bits 17-19: Number of clocks in conversion */ +#define ADC_CR_CLKS_MASK (7 << ADC_CR_CLKS_SHIFT) +# define ADC_CR_CLKS_11 (0 << ADC_CR_CLKS_SHIFT) /* 11 clocks / 10 bits */ +# define ADC_CR_CLKS_10 (1 << ADC_CR_CLKS_SHIFT) /* 10 clocks / 9 bits */ +# define ADC_CR_CLKS_9 (2 << ADC_CR_CLKS_SHIFT) /* 9 clocks / 8 bits */ +# define ADC_CR_CLKS_8 (3 << ADC_CR_CLKS_SHIFT) /* 8 clocks / 7 bits */ +# define ADC_CR_CLKS_7 (4 << ADC_CR_CLKS_SHIFT) /* 7 clocks / 6 bits */ +# define ADC_CR_CLKS_6 (5 << ADC_CR_CLKS_SHIFT) /* 6 clocks / 5 bits */ +# define ADC_CR_CLKS_5 (6 << ADC_CR_CLKS_SHIFT) /* 5 clocks / 4 bits */ +# define ADC_CR_CLKS_4 (7 << ADC_CR_CLKS_SHIFT) /* 4 clocks / 3 bits */ + /* Bit 20: Reserved */ +#define ADC_CR_PDN (1 << 21) /* Bit 21: A/D converter power-down mode */ + /* Bits 22-23: Reserved */ +#define ADC_CR_START_SHIFT (24) /* Bits 24-26: Control A/D conversion start */ +#define ADC_CR_START_MASK (7 << ADC_CR_START_SHIFT) +# define ADC_CR_START_NOSTART (0 << ADC_CR_START_SHIFT) /* No start */ +# define ADC_CR_START_NOW (1 << ADC_CR_START_SHIFT) /* Start now */ +# define ADC_CR_START_CTOUT15 (2 << ADC_CR_START_SHIFT) /* Start when edge on CTOUT_15 */ +# define ADC_CR_START_CTOUT8 (3 << ADC_CR_START_SHIFT) /* Start when edge on CTOUT_8 */ +# define ADC_CR_START_ADCTRIG0 (4 << ADC_CR_START_SHIFT) /* Start when edge on ADCTRIG0 */ +# define ADC_CR_START_ADCTRIG1 (5 << ADC_CR_START_SHIFT) /* Start when edge on ADCTRIG1 */ +# define ADC_CR_START_MCPWM (6 << ADC_CR_START_SHIFT) /* Start when edge on MCPWM */ +#define ADC_CR_EDGE (1 << 27) /* Bit 27: Start on falling edge */ + /* Bits 28-31: Reserved */ +/* A/D Global Data Register */ + /* Bits 0-3: Reserved */ +#define ADC_GDR_VVREF_SHIFT (6) /* Bits 6-15: Result of conversion (DONE==1) */ +#define ADC_GDR_VVREF_MASK (0x03ff << ADC_GDR_VVREF_SHIFT) + /* Bits 16-23: Reserved */ +#define ADC_GDR_CHAN_SHIFT (24) /* Bits 24-26: Channel converted */ +#define ADC_GDR_CHAN_MASK (3 << ADC_GDR_CHAN_SHIFT) + /* Bits 27-29: Reserved */ +#define ADC_GDR_OVERRUN (1 << 30) /* Bit 30: Conversion(s) lost/overwritten*/ +#define ADC_GDR_DONE (1 << 31) /* Bit 31: A/D conversion complete*/ + +/* A/D Interrupt Enable Register */ + +#define ADC_INTEN_CHAN(n) (1 << (n)) +#define ADC_INTEN_CHAN0 (1 << 0) /* Bit 0: Enable ADC chan 0 complete intterrupt */ +#define ADC_INTEN_CHAN1 (1 << 1) /* Bit 1: Enable ADC chan 1 complete interrupt */ +#define ADC_INTEN_CHAN2 (1 << 2) /* Bit 2: Enable ADC chan 2 complete interrupt */ +#define ADC_INTEN_CHAN3 (1 << 3) /* Bit 3: Enable ADC chan 3 complete interrupt */ +#define ADC_INTEN_CHAN4 (1 << 4) /* Bit 4: Enable ADC chan 4 complete interrupt */ +#define ADC_INTEN_CHAN5 (1 << 5) /* Bit 5: Enable ADC chan 5 complete interrupt */ +#define ADC_INTEN_CHAN6 (1 << 6) /* Bit 6: Enable ADC chan 6 complete interrupt */ +#define ADC_INTEN_CHAN7 (1 << 7) /* Bit 7: Enable ADC chan 7 complete interrupt */ +#define ADC_INTEN_GLOBAL (1 << 8) /* Bit 8: Only the global DONE generates interrupt */ + /* Bits 9-31: Reserved */ +/* Channel 0-7 A/D Data Register */ + /* Bits 0-3: Reserved */ +#define ADC_DR_VVREF_SHIFT (6) /* Bits 6-15: Result of conversion (DONE==1) */ +#define ADC_DR_VVREF_MASK (0x03ff << ADC_DR_VVREF_SHIFT) + /* Bits 16-29: Reserved */ +#define ADC_DR_OVERRUN (1 << 30) /* Bit 30: Conversion(s) lost/overwritten*/ +#define ADC_DR_DONE (1 << 31) /* Bit 31: A/D conversion complete*/ + +/* A/D Status Register */ + +#define ADC_STAT_DONE(n) (1 << (n)) +#define ADC_STAT_DONE0 (1 << 0) /* Bit 0: A/D chan 0 DONE */ +#define ADC_STAT_DONE1 (1 << 1) /* Bit 1: A/D chan 1 DONE */ +#define ADC_STAT_DONE2 (1 << 2) /* Bit 2: A/D chan 2 DONE */ +#define ADC_STAT_DONE3 (1 << 3) /* Bit 3: A/D chan 3 DONE */ +#define ADC_STAT_DONE4 (1 << 4) /* Bit 4: A/D chan 4 DONE */ +#define ADC_STAT_DONE5 (1 << 5) /* Bit 5: A/D chan 5 DONE */ +#define ADC_STAT_DONE6 (1 << 6) /* Bit 6: A/D chan 6 DONE */ +#define ADC_STAT_DONE7 (1 << 7) /* Bit 7: A/D chan 7 DONE */ +#define ADC_STAT_OVERRUN(n) ((1 << (n)) + 8) +#define ADC_STAT_OVERRUN0 (1 << 8) /* Bit 8: A/D chan 0 OVERRUN */ +#define ADC_STAT_OVERRUN1 (1 << 9) /* Bit 9: A/D chan 1 OVERRUN */ +#define ADC_STAT_OVERRUN2 (1 << 10) /* Bit 10: A/D chan 2 OVERRUN */ +#define ADC_STAT_OVERRUN3 (1 << 11) /* Bit 11: A/D chan 3 OVERRUN */ +#define ADC_STAT_OVERRUN4 (1 << 12) /* Bit 12: A/D chan 4 OVERRUN */ +#define ADC_STAT_OVERRUN5 (1 << 13) /* Bit 13: A/D chan 5 OVERRUN */ +#define ADC_STAT_OVERRUN6 (1 << 14) /* Bit 14: A/D chan 6 OVERRUN */ +#define ADC_STAT_OVERRUN7 (1 << 15) /* Bit 15: A/D chan 7 OVERRUN */ +#define ADC_STAT_INT (1 << 16) /* Bit 15: A/D interrupt */ + /* Bits 17-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ADC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_aes.h b/arch/arm/src/lpc43xx/chip/lpc43_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..e5f66d5f1ffc77ee46eb0f98f308499cf528f5d5 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_aes.h @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_aes.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_AES_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_AES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* The AES is controlled through a set of simple API calls located in the LPC43xx + * ROM. This value holds the pointer to the AES driver table. + */ + +#define LPC43_ROM_AES_DRIVER_TABLE LPC43_ROM_DRIVER_TABLE2 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +enum lpc43_aescmd_e +{ + AES_API_CMD_ENCODE_ECB = 0, + AES_API_CMD_DECODE_ECB = 1, + AES_API_CMD_ENCODE_CBC = 2, + AES_API_CMD_DECODE_CBC = 3 +}; + +struct lpc43_aes_s +{ + /* Initialize the AES engine */ + + void (*aes_Init)(void); + + /* Offset 0x04 -- Defines AES engine operation mode. See enum lpc43_aescmd_e */ + + unsigned int (*aes_SetMode)(unsigned int cmd); + + /* Load 128-bit AES user keys */ + + void (*aes_LoadKey1)(void); + void (*aes_LoadKey2)(void); + + /* Loads randomly generated key in AES engine. To update the RNG and load a new + * random number, use the API call otp_GenRand before aes_LoadKeyRNG. + */ + + void (*aes_LoadKeyRNG)(void); + + /* Loads 128-bit AES software defined user key (16 bytes) */ + + void (*aes_LoadKeySW)(unsigned char *key); + + /* Loads 128-bit AES initialization vector (16 bytes) */ + + void (*aes_LoadIV_SW)(unsigned char *iv); + + /* Loads 128-bit AES IC specific initialization vector, which is used to decrypt + * a boot image. + */ + + void (*aes_LoadIV_IC)(void); +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_AES_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_atimer.h b/arch/arm/src/lpc43xx/chip/lpc43_atimer.h new file mode 100644 index 0000000000000000000000000000000000000000..1a5ef860274e812a9518678e4466b97633bd151c --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_atimer.h @@ -0,0 +1,117 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_atimer.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ATIMER_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ATIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_ATIMER_COUNT_OFFSET 0x0000 /* Downcounter register */ +#define LPC43_ATIMER_PRESET_OFFSET 0x0004 /* Preset value register */ +#define LPC43_ATIMER_CLREN_OFFSET 0x0fd8 /* Interrupt clear enable register */ +#define LPC43_ATIMER_SETEN_OFFSET 0x0fdc /* Interrupt set enable register */ +#define LPC43_ATIMER_STATUS_OFFSET 0x0fe0 /* Status register */ +#define LPC43_ATIMER_ENABLE_OFFSET 0x0fe4 /* Enable register */ +#define LPC43_ATIMER_CLRSTAT_OFFSET 0x0fe8 /* Clear register */ +#define LPC43_ATIMER_SETSTAT_OFFSET 0x0fec /* Set register */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_ATIMER_COUNT (LPC43_ATIMER_BASE+LPC43_ATIMER_COUNT_OFFSET) +#define LPC43_ATIMER_PRESET (LPC43_ATIMER_BASE+LPC43_ATIMER_PRESET_OFFSET) +#define LPC43_ATIMER_CLREN (LPC43_ATIMER_BASE+LPC43_ATIMER_CLREN_OFFSET) +#define LPC43_ATIMER_SETEN (LPC43_ATIMER_BASE+LPC43_ATIMER_SETEN_OFFSET) +#define LPC43_ATIMER_STATUS (LPC43_ATIMER_BASE+LPC43_ATIMER_STATUS_OFFSET) +#define LPC43_ATIMER_ENABLE (LPC43_ATIMER_BASE+LPC43_ATIMER_ENABLE_OFFSET) +#define LPC43_ATIMER_CLRSTAT (LPC43_ATIMER_BASE+LPC43_ATIMER_CLRSTAT_OFFSET) +#define LPC43_ATIMER_SETSTAT (LPC43_ATIMER_BASE+LPC43_ATIMER_SETSTAT_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Downcounter register */ + +#define ATIMER_COUNT_MASK 0xffff /* Bits 0-15: Down counter */ + /* Bits 16-31: Reserved */ +/* Preset value register */ + +#define ATIMER_PRESET_MASK 0xffff /* Bits 0-15: Counter reload value */ + /* Bits 16-31: Reserved */ +/* Interrupt clear enable register */ + +#define ATIMER_CLREN (1 << 0) /* Bit 0: Clear interrupt enable */ + /* Bits 1-31: Reserved */ +/* Interrupt set enable register */ + +#define ATIMER_SETEN (1 << 0) /* Bit 0: Set interrupt enable */ + /* Bits 1-31: Reserved */ +/* Status register */ + +#define ATIMER_STATUS (1 << 0) /* Bit 0: Interrupt status */ + /* Bits 1-31: Reserved */ +/* Enable register */ + +#define ATIMER_ENABLE (1 << 0) /* Bit 0: Interrupt enable status */ + /* Bits 1-31: Reserved */ +/* Clear register */ + +#define ATIMER_CLRSTAT (1 << 0) /* Bit 0: Clear interrupt status */ + /* Bits 1-31: Reserved */ +/* Set register */ + +#define ATIMER_SETSTAT (1 << 0) /* Bit 0: Set interrupt status */ + /* Bits 1-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ATIMER_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_can.h b/arch/arm/src/lpc43xx/chip/lpc43_can.h new file mode 100644 index 0000000000000000000000000000000000000000..cebeaccd8ce4e1f35003f285243d0514e19c37f8 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_can.h @@ -0,0 +1,458 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_can.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CAN_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_CAN_CNTL_OFFSET 0x0000 /* CAN control register */ +#define LPC43_CAN_STAT_OFFSET 0x0004 /* Status register */ +#define LPC43_CAN_EC_OFFSET 0x0008 /* Error counter register */ +#define LPC43_CAN_BT_OFFSET 0x000c /* Bit timing register */ +#define LPC43_CAN_INT_OFFSET 0x0010 /* Interrupt register */ +#define LPC43_CAN_TEST_OFFSET 0x0014 /* Test register */ +#define LPC43_CAN_BRPE_OFFSET 0x0018 /* Baud rate prescaler extension register */ + +#define LPC43_CAN_IF1_CMDREQ_OFFSET 0x0020 /* Message interface 1 command request */ +#define LPC43_CAN_IF1_CMDMSKW_OFFSET 0x0024 /* Message interface 1 command mask (write) */ +#define LPC43_CAN_IF1_CMDMSKR_OFFSET 0x0024 /* Message interface 1 command mask (read) */ +#define LPC43_CAN_IF1_MSK1_OFFSET 0x0028 /* Message interface 1 mask 1 */ +#define LPC43_CAN_IF1_MSK2_OFFSET 0x002c /* Message interface 1 mask 2 */ +#define LPC43_CAN_IF1_ARB1_OFFSET 0x0030 /* Message interface 1 arbitration */ +#define LPC43_CAN_IF1_ARB2_OFFSET 0x0034 /* Message interface 1 arbitration */ +#define LPC43_CAN_IF1_MCTRL_OFFSET 0x0038 /* Message interface 1 message control */ +#define LPC43_CAN_IF1_DA1_OFFSET 0x003c /* Message interface 1 data A1 */ +#define LPC43_CAN_IF1_DA2_OFFSET 0x0040 /* Message interface 1 data A2 */ +#define LPC43_CAN_IF1_DB1_OFFSET 0x0044 /* Message interface 1 data B1 */ +#define LPC43_CAN_IF1_DB2_OFFSET 0x0048 /* Message interface 1 data B2 */ + +#define LPC43_CAN_IF2_CMDREQ_OFFSET 0x0080 /* Message interface 2 command request */ +#define LPC43_CAN_IF2_CMDMSKW_OFFSET 0x0084 /* Message interface 2 command mask (write) */ +#define LPC43_CAN_IF2_CMDMSKR_OFFSET 0x0084 /* Message interface 2 command mask (read) */ +#define LPC43_CAN_IF2_MSK1_OFFSET 0x0088 /* Message interface 2 mask 1 */ +#define LPC43_CAN_IF2_MSK2_OFFSET 0x008c /* Message interface 2 mask 2 */ +#define LPC43_CAN_IF2_ARB1_OFFSET 0x0090 /* Message interface 2 arbitration 1 */ +#define LPC43_CAN_IF2_ARB2_OFFSET 0x0094 /* Message interface 2 arbitration 2 */ +#define LPC43_CAN_IF2_MCTRL_OFFSET 0x0098 /* Message interface 2 message control */ +#define LPC43_CAN_IF2_DA1_OFFSET 0x009c /* Message interface 2 data A1 */ +#define LPC43_CAN_IF2_DA2_OFFSET 0x00a0 /* Message interface 2 data A2 */ +#define LPC43_CAN_IF2_DB1_OFFSET 0x00a4 /* Message interface 2 data B1 */ +#define LPC43_CAN_IF2_DB2_OFFSET 0x00a8 /* Message interface 2 data B2 */ + +#define LPC43_CAN_TXREQ1_OFFSET 0x0100 /* Transmission request 1 */ +#define LPC43_CAN_TXREQ2_OFFSET 0x0104 /* Transmission request 2 */ +#define LPC43_CAN_ND1_OFFSET 0x0120 /* New data 1 */ +#define LPC43_CAN_ND2_OFFSET 0x0124 /* New data 2 */ +#define LPC43_CAN_IR1_OFFSET 0x0140 /* Interrupt pending 1 */ +#define LPC43_CAN_IR2_OFFSET 0x0144 /* Interrupt pending 2 */ +#define LPC43_CAN_MSGV1_OFFSET 0x0160 /* Message valid 1 */ +#define LPC43_CAN_MSGV2_OFFSET 0x0164 /* Message valid 2 */ +#define LPC43_CAN_CLKDIV_OFFSET 0x0180 /* CAN clock divider register */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_CAN1_CNTL (LPC43_CAN1_BASE+LPC43_CAN_CNTL_OFFSET) +#define LPC43_CAN1_STAT (LPC43_CAN1_BASE+LPC43_CAN_STAT_OFFSET) +#define LPC43_CAN1_EC (LPC43_CAN1_BASE+LPC43_CAN_EC_OFFSET) +#define LPC43_CAN1_BT (LPC43_CAN1_BASE+LPC43_CAN_BT_OFFSET) +#define LPC43_CAN1_INT (LPC43_CAN1_BASE+LPC43_CAN_INT_OFFSET) +#define LPC43_CAN1_TEST (LPC43_CAN1_BASE+LPC43_CAN_TEST_OFFSET) +#define LPC43_CAN1_BRPE (LPC43_CAN1_BASE+LPC43_CAN_BRPE_OFFSET) + +#define LPC43_CAN1_IF1_CMDREQ (LPC43_CAN1_BASE+LPC43_CAN_IF1_CMDREQ_OFFSET) +#define LPC43_CAN1_IF1_CMDMSKW (LPC43_CAN1_BASE+LPC43_CAN_IF1_CMDMSKW_OFFSET) +#define LPC43_CAN1_IF1_CMDMSKR (LPC43_CAN1_BASE+LPC43_CAN_IF1_CMDMSKR_OFFSET) +#define LPC43_CAN1_IF1_MSK1 (LPC43_CAN1_BASE+LPC43_CAN_IF1_MSK1_OFFSET) +#define LPC43_CAN1_IF1_MSK2 (LPC43_CAN1_BASE+LPC43_CAN_IF1_MSK2_OFFSET) +#define LPC43_CAN1_IF1_ARB1 (LPC43_CAN1_BASE+LPC43_CAN_IF1_ARB1_OFFSET) +#define LPC43_CAN1_IF1_ARB2 (LPC43_CAN1_BASE+LPC43_CAN_IF1_ARB2_OFFSET) +#define LPC43_CAN1_IF1_MCTRL (LPC43_CAN1_BASE+LPC43_CAN_IF1_MCTRL_OFFSET) +#define LPC43_CAN1_IF1_DA1 (LPC43_CAN1_BASE+LPC43_CAN_IF1_DA1_OFFSET) +#define LPC43_CAN1_IF1_DA2 (LPC43_CAN1_BASE+LPC43_CAN_IF1_DA2_OFFSET) +#define LPC43_CAN1_IF1_DB1 (LPC43_CAN1_BASE+LPC43_CAN_IF1_DB1_OFFSET) +#define LPC43_CAN1_IF1_DB2 (LPC43_CAN1_BASE+LPC43_CAN_IF1_DB2_OFFSET) + +#define LPC43_CAN1_IF2_CMDREQ (LPC43_CAN1_BASE+LPC43_CAN_IF2_CMDREQ_OFFSET) +#define LPC43_CAN1_IF2_CMDMSKW (LPC43_CAN1_BASE+LPC43_CAN_IF2_CMDMSKW_OFFSET) +#define LPC43_CAN1_IF2_CMDMSKR (LPC43_CAN1_BASE+LPC43_CAN_IF2_CMDMSKR_OFFSET) +#define LPC43_CAN1_IF2_MSK1 (LPC43_CAN1_BASE+LPC43_CAN_IF2_MSK1_OFFSET) +#define LPC43_CAN1_IF2_MSK2 (LPC43_CAN1_BASE+LPC43_CAN_IF2_MSK2_OFFSET) +#define LPC43_CAN1_IF2_ARB1 (LPC43_CAN1_BASE+LPC43_CAN_IF2_ARB1_OFFSET) +#define LPC43_CAN1_IF2_ARB2 (LPC43_CAN1_BASE+LPC43_CAN_IF2_ARB2_OFFSET) +#define LPC43_CAN1_IF2_MCTRL (LPC43_CAN1_BASE+LPC43_CAN_IF2_MCTRL_OFFSET) +#define LPC43_CAN1_IF2_DA1 (LPC43_CAN1_BASE+LPC43_CAN_IF2_DA1_OFFSET) +#define LPC43_CAN1_IF2_DA2 (LPC43_CAN1_BASE+LPC43_CAN_IF2_DA2_OFFSET) +#define LPC43_CAN1_IF2_DB1 (LPC43_CAN1_BASE+LPC43_CAN_IF2_DB1_OFFSET) +#define LPC43_CAN1_IF2_DB2 (LPC43_CAN1_BASE+LPC43_CAN_IF2_DB2_OFFSET) + +#define LPC43_CAN1_TXREQ1 (LPC43_CAN1_BASE+LPC43_CAN_TXREQ1_OFFSET) +#define LPC43_CAN1_TXREQ2 (LPC43_CAN1_BASE+LPC43_CAN_TXREQ2_OFFSET) +#define LPC43_CAN1_ND1 (LPC43_CAN1_BASE+LPC43_CAN_ND1_OFFSET) +#define LPC43_CAN1_ND2 (LPC43_CAN1_BASE+LPC43_CAN_ND2_OFFSET) +#define LPC43_CAN1_IR1 (LPC43_CAN1_BASE+LPC43_CAN_IR1_OFFSET) +#define LPC43_CAN1_IR2 (LPC43_CAN1_BASE+LPC43_CAN_IR2_OFFSET) +#define LPC43_CAN1_MSGV1 (LPC43_CAN1_BASE+LPC43_CAN_MSGV1_OFFSET) +#define LPC43_CAN1_MSGV2 (LPC43_CAN1_BASE+LPC43_CAN_MSGV2_OFFSET) +#define LPC43_CAN1_CLKDIV (LPC43_CAN1_BASE+LPC43_CAN_CLKDIV_OFFSET) + +#define LPC43_CAN2_CNTL (LPC43_CAN2_BASE+LPC43_CAN_CNTL_OFFSET) +#define LPC43_CAN2_STAT (LPC43_CAN2_BASE+LPC43_CAN_STAT_OFFSET) +#define LPC43_CAN2_EC (LPC43_CAN2_BASE+LPC43_CAN_EC_OFFSET) +#define LPC43_CAN2_BT (LPC43_CAN2_BASE+LPC43_CAN_BT_OFFSET) +#define LPC43_CAN2_INT (LPC43_CAN2_BASE+LPC43_CAN_INT_OFFSET) +#define LPC43_CAN2_TEST (LPC43_CAN2_BASE+LPC43_CAN_TEST_OFFSET) +#define LPC43_CAN2_BRPE (LPC43_CAN2_BASE+LPC43_CAN_BRPE_OFFSET) + +#define LPC43_CAN2_IF1_CMDREQ (LPC43_CAN2_BASE+LPC43_CAN_IF1_CMDREQ_OFFSET) +#define LPC43_CAN2_IF1_CMDMSKW (LPC43_CAN2_BASE+LPC43_CAN_IF1_CMDMSKW_OFFSET) +#define LPC43_CAN2_IF1_CMDMSKR (LPC43_CAN2_BASE+LPC43_CAN_IF1_CMDMSKR_OFFSET) +#define LPC43_CAN2_IF1_MSK1 (LPC43_CAN2_BASE+LPC43_CAN_IF1_MSK1_OFFSET) +#define LPC43_CAN2_IF1_MSK2 (LPC43_CAN2_BASE+LPC43_CAN_IF1_MSK2_OFFSET) +#define LPC43_CAN2_IF1_ARB1 (LPC43_CAN2_BASE+LPC43_CAN_IF1_ARB1_OFFSET) +#define LPC43_CAN2_IF1_ARB2 (LPC43_CAN2_BASE+LPC43_CAN_IF1_ARB2_OFFSET) +#define LPC43_CAN2_IF1_MCTRL (LPC43_CAN2_BASE+LPC43_CAN_IF1_MCTRL_OFFSET) +#define LPC43_CAN2_IF1_DA1 (LPC43_CAN2_BASE+LPC43_CAN_IF1_DA1_OFFSET) +#define LPC43_CAN2_IF1_DA2 (LPC43_CAN2_BASE+LPC43_CAN_IF1_DA2_OFFSET) +#define LPC43_CAN2_IF1_DB1 (LPC43_CAN2_BASE+LPC43_CAN_IF1_DB1_OFFSET) +#define LPC43_CAN2_IF1_DB2 (LPC43_CAN2_BASE+LPC43_CAN_IF1_DB2_OFFSET) + +#define LPC43_CAN2_IF2_CMDREQ (LPC43_CAN2_BASE+LPC43_CAN_IF2_CMDREQ_OFFSET) +#define LPC43_CAN2_IF2_CMDMSKW (LPC43_CAN2_BASE+LPC43_CAN_IF2_CMDMSKW_OFFSET) +#define LPC43_CAN2_IF2_CMDMSKR (LPC43_CAN2_BASE+LPC43_CAN_IF2_CMDMSKR_OFFSET) +#define LPC43_CAN2_IF2_MSK1 (LPC43_CAN2_BASE+LPC43_CAN_IF2_MSK1_OFFSET) +#define LPC43_CAN2_IF2_MSK2 (LPC43_CAN2_BASE+LPC43_CAN_IF2_MSK2_OFFSET) +#define LPC43_CAN2_IF2_ARB1 (LPC43_CAN2_BASE+LPC43_CAN_IF2_ARB1_OFFSET) +#define LPC43_CAN2_IF2_ARB2 (LPC43_CAN2_BASE+LPC43_CAN_IF2_ARB2_OFFSET) +#define LPC43_CAN2_IF2_MCTRL (LPC43_CAN2_BASE+LPC43_CAN_IF2_MCTRL_OFFSET) +#define LPC43_CAN2_IF2_DA1 (LPC43_CAN2_BASE+LPC43_CAN_IF2_DA1_OFFSET) +#define LPC43_CAN2_IF2_DA2 (LPC43_CAN2_BASE+LPC43_CAN_IF2_DA2_OFFSET) +#define LPC43_CAN2_IF2_DB1 (LPC43_CAN2_BASE+LPC43_CAN_IF2_DB1_OFFSET) +#define LPC43_CAN2_IF2_DB2 (LPC43_CAN2_BASE+LPC43_CAN_IF2_DB2_OFFSET) + +#define LPC43_CAN2_TXREQ1 (LPC43_CAN2_BASE+LPC43_CAN_TXREQ1_OFFSET) +#define LPC43_CAN2_TXREQ2 (LPC43_CAN2_BASE+LPC43_CAN_TXREQ2_OFFSET) +#define LPC43_CAN2_ND1 (LPC43_CAN2_BASE+LPC43_CAN_ND1_OFFSET) +#define LPC43_CAN2_ND2 (LPC43_CAN2_BASE+LPC43_CAN_ND2_OFFSET) +#define LPC43_CAN2_IR1 (LPC43_CAN2_BASE+LPC43_CAN_IR1_OFFSET) +#define LPC43_CAN2_IR2 (LPC43_CAN2_BASE+LPC43_CAN_IR2_OFFSET) +#define LPC43_CAN2_MSGV1 (LPC43_CAN2_BASE+LPC43_CAN_MSGV1_OFFSET) +#define LPC43_CAN2_MSGV2 (LPC43_CAN2_BASE+LPC43_CAN_MSGV2_OFFSET) +#define LPC43_CAN2_CLKDIV (LPC43_CAN2_BASE+LPC43_CAN_CLKDIV_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* CAN control register */ + +#define CAN_CNTL_INIT (1 << 0) /* Bit 0: Initialization */ +#define CAN_CNTL_IE (1 << 1) /* Bit 1: Module interrupt enable */ +#define CAN_CNTL_SIE (1 << 2) /* Bit 2: Status change interrupt enable */ +#define CAN_CNTL_EIE (1 << 3) /* Bit 3: Error interrupt enable */ + /* Bit 4: Reserved */ +#define CAN_CNTL_DAR (1 << 5) /* Bit 5: Disable automatic retransmission */ +#define CAN_CNTL_CCE (1 << 6) /* Bit 6: Configuration change enable */ +#define CAN_CNTL_TEST (1 << 7) /* Bit 7: Test mode enable */ + /* Bits 8-31: Reserved */ +/* Status register */ + +#define CAN_STAT_LEC_SHIFT (0) /* Bits 0-2: Last error code */ +#define CAN_STAT_LEC_MASK (7 << CAN_STAT_LEC_SHIFT) +#define CAN_STAT_LEC_NOE (0 << CAN_STAT_LEC_SHIFT) /* No error */ +#define CAN_STAT_LEC_STUFFE (1 << CAN_STAT_LEC_SHIFT) /* Stuff error */ +#define CAN_STAT_LEC_FORME (2 << CAN_STAT_LEC_SHIFT) /* Form error */ +#define CAN_STAT_LEC_ACKE (3 << CAN_STAT_LEC_SHIFT) /* AckError */ +#define CAN_STAT_LEC_BI1E (4 << CAN_STAT_LEC_SHIFT) /* Bit1Error */ +#define CAN_STAT_LEC_BIT0E (5 << CAN_STAT_LEC_SHIFT) /* Bit0Error */ +#define CAN_STAT_LEC_CRCE (6 << CAN_STAT_LEC_SHIFT) /* CRCError */ +#define CAN_STAT_TXOK (1 << 3) /* Bit 3: Transmitted a message successfully */ +#define CAN_STAT_RXOK (1 << 4) /* Bit 4: Received a message successfully */ +#define CAN_STAT_EPASS (1 << 5) /* Bit 5: Error passive */ +#define CAN_STAT_EWARN (1 << 6) /* Bit 6: Warning status */ +#define CAN_STAT_BOFF (1 << 7) /* Bit 7: Busoff status */ + /* Bits 8-31: Reserved */ +/* Error counter register */ + +#define CAN_EC_TEC_SHIFT (0) /* Bits 0-7: Transmit error counter */ +#define CAN_EC_TEC_MASK (0xff << CAN_EC_TEC_SHIFT) +#define CAN_EC_REC_SHIFT (8) /* Bits 8-14: Receive error counter */ +#define CAN_EC_REC_MASK (0x7f << CAN_EC_REC_SHIFT) +#define CAN_EC_RP (1 << 15) /* Bit 15: Receive error passive */ + /* Bits 16-31: Reserved */ +/* Bit timing register */ + +#define CAN_BT_BRP_SHIFT (0) /* Bits 0-5: Baud rate prescaler */ +#define CAN_BT_BRP_MASK (0x3f << CAN_BT_BRP_SHIFT) +#define CAN_BT_SJW_SHIFT (6) /* Bits 6-7: (Re)synchronization jump width */ +#define CAN_BT_SJW_MASK (3 << CAN_BT_SJW_SHIFT) +#define CAN_BT_TSEG1_SHIFT (8) /* Bits 8-11: Time segment after the sample point */ +#define CAN_BT_TSEG1_MASK (15 << CAN_BT_TSEG1_SHIFT) +#define CAN_BT_TSEG2_SHIFT (12) /* Bits 12-14: Time segment before the sample point */ +#define CAN_BT_TSEG2_MASK (7 << CAN_BT_TSEG2_SHIFT) + /* Bits 15-31: Reserved */ +/* Interrupt register */ + +#define CAN_INT_SHIFT (0) /* Bits 0-15: Interrupt ID */ +#define CAN_INT_MASK (0xffff << CAN_INT_SHIFT) +# define CAN_INT_NONE (0 << CAN_INT_SHIFT) /* No interrupt pending */ +# define CAN_INT_MSG1 (1 << CAN_INT_SHIFT) /* Message 1 */ +# define CAN_INT_MSG2 (2 << CAN_INT_SHIFT) /* Message 2 */ +# define CAN_INT_MSG3 (3 << CAN_INT_SHIFT) /* Message 3 */ +# define CAN_INT_MSG4 (4 << CAN_INT_SHIFT) /* Message 4 */ +# define CAN_INT_MSG5 (5 << CAN_INT_SHIFT) /* Message 5 */ +# define CAN_INT_MSG6 (6 << CAN_INT_SHIFT) /* Message 6 */ +# define CAN_INT_MSG7 (7 << CAN_INT_SHIFT) /* Message 7 */ +# define CAN_INT_MSG8 (8 << CAN_INT_SHIFT) /* Message 8 */ +# define CAN_INT_MSG9 (9 << CAN_INT_SHIFT) /* Message 9 */ +# define CAN_INT_MSG10 (10 << CAN_INT_SHIFT) /* Message 10 */ +# define CAN_INT_MSG11 (11 << CAN_INT_SHIFT) /* Message 11 */ +# define CAN_INT_MSG12 (12 << CAN_INT_SHIFT) /* Message 12 */ +# define CAN_INT_MSG13 (13 << CAN_INT_SHIFT) /* Message 13 */ +# define CAN_INT_MSG14 (14 << CAN_INT_SHIFT) /* Message 14 */ +# define CAN_INT_MSG15 (15 << CAN_INT_SHIFT) /* Message 15 */ +# define CAN_INT_MSG16 (16 << CAN_INT_SHIFT) /* Message 16 */ +# define CAN_INT_MSG17 (17 << CAN_INT_SHIFT) /* Message 17 */ +# define CAN_INT_MSG18 (18 << CAN_INT_SHIFT) /* Message 18 */ +# define CAN_INT_MSG19 (19 << CAN_INT_SHIFT) /* Message 19 */ +# define CAN_INT_MSG20 (20 << CAN_INT_SHIFT) /* Message 20 */ +# define CAN_INT_MSG21 (21 << CAN_INT_SHIFT) /* Message 21 */ +# define CAN_INT_MSG22 (22 << CAN_INT_SHIFT) /* Message 22 */ +# define CAN_INT_MSG23 (23 << CAN_INT_SHIFT) /* Message 23 */ +# define CAN_INT_MSG24 (24 << CAN_INT_SHIFT) /* Message 24 */ +# define CAN_INT_MSG25 (25 << CAN_INT_SHIFT) /* Message 25 */ +# define CAN_INT_MSG26 (26 << CAN_INT_SHIFT) /* Message 26 */ +# define CAN_INT_MSG27 (27 << CAN_INT_SHIFT) /* Message 27 */ +# define CAN_INT_MSG28 (28 << CAN_INT_SHIFT) /* Message 28 */ +# define CAN_INT_MSG29 (29 << CAN_INT_SHIFT) /* Message 29 */ +# define CAN_INT_MSG30 (30 << CAN_INT_SHIFT) /* Message 30 */ +# define CAN_INT_MSG31 (31 << CAN_INT_SHIFT) /* Message 31 */ +# define CAN_INT_MSG32 (32 << CAN_INT_SHIFT) /* Message 32 */ +# define CAN_INT_MSG32 (0x8000 << CAN_INT_SHIFT) /* Status interrupt */ + /* Bits 16-31: Reserved */ +/* Test register */ + /* Bits 0-1: Reserved */ +#define CAN_TEST_BASIC (1 << 2) /* Bit 2: Basic mode */ +#define CAN_TEST_SILENT (1 << 3) /* Bit 3: Silent mode */ +#define CAN_TEST_LBACK (1 << 4) /* Bit 4: Loop back mode */ +#define CAN_TEST_TX_SHIFT (5) /* Bits 5-6: Control of TD pins */ +#define CAN_TEST_TX_MASK (3 << CAN_TEST_TX_SHIFT) +# define CAN_TEST_TX_CAN (0 << CAN_TEST_TX_SHIFT) /* Level controlled CAN controller */ +# define CAN_TEST_TX_MONITOR (1 << CAN_TEST_TX_SHIFT) /* Sample point monitored TD pin */ +# define CAN_TEST_TX_DOMINANT (2 << CAN_TEST_TX_SHIFT) /* TD pin LOW/dominant */ +# define CAN_TEST_TX_RECESSIVE (3 << CAN_TEST_TX_SHIFT) /* TD pin HIGH/recessive */ +#define CAN_TEST_RX (1 << 7) /* Bit 7: Monitors actual value of RD Pin */ + /* Bits 8-31: Reserved */ +/* Baud rate prescaler extension register */ + +#define CAN_BRPE_SHIFT (0) /* Bits 0-3: Baud rate prescaler extension */ +#define CAN_BRPE_MASK (15 << CAN_BRPE_SHIFT) + /* Bits 4-31: Reserved */ +/* Message interface 1/2 command request */ + +#define CAN_CMDREQ_MSGNO_SHIFT (0) /* Bits 0-5: Message number */ +#define CAN_CMDREQ_MSGNO_MASK (0x3f << CAN_CMDREQ_MSGNO_SHIFT) + /* Bits 6-14: Reserved */ +#define CAN_CMDREQ_BUSY (1 << 15) /* Bit 15: BUSY flag */ + /* Bits 16-31: Reserved */ +/* Message interface 1/2 command mask (write) */ + +#define CAN_CMDMSKW_DATAB (1 << 0) /* Bit 0: Access data bytes 4-7 */ +#define CAN_CMDMSKW_DATAA (1 << 1) /* Bit 1: Access data bytes 0-3 */ +#define CAN_CMDMSKW_TXRQST (1 << 2) /* Bit 2: Access transmission request bit */ +#define CAN_CMDMSKW_CLRINTPND (1 << 3) /* Bit 3: Ignored in the write direction */ +#define CAN_CMDMSKW_CTRL (1 << 4) /* Bit 4: Access control bits */ +#define CAN_CMDMSKW_ARB (1 << 5) /* Bit 5: Access arbitration bits */ +#define CAN_CMDMSKW_MASK (1 << 6) /* Bit 6: Access mask bits */ +#define CAN_CMDMSKW_WRRD (1 << 7) /* Bit 7: Write transfer (1) */ + /* Bits 8-31: Reserved */ +/* Message interface 1/2 command mask (read) */ + +#define CAN_CMDMSKR_DATAB (1 << 0) /* Bit 0: Access data bytes 4-7 */ +#define CAN_CMDMSKR_DATAA (1 << 1) /* Bit 1: Access data bytes 0-3 */ +#define CAN_CMDMSKR_NEWDAT (1 << 2) /* Bit 2: Access new data bit */ +#define CAN_CMDMSKR_CLRINTPND (1 << 3) /* Bit 3: Clear interrupt pending bit */ +#define CAN_CMDMSKR_CTRL (1 << 4) /* Bit 4: Access control bits */ +#define CAN_CMDMSKR_ARB (1 << 5) /* Bit 5: Access arbitration bits */ +#define CAN_CMDMSKR_MASK (1 << 6) /* Bit 6: Access mask bits */ +#define CAN_CMDMSKR_WRRD (1 << 7) /* Bit 7: Read transfer (0) */ + /* Bits 8-31: Reserved */ +/* Message interface 1/2 mask 1 */ + +#define CAN_MSK1 0xffff /* Bits 0-15: Identifier mask 0-15 */ + /* Bits 16-31: Reserved */ +/* Message interface 1/2 mask 2 */ + +#define CAN_MSK2 0x1fff /* Bits 0-12: Identifier mask 16-28 */ + /* Bit 13: Reserved */ +#define CAN_MSK2_MDIR (1 << 14) /* Bit 14: Mask message direction */ +#define CAN_MSK2_MXTD (1 << 15) /* Bit 15: Mask extend identifier */ + /* Bits 16-31: Reserved */ +/* Message interface 1/2 arbitration */ + +#define CAN_ARB1 0xffff /* Bits 0-15: Identifier mask 0-15 */ + /* Bits 16-31: Reserved */ +/* Message interface 1/2 arbitration */ + +#define CAN_MSK2 0x1fff /* Bits 0-12: Identifier mask 16-28 */ +#define CAN_MSK2_DIR (1 << 13) /* Bit 13: Message direction */ +#define CAN_MSK2_XTD (1 << 14) /* Bit 14: Extend identifier */ +#define CAN_MSK2_MSGVAL (1 << 15) /* Bit 15: Message valid */ + /* Bits 16-31: Reserved */ +/* Message interface 1 message control */ + +#define CAN_MCTRL_DLC_SHIFT (0) /* Bits 0-3: Data length code */ +#define CAN_MCTRL_DLC_MASK (15 << CAN_MCTRL_DLC_SHIFT) + /* Bits 4-6: Reserved */ +#define CAN_MCTRL_EOB (1 << 7) /* Bit 7: End of buffer */ +#define CAN_MCTRL_TXRQST (1 << 8) /* Bit 8: Transmit request */ +#define CAN_MCTRL_RMTEN (1 << 9) /* Bit 9: Remote enable */ +#define CAN_MCTRL_RXIE (1 << 10) /* Bit 10: Receive interrupt enable */ +#define CAN_MCTRL_TXIE (1 << 11) /* Bit 11: Transmit interrupt enable */ +#define CAN_MCTRL_UMASK (1 << 12) /* Bit 12: Use acceptance mask */ +#define CAN_MCTRL_INTPND (1 << 13) /* Bit 13: Interrupt pending */ +#define CAN_MCTRL_MSGLST (1 << 14) /* Bit 14: Message lost */ +#define CAN_MCTRL_NEWDAT (1 << 15) /* Bit 15: New data */ + /* Bits 16-31: Reserved */ +/* Message interface 1/2 data A1 */ + +#define CAN_DA1_DATA0_SHIFT (0) /* Bits 0-7: Data byte 0 */ +#define CAN_DA1_DATA0_MASK (0xff << CAN_DA1_DATA0_SHIFT) +#define CAN_DA1_DATA1_SHIFT (8) /* Bits 8-15: Data byte 1 */ +#define CAN_DA1_DATA1_MASK (0xff << CAN_DA1_DATA1_SHIFT) + /* Bits 16-31: Reserved */ +/* Message interface 1/2 data A2 */ + +#define CAN_DA2_DATA2_SHIFT (0) /* Bits 0-7: Data byte 2 */ +#define CAN_DA2_DATA2_MASK (0xff << CAN_DA2_DATA2_SHIFT) +#define CAN_DA2_DATA3_SHIFT (8) /* Bits 8-15: Data byte 3 */ +#define CAN_DA2_DATA3_MASK (0xff << CAN_DA2_DATA3_SHIFT) + /* Bits 16-31: Reserved */ +/* Message interface 1/2 data B1 */ + +#define CAN_DB1_DATA4_SHIFT (0) /* Bits 0-7: Data byte 4 */ +#define CAN_DB1_DATA4_MASK (0xff << CAN_DB1_DATA4_SHIFT) +#define CAN_DB1_DATA5_SHIFT (8) /* Bits 8-15: Data byte 5 */ +#define CAN_DB1_DATA5_MASK (0xff << CAN_DB1_DATA5_SHIFT) + /* Bits 16-31: Reserved */ +/* Message interface 1/2 data B2 */ + +#define CAN_DB2_DATA6_SHIFT (0) /* Bits 0-7: Data byte 6 */ +#define CAN_DB2_DATA6_MASK (0xff << CAN_DB2_DATA6_SHIFT) +#define CAN_DB2_DATA7_SHIFT (8) /* Bits 8-15: Data byte 7 */ +#define CAN_DB2_DATA7_MASK (0xff << CAN_DB2_DATA6_SHIFT) + /* Bits 16-31: Reserved */ +/* Transmission request 1 */ + +#define CAN_TXREQ1_MASK 0xffff /* Bits 0-15: TX request bit msg 1-16 */ +#define CAN_TXREQ1(n) (1 << ((n)-1) + /* Bits 16-31: Reserved */ +/* Transmission request 2 */ + +#define CAN_TXREQ2_MASK 0xffff /* Bits 0-15: TX request bit msg 17-32 */ +#define CAN_TXREQ2(n) (1 << ((n)-17) + /* Bits 16-31: Reserved */ +/* New data 1 */ + +#define CAN_ND1_MASK 0xffff /* Bits 0-15: New data bits msg 1-16 */ +#define CAN_ND1(n) (1 << ((n)-1) + /* Bits 16-31: Reserved */ +/* New data 2 */ + +#define CAN_ND2_MASK 0xffff /* Bits 0-15: New data bits msg 17-32 */ +#define CAN_ND2(n) (1 << ((n)-17) + /* Bits 16-31: Reserved */ +/* Interrupt pending 1 */ + +#define CAN_IR1_MASK 0xffff /* Bits 0-15: Interrup pending msg 1-16 */ +#define CAN_IR1(n) (1 << ((n)-1) + /* Bits 16-31: Reserved */ +/* Interrupt pending 2 */ + +#define CAN_IR2_MASK 0xffff /* Bits 0-15: Interrup pending msg 17-32 */ +#define CAN_IR2(n) (1 << ((n)-17) + /* Bits 16-31: Reserved */ +/* Message valid 1 */ + +#define CAN_MSGV1_MASK 0xffff /* Bits 0-15: Interrup pending msg 1-16 */ +#define CAN_MSGV1(n) (1 << ((n)-1) + /* Bits 16-31: Reserved */ +/* Message valid 2 */ + +#define CAN_MSGV2_MASK 0xffff /* Bits 0-15: Interrup pending msg 17-32 */ +#define CAN_MSGV2(n) (1 << ((n)-17) + /* Bits 16-31: Reserved */ +/* CAN clock divider register */ + +#define CAN_CLKDIV_SHIFT (0) /* Bits 0-3: Clock divider value */ +#define CAN_CLKDIV_MASK (15 << CAN_CLKDIV_SHIFT) +# define CAN_CLKDIV_DIV1 (0 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 1 */ +# define CAN_CLKDIV_DIV2 (1 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 2 */ +# define CAN_CLKDIV_DIV3 (2 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 3 */ +# define CAN_CLKDIV_DIV5 (3 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 5 */ +# define CAN_CLKDIV_DIV9 (4 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 9 */ +# define CAN_CLKDIV_DIV 17 (5 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 17 */ +# define CAN_CLKDIV_DIV33 (6 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 33 */ +# define CAN_CLKDIV_DIV65 (7 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 65 */ +# define CAN_CLKDIV_DIV129 (8 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 129 */ +# define CAN_CLKDIV_DIV257 (9 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 257 */ +# define CAN_CLKDIV_DIV513 (10 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 513 */ +# define CAN_CLKDIV_DIV1025 (11 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 1025 */ +# define CAN_CLKDIV_DIV2049 (12 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 2049 */ +# define CAN_CLKDIV_DIV4097 (13 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 4097 */ +# define CAN_CLKDIV_DIV8093 (14 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 8093 */ +# define CAN_CLKDIV_DIV16385 (15 << CAN_CLKDIV_SHIFT) /* CAN_CLK = PCLK / 16385 */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CAN_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_ccu.h b/arch/arm/src/lpc43xx/chip/lpc43_ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..a2cb20ca62f67d823682ab60232c816dea209923 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_ccu.h @@ -0,0 +1,358 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_ccu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CCU_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CCU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_CCU1_PM_OFFSET 0x0000 /* CCU1 power mode register */ +#define LPC43_CCU1_BASE_STAT_OFFSET 0x0004 /* CCU1 base clock status register */ +#define LPC43_CCU1_APB3_BUS_CFG_OFFSET 0x0100 /* CLK_APB3_BUS clock configuration register */ +#define LPC43_CCU1_APB3_BUS_STAT_OFFSET 0x0104 /* CLK_APB3_BUS clock status register */ +#define LPC43_CCU1_APB3_I2C1_CFG_OFFSET 0x0108 /* CLK_APB3_I2C1 configuration register */ +#define LPC43_CCU1_APB3_I2C1_STAT_OFFSET 0x010c /* CLK_APB3_I2C1 status register */ +#define LPC43_CCU1_APB3_DAC_CFG_OFFSET 0x0110 /* CLK_APB3_DAC configuration register */ +#define LPC43_CCU1_APB3_DAC_STAT_OFFSET 0x0114 /* CLK_APB3_DAC status register */ +#define LPC43_CCU1_APB3_ADC0_CFG_OFFSET 0x0118 /* CLK_APB3_ADC0 configuration register */ +#define LPC43_CCU1_APB3_ADC0_STAT_OFFSET 0x011c /* CLK_APB3_ADC0 status register */ +#define LPC43_CCU1_APB3_ADC1_CFG_OFFSET 0x0120 /* CLK_APB3_ADC1 configuration register */ +#define LPC43_CCU1_APB3_ADC1_STAT_OFFSET 0x0124 /* CLK_APB3_ADC1 status register */ +#define LPC43_CCU1_APB3_CAN0_CFG_OFFSET 0x0128 /* CLK_APB3_CAN0 configuration register */ +#define LPC43_CCU1_APB3_CAN0_STAT_OFFSET 0x012c /* CLK_APB3_CAN0 status register */ +#define LPC43_CCU1_APB1_BUS_CFG_OFFSET 0x0200 /* CLK_APB1_BUS configuration register */ +#define LPC43_CCU1_APB1_BUS_STAT_OFFSET 0x0204 /* CLK_APB1_BUS status register */ +#define LPC43_CCU1_APB1_MCPWM_CFG_OFFSET 0x0208 /* CLK_APB1_MOTOCON configuration register */ +#define LPC43_CCU1_APB1_MCPWM_STAT_OFFSET 0x020c /* CLK_APB1_MOTOCON status register */ +#define LPC43_CCU1_APB1_I2C0_CFG_OFFSET 0x0210 /* CLK_APB1_I2C0 configuration register */ +#define LPC43_CCU1_APB1_I2C0_STAT_OFFSET 0x0214 /* CLK_APB1_I2C0 status register */ +#define LPC43_CCU1_APB1_I2S_CFG_OFFSET 0x0218 /* CLK_APB1_I2S configuration register */ +#define LPC43_CCU1_APB1_I2S_STAT_OFFSET 0x021c /* CLK_APB1_I2S status register */ +#define LPC43_CCU1_APB1_CAN1_CFG_OFFSET 0x0220 /* CLK_APB3_CAN1 configuration register */ +#define LPC43_CCU1_APB1_CAN1_STAT_OFFSET 0x0224 /* CLK_APB3_CAN1 status register */ +#define LPC43_CCU1_SPIFI_CFG_OFFSET 0x0300 /* CLK_SPIFI configuration register */ +#define LPC43_CCU1_SPIFI_STAT_OFFSET 0x0304 /* CLK_SPIFI status register */ +#define LPC43_CCU1_M4_BUS_CFG_OFFSET 0x0400 /* CLK_M4_BUS configuration register */ +#define LPC43_CCU1_M4_BUS_STAT_OFFSET 0x0404 /* CLK_M4_BUS status register */ +#define LPC43_CCU1_M4_SPIFI_CFG_OFFSET 0x0408 /* CLK_M4_SPIFI configuration register */ +#define LPC43_CCU1_M4_SPIFI_STAT_OFFSET 0x040c /* CLK_M4_SPIFI status register */ +#define LPC43_CCU1_M4_GPIO_CFG_OFFSET 0x0410 /* CLK_M4_GPIO configuration register */ +#define LPC43_CCU1_M4_GPIO_STAT_OFFSET 0x0414 /* CLK_M4_GPIO status register */ +#define LPC43_CCU1_M4_LCD_CFG_OFFSET 0x0418 /* CLK_M4_LCD configuration register */ +#define LPC43_CCU1_M4_LCD_STAT_OFFSET 0x041c /* CLK_M4_LCD status register */ +#define LPC43_CCU1_M4_ETHERNET_CFG_OFFSET 0x0420 /* CLK_M4_ETHERNET configuration register */ +#define LPC43_CCU1_M4_ETHERNET_STAT_OFFSET 0x0424 /* CLK_M4_ETHERNET status register */ +#define LPC43_CCU1_M4_USB0_CFG_OFFSET 0x0428 /* CLK_M4_USB0 configuration register */ +#define LPC43_CCU1_M4_USB0_STAT_OFFSET 0x042c /* CLK_M4_USB0 status register */ +#define LPC43_CCU1_M4_EMC_CFG_OFFSET 0x0430 /* CLK_M4_EMC configuration register */ +#define LPC43_CCU1_M4_EMC_STAT_OFFSET 0x0434 /* CLK_M4_EMC status register */ +#define LPC43_CCU1_M4_SDIO_CFG_OFFSET 0x0438 /* CLK_M4_SDIO configuration register */ +#define LPC43_CCU1_M4_SDIO_STAT_OFFSET 0x043c /* CLK_M4_SDIO status register */ +#define LPC43_CCU1_M4_DMA_CFG_OFFSET 0x0440 /* CLK_M4_DMA configuration register */ +#define LPC43_CCU1_M4_DMA_STAT_OFFSET 0x0444 /* CLK_M4_DMA status register */ +#define LPC43_CCU1_M4_M4CORE_CFG_OFFSET 0x0448 /* CLK_M4_M4CORE configuration register */ +#define LPC43_CCU1_M4_M4CORE_STAT_OFFSET 0x044c /* CLK_M4_M4CORE status register */ +#define LPC43_CCU1_M4_SCT_CFG_OFFSET 0x0468 /* CLK_M4_SCT configuration register */ +#define LPC43_CCU1_M4_SCT_STAT_OFFSET 0x046c /* CLK_M4_SCT status register */ +#define LPC43_CCU1_M4_USB1_CFG_OFFSET 0x0470 /* CLK_M4_USB1 configuration register */ +#define LPC43_CCU1_M4_USB1_STAT_OFFSET 0x0474 /* CLK_M4_USB1 status register */ +#define LPC43_CCU1_M4_EMCDIV_CFG_OFFSET 0x0478 /* CLK_M4_EMCDIV configuration register */ +#define LPC43_CCU1_M4_EMCDIV_STAT_OFFSET 0x047c /* CLK_M4_EMCDIV status register */ +#define LPC43_CCU1_M4_FLASHA_CFG_OFFSET 0x0480 /* CLK_M4_FLASHA configuration register */ +#define LPC43_CCU1_M4_FLASHA_STAT_OFFSET 0x0484 /* CLK_M4_FLASHA status register */ +#define LPC43_CCU1_M4_FLASHB_CFG_OFFSET 0x0488 /* CLK_M4_FLASHB configuration register */ +#define LPC43_CCU1_M4_FLASHB_STAT_OFFSET 0x048c /* CLK_M4_FLASHB status register */ +#define LPC43_CCU1_M4_M0APP_CFG_OFFSET 0x0490 /* CLK_M4_M0_CFG configuration register */ +#define LPC43_CCU1_M4_M0APP_STAT_OFFSET 0x0494 /* CLK_M4_M0_STAT status register */ +#define LPC43_CCU1_M4_VADC_CFG_OFFSET 0x0498 /* CLK_M4_VADC_CFG configuration register */ +#define LPC43_CCU1_M4_VADC_STAT_OFFSET 0x049c /* CLK_M4_VADC_STAT configuration register */ +#define LPC43_CCU1_M4_EEPROM_CFG_OFFSET 0x04a0 /* CLK_M4_EEPROM configuration register */ +#define LPC43_CCU1_M4_EEPROM_STAT_OFFSET 0x04a4 /* CLK_M4_EEPROM status register */ +#define LPC43_CCU1_M4_WWDT_CFG_OFFSET 0x0500 /* CLK_M4_WWDT configuration register */ +#define LPC43_CCU1_M4_WWDT_STAT_OFFSET 0x0504 /* CLK_M4_WWDT status register */ +#define LPC43_CCU1_M4_USART0_CFG_OFFSET 0x0508 /* CLK_M4_USART0 configuration register */ +#define LPC43_CCU1_M4_USART0_STAT_OFFSET 0x050c /* CLK_M4_USART0 status register */ +#define LPC43_CCU1_M4_UART1_CFG_OFFSET 0x0510 /* CLK_M4_UART1 configuration register */ +#define LPC43_CCU1_M4_UART1_STAT_OFFSET 0x0514 /* CLK_M4_UART1 status register */ +#define LPC43_CCU1_M4_SSP0_CFG_OFFSET 0x0518 /* CLK_M4_SSP0 configuration register */ +#define LPC43_CCU1_M4_SSP0_STAT_OFFSET 0x051c /* CLK_M4_SSP0 status register */ +#define LPC43_CCU1_M4_TIMER0_CFG_OFFSET 0x0520 /* CLK_M4_TIMER0 configuration register */ +#define LPC43_CCU1_M4_TIMER0_STAT_OFFSET 0x0524 /* CLK_M4_TIMER0 status register */ +#define LPC43_CCU1_M4_TIMER1_CFG_OFFSET 0x0528 /* CLK_M4_TIMER1 configuration register */ +#define LPC43_CCU1_M4_TIMER1_STAT_OFFSET 0x052c /* CLK_M4_TIMER1 status register */ +#define LPC43_CCU1_M4_SCU_CFG_OFFSET 0x0530 /* CLK_M4_SCU configuration register */ +#define LPC43_CCU1_M4_SCU_STAT_OFFSET 0x0534 /* CLK_M4_SCU status register */ +#define LPC43_CCU1_M4_CREG_CFG_OFFSET 0x0538 /* CLK_M4_CREG configuration register */ +#define LPC43_CCU1_M4_CREG_STAT_OFFSET 0x053c /* CLK_M4_CREG status register */ +#define LPC43_CCU1_M4_UART1_RS485CTRL_OFFSET 0x054c /* CLK_M4_UART1 RS485 Control register */ +#define LPC43_CCU1_M4_RITIMER_CFG_OFFSET 0x0600 /* CLK_M4_RITIMER configuration register */ +#define LPC43_CCU1_M4_RITIMER_STAT_OFFSET 0x0604 /* CLK_M4_RITIMER status register */ +#define LPC43_CCU1_M4_USART2_CFG_OFFSET 0x0608 /* CLK_M4_USART2 configuration register */ +#define LPC43_CCU1_M4_USART2_STAT_OFFSET 0x060c /* CLK_M4_USART2 status register */ +#define LPC43_CCU1_M4_USART3_CFG_OFFSET 0x0610 /* CLK_M4_USART3 configuration register */ +#define LPC43_CCU1_M4_USART3_STAT_OFFSET 0x0614 /* CLK_M4_USART3 status register */ +#define LPC43_CCU1_M4_TIMER2_CFG_OFFSET 0x0618 /* CLK_M4_TIMER2 configuration register */ +#define LPC43_CCU1_M4_TIMER2_STAT_OFFSET 0x061c /* CLK_M4_TIMER2 status register */ +#define LPC43_CCU1_M4_TIMER3_CFG_OFFSET 0x0620 /* CLK_M4_TIMER3 configuration register */ +#define LPC43_CCU1_M4_TIMER3_STAT_OFFSET 0x0624 /* CLK_M4_TIMER3 status register */ +#define LPC43_CCU1_M4_SSP1_CFG_OFFSET 0x0628 /* CLK_M4_SSP1 configuration register */ +#define LPC43_CCU1_M4_SSP1_STAT_OFFSET 0x062c /* CLK_M4_SSP1 status register */ +#define LPC43_CCU1_M4_QEI_CFG_OFFSET 0x0630 /* CLK_M4_QEI configuration register */ +#define LPC43_CCU1_M4_QEI_STAT_OFFSET 0x0634 /* CLK_M4_QEI status register */ +#define LPC43_CCU1_PERIPH_BUS_CFG_OFFSET 0x0700 /* CLK_PERIPH_BUS configuration register */ +#define LPC43_CCU1_PERIPH_BUS_STAT_OFFSET 0x0704 /* CLK_PERIPH_BUS status register */ +#define LPC43_CCU1_PERIPH_CORE_CFG_OFFSET 0x0710 /* CLK_PERIPH_CORE configuration register */ +#define LPC43_CCU1_PERIPH_CORE_STAT_OFFSET 0x0714 /* CLK_PERIPH_CORE status register */ +#define LPC43_CCU1_PERIPH_SGPIO_CFG_OFFSET 0x0718 /* CLK_PERIPH_SGPIO configuration register */ +#define LPC43_CCU1_PERIPH_SGPIO_STAT_OFFSET 0x071c /* CLK_PERIPH_SGPIO status register */ +#define LPC43_CCU1_USB0_CFG_OFFSET 0x0800 /* CLK_USB0 configuration register */ +#define LPC43_CCU1_USB0_STAT_OFFSET 0x0804 /* CLK_USB0 status register */ +#define LPC43_CCU1_USB1_CFG_OFFSET 0x0900 /* CLK_USB1 configuration register */ +#define LPC43_CCU1_USB1_STAT_OFFSET 0x0904 /* CLK_USB1 status register */ +#define LPC43_CCU1_SPI_CFG_OFFSET 0x0a00 /* CLK_SPI configuration register */ +#define LPC43_CCU1_SPI_STAT_OFFSET 0x0a04 /* CLK_SPI status register */ +#define LPC43_CCU1_VADC_CFG_OFFSET 0x0b00 /* CLK_VADC configuration register */ +#define LPC43_CCU1_VADC_STAT_OFFSET 0x0b04 /* CLK_VADC status register */ + +#define LPC43_CCU2_PM_OFFSET 0x0000 /* CCU2 power mode register */ +#define LPC43_CCU2_BASE_STAT_OFFSET 0x0004 /* CCU2 base clocks status register */ +#define LPC43_CCU2_APLL_CFG_OFFSET 0x0100 /* CLK_APLL configuration register */ +#define LPC43_CCU2_APLL_STAT_OFFSET 0x0104 /* CLK_APLL status register */ +#define LPC43_CCU2_APB2_USART3_CFG_OFFSET 0x0200 /* CLK_APB2_USART3 configuration register */ +#define LPC43_CCU2_APB2_USART3_STAT_OFFSET 0x0204 /* CLK_APB2_USART3 status register */ +#define LPC43_CCU2_APB2_USART2_CFG_OFFSET 0x0300 /* CLK_APB2_USART2 configuration register */ +#define LPC43_CCU2_APB2_USART2_STAT_OFFSET 0x0304 /* CLK_APB2_USART2 status register */ +#define LPC43_CCU2_APB0_UART1_CFG_OFFSET 0x0400 /* CLK_APB0_UART1 configuration register */ +#define LPC43_CCU2_APB0_UART1_STAT_OFFSET 0x0404 /* CLK_APB0_UART1 status register */ +#define LPC43_CCU2_APB0_USART0_CFG_OFFSET 0x0500 /* CLK_APB0_USART0 configuration register */ +#define LPC43_CCU2_APB0_USART0_STAT_OFFSET 0x0504 /* CLK_APB0_USART0 status register */ +#define LPC43_CCU2_APB2_SSP1_CFG_OFFSET 0x0600 /* CLK_APB2_SSP1 configuration register */ +#define LPC43_CCU2_APB2_SSP1_STAT_OFFSET 0x0604 /* CLK_APB2_SSP1 status register */ +#define LPC43_CCU2_APB0_SSP0_CFG_OFFSET 0x0700 /* CLK_APB0_SSP0 configuration register */ +#define LPC43_CCU2_APB0_SSP0_STAT_OFFSET 0x0704 /* CLK_APB0_SSP0 status register */ +#define LPC43_CCU2_SDIO_CFG_OFFSET 0x0800 /* CLK_SDIO configuration register (for SD/MMC) */ +#define LPC43_CCU2_SDIO_STAT_OFFSET 0x0804 /* CLK_SDIO status register (for SD/MMC) */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_CCU1_PM (LPC43_CCU1_BASE+LPC43_CCU1_PM_OFFSET) +#define LPC43_CCU1_BASE_STAT (LPC43_CCU1_BASE+LPC43_CCU1_BASE_STAT_OFFSET) +#define LPC43_CCU1_APB3_BUS_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_BUS_CFG_OFFSET) +#define LPC43_CCU1_APB3_BUS_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_BUS_STAT_OFFSET) +#define LPC43_CCU1_APB3_I2C1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_I2C1_CFG_OFFSET) +#define LPC43_CCU1_APB3_I2C1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_I2C1_STAT_OFFSET) +#define LPC43_CCU1_APB3_DAC_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_DAC_CFG_OFFSET) +#define LPC43_CCU1_APB3_DAC_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_DAC_STAT_OFFSET) +#define LPC43_CCU1_APB3_ADC0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_ADC0_CFG_OFFSET) +#define LPC43_CCU1_APB3_ADC0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_ADC0_STAT_OFFSET) +#define LPC43_CCU1_APB3_ADC1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_ADC1_CFG_OFFSET) +#define LPC43_CCU1_APB3_ADC1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_ADC1_STAT_OFFSET) +#define LPC43_CCU1_APB3_CAN0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB3_CAN0_CFG_OFFSET) +#define LPC43_CCU1_APB3_CAN0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB3_CAN0_STAT_OFFSET) +#define LPC43_CCU1_APB1_BUS_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB1_BUS_CFG_OFFSET) +#define LPC43_CCU1_APB1_BUS_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB1_BUS_STAT_OFFSET) +#define LPC43_CCU1_APB1_MCPWM_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB1_MCPWM_CFG_OFFSET) +#define LPC43_CCU1_APB1_MCPWM_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB1_MCPWM_STAT_OFFSET) +#define LPC43_CCU1_APB1_I2C0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB1_I2C0_CFG_OFFSET) +#define LPC43_CCU1_APB1_I2C0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB1_I2C0_STAT_OFFSET) +#define LPC43_CCU1_APB1_I2S_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB1_I2S_CFG_OFFSET) +#define LPC43_CCU1_APB1_I2S_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB1_I2S_STAT_OFFSET) +#define LPC43_CCU1_APB1_CAN1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_APB1_CAN1_CFG_OFFSET) +#define LPC43_CCU1_APB1_CAN1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_APB1_CAN1_STAT_OFFSET) +#define LPC43_CCU1_SPIFI_CFG (LPC43_CCU1_BASE+LPC43_CCU1_SPIFI_CFG_OFFSET) +#define LPC43_CCU1_SPIFI_STAT (LPC43_CCU1_BASE+LPC43_CCU1_SPIFI_STAT_OFFSET) +#define LPC43_CCU1_M4_BUS_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_BUS_CFG_OFFSET) +#define LPC43_CCU1_M4_BUS_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_BUS_STAT_OFFSET) +#define LPC43_CCU1_M4_SPIFI_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SPIFI_CFG_OFFSET) +#define LPC43_CCU1_M4_SPIFI_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SPIFI_STAT_OFFSET) +#define LPC43_CCU1_M4_GPIO_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_GPIO_CFG_OFFSET) +#define LPC43_CCU1_M4_GPIO_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_GPIO_STAT_OFFSET) +#define LPC43_CCU1_M4_LCD_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_LCD_CFG_OFFSET) +#define LPC43_CCU1_M4_LCD_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_LCD_STAT_OFFSET) +#define LPC43_CCU1_M4_ETHERNET_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_ETHERNET_CFG_OFFSET) +#define LPC43_CCU1_M4_ETHERNET_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_ETHERNET_STAT_OFFSET) +#define LPC43_CCU1_M4_USB0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_USB0_CFG_OFFSET) +#define LPC43_CCU1_M4_USB0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_USB0_STAT_OFFSET) +#define LPC43_CCU1_M4_EMC_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_EMC_CFG_OFFSET) +#define LPC43_CCU1_M4_EMC_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_EMC_STAT_OFFSET) +#define LPC43_CCU1_M4_SDIO_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SDIO_CFG_OFFSET) +#define LPC43_CCU1_M4_SDIO_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SDIO_STAT_OFFSET) +#define LPC43_CCU1_M4_DMA_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_DMA_CFG_OFFSET) +#define LPC43_CCU1_M4_DMA_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_DMA_STAT_OFFSET) +#define LPC43_CCU1_M4_M4CORE_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_M4CORE_CFG_OFFSET) +#define LPC43_CCU1_M4_M4CORE_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_M4CORE_STAT_OFFSET) +#define LPC43_CCU1_M4_SCT_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SCT_CFG_OFFSET) +#define LPC43_CCU1_M4_SCT_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SCT_STAT_OFFSET) +#define LPC43_CCU1_M4_USB1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_USB1_CFG_OFFSET) +#define LPC43_CCU1_M4_USB1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_USB1_STAT_OFFSET) +#define LPC43_CCU1_M4_EMCDIV_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_EMCDIV_CFG_OFFSET) +#define LPC43_CCU1_M4_EMCDIV_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_EMCDIV_STAT_OFFSET) +#define LPC43_CCU1_M4_FLASHA_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_FLASHA_CFG_OFFSET) +#define LPC43_CCU1_M4_FLASHA_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_FLASHA_STAT_OFFSET) +#define LPC43_CCU1_M4_FLASHB_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_FLASHB_CFG_OFFSET) +#define LPC43_CCU1_M4_FLASHB_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_FLASHB_STAT_OFFSET) +#define LPC43_CCU1_M4_M0APP_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_M0APP_CFG_OFFSET) +#define LPC43_CCU1_M4_M0APP_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_M0APP_STAT_OFFSET) +#define LPC43_CCU1_M4_VADC_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_VADC_CFG_OFFSET) +#define LPC43_CCU1_M4_VADC_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_VADC_STAT_OFFSET) +#define LPC43_CCU1_M4_EEPROM_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_EEPROM_CFG_OFFSET) +#define LPC43_CCU1_M4_EEPROM_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_EEPROM_STAT_OFFSET) +#define LPC43_CCU1_M4_WWDT_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_WWDT_CFG_OFFSET) +#define LPC43_CCU1_M4_WWDT_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_WWDT_STAT_OFFSET) +#define LPC43_CCU1_M4_USART0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART0_CFG_OFFSET) +#define LPC43_CCU1_M4_USART0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART0_STAT_OFFSET) +#define LPC43_CCU1_M4_UART1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_UART1_CFG_OFFSET) +#define LPC43_CCU1_M4_UART1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_UART1_STAT_OFFSET) +#define LPC43_CCU1_M4_SSP0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SSP0_CFG_OFFSET) +#define LPC43_CCU1_M4_SSP0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SSP0_STAT_OFFSET) +#define LPC43_CCU1_M4_TIMER0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER0_CFG_OFFSET) +#define LPC43_CCU1_M4_TIMER0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER0_STAT_OFFSET) +#define LPC43_CCU1_M4_TIMER1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER1_CFG_OFFSET) +#define LPC43_CCU1_M4_TIMER1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER1_STAT_OFFSET) +#define LPC43_CCU1_M4_SCU_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SCU_CFG_OFFSET) +#define LPC43_CCU1_M4_SCU_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SCU_STAT_OFFSET) +#define LPC43_CCU1_M4_CREG_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_CREG_CFG_OFFSET) +#define LPC43_CCU1_M4_CREG_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_CREG_STAT_OFFSET) +#define LPC43_CCU1_M4_UART1_RS485CTRL (LPC43_CCU1_BASE+LPC43_CCU1_M4_UART1_RS485CTRL_OFFSET) +#define LPC43_CCU1_M4_RITIMER_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_RITIMER_CFG_OFFSET) +#define LPC43_CCU1_M4_RITIMER_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_RITIMER_STAT_OFFSET) +#define LPC43_CCU1_M4_USART2_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART2_CFG_OFFSET) +#define LPC43_CCU1_M4_USART2_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART2_STAT_OFFSET) +#define LPC43_CCU1_M4_USART3_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART3_CFG_OFFSET) +#define LPC43_CCU1_M4_USART3_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_USART3_STAT_OFFSET) +#define LPC43_CCU1_M4_TIMER2_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER2_CFG_OFFSET) +#define LPC43_CCU1_M4_TIMER2_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER2_STAT_OFFSET) +#define LPC43_CCU1_M4_TIMER3_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER3_CFG_OFFSET) +#define LPC43_CCU1_M4_TIMER3_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_TIMER3_STAT_OFFSET) +#define LPC43_CCU1_M4_SSP1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_SSP1_CFG_OFFSET) +#define LPC43_CCU1_M4_SSP1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_SSP1_STAT_OFFSET) +#define LPC43_CCU1_M4_QEI_CFG (LPC43_CCU1_BASE+LPC43_CCU1_M4_QEI_CFG_OFFSET) +#define LPC43_CCU1_M4_QEI_STAT (LPC43_CCU1_BASE+LPC43_CCU1_M4_QEI_STAT_OFFSET) +#define LPC43_CCU1_PERIPH_BUS_CFG (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_BUS_CFG_OFFSET) +#define LPC43_CCU1_PERIPH_BUS_STAT (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_BUS_STAT_OFFSET) +#define LPC43_CCU1_PERIPH_CORE_CFG (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_CORE_CFG_OFFSET) +#define LPC43_CCU1_PERIPH_CORE_STAT (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_CORE_STAT_OFFSET) +#define LPC43_CCU1_PERIPH_SGPIO_CFG (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_SGPIO_CFG_OFFSET) +#define LPC43_CCU1_PERIPH_SGPIO_STAT (LPC43_CCU1_BASE+LPC43_CCU1_PERIPH_SGPIO_STAT_OFFSET) +#define LPC43_CCU1_USB0_CFG (LPC43_CCU1_BASE+LPC43_CCU1_USB0_CFG_OFFSET) +#define LPC43_CCU1_USB0_STAT (LPC43_CCU1_BASE+LPC43_CCU1_USB0_STAT_OFFSET) +#define LPC43_CCU1_USB1_CFG (LPC43_CCU1_BASE+LPC43_CCU1_USB1_CFG_OFFSET) +#define LPC43_CCU1_USB1_STAT (LPC43_CCU1_BASE+LPC43_CCU1_USB1_STAT_OFFSET) +#define LPC43_CCU1_SPI_CFG (LPC43_CCU1_BASE+LPC43_CCU1_SPI_CFG_OFFSET) +#define LPC43_CCU1_SPI_STAT (LPC43_CCU1_BASE+LPC43_CCU1_SPI_STAT_OFFSET) +#define LPC43_CCU1_VADC_CFG (LPC43_CCU1_BASE+LPC43_CCU1_VADC_CFG_OFFSET) +#define LPC43_CCU1_VADC_STAT (LPC43_CCU1_BASE+LPC43_CCU1_VADC_STAT_OFFSET) + +#define LPC43_CCU2_PM (LPC43_CCU2_BASE+LPC43_CCU2_PM_OFFSET) +#define LPC43_CCU2_BASE_STAT (LPC43_CCU2_BASE+LPC43_CCU2_BASE_STAT_OFFSET) +#define LPC43_CCU2_APLL_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APLL_CFG_OFFSET) +#define LPC43_CCU2_APLL_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APLL_STAT_OFFSET) +#define LPC43_CCU2_APB2_USART3_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB2_USART3_CFG_OFFSET) +#define LPC43_CCU2_APB2_USART3_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB2_USART3_STAT_OFFSET) +#define LPC43_CCU2_APB2_USART2_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB2_USART2_CFG_OFFSET) +#define LPC43_CCU2_APB2_USART2_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB2_USART2_STAT_OFFSET) +#define LPC43_CCU2_APB0_UART1_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB0_UART1_CFG_OFFSET) +#define LPC43_CCU2_APB0_UART1_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB0_UART1_STAT_OFFSET) +#define LPC43_CCU2_APB0_USART0_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB0_USART0_CFG_OFFSET) +#define LPC43_CCU2_APB0_USART0_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB0_USART0_STAT_OFFSET) +#define LPC43_CCU2_APB2_SSP1_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB2_SSP1_CFG_OFFSET) +#define LPC43_CCU2_APB2_SSP1_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB2_SSP1_STAT_OFFSET) +#define LPC43_CCU2_APB0_SSP0_CFG (LPC43_CCU2_BASE+LPC43_CCU2_APB0_SSP0_CFG_OFFSET) +#define LPC43_CCU2_APB0_SSP0_STAT (LPC43_CCU2_BASE+LPC43_CCU2_APB0_SSP0_STAT_OFFSET) +#define LPC43_CCU2_SDIO_CFG (LPC43_CCU2_BASE+LPC43_CCU2_SDIO_CFG_OFFSET) +#define LPC43_CCU2_SDIO_STAT (LPC43_CCU2_BASE+LPC43_CCU2_SDIO_STAT_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* CCU1/2 Power Mode Register */ + +#define CCU_PM_PD (1 << 0) /* Bit 0: Initiate power-down mode */ + /* Bits 1-31: Reserved */ +/* CCU1 Base Clock Status Register */ + +#define CCU1_BASE_STAT_AB3 (1 << 0) /* Bit 0: Base clock indicator for BASE_APB3_CLK */ +#define CCU1_BASE_STAT_APB1 (1 << 1) /* Bit 1: Base clock indicator for BASE_APB1_CLK */ +#define CCU1_BASE_STAT_SPIFI (1 << 2) /* Bit 2: Base clock indicator for BASE_SPIFI_CLK */ +#define CCU1_BASE_STAT_M4 (1 << 3) /* Bit 3: Base clock indicator for BASE_M4_CLK */ + /* Bits 4-5: Reserved */ +#define CCU1_BASE_STAT_PERIPH (1 << 6) /* Bit 6: Base clock indicator for BASE_PERIPH_CLK */ +#define CCU1_BASE_STAT_USB0 (1 << 7) /* Bit 7: Base clock indicator for BASE_USB0_CLK */ +#define CCU1_BASE_STAT_USB1 (1 << 8) /* Bit 8: Base clock indicator for BASE_USB1_CLK */ +#define CCU1_BASE_STAT_SPI (1 << 9) /* Bit 9: Base clock indicator for BASE_SPI_CLK */ + /* Bits 10-31: Reserved */ +/* CCU2 Base Clock Status Register */ + /* Bit 0: Reserved */ +#define CCU2_BASE_STAT_USART3 (1 << 1) /* Bit 1: Base clock indicator for BASE_USART3_CLK */ +#define CCU2_BASE_STAT_USART2 (1 << 2) /* Bit 2: Base clock indicator for BASE_USART2_CLK */ +#define CCU2_BASE_STAT_UART1 (1 << 3) /* Bit 3: Base clock indicator for BASE_UART1_CLK */ +#define CCU2_BASE_STAT_USART0 (1 << 4) /* Bit 4: Base clock indicator for BASE_USART0_CLK */ +#define CCU2_BASE_STAT_SSP1 (1 << 5) /* Bit 5: Base clock indicator for BASE_SSP1_CLK */ +#define CCU2_BASE_STAT_SSP0 (1 << 6) /* Bit 6: Base clock indicator for BASE_SSP0_CLK */ + /* Bits 7-31: Reserved */ +/* CCU1/2 Branch Clock Configuration/Status Registers */ + +#define CCU_CLK_CFG_RUN (1 << 0) /* Bit 0: Run enable */ +#define CCU_CLK_CFG_AUTO (1 << 1) /* Bit 1: Auto (AHB disable mechanism) enable */ +#define CCU_CLK_CFG_WAKEUP (1 << 2) /* Bit 2: Wake-up mechanism enable */ + /* Bits 3-31: Reserved */ +/* CCU1/2 Branch Clock Status Registers */ + +#define CCU_CLK_STAT_RUN (1 << 0) /* Bit 0: Run enable status */ +#define CCU_CLK_STAT_AUTO (1 << 1) /* Bit 1: Auto (AHB disable mechanism) enable status */ +#define CCU_CLK_STAT_WAKEUP (1 << 2) /* Bit 2: Wake-up mechanism enable status */ + /* Bits 3-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CCU_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_cgu.h b/arch/arm/src/lpc43xx/chip/lpc43_cgu.h new file mode 100644 index 0000000000000000000000000000000000000000..bd9682c8fd444d076e52da49a6ba2d40202fd162 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_cgu.h @@ -0,0 +1,866 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_cgu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CGU_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CGU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_FREQ_MON_OFFSET 0x0014 /* Frequency monitor register */ +#define LPC43_XTAL_OSC_CTRL_OFFSET 0x0018 /* Crystal oscillator control register */ +#define LPC43_PLL0USB_STAT_OFFSET 0x001c /* PLL0USB status register */ +#define LPC43_PLL0USB_CTRL_OFFSET 0x0020 /* PLL0USB control register */ +#define LPC43_PLL0USB_MDIV_OFFSET 0x0024 /* PLL0USB M-divider register */ +#define LPC43_PLL0USB_NP_DIV_OFFSET 0x0028 /* PLL0USB N/P-divider register */ +#define LPC43_PLL0AUDIO_STAT_OFFSET 0x002c /* PLL0AUDIO status register */ +#define LPC43_PLL0AUDIO_CTRL_OFFSET 0x0030 /* PLL0AUDIO control register */ +#define LPC43_PLL0AUDIO_MDIV_OFFSET 0x0034 /* PLL0AUDIO M-divider */ +#define LPC43_PLL0AUDIO_NP_DIV_OFFSET 0x0038 /* PLL0AUDIO N/P-divider */ +#define LPC43_PLL0AUDIO_FRAC_OFFSET 0x003c /* PLL0AUDIO fractional */ +#define LPC43_PLL1_STAT_OFFSET 0x0040 /* PLL1 status register */ +#define LPC43_PLL1_CTRL_OFFSET 0x0044 /* PLL1 control register */ +#define LPC43_IDIVA_CTRL_OFFSET 0x0048 /* Integer divider A control register */ +#define LPC43_IDIVB_CTRL_OFFSET 0x004c /* Integer divider B control register */ +#define LPC43_IDIVC_CTRL_OFFSET 0x0050 /* Integer divider C control register */ +#define LPC43_IDIVD_CTRL_OFFSET 0x0054 /* Integer divider D control register */ +#define LPC43_IDIVE_CTRL_OFFSET 0x0058 /* Integer divider E control register */ +#define LPC43_BASE_SAFE_CLK_OFFSET 0x005c /* Output stage 0 control register (BASE_SAFE_CLK) */ +#define LPC43_BASE_USB0_CLK_OFFSET 0x0060 /* Output stage 1 control register (BASE_USB0_CLK) */ +#define LPC43_BASE_PERIPH_CLK_OFFSET 0x0064 /* Output stage 2 control register (BASE_PERIPH_CLK) */ +#define LPC43_BASE_USB1_CLK_OFFSET 0x0068 /* Output stage 3 control register (BASE_USB1_CLK) */ +#define LPC43_BASE_M4_CLK_OFFSET 0x006c /* Output stage 4 control register (BASE_M4_CLK) */ +#define LPC43_BASE_SPIFI_CLK_OFFSET 0x0070 /* Output stage 5 control register (BASE_SPIFI_CLK) */ +#define LPC43_BASE_SPI_CLK_OFFSET 0x0074 /* Output stage 6 control register (BASE_SPI_CLK) */ +#define LPC43_BASE_PHYRX_CLK_OFFSET 0x0078 /* Output stage 7 control register (BASE_PHY_RX_CLK) */ +#define LPC43_BASE_PHYTX_CLK_OFFSET 0x007c /* Output stage 8 control register (BASE_PHY_TX_CLK) */ +#define LPC43_BASE_APB1_CLK_OFFSET 0x0080 /* Output stage 9 control register (BASE_APB1_CLK) */ +#define LPC43_BASE_APB3_CLK_OFFSET 0x0084 /* Output stage 10 control register (BASE_APB3_CLK) */ +#define LPC43_BASE_LCD_CLK_OFFSET 0x0088 /* Output stage 11 control register (BASE_LCD_CLK) */ +#define LPC43_BASE_VADC_CLK_OFFSET 0x008c /* Output stage 12 control register (BASE_VADC_CLK) */ +#define LPC43_BASE_SDIO_CLK_OFFSET 0x0090 /* Output stage 13 control register (BASE_SDIO_CLK) */ +#define LPC43_BASE_SSP0_CLK_OFFSET 0x0094 /* Output stage 14 control register (BASE_SSP0_CLK) */ +#define LPC43_BASE_SSP1_CLK_OFFSET 0x0098 /* Output stage 15 control register (BASE_SSP1_CLK) */ +#define LPC43_BASE_USART0_CLK_OFFSET 0x009c /* Output stage 16 control register (BASE_USART0_CLK) */ +#define LPC43_BASE_UART1_CLK_OFFSET 0x00a0 /* Output stage 17 control register (BASE_UART1_CLK) */ +#define LPC43_BASE_USART2_CLK_OFFSET 0x00a4 /* Output stage 18 control register (BASE_USART2_CLK) */ +#define LPC43_BASE_USART3_CLK_OFFSET 0x00a8 /* Output stage 19 control register (BASE_USART3_CLK) */ +#define LPC43_BASE_OUT_CLK_OFFSET 0x00ac /* Output stage 20 control register (BASE_OUT_CLK) */ +#define LPC43_BASE_APLL_CLK_OFFSET 0x00c0 /* Output stage 25 control register (BASE_APLL_CLK) */ +#define LPC43_BASE_CGU_OUT0_CLK_OFFSET 0x00c4 /* Output stage 26 control register (BASE_CGU_OUT0_CLK) */ +#define LPC43_BASE_CGU_OUT1_CLK_OFFSET 0x00c8 /* Output stage 27 control register (BASE_CGU_OUT1_CLK) */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_FREQ_MON (LPC43_CGU_BASE+LPC43_FREQ_MON_OFFSET) +#define LPC43_XTAL_OSC_CTRL (LPC43_CGU_BASE+LPC43_XTAL_OSC_CTRL_OFFSET) +#define LPC43_PLL0USB_STAT (LPC43_CGU_BASE+LPC43_PLL0USB_STAT_OFFSET) +#define LPC43_PLL0USB_CTRL (LPC43_CGU_BASE+LPC43_PLL0USB_CTRL_OFFSET) +#define LPC43_PLL0USB_MDIV (LPC43_CGU_BASE+LPC43_PLL0USB_MDIV_OFFSET) +#define LPC43_PLL0USB_NP_DIV (LPC43_CGU_BASE+LPC43_PLL0USB_NP_DIV_OFFSET) +#define LPC43_PLL0AUDIO_STAT (LPC43_CGU_BASE+LPC43_PLL0AUDIO_STAT_OFFSET) +#define LPC43_PLL0AUDIO_CTRL (LPC43_CGU_BASE+LPC43_PLL0AUDIO_CTRL_OFFSET) +#define LPC43_PLL0AUDIO_MDIV (LPC43_CGU_BASE+LPC43_PLL0AUDIO_MDIV_OFFSET) +#define LPC43_PLL0AUDIO_NP_DIV (LPC43_CGU_BASE+LPC43_PLL0AUDIO_NP_DIV_OFFSET) +#define LPC43_PLL0AUDIO_FRAC (LPC43_CGU_BASE+LPC43_PLL0AUDIO_FRAC_OFFSET) +#define LPC43_PLL1_STAT (LPC43_CGU_BASE+LPC43_PLL1_STAT_OFFSET) +#define LPC43_PLL1_CTRL (LPC43_CGU_BASE+LPC43_PLL1_CTRL_OFFSET) +#define LPC43_IDIVA_CTRL (LPC43_CGU_BASE+LPC43_IDIVA_CTRL_OFFSET) +#define LPC43_IDIVB_CTRL (LPC43_CGU_BASE+LPC43_IDIVB_CTRL_OFFSET) +#define LPC43_IDIVC_CTRL (LPC43_CGU_BASE+LPC43_IDIVC_CTRL_OFFSET) +#define LPC43_IDIVD_CTRL (LPC43_CGU_BASE+LPC43_IDIVD_CTRL_OFFSET) +#define LPC43_IDIVE_CTRL (LPC43_CGU_BASE+LPC43_IDIVE_CTRL_OFFSET) +#define LPC43_BASE_SAFE_CLK (LPC43_CGU_BASE+LPC43_BASE_SAFE_CLK_OFFSET) +#define LPC43_BASE_USB0_CLK (LPC43_CGU_BASE+LPC43_BASE_USB0_CLK_OFFSET) +#define LPC43_BASE_PERIPH_CLK (LPC43_CGU_BASE+LPC43_BASE_PERIPH_CLK_OFFSET) +#define LPC43_BASE_USB1_CLK (LPC43_CGU_BASE+LPC43_BASE_USB1_CLK_OFFSET) +#define LPC43_BASE_M4_CLK (LPC43_CGU_BASE+LPC43_BASE_M4_CLK_OFFSET) +#define LPC43_BASE_SPIFI_CLK (LPC43_CGU_BASE+LPC43_BASE_SPIFI_CLK_OFFSET) +#define LPC43_BASE_SPI_CLK (LPC43_CGU_BASE+LPC43_BASE_SPI_CLK_OFFSET) +#define LPC43_BASE_PHYRX_CLK (LPC43_CGU_BASE+LPC43_BASE_PHYRX_CLK_OFFSET) +#define LPC43_BASE_PHYTX_CLK (LPC43_CGU_BASE+LPC43_BASE_PHYTX_CLK_OFFSET) +#define LPC43_BASE_APB1_CLK (LPC43_CGU_BASE+LPC43_BASE_APB1_CLK_OFFSET) +#define LPC43_BASE_APB3_CLK (LPC43_CGU_BASE+LPC43_BASE_APB3_CLK_OFFSET) +#define LPC43_BASE_LCD_CLK (LPC43_CGU_BASE+LPC43_BASE_LCD_CLK_OFFSET) +#define LPC43_BASE_VADC_CLK (LPC43_CGU_BASE+LPC43_BASE_VADC_CLK_OFFSET) +#define LPC43_BASE_SDIO_CLK (LPC43_CGU_BASE+LPC43_BASE_SDIO_CLK_OFFSET) +#define LPC43_BASE_SSP0_CLK (LPC43_CGU_BASE+LPC43_BASE_SSP0_CLK_OFFSET) +#define LPC43_BASE_SSP1_CLK (LPC43_CGU_BASE+LPC43_BASE_SSP1_CLK_OFFSET) +#define LPC43_BASE_USART0_CLK (LPC43_CGU_BASE+LPC43_BASE_USART0_CLK_OFFSET) +#define LPC43_BASE_UART1_CLK (LPC43_CGU_BASE+LPC43_BASE_UART1_CLK_OFFSET) +#define LPC43_BASE_USART2_CLK (LPC43_CGU_BASE+LPC43_BASE_USART2_CLK_OFFSET) +#define LPC43_BASE_USART3_CLK (LPC43_CGU_BASE+LPC43_BASE_USART3_CLK_OFFSET) +#define LPC43_BASE_OUT_CLK (LPC43_CGU_BASE+LPC43_BASE_OUT_CLK_OFFSET) +#define LPC43_BASE_APLL_CLK (LPC43_CGU_BASE+LPC43_BASE_APLL_CLK_OFFSET) +#define LPC43_BASE_CGU_OUT0_CLK (LPC43_CGU_BASE+LPC43_BASE_CGU_OUT0_CLK_OFFSET) +#define LPC43_BASE_CGU_OUT1_CLK (LPC43_CGU_BASE+LPC43_BASE_CGU_OUT1_CLK_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Frequency monitor register */ + +#define FREQ_MON_RCNT_SHIFT (0) /* Bits 0-8: 9-bit reference clock-counter value */ +#define FREQ_MON_RCNT_MASK (0x1ff << FREQ_MON_RCNT_SHIFT) +#define FREQ_MON_FCNT_SHIFT (9) /* Bits 9-22: 14-bit selected clock-counter value */ +#define FREQ_MON_FCNT_MASK (0x3fff << FREQ_MON_FCNT_SHIFT) +#define FREQ_MON_MEAS (1 << 23) /* Bit 23: Measure frequency */ +#define FREQ_MON_CLKSEL_SHIFT (24) /* Bits 24-28: Clock-source selection */ +#define FREQ_MON_CLKSEL_MASK (31 << FREQ_MON_CLKSEL_SHIFT) +# define FREQ_MON_CLKSEL_32KHZOSC (0 << FREQ_MON_CLKSEL_SHIFT) /* 32 kHz oscillator (default) */ +# define FREQ_MON_CLKSEL_IRQ (1 << FREQ_MON_CLKSEL_SHIFT) /* IRC */ +# define FREQ_MON_CLKSEL_ENET_RXCLK (2 << FREQ_MON_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define FREQ_MON_CLKSEL_ENET_TXCLK (3 << FREQ_MON_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define FREQ_MON_CLKSEL_GPCLKIN (4 << FREQ_MON_CLKSEL_SHIFT) /* GP_CLKIN */ +# define FREQ_MON_CLKSEL_XTAL (6 << FREQ_MON_CLKSEL_SHIFT) /* Crystal oscillator */ +# define FREQ_MON_CLKSEL_PLL0USB (7 << FREQ_MON_CLKSEL_SHIFT) /* PLL0USB */ +# define FREQ_MON_CLKSEL_PLL0AUDIO (8 << FREQ_MON_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define FREQ_MON_CLKSEL_PLL1 (9 << FREQ_MON_CLKSEL_SHIFT) /* PLL1 */ +# define FREQ_MON_CLKSEL_IDIVA (12 << FREQ_MON_CLKSEL_SHIFT) /* IDIVA */ +# define FREQ_MON_CLKSEL_IDIVB (13 << FREQ_MON_CLKSEL_SHIFT) /* IDIVB */ +# define FREQ_MON_CLKSEL_IDIVC (14 << FREQ_MON_CLKSEL_SHIFT) /* IDIVC */ +# define FREQ_MON_CLKSEL_IDIVD (15 << FREQ_MON_CLKSEL_SHIFT) /* IDIVD */ +# define FREQ_MON_CLKSEL_IDIVE (16 << FREQ_MON_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Crystal oscillator control register */ + +#define XTAL_OSC_CTRL_ENABLE (1 << 0) /* Bit 0: Oscillator-pad enable */ +#define XTAL_OSC_CTRL_BYPASS (1 << 1) /* Bit 1: Configure crystal or external-clock input */ +#define XTAL_OSC_CTRL_HF (1 << 2) /* Bit 2: Select frequency range */ + /* Bits 3-31: Reserved */ +/* PLL0USB status register */ + +#define PLL0USB_STAT_LOCK (1 << 0) /* Bit 0: PLL0 lock indicator */ +#define PLL0USB_STAT_FR (1 << 1) /* Bit 1: PLL0 free running indicator */ + /* Bits 2-31: Reserved */ +/* PLL0USB control register */ + +#define PLL0USB_CTRL_PD (1 << 0) /* Bit 0: PLL0 power down */ +#define PLL0USB_CTRL_BYPASS (1 << 1) /* Bit 1: Input clock bypass control */ +#define PLL0USB_CTRL_DIRECTI (1 << 2) /* Bit 2: PLL0 direct input */ +#define PLL0USB_CTRL_DIRECTO (1 << 3) /* Bit 3: PLL0 direct output */ +#define PLL0USB_CTRL_CLKEN (1 << 4) /* Bit 4: PLL0 clock enable */ + /* Bit 5: Reserved */ +#define PLL0USB_CTRL_FRM (1 << 6) /* Bit 6: Free running mode */ + /* Bits 7-10: Reserved */ +#define PLL0USB_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define PLL0USB_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define PLL0USB_CTRL_CLKSEL_MASK (31 << PLL0USB_CTRL_CLKSEL_SHIFT) +# define PLL0USB_CLKSEL_32KHZOSC (0 << PLL0USB_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define PLL0USB_CLKSEL_IRC (1 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define PLL0USB_CLKSEL_ENET_RXCLK (2 << PLL0USB_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define PLL0USB_CLKSEL_ENET_TXCLK (3 << PLL0USB_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define PLL0USB_CLKSEL_GPCLKIN (4 << PLL0USB_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define PLL0USB_CLKSEL_XTAL (6 << PLL0USB_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define PLL0USB_CLKSEL_PLL1 (9 << PLL0USB_CTRL_CLKSEL_SHIFT) /* PLL1 */ +# define PLL0USB_CLKSEL_IDIVA (12 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IDIVA */ +# define PLL0USB_CLKSEL_IDIVB (13 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IDIVB */ +# define PLL0USB_CLKSEL_IDIVC (14 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IDIVC */ +# define PLL0USB_CLKSEL_IDIVD (15 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IDIVD */ +# define PLL0USB_CLKSEL_IDIVE (16 << PLL0USB_CTRL_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* PLL0USB M-divider register */ + +#define PLL0USB_MDIV_MDEC_SHIFT (0) /* Bits 0-16: Decoded M-divider coefficient value (1-131071) */ +#define PLL0USB_MDIV_MDEC_MASK (0x1ffff << PLL0USB_MDIV_MDEC_SHIFT) +# define PLL0USB_MDIV_MDEC(n) ((n) << PLL0USB_MDIV_MDEC_SHIFT) +#define PLL0USB_MDIV_SELP_SHIFT (17) /* Bits 17-21: Bandwidth select P value */ +#define PLL0USB_MDIV_SELP_MASK (0x1f << PLL0USB_MDIV_SELP_SHIFT) +# define PLL0USB_MDIV_SELP(n) ((n) << PLL0USB_MDIV_SELP_SHIFT) +#define PLL0USB_MDIV_SELI_SHIFT (22) /* Bits 22-27: Bandwidth select I value */ +#define PLL0USB_MDIV_SELI_MASK (0x3f << PLL0USB_MDIV_SELI_SHIFT) +# define PLL0USB_MDIV_SELI(n) ((n) << PLL0USB_MDIV_SELI_SHIFT) +#define PLL0USB_MDIV_SELR_SHIFT (28) /* Bits 28-31: Bandwidth select R value */ +#define PLL0USB_MDIV_SELR_MASK (15 << PLL0USB_MDIV_SELR_SHIFT) +# define PLL0USB_MDIV_SELR(n) ((n) << PLL0USB_MDIV_SELR_SHIFT) + +/* PLL0USB N/P-divider register */ + +#define PLL0USB_NP_DIV_PDEC_SHIFT (0) /* Bits 0-6: Decoded P-divider coefficient value */ +#define PLL0USB_NP_DIV_PDEC_MASK (0x7f << PLL0USB_NP_DIV_PDEC_SHIFT) +# define PLL0USB_NP_DIV_PDEC(n) ((n) << PLL0USB_NP_DIV_PDEC_SHIFT) + /* Bits 7-11: Reserved */ +#define PLL0USB_NP_DIV_NDEC_SHIFT (12) /* Bits 12-21: Decoded N-divider coefficient value */ +#define PLL0USB_NP_DIV_NDEC_MASK (0x3ff << PLL0USB_NP_DIV_NDEC_SHIFT) +# define PLL0USB_NP_DIV_NDEC(n) ((n) << PLL0USB_NP_DIV_NDEC_SHIFT) + /* Bits 22-31: Reserved */ +/* PLL0AUDIO status register */ + +#define PLL0AUDIO_STAT_LOCK (1 << 0) /* Bit 0: PLL0 lock indicator */ +#define PLL0AUDIO_STAT_FR (1 << 1) /* Bit 1: PLL0 free running indicator */ + /* Bits 2-31: Reserved */ +/* PLL0AUDIO control register */ + +#define PLL0AUDIO_CTRL_PD (1 << 0) /* Bit 0: PLL0 power down */ +#define PLL0AUDIO_CTRL_BYPASS (1 << 1) /* Bit 1: Input clock bypass control */ +#define PLL0AUDIO_CTRL_DIRECTI (1 << 2) /* Bit 2: PLL0 direct input */ +#define PLL0AUDIO_CTRL_DIRECTO (1 << 3) /* Bit 3: PLL0 direct output */ +#define PLL0AUDIO_CTRL_CLKEN (1 << 4) /* Bit 4: PLL0 clock enable */ + /* Bit 5: Reserved */ +#define PLL0AUDIO_CTRL_FRM (1 << 6) /* Bit 6: Free running mode */ + /* Bits 7-10: Reserved */ +#define PLL0AUDIO_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + +#define PLL0AUDIO_CTRL_PLLFRACTREQ (1 << 12) /* Bit 12: Fractional PLL word write request */ +#define PLL0AUDIO_CTRL_SELEXT (1 << 13) /* Bit 13: Select fractional divider */ +#define PLL0AUDIO_CTRL_MODPD (1 << 14) /* Bit 14: Sigma-Delta modulator power-down */ + /* Bits 15-23: Reserved */ +#define PLL0AUDIO_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define PLL0AUDIO_CTRL_CLKSEL_MASK (31 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) +# define PLL0AUDIO_CLKSEL_32KHZOSC (0 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define PLL0AUDIO_CLKSEL_IRC (1 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define PLL0AUDIO_CLKSEL_ENET_RXCLK (2 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define PLL0AUDIO_CLKSEL_ENET_TXCLK (3 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define PLL0AUDIO_CLKSEL_GPCLKIN (4 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define PLL0AUDIO_CLKSEL_XTAL (6 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define PLL0AUDIO_CLKSEL_PLL1 (9 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* PLL1 */ +# define PLL0AUDIO_CLKSEL_IDIVA (12 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IDIVA */ +# define PLL0AUDIO_CLKSEL_IDIVB (13 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IDIVB */ +# define PLL0AUDIO_CLKSEL_IDIVC (14 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IDIVC */ +# define PLL0AUDIO_CLKSEL_IDIVD (15 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IDIVD */ +# define PLL0AUDIO_CLKSEL_IDIVE (16 << PLL0AUDIO_CTRL_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* PLL0AUDIO M-divider */ + +#define PLL0AUDIO_MDIV_MDEC_SHIFT (0) /* Bits 0-16: Decoded M-divider coefficient value (1-131071) */ +#define PLL0AUDIO_MDIV_MDEC_MASK (0x1ffff << PLL0AUDIO_MDIV_MDEC_SHIFT) +# define PLL0AUDIO_MDIV_MDEC(n) ((n) << PLL0AUDIO_MDIV_MDEC_SHIFT) + /* Bits 17-31: Reserved */ +/* PLL0AUDIO N/P-divider */ + +#define PLL0AUDIO_NP_DIV_PDEC_SHIFT (0) /* Bits 0-6: Decoded P-divider coefficient value */ +#define PLL0AUDIO_NP_DIV_PDEC_MASK (0x7f << PLL0AUDIO_NP_DIV_PDEC_SHIFT) +# define PLL0AUDIO_NP_DIV_PDEC(n) ((n) << PLL0AUDIO_NP_DIV_PDEC_SHIFT) + /* Bits 7-11: Reserved */ +#define PLL0AUDIO_NP_DIV_NDEC_SHIFT (12) /* Bits 12-21: Decoded N-divider coefficient value */ +#define PLL0AUDIO_NP_DIV_NDEC_MASK (0x3ff << PLL0AUDIO_NP_DIV_NDEC_SHIFT) +# define PLL0AUDIO_NP_DIV_NDEC(n) ((n) << PLL0AUDIO_NP_DIV_NDEC_SHIFT) + /* Bits 22-31: Reserved */ +/* PLL0AUDIO fractional */ + +#define PLL0AUDIO_FRAC_CTRL_SHIFT (0) /* Bits 0-21: Decoded P-divider coefficient value */ +#define PLL0AUDIO_FRAC_CTRL_MASK (0x3fffff << PLL0AUDIO_FRAC_CTRL_SHIFT) +# define PLL0AUDIO_FRA_CCTRL(n) ((n) << PLL0AUDIO_FRAC_CTRL_SHIFT) + /* Bits 22-31: Reserved */ +/* PLL1 status register */ + +#define PLL1_STAT_LOCK (1 << 0) /* Bit 0: PLL1 lock indicator */ + /* Bits 1-31: Reserved */ +/* PLL1 control register */ + +#define PLL1_CTRL_PD (1 << 0) /* Bit 0: PLL1 power down */ +#define PLL1_CTRL_BYPASS (1 << 1) /* Bit 1: Input clock bypass control */ + /* Bits 2-5: Reserved */ +#define PLL1_CTRL_FBSEL (1 << 6) /* Bit 6: PLL1 feedback select */ +#define PLL1_CTRL_DIRECT (1 << 7) /* Bit 7: PLL1 direct CCO output */ + +#define PLL1_CTRL_PSEL_SHIFT (8) /* Bits 8-9: Post-divider division ratio P */ +#define PLL1_CTRL_PSEL_MASK (3 << PLL1_CTRL_PSEL_SHIFT) +# define PLL1_CTRL_PSEL_DIV1 (0 << PLL1_CTRL_PSEL_SHIFT) +# define PLL1_CTRL_PSEL_DIV2 (1 << PLL1_CTRL_PSEL_SHIFT) +# define PLL1_CTRL_PSEL_DIV4 (2 << PLL1_CTRL_PSEL_SHIFT) +# define PLL1_CTRL_PSEL_DIV8 (3 << PLL1_CTRL_PSEL_SHIFT) + /* Bit 10: Reserved */ +#define PLL1_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ +#define PLL1_CTRL_NSEL_SHIFT (12) /* Bits 12-13: Pre-divider division ratio N */ +#define PLL1_CTRL_NSEL_MASK (3 << PLL1_CTRL_NSEL_SHIFT) +# define PLL1_CTRL_NSEL_DIV1 (0 << PLL1_CTRL_NSEL_SHIFT) +# define PLL1_CTRL_NSEL_DIV2 (1 << PLL1_CTRL_NSEL_SHIFT) +# define PLL1_CTRL_NSEL_DIV3 (2 << PLL1_CTRL_NSEL_SHIFT) +# define PLL1_CTRL_NSEL_DIV4 (3 << PLL1_CTRL_NSEL_SHIFT) + /* Bits 14-15: Reserved */ +#define PLL1_CTRL_MSEL_SHIFT (16) /* Bits 16-23: Feedback-divider division ratio M */ +#define PLL1_CTRL_MSEL_MASK (0xff << PLL1_CTRL_MSEL_SHIFT) +# define PLL1_CTRL_MSEL(n) (((n)-1) << PLL1_CTRL_MSEL_SHIFT) /* n=1..256 */ +#define PLL1_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define PLL1_CTRL_CLKSEL_MASK (31 << PLL1_CTRL_CLKSEL_SHIFT) +# define PLL1_CLKSEL_32KHZOSC (0 << PLL1_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define PLL1_CLKSEL_IRC (1 << PLL1_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define PLL1_CLKSEL_ENET_RXCLK (2 << PLL1_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define PLL1_CLKSEL_ENET_TXCLK (3 << PLL1_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define PLL1_CLKSEL_GPCLKIN (4 << PLL1_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define PLL1_CLKSEL_XTAL (6 << PLL1_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define PLL1_CLKSEL_PLL0USB (7 << PLL1_CTRL_CLKSEL_SHIFT) /* PLL0USB */ +# define PLL1_CLKSEL_PLL0AUDIO (8 << PLL1_CTRL_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define PLL1_CLKSEL_IDIVA (12 << PLL1_CTRL_CLKSEL_SHIFT) /* IDIVA */ +# define PLL1_CLKSEL_IDIVB (13 << PLL1_CTRL_CLKSEL_SHIFT) /* IDIVB */ +# define PLL1_CLKSEL_IDIVC (14 << PLL1_CTRL_CLKSEL_SHIFT) /* IDIVC */ +# define PLL1_CLKSEL_IDIVD (15 << PLL1_CTRL_CLKSEL_SHIFT) /* IDIVD */ +# define PLL1_CLKSEL_IDIVE (16 << PLL1_CTRL_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Integer divider A control register */ + +#define IDIVA_CTRL_PD (1 << 0) /* Bit 0: Integer divider A power down */ + /* Bit 1: Reserved */ +#define IDIVA_CTRL_IDIV_SHIFT (2) /* Bits 2-3: Integer divider A divider values (1/(IDIV + 1)) */ +#define IDIVA_CTRL_IDIV_MASK (3 << IDIVA_CTRL_IDIV_SHIFT) +# define IDIVA_CTRL_IDIV(n) (((n)-1) << IDIVA_CTRL_IDIV_SHIFT) /* n=1..4 */ + /* Bits 4-10: Reserved */ +#define IDIVA_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define IDIVA_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define IDIVA_CTRL_CLKSEL_MASK (31 << IDIVA_CTRL_CLKSEL_SHIFT) +# define IDIVA_CLKSEL_32KHZOSC (0 << IDIVA_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define IDIVA_CLKSEL_IRC (1 << IDIVA_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define IDIVA_CLKSEL_ENET_RXCLK (2 << IDIVA_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define IDIVA_CLKSEL_ENET_TXCLK (3 << IDIVA_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define IDIVA_CLKSEL_GPCLKIN (4 << IDIVA_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define IDIVA_CLKSEL_XTAL (6 << IDIVA_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define IDIVA_CLKSEL_PLL0USB (7 << IDIVA_CTRL_CLKSEL_SHIFT) /* PLL0USB */ +# define IDIVA_CLKSEL_PLL0AUDIO (8 << IDIVA_CTRL_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define IDIVA_CLKSEL_PLL1 (9 << IDIVA_CTRL_CLKSEL_SHIFT) /* PLL1 */ + /* Bits 29-31: Reserved */ +/* Integer divider B/C/D control register */ + +#define IDIVBCD_CTRL_PD (1 << 0) /* Bit 0: Integer divider power down */ + /* Bit 1: Reserved */ +#define IDIVBCD_CTRL_IDIV_SHIFT (2) /* Bits 2-5: Integer divider A divider values (1/(IDIV + 1)) */ +#define IDIVBCD_CTRL_IDIV_MASK (15 << IDIVBCD_CTRL_IDIV_SHIFT) +# define IDIVBCD_CTRL_IDIV(n) (((n)-1) << IDIVBCD_CTRL_IDIV_SHIFT) /* n=1..16 */ + /* Bits 6-10: Reserved */ +#define IDIVBCD_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define IDIVBCD_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define IDIVBCD_CTRL_CLKSEL_MASK (31 << IDIVBCD_CTRL_CLKSEL_SHIFT) +# define IDIVBCD_CLKSEL_32KHZOSC (0 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define IDIVBCD_CLKSEL_IRC (1 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define IDIVBCD_CLKSEL_ENET_RXCLK (2 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define IDIVBCD_CLKSEL_ENET_TXCLK (3 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define IDIVBCD_CLKSEL_GPCLKIN (4 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define IDIVBCD_CLKSEL_XTAL (6 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define IDIVBCD_CLKSEL_PLL0AUDIO (8 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define IDIVBCD_CLKSEL_PLL1 (9 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* PLL1 */ +# define IDIVBCD_CLKSEL_IDIVA (12 << IDIVBCD_CTRL_CLKSEL_SHIFT) /* IDIVA */ + /* Bits 29-31: Reserved */ +/* Integer divider E control register */ + +#define IDIVE_CTRL_PD (1 << 0) /* Bit 0: Integer divider E power down */ + /* Bit 1: Reserved */ +#define IDIVE_CTRL_IDIV_SHIFT (2) /* Bits 2-9: Integer divider A divider values (1/(IDIV + 1)) */ +#define IDIVE_CTRL_IDIV_MASK (0xff << IDIVE_CTRL_IDIV_SHIFT) +# define IDIVE_CTRL_IDIV(n) (((n)-1) << IDIVE_CTRL_IDIV_SHIFT) /* n=1..256 */ + /* Bit 10: Reserved */ +#define IDIVE_CTRL_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define IDIVE_CTRL_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define IDIVE_CTRL_CLKSEL_MASK (31 << IDIVE_CTRL_CLKSEL_SHIFT) +# define IDIVE_CLKSEL_32KHZOSC (0 << IDIVE_CTRL_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define IDIVE_CLKSEL_IRC (1 << IDIVE_CTRL_CLKSEL_SHIFT) /* IRC (default) */ +# define IDIVE_CLKSEL_ENET_RXCLK (2 << IDIVE_CTRL_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define IDIVE_CLKSEL_ENET_TXCLK (3 << IDIVE_CTRL_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define IDIVE_CLKSEL_GPCLKIN (4 << IDIVE_CTRL_CLKSEL_SHIFT) /* GP_CLKIN */ +# define IDIVE_CLKSEL_XTAL (6 << IDIVE_CTRL_CLKSEL_SHIFT) /* Crystal oscillator */ +# define IDIVE_CLKSEL_PLL0AUDIO (8 << IDIVE_CTRL_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define IDIVE_CLKSEL_PLL1 (9 << IDIVE_CTRL_CLKSEL_SHIFT) /* PLL1 */ +# define IDIVE_CLKSEL_IDIVA (12 << IDIVE_CTRL_CLKSEL_SHIFT) /* IDIVA */ + /* Bits 29-31: Reserved */ +/* Output stage 0 control register (BASE_SAFE_CLK) */ + +#define BASE_SAFE_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_SAFE_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_SAFE_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_SAFE_CLK_CLKSEL_MASK (31 << BASE_SAFE_CLK_CLKSEL_SHIFT) +# define BASE_SAFE_CLKSEL_IRC (1 << BASE_SAFE_CLK_CLKSEL_SHIFT) /* IRC (default) */ + /* Bits 29-31: Reserved */ +/* Output stage 1 control register (BASE_USB0_CLK) */ + +#define BASE_USB0_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_USB0_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_USB0_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_USB0_CLK_CLKSEL_MASK (31 << BASE_USB0_CLK_CLKSEL_SHIFT) +# define BASE_USB0_CLKSEL_PLL0USB (7 << BASE_USB0_CLK_CLKSEL_SHIFT) /* PLL0USB (default) */ + /* Bits 29-31: Reserved */ +/* Output stage 2 control register (BASE_PERIPH_CLK) */ + +#define BASE_PERIPH_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_PERIPH_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_PERIPH_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_PERIPH_CLK_CLKSEL_MASK (31 << BASE_PERIPH_CLK_CLKSEL_SHIFT) +# define BASE_PERIPH_CLKSEL_32KHZOSC (0 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_PERIPH_CLKSEL_IRC (1 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_PERIPH_CLKSEL_ENET_RXCLK (2 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_PERIPH_CLKSEL_ENET_TXCLK (3 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_PERIPH_CLKSEL_GPCLKIN (4 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_PERIPH_CLKSEL_XTAL (6 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_PERIPH_CLKSEL_PLL0AUDIO (8 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_PERIPH_CLKSEL_PLL1 (9 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_PERIPH_CLKSEL_IDIVA (12 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_PERIPH_CLKSEL_IDIVB (13 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_PERIPH_CLKSEL_IDIVC (14 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_PERIPH_CLKSEL_IDIVD (15 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_PERIPH_CLKSEL_IDIVE (16 << BASE_PERIPH_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 3 control register (BASE_USB1_CLK) */ + +#define BASE_USB1_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_USB1_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_USB1_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_USB1_CLK_CLKSEL_MASK (31 << BASE_USB1_CLK_CLKSEL_SHIFT) +# define BASE_USB1_CLKSEL_32KHZOSC (0 << BASE_USB1_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_USB1_CLKSEL_IRC (1 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_USB1_CLKSEL_ENET_RXCLK (2 << BASE_USB1_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_USB1_CLKSEL_ENET_TXCLK (3 << BASE_USB1_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_USB1_CLKSEL_GPCLKIN (4 << BASE_USB1_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_USB1_CLKSEL_XTAL (6 << BASE_USB1_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_USB1_CLKSEL_PLL0USB (7 << BASE_USB1_CLK_CLKSEL_SHIFT) /* PLL0USB */ +# define BASE_USB1_CLKSEL_PLL0AUDIO (8 << BASE_USB1_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_USB1_CLKSEL_PLL1 (9 << BASE_USB1_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_USB1_CLKSEL_IDIVA (12 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_USB1_CLKSEL_IDIVB (13 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_USB1_CLKSEL_IDIVC (14 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_USB1_CLKSEL_IDIVD (15 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_USB1_CLKSEL_IDIVE (16 << BASE_USB1_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 4 control register (BASE_M4_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_M4_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_M4_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_M4_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_M4_CLK_CLKSEL_MASK (31 << BASE_M4_CLK_CLKSEL_SHIFT) +# define BASE_M4_CLKSEL_32KHZOSC (0 << BASE_M4_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_M4_CLKSEL_IRC (1 << BASE_M4_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_M4_CLKSEL_ENET_RXCLK (2 << BASE_M4_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_M4_CLKSEL_ENET_TXCLK (3 << BASE_M4_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_M4_CLKSEL_GPCLKIN (4 << BASE_M4_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_M4_CLKSEL_XTAL (6 << BASE_M4_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_M4_CLKSEL_PLL0AUDIO (8 << BASE_M4_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_M4_CLKSEL_PLL1 (9 << BASE_M4_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_M4_CLKSEL_IDIVA (12 << BASE_M4_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_M4_CLKSEL_IDIVB (13 << BASE_M4_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_M4_CLKSEL_IDIVC (14 << BASE_M4_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_M4_CLKSEL_IDIVD (15 << BASE_M4_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_M4_CLKSEL_IDIVE (16 << BASE_M4_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 5 control register (BASE_SPIFI_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_SPIFI_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_SPIFI_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_SPIFI_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_SPIFI_CLK_CLKSEL_MASK (31 << BASE_SPIFI_CLK_CLKSEL_SHIFT) +# define BASE_SPIFI_CLKSEL_32KHZOSC (0 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_SPIFI_CLKSEL_IRC (1 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_SPIFI_CLKSEL_ENET_RXCLK (2 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_SPIFI_CLKSEL_ENET_TXCLK (3 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_SPIFI_CLKSEL_GPCLKIN (4 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_SPIFI_CLKSEL_XTAL (6 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_SPIFI_CLKSEL_PLL0AUDIO (8 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_SPIFI_CLKSEL_PLL1 (9 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_SPIFI_CLKSEL_IDIVA (12 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_SPIFI_CLKSEL_IDIVB (13 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_SPIFI_CLKSEL_IDIVC (14 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_SPIFI_CLKSEL_IDIVD (15 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_SPIFI_CLKSEL_IDIVE (16 << BASE_SPIFI_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 6 control register (BASE_SPI_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_SPI_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_SPI_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_SPI_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_SPI_CLK_CLKSEL_MASK (31 << BASE_SPI_CLK_CLKSEL_SHIFT) +# define BASE_SPI_CLKSEL_32KHZOSC (0 << BASE_SPI_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_SPI_CLKSEL_IRC (1 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_SPI_CLKSEL_ENET_RXCLK (2 << BASE_SPI_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_SPI_CLKSEL_ENET_TXCLK (3 << BASE_SPI_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_SPI_CLKSEL_GPCLKIN (4 << BASE_SPI_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_SPI_CLKSEL_XTAL (6 << BASE_SPI_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_SPI_CLKSEL_PLL0AUDIO (8 << BASE_SPI_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_SPI_CLKSEL_PLL1 (9 << BASE_SPI_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_SPI_CLKSEL_IDIVA (12 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_SPI_CLKSEL_IDIVB (13 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_SPI_CLKSEL_IDIVC (14 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_SPI_CLKSEL_IDIVD (15 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_SPI_CLKSEL_IDIVE (16 << BASE_SPI_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 7 control register (BASE_PHY_RX_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_PHYRX_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_PHYRX_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_PHYRX_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_PHYRX_CLK_CLKSEL_MASK (31 << BASE_PHYRX_CLK_CLKSEL_SHIFT) +# define BASE_PHYRX_CLKSEL_32KHZOSC (0 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_PHYRX_CLKSEL_IRC (1 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_PHYRX_CLKSEL_ENET_RXCLK (2 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_PHYRX_CLKSEL_ENET_TXCLK (3 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_PHYRX_CLKSEL_GPCLKIN (4 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_PHYRX_CLKSEL_XTAL (6 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_PHYRX_CLKSEL_PLL0AUDIO (8 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_PHYRX_CLKSEL_PLL1 (9 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_PHYRX_CLKSEL_IDIVA (12 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_PHYRX_CLKSEL_IDIVB (13 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_PHYRX_CLKSEL_IDIVC (14 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_PHYRX_CLKSEL_IDIVD (15 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_PHYRX_CLKSEL_IDIVE (16 << BASE_PHYRX_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 8 control register (BASE_PHY_TX_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_PHYTX_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_PHYTX_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_PHYTX_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_PHYTX_CLK_CLKSEL_MASK (31 << BASE_PHYTX_CLK_CLKSEL_SHIFT) +# define BASE_PHYTX_CLKSEL_32KHZOSC (0 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_PHYTX_CLKSEL_IRC (1 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_PHYTX_CLKSEL_ENET_RXCLK (2 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_PHYTX_CLKSEL_ENET_TXCLK (3 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_PHYTX_CLKSEL_GPCLKIN (4 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_PHYTX_CLKSEL_XTAL (6 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_PHYTX_CLKSEL_PLL0AUDIO (8 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_PHYTX_CLKSEL_PLL1 (9 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_PHYTX_CLKSEL_IDIVA (12 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_PHYTX_CLKSEL_IDIVB (13 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_PHYTX_CLKSEL_IDIVC (14 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_PHYTX_CLKSEL_IDIVD (15 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_PHYTX_CLKSEL_IDIVE (16 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 9 control register (BASE_APB1_CLK, BASE_APB3_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_APB_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_APB_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_APB_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_APB_CLK_CLKSEL_MASK (31 << BASE_APB_CLK_CLKSEL_SHIFT) +# define BASE_APB_CLKSEL_32KHZOSC (0 << BASE_APB_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_APB_CLKSEL_IRC (1 << BASE_APB_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_APB_CLKSEL_ENET_RXCLK (2 << BASE_APB_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_APB_CLKSEL_ENET_TXCLK (3 << BASE_APB_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_APB_CLKSEL_GPCLKIN (4 << BASE_APB_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_APB_CLKSEL_XTAL (6 << BASE_APB_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_APB_CLKSEL_PLL0AUDIO (8 << BASE_APB_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_APB_CLKSEL_PLL1 (9 << BASE_APB_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_APB_CLKSEL_IDIVA (12 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_APB_CLKSEL_IDIVB (13 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_APB_CLKSEL_IDIVC (14 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_APB_CLKSEL_IDIVD (15 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_APB_CLKSEL_IDIVE (16 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 11 control register (BASE_LCD_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_LCD_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_LCD_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_LCD_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_LCD_CLK_CLKSEL_MASK (31 << BASE_LCD_CLK_CLKSEL_SHIFT) +# define BASE_LCD_CLKSEL_32KHZOSC (0 << BASE_LCD_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_LCD_CLKSEL_IRC (1 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_LCD_CLKSEL_ENET_RXCLK (2 << BASE_LCD_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_LCD_CLKSEL_ENET_TXCLK (3 << BASE_LCD_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_LCD_CLKSEL_GPCLKIN (4 << BASE_LCD_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_LCD_CLKSEL_XTAL (6 << BASE_LCD_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_LCD_CLKSEL_PLL0AUDIO (8 << BASE_LCD_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_LCD_CLKSEL_PLL1 (9 << BASE_LCD_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_LCD_CLKSEL_IDIVA (12 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_LCD_CLKSEL_IDIVB (13 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_LCD_CLKSEL_IDIVC (14 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_LCD_CLKSEL_IDIVD (15 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_LCD_CLKSEL_IDIVE (16 << BASE_LCD_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 12 control register (BASE_VADC_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_VADC_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_VADC_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_VADC_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_VADC_CLK_CLKSEL_MASK (31 << BASE_VADC_CLK_CLKSEL_SHIFT) +# define BASE_VADC_CLKSEL_32KHZOSC (0 << BASE_VADC_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_VADC_CLKSEL_IRC (1 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_VADC_CLKSEL_ENET_RXCLK (2 << BASE_VADC_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_VADC_CLKSEL_ENET_TXCLK (3 << BASE_VADC_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_VADC_CLKSEL_GPCLKIN (4 << BASE_VADC_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_VADC_CLKSEL_XTAL (6 << BASE_VADC_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_VADC_CLKSEL_PLL0AUDIO (8 << BASE_VADC_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_VADC_CLKSEL_PLL1 (9 << BASE_VADC_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_VADC_CLKSEL_IDIVA (12 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_VADC_CLKSEL_IDIVB (13 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_VADC_CLKSEL_IDIVC (14 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_VADC_CLKSEL_IDIVD (15 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_VADC_CLKSEL_IDIVE (16 << BASE_VADC_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 14 control register (BASE_SSP0_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_SSP0_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_SSP0_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_SSP0_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_SSP0_CLK_CLKSEL_MASK (31 << BASE_SSP0_CLK_CLKSEL_SHIFT) +# define BASE_SSP0_CLKSEL_32KHZOSC (0 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_SSP0_CLKSEL_IRC (1 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_SSP0_CLKSEL_ENET_RXCLK (2 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_SSP0_CLKSEL_ENET_TXCLK (3 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_SSP0_CLKSEL_GPCLKIN (4 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_SSP0_CLKSEL_XTAL (6 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_SSP0_CLKSEL_PLL0AUDIO (8 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_SSP0_CLKSEL_PLL1 (9 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_SSP0_CLKSEL_IDIVA (12 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_SSP0_CLKSEL_IDIVB (13 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_SSP0_CLKSEL_IDIVC (14 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_SSP0_CLKSEL_IDIVD (15 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_SSP0_CLKSEL_IDIVE (16 << BASE_SSP0_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 15 control register (BASE_SSP1_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_SSP1_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_SSP1_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_SSP1_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_SSP1_CLK_CLKSEL_MASK (31 << BASE_SSP1_CLK_CLKSEL_SHIFT) +# define BASE_SSP1_CLKSEL_32KHZOSC (0 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_SSP1_CLKSEL_IRC (1 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_SSP1_CLKSEL_ENET_RXCLK (2 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_SSP1_CLKSEL_ENET_TXCLK (3 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_SSP1_CLKSEL_GPCLKIN (4 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_SSP1_CLKSEL_XTAL (6 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_SSP1_CLKSEL_PLL0AUDIO (8 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_SSP1_CLKSEL_PLL1 (9 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_SSP1_CLKSEL_IDIVA (12 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_SSP1_CLKSEL_IDIVB (13 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_SSP1_CLKSEL_IDIVC (14 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_SSP1_CLKSEL_IDIVD (15 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_SSP1_CLKSEL_IDIVE (16 << BASE_SSP1_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 16 control register (BASE_USART0_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_USART0_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_USART0_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_USART0_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_USART0_CLK_CLKSEL_MASK (31 << BASE_USART0_CLK_CLKSEL_SHIFT) +# define BASE_USART0_CLKSEL_32KHZOSC (0 << BASE_USART0_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_USART0_CLKSEL_IRC (1 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_USART0_CLKSEL_ENET_RXCLK (2 << BASE_USART0_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_USART0_CLKSEL_ENET_TXCLK (3 << BASE_USART0_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_USART0_CLKSEL_GPCLKIN (4 << BASE_USART0_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_USART0_CLKSEL_XTAL (6 << BASE_USART0_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_USART0_CLKSEL_PLL0AUDIO (8 << BASE_USART0_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_USART0_CLKSEL_PLL1 (9 << BASE_USART0_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_USART0_CLKSEL_IDIVA (12 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_USART0_CLKSEL_IDIVB (13 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_USART0_CLKSEL_IDIVC (14 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_USART0_CLKSEL_IDIVD (15 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_USART0_CLKSEL_IDIVE (16 << BASE_USART0_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 17 control register (BASE_UART1_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_UART1_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_UART1_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_UART1_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_UART1_CLK_CLKSEL_MASK (31 << BASE_UART1_CLK_CLKSEL_SHIFT) +# define BASE_UART1_CLKSEL_32KHZOSC (0 << BASE_UART1_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_UART1_CLKSEL_IRC (1 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_UART1_CLKSEL_ENET_RXCLK (2 << BASE_UART1_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_UART1_CLKSEL_ENET_TXCLK (3 << BASE_UART1_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_UART1_CLKSEL_GPCLKIN (4 << BASE_UART1_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_UART1_CLKSEL_XTAL (6 << BASE_UART1_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_UART1_CLKSEL_PLL0AUDIO (8 << BASE_UART1_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_UART1_CLKSEL_PLL1 (9 << BASE_UART1_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_UART1_CLKSEL_IDIVA (12 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_UART1_CLKSEL_IDIVB (13 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_UART1_CLKSEL_IDIVC (14 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_UART1_CLKSEL_IDIVD (15 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_UART1_CLKSEL_IDIVE (16 << BASE_UART1_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 18 control register (BASE_USART2_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_USART2_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_USART2_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_USART2_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_USART2_CLK_CLKSEL_MASK (31 << BASE_USART2_CLK_CLKSEL_SHIFT) +# define BASE_USART2_CLKSEL_32KHZOSC (0 << BASE_USART2_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_USART2_CLKSEL_IRC (1 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_USART2_CLKSEL_ENET_RXCLK (2 << BASE_USART2_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_USART2_CLKSEL_ENET_TXCLK (3 << BASE_USART2_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_USART2_CLKSEL_GPCLKIN (4 << BASE_USART2_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_USART2_CLKSEL_XTAL (6 << BASE_USART2_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_USART2_CLKSEL_PLL0AUDIO (8 << BASE_USART2_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_USART2_CLKSEL_PLL1 (9 << BASE_USART2_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_USART2_CLKSEL_IDIVA (12 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_USART2_CLKSEL_IDIVB (13 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_USART2_CLKSEL_IDIVC (14 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_USART2_CLKSEL_IDIVD (15 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_USART2_CLKSEL_IDIVE (16 << BASE_USART2_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 19 control register (BASE_USART3_CLK) */ +/* NOTE: Clocks 4-19 are identical */ + +#define BASE_USART3_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_USART3_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_USART3_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_USART3_CLK_CLKSEL_MASK (31 << BASE_USART3_CLK_CLKSEL_SHIFT) +# define BASE_USART3_CLKSEL_32KHZOSC (0 << BASE_USART3_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_USART3_CLKSEL_IRC (1 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_USART3_CLKSEL_ENET_RXCLK (2 << BASE_USART3_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_USART3_CLKSEL_ENET_TXCLK (3 << BASE_USART3_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_USART3_CLKSEL_GPCLKIN (4 << BASE_USART3_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_USART3_CLKSEL_XTAL (6 << BASE_USART3_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_USART3_CLKSEL_PLL0AUDIO (8 << BASE_USART3_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_USART3_CLKSEL_PLL1 (9 << BASE_USART3_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_USART3_CLKSEL_IDIVA (12 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_USART3_CLKSEL_IDIVB (13 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_USART3_CLKSEL_IDIVC (14 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_USART3_CLKSEL_IDIVD (15 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_USART3_CLKSEL_IDIVE (16 << BASE_USART3_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 20 control register (BASE_OUT_CLK) */ + +#define BASE_OUT_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_OUT_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_OUT_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_OUT_CLK_CLKSEL_MASK (31 << BASE_OUT_CLK_CLKSEL_SHIFT) +# define BASE_OUT_CLKSEL_32KHZOSC (0 << BASE_OUT_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_OUT_CLKSEL_IRC (1 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_OUT_CLKSEL_ENET_RXCLK (2 << BASE_OUT_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_OUT_CLKSEL_ENET_TXCLK (3 << BASE_OUT_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_OUT_CLKSEL_GPCLKIN (4 << BASE_OUT_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_OUT_CLKSEL_XTAL (6 << BASE_OUT_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_OUT_CLKSEL_PLL0USB (7 << BASE_OUT_CLK_CLKSEL_SHIFT) /* PLL0USB */ +# define BASE_OUT_CLKSEL_PLL0AUDIO (8 << BASE_OUT_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_OUT_CLKSEL_PLL1 (9 << BASE_OUT_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_OUT_CLKSEL_IDIVA (12 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_OUT_CLKSEL_IDIVB (13 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_OUT_CLKSEL_IDIVC (14 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_OUT_CLKSEL_IDIVD (15 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_OUT_CLKSEL_IDIVE (16 << BASE_OUT_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 25 control register (BASE_APLL_CLK) */ + +#define BASE_APLL_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_APLL_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_APLL_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_APLL_CLK_CLKSEL_MASK (31 << BASE_APLL_CLK_CLKSEL_SHIFT) +# define BASE_APLL_CLKSEL_32KHZOSC (0 << BASE_APLL_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_APLL_CLKSEL_IRC (1 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_APLL_CLKSEL_ENET_RXCLK (2 << BASE_APLL_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_APLL_CLKSEL_ENET_TXCLK (3 << BASE_APLL_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_APLL_CLKSEL_GPCLKIN (4 << BASE_APLL_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_APLL_CLKSEL_XTAL (6 << BASE_APLL_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_APLL_CLKSEL_PLL0AUDIO (8 << BASE_APLL_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_APLL_CLKSEL_PLL1 (9 << BASE_APLL_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_APLL_CLKSEL_IDIVA (12 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_APLL_CLKSEL_IDIVB (13 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_APLL_CLKSEL_IDIVC (14 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_APLL_CLKSEL_IDIVD (15 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_APLL_CLKSEL_IDIVE (16 << BASE_APLL_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ +/* Output stage 26/27 control register (BASE_CGU_OUT0/1_CLK) */ +/* NOTE: Clocks 26-27 are identical */ + +#define BASE_CGU_CLK_PD (1 << 0) /* Bit 0: Output stage power down */ + /* Bits 1-10: Reserved */ +#define BASE_CGU_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */ + /* Bits 12-23: Reserved */ +#define BASE_CGU_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */ +#define BASE_CGU_CLK_CLKSEL_MASK (31 << BASE_CGU_CLK_CLKSEL_SHIFT) +# define BASE_CGU_CLKSEL_32KHZOSC (0 << BASE_CGU_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */ +# define BASE_CGU_CLKSEL_IRC (1 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IRC (default) */ +# define BASE_CGU_CLKSEL_ENET_RXCLK (2 << BASE_CGU_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */ +# define BASE_CGU_CLKSEL_ENET_TXCLK (3 << BASE_CGU_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */ +# define BASE_CGU_CLKSEL_GPCLKIN (4 << BASE_CGU_CLK_CLKSEL_SHIFT) /* GP_CLKIN */ +# define BASE_CGU_CLKSEL_XTAL (6 << BASE_CGU_CLK_CLKSEL_SHIFT) /* Crystal oscillator */ +# define BASE_CGU_CLKSEL_PLL0USB (7 << BASE_CGU_CLK_CLKSEL_SHIFT) /* PLL0USB */ +# define BASE_CGU_CLKSEL_PLL0AUDIO (8 << BASE_CGU_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */ +# define BASE_CGU_CLKSEL_PLL1 (9 << BASE_CGU_CLK_CLKSEL_SHIFT) /* PLL1 */ +# define BASE_CGU_CLKSEL_IDIVA (12 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IDIVA */ +# define BASE_CGU_CLKSEL_IDIVB (13 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IDIVB */ +# define BASE_CGU_CLKSEL_IDIVC (14 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IDIVC */ +# define BASE_CGU_CLKSEL_IDIVD (15 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IDIVD */ +# define BASE_CGU_CLKSEL_IDIVE (16 << BASE_CGU_CLK_CLKSEL_SHIFT) /* IDIVE */ + /* Bits 29-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CGU_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_creg.h b/arch/arm/src/lpc43xx/chip/lpc43_creg.h new file mode 100644 index 0000000000000000000000000000000000000000..61a62e69406f71018264f00396429b12a4d77ed1 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_creg.h @@ -0,0 +1,291 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_creg.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CREG_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CREG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_CREG0_OFFSET 0x0004 /* Chip configuration register 0 */ +#define LPC43_CREG_M4MEMMAP_OFFSET 0x0100 /* ARM Cortex-M4 memory mapping */ +#define LPC43_CREG1_OFFSET 0x0108 /* Chip configuration register 1 */ +#define LPC43_CREG2_OFFSET 0x010c /* Chip configuration register 2 */ +#define LPC43_CREG3_OFFSET 0x0110 /* Chip configuration register 3 */ +#define LPC43_CREG4_OFFSET 0x0114 /* Chip configuration register 4 */ +#define LPC43_CREG5_OFFSET 0x0118 /* Chip configuration register 5 */ +#define LPC43_CREG_DMAMUX_OFFSET 0x011c /* DMA mux control */ +#define LPC43_CREG_FLASHCFGA_OFFSET 0x0120 /* Flash accelerator bank A configuration */ +#define LPC43_CREG_FLASHCFGB_OFFSET 0x0124 /* Flash accelerator bankd B configuration */ +#define LPC43_CREG_ETBCFG_OFFSET 0x0128 /* ETB RAM configuration */ +#define LPC43_CREG6_OFFSET 0x012c /* Chip configuration register 6 */ +#define LPC43_CREG_M4TXEVENT_OFFSET 0x0130 /* Cortex-M4 TXEV event clear 0 */ +#define LPC43_CREG_CHIPID_OFFSET 0x0200 /* Part ID */ +#define LPC43_CREG_M0TXEVENT_OFFSET 0x0400 /* Cortex-M0 TXEV event clear */ +#define LPC43_CREG_M0APPMEMMAP_OFFSET 0x0404 /* ARM Cortex-M0 memory mapping */ +#define LPC43_CREG_USB0FLADJ_OFFSET 0x0500 /* USB0 frame length adjust */ +#define LPC43_CREG_USB1FLADJ_OFFSET 0x0600 /* USB1 frame length adjust */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_CREG0 (LPC43_CREG_BASE+LPC43_CREG0_OFFSET) +#define LPC43_CREG_M4MEMMAP (LPC43_CREG_BASE+LPC43_CREG_M4MEMMAP_OFFSET) +#define LPC43_CREG1 (LPC43_CREG_BASE+LPC43_CREG1_OFFSET) +#define LPC43_CREG2 (LPC43_CREG_BASE+LPC43_CREG2_OFFSET) +#define LPC43_CREG3 (LPC43_CREG_BASE+LPC43_CREG3_OFFSET) +#define LPC43_CREG4 (LPC43_CREG_BASE+LPC43_CREG4_OFFSET) +#define LPC43_CREG5 (LPC43_CREG_BASE+LPC43_CREG5_OFFSET) +#define LPC43_CREG_DMAMUX (LPC43_CREG_BASE+LPC43_CREG_DMAMUX_OFFSET) +#define LPC43_CREG_FLASHCFGA (LPC43_CREG_BASE+LPC43_CREG_FLASHCFGA_OFFSET) +#define LPC43_CREG_FLASHCFGB (LPC43_CREG_BASE+LPC43_CREG_FLASHCFGB_OFFSET) +#define LPC43_CREG_ETBCFG (LPC43_CREG_BASE+LPC43_CREG_ETBCFG_OFFSET) +#define LPC43_CREG6 (LPC43_CREG_BASE+LPC43_CREG6_OFFSET) +#define LPC43_CREG_M4TXEVENT (LPC43_CREG_BASE+LPC43_CREG_M4TXEVENT_OFFSET) +#define LPC43_CREG_CHIPID (LPC43_CREG_BASE+LPC43_CREG_CHIPID_OFFSET) +#define LPC43_CREG_M0TXEVENT (LPC43_CREG_BASE+LPC43_CREG_M0TXEVENT_OFFSET) +#define LPC43_CREG_M0APPMEMMAP (LPC43_CREG_BASE+LPC43_CREG_M0APPMEMMAP_OFFSET) +#define LPC43_CREG_USB0FLADJ (LPC43_CREG_BASE+LPC43_CREG_USB0FLADJ_OFFSET) +#define LPC43_CREG_USB1FLADJ (LPC43_CREG_BASE+LPC43_CREG_USB1FLADJ_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Chip configuration register 0 */ + +#define CREG0_EN1KHZ (1 << 0) /* Bit 0: Enable 1 kHz output */ +#define CREG0_EN32KHZ (1 << 1) /* Bit 1: Enable 32 kHz output */ +#define CREG0_RESET32KHZ (1 << 2) /* Bit 2: 32 kHz oscillator reset */ +#define CREG0_PD32KHZ (1 << 3) /* Bit 3: 32 kHz power control */ + /* Bit 4: Reserved */ +#define CREG0_USB0PHY (1 << 5) /* Bit 5: USB0 PHY power control */ +#define CREG0_ALARMCTRL_SHIFT (6) /* Bits 6-7: RTC_ALARM pin output control 0 R/W */ +#define CREG0_ALARMCTRL_MASK (3 << CREG0_ALARMCTRL_SHIFT) +# define CREG0_ALARMCTRL_RTC (0 << CREG0_ALARMCTRL_SHIFT) /* RTC alarm */ +# define CREG0_ALARMCTRL_EVENT (1 << CREG0_ALARMCTRL_SHIFT) /* Event router event */ +# define CREG0_ALARMCTRL_INACTIVE (3 << CREG0_ALARMCTRL_SHIFT) /* Inactive */ +#define CREG0_BODLVL1_SHIFT (8) /* Bits 8-9: BOD trip level to generate an interrupt */ +#define CREG0_BODLVL1_MASK (3 << CREG0_BODLVL1_SHIFT) +# define CREG0_BODLVL1_LEVEL0 (0 << CREG0_BODLVL1_SHIFT) /* Level 0 interrupt */ +# define CREG0_BODLVL1_LEVEL1 (1 << CREG0_BODLVL1_SHIFT) /* Level 1 interrupt */ +# define CREG0_BODLVL1_LEVEL2 (2 << CREG0_BODLVL1_SHIFT) /* Level 2 interrupt */ +# define CREG0_BODLVL1_LEVEL3 (3 << CREG0_BODLVL1_SHIFT) /* Level 3 interrupt */ +#define CREG0_BODLVL2_SHIFT (10) /* Bits 10-11: BOD trip level to generate a reset */ +#define CREG0_BODLVL2_MASK (3 << CREG0_BODLVL2_SHIFT) +# define CREG0_BODLVL2_LEVEL0 (0 << CREG0_BODLVL2_SHIFT) /* Level 0 reset */ +# define CREG0_BODLVL2_LEVEL1 (1 << CREG0_BODLVL2_SHIFT) /* Level 1 reset */ +# define CREG0_BODLVL2_LEVEL2 (2 << CREG0_BODLVL2_SHIFT) /* Level 2 reset */ +# define CREG0_BODLVL2_LEVEL3 (3 << CREG0_BODLVL2_SHIFT) /* Level 3 reset */ +#define CREG0_SAMPLECTRL_SHIFT (12) /* Bits 12-13: SAMPLE pin input/output control */ +#define CREG0_SAMPLECTRL_MASK (3 << CREG0_SAMPLECTRL_SHIFT) +# define CREG0_SAMPLECTRL_MONITOR (1 << CREG0_SAMPLECTRL_SHIFT) /* Output from event monitor/recorder */ +# define CREG0_SAMPLECTRL_EVNTRTR (2 << CREG0_SAMPLECTRL_SHIFT) /* Output from the event router */ +#define CREG0_WAKEUP0CTRL_SHIFT (14) /* Bits 14-15: WAKEUP0 pin input/output control */ +#define CREG0_WAKEUP0CTRL_MASK (3 << CREG0_WAKEUP0CTRL_SHIFT) +# define CREG0_WAKEUP0CTRL_EVNTIN (0 << CREG0_WAKEUP0CTRL_SHIFT) /* Input to the event router */ +# define CREG0_WAKEUP0CTRL_EVNTOUT (1 << CREG0_WAKEUP0CTRL_SHIFT) /* Output from the event router */ +# define CREG0_WAKEUP0CTRL_EVNTIN2 (3 << CREG0_WAKEUP0CTRL_SHIFT) /* Input to the event router */ +#define CREG0_WAKEUP1CTRL_SHIFT (16) /* Bits 16-17: WAKEUP1 pin input/output control */ +#define CREG0_WAKEUP1CTRL_MASK (3 << CREG0_WAKEUP1CTRL_SHIFT) +# define CREG0_WAKEUP1CTRL_EVNTIN (0 << CREG0_WAKEUP1CTRL_SHIFT) /* Input to the event router */ +# define CREG0_WAKEUP1CTRL_EVNTOUT (1 << CREG0_WAKEUP1CTRL_SHIFT) /* Output from the event router */ +# define CREG0_WAKEUP1CTRL_EVNTIN2 (3 << CREG0_WAKEUP1CTRL_SHIFT) /* Input to the event router */ + /* Bits 18-31: Reserved */ +/* ARM Cortex-M4 memory mapping */ + /* Bits 0-11: Reserved */ +#define CREG_M4MEMMAP_SHIFT (12) /* Bits 12-31: M4MAP Shadow address */ +#define CREG_M4MEMMAP_MASK (0x000fffff << CREG_M4MEMMAP_SHIFT) + +/* Chip configuration register 1-4. Bit definitions not provided in the user manual */ + +/* Chip configuration register 5 */ + /* Bits 0-5: Reserved */ +#define CREG5_M4TAPSEL (1 << 6) /* Bit 6: JTAG debug select for M4 core */ + /* Bits 7-8: Reserved */ +#define CREG5_M0APPTAPSEL (1 << 9) /* Bit 9: JTAG debug select for M0 co-processor */ + /* Bits 10-31: Reserved */ +/* DMA mux control */ + +#define CREG_DMAMUX_PER0_SHIFT (0) /* Bits 0-1: Selection for DMA peripheral 0 */ +#define CREG_DMAMUX_PER0_MASK (3 << CREG_DMAMUX_PER0_SHIFT) +# define CREG_DMAMUX_PER0 SPIFI (0 << CREG_DMAMUX_PER0_SHIFT) /* SPIFI */ +# define CREG_DMAMUX_PER0_SCTM2 (1 << CREG_DMAMUX_PER0_SHIFT) /* SCT match 2 */ +# define CREG_DMAMUX_PER0_T3M1 (3 << CREG_DMAMUX_PER0_SHIFT) /* T3 match 1 */ +#define CREG_DMAMUX_PER1_SHIFT (2) /* Bits 2-3: Selection for DMA peripheral 1 */ +#define CREG_DMAMUX_PER1_MASK (3 << CREG_DMAMUX_PER1_SHIFT) +# define CREG_DMAMUX_PER1_T0M0 (0 << CREG_DMAMUX_PER1_SHIFT) /* Timer 0 match 0 */ +# define CREG_DMAMUX_PER1_U0TX (1 << CREG_DMAMUX_PER1_SHIFT) /* USART0 transmit */ +#define CREG_DMAMUX_PER2_SHIFT (4) /* Bits 4-5: Selection for DMA peripheral 2 */ +#define CREG_DMAMUX_PER2_MASK (3 << CREG_DMAMUX_PER2_SHIFT) +# define CREG_DMAMUX_PER2_T0M1 (0 << CREG_DMAMUX_PER2_SHIFT) /* Timer 0 match 1 */ +# define CREG_DMAMUX_PER2_U0RX (1 << CREG_DMAMUX_PER2_SHIFT) /* USART0 receive */ +#define CREG_DMAMUX_PER3_SHIFT (6) /* Bits 6-7: Selection for DMA peripheral 3 */ +#define CREG_DMAMUX_PER3_MASK (3 << CREG_DMAMUX_PER3_SHIFT) +# define CREG_DMAMUX_PER3_T1M0 (0 << CREG_DMAMUX_PER3_SHIFT) /* Timer 1 match 0 */ +# define CREG_DMAMUX_PER3_U1TX (1 << CREG_DMAMUX_PER3_SHIFT) /* UART1 transmit */ +# define CREG_DMAMUX_PER3_I2S1D1 (2 << CREG_DMAMUX_PER3_SHIFT) /* I2S1 DMA request 1 */ +# define CREG_DMAMUX_PER3_SSP1TX (3 << CREG_DMAMUX_PER3_SHIFT) /* SSP1 transmit */ +#define CREG_DMAMUX_PER4_SHIFT (8) /* Bits 8-9: Selection for DMA peripheral 4 */ +#define CREG_DMAMUX_PER4_MASK (3 << CREG_DMAMUX_PER4_SHIFT) +# define CREG_DMAMUX_PER4_T1M1 (0 << CREG_DMAMUX_PER4_SHIFT) /* Timer 1 match 1 */ +# define CREG_DMAMUX_PER4_U1RX (1 << CREG_DMAMUX_PER4_SHIFT) /* UART1 receive */ +# define CREG_DMAMUX_PER4_I2S1D2 (2 << CREG_DMAMUX_PER4_SHIFT) /* I2S1 DMA request 2 */ +# define CREG_DMAMUX_PER4_SSP1RX (3 << CREG_DMAMUX_PER4_SHIFT) /* SSP1 receive */ +#define CREG_DMAMUX_PER5_SHIFT (10) /* Bits 10-11: Selection for DMA peripheral 5 */ +#define CREG_DMAMUX_PER5_MASK (3 << CREG_DMAMUX_PER5_SHIFT) +# define CREG_DMAMUX_PER5_T2M0 (0 << CREG_DMAMUX_PER5_SHIFT) /* Timer 2 match 0 */ +# define CREG_DMAMUX_PER5_U2TX (1 << CREG_DMAMUX_PER5_SHIFT) /* USART2 transmit */ +# define CREG_DMAMUX_PER5_SSP1TX (2 << CREG_DMAMUX_PER5_SHIFT) /* SSP1 transmit */ +#define CREG_DMAMUX_PER6_SHIFT (12) /* Bits 12-13: Selection for DMA peripheral 6 */ +#define CREG_DMAMUX_PER6_MASK (3 << CREG_DMAMUX_PER6_SHIFT) +# define CREG_DMAMUX_PER6_T2M1 (0 << CREG_DMAMUX_PER6_SHIFT) /* Timer 2 match 1 */ +# define CREG_DMAMUX_PER6_U2RX (1 << CREG_DMAMUX_PER6_SHIFT) /* USART2 receive */ +# define CREG_DMAMUX_PER6_SSP1RX (2 << CREG_DMAMUX_PER6_SHIFT) /* SSP1 receive */ +#define CREG_DMAMUX_PER7_SHIFT (14) /* Bits 14-15: Selection for DMA peripheral 7 */ +#define CREG_DMAMUX_PER7_MASK (3 << CREG_DMAMUX_PER7_SHIFT) +# define CREG_DMAMUX_PER7_T3M1 (0 << CREG_DMAMUX_PER7_SHIFT) /* Timer 3 match l */ +# define CREG_DMAMUX_PER7_U3TX (1 << CREG_DMAMUX_PER7_SHIFT) /* USART3 transmit */ +# define CREG_DMAMUX_PER7_SCTM0 (2 << CREG_DMAMUX_PER7_SHIFT) /* SCT match output 0 */ +#define CREG_DMAMUX_PER8_SHIFT (16) /* Bits 16-17: Selection for DMA peripheral 8 */ +#define CREG_DMAMUX_PER8_MASK (3 << CREG_DMAMUX_PER8_SHIFT) +# define CREG_DMAMUX_PER8_T3M1 (0 << CREG_DMAMUX_PER8_SHIFT) /* Timer 3 match 1 */ +# define CREG_DMAMUX_PER8_U3RX (1 << CREG_DMAMUX_PER8_SHIFT) /* USART3 receive */ +# define CREG_DMAMUX_PER8_SCTM1 (2 << CREG_DMAMUX_PER8_SHIFT) /* SCT match output 1 */ +#define CREG_DMAMUX_PER9_SHIFT (18) /* Bits 18-19: Selection for DMA peripheral 9 */ +#define CREG_DMAMUX_PER9_MASK (3 << CREG_DMAMUX_PER9_SHIFT) +# define CREG_DMAMUX_PER9_SSP0RX (0 << CREG_DMAMUX_PER9_SHIFT) /* SSP0 receive */ +# define CREG_DMAMUX_PER9_I2S0D1 (1 << CREG_DMAMUX_PER9_SHIFT) /* I2S0 DMA request 1 */ +# define CREG_DMAMUX_PER9_SCTM1 (2 << CREG_DMAMUX_PER9_SHIFT) /* SCT match output 1 */ +#define CREG_DMAMUX_PER10_SHIFT (20) /* Bits 20-21: Selection for DMA peripheral 10 */ +#define CREG_DMAMUX_PER10_MASK (3 << CREG_DMAMUX_PER10_SHIFT) +# define CREG_DMAMUX_PER10_SSP0TX (0 << CREG_DMAMUX_PER10_SHIFT) /* SSP0 transmit */ +# define CREG_DMAMUX_PER10_I2S0D2 (1 << CREG_DMAMUX_PER10_SHIFT) /* I2S0 DMA request 2 */ +# define CREG_DMAMUX_PER10_SCTM0 (2 << CREG_DMAMUX_PER10_SHIFT) /* SCT match output 0 */ +#define CREG_DMAMUX_PER11_SHIFT (22) /* Bits 22-23: Selection for DMA peripheral 11 */ +#define CREG_DMAMUX_PER11_MASK (3 << CREG_DMAMUX_PER11_SHIFT) +# define CREG_DMAMUX_PER11_SSP1RX (0 << CREG_DMAMUX_PER11_SHIFT) /* SSP1 receive */ +# define CREG_DMAMUX_PER11_U0TX (2 << CREG_DMAMUX_PER11_SHIFT) /* USART0 transmit */ +#define CREG_DMAMUX_PER12_SHIFT (24) /* Bits 24-25: Selection for DMA peripheral 12 */ +#define CREG_DMAMUX_PER12_MASK (3 << CREG_DMAMUX_PER12_SHIFT) +# define CREG_DMAMUX_PER12_SSP1TX (0 << CREG_DMAMUX_PER12_SHIFT) /* SSP1 transmit */ +# define CREG_DMAMUX_PER12_U0RX (2 << CREG_DMAMUX_PER12_SHIFT) /* USART0 receive */ +#define CREG_DMAMUX_PER13_SHIFT (26) /* Bits 26-27: Selection for DMA peripheral 13 */ +#define CREG_DMAMUX_PER13_MASK (3 << CREG_DMAMUX_PER13_SHIFT) +# define CREG_DMAMUX_PER13_ADC0 (0 << CREG_DMAMUX_PER13_SHIFT) /* ADC0 */ +# define CREG_DMAMUX_PER13_SSP1RX (2 << CREG_DMAMUX_PER13_SHIFT) /* SSP1 receive */ +# define CREG_DMAMUX_PER13_U3RX (3 << CREG_DMAMUX_PER13_SHIFT) /* USART3 receive */ +#define CREG_DMAMUX_PER14_SHIFT (28) /* Bits 28-29: Selection for DMA peripheral 14 */ +#define CREG_DMAMUX_PER14_MASK (3 << CREG_DMAMUX_PER12_SHIFT) +# define CREG_DMAMUX_PER14_ADC1 (0 << CREG_DMAMUX_PER14_SHIFT) /* ADC1 */ +# define CREG_DMAMUX_PER14_SSP1TX (2 << CREG_DMAMUX_PER14_SHIFT) /* SSP1 transmit */ +# define CREG_DMAMUX_PER14_U3TX (3 << CREG_DMAMUX_PER14_SHIFT) /* USART3 transmit */ +#define CREG_DMAMUX_PER15_SHIFT (30) /* Bits 30-31: Selection for DMA peripheral 15 */ +#define CREG_DMAMUX_PER15_MASK (3 << CREG_DMAMUX_PER15_SHIFT) +# define CREG_DMAMUX_PER15_DAC (0 << CREG_DMAMUX_PER15_SHIFT) /* DAC */ +# define CREG_DMAMUX_PER15_SCTM3 (1 << CREG_DMAMUX_PER15_SHIFT) /* SCT match output 3 */ +# define CREG_DMAMUX_PER15_T3M0 (3 << CREG_DMAMUX_PER15_SHIFT) /* Timer 3 match 0 */ + +/* Flash accelerator bank A/B configuration */ + /* Bits 0-11: Reserved */ +#define CREG_FLASHCFG_FLASHTIM_SHIFT (12) /* Bits 12-15: Flash access time */ +#define CREG_FLASHCFG_FLASHTIM_MASK (15 << CREG_FLASHCFG_FLASHTIM_SHIFT) +# define CREG_FLASHCFG_FLASHTIM(n) (((n)-1) << CREG_FLASHCFG_FLASHTIM_SHIFT) /* n BASE_M4_CLK clocks, n=1..10 */ + /* Bits 16-31: Reserved */ +#define CREG_FLASHCFG_POW (1 << 31) /* Bit 31: Flash bank A power control */ + +/* ETB RAM configuration */ + +#define CREG_ETBCFG (1 << 0) /* Bit 0: Select SRAM interface */ + /* Bits 1-31: Reserved */ +/* Chip configuration register 6 */ + +#define CREG6_ETHMODE_SHIFT (0) /* Bits 0-2: Selects the Ethernet mode */ +#define CREG6_ETHMODE_MASK (7 << CREG6_ETHMODE_SHIFT) +# define CREG6_ETHMODE_MII (0 << CREG6_ETHMODE_SHIFT) +# define CREG6_ETHMODE_RMII (4 << CREG6_ETHMODE_SHIFT) + /* Bit 3: Reserved */ +#define CREG6_CTOUTCTRL (1 << 4) /* Bit 4: Selects the functionality of the SCT outputs */ + /* Bits 5-11: Reserved */ +#define CREG6_I2S0_TXSCK (1 << 12) /* Bit 12: I2S0_TX_SCK input select */ +#define CREG6_I2S0_RXSCK (1 << 13) /* Bit 13: I2S0_RX_SCK input select */ +#define CREG6_I2S1_TXSCK (1 << 14) /* Bit 14: I2S1_TX_SCK input select */ +#define CREG6_I2S1_RXSCK (1 << 15) /* Bit 15: I2S1_RX_SCK input select */ +#define CREG6_EMC_CLK (1 << 16) /* Bit 16: EMC_CLK divided clock select */ + /* Bits 17-31: Reserved */ +/* Cortex-M4 TXEV event clear 0 */ + +#define CREG_M4TXEVENT (1 << 0) /* Bit 0: Cortex-M4 TXEV event */ + /* Bits 1-31: Reserved */ +/* Part ID (32-bit ID) */ + +#define CREG_CHIPID_FLASHLESS1 0x5906002b /* LPC4350/30/20/10 */ +#define CREG_CHIPID_FLASHLESS2 0x6906002b /* LPC4350/30/20/10 */ +#define CREG_CHIPID_FLASHPARTS 0x4906002b /* LPC4357/53 */ + +/* Cortex-M0 TXEV event clear */ + +#define CREG_M0TXEVENT (1 << 0) /* Bit 0: Cortex-M0 TXEV event */ + /* Bits 1-31: Reserved */ +/* ARM Cortex-M0 memory mapping */ + /* Bits 0-11: Reserved */ +#define CREG_M0APPMEMMAP_SHIFT (12) /* Bits 12-31: M4MAP Shadow address */ +#define CREG_M0APPMEMMAP_MASK (0x000fffff << CREG_M0APPMEMMAP_SHIFT) + +/* USB0/1 frame length adjust */ + +#define CREG_USBFLADJ_SHIFT (0) /* Bits 0-5: FLTV Frame length timing value */ +#define CREG_USBFLADJ_MASK (0x3f << CREG_USBFLADJ_SHIFT) +# define CREG_USBFLADJ(n) ((((n)-59488) >> 4) << CREG_USBFLADJ_SHIFT) + /* Bits 6-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_CREG_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_dac.h b/arch/arm/src/lpc43xx/chip/lpc43_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..e06ecf442c1e71f08a17a3611a88ddc66b9afdd5 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_dac.h @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_dac.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_DAC_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_DAC_CR_OFFSET 0x0000 /* D/A Converter Register */ +#define LPC43_DAC_CTRL_OFFSET 0x0004 /* DAC Control register */ +#define LPC43_DAC_CNTVAL_OFFSET 0x0008 /* DAC Counter Value register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_DAC_CR (LPC43_DAC_BASE+LPC43_DAC_CR_OFFSET) +#define LPC43_DAC_CTRL (LPC43_DAC_BASE+LPC43_DAC_CTRL_OFFSET) +#define LPC43_DAC_CNTVAL (LPC43_DAC_BASE+LPC43_DAC_CNTVAL_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* D/A Converter Register */ + /* Bits 0-5: Reserved */ +#define DAC_CR_VALUE_SHIFT (6) /* Bits 6-15: Controls voltage on the AOUT pin */ +#define DAC_CR_VALUE_MASK (0x3ff << DAC_CR_VALUE_SHIFT) +#define DAC_CR_BIAS (1 << 16) /* Bit 16: Controls DAC settling time */ + /* Bits 17-31: Reserved */ +/* DAC Control register */ + +#define DAC_CTRL_INTDMAREQ (1 << 0) /* Bit 0: Timer timed out */ +#define DAC_CTRL_DBLBUFEN (1 << 1) /* Bit 1: Enable DACR double-buffering */ +#define DAC_CTRL_CNTEN (1 << 2) /* Bit 2: Enable timeout counter */ +#define DAC_CTRL_DMAEN (1 << 3) /* Bit 3: Enable DMA access */ + /* Bits 4-31: Reserved */ +/* DAC Counter Value register */ + +#define DAC_CNTVAL_SHIFT (0) /* Bits 0-15: Reload value for DAC interrupt/DMA timer */ +#define DAC_CNTVAL_MASK (0xffff << DAC_CNTVAL_SHIFT) + /* Bits 8-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_DAC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h b/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..8b0398447eaefb8f96bf0159af0d8ac3f9767495 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_eeprom.h @@ -0,0 +1,158 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_eeprom.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EEPROM_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EEPROM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +/* EEPROM registers */ + +#define LPC43_EEPROM_CMD_OFFSET 0x000 /* EEPROM command register */ +#define LPC43_EEPROM_RWSTATE_OFFSET 0x008 /* EEPROM read wait state register */ +#define LPC43_EEPROM_AUTOPROG_OFFSET 0x00c /* EEPROM auto programming register */ +#define LPC43_EEPROM_WSTATE_OFFSET 0x010 /* EEPROM wait state register */ +#define LPC43_EEPROM_CLKDIV_OFFSET 0x014 /* EEPROM clock divider register */ +#define LPC43_EEPROM_PWRDWN_OFFSET 0x018 /* EEPROM power-down register */ + +/* EEPROM interrupt registers */ + +#define LPC43_EEPROM_INTENCLR_OFFSET 0xfd8 /* EEPROM interrupt enable clear */ +#define LPC43_EEPROM_INTENSET_OFFSET 0xfdc /* EEPROM interrupt enable set */ +#define LPC43_EEPROM_INTSTAT_OFFSET 0xfe0 /* EEPROM interrupt status */ +#define LPC43_EEPROM_INTEN_OFFSET 0xfe4 /* EEPROM interrupt enable */ +#define LPC43_EEPROM_INTSTATCLR_OFFSET 0xfe8 /* EEPROM interrupt status clear */ +#define LPC43_EEPROM_INTSTATSET_OFFSET 0xfec /* EEPROM interrupt status set */ + +/* Register Addresses ***************************************************************/ + +/* EEPROM registers */ + +#define LPC43_EEPROM_CMD (LPC43_EEPROMC_BASE+LPC43_EEPROM_CMD_OFFSET) +#define LPC43_EEPROM_RWSTATE (LPC43_EEPROMC_BASE+LPC43_EEPROM_RWSTATE_OFFSET) +#define LPC43_EEPROM_AUTOPROG (LPC43_EEPROMC_BASE+LPC43_EEPROM_AUTOPROG_OFFSET) +#define LPC43_EEPROM_WSTATE (LPC43_EEPROMC_BASE+LPC43_EEPROM_WSTATE_OFFSET) +#define LPC43_EEPROM_CLKDIV (LPC43_EEPROMC_BASE+LPC43_EEPROM_CLKDIV_OFFSET) +#define LPC43_EEPROM_PWRDWN (LPC43_EEPROMC_BASE+LPC43_EEPROM_PWRDWN_OFFSET) + +/* EEPROM interrupt registers */ + +#define LPC43_EEPROM_INTENCLR (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTENCLR_OFFSET) +#define LPC43_EEPROM_INTENSET (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTENSET_OFFSET) +#define LPC43_EEPROM_INTSTAT (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTSTAT_OFFSET) +#define LPC43_EEPROM_INTEN (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTEN_OFFSET) +#define LPC43_EEPROM_INTSTATCLR (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTSTATCLR_OFFSET) +#define LPC43_EEPROM_INTSTATSET (LPC43_EEPROMC_BASE+LPC43_EEPROM_INTSTATSET_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* EEPROM registers */ + +/* EEPROM command register */ + +#define EEPROM_CMD_SHIFT (0) /* Bits 0-2: Command */ +#define EEPROM_CMD_MASK (7 << EEPROM_CMD_SHIFT) +# define EEPROM_CMD_PROGRAM 6 /* 110=erase/program page */ + /* Bits 3-31: Reserved */ +/* EEPROM read wait state register */ + +#define EEPROM_RWSTATE_RPHASE2_SHIFT (0) /* Bits 0-7: Wait states 2 (minus 1) */ +#define EEPROM_RWSTATE_RPHASE2_MASK (0xff << EEPROM_RWSTATE_RPHASE2_SHIFT) +# define EEPROM_RWSTATE_RPHASE2(n) (((n)-1) << EEPROM_RWSTATE_RPHASE2_SHIFT) +#define EEPROM_RWSTATE_RPHASE1_SHIFT (8) /* Bits 8-15: Wait states 1 (minus 1) */ +#define EEPROM_RWSTATE_RPHASE1_MASK (0xff << EEPROM_RWSTATE_RPHASE1_SHIFT) +# define EEPROM_RWSTATE_RPHASE1(n) (((n)-1) << EEPROM_RWSTATE_RPHASE1_SHIFT) + /* Bits 16-31: Reserved */ +/* EEPROM auto programming register */ + +#define EEPROM_AUTOPROG_SHIFT (0) /* Bits 0-1: Auto programming mode */ +#define EEPROM_AUTOPROG_MASK (3 << EEPROM_AUTOPROG_SHIFT) +# define EEPROM_AUTOPROG_OFF (0 << EEPROM_AUTOPROG_SHIFT) /* auto programming off */ +# define EEPROM_AUTOPROG_FIRST (1 << EEPROM_AUTOPROG_SHIFT) /* erase/program cycle triggered by first word */ +# define EEPROM_AUTOPROG_LAST (2 << EEPROM_AUTOPROG_SHIFT) /* erase/program cycle triggered by last word */ + /* Bits 2-31: Reserved */ +/* EEPROM wait state register */ + +#define EEPROM_WSTATE_PHASE3_SHIFT (0) /* Bits 0-7: Wait states for phase 3 (minus 1) */ +#define EEPROM_WSTATE_PHASE3_MASK (0xff << EEPROM_WSTATE_PHASE3_SHIFT) +#define EEPROM_WSTATE_PHASE2_SHIFT (8) /* Bits 8-15: Wait states for phase 2 (minus 1) */ +#define EEPROM_WSTATE_PHASE2_MASK (0xff << EEPROM_WSTATE_PHASE2_SHIFT) +#define EEPROM_WSTATE_PHASE1_SHIFT (16) /* Bits 16-23: Wait states for phase 1 (minus 1) */ +#define EEPROM_WSTATE_PHASE1_MASK (0xff << EEPROM_WSTATE_PHASE1_SHIFT) + /* Bits 24-30: Reserved */ +#define EEPROM_WSTATE_LCK_PARWEP (1 << 31) /* Bit 31: Lock for write, erase and program */ + +/* EEPROM clock divider register */ + +#define EEPROM_CLKDIV_MASK (0xffff) /* Bits 0-15: Division factor (minus 1) */ +#define EEPROM_CLKDIV(n) ((n)-1) /* Bits 0-15: Division factor (minus 1) */ + /* Bits 16-31: Reserved */ +/* EEPROM power-down register */ + +#define EEPROM_PWRDWN (1 << 0) /* Bit 0: Power down mode bit */ + /* Bits 1-31: Reserved */ +/* EEPROM interrupt registers */ +/* EEPROM interrupt enable clear */ +/* EEPROM interrupt enable set */ +/* EEPROM interrupt status */ +/* EEPROM interrupt enable */ +/* EEPROM interrupt status clear */ +/* EEPROM interrupt status set */ + /* Bits 0-1: Reserved */ +#define EEPROM_INT_ENDOFPROG (1 << 2) /* Bit 2: Program operation finished interrupt */ + /* Bits 3-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EEPROM_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_emc.h b/arch/arm/src/lpc43xx/chip/lpc43_emc.h new file mode 100644 index 0000000000000000000000000000000000000000..4fb3ae38be61f47a15f3a0fae38a11550dbb4bc9 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_emc.h @@ -0,0 +1,425 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_emc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EMC_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EMC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_EMC_CONTROL_OFFSET 0x0000 /* EMC Control register */ +#define LPC43_EMC_STATUS_OFFSET 0x0004 /* EMC Status register */ +#define LPC43_EMC_CONFIG_OFFSET 0x0008 /* EMC Configuration register */ +#define LPC43_EMC_DYNCONTROL_OFFSET 0x0020 /* Dynamic Memory Control register */ +#define LPC43_EMC_DYNREFRESH_OFFSET 0x0024 /* Dynamic Memory Refresh Timer register */ +#define LPC43_EMC_DYNREADCONFIG_OFFSET 0x0028 /* Dynamic Memory Read Configuration register */ +#define LPC43_EMC_DYNRP_OFFSET 0x0030 /* Dynamic Memory Precharge Command Period register */ +#define LPC43_EMC_DYNRAS_OFFSET 0x0034 /* Dynamic Memory Active to Precharge Command Period register */ +#define LPC43_EMC_DYNSREX_OFFSET 0x0038 /* Dynamic Memory Self Refresh Exit Time register */ +#define LPC43_EMC_DYNAPR_OFFSET 0x003c /* Dynamic Memory Last Data Out to Active Time register */ +#define LPC43_EMC_DYNDAL_OFFSET 0x0040 /* Dynamic Memory Data In to Active Command Time register */ +#define LPC43_EMC_DYNWR_OFFSET 0x0044 /* Dynamic Memory Write Recovery Time register */ +#define LPC43_EMC_DYNRC_OFFSET 0x0048 /* Dynamic Memory Active to Active Command Period register */ +#define LPC43_EMC_DYNRFC_OFFSET 0x004c /* Dynamic Memory Auto-refresh Period register */ +#define LPC43_EMC_DYNXSR_OFFSET 0x0050 /* Dynamic Memory Exit Self Refresh register */ +#define LPC43_EMC_DYNRRD_OFFSET 0x0054 /* Dynamic Memory Active Bank A to Active Bank B Time register */ +#define LPC43_EMC_DYNMRD_OFFSET 0x0058 /* Dynamic Memory Load Mode register to Active Command Time */ +#define LPC43_EMC_STATEXTWAIT_OFFSET 0x0080 /* Static Memory Extended Wait register */ + +#define LPC43_EMC_DYNCONFIG_CSOFFSET 0x0000 +#define LPC43_EMC_DYNRASCAS_CSOFFSET 0x0004 +#define LPC43_EMC_DYNCS_OFFSET(n) (0x100 + ((n) << 5)) +#define LPC43_EMC_DYNCONFIG_OFFSET(n) (DYNCS_OFFSET(n)+DYNCONFIG_CSOFFSET) +#define LPC43_EMC_DYNRASCAS_OFFSET(n) (DYNCS_OFFSET(n)+DYNRASCAS_CSOFFSET) + +#define LPC43_EMC_DYNCONFIG0_OFFSET 0x0100 /* Dynamic Memory Configuration register CS0 */ +#define LPC43_EMC_DYNRASCAS0_OFFSET 0x0104 /* Dynamic Memory RAS & CAS Delay register CS0 */ +#define LPC43_EMC_DYNCONFIG1_OFFSET 0x0120 /* Dynamic Memory Configuration register CS1 */ +#define LPC43_EMC_DYNRASCAS1_OFFSET 0x0124 /* Dynamic Memory RAS & CAS Delay register CS1 */ +#define LPC43_EMC_DYNCONFIG2_OFFSET 0x0140 /* Dynamic Memory Configuration register CS2 */ +#define LPC43_EMC_DYNRASCAS2_OFFSET 0x0144 /* Dynamic Memory RAS & CAS Delay register CS2 */ +#define LPC43_EMC_DYNCONFIG3_OFFSET 0x0160 /* Dynamic Memory Configuration register CS3 */ +#define LPC43_EMC_DYNRASCAS3_OFFSET 0x0164 /* ynamic Memory RAS & CAS Delay register CS3 */ + +#define LPC43_EMC_STATCONFIG_CSOFFSET 0x0000 /* Static Memory Configuration register */ +#define LPC43_EMC_STATWAITWEN_CSOFFSET 0x0004 /* Static Memory Write Enable Delay register */ +#define LPC43_EMC_STATWAITOEN_CSOFFSET 0x0008 /* Static Memory Output Enable Delay register */ +#define LPC43_EMC_STATWAITRD_CSOFFSET 0x000c /* Static Memory Read Delay register */ +#define LPC43_EMC_STATWAITPAGE_CSOFFSET 0x0010 /* Static Memory Write Delay registers */ +#define LPC43_EMC_STATWAITWR_CSOFFSET 0x0014 /* Static Memory Page Mode Read Delay register */ +#define LPC43_EMC_STATWAITTURN_CSOFFSET 0x0018 /* Static Memory Turn Round Delay register */ +#define LPC43_EMC_STATCS_OFFSET(n) (0x0200 + ((n) << 5)) +#define LPC43_EMC_STATCONFIG_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATCONFIG_CSOFFSET) +#define LPC43_EMC_STATWAITWEN_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITWEN_CSOFFSET) +#define LPC43_EMC_STATWAITOEN_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITOEN_CSOFFSET) +#define LPC43_EMC_STATWAITRD_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITRD_CSOFFSET) +#define LPC43_EMC_STATWAITPAGE_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITPAGE_CSOFFSET) +#define LPC43_EMC_STATWAITWR_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITWR_CSOFFSET) +#define LPC43_EMC_STATWAITTURN_OFFSET(n) (LPC43_EMC_STATCS_OFFSET(n)+LPC43_EMC_STATWAITTURN_CSOFFSET) + +#define LPC43_EMC_STATCONFIG0_OFFSET 0x0200 /* Static Memory Configuration register CS0 */ +#define LPC43_EMC_STATWAITWEN0_OFFSET 0x0204 /* Static Memory Write Enable Delay register CS0 */ +#define LPC43_EMC_STATWAITOEN0_OFFSET 0x0208 /* Static Memory Output Enable Delay register CS0 */ +#define LPC43_EMC_STATWAITRD0_OFFSET 0x020c /* Static Memory Read Delay register CS0 */ +#define LPC43_EMC_STATWAITPAGE0_OFFSET 0x0210 /* Static Memory Page Mode Read Delay register CS0 */ +#define LPC43_EMC_STATWAITWR0_OFFSET 0x0214 /* Static Memory Write Delay register CS0 */ +#define LPC43_EMC_STATWAITTURN0_OFFSET 0x0218 /* Static Memory Turn Round Delay register CS0 */ + +#define LPC43_EMC_STATCONFIG1_OFFSET 0x0220 /* Static Memory Configuration register CS1 */ +#define LPC43_EMC_STATWAITWEN1_OFFSET 0x0224 /* Static Memory Write Enable Delay register CS1 */ +#define LPC43_EMC_STATWAITOEN1_OFFSET 0x0228 /* Static Memory Output Enable Delay register CS1 */ +#define LPC43_EMC_STATWAITRD1_OFFSET 0x022c /* Static Memory Read Delay register CS1 */ +#define LPC43_EMC_STATWAITPAGE1_OFFSET 0x0230 /* Static Memory Page Mode Read Delay register CS1 */ +#define LPC43_EMC_STATWAITWR1_OFFSET 0x0234 /* Static Memory Write Delay registers CS1 */ +#define LPC43_EMC_STATWAITTURN1_OFFSET 0x0238 /* Static Memory Turn Round Delay register CS1 */ + +#define LPC43_EMC_STATCONFIG2_OFFSET 0x0240 /* Static Memory Configuration register CS2 */ +#define LPC43_EMC_STATWAITWEN2_OFFSET 0x0244 /* Static Memory Write Enable Delay register CS2 */ +#define LPC43_EMC_STATWAITOEN2_OFFSET 0x0248 /* Static Memory Output Enable Delay register CS2 */ +#define LPC43_EMC_STATWAITRD2_OFFSET 0x024c /* Static Memory Read Delay register CS2 */ +#define LPC43_EMC_STATWAITPAGE2_OFFSET 0x0250 /* Static Memory Page Mode Read Delay register CS2 */ +#define LPC43_EMC_STATWAITWR2_OFFSET 0x0254 /* Static Memory Write Delay registers CS2 */ +#define LPC43_EMC_STATWAITTURN2_OFFSET 0x0258 /* Static Memory Turn Round Delay register CS2 */ + +#define LPC43_EMC_STATCONFIG3_OFFSET 0x0260 /* Static Memory Configuration register CS3 */ +#define LPC43_EMC_STATWAITWEN3_OFFSET 0x0264 /* Static Memory Write Enable Delay register CS3 */ +#define LPC43_EMC_STATWAITOEN3_OFFSET 0x0268 /* Static Memory Output Enable Delay register CS3 */ +#define LPC43_EMC_STATWAITRD3_OFFSET 0x026c /* Static Memory Read Delay register CS3 */ +#define LPC43_EMC_STATWAITPAGE3_OFFSET 0x0270 /* Static Memory Page Mode Read Delay register CS3 */ +#define LPC43_EMC_STATWAITWR3_OFFSET 0x0274 /* Static Memory Write Delay registers CS3 */ +#define LPC43_EMC_STATWAITTURN3_OFFSET 0x0278 /* Static Memory Turn Round Delay register CS3 */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_EMC_CONTROL (LPC43_EMC_BASE+LPC43_EMC_CONTROL_OFFSET) +#define LPC43_EMC_STATUS (LPC43_EMC_BASE+LPC43_EMC_STATUS_OFFSET) +#define LPC43_EMC_CONFIG (LPC43_EMC_BASE+LPC43_EMC_CONFIG_OFFSET) +#define LPC43_EMC_DYNCONTROL (LPC43_EMC_BASE+LPC43_EMC_DYNCONTROL_OFFSET) +#define LPC43_EMC_DYNREFRESH (LPC43_EMC_BASE+LPC43_EMC_DYNREFRESH_OFFSET) +#define LPC43_EMC_DYNREADCONFIG (LPC43_EMC_BASE+LPC43_EMC_DYNREADCONFIG_OFFSET) +#define LPC43_EMC_DYNRP (LPC43_EMC_BASE+LPC43_EMC_DYNRP_OFFSET) +#define LPC43_EMC_DYNRAS (LPC43_EMC_BASE+LPC43_EMC_DYNRAS_OFFSET) +#define LPC43_EMC_DYNSREX (LPC43_EMC_BASE+LPC43_EMC_DYNSREX_OFFSET) +#define LPC43_EMC_DYNAPR (LPC43_EMC_BASE+LPC43_EMC_DYNAPR_OFFSET) +#define LPC43_EMC_DYNDAL (LPC43_EMC_BASE+LPC43_EMC_DYNDAL_OFFSET) +#define LPC43_EMC_DYNWR (LPC43_EMC_BASE+LPC43_EMC_DYNWR_OFFSET) +#define LPC43_EMC_DYNRC (LPC43_EMC_BASE+LPC43_EMC_DYNRC_OFFSET) +#define LPC43_EMC_DYNRFC (LPC43_EMC_BASE+LPC43_EMC_DYNRFC_OFFSET) +#define LPC43_EMC_DYNXSR (LPC43_EMC_BASE+LPC43_EMC_DYNXSR_OFFSET) +#define LPC43_EMC_DYNRRD (LPC43_EMC_BASE+LPC43_EMC_DYNRRD_OFFSET) +#define LPC43_EMC_DYNMRD (LPC43_EMC_BASE+LPC43_EMC_DYNMRD_OFFSET) +#define LPC43_EMC_STATEXTWAIT (LPC43_EMC_BASE+LPC43_EMC_STATEXTWAIT_OFFSET) + +#define LPC43_EMC_DYNCS(n) (LPC43_EMC_BASE+LPC43_EMC_DYNCS_OFFSET(n)) +#define LPC43_EMC_DYNCONFIG(n) (LPC43_EMC_BASE+LPC43_EMC_DYNCONFIG_OFFSET(n)) +#define LPC43_EMC_DYNRASCAS(n) (LPC43_EMC_BASE+LPC43_EMC_DYNRASCAS_OFFSET(n)) + +#define LPC43_EMC_DYNCONFIG0 (LPC43_EMC_BASE+LPC43_EMC_DYNCONFIG0_OFFSET) +#define LPC43_EMC_DYNRASCAS0 (LPC43_EMC_BASE+LPC43_EMC_DYNRASCAS0_OFFSET) +#define LPC43_EMC_DYNCONFIG1 (LPC43_EMC_BASE+LPC43_EMC_DYNCONFIG1_OFFSET) +#define LPC43_EMC_DYNRASCAS1 (LPC43_EMC_BASE+LPC43_EMC_DYNRASCAS1_OFFSET) +#define LPC43_EMC_DYNCONFIG2 (LPC43_EMC_BASE+LPC43_EMC_DYNCONFIG2_OFFSET) +#define LPC43_EMC_DYNRASCAS2 (LPC43_EMC_BASE+LPC43_EMC_DYNRASCAS2_OFFSET) +#define LPC43_EMC_DYNCONFIG3 (LPC43_EMC_BASE+LPC43_EMC_DYNCONFIG3_OFFSET) +#define LPC43_EMC_DYNRASCAS3 (LPC43_EMC_BASE+LPC43_EMC_DYNRASCAS3_OFFSET) + +#define LPC43_EMC_STATCS(n) (LPC43_EMC_BASE+LPC43_EMC_STATCS_OFFSET(n)) +#define LPC43_EMC_STATCONFIG(n) (LPC43_EMC_BASE+LPC43_EMC_STATCONFIG_OFFSET(n)) +#define LPC43_EMC_STATWAITWEN(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITWEN_OFFSET(n)) +#define LPC43_EMC_STATWAITOEN(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITOEN_OFFSET(n)) +#define LPC43_EMC_STATWAITRD(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITRD_OFFSET(n)) +#define LPC43_EMC_STATWAITPAGE(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITPAGE_OFFSET(n)) +#define LPC43_EMC_STATWAITWR(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITWR_OFFSET(n)) +#define LPC43_EMC_STATWAITTURN(n) (LPC43_EMC_BASE+LPC43_EMC_STATWAITTURN_OFFSET(n)) + +#define LPC43_EMC_STATCONFIG0 (LPC43_EMC_BASE+LPC43_EMC_STATCONFIG0_OFFSET) +#define LPC43_EMC_STATWAITWEN0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWEN0_OFFSET) +#define LPC43_EMC_STATWAITOEN0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITOEN0_OFFSET) +#define LPC43_EMC_STATWAITRD0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITRD0_OFFSET) +#define LPC43_EMC_STATWAITPAGE0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITPAGE0_OFFSET) +#define LPC43_EMC_STATWAITWR0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWR0_OFFSET) +#define LPC43_EMC_STATWAITTURN0 (LPC43_EMC_BASE+LPC43_EMC_STATWAITTURN0_OFFSET) + +#define LPC43_EMC_STATCONFIG1 (LPC43_EMC_BASE+LPC43_EMC_STATCONFIG1_OFFSET) +#define LPC43_EMC_STATWAITWEN1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWEN1_OFFSET) +#define LPC43_EMC_STATWAITOEN1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITOEN1_OFFSET) +#define LPC43_EMC_STATWAITRD1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITRD1_OFFSET) +#define LPC43_EMC_STATWAITPAGE1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITPAGE1_OFFSET) +#define LPC43_EMC_STATWAITWR1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWR1_OFFSET) +#define LPC43_EMC_STATWAITTURN1 (LPC43_EMC_BASE+LPC43_EMC_STATWAITTURN1_OFFSET) + +#define LPC43_EMC_STATCONFIG2 (LPC43_EMC_BASE+LPC43_EMC_STATCONFIG2_OFFSET) +#define LPC43_EMC_STATWAITWEN2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWEN2_OFFSET) +#define LPC43_EMC_STATWAITOEN2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITOEN2_OFFSET) +#define LPC43_EMC_STATWAITRD2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITRD2_OFFSET) +#define LPC43_EMC_STATWAITPAGE2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITPAGE2_OFFSET) +#define LPC43_EMC_STATWAITWR2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWR2_OFFSET) +#define LPC43_EMC_STATWAITTURN2 (LPC43_EMC_BASE+LPC43_EMC_STATWAITTURN2_OFFSET) + +#define LPC43_EMC_STATCONFIG3 (LPC43_EMC_BASE+LPC43_EMC_STATCONFIG3_OFFSET) +#define LPC43_EMC_STATWAITWEN3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWEN3_OFFSET) +#define LPC43_EMC_STATWAITOEN3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITOEN3_OFFSET) +#define LPC43_EMC_STATWAITRD3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITRD3_OFFSET) +#define LPC43_EMC_STATWAITPAGE3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITPAGE3_OFFSET) +#define LPC43_EMC_STATWAITWR3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITWR3_OFFSET) +#define LPC43_EMC_STATWAITTURN3 (LPC43_EMC_BASE+LPC43_EMC_STATWAITTURN3_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* EMC Control register */ + +#define EMC_CONTROL_ENA (1 << 0) /* Bit 0: EMC Enable */ +#define EMC_CONTROL_ADDRMIRROR (1 << 1) /* Bit 1: Address mirror */ +#define EMC_CONTROL_LOWPOWER (1 << 2) /* Bit 2: Low-power mode */ + /* Bits 3-31: Reserved */ +/* EMC Status register */ +#define EMC__ +#define EMC_STATUS_BUSY (1 << 0) /* Bit 0: Busy */ +#define EMC_STATUS_WB (1 << 1) /* Bit 1: Write buffer status */ +#define EMC_CONFIG_SA (1 << 2) /* Bit 2: Self-refresh acknowledge */ + /* Bits 3-31: Reserved */ +/* EMC Configuration register */ + +#define EMC_CONFIG_EM (1 << 0) /* Bit 0: Endian mode */ + /* Bits 1-7: Reserved */ +#define EMC_CONFIG_CR (1 << 8) /* Bit 8: Clock Ratio */ + /* Bits 9-31: Reserved */ +/* Dynamic Memory Control register */ + +#define EMC_DYNCONTROL_ +#define EMC_DYNCONTROL_CE (1 << 0) /* Bit 0: Dynamic memory clock enable */ +#define EMC_DYNCONTROL_CS (1 << 1) /* Bit 1: Dynamic memory clock control */ +#define EMC_DYNCONTROL_SR (1 << 2) /* Bit 2: Self-refresh request, EMCSREFREQ */ + /* Bits 3-4: Reserved */ +#define EMC_DYNCONTROL_MMC (1 << 5) /* Bit 5: Memory clock control */ + /* Bit 6: Reserved */ +#define EMC_DYNCONTROL_SI_SHIFT (7) /* Bits 7-8: SDRAM initialization */ +#define EMC_DYNCONTROL_SI_MASK (3 << EMC_DYNCONTROL_SI_SHIFT) +# define EMC_DYNCONTROL_SI_NORMAL (0 << EMC_DYNCONTROL_SI_SHIFT) /* SDRAM NORMAL command */ +# define EMC_DYNCONTROL_SI_MODE (1 << EMC_DYNCONTROL_SI_SHIFT) /* SDRAM MODE command */ +# define EMC_DYNCONTROL_SI_PALL (2 << EMC_DYNCONTROL_SI_SHIFT) /* SDRAM PALL (precharge all) command */ +# define EMC_DYNCONTROL_SI_ MASK (3 << EMC_DYNCONTROL_SI_SHIFT) /* SDRAM NOP (no operation) command) */ + /* Bits 9-31: Reserved */ +/* Dynamic Memory Refresh Timer register */ + +#define EMC_DYNREFRESH_SHIFT (0) /* Bits 0-10: Refresh timer */ +#define EMC_DYNREFRESH_MASK (0x7ff << EMC_DYNREFRESH_SHIFT) + /* Bits 11-31: Reserved */ +/* Dynamic Memory Read Configuration register */ + +#define EMC_DYNREADCONFIG_SHIFT (0) /* Bits 0-1: Read data strategy */ +#define EMC_DYNREADCONFIG_MASK (3 << EMC_DYNREADCONFIG_SHIFT) +# define EMC_DYNREADCONFIG_0p5CCLK (1 << EMC_DYNREADCONFIG_SHIFT) /* Command delayed by 0.5 CCLK */ +# define EMC_DYNREADCONFIG_1p5CCLK (2 << EMC_DYNREADCONFIG_SHIFT) /* Command delayed by 1.5 CCLK */ +# define EMC_DYNREADCONFIG_2p5CCLK (3 << EMC_DYNREADCONFIG_SHIFT) /* Command delayed by 2.5 CCLK */ + /* Bits 2-31: Reserved */ +/* Dynamic Memory Precharge Command Period register */ + +#define EMC_DYNRP_SHIFT (0) /* Bits 0-3: Precharge command period */ +#define EMC_DYNRP_MASK (15 << EMC_DYNRP_SHIFT) +# define EMC_DYNRP(n) (((n)-1) << EMC_DYNRP_SHIFT) /* Delay n CCLK cycles */ + /* Bits 2-31: Reserved */ +/* Dynamic Memory Active to Precharge Command Period register */ + +#define EMC_DYNRAS_SHIFT (0) /* Bits 0-3: Active to precharge command period */ +#define EMC_DYNRAS_MASK (15 << EMC_DYNRAS_SHIFT) +# define EMC_DYNRAS(n) (((n)-1) << EMC_DYNRAS_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Self Refresh Exit Time register */ + +#define EMC_DYNSREX_SHIFT (0) /* Bits 0-3: Self-refresh exit time */ +#define EMC_DYNSREX_MASK (15 << EMC_DYNSREX_SHIFT) +# define EMC_DYNSREX(n) (((n)-1) << EMC_DYNSREX_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Last Data Out to Active Time register */ + +#define EMC_DYNAPR_SHIFT (0) /* Bits 0-3: Last-data-out to active command time */ +#define EMC_DYNAPR_MASK (15 << EMC_DYNAPR_SHIFT) +# define EMC_DYNAPR(n) (((n)-1) << EMC_DYNAPR_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Data In to Active Command Time register */ + +#define EMC_DYNDAL_SHIFT (0) /* Bits 0-3: Data-in to active command */ +#define EMC_DYNDAL_MASK (15 << EMC_DYNDAL_SHIFT) +# define EMC_DYNDAL(n) (((n)-1) << EMC_DYNDAL_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Write Recovery Time register */ + +#define EMC_DYNWR_SHIFT (0) /* Bits 0-3: Write recovery time */ +#define EMC_DYNWR_MASK (15 << EMC_DYNWR_SHIFT) +# define EMC_DYNWR(n) (((n)-1) << EMC_DYNWR_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Active to Active Command Period register */ + +#define EMC_DYNRC_SHIFT (0) /* Bits 0-4: Active to active command period */ +#define EMC_DYNRC_MASK (31 << EMC_DYNRC_SHIFT) +# define EMC_DYNRC(n) (((n)-1) << EMC_DYNRC_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Dynamic Memory Auto-refresh Period register */ + +#define EMC_DYNRFC_SHIFT (0) /* Bits 0-4: Auto-refresh period and + * auto-refresh to active command period */ +#define EMC_DYNRFC_MASK (31 << EMC_DYNRFC_SHIFT) +# define EMC_DYNRFC(n) (((n)-1) << EMC_DYNRFC_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Dynamic Memory Exit Self Refresh register */ + +#define EMC_DYNXSR_SHIFT (0) /* Bits 0-4: Exit self-refresh to active command time */ +#define EMC_DYNXSR_MASK (31 << EMC_DYNXSR_SHIFT) +# define EMC_DYNXSR(n) (((n)-1) << EMC_DYNXSR_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Dynamic Memory Active Bank A to Active Bank B Time register */ + +#define EMC_DYNRRD_SHIFT (0) /* Bits 0-3: Active bank A to active bank B latency */ +#define EMC_DYNRRD_MASK (15 << EMC_DYNRRD_SHIFT) +# define EMC_DYNRRD(n) (((n)-1) << EMC_DYNRRD_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Dynamic Memory Load Mode register to Active Command Time */ + +#define EMC_DYNMRD_SHIFT (0) /* Bits 0-3: Load mode register to active command time */ +#define EMC_DYNMRD_MASK (15 << EMC_DYNMRD_SHIFT) +# define EMC_DYNMRD(n) (((n)-1) << EMC_DYNMRD_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Static Memory Extended Wait register */ + +#define EMC_STATEXTWAIT_SHIFT (0) /* Bits 0-9: Extended wait time out */ +#define EMC_STATEXTWAIT_MASK (0x3ff << EMC_STATEXTWAIT_SHIFT) +# define EMC_STATEXTWAIT(n) (((n)-1) << EMC_STATEXTWAIT_SHIFT) /* Delay n CCLK cycles */ + /* Bits 10-31: Reserved */ +/* Dynamic Memory Configuration registers */ + /* Bits 0-2: Reserved */ +#define EMC_DYNCONFIG_MD_SHIFT (3) /* Bits 3-4: Memory device */ +#define EMC_DYNCONFIG_MD_MASK (3 << EMC_DYNCONFIG_MD_SHIFT) +# define EMC_DYNCONFIG_MD_SDRAM (0 << EMC_DYNCONFIG_MD_SHIFT) /* SDRAM (POR reset value) */ + /* Bits 5-6: Reserved */ +#define EMC_DYNCONFIG_AM0_SHIFT (7) /* Bits 7-12: AM0 Address mapping (see user manual) */ +#define EMC_DYNCONFIG_AM0_MASK (0x3f << EMC_DYNCONFIG_AM0_SHIFT) + /* Bit 13: Reserved */ +#define EMC_DYNCONFIG_AM1 (1 << 14) /* Bit 14: AM1 Address mapping (see user manual) */ + /* Bits 15-18: Reserved */ +#define EMC_DYNCONFIG_BENA (1 << 10) /* Bit 19: Buffer enable */ +#define EMC_DYNCONFIG_WP (1 << 20) /* Bit 20: Write protect. */ + /* Bits 21-31: Reserved */ +/* Dynamic Memory RAS & CAS Delay registers */ + +#define EMC_DYNRASCAS_RAS_SHIFT (0) /* Bits 0-1: RAS latency (active to read/write delay) */ +#define EMC_DYNRASCAS_RAS_MASK (3 << EMC_DYNRASCAS_RAS_SHIFT) +# define EMC_DYNRASCAS_RAS_1CCLK (1 << EMC_DYNRASCAS_RAS_SHIFT) /* One CCLK cycle */ +# define EMC_DYNRASCAS_RAS_2CCLK (2 << EMC_DYNRASCAS_RAS_SHIFT) /* Two CCLK cycles */ +# define EMC_DYNRASCAS_RAS_3CCLK (3 << EMC_DYNRASCAS_RAS_SHIFT) /* Three CCLK cycles (POR reset value) */ + /* Bits 2-7: Reserved */ +#define EMC_DYNRASCAS_CAS_SHIFT (8) /* Bits 8-9: CAS latency */ +#define EMC_DYNRASCAS_CAS_MASK (3 << EMC_DYNRASCAS_CAS_SHIFT) +# define EMC_DYNRASCAS_CAS_1CCLK (1 << EMC_DYNRASCAS_CAS_SHIFT) /* One CCLK cycle */ +# define EMC_DYNRASCAS_CAS_2CCLK (2 << EMC_DYNRASCAS_CAS_SHIFT) /* Two CCLK cycles */ +# define EMC_DYNRASCAS_CAS_3CCLK (3 << EMC_DYNRASCAS_CAS_SHIFT) /* Three CCLK cycles (POR reset value) */ + /* Bits 10-31: Reserved */ +/* Static Memory Configuration registers */ + +#define EMC_STATCONFIG_MW_SHIFT (0) /* Bits 0-1: Memory width */ +#define EMC_STATCONFIG_MW_MASK (3 << EMC_STATCONFIG_MW_SHIFT) +# define EMC_STATCONFIG_MW_8BITS (0 << EMC_STATCONFIG_MW_SHIFT) +# define EMC_STATCONFIG_MW_16BITS (1 << EMC_STATCONFIG_MW_SHIFT) +# define EMC_STATCONFIG_MW_32BITS (2 << EMC_STATCONFIG_MW_SHIFT) + /* Bit 2: Reserved */ +#define EMC_STATCONFIG_PM (1 << 3) /* Bit 3: Page mode */ + /* Bits 4-5: Reserved */ +#define EMC_STATCONFIG_PC (1 << 6) /* Bit 6: Chip select polarity */ +#define EMC_STATCONFIG_PB (1 << 7) /* Bit 7: Byte lane state */ +#define EMC_STATCONFIG_EW (1 << 8) /* Bit 8: Extended wait */ + /* Bits 9-18: Reserved */ +#define EMC_STATCONFIG_BENA (1 << 19) /* Bit 19: Buffer enable */ +#define EMC_STATCONFIG_WP (1 << 20) /* Bit 20: Write protect */ + /* Bits 21-31: Reserved */ +/* Static Memory Write Enable Delay registers */ + +#define EMC_STATWAITWEN_SHIFT (0) /* Bits 0-3: Wait write enable */ +#define EMC_STATWAITWEN_MASK (15 << EMC_STATWAITWEN_SHIFT) +# define EMC_STATWAITWEN(n) (((n)-1) << EMC_STATWAITWEN_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Static Memory Output Enable Delay registers */ + +#define EMC_STATWAITOEN_SHIFT (0) /* Bits 0-3: Wait output enable */ +#define EMC_STATWAITOEN_MASK (15 << EMC_STATWAITOEN_SHIFT) +# define EMC_STATWAITOEN(n) (((n)-1) << EMC_STATWAITOEN_SHIFT) /* Delay n CCLK cycles */ + /* Bits 4-31: Reserved */ +/* Static Memory Read Delay registers */ + +#define EMC_STATWAITRD_SHIFT (0) /* Bits 0-4: Non-page mode read wait states or + * asynchronous page mode read first access wait state */ +#define EMC_STATWAITRD_MASK (31 << EMC_STATWAITRD_SHIFT) +# define EMC_STATWAITRD(n) (((n)-1) << EMC_STATWAITRD_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Static Memory Page Mode Read Delay registers */ + +#define EMC_STATWAITPAGE_SHIFT (0) /* Bits 0-4: Asynchronous page mode read after the + * first read wait states */ +#define EMC_STATWAITPAGE_MASK (31 << EMC_STATWAITPAGE_SHIFT) +# define EMC_STATWAITPAGE(n) (((n)-1) << EMC_STATWAITPAGE_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Static Memory Write Delay registers */ + +#define EMC_STATWAITWR_SHIFT (0) /* Bits 0-4: Write wait states */ +#define EMC_STATWAITWR_MASK (31 << EMC_STATWAITWR_SHIFT) +# define EMC_STATWAITWR(n) (((n)-1) << EMC_STATWAITWR_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ +/* Static Memory Turn Round Delay registers */ + +#define EMC_STATWAITTURN_SHIFT (0) /* Bits 0-3: Bus turnaround cycles */ +#define EMC_STATWAITTURN_MASK (15 << EMC_STATWAITTURN_SHIFT) +# define EMC_STATWAITTURN(n) (((n)-1) << EMC_STATWAITTURN_SHIFT) /* Delay n CCLK cycles */ + /* Bits 5-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EMC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..6da125a6fee22b81277562c9892efb9eaa4022f6 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h @@ -0,0 +1,667 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_ethernet.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ +/* MAC Registers */ + +#define LPC43_ETH_MACCFG_OFFSET 0x0000 /* MAC configuration register */ +#define LPC43_ETH_MACFFLT_OFFSET 0x0004 /* MAC frame filter register */ +#define LPC43_ETH_MACHTHI_OFFSET 0x0008 /* MAC hash table high register */ +#define LPC43_ETH_MACHTLO_OFFSET 0x000c /* MAC hash table low register */ +#define LPC43_ETH_MACMIIA_OFFSET 0x0010 /* MAC MII address register */ +#define LPC43_ETH_MACMIID_OFFSET 0x0014 /* MAC MII data register */ +#define LPC43_ETH_MACFC_OFFSET 0x0018 /* MAC flow control register */ +#define LPC43_ETH_MACVLANT_OFFSET 0x001c /* MAC VLAN tag register */ +#define LPC43_ETH_MACDBG_OFFSET 0x0024 /* MAC debug register */ +#define LPC43_ETH_MACRWFFLT_OFFSET 0x0028 /* MAC remote wakeup frame filter reg */ +#define LPC43_ETH_MACPMTCS_OFFSET 0x002c /* MAC PMT control and status register */ +#define LPC43_ETH_MACINTR_OFFSET 0x0038 /* MAC interrupt status register */ +#define LPC43_ETH_MACIM_OFFSET 0x003c /* MAC interrupt mask register */ +#define LPC43_ETH_MACA0HI_OFFSET 0x0040 /* MAC address 0 high register */ +#define LPC43_ETH_MACA0LO_OFFSET 0x0044 /* MAC address 0 low register */ + +/* IEEE 1588 time stamp registers */ + +#define LPC43_ETH_TSCTRL_OFFSET 0x0700 /* Time stamp control register */ +#define LPC43_ETH_SSINCR_OFFSET 0x0704 /* Sub-second increment register */ +#define LPC43_ETH_SECONDS_OFFSET 0x0708 /* System time seconds register */ +#define LPC43_ETH_NANOSEC_OFFSET 0x070c /* System time nanoseconds register */ +#define LPC43_ETH_SECUPD_OFFSET 0x0710 /* System time seconds update register */ +#define LPC43_ETH_NSECUPD_OFFSET 0x0714 /* System time nanoseconds update register */ +#define LPC43_ETH_ADDEND_OFFSET 0x0718 /* Time stamp addend register */ +#define LPC43_ETH_TGTSEC_OFFSET 0x071c /* Target time seconds register */ +#define LPC43_ETH_TGTNSEC_OFFSET 0x0720 /* Target time nanoseconds register */ +#define LPC43_ETH_HIGHWORD_OFFSET 0x0724 /* System time higher word seconds register */ +#define LPC43_ETH_TSSTAT_OFFSET 0x0728 /* Time stamp status register */ + +/* DMA Registers */ + +#define LPC43_ETH_DMABMODE_OFFSET 0x1000 /* DMA bus mode register */ +#define LPC43_ETH_DMATXPD_OFFSET 0x1004 /* DMA transmit poll demand register */ +#define LPC43_ETH_DMARXPD_OFFSET 0x1008 /* DMA receive poll demand register */ +#define LPC43_ETH_DMARXDLA_OFFSET 0x100c /* DMA receive descriptor list address register */ +#define LPC43_ETH_DMATXDLA_OFFSET 0x1010 /* DMA transmit descriptor list address register */ +#define LPC43_ETH_DMASTAT_OFFSET 0x1014 /* DMA status register */ +#define LPC43_ETH_DMAOPMODE_OFFSET 0x1018 /* DMA operation mode register */ +#define LPC43_ETH_DMAINTEN_OFFSET 0x101c /* DMA interrupt enable register */ +#define LPC43_ETH_DMAMFBO_OFFSET 0x1020 /* DMA missed frame and buffer overflow counter register */ +#define LPC43_ETH_DMARXWDT_OFFSET 0x1024 /* DMA receive status watchdog timer register */ +#define LPC43_ETH_DMACHTXD_OFFSET 0x1048 /* DMA current host transmit descriptor register */ +#define LPC43_ETH_DMACHRXD_OFFSET 0x104c /* DMA current host receive descriptor register */ +#define LPC43_ETH_DMACHTXBUF_OFFSET 0x1050 /* DMA current host transmit buffer address register */ +#define LPC43_ETH_DMACHRXBUF_OFFSET 0x1054 /* DMA current host receive buffer address register */ + +/* Register Base Addresses **************************************************************************/ +/* MAC Registers */ + +#define LPC43_ETH_MACCR (LPC43_ETHERNET_BASE+LPC43_ETH_MACCFG_OFFSET) +#define LPC43_ETH_MACFFLT (LPC43_ETHERNET_BASE+LPC43_ETH_MACFFLT_OFFSET) +#define LPC43_ETH_MACHTHI (LPC43_ETHERNET_BASE+LPC43_ETH_MACHTHI_OFFSET) +#define LPC43_ETH_MACHTLO (LPC43_ETHERNET_BASE+LPC43_ETH_MACHTLO_OFFSET) +#define LPC43_ETH_MACMIIA (LPC43_ETHERNET_BASE+LPC43_ETH_MACMIIA_OFFSET) +#define LPC43_ETH_MACMIID (LPC43_ETHERNET_BASE+LPC43_ETH_MACMIID_OFFSET) +#define LPC43_ETH_MACFC (LPC43_ETHERNET_BASE+LPC43_ETH_MACFC_OFFSET) +#define LPC43_ETH_MACVLANT (LPC43_ETHERNET_BASE+LPC43_ETH_MACVLANT_OFFSET) +#define LPC43_ETH_MACDBG (LPC43_ETHERNET_BASE+LPC43_ETH_MACDBG_OFFSET) +#define LPC43_ETH_MACRWFFLT (LPC43_ETHERNET_BASE+LPC43_ETH_MACRWFFLT_OFFSET) +#define LPC43_ETH_MACPMTCS (LPC43_ETHERNET_BASE+LPC43_ETH_MACPMTCS_OFFSET) +#define LPC43_ETH_MACSR (LPC43_ETHERNET_BASE+LPC43_ETH_MACINTR_OFFSET) +#define LPC43_ETH_MACIM (LPC43_ETHERNET_BASE+LPC43_ETH_MACIM_OFFSET) +#define LPC43_ETH_MACA0HI (LPC43_ETHERNET_BASE+LPC43_ETH_MACA0HI_OFFSET) +#define LPC43_ETH_MACA0LO (LPC43_ETHERNET_BASE+LPC43_ETH_MACA0LO_OFFSET) + +/* IEEE 1588 time stamp registers */ + +#define LPC43_ETH_TSCTRL (LPC43_ETHERNET_BASE+LPC43_ETH_TSCTRL_OFFSET) +#define LPC43_ETH_SSINCR (LPC43_ETHERNET_BASE+LPC43_ETH_SSINCR_OFFSET) +#define LPC43_ETH_SECONDS (LPC43_ETHERNET_BASE+LPC43_ETH_SECONDS_OFFSET) +#define LPC43_ETH_NANOSEC (LPC43_ETHERNET_BASE+LPC43_ETH_NANOSEC_OFFSET) +#define LPC43_ETH_SECUPD (LPC43_ETHERNET_BASE+LPC43_ETH_SECUPD_OFFSET) +#define LPC43_ETH_NSECUPD (LPC43_ETHERNET_BASE+LPC43_ETH_NSECUPD_OFFSET) +#define LPC43_ETH_ADDEND (LPC43_ETHERNET_BASE+LPC43_ETH_ADDEND_OFFSET) +#define LPC43_ETH_TGTSEC (LPC43_ETHERNET_BASE+LPC43_ETH_TGTSEC_OFFSET) +#define LPC43_ETH_TGTNSEC (LPC43_ETHERNET_BASE+LPC43_ETH_TGTNSEC_OFFSET) +#define LPC43_ETH_HIGHWORD (LPC43_ETHERNET_BASE+LPC43_ETH_HIGHWORD_OFFSET) +#define LPC43_ETH_TSSTAT (LPC43_ETHERNET_BASE+LPC43_ETH_TSSTAT_OFFSET) + +/* DMA Registers */ + +#define LPC43_ETH_DMABMODE (LPC43_ETHERNET_BASE+LPC43_ETH_DMABMODE_OFFSET) +#define LPC43_ETH_DMATXPD (LPC43_ETHERNET_BASE+LPC43_ETH_DMATXPD_OFFSET) +#define LPC43_ETH_DMARXPD (LPC43_ETHERNET_BASE+LPC43_ETH_DMARXPD_OFFSET) +#define LPC43_ETH_DMARXDLA (LPC43_ETHERNET_BASE+LPC43_ETH_DMARXDLA_OFFSET) +#define LPC43_ETH_DMATXDLA (LPC43_ETHERNET_BASE+LPC43_ETH_DMATXDLA_OFFSET) +#define LPC43_ETH_DMASTAT (LPC43_ETHERNET_BASE+LPC43_ETH_DMASTAT_OFFSET) +#define LPC43_ETH_DMAOPMODE (LPC43_ETHERNET_BASE+LPC43_ETH_DMAOPMODE_OFFSET) +#define LPC43_ETH_DMAINTEN (LPC43_ETHERNET_BASE+LPC43_ETH_DMAINTEN_OFFSET) +#define LPC43_ETH_DMAMFBO (LPC43_ETHERNET_BASE+LPC43_ETH_DMAMFBO_OFFSET) +#define LPC43_ETH_DMARXWDT (LPC43_ETHERNET_BASE+LPC43_ETH_DMARXWDT_OFFSET) +#define LPC43_ETH_DMACHTXD (LPC43_ETHERNET_BASE+LPC43_ETH_DMACHTXD_OFFSET) +#define LPC43_ETH_DMACHRXD (LPC43_ETHERNET_BASE+LPC43_ETH_DMACHRXD_OFFSET) +#define LPC43_ETH_DMACHTXBUF (LPC43_ETHERNET_BASE+LPC43_ETH_DMACHTXBUF_OFFSET) +#define LPC43_ETH_DMACHRXBUF (LPC43_ETHERNET_BASE+LPC43_ETH_DMACHRXBUF_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ +/* MAC Registers */ + +/* MAC configuration register */ + /* Bits 0-1: Reserved */ +#define ETH_MACCFG_RE (1 << 2) /* Bit 2: Receiver enable */ +#define ETH_MACCFG_TE (1 << 3) /* Bit 3: Transmitter enable */ +#define ETH_MACCFG_DF (1 << 4) /* Bit 4: Deferral check */ +#define ETH_MACCFG_BL_SHIFT (5) /* Bits 5-6: Back-off limit */ +#define ETH_MACCFG_BL_MASK (3 << ETH_MACCFG_BL_SHIFT) +# define ETH_MACCFG_BL_10 (0 << ETH_MACCFG_BL_SHIFT) /* 00: k = min (n, 10) */ +# define ETH_MACCFG_BL_8 (1 << ETH_MACCFG_BL_SHIFT) /* 01: k = min (n, 8) */ +# define ETH_MACCFG_BL_4 (2 << ETH_MACCFG_BL_SHIFT) /* 10: k = min (n, 4) */ +# define ETH_MACCFG_BL_1 (3 << ETH_MACCFG_BL_SHIFT) /* 11: k = min (n, 1) */ +#define ETH_MACCFG_ACS (1 << 7) /* Bit 7: Automatic pad/CRC stripping */ +#define ETH_MACCFG_LUD (1 << 8) /* Bit 8: Link up/down */ +#define ETH_MACCFG_RD (1 << 9) /* Bit 9: Disable Retry */ + /* Bit 10: Reserved */ +#define ETH_MACCFG_DM (1 << 11) /* Bit 11: Duplex mode */ +#define ETH_MACCFG_LM (1 << 12) /* Bit 12: Loopback mode */ +#define ETH_MACCFG_DO (1 << 13) /* Bit 13: Disable receive own */ +#define ETH_MACCFG_FES (1 << 14) /* Bit 14: Fast Ethernet speed */ +#define ETH_MACCFG_PS (1 << 15) /* Bit 15: Port select */ +#define ETH_MACCFG_DCRS (1 << 16) /* Bit 16: Disable carrier sense during transmission */ +#define ETH_MACCFG_IFG_SHIFT (17) /* Bits 17-19: Interframe gap */ +#define ETH_MACCFG_IFG_MASK (7 << ETH_MACCFG_IFG_SHIFT) +# define ETH_MACCFG_IFG(n) ((12-((n) >> 3)) << ETH_MACCFG_IFG_SHIFT) /* n bit times, n=40,48,..96 */ +#define ETH_MACCFG_JE (1 << 20) /* Bit 20: Jumbo frame enable */ + /* Bit 21: Reserved */ +#define ETH_MACCFG_JD (1 << 22) /* Bit 22: Jabber disable */ +#define ETH_MACCFG_WD (1 << 23) /* Bit 23: Watchdog disable */ +#define ETH_MACCFG_CSTF (1 << 25) /* Bits 25: CRC stripping for Type frames */ + /* Bots 24-31: Reserved */ +/* MAC frame filter register */ + +#define ETH_MACFFLT_PR (1 << 0) /* Bit 0: Promiscuous mode */ +#define ETH_MACFFLT_HUC (1 << 1) /* Bit 1: Hash Unicast */ +#define ETH_MACFFLT_HMC (1 << 2) /* Bit 2: Hash Multicast */ +#define ETH_MACFFLT_DAIF (1 << 3) /* Bit 3: Destination address inverse filtering */ +#define ETH_MACFFLT_PM (1 << 4) /* Bit 4: Pass all multicast */ +#define ETH_MACFFLT_DBF (1 << 5) /* Bit 5: Disable Broadcast Frames */ +#define ETH_MACFFLT_PCF_SHIFT (6) /* Bits 6-7: Pass control frames */ +#define ETH_MACFFLT_PCF_MASK (3 << ETH_MACFFLT_PCF_SHIFT) +# define ETH_MACFFLT_PCF_NONE (0 << ETH_MACFFLT_PCF_SHIFT) /* Prevents all control frames */ +# define ETH_MACFFLT_PCF_PAUSE (1 << ETH_MACFFLT_PCF_SHIFT) /* Prevents all except Pause control frames */ +# define ETH_MACFFLT_PCF_ALL (2 << ETH_MACFFLT_PCF_SHIFT) /* Forwards all control frames */ +# define ETH_MACFFLT_PCF_FILTER (3 << ETH_MACFFLT_PCF_SHIFT) /* Forwards all that pass address filter */ + /* Bit 8-9: Reserved */ +#define ETH_MACFFLT_HPF (1 << 10) /* Bit 10: Hash or perfect filter */ + /* Bits 11-30: Reserved */ +#define ETH_MACFFLT_RA (1 << 31) /* Bit 31: Receive all */ + +/* MAC hash table high/low register (32-bit values) */ + +/* MAC MII address register */ + +#define ETH_MACMIIA_GB (1 << 0) /* Bit 0: MII busy */ +#define ETH_MACMIIA_WR (1 << 1) /* Bit 1: MII write */ +#define ETH_MACMIIA_CR_SHIFT (2) /* Bits 2-5: Clock range */ +#define ETH_MACMIIA_CR_MASK (15 << ETH_MACMIIA_CR_SHIFT) +# define ETH_MACMIIA_CR_60_100 (0 << ETH_MACMIIA_CR_SHIFT) /* 60-100 MHz CLK_M4_ETHERNET/42 */ +# define ETH_MACMIIA_CR_100_150 (1 << ETH_MACMIIA_CR_SHIFT) /* 100-150 MHz CLK_M4_ETHERNET/62 */ +# define ETH_MACMIIA_CR_20_35 (2 << ETH_MACMIIA_CR_SHIFT) /* 20-35 MHz CLK_M4_ETHERNET/16 */ +# define ETH_MACMIIA_CR_35_60 (3 << ETH_MACMIIA_CR_SHIFT) /* 35-60 MHz CLK_M4_ETHERNET/26 */ +# define ETH_MACMIIA_CR_150_250 (4 << ETH_MACMIIA_CR_SHIFT) /* 150-250 MHz CLK_M4_ETHERNET/102 */ +# define ETH_MACMIIA_CR_250_300 (5 << ETH_MACMIIA_CR_SHIFT) /* 250-300 MHz CLK_M4_ETHERNET/124 */ +# define ETH_MACMIIA_CR_DIV42 (8 << ETH_MACMIIA_CR_SHIFT) /* 60-100 MHz CLK_M4_ETHERNET/42 */ +# define ETH_MACMIIA_CR_DIV62 (9 << ETH_MACMIIA_CR_SHIFT) /* 100-150 MHz CLK_M4_ETHERNET/62 */ +# define ETH_MACMIIA_CR_DIV16 (10 << ETH_MACMIIA_CR_SHIFT) /* 20-35 MHz CLK_M4_ETHERNET/16 */ +# define ETH_MACMIIA_CR_DIV26 (11 << ETH_MACMIIA_CR_SHIFT) /* 35-60 MHz CLK_M4_ETHERNET/26 */ +# define ETH_MACMIIA_CR_DIV102 (12 << ETH_MACMIIA_CR_SHIFT) /* 150-168 MHz CLK_M4_ETHERNET/102 */ +# define ETH_MACMIIA_CR_DIV124 (13 << ETH_MACMIIA_CR_SHIFT) /* 250 - 300 MHz CLK_M4_ETHERNET/124 */ +# define ETH_MACMIIA_CR_DIV42_2 (14 << ETH_MACMIIA_CR_SHIFT) /* 60-100 MHz CLK_M4_ETHERNET/42 */ +# define ETH_MACMIIA_CR_DIV62_2 (15 << ETH_MACMIIA_CR_SHIFT) /* 100-150 MHz CLK_M4_ETHERNET/62 */ +#define ETH_MACMIIA_MR_SHIFT (6) /* Bits 6-10: MII register */ +#define ETH_MACMIIA_MR_MASK (31 << ETH_MACMIIA_MR_SHIFT) +#define ETH_MACMIIA_PA_SHIFT (11) /* Bits 11-15: PHY address */ +#define ETH_MACMIIA_PA_MASK (31 << ETH_MACMIIA_PA_SHIFT) + /* Bits 16-31: Reserved */ +/* MAC MII data register */ + +#define ETH_MACMIID_MASK (0xffff) + +/* MAC flow control register */ + +#define ETH_MACFC_FCB (1 << 0) /* Bit 0: Flow control busy/back pressure activate */ +#define ETH_MACFC_TFE (1 << 1) /* Bit 1: Transmit flow control enable */ +#define ETH_MACFC_RFE (1 << 2) /* Bit 2: Receive flow control enable */ +#define ETH_MACFC_UP (1 << 3) /* Bit 3: Unicast pause frame detect */ +#define ETH_MACFC_PLT_SHIFT (4) /* Bits 4-5: Pause low threshold */ +#define ETH_MACFC_PLT_MASK (3 << ETH_MACFC_PLT_SHIFT) +# define ETH_MACFC_PLT(n) ((n) << ETH_MACFC_PLT_SHIFT) + /* Bit 6: Reserved */ +#define ETH_MACFC_DZPQ (1 << 7) /* Bit 7: Disable Zero-Quanta Pause */ + /* Bits 8-15: Reserved */ +#define ETH_MACFC_PT_SHIFT (16) /* Bits 16-31: Pause time */ +#define ETH_MACFC_PT_MASK (0xffff << ETH_MACFC_PT_SHIFT) + +/* MAC VLAN tag register */ + +#define ETH_MACVLANT_VL_SHIFT (0) /* Bits 0-15: VLAN tag identifier (for receive frames) */ +#define ETH_MACVLANT_VL_MAS K (0xffff << ETH_MACVLANT_VLANTI_SHIFT) +#define ETH_MACVLANT_ETV (1 << 16) /* Bit 16: 12-bit VLAN tag comparison */ + +/* MAC debug register */ + +#define ETH_MACDBG_RXACTIVE (1 << 0) /* Bit 0: MAC MII receive protocol engine active */ +#define ETH_MACDBG_FS0_SHIFT (1) /* Bits 1-2: MAC small FIFO read / write controllers status */ +#define ETH_MACDBG_FS0_MASK (3 << ETH_MACDBG_FS0_SHIFT) +#define ETH_MACDBG_RFS1 (1 << 4) /* Bit 4: Rx FIFO write controller active */ +#define ETH_MACDBG_RFS_SHIFT (5) /* Bits 5-6: Rx FIFO read controller status */ +#define ETH_MACDBG_RFS_MASK (3 << ETH_MACDBG_RFS_SHIFT) +# define ETH_MACDBG_RFS_IDLE (0 << ETH_MACDBG_RFS_SHIFT) /* 00: IDLE state */ +# define ETH_MACDBG_RFS_RFRAME (1 << ETH_MACDBG_RFS_SHIFT) /* 01: Reading frame data */ +# define ETH_MACDBG_RFS_RSTATUS (2 << ETH_MACDBG_RFS_SHIFT) /* 10: Reading frame status (or time-stamp) */ +# define ETH_MACDBG_RFS_FLUSHING (3 << ETH_MACDBG_RFS_SHIFT) /* 11: Flushing the frame data and status */ + /* Bit 7: Reserved */ +#define ETH_MACDBG_RFFL_SHIFT (8) /* Bits 8-9: Rx FIFO fill level */ +#define ETH_MACDBG_RFFL_MASK (3 << ETH_MACDBG_RFFL_SHIFT) +# define ETH_MACDBG_RFFL_EMPTY (0 << ETH_MACDBG_RFFL_SHIFT) /* 00: RxFIFO empty */ +# define ETH_MACDBG_RFFL_DEACT (1 << ETH_MACDBG_RFFL_SHIFT) /* 01: RxFIFO fill-level below flow-control de-activate threshold */ +# define ETH_MACDBG_RFFL_ACTIV (2 << ETH_MACDBG_RFFL_SHIFT) /* 10: RxFIFO fill-level above flow-control activate threshold */ +# define ETH_MACDBG_RFFL_FULL (3 << ETH_MACDBG_RFFL_SHIFT) /* 11: RxFIFO full */ + /* Bits 10-15: Reserved */ +#define ETH_MACDBG_TXACTIVE (1 << 16) /* Bit 16: MAC MII transmit engine active */ +#define ETH_MACDBG_TXSTAT_SHIFT (17) /* Bits 17-18: State of the MAC transmit frame controller module */ +#define ETH_MACDBG_TXSTAT_MASK (3 << ETH_MACDBG_TXSTAT_SHIFT) +# define ETH_MACDBG_TXSTAT_IDLE (0 << ETH_MACDBG_TXSTAT_SHIFT) /* 00: Idle */ +# define ETH_MACDBG_TXSTAT_WAITING (1 << ETH_MACDBG_TXSTAT_SHIFT) /* 01: Waiting for Status of previous frame or IFG/backoff period to be over */ +# define ETH_MACDBG_TXSTAT_PAUSE (2 << ETH_MACDBG_TXSTAT_SHIFT) /* 10: Generating and transmitting a Pause control frame */ +# define ETH_MACDBG_TXSTAT_FRAME (3 << ETH_MACDBG_TXSTAT_SHIFT) /* 11: Transferring input frame for transmission */ +#define ETH_MACDBG_PAUSE (1 << 19) /* Bit 19: MAC transmitter in pause */ +#define ETH_MACDBG_TFRS_SHIFT (20) /* Bits 20-21: State of the TxFIFO read Controller */ +#define ETH_MACDBG_TFRS_MASK (3 << ETH_MACDBG_TFRS_SHIFT) +# define ETH_MACDBG_TFRS_IDLE (0 << ETH_MACDBG_TFRS_SHIFT) /* 00: Idle state */ +# define ETH_MACDBG_TFRS_READ (1 << ETH_MACDBG_TFRS_SHIFT) /* 01: Read state */ +# define ETH_MACDBG_TFRS_WAITING (2 << ETH_MACDBG_TFRS_SHIFT) /* 10: Waiting for TxStatus from MAC transmitter */ +# define ETH_MACDBG_TFRS_WRITING (3 << ETH_MACDBG_TFRS_SHIFT) /* 11: Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MACDBG_TFS1 (1 << 22) /* Bit 22: Tx FIFO write active */ + /* Bit 23: Reserved */ +#define ETH_MACDBG_TFNE (1 << 24) /* Bit 24: Tx FIFO not empty */ +#define ETH_MACDBG_TFF (1 << 25) /* Bit 25: Tx FIFO full */ + /* Bits 26-31: Reserved */ + +/* MAC remote wakeup frame filter reg. Provides 32-bit access to remote remote wake-up filters. */ + +/* MAC PMT control and status register */ + +#define ETH_MACPMTCS_PD (1 << 0) /* Bit 0: Power down */ +#define ETH_MACPMTCS_MPE (1 << 1) /* Bit 1: Magic Packet enable */ +#define ETH_MACPMTCS_WFE (1 << 2) /* Bit 2: Wakeup frame enable */ + /* Bits 3-4: Reserved */ +#define ETH_MACPMTCS_MPR (1 << 5) /* Bit 5: Magic packet received */ +#define ETH_MACPMTCS_WFR (1 << 6) /* Bit 6: Wakeup frame received */ +#define ETH_MACPMTCS_GU (1 << 9) /* Bit 9: Global unicast */ + /* Bits 10-30: Reserved */ +#define ETH_MACPMTCS_WFFRPR (1 << 31) /* Bit 31: Wake-up Frame Filter Register Pointer Reset */ + +/* MAC interrupt status register */ + /* Bits 0-2: Reserved */ +#define ETH_MACINTR_PMT (1 << 3) /* Bit 3: PMT status */ + /* Bits 4-8: Reserved */ +#define ETH_MACINTR_TS (1 << 9) /* Bit 9: Time stamp trigger status */ + /* Bits 10-31: Reserved */ +/* MAC interrupt mask register */ + /* Bits 0-2: Reserved */ +#define ETH_MACIM_PMTIM (1 << 3) /* Bit 3: PMT interrupt mask */ + /* Bits 4-8: Reserved */ +#define ETH_MACIM_TSIM (1 << 9) /* Bit 9: Time stamp interrupt mask */ + /* Bits 10-31: Reserved */ +#define ETH_MACIM_ALLINTS (ETH_MACIM_PMTIM|ETH_MACIM_TSIM) + +/* MAC address 0 high register */ + +#define ETH_MACA0HI_MACA0H_SHIFT (0) /* Bits 0-15: MAC address0 high [47:32] */ +#define ETH_MACA0HI_MACA0H_MASK (0xffff << ETH_MACA0HI_MACA0H_SHIFT) + /* Bits 16-30: Reserved */ +#define ETH_MACA0HI_MO (1 << 31) /* Bit 31: Always 1 */ + +/* MAC address 0 low register (MAC address0 low [31:0]) */ + +/* Time stamp control register */ + +#define ETH_TSCTRL_TSENA (1 << 0) /* Bit 0: Time stamp enable */ +#define ETH_TSCTRL_TSCFUPDT (1 << 1) /* Bit 1: Time stamp fine or coarse update */ +#define ETH_TSCTRL_TSINIT (1 << 2) /* Bit 2: Time stamp initialize */ +#define ETH_TSCTRL_TSUPDT (1 << 3) /* Bit 3: Time stamp up */ +#define ETH_TSCTRL_TSTRIG (1 << 4) /* Bit 4: Time stamp interrupt trigger enable */ +#define ETH_TSCTRL_TSADDREG (1 << 5) /* Bit 5: Addend reg update */ + /* Bits 6-7: Reserved */ +#define ETH_TSCTRL_TSENALL (1 << 8) /* Bit 8: Enable time stamp for all frames */ +#define ETH_TSCTRL_TSCTRLSSR (1 << 9) /* Bit 9: Time stamp digital or binary rollover control */ +#define ETH_TSCTRL_TSVER2ENA (1 << 10) /* Bit 10: Enable PTP packet snooping for version 2 format */ +#define ETH_TSCTRL_TSIPENA (1 << 11) /* Bit 11: Enable time stamp snapshot for ptp over ethernet frames */ +#define ETH_TSCTRL_TSIPV6ENA (1 << 12) /* Bit 12: Enable time stamp snapshot for IPv6 frames */ +#define ETH_TSCTRL_TSIPV4ENA (1 << 13) /* Bit 13: Enable time stamp snapshot for IPv4 frames */ +#define ETH_TSCTRL_TSEVNTENA (1 << 14) /* Bit 14: Enable time stamp snapshot for event messages */ +#define ETH_TSCTRL_TSMSTRENA (1 << 15) /* Bit 15: Enable snapshot for messages relevant to master */ +#define ETH_TSCTRL_TSCNT_SHIFT (16) /* Bits 16-17: Time stamp clock node type */ +#define ETH_TSCTRL_TSCNT_MASK (3 << ETH_TSCTRL_TSCNT_SHIFT) +# define ETH_TSCTRL_TSCNT_ORDINARY (0 << ETH_TSCTRL_TSCNT_SHIFT) /* 00: Ordinary clock */ +# define ETH_TSCTRL_TSCNT_BOUNDARY (1 << ETH_TSCTRL_TSCNT_SHIFT) /* 01: Boundary clock */ +# define ETH_TSCTRL_TSCNT_E2E (2 << ETH_TSCTRL_TSCNT_SHIFT) /* 10: End-to-end transparent clock */ +# define ETH_TSCTRL_TSCNT_P2P (3 << ETH_TSCTRL_TSCNT_SHIFT) /* 11: Peer-to-peer transparent clock */ +#define ETH_TSCTRL_TSENMACADDR (1 << 18) /* Bit 18: Enable MAC address for PTP frame filtering */ + /* Bits 19-31: Reserved */ +/* Sub-second increment register */ + +#define ETH_SSINCR_MASK (0xff) /* Bits 0-7: Sub-second increment value */ + /* Bits 8-31: Reserved */ +/* System time seconds register (32-bit) */ + +/* System time nanoseconds register */ + +#define ETH_NANOSEC_MASK (0x7fffffff) /* Bits 0-30: Time stamp sub seconds */ +#define ETH_NANOSEC_PSNT (1 << 31) /* Bit 31: Positive or negative time */ + +/* System time seconds update register (32-bit) */ + +/* System time nanoseconds update register */ + +#define ETH_NSECUPD_MASK (0x7fffffff) /* Bits 0-30: Time stamp sub seconds */ +#define ETH_NSECUPD_ADDSUB (1 << 31) /* Bit 31: Add or subtract time */ + +/* Time stamp addend register (32-bit) */ +/* Target time seconds register (32-bit) */ +/* Target time nanoseconds register (32-bit) */ + +#define ETH_TGTNSEC_MASK (0x7fffffff) /* Bits 0-30: Target time stamp low */ + /* Bit 31: Reserved */ +/* System time higher words seconds register */ + +#define ETH_HIGHWORD_MASK (0x0000ffff) /* Bits 0-15:Time stamp higher word */ +#define ETH_HIGHWORD_ADDSUB (1 << 31) /* Bit 31: Add or subtract time */ + +/* Time stamp status register */ + +#define ETH_TSSTAT_TSSOVF (1 << 0) /* Bit 0: Time stamp second overflow */ +#define ETH_TSSTAT_TSTARGT (1 << 1) /* Bit 1: Time stamp target time reached */ + /* Bits 2-31: Reserved */ +/* DMA Registers */ + +/* DMA bus mode register */ + +#define ETH_DMABMODE_SWR (1 << 0) /* Bit 0: Software reset */ +#define ETH_DMABMODE_DA (1 << 1) /* Bit 1: DMA arbitration scheme */ +#define ETH_DMABMODE_DSL_SHIFT (2) /* Bits 2-6: Descriptor skip length */ +#define ETH_DMABMODE_DSL_MASK (31 << ETH_DMABMODE_DSL_SHIFT) +# define ETH_DMABMODE_DSL(n) ((n) << ETH_DMABMODE_DSL_SHIFT) +#define ETH_DMABMODE_ATDS (1 << 7) /* Bit 7: Alternate descriptor size */ +#define ETH_DMABMODE_PBL_SHIFT (8) /* Bits 8-13: Programmable burst length */ +#define ETH_DMABMODE_PBL_MASK (0x3f << ETH_DMABMODE_PBL_SHIFT) +# define ETH_DMABMODE_PBL(n) ((n) << ETH_DMABMODE_PBL_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMODE_PR_SHIFT (14) /* Bits 14-15: Rx-to-Tx priority ratio */ +#define ETH_DMABMODE_PR_MASK (3 << ETH_DMABMODE_PR_SHIFT) +# define ETH_DMABMODE_PR_1TO1 (0 << ETH_DMABMODE_PR_SHIFT) /* 00: 1-to-1 */ +# define ETH_DMABMODE_PR_2TO1 (1 << ETH_DMABMODE_PR_SHIFT) /* 01: 2-to-1 */ +# define ETH_DMABMODE_PR_3TO1 (2 << ETH_DMABMODE_PR_SHIFT) /* 10: 3-to-1 */ +# define ETH_DMABMODE_PR_4TO1 (3 << ETH_DMABMODE_PR_SHIFT) /* 11: 4-to-1 */ +#define ETH_DMABMODE_FB (1 << 16) /* Bit 16: Fixed burst */ +#define ETH_DMABMODE_RPBL_SHIFT (17) /* Bits 17-22: RxDMA PBL */ +#define ETH_DMABMODE_RPBL_MASK (0x3f << ETH_DMABMODE_RPBL_SHIFT) +# define ETH_DMABMODE_RPBL(n) ((n) << ETH_DMABMODE_RPBL_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMODE_USP (1 << 23) /* Bit 23: Use separate PBL */ +#define ETH_DMABMODE_PBL8X (1 << 24) /* Bit 24: 8 x PBL mode */ +#define ETH_DMABMODE_AAL (1 << 25) /* Bit 25: Address-aligned beats */ +#define ETH_DMABMODE_MB (1 << 26) /* Bit 26: Mixed burst */ +#define ETH_DMABMODE_TXPR (1 << 27) /* Bit 27: Tx DMA has higher priority than Rx DMA */ + /* Bits 28-31: Reserved */ +/* DMA transmit poll demand register (32-bit) */ +/* DMA receive poll demand register (32-bit) */ +/* DMA receive descriptor list address register (32-bit address) */ +/* DMA transmit descriptor list address register (32-bit address) */ + +/* Interrupt bit definitions common between the DMA status register (DMASTAT) and + * the DMA interrupt enable register (DMAINTEN). + */ + +#define ETH_DMAINT_TI (1 << 0) /* Bit 0: Transmit interrupt */ +#define ETH_DMAINT_TPS (1 << 1) /* Bit 1: Transmit process stopped */ +#define ETH_DMAINT_TU (1 << 2) /* Bit 2: Transmit buffer unavailable */ +#define ETH_DMAINT_TJT (1 << 3) /* Bit 3: Transmit jabber timeout */ +#define ETH_DMAINT_OVF (1 << 4) /* Bit 4: Receive overflow */ +#define ETH_DMAINT_UNF (1 << 5) /* Bit 5: Transmit underflow */ +#define ETH_DMAINT_RI (1 << 6) /* Bit 6: Receive interrupt */ +#define ETH_DMAINT_RU (1 << 7) /* Bit 7: Receive buffer unavailable */ +#define ETH_DMAINT_RPS (1 << 8) /* Bit 8: Receive process stopped */ +#define ETH_DMAINT_RWT (1 << 9) /* Bit 9: Receive watchdog timeout */ +#define ETH_DMAINT_ETI (1 << 10) /* Bit 10: Early transmit interrupt */ + /* Bits 11-12: Reserved */ +#define ETH_DMAINT_FBI (1 << 13) /* Bit 13: Fatal bus error interrupt */ +#define ETH_DMAINT_ERI (1 << 14) /* Bit 14: Early receive interrupt */ +#define ETH_DMAINT_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */ +#define ETH_DMAINT_NIS (1 << 16) /* Bit 16: Normal interrupt summary */ + /* Bits 17-31: Reserved */ + +/* DMA operation mode register */ + /* Bit 0: Reserved */ +#define ETH_DMAOPMODE_SR (1 << 1) /* Bit 1: Start/stop receive */ +#define ETH_DMAOPMODE_OSF (1 << 2) /* Bit 2: Operate on second frame */ +#define ETH_DMAOPMODE_RTC_SHIFT (3) /* Bits 3-4: Receive threshold control */ +#define ETH_DMAOPMODE_RTC_MASK (3 << ETH_DMAOPMODE_RTC_SHIFT) +# define ETH_DMAOPMODE_RTC_64 (0 << ETH_DMAOPMODE_RTC_SHIFT) +# define ETH_DMAOPMODE_RTC_32 (1 << ETH_DMAOPMODE_RTC_SHIFT) +# define ETH_DMAOPMODE_RTC_96 (2 << ETH_DMAOPMODE_RTC_SHIFT) +# define ETH_DMAOPMODE_RTC_128 (3 << ETH_DMAOPMODE_RTC_SHIFT) + /* Bit 5: Reserved */ +#define ETH_DMAOPMODE_FUF (1 << 6) /* Bit 6: Forward undersized good frames */ +#define ETH_DMAOPMODE_FEF (1 << 7) /* Bit 7: Forward error frames */ + /* Bits 8-12: Reserved */ +#define ETH_DMAOPMODE_ST (1 << 13) /* Bit 13: Start/stop transmission */ +#define ETH_DMAOPMODE_TTC_SHIFT (14) /* Bits 14-16: Transmit threshold control */ +#define ETH_DMAOPMODE_TTC_MASK (7 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_64 (0 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_128 (1 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_192 (2 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_256 (3 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_40 (4 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_32 (5 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_24 (6 << ETH_DMAOPMODE_TTC_SHIFT) +# define ETH_DMAOPMODE_TTC_16 (7 << ETH_DMAOPMODE_TTC_SHIFT) + /* Bits 17-19: Reserved */ +#define ETH_DMAOPMODE_FTF (1 << 20) /* Bit 20: Flush transmit FIFO */ + /* Bits 21-23: Reserved */ +#define ETH_DMAOPMODE_DFF (1 << 24) /* Bit 24: Disable flushing of received frames */ + /* Bits 25-31: Reserved */ + +/* DMA missed frame and buffer overflow counter register */ + +#define ETH_DMAMFBO_FMC_SHIFT (0) /* Bits 0-15: Number of frames missed */ +#define ETH_DMAMFBO_FMC_MASK (0xffff << ETH_DMAMFBO_FMC_SHIFT) +#define ETH_DMAMFBO_OC (1 << 16) /* Bit 16: Overflow bit for missed frame counter */ +#define ETH_DMAMFBO_FMA_SHIFT (17) /* Bits 17-27: Number of frames missed by the application */ +#define ETH_DMAMFBO_FMA_MASK (0x7ff << ETH_DMAMFBO_FMA_SHIFT) +#define ETH_DMAMFBO_OF (1 << 28) /* Bit 28: Overflow bit for FIFO overflow counter */ + /* Bits 29-31: Reserved */ +/* DMA receive status watchdog timer register */ + +#define ETH_DMARXWDT_MASK (0xff) /* Bits 9-6: RI watchdog timeout */ + /* Bits 8-31: Reserved */ +/* DMA current host transmit descriptor register (32-bit address) */ +/* DMA current host receive descriptor register (32-bit address) */ +/* DMA current host transmit buffer address register (32-bit address) */ +/* DMA current host receive buffer address register (32-bit address) */ + +/* DMA Descriptors **********************************************************************************/ +/* TDES0: Transmit descriptor Word0 */ + +#define ETH_TDES0_DB (1 << 0) /* Bit 0: Deferred bit */ +#define ETH_TDES0_UF (1 << 1) /* Bit 1: Underflow error */ +#define ETH_TDES0_ED (1 << 2) /* Bit 2: Excessive deferral */ +#define ETH_TDES0_CC_SHIFT (3) /* Bits 3-6: Collision count */ +#define ETH_TDES0_CC_MASK (15 << ETH_TDES0_CC_SHIFT) +#define ETH_TDES0_VF (1 << 7) /* Bit 7: VLAN frame */ +#define ETH_TDES0_EC (1 << 8) /* Bit 8: Excessive collision */ +#define ETH_TDES0_LCL (1 << 9) /* Bit 9: Late collision */ +#define ETH_TDES0_NC (1 << 10) /* Bit 10: No carrier */ +#define ETH_TDES0_LCR (1 << 11) /* Bit 11: Loss of carrier */ +#define ETH_TDES0_IPE (1 << 12) /* Bit 12: IP payload error */ +#define ETH_TDES0_FF (1 << 13) /* Bit 13: Frame flushed */ +#define ETH_TDES0_JT (1 << 14) /* Bit 14: Jabber timeout */ +#define ETH_TDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_TDES0_IHE (1 << 16) /* Bit 16: IP header error */ +#define ETH_TDES0_TTSS (1 << 17) /* Bit 17: Transmit time stamp status */ + /* Bits 18-19: Reserved */ +#define ETH_TDES0_TCH (1 << 20) /* Bit 20: Second address chained */ +#define ETH_TDES0_TER (1 << 21) /* Bit 21: Transmit end of ring */ + /* Bits 22-24: Reserved */ +#define ETH_TDES0_TTSE (1 << 25) /* Bit 25: Transmit time stamp enable */ +#define ETH_TDES0_DP (1 << 26) /* Bit 26: Disable pad */ +#define ETH_TDES0_DC (1 << 27) /* Bit 27: Disable CRC */ +#define ETH_TDES0_FS (1 << 28) /* Bit 28: First segment */ +#define ETH_TDES0_LS (1 << 29) /* Bit 29: Last segment */ +#define ETH_TDES0_IC (1 << 30) /* Bit 30: Interrupt on completion */ +#define ETH_TDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* TDES1: Transmit descriptor Word1 */ + +#define ETH_TDES1_TBS1_SHIFT (0) /* Bits 0-12: Transmit buffer 1 size */ +#define ETH_TDES1_TBS1_MASK (0x1fff << ETH_TDES1_TBS1_SHIFT) +#define ETH_TDES1_TBS2_SHIFT (16) /* Bits 16-28: Transmit buffer 2 size */ +#define ETH_TDES1_TBS2_MASK (0x1fff << ETH_TDES1_TBS2_SHIFT) + +/* TDES2: Transmit descriptor Word2 (32-bit address) */ +/* TDES3: Transmit descriptor Word3 (32-bit address) */ +/* TDES6: Transmit descriptor Word6 (32-bit time stamp) */ +/* TDES7: Transmit descriptor Word7 (32-bit time stamp) */ + +/* RDES0: Receive descriptor Word0 */ + +#define ETH_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#define ETH_RDES0_CE (1 << 1) /* Bit 1: CRC error */ +#define ETH_RDES0_DRE (1 << 2) /* Bit 2: Dribble bit error */ +#define ETH_RDES0_RE (1 << 3) /* Bit 3: Receive error */ +#define ETH_RDES0_RWT (1 << 4) /* Bit 4: Receive watchdog timeout */ +#define ETH_RDES0_FT (1 << 5) /* Bit 5: Frame type */ +#define ETH_RDES0_LC (1 << 6) /* Bit 6: Late collision */ +#define ETH_RDES0_TSA (1 << 7) /* Bit 7: Time stamp available */ +#define ETH_RDES0_LS (1 << 8) /* Bit 8: Last descriptor */ +#define ETH_RDES0_FS (1 << 9) /* Bit 9: First descriptor */ +#define ETH_RDES0_VLAN (1 << 10) /* Bit 10: VLAN tag */ +#define ETH_RDES0_OE (1 << 11) /* Bit 11: Overflow error */ +#define ETH_RDES0_LE (1 << 12) /* Bit 12: Length error */ +#define ETH_RDES0_SAF (1 << 13) /* Bit 13: Source address filter fail */ +#define ETH_RDES0_DS (1 << 14) /* Bit 14: Descriptor error */ +#define ETH_RDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_RDES0_FL_SHIFT (16) /* Bits 16-29: Frame length */ +#define ETH_RDES0_FL_MASK (0x3fff << ETH_RDES0_FL_SHIFT) +#define ETH_RDES0_AFM (1 << 30) /* Bit 30: Destination address filter fail */ +#define ETH_RDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* RDES1: Receive descriptor Word1 */ + +#define ETH_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ +#define ETH_RDES1_RBS1_MASK (0x1fff << ETH_RDES1_RBS1_SHIFT) + /* Bit 13: Reserved */ +#define ETH_RDES1_RCH (1 << 14) /* Bit 14: Second address chained */ +#define ETH_RDES1_RER (1 << 15) /* Bit 15: Receive end of ring */ +#define ETH_RDES1_RBS2_SHIFT (16) /* Bits 16-28: Receive buffer 2 size */ +#define ETH_RDES1_RBS2_MASK (0x1fff << ETH_RDES1_RBS2_SHIFT) + /* Bit 29-31: Reserved */ +/* RDES2: Receive descriptor Word2 (32-bit address) */ +/* RDES3: Receive descriptor Word3 (32-bit address) */ + +/* RDES4: Receive descriptor Word4 */ + + /* Bits 0-5: Reserved */ +#define ETH_RDES4_IPV4 (1 << 6) /* Bit 6: IPv4 packet received */ +#define ETH_RDES4_IPV6 (1 << 7) /* Bit 7: IPv6 packet received */ +#define ETH_RDES4_MT_SHIFT (8) /* Bits 8-11: Message type */ +#define ETH_RDES4_MT_MASK (15 << ETH_RDES4_MT_SHIFT) +# define ETH_RDES4_MT_NONE (0 << ETH_RDES4_MT_SHIFT) /* No PTP message received */ +# define ETH_RDES4_MT_SYNC (1 << ETH_RDES4_MT_SHIFT) /* SYNC (all clock types) */ +# define ETH_RDES4_MT_FOLLOWUP (2 << ETH_RDES4_MT_SHIFT) /* Follow_Up (all clock types) */ +# define ETH_RDES4_MT_DELAYREQ (3 << ETH_RDES4_MT_SHIFT) /* Delay_Req (all clock types) */ +# define ETH_RDES4_MT_DELAYRESP (4 << ETH_RDES4_MT_SHIFT) /* Delay_Resp (all clock types) */ +# define ETH_RDES4_MT_PDELREQAM (5 << ETH_RDES4_MT_SHIFT) /* Pdelay_Req (in peer-to-peer + * transparent clock) */ +# define ETH_RDES4_MT_PDELREQMM (6 << ETH_RDES4_MT_SHIFT) /* Pdelay_Resp (in peer-to-peer + * transparent clock) */ +# define ETH_RDES4_MT_PDELRESFUS (7 << ETH_RDES4_MT_SHIFT) /* Pdelay_Resp_Follow_Up (in + * peer-to-peer transparent clock) */ +# define ETH_RDES4_MT_ANNOUNCE (8 << ETH_RDES4_MT_SHIFT) /* Announce */ +# define ETH_RDES4_MT_MANAGEMENT (9 << ETH_RDES4_MT_SHIFT) /* Management */ +# define ETH_RDES4_MT_SIGNALING (10 << ETH_RDES4_MT_SHIFT) /* Signaling */ +# define ETH_RDES4_MT_PTP (15 << ETH_RDES4_MT_SHIFT) /* PTP packet with Reserved message type */ +#define ETH_RDES4_PTPTYPE (1 << 12) /* Bit 12: PTP frame type */ +#define ETH_RDES4_PTPVERSION (1 << 13) /* Bit 13: PTP version */ + /* Bits 14-31: Reserved */ + +/* RDES5: Receive descriptor Word5 - Reserved */ +/* RDES6: Receive descriptor Word6 (32-bit time stamp) */ +/* RDES7: Receive descriptor Word7 (32-bit time stamp) */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Ethernet TX DMA Descriptor. Descriptor size can be 4 DWORDS (16 bytes) or 8 DWORDS (32 bytes) + * depending on the setting of the ATDS bit in the DMA Bus Mode register. + */ + +struct eth_txdesc_s +{ + /* Normal DMA descriptor words */ + + volatile uint32_t tdes0; /* Status */ + volatile uint32_t tdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t tdes2; /* Buffer1 address pointer */ + volatile uint32_t tdes3; /* Buffer2 or next descriptor address pointer */ + + /* Alternate DMA descriptor with time stamp */ + +#ifdef CONFIG_LPC43_ETH_ALTDESC + volatile uint32_t tdes4; /* Reserved */ + volatile uint32_t tdes5; /* Reserved */ + volatile uint32_t tdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t tdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/* Ethernet RX DMA Descriptor. Descriptor size can be 4 DWORDS (16 bytes) or 8 DWORDS (32 bytes) + * depending on the setting of the ATDS bit in the DMA Bus Mode register. + */ + +struct eth_rxdesc_s +{ + volatile uint32_t rdes0; /* Status */ + volatile uint32_t rdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t rdes2; /* Buffer1 address pointer */ + volatile uint32_t rdes3; /* Buffer2 or next descriptor address pointer */ + + /* Alternate DMA descriptor with time stamp and PTP support */ + +#ifdef CONFIG_LPC43_ETH_ALTDESC + volatile uint32_t rdes4; /* Extended status for PTP receive descriptor */ + volatile uint32_t rdes5; /* Reserved */ + volatile uint32_t rdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t rdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H */ + diff --git a/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h b/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h new file mode 100644 index 0000000000000000000000000000000000000000..a12112ecedf428fff04211e1fe5a78183353bf96 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_evntmntr.h @@ -0,0 +1,150 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_eventmntr.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTMNTR_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTMNTR_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_EMR_CONTROL_OFFSET 0x0004 /* Event Monitor/Recorder Control register */ +#define LPC43_EMR_STATUS_OFFSET 0x0000 /* Event Monitor/Recorder Status register */ +#define LPC43_EMR_COUNTERS_OFFSET 0x0008 /* Event Monitor/Recorder Counters register */ + +#define LPC43_EMR_FIRSTSTAMP_OFFSET(n) (0x0010 + ((n) << 2)) +#define LPC43_EMR_FIRSTSTAMP0_OFFSET 0x0010 /* Event Monitor/Recorder First Stamp register Ch0 */ +#define LPC43_EMR_FIRSTSTAMP1_OFFSET 0x0014 /* Event Monitor/Recorder First Stamp register Ch1 */ +#define LPC43_EMR_FIRSTSTAMP2_OFFSET 0x0018 /* Event Monitor/Recorder First Stamp register Ch2 */ + +#define LPC43_EMR_LASTSTAMP_OFFSET(n) (0x0020 + ((n) << 2)) +#define LPC43_EMR_LASTSTAMP0_OFFSET 0x0020 /* Event Monitor/Recorder Last Stamp register Ch0 */ +#define LPC43_EMR_LASTSTAMP1_OFFSET 0x0024 /* Event Monitor/Recorder Last Stamp register Ch1 */ +#define LPC43_EMR_LASTSTAMP2_OFFSET 0x0028 /* Event Monitor/Recorder Last Stamp register Ch2 */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_EMR_CONTROL (LPC43_EVNTMNTR_BASE+LPC43_EMR_CONTROL_OFFSET) +#define LPC43_EMR_STATUS (LPC43_EVNTMNTR_BASE+LPC43_EMR_STATUS_OFFSET) +#define LPC43_EMR_COUNTERS (LPC43_EVNTMNTR_BASE+LPC43_EMR_COUNTERS_OFFSET) + +#define LPC43_EMR_FIRSTSTAMP(n) (LPC43_EVNTMNTR_BASE+LPC43_EMR_FIRSTSTAMP_OFFSET(n)) +#define LPC43_EMR_FIRSTSTAMP0 (LPC43_EVNTMNTR_BASE+LPC43_EMR_FIRSTSTAMP0_OFFSET) +#define LPC43_EMR_FIRSTSTAMP1 (LPC43_EVNTMNTR_BASE+LPC43_EMR_FIRSTSTAMP1_OFFSET) +#define LPC43_EMR_FIRSTSTAMP2 (LPC43_EVNTMNTR_BASE+LPC43_EMR_FIRSTSTAMP2_OFFSET) + +#define LPC43_EMR_LASTSTAMP(n) (LPC43_EVNTMNTR_BASE+LPC43_EMR_LASTSTAMP_OFFSET(n)) +#define LPC43_EMR_LASTSTAMP0 (LPC43_EVNTMNTR_BASE+LPC43_EMR_LASTSTAMP0_OFFSET) +#define LPC43_EMR_LASTSTAMP1 (LPC43_EVNTMNTR_BASE+LPC43_EMR_LASTSTAMP1_OFFSET) +#define LPC43_EMR_LASTSTAMP2 (LPC43_EVNTMNTR_BASE+LPC43_EMR_LASTSTAMP2_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Event Monitor/Recorder Control register */ + +#define EMR_CONTROL_INTWAKE_EN0 (1 << 0) /* Bit 0: Interrupt and wakeup enable Ch0 */ +#define EMR_CONTROL_GPCLEAR_EN0 (1 << 1) /* Bit 1: Enables auto clearing of RTC GP regs Ch0 */ +#define EMR_CONTROL_POL0 (1 << 2) /* Bit 2: Selects polarity of input pin WAKEUP0 */ +#define EMR_CONTROL_EV0_INPUT_EN (1 << 3) /* Bit 3: Event enable control Ch0 */ + /* Bits 4-9: Reserved */ +#define EMR_CONTROL_INTWAKE_EN1 (1 << 10) /* Bit 10: Interrupt and wakeup enable Ch1 */ +#define EMR_CONTROL_GPCLEAR_EN1 (1 << 11) /* Bit 11: Enables auto clearing the RTC GP regs Ch1 */ +#define EMR_CONTROL_POL1 (1 << 12) /* Bit 12: Selects polarity of input pin WAKEUP1 */ +#define EMR_CONTROL_EV1_INPUT_EN (1 << 13) /* Bit 13: Event enable control Ch1 */ + /* Bits 14-19: Reserved */ +#define EMR_CONTROL_INTWAKE_EN2 (1 << 20) /* Bit 20: Interrupt and wakeup enable Ch2 */ +#define EMR_CONTROL_GPCLEAR_EN2 (1 << 21) /* Bit 21: Enables auto clearing of RTC GP regs Ch2 */ +#define EMR_CONTROL_POL2 (1 << 22) /* Bit 22: Selects polarity of input pin WAKEUP2 */ +#define EMR_CONTROL_EV2_INPUT_EN (1 << 23) /* Bit 23: Event enable control Ch2 */ + /* Bits 24-29: Reserved */ +#define EMR_CONTROL_ERMODE_SHIFT (30) /* Bits 30-31: Enable Event Monitor/Recorder */ +#define EMR_CONTROL_ERMODE_MASK (3 << EMR_CONTROL_ERMODE_SHIFT) +# define EMR_CONTROL_ERMODE_DISABLE (0 << EMR_CONTROL_ERMODE_SHIFT) /* Disable Event Monitor/Recorder clocks */ +# define EMR_CONTROL_ERMODE_16Hz (1 << EMR_CONTROL_ERMODE_SHIFT) /* 16 Hz sample clock */ +# define EMR_CONTROL_ERMODE_64Hz (2 << EMR_CONTROL_ERMODE_SHIFT) /* 64 Hz sample clock */ +# define EMR_CONTROL_ERMODE_1KHz (3 << EMR_CONTROL_ERMODE_SHIFT) /* 1 kHz sample clock */ + +/* Event Monitor/Recorder Status register */ + +#define EMR_STATUS_EV0 (1 << 0) /* Bit 0: Channel0 event flag (WAKEUP0 pin) */ +#define EMR_STATUS_EV1 (1 << 1) /* Bit 1: Channel1 Event flag (WAKEUP1 pin) */ +#define EMR_STATUS_EV2 (1 << 2) /* Bit 2: Channel2 Event flag (WAKEUP2 pin) */ +#define EMR_STATUS_GPCLR (1 << 3) /* Bit 3: General purpose register asynchronous clear flag */ + /* Bits 4-30: Reserved */ +#define EMR_STATUS_WAKEUP (1 << 31) /* Bit 31: WAKEUP Interrupt/wakeup request flag */ + +/* Event Monitor/Recorder Counters register */ + +#define EMR_COUNTERS_COUNTER0_SHIFT (0) /* Bits 0-2: Value of the counter for Event 0 */ +#define EMR_COUNTERS_COUNTER0_MASK (7 << EMR_COUNTERS_COUNTER0_SHIFT) + /* Bits 3-7: Reserved */ +#define EMR_COUNTERS_COUNTER1_SHIFT (8) /* Bits 8-10: Value of the counter for event 1 */ +#define EMR_COUNTERS_COUNTER1_MASK (8 << EMR_COUNTERS_COUNTER1_SHIFT) + /* Bits 11-15: Reserved */ +#define EMR_COUNTERS_COUNTER2_SHIFT (16) /* Bits 16-18: Value of the counter for event 2 */ +#define EMR_COUNTERS_COUNTER2_MASK (7 << EMR_COUNTERS_COUNTER2_SHIFT) + /* Bits 19-31: Reserved */ +/* Event Monitor/Recorder First/Last Stamp registers */ + +#define EMR_STAMP_SEC_SHIFT (0) /* Bits 0-5: Seconds value 0-59 */ +#define EMR_STAMP_SEC_MASK (63 << EMR_STAMP_SEC_SHIFT) +#define EMR_STAMP_MIN_SHIFT (6) /* Bits 6-11: Minutes value 0-59 */ +#define EMR_STAMP_MIN_MASK (63 << EMR_STAMP_MIN_SHIFT) +#define EMR_STAMP_HOUR_SHIFT (12) /* Bits 12-16: Hours value 0-23 */ +#define EMR_STAMP_HOUR_MASK (31 << EMR_STAMP_HOUR_SHIFT) +#define EMR_STAMP_DOY_SHIFT (17) /* Bits 17-25: Day of Year value1-366 */ +#define EMR_STAMP_DOY_MASK (511 << EMR_STAMP_DOY_SHIFT) + /* Bits 26-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTMNTR_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h b/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h new file mode 100644 index 0000000000000000000000000000000000000000..1287dfd875718c71e4eb2b659baeedb1a84c3bde --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h @@ -0,0 +1,159 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_evntrtr.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTRTR_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTRTR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_EVNTRTR_HILO_OFFSET 0x0000 /* Level configuration register */ +#define LPC43_EVNTRTR_EDGE_OFFSET 0x0004 /* Edge configuration */ + +#define LPC43_EVNTRTR_CLREN_OFFSET 0x0fd8 /* Clear event enable register */ +#define LPC43_EVNTRTR_SETEN_OFFSET 0x0fdc /* Set event enable register */ +#define LPC43_EVNTRTR_STATUS_OFFSET 0x0fe0 /* Event Status register */ +#define LPC43_EVNTRTR_ENABLE_OFFSET 0x0fe4 /* Event Enable register */ +#define LPC43_EVNTRTR_CLRSTAT_OFFSET 0x0fe8 /* Clear event status register */ +#define LPC43_EVNTRTR_SETSTAT_OFFSET 0x0fec /* Set event status register */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_EVNTRTR_HILO (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_HILO_OFFSET) +#define LPC43_EVNTRTR_EDGE (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_EDGE_OFFSET) + +#define LPC43_EVNTRTR_CLREN (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_CLREN_OFFSET) +#define LPC43_EVNTRTR_SETEN (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_SETEN_OFFSET) +#define LPC43_EVNTRTR_STATUS (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_STATUS_OFFSET) +#define LPC43_EVNTRTR_ENABLE (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_ENABLE_OFFSET) +#define LPC43_EVNTRTR_CLRSTAT (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_CLRSTAT_OFFSET) +#define LPC43_EVNTRTR_SETSTAT (LPC43_EVNTRTR_BASE+LPC43_EVNTRTR_SETSTAT_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Event router inputs. Bit settings common to all registers */ + +#define EVNTRTR_SOURCE_WAKEUP0 0 /* WAKEUP0 pin */ +#define EVNTRTR_SOURCE_WAKEUP1 1 /* WAKEUP1 pin */ +#define EVNTRTR_SOURCE_WAKEUP2 2 /* WAKEUP2 pin */ +#define EVNTRTR_SOURCE_WAKEUP3 3 /* WAKEUP3 pin */ +#define EVNTRTR_SOURCE_ATIMER 4 /* Alarm timer interrupt */ +#define EVNTRTR_SOURCE_RTC 5 /* RTC interrupt and event recorder/monitor interrupt */ +#define EVNTRTR_SOURCE_BOD 6 /* BOD trip level 1interrupt */ +#define EVNTRTR_SOURCE_WWDT 7 /* WWDT interrupt */ +#define EVNTRTR_SOURCE_ETHERNET 8 /* Ethernet wake-up packet indicator */ +#define EVNTRTR_SOURCE_USB0 9 /* USB0 wake-up request signal */ +#define EVNTRTR_SOURCE_USB1 10 /* USB1 AHB_NEED_CLK signal */ +#define EVNTRTR_SOURCE_SDMMC 11 /* SD/MMC interrupt */ +#define EVNTRTR_SOURCE_CAN 12 /* C_CAN0 | C_CAN1 interrupt */ +#define EVNTRTR_SOURCE_TIM2 13 /* Combined timer output 2 (SCT output 2 | TIMER0 Ch2) */ +#define EVNTRTR_SOURCE_TIM6 14 /* Combined timer output 6 (SCT output 6 | TIMER1 Ch2) */ +#define EVNTRTR_SOURCE_QEI 15 /* QEI interrupt */ +#define EVNTRTR_SOURCE_TIM14 16 /* Combined timer output 14 (SCT output 14 | TIMER3 Ch2) */ + /* 17-18: Reserved */ +#define EVNTRTR_SOURCE_RESET 19 /* Reset event */ + +#define EVNTRTR_WAKEUP0 (1 << EVNTRTR_SOURCE_WAKEUP0) +#define EVNTRTR_WAKEUP1 (1 << EVNTRTR_SOURCE_WAKEUP1) +#define EVNTRTR_WAKEUP2 (1 << EVNTRTR_SOURCE_WAKEUP2) +#define EVNTRTR_WAKEUP3 (1 << EVNTRTR_SOURCE_WAKEUP3) +#define EVNTRTR_ATIMER (1 << EVNTRTR_SOURCE_ATIMER) +#define EVNTRTR_RTC (1 << EVNTRTR_SOURCE_RTC) +#define EVNTRTR_BOD (1 << EVNTRTR_SOURCE_BOD) +#define EVNTRTR_WWDT (1 << EVNTRTR_SOURCE_WWDT) +#define EVNTRTR_ETH (1 << EVNTRTR_SOURCE_ETHERNET) +#define EVNTRTR_USB0 (1 << EVNTRTR_SOURCE_USB0) +#define EVNTRTR_USB1 (1 << EVNTRTR_SOURCE_USB1) +#define EVNTRTR_SDMMC (1 << EVNTRTR_SOURCE_SDMMC) +#define EVNTRTR_CAN (1 << EVNTRTR_SOURCE_CAN) +#define EVNTRTR_TIM2 (1 << EVNTRTR_SOURCE_TIM2) +#define EVNTRTR_TIM6 (1 << EVNTRTR_SOURCE_TIM6) +#define EVNTRTR_QEI (1 << EVNTRTR_SOURCE_QEI) +#define EVNTRTR_TIM14 (1 << EVNTRTR_SOURCE_TIM14) +#define EVNTRTR_RESET (1 << EVNTRTR_SOURCE_RESET) + +/* Level configuration register */ + +#define EVNTRTR_HILO(n) (1 << (n)) + +/* Edge configuration */ + +#define EVNTRTR_EDGE(n) (1 << (n)) + +/* Clear event enable register */ + +#define EVNTRTR_CLREN(n) (1 << (n)) + +/* Set event enable register */ + +#define EVNTRTR_SETEN(n) (1 << (n)) + +/* Event Status register */ + +#define EVNTRTR_STATUS(n) (1 << (n)) + +/* Event Enable register */ + +#define EVNTRTR_ENABLE(n) (1 << (n)) + +/* Clear event status register */ + +#define EVNTRTR_CLRSTAT(n) (1 << (n)) + +/* Set event status register */ + +#define EVNTRTR_SETSTAT(n) (1 << (n)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_EVNTRTR_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_flash.h b/arch/arm/src/lpc43xx/chip/lpc43_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..4f99484dac765b382624254308bd8161f377ff43 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_flash.h @@ -0,0 +1,187 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_flash.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_FLASH_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* The AES is controlled through a set of simple API calls located in the LPC43xx + * ROM. This value holds the pointer to the AES driver table. + */ + +#define LPC43_ROM_IAP_DRIVER_TABLE LPC43_ROM_DRIVER_TABLE0 + +#define IAP_LOCATION *(volatile unsigned int *)LPC43_ROM_IAP_DRIVER_TABLE; + +/* General usage: + * + * Declare a function pointer in your code like: + * + * iap_t iap = (iap_t)IAP_LOCATION; + * + * Then call the IAP using the function pointe like: + * + * unsigned long command[6]; + * unsigned long result[5]; + * ... + * iap(command, result); + */ + +/* IAP Commands + * + * See tables 1042-1053 in the "LPC43xx User Manual" (UM10503), Rev. 1.2, 8 June + * 2012, NXP for definitions descriptions of each IAP command. + */ + +#define IAP_INIT 49 /* Initialization */ +#define IAP_WRITE_PREPARE 50 /* Prepare sectors for write operation */ +#define IAP_WRITE 51 /* Copy RAM to Flash */ +#define IAP_ERASE_SECTOR 52 /* Erase sectors */ +#define IAP_BLANK_CHECK 53 /* Blank check sectors */ +#define IAP_PART_ID 54 /* Read part ID */ +#define IAP_BOOT_VERSION 55 /* Read Boot Code version */ +#define IAP_SERIAL_NUMBER 58 /* Read device serial number */ +#define IAP_COMPARE 56 /* Compare */ +#define IAP_REINVOKE 57 /* Reinvoke ISP */ +#define IAP_ERASE_PAGE 59 /* Erase page */ +#define IAP_SET_BANK 60 /* Set active boot flash bank */ + +/* ISP/IAP return codes */ + +/* Command is executed successfully. Sent by ISP handler only when command given by + * the host has been completely and successfully executed. + */ + +#define CMD_SUCCESS 0 + +/* Invalid command */ + +#define INVALID_COMMAND + +/* Source address is not on word boundary. */ + +#define SRC_ADDR_ERROR 2 + +/* Destination address not on word or 256 byte boundary. */ + +#define DST_ADDR_ERROR 3 + +/* Source address is not mapped in the memory map. Count value is taken into + * consideration where applicable. + */ + +#define SRC_ADDR_NOT_MAPPED 4 + +/* Destination address is not mapped in the memory map. Count value is taken into + * consideration where applicable. + */ + +#define DST_ADDR_NOT_MAPPED 5 + +/* Byte count is not multiple of 4 or is not a permitted value. */ + +#define COUNT_ERROR 6 + +/* Sector number is invalid or end sector number is greater than start sector number. */ + +#define INVALID_SECTOR 7 + +/* Sector is not blank. */ + +#define SECTOR_NOT_BLANK 8 + +/* Command to prepare sector for write operation was not executed. */ + +#define SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9 + +/* Source and destination data not equal. */ + +#define COMPARE_ERROR 10 + +/* Flash programming hardware interface is busy. */ + +#define BUSY 11 + +/* Insufficient number of parameters or invalid parameter. */ + +#define PARAM_ERROR 12 + +/* Address is not on word boundary. */ + +#define ADDR_ERROR 13 + +/* Address is not mapped in the memory map. Count value is taken in to consideration + * where applicable. + */ + +#define ADDR_NOT_MAPPED 14 + +/* Command is locked. */ + +#define CMD_LOCKED 15 + +/* Unlock code is invalid. */ + +#define INVALID_CODE 16 + +/* Invalid baud rate setting. */ + +#define INVALID_BAUD_RATE 17 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* IAP function pointer */ + +typedef void (*iap_t)(unsigned int *cmd, unsigned int *result); + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_FLASH_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_gima.h b/arch/arm/src/lpc43xx/chip/lpc43_gima.h new file mode 100644 index 0000000000000000000000000000000000000000..993242ebe49966baa81ec3efb7379a2294b7e443 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_gima.h @@ -0,0 +1,336 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_gima.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GIMA_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GIMA_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +/* Timer capture input multiplexor registers */ + +#define LPC43_GIMA_CAP_OFFSET(t,i) (((t) << 4) | ((i) << 2)) +#define LPC43_GIMA_CAP00_OFFSET 0x0000 /* Timer 0 CAP0_0 capture input multiplexer (GIMA output 0) */ +#define LPC43_GIMA_CAP01_OFFSET 0x0004 /* Timer 0 CAP0_1 capture input multiplexer (GIMA output 1) */ +#define LPC43_GIMA_CAP02_OFFSET 0x0008 /* Timer 0 CAP0_2 capture input multiplexer (GIMA output 2) */ +#define LPC43_GIMA_CAP03_OFFSET 0x000c /* Timer 0 CAP0_3 capture input multiplexer (GIMA output 3) */ +#define LPC43_GIMA_CAP10_OFFSET 0x0010 /* Timer 1 CAP1_0 capture input multiplexer (GIMA output 4) */ +#define LPC43_GIMA_CAP11_OFFSET 0x0014 /* Timer 1 CAP1_1 capture input multiplexer (GIMA output 5) */ +#define LPC43_GIMA_CAP12_OFFSET 0x0018 /* Timer 1 CAP1_2 capture input multiplexer (GIMA output 6) */ +#define LPC43_GIMA_CAP13_OFFSET 0x001c /* Timer 1 CAP1_3 capture input multiplexer (GIMA output 7) */ +#define LPC43_GIMA_CAP20_OFFSET 0x0020 /* Timer 2 CAP2_0 capture input multiplexer (GIMA output 8) */ +#define LPC43_GIMA_CAP21_OFFSET 0x0024 /* Timer 2 CAP2_1 capture input multiplexer (GIMA output 9) */ +#define LPC43_GIMA_CAP22_OFFSET 0x0028 /* Timer 2 CAP2_2 capture input multiplexer (GIMA output 10) */ +#define LPC43_GIMA_CAP23_OFFSET 0x002c /* Timer 2 CAP2_3 capture input multiplexer (GIMA output 11) */ +#define LPC43_GIMA_CAP30_OFFSET 0x0030 /* Timer 3 CAP3_0 capture input multiplexer (GIMA output 12) */ +#define LPC43_GIMA_CAP31_OFFSET 0x0034 /* Timer 3 CAP3_1 capture input multiplexer (GIMA output 13) */ +#define LPC43_GIMA_CAP32_OFFSET 0x0038 /* Timer 3 CAP3_2 capture input multiplexer (GIMA output 14) */ +#define LPC43_GIMA_CAP33_OFFSET 0x003c /* Timer 3 CAP3_3 capture input multiplexer (GIMA output 15) */ + +#define LPC43_GIMA_CTIN_OFFSET(i) (0x0040 + ((i) << 2)) +#define LPC43_GIMA_CTIN0_OFFSET 0x0040 /* SCT CTIN_0 capture input multiplexer (GIMA output 16) */ +#define LPC43_GIMA_CTIN1_OFFSET 0x0044 /* SCT CTIN_1 capture input multiplexer (GIMA output 17) */ +#define LPC43_GIMA_CTIN2_OFFSET 0x0048 /* SCT CTIN_2 capture input multiplexer (GIMA output 18) */ +#define LPC43_GIMA_CTIN3_OFFSET 0x004c /* SCT CTIN_3 capture input multiplexer (GIMA output 19) */ +#define LPC43_GIMA_CTIN4_OFFSET 0x0050 /* SCT CTIN_4 capture input multiplexer (GIMA output 20) */ +#define LPC43_GIMA_CTIN5_OFFSET 0x0054 /* SCT CTIN_5 capture input multiplexer (GIMA output 21) */ +#define LPC43_GIMA_CTIN6_OFFSET 0x0058 /* SCT CTIN_6 capture input multiplexer (GIMA output 22) */ +#define LPC43_GIMA_CTIN7_OFFSET 0x005c /* SCT CTIN_7 capture input multiplexer (GIMA output 23) */ + +#define LPC43_GIMA_VADCTRIG_OFFSET 0x0060 /* VADC trigger input multiplexer (GIMA output 24) */ +#define LPC43_GIMA_EVNTRTR13_OFFSET 0x0064 /* Event router input 13 multiplexer (GIMA output 25) */ +#define LPC43_GIMA_EVNTRTR14_OFFSET 0x0068 /* Event router input 14 multiplexer (GIMA output 26) */ +#define LPC43_GIMA_EVNTRTR16_OFFSET 0x006c /* Event router input 16 multiplexer (GIMA output 27) */ +#define LPC43_GIMA_ADCSTART0_OFFSET 0x0070 /* ADC start0 input multiplexer (GIMA output 28) */ +#define LPC43_GIMA_ADCSTART1_OFFSET 0x0074 /* ADC start1 input multiplexer (GIMA output 29) */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_GIMA_CAP(t,i) (LPC43_GIMA_BASE+LPC43_GIMA_CAP_OFFSET(t,i)) +#define LPC43_GIMA_CAP00 (LPC43_GIMA_BASE+LPC43_GIMA_CAP00_OFFSET) +#define LPC43_GIMA_CAP01 (LPC43_GIMA_BASE+LPC43_GIMA_CAP01_OFFSET) +#define LPC43_GIMA_CAP02 (LPC43_GIMA_BASE+LPC43_GIMA_CAP02_OFFSET) +#define LPC43_GIMA_CAP03 (LPC43_GIMA_BASE+LPC43_GIMA_CAP03_OFFSET) +#define LPC43_GIMA_CAP10 (LPC43_GIMA_BASE+LPC43_GIMA_CAP10_OFFSET) +#define LPC43_GIMA_CAP11 (LPC43_GIMA_BASE+LPC43_GIMA_CAP11_OFFSET) +#define LPC43_GIMA_CAP12 (LPC43_GIMA_BASE+LPC43_GIMA_CAP12_OFFSET) +#define LPC43_GIMA_CAP13 (LPC43_GIMA_BASE+LPC43_GIMA_CAP13_OFFSET) +#define LPC43_GIMA_CAP20 (LPC43_GIMA_BASE+LPC43_GIMA_CAP20_OFFSET) +#define LPC43_GIMA_CAP21 (LPC43_GIMA_BASE+LPC43_GIMA_CAP21_OFFSET) +#define LPC43_GIMA_CAP22 (LPC43_GIMA_BASE+LPC43_GIMA_CAP22_OFFSET) +#define LPC43_GIMA_CAP23 (LPC43_GIMA_BASE+LPC43_GIMA_CAP23_OFFSET) +#define LPC43_GIMA_CAP30 (LPC43_GIMA_BASE+LPC43_GIMA_CAP30_OFFSET) +#define LPC43_GIMA_CAP31 (LPC43_GIMA_BASE+LPC43_GIMA_CAP31_OFFSET) +#define LPC43_GIMA_CAP32 (LPC43_GIMA_BASE+LPC43_GIMA_CAP32_OFFSET) +#define LPC43_GIMA_CAP33 (LPC43_GIMA_BASE+LPC43_GIMA_CAP33_OFFSET) + +#define LPC43_GIMA_CTIN(i) (LPC43_GIMA_BASE+LPC43_GIMA_CTIN_OFFSET(i)) +#define LPC43_GIMA_CTIN0 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN0_OFFSET) +#define LPC43_GIMA_CTIN1 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN1_OFFSET) +#define LPC43_GIMA_CTIN2 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN2_OFFSET) +#define LPC43_GIMA_CTIN3 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN3_OFFSET) +#define LPC43_GIMA_CTIN4 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN4_OFFSET) +#define LPC43_GIMA_CTIN5 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN5_OFFSET) +#define LPC43_GIMA_CTIN6 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN6_OFFSET) +#define LPC43_GIMA_CTIN7 (LPC43_GIMA_BASE+LPC43_GIMA_CTIN7_OFFSET) +#define LPC43_GIMA_VADCTRIG (LPC43_GIMA_BASE+LPC43_GIMA_VADCTRIG_OFFSET) +#define LPC43_GIMA_EVNTRTR13 (LPC43_GIMA_BASE+LPC43_GIMA_EVNTRTR13_OFFSET) +#define LPC43_GIMA_EVNTRTR14 (LPC43_GIMA_BASE+LPC43_GIMA_EVNTRTR14_OFFSET) +#define LPC43_GIMA_EVNTRTR16 (LPC43_GIMA_BASE+LPC43_GIMA_EVNTRTR16_OFFSET) +#define LPC43_GIMA_ADCSTART0 (LPC43_GIMA_BASE+LPC43_GIMA_ADCSTART0_OFFSET) +#define LPC43_GIMA_ADCSTART1 (LPC43_GIMA_BASE+LPC43_GIMA_ADCSTART1_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Common register field definitions */ + +#define GIMA_INV (1 << 0) /* Bit 0: Invert input */ +#define GIMA_EDGE (1 << 1) /* Bit 1: Enable rising edge detection */ +#define GIMA_SYNCH (1 << 2) /* Bit 2: Enable synchronization */ +#define GIMA_PULSE (1 << 3) /* Bit 3: Enable single pulse generation */ +#define GIMA_SELECT_SHIFT (4) /* Bits 4-7: Select input */ +#define GIMA_SELECT_MASK (15 << GIMA_SELECT_SHIFT) + /* Bits 8-31: Reserved */ +/* Timer 0 CAP0_0 capture input multiplexer (GIMA output 0) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP00_SELECT_CTIN0 (0 << GIMA_SELECT_SHIFT) /* CTIN_0 */ +# define GIMA_CAP00_SELECT_SGPIO3 (1 << GIMA_SELECT_SHIFT) /* SGPIO3 */ +# define GIMA_CAP00_SELECT_TOCAP0 (2 << GIMA_SELECT_SHIFT) /* T0_CAP0 */ + /* Bits 8-31: Reserved */ +/* Timer 0 CAP0_1 capture input multiplexer (GIMA output 1) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP01_SELECT_CTIN1 (0 << GIMA_SELECT_SHIFT) /* CTIN_1 */ +# define GIMA_CAP01_SELECT_U2TX (1 << GIMA_SELECT_SHIFT) /* USART2 TX active */ +# define GIMA_CAP01_SELECT_TOCAP1 (2 << GIMA_SELECT_SHIFT) /* T0_CAP1 */ + /* Bits 8-31: Reserved */ +/* Timer 0 CAP0_2 capture input multiplexer (GIMA output 2) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP02_SELECT_CTIN2 (0 << GIMA_SELECT_SHIFT) /* CTIN_2 */ +# define GIMA_CAP02_SELECT_SGPIO3D (1 << GIMA_SELECT_SHIFT) /* SGPIO3_DIV */ +# define GIMA_CAP02_SELECT_T0CAP2 (2 << GIMA_SELECT_SHIFT) /* T0_CAP2 */ + /* Bits 8-31: Reserved */ +/* Timer 0 CAP0_3 capture input multiplexer (GIMA output 3) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP03_SELECT_CTOUT15 (0 << GIMA_SELECT_SHIFT) /* CTOUT_15 or T3_MAT3 */ +# define GIMA_CAP03_SELECT_T0CAP3 (1 << GIMA_SELECT_SHIFT) /* T0_CAP3 */ +# define GIMA_CAP03_SELECT_T3MAT3 (2 << GIMA_SELECT_SHIFT) /* T3_MAT3 */ + /* Bits 8-31: Reserved */ +/* Timer 1 CAP1_0 capture input multiplexer (GIMA output 4) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP10_SELECT_CTIN0 (0 << GIMA_SELECT_SHIFT) /* CTIN_0 */ +# define GIMA_CAP10_SELECT_SGPIO12 (1 << GIMA_SELECT_SHIFT) /* SGPIO12 */ +# define GIMA_CAP10_SELECT_T1CAP0 (2 << GIMA_SELECT_SHIFT) /* T1_CAP0 */ + /* Bits 8-31: Reserved */ +/* Timer 1 CAP1_1 capture input multiplexer (GIMA output 5) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP11_SELECT_CTIN3 (0 << GIMA_SELECT_SHIFT) /* CTIN_3 */ +# define GIMA_CAP11_SELECT_U0TX (1 << GIMA_SELECT_SHIFT) /* USART0 TX active */ +# define GIMA_CAP11_SELECT_T1CAP1 (2 << GIMA_SELECT_SHIFT) /* T1_CAP1 */ + /* Bits 8-31: Reserved */ +/* Timer 1 CAP1_2 capture input multiplexer (GIMA output 6) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP12_SELECT_CTIN4 (0 << GIMA_SELECT_SHIFT) /* CTIN_4 */ +# define GIMA_CAP12_SELECT_U0RX (1 << GIMA_SELECT_SHIFT) /* USART0 RX active */ +# define GIMA_CAP12_SELECT_T1CAP2 (2 << GIMA_SELECT_SHIFT) /* T1_CAP2 */ + /* Bits 8-31: Reserved */ +/* Timer 1 CAP1_3 capture input multiplexer (GIMA output 7) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP13_SELECT_CTOUT3 (0 << GIMA_SELECT_SHIFT) /* CTOUT_3 or T0_MAT3 */ +# define GIMA_CAP13_SELECT_T1CAP3 (1 << GIMA_SELECT_SHIFT) /* T1_CAP3 */ +# define GIMA_CAP13_SELECT_T0MAT3 (2 << GIMA_SELECT_SHIFT) /* T0_MAT3 */ + /* Bits 8-31: Reserved */ +/* Timer 2 CAP2_0 capture input multiplexer (GIMA output 8) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP20_SELECT_CTIN0 (0 << GIMA_SELECT_SHIFT) /* CTIN_0 */ +# define GIMA_CAP20_SELECT_SGPIO12D (1 << GIMA_SELECT_SHIFT) /* SGPIO12_DIV */ +# define GIMA_CAP20_SELECT_T2CAP0 (2 << GIMA_SELECT_SHIFT) /* T2_CAP0 */ + /* Bits 8-31: Reserved */ +/* Timer 2 CAP2_1 capture input multiplexer (GIMA output 9) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP21_SELECT_CTIN1 (0 << GIMA_SELECT_SHIFT) /* CTIN_1 */ +# define GIMA_CAP21_SELECT_U2TX (1 << GIMA_SELECT_SHIFT) /* USART2 TX active */ +# define GIMA_CAP21_SELECT_T2CAP1 (2 << GIMA_SELECT_SHIFT) /* T2_CAP1 */ + /* Bits 8-31: Reserved */ +/* Timer 2 CAP2_2 capture input multiplexer (GIMA output 10) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP22_SELECT_CTIN5 (0 << GIMA_SELECT_SHIFT) /* CTIN_5 */ +# define GIMA_CAP22_SELECT_U2RX (1 << GIMA_SELECT_SHIFT) /* USART2 RX active */ +# define GIMA_CAP22_SELECT_I2S1TX (2 << GIMA_SELECT_SHIFT) /* I2S1_TX_MWS */ +# define GIMA_CAP22_SELECT_T2CAP2 (3 << GIMA_SELECT_SHIFT) /* T2_CAP2 */ + /* Bits 8-31: Reserved */ +/* Timer 2 CAP2_3 capture input multiplexer (GIMA output 11) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP23_SELECT_CTOUT7 (0 << GIMA_SELECT_SHIFT) /* CTOUT_7 or T1_MAT3 */ +# define GIMA_CAP23_SELECT_T2CAP3 (1 << GIMA_SELECT_SHIFT) /* T2_CAP3 */ +# define GIMA_CAP23_SELECT_T1MAT3 (2 << GIMA_SELECT_SHIFT) /* T1_MAT3 */ + /* Bits 8-31: Reserved */ +/* Timer 3 CAP3_0 capture input multiplexer (GIMA output 12) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP30_SELECT_CTIN0 (0 << GIMA_SELECT_SHIFT) /* CTIN_0 */ +# define GIMA_CAP30_SELECT_I2S0RX (1 << GIMA_SELECT_SHIFT) /* I2S0_RX_MWS */ +# define GIMA_CAP30_SELECT_T3CAP0 (2 << GIMA_SELECT_SHIFT) /* T3_CAP0 */ + /* Bits 8-31: Reserved */ +/* Timer 3 CAP3_1 capture input multiplexer (GIMA output 13) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP31_SELECT_CTIN6 (0 << GIMA_SELECT_SHIFT) /* CTIN_6 */ +# define GIMA_CAP31_SELECT_U3TX (1 << GIMA_SELECT_SHIFT) /* USART3 TX active */ +# define GIMA_CAP31_SELECT_I2S0TX (2 << GIMA_SELECT_SHIFT) /* I2S0_TX_MWS */ +# define GIMA_CAP31_SELECT_T3CAP1 (3 << GIMA_SELECT_SHIFT) /* T3_CAP1 */ + /* Bits 8-31: Reserved */ +/* Timer 3 CAP3_2 capture input multiplexer (GIMA output 14) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP32_SELECT_CTIN7 (0 << GIMA_SELECT_SHIFT) /* CTIN_7 */ +# define GIMA_CAP32_SELECT_U3RX (1 << GIMA_SELECT_SHIFT) /* USART3 RX active */ +# define GIMA_CAP32_SELECT_SOF0 (2 << GIMA_SELECT_SHIFT) /* SOF0 (Start-Of-Frame USB0) */ +# define GIMA_CAP32_SELECT_T3CAP2 (3 << GIMA_SELECT_SHIFT) /* T3_CAP2 */ + /* Bits 8-31: Reserved */ +/* Timer 3 CAP3_3 capture input multiplexer (GIMA output 15) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CAP33_SELECT_CTOUT11 (0 << GIMA_SELECT_SHIFT) /* CTOUT11 or T2_MAT3 */ +# define GIMA_CAP33_SELECT_SOF1 (1 << GIMA_SELECT_SHIFT) /* SOF1 (Start-Of-Frame USB1) */ +# define GIMA_CAP33_SELECT_T3CAP3 (2 << GIMA_SELECT_SHIFT) /* T3_CAP3 */ +# define GIMA_CAP33_SELECT_T2MAT3 (3 << GIMA_SELECT_SHIFT) /* T2_MAT3 */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_0 capture input multiplexer (GIMA output 16) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN0_SELECT_CTIN0 (0 << GIMA_SELECT_SHIFT) /* CTIN_0 */ +# define GIMA_CTIN0_SELECT_SGPIO3 (1 << GIMA_SELECT_SHIFT) /* SGPIO3 */ +# define GIMA_CTIN0_SELECT_SGPIO3D (2 << GIMA_SELECT_SHIFT) /* SGPIO3_DIV */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_1 capture input multiplexer (GIMA output 17) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN1_SELECT_CTIN1 (0 << GIMA_SELECT_SHIFT) /* CTIN_1 */ +# define GIMA_CTIN1_SELECT_U2TX (1 << GIMA_SELECT_SHIFT) /* USART2 TX active */ +# define GIMA_CTIN1_SELECT_SGPIO12 (2 << GIMA_SELECT_SHIFT) /* SGPIO12 */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_2 capture input multiplexer (GIMA output 18) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN2_SELECT_CTIN2 (0 << GIMA_SELECT_SHIFT) /* CTIN_2 */ +# define GIMA_CTIN2_SELECT_SGPIO12 (1 << GIMA_SELECT_SHIFT) /* SGPIO12 */ +# define GIMA_CTIN2_SELECT_SGPIO12D (2 << GIMA_SELECT_SHIFT) /* SGPIO12_DIV */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_3 capture input multiplexer (GIMA output 19) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN3_SELECT_CTIN3 (0 << GIMA_SELECT_SHIFT) /* CTIN_3 */ +# define GIMA_CTIN3_SELECT_U0TX (1 << GIMA_SELECT_SHIFT) /* USART0 TX active */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_4 capture input multiplexer (GIMA output 20) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN4_SELECT_CTIN4 (0 << GIMA_SELECT_SHIFT) /* CTIN_4*/ +# define GIMA_CTIN4_SELECT_U0RX (1 << GIMA_SELECT_SHIFT) /* USART0 RX active */ +# define GIMA_CTIN4_SELECT_I2S1RX (2 << GIMA_SELECT_SHIFT) /* I2S1_RX_MWS1 */ +# define GIMA_CTIN4_SELECT_I2S1TX (3 << GIMA_SELECT_SHIFT) /* I2S1_TX_MWS1 */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_5 capture input multiplexer (GIMA output 21) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN5_SELECT_CTIN5 (0 << GIMA_SELECT_SHIFT) /* CTIN_5 */ +# define GIMA_CTIN5_SELECT_U2RX (1 << GIMA_SELECT_SHIFT) /* USART2 RX active */ +# define GIMA_CTIN5_SELECT_SGPIO12D (2 << GIMA_SELECT_SHIFT) /* SGPIO12_DIV */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_6 capture input multiplexer (GIMA output 22) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN6_SELECT_CTIN6 (0 << GIMA_SELECT_SHIFT) /* CTIN_6 */ +# define GIMA_CTIN6_SELECT_U3TX (1 << GIMA_SELECT_SHIFT) /* USART3 TX active */ +# define GIMA_CTIN6_SELECT_I2S0RX (2 << GIMA_SELECT_SHIFT) /* I2S0_RX_MWS */ +# define GIMA_CTIN6_SELECT_I2S0TX (3 << GIMA_SELECT_SHIFT) /* I2S0_TX_MWS */ + /* Bits 8-31: Reserved */ +/* SCT CTIN_7 capture input multiplexer (GIMA output 23) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_CTIN7_SELECT_CTIN7 (0 << GIMA_SELECT_SHIFT) /* CTIN_7 */ +# define GIMA_CTIN7_SELECT_U3RX (1 << GIMA_SELECT_SHIFT) /* USART3 RX active */ +# define GIMA_CTIN7_SELECT_SOF0 (2 << GIMA_SELECT_SHIFT) /* SOF0 (Start-Of-Frame USB0) */ +# define GIMA_CTIN7_SELECT_SOF1 (3 << GIMA_SELECT_SHIFT) /* SOF1 (Start-Of-Frame USB1) */ + /* Bits 8-31: Reserved */ +/* VADC trigger input multiplexer (GIMA output 24) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_VADC_SELECT_GPIO6p28 (0 << GIMA_SELECT_SHIFT) /* GPIO6[28] */ +# define GIMA_VADC_SELECT_GPIO5p3 (1 << GIMA_SELECT_SHIFT) /* GPIO5[3] */ +# define GIMA_VADC_SELECT_SGPIO10 (2 << GIMA_SELECT_SHIFT) /* SGPIO10 */ +# define GIMA_VADC_SELECT_SGPIO12 (3 << GIMA_SELECT_SHIFT) /* SGPIO12 */ +# define GIMA_VADC_SELECT_MCOB2 (5 << GIMA_SELECT_SHIFT) /* MCOB2 */ +# define GIMA_VADC_SELECT_CTOUT0 (6 << GIMA_SELECT_SHIFT) /* CTOUT_0 or T0_MAT0 */ +# define GIMA_VADC_SELECT_CTOUT8 (7 << GIMA_SELECT_SHIFT) /* CTOUT_8 or T2_MAT0 */ +# define GIMA_VADC_SELECT_T0MAT0 (8 << GIMA_SELECT_SHIFT) /* T0_MAT0 */ +# define GIMA_VADC_SELECT_T2MAT0 (9 << GIMA_SELECT_SHIFT) /* T2_MAT0 */ + /* Bits 8-31: Reserved */ +/* Event router input 13 multiplexer (GIMA output 25) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_EVNTRTR_SELECT_CTOUT2 (0 << GIMA_SELECT_SHIFT) /* CTOUT_2 or T0_MAT2 */ +# define GIMA_EVNTRTR_SELECT_SGPIO3 (1 << GIMA_SELECT_SHIFT) /* SGPIO3 */ +# define GIMA_EVNTRTR_SELECT_T0MAT2 (2 << GIMA_SELECT_SHIFT) /* T0_MAT2 */ + /* Bits 8-31: Reserved */ +/* Event router input 14 multiplexer (GIMA output 26) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_EVNTRTR_SELECT_CTOUT6 (0 << GIMA_SELECT_SHIFT) /* CTOUT_6 or T1_MAT2 */ +# define GIMA_EVNTRTR_SELECT_SGPIO12 (1 << GIMA_SELECT_SHIFT) /* SGPIO12 */ +# define GIMA_EVNTRTR_SELECT_T1MAT2 (2 << GIMA_SELECT_SHIFT) /* T1_MAT2 */ + /* Bits 8-31: Reserved */ +/* Event router input 16 multiplexer (GIMA output 27) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_EVNTRTR_SELECT_CTOUT14 (0 << GIMA_SELECT_SHIFT) /* CTOUT_14 or T3_MAT2 */ +# define GIMA_EVNTRTR_SELECT_T3MAT2 (1 << GIMA_SELECT_SHIFT) /* T3_MAT2 */ + /* Bits 8-31: Reserved */ +/* ADC start0 input multiplexer (GIMA output 28) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_ADC0_SELECT_CTOUT15 (0 << GIMA_SELECT_SHIFT) /* CTOUT_15 or T3_MAT3 */ +# define GIMA_ADC0_SELECT_T3MAT2 (1 << GIMA_SELECT_SHIFT) /* T3_MAT2 */ + /* Bits 8-31: Reserved */ +/* ADC start1 input multiplexer (GIMA output 29) */ + /* Bits 4-7: Same as the common definitions */ +# define GIMA_ADC1_SELECT_CTOUT8 (0 << GIMA_SELECT_SHIFT) /* CTOUT_8 or T2_MAT0 */ +# define GIMA_ADC1_SELECT_T2MAT0 (1 << GIMA_SELECT_SHIFT) /* T2_MAT0 */ + /* Bits 8-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GIMA_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h b/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h new file mode 100644 index 0000000000000000000000000000000000000000..2139e09766f17c545223e04560c080ded3305eb3 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_gpdma.h @@ -0,0 +1,465 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_gpdma.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPDMA_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPDMA_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_GPDMA_INTSTAT_OFFSET 0x0000 /* DMA Interrupt Status Register */ +#define LPC43_GPDMA_INTTCSTAT_OFFSET 0x0004 /* DMA Interrupt Terminal Count Request Status Register */ +#define LPC43_GPDMA_INTTCCLEAR_OFFSET 0x0008 /* DMA Interrupt Terminal Count Request Clear Register */ +#define LPC43_GPDMA_INTERRSTAT_OFFSET 0x000c /* DMA Interrupt Error Status Register */ +#define LPC43_GPDMA_INTERRCLR_OFFSET 0x0010 /* DMA Interrupt Error Clear Register */ +#define LPC43_GPDMA_RAWINTTCSTAT_OFFSET 0x0014 /* DMA Raw Interrupt Terminal Count Status Register */ +#define LPC43_GPDMA_RAWINTERRSTAT_OFFSET 0x0018 /* DMA Raw Error Interrupt Status Register */ +#define LPC43_GPDMA_ENBLDCHNS_OFFSET 0x001c /* DMA Enabled Channel Register */ +#define LPC43_GPDMA_SOFTBREQ_OFFSET 0x0020 /* DMA Software Burst Request Register */ +#define LPC43_GPDMA_SOFTSREQ_OFFSET 0x0024 /* DMA Software Single Request Register */ +#define LPC43_GPDMA_SOFTLBREQ_OFFSET 0x0028 /* DMA Software Last Burst Request Register */ +#define LPC43_GPDMA_SOFTLSREQ_OFFSET 0x002c /* DMA Software Last Single Request Register */ +#define LPC43_GPDMA_CONFIG_OFFSET 0x0030 /* DMA Configuration Register */ +#define LPC43_GPDMA_SYNC_OFFSET 0x0034 /* DMA Synchronization Register */ + +/* Channel registers */ + +#define LPC43_GPDMA_SRCADDR_CHOFFSET 0x0000 /* DMA Channel Source Address Register */ +#define LPC43_GPDMA_DESTADDR_CHOFFSET 0x0004 /* DMA Channel Destination Address Register */ +#define LPC43_GPDMA_LLI_CHOFFSET 0x0008 /* DMA Channel Linked List Item Register */ +#define LPC43_GPDMA_CONTROL_CHOFFSET 0x000c /* DMA Channel Control Register */ +#define LPC43_GPDMA_CONFIG_CHOFFSET 0x0010 /* DMA Channel Configuration Register */ + +#define LPC43_GPDMA_CHOFFSET(n) (0x0100 ((n) << 5)) +#define LPC43_GPDMA_SRCADDR_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_SRCADDR_CHOFFSET) +#define LPC43_GPDMA_DESTADDR_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_DESTADDR_CHOFFSET) +#define LPC43_GPDMA_LLI_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_LLI_CHOFFSET) +#define LPC43_GPDMA_CONTROL_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_CONTROL_CHOFFSET) +#define LPC43_GPDMA_CONFIG_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_CONFIG_CHOFFSET) + +#define LPC43_GPDMA_SRCADDR0_OFFSET 0x0100 /* DMA Channel 0 Source Address Register */ +#define LPC43_GPDMA_DESTADDR0_OFFSET 0x0104 /* DMA Channel 0 Destination Address Register */ +#define LPC43_GPDMA_LLI0_OFFSET 0x0108 /* DMA Channel 0 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL0_OFFSET 0x010c /* DMA Channel 0 Control Register */ +#define LPC43_GPDMA_CONFIG0_OFFSET 0x0110 /* DMA Channel 0 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR1_OFFSET 0x0120 /* DMA Channel 1 Source Address Register */ +#define LPC43_GPDMA_DESTADDR1_OFFSET 0x0124 /* DMA Channel 1 Destination Address Register */ +#define LPC43_GPDMA_LLI1_OFFSET 0x0128 /* DMA Channel 1 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL1_OFFSET 0x012c /* DMA Channel 1 Control Register */ +#define LPC43_GPDMA_CONFIG1_OFFSET 0x0130 /* DMA Channel 1 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR2_OFFSET 0x0140 /* DMA Channel 2 Source Address Register */ +#define LPC43_GPDMA_DESTADDR2_OFFSET 0x0144 /* DMA Channel 2 Destination Address Register */ +#define LPC43_GPDMA_LLI2_OFFSET 0x0148 /* DMA Channel 2 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL2_OFFSET 0x014c /* DMA Channel 2 Control Register */ +#define LPC43_GPDMA_CONFIG2_OFFSET 0x0150 /* DMA Channel 2 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR3_OFFSET 0x0160 /* DMA Channel 3 Source Address Register */ +#define LPC43_GPDMA_DESTADDR3_OFFSET 0x0164 /* DMA Channel 3 Destination Address */ +#define LPC43_GPDMA_LLI3_OFFSET 0x0168 /* DMA Channel 3 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL3_OFFSET 0x016c /* DMA Channel 3 Control Register */ +#define LPC43_GPDMA_CONFIG3_OFFSET 0x0170 /* DMA Channel 3 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR4_OFFSET 0x0180 /* DMA Channel 4 Source Address Register */ +#define LPC43_GPDMA_DESTADDR4_OFFSET 0x0184 /* DMA Channel 4 Destination Address Register */ +#define LPC43_GPDMA_LLI4_OFFSET 0x0188 /* DMA Channel 4 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL4_OFFSET 0x018c /* DMA Channel 4 Control Register */ +#define LPC43_GPDMA_CONFIG4_OFFSET 0x0190 /* DMA Channel 4 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR5_OFFSET 0x01a0 /* DMA Channel 5 Source Address Register */ +#define LPC43_GPDMA_DESTADDR5_OFFSET 0x01a4 /* DMA Channel 5 Destination Address Register */ +#define LPC43_GPDMA_LLI5_OFFSET 0x01a8 /* DMA Channel 5 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL5_OFFSET 0x01ac /* DMA Channel 5 Control Register */ +#define LPC43_GPDMA_CONFIG5_OFFSET 0x01b0 /* DMA Channel 5 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR6_OFFSET 0x01c0 /* DMA Channel 6 Source Address Register */ +#define LPC43_GPDMA_DESTADDR6_OFFSET 0x01c4 /* DMA Channel 6 Destination Address Register */ +#define LPC43_GPDMA_LLI6_OFFSET 0x01c8 /* DMA Channel 6 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL6_OFFSET 0x01cc /* DMA Channel 6 Control Register */ +#define LPC43_GPDMA_CONFIG6_OFFSET 0x01d0 /* DMA Channel 6 Configuration Register */ + +#define LPC43_GPDMA_SRCADDR7_OFFSET 0x01e0 /* DMA Channel 7 Source Address Register */ +#define LPC43_GPDMA_DESTADDR7_OFFSET 0x01e4 /* DMA Channel 7 Destination Address Register */ +#define LPC43_GPDMA_LLI7_OFFSET 0x01e8 /* DMA Channel 7 Linked List Item Register */ +#define LPC43_GPDMA_CONTROL7_OFFSET 0x01ec /* DMA Channel 7 Control Register */ +#define LPC43_GPDMA_CONFIG7_OFFSET 0x01f0 /* DMA Channel 7 Configuration Register */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_GPDMA_INTSTAT (LPC43_DMA_BASE+LPC43_GPDMA_INTSTAT_OFFSET) +#define LPC43_GPDMA_INTTCSTAT (LPC43_DMA_BASE+LPC43_GPDMA_INTTCSTAT_OFFSET) +#define LPC43_GPDMA_INTTCCLEAR (LPC43_DMA_BASE+LPC43_GPDMA_INTTCCLEAR_OFFSET) +#define LPC43_GPDMA_INTERRSTAT (LPC43_DMA_BASE+LPC43_GPDMA_INTERRSTAT_OFFSET) +#define LPC43_GPDMA_INTERRCLR (LPC43_DMA_BASE+LPC43_GPDMA_INTERRCLR_OFFSET) +#define LPC43_GPDMA_RAWINTTCSTAT (LPC43_DMA_BASE+LPC43_GPDMA_RAWINTTCSTAT_OFFSET) +#define LPC43_GPDMA_RAWINTERRSTAT (LPC43_DMA_BASE+LPC43_GPDMA_RAWINTERRSTAT_OFFSET) +#define LPC43_GPDMA_ENBLDCHNS (LPC43_DMA_BASE+LPC43_GPDMA_ENBLDCHNS_OFFSET) +#define LPC43_GPDMA_SOFTBREQ (LPC43_DMA_BASE+LPC43_GPDMA_SOFTBREQ_OFFSET) +#define LPC43_GPDMA_SOFTSREQ (LPC43_DMA_BASE+LPC43_GPDMA_SOFTSREQ_OFFSET) +#define LPC43_GPDMA_SOFTLBREQ (LPC43_DMA_BASE+LPC43_GPDMA_SOFTLBREQ_OFFSET) +#define LPC43_GPDMA_SOFTLSREQ (LPC43_DMA_BASE+LPC43_GPDMA_SOFTLSREQ_OFFSET) +#define LPC43_GPDMA_CONFIG (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG_OFFSET) +#define LPC43_GPDMA_SYNC (LPC43_DMA_BASE+LPC43_GPDMA_SYNC_OFFSET) + +/* Channel registers */ + +#define LPC43_GPDMA_CHANNEL(n) (LPC43_DMA_BASE+LPC43_GPDMA_CHOFFSET(n)) +#define LPC43_GPDMA_SRCADDR(n) (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR_OFFSET(n)) +#define LPC43_GPDMA_DESTADDR(n) (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR_OFFSET(n)) +#define LPC43_GPDMA_LLI(n) (LPC43_DMA_BASE+LPC43_GPDMA_LLI_OFFSET(n)) +#define LPC43_GPDMA_CONTROL(n) (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL_OFFSET(n)) +#define LPC43_GPDMA_CONFIG(n) (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG_OFFSET(n)) + +#define LPC43_GPDMA_SRCADDR0 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR0_OFFSET) +#define LPC43_GPDMA_DESTADDR0 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR0_OFFSET) +#define LPC43_GPDMA_LLI0 (LPC43_DMA_BASE+LPC43_GPDMA_LLI0_OFFSET) +#define LPC43_GPDMA_CONTROL0 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL0_OFFSET) +#define LPC43_GPDMA_CONFIG0 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG0_OFFSET) + +#define LPC43_GPDMA_SRCADDR1 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR1_OFFSET) +#define LPC43_GPDMA_DESTADDR1 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR1_OFFSET) +#define LPC43_GPDMA_LLI1 (LPC43_DMA_BASE+LPC43_GPDMA_LLI1_OFFSET) +#define LPC43_GPDMA_CONTROL1 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL1_OFFSET) +#define LPC43_GPDMA_CONFIG1 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG1_OFFSET) + +#define LPC43_GPDMA_SRCADDR2 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR2_OFFSET) +#define LPC43_GPDMA_DESTADDR2 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR2_OFFSET) +#define LPC43_GPDMA_LLI2 (LPC43_DMA_BASE+LPC43_GPDMA_LLI2_OFFSET) +#define LPC43_GPDMA_CONTROL2 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL2_OFFSET) +#define LPC43_GPDMA_CONFIG2 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG2_OFFSET) + +#define LPC43_GPDMA_SRCADDR3 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR3_OFFSET) +#define LPC43_GPDMA_DESTADDR3 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR3_OFFSET) +#define LPC43_GPDMA_LLI3 (LPC43_DMA_BASE+LPC43_GPDMA_LLI3_OFFSET) +#define LPC43_GPDMA_CONTROL3 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL3_OFFSET) +#define LPC43_GPDMA_CONFIG3 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG3_OFFSET) + +#define LPC43_GPDMA_SRCADDR4 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR4_OFFSET) +#define LPC43_GPDMA_DESTADDR4 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR4_OFFSET) +#define LPC43_GPDMA_LLI4 (LPC43_DMA_BASE+LPC43_GPDMA_LLI4_OFFSET) +#define LPC43_GPDMA_CONTROL4 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL4_OFFSET) +#define LPC43_GPDMA_CONFIG4 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG4_OFFSET) + +#define LPC43_GPDMA_SRCADDR5 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR5_OFFSET) +#define LPC43_GPDMA_DESTADDR5 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR5_OFFSET) +#define LPC43_GPDMA_LLI5 (LPC43_DMA_BASE+LPC43_GPDMA_LLI5_OFFSET) +#define LPC43_GPDMA_CONTROL5 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL5_OFFSET) +#define LPC43_GPDMA_CONFIG5 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG5_OFFSET) + +#define LPC43_GPDMA_SRCADDR6 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR6_OFFSET) +#define LPC43_GPDMA_DESTADDR6 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR6_OFFSET) +#define LPC43_GPDMA_LLI6 (LPC43_DMA_BASE+LPC43_GPDMA_LLI6_OFFSET) +#define LPC43_GPDMA_CONTROL6 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL6_OFFSET) +#define LPC43_GPDMA_CONFIG6 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG6_OFFSET) + +#define LPC43_GPDMA_SRCADDR7 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR7_OFFSET) +#define LPC43_GPDMA_DESTADDR7 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR7_OFFSET) +#define LPC43_GPDMA_LLI7 (LPC43_DMA_BASE+LPC43_GPDMA_LLI7_OFFSET) +#define LPC43_GPDMA_CONTROL7 (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL7_OFFSET) +#define LPC43_GPDMA_CONFIG7 (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG7_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Common macros for DMA channel and source bit settings */ + +#define GPDMA_CHANNEL(n) (1 << (n)) /* Bits 0-7 correspond to DMA channel 0-7 */ +#define GPDMA_SOURCE(n) (1 << (n)) /* Bits 0-15 correspond to DMA source 0-15 */ +#define GPDMA_REQUEST(n) (1 << (n)) /* Bits 0-15 correspond to DMA request 0-15 */ + +/* DMA Interrupt Status Register */ + +#define GPDMA_INTSTAT(n) (1 << (n)) /* Bits 0-7: Status of DMA channel n interrupts after masking */ + /* Bits 8-31: Reserved */ +/* DMA Interrupt Terminal Count Request Status Register */ + +#define GPDMA_INTTCSTAT(n) (1 << (n)) /* Bits 0-7: Terminal count interrupt request status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Interrupt Terminal Count Request Clear Register */ + +#define GPDMA_INTTCCLEAR(n) (1 << (n)) /* Bits 0-7: Clear terminal count interrupt request for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Interrupt Error Status Register */ + +#define GPDMA_INTERRSTAT(n) (1 << (n)) /* Bits 0-7: Interrupt error status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Interrupt Error Clear Register */ + +#define GPDMA_INTERRCLR(n) (1 << (n)) /* Bits 0-7: Clear nterrupt error status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Raw Interrupt Terminal Count Status Register */ + +#define GPDMA_RAWINTTCSTAT(n) (1 << (n)) /* Bits 0-7: Terminal count interrupt request status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Raw Error Interrupt Status Register */ + +#define GPDMA_RAWINTERRSTAT(n) (1 << (n)) /* Bits 0-7: Interrupt error status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Enabled Channel Register */ + +#define GPDMA_ENBLDCHNS(n) (1 << (n)) /* Bits 0-7: Enabled status for DMA channel n */ + /* Bits 8-31: Reserved */ +/* DMA Software Burst Request Register */ + +#define GPDMA_SOFTBREQ(n) (1 << (n)) /* Bits 0-15: Software burst request flags for source n */ + /* Bits 16-31: Reserved */ + +/* DMA Software Single Request Register */ + +#define GPDMA_SOFTSREQ(n) (1 << (n)) /* Bits 0-15: Software single burst request flags for source n */ + /* Bits 16-31: Reserved */ +/* DMA Software Last Burst Request Register */ + +#define GPDMA_SOFTLBREQ(n) (1 << (n)) /* Bits 0-15: Software last burst request flags for source n */ + /* Bits 16-31: Reserved */ +/* DMA Software Last Single Request Register */ + +#define GPDMA_SOFTLSREQ(n) (1 << (n)) /* Bits 0-15: Software last single burst request flags for source n */ + /* Bits 16-31: Reserved */ +/* DMA Configuration Register */ + +#define GPDMA_CONFIG_ENA (1 << 0) /* Bit 0: DMA Controller enable */ +#define GPDMA_CONFIG_M0 (1 << 1) /* Bit 1: AHB Master 0 endianness configuration */ +#define GPDMA_CONFIG_M1 (1 << 2) /* Bit 2: M1 AHB Master 1 endianness configuration */ + /* Bits 3-31: Reserved */ +/* DMA Synchronization Register */ + +#define GPDMA_SYNC(n) (1 << (n)) /* Bits 0-15: Control synchrononization for DMA request n */ + /* Bits 16-31: Reserved */ +/* DMA Channel Source Address Register (32-bit address) */ +/* DMA Channel Destination Address Register (32-bit address) */ + +/* DMA Channel Linked List Item Register */ + +#define GPDMA_LLI_LM (1 << 0) /* Bit 0: LM AHB master select for loading the next LLI */ + /* Bit 1: Reserved */ +#define GPDMA_LLI_MASK 0xfffffffc /* 31:2 LLI Linked list item */ + +/* DMA Channel Control Register */ + +#define GPDMA_CONTROL_XFRSIZE_SHIFT (0) /* Bits 0-11: Transfer size in number of transfers */ +#define GPDMA_CONTROL_XFRSIZE_MASK (0xfff << GPDMA_CONTROL_XFRSIZE_SHIFT) +#define GPDMA_CONTROL_SBSIZE_SHIFT (12) /* Bits 12-14: Source burst size */ +#define GPDMA_CONTROL_SBSIZE_MASK (7 << GPDMA_CONTROL_XFRSIZE_MASK) +# define GPDMA_CONTROL_SBSIZE_1 (0 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 1 */ +# define GPDMA_CONTROL_SBSIZE_4 (1 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 4 */ +# define GPDMA_CONTROL_SBSIZE_8 (2 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 8 */ +# define GPDMA_CONTROL_SBSIZE_16 (3 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 16 */ +# define GPDMA_CONTROL_SBSIZE_32 (4 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 32 */ +# define GPDMA_CONTROL_SBSIZE_64 (5 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 64 */ +# define GPDMA_CONTROL_SBSIZE_128 (6 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 128 */ +# define GPDMA_CONTROL_SBSIZE_256 (7 << GPDMA_CONTROL_XFRSIZE_MASK) /* Source burst size = 256 */ +#define GPDMA_CONTROL_DBSIZE_SHIFT (15) /* Bits 15-17: Destination burst size */ +#define GPDMA_CONTROL_DBSIZE_MASK (7 << GPDMA_CONTROL_DBSIZE_SHIFT) +# define GPDMA_CONTROL_DBSIZE_1 (0 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 1 */ +# define GPDMA_CONTROL_DBSIZE_4 (1 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 4 */ +# define GPDMA_CONTROL_DBSIZE_8 (2 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 8 */ +# define GPDMA_CONTROL_DBSIZE_16 (3 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 16 */ +# define GPDMA_CONTROL_DBSIZE_32 (4 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 32 */ +# define GPDMA_CONTROL_DBSIZE_64 (5 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 64 */ +# define GPDMA_CONTROL_DBSIZE_128 (6 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 128 */ +# define GPDMA_CONTROL_DBSIZE_256 (7 << GPDMA_CONTROL_DBSIZE_SHIFT) /* Destination burst size = 256 */ +#define GPDMA_CONTROL_SWIDTH_SHIFT (18) /* Bits 18-20: Source transfer width */ +#define GPDMA_CONTROL_SWIDTH_MASK (7 << GPDMA_CONTROL_SWIDTH_SHIFT) +# define GPDMA_CONTROL_SWIDTH_BYTE (0 << GPDMA_CONTROL_SWIDTH_SHIFT) /* Byte (8-bit) */ +# define GPDMA_CONTROL_SWIDTH_HWORD (1 << GPDMA_CONTROL_SWIDTH_SHIFT) /* Halfword (16-bit) */ +# define GPDMA_CONTROL_SWIDTH_WORD (2 << GPDMA_CONTROL_SWIDTH_SHIFT) /* Word (32-bit) */ +#define GPDMA_CONTROL_DWIDTH_SHIFT (21) /* Bits 21-23: Destination transfer width */ +#define GPDMA_CONTROL_DWIDTH_MASK (7 << GPDMA_CONTROL_DWIDTH_SHIFT) +# define GPDMA_CONTROL_DWIDTH_BYTE (0 << GPDMA_CONTROL_DWIDTH_SHIFT) /* Byte (8-bit) */ +# define GPDMA_CONTROL_DWIDTH_HWORD (1 << GPDMA_CONTROL_DWIDTH_SHIFT) /* Halfword (16-bit) */ +# define GPDMA_CONTROL_DWIDTH_WORD (2 << GPDMA_CONTROL_DWIDTH_SHIFT) /* Word (32-bit) */ +#define GPDMA_CONTROL_SS (1 << 24) /* Bit 24: Source AHB master select */ +#define GPDMA_CONTROL_DS (1 << 25) /* Bit 25: Destination AHB master select */ +#define GPDMA_CONTROL_SI (1 << 26) /* Bit 26: Source increment */ +#define GPDMA_CONTROL_DI (1 << 27) /* Bit 27: Destination increment */ +#define GPDMA_CONTROL_PROT1 (1 << 28) /* Bit 28: Privileged mode */ +#define GPDMA_CONTROL_PROT2 (1 << 29) /* Bit 29: Bufferable */ +#define GPDMA_CONTROL_PROT3 (1 << 30) /* Bit 30: Cacheable */ +#define GPDMA_CONTROL_IE (1 << 31) /* Bit 31: Terminal count interrupt enable bit */ + +/* DMA Channel Configuration Register */ + +#define GPDMA_CONFIG_ENA (1 << 0) /* Bit 0: Channel enable */ +#define GPDMA_CONFIG_SRCPER_SHIFT (1) /* Bits 1-5: Source peripheral */ +#define GPDMA_CONFIG_SRCPER_MASK (31 << GPDMA_CONFIG_SRCPER_SHIFT) +# define GPDMA_CONFIG_SRCPER_SPIFI (0 << GPDMA_CONFIG_SRCPER_SHIFT) /* SPIFI */ +# define GPDMA_CONFIG_SRCPER_SCTM3_1 (0 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT match3 */ +# define GPDMA_CONFIG_SRCPER_SGPIO14_1 (0 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_SRCPER_T3MAT1_1 (0 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer3 match 1 */ +# define GPDMA_CONFIG_SRCPER_T0MAT0 (1 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer0 match 0 */ +# define GPDMA_CONFIG_SRCPER_U0TX_1 (1 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART0 transmit */ +# define GPDMA_CONFIG_SRCPER_T0MAT1 (2 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer0 match 1 */ +# define GPDMA_CONFIG_SRCPER_U0RX_1 (2 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART0 receive */ +# define GPDMA_CONFIG_SRCPER_T1MAT0 (3 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer1 match 0 */ +# define GPDMA_CONFIG_SRCPER_U1TX (3 << GPDMA_CONFIG_SRCPER_SHIFT) /* UART1 transmit */ +# define GPDMA_CONFIG_SRCPER_I2S1D1 (3 << GPDMA_CONFIG_SRCPER_SHIFT) /* I2S1 DMA request 1 */ +# define GPDMA_CONFIG_SRCPER_SSP1TX_1 (3 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_SRCPER_T1MAT1 (4 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer1 match 1 */ +# define GPDMA_CONFIG_SRCPER_U1RX (4 << GPDMA_CONFIG_SRCPER_SHIFT) /* UART1 receive */ +# define GPDMA_CONFIG_SRCPER_I2S1D2 (4 << GPDMA_CONFIG_SRCPER_SHIFT) /* I2S1 DMA request 2 */ +# define GPDMA_CONFIG_SRCPER_SSP1RX_1 (4 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_SRCPER_T2MAT0 (5 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer2 match 0 */ +# define GPDMA_CONFIG_SRCPER_U2TX (5 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART2 transmit */ +# define GPDMA_CONFIG_SRCPER_SSP1TX_2 (5 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_SRCPER_SGPIO15_1 (5 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_SRCPER_T2MAT1 (6 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer2 match 1 */ +# define GPDMA_CONFIG_SRCPER_U2RX (6 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART2 receive */ +# define GPDMA_CONFIG_SRCPER_SSP1RX_2 (6 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_SRCPER_SGPIO14_2 (6 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_SRCPER_T3MAT0_1 (7 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer3 match 0 */ +# define GPDMA_CONFIG_SRCPER_U3TX_1 (7 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART3 transmit */ +# define GPDMA_CONFIG_SRCPER_SCTD0_1 (7 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT DMA request 0 */ +# define GPDMA_CONFIG_SRCPER_VADCWR (7 << GPDMA_CONFIG_SRCPER_SHIFT) /* VADC write */ +# define GPDMA_CONFIG_SRCPER_T3MAT1_2 (8 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer3 match 1 */ +# define GPDMA_CONFIG_SRCPER_U3RX_1 (8 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART3 receive */ +# define GPDMA_CONFIG_SRCPER_SCTD1_1 (8 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT DMA request 1 */ +# define GPDMA_CONFIG_SRCPER_VADCRD (8 << GPDMA_CONFIG_SRCPER_SHIFT) /* VADC read */ +# define GPDMA_CONFIG_SRCPER_SSP0RX (9 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP0 receive */ +# define GPDMA_CONFIG_SRCPER_I2S0D1 (9 << GPDMA_CONFIG_SRCPER_SHIFT) /* I2S0 DMA request 1 */ +# define GPDMA_CONFIG_SRCPER_SCTD1_2 (9 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT DMA request 1 */ +# define GPDMA_CONFIG_SRCPER_SSP0TX (10 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP0 transmit */ +# define GPDMA_CONFIG_SRCPER_I2S0D2 (10 << GPDMA_CONFIG_SRCPER_SHIFT) /* I2S0 DMA request 2 */ +# define GPDMA_CONFIG_SRCPER_SCTD0_2 (10 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT DMA request 0 */ +# define GPDMA_CONFIG_SRCPER_SSP1RX_3 (11 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_SRCPER_SGPIO14_3 (11 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_SRCPER_U0TX_2 (11 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART0 transmit */ +# define GPDMA_CONFIG_SRCPER_SSP1TX_3 (12 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_SRCPER_SGPIO15_2 (12 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_SRCPER_U0RX_2 (12 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART0 receive */ +# define GPDMA_CONFIG_SRCPER_ADC0 (13 << GPDMA_CONFIG_SRCPER_SHIFT) /* ADC0 */ +# define GPDMA_CONFIG_SRCPER_SSP1RX_4 (13 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_SRCPER_U3RX_2 (13 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART3 receive */ +# define GPDMA_CONFIG_SRCPER_ADC1 (14 << GPDMA_CONFIG_SRCPER_SHIFT) /* ADC1 */ +# define GPDMA_CONFIG_SRCPER_SSP1TX_4 (14 << GPDMA_CONFIG_SRCPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_SRCPER_U3TX_2 (14 << GPDMA_CONFIG_SRCPER_SHIFT) /* USART3 transmit */ +# define GPDMA_CONFIG_SRCPER_DAC (15 << GPDMA_CONFIG_SRCPER_SHIFT) /* DAC */ +# define GPDMA_CONFIG_SRCPER_SCTM3_2 (15 << GPDMA_CONFIG_SRCPER_SHIFT) /* SCT match 3 */ +# define GPDMA_CONFIG_SRCPER_SGPIO15_3 (15 << GPDMA_CONFIG_SRCPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_SRCPER_T3MAT0_2 (15 << GPDMA_CONFIG_SRCPER_SHIFT) /* Timer3 match 0 */ +#define GPDMA_CONFIG_DESTPER_SHIFT (6) /* Bits 6-10: Destination peripheral */ +#define GPDMA_CONFIG_DESTPER_MASK (31 << GPDMA_CONFIG_DESTPER_SHIFT) +# define GPDMA_CONFIG_DESTPER_SPIFI (0 << GPDMA_CONFIG_DESTPER_SHIFT) /* SPIFI */ +# define GPDMA_CONFIG_DESTPER_SCTM3_1 (0 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT match3 */ +# define GPDMA_CONFIG_DESTPER_SGPIO14_1 (0 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_DESTPER_T3MAT1_1 (0 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer3 match 1 */ +# define GPDMA_CONFIG_DESTPER_T0MAT0 (1 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer0 match 0 */ +# define GPDMA_CONFIG_DESTPER_U0TX_1 (1 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART0 transmit */ +# define GPDMA_CONFIG_DESTPER_T0MAT1 (2 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer0 match 1 */ +# define GPDMA_CONFIG_DESTPER_U0RX_1 (2 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART0 receive */ +# define GPDMA_CONFIG_DESTPER_T1MAT0 (3 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer1 match 0 */ +# define GPDMA_CONFIG_DESTPER_U1TX (3 << GPDMA_CONFIG_DESTPER_SHIFT) /* UART1 transmit */ +# define GPDMA_CONFIG_DESTPER_I2S1D1 (3 << GPDMA_CONFIG_DESTPER_SHIFT) /* I2S1 DMA request 1 */ +# define GPDMA_CONFIG_DESTPER_SSP1TX_1 (3 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_DESTPER_T1MAT1 (4 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer1 match 1 */ +# define GPDMA_CONFIG_DESTPER_U1RX (4 << GPDMA_CONFIG_DESTPER_SHIFT) /* UART1 receive */ +# define GPDMA_CONFIG_DESTPER_I2S1D2 (4 << GPDMA_CONFIG_DESTPER_SHIFT) /* I2S1 DMA request 2 */ +# define GPDMA_CONFIG_DESTPER_SSP1RX_1 (4 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_DESTPER_T2MAT0 (5 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer2 match 0 */ +# define GPDMA_CONFIG_DESTPER_U2TX (5 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART2 transmit */ +# define GPDMA_CONFIG_DESTPER_SSP1TX_2 (5 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_DESTPER_SGPIO15_1 (5 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_DESTPER_T2MAT1 (6 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer2 match 1 */ +# define GPDMA_CONFIG_DESTPER_U2RX (6 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART2 receive */ +# define GPDMA_CONFIG_DESTPER_SSP1RX_2 (6 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_DESTPER_SGPIO14_2 (6 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_DESTPER_T3MAT0_1 (7 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer3 match 0 */ +# define GPDMA_CONFIG_DESTPER_U3TX_1 (7 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART3 transmit */ +# define GPDMA_CONFIG_DESTPER_SCTD0_1 (7 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT DMA request 0 */ +# define GPDMA_CONFIG_DESTPER_VADCWR (7 << GPDMA_CONFIG_DESTPER_SHIFT) /* VADC write */ +# define GPDMA_CONFIG_DESTPER_T3MAT1_2 (8 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer3 match 1 */ +# define GPDMA_CONFIG_DESTPER_U3RX_1 (8 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART3 receive */ +# define GPDMA_CONFIG_DESTPER_SCTD1_1 (8 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT DMA request 1 */ +# define GPDMA_CONFIG_DESTPER_VADCRD (8 << GPDMA_CONFIG_DESTPER_SHIFT) /* VADC read */ +# define GPDMA_CONFIG_DESTPER_SSP0RX (9 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP0 receive */ +# define GPDMA_CONFIG_DESTPER_I2S0D1 (9 << GPDMA_CONFIG_DESTPER_SHIFT) /* I2S0 DMA request 1 */ +# define GPDMA_CONFIG_DESTPER_SCTD1_2 (9 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT DMA request 1 */ +# define GPDMA_CONFIG_DESTPER_SSP0TX (10 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP0 transmit */ +# define GPDMA_CONFIG_DESTPER_I2S0D2 (10 << GPDMA_CONFIG_DESTPER_SHIFT) /* I2S0 DMA request 2 */ +# define GPDMA_CONFIG_DESTPER_SCTD0_2 (10 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT DMA request 0 */ +# define GPDMA_CONFIG_DESTPER_SSP1RX_3 (11 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_DESTPER_SGPIO14_3 (11 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO14 */ +# define GPDMA_CONFIG_DESTPER_U0TX_2 (11 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART0 transmit */ +# define GPDMA_CONFIG_DESTPER_SSP1TX_3 (12 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_DESTPER_SGPIO15_2 (12 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_DESTPER_U0RX_2 (12 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART0 receive */ +# define GPDMA_CONFIG_DESTPER_ADC0 (13 << GPDMA_CONFIG_DESTPER_SHIFT) /* ADC0 */ +# define GPDMA_CONFIG_DESTPER_SSP1RX_4 (13 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 receive */ +# define GPDMA_CONFIG_DESTPER_U3RX_2 (13 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART3 receive */ +# define GPDMA_CONFIG_DESTPER_ADC1 (14 << GPDMA_CONFIG_DESTPER_SHIFT) /* ADC1 */ +# define GPDMA_CONFIG_DESTPER_SSP1TX_4 (14 << GPDMA_CONFIG_DESTPER_SHIFT) /* SSP1 transmit */ +# define GPDMA_CONFIG_DESTPER_U3TX_2 (14 << GPDMA_CONFIG_DESTPER_SHIFT) /* USART3 transmit */ +# define GPDMA_CONFIG_DESTPER_DAC (15 << GPDMA_CONFIG_DESTPER_SHIFT) /* DAC */ +# define GPDMA_CONFIG_DESTPER_SCTM3_2 (15 << GPDMA_CONFIG_DESTPER_SHIFT) /* SCT match 3 */ +# define GPDMA_CONFIG_DESTPER_SGPIO15_3 (15 << GPDMA_CONFIG_DESTPER_SHIFT) /* SGPIO15 */ +# define GPDMA_CONFIG_DESTPER_T3MAT0_2 (15 << GPDMA_CONFIG_DESTPER_SHIFT) /* Timer3 match 0 */ +#define GPDMA_CONFIG_FCNTRL_SHIFT (11) /* Bits 11-13: Flow control and transfer type */ +#define GPDMA_CONFIG_FCNTRL_MASK (7 << GPDMA_CONFIG_FCNTRL_SHIFT) +# define GPDMA_CONFIG_FCNTRL_M2M_DMA (0 << GPDMA_CONFIG_FCNTRL_SHIFT) /* Memory to memory (DMA control) */ +# define GPDMA_CONFIG_FCNTRL_M2P_DMA (1 << GPDMA_CONFIG_FCNTRL_SHIFT) /* Memory to peripheral (DMA control) */ +# define GPDMA_CONFIG_FCNTRL_P2M_DMA (2 << GPDMA_CONFIG_FCNTRL_SHIFT) /* Peripheral to memory (DMA control) */ +# define GPDMA_CONFIG_FCNTRL_P2P_DMA (3 << GPDMA_CONFIG_FCNTRL_SHIFT) /* SRC peripheral to DEST peripheral (DMA control) */ +# define GPDMA_CONFIG_FCNTRL_P2P_DEST (4 << GPDMA_CONFIG_FCNTRL_SHIFT) /* SRC peripheral to DEST peripheral (DEST control) */ +# define GPDMA_CONFIG_FCNTRL_M2P_PER (5 << GPDMA_CONFIG_FCNTRL_SHIFT) /* Memory to peripheral (peripheral control) */ +# define GPDMA_CONFIG_FCNTRL_P2M_PER (6 << GPDMA_CONFIG_FCNTRL_SHIFT) /* Peripheral to memory (peripheral control) */ +# define GPDMA_CONFIG_FCNTRL_P2P_SRC (7 << GPDMA_CONFIG_FCNTRL_SHIFT) /* SRC peripheral to DEST peripheral (SRC control) */ +#define GPDMA_CONFIG_IE (1 << 14) /* Bit 14: Interrupt error mask */ +#define GPDMA_CONFIG_ITC (1 << 15) /* Bit 15: Terminal count interrupt mask */ +#define GPDMA_CONFIG_LOCK (1 << 16) /* Bit 16: Lock */ +#define GPDMA_CONFIG_ACTIVE (1 << 17) /* Bit 17: Active */ +#define GPDMA_CONFIG_HALT (1 << 18) /* Bit 18: Halt */ + /* Bits 19-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPDMA_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_gpio.h b/arch/arm/src/lpc43xx/chip/lpc43_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..a4d0ad7ad077701814b0174b5da0b3f6064c5d0b --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_gpio.h @@ -0,0 +1,441 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_gpio.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPIO_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPIO_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + + /* Register Offsets *********************************************************************************/ + +/* Pin interrupt registers (relative to LPC43_GPIOINT_BASE) */ + +#define LPC43_GPIOINT_ISEL_OFFSET 0x0000 /* Pin Interrupt Mode register */ +#define LPC43_GPIOINT_IENR_OFFSET 0x0004 /* Pin interrupt level (rising edge) interrupt enable register */ +#define LPC43_GPIOINT_SIENR_OFFSET 0x0008 /* Pin interrupt level (rising edge) interrupt set register */ +#define LPC43_GPIOINT_CIENR_OFFSET 0x000c /* Pin interrupt level (rising edge interrupt) clear register */ +#define LPC43_GPIOINT_IENF_OFFSET 0x0010 /* Pin interrupt active level (falling edge) interrupt enable register */ +#define LPC43_GPIOINT_SIENF_OFFSET 0x0014 /* Pin interrupt active level (falling edge) interrupt set register */ +#define LPC43_GPIOINT_CIENF_OFFSET 0x0018 /* Pin interrupt active level (falling edge) interrupt clear register */ +#define LPC43_GPIOINT_RISE_OFFSET 0x001c /* Pin interrupt rising edge register */ +#define LPC43_GPIOINT_FALL_OFFSET 0x0020 /* Pin interrupt falling edge register */ +#define LPC43_GPIOINT_IST_OFFSET 0x0024 /* Pin interrupt status register */ + +/* GPIO GROUP interrupt registers (relative to either LPC43_GRP0INT_BASE or LPC43_GRP1INT_BASE) */ + +#define LPC43_GRPINT_CTRL_OFFSET 0x0000 /* GPIO grouped interrupt control register */ + +#define LPC43_GRPINT_POL_OFFSET(p) (0x0020 + ((p) << 2 )) +#define LPC43_GRPINT_POL0_OFFSET 0x0020 /* GPIO grouped interrupt port 0 polarity register */ +#define LPC43_GRPINT_POL1_OFFSET 0x0024 /* GPIO grouped interrupt port 1 polarity register */ +#define LPC43_GRPINT_POL2_OFFSET 0x0028 /* GPIO grouped interrupt port 2 polarity register */ +#define LPC43_GRPINT_POL3_OFFSET 0x002c /* GPIO grouped interrupt port 3 polarity register */ +#define LPC43_GRPINT_POL4_OFFSET 0x0030 /* GPIO grouped interrupt port 4 polarity register */ +#define LPC43_GRPINT_POL5_OFFSET 0x0034 /* GPIO grouped interrupt port 5 polarity register */ +#define LPC43_GRPINT_POL6_OFFSET 0x0038 /* GPIO grouped interrupt port 6 polarity register */ +#define LPC43_GRPINT_POL7_OFFSET 0x003c /* GPIO grouped interrupt port 7 polarity register */ + +#define LPC43_GRPINT_ENA_OFFSET(p) (0x0040 + ((p) << 2 )) +#define LPC43_GRPINT_ENA0_OFFSET 0x0040 /* GPIO grouped interrupt port 0 enable register */ +#define LPC43_GRPINT_ENA1_OFFSET 0x0044 /* GPIO grouped interrupt port 1 enable register */ +#define LPC43_GRPINT_ENA2_OFFSET 0x0048 /* GPIO grouped interrupt port 2 enable register */ +#define LPC43_GRPINT_ENA3_OFFSET 0x004c /* GPIO grouped interrupt port 3 enable register */ +#define LPC43_GRPINT_ENA4_OFFSET 0x0050 /* GPIO grouped interrupt port 4 enable register */ +#define LPC43_GRPINT_ENA5_OFFSET 0x0054 /* GPIO grouped interrupt port 5 enable register */ +#define LPC43_GRPINT_ENA6_OFFSET 0x0058 /* GPIO grouped interrupt port 5 enable register */ +#define LPC43_GRPINT_ENA7_OFFSET 0x005c /* GPIO grouped interrupt port 5 enable register */ + +/* GPIO Port Registers (relative to LPC43_GPIO_BASE) */ + +#define LPC43_GPIO_B_OFFSET(p,n) (((p) << 5) + (n)) +#define LPC43_GPIO_B0_OFFSET(n) (0x0000 + (n)) /* PIO0_0 to PIO0_31 byte pin registers */ +#define LPC43_GPIO_B1_OFFSET(n) (0x0020 + (n)) /* PIO1_0 to PIO1_31 byte pin registers */ +#define LPC43_GPIO_B2_OFFSET(n) (0x0040 + (n)) /* PIO2_0 to PIO2_31 byte pin registers */ +#define LPC43_GPIO_B3_OFFSET(n) (0x0060 + (n)) /* PIO3_0 to PIO3_31 byte pin registers */ +#define LPC43_GPIO_B4_OFFSET(n) (0x0080 + (n)) /* PIO4_0 to PIO4_31 byte pin registers */ +#define LPC43_GPIO_B5_OFFSET(n) (0x00a0 + (n)) /* PIO5_0 to PIO5_31 byte pin registers */ +#define LPC43_GPIO_B6_OFFSET(n) (0x00c0 + (n)) /* PIO6_0 to PIO6_31 byte pin registers */ +#define LPC43_GPIO_B7_OFFSET(n) (0x00e0 + (n)) /* PIO7_0 to PIO7_31 byte pin registers */ + +#define LPC43_GPIO_W_OFFSET(p,n) (0x1000 + ((p) << 7) + ((n) << 2)) +#define LPC43_GPIO_W0_OFFSET(n) (0x1000 + ((n) << 2)) /* PIO0_0 to PIO0_31 word pin registers */ +#define LPC43_GPIO_W1_OFFSET(n) (0x1080 + ((n) << 2)) /* PIO1_0 to PIO1_31 word pin registers */ +#define LPC43_GPIO_W2_OFFSET(n) (0x1100 + ((n) << 2)) /* PIO2_0 to PIO2_31 word pin registers */ +#define LPC43_GPIO_W3_OFFSET(n) (0x1180 + ((n) << 2)) /* PIO3_0 to PIO3_31 word pin registers */ +#define LPC43_GPIO_W4_OFFSET(n) (0x1200 + ((n) << 2)) /* PIO4_0 to PIO4_31 word pin registers */ +#define LPC43_GPIO_W5_OFFSET(n) (0x1280 + ((n) << 2)) /* PIO5_0 to PIO5_31 word pin registers */ +#define LPC43_GPIO_W6_OFFSET(n) (0x1300 + ((n) << 2)) /* PIO6_0 to PIO6_31 word pin registers */ +#define LPC43_GPIO_W7_OFFSET(n) (0x1380 + ((n) << 2)) /* PIO7_0 to PIO7_31 word pin registers */ + +#define LPC43_GPIO_DIR_OFFSET(p) (0x2000 + ((p) << 2)) +#define LPC43_GPIO_DIR0_OFFSET 0x2000 /* Direction registers port 0 */ +#define LPC43_GPIO_DIR1_OFFSET 0x2004 /* Direction registers port 1 */ +#define LPC43_GPIO_DIR2_OFFSET 0x2008 /* Direction registers port 2 */ +#define LPC43_GPIO_DIR3_OFFSET 0x200c /* Direction registers port 3 */ +#define LPC43_GPIO_DIR4_OFFSET 0x2010 /* Direction registers port 4 */ +#define LPC43_GPIO_DIR5_OFFSET 0x2014 /* Direction registers port 5 */ +#define LPC43_GPIO_DIR6_OFFSET 0x2018 /* Direction registers port 6 */ +#define LPC43_GPIO_DIR7_OFFSET 0x201c /* Direction registers port 7 */ + +#define LPC43_GPIO_MASK_OFFSET(p) (0x2080 + ((p) << 2)) +#define LPC43_GPIO_MASK0_OFFSET 0x2080 /* Mask register port 0 */ +#define LPC43_GPIO_MASK1_OFFSET 0x2084 /* Mask register port 1 */ +#define LPC43_GPIO_MASK2_OFFSET 0x2088 /* Mask register port 2 */ +#define LPC43_GPIO_MASK3_OFFSET 0x208c /* Mask register port 3 */ +#define LPC43_GPIO_MASK4_OFFSET 0x2090 /* Mask register port 4 */ +#define LPC43_GPIO_MASK5_OFFSET 0x2094 /* Mask register port 5 */ +#define LPC43_GPIO_MASK6_OFFSET 0x2098 /* Mask register port 6 */ +#define LPC43_GPIO_MASK7_OFFSET 0x209c /* Mask register port 7 */ + +#define LPC43_GPIO_PIN_OFFSET(p) (0x2100 + ((p) << 2)) +#define LPC43_GPIO_PIN0_OFFSET 0x2100 /* Port pin register port 0 */ +#define LPC43_GPIO_PIN1_OFFSET 0x2104 /* Port pin register port 1 */ +#define LPC43_GPIO_PIN2_OFFSET 0x2108 /* Port pin register port 2 */ +#define LPC43_GPIO_PIN3_OFFSET 0x210c /* Port pin register port 3 */ +#define LPC43_GPIO_PIN4_OFFSET 0x2110 /* Port pin register port 4 */ +#define LPC43_GPIO_PIN5_OFFSET 0x2114 /* Port pin register port 5 */ +#define LPC43_GPIO_PIN6_OFFSET 0x2118 /* Port pin register port 6 */ +#define LPC43_GPIO_PIN7_OFFSET 0x211c /* Port pin register port 7 */ + +#define LPC43_GPIO_MPIN_OFFSET(p) (0x2100 + ((p) << 2)) +#define LPC43_GPIO_MPIN0_OFFSET 0x2180 /* Masked port register port 0 */ +#define LPC43_GPIO_MPIN1_OFFSET 0x2184 /* Masked port register port 1 */ +#define LPC43_GPIO_MPIN2_OFFSET 0x2188 /* Masked port register port 2 */ +#define LPC43_GPIO_MPIN3_OFFSET 0x218c /* Masked port register port 3 */ +#define LPC43_GPIO_MPIN4_OFFSET 0x2190 /* Masked port register port 4 */ +#define LPC43_GPIO_MPIN5_OFFSET 0x2194 /* Masked port register port 5 */ +#define LPC43_GPIO_MPIN6_OFFSET 0x2198 /* Masked port register port 6 */ +#define LPC43_GPIO_MPIN7_OFFSET 0x219c /* Masked port register port 7 */ + +#define LPC43_GPIO_SET_OFFSET(p) (0x2200 + ((p) << 2)) +#define LPC43_GPIO_SET0_OFFSET 0x2200 /* Write: Set register for port 0 */ +#define LPC43_GPIO_SET1_OFFSET 0x2204 /* Write: Set register for port 1 */ +#define LPC43_GPIO_SET2_OFFSET 0x2208 /* Write: Set register for port 2 */ +#define LPC43_GPIO_SET3_OFFSET 0x220c /* Write: Set register for port 3 */ +#define LPC43_GPIO_SET4_OFFSET 0x2210 /* Write: Set register for port 4 */ +#define LPC43_GPIO_SET5_OFFSET 0x2214 /* Write: Set register for port 5 */ +#define LPC43_GPIO_SET6_OFFSET 0x2218 /* Write: Set register for port 6 */ +#define LPC43_GPIO_SET7_OFFSET 0x221c /* Write: Set register for port 7 */ + +#define LPC43_GPIO_CLR_OFFSET(p) (0x2280 + ((p) << 2)) +#define LPC43_GPIO_CLR0_OFFSET 0x2280 /* Clear port 0 */ +#define LPC43_GPIO_CLR1_OFFSET 0x2284 /* Clear port 1 */ +#define LPC43_GPIO_CLR2_OFFSET 0x2288 /* Clear port 2 */ +#define LPC43_GPIO_CLR3_OFFSET 0x228c /* Clear port 3 */ +#define LPC43_GPIO_CLR4_OFFSET 0x2290 /* Clear port 4 */ +#define LPC43_GPIO_CLR5_OFFSET 0x2294 /* Clear port 5 */ +#define LPC43_GPIO_CLR6_OFFSET 0x2298 /* Clear port 6 */ +#define LPC43_GPIO_CLR7_OFFSET 0x229c /* Clear port 7 */ + +#define LPC43_GPIO_NOT_OFFSET(p) (0x2300 + ((p) << 2)) +#define LPC43_GPIO_NOT0_OFFSET 0x2300 /* Toggle port 0 */ +#define LPC43_GPIO_NOT1_OFFSET 0x2304 /* Toggle port 1 */ +#define LPC43_GPIO_NOT2_OFFSET 0x2308 /* Toggle port 2 */ +#define LPC43_GPIO_NOT3_OFFSET 0x230c /* Toggle port 3 */ +#define LPC43_GPIO_NOT4_OFFSET 0x2310 /* Toggle port 4 */ +#define LPC43_GPIO_NOT5_OFFSET 0x2314 /* Toggle port 5 */ +#define LPC43_GPIO_NOT6_OFFSET 0x2318 /* Toggle port 6 */ +#define LPC43_GPIO_NOT7_OFFSET 0x231c /* Toggle port 7 */ + +/* Register Addresses *******************************************************************************/ + +/* Pin interrupt registers (relative to LPC43_GPIOINT_BASE) */ + +#define LPC43_GPIOINT_ISEL (LPC43_GPIOINT_BASE+LPC43_GPIOINT_ISEL_OFFSET) +#define LPC43_GPIOINT_IENR (LPC43_GPIOINT_BASE+LPC43_GPIOINT_IENR_OFFSET) +#define LPC43_GPIOINT_SIENR (LPC43_GPIOINT_BASE+LPC43_GPIOINT_SIENR_OFFSET) +#define LPC43_GPIOINT_CIENR (LPC43_GPIOINT_BASE+LPC43_GPIOINT_CIENR_OFFSET) +#define LPC43_GPIOINT_IENF (LPC43_GPIOINT_BASE+LPC43_GPIOINT_IENF_OFFSET) +#define LPC43_GPIOINT_SIENF (LPC43_GPIOINT_BASE+LPC43_GPIOINT_SIENF_OFFSET) +#define LPC43_GPIOINT_CIENF (LPC43_GPIOINT_BASE+LPC43_GPIOINT_CIENF_OFFSET) +#define LPC43_GPIOINT_RISE (LPC43_GPIOINT_BASE+LPC43_GPIOINT_RISE_OFFSET) +#define LPC43_GPIOINT_FALL (LPC43_GPIOINT_BASE+LPC43_GPIOINT_FALL_OFFSET) +#define LPC43_GPIOINT_IST (LPC43_GPIOINT_BASE+LPC43_GPIOINT_IST_OFFSET) + +/* GPIO GROUP0 interrupt registers (relative to LPC43_GRP0INT_BASE) */ + +#define LPC43_GRP0INT_CTRL (LPC43_GRP0INT_BASE+LPC43_GRPINT_CTRL_OFFSET) + +#define LPC43_GRP0INT_POL(p) (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL_OFFSET(p)) +#define LPC43_GRP0INT_POL0 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL0_OFFSET) +#define LPC43_GRP0INT_POL1 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL1_OFFSET) +#define LPC43_GRP0INT_POL2 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL2_OFFSET) +#define LPC43_GRP0INT_POL3 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL3_OFFSET) +#define LPC43_GRP0INT_POL4 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL4_OFFSET) +#define LPC43_GRP0INT_POL5 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL5_OFFSET) +#define LPC43_GRP0INT_POL6 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL6_OFFSET) +#define LPC43_GRP0INT_POL7 (LPC43_GRP0INT_BASE+LPC43_GRPINT_POL7_OFFSET) + +#define LPC43_GRP0INT_ENA(p) (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA_OFFSET(p)) +#define LPC43_GRP0INT_ENA0 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA0_OFFSET) +#define LPC43_GRP0INT_ENA1 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA1_OFFSET) +#define LPC43_GRP0INT_ENA2 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA2_OFFSET) +#define LPC43_GRP0INT_ENA3 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA3_OFFSET) +#define LPC43_GRP0INT_ENA4 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA4_OFFSET) +#define LPC43_GRP0INT_ENA5 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA5_OFFSET) +#define LPC43_GRP0INT_ENA6 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA6_OFFSET) +#define LPC43_GRP0INT_ENA7 (LPC43_GRP0INT_BASE+LPC43_GRPINT_ENA7_OFFSET) + +/* GPIO GROUP1 interrupt registers (relative to LPC43_GRP1INT_BASE) */ + +#define LPC43_GRP1INT_CTRL (LPC43_GRP1INT_BASE+LPC43_GRPINT_CTRL_OFFSET) + +#define LPC43_GRP1INT_POL(p) (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL_OFFSET(p)) +#define LPC43_GRP1INT_POL0 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL0_OFFSET) +#define LPC43_GRP1INT_POL1 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL1_OFFSET) +#define LPC43_GRP1INT_POL2 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL2_OFFSET) +#define LPC43_GRP1INT_POL3 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL3_OFFSET) +#define LPC43_GRP1INT_POL4 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL4_OFFSET) +#define LPC43_GRP1INT_POL5 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL5_OFFSET) +#define LPC43_GRP1INT_POL6 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL6_OFFSET) +#define LPC43_GRP1INT_POL7 (LPC43_GRP1INT_BASE+LPC43_GRPINT_POL7_OFFSET) + +#define LPC43_GRP1INT_ENA(p) (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA_OFFSET(p)) +#define LPC43_GRP1INT_ENA0 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA0_OFFSET) +#define LPC43_GRP1INT_ENA1 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA1_OFFSET) +#define LPC43_GRP1INT_ENA2 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA2_OFFSET) +#define LPC43_GRP1INT_ENA3 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA3_OFFSET) +#define LPC43_GRP1INT_ENA4 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA4_OFFSET) +#define LPC43_GRP1INT_ENA5 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA5_OFFSET) +#define LPC43_GRP1INT_ENA6 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA6_OFFSET) +#define LPC43_GRP1INT_ENA7 (LPC43_GRP1INT_BASE+LPC43_GRPINT_ENA7_OFFSET) + +/* GPIO Port Registers (relative to LPC43_GPIO_BASE) */ + +#define LPC43_GPIO_B(p,n) (LPC43_GPIO_BASE+LPC43_GPIO_B_OFFSET(p,n)) +#define LPC43_GPIO_B0(n) (LPC43_GPIO_BASE+LPC43_GPIO_B0_OFFSET(n)) +#define LPC43_GPIO_B1(n) (LPC43_GPIO_BASE+LPC43_GPIO_B1_OFFSET(n)) +#define LPC43_GPIO_B2(n) (LPC43_GPIO_BASE+LPC43_GPIO_B2_OFFSET(n)) +#define LPC43_GPIO_B3(n) (LPC43_GPIO_BASE+LPC43_GPIO_B3_OFFSET(n)) +#define LPC43_GPIO_B4(n) (LPC43_GPIO_BASE+LPC43_GPIO_B4_OFFSET(n)) +#define LPC43_GPIO_B5(n) (LPC43_GPIO_BASE+LPC43_GPIO_B5_OFFSET(n)) +#define LPC43_GPIO_B6(n) (LPC43_GPIO_BASE+LPC43_GPIO_B6_OFFSET(n)) +#define LPC43_GPIO_B7(n) (LPC43_GPIO_BASE+LPC43_GPIO_B7_OFFSET(n)) + +#define LPC43_GPIO_W(p,n) (LPC43_GPIO_BASE+LPC43_GPIO_W_OFFSET(p,n)) +#define LPC43_GPIO_W0(n) (LPC43_GPIO_BASE+LPC43_GPIO_W0_OFFSET(n)) +#define LPC43_GPIO_W1(n) (LPC43_GPIO_BASE+LPC43_GPIO_W1_OFFSET(n)) +#define LPC43_GPIO_W2(n) (LPC43_GPIO_BASE+LPC43_GPIO_W2_OFFSET(n)) +#define LPC43_GPIO_W3(n) (LPC43_GPIO_BASE+LPC43_GPIO_W3_OFFSET(n)) +#define LPC43_GPIO_W4(n) (LPC43_GPIO_BASE+LPC43_GPIO_W4_OFFSET(n)) +#define LPC43_GPIO_W5(n) (LPC43_GPIO_BASE+LPC43_GPIO_W5_OFFSET(n)) +#define LPC43_GPIO_W6(n) (LPC43_GPIO_BASE+LPC43_GPIO_W6_OFFSET(n)) +#define LPC43_GPIO_W7(n) (LPC43_GPIO_BASE+LPC43_GPIO_W7_OFFSET(n)) + +#define LPC43_GPIO_DIR(p) (LPC43_GPIO_BASE+LPC43_GPIO_DIR_OFFSET(p)) +#define LPC43_GPIO_DIR0 (LPC43_GPIO_BASE+LPC43_GPIO_DIR0_OFFSET) +#define LPC43_GPIO_DIR1 (LPC43_GPIO_BASE+LPC43_GPIO_DIR1_OFFSET) +#define LPC43_GPIO_DIR2 (LPC43_GPIO_BASE+LPC43_GPIO_DIR2_OFFSET) +#define LPC43_GPIO_DIR3 (LPC43_GPIO_BASE+LPC43_GPIO_DIR3_OFFSET) +#define LPC43_GPIO_DIR4 (LPC43_GPIO_BASE+LPC43_GPIO_DIR4_OFFSET) +#define LPC43_GPIO_DIR5 (LPC43_GPIO_BASE+LPC43_GPIO_DIR5_OFFSET) +#define LPC43_GPIO_DIR6 (LPC43_GPIO_BASE+LPC43_GPIO_DIR6_OFFSET) +#define LPC43_GPIO_DIR7 (LPC43_GPIO_BASE+LPC43_GPIO_DIR7_OFFSET) + +#define LPC43_GPIO_MASK(p) (LPC43_GPIO_BASE+LPC43_GPIO_MASK_OFFSET(p)) +#define LPC43_GPIO_MASK0 (LPC43_GPIO_BASE+LPC43_GPIO_MASK0_OFFSET) +#define LPC43_GPIO_MASK1 (LPC43_GPIO_BASE+LPC43_GPIO_MASK1_OFFSET) +#define LPC43_GPIO_MASK2 (LPC43_GPIO_BASE+LPC43_GPIO_MASK2_OFFSET) +#define LPC43_GPIO_MASK3 (LPC43_GPIO_BASE+LPC43_GPIO_MASK3_OFFSET) +#define LPC43_GPIO_MASK4 (LPC43_GPIO_BASE+LPC43_GPIO_MASK4_OFFSET) +#define LPC43_GPIO_MASK5 (LPC43_GPIO_BASE+LPC43_GPIO_MASK5_OFFSET) +#define LPC43_GPIO_MASK6 (LPC43_GPIO_BASE+LPC43_GPIO_MASK6_OFFSET) +#define LPC43_GPIO_MASK7 (LPC43_GPIO_BASE+LPC43_GPIO_MASK7_OFFSET) + +#define LPC43_GPIO_PIN(p) (LPC43_GPIO_BASE+LPC43_GPIO_PIN_OFFSET(p)) +#define LPC43_GPIO_PIN0 (LPC43_GPIO_BASE+LPC43_GPIO_PIN0_OFFSET) +#define LPC43_GPIO_PIN1 (LPC43_GPIO_BASE+LPC43_GPIO_PIN1_OFFSET) +#define LPC43_GPIO_PIN2 (LPC43_GPIO_BASE+LPC43_GPIO_PIN2_OFFSET) +#define LPC43_GPIO_PIN3 (LPC43_GPIO_BASE+LPC43_GPIO_PIN3_OFFSET) +#define LPC43_GPIO_PIN4 (LPC43_GPIO_BASE+LPC43_GPIO_PIN4_OFFSET) +#define LPC43_GPIO_PIN5 (LPC43_GPIO_BASE+LPC43_GPIO_PIN5_OFFSET) +#define LPC43_GPIO_PIN6 (LPC43_GPIO_BASE+LPC43_GPIO_PIN6_OFFSET) +#define LPC43_GPIO_PIN7 (LPC43_GPIO_BASE+LPC43_GPIO_PIN7_OFFSET) + +#define LPC43_GPIO_MPIN(p) (LPC43_GPIO_BASE+LPC43_GPIO_MPIN_OFFSET(p)) +#define LPC43_GPIO_MPIN0 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN0_OFFSET) +#define LPC43_GPIO_MPIN1 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN1_OFFSET) +#define LPC43_GPIO_MPIN2 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN2_OFFSET) +#define LPC43_GPIO_MPIN3 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN3_OFFSET) +#define LPC43_GPIO_MPIN4 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN4_OFFSET) +#define LPC43_GPIO_MPIN5 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN5_OFFSET) +#define LPC43_GPIO_MPIN6 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN6_OFFSET) +#define LPC43_GPIO_MPIN7 (LPC43_GPIO_BASE+LPC43_GPIO_MPIN7_OFFSET) + +#define LPC43_GPIO_SET(p) (LPC43_GPIO_BASE+LPC43_GPIO_SET_OFFSET(p)) +#define LPC43_GPIO_SET0 (LPC43_GPIO_BASE+LPC43_GPIO_SET0_OFFSET) +#define LPC43_GPIO_SET1 (LPC43_GPIO_BASE+LPC43_GPIO_SET1_OFFSET) +#define LPC43_GPIO_SET2 (LPC43_GPIO_BASE+LPC43_GPIO_SET2_OFFSET) +#define LPC43_GPIO_SET3 (LPC43_GPIO_BASE+LPC43_GPIO_SET3_OFFSET) +#define LPC43_GPIO_SET4 (LPC43_GPIO_BASE+LPC43_GPIO_SET4_OFFSET) +#define LPC43_GPIO_SET5 (LPC43_GPIO_BASE+LPC43_GPIO_SET5_OFFSET) +#define LPC43_GPIO_SET6 (LPC43_GPIO_BASE+LPC43_GPIO_SET6_OFFSET) +#define LPC43_GPIO_SET7 (LPC43_GPIO_BASE+LPC43_GPIO_SET7_OFFSET) + +#define LPC43_GPIO_CLR(p) (LPC43_GPIO_BASE+LPC43_GPIO_CLR_OFFSET(p)) +#define LPC43_GPIO_CLR0 (LPC43_GPIO_BASE+LPC43_GPIO_CLR0_OFFSET) +#define LPC43_GPIO_CLR1 (LPC43_GPIO_BASE+LPC43_GPIO_CLR1_OFFSET) +#define LPC43_GPIO_CLR2 (LPC43_GPIO_BASE+LPC43_GPIO_CLR2_OFFSET) +#define LPC43_GPIO_CLR3 (LPC43_GPIO_BASE+LPC43_GPIO_CLR3_OFFSET) +#define LPC43_GPIO_CLR4 (LPC43_GPIO_BASE+LPC43_GPIO_CLR4_OFFSET) +#define LPC43_GPIO_CLR5 (LPC43_GPIO_BASE+LPC43_GPIO_CLR5_OFFSET) +#define LPC43_GPIO_CLR6 (LPC43_GPIO_BASE+LPC43_GPIO_CLR6_OFFSET) +#define LPC43_GPIO_CLR7 (LPC43_GPIO_BASE+LPC43_GPIO_CLR7_OFFSET) + +#define LPC43_GPIO_NOT(p) (LPC43_GPIO_BASE+LPC43_GPIO_NOT_OFFSET(p)) +#define LPC43_GPIO_NOT0 (LPC43_GPIO_BASE+LPC43_GPIO_NOT0_OFFSET) +#define LPC43_GPIO_NOT1 (LPC43_GPIO_BASE+LPC43_GPIO_NOT1_OFFSET) +#define LPC43_GPIO_NOT2 (LPC43_GPIO_BASE+LPC43_GPIO_NOT2_OFFSET) +#define LPC43_GPIO_NOT3 (LPC43_GPIO_BASE+LPC43_GPIO_NOT3_OFFSET) +#define LPC43_GPIO_NOT4 (LPC43_GPIO_BASE+LPC43_GPIO_NOT4_OFFSET) +#define LPC43_GPIO_NOT5 (LPC43_GPIO_BASE+LPC43_GPIO_NOT5_OFFSET) +#define LPC43_GPIO_NOT6 (LPC43_GPIO_BASE+LPC43_GPIO_NOT6_OFFSET) +#define LPC43_GPIO_NOT7 (LPC43_GPIO_BASE+LPC43_GPIO_NOT7_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Pin Interrupt Mode register */ + +#define GPIOINT_ISEL(i) (1 << (i)) /* Bits 0-7: Selects the interrupt mode */ + +/* Pin interrupt level (rising edge) interrupt enable register */ + +#define GPIOINT_IENR(i) (1 << (i)) /* Bits 0-7: Enables the rising edge or level interrupt */ + +/* Pin interrupt level (rising edge) interrupt set register */ + +#define GPIOINT_SIENR(i) (1 << (i)) /* Bits 0-7: Set bits in the IENR, enabling interrupts */ + +/* Pin interrupt level (rising edge interrupt) clear register */ + +#define GPIOINT_CIENR(i) (1 << (i)) /* Bits 0-7: Clears bits in the IENR, disabling interrupts */ + +/* Pin interrupt active level (falling edge) interrupt enable register */ + +#define GPIOINT_IENF(i) (1 << (i)) /* Bits 0-7: Enables the falling edge or configures the active level interrupt */ + +/* Pin interrupt active level (falling edge) interrupt set register */ + +#define GPIOINT_SIENF(i) (1 << (i)) /* Bits 0-7: Set bits in the IENF, enabling interrupts */ + +/* Pin interrupt active level (falling edge) interrupt clear register */ + +#define GPIOINT_CIENF(i) (1 << (i)) /* Bits 0-7: Clears bits in the IENF, disabling interrupts */ + +/* Pin interrupt rising edge register */ + +#define GPIOINT_RISE(i) (1 << (i)) /* Bits 0-7: Rising edge detect */ + +/* Pin interrupt falling edge register */ + +#define GPIOINT_FALL(i) (1 << (i)) /* Bits 0-7: Falling edge detect */ + +/* Pin interrupt status register */ + +#define GPIOINT_IST(i) (1 << (i)) /* Bits 0-7: Pin interrupt status */ + +/* GPIO grouped interrupt control registers */ + +#define GRPINT_CTRL_INT (1 << 0) /* Bit 0: Group interrupt status */ +#define GRPINT_CTRL_COMB (1 << 1) /* Bit 1: Combine enabled inputs for group interrupt */ +#define GRPINT_CTRL_TRIG (1 << 2) /* Bit 2: Group interrupt trigger */ + /* Bits 3-31: Reserved */ +/* GPIO grouped interrupt polarity registers */ + +#define GRPINT_POL(p) (1 << (p)) /* Bits 0-31: Configure polarity of port pins */ + +/* GPIO grouped interrupt enable registers */ + +#define GRPINT_ENA(p) (1 << (p)) /* Bits 0-31: Enable pin for group interrupt */ + +/* Byte pin registers */ + +#define GPIO_B (1 << 0) /* Bit 0: State of GPIO pin */ + /* Bits 1-7: Reserved */ +/* Byte word registers. On Read: 0x00000000 or 0xffffffff. On write 0x0000000 or any + * non-zero value + */ + +/* Direction registers */ + +#define GPIO_DIR(p) (1 << (p)) /* Bits 0-31: Selects pin direction for pin */ + +/* Mask registers */ + +#define GPIO_MASK(p) (1 << (p)) /* Bits 0-31: Controls which bits are active */ + +/* Port pin registers */ + +#define GPIO_PIN(p) (1 << (p)) /* Bits 0-31: Read/write pin state */ + +/* Masked port registers */ + +#define GPIO_MPIN(p) (1 << (p)) /* Bits 0-31: Read/write masked pin state */ + +/* Write: Set registers */ + +#define GPIO_SET(p) (1 << (p)) /* Bits 0-31: Read or set output bits */ + +/* Write: Clear registers */ + +#define GPIO_CLR(p) (1 << (p)) /* Bits 0-31: Clear output bits */ + +/* Toggle registers */ + +#define GPIO_NOT(p) (1 << (p)) /* Bits 0-31: Toggle output bits */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_GPIO_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_i2c.h b/arch/arm/src/lpc43xx/chip/lpc43_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..000fbed5151f9d6ec3e29170ac9a6f728c0fae88 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_i2c.h @@ -0,0 +1,205 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_i2c.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2C_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_I2C_CONSET_OFFSET 0x0000 /* I2C Control Set Register */ +#define LPC43_I2C_STAT_OFFSET 0x0004 /* I2C Status Register */ +#define LPC43_I2C_DAT_OFFSET 0x0008 /* I2C Data Register */ +#define LPC43_I2C_ADR0_OFFSET 0x000c /* I2C Slave Address Register 0 */ +#define LPC43_I2C_SCLH_OFFSET 0x0010 /* SCH Duty Cycle Register High Half Word */ +#define LPC43_I2C_SCLL_OFFSET 0x0014 /* SCL Duty Cycle Register Low Half Word */ +#define LPC43_I2C_CONCLR_OFFSET 0x0018 /* I2C Control Clear Register */ +#define LPC43_I2C_MMCTRL_OFFSET 0x001c /* Monitor mode control register */ +#define LPC43_I2C_ADR1_OFFSET 0x0020 /* I2C Slave Address Register 1 */ +#define LPC43_I2C_ADR2_OFFSET 0x0024 /* I2C Slave Address Register 2 */ +#define LPC43_I2C_ADR3_OFFSET 0x0028 /* I2C Slave Address Register 3 */ +#define LPC43_I2C_BUFR_OFFSET 0x002c /* Data buffer register */ +#define LPC43_I2C_MASK0_OFFSET 0x0030 /* I2C Slave address mask register 0 */ +#define LPC43_I2C_MASK1_OFFSET 0x0034 /* I2C Slave address mask register 1 */ +#define LPC43_I2C_MASK2_OFFSET 0x0038 /* I2C Slave address mask register 2 */ +#define LPC43_I2C_MASK3_OFFSET 0x003c /* I2C Slave address mask register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_I2C0_CONSET (LPC43_I2C0_BASE+LPC43_I2C_CONSET_OFFSET) +#define LPC43_I2C0_STAT (LPC43_I2C0_BASE+LPC43_I2C_STAT_OFFSET) +#define LPC43_I2C0_DAT (LPC43_I2C0_BASE+LPC43_I2C_DAT_OFFSET) +#define LPC43_I2C0_ADR0 (LPC43_I2C0_BASE+LPC43_I2C_ADR0_OFFSET) +#define LPC43_I2C0_SCLH (LPC43_I2C0_BASE+LPC43_I2C_SCLH_OFFSET) +#define LPC43_I2C0_SCLL (LPC43_I2C0_BASE+LPC43_I2C_SCLL_OFFSET) +#define LPC43_I2C0_CONCLR (LPC43_I2C0_BASE+LPC43_I2C_CONCLR_OFFSET) +#define LPC43_I2C0_MMCTRL (LPC43_I2C0_BASE+LPC43_I2C_MMCTRL_OFFSET) +#define LPC43_I2C0_ADR1 (LPC43_I2C0_BASE+LPC43_I2C_ADR1_OFFSET) +#define LPC43_I2C0_ADR2 (LPC43_I2C0_BASE+LPC43_I2C_ADR2_OFFSET) +#define LPC43_I2C0_ADR3 (LPC43_I2C0_BASE+LPC43_I2C_ADR3_OFFSET) +#define LPC43_I2C0_BUFR (LPC43_I2C0_BASE+LPC43_I2C_BUFR_OFFSET) +#define LPC43_I2C0_MASK0 (LPC43_I2C0_BASE+LPC43_I2C_MASK0_OFFSET) +#define LPC43_I2C0_MASK1 (LPC43_I2C0_BASE+LPC43_I2C_MASK1_OFFSET) +#define LPC43_I2C0_MASK2 (LPC43_I2C0_BASE+LPC43_I2C_MASK2_OFFSET) +#define LPC43_I2C0_MASK3 (LPC43_I2C0_BASE+LPC43_I2C_MASK3_OFFSET) + +#define LPC43_I2C1_CONSET (LPC43_I2C1_BASE+LPC43_I2C_CONSET_OFFSET) +#define LPC43_I2C1_STAT (LPC43_I2C1_BASE+LPC43_I2C_STAT_OFFSET) +#define LPC43_I2C1_DAT (LPC43_I2C1_BASE+LPC43_I2C_DAT_OFFSET) +#define LPC43_I2C1_ADR0 (LPC43_I2C1_BASE+LPC43_I2C_ADR0_OFFSET) +#define LPC43_I2C1_SCLH (LPC43_I2C1_BASE+LPC43_I2C_SCLH_OFFSET) +#define LPC43_I2C1_SCLL (LPC43_I2C1_BASE+LPC43_I2C_SCLL_OFFSET) +#define LPC43_I2C1_CONCLR (LPC43_I2C1_BASE+LPC43_I2C_CONCLR_OFFSET) +#define LPC43_I2C1_MMCTRL (LPC43_I2C1_BASE+LPC43_I2C_MMCTRL_OFFSET) +#define LPC43_I2C1_ADR1 (LPC43_I2C1_BASE+LPC43_I2C_ADR1_OFFSET) +#define LPC43_I2C1_ADR2 (LPC43_I2C1_BASE+LPC43_I2C_ADR2_OFFSET) +#define LPC43_I2C1_ADR3 (LPC43_I2C1_BASE+LPC43_I2C_ADR3_OFFSET) +#define LPC43_I2C1_BUFR (LPC43_I2C1_BASE+LPC43_I2C_BUFR_OFFSET) +#define LPC43_I2C1_MASK0 (LPC43_I2C1_BASE+LPC43_I2C_MASK0_OFFSET) +#define LPC43_I2C1_MASK1 (LPC43_I2C1_BASE+LPC43_I2C_MASK1_OFFSET) +#define LPC43_I2C1_MASK2 (LPC43_I2C1_BASE+LPC43_I2C_MASK2_OFFSET) +#define LPC43_I2C1_MASK3 (LPC43_I2C1_BASE+LPC43_I2C_MASK3_OFFSET) + +#define LPC43_I2C2_CONSET (LPC43_I2C2_BASE+LPC43_I2C_CONSET_OFFSET) +#define LPC43_I2C2_STAT (LPC43_I2C2_BASE+LPC43_I2C_STAT_OFFSET) +#define LPC43_I2C2_DAT (LPC43_I2C2_BASE+LPC43_I2C_DAT_OFFSET) +#define LPC43_I2C2_ADR0 (LPC43_I2C2_BASE+LPC43_I2C_ADR0_OFFSET) +#define LPC43_I2C2_SCLH (LPC43_I2C2_BASE+LPC43_I2C_SCLH_OFFSET) +#define LPC43_I2C2_SCLL (LPC43_I2C2_BASE+LPC43_I2C_SCLL_OFFSET) +#define LPC43_I2C2_CONCLR (LPC43_I2C2_BASE+LPC43_I2C_CONCLR_OFFSET) +#define LPC43_I2C2_MMCTRL (LPC43_I2C2_BASE+LPC43_I2C_MMCTRL_OFFSET) +#define LPC43_I2C2_ADR1 (LPC43_I2C2_BASE+LPC43_I2C_ADR1_OFFSET) +#define LPC43_I2C2_ADR2 (LPC43_I2C2_BASE+LPC43_I2C_ADR2_OFFSET) +#define LPC43_I2C2_ADR3 (LPC43_I2C2_BASE+LPC43_I2C_ADR3_OFFSET) +#define LPC43_I2C2_BUFR (LPC43_I2C2_BASE+LPC43_I2C_BUFR_OFFSET) +#define LPC43_I2C2_MASK0 (LPC43_I2C2_BASE+LPC43_I2C_MASK0_OFFSET) +#define LPC43_I2C2_MASK1 (LPC43_I2C2_BASE+LPC43_I2C_MASK1_OFFSET) +#define LPC43_I2C2_MASK2 (LPC43_I2C2_BASE+LPC43_I2C_MASK2_OFFSET) +#define LPC43_I2C2_MASK3 (LPC43_I2C2_BASE+LPC43_I2C_MASK3_OFFSET) + +/* Register bit definitions *********************************************************/ +/* I2C Control Set Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONSET_AA (1 << 2) /* Bit 2: Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* Bit 3: I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* Bit 4: STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* Bit 5: START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* Bit 6: I2C interface enable */ + /* Bits 7-31: Reserved */ +/* I2C Control Clear Register */ + /* Bits 0-1: Reserved */ +#define I2C_CONCLR_AAC (1 << 2) /* Bit 2: Assert acknowledge Clear bit */ +#define I2C_CONCLR_SIC (1 << 3) /* Bit 3: I2C interrupt Clear bit */ + /* Bit 4: Reserved */ +#define I2C_CONCLR_STAC (1 << 5) /* Bit 5: START flag Clear bit */ +#define I2C_CONCLRT_I2ENC (1 << 6) /* Bit 6: I2C interface Disable bit */ + /* Bits 7-31: Reserved */ +/* I2C Status Register + * + * See tables 997-1002 in the "LPC43xx User Manual" (UM10503), Rev. 1.2, 8 June + * 2012, NXP for definitions of status codes. + */ + +#define I2C_STAT_MASK (0xff) /* Bits 0-7: I2C interface status + * Bits 0-2 always zero */ + /* Bits 8-31: Reserved */ +/* I2C Data Register */ + +#define I2C_DAT_MASK (0xff) /* Bits 0-7: I2C data */ + /* Bits 8-31: Reserved */ +/* Monitor mode control register */ + +#define I2C_MMCTRL_MMENA (1 << 0) /* Bit 0: Monitor mode enable */ +#define I2C_MMCTRL_ENASCL (1 << 1) /* Bit 1: SCL output enable */ +#define I2C_MMCTRL_MATCHALL (1 << 2) /* Bit 2: Select interrupt register match */ + /* Bits 3-31: Reserved */ +/* Data buffer register */ + +#define I2C_BUFR_MASK (0xff) /* Bits 0-7: 8 MSBs of the I2DAT shift register */ + /* Bits 8-31: Reserved */ +/* I2C Slave address registers: + * + * I2C Slave Address Register 0 + * I2C Slave Address Register 1 + * I2C Slave Address Register 2 + * I2C Slave Address Register 3 + */ + +#define I2C_ADR_GC (1 << 0) /* Bit 0: GC General Call enable bit */ +#define I2C_ADR_ADDR_SHIFT (1) /* Bits 1-7: I2C slave address */ +#define I2C_ADR_ADDR_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* I2C Slave address mask registers: + * + * I2C Slave address mask register 0 + * I2C Slave address mask register 1 + * I2C Slave address mask register 2 + * I2C Slave address mask register 3 + */ + /* Bit 0: Reserved */ +#define I2C_MASK_SHIFT (1) /* Bits 1-7: I2C mask bits */ +#define I2C_MASK_MASK (0x7f << I2C_ADR_ADDR_SHIFT) + /* Bits 8-31: Reserved */ +/* SCH Duty Cycle Register High Half Word */ + +#define I2C_SCLH_MASK (0xffff) /* Bit 0-15: Count for SCL HIGH time period selection */ + /* Bits 16-31: Reserved */ +/* SCL Duty Cycle Register Low Half Word */ + +#define I2C_SCLL_MASK (0xffff) /* Bit 0-15: Count for SCL LOW time period selection */ + /* Bits 16-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2C_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_i2s.h b/arch/arm/src/lpc43xx/chip/lpc43_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..71fc875e98f53421781aa2bdc409c33a3e74535b --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_i2s.h @@ -0,0 +1,202 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_i2s + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2S_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2S_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_I2S_DAO_OFFSET 0x0000 /* Digital Audio Output Register */ +#define LPC43_I2S_DAI_OFFSET 0x0004 /* Digital Audio Input Register */ +#define LPC43_I2S_TXFIFO_OFFSET 0x0008 /* Transmit FIFO */ +#define LPC43_I2S_RXFIFO_OFFSET 0x000c /* Receive FIFO */ +#define LPC43_I2S_STATE_OFFSET 0x0010 /* Status Feedback Register */ +#define LPC43_I2S_DMA1_OFFSET 0x0014 /* DMA Configuration Register 1 */ +#define LPC43_I2S_DMA2_OFFSET 0x0018 /* DMA Configuration Register 2 */ +#define LPC43_I2S_IRQ_OFFSET 0x001c /* Interrupt Request Control Register */ +#define LPC43_I2S_TXRATE_OFFSET 0x0020 /* Transmit MCLK divider */ +#define LPC43_I2S_RXRATE_OFFSET 0x0024 /* Receive MCLK divider */ +#define LPC43_I2S_TXBITRATE_OFFSET 0x0028 /* Transmit bit rate divider */ +#define LPC43_I2S_RXBITRATE_OFFSET 0x002c /* Receive bit rate divider */ +#define LPC43_I2S_TXMODE_OFFSET 0x0030 /* Transmit mode control */ +#define LPC43_I2S_RXMODE_OFFSET 0x0034 /* Receive mode control */ + +/* Register addresses ***************************************************************/ + +#define LPC43_I2S0_DAO (LPC43_I2S0_BASE+LPC43_I2S_DAO_OFFSET) +#define LPC43_I2S0_DAI (LPC43_I2S0_BASE+LPC43_I2S_DAI_OFFSET) +#define LPC43_I2S0_TXFIFO (LPC43_I2S0_BASE+LPC43_I2S_TXFIFO_OFFSET) +#define LPC43_I2S0_RXFIFO (LPC43_I2S0_BASE+LPC43_I2S_RXFIFO_OFFSET) +#define LPC43_I2S0_STATE (LPC43_I2S0_BASE+LPC43_I2S_STATE_OFFSET) +#define LPC43_I2S0_DMA1 (LPC43_I2S0_BASE+LPC43_I2S_DMA1_OFFSET) +#define LPC43_I2S0_DMA2 (LPC43_I2S0_BASE+LPC43_I2S_DMA2_OFFSET) +#define LPC43_I2S0_IRQ (LPC43_I2S0_BASE+LPC43_I2S_IRQ_OFFSET) +#define LPC43_I2S0_TXRATE (LPC43_I2S0_BASE+LPC43_I2S_TXRATE_OFFSET) +#define LPC43_I2S0_RXRATE (LPC43_I2S0_BASE+LPC43_I2S_RXRATE_OFFSET) +#define LPC43_I2S0_TXBITRATE (LPC43_I2S0_BASE+LPC43_I2S_TXBITRATE_OFFSET) +#define LPC43_I2S0_RXBITRATE (LPC43_I2S0_BASE+LPC43_I2S_RXBITRATE_OFFSET) +#define LPC43_I2S0_TXMODE (LPC43_I2S0_BASE+LPC43_I2S_TXMODE_OFFSET) +#define LPC43_I2S0_RXMODE (LPC43_I2S0_BASE+LPC43_I2S_RXMODE_OFFSET) + +#define LPC43_I2S1_DAO (LPC43_I2S1_BASE+LPC43_I2S_DAO_OFFSET) +#define LPC43_I2S1_DAI (LPC43_I2S1_BASE+LPC43_I2S_DAI_OFFSET) +#define LPC43_I2S1_TXFIFO (LPC43_I2S1_BASE+LPC43_I2S_TXFIFO_OFFSET) +#define LPC43_I2S1_RXFIFO (LPC43_I2S1_BASE+LPC43_I2S_RXFIFO_OFFSET) +#define LPC43_I2S1_STATE (LPC43_I2S1_BASE+LPC43_I2S_STATE_OFFSET) +#define LPC43_I2S1_DMA1 (LPC43_I2S1_BASE+LPC43_I2S_DMA1_OFFSET) +#define LPC43_I2S1_DMA2 (LPC43_I2S1_BASE+LPC43_I2S_DMA2_OFFSET) +#define LPC43_I2S1_IRQ (LPC43_I2S1_BASE+LPC43_I2S_IRQ_OFFSET) +#define LPC43_I2S1_TXRATE (LPC43_I2S1_BASE+LPC43_I2S_TXRATE_OFFSET) +#define LPC43_I2S1_RXRATE (LPC43_I2S1_BASE+LPC43_I2S_RXRATE_OFFSET) +#define LPC43_I2S1_TXBITRATE (LPC43_I2S1_BASE+LPC43_I2S_TXBITRATE_OFFSET) +#define LPC43_I2S1_RXBITRATE (LPC43_I2S1_BASE+LPC43_I2S_RXBITRATE_OFFSET) +#define LPC43_I2S1_TXMODE (LPC43_I2S1_BASE+LPC43_I2S_TXMODE_OFFSET) +#define LPC43_I2S1_RXMODE (LPC43_I2S1_BASE+LPC43_I2S_RXMODE_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Digital Audio Output Register */ + +#define I2S_DAO_WDWID_SHIFT (0) /* Bits 0-1: Selects the number of bytes in data */ +#define I2S_DAO_WDWID_MASK (3 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_8BITS (0 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_16BITS (1 << I2S_DAO_WDWID_SHIFT) +# define I2S_DAO_WDWID_32BITS (3 << I2S_DAO_WDWID_SHIFT) +#define I2S_DAO_MONO (1 << 2) /* Bit 2: Mono format */ +#define I2S_DAO_STOP (1 << 3) /* Bit 3: Disable FIFOs / mute mode */ +#define I2S_DAO_RESET (1 << 4) /* Bit 4: Reset TX channel and FIFO */ +#define I2S_DAO_WSSEL (1 << 5) /* Bit 5: Slave mode select */ +#define I2S_DAO_WSHALFPER_SHIFT (6) /* Bits 6-14: Word select half period minus 1 */ +#define I2S_DAO_WSHALFPER_MASK (0x01ff << I2S_DAO_WSHALFPER_SHIFT) +#define I2S_DAO_MUTE (1 << 15) /* Bit 15: Send only zeros on channel */ + /* Bits 16-31: Reserved */ +/* Digital Audio Input Register */ + +#define I2S_DAI_WDWID_SHIFT (0) /* Bits 0-1: Selects the number of bytes in data */ +#define I2S_DAI_WDWID_MASK (3 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_8BITS (0 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_16BITS (1 << I2S_DAI_WDWID_SHIFT) +# define I2S_DAI_WDWID_32BITS (3 << I2S_DAI_WDWID_SHIFT) +#define I2S_DAI_MONO (1 << 2) /* Bit 2: Mono format */ +#define I2S_DAI_STOP (1 << 3) /* Bit 3: Disable FIFOs / mute mode */ +#define I2S_DAI_RESET (1 << 4) /* Bit 4: Reset TX channel and FIFO */ +#define I2S_DAI_WSSEL (1 << 5) /* Bit 5: Slave mode select */ +#define I2S_DAI_WSHALFPER_SHIFT (6) /* Bits 6-14: Word select half period minus 1 */ +#define I2S_DAI_WSHALFPER_MASK (0x01ff << I2S_DAI_WSHALFPER_SHIFT) + /* Bits 15-31: Reserved */ +/* Transmit FIFO: 8 × 32-bit transmit FIFO */ +/* Receive FIFO: 8 × 32-bit receive FIFO */ + +/* Status Feedback Register */ + +#define I2S_STATE_IRQ (1 << 0) /* Bit 0: Receive Transmit Interrupt */ +#define I2S_STATE_DMAREQ1 (1 << 1) /* Bit 1: Receive or Transmit DMA Request 1 */ +#define I2S_STATE_DMAREQ2 (1 << 2) /* Bit 2: Receive or Transmit DMA Request 2 */ + /* Bits 3-7: Reserved */ +#define I2S_STATE_RXLEVEL_SHIFT (8) /* Bits 8-11: Current level of the Receive FIFO */ +#define I2S_STATE_RXLEVEL_MASK (15 << I2S_STATE_RXLEVEL_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_STATE_TXLEVEL_SHIFT (16) /* Bits 16-19: Current level of the Transmit FIFO */ +#define I2S_STATE_TXLEVEL_MASK (15 << I2S_STATE_TXLEVEL_SHIFT) + /* Bits 20-31: Reserved */ +/* DMA Configuration Register 1 and 2 */ + +#define I2S_DMA_RXDMAEN (1 << 0) /* Bit 0: Enable DMA1 for I2S receive */ +#define I2S_DMA_TXDMAEN (1 << 1) /* Bit 1: Enable DMA1 for I2S transmit */ + /* Bits 2-7: Reserved */ +#define I2S_DMA_RXDEPTH_SHIFT (8) /* Bits 8-11: FIFO level that triggers RX request on DMA1 */ +#define I2S_DMA_RXDEPTH_MASK (15 << I2S_DMA_RXDEPTH_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_DMA_TXDEPTH_SHIFT (16) /* Bits 16-19: FIFO level that triggers a TX request on DMA1 */ +#define I2S_DMA_TXDEPTH_MASK (15 << I2S_DMA_TXDEPTH_SHIFT) + /* Bits 20-31: Reserved */ +/* Interrupt Request Control Register */ + +#define I2S_IRQ_RXEN (1 << 0) /* Bit 0: Enable I2S receive interrupt */ +#define I2S_IRQ_TXEN (1 << 1) /* Bit 1: Enable I2S transmit interrupt */ + /* Bits 2-7: Reserved */ +#define I2S_IRQ_RXDEPTH_SHIFT (8) /* Bits 8-11: Set FIFO level for irq request */ +#define I2S_IRQ_RXDEPTH_MASK (15 << I2S_IRQ_RXDEPTH_SHIFT) + /* Bits 12-15: Reserved */ +#define I2S_IRQ_TXDEPTH_SHIFT (16) /* Bits 16-19: Set FIFO level for irq request */ +#define I2S_IRQ_TXDEPTH_MASK (15 << I2S_IRQ_TXDEPTH_SHIFT) + /* Bits 20-31: Reserved */ +/* Transmit and Receive MCLK divider */ + +#define I2S_RATE_YDIV_SHIFT (0) /* Bits 0-7: I2S transmit MCLK rate denominator */ +#define I2S_RATE_YDIV_MASK (0xff << I2S_RATE_YDIV_SHIFT) +#define I2S_RATE_XDIV_SHIFT (8) /* Bits 8-15: I2S transmit MCLK rate numerator */ +#define I2S_RATE_XDIV_MASK (0xff << I2S_RATE_XDIV_SHIFT) + /* Bits 16-31: Reserved */ + +/* Transmit and received bit rate divider */ + +#define I2S_BITRATE_SHIFT (0) /* Bits 0-5: I2S transmit bit rate */ +#define I2S_BITRATE_MASK (0x3f << I2S_BITRATE_SHIFT) + /* Bits 6-31: Reserved */ +/* Transmit and Receive mode control */ + +#define I2S_MODE_CLKSEL_SHIFT (0) /* Bits 0-1: Clock source for bit clock divider */ +#define I2S_MODE_CLKSEL_MASK (3 << I2S_MODE_CLKSEL_SHIFT) +# define I2S_MODE_CLKSEL_FRACDIV (0 << I2S_MODE_CLKSEL_SHIFT) /* TX/RX fractional rate divider */ +# define I2S_MODE_CLKSEL_RXMCLK (2 << I2S_MODE_CLKSEL_SHIFT) /* RX_CLCK for TX_MCLK source */ +# define I2S_MODE_CLKSEL_TXMCLK (2 << I2S_MODE_CLKSEL_SHIFT) /* TX_CLCK for RX_MCLK source */ +#define I2S_MODE_4PIN (1 << 2) /* Bit 2: Transmit/Receive 4-pin mode selection */ +#define I2S_MODE_MCENA (1 << 3) /* Bit 3: Enable for the TX/RX_MCLK output */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_I2S_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_lcd.h b/arch/arm/src/lpc43xx/chip/lpc43_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..5762bed5e2628e49b0ff31ec52b23b315fbe6c4d --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_lcd.h @@ -0,0 +1,304 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_lcd.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_LCD_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_LCD_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_LCD_TIMH_OFFSET 0x000 /* Horizontal Timing Control register */ +#define LPC43_LCD_TIMV_OFFSET 0x004 /* Vertical Timing Control register */ +#define LPC43_LCD_POL_OFFSET 0x008 /* Clock and Signal Polarity Control register */ +#define LPC43_LCD_LE_OFFSET 0x00c /* Line End Control register */ +#define LPC43_LCD_UPBASE_OFFSET 0x010 /* Upper Panel Frame Base Address register */ +#define LPC43_LCD_LPBASE_OFFSET 0x014 /* Lower Panel Frame Base Address register */ +#define LPC43_LCD_CTRL_OFFSET 0x018 /* LCD Control register */ +#define LPC43_LCD_INTMSK_OFFSET 0x01c /* Interrupt Mask register */ +#define LPC43_LCD_INTRAW_OFFSET 0x020 /* Raw Interrupt Status register */ +#define LPC43_LCD_INTSTAT_OFFSET 0x024 /* Masked Interrupt Status register */ +#define LPC43_LCD_INTCLR_OFFSET 0x028 /* Interrupt Clear register */ +#define LPC43_LCD_UPCURR_OFFSET 0x02c /* Upper Panel Current Address Value register */ +#define LPC43_LCD_LPCURR_OFFSET 0x030 /* Lower Panel Current Address Value register */ + +/* 0x200 to 0x3fc 256x16-bit Color Palette registers */ + +#define LPC43_LCD_PAL_OFFSET(n) (0x200 + ((n) << 2)) /* n=0..128, two colors per word */ + +/* 0x800 to 0xbfc Cursor Image registers */ + +#define LPC43_LCD_CRSR_IMG_OFFSET(n) (0x800 + ((n) << 2)) /* n = 0..256 */ + +#define LPC43_LCD_CRSR_CTRL_OFFSET 0xc00 /* Cursor Control register */ +#define LPC43_LCD_CRSR_CFG_OFFSET 0xc04 /* Cursor Configuration register */ +#define LPC43_LCD_CRSR_PAL0_OFFSET 0xc08 /* Cursor Palette register 0 */ +#define LPC43_LCD_CRSR_PAL1_OFFSET 0xc0c /* Cursor Palette register 1 */ +#define LPC43_LCD_CRSR_XY_OFFSET 0xc10 /* Cursor XY Position register */ +#define LPC43_LCD_CRSR_CLIP_OFFSET 0xc14 /* Cursor Clip Position register */ +#define LPC43_LCD_CRSR_INTMSK_OFFSET 0xc20 /* Cursor Interrupt Mask register */ +#define LPC43_LCD_CRSR_INTCLR_OFFSET 0xc24 /* Cursor Interrupt Clear register */ +#define LPC43_LCD_CRSR_INTRAW_OFFSET 0xc28 /* Cursor Raw Interrupt Status register */ +#define LPC43_LCD_CRSR_INTSTAT_OFFSET 0xc2c /* Cursor Masked Interrupt Status register */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_LCD_TIMH (LPC43_LCD_BASE+LPC43_LCD_TIMH_OFFSET) +#define LPC43_LCD_TIMV (LPC43_LCD_BASE+LPC43_LCD_TIMV_OFFSET) +#define LPC43_LCD_POL (LPC43_LCD_BASE+LPC43_LCD_POL_OFFSET) +#define LPC43_LCD_LE (LPC43_LCD_BASE+LPC43_LCD_LE_OFFSET) +#define LPC43_LCD_UPBASE (LPC43_LCD_BASE+LPC43_LCD_UPBASE_OFFSET) +#define LPC43_LCD_LPBASE (LPC43_LCD_BASE+LPC43_LCD_LPBASE_OFFSET) +#define LPC43_LCD_CTRL (LPC43_LCD_BASE+LPC43_LCD_CTRL_OFFSET) +#define LPC43_LCD_INTMSK (LPC43_LCD_BASE+LPC43_LCD_INTMSK_OFFSET) +#define LPC43_LCD_INTRAW (LPC43_LCD_BASE+LPC43_LCD_INTRAW_OFFSET) +#define LPC43_LCD_INTSTAT (LPC43_LCD_BASE+LPC43_LCD_INTSTAT_OFFSET) +#define LPC43_LCD_INTCLR (LPC43_LCD_BASE+LPC43_LCD_INTCLR_OFFSET) +#define LPC43_LCD_UPCURR (LPC43_LCD_BASE+LPC43_LCD_UPCURR_OFFSET) +#define LPC43_LCD_LPCURR (LPC43_LCD_BASE+LPC43_LCD_LPCURR_OFFSET) + +/* 0x200 to 0x3fc 256x16-bit Color Palette registers */ + +#define LPC43_LCD_PAL(n) (LPC43_LCD_BASE+LPC43_LCD_PAL_OFFSET(n)) + +/* 0x800 to 0xbfc Cursor Image registers */ + +#define LPC43_LCD_CRSR_IMG(n) (LPC43_LCD_BASE+LPC43_LCD_CRSR_IMG_OFFSET(n)) + +#define LPC43_LCD_CRSR_CTRL (LPC43_LCD_BASE+LPC43_LCD_CRSR_CTRL_OFFSET) +#define LPC43_LCD_CRSR_CFG (LPC43_LCD_BASE+LPC43_LCD_CRSR_CFG_OFFSET) +#define LPC43_LCD_CRSR_PAL0 (LPC43_LCD_BASE+LPC43_LCD_CRSR_PAL0_OFFSET) +#define LPC43_LCD_CRSR_PAL1 (LPC43_LCD_BASE+LPC43_LCD_CRSR_PAL1_OFFSET) +#define LPC43_LCD_CRSR_XY (LPC43_LCD_BASE+LPC43_LCD_CRSR_XY_OFFSET) +#define LPC43_LCD_CRSR_CLIP (LPC43_LCD_BASE+LPC43_LCD_CRSR_CLIP_OFFSET) +#define LPC43_LCD_CRSR_INTMSK (LPC43_LCD_BASE+LPC43_LCD_CRSR_INTMSK_OFFSET) +#define LPC43_LCD_CRSR_INTCLR (LPC43_LCD_BASE+LPC43_LCD_CRSR_INTCLR_OFFSET) +#define LPC43_LCD_CRSR_INTRAW (LPC43_LCD_BASE+LPC43_LCD_CRSR_INTRAW_OFFSET) +#define LPC43_LCD_CRSR_INTSTAT (LPC43_LCD_BASE+LPC43_LCD_CRSR_INTSTAT_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Horizontal Timing Control register */ + + /* Bits 0-1: Reserved */ +#define LCD_TIMH_PPL_SHIFT (2) /* Bits 2-7: Pixels-per-line */ +#define LCD_TIMH_PPL_MASK (0x3f << LCD_TIMH_PPL_SHIFT) +#define LCD_TIMH_HSW_SHIFT (8) /* Bits 8-15: Horizontal synchronization pulse width */ +#define LCD_TIMH_HSW_MASK (0xff << LCD_TIMH_HSW_SHIFT) +#define LCD_TIMH_HFP_SHIFT (16) /* Bits 16-23: Horizontal front porch */ +#define LCD_TIMH_HFP_MASK (0xff << LCD_TIMH_HFP_SHIFT) +#define LCD_TIMH_HBP_SHIFT (24) /* Bits 24-31: Horizontal back porch */ +#define LCD_TIMH_HBP_MASK (0xff << LCD_TIMH_HBP_SHIFT) + /* Bit nn: Reserved */ +/* Vertical Timing Control register */ + +#define LCD_TIMV_LPP_SHIFT (0) /* Bits 0-9: Lines per panel */ +#define LCD_TIMV_LPP_MASK (0x3ff << LCD_TIMV_LPP_SHIFT) +#define LCD_TIMV_VSW_SHIFT (10) /* Bits 10-15: Vertical synchronization pulse width */ +#define LCD_TIMV_VSW_MASK (0x3f << LCD_TIMV_VSW_SHIFT) +#define LCD_TIMV_VFP_SHIFT (16) /* Bits 16-23: Vertical front porch */ +#define LCD_TIMV_VFP_MASK (0xff << LCD_TIMV_VFP_SHIFT) +#define LCD_TIMV_VBP_SHIFT (24) /* Bits 24-31: Vertical back porch */ +#define LCD_TIMV_VBP_MASK (0xff << LCD_TIMV_VBP_SHIFT) + +/* Clock and Signal Polarity Control register */ + +#define LCD_POL_PCDLO_SHIFT (0) /* Bits 0-4: Lower five bits of panel clock divisor */ +#define LCD_POL_PCDLO_MASK (31 << LCD_POL_PCDLO_SHIFT) +#define LCD_POL_CLKSEL (1 << 5) /* Bit 5: Clock Select */ +#define LCD_POL_ACB_SHIFT (6) /* Bits 6-10: AC bias pin frequency */ +#define LCD_POL_ACB_MASK (31 << LCD_POL_ACB_SHIFT) +#define LCD_POL_IVS (1 << 11) /* Bit 11: Invert vertical synchronization */ +#define LCD_POL_IHS (1 << 12) /* Bit 12: Invert horizontal synchronization */ +#define LCD_POL_IPC (1 << 13) /* Bit 13: Invert panel clock */ +#define LCD_POL_IOE (1 << 14) /* Bit 14: Invert output enable */ + /* Bit 15: Reserved */ +#define LCD_POL_CPL_SHIFT (16) /* Bits 16-25: Clocks per line */ +#define LCD_POL_CPL_MASK (0x3ff << LCD_POL_CPL_SHIFT) +#define LCD_POL_BCD (1 << 26) /* Bit 26: Bypass pixel clock divider */ +#define LCD_POL_PCDHI_SHIFT (27) /* Bits 27-31: Upper five bits of panel clock divisor */ +#define LCD_POL_PCDHI_MASK (31 << LCD_POL_PCDHI_SHIFT) + +/* Line End Control register */ + +#define LCD_LE_DELAY_SHIFT (0) /* Bits 0-6: Line-end delay */ +#define LCD_LE_DELAY_MASK (0x7f << LCD_LE_DELAY_SHIFT) + /* Bits 7-15: Reserved */ +#define LCD_LE_ENA (1 << 16) /* Bit 16: LCD Line end enable */ + /* Bits 17-31: Reserved */ + +/* Upper Panel Frame Base Address register */ + /* Bits 0-2: Reserved */ +#define LCD_UPBASE_SHIFT (3) /* Bits 3-31: Upper panel base address */ +#define LCD_UPBASE_MASK (0xfffffff8) + +/* Lower Panel Frame Base Address register */ + /* Bits 0-2: Reserved */ +#define LCD_LPBASE_SHIFT (3) /* Bits 3-31: Lower panel base address */ +#define LCD_LPBASE_MASK (0xfffffff8) + +/* LCD Control register */ + +#define LCD_CTRL_LCDEN (1 << 0) /* Bit 0: LCD enable control bit */ +#define LCD_CTRL_LCDBPP_SHIFT (1) /* Bits 1-3: LCD bits per pixel */ +#define LCD_CTRL_LCDBPP_MASK (7 << LCD_CTRL_LCDBPP_SHIFT) +# define LCD_CTRL_LCDBPP_1BPP (0 << LCD_CTRL_LCDBPP_SHIFT) /* 1 bpp */ +# define LCD_CTRL_LCDBPP_2BPP (1 << LCD_CTRL_LCDBPP_SHIFT) /* 2 bpp */ +# define LCD_CTRL_LCDBPP_4BPP (2 << LCD_CTRL_LCDBPP_SHIFT) /* 4 bpp */ +# define LCD_CTRL_LCDBPP_8BPP (3 << LCD_CTRL_LCDBPP_SHIFT) /* 8 bpp */ +# define LCD_CTRL_LCDBPP_16BPP (4 << LCD_CTRL_LCDBPP_SHIFT) /* 16 bpp */ +# define LCD_CTRL_LCDBPP_24BPP (5 << LCD_CTRL_LCDBPP_SHIFT) /* 24 bpp (TFT panel only) */ +# define LCD_CTRL_LCDBPP_RGB565 (6 << LCD_CTRL_LCDBPP_SHIFT) /* 16 bpp, 5:6:5 mode */ +# define LCD_CTRL_LCDBPP_RGB444 (7 << LCD_CTRL_LCDBPP_SHIFT) /* 12 bpp, 4:4:4 mode */ +#define LCD_CTRL_LCDBW (1 << 4) /* Bit 4: STN LCD monochrome/color selection */ +#define LCD_CTRL_LCDTFT (1 << 5) /* Bit 5: LCD panel TFT type selection */ +#define LCD_CTRL_LCDMONO8 (1 << 6) /* Bit 6: Monochrome LCD interface width */ +#define LCD_CTRL_LCDDUAL (1 << 7) /* Bit 7: Single or Dual LCD panel selection */ +#define LCD_CTRL_BGR (1 << 8) /* Bit 8: Color format selection */ +#define LCD_CTRL_BEBO (1 << 9) /* Bit 9: Big-endian Byte Order */ +#define LCD_CTRL_BEPO (1 << 10) /* Bit 10: Big-Endian Pixel Ordering */ +#define LCD_CTRL_LCDPWR (1 << 11) /* Bit 11: LCD power enable */ +#define LCD_CTRL_LCDVCOMP_SHIFT (12) /* Bits 12-13: LCD vertical compare interrupt */ +#define LCD_CTRL_LCDVCOMP_MASK (3 << LCD_CTRL_LCDVCOMP_SHIFT) +# define LCD_CTRL_LCDVCOMP_START (0 << LCD_CTRL_LCDVCOMP_SHIFT) /* Start of vertical synchronization */ +# define LCD_CTRL_LCDVCOMP_BACK (1 << LCD_CTRL_LCDVCOMP_SHIFT) /* Start of back porch */ +# define LCD_CTRL_LCDVCOMP_ACTIVE (2 << LCD_CTRL_LCDVCOMP_SHIFT) /* Start of active video */ +# define LCD_CTRL_LCDVCOMP_FRONT (3 << LCD_CTRL_LCDVCOMP_SHIFT) /* Start of front porch */ + /* Bits 14-15: Reserved */ +#define LCD_INTMSK_WATERMARK (1 << 16) /* Bit 16: LCD DMA FIFO watermark level */ + /* Bits 17-31: Reserved */ +/* Interrupt Mask register */ +/* Raw Interrupt Status register */ +/* Masked Interrupt Status register */ +/* Interrupt Clear register */ + + + /* Bit 0: Reserved */ +#define LCD_INT_FUFI (1 << 1) /* Bit 1: FIFO underflow interrupt */ +#define LCD_INT_LNBUI (1 << 2) /* Bit 2: LCD next base address update interrupt enable */ +#define LCD_INT_VCOMPI (1 << 3) /* Bit 3: Vertical compare interrupt enable */ +#define LCD_INT_BERI (1 << 4) /* Bit 4: AHB master error interrupt enable */ + /* Bits 5-31: Reserved */ +/* Upper Panel Current Address Value register (32-bit address) */ +/* Lower Panel Current Address Value register (32-bit address) */ + +/* 256x16-bit Color Palette registers */ + +#define LCD_PAL_R0_SHIFT (0) /* Bits 0-4: Red palette data */ +#define LCD_PAL_R0_MASK (31 << LCD_PAL_R0_SHIFT) +#define LCD_PAL_G0_SHIFT (5) /* Bits 5-9: Green palette data */ +#define LCD_PAL_G0_MASK (31 << LCD_PAL_G0_SHIFT) +#define LCD_PAL_B0_SHIFT (10) /* Bits 10-14: Blue palette data */ +#define LCD_PAL_B0_MASK (31 << LCD_PAL_B0_SHIFT) +#define LCD_PAL_I0 (1 << 16) /* Bit 15: Intensity / unused bit */ +#define LCD_PAL_R1_SHIFT (16) /* Bits 16-20: Red palette data */ +#define LCD_PAL_R1_MASK (31 << LCD_PAL_R1_SHIFT) +#define LCD_PAL_G1_SHIFT (21) /* Bits 21-25: Green palette data */ +#define LCD_PAL_G1_MASK (31 << LCD_PAL_G1_SHIFT) +#define LCD_PAL_B1_SHIFT (26) /* Bits 26-30: Blue palette data */ +#define LCD_PAL_B1_MASK (31 << LCD_PAL_B1_SHIFT) +#define LCD_PAL_I1 (1 << 31) /* Bit 31: Intensity / unused bit */ + +/* Cursor Image registers (32-bit image data) */ + +/* Cursor Control register */ + +#define LCD_CRSR_CTRL_ON (1 << 0) /* Bit 0: Cursor enable */ + /* Bits 1-3: Reserved */ +#define LCD_CRSR_CTRL_NUM_SHIFT (4) /* Bits 4-5: Cursor image number */ +#define LCD_CRSR_CTRL_NUM_MASK (3 << LCD_CRSR_CTRL_NUM_SHIFT) +# define LCD_CRSR_CTRL_NUM_0 (0 << LCD_CRSR_CTRL_NUM_SHIFT) +# define LCD_CRSR_CTRL_NUM_1 (1 << LCD_CRSR_CTRL_NUM_SHIFT) +# define LCD_CRSR_CTRL_NUM_2 (2 << LCD_CRSR_CTRL_NUM_SHIFT) +# define LCD_CRSR_CTRL_NUM_3 (3 << LCD_CRSR_CTRL_NUM_SHIFT) + /* Bits 6-31: Reserved */ +/* Cursor Configuration register */ + +#define LCD_CRSR_CFG_CRSRSIZE (1 << 0) /* Bit 0: Cursor size selection */ +#define LCD_CRSR_CFG_FRAMESYNC (1 << 1) /* Bit 1: Cursor frame synchronization type */ + /* Bits 2-31: Reserved */ +/* Cursor Palette register 0/1 */ + +#define LCD_CRSR_PAL_RED_SHIFT (0) /* Bits 0-7: Red color component */ +#define LCD_CRSR_PAL_RED_MASK (0xff << LCD_CRSR_PAL_RED_SHIFT) +#define LCD_CRSR_PAL_GREEN_SHIFT (8) /* Bits 8-15: Green color component */ +#define LCD_CRSR_PAL_GREEN_MASK (0xff << LCD_CRSR_PAL_GREEN_SHIFT) +#define LCD_CRSR_PAL_BLUE_SHIFT (16) /* Bits 16-23: Blue color component */ +#define LCD_CRSR_PAL_BLUE_MASK (0xff << LCD_CRSR_PAL_BLUE_SHIFT) + /* Bits 24-31: Reserved */ +/* Cursor XY Position register */ + +#define LCD_CRSRX_SHIFT (0) /* Bits 0-9: X ordinate of the cursor origin measured in pixels */ +#define LCD_CRSRX_MASK (0x3ff << LCD_CRSRX_SHIFT) + /* Bits 10-15: Reserved */ +#define LCD_CRSRY_SHIFT (16) /* Bits 16-25: Y ordinate of the cursor origin measured in pixels */ +#define LCD_CRSRY_MASK (0x3ff << LCD_CRSRY_SHIFT) + /* Bits 26-31: Reserved */ +/* Cursor Clip Position register */ + +#define LCD_CRSR_CLIPX_SHIFT (0) /* Bits 0-5: Cursor clip position for X direction */ +#define LCD_CRSR_CLIPX_MASK (0x3f << LCD_CRSR_CLIPX_SHIFT) + /* Bits 6-7: Reserved */ +#define LCD_CRSR_CLIPY_SHIFT (8) /* Bits 8-13: Cursor clip position for Y direction */ +#define LCD_CRSR_CLIPY_MASK (0x3f << LCD_CRSR_CLIPY_SHIFT) + /* Bits 14-31: Reserved */ +/* Cursor Interrupt Mask register */ +/* Cursor Interrupt Clear register */ +/* Cursor Raw Interrupt Status register */ +/* Cursor Masked Interrupt Status register */ + +#define LCD_CRSR_INT (1 << 0) /* CRSRIM Cursor interrupt */ + /* Bits 1-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_LCD_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h b/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h new file mode 100644 index 0000000000000000000000000000000000000000..720b8affc427a5bc73e89799626baac8c4cfa40f --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_mcpwm.h @@ -0,0 +1,274 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_mcpwm.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_MCPWM_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_MCPWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_MCPWM_CON_OFFSET 0x0000 /* PWM Control read address */ +#define LPC43_MCPWM_CONSET_OFFSET 0x0004 /* PWM Control set address */ +#define LPC43_MCPWM_CONCLR_OFFSET 0x0008 /* PWM Control clear address */ +#define LPC43_MCPWM_CAPCON_OFFSET 0x000c /* Capture Control read address */ +#define LPC43_MCPWM_CAPCONSET_OFFSET 0x0010 /* Capture Control set address */ +#define LPC43_MCPWM_CAPCONCLR_OFFSET 0x0014 /* Event Control clear address */ +#define LPC43_MCPWM_TC0_OFFSET 0x0018 /* Timer Counter register, channel 0 */ +#define LPC43_MCPWM_TC1_OFFSET 0x001c /* Timer Counter register, channel 1 */ +#define LPC43_MCPWM_TC2_OFFSET 0x0020 /* Timer Counter register, channel 2 */ +#define LPC43_MCPWM_LIM0_OFFSET 0x0024 /* Limit register, channel 0 */ +#define LPC43_MCPWM_LIM1_OFFSET 0x0028 /* Limit register, channel 1 */ +#define LPC43_MCPWM_LIM2_OFFSET 0x002c /* Limit register, channel 2 */ +#define LPC43_MCPWM_MAT0_OFFSET 0x0030 /* Match register, channel 0 */ +#define LPC43_MCPWM_MAT1_OFFSET 0x0034 /* Match register, channel 1 */ +#define LPC43_MCPWM_MAT2_OFFSET 0x0038 /* Match register, channel 2 */ +#define LPC43_MCPWM_DT_OFFSET 0x003c /* Dead time register */ +#define LPC43_MCPWM_MCCP_OFFSET 0x0040 /* Communication Pattern register */ +#define LPC43_MCPWM_CAP0_OFFSET 0x0044 /* Capture register, channel 0 */ +#define LPC43_MCPWM_CAP1_OFFSET 0x0048 /* Capture register, channel 1 */ +#define LPC43_MCPWM_CAP2_OFFSET 0x004c /* Capture register, channel 2 */ +#define LPC43_MCPWM_INTEN_OFFSET 0x0050 /* Interrupt Enable read address */ +#define LPC43_MCPWM_INTENSET_OFFSET 0x0054 /* Interrupt Enable set address */ +#define LPC43_MCPWM_INTENCLR_OFFSET 0x0058 /* Interrupt Enable clear address */ +#define LPC43_MCPWM_CNTCON_OFFSET 0x005c /* Count Control read address */ +#define LPC43_MCPWM_CNTCONSET_OFFSET 0x0060 /* Count Control set address */ +#define LPC43_MCPWM_CNTCONCLR_OFFSET 0x0064 /* Count Control clear address */ +#define LPC43_MCPWM_INTF_OFFSET 0x0068 /* Interrupt flags read address */ +#define LPC43_MCPWM_INTFSET_OFFSET 0x006c /* Interrupt flags set address */ +#define LPC43_MCPWM_INTFCLR_OFFSET 0x0070 /* Interrupt flags clear address */ +#define LPC43_MCPWM_CAPCLR_OFFSET 0x0074 /* Capture clear address */ + +/* Register addresses ***************************************************************/ + +#define LPC43_MCPWM_CON (LPC43_MCPWM_BASE+LPC43_MCPWM_CON_OFFSET) +#define LPC43_MCPWM_CONSET (LPC43_MCPWM_BASE+LPC43_MCPWM_CONSET_OFFSET) +#define LPC43_MCPWM_CONCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_CONCLR_OFFSET) +#define LPC43_MCPWM_CAPCON (LPC43_MCPWM_BASE+LPC43_MCPWM_CAPCON_OFFSET) +#define LPC43_MCPWM_CAPCONSET (LPC43_MCPWM_BASE+LPC43_MCPWM_CAPCONSET_OFFSET) +#define LPC43_MCPWM_CAPCONCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_CAPCONCLR_OFFSET) +#define LPC43_MCPWM_TC0 (LPC43_MCPWM_BASE+LPC43_MCPWM_TC0_OFFSET) +#define LPC43_MCPWM_TC1 (LPC43_MCPWM_BASE+LPC43_MCPWM_TC1_OFFSET) +#define LPC43_MCPWM_TC2 (LPC43_MCPWM_BASE+LPC43_MCPWM_TC2_OFFSET) +#define LPC43_MCPWM_LIM0 (LPC43_MCPWM_BASE+LPC43_MCPWM_LIM0_OFFSET) +#define LPC43_MCPWM_LIM1 (LPC43_MCPWM_BASE+LPC43_MCPWM_LIM1_OFFSET) +#define LPC43_MCPWM_LIM2 (LPC43_MCPWM_BASE+LPC43_MCPWM_LIM2_OFFSET) +#define LPC43_MCPWM_MAT0 (LPC43_MCPWM_BASE+LPC43_MCPWM_MAT0_OFFSET) +#define LPC43_MCPWM_MAT1 (LPC43_MCPWM_BASE+LPC43_MCPWM_MAT1_OFFSET) +#define LPC43_MCPWM_MAT2 (LPC43_MCPWM_BASE+LPC43_MCPWM_MAT2_OFFSET) +#define LPC43_MCPWM_DT (LPC43_MCPWM_BASE+LPC43_MCPWM_DT_OFFSET) +#define LPC43_MCPWM_MCCP (LPC43_MCPWM_BASE+LPC43_MCPWM_MCCP_OFFSET) +#define LPC43_MCPWM_CAP0 (LPC43_MCPWM_BASE+LPC43_MCPWM_CAP0_OFFSET) +#define LPC43_MCPWM_CAP1 (LPC43_MCPWM_BASE+LPC43_MCPWM_CAP1_OFFSET) +#define LPC43_MCPWM_CAP2 (LPC43_MCPWM_BASE+LPC43_MCPWM_CAP2_OFFSET) +#define LPC43_MCPWM_INTEN (LPC43_MCPWM_BASE+LPC43_MCPWM_INTEN_OFFSET) +#define LPC43_MCPWM_INTENSET (LPC43_MCPWM_BASE+LPC43_MCPWM_INTENSET_OFFSET) +#define LPC43_MCPWM_INTENCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_INTENCLR_OFFSET) +#define LPC43_MCPWM_CNTCON (LPC43_MCPWM_BASE+LPC43_MCPWM_CNTCON_OFFSET) +#define LPC43_MCPWM_CNTCONSET (LPC43_MCPWM_BASE+LPC43_MCPWM_CNTCONSET_OFFSET) +#define LPC43_MCPWM_CNTCONCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_CNTCONCLR_OFFSET) +#define LPC43_MCPWM_INTF (LPC43_MCPWM_BASE+LPC43_MCPWM_INTF_OFFSET) +#define LPC43_MCPWM_INTFSET (LPC43_MCPWM_BASE+LPC43_MCPWM_INTFSET_OFFSET) +#define LPC43_MCPWM_INTFCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_INTFCLR_OFFSET) +#define LPC43_MCPWM_CAPCLR (LPC43_MCPWM_BASE+LPC43_MCPWM_CAPCLR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* There are no bit field definitions for the following registers because they support + * 32-bit values: + * + * - Timer Counter register, channel 0 (TC0), Timer Counter register, channel 1 (TC1), + * and Timer Counter register, channel 2 (TC2): 32-bit Timer/Counter values for + * channels 0, 1, 2 (no bit field definitions) + * + * - Limit register, channel 0 (LIM0), Limit register, channel 1 (LIM1), and Limit + * register, channel 2 (LIM2): 32-bit Limit values for TC0, 1, 2 (no bit field + * definitions) + * + * - Match register, channel 0 MAT0), Match register, channel 1 (MAT1), and Match + * register, channel 2 (MAT2): 32-bit Match values for TC0, 1, 2 (no bit field + * definitions). + * + * - Capture register, channel 0 (CAP0), Capture register, channel 1 (CAP1), and + * Capture register, channel 2 (CAP2): 32-bit TC value at a capture event for + * channels 0, 1, 2 (no bit field definitions) + */ + +/* PWM Control read address (CON), PWM Control set address (CONSET), and PWM Control + * clear address (CONCLR) common regiser bit definitions. + */ + +#define MCPWM_CON_RUN0 (1 << 0) /* Bit 0: Stops/starts timer channel 0 */ +#define MCPWM_CON_CENTER0 (1 << 1) /* Bit 1: Chan 0 edge/center aligned operation */ +#define MCPWM_CON_POLA0 (1 << 2) /* Bit 2: Polarity of MCOA0 and MCOB0 */ +#define MCPWM_CON_DTE0 (1 << 3) /* Bit 3: Dead time feature control */ +#define MCPWM_CON_DISUP0 (1 << 4) /* Bit 4: Enable/disable register updates */ + /* Bits 5-7: Reserved */ +#define MCPWM_CON_RUN1 (1 << 8) /* Bit 8: Stops/starts timer channel 1 */ +#define MCPWM_CON_CENTER1 (1 << 9) /* Bit 9: Chan 1 edge/center aligned operation */ +#define MCPWM_CON_POLA1 (1 << 10) /* Bit 10: Polarity of MCOA1 and MCOB1 */ +#define MCPWM_CON_DTE1 (1 << 11) /* Bit 11: Dead time feature control */ +#define MCPWM_CON_DISUP1 (1 << 12) /* Bit 12: Enable/disable register updates */ + /* Bits 13-15: Reserved */ +#define MCPWM_CON_RUN2 (1 << 16) /* Bit 16: Stops/starts timer channel 2 */ +#define MCPWM_CON_CENTER2 (1 << 17) /* Bit 17: Chan 2 edge/center aligned operation */ +#define MCPWM_CON_POLA2 (1 << 18) /* Bit 18: Polarity of MCOA1 and MCOB1 */ +#define MCPWM_CON_DTE2 (1 << 19) /* Bit 19: Dead time feature control */ +#define MCPWM_CON_DISUP2 (1 << 20) /* Bit 20: Enable/disable register updates */ + /* Bits 21-28: Reserved */ +#define MCPWM_CON_INVBDC (1 << 29) /* Bit 29: Polarity of MCOB outputs (all channels) */ +#define MCPWM_CON_ACMODE (1 << 30) /* Bit 30: 3-phase AC mode select */ +#define MCPWM_CON_DCMODE (1 << 31) /* Bit 31: 3-phase DC mode select */ + +/* Capture Control read address (CAPCON), Capture Control set address (CAPCONSET), + * and Event Control clear address (CAPCONCLR) common register bit defintions + */ + +#define MCPWM_CAPCON_CAP0MCI0RE (1 << 0) /* Bit 0: Enable chan0 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP0MCI0FE (1 << 1) /* Bit 1: Enable chan 0 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP0MCI1RE (1 << 2) /* Bit 2: Enable chan 0 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP0MCI1FE (1 << 3) /* Bit 3: Enable chan 0 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP0MCI2RE (1 << 4) /* Bit 4: Enable chan 0 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP0MCI2FE (1 << 5) /* Bit 5: Enable chan 0 falling edge capture MCI2 */ +#define MCPWM_CAPCON_CAP1MCI0RE (1 << 6) /* Bit 6: Enable chan 1 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP1MCI0FE (1 << 7) /* Bit 7: Enable chan 1 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP1MCI1RE (1 << 8) /* Bit 8: Enable chan 1 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP1MCI1FE (1 << 9) /* Bit 9: Enable chan 1 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP1MCI2RE (1 << 10) /* Bit 10: Enable chan 1 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP1MCI2FE (1 << 11) /* Bit 11: Enable chan 1 falling edge capture MCI2 */ +#define MCPWM_CAPCON_CAP2MCI0RE (1 << 12) /* Bit 12: Enable chan 2 rising edge capture MCI0 */ +#define MCPWM_CAPCON_CAP2MCI0FE (1 << 13) /* Bit 13: Enable chan 2 falling edge capture MCI0 */ +#define MCPWM_CAPCON_CAP2MCI1RE (1 << 14) /* Bit 14: Enable chan 2 rising edge capture MCI1 */ +#define MCPWM_CAPCON_CAP2MCI1FE (1 << 15) /* Bit 15: Enable chan 2 falling edge capture MCI1 */ +#define MCPWM_CAPCON_CAP2MCI2RE (1 << 16) /* Bit 16: Enable chan 2 rising edge capture MCI2 */ +#define MCPWM_CAPCON_CAP2MCI2FE (1 << 17) /* Bit 17: Enable chan 2 falling edge capture MCI2 */ +#define MCPWM_CAPCON_RT0 (1 << 18) /* Bit 18: TC0 reset by chan 0 capture event */ +#define MCPWM_CAPCON_RT1 (1 << 19) /* Bit 19: TC1 reset by chan 1 capture event */ +#define MCPWM_CAPCON_RT2 (1 << 20) /* Bit 20: TC2 reset by chan 2 capture event */ + /* Bits 21-31: Reserved +/* Dead time register */ + +#define MCPWM_DT_DT0_SHIFT (0) /* Bits 0-9: Dead time for channel 0 */ +#define MCPWM_DT_DT0_MASK (0x03ff << MCPWM_DT_DT0_SHIFT) +#define MCPWM_DT_DT1_SHIFT (10) /* Bits 10-19: Dead time for channel 1 */ +#define MCPWM_DT_DT1_MASK (0x03ff << MCPWM_DT_DT1_SHIFT) +#define MCPWM_DT_DT2_SHIFT (20) /* Bits 20-29: Dead time for channel 2 */ +#define MCPWM_DT_DT2_MASK (0x03ff << MCPWM_DT_DT2_SHIFT) + /* Bits 30-31: reserved */ +/* Communication Pattern register */ + +#define MCPWM_MCCP_CCPA0 (1 << 0) /* Bit 0: Iinternal MCOA0 */ +#define MCPWM_MCCP_CCPB0 (1 << 1) /* Bit 1: MCOB0 tracks internal MCOA0 */ +#define MCPWM_MCCP_CCPA1 (1 << 2) /* Bit 2: MCOA1 tracks internal MCOA0 */ +#define MCPWM_MCCP_CCPB1 (1 << 3) /* Bit 3: MCOB1 tracks internal MCOA0 */ +#define MCPWM_MCCP_CCPA2 (1 << 4) /* Bit 4: MCOA2 tracks internal MCOA0 */ +#define MCPWM_MCCP_CCPB2 (1 << 5) /* Bit 5: MCOB2 tracks internal MCOA0 */ + /* Bits 6-31: reserved */ + +/* Interrupt Enable read address (INTEN), Interrupt Enable set address (INTENSET), + * Interrupt Enable clear address (INTENCLR), Interrupt flags read address (INTF), + * Interrupt flags set address (INTFSET), and Interrupt flags clear address (INTFCLR) + * common bit field definitions + */ + +#define MCPWM_INT_ILIM0 (1 << 0) /* Bit 0: Limit interrupts for channel 0 */ +#define MCPWM_INT_IMAT0 (1 << 1) /* Bit 1: Match interrupts for channel 0 */ +#define MCPWM_INT_ICAP0 (1 << 2) /* Bit 2: Capture interrupts for channel 0 */ + /* Bit 3: Reserved */ +#define MCPWM_INT_ILIM1 (1 << 4) /* Bit 4: Limit interrupts for channel 1 */ +#define MCPWM_INT_IMAT1 (1 << 5) /* Bit 5: Match interrupts for channel 1 */ +#define MCPWM_INT_ICAP1 (1 << 6) /* Bit 6: Capture interrupts for channel 1 */ + /* Bit 7: Reserved */ +#define MCPWM_INT_ILIM2 (1 << 8) /* Bit 8: Limit interrupts for channel 2 */ +#define MCPWM_INT_IMAT2 (1 << 9) /* Bit 9: Match interrupts for channel 2 */ +#define MCPWM_INT_ICAP2 (1 << 10) /* Bit 10: Capture interrupts for channel 2 */ + /* Bits 11-14: Reserved */ +#define MCPWM_INT_ABORT (1 << 15) /* Bit 15: Fast abort interrupt */ + /* Bits 16-31: Reserved */ + +/* Count Control read address (CNTCON), Count Control set address (CNTCONSET), and + * Count Control clear address (CNTCONCLR) common register bit definitions. + */ + +#define MCPWM_CNTCON_TC0MCI0RE (1 << 0) /* Bit 0: Counter 0 incr on rising edge MCI0 */ +#define MCPWM_CNTCON_TC0MCI0FE (1 << 1) /* Bit 1: Counter 0 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC0MCI1RE (1 << 2) /* Bit 2: Counter 0 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC0MCI1FE (1 << 3) /* Bit 3: Counter 0 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC0MCI2RE (1 << 4) /* Bit 4: Counter 0 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC0MCI2FE (1 << 5) /* Bit 5: Counter 0 incr onfalling edge MCI2 */ +#define MCPWM_CNTCON_TC1MCI0RE (1 << 6) /* Bit 6: Counter 1 incr onrising edge MCI0 */ +#define MCPWM_CNTCON_TC1MCI0FE (1 << 7) /* Bit 7: Counter 1 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC1MCI1RE (1 << 8) /* Bit 8: Counter 1 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC1MCI1FE (1 << 9) /* Bit 9: Counter 1 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC1MCI2RE (1 << 10) /* Bit 10: Counter 1 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC1MCI2FE (1 << 11) /* Bit 11: Counter 1 incr onfalling edge MCI2 */ +#define MCPWM_CNTCON_TC2MCI0RE (1 << 12) /* Bit 12: Counter 2 incr onrising edge MCI0 */ +#define MCPWM_CNTCON_TC2MCI0FE (1 << 13) /* Bit 13: Counter 2 incr onfalling edge MCI0 */ +#define MCPWM_CNTCON_TC2MCI1RE (1 << 14) /* Bit 14: Counter 2 incr onrising edge MCI1 */ +#define MCPWM_CNTCON_TC2MCI1FE (1 << 15) /* Bit 15: Counter 2 incr onfalling edge MCI1 */ +#define MCPWM_CNTCON_TC2MCI2RE (1 << 16) /* Bit 16: Counter 2 incr onrising edge MCI2 */ +#define MCPWM_CNTCON_TC2MCI2FE (1 << 17) /* Bit 17: Counter 2 incr onfalling edge MCI2 */ + /* Bits 18-28: Reserved */ +#define MCPWM_CNTCON_CNTR0 (1 << 29) /* Bit 29: Channel 0 counter mode */ +#define MCPWM_CNTCON_CNTR1 (1 << 30) /* Bit 30: Channel 1 counter mode */ +#define MCPWM_CNTCON_CNTR2 (1 << 31) /* Bit 31: Channel 2 counter mode */ + +/* Capture clear address */ + +#define MCPWM_CAPCLR_CLR0 (1 << 0) /* Bit 0: Clear CAP0 register */ +#define MCPWM_CAPCLR_CLR1 (1 << 1) /* Bit 1: Clear CAP1 register */ +#define MCPWM_CAPCLR_CLR2 (1 << 2) /* Bit 2: Clear CAP2 register */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_MCPWM_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_otp.h b/arch/arm/src/lpc43xx/chip/lpc43_otp.h new file mode 100644 index 0000000000000000000000000000000000000000..45a777fd943d954a023f1394699456951f08e982 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_otp.h @@ -0,0 +1,192 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_otp.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_OTP_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_OTP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_OTP_MEM00_OFFSET 0x0010 /* General purpose OTP memory 0, word 0 */ +#define LPC43_OTP_MEM01_OFFSET 0x0014 /* General purpose OTP memory 0, word 1 */ +#define LPC43_OTP_MEM02_OFFSET 0x0018 /* General purpose OTP memory 0, word 2 */ +#define LPC43_OTP_MEM03_OFFSET 0x001c /* General purpose OTP memory 0, word 3 */ + +#define LPC43_OTP_MEM10_OFFSET 0x0020 /* General purpose OTP memory 1, word 0 */ +#define LPC43_OTP_MEM11_OFFSET 0x0024 /* General purpose OTP memory 1, word 1 */ +#define LPC43_OTP_MEM12_OFFSET 0x0028 /* General purpose OTP memory 1, word 2 */ +#define LPC43_OTP_MEM13_OFFSET 0x002c /* General purpose OTP memory 1, word 3 */ + +#define LPC43_OTP_MEM20_OFFSET 0x0034 /* General purpose OTP memory 2, word 0 */ +#define LPC43_OTP_MEM21_OFFSET 0x0038 /* General purpose OTP memory 2, word 1 */ +#define LPC43_OTP_MEM22_OFFSET 0x003c /* General purpose OTP memory 2, word 2 */ + +#define LPC43_OTP_AES00_OFFSET 0x0010 /* AES key 0, word 0 */ +#define LPC43_OTP_AES01_OFFSET 0x0014 /* AES key 0, word 1 */ +#define LPC43_OTP_AES02_OFFSET 0x0018 /* AES key 0, word 2 */ +#define LPC43_OTP_AES03_OFFSET 0x001c /* AES key 0, word 3 */ + +#define LPC43_OTP_AES10_OFFSET 0x0020 /* AES key 1, word 0 */ +#define LPC43_OTP_AES11_OFFSET 0x0024 /* AES key 1, word 1 */ +#define LPC43_OTP_AES12_OFFSET 0x0028 /* AES key 1, word 2 */ +#define LPC43_OTP_AES13_OFFSET 0x002c /* AES key 1, word 3 */ + +#define LPC43_OTP_CCD_OFFSET 0x0030 /* Customer control data */ +#define LPC43_OTP_USBID_OFFSET 0x0034 /* USB ID */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_OTP_MEM00 (LPC43_OTPC_BASE+LPC43_OTP_MEM00_OFFSET) +#define LPC43_OTP_MEM01 (LPC43_OTPC_BASE+LPC43_OTP_MEM01_OFFSET) +#define LPC43_OTP_MEM02 (LPC43_OTPC_BASE+LPC43_OTP_MEM02_OFFSET) +#define LPC43_OTP_MEM03 (LPC43_OTPC_BASE+LPC43_OTP_MEM03_OFFSET) + +#define LPC43_OTP_MEM10 (LPC43_OTPC_BASE+LPC43_OTP_MEM10_OFFSET) +#define LPC43_OTP_MEM11 (LPC43_OTPC_BASE+LPC43_OTP_MEM11_OFFSET) +#define LPC43_OTP_MEM12 (LPC43_OTPC_BASE+LPC43_OTP_MEM12_OFFSET) +#define LPC43_OTP_MEM13 (LPC43_OTPC_BASE+LPC43_OTP_MEM13_OFFSET) + +#define LPC43_OTP_MEM20 (LPC43_OTPC_BASE+LPC43_OTP_MEM20_OFFSET) +#define LPC43_OTP_MEM21 (LPC43_OTPC_BASE+LPC43_OTP_MEM21_OFFSET) +#define LPC43_OTP_MEM22 (LPC43_OTPC_BASE+LPC43_OTP_MEM22_OFFSET) + +#define LPC43_OTP_AES00 (LPC43_OTPC_BASE+LPC43_OTP_AES00_OFFSET) +#define LPC43_OTP_AES01 (LPC43_OTPC_BASE+LPC43_OTP_AES01_OFFSET) +#define LPC43_OTP_AES02 (LPC43_OTPC_BASE+LPC43_OTP_AES02_OFFSET) +#define LPC43_OTP_AES03 (LPC43_OTPC_BASE+LPC43_OTP_AES03_OFFSET) + +#define LPC43_OTP_AES10 (LPC43_OTPC_BASE+LPC43_OTP_AES10_OFFSET) +#define LPC43_OTP_AES11 (LPC43_OTPC_BASE+LPC43_OTP_AES11_OFFSET) +#define LPC43_OTP_AES12 (LPC43_OTPC_BASE+LPC43_OTP_AES12_OFFSET) +#define LPC43_OTP_AES13 (LPC43_OTPC_BASE+LPC43_OTP_AES13_OFFSET) + +#define LPC43_OTP_CCD (LPC43_OTPC_BASE+LPC43_OTP_CCD_OFFSET) +#define LPC43_OTP_USBID (LPC43_OTPC_BASE+LPC43_OTP_USBID_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Customer control data */ + /* Bits 0-22: Reserved */ +#define OTP_CCD_USBID (1 << 23) /* Bit 23: USB ID enable */ + /* Bit 24: Reserved */ +#define OPT_CCD_BOOTSRC_SHIFT (25) /* Bits 25-28: Boot source selection in OTP */ +#define OPT_CCD_BOOTSRC_MASK (15 << OPT_CCD_BOOTSRC_SHIFT) +# define OPT_CCD_BOOTSRC_EXT (0 << OPT_CCD_BOOTSRC_SHIFT) /* External pins */ +# define OPT_CCD_BOOTSRC_USART0 (1 << OPT_CCD_BOOTSRC_SHIFT) /* USART0 */ +# define OPT_CCD_BOOTSRC_EMC8 (3 << OPT_CCD_BOOTSRC_SHIFT) /* EMC 8-bit */ +# define OPT_CCD_BOOTSRC_EMC16 (4 << OPT_CCD_BOOTSRC_SHIFT) /* EMC 16-bit */ +# define OPT_CCD_BOOTSRC_EMC32 (5 << OPT_CCD_BOOTSRC_SHIFT) /* EMC 32-bit */ +# define OPT_CCD_BOOTSRC_USB0 (6 << OPT_CCD_BOOTSRC_SHIFT) /* USB0 */ +# define OPT_CCD_BOOTSRC_USB1 (7 << OPT_CCD_BOOTSRC_SHIFT) /* USB1 */ +# define OPT_CCD_BOOTSRC_SPI (8 << OPT_CCD_BOOTSRC_SHIFT) /* SPI (via SSP) */ +# define OPT_CCD_BOOTSRC_USART3 (9 << OPT_CCD_BOOTSRC_SHIFT) /* USART3 */ + /* Bits 29-30: Reserved */ +#define OTP_CCD_JTAGDIS (1 << 31) /* Bit 31: JTAG disable */ + +/* USB ID */ + +#define OTP_USBID_VID_SHIFT (0) /* Bits 0-15: USB vendor ID */ +#define OTP_USBID_VID_MASK (0xffff << OTP_USBID_VID_SHIFT) +#define OTP_USBID_PID_SHIFT (0) /* Bits 16-31: USB product ID */ +#define OTP_USBID_PID_MASK (0xffff << OTP_USBID_PID_SHIFT) + +/* OTP API *************************************************************************/ +/* The AES is controlled through a set of simple API calls located in the LPC43xx + * ROM. This value holds the pointer to the OTP driver table. + */ + +#define LPC43_ROM_OTP_DRIVER_TABLE LPC43_ROM_DRIVER_TABLE1 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +struct lpc43_otp_s +{ + /* Initializes the OTP controller */ + + unsigned int (*otp_Init)(void); + + /* Programs boot source */ + + unsigned int (*otp_ProgBootSrc)(unsigned int src); + + /* JTAG disable. This command disables JTAG only when the device is AES capable. */ + + unsigned int (*otp_ProgJTAGDis)(void); + + /* Programs USB_ID */ + + unsigned int (*otp_ProgUSBID)(unsigned int pid, unsigned int vid); + + /* Reserved */ + + void *reserved[3]; + + /* Program the general purpose OTP memories. Use only if the device is not AES + * capable. + */ + + unsigned int (*otp_ProgGP0)(unsigned int data, unsigned int mask); + unsigned int (*otp_ProgGP1)(unsigned int data, unsigned int mask); + unsigned int (*otp_ProgGP2)(unsigned int data, unsigned int mask); + + /* Program AES keys. 16 byte keys are expected. */ + + unsigned int (*otp_ProgKey1)(unsigned char *key); + unsigned int (*otp_ProgKey2)(unsigned char *key); + + /* Generate new random number using the hardware Random Number Generator (RNG). */ + + unsigned int (*otp_GenRand)(void); +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_OTP_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_pmc.h b/arch/arm/src/lpc43xx/chip/lpc43_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..511c515a28e0a392de023317ab7b4b3d3a8dbf16 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_pmc.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/chip/lpc43_pmc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_PMC_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_PMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define LPC43_PD0_SLEEP0_HWENA_OFFSET 0x0000 /* Hardware sleep event enable register */ +#define LPC43_PD0_SLEEP0_MODE_OFFSET 0x001c /* Power-down mode control register */ + +/* Register Addresses ***************************************************************/ + +#define LPC43_PD0_SLEEP0_HWENA (LPC43_PMC_BASE+LPC43_PD0_SLEEP0_HWENA_OFFSET) +#define LPC43_PD0_SLEEP0_MODE (LPC43_PMC_BASE+LPC43_PD0_SLEEP0_MODE_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Hardware sleep event enable register */ + +#define PD0_SLEEP0_HWENA (1 << 0) /* Bit 0: Enable power down mode */ + /* Bits 1-31: Reserved */ +/* Power-down mode control register */ + +#define PD0_DEEP_SLEEP_MODE 0x003000aa +#define PD0_PWRDOWN_MODE 0x0030fcba +#define PD0_DEEP_PWRDOWN_MODE 0x0030ff7f + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_PMC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_qei.h b/arch/arm/src/lpc43xx/chip/lpc43_qei.h new file mode 100644 index 0000000000000000000000000000000000000000..9994c4e9e7fc5e27445bacc9a3c5cc600dd14831 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_qei.h @@ -0,0 +1,211 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_qei.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_QEI_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_QEI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* Control registers */ + +#define LPC43_QEI_CON_OFFSET 0x0000 /* Control register */ +#define LPC43_QEI_STAT_OFFSET 0x0004 /* Encoder status register */ +#define LPC43_QEI_CONF_OFFSET 0x0008 /* Configuration register */ + +/* Position, index, and timer registers */ + +#define LPC43_QEI_POS_OFFSET 0x000c /* Position register */ +#define LPC43_QEI_MAXPOS_OFFSET 0x0010 /* Maximum position register */ +#define LPC43_QEI_CMPOS0_OFFSET 0x0014 /* Position compare register */ +#define LPC43_QEI_CMPOS1_OFFSET 0x0018 /* Position compare register */ +#define LPC43_QEI_CMPOS2_OFFSET 0x001c /* Position compare register */ +#define LPC43_QEI_INXCNT_OFFSET 0x0020 /* Index count register */ +#define LPC43_QEI_INXCMP0_OFFSET 0x0024 /* Index compare register 0 */ +#define LPC43_QEI_LOAD_OFFSET 0x0028 /* Velocity timer reload register */ +#define LPC43_QEI_TIME_OFFSET 0x002c /* Velocity timer register */ +#define LPC43_QEI_VEL_OFFSET 0x0030 /* Velocity counter register */ +#define LPC43_QEI_CAP_OFFSET 0x0034 /* Velocity capture register */ +#define LPC43_QEI_VELCOMP_OFFSET 0x0038 /* Velocity compare register */ +#define LPC43_QEI_FLTRPHA_OFFSET 0x003c /* Input digital filter register phase A */ +#define LPC43_QEI_FLTRPHB_OFFSET 0x0040 /* Input digital filter register phase B */ +#define LPC43_QEI_FLTRINX_OFFSET 0x0044 /* Input digital filter register index */ +#define LPC43_QEI_WINDOW_OFFSET 0x0048 /* Index acceptance window register */ +#define LPC43_QEI_INXCMP1_OFFSET 0x004c /* Index compare register 1 */ +#define LPC43_QEI_INXCMP2_OFFSET 0x0050 /* Index compare register 2 */ + +/* Interrupt registers */ + +#define LPC43_QEI_IEC_OFFSET 0x0fd8 /* Interrupt enable clear register */ +#define LPC43_QEI_IES_OFFSET 0x0fdc /* Interrupt enable set register */ +#define LPC43_QEI_INTSTAT_OFFSET 0x0fe0 /* Interrupt status register */ +#define LPC43_QEI_IE_OFFSET 0x0fe4 /* Interrupt enable register */ +#define LPC43_QEI_CLR_OFFSET 0x0fe8 /* Interrupt status clear register */ +#define LPC43_QEI_SET_OFFSET 0x0fec /* Interrupt status set register */ + +/* Register addresses ***************************************************************/ +/* Control registers */ + +#define LPC43_QEI_CON (LPC43_QEI_BASE+LPC43_QEI_CON_OFFSET) +#define LPC43_QEI_STAT (LPC43_QEI_BASE+LPC43_QEI_STAT_OFFSET) +#define LPC43_QEI_CONF (LPC43_QEI_BASE+LPC43_QEI_CONF_OFFSET) + +/* Position, index, and timer registers */ + +#define LPC43_QEI_POS (LPC43_QEI_BASE+LPC43_QEI_POS_OFFSET) +#define LPC43_QEI_MAXPOS (LPC43_QEI_BASE+LPC43_QEI_MAXPOS_OFFSET) +#define LPC43_QEI_CMPOS0 (LPC43_QEI_BASE+LPC43_QEI_CMPOS0_OFFSET) +#define LPC43_QEI_CMPOS1 (LPC43_QEI_BASE+LPC43_QEI_CMPOS1_OFFSET) +#define LPC43_QEI_CMPOS2 (LPC43_QEI_BASE+LPC43_QEI_CMPOS2_OFFSET) +#define LPC43_QEI_INXCNT (LPC43_QEI_BASE+LPC43_QEI_INXCNT_OFFSET) +#define LPC43_QEI_INXCMP0 (LPC43_QEI_BASE+LPC43_QEI_INXCMP0_OFFSET) +#define LPC43_QEI_LOAD (LPC43_QEI_BASE+LPC43_QEI_LOAD_OFFSET) +#define LPC43_QEI_TIME (LPC43_QEI_BASE+LPC43_QEI_TIME_OFFSET) +#define LPC43_QEI_VEL (LPC43_QEI_BASE+LPC43_QEI_VEL_OFFSET) +#define LPC43_QEI_CAP (LPC43_QEI_BASE+LPC43_QEI_CAP_OFFSET) +#define LPC43_QEI_VELCOMP (LPC43_QEI_BASE+LPC43_QEI_VELCOMP_OFFSET) +#define LPC43_QEI_FLTRPHA (LPC43_QEI_BASE+LPC43_QEI_FLTRPHA_OFFSET) +#define LPC43_QEI_FLTRPHB (LPC43_QEI_BASE+LPC43_QEI_FLTRPHB_OFFSET) +#define LPC43_QEI_FLTRINX (LPC43_QEI_BASE+LPC43_QEI_FLTRINX_OFFSET) +#define LPC43_QEI_WINDOW (LPC43_QEI_BASE+LPC43_QEI_WINDOW_OFFSET) +#define LPC43_QEI_INXCMP1 (LPC43_QEI_BASE+LPC43_QEI_INXCMP1_OFFSET) +#define LPC43_QEI_INXCMP2 (LPC43_QEI_BASE+LPC43_QEI_INXCMP2_OFFSET) + +/* Interrupt registers */ + +#define LPC43_QEI_IEC (LPC43_QEI_BASE+LPC43_QEI_IEC_OFFSET) +#define LPC43_QEI_IES (LPC43_QEI_BASE+LPC43_QEI_IES_OFFSET) +#define LPC43_QEI_INTSTAT (LPC43_QEI_BASE+LPC43_QEI_INTSTAT_OFFSET) +#define LPC43_QEI_IE (LPC43_QEI_BASE+LPC43_QEI_IE_OFFSET) +#define LPC43_QEI_CLR (LPC43_QEI_BASE+LPC43_QEI_CLR_OFFSET) +#define LPC43_QEI_SET (LPC43_QEI_BASE+LPC43_QEI_SET_OFFSET) + +/* Register bit definitions *********************************************************/ +/* The following registers hold 32-bit integer values and have no bit fields defined + * in this section: + * + * Position register (POS) + * Maximum position register (MAXPOS) + * Position compare register 0 (CMPOS0) + * Position compare register 1 (CMPOS1) + * Position compare register 2 (CMPOS2) + * Index count register (INXCNT) + * Index compare register 0 (INXCMP0) + * Index compare register 1 (INXCMP1) + * Index compare register 2 (INXCMP2) + * Velocity timer reload register (LOAD) + * Velocity timer register (TIME) + * Velocity counter register (VEL) + * Velocity capture register (CAP) + * Velocity compare register (VELCOMP) + * Digital filter registers (FLTRPHA, FLTRPHB) + * Digital filter index register (FLTINX) + * Index acceptance window register (WINDOW) + */ + +/* Control registers */ +/* Control register */ + +#define QEI_CON_RESP (1 << 0) /* Bit 0: Reset position counter */ +#define QEI_CON_RESPI (1 << 1) /* Bit 1: Reset position counter on index */ +#define QEI_CON_RESV (1 << 2) /* Bit 2: Reset velocity */ +#define QEI_CON_RESI (1 << 3) /* Bit 3: Reset index counter */ + /* Bits 4-31: reserved */ +/* Encoder status register */ + +#define QEI_STAT_DIR (1 << 0) /* Bit 0: Direction bit */ + /* Bits 1-31: reserved */ +/* Configuration register */ + +#define QEI_CONF_DIRINV (1 << 0) /* Bit 0: Direction invert */ +#define QEI_CONF_SIGMODE (1 << 1) /* Bit 1: Signal Mode */ +#define QEI_CONF_CAPMODE (1 << 2) /* Bit 2: Capture Mode */ +#define QEI_CONF_INVINX (1 << 3) /* Bit 3: Invert Index */ +#define QEI_CONF_CRESPI (1 << 4) /* Bit 4: Reset position counter on index */ + /* Bits 1-15: reserved */ +#define QEI_CONF_INXGATE_SHIFT (16) /* Bits 16-19: Index gating configuration */ +#define QEI_CONF_INXGATE_MASK (15 << QEI_CONF_INXGATE_SHIFT) +# define QEI_CONF_INXGATE_A1B0 (1 << QEI_CONF_INXGATE_SHIFT) /* Pass index on Pha=1 Phb=0 */ +# define QEI_CONF_INXGATE_A1B1 (2 << QEI_CONF_INXGATE_SHIFT) /* Pass index on Pha=1 Phb=1 */ +# define QEI_CONF_INXGATE_A0B1 (4 << QEI_CONF_INXGATE_SHIFT) /* Pass index on Pha=0 Phb=1 */ +# define QEI_CONF_INXGATE_A0B0 (8 << QEI_CONF_INXGATE_SHIFT) /* Pass index on Pha=0 Phb=0 */ + /* Bits 4-31: reserved */ + +/* Interrupt registers */ +/* Interrupt enable clear register (IEC), Interrupt enable set register (IES), + * Interrupt status register (INTSTAT), Interrupt enable register (IE), Interrupt + * status clear register (CLR), and Interrupt status set register (SET) common + * bit definitions. + */ + +#define QEI_INT_INX (1 << 0) /* Bit 0: Index pulse detected */ +#define QEI_INT_TIM (1 << 1) /* Bit 1: Velocity timer overflow occurred */ +#define QEI_INT_VELC (1 << 2) /* Bit 2: Captured velocity less than compare velocity */ +#define QEI_INT_DIR (1 << 3) /* Bit 3: Change of direction detected */ +#define QEI_INT_ERR (1 << 4) /* Bit 4: Encoder phase error detected */ +#define QEI_INT_ENCLK (1 << 5) /* Bit 5: Eencoder clock pulse detected */ +#define QEI_INT_POS0 (1 << 6) /* Bit 6: Position 0 compare equal to current position */ +#define QEI_INT_POS1 (1 << 7) /* Bit 7: Position 1 compare equal to current position */ +#define QEI_INT_POS2 (1 << 8) /* Bit 8: Position 2 compare equal to current position */ +#define QEI_INT_REV0 (1 << 9) /* Bit 9: Index 0 compare equal to current index count */ +#define QEI_INT_POS0REV (1 << 10) /* Bit 10: Position 0 and revolution count interrupt */ +#define QEI_INT_POS1REV (1 << 11) /* Bit 11: Position 1 and revolution count interrupt */ +#define QEI_INT_POS2REV (1 << 12) /* Bit 12: Position 2 and revolution count interrupt */ +#define QEI_INT_REV1 (1 << 13) /* Bit 13: Index 1 compare equal to current index count */ +#define QEI_INT_REV2 (1 << 14) /* Bit 14: Index 2 compare equal to current index count */ +#define QEI_INT_MAXPOS (1 << 15) /* Bit 15: Current position count goes through MAXPOS */ + /* Bits 16-31: reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_QEI_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_rgu.h b/arch/arm/src/lpc43xx/chip/lpc43_rgu.h new file mode 100644 index 0000000000000000000000000000000000000000..acf2fdc5d86c63eb4a06de4c9c3efd25cb2b6305 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_rgu.h @@ -0,0 +1,669 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_rgu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RGU_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RGU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_RGU_CTRL0_OFFSET 0x100 /* Reset control register 0 */ +#define LPC43_RGU_CTRL1_OFFSET 0x104 /* Reset control register 1 */ +#define LPC43_RGU_STATUS0_OFFSET 0x110 /* Reset status register 0 */ +#define LPC43_RGU_STATUS1_OFFSET 0x114 /* Reset status register 1 */ +#define LPC43_RGU_STATUS2_OFFSET 0x118 /* Reset status register 2 */ +#define LPC43_RGU_STATUS3_OFFSET 0x11c /* Reset status register 3 */ +#define LPC43_RGU_ACTIVE0_OFFSET 0x150 /* Reset active status register */ +#define LPC43_RGU_ACTIVE1_OFFSET 0x154 /* Reset active status register */ + +/* External Status Register Indices */ + +#define RGU_CORE_RST 0 +#define RGU_PERIPH_RST 1 +#define RGU_MASTER_RST 2 +#define RGU_WWDT_RST 4 +#define RGU_CREG_RST 5 +#define RGU_BUS_RST 8 +#define RGU_SCU_RST 9 +#define RGU_M4_RST 13 +#define RGU_LCD_RST 16 +#define RGU_USB0_RST 17 +#define RGU_USB1_RST 18 +#define RGU_DMA_RST 19 +#define RGU_SDIO_RST 20 +#define RGU_EMC_RST 21 +#define RGU_ETHERNET_RST 22 +#define RGU_FLASHA_RST 25 +#define RGU_EEPROM_RST 27 +#define RGU_GPIO_RST 28 +#define RGU_FLASHB_RST 29 +#define RGU_TIMER0_RST 32 +#define RGU_TIMER1_RST 33 +#define RGU_TIMER2_RST 34 +#define RGU_TIMER3_RST 35 +#define RGU_RITIMER_RST 36 +#define RGU_SCT_RST 37 +#define RGU_MCPWM_RST 38 +#define RGU_QEI_RST 39 +#define RGU_ADC0_RST 40 +#define RGU_ADC1_RST 41 +#define RGU_DAC_RST 42 +#define RGU_USART0_RST 44 +#define RGU_UART1_RST 45 +#define RGU_USART2_RST 46 +#define RGU_USART3_RST 47 +#define RGU_I2C0_RST 48 +#define RGU_I2C1_RST 49 +#define RGU_SSP0_RST 50 +#define RGU_SSP1_RST 51 +#define RGU_I2S_RST 52 +#define RGU_SPIFI_RST 53 +#define RGU_CAN1_RST 54 +#define RGU_CAN0_RST 55 +#define RGU_M0APP_RST 56 +#define RGU_SGPIO_RST 57 +#define RGU_SPI_RST 58 + +/* External Status Registers */ + +#define LPC43_RGU_EXTSTAT_OFFSET(n) (0x0400 + ((n) << 2)) /* Reset external status register n=0..63 */ +#define LPC43_RGU_EXTSTAT0_OFFSET 0x400 /* Reset external status register 0 for CORE_RST */ +#define LPC43_RGU_EXTSTAT1_OFFSET 0x404 /* Reset external status register 1 for PERIPH_RST */ +#define LPC43_RGU_EXTSTAT2_OFFSET 0x408 /* Reset external status register 2 for MASTER_RST */ +#define LPC43_RGU_EXTSTAT4_OFFSET 0x410 /* Reset external status register 4 for WWDT_RST */ +#define LPC43_RGU_EXTSTAT5_OFFSET 0x414 /* Reset external status register 5 for CREG_RST */ +#define LPC43_RGU_EXTSTAT8_OFFSET 0x420 /* Reset external status register 8 for BUS_RST */ +#define LPC43_RGU_EXTSTAT9_OFFSET 0x424 /* Reset external status register 9 for SCU_RST */ +#define LPC43_RGU_EXTSTAT13_OFFSET 0x434 /* Reset external status register 13 for M4_RST */ +#define LPC43_RGU_EXTSTAT16_OFFSET 0x440 /* Reset external status register 16 for LCD_RST */ +#define LPC43_RGU_EXTSTAT17_OFFSET 0x444 /* Reset external status register 17 for USB0_RST */ +#define LPC43_RGU_EXTSTAT18_OFFSET 0x448 /* Reset external status register 18 for USB1_RST */ +#define LPC43_RGU_EXTSTAT19_OFFSET 0x44c /* Reset external status register 19 for DMA_RST */ +#define LPC43_RGU_EXTSTAT20_OFFSET 0x450 /* Reset external status register 20 for SDIO_RST */ +#define LPC43_RGU_EXTSTAT21_OFFSET 0x454 /* Reset external status register 21 for EMC_RST */ +#define LPC43_RGU_EXTSTAT22_OFFSET 0x458 /* Reset external status register 22 for ETHERNET_RST */ +#define LPC43_RGU_EXTSTAT25_OFFSET 0x464 /* Reset external status register 25 for FLASHA_RST */ +#define LPC43_RGU_EXTSTAT27_OFFSET 0x46c /* Reset external status register 27 for EEPROM_RST */ +#define LPC43_RGU_EXTSTAT28_OFFSET 0x470 /* Reset external status register 28 for GPIO_RST */ +#define LPC43_RGU_EXTSTAT29_OFFSET 0x474 /* Reset external status register 29 for FLASHB_RST */ +#define LPC43_RGU_EXTSTAT32_OFFSET 0x480 /* Reset external status register 32 for TIMER0_RST */ +#define LPC43_RGU_EXTSTAT33_OFFSET 0x484 /* Reset external status register 33 for TIMER1_RST */ +#define LPC43_RGU_EXTSTAT34_OFFSET 0x488 /* Reset external status register 34 for TIMER2_RST */ +#define LPC43_RGU_EXTSTAT35_OFFSET 0x48c /* Reset external status register 35 for TIMER3_RST */ +#define LPC43_RGU_EXTSTAT36_OFFSET 0x490 /* Reset external status register 36 for RITIMER_RST */ +#define LPC43_RGU_EXTSTAT37_OFFSET 0x494 /* Reset external status register 37 for SCT_RST */ +#define LPC43_RGU_EXTSTAT38_OFFSET 0x498 /* Reset external status register 38 for MCPWM_RST */ +#define LPC43_RGU_EXTSTAT39_OFFSET 0x49c /* Reset external status register 39 for QEI_RST */ +#define LPC43_RGU_EXTSTAT40_OFFSET 0x4a0 /* Reset external status register 40 for ADC0_RST */ +#define LPC43_RGU_EXTSTAT41_OFFSET 0x4a4 /* Reset external status register 41 for ADC1_RST */ +#define LPC43_RGU_EXTSTAT42_OFFSET 0x4a8 /* Reset external status register 42 for DAC_RST */ +#define LPC43_RGU_EXTSTAT44_OFFSET 0x4b0 /* Reset external status register 44 for USART0_RST */ +#define LPC43_RGU_EXTSTAT45_OFFSET 0x4b4 /* Reset external status register 45 for UART1_RST */ +#define LPC43_RGU_EXTSTAT46_OFFSET 0x4b8 /* Reset external status register 46 for USART2_RST */ +#define LPC43_RGU_EXTSTAT47_OFFSET 0x4bc /* Reset external status register 47 for USART3_RST */ +#define LPC43_RGU_EXTSTAT48_OFFSET 0x4c0 /* Reset external status register 48 for I2C0_RST */ +#define LPC43_RGU_EXTSTAT49_OFFSET 0x4c4 /* Reset external status register 49 for I2C1_RST */ +#define LPC43_RGU_EXTSTAT50_OFFSET 0x4c8 /* Reset external status register 50 for SSP0_RST */ +#define LPC43_RGU_EXTSTAT51_OFFSET 0x4cc /* Reset external status register 51 for SSP1_RST */ +#define LPC43_RGU_EXTSTAT52_OFFSET 0x4d0 /* Reset external status register 52 for I2S_RST */ +#define LPC43_RGU_EXTSTAT53_OFFSET 0x4d4 /* Reset external status register 53 for SPIFI_RST */ +#define LPC43_RGU_EXTSTAT54_OFFSET 0x4d8 /* Reset external status register 54 for CAN1_RST */ +#define LPC43_RGU_EXTSTAT55_OFFSET 0x4dc /* Reset external status register 55 for CAN0_RST */ +#define LPC43_RGU_EXTSTAT56_OFFSET 0x4e0 /* Reset external status register 56 for M0APP_RST */ +#define LPC43_RGU_EXTSTAT57_OFFSET 0x4e4 /* Reset external status register 57 for SGPIO_RST */ +#define LPC43_RGU_EXTSTAT58_OFFSET 0x4e8 /* Reset external status register 58 for SPI_RST */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_RGU_CTRL0 (LPC43_RGU_BASE+LPC43_RGU_CTRL0_OFFSET) +#define LPC43_RGU_CTRL1 (LPC43_RGU_BASE+LPC43_RGU_CTRL1_OFFSET) +#define LPC43_RGU_STATUS0 (LPC43_RGU_BASE+LPC43_RGU_STATUS0_OFFSET) +#define LPC43_RGU_STATUS1 (LPC43_RGU_BASE+LPC43_RGU_STATUS1_OFFSET) +#define LPC43_RGU_STATUS2 (LPC43_RGU_BASE+LPC43_RGU_STATUS2_OFFSET) +#define LPC43_RGU_STATUS3 (LPC43_RGU_BASE+LPC43_RGU_STATUS3_OFFSET) +#define LPC43_RGU_ACTIVE0 (LPC43_RGU_BASE+LPC43_RGU_ACTIVE0_OFFSET) +#define LPC43_RGU_ACTIVE1 (LPC43_RGU_BASE+LPC43_RGU_ACTIVE1_OFFSET) + +/* External Status Registers */ + +#define LPC43_RGU_EXTSTAT(n) (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT_OFFSET(n)) +#define LPC43_RGU_EXTSTAT0 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT0_OFFSET) +#define LPC43_RGU_EXTSTAT1 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT1_OFFSET) +#define LPC43_RGU_EXTSTAT2 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT2_OFFSET) +#define LPC43_RGU_EXTSTAT4 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT4_OFFSET) +#define LPC43_RGU_EXTSTAT5 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT5_OFFSET) +#define LPC43_RGU_EXTSTAT8 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT8_OFFSET) +#define LPC43_RGU_EXTSTAT9 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT9_OFFSET) +#define LPC43_RGU_EXTSTAT13 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT13_OFFSET) +#define LPC43_RGU_EXTSTAT16 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT16_OFFSET) +#define LPC43_RGU_EXTSTAT17 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT17_OFFSET) +#define LPC43_RGU_EXTSTAT18 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT18_OFFSET) +#define LPC43_RGU_EXTSTAT19 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT19_OFFSET) +#define LPC43_RGU_EXTSTAT20 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT20_OFFSET) +#define LPC43_RGU_EXTSTAT21 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT21_OFFSET) +#define LPC43_RGU_EXTSTAT22 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT22_OFFSET) +#define LPC43_RGU_EXTSTAT25 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT25_OFFSET) +#define LPC43_RGU_EXTSTAT27 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT27_OFFSET) +#define LPC43_RGU_EXTSTAT28 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT28_OFFSET) +#define LPC43_RGU_EXTSTAT29 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT29_OFFSET) +#define LPC43_RGU_EXTSTAT32 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT32_OFFSET) +#define LPC43_RGU_EXTSTAT33 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT33_OFFSET) +#define LPC43_RGU_EXTSTAT34 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT34_OFFSET) +#define LPC43_RGU_EXTSTAT35 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT35_OFFSET) +#define LPC43_RGU_EXTSTAT36 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT36_OFFSET) +#define LPC43_RGU_EXTSTAT37 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT37_OFFSET) +#define LPC43_RGU_EXTSTAT38 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT38_OFFSET) +#define LPC43_RGU_EXTSTAT39 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT39_OFFSET) +#define LPC43_RGU_EXTSTAT40 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT40_OFFSET) +#define LPC43_RGU_EXTSTAT41 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT41_OFFSET) +#define LPC43_RGU_EXTSTAT42 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT42_OFFSET) +#define LPC43_RGU_EXTSTAT44 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT44_OFFSET) +#define LPC43_RGU_EXTSTAT45 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT45_OFFSET) +#define LPC43_RGU_EXTSTAT46 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT46_OFFSET) +#define LPC43_RGU_EXTSTAT47 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT47_OFFSET) +#define LPC43_RGU_EXTSTAT48 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT48_OFFSET) +#define LPC43_RGU_EXTSTAT49 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT49_OFFSET) +#define LPC43_RGU_EXTSTAT50 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT50_OFFSET) +#define LPC43_RGU_EXTSTAT51 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT51_OFFSET) +#define LPC43_RGU_EXTSTAT52 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT52_OFFSET) +#define LPC43_RGU_EXTSTAT53 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT53_OFFSET) +#define LPC43_RGU_EXTSTAT54 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT54_OFFSET) +#define LPC43_RGU_EXTSTAT55 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT55_OFFSET) +#define LPC43_RGU_EXTSTAT56 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT56_OFFSET) +#define LPC43_RGU_EXTSTAT57 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT57_OFFSET) +#define LPC43_RGU_EXTSTAT58 (LPC43_RGU_BASE+LPC43_RGU_EXTSTAT58_OFFSET) + +/* Alternative naming */ + +#define LPC43_RGU_EXTSTAT_CORE_RST LPC43_RGU_EXTSTAT0 +#define LPC43_RGU_EXTSTAT_PERIPH_RST LPC43_RGU_EXTSTAT1 +#define LPC43_RGU_EXTSTAT_MASTER_RST LPC43_RGU_EXTSTAT2 +#define LPC43_RGU_EXTSTAT_WWDT_RST LPC43_RGU_EXTSTAT4 +#define LPC43_RGU_EXTSTAT_CREG_RST LPC43_RGU_EXTSTAT5 +#define LPC43_RGU_EXTSTAT_BUS_RST LPC43_RGU_EXTSTAT8 +#define LPC43_RGU_EXTSTAT_SCU_RST LPC43_RGU_EXTSTAT9 +#define LPC43_RGU_EXTSTAT_M4_RST LPC43_RGU_EXTSTAT13 +#define LPC43_RGU_EXTSTAT_LCD_RST LPC43_RGU_EXTSTAT16 +#define LPC43_RGU_EXTSTAT_USB0_RST LPC43_RGU_EXTSTAT17 +#define LPC43_RGU_EXTSTAT_USB1_RST LPC43_RGU_EXTSTAT18 +#define LPC43_RGU_EXTSTAT_DMA_RST LPC43_RGU_EXTSTAT19 +#define LPC43_RGU_EXTSTAT_SDIO_RST LPC43_RGU_EXTSTAT20 +#define LPC43_RGU_EXTSTAT_EMC_RST LPC43_RGU_EXTSTAT21 +#define LPC43_RGU_EXTSTAT_ETHERNET_RST LPC43_RGU_EXTSTAT22 +#define LPC43_RGU_EXTSTAT_FLASHA_RST LPC43_RGU_EXTSTAT25 +#define LPC43_RGU_EXTSTAT_EEPROM_RST LPC43_RGU_EXTSTAT27 +#define LPC43_RGU_EXTSTAT_GPIO_RST LPC43_RGU_EXTSTAT28 +#define LPC43_RGU_EXTSTAT_FLASHB_RST LPC43_RGU_EXTSTAT29 +#define LPC43_RGU_EXTSTAT_TIMER0_RST LPC43_RGU_EXTSTAT32 +#define LPC43_RGU_EXTSTAT_TIMER1_RST LPC43_RGU_EXTSTAT33 +#define LPC43_RGU_EXTSTAT_TIMER2_RST LPC43_RGU_EXTSTAT34 +#define LPC43_RGU_EXTSTAT_TIMER3_RST LPC43_RGU_EXTSTAT35 +#define LPC43_RGU_EXTSTAT_RITIMER_RST LPC43_RGU_EXTSTAT36 +#define LPC43_RGU_EXTSTAT_SCT_RST LPC43_RGU_EXTSTAT37 +#define LPC43_RGU_EXTSTAT_MCPWM_RST LPC43_RGU_EXTSTAT38 +#define LPC43_RGU_EXTSTAT_QEI_RST LPC43_RGU_EXTSTAT39 +#define LPC43_RGU_EXTSTAT_ADC0_RST LPC43_RGU_EXTSTAT40 +#define LPC43_RGU_EXTSTAT_ADC1_RST LPC43_RGU_EXTSTAT41 +#define LPC43_RGU_EXTSTAT_DAC_RST LPC43_RGU_EXTSTAT42 +#define LPC43_RGU_EXTSTAT_USART0_RST LPC43_RGU_EXTSTAT44 +#define LPC43_RGU_EXTSTAT_UART1_RST LPC43_RGU_EXTSTAT45 +#define LPC43_RGU_EXTSTAT_USART2_RST LPC43_RGU_EXTSTAT46 +#define LPC43_RGU_EXTSTAT_USART3_RST LPC43_RGU_EXTSTAT47 +#define LPC43_RGU_EXTSTAT_I2C0_RST LPC43_RGU_EXTSTAT48 +#define LPC43_RGU_EXTSTAT_I2C1_RST LPC43_RGU_EXTSTAT49 +#define LPC43_RGU_EXTSTAT_SSP0_RST LPC43_RGU_EXTSTAT50 +#define LPC43_RGU_EXTSTAT_SSP1_RST LPC43_RGU_EXTSTAT51 +#define LPC43_RGU_EXTSTAT_I2S_RST LPC43_RGU_EXTSTAT52 +#define LPC43_RGU_EXTSTAT_SPIFI_RST LPC43_RGU_EXTSTAT53 +#define LPC43_RGU_EXTSTAT_CAN1_RST LPC43_RGU_EXTSTAT54 +#define LPC43_RGU_EXTSTAT_CAN0_RST LPC43_RGU_EXTSTAT55 +#define LPC43_RGU_EXTSTAT_M0APP_RST LPC43_RGU_EXTSTAT56 +#define LPC43_RGU_EXTSTAT_SGPIO_RST LPC43_RGU_EXTSTAT57 +#define LPC43_RGU_EXTSTAT_SPI_RST LPC43_RGU_EXTSTAT58 + +/* Register Bit Definitions *************************************************************************/ + +/* Reset control register 0 */ + +#define RGU_CTRL0_CORE_RST (1 << 0) +#define RGU_CTRL0_PERIPH_RST (1 << 1) +#define RGU_CTRL0_MASTER_RST (1 << 2) + /* Bit 3: Reserved */ +#define RGU_CTRL0_WWDT_RST (1 << 4) /* Writing a one to this bit has no effect */ +#define RGU_CTRL0_CREG_RST (1 << 5) /* Writing a one to this bit has no effect */ + /* Bits 6-7: Reserved */ +#define RGU_CTRL0_BUS_RST (1 << 8) +#define RGU_CTRL0_SCU_RST (1 << 9) + /* Bits 10-12: Reserved */ +#define RGU_CTRL0_M4_RST (1 << 13) + /* Bits 14-15: Reserved */ +#define RGU_CTRL0_LCD_RST (1 << 16) +#define RGU_CTRL0_USB0_RST (1 << 17) +#define RGU_CTRL0_USB1_RST (1 << 18) +#define RGU_CTRL0_DMA_RST (1 << 19) +#define RGU_CTRL0_SDIO_RST (1 << 20) +#define RGU_CTRL0_EMC_RST (1 << 21) +#define RGU_CTRL0_ETHERNET_RST (1 << 22) + /* Bits 23-24: Reserved */ +#define RGU_CTRL0_FLASHA_RST (1 << 25) + /* Bit 26: Reserved */ +#define RGU_CTRL0_EEPROM_RST (1 << 27) +#define RGU_CTRL0_GPIO_RST (1 << 28) +#define RGU_CTRL0_FLASHB_RST (1 << 29) + /* Bits 30-31: Reserved */ +/* Reset control register 1 */ + +#define RGU_CTRL1_TIMER0_RST (1 << 0) +#define RGU_CTRL1_TIMER1_RST (1 << 1) +#define RGU_CTRL1_TIMER2_RST (1 << 2) +#define RGU_CTRL1_TIMER3_RST (1 << 3) +#define RGU_CTRL1_RITIMER_RST (1 << 4) +#define RGU_CTRL1_SCT_RST (1 << 5) +#define RGU_CTRL1_MCPWM_RST (1 << 6) +#define RGU_CTRL1_QEI_RST (1 << 7) +#define RGU_CTRL1_ADC0_RST (1 << 8) +#define RGU_CTRL1_ADC1_RST (1 << 9) +#define RGU_CTRL1_DAC_RST (1 << 10) + /* Bit 11: Reserved */ +#define RGU_CTRL1_USART0_RST (1 << 12) +#define RGU_CTRL1_UART1_RST (1 << 13) +#define RGU_CTRL1_USART2_RST (1 << 14) +#define RGU_CTRL1_USART3_RST (1 << 15) +#define RGU_CTRL1_I2C0_RST (1 << 16) +#define RGU_CTRL1_I2C1_RST (1 << 17) +#define RGU_CTRL1_SSP0_RST (1 << 18) +#define RGU_CTRL1_SSP1_RST (1 << 19) +#define RGU_CTRL1_I2S_RST (1 << 20) +#define RGU_CTRL1_SPIFI_RST (1 << 21) +#define RGU_CTRL1_CAN1_RST (1 << 22) +#define RGU_CTRL1_CAN0_RST (1 << 23) +#define RGU_CTRL1_M0APP_RST (1 << 24) +#define RGU_CTRL1_SGPIO_RST (1 << 25) +#define RGU_CTRL1_SPI_RST (1 << 26) + /* Bits 27-31: Reserved */ +/* Reset status register 0 */ + +#define RGU_RST_NONE 0 /* No reset activated */ +#define RGU_RST_HW 1 /* Reset output activated by input to the reset generator */ +#define RGU_RST_SW 3 /* Reset output activated by software write to RESET_CTRL register */ + +#define RGU_STATUS0_CORE_RST_SHIFT (0) /* Bits 0-1: Status of the CORE_RST reset generator output */ +#define RGU_STATUS0_CORE_RST_MASK (3 << RGU_STATUS0_CORE_RST_SHIFT) +# define RGU_STATUS0_CORE_RST_NONE (0 << RGU_STATUS0_CORE_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_CORE_RST_HW (1 << RGU_STATUS0_CORE_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_CORE_RST_SW (3 << RGU_STATUS0_CORE_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS0_PERIPH_RST_SHIFT (2) /* Bits 2-3: Status of the PERIPH_RST reset generator output */ +#define RGU_STATUS0_PERIPH_RST_MASK (3 << RGU_STATUS0_PERIPH_RST_SHIFT) +# define RGU_STATUS0_PERIPH_RST_NONE (0 << RGU_STATUS0_PERIPH_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_PERIPH_RST_HW (1 << RGU_STATUS0_PERIPH_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_PERIPH_RST_SW (3 << RGU_STATUS0_PERIPH_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS0_MASTER_RST_SHIFT (4) /* Bits 4-5: Status of the MASTER_RST reset generator output */ +#define RGU_STATUS0_MASTER_RST_MASK (3 << RGU_STATUS0_MASTER_RST_SHIFT) +# define RGU_STATUS0_MASTER_RST_NONE (0 << RGU_STATUS0_MASTER_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_MASTER_RST_HW (1 << RGU_STATUS0_MASTER_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_MASTER_RST_SW (3 << RGU_STATUS0_MASTER_RST_SHIFT) /* Activated by software */ + /* Bits 6-7: Reserved */ +#define RGU_STATUS0_WWDT_RST_SHIFT (8) /* Bits 8-9: Status of the WWDT_RST reset generator output */ +#define RGU_STATUS0_WWDT_RST_MASK (3 << RGU_STATUS0_WWDT_RST_SHIFT) +# define RGU_STATUS0_WWDT_RST_NONE (0 << RGU_STATUS0_WWDT_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_WWDT_RST_HW (1 << RGU_STATUS0_WWDT_RST_SHIFT) /* Activated by reset generator */ +#define RGU_STATUS0_CREG_RST_SHIFT (10) /* Bits 10-11: Status of the CREG_RST reset generator output */ +#define RGU_STATUS0_CREG_RST_MASK (3 << RGU_STATUS0_CREG_RST_SHIFT) +# define RGU_STATUS0_CREG_RST_NONE (0 << RGU_STATUS0_CREG_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_CREG_RST_HW (1 << RGU_STATUS0_CREG_RST_SHIFT) /* Activated by reset generator */ + /* Bits 12-15: Reserved */ +#define RGU_STATUS0_BUS_RST_SHIFT (16) /* Bits 16-17: Status of the BUS_RST reset generator output */ +#define RGU_STATUS0_BUS_RST_MASK (3 << RGU_STATUS0_BUS_RST_SHIFT) +# define RGU_STATUS0_BUS_RST_NONE (0 << RGU_STATUS0_BUS_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_BUS_RST_HW (1 << RGU_STATUS0_BUS_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_BUS_RST_SW (3 << RGU_STATUS0_BUS_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS0_SCU_RST_SHIFT (18) /* Bits 18-19: Status of the SCU_RST reset generator output */ +#define RGU_STATUS0_SCU_RST_MASK (3 << RGU_STATUS0_SCU_RST_SHIFT) +# define RGU_STATUS0_SCU_RST_NONE (0 << RGU_STATUS0_SCU_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_SCU_RST_HW (1 << RGU_STATUS0_SCU_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_SCU_RST_SW (3 << RGU_STATUS0_SCU_RST_SHIFT) /* Activated by software */ + /* Bits 20-25: Reserved */ +#define RGU_STATUS0_M4_RST_SHIFT (26) /* Bits 26-27: Status of the M4_RST reset generator output */ +#define RGU_STATUS0_M4_RST_MASK (3 << RGU_STATUS0_M4_RST_SHIFT) +# define RGU_STATUS0_M4_RST_NONE (0 << RGU_STATUS0_M4_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS0_M4_RST_HW (1 << RGU_STATUS0_M4_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS0_M4_RST_SW (3 << RGU_STATUS0_M4_RST_SHIFT) /* Activated by software */ + /* Bits 29-31: Reserved */ +/* Reset status register 1 */ + +#define RGU_STATUS1_LCD_RST_SHIFT (0) /* Bits 0-1: Status of the LCD_RST reset generator output */ +#define RGU_STATUS1_LCD_RST_MASK (3 << RGU_STATUS1_LCD_RST_SHIFT) +# define RGU_STATUS1_LCD_RST_NONE (0 << RGU_STATUS1_LCD_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_LCD_RST_HW (1 << RGU_STATUS1_LCD_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_LCD_RST_SW (3 << RGU_STATUS1_LCD_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_USB0_RST_SHIFT (2) /* Bits 2-3: Status of the USB0_RST reset generator output */ +#define RGU_STATUS1_USB0_RST_MASK (3 << RGU_STATUS1_USB0_RST_SHIFT) +# define RGU_STATUS1_USB0_RST_NONE (0 << RGU_STATUS1_USB0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_USB0_RST_HW (1 << RGU_STATUS1_USB0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_USB0_RST_SW (3 << RGU_STATUS1_USB0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_USB1_RST_SHIFT (4) /* Bits 4-5: Status of the USB1_RST reset generator output */ +#define RGU_STATUS1_USB1_RST_MASK (3 << RGU_STATUS1_USB1_RST_SHIFT) +# define RGU_STATUS1_USB1_RST_NONE (0 << RGU_STATUS1_USB1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_USB1_RST_HW (1 << RGU_STATUS1_USB1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_USB1_RST_SW (3 << RGU_STATUS1_USB1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_DMA_RST_SHIFT (6) /* Bits 6-7: Status of the DMA_RST reset generator output */ +#define RGU_STATUS1_DMA_RST_MASK (3 << RGU_STATUS1_DMA_RST_SHIFT) +# define RGU_STATUS1_DMA_RST_NONE (0 << RGU_STATUS1_DMA_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_DMA_RST_HW (1 << RGU_STATUS1_DMA_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_DMA_RST_SW (3 << RGU_STATUS1_DMA_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_SDIO_RST_SHIFT (8) /* Bits 8-9: Status of the SDIO_RST reset generator output */ +#define RGU_STATUS1_SDIO_RST_MASK (3 << RGU_STATUS1_SDIO_RST_SHIFT) +# define RGU_STATUS1_SDIO_RST_NONE (0 << RGU_STATUS1_SDIO_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_SDIO_RST_HW (1 << RGU_STATUS1_SDIO_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_SDIO_RST_SW (3 << RGU_STATUS1_SDIO_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_EMC_RST_SHIFT (10) /* Bits 10-11: Status of the EMC_RST reset generator output */ +#define RGU_STATUS1_EMC_RST_MASK (3 << RGU_STATUS1_EMC_RST_SHIFT) +# define RGU_STATUS1_EMC_RST_NONE (0 << RGU_STATUS1_EMC_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_EMC_RST_HW (1 << RGU_STATUS1_EMC_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_EMC_RST_SW (3 << RGU_STATUS1_EMC_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_ETHERNET_RST_SHIFT (12) /* Bits 12-13: Status of the ETHERNET_RST reset generator output */ +#define RGU_STATUS1_ETHERNET_RST_MASK (3 << RGU_STATUS1_ETHERNET_RST_SHIFT) +# define RGU_STATUS1_ETHERNET_RST_NONE (0 << RGU_STATUS1_ETHERNET_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_ETHERNET_RST_HW (1 << RGU_STATUS1_ETHERNET_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_ETHERNET_RST_SW (3 << RGU_STATUS1_ETHERNET_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_FLASHA_RST_SHIFT (18) /* Bits 18-19: Status of the FLASHA_RST reset generator output */ +#define RGU_STATUS1_FLASHA_RST_MASK (3 << RGU_STATUS1_FLASHA_RST_SHIFT) +# define RGU_STATUS1_FLASHA_RST_NONE (0 << RGU_STATUS1_FLASHA_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_FLASHA_RST_HW (1 << RGU_STATUS1_FLASHA_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_FLASHA_RST_SW (3 << RGU_STATUS1_FLASHA_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_EEPROM_RST_SHIFT (22) /* Bits 22-23: Status of the EEPROM_RST reset generator output */ +#define RGU_STATUS1_EEPROM_RST_MASK (3 << RGU_STATUS1_EEPROM_RST_SHIFT) +# define RGU_STATUS1_EEPROM_RST_NONE (0 << RGU_STATUS1_EEPROM_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_EEPROM_RST_HW (1 << RGU_STATUS1_EEPROM_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_EEPROM_RST_SW (3 << RGU_STATUS1_EEPROM_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_GPIO_RST_SHIFT (24) /* Bits 24-25: Status of the GPIO_RST reset generator output */ +#define RGU_STATUS1_GPIO_RST_MASK (3 << RGU_STATUS1_GPIO_RST_SHIFT) +# define RGU_STATUS1_GPIO_RST_NONE (0 << RGU_STATUS1_GPIO_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_GPIO_RST_HW (1 << RGU_STATUS1_GPIO_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_GPIO_RST_SW (3 << RGU_STATUS1_GPIO_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS1_FLASHB_RST_SHIFT (26) /* Bits 26-27: Status of the FLASHB_RST reset generator output */ +#define RGU_STATUS1_FLASHB_RST_MASK (3 << RGU_STATUS1_FLASHB_RST_SHIFT) +# define RGU_STATUS1_FLASHB_RST_NONE (0 << RGU_STATUS1_FLASHB_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS1_FLASHB_RST_HW (1 << RGU_STATUS1_FLASHB_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS1_FLASHB_RST_SW (3 << RGU_STATUS1_FLASHB_RST_SHIFT) /* Activated by software */ + /* Bits 28-31: Reserved */ +/* Reset status register 2 */ + +#define RGU_STATUS2_TIMER0_RST_SHIFT (0) /* Bits 0-1: 1:0 Status of the TIMER0_RST reset generator output */ +#define RGU_STATUS2_TIMER0_RST_MASK (3 << RGU_STATUS2_TIMER0_RST_SHIFT) +# define RGU_STATUS2_TIMER0_RST_NONE (0 << RGU_STATUS2_TIMER0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_TIMER0_RST_HW (1 << RGU_STATUS2_TIMER0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_TIMER0_RST_SW (3 << RGU_STATUS2_TIMER0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_TIMER1_RST_SHIFT (2) /* Bits 2-3: 3:2 Status of the TIMER1_RST reset generator output */ +#define RGU_STATUS2_TIMER1_RST_MASK (3 << RGU_STATUS2_TIMER1_RST_SHIFT) +# define RGU_STATUS2_TIMER1_RST_NONE (0 << RGU_STATUS2_TIMER1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_TIMER1_RST_HW (1 << RGU_STATUS2_TIMER1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_TIMER1_RST_SW (3 << RGU_STATUS2_TIMER1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_TIMER2_RST_SHIFT (4) /* Bits 4-5: 5:4 Status of the TIMER2_RST reset generator output */ +#define RGU_STATUS2_TIMER2_RST_MASK (3 << RGU_STATUS2_TIMER2_RST_SHIFT) +# define RGU_STATUS2_TIMER2_RST_NONE (0 << RGU_STATUS2_TIMER2_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_TIMER2_RST_HW (1 << RGU_STATUS2_TIMER2_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_TIMER2_RST_SW (3 << RGU_STATUS2_TIMER2_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_TIMER3_RST_SHIFT (6) /* Bits 6-7: 7:6 Status of the TIMER3_RST reset generator output */ +#define RGU_STATUS2_TIMER3_RST_MASK (3 << RGU_STATUS2_TIMER3_RST_SHIFT) +# define RGU_STATUS2_TIMER3_RST_NONE (0 << RGU_STATUS2_TIMER3_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_TIMER3_RST_HW (1 << RGU_STATUS2_TIMER3_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_TIMER3_RST_SW (3 << RGU_STATUS2_TIMER3_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_RITIMER_RST_SHIFT (8) /* Bits 8-9: 9:8 Status of the RITIMER_RST reset generator output */ +#define RGU_STATUS2_RITIMER_RST_MASK (3 << RGU_STATUS2_RITIMER_RST_SHIFT) +# define RGU_STATUS2_RITIMER_RST_NONE (0 << RGU_STATUS2_RITIMER_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_RITIMER_RST_HW (1 << RGU_STATUS2_RITIMER_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_RITIMER_RST_SW (3 << RGU_STATUS2_RITIMER_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_SCT_RST_SHIFT (10) /* Bits 10-11: 11:10 Status of the SCT_RST reset generator output */ +#define RGU_STATUS2_SCT_RST_MASK (3 << RGU_STATUS2_SCT_RST_SHIFT) +# define RGU_STATUS2_SCT_RST_NONE (0 << RGU_STATUS2_SCT_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_SCT_RST_HW (1 << RGU_STATUS2_SCT_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_SCT_RST_SW (3 << RGU_STATUS2_SCT_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_MCPWM_RST_SHIFT (12) /* Bits 12-13: 13:12 Status of the MOTOCONPWM_RST reset generator output */ +#define RGU_STATUS2_MCPWM_RST_MASK (3 << RGU_STATUS2_MCPWM_RST_SHIFT) +# define RGU_STATUS2_MCPWM_RST_NONE (0 << RGU_STATUS2_MCPWM_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_MCPWM_RST_HW (1 << RGU_STATUS2_MCPWM_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_MCPWM_RST_SW (3 << RGU_STATUS2_MCPWM_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_QEI_RST_SHIFT (14) /* Bits 14-15: 15:14 Status of the QEI_RST reset generator output */ +#define RGU_STATUS2_QEI_RST_MASK (3 << RGU_STATUS2_QEI_RST_SHIFT) +# define RGU_STATUS2_QEI_RST_NONE (0 << RGU_STATUS2_QEI_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_QEI_RST_HW (1 << RGU_STATUS2_QEI_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_QEI_RST_SW (3 << RGU_STATUS2_QEI_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_ADC0_RST_SHIFT (16) /* Bits 16-17: 17:16 Status of the ADC0_RST reset generator output */ +#define RGU_STATUS2_ADC0_RST_MASK (3 << RGU_STATUS2_ADC0_RST_SHIFT) +# define RGU_STATUS2_ADC0_RST_NONE (0 << RGU_STATUS2_ADC0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_ADC0_RST_HW (1 << RGU_STATUS2_ADC0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_ADC0_RST_SW (3 << RGU_STATUS2_ADC0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_ADC1_RST_SHIFT (18) /* Bits 18-19: 19:18 Status of the ADC1_RST reset generator output */ +#define RGU_STATUS2_ADC1_RST_MASK (3 << RGU_STATUS2_ADC1_RST_SHIFT) +# define RGU_STATUS2_ADC1_RST_NONE (0 << RGU_STATUS2_ADC1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_ADC1_RST_HW (1 << RGU_STATUS2_ADC1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_ADC1_RST_SW (3 << RGU_STATUS2_ADC1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_DAC_RST_SHIFT (20) /* Bits 20-21: 21:20 Status of the DAC_RST reset generator output */ +#define RGU_STATUS2_DAC_RST_MASK (3 << RGU_STATUS2_DAC_RST_SHIFT) +# define RGU_STATUS2_DAC_RST_NONE (0 << RGU_STATUS2_DAC_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_DAC_RST_HW (1 << RGU_STATUS2_DAC_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_DAC_RST_SW (3 << RGU_STATUS2_DAC_RST_SHIFT) /* Activated by software */ + /* Bits 22-23: Reserved */ +#define RGU_STATUS2_USART0_RST_SHIFT (24) /* Bits 24-24: 25:24 Status of the USART0_RST reset generator output */ +#define RGU_STATUS2_USART0_RST_MASK (3 << RGU_STATUS2_USART0_RST_SHIFT) +# define RGU_STATUS2_USART0_RST_NONE (0 << RGU_STATUS2_USART0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_USART0_RST_HW (1 << RGU_STATUS2_USART0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_USART0_RST_SW (3 << RGU_STATUS2_USART0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_UART1_RST_SHIFT (26) /* Bits 26-27: 27:26 Status of the UART1_RST reset generator output */ +#define RGU_STATUS2_UART1_RST_MASK (3 << RGU_STATUS2_UART1_RST_SHIFT) +# define RGU_STATUS2_UART1_RST_NONE (0 << RGU_STATUS2_UART1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_UART1_RST_HW (1 << RGU_STATUS2_UART1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_UART1_RST_SW (3 << RGU_STATUS2_UART1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_USART2_RST_SHIFT (28) /* Bits 28-29: 29:28 Status of the USART2_RST reset generator output */ +#define RGU_STATUS2_USART2_RST_MASK (3 << RGU_STATUS2_USART2_RST_SHIFT) +# define RGU_STATUS2_USART2_RST_NONE (0 << RGU_STATUS2_USART2_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_USART2_RST_HW (1 << RGU_STATUS2_USART2_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_USART2_RST_SW (3 << RGU_STATUS2_USART2_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS2_USART3_RST_SHIFT (30) /* Bits 30-31: 31:30 Status of the USART3_RST reset generator output */ +#define RGU_STATUS2_USART3_RST_MASK (3 << RGU_STATUS2_USART3_RST_SHIFT) +# define RGU_STATUS2_USART3_RST_NONE (0 << RGU_STATUS2_USART3_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS2_USART3_RST_HW (1 << RGU_STATUS2_USART3_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS2_USART3_RST_SW (3 << RGU_STATUS2_USART3_RST_SHIFT) /* Activated by software */ + +/* Reset status register 3 */ + +#define RGU_STATUS3_I2C0_RST_SHIFT (0) /* Bits 0-1: 1:0 Status of the I2C0_RST reset generator output */ +#define RGU_STATUS3_I2C0_RST_MASK (3 << RGU_STATUS3_I2C0_RST_SHIFT) +# define RGU_STATUS3_I2C0_RST_NONE (0 << RGU_STATUS3_I2C0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_I2C0_RST_HW (1 << RGU_STATUS3_I2C0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_I2C0_RST_SW (3 << RGU_STATUS3_I2C0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_I2C1_RST_SHIFT (2) /* Bits 2-3: 3:2 Status of the I2C1_RST reset generator output */ +#define RGU_STATUS3_I2C1_RST_MASK (3 << RGU_STATUS3_I2C1_RST_SHIFT) +# define RGU_STATUS3_I2C1_RST_NONE (0 << RGU_STATUS3_I2C1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_I2C1_RST_HW (1 << RGU_STATUS3_I2C1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_I2C1_RST_SW (3 << RGU_STATUS3_I2C1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_SSP0_RST_SHIFT (4) /* Bits 4-5: 5:4 Status of the SSP0_RST reset generator output */ +#define RGU_STATUS3_SSP0_RST_MASK (3 << RGU_STATUS3_SSP0_RST_SHIFT) +# define RGU_STATUS3_SSP0_RST_NONE (0 << RGU_STATUS3_SSP0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_SSP0_RST_HW (1 << RGU_STATUS3_SSP0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_SSP0_RST_SW (3 << RGU_STATUS3_SSP0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_SSP1_RST_SHIFT (6) /* Bits 6-7: 7:6 Status of the SSP1_RST reset generator output */ +#define RGU_STATUS3_SSP1_RST_MASK (3 << RGU_STATUS3_SSP1_RST_SHIFT) +# define RGU_STATUS3_SSP1_RST_NONE (0 << RGU_STATUS3_SSP1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_SSP1_RST_HW (1 << RGU_STATUS3_SSP1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_SSP1_RST_SW (3 << RGU_STATUS3_SSP1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_I2S_RST_SHIFT (8) /* Bits 8-9: 9:8 Status of the I2S_RST reset generator output */ +#define RGU_STATUS3_I2S_RST_MASK (3 << RGU_STATUS3_I2S_RST_SHIFT) +# define RGU_STATUS3_I2S_RST_NONE (0 << RGU_STATUS3_I2S_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_I2S_RST_HW (1 << RGU_STATUS3_I2S_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_I2S_RST_SW (3 << RGU_STATUS3_I2S_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_SPIFI_RST_SHIFT (10) /* Bits 10-11: 11:10 Status of the SPIFI_RST reset generator output */ +#define RGU_STATUS3_SPIFI_RST_MASK (3 << RGU_STATUS3_SPIFI_RST_SHIFT) +# define RGU_STATUS3_SPIFI_RST_NONE (0 << RGU_STATUS3_SPIFI_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_SPIFI_RST_HW (1 << RGU_STATUS3_SPIFI_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_SPIFI_RST_SW (3 << RGU_STATUS3_SPIFI_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_CAN1_RST_SHIFT (12) /* Bits 12-13: 13:12 Status of the CAN1_RST reset generator output */ +#define RGU_STATUS3_CAN1_RST_MASK (3 << RGU_STATUS3_CAN1_RST_SHIFT) +# define RGU_STATUS3_CAN1_RST_NONE (0 << RGU_STATUS3_CAN1_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_CAN1_RST_HW (1 << RGU_STATUS3_CAN1_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_CAN1_RST_SW (3 << RGU_STATUS3_CAN1_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_CAN0_RST_SHIFT (14) /* Bits 14-15: 15:14 Status of the CAN0_RST reset generator output */ +#define RGU_STATUS3_CAN0_RST_MASK (3 << RGU_STATUS3_CAN0_RST_SHIFT) +# define RGU_STATUS3_CAN0_RST_NONE (0 << RGU_STATUS3_CAN0_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_CAN0_RST_HW (1 << RGU_STATUS3_CAN0_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_CAN0_RST_SW (3 << RGU_STATUS3_CAN0_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_M0APP_RST_SHIFT (16) /* Bits 16-17: 17:16 Status of the M0APP_RST reset generator output */ +#define RGU_STATUS3_M0APP_RST_MASK (3 << RGU_STATUS3_M0APP_RST_SHIFT) +# define RGU_STATUS3_M0APP_RST_NONE (0 << RGU_STATUS3_M0APP_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_M0APP_RST_HW (1 << RGU_STATUS3_M0APP_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_M0APP_RST_SW (3 << RGU_STATUS3_M0APP_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_SGPIO_RST_SHIFT (18) /* Bits 18-19: 19:18 Status of the SGPIO_RST reset generator output */ +#define RGU_STATUS3_SGPIO_RST_MASK (3 << RGU_STATUS3_SGPIO_RST_SHIFT) +# define RGU_STATUS3_SGPIO_RST_NONE (0 << RGU_STATUS3_SGPIO_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_SGPIO_RST_HW (1 << RGU_STATUS3_SGPIO_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_SGPIO_RST_SW (3 << RGU_STATUS3_SGPIO_RST_SHIFT) /* Activated by software */ +#define RGU_STATUS3_SPI_RST_SHIFT (20) /* Bits 20-21: 21:20 Status of the SPI_RST reset generator output */ +#define RGU_STATUS3_SPI_RST_MASK (3 << RGU_STATUS3_SPI_RST_SHIFT) +# define RGU_STATUS3_SPI_RST_NONE (0 << RGU_STATUS3_SPI_RST_SHIFT) /* No reset activated */ +# define RGU_STATUS3_SPI_RST_HW (1 << RGU_STATUS3_SPI_RST_SHIFT) /* Activated by reset generator */ +# define RGU_STATUS3_SPI_RST_SW (3 << RGU_STATUS3_SPI_RST_SHIFT) /* Activated by software */ + /* Bits 22-31: Reserved */ +/* Reset active status register */ + +#define RGU_ACTIVE0_CORE_RST (1 << 0) +#define RGU_ACTIVE0_PERIPH_RST (1 << 1) +#define RGU_ACTIVE0_MASTER_RST (1 << 2) + /* Bit 3: Reserved */ +#define RGU_ACTIVE0_WWDT_RST (1 << 4) +#define RGU_ACTIVE0_CREG_RST (1 << 5) + /* Bits 6-7: Reserved */ +#define RGU_ACTIVE0_BUS_RST (1 << 8) +#define RGU_ACTIVE0_SCU_RST (1 << 9) + /* Bits 10-12: Reserved */ +#define RGU_ACTIVE0_M4_RST (1 << 13) + /* Bits 14-15: Reserved */ +#define RGU_ACTIVE0_LCD_RST (1 << 16) +#define RGU_ACTIVE0_USB0_RST (1 << 17) +#define RGU_ACTIVE0_USB1_RST (1 << 18) +#define RGU_ACTIVE0_DMA_RST (1 << 19) +#define RGU_ACTIVE0_SDIO_RST (1 << 20) +#define RGU_ACTIVE0_EMC_RST (1 << 21) +#define RGU_ACTIVE0_ETHERNET_RST (1 << 22) + /* Bits 23-24: Reserved */ +#define RGU_ACTIVE0_FLASHA_RST (1 << 25) + /* Bit 26: Reserved */ +#define RGU_ACTIVE0_EEPROM_RST (1 << 27) +#define RGU_ACTIVE0_GPIO_RST (1 << 28) +#define RGU_ACTIVE0_FLASHB_RST (1 << 29) + /* Bits 30-31: Reserved */ +/* Reset active status register */ + +#define RGU_ACTIVE1_TIMER0_RST (1 << 0) +#define RGU_ACTIVE1_TIMER1_RST (1 << 1) +#define RGU_ACTIVE1_TIMER2_RST (1 << 2) +#define RGU_ACTIVE1_TIMER3_RST (1 << 3) +#define RGU_ACTIVE1_RITIMER_RST (1 << 4) +#define RGU_ACTIVE1_SCT_RST (1 << 5) +#define RGU_ACTIVE1_MCPWM_RST (1 << 6) +#define RGU_ACTIVE1_QEI_RST (1 << 7) +#define RGU_ACTIVE1_ADC0_RST (1 << 8) +#define RGU_ACTIVE1_ADC1_RST (1 << 9) +#define RGU_ACTIVE1_DAC_RST (1 << 10) + /* Bit 11: Reserved */ +#define RGU_ACTIVE1_USART0_RST (1 << 12) +#define RGU_ACTIVE1_UART1_RST (1 << 13) +#define RGU_ACTIVE1_USART2_RST (1 << 14) +#define RGU_ACTIVE1_USART3_RST (1 << 15) +#define RGU_ACTIVE1_I2C0_RST (1 << 16) +#define RGU_ACTIVE1_I2C1_RST (1 << 17) +#define RGU_ACTIVE1_SSP0_RST (1 << 18) +#define RGU_ACTIVE1_SSP1_RST (1 << 19) +#define RGU_ACTIVE1_I2S_RST (1 << 20) +#define RGU_ACTIVE1_SPIFI_RST (1 << 21) +#define RGU_ACTIVE1_CAN1_RST (1 << 22) +#define RGU_ACTIVE1_CAN0_RST (1 << 23) +#define RGU_ACTIVE1_M0APP_RST (1 << 24) +#define RGU_ACTIVE1_SGPIO_RST (1 << 25) +#define RGU_ACTIVE1_SPI_RST (1 << 26) + /* Bits 27-31: Reserved */ +/* Reset external status register 0 for CORE_RST */ + +#define RGU_EXTSTAT_CORE_EXTRESET (1 << 0) /* Bit 0: Reset activated by external reset from reset pin */ + /* Bits 1-3: Reserved */ +#define RGU_EXTSTAT_CORE_BODRESET (1 << 4) /* Bit 4: Reset activated by BOD reset */ +#define RGU_EXTSTAT_CORE_WWDTRESET (1 << 5) /* Bit 5: Reset activated by WWDT time-out */ + /* Bits 6-31: Reserved */ +/* Reset external status register 1 for PERIPH_RST */ + /* Bit 0: Reserved */ +#define RGU_EXTSTAT_PERIPH_CORERESET (1 << 1) /* Bit 1: Reset activated by CORE_RST output */ + /* Bits 2-31: Reserved */ +/* Reset external status register 2 for MASTER_RST */ + /* Bits 0-1: Reserved */ +#define RGU_EXTSTAT_MASTER_PERIPHRESET (1 << 2) /* Bit 2: Reset activated by PERIPHERAL_RST output */ + /* Bits 2-31: Reserved */ +/* Reset external status register 4 for WWDT_RST */ + /* Bit 0: Reserved */ +#define RGU_EXTSTAT_WWDT_CORERESET (1 << 1) /* Bit 1: Reset activated by CORE_RST output */ + /* Bits 2-31: Reserved */ +/* Reset external status register 5 for CREG_RST */ + /* Bit 0: Reserved */ +#define RGU_EXTSTAT_CREG_CORERESET (1 << 1) /* Bit 1: Reset activated by CORE_RST output */ + /* Bits 2-31: Reserved */ +/* Reset external status registers for PERIPHERAL_RESET */ + /* Bits 0-1: Reserved */ +#define RGU_EXTSTAT_PERIPH_RESET (1 << 2) /* Bit 2: Reset activated by PERIPHERAL_RST output */ + /* Bits 2-31: Reserved */ +/* Reset external status registers for MASTER_RESET */ + /* Bits 0-2: Reserved */ +#define RGU_EXTSTAT_MASTER_RESET (1 << 3) /* Bit 3: Reset activated by MASTER_RST output */ + /* Bits 2-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RGU_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_rit.h b/arch/arm/src/lpc43xx/chip/lpc43_rit.h new file mode 100644 index 0000000000000000000000000000000000000000..71671cd3ab0d57433df4d67409e6c528e0568c7f --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_rit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_rit.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Brandon Warhurst + * Original Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RIT_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_RIT_COMPVAL_OFFSET 0x0000 /* Compare register */ +#define LPC43_RIT_MASK_OFFSET 0x0004 /* Mask register */ +#define LPC43_RIT_CTRL_OFFSET 0x0008 /* Control register */ +#define LPC43_RIT_COUNTER_OFFSET 0x000c /* 32-bit counter */ + +/* Register addresses ***************************************************************/ + +#define LPC43_RIT_COMPVAL (LPC43_RIT_BASE+LPC43_RIT_COMPVAL_OFFSET) +#define LPC43_RIT_MASK (LPC43_RIT_BASE+LPC43_RIT_MASK_OFFSET) +#define LPC43_RIT_CTRL (LPC43_RIT_BASE+LPC43_RIT_CTRL_OFFSET) +#define LPC43_RIT_COUNTER (LPC43_RIT_BASE+LPC43_RIT_COUNTER_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Compare register (Bits 0-31: value compared to the counter) */ + +/* Mask register (Bits 0-31: 32-bit mask value) */ + +/* Control register */ + +#define RIT_CTRL_INT (1 << 0) /* Bit 0: Interrupt flag */ +#define RIT_CTRL_ENCLR (1 << 1) /* Bit 1: Timer enable clear */ +#define RIT_CTRL_ENBR (1 << 2) /* Bit 2: Timer enable for debug */ +#define RIT_CTRL_EN (1 << 3) /* Bit 3: Timer enable */ + /* Bits 4-31: Reserved */ +/* 32-bit counter (Bits 0-31: 32-bit up counter) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_RIT_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_rtc.h b/arch/arm/src/lpc43xx/chip/lpc43_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..9713493543dbbf1217e7b101f24c36f1ea80d81d --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_rtc.h @@ -0,0 +1,371 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_rtc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_RTC_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* Miscellaneous registers */ + +#define LPC43_RTC_ILR_OFFSET 0x0000 /* Interrupt Location Register */ +#define LPC43_RTC_CCR_OFFSET 0x0008 /* Clock Control Register */ +#define LPC43_RTC_CIIR_OFFSET 0x000c /* Counter Increment Interrupt Register */ +#define LPC43_RTC_AMR_OFFSET 0x0010 /* Alarm Mask Register */ + +/* Consolidated time registers */ + +#define LPC43_RTC_CTIME0_OFFSET 0x0014 /* Consolidated Time Register 0 */ +#define LPC43_RTC_CTIME1_OFFSET 0x0018 /* Consolidated Time Register 1 */ +#define LPC43_RTC_CTIME2_OFFSET 0x001c /* Consolidated Time Register 2 */ + +/* Time counter registers */ + +#define LPC43_RTC_SEC_OFFSET 0x0020 /* Seconds Counter */ +#define LPC43_RTC_MIN_OFFSET 0x0024 /* Minutes Register */ +#define LPC43_RTC_HOUR_OFFSET 0x0028 /* Hours Register */ +#define LPC43_RTC_DOM_OFFSET 0x002c /* Day of Month Register */ +#define LPC43_RTC_DOW_OFFSET 0x0030 /* Day of Week Register */ +#define LPC43_RTC_DOY_OFFSET 0x0034 /* Day of Year Register */ +#define LPC43_RTC_MONTH_OFFSET 0x0038 /* Months Register */ +#define LPC43_RTC_YEAR_OFFSET 0x003c /* Years Register */ +#define LPC43_RTC_CALIB_OFFSET 0x0040 /* Calibration Value Register */ + +/* Alarm register group */ + +#define LPC43_RTC_ASEC_OFFSET 0x0060 /* Alarm value for Seconds */ +#define LPC43_RTC_AMIN_OFFSET 0x0064 /* Alarm value for Minutes */ +#define LPC43_RTC_AHOUR_OFFSET 0x0068 /* Alarm value for Hours */ +#define LPC43_RTC_ADOM_OFFSET 0x006c /* Alarm value for Day of Month */ +#define LPC43_RTC_ADOW_OFFSET 0x0070 /* Alarm value for Day of Week */ +#define LPC43_RTC_ADOY_OFFSET 0x0074 /* Alarm value for Day of Year */ +#define LPC43_RTC_AMON_OFFSET 0x0078 /* Alarm value for Months */ +#define LPC43_RTC_AYEAR_OFFSET 0x007c /* Alarm value for Year */ + +/* General Purpose Registers. + * + * In addition to the RTC registers, 64 general purpose registers are available + * to store data when the main power supply is switched off. The general purpose + * registers reside in the RTC power domain and can be battery powered. + */ + +#define LPC43_REGFILE_OFFSET(n) (0x0000 + ((n) << 2)) +#define LPC43_REGFILE0_OFFSET 0x0000 +#define LPC43_REGFILE1_OFFSET 0x0004 +#define LPC43_REGFILE2_OFFSET 0x0008 +#define LPC43_REGFILE3_OFFSET 0x000c +#define LPC43_REGFILE4_OFFSET 0x0010 +#define LPC43_REGFILE5_OFFSET 0x0014 +#define LPC43_REGFILE6_OFFSET 0x0018 +#define LPC43_REGFILE7_OFFSET 0x001c +#define LPC43_REGFILE8_OFFSET 0x0020 +#define LPC43_REGFILE9_OFFSET 0x0024 +#define LPC43_REGFILE10_OFFSET 0x0028 +#define LPC43_REGFILE11_OFFSET 0x002c +#define LPC43_REGFILE12_OFFSET 0x0030 +#define LPC43_REGFILE13_OFFSET 0x0034 +#define LPC43_REGFILE14_OFFSET 0x0038 +#define LPC43_REGFILE15_OFFSET 0x003c +#define LPC43_REGFILE16_OFFSET 0x0040 +#define LPC43_REGFILE17_OFFSET 0x0044 +#define LPC43_REGFILE18_OFFSET 0x0048 +#define LPC43_REGFILE19_OFFSET 0x004c +#define LPC43_REGFILE20_OFFSET 0x0050 +#define LPC43_REGFILE21_OFFSET 0x0054 +#define LPC43_REGFILE22_OFFSET 0x0058 +#define LPC43_REGFILE23_OFFSET 0x005c +#define LPC43_REGFILE24_OFFSET 0x0060 +#define LPC43_REGFILE25_OFFSET 0x0064 +#define LPC43_REGFILE26_OFFSET 0x0068 +#define LPC43_REGFILE27_OFFSET 0x006c +#define LPC43_REGFILE28_OFFSET 0x0070 +#define LPC43_REGFILE29_OFFSET 0x0074 +#define LPC43_REGFILE30_OFFSET 0x0078 +#define LPC43_REGFILE31_OFFSET 0x007c +#define LPC43_REGFILE32_OFFSET 0x0080 +#define LPC43_REGFILE33_OFFSET 0x0084 +#define LPC43_REGFILE34_OFFSET 0x0088 +#define LPC43_REGFILE35_OFFSET 0x008c +#define LPC43_REGFILE36_OFFSET 0x0090 +#define LPC43_REGFILE37_OFFSET 0x0094 +#define LPC43_REGFILE38_OFFSET 0x0098 +#define LPC43_REGFILE39_OFFSET 0x009c +#define LPC43_REGFILE40_OFFSET 0x00a0 +#define LPC43_REGFILE41_OFFSET 0x00a4 +#define LPC43_REGFILE42_OFFSET 0x00a8 +#define LPC43_REGFILE43_OFFSET 0x00ac +#define LPC43_REGFILE44_OFFSET 0x00b0 +#define LPC43_REGFILE45_OFFSET 0x00b4 +#define LPC43_REGFILE46_OFFSET 0x00b8 +#define LPC43_REGFILE47_OFFSET 0x00bc +#define LPC43_REGFILE48_OFFSET 0x00c0 +#define LPC43_REGFILE49_OFFSET 0x00c4 +#define LPC43_REGFILE50_OFFSET 0x00c8 +#define LPC43_REGFILE51_OFFSET 0x00cc +#define LPC43_REGFILE52_OFFSET 0x00d0 +#define LPC43_REGFILE53_OFFSET 0x00d4 +#define LPC43_REGFILE54_OFFSET 0x00d8 +#define LPC43_REGFILE55_OFFSET 0x00dc +#define LPC43_REGFILE56_OFFSET 0x00e0 +#define LPC43_REGFILE57_OFFSET 0x00e4 +#define LPC43_REGFILE58_OFFSET 0x00e8 +#define LPC43_REGFILE59_OFFSET 0x00ec +#define LPC43_REGFILE60_OFFSET 0x00f0 +#define LPC43_REGFILE61_OFFSET 0x00f4 +#define LPC43_REGFILE62_OFFSET 0x00f8 +#define LPC43_REGFILE63_OFFSET 0x00fc + +/* Register addresses ***************************************************************/ +/* Miscellaneous registers */ + +#define LPC43_RTC_ILR (LPC43_RTC_BASE+LPC43_RTC_ILR_OFFSET) +#define LPC43_RTC_CCR (LPC43_RTC_BASE+LPC43_RTC_CCR_OFFSET) +#define LPC43_RTC_CIIR (LPC43_RTC_BASE+LPC43_RTC_CIIR_OFFSET) +#define LPC43_RTC_AMR (LPC43_RTC_BASE+LPC43_RTC_AMR_OFFSET) + +/* Consolidated time registers */ + +#define LPC43_RTC_CTIME0 (LPC43_RTC_BASE+LPC43_RTC_CTIME0_OFFSET) +#define LPC43_RTC_CTIME1 (LPC43_RTC_BASE+LPC43_RTC_CTIME1_OFFSET) +#define LPC43_RTC_CTIME2 (LPC43_RTC_BASE+LPC43_RTC_CTIME2_OFFSET) + +/* Time counter registers */ + +#define LPC43_RTC_SEC (LPC43_RTC_BASE+LPC43_RTC_SEC_OFFSET) +#define LPC43_RTC_MIN (LPC43_RTC_BASE+LPC43_RTC_MIN_OFFSET) +#define LPC43_RTC_HOUR (LPC43_RTC_BASE+LPC43_RTC_HOUR_OFFSET) +#define LPC43_RTC_DOM (LPC43_RTC_BASE+LPC43_RTC_DOM_OFFSET) +#define LPC43_RTC_DOW (LPC43_RTC_BASE+LPC43_RTC_DOW_OFFSET) +#define LPC43_RTC_DOY (LPC43_RTC_BASE+LPC43_RTC_DOY_OFFSET) +#define LPC43_RTC_MONTH (LPC43_RTC_BASE+LPC43_RTC_MONTH_OFFSET) +#define LPC43_RTC_YEAR (LPC43_RTC_BASE+LPC43_RTC_YEAR_OFFSET) +#define LPC43_RTC_CALIB (LPC43_RTC_BASE+LPC43_RTC_CALIB_OFFSET) + +/* Alarm register group */ + +#define LPC43_RTC_ASEC (LPC43_RTC_BASE+LPC43_RTC_ASEC_OFFSET) +#define LPC43_RTC_AMIN (LPC43_RTC_BASE+LPC43_RTC_AMIN_OFFSET) +#define LPC43_RTC_AHOUR (LPC43_RTC_BASE+LPC43_RTC_AHOUR_OFFSET) +#define LPC43_RTC_ADOM (LPC43_RTC_BASE+LPC43_RTC_ADOM_OFFSET) +#define LPC43_RTC_ADOW (LPC43_RTC_BASE+LPC43_RTC_ADOW_OFFSET) +#define LPC43_RTC_ADOY (LPC43_RTC_BASE+LPC43_RTC_ADOY_OFFSET) +#define LPC43_RTC_AMON (LPC43_RTC_BASE+LPC43_RTC_AMON_OFFSET) +#define LPC43_RTC_AYEAR (LPC43_RTC_BASE+LPC43_RTC_AYEAR_OFFSET) + +/* General Purpose Registers */ + +#define LPC43_REGFILE(n) (LPC43_BACKUP_BASE+LPC43_REGFILE_OFFSET(n)) +#define LPC43_REGFILE0 (LPC43_BACKUP_BASE+LPC43_REGFILE0_OFFSET) +#define LPC43_REGFILE1 (LPC43_BACKUP_BASE+LPC43_REGFILE1_OFFSET) +#define LPC43_REGFILE2 (LPC43_BACKUP_BASE+LPC43_REGFILE2_OFFSET) +#define LPC43_REGFILE3 (LPC43_BACKUP_BASE+LPC43_REGFILE3_OFFSET) +#define LPC43_REGFILE4 (LPC43_BACKUP_BASE+LPC43_REGFILE4_OFFSET) +#define LPC43_REGFILE5 (LPC43_BACKUP_BASE+LPC43_REGFILE5_OFFSET) +#define LPC43_REGFILE6 (LPC43_BACKUP_BASE+LPC43_REGFILE6_OFFSET) +#define LPC43_REGFILE7 (LPC43_BACKUP_BASE+LPC43_REGFILE7_OFFSET) +#define LPC43_REGFILE8 (LPC43_BACKUP_BASE+LPC43_REGFILE8_OFFSET) +#define LPC43_REGFILE9 (LPC43_BACKUP_BASE+LPC43_REGFILE9_OFFSET) +#define LPC43_REGFILE10 (LPC43_BACKUP_BASE+LPC43_REGFILE10_OFFSET) +#define LPC43_REGFILE11 (LPC43_BACKUP_BASE+LPC43_REGFILE11_OFFSET) +#define LPC43_REGFILE12 (LPC43_BACKUP_BASE+LPC43_REGFILE12_OFFSET) +#define LPC43_REGFILE13 (LPC43_BACKUP_BASE+LPC43_REGFILE13_OFFSET) +#define LPC43_REGFILE14 (LPC43_BACKUP_BASE+LPC43_REGFILE14_OFFSET) +#define LPC43_REGFILE15 (LPC43_BACKUP_BASE+LPC43_REGFILE15_OFFSET) +#define LPC43_REGFILE16 (LPC43_BACKUP_BASE+LPC43_REGFILE16_OFFSET) +#define LPC43_REGFILE17 (LPC43_BACKUP_BASE+LPC43_REGFILE17_OFFSET) +#define LPC43_REGFILE18 (LPC43_BACKUP_BASE+LPC43_REGFILE18_OFFSET) +#define LPC43_REGFILE19 (LPC43_BACKUP_BASE+LPC43_REGFILE19_OFFSET) +#define LPC43_REGFILE20 (LPC43_BACKUP_BASE+LPC43_REGFILE20_OFFSET) +#define LPC43_REGFILE21 (LPC43_BACKUP_BASE+LPC43_REGFILE21_OFFSET) +#define LPC43_REGFILE22 (LPC43_BACKUP_BASE+LPC43_REGFILE22_OFFSET) +#define LPC43_REGFILE23 (LPC43_BACKUP_BASE+LPC43_REGFILE23_OFFSET) +#define LPC43_REGFILE24 (LPC43_BACKUP_BASE+LPC43_REGFILE24_OFFSET) +#define LPC43_REGFILE25 (LPC43_BACKUP_BASE+LPC43_REGFILE25_OFFSET) +#define LPC43_REGFILE26 (LPC43_BACKUP_BASE+LPC43_REGFILE26_OFFSET) +#define LPC43_REGFILE27 (LPC43_BACKUP_BASE+LPC43_REGFILE27_OFFSET) +#define LPC43_REGFILE28 (LPC43_BACKUP_BASE+LPC43_REGFILE28_OFFSET) +#define LPC43_REGFILE29 (LPC43_BACKUP_BASE+LPC43_REGFILE29_OFFSET) +#define LPC43_REGFILE30 (LPC43_BACKUP_BASE+LPC43_REGFILE30_OFFSET) +#define LPC43_REGFILE31 (LPC43_BACKUP_BASE+LPC43_REGFILE31_OFFSET) +#define LPC43_REGFILE32 (LPC43_BACKUP_BASE+LPC43_REGFILE32_OFFSET) +#define LPC43_REGFILE33 (LPC43_BACKUP_BASE+LPC43_REGFILE33_OFFSET) +#define LPC43_REGFILE34 (LPC43_BACKUP_BASE+LPC43_REGFILE34_OFFSET) +#define LPC43_REGFILE35 (LPC43_BACKUP_BASE+LPC43_REGFILE35_OFFSET) +#define LPC43_REGFILE36 (LPC43_BACKUP_BASE+LPC43_REGFILE36_OFFSET) +#define LPC43_REGFILE37 (LPC43_BACKUP_BASE+LPC43_REGFILE37_OFFSET) +#define LPC43_REGFILE38 (LPC43_BACKUP_BASE+LPC43_REGFILE38_OFFSET) +#define LPC43_REGFILE39 (LPC43_BACKUP_BASE+LPC43_REGFILE39_OFFSET) +#define LPC43_REGFILE40 (LPC43_BACKUP_BASE+LPC43_REGFILE40_OFFSET) +#define LPC43_REGFILE41 (LPC43_BACKUP_BASE+LPC43_REGFILE41_OFFSET) +#define LPC43_REGFILE42 (LPC43_BACKUP_BASE+LPC43_REGFILE42_OFFSET) +#define LPC43_REGFILE43 (LPC43_BACKUP_BASE+LPC43_REGFILE43_OFFSET) +#define LPC43_REGFILE44 (LPC43_BACKUP_BASE+LPC43_REGFILE44_OFFSET) +#define LPC43_REGFILE45 (LPC43_BACKUP_BASE+LPC43_REGFILE45_OFFSET) +#define LPC43_REGFILE46 (LPC43_BACKUP_BASE+LPC43_REGFILE46_OFFSET) +#define LPC43_REGFILE47 (LPC43_BACKUP_BASE+LPC43_REGFILE47_OFFSET) +#define LPC43_REGFILE48 (LPC43_BACKUP_BASE+LPC43_REGFILE48_OFFSET) +#define LPC43_REGFILE49 (LPC43_BACKUP_BASE+LPC43_REGFILE49_OFFSET) +#define LPC43_REGFILE50 (LPC43_BACKUP_BASE+LPC43_REGFILE50_OFFSET) +#define LPC43_REGFILE51 (LPC43_BACKUP_BASE+LPC43_REGFILE51_OFFSET) +#define LPC43_REGFILE52 (LPC43_BACKUP_BASE+LPC43_REGFILE52_OFFSET) +#define LPC43_REGFILE53 (LPC43_BACKUP_BASE+LPC43_REGFILE53_OFFSET) +#define LPC43_REGFILE54 (LPC43_BACKUP_BASE+LPC43_REGFILE54_OFFSET) +#define LPC43_REGFILE55 (LPC43_BACKUP_BASE+LPC43_REGFILE55_OFFSET) +#define LPC43_REGFILE56 (LPC43_BACKUP_BASE+LPC43_REGFILE56_OFFSET) +#define LPC43_REGFILE57 (LPC43_BACKUP_BASE+LPC43_REGFILE57_OFFSET) +#define LPC43_REGFILE58 (LPC43_BACKUP_BASE+LPC43_REGFILE58_OFFSET) +#define LPC43_REGFILE59 (LPC43_BACKUP_BASE+LPC43_REGFILE59_OFFSET) +#define LPC43_REGFILE60 (LPC43_BACKUP_BASE+LPC43_REGFILE60_OFFSET) +#define LPC43_REGFILE61 (LPC43_BACKUP_BASE+LPC43_REGFILE61_OFFSET) +#define LPC43_REGFILE62 (LPC43_BACKUP_BASE+LPC43_REGFILE62_OFFSET) +#define LPC43_REGFILE63 (LPC43_BACKUP_BASE+LPC43_REGFILE63_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Miscellaneous registers */ +/* Interrupt Location Register */ + +#define RTC_ILR_RTCCIF (1 << 0) /* Bit 0: Counter Increment Interrupt */ +#define RTC_ILR_RTCALF (1 << 1) /* Bit 1: Alarm interrupt */ + /* Bits 2-31: Reserved */ +/* Clock Control Register */ + +#define RTC_CCR_CLKEN (1 << 0) /* Bit 0: Clock Enable */ +#define RTC_CCR_CTCRST (1 << 1) /* Bit 1: CTC Reset */ + /* Bits 2-3: Internal test mode controls */ +#define RTC_CCR_CCALEN (1 << 4) /* Bit 4: Calibration counter enable */ + /* Bits 5-31: Reserved */ +/* Counter Increment Interrupt Register */ + +#define RTC_CIIR_IMSEC (1 << 0) /* Bit 0: Second interrupt */ +#define RTC_CIIR_IMMIN (1 << 1) /* Bit 1: Minute interrupt */ +#define RTC_CIIR_IMHOUR (1 << 2) /* Bit 2: Hour interrupt */ +#define RTC_CIIR_IMDOM (1 << 3) /* Bit 3: Day of Month value interrupt */ +#define RTC_CIIR_IMDOW (1 << 4) /* Bit 4: Day of Week value interrupt */ +#define RTC_CIIR_IMDOY (1 << 5) /* Bit 5: Day of Year interrupt */ +#define RTC_CIIR_IMMON (1 << 6) /* Bit 6: Month interrupt */ +#define RTC_CIIR_IMYEAR (1 << 7) /* Bit 7: Yearinterrupt */ + /* Bits 8-31: Reserved */ +/* Alarm Mask Register */ + +#define RTC_AMR_SEC (1 << 0) /* Bit 0: Second not compared for alarm */ +#define RTC_AMR_MIN (1 << 1) /* Bit 1: Minutes not compared for alarm */ +#define RTC_AMR_HOUR (1 << 2) /* Bit 2: Hour not compared for alarm */ +#define RTC_AMR_DOM (1 << 3) /* Bit 3: Day of Monthnot compared for alarm */ +#define RTC_AMR_DOW (1 << 4) /* Bit 4: Day of Week not compared for alarm */ +#define RTC_AMR_DOY (1 << 5) /* Bit 5: Day of Year not compared for alarm */ +#define RTC_AMR_MON (1 << 6) /* Bit 6: Month not compared for alarm */ +#define RTC_AMR_YEAR (1 << 7) /* Bit 7: Year not compared for alarm */ + /* Bits 8-31: Reserved */ +/* Consolidated time registers */ +/* Consolidated Time Register 0 */ + +#define RTC_CTIME0_SEC_SHIFT (0) /* Bits 0-5: Seconds */ +#define RTC_CTIME0_SEC_MASK (63 << RTC_CTIME0_SEC_SHIFT) + /* Bits 6-7: Reserved */ +#define RTC_CTIME0_MIN_SHIFT (8) /* Bits 8-13: Minutes */ +#define RTC_CTIME0_MIN_MASK (63 << RTC_CTIME0_MIN_SHIFT) + /* Bits 14-15: Reserved */ +#define RTC_CTIME0_HOURS_SHIFT (16) /* Bits 16-20: Hours */ +#define RTC_CTIME0_HOURS_MASK (31 << RTC_CTIME0_HOURS_SHIFT) + /* Bits 21-23: Reserved */ +#define RTC_CTIME0_DOW_SHIFT (24) /* Bits 24-26: Day of Week */ +#define RTC_CTIME0_DOW_MASK (7 << RTC_CTIME0_DOW_SHIFT) + /* Bits 27-31: Reserved */ +/* Consolidated Time Register 1 */ + +#define RTC_CTIME1_DOM_SHIFT (0) /* Bits 0-4: Day of Month */ +#define RTC_CTIME1_DOM_MASK (31 << RTC_CTIME1_DOM_SHIFT) + /* Bits 5-7: Reserved */ +#define RTC_CTIME1_MON_SHIFT (8) /* Bits 8-11: Month */ +#define RTC_CTIME1_MON_MASK (15 << RTC_CTIME1_MON_SHIFT) + /* Bits 12-15: Reserved */ +#define RTC_CTIME1_YEAR_SHIFT (16) /* Bits 16-27: Year */ +#define RTC_CTIME1_YEAR_MASK (0x0fff << RTC_CTIME1_YEAR_SHIFT) + /* Bits 28-31: Reserved */ +/* Consolidated Time Register 2 */ + +#define RTC_CTIME2_DOY_SHIFT (0) /* Bits 0-11: Day of Year */ +#define RTC_CTIME2_DOY_MASK (0x0fff << RTC_CTIME2_DOY_SHIFT) + /* Bits 12-31: Reserved */ +/* Time counter registers */ + +#define RTC_SEC_MASK (0x003f) +#define RTC_MIN_MASK (0x003f) +#define RTC_HOUR_MASK (0x001f) +#define RTC_DOM_MASK (0x001f) +#define RTC_DOW_MASK (0x0007) +#define RTC_DOY_MASK (0x01ff) +#define RTC_MONTH_MASK (0x000f) +#define RTC_YEAR_MASK (0x0fff) + +/* Calibration Value Register */ + +#define RTC_CALIB_CALVAL_SHIFT (0) /* Bits 0-16: calibration counter counts to this value */ +#define RTC_CALIB_CALVAL_MASK (0xffff << RTC_CALIB_CALVAL_SHIFT) +#define RTC_CALIB_CALDIR (1 << 17) /* Bit 17: Calibration direction */ + /* Bits 18-31: Reserved */ +/* Alarm register group */ + +#define RTC_ASEC_MASK (0x003f) +#define RTC_AMIN_MASK (0x003f) +#define RTC_AHOUR_MASK (0x001f) +#define RTC_ADOM_MASK (0x001f) +#define RTC_ADOW_MASK (0x0007) +#define RTC_ADOY_MASK (0x01ff) +#define RTC_AMON_MASK (0x000f) +#define RTC_AYEAR_MASK (0x0fff) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_RTC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_sct.h b/arch/arm/src/lpc43xx/chip/lpc43_sct.h new file mode 100644 index 0000000000000000000000000000000000000000..d93db28349df2698fb4a0adaf839562fc855e5b6 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_sct.h @@ -0,0 +1,1593 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_sct.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCT_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCT_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_SCT_CONFIG_OFFSET 0x0000 /* SCT configuration register */ +#define LPC43_SCT_CTRL_OFFSET 0x0004 /* SCT control register */ +#define LPC43_SCT_CTRLL_OFFSET 0x0004 /* SCT control register low 16-bit */ +#define LPC43_SCT_CTRLH_OFFSET 0x0006 /* SCT control register high 16-bit */ +#define LPC43_SCT_LIMIT_OFFSET 0x0008 /* SCT limit register */ +#define LPC43_SCT_LIMITL_OFFSET 0x0008 /* SCT limit register low 16-bit */ +#define LPC43_SCT_LIMITH_OFFSET 0x000a /* SCT limit register high 16-bit */ +#define LPC43_SCT_HALT_OFFSET 0x000c /* SCT halt condition register */ +#define LPC43_SCT_HALTL_OFFSET 0x000c /* SCT halt condition register low 16-bit */ +#define LPC43_SCT_HALTH_OFFSET 0x000e /* SCT halt condition register high 16-bit */ +#define LPC43_SCT_STOP_OFFSET 0x0010 /* SCT stop condition register */ +#define LPC43_SCT_STOPL_OFFSET 0x0010 /* SCT stop condition register low 16-bit */ +#define LPC43_SCT_STOPH_OFFSET 0x0012 /* SCT stop condition register high 16-bit */ +#define LPC43_SCT_START_OFFSET 0x0014 /* SCT start condition register */ +#define LPC43_SCT_STARTL_OFFSET 0x0014 /* SCT start condition register low 16-bit */ +#define LPC43_SCT_STARTH_OFFSET 0x0016 /* SCT start condition register high 16-bit */ + +#define LPC43_SCT_COUNT_OFFSET 0x0040 /* SCT counter register */ +#define LPC43_SCT_COUNTL_OFFSET 0x0040 /* SCT counter register low 16-bit */ +#define LPC43_SCT_COUNTH_OFFSET 0x0042 /* SCT counter register high 16-bit */ +#define LPC43_SCT_STATE_OFFSET 0x0044 /* SCT state register */ +#define LPC43_SCT_STATEL_OFFSET 0x0044 /* SCT state register low 16-bit */ +#define LPC43_SCT_STATEH_OFFSET 0x0046 /* SCT state register high 16-bit */ +#define LPC43_SCT_INPUT_OFFSET 0x0048 /* SCT input register */ +#define LPC43_SCT_REGM_OFFSET 0x004c /* SCT match/capture registers mode register */ +#define LPC43_SCT_REGML_OFFSET 0x004c /* SCT match/capture registers mode register low 16-bit */ +#define LPC43_SCT_REGMH_OFFSET 0x004e /* SCT match/capture registers mode register high 16-bit */ +#define LPC43_SCT_OUT_OFFSET 0x0050 /* SCT output register */ +#define LPC43_SCT_OUTDIRC_OFFSET 0x0054 /* SCT output counter direction control register */ +#define LPC43_SCT_RES_OFFSET 0x0058 /* SCT conflict resolution register */ +#define LPC43_SCT_DMAREQ0_OFFSET 0x005c /* SCT DMA request 0 register */ +#define LPC43_SCT_DMAREQ1_OFFSET 0x0060 /* SCT DMA request 1 register */ + +#define LPC43_SCT_EVEN_OFFSET 0x00f0 /* SCT event enable register */ +#define LPC43_SCT_EVFLAG_OFFSET 0x00f4 /* SCT event flag register */ +#define LPC43_SCT_CONEN_OFFSET 0x00f8 /* SCT conflict enable register */ +#define LPC43_SCT_CONFLAG_OFFSET 0x00fC /* SCT conflict flag register */ + +#define LPC43_SCT_MATCH_OFFSET(n) (0x0100 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0_OFFSET 0x0100 /* SCT match value register of match channel 0 */ +#define LPC43_SCT_MATCH1_OFFSET 0x0104 /* SCT match value register of match channel 1 */ +#define LPC43_SCT_MATCH2_OFFSET 0x0108 /* SCT match value register of match channel 2 */ +#define LPC43_SCT_MATCH3_OFFSET 0x010c /* SCT match value register of match channel 3 */ +#define LPC43_SCT_MATCH4_OFFSET 0x0110 /* SCT match value register of match channel 4 */ +#define LPC43_SCT_MATCH5_OFFSET 0x0114 /* SCT match value register of match channel 5 */ +#define LPC43_SCT_MATCH6_OFFSET 0x0118 /* SCT match value register of match channel 6 */ +#define LPC43_SCT_MATCH7_OFFSET 0x011c /* SCT match value register of match channel 7 */ +#define LPC43_SCT_MATCH8_OFFSET 0x0120 /* SCT match value register of match channel 8 */ +#define LPC43_SCT_MATCH9_OFFSET 0x0124 /* SCT match value register of match channel 9 */ +#define LPC43_SCT_MATCH10_OFFSET 0x0128 /* SCT match value register of match channel 10 */ +#define LPC43_SCT_MATCH11_OFFSET 0x012c /* SCT match value register of match channel 11 */ +#define LPC43_SCT_MATCH12_OFFSET 0x0130 /* SCT match value register of match channel 12 */ +#define LPC43_SCT_MATCH13_OFFSET 0x0134 /* SCT match value register of match channel 13 */ +#define LPC43_SCT_MATCH14_OFFSET 0x0138 /* SCT match value register of match channel 14 */ +#define LPC43_SCT_MATCH15_OFFSET 0x013c /* SCT match value register of match channel 15 */ + +#define LPC43_SCT_MATCHL_OFFSET(n) (0x0100 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0L_OFFSET 0x0100 /* SCT match value register of match channel 0; low 16-bit */ +#define LPC43_SCT_MATCH1L_OFFSET 0x0104 /* SCT match value register of match channel 1; low 16-bit */ +#define LPC43_SCT_MATCH2L_OFFSET 0x0108 /* SCT match value register of match channel 2; low 16-bit */ +#define LPC43_SCT_MATCH3L_OFFSET 0x010c /* SCT match value register of match channel 3; low 16-bit */ +#define LPC43_SCT_MATCH4L_OFFSET 0x0110 /* SCT match value register of match channel 4; low 16-bit */ +#define LPC43_SCT_MATCH5L_OFFSET 0x0114 /* SCT match value register of match channel 5; low 16-bit */ +#define LPC43_SCT_MATCH6L_OFFSET 0x0118 /* SCT match value register of match channel 6; low 16-bit */ +#define LPC43_SCT_MATCH7L_OFFSET 0x011c /* SCT match value register of match channel 7; low 16-bit */ +#define LPC43_SCT_MATCH8L_OFFSET 0x0120 /* SCT match value register of match channel 8; low 16-bit */ +#define LPC43_SCT_MATCH9L_OFFSET 0x0124 /* SCT match value register of match channel 9; low 16-bit */ +#define LPC43_SCT_MATCH10L_OFFSET 0x0128 /* SCT match value register of match channel 10; low 16-bit */ +#define LPC43_SCT_MATCH11L_OFFSET 0x012c /* SCT match value register of match channel 11; low 16-bit */ +#define LPC43_SCT_MATCH12L_OFFSET 0x0130 /* SCT match value register of match channel 12; low 16-bit */ +#define LPC43_SCT_MATCH13L_OFFSET 0x0134 /* SCT match value register of match channel 13; low 16-bit */ +#define LPC43_SCT_MATCH14L_OFFSET 0x0138 /* SCT match value register of match channel 14; low 16-bit */ +#define LPC43_SCT_MATCH15L_OFFSET 0x013c /* SCT match value register of match channel 15; low 16-bit */ + +#define LPC43_SCT_MATCHH_OFFSET(n) (0x0102 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0H_OFFSET 0x0102 /* SCT match value register of match channel 0; high 16-bit */ +#define LPC43_SCT_MATCH1H_OFFSET 0x0106 /* SCT match value register of match channel 1; high 16-bit */ +#define LPC43_SCT_MATCH2H_OFFSET 0x010a /* SCT match value register of match channel 2; high 16-bit */ +#define LPC43_SCT_MATCH3H_OFFSET 0x010e /* SCT match value register of match channel 3; high 16-bit */ +#define LPC43_SCT_MATCH4H_OFFSET 0x0112 /* SCT match value register of match channel 4; high 16-bit */ +#define LPC43_SCT_MATCH5H_OFFSET 0x0116 /* SCT match value register of match channel 5; high 16-bit */ +#define LPC43_SCT_MATCH6H_OFFSET 0x011a /* SCT match value register of match channel 6; high 16-bit */ +#define LPC43_SCT_MATCH7H_OFFSET 0x011e /* SCT match value register of match channel 7; high 16-bit */ +#define LPC43_SCT_MATCH8H_OFFSET 0x0122 /* SCT match value register of match channel 8; high 16-bit */ +#define LPC43_SCT_MATCH9H_OFFSET 0x0126 /* SCT match value register of match channel 9; high 16-bit */ +#define LPC43_SCT_MATCH10H_OFFSET 0x012a /* SCT match value register of match channel 10; high 16-bit */ +#define LPC43_SCT_MATCH11H_OFFSET 0x012e /* SCT match value register of match channel 11; high 16-bit */ +#define LPC43_SCT_MATCH12H_OFFSET 0x0132 /* SCT match value register of match channel 12; high 16-bit */ +#define LPC43_SCT_MATCH13H_OFFSET 0x0136 /* SCT match value register of match channel 13; high 16-bit */ +#define LPC43_SCT_MATCH14H_OFFSET 0x013a /* SCT match value register of match channel 14; high 16-bit */ +#define LPC43_SCT_MATCH15H_OFFSET 0x013e /* SCT match value register of match channel 15; high 16-bit */ + +#define LPC43_SCT_CAP_OFFSET(n) (0x0100 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0_OFFSET 0x0100 /* SCT capture value register Ch0 */ +#define LPC43_SCT_CAP1_OFFSET 0x0104 /* SCT capture value register Ch1 */ +#define LPC43_SCT_CAP2_OFFSET 0x0108 /* SCT capture value register Ch2 */ +#define LPC43_SCT_CAP3_OFFSET 0x010c /* SCT capture value register Ch3 */ +#define LPC43_SCT_CAP4_OFFSET 0x0110 /* SCT capture value register Ch4 */ +#define LPC43_SCT_CAP5_OFFSET 0x0114 /* SCT capture value register Ch5 */ +#define LPC43_SCT_CAP6_OFFSET 0x0118 /* SCT capture value register Ch6 */ +#define LPC43_SCT_CAP7_OFFSET 0x011c /* SCT capture value register Ch7 */ +#define LPC43_SCT_CAP8_OFFSET 0x0120 /* SCT capture value register Ch8 */ +#define LPC43_SCT_CAP9_OFFSET 0x0124 /* SCT capture value register Ch9 */ +#define LPC43_SCT_CAP10_OFFSET 0x0128 /* SCT capture value register Ch10 */ +#define LPC43_SCT_CAP11_OFFSET 0x012c /* SCT capture value register Ch11 */ +#define LPC43_SCT_CAP12_OFFSET 0x0130 /* SCT capture value register Ch12 */ +#define LPC43_SCT_CAP13_OFFSET 0x0134 /* SCT capture value register Ch13 */ +#define LPC43_SCT_CAP14_OFFSET 0x0138 /* SCT capture value register Ch14 */ +#define LPC43_SCT_CAP15_OFFSET 0x013c /* SCT capture value register Ch15 */ + +#define LPC43_SCT_CAPL_OFFSET(n) (0x0100 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0L_OFFSET 0x0100 /* SCT capture value register Ch0; low 16-bit */ +#define LPC43_SCT_CAP1L_OFFSET 0x0104 /* SCT capture value register Ch1; low 16-bit */ +#define LPC43_SCT_CAP2L_OFFSET 0x0108 /* SCT capture value register Ch2; low 16-bit */ +#define LPC43_SCT_CAP3L_OFFSET 0x010c /* SCT capture value register Ch3; low 16-bit */ +#define LPC43_SCT_CAP4L_OFFSET 0x0110 /* SCT capture value register Ch4; low 16-bit */ +#define LPC43_SCT_CAP5L_OFFSET 0x0114 /* SCT capture value register Ch5; low 16-bit */ +#define LPC43_SCT_CAP6L_OFFSET 0x0118 /* SCT capture value register Ch6; low 16-bit */ +#define LPC43_SCT_CAP7L_OFFSET 0x011c /* SCT capture value register Ch7; low 16-bit */ +#define LPC43_SCT_CAP8L_OFFSET 0x0120 /* SCT capture value register Ch8; low 16-bit */ +#define LPC43_SCT_CAP9L_OFFSET 0x0124 /* SCT capture value register Ch9; low 16-bit */ +#define LPC43_SCT_CAP10L_OFFSET 0x0128 /* SCT capture value register Ch10; low 16-bit */ +#define LPC43_SCT_CAP11L_OFFSET 0x012c /* SCT capture value register Ch11; low 16-bit */ +#define LPC43_SCT_CAP12L_OFFSET 0x0130 /* SCT capture value register Ch12; low 16-bit */ +#define LPC43_SCT_CAP13L_OFFSET 0x0134 /* SCT capture value register Ch13; low 16-bit */ +#define LPC43_SCT_CAP14L_OFFSET 0x0138 /* SCT capture value register Ch14; low 16-bit */ +#define LPC43_SCT_CAP15L_OFFSET 0x013c /* SCT capture value register Ch15; low 16-bit */ + +#define LPC43_SCT_CAPH_OFFSET(n) (0x0102 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0H_OFFSET 0x0102 /* SCT capture value register Ch0; high 16-bit */ +#define LPC43_SCT_CAP1H_OFFSET 0x0106 /* SCT capture value register Ch1; high 16-bit */ +#define LPC43_SCT_CAP2H_OFFSET 0x010a /* SCT capture value register Ch2; high 16-bit */ +#define LPC43_SCT_CAP3H_OFFSET 0x010e /* SCT capture value register Ch3; high 16-bit */ +#define LPC43_SCT_CAP4H_OFFSET 0x0112 /* SCT capture value register Ch4; high 16-bit */ +#define LPC43_SCT_CAP5H_OFFSET 0x0116 /* SCT capture value register Ch5; high 16-bit */ +#define LPC43_SCT_CAP6H_OFFSET 0x011a /* SCT capture value register Ch6; high 16-bit */ +#define LPC43_SCT_CAP7H_OFFSET 0x011e /* SCT capture value register Ch7; high 16-bit */ +#define LPC43_SCT_CAP8H_OFFSET 0x0122 /* SCT capture value register Ch8; high 16-bit */ +#define LPC43_SCT_CAP9H_OFFSET 0x0126 /* SCT capture value register Ch9; high 16-bit */ +#define LPC43_SCT_CAP10H_OFFSET 0x012a /* SCT capture value register Ch10; high 16-bit */ +#define LPC43_SCT_CAP11H_OFFSET 0x012e /* SCT capture value register Ch11; high 16-bit */ +#define LPC43_SCT_CAP12H_OFFSET 0x0132 /* SCT capture value register Ch12; high 16-bit */ +#define LPC43_SCT_CAP13H_OFFSET 0x0136 /* SCT capture value register Ch13; high 16-bit */ +#define LPC43_SCT_CAP14H_OFFSET 0x013a /* SCT capture value register Ch14; high 16-bit */ +#define LPC43_SCT_CAP15H_OFFSET 0x013e /* SCT capture value register Ch15; high 16-bit */ + +#define LPC43_SCT_MATCHA_OFFSET(n) (0x0180 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0A_OFFSET 0x0180 /* SCT match alias register of match channel 0 */ +#define LPC43_SCT_MATCH1A_OFFSET 0x0184 /* SCT match alias register of match channel 1 */ +#define LPC43_SCT_MATCH2A_OFFSET 0x0188 /* SCT match alias register of match channel 2 */ +#define LPC43_SCT_MATCH3A_OFFSET 0x018c /* SCT match alias register of match channel 3 */ +#define LPC43_SCT_MATCH4A_OFFSET 0x0190 /* SCT match alias register of match channel 4 */ +#define LPC43_SCT_MATCH5A_OFFSET 0x0194 /* SCT match alias register of match channel 5 */ +#define LPC43_SCT_MATCH6A_OFFSET 0x0198 /* SCT match alias register of match channel 6 */ +#define LPC43_SCT_MATCH7A_OFFSET 0x019c /* SCT match alias register of match channel 7 */ +#define LPC43_SCT_MATCH8A_OFFSET 0x01a0 /* SCT match alias register of match channel 8 */ +#define LPC43_SCT_MATCH9A_OFFSET 0x01a4 /* SCT match alias register of match channel 9 */ +#define LPC43_SCT_MATCH10A_OFFSET 0x01a8 /* SCT match alias register of match channel 10 */ +#define LPC43_SCT_MATCH11A_OFFSET 0x01ac /* SCT match alias register of match channel 11 */ +#define LPC43_SCT_MATCH12A_OFFSET 0x01b0 /* SCT match alias register of match channel 12 */ +#define LPC43_SCT_MATCH13A_OFFSET 0x01b4 /* SCT match alias register of match channel 13 */ +#define LPC43_SCT_MATCH14A_OFFSET 0x01b8 /* SCT match alias register of match channel 14 */ +#define LPC43_SCT_MATCH15A_OFFSET 0x01bc /* SCT match alias register of match channel 15 */ + +#define LPC43_SCT_MATCHLA_OFFSET(n) (0x0180 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0LA_OFFSET 0x0180 /* SCT match alias register of match channel 0; low 16-bit */ +#define LPC43_SCT_MATCH1LA_OFFSET 0x0184 /* SCT match alias register of match channel 1; low 16-bit */ +#define LPC43_SCT_MATCH2LA_OFFSET 0x0188 /* SCT match alias register of match channel 2; low 16-bit */ +#define LPC43_SCT_MATCH3LA_OFFSET 0x018c /* SCT match alias register of match channel 3; low 16-bit */ +#define LPC43_SCT_MATCH4LA_OFFSET 0x0190 /* SCT match alias register of match channel 4; low 16-bit */ +#define LPC43_SCT_MATCH5LA_OFFSET 0x0194 /* SCT match alias register of match channel 5; low 16-bit */ +#define LPC43_SCT_MATCH6LA_OFFSET 0x0198 /* SCT match alias register of match channel 6; low 16-bit */ +#define LPC43_SCT_MATCH7LA_OFFSET 0x019c /* SCT match alias register of match channel 7; low 16-bit */ +#define LPC43_SCT_MATCH8LA_OFFSET 0x01a0 /* SCT match alias register of match channel 8; low 16-bit */ +#define LPC43_SCT_MATCH9LA_OFFSET 0x01a4 /* SCT match alias register of match channel 9; low 16-bit */ +#define LPC43_SCT_MATCH10LA_OFFSET 0x01a8 /* SCT match alias register of match channel 10; low 16-bit */ +#define LPC43_SCT_MATCH11LA_OFFSET 0x01ac /* SCT match alias register of match channel 11; low 16-bit */ +#define LPC43_SCT_MATCH12LA_OFFSET 0x01b0 /* SCT match alias register of match channel 12; low 16-bit */ +#define LPC43_SCT_MATCH13LA_OFFSET 0x01b4 /* SCT match alias register of match channel 13; low 16-bit */ +#define LPC43_SCT_MATCH14LA_OFFSET 0x01b8 /* SCT match alias register of match channel 14; low 16-bit */ +#define LPC43_SCT_MATCH15LA_OFFSET 0x01bc /* SCT match alias register of match channel 15; low 16-bit */ + +#define LPC43_SCT_MATCHHA_OFFSET(n) (0x0182 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCH0HA_OFFSET 0x0182 /* SCT match alias register of match channel 0; high 16-bit */ +#define LPC43_SCT_MATCH1HA_OFFSET 0x0186 /* SCT match alias register of match channel 1; high 16-bit */ +#define LPC43_SCT_MATCH2HA_OFFSET 0x018a /* SCT match alias register of match channel 2; high 16-bit */ +#define LPC43_SCT_MATCH3HA_OFFSET 0x018e /* SCT match alias register of match channel 3; high 16-bit */ +#define LPC43_SCT_MATCH4HA_OFFSET 0x0192 /* SCT match alias register of match channel 4; high 16-bit */ +#define LPC43_SCT_MATCH5HA_OFFSET 0x0196 /* SCT match alias register of match channel 5; high 16-bit */ +#define LPC43_SCT_MATCH6HA_OFFSET 0x019a /* SCT match alias register of match channel 6; high 16-bit */ +#define LPC43_SCT_MATCH7HA_OFFSET 0x019e /* SCT match alias register of match channel 7; high 16-bit */ +#define LPC43_SCT_MATCH8HA_OFFSET 0x01a2 /* SCT match alias register of match channel 8; high 16-bit */ +#define LPC43_SCT_MATCH9HA_OFFSET 0x01a6 /* SCT match alias register of match channel 9; high 16-bit */ +#define LPC43_SCT_MATCH10HA_OFFSET 0x01aa /* SCT match alias register of match channel 10; high 16-bit */ +#define LPC43_SCT_MATCH11HA_OFFSET 0x01ae /* SCT match alias register of match channel 11; high 16-bit */ +#define LPC43_SCT_MATCH12HA_OFFSET 0x01b2 /* SCT match alias register of match channel 12; high 16-bit */ +#define LPC43_SCT_MATCH13HA_OFFSET 0x01b6 /* SCT match alias register of match channel 13; high 16-bit */ +#define LPC43_SCT_MATCH14HA_OFFSET 0x01ba /* SCT match alias register of match channel 14; high 16-bit */ +#define LPC43_SCT_MATCH15HA_OFFSET 0x01be /* SCT match alias register of match channel 15; high 16-bit */ + +#define LPC43_SCT_CAPA_OFFSET(n) (0x0180 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0A_OFFSET 0x0180 /* SCT capture alias register Ch0 */ +#define LPC43_SCT_CAP1A_OFFSET 0x0184 /* SCT capture alias register Ch1 */ +#define LPC43_SCT_CAP2A_OFFSET 0x0188 /* SCT capture alias register Ch2 */ +#define LPC43_SCT_CAP3A_OFFSET 0x018c /* SCT capture alias register Ch3 */ +#define LPC43_SCT_CAP4A_OFFSET 0x0190 /* SCT capture alias register Ch4 */ +#define LPC43_SCT_CAP5A_OFFSET 0x0194 /* SCT capture alias register Ch5 */ +#define LPC43_SCT_CAP6A_OFFSET 0x0198 /* SCT capture alias register Ch6 */ +#define LPC43_SCT_CAP7A_OFFSET 0x019c /* SCT capture alias register Ch7 */ +#define LPC43_SCT_CAP8A_OFFSET 0x01a0 /* SCT capture alias register Ch8 */ +#define LPC43_SCT_CAP9A_OFFSET 0x01a4 /* SCT capture alias register Ch9 */ +#define LPC43_SCT_CAP10A_OFFSET 0x01a8 /* SCT capture alias register Ch10 */ +#define LPC43_SCT_CAP11A_OFFSET 0x01ac /* SCT capture alias register Ch11 */ +#define LPC43_SCT_CAP12A_OFFSET 0x01b0 /* SCT capture alias register Ch12 */ +#define LPC43_SCT_CAP13A_OFFSET 0x01b4 /* SCT capture alias register Ch13 */ +#define LPC43_SCT_CAP14A_OFFSET 0x01b8 /* SCT capture alias register Ch14 */ +#define LPC43_SCT_CAP15A_OFFSET 0x01bc /* SCT capture alias register Ch15 */ + +#define LPC43_SCT_CAPLA_OFFSET(n) (0x0180 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0LA_OFFSET 0x0180 /* SCT capture alias register Ch0; low 16-bit */ +#define LPC43_SCT_CAP1LA_OFFSET 0x0184 /* SCT capture alias register Ch1; low 16-bit */ +#define LPC43_SCT_CAP2LA_OFFSET 0x0188 /* SCT capture alias register Ch2; low 16-bit */ +#define LPC43_SCT_CAP3LA_OFFSET 0x018c /* SCT capture alias register Ch3; low 16-bit */ +#define LPC43_SCT_CAP4LA_OFFSET 0x0190 /* SCT capture alias register Ch4; low 16-bit */ +#define LPC43_SCT_CAP5LA_OFFSET 0x0194 /* SCT capture alias register Ch5; low 16-bit */ +#define LPC43_SCT_CAP6LA_OFFSET 0x0198 /* SCT capture alias register Ch6; low 16-bit */ +#define LPC43_SCT_CAP7LA_OFFSET 0x019c /* SCT capture alias register Ch7; low 16-bit */ +#define LPC43_SCT_CAP8LA_OFFSET 0x01a0 /* SCT capture alias register Ch8; low 16-bit */ +#define LPC43_SCT_CAP9LA_OFFSET 0x01a4 /* SCT capture alias register Ch9; low 16-bit */ +#define LPC43_SCT_CAP10LA_OFFSET 0x01a8 /* SCT capture alias register Ch10; low 16-bit */ +#define LPC43_SCT_CAP11LA_OFFSET 0x01ac /* SCT capture alias register Ch11; low 16-bit */ +#define LPC43_SCT_CAP12LA_OFFSET 0x01b0 /* SCT capture alias register Ch12; low 16-bit */ +#define LPC43_SCT_CAP13LA_OFFSET 0x01b4 /* SCT capture alias register Ch13; low 16-bit */ +#define LPC43_SCT_CAP14LA_OFFSET 0x01b8 /* SCT capture alias register Ch14; low 16-bit */ +#define LPC43_SCT_CAP15LA_OFFSET 0x01bc /* SCT capture alias register Ch15; low 16-bit */ + +#define LPC43_SCT_CAPHA_OFFSET(n) (0x0182 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAP0HA_OFFSET 0x0182 /* SCT capture alias register Ch0; high 16-bit */ +#define LPC43_SCT_CAP1HA_OFFSET 0x0186 /* SCT capture alias register Ch1; high 16-bit */ +#define LPC43_SCT_CAP2HA_OFFSET 0x018a /* SCT capture alias register Ch2; high 16-bit */ +#define LPC43_SCT_CAP3HA_OFFSET 0x018e /* SCT capture alias register Ch3; high 16-bit */ +#define LPC43_SCT_CAP4HA_OFFSET 0x0192 /* SCT capture alias register Ch4; high 16-bit */ +#define LPC43_SCT_CAP5HA_OFFSET 0x0196 /* SCT capture alias register Ch5; high 16-bit */ +#define LPC43_SCT_CAP6HA_OFFSET 0x019a /* SCT capture alias register Ch6; high 16-bit */ +#define LPC43_SCT_CAP7HA_OFFSET 0x019e /* SCT capture alias register Ch7; high 16-bit */ +#define LPC43_SCT_CAP8HA_OFFSET 0x01a2 /* SCT capture alias register Ch8; high 16-bit */ +#define LPC43_SCT_CAP9HA_OFFSET 0x01a6 /* SCT capture alias register Ch9; high 16-bit */ +#define LPC43_SCT_CAP10HA_OFFSET 0x01aa /* SCT capture alias register Ch10; high 16-bit */ +#define LPC43_SCT_CAP11HA_OFFSET 0x01ae /* SCT capture alias register Ch11; high 16-bit */ +#define LPC43_SCT_CAP12HA_OFFSET 0x01b2 /* SCT capture alias register Ch12; high 16-bit */ +#define LPC43_SCT_CAP13HA_OFFSET 0x01b6 /* SCT capture alias register Ch13; high 16-bit */ +#define LPC43_SCT_CAP14HA_OFFSET 0x01ba /* SCT capture alias register Ch14; high 16-bit */ +#define LPC43_SCT_CAP15HA_OFFSET 0x01be /* SCT capture alias register Ch15; high 16-bit */ + +#define LPC43_SCT_MATCHR_OFFSET(n) (0x0200 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0_OFFSET 0x0200 /* SCT match reload register of match channel 0 */ +#define LPC43_SCT_MATCHR1_OFFSET 0x0204 /* SCT match reload register of match channel 1 */ +#define LPC43_SCT_MATCHR2_OFFSET 0x0208 /* SCT match reload register of match channel 2 */ +#define LPC43_SCT_MATCHR3_OFFSET 0x020c /* SCT match reload register of match channel 3 */ +#define LPC43_SCT_MATCHR4_OFFSET 0x0210 /* SCT match reload register of match channel 4 */ +#define LPC43_SCT_MATCHR5_OFFSET 0x0214 /* SCT match reload register of match channel 5 */ +#define LPC43_SCT_MATCHR6_OFFSET 0x0218 /* SCT match reload register of match channel 6 */ +#define LPC43_SCT_MATCHR7_OFFSET 0x021c /* SCT match reload register of match channel 7 */ +#define LPC43_SCT_MATCHR8_OFFSET 0x0220 /* SCT match reload register of match channel 8 */ +#define LPC43_SCT_MATCHR9_OFFSET 0x0224 /* SCT match reload register of match channel 9 */ +#define LPC43_SCT_MATCHR10_OFFSET 0x0228 /* SCT match reload register of match channel 10 */ +#define LPC43_SCT_MATCHR11_OFFSET 0x022c /* SCT match reload register of match channel 11 */ +#define LPC43_SCT_MATCHR12_OFFSET 0x0230 /* SCT match reload register of match channel 12 */ +#define LPC43_SCT_MATCHR13_OFFSET 0x0234 /* SCT match reload register of match channel 13 */ +#define LPC43_SCT_MATCHR14_OFFSET 0x0238 /* SCT match reload register of match channel 14 */ +#define LPC43_SCT_MATCHR15_OFFSET 0x023c /* SCT match reload register of match channel 15 */ + +#define LPC43_SCT_MATCHRL_OFFSET(n) (0x0200 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0L_OFFSET 0x0200 /* SCT match reload register of match channel 0; low 16-bit */ +#define LPC43_SCT_MATCHR1L_OFFSET 0x0204 /* SCT match reload register of match channel 1; low 16-bit */ +#define LPC43_SCT_MATCHR2L_OFFSET 0x0208 /* SCT match reload register of match channel 2; low 16-bit */ +#define LPC43_SCT_MATCHR3L_OFFSET 0x020c /* SCT match reload register of match channel 3; low 16-bit */ +#define LPC43_SCT_MATCHR4L_OFFSET 0x0210 /* SCT match reload register of match channel 4; low 16-bit */ +#define LPC43_SCT_MATCHR5L_OFFSET 0x0214 /* SCT match reload register of match channel 5; low 16-bit */ +#define LPC43_SCT_MATCHR6L_OFFSET 0x0218 /* SCT match reload register of match channel 6; low 16-bit */ +#define LPC43_SCT_MATCHR7L_OFFSET 0x021c /* SCT match reload register of match channel 7; low 16-bit */ +#define LPC43_SCT_MATCHR8L_OFFSET 0x0220 /* SCT match reload register of match channel 8; low 16-bit */ +#define LPC43_SCT_MATCHR9L_OFFSET 0x0224 /* SCT match reload register of match channel 9; low 16-bit */ +#define LPC43_SCT_MATCHR10L_OFFSET 0x0228 /* SCT match reload register of match channel 10; low 16-bit */ +#define LPC43_SCT_MATCHR11L_OFFSET 0x022c /* SCT match reload register of match channel 11; low 16-bit */ +#define LPC43_SCT_MATCHR12L_OFFSET 0x0230 /* SCT match reload register of match channel 12; low 16-bit */ +#define LPC43_SCT_MATCHR13L_OFFSET 0x0234 /* SCT match reload register of match channel 13; low 16-bit */ +#define LPC43_SCT_MATCHR14L_OFFSET 0x0238 /* SCT match reload register of match channel 14; low 16-bit */ +#define LPC43_SCT_MATCHR15L_OFFSET 0x023c /* SCT match reload register of match channel 15; low 16-bit */ + +#define LPC43_SCT_MATCHRH_OFFSET(n) (0x0202 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0H_OFFSET 0x0202 /* SCT match reload register of match channel 0; high 16-bit */ +#define LPC43_SCT_MATCHR1H_OFFSET 0x0206 /* SCT match reload register of match channel 1; high 16-bit */ +#define LPC43_SCT_MATCHR2H_OFFSET 0x020a /* SCT match reload register of match channel 2; high 16-bit */ +#define LPC43_SCT_MATCHR3H_OFFSET 0x020e /* SCT match reload register of match channel 3; high 16-bit */ +#define LPC43_SCT_MATCHR4H_OFFSET 0x0212 /* SCT match reload register of match channel 4; high 16-bit */ +#define LPC43_SCT_MATCHR5H_OFFSET 0x0216 /* SCT match reload register of match channel 5; high 16-bit */ +#define LPC43_SCT_MATCHR6H_OFFSET 0x021a /* SCT match reload register of match channel 6; high 16-bit */ +#define LPC43_SCT_MATCHR7H_OFFSET 0x021e /* SCT match reload register of match channel 7; high 16-bit */ +#define LPC43_SCT_MATCHR8H_OFFSET 0x0222 /* SCT match reload register of match channel 8; high 16-bit */ +#define LPC43_SCT_MATCHR9H_OFFSET 0x0226 /* SCT match reload register of match channel 9; high 16-bit */ +#define LPC43_SCT_MATCHR10H_OFFSET 0x022a /* SCT match reload register of match channel 10; high 16-bit */ +#define LPC43_SCT_MATCHR11H_OFFSET 0x022e /* SCT match reload register of match channel 11; high 16-bit */ +#define LPC43_SCT_MATCHR12H_OFFSET 0x0232 /* SCT match reload register of match channel 12; high 16-bit */ +#define LPC43_SCT_MATCHR13H_OFFSET 0x0236 /* SCT match reload register of match channel 13; high 16-bit */ +#define LPC43_SCT_MATCHR14H_OFFSET 0x023a /* SCT match reload register of match channel 14; high 16-bit */ +#define LPC43_SCT_MATCHR15H_OFFSET 0x023e /* SCT match reload register of match channel 15; high 16-bit */ + +#define LPC43_SCT_CAPC_OFFSET(n) (0x0200 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0_OFFSET 0x0200 /* SCT capture control register Ch0 */ +#define LPC43_SCT_CAPC1_OFFSET 0x0204 /* SCT capture control register Ch1 */ +#define LPC43_SCT_CAPC2_OFFSET 0x0208 /* SCT capture control register Ch2 */ +#define LPC43_SCT_CAPC3_OFFSET 0x020c /* SCT capture control register Ch3 */ +#define LPC43_SCT_CAPC4_OFFSET 0x0210 /* SCT capture control register Ch4 */ +#define LPC43_SCT_CAPC5_OFFSET 0x0214 /* SCT capture control register Ch5 */ +#define LPC43_SCT_CAPC6_OFFSET 0x0218 /* SCT capture control register Ch6 */ +#define LPC43_SCT_CAPC7_OFFSET 0x021c /* SCT capture control register Ch7 */ +#define LPC43_SCT_CAPC8_OFFSET 0x0220 /* SCT capture control register Ch8 */ +#define LPC43_SCT_CAPC9_OFFSET 0x0224 /* SCT capture control register Ch9 */ +#define LPC43_SCT_CAPC10_OFFSET 0x0228 /* SCT capture control register Ch10 */ +#define LPC43_SCT_CAPC11_OFFSET 0x022c /* SCT capture control register Ch11 */ +#define LPC43_SCT_CAPC12_OFFSET 0x0230 /* SCT capture control register Ch12 */ +#define LPC43_SCT_CAPC13_OFFSET 0x0234 /* SCT capture control register Ch13 */ +#define LPC43_SCT_CAPC14_OFFSET 0x0238 /* SCT capture control register Ch14 */ +#define LPC43_SCT_CAPC15_OFFSET 0x023c /* SCT capture control register Ch15 */ + +#define LPC43_SCT_CAPCL_OFFSET(n) (0x0200 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0L_OFFSET 0x0200 /* SCT capture control register Ch0; low 16-bit */ +#define LPC43_SCT_CAPC1L_OFFSET 0x0204 /* SCT capture control register Ch1; low 16-bit */ +#define LPC43_SCT_CAPC2L_OFFSET 0x0208 /* SCT capture control register Ch2; low 16-bit */ +#define LPC43_SCT_CAPC3L_OFFSET 0x020c /* SCT capture control register Ch3; low 16-bit */ +#define LPC43_SCT_CAPC4L_OFFSET 0x0210 /* SCT capture control register Ch4; low 16-bit */ +#define LPC43_SCT_CAPC5L_OFFSET 0x0214 /* SCT capture control register Ch5; low 16-bit */ +#define LPC43_SCT_CAPC6L_OFFSET 0x0218 /* SCT capture control register Ch6; low 16-bit */ +#define LPC43_SCT_CAPC7L_OFFSET 0x021c /* SCT capture control register Ch7; low 16-bit */ +#define LPC43_SCT_CAPC8L_OFFSET 0x0220 /* SCT capture control register Ch8; low 16-bit */ +#define LPC43_SCT_CAPC9L_OFFSET 0x0224 /* SCT capture control register Ch9; low 16-bit */ +#define LPC43_SCT_CAPC10L_OFFSET 0x0228 /* SCT capture control register Ch10; low 16-bit */ +#define LPC43_SCT_CAPC11L_OFFSET 0x022c /* SCT capture control register Ch11; low 16-bit */ +#define LPC43_SCT_CAPC12L_OFFSET 0x0230 /* SCT capture control register Ch12; low 16-bit */ +#define LPC43_SCT_CAPC13L_OFFSET 0x0234 /* SCT capture control register Ch13; low 16-bit */ +#define LPC43_SCT_CAPC14L_OFFSET 0x0238 /* SCT capture control register Ch14; low 16-bit */ +#define LPC43_SCT_CAPC15L_OFFSET 0x023c /* SCT capture control register Ch15; low 16-bit */ + +#define LPC43_SCT_CAPCH_OFFSET(n) (0x0202 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0H_OFFSET 0x0202 /* SCT capture control register Ch0; high 16-bit */ +#define LPC43_SCT_CAPC1H_OFFSET 0x0206 /* SCT capture control register Ch1; high 16-bit */ +#define LPC43_SCT_CAPC2H_OFFSET 0x020a /* SCT capture control register Ch2; high 16-bit */ +#define LPC43_SCT_CAPC3H_OFFSET 0x020e /* SCT capture control register Ch3; high 16-bit */ +#define LPC43_SCT_CAPC4H_OFFSET 0x0212 /* SCT capture control register Ch4; high 16-bit */ +#define LPC43_SCT_CAPC5H_OFFSET 0x0216 /* SCT capture control register Ch5; high 16-bit */ +#define LPC43_SCT_CAPC6H_OFFSET 0x021a /* SCT capture control register Ch6; high 16-bit */ +#define LPC43_SCT_CAPC7H_OFFSET 0x021e /* SCT capture control register Ch7; high 16-bit */ +#define LPC43_SCT_CAPC8H_OFFSET 0x0222 /* SCT capture control register Ch8; high 16-bit */ +#define LPC43_SCT_CAPC9H_OFFSET 0x0226 /* SCT capture control register Ch9; high 16-bit */ +#define LPC43_SCT_CAPC10H_OFFSET 0x022a /* SCT capture control register Ch10; high 16-bit */ +#define LPC43_SCT_CAPC11H_OFFSET 0x022e /* SCT capture control register Ch11; high 16-bit */ +#define LPC43_SCT_CAPC12H_OFFSET 0x0232 /* SCT capture control register Ch12; high 16-bit */ +#define LPC43_SCT_CAPC13H_OFFSET 0x0236 /* SCT capture control register Ch13; high 16-bit */ +#define LPC43_SCT_CAPC14H_OFFSET 0x023a /* SCT capture control register Ch14; high 16-bit */ +#define LPC43_SCT_CAPC15H_OFFSET 0x023e /* SCT capture control register Ch15; high 16-bit */ + +#define LPC43_SCT_MATCHRA_OFFSET(n) (0x0280 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0A_OFFSET 0x0280 /* SCT match reload alias register of match channel 0 */ +#define LPC43_SCT_MATCHR1A_OFFSET 0x0284 /* SCT match reload alias register of match channel 1 */ +#define LPC43_SCT_MATCHR2A_OFFSET 0x0288 /* SCT match reload alias register of match channel 2 */ +#define LPC43_SCT_MATCHR3A_OFFSET 0x028c /* SCT match reload alias register of match channel 3 */ +#define LPC43_SCT_MATCHR4A_OFFSET 0x0290 /* SCT match reload alias register of match channel 4 */ +#define LPC43_SCT_MATCHR5A_OFFSET 0x0294 /* SCT match reload alias register of match channel 5 */ +#define LPC43_SCT_MATCHR6A_OFFSET 0x0298 /* SCT match reload alias register of match channel 6 */ +#define LPC43_SCT_MATCHR7A_OFFSET 0x029c /* SCT match reload alias register of match channel 7 */ +#define LPC43_SCT_MATCHR8A_OFFSET 0x02a0 /* SCT match reload alias register of match channel 8 */ +#define LPC43_SCT_MATCHR9A_OFFSET 0x02a4 /* SCT match reload alias register of match channel 9 */ +#define LPC43_SCT_MATCHR10A_OFFSET 0x02a8 /* SCT match reload alias register of match channel 10 */ +#define LPC43_SCT_MATCHR11A_OFFSET 0x02ac /* SCT match reload alias register of match channel 11 */ +#define LPC43_SCT_MATCHR12A_OFFSET 0x02b0 /* SCT match reload alias register of match channel 12 */ +#define LPC43_SCT_MATCHR13A_OFFSET 0x02b4 /* SCT match reload alias register of match channel 13 */ +#define LPC43_SCT_MATCHR14A_OFFSET 0x02b8 /* SCT match reload alias register of match channel 14 */ +#define LPC43_SCT_MATCHR15A_OFFSET 0x02bc /* SCT match reload alias register of match channel 15 */ + +#define LPC43_SCT_MATCHRLA_OFFSET(n) (0x0280 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0LA_OFFSET 0x0280 /* SCT match reload alias register of match channel 0; low 16-bit */ +#define LPC43_SCT_MATCHR1LA_OFFSET 0x0284 /* SCT match reload alias register of match channel 1; low 16-bit */ +#define LPC43_SCT_MATCHR2LA_OFFSET 0x0288 /* SCT match reload alias register of match channel 2; low 16-bit */ +#define LPC43_SCT_MATCHR3LA_OFFSET 0x028c /* SCT match reload alias register of match channel 3; low 16-bit */ +#define LPC43_SCT_MATCHR4LA_OFFSET 0x0290 /* SCT match reload alias register of match channel 4; low 16-bit */ +#define LPC43_SCT_MATCHR5LA_OFFSET 0x0294 /* SCT match reload alias register of match channel 5; low 16-bit */ +#define LPC43_SCT_MATCHR6LA_OFFSET 0x0298 /* SCT match reload alias register of match channel 6; low 16-bit */ +#define LPC43_SCT_MATCHR7LA_OFFSET 0x029c /* SCT match reload alias register of match channel 7; low 16-bit */ +#define LPC43_SCT_MATCHR8LA_OFFSET 0x02a0 /* SCT match reload alias register of match channel 8; low 16-bit */ +#define LPC43_SCT_MATCHR9LA_OFFSET 0x02a4 /* SCT match reload alias register of match channel 9; low 16-bit */ +#define LPC43_SCT_MATCHR10LA_OFFSET 0x02a8 /* SCT match reload alias register of match channel 10; low 16-bit */ +#define LPC43_SCT_MATCHR11LA_OFFSET 0x02ac /* SCT match reload alias register of match channel 11; low 16-bit */ +#define LPC43_SCT_MATCHR12LA_OFFSET 0x02b0 /* SCT match reload alias register of match channel 12; low 16-bit */ +#define LPC43_SCT_MATCHR13LA_OFFSET 0x02b4 /* SCT match reload alias register of match channel 13; low 16-bit */ +#define LPC43_SCT_MATCHR14LA_OFFSET 0x02b8 /* SCT match reload alias register of match channel 14; low 16-bit */ +#define LPC43_SCT_MATCHR15LA_OFFSET 0x02bc /* SCT match reload alias register of match channel 15; low 16-bit */ + +#define LPC43_SCT_MATCHRHA_OFFSET(n) (0x0282 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_MATCHR0HA_OFFSET 0x0282 /* SCT match reload alias register of match channel 0; high 16-bit */ +#define LPC43_SCT_MATCHR1HA_OFFSET 0x0286 /* SCT match reload alias register of match channel 1; high 16-bit */ +#define LPC43_SCT_MATCHR2HA_OFFSET 0x028a /* SCT match reload alias register of match channel 2; high 16-bit */ +#define LPC43_SCT_MATCHR3HA_OFFSET 0x028e /* SCT match reload alias register of match channel 3; high 16-bit */ +#define LPC43_SCT_MATCHR4HA_OFFSET 0x0292 /* SCT match reload alias register of match channel 4; high 16-bit */ +#define LPC43_SCT_MATCHR5HA_OFFSET 0x0296 /* SCT match reload alias register of match channel 5; high 16-bit */ +#define LPC43_SCT_MATCHR6HA_OFFSET 0x029a /* SCT match reload alias register of match channel 6; high 16-bit */ +#define LPC43_SCT_MATCHR7HA_OFFSET 0x029e /* SCT match reload alias register of match channel 7; high 16-bit */ +#define LPC43_SCT_MATCHR8HA_OFFSET 0x02a2 /* SCT match reload alias register of match channel 8; high 16-bit */ +#define LPC43_SCT_MATCHR9HA_OFFSET 0x02a6 /* SCT match reload alias register of match channel 9; high 16-bit */ +#define LPC43_SCT_MATCHR10HA_OFFSET 0x02aa /* SCT match reload alias register of match channel 10; high 16-bit */ +#define LPC43_SCT_MATCHR11HA_OFFSET 0x02ae /* SCT match reload alias register of match channel 11; high 16-bit */ +#define LPC43_SCT_MATCHR12HA_OFFSET 0x02b2 /* SCT match reload alias register of match channel 12; high 16-bit */ +#define LPC43_SCT_MATCHR13HA_OFFSET 0x02b6 /* SCT match reload alias register of match channel 13; high 16-bit */ +#define LPC43_SCT_MATCHR14HA_OFFSET 0x02ba /* SCT match reload alias register of match channel 14; high 16-bit */ +#define LPC43_SCT_MATCHR15HA_OFFSET 0x02be /* SCT match reload alias register of match channel 15; high 16-bit */ + +#define LPC43_SCT_CAPCA_OFFSET(n) (0x0280 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0A_OFFSET 0x0280 /* SCT capture control alias register Ch0 */ +#define LPC43_SCT_CAPC1A_OFFSET 0x0284 /* SCT capture control alias register Ch1 */ +#define LPC43_SCT_CAPC2A_OFFSET 0x0288 /* SCT capture control alias register Ch2 */ +#define LPC43_SCT_CAPC3A_OFFSET 0x028c /* SCT capture control alias register Ch3 */ +#define LPC43_SCT_CAPC4A_OFFSET 0x0290 /* SCT capture control alias register Ch4 */ +#define LPC43_SCT_CAPC5A_OFFSET 0x0294 /* SCT capture control alias register Ch5 */ +#define LPC43_SCT_CAPC6A_OFFSET 0x0298 /* SCT capture control alias register Ch6 */ +#define LPC43_SCT_CAPC7A_OFFSET 0x029c /* SCT capture control alias register Ch7 */ +#define LPC43_SCT_CAPC8A_OFFSET 0x02a0 /* SCT capture control alias register Ch8 */ +#define LPC43_SCT_CAPC9A_OFFSET 0x02a4 /* SCT capture control alias register Ch9 */ +#define LPC43_SCT_CAPC10A_OFFSET 0x02a8 /* SCT capture control alias register Ch10 */ +#define LPC43_SCT_CAPC11A_OFFSET 0x02ac /* SCT capture control alias register Ch11 */ +#define LPC43_SCT_CAPC12A_OFFSET 0x02b0 /* SCT capture control alias register Ch12 */ +#define LPC43_SCT_CAPC13A_OFFSET 0x02b4 /* SCT capture control alias register Ch13 */ +#define LPC43_SCT_CAPC14A_OFFSET 0x02b8 /* SCT capture control alias register Ch14 */ +#define LPC43_SCT_CAPC15A_OFFSET 0x02bc /* SCT capture control alias register Ch15 */ + +#define LPC43_SCT_CAPCLA_OFFSET(n) (0x0280 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0LA_OFFSET 0x0280 /* SCT capture control alias register Ch0; low 16-bit */ +#define LPC43_SCT_CAPC1LA_OFFSET 0x0284 /* SCT capture control alias register Ch1; low 16-bit */ +#define LPC43_SCT_CAPC2LA_OFFSET 0x0288 /* SCT capture control alias register Ch2; low 16-bit */ +#define LPC43_SCT_CAPC3LA_OFFSET 0x028c /* SCT capture control alias register Ch3; low 16-bit */ +#define LPC43_SCT_CAPC4LA_OFFSET 0x0290 /* SCT capture control alias register Ch4; low 16-bit */ +#define LPC43_SCT_CAPC5LA_OFFSET 0x0294 /* SCT capture control alias register Ch5; low 16-bit */ +#define LPC43_SCT_CAPC6LA_OFFSET 0x0298 /* SCT capture control alias register Ch6; low 16-bit */ +#define LPC43_SCT_CAPC7LA_OFFSET 0x029c /* SCT capture control alias register Ch7; low 16-bit */ +#define LPC43_SCT_CAPC8LA_OFFSET 0x02a0 /* SCT capture control alias register Ch8; low 16-bit */ +#define LPC43_SCT_CAPC9LA_OFFSET 0x02a4 /* SCT capture control alias register Ch9; low 16-bit */ +#define LPC43_SCT_CAPC10LA_OFFSET 0x02a8 /* SCT capture control alias register Ch10; low 16-bit */ +#define LPC43_SCT_CAPC11LA_OFFSET 0x02ac /* SCT capture control alias register Ch11; low 16-bit */ +#define LPC43_SCT_CAPC12LA_OFFSET 0x02b0 /* SCT capture control alias register Ch12; low 16-bit */ +#define LPC43_SCT_CAPC13LA_OFFSET 0x02b4 /* SCT capture control alias register Ch13; low 16-bit */ +#define LPC43_SCT_CAPC14LA_OFFSET 0x02b8 /* SCT capture control alias register Ch14; low 16-bit */ +#define LPC43_SCT_CAPC15LA_OFFSET 0x02bc /* SCT capture control alias register Ch15; low 16-bit */ + +#define LPC43_SCT_CAPCHA_OFFSET(n) (0x0282 + ((n) << 4)) /* n = 0..15 */ +#define LPC43_SCT_CAPC0HA_OFFSET 0x0282 /* SCT capture control alias register Ch0; high 16-bit */ +#define LPC43_SCT_CAPC1HA_OFFSET 0x0286 /* SCT capture control alias register Ch1; high 16-bit */ +#define LPC43_SCT_CAPC2HA_OFFSET 0x028a /* SCT capture control alias register Ch2; high 16-bit */ +#define LPC43_SCT_CAPC3HA_OFFSET 0x028e /* SCT capture control alias register Ch3; high 16-bit */ +#define LPC43_SCT_CAPC4HA_OFFSET 0x0292 /* SCT capture control alias register Ch4; high 16-bit */ +#define LPC43_SCT_CAPC5HA_OFFSET 0x0296 /* SCT capture control alias register Ch5; high 16-bit */ +#define LPC43_SCT_CAPC6HA_OFFSET 0x029a /* SCT capture control alias register Ch6; high 16-bit */ +#define LPC43_SCT_CAPC7HA_OFFSET 0x029e /* SCT capture control alias register Ch7; high 16-bit */ +#define LPC43_SCT_CAPC8HA_OFFSET 0x02a2 /* SCT capture control alias register Ch8; high 16-bit */ +#define LPC43_SCT_CAPC9HA_OFFSET 0x02a6 /* SCT capture control alias register Ch9; high 16-bit */ +#define LPC43_SCT_CAPC10HA_OFFSET 0x02aa /* SCT capture control alias register Ch10; high 16-bit */ +#define LPC43_SCT_CAPC11HA_OFFSET 0x02ae /* SCT capture control alias register Ch11; high 16-bit */ +#define LPC43_SCT_CAPC12HA_OFFSET 0x02b2 /* SCT capture control alias register Ch12; high 16-bit */ +#define LPC43_SCT_CAPC13HA_OFFSET 0x02b6 /* SCT capture control alias register Ch13; high 16-bit */ +#define LPC43_SCT_CAPC14HA_OFFSET 0x02ba /* SCT capture control alias register Ch14; high 16-bit */ +#define LPC43_SCT_CAPC15HA_OFFSET 0x02be /* SCT capture control alias register Ch15; high 16-bit */ + +#define LPC43_SCT_EVSM_OFFSET(n) (0x0300 + ((n) << 3)) +#define LPC43_SCT_EVC_OFFSET(n) (0x0304 + ((n) << 3)) + +#define LPC43_SCT_EVSM0_OFFSET 0x0300 /* SCT event state register 0 */ +#define LPC43_SCT_EVC0_OFFSET 0x0304 /* SCT event control register 0 */ +#define LPC43_SCT_EVSM1_OFFSET 0x0308 /* SCT event state register 1 */ +#define LPC43_SCT_EVC1_OFFSET 0x030c /* SCT event control register 1 */ +#define LPC43_SCT_EVSM2_OFFSET 0x0310 /* SCT event state register 2 */ +#define LPC43_SCT_EVC2_OFFSET 0x0314 /* SCT event control register 2 */ +#define LPC43_SCT_EVSM3_OFFSET 0x0318 /* SCT event state register 3 */ +#define LPC43_SCT_EVC3_OFFSET 0x031c /* SCT event control register 3 */ +#define LPC43_SCT_EVSM4_OFFSET 0x0320 /* SCT event state register 4 */ +#define LPC43_SCT_EVC4_OFFSET 0x0324 /* SCT event control register 4 */ +#define LPC43_SCT_EVSM5_OFFSET 0x0328 /* SCT event state register 5 */ +#define LPC43_SCT_EVC5_OFFSET 0x032c /* SCT event control register 5 */ +#define LPC43_SCT_EVSM6_OFFSET 0x0330 /* SCT event state register 6 */ +#define LPC43_SCT_EVC6_OFFSET 0x0334 /* SCT event control register 6 */ +#define LPC43_SCT_EVSM7_OFFSET 0x0338 /* SCT event state register 7 */ +#define LPC43_SCT_EVC7_OFFSET 0x033c /* SCT event control register 7 */ +#define LPC43_SCT_EVSM8_OFFSET 0x0340 /* SCT event state register 8 */ +#define LPC43_SCT_EVC8_OFFSET 0x0344 /* SCT event control register 8 */ +#define LPC43_SCT_EVSM9_OFFSET 0x0348 /* SCT event state register 9 */ +#define LPC43_SCT_EVC9_OFFSET 0x034c /* SCT event control register 9 */ +#define LPC43_SCT_EVSM10_OFFSET 0x0350 /* SCT event state register 10 */ +#define LPC43_SCT_EVC10_OFFSET 0x0354 /* SCT event control register 10 */ +#define LPC43_SCT_EVSM11_OFFSET 0x0358 /* SCT event state register 11 */ +#define LPC43_SCT_EVC11_OFFSET 0x035c /* SCT event control register 11 */ +#define LPC43_SCT_EVSM12_OFFSET 0x0360 /* SCT event state register 12 */ +#define LPC43_SCT_EVC12_OFFSET 0x0364 /* SCT event control register 12 */ +#define LPC43_SCT_EVSM13_OFFSET 0x0368 /* SCT event state register 13 */ +#define LPC43_SCT_EVC13_OFFSET 0x036c /* SCT event control register 13 */ +#define LPC43_SCT_EVSM14_OFFSET 0x0370 /* SCT event state register 14 */ +#define LPC43_SCT_EVC14_OFFSET 0x0374 /* SCT event control register 14 */ +#define LPC43_SCT_EVSM15_OFFSET 0x0378 /* SCT event state register 15 */ +#define LPC43_SCT_EVC15_OFFSET 0x037c /* SCT event control register 15 */ + +#define LPC43_SCT_OUTSET_OFFSET(n) (0x0500 + ((n) << 3)) +#define LPC43_SCT_OUTCLR_OFFSET(n) (0x0504 + ((n) << 3)) + +#define LPC43_SCT_OUTSET0_OFFSET 0x0500 /* SCT output 0 set register */ +#define LPC43_SCT_OUTCLR0_OFFSET 0x0504 /* SCT output 0 clear register */ +#define LPC43_SCT_OUTSET1_OFFSET 0x0508 /* SCT output 1 set register */ +#define LPC43_SCT_OUTCLR1_OFFSET 0x050c /* SCT output 1 clear register */ +#define LPC43_SCT_OUTSET2_OFFSET 0x0510 /* SCT output 2 set register */ +#define LPC43_SCT_OUTCLR2_OFFSET 0x0514 /* SCT output 2 clear register */ +#define LPC43_SCT_OUTSET3_OFFSET 0x0518 /* SCT output 3 set register */ +#define LPC43_SCT_OUTCLR3_OFFSET 0x051c /* SCT output 3 clear register */ +#define LPC43_SCT_OUTSET4_OFFSET 0x0520 /* SCT output 4 set register */ +#define LPC43_SCT_OUTCLR4_OFFSET 0x0524 /* SCT output 4 clear register */ +#define LPC43_SCT_OUTSET5_OFFSET 0x0528 /* SCT output 5 set register */ +#define LPC43_SCT_OUTCLR5_OFFSET 0x052c /* SCT output 5 clear register */ +#define LPC43_SCT_OUTSET6_OFFSET 0x0530 /* SCT output 6 set register */ +#define LPC43_SCT_OUTCLR6_OFFSET 0x0534 /* SCT output 6 clear register */ +#define LPC43_SCT_OUTSET7_OFFSET 0x0538 /* SCT output 7 set register */ +#define LPC43_SCT_OUTCLR7_OFFSET 0x053c /* SCT output 7 clear register */ +#define LPC43_SCT_OUTSET8_OFFSET 0x0540 /* SCT output 8 set register */ +#define LPC43_SCT_OUTCLR8_OFFSET 0x0544 /* SCT output 8 clear register */ +#define LPC43_SCT_OUTSET9_OFFSET 0x0548 /* SCT output 9 set register */ +#define LPC43_SCT_OUTCLR9_OFFSET 0x054c /* SCT output 9 clear register */ +#define LPC43_SCT_OUTSET10_OFFSET 0x0550 /* SCT output 10 set register */ +#define LPC43_SCT_OUTCLR10_OFFSET 0x0554 /* SCT output 10 clear register */ +#define LPC43_SCT_OUTSET11_OFFSET 0x0558 /* SCT output 11 set register */ +#define LPC43_SCT_OUTCLR11_OFFSET 0x055c /* SCT output 11 clear register */ +#define LPC43_SCT_OUTSET12_OFFSET 0x0560 /* SCT output 12 set register */ +#define LPC43_SCT_OUTCLR12_OFFSET 0x0564 /* SCT output 12 clear register */ +#define LPC43_SCT_OUTSET13_OFFSET 0x0568 /* SCT output 13 set register */ +#define LPC43_SCT_OUTCLR13_OFFSET 0x056c /* SCT output 13 clear register */ +#define LPC43_SCT_OUTSET14_OFFSET 0x0570 /* SCT output 14 set register */ +#define LPC43_SCT_OUTCLR14_OFFSET 0x0574 /* SCT output 14 clear register */ +#define LPC43_SCT_OUTSET15_OFFSET 0x0578 /* SCT output 15 set register */ +#define LPC43_SCT_OUTCLR15_OFFSET 0x057c /* SCT output 15 clear register */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_SCT_CONFIG (LPC43_SCT_BASE+LPC43_SCT_CONFIG_OFFSET) +#define LPC43_SCT_CTRL (LPC43_SCT_BASE+LPC43_SCT_CTRL_OFFSET) +#define LPC43_SCT_CTRLL (LPC43_SCT_BASE+LPC43_SCT_CTRLL_OFFSET) +#define LPC43_SCT_CTRLH (LPC43_SCT_BASE+LPC43_SCT_CTRLH_OFFSET) +#define LPC43_SCT_LIMIT (LPC43_SCT_BASE+LPC43_SCT_LIMIT_OFFSET) +#define LPC43_SCT_LIMITL (LPC43_SCT_BASE+LPC43_SCT_LIMITL_OFFSET) +#define LPC43_SCT_LIMITH (LPC43_SCT_BASE+LPC43_SCT_LIMITH_OFFSET) +#define LPC43_SCT_HALT (LPC43_SCT_BASE+LPC43_SCT_HALT_OFFSET) +#define LPC43_SCT_HALTL (LPC43_SCT_BASE+LPC43_SCT_HALTL_OFFSET) +#define LPC43_SCT_HALTH (LPC43_SCT_BASE+LPC43_SCT_HALTH_OFFSET) +#define LPC43_SCT_STOP (LPC43_SCT_BASE+LPC43_SCT_STOP_OFFSET) +#define LPC43_SCT_STOPL (LPC43_SCT_BASE+LPC43_SCT_STOPL_OFFSET) +#define LPC43_SCT_STOPH (LPC43_SCT_BASE+LPC43_SCT_STOPH_OFFSET) +#define LPC43_SCT_START (LPC43_SCT_BASE+LPC43_SCT_START_OFFSET) +#define LPC43_SCT_STARTL (LPC43_SCT_BASE+LPC43_SCT_STARTL_OFFSET) +#define LPC43_SCT_STARTH (LPC43_SCT_BASE+LPC43_SCT_STARTH_OFFSET) + +#define LPC43_SCT_COUNT (LPC43_SCT_BASE+LPC43_SCT_COUNT_OFFSET) +#define LPC43_SCT_COUNTL (LPC43_SCT_BASE+LPC43_SCT_COUNTL_OFFSET) +#define LPC43_SCT_COUNTH (LPC43_SCT_BASE+LPC43_SCT_COUNTH_OFFSET) +#define LPC43_SCT_STATE (LPC43_SCT_BASE+LPC43_SCT_STATE_OFFSET) +#define LPC43_SCT_STATEL (LPC43_SCT_BASE+LPC43_SCT_STATEL_OFFSET) +#define LPC43_SCT_STATEH (LPC43_SCT_BASE+LPC43_SCT_STATEH_OFFSET) +#define LPC43_SCT_INPUT (LPC43_SCT_BASE+LPC43_SCT_INPUT_OFFSET) +#define LPC43_SCT_REGM (LPC43_SCT_BASE+LPC43_SCT_REGM_OFFSET) +#define LPC43_SCT_REGML (LPC43_SCT_BASE+LPC43_SCT_REGML_OFFSET) +#define LPC43_SCT_REGMH (LPC43_SCT_BASE+LPC43_SCT_REGMH_OFFSET) +#define LPC43_SCT_OUT (LPC43_SCT_BASE+LPC43_SCT_OUT_OFFSET) +#define LPC43_SCT_OUTDIRC (LPC43_SCT_BASE+LPC43_SCT_OUTDIRC_OFFSET) +#define LPC43_SCT_RES (LPC43_SCT_BASE+LPC43_SCT_RES_OFFSET) +#define LPC43_SCT_DMAREQ0 (LPC43_SCT_BASE+LPC43_SCT_DMAREQ0_OFFSET) +#define LPC43_SCT_DMAREQ1 (LPC43_SCT_BASE+LPC43_SCT_DMAREQ1_OFFSET) + +#define LPC43_SCT_EVEN (LPC43_SCT_BASE+LPC43_SCT_EVEN_OFFSET) +#define LPC43_SCT_EVFLAG (LPC43_SCT_BASE+LPC43_SCT_EVFLAG_OFFSET) +#define LPC43_SCT_CONEN (LPC43_SCT_BASE+LPC43_SCT_CONEN_OFFSET) +#define LPC43_SCT_CONFLAG (LPC43_SCT_BASE+LPC43_SCT_CONFLAG_OFFSET) + +#define LPC43_SCT_MATCH(n) (LPC43_SCT_BASE+LPC43_SCT_MATCH_OFFSET(n)) +#define LPC43_SCT_MATCH0 (LPC43_SCT_BASE+LPC43_SCT_MATCH0_OFFSET) +#define LPC43_SCT_MATCH1 (LPC43_SCT_BASE+LPC43_SCT_MATCH1_OFFSET) +#define LPC43_SCT_MATCH2 (LPC43_SCT_BASE+LPC43_SCT_MATCH2_OFFSET) +#define LPC43_SCT_MATCH3 (LPC43_SCT_BASE+LPC43_SCT_MATCH3_OFFSET) +#define LPC43_SCT_MATCH4 (LPC43_SCT_BASE+LPC43_SCT_MATCH4_OFFSET) +#define LPC43_SCT_MATCH5 (LPC43_SCT_BASE+LPC43_SCT_MATCH5_OFFSET) +#define LPC43_SCT_MATCH6 (LPC43_SCT_BASE+LPC43_SCT_MATCH6_OFFSET) +#define LPC43_SCT_MATCH7 (LPC43_SCT_BASE+LPC43_SCT_MATCH7_OFFSET) +#define LPC43_SCT_MATCH8 (LPC43_SCT_BASE+LPC43_SCT_MATCH8_OFFSET) +#define LPC43_SCT_MATCH9 (LPC43_SCT_BASE+LPC43_SCT_MATCH9_OFFSET) +#define LPC43_SCT_MATCH10 (LPC43_SCT_BASE+LPC43_SCT_MATCH10_OFFSET) +#define LPC43_SCT_MATCH11 (LPC43_SCT_BASE+LPC43_SCT_MATCH11_OFFSET) +#define LPC43_SCT_MATCH12 (LPC43_SCT_BASE+LPC43_SCT_MATCH12_OFFSET) +#define LPC43_SCT_MATCH13 (LPC43_SCT_BASE+LPC43_SCT_MATCH13_OFFSET) +#define LPC43_SCT_MATCH14 (LPC43_SCT_BASE+LPC43_SCT_MATCH14_OFFSET) +#define LPC43_SCT_MATCH15 (LPC43_SCT_BASE+LPC43_SCT_MATCH15_OFFSET) + +#define LPC43_SCT_MATCHL(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHL_OFFSET(n)) +#define LPC43_SCT_MATCHL0 (LPC43_SCT_BASE+LPC43_SCT_MATCHL0_OFFSET) +#define LPC43_SCT_MATCHL1 (LPC43_SCT_BASE+LPC43_SCT_MATCHL1_OFFSET) +#define LPC43_SCT_MATCHL2 (LPC43_SCT_BASE+LPC43_SCT_MATCHL2_OFFSET) +#define LPC43_SCT_MATCHL3 (LPC43_SCT_BASE+LPC43_SCT_MATCHL3_OFFSET) +#define LPC43_SCT_MATCHL4 (LPC43_SCT_BASE+LPC43_SCT_MATCHL4_OFFSET) +#define LPC43_SCT_MATCHL5 (LPC43_SCT_BASE+LPC43_SCT_MATCHL5_OFFSET) +#define LPC43_SCT_MATCHL6 (LPC43_SCT_BASE+LPC43_SCT_MATCHL6_OFFSET) +#define LPC43_SCT_MATCHL7 (LPC43_SCT_BASE+LPC43_SCT_MATCHL7_OFFSET) +#define LPC43_SCT_MATCHL8 (LPC43_SCT_BASE+LPC43_SCT_MATCHL8_OFFSET) +#define LPC43_SCT_MATCHL9 (LPC43_SCT_BASE+LPC43_SCT_MATCHL9_OFFSET) +#define LPC43_SCT_MATCHL10 (LPC43_SCT_BASE+LPC43_SCT_MATCHL10_OFFSET) +#define LPC43_SCT_MATCHL11 (LPC43_SCT_BASE+LPC43_SCT_MATCHL11_OFFSET) +#define LPC43_SCT_MATCHL12 (LPC43_SCT_BASE+LPC43_SCT_MATCHL12_OFFSET) +#define LPC43_SCT_MATCHL13 (LPC43_SCT_BASE+LPC43_SCT_MATCHL13_OFFSET) +#define LPC43_SCT_MATCHL14 (LPC43_SCT_BASE+LPC43_SCT_MATCHL14_OFFSET) +#define LPC43_SCT_MATCHL15 (LPC43_SCT_BASE+LPC43_SCT_MATCHL15_OFFSET) + +#define LPC43_SCT_MATCHH(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHH_OFFSET(n)) +#define LPC43_SCT_MATCHH0 (LPC43_SCT_BASE+LPC43_SCT_MATCHH0_OFFSET) +#define LPC43_SCT_MATCHH1 (LPC43_SCT_BASE+LPC43_SCT_MATCHH1_OFFSET) +#define LPC43_SCT_MATCHH2 (LPC43_SCT_BASE+LPC43_SCT_MATCHH2_OFFSET) +#define LPC43_SCT_MATCHH3 (LPC43_SCT_BASE+LPC43_SCT_MATCHH3_OFFSET) +#define LPC43_SCT_MATCHH4 (LPC43_SCT_BASE+LPC43_SCT_MATCHH4_OFFSET) +#define LPC43_SCT_MATCHH5 (LPC43_SCT_BASE+LPC43_SCT_MATCHH5_OFFSET) +#define LPC43_SCT_MATCHH6 (LPC43_SCT_BASE+LPC43_SCT_MATCHH6_OFFSET) +#define LPC43_SCT_MATCHH7 (LPC43_SCT_BASE+LPC43_SCT_MATCHH7_OFFSET) +#define LPC43_SCT_MATCHH8 (LPC43_SCT_BASE+LPC43_SCT_MATCHH8_OFFSET) +#define LPC43_SCT_MATCHH9 (LPC43_SCT_BASE+LPC43_SCT_MATCHH9_OFFSET) +#define LPC43_SCT_MATCHH10 (LPC43_SCT_BASE+LPC43_SCT_MATCHH10_OFFSET) +#define LPC43_SCT_MATCHH11 (LPC43_SCT_BASE+LPC43_SCT_MATCHH11_OFFSET) +#define LPC43_SCT_MATCHH12 (LPC43_SCT_BASE+LPC43_SCT_MATCHH12_OFFSET) +#define LPC43_SCT_MATCHH13 (LPC43_SCT_BASE+LPC43_SCT_MATCHH13_OFFSET) +#define LPC43_SCT_MATCHH14 (LPC43_SCT_BASE+LPC43_SCT_MATCHH14_OFFSET) +#define LPC43_SCT_MATCHH15 (LPC43_SCT_BASE+LPC43_SCT_MATCHH15_OFFSET) + +#define LPC43_SCT_CAP(n) (LPC43_SCT_BASE+LPC43_SCT_CAP_OFFSET(n)) +#define LPC43_SCT_CAP0 (LPC43_SCT_BASE+LPC43_SCT_CAP0_OFFSET) +#define LPC43_SCT_CAP1 (LPC43_SCT_BASE+LPC43_SCT_CAP1_OFFSET) +#define LPC43_SCT_CAP2 (LPC43_SCT_BASE+LPC43_SCT_CAP2_OFFSET) +#define LPC43_SCT_CAP3 (LPC43_SCT_BASE+LPC43_SCT_CAP3_OFFSET) +#define LPC43_SCT_CAP4 (LPC43_SCT_BASE+LPC43_SCT_CAP4_OFFSET) +#define LPC43_SCT_CAP5 (LPC43_SCT_BASE+LPC43_SCT_CAP5_OFFSET) +#define LPC43_SCT_CAP6 (LPC43_SCT_BASE+LPC43_SCT_CAP6_OFFSET) +#define LPC43_SCT_CAP7 (LPC43_SCT_BASE+LPC43_SCT_CAP7_OFFSET) +#define LPC43_SCT_CAP8 (LPC43_SCT_BASE+LPC43_SCT_CAP8_OFFSET) +#define LPC43_SCT_CAP9 (LPC43_SCT_BASE+LPC43_SCT_CAP9_OFFSET) +#define LPC43_SCT_CAP10 (LPC43_SCT_BASE+LPC43_SCT_CAP10_OFFSET) +#define LPC43_SCT_CAP11 (LPC43_SCT_BASE+LPC43_SCT_CAP11_OFFSET) +#define LPC43_SCT_CAP12 (LPC43_SCT_BASE+LPC43_SCT_CAP12_OFFSET) +#define LPC43_SCT_CAP13 (LPC43_SCT_BASE+LPC43_SCT_CAP13_OFFSET) +#define LPC43_SCT_CAP14 (LPC43_SCT_BASE+LPC43_SCT_CAP14_OFFSET) +#define LPC43_SCT_CAP15 (LPC43_SCT_BASE+LPC43_SCT_CAP15_OFFSET) + +#define LPC43_SCT_CAPL(n) (LPC43_SCT_BASE+LPC43_SCT_CAPL_OFFSET(n)) +#define LPC43_SCT_CAPL0 (LPC43_SCT_BASE+LPC43_SCT_CAPL0_OFFSET) +#define LPC43_SCT_CAPL1 (LPC43_SCT_BASE+LPC43_SCT_CAPL1_OFFSET) +#define LPC43_SCT_CAPL2 (LPC43_SCT_BASE+LPC43_SCT_CAPL2_OFFSET) +#define LPC43_SCT_CAPL3 (LPC43_SCT_BASE+LPC43_SCT_CAPL3_OFFSET) +#define LPC43_SCT_CAPL4 (LPC43_SCT_BASE+LPC43_SCT_CAPL4_OFFSET) +#define LPC43_SCT_CAPL5 (LPC43_SCT_BASE+LPC43_SCT_CAPL5_OFFSET) +#define LPC43_SCT_CAPL6 (LPC43_SCT_BASE+LPC43_SCT_CAPL6_OFFSET) +#define LPC43_SCT_CAPL7 (LPC43_SCT_BASE+LPC43_SCT_CAPL7_OFFSET) +#define LPC43_SCT_CAPL8 (LPC43_SCT_BASE+LPC43_SCT_CAPL8_OFFSET) +#define LPC43_SCT_CAPL9 (LPC43_SCT_BASE+LPC43_SCT_CAPL9_OFFSET) +#define LPC43_SCT_CAPL10 (LPC43_SCT_BASE+LPC43_SCT_CAPL10_OFFSET) +#define LPC43_SCT_CAPL11 (LPC43_SCT_BASE+LPC43_SCT_CAPL11_OFFSET) +#define LPC43_SCT_CAPL12 (LPC43_SCT_BASE+LPC43_SCT_CAPL12_OFFSET) +#define LPC43_SCT_CAPL13 (LPC43_SCT_BASE+LPC43_SCT_CAPL13_OFFSET) +#define LPC43_SCT_CAPL14 (LPC43_SCT_BASE+LPC43_SCT_CAPL14_OFFSET) +#define LPC43_SCT_CAPL15 (LPC43_SCT_BASE+LPC43_SCT_CAPL15_OFFSET) + +#define LPC43_SCT_CAPH(n) (LPC43_SCT_BASE+LPC43_SCT_CAPH_OFFSET(n)) +#define LPC43_SCT_CAPH0 (LPC43_SCT_BASE+LPC43_SCT_CAPH0_OFFSET) +#define LPC43_SCT_CAPH1 (LPC43_SCT_BASE+LPC43_SCT_CAPH1_OFFSET) +#define LPC43_SCT_CAPH2 (LPC43_SCT_BASE+LPC43_SCT_CAPH2_OFFSET) +#define LPC43_SCT_CAPH3 (LPC43_SCT_BASE+LPC43_SCT_CAPH3_OFFSET) +#define LPC43_SCT_CAPH4 (LPC43_SCT_BASE+LPC43_SCT_CAPH4_OFFSET) +#define LPC43_SCT_CAPH5 (LPC43_SCT_BASE+LPC43_SCT_CAPH5_OFFSET) +#define LPC43_SCT_CAPH6 (LPC43_SCT_BASE+LPC43_SCT_CAPH6_OFFSET) +#define LPC43_SCT_CAPH7 (LPC43_SCT_BASE+LPC43_SCT_CAPH7_OFFSET) +#define LPC43_SCT_CAPH8 (LPC43_SCT_BASE+LPC43_SCT_CAPH8_OFFSET) +#define LPC43_SCT_CAPH9 (LPC43_SCT_BASE+LPC43_SCT_CAPH9_OFFSET) +#define LPC43_SCT_CAPH10 (LPC43_SCT_BASE+LPC43_SCT_CAPH10_OFFSET) +#define LPC43_SCT_CAPH11 (LPC43_SCT_BASE+LPC43_SCT_CAPH11_OFFSET) +#define LPC43_SCT_CAPH12 (LPC43_SCT_BASE+LPC43_SCT_CAPH12_OFFSET) +#define LPC43_SCT_CAPH13 (LPC43_SCT_BASE+LPC43_SCT_CAPH13_OFFSET) +#define LPC43_SCT_CAPH14 (LPC43_SCT_BASE+LPC43_SCT_CAPH14_OFFSET) +#define LPC43_SCT_CAPH15 (LPC43_SCT_BASE+LPC43_SCT_CAPH15_OFFSET) + +#define LPC43_SCT_MATCHA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHA_OFFSET(n)) +#define LPC43_SCT_MATCHA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHA0_OFFSET) +#define LPC43_SCT_MATCHA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHA1_OFFSET) +#define LPC43_SCT_MATCHA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHA2_OFFSET) +#define LPC43_SCT_MATCHA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHA3_OFFSET) +#define LPC43_SCT_MATCHA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHA4_OFFSET) +#define LPC43_SCT_MATCHA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHA5_OFFSET) +#define LPC43_SCT_MATCHA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHA6_OFFSET) +#define LPC43_SCT_MATCHA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHA7_OFFSET) +#define LPC43_SCT_MATCHA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHA8_OFFSET) +#define LPC43_SCT_MATCHA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHA9_OFFSET) +#define LPC43_SCT_MATCHA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHA10_OFFSET) +#define LPC43_SCT_MATCHA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHA11_OFFSET) +#define LPC43_SCT_MATCHA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHA12_OFFSET) +#define LPC43_SCT_MATCHA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHA13_OFFSET) +#define LPC43_SCT_MATCHA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHA14_OFFSET) +#define LPC43_SCT_MATCHA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHA15_OFFSET) + +#define LPC43_SCT_MATCHLA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHLA_OFFSET(n)) +#define LPC43_SCT_MATCHLA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA0_OFFSET) +#define LPC43_SCT_MATCHLA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA1_OFFSET) +#define LPC43_SCT_MATCHLA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA2_OFFSET) +#define LPC43_SCT_MATCHLA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA3_OFFSET) +#define LPC43_SCT_MATCHLA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA4_OFFSET) +#define LPC43_SCT_MATCHLA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA5_OFFSET) +#define LPC43_SCT_MATCHLA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA6_OFFSET) +#define LPC43_SCT_MATCHLA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA7_OFFSET) +#define LPC43_SCT_MATCHLA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA8_OFFSET) +#define LPC43_SCT_MATCHLA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA9_OFFSET) +#define LPC43_SCT_MATCHLA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA10_OFFSET) +#define LPC43_SCT_MATCHLA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA11_OFFSET) +#define LPC43_SCT_MATCHLA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA12_OFFSET) +#define LPC43_SCT_MATCHLA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA13_OFFSET) +#define LPC43_SCT_MATCHLA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA14_OFFSET) +#define LPC43_SCT_MATCHLA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHLA15_OFFSET) + +#define LPC43_SCT_MATCHHA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHHA_OFFSET(n)) +#define LPC43_SCT_MATCHHA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA0_OFFSET) +#define LPC43_SCT_MATCHHA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA1_OFFSET) +#define LPC43_SCT_MATCHHA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA2_OFFSET) +#define LPC43_SCT_MATCHHA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA3_OFFSET) +#define LPC43_SCT_MATCHHA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA4_OFFSET) +#define LPC43_SCT_MATCHHA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA5_OFFSET) +#define LPC43_SCT_MATCHHA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA6_OFFSET) +#define LPC43_SCT_MATCHHA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA7_OFFSET) +#define LPC43_SCT_MATCHHA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA8_OFFSET) +#define LPC43_SCT_MATCHHA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA9_OFFSET) +#define LPC43_SCT_MATCHHA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA10_OFFSET) +#define LPC43_SCT_MATCHHA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA11_OFFSET) +#define LPC43_SCT_MATCHHA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA12_OFFSET) +#define LPC43_SCT_MATCHHA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA13_OFFSET) +#define LPC43_SCT_MATCHHA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA14_OFFSET) +#define LPC43_SCT_MATCHHA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHHA15_OFFSET) + +#define LPC43_SCT_CAPA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPA_OFFSET(n)) +#define LPC43_SCT_CAPA0 (LPC43_SCT_BASE+LPC43_SCT_CAPA0_OFFSET) +#define LPC43_SCT_CAPA1 (LPC43_SCT_BASE+LPC43_SCT_CAPA1_OFFSET) +#define LPC43_SCT_CAPA2 (LPC43_SCT_BASE+LPC43_SCT_CAPA2_OFFSET) +#define LPC43_SCT_CAPA3 (LPC43_SCT_BASE+LPC43_SCT_CAPA3_OFFSET) +#define LPC43_SCT_CAPA4 (LPC43_SCT_BASE+LPC43_SCT_CAPA4_OFFSET) +#define LPC43_SCT_CAPA5 (LPC43_SCT_BASE+LPC43_SCT_CAPA5_OFFSET) +#define LPC43_SCT_CAPA6 (LPC43_SCT_BASE+LPC43_SCT_CAPA6_OFFSET) +#define LPC43_SCT_CAPA7 (LPC43_SCT_BASE+LPC43_SCT_CAPA7_OFFSET) +#define LPC43_SCT_CAPA8 (LPC43_SCT_BASE+LPC43_SCT_CAPA8_OFFSET) +#define LPC43_SCT_CAPA9 (LPC43_SCT_BASE+LPC43_SCT_CAPA9_OFFSET) +#define LPC43_SCT_CAPA10 (LPC43_SCT_BASE+LPC43_SCT_CAPA10_OFFSET) +#define LPC43_SCT_CAPA11 (LPC43_SCT_BASE+LPC43_SCT_CAPA11_OFFSET) +#define LPC43_SCT_CAPA12 (LPC43_SCT_BASE+LPC43_SCT_CAPA12_OFFSET) +#define LPC43_SCT_CAPA13 (LPC43_SCT_BASE+LPC43_SCT_CAPA13_OFFSET) +#define LPC43_SCT_CAPA14 (LPC43_SCT_BASE+LPC43_SCT_CAPA14_OFFSET) +#define LPC43_SCT_CAPA15 (LPC43_SCT_BASE+LPC43_SCT_CAPA15_OFFSET) + +#define LPC43_SCT_CAPLA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPLA_OFFSET(n)) +#define LPC43_SCT_CAPLA0 (LPC43_SCT_BASE+LPC43_SCT_CAPLA0_OFFSET) +#define LPC43_SCT_CAPLA1 (LPC43_SCT_BASE+LPC43_SCT_CAPLA1_OFFSET) +#define LPC43_SCT_CAPLA2 (LPC43_SCT_BASE+LPC43_SCT_CAPLA2_OFFSET) +#define LPC43_SCT_CAPLA3 (LPC43_SCT_BASE+LPC43_SCT_CAPLA3_OFFSET) +#define LPC43_SCT_CAPLA4 (LPC43_SCT_BASE+LPC43_SCT_CAPLA4_OFFSET) +#define LPC43_SCT_CAPLA5 (LPC43_SCT_BASE+LPC43_SCT_CAPLA5_OFFSET) +#define LPC43_SCT_CAPLA6 (LPC43_SCT_BASE+LPC43_SCT_CAPLA6_OFFSET) +#define LPC43_SCT_CAPLA7 (LPC43_SCT_BASE+LPC43_SCT_CAPLA7_OFFSET) +#define LPC43_SCT_CAPLA8 (LPC43_SCT_BASE+LPC43_SCT_CAPLA8_OFFSET) +#define LPC43_SCT_CAPLA9 (LPC43_SCT_BASE+LPC43_SCT_CAPLA9_OFFSET) +#define LPC43_SCT_CAPLA10 (LPC43_SCT_BASE+LPC43_SCT_CAPLA10_OFFSET) +#define LPC43_SCT_CAPLA11 (LPC43_SCT_BASE+LPC43_SCT_CAPLA11_OFFSET) +#define LPC43_SCT_CAPLA12 (LPC43_SCT_BASE+LPC43_SCT_CAPLA12_OFFSET) +#define LPC43_SCT_CAPLA13 (LPC43_SCT_BASE+LPC43_SCT_CAPLA13_OFFSET) +#define LPC43_SCT_CAPLA14 (LPC43_SCT_BASE+LPC43_SCT_CAPLA14_OFFSET) +#define LPC43_SCT_CAPLA15 (LPC43_SCT_BASE+LPC43_SCT_CAPLA15_OFFSET) + +#define LPC43_SCT_CAPHA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPHA_OFFSET(n)) +#define LPC43_SCT_CAPHA0 (LPC43_SCT_BASE+LPC43_SCT_CAPHA0_OFFSET) +#define LPC43_SCT_CAPHA1 (LPC43_SCT_BASE+LPC43_SCT_CAPHA1_OFFSET) +#define LPC43_SCT_CAPHA2 (LPC43_SCT_BASE+LPC43_SCT_CAPHA2_OFFSET) +#define LPC43_SCT_CAPHA3 (LPC43_SCT_BASE+LPC43_SCT_CAPHA3_OFFSET) +#define LPC43_SCT_CAPHA4 (LPC43_SCT_BASE+LPC43_SCT_CAPHA4_OFFSET) +#define LPC43_SCT_CAPHA5 (LPC43_SCT_BASE+LPC43_SCT_CAPHA5_OFFSET) +#define LPC43_SCT_CAPHA6 (LPC43_SCT_BASE+LPC43_SCT_CAPHA6_OFFSET) +#define LPC43_SCT_CAPHA7 (LPC43_SCT_BASE+LPC43_SCT_CAPHA7_OFFSET) +#define LPC43_SCT_CAPHA8 (LPC43_SCT_BASE+LPC43_SCT_CAPHA8_OFFSET) +#define LPC43_SCT_CAPHA9 (LPC43_SCT_BASE+LPC43_SCT_CAPHA9_OFFSET) +#define LPC43_SCT_CAPHA10 (LPC43_SCT_BASE+LPC43_SCT_CAPHA10_OFFSET) +#define LPC43_SCT_CAPHA11 (LPC43_SCT_BASE+LPC43_SCT_CAPHA11_OFFSET) +#define LPC43_SCT_CAPHA12 (LPC43_SCT_BASE+LPC43_SCT_CAPHA12_OFFSET) +#define LPC43_SCT_CAPHA13 (LPC43_SCT_BASE+LPC43_SCT_CAPHA13_OFFSET) +#define LPC43_SCT_CAPHA14 (LPC43_SCT_BASE+LPC43_SCT_CAPHA14_OFFSET) +#define LPC43_SCT_CAPHA15 (LPC43_SCT_BASE+LPC43_SCT_CAPHA15_OFFSET) + +#define LPC43_SCT_MATCHR(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHR_OFFSET(n)) +#define LPC43_SCT_MATCHR0 (LPC43_SCT_BASE+LPC43_SCT_MATCHR0_OFFSET) +#define LPC43_SCT_MATCHR1 (LPC43_SCT_BASE+LPC43_SCT_MATCHR1_OFFSET) +#define LPC43_SCT_MATCHR2 (LPC43_SCT_BASE+LPC43_SCT_MATCHR2_OFFSET) +#define LPC43_SCT_MATCHR3 (LPC43_SCT_BASE+LPC43_SCT_MATCHR3_OFFSET) +#define LPC43_SCT_MATCHR4 (LPC43_SCT_BASE+LPC43_SCT_MATCHR4_OFFSET) +#define LPC43_SCT_MATCHR5 (LPC43_SCT_BASE+LPC43_SCT_MATCHR5_OFFSET) +#define LPC43_SCT_MATCHR6 (LPC43_SCT_BASE+LPC43_SCT_MATCHR6_OFFSET) +#define LPC43_SCT_MATCHR7 (LPC43_SCT_BASE+LPC43_SCT_MATCHR7_OFFSET) +#define LPC43_SCT_MATCHR8 (LPC43_SCT_BASE+LPC43_SCT_MATCHR8_OFFSET) +#define LPC43_SCT_MATCHR9 (LPC43_SCT_BASE+LPC43_SCT_MATCHR9_OFFSET) +#define LPC43_SCT_MATCHR10 (LPC43_SCT_BASE+LPC43_SCT_MATCHR10_OFFSET) +#define LPC43_SCT_MATCHR11 (LPC43_SCT_BASE+LPC43_SCT_MATCHR11_OFFSET) +#define LPC43_SCT_MATCHR12 (LPC43_SCT_BASE+LPC43_SCT_MATCHR12_OFFSET) +#define LPC43_SCT_MATCHR13 (LPC43_SCT_BASE+LPC43_SCT_MATCHR13_OFFSET) +#define LPC43_SCT_MATCHR14 (LPC43_SCT_BASE+LPC43_SCT_MATCHR14_OFFSET) +#define LPC43_SCT_MATCHR15 (LPC43_SCT_BASE+LPC43_SCT_MATCHR15_OFFSET) + +#define LPC43_SCT_MATCHRL(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHRL_OFFSET(n)) +#define LPC43_SCT_MATCHRL0 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL0_OFFSET) +#define LPC43_SCT_MATCHRL1 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL1_OFFSET) +#define LPC43_SCT_MATCHRL2 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL2_OFFSET) +#define LPC43_SCT_MATCHRL3 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL3_OFFSET) +#define LPC43_SCT_MATCHRL4 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL4_OFFSET) +#define LPC43_SCT_MATCHRL5 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL5_OFFSET) +#define LPC43_SCT_MATCHRL6 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL6_OFFSET) +#define LPC43_SCT_MATCHRL7 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL7_OFFSET) +#define LPC43_SCT_MATCHRL8 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL8_OFFSET) +#define LPC43_SCT_MATCHRL9 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL9_OFFSET) +#define LPC43_SCT_MATCHRL10 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL10_OFFSET) +#define LPC43_SCT_MATCHRL11 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL11_OFFSET) +#define LPC43_SCT_MATCHRL12 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL12_OFFSET) +#define LPC43_SCT_MATCHRL13 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL13_OFFSET) +#define LPC43_SCT_MATCHRL14 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL14_OFFSET) +#define LPC43_SCT_MATCHRL15 (LPC43_SCT_BASE+LPC43_SCT_MATCHRL15_OFFSET) + +#define LPC43_SCT_MATCHRH(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHRH_OFFSET(n)) +#define LPC43_SCT_MATCHRH0 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH0_OFFSET) +#define LPC43_SCT_MATCHRH1 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH1_OFFSET) +#define LPC43_SCT_MATCHRH2 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH2_OFFSET) +#define LPC43_SCT_MATCHRH3 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH3_OFFSET) +#define LPC43_SCT_MATCHRH4 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH4_OFFSET) +#define LPC43_SCT_MATCHRH5 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH5_OFFSET) +#define LPC43_SCT_MATCHRH6 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH6_OFFSET) +#define LPC43_SCT_MATCHRH7 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH7_OFFSET) +#define LPC43_SCT_MATCHRH8 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH8_OFFSET) +#define LPC43_SCT_MATCHRH9 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH9_OFFSET) +#define LPC43_SCT_MATCHRH10 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH10_OFFSET) +#define LPC43_SCT_MATCHRH11 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH11_OFFSET) +#define LPC43_SCT_MATCHRH12 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH12_OFFSET) +#define LPC43_SCT_MATCHRH13 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH13_OFFSET) +#define LPC43_SCT_MATCHRH14 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH14_OFFSET) +#define LPC43_SCT_MATCHRH15 (LPC43_SCT_BASE+LPC43_SCT_MATCHRH15_OFFSET) + +#define LPC43_SCT_CAPC(n) (LPC43_SCT_BASE+LPC43_SCT_CAPC_OFFSET(n)) +#define LPC43_SCT_CAPC0 (LPC43_SCT_BASE+LPC43_SCT_CAPC0_OFFSET) +#define LPC43_SCT_CAPC1 (LPC43_SCT_BASE+LPC43_SCT_CAPC1_OFFSET) +#define LPC43_SCT_CAPC2 (LPC43_SCT_BASE+LPC43_SCT_CAPC2_OFFSET) +#define LPC43_SCT_CAPC3 (LPC43_SCT_BASE+LPC43_SCT_CAPC3_OFFSET) +#define LPC43_SCT_CAPC4 (LPC43_SCT_BASE+LPC43_SCT_CAPC4_OFFSET) +#define LPC43_SCT_CAPC5 (LPC43_SCT_BASE+LPC43_SCT_CAPC5_OFFSET) +#define LPC43_SCT_CAPC6 (LPC43_SCT_BASE+LPC43_SCT_CAPC6_OFFSET) +#define LPC43_SCT_CAPC7 (LPC43_SCT_BASE+LPC43_SCT_CAPC7_OFFSET) +#define LPC43_SCT_CAPC8 (LPC43_SCT_BASE+LPC43_SCT_CAPC8_OFFSET) +#define LPC43_SCT_CAPC9 (LPC43_SCT_BASE+LPC43_SCT_CAPC9_OFFSET) +#define LPC43_SCT_CAPC10 (LPC43_SCT_BASE+LPC43_SCT_CAPC10_OFFSET) +#define LPC43_SCT_CAPC11 (LPC43_SCT_BASE+LPC43_SCT_CAPC11_OFFSET) +#define LPC43_SCT_CAPC12 (LPC43_SCT_BASE+LPC43_SCT_CAPC12_OFFSET) +#define LPC43_SCT_CAPC13 (LPC43_SCT_BASE+LPC43_SCT_CAPC13_OFFSET) +#define LPC43_SCT_CAPC14 (LPC43_SCT_BASE+LPC43_SCT_CAPC14_OFFSET) +#define LPC43_SCT_CAPC15 (LPC43_SCT_BASE+LPC43_SCT_CAPC15_OFFSET) + +#define LPC43_SCT_CAPCL(n) (LPC43_SCT_BASE+LPC43_SCT_CAPCL_OFFSET(n)) +#define LPC43_SCT_CAPCL0 (LPC43_SCT_BASE+LPC43_SCT_CAPCL0_OFFSET) +#define LPC43_SCT_CAPCL1 (LPC43_SCT_BASE+LPC43_SCT_CAPCL1_OFFSET) +#define LPC43_SCT_CAPCL2 (LPC43_SCT_BASE+LPC43_SCT_CAPCL2_OFFSET) +#define LPC43_SCT_CAPCL3 (LPC43_SCT_BASE+LPC43_SCT_CAPCL3_OFFSET) +#define LPC43_SCT_CAPCL4 (LPC43_SCT_BASE+LPC43_SCT_CAPCL4_OFFSET) +#define LPC43_SCT_CAPCL5 (LPC43_SCT_BASE+LPC43_SCT_CAPCL5_OFFSET) +#define LPC43_SCT_CAPCL6 (LPC43_SCT_BASE+LPC43_SCT_CAPCL6_OFFSET) +#define LPC43_SCT_CAPCL7 (LPC43_SCT_BASE+LPC43_SCT_CAPCL7_OFFSET) +#define LPC43_SCT_CAPCL8 (LPC43_SCT_BASE+LPC43_SCT_CAPCL8_OFFSET) +#define LPC43_SCT_CAPCL9 (LPC43_SCT_BASE+LPC43_SCT_CAPCL9_OFFSET) +#define LPC43_SCT_CAPCL10 (LPC43_SCT_BASE+LPC43_SCT_CAPCL10_OFFSET) +#define LPC43_SCT_CAPCL11 (LPC43_SCT_BASE+LPC43_SCT_CAPCL11_OFFSET) +#define LPC43_SCT_CAPCL12 (LPC43_SCT_BASE+LPC43_SCT_CAPCL12_OFFSET) +#define LPC43_SCT_CAPCL13 (LPC43_SCT_BASE+LPC43_SCT_CAPCL13_OFFSET) +#define LPC43_SCT_CAPCL14 (LPC43_SCT_BASE+LPC43_SCT_CAPCL14_OFFSET) +#define LPC43_SCT_CAPCL15 (LPC43_SCT_BASE+LPC43_SCT_CAPCL15_OFFSET) + +#define LPC43_SCT_CAPCH(n) (LPC43_SCT_BASE+LPC43_SCT_CAPCH_OFFSET(n)) +#define LPC43_SCT_CAPCH0 (LPC43_SCT_BASE+LPC43_SCT_CAPCH0_OFFSET) +#define LPC43_SCT_CAPCH1 (LPC43_SCT_BASE+LPC43_SCT_CAPCH1_OFFSET) +#define LPC43_SCT_CAPCH2 (LPC43_SCT_BASE+LPC43_SCT_CAPCH2_OFFSET) +#define LPC43_SCT_CAPCH3 (LPC43_SCT_BASE+LPC43_SCT_CAPCH3_OFFSET) +#define LPC43_SCT_CAPCH4 (LPC43_SCT_BASE+LPC43_SCT_CAPCH4_OFFSET) +#define LPC43_SCT_CAPCH5 (LPC43_SCT_BASE+LPC43_SCT_CAPCH5_OFFSET) +#define LPC43_SCT_CAPCH6 (LPC43_SCT_BASE+LPC43_SCT_CAPCH6_OFFSET) +#define LPC43_SCT_CAPCH7 (LPC43_SCT_BASE+LPC43_SCT_CAPCH7_OFFSET) +#define LPC43_SCT_CAPCH8 (LPC43_SCT_BASE+LPC43_SCT_CAPCH8_OFFSET) +#define LPC43_SCT_CAPCH9 (LPC43_SCT_BASE+LPC43_SCT_CAPCH9_OFFSET) +#define LPC43_SCT_CAPCH10 (LPC43_SCT_BASE+LPC43_SCT_CAPCH10_OFFSET) +#define LPC43_SCT_CAPCH11 (LPC43_SCT_BASE+LPC43_SCT_CAPCH11_OFFSET) +#define LPC43_SCT_CAPCH12 (LPC43_SCT_BASE+LPC43_SCT_CAPCH12_OFFSET) +#define LPC43_SCT_CAPCH13 (LPC43_SCT_BASE+LPC43_SCT_CAPCH13_OFFSET) +#define LPC43_SCT_CAPCH14 (LPC43_SCT_BASE+LPC43_SCT_CAPCH14_OFFSET) +#define LPC43_SCT_CAPCH15 (LPC43_SCT_BASE+LPC43_SCT_CAPCH15_OFFSET) + +#define LPC43_SCT_MATCHRA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHRA_OFFSET(n)) +#define LPC43_SCT_MATCHRA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA0_OFFSET) +#define LPC43_SCT_MATCHRA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA1_OFFSET) +#define LPC43_SCT_MATCHRA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA2_OFFSET) +#define LPC43_SCT_MATCHRA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA3_OFFSET) +#define LPC43_SCT_MATCHRA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA4_OFFSET) +#define LPC43_SCT_MATCHRA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA5_OFFSET) +#define LPC43_SCT_MATCHRA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA6_OFFSET) +#define LPC43_SCT_MATCHRA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA7_OFFSET) +#define LPC43_SCT_MATCHRA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA8_OFFSET) +#define LPC43_SCT_MATCHRA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA9_OFFSET) +#define LPC43_SCT_MATCHRA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA10_OFFSET) +#define LPC43_SCT_MATCHRA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA11_OFFSET) +#define LPC43_SCT_MATCHRA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA12_OFFSET) +#define LPC43_SCT_MATCHRA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA13_OFFSET) +#define LPC43_SCT_MATCHRA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA14_OFFSET) +#define LPC43_SCT_MATCHRA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHRA15_OFFSET) + +#define LPC43_SCT_MATCHRLA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA_OFFSET(n)) +#define LPC43_SCT_MATCHRLA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA0_OFFSET) +#define LPC43_SCT_MATCHRLA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA1_OFFSET) +#define LPC43_SCT_MATCHRLA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA2_OFFSET) +#define LPC43_SCT_MATCHRLA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA3_OFFSET) +#define LPC43_SCT_MATCHRLA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA4_OFFSET) +#define LPC43_SCT_MATCHRLA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA5_OFFSET) +#define LPC43_SCT_MATCHRLA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA6_OFFSET) +#define LPC43_SCT_MATCHRLA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA7_OFFSET) +#define LPC43_SCT_MATCHRLA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA8_OFFSET) +#define LPC43_SCT_MATCHRLA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA9_OFFSET) +#define LPC43_SCT_MATCHRLA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA10_OFFSET) +#define LPC43_SCT_MATCHRLA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA11_OFFSET) +#define LPC43_SCT_MATCHRLA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA12_OFFSET) +#define LPC43_SCT_MATCHRLA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA13_OFFSET) +#define LPC43_SCT_MATCHRLA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA14_OFFSET) +#define LPC43_SCT_MATCHRLA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHRLA15_OFFSET) + +#define LPC43_SCT_MATCHRHA(n) (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA_OFFSET(n)) +#define LPC43_SCT_MATCHRHA0 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA0_OFFSET) +#define LPC43_SCT_MATCHRHA1 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA1_OFFSET) +#define LPC43_SCT_MATCHRHA2 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA2_OFFSET) +#define LPC43_SCT_MATCHRHA3 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA3_OFFSET) +#define LPC43_SCT_MATCHRHA4 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA4_OFFSET) +#define LPC43_SCT_MATCHRHA5 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA5_OFFSET) +#define LPC43_SCT_MATCHRHA6 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA6_OFFSET) +#define LPC43_SCT_MATCHRHA7 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA7_OFFSET) +#define LPC43_SCT_MATCHRHA8 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA8_OFFSET) +#define LPC43_SCT_MATCHRHA9 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA9_OFFSET) +#define LPC43_SCT_MATCHRHA10 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA10_OFFSET) +#define LPC43_SCT_MATCHRHA11 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA11_OFFSET) +#define LPC43_SCT_MATCHRHA12 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA12_OFFSET) +#define LPC43_SCT_MATCHRHA13 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA13_OFFSET) +#define LPC43_SCT_MATCHRHA14 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA14_OFFSET) +#define LPC43_SCT_MATCHRHA15 (LPC43_SCT_BASE+LPC43_SCT_MATCHRHA15_OFFSET) + +#define LPC43_SCT_CAPCA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPCA_OFFSET(n)) +#define LPC43_SCT_CAPCA0 (LPC43_SCT_BASE+LPC43_SCT_CAPCA0_OFFSET) +#define LPC43_SCT_CAPCA1 (LPC43_SCT_BASE+LPC43_SCT_CAPCA1_OFFSET) +#define LPC43_SCT_CAPCA2 (LPC43_SCT_BASE+LPC43_SCT_CAPCA2_OFFSET) +#define LPC43_SCT_CAPCA3 (LPC43_SCT_BASE+LPC43_SCT_CAPCA3_OFFSET) +#define LPC43_SCT_CAPCA4 (LPC43_SCT_BASE+LPC43_SCT_CAPCA4_OFFSET) +#define LPC43_SCT_CAPCA5 (LPC43_SCT_BASE+LPC43_SCT_CAPCA5_OFFSET) +#define LPC43_SCT_CAPCA6 (LPC43_SCT_BASE+LPC43_SCT_CAPCA6_OFFSET) +#define LPC43_SCT_CAPCA7 (LPC43_SCT_BASE+LPC43_SCT_CAPCA7_OFFSET) +#define LPC43_SCT_CAPCA8 (LPC43_SCT_BASE+LPC43_SCT_CAPCA8_OFFSET) +#define LPC43_SCT_CAPCA9 (LPC43_SCT_BASE+LPC43_SCT_CAPCA9_OFFSET) +#define LPC43_SCT_CAPCA10 (LPC43_SCT_BASE+LPC43_SCT_CAPCA10_OFFSET) +#define LPC43_SCT_CAPCA11 (LPC43_SCT_BASE+LPC43_SCT_CAPCA11_OFFSET) +#define LPC43_SCT_CAPCA12 (LPC43_SCT_BASE+LPC43_SCT_CAPCA12_OFFSET) +#define LPC43_SCT_CAPCA13 (LPC43_SCT_BASE+LPC43_SCT_CAPCA13_OFFSET) +#define LPC43_SCT_CAPCA14 (LPC43_SCT_BASE+LPC43_SCT_CAPCA14_OFFSET) +#define LPC43_SCT_CAPCA15 (LPC43_SCT_BASE+LPC43_SCT_CAPCA15_OFFSET) + +#define LPC43_SCT_CAPCLA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPCLA_OFFSET(n)) +#define LPC43_SCT_CAPCLA0 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA0_OFFSET) +#define LPC43_SCT_CAPCLA1 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA1_OFFSET) +#define LPC43_SCT_CAPCLA2 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA2_OFFSET) +#define LPC43_SCT_CAPCLA3 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA3_OFFSET) +#define LPC43_SCT_CAPCLA4 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA4_OFFSET) +#define LPC43_SCT_CAPCLA5 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA5_OFFSET) +#define LPC43_SCT_CAPCLA6 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA6_OFFSET) +#define LPC43_SCT_CAPCLA7 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA7_OFFSET) +#define LPC43_SCT_CAPCLA8 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA8_OFFSET) +#define LPC43_SCT_CAPCLA9 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA9_OFFSET) +#define LPC43_SCT_CAPCLA10 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA10_OFFSET) +#define LPC43_SCT_CAPCLA11 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA11_OFFSET) +#define LPC43_SCT_CAPCLA12 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA12_OFFSET) +#define LPC43_SCT_CAPCLA13 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA13_OFFSET) +#define LPC43_SCT_CAPCLA14 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA14_OFFSET) +#define LPC43_SCT_CAPCLA15 (LPC43_SCT_BASE+LPC43_SCT_CAPCLA15_OFFSET) + +#define LPC43_SCT_CAPCHA(n) (LPC43_SCT_BASE+LPC43_SCT_CAPCHA_OFFSET(n)) +#define LPC43_SCT_CAPCHA0 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA0_OFFSET) +#define LPC43_SCT_CAPCHA1 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA1_OFFSET) +#define LPC43_SCT_CAPCHA2 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA2_OFFSET) +#define LPC43_SCT_CAPCHA3 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA3_OFFSET) +#define LPC43_SCT_CAPCHA4 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA4_OFFSET) +#define LPC43_SCT_CAPCHA5 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA5_OFFSET) +#define LPC43_SCT_CAPCHA6 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA6_OFFSET) +#define LPC43_SCT_CAPCHA7 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA7_OFFSET) +#define LPC43_SCT_CAPCHA8 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA8_OFFSET) +#define LPC43_SCT_CAPCHA9 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA9_OFFSET) +#define LPC43_SCT_CAPCHA10 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA10_OFFSET) +#define LPC43_SCT_CAPCHA11 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA11_OFFSET) +#define LPC43_SCT_CAPCHA12 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA12_OFFSET) +#define LPC43_SCT_CAPCHA13 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA13_OFFSET) +#define LPC43_SCT_CAPCHA14 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA14_OFFSET) +#define LPC43_SCT_CAPCHA15 (LPC43_SCT_BASE+LPC43_SCT_CAPCHA15_OFFSET) + +#define LPC43_SCT_EVSM(n) (LPC43_SCT_BASE+LPC43_SCT_EVSM_OFFSET(n)) +#define LPC43_SCT_EVC(n) (LPC43_SCT_BASE+LPC43_SCT_EVC_OFFSET(n)) + +#define LPC43_SCT_EVSM0 (LPC43_SCT_BASE+LPC43_SCT_EVSM0_OFFSET) +#define LPC43_SCT_EVC0 (LPC43_SCT_BASE+LPC43_SCT_EVC0_OFFSET) +#define LPC43_SCT_EVSM1 (LPC43_SCT_BASE+LPC43_SCT_EVSM1_OFFSET) +#define LPC43_SCT_EVC1 (LPC43_SCT_BASE+LPC43_SCT_EVC1_OFFSET) +#define LPC43_SCT_EVSM2 (LPC43_SCT_BASE+LPC43_SCT_EVSM2_OFFSET) +#define LPC43_SCT_EVC2 (LPC43_SCT_BASE+LPC43_SCT_EVC2_OFFSET) +#define LPC43_SCT_EVSM3 (LPC43_SCT_BASE+LPC43_SCT_EVSM3_OFFSET) +#define LPC43_SCT_EVC3 (LPC43_SCT_BASE+LPC43_SCT_EVC3_OFFSET) +#define LPC43_SCT_EVSM4 (LPC43_SCT_BASE+LPC43_SCT_EVSM4_OFFSET) +#define LPC43_SCT_EVC4 (LPC43_SCT_BASE+LPC43_SCT_EVC4_OFFSET) +#define LPC43_SCT_EVSM5 (LPC43_SCT_BASE+LPC43_SCT_EVSM5_OFFSET) +#define LPC43_SCT_EVC5 (LPC43_SCT_BASE+LPC43_SCT_EVC5_OFFSET) +#define LPC43_SCT_EVSM6 (LPC43_SCT_BASE+LPC43_SCT_EVSM6_OFFSET) +#define LPC43_SCT_EVC6 (LPC43_SCT_BASE+LPC43_SCT_EVC6_OFFSET) +#define LPC43_SCT_EVSM7 (LPC43_SCT_BASE+LPC43_SCT_EVSM7_OFFSET) +#define LPC43_SCT_EVC7 (LPC43_SCT_BASE+LPC43_SCT_EVC7_OFFSET) +#define LPC43_SCT_EVSM8 (LPC43_SCT_BASE+LPC43_SCT_EVSM8_OFFSET) +#define LPC43_SCT_EVC8 (LPC43_SCT_BASE+LPC43_SCT_EVC8_OFFSET) +#define LPC43_SCT_EVSM9 (LPC43_SCT_BASE+LPC43_SCT_EVSM9_OFFSET) +#define LPC43_SCT_EVC9 (LPC43_SCT_BASE+LPC43_SCT_EVC9_OFFSET) +#define LPC43_SCT_EVSM10 (LPC43_SCT_BASE+LPC43_SCT_EVSM10_OFFSET) +#define LPC43_SCT_EVC10 (LPC43_SCT_BASE+LPC43_SCT_EVC10_OFFSET) +#define LPC43_SCT_EVSM11 (LPC43_SCT_BASE+LPC43_SCT_EVSM11_OFFSET) +#define LPC43_SCT_EVC11 (LPC43_SCT_BASE+LPC43_SCT_EVC11_OFFSET) +#define LPC43_SCT_EVSM12 (LPC43_SCT_BASE+LPC43_SCT_EVSM12_OFFSET) +#define LPC43_SCT_EVC12 (LPC43_SCT_BASE+LPC43_SCT_EVC12_OFFSET) +#define LPC43_SCT_EVSM13 (LPC43_SCT_BASE+LPC43_SCT_EVSM13_OFFSET) +#define LPC43_SCT_EVC13 (LPC43_SCT_BASE+LPC43_SCT_EVC13_OFFSET) +#define LPC43_SCT_EVSM14 (LPC43_SCT_BASE+LPC43_SCT_EVSM14_OFFSET) +#define LPC43_SCT_EVC14 (LPC43_SCT_BASE+LPC43_SCT_EVC14_OFFSET) +#define LPC43_SCT_EVSM15 (LPC43_SCT_BASE+LPC43_SCT_EVSM15_OFFSET) +#define LPC43_SCT_EVC15 (LPC43_SCT_BASE+LPC43_SCT_EVC15_OFFSET) + +#define LPC43_SCT_OUTSET(n) (LPC43_SCT_BASE+LPC43_SCT_OUTSET_OFFSET(n)) +#define LPC43_SCT_OUTCLR(n) (LPC43_SCT_BASE+LPC43_SCT_OUTCLR_OFFSET(n)) + +#define LPC43_SCT_OUTSET0 (LPC43_SCT_BASE+LPC43_SCT_OUTSET0_OFFSET) +#define LPC43_SCT_OUTCLR0 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR0_OFFSET) +#define LPC43_SCT_OUTSET1 (LPC43_SCT_BASE+LPC43_SCT_OUTSET1_OFFSET) +#define LPC43_SCT_OUTCLR1 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR1_OFFSET) +#define LPC43_SCT_OUTSET2 (LPC43_SCT_BASE+LPC43_SCT_OUTSET2_OFFSET) +#define LPC43_SCT_OUTCLR2 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR2_OFFSET) +#define LPC43_SCT_OUTSET3 (LPC43_SCT_BASE+LPC43_SCT_OUTSET3_OFFSET) +#define LPC43_SCT_OUTCLR3 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR3_OFFSET) +#define LPC43_SCT_OUTSET4 (LPC43_SCT_BASE+LPC43_SCT_OUTSET4_OFFSET) +#define LPC43_SCT_OUTCLR4 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR4_OFFSET) +#define LPC43_SCT_OUTSET5 (LPC43_SCT_BASE+LPC43_SCT_OUTSET5_OFFSET) +#define LPC43_SCT_OUTCLR5 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR5_OFFSET) +#define LPC43_SCT_OUTSET6 (LPC43_SCT_BASE+LPC43_SCT_OUTSET6_OFFSET) +#define LPC43_SCT_OUTCLR6 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR6_OFFSET) +#define LPC43_SCT_OUTSET7 (LPC43_SCT_BASE+LPC43_SCT_OUTSET7_OFFSET) +#define LPC43_SCT_OUTCLR7 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR7_OFFSET) +#define LPC43_SCT_OUTSET8 (LPC43_SCT_BASE+LPC43_SCT_OUTSET8_OFFSET) +#define LPC43_SCT_OUTCLR8 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR8_OFFSET) +#define LPC43_SCT_OUTSET9 (LPC43_SCT_BASE+LPC43_SCT_OUTSET9_OFFSET) +#define LPC43_SCT_OUTCLR9 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR9_OFFSET) +#define LPC43_SCT_OUTSET10 (LPC43_SCT_BASE+LPC43_SCT_OUTSET10_OFFSET) +#define LPC43_SCT_OUTCLR10 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR10_OFFSET) +#define LPC43_SCT_OUTSET11 (LPC43_SCT_BASE+LPC43_SCT_OUTSET11_OFFSET) +#define LPC43_SCT_OUTCLR11 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR11_OFFSET) +#define LPC43_SCT_OUTSET12 (LPC43_SCT_BASE+LPC43_SCT_OUTSET12_OFFSET) +#define LPC43_SCT_OUTCLR12 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR12_OFFSET) +#define LPC43_SCT_OUTSET13 (LPC43_SCT_BASE+LPC43_SCT_OUTSET13_OFFSET) +#define LPC43_SCT_OUTCLR13 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR13_OFFSET) +#define LPC43_SCT_OUTSET14 (LPC43_SCT_BASE+LPC43_SCT_OUTSET14_OFFSET) +#define LPC43_SCT_OUTCLR14 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR14_OFFSET) +#define LPC43_SCT_OUTSET15 (LPC43_SCT_BASE+LPC43_SCT_OUTSET15_OFFSET) +#define LPC43_SCT_OUTCLR15 (LPC43_SCT_BASE+LPC43_SCT_OUTCLR15_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* SCT configuration register */ + +#define SCT_CONFIG_UNIFY (1 << 0) /* Bit 0: 0 SCT operation */ +#define SCT_CONFIG_CLKMODE_SHIFT (1) /* Bits 1-2: SCT clock mode */ +#define SCT_CONFIG_CLKMODE_MASK (3 << SCT_CONFIG_CLKMODE_SHIFT) +# define SCT_CONFIG_CLKMODE_BUS (0 << SCT_CONFIG_CLKMODE_SHIFT) /* Bus clock clocks SCT and prescalers */ +# define SCT_CONFIG_CLKMODE_SCT (1 << SCT_CONFIG_CLKMODE_SHIFT) /* SCT clock is the bus clock */ +# define SCT_CONFIG_CLKMODE_CLKSEL (2 << SCT_CONFIG_CLKMODE_SHIFT) /* CLKSEL clocks SCT and prescalers */ +# define SCT_CONFIG_CLKMODE_EDGE (3 << SCT_CONFIG_CLKMODE_SHIFT) /* CLKSEL input edge clocks SCT and prescalers */ +#define SCT_CONFIG_CLKSEL_SHIFT (3) /* Bits 3-6: SCT clock select */ +#define SCT_CONFIG_CLKSEL_MASK (15 << SCT_CONFIG_CLKSEL_SHIFT) +# define SCT_CONFIG_CLKSEL_REDGE0 (0 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 0 */ +# define SCT_CONFIG_CLKSEL_FEDGE0 (1 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 0 */ +# define SCT_CONFIG_CLKSEL_REDGE1 (2 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 1 */ +# define SCT_CONFIG_CLKSEL_FEDGE1 (3 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 1 */ +# define SCT_CONFIG_CLKSEL_REDGE2 (4 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 2 */ +# define SCT_CONFIG_CLKSEL_FEDGE2 (5 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 2 */ +# define SCT_CONFIG_CLKSEL_REDGE3 (6 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 3 */ +# define SCT_CONFIG_CLKSEL_FEDGE3 (7 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 3 */ +# define SCT_CONFIG_CLKSEL_REDGE4 (8 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 4 */ +# define SCT_CONFIG_CLKSEL_FEDGE4 (9 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 4 */ +# define SCT_CONFIG_CLKSEL_REDGE5 (10 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 5 */ +# define SCT_CONFIG_CLKSEL_FEDGE5 (11 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 5 */ +# define SCT_CONFIG_CLKSEL_REDGE6 (12 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 6 */ +# define SCT_CONFIG_CLKSEL_FEDGE6 (13 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 6 */ +# define SCT_CONFIG_CLKSEL_REDGE7 (14 << SCT_CONFIG_CLKSEL_SHIFT) /* Rising edges on input 7 */ +# define SCT_CONFIG_CLKSEL_FEDGE7 (15 << SCT_CONFIG_CLKSEL_SHIFT) /* Falling edges on input 7 */ +#define SCT_CONFIG_NORELOADU (1 << 7) /* Bit 7: Disable unified match register reload */ +#define SCT_CONFIG_NORELOADL (1 << 7) /* Bit 7: Disable lower match registers reload */ +#define SCT_CONFIG_NORELOADH (1 << 8) /* Bit 8: Disable higher match register reload */ +#define SCT_CONFIG_INSYNC_SHIFT (9) /* Bits 9-16: Synchronization for input n=1..7 */ +#define SCT_CONFIG_INSYNC_MASK (0xff << SCT_CONFIG_INSYNC_SHIFT) +# define SCT_CONFIG_INSYNC(n) (1 << (SCT_CONFIG_INSYNC_SHIFT+(n))) + /* Bits 17-31: Reserved */ +/* SCT control register */ + +#define SCT_CTRL_DOWNU (1 << 0) /* Bit 0: Unified counter counts down */ +#define SCT_CTRL_STOPU (1 << 1) /* Bit 1: Unified counter stopped (I/O events can occur) */ +#define SCT_CTRL_HALTU (1 << 2) /* Bit 2: Unified counter halted (no events can occur) */ +#define SCT_CTRL_CLRCTRU (1 << 3) /* Bit 3: Clear unified counter */ +#define SCT_CTRL_BIDIRU (1 << 4) /* Bit 4: Unified counter direction select */ +#define SCT_CTRL_PREU_SHIFT (5) /* Bits 5-12: Unified counter SCT clock prescale factor */ +#define SCT_CTRL_PREU_MASK (0xff << SCT_CTRL_PREU_SHIFT) + +#define SCT_CTRL_DOWNL (1 << 0) /* Bit 0: L counter counts down */ +#define SCT_CTRL_STOPL (1 << 1) /* Bit 1: L counter stopped (I/O events can occur) */ +#define SCT_CTRL_HALTL (1 << 2) /* Bit 2: L counter halted (no events can occur) */ +#define SCT_CTRL_CLRCTRL (1 << 3) /* Bit 3: Clear L counter */ +#define SCT_CTRL_BIDIRL (1 << 4) /* Bit 4: L counter direction select */ +#define SCT_CTRL_PREL_SHIFT (5) /* Bits 5-12: L counter SCT clock prescale factor */ +#define SCT_CTRL_PREL_MASK (0xff << SCT_CTRL_PREL_SHIFT) + /* Bits 13-15: Reserved */ +#define SCT_CTRL_DOWNH (1 << 16) /* Bit 16: H counter counts down */ +#define SCT_CTRL_STOPH (1 << 17) /* Bit 17: H counter stopped (I/O events can occur) */ +#define SCT_CTRL_HALTH (1 << 18) /* Bit 18: H counter halted (no events can occur) */ +#define SCT_CTRL_CLRCTRH (1 << 19) /* Bit 19: Clear H counter */ +#define SCT_CTRL_BIDIRH (1 << 20) /* Bit 20: H counter direction select */ +#define SCT_CTRL_PREH_SHIFT (21) /* Bits 21-28: H counter SCT clock prescale factor */ +#define SCT_CTRL_PREH_MASK (0xff << yy) + /* Bits 29-31: Reserved */ +/* SCT control register low/high 16-bit */ + +#define SCT_CTRL_DOWN (1 << 0) /* Bit 0: Unified counter counts down */ +#define SCT_CTRL_STOP (1 << 1) /* Bit 1: Unified counter stopped (I/O events can occur) */ +#define SCT_CTRL_HALT (1 << 2) /* Bit 2: Unified counter halted (no events can occur) */ +#define SCT_CTRL_CLRCTR (1 << 3) /* Bit 3: Clear unified counter */ +#define SCT_CTRL_BIDIR (1 << 4) /* Bit 4: Unified counter direction select */ +#define SCT_CTRL_PRE_SHIFT (5) /* Bits 5-12: Unified counter SCT clock prescale factor */ +#define SCT_CTRL_PRE_MASK (0xff << SCT_CTRL_PRE_SHIFT) + /* Bits 13-16: Reserved */ +/* SCT limit register (all 32-bits for unified counter) */ + +#define SCT_LIMITL_SHIFT (0) /* Bits 0-15: Limit for L counter */ +#define SCT_LIMITL_MASK (0xffff << SCT_LIMITL_SHIFT) +#define SCT_LIMITH_SHIFT (16) /* Bits 16-31: Limit for H counter */ +#define SCT_LIMITH_MASK (0xffff << SCT_LIMITH_SHIFT) + +/* SCT limit register low/high 16-bit (all 16-bits for limit value) */ + +/* SCT halt condition register (all 32-bits for unified counter) */ + +#define SCT_HALTU(n) (1 << (n)) +#define SCT_HALTL_SHIFT (0) /* Bits 0-15: Set HALTL in CTRL register */ +#define SCT_HALTL_MASK (0xffff << SCT_HALTL_SHIFT) +# define SCT_HALTL(n) (1 << (n)) +#define SCT_HALTH_SHIFT (16) /* Bits 16-31:Set HALTL in CTRL register */ +#define SCT_HALTH_MASK (0xffff << SCT_HALTH_SHIFT) +# define SCT_HALTH(n) (1 << (SCT_HALTH_SHIFT+(n))) + +/* SCT halt condition register low/high 16-bit (all 16-bits for halt condition) */ + +#define SCT_HALT(n) (1 << (n)) + +/* SCT stop condition register (all 32-bits for unified counter) */ + +#define SCT_STOPU(n) (1 << (n)) +#define SCT_STOPL_SHIFT (0) /* Bits 0-15: Set STOPL in CTRL register */ +#define SCT_STOPL_MASK (0xffff << SCT_STOPL_SHIFT) +# define SCT_STOPL(n) (1 << (n)) +#define SCT_STOPH_SHIFT (16) /* Bits 16-31:Set STOPL in CTRL register */ +#define SCT_STOPH_MASK (0xffff << SCT_STOPH_SHIFT) +# define SCT_STOPH(n) (1 << (SCT_STOPH_SHIFT+(n))) + +/* SCT stop condition register low 16-bit (all 16-bits for stop condition) */ + +#define SCT_STOP(n) (1 << (n)) + +/* SCT start condition register (all 32-bits for unified counter) */ + +#define SCT_STARTU(n) (1 << (n)) +#define SCT_STARTL_SHIFT (0) /* Bits 0-15: Clear STOPL in CTRL register */ +#define SCT_STARTL_MASK (0xffff << SCT_STARTL_SHIFT) +# define SCT_STARTL(n) (1 << (n)) +#define SCT_STARTH_SHIFT (16) /* Bits 16-31: Clear STOPL in CTRL register */ +#define SCT_STARTH_MASK (0xffff << SCT_STARTH_SHIFT) +# define SCT_STARTH(n) (1 << (SCT_STARTH_SHIFT+(n))) + +/* SCT start condition register low 16-bit (all 16-bits for start condition) */ + +#define SCT_START(n) (1 << (n)) + +/* SCT counter register (all 32-bits for unified counter) */ + +#define SCT_COUNTL_SHIFT (0) /* Bits 0-15: L counter value */ +#define SCT_COUNTL_MASK (0xffff << SCT_COUNTL_SHIFT) +#define SCT_COUNTH_SHIFT (16) /* Bits 16-31: H counter value */ +#define SCT_COUNTH_MASK (0xffff << SCT_COUNTH_SHIFT) + +/* SCT counter register low/high 16-bit (all 16-bits for counter value)*/ + +/* SCT state register */ + +#define SCT_STATEU_SHIFT (0) /* Bits 0-5: Unified counter state */ +#define SCT_STATEU_MASK (31 << SCT_STATEL_SHIFT) +#define SCT_STATEL_SHIFT (0) /* Bits 0-5: L counter state */ +#define SCT_STATEL_MASK (31 << SCT_STATEL_SHIFT) + /* Bits 6-15: Reserved */ +#define SCT_STATEH_SHIFT (16) /* Bits 16-20: H counter state */ +#define SCT_STATEH_MASK (31 << SCT_STATEH_SHIFT) + /* Bits 21-31: Reserved */ +/* SCT state register low/high 16-bit */ + +#define SCT_STATE_SHIFT (0) /* Bits 0-5: Counter state */ +#define SCT_STATE_MASK (31 << SCT_STATE_SHIFT) + /* Bits 6-15: Reserved */ +/* SCT input register */ + +#define SCT_INPUT_AIN(n) (1 << (n)) +#define SCT_INPUT_AIN0 (1 << 0) /* Bit 0: Real-time status of input 0 */ +#define SCT_INPUT_AIN1 (1 << 1) /* Bit 1: Real-time status of input 1 */ +#define SCT_INPUT_AIN2 (1 << 2) /* Bit 2: Real-time status of input 2 */ +#define SCT_INPUT_AIN3 (1 << 3) /* Bit 3: Real-time status of input 3 */ +#define SCT_INPUT_AIN4 (1 << 4) /* Bit 4: Real-time status of input 4 */ +#define SCT_INPUT_AIN5 (1 << 5) /* Bit 5: Real-time status of input 5 */ +#define SCT_INPUT_AIN6 (1 << 6) /* Bit 6: Real-time status of input 6 */ +#define SCT_INPUT_AIN7 (1 << 7) /* Bit 7: Real-time status of input 7 */ + /* Bits 8-15: Reserved */ +#define SCT_INPUT_SIN(n) (1 << ((n)+16)) +#define SCT_INPUT_SIN0 (1 << 16) /* Bit 16: Synchronized input 0 state */ +#define SCT_INPUT_SIN1 (1 << 17) /* Bit 17: Synchronized input 1 state */ +#define SCT_INPUT_SIN2 (1 << 18) /* Bit 18: Synchronized input 2 state */ +#define SCT_INPUT_SIN3 (1 << 19) /* Bit 19: Synchronized input 3 state */ +#define SCT_INPUT_SIN4 (1 << 20) /* Bit 20: Synchronized input 4 state */ +#define SCT_INPUT_SIN5 (1 << 21) /* Bit 21: Synchronized input 5 state */ +#define SCT_INPUT_SIN6 (1 << 22) /* Bit 22: Synchronized input 6 state */ +#define SCT_INPUT_SIN7 (1 << 23) /* Bit 23: Synchronized input 7 state */ + /* Bits 24-31: Reserved */ +/* SCT match/capture registers mode register (all 32-bits for unified counter)*/ + +#define SCT_REGMU(n) (1 << (n)) +#define SCT_REGML_SHIFT (0) /* Bits 0-15: Match/capture registers n */ +#define SCT_REGML_MASK (0xffff << SCT_REGML_SHIFT) +# define SCT_REGML(n) (1 << (n)) +#define SCT_REGMH_SHIFT (16) /* Bits 16-31: Match/capture registers n */ +#define SCT_REGMH_MASK (0xffff << SCT_REGMH_SHIFT) +# define SCT_REGMH(n) (1 << (SCT_REGMH_SHIFT+(n))) + +/* SCT match/capture registers mode register low 16-bit (all 16-bits)*/ + +#define SCT_REGM(n) (1 << (n)) + +/* SCT output register */ + +#define SCT_OUTU(n) (1 << (n)) /* Bits 0-15: Set output n */ + +/* SCT output counter direction control register */ + +#define SCT_OUTDIRC_UNCOND (0) /* Set and clear do not depend on any counter */ +#define SCT_OUTDIRC_REVU (1) /* Reversed when unified counter is counting down */ +#define SCT_OUTDIRC_REVL (1) /* Reversed when L counter is counting down */ +#define SCT_OUTDIRC_REVH (2) /* Reversed when H counter is counting down */ + +#define SCT_OUTDIRC_SETCLR_SHIFT(c) ((c) << 1) +#define SCT_OUTDIRC_SETCLR_SHIFT(c) (3 << SCT_OUTDIRC_SETCLR_SHIFT(c)) +# define SCT_OUTDIRC_SETCLR(c,n) ((n) << SCT_OUTDIRC_SETCLR_SHIFT(c)) + +#define SCT_OUTDIRC_SETCLR0_SHIFT (0) /* Bits 0-1: Set/clear operation on output 0 */ +#define SCT_OUTDIRC_SETCLR0_MASK (3 << SCT_OUTDIRC_SETCLR0_SHIFT) +# define SCT_OUTDIRC_SETCLR0(n) ((n) << SCT_OUTDIRC_SETCLR0_SHIFT) +#define SCT_OUTDIRC_SETCLR1_SHIFT (2) /* Bits 2-3: Set/clear operation on output 1 */ +#define SCT_OUTDIRC_SETCLR1_MASK (3 << SCT_OUTDIRC_SETCLR1_SHIFT) +# define SCT_OUTDIRC_SETCLR1(n) ((n) << SCT_OUTDIRC_SETCLR1_SHIFT) +#define SCT_OUTDIRC_SETCLR2_SHIFT (4) /* Bits 4-5: Set/clear operation on output 2 */ +#define SCT_OUTDIRC_SETCLR2_MASK (3 << SCT_OUTDIRC_SETCLR2_SHIFT) +# define SCT_OUTDIRC_SETCLR2(n) ((n) << SCT_OUTDIRC_SETCLR2_SHIFT) +#define SCT_OUTDIRC_SETCLR3_SHIFT (6) /* Bits 6-7: Set/clear operation on output 3 */ +#define SCT_OUTDIRC_SETCLR3_MASK (3 << SCT_OUTDIRC_SETCLR3_SHIFT) +# define SCT_OUTDIRC_SETCLR3(n) ((n) << SCT_OUTDIRC_SETCLR3_SHIFT) +#define SCT_OUTDIRC_SETCLR4_SHIFT (8) /* Bits 8-9: Set/clear operation on output 4 */ +#define SCT_OUTDIRC_SETCLR4_MASK (3 << SCT_OUTDIRC_SETCLR4_SHIFT) +# define SCT_OUTDIRC_SETCLR4(n) ((n) << SCT_OUTDIRC_SETCLR4_SHIFT) +#define SCT_OUTDIRC_SETCLR5_SHIFT (10) /* Bits 10-11: Set/clear operation on output 5 */ +#define SCT_OUTDIRC_SETCLR5_MASK (3 << SCT_OUTDIRC_SETCLR5_SHIFT) +# define SCT_OUTDIRC_SETCLR5(n) ((n) << SCT_OUTDIRC_SETCLR5_SHIFT) +#define SCT_OUTDIRC_SETCLR6_SHIFT (12) /* Bits 12-13: Set/clear operation on output 6 */ +#define SCT_OUTDIRC_SETCLR6_MASK (3 << SCT_OUTDIRC_SETCLR6_SHIFT) +# define SCT_OUTDIRC_SETCLR6(n) ((n) << SCT_OUTDIRC_SETCLR6_SHIFT) +#define SCT_OUTDIRC_SETCLR7_SHIFT (14) /* Bits 14-15: Set/clear operation on output 7 */ +#define SCT_OUTDIRC_SETCLR7_MASK (3 << SCT_OUTDIRC_SETCLR7_SHIFT) +# define SCT_OUTDIRC_SETCLR7(n) ((n) << SCT_OUTDIRC_SETCLR7_SHIFT) +#define SCT_OUTDIRC_SETCLR8_SHIFT (16) /* Bits 16-17: Set/clear operation on output 8 */ +#define SCT_OUTDIRC_SETCLR8_MASK (3 << SCT_OUTDIRC_SETCLR8_SHIFT) +# define SCT_OUTDIRC_SETCLR8(n) ((n) << SCT_OUTDIRC_SETCLR8_SHIFT) +#define SCT_OUTDIRC_SETCLR9_SHIFT (18) /* Bits 18-19: Set/clear operation on output 9 */ +#define SCT_OUTDIRC_SETCLR9_MASK (3 << SCT_OUTDIRC_SETCLR9_SHIFT) +# define SCT_OUTDIRC_SETCLR9(n) ((n) << SCT_OUTDIRC_SETCLR9_SHIFT) +#define SCT_OUTDIRC_SETCLR10_SHIFT (20) /* Bits 20-21: Set/clear operation on output 10 */ +#define SCT_OUTDIRC_SETCLR10_MASK (3 << SCT_OUTDIRC_SETCLR10_SHIFT) +# define SCT_OUTDIRC_SETCLR10(n) ((n) << SCT_OUTDIRC_SETCLR10_SHIFT) +#define SCT_OUTDIRC_SETCLR11_SHIFT (22) /* Bits 22-23: Set/clear operation on output 11 */ +#define SCT_OUTDIRC_SETCLR11_MASK (3 << SCT_OUTDIRC_SETCLR11_SHIFT) +# define SCT_OUTDIRC_SETCLR11(n) ((n) << SCT_OUTDIRC_SETCLR11_SHIFT) +#define SCT_OUTDIRC_SETCLR12_SHIFT (24) /* Bits 24-25: Set/clear operation on output 12 */ +#define SCT_OUTDIRC_SETCLR12_MASK (3 << SCT_OUTDIRC_SETCLR12_SHIFT) +# define SCT_OUTDIRC_SETCLR12(n) ((n) << SCT_OUTDIRC_SETCLR12_SHIFT) +#define SCT_OUTDIRC_SETCLR13_SHIFT (26) /* Bits 26-27: Set/clear operation on output 13 */ +#define SCT_OUTDIRC_SETCLR13_MASK (3 << SCT_OUTDIRC_SETCLR13_SHIFT) +# define SCT_OUTDIRC_SETCLR13(n) ((n) << SCT_OUTDIRC_SETCLR13_SHIFT) +#define SCT_OUTDIRC_SETCLR14_SHIFT (28) /* Bits 28-29: Set/clear operation on output 14 */ +#define SCT_OUTDIRC_SETCLR14_MASK (3 << SCT_OUTDIRC_SETCLR14_SHIFT) +# define SCT_OUTDIRC_SETCLR14(n) ((n) << SCT_OUTDIRC_SETCLR14_SHIFT) +#define SCT_OUTDIRC_SETCLR15_SHIFT (30) /* Bits 30-31: Set/clear operation on output 15 */ +#define SCT_OUTDIRC_SETCLR15_MASK (3 << SCT_OUTDIRC_SETCLR15_SHIFT) +# define SCT_OUTDIRC_SETCLR15(n) ((n) << SCT_OUTDIRC_SETCLR15_SHIFT) + +/* SCT conflict resolution register */ + +#define SCT_RES_NOCHANGE (0) /* No change */ +#define SCT_RES_SET (1) /* Set output */ +#define SCT_RES_CLEAR (1) /* Clear output */ +#define SCT_RES_TOGGLE (2) /* Toggle output */ + +#define SCT_RES_OUT_SHIFT(c) ((c) << 1) +#define SCT_RES_OUT_SHIFT(c) (3 << SCT_RES_OUT_SHIFT(c)) +# define SCT_RES_OUT(c,n) ((n) << SCT_RES_OUT_SHIFT(c)) + +#define SCT_RES_OUT0_SHIFT (0) /* Bits 0-1: Effect of simultaneous set and clear on output 0 */ +#define SCT_RES_OUT0_MASK (3 << SCT_RES_OUT0_SHIFT) +# define SCT_RES_OUT0(n) ((n) << SCT_RES_OUT0_SHIFT) +#define SCT_RES_OUT1_SHIFT (2) /* Bits 2-3: Effect of simultaneous set and clear on output 1 */ +#define SCT_RES_OUT1_MASK (3 << SCT_RES_OUT1_SHIFT) +# define SCT_RES_OUT1(n) ((n) << SCT_RES_OUT1_SHIFT) +#define SCT_RES_OUT2_SHIFT (4) /* Bits 4-5: Effect of simultaneous set and clear on output 2 */ +#define SCT_RES_OUT2_MASK (3 << SCT_RES_OUT2_SHIFT) +# define SCT_RES_OUT2(n) ((n) << SCT_RES_OUT2_SHIFT) +#define SCT_RES_OUT3_SHIFT (6) /* Bits 6-7: Effect of simultaneous set and clear on output 3 */ +#define SCT_RES_OUT3_MASK (3 << SCT_RES_OUT3_SHIFT) +# define SCT_RES_OUT3(n) ((n) << SCT_RES_OUT3_SHIFT) +#define SCT_RES_OUT4_SHIFT (8) /* Bits 8-9: Effect of simultaneous set and clear on output 4 */ +#define SCT_RES_OUT4_MASK (3 << SCT_RES_OUT4_SHIFT) +# define SCT_RES_OUT4(n) ((n) << SCT_RES_OUT4_SHIFT) +#define SCT_RES_OUT5_SHIFT (10) /* Bits 10-11: Effect of simultaneous set and clear on output 5 */ +#define SCT_RES_OUT5_MASK (3 << SCT_RES_OUT5_SHIFT) +# define SCT_RES_OUT5(n) ((n) << SCT_RES_OUT5_SHIFT) +#define SCT_RES_OUT6_SHIFT (12) /* Bits 12-13: Effect of simultaneous set and clear on output 6 */ +#define SCT_RES_OUT6_MASK (3 << SCT_RES_OUT6_SHIFT) +# define SCT_RES_OUT6(n) ((n) << SCT_RES_OUT6_SHIFT) +#define SCT_RES_OUT7_SHIFT (14) /* Bits 14-15: Effect of simultaneous set and clear on output 7 */ +#define SCT_RES_OUT7_MASK (3 << SCT_RES_OUT7_SHIFT) +# define SCT_RES_OUT7(n) ((n) << SCT_RES_OUT7_SHIFT) +#define SCT_RES_OUT8_SHIFT (16) /* Bits 16-17: Effect of simultaneous set and clear on output 8 */ +#define SCT_RES_OUT8_MASK (3 << SCT_RES_OUT8_SHIFT) +# define SCT_RES_OUT8(n) ((n) << SCT_RES_OUT8_SHIFT) +#define SCT_RES_OUT9_SHIFT (18) /* Bits 18-19: Effect of simultaneous set and clear on output 9 */ +#define SCT_RES_OUT9_MASK (3 << SCT_RES_OUT9_SHIFT) +# define SCT_RES_OUT9(n) ((n) << SCT_RES_OUT9_SHIFT) +#define SCT_RES_OUT10_SHIFT (20) /* Bits 20-21: Effect of simultaneous set and clear on output 10 */ +#define SCT_RES_OUT10_MASK (3 << SCT_RES_OUT10_SHIFT) +# define SCT_RES_OUT10(n) ((n) << SCT_RES_OUT10_SHIFT) +#define SCT_RES_OUT11_SHIFT (22) /* Bits 22-23: Effect of simultaneous set and clear on output 11 */ +#define SCT_RES_OUT11_MASK (3 << SCT_RES_OUT11_SHIFT) +# define SCT_RES_OUT11(n) ((n) << SCT_RES_OUT11_SHIFT) +#define SCT_RES_OUT12_SHIFT (24) /* Bits 24-25: Effect of simultaneous set and clear on output 12 */ +#define SCT_RES_OUT12_MASK (3 << SCT_RES_OUT12_SHIFT) +# define SCT_RES_OUT12(n) ((n) << SCT_RES_OUT12_SHIFT) +#define SCT_RES_OUT13_SHIFT (26) /* Bits 26-27: Effect of simultaneous set and clear on output 13 */ +#define SCT_RES_OUT13_MASK (3 << SCT_RES_OUT13_SHIFT) +# define SCT_RES_OUT13(n) ((n) << SCT_RES_OUT13_SHIFT) +#define SCT_RES_OUT14_SHIFT (28) /* Bits 28-29: Effect of simultaneous set and clear on output 14 */ +#define SCT_RES_OUT14_MASK (3 << SCT_RES_OUT14_SHIFT) +# define SCT_RES_OUT14(n) ((n) << SCT_RES_OUT14_SHIFT) +#define SCT_RES_OUT15_SHIFT (30) /* Bits 30-31: Effect of simultaneous set and clear on output 15 */ +#define SCT_RES_OUT15_MASK (3 << SCT_RES_OUT15_SHIFT) +# define SCT_RES_OUT15(n) ((n) << SCT_RES_OUT15_SHIFT) + +/* SCT DMA request 0/1 registers */ + +#define SCT_DMAREQ_DEV_SHIFT (0) /* Bits 0-15: Event n sets DMA request */ +#define SCT_DMAREQ_DEV_MASK (0xffff << SCT_DMAREQ_DEV_SHIFT) +# define SCT_DMAREQ_DEV(n) (1 << ((n) + SCT_DMAREQ_DEV_SHIFT)) + /* Bits 16-29: Reserved */ +#define SCT_DMAREQ_DRL (1 << 30) /* Bit 30: DMA request when counter reloaded */ +#define SCT_DMAREQ_DRQ (1 << 31) /* Bit 31: State of DMA Request */ + +/* SCT event enable register */ + +#define SCT_EVEN_SHIFT (0) /* Bits 0-15: Enable event n interrupts */ +#define SCT_EVEN_MASK (0xffff << SCT_EVEN_SHIFT) +# define SCT_EVEN(n) (1 << ((n) + SCT_EVEN_SHIFT)) + /* Bits 1-31: Reserved */ +/* SCT event flag register */ + +#define SCT_EVFLAG_SHIFT (0) /* Bits 0-15: Event n status */ +#define SCT_EVFLAG_MASK (0xffff << SCT_EVFLAG_SHIFT) +# define SCT_EVFLAG(n) (1 << ((n) + SCT_EVFLAG_SHIFT)) + /* Bits 1-31: Reserved */ +/* SCT conflict enable register */ + +#define SCT_CONEN_SHIFT (0) /* Bits 0-15: Event n conflict interrupts */ +#define SCT_CONEN_MASK (0xffff << SCT_CONEN_SHIFT) +# define SCT_CONEN(n) (1 << ((n) + SCT_CONEN_SHIFT)) + /* Bits 1-31: Reserved */ +/* SCT conflict flag register */ + +#define SCT_CONFLAG_DEV_SHIFT (0) /* Bits 0-15: No-change conflict on output n */ +#define SCT_CONFLAG_DEV_MASK (0xffff << SCT_CONFLAG_DEV_SHIFT) +# define SCT_CONFLAG_DEV(n) (1 << ((n) + SCT_CONFLAG_DEV_SHIFT)) + /* Bits 16-29: Reserved */ +#define SCT_CONFLAG_BUSERRU (1 << 30) /* Bit 30: Unified counter bus error */ +#define SCT_CONFLAG_BUSERRL (1 << 30) /* Bit 30: L counter bus error bus error */ +#define SCT_CONFLAG_BUSERRH (1 << 31) /* Bit 31: H counter bus error bus error */ + +/* SCT match value register of match channels 0-15 (all 32-bits for unified counter) */ +/* SCT match alias register of match channels 0-15 (all 32-bits for unified counter) */ + +#define SCT_MATCHL_SHIFT (0) /* Bits 0-15: L match value */ +#define SCT_MATCHL_MASK (0xffff << SCT_MATCHL_SHIFT) +#define SCT_MATCHH_SHIFT (16) /* Bits 16-31: H match value */ +#define SCT_MATCHH_MASK (0xffff << SCT_MATCHH_SHIFT) + +/* SCT high/low match value register of match channels 0-15 */ +/* SCT high/low match alias register of match channels 0-15 */ + +#define SCT_MATCH_SHIFT (0) /* Bits 0-15: match value */ +#define SCT_MATCH_MASK (0xffff << SCT_MATCH_SHIFT)) + +/* SCT match reload register of match channels 0-15 (all 32-bits for unified counter) */ +/* SCT match reload alias register of match channels 0-15 (all 32-bits for unified counter) */ + +#define SCT_RELOADL_SHIFT (0) /* Bits 0-15: L reload value */ +#define SCT_RELOADL_MASK (0xffff << SCT_RELOADL_SHIFT) +#define SCT_RELOADH_SHIFT (16) /* Bits 16-31: H reload value */ +#define SCT_RELOADH_MASK (0xffff << SCT_RELOADH_SHIFT) + +/* SCT high/low match reload register of match channels 0-15 */ +/* SCT high/low match reload alias register of match channels 0-15 */ + +#define SCT_RELOAD_SHIFT (0) /* Bits 0-15: Reload value */ +#define SCT_RELOAD_MASK (0xffff << SCT_RELOAD_SHIFT) + +/* SCT capture value register of capture channels 0-15 (all 32-bits for unified counter) */ +/* SCT capture alias register of capture channels 0-15 (all 32-bits for unified counter) */ + +#define SCT_CAPL_SHIFT (0) /* Bits 0-15: L capture value */ +#define SCT_CAPL_MASK (0xffff << SCT_CAPL_SHIFT) +#define SCT_CAPH_SHIFT (16) /* Bits 16-31: H capture value */ +#define SCT_CAPH_MASK (0xffff << SCT_CAPH_SHIFT) + +/* SCT high/low capture value register of capture channels 0-15 */ +/* SCT high/low capture alias register of capture channels 0-15 */ + +#define SCT_CAP_SHIFT (0) /* Bits 0-15: Capture value */ +#define SCT_CAP_MASK (0xffff << SCT_CAP_SHIFT) + +/* SCT capture control register of capture channels 0-15 (all 32-bits for unified counter) */ +/* SCT capture control alias register of capture channels 0-15 (all 32-bits for unified counter) */ + +#define SCT_CAPCONU(n) (1 << (n)) +#define SCT_CAPCONL_SHIFT (0) /* Bits 0-15: L capture controls */ +#define SCT_CAPCONL_MASK (0xffff << SCT_CAPCONL_SHIFT) +# define SCT_CAPCONL(n) (1 << ((n)+SCT_CAPCONL_SHIFT)) +#define SCT_CAPCONH_SHIFT (16) /* Bits 16-31: H capture controls */ +#define SCT_CAPCONH_MASK (0xffff << SCT_CAPCONH_SHIFT) +# define SCT_CAPCONH(n) (1 << ((n)+SCT_CAPCONH_SHIFT)) + +/* SCT high/low capture control register of capture channels 0-15 */ +/* SCT high/low capture control alias register of capture channels 0-15 */ + +#define SCT_CAPCON_SHIFT (0) /* Bits 0-15: Capture controls */ +#define SCT_CAPCON_MASK (0xffff << SCT_CAPCON_SHIFT) +# define SCT_CAPCON(n) (1 << ((n)+SCT_CAPCON_SHIFT)) + +/* SCT event state mask registers 0 to 15 */ + +#define SCT_EVSM(n) (1 << (n)) + +/* SCT event control registers 0 to 15 */ + +#define SCT_EVC_MATCHSEL_SHIFT (0) /* Bits 0-3: Selects Match register associated event */ +#define SCT_EVC_MATCHSEL_MASK (15 << SCT_EVC_MATCHSEL_SHIFT) +#define SCT_EVC_HEVENT (1 << 4) /* Bit 4: Select L/H counter */ +#define SCT_EVC_OUTSEL (1 << 5) /* Bit 5: Input/output select*/ +#define SCT_EVC_IOSEL_SHIFT (6) /* Bits 6-9: Selects input or output signal associated event */ +#define SCT_EVC_IOSEL_MASK (15 << SCT_EVC_IOSEL_SHIFT) +#define SCT_EVC_IOCOND_SHIFT (10) /* Bits 10-11: Selects I/O condition for event n */ +#define SCT_EVC_IOCOND_MASK (3 << SCT_EVC_IOCOND_SHIFT) +# define SCT_EVC_IOCOND_LOW (0 << SCT_EVC_IOCOND_SHIFT) +# define SCT_EVC_IOCOND_RISE (1 << SCT_EVC_IOCOND_SHIFT) +# define SCT_EVC_IOCOND_FALL (2 << SCT_EVC_IOCOND_SHIFT) +# define SCT_EVC_IOCOND_HIGH (3 << SCT_EVC_IOCOND_SHIFT) +#define SCT_EVC_COMBMODE_SHIFT (12) /* Bits 12-13: Match and I/O condition usage */ +#define SCT_EVC_COMBMODE_MASK (3 << SCT_EVC_COMBMODE_SHIFT) +# define SCT_EVC_COMBMODE_OR (0 << SCT_EVC_COMBMODE_SHIFT) +# define SCT_EVC_COMBMODE_MATCH (1 << SCT_EVC_COMBMODE_SHIFT) +# define SCT_EVC_COMBMODE_IO (2 << SCT_EVC_COMBMODE_SHIFT) +# define SCT_EVC_COMBMODE_AND (3 << SCT_EVC_COMBMODE_SHIFT) +#define SCT_EVC_STATELD (1 << 14) /* Bit 14: STATEV control */ +#define SCT_EVC_STATEV_SHIFT (15) /* Bits 15-19: State value */ +#define SCT_EVC_STATEV_MASK (31 << SCT_EVC_STATEV_SHIFT) + /* Bits 20-31: Reserved */ +/* SCT output set registers 0 to 15 */ + +#define SCT_OUTSET_SHIFT (0) /* Bits 0-15: Bit m selects event m to set output n */ +#define SCT_OUTSET_MASK (0xffff << SCT_OUTSET_SHIFT) +# define SCT_OUTSET_MASK(m) (1 << ((n)SCT_OUTSET_SHIFT)) + /* Bits 16-31: Reserved */ +/* SCT output clear registers 0 to 15 */ + +#define SCT_OUTCLR_SHIFT (0) /* Bits 0-15: Bit m selects event m to clear output n */ +#define SCT_OUTCLR_MASK (0xffff << SCT_OUTCLR_SHIFT) +# define SCT_OUTCLR_MASK(m) (1 << ((n)SCT_OUTCLR_SHIFT)) + /* Bits 16-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCT_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_scu.h b/arch/arm/src/lpc43xx/chip/lpc43_scu.h new file mode 100644 index 0000000000000000000000000000000000000000..a63fc35bde77a61f777b076e3050a0819fd76378 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_scu.h @@ -0,0 +1,435 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_scu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCU_SCU_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCU_SCU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +/* Pin Groups */ + +#define SPSP0 0 +#define SPSP1 1 +#define SPSP2 2 +#define SPSP3 3 +#define SPSP4 4 +#define SPSP5 5 +#define SPSP6 6 +#define SPSP7 7 +#define SPSP8 8 +#define SPSP9 9 +#define SPSP10 10 +#define SPSP11 11 +#define SPSP12 12 +#define SPSP13 13 +#define SPSP14 14 +#define SPSP15 15 + +#define LPC43_SCU_SFSP_OFFSET(p,n) (((p) << 7) | ((n) << 2)) +#define LPC43_SCU_SFSP0_OFFSET(n) (0x0000 | ((n) << 2)) +#define LPC43_SCU_SFSP1_OFFSET(n) (0x0080 | ((n) << 2)) +#define LPC43_SCU_SFSP2_OFFSET(n) (0x0100 | ((n) << 2)) +#define LPC43_SCU_SFSP3_OFFSET(n) (0x0180 | ((n) << 2)) +#define LPC43_SCU_SFSP4_OFFSET(n) (0x0200 | ((n) << 2)) +#define LPC43_SCU_SFSP5_OFFSET(n) (0x0280 | ((n) << 2)) +#define LPC43_SCU_SFSP6_OFFSET(n) (0x0300 | ((n) << 2)) +#define LPC43_SCU_SFSP7_OFFSET(n) (0x0380 | ((n) << 2)) +#define LPC43_SCU_SFSP8_OFFSET(n) (0x0400 | ((n) << 2)) +#define LPC43_SCU_SFSP9_OFFSET(n) (0x0480 | ((n) << 2)) +#define LPC43_SCU_SFSPA_OFFSET(n) (0x0500 | ((n) << 2)) +#define LPC43_SCU_SFSPB_OFFSET(n) (0x0580 | ((n) << 2)) +#define LPC43_SCU_SFSPC_OFFSET(n) (0x0600 | ((n) << 2)) +#define LPC43_SCU_SFSPD_OFFSET(n) (0x0680 | ((n) << 2)) +#define LPC43_SCU_SFSPE_OFFSET(n) (0x0700 | ((n) << 2)) +#define LPC43_SCU_SFSPF_OFFSET(n) (0x0780 | ((n) << 2)) + +/* CLKn pins */ + +#define SFSCLK0 0 +#define SFSCLK1 1 +#define SFSCLK2 2 +#define SFSCLK3 3 + +#define LPC43_SCU_SFSCLK_OFFSET(n) (0x0c00 | ((n) << 2)) +#define LPC43_SCU_SFSCLK0_OFFSET 0x0c00 +#define LPC43_SCU_SFSCLK1_OFFSET 0x0c04 +#define LPC43_SCU_SFSCLK2_OFFSET 0x0c08 +#define LPC43_SCU_SFSCLK3_OFFSET 0x0c0c + +/* USB1 USB1_DP/USB1_DM pins and I2C-bus open-drain pins */ + +#define LPC43_SCU_SFSUSB_OFFSET 0x0c80 +#define LPC43_SCU_SFSI2C0_OFFSET 0x0c84 + +/* ADC pin select registers */ + +#define ENAIO0 0 +#define ENAIO1 1 +#define ENAIO2 2 + +#define LPC43_SCU_ENAIO_OFFSET(n) (0x0c88 | ((n) << 2)) +#define LPC43_SCU_ENAIO0_OFFSET 0x0c88 +#define LPC43_SCU_ENAIO1_OFFSET 0x0c8c +#define LPC43_SCU_ENAIO2_OFFSET 0x0c90 + +/* EMC delay register */ + +#define LPC43_SCU_EMCDELAYCLK_OFFSET 0x0d00 + +/* Pin interrupt select registers */ + +#define PINTSEL0 0 +#define PINTSEL1 1 + +#define LPC43_SCU_PINTSEL_OFFSET(n) (0x0e00 | ((n) << 2)) +#define LPC43_SCU_PINTSEL0_OFFSET 0x0e00 +#define LPC43_SCU_PINTSEL1_OFFSET 0x0e04 + +/* Register Addresses *******************************************************************************/ + +/* Pin Groups */ + +#define LPC43_SCU_SFSP(p,n) (LPC43_SCU_BASE+LPC43_SCU_SFSP_OFFSET(p,n)) +#define LPC43_SCU_SFSP0(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP0_OFFSET(n)) +#define LPC43_SCU_SFSP1(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP1_OFFSET(n)) +#define LPC43_SCU_SFSP2(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP2_OFFSET(n)) +#define LPC43_SCU_SFSP3(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP3_OFFSET(n)) +#define LPC43_SCU_SFSP4(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP4_OFFSET(n)) +#define LPC43_SCU_SFSP5(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP5_OFFSET(n)) +#define LPC43_SCU_SFSP6(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP6_OFFSET(n)) +#define LPC43_SCU_SFSP7(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP7_OFFSET(n)) +#define LPC43_SCU_SFSP8(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP8_OFFSET(n)) +#define LPC43_SCU_SFSP9(n) (LPC43_SCU_BASE+LPC43_SCU_SFSP9_OFFSET(n)) +#define LPC43_SCU_SFSPA(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPA_OFFSET(n)) +#define LPC43_SCU_SFSPB(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPB_OFFSET(n)) +#define LPC43_SCU_SFSPC(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPC_OFFSET(n)) +#define LPC43_SCU_SFSPD(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPD_OFFSET(n)) +#define LPC43_SCU_SFSPE(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPE_OFFSET(n)) +#define LPC43_SCU_SFSPF(n) (LPC43_SCU_BASE+LPC43_SCU_SFSPF_OFFSET(n)) + +/* CLKn pins */ + +#define LPC43_SCU_SFSCLK(n) (LPC43_SCU_BASE+LPC43_SCU_SFSCLK_OFFSET(n)) +#define LPC43_SCU_SFSCLK0 (LPC43_SCU_BASE+LPC43_SCU_SFSCLK0_OFFSET) +#define LPC43_SCU_SFSCLK1 (LPC43_SCU_BASE+LPC43_SCU_SFSCLK1_OFFSET) +#define LPC43_SCU_SFSCLK2 (LPC43_SCU_BASE+LPC43_SCU_SFSCLK2_OFFSET) +#define LPC43_SCU_SFSCLK3 (LPC43_SCU_BASE+LPC43_SCU_SFSCLK3_OFFSET) + +/* USB1 USB1_DP/USB1_DM pins and I2C-bus open-drain pins */ + +#define LPC43_SCU_SFSUSB (LPC43_SCU_BASE+LPC43_SCU_SFSUSB_OFFSET) +#define LPC43_SCU_SFSI2C0 (LPC43_SCU_BASE+LPC43_SCU_SFSI2C0_OFFSET) + +/* ADC pin select registers */ + +#define LPC43_SCU_ENAIO(n) (LPC43_SCU_BASE+LPC43_SCU_ENAIO_OFFSET(n)) +#define LPC43_SCU_ENAIO0 (LPC43_SCU_BASE+LPC43_SCU_ENAIO0_OFFSET) +#define LPC43_SCU_ENAIO1 (LPC43_SCU_BASE+LPC43_SCU_ENAIO1_OFFSET) +#define LPC43_SCU_ENAIO2 (LPC43_SCU_BASE+LPC43_SCU_ENAIO2_OFFSET) + +/* EMC delay register */ + +#define LPC43_SCU_EMCDELAYCLK (LPC43_SCU_BASE+LPC43_SCU_EMCDELAYCLK_OFFSET) + +/* Pin interrupt select registers */ + +#define LPC43_SCU_PINTSEL(n) (LPC43_SCU_BASE+LPC43_SCU_PINTSEL_OFFSET(n)) +#define LPC43_SCU_PINTSEL0 (LPC43_SCU_BASE+LPC43_SCU_PINTSEL0_OFFSET) +#define LPC43_SCU_PINTSEL1 (LPC43_SCU_BASE+LPC43_SCU_PINTSEL1_OFFSET) + +/* Register Bit Definitions *************************************************************************/ +/* Common Pin configuration register bit settings */ + +#define SCU_PIN_MODE_SHIFT (0) /* Bits 0-2: Select pin function */ +#define SCU_PIN_MODE_MASK (7 << SCU_PIN_MODE_SHIFT) +# define SCU_PIN_MODE_FUNC(n) ((n) << SCU_PIN_MODE_SHIFT) +# define SCU_PIN_MODE_FUNC0 (0 << SCU_PIN_MODE_SHIFT) /* Function 0 (default) */ +# define SCU_PIN_MODE_FUNC1 (1 << SCU_PIN_MODE_SHIFT) /* Function 1 */ +# define SCU_PIN_MODE_FUNC2 (2 << SCU_PIN_MODE_SHIFT) /* Function 2 */ +# define SCU_PIN_MODE_FUNC3 (3 << SCU_PIN_MODE_SHIFT) /* Function 3 */ +# define SCU_PIN_MODE_FUNC4 (4 << SCU_PIN_MODE_SHIFT) /* Function 4 */ +# define SCU_PIN_MODE_FUNC5 (5 << SCU_PIN_MODE_SHIFT) /* Function 5 */ +# define SCU_PIN_MODE_FUNC6 (6 << SCU_PIN_MODE_SHIFT) /* Function 6 */ +# define SCU_PIN_MODE_FUNC7 (7 << SCU_PIN_MODE_SHIFT) /* Function 7 */ +#define SCU_PIN_EPD (1 << 3) /* Bit 3: Enable pull-down resistor at pad */ +#define SCU_PIN_EPUN (1 << 4) /* Bit 4: Disable pull-up resistor at pad */ + /* Bit 5: Usage varies with pin type */ +#define SCU_PIN_EZI (1 << 6) /* Bit 6: Input buffer enable */ +#define SCU_PIN_ZIF (1 << 7) /* Bit 7: Input glitch filter */ + /* Bits 8-9: Usage varies with pin type */ + /* Bits 10-31: Reserved */ +/* Pin configuration registers for normal-drive pins (only): + * + * P0_0 and P0_1 + * P1_0 to P1_16 and P1_18 to P1_20 + * P2_0 to P2_2 and P2_6 to P2_13 + * P3_0 to P3_2 and P3_4 to P3_8 + * P4_0 to P4_10 + * P5_0 to P5_7 + * P6_0 to P6_12 + * P7_0 to P7_7 + * P8_3 to P8_8 + * P9_0 to P9_6 + * PA_0 and PA_4 + * PB_0 to PB_6 + * PC_0 to PC_14 + * PE_0 to PE_15 + * PF_0 to PF_11 + */ + /* Bits 0-4: Same as common bit definitions */ +#define SCU_NDPIN_EHS (1 << 5) /* Bit 5: EHS Select Slew rate */ + /* Bits 6-31: Same as common bit definitions */ +/* Pin configuration registers for high-drive pins + * + * P1_17 + * P2_3 to P2_5 + * P8_0 to P8_2 + * PA_1 to PA_3 + */ + /* Bits 0-7: Same as common bit definitions */ +#define SCU_HDPIN_EHD_SHIFT (8) /* Bits 8-9: Select drive strength */ +#define SCU_HDPIN_EHD_MASK (3 << SCU_HDPIN_EHD_SHIFT) +# define SCU_HDPIN_EHD_NORMAL (0 << SCU_HDPIN_EHD_SHIFT) /* Normal-drive: 4 mA drive strength */ +# define SCU_HDPIN_EHD_MEDIUM (1 << SCU_HDPIN_EHD_SHIFT) /* Medium-drive: 8 mA drive strength */ +# define SCU_HDPIN_EHD_HIGH (2 << SCU_HDPIN_EHD_SHIFT) /* High-drive: 14 mA drive strength */ +# define SCU_HDPIN_EHD_ULTRA (3 << SCU_HDPIN_EHD_SHIFT) /* Ultra high-drive: 20 mA drive strength */ + /* Bits 10-31: Reserved */ +/* Pin configuration registers for high-speed pins + * + * P3_3 and pins CLK0 to CLK3 + */ + /* Bits 0-4: Same as common bit definitions */ +#define SCU_HSPIN_EHS (1 << 5) /* Bit 5: EHS Select Slew rate */ + /* Bits 6-31: Same as common bit definitions */ +/* Pin configuration register for USB1 pins USB1_DP/USB1_DM */ + +#define SCU_SFSUSB_AIM (1 << 0) /* Bit 0: Differential data input AIP/AIM */ +#define SCU_SFSUSB_ESEA (1 << 1) /* Bit 1: Control signal for differential input or single input */ +#define SCU_SFSUSB_EPD (1 << 2) /* Bit 2: Enable pull-down connect */ + /* Bit 3: Reserved */ +#define SCU_SFSUSB_EPWR (1 << 4) /* Bit 4: Power mode */ +#define SCU_SFSUSB_VBUS (1 << 5) /* Bit 5: Enable the vbus_valid signal */ + /* Bits 6-31: Reserved */ +/* Pin configuration register for open-drain I2C-bus pins */ + +#define SCU_SFSI2C0_SCL_EFP (1 << 0) /* Bit 0: Select input glitch filter time constant for the SCL pin */ + /* Bit 1: Reserved */ +#define SCU_SFSI2C0_SCL_EHD (1 << 2) /* Bit 2: Select I2C mode for the SCL pin */ +#define SCU_SFSI2C0_SCL_EZI (1 << 3) /* Bit 3: Enable the input receiver for the SCL pin */ + /* Bits 4-6: Reserved */ +#define SCU_SFSI2C0_SCL_ZIF (1 << 7) /* Bit 7: Enable or disable input glitch filter for the SCL pin */ +#define SCU_SFSI2C0_SDA_EFP (1 << 8) /* Bit 8: Select input glitch filter time constant for the SDA pin */ + /* Bit 9: Reserved */ +#define SCU_SFSI2C0_SDA_EHD (1 << 10) /* Bit 10: Select I2C mode for the SDA pin */ +#define SCU_SFSI2C0_SDA_EZI (1 << 11) /* Bit 11: Enable the input receiver for the SDA pin */ + /* Bits 12-14: Reserved */ +#define SCU_SFSI2C0_SDA_ZIF (1 << 15) /* Bit 15: Enable or disable input glitch filter for the SDA pin */ + /* Bits 16-31: Reserved */ +/* ADC0 function select register. The following pins are controlled by the ENAIO0 register: + * + * Pin ADC function ENAIO0 register bit + * P4_3 ADC0_0 0 + * P4_1 ADC0_1 1 + * PF_8 ADC0_2 2 + * P7_5 ADC0_3 3 + * P7_4 ADC0_4 4 + * PF_10 ADC0_5 5 + * PB_6 ADC0_6 6 + */ + +#define SCU_ENAI00_ADC0(n) (1 << (n)) +#define SCU_ENAI00_ADC0_0 (1 << 0) /* Select ADC0_0 */ +#define SCU_ENAI00_ADC0_1 (1 << 1) /* Select ADC0_1 */ +#define SCU_ENAI00_ADC0_2 (1 << 2) /* Select ADC0_2 */ +#define SCU_ENAI00_ADC0_3 (1 << 3) /* Select ADC0_3 */ +#define SCU_ENAI00_ADC0_4 (1 << 4) /* Select ADC0_4 */ +#define SCU_ENAI00_ADC0_5 (1 << 5) /* Select ADC0_5 */ +#define SCU_ENAI00_ADC0_6 (1 << 6) /* Select ADC0_6 */ + +/* ADC1 function select register. The following pins are controlled by the ENAIO1 register: + * + * Pin ADC function ENAIO0 register bit + * PC_3 ADC1_0 0 + * PC_0 ADC1_1 1 + * PF_9 ADC1_2 2 + * PF_6 ADC1_3 3 + * PF_5 ADC1_4 4 + * PF_11 ADC1_5 5 + * P7_7 ADC1_6 6 + * PF_7 ADC1_7 7 + */ + +#define SCU_ENAI01_ADC1(n) (1 << (n)) +#define SCU_ENAI01_ADC1_0 (1 << 0) /* Select ADC1_0 */ +#define SCU_ENAI01_ADC1_1 (1 << 1) /* Select ADC1_1 */ +#define SCU_ENAI01_ADC1_2 (1 << 2) /* Select ADC1_2 */ +#define SCU_ENAI01_ADC1_3 (1 << 3) /* Select ADC1_3 */ +#define SCU_ENAI01_ADC1_4 (1 << 4) /* Select ADC1_4 */ +#define SCU_ENAI01_ADC1_5 (1 << 5) /* Select ADC1_5 */ +#define SCU_ENAI01_ADC1_6 (1 << 6) /* Select ADC1_6 */ +#define SCU_ENAI01_ADC1_7 (1 << 7) /* Select ADC1_7 */ + +/* Analog function select register. The following pins are controlled by the ENAIO2 register: + * + * Pin ADC function ENAIO0 register bit + * P4_4 DAC 0 + * PF_7 BG (band gap output) 4 + */ + +#define SCU_ENAI02_DAC (1 << 0) /* Select DAC */ +#define SCU_ENAI02_BG (1 << 4) /* Select band gap output */ + +/* EMC clock delay register. The value 0x1111 corresponds to about 0.5 ns of delay */ + +#define SCU_EMCDELAYCLK_SHIFT (0) /* Bits 0-15: EMC_CLKn SDRAM clock output delay */ +#define SCU_EMCDELAYCLK_MASK (0xffff << SCU_EMCDELAYCLK_SHIFT) +# define SCU_EMCDELAYCLK(n) ((n) << SCU_EMCDELAYCLK_SHIFT) /* 0=no delay, N*0x1111 = N*0.5 ns delay */ + /* Bits 16-31: Reserved */ +/* Pin interrupt select register 0 */ + +#define SCU_GPIO_PORT0 0 +#define SCU_GPIO_PORT1 1 +#define SCU_GPIO_PORT2 2 +#define SCU_GPIO_PORT3 3 +#define SCU_GPIO_PORT4 4 +#define SCU_GPIO_PORT5 5 +#define SCU_GPIO_PORT6 6 +#define SCU_GPIO_PORT7 7 + +#define SCU_GPIO_PIN0 0 +#define SCU_GPIO_PIN1 1 +#define SCU_GPIO_PIN2 2 +#define SCU_GPIO_PIN3 3 +#define SCU_GPIO_PIN4 4 +#define SCU_GPIO_PIN5 5 +#define SCU_GPIO_PIN6 6 +#define SCU_GPIO_PIN7 7 +#define SCU_GPIO_PIN8 8 +#define SCU_GPIO_PIN9 9 +#define SCU_GPIO_PIN10 10 +#define SCU_GPIO_PIN11 11 +#define SCU_GPIO_PIN12 12 +#define SCU_GPIO_PIN13 13 +#define SCU_GPIO_PIN14 14 +#define SCU_GPIO_PIN15 15 +#define SCU_GPIO_PIN16 16 +#define SCU_GPIO_PIN17 17 +#define SCU_GPIO_PIN18 18 +#define SCU_GPIO_PIN19 19 +#define SCU_GPIO_PIN20 20 +#define SCU_GPIO_PIN21 21 +#define SCU_GPIO_PIN22 22 +#define SCU_GPIO_PIN23 23 +#define SCU_GPIO_PIN24 24 +#define SCU_GPIO_PIN25 25 +#define SCU_GPIO_PIN26 26 +#define SCU_GPIO_PIN27 27 +#define SCU_GPIO_PIN28 28 +#define SCU_GPIO_PIN29 29 +#define SCU_GPIO_PIN30 30 +#define SCU_GPIO_PIN31 31 + +#define SCU_PINTSEL0_SHIFT(n) ((n) << 3) +#define SCU_PINTSEL0_MASK(n) (0xff << SCU_PINTSEL0_SHIFT(n)) +#define SCU_PINTSEL0_INTPIN_SHIFT(n) ((n) << 3) +#define SCU_PINTSEL0_INTPIN_MASK(n) (31 << SCU_PINTSEL0_INTPIN_SHIFT(n)) +#define SCU_PINTSEL0_PORTSEL_SHIFT(n) (((n) << 3) + 5) +#define SCU_PINTSEL0_PORTSEL_MASK(n) (7 << SCU_PINTSEL0_PORTSEL_SHIFT(n)) + +#define SCU_PINTSEL0_INTPIN0_SHIFT (0) /* Bits 0-4: Pint interrupt 0 */ +#define SCU_PINTSEL0_INTPIN0_MASK (31 << SCU_PINTSEL0_INTPIN0_SHIFT) +#define SCU_PINTSEL0_PORTSEL0_SHIFT (5) /* Bits 5-7: Pin interrupt 0 */ +#define SCU_PINTSEL0_PORTSEL0_MASK (7 << SCU_PINTSEL0_PORTSEL0_SHIFT) +#define SCU_PINTSEL0_INTPIN1_SHIFT (8) /* Bits 8-12: Pint interrupt 1 */ +#define SCU_PINTSEL0_INTPIN1_MASK (31 << SCU_PINTSEL0_INTPIN1_SHIFT) +#define SCU_PINTSEL0_PORTSEL1_SHIFT (13) /* Bits 13-15: Pin interrupt 1 */ +#define SCU_PINTSEL0_PORTSEL1_MASK (7 << SCU_PINTSEL0_PORTSEL1_SHIFT) +#define SCU_PINTSEL0_INTPIN2_SHIFT (16) /* Bits 16-20: Pint interrupt 2 */ +#define SCU_PINTSEL0_INTPIN2_MASK (31 << SCU_PINTSEL0_INTPIN2_SHIFT) +#define SCU_PINTSEL0_PORTSEL2_SHIFT (21) /* Bits 21-23: Pin interrupt 2 */ +#define SCU_PINTSEL0_PORTSEL2_MASK (7 << SCU_PINTSEL0_PORTSEL2_SHIFT) +#define SCU_PINTSEL0_INTPIN3_SHIFT (24) /* Bits 24-28: Pint interrupt 3 */ +#define SCU_PINTSEL0_INTPIN3_MASK (31 << SCU_PINTSEL0_INTPIN3_SHIFT) +#define SCU_PINTSEL0_PORTSEL3_SHIFT (29) /* Bits 29-31: Pin interrupt 3 */ +#define SCU_PINTSEL0_PORTSEL3_MASK (7 << SCU_PINTSEL0_PORTSEL3_SHIFT) + +/* Pin interrupt select register 1 */ + +#define SCU_PINTSEL1_SHIFT(n) (((n) - 4) << 3) +#define SCU_PINTSEL1_MASK(n) (0xff << SCU_PINTSEL1_SHIFT(n)) +#define SCU_PINTSEL1_INTPIN_SHIFT(n) (((n) - 4) << 3) +#define SCU_PINTSEL1_INTPIN_MASK(n) (31 << SCU_PINTSEL0_INTPIN_SHIFT(n)) +#define SCU_PINTSEL1_PORTSEL_SHIFT(n) ((((n) - 4) << 3) + 5) +#define SCU_PINTSEL1_PORTSEL_MASK(n) (7 << SCU_PINTSEL0_PORTSEL_SHIFT(n)) + +#define SCU_PINTSEL1_INTPIN4_SHIFT (0) /* Bits 0-4: Pint interrupt 4 */ +#define SCU_PINTSEL1_INTPIN4_MASK (31 << SCU_PINTSEL1_INTPIN4_SHIFT) +#define SCU_PINTSEL1_PORTSEL4_SHIFT (5) /* Bits 5-7: Pin interrupt 4 */ +#define SCU_PINTSEL1_PORTSEL4_MASK (7 << SCU_PINTSEL1_PORTSEL4_SHIFT) +#define SCU_PINTSEL1_INTPIN5_SHIFT (8) /* Bits 8-12: Pint interrupt 5 */ +#define SCU_PINTSEL1_INTPIN5_MASK (31 << SCU_PINTSEL1_INTPIN5_SHIFT) +#define SCU_PINTSEL1_PORTSEL5_SHIFT (13) /* Bits 13-15: Pin interrupt 5 */ +#define SCU_PINTSEL1_PORTSEL5_MASK (7 << SCU_PINTSEL1_PORTSEL5_SHIFT) +#define SCU_PINTSEL1_INTPIN6_SHIFT (16) /* Bits 16-20: Pint interrupt 6 */ +#define SCU_PINTSEL1_INTPIN6_MASK (31 << SCU_PINTSEL1_INTPIN6_SHIFT) +#define SCU_PINTSEL1_PORTSEL6_SHIFT (21) /* Bits 21-23: Pin interrupt 6 */ +#define SCU_PINTSEL1_PORTSEL6_MASK (7 << SCU_PINTSEL1_PORTSEL6_SHIFT) +#define SCU_PINTSEL1_INTPIN7_SHIFT (24) /* Bits 24-28: Pint interrupt 7 */ +#define SCU_PINTSEL1_INTPIN7_MASK (31 << SCU_PINTSEL1_INTPIN7_SHIFT) +#define SCU_PINTSEL1_PORTSEL7_SHIFT (29) /* Bits 29-31: Pin interrupt 7 */ +#define SCU_PINTSEL1_PORTSEL7_MASK (7 << SCU_PINTSEL1_PORTSEL7_SHIFT) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SCU_SCU_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h b/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h new file mode 100644 index 0000000000000000000000000000000000000000..1236d82f31c886e49a05955fb308388b999cd12f --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_sdmmc.h @@ -0,0 +1,391 @@ +/************************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_sdmmc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SDMMC_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SDMMC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* MCI register offsets (with respect to the MCI base) ******************************************/ + +#define LPC43_SDMMC_CTRL_OFFSET 0x0000 /* Control register */ +#define LPC43_SDMMC_PWREN_OFFSET 0x0004 /* Power Enable Register */ +#define LPC43_SDMMC_CLKDIV_OFFSET 0x0008 /* Clock-divider register */ +#define LPC43_SDMMC_CLKSRC_OFFSET 0x000c /* Clock-source register */ +#define LPC43_SDMMC_CLKENA_OFFSET 0x0010 /* Clock-enable register */ +#define LPC43_SDMMC_TMOUT_OFFSET 0x0014 /* Time-out register */ +#define LPC43_SDMMC_CTYPE_OFFSET 0x0018 /* Card-type register */ +#define LPC43_SDMMC_BLKSIZ_OFFSET 0x001c /* Block-size register */ +#define LPC43_SDMMC_BYTCNT_OFFSET 0x0020 /* Byte-count register */ +#define LPC43_SDMMC_INTMASK_OFFSET 0x0024 /* Interrupt-mask register */ +#define LPC43_SDMMC_CMDARG_OFFSET 0x0028 /* Command-argument register */ +#define LPC43_SDMMC_CMD_OFFSET 0x002c /* Command register */ +#define LPC43_SDMMC_RESP0_OFFSET 0x0030 /* Response-0 register */ +#define LPC43_SDMMC_RESP1_OFFSET 0x0034 /* Response-1 register */ +#define LPC43_SDMMC_RESP2_OFFSET 0x0038 /* Response-2 register */ +#define LPC43_SDMMC_RESP3_OFFSET 0x003c /* Response-3 register */ +#define LPC43_SDMMC_MINTSTS_OFFSET 0x0040 /* Masked interrupt-status register */ +#define LPC43_SDMMC_RINTSTS_OFFSET 0x0044 /* Raw interrupt-status register */ +#define LPC43_SDMMC_STATUS_OFFSET 0x0048 /* Status register */ +#define LPC43_SDMMC_FIFOTH_OFFSET 0x004c /* FIFO threshold register */ +#define LPC43_SDMMC_CDETECT_OFFSET 0x0050 /* Card-detect register value */ +#define LPC43_SDMMC_WRTPRT_OFFSET 0x0054 /* Write-protect register */ + /* 0x58: Reserved */ +#define LPC43_SDMMC_TCBCNT_OFFSET 0x005c /* Transferred CIU card byte count */ +#define LPC43_SDMMC_TBBCNT_OFFSET 0x0060 /* Transferred cpu/DMA to/from BIU-FIFO byte count */ +#define LPC43_SDMMC_DEBNCE_OFFSET 0x0064 /* Debounce count register */ + /* 0x0068-0x0074: Reserved */ +#define LPC43_SDMMC_RSTN_OFFSET 0x0078 /* Hardware Reset */ +#define LPC43_SDMMC_BMOD_OFFSET 0x0080 /* Bus Mode Register */ +#define LPC43_SDMMC_PLDMND_OFFSET 0x0084 /* Poll Demand Register */ +#define LPC43_SDMMC_DBADDR_OFFSET 0x0088 /* Descriptor List Base Address Register */ +#define LPC43_SDMMC_IDSTS_OFFSET 0x008c /* Internal DMAC Status Register */ +#define LPC43_SDMMC_IDINTEN_OFFSET 0x0090 /* Internal DMAC Interrupt Enable Register */ +#define LPC43_SDMMC_DSCADDR_OFFSET 0x0094 /* Current Host Descriptor Address Register */ +#define LPC43_SDMMC_BUFADDR_OFFSET 0x0098 /* Current Buffer Descriptor Address Register */ + /* 0x009c-0x00ff: Reserved */ +#define LPC43_SDMMC_DATA_OFFSET 0x0100 /* Data FIFO read/write (>=) */ + +/* MCI register (virtual) addresses *************************************************************/ + +#define LPC43_SDMMC_CTRL (LPC43_SDMMC_BASE+LPC43_SDMMC_CTRL_OFFSET) +#define LPC43_SDMMC_PWREN (LPC43_SDMMC_BASE+LPC43_SDMMC_PWREN_OFFSET) +#define LPC43_SDMMC_CLKDIV (LPC43_SDMMC_BASE+LPC43_SDMMC_CLKDIV_OFFSET) +#define LPC43_SDMMC_CLKSRC (LPC43_SDMMC_BASE+LPC43_SDMMC_CLKSRC_OFFSET) +#define LPC43_SDMMC_CLKENA (LPC43_SDMMC_BASE+LPC43_SDMMC_CLKENA_OFFSET) +#define LPC43_SDMMC_TMOUT (LPC43_SDMMC_BASE+LPC43_SDMMC_TMOUT_OFFSET) +#define LPC43_SDMMC_CTYPE (LPC43_SDMMC_BASE+LPC43_SDMMC_CTYPE_OFFSET) +#define LPC43_SDMMC_BLKSIZ (LPC43_SDMMC_BASE+LPC43_SDMMC_BLKSIZ_OFFSET) +#define LPC43_SDMMC_BYTCNT (LPC43_SDMMC_BASE+LPC43_SDMMC_BYTCNT_OFFSET) +#define LPC43_SDMMC_INTMASK (LPC43_SDMMC_BASE+LPC43_SDMMC_INTMASK_OFFSET) +#define LPC43_SDMMC_CMDARG (LPC43_SDMMC_BASE+LPC43_SDMMC_CMDARG_OFFSET) +#define LPC43_SDMMC_CMD (LPC43_SDMMC_BASE+LPC43_SDMMC_CMD_OFFSET) +#define LPC43_SDMMC_RESP0 (LPC43_SDMMC_BASE+LPC43_SDMMC_RESP0_OFFSET) +#define LPC43_SDMMC_RESP1 (LPC43_SDMMC_BASE+LPC43_SDMMC_RESP1_OFFSET) +#define LPC43_SDMMC_RESP2 (LPC43_SDMMC_BASE+LPC43_SDMMC_RESP2_OFFSET) +#define LPC43_SDMMC_RESP3 (LPC43_SDMMC_BASE+LPC43_SDMMC_RESP3_OFFSET) +#define LPC43_SDMMC_MINTSTS (LPC43_SDMMC_BASE+LPC43_SDMMC_MINTSTS_OFFSET) +#define LPC43_SDMMC_RINTSTS (LPC43_SDMMC_BASE+LPC43_SDMMC_RINTSTS_OFFSET) +#define LPC43_SDMMC_STATUS (LPC43_SDMMC_BASE+LPC43_SDMMC_STATUS_OFFSET) +#define LPC43_SDMMC_FIFOTH (LPC43_SDMMC_BASE+LPC43_SDMMC_FIFOTH_OFFSET) +#define LPC43_SDMMC_CDETECT (LPC43_SDMMC_BASE+LPC43_SDMMC_CDETECT_OFFSET) +#define LPC43_SDMMC_WRTPRT (LPC43_SDMMC_BASE+LPC43_SDMMC_WRTPRT_OFFSET) +#define LPC43_SDMMC_TCBCNT (LPC43_SDMMC_BASE+LPC43_SDMMC_TCBCNT_OFFSET) +#define LPC43_SDMMC_TBBCNT (LPC43_SDMMC_BASE+LPC43_SDMMC_TBBCNT_OFFSET) +#define LPC43_SDMMC_TBBCNT (LPC43_SDMMC_BASE+LPC43_SDMMC_TBBCNT_OFFSET) +#define LPC43_SDMMC_DEBNCE (LPC43_SDMMC_BASE+LPC43_SDMMC_DEBNCE_OFFSET) +#define LPC43_SDMMC_DEBNCE (LPC43_SDMMC_BASE+LPC43_SDMMC_DEBNCE_OFFSET) +#define LPC43_SDMMC_RSTN (LPC43_SDMMC_BASE+LPC43_SDMMC_RSTN_OFFSET) +#define LPC43_SDMMC_BMOD (LPC43_SDMMC_BASE+LPC43_SDMMC_BMOD_OFFSET) +#define LPC43_SDMMC_PLDMND (LPC43_SDMMC_BASE+LPC43_SDMMC_PLDMND_OFFSET) +#define LPC43_SDMMC_DBADDR (LPC43_SDMMC_BASE+LPC43_SDMMC_DBADDR_OFFSET) +#define LPC43_SDMMC_IDSTS (LPC43_SDMMC_BASE+LPC43_SDMMC_IDSTS_OFFSET) +#define LPC43_SDMMC_IDINTEN (LPC43_SDMMC_BASE+LPC43_SDMMC_IDINTEN_OFFSET) +#define LPC43_SDMMC_DSCADDR (LPC43_SDMMC_BASE+LPC43_SDMMC_DSCADDR_OFFSET) +#define LPC43_SDMMC_BUFADDR (LPC43_SDMMC_BASE+LPC43_SDMMC_BUFADDR_OFFSET) +#define LPC43_SDMMC_DATA (LPC43_SDMMC_BASE+LPC43_SDMMC_DATA_OFFSET) + +/* MCI register bit definitions *****************************************************************/ + +/* Control register CTRL */ + +#define SDMMC_CTRL_CNTLRRESET (1 << 0) /* Bit 0: Reset Module controller */ +#define SDMMC_CTRL_FIFORESET (1 << 1) /* Bit 1: Reset to data FIFO To reset FIFO pointers */ +#define SDMMC_CTRL_DMARESET (1 << 2) /* Bit 2: Reset internal DMA interface control logic */ + /* Bit 3: Reserved */ +#define SDMMC_CTRL_INTENABLE (1 << 4) /* Bit 4: Enable interrupts */ + /* Bit 5: Reserved */ +#define SDMMC_CTRL_READWAIT (1 << 6) /* Bit 6: Assert read wait */ +#define SDMMC_CTRL_SENDIRQRESP (1 << 7) /* Bit 7: Send auto IRQ response */ +#define SDMMC_CTRL_ABORTREAD (1 << 8) /* Bit 8: Reset data state-machine (suspend sequence) */ +#define SDMMC_CTRL_SENDCCSD (1 << 9) /* Bit 9: Send CCSD to CE-ATA device */ +#define SDMMC_CTRL_AUTOSTOP (1 << 10) /* Bit 10: Send STOP after CCSD to CE-ATA device */ +#define SDMMC_CTRL_CEATAINT (1 << 11) /* Bit 11: CE-ATA device interrupts enabled */ + /* Bits 12-15: Reserved */ +#define SDMMC_CTRL_CDVA0 (1 << 16) /* Bit 16: Controls SD_VOLT0 pin */ +#define SDMMC_CTRL_CDVA0 (1 << 17) /* Bit 17: Controls SD_VOLT1 pin */ +#define SDMMC_CTRL_CDVA0 (1 << 18) /* Bit 18: Controls SD_VOLT2 pin */ + /* Bits 19-23: Reserved */ +#define SDMMC_CTRL_INTDMA (1 << 25) /* Bit 24: SD/MMC DMA use */ + /* Bits 26-31: Reserved */ +/* Power Enable Register (PWREN) */ + +#define SDMMC_PWREN (1 << 0) /* Bit 0: Power on/off switch */ + /* Bits 1-31: Reserved */ +/* Clock divider register CLKDIV */ + +#define SDMMC_CLKDIV0_SHIFT (0) /* Bits 0-7: Clock divider 0 value */ +#define SDMMC_CLKDIV0_MASK (255 << SDMMC_CLKDIV0_SHIFT) +#define SDMMC_CLKDIV1_SHIFT (8) /* Bits 8-15: Clock divider 1 value */ +#define SDMMC_CLKDIV1_MASK (255 << SDMMC_CLKDIV1_SHIFT) +#define SDMMC_CLKDIV2_SHIFT (16) /* Bits 16-23: Clock divider 2 value */ +#define SDMMC_CLKDIV2_MASK (255 << SDMMC_CLKDIV2_SHIFT) +#define SDMMC_CLKDIV3_SHIFT (24) /* Bits 24-31: Clock divider 3 value */ +#define SDMMC_CLKDIV3_MASK (255 << SDMMC_CLKDIV3_SHIFT) + +/* Clock source register CLKSRC */ + +#define SDMMC_CLKSRC_SHIFT (0) /* Bits 0-1: Clock divider source for SD card */ +#define SDMMC_CLKSRC_MASK (3 << SDMMC_CLKSRC_SHIFT) +# define SDMMC_CLKSRC_CLKDIV0 (0 << SDMMC_CLKSRC_SHIFT) /* Clock divider 0 */ +# define SDMMC_CLKSRC_CLKDIV1 (1 << SDMMC_CLKSRC_SHIFT) /* Clock divider 1 */ +# define SDMMC_CLKSRC_CLKDIV2 (2 << SDMMC_CLKSRC_SHIFT) /* Clock divider 2 */ +# define SDMMC_CLKSRC_CLKDIV3 (3 << SDMMC_CLKSRC_SHIFT) /* Clock divider 3 */ + /* Bits 2-31: Reserved */ +/* Clock enable register CLKENA */ + +#define SDMMC_CLKENA_EMABLE (1 << 0) /* Bit 0: Clock enable */ + /* Bits 1-15: Reserved */ +#define SDMMC_CLKENA_LOWPOWER (1 << 16) /* Bit 16: Low-power mode */ + /* Bits 17-31: Reserved */ +/*Timeout register TMOUT */ + +#define SDMMC_TMOUT_RESPONSE_SHIFT (0) /* Bits 0-7: Response timeout value */ +#define SDMMC_TMOUT_RESPONSE_MASK (255 << SDMMC_TMOUT_RESPONSE_SHIFT) +#define SDMMC_TMOUT_DATA_SHIFT (8) /* Bits 8-31: Data Read Timeout value */ +#define SDMMC_TMOUT_DATA_MASK (0x00ffffff << SDMMC_TMOUT_DATA_SHIFT) + +/* Card type register CTYPE */ + +#define SDMMC_CTYPE_WIDTH4 (1 << 0) /* Bit 0: 4-bit mode */ + /* Bits 1-15: Reserved */ +#define SDMMC_CTYPE_WIDTH8 (1 << 16) /* Bit 16: 8-bit mode */ + /* Bits 17-31: Reserved */ +/* Blocksize register BLKSIZ */ + +#define SDMMC_BLKSIZ_SHIFT (0) /* Bits 0-15: Block size */ +#define SDMMC_BLKSIZ_MASK (0xffff << SDMMC_BLKSIZ_SHIFT) + /* Bits 16-31: Reserved */ +/* Interrupt mask register INTMASK + * Masked interrupt status register MINTSTS + * Raw interrupt status register RINTSTS + */ + +#define SDMMC_INT_CDET (1 << 0) /* Bit 0: Card detect */ +#define SDMMC_INT_RE (1 << 1) /* Bit 1: Response error */ +#define SDMMC_INT_CDONE (1 << 2) /* Bit 2: Command done */ +#define SDMMC_INT_DTO (1 << 3) /* Bit 3: Data transfer over */ +#define SDMMC_INT_TXDR (1 << 4) /* Bit 4: Transmit FIFO data request */ +#define SDMMC_INT_RXDR (1 << 5) /* Bit 5: Receive FIFO data request */ +#define SDMMC_INT_RCRC (1 << 6) /* Bit 6: Response CRC error */ +#define SDMMC_INT_DCRC (1 << 7) /* Bit 7: Data CRC error */ +#define SDMMC_INT_RTO (1 << 8) /* Bit 8: Response timeout */ +#define SDMMC_INT_DRTO (1 << 9) /* Bit 9: Data read timeout */ +#define SDMMC_INT_HTO (1 << 10) /* Bit 10: Data starvation-by-cpu timeout */ +#define SDMMC_INT_FRUN (1 << 11) /* Bit 11: FIFO underrun/overrun error */ +#define SDMMC_INT_HLE (1 << 12) /* Bit 12: Hardware locked write error */ +#define SDMMC_INT_SBE (1 << 13) /* Bit 13: Start-bit error */ +#define SDMMC_INT_ACD (1 << 14) /* Bit 14: Auto command done */ +#define SDMMC_INT_EBE (1 << 15) /* Bit 15: End-bit error (read)/Write no CRC */ +#define SDMMC_INT_SDIO (1 << 16) /* Bit 16: Mask SDIO interrupt */ + /* Bits 17-31: Reserved */ +#define SDMMC_INT_ALL (0x1ffff) + +/* Command register CMD */ + +#define SDMMC_CMD_CMDINDEX_SHIFT (0) /* Bits 0-5: 5:0 Command index */ +#define SDMMC_CMD_CMDINDEX_MASK (63 << SDMMC_CMD_CMDINDEX_SHIFT) +#define SDMMC_CMD_RESPONSE (1 << 6) /* Bit 6: Response expected from card */ +#define SDMMC_CMD_LONGRESP (1 << 7) /* Bit 7: Long response expected from card */ +#define SDMMC_CMD_RESPCRC (1 << 8) /* Bit 8: Check response CRC */ +#define SDMMC_CMD_DATAXFREXPTD (1 << 9) /* Bit 9: Data transfer expected (read/write) */ +#define SDMMC_CMD_WRITE (1 << 10) /* Bit 10: Write to card */ +#define SDMMC_CMD_XFRMODE (1 << 11) /* Bit 11: Stream data transfer command */ +#define SDMMC_CMD_AUTOSTOP (1 << 12) /* Bit 12: Send stop command at end of data transfer */ +#define SDMMC_CMD_WAITPREV (1 << 13) /* Bit 13: Wait previous transfer complete before sending */ +#define SDMMC_CMD_STOPABORT (1 << 14) /* Bit 14: Stop current data transfer */ +#define SDMMC_CMD_SENDINIT (1 << 15) /* Bit 15: Send initialization sequence before command */ + /* Bits 16-20: Reserved */ +#define SDMMC_CMD_UPDCLOCK (1 << 21) /* Bit 21: Update clock register value (no command) */ +#define SDMMC_CMD_READCEATA (1 << 22) /* Bit 22: Performing read access on CE-ATA device */ +#define SDMMC_CMD_CCSEXPTD (1 << 23) /* Bit 23: Expect command completion from CE-ATA device */ +#define SDMMC_CMD_ENABOOT (1 << 24) /* Bit 24: Enable Boot */ +#define SDMMC_CMD_BACKEXPTED (1 << 25) /* Bit 25: Expect Boot Acknowledge */ +#define SDMMC_CMD_DISBOOT (1 << 26) /* Bit 26: Disable Boot */ +#define SDMMC_CMD_BOOTMODE (1 << 27) /* Bit 27: Boot Mode */ +#define SDMMC_CMD_VSWITCH (1 << 28) /* Bit 28: Voltage switch bit */ + /* Bits 29-30: Reserved */ +#define SDMMC_CMD_STARTCMD (1 << 31) /* Bit 31: Start command */ + +/* Status register STATUS */ + +#define SDMMC_STATUS_RXWMARK (1 << 0) /* Bit 0: FIFO reached Receive watermark level */ +#define SDMMC_STATUS_TXWMARK (1 << 1) /* Bit 1: FIFO reached Transmit watermark level */ +#define SDMMC_STATUS_FIFOEMPTY (1 << 2) /* Bit 2: FIFO is empty */ +#define SDMMC_STATUS_FIFOFULL (1 << 3) /* Bit 3: FIFO is full */ +#define SDMMC_STATUS_FSMSTATE_SHIFT (4) /* Bits 4-7: 7:4 Command FSM states */ +#define SDMMC_STATUS_FSMSTATE_MASK (15 << SDMMC_STATUS_FSMSTATE_SHIFT) +# define SDMMC_STATUS_FSMSTATE_IDLE (0 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Idle */ +# define SDMMC_STATUS_FSMSTATE_INIT (1 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Send init sequence */ +# define SDMMC_STATUS_FSMSTATE_TXSTART (2 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Tx cmd start bit */ +# define SDMMC_STATUS_FSMSTATE_TXTXBIT (3 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Tx cmd tx bit */ +# define SDMMC_STATUS_FSMSTATE_TXCMDARG (4 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Tx cmd index + arg */ +# define SDMMC_STATUS_FSMSTATE_TXCMDCRC (5 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Tx cmd crc7 */ +# define SDMMC_STATUS_FSMSTATE_TXEND (6 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Tx cmd end bit */ +# define SDMMC_STATUS_FSMSTATE_RXSTART (7 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp start bit */ +# define SDMMC_STATUS_FSMSTATE_RXIRQ (8 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp IRQ response */ +# define SDMMC_STATUS_FSMSTATE_RXTXBIT (9 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp tx bit */ +# define SDMMC_STATUS_FSMSTATE_RXCMD (10 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp cmd idx */ +# define SDMMC_STATUS_FSMSTATE_RXRESP (11 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp data */ +# define SDMMC_STATUS_FSMSTATE_RXRESPCRC (12 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp crc7 */ +# define SDMMC_STATUS_FSMSTATE_RXEND (13 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Rx resp end bit */ +# define SDMMC_STATUS_FSMSTATE_WAITNCC (14 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Cmd path wait NCC */ +# define SDMMC_STATUS_FSMSTATE_WAITTURN (15 << SDMMC_STATUS_FSMSTATE_SHIFT) /* Wait; CMD-to-resp turnaround */ +#define SDMMC_STATUS_DAT3 (1 << 8) /* Bit 8: DAT3=1: Card present */ +#define SDMMC_STATUS_DATABUSY (1 << 9) /* Bit 9: Card data busy */ +#define SDMMC_STATUS_MCBUSY (1 << 10) /* Bit 10: Data transmit/receive state machine busy */ +#define SDMMC_STATUS_RESPINDEX_SHIFT (11) /* Bits 11-16: Index of previous response */ +#define SDMMC_STATUS_RESPINDEX_MASK (63 << SDMMC_STATUS_RESPINDEX_SHIFT) +#define SDMMC_STATUS_FIFOCOUNT_SHIFT (17) /* Bits 17-29: FIFO count */ +#define SDMMC_STATUS_FIFOCOUNT_MASK (0x1fff << SDMMC_STATUS_FIFOCOUNT_SHIFT) +#define SDMMC_STATUS_DMAACK (1 << 30) /* Bit 30: DMA acknowledge signal state */ +#define SDMMC_STATUS_DMAREQ (1 << 31) /* Bit 31: DMA request signal state */ + +/* FIFO threshold register FIFOTH */ + +#define SDMMC_FIFOTH_TXWMARK_SHIFT (0) /* Bits 0-11: FIFO threshold level when transmitting */ +#define SDMMC_FIFOTH_TXWMARK_MASK (0xfff << SDMMC_FIFOTH_TXWMARK_SHIFT) + /* Bits 12-15: Reserved */ +#define SDMMC_FIFOTH_RXWMARK_SHIFT (16) /* Bits 16-27: FIFO threshold level when receiving */ +#define SDMMC_FIFOTH_RXWMARK_MASK (0xfff << SDMMC_FIFOTH_RXWMARK_SHIFT) +#define SDMMC_FIFOTH_DMABURST_SHIFT (28) /* Bits 28-30: Burst size for multiple transaction */ +#define SDMMC_FIFOTH_DMABURST_MASK (7 << SDMMC_FIFOTH_DMABURST_SHIFT) +# define SDMMC_FIFOTH_DMABURST_1XFR (0 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 1 transfer */ +# define SDMMC_FIFOTH_DMABURST_4XFRS (1 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 4 transfers */ +# define SDMMC_FIFOTH_DMABURST_8XFRS (2 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 8 transfers */ +# define SDMMC_FIFOTH_DMABURST_16XFRS (3 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 16 transfers */ +# define SDMMC_FIFOTH_DMABURST_32XFRS (4 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 32 transfers */ +# define SDMMC_FIFOTH_DMABURST_64XFRS (5 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 64 transfers */ +# define SDMMC_FIFOTH_DMABURST_128XFRS (6 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 128 transfers */ +# define SDMMC_FIFOTH_DMABURST_256XFRS (7 << SDMMC_FIFOTH_DMABURST_SHIFT) /* 256 transfers */ + /* Bit 31: Reserved */ +/* Card detect register CDETECT */ + +#define SDMMC_CDETECT_NOTPRESENT (1 << 0) /* Bit 0: Card detect */ + /* Bit 1-31: Reserved */ +/* Write protect register WRTPRT */ + +#define SDMMC_WRTPRT_PROTECTED (1 << 0) /* Bit 0: Write protect */ + /* Bit 1-31: Reserved */ +/* Debounce count register */ + +#define SDMMC_DEBNCE_MASK 0x00ffffff /* Bits 0-23: Debounce count */ + /* Bit 24-31: Reserved */ + +/* Hardware Reset */ + +#define SDMMC_RSTN (1 << 0) /* Bit 0: Hardware reset */ + /* Bit 1-31: Reserved */ + +/* Bus Mode Register */ + +#define SDMMC_BMOD_SWR (1 << 0) /* Bit 0: Software Reset */ +#define SDMMC_BMOD_FB (1 << 1) /* Bit 1: Fixed Burst */ +#define SDMMC_BMOD_DSL_SHIFT (2) /* Bits 2-6: Descriptor Skip Length */ +#define SDMMC_BMOD_DSL_MASK (31 << SDMMC_BMOD_DSL_SHIFT) +#define SDMMC_BMOD_DE (1 << 7) /* Bit 7: SD/MMC DMA Enable */ +#define SDMMC_BMOD_PBL_SHIFT (8) /* Bits 8-10: Programmable Burst Length */ +#define SDMMC_BMOD_PBL_MASK (7 << SDMMC_BMOD_PBL_SHIFT) +# define SDMMC_BMOD_PBL_1XFRS (0 << SDMMC_BMOD_PBL_SHIFT) /* 1 transfer */ +# define SDMMC_BMOD_PBL_4XFRS (1 << SDMMC_BMOD_PBL_SHIFT) /* 4 transfers */ +# define SDMMC_BMOD_PBL_8XFRS (2 << SDMMC_BMOD_PBL_SHIFT) /* 8 transfers */ +# define SDMMC_BMOD_PBL_16XFRS (3 << SDMMC_BMOD_PBL_SHIFT) /* 16 transfers */ +# define SDMMC_BMOD_PBL_32XFRS (4 << SDMMC_BMOD_PBL_SHIFT) /* 32 transfers */ +# define SDMMC_BMOD_PBL_64XFRS (5 << SDMMC_BMOD_PBL_SHIFT) /* 64 transfers */ +# define SDMMC_BMOD_PBL_128XFRS (6 << SDMMC_BMOD_PBL_SHIFT) /* 128 transfers */ +# define SDMMC_BMOD_PBL_256XFRS (7 << SDMMC_BMOD_PBL_SHIFT) /* 256 transfers */ + /* Bits 11-31: Reserved */ +/* Internal DMAC Status Register */ + +#define SDMMC_IDSTS_TI (1 << 0) /* Bit 0: Transmit Interrupt */ +#define SDMMC_IDSTS_RI (1 << 1) /* Bit 1: Receive Interrupt */ +#define SDMMC_IDSTS_FBE (1 << 2) /* Bit 2: Fatal Bus Error Interrupt */ + /* Bit 3: Reserved */ +#define SDMMC_IDSTS_DU (1 << 4) /* Bit 4: Descriptor Unavailable Interrupt */ +#define SDMMC_IDSTS_CES (1 << 5) /* Bit 5: Card Error Summary */ + /* Bits 6-7: Reserved */ +#define SDMMC_IDSTS_NIS (1 << 8) /* Bit 8: Normal Interrupt Summary */ +#define SDMMC_IDSTS_AIS (1 << 9) /* Bit 9: Abnormal Interrupt Summary */ +#define SDMMC_IDSTS_EB_SHIFT (10) /* Bits 10-12: Error Bits */ +#define SDMMC_IDSTS_EB_MASK (7 << SDMMC_IDSTS_EB_SHIFT) +# define SDMMC_IDSTS_EB_TXHABORT (1 << SDMMC_IDSTS_EB_SHIFT) /* Host Abort received during transmission */ +# define SDMMC_IDSTS_EB_RXHABORT (2 << SDMMC_IDSTS_EB_SHIFT) /* Host Abort received during reception */ +#define SDMMC_IDSTS_FSM_SHIFT (13) /* Bits 13-16: DMAC state machine present state */ +#define SDMMC_IDSTS_FSM_MASK (15 << SDMMC_IDSTS_FSM_SHIFT) +# define SDMMC_IDSTS_FSM_DMAIDLE (0 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_IDLE*/ +# define SDMMC_IDSTS_FSM_DMASUSP (1 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_SUSPEND */ +# define SDMMC_IDSTS_FSM_DESCRD (2 << SDMMC_IDSTS_FSM_SHIFT) /* DESC_RD */ +# define SDMMC_IDSTS_FSM_DESCCHK (3 << SDMMC_IDSTS_FSM_SHIFT) /* DESC_CHK */ +# define SDMMC_IDSTS_FSM_DMARDREQW (4 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_RD_REQ_WAIT */ +# define SDMMC_IDSTS_FSM_DMAWRREQW (5 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_WR_REQ_WAIT */ +# define SDMMC_IDSTS_FSM_DMARD (6 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_RD */ +# define SDMMC_IDSTS_FSM_DMAWR (7 << SDMMC_IDSTS_FSM_SHIFT) /* DMA_WR */ +# define SDMMC_IDSTS_FSM_DMACLOSE (8 << SDMMC_IDSTS_FSM_SHIFT) /* DESC_CLOSE */ + /* Bits 17-31: Reserved */ +/* Internal DMAC Interrupt Enable Register */ + +#define SDMMC_IDINTEN_ +#define SDMMC_IDINTEN_TI (1 << 0) /* Bit 0: Transmit Interrupt */ +#define SDMMC_IDINTEN_RI (1 << 1) /* Bit 1: Receive Interrupt */ +#define SDMMC_IDINTEN_FBE (1 << 2) /* Bit 2: Fatal Bus Error Interrupt */ + /* Bit 3: Reserved */ +#define SDMMC_IDINTEN_DU (1 << 4) /* Bit 4: Descriptor Unavailable Interrupt */ +#define SDMMC_IDINTEN_CES (1 << 5) /* Bit 5: Card Error Summary */ + /* Bits 6-7: Reserved */ +#define SDMMC_IDINTEN_NIS (1 << 8) /* Bit 8: Normal Interrupt Summary */ +#define SDMMC_IDINTEN_AIS (1 << 9) /* Bit 9: Abnormal Interrupt Summary */ + /* Bits 10-31: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SDMMC_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h b/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h new file mode 100644 index 0000000000000000000000000000000000000000..bd3d2df39d2595716891e4fa12a06a9058b2fafd --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_sgpio.h @@ -0,0 +1,682 @@ +/**************************************************************************************************** + * arch/arm/src/lpc43xx/chip/lpc43_sgpio.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SGPIO_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SGPIO_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +#define LPC43_SGPIO_OUT_MUXCFG_OFFSET(n) (0x0000 + ((n) << 2) +#define LPC43_SGPIO_OUT_MUXCFG0_OFFSET 0x0000 /* Pin multiplexer configuration register 0 */ +#define LPC43_SGPIO_OUT_MUXCFG1_OFFSET 0x0004 /* Pin multiplexer configuration register 1 */ +#define LPC43_SGPIO_OUT_MUXCFG2_OFFSET 0x0008 /* Pin multiplexer configuration register 2 */ +#define LPC43_SGPIO_OUT_MUXCFG3_OFFSET 0x000c /* Pin multiplexer configuration register 3 */ +#define LPC43_SGPIO_OUT_MUXCFG4_OFFSET 0x0010 /* Pin multiplexer configuration register 4 */ +#define LPC43_SGPIO_OUT_MUXCFG5_OFFSET 0x0014 /* Pin multiplexer configuration register 5 */ +#define LPC43_SGPIO_OUT_MUXCFG6_OFFSET 0x0018 /* Pin multiplexer configuration register 6 */ +#define LPC43_SGPIO_OUT_MUXCFG7_OFFSET 0x001c /* Pin multiplexer configuration register 7 */ +#define LPC43_SGPIO_OUT_MUXCFG8_OFFSET 0x0020 /* Pin multiplexer configuration register 8 */ +#define LPC43_SGPIO_OUT_MUXCFG9_OFFSET 0x0024 /* Pin multiplexer configuration register 9 */ +#define LPC43_SGPIO_OUT_MUXCFG10_OFFSET 0x0028 /* Pin multiplexer configuration register 10 */ +#define LPC43_SGPIO_OUT_MUXCFG11_OFFSET 0x002c /* Pin multiplexer configuration register 11 */ +#define LPC43_SGPIO_OUT_MUXCFG12_OFFSET 0x0030 /* Pin multiplexer configuration register 12 */ +#define LPC43_SGPIO_OUT_MUXCFG13_OFFSET 0x0034 /* Pin multiplexer configuration register 13 */ +#define LPC43_SGPIO_OUT_MUXCFG14_OFFSET 0x0038 /* Pin multiplexer configuration register 14 */ +#define LPC43_SGPIO_OUT_MUXCFG15_OFFSET 0x003c /* Pin multiplexer configuration register 15 */ + +#define LPC43_SGPIO_MUXCFG_OFFSET(n) (0x0040 + ((n) << 2) +#define LPC43_SGPIO_MUXCFG0_OFFSET 0x0040 /* SGPIO multiplexer configuration register 0 */ +#define LPC43_SGPIO_MUXCFG1_OFFSET 0x0044 /* SGPIO multiplexer configuration register 1 */ +#define LPC43_SGPIO_MUXCFG2_OFFSET 0x0048 /* SGPIO multiplexer configuration register 2 */ +#define LPC43_SGPIO_MUXCFG3_OFFSET 0x004c /* SGPIO multiplexer configuration register 3 */ +#define LPC43_SGPIO_MUXCFG4_OFFSET 0x0050 /* SGPIO multiplexer configuration register 4 */ +#define LPC43_SGPIO_MUXCFG5_OFFSET 0x0054 /* SGPIO multiplexer configuration register 5 */ +#define LPC43_SGPIO_MUXCFG6_OFFSET 0x0058 /* SGPIO multiplexer configuration register 6 */ +#define LPC43_SGPIO_MUXCFG7_OFFSET 0x005c /* SGPIO multiplexer configuration register 7 */ +#define LPC43_SGPIO_MUXCFG8_OFFSET 0x0060 /* SGPIO multiplexer configuration register 8 */ +#define LPC43_SGPIO_MUXCFG9_OFFSET 0x0064 /* SGPIO multiplexer configuration register 9 */ +#define LPC43_SGPIO_MUXCFG10_OFFSET 0x0068 /* SGPIO multiplexer configuration register 10 */ +#define LPC43_SGPIO_MUXCFG11_OFFSET 0x006c /* SGPIO multiplexer configuration register 11 */ +#define LPC43_SGPIO_MUXCFG12_OFFSET 0x0070 /* SGPIO multiplexer configuration register 12 */ +#define LPC43_SGPIO_MUXCFG13_OFFSET 0x0074 /* SGPIO multiplexer configuration register 13 */ +#define LPC43_SGPIO_MUXCFG14_OFFSET 0x0078 /* SGPIO multiplexer configuration register 14 */ +#define LPC43_SGPIO_MUXCFG15_OFFSET 0x007c /* SGPIO multiplexer configuration register 15 */ + +#define LPC43_SGPIO_SLICE_MUXCFG_OFFSET(n) (0x0080 + ((n) << 2) +#define LPC43_SGPIO_SLICE_MUXCFG0_OFFSET 0x0080 /* Slice multiplexer configuration register 0 */ +#define LPC43_SGPIO_SLICE_MUXCFG1_OFFSET 0x0084 /* Slice multiplexer configuration register 1 */ +#define LPC43_SGPIO_SLICE_MUXCFG2_OFFSET 0x0088 /* Slice multiplexer configuration register 2 */ +#define LPC43_SGPIO_SLICE_MUXCFG3_OFFSET 0x008c /* Slice multiplexer configuration register 3 */ +#define LPC43_SGPIO_SLICE_MUXCFG4_OFFSET 0x0090 /* Slice multiplexer configuration register 4 */ +#define LPC43_SGPIO_SLICE_MUXCFG5_OFFSET 0x0094 /* Slice multiplexer configuration register 5 */ +#define LPC43_SGPIO_SLICE_MUXCFG6_OFFSET 0x0098 /* Slice multiplexer configuration register 6 */ +#define LPC43_SGPIO_SLICE_MUXCFG7_OFFSET 0x009c /* Slice multiplexer configuration register 7 */ +#define LPC43_SGPIO_SLICE_MUXCFG8_OFFSET 0x00a0 /* Slice multiplexer configuration register 8 */ +#define LPC43_SGPIO_SLICE_MUXCFG9_OFFSET 0x00a4 /* Slice multiplexer configuration register 9 */ +#define LPC43_SGPIO_SLICE_MUXCFG10_OFFSET 0x00a8 /* Slice multiplexer configuration register 10 */ +#define LPC43_SGPIO_SLICE_MUXCFG11_OFFSET 0x00ac /* Slice multiplexer configuration register 11 */ +#define LPC43_SGPIO_SLICE_MUXCFG12_OFFSET 0x00b0 /* Slice multiplexer configuration register 12 */ +#define LPC43_SGPIO_SLICE_MUXCFG13_OFFSET 0x00b4 /* Slice multiplexer configuration register 13 */ +#define LPC43_SGPIO_SLICE_MUXCFG14_OFFSET 0x00b8 /* Slice multiplexer configuration register 14 */ +#define LPC43_SGPIO_SLICE_MUXCFG15_OFFSET 0x00bc /* Slice multiplexer configuration register 15 */ + +#define LPC43_SGPIO_REG_OFFSET(n) (0x00c0 + ((n) << 2) +#define LPC43_SGPIO_REG0_OFFSET 0x00c0 /* Slice data register 0 */ +#define LPC43_SGPIO_REG1_OFFSET 0x00c4 /* Slice data register 1 */ +#define LPC43_SGPIO_REG2_OFFSET 0x00c8 /* Slice data register 2 */ +#define LPC43_SGPIO_REG3_OFFSET 0x00cc /* Slice data register 3 */ +#define LPC43_SGPIO_REG4_OFFSET 0x00d0 /* Slice data register 4 */ +#define LPC43_SGPIO_REG5_OFFSET 0x00d4 /* Slice data register 5 */ +#define LPC43_SGPIO_REG6_OFFSET 0x00d8 /* Slice data register 6 */ +#define LPC43_SGPIO_REG7_OFFSET 0x00dc /* Slice data register 7 */ +#define LPC43_SGPIO_REG8_OFFSET 0x00e0 /* Slice data register 8 */ +#define LPC43_SGPIO_REG9_OFFSET 0x00e4 /* Slice data register 9 */ +#define LPC43_SGPIO_REG10_OFFSET 0x00e8 /* Slice data register 10 */ +#define LPC43_SGPIO_REG11_OFFSET 0x00ec /* Slice data register 11 */ +#define LPC43_SGPIO_REG12_OFFSET 0x00f0 /* Slice data register 12 */ +#define LPC43_SGPIO_REG13_OFFSET 0x00f4 /* Slice data register 13 */ +#define LPC43_SGPIO_REG14_OFFSET 0x00f8 /* Slice data register 14 */ +#define LPC43_SGPIO_REG15_OFFSET 0x00fc /* Slice data register 15 */ + +#define LPC43_SGPIO_REG_SS_OFFSET(n) (0x0100 + ((n) << 2) +#define LPC43_SGPIO_REG_SS0_OFFSET 0x0100 /* Slice data shadow register 0 */ +#define LPC43_SGPIO_REG_SS1_OFFSET 0x0104 /* Slice data shadow register 1 */ +#define LPC43_SGPIO_REG_SS2_OFFSET 0x0108 /* Slice data shadow register 2 */ +#define LPC43_SGPIO_REG_SS3_OFFSET 0x010c /* Slice data shadow register 3 */ +#define LPC43_SGPIO_REG_SS4_OFFSET 0x0110 /* Slice data shadow register 4 */ +#define LPC43_SGPIO_REG_SS5_OFFSET 0x0114 /* Slice data shadow register 5 */ +#define LPC43_SGPIO_REG_SS6_OFFSET 0x0118 /* Slice data shadow register 6 */ +#define LPC43_SGPIO_REG_SS7_OFFSET 0x011c /* Slice data shadow register 7 */ +#define LPC43_SGPIO_REG_SS8_OFFSET 0x0120 /* Slice data shadow register 8 */ +#define LPC43_SGPIO_REG_SS9_OFFSET 0x0124 /* Slice data shadow register 9 */ +#define LPC43_SGPIO_REG_SS10_OFFSET 0x0128 /* Slice data shadow register 10 */ +#define LPC43_SGPIO_REG_SS11_OFFSET 0x012c /* Slice data shadow register 11 */ +#define LPC43_SGPIO_REG_SS12_OFFSET 0x0130 /* Slice data shadow register 12 */ +#define LPC43_SGPIO_REG_SS13_OFFSET 0x0134 /* Slice data shadow register 13 */ +#define LPC43_SGPIO_REG_SS14_OFFSET 0x0138 /* Slice data shadow register 14 */ +#define LPC43_SGPIO_REG_SS15_OFFSET 0x013c /* Slice data shadow register 15 */ + +#define LPC43_SGPIO_PRESET_OFFSET(n) (0x0140 + ((n) << 2) +#define LPC43_SGPIO_PRESET0_OFFSET 0x0140 /* COUNT0 reload value */ +#define LPC43_SGPIO_PRESET1_OFFSET 0x0144 /* COUNT1 reload value */ +#define LPC43_SGPIO_PRESET2_OFFSET 0x0148 /* COUNT2 reload value */ +#define LPC43_SGPIO_PRESET3_OFFSET 0x014c /* COUNT3 reload value */ +#define LPC43_SGPIO_PRESET4_OFFSET 0x0150 /* COUNT4 reload value */ +#define LPC43_SGPIO_PRESET5_OFFSET 0x0154 /* COUNT5 reload value */ +#define LPC43_SGPIO_PRESET6_OFFSET 0x0158 /* COUNT6 reload value */ +#define LPC43_SGPIO_PRESET7_OFFSET 0x015c /* COUNT7 reload value */ +#define LPC43_SGPIO_PRESET8_OFFSET 0x0160 /* COUNT8 reload value */ +#define LPC43_SGPIO_PRESET9_OFFSET 0x0164 /* COUNT9 reload value */ +#define LPC43_SGPIO_PRESET10_OFFSET 0x0168 /* COUNT10 reload value */ +#define LPC43_SGPIO_PRESET11_OFFSET 0x016c /* COUNT11 reload value */ +#define LPC43_SGPIO_PRESET12_OFFSET 0x0170 /* COUNT12 reload value */ +#define LPC43_SGPIO_PRESET13_OFFSET 0x0174 /* COUNT13 reload value */ +#define LPC43_SGPIO_PRESET14_OFFSET 0x0178 /* COUNT14 reload value */ +#define LPC43_SGPIO_PRESET15_OFFSET 0x017c /* COUNT15 reload value */ + +#define LPC43_SGPIO_COUNT_OFFSET(n) (0x0180 + ((n) << 2) +#define LPC43_SGPIO_COUNT0_OFFSET 0x0180 /* Down counter 0 */ +#define LPC43_SGPIO_COUNT1_OFFSET 0x0184 /* Down counter 1 */ +#define LPC43_SGPIO_COUNT2_OFFSET 0x0188 /* Down counter 2 */ +#define LPC43_SGPIO_COUNT3_OFFSET 0x018c /* Down counter 3 */ +#define LPC43_SGPIO_COUNT4_OFFSET 0x0190 /* Down counter 4 */ +#define LPC43_SGPIO_COUNT5_OFFSET 0x0194 /* Down counter 5 */ +#define LPC43_SGPIO_COUNT6_OFFSET 0x0198 /* Down counter 6 */ +#define LPC43_SGPIO_COUNT7_OFFSET 0x019c /* Down counter 7 */ +#define LPC43_SGPIO_COUNT8_OFFSET 0x01a0 /* Down counter 8 */ +#define LPC43_SGPIO_COUNT9_OFFSET 0x01a4 /* Down counter 9 */ +#define LPC43_SGPIO_COUNT10_OFFSET 0x01a8 /* Down counter 10 */ +#define LPC43_SGPIO_COUNT11_OFFSET 0x01ac /* Down counter 11 */ +#define LPC43_SGPIO_COUNT12_OFFSET 0x01b0 /* Down counter 12 */ +#define LPC43_SGPIO_COUNT13_OFFSET 0x01b4 /* Down counter 13 */ +#define LPC43_SGPIO_COUNT14_OFFSET 0x01b8 /* Down counter 14 */ +#define LPC43_SGPIO_COUNT15_OFFSET 0x01bc /* Down counter 15 */ + +#define LPC43_SGPIO_POS_OFFSET(n) (0x01c0 + ((n) << 2) +#define LPC43_SGPIO_POS0_OFFSET 0x01c0 /* Position register 0 */ +#define LPC43_SGPIO_POS1_OFFSET 0x01c4 /* Position register 1 */ +#define LPC43_SGPIO_POS2_OFFSET 0x01c8 /* Position register 2 */ +#define LPC43_SGPIO_POS3_OFFSET 0x01cc /* Position register 3 */ +#define LPC43_SGPIO_POS4_OFFSET 0x01d0 /* Position register 4 */ +#define LPC43_SGPIO_POS5_OFFSET 0x01d4 /* Position register 5 */ +#define LPC43_SGPIO_POS6_OFFSET 0x01d8 /* Position register 6 */ +#define LPC43_SGPIO_POS7_OFFSET 0x01dc /* Position register 7 */ +#define LPC43_SGPIO_POS8_OFFSET 0x01e0 /* Position register 8 */ +#define LPC43_SGPIO_POS9_OFFSET 0x01e4 /* Position register 9 */ +#define LPC43_SGPIO_POS10_OFFSET 0x01e8 /* Position register 0 */ +#define LPC43_SGPIO_POS11_OFFSET 0x01ec /* Position register 1 */ +#define LPC43_SGPIO_POS12_OFFSET 0x01f0 /* Position register 2 */ +#define LPC43_SGPIO_POS13_OFFSET 0x01f4 /* Position register 3 */ +#define LPC43_SGPIO_POS14_OFFSET 0x01f8 /* Position register 4 */ +#define LPC43_SGPIO_POS15_OFFSET 0x01fc /* Position register 5 */ + +#define LPC43_SGPIO_MASKA_OFFSET 0x0200 /* Mask for pattern match function of slice A */ +#define LPC43_SGPIO_MASKH_OFFSET 0x0204 /* Mask for pattern match function of slice H */ +#define LPC43_SGPIO_MASKI_OFFSET 0x0208 /* Mask for pattern match function of slice I */ +#define LPC43_SGPIO_MASKP_OFFSET 0x020c /* Mask for pattern match function of slice P */ +#define LPC43_SGPIO_GPIO_INREG_OFFSET 0x0210 /* GPIO input status register */ +#define LPC43_SGPIO_GPIO_OUTREG_OFFSET 0x0214 /* GPIO output control register */ +#define LPC43_SGPIO_GPIO_OENREG_OFFSET 0x0218 /* GPIO OE control register */ +#define LPC43_SGPIO_CTRL_ENABLE_OFFSET 0x021c /* Enables the slice COUNT counter */ +#define LPC43_SGPIO_CTRL_DISABLE_OFFSET 0x0220 /* Disables the slice POS counter */ + +#define LPC43_SGPIO_INT_OFFSET(n) (0xf00 + ((n) << 5)) +#define LPC43_SGPIO_CLREN_INTOFFSET 0x0000 /* Interrupt clear mask */ +#define LPC43_SGPIO_SETEN_INTOFFSET 0x0004 /* Interrupt set mask */ +#define LPC43_SGPIO_ENABLE_INTOFFSET 0x0008 /* Interrupt enable */ +#define LPC43_SGPIO_STATUS_INTOFFSET 0x000c /* Interrupt status */ +#define LPC43_SGPIO_CLRSTAT_INTOFFSET 0x0010 /* Interrupt clear status */ +#define LPC43_SGPIO_SETSTAT_INTOFFSET 0x0014 /* Interrupt set status */ + +#define LPC43_SGPIO_CLREN_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_CLREN_INTOFFSET) +#define LPC43_SGPIO_SETEN_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_SETEN_INTOFFSET) +#define LPC43_SGPIO_ENABLE_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_ENABLE_INTOFFSET) +#define LPC43_SGPIO_STATUS_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_STATUS_INTOFFSET) +#define LPC43_SGPIO_CLRSTAT_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_CLRSTAT_INTOFFSET) +#define LPC43_SGPIO_SETSTAT_OFFSET(n) (LPC43_SGPIO_INT_OFFSET(n)+LPC43_SGPIO_SETSTAT_INTOFFSET) + +#define LPC43_SGPIO_CLREN0_OFFSET 0x0f00 /* Shift clock interrupt clear mask */ +#define LPC43_SGPIO_SETEN0_OFFSET 0x0f04 /* Shift clock interrupt set mask */ +#define LPC43_SGPIO_ENABLE0_OFFSET 0x0f08 /* Shift clock interrupt enable */ +#define LPC43_SGPIO_STATUS0_OFFSET 0x0f0c /* Shift clock interrupt status */ +#define LPC43_SGPIO_CLRSTAT0_OFFSET 0x0f10 /* Shift clock interrupt clear status */ +#define LPC43_SGPIO_SETSTAT0_OFFSET 0x0f14 /* Shift clock interrupt set status */ + +#define LPC43_SGPIO_CLREN1_OFFSET 0x0f20 /* Exchange clock interrupt clear mask */ +#define LPC43_SGPIO_SETEN1_OFFSET 0x0f24 /* Exchange clock interrupt set mask */ +#define LPC43_SGPIO_ENABLE1_OFFSET 0x0f28 /* Exchange clock interrupt enable */ +#define LPC43_SGPIO_STATUS1_OFFSET 0x0f2c /* Exchange clock interrupt status */ +#define LPC43_SGPIO_CLRSTAT1_OFFSET 0x0f30 /* Exchange clock interrupt clear status */ +#define LPC43_SGPIO_SETSTAT1_OFFSET 0x0f34 /* Exchange clock interrupt set status */ + +#define LPC43_SGPIO_CLREN2_OFFSET 0x0f40 /* Pattern match interrupt clear mask */ +#define LPC43_SGPIO_SETEN2_OFFSET 0x0f44 /* Pattern match interrupt set mask */ +#define LPC43_SGPIO_ENABLE2_OFFSET 0x0f48 /* Pattern match interrupt enable */ +#define LPC43_SGPIO_STATUS2_OFFSET 0x0f4c /* Pattern match interrupt status */ +#define LPC43_SGPIO_CLRSTAT2_OFFSET 0x0f50 /* Pattern match interrupt clear status */ +#define LPC43_SGPIO_SETSTAT2_OFFSET 0x0f54 /* Pattern match interrupt set status */ + +#define LPC43_SGPIO_CLREN3_OFFSET 0x0f60 /* Input interrupt clear mask */ +#define LPC43_SGPIO_SETEN3_OFFSET 0x0f64 /* Input bit match interrupt set mask */ +#define LPC43_SGPIO_ENABLE3_OFFSET 0x0f68 /* Input bit match interrupt enable */ +#define LPC43_SGPIO_STATUS3_OFFSET 0x0f6c /* Input bit match interrupt status */ +#define LPC43_SGPIO_CLRSTAT3_OFFSET 0x0f70 /* Input bit match interrupt clear status */ +#define LPC43_SGPIO_SETSTAT3_OFFSET 0x0f74 /* Input bit match interrupt set status */ + +/* Register Addresses *******************************************************************************/ + +#define LPC43_SGPIO_OUT_MUXCFG(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG_OFFSET(n)) +#define LPC43_SGPIO_OUT_MUXCFG0 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG0_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG1 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG1_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG2 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG2_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG3 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG3_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG4 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG4_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG5 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG5_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG6 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG6_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG7 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG7_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG8 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG8_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG9 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG9_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG10 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG10_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG11 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG11_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG12 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG12_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG13 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG13_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG14 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG14_OFFSET) +#define LPC43_SGPIO_OUT_MUXCFG15 (LPC43_SGPIO_BASE+LPC43_SGPIO_OUT_MUXCFG15_OFFSET) + +#define LPC43_SGPIO_MUXCFG(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG_OFFSET(n)) +#define LPC43_SGPIO_MUXCFG0 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG0_OFFSET) +#define LPC43_SGPIO_MUXCFG1 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG1_OFFSET) +#define LPC43_SGPIO_MUXCFG2 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG2_OFFSET) +#define LPC43_SGPIO_MUXCFG3 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG3_OFFSET) +#define LPC43_SGPIO_MUXCFG4 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG4_OFFSET) +#define LPC43_SGPIO_MUXCFG5 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG5_OFFSET) +#define LPC43_SGPIO_MUXCFG6 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG6_OFFSET) +#define LPC43_SGPIO_MUXCFG7 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG7_OFFSET) +#define LPC43_SGPIO_MUXCFG8 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG8_OFFSET) +#define LPC43_SGPIO_MUXCFG9 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG9_OFFSET) +#define LPC43_SGPIO_MUXCFG10 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG10_OFFSET) +#define LPC43_SGPIO_MUXCFG11 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG11_OFFSET) +#define LPC43_SGPIO_MUXCFG12 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG12_OFFSET) +#define LPC43_SGPIO_MUXCFG13 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG13_OFFSET) +#define LPC43_SGPIO_MUXCFG14 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG14_OFFSET) +#define LPC43_SGPIO_MUXCFG15 (LPC43_SGPIO_BASE+LPC43_SGPIO_MUXCFG15_OFFSET) + +#define LPC43_SGPIO_SLICE_MUXCFG(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG_OFFSET(n)) +#define LPC43_SGPIO_SLICE_MUXCFG0 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG0_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG1 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG1_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG2 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG2_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG3 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG3_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG4 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG4_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG5 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG5_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG6 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG6_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG7 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG7_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG8 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG8_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG9 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG9_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG10 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG10_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG11 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG11_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG12 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG12_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG13 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG13_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG14 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG14_OFFSET) +#define LPC43_SGPIO_SLICE_MUXCFG15 (LPC43_SGPIO_BASE+LPC43_SGPIO_SLICE_MUXCFG15_OFFSET) + +#define LPC43_SGPIO_REG(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_OFFSET(n)) +#define LPC43_SGPIO_REG0 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG0_OFFSET) +#define LPC43_SGPIO_REG1 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG1_OFFSET) +#define LPC43_SGPIO_REG2 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG2_OFFSET) +#define LPC43_SGPIO_REG3 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG3_OFFSET) +#define LPC43_SGPIO_REG4 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG4_OFFSET) +#define LPC43_SGPIO_REG5 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG5_OFFSET) +#define LPC43_SGPIO_REG6 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG6_OFFSET) +#define LPC43_SGPIO_REG7 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG7_OFFSET) +#define LPC43_SGPIO_REG8 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG8_OFFSET) +#define LPC43_SGPIO_REG9 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG9_OFFSET) +#define LPC43_SGPIO_REG10 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG10_OFFSET) +#define LPC43_SGPIO_REG11 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG11_OFFSET) +#define LPC43_SGPIO_REG12 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG12_OFFSET) +#define LPC43_SGPIO_REG13 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG13_OFFSET) +#define LPC43_SGPIO_REG14 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG14_OFFSET) +#define LPC43_SGPIO_REG15 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG15_OFFSET) + +#define LPC43_SGPIO_REG_SS(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS_OFFSET(n)) +#define LPC43_SGPIO_REG_SS0 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS0_OFFSET) +#define LPC43_SGPIO_REG_SS1 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS1_OFFSET) +#define LPC43_SGPIO_REG_SS2 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS2_OFFSET) +#define LPC43_SGPIO_REG_SS3 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS3_OFFSET) +#define LPC43_SGPIO_REG_SS4 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS4_OFFSET) +#define LPC43_SGPIO_REG_SS5 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS5_OFFSET) +#define LPC43_SGPIO_REG_SS6 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS6_OFFSET) +#define LPC43_SGPIO_REG_SS7 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS7_OFFSET) +#define LPC43_SGPIO_REG_SS8 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS8_OFFSET) +#define LPC43_SGPIO_REG_SS9 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS9_OFFSET) +#define LPC43_SGPIO_REG_SS10 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS10_OFFSET) +#define LPC43_SGPIO_REG_SS11 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS11_OFFSET) +#define LPC43_SGPIO_REG_SS12 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS12_OFFSET) +#define LPC43_SGPIO_REG_SS13 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS13_OFFSET) +#define LPC43_SGPIO_REG_SS14 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS14_OFFSET) +#define LPC43_SGPIO_REG_SS15 (LPC43_SGPIO_BASE+LPC43_SGPIO_REG_SS15_OFFSET) + +#define LPC43_SGPIO_PRESET(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET_OFFSET(n)) +#define LPC43_SGPIO_PRESET0 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET0_OFFSET) +#define LPC43_SGPIO_PRESET1 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET1_OFFSET) +#define LPC43_SGPIO_PRESET2 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET2_OFFSET) +#define LPC43_SGPIO_PRESET3 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET3_OFFSET) +#define LPC43_SGPIO_PRESET4 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET4_OFFSET) +#define LPC43_SGPIO_PRESET5 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET5_OFFSET) +#define LPC43_SGPIO_PRESET6 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET6_OFFSET) +#define LPC43_SGPIO_PRESET7 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET7_OFFSET) +#define LPC43_SGPIO_PRESET8 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET8_OFFSET) +#define LPC43_SGPIO_PRESET9 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET9_OFFSET) +#define LPC43_SGPIO_PRESET10 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET10_OFFSET) +#define LPC43_SGPIO_PRESET11 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET11_OFFSET) +#define LPC43_SGPIO_PRESET12 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET12_OFFSET) +#define LPC43_SGPIO_PRESET13 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET13_OFFSET) +#define LPC43_SGPIO_PRESET14 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET14_OFFSET) +#define LPC43_SGPIO_PRESET15 (LPC43_SGPIO_BASE+LPC43_SGPIO_PRESET15_OFFSET) + +#define LPC43_SGPIO_COUNT(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT_OFFSET(n)) +#define LPC43_SGPIO_COUNT0 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT0_OFFSET) +#define LPC43_SGPIO_COUNT1 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT1_OFFSET) +#define LPC43_SGPIO_COUNT2 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT2_OFFSET) +#define LPC43_SGPIO_COUNT3 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT3_OFFSET) +#define LPC43_SGPIO_COUNT4 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT4_OFFSET) +#define LPC43_SGPIO_COUNT5 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT5_OFFSET) +#define LPC43_SGPIO_COUNT6 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT6_OFFSET) +#define LPC43_SGPIO_COUNT7 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT7_OFFSET) +#define LPC43_SGPIO_COUNT8 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT8_OFFSET) +#define LPC43_SGPIO_COUNT9 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT9_OFFSET) +#define LPC43_SGPIO_COUNT10 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT10_OFFSET) +#define LPC43_SGPIO_COUNT11 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT11_OFFSET) +#define LPC43_SGPIO_COUNT12 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT12_OFFSET) +#define LPC43_SGPIO_COUNT13 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT13_OFFSET) +#define LPC43_SGPIO_COUNT14 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT14_OFFSET) +#define LPC43_SGPIO_COUNT15 (LPC43_SGPIO_BASE+LPC43_SGPIO_COUNT15_OFFSET) + +#define LPC43_SGPIO_POS(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_POS_OFFSET(n)) +#define LPC43_SGPIO_POS0 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS0_OFFSET) +#define LPC43_SGPIO_POS1 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS1_OFFSET) +#define LPC43_SGPIO_POS2 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS2_OFFSET) +#define LPC43_SGPIO_POS3 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS3_OFFSET) +#define LPC43_SGPIO_POS4 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS4_OFFSET) +#define LPC43_SGPIO_POS5 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS5_OFFSET) +#define LPC43_SGPIO_POS6 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS6_OFFSET) +#define LPC43_SGPIO_POS7 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS7_OFFSET) +#define LPC43_SGPIO_POS8 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS8_OFFSET) +#define LPC43_SGPIO_POS9 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS9_OFFSET) +#define LPC43_SGPIO_POS10 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS10_OFFSET) +#define LPC43_SGPIO_POS11 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS11_OFFSET) +#define LPC43_SGPIO_POS12 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS12_OFFSET) +#define LPC43_SGPIO_POS13 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS13_OFFSET) +#define LPC43_SGPIO_POS14 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS14_OFFSET) +#define LPC43_SGPIO_POS15 (LPC43_SGPIO_BASE+LPC43_SGPIO_POS15_OFFSET) + +#define LPC43_SGPIO_MASKA (LPC43_SGPIO_BASE+LPC43_SGPIO_MASKA_OFFSET) +#define LPC43_SGPIO_MASKH (LPC43_SGPIO_BASE+LPC43_SGPIO_MASKH_OFFSET) +#define LPC43_SGPIO_MASKI (LPC43_SGPIO_BASE+LPC43_SGPIO_MASKI_OFFSET) +#define LPC43_SGPIO_MASKP (LPC43_SGPIO_BASE+LPC43_SGPIO_MASKP_OFFSET) +#define LPC43_SGPIO_GPIO_INREG (LPC43_SGPIO_BASE+LPC43_SGPIO_GPIO_INREG_OFFSET) +#define LPC43_SGPIO_GPIO_OUTREG (LPC43_SGPIO_BASE+LPC43_SGPIO_GPIO_OUTREG_OFFSET) +#define LPC43_SGPIO_GPIO_OENREG (LPC43_SGPIO_BASE+LPC43_SGPIO_GPIO_OENREG_OFFSET) +#define LPC43_SGPIO_CTRL_ENABLE (LPC43_SGPIO_BASE+LPC43_SGPIO_CTRL_ENABLE_OFFSET) +#define LPC43_SGPIO_CTRL_DISABLE (LPC43_SGPIO_BASE+LPC43_SGPIO_CTRL_DISABLE_OFFSET) + +#define LPC43_SGPIO_INT(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_INT_OFFSET(n)) +#define LPC43_SGPIO_CLREN(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_CLREN_OFFSET(n)) +#define LPC43_SGPIO_SETEN(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_SETEN_OFFSET(n)) +#define LPC43_SGPIO_ENABLE(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_ENABLE_OFFSET(n)) +#define LPC43_SGPIO_STATUS(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_STATUS_OFFSET(n)) +#define LPC43_SGPIO_CLRSTAT(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_CLRSTAT_OFFSET(n)) +#define LPC43_SGPIO_SETSTAT(n) (LPC43_SGPIO_BASE+LPC43_SGPIO_SETSTAT_OFFSET(n)) + +#define LPC43_SGPIO_CLREN0 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLREN0_OFFSET) +#define LPC43_SGPIO_SETEN0 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETEN0_OFFSET) +#define LPC43_SGPIO_ENABLE0 (LPC43_SGPIO_BASE+LPC43_SGPIO_ENABLE0_OFFSET) +#define LPC43_SGPIO_STATUS0 (LPC43_SGPIO_BASE+LPC43_SGPIO_STATUS0_OFFSET) +#define LPC43_SGPIO_CLRSTAT0 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLRSTAT0_OFFSET) +#define LPC43_SGPIO_SETSTAT0 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETSTAT0_OFFSET) + +#define LPC43_SGPIO_CLREN1 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLREN1_OFFSET) +#define LPC43_SGPIO_SETEN1 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETEN1_OFFSET) +#define LPC43_SGPIO_ENABLE1 (LPC43_SGPIO_BASE+LPC43_SGPIO_ENABLE1_OFFSET) +#define LPC43_SGPIO_STATUS1 (LPC43_SGPIO_BASE+LPC43_SGPIO_STATUS1_OFFSET) +#define LPC43_SGPIO_CLRSTAT1 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLRSTAT1_OFFSET) +#define LPC43_SGPIO_SETSTAT1 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETSTAT1_OFFSET) + +#define LPC43_SGPIO_CLREN2 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLREN2_OFFSET) +#define LPC43_SGPIO_SETEN2 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETEN2_OFFSET) +#define LPC43_SGPIO_ENABLE2 (LPC43_SGPIO_BASE+LPC43_SGPIO_ENABLE2_OFFSET) +#define LPC43_SGPIO_STATUS2 (LPC43_SGPIO_BASE+LPC43_SGPIO_STATUS2_OFFSET) +#define LPC43_SGPIO_CLRSTAT2 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLRSTAT2_OFFSET) +#define LPC43_SGPIO_SETSTAT2 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETSTAT2_OFFSET) + +#define LPC43_SGPIO_CLREN3 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLREN3_OFFSET) +#define LPC43_SGPIO_SETEN3 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETEN3_OFFSET) +#define LPC43_SGPIO_ENABLE3 (LPC43_SGPIO_BASE+LPC43_SGPIO_ENABLE3_OFFSET) +#define LPC43_SGPIO_STATUS3 (LPC43_SGPIO_BASE+LPC43_SGPIO_STATUS3_OFFSET) +#define LPC43_SGPIO_CLRSTAT3 (LPC43_SGPIO_BASE+LPC43_SGPIO_CLRSTAT3_OFFSET) +#define LPC43_SGPIO_SETSTAT3 (LPC43_SGPIO_BASE+LPC43_SGPIO_SETSTAT3_OFFSET) + +/* Register Bit Definitions *************************************************************************/ + +/* Pin multiplexer configuration registers */ + +#define SGPIO_OUT_MUXCFG_OUTCFG_SHIFT (0) /* Bits 0-3: P_OUT_CFG Output control SGPIOn */ +#define SGPIO_OUT_MUXCFG_OUTCFG_MASK (15 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM1 (0 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm1 (1-bit mode) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_ DOUTM2A (1 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm2a (2-bit mode 2a) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM2B (2 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm2b (2-bit mode 2b) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM2C (3 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm2c (2-bit mode 2c) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_GPIOOUT (4 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* gpio_out (level set by GPIO_OUTREG) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM4A (5 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm4a (4-bit mode 4a) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM4B (6 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm4b (4-bit mode 4b) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM4C (7 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm4c (4-bit mode 4c) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_CLKOUT (8 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* clk_out */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM8A (9 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm8a (8-bit mode 8a) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM8B (10 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm8b (8-bit mode 8b) */ +# define SGPIO_OUT_MUXCFG_OUTCFG_DOUTM8C (11 << SGPIO_OUT_MUXCFG_OUTCFG_SHIFT) /* dout_doutm8c (8-bit mode 8c) */ +#define SGPIO_OUT_MUXCFG_OECFG_SHIFT (4) /* Bits 4-6: P_OE_CFG Output enable source */ +#define SGPIO_OUT_MUXCFG_OECFG_MASK (7 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) +# define SGPIO_OUT_MUXCFG_OECFG_GPIOOE (0 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) /* gpio_oe (state set by GPIO_OEREG) */ +# define SGPIO_OUT_MUXCFG_OECFG_OEM1 (4 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) /* dout_oem1 (1-bit mode) */ +# define SGPIO_OUT_MUXCFG_OECFG_OEM2 (5 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) /* dout_oem2 (2-bit mode) */ +# define SGPIO_OUT_MUXCFG_OECFG_OEM4 (6 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) /* dout_oem4 (4-bit mode) */ +# define SGPIO_OUT_MUXCFG_OECFG_OEM8 (7 << SGPIO_OUT_MUXCFG_OECFG_SHIFT) /* dout_oem8 (8-bit mode) */ + /* Bits 7-31: Reserved */ +/* SGPIO multiplexer configuration registers */ + +#define SGPIO_MUXCFG_EXTCLK (1 << 9) /* Bit 9: Select clock signal */ +#define SGPIO_MUXCFG_CS_PMODE_SHIFT (1) /* Bits 1-2: Select source clock pin */ +#define SGPIO_MUXCFG_CS_PMODE_MASK (3 << SGPIO_MUXCFG_CS_PMODE_SHIFT) +# define SGPIO_MUXCFG_CS_PMODE_SGPIO8 (0 << SGPIO_MUXCFG_CS_PMODE_SHIFT) +# define SGPIO_MUXCFG_CS_PMODE_SGPIO9 (1 << SGPIO_MUXCFG_CS_PMODE_SHIFT) +# define SGPIO_MUXCFG_CS_PMODE_SGPIO10 (2 << SGPIO_MUXCFG_CS_PMODE_SHIFT) +# define SGPIO_MUXCFG_CS_PMODE_SGPIO11 (3 << SGPIO_MUXCFG_CS_PMODE_SHIFT) +#define SGPIO_MUXCFG_CS_SMODE_SHIFT (3) /* Bits 3-4: CLK_SOURCE_SLICE_MODE Select clock source slice */ +#define SGPIO_MUXCFG_CS_SMODE_MASK (3 << SGPIO_MUXCFG_CS_SMODE_SHIFT) +# define SGPIO_MUXCFG_CS_SMODE_SLICED (0 << SGPIO_MUXCFG_CS_SMODE_SHIFT) +# define SGPIO_MUXCFG_CS_SMODE_SLICEH (1 << SGPIO_MUXCFG_CS_SMODE_SHIFT) +# define SGPIO_MUXCFG_CS_SMODE_SLICEO (2 << SGPIO_MUXCFG_CS_SMODE_SHIFT) +# define SGPIO_MUXCFG_CS_SMODE_SLICEP (3 << SGPIO_MUXCFG_CS_SMODE_SHIFT) +#define SGPIO_MUXCFG_QUAL_MODE_SHIFT (5) /* Bits 5-6: Select qualifier mode */ +#define SGPIO_MUXCFG_QUAL_MODE_MASK (3 << SGPIO_MUXCFG_QUAL_MODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_MODE_ENABLE (0 << SGPIO_MUXCFG_QUAL_MODE_SHIFT) /* Enable */ +# define SGPIO_MUXCFG_QUAL_MODE_DISABLE (1 << SGPIO_MUXCFG_QUAL_MODE_SHIFT) /* Disable */ +# define SGPIO_MUXCFG_QUAL_MODE_SLICE (2 << SGPIO_MUXCFG_QUAL_MODE_SHIFT) /* Slice */ +# define SGPIO_MUXCFG_QUAL_MODE_SGPIO (3 << SGPIO_MUXCFG_QUAL_MODE_SHIFT) /* External SGPIO pin (8, 9, 10, or 11) */ +#define SGPIO_MUXCFG_QUAL_PMODE_SHIFT (7) /* Bits 7-8: Select qualifier pin */ +#define SGPIO_MUXCFG_QUAL_PMODE_MASK (3 << SGPIO_MUXCFG_QUAL_PMODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_PMODE_SGPIO8 (0 << SGPIO_MUXCFG_QUAL_PMODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_PMODE_SGPIO9 (1 << SGPIO_MUXCFG_QUAL_PMODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_PMODE_SGPIO10 (2 << SGPIO_MUXCFG_QUAL_PMODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_PMODE_SGPIO11 (3 << SGPIO_MUXCFG_QUAL_PMODE_SHIFT) +#define SGPIO_MUXCFG_QUAL_SMODE_SHIFT (9) /* Bits 9-10: Select qualifier slice */ +#define SGPIO_MUXCFG_QUAL_SMODE_MASK (3 << SGPIO_MUXCFG_QUAL_SMODE_SHIFT) +# define SGPIO_MUXCFG_QUAL_SMODE_SLICEA (0 << SGPIO_MUXCFG_QUAL_SMODE_SHIFT) /* Slice A, but for slice A slice D is used */ +# define SGPIO_MUXCFG_QUAL_SMODE_SLICEH (1 << SGPIO_MUXCFG_QUAL_SMODE_SHIFT) /* Slice H, but for slice H slice O is used */ +# define SGPIO_MUXCFG_QUAL_SMODE_SLICEI (2 << SGPIO_MUXCFG_QUAL_SMODE_SHIFT) /* Slice I, but for slice I slice D is used */ +# define SGPIO_MUXCFG_QUAL_SMODE_SLICEP (3 << SGPIO_MUXCFG_QUAL_SMODE_SHIFT) /* Slice P, but for slice P slice O is used */ +#define SGPIO_MUXCFG_CONCAT (1 << 11) /* Bit 11: Enable concatenation */ +#define SGPIO_MUXCFG_CONCAT_ORDER_SHIFT (12) /* Bits 12-13: CONCAT_ORDER Select concatenation order */ +#define SGPIO_MUXCFG_CONCAT_ORDER_MASK (3 << SGPIO_MUXCFG_CONCAT_ORDER_SHIFT) +# define SGPIO_MUXCFG_CONCAT_ORDER_SELT (0 << SGPIO_MUXCFG_CONCAT_ORDER_SHIFT) /* Self-loop */ +# define SGPIO_MUXCFG_CONCAT_ORDER_S2 (1 << SGPIO_MUXCFG_CONCAT_ORDER_SHIFT) /* 2 slices */ +# define SGPIO_MUXCFG_CONCAT_ORDER_S4 (2 << SGPIO_MUXCFG_CONCAT_ORDER_SHIFT) /* 4 slices */ +# define SGPIO_MUXCFG_CONCAT_ORDER_S8 (3 << SGPIO_MUXCFG_CONCAT_ORDER_SHIFT) /* 8 slices */ + /* Bits 14-31: Reserved */ +/* Slice multiplexer configuration register 0 */ + +#define SGPIO_SLICE_MUXCFG_MATCH (1 << 0) /* Bit 0: Match mode */ +#define SGPIO_SLICE_MUXCFG_CAPTURE (1 << 1) /* Bit 1: Capture clock mode */ +#define SGPIO_SLICE_MUXCFG_CLKGEN (1 << 2) /* Bit 2: Clock generation mode */ +#define SGPIO_SLICE_MUXCFG_INTOUTCLK (1 << 3) /* Bit 3: Invert output clock */ +#define SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT (4) /* Bits 4-5: Condition for input bit match interrupt */ +#define SGPIO_SLICE_MUXCFG_CAPMODE_MASK (3 << SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT) +# define SGPIO_SLICE_MUXCFG_CAPMODE_RISING (0 << SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT) /* Detect rising edge */ +# define SGPIO_SLICE_MUXCFG_CAPMODE_FALLING (1 << SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT) /* Detect falling edge */ +# define SGPIO_SLICE_MUXCFG_CAPMODE_LOW (2 << SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT) /* Detect LOW level */ +# define SGPIO_SLICE_MUXCFG_CAPMODE_HIGH (3 << SGPIO_SLICE_MUXCFG_CAPMODE_SHIFT) /* Detect HIGH level */ +#define SGPIO_SLICE_MUXCFG_PARMODE_SHIFT (6) /* Bits 6-7: Parallel mode */ +#define SGPIO_SLICE_MUXCFG_PARMODE_MASK (3 << SGPIO_SLICE_MUXCFG_PARMODE_SHIFT) +# define SGPIO_SLICE_MUXCFG_PARMODE_SHIFT1 (0 << SGPIO_SLICE_MUXCFG_PARMODE_SHIFT) /* Shift 1 bit per clock */ +# define SGPIO_SLICE_MUXCFG_PARMODE_SHIFT2 (1 << SGPIO_SLICE_MUXCFG_PARMODE_SHIFT) /* Shift 2 bits per clock */ +# define SGPIO_SLICE_MUXCFG_PARMODE_SHIFT4 (2 << SGPIO_SLICE_MUXCFG_PARMODE_SHIFT) /* Shift 4 bits per clock */ +# define SGPIO_SLICE_MUXCFG_PARMODE_SHIFT8 (3 << SGPIO_SLICE_MUXCFG_PARMODE_SHIFT) /* Shift 1 byte per clock */ +#define SGPIO_SLICE_MUXCFG_INVQUAL (1 << 8) /* Bit 8: Inversion qualifier */ + /* Bits 9-31: Reserved */ +/* Slice data registers (32-bit data) */ +/* Slice data shadow registers (32-bit data) */ + +/* COUNTn reload value (32-bit data) */ + +#define SGPIO_PRESET_MASK (0xfff) /* Bits 0-11: Counter reload value */ + /* Bits 12-31: Reserved */ +/* Down counter registers */ + +#define SGPIO_COUNT_MASK (0xfff) /* Bits 0-11: Down counter */ + /* Bits 12-31: Reserved */ +/* Position registers */ + +#define SGPIO_POS_POS_SHIFT (0) /* Bits 0-7: Each time COUNT reaches zero POS counts down */ +#define SGPIO_POS_POS_MASK (0xffff << SGPIO_POS_POS_SHIFT) +#define SGPIO_POS_RESET_SHIFT (8) /* Bits 8-15: Reload value for POS after POS reaches zero */ +#define SGPIO_POS_RESET_MASK (0xffff << SGPIO_POS_RESET_SHIFT) + /* Bits 16-31: Reserved */ +/* Mask for pattern match function of slice A (32-bit bit mask) */ +/* Mask for pattern match function of slice H (32-bit bit mask) */ +/* Mask for pattern match function of slice I (32-bit bit mask) */ +/* Mask for pattern match function of slice P (32-bit bit mask) */ + +/* Common bit mask that can be used in all interrupt registers */ + +#define SGPIO_SLICE(n) (1 << (n)) /* Bits 0-15: Bit n corresponids to slice n */ + /* Bits 16-31: Reserved */ +/* GPIO input status register */ + +#define SGPIO_GPIO_INREG(n) (1 << (n)) /* Bits 0-15: Bit i reflects the input state of SGPIO pin */ + /* Bits 16-31: Reserved */ +/* GPIO output control register */ + +#define SGPIO_GPIO_OUTREG(n) (1 << (n)) /* Bits 0-15: Bit i sets the output of SGPIO pin i */ + /* Bits 16-31: Reserved */ +/* GPIO output enable register */ + +#define SGPIO_GPIO_OENREG(n) (1 << (n)) /* Bits 0-15: Bit i selects the output enable state of SGPIO pin i */ + /* Bits 16-31: Reserved */ +/* Slice count enable register */ + +#define SGPIO_CTRL_ENABLE(n) (1 << (n)) /* Bits 0-15: Bit n controls slice n */ + /* Bits 16-31: Reserved */ +/* Slice count disable register */ + +#define SGPIO_CTRL_DISABLE(n) (1 << (n)) /* Bits 0-15: Bit n controls slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt clear mask */ + +#define SGPIO_CLREN0(n) (1 << (n)) /* Bits 0-15: Bit n shift clock interrupt clear mask of slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt set mask */ + +#define SGPIO_SETEN0(n) (1 << (n)) /* Bits 0-15: Bit n shift clock interrupt clear mask of slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt enable */ + +#define SGPIO_ENABLE0(n) (1 << (n)) /* Bits 0-15: Bit n shift clock interrupt enable of slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt status */ + +#define SGPIO_STATUS0(n) (1 << (n)) /* Bits 0-15: Bit n shift clock interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt clear status */ + +#define SGPIO_CLRSTAT0(n) (1 << (n)) /* Bits 0-15: Bit n shift clears interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Shift clock interrupt set status */ + +#define SGPIO_SETSTAT0(n) (1 << (n)) /* Bits 0-15: Bit n shift sets interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt clear mask */ + +#define SGPIO_CLREN1(n) (1 << (n)) /* Bits 0-15: Bit n clears exchange clock interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt set mask */ + +#define SGPIO_SETEN1(n) (1 << (n)) /* Bits 0-15: Bit n sets exchange clock interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt enable */ + +#define SGPIO_ENABLE1(n) (1 << (n)) /* Bits 0-15: Bit n enables exchange clock interrupt of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt status */ + +#define SGPIO_STATUS1(n) (1 << (n)) /* Bits 0-15: Bit n status of exchange clock interrupt of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt clear status */ + +#define SGPIO_CLRSTAT1(n) (1 << (n)) /* Bits 0-15: Bit n clears exchange clock interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Exchange clock interrupt set status */ + +#define SGPIO_SETSTAT1(n) (1 << (n)) /* Bits 0-15: Bit n sets exchange clock interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt clear mask */ + +#define SGPIO_CLREN2(n) (1 << (n)) /* Bits 0-15: Bit n clears match interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt set mask */ + +#define SGPIO_SETEN2(n) (1 << (n)) /* Bits 0-15: Bit n sets match interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt enable */ + +#define SGPIO_ENABLE2(n) (1 << (n)) /* Bits 0-15: Bit n enables match interrupt of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt status */ + +#define SGPIO_STATUS2(n) (1 << (n)) /* Bits 0-15: Bit n is match interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt clear status */ + +#define SGPIO_CLRSTAT2(n) (1 << (n)) /* Bits 0-15: Bit n sets match interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Pattern match interrupt set status */ + +#define SGPIO_SETSTAT2(n) (1 << (n)) /* Bits 0-15: Bit n sets match interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Input interrupt clear mask */ + +#define SGPIO_CLREN3(n) (1 << (n)) /* Bits 0-15: Bit n clears input interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Input bit match interrupt set mask */ + +#define SGPIO_SETEN3(n) (1 << (n)) /* Bits 0-15: Bit n sets input interrupt mask of slice n */ + /* Bits 16-31: Reserved */ +/* Input bit match interrupt enable */ + +#define SGPIO_ENABLE3(n) (1 << (n)) /* Bits 0-15: Bit n enables input interrupt of slice n */ + /* Bits 16-31: Reserved */ +/* Input bit match interrupt status */ + +#define SGPIO_STATUS3(n) (1 << (n)) /* Bits 0-15: Bit n is input interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Input bit match interrupt clear status */ + +#define SGPIO_CLRSTAT3(n) (1 << (n)) /* Bits 0-15: Bit n clears input interrupt status of slice n */ + /* Bits 16-31: Reserved */ +/* Input bit match interrupt set status */ + +#define SGPIO_SETSTAT3(n) (1 << (n)) /* Bits 0-15: Bit n sets match interrupt status of slice n */ + /* Bits 16-31: Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SGPIO_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_spi.h b/arch/arm/src/lpc43xx/chip/lpc43_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..5f6e26d6b90ec4c7dbe937e5493c2512c74a873e --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_spi.h @@ -0,0 +1,138 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_spi.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPI_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_SPI_CR_OFFSET 0x0000 /* Control Register */ +#define LPC43_SPI_SR_OFFSET 0x0004 /* SPI Status Register */ +#define LPC43_SPI_DR_OFFSET 0x0008 /* SPI Data Register */ +#define LPC43_SPI_CCR_OFFSET 0x000c /* SPI Clock Counter Register */ +#define LPC43_SPI_TCR_OFFSET 0x0010 /* SPI Test Control Register */ +#define LPC43_SPI_TSR_OFFSET 0x0014 /* SPI Test Status Register */ +#define LPC43_SPI_INT_OFFSET 0x001c /* SPI Interrupt Register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_SPI_CR (LPC43_SPI_BASE+LPC43_SPI_CR_OFFSET) +#define LPC43_SPI_SR (LPC43_SPI_BASE+LPC43_SPI_SR_OFFSET) +#define LPC43_SPI_DR (LPC43_SPI_BASE+LPC43_SPI_DR_OFFSET) +#define LPC43_SPI_CCR (LPC43_SPI_BASE+LPC43_SPI_CCR_OFFSET) +#define LPC43_TCR_CCR (LPC43_SPI_BASE+LPC43_SPI_TCR_OFFSET) +#define LPC43_TSR_CCR (LPC43_SPI_BASE+LPC43_SPI_TSR_OFFSET) +#define LPC43_SPI_INT (LPC43_SPI_BASE+LPC43_SPI_INT_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Control Register */ + /* Bits 0-1: Reserved */ +#define SPI_CR_BITENABLE (1 << 2) /* Bit 2: Enable word size selected by BITS */ +#define SPI_CR_CPHA (1 << 3) /* Bit 3: Clock phase control */ +#define SPI_CR_CPOL (1 << 4) /* Bit 4: Clock polarity control */ +#define SPI_CR_MSTR (1 << 5) /* Bit 5: Master mode select */ +#define SPI_CR_LSBF (1 << 6) /* Bit 6: SPI data is transferred LSB first */ +#define SPI_CR_SPIE (1 << 7) /* Bit 7: Serial peripheral interrupt enable */ +#define SPI_CR_BITS_SHIFT (8) /* Bits 8-11: Number of bits per word (BITENABLE==1) */ +#define SPI_CR_BITS_MASK (15 << SPI_CR_BITS_SHIFT) +# define SPI_CR_BITS_8BITS (8 << SPI_CR_BITS_SHIFT) /* 8 bits per transfer */ +# define SPI_CR_BITS_9BITS (9 << SPI_CR_BITS_SHIFT) /* 9 bits per transfer */ +# define SPI_CR_BITS_10BITS (10 << SPI_CR_BITS_SHIFT) /* 10 bits per transfer */ +# define SPI_CR_BITS_11BITS (11 << SPI_CR_BITS_SHIFT) /* 11 bits per transfer */ +# define SPI_CR_BITS_12BITS (12 << SPI_CR_BITS_SHIFT) /* 12 bits per transfer */ +# define SPI_CR_BITS_13BITS (13 << SPI_CR_BITS_SHIFT) /* 13 bits per transfer */ +# define SPI_CR_BITS_14BITS (14 << SPI_CR_BITS_SHIFT) /* 14 bits per transfer */ +# define SPI_CR_BITS_15BITS (15 << SPI_CR_BITS_SHIFT) /* 15 bits per transfer */ +# define SPI_CR_BITS_16BITS (0 << SPI_CR_BITS_SHIFT) /* 16 bits per transfer */ + /* Bits 12-31: Reserved */ +/* SPI Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_SR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_SR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_SR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_SR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_SR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Data Register */ + +#define SPI_DR_MASK (0xff) /* Bits 0-15: SPI Bi-directional data port */ +#define SPI_DR_MASKWIDE (0xffff) /* Bits 0-15: If SPI_CR_BITENABLE != 0 */ + /* Bits 8-31: Reserved */ +/* SPI Clock Counter Register */ + +#define SPI_CCR_MASK (0xff) /* Bits 0-7: SPI Clock counter setting */ + /* Bits 8-31: Reserved */ +/* SPI Test Control Register */ + /* Bit 0: Reserved */ +#define SPI_TCR_TEST_SHIFT (1) /* Bits 1-7: SPI test mode */ +#define SPI_TCR_TEST_MASK (0x7f << SPI_TCR_TEST_SHIFT) + /* Bits 8-31: Reserved */ +/* SPI Test Status Register */ + /* Bits 0-2: Reserved */ +#define SPI_TSR_ABRT (1 << 3) /* Bit 3: Slave abort */ +#define SPI_TSR_MODF (1 << 4) /* Bit 4: Mode fault */ +#define SPI_TSR_ROVR (1 << 5) /* Bit 5: Read overrun */ +#define SPI_TSR_WCOL (1 << 6) /* Bit 6: Write collision */ +#define SPI_TSR_SPIF (1 << 7) /* Bit 7: SPI transfer complete */ + /* Bits 8-31: Reserved */ +/* SPI Interrupt Register */ + +#define SPI_INT_SPIF (1 << 0) /* SPI interrupt */ + /* Bits 1-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPI_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_spifi.h b/arch/arm/src/lpc43xx/chip/lpc43_spifi.h new file mode 100644 index 0000000000000000000000000000000000000000..df70d727edf90bd0b7cd12a59a8c78ffae47cd17 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_spifi.h @@ -0,0 +1,295 @@ +/**************************************************************************** + * arch/arm/src/lpc43/chip/lpc43_spifi.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************** + * + * NOTE: The SPIFI ROM interface is not defined in the LPC43xx user manual. + * Some information in this file drivers from the NXP header file + * spifi_rom_api.h. I do not believe that any copyright restrictions apply. + * But just to be certain: + * + * 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. + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' relevant + * copyright 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 __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPIFI_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPIFI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register addresses *******************************************************/ + +#define LPC43_SPIFI_CTRL_OFFSET 0x000 +#define LPC43_SPIFI_CMD_OFFSET 0x004 +#define LPC43_SPIFI_ADDR_OFFSET 0x008 +#define LPC43_SPIFI_IDATA_OFFSET 0x00c +#define LPC43_SPIFI_CLIMIT_OFFSET 0x010 +#define LPC43_SPIFI_DATA_OFFSET 0x014 +#define LPC43_SPIFI_MCMD_OFFSET 0x018 +#define LPC43_SPIFI_STAT_OFFSET 0x01c + +#define LPC43_SPIFI_CTRL (LPC43_SPIFI_BASE+LPC43_SPIFI_CTRL_OFFSET) +#define LPC43_SPIFI_CMD (LPC43_SPIFI_BASE+LPC43_SPIFI_CMD_OFFSET) +#define LPC43_SPIFI_ADDR (LPC43_SPIFI_BASE+LPC43_SPIFI_ADDR_OFFSET) +#define LPC43_SPIFI_IDATA (LPC43_SPIFI_BASE+LPC43_SPIFI_IDATA_OFFSET) +#define LPC43_SPIFI_CLIMIT (LPC43_SPIFI_BASE+LPC43_SPIFI_CLIMIT_OFFSET) +#define LPC43_SPIFI_DATA (LPC43_SPIFI_BASE+LPC43_SPIFI_DATA_OFFSET) +#define LPC43_SPIFI_MCMD (LPC43_SPIFI_BASE+LPC43_SPIFI_MCMD_OFFSET) +#define LPC43_SPIFI_STAT (LPC43_SPIFI_BASE+LPC43_SPIFI_STAT_OFFSET) + +/* The largest protection block of any serial flash that the ROM driver + * can handle + */ + +#define SPIFI_LONGEST_PROTBLOCK 68 + +/* Protection flag bit definitions */ + +#define SPIFI_RWPROT (1 << 0) + +/* Instruction classes for wait_busy */ + +#define SPIFI_STAT_INST 0 +#define SPIFI_BLOCK_ERASE 1 +#define SPIFI_PROG_INST 2 +#define SPIFI_CHIP_ERASE 3 + +/* Bit definitions in options operands (MODE3, RCVCLK, and FULLCLK + * have the same relationship as in the Control register) + */ + +#define S_MODE3 (1 << 0) +#define S_MODE0 (0) +#define S_MINIMAL (1 << 1) +#define S_MAXIMAL (0) +#define S_FORCE_ERASE (1 << 2) +#define S_ERASE_NOT_REQD (1 << 3) +#define S_CALLER_ERASE (1 << 3) +#define S_ERASE_AS_REQD (0) +#define S_VERIFY_PROG (1 << 4) +#define S_VERIFY_ERASE (1 << 5) +#define S_NO_VERIFY (0) +#define S_FULLCLK (1 << 6) +#define S_HALFCLK (0) +#define S_RCVCLK (1 << 7) +#define S_INTCLK (0) +#define S_DUAL (1 << 8) +#define S_CALLER_PROT (1 << 9) +#define S_DRIVER_PROT (0) + +/* The length of a standard program command is 256 on all devices */ + +#define PROG_SIZE 256 + +/* SPI ROM driver table pointer */ + +#define SPIFI_ROM_PTR LPC43_ROM_DRIVER_TABLE6 +#define pSPIFI *((struct spifi_driver_s **)SPIFI_ROM_PTR) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Protection/sector descriptors */ + +struct spfi_desc_s +{ + uint32_t base; + uint8_t flags; + int8_t log2; + uint16_t rept; +}; + +/* The SPFI device state structure, passed to all ROM driver methods. */ + +struct spifi_dev_s +{ + uint32_t base; + uint32_t regbase; + uint32_t devsize; + uint32_t memsize; + + uint8_t mfger; + uint8_t devtype; + uint8_t devid; + uint8_t busy; + + union + { + uint16_t h; + uint8_t b[2]; + } stat; + uint16_t reserved; + + uint16_t setprot; + uint16_t writeprot; + + uint32_t memcmd; + uint32_t progcmd; + + uint16_t sectors; + uint16_t protbytes; + + uint32_t opts; + uint32_t errcheck; + + uint8_t eraseshifts[4]; + uint8_t eraseops[4]; + + struct spfi_desc_s *protents; + char prot[SPIFI_LONGEST_PROTBLOCK]; +}; + +/* Operands of program and erase ROM driver methods */ + +struct spifi_operands_s +{ + uint8_t *dest; + uint32_t length; + uint8_t *scratch; + int32_t protect; + uint32_t options; +}; + +/* Interface to SPIFI ROM driver */ + +#ifndef CONFIG_SPIFI_LIBRARY +struct spifi_driver_s +{ + int32_t (*spifi_init)(struct spifi_dev_s *dev, uint32_t cshigh, + uint32_t options, uint32_t mhz); + int32_t (*spifi_program)(struct spifi_dev_s *dev, const uint8_t *source, + struct spifi_operands_s *opers); + int32_t (*spifi_erase)(struct spifi_dev_s *dev, + struct spifi_operands_s *opers); + + /* Mode switching */ + + void (*cancel_mem_mode)(struct spifi_dev_s *dev); + void (*set_mem_mode)(struct spifi_dev_s *dev); + + /* Mid level functions */ + + int32_t (*checkAd)(struct spifi_dev_s *dev, + struct spifi_operands_s *opers); + int32_t (*setProt)(struct spifi_dev_s *dev, + struct spifi_operands_s *opers, uint8_t *change, uint8_t *saveprot); + int32_t (*check_block) (struct spifi_dev_s *dev, uint8_t *source, + struct spifi_operands_s *opers, uint32_t check_program); + int32_t (*send_erase_cmd)(struct spifi_dev_s *dev, uint8_t op, + uint32_t addr); + uint32_t (*ck_erase) (struct spifi_dev_s *dev, uint32_t *addr, + uint32_t length); + int32_t (*prog_block)(struct spifi_dev_s *dev, uint8_t *source, + struct spifi_operands_s *opers, uint32_t *left_in_page); + uint32_t (*ck_prog)(struct spifi_dev_s *dev, uint8_t *source, uint8_t *dest, + uint32_t length); + + /* Low level functions */ + + void (*setsize) (struct spifi_dev_s *dev, int32_t value); + int32_t (*setdev)(struct spifi_dev_s *dev, uint32_t opts, + uint32_t mem_cmd, uint32_t prog_cmd); + uint32_t (*cmd)(uint8_t op, uint8_t addrlen, uint8_t intLen, uint16_t len); + uint32_t (*readad)(struct spifi_dev_s *dev, uint32_t cmd, uint32_t addr); + void (*send04)(struct spifi_dev_s *dev, uint8_t op, uint8_t len, + uint32_t value); + void (*wren_sendad)(struct spifi_dev_s *dev, uint32_t cmd, + uint32_t addr, uint32_t value); + int32_t (*write_stat)(struct spifi_dev_s *dev, uint8_t len, + uint16_t value); + int32_t (*wait_busy)(struct spifi_dev_s *dev, uint8_t prog_or_erase); +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int32_t spifi_init(struct spifi_dev_s *dev, uint32_t cshigh, + uint32_t options, uint32_t mhz); +int32_t spifi_program(struct spifi_dev_s *dev, const uint8_t *source, + struct spifi_operands_s *opers); +int32_t spifi_erase(struct spifi_dev_s *dev, + struct spifi_operands_s *opers); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPIFI_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_ssp.h b/arch/arm/src/lpc43xx/chip/lpc43_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..2bf9340973f8a3aca76999eb4fd4e0f0cdab116a --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_ssp.h @@ -0,0 +1,171 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_ssp.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SSP_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* 8 frame FIFOs for both transmit and receive */ + +#define LPC43_SSP_FIFOSZ 8 + +/* Register offsets *****************************************************************/ + +#define LPC43_SSP_CR0_OFFSET 0x0000 /* Control Register 0 */ +#define LPC43_SSP_CR1_OFFSET 0x0004 /* Control Register 1 */ +#define LPC43_SSP_DR_OFFSET 0x0008 /* Data Register */ +#define LPC43_SSP_SR_OFFSET 0x000c /* Status Register */ +#define LPC43_SSP_CPSR_OFFSET 0x0010 /* Clock Prescale Register */ +#define LPC43_SSP_IMSC_OFFSET 0x0014 /* Interrupt Mask Set and Clear Register */ +#define LPC43_SSP_RIS_OFFSET 0x0018 /* Raw Interrupt Status Register */ +#define LPC43_SSP_MIS_OFFSET 0x001c /* Masked Interrupt Status Register */ +#define LPC43_SSP_ICR_OFFSET 0x0020 /* Interrupt Clear Register */ +#define LPC43_SSP_DMACR_OFFSET 0x0024 /* DMA Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_SSP0_CR0 (LPC43_SSP0_BASE+LPC43_SSP_CR0_OFFSET) +#define LPC43_SSP0_CR1 (LPC43_SSP0_BASE+LPC43_SSP_CR1_OFFSET) +#define LPC43_SSP0_DR (LPC43_SSP0_BASE+LPC43_SSP_DR_OFFSET) +#define LPC43_SSP0_SR (LPC43_SSP0_BASE+LPC43_SSP_SR_OFFSET) +#define LPC43_SSP0_CPSR (LPC43_SSP0_BASE+LPC43_SSP_CPSR_OFFSET) +#define LPC43_SSP0_IMSC (LPC43_SSP0_BASE+LPC43_SSP_IMSC_OFFSET) +#define LPC43_SSP0_RIS (LPC43_SSP0_BASE+LPC43_SSP_RIS_OFFSET) +#define LPC43_SSP0_MIS (LPC43_SSP0_BASE+LPC43_SSP_MIS_OFFSET) +#define LPC43_SSP0_ICR (LPC43_SSP0_BASE+LPC43_SSP_ICR_OFFSET) +#define LPC43_SSP0_DMACR (LPC43_SSP0_BASE+LPC43_SSP_DMACR_OFFSET) + +#define LPC43_SSP1_CR0 (LPC43_SSP1_BASE+LPC43_SSP_CR0_OFFSET) +#define LPC43_SSP1_CR1 (LPC43_SSP1_BASE+LPC43_SSP_CR1_OFFSET) +#define LPC43_SSP1_DR (LPC43_SSP1_BASE+LPC43_SSP_DR_OFFSET) +#define LPC43_SSP1_SR (LPC43_SSP1_BASE+LPC43_SSP_SR_OFFSET) +#define LPC43_SSP1_CPSR (LPC43_SSP1_BASE+LPC43_SSP_CPSR_OFFSET) +#define LPC43_SSP1_IMSC (LPC43_SSP1_BASE+LPC43_SSP_IMSC_OFFSET) +#define LPC43_SSP1_RIS (LPC43_SSP1_BASE+LPC43_SSP_RIS_OFFSET) +#define LPC43_SSP1_MIS (LPC43_SSP1_BASE+LPC43_SSP_MIS_OFFSET) +#define LPC43_SSP1_ICR (LPC43_SSP1_BASE+LPC43_SSP_ICR_OFFSET) +#define LPC43_SSP1_DMACR (LPC43_SSP1_BASE+LPC43_SSP_DMACR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Control Register 0 */ + +#define SSP_CR0_DSS_SHIFT (0) /* Bits 0-3: DSS Data Size Select */ +#define SSP_CR0_DSS_MASK (15 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_4BIT (3 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_5BIT (4 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_6BIT (5 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_7BIT (6 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_8BIT (7 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_9BIT (8 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_10BIT (9 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_11BIT (10 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_12BIT (11 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_13BIT (12 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_14BIT (13 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_15BIT (14 << SSP_CR0_DSS_SHIFT) +# define SSP_CR0_DSS_16BIT (15 << SSP_CR0_DSS_SHIFT) +#define SSP_CR0_FRF_SHIFT (4) /* Bits 4-5: FRF Frame Format */ +#define SSP_CR0_FRF_MASK (3 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_SPI (0 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_TI (1 << SSP_CR0_FRF_SHIFT) +# define SSP_CR0_FRF_UWIRE (2 << SSP_CR0_FRF_SHIFT) +#define SSP_CR0_CPOL (1 << 6) /* Bit 6: Clock Out Polarity */ +#define SSP_CR0_CPHA (1 << 7) /* Bit 7: Clock Out Phase */ +#define SSP_CR0_SCR_SHIFT (8) /* Bits 8-15: Serial Clock Rate */ +#define SSP_CR0_SCR_MASK (0xff << SSP_CR0_SCR_SHIFT) + /* Bits 8-31: Reserved */ +/* Control Register 1 */ + +#define SSP_CR1_LBM (1 << 0) /* Bit 0: Loop Back Mode */ +#define SSP_CR1_SSE (1 << 1) /* Bit 1: SSP Enable */ +#define SSP_CR1_MS (1 << 2) /* Bit 2: Master/Slave Mode */ +#define SSP_CR1_SOD (1 << 3) /* Bit 3: Slave Output Disable */ + /* Bits 4-31: Reserved */ +/* Data Register */ + +#define SSP_DR_MASK (0xffff) /* Bits 0-15: Data */ + /* Bits 16-31: Reserved */ +/* Status Register */ + +#define SSP_SR_TFE (1 << 0) /* Bit 0: Transmit FIFO Empty */ +#define SSP_SR_TNF (1 << 1) /* Bit 1: Transmit FIFO Not Full */ +#define SSP_SR_RNE (1 << 2) /* Bit 2: Receive FIFO Not Empty */ +#define SSP_SR_RFF (1 << 3) /* Bit 3: Receive FIFO Full */ +#define SSP_SR_BSY (1 << 4) /* Bit 4: Busy */ + /* Bits 5-31: Reserved */ +/* Clock Prescale Register */ + +#define SSP_CPSR_DVSR_MASK (0xff) /* Bits 0-7: clock = SSP_PCLK/DVSR */ + /* Bits 8-31: Reserved */ +/* Common format for interrupt control registers: + * + * Interrupt Mask Set and Clear Register (IMSC) + * Raw Interrupt Status Register (RIS) + * Masked Interrupt Status Register (MIS) + * Interrupt Clear Register (ICR) + */ + +#define SSP_INT_ROR (1 << 0) /* Bit 0: RX FIFO overrun */ +#define SSP_INT_RT (1 << 1) /* Bit 1: RX FIFO timeout */ +#define SSP_INT_RX (1 << 2) /* Bit 2: RX FIFO at least half full (not ICR) */ +#define SSP_INT_TX (1 << 3 ) /* Bit 3: TX FIFO at least half empy (not ICR) */ + /* Bits 4-31: Reserved */ +/* DMA Control Register */ + +#define SSP_DMACR_RXDMAE (1 << 0) /* Bit 0: Receive DMA Enable */ +#define SSP_DMACR_TXDMAE (1 << 1) /* Bit 1: Transmit DMA Enable */ + /* Bits 2-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SSP_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_timer.h b/arch/arm/src/lpc43xx/chip/lpc43_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..109b8c8b7fad03587f1608b37ca6fb25b8645f68 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_timer.h @@ -0,0 +1,269 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_timer.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_TIMER_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_TMR_IR_OFFSET 0x0000 /* Interrupt Register */ +#define LPC43_TMR_TCR_OFFSET 0x0004 /* Timer Control Register */ +#define LPC43_TMR_TC_OFFSET 0x0008 /* Timer Counter */ +#define LPC43_TMR_PR_OFFSET 0x000c /* Prescale Register */ +#define LPC43_TMR_PC_OFFSET 0x0010 /* Prescale Counter */ +#define LPC43_TMR_MCR_OFFSET 0x0014 /* Match Control Register */ +#define LPC43_TMR_MR0_OFFSET 0x0018 /* Match Register 0 */ +#define LPC43_TMR_MR1_OFFSET 0x001c /* Match Register 1 */ +#define LPC43_TMR_MR2_OFFSET 0x0020 /* Match Register 2 */ +#define LPC43_TMR_MR3_OFFSET 0x0024 /* Match Register 3 */ +#define LPC43_TMR_CCR_OFFSET 0x0028 /* Capture Control Register */ +#define LPC43_TMR_CR0_OFFSET 0x002c /* Capture Register 0 */ +#define LPC43_TMR_CR1_OFFSET 0x0030 /* Capture Register 1 */ +#define LPC43_TMR_CR2_OFFSET 0x0034 /* Capture Register 2 */ +#define LPC43_TMR_CR3_OFFSET 0x0038 /* Capture Register 3 */ +#define LPC43_TMR_EMR_OFFSET 0x003c /* External Match Register */ +#define LPC43_TMR_CTCR_OFFSET 0x0070 /* Count Control Register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_TMR0_IR (LPC43_TIMER0_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR0_TCR (LPC43_TIMER0_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR0_TC (LPC43_TIMER0_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR0_PR (LPC43_TIMER0_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR0_PC (LPC43_TIMER0_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR0_MCR (LPC43_TIMER0_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR0_MR0 (LPC43_TIMER0_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR0_MR1 (LPC43_TIMER0_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR0_MR2 (LPC43_TIMER0_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR0_MR3 (LPC43_TIMER0_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR0_CCR (LPC43_TIMER0_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR0_CR0 (LPC43_TIMER0_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR0_CR1 (LPC43_TIMER0_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR0_CR2 (LPC43_TIMER0_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR0_CR3 (LPC43_TIMER0_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR0_EMR (LPC43_TIMER0_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR0_CTCR (LPC43_TIMER0_BASE+LPC43_TMR_CTCR_OFFSET) + +#define LPC43_TMR1_IR (LPC43_TIMER1_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR1_TCR (LPC43_TIMER1_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR1_TC (LPC43_TIMER1_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR1_PR (LPC43_TIMER1_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR1_PC (LPC43_TIMER1_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR1_MCR (LPC43_TIMER1_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR1_MR0 (LPC43_TIMER1_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR1_MR1 (LPC43_TIMER1_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR1_MR2 (LPC43_TIMER1_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR1_MR3 (LPC43_TIMER1_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR1_CCR (LPC43_TIMER1_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR1_CR0 (LPC43_TIMER1_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR1_CR1 (LPC43_TIMER1_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR1_CR2 (LPC43_TIMER1_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR1_CR3 (LPC43_TIMER1_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR1_EMR (LPC43_TIMER1_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR1_CTCR (LPC43_TIMER1_BASE+LPC43_TMR_CTCR_OFFSET) + +#define LPC43_TMR2_IR (LPC43_TIMER2_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR2_TCR (LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR2_TC (LPC43_TIMER2_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR2_PR (LPC43_TIMER2_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR2_PC (LPC43_TIMER2_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR2_MCR (LPC43_TIMER2_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR2_MR0 (LPC43_TIMER2_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR2_MR1 (LPC43_TIMER2_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR2_MR2 (LPC43_TIMER2_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR2_MR3 (LPC43_TIMER2_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR2_CCR (LPC43_TIMER2_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR2_CR0 (LPC43_TIMER2_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR2_CR1 (LPC43_TIMER2_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR2_CR2 (LPC43_TIMER2_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR2_CR3 (LPC43_TIMER2_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR2_EMR (LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR2_CTCR (LPC43_TIMER2_BASE+LPC43_TMR_CTCR_OFFSET) + +#define LPC43_TMR3_IR (LPC43_TIMER3_BASE+LPC43_TMR_IR_OFFSET) +#define LPC43_TMR3_TCR (LPC43_TIMER3_BASE+LPC43_TMR_TCR_OFFSET) +#define LPC43_TMR3_TC (LPC43_TIMER3_BASE+LPC43_TMR_TC_OFFSET) +#define LPC43_TMR3_PR (LPC43_TIMER3_BASE+LPC43_TMR_PR_OFFSET) +#define LPC43_TMR3_PC (LPC43_TIMER3_BASE+LPC43_TMR_PC_OFFSET) +#define LPC43_TMR3_MCR (LPC43_TIMER3_BASE+LPC43_TMR_MCR_OFFSET) +#define LPC43_TMR3_MR0 (LPC43_TIMER3_BASE+LPC43_TMR_MR0_OFFSET) +#define LPC43_TMR3_MR1 (LPC43_TIMER3_BASE+LPC43_TMR_MR1_OFFSET) +#define LPC43_TMR3_MR2 (LPC43_TIMER3_BASE+LPC43_TMR_MR2_OFFSET) +#define LPC43_TMR3_MR3 (LPC43_TIMER3_BASE+LPC43_TMR_MR3_OFFSET) +#define LPC43_TMR3_CCR (LPC43_TIMER3_BASE+LPC43_TMR_CCR_OFFSET) +#define LPC43_TMR3_CR0 (LPC43_TIMER3_BASE+LPC43_TMR_CR0_OFFSET) +#define LPC43_TMR3_CR1 (LPC43_TIMER3_BASE+LPC43_TMR_CR1_OFFSET) +#define LPC43_TMR3_CR2 (LPC43_TIMER3_BASE+LPC43_TMR_CR2_OFFSET) +#define LPC43_TMR3_CR3 (LPC43_TIMER3_BASE+LPC43_TMR_CR3_OFFSET) +#define LPC43_TMR3_EMR (LPC43_TIMER3_BASE+LPC43_TMR_EMR_OFFSET) +#define LPC43_TMR3_CTCR (LPC43_TIMER3_BASE+LPC43_TMR_CTCR_OFFSET) + +/* Register bit definitions *********************************************************/ +/* Registers holding 32-bit numeric values (no bit field definitions): + * + * Timer Counter (TC) + * Prescale Register (PR) + * Prescale Counter (PC) + * Match Register 0 (MR0) + * Match Register 1 (MR1) + * Match Register 2 (MR2) + * Match Register 3 (MR3) + * Capture Register 0 (CR0) + * Capture Register 1 (CR1) + * Capture Register 2 (CR2) + * Capture Register 3 (CR3) + */ + +/* Interrupt Register */ + +#define TMR_IR_MR0 (1 << 0) /* Bit 0: Match channel 0 interrupt */ +#define TMR_IR_MR1 (1 << 1) /* Bit 1: Match channel 1 interrupt */ +#define TMR_IR_MR2 (1 << 2) /* Bit 2: Match channel 2 interrupt */ +#define TMR_IR_MR3 (1 << 3) /* Bit 3: Match channel 3 interrupt */ +#define TMR_IR_CR0 (1 << 4) /* Bit 4: Capture channel 0 interrupt */ +#define TMR_IR_CR1 (1 << 5) /* Bit 5: Capture channel 1 interrupt */ +#define TMR_IR_CR2 (1 << 6) /* Bit 6: Capture channel 2 interrupt */ +#define TMR_IR_CR3 (1 << 7) /* Bit 7: Capture channel 3 interrupt */ + /* Bits 8-31: Reserved */ +/* Timer Control Register */ + +#define TMR_TCR_EN (1 << 0) /* Bit 0: Counter Enable */ +#define TMR_TCR_RESET (1 << 1) /* Bit 1: Counter Reset */ + /* Bits 2-31: Reserved */ +/* Match Control Register */ + +#define TMR_MCR_MR0I (1 << 0) /* Bit 0: Interrupt on MR0 */ +#define TMR_MCR_MR0R (1 << 1) /* Bit 1: Reset on MR0 */ +#define TMR_MCR_MR0S (1 << 2) /* Bit 2: Stop on MR0 */ +#define TMR_MCR_MR1I (1 << 3) /* Bit 3: Interrupt on MR1 */ +#define TMR_MCR_MR1R (1 << 4) /* Bit 4: Reset on MR1 */ +#define TMR_MCR_MR1S (1 << 5) /* Bit 5: Stop on MR1 */ +#define TMR_MCR_MR2I (1 << 6) /* Bit 6: Interrupt on MR2 */ +#define TMR_MCR_MR2R (1 << 7) /* Bit 7: Reset on MR2 */ +#define TMR_MCR_MR2S (1 << 8) /* Bit 8: Stop on MR2 */ +#define TMR_MCR_MR3I (1 << 9) /* Bit 9: Interrupt on MR3 */ +#define TMR_MCR_MR3R (1 << 10) /* Bit 10: Reset on MR3 */ +#define TMR_MCR_MR3S (1 << 11) /* Bit 11: Stop on MR3 */ + /* Bits 12-31: Reserved */ +/* Capture Control Register */ + +#define TMR_CCR_CAP0RE (1 << 0) /* Bit 0: Capture on CAPn.0 rising edge */ +#define TMR_CCR_CAP0FE (1 << 1) /* Bit 1: Capture on CAPn.0 falling edg3 */ +#define TMR_CCR_CAP0I (1 << 2) /* Bit 2: Interrupt on CAPn.0 */ +#define TMR_CCR_CAP1RE (1 << 3) /* Bit 3: Capture on CAPn.1 rising edge */ +#define TMR_CCR_CAP1FE (1 << 4) /* Bit 4: Capture on CAPn.1 falling edg3 */ +#define TMR_CCR_CAP1I (1 << 5) /* Bit 5: Interrupt on CAPn.1 */ +#define TMR_CCR_CAP2RE (1 << 6) /* Bit 6: Capture on CAPn.2 rising edge */ +#define TMR_CCR_CAP2FE (1 << 7) /* Bit 7: Capture on CAPn.2 falling edg3 */ +#define TMR_CCR_CAP2I (1 << 8) /* Bit 8: Interrupt on CAPn.2 */ +#define TMR_CCR_CAP3RE (1 << 9) /* Bit 9: Capture on CAPn.3 rising edge */ +#define TMR_CCR_CAP3FE (1 << 10) /* Bit 10: Capture on CAPn.3 falling edg3 */ +#define TMR_CCR_CAP3I (1 << 11) /* Bit 11: Interrupt on CAPn.3 */ + /* Bits 12-31: Reserved */ +/* External Match Register */ + +#define TMR_EMR_NOTHING (0) /* Do Nothing */ +#define TMR_EMR_CLEAR (1) /* Clear external match bit MATn.m */ +#define TMR_EMR_SET (2) /* Set external match bit MATn.m */ +#define TMR_EMR_TOGGLE (3) /* Toggle external match bit MATn.m */ + +#define TMR_EMR_EM0 (1 << 0) /* Bit 0: External Match 0 */ +#define TMR_EMR_EM1 (1 << 1) /* Bit 1: External Match 1 */ +#define TMR_EMR_EM2 (1 << 2) /* Bit 2: External Match 2 */ +#define TMR_EMR_EM3 (1 << 3) /* Bit 3: External Match 3 */ +#define TMR_EMR_EMC0_SHIFT (4) /* Bits 4-5: External Match Control 0 */ +#define TMR_EMR_EMC0_MASK (3 << TMR_EMR_EMC0_SHIFTy) +# define TMR_EMR_EMC0_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_SET (TMR_EMR_SET << TMR_EMR_EMC0_SHIFT) +# define TMR_EMR_EMC0_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC0_SHIFT) +#define TMR_EMR_EMC1_SHIFT (6) /* Bits 6-7: External Match Control 1 */ +#define TMR_EMR_EMC1_MASK (3 << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_SET (TMR_EMR_SET << TMR_EMR_EMC1_SHIFT) +# define TMR_EMR_EMC1_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC1_SHIFT) +#define TMR_EMR_EMC2_SHIFT (8) /* Bits 8-9: External Match Control 2 */ +#define TMR_EMR_EMC2_MASK (3 << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_SET (TMR_EMR_SET << TMR_EMR_EMC2_SHIFT) +# define TMR_EMR_EMC2_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC2_SHIFT) +#define TMR_EMR_EMC3_SHIFT (10) /* Bits 10-11: External Match Control 3 */ +#define TMR_EMR_EMC3_MASK (3 << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_NOTHING (TMR_EMR_NOTHING << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_CLEAR (TMR_EMR_CLEAR << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_SET (TMR_EMR_SET << TMR_EMR_EMC3_SHIFT) +# define TMR_EMR_EMC3_TOGGLE (TMR_EMR_TOGGLE << TMR_EMR_EMC3_SHIFT) + /* Bits 12-31: Reserved */ +/* Count Control Register */ + +#define TMR_CTCR_MODE_SHIFT (0) /* Bits 0-1: Counter/Timer Mode */ +#define TMR_CTCR_MODE_MASK (3 << TMR_CTCR_MODE_SHIFT) +# define TMR_CTCR_MODE_TIMER (0 << TMR_CTCR_MODE_SHIFT) /* Timer ModeMode: Rising PCLK edge */ +# define TMR_CTCR_MODE_CNTRRE (1 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP rising edge */ +# define TMR_CTCR_MODE_CNTRFE (2 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP falling edge */ +# define TMR_CTCR_MODE_CNTRBE (3 << TMR_CTCR_MODE_SHIFT) /* Counter Mode, CAP both edges */ +#define TMR_CTCR_INSEL_SHIFT (2) /* Bits 2-3: Count Input Select */ +#define TMR_CTCR_INSEL_MASK (3 << TMR_CTCR_INSEL_SHIFT) +# define TMR_CTCR_INSEL_CAPNp0 (0 << TMR_CTCR_INSEL_SHIFT) /* CAPn.0 for TIMERn */ +# define TMR_CTCR_INSEL_CAPNp1 (1 << TMR_CTCR_INSEL_SHIFT) /* CAPn.1 for TIMERn */ +# define TMR_CTCR_INSEL_CAPNp2 (2 << TMR_CTCR_INSEL_SHIFT) /* CAPn.2 for TIMERn */ +# define TMR_CTCR_INSEL_CAPNp3 (3 << TMR_CTCR_INSEL_SHIFT) /* CAPn.3 for TIMERn */ + /* Bits 4-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_TIMER_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_uart.h b/arch/arm/src/lpc43xx/chip/lpc43_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..a0ea29718ab1282b73e264b67254968b7f400e11 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_uart.h @@ -0,0 +1,397 @@ +/******************************************************************************************** + * arch/arm/src/lpc43xx/lpc43_uart.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_UART_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_UART_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Register offsets *************************************************************************/ +/* Common Register Offsets */ + +#define LPC43_UART_RBR_OFFSET 0x0000 /* (DLAB =0) Receiver Buffer Register */ +#define LPC43_UART_THR_OFFSET 0x0000 /* (DLAB =0) Transmit Holding Register */ +#define LPC43_UART_DLL_OFFSET 0x0000 /* (DLAB =1) Divisor Latch LSB */ +#define LPC43_UART_DLM_OFFSET 0x0004 /* (DLAB =1) Divisor Latch MSB */ +#define LPC43_UART_IER_OFFSET 0x0004 /* (DLAB =0) Interrupt Enable Register */ +#define LPC43_UART_IIR_OFFSET 0x0008 /* Interrupt ID Register */ +#define LPC43_UART_FCR_OFFSET 0x0008 /* FIFO Control Register */ +#define LPC43_UART_LCR_OFFSET 0x000c /* Line Control Register */ +#define LPC43_UART_LSR_OFFSET 0x0014 /* Line Status Register */ +#define LPC43_UART_SCR_OFFSET 0x001c /* Scratch Pad Register */ +#define LPC43_UART_ACR_OFFSET 0x0020 /* Auto-baud Control Register */ +#define LPC43_UART_FDR_OFFSET 0x0028 /* Fractional Divider Register */ + +#define LPC43_UART_RS485CTRL_OFFSET 0x004c /* RS-485/EIA-485 Control */ +#define LPC43_UART_ADRMATCH_OFFSET 0x0050 /* RS-485/EIA-485 address match */ +#define LPC43_UART_RS485DLY_OFFSET 0x0054 /* RS-485/EIA-485 direction control delay */ + +/* Registers available only on UART1 */ + +#define LPC43_UART_MCR_OFFSET 0x0010 /* Modem Control Register */ +#define LPC43_UART_MSR_OFFSET 0x0018 /* Modem Status Register */ +#define LPC43_UART_TER_OFFSET 0x0030 /* Transmit Enable Register */ + +/* Registers available only on USART0,2,3 */ + +#define LPC43_USART_ICR_OFFSET 0x0024 /* IrDA Control Register */ +#define LPC43_USART_OSR_OFFSET 0x002c /* Oversampling Register */ +#define LPC43_USART_HDEN_OFFSET 0x0040 /* Half-duplex enable Register */ +#define LPC43_USART_SCICTRL_OFFSET 0x0048 /* Smart card interface control register */ +#define LPC43_USART_SYNCCTRL_OFFSET 0x0058 /* Synchronous mode control register */ +#define LPC43_USART_TER_OFFSET 0x005c /* Transmit Enable Register */ + +/* Register addresses ***********************************************************************/ + +#define LPC43_USART0_RBR (LPC43_USART0_BASE+LPC43_UART_RBR_OFFSET) +#define LPC43_USART0_THR (LPC43_USART0_BASE+LPC43_UART_THR_OFFSET) +#define LPC43_USART0_DLL (LPC43_USART0_BASE+LPC43_UART_DLL_OFFSET) +#define LPC43_USART0_DLM (LPC43_USART0_BASE+LPC43_UART_DLM_OFFSET) +#define LPC43_USART0_IER (LPC43_USART0_BASE+LPC43_UART_IER_OFFSET) +#define LPC43_USART0_IIR (LPC43_USART0_BASE+LPC43_UART_IIR_OFFSET) +#define LPC43_USART0_FCR (LPC43_USART0_BASE+LPC43_UART_FCR_OFFSET) +#define LPC43_USART0_LCR (LPC43_USART0_BASE+LPC43_UART_LCR_OFFSET) +#define LPC43_USART0_LSR (LPC43_USART0_BASE+LPC43_UART_LSR_OFFSET) +#define LPC43_USART0_SCR (LPC43_USART0_BASE+LPC43_UART_SCR_OFFSET) +#define LPC43_USART0_ACR (LPC43_USART0_BASE+LPC43_UART_ACR_OFFSET) +#define LPC43_USART0_ICR (LPC43_USART0_BASE+LPC43_USART_ICR_OFFSET) +#define LPC43_USART0_FDR (LPC43_USART0_BASE+LPC43_UART_FDR_OFFSET) +#define LPC43_USART0_OSR (LPC43_USART0_BASE+LPC43_USART_OSR_OFFSET) +#define LPC43_USART0_HDEM (LPC43_USART0_BASE+LPC43_USART_HDEN_OFFSET) +#define LPC43_USART0_SCICTRL (LPC43_USART0_BASE+LPC43_USART_SCICTRL_OFFSET) +#define LPC43_USART0_RS485CTRL (LPC43_USART0_BASE+LPC43_UART_RS485CTRL_OFFSET) +#define LPC43_USART0_ADRMATCH (LPC43_USART0_BASE+LPC43_UART_ADRMATCH_OFFSET) +#define LPC43_USART0_RS485DLY (LPC43_USART0_BASE+LPC43_UART_RS485DLY_OFFSET) +#define LPC43_USART0_SYNCCTRL (LPC43_USART0_BASE+LPC43_USART_SYNCCTRL_OFFSET) +#define LPC43_USART0_TER (LPC43_USART0_BASE+LPC43_USART_TER_OFFSET) + +#define LPC43_UART1_RBR (LPC43_UART1_BASE+LPC43_UART_RBR_OFFSET) +#define LPC43_UART1_THR (LPC43_UART1_BASE+LPC43_UART_THR_OFFSET) +#define LPC43_UART1_DLL (LPC43_UART1_BASE+LPC43_UART_DLL_OFFSET) +#define LPC43_UART1_DLM (LPC43_UART1_BASE+LPC43_UART_DLM_OFFSET) +#define LPC43_UART1_IER (LPC43_UART1_BASE+LPC43_UART_IER_OFFSET) +#define LPC43_UART1_IIR (LPC43_UART1_BASE+LPC43_UART_IIR_OFFSET) +#define LPC43_UART1_FCR (LPC43_UART1_BASE+LPC43_UART_FCR_OFFSET) +#define LPC43_UART1_LCR (LPC43_UART1_BASE+LPC43_UART_LCR_OFFSET) +#define LPC43_UART1_MCR (LPC43_UART1_BASE+LPC43_UART_MCR_OFFSET) +#define LPC43_UART1_LSR (LPC43_UART1_BASE+LPC43_UART_LSR_OFFSET) +#define LPC43_UART1_MSR (LPC43_UART1_BASE+LPC43_UART_MSR_OFFSET) +#define LPC43_UART1_SCR (LPC43_UART1_BASE+LPC43_UART_SCR_OFFSET) +#define LPC43_UART1_ACR (LPC43_UART1_BASE+LPC43_UART_ACR_OFFSET) +#define LPC43_UART1_FDR (LPC43_UART1_BASE+LPC43_UART_FDR_OFFSET) +#define LPC43_UART1_TER (LPC43_UART1_BASE+LPC43_UART_TER_OFFSET) +#define LPC43_UART1_RS485CTRL (LPC43_UART1_BASE+LPC43_UART_RS485CTRL_OFFSET) +#define LPC43_UART1_ADRMATCH (LPC43_UART1_BASE+LPC43_UART_ADRMATCH_OFFSET) +#define LPC43_UART1_RS485DLY (LPC43_UART1_BASE+LPC43_UART_RS485DLY_OFFSET) + +#define LPC43_USART1_RBR (LPC43_USART1_BASE+LPC43_UART_RBR_OFFSET) +#define LPC43_USART1_THR (LPC43_USART1_BASE+LPC43_UART_THR_OFFSET) +#define LPC43_USART1_DLL (LPC43_USART1_BASE+LPC43_UART_DLL_OFFSET) +#define LPC43_USART1_DLM (LPC43_USART1_BASE+LPC43_UART_DLM_OFFSET) +#define LPC43_USART1_IER (LPC43_USART1_BASE+LPC43_UART_IER_OFFSET) +#define LPC43_USART1_IIR (LPC43_USART1_BASE+LPC43_UART_IIR_OFFSET) +#define LPC43_USART1_FCR (LPC43_USART1_BASE+LPC43_UART_FCR_OFFSET) +#define LPC43_USART1_LCR (LPC43_USART1_BASE+LPC43_UART_LCR_OFFSET) +#define LPC43_USART1_LSR (LPC43_USART1_BASE+LPC43_UART_LSR_OFFSET) +#define LPC43_USART1_SCR (LPC43_USART1_BASE+LPC43_UART_SCR_OFFSET) +#define LPC43_USART1_ACR (LPC43_USART1_BASE+LPC43_UART_ACR_OFFSET) +#define LPC43_USART1_ICR (LPC43_USART1_BASE+LPC43_USART_ICR_OFFSET) +#define LPC43_USART1_FDR (LPC43_USART1_BASE+LPC43_UART_FDR_OFFSET) +#define LPC43_USART1_OSR (LPC43_USART1_BASE+LPC43_USART_OSR_OFFSET) +#define LPC43_USART1_HDEM (LPC43_USART1_BASE+LPC43_USART_HDEN_OFFSET) +#define LPC43_USART1_SCICTRL (LPC43_USART1_BASE+LPC43_USART_SCICTRL_OFFSET) +#define LPC43_USART1_RS485CTRL (LPC43_USART1_BASE+LPC43_UART_RS485CTRL_OFFSET) +#define LPC43_USART1_ADRMATCH (LPC43_USART1_BASE+LPC43_UART_ADRMATCH_OFFSET) +#define LPC43_USART1_RS485DLY (LPC43_USART1_BASE+LPC43_UART_RS485DLY_OFFSET) +#define LPC43_USART1_SYNCCTRL (LPC43_USART1_BASE+LPC43_USART_SYNCCTRL_OFFSET) +#define LPC43_USART1_TER (LPC43_USART1_BASE+LPC43_USART_TER_OFFSET) + +#define LPC43_USART2_RBR (LPC43_USART2_BASE+LPC43_UART_RBR_OFFSET) +#define LPC43_USART2_THR (LPC43_USART2_BASE+LPC43_UART_THR_OFFSET) +#define LPC43_USART2_DLL (LPC43_USART2_BASE+LPC43_UART_DLL_OFFSET) +#define LPC43_USART2_DLM (LPC43_USART2_BASE+LPC43_UART_DLM_OFFSET) +#define LPC43_USART2_IER (LPC43_USART2_BASE+LPC43_UART_IER_OFFSET) +#define LPC43_USART2_IIR (LPC43_USART2_BASE+LPC43_UART_IIR_OFFSET) +#define LPC43_USART2_FCR (LPC43_USART2_BASE+LPC43_UART_FCR_OFFSET) +#define LPC43_USART2_LCR (LPC43_USART2_BASE+LPC43_UART_LCR_OFFSET) +#define LPC43_USART2_LSR (LPC43_USART2_BASE+LPC43_UART_LSR_OFFSET) +#define LPC43_USART2_SCR (LPC43_USART2_BASE+LPC43_UART_SCR_OFFSET) +#define LPC43_USART2_ACR (LPC43_USART2_BASE+LPC43_UART_ACR_OFFSET) +#define LPC43_USART2_ICR (LPC43_USART2_BASE+LPC43_USART_ICR_OFFSET) +#define LPC43_USART2_FDR (LPC43_USART2_BASE+LPC43_UART_FDR_OFFSET) +#define LPC43_USART2_OSR (LPC43_USART2_BASE+LPC43_USART_OSR_OFFSET) +#define LPC43_USART2_HDEM (LPC43_USART2_BASE+LPC43_USART_HDEN_OFFSET) +#define LPC43_USART2_SCICTRL (LPC43_USART2_BASE+LPC43_USART_SCICTRL_OFFSET) +#define LPC43_USART2_RS485CTRL (LPC43_USART2_BASE+LPC43_UART_RS485CTRL_OFFSET) +#define LPC43_USART2_ADRMATCH (LPC43_USART2_BASE+LPC43_UART_ADRMATCH_OFFSET) +#define LPC43_USART2_RS485DLY (LPC43_USART2_BASE+LPC43_UART_RS485DLY_OFFSET) +#define LPC43_USART2_SYNCCTRL (LPC43_USART2_BASE+LPC43_USART_SYNCCTRL_OFFSET) +#define LPC43_USART2_TER (LPC43_USART2_BASE+LPC43_USART_TER_OFFSET) + +/* Register bit definitions *****************************************************************/ + +/* RBR (DLAB =0) Receiver Buffer Register */ + +#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */ + /* Bits 8-31: Reserved */ + +/* THR (DLAB =0) Transmit Holding Register */ + +#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */ + /* Bits 8-31: Reserved */ + +/* DLL (DLAB =1) Divisor Latch LSB */ + +#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */ + /* Bits 8-31: Reserved */ + +/* DLM (DLAB =1) Divisor Latch MSB */ + +#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */ + /* Bits 8-31: Reserved */ + +/* IER (DLAB =0) Interrupt Enable Register */ + +#define UART_IER_RBRIE (1 << 0) /* Bit 0: RBR Interrupt Enable */ +#define UART_IER_THREIE (1 << 1) /* Bit 1: THRE Interrupt Enable */ +#define UART_IER_RXIE (1 << 2) /* Bit 2: RX Line Status Interrupt Enable */ +#define UART_IER_MSIE (1 << 3) /* Bit 3: Modem Status Interrupt Enable (UART only) */ + /* Bits 4-6: Reserved */ +#define UART_IER_CTSIE (1 << 7) /* Bit 7: CTS transition interrupt (UART only) */ +#define UART_IER_ABEOIE (1 << 8) /* Bit 8: Enables the end of auto-baud interrupt */ +#define UART_IER_ABTOIE (1 << 9) /* Bit 9: Enables the auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +#define UART_IER_ALLIE (0x038f) +#define USART_IER_ALLIE (0x0307) + +/* IIR Interrupt ID Register */ + +#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */ +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status (UART only) */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THRE Interrupt */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* 2a - Receive Data Available (RDA) */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* 1 - Receive Line Status (RLS) */ +# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* 2b - Character Time-out Indicator (CTI) */ + /* Bits 4-5: Reserved */ +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: Copies of FCR[0] */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) +#define UART_IIR_ABEOINT (1 << 8) /* Bit 8: End of auto-baud interrupt */ +#define UART_IIR_ABTOINT (1 << 9) /* Bit 9: Auto-baud time-out interrupt */ + /* Bits 10-31: Reserved */ +/* FCR FIFO Control Register */ + +#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */ +#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */ +#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA Mode Select */ + /* Bits 4-5: Reserved */ +#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */ +#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT) +# define UART_FCR_RXTRIGGER_0 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 char) */ +# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 chars) */ +# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 chars) */ +# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 chars) */ + /* Bits 8-31: Reserved */ +/* LCR Line Control Register */ + +#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_STOP (1 << 2) /* Bit 2: Stop Bit Select */ +#define UART_LCR_PE (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_PS_SHIFT (4) /* Bits 4-5: Parity Select */ +#define UART_LCR_PS_MASK (3 << UART_LCR_PS_SHIFT) +# define UART_LCR_PS_ODD (0 << UART_LCR_PS_SHIFT) /* Odd parity */ +# define UART_LCR_PS_EVEN (1 << UART_LCR_PS_SHIFT) /* Even Parity */ +# define UART_LCR_PS_STICKY1 (2 << UART_LCR_PS_SHIFT) /* Forced "1" stick parity */ +# define UART_LCR_PS_STICKY0 (3 << UART_LCR_PS_SHIFT) /* Forced "0" stick parity */ +#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */ + /* Bits 8-31: Reserved */ +/* MCR Modem Control Register (UART only) */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */ + /* Bits 2-3: Reserved */ +#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */ + /* Bit 5: Reserved */ +#define UART_MCR_RTSEN (1 << 6) /* Bit 6: Enable auto-RTS flow control */ +#define UART_MCR_CTSEN (1 << 7) /* Bit 7: Enable auto-CTS flow control */ + /* Bits 8-31: Reserved */ +/* LSR Line Status Register */ + +#define UART_LSR_RDR (1 << 0) /* Bit 0: Receiver Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */ +#define USART_LSR_RXFE (1 << 8) /* Bit 8: Error in transmitted char (USART onlY) */ + /* Bits 8-31: Reserved */ +/* MSR Modem Status Register (UART only) */ + +#define UART_MSR_DCTS (1 << 0) /* Bit 0: Delta CTS. CTS state change */ +#define UART_MSR_DDSR (1 << 1) /* Bit 1: Delta DSR. DSR state change */ +#define UART_MSR_TERI (1 << 2) /* Bit 2: Trailing Edge RI */ +#define UART_MSR_DDCD (1 << 3) /* Bit 3: Delta DCD. DCD state change */ +#define UART_MSR_CTS (1 << 4) /* Bit 4: CTS State */ +#define UART_MSR_DSR (1 << 5) /* Bit 5: DSR State */ +#define UART_MSR_RI (1 << 6) /* Bit 6: Ring Indicator State */ +#define UART_MSR_DCD (1 << 7) /* Bit 7: Data Carrier Detect State */ + /* Bits 8-31: Reserved */ +/* SCR Scratch Pad Register */ + +#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */ + /* Bits 8-31: Reserved */ +/* ACR Auto-baud Control Register */ + +#define UART_ACR_START (1 << 0) /* Bit 0: Auto-baud start/running */ +#define UART_ACR_MODE (1 << 1) /* Bit 1: Auto-baud mode select */ +#define UART_ACR_AUTORESTART (1 << 2) /* Bit 2: Restart in case of time-out */ + /* Bits 3-7: Reserved */ +#define UART_ACR_ABEOINTCLR (1 << 8) /* Bit 8: End of auto-baud interrupt clear */ +#define UART_ACR_ABTOINTCLRT (1 << 9) /* Bit 9: Auto-baud time-out interrupt clear */ + /* Bits 10-31: Reserved */ +/* ICA IrDA Control Register (USART0,2,3 only) */ + +#define UART_ICR_IRDAEN (1 << 0) /* Bit 0: Enable IrDA mode */ +#define UART_ICR_IRDAINV (1 << 1) /* Bit 1: Invert serial input */ +#define UART_ICR_FIXPULSEEN (1 << 2) /* Bit 2: Enable IrDA fixed pulse width mode */ +#define UART_ICR_PULSEDIV_SHIFT (3) /* Bits 3-5: Configures the pulse when FixPulseEn = 1 */ +#define UART_ICR_PULSEDIV_MASK (7 << UART_ICR_PULSEDIV_SHIFT) +# define UART_ICR_PULSEDIV_2TPCLK (0 << UART_ICR_PULSEDIV_SHIFT) /* 2 x TPCLK */ +# define UART_ICR_PULSEDIV_4TPCLK (1 << UART_ICR_PULSEDIV_SHIFT) /* 4 x TPCLK */ +# define UART_ICR_PULSEDIV_8TPCLK (2 << UART_ICR_PULSEDIV_SHIFT) /* 8 x TPCLK */ +# define UART_ICR_PULSEDIV_16TPCLK (3 << UART_ICR_PULSEDIV_SHIFT) /* 16 x TPCLK */ +# define UART_ICR_PULSEDIV_32TPCLK (4 << UART_ICR_PULSEDIV_SHIFT) /* 32 x TPCLK */ +# define UART_ICR_PULSEDIV_64TPCLK (5 << UART_ICR_PULSEDIV_SHIFT) /* 64 x TPCLK */ +# define UART_ICR_PULSEDIV_128TPCLK (6 << UART_ICR_PULSEDIV_SHIFT) /* 128 x TPCLK */ +# define UART_ICR_PULSEDIV_256TPCLK (7 << UART_ICR_PULSEDIV_SHIFT) /* 256 x TPCLK */ + /* Bits 6-31: Reserved */ +/* FDR Fractional Divider Register */ + +#define UART_FDR_DIVADDVAL_SHIFT (0) /* Bits 0-3: Baud-rate generation pre-scaler divisor value */ +#define UART_FDR_DIVADDVAL_MASK (15 << UART_FDR_DIVADDVAL_SHIFT) +#define UART_FDR_MULVAL_SHIFT (4) /* Bits 4-7 Baud-rate pre-scaler multiplier value */ +#define UART_FDR_MULVAL_MASK (15 << UART_FDR_MULVAL_SHIFT) + /* Bits 8-31: Reserved */ +/* Oversampling Register (USART only) */ + /* Bit 0: Reserved */ +#define USART_OSR_OSFRAC_SHIFT (1) /* Bits 1-3: Fractional part of the oversampling ratio */ +#define USART_OSR_OSFRAC_MASK (7 << USART_OSR_OSFRAC_SHIFT) +#define USART_OSR_OSINT_SHIFT (4) /* Bits 4-7: Integer part of the oversampling ratio */ +#define USART_OSR_OSINT_MASK (15 << USART_OSR_OSINT_SHIFT) +#define USART_OSR_FDINT_SHIFT (8) /* Bits 8-14: Extension for Smart Card mode */ +#define USART_OSR_FDINT_MASK (0x7f << USART_OSR_FDINT_SHIFT) + /* Bits 15-31: Reserved */ +/* TER Transmit Enable Register (UART only) */ + /* Bits 0-6: Reserved */ +#define UART_TER_TXEN (1 << 7) /* Bit 7: TX Enable */ + /* Bits 8-31: Reserved */ +/* Half-duplex enable Register (USART only) */ + +#define USART_HDEN_TXEN (1 << 0) /* Bit 0: Half-duplex mode enable */ + /* Bits 1-31: Reserved */ +/* Smart card interface control register (USART only) */ + +#define USART_SCICTRL_SCIEN (1 << 0) /* Bit 0: Smart Card Interface Enable */ +#define USART_SCICTRL_NACKDIS (1 << 1) /* Bit 1: NACK response disable */ +#define USART_SCICTRL_PROTSEL (1 << 2) /* Bit 2: Protocol selection */ + /* Bits 3-4: Reserved */ +#define USART_SCICTRL_TXRETRY_SHIFT (5) /* Bits 5-7: Maximum number of retransmissions */ +#define USART_SCICTRL_TXRETRY_MASK (7 << USART_SCICTRL_TXRETRY_SHIFT) +#define USART_SCICTRL_GUARDTIME_SHIFT (8) /* Bits 8-15: Extra guard time */ +#define USART_SCICTRL_GUARDTIME_MASK (0xff << USART_SCICTRL_GUARDTIME_SHIFT) + /* Bits 16-31: Reserved */ +/* RS-485/EIA-485 Control */ + +#define UART_RS485CTRL_NMMEN (1 << 0) /* Bit 0: RS-485/EIA-485 Normal Multidrop Mode (NMM) enabled */ +#define UART_RS485CTRL_RXDIS (1 << 1) /* Bit 1: Receiver is disabled */ +#define UART_RS485CTRL_AADEN (1 << 2) /* Bit 2: Auto Address Detect (AAD) is enabled */ +#define UART_RS485CTRL_SEL (1 << 3) /* Bit 3: RTS/DTR used for direction control (DCTRL=1) */ +#define UART_RS485CTRL_DCTRL (1 << 4) /* Bit 4: Enable Auto Direction Control */ +#define UART_RS485CTRL_OINV (1 << 5) /* Bit 5: Polarity of the direction control signal on RTS/DTR */ + /* Bits 6-31: Reserved */ +/* RS-485/EIA-485 address match */ + +#define UART_ADRMATCH_MASK (0xff) /* Bits 0-7: Address match value */ + /* Bits 8-31: Reserved */ +/* RS-485/EIA-485 direction control delay */ + +#define UART_RS485DLY_MASK (0xff) /* Bits 0-7: Firection control (RTS/DTR) delay */ + /* Bits 8-31: Reserved */ +/* Synchronous mode control register (USART only) */ + +#define USART_SYNCCTRL_SYNC (1 << 0) /* Bit 0: Enables synchronous mode */ +#define USART_SYNCCTRL_CSRC (1 << 1) /* Bit 1: Clock source select */ +#define USART_SYNCCTRL_FES (1 << 2) /* Bit 2: Falling edge sampling */ +#define USART_SYNCCTRL_TSBYPASS (1 << 3) /* Bit 3: Transmit synchronization bypass */ +#define USART_SYNCCTRL_CSCEN (1 << 4) /* Bit 4: Continuous master clock enable */ +#define USART_SYNCCTRL_SSSDIS (1 << 5) /* Bit 5: Start/stop bits */ +#define USART_SYNCCTRL_CCCLR (1 << 6) /* Bit 6: Continuous clock clear */ + /* Bits 7-31: Reserved */ +/* TER Transmit Enable Register (USART only) */ + +#define USART_TER_TXEN (1 << 0) /* Bit 0: TX Enable */ + /* Bits 1-31: Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_UART_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_usb0.h b/arch/arm/src/lpc43xx/chip/lpc43_usb0.h new file mode 100644 index 0000000000000000000000000000000000000000..caa4c86cc2faaa6618ac3b193dbb0101b39aaf22 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_usb0.h @@ -0,0 +1,718 @@ +/************************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_usb0.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_USB0_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_USB0_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Register Offsets *****************************************************************************/ + /* 0x000 - 0x0ff: Reserved */ +/* Device/host capability registers */ + +#define LPC43_USBOTG_HCCR_OFFSET 0x0100 /* Offset to EHCI Host Controller Capabiliy registers */ +#define LPC43_USBOTG_CAPLENGTH_OFFSET 0x0100 /* Capability length register */ +#define LPC43_USBHOST_HCSPARAMS_OFFSET 0x0104 /* Host controller structural parameters */ +#define LPC43_USBHOST_HCCPARAMS_OFFSET 0x0108 /* Host controller capability parameters */ +#define LPC43_USBDEV_DCIVERSION_OFFSET 0x0120 /* Device interface version number */ +#define LPC43_USBDEV_DCCPARAMS_OFFSET 0x0124 /* Device controller capability parameters */ + +/* Device/host/OTG operational registers */ +#define LPC43_USBOTG_HCOR_OFFSET 0x0140 /* Offset to EHCI Host Controller Operational Registers */ +#define LPC43_USBOTG_USBCMD_OFFSET 0x0140 /* USB command (both) */ +#define LPC43_USBOTG_USBSTS_OFFSET 0x0144 /* USB status (both) */ +#define LPC43_USBOTG_USBINTR_OFFSET 0x0148 /* USB interrupt enable (both) */ +#define LPC43_USBOTG_FRINDEX_OFFSET 0x014c /* USB frame index (both) */ +#define LPC43_USBHOST_PERIODICLIST_OFFSET 0x0154 /* Frame list base address (host) */ +#define LPC43_USBDEV_DEVICEADDR_OFFSET 0x0154 /* USB device address (device) */ +#define LPC43_USBHOST_ASYNCLISTADDR_OFFSET 0x0158 /* Next asynchronous list address (host) */ +#define LPC43_USBDEV_ENDPOINTLIST_OFFSET 0x0158 /* Address of endpoint list in memory (device) */ +#define LPC43_USBHOST_TTCTRL_OFFSET 0x015c /* Asynchronous buffer status for embedded TT (host) */ +#define LPC43_USBOTG_BURSTSIZE_OFFSET 0x0160 /* Programmable burst size (both) */ +#define LPC43_USBHOST_TXFILLTUNING_OFFSET 0x0164 /* Host transmit pre-buffer packet tuning (host) */ +#define LPC43_USBOTG_BINTERVAL_OFFSET 0x0174 /* Length of virtual frame (both) */ +#define LPC43_USBDEV_ENDPTNAK_OFFSET 0x0178 /* Endpoint NAK (device) */ +#define LPC43_USBDEV_ENDPTNAKEN_OFFSET 0x017c /* Endpoint NAK Enable (device) */ +#define LPC43_USBOTG_PORTSC1_OFFSET 0x0184 /* Port status/control 1 (both) */ +#define LPC43_USBOTG_OTGSC_OFFSET 0x01a4 /* OTG status and control (otg) */ +#define LPC43_USBOTG_USBMODE_OFFSET 0x01a8 /* USB device mode (both) */ + +/* Device side naming of common register offsets */ + +#define LPC43_USBDEV_USBCMD_OFFSET LPC43_USBOTG_USBCMD_OFFSET +#define LPC43_USBDEV_USBSTS_OFFSET LPC43_USBOTG_USBSTS_OFFSET +#define LPC43_USBDEV_USBINTR_OFFSET LPC43_USBOTG_USBINTR_OFFSET +#define LPC43_USBDEV_FRINDEX_OFFSET LPC43_USBOTG_FRINDEX_OFFSET +#define LPC43_USBDEV_BURSTSIZE_OFFSET LPC43_USBOTG_BURSTSIZE_OFFSET +#define LPC43_USBDEV_BINTERVAL_OFFSET LPC43_USBOTG_BINTERVAL_OFFSET +#define LPC43_USBDEV_PORTSC1_OFFSET LPC43_USBOTG_OTGSC_OFFSET +#define LPC43_USBDEV_USBMODE_OFFSET LPC43_USBOTG_USBMODE_OFFSET + +/* Host side naming of common registers */ + +#define LPC43_USBHOST_USBCMD_OFFSET LPC43_USBOTG_USBCMD_OFFSET +#define LPC43_USBHOST_USBSTS_OFFSET LPC43_USBOTG_USBSTS_OFFSET +#define LPC43_USBHOST_USBINTR_OFFSET LPC43_USBOTG_USBINTR_OFFSET +#define LPC43_USBHOST_FRINDEX_OFFSET LPC43_USBOTG_FRINDEX_OFFSET +#define LPC43_USBHOST_BURSTSIZE_OFFSET LPC43_USBOTG_BURSTSIZE_OFFSET +#define LPC43_USBHOST_BINTERVAL_OFFSET LPC43_USBOTG_BINTERVAL_OFFSET +#define LPC43_USBHOST_PORTSC1_OFFSET LPC43_USBOTG_OTGSC_OFFSET +#define LPC43_USBHOST_USBMODE_OFFSET LPC43_USBOTG_USBMODE_OFFSET + +/* Device endpoint registers */ + +#define LPC43_USBDEV_ENDPTSETUPSTAT_OFFSET 0x01ac /* Endpoint setup status */ +#define LPC43_USBDEV_ENDPTPRIME_OFFSET 0x01b0 /* Endpoint initialization */ +#define LPC43_USBDEV_ENDPTFLUSH_OFFSET 0x01b4 /* Endpoint de-initialization */ +#define LPC43_USBDEV_ENDPTSTATUS_OFFSET 0x01b8 /* Endpoint status */ +#define LPC43_USBDEV_ENDPTCOMPLETE_OFFSET 0x01bc /* Endpoint complete */ + +#define LPC43_USBDEV_ENDPTCTRL_OFFSET(n) (0x01c0 + ((n) << 2)) +#define LPC43_USBDEV_ENDPTCTRL0_OFFSET 0x01c0 /* Endpoint control 0 */ +#define LPC43_USBDEV_ENDPTCTRL1_OFFSET 0x01c4 /* Endpoint control 1 */ +#define LPC43_USBDEV_ENDPTCTRL2_OFFSET 0x01c8 /* Endpoint control 2 */ +#define LPC43_USBDEV_ENDPTCTRL3_OFFSET 0x01cc /* Endpoint control 3 */ +#define LPC43_USBDEV_ENDPTCTRL4_OFFSET 0x01d0 /* Endpoint control 4 */ +#define LPC43_USBDEV_ENDPTCTRL5_OFFSET 0x01d4 /* Endpoint control 5 */ + +/* USB0 register (virtual) addresses **********************************************************/ + +/* Device/host capability registers */ +#define LPC43_USBOTG_HCCR_BASE (LPC43_USB0_BASE+LPC43_USBOTG_HCCR_OFFSET) +#define LPC43_USBOTG_CAPLENGTH (LPC43_USB0_BASE+LPC43_USBOTG_CAPLENGTH_OFFSET) +#define LPC43_USBHOST_HCIVERSION (LPC43_USB0_BASE+LPC43_USBHOST_HCIVERSION_OFFSET) +#define LPC43_USBHOST_HCSPARAMS (LPC43_USB0_BASE+LPC43_USBHOST_HCSPARAMS_OFFSET) +#define LPC43_USBHOST_HCCPARAMS (LPC43_USB0_BASE+LPC43_USBHOST_HCCPARAMS_OFFSET) +#define LPC43_USBDEV_DCIVERSION (LPC43_USB0_BASE+LPC43_USBDEV_DCIVERSION_OFFSET) +#define LPC43_USBDEV_DCCPARAMS (LPC43_USB0_BASE+LPC43_USBDEV_DCCPARAMS_OFFSET) + +/* Device/host operational registers */ +#define LPC43_USBOTG_HCOR_BASE (LPC43_USB0_BASE+LPC43_USBOTG_HCOR_OFFSET) +#define LPC43_USBOTG_USBCMD (LPC43_USB0_BASE+LPC43_USBOTG_USBCMD_OFFSET) +#define LPC43_USBOTG_USBSTS (LPC43_USB0_BASE+LPC43_USBOTG_USBSTS_OFFSET) +#define LPC43_USBOTG_USBINTR (LPC43_USB0_BASE+LPC43_USBOTG_USBINTR_OFFSET) +#define LPC43_USBOTG_FRINDEX (LPC43_USB0_BASE+LPC43_USBOTG_FRINDEX_OFFSET) +#define LPC43_USBHOST_PERIODICLIST (LPC43_USB0_BASE+LPC43_USBHOST_PERIODICLIST_OFFSET) +#define LPC43_USBDEV_DEVICEADDR (LPC43_USB0_BASE+LPC43_USBDEV_DEVICEADDR_OFFSET) +#define LPC43_USBHOST_ASYNCLISTADDR (LPC43_USB0_BASE+LPC43_USBHOST_ASYNCLISTADDR_OFFSET) +#define LPC43_USBDEV_ENDPOINTLIST (LPC43_USB0_BASE+LPC43_USBDEV_ENDPOINTLIST_OFFSET) +#define LPC43_USBHOST_TTCTRL (LPC43_USB0_BASE+LPC43_USBHOST_TTCTRL_OFFSET) +#define LPC43_USBOTG_BURSTSIZE (LPC43_USB0_BASE+LPC43_USBOTG_BURSTSIZE_OFFSET) +#define LPC43_USBHOST_TXFILLTUNING (LPC43_USB0_BASE+LPC43_USBHOST_TXFILLTUNING_OFFSET) +#define LPC43_USBOTG_BINTERVAL (LPC43_USB0_BASE+LPC43_USBOTG_BINTERVAL_OFFSET) +#define LPC43_USBDEV_ENDPTNAK (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTNAK_OFFSET) +#define LPC43_USBDEV_ENDPTNAKEN (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTNAKEN_OFFSET) +#define LPC43_USBOTG_PORTSC1 (LPC43_USB0_BASE+LPC43_USBOTG_PORTSC1_OFFSET) +#define LPC43_USBOTG_OTGSC (LPC43_USB0_BASE+LPC43_USBOTG_OTGSC_OFFSET) +#define LPC43_USBOTG_USBMODE (LPC43_USB0_BASE+LPC43_USBOTG_USBMODE_OFFSET) + +/* Device side naming of common register offsets */ + +#define LPC43_USBDEV_USBCMD LPC43_USBOTG_USBCMD +#define LPC43_USBDEV_USBSTS LPC43_USBOTG_USBSTS +#define LPC43_USBDEV_USBINTR LPC43_USBOTG_USBINTR +#define LPC43_USBDEV_FRINDEX LPC43_USBOTG_FRINDEX +#define LPC43_USBDEV_BURSTSIZE LPC43_USBOTG_BURSTSIZE +#define LPC43_USBDEV_BINTERVAL LPC43_USBOTG_BINTERVAL +#define LPC43_USBDEV_PORTSC1 LPC43_USBOTG_OTGSC +#define LPC43_USBDEV_USBMODE LPC43_USBOTG_USBMODE + +/* Host side naming of common registers */ + +#define LPC43_USBHOST_USBCMD LPC43_USBOTG_USBCMD +#define LPC43_USBHOST_USBSTS LPC43_USBOTG_USBSTS +#define LPC43_USBHOST_USBINTR LPC43_USBOTG_USBINTR +#define LPC43_USBHOST_FRINDEX LPC43_USBOTG_FRINDEX +#define LPC43_USBHOST_BURSTSIZE LPC43_USBOTG_BURSTSIZE +#define LPC43_USBHOST_BINTERVAL LPC43_USBOTG_BINTERVAL +#define LPC43_USBHOST_PORTSC1 LPC43_USBOTG_OTGSC +#define LPC43_USBHOST_USBMODE LPC43_USBOTG_USBMODE + +/* Device endpoint registers */ + +#define LPC43_USBDEV_ENDPTSETUPSTAT (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTSETUPSTAT_OFFSET) +#define LPC43_USBDEV_ENDPTPRIME (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTPRIME_OFFSET) +#define LPC43_USBDEV_ENDPTFLUSH (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTFLUSH_OFFSET) +#define LPC43_USBDEV_ENDPTSTATUS (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTSTATUS_OFFSET) +#define LPC43_USBDEV_ENDPTCOMPLETE (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCOMPLETE_OFFSET) + +#define LPC43_USBDEV_ENDPTCTRL(n) (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL_OFFSET(n)) +#define LPC43_USBDEV_ENDPTCTRL0 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL0_OFFSET) +#define LPC43_USBDEV_ENDPTCTRL1 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL1_OFFSET) +#define LPC43_USBDEV_ENDPTCTRL2 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL2_OFFSET) +#define LPC43_USBDEV_ENDPTCTRL3 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL3_OFFSET) +#define LPC43_USBDEV_ENDPTCTRL4 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL4_OFFSET) +#define LPC43_USBDEV_ENDPTCTRL5 (LPC43_USB0_BASE+LPC43_USBDEV_ENDPTCTRL5_OFFSET) + +/* USB0 register bit definitions **************************************************************/ + +/* Device/host capability registers */ +/* Capability length register */ + +#define USBOTG_CAPLENGTH_SHIFT (0) /* Bits 0-7: Offset from register base to operational regs */ +#define USBOTG_CAPLENGTH_MASK (0xff << USBOTG_CAPLENGTH_SHIFT) +#define USBHOST_HCIVERSION_SHIFT (8) /* Bits 8-23: BCD encoding of the EHCI revision number */ +#define USBHOST_HCIVERSION_MASK (0xffff << USBHOST_HCIVERSION_SHIFT) + /* Bits 24-31: Reserved */ +/* Host controller structural parameters */ + +#define USBHOST_HCSPARAMS_NPORTS_SHIF (0) /* Bits 0-3: Number of downstream ports */ +#define USBHOST_HCSPARAMS_NPORTS_MASK (15 << USBHOST_HCSPARAMS_NPORTS_SHIFT) +#define USBHOST_HCSPARAMS_PPC (1 >> 4) /* Bit 4: Port Power Control */ + /* Bits 5-7: Reserved */ +#define USBHOST_HCSPARAMS_NPCC_SHIFT (8) /* Bits 8-11: Number of Ports per Companion Controller */ +#define USBHOST_HCSPARAMS_NPCC_MASK (15 << USBHOST_HCSPARAMS_NPCC_SHIFT) +#define USBHOST_HCSPARAMS_NCC_SHIFT (15) /* Bits 12-15: Number of Companion Controller */ +#define USBHOST_HCSPARAMS_NCC_MASK (15 << USBHOST_HCSPARAMS_NCC_SHIFT) +#define USBHOST_HCSPARAMS_PI (1 >> 16) /* Bit 16: Port indicators */ + /* Bits 17-19: Reserved */ +#define USBHOST_HCSPARAMS_NPTT_SHIFT (20) /* Bits 20-23: Number of Ports per Transaction Translator */ +#define USBHOST_HCSPARAMS_NPTT_MASK (15 << USBHOST_HCSPARAMS_NPTT_SHIFT) +#define USBHOST_HCSPARAMS_NTT_SHIFT (24) /* Bits 24-27: Number of Transaction Translators */ +#define USBHOST_HCSPARAMS_NTT_MASK (15 << USBHOST_HCSPARAMS_NTT_SHIFT) + /* Bits 28-31: Reserved */ +/* Host controller capability parameters */ + +#define USBHOST_HCCPARAMS_ADC (1 >> 0) /* Bit 0: 64-bit Addressing Capability */ +#define USBHOST_HCCPARAMS_PFL (1 >> 1) /* Bit 1: Programmable Frame List Flag */ +#define USBHOST_HCCPARAMS_ASP (1 >> 2) /* Bit 2: Asynchronous Schedule Park Capability */ +#define USBHOST_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ +#define USBHOST_HCCPARAMS_IST_MASK (15 << USBHOST_HCCPARAMS_IST_SHIFT) +#define USBHOST_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ +#define USBHOST_HCCPARAMS_EECP_MASK (255 << USBHOST_HCCPARAMS_EECP_SHIFT) + /* Bits 16-31: Reserved */ +/* Device interface version number */ + +#define USBDEV_DCIVERSION_SHIFT (0) /* Bits 0-15: BCD encoding of the device interface */ +#define USBDEV_DCIVERSION_MASK (0xffff << USBDEV_DCIVERSION_SHIFT) + /* Bits 16-31: Reserved */ + +/* Device controller capability parameters */ + +#define USBDEV_DCCPARAMS_DEN_SHIFT (0) /* Bits 0-4: DEN Device Endpoint Number */ +#define USBDEV_DCCPARAMS_DEN_MASK (31 << USBDEV_DCCPARAMS_DEN_SHIFT) + /* Bits 5-6: Reserved */ +#define USBDEV_DCCPARAMS_DC (1 >> 7) /* Bit 7: Device Capable */ +#define USBDEV_DCCPARAMS_HC (1 >> 8) /* Bit 8: Host Capable */ + /* Bits 9-31: Reserved */ +/* Device/host operational registers */ +/* USB Command register USBCMD -- Device Mode */ + +#define USBDEV_USBCMD_RS (1 << 0) /* Bit 0: 0 Run/Stop */ +#define USBDEV_USBCMD_RST (1 << 1) /* Bit 1: Controller reset */ + /* Bits 2-12: Reserved OR not used in device mode */ +#define USBDEV_USBCMD_SUTW (1 << 13) /* Bit 13: Setup trip wire */ +#define USBDEV_USBCMD_ATDTW (1 << 14) /* Bit 14: Add dTD trip wire */ + /* Bit 15: Reserved OR not used in device mode */ +#define USBDEV_USBCMD_ITC_SHIFT (16) /* Bits 16-23: Interrupt threshold control */ +#define USBDEV_USBCMD_ITC_MASK (255 << USBDEV_USBCMD_ITC_SHIFT) +# define USBDEV_USBCMD_ITCIMME (0 << USBDEV_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBDEV_USBCMD_ITC1UF (1 << USBDEV_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBDEV_USBCMD_ITC2UF (2 << USBDEV_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBDEV_USBCMD_ITC4UF (4 << USBDEV_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBDEV_USBCMD_ITC8UF (8 << USBDEV_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBDEV_USBCMD_ITC16UF (16 << USBDEV_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBDEV_USBCMD_ITC32UF (32 << USBDEV_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBDEV_USBCMD_ITC64UF (64 << USBDEV_USBCMD_ITC_SHIFT) /* 64 micro frames */ + /* Bits 24-31: Reserved */ +/* USB Command register USBCMD -- Host Mode */ + +#define USBHOST_USBCMD_RS (1 << 0) /* Bit 0: Run/Stop */ +#define USBHOST_USBCMD_RST (1 << 1) /* Bit 1: Controller reset */ +#define USBHOST_USBCMD_FS0 (1 << 2) /* Bit 2: Bit 0 of the Frame List Size bits */ +#define USBHOST_USBCMD_FS1 (1 << 3) /* Bit 3: Bit 1 of the Frame List Size bits */ +#define USBHOST_USBCMD_PSE (1 << 4) /* Bit 4: Skips processing periodic schedule */ +#define USBHOST_USBCMD_ASE (1 << 5) /* Bit 5: Skips processing asynchronous schedule */ +#define USBHOST_USBCMD_IAA (1 << 6) /* Bit 6: Interrupt next asynchronous schedule */ + /* Bit 7: Reserved OR not used in host mode */ +#define USBHOST_USBCMD_ASP_SHIFT (8) /* Bits 8-9: Asynchronous schedule park mode */ +#define USBHOST_USBCMD_ASP_MASK (3 << USBHOST_USBCMD_ASP_SHIFT) + /* Bit 10: Reserved OR not used in host mode */ +#define USBHOST_USBCMD_ASPE (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ + /* Bits 12-14: Reserved OR not used in host mode */ +#define USBHOST_USBCMD_FS2 (1 << 15) /* Bit 15: Bit 2 of the Frame List Size bits */ +#define USBHOST_USBCMD_ITC_SHIFT (16) /* Bits 16-13: Interrupt threshold control */ +#define USBHOST_USBCMD_ITC_MASK (255 << USBHOST_USBCMD_ITC_SHIFT) +# define USBHOST_USBCMD_ITCIMMED (0 << USBHOST_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBHOST_USBCMD_ITC1UF (1 << USBHOST_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBHOST_USBCMD_ITC2UF (2 << USBHOST_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBHOST_USBCMD_ITC4UF (4 << USBHOST_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBHOST_USBCMD_ITC8UF (8 << USBHOST_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBHOST_USBCMD_ITC16UF (16 << USBHOST_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBHOST_USBCMD_ITC32UF (32 << USBHOST_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBHOST_USBCMD_ITC64UF (64 << USBHOST_USBCMD_ITC_SHIFT) /* 64 micro frames */ + /* Bits 24-31: Reserved */ +/* USB Status register USBSTS -- Device Mode */ + +#define USBDEV_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ +#define USBDEV_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBDEV_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ + /* Bits 3-5: Reserved OR not used in device mode */ +#define USBDEV_USBSTS_URI (1 << 6) /* Bit 6: USB reset received */ +#define USBDEV_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ +#define USBDEV_USBSTS_SLI (1 << 8) /* Bit 8: DCSuspend */ + /* Bits 9-15: Reserved OR not used in device mode */ +#define USBDEV_USBSTS_NAKI (1 << 16) /* Bit 16: NAK interrupt bit */ + /* Bits 17-31: Reserved OR not used in device mode */ +/* USB Status register USBSTS -- Host Mode */ + +#define USBHOST_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ +#define USBHOST_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBHOST_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ +#define USBHOST_USBSTS_FRI (1 << 3) /* Bit 3: Frame list roll-over */ + /* Bit 4: Reserved */ +#define USBHOST_USBSTS_AAI (1 << 5) /* Bit 5: Interrupt on async advance */ + /* Bit 6: Not used in host mode */ +#define USBHOST_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ + /* Bit 8-11: Reserved OR Not used in host mode */ +#define USBHOST_USBSTS_HCH (1 << 12) /* Bit 12: HCHalted */ +#define USBHOST_USBSTS_RCL (1 << 13) /* Bit 13: Reclamation */ +#define USBHOST_USBSTS_PS (1 << 14) /* Bit 14: Periodic schedule status */ +#define USBHOST_USBSTS_AS (1 << 15) /* Bit 15: Asynchronous schedule status */ + /* Bit 16-17: Reserved OR Not used in host mode */ +#define USBHOST_USBSTS_UAI (1 << 18) /* Bit 18: USB host asynchronous interrupt */ +#define USBHOST_USBSTS_UPI (1 << 19) /* Bit 19: USB host periodic interrupt */ + /* Bits 20-31: Reserved */ +/* USB interrupt register USBINTR -- Device Mode */ + +#define USBDEV_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ +#define USBDEV_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBDEV_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ + /* Bits 3-5: Reserved OR Not used in device mode */ +#define USBDEV_USBINTR_URE (1 << 6) /* Bit 6: USB reset enable */ +#define USBDEV_USBINTR_SRE (1 << 7) /* Bit 7: SOF received enable */ +#define USBDEV_USBINTR_SLE (1 << 8) /* Bit 8: Sleep enable */ + /* Bits 8-15: Reserved */ +#define USBDEV_USBINTR_NAKE (1 << 16) /* Bit 16: NAK interrupt enable */ + /* Bits 17-31: Reserved OR Not used in device mode */ +/* USB interrupt register USBINTR -- Host Mode */ + +#define USBHOST_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ +#define USBHOST_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBHOST_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ +#define USBHOST_USBINTR_FRE (1 << 3) /* Bit 3: Frame list rollover enable */ + /* Bit 4: Reserved */ +#define USBHOST_USBINTR_AAE (1 << 5) /* Bit 5: Interrupt on asynchronous advance enable */ + /* Bit 6: Not used in host mode */ +#define USBHOST_USBINTR_SRE (1 << 7) /* Bit 7: SOF timer interrupt enable */ + /* Bits 8-17: Reserved OR Not used in host mode */ +#define USBHOST_USBINTR_UAIE (1 << 18) /* Bit 18: USB host asynchronous interrupt enable */ +#define USBHOST_USBINTR_UPIA (1 << 19) /* Bit 19: USB host periodic interrupt enable */ + /* Bits 20-31: Reserved */ +/* Frame index register FRINDEX -- Device Mode */ + +#define USBDEV_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBDEV_FRINDEX_CUFN_MASK (7 << USBDEV_FRINDEX_CUFN_SHIFT) +#define USBDEV_FRINDEX_LFN_SHIFT (3) /* Bits 3-13: Frame number of last frame transmitted */ +#define USBDEV_FRINDEX_LFN_MASK (0x7ff << USBDEV_FRINDEX_LFN_SHIFT) + /* Bits 14-31: Reserved */ +/* Frame index register FRINDEX -- Host Mode */ + +#define USBHOST_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBHOST_FRINDEX_CUFN_MASK (7 << USBHOST_FRINDEX_CUFN_SHIFT) +#define USBHOST_FRINDEX_FLI_SHIFT (3) /* Bits 3-12: Frame list current index */ +#define USBHOST_FRINDEX_FLI_MASK (0x3ff << USBHOST_FRINDEX_FLI_SHIFT) + /* Bits 13-31: Reserved */ +/* USB Device Address register DEVICEADDR -- Device Mode */ + /* Bits 0-23: Reserved */ +#define USBDEV_DEVICEADDR_USBADRA (1 << 24) /* Bit 24: Device address advance */ +#define USBDEV_DEVICEADDR_SHIFT (25) /* Bits 25-31: USBADR USB device address */ +#define USBDEV_DEVICEADDR_MASK (0x3f << USBDEV_DEVICEADDR_SHIFT) + +/* USB Periodic List Base register PERIODICLIST -- Host Mode */ + /* Bits 0-11: Reserved */ +#define USBHOST_PERIODICLIST_PERBASE_SHIFT (12) /* Bits 12-31: Base Address (Low) */ +#define USBHOST_PERIODICLIST_PERBASE_MASK (0x000fffff << USBHOST_PERIODICLIST_PERBASE_SHIFT) + +/* USB Endpoint List Address register ENDPOINTLISTADDR -- Device Mode */ + /* Bits 0-10: Reserved */ +#define USBDEV_ENDPOINTLIST_EPBASE_SHIFT (11) /* Bits 11-31: Endpoint list pointer (low) */ +#define USBDEV_ENDPOINTLIST_EPBASE_MASK (0x001fffff << USBDEV_ENDPOINTLIST_EPBASE_SHIFT) + +/* USB Asynchronous List Address register ASYNCLISTADDR -- Host Mode */ + /* Bits 0-4: Reserved */ +#define USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT (5) /* Bits 5-31: Link pointer (Low) LPL */ +#define USBHOST_ASYNCLISTADDR_ASYBASE_MASK (0x07ffffff << USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT) + +/* USB TT Control register TTCTRL -- Host Mode */ + /* Bits 0-23: Reserved */ +#define USBHOST_TTCTRL_TTHA_SHIFT (24) /* Bits 24-30: Hub address */ +#define USBHOST_TTCTRL_TTHA_MASK (0x7f << USBHOST_TTCTRL_TTHA_SHIFT) + +/* USB burst size register BURSTSIZE -- Device/Host Mode */ + +#define USBHOST_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBHOST_BURSTSIZE_RXPBURST_MASK (255 << USBHOST_BURSTSIZE_RXPBURST_SHIFT) +#define USBHOST_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBHOST_BURSTSIZE_TXPBURST_MASK (255 << USBHOST_BURSTSIZE_TXPBURST_SHIFT) + /* Bits 16-31: Reserved */ + +#define USBDEV_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBDEV_BURSTSIZE_RXPBURST_MASK (255 << USBDEV_BURSTSIZE_RXPBURST_SHIFT) +#define USBDEV_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBDEV_BURSTSIZE_TXPBURST_MASK (255 << USBDEV_BURSTSIZE_TXPBURST_SHIFT) + /* Bits 16-31: Reserved */ +/* USB Transfer buffer Fill Tuning register TXFIFOFILLTUNING -- Host Mode */ + +#define USBHOST_TXFILLTUNING_SCHOH_SHIFT (0) /* Bits 0-7: FIFO burst threshold */ +#define USBHOST_TXFILLTUNING_SCHOH_MASK (0xff << USBHOST_TXFILLTUNING_SCHOH_SHIFT) +#define USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT (8) /* Bits 8-12: Scheduler health counter */ +#define USBHOST_TXFILLTUNING_SCHEATLTH_MASK (0x1f << USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT) +#define USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT (16) /* Bits 16-21: Scheduler overhead */ +#define USBHOST_TXFILLTUNING_FIFOTHRES_MASK (0x3f << USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT) + /* Bits 22-31: Reserved */ +/* USB BINTERVAL register BINTERVAL -- Device/Host Mode */ + +#define USBDEV_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBDEV_BINTERVAL_MASK (15 << USBDEV_BINTERVAL_SHIFT) + /* Bits 4-31: Reserved */ + +#define USBHOST_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBHOST_BINTERVAL_MASK (15 << USBHOST_BINTERVAL_SHIFT) + /* Bits 4-31: Reserved */ +/* USB endpoint NAK register ENDPTNAK -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPRN_SHIFT (0) /* Bits 0-5: Rx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPRN_MASK (0x3f << USBDEV_ENDPTNAK_EPRN_SHIFT) + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTNAK_EPTN_SHIFT (16) /* Bits 16-21: Tx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPTN_MASK (0x3f << USBDEV_ENDPTNAK_EPTN_SHIFT) + /* Bits 22-31: Reserved */ +/* USB Endpoint NAK Enable register ENDPTNAKEN -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPRNE_SHIFT (0) /* Bits 0-5: Rx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPRNE_MASK (0x3f << USBDEV_ENDPTNAK_EPRNE_SHIFT) + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTNAK_EPTNE_SHIFT (16) /* Bits 16-21: Tx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPTNE_MASK (0x3f << USBDEV_ENDPTNAK_EPTNE_SHIFT) + /* Bits 22-31: Reserved */ +/* Port Status and Control register PRTSC1 -- Device Mode */ + +#define USBDEV_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ + /* Bit 1: Not used in device mode */ +#define USBDEV_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBDEV_PRTSC1_PEC (1 << 3) /* Bit 3: Port enable/disable change */ +#define USBDEV_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBDEV_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBDEV_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBDEV_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ + /* Bits 10-13: Reserved OR not used in device mode */ +#define USBDEV_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBDEV_PRTSC1_PIC_MASK (3 << USBDEV_PRTSC1_PIC_SHIFT) +# define USBDEV_PRTSC1_PIC_OFF (0 << USBDEV_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBDEV_PRTSC1_PIC_AMBER (1 << USBDEV_PRTSC1_PIC_SHIFT) /* 01 amber */ +# define USBDEV_PRTSC1_PIC_GREEN (2 << USBDEV_PRTSC1_PIC_SHIFT) /* 10 green */ +#define USBDEV_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: 19: Port test control */ +#define USBDEV_PRTSC1_PTC_MASK (15 << USBDEV_PRTSC1_PTC_SHIFT) +# define USBDEV_PRTSC1_PTC_DISABLE (0 << USBDEV_PRTSC1_PTC_SHIFT) /* TEST_MODE_DISABLE */ +# define USBDEV_PRTSC1_PTC_JSTATE (1 << USBDEV_PRTSC1_PTC_SHIFT) /* J_STATE */ +# define USBDEV_PRTSC1_PTC_KSTATE (2 << USBDEV_PRTSC1_PTC_SHIFT) /* K_STATE */ +# define USBDEV_PRTSC1_PTC_SE0 (3 << USBDEV_PRTSC1_PTC_SHIFT) /* SE0 (host)/NAK (device) */ +# define USBDEV_PRTSC1_PTC_PACKET (4 << USBDEV_PRTSC1_PTC_SHIFT) /* Packet */ +# define USBDEV_PRTSC1_PTC_HS (5 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_HS */ +# define USBDEV_PRTSC1_PTC_FS (6 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_FS */ + /* Bits 20-22: Not used in device mode */ +#define USBDEV_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +# define USBDEV_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ + /* Bit 25: Reserved */ +#define USBDEV_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBDEV_PRTSC1_PSPD_MASK (3 << USBDEV_PRTSC1_PSPD_SHIFT) +# define USBDEV_PRTSC1_PSPD_FS (0 << USBDEV_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBDEV_PRTSC1_PSPD_LS (0 << USBDEV_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBDEV_PRTSC1_PSPD_HS (2 << USBDEV_PRTSC1_PSPD_SHIFT) /* High-speed */ + /* Bits 28-31: Reserved */ +/* Port Status and Control register PRTSC1 -- Host Mode */ + +#define USBHOST_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ +#define USBHOST_PRTSC1_CSC (1 << 1) /* Bit 1: Connect status change */ +#define USBHOST_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBHOST_PRTSC1_PEC (1 << 3) /* Bit 3: Port disable/enable change */ +#define USBHOST_PRTSC1_OCA (1 << 4) /* Bit 4: Over-current active */ +#define USBHOST_PRTSC1_OCC (1 << 5) /* Bit 5: Over-current change */ +#define USBHOST_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBHOST_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBHOST_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBHOST_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ +#define USBHOST_PRTSC1_LS_SHIFT (10) /* Bits 10-11: Line status */ +#define USBHOST_PRTSC1_LS_MASK (3 << USBHOST_PRTSC1_LS_SHIFT) +# define USBHOST_PRTSC1_LS_SE0 (0 << USBHOST_PRTSC1_LS_SHIFT) /* SE0 (USB_DP and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_JSTATE (2 << USBHOST_PRTSC1_LS_SHIFT) /* J-state (USB_DP HIGH and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_KSTATE (1 << USBHOST_PRTSC1_LS_SHIFT) /* K-state (USB_DP LOW and USB_DM HIGH) */ +#define USBHOST_PRTSC1_PP (1 << 12) /* Bit 12: Port power control */ + /* Bit 13: Reserved */ +#define USBHOST_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBHOST_PRTSC1_PIC_MASK (3 << USBHOST_PRTSC1_PIC_SHIFT) +# define USBHOST_PRTSC1_PIC_OFF (0 << USBHOST_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBHOST_PRTSC1_PIC_AMBER (1 << USBHOST_PRTSC1_PIC_SHIFT) /* 01 Amber */ +# define USBHOST_PRTSC1_PIC_GREEN (2 << USBHOST_PRTSC1_PIC_SHIFT) /* 10 Green */ +#define USBHOST_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: Port test control */ +#define USBHOST_PRTSC1_PTC_MASK (15 << USBHOST_PRTSC1_PTC_SHIFT) +# define USBHOST_PRTSC1_PTC_DISABLE (0 << USBHOST_PRTSC1_PTC_SHIFT) /* 0000 TEST_MODE_DISABLE */ +# define USBHOST_PRTSC1_PTC_JSTATE (1 << USBHOST_PRTSC1_PTC_SHIFT) /* 0001 J_STATE */ +# define USBHOST_PRTSC1_PTC_KSTATE (2 << USBHOST_PRTSC1_PTC_SHIFT) /* 0010 K_STATE */ +# define USBHOST_PRTSC1_PTC_SE0 (3 << USBHOST_PRTSC1_PTC_SHIFT) /* 0011 SE0 (host)/NAK (device) */ +# define USBHOST_PRTSC1_PTC_PACKET (4 << USBHOST_PRTSC1_PTC_SHIFT) /* 0100 Packet */ +# define USBHOST_PRTSC1_PTC_HS (5 << USBHOST_PRTSC1_PTC_SHIFT) /* 0101 FORCE_ENABLE_HS */ +# define USBHOST_PRTSC1_PTC_FS (6 << USBHOST_PRTSC1_PTC_SHIFT) /* 0110 FORCE_ENABLE_FS */ +# define USBHOST_PRTSC1_PTC_LS (7 << USBHOST_PRTSC1_PTC_SHIFT) /* 0111 FORCE_ENABLE_LS */ +#define USBHOST_PRTSC1_WKCN (1 << 20) /* Bit 20: Wake on connect enable (WKCNNT_E) */ +#define USBHOST_PRTSC1_WKDC (1 << 21) /* Bit 21: Wake on disconnect enable (WKDSCNNT_E) */ +#define USBHOST_PRTSC1_WKOC (1 << 22) /* Bit 22: Wake on over-current enable (WKOC_E) */ +#define USBHOST_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +#define USBHOST_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ + /* Bit 25: Reserved */ +#define USBHOST_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBHOST_PRTSC1_PSPD_MASK (3 << USBHOST_PRTSC1_PSPD_SHIFT) +# define USBHOST_PRTSC1_PSPD_FS (0 << USBHOST_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBHOST_PRTSC1_PSPD_LS (1 << USBHOST_PRTSC1_PSPD_SHIFT) /* Low-speed */ +# define USBHOST_PRTSC1_PSPD_HS (2 << USBHOST_PRTSC1_PSPD_SHIFT) /* High-speed */ + /* Bits 28-31: Reserved */ +/* OTG Status and Control register */ +/* OTG controls */ + +#define USBOTG_OTGSC_VD (1 << 0) /* Bit 0: VBUS_Discharge */ +#define USBOTG_OTGSC_VC (1 << 1) /* Bit 1: VBUS_Charge */ +#define USBOTG_OTGSC_HAAR (1 << 2) /* Bit 2: Hardware assist auto_reset */ +#define USBOTG_OTGSC_OT (1 << 3) /* Bit 3: OTG termination */ +#define USBOTG_OTGSC_DP (1 << 4) /* Bit 4: Data pulsing */ +#define USBOTG_OTGSC_IDPU (1 << 5) /* Bit 5: ID pull-up */ +#define USBOTG_OTGSC_HADP (1 << 6) /* Bit 6: Hardware assist data pulse */ +#define USBOTG_OTGSC_HABA (1 << 7) /* Bit 7: Hardware assist B-disconnect to A-connect */ + +/* OTG status inputs */ + +#define USBOTG_OTGSC_ID (1 << 8) /* Bit 8: USB ID */ +#define USBOTG_OTGSC_AVV (1 << 9) /* Bit 9: A-VBUS valid */ +#define USBOTG_OTGSC_ASV (1 << 10) /* Bit 10: A-session valid */ +#define USBOTG_OTGSC_BSV (1 << 11) /* Bit 11: B-session valid */ +#define USBOTG_OTGSC_BSE (1 << 12) /* Bit 12: B-session end */ +#define USBOTG_OTGSC_1MST (1 << 13) /* Bit 13: 1 millisecond timer toggle */ +#define USBOTG_OTGSC_DPS (1 << 14) /* Bit 14: Data bus pulsing status */ + /* Bit 15: Reserved */ +/* OTG interrupt status */ + +#define USBOTG_OTGSC_IDIS (1 << 16) /* Bit 16: USB ID interrupt status */ +#define USBOTG_OTGSC_AVVIS (1 << 17) /* Bit 17: A-VBUS valid interrupt status */ +#define USBOTG_OTGSC_ASVIS (1 << 18) /* Bit 18: A-Session valid interrupt status */ +#define USBOTG_OTGSC_BSVIS (1 << 19) /* Bit 19: B-Session valid interrupt status */ +#define USBOTG_OTGSC_BSEIS (1 << 20) /* Bit 20: B-Session end interrupt status */ +#define USBOTG_OTGSC_MS1S (1 << 21) /* Bit 21: 1 millisecond timer interrupt status */ +#define USBOTG_OTGSC_DPIS (1 << 22) /* Bit 22: Data pulse interrupt status */ + /* Bit 23: Reserved */ +/* OTG interrupt enable */ + +#define USBOTG_OTGSC_IDIE (1 << 24) /* Bit 24: USB ID interrupt enable */ +#define USBOTG_OTGSC_AVVIE (1 << 25) /* Bit 25: A-VBUS valid interrupt enable */ +#define USBOTG_OTGSC_ASVIE (1 << 26) /* Bit 26: A-session valid interrupt enable */ +#define USBOTG_OTGSC_BSVIE (1 << 27) /* Bit 27: B-session valid interrupt enable */ +#define USBOTG_OTGSC_BSEIE (1 << 28) /* Bit 28: B-session end interrupt enable */ +#define USBOTG_OTGSC_MS1E (1 << 29) /* Bit 29: 1 millisecond timer interrupt enable */ +#define USBOTG_OTGSC_DPIE (1 << 30) /* Bit 30: Data pulse interrupt enable */ + /* Bit 31: Reserved */ +/* USB Mode register USBMODE -- Device Mode */ + +#define USBDEV_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBDEV_USBMODE_CM_MASK (3 << USBDEV_USBMODE_CM_SHIFT) +# define USBDEV_USBMODE_CM_IDLE (0 << USBDEV_USBMODE_CM_SHIFT) /* Idle */ +# define USBDEV_USBMODE_CM_DEVICE (2 << USBDEV_USBMODE_CM_SHIFT) /* Device controller */ +# define USBDEV_USBMODE_CM_HOST (3 << USBDEV_USBMODE_CM_SHIFT) /* Host controller */ +#define USBDEV_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ +#define USBDEV_USBMODE_SLOM (1 << 3) /* Bit 3: Setup Lockout mode */ +#define USBDEV_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ + /* Bits 5-31: Reserved OR not used in device mode */ + +/* USB Mode register USBMODE -- Host Mode */ + +#define USBHOST_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBHOST_USBMODE_CM_MASK (3 << USBHOST_USBMODE_CM_SHIFT) +# define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */ +# define USBHOST_USBMODE_CM_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */ +# define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */ +#define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ + /* Bit 3: Not used in host mode */ +#define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ +#define USBHOST_USBMODE_VBPS (1 << 5) /* Bit 5: VBUS power select */ + /* Bits 6-31: Reserved */ +/* Device endpoint registers */ + +/* USB Endpoint Setup Status register ENDPTSETUPSTAT */ + +#define USBDEV_ENDPTSETSTAT_STAT(n) (1 << (n)) +#define USBDEV_ENDPTSETSTAT_STAT0 (1 << 0) /* Bit 0: Setup EP status for logical EP 0 */ +#define USBDEV_ENDPTSETSTAT_STAT1 (1 << 1) /* Bit 1: Setup EP status for logical EP 1 */ +#define USBDEV_ENDPTSETSTAT_STAT2 (1 << 2) /* Bit 2: Setup EP status for logical EP 2 */ +#define USBDEV_ENDPTSETSTAT_STAT3 (1 << 3) /* Bit 3: Setup EP status for logical EP 3 */ +#define USBDEV_ENDPTSETSTAT_STAT4 (1 << 4) /* Bit 4: Setup EP status for logical EP 4 */ +#define USBDEV_ENDPTSETSTAT_STAT5 (1 << 5) /* Bit 5: Setup EP status for logical EP 5 */ + /* Bits 6-31: Reserved */ +/* USB Endpoint Prime register ENDPTPRIME */ + +#define USBDEV_ENDPTPRIM_PERB(n) (1 << (n)) +#define USBDEV_ENDPTPRIM_PERB0 (1 << 0) /* Bit 0: Prime EP recv buffer for physical OUT EP 0 */ +#define USBDEV_ENDPTPRIM_PERB1 (1 << 1) /* Bit 1: Prime EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTPRIM_PERB2 (1 << 2) /* Bit 2: Prime EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTPRIM_PERB3 (1 << 3) /* Bit 3: Prime EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTPRIM_PERB4 (1 << 4) /* Bit 4: Prime EP recv buffer for physical OUT EP 4 */ +#define USBDEV_ENDPTPRIM_PERB5 (1 << 5) /* Bit 5: Prime EP recv buffer for physical OUT EP 5 */ + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTPRIM_PETB(n) (1 << ((n) + 16)) +#define USBDEV_ENDPTPRIM_PETB0 (1 << 16) /* Bit 16: Prime EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTPRIM_PETB1 (1 << 17) /* Bit 17: Prime EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTPRIM_PETB2 (1 << 18) /* Bit 18: Prime EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTPRIM_PETB3 (1 << 19) /* Bit 19: Prime EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTPRIM_PETB4 (1 << 20) /* Bit 20: Prime EP xmt buffer for physical IN EP 4 */ +#define USBDEV_ENDPTPRIM_PETB5 (1 << 21) /* Bit 21: Prime EP xmt buffer for physical IN EP 5 */ + /* Bits 22-31: Reserved */ +/* USB Endpoint Flush register ENDPTFLUSH */ + +#define USBDEV_ENDPTFLUSH_FERB(n) (1 << (n)) +#define USBDEV_ENDPTFLUSH_FERB0 (1 << 0) /* Bit 0: Flush EP recv buffer for physical OUT EP 0 */ +#define USBDEV_ENDPTFLUSH_FERB1 (1 << 1) /* Bit 1: Flush EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTFLUSH_FERB2 (1 << 2) /* Bit 2: Flush EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTFLUSH_FERB3 (1 << 3) /* Bit 3: Flush EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTFLUSH_FERB4 (1 << 4) /* Bit 4: Flush EP recv buffer for physical OUT EP 4 */ +#define USBDEV_ENDPTFLUSH_FERB5 (1 << 5) /* Bit 5: Flush EP recv buffer for physical OUT EP 5 */ + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTFLUSH_FETB(n) (1 << ((n) + 16)) +#define USBDEV_ENDPTFLUSH_FETB0 (1 << 16) /* Bit 16: Flush EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTFLUSH_FETB1 (1 << 17) /* Bit 17: Flush EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTFLUSH_FETB2 (1 << 18) /* Bit 18: Flush EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTFLUSH_FETB3 (1 << 19) /* Bit 19: Flush EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTFLUSH_FETB4 (1 << 20) /* Bit 20: Flush EP xmt buffer for physical IN EP 4 */ +#define USBDEV_ENDPTFLUSH_FETB5 (1 << 21) /* Bit 21: Flush EP xmt buffer for physical IN EP 5 */ + /* Bits 22-31: Reserved */ +/* USB Endpoint Status register ENDPTSTATUS */ + +#define USBDEV_ENDPTSTATUS_ERBR(n) (1 << (n)) +#define USBDEV_ENDPTSTATUS_ERBR0 (1 << 0) /* Bit 0: EP recv buffer ready for physical OUT EP 0 */ +#define USBDEV_ENDPTSTATUS_ERBR1 (1 << 1) /* Bit 1: EP recv buffer ready for physical OUT EP 1 */ +#define USBDEV_ENDPTSTATUS_ERBR2 (1 << 2) /* Bit 2: EP recv buffer ready for physical OUT EP 2 */ +#define USBDEV_ENDPTSTATUS_ERBR3 (1 << 3) /* Bit 3: EP recv buffer ready for physical OUT EP 3 */ +#define USBDEV_ENDPTSTATUS_ERBR4 (1 << 4) /* Bit 4: EP recv buffer ready for physical OUT EP 4 */ +#define USBDEV_ENDPTSTATUS_ERBR5 (1 << 5) /* Bit 5: EP recv buffer ready for physical OUT EP 5 */ + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTSTATUS_ETBR(n) (1 << ((n) + 16)) +#define USBDEV_ENDPTSTATUS_ETBR0 (1 << 16) /* Bit 16: EP xmt buffer ready for physical IN EP 0 */ +#define USBDEV_ENDPTSTATUS_ETBR1 (1 << 17) /* Bit 17: EP xmt buffer ready for physical IN EP 1 */ +#define USBDEV_ENDPTSTATUS_ETBR2 (1 << 18) /* Bit 18: EP xmt buffer ready for physical IN EP 2 */ +#define USBDEV_ENDPTSTATUS_ETBR3 (1 << 19) /* Bit 19: EP xmt buffer ready for physical IN EP 3 */ +#define USBDEV_ENDPTSTATUS_ETBR4 (1 << 20) /* Bit 20: EP xmt buffer ready for physical IN EP 4 */ +#define USBDEV_ENDPTSTATUS_ETBR5 (1 << 21) /* Bit 21: EP xmt buffer ready for physical IN EP 5 */ + /* Bits 22-31: Reserved */ +/* USB Endpoint Complete register ENDPTCOMPLETE */ + +#define USBDEV_ENDPTCOMPLETE_ERCE(n) (1 << (n)) +#define USBDEV_ENDPTCOMPLETE_ERCE0 (1 << 0) /* Bit 0: EP recv complete event for physical OUT EP 0 */ +#define USBDEV_ENDPTCOMPLETE_ERCE1 (1 << 1) /* Bit 1: EP recv complete event for physical OUT EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ERCE2 (1 << 2) /* Bit 2: EP recv complete event for physical OUT EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ERCE3 (1 << 3) /* Bit 3: EP recv complete event for physical OUT EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ERCE4 (1 << 4) /* Bit 4: EP recv complete event for physical OUT EP 4 */ +#define USBDEV_ENDPTCOMPLETE_ERCE5 (1 << 5) /* Bit 4: EP recv complete event for physical OUT EP 5 */ + /* Bits 6-15: Reserved */ +#define USBDEV_ENDPTCOMPLETE_ETCE(n) (1 << ((n) + 16)) +#define USBDEV_ENDPTCOMPLETE_ETCE0 (1 << 16) /* Bit 16: EP xmt complete event for physical IN EP 0 */ +#define USBDEV_ENDPTCOMPLETE_ETCE1 (1 << 17) /* Bit 17: EP xmt complete event for physical IN EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ETCE2 (1 << 18) /* Bit 18: EP xmt complete event for physical IN EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ETCE3 (1 << 19) /* Bit 19: EP xmt complete event for physical IN EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ETCE4 (1 << 20) /* Bit 20: EP xmt complete event for physical IN EP 4 */ +#define USBDEV_ENDPTCOMPLETE_ETCE5 (1 << 21) /* Bit 21: EP xmt complete event for physical IN EP 5 */ + /* Bits 22-31: Reserved */ +/* USB Endpoint 0 Control register ENDPTCTRL0 */ + +#define USBDEV_ENDPTCTRL0_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + /* Bit 1: Reserved */ +#define USBDEV_ENDPTCTRL0_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTR0L_RXT_MASK (3 << USBDEV_ENDPTCTRL0_RXT_SHIFT) +# define USBDEV_ENDPTCTRL0_RXT_CTRL (0 << USBDEV_ENDPTCTRL0_RXT_SHIFT) /* Control */ + /* Bits 4-6: Reserved */ +#define USBDEV_ENDPTCTRL0_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ + /* Bits 8-15: Reserved */ +#define USBDEV_ENDPTCTRL0_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ + /* Bit 17: Reserved */ +#define USBDEV_ENDPTCTRL0_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL0_TXT_MASK (3 << USBDEV_ENDPTCTRL0_TXT_SHIFT) +# define USBDEV_ENDPTCTRL0_TXT_CTRL (0 << USBDEV_ENDPTCTRL0_TXT_SHIFT) /* Control */ +#define USBDEV_ENDPTCTRL0_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ + /* Bits 24-31: Reserved */ +/* USB Endpoint 1-3 control registers ENDPTCTRL1-ENDPPTCTRL5 */ + +#define USBDEV_ENDPTCTRL_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + /* Bit 1: Reserved */ +#define USBDEV_ENDPTCTRL_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTRL_RXT_MASK (3 << USBDEV_ENDPTCTRL_RXT_SHIFT) +# define USBDEV_ENDPTCTRL_RXT_CTRL (0 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_RXT_ISOC (1 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_RXT_BULK (2 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Bulk */ +# define USBDEV_ENDPTCTRL_RXT_INTR (3 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Interrupt */ + /* Bit 4: Reserved */ +#define USBDEV_ENDPTCTRL_RXI (1 << 5) /* Bit 5: Rx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_RXR (1 << 6) /* Bit 6: Rx data toggle reset */ +#define USBDEV_ENDPTCTRL_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ + /* Bits 8-15: Reserved */ +#define USBDEV_ENDPTCTRL_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ + /* Bit 17: Reserved */ +#define USBDEV_ENDPTCTRL_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL_TXT_MASK (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) +# define USBDEV_ENDPTCTRL_TXT_CTRL (0 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_TXT_ISOC (1 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_TXT_BULK (2 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Bulk */ +# define USBDEV_ENDPTCTRL_TXT_INTR (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Interrupt */ + /* Bit 20: Reserved */ +#define USBDEV_ENDPTCTRL_TXI (1 << 21) /* Bit 21: Tx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_TXR (1 << 22) /* Bit 22: Tx data toggle reset */ +#define USBDEV_ENDPTCTRL_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ + /* Bits 24-31: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_USB0_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h b/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h new file mode 100644 index 0000000000000000000000000000000000000000..df9d172c7568236df2afa5609b2d7d99e39165c7 --- /dev/null +++ b/arch/arm/src/lpc43xx/chip/lpc43_wwdt.h @@ -0,0 +1,111 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_wwdt.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_WWDT_H +#define __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_WWDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define LPC43_WWDT_MOD_OFFSET 0x0000 /* Watchdog mode register */ +#define LPC43_WWDT_TC_OFFSET 0x0004 /* Watchdog timer constant register */ +#define LPC43_WWDT_FEED_OFFSET 0x0008 /* Watchdog feed sequence register */ +#define LPC43_WWDT_TV_OFFSET 0x000c /* Watchdog timer value register */ +#define LPC43_WWDT_WARNINT_OFFSET 0x0014 /* Watchdog warning interrupt register */ +#define LPC43_WWDT_WINDOW_OFFSET 0x0018 /* Watchdog timer window register */ + +/* Register addresses ***************************************************************/ + +#define LPC43_WWDT_MOD (LPC43_WWDT_BASE+LPC43_WWDT_MOD_OFFSET) +#define LPC43_WWDT_TC (LPC43_WWDT_BASE+LPC43_WWDT_TC_OFFSET) +#define LPC43_WWDT_FEED (LPC43_WWDT_BASE+LPC43_WWDT_FEED_OFFSET) +#define LPC43_WWDT_TV (LPC43_WWDT_BASE+LPC43_WWDT_TV_OFFSET) +#define LPC43_WWDT_WDCLKSEL (LPC43_WWDT_BASE+LPC43_WWDT_WDCLKSEL_OFFSET) +#define LPC43_WWDT_WARNINT (LPC43_WWDT_BASE+LPC43_WWDT_WARNINT_OFFSET) +#define LPC43_WWDT_WINDOW (LPC43_WWDT_BASE+LPC43_WWDT_WINDOW_OFFSET) + +/* Register bit definitions *********************************************************/ + +/* Watchdog mode register */ + +#define WWDT_MOD_WDEN (1 << 0) /* Bit 0: Watchdog enable */ +#define WWDT_MOD_WDRESET (1 << 1) /* Bit 1: Watchdog reset enable */ +#define WWDT_MOD_WDTOF (1 << 2) /* Bit 2: Watchdog time-out */ +#define WWDT_MOD_WDINT (1 << 3) /* Bit 3: Watchdog interrupt */ +#define WWDT_MOD_WDPROTECT (1 << 4) /* Bit 4: Watchdog update mode */ + /* Bits 5-31: Reserved */ +/* Watchdog timer constant register */ + +#define WWDT_TC_MASK 0x00ffffff /* Bits 0-23: Watchdog time-out value */ + /* Bits 24-31: Reserved */ +/* Watchdog feed sequence register */ + +#define WWDT_FEED_MASK 0xff /* Bits 0-7: Feed value: 0xaa followed by 0x55 */ + /* Bits 14-31: Reserved */ +/* Watchdog timer value register */ + +#define WWDT_TV_MASK 0x00ffffff /* Bits 0-23: Counter timer value */ + /* Bits 24-31: Reserved */ +/* Watchdog warning interrupt register */ + +#define WWDT_WARNINT_MASK 0x03ff /* Bits 0-9: Watchdog warning compare value */ + /* Bits 10-31: Reserved */ +/* Watchdog timer window register */ + +#define WWDT_WINDOW_MASK 0x00ffffff /* Bits 0-23: Watchdog window value */ + /* Bits 24-31: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_WWDT_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_adc.c b/arch/arm/src/lpc43xx/lpc43_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..487c0b5cf37b5546d5b248c735509495baa13f80 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_adc.c @@ -0,0 +1,485 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_adc.c + * + * Copyright(C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Ported from from the LPC17 version: + * + * Copyright(C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright(C) 2010-2012, 2015 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "lpc43_adc.h" +#include "lpc43_cgu.h" +#include "lpc43_scu.h" +#include "lpc43_ccu.h" +#include "lpc43_creg.h" + +#include "chip/lpc43_gima.h" +#include "chip/lpc43_timer.h" + +#include "lpc43_pinconfig.h" + +#if defined(CONFIG_LPC43_ADC0) /* TODO ADC1 */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ADC0_MASK +# define CONFIG_ADC0_MASK 0x01 +#endif +#ifndef CONFIG_ADC0_FREQ +# define CONFIG_ADC0_FREQ 0 +#endif + +#define LPC43_ADC_MAX_FREQUENCY 4500000 +#define LPC43_ADC_MIN_FREQUENCY (BOARD_ABP3_FREQUENCY/256) + +#if defined(CONFIG_ADC0_USE_TIMER) && CONFIG_ADC0_FREQ == 0 +# error "Set CONFIG_ADC0_FREQ != 0 if CONFIG_ADC0_USE_TIMER" +#endif + +#ifndef CONFIG_ADC0_USE_TIMER +# if (CONFIG_ADC0_FREQ != 0 &&(CONFIG_ADC0_FREQ > LPC43_ADC_MAX_FREQUENCY || \ + CONFIG_ADC0_FREQ < LPC43_ADC_MIN_FREQUENCY)) +# error "ADC0 sample rate can't be grater than LPC43_ADC_MAX_FREQUENCY or less than LPC43_ADC_MIN_FREQUENCY" +# endif +# define CONFIG_ADC0_USE_TIMER 0 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint8_t mask; + uint8_t mask_int; + uint32_t freq; + int irq; + bool timer; + bool m_ch; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* ADC methods */ + +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); +static int adc_interrupt(int irq, void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset = adc_reset, + .ao_setup = adc_setup, + .ao_shutdown = adc_shutdown, + .ao_rxint = adc_rxint, + .ao_ioctl = adc_ioctl, +}; + +static struct up_dev_s g_adcpriv = +{ + .freq = CONFIG_ADC0_FREQ, + .mask = CONFIG_ADC0_MASK, + .mask_int = CONFIG_ADC0_MASK, + .irq = LPC43M4_IRQ_ADC0, + .timer = CONFIG_ADC0_USE_TIMER, + .m_ch = (CONFIG_ADC0_MASK & (CONFIG_ADC0_MASK - 1)) ? true : false +}; + +static struct adc_dev_s g_adcdev = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before adc_setup() and on error conditions. + * + ****************************************************************************/ + +static void adc_reset(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + irqstate_t flags; + uint32_t regval; + + if (priv->m_ch) /* calc MSB */ + { + priv->mask_int |= (priv->mask_int >> 1); + priv->mask_int |= (priv->mask_int >> 2); + priv->mask_int |= (priv->mask_int >> 4); + priv->mask_int &= ~(priv->mask_int >> 1); + } + + flags = enter_critical_section(); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU1_APB3_ADC0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_APB3_ADC0_CFG); + + /* Calc config value*/ + + regval = ADC_CR_PDN; + regval |= priv->mask; + + if (priv->freq != 0) + { + if (priv->timer) + { + /* Start adc on timer */ + + regval |= ADC_CR_START_CTOUT8; + + /* enable timer out in creg */ + + uint32_t regval_timer = getreg32(LPC43_CREG6); + regval_timer &= ~CREG6_CTOUTCTRL; + putreg32(regval_timer, LPC43_CREG6); + + /* Enable synch timer 2 match 0 to adc */ + + putreg32(GIMA_EDGE | GIMA_SYNCH | GIMA_ADC1_SELECT_T2MAT0, LPC43_GIMA_ADCSTART1); + + /* Power on */ + + regval_timer = getreg32(LPC43_CCU1_M4_TIMER2_CFG); + regval_timer |= CCU_CLK_CFG_RUN; + putreg32(regval_timer, LPC43_CCU1_M4_TIMER2_CFG); + + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET); /* disable */ + putreg32(TMR_MCR_MR0R, LPC43_TIMER2_BASE+LPC43_TMR_MCR_OFFSET); /* reset on match only */ + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_CCR_OFFSET); /* do not use capture */ + putreg32(TMR_EMR_EMC0_SET, LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET); /* external match */ + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_CTCR_OFFSET); /* counter/timer mode */ + + putreg32(LPC43_CCLK/priv->freq/2-1, LPC43_TIMER2_BASE+LPC43_TMR_PR_OFFSET); /* set clock, divide by 2 - bug in chip */ + + putreg32(1, LPC43_TMR2_MR0); /* set match on 1*/ + } + else + { + uint32_t clkdiv = BOARD_ABP3_FREQUENCY/priv->freq +(BOARD_ABP3_FREQUENCY%priv->freq != 0) - 1; + regval |= clkdiv<mask & 0x01) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C0); + } +#endif /* PINCONF_ADC0_C0 */ + +#ifdef PINCONF_ADC0_C1 + if ((priv->mask & 0x02) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C1); + } +#endif /* PINCONF_ADC0_C1 */ + +#ifdef PINCONF_ADC0_C2 + if ((priv->mask & 0x04) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C2); + } +#endif /* PINCONF_ADC0_C2 */ + +#ifdef PINCONF_ADC0_C3 + if ((priv->mask & 0x08) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C3); + } +#endif /* PINCONF_ADC0_C3 */ + +#ifdef PINCONF_ADC0_C4 + if ((priv->mask & 0x10) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C4); + } +#endif /* PINCONF_ADC0_C4 */ + +#ifdef PINCONF_ADC0_C5 + if ((priv->mask & 0x20) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C5); + } +#endif /* PINCONF_ADC0_C5 */ + +#ifdef PINCONF_ADC0_C6 + if ((priv->mask & 0x40) != 0) + { + lpc43_pin_config(PINCONF_ADC0_C6); + } +#endif /* PINCONF_ADC0_C6 */ + +#ifdef PINCONF_ADC0_C7 + if ((priv->mask & 0x80) != 0) + { + lpc43_configgpio(PINCONF_ADC0_C7); + } +#endif /* PINCONF_ADC0_C7 */ + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. Interrupts + * are all disabled upon return. + * + ****************************************************************************/ + +static int adc_setup(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + int ret = irq_attach(priv->irq, adc_interrupt); + if (ret == OK) + { + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + ****************************************************************************/ + +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + if (priv->timer) + { + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET); /* disable the timer */ + } + + /* Disable ADC interrupts, both at the level of the ADC device and at the + * level of the NVIC. + */ + + putreg32(0, LPC43_ADC0_INTEN); + up_disable_irq(priv->irq); + + /* Then detach the ADC interrupt handler. */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: adc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; + + if (enable) + { + putreg32(priv->mask_int, LPC43_ADC0_INTEN); + + if (priv->timer) + { + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_PC_OFFSET); /* reset prescale counter */ + putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_TC_OFFSET); /* reset timer counter */ + putreg32(TMR_TCR_EN, LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET); /* enable the timer */ + } + else + { + uint32_t regval = getreg32(LPC43_ADC0_CR); + + if (priv->freq == 0 && !priv->m_ch) + { + regval |= ADC_CR_START_NOW; + } + else + { + regval |= ADC_CR_BURST; + } + + putreg32(regval, LPC43_ADC0_CR); + } + } + else + { + putreg32(0, LPC43_ADC0_INTEN); + } +} + +/**************************************************************************** + * Name: adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + /* No ioctl commands supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Name: adc_interrupt + * + * Description: + * ADC interrupt handler + * + ****************************************************************************/ + +static int adc_interrupt(int irq, void *context) +{ + + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv; + uint32_t regval; + int i; + + if (priv->timer) + { + putreg32(TMR_EMR_EMC0_SET, LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET); /* put match to low */ + } + else + { + if (priv->freq == 0 && priv->m_ch) /* clear burst mode */ + { + regval = getreg32(LPC43_ADC0_CR); + regval &= ~ADC_CR_BURST; + putreg32(regval, LPC43_ADC0_CR); + } + } + + /* Read data, clear interrupt by this */ + + for(i = 0; i < 8; i++) + { + if (priv->mask & (1 << i)) + { + regval = getreg32(LPC43_ADC0_DR(i)); + adc_receive(&g_adcdev, i,(regval&ADC_DR_VVREF_MASK)>>ADC_DR_VVREF_SHIFT); + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_adcinitialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct adc_dev_s *lpc43_adcinitialize(void) +{ + return &g_adcdev; +} + +#endif /* CONFIG_LPC43_ADC0 */ diff --git a/arch/arm/src/lpc43xx/lpc43_adc.h b/arch/arm/src/lpc43xx/lpc43_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..62b2cc5b8553092905eb7841db2c03294bf8d64e --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_adc.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_adc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_ADC_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_ADC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc43_adc.h" + +#ifdef CONFIG_LPC43_ADC0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_adcinitialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct adc_dev_s *lpc43_adcinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_ADC */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_ADC_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_allocateheap.c b/arch/arm/src/lpc43xx/lpc43_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..70a0bbe5873f4078c5df98f609165d68cb605ac6 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_allocateheap.c @@ -0,0 +1,299 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_allocateheap.c + * + * Copyright (C) 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc43_emacram.h" +#include "lpc43_usbram.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Get customizations for each supported chip. + * + * SRAM Resources + * --------------------- -------- ------- ------- ------- ------- ------- + * Local SRAM LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 + * --------------------- -------- ------- ------- ------- ------- ------- + * BANK 0 (0x1000 0000) 96Kb 96Kb 128Kb 128Kb 32Kb 32Kb + * BANK 1 (0x1008 0000) 40Kb 40Kb 72Kb 72Kb 40Kb 40Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * SUBTOTAL 136Kb 136Kb 200Kb 200Kb 72Kb 72Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * AHB SRAM LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 + * --------------------- -------- ------- ------- ------- ------- ------- + * BANK 0 (0x2000 0000) 16Kb 48Kb 48Kb 48Kb 48Kb 48Kb + * BANK 1 (0x2000 8000) NOTE 1 NOTE 1 NOTE 1 NOTE 1 NOTE 1 + * BANK 2 (0x2000 c000) 16Kb 16Kb 16Kb 16Kb 16Kb 16Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * SUBTOTAL 32Kb 64Kb 64Kb 64Kb 64Kb 64Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * TOTAL 168Kb 200Kb 264Kb 264Kb 136Kb 136Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * + * --------------------- -------- ------- ------- ------- ------- ------- + * FLASH LPC4310 LPC4320 LPC4330 LPC4350 LPC4353 LPC4357 + * --------------------- -------- ------- ------- ------- ------- ------- + * BANK A (0x1a00 0000) 256Kb 512Kb + * BANK B (0x1b00 8000) 256Kb 512Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * TOTAL None None None None 512Kb 1024Kb + * --------------------- -------- ------- ------- ------- ------- ------- + * + * NOTE 1: The 64Kb of AHB of SRAM on the LPC4350/30/20 span all AHB SRAM + * banks but are treated as two banks of 48 an 16Kb by the NuttX memory + * manager. This gives some symmetry to all of the members of the family. + */ + +/* Configuration ************************************************************/ + +/* Two configurations are supported: + * + * Configuration A: + * Program memory = FLASH + * Data memory = Local RAM Bank 0 + * Additional regions = Local RAM Bank 1 + AHB SRAM (exluding DMA buffers) + * + * Configuration B: + * Program memory = Local RAM Bank 0 + * Data memory = Local RAM Bank 1 + * Additional regions = AHB SRAM (exluding DMA buffers) + * + * This file supports only memory configuration A. + * + * These should be defined in the memory map header file: + * + * LPC43_LOCSRAM_BANK0_BASE 0x10000000 + * LPC43_LOCSRAM_BANK1_BASE 0x10080000 + * LPC43_AHBSRAM_BANK0_BASE 0x20000000 + * LPC43_AHBSRAM_BANK1_BASE 0x20008000 + * LPC43_AHBSRAM_BANK2_BASE 0x2000c000 + * + * These should be defined for the specific chip in the chip.h header file. + * The value will be defined to be zero in size of the bank does not exist. + * If two banks are contiguous, the combined size will be added to the + * first bank and the size of the second bank will be defined to be zero. + * + * LPC43_LOCSRAM_BANK0_SIZE + * LPC43_LOCSRAM_BANK1_SIZE + * LPC43_AHBSRAM_BANK0_SIZE + * LPC43_AHBSRAM_BANK1_SIZE + * LPC43_AHBSRAM_BANK2_SIZE + * + * The config.h file will define only: + * + * CONFIG_RAM_START = The start of the data RAM region which may be + * either local SRAM bank 0 (Configuration A) or 1 (Configuration B). + * CONFIG_RAM_START = The size of the data RAM region. + * CONFIG_RAM_END = The sum of the above + */ + +/* Check for Configuration A. */ + +#ifndef CONFIG_LPC43_BOOT_SRAM + +/* Configuration A */ +/* CONFIG_RAM_START should be set to the base of AHB SRAM, local 0. */ + +# if CONFIG_RAM_START != LPC43_LOCSRAM_BANK0_BASE +# error "CONFIG_RAM_START must be set to the base address of RAM Bank 0" +# endif + +/* The configured RAM size should be equal to the size of local SRAM Bank 0 */ + +# if CONFIG_RAM_SIZE != LPC43_LOCSRAM_BANK0_SIZE +# error "CONFIG_RAM_SIZE must be set to size of AHB SRAM Bank 0" +# endif + +/* Now we can assign all of the memory regions for configuration A */ + +# define MM_REGION1_BASE LPC43_LOCSRAM_BANK0_BASE +# define MM_REGION1_SIZE LPC43_LOCSRAM_BANK0_SIZE +# define MM_REGION2_BASE LPC43_LOCSRAM_BANK1_BASE +# define MM_REGION2_SIZE LPC43_LOCSRAM_BANK1_SIZE +# define MM_REGION3_BASE LPC43_AHBSRAM_BANK0_BASE +# define MM_REGION3_SIZE LPC43_AHBSRAM_BANK0_SIZE +#else + +/* Configuration B */ +/* CONFIG_RAM_START should be set to the base of local SRAM, bank 1. */ + +# if CONFIG_RAM_START != LPC43_LOCSRAM_BANK1_BASE +# error "CONFIG_RAM_START must be set to the base address of SRAM Bank 1" +# endif + +/* The configured RAM size should be equal to the size of local SRAM Bank 1 */ + +# if CONFIG_RAM_SIZE != LPC43_LOCSRAM_BANK1_SIZE +# error "CONFIG_RAM_SIZE must be set to size of AHB SRAM Bank 1" +# endif + +/* Now we can assign all of the memory regions for configuration B */ + +# define MM_REGION1_BASE LPC43_LOCSRAM_BANK1_BASE +# define MM_REGION1_SIZE LPC43_LOCSRAM_BANK1_SIZE +# define MM_REGION2_BASE LPC43_AHBSRAM_BANK0_BASE +# define MM_REGION2_SIZE LPC43_AHBSRAM_BANK0_SIZE +# undef MM_REGION3_BASE +# undef MM_REGION3_SIZE +#endif + +#define MM_DMAREGION_BASE LPC43_AHBSRAM_BANK2_BASE +#define MM_DMAREGION_SIZE LPC43_AHBSRAM_BANK2_SIZE + +/* Figure out how much heap we have in the DMA region that is not being + * used by USB and/or Ethernet (if any). + */ + +#warning "Missing Logic" + +#define MM_DMAHEAP_BASE MM_DMAREGION_BASE /* For now... use it all */ +#define MM_DMAHEAP_SIZE MM_DMAREGION_SIZE + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* _sbss is the start of the BSS region (see the linker script) _ebss is the + * end of the BSS regsion (see the linker script). The idle task stack starts + * at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE + * thread is the thread that the system boots on and, eventually, becomes the + * idle, do nothing task that runs only when there is nothing else to run. + * The heap continues from there until the configured end of memory. + * g_idle_topstack is the beginning of this heap region (not necessarily aligned). + */ + +const uint32_t g_idle_topstack = (uint32_t)&_ebss + CONFIG_IDLETHREAD_STACKSIZE; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + /* Start with the first SRAM region */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#if CONFIG_MM_REGIONS > 1 + /* Add the next SRAM region (which should exist) */ + + kmm_addregion((FAR void *)MM_REGION2_BASE, MM_REGION2_SIZE); + +#ifdef MM_REGION3_BASE + /* Add the third SRAM region (which will not exist in configuration B) */ + +#if CONFIG_MM_REGIONS > 2 + /* Add the third SRAM region (which may not exist) */ + + kmm_addregion((FAR void *)MM_REGION3_BASE, MM_REGION3_SIZE); + +#if CONFIG_MM_REGIONS > 3 && defined(MM_DMAHEAP_BASE) + /* Add the DMA region (which may not be available) */ + + kmm_addregion((FAR void *)MM_DMAHEAP_BASE, MM_DMAHEAP_SIZE); + +#endif /* CONFIG_MM_REGIONS > 3 && defined(MM_DMAHEAP_BASE) */ +#endif /* CONFIG_MM_REGIONS > 2 */ +#else /* MM_REGION3_BASE */ + +#if CONFIG_MM_REGIONS > 2 && defined(MM_DMAHEAP_BASE) + /* Add the DMA region (which may not be available) */ + + kmm_addregion((FAR void *)MM_DMAHEAP_BASE, MM_DMAHEAP_SIZE); + +#endif /* CONFIG_MM_REGIONS > 3 && defined(MM_DMAHEAP_BASE) */ +#endif /* MM_REGION3_BASE */ +#endif /* CONFIG_MM_REGIONS > 1 */ +} +#endif diff --git a/arch/arm/src/lpc43xx/lpc43_ccu.h b/arch/arm/src/lpc43xx/lpc43_ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..21fd0b1b147bdda907b20d3b95750ac25f4b1b92 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ccu.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_ccu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_CCU_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_CCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc43_ccu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_CCU_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_cgu.c b/arch/arm/src/lpc43xx/lpc43_cgu.c new file mode 100644 index 0000000000000000000000000000000000000000..74668fcd650e9de9031fb83fce8bf97da3f989dc --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_cgu.c @@ -0,0 +1,716 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_cgu.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_arch.h" +#include "lpc43_cgu.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Maximum/Threashold Frequencies *******************************************/ + +#define LOW_XTAL_FREQUENCY 15000000 +#define MAX_XTAL_FREQUENCY 25000000 + +#define MAX_FCLKOUT_FREQUENCY 204000000 +#define MAX_FCLKOUT_DIRECT 156000000 +#define MAX_FCCO_FRQUENCY 320000000 + +/* Configuration ************************************************************/ +/* This supports configuration of CGU clocking from board-specific parameters + * that must be provided in the board.h header file. + * + * That header file must provided the following values: + * + * BOARD_XTAL_FREQUENCY - The LPC43xx XTAL oscillator input frequency + */ + +#ifndef BOARD_XTAL_FREQUENCY +# error "board.h must provide the LPC43xx cystal input frequency (BOARD_XTAL_FREQUENCY)" +#endif + +#if BOARD_XTAL_FREQUENCY >= MAX_XTAL_FREQUENCY +# error "BOARD_XTAL_FREQUENCY exceeds the maximum value" +#endif + +#if BOARD_FCLKOUT_FREQUENCY > MAX_FCLKOUT_FREQUENCY +# error "BOARD_FCLKOUT_FREQUENCY exceed the maximum" +#endif + +#if BOARD_FCCO_FREQUENCY > MAX_FCCO_FRQUENCY +# error "BOARD_FCCO_FREQUENCY exceed the maximum" +#endif + +/* Convert the user-friendly definitions in board.h to register bit settings */ + +/* Check if we are using a RAMP */ + +#undef PLL_RAMP + +#ifdef BOARD_PLL_RAMP_MSEL + +# define PLL_RAMP 1 + + /* Get initial PLL values */ + +# define INIT_MSEL_VALUE PLL1_CTRL_MSEL(1) +# define INIT_NSEL_VALUE PLL1_CTRL_NSEL_DIV1 + + /* Pick the initial PSEL value (integer mode) */ + +# ifndef BOARD_XTAL_FREQUENCY +# error "BOARD_XTAL_FREQUENCY is not defined in board.h" +# endif + +# if BOARD_XTAL_FREQUENCY >= MAX_FCLKOUT_DIRECT +# error "BOARD_XTAL_FREQUENCY value is not supported" +# endif + +# if (2 * BOARD_XTAL_FREQUENCY) > MAX_FCCO_FRQUENCY +# error "Impossible value for BOARD_XTAL_FREQUENCY" +# elif (2 * 2 * BOARD_XTAL_FREQUENCY) > MAX_FCCO_FRQUENCY +# define INIT_PSEL_VALUE PLL1_CTRL_PSEL_DIV1 +# elif (2 * 4 * BOARD_XTAL_FREQUENCY) > MAX_FCCO_FRQUENCY +# define INIT_PSEL_VALUE PLL1_CTRL_PSEL_DIV2 +# elif (2 * 8 * BOARD_XTAL_FREQUENCY) > MAX_FCCO_FRQUENCY +# define INIT_PSEL_VALUE PLL1_CTRL_PSEL_DIV4 +# else +# define INIT_PSEL_VALUE PLL1_CTRL_PSEL_DIV8 +# endif + + /* Select initial integer mode controls */ + +# define INIT_PLL_CONTROLS \ + (PLL1_CTRL_FBSEL | INIT_PSEL_VALUE | INIT_NSEL_VALUE | INIT_MSEL_VALUE) + + /* Select a value close to a 10 millisecond delay */ + +# define XTAL_DELAY \ + (10 * BOARD_XTAL_FREQUENCY + (LPC43_CCLK - 1)) / LPC43_CCLK + + /* Check the ramp-up MSEL value */ + +# if (BOARD_PLL_RAMP_MSEL > 0) && (BOARD_PLL_RAMP_MSEL < 256) +# define RAMP_MSEL_VALUE PLL1_CTRL_MSEL(BOARD_PLL_RAMP_MSEL) +# else +# error "Unsupported value of BOARD_PLL_RAMP_NSEL" +# endif + + /* Check the ramp-up NSEL value */ + +# ifndef BOARD_PLL_RAMP_NSEL +# error "BOARD_PLL_RAMP_NSEL is not defined in board.h" +# endif + +# if BOARD_PLL_RAMP_NSEL == 1 +# define RAMP_NSEL_VALUE PLL1_CTRL_NSEL_DIV1 +# elif BOARD_PLL_RAMP_NSEL == 2 +# define RAMP_NSEL_VALUE PLL1_CTRL_NSEL_DIV2 +# elif BOARD_PLL_RAMP_NSEL == 3 +# define RAMP_NSEL_VALUE PLL1_CTRL_NSEL_DIV3 +# elif BOARD_PLL_RAMP_NSEL == 4 +# define RAMP_NSEL_VALUE PLL1_CTRL_NSEL_DIV4 +# else +# error "Unsupported value of BOARD_PLL_RAMP_NSEL" +# endif + + /* Check for direct mode */ + +# ifndef BOARD_RAMP_FCLKOUT +# error "BOARD_RAMP_FCLKOUT is not defined in board.h" +# endif + +# if BOARD_RAMP_FCLKOUT >= MAX_FCLKOUT_DIRECT + + /* Select direct mode controls */ + +# define RAMP_PLL_CONTROLS \ + (PLL1_CTRL_FBSEL | PLL1_CTRL_DIRECT | RAMP_NSEL_VALUE | RAMP_MSEL_VALUE) + +# else + + /* Check the ramp-up PSEL value */ + +# ifndef BOARD_PLL_RAMP_PSEL +# error "BOARD_PLL_RAMP_PSEL is not defined in board.h" +# endif + +# if BOARD_PLL_RAMP_PSEL == 1 +# define RAMP_PSEL_VALUE PLL1_CTRL_PSEL_DIV1 +# elif BOARD_PLL_RAMP_PSEL == 2 +# define RAMP_PSEL_VALUE PLL1_CTRL_PSEL_DIV2 +# elif BOARD_PLL_RAMP_PSEL == 4 +# define RAMP_PSEL_VALUE PLL1_CTRL_PSEL_DIV4 +# elif BOARD_PLL_RAMP_PSEL == 8 +# define RAMP_PSEL_VALUE PLL1_CTRL_PSEL_DIV8 +# else +# error "Unsupported value of BOARD_PLL_RAMP_PSEL" +# endif +# endif + + /* Select integer mode controls */ + +# define RAMP_PLL_CONTROLS \ + (PLL1_CTRL_FBSEL | RAMP_PSEL_VALUE | RAMP_NSEL_VALUE | RAMP_MSEL_VALUE) + + /* Select a value close to a 10 millisecond delay */ + +#endif + + /* Check the Final MSEL value */ + +#ifndef BOARD_PLL_MSEL +# error "BOARD_PLL_MSEL is not defined in board.h" +#endif + +#if (BOARD_PLL_MSEL > 0) && (BOARD_PLL_MSEL < 256) +# define CTRL_MSEL_VALUE PLL1_CTRL_MSEL(BOARD_PLL_MSEL) +#else +# error "Unsupported value of BOARD_PLL_MSEL" +#endif + + /* Check the Final NSEL value */ + +#ifndef BOARD_PLL_NSEL +# error "BOARD_PLL_NSEL is not defined in board.h" +#endif + +#if BOARD_PLL_NSEL == 1 +# define CTRL_NSEL_VALUE PLL1_CTRL_NSEL_DIV1 +#elif BOARD_PLL_NSEL == 2 +# define CTRL_NSEL_VALUE PLL1_CTRL_NSEL_DIV2 +#elif BOARD_PLL_NSEL == 3 +# define CTRL_NSEL_VALUE PLL1_CTRL_NSEL_DIV3 +#elif BOARD_PLL_NSEL == 4 +# define CTRL_NSEL_VALUE PLL1_CTRL_NSEL_DIV4 +#else +# error "Unsupported value of BOARD_PLL_NSEL" +#endif + + /* Check for direct mode */ + +#ifndef BOARD_FCLKOUT_FREQUENCY +# error "BOARD_FCLKOUT_FREQUENCY is not defined in board.h" +#endif + +#if BOARD_FCLKOUT_FREQUENCY >= MAX_FCLKOUT_DIRECT + + /* Select direct mode controls */ + +# define PLL_CONTROLS \ + (PLL1_CTRL_FBSEL | PLL1_CTRL_DIRECT | CTRL_NSEL_VALUE | CTRL_MSEL_VALUE) + +# else + + /* Check the Final PSEL value */ + +# ifndef BOARD_PLL_PSEL +# error "BOARD_PLL_PSEL is not defined in board.h" +# endif + +# if BOARD_PLL_PSEL == 1 +# define CTRL_PSEL_VALUE PLL1_CTRL_PSEL_DIV1 +# elif BOARD_PLL_PSEL == 2 +# define CTRL_PSEL_VALUE PLL1_CTRL_PSEL_DIV2 +# elif BOARD_PLL_PSEL == 4 +# define CTRL_PSEL_VALUE PLL1_CTRL_PSEL_DIV4 +# elif BOARD_PLL_PSEL == 8 +# define CTRL_PSEL_VALUE PLL1_CTRL_PSEL_DIV8 +# else +# error "Unsupported value of BOARD_PLL_PSEL" +# endif + + /* Select integer mode controls */ + +# define PLL_CONTROLS \ + (PLL1_CTRL_FBSEL | CTRL_PSEL_VALUE | CTRL_NSEL_VALUE | CTRL_MSEL_VALUE) + +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_xtalconfig + * + * Description: + * Configure the cystal input to PLL1 using the settings provided in + * the board.h file. + * + ****************************************************************************/ + +static inline void lpc43_xtalconfig(void) +{ + /* Configure the crystal input to PLL1 */ + + uint32_t regval; + + /* Set/clear the HF bit in the crystal oscillator control register. + * - The bit must be cleared if low-frequency oscillators (<=15MHz) + * - The HF bit must be set for high-frequency osciallators (>20MHz) + * - For oscillators in the range 15-20 MHz, the HF setting does not matter. + */ + + regval = getreg32(LPC43_XTAL_OSC_CTRL); +#if BOARD_XTAL_FREQUENCY <= LOW_XTAL_FREQUENCY + regval &= ~XTAL_OSC_CTRL_HF; +#else + regval |= XTAL_OSC_CTRL_HF; +#endif + putreg32(regval, LPC43_XTAL_OSC_CTRL); + + /* Enable the crystal oscillator by taking it out of power down mode */ + + regval &= ~XTAL_OSC_CTRL_ENABLE; + putreg32(regval, LPC43_XTAL_OSC_CTRL); + + /* Delay for stable clock input */ + + up_mdelay(20); + + /* Select the crystal oscillator as the input to PLL1 */ + + regval = getreg32(LPC43_PLL1_CTRL); + regval &= ~PLL1_CTRL_CLKSEL_MASK; + regval |= PLL1_CLKSEL_XTAL | PLL1_CTRL_AUTOBLOCK; + putreg32(regval, LPC43_PLL1_CTRL); +} + +/**************************************************************************** + * Name: lpc43_pll1config + * + * Description: + * Configure PLL1 dividers and multipliers per the settings in the board.h + * file to generate the desired Fclkcout and Fcco frequencies. + * + ****************************************************************************/ + +static inline void lpc43_pll1config(uint32_t ctrlvalue) +{ + uint32_t regval; + + /* Clear PLL1 controls: + * + * - PLL1_CTRL_BYPASS: Input clock bypass control + * - PLL1_CTRL_FBSEL: PLL1 feedback select + * - PLL1_CTRL_DIRECT: PLL1 direct CCO output + * - PLL1_CTRL_PSEL_MASK: Post-divider division ratio P (psel) + * - PLL1_CTRL_NSEL_MASK: Pre-divider division ratio N (nsel) + * - PLL1_CTRL_MSEL_MASK: Feedback-divider division ratio M (msel) + */ + + regval = getreg32(LPC43_PLL1_CTRL); + regval &= ~(PLL1_CTRL_BYPASS | PLL1_CTRL_FBSEL | PLL1_CTRL_DIRECT | + PLL1_CTRL_PSEL_MASK | PLL1_CTRL_NSEL_MASK | + PLL1_CTRL_MSEL_MASK); + + /* Set selected PLL1 controls: + * + * - PLL1_CTRL_FBSEL: Set in both integer and direct modes + * - PLL1_CTRL_DIRECT: Set in direct mode + * - PLL1_CTRL_PSEL: Set to the value from board.h (integer mode only) + * - PLL1_CTRL_NSEL: Set to the value from board.h + * - PLL1_CTRL_MSEL: Set to the value from board.h + */ + + regval |= ctrlvalue; + putreg32(regval, LPC43_PLL1_CTRL); +} + +/**************************************************************************** + * Name: lpc43_pll1enable + * + * Description: + * Take PLL1 out of power-down mode and wait until it is locked onto the + * input clock. + * + ****************************************************************************/ + +static inline void lpc43_pll1enable(void) +{ + uint32_t regval; + + /* Take PLL1 out of power down mode. The reset state of the PD bit + * is one, i.e., powered down. + */ + + regval = getreg32(LPC43_PLL1_CTRL); + regval &= ~PLL1_CTRL_PD; + putreg32(regval, LPC43_PLL1_CTRL); + + /* When the power-down mode is terminated, PPL1 will resume its normal + * operation and will make the lock signal high once it has regained + * lock on the input clock + * + * Wait for PLL1 to report that it is locked. + */ + + while ((getreg32(LPC43_PLL1_STAT) & PLL1_STAT_LOCK) == 0); +} + +/**************************************************************************** + * Name: lpc43_m4clkselect + * + * Description: + * Select PLL1 output as the Cortex-M4 source clock. + * + ****************************************************************************/ + +static inline void lpc43_m4clkselect(uint32_t clksel) +{ + uint32_t regval; + + regval = getreg32(LPC43_BASE_M4_CLK); + regval &= ~BASE_M4_CLK_CLKSEL_MASK; + regval |= clksel; + putreg32(regval, LPC43_BASE_M4_CLK); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_pll0usbconfig + * + * Description: + * Configure PLL0USB dividers and multipliers per the settings in the board.h + * file to generate the desired Fclkcout and Fcco frequencies. + * + ****************************************************************************/ + +void lpc43_pll0usbconfig(void) +{ + /* Power down, no bypass, direct i-o, */ + + putreg32((PLL0USB_CTRL_PD | PLL0USB_CTRL_DIRECTI | PLL0USB_CTRL_DIRECTO | PLL0USB_CTRL_CLKEN | PLL0USB_CTRL_AUTOBLOCK | BOARD_USB0_CLKSRC), LPC43_PLL0USB_CTRL); + + putreg32(BOARD_USB0_MDIV, LPC43_PLL0USB_MDIV); + putreg32(BOARD_USB0_NP_DIV, LPC43_PLL0USB_NP_DIV); +} + +/**************************************************************************** + * Name: lpc43_enetclkconfig(void) + * + * Description: + * Initialise ethernet clock block to take clock from ENET_TX_CLK. + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_ETHERNET) +void lpc43_enetclkconfig(void) + +{ + /* Note that using TXCLK for RX implies use of RMII */ + +#if defined(CONFIG_LPC43_RMII) + putreg32((BASE_LCD_CLKSEL_ENET_TXCLK | BASE_LCD_CLK_AUTOBLOCK), + LPC43_BASE_PHYRX_CLK); +#else + putreg32((BASE_LCD_CLKSEL_ENET_RXCLK | BASE_LCD_CLK_AUTOBLOCK), + LPC43_BASE_PHYRX_CLK); +#endif + putreg32((BASE_LCD_CLKSEL_ENET_TXCLK | BASE_LCD_CLK_AUTOBLOCK), + LPC43_BASE_PHYTX_CLK); +} +#endif + +/**************************************************************************** + * Name: lpc43_pll0usbenable + * + * Description: + * Take PLL0USB out of power-down mode and wait until it is locked onto the + * input clock. + * + ****************************************************************************/ + +void lpc43_pll0usbenable(void) +{ + uint32_t regval; + + /* Take PLL0 out of power down mode. The reset state of the PD bit + * is one, i.e., powered down. + */ + + regval = getreg32(LPC43_PLL0USB_CTRL); + regval &= ~PLL0USB_CTRL_PD; + putreg32(regval, LPC43_PLL0USB_CTRL); + + /* When the power-down mode is terminated, PPL0 will resume its normal + * operation and will make the lock signal high once it has regained + * lock on the input clock + * + * Wait for PLL0 to report that it is locked. + */ + + while ((getreg32(LPC43_PLL0USB_STAT) & PLL0USB_STAT_LOCK) == 0); +} + +/**************************************************************************** + * Name: lpc43_pll0usbdisable + * + * Description: + * Take PLL0USB to power-down mode. + * + ****************************************************************************/ + +void lpc43_pll0usbdisable(void) +{ + uint32_t regval; + + /* Take PLL1 out of power down mode. The reset state of the PD bit + * is one, i.e., powered down. + */ + + regval = getreg32(LPC43_PLL0USB_CTRL); + regval |= PLL0USB_CTRL_PD; + putreg32(regval, LPC43_PLL0USB_CTRL); +} + +#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC) +void lpc43_idiva(void) +{ + uint32_t regval; + + /* Set clock source, divider */ + + regval = getreg32(LPC43_IDIVA_CTRL); + regval &= ~(IDIVA_CTRL_CLKSEL_MASK | IDIVA_CTRL_IDIV_MASK); + regval |= BOARD_IDIVA_CLKSRC | IDIVA_CTRL_AUTOBLOCK | IDIVA_CTRL_IDIV(BOARD_IDIVA_DIVIDER); + putreg32(regval, LPC43_IDIVA_CTRL); +} +#endif + +#if defined(BOARD_IDIVB_DIVIDER) && defined(BOARD_IDIVB_CLKSRC) +void lpc43_idivb(void) +{ + uint32_t regval; + + /* Set clock source, divider */ + + regval = getreg32(LPC43_IDIVB_CTRL); + regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK); + regval |= BOARD_IDIVB_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVB_DIVIDER); + putreg32(regval, LPC43_IDIVB_CTRL); +} +#endif + +#if defined(BOARD_IDIVC_DIVIDER) && defined(BOARD_IDIVC_CLKSRC) +void lpc43_idivc(void) +{ + uint32_t regval; + + /* Set clock source, divider */ + + regval = getreg32(LPC43_IDIVC_CTRL); + regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK); + regval |= BOARD_IDIVC_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVC_DIVIDER); + putreg32(regval, LPC43_IDIVC_CTRL); +} +#endif + +#if defined(BOARD_IDIVD_DIVIDER) && defined(BOARD_IDIVD_CLKSRC) +void lpc43_idivd(void) +{ + uint32_t regval; + + /* Set clock source, divider */ + + regval = getreg32(LPC43_IDIVD_CTRL); + regval &= ~(IDIVBCD_CTRL_CLKSEL_MASK | IDIVBCD_CTRL_IDIV_MASK); + regval |= BOARD_IDIVD_CLKSRC | IDIVBCD_CTRL_AUTOBLOCK | IDIVBCD_CTRL_IDIV(BOARD_IDIVD_DIVIDER); + putreg32(regval, LPC43_IDIVD_CTRL); +} +#endif + +#if defined(BOARD_IDIVE_DIVIDER) && defined(BOARD_IDIVE_CLKSRC) +void lpc43_idive(void) +{ + uint32_t regval; + + /* Set clock source, divider */ + + regval = getreg32(LPC43_IDIVE_CTRL); + regval &= ~(IDIVE_CTRL_CLKSEL_MASK | IDIVE_CTRL_IDIV_MASK); + regval |= BOARD_IDIVE_CLKSRC | IDIVE_CTRL_AUTOBLOCK | IDIVE_CTRL_IDIV(BOARD_IDIVE_DIVIDER); + putreg32(regval, LPC43_IDIVE_CTRL); +} +#endif + +#if defined(BOARD_ABP1_CLKSRC) +void lpc43_abp1(void) +{ + uint32_t regval; + + /* Set clock source */ + + regval = getreg32(LPC43_BASE_APB1_CLK); + regval &= ~BASE_APB_CLK_CLKSEL_MASK; + regval |= BOARD_ABP1_CLKSRC | BASE_APB_CLK_AUTOBLOCK; + putreg32(regval, LPC43_BASE_APB1_CLK); +} +#endif + +#if defined(BOARD_ABP3_CLKSRC) +void lpc43_abp3(void) +{ + uint32_t regval; + + /* Set clock source */ + + regval = getreg32(LPC43_BASE_APB3_CLK); + regval &= ~BASE_APB_CLK_CLKSEL_MASK; + regval |= BOARD_ABP3_CLKSRC | BASE_APB_CLK_AUTOBLOCK; + putreg32(regval, LPC43_BASE_APB3_CLK); +} +#endif + + +/**************************************************************************** + * Name: lpc43_clockconfig + * + * Description: + * Called to initialize the LPC43XX. This does whatever setup is needed + * to put the MCU in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void lpc43_clockconfig(void) +{ + /* Configure the crystal input to PLL1 */ + + lpc43_xtalconfig(); + +#ifndef PLL_RAMP + /* Configure PLL1 */ + + lpc43_pll1config(PLL_CONTROLS); + + /* Enable PLL1 */ + + lpc43_pll1enable(); + + /* Set up PLL1 output as the M4 clock */ + + lpc43_m4clkselect(BASE_M4_CLKSEL_PLL1); +#else + + /* Drive the M4 clock from the XTAL until the PLL is configured */ + + lpc43_m4clkselect(BASE_M4_CLKSEL_XTAL); + + /* Select the initial PLL1 configured (BOARD_XTAL_FREQUENCY x 1) */ + + lpc43_pll1config(INIT_PLL_CONTROLS); + + /* Enable PLL1 */ + + lpc43_pll1enable(); + + /* Delay around 10 milliseconds */ + + up_mdelay(XTAL_DELAY); + + /* Configure the intermediate, ramp-up configuration for PLL1 */ + + lpc43_pll1config(RAMP_PLL_CONTROLS); + + /* Set up PLL1 output as the M4 clock */ + + lpc43_m4clkselect(BASE_M4_CLKSEL_PLL1); + + /* Delay around 10 milliseconds */ + + up_mdelay(XTAL_DELAY); + + /* Go to the final, full-speed PLL1 configuration */ + + lpc43_pll1config(PLL_CONTROLS); +#endif + + /* Configure idivs */ + +#if defined(BOARD_IDIVA_DIVIDER) && defined(BOARD_IDIVA_CLKSRC) + lpc43_idiva(); +#endif + +#if defined(BOARD_IDIVB_DIVIDER) && defined(BOARD_IDIVB_CLKSRC) + lpc43_idivb(); +#endif + +#if defined(BOARD_IDIVC_DIVIDER) && defined(BOARD_IDIVC_CLKSRC) + lpc43_idivc(); +#endif + +#if defined(BOARD_IDIVD_DIVIDER) && defined(BOARD_IDIVD_CLKSRC) + lpc43_idivd(); +#endif + +#if defined(BOARD_IDIVE_DIVIDER) && defined(BOARD_IDIVE_CLKSRC) + lpc43_idive(); +#endif + + /* Configure abpXs */ + +#if defined(BOARD_ABP1_CLKSRC) + lpc43_abp1(); +#endif + +#if defined(BOARD_ABP3_CLKSRC) + lpc43_abp3(); +#endif + +#if defined(CONFIG_LPC43_ETHERNET) + /* Configure ethernet */ + + lpc43_enetclkconfig(); +#endif +} diff --git a/arch/arm/src/lpc43xx/lpc43_cgu.h b/arch/arm/src/lpc43xx/lpc43_cgu.h new file mode 100644 index 0000000000000000000000000000000000000000..6cdfff5ba745d45f09c3d0cd54c277486b1beb74 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_cgu.h @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_cgu.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_CGU_H +#define __ARCH_ARM_SRC_LPC43XX_CGU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc43_cgu.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_pll0usbdisable + * + * Description: + * Take PLL0USB to power-down mode. + * + ****************************************************************************/ + +EXTERN void lpc43_pll0usbdisable(void); + +/**************************************************************************** + * Name: lpc43_pll0usbenable + * + * Description: + * Take PLL0USB out of power-down mode and wait until it is locked onto the + * input clock. + * + ****************************************************************************/ + +EXTERN void lpc43_pll0usbenable(void); + +/************************************************************************************ + * Name: lpc43_pll0usbconfig + * + * Description: + * Config USB0 PLL + * + ************************************************************************************/ + +EXTERN void lpc43_pll0usbconfig(void); + +/************************************************************************************ + * Name: lpc43_clockconfig + * + * Description: + * Called to initialize the LPC43XX. This does whatever setup is needed to put the + * MCU in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void lpc43_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_CGU_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_clrpend.c b/arch/arm/src/lpc43xx/lpc43_clrpend.c new file mode 100644 index 0000000000000000000000000000000000000000..cb3ce5f095e1798f1550e77436457d426f6c234b --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_clrpend.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_clrpend.c + * arch/arm/src/chip/lpc43_clrpend.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nvic.h" +#include "up_arch.h" + +#include "lpc43_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. Don't know why... but the LPC4366 Ethernet EMAC + * interrupt definitely needs it! + * + * This function is logically a part of lpc43_irq.c, but I will keep it in + * a separate file so that it will not increase the footprint on LPC43xx + * platforms that do not need this function. + * + ****************************************************************************/ + +void lpc43_clrpend(int irq) +{ + /* Check for external interrupt */ + + if (irq >= LPC43_IRQ_EXTINT) + { + if (irq < (LPC43_IRQ_EXTINT + 32)) + { + putreg32(1 << (irq - LPC43_IRQ_EXTINT), NVIC_IRQ0_31_CLRPEND); + } + else if (irq < LPC43M4_IRQ_NIRQS) + { + putreg32(1 << (irq - LPC43_IRQ_EXTINT - 32), NVIC_IRQ32_63_CLRPEND); + } + } +} diff --git a/arch/arm/src/lpc43xx/lpc43_config.h b/arch/arm/src/lpc43xx/lpc43_config.h new file mode 100644 index 0000000000000000000000000000000000000000..8a4509b8f049e6ffc9936ebdb2e5564ee86a72a4 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_config.h @@ -0,0 +1,158 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_config.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43XX_CONFIG_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43XX_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Required configuration settings */ + +/* There are two version of the FPU support built into the most NuttX Cortex-M4 ports. + * The current LPC43xx port support only one of these options, the "Non-Lazy Floating + * Point Register Save". As a consequence, CONFIG_ARMV7M_CMNVECTOR must be defined + * in *all* LPC43xx configuration files. + */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR +# error "CONFIG_ARMV7M_CMNVECTOR must be defined for the LPC43xx" +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_LPC43_USART0) || defined(CONFIG_LPC43_UART1) || \ + defined(CONFIG_LPC43_USART2) || defined(CONFIG_LPC43_USART3) +# define HAVE_UART 1 +#endif + +/* Make sure all features are disabled for diabled U[S]ARTs. This simplifies + * checking later. + */ + +#ifndef CONFIG_LPC43_USART0 +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART0_RS485MODE +# undef CONFIG_USART0_RS485_DTRDIR +#endif + +#ifndef CONFIG_LPC43_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART1_RS485MODE +# undef CONFIG_UART1_RS485_DTRDIR +#endif + +#ifndef CONFIG_LPC43_USART2 +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART2_RS485MODE +# undef CONFIG_USART2_RS485_DTRDIR +#endif + +#ifndef CONFIG_LPC43_USART3 +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART3_RS485MODE +# undef CONFIG_USART3_RS485_DTRDIR +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3 - OR - there might not be any serial console at all. + */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef HAVE_CONSOLE +#endif + +/* Check UART flow control (Only supported by UART1) */ + +# undef CONFIG_USART0_FLOWCONTROL +# undef CONFIG_USART2_FLOWCONTROL +# undef CONFIG_USART3_FLOWCONTROL +#ifndef CONFIG_LPC43_UART1 +# undef CONFIG_UART1_FLOWCONTROL +#endif + +/* Check for RS-485 support (All USARTS & UART1) */ + +#undef HAVE_RS485 +#if defined(CONFIG_USART0_RS485MODE) || defined(CONFIG_UART1_RS485MODE) || \ + defined(CONFIG_USART2_RS485MODE) || defined(CONFIG_USART3_RS485MODE) +# define HAVE_RS485 1 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43XX_CONFIG_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_creg.h b/arch/arm/src/lpc43xx/lpc43_creg.h new file mode 100644 index 0000000000000000000000000000000000000000..d917bd63815c1b28baf0ebfb71b9bbfc5252ba02 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_creg.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_creg.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_CREG_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_CREG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc43_creg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_CREG_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_dac.c b/arch/arm/src/lpc43xx/lpc43_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..16fa92a36547167452602bb8142ac73d9a7cb2c5 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_dac.c @@ -0,0 +1,204 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_dac.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Ported from from the LPC17 version: + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2011-08-05 initial version + * + * This file is a part of NuttX: + * + * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "lpc43_syscon.h" +#include "lpc43_pinconn.h" +#include "lpc43_dac.h" + +#ifdef CONFIG_LPC43_DAC + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* DAC methods */ + +static void dac_reset(FAR struct dac_dev_s *dev); +static int dac_setup(FAR struct dac_dev_s *dev); +static void dac_shutdown(FAR struct dac_dev_s *dev); +static void dac_txint(FAR struct dac_dev_s *dev, bool enable); +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); +static int dac_interrupt(int irq, void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct dac_ops_s g_dacops = +{ + .ao_reset = dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, +}; + +static struct dac_dev_s g_dacdev = +{ + .ad_ops = &g_dacops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Reset the DAC device. Called early to initialize the hardware. This + * is called, before ao_setup() and on error conditions. + */ + +static void dac_reset(FAR struct dac_dev_s *dev) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + regval = getreg32(LPC43_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_DAC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_DAC_SHIFT); + putreg32(regval, LPC43_SYSCON_PCLKSEL0); + + //putreg32(DAC_CTRL_DBLBUFEN, LPC43_DAC_CTRL); ? + + lpc43_configgpio(GPIO_AOUT); + + leave_critical_section(flags); +} + +/* Configure the DAC. This method is called the first time that the DAC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching DAC interrupts. Interrupts + * are all disabled upon return. + */ + +static int dac_setup(FAR struct dac_dev_s *dev) +{ + return OK; +} + +/* Disable the DAC. This method is called when the DAC device is closed. + * This method reverses the operation the setup method. + */ + +static void dac_shutdown(FAR struct dac_dev_s *dev) +{ +} + +/* Call to enable or disable TX interrupts */ + +static void dac_txint(FAR struct dac_dev_s *dev, bool enable) +{ +} + +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) +{ + putreg32((msg->am_data >> 16) & 0xfffff, LPC43_DAC_CR); + dac_txdone(&g_dacdev); + return 0; +} + +/* All ioctl calls will be routed through this method */ + +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) +{ + dbg("Fix me:Not Implemented\n"); + return 0; +} + +static int dac_interrupt(int irq, void *context) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct dac_dev_s *lpc43_dacinitialize(void) +{ + return &g_dacdev; +} + +#endif /* CONFIG_LPC43_DAC */ diff --git a/arch/arm/src/lpc43xx/lpc43_dac.h b/arch/arm/src/lpc43xx/lpc43_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..f652d71c9b271a549a9e1e1ac200fa2a3dcfa9e3 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_dac.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_dac.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_DAC_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_DAC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc43_dac.h" + +#ifdef CONFIG_LPC43_DAC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct dac_dev_s *lpc43_dacinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_DAC */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_DAC_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_debug.c b/arch/arm/src/lpc43xx/lpc43_debug.c new file mode 100644 index 0000000000000000000000000000000000000000..51cf9470672601f15904c445e435afdcbd7c058a --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_debug.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_debug.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" +#include "lpc43_pinconfig.h" +#include "lpc43_gpio.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Function: lpc43_pin_dump + * + * Description: + * Dump all pin configuration registers associated with the provided pin + * configuration + * + ****************************************************************************/ + +int lpc43_pin_dump(uint32_t pinconf, const char *msg) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/******************************************************************************************** + * Function: lpc43_gpio_dump + * + * Description: + * Dump all pin configuration registers associated with the provided base address + * + ********************************************************************************************/ + +int lpc43_gpio_dump(uint16_t gpiocfg, const char *msg) +{ +#warning "Missing logic" + return -ENOSYS; +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/lpc43xx/lpc43_ehci.c b/arch/arm/src/lpc43xx/lpc43_ehci.c new file mode 100644 index 0000000000000000000000000000000000000000..08b2ae8e0f99344819224fcb2735b9bb03d59f40 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ehci.c @@ -0,0 +1,5178 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_ehci.c + * + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "chip/lpc43_usb0.h" +#include "up_arch.h" + +#include "lpc43_cgu.h" +#include "chip/lpc43_creg.h" +#include "chip/lpc43_evntrtr.h" + +#if defined(CONFIG_LPC43_USBOTG) && defined(CONFIG_USBHOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* Pre-requisites */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#elif !defined(CONFIG_SCHED_HPWORK) +# error Hi-priority work queue support is required (CONFIG_SCHED_HPWORK) +#endif + +/* Configurable number of Queue Head (QH) structures. The default is one per + * Root hub port plus one for EP0. + */ + +#ifndef CONFIG_LPC43_EHCI_NQHS +# define CONFIG_LPC43_EHCI_NQHS (LPC43_EHCI_NRHPORT + 1) +#endif + +/* Configurable number of Queue Element Transfer Descriptor (qTDs). The default + * is one per root hub plus three from EP0. + */ + +#ifndef CONFIG_LPC43_EHCI_NQTDS +# define CONFIG_LPC43_EHCI_NQTDS (LPC43_EHCI_NRHPORT + 3) +#endif + +/* Configurable size of a request/descriptor buffers */ + +#ifndef CONFIG_LPC43_EHCI_BUFSIZE +# define CONFIG_LPC43_EHCI_BUFSIZE 128 +#endif + +/* Debug options */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_LPC43_EHCI_REGDEBUG +#endif + +/* Isochronous transfers are not currently supported */ + +#undef CONFIG_USBHOST_ISOC_DISABLE +#define CONFIG_USBHOST_ISOC_DISABLE 1 + +/* Simplify DEBUG checks */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_USB +#endif + +/* Registers *******************************************************************/ +/* Traditionally, NuttX specifies register locations using individual + * register offsets from a base address. That tradition is broken here and, + * instead, register blocks are represented as structures. This is done here + * because, in principle, EHCI operational register address may not be known + * at compile time; the operational registers lie at an offset specified in + * the 'caplength' byte of the Host Controller Capability Registers. + * + * However, for the case of the LPC43 EHCI, we know apriori that locations + * of these register blocks. + */ + +/* Host Controller Capability Registers */ + +#define HCCR ((struct ehci_hccr_s *)LPC43_USBOTG_HCCR_BASE) + +/* Host Controller Operational Registers */ + +#define HCOR ((volatile struct ehci_hcor_s *)LPC43_USBOTG_HCOR_BASE) + +/* Interrupts ******************************************************************/ +/* This is the set of interrupts handled by this driver */ + +#define EHCI_HANDLED_INTS (EHCI_INT_USBINT | EHCI_INT_USBERRINT | \ + EHCI_INT_PORTSC | EHCI_INT_SYSERROR | \ + EHCI_INT_AAINT) + +/* The periodic frame list is a 4K-page aligned array of Frame List Link + * pointers. The length of the frame list may be programmable. The programmability + * of the periodic frame list is exported to system software via the HCCPARAMS + * register. If non-programmable, the length is 1024 elements. If programmable, + * the length can be selected by system software as one of 256, 512, or 1024 + * elements. + */ + +#define FRAME_LIST_SIZE 1024 + +/* DMA *************************************************************************/ +/* For now, we are assuming an identity mapping between physical and virtual + * address spaces. + */ + +#define lpc43_physramaddr(a) (a) +#define lpc43_virtramaddr(a) (a) + +/* USB trace *******************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +# define TR_FMT1 false +# define TR_FMT2 true + +# define TRENTRY(id,fmt1,string) {string} + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) +#endif + +/* Port numbers */ + +#define RHPNDX(rh) ((rh)->hport.hport.port) +#define RHPORT(rh) (RHPNDX(rh)+1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Internal representation of the EHCI Queue Head (QH) */ + +struct lpc43_epinfo_s; +struct lpc43_qh_s +{ + /* Fields visible to hardware */ + + struct ehci_qh_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ + + struct lpc43_epinfo_s *epinfo; /* Endpoint used for the transfer */ + uint32_t fqp; /* First qTD in the list (physical address) */ + uint8_t pad[8]; /* Padding to assure 32-byte alignment */ +}; + +/* Internal representation of the EHCI Queue Element Transfer Descriptor (qTD) */ + +struct lpc43_qtd_s +{ + /* Fields visible to hardware */ + + struct ehci_qtd_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ +}; + +/* The following is used to manage lists of free QHs and qTDs */ + +struct lpc43_list_s +{ + struct lpc43_list_s *flink; /* Link to next entry in the list */ + /* Variable length entry data follows */ +}; + +/* List traversal callout functions */ + +typedef int (*foreach_qh_t)(struct lpc43_qh_s *qh, uint32_t **bp, void *arg); +typedef int (*foreach_qtd_t)(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg); + +/* This structure describes one endpoint. */ + +struct lpc43_epinfo_s +{ + uint8_t epno:7; /* Endpoint number */ + uint8_t dirin:1; /* 1:IN endpoint 0:OUT endpoint */ + uint8_t devaddr:7; /* Device address */ + uint8_t toggle:1; /* Next data toggle */ +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t interval; /* Polling interval */ +#endif + uint8_t status; /* Retained token status bits (for debug purposes) */ + volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */ + uint16_t maxpacket:11; /* Maximum packet size */ + uint16_t xfrtype:2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */ + uint16_t speed:2; /* See USB_*_SPEED definitions in ehci.h */ + int result; /* The result of the transfer */ + uint32_t xfrd; /* On completion, will hold the number of bytes transferred */ + sem_t iocsem; /* Semaphore used to wait for transfer completion */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* This structure retains the state of one root hub port */ + +struct lpc43_rhport_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct lpc43_rhport_s. + */ + + struct usbhost_driver_s drvr; + + /* Root hub port status */ + + volatile bool connected; /* Connected to device */ + volatile bool lowspeed; /* Low speed device attached */ + struct lpc43_epinfo_s ep0; /* EP0 endpoint info */ + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s hport; +}; + +/* This structure retains the overall state of the USB host controller */ + +struct lpc43_ehci_s +{ + volatile bool pscwait; /* TRUE: Thread is waiting for port status change event */ + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for port status change events */ + + struct lpc43_epinfo_s ep0; /* Endpoint 0 */ + struct lpc43_list_s *qhfree; /* List of free Queue Head (QH) structures */ + struct lpc43_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */ + struct work_s work; /* Supports interrupt bottom half */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* Root hub ports */ + + struct lpc43_rhport_s rhport[LPC43_EHCI_NRHPORT]; +}; + +#ifdef HAVE_USBHOST_TRACE +/* USB trace codes */ + +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + EHCI_TRACE1_SYSTEMERROR, /* EHCI ERROR: System error */ + EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: lpc43_qtd_foreach failed */ + EHCI_TRACE1_QHALLOC_FAILED, /* EHCI ERROR: Failed to allocate a QH */ + EHCI_TRACE1_BUFTOOBIG, /* EHCI ERROR: Buffer too big */ + EHCI_TRACE1_REQQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate request qTD */ + EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: lpc43_qtd_addbpl failed */ + EHCI_TRACE1_DATAQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate data buffer qTD */ + EHCI_TRACE1_DEVDISCONNECTED, /* EHCI ERROR: Device disconnected */ + EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: lpc43_qh_create failed */ + EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: lpc43_qtd_setupphase failed */ + + EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: lpc43_qtd_dataphase failed */ + EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: lpc43_qtd_statusphase failed */ + EHCI_TRACE1_TRANSFER_FAILED, /* EHCI ERROR: Transfer failed */ + EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: lpc43_qh_foreach failed: */ + EHCI_TRACE1_SYSERR_INTR, /* EHCI: Host System Error Interrup */ + EHCI_TRACE1_USBERR_INTR, /* EHCI: USB Error Interrupt (USBERRINT) Interrupt */ + EHCI_TRACE1_EPALLOC_FAILED, /* EHCI ERROR: Failed to allocate EP info structure */ + EHCI_TRACE1_BADXFRTYPE, /* EHCI ERROR: Support for transfer type not implemented */ + EHCI_TRACE1_HCHALTED_TIMEOUT, /* EHCI ERROR: Timed out waiting for HCHalted */ + EHCI_TRACE1_QHPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the QH pool */ + + EHCI_TRACE1_QTDPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the qTD pool */ + EHCI_TRACE1_PERFLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the periodic frame list */ + EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: lpc43_reset failed */ + EHCI_TRACE1_RUN_FAILED, /* EHCI ERROR: EHCI Failed to run */ + EHCI_TRACE1_IRQATTACH_FAILED, /* EHCI ERROR: Failed to attach IRQ */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE1_PORTSC_CSC, /* EHCI Connect Status Change */ + EHCI_VTRACE1_PORTSC_CONNALREADY, /* EHCI Already connected */ + EHCI_VTRACE1_PORTSC_DISCALREADY, /* EHCI Already disconnected */ + EHCI_VTRACE1_TOPHALF, /* EHCI Interrupt top half */ + EHCI_VTRACE1_AAINTR, /* EHCI Async Advance Interrupt */ + + EHCI_VTRACE1_CLASSENUM, /* EHCI Hub port CLASS enumeration */ + EHCI_VTRACE1_USBINTR, /* EHCI USB Interrupt (USBINT) Interrupt */ + EHCI_VTRACE1_ENUM_DISCONN, /* EHCI Enumeration not connected */ + EHCI_VTRACE1_INITIALIZING, /* EHCI Initializing EHCI Stack */ + EHCI_VTRACE1_HCCPARAMS, /* EHCI HCCPARAMS */ + EHCI_VTRACE1_INIITIALIZED, /* EHCI USB EHCI Initialized */ +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + EHCI_TRACE2_EPSTALLED, /* EHCI EP Stalled */ + EHCI_TRACE2_EPIOERROR, /* EHCI ERROR: EP TOKEN */ + EHCI_TRACE2_CLASSENUM_FAILED, /* EHCI usbhost_enumerate() failed */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE2_ASYNCXFR, /* EHCI Async transfer */ + EHCI_VTRACE2_INTRXFR, /* EHCI Interrupt Transfer */ + EHCI_VTRACE2_IOCCHECK, /* EHCI IOC */ + EHCI_VTRACE2_PORTSC, /* EHCI PORTSC */ + EHCI_VTRACE2_PORTSC_CONNECTED, /* EHCI RHPort connected */ + EHCI_VTRACE2_PORTSC_DISCONND, /* EHCI RHport disconnected */ + EHCI_VTRACE2_MONWAKEUP, /* EHCI RHPort connected wakeup */ + + EHCI_VTRACE2_EPALLOC, /* EHCI EPALLOC */ + EHCI_VTRACE2_CTRLINOUT, /* EHCI CTRLIN/OUT */ + EHCI_VTRACE2_HCIVERSION, /* EHCI HCIVERSION */ + EHCI_VTRACE2_HCSPARAMS, /* EHCI HCSPARAMS */ +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +/* USB trace data structure */ + +struct lpc43_ehci_trace_s +{ +#if 0 + uint16_t id; + bool fmt2; +#endif + FAR const char *string; +}; + +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +static uint16_t lpc43_read16(const uint8_t *addr); +static uint32_t lpc43_read32(const uint8_t *addr); +#if 0 /* Not used */ +static void lpc43_write16(uint16_t memval, uint8_t *addr); +static void lpc43_write32(uint32_t memval, uint8_t *addr); +#endif + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t lpc43_swap16(uint16_t value); +static uint32_t lpc43_swap32(uint32_t value); +#else +# define lpc43_swap16(value) (value) +# define lpc43_swap32(value) (value) +#endif + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static void lpc43_checkreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static uint32_t lpc43_getreg(volatile uint32_t *regaddr); +static void lpc43_putreg(uint32_t regval, volatile uint32_t *regaddr); +#else +static inline uint32_t lpc43_getreg(volatile uint32_t *regaddr); +static inline void lpc43_putreg(uint32_t regval, volatile uint32_t *regaddr); +#endif +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay); + +/* Semaphores ******************************************************************/ + +static void lpc43_takesem(sem_t *sem); +#define lpc43_givesem(s) sem_post(s); + +/* Allocators ******************************************************************/ + +static struct lpc43_qh_s *lpc43_qh_alloc(void); +static void lpc43_qh_free(struct lpc43_qh_s *qh); +static struct lpc43_qtd_s *lpc43_qtd_alloc(void); +static void lpc43_qtd_free(struct lpc43_qtd_s *qtd); + +/* List Management *************************************************************/ + +static int lpc43_qh_foreach(struct lpc43_qh_s *qh, uint32_t **bp, + foreach_qh_t handler, void *arg); +static int lpc43_qtd_foreach(struct lpc43_qh_s *qh, foreach_qtd_t handler, + void *arg); +static int lpc43_qtd_discard(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc43_qh_discard(struct lpc43_qh_s *qh); + + +/* Endpoint Transfer Handling **************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_qtd_print(struct lpc43_qtd_s *qtd); +static void lpc43_qh_print(struct lpc43_qh_s *qh); +static int lpc43_qtd_dump(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc43_qh_dump(struct lpc43_qh_s *qh, uint32_t **bp, void *arg); +#else +# define lpc43_qtd_print(qtd) +# define lpc43_qh_print(qh) +# define lpc43_qtd_dump(qtd, bp, arg) OK +# define lpc43_qh_dump(qh, bp, arg) OK +#endif + +static inline uint8_t lpc43_ehci_speed(uint8_t usbspeed); +static int lpc43_ioc_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo); +static int lpc43_ioc_wait(struct lpc43_epinfo_s *epinfo); +static void lpc43_qh_enqueue(struct lpc43_qh_s *qhead, + struct lpc43_qh_s *qh); +static struct lpc43_qh_s *lpc43_qh_create(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo); +static int lpc43_qtd_addbpl(struct lpc43_qtd_s *qtd, const void *buffer, + size_t buflen); +static struct lpc43_qtd_s *lpc43_qtd_setupphase(struct lpc43_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req); +static struct lpc43_qtd_s *lpc43_qtd_dataphase(struct lpc43_epinfo_s *epinfo, + void *buffer, int buflen, uint32_t tokenbits); +static struct lpc43_qtd_s *lpc43_qtd_statusphase(uint32_t tokenbits); +static ssize_t lpc43_async_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen); +#ifndef CONFIG_USBHOST_INT_DISABLE +static int lpc43_intr_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, uint8_t *buffer, size_t buflen); +#endif +static ssize_t lpc43_transfer_wait(struct lpc43_epinfo_s *epinfo); +#ifdef CONFIG_USBHOST_ASYNCH +static inline int lpc43_ioc_async_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, usbhost_asynch_t callback, + FAR void *arg); +static void lpc43_asynch_completion(struct lpc43_epinfo_s *epinfo); +#endif + +/* Interrupt Handling **********************************************************/ + +static int lpc43_qtd_ioccheck(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc43_qh_ioccheck(struct lpc43_qh_s *qh, uint32_t **bp, void *arg); +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc43_qtd_cancel(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg); +static int lpc43_qh_cancel(struct lpc43_qh_s *qh, uint32_t **bp, void *arg); +#endif +static inline void lpc43_ioc_bottomhalf(void); +static inline void lpc43_portsc_bottomhalf(void); +static inline void lpc43_syserr_bottomhalf(void); +static inline void lpc43_async_advance_bottomhalf(void); +static void lpc43_ehci_bottomhalf(FAR void *arg); +static int lpc43_ehci_interrupt(int irq, FAR void *context); + +/* USB Host Controller Operations **********************************************/ + +static int lpc43_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int lpc43_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int lpc43_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int lpc43_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); +static int lpc43_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int lpc43_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int lpc43_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int lpc43_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int lpc43_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int lpc43_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int lpc43_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer); +static int lpc43_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer); +static ssize_t lpc43_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc43_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback, + FAR void *arg); +#endif +static int lpc43_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int lpc43_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, bool connected); +#endif +static void lpc43_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static int lpc43_reset(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct lpc43_ehci_s g_ehci; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_ehciconn; + +/* Maps USB chapter 9 speed to EHCI speed */ + +static const uint8_t g_ehci_speed[4] = +{ + 0, EHCI_LOW_SPEED, EHCI_FULL_SPEED, EHCI_HIGH_SPEED +}; + +/* The head of the asynchronous queue */ + +static struct lpc43_qh_s g_asynchead __attribute__ ((aligned(32))); + +#ifndef CONFIG_USBHOST_INT_DISABLE +/* The head of the periodic queue */ + +static struct lpc43_qh_s g_intrhead __attribute__ ((aligned(32))); + +/* The frame list */ + +#ifdef CONFIG_LPC43_EHCI_PREALLOCATE +static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__ ((aligned(4096))); +#else +static uint32_t *g_framelist; +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +#ifdef CONFIG_LPC43_EHCI_PREALLOCATE +/* Pools of pre-allocated data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct lpc43_qh_s g_qhpool[CONFIG_LPC43_EHCI_NQHS] + __attribute__ ((aligned(32))); + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct lpc43_qtd_s g_qtdpool[CONFIG_LPC43_EHCI_NQTDS] + __attribute__ ((aligned(32))); + +#else +/* Pools of dynamically data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct lpc43_qh_s *g_qhpool; + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct lpc43_qtd_s *g_qtdpool; + +#endif + +#ifdef HAVE_USBHOST_TRACE +/* USB trace strings */ + +static const struct lpc43_ehci_trace_s g_trace1[TRACE1_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE1_SYSTEMERROR, TR_FMT1, "EHCI ERROR: System error: %06x\n"), + TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qtd_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_QHALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate a QH\n"), + TRENTRY(EHCI_TRACE1_BUFTOOBIG, TR_FMT1, "EHCI ERROR: Buffer too big. Remaining %d\n"), + TRENTRY(EHCI_TRACE1_REQQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate request qTD"), + TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qtd_addbpl failed: %d\n"), + TRENTRY(EHCI_TRACE1_DATAQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate data buffer qTD, 0"), + TRENTRY(EHCI_TRACE1_DEVDISCONNECTED, TR_FMT1, "EHCI ERROR: Device disconnected %d\n"), + TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qh_create failed\n"), + TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qtd_setupphase failed\n"), + + TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qtd_dataphase failed\n"), + TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qtd_statusphase failed\n"), + TRENTRY(EHCI_TRACE1_TRANSFER_FAILED, TR_FMT1, "EHCI ERROR: Transfer failed %d\n"), + TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc43_qh_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_SYSERR_INTR, TR_FMT1, "EHCI: Host System Error Interrupt\n"), + TRENTRY(EHCI_TRACE1_USBERR_INTR, TR_FMT1, "EHCI: USB Error Interrupt (USBERRINT) Interrupt: %06x\n"), + TRENTRY(EHCI_TRACE1_EPALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate EP info structure\n"), + TRENTRY(EHCI_TRACE1_BADXFRTYPE, TR_FMT1, "EHCI ERROR: Support for transfer type %d not implemented\n"), + TRENTRY(EHCI_TRACE1_HCHALTED_TIMEOUT, TR_FMT1, "EHCI ERROR: Timed out waiting for HCHalted. USBSTS: %06x\n"), + TRENTRY(EHCI_TRACE1_QHPOOLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the QH pool\n"), + + TRENTRY(EHCI_TRACE1_QTDPOOLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the qTD pool\n"), + TRENTRY(EHCI_TRACE1_PERFLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the periodic frame list\n"), + TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_FMT1, "EHCI ERROR: lpc43_reset failed: %d\n"), + TRENTRY(EHCI_TRACE1_RUN_FAILED, TR_FMT1, "EHCI ERROR: EHCI Failed to run: USBSTS=%06x\n"), + TRENTRY(EHCI_TRACE1_IRQATTACH_FAILED, TR_FMT1, "EHCI ERROR: Failed to attach IRQ%d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE1_PORTSC_CSC, TR_FMT1, "EHCI Connect Status Change: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_CONNALREADY, TR_FMT1, "EHCI Already connected: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_DISCALREADY, TR_FMT1, "EHCI Already disconnected: %06x\n"), + TRENTRY(EHCI_VTRACE1_TOPHALF, TR_FMT1, "EHCI Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_AAINTR, TR_FMT1, "EHCI Async Advance Interrupt\n"), + + TRENTRY(EHCI_VTRACE1_CLASSENUM, TR_FMT1, "EHCI Hub port %d: Enumerate the device\n"), + TRENTRY(EHCI_VTRACE1_USBINTR, TR_FMT1, "EHCI USB Interrupt (USBINT) Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_ENUM_DISCONN, TR_FMT1, "EHCI Enumeration not connected\n"), + TRENTRY(EHCI_VTRACE1_INITIALIZING, TR_FMT1, "EHCI Initializing EHCI Stack\n"), + TRENTRY(EHCI_VTRACE1_HCCPARAMS, TR_FMT1, "EHCI HCCPARAMS=%06x\n"), + TRENTRY(EHCI_VTRACE1_INIITIALIZED, TR_FMT1, "EHCI USB EHCI Initialized\n"), +#endif +}; + +static const struct lpc43_ehci_trace_s g_trace2[TRACE2_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE2_EPSTALLED, TR_FMT2, "EHCI EP%d Stalled: TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_EPIOERROR, TR_FMT2, "EHCI ERROR: EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_CLASSENUM_FAILED, TR_FMT2, "EHCI Hub port %d usbhost_enumerate() failed: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE2_ASYNCXFR, TR_FMT2, "EHCI Async transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_INTRXFR, TR_FMT2, "EHCI Intr Transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_IOCCHECK, TR_FMT2, "EHCI IOC EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC, TR_FMT2, "EHCI PORTSC%d: %04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_CONNECTED, TR_FMT2, "EHCI RHPort%d connected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_DISCONND, TR_FMT2, "EHCI RHport%d disconnected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_MONWAKEUP, TR_FMT2, "EHCI RHPort%d connected: %d\n"), + + TRENTRY(EHCI_VTRACE2_EPALLOC, TR_FMT2, "EHCI EPALLOC: EP%d TYPE=%d\n"), + TRENTRY(EHCI_VTRACE2_CTRLINOUT, TR_FMT2, "EHCI CTRLIN/OUT: RHPort%d req: %02x\n"), + TRENTRY(EHCI_VTRACE2_HCIVERSION, TR_FMT2, "EHCI HCIVERSION %x.%02x\n"), + TRENTRY(EHCI_VTRACE2_HCSPARAMS, TR_FMT2, "EHCI nports=%d, HCSPARAMS=%04x\n"), +#endif +}; +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_read16 + * + * Description: + * Read 16-bit little endian data + * + ****************************************************************************/ + +static uint16_t lpc43_read16(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint16_t)addr[0] << 8 | (uint16_t)addr[1]; +#else + return (uint16_t)addr[1] << 8 | (uint16_t)addr[0]; +#endif +} + +/**************************************************************************** + * Name: lpc43_read32 + * + * Description: + * Read 32-bit little endian data + * + ****************************************************************************/ + +static inline uint32_t lpc43_read32(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint32_t)lpc43_read16(&addr[0]) << 16 | + (uint32_t)lpc43_read16(&addr[2]); +#else + return (uint32_t)lpc43_read16(&addr[2]) << 16 | + (uint32_t)lpc43_read16(&addr[0]); +#endif +} + +/**************************************************************************** + * Name: lpc43_write16 + * + * Description: + * Write 16-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc43_write16(uint16_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + addr[0] = memval & 0xff; + addr[1] = memval >> 8; +#else + addr[0] = memval >> 8; + addr[1] = memval & 0xff; +#endif +} +#endif + +/**************************************************************************** + * Name: lpc43_write32 + * + * Description: + * Write 32-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void lpc43_write32(uint32_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + lpc43_write16(memval >> 16, &addr[0]); + lpc43_write16(memval & 0xffff, &addr[2]); +#else + lpc43_write16(memval & 0xffff, &addr[0]); + lpc43_write16(memval >> 16, &addr[2]); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc43_swap16 + * + * Description: + * Swap bytes on a 16-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t lpc43_swap16(uint16_t value) +{ + return ((value >> 8) & 0xff) | ((value & 0xff) << 8); +} +#endif + +/**************************************************************************** + * Name: lpc43_swap32 + * + * Description: + * Swap bytes on a 32-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint32_t lpc43_swap32(uint32_t value) +{ + return (uint32_t)lpc43_swap16((uint16_t)((value >> 16) & 0xffff)) | + (uint32_t)lpc43_swap16((uint16_t)(value & 0xffff)) << 16; +} +#endif + +/**************************************************************************** + * Name: lpc43_printreg + * + * Description: + * Print the contents of a LPC43 EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite) +{ + lldbg("%08x%s%08x\n", (uintptr_t)regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: lpc43_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a LPC43 + * EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_checkreg(volatile uint32_t *regaddr, uint32_t regval, bool iswrite) +{ + static uint32_t *prevaddr = NULL; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + lpc43_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = (uint32_t *)regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + lpc43_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: lpc43_getreg + * + * Description: + * Get the contents of an LPC43 register + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static uint32_t lpc43_getreg(volatile uint32_t *regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = *regaddr; + + /* Check if we need to print this value */ + + lpc43_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t lpc43_getreg(volatile uint32_t *regaddr) +{ + return *regaddr; +} +#endif + +/**************************************************************************** + * Name: lpc43_putreg + * + * Description: + * Set the contents of an LPC43 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + /* Check if we need to print this value */ + + lpc43_checkreg(regaddr, regval, true); + + /* Write the value */ + + *regaddr = regval; +} +#else +static inline void lpc43_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + *regaddr = regval; +} +#endif + +/**************************************************************************** + * Name: ehci_wait_usbsts + * + * Description: + * Wait for either (1) a field in the USBSTS register to take a specific + * value, (2) for a timeout to occur, or (3) a error to occur. Return + * a value to indicate which terminated the wait. + * + ****************************************************************************/ + +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay) +{ + uint32_t regval; + unsigned int timeout; + + timeout = 0; + do + { + /* Wait 5usec before trying again */ + + up_udelay(5); + timeout += 5; + + /* Read the USBSTS register and check for a system error */ + + regval = lpc43_getreg(&HCOR->usbsts); + if ((regval & EHCI_INT_SYSERROR) != 0) + { + usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval); + return -EIO; + } + + /* Mask out the bits of interest */ + + regval &= maskbits; + + /* Loop until the masked bits take the specified value or until a + * timeout occurs. + */ + } + while (regval != donebits && timeout < delay); + + /* We got here because either the waited for condition or a timeout + * occurred. Return a value to indicate which. + */ + + return (regval == donebits) ? OK : -ETIMEDOUT; +} + +/**************************************************************************** + * Semaphores + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void lpc43_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Allocators + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_qh_alloc + * + * Description: + * Allocate a Queue Head (QH) structure by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct lpc43_qh_s *lpc43_qh_alloc(void) +{ + struct lpc43_qh_s *qh; + + /* Remove the QH structure from the freelist */ + + qh = (struct lpc43_qh_s *)g_ehci.qhfree; + if (qh) + { + g_ehci.qhfree = ((struct lpc43_list_s *)qh)->flink; + memset(qh, 0, sizeof(struct lpc43_qh_s)); + } + + return qh; +} + +/**************************************************************************** + * Name: lpc43_qh_free + * + * Description: + * Free a Queue Head (QH) structure by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void lpc43_qh_free(struct lpc43_qh_s *qh) +{ + struct lpc43_list_s *entry = (struct lpc43_list_s *)qh; + + /* Put the QH structure back into the free list */ + + entry->flink = g_ehci.qhfree; + g_ehci.qhfree = entry; +} + +/**************************************************************************** + * Name: lpc43_qtd_alloc + * + * Description: + * Allocate a Queue Element Transfer Descriptor (qTD) by removing it from the + * free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct lpc43_qtd_s *lpc43_qtd_alloc(void) +{ + struct lpc43_qtd_s *qtd; + + /* Remove the qTD from the freelist */ + + qtd = (struct lpc43_qtd_s *)g_ehci.qtdfree; + if (qtd) + { + g_ehci.qtdfree = ((struct lpc43_list_s *)qtd)->flink; + memset(qtd, 0, sizeof(struct lpc43_qtd_s)); + } + + return qtd; +} + +/**************************************************************************** + * Name: lpc43_qtd_free + * + * Description: + * Free a Queue Element Transfer Descriptor (qTD) by returning it to the free + * list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void lpc43_qtd_free(struct lpc43_qtd_s *qtd) +{ + struct lpc43_list_s *entry = (struct lpc43_list_s *)qtd; + + /* Put the qTD back into the free list */ + + entry->flink = g_ehci.qtdfree; + g_ehci.qtdfree = entry; +} + +/**************************************************************************** + * List Management + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_qh_foreach + * + * Description: + * Give the first entry in a list of Queue Head (QH) structures, call the + * handler for each QH structure in the list (including the one at the head + * of the list). + * + ****************************************************************************/ + +static int lpc43_qh_foreach(struct lpc43_qh_s *qh, uint32_t **bp, foreach_qh_t handler, + void *arg) +{ + struct lpc43_qh_s *next; + uintptr_t physaddr; + int ret; + + DEBUGASSERT(qh && handler); + while (qh) + { + /* Is this the end of the list? Check the horizontal link pointer (HLP) + * terminate (T) bit. If T==1, then the HLP address is not valid. + */ + + physaddr = lpc43_swap32(qh->hw.hlp); + if ((physaddr & QH_HLP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + + /* Is the next QH the asynchronous list head which will always be at + * the end of the asynchronous queue? + */ + + else if (lpc43_virtramaddr(physaddr & QH_HLP_MASK) == (uintptr_t)&g_asynchead) + { + /* That will also terminate the loop */ + + next = NULL; + } + + /* Otherwise, there is a QH structure after this one that describes + * another transaction. + */ + + else + { + physaddr = lpc43_swap32(qh->hw.hlp) & QH_HLP_MASK; + next = (struct lpc43_qh_s *)lpc43_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next QH pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qh, bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qh = next; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_qtd_foreach + * + * Description: + * Give a Queue Head (QH) instance, call the handler for each qTD structure + * in the queue. + * + ****************************************************************************/ + +static int lpc43_qtd_foreach(struct lpc43_qh_s *qh, foreach_qtd_t handler, void *arg) +{ + struct lpc43_qtd_s *qtd; + struct lpc43_qtd_s *next; + uintptr_t physaddr; + uint32_t *bp; + int ret; + + DEBUGASSERT(qh && handler); + + /* Handle the special case where the queue is empty */ + + bp = &qh->fqp; /* Start of qTDs in original list */ + physaddr = lpc43_swap32(*bp); /* Physical address of first qTD in CPU order */ + + if ((physaddr & QTD_NQP_T) != 0) + { + return 0; + } + + /* Start with the first qTD in the list */ + + qtd = (struct lpc43_qtd_s *)lpc43_virtramaddr(physaddr); + next = NULL; + + /* And loop until we encounter the end of the qTD list */ + + while (qtd) + { + /* Is this the end of the list? Check the next qTD pointer (NQP) + * terminate (T) bit. If T==1, then the NQP address is not valid. + */ + + if ((lpc43_swap32(qtd->hw.nqp) & QTD_NQP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + else + { + physaddr = lpc43_swap32(qtd->hw.nqp) & QTD_NQP_NTEP_MASK; + next = (struct lpc43_qtd_s *)lpc43_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next qTD pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qtd, &bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qtd = next; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_qtd_discard + * + * Description: + * This is a lpc43_qtd_foreach callback. It simply unlinks the QTD, updates + * the back pointer, and frees the QTD structure. + * + ****************************************************************************/ + +static int lpc43_qtd_discard(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd && bp && *bp); + + /* Remove the qTD from the list by updating the forward pointer to skip + * around this qTD. We do not change that pointer because are repeatedly + * removing the aTD at the head of the QH list. + */ + + **bp = qtd->hw.nqp; + + /* Then free the qTD */ + + lpc43_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: lpc43_qh_discard + * + * Description: + * Free the Queue Head (QH) and all qTD's attached to the QH. + * + * Assumptions: + * The QH structure itself has already been unlinked from whatever list it + * may have been in. + * + ****************************************************************************/ + +static int lpc43_qh_discard(struct lpc43_qh_s *qh) +{ + int ret; + + DEBUGASSERT(qh); + + /* Free all of the qTD's attached to the QH */ + + ret = lpc43_qtd_foreach(qh, lpc43_qtd_discard, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then free the QH itself */ + + lpc43_qh_free(qh); + return ret; +} + +/**************************************************************************** + * Endpoint Transfer Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_qtd_print + * + * Description: + * Print the context of one qTD + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_qtd_print(struct lpc43_qtd_s *qtd) +{ + udbg(" QTD[%p]:\n", qtd); + udbg(" hw:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + qtd->hw.nqp, qtd->hw.alt, qtd->hw.token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + qtd->hw.bpl[0], qtd->hw.bpl[1], qtd->hw.bpl[2], + qtd->hw.bpl[3], qtd->hw.bpl[4]); +} +#endif + +/**************************************************************************** + * Name: lpc43_qh_print + * + * Description: + * Print the context of one QH + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static void lpc43_qh_print(struct lpc43_qh_s *qh) +{ + struct lpc43_epinfo_s *epinfo; + struct ehci_overlay_s *overlay; + + udbg("QH[%p]:\n", qh); + udbg(" hw:\n"); + udbg(" hlp: %08x epchar: %08x epcaps: %08x cqp: %08x\n", + qh->hw.hlp, qh->hw.epchar, qh->hw.epcaps, qh->hw.cqp); + + overlay = &qh->hw.overlay; + udbg(" overlay:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + overlay->nqp, overlay->alt, overlay->token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + overlay->bpl[0], overlay->bpl[1], overlay->bpl[2], + overlay->bpl[3], overlay->bpl[4]); + + udbg(" fqp:\n", qh->fqp); + + epinfo = qh->epinfo; + udbg(" epinfo[%p]:\n", epinfo); + if (epinfo) + { + udbg(" EP%d DIR=%s FA=%08x TYPE=%d MaxPacket=%d\n", + epinfo->epno, epinfo->dirin ? "IN" : "OUT", epinfo->devaddr, + epinfo->xfrtype, epinfo->maxpacket); + udbg(" Toggle=%d iocwait=%d speed=%d result=%d\n", + epinfo->toggle, epinfo->iocwait, epinfo->speed, epinfo->result); + } +} +#endif + +/**************************************************************************** + * Name: lpc43_qtd_dump + * + * Description: + * This is a lpc43_qtd_foreach callout function. It dumps the context of one + * qTD + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static int lpc43_qtd_dump(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg) +{ + lpc43_qtd_print(qtd); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc43_qh_dump + * + * Description: + * This is a lpc43_qh_foreach callout function. It dumps a QH structure and + * all of the qTD structures linked to the QH. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_EHCI_REGDEBUG +static int lpc43_qh_dump(struct lpc43_qh_s *qh, uint32_t **bp, void *arg) +{ + lpc43_qh_print(qh); + return lpc43_qtd_foreach(qh, lpc43_qtd_dump, NULL); +} +#endif + +/**************************************************************************** + * Name: lpc43_ehci_speed + * + * Description: + * Map a speed enumeration value per Chapter 9 of the USB specification to the + * speed enumeration required in the EHCI queue head. + * + ****************************************************************************/ + +static inline uint8_t lpc43_ehci_speed(uint8_t usbspeed) +{ + DEBUGASSERT(usbspeed >= USB_SPEED_LOW && usbspeed <= USB_SPEED_HIGH); + return g_ehci_speed[usbspeed]; +} + +/**************************************************************************** + * Name: lpc43_ioc_setup + * + * Description: + * Set the request for the IOC event well BEFORE enabling the transfer (as + * soon as we are absolutely committed to the to avoid transfer). We do this + * to minimize race conditions. This logic would have to be expanded if we + * want to have more than one packet in flight at a time! + * + * Assumption: The caller holds tex EHCI exclsem + * + ****************************************************************************/ + +static int lpc43_ioc_setup(struct lpc43_rhport_s *rhport, struct lpc43_epinfo_s *epinfo) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait); +#ifdef CONFIG_USBHOST_ASYNCH + DEBUGASSERT(epinfo->callback == NULL); +#endif + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then set iocwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + epinfo->iocwait = true; /* We want to be awakened by IOC interrupt */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; /* No asynchronous callback */ + epinfo->arg = NULL; +#endif + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc43_ioc_wait + * + * Description: + * Wait for the IOC event. + * + * Assumption: The caller does *NOT* hold the EHCI exclsem. That would cause + * a deadlock when the bottom-half, worker thread needs to take the semaphore. + * + ****************************************************************************/ + +static int lpc43_ioc_wait(struct lpc43_epinfo_s *epinfo) +{ + /* Wait for the IOC event. Loop to handle any false alarm semaphore counts. */ + + while (epinfo->iocwait) + { + lpc43_takesem(&epinfo->iocsem); + } + + return epinfo->result; +} + +/**************************************************************************** + * Name: lpc43_qh_enqueue + * + * Description: + * Add a new, ready-to-go QH w/attached qTDs to the asynchonous queue. + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static void lpc43_qh_enqueue(struct lpc43_qh_s *qhead, struct lpc43_qh_s *qh) +{ + uintptr_t physaddr; + + /* Set the internal fqp field. When we transverse the QH list later, + * we need to know the correct place to start because the overlay may no + * longer point to the first qTD entry. + */ + + qh->fqp = qh->hw.overlay.nqp; + (void)lpc43_qh_dump(qh, NULL, NULL); + + /* Add the new QH to the head of the asynchronous queue list. + * + * First, attach the old head as the new QH HLP and flush the new QH and its + * attached qTDs to RAM. + */ + + qh->hw.hlp = qhead->hw.hlp; + + /* Then set the new QH as the first QH in the asychronous queue and flush the + * modified head to RAM. + */ + + physaddr = (uintptr_t)lpc43_physramaddr((uintptr_t)qh); + qhead->hw.hlp = lpc43_swap32(physaddr | QH_HLP_TYP_QH); +} + +/**************************************************************************** + * Name: lpc43_qh_create + * + * Description: + * Create a new Queue Head (QH) + * + ****************************************************************************/ + +static struct lpc43_qh_s *lpc43_qh_create(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo) +{ + struct lpc43_qh_s *qh; + uint32_t rhpndx; + uint32_t regval; + uint8_t hubaddr; + uint8_t hubport; + + /* Allocate a new queue head structure */ + + qh = lpc43_qh_alloc(); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0); + return NULL; + } + + /* Save the endpoint information with the QH itself */ + + qh->epinfo = epinfo; + + /* Write QH endpoint characteristics: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * DEVADDR Device address Endpoint structure + * I Inactivate on Next Transaction 0 + * ENDPT Endpoint number Endpoint structure + * EPS Endpoint speed Endpoint structure + * DTC Data toggle control 1 + * MAXPKT Max packet size Endpoint structure + * C Control endpoint Calculated + * RL NAK count reloaded 8 + */ + + regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) | + ((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) | + ((uint32_t)lpc43_ehci_speed(epinfo->speed) << QH_EPCHAR_EPS_SHIFT) | + QH_EPCHAR_DTC | + ((uint32_t)epinfo->maxpacket << QH_EPCHAR_MAXPKT_SHIFT) | + ((uint32_t)8 << QH_EPCHAR_RL_SHIFT); + + /* Paragraph 3.6.3: "Control Endpoint Flag (C). If the QH.EPS field + * indicates the endpoint is not a high-speed device, and the endpoint + * is an control endpoint, then software must set this bit to a one. + * Otherwise it should always set this bit to a zero." + */ + + if (epinfo->speed != USB_SPEED_HIGH && + epinfo->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + regval |= QH_EPCHAR_C; + } + + /* Save the endpoint characteristics word with the correct byte order */ + + qh->hw.epchar = lpc43_swap32(regval); + + /* Write QH endpoint capabilities + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * SSMASK Interrupt Schedule Mask Depends on epinfo->xfrtype + * SCMASK Split Completion Mask 0 + * HUBADDR Hub Address Always 0 for now + * PORT Port number RH port index + 1 + * MULT High band width multiplier 1 + */ + + rhpndx = RHPNDX(rhport); + +#ifdef CONFIG_USBHOST_HUB + /* REVISIT: Future HUB support will require the HUB port number + * and HUB device address to be included here: + * + * - The HUB device address is the USB device address of the USB 2.0 Hub + * below which a full- or low-speed device is attached. + * - The HUB port number is the port number on the above USB 2.0 Hub + * + * These fields are used in the split-transaction protocol. The kludge + * below should work for hubs connected directly to a root hub port, + * but would not work for devices connected to downstream hubs. + */ + +#warning Missing logic + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#else + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#endif + + regval = ((uint32_t)hubaddr << QH_EPCAPS_HUBADDR_SHIFT) | + ((uint32_t)hubport << QH_EPCAPS_PORT_SHIFT) | + ((uint32_t)1 << QH_EPCAPS_MULT_SHIFT); + +#ifndef CONFIG_USBHOST_INT_DISABLE + if (epinfo->xfrtype == USB_EP_ATTR_XFER_INT) + { + /* Here, the S-Mask field in the queue head is set to 1, indicating + * that the transaction for the endpoint should be executed on the bus + * during micro-frame 0 of the frame. + * + * REVISIT: The polling interval should be controlled by the which + * entry is the framelist holds the QH pointer for a given micro-frame + * and the QH pointer should be replicated for different polling rates. + * This implementation currently just sets all frame_list entry to + * all the same interrupt queue. That should work but will not give + * any control over polling rates. + */ +#warning REVISIT + + regval |= ((uint32_t)1 << QH_EPCAPS_SSMASK_SHIFT); + } +#endif + + qh->hw.epcaps = lpc43_swap32(regval); + + /* Mark this as the end of this list. This will be overwritten if/when the + * next qTD is added to the queue. + */ + + qh->hw.hlp = lpc43_swap32(QH_HLP_T); + qh->hw.overlay.nqp = lpc43_swap32(QH_NQP_T); + qh->hw.overlay.alt = lpc43_swap32(QH_AQP_T); + return qh; +} + +/**************************************************************************** + * Name: lpc43_qtd_addbpl + * + * Description: + * Add a buffer pointer list to a qTD. + * + ****************************************************************************/ + +static int lpc43_qtd_addbpl(struct lpc43_qtd_s *qtd, const void *buffer, size_t buflen) +{ + uint32_t physaddr; + uint32_t nbytes; + uint32_t next; + int ndx; + + /* Loop, adding the aligned physical addresses of the buffer to the buffer page + * list. Only the first entry need not be aligned (because only the first + * entry has the offset field). The subsequent entries must begin on 4KB + * address boundaries. + */ + + physaddr = (uint32_t)lpc43_physramaddr((uintptr_t)buffer); + + for (ndx = 0; ndx < 5; ndx++) + { + /* Write the physical address of the buffer into the qTD buffer pointer + * list. + */ + + qtd->hw.bpl[ndx] = lpc43_swap32(physaddr); + + /* Get the next buffer pointer (in the case where we will have to transfer + * more then one chunk). This buffer must be aligned to a 4KB address + * boundary. + */ + + next = (physaddr + 4096) & ~4095; + + /* How many bytes were included in the last buffer? Was it the whole + * thing? + */ + + nbytes = next - physaddr; + if (nbytes >= buflen) + { + /* Yes... it was the whole thing. Break out of the loop early. */ + + break; + } + + /* Adjust the buffer length and physical address for the next time + * through the loop. + */ + + buflen -= nbytes; + physaddr = next; + } + + /* Handle the case of a huge buffer > 4*4KB = 16KB */ + + if (ndx >= 5) + { + usbhost_trace1(EHCI_TRACE1_BUFTOOBIG, buflen); + return -EFBIG; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_qtd_setupphase + * + * Description: + * Create a SETUP phase request qTD. + * + ****************************************************************************/ + +static struct lpc43_qtd_s *lpc43_qtd_setupphase(struct lpc43_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req) +{ + struct lpc43_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc43_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc43_swap32(QTD_NQP_T); + qtd->hw.alt = lpc43_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code QTD_TOKEN_PID_SETUP + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete 0 + * NBYTES Total Bytes to Transfer USB_SIZEOF_CTRLREQ + * TOGGLE Data Toggle 0 + */ + + regval = QTD_TOKEN_ACTIVE | QTD_TOKEN_PID_SETUP | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)USB_SIZEOF_CTRLREQ << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = lpc43_swap32(regval); + + /* Add the buffer data */ + + ret = lpc43_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + lpc43_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += USB_SIZEOF_CTRLREQ; + + return qtd; +} + +/**************************************************************************** + * Name: lpc43_qtd_dataphase + * + * Description: + * Create a data transfer or SET data phase qTD. + * + ****************************************************************************/ + +static struct lpc43_qtd_s *lpc43_qtd_dataphase(struct lpc43_epinfo_s *epinfo, + void *buffer, int buflen, + uint32_t tokenbits) +{ + struct lpc43_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc43_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc43_swap32(QTD_NQP_T); + qtd->hw.alt = lpc43_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete Contained in tokenbits + * NBYTES Total Bytes to Transfer buflen + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)buflen << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = lpc43_swap32(regval); + + /* Add the buffer information to the bufffer pointer list */ + + ret = lpc43_qtd_addbpl(qtd, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + lpc43_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += buflen; + + return qtd; +} + +/**************************************************************************** + * Name: lpc43_qtd_statusphase + * + * Description: + * Create a STATUS phase request qTD. + * + ****************************************************************************/ + +static struct lpc43_qtd_s *lpc43_qtd_statusphase(uint32_t tokenbits) +{ + struct lpc43_qtd_s *qtd; + uint32_t regval; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = lpc43_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = lpc43_swap32(QTD_NQP_T); + qtd->hw.alt = lpc43_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete QTD_TOKEN_IOC + * NBYTES Total Bytes to Transfer 0 + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | QTD_TOKEN_IOC | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT); + + qtd->hw.token = lpc43_swap32(regval); + return qtd; +} + +/**************************************************************************** + * Name: lpc43_async_setup + * + * Description: + * Process a IN or OUT request on any asynchronous endpoint (bulk or control). + * This function will enqueue the request and wait for it to complete. Bulk + * data transfers differ in that req == NULL and there are not SETUP or STATUS + * phases. + * + * This is a blocking function; it will not return until the control transfer + * has completed. + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +static int lpc43_async_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen) +{ + struct lpc43_qh_s *qh; + struct lpc43_qtd_s *qtd; + uintptr_t physaddr; + uint32_t *flink; + uint32_t *alt; + uint32_t toggle; + bool dirin = false; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_ASYNCXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d, req=%p\n", + RHPORT(rhport), epinfo->epno, buffer, buflen, req); +#endif + + DEBUGASSERT(rhport && epinfo); + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + DEBUGASSERT(req || (buffer && buflen > 0)); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = lpc43_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the QH link and get the next data toggle (not used for SETUP + * transfers) + */ + + flink = &qh->hw.overlay.nqp; + toggle = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + ret = -EIO; + + /* Is the an EP0 SETUP request? If so, req will be non-NULL and we will + * queue two or three qTDs: + * + * 1) One for the SETUP phase, + * 2) One for the DATA phase (if there is data), and + * 3) One for the STATUS phase. + * + * If this is not an EP0 SETUP request, then only a data transfer will be + * enqueued. + */ + + if (req != NULL) + { + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the SETUP + * phase of the request sequence. + */ + + qtd = lpc43_qtd_setupphase(epinfo, req); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to the QH head. */ + + physaddr = lpc43_physramaddr((uintptr_t)qtd); + *flink = lpc43_swap32(physaddr); + + /* Get the new forward link pointer and data toggle */ + + flink = &qtd->hw.nqp; + toggle = QTD_TOKEN_TOGGLE; + } + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + alt = NULL; + if (buffer != NULL && buflen > 0) + { + uint32_t tokenbits; + + /* Extra TOKEN bits include the data toggle, the data PID, and if + * there is no request, an indication to interrupt at the end of this + * transfer. + */ + + tokenbits = toggle; + + /* Get the data token direction. + * + * If this is a SETUP request, use the direction contained in the + * request. The IOC bit is not set. + */ + + if (req) + { + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_IN; + dirin = true; + } + else + { + tokenbits |= QTD_TOKEN_PID_OUT; + dirin = false; + } + } + + /* Otherwise, the endpoint is uni-directional. Get the direction from + * the epinfo structure. Since this is not an EP0 SETUP request, + * nothing follows the data and we want the IOC interrupt when the + * data transfer completes. + */ + + else if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + dirin = true; + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + dirin = false; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = lpc43_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either QH head of the SETUP qTD. */ + + physaddr = lpc43_physramaddr((uintptr_t)qtd); + *flink = lpc43_swap32(physaddr); + + /* Set the forward link pointer to this new qTD */ + + flink = &qtd->hw.nqp; + + /* If this was an IN transfer, then setup a pointer alternate link. + * The EHCI hardware will use this link if a short packet is received. + */ + + if (dirin) + { + alt = &qtd->hw.alt; + } + } + + /* If this is an EP0 SETUP request, then enqueue one more qTD for the + * STATUS phase transfer. + */ + + if (req != NULL) + { + /* Extra TOKEN bits include the data toggle and the correct data PID. */ + + uint32_t tokenbits = toggle; + + /* The status phase direction is the opposite of the data phase. If + * this is an IN request, then we received the buffer and we will send + * the zero length packet handshake. + */ + + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_OUT; + } + + /* Otherwise, this in an OUT request. We send the buffer and we expect + * to receive the NULL packet handshake. + */ + + else + { + tokenbits |= QTD_TOKEN_PID_IN; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the status */ + + qtd = lpc43_qtd_statusphase(tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either the SETUP or data qTD. */ + + physaddr = lpc43_physramaddr((uintptr_t)qtd); + *flink = lpc43_swap32(physaddr); + + /* In an IN data qTD was also enqueued, then linke the data qTD's + * alternate pointer to this STATUS phase qTD in order to handle short + * transfers. + */ + + if (alt) + { + *alt = lpc43_swap32(physaddr); + } + } + + /* Add the new QH to the head of the asynchronous queue list */ + + lpc43_qh_enqueue(&g_asynchead, qh); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + lpc43_qh_discard(qh); + return ret; +} + +/**************************************************************************** + * Name: lpc43_intr_setup + * + * Description: + * Process a IN or OUT request on any interrupt endpoint by inserting a qTD + * into the periodic frame list. + * + * Paragraph 4.10.7 "Adding Interrupt Queue Heads to the Periodic Schedule" + * "The link path(s) from the periodic frame list to a queue head establishes + * in which frames a transaction can be executed for the queue head. Queue + * heads are linked into the periodic schedule so they are polled at + * the appropriate rate. System software sets a bit in a queue head's + * S-Mask to indicate which micro-frame with-in a 1 millisecond period a + * transaction should be executed for the queue head. Software must ensure + * that all queue heads in the periodic schedule have S-Mask set to a non- + * zero value. An S-mask with a zero value in the context of the periodic + * schedule yields undefined results. + * + * "If the desired poll rate is greater than one frame, system software can + * use a combination of queue head linking and S-Mask values to spread + * interrupts of equal poll rates through the schedule so that the + * periodic bandwidth is allocated and managed in the most efficient + * manner possible." + * + * Paragraph 4.6 "Periodic Schedule" + * + * "The periodic schedule is used to manage all isochronous and interrupt + * transfer streams. The base of the periodic schedule is the periodic + * frame list. Software links schedule data structures to the periodic + * frame list to produce a graph of scheduled data structures. The graph + * represents an appropriate sequence of transactions on the USB. ... + * isochronous transfers (using iTDs and siTDs) with a period of one are + * linked directly to the periodic frame list. Interrupt transfers (are + * managed with queue heads) and isochronous streams with periods other + * than one are linked following the period-one iTD/siTDs. Interrupt + * queue heads are linked into the frame list ordered by poll rate. + * Longer poll rates are linked first (e.g. closest to the periodic + * frame list), followed by shorter poll rates, with queue heads with a + * poll rate of one, on the very end." + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +#ifndef CONFIG_USBHOST_INT_DISABLE +static int lpc43_intr_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, + uint8_t *buffer, size_t buflen) +{ + struct lpc43_qh_s *qh; + struct lpc43_qtd_s *qtd; + uintptr_t physaddr; + uint32_t tokenbits; + uint32_t regval; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_INTRXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d\n", + RHPORT(rhport), epinfo->epno, buffer, buflen); +#endif + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = lpc43_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Extra TOKEN bits include the data toggle, the data PID, and an + * indication to interrupt at the end of this transfer. + */ + + tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + + /* Get the data token direction. */ + + if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = lpc43_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + ret = -ENOMEM; + goto errout_with_qh; + } + + /* Link the new qTD to the QH. */ + + physaddr = lpc43_physramaddr((uintptr_t)qtd); + qh->hw.overlay.nqp = lpc43_swap32(physaddr); + + /* Disable the periodic schedule */ + + regval = lpc43_getreg(&HCOR->usbcmd); + regval &= ~EHCI_USBCMD_PSEN; + lpc43_putreg(regval, &HCOR->usbcmd); + + /* Add the new QH to the head of the interrupt transfer list */ + + lpc43_qh_enqueue(&g_intrhead, qh); + + /* Re-enable the periodic schedule */ + + regval |= EHCI_USBCMD_PSEN; + lpc43_putreg(regval, &HCOR->usbcmd); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + lpc43_qh_discard(qh); + return ret; +} +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +/**************************************************************************** + * Name: lpc43_transfer_wait + * + * Description: + * Wait for an IN or OUT transfer to complete. + * + * Assumption: The caller holds the EHCI exclsem. The caller must be aware + * that the EHCI exclsem will released while waiting for the transfer to + * complete, but will be re-acquired when before returning. The state of + * EHCI resources could be very different upon return. + * + * Returned value: + * On success, this function returns the number of bytes actually transferred. + * For control transfers, this size includes the size of the control request + * plus the size of the data (which could be short); For bulk transfers, this + * will be the number of data bytes transfers (which could be short). + * + ****************************************************************************/ + +static ssize_t lpc43_transfer_wait(struct lpc43_epinfo_s *epinfo) +{ + int ret; + + /* Release the EHCI semaphore while we wait. Other threads need the + * opportunity to access the EHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not EHCI common) until + * the transfer is complete. But we can't use the common EHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ +#warning REVISIT + lpc43_givesem(&g_ehci.exclsem); + + /* Wait for the IOC completion event */ + + ret = lpc43_ioc_wait(epinfo); + + /* Re-acquire the EHCI semaphore. The caller expects to be holding + * this upon return. + */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Did lpc43_ioc_wait() report an error? */ + + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_TRANSFER_FAILED, -ret); + epinfo->iocwait = false; + return (ssize_t)ret; + } + + /* Transfer completed successfully. Return the number of bytes + * transferred. + */ + + return epinfo->xfrd; +} + +/**************************************************************************** + * Name: lpc43_ioc_async_setup + * + * Description: + * Setup to receive an asynchronous notification when a transfer completes. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer will be performed. + * callback - The function to be called when the completes + * arg - An arbitrary argument that will be provided with the callback. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static inline int lpc43_ioc_async_setup(struct lpc43_rhport_s *rhport, + struct lpc43_epinfo_s *epinfo, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait && + callback != NULL && epinfo->callback == NULL); + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then save callback information to used when either (1) the + * device is disconnected, or (2) the transfer completes. + */ + + epinfo->iocwait = false; /* No synchronous wakeup */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ + epinfo->callback = callback; /* Asynchronous callback */ + epinfo->arg = arg; /* Argument that accompanies the callback */ + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: lpc43_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer was performed. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void lpc43_asynch_completion(struct lpc43_epinfo_s *epinfo) +{ + usbhost_asynch_t callback; + ssize_t nbytes; + void *arg; + int result; + + DEBUGASSERT(epinfo != NULL && epinfo->iocwait == false && + epinfo->callback != NULL); + + /* Extract and reset the callback info */ + + callback = epinfo->callback; + arg = epinfo->arg; + result = epinfo->result; + nbytes = epinfo->xfrd; + + epinfo->callback = NULL; + epinfo->arg = NULL; + epinfo->result = OK; + epinfo->iocwait = false; + + /* Then perform the callback. Provide the number of bytes successfully + * transferred or the negated errno value in the event of a failure. + */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * EHCI Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_qtd_ioccheck + * + * Description: + * This function is a lpc43_qtd_foreach() callback function. It services one + * qTD in the asynchronous queue. It removes all of the qTD structures that + * are no longer active. + * + ****************************************************************************/ + +static int lpc43_qtd_ioccheck(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg) +{ + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)arg; + DEBUGASSERT(qtd && epinfo); + + lpc43_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + */ + + **bp = qtd->hw.nqp; + + /* Subtract the number of bytes left untransferred. The epinfo->xfrd + * field is initialized to the total number of bytes to be transferred + * (all qTDs in the list). We subtract out the number of untransferred + * bytes on each transfer and the final result will be the number of bytes + * actually transferred. + */ + + epinfo->xfrd -= (lpc43_swap32(qtd->hw.token) & QTD_TOKEN_NBYTES_MASK) >> + QTD_TOKEN_NBYTES_SHIFT; + + /* Release this QH by returning it to the free list */ + + lpc43_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: lpc43_qh_ioccheck + * + * Description: + * This function is a lpc43_qh_foreach() callback function. It services one + * QH in the asynchronous queue. It check all attached qTD structures and + * remove all of the structures that are no longer active. if all of the + * qTD structures are removed, then QH itself will also be removed. + * + ****************************************************************************/ + +static int lpc43_qh_ioccheck(struct lpc43_qh_s *qh, uint32_t **bp, void *arg) +{ + struct lpc43_epinfo_s *epinfo; + uint32_t token; + int ret; + + DEBUGASSERT(qh && bp); + + lpc43_qh_print(qh); + + /* Get the endpoint info pointer from the extended QH data. Only the + * g_asynchead QH can have a NULL epinfo field. + */ + + epinfo = qh->epinfo; + DEBUGASSERT(epinfo); + + /* Paragraph 3.6.3: "The nine DWords in [the Transfer Overlay] area represent + * a transaction working space for the host controller. The general + * operational model is that the host controller can detect whether the + * overlay area contains a description of an active transfer. If it does + * not contain an active transfer, then it follows the Queue Head Horizontal + * Link Pointer to the next queue head. The host controller will never follow + * the Next Transfer Queue Element or Alternate Queue Element pointers unless + * it is actively attempting to advance the queue ..." + */ + + /* Is the qTD still active? */ + + token = lpc43_swap32(qh->hw.overlay.token); + usbhost_vtrace2(EHCI_VTRACE2_IOCCHECK, epinfo->epno, token); + + if ((token & QH_TOKEN_ACTIVE) != 0) + { + /* Yes... we cannot process the QH while it is still active. Return + * zero to visit the next QH in the list. + */ + *bp = &qh->hw.hlp; + return OK; + } + + /* Remove all active, attached qTD structures from the inactive QH */ + + ret = lpc43_qtd_foreach(qh, lpc43_qtd_ioccheck, (void *)qh->epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* If there is no longer anything attached to the QH, then remove it from + * the asynchronous queue. + */ + + if ((lpc43_swap32(qh->fqp) & QTD_NQP_T) != 0) + { + /* Set the forward link of the previous QH to point to the next + * QH in the list. + */ + + **bp = qh->hw.hlp; + + /* Check for errors, update the data toggle */ + + if ((token & QH_TOKEN_ERRORS) == 0) + { + /* No errors.. Save the last data toggle value */ + + epinfo->toggle = (token >> QTD_TOKEN_TOGGLE_SHIFT) & 1; + + /* Report success */ + + epinfo->status = 0; + epinfo->result = OK; + } + else + { + /* An error occurred */ + + epinfo->status = (token & QH_TOKEN_STATUS_MASK) >> QH_TOKEN_STATUS_SHIFT; + + /* The HALT condition is set on a variety of conditions: babble, error + * counter countdown to zero, or a STALL. If we can rule out babble + * (babble bit not set) and if the error counter is non-zero, then we can + * assume a STALL. In this case, we return -PERM to inform the class + * driver of the stall condition. + */ + + if ((token & (QH_TOKEN_BABBLE | QH_TOKEN_HALTED)) == QH_TOKEN_HALTED && + (token & QH_TOKEN_CERR_MASK) != 0) + { + /* It is a stall, Note the that the data toggle is reset + * after the stall. + */ + + usbhost_trace2(EHCI_TRACE2_EPSTALLED, epinfo->epno, token); + epinfo->result = -EPERM; + epinfo->toggle = 0; + } + else + { + /* Otherwise, it is some kind of data transfer error */ + + usbhost_trace2(EHCI_TRACE2_EPIOERROR, epinfo->epno, token); + epinfo->result = -EIO; + } + } + + /* Is there a thread waiting for this transfer to complete? */ + + if (epinfo->iocwait) + { + /* Yes... wake it up */ + + lpc43_givesem(&epinfo->iocsem); + epinfo->iocwait = 0; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. Is there a pending asynchronous transfer? */ + + else if (epinfo->callback != NULL) + { + /* Yes.. perform the callback */ + + lpc43_asynch_completion(epinfo); + } +#endif + + /* Then release this QH by returning it to the free list */ + + lpc43_qh_free(qh); + } + else + { + /* Otherwise, the horizontal link pointer of this QH will become the next back pointer. + */ + + *bp = &qh->hw.hlp; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_qtd_cancel + * + * Description: + * This function is a lpc43_qtd_foreach() callback function. It removes each + * qTD attached to a QH. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc43_qtd_cancel(struct lpc43_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd != NULL && bp != NULL); + + lpc43_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qtd->hw.nqp; + + /* Release this QH by returning it to the free list */ + + lpc43_qtd_free(qtd); + return OK; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: lpc43_qh_cancel + * + * Description: + * This function is a lpc43_qh_foreach() callback function. It cancels one + * QH in the asynchronous queue. It will remove all attached qTD structures + * and remove all of the structures that are no longer active. Then QH + * itself will also be removed. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc43_qh_cancel(struct lpc43_qh_s *qh, uint32_t **bp, void *arg) +{ + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)arg; + uint32_t regval; + int ret; + + DEBUGASSERT(qh != NULL && bp != NULL && epinfo != NULL); + + lpc43_qh_print(qh); + + /* Check if this is the QH that we are looking for */ + + if (qh->epinfo == epinfo) + { + /* No... keep looking */ + + return OK; + } + + /* Disable both the asynchronous and period schedules */ + + regval = lpc43_getreg(&HCOR->usbcmd); + lpc43_putreg(regval & ~(EHCI_USBCMD_ASEN | EHCI_USBCMD_PSEN), + &HCOR->usbcmd); + + /* Remove the QH from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qh->hw.hlp; + + /* Re-enable the schedules (if they were enabled before. */ + + lpc43_putreg(regval, &HCOR->usbcmd); + + /* Remove all active, attached qTD structures from the removed QH */ + + ret = lpc43_qtd_foreach(qh, lpc43_qtd_cancel, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then release this QH by returning it to the free list. Return 1 + * to stop the traverse without an error. + */ + + lpc43_qh_free(qh); + return 1; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: lpc43_ioc_bottomhalf + * + * Description: + * EHCI USB Interrupt (USBINT) "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor that + * had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is detected + * (actual number of bytes received was less than the expected number of + * bytes)." + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static inline void lpc43_ioc_bottomhalf(void) +{ + struct lpc43_qh_s *qh; + uint32_t *bp; + int ret; + + /* Set the back pointer to the forward qTD pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct lpc43_qh_s *)lpc43_virtramaddr(lpc43_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in the + * asynchronous queue head will point back to the the queue head. + */ + + if (qh && qh != &g_asynchead) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue + */ + + ret = lpc43_qh_foreach(qh, &bp, lpc43_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Check the Interrupt Queue */ + + /* Set the back pointer to the forward qTD pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct lpc43_qh_s *)lpc43_virtramaddr(lpc43_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue. + */ + + ret = lpc43_qh_foreach(qh, &bp, lpc43_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } +#endif +} + +/**************************************************************************** + * Name: lpc43_portsc_bottomhalf + * + * Description: + * EHCI Port Change Detect "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to a one when any port for which the Port + * Owner bit is set to zero ... has a change bit transition from a zero to a + * one or a Force Port Resume bit transition from a zero to a one as a result + * of a J-K transition detected on a suspended port. This bit will also be set + * as a result of the Connect Status Change being set to a one after system + * software has relinquished ownership of a connected port by writing a one + * to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition of the + * EHCI HC device, this bit is loaded with the OR of all of the PORTSC change + * bits (including: Force port resume, over-current change, enable/disable + * change and connect status change)." + * + ****************************************************************************/ + +static inline void lpc43_portsc_bottomhalf(void) +{ + struct lpc43_rhport_s *rhport; + struct usbhost_hubport_s *hport; + uint32_t portsc; + int rhpndx; + + /* Handle root hub status change on each root port */ + + for (rhpndx = 0; rhpndx < LPC43_EHCI_NRHPORT; rhpndx++) + { + rhport = &g_ehci.rhport[rhpndx]; + portsc = lpc43_getreg(&HCOR->portsc[rhpndx]); + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc); + + /* Handle port connection status change (CSC) events */ + + if ((portsc & EHCI_PORTSC_CSC) != 0) + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CSC, portsc); + + /* Check current connect status */ + + if ((portsc & EHCI_PORTSC_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!rhport->connected) + { + /* Yes.. connected. */ + + rhport->connected = true; + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_CONNECTED, + rhpndx + 1, g_ehci.pscwait); + + /* Notify any waiters */ + + if (g_ehci.pscwait) + { + lpc43_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CONNALREADY, portsc); + } + } + else + { + /* Disconnected... Did we just become disconnected? */ + + if (rhport->connected) + { + /* Yes.. disconnect the device */ + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_DISCONND, + rhpndx+1, g_ehci.pscwait); + + rhport->connected = false; + rhport->lowspeed = false; + + /* Are we bound to a class instance? */ + + hport = &rhport->hport.hport; + if (hport->devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(hport->devclass); + hport->devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change + * event. + */ + + if (g_ehci.pscwait) + { + lpc43_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_DISCALREADY, portsc); + } + } + } + + /* Clear all pending port interrupt sources by writing a '1' to the + * corresponding bit in the PORTSC register. In addition, we need + * to preserve the values of all R/W bits (RO bits don't matter) + */ + + lpc43_putreg(portsc, &HCOR->portsc[rhpndx]); + } +} + +/**************************************************************************** + * Name: lpc43_syserr_bottomhalf + * + * Description: + * EHCI Host System Error "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 when a serious error occurs during a + * host system access involving the Host Controller module. ... When this + * error occurs, the Host Controller clears the Run/Stop bit in the Command + * register to prevent further execution of the scheduled TDs." + * + ****************************************************************************/ + +static inline void lpc43_syserr_bottomhalf(void) +{ + usbhost_trace1(EHCI_TRACE1_SYSERR_INTR, 0); + PANIC(); +} + +/**************************************************************************** + * Name: lpc43_async_advance_bottomhalf + * + * Description: + * EHCI Async Advance "Bottom Half" interrupt handler + * + * "System software can force the host controller to issue an interrupt the + * next time the host controller advances the asynchronous schedule by writing + * a one to the Interrupt on Async Advance Doorbell bit in the USBCMD + * register. This status bit indicates the assertion of that interrupt + * source." + * + ****************************************************************************/ + +static inline void lpc43_async_advance_bottomhalf(void) +{ + usbhost_vtrace1(EHCI_VTRACE1_AAINTR, 0); + + /* REVISIT: Could remove all tagged QH entries here */ +} + +/**************************************************************************** + * Name: lpc43_ehci_bottomhalf + * + * Description: + * EHCI "Bottom Half" interrupt handler + * + ****************************************************************************/ + +static void lpc43_ehci_bottomhalf(FAR void *arg) +{ + uint32_t pending = (uint32_t)arg; + + /* We need to have exclusive access to the EHCI data structures. Waiting here + * is not a good thing to do on the worker thread, but there is no real option + * (other than to reschedule and delay). + */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Handle all unmasked interrupt sources */ + /* USB Interrupt (USBINT) + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * USB Error Interrupt (USBERRINT) + * + * "The Host Controller sets this bit to 1 when completion of a USB + * transaction results in an error condition (e.g., error counter + * underflow). If the TD on which the error interrupt occurred also + * had its IOC bit set, both this bit and USBINT bit are set. ..." + * + * We do the same thing in either case: Traverse the asynchonous queue + * and remove all of the transfers that are no longer active. + */ + + if ((pending & (EHCI_INT_USBINT | EHCI_INT_USBERRINT)) != 0) + { + if ((pending & EHCI_INT_USBERRINT) != 0) + { + usbhost_trace1(EHCI_TRACE1_USBERR_INTR, pending); + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending); + } + + lpc43_ioc_bottomhalf(); + } + + /* Port Change Detect + * + * "The Host Controller sets this bit to a one when any port for which + * the Port Owner bit is set to zero ... has a change bit transition + * from a zero to a one or a Force Port Resume bit transition from a zero + * to a one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership + * of a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition + * of the EHCI HC device, this bit is loaded with the OR of all of the + * PORTSC change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + */ + + if ((pending & EHCI_INT_PORTSC) != 0) + { + lpc43_portsc_bottomhalf(); + } + + /* Frame List Rollover + * + * "The Host Controller sets this bit to a one when the Frame List Index ... + * rolls over from its maximum value to zero. The exact value at which + * the rollover occurs depends on the frame list size. For example, if + * the frame list size (as programmed in the Frame List Size field of the + * USBCMD register) is 1024, the Frame Index Register rolls over every + * time FRINDEX[13] toggles. Similarly, if the size is 512, the Host + * Controller sets this bit to a one every time FRINDEX[12] toggles." + */ + +#if 0 /* Not used */ + if ((pending & EHCI_INT_FLROLL) != 0) + { + lpc43_flroll_bottomhalf(); + } +#endif + + /* Host System Error + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit + * in the Command register to prevent further execution of the scheduled + * TDs." + */ + + if ((pending & EHCI_INT_SYSERROR) != 0) + { + lpc43_syserr_bottomhalf(); + } + + /* Interrupt on Async Advance + * + * "System software can force the host controller to issue an interrupt + * the next time the host controller advances the asynchronous schedule + * by writing a one to the Interrupt on Async Advance Doorbell bit in + * the USBCMD register. This status bit indicates the assertion of that + * interrupt source." + */ + + if ((pending & EHCI_INT_AAINT) != 0) + { + lpc43_async_advance_bottomhalf(); + } + + /* We are done with the EHCI structures */ + + lpc43_givesem(&g_ehci.exclsem); + + /* Re-enable relevant EHCI interrupts. Interrupts should still be enabled + * at the level of the interrupt controller. + */ + + lpc43_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); +} + +/**************************************************************************** + * Name: lpc43_ehci_interrupt + * + * Description: + * EHCI "Top Half" interrupt handler + * + ****************************************************************************/ + +static int lpc43_ehci_interrupt(int irq, FAR void *context) +{ + uint32_t usbsts; + uint32_t pending; + uint32_t regval; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + usbsts = lpc43_getreg(&HCOR->usbsts); + regval = lpc43_getreg(&HCOR->usbintr); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(EHCI_VTRACE1_TOPHALF, usbsts & regval); +#else + ullvdbg("USBSTS: %08x USBINTR: %08x\n", usbsts, regval); +#endif + + /* Handle all unmasked interrupt sources */ + + pending = usbsts & regval; + if (pending != 0) + { + /* Schedule interrupt handling work for the high priority worker thread + * so that we are not pressed for time and so that we can interrupt with + * other USB threads gracefully. + * + * The worker should be available now because we implement a handshake + * by controlling the EHCI interrupts. + */ + + DEBUGASSERT(work_available(&g_ehci.work)); + DEBUGVERIFY(work_queue(HPWORK, &g_ehci.work, lpc43_ehci_bottomhalf, + (FAR void *)pending, 0)); + + /* Disable further EHCI interrupts so that we do not overrun the work + * queue. + */ + + lpc43_putreg(0, &HCOR->usbintr); + + /* Clear all pending status bits by writing the value of the pending + * interrupt bits back to the status register. + */ + + lpc43_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR->usbsts); + } + + return OK; +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc43_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + irqstate_t flags; + int rhpndx; + + /* Loop until a change in the connection state changes on one of the root hub + * ports or until an error occurs. + */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < LPC43_EHCI_NRHPORT; rhpndx++) + { + struct lpc43_rhport_s *rhport; + struct usbhost_hubport_s *connport; + + /* Has the connection state changed on the RH port? */ + + rhport = &g_ehci.rhport[rhpndx]; + connport = &rhport->hport.hport; + if (rhport->connected != connport->connected) + { + /* Yes.. Return the RH port to inform the caller which + * port has the connection change. + */ + + connport->connected = rhport->connected; + *hport = connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + rhpndx + 1, rhport->connected); + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (g_ehci.hport) + { + volatile struct usbhost_hubport_s *connport; + + /* Yes.. return the external hub port */ + + connport = g_ehci.hport; + g_ehci.hport = NULL; + + *hport = (struct usbhost_hubport_s *)connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + connport->port + 1, connport->connected); + return OK; + } +#endif + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + + g_ehci.pscwait = true; + lpc43_takesem(&g_ehci.pscsem); + } +} + +/**************************************************************************** + * Name: lpc43_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc43_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + struct lpc43_rhport_s *rhport; + volatile uint32_t *regaddr; + uint32_t regval; + int rhpndx; + + DEBUGASSERT(conn != NULL && hport != NULL); + rhpndx = hport->port; + + DEBUGASSERT(rhpndx >= 0 && rhpndx < LPC43_EHCI_NRHPORT); + rhport = &g_ehci.rhport[rhpndx]; + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!rhport->connected) + { + /* No, return an error */ + + usbhost_vtrace1(EHCI_VTRACE1_ENUM_DISCONN, 0); + return -ENODEV; + } + + /* USB 2.0 spec says at least 50ms delay before port reset. + * REVISIT: I think this is wrong. It needs to hold the port in + * reset for 50Msec, not wait 50Msec before resetting. + */ + + usleep(100*1000); + + /* Paragraph 2.3.9: + * + * "Line Status ... These bits reflect the current logical levels of the + * D+ (bit 11) and D- (bit 10) signal lines. These bits are used for + * detection of low-speed USB devices prior to the port reset and enable + * sequence. This field is valid only when the port enable bit is zero + * and the current connect status bit is set to a one." + * + * Bits[11:10] USB State Interpretation + * ----------- --------- -------------- + * 00b SE0 Not Low-speed device, perform EHCI reset + * 10b J-state Not Low-speed device, perform EHCI reset + * 01b K-state Low-speed device, release ownership of port + * + * NOTE: Low-speed devices could be detected by examining the PORTSC PSPD + * field after resetting the device. The more convential way here, however, + * also appears to work. + */ + + regval = lpc43_getreg(&HCOR->portsc[rhpndx]); + if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE) + { + /* EHCI Paragraph 2.3.9: + * + * "Port Owner ... This bit unconditionally goes to a 0b when the + * Configured bit in the CONFIGFLAG register makes a 0b to 1b + * transition. This bit unconditionally goes to 1b whenever the + * Configured bit is zero. + * + * "System software uses this field to release ownership of the + * port to a selected host controller (in the event that the + * attached device is not a high-speed device). Software writes + * a one to this bit when the attached device is not a high-speed + * device. A one in this bit means that a companion host + * controller owns and controls the port. .... + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + hport->speed = USB_SPEED_LOW; + +#if 0 /* The LPC43xx does not support a companion host controller */ + regval |= EHCI_PORTSC_OWNER; + lpc43_putreg(regval, &HCOR->portsc[rhpndx]); + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; +#endif + } + else + { + /* Assume full-speed for now */ + + hport->speed = USB_SPEED_FULL; + } + + /* Put the root hub port in reset. + * + * Paragraph 2.3.9: + * + * "The HCHalted bit in the USBSTS register should be a zero before + * software attempts to use [the Port Reset] bit. The host controller + * may hold Port Reset asserted to a one when the HCHalted bit is a one. + */ + + DEBUGASSERT((lpc43_getreg(&HCOR->usbsts) & EHCI_USBSTS_HALTED) == 0); + + /* EHCI paragraph 2.3.9: + * + * "When software writes a one to [the Port Reset] bit (from a zero), the + * bus reset sequence as defined in the USB Specification Revision 2.0 is + * started. Software writes a zero to this bit to terminate the bus reset + * sequence. Software must keep this bit at a one long enough to ensure + * the reset sequence, as specified in the USB Specification Revision 2.0, + * completes. Note: when software writes this bit to a one, it must also + * write a zero to the Port Enable bit." + */ + + regaddr = &HCOR->portsc[RHPNDX(rhport)]; + regval = lpc43_getreg(regaddr); + regval &= ~EHCI_PORTSC_PE; + regval |= EHCI_PORTSC_RESET; + lpc43_putreg(regval, regaddr); + + /* USB 2.0 "Root hubs must provide an aggregate reset period of at least + * 50 ms." + */ + + usleep(50*1000); + + regval = lpc43_getreg(regaddr); + regval &= ~EHCI_PORTSC_RESET; + lpc43_putreg(regval, regaddr); + + /* Wait for the port reset to complete + * + * EHCI Paragraph 2.3.9: + * + * "Note that when software writes a zero to this bit there may be a + * delay before the bit status changes to a zero. The bit status will + * not read as a zero until after the reset has completed. If the port + * is in high-speed mode after reset is complete, the host controller + * will automatically enable this port (e.g. set the Port Enable bit + * to a one). A host controller must terminate the reset and stabilize + * the state of the port within 2 milliseconds of software transitioning + * this bit from a one to a zero ..." + */ + + while ((lpc43_getreg(regaddr) & EHCI_PORTSC_RESET) != 0); + usleep(200*1000); + + /* EHCI Paragraph 4.2.2: + * + * "... The reset process is actually complete when software reads a zero + * in the PortReset bit. The EHCI Driver checks the PortEnable bit in the + * PORTSC register. If set to a one, the connected device is a high-speed + * device and EHCI Driver (root hub emulator) issues a change report to the + * hub driver and the hub driver continues to enumerate the attached device." + * + * "At the time the EHCI Driver receives the port reset and enable request + * the LineStatus bits might indicate a low-speed device. Additionally, + * when the port reset process is complete, the PortEnable field may + * indicate that a full-speed device is attached. In either case the EHCI + * driver sets the PortOwner bit in the PORTSC register to a one to + * release port ownership to a companion host controller." + * + * LPC43xx User Manual Paragraph 6.1.3: + * + * "In a standard EHCI controller design, the EHCI host controller driver + * detects a Full speed (FS) or Low speed (LS) device by noting if the + * port enable bit is set after the port reset operation. The port enable + * will only be set in a standard EHCI controller implementation after the + * port reset operation and when the host and device negotiate a High-Speed + * connection (i.e. Chirp completes successfully). Since this controller has + * an embedded Transaction Translator, the port enable will always be set + * after the port reset operation regardless of the result of the host device + * chirp result and the resulting port speed will be indicated by the PSPD + * field in PORTSC1. + */ + + regval = lpc43_getreg(&HCOR->portsc[rhpndx]); + +#if 0 /* LPC43xx detects high- vs full-speed devices using the PSPD field */ + if ((regval & EHCI_PORTSC_PE) != 0) +#else + if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_HS) +#endif + { + /* High speed device */ + + hport->speed = USB_SPEED_HIGH; + } + else if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_FS) + { + /* Low- or Full- speed device. Set the port ownership bit. + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + DEBUGASSERT(hport->speed == USB_SPEED_FULL); + +#if 0 /* The LPC43xx does not support a companion host controller */ + regval |= EHCI_PORTSC_OWNER; + lpc43_putreg(regval, &HCOR->portsc[rhpndx]); + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; +#endif + } + + /* Otherwise it must be a low speed device */ + + else + { + DEBUGASSERT(hport->speed == USB_SPEED_LOW); + DEBUGASSERT((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_LS); + } + + return OK; +} + +static int lpc43_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + int ret; + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + + DEBUGASSERT(hport); +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = lpc43_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + usbhost_vtrace1(EHCI_VTRACE1_CLASSENUM, hport->port); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + /* Failed to enumerate */ + + usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, hport->port + 1, -ret); + + /* If this is a root hub port, then marking the hub port not connected will + * cause lpc43_wait() to return and we will try the connection again. + */ + + hport->connected = false; + } + + return ret; +} + +/************************************************************************************ + * Name: lpc43_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls. A funcaddr of zero will be received if no address is yet assigned + * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc43_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) +{ + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)ep0; + + DEBUGASSERT(drvr != NULL && epinfo != NULL && maxpacketsize < 2048); + + /* We must have exclusive access to the EHCI data structures. */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Remember the new device address and max packet size */ + + epinfo->devaddr = funcaddr; + epinfo->speed = speed; + epinfo->maxpacket = maxpacketsize; + + lpc43_givesem(&g_ehci.exclsem); + return OK; +} + +/************************************************************************************ + * Name: lpc43_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc43_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep) +{ + struct lpc43_epinfo_s *epinfo; + struct usbhost_hubport_s *hport; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && epdesc->hport != NULL && ep != NULL); + hport = epdesc->hport; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_EPALLOC, epdesc->addr, epdesc->xfrtype); +#else + uvdbg("EP%d DIR=%s FA=%08x TYPE=%d Interval=%d MaxPacket=%d\n", + epdesc->addr, epdesc->in ? "IN" : "OUT", hport->funcaddr, + epdesc->xfrtype, epdesc->interval, epdesc->mxpacketsize); +#endif + + /* Allocate a endpoint information structure */ + + epinfo = (struct lpc43_epinfo_s *)kmm_zalloc(sizeof(struct lpc43_epinfo_s)); + if (!epinfo) + { + usbhost_trace1(EHCI_TRACE1_EPALLOC_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the endpoint container (which is really just another form of + * 'struct usbhost_epdesc_s', packed differently and with additional + * information. A cleaner design might just embed struct usbhost_epdesc_s + * inside of struct lpc43_epinfo_s and just memcpy here. + */ + + epinfo->epno = epdesc->addr; + epinfo->dirin = epdesc->in; + epinfo->devaddr = hport->funcaddr; +#ifndef CONFIG_USBHOST_INT_DISABLE + epinfo->interval = epdesc->interval; +#endif + epinfo->maxpacket = epdesc->mxpacketsize; + epinfo->xfrtype = epdesc->xfrtype; + epinfo->speed = hport->speed; + sem_init(&epinfo->iocsem, 0, 0); + + /* Success.. return an opaque reference to the endpoint information structure + * instance + */ + + *ep = (usbhost_ep_t)epinfo; + return OK; +} + +/************************************************************************************ + * Name: lpc43_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc43_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)ep; + + /* There should not be any pending, transfers */ + + DEBUGASSERT(drvr && epinfo && epinfo->iocwait == 0); + + /* Free the container */ + + kmm_free(epinfo); + return OK; +} + +/**************************************************************************** + * Name: lpc43_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * allocate the request/descriptor memory. If the underlying hardware does + * not support such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was + * assumed that the driver maintains a pool of small, pre-allocated buffers + * for descriptor traffic. NOTE that size is not an input, but an output: + * The size of the pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of a memory location provided by the caller in which + * to return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which + * to return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc43_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + int ret = -ENOMEM; + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special requirements for transfer/descriptor buffers. */ + + *buffer = (FAR uint8_t *)kmm_malloc(CONFIG_LPC43_EHCI_BUFSIZE); + if (*buffer) + { + *maxlen = CONFIG_LPC43_EHCI_BUFSIZE; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc43_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * free that request/descriptor memory. If the underlying hardware does not + * support such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc43_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the transfer/descriptor buffer memory */ + + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: lpc43_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kumm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc43_ioalloc(FAR struct usbhost_driver_s *drvr, FAR uint8_t **buffer, + size_t buflen) +{ + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* The only special requirements for I/O buffers are they might need to be user + * accessible (depending on how the class driver implements its buffering). + */ + + *buffer = (FAR uint8_t *)kumm_malloc(buflen); + return *buffer ? OK : -ENOMEM; +} + +/************************************************************************************ + * Name: lpc43_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kumm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int lpc43_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the I/O buffer memory */ + + kumm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: lpc43_ctrlin and lpc43_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer + * may be queued; Neither these methods nor the transfer() method can be + * called again until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using + * DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int lpc43_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + struct lpc43_rhport_s *rhport = (struct lpc43_rhport_s *)drvr; + struct lpc43_epinfo_s *ep0info = (struct lpc43_epinfo_s *)ep0; + uint16_t len; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport != NULL && ep0info != NULL && req != NULL); + + len = lpc43_read16(req->len); + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, RHPORT(rhport), req->req); +#else + uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %04x\n", + RHPORT(rhport), req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], len); +#endif + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = lpc43_ioc_setup(rhport, ep0info); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Now initiate the transfer */ + + ret = lpc43_async_setup(rhport, ep0info, req, buffer, len); + if (ret < 0) + { + udbg("ERROR: lpc43_async_setup failed: %d\n", ret); + goto errout_with_iocwait; + } + + /* And wait for the transfer to complete */ + + nbytes = lpc43_transfer_wait(ep0info); + lpc43_givesem(&g_ehci.exclsem); + return nbytes >= 0 ? OK : (int)nbytes; + +errout_with_iocwait: + ep0info->iocwait = false; +errout_with_sem: + lpc43_givesem(&g_ehci.exclsem); + return ret; +} + +static int lpc43_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + /* lpc43_ctrlin can handle both directions. We just need to work around the + * differences in the function signatures. + */ + + return lpc43_ctrlin(drvr, ep0, req, (uint8_t *)buffer); +} + +/**************************************************************************** + * Name: lpc43_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t lpc43_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + struct lpc43_rhport_s *rhport = (struct lpc43_rhport_s *)drvr; + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)ep; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = lpc43_ioc_setup(rhport, epinfo); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = lpc43_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = lpc43_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_iocwait; + } + + /* Then wait for the transfer to complete */ + + nbytes = lpc43_transfer_wait(epinfo); + lpc43_givesem(&g_ehci.exclsem); + return nbytes; + +errout_with_iocwait: + epinfo->iocwait = false; +errout_with_sem: + lpc43_givesem(&g_ehci.exclsem); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: lpc43_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int lpc43_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + struct lpc43_rhport_s *rhport = (struct lpc43_rhport_s *)drvr; + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)ep; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Set the request for the callback well BEFORE initiating the transfer. */ + + ret = lpc43_ioc_async_setup(rhport, epinfo, callback, arg); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = lpc43_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = lpc43_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_callback; + } + + /* The transfer is in progress */ + + lpc43_givesem(&g_ehci.exclsem); + return OK; + +errout_with_callback: + epinfo->callback = NULL; + epinfo->arg = NULL; +errout_with_sem: + lpc43_givesem(&g_ehci.exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: lpc43_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int lpc43_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct lpc43_epinfo_s *epinfo = (struct lpc43_epinfo_s *)ep; + struct lpc43_qh_s *qh; +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; + void *arg; +#endif + uint32_t *bp; + irqstate_t flags; + bool iocwait; + int ret; + + DEBUGASSERT(epinfo); + + /* We must have exclusive access to the EHCI hardware and data structures. This + * will prevent servicing any transfer completion events while we perform the + * the cancellation, but will not prevent DMA-related race conditions. + * + * REVISIT: This won't work. This function must be callable from the interrupt + * level. + */ + + lpc43_takesem(&g_ehci.exclsem); + + /* Sample and reset all transfer termination information. This will prevent any + * callbacks from occurring while are performing the cancellation. The transfer + * may still be in progress, however, so this does not eliminate other DMA- + * related race conditions. + */ + + flags = enter_critical_section(); +#ifdef CONFIG_USBHOST_ASYNCH + callback = epinfo->callback; + arg = epinfo->arg; +#endif + iocwait = epinfo->iocwait; + +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; + epinfo->arg = NULL; +#endif + epinfo->iocwait = false; + + /* This will prevent any callbacks from occurring while are performing + * the cancellation. The transfer may still be in progress, however, so + * this does not eliminate other DMA-related race conditions. + */ + + epinfo->callback = NULL; + epinfo->arg = NULL; + leave_critical_section(flags); + + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + + /* Handle the cancellation according to the type of the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + case USB_EP_ATTR_XFER_BULK: + { + /* Get the horizontal pointer from the head of the asynchronous + * queue. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct lpc43_qh_s *)lpc43_virtramaddr(lpc43_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in + * the asynchronous queue head will point back to the the queue + * head. + */ + + if (qh && qh != &g_asynchead) + { + /* Claim that we successfully cancelled the transfer */ + + ret = OK; + goto exit_terminate; + } + } + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + { + /* Get the horizontal pointer from the head of the interrupt + * queue. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct lpc43_qh_s *)lpc43_virtramaddr(lpc43_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* if the queue is empty, then just claim that we successfully + * cancelled the transfer. + */ + + ret = OK; + goto exit_terminate; + } + } + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + goto errout_with_sem; + } + + /* Find and remove the QH. There are four possibilities: + * + * 1) The transfer has already completed and the QH is no longer in the list. In + * this case, lpc43_hq_foreach will return zero + * 2a) The transfer is not active and still pending. It was removed from the list + * and lpc43_hq_foreach will return one. + * 2b) The is active but not yet complete. This is currently handled the same as + * 2a). REVISIT: This needs to be fixed. + * 3) Some bad happened and lpc43_hq_foreach returned an error code < 0. + */ + + ret = lpc43_qh_foreach(qh, &bp, lpc43_qh_cancel, epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Was there a pending synchronous transfer? */ + +exit_terminate: + epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH + if (iocwait) + { + /* Yes... wake it up */ + + DEBUGASSERT(callback == NULL); + lpc43_givesem(&epinfo->iocsem); + } + + /* No.. Is there a pending asynchronous transfer? */ + + else /* if (callback != NULL) */ + { + /* Yes.. perform the callback */ + + callback(arg, -ESHUTDOWN); + } + +#else + /* Wake up the waiting thread */ + + lpc43_givesem(&epinfo->iocsem); +#endif + +errout_with_sem: + lpc43_givesem(&g_ehci.exclsem); + return ret; +} + +/************************************************************************************ + * Name: lpc43_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int lpc43_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */ + + g_ehci.hport = hport; + if (g_ehci.pscwait) + { + g_ehci.pscwait = false; + lpc43_givesem(&g_ehci.pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc43_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void lpc43_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_reset + * + * Description: + * Set the HCRESET bit in the USBCMD register to reset the EHCI hardware. + * + * Table 2-9. USBCMD - USB Command Register Bit Definitions + * + * "Host Controller Reset (HCRESET) ... This control bit is used by software + * to reset the host controller. The effects of this on Root Hub registers + * are similar to a Chip Hardware Reset. + * + * "When software writes a one to this bit, the Host Controller resets its + * internal pipelines, timers, counters, state machines, etc. to their + * initial value. Any transaction currently in progress on USB is + * immediately terminated. A USB reset is not driven on downstream + * ports. + * + * "PCI Configuration registers are not affected by this reset. All + * operational registers, including port registers and port state machines + * are set to their initial values. Port ownership reverts to the companion + * host controller(s)... Software must reinitialize the host controller ... + * in order to return the host controller to an operational state. + * + * "This bit is set to zero by the Host Controller when the reset process is + * complete. Software cannot terminate the reset process early by writing a + * zero to this register. Software should not set this bit to a one when + * the HCHalted bit in the USBSTS register is a zero. Attempting to reset + * an actively running host controller will result in undefined behavior." + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + * Assumptions: + * - Called during the initialization of the EHCI. + * + ****************************************************************************/ + +static int lpc43_reset(void) +{ + uint32_t regval; + unsigned int timeout; + + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to 0, + * the Host Controller completes the current transaction on the USB and then + * halts. The HC Halted bit in the status register indicates when the Hos + * Controller has finished the transaction and has entered the stopped state..." + */ + + lpc43_putreg(0, &HCOR->usbcmd); + + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in + * the USBSTS register is a zero. Attempting to reset an actively running + * host controller will result in undefined behavior." + */ + + timeout = 0; + do + { + /* Wait one microsecond and update the timeout counter */ + + up_udelay(1); + timeout++; + + /* Get the current value of the USBSTS register. This loop will terminate + * when either the timeout exceeds one millisecond or when the HCHalted + * bit is no longer set in the USBSTS register. + */ + + regval = lpc43_getreg(&HCOR->usbsts); + } + while (((regval & EHCI_USBSTS_HALTED) == 0) && (timeout < 1000)); + + /* Is the EHCI still running? Did we timeout? */ + + if ((regval & EHCI_USBSTS_HALTED) == 0) + { + usbhost_trace1(EHCI_TRACE1_HCHALTED_TIMEOUT, regval); + return -ETIMEDOUT; + } + + /* Now we can set the HCReset bit in the USBCMD register to initiate the reset */ + + regval = lpc43_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_HCRESET; + lpc43_putreg(regval, &HCOR->usbcmd); + + /* Wait for the HCReset bit to become clear */ + + do + { + /* Wait five microsecondw and update the timeout counter */ + + up_udelay(5); + timeout += 5; + + /* Get the current value of the USBCMD register. This loop will terminate + * when either the timeout exceeds one second or when the HCReset + * bit is no longer set in the USBSTS register. + */ + + regval = lpc43_getreg(&HCOR->usbcmd); + } + while (((regval & EHCI_USBCMD_HCRESET) != 0) && (timeout < 1000000)); + + /* Return either success or a timeout */ + + return (regval & EHCI_USBCMD_HCRESET) != 0 ? -ETIMEDOUT : OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *lpc43_ehci_initialize(int controller) +{ + FAR struct usbhost_hubport_s *hport; + uint32_t regval; +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + uint16_t regval16; + unsigned int nports; +#endif + uintptr_t physaddr; + int ret; + int i; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(((uintptr_t)&g_asynchead & 0x1f) == 0); + DEBUGASSERT((sizeof(struct lpc43_qh_s) & 0x1f) == 0); + DEBUGASSERT((sizeof(struct lpc43_qtd_s) & 0x1f) == 0); + +#ifdef CONFIG_LPC43_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0); + DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0); +#endif + +#ifndef CONFIG_USBHOST_INT_DISABLE + DEBUGASSERT(((uintptr_t)&g_intrhead & 0x1f) == 0); +#ifdef CONFIG_LPC43_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)g_framelist & 0xfff) == 0); +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + + /* Software Configuration ****************************************************/ + + usbhost_vtrace1(EHCI_VTRACE1_INITIALIZING, 0); + + /* Initialize the EHCI state data structure */ + + sem_init(&g_ehci.exclsem, 0, 1); + sem_init(&g_ehci.pscsem, 0, 0); + + /* Initialize EP0 */ + + sem_init(&g_ehci.ep0.iocsem, 0, 1); + + /* Initialize the root hub port structures */ + + for (i = 0; i < LPC43_EHCI_NRHPORT; i++) + { + struct lpc43_rhport_s *rhport = &g_ehci.rhport[i]; + + /* Initialize the device operations */ + + rhport->drvr.ep0configure = lpc43_ep0configure; + rhport->drvr.epalloc = lpc43_epalloc; + rhport->drvr.epfree = lpc43_epfree; + rhport->drvr.alloc = lpc43_alloc; + rhport->drvr.free = lpc43_free; + rhport->drvr.ioalloc = lpc43_ioalloc; + rhport->drvr.iofree = lpc43_iofree; + rhport->drvr.ctrlin = lpc43_ctrlin; + rhport->drvr.ctrlout = lpc43_ctrlout; + rhport->drvr.transfer = lpc43_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + rhport->drvr.asynch = lpc43_asynch; +#endif + rhport->drvr.cancel = lpc43_cancel; +#ifdef CONFIG_USBHOST_HUB + rhport->drvr.connect = lpc43_connect; +#endif + rhport->drvr.disconnect = lpc43_disconnect; + + /* Initialize EP0 */ + + rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; + rhport->ep0.speed = USB_SPEED_FULL; + rhport->ep0.maxpacket = 8; + sem_init(&rhport->ep0.iocsem, 0, 0); + + /* Initialize the public port representation */ + + hport = &rhport->hport.hport; + hport->drvr = &rhport->drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = &rhport->ep0; + hport->port = i; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&rhport->hport); + } + +#ifndef CONFIG_LPC43_EHCI_PREALLOCATE + /* Allocate a pool of free Queue Head (QH) structures */ + + g_qhpool = (struct lpc43_qh_s *) + kmm_memalign(32, CONFIG_LPC43_EHCI_NQHS * sizeof(struct lpc43_qh_s)); + if (!g_qhpool) + { + usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0); + return NULL; + } +#endif + + /* Initialize the list of free Queue Head (QH) structures */ + + for (i = 0; i < CONFIG_LPC43_EHCI_NQHS; i++) + { + /* Put the QH structure in a free list */ + + lpc43_qh_free(&g_qhpool[i]); + } + +#ifndef CONFIG_LPC43_EHCI_PREALLOCATE + /* Allocate a pool of free Transfer Descriptor (qTD) structures */ + + g_qtdpool = (struct lpc43_qtd_s *) + kmm_memalign(32, CONFIG_LPC43_EHCI_NQTDS * sizeof(struct lpc43_qtd_s)); + if (!g_qtdpool) + { + usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0); + kmm_free(g_qhpool); + return NULL; + } +#endif + +#if !defined(CONFIG_LPC43_EHCI_PREALLOCATE) && !defined(CONFIG_USBHOST_INT_DISABLE) + /* Allocate the periodic framelist */ + + g_framelist = (uint32_t *) + kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t)); + if (!g_framelist) + { + usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0); + kmm_free(g_qhpool); + kmm_free(g_qtdpool); + return NULL; + } +#endif + + /* Initialize the list of free Transfer Descriptor (qTD) structures */ + + for (i = 0; i < CONFIG_LPC43_EHCI_NQTDS; i++) + { + /* Put the TD in a free list */ + + lpc43_qtd_free(&g_qtdpool[i]); + } + + /* EHCI Hardware Configuration ***********************************************/ + /* Enable USB to AHB clock and to Event router */ + + lpc43_pll0usbconfig(); + lpc43_pll0usbenable(); + + /* Program the controller to be the USB host controller + * + * Fixed selections: + * + * CM = Host mode + * ES = 0, Little endian mode. + * SLOM Not used in host mode. + * VBPS = 1, off-chip power source + * + * Configurable selections: + * + * SDIS = 1, Stream disable mode. Eliminates overruns/underruns at + * the expense of some performance. + */ + +#ifdef CONFIG_LPC43_EHCI_SDIS + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | USBHOST_USBMODE_VBPS, + LPC43_USBDEV_USBMODE); +#else + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS, LPC43_USBDEV_USBMODE); +#endif + + /* Host Controller Initialization. Paragraph 4.1 */ + /* Reset the EHCI hardware */ + + ret = lpc43_reset(); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); + return NULL; + } + + /* Re-program the USB host controller. As implemented, lpc43_reset() + * requires the host mode setup in order to work. However, we lose the + * host configuration in the reset. + */ + +#ifdef CONFIG_LPC43_EHCI_SDIS + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | USBHOST_USBMODE_VBPS, + LPC43_USBDEV_USBMODE); +#else + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS, LPC43_USBDEV_USBMODE); +#endif + + /* "In order to initialize the host controller, software should perform the + * following steps: + * + * - "Program the CTRLDSSEGMENT register with 4-Gigabyte segment where all + * of the interface data structures are allocated. [64-bit mode] + * - "Write the appropriate value to the USBINTR register to enable the + * appropriate interrupts. + * - "Write the base address of the Periodic Frame List to the PERIODICLIST + * BASE register. If there are no work items in the periodic schedule, + * all elements of the Periodic Frame List should have their T-Bits set + * to a one. + * - "Write the USBCMD register to set the desired interrupt threshold, + * frame list size (if applicable) and turn the host controller ON via + * setting the Run/Stop bit. + * - Write a 1 to CONFIGFLAG register to route all ports to the EHCI controller + * ... + * + * "At this point, the host controller is up and running and the port registers + * will begin reporting device connects, etc. System software can enumerate a + * port through the reset process (where the port is in the enabled state). At + * this point, the port is active with SOFs occurring down the enabled por + * enabled Highspeed ports, but the schedules have not yet been enabled. The + * EHCI Host controller will not transmit SOFs to enabled Full- or Low-speed + * ports. + */ + + regval = getreg32(LPC43_CREG0); + regval &= ~CREG0_USB0PHY; + putreg32(regval, LPC43_CREG0); + + /* Disable all interrupts */ + + lpc43_putreg(0, &HCOR->usbintr); + + /* Clear pending interrupts. Bits in the USBSTS register are cleared by + * writing a '1' to the corresponding bit. + */ + + lpc43_putreg(EHCI_INT_ALLINTS, &HCOR->usbsts); + +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + /* Show the EHCI version */ + + regval16 = lpc43_swap16(HCCR->hciversion); + usbhost_vtrace2(EHCI_VTRACE2_HCIVERSION, regval16 >> 8, regval16 & 0xff); + + /* Verify that the correct number of ports is reported */ + + regval = lpc43_getreg(&HCCR->hcsparams); + nports = (regval & EHCI_HCSPARAMS_NPORTS_MASK) >> EHCI_HCSPARAMS_NPORTS_SHIFT; + + usbhost_vtrace2(EHCI_VTRACE2_HCSPARAMS, nports, regval); + DEBUGASSERT(nports == LPC43_EHCI_NRHPORT); + + /* Show the HCCPARAMS register */ + + regval = lpc43_getreg(&HCCR->hccparams); + usbhost_vtrace1(EHCI_VTRACE1_HCCPARAMS, regval); +#endif + + /* Initialize the head of the asynchronous queue/reclamation list. + * + * "In order to communicate with devices via the asynchronous schedule, + * system software must write the ASYNDLISTADDR register with the address + * of a control or bulk queue head. Software must then enable the + * asynchronous schedule by writing a one to the Asynchronous Schedule + * Enable bit in the USBCMD register. In order to communicate with devices + * via the periodic schedule, system software must enable the periodic + * schedule by writing a one to the Periodic Schedule Enable bit in the + * USBCMD register. Note that the schedules can be turned on before the + * first port is reset (and enabled)." + */ + + memset(&g_asynchead, 0, sizeof(struct lpc43_qh_s)); + physaddr = lpc43_physramaddr((uintptr_t)&g_asynchead); + g_asynchead.hw.hlp = lpc43_swap32(physaddr | QH_HLP_TYP_QH); + g_asynchead.hw.epchar = lpc43_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL); + g_asynchead.hw.overlay.nqp = lpc43_swap32(QH_NQP_T); + g_asynchead.hw.overlay.alt = lpc43_swap32(QH_NQP_T); + g_asynchead.hw.overlay.token = lpc43_swap32(QH_TOKEN_HALTED); + g_asynchead.fqp = lpc43_swap32(QTD_NQP_T); + + /* Set the Current Asynchronous List Address. */ + + lpc43_putreg(lpc43_swap32(physaddr), &HCOR->asynclistaddr); + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Initialize the head of the periodic list. Since Isochronous + * endpoints are not not yet supported, each element of the + * frame list is initialized to point to the Interrupt Queue + * Head (g_intrhead). + */ + + memset(&g_intrhead, 0, sizeof(struct lpc43_qh_s)); + g_intrhead.hw.hlp = lpc43_swap32(QH_HLP_T); + g_intrhead.hw.overlay.nqp = lpc43_swap32(QH_NQP_T); + g_intrhead.hw.overlay.alt = lpc43_swap32(QH_NQP_T); + g_intrhead.hw.overlay.token = lpc43_swap32(QH_TOKEN_HALTED); + g_intrhead.hw.epcaps = lpc43_swap32(QH_EPCAPS_SSMASK(1)); + + /* Attach the periodic QH to Period Frame List */ + + physaddr = lpc43_physramaddr((uintptr_t)&g_intrhead); + for (i = 0; i < FRAME_LIST_SIZE; i++) + { + g_framelist[i] = lpc43_swap32(physaddr) | PFL_TYP_QH; + } + + /* Set the Periodic Frame List Base Address. */ + + physaddr = lpc43_physramaddr((uintptr_t)g_framelist); + lpc43_putreg(lpc43_swap32(physaddr), &HCOR->periodiclistbase); +#endif + + /* Enable the asynchronous schedule and, possibly enable the periodic + * schedule and set the frame list size. + */ + + regval = lpc43_getreg(&HCOR->usbcmd); + regval &= ~(EHCI_USBCMD_HCRESET | EHCI_USBCMD_FLSIZE_MASK | + EHCI_USBCMD_FLSIZE_MASK | EHCI_USBCMD_PSEN | + EHCI_USBCMD_IAADB | EHCI_USBCMD_LRESET); + regval |= EHCI_USBCMD_ASEN; + +#ifndef CONFIG_USBHOST_INT_DISABLE + regval |= EHCI_USBCMD_PSEN; +# if FRAME_LIST_SIZE == 1024 + regval |= EHCI_USBCMD_FLSIZE_1024; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_512; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_256; +# else +# error Unsupported frame size list size +# endif +#endif + + lpc43_putreg(regval, &HCOR->usbcmd); + + /* Start the host controller by setting the RUN bit in the USBCMD regsiter. */ + + regval = lpc43_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_RUN; + lpc43_putreg(regval, &HCOR->usbcmd); + + /* Route all ports to this host controller by setting the CONFIG flag. */ + + regval = lpc43_getreg(&HCOR->configflag); + regval |= EHCI_CONFIGFLAG; + lpc43_putreg(regval, &HCOR->configflag); + + /* Wait for the EHCI to run (i.e., no longer report halted) */ + + ret = ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100*1000); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RUN_FAILED, lpc43_getreg(&HCOR->usbsts)); + return NULL; + } + + /* Interrupt Configuration ***************************************************/ + + ret = irq_attach(LPC43M4_IRQ_USB0, lpc43_ehci_interrupt); + if (ret != 0) + { + usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, LPC43M4_IRQ_USB0); + return NULL; + } + + /* Enable EHCI interrupts. Interrupts are still disabled at the level of + * the interrupt controller. + */ + + lpc43_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); + + /* Drive Vbus +5V (the smoke test) + * + * REVISIT: + * - Should be done elsewhere in OTG mode. + * - Can we postpone enabling VBUS to save power? I think it can be + * done in lpc43_enumerate() and can probably be disabled when the + * port is disconnected. + * - Some EHCI implementations require setting the power bit in the + * PORTSC register to enable power. + */ + + /* Handle root hub status change on each root port */ + + for (i = 0; i < LPC43_EHCI_NRHPORT; i++) + { + /* Enable VBUS power for the port */ + + //lpc43_usbhost_vbusdrive(i, true); + up_mdelay(25); + + /* Power up the power. REVISIT: Is this necessary? The PP bit never + * gets set unless I explicitly set it here. + */ + + regval = lpc43_getreg(&HCOR->portsc[i]); + regval |= EHCI_PORTSC_PP; + lpc43_putreg(regval, &HCOR->portsc[i]); + up_mdelay(25); + } + + /* If there is a USB device in the slot at power up, then we will not + * get the status change interrupt to signal us that the device is + * connected. We need to set the initial connected state accordingly. + */ + + for (i = 0; i < LPC43_EHCI_NRHPORT; i++) + { + g_ehci.rhport[i].connected = + ((lpc43_getreg(&HCOR->portsc[i]) & EHCI_PORTSC_CCS) != 0); + } + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(LPC43M4_IRQ_USB0); /* enable USB interrupt */ + usbhost_vtrace1(EHCI_VTRACE1_INIITIALIZED, 0); + + /* Initialize and return the connection interface */ + + g_ehciconn.wait = lpc43_wait; + g_ehciconn.enumerate = lpc43_enumerate; + return &g_ehciconn; +} + +/******************************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ********************************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +FAR const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +FAR const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} +#endif /* HAVE_USBHOST_TRACE */ + +#endif /* CONFIG_LPC43_USBOTG && CONFIG_USBHOST */ diff --git a/arch/arm/src/lpc43xx/lpc43_ehci.h b/arch/arm/src/lpc43xx/lpc43_ehci.h new file mode 100644 index 0000000000000000000000000000000000000000..b6ad0474e58910b10c24ee74d442bec7441c6fd7 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ehci.h @@ -0,0 +1,109 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_ehci.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_EHCI_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_EHCI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc31_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ************************************************************************************/ + +#if defined(CONFIG_LPC43_USBOTG) && defined(CONFIG_USBHOST) +struct usbhost_connection_s; +FAR struct usbhost_connection_s *lpc43_ehci_initialize(int controller); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_EHCI_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_emacram.h b/arch/arm/src/lpc43xx/lpc43_emacram.h new file mode 100644 index 0000000000000000000000000000000000000000..2c472b616cd1ea060a7cce605dc04b20e40d8302 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_emacram.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_emacram.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_EMACRAM_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_EMACRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_EMACRAM_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_emc.h b/arch/arm/src/lpc43xx/lpc43_emc.h new file mode 100644 index 0000000000000000000000000000000000000000..3c2bd2496feacbafc3be8299f70383c2c0ae6324 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_emc.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_emc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_EMC_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_EMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc43_emc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_EMC_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.c b/arch/arm/src/lpc43xx/lpc43_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..733a161c2be0c620fb2c8a6a978313a78deae50c --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ethernet.c @@ -0,0 +1,4063 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_eth.c + * + * Copyright (C) 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_LPC43_ETHERNET) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#if defined(CONFIG_NET_PKT) +# include +#endif + +#include "up_internal.h" + +#include "chip.h" +#include "lpc43_pinconfig.h" +#include "lpc43_ethernet.h" +#include "chip/lpc43_creg.h" +#include "chip/lpc43_cgu.h" +#include "chip/lpc43_ccu.h" +#include "lpc43_rgu.h" +#include "lpc43_gpio.h" +#include "up_arch.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +#ifndef CONFIG_LPC43_PHYADDR +# error "CONFIG_LPC43_PHYADDR must be defined in the NuttX configuration" +#endif + +#if !defined(CONFIG_LPC43_MII) && !defined(CONFIG_LPC43_RMII) +# warning "Neither CONFIG_LPC43_MII nor CONFIG_LPC43_RMII defined" +#endif + +#if defined(CONFIG_LPC43_MII) && defined(CONFIG_LPC43_RMII) +# error "Both CONFIG_LPC43_MII and CONFIG_LPC43_RMII defined" +#endif + +# ifndef CONFIG_LPC43_PHYSR +# error "CONFIG_LPC43_PHYSR must be defined in the NuttX configuration" +# endif + +#ifndef CONFIG_LPC43_AUTONEG +# ifdef CONFIG_LPC43_PHYSR_ALTCONFIG +# ifndef CONFIG_LPC43_PHYSR_ALTMODE +# error "CONFIG_LPC43_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_10HD +# error "CONFIG_LPC43_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_100HD +# error "CONFIG_LPC43_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_10FD +# error "CONFIG_LPC43_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_100FD +# error "CONFIG_LPC43_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_LPC43_PHYSR_SPEED +# error "CONFIG_LPC43_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_100MBPS +# error "CONFIG_LPC43_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_MODE +# error "CONFIG_LPC43_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_LPC43_PHYSR_FULLDUPLEX +# error "CONFIG_LPC43_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +#endif + +#ifdef CONFIG_LPC43_ETH_PTP +# warning "CONFIG_LPC43_ETH_PTP is not yet supported" +#endif + +/* This driver does not use enhanced descriptors. Enhanced descriptors must + * be used, however, if time stamping or and/or IPv4 checksum offload is + * supported. + */ + +#undef CONFIG_LPC43_ETH_ENHANCEDDESC +#undef CONFIG_LPC43_ETH_HWCHECKSUM + +/* Ethernet buffer sizes, number of buffers, and number of descriptors */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER is required" +#endif + +/* Add 4 to the configured buffer size to account for the 2 byte checksum + * memory needed at the end of the maximum size packet. Buffer sizes must + * be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We + * will use the 16-byte alignment in all cases. + */ + +#define OPTIMAL_ETH_BUFSIZE ((CONFIG_NET_ETH_MTU + 4 + 15) & ~15) + +#ifndef CONFIG_LPC43_ETH_BUFSIZE +# define CONFIG_LPC43_ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE +#endif + +#if CONFIG_LPC43_ETH_BUFSIZE > ETH_TDES1_TBS1_MASK +# error "CONFIG_LPC43_ETH_BUFSIZE is too large" +#endif + +#if (CONFIG_LPC43_ETH_BUFSIZE & 15) != 0 +# error "CONFIG_LPC43_ETH_BUFSIZE must be aligned" +#endif + +#if CONFIG_LPC43_ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE +# warning "You using an incomplete/untested configuration" +#endif + +#ifndef CONFIG_LPC43_ETH_NRXDESC +# define CONFIG_LPC43_ETH_NRXDESC 8 +#endif +#ifndef CONFIG_LPC43_ETH_NTXDESC +# define CONFIG_LPC43_ETH_NTXDESC 4 +#endif + +/* We need at least one more free buffer than transmit buffers */ + +#define LPC43_ETH_NFREEBUFFERS (CONFIG_LPC43_ETH_NTXDESC+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_LPC43_ETHMAC_REGDEBUG +#endif + +/* Clocking *****************************************************************/ +/* Set MACMIIAR CR bits depending on HCLK setting */ + +#if BOARD_FCLKOUT_FREQUENCY >= 20000000 && BOARD_FCLKOUT_FREQUENCY < 35000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_20_35 +#elif BOARD_FCLKOUT_FREQUENCY >= 35000000 && BOARD_FCLKOUT_FREQUENCY < 60000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_35_60 +#elif BOARD_FCLKOUT_FREQUENCY >= 60000000 && BOARD_FCLKOUT_FREQUENCY < 100000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_60_100 +#elif BOARD_FCLKOUT_FREQUENCY >= 100000000 && BOARD_FCLKOUT_FREQUENCY < 150000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_100_150 +#elif BOARD_FCLKOUT_FREQUENCY >= 150000000 && BOARD_FCLKOUT_FREQUENCY <= 250000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_150_250 +#elif BOARD_FCLKOUT_FREQUENCY >= 250000000 && BOARD_FCLKOUT_FREQUENCY <= 350000000 +# define ETH_MACMIIA_CR ETH_MACMIIA_CR_250_300 +#else +# error "BOARD_FCLKOUT_FREQUENCY not supportable" +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define LPC43_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define LPC43_TXTIMEOUT (60*CLK_TCK) + +/* PHY reset/configuration delays in milliseconds */ + +#define PHY_RESET_DELAY (65) +#define PHY_CONFIG_DELAY (1000) + +/* PHY read/write delays in loop counts */ + +#define PHY_READ_TIMEOUT (0x0004ffff) +#define PHY_WRITE_TIMEOUT (0x0004ffff) +#define PHY_RETRY_TIMEOUT (0x0004ffff) + +/* Register values **********************************************************/ + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACCFG_RE Bit 2: Receiver enable + * ETH_MACCFG_TE Bit 3: Transmitter enable + * ETH_MACCFG_DC Bit 4: Deferral check + * ETH_MACCFG_BL Bits 5-6: Back-off limit + * ETH_MACCFG_APCS Bit 7: Automatic pad/CRC stripping + * ETH_MACCFG_RD Bit 9: Retry disable + * ETH_MACCFG_DM Bit 11: Duplex mode + * ETH_MACCFG_LM Bit 12: Loopback mode + * ETH_MACCFG_DO Bit 13: Receive own disable + * ETH_MACCFG_FES Bit 14: Fast Ethernet speed + * ETH_MACCFG_CSD Bit 16: Carrier sense disable + * ETH_MACCFG_IFG Bits 17-19: Interframe gap + * ETH_MACCFG_JD Bit 22: Jabber disable + * ETH_MACCFG_WD Bit 23: Watchdog disable + * ETH_MACCFG_CSTF Bits 25: CRC stripping for Type frames (F2/F4 only) + */ + +#define MACCR_CLEAR_BITS \ + (ETH_MACCFG_RE | ETH_MACCFG_TE | ETH_MACCFG_DF | ETH_MACCFG_BL_MASK | \ + ETH_MACCFG_ACS | ETH_MACCFG_RD | ETH_MACCFG_DM | \ + ETH_MACCFG_LM | ETH_MACCFG_DO | ETH_MACCFG_FES | ETH_MACCFG_DCRS | \ + ETH_MACCFG_JE | ETH_MACCFG_IFG_MASK | ETH_MACCFG_JD | ETH_MACCFG_WD) + + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACCFG_RE Receiver enable 0 (disabled) + * ETH_MACCFG_TE Transmitter enable 0 (disabled) + * ETH_MACCFG_DC Deferral check 0 (disabled) + * ETH_MACCFG_BL Back-off limit 0 (10) + * ETH_MACCFG_APCS Automatic pad/CRC stripping 0 (disabled) + * ETH_MACCFG_RD Retry disable 1 (disabled) + * ETH_MACCFG_LM Loopback mode 0 (disabled) + * ETH_MACCFG_ROD Receive own disable 0 (enabled) + * ETH_MACCFG_CSD Carrier sense disable 0 (enabled) + * ETH_MACCFG_IFG Interframe gap 0 (96 bits) + * ETH_MACCFG_JD Jabber disable 0 (enabled) + * ETH_MACCFG_WD Watchdog disable 0 (enabled) + * ETH_MACCFG_CSTF CRC stripping for Type frames 0 (disabled, F2/F4 only) + * + * The following are set conditioinally based on mode and speed. + * + * ETH_MACCFG_DM Duplex mode Depends on priv->fduplex + * ETH_MACCFG_FES Fast Ethernet speed Depends on priv->mbps100 + */ + +# define MACCR_SET_BITS \ + (ETH_MACCFG_BL_10 | ETH_MACCFG_RD | ETH_MACCFG_IFG(96)) + + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFFR_PM Bit 0: Promiscuous mode + * ETH_MACFFR_HU Bit 1: Hash unicast + * ETH_MACFFR_HM Bit 2: Hash multicast + * ETH_MACFFR_DAIF Bit 3: Destination address inverse filtering + * ETH_MACFFR_PAM Bit 4: Pass all multicast + * ETH_MACFFR_BFD Bit 5: Broadcast frames disable + * ETH_MACFFR_PCF Bits 6-7: Pass control frames + * ETH_MACFFR_SAIF Bit 8: Source address inverse filtering + * ETH_MACFFR_SAF Bit 9: Source address filter + * ETH_MACFFR_HPF Bit 10: Hash or perfect filter + * ETH_MACFFR_RA Bit 31: Receive all + */ + +#define MACFFR_CLEAR_BITS \ + (ETH_MACFFLT_PR | ETH_MACFFLT_HUC | ETH_MACFFLT_HMC | ETH_MACFFLT_DAIF | \ + ETH_MACFFLT_PM | ETH_MACFFLT_DBF | ETH_MACFFLT_PCF_MASK | ETH_MACFFLT_HPF | \ + ETH_MACFFLT_RA) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFFLT_PM Promiscuous mode 0 (disabled) + * ETH_MACFFLT_HU Hash unicast 0 (perfect dest filtering) + * ETH_MACFFLT_HM Hash multicast 0 (perfect dest filtering) + * ETH_MACFFLT_DAIF Destination address inverse filtering 0 (normal) + * ETH_MACFFLT_PAM Pass all multicast 0 (Depends on HM bit) + * ETH_MACFFLT_BFD Broadcast frames disable 0 (enabled) + * ETH_MACFFLT_PCF Pass control frames 1 (block all but PAUSE) + * ETH_MACFFLT_HPF Hash or perfect filter 0 (Only matching frames passed) + * ETH_MACFFLT_RA Receive all 0 (disabled) + */ + +#define MACFFR_SET_BITS (ETH_MACFFLT_PCF_PAUSE) + +/* Clear the MACFCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFCR_FCB_BPA Bit 0: Flow control busy/back pressure activate + * ETH_MACFCR_TFCE Bit 1: Transmit flow control enable + * ETH_MACFCR_RFCE Bit 2: Receive flow control enable + * ETH_MACFCR_UPFD Bit 3: Unicast pause frame detect + * ETH_MACFCR_PLT Bits 4-5: Pause low threshold + * ETH_MACFCR_ZQPD Bit 7: Zero-quanta pause disable + * ETH_MACFCR_PT Bits 16-31: Pause time + */ + +#define MACFCR_CLEAR_MASK \ + (ETH_MACFC_FCB | ETH_MACFC_TFE | ETH_MACFC_RFE | ETH_MACFC_UP | \ + ETH_MACFC_PLT_MASK | ETH_MACFC_DZPQ | ETH_MACFC_PT_MASK) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFCR_FCB_BPA Flow control busy/back pressure activate 0 (no pause control frame) + * ETH_MACFCR_TFCE Transmit flow control enable 0 (disabled) + * ETH_MACFCR_RFCE Receive flow control enable 0 (disabled) + * ETH_MACFCR_UPFD Unicast pause frame detect 0 (disabled) + * ETH_MACFCR_PLT Pause low threshold 0 (pause time - 4) + * ETH_MACFCR_ZQPD Zero-quanta pause disable 1 (disabled) + * ETH_MACFCR_PT Pause time 0 + */ + +#define MACFCR_SET_MASK (ETH_MACFC_PLT(4) | ETH_MACFC_DZPQ) + +/* Clear the DMAOMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMAOPMODE_SR Bit 1: Start/stop receive + * TH_DMAOMR_OSF Bit 2: Operate on second frame + * ETH_DMAOPMODE_RTC Bits 3-4: Receive threshold control + * ETH_DMAOPMODE_FUGF Bit 6: Forward undersized good frames + * ETH_DMAOPMODE_FEF Bit 7: Forward error frames + * ETH_DMAOPMODE_ST Bit 13: Start/stop transmission + * ETH_DMAOPMODE_TTC Bits 14-16: Transmit threshold control + * ETH_DMAOPMODE_FTF Bit 20: Flush transmit FIFO + * ETH_DMAOPMODE_TSF Bit 21: Transmit store and forward + * ETH_DMAOPMODE_DFRF Bit 24: Disable flushing of received frames + * ETH_DMAOPMODE_RSF Bit 25: Receive store and forward + * TH_DMAOMR_DTCEFD Bit 26: Dropping of TCP/IP checksum error frames disable + */ + +#define DMAOMR_CLEAR_MASK \ + (ETH_DMAOPMODE_SR | ETH_DMAOPMODE_OSF | ETH_DMAOPMODE_RTC_MASK | ETH_DMAOPMODE_FUF | \ + ETH_DMAOPMODE_FEF | ETH_DMAOPMODE_ST | ETH_DMAOPMODE_TTC_MASK | ETH_DMAOPMODE_FTF | \ + ETH_DMAOPMODE_DFF) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_DMAOPMODE_SR Start/stop receive 0 (not running) + * TH_DMAOMR_OSF Operate on second frame 1 (enabled) + * ETH_DMAOPMODE_RTC Receive threshold control 0 (64 bytes) + * ETH_DMAOPMODE_FUGF Forward undersized good frames 0 (disabled) + * ETH_DMAOPMODE_FEF Forward error frames 0 (disabled) + * ETH_DMAOPMODE_ST Start/stop transmission 0 (not running) + * ETH_DMAOPMODE_TTC Transmit threshold control 0 (64 bytes) + * ETH_DMAOPMODE_FTF Flush transmit FIFO 0 (no flush) + * ETH_DMAOPMODE_TSF Transmit store and forward Depends on CONFIG_LPC43_ETH_HWCHECKSUM + * ETH_DMAOPMODE_DFRF Disable flushing of received frames 0 (enabled) + * ETH_DMAOPMODE_RSF Receive store and forward Depends on CONFIG_LPC43_ETH_HWCHECKSUM + * TH_DMAOMR_DTCEFD Dropping of TCP/IP checksum error Depends on CONFIG_LPC43_ETH_HWCHECKSUM + * frames disable + * + * When the checksum offload feature is enabled, we need to enable the Store + * and Forward mode: the store and forward guarantee that a whole frame is + * stored in the FIFO, so the MAC can insert/verify the checksum, if the + * checksum is OK the DMA can handle the frame otherwise the frame is dropped + */ + +#ifdef CONFIG_LPC43_ETH_HWCHECKSUM +# define DMAOMR_SET_MASK \ + (ETH_DMAOPMODE_OSF | ETH_DMAOPMODE_RTC_64 | ETH_DMAOPMODE_TTC_64 | \ + ETH_DMAOPMODE_TSF | ETH_DMAOPMODE_RSF) +#else +# define DMAOMR_SET_MASK \ + (ETH_DMAOPMODE_OSF | ETH_DMAOPMODE_RTC_64 | ETH_DMAOPMODE_TTC_64) +#endif + +/* Clear the DMABMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMABMODE_SR Bit 0: Software reset + * ETH_DMABMODE_DA Bit 1: DMA Arbitration + * ETH_DMABMODE_DSL Bits 2-6: Descriptor skip length + * ETH_DMABMODE_ATDS Bit 7: Enhanced descriptor format enable + * ETH_DMABMODE_PBL Bits 8-13: Programmable burst length + * ETH_DMABMODE_RTPR Bits 14-15: RX TX priority ratio + * ETH_DMABMODE_FB Bit 16: Fixed burst + * ETH_DMABMODE_RDP Bits 17-22: RX DMA PBL + * ETH_DMABMODE_USP Bit 23: Use separate PBL + * ETH_DMABMODE_FPM Bit 24: 4xPBL mode + * ETH_DMABMODE_AAB Bit 25: Address-aligned beats + * ETH_DMABMODE_MB Bit 26: Mixed burst (F2/F4 only) + */ + +#define DMABMR_CLEAR_MASK \ + (ETH_DMABMODE_SWR | ETH_DMABMODE_DA | ETH_DMABMODE_DSL_MASK | ETH_DMABMODE_ATDS | \ + ETH_DMABMODE_PBL_MASK | ETH_DMABMODE_PR_MASK | ETH_DMABMODE_FB | ETH_DMABMODE_RPBL_MASK | \ + ETH_DMABMODE_USP | ETH_DMABMODE_PBL8X | ETH_DMABMODE_AAL | ETH_DMABMODE_MB | ETH_DMABMODE_TXPR) + + +/* The following bits are set or left zero unconditionally in all modes. + * + * + * ETH_DMABMODE_SR Software reset 0 (no reset) + * ETH_DMABMODE_DA DMA Arbitration 0 (round robin) + * ETH_DMABMODE_DSL Descriptor skip length 0 + * ETH_DMABMODE_ATDS Enhanced descriptor format enable Depends on CONFIG_LPC43_ETH_ENHANCEDDESC + * ETH_DMABMODE_PBL Programmable burst length 32 beats + * ETH_DMABMODE_RTPR RX TX priority ratio 2:1 + * ETH_DMABMODE_FB Fixed burst 1 (enabled) + * ETH_DMABMODE_RDP RX DMA PBL 32 beats + * ETH_DMABMODE_USP Use separate PBL 1 (enabled) + * ETH_DMABMODE_FPM 4xPBL mode 0 (disabled) + * ETH_DMABMODE_AAB Address-aligned beats 1 (enabled) + * ETH_DMABMODE_MB Mixed burst 0 (disabled, F2/F4 only) + */ + +#ifdef CONFIG_LPC43_ETH_ENHANCEDDESC +# define DMABMR_SET_MASK \ + (ETH_DMABMODE_DSL(0) | ETH_DMABMODE_PBL(32) | ETH_DMABMODE_ATDS | ETH_DMABMODE_RTPR_2TO1 | \ + ETH_DMABMODE_FB | ETH_DMABMODE_RPBL(32) | ETH_DMABMODE_USP | ETH_DMABMODE_AAB) +#else +# define DMABMR_SET_MASK \ + (ETH_DMABMODE_DSL(0) | ETH_DMABMODE_PBL(32) | ETH_DMABMODE_PR_2TO1 | ETH_DMABMODE_FB | \ + ETH_DMABMODE_RPBL(32) | ETH_DMABMODE_USP | ETH_DMABMODE_AAL) +#endif + +/* Interrupt bit sets *******************************************************/ +/* All interrupts in the normal and abnormal interrupt summary. Early transmit + * interrupt (ETI) is excluded from the abnormal set because it causes too + * many interrupts and is not interesting. + */ + +#define ETH_DMAINT_NORMAL \ + (ETH_DMAINT_TI | ETH_DMAINT_TU | ETH_DMAINT_RI | ETH_DMAINT_ERI) + +#define ETH_DMAINT_ABNORMAL \ + (ETH_DMAINT_TPS | ETH_DMAINT_TJT | ETH_DMAINT_OVF | ETH_DMAINT_UNF | \ + ETH_DMAINT_RU | ETH_DMAINT_RPS | ETH_DMAINT_RWT | /* ETH_DMAINT_ETI | */ \ + ETH_DMAINT_FBI) + +/* Normal receive, transmit, error interrupt enable bit sets */ + +#define ETH_DMAINT_RECV_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_RI) +#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI) +#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI) + +#ifdef CONFIG_DEBUG_NET +# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL) +#else +# define ETH_DMAINT_ERROR_ENABLE (0) +#endif + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the Ethernet + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The lpc43_ethmac_s encapsulates all state information for a single hardware + * interface + */ + +struct lpc43_ethmac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */ + uint8_t fduplex : 1; /* Full (vs. half) duplex */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + struct eth_txdesc_s *txhead; /* Next available TX descriptor */ + struct eth_rxdesc_s *rxhead; /* Next available RX descriptor */ + + struct eth_txdesc_s *txtail; /* First "in_flight" TX descriptor */ + struct eth_rxdesc_s *rxcurr; /* First RX descriptor of the segment */ + uint16_t segments; /* RX segment count */ + uint16_t inflight; /* Number of TX transfers "in_flight" */ + sq_queue_t freeb; /* The free buffer list */ + + /* Descriptor allocations */ + + struct eth_rxdesc_s rxtable[CONFIG_LPC43_ETH_NRXDESC]; + struct eth_txdesc_s txtable[CONFIG_LPC43_ETH_NTXDESC]; + + /* Buffer allocations */ + + uint8_t rxbuffer[CONFIG_LPC43_ETH_NRXDESC*CONFIG_LPC43_ETH_BUFSIZE]; + uint8_t alloc[LPC43_ETH_NFREEBUFFERS*CONFIG_LPC43_ETH_BUFSIZE]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct lpc43_ethmac_s g_lpc43ethmac; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_LPC43_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc43_getreg(uint32_t addr); +static void lpc43_putreg(uint32_t val, uint32_t addr); +static void lpc43_checksetup(void); +#else +# define lpc43_getreg(addr) getreg32(addr) +# define lpc43_putreg(val,addr) putreg32(val,addr) +# define lpc43_checksetup() +#endif + +/* Free buffer management */ + +static void lpc43_initbuffer(FAR struct lpc43_ethmac_s *priv); +static inline uint8_t *lpc43_allocbuffer(FAR struct lpc43_ethmac_s *priv); +static inline void lpc43_freebuffer(FAR struct lpc43_ethmac_s *priv, uint8_t *buffer); +static inline bool lpc43_isfreebuffer(FAR struct lpc43_ethmac_s *priv); + +/* Common TX logic */ + +static int lpc43_transmit(FAR struct lpc43_ethmac_s *priv); +static int lpc43_txpoll(struct net_driver_s *dev); +static void lpc43_dopoll(FAR struct lpc43_ethmac_s *priv); + +/* Interrupt handling */ + +static void lpc43_enableint(FAR struct lpc43_ethmac_s *priv, uint32_t ierbit); +static void lpc43_disableint(FAR struct lpc43_ethmac_s *priv, uint32_t ierbit); + +static void lpc43_freesegment(FAR struct lpc43_ethmac_s *priv, + FAR struct eth_rxdesc_s *rxfirst, int segments); +static int lpc43_recvframe(FAR struct lpc43_ethmac_s *priv); +static void lpc43_receive(FAR struct lpc43_ethmac_s *priv); +static void lpc43_freeframe(FAR struct lpc43_ethmac_s *priv); +static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc43_interrupt_work(FAR void *arg); +#endif +static int lpc43_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc43_txtimeout_work(FAR void *arg); +#endif +static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc43_poll_work(FAR void *arg); +#endif +static void lpc43_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int lpc43_ifup(struct net_driver_s *dev); +static int lpc43_ifdown(struct net_driver_s *dev); +static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void lpc43_txavail_work(FAR void *arg); +#endif +static int lpc43_txavail(struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lpc43_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int lpc43_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int lpc43_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif +/* Descriptor Initialization */ + +static void lpc43_txdescinit(FAR struct lpc43_ethmac_s *priv); +static void lpc43_rxdescinit(FAR struct lpc43_ethmac_s *priv); + +/* PHY Initialization */ +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int lpc43_phyintenable(FAR struct lpc43_ethmac_s *priv); +#endif +static int lpc43_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value); +static int lpc43_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value); +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int lpc43_dm9161(FAR struct lpc43_ethmac_s *priv); +#endif +static int lpc43_phyinit(FAR struct lpc43_ethmac_s *priv); + +/* MAC/DMA Initialization */ + +#ifdef CONFIG_LPC43_MII +static inline void lpc43_selectmii(void); +#endif +#ifdef CONFIG_LPC43_RMII +static inline void lpc43_selectrmii(void); +#endif +static inline void lpc43_ethgpioconfig(FAR struct lpc43_ethmac_s *priv); +static void lpc43_ethreset(FAR struct lpc43_ethmac_s *priv); +static int lpc43_macconfig(FAR struct lpc43_ethmac_s *priv); +static void lpc43_macaddress(FAR struct lpc43_ethmac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void lpc43_ipv6multicast(FAR struct lpc43_ethmac_s *priv); +#endif +static int lpc43_macenable(FAR struct lpc43_ethmac_s *priv); +static int lpc43_ethconfig(FAR struct lpc43_ethmac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lpc43_getreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * addr - The register address to read + * + * Returned Value: + * The value read from the register + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc43_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc43_putreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * val - The value to write to the register + * addr - The register address to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void lpc43_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc43_checksetup + * + * Description: + * Show the state of critical configuration registers. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void lpc43_checksetup(void) +{ +} +#endif + +/**************************************************************************** + * Function: lpc43_initbuffer + * + * Description: + * Initialize the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called during early driver initialization before Ethernet interrupts + * are enabled. + * + ****************************************************************************/ + +static void lpc43_initbuffer(FAR struct lpc43_ethmac_s *priv) +{ + uint8_t *buffer; + int i; + + /* Initialize the head of the free buffer list */ + + sq_init(&priv->freeb); + + /* Add all of the pre-allocated buffers to the free buffer list */ + + for (i = 0, buffer = priv->alloc; + i < LPC43_ETH_NFREEBUFFERS; + i++, buffer += CONFIG_LPC43_ETH_BUFSIZE) + { + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); + } +} + +/**************************************************************************** + * Function: lpc43_allocbuffer + * + * Description: + * Allocate one buffer from the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * Pointer to the allocated buffer on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline uint8_t *lpc43_allocbuffer(FAR struct lpc43_ethmac_s *priv) +{ + /* Allocate a buffer by returning the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->freeb); +} + +/**************************************************************************** + * Function: lpc43_freebuffer + * + * Description: + * Return a buffer to the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * buffer - A pointer to the buffer to be freed + * + * Returned Value: + * None + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline void lpc43_freebuffer(FAR struct lpc43_ethmac_s *priv, uint8_t *buffer) +{ + /* Free the buffer by adding it to to the end of the free buffer list */ + + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); +} + +/**************************************************************************** + * Function: lpc43_isfreebuffer + * + * Description: + * Return TRUE if the free buffer list is not empty. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * True if there are one or more buffers in the free buffer list; + * false if the free buffer list is empty + * + * Assumptions: + * None. + * + ****************************************************************************/ + +static inline bool lpc43_isfreebuffer(FAR struct lpc43_ethmac_s *priv) +{ + /* Return TRUE if the free buffer list is not empty */ + + return !sq_empty(&priv->freeb); +} + +/**************************************************************************** + * Function: lpc43_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int lpc43_transmit(FAR struct lpc43_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + struct eth_txdesc_s *txfirst; + + /* The internal (optimal) uIP buffer size may be configured to be larger + * than the Ethernet buffer size. + */ + +#if OPTIMAL_ETH_BUFSIZE > CONFIG_LPC43_ETH_BUFSIZE + uint8_t *buffer; + int bufcount; + int lastsize; + int i; +#endif + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + txdesc = priv->txhead; + txfirst = txdesc; + + nllvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n", + priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0); + + DEBUGASSERT(txdesc && (txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Is the size to be sent greater than the size of the Ethernet buffer? */ + + DEBUGASSERT(priv->dev.d_len > 0 && priv->dev.d_buf != NULL); + +#if OPTIMAL_ETH_BUFSIZE > CONFIG_LPC43_ETH_BUFSIZE + if (priv->dev.d_len > CONFIG_LPC43_ETH_BUFSIZE) + { + /* Yes... how many buffers will be need to send the packet? */ + + bufcount = (priv->dev.d_len + (CONFIG_LPC43_ETH_BUFSIZE-1)) / CONFIG_LPC43_ETH_BUFSIZE; + lastsize = priv->dev.d_len - (bufcount - 1) * CONFIG_LPC43_ETH_BUFSIZE; + + nllvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize); + + /* Set the first segment bit in the first TX descriptor */ + + txdesc->tdes0 |= ETH_TDES0_FS; + + /* Set up all but the last TX descriptor */ + + buffer = priv->dev.d_buf; + + for (i = 0; i < bufcount; i++) + { + /* This could be a normal event but the design does not handle it */ + + DEBUGASSERT((txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)buffer; + + /* Set the buffer size in all TX descriptors */ + + if (i == (bufcount-1)) + { + /* This is the last segment. Set the last segment bit in the + * last TX descriptor and ask for an interrupt when this + * segment transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_LS | ETH_TDES0_IC); + + /* This segement is, most likely, of fractional buffersize */ + + txdesc->tdes1 = lastsize; + buffer += lastsize; + } + else + { + /* This is not the last segment. We don't want an interrupt + * when this segment transfer completes. + */ + + txdesc->tdes0 &= ~ETH_TDES0_IC; + + /* The size of the transfer is the whole buffer */ + + txdesc->tdes1 = CONFIG_LPC43_ETH_BUFSIZE; + buffer += CONFIG_LPC43_ETH_BUFSIZE; + } + + /* Give the descriptor to DMA */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + } + else +#endif + { + /* The single descriptor is both the first and last segment. And we do + * want an interrupt when the transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_FS | ETH_TDES0_LS | ETH_TDES0_IC); + + /* Set frame size */ + + DEBUGASSERT(priv->dev.d_len <= CONFIG_NET_ETH_MTU); + txdesc->tdes1 = priv->dev.d_len; + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)priv->dev.d_buf; + + /* Set OWN bit of the TX descriptor tdes0. This gives the buffer to + * Ethernet DMA + */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + + /* Point to the next available TX descriptor */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + + /* Remember where we left off in the TX descriptor chain */ + + priv->txhead = txdesc; + + /* Detach the buffer from priv->dev structure. That buffer is now + * "in-flight". + */ + + priv->dev.d_buf = NULL; + priv->dev.d_len = 0; + + /* If there is no other TX buffer, in flight, then remember the location + * of the TX descriptor. This is the location to check for TX done events. + */ + + if (!priv->txtail) + { + DEBUGASSERT(priv->inflight == 0); + priv->txtail = txfirst; + } + + /* Increment the number of TX transfer in-flight */ + + priv->inflight++; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* If all TX descriptors are in-flight, then we have to disable receive interrupts + * too. This is because receive events can trigger more un-stoppable transmit + * events. + */ + + if (priv->inflight >= CONFIG_LPC43_ETH_NTXDESC) + { + lpc43_disableint(priv, ETH_DMAINT_RI); + } + + /* Check if the TX Buffer unavailable flag is set */ + + if ((lpc43_getreg(LPC43_ETH_DMASTAT) & ETH_DMAINT_TU) != 0) + { + /* Clear TX Buffer unavailable flag */ + + lpc43_putreg(ETH_DMAINT_TU, LPC43_ETH_DMASTAT); + + /* Resume DMA transmission */ + + lpc43_putreg(0, LPC43_ETH_DMATXPD); + } + + /* Enable TX interrupts */ + + lpc43_enableint(priv, ETH_DMAINT_TI); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, LPC43_TXTIMEOUT, lpc43_txtimeout_expiry, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: lpc43_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int lpc43_txpoll(struct net_driver_s *dev) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private; + + DEBUGASSERT(priv->dev.d_buf != NULL); + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + lpc43_transmit(priv); + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the TX poll if we are unable to accept another packet for + * transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because lpc43_freeframe() has not yet run. If lpc43_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_LPC43_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) != 0 || + priv->txhead->tdes2 != 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + + /* We have the descriptor, we can continue the poll. Allocate a new + * buffer for the poll. + */ + + dev->d_buf = lpc43_allocbuffer(priv); + + /* We can't continue the poll if we have no buffers */ + + if (dev->d_buf == NULL) + { + /* Terminate the poll. */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: lpc43_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (lpc43_txdone), + * 2. When new TX data is available (lpc43_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (lpc43_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_dopoll(FAR struct lpc43_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or + * CPU. We cannot perform the TX poll if we are unable to accept + * another packet for transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because lpc43_freeframe() has not yet run. If lpc43_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_LPC43_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then poll for new XMIT data. + * Allocate a buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = lpc43_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + (void)devif_poll(dev, lpc43_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + lpc43_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: lpc43_enableint + * + * Description: + * Enable a "normal" interrupt + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_enableint(FAR struct lpc43_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Enable the specified "normal" interrupt */ + + regval = lpc43_getreg(LPC43_ETH_DMAINTEN); + regval |= (ETH_DMAINT_NIS | ierbit); + lpc43_putreg(regval, LPC43_ETH_DMAINTEN); +} + +/**************************************************************************** + * Function: lpc43_disableint + * + * Description: + * Disable a normal interrupt. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_disableint(FAR struct lpc43_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Disable the "normal" interrupt */ + + regval = lpc43_getreg(LPC43_ETH_DMAINTEN); + regval &= ~ierbit; + + /* Are all "normal" interrupts now disabled? */ + + if ((regval & ETH_DMAINT_NORMAL) == 0) + { + /* Yes.. disable normal interrupts */ + + regval &= ~ETH_DMAINT_NIS; + } + + lpc43_putreg(regval, LPC43_ETH_DMAINTEN); +} + +/**************************************************************************** + * Function: lpc43_freesegment + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors to the received frame. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_freesegment(FAR struct lpc43_ethmac_s *priv, + FAR struct eth_rxdesc_s *rxfirst, int segments) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + nllvdbg("rxfirst: %p segments: %d\n", rxfirst, segments); + + /* Set OWN bit in RX descriptors. This gives the buffers back to DMA */ + + rxdesc = rxfirst; + for (i = 0; i < segments; i++) + { + rxdesc->rdes0 = ETH_RDES0_OWN; + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + } + + /* Reset the segment management logic */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Check if the RX Buffer unavailable flag is set */ + + if ((lpc43_getreg(LPC43_ETH_DMASTAT) & ETH_DMAINT_RU) != 0) + { + /* Clear RBUS Ethernet DMA flag */ + + lpc43_putreg(ETH_DMAINT_RU, LPC43_ETH_DMASTAT); + + /* Resume DMA reception */ + + lpc43_putreg(0, LPC43_ETH_DMARXPD); + } +} + +/**************************************************************************** + * Function: lpc43_recvframe + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors of the received frame. + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static int lpc43_recvframe(FAR struct lpc43_ethmac_s *priv) +{ + struct eth_rxdesc_s *rxdesc; + struct eth_rxdesc_s *rxcurr; + uint8_t *buffer; + int i; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if there are free buffers. We cannot receive new frames in this + * design unless there is at least one free buffer. + */ + + if (!lpc43_isfreebuffer(priv)) + { + nlldbg("No free buffers\n"); + return -ENOMEM; + } + + /* Scan descriptors owned by the CPU. Scan until: + * + * 1) We find a descriptor still owned by the DMA, + * 2) We have examined all of the RX descriptors, or + * 3) All of the TX descriptors are in flight. + * + * This last case is obscure. It is due to that fact that each packet + * that we receive can generate an unstoppable transmission. So we have + * to stop receiving when we can not longer transmit. In this case, the + * transmit logic should also have disabled further RX interrupts. + */ + + rxdesc = priv->rxhead; + for (i = 0; + (rxdesc->rdes0 & ETH_RDES0_OWN) == 0 && + i < CONFIG_LPC43_ETH_NRXDESC && + priv->inflight < CONFIG_LPC43_ETH_NTXDESC; + i++) + { + /* Check if this is the first segment in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_FS) != 0 && + (rxdesc->rdes0 & ETH_RDES0_LS) == 0) + { + priv->rxcurr = rxdesc; + priv->segments = 1; + } + + /* Check if this is an intermediate segment in the frame */ + + else if (((rxdesc->rdes0 & ETH_RDES0_LS) == 0) && + ((rxdesc->rdes0 & ETH_RDES0_FS) == 0)) + { + priv->segments++; + } + + /* Otherwise, it is the last segment in the frame */ + + else + { + priv->segments++; + + /* Check if the there is only one segment in the frame */ + + if (priv->segments == 1) + { + rxcurr = rxdesc; + } + else + { + rxcurr = priv->rxcurr; + } + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if any errors are reported in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0) + { + struct net_driver_s *dev = &priv->dev; + + /* Get the Frame Length of the received packet: subtract 4 + * bytes of the CRC + */ + + dev->d_len = ((rxdesc->rdes0 & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_SHIFT) - 4; + + /* Get a buffer from the free list. We don't even check if + * this is successful because we already assure the free + * list is not empty above. + */ + + buffer = lpc43_allocbuffer(priv); + + /* Take the buffer from the RX descriptor of the first free + * segment, put it into the uIP device structure, then replace + * the buffer in the RX descriptor with the newly allocated + * buffer. + */ + + DEBUGASSERT(dev->d_buf == NULL); + dev->d_buf = (uint8_t *)rxcurr->rdes2; + rxcurr->rdes2 = (uint32_t)buffer; + + /* Return success, remembering where we should re-start scanning + * and resetting the segment scanning logic + */ + + priv->rxhead = (struct eth_rxdesc_s *)rxdesc->rdes3; + lpc43_freesegment(priv, rxcurr, priv->segments); + + nllvdbg("rxhead: %p d_buf: %p d_len: %d\n", + priv->rxhead, dev->d_buf, dev->d_len); + + return OK; + } + else + { + /* Drop the frame that contains the errors, reset the segment + * scanning logic, and continue scanning with the next frame. + */ + + nlldbg("DROPPED: RX descriptor errors: %08x\n", rxdesc->rdes0); + lpc43_freesegment(priv, rxcurr, priv->segments); + } + } + + /* Try the next descriptor */ + + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + } + + /* We get here after all of the descriptors have been scanned or when rxdesc points + * to the first descriptor owned by the DMA. Remember where we left off. + */ + + priv->rxhead = rxdesc; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + return -EAGAIN; +} + +/**************************************************************************** + * Function: lpc43_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_receive(FAR struct lpc43_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while lpc43_recvframe() successfully retrieves valid + * Ethernet frames. + */ + + while (lpc43_recvframe(priv) == OK) + { +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + /* Free dropped packet buffer */ + + if (dev->d_buf) + { + lpc43_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + lpc43_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + lpc43_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + lpc43_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + + /* We are finished with the RX buffer. NOTE: If the buffer is + * re-used for transmission, the dev->d_buf field will have been + * nullified. + */ + + if (dev->d_buf) + { + /* Free the receive packet buffer */ + + lpc43_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + } +} + +/**************************************************************************** + * Function: lpc43_freeframe + * + * Description: + * Scans the TX descriptors and frees the buffers of completed TX transfers. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void lpc43_freeframe(FAR struct lpc43_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + int i; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* Scan for "in-flight" descriptors owned by the CPU */ + + txdesc = priv->txtail; + if (txdesc) + { + DEBUGASSERT(priv->inflight > 0); + + for (i = 0; (txdesc->tdes0 & ETH_TDES0_OWN) == 0; i++) + { + /* There should be a buffer assigned to all in-flight + * TX descriptors. + */ + + nllvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n", + txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3); + + DEBUGASSERT(txdesc->tdes2 != 0); + + /* Check if this is the first segment of a TX frame. */ + + if ((txdesc->tdes0 & ETH_TDES0_FS) != 0) + { + /* Yes.. Free the buffer */ + + lpc43_freebuffer(priv, (uint8_t *)txdesc->tdes2); + } + + /* In any event, make sure that TDES2 is nullified. */ + + txdesc->tdes2 = 0; + + /* Check if this is the last segment of a TX frame */ + + if ((txdesc->tdes0 & ETH_TDES0_LS) != 0) + { + /* Yes.. Decrement the number of frames "in-flight". */ + + priv->inflight--; + + /* If all of the TX descriptors were in-flight, then RX interrupts + * may have been disabled... we can re-enable them now. + */ + + lpc43_enableint(priv, ETH_DMAINT_RI); + + /* If there are no more frames in-flight, then bail. */ + + if (priv->inflight <= 0) + { + priv->txtail = NULL; + priv->inflight = 0; + return; + } + } + + /* Try the next descriptor in the TX chain */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + + /* We get here if (1) there are still frames "in-flight". Remember + * where we left off. + */ + + priv->txtail = txdesc; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + } +} + +/**************************************************************************** + * Function: lpc43_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv) +{ + DEBUGASSERT(priv->txtail != NULL); + + /* Scan the TX descriptor change, returning buffers to free list */ + + lpc43_freeframe(priv); + + /* If no further xmits are pending, then cancel the TX timeout */ + + if (priv->inflight <= 0) + { + /* Cancel the TX timeout */ + + wd_cancel(priv->txtimeout); + + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, priv); + + /* And disable further TX interrupts. */ + + lpc43_disableint(priv, ETH_DMAINT_TI); + } + + /* Then poll uIP for new XMIT data */ + + lpc43_dopoll(priv); +} + +/**************************************************************************** + * Function: lpc43_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv) +{ + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = lpc43_getreg(LPC43_ETH_DMASTAT); + + /* Mask only enabled interrupts. This depends on the fact that the interrupt + * related bits (0-16) correspond in these two registers. + */ + + dmasr &= lpc43_getreg(LPC43_ETH_DMAINTEN); + + /* Check if there are pending "normal" interrupts */ + + if ((dmasr & ETH_DMAINT_NIS) != 0) + { + /* Yes.. Check if we received an incoming packet, if so, call + * lpc43_receive() + */ + + if ((dmasr & ETH_DMAINT_RI) != 0) + { + /* Clear the pending receive interrupt */ + + lpc43_putreg(ETH_DMAINT_RI, LPC43_ETH_DMASTAT); + + /* Handle the received package */ + + lpc43_receive(priv); + } + + /* Check if a packet transmission just completed. If so, call + * lpc43_txdone(). This may disable further TX interrupts if there + * are no pending tansmissions. + */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* Clear the pending receive interrupt */ + + lpc43_putreg(ETH_DMAINT_TI, LPC43_ETH_DMASTAT); + + /* Check if there are pending transmissions */ + + lpc43_txdone(priv); + } + + /* Clear the pending normal summary interrupt */ + + lpc43_putreg(ETH_DMAINT_NIS, LPC43_ETH_DMASTAT); + } + + /* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */ + +#ifdef CONFIG_DEBUG_NET + + /* Check if there are pending "abnormal" interrupts */ + + if ((dmasr & ETH_DMAINT_AIS) != 0) + { + /* Just let the user know what happened */ + + nlldbg("Abnormal event(s): %08x\n", dmasr); + + /* Clear all pending abnormal events */ + + lpc43_putreg(ETH_DMAINT_ABNORMAL, LPC43_ETH_DMASTAT); + + /* Clear the pending abnormal summary interrupt */ + + lpc43_putreg(ETH_DMAINT_AIS, LPC43_ETH_DMASTAT); + } +#endif +} + +/**************************************************************************** + * Function: lpc43_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc43_interrupt_work(FAR void *arg) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + lpc43_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts at the NVIC */ + + up_enable_irq(LPC43M4_IRQ_ETHERNET); +} +#endif + +/**************************************************************************** + * Function: lpc43_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_interrupt(int irq, FAR void *context) +{ + FAR struct lpc43_ethmac_s *priv = &g_lpc43ethmac; + +#ifdef CONFIG_NET_NOINTS + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = lpc43_getreg(LPC43_ETH_DMASTAT); + if (dmasr != 0) + { + /* Disable further Ethernet interrupts. Because Ethernet interrupts + * are also disabled if the TX timeout event occurs, there can be no + * race condition here. + */ + + up_disable_irq(LPC43M4_IRQ_ETHERNET); + + /* Check if a packet transmission just completed. */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, lpc43_interrupt_work, priv, 0); + } + +#else + /* Process the interrupt now */ + + lpc43_interrupt_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: lpc43_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv) +{ + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + lpc43_ifdown(&priv->dev); + lpc43_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + lpc43_dopoll(priv); +} + +/**************************************************************************** + * Function: lpc43_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc43_txtimeout_work(FAR void *arg) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + lpc43_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: lpc43_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + + nlldbg("Timeout!\n"); + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + * + * Interrupts will be re-enabled when lpc43_ifup() is called. + */ + + up_disable_irq(LPC43M4_IRQ_ETHERNET); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, lpc43_txtimeout_work, priv, 0); + +#else + /* Process the timeout now */ + + lpc43_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: lpc43_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the timer poll if we are unable to accept another packet + * for transmission. Hmmm.. might be bug here. Does this mean if there is + * a transmit in progress, we will miss TCP time state updates? + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because lpc43_freeframe() has not yet run. If lpc43_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_LPC43_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then perform the timer poll. Allocate a + * buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = lpc43_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + /* Update TCP timing states and poll for new XMIT data. + */ + + (void)devif_timer(dev, lpc43_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + lpc43_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: lpc43_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc43_poll_work(FAR void *arg) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + lpc43_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: lpc43_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc43_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, lpc43_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, + (uint32_t)priv); + } + +#else + /* Process the interrupt now */ + + lpc43_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: lpc43_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_ifup(struct net_driver_s *dev) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the Ethernet interface for DMA operation. */ + + ret = lpc43_ethconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, + (uint32_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->ifup = true; + up_enable_irq(LPC43M4_IRQ_ETHERNET); + + lpc43_checksetup(); + return OK; +} + +/**************************************************************************** + * Function: lpc43_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_ifdown(struct net_driver_s *dev) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private; + irqstate_t flags; + + ndbg("Taking the network down\n"); + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(LPC43M4_IRQ_ETHERNET); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the lpc43_ifup() always + * successfully brings the interface back up. + */ + + lpc43_ethreset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: lpc43_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * priv - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv) +{ + nvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll for new XMIT data */ + + lpc43_dopoll(priv); + } +} + +/**************************************************************************** + * Function: lpc43_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void lpc43_txavail_work(FAR void *arg) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + lpc43_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: lpc43_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int lpc43_txavail(struct net_driver_s *dev) +{ + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, lpc43_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + lpc43_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Function: lpc43_calcethcrc + * + * Description: + * Function to calculate the CRC used by LPC43 to check an Ethernet frame + * + * Parameters: + * data - the data to be checked + * length - length of the data + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t lpc43_calcethcrc(const uint8_t *data, size_t length) +{ + uint32_t crc = 0xffffffff; + size_t i; + int j; + + for (i = 0; i < length; i++) + { + for (j = 0; j < 8; j++) + { + if (((crc >> 31) ^ (data[i] >> j)) & 0x01) + { + /* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ + crc = (crc << 1) ^ 0x04c11db7; + } + else + { + crc = crc << 1; + } + } + } + + return ~crc; +} +#endif + +/**************************************************************************** + * Function: lpc43_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lpc43_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Add the MAC address to the hardware multicast hash table */ + + crc = lpc43_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = LPC43_ETH_MACHTHI; + hashindex -= 32; + } + else + { + registeraddress = LPC43_ETH_MACHTLO; + } + + temp = lpc43_getreg(registeraddress); + temp |= 1 << hashindex; + lpc43_putreg(temp, registeraddress); + + temp = lpc43_getreg(LPC43_ETH_MACFFLT); + temp |= (ETH_MACFFLT_HM | ETH_MACFFLT_HPF); + lpc43_putreg(temp, LPC43_ETH_MACFFLT); + + return OK; +} +#endif + +/**************************************************************************** + * Function: lpc43_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int lpc43_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Remove the MAC address to the hardware multicast hash table */ + + crc = lpc43_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = LPC43_ETH_MACHTHI; + hashindex -= 32; + } + else + { + registeraddress = LPC43_ETH_MACHTLO; + } + + temp = lpc43_getreg(registeraddress); + temp &= ~(1 << hashindex); + lpc43_putreg(temp, registeraddress); + + /* If there is no address registered any more, delete multicast filtering */ + + if (lpc43_getreg(LPC43_ETH_MACHTHI) == 0 && + lpc43_getreg(LPC43_ETH_MACHTLO) == 0) + { + temp = lpc43_getreg(LPC43_ETH_MACFFLT); + temp &= ~(ETH_MACFFLT_HM | ETH_MACFFLT_HPF); + lpc43_putreg(temp, LPC43_ETH_MACFFLT); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: lpc43_txdescinit + * + * Description: + * Initializes the DMA TX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc43_txdescinit(FAR struct lpc43_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + int i; + + /* priv->txhead will point to the first, available TX descriptor in the chain. + * Set the priv->txhead pointer to the first descriptor in the table. + */ + + priv->txhead = priv->txtable; + + /* priv->txtail will point to the first segment of the oldest pending + * "in-flight" TX transfer. NULL means that there are no active TX + * transfers. + */ + + priv->txtail = NULL; + priv->inflight = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_LPC43_ETH_NTXDESC; i++) + { + txdesc = &priv->txtable[i]; + + /* Set Second Address Chained bit */ + + txdesc->tdes0 = ETH_TDES0_TCH; + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the checksum insertion for the TX frames */ + + txdesc->tdes0 |= ETH_TDES0_CIC_ALL; +#endif + + /* Clear Buffer1 address pointer (buffers will be assigned as they + * are used) + */ + + txdesc->tdes2 = 0; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_LPC43_ETH_NTXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + txdesc->tdes3 = (uint32_t)&priv->txtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + txdesc->tdes3 = (uint32_t)priv->txtable; + } + } + + /* Set Transmit Desciptor List Address Register */ + + lpc43_putreg((uint32_t)priv->txtable, LPC43_ETH_DMATXDLA); +} + +/**************************************************************************** + * Function: lpc43_rxdescinit + * + * Description: + * Initializes the DMA RX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc43_rxdescinit(FAR struct lpc43_ethmac_s *priv) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + /* priv->rxhead will point to the first, RX descriptor in the chain. + * This will be where we receive the first incomplete frame. + */ + + priv->rxhead = priv->rxtable; + + /* If we accumulate the frame in segments, priv->rxcurr points to the + * RX descriptor of the first segment in the current TX frame. + */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_LPC43_ETH_NRXDESC; i++) + { + rxdesc = &priv->rxtable[i]; + + /* Set Own bit of the RX descriptor rdes0 */ + + rxdesc->rdes0 = ETH_RDES0_OWN; + + /* Set Buffer1 size and Second Address Chained bit and enabled DMA + * RX desc receive interrupt + */ + + rxdesc->rdes1 = ETH_RDES1_RCH | (uint32_t)CONFIG_LPC43_ETH_BUFSIZE; + + /* Set Buffer1 address pointer */ + + rxdesc->rdes2 = (uint32_t)&priv->rxbuffer[i*CONFIG_LPC43_ETH_BUFSIZE]; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_LPC43_ETH_NRXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + rxdesc->rdes3 = (uint32_t)&priv->rxtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + rxdesc->rdes3 = (uint32_t)priv->rxtable; + } + } + + /* Set Receive Descriptor List Address Register */ + + lpc43_putreg((uint32_t)priv->rxtable, LPC43_ETH_DMARXDLA); +} + +/**************************************************************************** + * Function: lpc43_ioctl + * + * Description: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int lpc43_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ +#ifdef CONFIG_ARCH_PHY_INTERRUPT + FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private; +#endif + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = lpc43_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = CONFIG_LPC43_PHYADDR; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = lpc43_phyread(req->phy_id, req->reg_num, &req->val_out); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = lpc43_phywrite(req->phy_id, req->reg_num, req->val_in); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: lpc43_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like + * this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int lpc43_phyintenable(struct lpc43_ethmac_s *priv) +{ +#warning Missing logic + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Function: lpc43_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = lpc43_getreg(LPC43_ETH_MACMIIA); + regval &= ETH_MACMIIA_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the buy bit. + * the ETH_MACMIIA_WR is clear, indicating a read operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIA_PA_SHIFT) & ETH_MACMIIA_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIA_MR_SHIFT) & ETH_MACMIIA_MR_MASK); + regval |= ETH_MACMIIA_GB; + + lpc43_putreg(regval, LPC43_ETH_MACMIIA); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_READ_TIMEOUT; timeout++) + { + if ((lpc43_getreg(LPC43_ETH_MACMIIA) & ETH_MACMIIA_GB) == 0) + { + *value = (uint16_t)lpc43_getreg(LPC43_ETH_MACMIID); + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x\n", + phydevaddr, phyregaddr); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: lpc43_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The 16-bit value to write to the PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = lpc43_getreg(LPC43_ETH_MACMIIA); + regval &= ETH_MACMIIA_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the busy bit. + * the ETH_MACMIIA_WR is set, indicating a write operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIA_PA_SHIFT) & ETH_MACMIIA_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIA_MR_SHIFT) & ETH_MACMIIA_MR_MASK); + regval |= (ETH_MACMIIA_GB | ETH_MACMIIA_WR); + + /* Write the value into the MACIIDR register before setting the new MACMIIAR + * register value. + */ + + lpc43_putreg(value, LPC43_ETH_MACMIID); + lpc43_putreg(regval, LPC43_ETH_MACMIIA); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_WRITE_TIMEOUT; timeout++) + { + if ((lpc43_getreg(LPC43_ETH_MACMIIA) & ETH_MACMIIA_GB) == 0) + { + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x value: %04x\n", + phydevaddr, phyregaddr, value); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: lpc43_dm9161 + * + * Description: + * Special workaround for the Davicom DM9161 PHY is required. On power, + * up, the PHY is not usually configured correctly but will work after + * a powered-up reset. This is really a workaround for some more + * fundamental issue with the PHY clocking initialization, but the + * root cause has not been studied (nor will it be with this workaround). + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int lpc43_dm9161(FAR struct lpc43_ethmac_s *priv) +{ + uint16_t phyval; + int ret; + + /* Read the PHYID1 register; A failure to read the PHY ID is one + * indication that check if the DM9161 PHY CHIP is not ready. + */ + + ret = lpc43_phyread(CONFIG_LPC43_PHYADDR, MII_PHYID1, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY ID1: %d\n", ret); + return ret; + } + + /* If we failed to read the PHY ID1 register, the reset the MCU to recover */ + + else if (phyval == 0xffff) + { + up_systemreset(); + } + + nvdbg("PHY ID1: 0x%04X\n", phyval); + + /* Now check the "DAVICOM Specified Configuration Register (DSCR)", Register 16 */ + + ret = lpc43_phyread(CONFIG_LPC43_PHYADDR, 16, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY Register 0x10: %d\n", ret); + return ret; + } + + /* Bit 8 of the DSCR register is zero, then the DM9161 has not selected RMII. + * If RMII is not selected, then reset the MCU to recover. + */ + + else if ((phyval & (1 << 8)) == 0) + { + up_systemreset(); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: lpc43_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_phyinit(FAR struct lpc43_ethmac_s *priv) +{ + volatile uint32_t timeout; + uint32_t regval; + uint16_t phyval; + int ret; + + /* Assume 10MBps and half duplex */ + + priv->mbps100 = 0; + priv->fduplex = 0; + + /* Setup up PHY clocking by setting the SR field in the MACMIIAR register */ + + regval = lpc43_getreg(LPC43_ETH_MACMIIA); + regval &= ~ETH_MACMIIA_CR_MASK; + regval |= ETH_MACMIIA_CR; + lpc43_putreg(regval, LPC43_ETH_MACMIIA); + + /* Put the PHY in reset mode */ + + ret = lpc43_phywrite(CONFIG_LPC43_PHYADDR, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + ndbg("Failed to reset the PHY: %d\n", ret); + return ret; + } + + up_mdelay(PHY_RESET_DELAY); + +#ifdef CONFIG_LPC43_PHYINIT + /* Perform any necessary, board-specific PHY initialization */ + + ret = lpc43_phy_boardinitialize(0); + if (ret < 0) + { + ndbg("Failed to initialize the PHY: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_ETH0_PHY_DM9161 + /* Special workaround for the Davicom DM9161 PHY is required. */ + + ret = lpc43_dm9161(priv); + if (ret < 0) + { + return ret; + } +#endif + + /* Perform auto-negotion if so configured */ + +#ifdef CONFIG_LPC43_AUTONEG + /* Wait for link status */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = lpc43_phyread(CONFIG_LPC43_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_LINKSTATUS) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for link status: %04x\n", phyval); + return -ETIMEDOUT; + } + + /* Enable auto-negotiation */ + + ret = lpc43_phywrite(CONFIG_LPC43_PHYADDR, MII_MCR, MII_MCR_ANENABLE); + if (ret < 0) + { + ndbg("Failed to enable auto-negotiation: %d\n", ret); + return ret; + } + + /* Wait until auto-negotiation completes */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = lpc43_phyread(CONFIG_LPC43_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_ANEGCOMPLETE) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for auto-negotiation\n"); + return -ETIMEDOUT; + } + + /* Read the result of the auto-negotiation from the PHY-specific register */ + + ret = lpc43_phyread(CONFIG_LPC43_PHYADDR, CONFIG_LPC43_PHYSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read PHY status register\n"); + return ret; + } + + /* Remember the selected speed and duplex modes */ + + nvdbg("PHYSR[%d]: %04x\n", CONFIG_LPC43_PHYSR, phyval); + +#ifdef CONFIG_ETH0_PHY_LAN8720 + if ((phyval & (MII_MSR_100BASETXHALF | MII_MSR_100BASETXFULL)) != 0) + { + priv->mbps100 = 1; + } + + if ((phyval & (MII_MSR_100BASETXFULL | MII_MSR_10BASETXFULL)) != 0) + { + priv->fduplex = 1; + } + +#else + /* Different PHYs present speed and mode information in different ways. IF + * This CONFIG_LPC43_PHYSR_ALTCONFIG is selected, this indicates that the PHY + * represents speed and mode information are combined, for example, with + * separate bits for 10HD, 100HD, 10FD and 100FD. + */ + +#ifdef CONFIG_LPC43_PHYSR_ALTCONFIG + switch (phyval & CONFIG_LPC43_PHYSR_ALTMODE) + { + case CONFIG_LPC43_PHYSR_100FD: + priv->fduplex = 1; + priv->mbps100 = 1; + break; + + case CONFIG_LPC43_PHYSR_100HD: + priv->fduplex = 0; + priv->mbps100 = 1; + break; + + case CONFIG_LPC43_PHYSR_10FD: + priv->fduplex = 1; + priv->mbps100 = 0; + break; + + default: + case CONFIG_LPC43_PHYSR_10HD: + priv->fduplex = 0; + priv->mbps100 = 0; + break; + } + + /* Different PHYs present speed and mode information in different ways. Some + * will present separate information for speed and mode (this is the default). + * Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + * full/half duplex indication. + */ + +#else + if ((phyval & CONFIG_LPC43_PHYSR_MODE) == CONFIG_LPC43_PHYSR_FULLDUPLEX) + { + priv->fduplex = 1; + } + + if ((phyval & CONFIG_LPC43_PHYSR_SPEED) == CONFIG_LPC43_PHYSR_100MBPS) + { + priv->mbps100 = 1; + } +#endif + +#ifdef CONFIG_LPC43_ETHFD + priv->mbps100 = 1; +#endif + +#ifdef CONFIG_LPC43_ETH100MBPS + priv->fduplex = 1; +#endif +#endif + + /* However we got here, commit to the hardware */ + + phyval = 0; + if (priv->mbps100) + { + phyval |= MII_MCR_FULLDPLX; + } + + if (priv->fduplex) + { + phyval |= MII_MCR_SPEED100; + } + + ret = lpc43_phywrite(CONFIG_LPC43_PHYADDR, MII_MCR, phyval); + if (ret < 0) + { + ndbg("Failed to write the PHY MCR: %d\n", ret); + return ret; + } + + up_mdelay(PHY_CONFIG_DELAY); + + /* Remember the selected speed and duplex modes */ + +#ifdef CONFIG_LPC43_ETHFD + priv->fduplex = 1; +#endif +#ifdef CONFIG_LPC43_ETH100MBPS + priv->mbps100 = 1; +#endif +#endif + + ndbg("Duplex: %s Speed: %d MBps\n", + priv->fduplex ? "FULL" : "HALF", + priv->mbps100 ? 100 : 10); + + return OK; +} + +/************************************************************************************ + * Name: lpc43_selectmii + * + * Description: + * Selects the MII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_LPC43_MII +static inline void lpc43_selectmii(void) +{ + uint32_t regval; + + regval = getreg32(LPC43_CREG6); + regval &= ~SYSCFG_PMC_MII_RMII_SEL; + putreg32(regval, LPC43_CREG6); +} +#endif + +/************************************************************************************ + * Name: lpc43_selectrmii + * + * Description: + * Selects the RMII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void lpc43_selectrmii(void) +{ + uint32_t regval; + + regval = getreg32(LPC43_CREG6); + regval |= CREG6_ETHMODE_RMII; + putreg32(regval, LPC43_CREG6); +} + +/**************************************************************************** + * Function: lpc43_ethgpioconfig + * + * Description: + * Configure GPIOs for the Ethernet interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void lpc43_ethgpioconfig(FAR struct lpc43_ethmac_s *priv) +{ + /* Configure GPIO pins to support Ethernet */ + +#if defined(CONFIG_LPC43_MII) || defined(CONFIG_LPC43_RMII) + /* MDC and MDIO are common to both modes */ + + lpc43_pin_config(PINCONF_ENET_MDC); + lpc43_pin_config(PINCONF_ENET_MDIO); + + /* Set up the MII interface */ + +#if defined(CONFIG_LPC43_MII) + /* Select the MII interface */ + + lpc43_selectmii(); + + /* MII interface pins (17): + * + * MII_TX_CLK, MII_TXD[3:0], MII_TX_EN, MII_RX_CLK, MII_RXD[3:0], MII_RX_ER, + * MII_RX_DV, MII_CRS, MII_COL, MDC, MDIO + */ + + lpc43_pin_config(GPIO_ETH_MII_COL); + lpc43_pin_config(GPIO_ETH_MII_CRS); + lpc43_pin_config(GPIO_ETH_MII_RXD0); + lpc43_pin_config(GPIO_ETH_MII_RXD1); + lpc43_pin_config(GPIO_ETH_MII_RXD2); + lpc43_pin_config(GPIO_ETH_MII_RXD3); + lpc43_pin_config(GPIO_ETH_MII_RX_CLK); + lpc43_pin_config(GPIO_ETH_MII_RX_DV); + lpc43_pin_config(GPIO_ETH_MII_RX_ER); + lpc43_pin_config(GPIO_ETH_MII_TXD0); + lpc43_pin_config(GPIO_ETH_MII_TXD1); + lpc43_pin_config(GPIO_ETH_MII_TXD2); + lpc43_pin_config(GPIO_ETH_MII_TXD3); + lpc43_pin_config(GPIO_ETH_MII_TX_CLK); + lpc43_pin_config(GPIO_ETH_MII_TX_EN); + + /* Set up the RMII interface. */ + +#elif defined(CONFIG_LPC43_RMII) + /* Select the RMII interface */ + + lpc43_selectrmii(); + + /* RMII interface pins (7): + * + * RMII_TXD[1:0], RMII_TX_EN, RMII_RXD[1:0], RMII_CRS_DV, MDC, MDIO, + * RMII_REF_CLK + */ + + lpc43_pin_config(PINCONF_ENET_RX_DV); + lpc43_pin_config(PINCONF_ENET_REF_CLK); + lpc43_pin_config(PINCONF_ENET_RXD0); + lpc43_pin_config(PINCONF_ENET_RXD1); + lpc43_pin_config(PINCONF_ENET_TXD0); + lpc43_pin_config(PINCONF_ENET_TXD1); + lpc43_pin_config(PINCONF_ENET_TXEN); + +#ifdef PINCONF_ENET_RESET + lpc43_pin_config(PINCONF_ENET_RESET); + lpc43_gpio_config(GPIO_ENET_RESET); + lpc43_gpio_write(GPIO_ENET_RESET, 0); + up_mdelay(5); + lpc43_gpio_write(GPIO_ENET_RESET, 1); + up_mdelay(5); +#endif +#endif +#endif +} + +/**************************************************************************** + * Function: lpc43_ethreset + * + * Description: + * Reset the Ethernet block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc43_ethreset(FAR struct lpc43_ethmac_s *priv) +{ + uint32_t regval; + + lpc43_putreg(CCU_CLK_CFG_RUN|CCU_CLK_CFG_AUTO|CCU_CLK_CFG_WAKEUP,LPC43_CCU1_M4_ETHERNET_CFG); + + /* Reset the Ethernet */ + + lpc43_putreg(RGU_CTRL0_ETHERNET_RST, LPC43_RGU_CTRL0); + + regval = lpc43_getreg(LPC43_ETH_DMABMODE); + regval |= ETH_DMABMODE_SWR; + lpc43_putreg(regval, LPC43_ETH_DMABMODE); + + /* Wait for software reset to complete. The SR bit is cleared automatically + * after the reset operation has completed in all of the core clock domains. + */ + + while ((lpc43_getreg(LPC43_ETH_DMABMODE) & ETH_DMABMODE_SWR) != 0); +} + +/**************************************************************************** + * Function: lpc43_macconfig + * + * Description: + * Configure the Ethernet MAC for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_macconfig(FAR struct lpc43_ethmac_s *priv) +{ + uint32_t regval; + + /* Set up the MACCR register */ + + regval = lpc43_getreg(LPC43_ETH_MACCR); + regval &= ~MACCR_CLEAR_BITS; + regval |= MACCR_SET_BITS; + + if (priv->fduplex) + { + /* Set the DM bit for full duplex support */ + + regval |= ETH_MACCFG_DM; + } + + if (priv->mbps100) + { + /* Set the FES bit for 100Mbps fast ethernet support */ + + regval |= ETH_MACCFG_FES; + } + + lpc43_putreg(regval, LPC43_ETH_MACCR); + + /* Set up the MACFFR register */ + + regval = lpc43_getreg(LPC43_ETH_MACFFLT); + regval &= ~MACFFR_CLEAR_BITS; + regval |= MACFFR_SET_BITS; + lpc43_putreg(regval, LPC43_ETH_MACFFLT); + + /* Set up the MACHTHR and MACHTLR registers */ + + lpc43_putreg(0, LPC43_ETH_MACHTHI); + lpc43_putreg(0, LPC43_ETH_MACHTLO); + + /* Setup up the MACFCR register */ + + regval = lpc43_getreg(LPC43_ETH_MACFC); + regval &= ~MACFCR_CLEAR_MASK; + regval |= MACFCR_SET_MASK; + lpc43_putreg(regval, LPC43_ETH_MACFC); + + /* Setup up the MACVLANTR register */ + + lpc43_putreg(0, LPC43_ETH_MACVLANT); + + /* DMA Configuration */ + /* Set up the DMAOMR register */ + + regval = lpc43_getreg(LPC43_ETH_DMAOPMODE); + regval &= ~DMAOMR_CLEAR_MASK; + regval |= DMAOMR_SET_MASK; + lpc43_putreg(regval, LPC43_ETH_DMAOPMODE); + + /* Set up the DMABMR register */ + + regval = lpc43_getreg(LPC43_ETH_DMABMODE); + regval &= ~DMABMR_CLEAR_MASK; + regval |= DMABMR_SET_MASK; + lpc43_putreg(regval, LPC43_ETH_DMABMODE); + + return OK; +} + +/**************************************************************************** + * Function: lpc43_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void lpc43_macaddress(FAR struct lpc43_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address high register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[5] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[4]; + lpc43_putreg(regval, LPC43_ETH_MACA0HI); + + /* Set the MAC address low register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[3] << 24) | + ((uint32_t)dev->d_mac.ether_addr_octet[2] << 16) | + ((uint32_t)dev->d_mac.ether_addr_octet[1] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[0]; + lpc43_putreg(regval, LPC43_ETH_MACA0LO); +} + +/**************************************************************************** + * Function: lpc43_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void lpc43_ipv6multicast(FAR struct lpc43_ethmac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)lpc43_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)lpc43_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)lpc43_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: lpc43_macenable + * + * Description: + * Enable normal MAC operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_macenable(FAR struct lpc43_ethmac_s *priv) +{ + uint32_t regval; + + /* Set the MAC address */ + + lpc43_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + lpc43_ipv6multicast(priv); +#endif + + /* Enable transmit state machine of the MAC for transmission on the MII */ + + regval = lpc43_getreg(LPC43_ETH_MACCR); + regval |= ETH_MACCFG_TE; + lpc43_putreg(regval, LPC43_ETH_MACCR); + + /* Flush Transmit FIFO */ + + regval = lpc43_getreg(LPC43_ETH_DMAOPMODE); + regval |= ETH_DMAOPMODE_FTF; + lpc43_putreg(regval, LPC43_ETH_DMAOPMODE); + + /* Enable receive state machine of the MAC for reception from the MII */ + + /* Enables or disables the MAC reception. */ + + regval = lpc43_getreg(LPC43_ETH_MACCR); + regval |= ETH_MACCFG_RE; + lpc43_putreg(regval, LPC43_ETH_MACCR); + + /* Start DMA transmission */ + + regval = lpc43_getreg(LPC43_ETH_DMAOPMODE); + regval |= ETH_DMAOPMODE_ST; + lpc43_putreg(regval, LPC43_ETH_DMAOPMODE); + + /* Start DMA reception */ + + regval = lpc43_getreg(LPC43_ETH_DMAOPMODE); + regval |= ETH_DMAOPMODE_SR; + lpc43_putreg(regval, LPC43_ETH_DMAOPMODE); + + /* Enable Ethernet DMA interrupts. + * + * The LPC43 hardware supports two interrupts: (1) one dedicated to normal + * Ethernet operations and the other, used only for the Ethernet wakeup + * event. The wake-up interrupt is not used by this driver. + * + * The first Ethernet vector is reserved for interrupts generated by the + * MAC and the DMA. The MAC provides PMT and time stamp trigger interrupts, + * neither of which are used by this driver. + */ + + lpc43_putreg(ETH_MACIM_ALLINTS, LPC43_ETH_MACIM); + + /* Ethernet DMA supports two classes of interrupts: Normal interrupt + * summary (NIS) and Abnormal interrupt summary (AIS) with a variety + * individual normal and abnormal interrupting events. Here only + * the normal receive event is enabled (unless DEBUG is enabled). Transmit + * events will only be enabled when a transmit interrupt is expected. + */ + + lpc43_putreg((ETH_DMAINT_RECV_ENABLE | ETH_DMAINT_ERROR_ENABLE), + LPC43_ETH_DMAINTEN); + return OK; +} + +/**************************************************************************** + * Function: lpc43_ethconfig + * + * Description: + * Configure the Ethernet interface for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc43_ethconfig(FAR struct lpc43_ethmac_s *priv) +{ + int ret; + + /* NOTE: The Ethernet clocks were initialized early in the boot-up + * sequence in lpc43_rcc.c. + */ + + /* Reset the Ethernet block */ + + nllvdbg("Reset the Ethernet block\n"); + lpc43_ethreset(priv); + + /* Initialize the PHY */ + + nllvdbg("Initialize the PHY\n"); + ret = lpc43_phyinit(priv); + if (ret < 0) + { + return ret; + } + + /* Perform a software reset by setting the SR bit in the DMABMR register. + * This Resets all MAC subsystem internal registers and logic. After this + * reset all the registers holds their reset values. + */ + + + /* Initialize the MAC and DMA */ + + nllvdbg("Initialize the MAC and DMA\n"); + ret = lpc43_macconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the free buffer list */ + + lpc43_initbuffer(priv); + + /* Initialize TX Descriptors list: Chain Mode */ + + lpc43_txdescinit(priv); + + /* Initialize RX Descriptors list: Chain Mode */ + + lpc43_rxdescinit(priv); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + return lpc43_macenable(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: lpc43_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static inline int lpc43_ethinitialize(void) +{ + struct lpc43_ethmac_s *priv; + + /* Get the interface structure associated with this interface number. */ + + priv = &g_lpc43ethmac; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct lpc43_ethmac_s)); + priv->dev.d_ifup = lpc43_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = lpc43_ifdown; /* I/F down callback */ + priv->dev.d_txavail = lpc43_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = lpc43_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = lpc43_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = lpc43_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)&g_lpc43ethmac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Configure GPIO pins to support Ethernet */ + + lpc43_ethgpioconfig(priv); + + /* Attach the IRQ to the driver */ + + if (irq_attach(LPC43M4_IRQ_ETHERNET, lpc43_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Put the interface in the down state. */ + + lpc43_ifdown(&priv->dev); + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +void up_netinitialize(void) +{ + (void)lpc43_ethinitialize(); +} + +#endif /* CONFIG_NET && CONFIG_LPC43_ETHERNET */ diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.h b/arch/arm/src/lpc43xx/lpc43_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..55888fc7270aa0722ecd2b110038b053fb65d990 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ethernet.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_eth.h + * + * Copyright (C) 2009-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_ETH_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_ETH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#include "chip/lpc43_ethernet.h" + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Function: lpc43_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_LPC43_PHYINIT is defined in the configuration then the board specific + * logic must provide lpc43_phyinitialize(); The LPC43 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_LPC43_PHYINIT +int lpc43_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_ETH_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpdma.c b/arch/arm/src/lpc43xx/lpc43_gpdma.c new file mode 100644 index 0000000000000000000000000000000000000000..991f80a1cfd74590c4d603727c6ef909b4b581ab --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpdma.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_gpdma.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "lpc43_syscon.h" +#include "lpc43_gpdma.h" + +#ifdef CONFIG_LPC43_GPDMA + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Enables debug output from this file (needs CONFIG_DEBUG too) */ + +#undef DMA_DEBUG /* Define to enable debug */ +#undef DMA_VERBOSE /* Define to enable verbose debug */ + +#ifdef DMA_DEBUG +# define dmadbg lldbg +# ifdef DMA_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# undef DMA_VERBOSE +# define dmadbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc43_dmainitilaize(void) +{ +} + +/**************************************************************************** + * Name: lpc43_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +DMA_HANDLE lpc43_dmachannel(void) +{ + return NULL; +} + +/**************************************************************************** + * Name: lpc43_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until lpc43_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc43_dmafree(DMA_HANDLE handle) +{ +} + +/**************************************************************************** + * Name: lpc43_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +int lpc43_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: lpc43_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int lpc43_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: lpc43_dmastop + * + * Description: + * Cancel the DMA. After lpc43_dmastop() is called, the DMA channel is + * reset and lpc43_dmasetup() must be called before lpc43_dmastart() can be + * called again + * + ****************************************************************************/ + +void lpc43_dmastop(DMA_HANDLE handle) +{ +} + +/**************************************************************************** + * Name: lpc43_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc43_dmasample(DMA_HANDLE handle, struct lpc43_dmaregs_s *regs) +{ +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: lpc43_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc43_dmadump(DMA_HANDLE handle, const struct lpc43_dmaregs_s *regs, const char *msg) +{ +} +#endif /* CONFIG_DEBUG_DMA */ + +#endif /* CONFIG_LPC43_GPDMA */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpdma.h b/arch/arm/src/lpc43xx/lpc43_gpdma.h new file mode 100644 index 0000000000000000000000000000000000000000..ecf35f0834f771e5e947a53e3f131099188547d7 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpdma.h @@ -0,0 +1,235 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_gpdma.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LP43_GPDMA_H +#define __ARCH_ARM_SRC_LPC43XX_LP43_GPDMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc43_gpdma.h" + +#ifdef CONFIG_LPC43_GPDMA + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct lpc43_dmaglobalregs_s +{ + /* Global Registers */ + + uint32_t intst; /* DMA Interrupt Status Register */ + uint32_t inttcst; /* DMA Interrupt Terminal Count Request Status Register */ + uint32_t interrst; /* DMA Interrupt Error Status Register */ + uint32_t rawinttcst; /* DMA Raw Interrupt Terminal Count Status Register */ + uint32_t rawinterrst; /* DMA Raw Error Interrupt Status Register */ + uint32_t enbldchns; /* DMA Enabled Channel Register */ + uint32_t softbreq; /* DMA Software Burst Request Register */ + uint32_t softsreq; /* DMA Software Single Request Register */ + uint32_t softlbreq; /* DMA Software Last Burst Request Register */ + uint32_t softlsreq; /* DMA Software Last Single Request Register */ + uint32_t config; /* DMA Configuration Register */ + uint32_t sync; /* DMA Synchronization Register */ +}; + +struct lpc43_dmachanregs_s +{ + /* Channel Registers */ + + uint32_t srcaddr; /* DMA Channel Source Address Register */ + uint32_t destaddr; /* DMA Channel Destination Address Register */ + uint32_t lli; /* DMA Channel Linked List Item Register */ + uint32_t control; /* DMA Channel Control Register */ + uint32_t config; /* DMA Channel Configuration Register */ +}; + +struct lpc43_dmaregs_s +{ + /* Global Registers */ + + struct lpc43_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct lpc43_dmachanregs_s ch; +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc43_dmainitilaize(void); + +/**************************************************************************** + * Name: lpc43_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +DMA_HANDLE lpc43_dmachannel(void); + +/**************************************************************************** + * Name: lpc43_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until lpc43_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc43_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: lpc43_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +int lpc43_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); + +/**************************************************************************** + * Name: lpc43_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int lpc43_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: lpc43_dmastop + * + * Description: + * Cancel the DMA. After lpc43_dmastop() is called, the DMA channel is + * reset and lpc43_dmasetup() must be called before lpc43_dmastart() can be + * called again + * + ****************************************************************************/ + +void lpc43_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: lpc43_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc43_dmasample(DMA_HANDLE handle, struct lpc43_dmaregs_s *regs); +#else +# define lpc43_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: lpc43_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void lpc43_dmadump(DMA_HANDLE handle, const struct lpc43_dmaregs_s *regs, + const char *msg); +#else +# define lpc43_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_GPDMA */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LP43_GPDMA_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpio.c b/arch/arm/src/lpc43xx/lpc43_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..3d5db11b7e49646dad43ba004812e808f0812298 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpio.c @@ -0,0 +1,253 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_gpio.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "lpc43_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_configinput + * + * Description: + * Configure a GPIO pin as an input (or pre-configured the pin for an + * interrupt). + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +static inline void lpc43_configinput(uint16_t gpiocfg, + unsigned int port, unsigned int pin) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Then configure the pin as a normal input by clearing the corresponding + * bit in the GPIO DIR register for the port. + */ + + regaddr = LPC43_GPIO_DIR(port); + regval = getreg32(regaddr); + regval &= ~GPIO_DIR(pin); + putreg32(regval, regaddr); + + /* To be able to read the signal on the GPIO input, the input + * buffer must be enabled in the syscon block for the corresponding pin. + * This should have been done when the pin was configured as a GPIO. + */ +} + +/**************************************************************************** + * Name: lpc43_configoutput + * + * Description: + * Configure a GPIO pin as an output. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +static inline void lpc43_configoutput(uint16_t gpiocfg, + unsigned int port, unsigned int pin) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Then configure the pin as an output by setting the corresponding + * bit in the GPIO DIR register for the port. + */ + + regaddr = LPC43_GPIO_DIR(port); + regval = getreg32(regaddr); + regval |= GPIO_DIR(pin); + putreg32(regval, regaddr); + + /* Set the initial value of the output */ + + lpc43_gpio_write(gpiocfg, GPIO_IS_ONE(gpiocfg)); + + /* To be able to read the signal on the GPIO input, the input + * buffer must be enabled in the syscon block for the corresponding pin. + * This should have been done when the pin was configured as a GPIO. + */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_gpio_config + * + * Description: + * Configure a GPIO based on bit-encoded description of the pin. NOTE: + * The pin *must* have first been configured for GPIO usage with a + * corresponding call to lpc43_pin_config(). + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int lpc43_gpio_config(uint16_t gpiocfg) +{ + unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); + irqstate_t flags; + int ret = OK; + + DEBUGASSERT(port < NUM_GPIO_PORTS && pin < NUM_GPIO_PINS); + + /* Handle the GPIO configuration by the basic mode of the pin */ + + flags = enter_critical_section(); + switch (gpiocfg & GPIO_MODE_MASK) + { + case GPIO_MODE_INPUT: /* GPIO input pin */ + lpc43_configinput(gpiocfg, port, pin); + break; + + case GPIO_MODE_OUTPUT: /* GPIO output pin */ + lpc43_configoutput(gpiocfg, port, pin); + break; + + case GPIO_MODE_PININTR: /* GPIO pin interrupt */ + lpc43_configinput(gpiocfg, port, pin); +#ifdef CONFIG_GPIO_IRQ + ret = lpc43_gpioint_pinconfig(gpiocfg); +#endif + break; + + case GPIO_MODE_GRPINTR: /* GPIO group interrupt */ + lpc43_configinput(gpiocfg, port, pin); +#ifdef CONFIG_GPIO_IRQ + ret = lpc43_gpioint_grpconfig(gpiocfg); +#endif + break; + + default : + sdbg("ERROR: Unrecognized pin mode: %04x\n", gpiocfg); + ret = -EINVAL; + break; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc43_gpio_write + * + * Description: + * Write one or zero to the selected GPIO pin + * + * Returned Value: + * None + * + ****************************************************************************/ + +void lpc43_gpio_write(uint16_t gpiocfg, bool value) +{ + unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); + + DEBUGASSERT(port < NUM_GPIO_PORTS && pin < NUM_GPIO_PINS); + + /* Write the value (0 or 1). To the pin byte register */ + + putreg8((uint8_t)value, LPC43_GPIO_B(port, pin)); +} + +/**************************************************************************** + * Name: lpc43_gpio_read + * + * Description: + * Read one or zero from the selected GPIO pin + * + * Returned Value: + * The boolean state of the input pin + * + ****************************************************************************/ + +bool lpc43_gpio_read(uint16_t gpiocfg) +{ + unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); + + DEBUGASSERT(port < NUM_GPIO_PORTS && pin < NUM_GPIO_PINS); + + /* Get the value of the pin from the pin byte register */ + + return (getreg8(LPC43_GPIO_B(port, pin)) & GPIO_B) != 0; +} + + + diff --git a/arch/arm/src/lpc43xx/lpc43_gpio.h b/arch/arm/src/lpc43xx/lpc43_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..1ee14fac6395d20f41291c07e3bf0c0fa0af1523 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpio.h @@ -0,0 +1,325 @@ +/******************************************************************************************** + * arch/arm/src/lpc43xx/lpc43_gpio.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_GPIO_H +#define __ARCH_ARM_SRC_LPC43XX_GPIO_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include +#include + +/* Include the chip capabilities and GPIO definitions file */ + +#include "chip.h" +#include "chip/lpc43_gpio.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* Max number of GPIO ports and the maximum number of pins per port */ + +#define NUM_GPIO_PORTS 8 +#define NUM_GPIO_PINS 32 +#define NUM_GPIO_NGROUPS 2 + +/* Each configurable pin can be individually configured by software in several modes. The + * following definitions provide the bit encoding that is used to define a pin configuration. + * Note that these pins do not corresponding GPIO ports and pins. + * + * 16-bit Encoding: + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * Normal GPIO: MMV. .... PPPB BBBB + * Normal Interrupt: MMCC CIII PPPB BBBB + * Group Interrupt: MM.N P... PPPB BBBB + */ + +/* GPIO mode: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * MM.. .... .... .... + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: Mode of the GPIO pin */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_MODE_INPUT (0 << GPIO_MODE_SHIFT) /* GPIO input */ +# define GPIO_MODE_OUTPUT (1 << GPIO_MODE_SHIFT) /* GPIO output */ +# define GPIO_MODE_PININTR (2 << GPIO_MODE_SHIFT) /* GPIO pin interrupt */ +# define GPIO_MODE_GRPINTR (3 << GPIO_MODE_SHIFT) /* GPIO group interrupt */ + +#define GPIO_IS_OUTPUT(p) (((p) & GPIO_MODE_MASK) == GPIO_MODE_INPUT) +#define GPIO_IS_INPUT(p) (((p) & GPIO_MODE_MASK) == GPIO_MODE_OUTPUT) +#define GPIO_IS_PININT(p) (((p) & GPIO_MODE_MASK) == GPIO_MODE_PININTR) +#define GPIO_IS_GRPINTR(p) (((p) & GPIO_MODE_MASK) == GPIO_MODE_GRPINTR) + +/* Initial value (for GPIO outputs only) + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ..V. .... .... .... + */ + +#define GPIO_VALUE_ONE (1 << 13) /* Bit 13: 1=High */ +#define GPIO_VALUE_ZERO (0) /* Bit 13: 0=Low */ + +#define GPIO_IS_ONE(p) (((p) & GPIO_VALUE_ONE) != 0) +#define GPIO_IS_ZERO(p) (((p) & GPIO_VALUE_ONE) == 0) + +/* Group Interrupt Group Selection (valid only for GPIO group interrupts): + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ...N .... .... .... + */ + +#define GPIO_GRPINT_GROUPNO (1 << 12) /* Bit 12: 1=Member of group 1 */ +#define GPIO_GRPINT_GROUP0 (0) +#define GPIO_GRPINT_GROUP1 GPIO_GRPINT_GROUPNO + +#define GPIO_IS_GROUP0(p) (((p) & GPIO_GRPINT_GROUPNO) == 0) +#define GPIO_IS_GROUP1(p) (((p) & GPIO_GRPINT_GROUPNO) != 0) + +/* Group Interrupt Polarity (valid only for GPIO group interrupts): + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... P... .... .... + */ + +#define GPIO_POLARITY (1 << 11) /* Bit 11: Group Polarity */ +#define GPIO_POLARITY_HI GPIO_POLARITY +#define GPIO_POLARITY_LOW 0 + +#define GPIO_IS_POLARITY_HI(p) (((p) & GPIO_POLARITY) != 0) +#define GPIO_IS_POLARITY_LOW(p) (((p) & GPIO_POLARITY) == 0) + +/* Pin interrupt number (valid only for GPIO pin interrupts) + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ..CC C... .... .... + */ + +#define GPIO_PININT_SHIFT (10) /* Bits 11-13: Pin interrupt number */ +#define GPIO_PININT_MASK (7 << GPIO_PININT_SHIFT) +# define GPIO_PININT0 (0 << GPIO_PININT_SHIFT) +# define GPIO_PININT1 (1 << GPIO_PININT_SHIFT) +# define GPIO_PININT2 (2 << GPIO_PININT_SHIFT) +# define GPIO_PININT3 (3 << GPIO_PININT_SHIFT) +# define GPIO_PININT4 (4 << GPIO_PININT_SHIFT) +# define GPIO_PININT5 (5 << GPIO_PININT_SHIFT) +# define GPIO_PININT6 (6 << GPIO_PININT_SHIFT) +# define GPIO_PININT7 (7 << GPIO_PININT_SHIFT) + +/* Pin interrupt configuration (valid only for GPIO pin interrupts) + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .III .... .... + */ + +#define _GPIO_INT_LEVEL (1 << 10) /* Bit 10: 1=Level (vs edge) */ +#define _GPIO_INT_HIGH (1 << 9) /* Bit 9: 1=High level or rising edge */ +#define _GPIO_INT_LOW (1 << 8) /* Bit 8: 1=Low level or falling edge */ + +#define GPIO_INT_SHIFT (8) /* Bits 8-10: Interrupt mode */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define GPIO_INT_LEVEL_HI (1 << GPIO_INT_SHIFT) /* 001 Edge=NO LOW=0 HIGH=1 */ +# define GPIO_INT_LEVEL_LOW (2 << GPIO_INT_SHIFT) /* 010 Edge=NO LOW=1 HIGH=0 */ +# define GPIO_INT_EDGE_RISING (5 << GPIO_INT_SHIFT) /* 101 Edge=YES LOW=0 HIGH=1 */ +# define GPIO_INT_EDGE_FALLING (6 << GPIO_INT_SHIFT) /* 110 Edge=YES LOW=1 HIGH=0 */ +# define GPIO_INT_EDGE_BOTH (7 << GPIO_INT_SHIFT) /* 111 Edge=YES LOW=1 HIGH=1 */ + +#define GPIO_IS_ACTIVE_HI(p) (((p) & _GPIO_INT_HIGH) != 0) +#define GPIO_IS_ACTIVE_LOW(p) (((p) & _GPIO_INT_LOW) != 0) +#define GPIO_IS_EDGE(p) (((p) & _GPIO_INT_LEVEL) == 0) +#define GPIO_IS_LEVEL(p) (((p) & _GPIO_INT_LEVEL) != 0) + +/* GPIO Port Number: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bits 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT0 (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT1 (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT2 (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT3 (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT4 (4 << GPIO_PORT_SHIFT) +# define GPIO_PORT5 (5 << GPIO_PORT_SHIFT) +# define GPIO_PORT6 (6 << GPIO_PORT_SHIFT) +# define GPIO_PORT7 (7 << GPIO_PORT_SHIFT) + +/* GPIO Pin Number: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-5: Pin number */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Name: lpc43_gpio_config + * + * Description: + * Configure a GPIO based on bit-encoded description of the pin. NOTE: The pin *must* + * have first been configured for GPIO usage with a corresponding call to lpc43_pin_config. + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ********************************************************************************************/ + +int lpc43_gpio_config(uint16_t gpiocfg); + +/******************************************************************************************** + * Name: lpc43_gpio_write + * + * Description: + * Write one or zero to the selected GPIO pin + * + * Returned Value: + * None + * + ********************************************************************************************/ + +void lpc43_gpio_write(uint16_t gpiocfg, bool value); + +/******************************************************************************************** + * Name: lpc43_gpio_read + * + * Description: + * Read one or zero from the selected GPIO pin + * + * Returned Value: + * The boolean state of the input pin + * + ********************************************************************************************/ + +bool lpc43_gpio_read(uint16_t gpiocfg); + +/******************************************************************************************** + * Function: lpc43_gpio_dump + * + * Description: + * Dump all pin configuration registers associated with the provided base address + * + ********************************************************************************************/ + +#ifdef CONFIG_DEBUG +int lpc43_gpio_dump(uint16_t gpiocfg, const char *msg); +#else +# define lpc43_gpio_dump(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC43XX_GPIO_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpioint.c b/arch/arm/src/lpc43xx/lpc43_gpioint.c new file mode 100644 index 0000000000000000000000000000000000000000..51e010ba33042ae3349628df7f6000fe27cf55fe --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpioint.c @@ -0,0 +1,324 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_gpioint.c + * + * Copyright (C) 2012, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/* GPIO pin interrupts + * + * From all available GPIO pins, up to eight pins can be selected in the + * system control block to serve as external interrupt pins. The external + * interrupt pins are connected to eight individual interrupts in the NVIC + * and are created based on rising or falling edges or on the input level + * on the pin. + * + * GPIO group interrupt + * + * For each port/pin connected to one of the two the GPIO Grouped Interrupt + * blocks (GROUP0 and GROUP1), the GPIO grouped interrupt registers + * determine which pins are enabled to generate interrupts and what the + * active polarities of each of those inputs are. The GPIO grouped + * interrupt registers also select whether the interrupt output will be + * level or edge triggered and whether it will be based on the OR or the + * AND of all of the enabled inputs. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/lpc43_scu.h" +#include "chip/lpc43_gpio.h" +#include "lpc43_gpio.h" +#include "lpc43_gpioint.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_gpioint_grpinitialize + * + * Description: + * Initialize the properties of a GPIO group. The properties of the group + * should be configured before any pins are added to the group by + * lpc32_gpioint_grpconfig(). As side effects, this call also removes + * all pins from the group and disables the group interrupt. On return, + * this is a properly configured, empty GPIO interrupt group. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_grpinitialize(int group, bool anded, bool level) +{ + irqstate_t flags; + uintptr_t grpbase; + uint32_t regval; + int i; + + DEBUGASSERT(group >= 0 && group < NUM_GPIO_NGROUPS); + + /* Select the group register base address and disable the group interrupt */ + + flags = enter_critical_section(); + if (group == 0) + { + grpbase = LPC43_GRP0INT_BASE; + up_disable_irq(LPC43M4_IRQ_GINT0); + } + else + { + grpbase = LPC43_GRP1INT_BASE; + up_disable_irq(LPC43M4_IRQ_GINT1); + } + + /* Clear all group polarity and membership settings */ + + for (i = 0; i < NUM_GPIO_PORTS; i++) + { + putreg32(0, grpbase + LPC43_GRPINT_POL_OFFSET(i)); + putreg32(0, grpbase + LPC43_GRPINT_ENA_OFFSET(i)); + } + + /* Configure the group. Note that writing "1" to the status bit will also + * clear any pending group interrupts. + */ + + regval = GRPINT_CTRL_INT; + if (anded) + { + regval |= GRPINT_CTRL_COMB; + } + + if (level) + { + regval |= GRPINT_CTRL_TRIG; + } + + putreg32(regval, grpbase + LPC43_GRPINT_CTRL_OFFSET); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc43_gpioint_pinconfig + * + * Description: + * Configure a GPIO pin as an GPIO pin interrupt source (after it has been + * configured as an input). + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_pinconfig(uint16_t gpiocfg) +{ + unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pinint = ((gpiocfg & GPIO_PININT_MASK) >> GPIO_PININT_SHIFT); + uint32_t bitmask = (1 << pinint); + uint32_t regval; + + DEBUGASSERT(port < NUM_GPIO_PORTS && pin < NUM_GPIO_PINS && GPIO_IS_PININT(gpiocfg)); + + /* Make sure that pin interrupts are initially disabled at the NVIC. + * After the pin is configured, the caller will need to manually enable + * the pin interrupt. + */ + + up_disable_irq(LPC43M4_IRQ_PININT0 + pinint); + + /* Select the pin as the input in the SCU PINTSELn register (overwriting any + * previous selection). + */ + + if (pinint < 4) + { + regval = getreg32(LPC43_SCU_PINTSEL0); + regval &= ~SCU_PINTSEL0_MASK(pinint); + regval |= ((pin << SCU_PINTSEL0_INTPIN_SHIFT(pinint)) | + (port << SCU_PINTSEL0_PORTSEL_SHIFT(pinint))); + putreg32(regval, LPC43_SCU_PINTSEL0); + } + else + { + regval = getreg32(LPC43_SCU_PINTSEL1); + regval &= ~SCU_PINTSEL1_MASK(pinint); + regval |= ((pin << SCU_PINTSEL1_INTPIN_SHIFT(pinint)) | + (port << SCU_PINTSEL1_PORTSEL_SHIFT(pinint))); + putreg32(regval, LPC43_SCU_PINTSEL1); + } + + /* Set level or edge sensitive */ + + regval = getreg32(LPC43_GPIOINT_ISEL); + if (GPIO_IS_LEVEL(gpiocfg)) + { + regval |= bitmask; + } + else + { + regval &= ~bitmask; + } + + putreg32(regval, LPC43_GPIOINT_ISEL); + + /* Configure the active high level or rising edge */ + + regval = getreg32(LPC43_GPIOINT_IENR); + if (GPIO_IS_ACTIVE_HI(gpiocfg)) + { + regval |= bitmask; + } + else + { + regval &= ~bitmask; + } + + putreg32(regval, LPC43_GPIOINT_IENR); + + /* Configure the active high low or falling edge */ + + regval = getreg32(LPC43_GPIOINT_IENF); + if (GPIO_IS_ACTIVE_LOW(gpiocfg)) + { + regval |= bitmask; + } + else + { + regval &= ~bitmask; + } + + putreg32(regval, LPC43_GPIOINT_IENF); + return OK; +} + +/**************************************************************************** + * Name: lpc43_gpioint_grpconfig + * + * Description: + * Configure a GPIO pin as an GPIO group interrupt member (after it has + * been configured as an input). + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_grpconfig(uint16_t gpiocfg) +{ + unsigned int port = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + unsigned int pin = ((gpiocfg & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); + irqstate_t flags; + uintptr_t grpbase; + uintptr_t regaddr; + uint32_t regval; + uint32_t bitmask = (1 << pin); + + /* Select the group register base address */ + + flags = enter_critical_section(); + if (GPIO_IS_GROUP0(gpiocfg)) + { + grpbase = LPC43_GRP0INT_BASE; + } + else + { + grpbase = LPC43_GRP1INT_BASE; + } + + /* Set/clear the polarity for this pin */ + + regaddr = grpbase + LPC43_GRPINT_POL_OFFSET(port); + regval = getreg32(regaddr); + + if (GPIO_IS_POLARITY_HI(gpiocfg)) + { + regval |= bitmask; + } + else + { + regval &= ~bitmask; + } + + putreg32(regval, regaddr); + + /* Set the corresponding bit in the port enable register so that this pin + * will contribute to the group interrupt. + */ + + regaddr = grpbase + LPC43_GRPINT_ENA_OFFSET(port); + regval = getreg32(regaddr); + regval |= bitmask; + putreg32(regval, regaddr); + + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/arm/src/lpc43xx/lpc43_gpioint.h b/arch/arm/src/lpc43xx/lpc43_gpioint.h new file mode 100644 index 0000000000000000000000000000000000000000..35b22f7c7f27abd6e150a1e552bf1787308c184d --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_gpioint.h @@ -0,0 +1,140 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_gpioint.h + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +/* GPIO pin interrupts + * + * From all available GPIO pins, up to eight pins can be selected in the system + * control block to serve as external interrupt pins. The external interrupt pins + * are connected to eight individual interrupts in the NVIC and are created based + * on rising or falling edges or on the input level on the pin. + * + * GPIO group interrupt + * + * For each port/pin connected to one of the two the GPIO Grouped Interrupt blocks + * (GROUP0 and GROUP1), the GPIO grouped interrupt registers determine which pins are + * enabled to generate interrupts and what the active polarities of each of those + * inputs are. The GPIO grouped interrupt registers also select whether the interrupt + * output will be level or edge triggered and whether it will be based on the OR or + * the AND of all of the enabled inputs. + */ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_GPIOINT_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_GPIOINT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc43_gpio.h" + +#ifdef CONFIG_GPIO_IRQ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_gpioint_grpinitialize + * + * Description: + * Initialize the properties of a GPIO group. The properties of the group + * should be configured before any pins are added to the group by + * lpc32_gpioint_grpconfig(). As side effects, this call also removes + * all pins from the group and disables the group interrupt. On return, + * this is a properly configured, empty GPIO interrupt group. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_grpinitialize(int group, bool anded, bool level); + +/**************************************************************************** + * Name: lpc43_gpioint_pinconfig + * + * Description: + * Configure a GPIO pin as an GPIO pin interrupt source (after it has been + * configured as an input). This function should *not* be called directly + * from user application code; user code should call this function only + * indirectly through lpc32_gpio_config(). + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_pinconfig(uint16_t gpiocfg); + +/**************************************************************************** + * Name: lpc43_gpioint_grpconfig + * + * Description: + * Configure a GPIO pin as an GPIO group interrupt member (after it has been + * configured as an input). This function should *not* be called directly + * from user application code; user code should call this function only + * indirectly through lpc32_gpio_config(). + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts are disabled so that read-modify-write operations are safe. + * + ****************************************************************************/ + +int lpc43_gpioint_grpconfig(uint16_t gpiocfg); + +#endif /* CONFIG_GPIO_IRQ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_GPIOINT_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_i2c.c b/arch/arm/src/lpc43xx/lpc43_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..a7ddfa4726cbf0f43a9aa4137269b2d353c8c87d --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_i2c.c @@ -0,0 +1,582 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_i2c.c + * + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Ported from from the LPC17 version: + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2011-08-20 initial version + * + * Derived from arch/arm/src/lpc31xx/lpc31_i2c.c + * + * Author: David Hewson + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc43_i2c.h" +#include "lpc43_scu.h" +#include "lpc43_ccu.h" +#include "lpc43_pinconfig.h" + +#if defined(CONFIG_LPC43_I2C0) || defined(CONFIG_LPC43_I2C1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define I2C_TIMEOUT (20*1000/CONFIG_USEC_PER_TICK) /* 20 mS */ + +#ifdef CONFIG_LPC43_I2C0_SUPERFAST +# define I2C0_DEFAULT_FREQUENCY 1000000 +#else +# define I2C0_DEFAULT_FREQUENCY 400000 +#endif + +#define I2C1_DEFAULT_FREQUENCY 400000 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct lpc43_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + uint32_t baseFreq; /* branch frequency */ + + sem_t mutex; /* Only one thread can access at a time */ + sem_t wait; /* Place to wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ + unsigned int nmsg; /* number of transfer remaining */ + + uint16_t wrcnt; /* number of bytes sent to tx fifo */ + uint16_t rdcnt; /* number of bytes read from rx fifo */ +}; + +#ifdef CONFIG_LPC43_I2C0 +static struct lpc43_i2cdev_s g_i2c0dev; +#endif +#ifdef CONFIG_LPC43_I2C1 +static struct lpc43_i2cdev_s g_i2c1dev; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lpc43_i2c_start(struct lpc43_i2cdev_s *priv); +static void lpc43_i2c_stop(struct lpc43_i2cdev_s *priv); +static int lpc43_i2c_interrupt(int irq, FAR void *context); +static void lpc43_i2c_timeout(int argc, uint32_t arg, ...); +static void lpc43_i2c_setfrequency(struct lpc43_i2cdev_s *priv, + uint32_t frequency); +static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int lpc43_i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +struct i2c_ops_s lpc43_i2c_ops = +{ + .transfer = lpc43_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = lpc43_i2c_reset +#endif +}; + +/**************************************************************************** + * Name: lpc43_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void lpc43_i2c_setfrequency(struct lpc43_i2cdev_s *priv, + uint32_t frequency) +{ + if (frequency != priv->frequency) + { + if (frequency > 100000) + { + /* asymetric per 400Khz I2C spec */ + + putreg32(priv->baseFreq / (83 + 47) * 47 / frequency, + priv->base + LPC43_I2C_SCLH_OFFSET); + putreg32(priv->baseFreq / (83 + 47) * 83 / frequency, + priv->base + LPC43_I2C_SCLL_OFFSET); + } + else + { + /* 50/50 mark space ratio */ + + putreg32(priv->baseFreq / 100 * 50 / frequency, + priv->base + LPC43_I2C_SCLH_OFFSET); + putreg32(priv->baseFreq / 100 * 50 / frequency, + priv->base + LPC43_I2C_SCLL_OFFSET); + } + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: lpc43_i2c_start + * + * Description: + * Perform a I2C transfer start + * + ****************************************************************************/ + +static int lpc43_i2c_start(struct lpc43_i2cdev_s *priv) +{ + putreg32(I2C_CONCLR_STAC | I2C_CONCLR_SIC, + priv->base + LPC43_I2C_CONCLR_OFFSET); + putreg32(I2C_CONSET_STA, priv->base + LPC43_I2C_CONSET_OFFSET); + + wd_start(priv->timeout, I2C_TIMEOUT, lpc43_i2c_timeout, 1, (uint32_t)priv); + sem_wait(&priv->wait); + + wd_cancel(priv->timeout); + return priv->nmsg; +} + +/**************************************************************************** + * Name: lpc43_i2c_stop + * + * Description: + * Perform a I2C transfer stop + * + ****************************************************************************/ + +static void lpc43_i2c_stop(struct lpc43_i2cdev_s *priv) +{ + if (priv->state != 0x38) + { + putreg32(I2C_CONSET_STO | I2C_CONSET_AA, + priv->base + LPC43_I2C_CONSET_OFFSET); + } + + sem_post(&priv->wait); +} + +/**************************************************************************** + * Name: lpc43_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void lpc43_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)arg; + + irqstate_t flags = enter_critical_section(); + priv->state = 0xff; + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc32_i2c_nextmsg + * + * Description: + * Setup for the next message. + * + ****************************************************************************/ + +void lpc32_i2c_nextmsg(struct lpc43_i2cdev_s *priv) +{ + priv->nmsg--; + + if (priv->nmsg > 0) + { + priv->msgs++; + putreg32(I2C_CONSET_STA, priv->base + LPC43_I2C_CONSET_OFFSET); + } + else + { + lpc43_i2c_stop(priv); + } +} + +/**************************************************************************** + * Name: lpc43_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int lpc43_i2c_interrupt(int irq, FAR void *context) +{ + struct lpc43_i2cdev_s *priv; + struct i2c_msg_s *msg; + uint32_t state; + +#ifdef CONFIG_LPC43_I2C0 + if (irq == LPC43M0_IRQ_I2C0) + { + priv = &g_i2c0dev; + } + else +#endif +#ifdef CONFIG_LPC43_I2C1 + if (irq == LPC43_IRQ_I2C1) + { + priv = &g_i2c1dev; + } + else +#endif + { + PANIC(); + } + + /* Reference UM10360 19.10.5 */ + + state = getreg32(priv->base + LPC43_I2C_STAT_OFFSET); + msg = priv->msgs; + + priv->state = state; + state &= 0xf8; /* state mask, only 0xX8 is possible */ + switch (state) + { + + case 0x08: /* A START condition has been transmitted. */ + case 0x10: /* A Repeated START condition has been transmitted. */ + /* Set address */ + + putreg32(((I2C_M_READ & msg->flags) == I2C_M_READ) ? + I2C_READADDR8(msg->addr) : + I2C_WRITEADDR8(msg->addr), priv->base + LPC43_I2C_DAT_OFFSET); + + /* Clear start bit */ + + putreg32(I2C_CONCLR_STAC, priv->base + LPC43_I2C_CONCLR_OFFSET); + break; + + /* Write cases */ + + case 0x18: /* SLA+W has been transmitted; ACK has been received */ + priv->wrcnt = 0; + putreg32(msg->buffer[0], priv->base + LPC43_I2C_DAT_OFFSET); /* put first byte */ + break; + + case 0x28: /* Data byte in DAT has been transmitted; ACK has been received. */ + priv->wrcnt++; + + if (priv->wrcnt < msg->length) + { + putreg32(msg->buffer[priv->wrcnt], priv->base + LPC43_I2C_DAT_OFFSET); /* Put next byte */ + } + else + { + lpc32_i2c_nextmsg(priv); + } + break; + + /* Read cases */ + + case 0x40: /* SLA+R has been transmitted; ACK has been received */ + priv->rdcnt = 0; + if (msg->length > 1) + { + putreg32(I2C_CONSET_AA, priv->base + LPC43_I2C_CONSET_OFFSET); /* Set ACK next read */ + } + else + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* Do not ACK because only one byte */ + } + break; + + case 0x50: /* Data byte has been received; ACK has been returned. */ + priv->rdcnt++; + msg->buffer[priv->rdcnt - 1] = getreg32(priv->base + LPC43_I2C_BUFR_OFFSET); + + if (priv->rdcnt >= (msg->length - 1)) + { + putreg32(I2C_CONCLR_AAC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* Do not ACK any more */ + } + break; + + case 0x58: /* Data byte has been received; NACK has been returned. */ + msg->buffer[priv->rdcnt] = getreg32(priv->base + LPC43_I2C_BUFR_OFFSET); + lpc32_i2c_nextmsg(priv); + break; + + default: + lpc43_i2c_stop(priv); + break; + } + + putreg32(I2C_CONCLR_SIC, priv->base + LPC43_I2C_CONCLR_OFFSET); /* clear interrupt */ + + return OK; +} + +/**************************************************************************** + * Name: lpc43_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev; + int ret; + + DEBUGASSERT(dev != NULL); + + /* Get exclusive access to the I2C bus */ + + sem_wait(&priv->mutex); + + /* Set up for the transfer */ + + priv->wrcnt = 0; + priv->rdcnt = 0; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + lpc43_i2c_setfrequency(priv, msgs->frequency); + + /* Perform the transfer */ + + ret = lpc43_i2c_start(priv); + + sem_post(&priv->mutex); + return ret; +} + +/************************************************************************************ + * Name: lpc43_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int lpc43_i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc43_i2cbus_initialize(int port) +{ + struct lpc43_i2cdev_s *priv; + + if (port > 1) + { + dbg("lpc I2C Only support 0,1\n"); + return NULL; + } + + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + +#ifdef CONFIG_LPC43_I2C0 + if (port == 0) + { + priv = &g_i2c0dev; + priv->base = LPC43_I2C0_BASE; + priv->irqid = LPC43M0_IRQ_I2C0; + priv->baseFreq = BOARD_ABP1_FREQUENCY; + + /* Enable, set mode */ + + regval = getreg32(LPC43_SCU_SFSI2C0); + regval |= SCU_SFSI2C0_SCL_EZI | SCU_SFSI2C0_SDA_EZI; + +#ifdef CONFIG_LPC43_I2C0_SUPERFAST + /* Enable super fast mode */ + + regval |= SCU_SFSI2C0_SCL_EHD | SCU_SFSI2C0_SDA_EHD; +#endif + + putreg32(regval, LPC43_SCU_SFSI2C0); + + /* Enable clock */ + + regval = getreg32(LPC43_CCU1_APB1_I2C0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_APB1_I2C0_CFG); + + lpc43_i2c_setfrequency(priv, I2C0_DEFAULT_FREQUENCY); + + /* No pin configuration needed */ + } + else +#endif +#ifdef CONFIG_LPC43_I2C1 + if (port == 1) + { + priv = &g_i2c1dev; + priv->base = LPC43_I2C1_BASE; + priv->irqid = LPC43M0_IRQ_I2C1; + priv->baseFreq = BOARD_ABP3_FREQUENCY; + + /* No need to enable */ + + /* Enable clock */ + + regval = getreg32(LPC43_CCU1_APB3_I2C1_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_APB3_I2C1_CFG); + + /* Pin configuration */ + + lpc43_pin_config(PINCONF_I2C1_SCL); + lpc43_pin_config(PINCONF_I2C1_SDA); + + lpc43_i2c_setfrequency(priv, I2C1_DEFAULT_FREQUENCY); + } + else +#endif + { + return NULL; + } + + leave_critical_section(flags); + + putreg32(I2C_CONSET_I2EN, priv->base + LPC43_I2C_CONSET_OFFSET); + + sem_init(&priv->mutex, 0, 1); + sem_init(&priv->wait, 0, 0); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, lpc43_i2c_interrupt); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc43_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc43_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc43_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *) dev; + + putreg32(I2C_CONCLRT_I2ENC, priv->base + LPC43_I2C_CONCLR_OFFSET); + up_disable_irq(priv->irqid); + irq_detach(priv->irqid); + return OK; +} + +#endif /* CONFIG_LPC43_I2C0 || CONFIG_LPC43_I2C1 */ diff --git a/arch/arm/src/lpc43xx/lpc43_i2c.h b/arch/arm/src/lpc43xx/lpc43_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..ae8d94a7f883e5f25654ebe699ab1be0379a6af8 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_i2c.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_i2c.h + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_I2C_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc43_i2c.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *lpc43_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: lpc43_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc43_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int lpc43_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_I2C_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_idle.c b/arch/arm/src/lpc43xx/lpc43_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..62f665495e01bd3c1fddad91f2278912e347b362 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_idle.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_idle.c + * + * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + lpc43_pmstandby(true); + break; + + case PM_SLEEP: + (void)lpc43_pmsleep(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} + diff --git a/arch/arm/src/lpc43xx/lpc43_irq.c b/arch/arm/src/lpc43xx/lpc43_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..73ca6d3bc7cb53063899cb35d89b94a058036658 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_irq.c @@ -0,0 +1,564 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_irq.c + * + * Copyright (C) 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc43_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (LPC43M4_SYSH_PRIORITY_DEFAULT << 24 | \ + LPC43M4_SYSH_PRIORITY_DEFAULT << 16 | \ + LPC43M4_SYSH_PRIORITY_DEFAULT << 8 | \ + LPC43M4_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void lpc43_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + lldbg(" %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY)); + leave_critical_section(flags); +} +#else +# define lpc43_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: lpc43_nmi, lpc43_busfault, lpc43_usagefault, lpc43_pendsv, + * lpc43_dbgmonitor, lpc43_pendsv, lpc43_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int lpc43_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int lpc43_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int lpc43_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int lpc43_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int lpc43_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int lpc43_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: lpc43_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void lpc43_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: lpc43_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int lpc43_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= LPC43_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= LPC43_IRQ_EXTINT) + { + if (irq < (LPC43_IRQ_EXTINT + 32)) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - LPC43_IRQ_EXTINT); + } + else if (irq < LPC43M4_IRQ_NIRQS) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - LPC43_IRQ_EXTINT - 32); + } + else + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == LPC43_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == LPC43_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == LPC43_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == LPC43_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Complete initialization of the interrupt system and enable normal, + * interrupt processing. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; +#ifdef CONFIG_DEBUG + uint32_t regval; +#endif + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); + putreg32(0, NVIC_IRQ32_63_ENABLE); + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(LPC43_IRQ_SVCALL, up_svcall); + irq_attach(LPC43_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(LPC43_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + lpc43_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(LPC43_IRQ_MEMFAULT, up_memfault); + up_enable_irq(LPC43_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(LPC43_IRQ_NMI, lpc43_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(LPC43_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(LPC43_IRQ_BUSFAULT, lpc43_busfault); + irq_attach(LPC43_IRQ_USAGEFAULT, lpc43_usagefault); + irq_attach(LPC43_IRQ_PENDSV, lpc43_pendsv); + irq_attach(LPC43_IRQ_DBGMONITOR, lpc43_dbgmonitor); + irq_attach(LPC43_IRQ_RESERVED, lpc43_reserved); +#endif + + lpc43_dumpnvic("initial", LPC43M4_IRQ_NIRQS); + + /* If a debugger is connected, try to prevent it from catching hardfaults. + * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal + * operation. + */ + +#if defined(CONFIG_DEBUG) && !defined(CONFIG_ARMV7M_USEBASEPRI) + regval = getreg32(NVIC_DEMCR); + regval &= ~NVIC_DEMCR_VCHARDERR; + putreg32(regval, NVIC_DEMCR); +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (lpc43_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= LPC43_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + lpc43_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (lpc43_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= LPC43_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + lpc43_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + lpc43_clrpend(irq); +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= LPC43_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < LPC43_IRQ_EXTINT) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= LPC43_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + lpc43_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/lpc43xx/lpc43_irq.h b/arch/arm/src/lpc43xx/lpc43_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b0c12aaec30801f31e34c0d7b4f13073c63e123b --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_irq.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_irq.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_IRQ_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be + * required for most interrupts. + * + ****************************************************************************/ + +void lpc43_clrpend(int irq); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_IRQ_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_mpuinit.c b/arch/arm/src/lpc43xx/lpc43_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..3ed8d8a8c740f23bb6f86337f18a8b7e918a6466 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_mpuinit.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "lpc43_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void lpc43_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: lpc43_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void lpc43_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/lpc43xx/lpc43_mpuinit.h b/arch/arm/src/lpc43xx/lpc43_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..f4c6c59ca3479599330ca9f0a000d589b026ca0a --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_mpuinit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_mpuinit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_MPUINIT_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc43_mpuinitialize(void); +#else +# define lpc43_mpuinitialize() +#endif + +/**************************************************************************** + * Name: lpc43_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc43_mpu_uheap(uintptr_t start, size_t size); +#else +# define lpc43_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_MPUINIT_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_pinconfig.c b/arch/arm/src/lpc43xx/lpc43_pinconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..0a274dd6a898bac27314835e74a951e71f8aaa35 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_pinconfig.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_pin_config.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "lpc43_pinconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_pin_config + * + * Description: + * Configure a pin based on bit-encoded description of the pin. + * + * Input Value: + * 20-bit encoded value describing the pin. + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +int lpc43_pin_config(uint32_t pinconf) +{ + unsigned int pinset = ((pinconf & PINCONF_PINS_MASK) >> PINCONF_PINS_SHIFT); + unsigned int pin = ((pinconf & PINCONF_PIN_MASK) >> PINCONF_PIN_SHIFT); + unsigned int func = ((pinconf & PINCONF_FUNC_MASK) >> PINCONF_FUNC_SHIFT); + uintptr_t regaddr; + uint32_t regval; + + /* Set up common pin configurations */ + + regval = (func << SCU_PIN_MODE_SHIFT); + + /* Enable/disable pull-down resistor */ + + if (PINCONF_IS_PULLDOWN(pinconf)) + { + regval |= SCU_PIN_EPD; /* Set bit to enable */ + } + + if (!PINCONF_IS_PULLUP(pinconf)) + { + regval |= SCU_PIN_EPUN; /* Set bit to disable */ + } + + /* Enable/disable input buffering */ + + if (PINCONF_INBUFFER_ENABLED(pinconf)) + { + regval |= SCU_PIN_EZI; /* Set bit to enable */ + } + + /* Enable/disable glitch filtering */ + + if (!PINCONF_GLITCH_ENABLE(pinconf)) + { + regval |= SCU_PIN_ZIF; /* Set bit to disable */ + } + + /* Only normal and high speed pins support the slew rate setting */ + + if (PINCONF_IS_SLEW_FAST(pinconf)) + { + regval |= SCU_NDPIN_EHS; /* 0=slow; 1=fast */ + } + + /* Only high drive pins suppose drive strength */ + + switch (pinconf & PINCONF_DRIVE_MASK) + { + default: + case PINCONF_DRIVE_NORMAL: /* Normal-drive: 4 mA drive strength (or not high drive pin) */ + regval |= SCU_HDPIN_EHD_NORMAL; + break; + + case PINCONF_DRIVE_MEDIUM: /* Medium-drive: 8 mA drive strength */ + regval |= SCU_HDPIN_EHD_MEDIUM; + break; + + case PINCONF_DRIVE_HIGH: /* High-drive: 14 mA drive strength */ + regval |= SCU_HDPIN_EHD_HIGH; + break; + + case PINCONF_DRIVE_ULTRA: /* Ultra high-drive: 20 mA drive strength */ + regval |= SCU_HDPIN_EHD_ULTRA; + break; + } + + /* Get the address of the pin configuration register and save the new + * pin configuration. + */ + + regaddr = LPC43_SCU_SFSP(pinset, pin); + putreg32(regval, regaddr); + + return OK; +} diff --git a/arch/arm/src/lpc43xx/lpc43_pinconfig.h b/arch/arm/src/lpc43xx/lpc43_pinconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..dad885d86bd52050605ed24abd7df00322dde0e7 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_pinconfig.h @@ -0,0 +1,279 @@ +/******************************************************************************************** + * arch/arm/src/lpc43xx/lpc43_pinconfig.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_PINCONFIG_H +#define __ARCH_ARM_SRC_LPC43XX_PINCONFIG_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/* Include the chip capabilities and SCU definitions file */ + +#include "chip.h" +#include "chip/lpc43_scu.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Each configurable pin can be individually configured by software in several modes. The + * following definitions provide the bit encoding that is used to define a pin configuration. + * Note that these pins do not corresponding GPIO ports and pins. + * + * 20-bit Encoding: + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .FFF UUDD IGWS SSSP PPPP + */ + +/* Alternate function number: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .FFF .... .... .... .... + */ + +#define PINCONF_FUNC_SHIFT (16) /* Bits 16-18: Alternate function number */ +#define PINCONF_FUNC_MASK (7 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC(n) ((n) << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC0 (0 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC1 (1 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC2 (2 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC3 (3 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC4 (4 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC5 (5 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC6 (6 << PINCONF_FUNC_SHIFT) +# define PINCONF_FUNC7 (7 << PINCONF_FUNC_SHIFT) + +/* Pull-up/down resisters. These selections are available for all pins but may not + * make sense for all pins. NOTE: that both pull up and down is not precluded. + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... UU.. .... .... .... + */ + +#define PINCONF_PULLUP (1 << 15) /* Bit 15: 1=Pull-up */ +#define PINCONF_PULLDOWN (1 << 14) /* Bit 14: 1=Pull-down */ +#define PINCONF_FLOAT (0) /* Bit 14-15=0 if neither */ + +#define PINCONF_IS_PULLUP(p) (((p) & PINCONF_PULLUP) != 0) +#define PINCONF_IS_PULLDOWN(p) (((p) & PINCONF_PULLDOWN) != 0) +#define PINCONF_IS_FLOAT(p) (((p) & (PINCONF_PULLUP|PINCONF_PULLDOWN) == 0) + +/* Drive strength. These selections are available only for high-drive pins + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... ..DD .... .... .... + */ + +#define PINCONF_DRIVE_SHIFT (12) /* Bits 12-13 = Pin drive strength */ +#define PINCONF_DRIVE_MASK (3 << PINCONF_DRIVE_SHIFT) +# define PINCONF_DRIVE_NORMAL (0 << PINCONF_DRIVE_SHIFT) +# define PINCONF_DRIVE_MEDIUM (1 << PINCONF_DRIVE_SHIFT) +# define PINCONF_DRIVE_HIGH (2 << PINCONF_DRIVE_SHIFT) +# define PINCONF_DRIVE_ULTRA (3 << PINCONF_DRIVE_SHIFT) + +/* Input buffer enable + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... I... .... .... + */ + +#define PINCONF_INBUFFER (1 << 11) /* Bit 11: 1=Enabled input buffer */ +#define PINCONF_INBUFFER_ENABLED(p) (((p) & PINCONF_INBUFFER) != 0) + +/* Glitch filter enable + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .G.. .... .... + */ + +#define PINCONF_GLITCH (1 << 10) /* Bit 10: 1=Glitch filter enable */ +#define PINCONF_GLITCH_ENABLE(p) (((p) & PINCONF_GLITCH) == 0) + +/* Slew rate + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..W. .... .... + */ + +#define PINCONF_SLEW_FAST (1 << 9) /* Bit 9: 1=Alternate function */ +#define PINCONF_SLEW_SLOW (0) /* Bit 9: 0=Normal function */ + +#define PINCONF_IS_SLEW_FAST(p) (((p) & PINCONF_SLEW_FAST) != 0) +#define PINCONF_IS_SLOW_SLOW(p) (((p) & PINCONF_SLEW_FAST) == 0) + +/* Pin configuration sets: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...S SSS. .... + */ + +#define PINCONF_PINS_SHIFT (5) /* Bits 5-8: Pin set */ +#define PINCONF_PINS_MASK (15 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS0 (0 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS1 (1 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS2 (2 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS3 (3 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS4 (4 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS5 (5 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS6 (6 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS7 (7 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS8 (8 << PINCONF_PINS_SHIFT) +# define PINCONF_PINS9 (9 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSA (10 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSB (11 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSC (12 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSD (13 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSE (14 << PINCONF_PINS_SHIFT) +# define PINCONF_PINSF (15 << PINCONF_PINS_SHIFT) + +/* Pin numbers: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... ...P PPPP + */ + +#define PINCONF_PIN_SHIFT (0) /* Bits 0-4: Pin number */ +#define PINCONF_PIN_MASK (31 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_0 (0 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_1 (1 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_2 (2 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_3 (3 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_4 (4 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_5 (5 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_6 (6 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_7 (7 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_8 (8 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_9 (9 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_10 (10 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_11 (11 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_12 (12 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_13 (13 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_14 (14 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_15 (15 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_16 (16 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_17 (17 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_18 (18 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_19 (19 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_20 (20 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_21 (21 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_22 (22 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_23 (23 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_24 (24 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_25 (25 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_26 (26 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_27 (27 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_28 (28 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_29 (29 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_30 (30 << PINCONF_PIN_SHIFT) +# define PINCONF_PIN_31 (31 << PINCONF_PIN_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Name: lpc43_pin_config + * + * Description: + * Configure a pin based on bit-encoded description of the pin. + * + * Input Value: + * 20-bit encoded value describing the pin. + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ********************************************************************************************/ + +int lpc43_pin_config(uint32_t pinconf); + +/******************************************************************************************** + * Function: lpc43_pin_dump + * + * Description: + * Dump all pin configuration registers associated with the provided pin configuration + * + ********************************************************************************************/ + +#ifdef CONFIG_DEBUG +int lpc43_pin_dump(uint32_t pinconf, const char *msg); +#else +# define lpc43_pin_dump(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_LPC43XX_PINCONFIG_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_rgu.c b/arch/arm/src/lpc43xx/lpc43_rgu.c new file mode 100644 index 0000000000000000000000000000000000000000..9671a4f8a59709f3b672240eeeaa33acb1f5c4f6 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_rgu.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_rgu.c + * arch/arm/src/chip/lpc43_rgu.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "nvic.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc43_rgu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_softreset + * + * Description: + * Reset as many of the LPC43 peripherals as possible. This is necessary + * because the LPC43 does not provide any way of performing a full system + * reset under debugger control. So, if CONFIG_DEBUG is set (indicating + * that a debugger is being used?), the boot logic will call this + * function on all restarts. + * + * Assumptions: + * Since this function is called early in the boot sequence, it cannot + * depend on anything such as initialization of .bss or .data. It can + * only assume that it has a stack. + * + ****************************************************************************/ + +void lpc43_softreset(void) +{ + irqstate_t flags; + + /* Disable interrupts */ + + flags = enter_critical_section(); + + /* Reset all of the peripherals that we can (safely) */ + + putreg32((RGU_CTRL0_LCD_RST | RGU_CTRL0_USB0_RST | + RGU_CTRL0_USB1_RST | RGU_CTRL0_DMA_RST | + RGU_CTRL0_SDIO_RST | RGU_CTRL0_ETHERNET_RST | + RGU_CTRL0_GPIO_RST), LPC43_RGU_CTRL0); + putreg32((RGU_CTRL1_TIMER0_RST | RGU_CTRL1_TIMER1_RST | + RGU_CTRL1_TIMER2_RST | RGU_CTRL1_TIMER3_RST | + RGU_CTRL1_RITIMER_RST | RGU_CTRL1_SCT_RST | + RGU_CTRL1_MCPWM_RST | RGU_CTRL1_QEI_RST | + RGU_CTRL1_ADC0_RST | RGU_CTRL1_ADC1_RST | + RGU_CTRL1_USART0_RST | RGU_CTRL1_UART1_RST | + RGU_CTRL1_USART2_RST | RGU_CTRL1_USART3_RST | + RGU_CTRL1_I2C0_RST | RGU_CTRL1_I2C1_RST | + RGU_CTRL1_SSP0_RST | RGU_CTRL1_SSP1_RST | + RGU_CTRL1_I2S_RST | RGU_CTRL1_CAN1_RST | + RGU_CTRL1_CAN0_RST | RGU_CTRL1_M0APP_RST), + LPC43_RGU_CTRL1); + + /* A delay seems to be necessary somewhere around here */ + + up_mdelay(20); + + /* Clear all pending interrupts */ + + putreg32(0xffffffff, NVIC_IRQ0_31_CLRPEND); + putreg32(0xffffffff, NVIC_IRQ32_63_CLRPEND); + leave_critical_section(flags); +} diff --git a/arch/arm/src/lpc43xx/lpc43_rgu.h b/arch/arm/src/lpc43xx/lpc43_rgu.h new file mode 100644 index 0000000000000000000000000000000000000000..2d1604d23a4c3a9b44ce09773c587b1a6c47e75f --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_rgu.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_rgu.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_RGU_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_RGU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc43_rgu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_softreset + * + * Description: + * Reset as many of the LPC43 peripherals as possible. This is necessary + * because the LPC43 does not provide any way of performing a full system + * reset under debugger control. So, if CONFIG_DEBUG is set (indicating + * that a debugger is being used?), the boot logic will call this + * function on all restarts. + * + ****************************************************************************/ + +void lpc43_softreset(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_RGU_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_rit.c b/arch/arm/src/lpc43xx/lpc43_rit.c new file mode 100644 index 0000000000000000000000000000000000000000..f80cd550ac052725e44155c8ba45c918c1e5003a --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_rit.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_rit.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Brandon Warhurst + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * WARNING -- This code is currently *NOT* thread safe. No checking is done + * that one alarm call might not override an already enabled one. + * You might be able to handle this with some kind of cascading + * scheme where alarm receives the next value in a list of alarms + * all in the future. + * + * Brandon Warhurst + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_arch.h" +#include "chip/lpc43_rit.h" +#include "lpc43_rit.h" + +#ifdef CONFIG_LPC43_RIT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Set the timer resolution at 1uS + * + * This is a battery waster, but I need this kind of resolution for 1-wire + * protocols... Until I can find a better way to implement them. + * + * This should probable be Kconfig material. + */ + +#define RIT_TIMER_RESOLUTION CONFIG_LPC43_RIT_RES + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static double sec_per_tick; +static uint64_t internal_timer, alarm; +struct timespec g_ts; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lpc43_RIT_isr(int irq, FAR void *context) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + putreg32(RIT_CTRL_INT, LPC43_RIT_CTRL); + + internal_timer += (uint64_t)RIT_TIMER_RESOLUTION; + if (alarm > 0 && internal_timer >= alarm) + { + /* handle expired alarm */ + + g_ts.tv_sec = (uint32_t)(internal_timer / 1000000000); + g_ts.tv_nsec = (uint32_t)(internal_timer % 1000000000); + sched_alarm_expiration(&g_ts); + } + + leave_critical_section(flags); + return OK; +} + +static inline void lpc43_load_RIT_timer(uint32_t value) +{ + putreg32(value, LPC43_RIT_COUNTER); +} + +static inline void lpc43_load_RIT_compare(uint32_t value) +{ + putreg32(value, LPC43_RIT_COMPVAL); +} + +static inline void lpc43_set_RIT_timer_mask(uint32_t value) +{ + putreg32(value, LPC43_RIT_MASK); +} + +static inline uint32_t lpc43_read_RIT_timer(void) +{ + return getreg32(LPC43_RIT_COUNTER); +} + +static inline void lpc43_RIT_timer_start(void) +{ + uint32_t regval; + regval = getreg32(LPC43_RIT_CTRL); + + /* Since a cycle timer is in use here, the timer clear is enabled. If + * using the timer directly, this likely should not be used. Also, clear + * the interrupt flag. + */ + + regval |= RIT_CTRL_INT | RIT_CTRL_EN | RIT_CTRL_ENCLR; + putreg32(regval, LPC43_RIT_CTRL); +} + +static inline void lpc43_RIT_timer_stop(void) +{ + uint32_t regval; + regval = getreg32(LPC43_RIT_CTRL); + regval &= ~RIT_CTRL_EN; + putreg32(regval, LPC43_RIT_CTRL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t ticks_per_int; + uint32_t mask_bits = 0; + uint32_t mask_test = 0x80000000; + + lpc43_RIT_timer_stop(); + lpc43_load_RIT_timer(0); + internal_timer = 0; + + /* Set up the IRQ here */ + + irq_attach(LPC43M4_IRQ_RITIMER, lpc43_RIT_isr); + + /* Compute how many seconds per tick we have on the main clock. If it is + * 204MHz for example, then there should be about 4.90ns per tick + */ + + sec_per_tick = (double)1.0/(double)LPC43_CCLK; + + /* Given an RIT_TIMER_RESOLUTION, compute how many ticks it will take to + * reach that resolution. For example, if we wanted a 1/4uS timer + * resolution, that would be 250ns resolution. The timer is an integer + * value, although maybe this should change, but that means + * 250/1000000000*0.00000000490 = 51.02 ticks or 51 ticks, roughly. + * We round up by 1 tick. + */ + + ticks_per_int = RIT_TIMER_RESOLUTION/(1000000000*sec_per_tick)+1; + + /* Now we need to compute the mask that will let us set up to generate an + * interrupt every 1/4uS. This isn't "tickless" per-se, and probably + * should be implemented differently, however it allows me to create a + * 64 bit nanosecond timer than can "free-run" by being updated every + * RIT_TIMER_RESOLUTION cycles. I would have implemented the better + * approach, but I didn't have a good way to determine how to manage a + * 32 bit ns timer. Every 21 seconds the thing rolls over@ 204MHz, so + * you'd have to set up the compare interrupt to handle the roll over. It + * WOULD be fewer interrupts, but it seemed to make things more + * complicated. When I have a better idea, I'll change this. + */ + + while (!((mask_test >> mask_bits) & ticks_per_int)) + { + mask_bits++; + } + + lldbg("mask_bits = %d, mask = %X, ticks_per_int = %d\r\n", + mask_bits, (0xffffffff << (32 - mask_bits)), ticks_per_int); + + /* Set the mask and compare value so we get interrupts every + * RIT_TIMER_RESOLUTION cycles. + */ + + lpc43_set_RIT_timer_mask((0xFFFFFFFF << (32 - mask_bits))); + lpc43_load_RIT_compare(ticks_per_int); + + /* Turn on the IRQ */ + + up_enable_irq(LPC43M4_IRQ_RITIMER); + + /* Start the timer */ + + lpc43_RIT_timer_start(); +} + +int up_timer_gettime(FAR struct timespec *ts) +{ + ts->tv_sec = (uint32_t)(internal_timer / 1000000000); + ts->tv_nsec = (uint32_t)(internal_timer % 1000000000); + + return OK; +} + +int up_alarm_cancel(FAR struct timespec *ts) +{ + ts->tv_sec = (uint32_t)(internal_timer / 1000000000); + ts->tv_nsec = (uint32_t)(internal_timer % 1000000000); + alarm = 0; + return OK; +} + +int up_alarm_start(FAR const struct timespec *ts) +{ + /* According to the docs, this version should expect to receive the time + * in the future when the alarm should expire. So that's the way it's + * coded. + */ + + alarm = (uint64_t)ts->tv_sec * (uint64_t)1000000000 + (uint64_t)ts->tv_nsec; + return OK; +} + +int up_timer_cancel(FAR struct timespec *ts) +{ + /* Currently this is just an alarm and both are implemented. This is *NOT* + * how it is supposed to be and will be corrected, but for now, this is a + * simple way to implement both. + * FIXME + */ + + return up_alarm_cancel(ts); +} + +int up_timer_start(FAR const struct timespec *ts) +{ + /* According to the docs, this version should basically compute the time + * in the future when an alarm should go off. That is the way it could + * potentially be implemented, so that's the way I did it. + */ + + alarm = internal_timer; + alarm += (uint64_t)ts->tv_sec * (uint64_t)1000000000 + (uint64_t)ts->tv_nsec; + return OK; +} + +#endif /* CONFIG_LPC43_RIT */ diff --git a/arch/arm/src/lpc43xx/lpc43_rit.h b/arch/arm/src/lpc43xx/lpc43_rit.h new file mode 100644 index 0000000000000000000000000000000000000000..3088b8fe115766a99eaef843823e2182d71fd4c0 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_rit.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_rit.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Brandon Warhurst + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_RIT_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_RIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_timer_initialize(void); +int up_timer_gettime(FAR struct timespec *ts); +int up_alarm_cancel(FAR struct timespec *ts); +int up_alarm_start(FAR const struct timespec *ts); +int up_timer_cancel(FAR struct timespec *ts); +int up_timer_start(FAR const struct timespec *ts); + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_RIT_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_scu.h b/arch/arm/src/lpc43xx/lpc43_scu.h new file mode 100644 index 0000000000000000000000000000000000000000..4345a026088d97a9ac1c94069d5a784a052fc4e3 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_scu.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_scu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_SCU_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_SCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/lpc43_scu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SCU_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_serial.c b/arch/arm/src/lpc43xx/lpc43_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..0dda586af1b1abc31f2034a61848eddb08e8461c --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_serial.c @@ -0,0 +1,1494 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_serial.c + * + * Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc43_config.h" +#include "lpc43_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t basefreq; /* Base frequency of input clock */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + uint8_t id; /* ID=0,1,2,3 */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#ifdef HAVE_RS485 + bool dtrdir; /* DTR pin is the direction bit */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_LPC43_USART0 +static char g_uart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_LPC43_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_LPC43_USART2 +static char g_uart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_LPC43_USART3 +static char g_uart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif + +/* This describes the state of the LPC43xx uart0 port. */ + +#ifdef CONFIG_LPC43_USART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = LPC43_USART0_BASE, + .basefreq = BOARD_USART0_BASEFREQ, + .baud = CONFIG_USART0_BAUD, + .id = 0, + .irq = LPC43M4_IRQ_USART0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +#if defined(CONFIG_USART0_RS485MODE) && defined(CONFIG_USART0_RS485_DTRDIR) + .dtrdir = true; +#endif +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the LPC43xx uart1 port. */ + +#ifdef CONFIG_LPC43_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = LPC43_UART1_BASE, + .basefreq = BOARD_UART1_BASEFREQ, + .baud = CONFIG_UART1_BAUD, + .id = 1, + .irq = LPC43M4_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +#if defined(CONFIG_UART1_RS485MODE) && defined(CONFIG_UART1_RS485_DTRDIR) + .dtrdir = true; +#endif +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the LPC43xx uart1 port. */ + +#ifdef CONFIG_LPC43_USART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = LPC43_USART2_BASE, + .basefreq = BOARD_USART2_BASEFREQ, + .baud = CONFIG_USART2_BAUD, + .id = 2, + .irq = LPC43M4_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +#if defined(CONFIG_USART2_RS485MODE) && defined(CONFIG_USART2_RS485_DTRDIR) + .dtrdir = true; +#endif +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the LPC43xx uart1 port. */ + +#ifdef CONFIG_LPC43_USART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = LPC43_USART3_BASE, + .basefreq = BOARD_USART3_BASEFREQ, + .baud = CONFIG_USART3_BAUD, + .id = 3, + .irq = LPC43M4_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, +#if defined(CONFIG_USART3_RS485MODE) && defined(CONFIG_USART3_RS485_DTRDIR) + .dtrdir = true; +#endif +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* Which UART with be tty0/console and which tty1? tty2? tty3? */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* USART0=console */ +# define TTYS0_DEV g_uart0port /* USART0=ttyS0 */ +# ifdef CONFIG_LPC43_UART1 +# define TTYS1_DEV g_uart1port /* USART0=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC43_USART2 +# define TTYS2_DEV g_uart2port /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS2 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS3_DEV g_uart3port /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS2;USART3=ttyS3 */ +# else +# undef TTYS3_DEV /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART0=ttyS0;UART1=ttyS1;USART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART2 +# define TTYS1_DEV g_uart2port /* USART0=ttyS0;USART2=ttyS1;No ttyS3 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART0=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART0=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS1_DEV g_uart3port /* USART0=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* USART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1=console */ +# define TTYS0_DEV g_uart1port /* UART1=ttyS0 */ +# ifdef CONFIG_LPC43_USART0 +# define TTYS1_DEV g_uart0port /* UART1=ttyS0;USART0=ttyS1 */ +# ifdef CONFIG_LPC43_USART2 +# define TTYS2_DEV g_uart2port /* UART1=ttyS0;USART0=ttyS1;USART2=ttyS2 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS3_DEV g_uart3port /* UART1=ttyS0;USART0=ttyS1;USART2=ttyS2;USART3=ttyS3 */ +# else +# undef TTYS3_DEV /* UART1=ttyS0;USART0=ttyS1;USART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* UART1=ttyS0;USART0=ttyS1;USART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART1=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART2 +# define TTYS1_DEV g_uart2port /* UART1=ttyS0;USART2=ttyS1 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* UART1=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* UART1=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS1_DEV g_uart3port /* UART1=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* UART1=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* USART2=console */ +# define TTYS0_DEV g_uart2port /* USART2=ttyS0 */ +# ifdef CONFIG_LPC43_USART0 +# define TTYS1_DEV g_uart0port /* USART2=ttyS0;USART0=ttyS1 */ +# ifdef CONFIG_LPC43_UART1 +# define TTYS2_DEV g_uart1port /* USART2=ttyS0;USART0=ttyS1;UART1=ttyS2 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS3_DEV g_uart3port /* USART2=ttyS0;USART0=ttyS1;UART1=ttyS2;USART3=ttyS3 */ +# else +# undef TTYS3_DEV /* USART2=ttyS0;USART0=ttyS1;UART1=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART2=ttyS0;USART0=ttyS1;USART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART2=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_UART1 +# define TTYS1_DEV g_uart1port /* USART2=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART2=ttyS0;UART1=ttyS1;USART3=ttyS2 */ +# else +# undef TTYS2_DEV /* USART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS1_DEV g_uart3port /* USART2=ttyS0;USART3=ttyS1;No ttyS3 */ +# else +# undef TTYS1_DEV /* USART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* USART3=console */ +# define TTYS0_DEV g_uart3port /* USART3=ttyS0 */ +# ifdef CONFIG_LPC43_USART0 +# define TTYS1_DEV g_uart0port /* USART3=ttyS0;USART0=ttyS1 */ +# ifdef CONFIG_LPC43_UART1 +# define TTYS2_DEV g_uart1port /* USART3=ttyS0;USART0=ttyS1;UART1=ttyS2 */ +# ifdef CONFIG_LPC43_USART2 +# define TTYS3_DEV g_uart2port /* USART3=ttyS0;USART0=ttyS1;UART1=ttyS2;USART2=ttyS3 */ +# else +# undef TTYS3_DEV /* USART3=ttyS0;USART0=ttyS1;UART1=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART2 +# define TTYS2_DEV g_uart2port /* USART3=ttyS0;USART0=ttyS1;USART2=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART3=ttyS0;USART0=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_UART1 +# define TTYS1_DEV g_uart1port /* USART3=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC43_USART2 +# define TTYS2_DEV g_uart2port /* USART3=ttyS0;UART1=ttyS1;USART2=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART3=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC43_USART2 +# define TTYS1_DEV g_uart2port /* USART3=ttyS0;USART2=ttyS1;No ttyS3;No ttyS3 */ +# undef TTYS3_DEV /* USART3=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* USART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +# endif +#else /* No console */ +# define TTYS0_DEV g_uart0port /* USART0=ttyS0 */ +# ifdef CONFIG_LPC43_UART1 +# define TTYS1_DEV g_uart1port /* USART0=ttyS0;UART1=ttyS1 */ +# ifdef CONFIG_LPC43_USART2 +# define TTYS2_DEV g_uart2port /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS2 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS3_DEV g_uart3port /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS2;USART3=ttyS3 */ +# else +# undef TTYS3_DEV /* USART0=ttyS0;UART1=ttyS1;USART2=ttyS;No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART0=ttyS0;UART1=ttyS1;USART3=ttys2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# else +# ifdef CONFIG_LPC43_USART2 +# define TTYS1_DEV g_uart2port /* USART0=ttyS0;USART2=ttyS1;No ttyS3 */ +# ifdef CONFIG_LPC43_USART3 +# define TTYS2_DEV g_uart3port /* USART0=ttyS0;USART2=ttyS1;USART3=ttyS2;No ttyS3 */ +# else +# undef TTYS2_DEV /* USART0=ttyS0;USART2=ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS3_DEV /* No ttyS3 */ +# else +# ifdef CONFIG_LPC43_USART3 +# define TTYS1_DEV g_uart3port /* USART0=ttyS0;USART3=ttyS1;No ttyS2;No ttyS3 */ +# else +# undef TTYS1_DEV /* USART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# undef TTYS3_DEV /* No ttyS3 */ +# endif +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + up_serialout(priv, LPC43_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + up_serialout(priv, LPC43_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, LPC43_UART_LCR_OFFSET); + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + up_serialout(priv, LPC43_UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t lcr; + + /* Clear fifos */ + + up_serialout(priv, LPC43_UART_FCR_OFFSET, (UART_FCR_RXRST | UART_FCR_TXRST)); + + /* Set trigger */ + + up_serialout(priv, LPC43_UART_FCR_OFFSET, (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, LPC43_UART_IER_OFFSET); + + /* Set up the LCR */ + + lcr = 0; + + if (priv->bits == 7) + { + lcr |= UART_LCR_WLS_7BIT; + } + else + { + lcr |= UART_LCR_WLS_8BIT; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STOP; + } + + if (priv->parity == 1) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_ODD); + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PE | UART_LCR_PS_EVEN); + } + + /* Save the LCR */ + + up_serialout(priv, LPC43_UART_LCR_OFFSET, lcr); + + /* Set the BAUD divisor */ + + lpc43_setbaud(priv->uartbase, priv->basefreq, priv->baud); + + /* Configure the FIFOs */ + + up_serialout(priv, LPC43_UART_FCR_OFFSET, + (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN)); + + /* Enable Auto-RTS and Auto-CS Flow Control in the Modem Control Register */ + +#ifdef CONFIG_UART1_FLOWCONTROL + if (priv->id == 1) + { + up_serialout(priv, LPC43_UART_MCR_OFFSET, (UART_MCR_RTSEN | UART_MCR_CTSEN)); + } +#endif + +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable further interrupts from the U[S]ART */ + + up_disableuartint(priv, NULL); + + /* Put the U[S]ART hardware back its reset state */ + + switch (priv->id) + { +#ifdef CONFIG_LPC43_USART0 + case 0: + lpc43_usart0_reset(); + break; +#endif + +#ifdef CONFIG_LPC43_UART1 + case 1: + lpc43_uart1_reset(); + break; +#endif + +#ifdef CONFIG_LPC43_USART2 + case 2: + lpc43_usart2_reset(); + break; +#endif + +#ifdef CONFIG_LPC43_USART3 + case 3: + lpc43_usart3_reset(); + break; +#endif + + default: + break; + } +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t status; + int passes; + +#ifdef CONFIG_LPC43_USART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_LPC43_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_LPC43_USART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_LPC43_USART3 + if (g_uart3priv.irq == irq) + { + dev = &g_uart3port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, LPC43_UART_IIR_OFFSET); + + /* The UART_IIR_INTSTATUS bit should be zero if there are pending + * interrupts + */ + + if ((status & UART_IIR_INTSTATUS) != 0) + { + /* Break out of the loop when there is no longer a + * pending interrupt + */ + + break; + } + + /* Handle the interrupt by its interrupt ID field */ + + switch (status & UART_IIR_INTID_MASK) + { + /* Handle incoming, receive bytes (with or without timeout) */ + + case UART_IIR_INTID_RDA: + case UART_IIR_INTID_CTI: + { + uart_recvchars(dev); + break; + } + + /* Handle outgoing, transmit bytes */ + + case UART_IIR_INTID_THRE: + { + uart_xmitchars(dev); + break; + } + + /* Just clear modem status interrupts (UART1 only) */ + + case UART_IIR_INTID_MSI: + { + /* Read the modem status register (MSR) to clear */ + + status = up_serialin(priv, LPC43_UART_MSR_OFFSET); + vdbg("MSR: %02x\n", status); + break; + } + + /* Just clear any line status interrupts */ + + case UART_IIR_INTID_RLS: + { + /* Read the line status register (LSR) to clear */ + + status = up_serialin(priv, LPC43_UART_LSR_OFFSET); + vdbg("LSR: %02x\n", status); + break; + } + + /* There should be no other values */ + + default: + { + dbg("Unexpected IIR: %02x\n", status); + break; + } + } + } + return OK; +} + +/**************************************************************************** + * Name: up_set_rs485_mode + * + * Description: + * Handle LPC43xx USART0,2,3 RS485 mode set ioctl (TIOCSRS485) to enable + * and disable RS-485 mode. This is part of the serial ioctl logic. + * + * Supported and un-supported LPC43 RS-485 features: + * + * RS-485/EIA-485 Normal Multidrop Mode (NMM) -- NOT suppored + * + * In this mode, an address is detected when a received byte causes the + * USART to set the parity error and generate an interrupt. When the + * parity error interrupt will be generated and the processor can decide + * whether or not to disable the receiver. + * + * RS-485/EIA-485 Auto Address Detection (AAD) mode -- NOT supported + * + * In this mode, the receiver will compare any address byte received + * (parity = �1�) to the 8-bit value programmed into the RS485ADRMATCH + * register. When a matching address character is detected it will be + * pushed onto the RXFIFO along with the parity bit, and the receiver + * will be automatically enabled. + * + * When an address byte which does not match the RS485ADRMATCH value + * is received, the receiver will be automatically disabled in hardware. + * + * RS-485/EIA-485 Auto Direction Control -- Supported + * + * Allow the transmitter to automatically control the state of the DIR + * pin as a direction control output signal. The DIR pin will be asserted + * (driven LOW) when the CPU writes data into the TXFIFO. The pin will be + * de-asserted (driven HIGH) once the last bit of data has been transmitted. + * + * RS485/EIA-485 driver delay time -- Supported + * + * The driver delay time is the delay between the last stop bit leaving + * the TXFIFO and the de-assertion of the DIR pin. This delay time can be + * programmed in the 8-bit RS485DLY register. The delay time is in periods + * of the baud clock. + * + * RS485/EIA-485 output inversion -- Supported + * + * The polarity of the direction control signal on the DIR pin can be + * reversed by programming bit 5 in the RS485CTRL register. + * + ****************************************************************************/ + +#ifdef HAVE_RS485 +static inline int up_set_rs485_mode(struct up_dev_s *priv, + const struct serial_rs485 *mode) +{ + irqstate_t flags; + uint32_t regval; + uint64_t tmp; + + DEBUGASSERT(priv && mode); + flags = enter_critical_section(); + + /* Are we enabling or disabling RS-485 support? */ + + if ((mode->flags && SER_RS485_RTS_ON_SEND) != 0) + { + /* Disable all RS-485 features */ + + up_serialout(priv, LPC43_UART_RS485CTRL_OFFSET, 0); + } + else + { + /* Set the RS-485/EIA-485 Control register: + * + * NMMEN 0 = Normal Multidrop Mode (NMM) disabled + * RXDIS 0 = Receiver is not disabled + * AADEN 0 = Auto Address Detect (ADD) is disabled + * DCTRL 1 = Auto Direction Control is enabled + * OINV ? = Value controlle by user mode settings + * SEL ? = Value controlled by user mode settings + */ + + regval = UART_RS485CTRL_DCTRL; + + /* Logic levels are controlled by the SER_RS485_RTS_ON_SEND and + * SER_RS485_RTS_AFTER_SEND bits in the mode flags. + * SER_RS485_RTS_AFTER_SEND is ignored. + * + * By default, DIR will go logic low on send, but this can + * be inverted. + */ + + if ((mode->flags && SER_RS485_RTS_ON_SEND) != 0) + { + regval |= UART_RS485CTRL_OINV; + } + +#ifdef BOARD_LPC43_UART1_DTRDIR + if (priv->dtrdir) + { + /* If we ar using DTR for direction then ensure the H/W is + * configured correctly. + */ + + regval |= UART_RS485CTRL_SEL; + } +#endif + + up_serialout(priv, LPC43_UART_RS485CTRL_OFFSET, regval); + + /* We only have control of the delay after send. Time provided + * is in milliseconds; this must be converted to the baud clock. + * The baud clock should be 16 times the currently selected BAUD. + * + * Eg. Given BAUD=115,200, then a delay of n milliseconds would be: + * + * 115,200 * n / 1000 = 11525 clocks. + * + * n=1: 115 (OK) + * n=2: 230 (OK) + * n>2: Out of range + * + * The valid range is 0 to 255 bit times. + * + * REVISIT: Is this time in bit time or in terms of the baud clock? + * The text says either interchange-ably. Baud clock is 16 x BAUD + * and a bit time is 1/BAUD. The value range of values 0-255 suggests + * BAUD bit times, not the baud clock. + */ + + if (mode->delay_rts_after_send > 0) + { + regval = 0; + } + else + { + tmp = ((priv->baud << 4) * mode->delay_rts_after_send) / 1000; + if (tmp > 255) + { + regval = 255; + } + else + { + regval = (uint32_t)tmp; + } + } + + + up_serialout(priv, LPC43_UART_RS485DLY_OFFSET, regval); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: up_get_rs485_mode + * + * Description: + * Handle LPC43xx USART0,2,3 RS485 mode get ioctl (TIOCGRS485) to get the + * current RS-485 mode. + * + ****************************************************************************/ + +#ifdef HAVE_RS485 +static inline int up_get_rs485_mode(struct up_dev_s *priv, + struct serial_rs485 *mode) +{ + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(priv && mode); + flags = enter_critical_section(); + + /* Assume disabled */ + + memset(mode, 0, sizeof(struct serial_rs485)); + + /* If RS-485 mode is enabled, then the DCTRL will be set in the RS485CTRL + * register. + */ + + regval = up_serialin(priv, LPC43_UART_RS485CTRL_OFFSET); + if ((regval & UART_RS485CTRL_DCTRL) != 0) + { + /* RS-485 mode is enabled */ + + mode->flags = SER_RS485_ENABLED; + + /* Check if DIR is inverted */ + + if ((regval & UART_RS485CTRL_OINV) != 0) + { + mode->flags = (SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND); + } + else + { + mode->flags = SER_RS485_ENABLED; + } + + /* We only have control of the delay after send. Time must be + * returned in milliseconds; this must be converted from the baud clock. + * (The baud clock should be 16 times the currently selected BAUD.) + * + * msec = 1000 * dly / baud + */ + + regval = up_serialin(priv, LPC43_UART_RS485DLY_OFFSET); + mode->delay_rts_after_send = (1000 * regval) / priv->baud; + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that only cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used besued we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + lpc43_setbaud(priv->uartbase, priv->basefreq, priv->baud); + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#ifdef HAVE_RS485 + case TIOCSRS485: /* Set RS485 mode, arg: pointer to struct serial_rs485 */ + { + ret = up_set_rs485_mode(priv, + (const struct serial_rs485 *)((uintptr_t)arg)); + } + break; + + case TIOCGRS485: /* Get RS485 mode, arg: pointer to struct serial_rs485 */ + { + ret = up_get_rs485_mode(priv, + (struct serial_rs485 *)((uintptr_t)arg)); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, LPC43_UART_LSR_OFFSET); + rbr = up_serialin(priv, LPC43_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_RBRIE; +#endif + } + else + { + priv->ier &= ~UART_IER_RBRIE; + } + + up_serialout(priv, LPC43_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC43_UART_LSR_OFFSET) & UART_LSR_RDR) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, LPC43_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_IER_THREIE; + up_serialout(priv, LPC43_UART_IER_OFFSET, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_IER_THREIE; + up_serialout(priv, LPC43_UART_IER_OFFSET, priv->ier); + } + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC43_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, LPC43_UART_LSR_OFFSET) & UART_LSR_THRE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */ + +#ifdef CONFIG_LPC43_USART0 +#ifndef CONFIG_USART0_SERIAL_CONSOLE + lpc43_usart0_setup(); +#endif + up_disableuartint(&g_uart0priv, NULL); +#endif + +#ifdef CONFIG_LPC43_UART1 +#ifndef CONFIG_UART1_SERIAL_CONSOLE + lpc43_uart1_setup(); +#endif + up_disableuartint(&g_uart1priv, NULL); +#endif + +#ifdef CONFIG_LPC43_USART2 +#ifndef CONFIG_USART2_SERIAL_CONSOLE + lpc43_usart2_setup(); +#endif + up_disableuartint(&g_uart2priv, NULL); +#endif + +#ifdef CONFIG_LPC43_USART3 +#ifndef CONFIG_USART3_SERIAL_CONSOLE + lpc43_usart3_setup(); +#endif + up_disableuartint(&g_uart3priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#ifdef HAVE_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/lpc43xx/lpc43_serial.h b/arch/arm/src/lpc43xx/lpc43_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..f29a99023af8564bd0ca37cfe989610f90777235 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_serial.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_serial.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_SERIAL_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "lpc43_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SERIAL_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_spi.c b/arch/arm/src/lpc43xx/lpc43_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..32b5a45913188bb7bc0d1f39dbfafdf51f41bc01 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_spi.c @@ -0,0 +1,602 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_spi.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc43_pinconfig.h" +#include "lpc43_spi.h" +#include "lpc43_ssp.h" + +#ifdef CONFIG_LPC43_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Enables debug output from this file (needs CONFIG_DEBUG too) */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# undef CONFIG_DEBUG_VERBOSE +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/* SPI Clocking. + * + * The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock (SPI_CLOCK). + * SPI_CLOCK may be further divided by 8-254 to get the SPI clock. If we + * want a usable range of 4KHz to 25MHz for the SPI, then: + * + * 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz), + * and + * 2. SPICLK must be less than (254*40Khz) = 101.6MHz. + * + * If we assume that CCLK less than or equal to 100MHz, we can just + * use the CCLK undivided to get the SPI_CLOCK. + */ + +#define SPI_CLOCK LPC43_CCLK + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes the state of the SSP driver */ + +struct lpc43_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = lpc43_spiselect, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc43_spistatus, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc43_spicmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc43_spiregister, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc43_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc43_spidev_s *priv = (FAR struct lpc43_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc43_spidev_s *priv = (FAR struct lpc43_spidev_s *)dev; + uint32_t divisor; + uint32_t actual; + + /* Check if the requested frequence is the same as the frequency selection */ + + DEBUGASSERT(priv && frequency <= SPI_CLOCK / 2); + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* frequency = SPI_CLOCK / divisor, or divisor = SPI_CLOCK / frequency */ + + divisor = SPI_CLOCK / frequency; + + /* The SPI CCR register must contain an even number greater than or equal to 8. */ + + if (divisor < 8) + { + divisor = 8; + } + else if (divisor > 254) + { + divisor = 254; + } + + divisor = (divisor + 1) & ~1; + + /* Save the new divisor value */ + + putreg32(divisor, LPC43_SPI_CCR); + + /* Calculate the new actual */ + + actual = SPI_CLOCK / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc43_spidev_s *priv = (FAR struct lpc43_spidev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC43_SPI_CR); + regval &= ~(SPI_CR_CPOL | SPI_CR_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CR_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CR_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CR_CPOL | SPI_CR_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + putreg32(regval, LPC43_SPI_CR); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc43_spidev_s *priv = (FAR struct lpc43_spidev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR appropriately */ + + regval = getreg32(LPC43_SPI_CR); + regval &= ~SPI_CR_BITS_MASK; + regval |= (nbits << SPI_CR_BITS_SHIFT) & SPI_CR_BITS_MASK; + regval |= SPI_CR_BITENABLE; + regval = getreg32(LPC43_SPI_CR); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + /* Write the data to transmitted to the SPI Data Register */ + + putreg32((uint32_t)wd, LPC43_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC43_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC43_SPI_SR); + return (uint16_t)getreg32(LPC43_SPI_DR); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + uint8_t data; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + data = *ptr++; + putreg32((uint32_t)data, LPC43_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC43_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC43_SPI_SR); + nwords--; + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write some dummy data to the SPI Data Register in order to clock the + * read data. + */ + + putreg32(0xff, LPC43_SPI_DR); + + /* Wait for the SPIF bit in the SPI Status Register to be set to 1. The + * SPIF bit will be set after the last sampling clock edge of the SPI + * data transfer. + */ + + while ((getreg32(LPC43_SPI_SR) & SPI_SR_SPIF) == 0); + + /* Read the SPI Status Register again to clear the status bit */ + + (void)getreg32(LPC43_SPI_SR); + + /* Read the received data from the SPI Data Register */ + + *ptr++ = (uint8_t)getreg32(LPC43_SPI_DR); + nwords--; + } +} + +/**************************************************************************** + * Name: lpc43_spiport_initialize + * + * Description: + * Initialize the SPI port + * + * Input Parameter: + * port Port number (must be zero) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +static FAR struct spi_dev_s *lpc43_spiport_initialize(int port) +{ + FAR struct lpc43_spidev_s *priv = &g_spidev; + + /* Configure multiplexed pins as connected on the board. Chip select + * pins must be configured by board-specific logic. All SPI pins and + * one SPI1 pin (SCK) have multiple, alternative pin selections. + * Definitions in the board.h file must be provided to resolve the + * board-specific pin configuration like: + * + * #define PINCONF_SPI_SCK PINCONF_SPI_SCK_1 + */ + + lpc43_pin_config(PINCONF_SPI_SCK); + lpc43_pin_config(PINCONF_SPI_MISO); + lpc43_pin_config(PINCONF_SPI_MOSI); + + /* Configure 8-bit SPI mode and master mode */ + + putreg32(SPI_CR_BITS_8BITS | SPI_CR_BITENABLE | SPI_CR_MSTR, LPC43_SPI_CR); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + return &priv->spidev; +} +#endif /* CONFIG_LPC43_SPI */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * 0 - SPI + * 1 - SSP0 + * 2 - SSP1 + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc43_spibus_initialize(int port) +{ + if (port) + { +#if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) + return lpc43_sspbus_initialize(port - 1); +#else + return NULL; +#endif + } + else + { +#if defined(CONFIG_LPC43_SPI) + return lpc43_spiport_initialize(port); +#else + return NULL; +#endif + } +} diff --git a/arch/arm/src/lpc43xx/lpc43_spi.h b/arch/arm/src/lpc43xx/lpc43_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..42ade41b1a843f3de9762fcf6ba0f3027dd79e64 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_spi.h @@ -0,0 +1,180 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_spi.h + * + * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_SPI_H +#define __ARCH_ARM_SRC_LPC43XX_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip/lpc43_spi.h" + +#ifdef CONFIG_LPC43_SPI + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* This header file defines interfaces to common SPI logic. To use this common SPI + * logic on your board: + * + * 1. Provide logic in lpc43_boardinitialize() to configure SPI chip select pins. + * 2. Provide the lpc43_spiselect() and lpc43_spistatus() functions in your + * board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc43_spicmddata() functions in your board-specific logic. This + * function will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Your low level board initialization logic should call lpc43_spibus_initialize. + * 5. The handle returned by lpc43_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * 0 - SPI + * 1 - SSP0 + * 2 - SSP1 + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc43_spibus_initialize(int port); + +/************************************************************************************ + * Name: lpc43_spiselect, lpc43_spistatus, and lpc43_spicmddata + * + * Description: + * These functions must be provided in your board-specific logic. The + * lpc43_spiselect function will perform chip selection and the lpc43_spistatus + * will perform status operations using GPIOs in the way your board is configured. + * + * If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, then + * lpc43_spicmddata must also be provided. This functions performs cmd/data + * selection operations using GPIOs in the way your board is configured. + * + ************************************************************************************/ + +void lpc43_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc43_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); + +#ifdef CONFIG_SPI_CMDDATA +int lpc43_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: spi_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called from + * spiselect after a device is deselected (if you worry about such things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ************************************************************************************/ + +void spi_flush(FAR struct spi_dev_s *dev); + +/************************************************************************************ + * Name: lpc43_spi/spiregister + * + * Description: + * If the board supports a card detect callback to inform the SPI-based MMC/SD + * driver when an SD card is inserted or removed, then CONFIG_SPI_CALLBACK should + * be defined and the following function(s) must must be implemented. These + * functions implements the registercallback method of the SPI interface (see + * include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +int lpc43_spiregister(FAR struct spi_dev_s *dev, spi_mediachange_t callback, void *arg); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_SPI */ +#endif /* __ARCH_ARM_SRC_LPC43XX_SPI_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_spifi.c b/arch/arm/src/lpc43xx/lpc43_spifi.c new file mode 100644 index 0000000000000000000000000000000000000000..0d90ea9fceb15b162652c9a627e1888c160ef990 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_spifi.c @@ -0,0 +1,1271 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_spifi.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "lpc43_cgu.h" +#include "lpc43_spifi.h" +#include "lpc43_pinconfig.h" +#include "spifi/inc/spifilib_api.h" + +#ifdef CONFIG_LPC43_SPIFI_FIXME + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* SPIFI Configuration ******************************************************/ +/* This logic supports some special options that can be used to create an + * mtd device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y must also + * be defined to enable SPIFI setup support: + * + * CONFIG_SPIFI_READONLY - Create a read only device on SPIFI. + * CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many + * bytes into the device address space. This offset must be an exact + * multiple of the erase block size. Default 0. + * CONFIG_SPIFI_BLKSIZE - The size of one device erase block. If not defined + * then the driver will try to determine the correct erase block size by + * examining that data returned from spifi_initialize (which sometimes + * seems bad). + * CONFIG_SPIFI_SECTOR512 - If defined, then the driver will report a more + * FAT friendly 512 byte sector size and will manage the read-modify-write + * operations on the larger erase block. + * CONFIG_SPIFI_READONLY - Define to support only read-only operations. + * CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead, + * use an external library implementation of the SPIFI interface. + * CONFIG_SPIFI_VERIFY - Verify all spi_program() operations by reading + * from the SPI address space after each write. + * CONFIG_DEBUG_SPIFI_DUMP - Debug option to dump read/write buffers. You + * probably do not want to enable this unless you want to dig through a + * *lot* of debug output! Also required CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, + * and CONFIG_DEBUG_FS, + */ + +/* This is where the LPC43xx address where random-access reads begin */ + +#define SPIFI_BASE \ + (FAR uint8_t *)(LPC43_SPIFI_DATA_BASE + CONFIG_SPIFI_OFFSET) + +/* Check if we are using a hard-coded block size */ + +#ifdef CONFIG_SPIFI_BLKSIZE +# if CONFIG_SPIFI_BLKSIZE < 512 +# error "CONFIG_SPIFI_BLKSIZE is too small" +# elif CONFIG_SPIFI_BLKSIZE == 512 +# define SPIFI_BLKSHIFT 9 +# elif CONFIG_SPIFI_BLKSIZE == 1024 +# define SPIFI_BLKSHIFT 10 +# elif CONFIG_SPIFI_BLKSIZE == (2*1024) +# define SPIFI_BLKSHIFT 11 +# elif CONFIG_SPIFI_BLKSIZE == (4*1024) +# define SPIFI_BLKSHIFT 12 +# elif CONFIG_SPIFI_BLKSIZE == (8*1024) +# define SPIFI_BLKSHIFT 13 +# elif CONFIG_SPIFI_BLKSIZE == (16*1024) +# define SPIFI_BLKSHIFT 14 +# elif CONFIG_SPIFI_BLKSIZE == (32*1024) +# define SPIFI_BLKSHIFT 15 +# elif CONFIG_SPIFI_BLKSIZE == (64*1024) +# define SPIFI_BLKSHIFT 16 +# elif CONFIG_SPIFI_BLKSIZE == (128*1024) +# define SPIFI_BLKSHIFT 17 +# elif CONFIG_SPIFI_BLKSIZE == (256*1024) +# define SPIFI_BLKSHIFT 18 +# else +# error "Unsupported value of CONFIG_SPIFI_BLKSIZE" +# endif +# define SPIFI_BLKSIZE CONFIG_SPIFI_BLKSIZE +#else +# define SPIFI_BLKSIZE priv->blksize +# define SPIFI_BLKSHIFT priv->blkshift +#endif + +/* Can use ROM driver or an external driver library */ + +#ifndef CONFIG_SPIFI_LIBRARY +# define SPIFI_INIT(priv, rom, cshigh, options, mhz) \ + priv->spifi->spifi_init(rom, cshigh, options, mhz) +# define SPIFI_PROGRAM(priv, rom, src, operands) \ + priv->spifi->spifi_program(rom, src, operands) +# define SPIFI_ERASE(priv, rom, operands) \ + priv->spifi->spifi_erase(rom, operands) +#else +# define SPIFI_INIT(priv, rom, cshigh, options, mhz) \ + spifiInit(rom, cshigh, options, mhz) +# define SPIFI_PROGRAM(priv, rom, src, operands) \ + spifiProgram(rom, src, operands) +# define SPIFI_ERASE(priv, rom, operands) \ + spifiErase(rom, operands) +#endif + +/* 512 byte sector simulation */ + +#ifdef CONFIG_SPIFI_SECTOR512 /* Emulate a 512 byte sector */ +# define SPIFI_512SHIFT 9 /* Sector size 1 << 9 = 512 bytes */ +# define SPIFI_512SIZE 512 /* Sector size = 512 bytes */ +#endif + +#define SPIFI_ERASED_STATE 0xff /* State of FLASH when erased */ + +/* Cache flags */ + +#define SST25_CACHE_VALID (1 << 0) /* 1=Cache has valid data */ +#define SST25_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */ +#define SST25_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */ + +#define IS_VALID(p) ((((p)->flags) & SST25_CACHE_VALID) != 0) +#define IS_DIRTY(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0) +#define IS_ERASED(p) ((((p)->flags) & SST25_CACHE_ERASED) != 0) + +#define SET_VALID(p) do { (p)->flags |= SST25_CACHE_VALID; } while (0) +#define SET_DIRTY(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0) +#define SET_ERASED(p) do { (p)->flags |= SST25_CACHE_ERASED; } while (0) + +#define CLR_VALID(p) do { (p)->flags &= ~SST25_CACHE_VALID; } while (0) +#define CLR_DIRTY(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0) +#define CLR_ERASED(p) do { (p)->flags &= ~SST25_CACHE_ERASED; } while (0) + +/* Select the divider to use as SPIFI input based on definitions in the + * board.h header file. + */ + +#if defined(BOARD_SPIFI_PLL1) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_PLL1 +#elif defined(BOARD_SPIFI_DIVA) +# define LPC43_IDIV_CTRL LPC43_IDIVA_CTRL +# define IDIV_CTRL_PD IDIVA_CTRL_PD +# define IDIV_CTRL_IDIV_MASK IDIVA_CTRL_IDIV_MASK +# define IDIV_CTRL_IDIV IDIVA_CTRL_IDIV(BOARD_SPIFI_DIVIDER) +# define IDIV_CTRL_IDIV_MAX 4 +# define IDIV_CTRL_CLKSEL_MASK IDIVA_CTRL_CLKSEL_MASK +# define IDIV_CTRL_CLKSEL_PLL1 (IDIVA_CLKSEL_PLL1 | IDIVA_CTRL_AUTOBLOCK) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_IDIVA +#elif defined(BOARD_SPIFI_DIVB) +# define LPC43_IDIV_CTRL LPC43_IDIVB_CTRL +# define IDIV_CTRL_PD IDIVBCD_CTRL_PD +# define IDIV_CTRL_IDIV_MASK IDIVBCD_CTRL_IDIV_MASK +# define IDIV_CTRL_IDIV IDIVBCD_CTRL_IDIV(BOARD_SPIFI_DIVIDER) +# define IDIV_CTRL_IDIV_MAX 16 +# define IDIV_CTRL_CLKSEL_MASK IDIVBCD_CTRL_CLKSEL_MASK +# define IDIV_CTRL_CLKSEL_PLL1 (IDIVBCD_CLKSEL_PLL1 | IDIVBCD_CTRL_AUTOBLOCK) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_IDIVB +#elif defined(BOARD_SPIFI_DIVC) +# define LPC43_IDIV_CTRL LPC43_IDIVC_CTRL +# define IDIV_CTRL_PD IDIVBCD_CTRL_PD +# define IDIV_CTRL_IDIV_MASK IDIVBCD_CTRL_IDIV_MASK +# define IDIV_CTRL_IDIV IDIVBCD_CTRL_IDIV(BOARD_SPIFI_DIVIDER) +# define IDIV_CTRL_IDIV_MAX 16 +# define IDIV_CTRL_CLKSEL_MASK IDIVBCD_CTRL_CLKSEL_MASK +# define IDIV_CTRL_CLKSEL_PLL1 (IDIVBCD_CLKSEL_PLL1 | IDIVBCD_CTRL_AUTOBLOCK) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_IDIVC +#elif defined(BOARD_SPIFI_DIVD) +# define LPC43_IDIV_CTRL LPC43_IDIVD_CTRL +# define IDIV_CTRL_PD IDIVBCD_CTRL_PD +# define IDIV_CTRL_IDIV_MASK IDIVBCD_CTRL_IDIV_MASK +# define IDIV_CTRL_IDIV IDIVBCD_CTRL_IDIV(BOARD_SPIFI_DIVIDER) +# define IDIV_CTRL_IDIV_MAX 16 +# define IDIV_CTRL_CLKSEL_MASK IDIVBCD_CTRL_CLKSEL_MASK +# define IDIV_CTRL_CLKSEL_PLL1 (IDIVBCD_CLKSEL_PLL1 | IDIVBCD_CTRL_AUTOBLOCK) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_IDIVD +#elif defined(BOARD_SPIFI_DIVE) +# define LPC43_IDIV_CTRL LPC43_IDIVE_CTRL +# define IDIV_CTRL_PD IDIVE_CTRL_PD +# define IDIV_CTRL_IDIV_MASK IDIVE_CTRL_IDIV_MASK +# define IDIV_CTRL_IDIV IDIVE_CTRL_IDIV(BOARD_SPIFI_DIVIDER) +# define IDIV_CTRL_IDIV_MAX 256 +# define IDIV_CTRL_CLKSEL_MASK IDIVE_CTRL_CLKSEL_MASK +# define IDIV_CTRL_CLKSEL_PLL1 (IDIVE_CLKSEL_PLL1 | IDIVE_CTRL_AUTOBLOCK) +# define BASE_SPIFI_CLKSEL BASE_SPIFI_CLKSEL_IDIVE +#endif + +#if BOARD_SPIFI_DIVIDER < 1 || BOARD_SPIFI_DIVIDER > IDIV_CTRL_IDIV_MAX +# error "Invalid value for BOARD_SPIFI_DIVIDER" +#endif + +/* SPIFI_CSHIGH should be one less than the minimum number of clock cycles + * with the CS pin high, that the SPIFI should maintain between commands. + * Compute this from the SPIFI clock period and the minimum high time of CS + * from the serial flash data sheet: + * + * csHigh = ceiling(min CS high / SPIFI clock period) - 1 + * + * where ceiling means round up to the next higher integer if the argument + * isn't an integer. + */ + +#define SPIFI_CSHIGH 9 + +/* The final parameter of the spifi_init() ROM driver call should be the + * serial clock rate divided by 1000000, rounded to an integer. The SPIFI + * supports transfer rates of up to SPIFI_CLK/2 bytes per second. The SPIF_CLK + * is the output of the LPC43_BASE_SPIFI_CLK configured above; The frequency should + * be given by BOARD_SPIFI_FREQUENCY as provided by the board.h header file. + */ + +#define SCLK_MHZ (BOARD_SPIFI_FREQUENCY + (1000000 / 2)) / 1000000 + +/* DEBUG options to dump read/write buffers. You probably do not want to + * enable this unless you want to dig through a *lot* of debug output! + */ + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_FS) +# undef CONFIG_DEBUG_SPIFI_DUMP +#endif + +#ifdef CONFIG_DEBUG_SPIFI_DUMP +# define lpc43_dumpbuffer(m,b,n) lib_dumpbuffer(m,b,n); +#else +# define lpc43_dumpbuffer(m,b,n) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type represents the state of the MTD device. The struct mtd_dev_s must + * appear at the beginning of the definition so that you can freely cast between + * pointers to struct mtd_dev_s and struct lpc43_dev_s. + */ + +struct lpc43_dev_s +{ + struct mtd_dev_s mtd; /* MTD interface */ +#ifndef CONFIG_SPIFI_LIBRARY + FAR struct spifi_driver_s *spifi; /* Pointer to ROM driver table */ +#endif + FAR struct spifi_dev_s rom; /* Needed for communication with ROM driver */ + struct spifi_operands_s operands; /* Needed for program and erase ROM calls */ + uint16_t nblocks; /* Number of blocks of size blksize */ +#ifndef CONFIG_SPIFI_BLKSIZE + uint8_t blkshift; /* Log2 of erase block size */ + uint32_t blksize; /* Size of one erase block (up to 256K) */ +#endif + +#if defined(CONFIG_SPIFI_SECTOR512) && !defined(CONFIG_SPIFI_READONLY) + uint8_t flags; /* Buffered sector flags */ + uint16_t blkno; /* Erase block number in the cache */ + FAR uint8_t *cache; /* Allocated sector data */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static void lpc43_blockerase(FAR struct lpc43_dev_s *priv, off_t offset); +static inline int lpc43_chiperase(FAR struct lpc43_dev_s *priv); +static inline void lpc43_pageread(FAR struct lpc43_dev_s *priv, + FAR uint8_t *dest, FAR const uint8_t *src, + size_t nbytes); +#ifndef CONFIG_SPIFI_READONLY +#ifdef CONFIG_SPIFI_VERIFY +static int lpc43_verify(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest, + FAR const uint8_t *src, size_t nbytes); +#endif +static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest, + FAR const uint8_t *src, size_t nbytes); +#ifdef CONFIG_SPIFI_SECTOR512 +static void lpc43_cacheflush(struct lpc43_dev_s *priv); +static FAR uint8_t *lpc43_cacheread(struct lpc43_dev_s *priv, off_t sector); +static void lpc43_cacheerase(struct lpc43_dev_s *priv, off_t sector); +static void lpc43_cachewrite(FAR struct lpc43_dev_s *priv, FAR const uint8_t *buffer, + off_t sector, size_t nsectors); +#endif +#endif + +/* MTD driver methods */ + +static int lpc43_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); +static ssize_t lpc43_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t lpc43_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR uint8_t *buffer); +static int lpc43_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); + +/* Initialization */ + +#ifndef BOARD_SPIFI_PLL1 +static inline void lpc43_idiv_clkconfig(void); +#endif + +static inline void lpc43_spifi_clkconfig(void); +static inline void lpc43_spifi_pinconfig(void); +static inline int lpc43_rominit(FAR struct lpc43_dev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Only a single SPIFI driver instance is supported */ + +static struct lpc43_dev_s g_spifi; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_blockerase + ****************************************************************************/ + +static void lpc43_blockerase(struct lpc43_dev_s *priv, off_t sector) +{ + int result; + + /* Erase one block on the chip: + * + * dest - Specifies the first address to be programmed or erased, either in + * the SPIFI memory area or as a zero-based device address. It must + * be at an offset that is an exact multiple of the erase block size. + * length - The number of bytes to be programmed or erased + */ + + priv->operands.dest = SPIFI_BASE + (sector << SPIFI_BLKSHIFT); + priv->operands.length = SPIFI_BLKSIZE; + + fvdbg("SPIFI_ERASE: dest=%p length=%d\n", + priv->operands.dest, priv->operands.length); + + result = SPIFI_ERASE(priv, &priv->rom, &priv->operands); + if (result != 0) + { + fdbg("ERROR: SPIFI_ERASE failed: %05x\n", result); + } +} + +/**************************************************************************** + * Name: lpc43_chiperase + ****************************************************************************/ + +static inline int lpc43_chiperase(struct lpc43_dev_s *priv) +{ + int result; + + /* Erase the entire chip: + * + * dest - Specifies the first address to be programmed or erased, either in + * the SPIFI memory area or as a zero-based device address. It must + * be at an offset that is an exact multiple of the erase block size. + * length - The number of bytes to be programmed or erased + */ + + priv->operands.dest = SPIFI_BASE; + priv->operands.length = SPIFI_BLKSIZE * priv->nblocks; + + fvdbg("SPIFI_ERASE: dest=%p length=%d\n", + priv->operands.dest, priv->operands.length); + + result = SPIFI_ERASE(priv, &priv->rom, &priv->operands); + if (result != 0) + { + fdbg("ERROR: SPIFI_ERASE failed: %05x\n", result); + return -EIO; + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_pagewrite + ****************************************************************************/ + +#if !defined(CONFIG_SPIFI_READONLY) && defined(CONFIG_SPIFI_VERIFY) +static int lpc43_verify(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest, + FAR const uint8_t *src, size_t nbytes) +{ + return memcmp(src, dest, nbytes) != 0 ? -EIO : OK; +} +#endif + +/**************************************************************************** + * Name: lpc43_pagewrite + ****************************************************************************/ + +#ifndef CONFIG_SPIFI_READONLY +static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest, + FAR const uint8_t *src, size_t nbytes) +{ + int result; + + /* Write FLASH pages: + * + * dest - Specifies the first address to be programmed or erased, either in + * the SPIFI memory area or as a zero-based device address. It must + * be at an offset that is an exact multiple of the erase block size. + * length - The number of bytes to be programmed or erased + */ + + priv->operands.dest = dest; + priv->operands.length = nbytes; + + fvdbg("SPIFI_PROGRAM: src=%p dest=%p length=%d\n", + src, priv->operands.dest, priv->operands.length); + + result = SPIFI_PROGRAM(priv, &priv->rom, src, &priv->operands); + if (result != 0) + { + fdbg("ERROR: SPIFI_PROGRAM failed: %05x\n", result); + return -EIO; + } + + /* Verify the data that was written by comparing to the data visible in the + * SPIFI address space. + */ + +#ifdef CONFIG_SPIFI_VERIFY + result = lpc43_verify(priv, dest, src, nbytes); + if (result != 0) + { + fdbg("ERROR: lpc43_verify failed: %05x\n", result); + return -EIO; + } +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc43_pageread + ****************************************************************************/ + +static inline void lpc43_pageread(FAR struct lpc43_dev_s *priv, + FAR uint8_t *dest, FAR const uint8_t *src, + size_t nbytes) +{ + fvdbg("src=%p dest=%p length=%d\n", src, dest, nbytes); + memcpy(dest, src, nbytes); +} + +/**************************************************************************** + * Name: lpc43_cacheflush + ****************************************************************************/ + +#if defined(CONFIG_SPIFI_SECTOR512) && !defined(CONFIG_SPIFI_READONLY) +static void lpc43_cacheflush(struct lpc43_dev_s *priv) +{ + FAR uint8_t *dest; + int ret; + + /* If the cached is dirty (meaning that it no longer matches the old FLASH contents) + * or was erased (with the cache containing the correct FLASH contents), then write + * the cached erase block to FLASH. + */ + + fvdbg("flags: %02x blkno: %d\n", priv->flags, priv->blkno); + if (IS_DIRTY(priv) || IS_ERASED(priv)) + { + /* Get the SPIFI address corresponding to the cached erase block */ + + dest = SPIFI_BASE + ((off_t)priv->blkno << SPIFI_BLKSHIFT); + + /* Write entire erase block to FLASH */ + + ret = lpc43_pagewrite(priv, dest, priv->cache, SPIFI_BLKSIZE); + if (ret < 0) + { + fdbg("ERROR: lpc43_pagewrite failed: %d\n", ret); + } + + /* The case is no long dirty and the FLASH is no longer erased */ + + CLR_DIRTY(priv); + CLR_ERASED(priv); + } +} +#endif + +/**************************************************************************** + * Name: lpc43_cacheread + ****************************************************************************/ + +#if defined(CONFIG_SPIFI_SECTOR512) && !defined(CONFIG_SPIFI_READONLY) +static FAR uint8_t *lpc43_cacheread(struct lpc43_dev_s *priv, off_t sector) +{ + FAR const uint8_t *src; + off_t blkno; + int index; + + /* Convert from the 512 byte sector to the erase sector size of the device. For + * exmample, if the actual erase sector size if 4Kb (1 << 12), then we first + * shift to the right by 3 to get the sector number in 4096 increments. + */ + + blkno = sector >> (SPIFI_BLKSHIFT - SPIFI_512SHIFT); + fvdbg("sector: %ld blkno: %d\n", sector, blkno); + + /* Check if the requested erase block is already in the cache */ + + if (!IS_VALID(priv) || blkno != (off_t)priv->blkno) + { + /* No.. Flush any dirty erase block currently in the cache */ + + lpc43_cacheflush(priv); + + /* Read the new erase block into the cache */ + /* Get the SPIFI address corresponding to the new erase block */ + + src = SPIFI_BASE + (blkno << SPIFI_BLKSHIFT); + + /* Read the entire erase block from FLASH */ + + lpc43_pageread(priv, priv->cache, src, SPIFI_BLKSIZE); + + /* Mark the sector as cached */ + + priv->blkno = (uint16_t)blkno; + + SET_VALID(priv); /* The data in the cache is valid */ + CLR_DIRTY(priv); /* It should match the FLASH contents */ + CLR_ERASED(priv); /* The underlying FLASH has not been erased */ + } + + /* Get the index to the 512 sector in the erase block that holds the argument */ + + index = sector & ((1 << (SPIFI_BLKSHIFT - SPIFI_512SHIFT)) - 1); + + /* Return the address in the cache that holds this sector */ + + return &priv->cache[index << SPIFI_512SHIFT]; +} +#endif + +/**************************************************************************** + * Name: lpc43_cacheerase + ****************************************************************************/ + +#if defined(CONFIG_SPIFI_SECTOR512) && !defined(CONFIG_SPIFI_READONLY) +static void lpc43_cacheerase(struct lpc43_dev_s *priv, off_t sector) +{ + FAR uint8_t *dest; + + /* First, make sure that the erase block containing the 512 byte sector is in + * the cache. + */ + + dest = lpc43_cacheread(priv, sector); + + /* Erase the block containing this sector if it is not already erased. + * The erased indicated will be cleared when the data from the erase sector + * is read into the cache and set here when we erase the block. + */ + + if (!IS_ERASED(priv)) + { + off_t blkno = sector >> (SPIFI_BLKSHIFT - SPIFI_512SHIFT); + fvdbg("sector: %ld blkno: %d\n", sector, blkno); + + lpc43_blockerase(priv, blkno); + SET_ERASED(priv); + } + + /* Put the cached sector data into the erase state and mart the cache as dirty + * (but don't update the FLASH yet. The caller will do that at a more optimal + * time). + */ + + memset(dest, SPIFI_ERASED_STATE, SPIFI_512SIZE); + SET_DIRTY(priv); +} +#endif + +/**************************************************************************** + * Name: lpc43_cachewrite + ****************************************************************************/ + +#if defined(CONFIG_SPIFI_SECTOR512) && !defined(CONFIG_SPIFI_READONLY) +static void lpc43_cachewrite(FAR struct lpc43_dev_s *priv, FAR const uint8_t *buffer, + off_t sector, size_t nsectors) +{ + FAR uint8_t *dest; + + for (; nsectors > 0; nsectors--) + { + /* First, make sure that the erase block containing 512 byte sector is in + * memory. + */ + + dest = lpc43_cacheread(priv, sector); + + fvdbg("dest=%p src=%p sector: %ld flags: %02x\n", + dest, buffer, sector, priv->flags); + + /* Erase the block containing this sector if it is not already erased. + * The erased indicated will be cleared when the data from the erase sector + * is read into the cache and set here when we erase the sector. + */ + + if (!IS_ERASED(priv)) + { + off_t blkno = sector >> (SPIFI_BLKSHIFT - SPIFI_512SHIFT); + fvdbg("sector: %ld blkno: %d\n", sector, blkno); + + lpc43_blockerase(priv, blkno); + SET_ERASED(priv); + } + + /* Copy the new sector data into cached erase block */ + + memcpy(dest, buffer, SPIFI_512SIZE); + SET_DIRTY(priv); + + /* Set up for the next 512 byte sector */ + + buffer += SPIFI_512SIZE; + sector++; + } + + /* Flush the last erase block left in the cache */ + + lpc43_cacheflush(priv); +} +#endif + +/**************************************************************************** + * Name: lpc43_erase + ****************************************************************************/ + +static int lpc43_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) +{ +#ifdef CONFIG_SPIFI_READONLY + return -EACESS +#else + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + size_t blocksleft = nblocks; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + while (blocksleft-- > 0) + { + /* Erase each sector */ + +#ifdef CONFIG_SPIFI_SECTOR512 + lpc43_cacheerase(priv, startblock); +#else + lpc43_blockerase(priv, startblock); +#endif + startblock++; + } + +#ifdef CONFIG_SPIFI_SECTOR512 + /* Flush the last erase block left in the cache */ + + lpc43_cacheflush(priv); +#endif + + return (int)nblocks; +#endif +} + +/**************************************************************************** + * Name: lpc43_bread + ****************************************************************************/ + +static ssize_t lpc43_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, + FAR uint8_t *buffer) +{ +#ifdef CONFIG_SPIFI_SECTOR512 + ssize_t nbytes; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* On this device, we can handle the block read just like the byte-oriented read */ + + nbytes = lpc43_read(dev, startblock << SPIFI_512SHIFT, + nblocks << SPIFI_512SHIFT, buffer); + if (nbytes > 0) + { + lpc43_dumpbuffer(__func__, buffer, nbytes) + return nbytes >> SPIFI_512SHIFT; + } + + return (int)nbytes; +#else + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + ssize_t nbytes; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* On this device, we can handle the block read just like the byte-oriented read */ + + nbytes = lpc43_read(dev, startblock << SPIFI_BLKSHIFT, + nblocks << SPIFI_BLKSHIFT, buffer); + if (nbytes > 0) + { + lpc43_dumpbuffer(__func__, buffer, nbytes) + return nbytes >> SPIFI_BLKSHIFT; + } + + return (int)nbytes; +#endif +} + +/**************************************************************************** + * Name: lpc43_bwrite + ****************************************************************************/ + +static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, + FAR const uint8_t *buffer) +{ +#if defined(CONFIG_SPIFI_READONLY) + + return -EACCESS; + +#elif defined(CONFIG_SPIFI_SECTOR512) + + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + lpc43_cachewrite(priv, buffer, startblock, nblocks); + + lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_512SHIFT) + return nblocks; + +#else + + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + FAR uint8_t *dest; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* Get the SPIFI address corresponding to the erase block */ + + dest = SPIFI_BASE + (startblock << SPIFI_BLKSHIFT); + +#if defined(CONFIG_SPIFI_SECTOR512) + /* Write all of the erase blocks to FLASH */ + + ret = lpc43_pagewrite(priv, dest, buffer, nblocks << SPIFI_512SHIFT); + if (ret < 0) + { + fdbg("ERROR: lpc43_pagewrite failed: %d\n", ret); + return ret; + } +#endif + + lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_BLKSHIFT) + return nblocks; + +#endif +} + +/**************************************************************************** + * Name: lpc43_read + ****************************************************************************/ + +static ssize_t lpc43_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR uint8_t *buffer) +{ + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + FAR const uint8_t *src; + + fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + + /* Get the SPIFI address corresponding sector */ + + src = SPIFI_BASE + offset; + + /* Read FLASH contents into the user buffer */ + + lpc43_pageread(priv, buffer, src, nbytes); + + fvdbg("return nbytes: %d\n", (int)nbytes); + return nbytes; +} + +/**************************************************************************** + * Name: lpc43_ioctl + ****************************************************************************/ + +static int lpc43_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct lpc43_dev_s *priv = (FAR struct lpc43_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + fvdbg("cmd: %d \n", cmd); + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg); + if (geo) + { + /* Populate the geometry structure with information need to know + * the capacity and how to access the device. + * + * NOTE: that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but the client + * will expect the device logic to do whatever is necessary to make it + * appear so. + */ + +#ifdef CONFIG_SPIFI_SECTOR512 + geo->blocksize = 512; + geo->erasesize = 512; + geo->neraseblocks = priv->nblocks << (SPIFI_BLKSHIFT - SPIFI_512SHIFT); +#else + geo->blocksize = SPIFI_BLKSIZE; + geo->erasesize = SPIFI_BLKSIZE; + geo->neraseblocks = priv->nblocks; +#endif + ret = OK; + + fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + break; + + case MTDIOC_BULKERASE: + { + /* Erase the entire device */ + + ret = lpc43_chiperase(priv); + } + break; + + case MTDIOC_XIPBASE: + default: + ret = -ENOTTY; /* Bad command */ + break; + } + + fvdbg("return %d\n", ret); + return ret; +} + +/**************************************************************************** + * Name: lpc43_idiv_clkconfig + * + * Description: + * Configure PLL1 as the input to the selected divider and enable the + * divider. + * + ****************************************************************************/ + +#ifndef BOARD_SPIFI_PLL1 +static inline void lpc43_idiv_clkconfig(void) +{ + uint32_t regval; + + /* Configure PLL1 as the input to the selected divider */ + + regval = getreg32(LPC43_IDIV_CTRL); + regval &= ~IDIV_CTRL_CLKSEL_MASK; + regval |= IDIV_CTRL_CLKSEL_PLL1; + putreg32(regval, LPC43_IDIV_CTRL); + + /* Enable the divider (by making sure that the power down bit is clear) */ + + regval &= ~IDIV_CTRL_PD; + putreg32(regval, LPC43_IDIV_CTRL); + + /* Set the divider value */ + + regval &= ~IDIVA_CTRL_IDIV_MASK; + regval |= IDIV_CTRL_IDIV; + putreg32(regval, LPC43_IDIV_CTRL); +} +#else +# define lpc43_idiv_clkconfig() +#endif + +/**************************************************************************** + * Name: lpc43_spifi_clkconfig + * + * Description: + * Configure the selected divider (or PLL1) as the input to the SPIFI + * and enable the SPIFI clock. + * + ****************************************************************************/ + +static inline void lpc43_spifi_clkconfig(void) +{ + uint32_t regval; + + /* Configure the selected divider (or PLL1) as the input to the SPIFI */ + + regval = getreg32(LPC43_BASE_SPIFI_CLK); + regval &= ~BASE_SPIFI_CLK_CLKSEL_MASK; + regval |= BASE_SPIFI_CLKSEL; + putreg32(regval, LPC43_BASE_SPIFI_CLK); + + /* Enable the SPIFI clocking (by making sure that the power down bit is + * clear) + */ + + regval &= ~IDIVA_CTRL_PD; + putreg32(regval, LPC43_BASE_SPIFI_CLK); +} + +/**************************************************************************** + * Name: lpc43_spifi_pinconfig + * + * Description: + * Configure SPIFI pins + * + ****************************************************************************/ + +static inline void lpc43_spifi_pinconfig(void) +{ + /* Configure SPIFI pins */ + + lpc43_pin_config(PINCONF_SPIFI_CS); /* Input buffering not needed */ + lpc43_pin_config(PINCONF_SPIFI_MISO); /* High drive for SCLK */ + lpc43_pin_config(PINCONF_SPIFI_MOSI); + lpc43_pin_config(PINCONF_SPIFI_SCK); + lpc43_pin_config(PINCONF_SPIFI_SIO2); + lpc43_pin_config(PINCONF_SPIFI_SIO3); +} + +/**************************************************************************** + * Name: lpc43_rominit + * + * Description: + * Initialize the SPIFI ROM driver + * + ****************************************************************************/ + +static inline int lpc43_rominit(FAR struct lpc43_dev_s *priv) +{ +#ifndef CONFIG_SPIFI_BLKSIZE + FAR struct spfi_desc_s *desc; + uint16_t sectors; + uint8_t log2; +#endif + int32_t result; + + /* Get the pointer to the SPIFI ROM driver table. */ + +#ifndef CONFIG_SPIFI_LIBRARY + priv->spifi = *((struct spifi_driver_s **)SPIFI_ROM_PTR); +#endif + + /* The final parameter of the spifi_init() ROM driver call should be the + * serial clock rate divided by 1000000, rounded to an integer. The SPIFI + * supports transfer rates of up to SPIFI_CLK/2 bytes per second. The SPIF_CLK + * is the output of the LPC43_BASE_SPIFI_CLK configured above; The frequency should + * be given by BOARD_SPIFI_FREQUENCY as provided by the board.h header file. + * + * A return value of zero frp spifi_init() indicates success. Non-zero error + * codes include: + * + * 0x2000A No operative serial flash (JEDEC ID all zeroes or all ones) + * 0x20009 Unknown manufacturer code + * 0x20008 Unknown device type code + * 0x20007 Unknown device ID code + * 0x20006 Unknown extended device ID value (only for Spansion 25FL12x + * in the initial API) + * 0x20005 Device status error + * 0x20004 Operand error: S_MODE3+S_FULLCLK+S_RCVCLK in options + */ + + result = SPIFI_INIT(priv, &priv->rom, SPIFI_CSHIGH, + S_RCVCLK | S_FULLCLK, SCLK_MHZ); + if (result != 0) + { + fdbg("ERROR: SPIFI_INIT failed: %05x\n", result); + + /* Try again */ + + result = SPIFI_INIT(priv, &priv->rom, SPIFI_CSHIGH, + S_RCVCLK | S_FULLCLK, SCLK_MHZ); + if (result != 0) + { + fdbg("ERROR: SPIFI_INIT failed: %05x\n", result); + return -ENODEV; + } + } + + fvdbg("SPFI:\n"); + fvdbg(" base: %08x\n", priv->rom.base); + fvdbg(" regbase: %08x\n", priv->rom.regbase); + fvdbg(" devsize: %08x\n", priv->rom.devsize); + fvdbg(" memsize: %08x\n", priv->rom.memsize); + fvdbg(" mfger: %02x\n", priv->rom.mfger); + fvdbg(" devtype: %02x\n", priv->rom.devtype); + fvdbg(" devid: %02x\n", priv->rom.devid); + fvdbg(" busy: %02x\n", priv->rom.busy); + fvdbg(" stat: %04x\n", priv->rom.stat.h); + fvdbg(" setprot: %04x\n", priv->rom.setprot); + fvdbg(" writeprot: %04x\n", priv->rom.writeprot); + fvdbg(" memcmd: %08x\n", priv->rom.memcmd); + fvdbg(" progcmd: %08x\n", priv->rom.progcmd); + fvdbg(" sectors: %04x\n", priv->rom.sectors); + fvdbg(" protbytes: %04x\n", priv->rom.protbytes); + fvdbg(" opts: %08x\n", priv->rom.opts); + fvdbg(" errcheck: %08x\n", priv->rom.errcheck); + + /* Get the largest erase block size */ + +#ifndef CONFIG_SPIFI_BLKSIZE + + desc = priv->rom.protents; + sectors = priv->rom.sectors; + log2 = 0; + + fvdbg("FLASH Geometry:\n"); + + while (sectors > 0) + { + fvdbg(" log2: %d rept: %d\n", desc->log2, desc->rept); + + /* Check if this is the largest erase block size seen */ + + if (desc->log2 > log2) + { + log2 = desc->log2; + } + + /* Decrement the count of sectors we have checked */ + + sectors -= desc->rept; + } + + DEBUGASSERT(log2 > 0); + + /* Save the digested FLASH geometry info */ + + priv->blkshift = log2; + priv->blksize = (1 << log2); + priv->nblocks = (priv->rom.memsize - CONFIG_SPIFI_OFFSET) / priv->blksize; + + fvdbg("Driver FLASH Geometry:\n"); + fvdbg(" blkshift: %d\n", priv->blkshift); + fvdbg(" blksize: %08x\n", priv->blksize); + fvdbg(" nblocks: %d\n", priv->nblocks); + +#ifdef CONFIG_SPIFI_SECTOR512 + DEBUGASSERT(log2 > 9); +#endif + +#else + + /* Save the digested FLASH geometry info */ + + priv->nblocks = ((priv->rom.memsize - CONFIG_SPIFI_OFFSET) >> SPIFI_BLKSHIFT); + + fvdbg("Driver FLASH Geometry:\n"); + fvdbg(" blkshift: %d\n", SPIFI_BLKSHIFT); + fvdbg(" blksize: %08x\n", SPIFI_BLKSIZE); + fvdbg(" nblocks: %d\n", priv->nblocks); +#endif + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_spifi_initialize + * + * Description: + * Create an initialized MTD device instance for the SPIFI device. MTD + * devices are not registered in the file system, but are created as + * instances that can be bound to other functions (such as a block or + * character driver front end). + * + * SPIFI interface clocking is configured per settings in the board.h file. + * + * Input Parameters: + * None + * + * Returned value: + * One success, a reference to the initialized MTD device instance is + * returned; NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct mtd_dev_s *lpc43_spifi_initialize(void) +{ + /* At present, only a single instance of the SPIFI driver is supported */ + + FAR struct lpc43_dev_s *priv = &g_spifi; + irqstate_t flags; + int ret; + + /* Initialize the SPIFI driver structure. Since the driver instance lies + * in .bss, it should have been already cleared to zero. + */ + + priv->mtd.erase = lpc43_erase; + priv->mtd.bread = lpc43_bread; + priv->mtd.bwrite = lpc43_bwrite; + priv->mtd.read = lpc43_read; + priv->mtd.ioctl = lpc43_ioctl; + + priv->operands.protect = -1; /* Save and restore protection */ + priv->operands.options = S_CALLER_ERASE; /* This driver will do erasure */ + + /* Initialize the SPIFI. Interrupts must be disabled here because shared + * CGU registers will be modified. + */ + + flags = enter_critical_section(); + + /* The SPIFI will receive clocking from a divider per the settings + * provided in the board.h file. Configure PLL1 as the input clock + * for the selected divider + */ + + lpc43_idiv_clkconfig(); + + /* Configure SPIFI to received clocking from the selected divider */ + + lpc43_spifi_clkconfig(); + + /* Configure SPIFI pins */ + + lpc43_spifi_pinconfig(); + leave_critical_section(flags); + + /* Initialize the SPIFI ROM driver */ + + ret = lpc43_rominit(priv); + if (ret != OK) + { + return NULL; + } + + /* Check if we need to emulator a 512 byte sector */ + +#ifdef CONFIG_SPIFI_SECTOR512 + + /* Allocate a buffer for the erase block cache */ + + priv->cache = (FAR uint8_t *)kmm_malloc(SPIFI_BLKSIZE); + if (!priv->cache) + { + /* Allocation failed! Discard all of that work we just did and return NULL */ + + fdbg("ERROR: Allocation failed\n"); + return NULL; + } +#endif + + /* Return the implementation-specific state structure as the MTD device */ + + fvdbg("Return %p\n", priv); + return (FAR struct mtd_dev_s *)priv; +} + +/**************************************************************************** + * Name: pullMISO + * + * Description: + * hardware-control routine used by spifi_rom_api.c + * + * Input Parameters: + * high + * + * Returned value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_SPIFI_LIBRARY +void pullMISO(int high) +{ + uint32_t pinconfig; + + /* Control MISO pull-up/down state Assume pull down by clearing: + * + * EPD = Enable pull-down connect (bit + */ + + pinconfig = PINCONF_SPIFI_MISO & ~(PINCONF_PULLUP | PINCONF_PULLDOWN); + switch (high) + { + case 0: + { + /* Pull down */ + + pinconfig |= PINCONF_PULLDOWN; + } + break; + + case 1: + { + /* Pull up */ + + pinconfig |= PINCONF_PULLUP; + } + break; + + default: + { + /* Neither */ + } + break; + } + + /* Reconfigure MISO */ + + lpc43_pin_config(pinconfig); +} +#endif + +#endif /* CONFIG_LPC43_SPIFI */ diff --git a/arch/arm/src/lpc43xx/lpc43_spifi.h b/arch/arm/src/lpc43xx/lpc43_spifi.h new file mode 100644 index 0000000000000000000000000000000000000000..4445919259139dae7d863faf488338fc380666db --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_spifi.h @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_spifi.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/lpc43_spifi.h" + +#ifdef CONFIG_LPC43_SPIFI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* SPIFI Configuration ******************************************************/ +/* This logic supports some special options that can be used to create an + * MTD device on the SPIFI FLASH. + * + * CONFIG_LPC43_SPIFI - Enable SPIFI support + * + * SPIFI device geometry: + * + * CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many + * bytes into the device address space. This offset must be an exact + * multiple of the erase block size (CONFIG_SPIFI_BLKSIZE). Default 0. + * CONFIG_SPIFI_BLKSIZE - The size of one device erase block. If not defined + * then the driver will try to determine the correct erase block size by + * examining that data returned from spifi_initialize (which sometimes + * seems bad). + * + * Other SPIFI options + * + * CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead, + * use an external library implementation of the SPIFI interface. + * CONFIG_SPIFI_SECTOR512 - If defined, then the driver will report a more + * FAT friendly 512 byte sector size and will manage the read-modify-write + * operations on the larger erase block. + * CONFIG_SPIFI_READONLY - Define to support only read-only operations. + */ + +#ifndef CONFIG_SPIFI_OFFSET +# define CONFIG_SPIFI_OFFSET 0 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: lpc43_spifi_initialize + * + * Description: + * Create an initialized MTD device instance for the SPIFI device. MTD + * devices are not registered in the file system, but are created as + * instances that can be bound to other functions (such as a block or + * character driver front end). + * + * SPIFI interface clocking is configured per settings in the board.h file. + * + * Input Parameters: + * None + * + * Returned value: + * One success, a reference to the initialized MTD device instance is + * returned; NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct mtd_dev_s *lpc43_spifi_initialize(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_SPIFI */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H */ + diff --git a/arch/arm/src/lpc43xx/lpc43_ssp.c b/arch/arm/src/lpc43xx/lpc43_ssp.c new file mode 100644 index 0000000000000000000000000000000000000000..0d227fa8fa57e3ff7f808a366d78870eb564d22f --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ssp.c @@ -0,0 +1,906 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_ssp.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "lpc43_ssp.h" +#include "lpc43_cgu.h" +#include "lpc43_scu.h" +#include "lpc43_ccu.h" +#include "lpc43_pinconfig.h" + + +#if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The following enable debug output from this file (needs CONFIG_DEBUG too). + * + * CONFIG_SSP_DEBUG - Define to enable basic SSP debug + * CONFIG_SSP_VERBOSE - Define to enable verbose SSP debug + */ + +#ifdef CONFIG_SSP_DEBUG +# define sspdbg lldbg +# ifdef CONFIG_SSP_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# undef CONFIG_SSP_VERBOSE +# define sspdbg(x...) +# define spivdbg(x...) +#endif + + + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes the state of the SSP driver */ + +struct lpc43_sspdev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t sspbase; /* SPIn base address */ + uint32_t sspbasefreq; +#ifdef CONFIG_LPC43_SSP_INTERRUPTS + uint8_t sspirq; /* SPI IRQ number */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (4 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset); +static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset, + uint32_t value); + +/* SPI methods */ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); +#endif + +/* Initialization */ + +#ifdef CONFIG_LPC43_SSP0 +static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void); +#endif +#ifdef CONFIG_LPC43_SSP1 +static inline FAR struct lpc43_sspdev_s *lpc43_ssp1initialize(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LPC43_SSP0 +static const struct spi_ops_s g_spi0ops = +{ + .lock = ssp_lock, + .select = lpc43_ssp0select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = lpc43_ssp0status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc43_ssp0cmddata, /* Provided externally */ +#endif + .send = ssp_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = ssp_exchange, +#else + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc43_ssp0register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc43_sspdev_s g_ssp0dev = +{ + .spidev = { &g_spi0ops }, + .sspbase = LPC43_SSP0_BASE, + .sspbasefreq = BOARD_SSP0_BASEFREQ +#ifdef CONFIG_LPC43_SSP_INTERRUPTS + .sspirq = LPC43_IRQ_SSP0, +#endif +}; +#endif /* CONFIG_LPC43_SSP0 */ + +#ifdef CONFIG_LPC43_SSP1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = ssp_lock, + .select = lpc43_ssp1select, /* Provided externally */ + .setfrequency = ssp_setfrequency, + .setmode = ssp_setmode, + .setbits = ssp_setbits, + .status = lpc43_ssp1status, /* Provided externally */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = lpc43_ssp1cmddata, /* Provided externally */ +#endif + .send = ssp_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = ssp_exchange, +#else + .sndblock = ssp_sndblock, + .recvblock = ssp_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = lpc43_ssp1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct lpc43_sspdev_s g_ssp1dev = +{ + .spidev = { &g_spi1ops }, + .sspbase = LPC43_SSP1_BASE, + .sspbasefreq = BOARD_SSP1_BASEFREQ +#ifdef CONFIG_LPC43_SSP_INTERRUPTS + .sspirq = LPC43_IRQ_SSP1, +#endif +}; +#endif /* CONFIG_LPC43_SSP1 */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssp_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset) +{ + return getreg32(priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_putreg + * + * Description: + * Write a 32-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset, uint32_t value) +{ + putreg32(value, priv->sspbase + (uint32_t)offset); +} + +/**************************************************************************** + * Name: ssp_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ssp_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: ssp_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + uint32_t divisor; + uint32_t actual; + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* frequency = SSP_CLOCK / divisor, or divisor = SSP_CLOCK / frequency */ + + divisor = priv->sspbasefreq / frequency; + + /* "In master mode, CPSDVSRmin = 2 or larger (even numbers only)" */ + + if (divisor < 2) + { + divisor = 2; + } + else if (divisor > 254) + { + divisor = 254; + } + + divisor = (divisor + 1) & ~1; + + /* Save the new divisor value */ + + ssp_putreg(priv, LPC43_SSP_CPSR_OFFSET, divisor); + + /* Calculate the new actual */ + + actual = priv->sspbasefreq / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + sspdbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: ssp_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + uint32_t regval; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR0 appropriately */ + + regval = ssp_getreg(priv, LPC43_SSP_CR0_OFFSET); + regval &= ~(SSP_CR0_CPOL | SSP_CR0_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SSP_CR0_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SSP_CR0_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SSP_CR0_CPOL | SSP_CR0_CPHA); + break; + + default: + sspdbg("Bad mode: %d\n", mode); + DEBUGASSERT(FALSE); + return; + } + + ssp_putreg(priv, LPC43_SSP_CR0_OFFSET, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: ssp_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + uint32_t regval; + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 3 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set CR1 appropriately */ + + regval = ssp_getreg(priv, LPC43_SSP_CR0_OFFSET); + regval &= ~SSP_CR0_DSS_MASK; + regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT); + regval = ssp_getreg(priv, LPC43_SSP_CR0_OFFSET); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: ssp_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + register uint32_t regval; + + /* Wait while the TX FIFO is full */ + + while (!(ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF)); + + /* Write the byte to the TX FIFO */ + + ssp_putreg(priv, LPC43_SSP_DR_OFFSET, (uint32_t)wd); + + /* Wait for the RX FIFO not empty */ + + while (!(ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Get the value from the RX FIFO and return it */ + + regval = ssp_getreg(priv, LPC43_SSP_DR_OFFSET); + sspdbg("%04x->%04x\n", wd, regval); + return (uint16_t)regval; +} + +/**************************************************************************** + * Name: ssp_exchange + * + * Description: + * Exahange a block of data from SPI. Required. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + union + { + FAR const uint8_t *p8; + FAR const uint16_t *p16; + FAR const void *pv; + } tx; + union + { + FAR uint8_t *p8; + FAR uint16_t *p16; + FAR void *pv; + } rx; + uint32_t data; + uint32_t datadummy = (priv->nbits > 8) ? 0xffff : 0xff; + uint32_t rxpending = 0; + + /* While there is remaining to be sent (and no synchronization error has occurred) */ + + sspdbg("nwords: %d\n", nwords); + + tx.pv = txbuffer; + rx.pv = rxbuffer; + + while (nwords || rxpending) + { + /* Write data to the data register while (1) the TX FIFO is + * not full, (2) we have not exceeded the depth of the TX FIFO, + * and (3) there are more bytes to be sent. + */ + + spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); + while ((ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF) && + (rxpending < LPC43_SSP_FIFOSZ) && nwords) + { + if (txbuffer) + { + if (priv->nbits > 8) + { + data = (uint32_t)*tx.p16++; + } + else + { + data = (uint32_t)*tx.p8++; + } + } + + ssp_putreg(priv, LPC43_SSP_DR_OFFSET, txbuffer?data:datadummy); + nwords--; + rxpending++; + } + + /* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */ + + spivdbg("RX: rxpending: %d\n", rxpending); + while (ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE) + { + data = ssp_getreg(priv, LPC43_SSP_DR_OFFSET); + if (rxbuffer) + { + if(priv->nbits > 8) + { + *rx.p16++ = (uint16_t)data; + } + else + { + *rx.p8++ = (uint8_t)data; + } + } + + rxpending--; + } + } +} + +/**************************************************************************** + * Name: ssp_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + return ssp_exchange(dev, buffer, NULL, nwords); +} + +/**************************************************************************** + * Name: ssp_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + return ssp_exchange(dev, NULL, buffer, nwords); +} +#endif /* !CONFIG_SPI_EXCHANGE */ + +/**************************************************************************** + * Name: lpc43_ssp0initialize + * + * Description: + * Initialize the SSP0 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_SSP0 +static inline FAR struct lpc43_sspdev_s *lpc43_ssp0initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Configure clocking */ + + regval = getreg32(LPC43_BASE_SSP0_CLK); + regval &= ~BASE_SSP0_CLK_CLKSEL_MASK; + regval |= (BOARD_SSP0_CLKSRC | BASE_SSP0_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_SSP0_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_SSP0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_SSP0_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB0_SSP0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB0_SSP0_CFG); + + /* Pin configuration */ + + lpc43_pin_config(PINCONF_SSP0_SCK); + lpc43_pin_config(PINCONF_SSP0_MISO); + lpc43_pin_config(PINCONF_SSP0_MOSI); + + leave_critical_section(flags); + + return &g_ssp0dev; +} +#endif + +/**************************************************************************** + * Name: lpc43_ssp1initialize + * + * Description: + * Initialize the SSP1 + * + * Input Parameter: + * None + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_SSP1 +static inline FAR struct lpc43_sspdev_s *lpc43_ssp1initialize(void) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + /* Configure clocking */ + + regval = getreg32(LPC43_BASE_SSP1_CLK); + regval &= ~BASE_SSP1_CLK_CLKSEL_MASK; + regval |= (BOARD_SSP1_CLKSRC | BASE_SSP1_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_SSP1_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_SSP1_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_SSP1_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB2_SSP1_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB2_SSP1_CFG); + + /* Pins configuration */ + +#ifdef PINCONF_SSP1_SCK + /* It is possible this is not configured if CLK0 is being used for clocking SPI */ + + lpc43_pin_config(PINCONF_SSP1_SCK); +#endif + lpc43_pin_config(PINCONF_SSP1_MISO); + lpc43_pin_config(PINCONF_SSP1_MOSI); + + leave_critical_section(flags); + return &g_ssp1dev; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_sspbus_initialize + * + * Description: + * Initialize the selected SSP port (0=SSP0, 1=SSP1) + * + * Input Parameter: + * port - Port number (0=SSP0, 1=SSP1) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc43_sspbus_initialize(int port) +{ + FAR struct lpc43_sspdev_s *priv; + uint32_t regval; + int i; + + /* Only the SSP0 and SSP1 interfaces are supported */ + + switch (port) + { +#ifdef CONFIG_LPC43_SSP0 + case 0: + priv = lpc43_ssp0initialize(); + break; +#endif + +#ifdef CONFIG_LPC43_SSP1 + case 1: + priv = lpc43_ssp1initialize(); + break; +#endif + + default: + return NULL; + } + + /* Configure 8-bit SPI mode */ + + ssp_putreg(priv, LPC43_SSP_CR0_OFFSET, SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI); + + /* Disable the SSP and all interrupts (we'll poll for all data) */ + + ssp_putreg(priv, LPC43_SSP_CR1_OFFSET, 0); + ssp_putreg(priv, LPC43_SSP_IMSC_OFFSET, 0); + + /* Set the initial SSP configuration */ + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + ssp_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + /* Enable the SPI */ + + regval = ssp_getreg(priv, LPC43_SSP_CR1_OFFSET); + ssp_putreg(priv, LPC43_SSP_CR1_OFFSET, regval | SSP_CR1_SSE); + for (i = 0; i < LPC43_SSP_FIFOSZ; i++) + { + (void)ssp_getreg(priv, LPC43_SSP_DR_OFFSET); + } + + return &priv->spidev; +} + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be done + * after a device is deselected if you worry about such things. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void ssp_flush(FAR struct spi_dev_s *dev) +{ + FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev; + + /* Wait for the TX FIFO not full indication */ + + while (!(ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_TNF)); + ssp_putreg(priv, LPC43_SSP_DR_OFFSET, 0xff); + + /* Wait until TX FIFO and TX shift buffer are empty */ + + while (ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_BSY); + + /* Wait until RX FIFO is not empty */ + + while (!(ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE)); + + /* Then read and discard bytes until the RX FIFO is empty */ + + do + { + (void)ssp_getreg(priv, LPC43_SSP_DR_OFFSET); + } + while (ssp_getreg(priv, LPC43_SSP_SR_OFFSET) & SSP_SR_RNE); +} + +#endif /* CONFIG_LPC43_SSP0/1 */ diff --git a/arch/arm/src/lpc43xx/lpc43_ssp.h b/arch/arm/src/lpc43xx/lpc43_ssp.h new file mode 100644 index 0000000000000000000000000000000000000000..1c98618cbf697c8c79fdf7580167e783bf93a2c9 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_ssp.h @@ -0,0 +1,198 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_ssp.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_SSP_H +#define __ARCH_ARM_SRC_LPC43XX_SSP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip/lpc43_ssp.h" + +#if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* This header file defines interfaces to common SSP logic. To use this common SSP + * logic on your board: + * + * 1. Provide logic in lpc43_boardinitialize() to configure SSP chip select pins. + * 2. Provide lpc43_ssp0/1select() and lpc43_ssp0/1status() functions in your + * board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * lpc43_ssp0/1cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Your low level board initialization logic should call lpc43_sspbus_initialize. + * 5. The handle returned by lpc43_sspbus_initialize() may then be used to bind the + * SSP driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_sspbus_initialize + * + * Description: + * Initialize the selected SSP port (0=SSP0, 1=SSP1) + * + * Input Parameter: + * port - Port number (0=SSP0, 1=SSP1) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *lpc43_sspbus_initialize(int port); + +/************************************************************************************ + * Name: lpc43_ssp0/1select, lpc43_ssp0/1status, and lpc43_ssp0/1cmddata + * + * Description: + * These functions must be provided in your board-specific logic. The + * lpc43_ssp0/1select functions will perform chip selection and the + * lpc43_ssp0/1status will perform status operations using GPIOs in the way your + * board is configured. + * + * If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, then + * lpc43_ssp0/1cmddata must also be provided. This functions performs cmd/data + * selection operations using GPIOs in the way your board is configured. + * + ************************************************************************************/ + +#ifdef CONFIG_LPC43_SSP0 +void lpc43_ssp0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc43_ssp0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc43_ssp0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_LPC43_SSP1 +void lpc43_ssp1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t lpc43_ssp1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int lpc43_ssp1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from ssp0/1select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_SSP0) || defined(CONFIG_LPC43_SSP1) +void ssp_flush(FAR struct spi_dev_s *dev); +#endif + +/**************************************************************************** + * Name: lpc43_spi/ssp0/1register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD driver when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function(s) must + * must be implemented. These functions implements the registercallback + * method of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_LPC43_SSP0 +int lpc43_ssp0register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_LPC43_SSP1 +int lpc43_ssp1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_LPC43_SSP0/1 */ +#endif /* __ARCH_ARM_SRC_LPC43XX_SSP_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_start.c b/arch/arm/src/lpc43xx/lpc43_start.c new file mode 100644 index 0000000000000000000000000000000000000000..80ffb581ee8fb978e3f69d84435504b2a4493890 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_start.c @@ -0,0 +1,360 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_start.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/* Power-Up Reset Overview + * ----------------------- + * + * The ARM core starts executing code on reset with the program counter set + * to 0x0000:0000. The LPC43xx contains a shadow pointer register that + * allows areas of memory to be mapped to address 0x0000:0000. The default, + * reset value of the shadow pointer is 0x1040:0000 so that on reset code in + * the boot ROM is always executed first. + * + * The boot starts after reset is released. The IRC is selected as CPU clock + * and the Cortex-M4 starts the boot loader. By default the JTAG access to the + * chip is disabled at reset. The boot ROM determines the boot mode based on + * the OTP BOOT_SRC value or reset state pins. For flash-based parts, the part + * boots from internal flash by default. Otherwse, the boot ROM copies the + * image to internal SRAM at location 0x1000:0000, sets the ARM's shadow + * pointer to 0x1000:0000, and jumps to that location. + * + * However, using JTAG the executable image can be also loaded directly into + * and executed from SRAM. + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "nvic.h" + +#include "chip/lpc43_creg.h" + +#include "lpc43_rgu.h" +#include "lpc43_cgu.h" +#include "lpc43_emc.h" +#include "lpc43_uart.h" +#include "lpc43_userspace.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_setbootrom + * + * Description: + * Set the shadow register to 0x1040:0000 and the VTOR to 0x0000:0000 so + * that any exceptions (particulary things like hard faults) that occur + * before we are initialized are caught by the BOOT ROM. + * + ****************************************************************************/ + +static inline void lpc43_setbootrom(void) +{ + /* Set the shadow register to the beginning of the boot ROM (Only bits 12-31) */ + + putreg32(LPC43_ROM_BASE, LPC43_CREG_M4MEMMAP); + + /* Address zero now maps to the Boot ROM. Make sure that the VTOR will + * use the ROM vector table at that address. + */ + + putreg32(0, NVIC_VECTAB); +} + +/**************************************************************************** + * Name: lpc43_enabuffering + * + * Description: + * If we are executing from external FLASH, then enable buffering. + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_BOOT_CS0FLASH) || defined(CONFIG_LPC43_BOOT_CS1FLASH) || \ + defined(CONFIG_LPC43_BOOT_CS2FLASH) || defined(CONFIG_LPC43_BOOT_CS3FLASH) +static inline void lpc43_enabuffering(void) +{ + uint32_t regval; + +#ifdef CONFIG_LPC43_BOOT_CS0FLASH + regval = getreg32(LPC43_EMC_STATCONFIG0); + regval |= EMC_STATCONFIG_BENA + putreg32(regval, LPC43_EMC_STATCONFIG0); +#endif + +#ifdef CONFIG_LPC43_BOOT_CS1FLASH + regval = getreg32(LPC43_EMC_STATCONFIG1); + regval |= EMC_STATCONFIG_BENA + putreg32(regval, LPC43_EMC_STATCONFIG1); +#endif + +#ifdef CONFIG_LPC43_BOOT_CS2FLASH + regval = getreg32(LPC43_EMC_STATCONFIG2); + regval |= EMC_STATCONFIG_BENA + putreg32(regval, LPC43_EMC_STATCONFIG2); +#endif + +#ifdef CONFIG_LPC43_BOOT_CS3FLASH + regval = getreg32(LPC43_EMC_STATCONFIG3); + regval |= EMC_STATCONFIG_BENA + putreg32(regval, LPC43_EMC_STATCONFIG3); +#endif +} +#else +# define lpc43_enabuffering() +#endif + +/**************************************************************************** + * Name: lpc43_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void lpc43_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void lpc43_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define lpc43_fpuconfig() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Reset as many of the LPC43 peripherals as possible. This is necessary + * because the LPC43 does not provide any way of performing a full system + * reset under debugger control. So, if CONFIG_DEBUG is set (indicating + * that a debugger is being used?), the boot logic will call this + * function on all restarts. + */ + +#ifdef CONFIG_DEBUG + lpc43_softreset(); +#endif + + /* Make sure that any exceptions (such as hard faults) that occur before + * we are initialized are caught by the BOOT ROM. + */ + + lpc43_setbootrom(); + + /* Configure the CGU clocking and the console uart so that we can get + * debug output as soon as possible. + */ + + lpc43_clockconfig(); + lpc43_lowsetup(); + showprogress('A'); + + /* If we are executing from external FLASH, then enable buffering */ + + lpc43_enabuffering(); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + showprogress('C'); + + /* Initialize the FPU (if configured) */ + + lpc43_fpuconfig(); + showprogress('D'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('E'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + lpc43_userspace(); + showprogress('F'); +#endif + + /* Initialize onboard resources */ + + lpc43_boardinitialize(); + showprogress('G'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c new file mode 100644 index 0000000000000000000000000000000000000000..f7c94d3a6e581be80ca45c289fe643bc88ff2af4 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c @@ -0,0 +1,777 @@ +/**************************************************************************** + * arch/arm/src/lpc43/lpc43_rit.c + * + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * + * only controlled resets to 0 are performed, no direct set to counter + * working counter region is from 0 to TO_END + * all public functions are synchronized with disabled irqs + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/lpc43_rit.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef min +# define min(a,b) (a < b ? a : b) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t TO_RESET = UINT32_MAX / 2; +static uint32_t TO_RESET_NEXT = UINT32_MAX / 2 + UINT32_MAX / 4; +static uint32_t TO_END = UINT32_MAX / 2 + UINT32_MAX / 4 + UINT32_MAX / 8; /* any alarm should no last more than UINT32_MAX/8 */ +static struct timespec MAX_TS; + +static uint32_t COMMON_DEV; +static uint32_t MIN_TICKS; +static uint32_t MIN_NSEC; + +static uint32_t RESET_TICKS = 1000; /* Ticks to add to force a reset */ + +static struct timespec base_ts; /* Time base */ +static uint32_t base_rest; /* Rest of ticks that is < MIN_TICKS */ + +static struct timespec alarm_time_ts; /* alarmTime to set on next interrupt, used if not already armed */ + +static bool alarm_time_set = false; /* true if alarm_time set and need to be processed */ +static bool call = false; /* true if callback should be called on next interrupt */ +static bool forced_int = false; /* true if interrupt was forced with mask, no reset */ +static bool armed = false; /* true if alarm is armed for next match */ +static uint32_t synch = 0; /* Synch all calls, recursion is possible */ +static irqstate_t g_flags; + +static uint32_t ctrl_cache; +static uint32_t mask_cache; +static uint32_t compare_cache; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Some timer HW functions */ + +static inline void lpc43_tl_set_counter(uint32_t value) +{ + putreg32(value, LPC43_RIT_COUNTER); +} + +static inline uint32_t lpc43_tl_get_counter(void) +{ + return getreg32(LPC43_RIT_COUNTER); +} + +static inline void lpc43_tl_set_compare(uint32_t value) +{ + if (value != compare_cache) + { + compare_cache = value; + putreg32(value, LPC43_RIT_COMPVAL); + } +} + +static inline uint32_t lpc43_tl_get_compare(void) +{ + return compare_cache; +} + + static inline void lpc43_tl_set_mask(uint32_t value) +{ + if (value != mask_cache) + { + mask_cache = value; + putreg32(value, LPC43_RIT_MASK); + } +} + +static inline uint32_t lpc43_tl_get_mask(void) +{ + return mask_cache; +} + +static inline bool lpc43_tl_get_ctrl_bit(uint32_t bit) +{ + return ((ctrl_cache & bit)?true:false); +} + +static inline void lpc43_tl_set_ctrl_bit(uint32_t bit, bool value) +{ + if (lpc43_tl_get_ctrl_bit(bit) != value) + { + if (value) + { + ctrl_cache |= bit; + } + else + { + ctrl_cache &= ~bit; + } + + putreg32(ctrl_cache, LPC43_RIT_CTRL); + } +} + +static inline void lpc43_tl_set_reset_on_match(bool value) +{ + lpc43_tl_set_ctrl_bit(RIT_CTRL_ENCLR, value); +} + +static inline bool lpc43_tl_get_reset_on_match(void) +{ + return lpc43_tl_get_ctrl_bit(RIT_CTRL_ENCLR); +} + +static inline void lpc43_tl_set_enable(bool value) +{ + lpc43_tl_set_ctrl_bit(RIT_CTRL_EN, value); +} + +static inline bool lpc43_tl_get_enable(void) +{ + return lpc43_tl_get_ctrl_bit(RIT_CTRL_EN); +} + +static inline void lpc43_tl_clear_interrupt(void) +{ + putreg32(ctrl_cache | RIT_CTRL_INT, LPC43_RIT_CTRL); +} + +static inline bool lpc43_tl_get_interrupt(void) +{ + return ((getreg32(LPC43_RIT_CTRL) & RIT_CTRL_INT)?true:false); +} + +/* Converters */ + +static uint32_t commonDev(uint32_t a, uint32_t b) +{ + while (b != 0) + { + int h = a%b; + a = b; + b = h; + } + + return a; +} + +static void lpc43_tl_add(FAR const struct timespec *ts1, + FAR const struct timespec *ts2, + FAR struct timespec *ts3) +{ + time_t sec = ts1->tv_sec + ts2->tv_sec; + long nsec = ts1->tv_nsec + ts2->tv_nsec; + + if (nsec >= NSEC_PER_SEC) + { + nsec -= NSEC_PER_SEC; + sec++; + } + + ts3->tv_sec = sec; + ts3->tv_nsec = nsec; +} + +static void lpc43_tl_sub(FAR const struct timespec *ts1, + FAR const struct timespec *ts2, + FAR struct timespec *ts3) +{ + time_t sec; + long nsec; + + if (ts1->tv_sec < ts2->tv_sec) + { + sec = 0; + nsec = 0; + } + else if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec <= ts2->tv_nsec) + { + sec = 0; + nsec = 0; + } + else + { + sec = ts1->tv_sec - ts2->tv_sec; + if (ts1->tv_nsec < ts2->tv_nsec) + { + nsec = (ts1->tv_nsec + NSEC_PER_SEC) - ts2->tv_nsec; + sec--; + } + else + { + nsec = ts1->tv_nsec - ts2->tv_nsec; + } + } + + ts3->tv_sec = sec; + ts3->tv_nsec = nsec; +} + +static inline uint32_t lpc43_tl_ts2tick(FAR const struct timespec *ts) +{ + return (ts->tv_sec*LPC43_CCLK + (ts->tv_nsec/MIN_NSEC*MIN_TICKS)); +} + +static uint32_t lpc43_tl_tick2ts(uint32_t ticks, FAR struct timespec *ts, + bool with_rest) +{ + uint32_t ticks_whole; + uint32_t ticks_rest = 0; + + if (with_rest) + { + uint32_t ticks_mult = ticks/MIN_TICKS; + ticks_whole = ticks_mult*MIN_TICKS; + ticks_rest = ticks - ticks_whole; + } + else + { + ticks_whole = ticks; + } + + ts->tv_sec = ticks_whole/LPC43_CCLK; + ts->tv_nsec = ((ticks_whole%LPC43_CCLK)/MIN_TICKS)*MIN_NSEC; + + return ticks_rest; +} + +/* Logic functions */ + +static inline void lpc43_tl_sync_up(void) +{ + irqstate_t flags; + flags = enter_critical_section(); + + if (synch == 0) + { + g_flags = flags; + } + + synch++; +} + +static inline void lpc43_tl_sync_down(void) +{ + synch--; + if (synch == 0) + { + leave_critical_section(g_flags); + } +} + +/* Assuming safe timer state, force interrupt, no reset possible */ + +static inline void lpc43_tl_force_int(void) +{ + forced_int = true; + lpc43_tl_set_reset_on_match(false); + lpc43_tl_set_mask(UINT32_MAX); + lpc43_tl_set_compare(UINT32_MAX); +} + +/* Init all vars, forced_int should not be cleared */ + +static inline void lpc43_tl_init_timer_vars(void) +{ + alarm_time_set = false; + call = false; + armed = false; +} + +/* Calc RESET_TICKS and set compare to TO_RESET */ + +static void lpc43_tl_calibrate_init(void) +{ + uint32_t counter = lpc43_tl_get_counter(); + + uint32_t counter_after = lpc43_tl_get_counter(); + counter_after = TO_RESET + counter; + counter_after = counter_after - counter; + + /* Shift to to Reset */ + + lpc43_tl_set_compare(counter_after); + + counter_after = lpc43_tl_get_counter(); + + RESET_TICKS = (counter_after - counter) * 2; +} + +/* Process current and set timer in default safe state */ + +static void lpc43_tl_save_timer(bool from_isr) +{ + if (forced_int) /* special case of forced interrupt by mask */ + { + forced_int = false; + lpc43_tl_set_compare(UINT32_MAX); + lpc43_tl_set_mask(0); + lpc43_tl_clear_interrupt(); + } + else + { + /* Process reset if any */ + + uint32_t match = lpc43_tl_get_compare(); + + /* Move to end, no resets during processing */ + + lpc43_tl_set_compare(UINT32_MAX); + lpc43_tl_set_mask(0); + + if (from_isr || lpc43_tl_get_interrupt()) + { + if (lpc43_tl_get_reset_on_match()) /* Was reset? */ + { + struct timespec match_ts; + base_rest = lpc43_tl_tick2ts(match + base_rest, + &match_ts, true); + lpc43_tl_add(&base_ts, &match_ts, &base_ts); + } + + lpc43_tl_clear_interrupt(); + } + } +} + +/* Assuming safe timer state, true if set, false - time is in the past */ + +static bool lpc43_tl_set_safe_compare(uint32_t compare_to_set) +{ + if (compare_to_set < TO_RESET) + { + lpc43_tl_set_reset_on_match(false); + } + else + { + lpc43_tl_set_reset_on_match(true); + } + + lpc43_tl_set_compare(compare_to_set); + + /* Check if ok */ + + bool reset = lpc43_tl_get_interrupt(); + uint32_t counter = lpc43_tl_get_counter(); + bool reset_after = lpc43_tl_get_interrupt(); + + if (reset != reset_after) + { + /* Was a reset get new counter */ + + counter = lpc43_tl_get_counter(); + } + + if (reset_after || (!reset_after && compare_to_set > counter)) + { + return true; + } + else + { + lpc43_tl_set_compare(UINT32_MAX); + + return false; + } +} + +/* Assuming safe timer state, set_safe_compare in loop */ + +static void lpc43_tl_looped_forced_set_compare(void) +{ + uint32_t i = 1; + bool result = lpc43_tl_set_safe_compare( + lpc43_tl_get_counter() + RESET_TICKS); /* like in calibrateInit */ + + while (!result) + { + i++; + result = lpc43_tl_set_safe_compare( + lpc43_tl_get_counter() + RESET_TICKS * i); + } +} + +/* Assuming safe timer state, true if set, false - time is in the past */ + +static bool lpc43_tl_set_calc_arm(uint32_t curr, uint32_t to_set, bool arm) +{ + + uint32_t calcTime; + + if (curr < TO_RESET_NEXT) + { + calcTime = min(TO_RESET_NEXT, to_set); + } + else + { + if (curr < TO_END) + { + calcTime = min(curr + RESET_TICKS, to_set); + } + else + { + lpc43_tl_looped_forced_set_compare(); + return true; + } + } + + bool set = lpc43_tl_set_safe_compare(calcTime); + + if (arm && set && (calcTime == to_set)) + { + armed = true; + } + + return set; +} + +/* Assuming safe timer state, try to set compare for normal operation */ + +static void lpc43_tl_set_default_compare(uint32_t curr) +{ + bool result = lpc43_tl_set_calc_arm(curr, UINT32_MAX, false); + if (!result) + { + result = lpc43_tl_set_calc_arm(lpc43_tl_get_counter(), UINT32_MAX, + false); + if (!result) + { + lpc43_tl_looped_forced_set_compare(); + } + } +} + +/* Calculates ticks to set from alarm_time_ts and base_ts/base_rest, + * UINT32_MAX if overflow. + */ + +static inline uint32_t lpc43_tl_calc_to_set(void) +{ + struct timespec diff_ts; + struct timespec ovf_ts; + + lpc43_tl_sub(&alarm_time_ts, &base_ts, &diff_ts); + + lpc43_tl_sub(&diff_ts, &MAX_TS, &ovf_ts); + if (ovf_ts.tv_sec == 0 && ovf_ts.tv_nsec == 0) /* check overflow */ + { + return (lpc43_tl_ts2tick(&diff_ts) - base_rest); + } + else + { + return UINT32_MAX; + } +} + +/* Assuming safe timer state, used by isr: sets default compare, + * calls alarm. + */ + +static inline void lpc43_tl_alarm(uint32_t curr) +{ + lpc43_tl_init_timer_vars(); + lpc43_tl_set_default_compare(curr); + +#ifdef CONFIG_SCHED_TICKLESS_ALARM + struct timespec ts; + up_timer_gettime(&ts); + sched_alarm_expiration(&ts); +#else + sched_timer_expiration(); +#endif +} + +/* Interrupt handler */ + +static int lpc43_tl_isr(int irq, FAR void *context) +{ + lpc43_tl_sync_up(); + + lpc43_tl_save_timer(true); + + uint32_t curr = lpc43_tl_get_counter(); + if (call) + { + lpc43_tl_alarm(curr); + } + else + { + if (armed) + { + lpc43_tl_alarm(curr); /* armed - call alarm */ + } + else + { + if (alarm_time_set) /* need to set alarm time */ + { + uint32_t toSet = lpc43_tl_calc_to_set(); + + if (toSet > curr) + { + if (toSet > TO_END) + { + lpc43_tl_set_default_compare(curr); + } + else + { + bool set = lpc43_tl_set_calc_arm(curr, toSet, true); + if (!set) + { + lpc43_tl_alarm(curr); + } + } + } + else + { + lpc43_tl_alarm(curr); + } + } + else + { + lpc43_tl_set_default_compare(curr); + } + } + } + + lpc43_tl_sync_down(); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_timer_initialize(void) +{ + irqstate_t flags; + flags = enter_critical_section(); + + ctrl_cache = getreg32(LPC43_RIT_CTRL); + ctrl_cache &= ~RIT_CTRL_INT; /* Set interrupt to 0 */ + mask_cache = getreg32(LPC43_RIT_MASK); + compare_cache = getreg32(LPC43_RIT_COMPVAL); + + COMMON_DEV = commonDev(NSEC_PER_SEC, LPC43_CCLK); + MIN_TICKS = LPC43_CCLK/COMMON_DEV; + MIN_NSEC = NSEC_PER_SEC/COMMON_DEV; + + base_ts.tv_sec = 0; + base_ts.tv_nsec = 0; + base_rest = 0; + + lpc43_tl_tick2ts(TO_END, &MAX_TS, false); + + lpc43_tl_set_enable(false); + + lpc43_tl_set_compare(UINT32_MAX); + lpc43_tl_set_counter(0); + lpc43_tl_set_mask(0); + + lpc43_tl_set_reset_on_match(false); + lpc43_tl_clear_interrupt(); + + irq_attach(LPC43M4_IRQ_RITIMER, lpc43_tl_isr); + up_enable_irq(LPC43M4_IRQ_RITIMER); + + lpc43_tl_init_timer_vars(); + + lpc43_tl_set_enable(true); + + lpc43_tl_calibrate_init(); + + leave_critical_section(flags); +} + +/* No reg changes, only processing */ + +int up_timer_gettime(FAR struct timespec *ts) +{ + lpc43_tl_sync_up(); + + /* Order of calls is important, reset can come during processing */ + + bool reset = lpc43_tl_get_interrupt(); + uint32_t count = lpc43_tl_get_counter(); + + /* Not processed reset can exist */ + + if (lpc43_tl_get_reset_on_match()) + { + bool resetAfter = lpc43_tl_get_interrupt(); + + /* Was a reset during processing? get new counter */ + + if (reset != resetAfter) + { + count = lpc43_tl_get_counter(); + } + + if (resetAfter) + { + /* Count should be smaller then UINT32_MAX-TO_END -> no overflow */ + + count += lpc43_tl_get_compare(); + } + } + + struct timespec count_ts; + + lpc43_tl_tick2ts(count + base_rest, &count_ts, false); + + lpc43_tl_add(&base_ts, &count_ts, ts); + + lpc43_tl_sync_down(); + + return OK; +} + +int up_alarm_cancel(FAR struct timespec *ts) +{ + lpc43_tl_sync_up(); + + /* No reg changes, only variables logic */ + + if (ts != NULL) + { + up_timer_gettime(ts); + } + + /* Let default setup will be done in interrupt handler or up_alarm_start */ + + lpc43_tl_init_timer_vars(); + + lpc43_tl_sync_down(); + return OK; +} + +int up_alarm_start(FAR const struct timespec *ts) +{ + lpc43_tl_sync_up(); + + lpc43_tl_save_timer(false); + + lpc43_tl_init_timer_vars(); + + alarm_time_set = true; + alarm_time_ts.tv_sec = ts->tv_sec; + alarm_time_ts.tv_nsec = ts->tv_nsec; + + uint32_t toSet = lpc43_tl_calc_to_set(); + + uint32_t curr = lpc43_tl_get_counter(); + + if (toSet > curr) + { + if (toSet > TO_END) /* Future set */ + { + lpc43_tl_set_default_compare(curr); + } + else + { + bool set = lpc43_tl_set_calc_arm(curr, toSet, true); + if (!set) /* Signal call, force interrupt handler */ + { + call = true; + lpc43_tl_force_int(); + } + } + } + else /* Signal call, force interrupt handler */ + { + call = true; + lpc43_tl_force_int(); + } + + lpc43_tl_sync_down(); + + return OK; +} + +#ifndef CONFIG_SCHED_TICKLESS_ALARM +int up_timer_cancel(FAR struct timespec *ts) +{ + lpc43_tl_sync_up(); + + if (ts != NULL) + { + struct timespec abs_ts; + up_timer_gettime(&abs_ts); + lpc43_tl_sub(&alarm_time_ts, &abs_ts, ts); + } + + lpc43_tl_init_timer_vars(); + + lpc43_tl_sync_down(); + return OK; +} + +int up_timer_start(FAR const struct timespec *ts) +{ + lpc43_tl_sync_up(); + + struct timespec abs_ts; + up_timer_gettime(&abs_ts); + lpc43_tl_add(&abs_ts, ts, &abs_ts); + + up_alarm_start(&abs_ts); + + lpc43_tl_sync_down(); + return OK; +} + +#endif /* CONFIG_SCHED_TICKLESS_ALARM */ +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/lpc43xx/lpc43_timerisr.c b/arch/arm/src/lpc43xx/lpc43_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..2b728f7fb4316d717ed218e72026a1baec698d98 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_timerisr.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_timerisr.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The Clock Source: Either the internal CCLK or external STCLK (P3.26) clock + * as the source in the STCTRL register. This file alwyays configures the + * timer to use CCLK as its source. + */ + +#define SYSTICK_RELOAD ((LPC43_CCLK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (LPC43M4_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set to use the LPC43xx CCLK */ + + regval = getreg32(NVIC_SYSTICK_CTRL); + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(LPC43_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(LPC43_IRQ_SYSTICK); +} diff --git a/arch/arm/src/lpc43xx/lpc43_uart.c b/arch/arm/src/lpc43xx/lpc43_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..88d7950e6ac1eb8423d883f1476981fc9b47cd83 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_uart.c @@ -0,0 +1,651 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_uart.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "lpc43_config.h" +#include "lpc43_pinconfig.h" +#include "lpc43_rgu.h" +#include "lpc43_cgu.h" +#include "lpc43_ccu.h" + +#include "lpc43_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC43_USART0_BASE +# define CONSOLE_BASEFREQ BOARD_USART0_BASEFREQ +# define CONSOLE_BAUD CONFIG_USART0_BAUD +# define CONSOLE_BITS CONFIG_USART0_BITS +# define CONSOLE_PARITY CONFIG_USART0_PARITY +# define CONSOLE_2STOP CONFIG_USART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC43_UART1_BASE +# define CONSOLE_BASEFREQ BOARD_UART1_BASEFREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC43_USART2_BASE +# define CONSOLE_BASEFREQ BOARD_USART2_BASEFREQ +# define CONSOLE_BAUD CONFIG_USART2_BAUD +# define CONSOLE_BITS CONFIG_USART2_BITS +# define CONSOLE_PARITY CONFIG_USART2_PARITY +# define CONSOLE_2STOP CONFIG_USART2_2STOP +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC43_USART3_BASE +# define CONSOLE_BASEFREQ BOARD_USART3_BASEFREQ +# define CONSOLE_BAUD CONFIG_USART3_BAUD +# define CONSOLE_BITS CONFIG_USART3_BITS +# define CONSOLE_PARITY CONFIG_USART3_PARITY +# define CONSOLE_2STOP CONFIG_USART3_2STOP +#elif defined(HAVE_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS == 5 +# define CONSOLE_LCR_WLS UART_LCR_WLS_5BIT +#elif CONSOLE_BITS == 6 +# define CONSOLE_LCR_WLS UART_LCR_WLS_6BIT +#elif CONSOLE_BITS == 7 +# define CONSOLE_LCR_WLS UART_LCR_WLS_7BIT +#elif CONSOLE_BITS == 8 +# define CONSOLE_LCR_WLS UART_LCR_WLS_8BIT +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) +#elif CONSOLE_PARITY == 3 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) +#elif CONSOLE_PARITY == 4 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and USART0/2/3, UART1 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP UART_LCR_STOP +#else +# define CONSOLE_LCR_STOP 0 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | \ + CONSOLE_LCR_STOP) +#define CONSOLE_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ + UART_FCR_RXRST | UART_FCR_FIFOEN) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART && defined HAVE_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(CONSOLE_BASE+LPC43_UART_LSR_OFFSET) & UART_LSR_THRE) == 0); + + /* Send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE+LPC43_UART_THR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: lpc43_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + * The USART0/2/3 and UART1 peripherals are configured using the following registers: + * 1. Baud rate: In the LCR register, set bit DLAB = 1. This enables access + * to registers DLL and DLM for setting the baud rate. Also, if needed, + * set the fractional baud rate in the fractional divider + * 2. UART FIFO: Use bit FIFO enable (bit 0) in FCR register to + * enable FIFO. + * 3. Pins: Select UART pins through the PINSEL registers and pin modes + * through the PINMODE registers. UART receive pins should not have + * pull-down resistors enabled. + * 4. Interrupts: To enable UART interrupts set bit DLAB = 0 in the LCRF + * register. This enables access to IER. Interrupts are enabled + * in the NVIC using the appropriate Interrupt Set Enable register. + * 5. DMA: UART transmit and receive functions can operate with the + * GPDMA controller. + * + ****************************************************************************/ + +void lpc43_lowsetup(void) +{ +#ifdef HAVE_UART + /* Enable clocking and for all console UART and disable power for + * other UARTs + */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) + lpc43_usart0_setup(); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + lpc43_uart1_setup(); +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) + lpc43_usart2_setup(); +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) + lpc43_usart3_setup(); +#endif + + /* Configure the console (only) */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + /* Clear fifos */ + + putreg32(UART_FCR_RXRST | UART_FCR_TXRST, + CONSOLE_BASE + LPC43_UART_FCR_OFFSET); + + /* Set trigger */ + + putreg32(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8, + CONSOLE_BASE + LPC43_UART_FCR_OFFSET); + + /* Set up the LCR */ + + putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE + LPC43_UART_LCR_OFFSET); + + /* Set the BAUD divisor */ + + lpc43_setbaud(CONSOLE_BASE, CONSOLE_BASEFREQ, CONSOLE_BAUD); + + /* Configure the FIFOs */ + + putreg32(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN, CONSOLE_BASE + LPC43_UART_FCR_OFFSET); +#endif +#endif /* HAVE_UART */ +} + +/**************************************************************************** + * Name: lpc43_u[s]art0/1/2/3_reset + * + * Description: + * Reset a UART. These functions are used by the serial driver when a + * UART is closed. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_USART0 +void lpc43_usart0_reset(void) +{ + putreg32(RGU_CTRL1_USART0_RST, LPC43_RGU_CTRL1); +} +#endif + +#ifdef CONFIG_LPC43_UART1 +void lpc43_uart1_reset(void) +{ + putreg32(RGU_CTRL1_UART1_RST, LPC43_RGU_CTRL1); +} +#endif + +#ifdef CONFIG_LPC43_USART2 +void lpc43_usart2_reset(void) +{ + putreg32(RGU_CTRL1_USART2_RST, LPC43_RGU_CTRL1); +} +#endif + +#ifdef CONFIG_LPC43_USART3 +void lpc43_usart3_reset(void) +{ + putreg32(RGU_CTRL1_USART3_RST, LPC43_RGU_CTRL1); +} +#endif + +/**************************************************************************** + * Name: lpc43_usart0_setup, lpc43_uart1_setup, lpc43_usart2_setup, and + * lpc43_usart3_setup + * + * Description: + * Configure the U[S]ART. This involves: + * + * 1. Connecting the input clock to the U[S]ART as specified in the + * board.h file, + * 2. Configuring the U[S]ART pins + * + * USART0/2/3 and UART1 clocking and power control: + * + * ----------------------------------- -------------- -------------- + * BASE CLOCK BRANCH CLOCK + * ----------------------------------- -------------- -------------- + * USART0 clock to register interface BASE_M4_CLK CLK_M4_USART0 + * USART0 peripheral clock (PCLK) BASE_UART0_CLK CLK_APB0_UART0 + * UART1 clock to register interface BASE_M4_CLK CLK_M4_UART1 + * UART1 peripheral clock (PCLK) BASE_UART1_CLK CLK_APB0_UART1 + * USART2 clock to register interface BASE_M4_CLK CLK_M4_USART2 + * USART2 peripheral clock (PCLK) BASE_UART2_CLK CLK_APB2_UART2 + * USART3 clock to register interface BASE_M4_CLK CLK_M4_USART3 + * USART3 peripheral clock (PCLK) BASE_UART3_CLK CLK_APB2_UART3 + * ----------------------------------- -------------- -------------- + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_USART0 +void lpc43_usart0_setup(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Connect USART0 into the clock source specified in board.h */ + + flags = enter_critical_section(); + + regval = getreg32(LPC43_BASE_USART0_CLK); + regval &= ~BASE_USART0_CLK_CLKSEL_MASK; + regval |= (BOARD_USART0_CLKSRC | BASE_USART0_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_USART0_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_USART0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_USART0_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB0_USART0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB0_USART0_CFG); + + /* Configure I/O pins. NOTE that multiple pin configuration options must + * be disambiguated by defining the pin configuration in the board.h + * header file. + */ + + lpc43_pin_config(PINCONF_U0_TXD); + lpc43_pin_config(PINCONF_U0_RXD); + + /* If USART RS-485 mode is selected, then configure the DIR pin as well. + * NOTE, again, that multiple pin configuration options must be + * disambiguated by defining the pin configuration in the board.h header + * file. + */ + +#ifdef CONFIG_USART0_RS485MODE + lpc43_pin_config(PINCONF_U0_DIR); +#endif + + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC43_UART1 +void lpc43_uart1_setup(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Connect UART1 into the clock source specified in board.h */ + + flags = enter_critical_section(); + + regval = getreg32(LPC43_BASE_UART1_CLK); + regval &= ~BASE_UART1_CLK_CLKSEL_MASK; + regval |= (BOARD_UART1_CLKSRC | BASE_UART1_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_UART1_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_UART1_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_UART1_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB0_UART1_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB0_UART1_CFG); + + /* Configure I/O pins. NOTE that multiple pin configuration options must + * be disambiguated by defining the pin configuration in the board.h + * header file. + */ + + lpc43_pin_config(PINCONF_U1_TXD); + lpc43_pin_config(PINCONF_U1_RXD); +#ifdef CONFIG_UART1_FLOWCONTROL + lpc43_pin_config(PINCONF_U1_CTS); + lpc43_pin_config(PINCONF_U1_DCD); + lpc43_pin_config(PINCONF_U1_DSR); + lpc43_pin_config(PINCONF_U1_DTR); + lpc43_pin_config(PINCONF_U1_RTS); +#ifdef CONFIG_UART1_RINGINDICATOR + lpc43_pin_config(PINCONF_U1_RI); +#endif +#endif + +#ifdef CONFIG_UART1_RS485MODE + lpc43_pin_config(PINCONF_U1_DIR); +#endif + + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC43_USART2 +void lpc43_usart2_setup(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Connect USART2 the clock source specified in board.h */ + + flags = enter_critical_section(); + + regval = getreg32(LPC43_BASE_USART2_CLK); + regval &= ~BASE_USART2_CLK_CLKSEL_MASK; + regval |= (BOARD_USART2_CLKSRC | BASE_USART2_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_USART2_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_USART2_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_USART2_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB2_USART2_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB2_USART2_CFG); + + + /* Configure I/O pins. NOTE that multiple pin configuration options must + * be disambiguated by defining the pin configuration in the board.h + * header file. + */ + + lpc43_pin_config(PINCONF_U2_TXD); + lpc43_pin_config(PINCONF_U2_RXD); + + /* If USART RS-485 mode is selected, then configure the DIR pin as well. + * NOTE, again, that multiple pin configuration options must be + * disambiguated by defining the pin configuration in the board.h header + * file. + */ + +#ifdef CONFIG_USART2_RS485MODE + lpc43_pin_config(PINCONF_U2_DIR); +#endif + + leave_critical_section(flags); +}; +#endif + +#ifdef CONFIG_LPC43_USART3 +void lpc43_usart3_setup(void) +{ + uint32_t regval; + irqstate_t flags; + + /* Connect USART3 into the clock source specified in board.h */ + + flags = enter_critical_section(); + + regval = getreg32(LPC43_BASE_USART3_CLK); + regval &= ~BASE_USART3_CLK_CLKSEL_MASK; + regval |= (BOARD_USART3_CLKSRC | BASE_USART3_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_USART3_CLK); + + /* Clock register */ + + regval = getreg32(LPC43_CCU1_M4_USART3_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_USART3_CFG); + + /* Clock peripheral */ + + regval = getreg32(LPC43_CCU2_APB2_USART3_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU2_APB2_USART3_CFG); + + /* Configure I/O pins. NOTE that multiple pin configuration options must + * be disambiguated by defining the pin configuration in the board.h + * header file. + */ + + lpc43_pin_config(PINCONF_U3_TXD); + lpc43_pin_config(PINCONF_U3_RXD); + + /* If USART RS-485 mode is selected, then configure the DIR pin as well. + * NOTE, again, that multiple pin configuration options must be + * disambiguated by defining the pin configuration in the board.h header + * file. + */ + +#ifdef CONFIG_USART3_RS485MODE + lpc43_pin_config(PINCONF_U3_DIR); +#endif + + leave_critical_section(flags); +}; +#endif + +/**************************************************************************** + * Name: lpc43_setbaud + * + * Description: + * Configure the U[S]ART divisors to accomplish the desired BAUD given the + * U[S]ART base frequency. + * + * This computationally intensive algorithm is based on the same logic + * used in the NXP sample code. + * + ****************************************************************************/ + +void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud) +{ + uint32_t lcr; /* Line control register value */ + uint32_t dl; /* Best DLM/DLL full value */ + uint32_t mul; /* Best FDR MULVALL value */ + uint32_t divadd; /* Best FDR DIVADDVAL value */ + uint32_t best; /* Error value associated with best {dl, mul, divadd} */ + uint32_t cdl; /* Candidate DLM/DLL full value */ + uint32_t cmul; /* Candidate FDR MULVALL value */ + uint32_t cdivadd; /* Candidate FDR DIVADDVAL value */ + uint32_t errval; /* Error value associated with the candidate */ + + /* The U[S]ART buad is given by: + * + * Fbaud = Fbase * mul / (mul + divadd) / (16 * dl) + * dl = Fbase * mul / (mul + divadd) / Fbaud / 16 + * = Fbase * mul / ((mul + divadd) * Fbaud * 16) + * = ((Fbase * mul) >> 4) / ((mul + divadd) * Fbaud) + * + * Where the value of MULVAL and DIVADDVAL comply with: + * + * 0 < mul < 16 + * 0 <= divadd < mul + */ + + best = UINT32_MAX; + divadd = 0; + mul = 0; + dl = 0; + + /* Try each mulitplier value in the valid range */ + + for (cmul = 1 ; cmul < 16; cmul++) + { + /* Try each divider value in the valid range */ + + for (cdivadd = 0 ; cdivadd < cmul ; cdivadd++) + { + /* Candidate: + * dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud) + * (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud) + */ + + uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul / + ((cmul + cdivadd) * baud); + + /* The lower 32-bits of this value is the error */ + + errval = (uint32_t)(dl64 & 0x00000000ffffffffull); + + /* The upper 32-bits is the candidate DL value */ + + cdl = (uint32_t)(dl64 >> 32); + + /* Round up */ + + if (errval > (1 << 31)) + { + errval = -errval; + cdl++; + } + + /* Check if the resulting candidate DL value is within range */ + + if (cdl < 1 || cdl > 65536) + { + /* No... try a different divadd value */ + + continue; + } + + /* Is this the best combination that we have seen so far? */ + + if (errval < best) + { + /* Yes.. then the candidate is out best guess so far */ + + best = errval; + dl = cdl; + divadd = cdivadd; + mul = cmul; + + /* If the new best guess is exact (within our precision), then + * we are finished. + */ + + if (best == 0) + { + break; + } + } + } + } + + DEBUGASSERT(dl > 0); + + /* Enter DLAB=1 */ + + lcr = getreg32(uartbase + LPC43_UART_LCR_OFFSET); + putreg32(lcr | UART_LCR_DLAB, uartbase + LPC43_UART_LCR_OFFSET); + + /* Save then divider values */ + + putreg32(dl >> 8, uartbase + LPC43_UART_DLM_OFFSET); + putreg32(dl & 0xff, uartbase + LPC43_UART_DLL_OFFSET); + + /* Clear DLAB */ + + putreg32(lcr & ~UART_LCR_DLAB, uartbase + LPC43_UART_LCR_OFFSET); + + /* Then save the fractional divider values */ + + putreg32((mul << UART_FDR_MULVAL_SHIFT) | (divadd << UART_FDR_DIVADDVAL_SHIFT), + uartbase + LPC43_UART_FDR_OFFSET); +} diff --git a/arch/arm/src/lpc43xx/lpc43_uart.h b/arch/arm/src/lpc43xx/lpc43_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..b34efd732849ccd7038a1de43fc55256896bdb18 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_uart.h @@ -0,0 +1,157 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_uart.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_LOWSETUP_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_LOWSETUP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "chip/lpc43_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization of the serial console. + * + ****************************************************************************/ + +void lpc43_lowsetup(void); + +/**************************************************************************** + * Name: lpc43_usart0_reset, lpc43_uart1_reset, lpc43_usart2_reset, and + * lpc43_usart3_reset + * + * Description: + * Reset a U[S]ART. These functions are used by the serial driver when a + * U[S]ART is closed. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_USART0 +void lpc43_usart0_reset(void); +#endif +#ifdef CONFIG_LPC43_UART1 +void lpc43_uart1_reset(void); +#endif +#ifdef CONFIG_LPC43_USART2 +void lpc43_usart2_reset(void); +#endif +#ifdef CONFIG_LPC43_USART3 +void lpc43_usart3_reset(void); +#endif + +/**************************************************************************** + * Name: lpc43_usart0_setup, lpc43_uart1_setup, lpc43_usart2_setup, and + * lpc43_usart3_setup + * + * Description: + * Configure the U[S]ART. This involves: + * + * 1. Connecting the input clock to the U[S]ART as specified in the + * board.h file, + * 2. Configuring the U[S]ART pins + * + ****************************************************************************/ + +#ifdef CONFIG_LPC43_USART0 +void lpc43_usart0_setup(void); +#endif + +#ifdef CONFIG_LPC43_UART1 +void lpc43_uart1_setup(void); +#endif + +#ifdef CONFIG_LPC43_USART2 +void lpc43_usart2_setup(void); +#endif + +#ifdef CONFIG_LPC43_USART3 +void lpc43_usart3_setup(void); +#endif + +/**************************************************************************** + * Name: lpc43_setbaud + * + * Description: + * Configure the U[S]ART divisors to accomplish the desired BAUD given the + * U[S]ART base frequency. + * + * This computationally intensive algorithm is based on the same logic + * used in the NXP sample code. + * + ****************************************************************************/ + +void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_LOWSETUP_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_usb0dev.c b/arch/arm/src/lpc43xx/lpc43_usb0dev.c new file mode 100644 index 0000000000000000000000000000000000000000..57e3ef2c8ce7a934c7e606182a53b1ab49403721 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_usb0dev.c @@ -0,0 +1,2875 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_usb0dev.c + * + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Part of the NuttX OS and based, in part, on the LPC31xx USB driver: + * + * Authors: David Hewson + * Gregory Nutt + * + * Which, in turn, was based on the LPC2148 USB driver: + * + * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "lpc43_usb0dev.h" +#include "lpc43_creg.h" +#include "lpc43_ccu.h" +#include "lpc43_cgu.h" +#include "lpc43_rgu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#undef CONFIG_LPC43_USBDEV_REGDEBUG + +/* Enable reading SOF from interrupt handler vs. simply reading on demand. Probably + * a bad idea... Unless there is some issue with sampling the SOF from hardware + * asynchronously. + */ + +#ifdef CONFIG_LPC43_USBDEV_FRAME_INTERRUPT +# define USB_FRAME_INT USBDEV_USBINTR_SRE +#else +# define USB_FRAME_INT 0 +#endif + +#ifdef CONFIG_DEBUG +# define USB_ERROR_INT USBDEV_USBINTR_UEE +#else +# define USB_ERROR_INT 0 +#endif + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define LPC43_TRACEERR_ALLOCFAIL 0x0001 +#define LPC43_TRACEERR_BADCLEARFEATURE 0x0002 +#define LPC43_TRACEERR_BADDEVGETSTATUS 0x0003 +#define LPC43_TRACEERR_BADEPNO 0x0004 +#define LPC43_TRACEERR_BADEPGETSTATUS 0x0005 +#define LPC43_TRACEERR_BADEPTYPE 0x0006 +#define LPC43_TRACEERR_BADGETCONFIG 0x0007 +#define LPC43_TRACEERR_BADGETSETDESC 0x0008 +#define LPC43_TRACEERR_BADGETSTATUS 0x0009 +#define LPC43_TRACEERR_BADSETADDRESS 0x000a +#define LPC43_TRACEERR_BADSETCONFIG 0x000b +#define LPC43_TRACEERR_BADSETFEATURE 0x000c +#define LPC43_TRACEERR_BINDFAILED 0x000d +#define LPC43_TRACEERR_DISPATCHSTALL 0x000e +#define LPC43_TRACEERR_DRIVER 0x000f +#define LPC43_TRACEERR_DRIVERREGISTERED 0x0010 +#define LPC43_TRACEERR_EP0SETUPSTALLED 0x0011 +#define LPC43_TRACEERR_EPINNULLPACKET 0x0012 +#define LPC43_TRACEERR_EPOUTNULLPACKET 0x0013 +#define LPC43_TRACEERR_INVALIDCTRLREQ 0x0014 +#define LPC43_TRACEERR_INVALIDPARMS 0x0015 +#define LPC43_TRACEERR_IRQREGISTRATION 0x0016 +#define LPC43_TRACEERR_NOEP 0x0017 +#define LPC43_TRACEERR_NOTCONFIGURED 0x0018 +#define LPC43_TRACEERR_REQABORTED 0x0019 + +/* Trace interrupt codes */ + +#define LPC43_TRACEINTID_USB 0x0001 +#define LPC43_TRACEINTID_CLEARFEATURE 0x0002 +#define LPC43_TRACEINTID_DEVGETSTATUS 0x0003 +#define LPC43_TRACEINTID_DEVRESET 0x0004 +#define LPC43_TRACEINTID_DISPATCH 0x0005 +#define LPC43_TRACEINTID_EP0COMPLETE 0x0006 +#define LPC43_TRACEINTID_EP0NAK 0x0007 +#define LPC43_TRACEINTID_EP0SETUP 0x0008 +#define LPC43_TRACEINTID_EPGETSTATUS 0x0009 +#define LPC43_TRACEINTID_EPIN 0x000a +#define LPC43_TRACEINTID_EPINQEMPTY 0x000b +#define LPC43_TRACEINTID_EP0INSETADDRESS 0x000c +#define LPC43_TRACEINTID_EPOUT 0x000d +#define LPC43_TRACEINTID_EPOUTQEMPTY 0x000e +#define LPC43_TRACEINTID_EP0SETUPSETADDRESS 0x000f +#define LPC43_TRACEINTID_FRAME 0x0010 +#define LPC43_TRACEINTID_GETCONFIG 0x0011 +#define LPC43_TRACEINTID_GETSETDESC 0x0012 +#define LPC43_TRACEINTID_GETSETIF 0x0013 +#define LPC43_TRACEINTID_GETSTATUS 0x0014 +#define LPC43_TRACEINTID_IFGETSTATUS 0x0015 +#define LPC43_TRACEINTID_SETCONFIG 0x0016 +#define LPC43_TRACEINTID_SETFEATURE 0x0017 +#define LPC43_TRACEINTID_SUSPENDED 0x0018 +#define LPC43_TRACEINTID_RESUMED 0x0019 +#define LPC43_TRACEINTID_SYNCHFRAME 0x001a + +/* Hardware interface **********************************************************/ + +/* This represents a Endpoint Transfer Descriptor - note these must be 32 byte + * aligned. + */ + +struct lpc43_dtd_s +{ + volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */ + volatile uint32_t config; /* Misc. bit encoded configuration information */ + uint32_t buffer0; /* Buffer start address */ + uint32_t buffer1; /* Buffer start address */ + uint32_t buffer2; /* Buffer start address */ + uint32_t buffer3; /* Buffer start address */ + uint32_t buffer4; /* Buffer start address */ + uint32_t xfer_len; /* Software only - transfer len that was queued */ +}; + +/* DTD nextdesc field */ + +#define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid */ + +/* DTD config field */ + +#define DTD_CONFIG_LENGTH(n) ((n) << 16) /* Bits 16-31 : Total bytes to transfer */ +#define DTD_CONFIG_IOC (1 << 15) /* Bit 15 : Interrupt on Completion */ +#define DTD_CONFIG_MULT_VARIABLE (0 << 10) /* Bits 10-11 : Number of packets executed per transacation descriptor (override) */ +#define DTD_CONFIG_MULT_NUM(n) ((n) << 10) +#define DTD_CONFIG_ACTIVE (1 << 7) /* Bit 7 : Status Active */ +#define DTD_CONFIG_HALTED (1 << 6) /* Bit 6 : Status Halted */ +#define DTD_CONFIG_BUFFER_ERROR (1 << 5) /* Bit 6 : Status Buffer Error */ +#define DTD_CONFIG_TRANSACTION_ERROR (1 << 3) /* Bit 3 : Status Transaction Error */ + +/* This represents a queue head - not these must be aligned to a 2048 byte boundary */ + +struct lpc43_dqh_s +{ + uint32_t capability; /* Endpoint capability */ + uint32_t currdesc; /* Current dTD pointer */ + struct lpc43_dtd_s overlay; /* DTD overlay */ + volatile uint32_t setup[2]; /* Set-up buffer */ + uint32_t gap[4]; /* align to 64 bytes */ +}; + +/* DQH capability field */ + +#define DQH_CAPABILITY_MULT_VARIABLE (0 << 30) /* Bits 30-31 : Number of packets executed per transaction descriptor */ +#define DQH_CAPABILITY_MULT_NUM(n) ((n) << 30) +#define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */ +#define DQH_CAPABILITY_MAX_PACKET(n) ((n) << 16) /* Bits 16-29 : Maximum packet size of associated endpoint (<1024) */ +#define DQH_CAPABILITY_IOS (1 << 15) /* Bit 15 : Interrupt on Setup */ + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define LPC43_NLOGENDPOINTS (6) /* ep0-3 */ +#define LPC43_NPHYSENDPOINTS (12) /* x2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define LPC43_EPPHYIN(epphy) (((epphy) & 1) != 0) +#define LPC43_EPPHYOUT(epphy) (((epphy) & 1) == 0) + +#define LPC43_EPPHYIN2LOG(epphy) (((uint8_t)(epphy) >> 1) |USB_DIR_IN) +#define LPC43_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy) >> 1) | USB_DIR_OUT) + +/* Endpoint 0 is special... */ + +#define LPC43_EP0_OUT (0) +#define LPC43_EP0_IN (1) + +/* Each endpoint has somewhat different characteristics */ + +#define LPC43_EPALLSET (0xfff) /* All endpoints */ +#define LPC43_EPOUTSET (0x555) /* Even phy endpoint numbers are OUT EPs */ +#define LPC43_EPINSET (0xaaa) /* Odd endpoint numbers are IN EPs */ +#define LPC43_EPCTRLSET (0x003) /* EP0 IN/OUT are control endpoints */ +#define LPC43_EPINTRSET (0xffc) /* Interrupt endpoints */ +#define LPC43_EPBULKSET (0xffc) /* Bulk endpoints */ +#define LPC43_EPISOCSET (0xffc) /* Isochronous endpoints */ + +/* Maximum packet sizes for endpoints */ + +#define LPC43_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ +#define LPC43_BULKMAXPACKET (512) /* Bulk endpoint max packet (8/16/32/64/512) */ +#define LPC43_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */ +#define LPC43_ISOCMAXPACKET (512) /* Acutally 1..1023 */ + +/* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE registers */ + +#define LPC43_ENDPTSHIFT(epphy) (LPC43_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1)) +#define LPC43_ENDPTMASK(epphy) (1 << LPC43_ENDPTSHIFT(epphy)) +#define LPC43_ENDPTMASK_ALL 0x003f003f + +/* Request queue operations ****************************************************/ + +#define lpc43_rqempty(ep) ((ep)->head == NULL) +#define lpc43_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request may be retained in a list */ + +struct lpc43_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct lpc43_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct lpc43_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct lpc43_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* LPC43XX-specific fields */ + + struct lpc43_usbdev_s *dev; /* Reference to private driver data */ + struct lpc43_req_s *head; /* Request list for this endpoint */ + struct lpc43_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ +}; + +/* This structure retains the state of the USB device controller */ + +struct lpc43_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct lpc43_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* LPC43XX-specific fields */ + + uint8_t ep0state; /* State of certain EP0 operations */ + uint8_t ep0buf[64]; /* buffer for EP0 short transfers */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t suspended:1; /* 1: Suspended */ + uint32_t softprio; /* Bitset of high priority interrupts */ + uint32_t epavail; /* Bitset of available endpoints */ +#ifdef CONFIG_LPC43_USBDEV_FRAME_INTERRUPT + uint32_t sof; /* Last start-of-frame */ +#endif + + uint16_t ep0buf_len; + struct usb_ctrlreq_s ep0ctrl; + + /* The endpoint list */ + + struct lpc43_ep_s eplist[LPC43_NPHYSENDPOINTS]; +}; + +#define EP0STATE_IDLE 0 /* Idle State, leave on receiving a setup packet or epsubmit */ +#define EP0STATE_SETUP_OUT 1 /* Setup Packet received - SET/CLEAR */ +#define EP0STATE_SETUP_IN 2 /* Setup Packet received - GET */ +#define EP0STATE_SHORTREAD 3 /* Short read without a usb_request */ +#define EP0STATE_SHORTWRITE 4 /* Short write without a usb_request */ +#define EP0STATE_WAIT_NAK_OUT 5 /* Waiting for Host to illicit status phase (GET) */ +#define EP0STATE_WAIT_NAK_IN 6 /* Waiting for Host to illicit status phase (SET/CLEAR) */ +#define EP0STATE_WAIT_STATUS_OUT 7 /* Wait for status phase to complete */ +#define EP0STATE_WAIT_STATUS_IN 8 /* Wait for status phase to complete */ +#define EP0STATE_DATA_IN 9 +#define EP0STATE_DATA_OUT 10 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_LPC43_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc43_getreg(uint32_t addr); +static void lpc43_putreg(uint32_t val, uint32_t addr); +#else +# define lpc43_getreg(addr) getreg32(addr) +# define lpc43_putreg(val,addr) putreg32(val,addr) +#endif + +static inline void lpc43_clrbits(uint32_t mask, uint32_t addr); +static inline void lpc43_setbits(uint32_t mask, uint32_t addr); +static inline void lpc43_chgbits(uint32_t mask, uint32_t val, uint32_t addr); + +/* Request queue operations ****************************************************/ + +static FAR struct lpc43_req_s *lpc43_rqdequeue(FAR struct lpc43_ep_s *privep); +static bool lpc43_rqenqueue(FAR struct lpc43_ep_s *privep, + FAR struct lpc43_req_s *req); + +/* Low level data transfers and request operations *****************************/ + +static inline void lpc43_writedtd(struct lpc43_dtd_s *dtd, const uint8_t *data, + uint32_t nbytes); +static inline void lpc43_queuedtd(uint8_t epphy, struct lpc43_dtd_s *dtd); +static inline void lpc43_ep0xfer(uint8_t epphy, uint8_t *data, uint32_t nbytes); +static void lpc43_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl); + +static inline void lpc43_set_address(struct lpc43_usbdev_s *priv, uint16_t address); + +static void lpc43_flushep(struct lpc43_ep_s *privep); + +static int lpc43_progressep(struct lpc43_ep_s *privep); +static inline void lpc43_abortrequest(struct lpc43_ep_s *privep, + struct lpc43_req_s *privreq, int16_t result); +static void lpc43_reqcomplete(struct lpc43_ep_s *privep, + struct lpc43_req_s *privreq, int16_t result); + +static void lpc43_cancelrequests(struct lpc43_ep_s *privep, int16_t status); + +/* Interrupt handling **********************************************************/ + +static struct lpc43_ep_s *lpc43_epfindbyaddr(struct lpc43_usbdev_s *priv, + uint16_t eplog); +static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static void lpc43_ep0configure(struct lpc43_usbdev_s *priv); +static void lpc43_usbreset(struct lpc43_usbdev_s *priv); + +static inline void lpc43_ep0state(struct lpc43_usbdev_s *priv, uint16_t state); +static void lpc43_ep0setup(struct lpc43_usbdev_s *priv); + +static void lpc43_ep0complete(struct lpc43_usbdev_s *priv, uint8_t epphy); +static void lpc43_ep0nak(struct lpc43_usbdev_s *priv, uint8_t epphy); +static bool lpc43_epcomplete(struct lpc43_usbdev_s *priv, uint8_t epphy); + +static int lpc43_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ + +/* USB device controller operations ********************************************/ + +static int lpc43_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int lpc43_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *lpc43_epallocreq(FAR struct usbdev_ep_s *ep); +static void lpc43_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *lpc43_epallocbuffer(FAR struct usbdev_ep_s *ep, + unsigned bytes); +static void lpc43_epfreebuffer(FAR struct usbdev_ep_s *ep, + FAR void *buf); +#endif +static int lpc43_epsubmit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc43_epcancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int lpc43_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +static FAR struct usbdev_ep_s *lpc43_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void lpc43_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int lpc43_getframe(struct usbdev_s *dev); +static int lpc43_wakeup(struct usbdev_s *dev); +static int lpc43_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int lpc43_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct lpc43_usbdev_s g_usbdev; + +static struct lpc43_dqh_s __attribute__((aligned(2048))) g_qh[LPC43_NPHYSENDPOINTS]; +static struct lpc43_dtd_s __attribute__((aligned(32))) g_td[LPC43_NPHYSENDPOINTS]; + +static const struct usbdev_epops_s g_epops = +{ + .configure = lpc43_epconfigure, + .disable = lpc43_epdisable, + .allocreq = lpc43_epallocreq, + .freereq = lpc43_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = lpc43_epallocbuffer, + .freebuffer = lpc43_epfreebuffer, +#endif + .submit = lpc43_epsubmit, + .cancel = lpc43_epcancel, + .stall = lpc43_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = lpc43_allocep, + .freeep = lpc43_freeep, + .getframe = lpc43_getframe, + .wakeup = lpc43_wakeup, + .selfpowered = lpc43_selfpowered, + .pullup = lpc43_pullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_getreg + * + * Description: + * Get the contents of an LPC433x register + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t lpc43_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: lpc43_putreg + * + * Description: + * Set the contents of an LPC433x register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_LPC43_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void lpc43_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: lpc43_clrbits + * + * Description: + * Clear bits in a register + * + ****************************************************************************/ + +static inline void lpc43_clrbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = lpc43_getreg(addr); + reg &= ~mask; + lpc43_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc43_setbits + * + * Description: + * Set bits in a register + * + ****************************************************************************/ + +static inline void lpc43_setbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = lpc43_getreg(addr); + reg |= mask; + lpc43_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc43_chgbits + * + * Description: + * Change bits in a register + * + ****************************************************************************/ + +static inline void lpc43_chgbits(uint32_t mask, uint32_t val, uint32_t addr) +{ + uint32_t reg = lpc43_getreg(addr); + reg &= ~mask; + reg |= val; + lpc43_putreg(reg, addr); +} + +/**************************************************************************** + * Name: lpc43_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct lpc43_req_s *lpc43_rqdequeue(FAR struct lpc43_ep_s *privep) +{ + FAR struct lpc43_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: lpc43_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static bool lpc43_rqenqueue(FAR struct lpc43_ep_s *privep, + FAR struct lpc43_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + + return is_empty; +} + +/**************************************************************************** + * Name: lpc43_writedtd + * + * Description: + * Initialise a DTD to transfer the data + * + ****************************************************************************/ + +static inline void lpc43_writedtd(struct lpc43_dtd_s *dtd, const uint8_t *data, uint32_t nbytes) +{ + dtd->nextdesc = DTD_NEXTDESC_INVALID; + dtd->config = DTD_CONFIG_LENGTH(nbytes) | DTD_CONFIG_IOC | DTD_CONFIG_ACTIVE; + dtd->buffer0 = ((uint32_t) data); + dtd->buffer1 = (((uint32_t) data) + 0x1000) & 0xfffff000; + dtd->buffer2 = (((uint32_t) data) + 0x2000) & 0xfffff000; + dtd->buffer3 = (((uint32_t) data) + 0x3000) & 0xfffff000; + dtd->buffer4 = (((uint32_t) data) + 0x4000) & 0xfffff000; + dtd->xfer_len = nbytes; +} + +/**************************************************************************** + * Name: lpc43_queuedtd + * + * Description: + * Add the DTD to the device list + * + ****************************************************************************/ + +static void lpc43_queuedtd(uint8_t epphy, struct lpc43_dtd_s *dtd) +{ + /* Queue the DTD onto the Endpoint */ + /* NOTE - this only works when no DTD is currently queued */ + + g_qh[epphy].overlay.nextdesc = (uint32_t) dtd; + g_qh[epphy].overlay.config &= ~(DTD_CONFIG_ACTIVE | DTD_CONFIG_HALTED); + + uint32_t bit = LPC43_ENDPTMASK(epphy); + + lpc43_setbits (bit, LPC43_USBDEV_ENDPTPRIME); + + while (lpc43_getreg (LPC43_USBDEV_ENDPTPRIME) & bit) + ; +} + +/**************************************************************************** + * Name: lpc43_ep0xfer + * + * Description: + * Schedule a short transfer for Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static inline void lpc43_ep0xfer(uint8_t epphy, uint8_t *buf, uint32_t nbytes) +{ + struct lpc43_dtd_s *dtd = &g_td[epphy]; + + lpc43_writedtd(dtd, buf, nbytes); + + lpc43_queuedtd(epphy, dtd); +} + +/**************************************************************************** + * Name: lpc43_readsetup + * + * Description: + * Read a Setup packet from the DTD. + * + ****************************************************************************/ +static void lpc43_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl) +{ + struct lpc43_dqh_s *dqh = &g_qh[epphy]; + int i; + + do + { + /* Set the trip wire */ + + lpc43_setbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); + + /* Copy the request... */ + + for (i = 0; i < 8; i++) + { + ((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i]; + } + } + while (!(lpc43_getreg(LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW)); + + /* Clear the trip wire */ + + lpc43_clrbits(USBDEV_USBCMD_SUTW, LPC43_USBDEV_USBCMD); + + /* Clear the Setup Interrupt */ + + lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTSETUPSTAT); +} + +/**************************************************************************** + * Name: lpc43_set_address + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static inline void lpc43_set_address(struct lpc43_usbdev_s *priv, uint16_t address) +{ + priv->paddr = address; + priv->paddrset = address != 0; + + lpc43_chgbits(USBDEV_DEVICEADDR_MASK, priv->paddr << USBDEV_DEVICEADDR_SHIFT, + LPC43_USBDEV_DEVICEADDR); +} + +/**************************************************************************** + * Name: lpc43_flushep + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void lpc43_flushep(struct lpc43_ep_s *privep) +{ + uint32_t mask = LPC43_ENDPTMASK(privep->epphy); + do + { + lpc43_putreg (mask, LPC43_USBDEV_ENDPTFLUSH); + while ((lpc43_getreg(LPC43_USBDEV_ENDPTFLUSH) & mask) != 0) + ; + } + while ((lpc43_getreg(LPC43_USBDEV_ENDPTSTATUS) & mask) != 0); +} + + +/**************************************************************************** + * Name: lpc43_progressep + * + * Description: + * Progress the Endpoint by priming the first request into the queue head + * + ****************************************************************************/ + +static int lpc43_progressep(struct lpc43_ep_s *privep) +{ + struct lpc43_dtd_s *dtd = &g_td[privep->epphy]; + struct lpc43_req_s *privreq; + + /* Check the request from the head of the endpoint request queue */ + + privreq = lpc43_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0); + return OK; + } + + /* Ignore any attempt to send a zero length packet */ + + if (privreq->req.len == 0) + { + /* If the class driver is responding to a setup packet, then wait for + * the host to illicit thr response + */ + + if (privep->epphy == LPC43_EP0_IN && privep->dev->ep0state == EP0STATE_SETUP_OUT) + { + lpc43_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN); + } + else + { + if (LPC43_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPINNULLPACKET), 0); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EPOUTNULLPACKET), 0); + } + } + + lpc43_reqcomplete(privep, lpc43_rqdequeue(privep), OK); + return OK; + } + + if (privep->epphy == LPC43_EP0_IN) + { + lpc43_ep0state (privep->dev, EP0STATE_DATA_IN); + } + else if (privep->epphy == LPC43_EP0_OUT) + { + lpc43_ep0state (privep->dev, EP0STATE_DATA_OUT); + } + + int bytesleft = privreq->req.len - privreq->req.xfrd; + + if (LPC43_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + } + else + { + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + } + + /* Initialise the DTD to transfer the next chunk */ + + lpc43_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft); + + /* Then queue onto the DQH */ + + lpc43_queuedtd(privep->epphy, dtd); + + return OK; +} + +/**************************************************************************** + * Name: lpc43_abortrequest + * + * Description: + * Discard a request + * + ****************************************************************************/ + +static inline void lpc43_abortrequest(struct lpc43_ep_s *privep, + struct lpc43_req_s *privreq, + int16_t result) +{ + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_REQABORTED), (uint16_t)privep->epphy); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: lpc43_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void lpc43_reqcomplete(struct lpc43_ep_s *privep, + struct lpc43_req_s *privreq, int16_t result) +{ + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == LPC43_EP0_IN) + privep->stalled = privep->dev->stalled; + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: lpc43_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void lpc43_cancelrequests(struct lpc43_ep_s *privep, int16_t status) +{ + if (!lpc43_rqempty(privep)) + lpc43_flushep(privep); + + while (!lpc43_rqempty(privep)) + { + /* FIXME: the entry at the head should be sync'd with the DTD + * FIXME: only report the error status if the transfer hasn't completed + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), + (lpc43_rqpeek(privep))->req.xfrd); + lpc43_reqcomplete(privep, lpc43_rqdequeue(privep), status); + } +} + +/**************************************************************************** + * Name: lpc43_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct lpc43_ep_s *lpc43_epfindbyaddr(struct lpc43_usbdev_s *priv, + uint16_t eplog) +{ + struct lpc43_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < LPC43_NPHYSENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: lpc43_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static void lpc43_dispatchrequest(struct lpc43_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, priv->ep0buf, priv->ep0buf_len); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } +} + +/**************************************************************************** + * Name: lpc43_ep0configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc43_ep0configure(struct lpc43_usbdev_s *priv) +{ + /* Enable ep0 IN and ep0 OUT */ + + g_qh[LPC43_EP0_OUT].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | DQH_CAPABILITY_ZLT); + + g_qh[LPC43_EP0_IN].capability = (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | DQH_CAPABILITY_ZLT); + + g_qh[LPC43_EP0_OUT].currdesc = DTD_NEXTDESC_INVALID; + g_qh[LPC43_EP0_IN].currdesc = DTD_NEXTDESC_INVALID; + + /* Enable EP0 */ + + lpc43_setbits (USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE, LPC43_USBDEV_ENDPTCTRL0); +} + +/**************************************************************************** + * Name: lpc43_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void lpc43_usbreset(struct lpc43_usbdev_s *priv) +{ + int epphy; + + /* Disable all endpoints. Control endpoint 0 is always enabled */ + + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL1); + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL2); + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL3); + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL4); + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL5); + + /* Clear all pending interrupts */ + + lpc43_putreg (lpc43_getreg(LPC43_USBDEV_ENDPTNAK), LPC43_USBDEV_ENDPTNAK); + lpc43_putreg (lpc43_getreg(LPC43_USBDEV_ENDPTSETUPSTAT), LPC43_USBDEV_ENDPTSETUPSTAT); + lpc43_putreg (lpc43_getreg(LPC43_USBDEV_ENDPTCOMPLETE), LPC43_USBDEV_ENDPTCOMPLETE); + + /* Wait for all prime operations to have completed and then flush all DTDs */ + + while (lpc43_getreg (LPC43_USBDEV_ENDPTPRIME) != 0) + ; + lpc43_putreg (LPC43_ENDPTMASK_ALL, LPC43_USBDEV_ENDPTFLUSH); + while (lpc43_getreg (LPC43_USBDEV_ENDPTFLUSH)) + ; + + /* Reset endpoints */ + + for (epphy = 0; epphy < LPC43_NPHYSENDPOINTS; epphy++) + { + struct lpc43_ep_s *privep = &priv->eplist[epphy]; + + lpc43_cancelrequests (privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Set the interrupt Threshold control interval to 0 */ + + lpc43_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC43_USBDEV_USBCMD); + + /* Zero out the Endpoint queue heads */ + + memset ((void *) g_qh, 0, sizeof (g_qh)); + memset ((void *) g_td, 0, sizeof (g_td)); + + /* Set USB address to 0 */ + + lpc43_set_address (priv, 0); + + /* Initialise the Enpoint List Address */ + + lpc43_putreg ((uint32_t)g_qh, LPC43_USBDEV_ENDPOINTLIST); + + /* EndPoint 0 initialization */ + + lpc43_ep0configure(priv); + + /* Enable Device interrupts */ + + lpc43_putreg(USB_FRAME_INT | USB_ERROR_INT | + USBDEV_USBINTR_NAKE | USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | USBDEV_USBINTR_UE, + LPC43_USBDEV_USBINTR); +} + +/**************************************************************************** + * Name: lpc43_setstate + * + * Description: + * Sets the EP0 state and manages the NAK interrupts + * + ****************************************************************************/ + +static inline void lpc43_ep0state(struct lpc43_usbdev_s *priv, uint16_t state) +{ + priv->ep0state = state; + + switch (state) + { + case EP0STATE_WAIT_NAK_IN: + lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_IN), LPC43_USBDEV_ENDPTNAKEN); + break; + + case EP0STATE_WAIT_NAK_OUT: + lpc43_putreg (LPC43_ENDPTMASK(LPC43_EP0_OUT), LPC43_USBDEV_ENDPTNAKEN); + break; + + default: + lpc43_putreg(0, LPC43_USBDEV_ENDPTNAKEN); + break; + } +} + +/**************************************************************************** + * Name: lpc43_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void lpc43_ep0setup(struct lpc43_usbdev_s *priv) +{ + struct lpc43_ep_s *privep; + struct usb_ctrlreq_s *ctrl; + uint16_t value; + uint16_t index; + uint16_t len; + + ctrl = &priv->ep0ctrl; + + /* Terminate any pending requests - since all DTDs will have been retired + * because of the setup packet. + */ + + lpc43_cancelrequests(&priv->eplist[LPC43_EP0_OUT], -EPROTO); + lpc43_cancelrequests(&priv->eplist[LPC43_EP0_IN], -EPROTO); + + /* Assume NOT stalled */ + + priv->eplist[LPC43_EP0_OUT].stalled = false; + priv->eplist[LPC43_EP0_IN].stalled = false; + priv->stalled = false; + + /* Read EP0 setup data */ + + lpc43_readsetup(LPC43_EP0_OUT, ctrl); + + /* And extract the little-endian 16-bit values to host order */ + + value = GETUINT16(ctrl->value); + index = GETUINT16(ctrl->index); + len = GETUINT16(ctrl->len); + + priv->ep0buf_len = len; + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl->type, ctrl->req, value, index, len); + + /* Starting a control request - update state */ + + if (ctrl->type & USB_REQ_DIR_IN) + { + lpc43_ep0state (priv, EP0STATE_SETUP_IN); + } + else + { + lpc43_ep0state (priv, EP0STATE_SETUP_OUT); + + if (len > 0) + { + lpc43_ep0state(priv, EP0STATE_SHORTREAD); + lpc43_ep0xfer(LPC43_EP0_OUT, priv->ep0buf, len); + return; + } + } + + /* Dispatch any non-standard requests */ + + if ((ctrl->type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + lpc43_dispatchrequest(priv, ctrl); + } + else + { + /* Handle standard request. Pick off the things of interest to the USB + * device controller driver; pass what is left to the class driver. + */ + + switch (ctrl->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSTATUS), 0); + if (!priv->paddrset || len != 2 || + (ctrl->type & USB_REQ_DIR_IN) == 0 || value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrl->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPGETSTATUS), 0); + privep = lpc43_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0buf[0] = 1; /* Stalled */ + } + else + { + priv->ep0buf[0] = 0; /* Not stalled */ + } + + priv->ep0buf[1] = 0; + + lpc43_ep0xfer (LPC43_EP0_IN, priv->ep0buf, 2); + lpc43_ep0state (priv, EP0STATE_SHORTWRITE); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + priv->ep0buf[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + priv->ep0buf[1] = 0; + + lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2); + lpc43_ep0state (priv, EP0STATE_SHORTWRITE); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_IFGETSTATUS), 0); + priv->ep0buf[0] = 0; + priv->ep0buf[1] = 0; + + lpc43_ep0xfer(LPC43_EP0_IN, priv->ep0buf, 2); + lpc43_ep0state (priv, EP0STATE_SHORTWRITE); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_CLEARFEATURE), 0); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc43_dispatchrequest(priv, ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc43_epfindbyaddr(priv, index)) != NULL) + { + lpc43_epstall(&privep->ep, true); + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_SETFEATURE), 0); + if (((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value == USB_FEATURE_TESTMODE) + { + ullvdbg("test mode: %d\n", index); + } + else if ((ctrl->type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + lpc43_dispatchrequest(priv, ctrl); + } + else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT && len == 0 && + (privep = lpc43_epfindbyaddr(priv, index)) != NULL) + { + lpc43_epstall(&privep->ep, false); + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0SETUPSETADDRESS), value); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0 && value < 128) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. */ + + priv->paddr = ctrl->value[0]; + priv->paddrset = false; + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSETDESC), 0); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + lpc43_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETCONFIG), 0); + if (priv->paddrset && (ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value == 0 && index == 0 && len == 1) + { + lpc43_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_SETCONFIG), 0); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && len == 0) + { + lpc43_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_GETSETIF), 0); + lpc43_dispatchrequest(priv, ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc43_epstall(&priv->eplist[LPC43_EP0_IN].ep, false); + lpc43_epstall(&priv->eplist[LPC43_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc43_ep0complete + * + * Description: + * Transfer complete handler for Endpoint 0 + * + ****************************************************************************/ + +static void lpc43_ep0complete(struct lpc43_usbdev_s *priv, uint8_t epphy) +{ + struct lpc43_ep_s *privep = &priv->eplist[epphy]; + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0COMPLETE), (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_DATA_IN: + if (lpc43_rqempty(privep)) + { + return; + } + + if (lpc43_epcomplete (priv, epphy)) + { + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + } + break; + + case EP0STATE_DATA_OUT: + if (lpc43_rqempty(privep)) + { + return; + } + + if (lpc43_epcomplete (priv, epphy)) + { + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + break; + + case EP0STATE_SHORTREAD: + lpc43_dispatchrequest(priv, &priv->ep0ctrl); + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_IN); + break; + + case EP0STATE_SHORTWRITE: + lpc43_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + break; + + case EP0STATE_WAIT_STATUS_IN: + lpc43_ep0state (priv, EP0STATE_IDLE); + + /* If we've received a SETADDRESS packet, then we set the address + * now that the status phase has completed + */ + + if (! priv->paddrset && priv->paddr != 0) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0INSETADDRESS), (uint16_t)priv->paddr); + lpc43_set_address (priv, priv->paddr); + } + + break; + + case EP0STATE_WAIT_STATUS_OUT: + lpc43_ep0state (priv, EP0STATE_IDLE); + break; + + default: +#ifdef CONFIG_DEBUG + DEBUGASSERT(priv->ep0state != EP0STATE_DATA_IN && + priv->ep0state != EP0STATE_DATA_OUT && + priv->ep0state != EP0STATE_SHORTWRITE && + priv->ep0state != EP0STATE_WAIT_STATUS_IN && + priv->ep0state != EP0STATE_WAIT_STATUS_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc43_epstall(&priv->eplist[LPC43_EP0_IN].ep, false); + lpc43_epstall(&priv->eplist[LPC43_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc43_ep0nak + * + * Description: + * Handle a NAK interrupt on EP0 + * + ****************************************************************************/ + +static void lpc43_ep0nak(struct lpc43_usbdev_s *priv, uint8_t epphy) +{ + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0NAK), (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_WAIT_NAK_IN: + lpc43_ep0xfer (LPC43_EP0_IN, NULL, 0); + lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_IN); + break; + + case EP0STATE_WAIT_NAK_OUT: + lpc43_ep0xfer (LPC43_EP0_OUT, NULL, 0); + lpc43_ep0state (priv, EP0STATE_WAIT_STATUS_OUT); + break; + + default: +#ifdef CONFIG_DEBUG + DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN && + priv->ep0state != EP0STATE_WAIT_NAK_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + lpc43_epstall(&priv->eplist[LPC43_EP0_IN].ep, false); + lpc43_epstall(&priv->eplist[LPC43_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: lpc43_epcomplete + * + * Description: + * Transfer complete handler for Endpoints other than 0 + * returns whether the request at the head has completed + * + ****************************************************************************/ + +bool lpc43_epcomplete(struct lpc43_usbdev_s *priv, uint8_t epphy) +{ + struct lpc43_ep_s *privep = &priv->eplist[epphy]; + struct lpc43_req_s *privreq = privep->head; + struct lpc43_dtd_s *dtd = &g_td[epphy]; + + if (privreq == NULL) /* This shouldn't really happen */ + { + if (LPC43_EPPHYOUT(privep->epphy)) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPINQEMPTY), 0); + } + else + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUTQEMPTY), 0); + } + + return true; + } + + int xfrd = dtd->xfer_len - (dtd->config >> 16); + + privreq->req.xfrd += xfrd; + + bool complete = true; + if (LPC43_EPPHYOUT(privep->epphy)) + { + /* read(OUT) completes when request filled, or a short transfer is received */ + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPIN), complete); + } + else + { + /* write(IN) completes when request finished, unless we need to terminate with a ZLP */ + + bool need_zlp = (xfrd == privep->ep.maxpacket) && ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + + complete = (privreq->req.xfrd >= privreq->req.len && !need_zlp); + + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EPOUT), complete); + } + + /* If the transfer is complete, then dequeue and progress any further queued requests */ + + if (complete) + { + privreq = lpc43_rqdequeue (privep); + } + + if (!lpc43_rqempty(privep)) + { + lpc43_progressep(privep); + } + + /* Now it's safe to call the completion callback as it may well submit a new request */ + + if (complete) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + lpc43_reqcomplete(privep, privreq, OK); + } + + return complete; +} + + +/**************************************************************************** + * Name: lpc43_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int lpc43_usbinterrupt(int irq, FAR void *context) +{ + struct lpc43_usbdev_s *priv = &g_usbdev; + uint32_t disr, portsc1, n; + + usbtrace(TRACE_INTENTRY(LPC43_TRACEINTID_USB), 0); + + /* Read the interrupts and then clear them */ + + disr = lpc43_getreg(LPC43_USBDEV_USBSTS); + lpc43_putreg(disr, LPC43_USBDEV_USBSTS); + + if (disr & USBDEV_USBSTS_URI) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_DEVRESET), 0); + + lpc43_usbreset(priv); + + usbtrace(TRACE_INTEXIT(LPC43_TRACEINTID_USB), 0); + return OK; + } + + /* When the device controller enters a suspend state from an active state, + * the SLI bit will be set to a one. + */ + + if (!priv->suspended && (disr & USBDEV_USBSTS_SLI) != 0) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_SUSPENDED), 0); + + /* Inform the Class driver of the suspend event */ + + priv->suspended = 1; + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + /* The device controller clears the SLI bit upon exiting from a suspend + * state. This bit can also be cleared by software writing a one to it. + */ + + else if (priv->suspended && (disr & USBDEV_USBSTS_SLI) == 0) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_RESUMED), 0); + + /* Inform the Class driver of the resume event */ + + priv->suspended = 0; + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + if (disr & USBDEV_USBSTS_PCI) + { + portsc1 = lpc43_getreg(LPC43_USBDEV_PORTSC1); + + if (portsc1 & USBDEV_PRTSC1_HSP) + priv->usbdev.speed = USB_SPEED_HIGH; + else + priv->usbdev.speed = USB_SPEED_FULL; + + if (portsc1 & USBDEV_PRTSC1_FPR) + { + /* FIXME: this occurs because of a J-to-K transition detected + * while the port is in SUSPEND state - presumambly this + * is where the host is resuming the device? + * + * - but do we need to "ack" the interrupt + */ + } + } + +#ifdef CONFIG_LPC43_USBDEV_FRAME_INTERRUPT + if (disr & USBDEV_USBSTT_SRI) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_FRAME), 0); + + priv->sof = (int)lpc43_getreg(LPC43_USBDEV_FRINDEX_OFFSET); + } +#endif + + if (disr & USBDEV_USBSTS_UEI) + { + /* FIXME: these occur when a transfer results in an error condition + * it is set alongside USBINT if the DTD also had its IOC + * bit set. */ + } + + if (disr & USBDEV_USBSTS_UI) + { + /* Handle completion interrupts */ + + uint32_t mask = lpc43_getreg (LPC43_USBDEV_ENDPTCOMPLETE); + + if (mask) + { + /* Clear any NAK interrupt and completion interrupts */ + + lpc43_putreg (mask, LPC43_USBDEV_ENDPTNAK); + lpc43_putreg (mask, LPC43_USBDEV_ENDPTCOMPLETE); + + if (mask & LPC43_ENDPTMASK(0)) + { + lpc43_ep0complete(priv, 0); + } + + if (mask & LPC43_ENDPTMASK(1)) + { + lpc43_ep0complete(priv, 1); + } + + for (n = 1; n < LPC43_NLOGENDPOINTS; n++) + { + if (mask & LPC43_ENDPTMASK((n << 1))) + { + lpc43_epcomplete (priv, (n << 1)); + } + + if (mask & LPC43_ENDPTMASK((n << 1)+1)) + { + lpc43_epcomplete(priv, (n << 1)+1); + } + } + } + + /* Handle setup interrupts */ + + uint32_t setupstat = lpc43_getreg(LPC43_USBDEV_ENDPTSETUPSTAT); + if (setupstat) + { + /* Clear the endpoint complete CTRL OUT and IN when a Setup is received */ + + lpc43_putreg(LPC43_ENDPTMASK(LPC43_EP0_IN) | LPC43_ENDPTMASK(LPC43_EP0_OUT), + LPC43_USBDEV_ENDPTCOMPLETE); + + if (setupstat & LPC43_ENDPTMASK(LPC43_EP0_OUT)) + { + usbtrace(TRACE_INTDECODE(LPC43_TRACEINTID_EP0SETUP), setupstat); + lpc43_ep0setup(priv); + } + } + } + + if (disr & USBDEV_USBSTS_NAKI) + { + uint32_t pending = lpc43_getreg(LPC43_USBDEV_ENDPTNAK) & lpc43_getreg(LPC43_USBDEV_ENDPTNAKEN); + if (pending) + { + /* We shouldn't see NAK interrupts except on Endpoint 0 */ + + if (pending & LPC43_ENDPTMASK(0)) + { + lpc43_ep0nak(priv, 0); + } + + if (pending & LPC43_ENDPTMASK(1)) + { + lpc43_ep0nak(priv, 1); + } + } + + /* Clear the interrupts */ + + lpc43_putreg(pending, LPC43_USBDEV_ENDPTNAK); + } + + usbtrace(TRACE_INTEXIT(LPC43_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int lpc43_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialise EP capabilities */ + + uint16_t maxsize = GETUINT16(desc->mxpacketsize); + if ((desc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_ISOC) + { + g_qh[privep->epphy].capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_IOS | + DQH_CAPABILITY_ZLT); + } + else + { + g_qh[privep->epphy].capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_ZLT); + } + + /* Setup Endpoint Control Register */ + + if (LPC43_EPPHYIN(privep->epphy)) + { + /* Reset the data toggles */ + + uint32_t cfg = USBDEV_ENDPTCTRL_TXR; + + /* Set the endpoint type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_TXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_TXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_TXT_BULK; break; + case USB_EP_ATTR_XFER_INT: cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break; + } + + lpc43_chgbits (0xFFFF0000, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + /* Reset the data toggles */ + + uint32_t cfg = USBDEV_ENDPTCTRL_RXR; + + /* Set the endpoint type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: cfg |= USBDEV_ENDPTCTRL_RXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: cfg |= USBDEV_ENDPTCTRL_RXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: cfg |= USBDEV_ENDPTCTRL_RXT_BULK; break; + } + + lpc43_chgbits (0x0000FFFF, cfg, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + /* Reset endpoint status */ + + privep->stalled = false; + + /* Enable the endpoint */ + + if (LPC43_EPPHYIN(privep->epphy)) + { + lpc43_setbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + lpc43_setbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc43_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int lpc43_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->epphy); + + flags = enter_critical_section(); + + /* Disable Endpoint */ + + if (LPC43_EPPHYIN(privep->epphy)) + { + lpc43_clrbits (USBDEV_ENDPTCTRL_TXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + lpc43_clrbits (USBDEV_ENDPTCTRL_RXE, LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + privep->stalled = true; + + /* Cancel any ongoing activity */ + + lpc43_cancelrequests(privep, -ESHUTDOWN); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc43_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *lpc43_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc43_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct lpc43_ep_s *)ep)->epphy); + + privreq = (FAR struct lpc43_req_s *)kmm_malloc(sizeof(struct lpc43_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct lpc43_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: lpc43_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void lpc43_epfreereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc43_req_s *privreq = (FAR struct lpc43_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct lpc43_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: lpc43_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *lpc43_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc43_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void lpc43_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: lpc43_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int lpc43_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc43_req_s *privreq = (FAR struct lpc43_req_s *)req; + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + FAR struct lpc43_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint */ + + if (LPC43_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + } + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + } + + if (lpc43_rqenqueue(privep, privreq)) + { + lpc43_progressep(privep); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: lpc43_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int lpc43_epcancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + lpc43_cancelrequests(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc43_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int lpc43_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy); + + uint32_t addr = LPC43_USBDEV_ENDPTCTRL(privep->epphy >> 1); + uint32_t ctrl_xs = LPC43_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXS : USBDEV_ENDPTCTRL_RXS; + uint32_t ctrl_xr = LPC43_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXR : USBDEV_ENDPTCTRL_RXR; + + if (resume) + { + privep->stalled = false; + + /* Clear stall and reset the data toggle */ + + lpc43_chgbits (ctrl_xs | ctrl_xr, ctrl_xr, addr); + } + else + { + privep->stalled = true; + + lpc43_setbits (ctrl_xs, addr); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *lpc43_allocep(FAR struct usbdev_s *dev, uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev; + uint32_t epset = LPC43_EPALLSET & ~LPC43_EPCTRLSET; + irqstate_t flags; + int epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* A logical address of 0 means that any endpoint will do */ + + if (eplog > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (eplog >= LPC43_NLOGENDPOINTS) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPNO), (uint16_t)eplog); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset &= 3 << (eplog << 1); + } + + /* Get the subset matching the requested direction */ + + if (in) + { + epset &= LPC43_EPINSET; + } + else + { + epset &= LPC43_EPOUTSET; + } + + /* Get the subset matching the requested type */ + + switch (eptype) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + epset &= LPC43_EPINTRSET; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + epset &= LPC43_EPBULKSET; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + epset &= LPC43_EPISOCSET; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ + default: + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BADEPTYPE), (uint16_t)eptype); + return NULL; + } + + /* Is the resulting endpoint supported by the LPC433x? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints */ + + for (epndx = 2; epndx < LPC43_NPHYSENDPOINTS; epndx++) + { + uint32_t bit = 1 << epndx; + if ((epset & bit) != 0) + { + /* Mark endpoint no longer available */ + + priv->epavail &= ~bit; + leave_critical_section(flags); + + /* And return the pointer to the standard endpoint structure */ + + return &priv->eplist[epndx].ep; + } + } + + /* Shouldn't get here */ + + } + + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_NOEP), (uint16_t)eplog); + return NULL; +} + +/**************************************************************************** + * Name: lpc43_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void lpc43_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev; + FAR struct lpc43_ep_s *privep = (FAR struct lpc43_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: lpc43_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int lpc43_getframe(struct usbdev_s *dev) +{ +#ifdef CONFIG_LPC43_USBDEV_FRAME_INTERRUPT + FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev; + + /* Return last valid value of SOF read by the interrupt handler */ + + usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof); + return priv->sof; +#else + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* FIXME: this actually returns the micro frame number! */ + + return (int)lpc43_getreg(LPC43_USBDEV_FRINDEX_OFFSET); +#endif +} + +/**************************************************************************** + * Name: lpc43_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int lpc43_wakeup(struct usbdev_s *dev) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + flags = enter_critical_section(); + lpc43_setbits(USBDEV_PRTSC1_FPR, LPC43_USBDEV_PORTSC1); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc43_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int lpc43_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct lpc43_usbdev_s *priv = (FAR struct lpc43_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: lpc43_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int lpc43_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + if (enable) + { + lpc43_setbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD); + +#ifdef CONFIG_LPC43_USB0DEV_NOVBUS + /* Create a 'false' power event on the USB port so the MAC connects */ + + lpc43_clrbits (USBOTG_OTGSC_VD, LPC43_USBOTG_OTGSC); + lpc43_setbits (USBOTG_OTGSC_VC, LPC43_USBOTG_OTGSC); +#endif + } + else + { + lpc43_clrbits (USBDEV_USBCMD_RS, LPC43_USBDEV_USBCMD); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL initialization is not performed here but should been in + * the low-level boot logic: PLL0 must be configured for operation at 480MHz + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + struct lpc43_usbdev_s *priv = &g_usbdev; + int i; + uint32_t regval; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct lpc43_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[LPC43_EP0_IN].ep; + priv->epavail = LPC43_EPALLSET & ~LPC43_EPCTRLSET; + + /* Initialize the endpoint list */ + + for (i = 0; i < LPC43_NPHYSENDPOINTS; i++) + { + uint32_t bit = 1 << i; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + priv->eplist[i].ep.ops = &g_epops; + priv->eplist[i].dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + priv->eplist[i].epphy = i; + if (LPC43_EPPHYIN(i)) + { + priv->eplist[i].ep.eplog = LPC43_EPPHYIN2LOG(i); + } + else + { + priv->eplist[i].ep.eplog = LPC43_EPPHYOUT2LOG(i); + } + + /* The maximum packet size may depend on the type of endpoint */ + + if ((LPC43_EPCTRLSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC43_EP0MAXPACKET; + } + else if ((LPC43_EPINTRSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC43_INTRMAXPACKET; + } + else if ((LPC43_EPBULKSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = LPC43_BULKMAXPACKET; + } + else /* if ((LPC43_EPISOCSET & bit) != 0) */ + { + priv->eplist[i].ep.maxpacket = LPC43_ISOCMAXPACKET; + } + } + + /* Enable PLL0 clock */ + + lpc43_pll0usbconfig(); + lpc43_pll0usbenable(); + + /* Clock */ + + regval = getreg32(LPC43_BASE_USB0_CLK); + regval &= ~(BASE_USB0_CLK_CLKSEL_MASK | BASE_USB0_CLK_PD) ; + regval |= (BASE_USB0_CLKSEL_PLL0USB | BASE_USB0_CLK_AUTOBLOCK); + putreg32(regval, LPC43_BASE_USB0_CLK); + + /* Clock run */ + + regval = getreg32(LPC43_CCU1_M4_USB0_CFG); + regval |= CCU_CLK_CFG_RUN; + putreg32(regval, LPC43_CCU1_M4_USB0_CFG); + + //lpc43_putreg(RGU_CTRL0_USB0_RST, LPC43_RGU_CTRL0); /* Reset USB block */ + + lpc43_pullup(&priv->usbdev, false); /* disconnect device */ + + lpc43_setbits (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); /* Reset the controller */ + while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Power PHY */ + + regval = getreg32(LPC43_CREG0); + regval &= ~CREG0_USB0PHY; + putreg32(regval, LPC43_CREG0); + + lpc43_putreg(0, LPC43_USBDEV_USBINTR); /* Disable USB interrupts */ + + /* Program the controller to be the USB device controller */ + + lpc43_putreg (USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM | USBDEV_USBMODE_CM_DEVICE, + LPC43_USBDEV_USBMODE); + + /* Attach USB controller interrupt handler */ + + irq_attach(LPC43M4_IRQ_USB0, lpc43_usbinterrupt); + up_enable_irq(LPC43M4_IRQ_USB0); + + leave_critical_section(flags); + + /* Reset/Re-initialize the USB hardware */ + + lpc43_usbreset(priv); + + return; +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct lpc43_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + lpc43_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(LPC43M4_IRQ_USB0); + irq_detach(LPC43M4_IRQ_USB0); + + /* Reset the controller */ + + lpc43_setbits (USBDEV_USBCMD_RST, LPC43_USBDEV_USBCMD); + while (lpc43_getreg (LPC43_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Turn off USB power and clocking */ + + lpc43_pll0usbdisable(); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(LPC43M4_IRQ_USB0); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + lpc43_pullup(&g_usbdev.usbdev, true); + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(LPC43_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable USB controller interrupts */ + + up_disable_irq(LPC43M4_IRQ_USB0); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} + diff --git a/arch/arm/src/lpc43xx/lpc43_usb0dev.h b/arch/arm/src/lpc43xx/lpc43_usb0dev.h new file mode 100644 index 0000000000000000000000000000000000000000..d94163201343537bdd23d8e70ec45119415883c7 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_usb0dev.h @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_usbdev.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_USB0DEV_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_USB0DEV_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/lpc43_usb0.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: lpc43_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide lpc43_pullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * + ************************************************************************************/ + +int lpc43_usbpullup(FAR struct usbdev_s *dev, bool enable); + +/************************************************************************************ + * Name: lpc43_usbsuspend + * + * Description: + * Board logic must provide the lpc43_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +void lpc43_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_USB0DEV_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_usbram.h b/arch/arm/src/lpc43xx/lpc43_usbram.h new file mode 100644 index 0000000000000000000000000000000000000000..7f23013e4b6dae9f02dbe5649181583bde263449 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_usbram.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_usbram.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_USBRAM_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_USBRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_USBRAM_H */ diff --git a/arch/arm/src/lpc43xx/lpc43_userspace.c b/arch/arm/src/lpc43xx/lpc43_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..43ded6b4abeb24b0593121058351594e5dbd0042 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_userspace.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/lpc43xx/lpc43_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "lpc43_mpuinit.h" +#include "lpc43_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc43_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void lpc43_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + lpc43_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/lpc43xx/lpc43_userspace.h b/arch/arm/src/lpc43xx/lpc43_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..77b6d1e609225a5c72cf34b173ef6ef995384ac0 --- /dev/null +++ b/arch/arm/src/lpc43xx/lpc43_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/lpc43xx/lpc43_qei.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_LPC43XX_LPC43_USERSPACE_H +#define __ARCH_ARM_SRC_LPC43XX_LPC43_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: lpc43_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void lpc43_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_USERSPACE_H */ diff --git a/arch/arm/src/lpc43xx/spifi/changelog.txt b/arch/arm/src/lpc43xx/spifi/changelog.txt new file mode 100644 index 0000000000000000000000000000000000000000..f96920a1f5105d9d0eecc53f80d88ffb35e3f3ea --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/changelog.txt @@ -0,0 +1,135 @@ +LPCSpifilib version <1.03> +========================== +Release date <01/19/2015> +1. Corrected id for S25FL256S device. +2. Added 4 Byte address support for large devices (S25FL256S and S25FL512S). +3. Changed directory structure to new v3.xx format. +4. Removed --gnu flag and produced generic lib for use with both IAR and Keil + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a] + +LPCSpifilib version <1.02> +========================== +Release date <12/30/2014> +1. Included pre-build of LPCXpresso M4F and M4F_hard libraries + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a] + +LPCSpifilib version <1.01> +========================== +Release date <12/11/2014> +1. Changed reported device string on S25FL512S from "S25FL512S 256kSec" to "S25FL512S". +2. Changelog update: Added support for MX25L1635E, MX25L6435E, MX25L8035E, S25FL016K, S25FL064P, S25FL128S, S25FL256S, + S25FL512S, W25Q16DV, and W25Q64FV devices. +3. Changelog update: Changed maxRead to 16128 (was 32768). + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a] + +LPCSpifilib version <1.0> +========================== +Release date <12/2/2014> +Change Log: +1. Added support for MX25L1635E, MX25L6435E, MX25L8035E, S25FL016K, S25FL064P, S25FL128P, S25FL256S, + S25FL512S, W25Q16DV, and W25Q64FV devices. +2. Added support for device enumeration. +3. Added support for device base address return. +4. Improved read/write performance by issuing dword access to spifi controller. +5. Changed device structure to use function enum to facilitate adding external devices without recompiling library. +6. Added support for dual read / write. +7. Changed quad command to quad io read (improved performance). +8. Added ability for device to define read / write configuration word on a per +device basis. +9. Changed maxRead to 16383 (was 32768) +10. Removed API spifiDeInit(); +11. Renamed spifiDevGetInfo option SPIFI_INFO_MAX_QUADREAD_CLOCK to SPIFI_INFO_MAX_HSREAD_CLOCK +12. Renamed spifiDevGetInfo option SPIFI_INFO_MAX_QUADPROG_CLOCK to SPIFI_INFO_MAX_HSPROG_CLOCK + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]. + +LPCSpifilib version <0.07> +========================== +Release date <9/9/2014> +Change Log: +1. Added support for Winbond W25Q32FV. +2. Added support for Winbond W25Q80BV. +3. Added API's to return max speed for specific functions: + Read, QuadRead, Program, Quad Program. +4. Added prvGetStatus, prvSetStatus and prvSetQuadMode Functions to device definition structure. +5. Added spifiDevGetCount function. +6. Consolidated MX25L3235E and S25FL164K support into spifilib_fam_standard_cmd module + (removed SPIFI_REG_FAMILY_xxx registration functions and replaced with + spifi_REG_FAMILY_StandardCommandSet function). +7. Fixed bug in spifiRegisterFamily where NULL was being returned instead of the + family handle. +8. Removed switch statements and clib calls to memcpy and memset to facilitate running from iRam. +9. Renamed SPIFI_DEV_FAMILY_T to SPIFI_FAM_NODE_T. +10. Moved spifiDevRegister to shared module (spifilib_dev_common.c). +11. Updated documentation to reflect current design. + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a] + +LPCSpifilib version <0.06> +========================== +Release date <6/25/2014> +Change Log: +1. Changed identify to allow dynamic ID bytes per MFG/PART #. Moved to common + module. +2. Added support for S25FL129P (256kB sectors). +3. Verified S25FL129P 64kB sectors variant. +4. Renamed familes to indicate functionality in place of root device. + (This was done to avoid confusion over where devices reside). +5. Family cleanup to aid in comparison. +6. Removed Chip.h dependency. +7. Moved getInfo to common module. +8. Code/Memory optimizations. +9. LPCXpresso XML projects added. +10. M0 Library added. +11. Sub-block erase fixed for devices with full capability. +12. IAR libarary renamed to match Keil library +13. Moved project files into proj directory + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be +renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a] + +LPCSpifilib version <0.05> +========================== +Release date <5/15/2014> +Change Log: +1. Comment cleanup. +2. Added support for 40xx series +3. Changed spifiInit() api to include spifi control register address. +4. Changed spifiInitDevice() to include spifi control register address. + +Known issues: (carried forward) +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Option SPIFI_CAP_SUBBLKERASE is not working. +3. Device S25FL129P is un-tested. + + +LPCSpifilib version <0.04> +=========================== +Release date <4/25/2014> +Change Log: +1. Initial version. + +Known issues: +1. Option SPIFI_CAP_NOBLOCK is not implemented. +2. Option SPIFI_CAP_SUBBLKERASE is not working. +3. Device S25FL129P is un-tested. diff --git a/arch/arm/src/lpc43xx/spifi/inc/private/spifilib_chiphw.h b/arch/arm/src/lpc43xx/spifi/inc/private/spifilib_chiphw.h new file mode 100644 index 0000000000000000000000000000000000000000..841915b10e10f3cfa8d1d633c9c5a928ce3adea2 --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/inc/private/spifilib_chiphw.h @@ -0,0 +1,349 @@ +/* + * @brief LPCSPIFILIB hardware definitions 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 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 __SPIFILIB_CHIPHW_H_ +#define __SPIFILIB_CHIPHW_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define for inline */ +#ifndef INLINE +#ifdef __CC_ARM +#define INLINE __inline +#else +#define INLINE inline +#endif /* __CC_ARM */ +#endif /* !INLINE */ + +#ifdef __CC_ARM +#pragma anon_unions +#endif +/** @defgroup LPCSPIFILIB_HW_API LPCSPIFILIB hardware definitions and API functions + * @ingroup LPCSPIFILIB + * @{ + */ + +/** + * @brief SPIFI controller hardware register structure + */ + +typedef struct LPC_SPIFI_CHIPHW { + volatile uint32_t CTRL; /**< SPIFI control register */ + volatile uint32_t CMD; /**< SPIFI command register */ + volatile uint32_t ADDR; /**< SPIFI address register */ + volatile uint32_t DATINTM; /**< SPIFI intermediate data register */ + volatile uint32_t CACHELIMIT; /**< SPIFI cache limit register */ + union { + volatile uint8_t DAT8; /**< SPIFI 8 bit data */ + volatile uint16_t DAT16; /**< SPIFI 16 bit data */ + volatile uint32_t DAT32; /**< SPIFI 32 bit data */ + }; + + volatile uint32_t MEMCMD; /**< SPIFI memory command register */ + volatile uint32_t STAT; /**< SPIFI status register */ +} LPC_SPIFI_CHIPHW_T; + +/** @defgroup LPCSPIFILIB_HW_PRIM LPCSPIFILIB primative API functions + * @{ + */ + +/** + * @brief SPIFI controller control register bit definitions + */ +#define SPIFI_CTRL_TO(t) ((t) << 0) /**< SPIFI timeout */ +#define SPIFI_CTRL_CSHI(c) ((c) << 16) /**< SPIFI chip select minimum high time */ +#define SPIFI_CTRL_DATA_PREFETCH_DISABLE(d) ((d) << 21) /**< SPIFI memMode prefetch enable*/ +#define SPIFI_CTRL_INTEN(i) ((i) << 22) /**< SPIFI cmdComplete irq enable */ +#define SPIFI_CTRL_MODE3(m) ((m) << 23) /**< SPIFI mode3 config */ +#define SPIFI_CTRL_PREFETCH_DISABLE(d) ((d) << 27) /**< SPIFI cache prefetch enable */ +#define SPIFI_CTRL_DUAL(d) ((d) << 28) /**< SPIFI enable dual */ +#define SPIFI_CTRL_RFCLK(m) ((m) << 29) /**< SPIFI clock edge config */ +#define SPIFI_CTRL_FBCLK(m) ((m) << 30) /**< SPIFI feedback clock select */ +#define SPIFI_CTRL_DMAEN(m) ((m) << 31) /**< SPIFI dma enable */ + +/** + * @brief Write SPIFI controller control register + * @param pSpifi : Base address of SPIFI controller + * @param ctrl : Control value to write + * @return Nothing + */ +static INLINE void spifi_HW_SetCtrl(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t ctrl) +{ + pSpifi->CTRL = ctrl; +} + +/** + * @brief Read SPIFI controller control register + * @param pSpifi : Base address of SPIFI controller + * @return Current CTRL register values + */ +static INLINE uint32_t spifi_HW_GetCtrl(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->CTRL; +} + +/** + * @brief SPIFI controller status register bit definitions + */ +#define SPIFI_STAT_RESET (1 << 4) /**< SPIFI reset */ +#define SPIFI_STAT_INTRQ (1 << 5) /**< SPIFI interrupt request */ +#define SPIFI_STAT_CMD (1 << 1) /**< SPIFI command in progress */ +#define SPIFI_STAT_MCINIT (1) /**< SPIFI MCINIT */ + +/** + * @brief Write SPIFI controller status register + * @param pSpifi : Base address of SPIFI controller + * @param stat : Status bits to write + * @return Nothing + */ +static INLINE void spifi_HW_SetStat(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t stat) +{ + pSpifi->STAT = stat; +} + +/** + * @brief Read SPIFI controller status register + * @param pSpifi : Base address of SPIFI controller + * @return Current STAT register values + */ +static INLINE uint32_t spifi_HW_GetStat(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->STAT; +} + +/** + * @brief SPIFI controller command register bit definitions + */ +#define SPIFI_CMD_DATALEN(l) ((l) << 0) /**< SPIFI bytes to send or receive */ +#define SPIFI_CMD_POLLRS(p) ((p) << 14) /**< SPIFI enable poll */ +#define SPIFI_CMD_DOUT(d) ((d) << 15) /**< SPIFI data direction is out */ +#define SPIFI_CMD_INTER(i) ((i) << 16) /**< SPIFI intermediate bit length */ +#define SPIFI_CMD_FIELDFORM(p) ((p) << 19) /**< SPIFI 2 bit data/cmd mode control */ +#define SPIFI_CMD_FRAMEFORM(f) ((f) << 21) /**< SPIFI op and adr field config */ +#define SPIFI_CMD_OPCODE(o) ((uint32_t) (o) << 24) /**< SPIFI 8-bit command code */ + +/** + * @brief frame form definitions + */ +typedef enum { + SPIFI_FRAMEFORM_OP = 1, + SPIFI_FRAMEFORM_OP_1ADDRESS = 2, + SPIFI_FRAMEFORM_OP_2ADDRESS = 3, + SPIFI_FRAMEFORM_OP_3ADDRESS = 4, + SPIFI_FRAMEFORM_OP_4ADDRESS = 5, + SPIFI_FRAMEFORM_NOOP_3ADDRESS = 6, + SPIFI_FRAMEFORM_NOOP_4ADDRESS = 7 +} SPIFI_FRAMEFORM_T; + +/** + * @brief serial type definitions + */ +typedef enum { + SPIFI_FIELDFORM_ALL_SERIAL = 0, + SPIFI_FIELDFORM_SERIAL_OPCODE_ADDRESS = 1, + SPIFI_FIELDFORM_SERIAL_OPCODE = 2, + SPIFI_FIELDFORM_NO_SERIAL = 3 +} SPIFI_FIELDFORM_T; + +/** + * @brief Read SPIFI controller command register + * @param pSpifi : Base address of SPIFI controller + * @return 32-bit value read from the command register + */ +static INLINE uint32_t spifi_HW_GetCmd(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->CMD; +} + +/** + * @brief Write SPIFI controller command register + * @param pSpifi : Base address of SPIFI controller + * @param cmd : Command to write + * @return Nothing + */ +static INLINE void spifi_HW_SetCmd(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t cmd) +{ + pSpifi->CMD = cmd; +} + +/** + * @brief Write SPIFI controller address register + * @param pSpifi : Base address of SPIFI controller + * @param addr : address (offset) to write + * @return Nothing + */ +static INLINE void spifi_HW_SetAddr(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t addr) +{ + pSpifi->ADDR = addr; +} + +/** + * @brief Read an 8-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @return 8-bit value read from the data register + */ +static INLINE uint8_t spifi_HW_GetData8(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->DAT8; +} + +/** + * @brief Read an 16-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @return 16-bit value read from the data register + */ +static INLINE uint16_t spifi_HW_GetData16(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->DAT16; +} + +/** + * @brief Read an 32-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @return 32-bit value read from the data register + */ +static INLINE uint32_t spifi_HW_GetData32(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + return pSpifi->DAT32; +} + +/** + * @brief Write an 8-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @param data : 8-bit data value to write + * @return Nothing + */ +static INLINE void spifi_HW_SetData8(LPC_SPIFI_CHIPHW_T *pSpifi, uint8_t data) +{ + pSpifi->DAT8 = data; +} + +/** + * @brief Write an 16-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @param data : 16-bit data value to write + * @return Nothing + */ +static INLINE void spifi_HW_SetData16(LPC_SPIFI_CHIPHW_T *pSpifi, uint16_t data) +{ + pSpifi->DAT16 = data; +} + +/** + * @brief Write an 32-bit value from the controller data register + * @param pSpifi : Base address of SPIFI controller + * @param data : 32-bit data value to write + * @return Nothing + */ +static INLINE void spifi_HW_SetData32(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t data) +{ + pSpifi->DAT32 = data; +} + +/** + * @brief Write IDATA register + * @param pSpifi : Base address of SPIFI controller + * @param mode : value to write. Used to specify value used for intermediate + data value when enabled. + * @return Nothing + */ +static INLINE void spifi_HW_SetIDATA(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t mode) +{ + pSpifi->DATINTM = mode; +} + +/** + * @brief Write MEMCMD register + * @param pSpifi : Base address of SPIFI controller + * @param cmd : Command value to write + * @return Nothing + */ +static INLINE void spifi_HW_SetMEMCMD(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t cmd) +{ + pSpifi->MEMCMD = cmd; +} + +/** + * @} + */ + +/** @defgroup LPCSPIFILIB_HW_L2 LPCSPIFILIB hardware support API functions + * @{ + */ + +/** + * @brief Reset SPIFI controller + * @param pSpifi : Base address of SPIFI controller + * @return Nothing + */ +static INLINE void spifi_HW_ResetController(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + pSpifi->STAT = SPIFI_STAT_RESET; + while ((pSpifi->STAT & SPIFI_STAT_RESET) != 0) {} +} + +/** + * @brief Wait for a command to complete + * @param pSpifi : Base address of SPIFI controller + * @return Nothing + */ +static INLINE void spifi_HW_WaitCMD(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + while ((spifi_HW_GetStat(pSpifi) & SPIFI_STAT_CMD) != 0) {} +} + +/** + * @brief Wait for a RESET bit to clear + * @param pSpifi : Base address of SPIFI controller + * @return Nothing + */ +static INLINE void spifi_HW_WaitRESET(LPC_SPIFI_CHIPHW_T *pSpifi) +{ + while ((spifi_HW_GetStat(pSpifi) & SPIFI_STAT_RESET) != 0) {} +} + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPIFILIB_CHIPHW_H_ */ diff --git a/arch/arm/src/lpc43xx/spifi/inc/spifilib_api.h b/arch/arm/src/lpc43xx/spifi/inc/spifilib_api.h new file mode 100644 index 0000000000000000000000000000000000000000..67d3a480d2dd0e2befa924c099412f683d8ac37c --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/inc/spifilib_api.h @@ -0,0 +1,438 @@ +/* + * @brief LPCSPIFILIB driver definitions 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 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 __SPIFILIB_API_H_ +#define __SPIFILIB_API_H_ + +#include "spifilib_dev.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup LPCSPIFILIB_API LPCSPIFILIB common API functions + * @ingroup LPCSPIFILIB + * These LPCSPIFILIB functions provide an abstracted interface to + * the LPCSPIFILIB functions. The device API is a private API which should + * only used to interface with the LPCSPIFILIB core library. + * @{ + */ + +/** @defgroup LPCSPIFILIB_CMNAPI LPCSPIFILIB library support functions + * Library support functions are not tied to any specific LPCSPIFILIB device. + * @{ + */ + +/** + * @brief Report the SPIFILIB version + * @return SPIFI library version in format MMmm where MM is major number + * and mm is minor number. + */ +uint16_t spifiGetLibVersion(void); + +/** + * @brief Initialize the SPIFILIB driver + * @param spifiCtrlAddr : Base address of SPIFI controller + * @param reset : true to reset the SPIFI controller, or false to not reset + * @return SPIFI library error code + * @note This function should be called prior to any other SPIFILIB functions. + * In most cases, a reset isn't needed. Before calling this function, all board + * specific functions related to the SPIFI interface must be setup and the SPIFI + * clock must be enabled. If booting from SPIFI FLASH, this will already be done. + * If not booting from SPIFI FLASH, the SPIFI FLASH pin muxing and SPIFI controller + * clock need to be enabled prior to this call. + */ +SPIFI_ERR_T spifiInit(uint32_t spifiCtrlAddr, uint8_t reset); + +/** + * @brief Register a SPIFILIB family driver + * @param regFx : A function which returns persistent device specific data structure. + * @return Handle to device specific data structure. + * @note This function should be called prior to calling spifiGetHandleMemSize() or + * spifiInitDevice(). + */ +SPIFI_FAM_NODE_T *spifiRegisterFamily(SPIFI_FAM_NODE_T *(*regFx)(void)); + +/** + * @brief Converts a SPIFILIB error code into a meaningful string + * @param errCode : Error code to get string pointer to + * @return Pointer to string for the passed error code + */ +const char *spifiReturnErrString(SPIFI_ERR_T errCode); + +/** + * @brief Return the number of registered device families in this driver + * @return number of registered device families in this driver + */ +uint32_t spifiGetSuppFamilyCount(void); + +/** + * @brief Return the driver device family name for a specific index + * @param index : Index (0 - n) where n = number of families returned + * by spifiGetSuppFamilyCount() -1 + * @return a string pointer to the generic device name + * @note Can be used with the spifiGetSuppFamilyCount() to get a list of + * device families the library is configured for. + */ +const char *spifiGetSuppFamilyName(uint32_t index); + +/** + * @brief Detect and return memory needed for device handle at passed address + * @param spifiCtrlAddr : Base address of SPIFI controller + * @return The size in bytes this device needs for the call to InitDevice(). + * If no supported device is detected 0 will be returned. + * @note Selects the first matching device in the library. + */ +uint32_t spifiGetHandleMemSize(uint32_t spifiCtrlAddr); + +/** + * @brief Initialize driver and hardware for a specific device + * @param pMem : Pointer to a 32-bit aligned buffer with a size returned from spifiGetHandleMemSize() + * @param sizePMem : Size of the buffer in bytes pass in pMem + * @param spifiCtrlAddr : Base address of SPIFI controller + * @param baseAddr : Base address of device + * @return Returns a pointer to a device handle if successful, or NULL on an error. + */ +SPIFI_HANDLE_T *spifiInitDevice(void *pMem, uint32_t sizePMem, uint32_t spifiCtrlAddr, uint32_t baseAddr); + +/** + * @brief Set or unset driver options + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param options : Options to set or unset, an OR'ed value of SPIFI_OPT_xxx values + * (example #SPIFI_OPT_USE_QUAD | #SPIFI_OPT_NOBLOCK) + * @param set : true to set the passed options, false to clear them + * @return Nothing + * @note Only options that are supported in the capabilities of the driver can be + * set or unset. + */ +SPIFI_ERR_T spifiDevSetOpts(SPIFI_HANDLE_T *pHandle, uint32_t options, uint8_t set); + +/** + * @} + */ + +/** @defgroup LPCSPIFILIB_DEVAPI LPCSPIFILIB library device functions + * Device functions are used to perform LPCSPIFILIB device operations. + * @{ + */ + +/** + * @brief Add device to family driver + * @param pFamily : Pointer to a SPIFI_DEV_FAMILY_T family handle + * @param pDevData : Pointer to a persistent SPIFI_DEV_DATA_T device structure + * @return A SPIFI_ERR_T error code (SPIFI_ERR_NONE for no errors) + * @note This function MUST be called prior to spifiGetHandleMemSize() or spifiInitDevice() + */ +SPIFI_ERR_T spifiDevRegister(const SPIFI_FAM_NODE_T *pFamily, SPIFI_DEV_NODE_T *pDevData); + +/** + * @brief Returns the number of supported devices within a family + * @param pFamily : Pointer to a SPIFI_DEV_FAMILY_T family handle + * @return The number of registered devices. + */ +static INLINE uint32_t spifiDevGetCount(const SPIFI_FAM_NODE_T *pFamily) +{ + return *(pFamily->pDesc->pDevCount); +} + +/** + * @brief Enumerates the friendly names of supported devices + * @param pContext : Pointer to a SPIFI_DEV_ENUMERATOR_T context structure + * @param reset : 0 enumerates next device, 1 resets list to beginning and returns first device + * @return A friendly string representing the device, NULL when list has been exhausted. + */ +const char *spifiDevEnumerateName(SPIFI_DEV_ENUMERATOR_T *pContext, uint8_t reset); + +/** + * @brief Initialize a detected LPCSPIFILIB device + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +SPIFI_ERR_T spifiDevInit(const SPIFI_HANDLE_T *pHandle); + +/** + * @brief De-initialize a detected LPCSPIFILIB device + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +SPIFI_ERR_T spifiDevDeInit(const SPIFI_HANDLE_T *pHandle); + +/** + * @brief Sets or clears memory mode + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param enMMode : true to enable memory mode, false to disable + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + * @note Enter memory mode to enable direct read access for Execute in + * place code and memory mapped data. Memory mode must be disabled + * for most operations. + */ +SPIFI_ERR_T spifiDevSetMemMode(const SPIFI_HANDLE_T *pHandle, uint8_t enMMode); + +/** + * @brief Return status of memory mode + * @param pSpifi : Base address of SPIFI controller + * @return state of memory mode (false = off, true = on) + */ +uint8_t spifiDevGetMemoryMode(const SPIFI_HANDLE_T *pSpifi); + +/** + * @brief Full LPCSPIFILIB device unlock + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevUnlockDevice(const SPIFI_HANDLE_T *pHandle) +{ + return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_UNLOCK_DEVICE, 0); +} + +/** + * @brief Full LPCSPIFILIB device lock + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevLockDevice(const SPIFI_HANDLE_T *pHandle) +{ + return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_LOCK_DEVICE, 0); +} + +/** + * @brief Unlock a single device block + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param block : Block number to unlock + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevUnlockBlock(const SPIFI_HANDLE_T *pHandle, uint32_t block) +{ + return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_UNLOCK_BLOCK, block); +} + +/** + * @brief Lock a single device block + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param block : Block number to lock + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevLockBlock(const SPIFI_HANDLE_T *pHandle, uint32_t block) +{ + return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_LOCK_BLOCK, block); +} + +/** + * @brief Full LPCSPIFILIB device erase + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevEraseAll(const SPIFI_HANDLE_T *pHandle) +{ + return pHandle->pFamFx->eraseAll(pHandle); +} + +/** + * @brief Erase a sub-block + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param blknum : Sub-block number to erase + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + */ +static INLINE SPIFI_ERR_T spifiDevEraseSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blknum) +{ + return pHandle->pFamFx->eraseSubBlock(pHandle, blknum); +} + +/** + * @brief Program up to a page of data at an address + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : LPCSPIFILIB device address to start write at + * @param writeBuff : Address of buffer to write, must be 32-bit aligned + * @param bytes : Number of bytes to write, must not exceed page length + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + * @note Only use this function to program data up to the page size. + */ +static INLINE SPIFI_ERR_T spifiDevPageProgram(const SPIFI_HANDLE_T *pHandle, + uint32_t addr, + uint32_t *writeBuff, + uint32_t bytes) +{ + return pHandle->pFamFx->pageProgram(pHandle, addr, writeBuff, bytes); +} + +/** + * @brief Read data from a LPCSPIFILIB device + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : LPCSPIFILIB device address to read from + * @param readBuff : Address of buffer to fill, must be 32-bit aligned + * @param bytes : Number of bytes to read + * @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors) + * @note Maximum read size is limited to the max single read size + */ +static INLINE SPIFI_ERR_T spifiDevRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes) +{ + return pHandle->pFamFx->read(pHandle, addr, readBuff, bytes); +} + +/** + * @brief Reset the device + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return Nothing + * @note Will set the device into read mode + */ +static INLINE void spifiDevReset(const SPIFI_HANDLE_T *pHandle) +{ + pHandle->pFamFx->reset(pHandle); +} + +/** + * @brief Returns a string pointer to the generic device family name + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @return a string pointer to the generic device family name + */ +static INLINE const char *spifiDevGetDeviceName(const SPIFI_HANDLE_T *pHandle) +{ + return pHandle->pInfoData->pDevName; +} + +#define spifiDevGetFamilyName spifiDevGetDeviceName /**< Deprecated! Do NOT use for new development */ + +/** + * @brief Returns information on the device + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param infoId : Info to get about the device + * @return Return value varies per selected function + */ +uint32_t spifiDevGetInfo(const SPIFI_HANDLE_T *pHandle, SPIFI_INFO_ID_T infoId); + +/** + * @} + */ + +/** @defgroup LPCSPIFILIB_HELPAPI LPCSPIFILIB library helper functions + * @{ + */ + +/** + * @brief Returns the starting address of a block number + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param blockNum : Block number fo get starting address for + * @return The starting address for the block, or 0xFFFFFFFF if the block number if invalid + */ +uint32_t spifiGetAddrFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum); + +/** + * @brief Returns the starting address of a sub-block number + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param subBlockNum : Sub-block number fo get starting address for + * @return The starting address for the sub-block, or 0xFFFFFFFF if the block number if invalid + */ +uint32_t spifiGetAddrFromSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t subBlockNum); + +/** + * @brief Returns the block number the passed address is located in + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : Address to get block number for + * @return The block number the passed address is in, 0xFFFFFFFF is the address is invalid + */ +uint32_t spifiGetBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr); + +/** + * @brief Returns the sub-block number the passed address is located in + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : Address to get sub-block number for + * @return The sub-block number the passed address is in, 0xFFFFFFFF is the address is invalid + */ +uint32_t spifiGetSubBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr); + +/** + * @brief Returns the first sub-block for a block + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param blockNum : Block number to get first sub-block for + * @return The first sub-block number in passed block, 0xFFFFFFFF if the block number if invalid + */ +uint32_t spifiGetSubBlockFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum); + +/** + * @brief Program the device with the passed buffer + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : LPCSPIFILIB device address to start write at + * @param writeBuff : Address of buffer to write, must be 32-bit aligned + * @param bytes : Number of bytes to write + * @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors) + * @note This function has no size limit. This function only works in blocking mode. + */ +SPIFI_ERR_T spifiProgram(const SPIFI_HANDLE_T *pHandle, uint32_t addr, const uint32_t *writeBuff, uint32_t bytes); + +/** + * @brief Read the device into the passed buffer + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param addr : LPCSPIFILIB device address to start read at + * @param readBuff : Address of buffer to read into, must be 32-bit aligned + * @param bytes : Number of bytes to read + * @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors) + * @note This function has no size limit. Optionally, the device can be placed into memory + * mode and accessed directly via memory mapped reads without using this function. This + * function only works in blocking mode. + */ +SPIFI_ERR_T spifiRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes); + +/** + * @brief Erase multiple blocks + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param firstBlock : First block number to erase + * @param numBlocks : Number of blocks to erase + * @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors) + * @note If any of the specified params are invalid, the operation is aborted + * before any sectors are erased. This function only works in blocking mode. + */ +SPIFI_ERR_T spifiErase(const SPIFI_HANDLE_T *pHandle, uint32_t firstBlock, uint32_t numBlocks); + +/** + * @brief Erase multiple blocks by address range + * @param pHandle : Pointer to a LPCSPIFILIB device handle + * @param firstAddr : Starting address range for block erase + * @param lastAddr : Ending address range for block erase + * @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors) + * @note This function will erase blocks inside the passed address + * range if and only if the address range is valid. + * This function only works in blocking mode. + */ +SPIFI_ERR_T spifiEraseByAddr(const SPIFI_HANDLE_T *pHandle, uint32_t firstAddr, uint32_t lastAddr); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPIFILIB_API_H_ */ diff --git a/arch/arm/src/lpc43xx/spifi/inc/spifilib_dev.h b/arch/arm/src/lpc43xx/spifi/inc/spifilib_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..0c499e91ffba9ed02de3c9460089cf6ccdadd690 --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/inc/spifilib_dev.h @@ -0,0 +1,416 @@ +/* + * @brief LPCSPIFILIB FLASH library device 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 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 __SPIFILIB_DEV_H_ +#define __SPIFILIB_DEV_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define for inline functions */ +#ifndef INLINE +#ifdef __CC_ARM +#define INLINE __inline +#else +#define INLINE inline +#endif /* __CC_ARM */ +#endif /* !INLINE */ + +/** @defgroup LPCSPIFILIB_DEV LPCSPIFILIB device driver API functions + * @ingroup LPCSPIFILIB + * @{ + */ +/** + * @brief Possible error codes that can be returned from functions + */ +typedef enum { + SPIFI_ERR_NONE = 0, /**< No error */ + SPIFI_ERR_BUSY, /**< Device is busy */ + SPIFI_ERR_GEN, /**< General error */ + SPIFI_ERR_NOTSUPPORTED, /**< Capability not supported */ + SPIFI_ERR_ALIGNERR, /**< Attempted to do an operation on an unaligned section of the device */ + SPIFI_ERR_LOCKED, /**< Device was locked and a program/erase operation was attempted */ + SPIFI_ERR_PROGERR, /**< Error programming device (blocking mode only) */ + SPIFI_ERR_ERASEERR, /**< Erase error (blocking mode only) */ + SPIFI_ERR_NOTBLANK, /**< Program operation on block that is not blank */ + SPIFI_ERR_PAGESIZE, /**< PageProgram write size exceeds page size */ + SPIFI_ERR_VAL, /**< Program operation failed validation or readback compare */ + SPIFI_ERR_RANGE, /**< Range error, bad block number, address out of range, etc. */ + SPIFI_ERR_MEMMODE, /**< Library calls not allowed while in memory mode. */ + /** @cond INTERNAL */ + SPIFI_ERR_LASTINDEX /* Internal use to count number of errors */ + /** @endcond */ +} SPIFI_ERR_T; + +/** + * @brief Possible device capabilities returned from getInfo() + */ +#define SPIFI_CAP_DUAL_READ (1 << 0) /**< Supports DUAL read mode */ +#define SPIFI_CAP_DUAL_WRITE (1 << 1) /**< Supports DUAL write mode */ +#define SPIFI_CAP_QUAD_READ (1 << 2) /**< Supports QUAD read mode */ +#define SPIFI_CAP_QUAD_WRITE (1 << 3) /**< Supports QUAD write mode */ +#define SPIFI_CAP_FULLLOCK (1 << 4) /**< Full device lock supported */ +#define SPIFI_CAP_BLOCKLOCK (1 << 5) /**< Individual block device lock supported */ +#define SPIFI_CAP_SUBBLKERASE (1 << 6) /**< Sub-block erase supported */ +#define SPIFI_CAP_4BYTE_ADDR (1 << 7) /**< Supports 4 Byte addressing */ +#define SPIFI_CAP_NOBLOCK (1 << 16) /**< Non-blocking mode supported */ + +/** + * @brief Possible driver options, may not be supported by all drivers + */ +#define SPIFI_OPT_USE_DUAL (3 << 0) /**< Enable DUAL read / write if option is supported */ +#define SPIFI_OPT_USE_QUAD (3 << 2) /**< Enable QUAD read / write if option is supported */ +#define SPIFI_OPT_NOBLOCK (1 << 16) /**< Will not block on program and erase operations, poll device status manually */ + +/** + * @brief Possible device statuses returned from getInfo() + */ +#define SPIFI_STAT_BUSY (1 << 0) /**< Device is busy erasing or programming */ +#define SPIFI_STAT_ISWP (1 << 1) /**< Device is write protected (software or hardware) */ +#define SPIFI_STAT_FULLLOCK (1 << 2) /**< Device is fully locked */ +#define SPIFI_STAT_PARTLOCK (1 << 3) /**< Device is partially locked (device specific) */ +#define SPIFI_STAT_PROGERR (1 << 4) /**< Device status shows a program error (non-blocking mode only) */ +#define SPIFI_STAT_ERASEERR (1 << 5) /**< Device status shows a erase error (non-blocking mode only) */ + +/** + * @brief Possible info lookup requests + */ +typedef enum { + SPIFI_INFO_BASE_ADDRESS = 0, /**< Device physical memory address */ + SPIFI_INFO_DEVSIZE, /**< Device size in Bytes */ + SPIFI_INFO_ERASE_BLOCKS, /**< Number of erase blocks */ + SPIFI_INFO_ERASE_BLOCKSIZE, /**< Size of erase blocks */ + SPIFI_INFO_ERASE_SUBBLOCKS, /**< Number of erase sub-blocks */ + SPIFI_INFO_ERASE_SUBBLOCKSIZE, /**< Size of erase sub-blocks */ + SPIFI_INFO_PAGESIZE, /**< Size of a page, page write size limit */ + SPIFI_INFO_MAXREADSIZE, /**< Maximum read size, read size limit in bytes */ + SPIFI_INFO_MAXCLOCK, /**< Maximum device speed in Hz */ + SPIFI_INFO_MAX_READ_CLOCK, /**< Maximum device speed for read cmd in Hz */ + SPIFI_INFO_MAX_HSREAD_CLOCK, /**< Maximum device speed for quad / dual read cmd in Hz */ + SPIFI_INFO_MAX_PROG_CLOCK, /**< Maximum device speed for program cmd in Hz */ + SPIFI_INFO_MAX_HSPROG_CLOCK, /**< Maximum device speed for quad program cmd in Hz */ + SPIFI_INFO_CAPS, /**< Device capabilities, OR'ed SPIFI_CAP_* values */ + SPIFI_INFO_STATUS, /**< Or'ed SPIFI_STAT_xxx values. Any persistent hardware bits will be cleared */ + SPIFI_INFO_STATUS_RETAIN, /**< Or'ed SPIFI_STAT_xxx values. Any persistent hardware bits will be retained */ + SPIFI_INFO_OPTIONS, /**< Device capabilities, Or'ed SPIFI_OPT_* values */ + + SPIFI_INFO_LASTINDEX +} SPIFI_INFO_ID_T; + +/** + * @brief SPIFI_INFO_QUADREAD_CLOCK Depricated! Do NOT use for new development + */ +#define SPIFI_INFO_QUADREAD_CLOCK SPIFI_INFO_MAX_HSREAD_CLOCK + +/** + * @brief SPIFI_INFO_QUADPROG_CLOCK Depricated! Do NOT use for new development + */ +#define SPIFI_INFO_QUADPROG_CLOCK SPIFI_INFO_MAX_HSPROG_CLOCK +/** + * @brief Possible device specific lock / un-lock commands + */ +typedef enum { + SPIFI_PCMD_UNLOCK_DEVICE = 0, /**< unlock device */ + SPIFI_PCMD_LOCK_DEVICE, /**< lock device */ + SPIFI_PCMD_UNLOCK_BLOCK, /**< unlock specified block */ + SPIFI_PCMD_LOCK_BLOCK /**< lock specified block */ + +} SPIFI_PCMD_LOCK_UNLOCK_T; + +/** + * @brief Possible device specific sub-block commands + */ +typedef enum { + SPIFI_PCMD_ADDR_TO_SUB_BLOCK = 0, /**< Convert address to a sub-block */ + SPIFI_PCMD_SUB_BLOCK_TO_ADDR, /**< Convert sub-block to address */ + SPIFI_PCMD_BLOCK_TO_SUB_BLOCK /**< Convert block to sub-block */ + +} SPIFI_PCMD_SUBBLK_T; + +/** + * @brief Enumeration of device specific functions. + */ +typedef enum { + FX_spifiDeviceDataInitDeinit = 0, /**< Generic device init / de-init function */ + FX_spifiDeviceDataInitDeinitS25FL164K, /**< S25FL164K specific device init / de-init function */ + + FX_spifiDeviceDataClearStatusNone, /**< General do nothing I.e no status bits to clear */ + FX_spifiDeviceDataClearStatusS25FL032P, /**< S25FL032P (and similar) clear status bits function */ + + FX_spifiDeviceDataGetStatusS25FL032P, /**< S25FL032P (and similar) get status function */ + FX_spifiDeviceDataGetStatusS25FL164K, /**< S25FL164K (and similar) get status function */ + FX_spifiDeviceDataGetStatusMX25L3235E, /**< MX25L3235E (and similar) get status function */ + FX_spifiDeviceDataGetStatusW25Q80BV, /**< W25Q80BV (and similar) get status function */ + + FX_spifiDeviceDataSetStatusS25FL032P, /**< S25FL032P (and similar) set status function */ + FX_spifiDeviceDataSetStatusS25FL164K, /**< S25FL164K (and similar) set status function */ + FX_spifiDeviceDataSetStatusMX25L3235E, /**< MX25L3235E (and similar) set sttus function */ + + FX_spifiDeviceDataSetOptsQuadModeBit9, /**< Set bit 9 when enabling Quad mode */ + FX_spifiDeviceDataSetOptsQuadModeBit6, /**< Set bit 6 when enabling Quad mode */ + + FX_spifiDeviceInitReadCommand, /**< General return cmdReg value for read */ + FX_spifiDevice4BInitReadCommand, /**< General return cmdReg value for read w/ 4Byte address */ + + FX_spifiDeviceInitWriteCommand, /**< General return cmdReg value for write */ + FX_spifiDevice4BInitWriteCommand, /**< General return cmdReg value for write w/ 4Byte address */ + FX_spifiDeviceInitWriteCommandMacronix /**< Macronix return cmdReg value for write */ + +} SPIFI_DEVFX_T; + +/* Forward type declaration */ +struct SPIFI_HANDLE; + +struct SPIFI_DEVICE_DATA; + +struct SPIFI_FAM_DESC; + +struct SPIFI_DEVICE_ID; + +/** + * @brief LPCSPIFILIB family data. + */ +typedef struct SPIFI_FAM_NODE { + const struct SPIFI_FAM_DESC *pDesc; /**< Pointer to device descriptor */ + + struct SPIFI_FAM_NODE *pNext; /**< Reserved list pointer */ + +} SPIFI_FAM_NODE_T; + +/** + * @brief LPCSPIFILIB family descriptor, used to describe devices to non-device specific functions + */ +typedef struct SPIFI_FAM_DESC { + const char *pFamName; /**< (required) Pointer to generic family name */ + struct SPIFI_DEV_NODE *pDevList; /**< (required) Pointer to device list */ + + uint32_t prvContextSize; /**< Number of bytes needed for driver context allocation */ + uint32_t *pDevCount; /**< (required) Pointer to device count */ + void (*pPrvDevGetID)(uint32_t baseAddr, struct SPIFI_DEVICE_ID *pID); /**< (NULL allowed) Pointer to method that queries deviceID */ + + SPIFI_ERR_T (*pPrvDevSetup)(struct SPIFI_HANDLE *pHandle, uint32_t spifiCtrlAddr, uint32_t baseAddr); /**< (required) Pointer to device specific device initialization */ + +} SPIFI_FAM_DESC_T; + +/** + * @brief Register device data node + */ +typedef struct SPIFI_DEV_NODE { + const struct SPIFI_DEVICE_DATA *pDevData; /**< (required) Pointer to device specific data */ + + struct SPIFI_DEV_NODE *pNext; /**< Reserved */ + +} SPIFI_DEV_NODE_T; + +typedef SPIFI_ERR_T (*deviceInitDeInitFx)(const struct SPIFI_HANDLE *, uint32_t); /**< Fx* to handle init / de-init */ + +typedef void (*devClearStatusFx)(const struct SPIFI_HANDLE *); /**< Fx* to clear status */ + +typedef uint32_t (*devGetStatusFx)(const struct SPIFI_HANDLE *); /**< Fx* to get status */ + +typedef void (*devSetStatusFx)(const struct SPIFI_HANDLE *, uint32_t); /**< Fx* to set status */ + +typedef SPIFI_ERR_T (*devSetOptsFx)(const struct SPIFI_HANDLE *, uint32_t, uint32_t); /**< Fx* to set options */ + +typedef void (*devGetReadCmdFx)(const struct SPIFI_HANDLE *, uint8_t, uint32_t *, uint32_t *); /**< Fx* to return read commandReg value */ + +typedef void (*devGetWriteCmdFx)(const struct SPIFI_HANDLE *, uint32_t *); /**< Fx* to return write commandReg value */ + +/** + * @brief Device specific function pointers + */ +typedef struct SPIFI_FAM_FX { + /* Device init and de-initialization */ + + SPIFI_ERR_T (*lockCmd)(const struct SPIFI_HANDLE *, SPIFI_PCMD_LOCK_UNLOCK_T, uint32_t); /**< (required) Lock / unlock handler */ + + SPIFI_ERR_T (*eraseAll)(const struct SPIFI_HANDLE *); /**< (required) Full device erase */ + + SPIFI_ERR_T (*eraseBlock)(const struct SPIFI_HANDLE *, uint32_t); /**< (required) Erase a block by block number */ + + SPIFI_ERR_T (*eraseSubBlock)(const struct SPIFI_HANDLE *, uint32_t); /**< (required) Erase a sub-block by block number */ + + SPIFI_ERR_T (*pageProgram)(const struct SPIFI_HANDLE *, uint32_t, const uint32_t *, uint32_t); /**< (required) Program up to a page of data at an address */ + + SPIFI_ERR_T (*read)(const struct SPIFI_HANDLE *, uint32_t, uint32_t *, uint32_t); /**< (required) Read an address range */ + + SPIFI_ERR_T (*reset)(const struct SPIFI_HANDLE *); /**< (required) Reset SPIFI device */ + + /* Info query functions */ + uint32_t (*getStatus)(const struct SPIFI_HANDLE *, uint8_t); /**< (required) Returns device status */ + + uint32_t (*subBlockCmd)(const struct SPIFI_HANDLE *, SPIFI_PCMD_SUBBLK_T, uint32_t); /**< (NULL allowed) Performs specified cmd */ + + /* Device specific functions */ + deviceInitDeInitFx devInitDeInit; /**< run-time assigned Fx* device init de-init */ + devClearStatusFx devClearStatus; /**< run-time assigned Fx* to clear status */ + devGetStatusFx devGetStatus; /**< run-time assigned Fx* to get status */ + devSetStatusFx devSetStatus; /**< run-time assigned Fx* to set status */ + devSetOptsFx devSetOpts; /**< run-time assigned Fx* to set quad mode */ + devGetReadCmdFx devGetReadCmd; /**< run-time assigned Fx* to return read cmd */ + devGetWriteCmdFx devGetWriteCmd; /**< run-time assigned Fx* to return write cmd */ +} SPIFI_FAM_FX_T; + +/** + * @brief Device identification data + */ +typedef struct SPIFI_DEVICE_ID { + uint8_t mfgId[3]; /**< JEDEC ID data */ + uint8_t extCount; /**< Number of extended bytes to check */ + uint8_t extId[8]; /**< extended data */ +} SPIFI_DEVICE_ID_T; + +/** + * @brief Register device data. + */ +typedef struct SPIFI_DEVICE_DATA { + const char *pDevName; /**< (required) Device friendly name */ + SPIFI_DEVICE_ID_T id; /**< Device id structure */ + uint32_t caps; /**< capabilities supported */ + uint16_t blks; /**< # of blocks */ + uint32_t blkSize; /**< size of block */ + uint16_t subBlks; /**< # of sub-blocks */ + uint16_t subBlkSize; /**< size of sub-block */ + uint16_t pageSize; /**< page size */ + uint32_t maxReadSize; /**< max read allowed in one operation */ + uint8_t maxClkRate; /**< (in Mhz) maximum clock rate (max common speed) */ + uint8_t maxReadRate; /**< (in Mhz) max clock rate for read (driver may utilize fast read) */ + uint8_t maxHSReadRate; /**< (in Mhz) max clock rate for quad / dual read */ + uint8_t maxProgramRate; /**< (in Mhz) max clock rate for program */ + uint8_t maxHSProgramRate; /**< (in Mhz) max clock rate for quad program */ + uint8_t initDeInitFxId; /**< init/DeInit fx_id */ + uint8_t clearStatusFxId; /**< clearStatus fx_id */ + uint8_t getStatusFxId; /**< getStatus fx_id */ + uint8_t setStatusFxId; /**< setStatus fx_id */ + uint8_t setOptionsFxId; /**< setOptions fx_id */ + uint8_t getReadCmdFxId; /**< getReadCommand fx_id */ + uint8_t getWriteCmdFxId; /**< getWriteCommand fx_id */ +} SPIFI_DEVICE_DATA_T; + +/** + * @brief LPCSPIFILIB device handle, used with all device and info functions + */ +typedef struct SPIFI_HANDLE { + const struct SPIFI_FAM_FX *pFamFx; /**< (required) Pointer to device specific functions */ + + struct SPIFI_INFODATA *pInfoData; /**< (required) Pointer to info data area */ + + void *pDevContext; /**< (NULL allowed) Pointer to device context (used by device functions) */ +} SPIFI_HANDLE_T; + +/** + * @brief Common data applicable to all devices + */ +typedef struct SPIFI_INFODATA { + uint32_t spifiCtrlAddr; /**< SPIFI controller base address */ + uint32_t baseAddr; /**< Physical base address for the device */ + uint32_t numBlocks; /**< Number of blocks on the device */ + uint32_t blockSize; /**< Size of blocks on the device */ + uint32_t numSubBlocks; /**< Number of sub-blocks on the device */ + uint32_t subBlockSize; /**< Size of sub-blocks on the device */ + uint32_t pageSize; /**< Size of a page, usually denotes maximum write size in bytes for a single write operation */ + uint32_t maxReadSize; /**< Maximum read size in bytes for a single read operation */ + const struct SPIFI_DEVICE_DATA *pDeviceData; /**< (required) Pointer to device specific data */ + + uint32_t opts; /**< Device options of values SPIFI_OPT_* */ + const char *pDevName; /**< (required) Pointer to device name */ + SPIFI_ERR_T lastErr; /**< Last error for the driver */ + const SPIFI_DEVICE_ID_T *pId; /**< (required) Device id structure (JEDEC ID etc) */ +} SPIFI_INFODATA_T; + +/** + * @brief Context for enumerating devices + */ +typedef struct SPIFI_DEV_ENUMERATOR { + SPIFI_FAM_NODE_T *pFamily; /**< pointer to family node */ + SPIFI_DEV_NODE_T *pDevice; /**< pointer to device structure */ +} SPIFI_DEV_ENUMERATOR_T; + +/** + * @} + */ + +/** @defgroup LPCSPIFILIB_REGISTERHELPER LPCSPIFILIB family registration functions + * @ingroup LPCSPIFILIB + * @{ + */ + +/** + * @brief Family registration function + * @return A pointer to a persistent SPIFI_DEV_FAMILY_T initialized for family. + * @note This function constructs and returns a non-volitile SPIFI_DEV_FAMILY_T + * structure that contains family specific information needed to register family. + * This function MUST NOT be called directly and should only be passed to the + * registration function spifiRegisterFamily() + */ +SPIFI_FAM_NODE_T *spifi_REG_FAMILY_CommonCommandSet(void); + +/** + * @brief SPIFI_REG_FAMILY_Spansion_2Byte_PStatus Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_Spansion_2Byte_PStatus spifi_REG_FAMILY_CommonCommandSet + +/** + * @brief SPIFI_REG_FAMILY_Spansion_3Byte_Status Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_Spansion_3Byte_Status spifi_REG_FAMILY_CommonCommandSet + +/** + * @brief SPIFI_REG_FAMILY_Macronix_2Byte_Status Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_Macronix_2Byte_Status spifi_REG_FAMILY_CommonCommandSet + +/** + * @brief SPIFI_REG_FAMILY_SpansionS25FLP Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_SpansionS25FLP spifi_REG_FAMILY_CommonCommandSet + +/** + * @brief SPIFI_REG_FAMILY_SpansionS25FL1 Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_SpansionS25FL1 spifi_REG_FAMILY_CommonCommandSet + +/** + * @brief SPIFI_REG_FAMILY_MacronixMX25L Depricated! Do NOT use for new development + */ +#define SPIFI_REG_FAMILY_MacronixMX25L spifi_REG_FAMILY_CommonCommandSet + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __SPIFILIB_DEV_H_ */ diff --git a/arch/arm/src/lpc43xx/spifi/src/Make.defs b/arch/arm/src/lpc43xx/spifi/src/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..12570a3aab868e09ff652da6b3d8f5e7efee2fe2 --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/src/Make.defs @@ -0,0 +1,41 @@ +############################################################################ +# configs/lpc4330-xplorer/src/Makefile +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +VPATH += chip/spifi/src + +ifeq ($(CONFIG_SPIFI_LIBRARY),y) +CHIP_CSRCS += spifilib_fam_standard_cmd.c +CHIP_CSRCS += spifilib_dev_common.c +endif diff --git a/arch/arm/src/lpc43xx/spifi/src/spifilib_dev_common.c b/arch/arm/src/lpc43xx/spifi/src/spifilib_dev_common.c new file mode 100644 index 0000000000000000000000000000000000000000..8adc8f762b30af84b5ef7cfa5691bf07b03dbe88 --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/src/spifilib_dev_common.c @@ -0,0 +1,864 @@ +/* + * @brief LPCSPIFILIB driver functions and structures that are not visible + * + * @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. + */ + +#include "spifi/inc/spifilib_api.h" +#include "spifi/inc/private/spifilib_chiphw.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ +#ifndef NULL +#define NULL 0L +#endif + +/* Declare the version numbers */ +#define LIBRARY_VERSION_MAJOR (1) +#define LIBRARY_VERSION_MINOR (03) + +/* device node count and linked list header */ +static uint32_t famCount = 0; +static SPIFI_FAM_NODE_T famListHead = {0}; + +/* Generic device OP Codes */ +#define SPIFI_OP_CODE_RDID 0x9F + +/* Number of supported devices */ +#define NUMSUPPDEVS (sizeof(pPrvDevs) / sizeof(SPIFI_DEVDESC_T *)) + +/* Mapped error strings to error codes */ +static const char *spifiErrStrings[SPIFI_ERR_LASTINDEX] = { + "No error", + "Device is busy", + "General error", + "Capability not supported", + "Alignment error", + "Device is locked", + "Program error", + "Erase error", + "Program region not blank", + "Page size exceeded", + "Validation error", + "Range exceeded", + "Not Allowed in Memory Mode" +}; + +static const char noName[] = "Invalid index"; + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ +static uint8_t spifiPrvCheckExtendedMatch(SPIFI_DEV_NODE_T *pNode, SPIFI_DEVICE_ID_T *pID) +{ + uint32_t x; + + if (pID->extCount != pNode->pDevData->id.extCount) { + return 0; + } + + if (pNode->pDevData->id.extCount) { + for (x = 0; x < pID->extCount; ++x) { + if (pNode->pDevData->id.extId[x] != pID->extId[x]) { + return 0; + } + } + } + + return 1; +} + +static SPIFI_DEV_NODE_T *spifiPrvFindDeviceMatch(SPIFI_DEV_NODE_T *pHead, SPIFI_DEVICE_ID_T *pID, uint8_t checkExtended) +{ + SPIFI_DEV_NODE_T *pNode; + + /* search the list looking for a match. Skip over head node since + it is a dummy node and NEVER contains data */ + for (pNode = pHead->pNext; pNode != NULL; pNode = pNode->pNext) { + /* Manufacturer and part match? */ + if ((pID->mfgId[0] == pNode->pDevData->id.mfgId[0]) && + (pID->mfgId[1] == pNode->pDevData->id.mfgId[1]) && + (pID->mfgId[2] == pNode->pDevData->id.mfgId[2])) { + /* If extended data check it */ + uint8_t matchFound = 1; + if (checkExtended) { + matchFound = spifiPrvCheckExtendedMatch(pNode, pID); + + } + /* Match, time to exit */ + if (matchFound) { + return pNode; + } + } + } + return NULL; +} + +/* Read Identification */ +static void spifiPrvDevGetID(uint32_t spifiAddr, SPIFI_DEVICE_ID_T *pID) +{ + uint8_t idx; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) spifiAddr; + + /* Read ID command, plus read 3 bytes on data */ + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(SPIFI_OP_CODE_RDID) | + SPIFI_CMD_DATALEN(3 + pID->extCount) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + /* Get info from the device */ + pID->mfgId[0] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Manufacturers ID */ + pID->mfgId[1] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Memory Type */ + pID->mfgId[2] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Memmory Capacity */ + + /* Read the specified number of extended bytes */ + for (idx = 0; idx < pID->extCount; ++idx) { + pID->extId[idx] = spifi_HW_GetData8(pSpifiCtrlAddr); + } + + spifi_HW_WaitCMD(pSpifiCtrlAddr); +} + +/* Detect if this device exists at the passed base address, returns 0 if the + device doesn't exist of the required memory allocation size for the device + context if the device exists. */ +static SPIFI_DEV_NODE_T *spifiPrvDevDetect(uint32_t spifiCtrlAddr, SPIFI_FAM_NODE_T *familyNode) +{ + SPIFI_DEV_NODE_T *devNode; + uint32_t idx; + SPIFI_DEVICE_ID_T id; + SPIFI_DEVICE_ID_T idVerify; + void (*pPrvspifiPrvDevGetID)(uint32_t baseAddr, SPIFI_DEVICE_ID_T *pID) = spifiPrvDevGetID; + + /* Do not ask for extended ID information yet */ + id.extCount = 0; + idVerify.extCount = 0; + + /* If the family has a specific readID routine, use it instead */ + if (familyNode->pDesc->pPrvDevGetID) { + pPrvspifiPrvDevGetID = familyNode->pDesc->pPrvDevGetID; + } + + /* Read device ID three times to validate. First read on a hard reset isn't reliable */ + pPrvspifiPrvDevGetID(spifiCtrlAddr, &id); + pPrvspifiPrvDevGetID(spifiCtrlAddr, &id); + pPrvspifiPrvDevGetID(spifiCtrlAddr, &idVerify); + + /* Compare both reads to make sure they match. If any byte doesn't compare, abort. */ + for (idx = 0; idx < sizeof(id.mfgId); ++idx) { + if (id.mfgId[idx] != idVerify.mfgId[idx]) { + return NULL; + } + } + + /* Find match for 3 bytes. If found, check to see if there is extended id information */ + devNode = spifiPrvFindDeviceMatch(familyNode->pDesc->pDevList, &id, 0); + if ((devNode) && (devNode->pDevData->id.extCount)) { + + /* read ID + extended ID data */ + id.extCount = devNode->pDevData->id.extCount; + pPrvspifiPrvDevGetID(spifiCtrlAddr, &id); + + /* Now get the node that matches JEDEC and extended data */ + devNode = spifiPrvFindDeviceMatch(familyNode->pDesc->pDevList, &id, 1); + } + + return devNode; +} + +/* Detect first SPIFI FLASH device at the passed base address */ +static SPIFI_FAM_NODE_T *spifiPrvPartDetect(uint32_t spifiCtrlAddr, SPIFI_DEV_NODE_T * *devData) +{ + SPIFI_FAM_NODE_T *pNode; + + /* Loop through the library and check for detected devices. + skip over head node because it is NEVER used. */ + for (pNode = famListHead.pNext; pNode != NULL; pNode = pNode->pNext) { + /* Match at this index */ + if ((*devData = spifiPrvDevDetect(spifiCtrlAddr, pNode)) != NULL) { + return pNode; + } + } + + return NULL; +} + +static uint32_t spifiPrvCalculateHandleSize(SPIFI_FAM_NODE_T *devData) +{ + /* This is the size needed for the device context instance by the driver */ + return sizeof(SPIFI_HANDLE_T) + sizeof(SPIFI_INFODATA_T) + + devData->pDesc->prvContextSize; +} + +static void *spifiPrvMemset(void *bufPtr, uint8_t value, uint32_t count) +{ + uint8_t *dest = (uint8_t *) bufPtr; + uint32_t index; + + for (index = 0; index < count; ++index) { + dest[index] = value; + } + return bufPtr; +} + +static void spifiPrvInitContext(SPIFI_DEV_ENUMERATOR_T *pContext, SPIFI_FAM_NODE_T *pFamily) +{ + /* Save the new family passed */ + pContext->pFamily = pFamily; + + /* Save pointer to device or NULL if No devices */ + if (pFamily) { + pContext->pDevice = pFamily->pDesc->pDevList->pNext; + } + else { + pContext->pDevice = NULL; + } +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ +SPIFI_FAM_NODE_T *spifiRegisterFamily(SPIFI_FAM_NODE_T *(*regFx)(void)) +{ + SPIFI_FAM_NODE_T *pFam; + + /* Get the family node from the user */ + pFam = regFx(); + + /* If not a valid family return NULL and don't process */ + if (!pFam) { + return NULL; + } + + /* Insert the node into the beginning of the list */ + pFam->pNext = famListHead.pNext; + famListHead.pNext = pFam; + + /* update the count of known families */ + ++famCount; + + /* Return handle */ + return pFam; +} + +/* register a device (i.e append to the list of known devices) */ +SPIFI_ERR_T spifiDevRegister(const SPIFI_FAM_NODE_T *pDevFamily, SPIFI_DEV_NODE_T *pDevData) +{ + /* insert into the beginning of the list */ + pDevData->pNext = pDevFamily->pDesc->pDevList->pNext; + pDevFamily->pDesc->pDevList->pNext = pDevData; + + /* update the number of devices in the list */ + (*pDevFamily->pDesc->pDevCount) += 1; + + /* Nothing to do here yet */ + return SPIFI_ERR_NONE; +} + +/* enumerate the friendly names of supported devices */ +const char *spifiDevEnumerateName(SPIFI_DEV_ENUMERATOR_T *pContext, uint8_t reset) +{ + const char *retValue = NULL; + + /* If user requested reset, point back to the beginning of the list */ + if (reset) { + /* Initialize the device list from new family */ + spifiPrvInitContext(pContext, famListHead.pNext); + } + + /* Now get the friendly name of the current device and increment to the next device. */ + if (pContext->pDevice) { + /* Retrieve friendly name */ + retValue = pContext->pDevice->pDevData->pDevName; + + /* Point at next device */ + pContext->pDevice = pContext->pDevice->pNext; + + /* Point at next family if at end of device list */ + if (!pContext->pDevice) { + + /* Initialize the device list from new family */ + spifiPrvInitContext(pContext, pContext->pFamily->pNext); + } + } + return retValue; +} + +/* Report the library version number */ +uint16_t spifiGetLibVersion(void) +{ + return (LIBRARY_VERSION_MAJOR << 8) | LIBRARY_VERSION_MINOR; +} + +/* Initialize the SPIFILIB driver */ +SPIFI_ERR_T spifiInit(uint32_t spifiCtrlAddr, uint8_t reset) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) spifiCtrlAddr; + + if (reset) { + /* Reset controller */ + spifi_HW_ResetController(pSpifiCtrlAddr); + + /* Set intermediate data and memcmd registers. */ + spifi_HW_SetIDATA(pSpifiCtrlAddr, 0x0); + spifi_HW_SetMEMCMD(pSpifiCtrlAddr, 0); + + spifi_HW_ResetController(pSpifiCtrlAddr); + + /* Setup SPIFI controller */ + spifi_HW_SetCtrl(pSpifiCtrlAddr, + (SPIFI_CTRL_TO(1000) | + SPIFI_CTRL_CSHI(15) | + SPIFI_CTRL_RFCLK(1) | + SPIFI_CTRL_FBCLK(1))); + } + + /* Nothing to do here yet */ + return SPIFI_ERR_NONE; +} + +/* performs device specific initialization */ +SPIFI_ERR_T spifiDevInit(const SPIFI_HANDLE_T *pHandle) +{ + SPIFI_ERR_T retValue = SPIFI_ERR_NONE; + + /* call device specific initialization if provided */ + pHandle->pFamFx->devInitDeInit(pHandle, 1); + + /* make sure the controller is not in memMode */ + spifiDevSetMemMode(pHandle, 0); + + return retValue; +} + +/* performs device specific de-initialization */ +SPIFI_ERR_T spifiDevDeInit(const SPIFI_HANDLE_T *pHandle) +{ + SPIFI_ERR_T retValue = SPIFI_ERR_NONE; + + /* call device specific de-init if provided */ + pHandle->pFamFx->devInitDeInit(pHandle, 0); + + /* make sure the controller is in memMode */ + spifiDevSetMemMode(pHandle, 1); + + return retValue; +} + +/* Converts a SPIFILIB error code into a meaningful string */ +const char *spifiReturnErrString(SPIFI_ERR_T errCode) +{ + if (((unsigned int) errCode) < SPIFI_ERR_LASTINDEX) { + return spifiErrStrings[errCode]; + } + + return noName; +} + +/* Returns information on the device */ +uint32_t spifiDevGetInfo(const SPIFI_HANDLE_T *pHandle, SPIFI_INFO_ID_T infoId) +{ + uint32_t val = 0; + + /* Don't use switch statement to prevent including clib helpers */ + if (infoId == SPIFI_INFO_BASE_ADDRESS) { + val = pHandle->pInfoData->baseAddr; + } + else if (infoId == SPIFI_INFO_DEVSIZE) { + val = pHandle->pInfoData->numBlocks * pHandle->pInfoData->blockSize; + + } + else if (infoId == SPIFI_INFO_ERASE_BLOCKS) { + val = pHandle->pInfoData->numBlocks; + + } + else if (infoId == SPIFI_INFO_ERASE_BLOCKSIZE) { + val = pHandle->pInfoData->blockSize; + + } + else if (infoId == SPIFI_INFO_ERASE_SUBBLOCKS) { + val = pHandle->pInfoData->numSubBlocks; + + } + else if (infoId == SPIFI_INFO_ERASE_SUBBLOCKSIZE) { + val = pHandle->pInfoData->subBlockSize; + + } + else if (infoId == SPIFI_INFO_PAGESIZE) { + val = pHandle->pInfoData->pageSize; + + } + else if (infoId == SPIFI_INFO_MAXREADSIZE) { + val = pHandle->pInfoData->maxReadSize; + + } + else if (infoId == SPIFI_INFO_MAXCLOCK) { + val = (pHandle->pInfoData->pDeviceData->maxClkRate * 1000000); + + } + else if (infoId == SPIFI_INFO_MAX_READ_CLOCK) { + val = (pHandle->pInfoData->pDeviceData->maxReadRate * 1000000); + + } + else if (infoId == SPIFI_INFO_MAX_HSREAD_CLOCK) { + val = (pHandle->pInfoData->pDeviceData->maxHSReadRate * 1000000); + + } + else if (infoId == SPIFI_INFO_MAX_PROG_CLOCK) { + val = (pHandle->pInfoData->pDeviceData->maxProgramRate * 1000000); + + } + else if (infoId == SPIFI_INFO_MAX_HSPROG_CLOCK) { + val = (pHandle->pInfoData->pDeviceData->maxHSProgramRate * 1000000); + + } + else if (infoId == SPIFI_INFO_CAPS) { + val = pHandle->pInfoData->pDeviceData->caps; + + } + else if (infoId == SPIFI_INFO_STATUS) { + val = pHandle->pFamFx->getStatus(pHandle, 1); + + } + else if (infoId == SPIFI_INFO_STATUS_RETAIN) { + val = pHandle->pFamFx->getStatus(pHandle, 0); + + } + else if (infoId == SPIFI_INFO_OPTIONS) { + val = pHandle->pInfoData->opts; + } + + return val; +} + +/* Returns status of memory mode */ +uint8_t spifiDevGetMemoryMode(const SPIFI_HANDLE_T *pHandle) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + return (spifi_HW_GetStat(pSpifiCtrlAddr) & SPIFI_STAT_MCINIT) != 0; +} + +SPIFI_ERR_T spifiDevSetMemMode(const SPIFI_HANDLE_T *pHandle, uint8_t enMMode) +{ + uint32_t cmdValue; + uint32_t iDataValue; + uint32_t ctrlReg; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + /* RESET the memMode controller */ + spifi_HW_ResetController(pSpifiCtrlAddr); + + /* Wait for HW to acknowledge the reset. */ + spifi_HW_WaitRESET(pSpifiCtrlAddr); + + /* First off set the HW mode based on current option */ + ctrlReg = spifi_HW_GetCtrl(pSpifiCtrlAddr); + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_READ) { + ctrlReg &= ~(SPIFI_CTRL_DUAL(1)); + } + else if (pHandle->pInfoData->opts & SPIFI_CAP_DUAL_READ) { + ctrlReg |= SPIFI_CTRL_DUAL(1); + } + spifi_HW_SetCtrl(pSpifiCtrlAddr, ctrlReg); + + if (enMMode) { + /* Get the device specific memory mode command and iData values */ + pHandle->pFamFx->devGetReadCmd(pHandle, enMMode, &cmdValue, &iDataValue); + + /* Specify the intermediate data byte. */ + spifi_HW_SetIDATA(pSpifiCtrlAddr, iDataValue); + + /* Set the appropriate values in the command reg. */ + spifi_HW_SetCmd(pSpifiCtrlAddr, cmdValue); + spifi_HW_WaitCMD(pSpifiCtrlAddr); + spifi_HW_SetMEMCMD(pSpifiCtrlAddr, cmdValue); + } + else { + spifi_HW_SetIDATA(pSpifiCtrlAddr, 0xFF); + spifi_HW_SetMEMCMD(pSpifiCtrlAddr, 0); + + /* RESET the memMode controller */ + spifi_HW_ResetController(pSpifiCtrlAddr); + + /* Wait for HW to acknowledge the reset. */ + spifi_HW_WaitRESET(pSpifiCtrlAddr); + } + return SPIFI_ERR_NONE; +} + +/* Return the number of supported device families in this driver */ +uint32_t spifiGetSuppFamilyCount(void) +{ + /* return number of registered devices */ + return famCount; +} + +/* Return the driver family name for a specific index */ +const char *spifiGetSuppFamilyName(uint32_t index) +{ + uint32_t idx; + SPIFI_FAM_NODE_T *pNode; + + if (index >= famCount) { + return noName; + } + + /* cycle through the list of families skipping over head node since it + is NEVER used. Once we break out of this loop pNode should be + pointing at the correct node. */ + pNode = famListHead.pNext; + for (idx = 0; idx < index; ++idx) { + pNode = pNode->pNext; + } + + return pNode->pDesc->pFamName; +} + +/* Detect and return memory needed for device handle at passed address */ +uint32_t spifiGetHandleMemSize(uint32_t spifiCtrlAddr) +{ + uint32_t bytesNeeded = 0; + SPIFI_FAM_NODE_T *detectedPart; + SPIFI_DEV_NODE_T *devData; + + /* Find first device at the base address */ + detectedPart = spifiPrvPartDetect(spifiCtrlAddr, &devData); + if (detectedPart) { + /* This is the size needed for the device context instance by the driver */ + bytesNeeded = spifiPrvCalculateHandleSize(detectedPart); + } + + return bytesNeeded; +} + +/* Initialize driver and hardware for a specific device */ +SPIFI_HANDLE_T *spifiInitDevice(void *pMem, uint32_t sizePMem, uint32_t spifiCtrlAddr, uint32_t baseAddr) +{ + SPIFI_FAM_NODE_T *detectedPart; + SPIFI_DEV_NODE_T *devData; + SPIFI_HANDLE_T *pSpifiHandle; + uint32_t *pMem32 = (uint32_t *) pMem; + + /* Is the passed buffer size aligned on a 32-bit boundary? */ + if (((uint32_t) pMem32 & 0x3) != 0) { + return NULL; + } + + /* Detect the device at at the base address and abort on error. */ + detectedPart = spifiPrvPartDetect(spifiCtrlAddr, &devData); + if (!detectedPart) { + return NULL; + } + + /* Is passed memory space big enough? */ + if (spifiPrvCalculateHandleSize(detectedPart) > sizePMem) { + return NULL; + } + + /* Setup handle */ + pSpifiHandle = (SPIFI_HANDLE_T *) pMem; + + /* Clear entire device context areas */ + spifiPrvMemset(pMem, 0, sizePMem); + + /* Setup device info region */ + pMem32 += (sizeof(SPIFI_HANDLE_T) / sizeof(uint32_t)); + pSpifiHandle->pInfoData = (SPIFI_INFODATA_T *) pMem32; + + /* Save ptr to the detected device specific data into the handle */ + pSpifiHandle->pInfoData->pId = &devData->pDevData->id; + + /* Setup device private data region */ + pMem32 += (sizeof(SPIFI_INFODATA_T) / sizeof(uint32_t)); + pSpifiHandle->pDevContext = (void *) pMem32; + + /* Setup device specific data */ + pSpifiHandle->pInfoData->spifiCtrlAddr = spifiCtrlAddr; + pSpifiHandle->pInfoData->baseAddr = baseAddr; + pSpifiHandle->pInfoData->numBlocks = devData->pDevData->blks; + pSpifiHandle->pInfoData->blockSize = devData->pDevData->blkSize; + pSpifiHandle->pInfoData->numSubBlocks = devData->pDevData->subBlks; + pSpifiHandle->pInfoData->subBlockSize = devData->pDevData->subBlkSize; + pSpifiHandle->pInfoData->pageSize = devData->pDevData->pageSize; + pSpifiHandle->pInfoData->maxReadSize = devData->pDevData->maxReadSize; + pSpifiHandle->pInfoData->pDeviceData = devData->pDevData; + pSpifiHandle->pInfoData->pDevName = devData->pDevData->pDevName; + + /* Call device setup */ + pSpifiHandle->pInfoData->lastErr = detectedPart->pDesc->pPrvDevSetup(pSpifiHandle, spifiCtrlAddr, baseAddr); + + if (pSpifiHandle->pInfoData->lastErr != SPIFI_ERR_NONE) { + return NULL; + } + + /* Call the device specific init */ + pSpifiHandle->pInfoData->lastErr = spifiDevInit(pSpifiHandle); + if (pSpifiHandle->pInfoData->lastErr != SPIFI_ERR_NONE) { + return NULL; + } + + return pSpifiHandle; +} + +SPIFI_ERR_T spifiDevSetOpts(SPIFI_HANDLE_T *pHandle, uint32_t options, uint8_t set) +{ + /* default to not supported */ + SPIFI_ERR_T retValue = SPIFI_ERR_NOTSUPPORTED; + + /* If changing any of the high speed modes process seperately */ + if (options & (SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE)) { + uint32_t hsOptions; + uint8_t memMode; + + /* first get the current memory mode */ + memMode = spifiDevGetMemoryMode(pHandle); + + /* First clear ALL high speed mode options */ + pHandle->pInfoData->opts &= + ~(SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE); + + /* sanitize the change list */ + hsOptions = options & + (pHandle->pInfoData->pDeviceData->caps & + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE)); + + /* Now set the high speed options */ + if (set) { + pHandle->pInfoData->opts |= hsOptions; + } + + /* Perform device specific setup for the option */ + retValue = pHandle->pFamFx->devSetOpts(pHandle, hsOptions, set); + + /* remove so that it won't be interpreted as an error */ + options &= ~(SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE); + + /* update memory mode when changing the high speed options */ + spifiDevSetMemMode(pHandle, memMode); + } + + /* If the remaining options are valid, process them */ + if ((options & pHandle->pInfoData->pDeviceData->caps) == options) { + retValue = SPIFI_ERR_NONE; + + /* Set the option in the driver so other routines will act accordingly */ + if (set) { + pHandle->pInfoData->opts |= options; + } + else { + pHandle->pInfoData->opts &= ~options; + } + + /* Perform device specific setup for the option if defined */ + if (pHandle->pFamFx->devSetOpts) { + retValue = pHandle->pFamFx->devSetOpts(pHandle, options, set); + } + + } + return retValue; +} + +/* Returns the address mapped to an block number */ +uint32_t spifiGetAddrFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum) +{ + uint32_t baseAddr = 0xFFFFFFFF; + + if (blockNum < pHandle->pInfoData->numBlocks) { + baseAddr = pHandle->pInfoData->baseAddr + (blockNum * pHandle->pInfoData->blockSize); + } + + return baseAddr; +} + +/* Returns the starting address of a sub-block number */ +uint32_t spifiGetAddrFromSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t subBlockNum) +{ + uint32_t baseAddr = ~0UL; + + /* If the device provides a specific method for calculating the address use it. */ + if (!pHandle->pFamFx->subBlockCmd) { + /* If sub-blocks are not supported (.e numSubBlocks = 0) then return error */ + if (subBlockNum < pHandle->pInfoData->numSubBlocks) { + baseAddr = pHandle->pInfoData->baseAddr + (subBlockNum * pHandle->pInfoData->subBlockSize); + } + } + else { + baseAddr = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_SUB_BLOCK_TO_ADDR, subBlockNum); + } + + return baseAddr; +} + +/* Returns the block number the passedd= address is located in */ +uint32_t spifiGetBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr) +{ + uint32_t block; + block = (addr - pHandle->pInfoData->baseAddr) / pHandle->pInfoData->blockSize; + + if (block >= pHandle->pInfoData->numBlocks) { + return ~0UL; + } + + return block; +} + +/* Returns the sub-block number the passed address is located in */ +uint32_t spifiGetSubBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr) +{ + uint32_t subBlock; + + /* If device does not support sub-blocks return error */ + if (!pHandle->pInfoData->subBlockSize) { + return ~0UL; + } + + if (!pHandle->pFamFx->subBlockCmd) { + subBlock = (addr - pHandle->pInfoData->baseAddr) / pHandle->pInfoData->subBlockSize; + + if (subBlock >= pHandle->pInfoData->numSubBlocks) { + return ~0UL; + } + } + else { + subBlock = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_ADDR_TO_SUB_BLOCK, addr); + } + + return subBlock; +} + +/* Returns the first sub-block in hte passed block */ +uint32_t spifiGetSubBlockFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum) +{ + uint32_t subBlock = ~0UL; + + if (!pHandle->pFamFx->subBlockCmd) { + /* If the blockNum passed is larger than this device, + or if sub-blocks are not supported report error */ + if ((blockNum >= pHandle->pInfoData->numBlocks) || + (!pHandle->pInfoData->subBlockSize)) { + return subBlock; + } + /* Calculate the sub-block number based on detected params */ + subBlock = (blockNum * (pHandle->pInfoData->blockSize / pHandle->pInfoData->subBlockSize)); + } + else { + + subBlock = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_BLOCK_TO_SUB_BLOCK, blockNum); + } + + return subBlock; +} + +/* Program the device with the passed buffer */ +SPIFI_ERR_T spifiProgram(const SPIFI_HANDLE_T *pHandle, uint32_t addr, const uint32_t *writeBuff, uint32_t bytes) +{ + uint32_t sendBytes; + SPIFI_ERR_T err = SPIFI_ERR_NONE; + + /* Program using up to page size */ + while ((bytes > 0) && (err == SPIFI_ERR_NONE)) { + sendBytes = bytes; + if (sendBytes > pHandle->pInfoData->pageSize) { + sendBytes = pHandle->pInfoData->pageSize; + } + + err = pHandle->pFamFx->pageProgram(pHandle, addr, writeBuff, sendBytes); + addr += sendBytes; + writeBuff += (sendBytes >> 2); + bytes -= sendBytes; + } + + return err; +} + +/* Read the device into the passed buffer */ +SPIFI_ERR_T spifiRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes) +{ + uint32_t readBytes; + SPIFI_ERR_T err = SPIFI_ERR_NONE; + + /* Read using up to the maximum read size */ + while ((bytes > 0) && (err == SPIFI_ERR_NONE)) { + readBytes = bytes; + if (readBytes > pHandle->pInfoData->maxReadSize) { + readBytes = pHandle->pInfoData->maxReadSize; + } + + err = pHandle->pFamFx->read(pHandle, addr, readBuff, readBytes); + addr += readBytes; + readBuff += (readBytes / sizeof(uint32_t)); + bytes -= readBytes; + } + + return err; +} + +/* Erase multiple blocks */ +SPIFI_ERR_T spifiErase(const SPIFI_HANDLE_T *pHandle, uint32_t firstBlock, uint32_t numBlocks) +{ + SPIFI_ERR_T err = SPIFI_ERR_NONE; + + if ((firstBlock + numBlocks) > pHandle->pInfoData->numBlocks) { + return SPIFI_ERR_RANGE; + } + + /* Only perform erase if numBlocks is != 0 */ + for (; (numBlocks); ++firstBlock, --numBlocks) { + err = pHandle->pFamFx->eraseBlock(pHandle, firstBlock); + if (err != SPIFI_ERR_NONE) { + break; + } + } + + return err; +} + +/* Erase multiple blocks by address range */ +SPIFI_ERR_T spifiEraseByAddr(const SPIFI_HANDLE_T *pHandle, uint32_t firstAddr, uint32_t lastAddr) +{ + uint32_t firstBlock, lastBlock; + SPIFI_ERR_T err = SPIFI_ERR_RANGE; + + /* Get block numbers for addresses */ + firstBlock = spifiGetBlockFromAddr(pHandle, firstAddr); + lastBlock = spifiGetBlockFromAddr(pHandle, lastAddr); + + /* Limit to legal address range */ + if ((firstBlock != ~0UL) && (lastBlock != ~0UL)) { + err = spifiErase(pHandle, firstBlock, ((lastBlock - firstBlock) + 1)); + } + + return err; +} diff --git a/arch/arm/src/lpc43xx/spifi/src/spifilib_fam_standard_cmd.c b/arch/arm/src/lpc43xx/spifi/src/spifilib_fam_standard_cmd.c new file mode 100644 index 0000000000000000000000000000000000000000..d51cb3a67c72fbebd75ed33083e2fc1c16bdd442 --- /dev/null +++ b/arch/arm/src/lpc43xx/spifi/src/spifilib_fam_standard_cmd.c @@ -0,0 +1,1866 @@ +/* + * @brief Common Command Set Family 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. + */ +#include + +#include "spifi/inc/spifilib_dev.h" +#include "spifi/inc/private/spifilib_chiphw.h" +#include +#include + +/* need access to the device register Fx without importing the whole API */ +extern SPIFI_ERR_T spifiDevRegister(SPIFI_FAM_NODE_T *pFamily, SPIFI_DEV_NODE_T *pDevData); + +/** @defgroup LPCSPIFILIB_CONFIG_STANDARD_CMD_SET LPCSPIFILIB Common Command set driver + * @ingroup LPCSPIFILIB_DRIVERS + * This driver includes support for the following devices. (Clones within {} brackets).
+ * S25FL016K {W25Q16DV}
+ * S25FL032P
+ * S25FL064P
+ * S25FL129P 64k Sector
+ * S25FL129P 256k Sector {S25FL128S}
+ * S25FL164K
+ * S25FL256S
+ * S25FL512S
+ * MX25L1635E
+ * MX25L3235E
+ * MX25L6435E
+ * MX25L8035E
+ * W25Q32FV
+ * W25Q64FV
+ * W25Q80BV {W25Q80DV}
+ * + * Driver Feature Specifics:
+ * - common command set
+ * + * Optimization: Ram / code size optimizations can be enabled by enabling specific + * devices in lieu of the default (all devices enabled). Change the setting of + * SPIFI_DEVICE_ALL to 0 and enable specific devices by changing the setting + * of the appropriate SPIFI_DEVICE_XXX to 1. + * @{ + */ + +/** + * @} + */ + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ +/** + * @brief The following set of defines allows fine tuning where specific device support + * can be pre determined and space is at a premium. To Reduce code / iRam requirements + * change the SPIFI_DEVICE_ALL to 0 and change the desired device definition(s) to 1 + */ +//#define SPIFI_DEVICE_ALL 0 /**< Enables all devices in family */ +//#define SPIFI_DEVICE_S25FL016K 0 /**< Enables Spansion S25FL016K device */ +//#define SPIFI_DEVICE_S25FL032P 0 /**< Enables Spansion S25FL032P device */ +//#define SPIFI_DEVICE_S25FL064P 0 /**< Enables Spansion S25FL064P device */ +//#define SPIFI_DEVICE_S25FL129P_64K 0 /**< Enables Spansion S25FL129P (64K block) device */ +//#define SPIFI_DEVICE_S25FL129P_256K 0 /**< Enables Spansion S25FL129P (256K block) device */ +//#define SPIFI_DEVICE_S25FL164K 0 /**< Enables Spansion S25FL164K device */ +//#define SPIFI_DEVICE_S25FL256S_64K 0 /**< Enables Spansion S25FL256S (64K block) device */ +//#define SPIFI_DEVICE_S25FL256S_256K 0 /**< Enables Spansion S25FL256S (256K block) device */ +//#define SPIFI_DEVICE_S25FL512S 0 /**< Enables Spansion S25FL512S device */ +//#define SPIFI_DEVICE_MX25L1635E 0 /**< Enables Macronix MX25L1635E device */ +//#define SPIFI_DEVICE_MX25L3235E 0 /**< Enables Macronix MX25L3235E device */ +//#define SPIFI_DEVICE_MX25L8035E 0 /**< Enables Macronix MX25L8035E device */ +//#define SPIFI_DEVICE_MX25L6435E 0 /**< Enables Macronix MX25L6435E device */ +//#define SPIFI_DEVICE_W25Q32FV 0 /**< Enables Winbond W25Q32FV device */ +//#define SPIFI_DEVICE_W25Q64FV 0 /**< Enables Winbond W25Q32V device */ +//#define SPIFI_DEVICE_W25Q80BV 0 /**< Enables Winbond W25Q80BV device */ + +/* Required private data size for this family */ +#define PRVDATASIZE 0 + +#define MAX_SINGLE_READ 16128 + +/* Command definitions. Only used commands are defined. */ +#define CMD_0B_FAST_READ 0x0B /**< Read Data bytes at Fast Speed */ +#define CMD_BB_DIOR 0xBB /**< Dual IORead (all dual except op code( */ +#define CMD_EB_QIOR 0xEB /**< Quad IORead (all quad except op code) */ +#define CMD_0C_FAST_READ 0x0C /**< Read Data (4B addr) bytes at Fast Speed */ +#define CMD_BC_DIOR 0xBC /**< Dual IORead (4B addr) (all dual except op code( */ +#define CMD_EC_QIOR 0xEC /**< Quad IORead (4B addr) (all quad except op code) */ +#define CMD_06_WREN 0x06 /**< Write Enable */ +#define CMD_20_P4E 0x20 /**< 4 KB Parameter Sector Erase */ +#define CMD_C7_BE 0xC7 /**< Bulk Erase */ +#define CMD_D8_SE 0xD8 /**< Sector Erase */ +#define CMD_DC_SE 0xDC /**< Sector erase (4B addr) */ +#define CMD_02_PP 0x02 /**< Page Programming */ +#define CMD_12_PP 0x12 /**< Page Programming (4B addr) */ +#define CMD_05_RDSR1 0x05 /**< Read Status Register 1 */ +#define CMD_35_RDSR2 0x35 /**< Read Status Register 2 */ +#define CMD_33_RDSR3 0x33 /**< Read Status Register 3 */ +#define CMD_01_WSR 0x01 /**< Write Status Registers */ +#define CMD_30_CSR 0x30 /**< Reset the Erase and Program Fail Flag (SR5 and SR6) and restore normal operation) */ +#define CMD_32_QPP 0x32 /**< Quad Page Programming */ +#define CMD_34_QPP 0x34 /**< Quad Page Programming (4B addr) */ +#define CMD_38_QPP_MACRONIX 0x38 /**< Quad Page Programming for 25L3235E */ + +/* Common status register definitions */ +/* Status Register Write Disable, + 1 = Protects when W# is low, + 0 = No protection, even when W# is low */ +#define STATUS_SRWD (1 << 7) + +/* Block protect bits, + Protects upper half of address range in 5 sizes */ +#define STATUS_BPMASK (7 << 2) +/* Write Enable Latch, + 1 = Device accepts Write Status Register, program, or erase commands, + 0 = Ignores Write Status Register, program, or erase commands */ +#define STATUS_WEL (1 << 1) +/* Write in Progress, + 1 = Device Busy. A Write Status Register, program, or erase, + 0 = Ready. Device is in standby mode and can accept commands. */ +#define STATUS_WIP (1 << 0) + +/* Virtual status bits + (i.e moved to byte 4 so they don't conflict with bits in lower 3 bytes */ +/* Programming Error Occurred, + 0 = No Error, + 1 = Error occurred */ +#define STATUS_P_ERR (1 << 24) +/* Erase Error Occurred, + 0 = No Error, + 1 = Error occurred */ +#define STATUS_W_ERR (1 << 25) + +/* Functions used macro definitions */ +/* Macros to control conditional use functions */ +#define NEED_spifiDeviceDataGetStatusS25FL032P (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S) + +#define NEED_spifiDeviceDataGetStatusS25FL164K (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL164K) + +#define NEED_spifiDeviceDataGetStatusMX25L3235E (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceDataGetStatusW25Q80BV (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV) + +#define NEED_spifiDeviceDataClearStatusNone (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceDataClearStatusS25FL032P (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL164K | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S) + +#define NEED_spifiDeviceDataSetStatusS25FL032P (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV) + +#define NEED_spifiDeviceDataSetStatusS25FL164K (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL164K) + +#define NEED_spifiDeviceDataSetStatusMX25L3235E (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceDataSetOptsQuadModeBit6 (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceDataSetOptsQuadModeBit9 (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL164K | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV) + +#define NEED_spifiDeviceDataInitDeinit (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceDataInitDeinitS25FL164K (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL164K) + +#define NEED_spifiDevice4BInitReadCommand (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S) + +#define NEED_spifiDeviceInitReadCommand (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL164K | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L8035E | \ + SPIFI_DEVICE_MX25L6435E) + +#define NEED_spifiDeviceInitWriteCommand (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL016K | \ + SPIFI_DEVICE_S25FL032P | \ + SPIFI_DEVICE_S25FL064P | \ + SPIFI_DEVICE_S25FL129P_64K | \ + SPIFI_DEVICE_S25FL129P_256K | \ + SPIFI_DEVICE_S25FL164K | \ + SPIFI_DEVICE_W25Q80BV | \ + SPIFI_DEVICE_W25Q32FV | \ + SPIFI_DEVICE_W25Q64FV | \ + SPIFI_DEVICE_MX25L8035E) + +#define NEED_spifiDevice4BInitWriteCommand (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_S25FL256S_64K | \ + SPIFI_DEVICE_S25FL256S_256K | \ + SPIFI_DEVICE_S25FL512S) + +#define NEED_spifiDeviceInitWriteCommandMacronix (SPIFI_DEVICE_ALL | \ + SPIFI_DEVICE_MX25L1635E | \ + SPIFI_DEVICE_MX25L3235E | \ + SPIFI_DEVICE_MX25L6435E) + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Software write Enable */ +static void spifiPrvSetWREN(LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr) +{ + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_06_WREN) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + spifi_HW_WaitCMD(pSpifiCtrlAddr); +} + +/* Wait for device to complete operation (I.e not busy) */ +static void spifiPrvWaitUnBusy(const SPIFI_HANDLE_T *pHandle) +{ + /* Device wait for device to be ready */ + while ((pHandle->pFamFx->devGetStatus(pHandle) & STATUS_WIP) != 0) {} +} + +static void spifiPrvSetQuadModeBitPosition(const SPIFI_HANDLE_T *pHandle, uint32_t bitPosition, uint8_t enQuadMode) +{ + uint32_t statusRegs; + + /* Read the device specific status bytes */ + statusRegs = pHandle->pFamFx->devGetStatus(pHandle); + + /* Set / clear bit x */ + if (enQuadMode) { + statusRegs |= (1 << bitPosition); + } + else { + statusRegs &= ~(1 << bitPosition); + } + + /* Write status back out */ + pHandle->pFamFx->devSetStatus(pHandle, statusRegs); +} + +/* Checks to see if the device is writable and not busy */ +static SPIFI_ERR_T spifiPrvCheckWriteState(const SPIFI_HANDLE_T *pHandle) +{ + uint32_t stat; + + /* Get status */ + stat = pHandle->pFamFx->devGetStatus(pHandle); + + /* Exit if blocks are locked or WIP in progress */ + if ((stat & STATUS_BPMASK) != 0) { + return SPIFI_ERR_LOCKED; + } + else if ((stat & STATUS_WIP) != 0) { + return SPIFI_ERR_BUSY; + } + + return SPIFI_ERR_NONE; +} + +/***************************************************************************** + * Semi-Private functions + * Functions may be assigned to SPIFI_DEVICE_DATA_T function pointers. + ****************************************************************************/ + +/* Read the status bytes for the following device(s)... */ +#if NEED_spifiDeviceDataGetStatusS25FL032P +static uint32_t spifiDeviceDataGetStatusS25FL032P(const SPIFI_HANDLE_T *pHandle) +{ + static const uint8_t spifiCmdOp[2] = {CMD_05_RDSR1, CMD_35_RDSR2}; + uint32_t statusReg = 0; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + uint32_t index; + + /* Read the status bytes needed */ + for (index = 0; index < (sizeof(spifiCmdOp) / sizeof(spifiCmdOp[0])); ++index) { + + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(spifiCmdOp[index]) | + SPIFI_CMD_DATALEN(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + statusReg |= (spifi_HW_GetData8(pSpifiCtrlAddr) << (8 * index)); + + /* Wait for command to complete */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + + /* Move the error bits to generic location */ + if (statusReg & (1 << 5)) { + statusReg |= STATUS_W_ERR; + } + if (statusReg & (1 << 6)) { + statusReg |= STATUS_P_ERR; + } + + /* Finally remove the error bits from the original location */ + statusReg &= ~(3 << 5); + + return statusReg; +} + +#endif + +/* Read the status bytes for the following device(s)... */ +#if NEED_spifiDeviceDataGetStatusS25FL164K +static uint32_t spifiDeviceDataGetStatusS25FL164K(const SPIFI_HANDLE_T *pHandle) +{ + static const uint8_t spifiCmdOp[3] = {CMD_05_RDSR1, CMD_35_RDSR2, CMD_33_RDSR3}; + uint32_t statusRegs = 0; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + uint32_t idx; + + for (idx = 0; idx < sizeof(spifiCmdOp) / sizeof(spifiCmdOp[0]); ++idx) { + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(spifiCmdOp[idx]) | + SPIFI_CMD_DATALEN(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + statusRegs |= (spifi_HW_GetData8(pSpifiCtrlAddr) << (8 * idx)); + + /* Wait for command to complete */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + + return statusRegs; +} + +#endif + +/* Read the status bytes for the following device(s)... */ +#if NEED_spifiDeviceDataGetStatusMX25L3235E +static uint32_t spifiDeviceDataGetStatusMX25L3235E(const SPIFI_HANDLE_T *pHandle) +{ + uint32_t statRegister; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_05_RDSR1) | + SPIFI_CMD_DATALEN(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + statRegister = spifi_HW_GetData8(pSpifiCtrlAddr); + + /* Wait for command to complete */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + return statRegister; +} + +#endif + +/* Read the status bytes for the following device(s)... */ +#if NEED_spifiDeviceDataGetStatusW25Q80BV +static uint32_t spifiDeviceDataGetStatusW25Q80BV(const SPIFI_HANDLE_T *pHandle) +{ + static const uint8_t spifiCmdOp[2] = {CMD_05_RDSR1, CMD_35_RDSR2}; + uint32_t statusReg = 0; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + uint32_t index; + + /* Read the status bytes needed */ + for (index = 0; index < (sizeof(spifiCmdOp) / sizeof(spifiCmdOp[0])); ++index) { + + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(spifiCmdOp[index]) | + SPIFI_CMD_DATALEN(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + statusReg |= (spifi_HW_GetData8(pSpifiCtrlAddr) << (8 * index)); + + /* Wait for command to complete */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + + return statusReg; +} + +#endif + +/* Software clear status for the following device(s) */ +#if NEED_spifiDeviceDataClearStatusNone +static void spifiDeviceDataClearStatusNone(const SPIFI_HANDLE_T *pHandle) +{ + /* Do nothing */ +} + +#endif + +/* Software clear status for the following device(s) */ +#if NEED_spifiDeviceDataClearStatusS25FL032P +static void spifiDeviceDataClearStatusS25FL032P(const SPIFI_HANDLE_T *pHandle) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_30_CSR) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + spifi_HW_WaitCMD(pSpifiCtrlAddr); +} + +#endif + +/* Write Status / Config Register for the following device(s) */ +#if NEED_spifiDeviceDataSetStatusS25FL032P +static void spifiDeviceDataSetStatusS25FL032P(const SPIFI_HANDLE_T *pHandle, uint32_t status) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + spifiPrvSetWREN(pSpifiCtrlAddr); + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_01_WSR) | + SPIFI_CMD_DATALEN(2) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + /* Write the data out. Don't worry about restoring error bits as they are read only anyway */ + spifi_HW_SetData8(pSpifiCtrlAddr, status); + spifi_HW_SetData8(pSpifiCtrlAddr, (status >> 8)); + + /* Wait for Controller to finish command */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* Wait for flash controller to finish command */ + spifiPrvWaitUnBusy(pHandle); +} + +#endif + +/* Write Status1, 2 and 3 Register for the following device(s) */ +#if NEED_spifiDeviceDataSetStatusS25FL164K +static void spifiDeviceDataSetStatusS25FL164K(const SPIFI_HANDLE_T *pHandle, uint32_t status) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + spifiPrvSetWREN(pSpifiCtrlAddr); + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_01_WSR) | + SPIFI_CMD_DATALEN(3) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + /* Write the data out */ + spifi_HW_SetData8(pSpifiCtrlAddr, status); + spifi_HW_SetData8(pSpifiCtrlAddr, (status >> 8)); + spifi_HW_SetData8(pSpifiCtrlAddr, (status >> 16)); + + /* Wait for Controller to finish command */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* Wait for flash controller to finish command */ + spifiPrvWaitUnBusy(pHandle); +} + +#endif + +/* Write Status / Config Register for the following device(s)*/ +#if NEED_spifiDeviceDataSetStatusMX25L3235E +static void spifiDeviceDataSetStatusMX25L3235E(const SPIFI_HANDLE_T *pHandle, uint32_t status) +{ + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + spifiPrvSetWREN(pSpifiCtrlAddr); + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_01_WSR) | + SPIFI_CMD_DATALEN(1) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + /* Write the data out */ + spifi_HW_SetData8(pSpifiCtrlAddr, status); + + /* Wait for Controller to finish command */ + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* Wait for flash controller to finish command */ + spifiPrvWaitUnBusy(pHandle); +} + +#endif + +/* Function to change bit 6 of status/config register for the following device(s) */ +#if NEED_spifiDeviceDataSetOptsQuadModeBit6 +static SPIFI_ERR_T spifiDeviceDataSetOptsQuadModeBit6(const SPIFI_HANDLE_T *pHandle, uint32_t opts, uint32_t enMode) +{ + /* Do not attempt to set bit if option is not supported */ + if (opts & (SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE)) { + spifiPrvSetQuadModeBitPosition(pHandle, 6, enMode); + } + return SPIFI_ERR_NONE; +} + +#endif + +/* Function to change bit 9 of status/config register for the following device(s) */ +#if NEED_spifiDeviceDataSetOptsQuadModeBit9 +static SPIFI_ERR_T spifiDeviceDataSetOptsQuadModeBit9(const SPIFI_HANDLE_T *pHandle, uint32_t opts, uint32_t enMode) +{ + /* Do not attempt to set bit if option is not supported */ + if (opts & (SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE)) { + spifiPrvSetQuadModeBitPosition(pHandle, 9, enMode); + } + return SPIFI_ERR_NONE; +} + +#endif + +/* Initialize SPIFI device for the following device(s) */ +#if NEED_spifiDeviceDataInitDeinit +static SPIFI_ERR_T spifiDeviceDataInitDeinit(const SPIFI_HANDLE_T *pHandle, uint32_t init) +{ + return SPIFI_ERR_NONE; +} + +#endif + +/* Initialize SPIFI device for the following device(s) */ +#if NEED_spifiDeviceDataInitDeinitS25FL164K +static SPIFI_ERR_T spifiDeviceDataInitDeinitS25FL164K(const SPIFI_HANDLE_T *pHandle, uint32_t init) +{ + uint32_t status; + + /* Disable variable read latency */ + if (init) { + status = pHandle->pFamFx->devGetStatus(pHandle); + status &= ~(0xf << 16); /* Latency control bits for this part */ + pHandle->pFamFx->devSetStatus(pHandle, status); + } + + return SPIFI_ERR_NONE; +} + +#endif + +/* Function to return spifi controller read cmd */ +#if NEED_spifiDeviceInitReadCommand +static void spifiDeviceInitReadCommand(const SPIFI_HANDLE_T *pHandle, uint8_t enable, + uint32_t *cmd, uint32_t *iData) +{ + if (iData) { + *iData = 0xFF; + } + + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_READ) { + *cmd = + (SPIFI_CMD_OPCODE(CMD_EB_QIOR) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(3) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } + else if (pHandle->pInfoData->opts & SPIFI_CAP_DUAL_READ) { + *cmd = + (SPIFI_CMD_OPCODE(CMD_BB_DIOR) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } + /* Default to single lane mode if no other modes enabled */ + else { + *cmd = + (SPIFI_CMD_OPCODE(CMD_0B_FAST_READ) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } +} + +#endif + +/* Function to return spifi controller read cmd */ +#if NEED_spifiDevice4BInitReadCommand +static void spifiDevice4BInitReadCommand(const SPIFI_HANDLE_T *pHandle, uint8_t enable, + uint32_t *cmd, uint32_t *iData) +{ + if (iData) { + *iData = 0xFF; + } + + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_READ) { + *cmd = + (SPIFI_CMD_OPCODE(CMD_EC_QIOR) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(3) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS)); + } + else if (pHandle->pInfoData->opts & SPIFI_CAP_DUAL_READ) { + *cmd = + (SPIFI_CMD_OPCODE(CMD_BC_DIOR) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS)); + } + /* Default to single lane mode if no other modes enabled */ + else { + *cmd = + (SPIFI_CMD_OPCODE(CMD_0C_FAST_READ) | + SPIFI_CMD_DOUT(0) | + SPIFI_CMD_INTER(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS)); + } +} + +#endif + +/* Function to return spifi controller write cmd */ +#if NEED_spifiDeviceInitWriteCommand +static void spifiDeviceInitWriteCommand(const SPIFI_HANDLE_T *pHandle, uint32_t *cmd) +{ + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_WRITE) { + *cmd = (SPIFI_CMD_OPCODE(CMD_32_QPP) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE_ADDRESS) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } + else { + *cmd = (SPIFI_CMD_OPCODE(CMD_02_PP) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } +} + +#endif + +#if NEED_spifiDevice4BInitWriteCommand +static void spifiDevice4BInitWriteCommand(const SPIFI_HANDLE_T *pHandle, uint32_t *cmd) +{ + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_WRITE) { + *cmd = (SPIFI_CMD_OPCODE(CMD_34_QPP) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE_ADDRESS) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS)); + } + else { + *cmd = (SPIFI_CMD_OPCODE(CMD_12_PP) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS)); + } +} + +#endif + +/* Function to return spifi controller write cmd */ +#if NEED_spifiDeviceInitWriteCommandMacronix +static void spifiDeviceInitWriteCommandMacronix(const SPIFI_HANDLE_T *pHandle, uint32_t *cmd) +{ + if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_WRITE) { + *cmd = (SPIFI_CMD_OPCODE(CMD_38_QPP_MACRONIX) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } + else { + *cmd = (SPIFI_CMD_OPCODE(CMD_02_PP) | + SPIFI_CMD_DOUT(1) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)); + } +} + +#endif + +/* Function to indicate configuration error */ +static void spifiDeviceFxError(void) +{ + while (1) {} +} + +/* Function to return Fx* for initialization */ +static deviceInitDeInitFx spifiDeviceAssignFxInitDeInit(SPIFI_HANDLE_T *pHandle) +{ + if (pHandle->pInfoData->pDeviceData->initDeInitFxId == FX_spifiDeviceDataInitDeinitS25FL164K) { +#if NEED_spifiDeviceDataInitDeinitS25FL164K + return spifiDeviceDataInitDeinitS25FL164K; +#endif + } + else if (pHandle->pInfoData->pDeviceData->initDeInitFxId == FX_spifiDeviceDataInitDeinit ) { +#if NEED_spifiDeviceDataInitDeinit + return spifiDeviceDataInitDeinit; +#endif + } + return (deviceInitDeInitFx) spifiDeviceFxError; +} + +/* Function to return Fx* for clearing status */ +static devClearStatusFx spifiDeviceAssignFxClearStatus(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device clearStatus Fx* */ + if (pHandle->pInfoData->pDeviceData->clearStatusFxId == FX_spifiDeviceDataClearStatusS25FL032P) { +#if NEED_spifiDeviceDataClearStatusS25FL032P + return spifiDeviceDataClearStatusS25FL032P; +#endif + } + else if (pHandle->pInfoData->pDeviceData->clearStatusFxId == FX_spifiDeviceDataClearStatusNone) { +#if NEED_spifiDeviceDataClearStatusNone + return spifiDeviceDataClearStatusNone; +#endif + } + return (devClearStatusFx) spifiDeviceFxError; +} + +/* Function to return Fx* for getting status */ +static devGetStatusFx spifiDeviceAssignFxGetStatus(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device getStatus Fx* */ + if (pHandle->pInfoData->pDeviceData->getStatusFxId == FX_spifiDeviceDataGetStatusS25FL032P) { +#if NEED_spifiDeviceDataGetStatusS25FL032P + return spifiDeviceDataGetStatusS25FL032P; +#endif + } + else if (pHandle->pInfoData->pDeviceData->getStatusFxId == FX_spifiDeviceDataGetStatusS25FL164K) { +#if NEED_spifiDeviceDataGetStatusS25FL164K + return spifiDeviceDataGetStatusS25FL164K; +#endif + } + else if (pHandle->pInfoData->pDeviceData->getStatusFxId == FX_spifiDeviceDataGetStatusMX25L3235E) { +#if NEED_spifiDeviceDataGetStatusMX25L3235E + return spifiDeviceDataGetStatusMX25L3235E; +#endif + } + else if (pHandle->pInfoData->pDeviceData->getStatusFxId == FX_spifiDeviceDataGetStatusW25Q80BV) { +#if NEED_spifiDeviceDataGetStatusW25Q80BV + return spifiDeviceDataGetStatusW25Q80BV; +#endif + } + return (devGetStatusFx) spifiDeviceFxError; +} + +/* Function for returning Fx* for setting status */ +static devSetStatusFx spifiDeviceAssignFxSetStatus(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device setStatus Fx* */ + if (pHandle->pInfoData->pDeviceData->setStatusFxId == FX_spifiDeviceDataSetStatusS25FL032P) { +#if NEED_spifiDeviceDataSetStatusS25FL032P + return spifiDeviceDataSetStatusS25FL032P; +#endif + } + else if (pHandle->pInfoData->pDeviceData->setStatusFxId == FX_spifiDeviceDataSetStatusS25FL164K) { +#if NEED_spifiDeviceDataSetStatusS25FL164K + return spifiDeviceDataSetStatusS25FL164K; +#endif + } + else if (pHandle->pInfoData->pDeviceData->setStatusFxId == FX_spifiDeviceDataSetStatusMX25L3235E) { +#if NEED_spifiDeviceDataSetStatusMX25L3235E + return spifiDeviceDataSetStatusMX25L3235E; +#endif + } + return (devSetStatusFx) spifiDeviceFxError; +} + +/* Function for returning Fx* for setting options */ +static devSetOptsFx spifiDeviceAssignFxSetOptions(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device setOptions Fx* */ + if (pHandle->pInfoData->pDeviceData->setOptionsFxId == FX_spifiDeviceDataSetOptsQuadModeBit9) { +#if NEED_spifiDeviceDataSetOptsQuadModeBit9 + return spifiDeviceDataSetOptsQuadModeBit9; +#endif + } + else if (pHandle->pInfoData->pDeviceData->setOptionsFxId == FX_spifiDeviceDataSetOptsQuadModeBit6) { +#if NEED_spifiDeviceDataSetOptsQuadModeBit6 + return spifiDeviceDataSetOptsQuadModeBit6; +#endif + } + return (devSetOptsFx) spifiDeviceFxError; +} + +/* Function for returning Fx* for getting spifi controller read cmd */ +static devGetReadCmdFx spifiDeviceAssignFxReadCmd(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device getReadCmd Fx* */ + if (pHandle->pInfoData->pDeviceData->getReadCmdFxId == FX_spifiDeviceInitReadCommand) { +#if NEED_spifiDeviceInitReadCommand + return spifiDeviceInitReadCommand; +#endif + } + else if (pHandle->pInfoData->pDeviceData->getReadCmdFxId == FX_spifiDevice4BInitReadCommand) { +#if NEED_spifiDevice4BInitReadCommand + return spifiDevice4BInitReadCommand; +#endif + } + return (devGetReadCmdFx) spifiDeviceFxError; +} + +/* Function for returning Fx* for getting spifi controller write cmd */ +static devGetWriteCmdFx spifiDeviceAssignFxWriteCmd(SPIFI_HANDLE_T *pHandle) +{ + /* Initialize the device getWriteCmd Fx* */ + if (pHandle->pInfoData->pDeviceData->getWriteCmdFxId == FX_spifiDeviceInitWriteCommand) { +#if NEED_spifiDeviceInitWriteCommand + return spifiDeviceInitWriteCommand; +#endif + } + else if (pHandle->pInfoData->pDeviceData->getWriteCmdFxId == FX_spifiDevice4BInitWriteCommand) { + #if NEED_spifiDevice4BInitWriteCommand + return spifiDevice4BInitWriteCommand; + #endif + } + else if (pHandle->pInfoData->pDeviceData->getWriteCmdFxId == FX_spifiDeviceInitWriteCommandMacronix) { +#if NEED_spifiDeviceInitWriteCommandMacronix + return spifiDeviceInitWriteCommandMacronix; +#endif + } + return (devGetWriteCmdFx) spifiDeviceFxError; +} + +/***************************************************************************** + * Semi-Private family functions + * Functions may be assigned to SPIFI_FAM_FX_T function pointers. + ****************************************************************************/ +/* Converts a device status to an OR'ed API status */ +static uint32_t spifiFamFxGetDeviceStatus(const SPIFI_HANDLE_T *pHandle, uint8_t clearStatus) +{ + uint32_t devStat; + uint32_t status = 0; + + /* Read device status word */ + devStat = pHandle->pFamFx->devGetStatus(pHandle); + + /* Convert to standard status values */ + if ((devStat & (STATUS_P_ERR | STATUS_W_ERR)) != 0) { + if ((devStat & STATUS_P_ERR) != 0) { + status |= SPIFI_STAT_PROGERR; + } + if ((devStat & STATUS_W_ERR) != 0) { + status |= SPIFI_STAT_ERASEERR; + } + + /* Only clear status if necessary */ + if (clearStatus) { + pHandle->pFamFx->devClearStatus(pHandle); + } + } + if ((devStat & STATUS_BPMASK) != 0) { + if ((devStat & STATUS_BPMASK) == STATUS_BPMASK) { + status |= SPIFI_STAT_FULLLOCK; + } + else { + status |= SPIFI_STAT_PARTLOCK; + } + } + if ((devStat & STATUS_WIP) != 0) { + status |= SPIFI_STAT_BUSY; + } + + return status; +} + +/* lock/ unlock commands */ +static SPIFI_ERR_T spifiFamFxLockDeviceCmd(const SPIFI_HANDLE_T *pHandle, SPIFI_PCMD_LOCK_UNLOCK_T cmd, uint32_t data) +{ + SPIFI_ERR_T status = SPIFI_ERR_NOTSUPPORTED; + + if ((cmd == SPIFI_PCMD_UNLOCK_DEVICE) || (cmd == SPIFI_PCMD_LOCK_DEVICE)) { + uint32_t stat; + + /* Get current status */ + stat = pHandle->pFamFx->devGetStatus(pHandle); + + if (cmd == SPIFI_PCMD_UNLOCK_DEVICE) { + /* Clear lock bits only if they are locked */ + if ((stat & STATUS_BPMASK) != 0) { + stat &= ~STATUS_BPMASK; + /* Write updated value back to status register */ + pHandle->pFamFx->devSetStatus(pHandle, stat); + } + } + else { + /* Clear lock bits only if they are locked */ + if ((stat & STATUS_BPMASK) != STATUS_BPMASK) { + stat |= STATUS_BPMASK; + /* Write updated value back to status register */ + pHandle->pFamFx->devSetStatus(pHandle, stat); + } + } + status = SPIFI_ERR_NONE; + } + + return status; +} + +/* Bulk Erase*/ +static SPIFI_ERR_T spifiFamFxEraseAll(const SPIFI_HANDLE_T *pHandle) +{ + SPIFI_ERR_T status; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + status = spifiPrvCheckWriteState(pHandle); + if (status == SPIFI_ERR_NONE) { + spifiPrvSetWREN(pSpifiCtrlAddr); + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_C7_BE) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP))); + + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* Device wait for device to become ready */ + spifiPrvWaitUnBusy(pHandle); + } + + return status; +} + +/* Erase a block by block number */ +static SPIFI_ERR_T spifiFamFxEraseBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum) +{ + uint16_t stat; + uint32_t addr; + SPIFI_ERR_T status = SPIFI_ERR_RANGE; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + if (blockNum < pHandle->pInfoData->numBlocks) { + status = spifiPrvCheckWriteState(pHandle); + if (status == SPIFI_ERR_NONE) { + addr = blockNum * pHandle->pInfoData->blockSize; + /* Only clear status if necessary */ + pHandle->pFamFx->devClearStatus(pHandle); + + spifiPrvSetWREN(pSpifiCtrlAddr); + + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + if (pHandle->pInfoData->pDeviceData->caps & SPIFI_CAP_4BYTE_ADDR) { + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_DC_SE) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_4ADDRESS))); + } + else { /* Setup for a 3 Byte address erase */ + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_D8_SE) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS))); + } + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* If blocking is disabled, exit now */ + if ((pHandle->pInfoData->opts & SPIFI_OPT_NOBLOCK) == 0) { + /* Device wait for device to become ready */ + spifiPrvWaitUnBusy(pHandle); + + /* Read status and check error bits */ + stat = spifiFamFxGetDeviceStatus(pHandle, 0); + if ((stat & SPIFI_STAT_ERASEERR) != 0) { + status = SPIFI_ERR_ERASEERR; + } + } + } + } + + return status; +} + +/* Erase a block by sub-block number */ +static SPIFI_ERR_T spifiFamFxEraseSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t subBlockNum) +{ + uint16_t stat; + uint32_t addr; + SPIFI_ERR_T status = SPIFI_ERR_RANGE; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + + if (subBlockNum < pHandle->pInfoData->numSubBlocks) { + status = spifiPrvCheckWriteState(pHandle); + if (status == SPIFI_ERR_NONE) { + addr = subBlockNum * pHandle->pInfoData->subBlockSize; + /* Only clear status if necessary */ + pHandle->pFamFx->devClearStatus(pHandle); + + spifiPrvSetWREN(pSpifiCtrlAddr); + + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + + spifi_HW_SetCmd(pSpifiCtrlAddr, + (SPIFI_CMD_OPCODE(CMD_20_P4E) | + SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) | + SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS))); + + spifi_HW_WaitCMD(pSpifiCtrlAddr); + + /* If blocking is disabled, exit now */ + if ((pHandle->pInfoData->opts & SPIFI_OPT_NOBLOCK) == 0) { + /* Device wait for device to become ready */ + spifiPrvWaitUnBusy(pHandle); + + /* Read status and check error bits */ + stat = spifiFamFxGetDeviceStatus(pHandle, 0); + if ((stat & SPIFI_STAT_ERASEERR) != 0) { + status = SPIFI_ERR_ERASEERR; + } + } + } + } + + return status; +} + +/* Program a region */ +static SPIFI_ERR_T spifiFamFxPageProgram(const SPIFI_HANDLE_T *pHandle, + uint32_t addr, + const uint32_t *writeBuff, + uint32_t bytes) +{ + uint16_t stat; + uint8_t *writeBuff8; + SPIFI_ERR_T status = SPIFI_ERR_PAGESIZE; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + uint32_t cmdOnlyValue; + uint32_t dwords; + + if (bytes <= pHandle->pInfoData->pageSize) { + status = spifiPrvCheckWriteState(pHandle); + if (status == SPIFI_ERR_NONE) { + /* Get the program cmd value for this device */ + pHandle->pFamFx->devGetWriteCmd(pHandle, &cmdOnlyValue); + + /* Get the number of dwords to write */ + dwords = bytes >> 2; + + /* process by bytes if amount isn't even number of dwords */ + if (bytes & 0x3) { + + writeBuff8 = (uint8_t *) writeBuff; + + /* Only clear status if the device requires it and set write enable*/ + pHandle->pFamFx->devClearStatus(pHandle); + spifiPrvSetWREN(pSpifiCtrlAddr); + + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + spifi_HW_SetCmd(pSpifiCtrlAddr, cmdOnlyValue | SPIFI_CMD_DATALEN(bytes)); + /* Write data */ + while (bytes) { + spifi_HW_SetData8(pSpifiCtrlAddr, *writeBuff8); + ++writeBuff8; + --bytes; + } + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + else if (dwords) { + uint32_t cmdValue = cmdOnlyValue | SPIFI_CMD_DATALEN(dwords << 2); + + /* Only clear status if the device requires it and set write enable */ + pHandle->pFamFx->devClearStatus(pHandle); + spifiPrvSetWREN(pSpifiCtrlAddr); + + /* Set address and increment for any remaining */ + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + + /* Finally send command and write the data */ + spifi_HW_SetCmd(pSpifiCtrlAddr, cmdValue); + while (dwords) { + spifi_HW_SetData32(pSpifiCtrlAddr, *writeBuff); + ++writeBuff; + --dwords; + } + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + } + + /* If block is disabled, exit now */ + if ((pHandle->pInfoData->opts & SPIFI_OPT_NOBLOCK) == 0) { + /* Device wait for device to become ready */ + spifiPrvWaitUnBusy(pHandle); + + /* Read status and check error bits */ + stat = spifiFamFxGetDeviceStatus(pHandle, 0); + if ((stat & SPIFI_STAT_PROGERR) != 0) { + status = SPIFI_ERR_PROGERR; + } + } + } + + return status; +} + +/* Read a region */ +static SPIFI_ERR_T spifiFamFxReadDevice(const SPIFI_HANDLE_T *pHandle, + uint32_t addr, + uint32_t *readBuff, + uint32_t bytes) +{ + uint8_t *readBuff8 = (uint8_t *) readBuff; + SPIFI_ERR_T status = SPIFI_ERR_RANGE; + LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr; + uint32_t cmdOnlyValue; + uint32_t cmdValue; + uint32_t dwords; + + /* Limit read to controller data limit in bytes */ + if (bytes <= pHandle->pInfoData->maxReadSize) { + /* Get the number of dwords to read */ + dwords = bytes >> 2; + bytes -= (dwords << 2); + + /* Get the command value to program the SPIFI controller */ + pHandle->pFamFx->devGetReadCmd(pHandle, 0, &cmdOnlyValue, NULL); + if (dwords) { + cmdValue = cmdOnlyValue | SPIFI_CMD_DATALEN(dwords << 2); + + /* Specify the intermediate data byte (turn off). */ + spifi_HW_SetIDATA(pSpifiCtrlAddr, 0xFF); + + /* Set the address and increment for any remaining bytes */ + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + addr += (dwords << 2); + + spifi_HW_SetCmd(pSpifiCtrlAddr, cmdValue); + while (dwords) { + *readBuff = spifi_HW_GetData32(pSpifiCtrlAddr); + ++readBuff; + --dwords; + } + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + + if (bytes) { + readBuff8 = (uint8_t *) readBuff; + cmdValue = cmdOnlyValue | SPIFI_CMD_DATALEN(bytes); + + /* Specify the intermediate data byte (turn off). */ + spifi_HW_SetIDATA(pSpifiCtrlAddr, 0xFF); + + spifi_HW_SetAddr(pSpifiCtrlAddr, addr); + spifi_HW_SetCmd(pSpifiCtrlAddr, cmdValue); + + /* Read data */ + while (bytes) { + *readBuff8 = spifi_HW_GetData8(pSpifiCtrlAddr); + ++readBuff8; + --bytes; + } + spifi_HW_WaitCMD(pSpifiCtrlAddr); + } + status = SPIFI_ERR_NONE; + } + + return status; +} + +/* Enable or disable software write protect state */ +static SPIFI_ERR_T spifiFamFxResetDevice(const SPIFI_HANDLE_T *pHandle) +{ + return SPIFI_ERR_NOTSUPPORTED; +} + +/* Setup a device */ +static SPIFI_ERR_T spifiFamFxDeviceSetup(SPIFI_HANDLE_T *pHandle, uint32_t spifiCtrlAddr, uint32_t baseAddr) +{ + /* Common Command Set family function table */ + static SPIFI_FAM_FX_T fxTable; + + fxTable.lockCmd = spifiFamFxLockDeviceCmd; + fxTable.eraseAll = spifiFamFxEraseAll; + fxTable.eraseBlock = spifiFamFxEraseBlock; + fxTable.eraseSubBlock = spifiFamFxEraseSubBlock; + fxTable.pageProgram = spifiFamFxPageProgram; + fxTable.read = spifiFamFxReadDevice; + fxTable.reset = spifiFamFxResetDevice; + fxTable.getStatus = spifiFamFxGetDeviceStatus; + fxTable.subBlockCmd = NULL; /* Use generic handler in spifilib_dev_common.c */ + + /* Initialize the device specific function pointers */ + fxTable.devInitDeInit = spifiDeviceAssignFxInitDeInit(pHandle); + fxTable.devClearStatus = spifiDeviceAssignFxClearStatus(pHandle); + fxTable.devGetStatus = spifiDeviceAssignFxGetStatus(pHandle); + fxTable.devSetStatus = spifiDeviceAssignFxSetStatus(pHandle); + fxTable.devSetOpts = spifiDeviceAssignFxSetOptions(pHandle); + fxTable.devGetReadCmd = spifiDeviceAssignFxReadCmd(pHandle); + fxTable.devGetWriteCmd = spifiDeviceAssignFxWriteCmd(pHandle); + + /* save pointer to family function table */ + pHandle->pFamFx = &fxTable; + + return SPIFI_ERR_NONE; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ +SPIFI_FAM_NODE_T *spifi_REG_FAMILY_CommonCommandSet(void) +{ + /* Variables declared static so they will persist after function returns. */ + /* All members are assigned at run-time so that position independent code + will know the address */ + static SPIFI_DEV_NODE_T devListBase = {0}; /* List base to hold devices */ + static SPIFI_FAM_NODE_T devFamily; /* Family node to hold family descriptor */ + static SPIFI_FAM_DESC_T famDesc; /* Family descriptor (holds all info about family) */ + static uint32_t devCount = 0; /* Variable to keep track of # registered devices */ + + /* Protect against multiple calls to register the same family */ + if (devCount) { + return NULL; + } + + /* Make sure that the base list is empty and the count reflects 0 */ + devListBase.pNext = NULL; + devCount = 0; + + /* Store the device specific info so it can be returned */ + famDesc.pFamName = "Common SPIFI Command Set"; + + /* Save the pointer to the device list and count */ + famDesc.pDevList = &devListBase; + famDesc.pDevCount = &devCount; + + famDesc.prvContextSize = 0; /* Reserve space for private data (this family doesn't need any)*/ + famDesc.pPrvDevGetID = NULL; /* Use the generic readID routine */ + famDesc.pPrvDevSetup = spifiFamFxDeviceSetup; /* Provide Fx to handle setup */ + + /* Save the descriptor in the handle */ + devFamily.pDesc = &famDesc; + + /* Begin Winbond devices */ + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_W25Q80BV + /* Add support for W25Q80BV */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "W25Q80BV", + {{0xEF, 0x40, 0x14}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | + SPIFI_CAP_NOBLOCK | SPIFI_CAP_SUBBLKERASE), + 16, /* # of blocks */ + 0x10000, /* block size */ + 256, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 0x100, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 104, /* max clock rate in Mhz */ + 104, /* max read clock rate in MHz */ + 104, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) Does not have persistent status */ + FX_spifiDeviceDataGetStatusW25Q80BV, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus (uses S25FL032P variant) */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_W25Q64FV + /* Add support for W25Q64FV */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "W25Q64FV", + {{0xEF, 0x40, 0x17}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | + SPIFI_CAP_NOBLOCK | SPIFI_CAP_SUBBLKERASE), + 128, /* # of blocks */ + 0x10000, /* block size */ + 2048, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 0x100, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 104, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 104, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) Does not have persistent status */ + FX_spifiDeviceDataGetStatusW25Q80BV, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus (uses S25FL032P variant) */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_W25Q32FV + /* Add support for W25Q32FV */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "W25Q32FV", + {{0xEF, 0x40, 0x16}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | + SPIFI_CAP_NOBLOCK | SPIFI_CAP_SUBBLKERASE), + 64, /* # of blocks */ + 0x10000, /* block size */ + 1024, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 0x100, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 104, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 104, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) Does not have persistent status */ + FX_spifiDeviceDataGetStatusW25Q80BV, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus (uses S25FL032P variant) */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + /* Begin Spansion devices */ + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL512S + /* Add support for S25FL512S 256K Sector */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL512S", + {{0x01, 0x02, 0x20}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_4BYTE_ADDR | SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), + 256, /* # of blocks */ + 0x40000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size */ + 512, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDevice4BInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDevice4BInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL256S_256K + /* Add support for S25FL256S 256K Sector */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL256S 256kSec", + {{0x01, 0x02, 0x19}, 2, {0x4D, 0x0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_4BYTE_ADDR | SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), + 128, /* # of blocks */ + 0x40000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDevice4BInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDevice4BInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL256S_64K + /* Add support for S25FL256S 64k sector */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL256S 64kSec", + {{0x01, 0x02, 0x19}, 2, {0x4D, 0x01}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_4BYTE_ADDR | SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), + 512, /* # of blocks */ + 0x10000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size 0x1000 */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDevice4BInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDevice4BInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL164K + /* Add support for S25FL164K */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL164K", + {{0x01, 0x40, 0x17}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK | SPIFI_CAP_SUBBLKERASE), /* does NOT support Quad Write */ + 128, /* # of blocks */ + 0x10000, /* block size */ + 2048, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 50, /* max clock rate in MHz */ + 97, /* max read clock rate in MHz */ + 97, /* max high speed read clock rate in MHz */ + 97, /* max program clock rate in MHz */ + 97, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinitS25FL164K, /* (Fx Id) device init / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) No persistent status */ + FX_spifiDeviceDataGetStatusS25FL164K, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL164K, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL129P_256K + /* Add support for S25FL129P 256K Sector. Clone: S25FL128S */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL129P 256kSec", + {{0x01, 0x20, 0x18}, 2, {0x4D, 0x0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), + 64, /* # of blocks */ + 0x40000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL129P_64K + /* Add support for S25FL129P 64k sector */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL129P 64kSec", + {{0x01, 0x20, 0x18}, 2, {0x4D, 0x01}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), + 256, /* # of blocks */ + 0x10000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size 0x1000 */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL064P + /* Add support for S25FL064P */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL064P", + {{0x01, 0x02, 0x16}, 1, {0x4d}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), /* Capabilities */ + 128, /* # of blocks */ + 0x10000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size 0x1000 */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL032P + /* Add support for S25FL032P */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL032P", + {{0x01, 0x02, 0x15}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | SPIFI_CAP_NOBLOCK), /* Capabilities */ + 64, /* # of blocks */ + 0x10000, /* block size */ + 0, /* # of sub-blocks (Does NOT support full sub-block erase) */ + 0, /* sub-block size 0x1000 */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusS25FL032P, /* (Fx Id) has persistent bits in status register */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* Fx* to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_S25FL016K + /* Add support for S25FL016K */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "S25FL016K", + {{0xef, 0x40, 0x15}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_FULLLOCK | + SPIFI_CAP_NOBLOCK | SPIFI_CAP_SUBBLKERASE), /* Capabilities */ + 32, /* # of blocks */ + 0x10000, /* block size */ + 512, /* # of sub-blocks (Does NOT support full sub-block erase)*/ + 0x1000, /* sub-block size 0x1000 */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 80, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 80, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) Does not have persistent status */ + FX_spifiDeviceDataGetStatusS25FL032P, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusS25FL032P, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit9, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommand /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + /* Begin Maxronix devices */ + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_MX25L8035E + /* Add support for MX25L8035E */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "MX25L8035E", + {{0xC2, 0x20, 0x14}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_NOBLOCK | + SPIFI_CAP_SUBBLKERASE), /* capabilities */ + 16, /* # of blocks */ + 0x10000, /* block size */ + 256, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 108, /* max read clock rate in MHz */ + 108, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) no persistent status */ + FX_spifiDeviceDataGetStatusMX25L3235E, /* (Fx Id) getStatus */ + FX_spifiDeviceDataSetStatusMX25L3235E, /* (Fx Id) setStatus */ + FX_spifiDeviceDataSetOptsQuadModeBit6, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommandMacronix /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_MX25L6435E + /* Add support for MX25L6435E */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "MX25L6435E", + {{0xC2, 0x20, 0x17}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_NOBLOCK | + SPIFI_CAP_SUBBLKERASE), /* capabilities */ + 128, /* # of blocks */ + 0x10000, /* block size */ + 2048, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 86, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) no persistent status */ + FX_spifiDeviceDataGetStatusMX25L3235E, /* (Fx Id) getStatus function */ + FX_spifiDeviceDataSetStatusMX25L3235E, /* (Fx Id) setStatus function */ + FX_spifiDeviceDataSetOptsQuadModeBit6, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommandMacronix /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_MX25L3235E + /* Add support for MX25L3235E */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "MX25L3235E", + {{0xC2, 0x20, 0x16}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_NOBLOCK | + SPIFI_CAP_SUBBLKERASE), /* capabilities */ + 64, /* # of blocks */ + 0x10000, /* block size */ + 1024, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 86, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) no persistent status */ + FX_spifiDeviceDataGetStatusMX25L3235E, /* (Fx Id) getStatus function */ + FX_spifiDeviceDataSetStatusMX25L3235E, /* (Fx Id) setStatus function */ + FX_spifiDeviceDataSetOptsQuadModeBit6, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommandMacronix /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + #if SPIFI_DEVICE_ALL || SPIFI_DEVICE_MX25L1635E + /* Add support for MX25L1635E */ + { + static const SPIFI_DEVICE_DATA_T pData = { + "MX25L1635E", + {{0xC2, 0x25, 0x15}, 0, {0}}, /* JEDEC ID, extCount, ext data */ + (SPIFI_CAP_DUAL_READ | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE | SPIFI_CAP_NOBLOCK | + SPIFI_CAP_SUBBLKERASE), /* capabilities */ + 32, /* # of blocks */ + 0x10000, /* block size */ + 512, /* # of sub-blocks */ + 0x1000, /* sub-block size */ + 256, /* page size */ + MAX_SINGLE_READ, /* max single read bytes */ + 80, /* max clock rate in MHz */ + 104, /* max read clock rate in MHz */ + 86, /* max high speed read clock rate in MHz */ + 104, /* max program clock rate in MHz */ + 104, /* max high speed program clock rate in MHz */ + FX_spifiDeviceDataInitDeinit, /* (Fx Id) use generic deviceInit / deInit */ + FX_spifiDeviceDataClearStatusNone, /* (Fx Id) no persistent status */ + FX_spifiDeviceDataGetStatusMX25L3235E, /* (Fx Id) getStatus function */ + FX_spifiDeviceDataSetStatusMX25L3235E, /* (Fx Id) setStatus function */ + FX_spifiDeviceDataSetOptsQuadModeBit6, /* (Fx Id) to set/clr options */ + FX_spifiDeviceInitReadCommand, /* (Fx Id) to get memoryMode Cmd */ + FX_spifiDeviceInitWriteCommandMacronix /* (Fx Id) to get program Cmd */ + }; + static SPIFI_DEV_NODE_T data; /* Create persistent node */ + + data.pDevData = &pData; /* save the data in the node */ + spifiDevRegister(&devFamily, &data); /* Register the new device */ + } + #endif + + /* finally return the family device structure */ + return &devFamily; +} diff --git a/arch/arm/src/moxart/Kconfig b/arch/arm/src/moxart/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d7487ee8a02d62d685ff973f928c2c8d46e196cb --- /dev/null +++ b/arch/arm/src/moxart/Kconfig @@ -0,0 +1,18 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "MoxART Configuration Options" + +config UART_MOXA_MODE_REG + hex "16550 UART mode register address" + default 0x982000E0 + +config UART_MOXA_IRQ_STATUS_REG + hex "16550 UART shared IRQ status register address" + default 0x982000C0 + +config UART_MOXA_SHARED_IRQ + int "16550 UART shared IRQ number" + default 31 diff --git a/arch/arm/src/moxart/Make.defs b/arch/arm/src/moxart/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..48b9a21fa08d4588b5c052d5ab0b06e25e94d7f8 --- /dev/null +++ b/arch/arm/src/moxart/Make.defs @@ -0,0 +1,60 @@ +############################################################################ +# arch/arm/src/moxart/Make.defs +# +# Copyright (C) 2007, 2013-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Copyright (C) 2011 Stefan Richter. All rights reserved. +# Author: Stefan Richter +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = moxart_head.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S +CMN_ASRCS += up_nommuhead.S vfork.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c +CMN_CSRCS += up_exit.c up_initialstate.c up_initialize.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_syscall.c up_unblocktask.c +CMN_CSRCS += up_undefinedinsn.c up_usestack.c up_vfork.c up_etherstub.c + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +CHIP_ASRCS = moxart_lowputc.S + +CHIP_CSRCS = moxart_16550.c moxart_irq.c moxart_timer.c moxart_idle.c +CHIP_CSRCS += moxart_systemreset.c diff --git a/arch/arm/src/moxart/chip.h b/arch/arm/src/moxart/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..e1e57ea5e0ccbb4da1db36fc3958ecc01c5a3be9 --- /dev/null +++ b/arch/arm/src/moxart/chip.h @@ -0,0 +1,145 @@ +/************************************************************************************ + * arch/arm/src/moxart/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_MOXART_CHIP_H +#define __ARCH_ARM_SRC_MOXART_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#define UART0_BASE 0x98200000 + +#define UART_THR 0x00 +#define UART_LSR 0x14 +#define UART_LSR_THRE 0x20 + +/* Common UART Registers. Expressed as offsets from the BASE address */ + +#define UART_RHR_OFFS 0x00000000 /* Rcv Holding Register */ +#define UART_THR_OFFS 0x00000000 /* Xmit Holding Register */ +#define UART_FCR_OFFS 0x00000002 /* FIFO Control Register */ +#define UART_RFCR_OFFS 0x00000002 /* Rcv FIFO Control Register */ +#define UART_TFCR_OFFS 0x00000002 /* Xmit FIFO Control Register */ +#define UART_SCR_OFFS 0x00000010 /* Status Control Register */ +#define UART_LCR_OFFS 0x00000003 /* Line Control Register */ +#define UART_LSR_OFFS 0x00000005 /* Line Status Register */ +#define UART_SSR_OFFS 0x00000011 /* Supplementary Status Register */ +#define UART_MCR_OFFS 0x00000004 /* Modem Control Register */ +#define UART_MSR_OFFS 0x00000006 /* Modem Status Register */ +#define UART_IER_OFFS 0x00000001 /* Interrupt Enable Register */ +#define UART_ISR_OFFS 0x00000002 /* Interrupt Status Register */ +#define UART_EFR_OFFS 0x00000002 /* Enhanced Feature Register */ +#define UART_XON1_OFFS 0x00000004 /* XON1 Character Register */ +#define UART_XON2_OFFS 0x00000005 /* XON2 Character Register */ +#define UART_XOFF1_OFFS 0x00000006 /* XOFF1 Character Register */ +#define UART_XOFF2_OFFS 0x00000007 /* XOFF2 Character Register */ +#define UART_SPR_OFFS 0x00000007 /* Scratch-pad Register */ +#define UART_DIV_LOW_OFFS 0x00000000 /* Divisor for baud generation */ +#define UART_DIV_HIGH_OFFS 0x00000001 +#define UART_TCR_OFFS 0x00000006 /* Transmission Control Register */ +#define UART_TLR_OFFS 0x00000007 /* Trigger Level Register */ +#define UART_MDR_OFFS 0x00000008 /* Mode Definition Register */ + +/* UART Settings ************************************************************/ + +/* Miscellaneous UART settings. */ + +#define IRQ_UART 1 +#define UART_REGISTER_BITS 8 +#define UART_IRQ IRQ_UART + +#define UART_RX_FIFO_NOEMPTY 0x00000001 +#define UART_SSR_TXFULL 0x00000001 +#define UART_LSR_TREF 0x00000020 + +#define UART_XMIT_FIFO_SIZE 64 +#define UART_IRDA_XMIT_FIFO_SIZE 64 + +/* UART_LCR Register */ + /* Bits 31-7: Reserved */ +#define UART_LCR_BOC 0x00000040 /* Bit 6: Break Control */ + /* Bit 5: Parity Type 2 */ +#define UART_LCR_PAREVEN 0x00000010 /* Bit 4: Parity Type 1 */ +#define UART_LCR_PARODD 0x00000000 +#define UART_LCR_PARMARK 0x00000010 +#define UART_LCR_PARSPACE 0x00000011 +#define UART_LCR_PAREN 0x00000008 /* Bit 3: Paity Enable */ +#define UART_LCR_PARDIS 0x00000000 +#define UART_LCR_2STOP 0x00000004 /* Bit 2: Number of stop bits */ +#define UART_LCR_1STOP 0x00000000 +#define UART_LCR_5BITS 0x00000000 /* Bits 0-1: Word-length */ +#define UART_LCR_6BITS 0x00000001 +#define UART_LCR_7BITS 0x00000002 +#define UART_LCR_8BITS 0x00000003 + +#define UART_FCR_FTL 0x000000f0 +#define UART_FCR_FIFO_EN 0x00000001 +#define UART_FCR_TX_CLR 0x00000002 +#define UART_FCR_RX_CLR 0x00000004 + +#define UART_IER_RECVINT 0x00000001 +#define UART_IER_XMITINT 0x00000002 +#define UART_IER_LINESTSINT 0x00000004 +#define UART_IER_MODEMSTSINT 0x00000008 /* IrDA UART only */ +#define UART_IER_XOFFINT 0x00000020 +#define UART_IER_RTSINT 0x00000040 /* IrDA UART only */ +#define UART_IER_CTSINT 0x00000080 /* IrDA UART only */ +#define UART_IER_INTMASK 0x000000ff + +#define BAUD_115200 0x00000007 +#define BAUD_57600 0x00000014 +#define BAUD_38400 0x00000021 +#define BAUD_19200 0x00000006 +#define BAUD_9600 0x0000000C +#define BAUD_4800 0x00000018 +#define BAUD_2400 0x00000030 +#define BAUD_1200 0x00000060 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_MOXART_CHIP_H */ diff --git a/arch/arm/src/moxart/moxart_16550.c b/arch/arm/src/moxart/moxart_16550.c new file mode 100644 index 0000000000000000000000000000000000000000..2754eab0cabe95d252fde2484689d6fcf1fed139 --- /dev/null +++ b/arch/arm/src/moxart/moxart_16550.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/arm/src/moxart/moxart_irq.c + * Driver for MoxaRT IRQ controller + * + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "arm.h" +#include "up_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uart_datawidth_t uart_getreg(uart_addrwidth_t base, unsigned int offset) +{ + return *((volatile uart_addrwidth_t *)base + offset); +} + +void uart_putreg(uart_addrwidth_t base, unsigned int offset, uart_datawidth_t value) +{ + *((volatile uart_addrwidth_t *)base + offset) = value; +} + +void uart_decodeirq(int irq, FAR void *context) +{ + int i; + uint32_t status; + static int os = 0; + + status = *((volatile uart_addrwidth_t *)CONFIG_UART_MOXA_IRQ_STATUS_REG); + + if ((status & 0x3f) == 0x3f) + { + return; + } + + i = 0; + do + { + if (!(status & 0x1)) + { + irq_dispatch(VIRQ_START + i, context); + } + + status >>= 1; + } + while (++i <= 4); +} + +#ifdef CONFIG_SERIAL_UART_ARCH_IOCTL +int uart_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct u16550_s *priv = (struct u16550_s *)dev->priv; + int ret = -ENOTTY; + uint32_t vmode; + unsigned int opmode; + int bitm_off; + + /* TODO: calculate bit offset from UART_BASE address. + * E.g.: + * 0x9820_0000 -> 0 + * 0x9820_0020 -> 1 + * 0x9820_0040 -> 2 + */ + + /* HARD: coded value for UART1 */ + bitm_off = 1; + + switch (cmd) + { + case MOXA_SET_OP_MODE: + { + irqstate_t flags; + opmode = *(unsigned long *)arg; + + /* Check for input data */ + + if (opmode & ~OP_MODE_MASK) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + + /* Update mode register with requested mode */ + + vmode = getreg32(CONFIG_UART_MOXA_MODE_REG); + putreg32(vmode & ~(OP_MODE_MASK << 2 * bitm_off), CONFIG_UART_MOXA_MODE_REG); + vmode = opmode << 2 * bitm_off; + putreg32(getreg32(CONFIG_UART_MOXA_MODE_REG) | vmode, CONFIG_UART_MOXA_MODE_REG); + + leave_critical_section(flags); + ret = OK; + break; + } + + case MOXA_GET_OP_MODE: + { + irqstate_t flags; + flags = enter_critical_section(); + + /* Read from mode register */ + + opmode = (getreg32(CONFIG_UART_MOXA_MODE_REG) >> 2 * bitm_off) & OP_MODE_MASK; + + leave_critical_section(flags); + *(unsigned long *)arg = opmode; + ret = OK; + break; + } + } + + return ret; +} +#endif diff --git a/arch/arm/src/moxart/moxart_head.S b/arch/arm/src/moxart/moxart_head.S new file mode 100644 index 0000000000000000000000000000000000000000..c67ac08566760cb0b8b3027d0ed68a9f6f4527dd --- /dev/null +++ b/arch/arm/src/moxart/moxart_head.S @@ -0,0 +1,60 @@ +/****************************************************************************** + * arch/arm/src/moxart/moxart_head.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Place a branch to the real head at the entry point */ + +.section .text.start + b __start + +/* Exception Vectors like they are needed for the exception vector + * indirection of the internal boot ROM. The following section must be + * linked to appear at 0x80001c + */ + +.section .text.exceptions +_undef_instr: + b up_vectorundefinsn +_sw_interr: + b up_vectorswi +_prefetch_abort: + b up_vectorprefetch +_data_abort: + b up_vectordata +_reserved: + b _reserved +_irq: + b up_vectorirq +_fiq: + b up_vectorfiq diff --git a/arch/arm/src/moxart/moxart_idle.c b/arch/arm/src/moxart/moxart_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..8659bac5010dc959b7c12ab40d9687c3faf1e9b3 --- /dev/null +++ b/arch/arm/src/moxart/moxart_idle.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/common/moxart_idle.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BEGIN_IDLE (*(volatile uint32_t *)0x98700000) &= ~0x10 +#define END_IDLE (*(volatile uint32_t *)0x98700000) |= 0x10 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + uint32_t i; + + /* Sleep until an interrupt occurs to save power */ + + BEGIN_IDLE; + for (i = 0; i < 0x40000; i++) + { + asm("nop"); + } + + END_IDLE; + for (i = 0; i < 0x40000; i++) + { + asm("nop"); + } +#endif +} diff --git a/arch/arm/src/moxart/moxart_irq.c b/arch/arm/src/moxart/moxart_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..8d2b07cc22011c5136622e354ed77009d09ff99a --- /dev/null +++ b/arch/arm/src/moxart/moxart_irq.c @@ -0,0 +1,325 @@ +/**************************************************************************** + * arch/arm/src/moxart/moxart_irq.c + * Driver for MoxaRT IRQ controller + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "arm.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IRQ_ADDR 0x98800000 +#define IRQ_REG(x) (IRQ_ADDR + x) + +#define IRQ__SRC 0x00 +#define IRQ__MASK 0x04 +#define IRQ__CLEAR 0x08 +#define IRQ__MODE 0x0C +#define IRQ__LEVEL 0x10 +#define IRQ__STATUS 0x14 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +extern void uart_decodeirq(int irq, uint32_t *regs); + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Setup the IRQ and FIQ controllers + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Prepare hardware */ + + *(volatile int *)0x98700000 |= 0x3f; + + /* PMU setup */ + + (*(volatile uint32_t *)0x98100008) &= ~0x9; + + while (!((*(volatile uint32_t *)0x98100008) & 0x2)) + ; + + (*(volatile uint32_t *)0x98100008) |= 0x4; + + (*(volatile uint32_t *)0x98800100) = 0xDFF8003F; + + /* Check board type */ + + /* Mask all interrupts off */ + + putreg32(0, IRQ_REG(IRQ__MASK)); + putreg32(0, IRQ_REG(IRQ__MASK+0x20)); + putreg32(0xffffffff, IRQ_REG(IRQ__CLEAR)); + putreg32(0xffffffff, IRQ_REG(IRQ__CLEAR+0x20)); + + /* Initial trigger mode and level */ + + putreg32(0, IRQ_REG(IRQ__MODE)); + putreg32(0, IRQ_REG(IRQ__LEVEL)); + putreg32(0, IRQ_REG(IRQ__MODE+0x20)); + putreg32(0, IRQ_REG(IRQ__LEVEL+0x20)); + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Setup UART shared interrupt */ + + irq_attach(CONFIG_UART_MOXA_SHARED_IRQ, uart_decodeirq); + up_enable_irq(CONFIG_UART_MOXA_SHARED_IRQ); + + /* And finally, enable interrupts */ + +#if 1 +#define REG(x) (*(volatile uint32_t *)(x)) + lldbg("\n=============================================================\n"); + lldbg("TM CNTL=%08x INTRS=%08x MASK=%08x LOAD=%08x COUNT=%08x M1=%08x\n", + REG(0x98400030), REG(0x98400034), REG(0x98400038), REG(0x98400004), + REG(0x98400000), REG(0x98400008)); + lldbg("IRQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", + REG(0x98800014), REG(0x98800004), REG(0x9880000C), REG(0x98800010)); + lldbg("FIQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", + REG(0x98800034), REG(0x98800024), REG(0x9880002C), REG(0x98800020)); + lldbg("=============================================================\n"); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +inline void ftintc010_mask_irq(int irq) +{ + /* 0: masked + * 1: unmasked + */ + + uint32_t mask; + + mask = getreg32(IRQ_REG(IRQ__MASK)); + mask &= ~(1 << irq); + putreg32(mask, IRQ_REG(IRQ__MASK)); +} + +inline void ftintc010_unmask_irq(int irq) +{ + /* 0: masked + * 1: unmasked + */ + + uint32_t mask; + + mask = getreg32(IRQ_REG(IRQ__MASK)); + mask |= 1 << irq; + putreg32(mask, IRQ_REG(IRQ__MASK)); +} + +inline void ftintc010_set_trig_mode(int irq, int mode) +{ + uint32_t irqmode; + + irqmode = getreg32(IRQ_REG(IRQ__MODE)); + + /* 0: level trigger + * 1: edge trigger + */ + + if (mode) + { + irqmode |= (1 << irq); + } + else + { + irqmode &= ~(1 << irq); + } + + putreg32(irqmode, IRQ_REG(IRQ__MODE)); +} + +inline void ftintc010_set_trig_level(int irq, int level) +{ + uint32_t irqlevel; + + irqlevel = getreg32(IRQ_REG(IRQ__LEVEL)); + + /* 0: active-high level trigger / rising edge trigger + * 1: active-low level trigger / falling edge trigger + */ + + if (level) + { + irqlevel |= (1 << irq); + } + else + { + irqlevel &= ~(1 << irq); + } + + putreg32(irqlevel, IRQ_REG(IRQ__LEVEL)); +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + ftintc010_mask_irq(irq); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + ftintc010_unmask_irq(irq); + } +} + +static int ffs(uint32_t word) +{ + int t, r; + + if (word == 0) + { + return 0; + } + + t = r = 1; + + while (!(word & t)) + { + t <<= 1; + r++; + } + + return r; +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + putreg32((1 << irq), IRQ_REG(IRQ__CLEAR)); +} + +/**************************************************************************** + * Entry point for interrupts + ****************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ + uint32_t num, status; + + /* Detect & deliver the IRQ */ + + status = getreg32(IRQ_REG(IRQ__STATUS)); + if (!status) + { + return; + } + + /* Ack IRQ */ + + num = ffs(status) - 1; + up_ack_irq(num); + + DEBUGASSERT(CURRENT_REGS == NULL); + CURRENT_REGS = regs; + + irq_dispatch(num, regs); + CURRENT_REGS = NULL; +} diff --git a/arch/arm/src/moxart/moxart_lowputc.S b/arch/arm/src/moxart/moxart_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..ea1f552f2a914d64b5830ce0b938d5ceae2c0c46 --- /dev/null +++ b/arch/arm/src/moxart/moxart_lowputc.S @@ -0,0 +1,124 @@ +/************************************************************************** + * moxart/moxart_lowputc.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + +/* This assembly language version has the advantage that it can does not + * require a C stack and uses only r0-r1. Hence it can be used during + * early boot phases. + */ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: + /* On entry, r0 holds the character to be printed */ + + ldr r2, =UART0_BASE /* r2=UART0 base */ + + /* Poll bit 0 of the UART_SSR register. When the bit + * is clear, the TX FIFO is no longer full + */ + +1: ldrb r1, [r2, #UART_LSR] + tst r1, #UART_LSR_THRE + beq 1b + + /* Send the character by writing it into the UART_THR + * register. + */ + + strb r0, [r2, #UART_THR] + + /* Wait for the tranmsit holding regiser (THR) to be + * emptied. This is detemined when bit 6 of the LSR + * is set. + */ + +2: ldrb r1, [r2, #UART_LSR] + tst r1, #UART_LSR_THRE + beq 2b + + /* If the character that we just sent was a linefeed, + * then send a carriage return as well. + */ + + teq r0, #'\n' + moveq r0, #'\r' + beq 1b + + /* And return */ + + mov pc, lr diff --git a/arch/arm/src/moxart/moxart_systemreset.c b/arch/arm/src/moxart/moxart_systemreset.c new file mode 100644 index 0000000000000000000000000000000000000000..6e3e6704721fb14a14cde22452c242720e331cff --- /dev/null +++ b/arch/arm/src/moxart/moxart_systemreset.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/moxart/moxart_systemreset.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FTWDT010_LOAD 0x98500004 +#define FTWDT010_RESTART 0x98500008 +#define FTWDT010_CR 0x9850000C + +/**************************************************************************** + * Public functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_systemreset + * + * Description: + * Internal, reset logic. + * + ****************************************************************************/ + +void up_systemreset(void) +{ + putreg32(0, FTWDT010_CR); + putreg32(0, FTWDT010_LOAD); + putreg32(0x5ab9, FTWDT010_RESTART); /* Magic */ + + putreg32(0x11, FTWDT010_CR); + putreg32(0x13, FTWDT010_CR); + + /* Wait for the reset */ + + for (; ; ); +} + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. This function may or may not be supported by a + * particular board architecture. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not used by + * a board, the value zero may be provided in calls to board_reset. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_RESET +int board_reset(int status) +{ + up_systemreset(); + return 0; +} +#endif diff --git a/arch/arm/src/moxart/moxart_timer.c b/arch/arm/src/moxart/moxart_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..e2c115bee8ac0f358fbf156034b7bfe9e3490bc3 --- /dev/null +++ b/arch/arm/src/moxart/moxart_timer.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/arm/src/moxart/moxart_timer.c + * MoxaRT internal Timer Driver + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Anton D. Kachalov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "arm.h" +#include "up_arch.h" + +/**************************************************************************** + * {re-processor Definitions + ****************************************************************************/ + +#define TM1_ADDR 0x98400000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum timer_reg +{ + COUNTER_TIMER = 0x00, + CNTL_TIMER = 0x30, + LOAD_TIMER = 0x04, + MATCH1_TIMER = 0x08, + MATCH2_TIMER = 0x0C, + INTR_STATE_TIMER = 0x34, + INTR_MASK_TIMER = 0x38, +}; + +enum timer_ctl +{ + TM1_ENABLE = (1 << 0), + TM1_CLOCK = (1 << 1), + TM1_OFENABLE = (1 << 5), + TM1_UPDOWN = (1 << 9), +}; + +enum timer_int +{ + TM1_MATCH1 = (1 << 0), + TM1_MATCH2 = (1 << 1), + TM1_OVERFLOW = (1 << 2), +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t cmp = BOARD_32KOSC_FREQUENCY / 100; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + uint32_t state; + + /* Process timer interrupt */ + + state = getreg32(TM1_ADDR + INTR_STATE_TIMER); + state &= ~0x7; + putreg32(state, TM1_ADDR + INTR_STATE_TIMER); + + /* Ready for the next interrupt */ + + putreg32(cmp, TM1_ADDR + COUNTER_TIMER); + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * Setup MoxaRT timer 0 to cause system ticks. + * + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t tmp; + +// up_disable_irq(IRQ_SYSTIMER); + putreg32(0, TM1_ADDR + CNTL_TIMER); + putreg32(0, TM1_ADDR + INTR_STATE_TIMER); + putreg32(0x1ff, TM1_ADDR + INTR_MASK_TIMER); + + /* Initialize to a known state */ + + putreg32(cmp, TM1_ADDR + COUNTER_TIMER); + putreg32(0, TM1_ADDR + LOAD_TIMER); + putreg32(0, TM1_ADDR + MATCH1_TIMER); + + /* Attach and enable the timer interrupt */ + + irq_attach(IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(IRQ_SYSTIMER); + ftintc010_set_trig_mode(IRQ_SYSTIMER, 1); + ftintc010_set_trig_level(IRQ_SYSTIMER, 0); + + /* Unmask IRQ */ + + tmp = getreg32(TM1_ADDR + INTR_MASK_TIMER); + tmp &= ~TM1_MATCH1; + putreg32(tmp, TM1_ADDR + INTR_MASK_TIMER); + + tmp = getreg32(TM1_ADDR + CNTL_TIMER); + tmp |= TM1_CLOCK | TM1_ENABLE; + putreg32(tmp, TM1_ADDR + CNTL_TIMER); +} diff --git a/arch/arm/src/nuc1xx/Kconfig b/arch/arm/src/nuc1xx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..50cddcbdee16727d7b252a163f9e2718b164b92c --- /dev/null +++ b/arch/arm/src/nuc1xx/Kconfig @@ -0,0 +1,403 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "NUC100/120 Configuration Options" + +choice + prompt "Nuvoton NUC1xx Chip Selection" + default ARCH_CHIP_NUC120LE3AN + depends on ARCH_CHIP_NUC1XX + +config ARCH_CHIP_NUC100LC1BN + bool "NUC100LC1BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 32K SRAM 4K, LQFP48 package + +config ARCH_CHIP_NUC100LD1BN + bool "NUC100LD1BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 64K SRAM 4K, LQFP48 package + +config ARCH_CHIP_NUC100LD2BN + bool "NUC100LD2BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 64K SRAM 8K, LQFP48 package + +config ARCH_CHIP_NUC100RC1BN + bool "NUC100RC1BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 32K SRAM 4K, LQFP64 package + +config ARCH_CHIP_NUC100RD1BN + bool "NUC100RD1BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 64K SRAM 4K, LQFP64 package + +config ARCH_CHIP_NUC100RD2BN + bool "NUC100RD2BN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC100 low density chip: Flash 64K SRAM 8K, LQFP64 package + +config ARCH_CHIP_NUC100LD3AN + bool "NUC100LD3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC100 medium density chip: Flash 64K SRAM 16K, LQFP48 package + +config ARCH_CHIP_NUC100LE3AN + bool "NUC100LE3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC100 medium density chip: Flash 128K SRAM 16K, LQFP48 package + +config ARCH_CHIP_NUC100RD3AN + bool "NUC100RD3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC100 medium density chip: Flash 64K SRAM 16K, LQFP64 package + +config ARCH_CHIP_NUC100RE3AN + bool "NUC100RE3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC100 medium density chip: Flash 128K SRAM 16K, LQFP64 package + +config ARCH_CHIP_NUC100VD2AN + bool "NUC100VD2AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC100 medium density chip: Flash 64K SRAM 8K, LQFP100 package + +config ARCH_CHIP_NUC100VD3AN + bool "NUC100VD3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC100 medium density chip: Flash 64K SRAM 16K, LQFP100 package + +config ARCH_CHIP_NUC100VE3AN + bool "NUC100VE3AN" + select ARCH_FAMILY_NUC100 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC100 medium density chip: Flash 128K SRAM 8K, LQFP100 package + +config ARCH_CHIP_NUC120LC1BN + bool "NUC120LC1BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 32K SRAM 4K, LQFP48 package + +config ARCH_CHIP_NUC120LD1BN + bool "NUC120LD1BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 64K SRAM 4K, LQFP48 package + +config ARCH_CHIP_NUC120LD2BN + bool "NUC120LD2BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 64K SRAM 8K, LQFP48 package + +config ARCH_CHIP_NUC120RC1BN + bool "NUC120RC1BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 32K SRAM 4K, LQFP64 package + +config ARCH_CHIP_NUC120RD1BN + bool "NUC120RD1BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 64K SRAM 4K, LQFP64 package + +config ARCH_CHIP_NUC120RD2BN + bool "NUC120RD2BN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_LOWDENSITY + ---help--- + Nuvoton NUC120 low density chip: Flash 64K SRAM 8K, LQFP64 package + +config ARCH_CHIP_NUC120LD3AN + bool "NUC120LD3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC120 medium density chip: Flash 64K SRAM 16K, LQFP48 package + +config ARCH_CHIP_NUC120LE3AN + bool "NUC120LE3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC120 medium density chip: Flash 128K SRAM 16K, LQFP48 package + +config ARCH_CHIP_NUC120RD3AN + bool "NUC120RD3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC120 medium density chip: Flash 64K SRAM 16K, LQFP64 package + +config ARCH_CHIP_NUC120RE3AN + bool "NUC120RE3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + ---help--- + Nuvoton NUC120 medium density chip: Flash 128K SRAM 16K, LQFP64 package + +config ARCH_CHIP_NUC120VD2AN + bool "NUC120VD2AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC120 medium density chip: Flash 64K SRAM 8K, LQFP100 package + +config ARCH_CHIP_NUC120VD3AN + bool "NUC120VD3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC120 medium density chip: Flash 64K SRAM 16K, LQFP100 package + +config ARCH_CHIP_NUC120VE3AN + bool "NUC120VE3AN" + select ARCH_FAMILY_NUC120 + select ARCH_NUC_MEDIUMDENSITY + select NUC_HAVE_UART2 + ---help--- + Nuvoton NUC120 medium density chip: Flash 128K SRAM 16K, LQFP100 package + +endchoice + +config ARCH_FAMILY_NUC100 + bool + +config ARCH_FAMILY_NUC120 + bool + +config ARCH_NUC_LOWDENSITY + bool + +config ARCH_NUC_MEDIUMDENSITY + bool + +config NUC_HAVE_UART2 + bool + +menu "NUC1XX Peripheral Support" + +config NUC_PDMA + bool "Peripheral DMA" + default n + +config NUC_FMC + bool "Flash memory" + default n + +config NUC_EBI + bool "External bus interface" + default n + +config NUC_WDT + bool "Watchdog timer" + default n + +config NUC_RTC + bool "Real time clock (RTC)" + default n + +config NUC_TMR0 + bool "Timer0" + default n + +config NUC_TMR1 + bool "Timer1" + default n + +config NUC_TIMR2 + bool "Timer2" + default n + +config NUC_TIMR3 + bool "Timer3" + default n + +config NUC_I2C0 + bool "I2C0 interface" + default n + +config NUC_I2C1 + bool "I2C1 interface" + default n + +config NUC_SPI0 + bool "SPI0 master/slave" + default n + +config NUC_SPI1 + bool "SPI1 master/slave" + default n + +config NUC_SPI2 + bool "SPI2 master/slave" + default n + +config NUC_SPI3 + bool "SPI3 master/slave" + default n + +config NUC_PWM0 + bool "PWM0" + default n + +config NUC_PWM1 + bool "PWM1" + default n + +config NUC_PWM2 + bool "PWM2" + default n + +config NUC_PWM3 + bool "PWM3" + default n + +config NUC_PWM4 + bool "PWM4" + default n + +config NUC_PWM5 + bool "PWM5" + default n + +config NUC_PWM6 + bool "PWM6" + default n + +config NUC_PWM7 + bool "PWM7" + default n + +config NUC_UART0 + bool "UART0" + default y + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config NUC_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config NUC_UART2 + bool "UART2" + default n + depends on NUC_HAVE_UART2 + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config NUC_USBD + bool "USB 2.0 FS device controller" + default n + depends on ARCH_FAMILY_NUC120 + +config NUC_ACMP + bool "Analog comparator" + default n + +config NUC_ADC + bool "Analog-digital-converter (ADC)" + default n + +config NUC_PS2 + bool "PS/2 interface" + default n + +config NUC_I2S + bool "I2S interface" + default n + +endmenu + +config NUC_XTALLO + bool + +config NUC_INTHI + bool + +choice + prompt "SysTick clock source" + default NUC_SYSTICK_CORECLK + +config NUC_SYSTICK_CORECLK + bool "Cortex-M0 core clock" + +config NUC_SYSTICK_XTALHI + bool "High speed XTAL clock" + +config NUC_SYSTICK_XTALLO + bool "Low speed XTAL clock" + select NUC_XTALLO + +config NUC_SYSTICK_XTALHId2 + bool "High speed XTAL clock/2" + +config NUC_SYSTICK_HCLKd2 + bool "HCLK/2" + +config NUC_SYSTICK_INTHId2 + bool "Internal high speed clock/2" + select NUC_INTHI + +endchoice + +choice + prompt "NUC UART clock source" + default NUC_UARTCLK_INTHI + depends on NUC_UART0 || NUC_UART1 || NUC_UART2 + +config NUC_UARTCLK_XTALHI + bool "External 4-24MHz high speed crystal" + +config NUC_UARTCLK_PLL + bool "PLL output" + +config NUC_UARTCLK_INTHI + bool "Internal 22.1184 high speed clock" + select NUC_INTHI + +endchoice diff --git a/arch/arm/src/nuc1xx/Make.defs b/arch/arm/src/nuc1xx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..3a9f06519125e649d5395e84056e24f1ec2bd0e6 --- /dev/null +++ b/arch/arm/src/nuc1xx/Make.defs @@ -0,0 +1,86 @@ +############################################################################ +# arch/arm/src/nuc1xx/Make.defs +# +# Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_ASRCS = up_exception.S up_saveusercontext.S up_fullcontextrestore.S +CMN_ASRCS += up_switchcontext.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vectors.c up_vfork.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CMN_CSRCS += up_dumpnvic.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = nuc_clockconfig.c nuc_gpio.c nuc_idle.c nuc_irq.c nuc_lowputc.c +CHIP_CSRCS += nuc_serial.c nuc_start.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += nuc_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += nuc_userspace.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += nuc_dumpgpio.c +endif diff --git a/arch/arm/src/nuc1xx/chip.h b/arch/arm/src/nuc1xx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..d47f4f5e28cdaed72932e33ff5254b983d3f2818 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* Define the number of interrupt vectors that need to be supported for this chip */ + +#define ARMV6M_PERIPHERAL_INTERRUPTS 32 + +/* Include the memory map file. Other chip hardware files should then include + * this file for the proper setup. + */ + +#include "chip/nuc_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_adc.h b/arch/arm/src/nuc1xx/chip/nuc_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..cea74a0fd6f9cdc588fe0e57e1b29b61b2c83eac --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_adc.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_adc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_ADC_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_ADC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_ADC_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_clk.h b/arch/arm/src/nuc1xx/chip/nuc_clk.h new file mode 100644 index 0000000000000000000000000000000000000000..69c54b9ce0d684cc49eb0ef7a127498217c79961 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_clk.h @@ -0,0 +1,288 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_clk.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CLK_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CLK_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Well-known clock frequencies *************************************************************/ + +#define NUC_INTHI_FREQUENCY 22118400 +#define NUC_INTLO_FREQUENCY 10000 + +/* Register offsets *************************************************************************/ + +#define NUC_CLK_PWRCON_OFFSET 0x0000 /* System power down control register */ +#define NUC_CLK_AHBCLK_OFFSET 0x0004 /* AHB devices clock enable control register */ +#define NUC_CLK_APBCLK_OFFSET 0x0008 /* APB devices clock enable control register */ +#define NUC_CLK_CLKSTATUS_OFFSET 0x000c /* Clock status monitor register */ +#define NUC_CLK_CLKSEL0_OFFSET 0x0010 /* Clock source select control register 0 */ +#define NUC_CLK_CLKSEL1_OFFSET 0x0014 /* Clock source select control register 1 */ +#define NUC_CLK_CLKSEL2_OFFSET 0x001c /* Clock source select control register 2 */ +#define NUC_CLK_CLKDIV_OFFSET 0x0018 /* Clock divider number register */ +#define NUC_CLK_PLLCON_OFFSET 0x0020 /* PLL control register */ +#define NUC_CLK_FRQDIV_OFFSET 0x0024 /* Frequency divider control register */ + +/* Register addresses ***********************************************************************/ + +#define NUC_CLK_PWRCON (NUC_CLK_BASE+NUC_CLK_PWRCON_OFFSET) +#define NUC_CLK_AHBCLK (NUC_CLK_BASE+NUC_CLK_AHBCLK_OFFSET) +#define NUC_CLK_APBCLK (NUC_CLK_BASE+NUC_CLK_APBCLK_OFFSET) +#define NUC_CLK_CLKSTATUS (NUC_CLK_BASE+NUC_CLK_CLKSTATUS_OFFSET) +#define NUC_CLK_CLKSEL0 (NUC_CLK_BASE+NUC_CLK_CLKSEL0_OFFSET) +#define NUC_CLK_CLKSEL1 (NUC_CLK_BASE+NUC_CLK_CLKSEL1_OFFSET) +#define NUC_CLK_CLKSEL2 (NUC_CLK_BASE+NUC_CLK_CLKSEL2_OFFSET) +#define NUC_CLK_CLKDIV (NUC_CLK_BASE+NUC_CLK_CLKDIV_OFFSET) +#define NUC_CLK_PLLCON (NUC_CLK_BASE+NUC_CLK_PLLCON_OFFSET) +#define NUC_CLK_FRQDIV (NUC_CLK_BASE+NUC_CLK_FRQDIV_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* System power down control register */ + +#define CLK_PWRCON_XTL12M_EN (1 << 0) /* Bit 0: External 4~24 mhz high speed crystal enable */ +#define CLK_PWRCON_XTL32K_EN (1 << 1) /* Bit 1: External 32.768 khz low speed crystal enable */ +#define CLK_PWRCON_OSC22M_EN (1 << 2) /* Bit 2: Internal 22.1184 MHz high speed oscillator enable */ +#define CLK_PWRCON_OSC10K_EN (1 << 3) /* Bit 3: Internal 10KHz low speed oscillator enable */ +#define CLK_PWRCON_PD_WU_DLY (1 << 4) /* Bit 4: Enable the wake-up delay counter */ +#define CLK_PWRCON_PD_WU_INT_EN (1 << 5) /* Bit 5: Power down mode wake-up interrupt status */ +#define CLK_PWRCON_PD_WU_STS (1 << 6) /* Bit 6: Power down mode wake-up interrupt status */ +#define CLK_PWRCON_PWR_DOWN_EN (1 << 7) /* Bit 7: System power down enable bit */ +#define CLK_PWRCON_PD_WAIT_CPU (1 << 8) /* Bit 8: Power down entry condition */ + +/* AHB devices clock enable control register */ + +#define CLK_AHBCLK_PDMA_EN (1 << 1) /* Bit 1: PDMA acontroller clock enable control */ +#define CLK_AHBCLK_ISP_EN (1 << 2) /* Bit 2: FLASH ISPO controller clock enable control */ +#define CLK_AHBCLK_EBI_EN (1 << 3) /* Bit 3: EBI controller clock enable control */ + +/* APB devices clock enable control register */ + +#define CLK_APBCLK_WDT_EN (1 << 0) /* Bit 0: Watchdog time clock enable */ +#define CLK_APBCLK_RTC_EN (1 << 1) /* Bit 1: Real time clock clock enable */ +#define CLK_APBCLK_TMR0_EN (1 << 2) /* Bit 2: Timer0 clock enable */ +#define CLK_APBCLK_TMR1_EN (1 << 3) /* Bit 3: Timer1 clock enable */ +#define CLK_APBCLK_TMR2_EN (1 << 4) /* Bit 4: Timer2 clock enable */ +#define CLK_APBCLK_TMR3_EN (1 << 5) /* Bit 5: Timer3 clock enable */ +#define CLK_APBCLK_FDIV_EN (1 << 6) /* Bit 6: Frequency divider output clock enable */ +#define CLK_APBCLK_I2C0_EN (1 << 8) /* Bit 8: I2C0 clock enable */ +#define CLK_APBCLK_I2C1_EN (1 << 9) /* Bit 9: I2C1 clock enable */ +#define CLK_APBCLK_SPI0_EN (1 << 12) /* Bit 12: SPI0 clock enable */ +#define CLK_APBCLK_SPI1_EN (1 << 13) /* Bit 13: SPI1 clock enable */ +#define CLK_APBCLK_SPI2_EN (1 << 14) /* Bit 14: SPI2 clock enable */ +#define CLK_APBCLK_SPI3_EN (1 << 15) /* Bit 15: SPI3 clock enable */ +#define CLK_APBCLK_UART0_EN (1 << 16) /* Bit 16: UART0 clock enable */ +#define CLK_APBCLK_UART1_EN (1 << 17) /* Bit 17: UART1 clock enable */ +#define CLK_APBCLK_UART2_EN (1 << 18) /* Bit 18: UART2 clock enable */ +#define CLK_APBCLK_PWM01_EN (1 << 20) /* Bit 20: PWM_01 clock enable */ +#define CLK_APBCLK_PWM23_EN (1 << 21) /* Bit 21: PWM_23 clock enable */ +#define CLK_APBCLK_PWM45_EN (1 << 22) /* Bit 22: PWM_45 clock enable */ +#define CLK_APBCLK_PWM67_EN (1 << 23) /* Bit 23: PWM_67 clock enable */ +#define CLK_APBCLK_USBD_EN (1 << 27) /* Bit 27: USB 2.0 FS device controller clock enable */ +#define CLK_APBCLK_ADC_EN (1 << 28) /* Bit 28: Analog-digital-converter clock enable */ +#define CLK_APBCLK_I2S_EN (1 << 29) /* Bit 29: I2S clock enable */ +#define CLK_APBCLK_ACMP_EN (1 << 30) /* Bit 30: Analog comparator clock enable */ +#define CLK_APBCLK_PS2_EN (1 << 31) /* Bit 31: PS/2 clock enable */ + +/* Clock status monitor register */ + +#define CLK_CLKSTATUS_XTL12M_STB (1 << 0) /* Bit 0: External 4~24 mhz high speed crystal + * clock source stable flag */ +#define CLK_CLKSTATUS_STL32K_STB (1 << 1) /* Bit 1: External 32.768 kHz low speed crystal + * clock source stable flag */ +#define CLK_CLKSTATUS_PLL_STB (1 << 2) /* Bit 2: Internal PLL clock source stable flag */ +#define CLK_CLKSTATUS_OSC10K_STB (1 << 3) /* Bit 3: Internal 10kHz low speed clock source + * stable flag */ +#define CLK_CLKSTATUS_OSC22M_STB (1 << 4) /* Bit 4: Internal 22.1184MHz high speed + * osciallator clock source stable flag */ +#define CLK_CLKSTATUS_CLK_SW_FAIL (1 << 7) /* Bit 7: Clock switching fail flag */ + +/* Clock source select control register 0 */ + +#define CLK_CLKSEL0_HCLK_S_SHIFT (0) /* Bits 0-2: HCLK clock source select */ +#define CLK_CLKSEL0_HCLK_S_MASK (7 << CLK_CLKSEL0_HCLK_S_SHIFT) +# define CLK_CLKSEL0_HCLK_S_XTALHI (0 << CLK_CLKSEL0_HCLK_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL0_HCLK_S_XTALLO (1 << CLK_CLKSEL0_HCLK_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL0_HCLK_S_PLL (2 << CLK_CLKSEL0_HCLK_S_SHIFT) /* PLL clock */ +# define CLK_CLKSEL0_HCLK_S_INTLO (3 << CLK_CLKSEL0_HCLK_S_SHIFT) /* Internal low speed clock */ +# define CLK_CLKSEL0_HCLK_S_INTHI (7 << CLK_CLKSEL0_HCLK_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL0_STCLK_S_SHIFT (3) /* Bits 3-5: Cortex M0 Systick clock source select */ +#define CLK_CLKSEL0_STCLK_S_MASK (7 << CLK_CLKSEL0_STCLK_S_SHIFT) +# define CLK_CLKSEL0_STCLK_S_XTALHI (0 << CLK_CLKSEL0_STCLK_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL0_STCLK_S_XTALLO (1 << CLK_CLKSEL0_STCLK_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL0_STCLK_S_XTALDIV2 (2 << CLK_CLKSEL0_STCLK_S_SHIFT) /* High speed XTAL clock/2 */ +# define CLK_CLKSEL0_STCLK_S_HCLKDIV2 (3 << CLK_CLKSEL0_STCLK_S_SHIFT) /* HCLK/2 */ +# define CLK_CLKSEL0_STCLK_S_INTDIV2 (7 << CLK_CLKSEL0_STCLK_S_SHIFT) /* Internal high speed clock/2 */ + +/* Clock source select control register 1 */ + +#define CLK_CLKSEL1_WDT_S_SHIFT (0) /* Bits 0-1: Watchdog timer clock source select */ +#define CLK_CLKSEL1_WDT_S_MASK (3 << CLK_CLKSEL1_WDT_S_SHIFT) +# define CLK_CLKSEL1_ADC_S_HCLKDIV (2 << CLK_CLKSEL1_WDT_S_SHIFT) /* HCLK / 2048 */ +# define CLK_CLKSEL1_ADC_S_INTLO (3 << CLK_CLKSEL1_WDT_S_SHIFT) /* Internal low speed clock */ +#define CLK_CLKSEL1_ADC_S_SHIFT (2) /* Bits 2-3: ADC clock source select */ +#define CLK_CLKSEL1_ADC_S_MASK (3 << CLK_CLKSEL1_ADC_S_SHIFT) +# define CLK_CLKSEL1_ADC_S_XTALHI (0 << CLK_CLKSEL1_ADC_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_ADC_S_PLL (1 << CLK_CLKSEL1_ADC_S_SHIFT) /* PLL */ +# define CLK_CLKSEL1_ADC_S_INTHI (3 << CLK_CLKSEL1_ADC_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_TMR0_S_SHIFT (8) /* Bits 8-10: Timer0 clock source select */ +#define CLK_CLKSEL1_TMR0_S_MASK (7 << CLK_CLKSEL1_TMR0_S_SHIFT) +# define CLK_CLKSEL1_TMR0_S_XTALHI (0 << CLK_CLKSEL1_TMR0_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_TMR0_S_XTALLO (1 << CLK_CLKSEL1_TMR0_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_TMR0_S_HCLK (2 << CLK_CLKSEL1_TMR0_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_TMR0_S_INTHI (7 << CLK_CLKSEL1_TMR0_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_TMR1_S_SHIFT (12) /* Bits 12-14: Timer1 clock source select */ +#define CLK_CLKSEL1_TMR1_S_MASK (7 << CLK_CLKSEL1_TMR1_S_SHIFT) +# define CLK_CLKSEL1_TMR1_S_XTALHI (0 << CLK_CLKSEL1_TMR1_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_TMR1_S_XTALLO (1 << CLK_CLKSEL1_TMR1_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_TMR1_S_HCLK (2 << CLK_CLKSEL1_TMR1_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_TMR1_S_INTHI (7 << CLK_CLKSEL1_TMR1_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_TMR2_S_SHIFT (16) /* Bits 16-18: Timer2 clock source select */ +#define CLK_CLKSEL1_TMR2_S_MASK (7 << CLK_CLKSEL1_TMR2_S_SHIFT) +# define CLK_CLKSEL1_TMR2_S_XTALHI (0 << CLK_CLKSEL1_TMR2_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_TMR2_S_XTALLO (1 << CLK_CLKSEL1_TMR2_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_TMR2_S_HCLK (2 << CLK_CLKSEL1_TMR2_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_TMR2_S_INTHI (7 << CLK_CLKSEL1_TMR2_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_TMR3_S_SHIFT (20) /* Bits 20-22: Timer3 clock source select */ +#define CLK_CLKSEL1_TMR3_S_MASK (7 << CLK_CLKSEL1_TMR3_S_SHIFT) +# define CLK_CLKSEL1_TMR3_S_XTALHI (0 << CLK_CLKSEL1_TMR3_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_TMR3_S_XTALLO (1 << CLK_CLKSEL1_TMR3_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_TMR3_S_HCLK (2 << CLK_CLKSEL1_TMR3_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_TMR3_S_INTHI (7 << CLK_CLKSEL1_TMR3_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_UART_S_SHIFT (24) /* Bits 24-25: UART clock source select */ +#define CLK_CLKSEL1_UART_S_MASK (3 << CLK_CLKSEL1_UART_S_SHIFT) +# define CLK_CLKSEL1_UART_S_XTALHI (0 << CLK_CLKSEL1_UART_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_UART_S_PLL (1 << CLK_CLKSEL1_UART_S_SHIFT) /* PLL */ +# define CLK_CLKSEL1_UART_S_INTHI (3 << CLK_CLKSEL1_UART_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_PWM01_S_SHIFT (28) /* Bits 28-29: PWM0 and PWM1 clock source select */ +#define CLK_CLKSEL1_PWM01_S_MASK (3 << CLK_CLKSEL1_PWM01_S_SHIFT) +# define CLK_CLKSEL1_PWM01_S_XTALHI (0 << CLK_CLKSEL1_PWM01_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_PWM01_S_XTALLO (1 << CLK_CLKSEL1_PWM01_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_PWM01_S_HCLK (2 << CLK_CLKSEL1_PWM01_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_PWM01_S_INTHI (3 << CLK_CLKSEL1_PWM01_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL1_PWM23_S_SHIFT (30) /* Bits 30-31: PWM2 and PWM3 clock source select */ +#define CLK_CLKSEL1_PWM23_S_MASK (3 << CLK_CLKSEL1_PWM23_S_SHIFT) +# define CLK_CLKSEL1_PWM23_S_XTALHI (0 << CLK_CLKSEL1_PWM23_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_PWM23_S_XTALLO (1 << CLK_CLKSEL1_PWM23_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_PWM23_S_HCLK (2 << CLK_CLKSEL1_PWM23_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_PWM23_S_INTHI (3 << CLK_CLKSEL1_PWM23_S_SHIFT) /* Internal high speed clock */ + +/* Clock source select control register 2 */ + +#define CLK_CLKSEL2_I2S_S_SHIFT (0) /* Bits 0-1: I2S clock source select */ +#define CLK_CLKSEL2_I2S_S_MASK (3 << CLK_CLKSEL2_I2S_S_SHIFT) +# define CLK_CLKSEL1_I2S_S_XTALHI (0 << CLK_CLKSEL2_I2S_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_I2S_S_XTALLO (1 << CLK_CLKSEL2_I2S_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_I2S_S_HCLK (2 << CLK_CLKSEL2_I2S_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_I2S_S_INTHI (3 << CLK_CLKSEL2_I2S_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL2_FRQDIV_S_SHIFT (2) /* Bits 2-3: Frequency divider clock source select */ +#define CLK_CLKSEL2_FRQDIV_S_MASK (3 << CLK_CLKSEL2_FRQDIV_S_SHIFT) +# define CLK_CLKSEL1_FRQDIV_S_XTALHI (0 << CLK_CLKSEL2_FRQDIV_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_FRQDIV_S_XTALLO (1 << CLK_CLKSEL2_FRQDIV_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_FRQDIV_S_HCLK (2 << CLK_CLKSEL2_FRQDIV_S_SHIFT) /* HCLK */ +#define CLK_CLKSEL2_PWM45_S_SHIFT (4) /* Bits 4-5: PWM4 and PWM5 clock source select */ +#define CLK_CLKSEL2_PWM45_S_MASK (3 << CLK_CLKSEL2_PWM45_S_SHIFT) +# define CLK_CLKSEL1_PWM45_S_XTALHI (0 << CLK_CLKSEL2_PWM45_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_PWM45_S_XTALLO (1 << CLK_CLKSEL2_PWM45_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_PWM45_S_HCLK (2 << CLK_CLKSEL2_PWM45_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_PWM45_S_INTHI (3 << CLK_CLKSEL2_PWM45_S_SHIFT) /* Internal high speed clock */ +#define CLK_CLKSEL2_PWM67_S_SHIFT (6) /* Bits 6-7: PWM6 and PWM7 clock source select */ +#define CLK_CLKSEL2_PWM67_S_MASK (3 << CLK_CLKSEL2_PWM67_S_SHIFT) +# define CLK_CLKSEL1_PWM67_S_XTALHI (0 << CLK_CLKSEL2_PWM67_S_SHIFT) /* High speed XTAL clock */ +# define CLK_CLKSEL1_PWM67_S_XTALLO (1 << CLK_CLKSEL2_PWM67_S_SHIFT) /* Low speed XTAL clock */ +# define CLK_CLKSEL1_PWM67_S_HCLK (2 << CLK_CLKSEL2_PWM67_S_SHIFT) /* HCLK */ +# define CLK_CLKSEL1_PWM67_S_INTHI (3 << CLK_CLKSEL2_PWM67_S_SHIFT) /* Internal high speed clock */ + +/* Clock divider number register */ + +#define CLK_CLKDIV_HCLK_N_SHIFT (0) /* Bits 0-3: HCLCK divide from clock source */ +#define CLK_CLKDIV_HCLK_N_MASK (15 << CLK_CLKDIV_HCLK_N_SHIFT) +# define CLK_CLKDIV_HCLK_N(n) (((n)-1) << CLK_CLKDIV_HCLK_N_SHIFT) /* n=1..16 */ +#define CLK_CLKDIV_USB_N_SHIFT (4) /* Bits 4-7: USBD divide from clock source */ +#define CLK_CLKDIV_USB_N_MASK (15 << CLK_CLKDIV_USB_N_SHIFT) +# define CLK_CLKDIV_USB_N(n) (((n)-1) << CLK_CLKDIV_USB_N_SHIFT) /* n=1..16 */ +#define CLK_CLKDIV_UART_N_SHIFT (8) /* Bits 8-11 UART divide from clock source */ +#define CLK_CLKDIV_UART_N_MASK (15 << CLK_CLKDIV_UART_N_SHIFT) +# define CLK_CLKDIV_UART_N(n) (((n)-1) << CLK_CLKDIV_UART_N_SHIFT) /* n=1..16 */ +#define CLK_CLKDIV_ADC_N_SHIFT (16) /* Bits 16-23: ADC divide from clock source */ +#define CLK_CLKDIV_ADC_N_MASK (255 << CLK_CLKDIV_ADC_N_SHIFT) +# define CLK_CLKDIV_ADC_N(n) (((n)-1) << CLK_CLKDIV_UART_N_SHIFT) /* n=1..256 */ + +/* PLL control register */ + +#define CLK_PLLCON_FB_DV_SHIFT (0) /* Bits 0-8: PLL feedback divider control pins */ +#define CLK_PLLCON_FB_DV_MASK (0x1ff << CLK_PLLCON_FB_DV_SHIFT) +# define CLK_PLLCON_FB_DV(n) ((n) << CLK_PLLCON_FB_DV_SHIFT) +#define CLK_PLLCON_IN_DV_SHIFT (9) /* bits 9-13: PLL input divider control pins */ +#define CLK_PLLCON_IN_DV_MASK (0x1f << CLK_PLLCON_IN_DV_SHIFT) +# define CLK_PLLCON_IN_DV(n) ((n) << CLK_PLLCON_IN_DV_SHIFT) +#define CLK_PLLCON_OUT_DV_SHIFT (14) /* Bits 14-15: PLL output divider control pins */ +#define CLK_PLLCON_OUT_DV_MASK (3 << CLK_PLLCON_OUT_DV_SHIFT) +# define CLK_PLLCON_OUT_DV(n) ((n) << CLK_PLLCON_OUT_DV_SHIFT) +#define CLK_PLLCON_PD (1 << 16) /* Bit 16: Power down mode */ +#define CLK_PLLCON_BP (1 << 17) /* Bit 17: PLL bypass control */ +#define CLK_PLLCON_OE (1 << 18) /* Bit 18: PLL OE (FOUT enable) pin control */ +#define CLK_PLLCON_PLL_SRC (1 << 19) /* Bit 19: PLL source clock select */ + +/* Frequency divider control register */ + +#define CLK_FRQDIV_FSEL_SHIFT (0) /* Bits 0-3: Divider output frequency selection bits */ +#define CLK_FRQDIV_FSEL_MASK (15 << CLK_FRQDIV_FSEL_SHIFT) +# define CLK_FRQDIV_FSEL(n) ((n) << CLK_FRQDIV_FSEL_SHIFT) /* fout = fin / (2^(n+1)) */ +#define CLK_FRQDIV_DIVIDER_EN (1 << 4) /* Bit 4: Frequency divider enable bit */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CLK_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_cmp.h b/arch/arm/src/nuc1xx/chip/nuc_cmp.h new file mode 100644 index 0000000000000000000000000000000000000000..64d11b31e02b84bac18dcceb58e07a914dd1076b --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_cmp.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_cmp.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CMP_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CMP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CMP_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_config.h b/arch/arm/src/nuc1xx/chip/nuc_config.h new file mode 100644 index 0000000000000000000000000000000000000000..cfc15bae9948a65321f441462a562a778a1a9a78 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_config.h @@ -0,0 +1,117 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_config.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CONFIG_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CONFIG_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + +#define NUC_CONFIG0_OFFSET 0x0000 /* Config 0 */ +#define NUC_CONFIG1_OFFSET 0x0004 /* Config 1 */ + +/* Register addresses ***********************************************************************/ + +#define NUC_CONFIG0 (NUC_CONFIG_BASE+NUC_CONFIG0_OFFSET) +#define NUC_CONFIG1 (NUC_CONFIG_BASE+NUC_CONFIG1_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* Config 0 */ + +#define CONFIG0_DFEN (1 << 0) /* Bit 0: Data FLASH enable */ +#define CONFIG0_LOCK (1 << 1) /* Bit 1: Security lock */ +#define CONFIG0_CBS (1 << 7) /* Bit 7: Chip boot selection. 1=LDROM 0=APROM */ +#define CONFIG0_CBORST (1 << 20) /* Bit 20: Brown-out reset enable */ +#define CONFIG0_CBOV_SHIFT (21) /* Bits 21-22: Brown-out voltage selection */ +#define CONFIG0_CBOV_MASK (3 << CONFIG0_CBOV_SHIFT) +# define CONFIG0_CBOV_2p2V (0 << CONFIG0_CBOV_SHIFT) /* 2.2V */ +# define CONFIG0_CBOV_2p7V (1 << CONFIG0_CBOV_SHIFT) /* 2.7V */ +# define CONFIG0_CBOV_3p8V (2 << CONFIG0_CBOV_SHIFT) /* 3.8V */ +# define CONFIG0_CBOV_4p5V (3 << CONFIG0_CBOV_SHIFT) /* 4.5V */ +#define CONFIG0_CBODEN (1 << 23) /* Bit 23: Brown out detector enable */ +#define CONFIG0_CFOSC_SHIFT (24) /* Bits 24-26: CPU clock source selection after reset */ +#define CONFIG0_CFOSC_MASK (7 << CONFIG0_CFOSC_SHIFT) +# define CONFIG0_CFOSC_XTALHI (0 << CONFIG0_CFOSC_SHIFT) +# define CONFIG0_CFOSC_INTHI (7 << CONFIG0_CFOSC_SHIFT) +#define CONFIG0_CKF (1 << 28) /* Bit 28: XT1 clock filter enable */ + +/* My NuTiny-SDK-NUC120 was programmed this way when I got it: + * CKF=1 + * CFOSC=0 + * CBODEN=1 + * CBOV=3 + * CBORST=1 + * CBS=0 + * LOCK=1 + * DFEN=1 + */ + +#define CONFIG0_FACTORY_DEFAULT (0xf8ffff7f) + +/* Config 1 */ + +#define CONFIG1_DFBADR_SHIFT (0) /* Bits 0-19: Data FLASH base address */ +#define CONFIG1_DFBADR_MASK (0x000fffff << CONFIG1_DFBADR_SHIFT) + +/* My NuTiny-SDK-NUC120 was programmed this way when I got it: + * DFBADR=0x05000 + */ + +#define CONFIG1_FACTORY_DEFAULT (0x00005000) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_CONFIG_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_ebi.h b/arch/arm/src/nuc1xx/chip/nuc_ebi.h new file mode 100644 index 0000000000000000000000000000000000000000..142ae60ab9aa9a9094ff01c409800ef77ee57c3a --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_ebi.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_ebi.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_EBI_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_EBI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_EBI_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_gcr.h b/arch/arm/src/nuc1xx/chip/nuc_gcr.h new file mode 100644 index 0000000000000000000000000000000000000000..065c3defbb2832d514e35149166ff93b5a22b7bc --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_gcr.h @@ -0,0 +1,373 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_gcr.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GCR_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GCR_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + +#define NUC_GCR_PDID_OFFSET 0x0000 /* Part didentification number register */ +#define NUC_GCR_RSTSRC_OFFSET 0x0004 /* System reset source register */ +#define NUC_GCR_IPRSTC1_OFFSET 0x0008 /* IP Reset control register 1 */ +#define NUC_GCR_IPRSTC2_OFFSET 0x000c /* IP Reset control register 2 */ +#define NUC_GCR_CPR_OFFSET 0x0010 /* Chip performance register */ +#define NUC_GCR_BODCR_OFFSET 0x0018 /* Brown-out detector control register */ +#define NUC_GCR_TEMPCR_OFFSET 0x001c /* Temperature sensor control register */ +#define NUC_GCR_PORCR_OFFSET 0x0024 /* Power-on-reset control register */ +#define NUC_GCR_GPA_MFP_OFFSET 0x0030 /* Multiple function pin GPIOA control register */ +#define NUC_GCR_GPB_MFP_OFFSET 0x0034 /* Multiple function pin GPIOB control register */ +#define NUC_GCR_GPC_MFP_OFFSET 0x0038 /* Multiple function pin GPIOC control register */ +#define NUC_GCR_GPD_MFP_OFFSET 0x003C /* Multiple function pin GPIOD control register */ +#define NUC_GCR_GPE_MFP_OFFSET 0x0040 /* Multiple function pin GPIOE control register */ +#define NUC_GCR_ALT_MFP_OFFSET 0x0050 /* Alternative multiple function pin control register */ +#define NUC_GCR_REGWRPROT_OFFSET 0x0100 /* Register write-protection control register */ + +/* Register addresses ***********************************************************************/ + +#define NUC_GCR_PDID (NUC_GCR_BASE+NUC_GCR_PDID_OFFSET) +#define NUC_GCR_RSTSRC (NUC_GCR_BASE+NUC_GCR_RSTSRC_OFFSET) +#define NUC_GCR_IPRSTC1 (NUC_GCR_BASE+NUC_GCR_IPRSTC1_OFFSET) +#define NUC_GCR_IPRSTC2 (NUC_GCR_BASE+NUC_GCR_IPRSTC2_OFFSET) +#define NUC_GCR_CPR (NUC_GCR_BASE+NUC_GCR_CPR_OFFSET) +#define NUC_GCR_BODCR (NUC_GCR_BASE+NUC_GCR_BODCR_OFFSET) +#define NUC_GCR_TEMPCR (NUC_GCR_BASE+NUC_GCR_TEMPCR_OFFSET) +#define NUC_GCR_PORCR (NUC_GCR_BASE+NUC_GCR_PORCR_OFFSET) +#define NUC_GCR_GPA_MFP (NUC_GCR_BASE+NUC_GCR_GPA_MFP_OFFSET) +#define NUC_GCR_GPB_MFP (NUC_GCR_BASE+NUC_GCR_GPB_MFP_OFFSET) +#define NUC_GCR_GPC_MFP (NUC_GCR_BASE+NUC_GCR_GPC_MFP_OFFSET) +#define NUC_GCR_GPD_MFP (NUC_GCR_BASE+NUC_GCR_GPD_MFP_OFFSET) +#define NUC_GCR_GPE_MFP (NUC_GCR_BASE+NUC_GCR_GPE_MFP_OFFSET) +#define NUC_GCR_ALT_MFP (NUC_GCR_BASE+NUC_GCR_ALT_MFP_OFFSET) +#define NUC_GCR_REGWRPROT (NUC_GCR_BASE+NUC_GCR_REGWRPROT_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* Part didentification number register (32-bit part ID number) */ + +/* System reset source register */ + +#define GCR_RSTSRC_POR (1 << 0) /* Bit 0: Power-on reset (POR) or chip reset (CHIP_RST) */ +#define GCR_RSTSRC_RESET (1 << 1) /* Bit 1: /RESET pin */ +#define GCR_RSTSRC_WDT (1 << 2) /* Bit 2: Watchdog timer */ +#define GCR_RSTSRC_LVR (1 << 3) /* Bit 3: Low voltage reset controller */ +#define GCR_RSTSRC_BOD (1 << 4) /* Bit 4: Brown-out detection */ +#define GCR_RSTSRC_SYS (1 << 5) /* Bit 5: Software set AIRCR:SYSRESETREQ */ +#define GCR_RSTSRC_CPU (1 << 7) /* Bit 7: Sofware set CPU_RST */ + +/* IP Reset control register 1 */ + +#define GCR_IPRSTC1_CHIP_RST (1 << 0) /* Bit 0: Chip one-shot reset */ +#define GCR_IPRSTC1_CPU_RST (1 << 1) /* Bit 1: CPU kernel one-shot reset */ +#define GCR_IPRSTC1_PDMA_RST (1 << 2) /* Bit 2: PDMA controller reset */ +#define GCR_IPRSTC1_EBI_RST (1 << 3) /* Bit 3: EBI controller reset */ + +/* IP Reset control register 2 */ + +#define GCR_IPRSTC2_GPIO_RST (1 << 1) /* Bit 1: GPIO controller reset */ +#define GCR_IPRSTC2_TMR0_RST (1 << 2) /* Bit 2: Timer0 controller reset */ +#define GCR_IPRSTC2_TMR1_RST (1 << 3) /* Bit 3: Timer1 controller reset */ +#define GCR_IPRSTC2_TMR2_RST (1 << 4) /* Bit 4: Timer2 controller reset */ +#define GCR_IPRSTC2_TMR3_RST (1 << 5) /* Bit 5: Timer3 controller reset */ +#define GCR_IPRSTC2_I2C0_RST (1 << 8) /* Bit 8: I2C0 controller reset */ +#define GCR_IPRSTC2_I2C1_RST (1 << 9) /* Bit 9: I2C1 controller reset */ +#define GCR_IPRSTC2_SPI0_RST (1 << 12) /* Bit 12: SPI0 controller reset */ +#define GCR_IPRSTC2_SPI1_RST (1 << 13) /* Bit 13: SPI1 controller reset */ +#define GCR_IPRSTC2_SPI2_RST (1 << 14) /* Bit 14: SPI2 controller reset */ +#define GCR_IPRSTC2_SPI3_RST (1 << 15) /* Bit 15: SPI3 controller reset */ +#define GCR_IPRSTC2_UART0_RST (1 << 16) /* Bit 16: UART0 controller reset */ +#define GCR_IPRSTC2_UART1_RST (1 << 17) /* Bit 17: UART1 controller reset */ +#define GCR_IPRSTC2_UART2_RST (1 << 18) /* Bit 18: UART2 controller reset */ +#define GCR_IPRSTC2_PWM03_RST (1 << 20) /* Bit 20: PWM0/1/2/3 controller reset */ +#define GCR_IPRSTC2_PWM47_RST (1 << 21) /* Bit 21: PWM4/5/6/7 controller reset */ +#define GCR_IPRSTC2_ACMP_RST (1 << 22) /* Bit 22: Analog comparator controller reset */ +#define GCR_IPRSTC2_PS2_RST (1 << 23) /* Bit 23: PS/2 controller reset */ +#define GCR_IPRSTC2_USBD_RST (1 << 27) /* Bit 27: USB device controller reset */ +#define GCR_IPRSTC2_ADC_RST (1 << 28) /* Bit 28: ADC controller reset */ +#define GCR_IPRSTC2_I2S_RST (1 << 29) /* Bit 29: I2S controller reset */ + +/* Chip performance register */ + +#define GCR_CPR_HPE (1 << 0) /* Bit 0: High performance enable */ + +/* Brown-out detector control register */ + +#define GCR_BODCR_BOD_EN (1 << 0) /* Bit 0: Brown-ut detector enable */ +#define GCR_BODCR_BOD_VL_SHIFT (1) /* Bits 1-2: Brown-out detector threshold voltage selection */ +#define GCR_BODCR_BOD_VL_MASK (3 << GCR_BODCR_BOD_VL_SHIFT) +# define GCR_BODCR_BOD_VL_2p2V (0 << GCR_BODCR_BOD_VL_SHIFT) /* 2.2V */ +# define GCR_BODCR_BOD_VL_2p7V (1 << GCR_BODCR_BOD_VL_SHIFT) /* 2.7V */ +# define GCR_BODCR_BOD_VL_3p8V (2 << GCR_BODCR_BOD_VL_SHIFT) /* 3.8V */ +# define GCR_BODCR_BOD_VL_4p5V (3 << GCR_BODCR_BOD_VL_SHIFT) /* 4.5V */ +#define GCR_BODCR_BOD_RSTEN (1 << 3) /* Bit 3: Brown-out reset enable */ +#define GCR_BODCR_BOD_INTF (1 << 4) /* Bit 4: Brown-out deletector interrupt flag */ +#define GCR_BODCR_BOD_LPM (1 << 5) /* Bit 5: Brown-out detector low power mode */ +#define GCR_BODCR_BOD_OUT (1 << 6) /* Bit 6: Brown-out detector output status */ +#define GCR_BODCR_LVR_EN (1 << 7) /* Bit 7: Low voltaghe reset enable */ + +/* Temperature sensor control register */ + +#define GCR_TEMPCR_VTEMP_EN (1 << 0) /* Bit 0: Temperature sensor enable */ + +/* Power-on-reset control register */ + +#define GCR_PORCR_MASK (0xffff) /* Bits 9-15: POR disable code */ + +/* Multiple function pin GPIOA control register */ + +#define GCR_GPA_MFP(n) (1 << (n)) /* Bits 0-15: PAn pin function selection */ +# define GCR_GPA_MFP0 (1 << 0) +# define GCR_GPA_MFP1 (1 << 1) +# define GCR_GPA_MFP2 (1 << 2) +# define GCR_GPA_MFP3 (1 << 3) +# define GCR_GPA_MFP4 (1 << 4) +# define GCR_GPA_MFP5 (1 << 5) +# define GCR_GPA_MFP6 (1 << 6) +# define GCR_GPA_MFP7 (1 << 7) +# define GCR_GPA_MFP8 (1 << 8) +# define GCR_GPA_MFP9 (1 << 9) +# define GCR_GPA_MFP10 (1 << 10) +# define GCR_GPA_MFP11 (1 << 11) +# define GCR_GPA_MFP12 (1 << 12) +# define GCR_GPA_MFP13 (1 << 13) +# define GCR_GPA_MFP14 (1 << 14) +# define GCR_GPA_MFP15 (1 << 15) +#define GCR_GPA_TYPE(n) (1 << ((n)+16)) /* Bits 16-31: Enable Schmitt trigger function */ +# define GCR_GPA_TYPE0 (1 << 0) +# define GCR_GPA_TYPE1 (1 << 1) +# define GCR_GPA_TYPE2 (1 << 2) +# define GCR_GPA_TYPE3 (1 << 3) +# define GCR_GPA_TYPE4 (1 << 4) +# define GCR_GPA_TYPE5 (1 << 5) +# define GCR_GPA_TYPE6 (1 << 6) +# define GCR_GPA_TYPE7 (1 << 7) +# define GCR_GPA_TYPE8 (1 << 8) +# define GCR_GPA_TYPE9 (1 << 9) +# define GCR_GPA_TYPE10 (1 << 10) +# define GCR_GPA_TYPE11 (1 << 11) +# define GCR_GPA_TYPE12 (1 << 12) +# define GCR_GPA_TYPE13 (1 << 13) +# define GCR_GPA_TYPE14 (1 << 14) +# define GCR_GPA_TYPE15 (1 << 15) + +/* Multiple function pin GPIOB control register */ + +#define GCR_GPB_MFP(n) (1 << (n)) /* Bits 0-15: PBn pin function selection */ +# define GCR_GPB_MFP0 (1 << 0) +# define GCR_GPB_MFP1 (1 << 1) +# define GCR_GPB_MFP2 (1 << 2) +# define GCR_GPB_MFP3 (1 << 3) +# define GCR_GPB_MFP4 (1 << 4) +# define GCR_GPB_MFP5 (1 << 5) +# define GCR_GPB_MFP6 (1 << 6) +# define GCR_GPB_MFP7 (1 << 7) +# define GCR_GPB_MFP8 (1 << 8) +# define GCR_GPB_MFP9 (1 << 9) +# define GCR_GPB_MFP10 (1 << 10) +# define GCR_GPB_MFP11 (1 << 11) +# define GCR_GPB_MFP12 (1 << 12) +# define GCR_GPB_MFP13 (1 << 13) +# define GCR_GPB_MFP14 (1 << 14) +# define GCR_GPB_MFP15 (1 << 15) +#define GCR_GPB_TYPE(n) (1 << ((n)+16)) /* Bits 16-31: Enable Schmitt trigger function */ +# define GCR_GPB_TYPE0 (1 << 0) +# define GCR_GPB_TYPE1 (1 << 1) +# define GCR_GPB_TYPE2 (1 << 2) +# define GCR_GPB_TYPE3 (1 << 3) +# define GCR_GPB_TYPE4 (1 << 4) +# define GCR_GPB_TYPE5 (1 << 5) +# define GCR_GPB_TYPE6 (1 << 6) +# define GCR_GPB_TYPE7 (1 << 7) +# define GCR_GPB_TYPE8 (1 << 8) +# define GCR_GPB_TYPE9 (1 << 9) +# define GCR_GPB_TYPE10 (1 << 10) +# define GCR_GPB_TYPE11 (1 << 11) +# define GCR_GPB_TYPE12 (1 << 12) +# define GCR_GPB_TYPE13 (1 << 13) +# define GCR_GPB_TYPE14 (1 << 14) +# define GCR_GPB_TYPE15 (1 << 15) + +/* Multiple function pin GPIOC control register */ + +#define GCR_GPC_MFP(n) (1 << (n)) /* Bits 0-15: PCn pin function selection */ +# define GCR_GPC_MFP0 (1 << 0) +# define GCR_GPC_MFP1 (1 << 1) +# define GCR_GPC_MFP2 (1 << 2) +# define GCR_GPC_MFP3 (1 << 3) +# define GCR_GPC_MFP4 (1 << 4) +# define GCR_GPC_MFP5 (1 << 5) +# define GCR_GPC_MFP6 (1 << 6) +# define GCR_GPC_MFP7 (1 << 7) +# define GCR_GPC_MFP8 (1 << 8) +# define GCR_GPC_MFP9 (1 << 9) +# define GCR_GPC_MFP10 (1 << 10) +# define GCR_GPC_MFP11 (1 << 11) +# define GCR_GPC_MFP12 (1 << 12) +# define GCR_GPC_MFP13 (1 << 13) +# define GCR_GPC_MFP14 (1 << 14) +# define GCR_GPC_MFP15 (1 << 15) +#define GCR_GPC_TYPE(n) (1 << ((n)+16)) /* Bits 16-31: Enable Schmitt trigger function */ +# define GCR_GPC_TYPE0 (1 << 0) +# define GCR_GPC_TYPE1 (1 << 1) +# define GCR_GPC_TYPE2 (1 << 2) +# define GCR_GPC_TYPE3 (1 << 3) +# define GCR_GPC_TYPE4 (1 << 4) +# define GCR_GPC_TYPE5 (1 << 5) +# define GCR_GPC_TYPE6 (1 << 6) +# define GCR_GPC_TYPE7 (1 << 7) +# define GCR_GPC_TYPE8 (1 << 8) +# define GCR_GPC_TYPE9 (1 << 9) +# define GCR_GPC_TYPE10 (1 << 10) +# define GCR_GPC_TYPE11 (1 << 11) +# define GCR_GPC_TYPE12 (1 << 12) +# define GCR_GPC_TYPE13 (1 << 13) +# define GCR_GPC_TYPE14 (1 << 14) +# define GCR_GPC_TYPE15 (1 << 15) + +/* Multiple function pin GPIOD control register */ + +#define GCR_GPD_MFP(n) (1 << (n)) /* Bits 0-15: PDn pin function selection */ +# define GCR_GPD_MFP0 (1 << 0) +# define GCR_GPD_MFP1 (1 << 1) +# define GCR_GPD_MFP2 (1 << 2) +# define GCR_GPD_MFP3 (1 << 3) +# define GCR_GPD_MFP4 (1 << 4) +# define GCR_GPD_MFP5 (1 << 5) +# define GCR_GPD_MFP6 (1 << 6) +# define GCR_GPD_MFP7 (1 << 7) +# define GCR_GPD_MFP8 (1 << 8) +# define GCR_GPD_MFP9 (1 << 9) +# define GCR_GPD_MFP10 (1 << 10) +# define GCR_GPD_MFP11 (1 << 11) +# define GCR_GPD_MFP12 (1 << 12) +# define GCR_GPD_MFP13 (1 << 13) +# define GCR_GPD_MFP14 (1 << 14) +# define GCR_GPD_MFP15 (1 << 15) +#define GCR_GPD_TYPE(n) (1 << ((n)+16)) /* Bits 16-31: Enable Schmitt trigger function */ +# define GCR_GPD_TYPE0 (1 << 0) +# define GCR_GPD_TYPE1 (1 << 1) +# define GCR_GPD_TYPE2 (1 << 2) +# define GCR_GPD_TYPE3 (1 << 3) +# define GCR_GPD_TYPE4 (1 << 4) +# define GCR_GPD_TYPE5 (1 << 5) +# define GCR_GPD_TYPE6 (1 << 6) +# define GCR_GPD_TYPE7 (1 << 7) +# define GCR_GPD_TYPE8 (1 << 8) +# define GCR_GPD_TYPE9 (1 << 9) +# define GCR_GPD_TYPE10 (1 << 10) +# define GCR_GPD_TYPE11 (1 << 11) +# define GCR_GPD_TYPE12 (1 << 12) +# define GCR_GPD_TYPE13 (1 << 13) +# define GCR_GPD_TYPE14 (1 << 14) +# define GCR_GPD_TYPE15 (1 << 15) + +/* Multiple function pin GPIOE control register */ + +#define GCR_GPE_MFP(n) (1 << (n)) /* Bits 0-15: PDn pin function selection */ +# define GCR_GPE_MFP0 (1 << 0) +# define GCR_GPE_MFP1 (1 << 1) +# define GCR_GPE_MFP2 (1 << 2) +# define GCR_GPE_MFP3 (1 << 3) +# define GCR_GPE_MFP4 (1 << 4) +# define GCR_GPE_MFP5 (1 << 5) +#define GCR_GPE_TYPE(n) (1 << ((n)+16)) /* Bits 16-31: Enable Schmitt trigger function */ +# define GCR_GPE_TYPE0 (1 << 0) +# define GCR_GPE_TYPE1 (1 << 1) +# define GCR_GPE_TYPE2 (1 << 2) +# define GCR_GPE_TYPE3 (1 << 3) +# define GCR_GPE_TYPE4 (1 << 4) +# define GCR_GPE_TYPE5 (1 << 5) + +/* Alternative multiple function pin control register */ + +#define GCR_ALT_MFP_PB10_S01 (1 << 0) /* Bit 0: Determines PB.10 function */ +#define GCR_ALT_MFP_PB9_S11 (1 << 1) /* Bit 1: Determines PB.9 function */ +#define GCR_ALT_MFP_PA7_S21 (1 << 2) /* Bit 2: Determines PA.7 function */ +#define GCR_ALT_MFP_PB14_S31 (1 << 3) /* Bit 3: Determines PB.14 function */ +#define GCR_ALT_MFP_PB11_PWM4 (1 << 4) /* Bit 4: Determines PB.11 function */ +#define GCR_ALT_MFP_PC0_I2SRCLK (1 << 5) /* Bit 5: Determines PC.0 function */ +#define GCR_ALT_MFP_PC1_I2SBCLK (1 << 6) /* Bit 6: Determines PC.1 function */ +#define GCR_ALT_MFP_PC2_I2SD1 (1 << 7) /* Bit 7: Determines PC.2 function */ +#define GCR_ALT_MFP_PC3_I2SD0 (1 << 8) /* Bit 8: Determines PC.3 function */ +#define GCR_ALT_MFP_PA15_I2SMCLK (1 << 9) /* Bit 9: Determines PA.15 function */ +#define GCR_ALT_MFP_PB12_CLKO (1 << 10) /* Bit 10: Determines PB.12 function */ +#define GCR_ALT_MFP_EBI_EN (1 << 11) /* Bit 11: Determines PA.6, PA.7, PA.10, PA.11, + * PB.6, PB.7, PB.12, PB.13, PC.6, PC.7, PC.14, + * PC.15 function */ +#define GCR_ALT_MFP_EBI_MCLK_EN (1 << 12) /* Bit 12: Determines PC.8 function */ +#define GCR_ALT_MFP_EBI_NWRL_EN (1 << 13) /* Bit 13: Determines PB.2 function */ +#define GCR_ALT_MFP_EBI_NWRH_WN (1 << 14) /* Bit 14: Determines PB.3 function */ +#define GCR_ALT_MFP_EBI_HB_EN0 (1 << 16) /* Bit 16: Determines PA.5 function */ +#define GCR_ALT_MFP_EBI_HB_EN1 (1 << 17) /* Bit 17: Determines PA.4 function */ +#define GCR_ALT_MFP_EBI_HB_EN2 (1 << 18) /* Bit 18: Determines PA.3 function */ +#define GCR_ALT_MFP_EBI_HB_EN3 (1 << 19) /* Bit 19: Determines PA.2 function */ +#define GCR_ALT_MFP_EBI_HB_EN4 (1 << 20) /* Bit 20: Determines PA.1 function */ +#define GCR_ALT_MFP_EBI_HB_EN5 (1 << 21) /* Bit 21: Determines PA.12 function */ +#define GCR_ALT_MFP_EBI_HB_EN6 (1 << 22) /* Bit 22: Determines PA.13 function */ +#define GCR_ALT_MFP_EBI_HB_EN7 (1 << 23) /* Bit 23: Determines PA.14 function */ + +/* Register write-protection control register */ + + /* Write: */ +#define GCR_REGWRPROT_MASK (0xff) /* Bits 0-7: Register write protection code */ +# define GCR_REGWRPROT_1 (0x59) /* Disable sequence */ +# define GCR_REGWRPROT_2 (0x16) +# define GCR_REGWRPROT_3 (0x88) + /* Read: */ +#define GCR_REGWRPROT_DIS (1 << 0) /* Bit 0: Register write protection disable index */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GCR_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_gpio.h b/arch/arm/src/nuc1xx/chip/nuc_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..7d99118e0e86b9300c5497e686c2da06df400e07 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_gpio.h @@ -0,0 +1,556 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GPIO_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GPIO_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + +#define NUC_GPIO_PORTA 0 +#define NUC_GPIO_PORTB 1 +#define NUC_GPIO_PORTC 2 +#define NUC_GPIO_PORTD 3 +#define NUC_GPIO_PORTE 4 + +#define NUC_GPIO_NPORTS 5 + +/* GPIO control registers */ + +#define NUC_GPIO_CTRL_OFFSET(n) (0x0000 + ((n) << 6)) +#define NUC_GPIOA_CTRL_OFFSET (0x0000 + ((NUC_GPIO_PORTA) << 6)) +#define NUC_GPIOB_CTRL_OFFSET (0x0000 + ((NUC_GPIO_PORTB) << 6)) +#define NUC_GPIOC_CTRL_OFFSET (0x0000 + ((NUC_GPIO_PORTC) << 6)) +#define NUC_GPIOD_CTRL_OFFSET (0x0000 + ((NUC_GPIO_PORTD) << 6)) +#define NUC_GPIOE_CTRL_OFFSET (0x0000 + ((NUC_GPIO_PORTE) << 6)) + +#define NUC_GPIO_PMD_OFFSET 0x0000 /* GPIO port pin I/O mode control */ +#define NUC_GPIO_OFFD_OFFSET 0x0004 /* GPIO port pin digital input path disable control */ +#define NUC_GPIO_DOUT_OFFSET 0x0008 /* GPIO port data output value */ +#define NUC_GPIO_DMASK_OFFSET 0x000c /* GPIO port data output write mask */ +#define NUC_GPIO_PIN_OFFSET 0x0010 /* GPIO port pin value */ +#define NUC_GPIO_DBEN_OFFSET 0x0014 /* GPIO port de-bounce enable */ +#define NUC_GPIO_IMD_OFFSET 0x0018 /* GPIO port interrupt mode control */ +#define NUC_GPIO_IEN_OFFSET 0x001c /* GPIO port interrupt enable */ +#define NUC_GPIO_ISRC_OFFSET 0x0020 /* GPIO port interrupt source flag */ + +/* GPIO port A control registers */ + +#define NUC_GPIOA_PMD_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_PMD_OFFSET) +#define NUC_GPIOA_OFFD_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_OFFD_OFFSET) +#define NUC_GPIOA_DOUT_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_DOUT_OFFSET) +#define NUC_GPIOA_DMASK_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_DMASK_OFFSET) +#define NUC_GPIOA_PIN_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_PIN_OFFSET) +#define NUC_GPIOA_DBEN_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_DBEN_OFFSET) +#define NUC_GPIOA_IMD_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_IMD_OFFSET) +#define NUC_GPIOA_IEN_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_IEN_OFFSET) +#define NUC_GPIOA_ISRC_OFFSET (NUC_GPIOA_CTRL_OFFSET+NUC_GPIO_ISRC_OFFSET) + +/* GPIO port B control registers */ + +#define NUC_GPIOB_PMD_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_PMD_OFFSET) +#define NUC_GPIOB_OFFD_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_OFFD_OFFSET) +#define NUC_GPIOB_DOUT_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_DOUT_OFFSET) +#define NUC_GPIOB_DMASK_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_DMASK_OFFSET) +#define NUC_GPIOB_PIN_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_PIN_OFFSET) +#define NUC_GPIOB_DBEN_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_DBEN_OFFSET) +#define NUC_GPIOB_IMD_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_IMD_OFFSET) +#define NUC_GPIOB_IEN_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_IEN_OFFSET) +#define NUC_GPIOB_ISRC_OFFSET (NUC_GPIOB_CTRL_OFFSET+NUC_GPIO_ISRC_OFFSET) + +/* GPIO port C control registers */ + +#define NUC_GPIOC_PMD_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_PMD_OFFSET) +#define NUC_GPIOC_OFFD_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_OFFD_OFFSET) +#define NUC_GPIOC_DOUT_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_DOUT_OFFSET) +#define NUC_GPIOC_DMASK_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_DMASK_OFFSET) +#define NUC_GPIOC_PIN_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_PIN_OFFSET) +#define NUC_GPIOC_DBEN_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_DBEN_OFFSET) +#define NUC_GPIOC_IMD_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_IMD_OFFSET) +#define NUC_GPIOC_IEN_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_IEN_OFFSET) +#define NUC_GPIOC_ISRC_OFFSET (NUC_GPIOC_CTRL_OFFSET+NUC_GPIO_ISRC_OFFSET) + +/* GPIO port D control registers */ + +#define NUC_GPIOD_PMD_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_PMD_OFFSET) +#define NUC_GPIOD_OFFD_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_OFFD_OFFSET) +#define NUC_GPIOD_DOUT_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_DOUT_OFFSET) +#define NUC_GPIOD_DMASK_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_DMASK_OFFSET) +#define NUC_GPIOD_PIN_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_PIN_OFFSET) +#define NUC_GPIOD_DBEN_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_DBEN_OFFSET) +#define NUC_GPIOD_IMD_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_IMD_OFFSET) +#define NUC_GPIOD_IEN_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_IEN_OFFSET) +#define NUC_GPIOD_ISRC_OFFSET (NUC_GPIOD_CTRL_OFFSET+NUC_GPIO_ISRC_OFFSET) + +/* GPIO port E control registers */ + +#define NUC_GPIOE_PMD_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_PMD_OFFSET) +#define NUC_GPIOE_OFFD_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_OFFD_OFFSET) +#define NUC_GPIOE_DOUT_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_DOUT_OFFSET) +#define NUC_GPIOE_DMASK_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_DMASK_OFFSET) +#define NUC_GPIOE_PIN_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_PIN_OFFSET) +#define NUC_GPIOE_DBEN_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_DBEN_OFFSET) +#define NUC_GPIOE_IMD_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_IMD_OFFSET) +#define NUC_GPIOE_IEN_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_IEN_OFFSET) +#define NUC_GPIOE_ISRC_OFFSET (NUC_GPIOE_CTRL_OFFSET+NUC_GPIO_ISRC_OFFSET) + +/* Debounce control registers */ + +#define NUC_GPIO_DBNCECON_OFFSEt 0x0180 /* De-bounce cycle control register */ + +/* GPIO port data I/O register offsets */ + +#define NUC_PORT_DATAIO_OFFSET(p) (0x0200 + ((p)<< 6)) +# define NUC_PORTA_DATAIO_OFFSET (0x0200 + ((NUC_GPIO_PORTA) << 6)) +# define NUC_PORTB_DATAIO_OFFSET (0x0200 + ((NUC_GPIO_PORTB) << 6)) +# define NUC_PORTC_DATAIO_OFFSET (0x0200 + ((NUC_GPIO_PORTC) << 6)) +# define NUC_PORTD_DATAIO_OFFSET (0x0200 + ((NUC_GPIO_PORTD) << 6)) +# define NUC_PORTE_DATAIO_OFFSET (0x0200 + ((NUC_GPIO_PORTE) << 6)) + +/* GPIO port pin data I/O register offsets */ + +#define NUC_PORT_PIN_OFFSET(n) ((n) << 2) +# define NUC_PORT_PIN0_OFFSET (0 << 2) +# define NUC_PORT_PIN1_OFFSET (1 << 2) +# define NUC_PORT_PIN2_OFFSET (2 << 2) +# define NUC_PORT_PIN3_OFFSET (3 << 2) +# define NUC_PORT_PIN4_OFFSET (4 << 2) +# define NUC_PORT_PIN5_OFFSET (5 << 2) +# define NUC_PORT_PIN6_OFFSET (16 << 2) +# define NUC_PORT_PIN7_OFFSET (17 << 2) +# define NUC_PORT_PIN8_OFFSET (18 << 2) +# define NUC_PORT_PIN9_OFFSET (19 << 2) +# define NUC_PORT_PIN10_OFFSET (10 << 2) +# define NUC_PORT_PIN11_OFFSET (11 << 2) +# define NUC_PORT_PIN12_OFFSET (12 << 2) +# define NUC_PORT_PIN13_OFFSET (13 << 2) +# define NUC_PORT_PIN14_OFFSET (14 << 2) +# define NUC_PORT_PIN15_OFFSET (15 << 2) + +#define NUC_PORT_PDIO_OFFSET(p,n) (NUC_PORT_DATAIO_OFFSET(p)+NUC_PORT_PIN_OFFSET(n)) + +/* GPIO PA Pin Data Input/Output */ + +#define NUC_PORTA_PDIO_OFFSET(n) (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN_OFFSET(n)) +# define NUC_PA1_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA2_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA3_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA4_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA5_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA6_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA7_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA8_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA9_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA10_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA11_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA12_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA13_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA14_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PA15_PDIO_OFFSET (NUC_PORTA_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) + +/* GPIO PB Pin Data Input/Output */ + +#define NUC_PORTB_PDIO_OFFSET(n) (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN_OFFSET(n)) +# define NUC_PB1_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB2_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB3_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB4_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB5_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB6_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB7_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB8_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB9_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB10_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB11_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB12_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB13_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB14_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PB15_PDIO_OFFSET (NUC_PORTB_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) + +/* GPIO PC Pin Data Input/Output */ + +#define NUC_PORTC_PDIO_OFFSET(n) (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN_OFFSET(n)) +# define NUC_PC1_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC2_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC3_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC4_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC5_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC6_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC7_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC8_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC9_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC10_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC11_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC12_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC13_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC14_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PC15_PDIO_OFFSET (NUC_PORTC_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) + +/* GPIO PD Pin Data Input/Output */ + +#define NUC_PORTD_PDIO_OFFSET(n) (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN_OFFSET(n)) +# define NUC_PD1_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD2_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD3_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD4_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD5_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD6_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD7_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD8_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD9_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD10_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD11_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD12_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD13_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD14_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) +# define NUC_PD15_PDIO_OFFSET (NUC_PORTD_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) + +/* GPIO PE Pin Data Input/Output */ + +#define NUC_PORTE_PDIO_OFFSET(n) (NUC_PORTE_DATAIO_OFFSET+NUC_PORT_PIN_OFFSET(n)) +# define NUC_PE5_PDIO_OFFSET (NUC_PORTE_DATAIO_OFFSET+NUC_PORT_PIN0_OFFSET) + +/* Register addresses ***********************************************************************/ + +/* GPIO control registers */ + +#define NUC_GPIO_CTRL_BASE(n) (NUC_GPIO_BASE+NUC_GPIO_CTRL_OFFSET(n)) +#define NUC_GPIOA_CTRL_BASE (NUC_GPIO_BASE+NUC_GPIOA_CTRL_OFFSET) +#define NUC_GPIOB_CTRL_BASE (NUC_GPIO_BASE+NUC_GPIOB_CTRL_OFFSET) +#define NUC_GPIOC_CTRL_BASE (NUC_GPIO_BASE+NUC_GPIOC_CTRL_OFFSET) +#define NUC_GPIOD_CTRL_BASE (NUC_GPIO_BASE+NUC_GPIOD_CTRL_OFFSET) +#define NUC_GPIOE_CTRL_BASE (NUC_GPIO_BASE+NUC_GPIOE_CTRL_OFFSET) + +/* GPIO port A control registers */ + +#define NUC_GPIOA_PMD (NUC_GPIO_BASE+NUC_GPIOA_PMD_OFFSET) +#define NUC_GPIOA_OFFD (NUC_GPIO_BASE+NUC_GPIOA_OFFD_OFFSET) +#define NUC_GPIOA_DOUT (NUC_GPIO_BASE+NUC_GPIOA_DOUT_OFFSET) +#define NUC_GPIOA_DMASK (NUC_GPIO_BASE+NUC_GPIOA_DMASK_OFFSET) +#define NUC_GPIOA_PIN (NUC_GPIO_BASE+NUC_GPIOA_PIN_OFFSET) +#define NUC_GPIOA_DBEN (NUC_GPIO_BASE+NUC_GPIOA_DBEN_OFFSET) +#define NUC_GPIOA_IMD (NUC_GPIO_BASE+NUC_GPIOA_IMD_OFFSET) +#define NUC_GPIOA_IEN (NUC_GPIO_BASE+NUC_GPIOA_IEN_OFFSET) +#define NUC_GPIOA_ISRC (NUC_GPIO_BASE+NUC_GPIOA_ISRC_OFFSET) + +/* GPIO port B control registers */ + +#define NUC_GPIOB_PMD (NUC_GPIO_BASE+NUC_GPIOB_PMD_OFFSET) +#define NUC_GPIOB_OFFD (NUC_GPIO_BASE+NUC_GPIOB_OFFD_OFFSET) +#define NUC_GPIOB_DOUT (NUC_GPIO_BASE+NUC_GPIOB_DOUT_OFFSET) +#define NUC_GPIOB_DMASK (NUC_GPIO_BASE+NUC_GPIOB_DMASK_OFFSET) +#define NUC_GPIOB_PIN (NUC_GPIO_BASE+NUC_GPIOB_PIN_OFFSET) +#define NUC_GPIOB_DBEN (NUC_GPIO_BASE+NUC_GPIOB_DBEN_OFFSET) +#define NUC_GPIOB_IMD (NUC_GPIO_BASE+NUC_GPIOB_IMD_OFFSET) +#define NUC_GPIOB_IEN (NUC_GPIO_BASE+NUC_GPIOB_IEN_OFFSET) +#define NUC_GPIOB_ISRC (NUC_GPIO_BASE+NUC_GPIOB_ISRC_OFFSET) + +/* GPIO port C control registers */ + +#define NUC_GPIOC_PMD (NUC_GPIO_BASE+NUC_GPIOC_PMD_OFFSET) +#define NUC_GPIOC_OFFD (NUC_GPIO_BASE+NUC_GPIOC_OFFD_OFFSET) +#define NUC_GPIOC_DOUT (NUC_GPIO_BASE+NUC_GPIOC_DOUT_OFFSET) +#define NUC_GPIOC_DMASK (NUC_GPIO_BASE+NUC_GPIOC_DMASK_OFFSET) +#define NUC_GPIOC_PIN (NUC_GPIO_BASE+NUC_GPIOC_PIN_OFFSET) +#define NUC_GPIOC_DBEN (NUC_GPIO_BASE+NUC_GPIOC_DBEN_OFFSET) +#define NUC_GPIOC_IMD (NUC_GPIO_BASE+NUC_GPIOC_IMD_OFFSET) +#define NUC_GPIOC_IEN (NUC_GPIO_BASE+NUC_GPIOC_IEN_OFFSET) +#define NUC_GPIOC_ISRC (NUC_GPIO_BASE+NUC_GPIOC_ISRC_OFFSET) + +/* GPIO port D control registers */ + +#define NUC_GPIOD_PMD (NUC_GPIO_BASE+NUC_GPIOD_PMD_OFFSET) +#define NUC_GPIOD_OFFD (NUC_GPIO_BASE+NUC_GPIOD_OFFD_OFFSET) +#define NUC_GPIOD_DOUT (NUC_GPIO_BASE+NUC_GPIOD_DOUT_OFFSET) +#define NUC_GPIOD_DMASK (NUC_GPIO_BASE+NUC_GPIOD_DMASK_OFFSET) +#define NUC_GPIOD_PIN (NUC_GPIO_BASE+NUC_GPIOD_PIN_OFFSET) +#define NUC_GPIOD_DBEN (NUC_GPIO_BASE+NUC_GPIOD_DBEN_OFFSET) +#define NUC_GPIOD_IMD (NUC_GPIO_BASE+NUC_GPIOD_IMD_OFFSET) +#define NUC_GPIOD_IEN (NUC_GPIO_BASE+NUC_GPIOD_IEN_OFFSET) +#define NUC_GPIOD_ISRC (NUC_GPIO_BASE+NUC_GPIOD_ISRC_OFFSET) + +/* GPIO port E control registers */ + +#define NUC_GPIOE_PMD (NUC_GPIO_BASE+NUC_GPIOE_PMD_OFFSET) +#define NUC_GPIOE_OFFD (NUC_GPIO_BASE+NUC_GPIOE_OFFD_OFFSET) +#define NUC_GPIOE_DOUT (NUC_GPIO_BASE+NUC_GPIOE_DOUT_OFFSET) +#define NUC_GPIOE_DMASK (NUC_GPIO_BASE+NUC_GPIOE_DMASK_OFFSET) +#define NUC_GPIOE_PIN (NUC_GPIO_BASE+NUC_GPIOE_PIN_OFFSET) +#define NUC_GPIOE_DBEN (NUC_GPIO_BASE+NUC_GPIOE_DBEN_OFFSET) +#define NUC_GPIOE_IMD (NUC_GPIO_BASE+NUC_GPIOE_IMD_OFFSET) +#define NUC_GPIOE_IEN (NUC_GPIO_BASE+NUC_GPIOE_IEN_OFFSET) +#define NUC_GPIOE_ISRC (NUC_GPIO_BASE+NUC_GPIOE_ISRC_OFFSET) + +/* Debounce control registers */ + +#define NUC_GPIO_DBNCECON (NUC_GPIO_BASE+NUC_GPIO_DBNCECON_OFFSET) + +/* GPIO port data I/O register offsets */ + +#define NUC_PORT_DATAIO_BASE(p) (NUC_GPIO_BASE+NUC_PORT_DATAIO_OFFSET(p)) +# define NUC_PORTA_DATAIO_BASE (NUC_GPIO_BASE+NUC_PORTA_DATAIO_OFFSET) +# define NUC_PORTB_DATAIO_BASE (NUC_GPIO_BASE+NUC_PORTB_DATAIO_OFFSET) +# define NUC_PORTC_DATAIO_BASE (NUC_GPIO_BASE+NUC_PORTC_DATAIO_OFFSET) +# define NUC_PORTD_DATAIO_BASE (NUC_GPIO_BASE+NUC_PORTD_DATAIO_OFFSET) +# define NUC_PORTE_DATAIO_BASE (NUC_GPIO_BASE+NUC_PORTE_DATAIO_OFFSET) + +#define NUC_PORT_PDIO(p,n) (NUC_GPIO_BASE+NUC_PORT_PDIO_OFFSET(p,n)) + +/* GPIO PA Pin Data Input/Output */ + +#define NUC_PORTA_PDIO(n) (NUC_GPIO_BASE+NUC_PORTA_PDIO_OFFSET(n)) +# define NUC_PA1_PDIO (NUC_GPIO_BASE+NUC_PA1_PDIO_OFFSET) +# define NUC_PA2_PDIO (NUC_GPIO_BASE+NUC_PA2_PDIO_OFFSET) +# define NUC_PA3_PDIO (NUC_GPIO_BASE+NUC_PA3_PDIO_OFFSET) +# define NUC_PA4_PDIO (NUC_GPIO_BASE+NUC_PA4_PDIO_OFFSET) +# define NUC_PA5_PDIO (NUC_GPIO_BASE+NUC_PA5_PDIO_OFFSET) +# define NUC_PA6_PDIO (NUC_GPIO_BASE+NUC_PA6_PDIO_OFFSET) +# define NUC_PA7_PDIO (NUC_GPIO_BASE+NUC_PA7_PDIO_OFFSET) +# define NUC_PA8_PDIO (NUC_GPIO_BASE+NUC_PA8_PDIO_OFFSET) +# define NUC_PA9_PDIO (NUC_GPIO_BASE+NUC_PA9_PDIO_OFFSET) +# define NUC_PA10_PDIO (NUC_GPIO_BASE+NUC_PA10_PDIO_OFFSET) +# define NUC_PA11_PDIO (NUC_GPIO_BASE+NUC_PA11_PDIO_OFFSET) +# define NUC_PA12_PDIO (NUC_GPIO_BASE+NUC_PA12_PDIO_OFFSET) +# define NUC_PA13_PDIO (NUC_GPIO_BASE+NUC_PA13_PDIO_OFFSET) +# define NUC_PA14_PDIO (NUC_GPIO_BASE+NUC_PA14_PDIO_OFFSET) +# define NUC_PA15_PDIO (NUC_GPIO_BASE+NUC_PA15_PDIO_OFFSET) + +/* GPIO PB Pin Data Input/Output */ + +#define NUC_PORTB_PDIO(n) (NUC_GPIO_BASE+NUC_PORTB_PDIO_OFFSET(n)) +# define NUC_PB1_PDIO (NUC_GPIO_BASE+NUC_PB1_PDIO_OFFSET) +# define NUC_PB2_PDIO (NUC_GPIO_BASE+NUC_PB2_PDIO_OFFSET) +# define NUC_PB3_PDIO (NUC_GPIO_BASE+NUC_PB3_PDIO_OFFSET) +# define NUC_PB4_PDIO (NUC_GPIO_BASE+NUC_PB4_PDIO_OFFSET) +# define NUC_PB5_PDIO (NUC_GPIO_BASE+NUC_PB5_PDIO_OFFSET) +# define NUC_PB6_PDIO (NUC_GPIO_BASE+NUC_PB6_PDIO_OFFSET) +# define NUC_PB7_PDIO (NUC_GPIO_BASE+NUC_PB7_PDIO_OFFSET) +# define NUC_PB8_PDIO (NUC_GPIO_BASE+NUC_PB8_PDIO_OFFSET) +# define NUC_PB9_PDIO (NUC_GPIO_BASE+NUC_PB9_PDIO_OFFSET) +# define NUC_PB10_PDIO (NUC_GPIO_BASE+NUC_PB10_PDIO_OFFSET) +# define NUC_PB11_PDIO (NUC_GPIO_BASE+NUC_PB11_PDIO_OFFSET) +# define NUC_PB12_PDIO (NUC_GPIO_BASE+NUC_PB12_PDIO_OFFSET) +# define NUC_PB13_PDIO (NUC_GPIO_BASE+NUC_PB13_PDIO_OFFSET) +# define NUC_PB14_PDIO (NUC_GPIO_BASE+NUC_PB14_PDIO_OFFSET) +# define NUC_PB15_PDIO (NUC_GPIO_BASE+NUC_PB15_PDIO_OFFSET) + +/* GPIO PC Pin Data Input/Output */ + +#define NUC_PORTC_PDIO(n) (NUC_GPIO_BASE+NUC_PORTC_PDIO_OFFSET(n)) +# define NUC_PC1_PDIO (NUC_GPIO_BASE+NUC_PC1_PDIO_OFFSET) +# define NUC_PC2_PDIO (NUC_GPIO_BASE+NUC_PC2_PDIO_OFFSET) +# define NUC_PC3_PDIO (NUC_GPIO_BASE+NUC_PC3_PDIO_OFFSET) +# define NUC_PC4_PDIO (NUC_GPIO_BASE+NUC_PC4_PDIO_OFFSET) +# define NUC_PC5_PDIO (NUC_GPIO_BASE+NUC_PC5_PDIO_OFFSET) +# define NUC_PC6_PDIO (NUC_GPIO_BASE+NUC_PC6_PDIO_OFFSET) +# define NUC_PC7_PDIO (NUC_GPIO_BASE+NUC_PC7_PDIO_OFFSET) +# define NUC_PC8_PDIO (NUC_GPIO_BASE+NUC_PC8_PDIO_OFFSET) +# define NUC_PC9_PDIO (NUC_GPIO_BASE+NUC_PC9_PDIO_OFFSET) +# define NUC_PC10_PDIO (NUC_GPIO_BASE+NUC_PC10_PDIO_OFFSET) +# define NUC_PC11_PDIO (NUC_GPIO_BASE+NUC_PC11_PDIO_OFFSET) +# define NUC_PC12_PDIO (NUC_GPIO_BASE+NUC_PC12_PDIO_OFFSET) +# define NUC_PC13_PDIO (NUC_GPIO_BASE+NUC_PC13_PDIO_OFFSET) +# define NUC_PC14_PDIO (NUC_GPIO_BASE+NUC_PC14_PDIO_OFFSET) +# define NUC_PC15_PDIO (NUC_GPIO_BASE+NUC_PC15_PDIO_OFFSET) + +/* GPIO PD Pin Data Input/Output */ + +#define NUC_PORTD_PDIO(n) (NUC_GPIO_BASE+NUC_PORTD_PDIO_OFFSET(n)) +# define NUC_PD1_PDIO (NUC_GPIO_BASE+NUC_PD1_PDIO_OFFSET) +# define NUC_PD2_PDIO (NUC_GPIO_BASE+NUC_PD2_PDIO_OFFSET) +# define NUC_PD3_PDIO (NUC_GPIO_BASE+NUC_PD3_PDIO_OFFSET) +# define NUC_PD4_PDIO (NUC_GPIO_BASE+NUC_PD4_PDIO_OFFSET) +# define NUC_PD5_PDIO (NUC_GPIO_BASE+NUC_PD5_PDIO_OFFSET) +# define NUC_PD6_PDIO (NUC_GPIO_BASE+NUC_PD6_PDIO_OFFSET) +# define NUC_PD7_PDIO (NUC_GPIO_BASE+NUC_PD7_PDIO_OFFSET) +# define NUC_PD8_PDIO (NUC_GPIO_BASE+NUC_PD8_PDIO_OFFSET) +# define NUC_PD9_PDIO (NUC_GPIO_BASE+NUC_PD9_PDIO_OFFSET) +# define NUC_PD10_PDIO (NUC_GPIO_BASE+NUC_PD10_PDIO_OFFSET) +# define NUC_PD11_PDIO (NUC_GPIO_BASE+NUC_PD11_PDIO_OFFSET) +# define NUC_PD12_PDIO (NUC_GPIO_BASE+NUC_PD12_PDIO_OFFSET) +# define NUC_PD13_PDIO (NUC_GPIO_BASE+NUC_PD13_PDIO_OFFSET) +# define NUC_PD14_PDIO (NUC_GPIO_BASE+NUC_PD14_PDIO_OFFSET) +# define NUC_PD15_PDIO (NUC_GPIO_BASE+NUC_PD15_PDIO_OFFSET) + +/* GPIO PE Pin Data Input/Output */ + +#define NUC_PORTE_PDIO(n) (NUC_GPIO_BASE+NUC_PORTE_PDIO_OFFSET(n)) +# define NUC_PE5_PDIO (NUC_GPIO_BASE+NUC_PE5_PDIO_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* GPIO port pin I/O mode control */ + +#define GPIO_PMD_INPUT 0 /* Input */ +#define GPIO_PMD_OUTPUT 1 /* Push-pull output */ +#define GPIO_PMD_OPENDRAIN 2 /* Open drain output */ +#define GPIO_PMD_BIDI 3 /* Quasi bi-directional */ + +#define GPIO_PMD_SHIFT(n) ((n) << 1) /* Bits 2n-2n+1: GPIOx Pin[n] mode control */ +#define GPIO_PMD_MASK(n) (3 << GPIO_PMD_SHIFT(n)) +# define GPIO_PMD(n,v) ((v) << GPIO_PMD_SHIFT(n)) + +#define GPIO_PMD0_SHIFT (0) /* Bits 0-1: GPIOx Pin0 mode control */ +#define GPIO_PMD0_MASK (3 << GPIO_PMD0_SHIFT) +# define GPIO_PMD0(v) ((v) << GPIO_PMD0_SHIFT) +#define GPIO_PMD1_SHIFT (2) /* Bits 2-3: GPIOx Pin1 mode control */ +#define GPIO_PMD1_MASK (3 << GPIO_PMD1_SHIFT) +# define GPIO_PMD1(v) ((v) << GPIO_PMD1_SHIFT) +#define GPIO_PMD2_SHIFT (4) /* Bits 4-5: GPIOx Pin2 mode control */ +#define GPIO_PMD2_MASK (3 << GPIO_PMD2_SHIFT) +# define GPIO_PMD2(v) ((v) << GPIO_PMD2_SHIFT) +#define GPIO_PMD3_SHIFT (6) /* Bits 6-7: GPIOx Pin3 mode control */ +#define GPIO_PMD3_MASK (3 << GPIO_PMD3_SHIFT) +# define GPIO_PMD3(v) ((v) << GPIO_PMD3_SHIFT) +#define GPIO_PMD4_SHIFT (8) /* Bits 8-9: GPIOx Pin4 mode control */ +#define GPIO_PMD4_MASK (3 << GPIO_PMD4_SHIFT) +# define GPIO_PMD4(v) ((v) << GPIO_PMD4_SHIFT) +#define GPIO_PMD5_SHIFT (10) /* Bits 10-11: GPIOx Pin5 mode control */ +#define GPIO_PMD5_MASK (3 << GPIO_PMD5_SHIFT) +# define GPIO_PMD5(v) ((v) << GPIO_PMD5_SHIFT) +#define GPIO_PMD6_SHIFT (12) /* Bits 12-13: GPIOx Pin6 mode control */ +#define GPIO_PMD6_MASK (3 << GPIO_PMD6_SHIFT) +# define GPIO_PMD6(v) ((v) << GPIO_PMD6_SHIFT) +#define GPIO_PMD7_SHIFT (14) /* Bits 14-15: GPIOx Pin7 mode control */ +#define GPIO_PMD7_MASK (3 << GPIO_PMD7_SHIFT) +# define GPIO_PMD7(v) ((v) << GPIO_PMD7_SHIFT) +#define GPIO_PMD8_SHIFT (16) /* Bits 16-17: GPIOx Pin8 mode control */ +#define GPIO_PMD8_MASK (3 << GPIO_PMD8_SHIFT) +# define GPIO_PMD8(v) ((v) << GPIO_PMD8_SHIFT) +#define GPIO_PMD9_SHIFT (18) /* Bits 18-19: GPIOx Pin9 mode control */ +#define GPIO_PMD9_MASK (3 << GPIO_PMD9_SHIFT) +# define GPIO_PMD9(v) ((v) << GPIO_PMD9_SHIFT) +#define GPIO_PMD10_SHIFT (20) /* Bits 20-21: GPIOx Pin0 mode control */ +#define GPIO_PMD10_MASK (3 << GPIO_PMD10_SHIFT) +# define GPIO_PMD10(v) ((v) << GPIO_PMD10_SHIFT) +#define GPIO_PMD11_SHIFT (22) /* Bits 22-23: GPIOx Pin1 mode control */ +#define GPIO_PMD11_MASK (3 << GPIO_PMD11_SHIFT) +# define GPIO_PMD11(v) ((v) << GPIO_PMD11_SHIFT) +#define GPIO_PMD12_SHIFT (24) /* Bits 24-25: GPIOx Pin2 mode control */ +#define GPIO_PMD12_MASK (3 << GPIO_PMD12_SHIFT) +# define GPIO_PMD12(v) ((v) << GPIO_PMD12_SHIFT) +#define GPIO_PMD13_SHIFT (26) /* Bits 26-27: GPIOx Pin3 mode control */ +#define GPIO_PMD13_MASK (3 << GPIO_PMD13_SHIFT) +# define GPIO_PMD13(v) ((v) << GPIO_PMD13_SHIFT) +#define GPIO_PMD14_SHIFT (28) /* Bits 28-29: GPIOx Pin4 mode control */ +#define GPIO_PMD14_MASK (3 << GPIO_PMD14_SHIFT) +# define GPIO_PMD14(v) ((v) << GPIO_PMD14_SHIFT) +#define GPIO_PMD15_SHIFT (30) /* Bits 30-31: GPIOx Pin5 mode control */ +#define GPIO_PMD15_MASK (3 << GPIO_PMD15_SHIFT) +# define GPIO_PMD15(v) ((v) << GPIO_PMD15_SHIFT) + +/* GPIO port pin digital input path disable control */ + +#define GPIO_OFFD(n) (1 << (n)) /* Bit n: GPIOx Pin[n] digital input path disable control */ + +/* GPIO port data output value */ + +#define GPIO_DOUT(n) (1 << (n)) /* Bit n: GPIOx Pin[n] output value */ + +/* GPIO port data output write mask */ + +#define GPIO_DMASK(n) (1 << (n)) /* Bit n: GPIOx Pin[n] data output write mask */ + +/* GPIO port pin value */ + +#define GPIO_PIN(n) (1 << (n)) /* Bit n: GPIOx Pin[n] pin value */ + +/* GPIO port de-bounce enable */ + +#define GPIO_DBEN(n) (1 << (n)) /* Bit n: GPIOx Pin[n] input signal de-bounce enable */ + +/* GPIO port interrupt mode control */ + +#define GPIO_IMD(n) (1 << (n)) /* Bit n: GPIOx Pin[n] edge/level detection interrupt control */ + +/* GPIO port interrupt enable */ + +#define GPIO_IF_EN(n) (1 << (n)) /* Bit n: GPIOx Pin[n] interrupt enable low/falling */ +#define GPIO_IR_EN(n) (1 << ((n)+16)) /* Bit n: GPIOx Pin[n] interrupt enable high/rising */ + +/* GPIO port interrupt source flag */ + +#define GPIO_ISRC(n) (1 << (n)) /* Bit n: GPIOx Pin[n] interrupt source flag */ + +/* De-bounce cycle control register */ + +#define GPIO_DBNCECON_DBCLKSEL_SHIFT (0) /* Bits 0-3: De-bounce cycling count selection */ +#define GPIO_DBNCECON_DBCLKSEL_MASK (15 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_1 (0 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_2 (1 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_4 (2 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_8 (3 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_16 (4 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_32 (5 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_64 (6 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_128 (7 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_256 (8 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_512 (9 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_1024 (10 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_2048 (11 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_4096 (12 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_8102 (13 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_16384 (14 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +# define GPIO_DBNCECON_DBCLKSEL_32768 (15 << GPIO_DBNCECON_DBCLKSEL_SHIFT) +#define GPIO_DBNCECON_DBCLKSRC (1 << 4) /* Bit 4: De-bounce counter clock source selection */ +#define GPIO_DBNCECON_ICLK_ON (1 << 5) /* Bit 5: Interrupt clock on mode */ + +/* GPIO port data I/O registers */ + +#define PORT_MASK (1) /* Bit 0: GPIOx Pin[n] data I/O */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_GPIO_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_i2c.h b/arch/arm/src/nuc1xx/chip/nuc_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..9b30e5797999c14c07d79cfce92da7052f49406c --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_i2c.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_i2c.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2C_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2C_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2C_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_i2s.h b/arch/arm/src/nuc1xx/chip/nuc_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..c94206324ace7888dd3355843bdc73b62c404524 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_i2s.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_i2s.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2S_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2S_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_I2S_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_memorymap.h b/arch/arm/src/nuc1xx/chip/nuc_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..4cdccfa727552ab927c3da2819af1ec3ccf786f1 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_memorymap.h @@ -0,0 +1,112 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_MEMORYMAP_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_MEMORYMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* System Memory Map */ + +#define NUC_FLASH_BASE 0x00000000 /* -0x0001ffff: FLASH memory space (128KB) */ +#define NUC_SRAM_BASE 0x20000000 /* -0x20003fff: SRAM memory space (16KB) */ +#define NUC_APB1_BASE 0x40000000 /* -0x400fffff: APB1 controller space */ +#define NUC_APB2_BASE 0x40100000 /* -0x401fffff: APB2 controller space */ +#define NUC_AHB_BASE 0x50000000 /* -0x501fffff: AHB controller space */ +#define NUC_EXTMEM_BASE 0x60000000 /* -0x6001ffff: External Memory space (128KB) */ +#define NUC_SYSCON_BASE 0x60000000 /* -0x6001ffff: ARMv6-M system controller space + * See nvic.h */ +/* FLASH space */ + +#define NUC_CONFIG_BASE 0x00300000 /* -0x00300004: User configuration */ + +/* AHB controller space */ + +#define NUC_GCR_BASE 0x50000000 /* -0x500001ff: System global control registers */ +#define NUC_CLK_BASE 0x50000200 /* -0x500002ff: Clock control registers */ +#define NUC_INT_BASE 0x50000300 /* -0x500003ff: Interrupt multiplexor control registers */ +#define NUC_GPIO_BASE 0x50004000 /* -0x50007fff: GPIO control registers */ +#define NUC_PDMA_BASE 0x50008000 /* -0x5000bfff: Peripheral DMA control registers */ +#define NUC_FMC_BASE 0x5000c000 /* -0x5000ffff: Flash memory control registers */ +#define NUC_EBI_BASE 0x50010000 /* -0x500103ff: External bus interface control registers */ + +/* APB1 controller space */ + +#define NUC_WDT_BASE 0x40004000 /* -0x40007fff: Watchdog timer control registers */ +#define NUC_RTC_BASE 0x40008000 /* -0x4000bfff: Real time clock (RTc) control registers */ +#define NUC_TMR01_BASE 0x40010000 /* -0x40013fff: Timer0/Timer0 control registers */ +#define NUC_I2C0_BASE 0x40020000 /* -0x40023fff: I2C interface control registers */ +#define NUC_SPI0_BASE 0x40030000 /* -0x40033fff: SPI0 master/slave control registers */ +#define NUC_SPI1_BASE 0x40034000 /* -0x40037fff: SPI1 master/slave control registers */ +#define NUC_PWMA_BASE 0x40040000 /* -0x40043fff: PWM0/1/2/3 control registers */ +#define NUC_UART0_BASE 0x40050000 /* -0x40053fff: UART0 control registers */ +#define NUC_USBD_BASE 0x40060000 /* -0x40063fff: USB 2.0 FS device controller registers */ +#define NUC_ACMP_BASE 0x400d0000 /* -0x400d3fff: Analog comparator control registers */ +#define NUC_ADC_BASE 0x400e0000 /* -0x400effff: Analog-digital-converter (ADC) control + * registers */ +/* APB2 controller space */ + +#define NUC_PS2_BASE 0x40100000 /* -0x40103fff: PS/2 interface control registers */ +#define NUC_TIMR23_BASE 0x40110000 /* -0x40113fff: Timer2/Timer3 control registers */ +#define NUC_I2C1_BASE 0x40120000 /* -0x40123fff: I2C1 interface control registers */ +#define NUC_SPI2_BASE 0x40130000 /* -0x40133fff: SPI2 master/slave control registers */ +#define NUC_SPI3_BASE 0x40134000 /* -0x40137fff: SPI3 master/slave control registers */ +#define NUC_PWMB_BASE 0x40140000 /* -0x40143fff: PWM4/5/6/7 control registers */ +#define NUC_UART1_BASE 0x40150000 /* -0x40153fff: UART1 control registers */ +#define NUC_UART2_BASE 0x40154000 /* -0x40157fff: UART2 control registers */ +#define NUC_I2S_BASE 0x401a0000 /* -0x401a3fff: I2S interface control registers */ + + /******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_MEMORYMAP_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_pdma.h b/arch/arm/src/nuc1xx/chip/nuc_pdma.h new file mode 100644 index 0000000000000000000000000000000000000000..964c01f0d5842d76a96a7dfeb5783e6d3cb00af4 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_pdma.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_pdma.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PDMA_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PDMA_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PDMA_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_ps2d.h b/arch/arm/src/nuc1xx/chip/nuc_ps2d.h new file mode 100644 index 0000000000000000000000000000000000000000..f011093324a436512a9fbba4e579a09f7ef9727c --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_ps2d.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_ps2d.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PS2D_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PS2D_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PS2D_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_pwm.h b/arch/arm/src/nuc1xx/chip/nuc_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..49f4f25a47f7c3d71a12bab686f89b283eaa68d7 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_pwm.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_pwm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PWM_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PWM_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_PWM_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_rtc.h b/arch/arm/src/nuc1xx/chip/nuc_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..1ec5e2baef2a0385902b194c9d1de6a6489f0307 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_rtc.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_rtc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_RTC_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_RTC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_RTC_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_spi.h b/arch/arm/src/nuc1xx/chip/nuc_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..74f46b1db5d4841db4896035f8b5228ee04f7a7d --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_spi.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_spi.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_SPI_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_SPI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_SPI_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_tmr.h b/arch/arm/src/nuc1xx/chip/nuc_tmr.h new file mode 100644 index 0000000000000000000000000000000000000000..e97615ce9405d12d19a6829cb2e8a202b944d234 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_tmr.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_tmr.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_TMR_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_TMR_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_TMR_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_uart.h b/arch/arm/src/nuc1xx/chip/nuc_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..18b0122b112e58dace87230085b8a3a6c636b8ea --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_uart.h @@ -0,0 +1,290 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_uart.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_UART_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_UART_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + +#define NUC_UART_RBR_OFFSET 0x0000 /* UART receive buffer register */ +#define NUC_UART_THR_OFFSET 0x0000 /* UART transmit holding register */ +#define NUC_UART_IER_OFFSET 0x0004 /* UART interrupt enable register */ +#define NUC_UART_FCR_OFFSET 0x0008 /* UART FIFO control register */ +#define NUC_UART_LCR_OFFSET 0x000c /* UART line control register */ +#define NUC_UART_MCR_OFFSET 0x0010 /* UART modem control register */ +#define NUC_UART_MSR_OFFSET 0x0014 /* UART modem status register */ +#define NUC_UART_FSR_OFFSET 0x0018 /* UART FIFO status register */ +#define NUC_UART_ISR_OFFSET 0x001c /* UART interrupt status register */ +#define NUC_UART_TOR_OFFSET 0x0020 /* UART time out register */ +#define NUC_UART_BAUD_OFFSET 0x0024 /* UART BAUD rate divisor register */ +#define NUC_UART_IRCR_OFFSET 0x0028 /* UART IrDA control register */ +#define NUC_UART_ALT_CSR_OFFSET 0x002c /* UART alternate control/status register */ +#define NUC_UART_FUN_SEL_OFFSET 0x0030 /* UART function select register */ + +/* Register addresses ***********************************************************************/ + +#define NUC_UART0_RBR (NUC_UART0_BASE+NUC_UART_RBR_OFFSET) +#define NUC_UART0_THR (NUC_UART0_BASE+NUC_UART_THR_OFFSET) +#define NUC_UART0_IER (NUC_UART0_BASE+NUC_UART_IER_OFFSET) +#define NUC_UART0_FCR (NUC_UART0_BASE+NUC_UART_FCR_OFFSET) +#define NUC_UART0_LCR (NUC_UART0_BASE+NUC_UART_LCR_OFFSET) +#define NUC_UART0_MCR (NUC_UART0_BASE+NUC_UART_MCR_OFFSET) +#define NUC_UART0_MSR (NUC_UART0_BASE+NUC_UART_MSR_OFFSET) +#define NUC_UART0_FSR (NUC_UART0_BASE+NUC_UART_FSR_OFFSET) +#define NUC_UART0_ISR (NUC_UART0_BASE+NUC_UART_ISR_OFFSET) +#define NUC_UART0_TOR (NUC_UART0_BASE+NUC_UART_TOR_OFFSET) +#define NUC_UART0_BAUD (NUC_UART0_BASE+NUC_UART_BAUD_OFFSET) +#define NUC_UART0_IRCR (NUC_UART0_BASE+NUC_UART_IRCR_OFFSET) +#define NUC_UART0_ALT_CSR (NUC_UART0_BASE+NUC_UART_ALT_CSR_OFFSET) +#define NUC_UART0_FUN_SEL (NUC_UART0_BASE+NUC_UART_FUN_SEL_OFFSET) + +#define NUC_UART1_RBR (NUC_UART1_BASE+NUC_UART_RBR_OFFSET) +#define NUC_UART1_THR (NUC_UART1_BASE+NUC_UART_THR_OFFSET) +#define NUC_UART1_IER (NUC_UART1_BASE+NUC_UART_IER_OFFSET) +#define NUC_UART1_FCR (NUC_UART1_BASE+NUC_UART_FCR_OFFSET) +#define NUC_UART1_LCR (NUC_UART1_BASE+NUC_UART_LCR_OFFSET) +#define NUC_UART1_MCR (NUC_UART1_BASE+NUC_UART_MCR_OFFSET) +#define NUC_UART1_MSR (NUC_UART1_BASE+NUC_UART_MSR_OFFSET) +#define NUC_UART1_FSR (NUC_UART1_BASE+NUC_UART_FSR_OFFSET) +#define NUC_UART1_ISR (NUC_UART1_BASE+NUC_UART_ISR_OFFSET) +#define NUC_UART1_TOR (NUC_UART1_BASE+NUC_UART_TOR_OFFSET) +#define NUC_UART1_BAUD (NUC_UART1_BASE+NUC_UART_BAUD_OFFSET) +#define NUC_UART1_IRCR (NUC_UART1_BASE+NUC_UART_IRCR_OFFSET) +#define NUC_UART1_ALT_CSR (NUC_UART1_BASE+NUC_UART_ALT_CSR_OFFSET) +#define NUC_UART1_FUN_SEL (NUC_UART1_BASE+NUC_UART_FUN_SEL_OFFSET) + +#define NUC_UART2_RBR (NUC_UART2_BASE+NUC_UART_RBR_OFFSET) +#define NUC_UART2_THR (NUC_UART2_BASE+NUC_UART_THR_OFFSET) +#define NUC_UART2_IER (NUC_UART2_BASE+NUC_UART_IER_OFFSET) +#define NUC_UART2_FCR (NUC_UART2_BASE+NUC_UART_FCR_OFFSET) +#define NUC_UART2_LCR (NUC_UART2_BASE+NUC_UART_LCR_OFFSET) +#define NUC_UART2_MCR (NUC_UART2_BASE+NUC_UART_MCR_OFFSET) +#define NUC_UART2_MSR (NUC_UART2_BASE+NUC_UART_MSR_OFFSET) +#define NUC_UART2_FSR (NUC_UART2_BASE+NUC_UART_FSR_OFFSET) +#define NUC_UART2_ISR (NUC_UART2_BASE+NUC_UART_ISR_OFFSET) +#define NUC_UART2_TOR (NUC_UART2_BASE+NUC_UART_TOR_OFFSET) +#define NUC_UART2_BAUD (NUC_UART2_BASE+NUC_UART_BAUD_OFFSET) +#define NUC_UART2_IRCR (NUC_UART2_BASE+NUC_UART_IRCR_OFFSET) +#define NUC_UART2_ALT_CSR (NUC_UART2_BASE+NUC_UART_ALT_CSR_OFFSET) +#define NUC_UART2_FUN_SEL (NUC_UART2_BASE+NUC_UART_FUN_SEL_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* UART receive buffer register */ + +#define UART_RBR_MASK (0xff) + +/* UART transmit holding register */ + +#define UART_THR_MASK (0xff) + +/* UART interrupt enable register */ + +#define UART_IER_RDA_IEN (1 << 0) /* Bit 0: Receive data avaiable interrupt enable */ +#define UART_IER_THRE_IEN (1 << 1) /* Bit 1: Transmit holding register empty interrupt enable */ +#define UART_IER_RLS_IEN (1 << 2) /* Bit 2: Receive line status interrupt enable */ +#define UART_IER_MODEM_IEN (1 << 3) /* Bit 3: Modem status interrupt enable (UART0/1) */ +#define UART_IER_RTO_IEN (1 << 4) /* Bit 4: RX timeout interrupt enable */ +#define UART_IER_BUF_ERR_IEN (1 << 5) /* Bit 5: Buffer error interrupt enable */ +#define UART_IER_WAKE_EN (1 << 6) /* Bit 6: UART wake-up function enable (UART0/1) */ +#define UART_IER_TIME_OUT_EN (1 << 11) /* Bit 11: Time out counter enable */ +#define UART_IER_AUTO_RTS_EN (1 << 12) /* Bit 12: RTS auto flow control enable (UART0/1) */ +#define UART_IER_AUTO_CTS_EN (1 << 13) /* Bit 13: CTS auto flow control enable (UART0/1) */ +#define UART_IER_DMA_TX_EN (1 << 14) /* Bit 14: TX DMA enable (UART0/1) */ +#define UART_IER_DMA_RX_EN (1 << 15) /* Bit 15: RX DMA enable (UART0/1) */ + +#define UART_IER_ALLIE (0x0000003f) +#define UART_IER_ALLBITS (0x0000f87f) + +/* UART FIFO control register */ + +#define UART_FCR_RFR (1 << 1) /* Bit 1: RX FIFO software reset */ +#define UART_FCR_TFR (1 << 2) /* Bit 2: TX FIFO software reset */ +#define UART_FCR_RFITL_SHIFT (4) /* Bits 4-7: RX FIFO interrupt trigger level */ +#define UART_FCR_RFITL_MASK (15 << UART_FCR_RFITL_SHIFT) +# define UART_FCR_RFITL_1 (0 << UART_FCR_RFITL_SHIFT) +# define UART_FCR_RFITL_4 (1 << UART_FCR_RFITL_SHIFT) +# define UART_FCR_RFITL_8 (2 << UART_FCR_RFITL_SHIFT) +# define UART_FCR_RFITL_14 (3 << UART_FCR_RFITL_SHIFT) +# define UART_FCR_RFITL_30 (4 << UART_FCR_RFITL_SHIFT) /* High speed */ +# define UART_FCR_RFITL_46 (5 << UART_FCR_RFITL_SHIFT) /* High speed */ +# define UART_FCR_RFITL_62 (6 << UART_FCR_RFITL_SHIFT) /* High speed */ +#define UART_FCR_RX_DIS (1 << 8) /* Bit 8: Recive disable register */ +#define UART_FCR_RTS_TRI_LEV_SHIFT (16) /* Bits 16-19: RTS trigger level for auto flow control */ +#define UART_FCR_RTS_TRI_LEV_MASK (15 << UART_FCR_RTS_TRI_LEV_SHIFT) +# define UART_FCR_RTS_TRI_LEV_1 (0 << UART_FCR_RTS_TRI_LEV_SHIFT) +# define UART_FCR_RTS_TRI_LEV_4 (1 << UART_FCR_RTS_TRI_LEV_SHIFT) +# define UART_FCR_RTS_TRI_LEV_8 (2 << UART_FCR_RTS_TRI_LEV_SHIFT) +# define UART_FCR_RTS_TRI_LEV_14 (3 << UART_FCR_RTS_TRI_LEV_SHIFT) +# define UART_FCR_RTS_TRI_LEV_30 (4 << UART_FCR_RTS_TRI_LEV_SHIFT) /* High speed */ +# define UART_FCR_RTS_TRI_LEV_46 (5 << UART_FCR_RTS_TRI_LEV_SHIFT) /* High speed */ +# define UART_FCR_RTS_TRI_LEV_62 (6 << UART_FCR_RTS_TRI_LEV_SHIFT) /* High speed */ + +/* UART line control register */ + +#define UART_LCR_WLS_SHIFT (0) /* Bits 0-1: Word length select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5 (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6 (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7 (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8 (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_NSB (1 << 2) /* Bit 2: Number of stop bits */ +#define UART_LCR_PBE (1 << 3) /* Bit 3: Parity enable bit */ +#define UART_LCR_EPE (1 << 4) /* Bit 4: Even parity enable bit */ +#define UART_LCR_SPE (1 << 5) /* Bit 5: Sticky parity enable bit */ +#define UART_LCR_BCB (1 << 6) /* Bit 6: Break control bit */ + +/* UART modem control register */ + +#define UART_MCR_RTS (1 << 1) /* Bit 1: RTS signal (UART0/1) */ +#define UART_MCR_LEV_RTS (1 << 9) /* Bit 9: RTS trigger level (UART0/1) */ +#define UART_MCR_RTS_ST (1 << 13) /* Bit 13: RTS pin state (UART0/1) */ + +/* UART modem status register */ + +#define UART_MSR_DCTSF (1 << 0) /* Bit 0: CTS state change detected (UART0/1) */ +#define UART_MSR_CTS_ST (1 << 4) /* Bit 4: CTS pin status (UART0/1) */ +#define UART_MSR_LEV_CTS (1 << 8) /* Bit 8: CTS trigger level (UART0/1) */ + +/* UART FIFO status register */ + +#define UART0_FIFO_DEPTH 64 +#define UART1_FIFO_DEPTH 16 +#define UART2_FIFO_DEPTH 16 + +#define UART_FSR_RX_OVER_IF (1 << 0) /* Bit 0: RX overflow error interrupt flag */ +#define UART_FSR_RS485_ADD_DETF (1 << 3) /* Bit 3: RS-485 address byte detection flag */ +#define UART_FSR_PEF (1 << 4) /* Bit 4: Parity error flag */ +#define UART_FSR_FEF (1 << 5) /* Bit 5: Framing error flag */ +#define UART_FSR_BIF (1 << 6) /* Bit 6: Break interrupt flag */ +#define UART_FSR_RX_POINTER_SHIFT (8) /* Bits 8-13: RX FIFO pointer */ +#define UART_FSR_RX_POINTER_MASK (0x3f << UART_FSR_RX_POINTER_SHIFT) +#define UART_FSR_RX_EMPTY (1 << 14) /* Bit 14: Receiver FIFO empty */ +#define UART_FSR_TX_POINTER_SHIFT (16) /* Bits 16-21: TX FIFO pointer */ +#define UART_FSR_TX_POINTER_MASK (0x3f << UART_FSR_TX_POINTER_SHIFT) +#define UART_FSR_TX_EMPTY (1 << 22) /* Bit 22: Transmitter FIFO empty flag */ +#define UART_FSR_TX_OVER_IF (1 << 24) /* Bit 24: TX overflow error interrupt flag */ +#define UART_FSR_TE_FLAG (1 << 28) /* Bit 28: Transmitter empty flag */ + +/* UART interrupt status register */ + +#define UART_ISR_RDA_IF (1 << 0) /* Bit 0: Receive data available interrupt flag */ +#define UART_ISR_THRE_IF (1 << 1) /* Bit 1: Transmit holding register empty interrupt flag */ +#define UART_ISR_RLS_IF (1 << 2) /* Bit 2: Receive line status interrupt flag */ +#define UART_ISR_MODEM_IF (1 << 3) /* Bit 3: Modem interrupt flag (UART0/1) */ +#define UART_ISR_TOUT_IF (1 << 4) /* Bit 4: Timeout interrupt flag */ +#define UART_ISR_BUF_ERR_IF (1 << 5) /* Bit 5: Buffer error interrupt flag */ +#define UART_ISR_RDA_INT (1 << 8) /* Bit 8: Receive data avaiable interrupt indicator */ +#define UART_ISR_THRE_INT (1 << 9) /* Bit 9: Transmit holding register empty interrupt indicator */ +#define UART_ISR_RLS_INT (1 << 10) /* Bit 10: Receive line status interrupt indicator */ +#define UART_ISR_MODEM_INT (1 << 11) /* Bit 11: Modem interrupt indicator (UART0/1) */ +#define UART_ISR_TOUT_INT (1 << 12) /* Bit 12: Timeout interrupt indicator */ +#define UART_ISR_BUF_ERR_INT (1 << 13) /* Bit 13: Buffer error interrupt indicator */ +#define UART_ISR_HW_RLS_IF (1 << 18) /* Bit 18: DMA mode receive line status interrupt flag */ +#define UART_ISR_HW_MODEM_IF (1 << 19) /* Bit 19: DMA mode modem interrupt flag (UART0/1) */ +#define UART_ISR_HW_TOUT_IF (1 << 20) /* Bit 20: DMA mode timeout interrupt flag */ +#define UART_ISR_HW_BUF_ERR_IF (1 << 21) /* Bit 21: DMA mode buffer error interrupt flag */ +#define UART_ISR_HW_RLS_INT (1 << 26) /* Bit 26: DMA mode receive line status interrupt indicator */ +#define UART_ISR_HW_MODEM_INT (1 << 27) /* Bit 27: DMA mode modem interrupt indicator (UART0/1) */ +#define UART_ISR_HW_TOUT_INT (1 << 28) /* Bit 28: DMA mode timeout interrupt indicator */ +#define UART_ISR_HW_BUF_ERR_INT (1 << 29) /* Bit 29: DMA mode buffer error interrupt indicator */ + +/* UART time out register */ + +#define UART_TOR_TOIC_SHIFT (0) /* Bits 0-7: Time out interrupt comparator */ +#define UART_TOR_TOIC_MASK (0xff << UART_TOR_TOIC_SHIFT) +# define UART_TOR_TOIC(t) ((t) << UART_TOR_TOIC_SHIFT) +#define UART_TOR_DLY_SHIFT (8) /* Bits 8-15: TX delay time value */ +#define UART_TOR_DLY_MASK (0xff << UART_TOR_DLY_SHIFT) +# define UART_TOR_DLY(d) ((d) << UART_TOR_DLY_SHIFT) + +/* UART BAUD rate divisor register */ + +#define UART_BAUD_BRD_SHIFT (0) /* Bits 0-15: Baud rate divider */ +#define UART_BAUD_BRD_MASK (0xffff << UART_BAUD_BRD_SHIFT) +# define UART_BAUD_BRD(b) ((b) << UART_BAUD_BRD_SHIFT) +#define UART_BAUD_DIVIDER_X_SHIFT (24) /* Bits 24-27: Divider X */ +#define UART_BAUD_DIVIDER_X_MASK (15 << UART_BAUD_DIVIDER_X_SHIFT) +# define UART_BAUD_DIVIDER_X(x) ((x) << UART_BAUD_DIVIDER_X_SHIFT) +#define UART_BAUD_DIV_X_ONE (1 << 28) /* Bit 28: Divider X equals one */ +#define UART_BAUD_DIV_X_EN (1 << 29) /* Bit 29: Divider X enable */ + +/* UART IrDA control register */ + +#define UART_IRCR_TX_SELECT (1 << 0) /* Bit 0: Invert RX input signal */ +#define UART_IRCR_INV_TX (1 << 1) /* Bit 1: Invert TX output signal */ +#define UART_IRCR_INV_RX (1 << 2) /* Bit 2: Enable IrDA transmitter */ + +/* UART alternate control/status register */ + +#define UART_ALT_CSR_RS485_NMM (1 << 8) /* Bit 8: RS-485 normal multi-drop operation mode (NMM) */ +#define UART_ALT_CSR_RS485_AAD (1 << 9) /* Bit 9: RS-485 auto address detection operation mode (AAD) */ +#define UART_ALT_CSR_RS485_AUD (1 << 10) /* Bit 10: RS-485 auto direction mode (AUD) */ +#define UART_ALT_CSR_RS485_ADD_EN (1 << 15) /* Bit 15: RS-485 address detection enable */ +#define UART_ALT_CSR_ADDR_MATCH_SHIFT (24) /* Bits 24-31: Address match value */ +#define UART_ALT_CSR_ADDR_MATCH_MASK (0xff << UART_ALT_CSR_ADDR_MATCH_SHIFT) + +/* UART function select register */ + +#define UART_FUN_SEL_SHIFT (0) /* Bits 0-1: Function select enable */ +#define UART_FUN_SEL_MASK (3 << UART_FUN_SEL_SHIFT) +# define UART_FUN_SEL_UART (0 << UART_FUN_SEL_SHIFT) +# define UART_FUN_SEL_IRDA (2 << UART_FUN_SEL_SHIFT) +# define UART_FUN_SEL_RS485 (3 << UART_FUN_SEL_SHIFT) /* Low density only */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_UART_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_usbd.h b/arch/arm/src/nuc1xx/chip/nuc_usbd.h new file mode 100644 index 0000000000000000000000000000000000000000..d950c3e8f7901bf111a841c755845f88dcf2882c --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_usbd.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_usbd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_USBD_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_USBD_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_USBD_H */ diff --git a/arch/arm/src/nuc1xx/chip/nuc_wdt.h b/arch/arm/src/nuc1xx/chip/nuc_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..458efe9774dbc9133b6abba0a4bba7fa31ce1ac6 --- /dev/null +++ b/arch/arm/src/nuc1xx/chip/nuc_wdt.h @@ -0,0 +1,71 @@ +/******************************************************************************************** + * arch/arm/src/nuc1xx/chip/nuc_wdt.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_WDT_H +#define __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_WDT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register offsets *************************************************************************/ + + +/* Register addresses ***********************************************************************/ + + +/* Register bit-field definitions ***********************************************************/ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_CHIP_NUC_WDT_H */ diff --git a/arch/arm/src/nuc1xx/nuc_clockconfig.c b/arch/arm/src/nuc1xx/nuc_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..95e4332ce7a67dcccc613f3c96fe6bddc38c8c5a --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_clockconfig.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_clockconfig.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "chip/chip/nuc_gcr.h" +#include "chip/chip/nuc_clk.h" + +#include "nuc_clockconfig.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_unlock + * + * Description: + * Unlock registers + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void nuc_unlock(void) +{ + putreg32(0x59, NUC_GCR_REGWRPROT); + putreg32(0x16, NUC_GCR_REGWRPROT); + putreg32(0x88, NUC_GCR_REGWRPROT); +} + +/**************************************************************************** + * Name: nuclock + * + * Description: + * Lok registers + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void nuc_lock(void) +{ + putreg32(0, NUC_GCR_REGWRPROT); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: nuc_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void nuc_clockconfig(void) +{ + uint32_t regval; + + /* Unlock registers */ + + nuc_unlock(); + + /* Enable External 4~24 mhz high speed crystal (And other clocks if needed by + * other drivers). + */ + + regval = getreg32(NUC_CLK_PWRCON); + regval |= CLK_PWRCON_XTL12M_EN; +#ifdef CONFIG_NUC_XTALLO + regval |= CLK_PWRCON_XTL32K_EN; +#endif +#ifdef CONFIG_NUC_INTHI + regval |= CLK_PWRCON_OSC22M_EN; +#endif + putreg32(regval, NUC_CLK_PWRCON); + + /* Delay to assure that crystal input to be stable */ + + up_mdelay(5); + + /* Set up the PLL configuration. + * + * Feedback divider (FB_DV) = Determined by settings in board.h + * Input divider (IN_DV) = Determined by settings in board.h + * Output divider (OUT_DV) = Determined by settings in board.h + * Power down mode (PD) = Normal mode (0) + * Bypass (BP) = Normal mode (0) + * FOUT enable (OE) = PLL FOUT enabled (0) + * PLL srouce clock (PLL_SRC) = External high speed crystal (0) + */ + + regval = getreg32(NUC_CLK_PLLCON); + regval &= ~(CLK_PLLCON_FB_DV_MASK | CLK_PLLCON_IN_DV_MASK | + CLK_PLLCON_OUT_DV_MASK | CLK_PLLCON_PD | CLK_PLLCON_BP | + CLK_PLLCON_OE | CLK_PLLCON_PLL_SRC); + regval |= (CLK_PLLCON_FB_DV(BOARD_PLL_FB_DV) | + CLK_PLLCON_IN_DV(BOARD_PLL_IN_DV) | + CLK_PLLCON_OUT_DV(BOARD_PLL_OUT_DV)); + putreg32(regval, NUC_CLK_PLLCON); + + /* Delay until the PLL output is stable */ + + up_mdelay(5); + + /* Set the HCLK divider per settings from the board.h file */ + + regval = getreg32(NUC_CLK_CLKDIV); + regval &= ~CLK_CLKDIV_HCLK_N_MASK; + regval |= CLK_CLKDIV_HCLK_N(BOARD_HCLK_N); + putreg32(regval, NUC_CLK_CLKDIV); + + /* Select the PLL output as the HCLKC source */ + + regval = getreg32(NUC_CLK_CLKSEL0); + regval &= ~CLK_CLKSEL0_HCLK_S_MASK; + regval |= CLK_CLKSEL0_HCLK_S_PLL; + putreg32(regval, NUC_CLK_CLKSEL0); + up_mdelay(1); + + /* Lock the registers */ + + nuc_lock(); +} diff --git a/arch/arm/src/nuc1xx/nuc_clockconfig.h b/arch/arm/src/nuc1xx/nuc_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..aaff547cfb2a306fff9cb7eb03d020c78fbe68df --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_clockconfig.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_clockconfig.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: nuc_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void nuc_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_CLOCKCONFIG_H */ diff --git a/arch/arm/src/nuc1xx/nuc_config.h b/arch/arm/src/nuc1xx/nuc_config.h new file mode 100644 index 0000000000000000000000000000000000000000..11f3e3f04eedb4553e986df5330a3a57a9f05d47 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_config.h @@ -0,0 +1,130 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_config.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_CONFIG_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Limit the number of enabled UARTs to those supported by the chip architecture */ + +#if NUC_NUARTS < 3 +# undef CONFIG_NUC_UART2 +#endif + +#if NUC_NUARTS < 2 +# undef CONFIG_NUC_UART1 +#endif + +#if NUC_NUARTS < 1 +# undef CONFIG_NUC_UART0 +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_NUC_UART0) || defined(CONFIG_NUC_UART1) || defined(CONFIG_NUC_UART2) +# define HAVE_UART 1 +#endif + +/* Make sure all features are disabled for diabled U[S]ARTs. This simplifies + * checking later. + */ + +#ifndef CONFIG_NUC_UART0 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART0_IRDAMODE +# undef CONFIG_UART0_RS485MODE +#endif + +#ifndef CONFIG_NUC_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART1_IRDAMODE +# undef CONFIG_UART1_RS485MODE +#endif + +#undef CONFIG_UART2_FLOWCONTROL /* UART2 does not support flow control */ +#ifndef CONFIG_NUC_UART2 +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART2_IRDAMODE +# undef CONFIG_UART2_RS485MODE +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2 - OR - there might not be any serial console at all. + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_CONFIG_H */ diff --git a/arch/arm/src/nuc1xx/nuc_dumpgpio.c b/arch/arm/src/nuc1xx/nuc_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..480bb4f588d3d96e51bbf284e81488dda38ff8ad --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_dumpgpio.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/arm/src/nuc/nuc_gpio.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "nuc_gpio.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Port letters for prettier debug output */ + +#ifdef CONFIG_DEBUG +static const char g_portchar[NUC_GPIO_NPORTS] = +{ +#if NUC_GPIO_NPORTS > 9 +# error "Additional support required for this number of GPIOs" +#elif NUC_GPIO_NPORTS > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif NUC_GPIO_NPORTS > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif NUC_GPIO_NPORTS > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif NUC_GPIO_NPORTS > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif NUC_GPIO_NPORTS > 4 + 'A', 'B', 'C', 'D', 'E' +#elif NUC_GPIO_NPORTS > 3 + 'A', 'B', 'C', 'D' +#elif NUC_GPIO_NPORTS > 2 + 'A', 'B', 'C' +#elif NUC_GPIO_NPORTS > 1 + 'A', 'B' +#elif NUC_GPIO_NPORTS > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: nuc_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin description + * along with a descriptive messasge. + * + ****************************************************************************/ + +void nuc_dumpgpio(gpio_cfgset_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + int port; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + base = NUC_GPIO_CTRL_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" PMD: %08x OFFD: %08x DOUT: %08x DMASK: %08x\n", + getreg32(base + NUC_GPIO_PMD_OFFSET), + getreg32(base + NUC_GPIO_OFFD_OFFSET), + getreg32(base + NUC_GPIO_DOUT_OFFSET), + getreg32(base + NUC_GPIO_DMASK_OFFSET)); + lldbg(" PIN: %08x DBEN: %08x IMD: %08x IEN: %08x\n", + getreg32(base + NUC_GPIO_PIN_OFFSET), + getreg32(base + NUC_GPIO_DBEN_OFFSET), + getreg32(base + NUC_GPIO_IMD_OFFSET), + getreg32(base + NUC_GPIO_IEN_OFFSET)); + lldbg(" ISRC: %08x\n", + getreg32(base + NUC_GPIO_ISRC_OFFSET)); + + leave_critical_section(flags); +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/nuc1xx/nuc_gpio.c b/arch/arm/src/nuc1xx/nuc_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..0e2b11d54c14f22cc81b67225f2a8be2491d82aa --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_gpio.c @@ -0,0 +1,310 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_gpio.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "chip/nuc_gpio.h" + +#include "nuc_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with nuc_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ****************************************************************************/ + +int nuc_configgpio(gpio_cfgset_t cfgset) +{ + uintptr_t base; + uint32_t regaddr; + uint32_t regval; + uint32_t isrc; + uint32_t imd; + uint32_t ien; + uint32_t value; + int port; + int pin; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + base = NUC_GPIO_CTRL_BASE(port); + + /* Set the GPIO PMD register */ + + regaddr = base + NUC_GPIO_PMD_OFFSET; + regval = getreg32(regaddr); + regval &= ~GPIO_PMD_MASK(pin); + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input */ + value = GPIO_PMD_INPUT; + break; + + case GPIO_OUTPUT: /* Push-pull output */ + value = GPIO_PMD_OUTPUT; + break; + + case GPIO_OPENDRAIN: /* Open drain output */ + value = GPIO_PMD_OPENDRAIN; + break; + + case GPIO_BIDI: /* Quasi bi-directional */ + value = GPIO_PMD_BIDI; + break; + } + + regval |= GPIO_PMD(pin, value); + putreg32(regval, regaddr); + + /* Check if we need to disable the digital input path */ + + regaddr = base + NUC_GPIO_OFFD_OFFSET; + regval = getreg32(regaddr); + regval &= ~GPIO_OFFD(pin); + + if ((cfgset & GPIO_ANALOG) != 0) + { + regval |= GPIO_OFFD(pin); + } + + putreg32(regval, regaddr); + + /* Check if we need to enable debouncing */ + + regaddr = base + NUC_GPIO_DBEN_OFFSET; + regval = getreg32(regaddr); + regval &= ~GPIO_DBEN(pin); + + if ((cfgset & GPIO_DEBOUNCE) != 0) + { + regval |= GPIO_DBEN(pin); + } + + putreg32(regval, regaddr); + + /* Configure interrupting pins */ + + isrc = getreg32(base + NUC_GPIO_ISRC_OFFSET); + isrc &= ~GPIO_ISRC(pin); + + imd = getreg32(base + NUC_GPIO_IMD_OFFSET); + imd &= ~GPIO_IMD(pin); + + ien = getreg32(base + NUC_GPIO_IEN_OFFSET); + ien &= ~(GPIO_IF_EN(pin) | GPIO_IR_EN(pin)); + + switch (cfgset & GPIO_INTERRUPT_MASK) + { + case GPIO_INTERRUPT_RISING_EDGE: + isrc |= GPIO_ISRC(pin); + ien |= GPIO_IR_EN(pin); + break; + + case GPIO_INTERRUPT_FALLING_EDGE: + isrc |= GPIO_ISRC(pin); + ien |= GPIO_IF_EN(pin); + break; + + case GPIO_INTERRUPT_BOTH_EDGES: + isrc |= GPIO_ISRC(pin); + ien |= (GPIO_IF_EN(pin) | GPIO_IR_EN(pin)); + break; + + case GPIO_INTERRUPT_HIGH_LEVEL: + isrc |= GPIO_ISRC(pin); + imd |= GPIO_IMD(pin); + ien |= GPIO_IR_EN(pin); + break; + + case GPIO_INTERRUPT_LOW_LEVEL: + isrc |= GPIO_ISRC(pin); + imd |= GPIO_IMD(pin); + ien |= GPIO_IF_EN(pin); + break; + + default: + break; + } + + putreg32(ien, base + NUC_GPIO_IEN_OFFSET); + putreg32(imd, base + NUC_GPIO_IMD_OFFSET); + putreg32(isrc, base + NUC_GPIO_ISRC_OFFSET); + + /* If the pin is an output, set the initial output value */ + + if ((cfgset & GPIO_MODE_MASK) == GPIO_OUTPUT) + { + nuc_gpiowrite(cfgset, (cfgset & GPIO_OUTPUT_SET) != 0); + } + + return 0; +} + +/**************************************************************************** + * Name: nuc_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void nuc_gpiowrite(gpio_cfgset_t pinset, bool value) +{ +#ifndef NUC_LOW + irqstate_t flags; + uintptr_t base; +#endif + int port; + int pin; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + + /* Only the low density NUC100/120 chips support bit-band access to GPIO + * pins. + */ + +#ifdef NUC_LOW + putreg32((uint32_t)value, NUC_PORT_PDIO(port, pin)); +#else + /* Get the base address of the GPIO port registers */ + + base = NUC_GPIO_CTRL_BASE(port); + + /* Disable interrupts -- the following operations must be atomic */ + + flags = enter_critical_section(); + + /* Allow writing only to the selected pin in the DOUT register */ + + putreg32(~(1 << pin), base + NUC_GPIO_DMASK_OFFSET); + + /* Set the pin to the selected value and re-enable interrupts */ + + putreg32(((uint32_t)value << pin), base + NUC_GPIO_DOUT_OFFSET); + leave_critical_section(flags); +#endif +} + +/**************************************************************************** + * Name: nuc_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool nuc_gpioread(gpio_cfgset_t pinset) +{ +#ifndef NUC_LOW + uintptr_t base; +#endif + int port; + int pin; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + + /* Only the low density NUC100/120 chips support bit-band access to GPIO + * pins. + */ + +#ifdef NUC_LOW + return (getreg32(NUC_PORT_PDIO(port, pin)) & PORT_MASK) != 0; +#else + /* Get the base address of the GPIO port registers */ + + base = NUC_GPIO_CTRL_BASE(port); + + /* Return the state of the selected pin */ + + return (getreg32(base + NUC_GPIO_PIN_OFFSET) & (1 << pin)) != 0; +#endif +} diff --git a/arch/arm/src/nuc1xx/nuc_gpio.h b/arch/arm/src/nuc1xx/nuc_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..52e9dd209506eb1c68801ffdd5a13b21ef635864 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_gpio.h @@ -0,0 +1,260 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_GPIO_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" +#include "chip/nuc_gpio.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +/* Bit-encoded input to nuc_configgpio() */ + +/* 16-bit Encoding: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * MMAD III. VPPP BBBB + */ + +/* GPIO mode: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * MM.. .... .... .... + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: GPIO mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Push-pull output */ +# define GPIO_OPENDRAIN (2 << GPIO_MODE_SHIFT) /* Open drain output */ +# define GPIO_BIDI (3 << GPIO_MODE_SHIFT) /* Quasi bi-directional */ + +/* GPIO analog: If the pin is an analog input, then it would be necessary to + * disable the digital input + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ..A. .... .... .... + */ + +#define GPIO_ANALOG (1 << 13) /* Bit 13: Disable digital input */ + +/* De-bounce enable: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ...D .... .... .... + */ + +#define GPIO_DEBOUNCE (1 << 12) /* Bit 12: Debounce enable */ + +/* Interrupt Controls: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... III. .... .... + */ + +#define GPIO_INTERRUPT_SHIFT (9) /* Bits 9-11: Interrupt controls */ +#define GPIO_INTERRUPT_MASK (7 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_NONE (0 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_RISING_EDGE (1 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_FALLING_EDGE (2 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_BOTH_EDGES (3 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_HIGH_LEVEL (4 << GPIO_INTERRUPT_SHIFT) +# define GPIO_INTERRUPT_LOW_LEVEL (5 << GPIO_INTERRUPT_SHIFT) + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... V... .... + */ + +#define GPIO_OUTPUT_SET (1 << 7) /* Bit 7: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... .PPP .... + */ + +#define GPIO_PORT_SHIFT 4 /* Bit 4-6: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# + +/* This identifies the bit in the port: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef uint16_t gpio_cfgset_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with nuc_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ****************************************************************************/ + +int nuc_configgpio(gpio_cfgset_t cfgset); + +/**************************************************************************** + * Name: nuc_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void nuc_gpiowrite(gpio_cfgset_t pinset, bool value); + +/**************************************************************************** + * Name: nuc_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool nuc_gpioread(gpio_cfgset_t pinset); + +/**************************************************************************** + * Function: nuc_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin description + * along with a descriptive messasge. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +void nuc_dumpgpio(gpio_cfgset_t pinset, const char *msg); +#else +# define nuc_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_GPIO_H */ diff --git a/arch/arm/src/nuc1xx/nuc_idle.c b/arch/arm/src/nuc1xx/nuc_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..9dd225313f948d8c90e4e62fb2466fb4f373d43c --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_idle.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_idle.c + * + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + nuc_pmstop(true); + break; + + case PM_SLEEP: + (void)nuc_pmstandby(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/nuc1xx/nuc_irq.c b/arch/arm/src/nuc1xx/nuc_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..0bdb86a8ee91758b9abe40595dc4197cf239cce5 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_irq.c @@ -0,0 +1,405 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_irq.c + * + * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "nuc_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | NVIC_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void nuc_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" ISER: %08x ICER: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); + lldbg(" ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), + getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), + getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); + + lldbg("SYSCON:\n"); + lldbg(" CPUID: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID)); + lldbg(" ICSR: %08x AIRCR: %08x\n", + getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); + lldbg(" SCR: %08x CCR: %08x\n", + getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); + lldbg(" SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#else +# define nuc_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: nuc_nmi, nuc_busfault, nuc_usagefault, nuc_pendsv, + * nuc_dbgmonitor, nuc_pendsv, nuc_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int nuc_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int nuc_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int nuc_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: nuc_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. + * + ****************************************************************************/ + +static inline void nuc_clrpend(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= NUC_IRQ_INTERRUPT && irq < NUC_IRQ_INTERRUPT + 32) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - NUC_IRQ_INTERRUPT)), ARMV6M_NVIC_ICPR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int i; + + /* Disable all interrupts */ + + putreg32(0xffffffff, ARMV6M_NVIC_ICER); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR2); + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR3); + + /* Now set all of the interrupt lines to the default priority */ + + for (i = 0; i < 8; i++) + { + regaddr = ARMV6M_NVIC_IPR(i); + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(NUC_IRQ_SVCALL, up_svcall); + irq_attach(NUC_IRQ_HARDFAULT, up_hardfault); + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(NUC_IRQ_NMI, nuc_nmi); + irq_attach(NUC_IRQ_PENDSV, nuc_pendsv); + irq_attach(NUC_IRQ_RESERVED, nuc_reserved); +#endif + + nuc_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= NUC_IRQ_INTERRUPT && irq < NUC_IRQ_INTERRUPT + 32) + { + /* Set the appropriate bit in the ICER register to disable the + * interrupt + */ + + putreg32((1 << (irq - NUC_IRQ_INTERRUPT)), ARMV6M_NVIC_ICER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == NUC_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, SYSTICK_CSR_ENABLE, 0); + } + + nuc_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= NUC_IRQ_INTERRUPT && irq < NUC_IRQ_INTERRUPT + 32) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - NUC_IRQ_INTERRUPT)), ARMV6M_NVIC_ISER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == NUC_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, 0, SYSTICK_CSR_ENABLE); + } + + nuc_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + nuc_clrpend(irq); +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq == NUC_IRQ_SVCALL || + irq == NUC_IRQ_PENDSV || + irq == NUC_IRQ_SYSTICK || + (irq >= NUC_IRQ_INTERRUPT && irq < NR_IRQS)); + DEBUGASSERT(priority >= NVIC_SYSH_PRIORITY_MAX && + priority <= NVIC_SYSH_PRIORITY_MIN); + + /* Check for external interrupt */ + + if (irq >= NUC_IRQ_INTERRUPT && irq < NUC_IRQ_INTERRUPT + 32) + { + /* ARMV6M_NVIC_IPR() maps register IPR0-IPR7 with four settings per + * register. + */ + + regaddr = ARMV6M_NVIC_IPR(irq >> 2); + shift = (irq & 3) << 3; + } + + /* Handle processor exceptions. Only SVCall, PendSV, and SysTick can be + * reprioritized. And we will not permit modification of SVCall through + * this function. + */ + + else if (irq == NUC_IRQ_PENDSV) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_14_SHIFT; + } + else if (irq == NUC_IRQ_SYSTICK) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_15_SHIFT; + } + else + { + return ERROR; + } + + /* Set the priority */ + + regval = getreg32(regaddr); + regval &= ~((uint32_t)0xff << shift); + regval |= ((uint32_t)priority << shift); + putreg32(regval, regaddr); + + nuc_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/nuc1xx/nuc_irq.h b/arch/arm/src/nuc1xx/nuc_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f475753bb45e0e063db6a44a4a97a7b1a22f0da0 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_irq.h @@ -0,0 +1,65 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_IRQ_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_IRQ_H */ diff --git a/arch/arm/src/nuc1xx/nuc_lowputc.c b/arch/arm/src/nuc1xx/nuc_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..be949b2c9a15057efbfdb72c3866f38952d84a56 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_lowputc.c @@ -0,0 +1,413 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_lowputc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "nuc_config.h" +#include "chip/chip/nuc_clk.h" +#include "chip/chip/nuc_uart.h" + +#include "chip/nuc_gcr.h" +#include "nuc_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Get the serial console UART configuration */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define NUC_CONSOLE_BASE NUC_UART0_BASE +# define NUC_CONSOLE_DEPTH UART0_FIFO_DEPTH +# define NUC_CONSOLE_BAUD CONFIG_UART0_BAUD +# define NUC_CONSOLE_BITS CONFIG_UART0_BITS +# define NUC_CONSOLE_PARITY CONFIG_UART0_PARITY +# define NUC_CONSOLE_2STOP CONFIG_UART0_2STOP +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define NUC_CONSOLE_BASE NUC_UART1_BASE +# define NUC_CONSOLE_DEPTH UART1_FIFO_DEPTH +# define NUC_CONSOLE_BAUD CONFIG_UART1_BAUD +# define NUC_CONSOLE_BITS CONFIG_UART1_BITS +# define NUC_CONSOLE_PARITY CONFIG_UART1_PARITY +# define NUC_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define NUC_CONSOLE_BASE NUC_UART2_BASE +# define NUC_CONSOLE_DEPTH UART2_FIFO_DEPTH +# define NUC_CONSOLE_BAUD CONFIG_UART2_BAUD +# define NUC_CONSOLE_BITS CONFIG_UART2_BITS +# define NUC_CONSOLE_PARITY CONFIG_UART2_PARITY +# define NUC_CONSOLE_2STOP CONFIG_UART2_2STOP +# endif +#endif + +/* Select either the external high speed crystal, the PLL output, or + * the internal high speed clock as the UART clock source. + */ + +#if defined(CONFIG_NUC_UARTCLK_XTALHI) +# define NUC_UART_CLK BOARD_XTALHI_FREQUENCY +#elif defined(CONFIG_NUC_UARTCLK_PLL) +# define NUC_UART_CLK BOARD_PLL_FOUT +#elif defined(CONFIG_NUC_UARTCLK_INTHI) +# define NUC_UART_CLK NUC_INTHI_FREQUENCY +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_console_ready + * + * Description: + * Wait until the console is ready to add another character to the TX + * FIFO. + * + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +static inline void nuc_console_ready(void) +{ +#if 1 + /* Wait for the TX FIFO to be empty (excessive!) */ + + while ((getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET) & UART_FSR_TX_EMPTY) == 0); +#else + uint32_t depth; + + /* Wait until there is space in the TX FIFO */ + + do + { + register uint32_t regval = getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET); + depth = (regval & UART_FSR_TX_POINTER_MASK) >> UART_FSR_TX_POINTER_SHIFT; + } + while (depth >= (NUC_CONSOLE_DEPTH-1)); +#endif +} +#endif /* HAVE_SERIAL_CONSOLE */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization. + * + ****************************************************************************/ + +void nuc_lowsetup(void) +{ +#ifdef HAVE_UART + uint32_t regval; + + /* Configure UART GPIO pins. + * + * Basic UART0 TX/RX requires that GPIOB MFP bits 0 and 1 be set. If flow + * control is enabled, then GPIOB MFP bits 3 and 4 must also be set and ALT + * MFP bits 11, 13, and 14 must be cleared. + */ + +#if defined(CONFIG_NUC_UART0) || defined(CONFIG_NUC_UART1) + regval = getreg32(NUC_GCR_GPB_MFP); + +#ifdef CONFIG_NUC_UART0 +#ifdef CONFIG_UART0_FLOWCONTROL + regval |= (GCR_GPB_MFP0 | GCR_GPB_MFP1 | GCR_GPB_MFP2 | GCR_GPB_MFP3); +#else + regval |= (GCR_GPB_MFP0 | GCR_GPB_MFP1); +#endif +#endif /* CONFIG_NUC_UART0 */ + + /* Basic UART1 TX/RX requires that GPIOB MFP bits 4 and 5 be set. If flow + * control is enabled, then GPIOB MFP bits 6 and 7 must also be set and ALT + * MFP bit 11 must be cleared. + */ + +#ifdef CONFIG_NUC_UART1 +#ifdef CONFIG_UART1_FLOWCONTROL + regval |= (GCR_GPB_MFP4 | GCR_GPB_MFP5 | GCR_GPB_MFP6 | GCR_GPB_MFP7) +#else + regval |= (GCR_GPB_MFP4 | GCR_GPB_MFP5); +#endif +#endif /* CONFIG_NUC_UART1 */ + + putreg32(regval, NUC_GCR_GPB_MFP); + +#if defined(CONFIG_UART0_FLOWCONTROL) || defined(CONFIG_UART1_FLOWCONTROL) + regval = getreg32(NUC_GCR_ALT_MFP); + regval &= ~GCR_ALT_MFP_EBI_EN; +#ifdef CONFIG_UART0_FLOWCONTROL + regval &= ~(GCR_ALT_MFP_EBI_NWRL_EN | GCR_ALT_MFP_EBI_NWRH_WN); +#endif + putreg32(NUC_GCR_ALT_MFP); +#endif /* CONFIG_UART0_FLOWCONTROL || CONFIG_UART1_FLOWCONTROL */ +#endif /* CONFIG_NUC_UART0 || CONFIG_NUC_UART1 */ + + /* UART1 TX/RX support requires that GPIOD bits 14 and 15 be set. UART2 + * does not support flow control. + */ + +#ifdef CONFIG_NUC_UART2 + regval = getreg32(NUC_GCR_GPD_MFP); + regval |= (GCR_GPD_MFP14 | GCR_GPD_MFP15); + putreg32(regval, NUC_GCR_GPD_MFP); +#endif /* CONFIG_NUC_UART2 */ + + /* Reset the UART peripheral(s) */ + + regval = getreg32(NUC_GCR_IPRSTC2); +#ifdef CONFIG_NUC_UART0 + regval |= GCR_IPRSTC2_UART0_RST; + putreg32(regval, NUC_GCR_IPRSTC2); + regval &= ~GCR_IPRSTC2_UART0_RST; + putreg32(regval, NUC_GCR_IPRSTC2); +#endif +#ifdef CONFIG_NUC_UART1 + regval |= GCR_IPRSTC2_UART1_RST; + putreg32(regval, NUC_GCR_IPRSTC2); + regval &= ~GCR_IPRSTC2_UART1_RST; + putreg32(regval, NUC_GCR_IPRSTC2); +#endif +#ifdef CONFIG_NUC_UART2 + regval |= GCR_IPRSTC2_UART2_RST; + putreg32(regval, NUC_GCR_IPRSTC2); + regval &= ~GCR_IPRSTC2_UART2_RST; + putreg32(regval, NUC_GCR_IPRSTC2); +#endif + + /* Configure the UART clock source. Set the UART clock source to either + * the external high speed crystal (CLKSEL1 reset value), the PLL output, + * or the internal high speed clock. + */ + + regval = getreg32(NUC_CLK_CLKSEL1); + regval &= ~CLK_CLKSEL1_UART_S_MASK; +#if defined(CONFIG_NUC_UARTCLK_XTALHI) + regval |= CLK_CLKSEL1_UART_S_XTALHI; +#elif defined(CONFIG_NUC_UARTCLK_PLL) + regval |= CLK_CLKSEL1_UART_S_PLL; +#elif defined(CONFIG_NUC_UARTCLK_INTHI) + regval |= CLK_CLKSEL1_UART_S_INTHI; +#endif + putreg32(regval, NUC_CLK_CLKSEL1); + + /* Enable UART clocking for the selected UARTs */ + + regval = getreg32(NUC_CLK_APBCLK); + regval &= ~(CLK_APBCLK_UART0_EN | CLK_APBCLK_UART1_EN | CLK_APBCLK_UART2_EN); + +#ifdef CONFIG_NUC_UART0 + regval |= CLK_APBCLK_UART0_EN; +#endif +#ifdef CONFIG_NUC_UART1 + regval |= CLK_APBCLK_UART1_EN; +#endif +#ifdef CONFIG_NUC_UART2 + regval |= CLK_APBCLK_UART2_EN; +#endif + + putreg32(regval, NUC_CLK_APBCLK); + + /* Configure the console UART */ + +#ifdef HAVE_SERIAL_CONSOLE + + /* Reset the TX FIFO */ + + regval = getreg32(NUC_CONSOLE_BASE + NUC_UART_FCR_OFFSET); + regval &= ~(UART_FCR_TFR | UART_FCR_RFR); + putreg32(regval | UART_FCR_TFR, NUC_CONSOLE_BASE + NUC_UART_FCR_OFFSET); + + /* Reset the RX FIFO */ + + putreg32(regval | UART_FCR_RFR, NUC_CONSOLE_BASE + NUC_UART_FCR_OFFSET); + + /* Set Rx Trigger Level */ + + regval &= ~UART_FCR_RFITL_MASK; + regval |= UART_FCR_RFITL_4; + putreg32(regval, NUC_CONSOLE_BASE + NUC_UART_FCR_OFFSET); + + /* Set Parity & Data bits and Stop bits */ + + regval = 0; +#if NUC_CONSOLE_BITS == 5 + regval |= UART_LCR_WLS_5; +#elif NUC_CONSOLE_BITS == 6 + regval |= UART_LCR_WLS_6; +#elif NUC_CONSOLE_BITS == 7 + regval |= UART_LCR_WLS_7; +#elif NUC_CONSOLE_BITS == 8 + regval |= UART_LCR_WLS_8; +#else + error "Unknown console UART data width" +#endif + +#if NUC_CONSOLE_PARITY == 1 + regval |= UART_LCR_PBE; +#elif NUC_CONSOLE_PARITY == 2 + regval |= (UART_LCR_PBE | UART_LCR_EPE); +#endif + +#if NUC_CONSOLE_2STOP != 0 + regval |= UART_LCR_NSB; +#endif + + putreg32(regval, NUC_CONSOLE_BASE + NUC_UART_LCR_OFFSET); + + /* Set Time-Out values */ + + regval = UART_TOR_TOIC(40) | UART_TOR_DLY(0); + putreg32(regval, NUC_CONSOLE_BASE + NUC_UART_TOR_OFFSET); + + /* Set the baud */ + + nuc_setbaud(NUC_CONSOLE_BASE, NUC_CONSOLE_BAUD); + +#endif /* HAVE_SERIAL_CONSOLE */ +#endif /* HAVE_UART */ +} + +/**************************************************************************** + * Name: nuc_lowputc + * + * Description: + * Output one character to the UART using a simple polling method. + * + ****************************************************************************/ + +void nuc_lowputc(uint32_t ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait for the TX FIFO to become available */ + + nuc_console_ready(); + + /* Then write the character to to the TX FIFO */ + + putreg32(ch, NUC_CONSOLE_BASE + NUC_UART_THR_OFFSET); +#endif /* HAVE_SERIAL_CONSOLE */ +} + +/**************************************************************************** + * Name: nuc_setbaud + * + * Description: + * Set the BAUD divxisor for the selected UART + * + * Mode DIV_X_EN DIV_X_ONE Divider X BRD (Baud rate equation) + * ------------------------------------------------------------- + * 0 0 0 B A UART_CLK / [16 * (A+2)] + * 1 1 0 B A UART_CLK / [(B+1) * (A+2)] , B must >= 8 + * 2 1 1 Don't care A UART_CLK / (A+2), A must >=3 + * + * Here we assume that the default clock source for the UART modules is + * the external high speed crystal. + * + ****************************************************************************/ + +#ifdef HAVE_UART +void nuc_setbaud(uintptr_t base, uint32_t baud) +{ + uint32_t regval; + uint32_t clksperbit; + uint32_t brd; + uint32_t divx; + + regval = getreg32(base + NUC_UART_BAUD_OFFSET); + + /* Mode 0: Source Clock mod 16 < 3 => Using Divider X = 16 */ + + clksperbit = (NUC_UART_CLK + (baud >> 1)) / baud; + if ((clksperbit & 15) < 3) + { + regval &= ~(UART_BAUD_DIV_X_ONE | UART_BAUD_DIV_X_EN); + brd = (clksperbit >> 4) - 2; + } + + /* Source Clock mod 16 >3 => Up 5% Error BaudRate */ + + else + { + /* Mode 2: Try to Set Divider X = 1 */ + + regval |= (UART_BAUD_DIV_X_ONE | UART_BAUD_DIV_X_EN); + brd = clksperbit - 2; + + /* Check if the divxider exceeds the range */ + + if (brd > 0xffff) + { + /* Mode 1: Try to Set Divider X up 10 */ + + regval &= ~UART_BAUD_DIV_X_ONE; + + for (divx = 8; divx < 16; divx++) + { + brd = clksperbit % (divx + 1); + if (brd < 3) + { + regval &= ~UART_BAUD_DIVIDER_X_MASK; + regval |= UART_BAUD_DIVIDER_X(divx); + + brd -= 2; + break; + } + } + } + } + + regval &= ~UART_BAUD_BRD_MASK; + regval |= UART_BAUD_BRD(brd); + putreg32(regval, base + NUC_UART_BAUD_OFFSET); +} +#endif /* HAVE_UART */ diff --git a/arch/arm/src/nuc1xx/nuc_lowputc.h b/arch/arm/src/nuc1xx/nuc_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..a6aab6cd72b645db5d3e95f84e4ccf0decf4078e --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_lowputc.h @@ -0,0 +1,121 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_LOWPUTC_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "nuc_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: nuc_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization. + * + ************************************************************************************/ + +void nuc_lowsetup(void); + +/**************************************************************************** + * Name: nuc_setbaud + * + * Description: + * Set the BAUD divxisor for the selected UART + * + * Mode DIV_X_EN DIV_X_ONE Divider X BRD (Baud rate equation) + * ------------------------------------------------------------- + * 0 Disable 0 B A UART_CLK / [16 * (A+2)] + * 1 Enable 0 B A UART_CLK / [(B+1) * (A+2)] , B must >= 8 + * 2 Enable 1 Don't care A UART_CLK / (A+2), A must >=3 + * + * Here we assume that the default clock source for the UART modules is + * the external high speed crystal. + * + ****************************************************************************/ + +#ifdef HAVE_UART +void nuc_setbaud(uintptr_t base, uint32_t baud); +#endif + +/**************************************************************************** + * Name: nuc_lowputc + * + * Description: + * Output one character to the UART using a simple polling method. + * + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void nuc_lowputc(uint32_t ch); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_LOWPUTC_H */ diff --git a/arch/arm/src/nuc1xx/nuc_serial.c b/arch/arm/src/nuc1xx/nuc_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..a098db77ce35c7cb69b9d561db051121a1da4f73 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_serial.c @@ -0,0 +1,1131 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_serial.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/nuc_uart.h" +#include "nuc_lowputc.h" +#include "nuc_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nuc_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-8) */ + uint8_t depth; /* RX/TX FIFO depth */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_NUC_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_NUC_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_NUC_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +/* This describes the state of the LPC17xx uart0 port. */ + +#ifdef CONFIG_NUC_UART0 +static struct nuc_dev_s g_uart0priv = +{ + .uartbase = NUC_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = NUC_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .depth = (UART0_FIFO_DEPTH-1), + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif /* CONFIG_NUC_UART0 */ + +/* This describes the state of the LPC17xx uart1 port. */ + +#ifdef CONFIG_NUC_UART1 +static struct nuc_dev_s g_uart1priv = +{ + .uartbase = NUC_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = NUC_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .depth = (UART1_FIFO_DEPTH-1), + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif /* CONFIG_NUC_UART1 */ + +/* This describes the state of the LPC17xx uart1 port. */ + +#ifdef CONFIG_NUC_UART2 +static struct nuc_dev_s g_uart2priv = +{ + .uartbase = NUC_UART2_BASE, + .baud = CONFIG_UART2_BAUD, + .irq = NUC_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .depth = (UART2_FIFO_DEPTH-1), + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif /* CONFIG_NUC_UART2 */ + +/* Which UART with be tty0/console and which tty1? tty2? The console, if it + * exists, will always be ttyS0. If there is no console then will use the + * lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-2 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_NUC_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_NUC_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_NUC_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any two of UART0-2 excluding the console UART. */ + +#if defined(CONFIG_NUC_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_NUC_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_NUC_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-2. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-2 could also be the + * console. + */ + +#if defined(CONFIG_NUC_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_NUC_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct nuc_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct nuc_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_setier + ****************************************************************************/ + +static uint32_t up_setier(struct nuc_dev_s *priv, + uint32_t clrbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t retval; + + /* Make sure that this is atomic */ + + flags = enter_critical_section(); + + /* Get the current IER setting */ + + retval = priv->ier; + + /* Modify and write the IER according to the inputs */ + + priv->ier &= ~clrbits; + priv->ier |= setbits; + up_serialout(priv, NUC_UART_IER_OFFSET, priv->ier); + leave_critical_section(flags); + + /* Return the value of the IER before modification */ + + return retval; +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct nuc_dev_s *priv, uint32_t *ier) +{ + *ier = up_setier(priv, UART_IER_ALLIE, 0); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct nuc_dev_s *priv, uint32_t ier) +{ + uint32_t setbits = ier & UART_IER_ALLIE; + uint32_t clrbits = (~ier) & UART_IER_ALLIE; + (void)up_setier(priv, clrbits, setbits); +} + +/**************************************************************************** + * Name: up_rxto_disable + ****************************************************************************/ + +static void up_rxto_disable(struct nuc_dev_s *priv) +{ + uint32_t regval; + + /* This function is called at initialization time and also when a timeout + * interrupt is received when the RX FIFO is empty. + * + * Set Rx Trigger Level so that an interrupt will be generated when the + * very next byte is received. + */ + + regval = up_serialin(priv, NUC_UART_FCR_OFFSET); + regval &= ~UART_FCR_RFITL_MASK; + regval |= UART_FCR_RFITL_1; + up_serialout(priv, NUC_UART_FCR_OFFSET, regval); + + /* Disable the RX timeout interrupt and disable the timeout */ + + (void)up_setier(priv, (UART_IER_RTO_IEN | UART_IER_TIME_OUT_EN), 0); +} + +/**************************************************************************** + * Name: up_rxto_enable + ****************************************************************************/ + +static void up_rxto_enable(struct nuc_dev_s *priv) +{ + uint32_t regval; + + /* This function is called after each RX interrupt. Data has been received + * and more may or may not be received. + * + * Set the RX FIFO level so that interrupts are only received when there + * are 8 or 14 bytes in the FIFO (depending on the UART FIFO depth). + */ + + regval = up_serialin(priv, NUC_UART_FCR_OFFSET); + regval &= ~UART_FCR_RFITL_MASK; +#if defined(CONFIG_NUC_UART0) +# if defined(CONFIG_NUC_UART0) || defined(CONFIG_NUC_UART0) + regval |= priv->depth > 16 ? UART_FCR_RFITL_14 : UART_FCR_RFITL_8; +# else + regval |= UART_FCR_RFITL_14; +# endif +#else + regval |= UART_FCR_RFITL_8; +#endif + up_serialout(priv, NUC_UART_FCR_OFFSET, regval); + + /* Enable the RX timeout interrupt and enable the timeout */ + + (void)up_setier(priv, 0, (UART_IER_RTO_IEN | UART_IER_TIME_OUT_EN)); +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + uint32_t regval; + + /* Reset the TX FIFO */ + + regval = up_serialin(priv, NUC_UART_FCR_OFFSET); + up_serialout(priv, NUC_UART_FCR_OFFSET, regval | UART_FCR_TFR); + + /* Reset the RX FIFO */ + + up_serialout(priv, NUC_UART_FCR_OFFSET, regval | UART_FCR_RFR); + + /* Set Rx Trigger Level */ + + regval &= ~(UART_FCR_RFITL_MASK | UART_FCR_TFR | UART_FCR_RFR); + regval |= UART_FCR_RFITL_1; + up_serialout(priv, NUC_UART_FCR_OFFSET, regval); + + /* Set Parity & Data bits and Stop bits */ + + regval = 0; + switch (priv->bits) + { + case 5: + regval |= UART_LCR_WLS_5; + break; + + case 6: + regval |= UART_LCR_WLS_6; + break; + + case 7: + regval |= UART_LCR_WLS_7; + break; + + default: + case 8: + regval |= UART_LCR_WLS_8; + break; + } + + switch (priv->parity) + { + default: + case 0: + break; + + case 1: + regval |= UART_LCR_PBE; + break; + + case 2: + regval |= (UART_LCR_PBE | UART_LCR_EPE); + break; + } + + if (priv->stopbits2) + { + regval |= UART_LCR_NSB; + } + + up_serialout(priv, NUC_UART_LCR_OFFSET, regval); + + /* Configure the RX timeout, but do not enable the interrupt yet */ + + regval = UART_TOR_TOIC(60) | UART_TOR_DLY(0); + up_serialout(priv, NUC_UART_TOR_OFFSET, regval); + + /* Set the baud */ + + nuc_setbaud(priv->uartbase, priv->baud); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, NUC_UART_IER_OFFSET); + + /* Enable Flow Control in the Modem Control Register */ + /* Not implemented */ + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct nuc_dev_s *priv; + uint32_t isr; + uint32_t regval; + int passes; + bool rxto; + bool rxfe; + +#ifdef CONFIG_NUC_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_NUC_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_NUC_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif + { + PANIC(); + } + priv = (struct nuc_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART interrupt status register (ISR) contents */ + + isr = up_serialin(priv, NUC_UART_ISR_OFFSET); + + /* Check if the RX FIFO is empty. Check if an RX timeout occur. These affect + * some later decisions. + */ + + rxfe = ((up_serialin(priv, NUC_UART_FSR_OFFSET) & UART_FSR_RX_EMPTY) != 0); + rxto = ((isr & UART_ISR_TOUT_INT) != 0); + + /* Check if the RX FIFO is filled to the threshold value OR if the RX + * timeout occurred with the FIFO non-empty. Both are cleared + * by reading from the RBR register. + */ + + if ((isr & UART_ISR_RDA_INT) != 0 || (rxto && !rxfe)) + { + uart_recvchars(dev); + } + + /* Enable or disable RX timeouts based on the state of RX FIFO: + * + * DISABLE: If the timeout occurred and the RX FIFO was empty. + * ENABLE: Data was in RX FIFO (may have been removed), RX interrupts + * are enabled, and the timeout is not already enabled. + */ + + if (rxto && rxfe) + { + /* A timeout interrupt occurred while the RX FIFO is empty. + * We need to read from the RBR to clear the interrupt. + */ + + (void)up_serialin(priv, NUC_UART_RBR_OFFSET); + + /* Disable, further RX timeout interrupts and set the RX FIFO + * threshold so that an interrupt will be generated when the + * very next byte is recieved. + */ + + up_rxto_disable(priv); + } + + /* Is the timeout enabled? Are RX interrupts enabled? Was there + * data in the RX FIFO when we entered the interrupt handler? + */ + + else if ((priv->ier & (UART_IER_RTO_IEN | UART_IER_RDA_IEN)) == UART_IER_RDA_IEN && !rxfe) + { + /* We are receiving data and the RX timeout is not enabled. + * Set the RX FIFO threshold so that RX interrupts will only be + * generated after several bytes have been recevied and enable + * the RX timout. + */ + + up_rxto_enable(priv); + } + + /* Check if the transmit holding register is empty. Cleared by writing + * to the THR register. + */ + + if ((isr & UART_ISR_THRE_INT) != 0) + { + uart_xmitchars(dev); + } + + /* Check for modem status. */ + + if ((isr & UART_ISR_MODEM_INT) != 0) + { + /* Cleared by setting the DCTSF bit in the modem control register (MCR) */ + + regval = up_serialin(priv, NUC_UART_MCR_OFFSET); + up_serialout(priv, NUC_UART_MCR_OFFSET, regval | UART_MSR_DCTSF); + } + + /* Check for line status or buffer errors */ + + if ((isr & UART_ISR_RLS_INT) != 0 || + (isr & UART_ISR_BUF_ERR_INT) != 0) + { + /* Both errors are cleared by reseting the RX FIFO */ + + regval = up_serialin(priv, NUC_UART_FCR_OFFSET); + up_serialout(priv, NUC_UART_FCR_OFFSET, regval | UART_FCR_RFR); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct nuc_dev_s *user = (struct nuc_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, priv, sizeof(struct nuc_dev_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + ret = -ENOTTY; /* Not supported */ + break; + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + * Both cfset(i|o)speed() translate to cfsetspeed. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + uint32_t lcr; /* Holds current values of line control register */ + uint16_t dl; /* Divisor latch */ + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + /* Get the c_speed field in the termios struct */ + + priv->baud = cfgetispeed(termiosp); + + /* Reset the baud */ + + nuc_setbaud(priv->base, priv->baud); + } + break; + +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + uint32_t rbr; + + *status = up_serialin(priv, NUC_UART_FSR_OFFSET); + rbr = up_serialin(priv, NUC_UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + /* Enable receive data, line status and buffer error interrupts */ + + irqstate_t flags = enter_critical_section(); + (void)up_setier(priv, 0, + (UART_IER_RDA_IEN | UART_IER_RLS_IEN | + UART_IER_BUF_ERR_IEN)); + + /* Enable or disable timeouts based on the state of RX FIFO */ + + if ((up_serialin(priv, NUC_UART_FSR_OFFSET) & UART_FSR_RX_EMPTY) != 0) + { + /* The FIFO is empty. Disable RX timeout interrupts and set the + * RX FIFO threshold so that an interrupt will be generated when + * the very next byte is recieved. + */ + + up_rxto_disable(priv); + } + else + { + /* Otherwise, set the RX FIFO threshold so that RX interrupts will + * only be generated after several bytes have been recevied and + * enable* the RX timout. + */ + + up_rxto_enable(priv); + } + + leave_critical_section(flags); +#endif + } + else + { + /* Enable receive data, line status, buffer error, and RX timeout + * interrupts. Also disables the RX timer. + */ + + (void)up_setier(priv, 0, + (UART_IER_RDA_IEN | UART_IER_RLS_IEN | UART_IER_RTO_IEN | + UART_IER_BUF_ERR_IEN | UART_IER_TIME_OUT_EN)); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + return ((up_serialin(priv, NUC_UART_FSR_OFFSET) & UART_FSR_RX_EMPTY) == 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + up_serialout(priv, NUC_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + /* Enable the THR empty interrupt */ + + irqstate_t flags = enter_critical_section(); + (void)up_setier(priv, 0, UART_IER_THRE_IEN); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + leave_critical_section(flags); +#endif + } + else + { + /* Disable the THR empty interrupt */ + + (void)up_setier(priv, UART_IER_THRE_IEN, 0); + } +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + uint32_t regval; + int depth; + + regval = up_serialin(priv, NUC_UART_FSR_OFFSET); + depth = (regval & UART_FSR_TX_POINTER_MASK) >> UART_FSR_TX_POINTER_SHIFT; + return depth < priv->depth; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct nuc_dev_s *priv = (struct nuc_dev_s *)dev->priv; + return ((up_serialin(priv, NUC_UART_FSR_OFFSET) & UART_FSR_TE_FLAG) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Configuration whichever UART is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct nuc_dev_s *priv = (struct nuc_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + nuc_lowputc((uint32_t)'\r'); + } + + nuc_lowputc((uint32_t)ch); +#ifdef HAVE_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER && HAVE_UART */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + nuc_lowputc((uint32_t)'\r'); + } + + nuc_lowputc((uint32_t)ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER && HAVE_UART */ diff --git a/arch/arm/src/nuc1xx/nuc_serial.h b/arch/arm/src/nuc1xx/nuc_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..950e30d1a9e727bef7e1f9d7e7fb3c98522f0620 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_serial.h @@ -0,0 +1,68 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_serial.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_SERIAL_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_SERIAL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "nuc_config.h" +#include "chip/nuc_uart.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_SERIAL_H */ diff --git a/arch/arm/src/nuc1xx/nuc_start.c b/arch/arm/src/nuc1xx/nuc_start.c new file mode 100644 index 0000000000000000000000000000000000000000..3cbb5becdeefd337815e90a32aef0a00dea9d778 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_start.c @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_start.c + * arch/arm/src/chip/nuc_start.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "nuc_config.h" +#include "nuc_lowputc.h" +#include "nuc_clockconfig.h" +#include "nuc_userspace.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map: + * + * 0x0000:0000 - Beginning of FLASH. Address of exception vectors. + * 0x0001:ffff - End of flash (assuming 128KB of FLASH) + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap + * 0x2000:3fff - End of SRAM and end of heap (assuming 16KB of SRAM) + */ + +#define IDLE_STACK ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uint32_t g_idle_topstack = IDLE_STACK; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(HAVE_SERIAL_CONSOLE) +# define showprogress(c) nuc_lowputc((uint32_t)c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Configure the uart so that we can get debug output as soon as possible */ + + nuc_clockconfig(); + nuc_lowsetup(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + nuc_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + nuc_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/nuc1xx/nuc_timerisr.c b/arch/arm/src/nuc1xx/nuc_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..d30e81b85caad5bfaf9cae7ab6df9e8558853f56 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_timerisr.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_timerisr.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/nuc_clk.h" +#include "chip/nuc_gcr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Get the frequency of the selected clock source */ + +#if defined(CONFIG_NUC_SYSTICK_CORECLK) +# define SYSTICK_CLOCK BOARD_HCLK_FREQUENCY /* Core clock */ +#elif defined(CONFIG_NUC_SYSTICK_XTALHI) +# define SYSTICK_CLOCK BOARD_XTALHI_FREQUENCY /* High speed XTAL clock */ +#elif defined(CONFIG_NUC_SYSTICK_XTALLO) +# define SYSTICK_CLOCK BOARD_XTALLO_FREQUENCY /* Low speed XTAL clock */ +#elif defined(CONFIG_NUC_SYSTICK_XTALHId2) +# define SYSTICK_CLOCK (BOARD_XTALHI_FREQUENCY/2) /* High speed XTAL clock/2 */ +#elif defined(CONFIG_NUC_SYSTICK_HCLKd2) +# define SYSTICK_CLOCK (BOARD_HCLK_FREQUENCY/2) /* HCLK/2 */ +#elif defined(CONFIG_NUC_SYSTICK_INTHId2) +# define SYSTICK_CLOCK (NUC_INTHI_FREQUENCY/2) /* Internal high speed clock/2 */ +#endif + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * Then, for example, if the external high speed crystal is the SysTick + * clock source and BOARD_XTALHI_FREQUENCY is 12MHz and CLK_TCK is 100, then + * the reload value would be: + * + * SYSTICK_RELOAD = (12,000,000 / 100) - 1 + * = 119,999 + * = 0x1d4bf + * + * Which fits within the maximum 24-bit reload value. + */ + +#define SYSTICK_RELOAD ((SYSTICK_CLOCK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_unlock + * + * Description: + * Unlock registers + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NUC_SYSTICK_CORECLK +static inline void nuc_unlock(void) +{ + putreg32(0x59, NUC_GCR_REGWRPROT); + putreg32(0x16, NUC_GCR_REGWRPROT); + putreg32(0x88, NUC_GCR_REGWRPROT); +} +#endif + +/**************************************************************************** + * Name: nuclock + * + * Description: + * Lok registers + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NUC_SYSTICK_CORECLK +static inline void nuc_lock(void) +{ + putreg32(0, NUC_GCR_REGWRPROT); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Configure the SysTick clock source. This is only necessary if we are not + * using the Cortex-M0 core clock as the frequency source. + */ + +#ifndef CONFIG_NUC_SYSTICK_CORECLK + + /* This field is write protected and must be unlocked */ + + nuc_unlock(); + + /* Read the CLKSEL0 register and set the STCLK_S field appropriately */ + + regval = getreg32(NUC_CLK_CLKSEL0); + regval &= ~CLK_CLKSEL0_STCLK_S_MASK; +#if defined(CONFIG_NUC_SYSTICK_XTALHI) + regval |= CLK_CLKSEL0_STCLK_S_XTALHI; /* High speed XTAL clock */ +#elif defined(CONFIG_NUC_SYSTICK_XTALLO) + regval |= CLK_CLKSEL0_STCLK_S_XTALLO; /* Low speed XTAL clock */ +#elif defined(CONFIG_NUC_SYSTICK_XTALHId2) + regval |= CLK_CLKSEL0_STCLK_S_XTALDIV2; /* High speed XTAL clock/2 */ +#elif defined(CONFIG_NUC_SYSTICK_HCLKd2) + regval |= CLK_CLKSEL0_STCLK_S_HCLKDIV2; /* HCLK/2 */ +#elif defined(CONFIG_NUC_SYSTICK_INTHId2) + regval |= CLK_CLKSEL0_STCLK_S_INTDIV2; /* Internal high speed clock/2 */ +#endif + putreg32(regval, NUC_CLK_CLKSEL0); + + /* Re-lock the register */ + + nuc_lock(); +#endif + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(ARMV6M_SYSCON_SHPR3); + regval &= ~SYSCON_SHPR3_PRI_15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << SYSCON_SHPR3_PRI_15_SHIFT); + putreg32(regval, ARMV6M_SYSCON_SHPR3); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, ARMV6M_SYSTICK_RVR); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(NUC_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts. We need to select the core clock here if + * we are not using one of the alternative clock sources above. + */ + +#ifdef CONFIG_NUC_SYSTICK_CORECLK + putreg32((SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), + ARMV6M_SYSTICK_CSR); +#else + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), ARMV6M_SYSTICK_CSR); +#endif + + /* And enable the timer interrupt */ + + up_enable_irq(NUC_IRQ_SYSTICK); +} diff --git a/arch/arm/src/nuc1xx/nuc_userspace.c b/arch/arm/src/nuc1xx/nuc_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..e0fc09cbcd18b1881d0670d8cc63359cdcc9e032 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_userspace.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/src/nuc1xx/nuc_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "nuc_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void nuc_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/nuc1xx/nuc_userspace.h b/arch/arm/src/nuc1xx/nuc_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..e648c04e7ae4d4f49d3daf7faa95f736aefb3c9a --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/nuc1xx/nuc_userspace.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NUC1XX_NUC_USERSPACE_H +#define __ARCH_ARM_SRC_NUC1XX_NUC_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: nuc_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void nuc_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_NUC1XX_NUC_USERSPACE_H */ diff --git a/arch/arm/src/sam34/Kconfig b/arch/arm/src/sam34/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bb400e649ce604574092a3d4df056aab77cc3536 --- /dev/null +++ b/arch/arm/src/sam34/Kconfig @@ -0,0 +1,1483 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "AT91SAM3/4 Configuration Options" + +choice + prompt "AT91SAM3/4 Chip Selection" + default ARCH_CHIP_ATSAM3U4E + depends on ARCH_CHIP_SAM34 + +config ARCH_CHIP_ATSAM3U4E + bool "ATSAM3U4E" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3U4C + bool "ATSAM3U4C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3U2E + bool "ATSAM3U2E" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3U2C + bool "ATSAM3U2C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3U1E + bool "ATSAM3U1E" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3U1C + bool "ATSAM3U1C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3U + +config ARCH_CHIP_ATSAM3X8E + bool "ATSAMSAM3X8E" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3X + select ARCH_HAVE_EXTNOR + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + +config ARCH_CHIP_ATSAM3X8C + bool "ATSAM3X8C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3X + +config ARCH_CHIP_ATSAM3X4E + bool "ATSAM3X4E" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3X + select ARCH_HAVE_EXTNOR + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + +config ARCH_CHIP_ATSAM3X4C + bool "ATSAM3X4C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3X + +config ARCH_CHIP_ATSAM3A8C + bool "ATSAM3A8C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3A + +config ARCH_CHIP_ATSAM3A4C + bool "ATSAM3A4C" + select ARCH_CORTEXM3 + select ARCH_CHIP_SAM3A + +config ARCH_CHIP_ATSAM4CMP16B + bool "ATSAM4CMP16B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4CM + +config ARCH_CHIP_ATSAM4LC2C + bool "ATSAM4LC2C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LC2B + bool "ATSAM4LC2B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LC2A + bool "ATSAM4LC2A" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LC4C + bool "ATSAM4LC4C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LC4B + bool "ATSAM4LC4B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LC4A + bool "ATSAM4LC4A" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS2C + bool "ATSAM4LS2C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS2B + bool "ATSAM4LS2B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS2A + bool "ATSAM4LS2A" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS4C + bool "ATSAM4LS4C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS4B + bool "ATSAM4LS4B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4LS4A + bool "ATSAM4LS4A" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4L + +config ARCH_CHIP_ATSAM4SD32C + bool "ATSAM4SD32C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4SD32B + bool "ATSAM4SD32B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4SD16C + bool "ATSAM4SD16C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4SD16B + bool "ATSAM4SD16B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4SA16C + bool "ATSAM4SA16C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4SA16B + bool "ATSAM4SA16B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4S16C + bool "ATSAM4S16C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4S16B + bool "ATSAM4S16B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4S8C + bool "ATSAM4S8C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4S8B + bool "ATSAM4S8B" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4S + +config ARCH_CHIP_ATSAM4E16E + bool "ATSAM4E16E" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4E + +config ARCH_CHIP_ATSAM4E16C + bool "ATSAM4E16C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4E + +config ARCH_CHIP_ATSAM4E8E + bool "ATSAM4E8E" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4E + +config ARCH_CHIP_ATSAM4E8C + bool "ATSAM4E8C" + select ARCH_CORTEXM4 + select ARCH_CHIP_SAM4E + +endchoice # AT91SAM3/4 Chip Selection + +config ARCH_CHIP_SAM3U + bool + default n + select ARCH_HAVE_EXTNOR + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + +config ARCH_CHIP_SAM3X + bool + default n + select SAM34_HAVE_GPIOD_IRQ + select SAM34_HAVE_GPIOE_IRQ + select SAM34_HAVE_GPIOF_IRQ + +config ARCH_CHIP_SAM3A + bool + default n + select SAM34_HAVE_GPIOD_IRQ + select SAM34_HAVE_GPIOE_IRQ + select SAM34_HAVE_GPIOF_IRQ + +config ARCH_CHIP_SAM4CM + bool + default n + select ARCH_HAVE_TICKLESS + +config ARCH_CHIP_SAM4L + bool + default n + select ARCH_HAVE_RAMFUNCS + +config ARCH_CHIP_SAM4E + bool + default n + select ARCH_HAVE_EXTNOR + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + select SAM34_HAVE_GPIOD_IRQ + select SAM34_HAVE_GPIOE_IRQ + select SAM34_HAVE_GPIOF_IRQ + +config ARCH_CHIP_SAM4S + bool + default n + select ARCH_HAVE_EXTNOR + select ARCH_HAVE_EXTNAND + select ARCH_HAVE_EXTSRAM0 + select ARCH_HAVE_EXTSRAM1 + +menu "AT91SAM3/4 Peripheral Support" + +config SAM34_ABDACB + bool "Audio Bitstream DAC (ABDAC)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_ACC + bool "Analog Comparator (ACC/ACMP)" + default n + depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_ADC + bool "10-bit ADC Controller (ADC)" + default n + depends on ARCH_CHIP_SAM3U + +config SAM34_ADC12B + bool "12-bit ADC Controller (ADC12)" + default n + depends on !ARCH_CHIP_SAM4E + +config SAM34_AES + bool "Advanced Encryption Standard (AES)" + default n + depends on ARCH_CHIP_SAM4CM || ARCH_CHIP_SAM4E + +config SAM34_AESA + bool "Advanced Encryption Standard (AESA)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_AFEC0 + bool "Analog Front End 0 (AFEC0)" + default n + depends on ARCH_CHIP_SAM4E + +config SAM34_AFEC1 + bool "Analog Front End 1 (AFEC1)" + default n + depends on ARCH_CHIP_SAM4E + +config SAM34_APBA + bool "APBA bridge (APBA)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_AST + bool "Asynchronous Timer (AST)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_CAN0 + bool "CAN0" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + +config SAM34_CAN1 + bool "CAN1" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + +config SAM34_CATB + bool "Capacitive Touch Module B (CATB)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_CHIPID + bool "Chip ID" + default n + depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4E + +config SAM34_CMCC + bool "Cortex M Cache Controller (CMCC)" + default n + depends on ARCH_CHIP_SAM4E + +config SAM34_CRCCU + bool "CRC Calculation Unit (CRCCU)" + default n + depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4S + +config SAM34_DACC + bool "Digital To Analog Converter (DACC)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_EIC + bool "External Interrupt Controller (EIC)" + default n + depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4E + +config SAM34_DMAC0 + bool "DMA controller (DMAC0)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + select ARCH_DMA + +config SAM34_DMAC1 + bool + default n + +config SAM34_EMAC + bool "Ethernet MAC (EMAC)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + select NETDEVICES + select ARCH_HAVE_PHY + +config SAM34_FREQM + bool "Frequency Meter (FREQM)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_GLOC + bool "GLOC" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_HMATRIX + bool "HMATRIX" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_HRAMC1 + bool "HRAMC1 (picoCache RAM)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_HSMCI + bool "High Speed Multimedia Card Interface (HSMCI)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select ARCH_HAVE_SDIO + select MMCSD + +config SAM34_IISC + bool "Inter-IC Sound (I2S) Controller" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_SLCDC + bool "Segment LCD Controller (SLCDC)" + default n + depends on ARCH_CHIP_SAM4CM + +config SAM34_LCDCA + bool "LCD Controller A (LCDCA)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_NAND + bool "NAND support" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM4E + +config SAM34_OCD + bool "On-chip DEBUG (OCD)" + depends on ARCH_CHIP_SAM4L + default y if DEBUG_SYMBOLS + default n if !DEBUG_SYMBOLS + +config SAM34_PARC + bool "Parallel Capture (PARC)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_PDCA + bool "Peripheral DMA controller (PDC)" + default n + depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select ARCH_DMA + +config SAM34_PEVC + bool "Peripheral Event Controller" + default n + depends on ARCH_CHIP_SAM4L + +config SAM_PICOCACHE + bool "PicoCACHE" + default y + depends on ARCH_CHIP_SAM4L + +config SAM34_PICOUART + bool "PicoUART" + default n + depends on ARCH_CHIP_SAM4L + select ARCH_HAVE_UART + +config SAM34_PWM + bool "Pulse Width Modulation (PWM) Controller" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_RTC + bool "Real Time Clock (RTC)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_RTT + bool "Real Time Timer (RTT)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_SDRAMC + bool "SDRAM Controller (SDRAMC)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A + +config SAM34_SMC + bool "Static Memory Controller (SMC)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + +config SAM34_SPI0 + bool "Serial Peripheral Interface 0 (SPI0)" + default n + select SPI + +config SAM34_SPI1 + bool "Serial Peripheral Interface 1 (SPI1)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A + select SPI + +config SAM34_SSC + bool "Synchronous Serial Controller (SSC)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S + +config SAM34_TC0 + bool "Timer/Counter 0 (TC0)" + default n + select SAM34_TC + +config SAM34_TC1 + bool "Timer/Counter 1 (TC1)" + default n + select SAM34_TC + +config SAM34_TC2 + bool "Timer/Counter 2 (TC2)" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC3 + bool "Timer/Counter 3 (TC3)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC4 + bool "Timer/Counter 4 (TC4)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC5 + bool "Timer/Counter 5 (TC5)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC6 + bool "Timer/Counter 6 (TC6)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC7 + bool "Timer/Counter 7 (TC7)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TC8 + bool "Timer/Counter 8 (TC8)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E + select SAM34_TC + +config SAM34_TRNG + bool "True Random Number Generator (TRNG)" + default n + depends on ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4L + select ARCH_HAVE_RNG + +config SAM34_TWI + bool + default n + +config SAM34_TWIM + bool + default n + +config SAM34_TWIS + bool + default n + + +config SAM34_TWIM0 + bool "Two-wire Master Interface 0 (TWIM0)" + default n + select SAM34_TWI + select SAM34_TWIM + +config SAM34_TWIS0 + bool "Two-wire Slave Interface 0 (TWIS0)" + default n + select SAM34_TWI + select SAM34_TWIS + +config SAM34_TWIM1 + bool "Two-wire Master Interface 1 (TWIM1)" + default n + select SAM34_TWI + select SAM34_TWIM + +config SAM34_TWIS1 + bool "Two-wire Slave Interface 1 (TWIS1)" + default n + select SAM34_TWI + select SAM34_TWIS + +config SAM34_TWIM2 + bool "Two-wire Master Interface 2 (TWIM2)" + default n + depends on ARCH_CHIP_SAM4L + select SAM34_TWI + select SAM34_TWIM + +config SAM34_TWIM3 + bool "Two-wire Master Interface 3 (TWIM3)" + default n + depends on ARCH_CHIP_SAM4L + select SAM34_TWI + select SAM34_TWIM + +config SAM34_UART0 + bool "UART 0" + default y + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4CM || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAM34_UART1 + bool "UART 1" + default n + depends on ARCH_CHIP_SAM4CM || ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +if SAM34_UART1 && ARCH_CHIP_SAM4CM + +config SAM34_UART1_OPTICAL + bool "UART 1 is optical" + default n + +endif + +config SAM34_UDP + bool "USB Device Full Speed (UDP)" + default n + depends on ARCH_CHIP_SAM4S || ARCH_CHIP_SAM4E + select ARCH_USBDEV_STALLQUEUE + +config SAM34_UDPHS + bool "USB Device High Speed (UDPHS)" + default n + depends on ARCH_CHIP_SAM3U + +config SAM34_UOTGHS + bool "USB OTG High Speed (UOTGHS)" + default n + depends on ARCH_CHIP_SAM3A || ARCH_CHIP_SAM3X + +config SAM34_USBC + bool "USB 2.0 Interface (USBC)" + default n + depends on ARCH_CHIP_SAM4L + +config SAM34_USART0 + bool "USART 0" + default n + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAM34_USART1 + bool "USART 1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAM34_USART2 + bool "USART 2" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4CM || ARCH_CHIP_SAM4L + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAM34_USART3 + bool "USART 3" + default n + depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4CM || ARCH_CHIP_SAM4L + select ARCH_HAVE_USART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAM34_WDT + bool "Watchdog Timer (WDT)" + default n + +endmenu # AT91SAM3/4 Peripheral Support + +if ARCH_CHIP_SAM4L +menu "AT91SAM3/4 Clock Configuration" + +config SAM34_RESET_PERIPHCLKS + bool "Enable all peripheral clocks on reset" + default n + ---help--- + By default, only a few necessary peripheral clocks are enabled at + reset. If this setting is enabled, then all clocking will be enabled + to all of the selected peripherals on reset. + +config SAM34_OSC0 + bool "External oscillator 0" + default n + ---help--- + Oscillator 0 might be automatically selected for several reasons: + Oscillator 0 might be the system clock or the source clock for + either PLL0 or DFPLL. It might also be needed if OSC0 is the source + clock for GCLK9. By selecting SAM34_OSC0, you can also force the + clock to be enabled at boot time for other uses. + +config SAM34_OSC32K + bool "32.768KHz external oscillator" + default n + ---help--- + The 32K oscillator might be automatically selected for several + reasons: The 32K oscillator may be the source clock for DFPLL0 or + the source clock for GLK9 that might be used to driver PLL0. By + selecting SAM34_OSC32K, you can also force the clock to be enabled + at boot time. OSC32 may needed by other devices as well (AST, WDT, + PICUART, RTC). + +config SAM34_RC80M + bool "80MHz RC oscillator" + default n + ---help--- + The 80MHz RC oscillator might be automatically selected for several + reasons: This might be the system clock or the source clock for the + DFPLL or it could be the source for GCLK9 that drives PLL0. By + selecting SAM34_RC80M, you can also force the clock to be enabled at + boot time for other uses. + +config SAM34_RCFAST + bool "Fast RC oscillator" + default n + ---help--- + The fast RC oscillator might be automatically selected for several + reasons: The 12/8/4 fast RC oscillator may be used as the system + clock or as the source for GLCK9 that drives PLL0. If not then, it + may be enabled by setting the SAM34_RCFASTxM configuration variable. + +if SAM34_RCFAST +choice + prompt "Fast RC Oscillator Speed" + default SAM34_RCFAST8M + +config SAM34_RCFAST12M + bool "12MHz" + +config SAM34_RCFAST8M + bool "8MHz" + +config SAM34_RCFAST4M + bool "4MHz" + +endchoice # Fast RC Oscillator Speed +endif # SAM34_RCFAST + +config SAM34_RC1M + bool "1MHz RC oscillator" + default n + ---help--- + The 1MHz RC oscillator might be automatically selected for several + reasons: The 1MHz RC oscillator may be used as the system block or + may be the source clock for GLCK9 that drives PLL0. By selecting + SAM34_RC1M, you can also force the clock to be enabled at boot time + for other purposes. + +config SAM34_RC32K + bool "32KHz RC oscillator" + default n + ---help--- + The 32KHz RC oscillator might be automatically selected for several + reasons: The 32KHz RC oscillator may be used as the input to DFLL0 + or as the input to GCLK9 that drives PLL0. By selecting SAM34_RC32K, + you can also force the clock to be enabled at boot time for other + purposes. + +endmenu # AT91SAM3/4 Clock Configuration +endif # ARCH_CHIP_SAM4L + +menu "AT91SAM3/4 External Memory Configuration" + +config ARCH_HAVE_EXTNAND + bool + +config ARCH_HAVE_EXTNOR + bool + +config ARCH_HAVE_EXTDRAM + bool + +config ARCH_HAVE_EXTSRAM0 + bool + +config ARCH_HAVE_EXTSRAM1 + bool + +config SAM34_EXTNAND + bool "Configure external NAND" + default n + depends on ARCH_HAVE_EXTNAND + ---help--- + Configure external NAND memory and, if applicable, map then external + NAND into the memory map. + +if SAM34_EXTNAND + +config SAM34_EXTNANDSIZE + int "External NAND size" + default 0 + ---help--- + Size of the external NAND in bytes. + +endif # SAM34_EXTNAND + +config SAM34_EXTNOR + bool "Configure external NOR memory" + default n + depends on ARCH_HAVE_EXTNOR + ---help--- + Configure external NOR memory and, if applicable, map then external + NOR into the memory map. + +if SAM34_EXTNOR + +config SAM34_EXTNORSIZE + int "External NOR size" + default 0 + ---help--- + Size of the external NOR in bytes. + +endif # SAM34_EXTNOR + +config SAM34_EXTDRAM + bool "Configure external DRAM" + default n + depends on ARCH_HAVE_EXTDRAM + select ARCH_HAVE_SDRAM + ---help--- + Configure external DRAM memory and, if applicable, map then external + DRAM into the memory map. + +if SAM34_EXTDRAM + +config SAM34_EXTDRAMSIZE + int "External SDRAM size" + default 0 + ---help--- + Size of the external SDRAM in bytes. + +choice + prompt "SDRAM Width Selection" + default SAM34_SDRAM_16BIT + +config SAM34_SDRAM_8BIT + bool "8-bit" + +config SAM34_SDRAM_16BIT + bool "16-bit" + +config SAM34_SDRAM_32BIT + bool "32-bit" + +endchoice # SDRAM Width Selection + +config SAM34_EXTDRAMHEAP + bool "Add external SDRAM to the heap" + default y + ---help--- + Add the external SDRAM into the heap. + +endif # SAM34_EXTDRAM + +config SAM34_EXTSRAM0 + bool "Configure external SRAM (Bank 0)" + default n + depends on ARCH_HAVE_EXTSRAM0 + ---help--- + Configure external SRAM Bank 0 memory and, if applicable, map then + external SRAM Bank 0 into the memory map. + +if SAM34_EXTSRAM0 + +config SAM34_EXTSRAM0SIZE + int "External SRAM size" + default 0 + ---help--- + Size of the external SRAM Bank 0 in bytes. + +config SAM34_EXTSRAM0HEAP + bool "Add external SRAM (Bank 0) to the heap" + default y + ---help--- + Add external SRAM Bank 0 into the heap. + +endif # SAM34_EXTSRAM0 + +config SAM34_EXTSRAM1 + bool "Configure external SRAM (Bank 1)" + default n + depends on ARCH_HAVE_EXTSRAM1 + ---help--- + Configure external SRAM Bank 1 memory and, if applicable, map then + external SRAM Bank 1 into the memory map. + +if SAM34_EXTSRAM1 + +config SAM34_EXTSRAM1SIZE + int "External SRAM1 size" + default 0 + ---help--- + Size of the external SRAM Bank 1 in bytes. + +config SAM34_EXTSRAM1HEAP + bool "Add external SRAM (Bank 1) to the heap" + default y + ---help--- + Add external SRAM Bank 1 into the heap. + +endif # SAM34_EXTSRAM1 +endmenu # External Memory Configuration + +menu "AT91SAM3/4 GPIO Interrupt Configuration" + +config SAM34_HAVE_GPIOD_IRQ + bool + default n + +config SAM34_HAVE_GPIOE_IRQ + bool + default n + +config SAM34_HAVE_GPIOF_IRQ + bool + default n + +config SAM34_GPIO_IRQ + bool "GPIO pin interrupts" + depends on !ARCH_CHIP_SAM4L + ---help--- + Enable support for interrupting GPIO pins + +if SAM34_GPIO_IRQ + +config SAM34_GPIOA_IRQ + bool "GPIOA interrupts" + default n + +config SAM34_GPIOB_IRQ + bool "GPIOB interrupts" + default n + +config SAM34_GPIOC_IRQ + bool "GPIOC interrupts" + default n + +config SAM34_GPIOD_IRQ + bool "GPIOD interrupts" + default n + depends on SAM34_HAVE_GPIOD_IRQ + +config SAM34_GPIOE_IRQ + bool "GPIOE interrupts" + default n + depends on SAM34_HAVE_GPIOE_IRQ + +config SAM34_GPIOF_IRQ + bool "GPIOF interrupts" + default n + depends on SAM34_HAVE_GPIOF_IRQ + +endif # SAM34_GPIO_IRQ +endmenu # AT91SAM3/4 GPIO Interrupt Configuration + +menu "AT91SAM3/4 Timer/Counter Configuration" + depends on SAM34_TC && ARCH_CHIP_SAM4CM + +config SAM34_TC0_CLK + bool "Enable TC channel 0 clock input pin" + default n + depends on SAM34_TC0 + +config SAM34_TC0_TIOA + bool "Enable TC channel 0 output A" + default n + depends on SAM34_TC0 + +config SAM34_TC0_TIOB + bool "Enable TC channel 0 output B" + default n + depends on SAM34_TC0 + +config SAM34_TC1_CLK + bool "Enable TC channel 1 clock input pin" + default n + depends on SAM34_TC1 + +config SAM34_TC1_TIOA + bool "Enable TC channel 1 output A" + default n + depends on SAM34_TC1 + +config SAM34_TC1_TIOB + bool "Enable TC channel 1 output B" + default n + depends on SAM34_TC1 + +config SAM34_TC2_CLK + bool "Enable TC channel 2 clock input pin" + default n + depends on SAM34_TC2 + +config SAM34_TC2_TIOA2 + bool "Enable TC channel 2 output A" + default n + depends on SAM34_TC2 + +config SAM34_TC2_TIOB2 + bool "Enable TC channel 2 output B" + default n + depends on SAM34_TC2 + +config SAM34_TC3_CLK + bool "Enable TC channel 3 clock input pin" + default n + depends on SAM34_TC3 + +config SAM34_TC3_TIOA + bool "Enable TC channel 3 output A" + default n + depends on SAM34_TC3 + +config SAM34_TC3_TIOB + bool "Enable TC channel 3 output B" + default n + depends on SAM34_TC3 + +config SAM34_TC4_CLK + bool "Enable TC channel 4 clock input pin" + default n + depends on SAM34_TC4 + +config SAM34_TC4_TIOA + bool "Enable TC channel 4 output A" + default n + depends on SAM34_TC4 + +config SAM34_TC4_TIOB + bool "Enable TC channel 4 output B" + default n + depends on SAM34_TC4 + +config SAM34_TC5_CLK + bool "Enable TC channel 5 clock input pin" + default n + depends on SAM34_TC5 + +config SAM34_TC5_TIOA + bool "Enable TC channel 5 output A" + default n + depends on SAM34_TC5 + +config SAM34_TC5_TIOB + bool "Enable TC channel 5 output B" + default n + depends on SAM34_TC5 + +config SAM34_ONESHOT + bool "TC one-shot wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config SAM34_FREERUN + bool "TC free-running wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support a free-running timer. + +if SCHED_TICKLESS + +config SAM34_TICKLESS_ONESHOT + int "Tickless one-shot timer channel" + default 0 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the one-shot timer needed by the OS. + +config SAM34_TICKLESS_FREERUN + int "Tickless free-running timer channel" + default 1 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the free-running timer needed by the OS. + +endif # SCHED_TICKLESS +endmenu # AT91SAM3/4 Timer/Counter Configuration + +if SAM34_SPI0 || SAM34_SPI1 + +menu "AT91SAM3/4 SPI device driver options" + +config SAM34_SPI_DMA + bool "SPI DMA" + default n + depends on (SAM34_DMAC0 && SAM34_SPI0) || (SAM34_DMAC1 && SAM34_SPI1) + ---help--- + Use DMA to improve SPI transfer performance. + +config SAM34_SPI_DMATHRESHOLD + int "SPI DMA threshold" + default 4 + depends on SAM34_SPI_DMA + ---help--- + When SPI DMA is enabled, small DMA transfers will still be performed + by polling logic. But we need a threshold value to determine what + is small. That value is provided by SAM34_SPI_DMATHRESHOLD. + +config SAM34_SPI_DMADEBUG + bool "SPI DMA transfer debug" + depends on SAM34_SPI_DMA && DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze SPI DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAM34_SPI_REGDEBUG + bool "SPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. + Requires also DEBUG. + +endmenu # AT91SAM3/4 SPI device driver options +endif # SAM34_SPI0 || SAM34_SPI1 + +if SAM34_EMAC + +menu "AT91SAM3/4 EMAC device driver options" + +config SAM34_EMAC_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + EMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAM34_EMAC_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + EMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAM34_EMAC_PREALLOCATE + bool "Preallocate buffers" + default n + ---help--- + Buffer an descriptor many may either be allocated from the memory + pool or pre-allocated to lie in .bss. This options selected pre- + allocated buffer memory. + +config SAM34_EMAC_NBC + bool "Disable Broadcast" + default n + ---help--- + Select to disable receipt of broadcast packets. + +config SAM34_EMAC_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAM34_EMAC_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAM34_EMAC_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAM34 EMAC driver will call this function + one time before it first uses the PHY. + +choice + prompt "PHY interface" + default SAM34_EMAC_MII + +config SAM34_EMAC_MII + bool "MII" + ---help--- + Support Ethernet MII interface (vs RMII). + +config SAM34_EMAC_RMII + bool "RMII" + depends on !ARCH_CHIP_SAM4E + ---help--- + Support Ethernet RMII interface (vs MII). + +endchoice # PHY interface + +config SAM34_EMAC_CLAUSE45 + bool "Clause 45 MII" + depends on SAM34_EMAC_MII + ---help--- + MDIO was originally defined in Clause 22 of IEEE RFC802.3. In the + original specification, a single MDIO interface is able to access up + to 32 registers in 32 different PHY devices. To meet the needs the + expanding needs of 10-Gigabit Ethernet devices, Clause 45 of the + 802.3ae specification provided the following additions to MDIO: + + - Ability to access 65,536 registers in 32 different devices on + 32 different ports + - Additional OP-code and ST-code for Indirect Address register + access for 10 Gigabit Ethernet + - End-to-end fault signaling + - Multiple loopback points + - Low voltage electrical specification + + By default, Clause 22 PHYs will be supported unless this option is + selected. + +config SAM34_EMAC_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config SAM34_EMAC_ETHFD + bool "Full duplex" + default n + depends on !SAM34_EMAC_AUTONEG + ---help--- + If SAM34_EMAC_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config SAM34_EMAC_ETH100MBPS + bool "100 Mbps" + default n + depends on !SAM34_EMAC_AUTONEG + ---help--- + If SAM34_EMAC_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config SAM34_EMAC_PHYSR + int "PHY Status Register Address (decimal)" + depends on SAM34_EMAC_AUTONEG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config SAM34_EMAC_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on SAM34_EMAC_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +config SAM34_EMAC_PHYSR_SPEED + hex "PHY Speed Mask" + depends on SAM34_EMAC_AUTONEG && !SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config SAM34_EMAC_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + depends on SAM34_EMAC_AUTONEG && !SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config SAM34_EMAC_PHYSR_MODE + hex "PHY Mode Mask" + depends on SAM34_EMAC_AUTONEG && !SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config SAM34_EMAC_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + depends on SAM34_EMAC_AUTONEG && !SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +config SAM34_EMAC_PHYSR_ALTMODE + hex "PHY Mode Mask" + depends on SAM34_EMAC_AUTONEG && SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config SAM34_EMAC_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + depends on SAM34_EMAC_AUTONEG && SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config SAM34_EMAC_PHYSR_100HD + hex "100Base-T Half Duplex Value" + depends on SAM34_EMAC_AUTONEG && SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config SAM34_EMAC_PHYSR_10FD + hex "10Base-T Full Duplex Value" + depends on SAM34_EMAC_AUTONEG && SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config SAM34_EMAC_PHYSR_100FD + hex "100Base-T Full Duplex Value" + depends on SAM34_EMAC_AUTONEG && SAM34_EMAC_PHYSR_ALTCONFIG + ---help--- + This must be provided if SAM34_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +config SAM34_EMAC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +config SAM34_EMAC_ISETH0 + bool + default y if !SAM34_EMAC || !SAM34_GMAC_ISETH0 + default n if SAM34_EMAC && SAM34_GMAC_ISETH0 + +endmenu # EMAC device driver options +endif # SAM34_EMAC + +if SAM34_HSMCI +menu "AT91SAM3/4 HSMCI device driver options" + +config SAM34_HSMCI_RDPROOF + bool "Read Proof Enable" + default n + ---help--- + Enabling Read Proof allows to stop the HSMCI Clock during read + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAM34_HSMCI_WRPROOF + bool "Write Proof Enable" + default n + ---help--- + Enabling Write Proof allows to stop the HSMCI Clock during write + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAM34_HSMCI_XFRDEBUG + bool "HSMCI transfer debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI data transfers. + This logic is as non-invasive as possible: It samples HSMCI + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. If DEBUG_DMA is also + enabled, then DMA register will be collected as well. Requires also + DEBUG_FS and DEBUG_VERBOSE. + +config SAM34_HSMCI_CMDDEBUG + bool "HSMCI command debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI commands. This + logic is as non-invasive as possible: It samples HSMCI registers at + key points in the data transfer and then dumps all of the registers + at the end of the transfer. If DEBUG_DMA is also enabled, then DMA + register will be collected as well. Requires also DEBUG_FS and + DEBUG_VERBOSE. + +endmenu # HSMCI device driver options +endif # SAM34_HSMCI + +menu "AT91SAM3/4 USB Full Speed Device Controller driver (DCD) options" + depends on SAM34_UDP + +config SAM34_UDP_REGDEBUG + bool "Enable low-level UDP register debug" + default n + depends on DEBUG + +endmenu # USB Full Speed Device Controller driver (DCD) options + +config SAM34_TC + bool + default n + select ARCH_HAVE_EXTCLK + +menu "AT91SAM3/4 Timer/Counter options" + depends on SAM34_TC + +config SAM34_TC_REGDEBUG + bool "Enable low-level timer/counter register debug" + default n + depends on DEBUG + +endmenu # USB Full Speed Device Controller driver (DCD) options + +menu "AT91SAM3/4 Watchdog Configuration" + depends on SAM34_WDT + +config WDT_ENABLED_ON_RESET + bool "Watchdog Enabled on reset" + default n + ---help--- + The WDT can be enabled at reset. This is controlled by the WDTAUTO + fuse. The WDT will be set in basic mode, RCSYS is set as source for + CLK_CNT, and PSEL will be set to a value giving Tpsel above 100 ms + (SAM4L) + + This setting informs that start-up logic that the watchdog is + enabled. + +config WDT_DISABLE_ON_RESET + bool "Disable watchdog on reset" + default n + depends on WDT_ENABLED_ON_RESET + ---help--- + If the WDT can be enabled at reset then this setting may be used to + configure and disable the watchdog timer very early in the boot + sequence. + +config WDT_TIMEOUT + int "Watchdog Timeout (ms)" + default 5000 + depends on !WDT_DISABLE_ON_RESET + ---help--- + Watchdog timeout value in milliseconds. + +config WDT_MINTIME + int "Watchdog Minimum Time (ms)" + default 2500 + depends on !WDT_DISABLE_ON_RESET + ---help--- + Minimum watchdog kick interval + +menuconfig WDT_THREAD + bool "Watchdog Kicker Thread" + depends on !WDT_DISABLE_ON_RESET + default y + +if WDT_THREAD + +config WDT_THREAD_NAME + string "Watchdog Thread Name" + default "wdog" + +config WDT_THREAD_INTERVAL + int "Watchdog Thread Interval (ms)" + default 2500 + +config WDT_THREAD_PRIORITY + int "Watchdog Thread Priority" + default 200 + +config WDT_THREAD_STACKSIZE + int "Watchdog Thread Stacksize" + default 1024 + +endif # WDT_THREAD +endmenu #"AT91SAM3/4 Watchdog device driver options" diff --git a/arch/arm/src/sam34/Make.defs b/arch/arm/src/sam34/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..48c751799ceb2df9e75552386a21ff6c05917eb9 --- /dev/null +++ b/arch/arm/src/sam34/Make.defs @@ -0,0 +1,211 @@ +############################################################################ +# arch/arm/src/sam34/Make.defs +# +# Copyright (C) 2009-2011, 2013-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +HEAD_ASRC = +else +HEAD_ASRC = sam_vectors.S +endif + +# Common ARM and Cortex-M3 files + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_memfault.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_vfork.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Required SAM3/4 files + +CHIP_ASRCS = +CHIP_CSRCS = sam_allocateheap.c sam_irq.c sam_lowputc.c sam_serial.c +CHIP_CSRCS += sam_start.c + +# Configuration-dependent SAM3/4 files + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CHIP_ASRCS += sam_vectors.S +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_timerisr.c +endif + +ifeq ($(CONFIG_CRYPTO_AES),y) +CHIP_CSRCS += sam_aes.c +endif + +ifeq ($(CONFIG_ARCH_CHIP_SAM4CM),y) +CHIP_CSRCS += sam4cm_supc.c +endif + +ifeq ($(CONFIG_ARCH_CHIP_SAM4L),y) +CHIP_CSRCS += sam4l_clockconfig.c sam4l_periphclks.c sam4l_gpio.c +else +CHIP_CSRCS += sam_clockconfig.c sam_gpio.c sam_gpioirq.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += sam_userspace.c sam_mpuinit.c +endif + +ifeq ($(CONFIG_SAM34_CMCC),y) +CHIP_CSRCS += sam_cmcc.c +endif + +ifeq ($(CONFIG_SAM34_DMAC0),y) +CHIP_CSRCS += sam_dmac.c +endif + +ifeq ($(CONFIG_ARCH_CHIP_SAM4L),y) +ifeq ($(CONFIG_SAM34_PDCA),y) +CHIP_CSRCS += sam4l_pdca.c +endif +endif + +ifeq ($(CONFIG_SAM34_EMAC),y) +CHIP_CSRCS += sam_emac.c +endif + +ifeq ($(CONFIG_SAM34_UDP),y) +CHIP_CSRCS += sam_udp.c +endif + +ifeq ($(CONFIG_SAM34_HSMCI),y) +CHIP_CSRCS += sam_hsmci.c +endif + +ifeq ($(CONFIG_SAM34_SPI0),y) +CHIP_CSRCS += sam_spi.c +else +ifeq ($(CONFIG_SAM34_SPI1),y) +CHIP_CSRCS += sam_spi.c +endif +endif + +ifeq ($(CONFIG_SAM34_TWIM),y) +CHIP_CSRCS += sam_twi.c +endif + +ifeq ($(CONFIG_SAM34_AES),y) +CHIP_CSRCS += sam_aes.c +endif + +ifeq ($(CONFIG_SAM34_RTC),y) +CHIP_CSRCS += sam_rtc.c +endif + +ifeq ($(CONFIG_SAM34_RTT),y) +CHIP_CSRCS += sam_rtt.c +endif + +ifeq ($(CONFIG_SAM34_WDT),y) +CHIP_CSRCS += sam_wdt.c +endif + +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += sam_tc.c +endif + +ifeq ($(CONFIG_ARCH_CHIP_SAM4CM),y) +ifeq ($(CONFIG_SAM34_TC),y) +CHIP_CSRCS += sam4cm_tc.c +ifeq ($(CONFIG_SAM34_ONESHOT),y) +CHIP_CSRCS += sam4cm_oneshot.c +endif +ifeq ($(CONFIG_SAM34_FREERUN),y) +CHIP_CSRCS += sam4cm_freerun.c +endif +ifeq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam4cm_tickless.c +endif +endif +endif diff --git a/arch/arm/src/sam34/chip.h b/arch/arm/src/sam34/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..c8a1fc86e736d134b4d44ed90ed1deb8a64c2434 --- /dev/null +++ b/arch/arm/src/sam34/chip.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include "chip/sam_memorymap.h" + +/* If the common ARMv7-M vector handling logic is used, then include the required + * vector definitions as well. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR +# if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "chip/sam3u_vectors.h" +# elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3x_vectors.h" +# elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "chip/sam4cm_vectors.h" +# elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_vectors.h" +# elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_vectors.h" +# elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_vectors.h" +# else +# error Unrecognized SAM architecture +# endif +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_H */ diff --git a/arch/arm/src/sam34/chip/sam3u_memorymap.h b/arch/arm/src/sam34/chip/sam3u_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..ffcc5589fb3de15922ab9cff2fb4e469ba04ac4c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3u_memorymap.h @@ -0,0 +1,145 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam3u_memorymap.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +# define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x0007ffff: Boot Memory */ +# define SAM_INTFLASH0_BASE 0x00080000 /* 0x00080000-0x000fffff: Internal FLASH 0 */ +# define SAM_INTFLASH1_BASE 0x00100000 /* 0x00100000-0x0017ffff: Internal FLASH 1 */ +# define SAM_INTROM_BASE 0x00180000 /* 0x00180000-0x001fffff: Internal ROM */ + /* 0x00200000-0x1fffffff: Reserved */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +# define SAM_INTSRAM0_BASE 0x20000000 /* 0x20000000-0x2007ffff: SRAM0 (see chip.h) */ +# define SAM_INTSRAM1_BASE 0x20080000 /* 0x20080000-0x200fffff: SRAM1 (see chip.h) */ +# define SAM_NFCSRAM_BASE 0x20100000 /* 0x20100000-0x207fffff: NAND FLASH controller (SRAM) */ +# define SAM_UDPHPSDMS_BASE 0x20180000 /* 0x20180000-0x201fffff: USB Device High Speed (DMA) */ + /* 0x20200000-0x2fffffff: Undefined */ +# define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32Mb bit-band alias */ + /* 0x24000000-0x3fffffff: Undefined */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +# define SAM_HSMCI_BASE 0x40000000 /* 0x40000000-0x400003ff: High Speed Multimedia Card Interface */ +# define SAM_SSC_BASE 0x40004000 /* 0x40004000-0x40007fff: Synchronous Serial Controller */ +# define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface */ + /* 0x4000c000-0x4007ffff: Reserved */ +# define SAM_TC_BASE 0x40080000 /* 0x40080000-0x40083fff: Timer Counters */ +# define SAM_TCN_BASE(n) (0x40080000+((n)<<6)) +# define SAM_TC0_BASE 0x40080000 /* 0x40080000-0x4008003f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x40080040 /* 0x40080040-0x4008007f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x40080080 /* 0x40080080-0x400800bf: Timer Counter 2 */ +# define SAM_TWI_BASE 0x40084000 /* 0x40084000-0x4008ffff: Two-Wire Interface */ +# define SAM_TWIN_BASE(n) (0x40084000+((n)<<14)) +# define SAM_TWI0_BASE 0x40084000 /* 0x40084000-0x40087fff: Two-Wire Interface 0 */ +# define SAM_TWI1_BASE 0x40088000 /* 0x40088000-0x4008bfff: Two-Wire Interface 1 */ +# define SAM_PWM_BASE 0x4008c000 /* 0x4008c000-0x4008ffff: Pulse Width Modulation Controller */ +# define SAM_USART_BASE 0x40090000 /* 0x40090000-0x4009ffff: USART */ +# define SAM_USARTN_BASE(n) (0x40090000+((n)<<14)) +# define SAM_USART0_BASE 0x40090000 /* 0x40090000-0x40093fff: USART0 */ +# define SAM_USART1_BASE 0x40094000 /* 0x40094000-0x40097fff: USART1 */ +# define SAM_USART2_BASE 0x40098000 /* 0x40098000-0x4009bfff: USART2 */ +# define SAM_USART3_BASE 0x4009c000 /* 0x4009c000-0x4009ffff: USART3 */ + /* 0x400a0000-0x400a3fff: Reserved */ +# define SAM_UDPHS_BASE 0x400a4000 /* 0x400a4000-0x400a7fff: USB Device High Speed */ +# define SAM_ADC12B_BASE 0x400a8000 /* 0x400a8000-0x400abfff: 12-bit ADC Controller */ +# define SAM_ADC_BASE 0x400ac000 /* 0x400ac000-0x400affff: 10-bit ADC Controller */ +# define SAM_DMAC_BASE 0x400b0000 /* 0x400b0000-0x400b3fff: DMA controller */ + /* 0x400b4000-0x400dffff: Reserved */ +# define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e25ff: System controller */ + /* 0x400e2600-0x400fffff: Reserved */ + /* 0x40100000-0x41ffffff: Reserved */ +# define SAM_BBPERIPH_BASE 0x42000000 /* 0x42000000-0x43ffffff: 32Mb bit-band alias */ + /* 0x44000000-0x5fffffff: Reserved */ +#define SAM_EXTSRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External SRAM */ +# define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */ +# define SAM_EXTCSN_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */ + /* 0x64000000-0x67ffffff: Reserved */ +# define SAM_NFC_BASE 0x68000000 /* 0x68000000-0x68ffffff: NAND FLASH controller */ + /* 0x69000000-0x9fffffff: Reserved */ + /* 0xa0000000-0xdfffffff: Reserved */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* System Controller Register Blocks: 0x400e0000-0x4007ffff */ + +#define SAM_SMC_BASE 0x400e0000 /* 0x400e0000-0x400e01ff: Static Memory Controller */ +#define SAM_MATRIX_BASE 0x400e0200 /* 0x400e0200-0x400e03ff: MATRIX */ +#define SAM_PMC_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: Power Management Controller */ +#define SAM_UART0_BASE 0x400e0600 /* 0x400e0600-0x400e073f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0740 /* 0x400e0740-0x400e07ff: CHIP ID */ +#define SAM_EEFC_BASE 0x400e0800 /* 0x400e0800-0x400e0bff: Enhanced Embedded Flash Controllers*/ +# define SAM_EEFCN_BASE(n) (0x400e0800 + ((n) << 9)) +# define SAM_EEFC0_BASE 0x400e0800 /* 0x400e0800-0x400e09ff: Enhanced Embedded Flash Controller 0 */ +# define SAM_EEFC1_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controller 1 */ +#define SAM_PIO_BASE 0x400e0c00 /* 0x400e0c00-0x400e11ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0c00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller C */ +#define SAM_RSTC_BASE 0x400e1200 /* 0x400e1200-0x400e120f: Reset Controller */ +#define SAM_SUPC_BASE 0x400e1210 /* 0x400e1210-0x400e122f: Supply Controller */ +#define SAM_RTT_BASE 0x400e1230 /* 0x400e1230-0x400e124f: Real Time Timer */ +#define SAM_WDT_BASE 0x400e1250 /* 0x400e1250-0x400e125f: Watchdog Timer */ +#define SAM_RTC_BASE 0x400e1260 /* 0x400e1260-0x400e128f: Real Time Clock */ +#define SAM_GPBR_BASE 0x400e1290 /* 0x400e1290-0x400e13ff: GPBR */ + /* 0x490e1400-0x4007ffff: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam3u_pinmap.h b/arch/arm/src/sam34/chip/sam3u_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..166a5213dc6d58e16ecb266e3416d912dbd8ccb2 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3u_pinmap.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam3u_pinmap.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ + +#define GPIO_ADC0_AD0 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN21) +#define GPIO_ADC0_AD1 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN30) +#define GPIO_ADC0_AD2 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN3) +#define GPIO_ADC0_AD3 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN4) +#define GPIO_ADC0_AD4 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN15) +#define GPIO_ADC0_AD5 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN16) +#define GPIO_ADC0_AD6 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN17) +#define GPIO_ADC0_AD7 (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN18) + +#define GPIO_CAN_XCVR_RS (GPIO_OUTPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_OUTPUT_SET|GPIO_PIN23) +#define GPIO_CAN1_XCVR_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN27) +#define GPIO_CAN1_XCVR_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN26) +#define GPIO_CAN2_XCVR_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN29) +#define GPIO_CAN2_XCVR_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN28) + +#define GPIO_SMC_D0 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN9) /* Check! */ +#define GPIO_SMC_D1 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN10) /* Check! */ +#define GPIO_SMC_D2 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN11) /* Check! */ +#define GPIO_SMC_D3 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN12) /* Check! */ +#define GPIO_SMC_D4 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN13) /* Check! */ +#define GPIO_SMC_D5 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN14) /* Check! */ +#define GPIO_SMC_D6 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN15) /* Check! */ +#define GPIO_SMC_D7 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN16) /* Check! */ +#define GPIO_SMC_D8 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN25) /* Check! */ +#define GPIO_SMC_D9 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN26) /* Check! */ +#define GPIO_SMC_D10 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN27) /* Check! */ +#define GPIO_SMC_D11 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN28) /* Check! */ +#define GPIO_SMC_D12 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN29) /* Check! */ +#define GPIO_SMC_D13 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN30) /* Check! */ +#define GPIO_SMC_D14 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|{GPIO_PIN31) /* Check! */ +#define GPIO_SMC_D15 (GPIO_PERIPHB|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN6) /* Check! */ +#define GPIO_SMC_NCS0 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN20) +#define GPIO_SMC_NRD (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN19) +#define GPIO_SMC_NWE (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN23) +#define GPIO_SMC_PSRAM_A0 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN0) /* Check! */ +#define GPIO_SMC_PSRAM_A1 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN1) /* Check! */ +#define GPIO_SMC_PSRAM_A2 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN2) /* Check! */ +#define GPIO_SMC_PSRAM_A3 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN3) /* Check! */ +#define GPIO_SMC_PSRAM_A4 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN4) /* Check! */ +#define GPIO_SMC_PSRAM_A5 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN5) /* Check! */ +#define GPIO_SMC_PSRAM_A6 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN6) /* Check! */ +#define GPIO_SMC_PSRAM_A7 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN7) /* Check! */ +#define GPIO_SMC_PSRAM_A8 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN8) /* Check! */ +#define GPIO_SMC_PSRAM_A9 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN9) /* Check! */ +#define GPIO_SMC_PSRAM_A10 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN10) /* Check! */ +#define GPIO_SMC_PSRAM_A11 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN11) /* Check! */ +#define GPIO_SMC_PSRAM_A12 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN24) /* Check! */ +#define GPIO_SMC_PSRAM_A13 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN25) /* Check! */ +#define GPIO_SMC_PSRAM_A14 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN26) /* Check! */ +#define GPIO_SMC_PSRAM_A15 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN27) /* Check! */ +#define GPIO_SMC_PSRAM_A16 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN27) /* Check! */ +#define GPIO_SMC_PSRAM_A17 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN28) /* Check! */ +#define GPIO_SMC_PSRAM_A18 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|{GPIO_PIN29) /* Check! */ +#define GPIO_SMC_PSRAM_NBS0 (GPIO_PERIPHB|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN7) /* Check! */ +#define GPIO_SMC_PSRAM_NBS1 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|GPIO_PIN15) +#define GPIO_SMC_A1 (GPIO_PERIPHB|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN8) +#define GPIO_SMC_NCS2 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOC|GPIO_PIN16) +#define GPIO_SMC_LCD_RS (GPIO_PERIPHB|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN8) + +#define GPIO_HSMCI_DAT0 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN5) +#define GPIO_HSMCI_DAT1 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN6) +#define GPIO_HSMCI_DAT2 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN7) +#define GPIO_HSMCI_DAT3 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN8) +#define GPIO_HSMCI_DAT4 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN28) +#define GPIO_HSMCI_DAT5 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN29) +#define GPIO_HSMCI_DAT6 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN30) +#define GPIO_HSMCI_DAT7 (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOB|GPIO_PIN31) +#define GPIO_HSMCI_CK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN3) +#define GPIO_HSMCI_DA (GPIO_PERIPHA|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN4) +#define GPIO_HSMCI_DAT0IN (GPIO_INPUT|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN5) + +#define GPIO_PWM0_H (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN0) +#define GPIO_PWM0_L (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN7) +#define GPIO_PWM1_H (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN1) +#define GPIO_PWM1_L (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN8) +#define GPIO_PWM2_H (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN2) +#define GPIO_PWM2_L (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN9) + +#define GPIO_SPI0_MISO (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN13) +#define GPIO_SPI0_MOSI (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN14) +#define GPIO_SPI0_SPCK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN15) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN16) + +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN0) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN3) +#define GPIO_SPI0_NPCS1_3 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN19) +#define GPIO_SPI0_NPCS2_1 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN1) +#define GPIO_SPI0_NPCS2_2 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN4) +#define GPIO_SPI0_NPCS2_3 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN14) +#define GPIO_SPI0_NPCS3_1 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN19) +#define GPIO_SPI0_NPCS3_2 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN5) + +#define GPIO_SSC_TD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN26) +#define GPIO_SSC_TK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN28) +#define GPIO_SSC_TF (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN30) + +#define GPIO_PCK0 (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN21) + +#define GPIO_TWI0_D (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN9) +#define GPIO_TWI0_CK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN10) +#define GPIO_TW1I_D (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN24) +#define GPIO_TWI1_CK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN25) + +#define GPIO_UART0_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN12) +#define GPIO_UART0_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN11) + +#define GPIO_USART0_CTS (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN8) +#define GPIO_USART0_DCD (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN11) +#define GPIO_USART0_DSR (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN10) +#define GPIO_USART0_DTR (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN9) +#define GPIO_USART0_RI (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN12) +#define GPIO_USART0_RTS (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN7) +#define GPIO_USART0_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN19) +#define GPIO_USART0_SCK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN17) +#define GPIO_USART0_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN18) + +#define GPIO_USART1_CTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN23) +#define GPIO_USART1_RTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN22) +#define GPIO_USART1_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN24) +#define GPIO_USART1_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN20) + +#define GPIO_USART2_CTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN22) +#define GPIO_USART2_RTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_PIN21) +#define GPIO_USART2_RXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN23) +#define GPIO_USART2_SCK (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN25) +#define GPIO_USART2_TXD (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN22) + +#define GPIO_USART3_CTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN10) +#define GPIO_USART3_RTS (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN11) +#define GPIO_USART3_RXD (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN13) +#define GPIO_USART3_SCK (GPIO_PERIPHA|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN19) +#define GPIO_USART3_TXD (GPIO_PERIPHB|GPIO_CFG_DEFAULT|GPIO_PORT_PIOC|GPIO_PIN12) + +#define GPIO_USB_VBUS (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN0) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam3u_pio.h b/arch/arm/src/sam34/chip/sam3u_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..aa5e32266ff08537bc8cee9814cdcaa54b5ecdb3 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3u_pio.h @@ -0,0 +1,467 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam3u_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAM3U, SAM3X, and SAM3A. + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PIO_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */ +#define SAM_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */ +#define SAM_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */ + /* 0x000c: Reserved */ +#define SAM_PIO_OER_OFFSET 0x0010 /* Output Enable Register */ +#define SAM_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */ +#define SAM_PIO_OSR_OFFSET 0x0018 /* Output Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */ +#define SAM_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */ +#define SAM_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */ + /* 0x002c: Reserved */ +#define SAM_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */ +#define SAM_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */ +#define SAM_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define SAM_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */ +#define SAM_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */ +#define SAM_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */ + /* 0x005c: Reserved */ +#define SAM_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */ +#define SAM_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */ +#define SAM_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */ + /* 0x006c: Reserved */ +#define SAM_PIO_ABSR_OFFSET 0x0070 /* Peripheral AB Select Register */ + /* 0x0074-0x007c: Reserved */ +#define SAM_PIO_SCIFSR_OFFSET 0x0080 /* System Clock Glitch Input Filter Select Register */ +#define SAM_PIO_DIFSR_OFFSET 0x0084 /* Debouncing Input Filter Select Register */ +#define SAM_PIO_IFDGSR_OFFSET 0x0088 /* Glitch or Debouncing Input Filter Clock Selection Status Register */ +#define SAM_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */ + /* 0x0090-0x009c: Reserved */ +#define SAM_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */ +#define SAM_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */ +#define SAM_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */ + /* 0x00ac: Reserved */ +#define SAM_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */ +#define SAM_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */ +#define SAM_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */ + /* 0x00bc: Reserved */ +#define SAM_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */ +#define SAM_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */ +#define SAM_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */ + /* 0x00cc: Reserved */ +#define SAM_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */ +#define SAM_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */ +#define SAM_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */ + /* 0x00dc: Reserved */ +#define SAM_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */ +#define SAM_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8: Reserved */ + /* 0x0100-0x0144: Reserved */ + +/* PIO register addresses ***************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define PIOD (3) +# define PIOE (4) +# define PIOF (5) +# define NPIO (6) +#else +# define NPIO (3) +#endif + +#define SAM_PIO_PER(n) (SAM_PIO_BASE(n)+SAM_PIO_PER_OFFSET) +#define SAM_PIO_PDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDR_OFFSET) +#define SAM_PIO_PSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PSR_OFFSET) +#define SAM_PIO_OER(n) (SAM_PIO_BASE(n)+SAM_PIO_OER_OFFSET) +#define SAM_PIO_ODR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODR_OFFSET) +#define SAM_PIO_OSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OSR_OFFSET) +#define SAM_PIO_IFER(n) (SAM_PIO_BASE(n)+SAM_PIO_IFER_OFFSET) +#define SAM_PIO_IFDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFDR_OFFSET) +#define SAM_PIO_IFSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSR_OFFSET) +#define SAM_PIO_SODR(n) (SAM_PIO_BASE(n)+SAM_PIO_SODR_OFFSET) +#define SAM_PIO_CODR(n) (SAM_PIO_BASE(n)+SAM_PIO_CODR_OFFSET) +#define SAM_PIO_ODSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODSR_OFFSET) +#define SAM_PIO_PDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDSR_OFFSET) +#define SAM_PIO_IER(n) (SAM_PIO_BASE(n)+SAM_PIO_IER_OFFSET) +#define SAM_PIO_IDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IDR_OFFSET) +#define SAM_PIO_IMR(n) (SAM_PIO_BASE(n)+SAM_PIO_IMR_OFFSET) +#define SAM_PIO_ISR(n) (SAM_PIO_BASE(n)+SAM_PIO_ISR_OFFSET) +#define SAM_PIO_MDER(n) (SAM_PIO_BASE(n)+SAM_PIO_MDER_OFFSET) +#define SAM_PIO_MDDR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDDR_OFFSET) +#define SAM_PIO_MDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDSR_OFFSET) +#define SAM_PIO_PUDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUDR_OFFSET) +#define SAM_PIO_PUER(n) (SAM_PIO_BASE(n)+SAM_PIO_PUER_OFFSET) +#define SAM_PIO_PUSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUSR_OFFSET) +#define SAM_PIO_ABSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ABSR_OFFSET) +#define SAM_PIO_SCIFSR(n) (SAM_PIO_BASE(n)+SAM_PIO_SCIFSR_OFFSET) +#define SAM_PIO_DIFSR(n) (SAM_PIO_BASE(n)+SAM_PIO_DIFSR_OFFSET) +#define SAM_PIO_IFDGSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFDGSR_OFFSET) +#define SAM_PIO_SCDR(n) (SAM_PIO_BASE(n)+SAM_PIO_SCDR_OFFSET) +#define SAM_PIO_OWER(n) (SAM_PIO_BASE(n)+SAM_PIO_OWER_OFFSET) +#define SAM_PIO_OWDR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWDR_OFFSET) +#define SAM_PIO_OWSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWSR_OFFSET) +#define SAM_PIO_AIMER(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMER_OFFSET) +#define SAM_PIO_AIMDR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIO_AIMMR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIO_ESR(n) (SAM_PIO_BASE(n)+SAM_PIO_ESR_OFFSET) +#define SAM_PIO_LSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LSR_OFFSET) +#define SAM_PIO_ELSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ELSR_OFFSET) +#define SAM_PIO_FELLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIO_REHLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIO_FRLHSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIO_LOCKSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIO_WPMR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPMR_OFFSET) +#define SAM_PIO_WPSR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPSR_OFFSET) + +#define SAM_PIOA_PER (SAM_PIOA_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOA_PDR (SAM_PIOA_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOA_PSR (SAM_PIOA_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOA_OER (SAM_PIOA_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOA_ODR (SAM_PIOA_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOA_OSR (SAM_PIOA_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOA_IFER (SAM_PIOA_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOA_IFDR (SAM_PIOA_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOA_IFSR (SAM_PIOA_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIOA_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIOA_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIOA_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIOA_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIOA_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIOA_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIOA_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIOA_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_MDER (SAM_PIOA_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOA_MDDR (SAM_PIOA_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOA_MDSR (SAM_PIOA_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOA_PUDR (SAM_PIOA_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOA_PUER (SAM_PIOA_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOA_PUSR (SAM_PIOA_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOA_ABSR (SAM_PIOA_BASE+SAM_PIO_ABSR_OFFSET) +#define SAM_PIOA_SCIFSR (SAM_PIOA_BASE+SAM_PIO_SCIFSR_OFFSET) +#define SAM_PIOA_DIFSR (SAM_PIOA_BASE+SAM_PIO_DIFSR_OFFSET) +#define SAM_PIOA_IFDGSR (SAM_PIOA_BASE+SAM_PIO_IFDGSR_OFFSET) +#define SAM_PIOA_SCDR (SAM_PIOA_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOA_OWER (SAM_PIOA_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOA_OWDR (SAM_PIOA_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOA_OWSR (SAM_PIOA_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOA_AIMER (SAM_PIOA_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOA_AIMDR (SAM_PIOA_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOA_AIMMR (SAM_PIOA_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOA_ESR (SAM_PIOA_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOA_LSR (SAM_PIOA_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOA_ELSR (SAM_PIOA_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOA_FELLSR (SAM_PIOA_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOA_REHLSR (SAM_PIOA_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOA_FRLHSR (SAM_PIOA_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOA_LOCKSR (SAM_PIOA_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOA_WPMR (SAM_PIOA_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOA_WPSR (SAM_PIOA_BASE+SAM_PIO_WPSR_OFFSET) + +#define SAM_PIOB_PER (SAM_PIOB_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOB_PDR (SAM_PIOB_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOB_PSR (SAM_PIOB_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOB_OER (SAM_PIOB_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOB_ODR (SAM_PIOB_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOB_OSR (SAM_PIOB_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOB_IFER (SAM_PIOB_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOB_IFDR (SAM_PIOB_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOB_IFSR (SAM_PIOB_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOB_SODR (SAM_PIOB_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOB_CODR (SAM_PIOB_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOB_ODSR (SAM_PIOB_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOB_PDSR (SAM_PIOB_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOB_IER (SAM_PIOB_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOB_IDR (SAM_PIOB_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOB_IMR (SAM_PIOB_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOB_ISR (SAM_PIOB_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOB_MDER (SAM_PIOB_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOB_MDDR (SAM_PIOB_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOB_MDSR (SAM_PIOB_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOB_PUDR (SAM_PIOB_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOB_PUER (SAM_PIOB_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOB_PUSR (SAM_PIOB_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOB_ABSR (SAM_PIOB_BASE+SAM_PIO_ABSR_OFFSET) +#define SAM_PIOB_SCIFSR (SAM_PIOB_BASE+SAM_PIO_SCIFSR_OFFSET) +#define SAM_PIOB_DIFSR (SAM_PIOB_BASE+SAM_PIO_DIFSR_OFFSET) +#define SAM_PIOB_IFDGSR (SAM_PIOB_BASE+SAM_PIO_IFDGSR_OFFSET) +#define SAM_PIOB_SCDR (SAM_PIOB_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOB_OWER (SAM_PIOB_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOB_OWDR (SAM_PIOB_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOB_OWSR (SAM_PIOB_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOB_AIMER (SAM_PIOB_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOB_AIMDR (SAM_PIOB_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOB_AIMMR (SAM_PIOB_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOB_ESR (SAM_PIOB_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOB_LSR (SAM_PIOB_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOB_ELSR (SAM_PIOB_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOB_FELLSR (SAM_PIOB_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOB_REHLSR (SAM_PIOB_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOB_FRLHSR (SAM_PIOB_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOB_LOCKSR (SAM_PIOB_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOB_WPMR (SAM_PIOB_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOB_WPSR (SAM_PIOB_BASE+SAM_PIO_WPSR_OFFSET) + +#define SAM_PIOC_PER (SAM_PIOC_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOC_PDR (SAM_PIOC_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOC_PSR (SAM_PIOC_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOC_OER (SAM_PIOC_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOC_ODR (SAM_PIOC_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOC_OSR (SAM_PIOC_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOC_IFER (SAM_PIOC_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOC_IFDR (SAM_PIOC_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOC_IFSR (SAM_PIOC_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOC_SODR (SAM_PIOC_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOC_CODR (SAM_PIOC_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOC_ODSR (SAM_PIOC_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOC_PDSR (SAM_PIOC_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOC_IER (SAM_PIOC_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOC_IDR (SAM_PIOC_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOC_IMR (SAM_PIOC_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOC_ISR (SAM_PIOC_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOC_MDER (SAM_PIOC_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOC_MDDR (SAM_PIOC_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOC_MDSR (SAM_PIOC_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOC_PUDR (SAM_PIOC_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOC_PUER (SAM_PIOC_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOC_PUSR (SAM_PIOC_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOC_ABSR (SAM_PIOC_BASE+SAM_PIO_ABSR_OFFSET) +#define SAM_PIOC_SCIFSR (SAM_PIOC_BASE+SAM_PIO_SCIFSR_OFFSET) +#define SAM_PIOC_DIFSR (SAM_PIOC_BASE+SAM_PIO_DIFSR_OFFSET) +#define SAM_PIOC_IFDGSR (SAM_PIOC_BASE+SAM_PIO_IFDGSR_OFFSET) +#define SAM_PIOC_SCDR (SAM_PIOC_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOC_OWER (SAM_PIOC_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOC_OWDR (SAM_PIOC_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOC_OWSR (SAM_PIOC_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOC_AIMER (SAM_PIOC_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOC_AIMDR (SAM_PIOC_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOC_AIMMR (SAM_PIOC_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOC_ESR (SAM_PIOC_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOC_LSR (SAM_PIOC_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOC_ELSR (SAM_PIOC_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOC_FELLSR (SAM_PIOC_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOC_REHLSR (SAM_PIOC_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOC_FRLHSR (SAM_PIOC_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOC_LOCKSR (SAM_PIOC_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOC_WPMR (SAM_PIOC_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOC_WPSR (SAM_PIOC_BASE+SAM_PIO_WPSR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_PIOD_PER (SAM_PIOD_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOD_PDR (SAM_PIOD_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOD_PSR (SAM_PIOD_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOD_OER (SAM_PIOD_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOD_ODR (SAM_PIOD_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOD_OSR (SAM_PIOD_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOD_IFER (SAM_PIOD_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOD_IFDR (SAM_PIOD_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOD_IFSR (SAM_PIOD_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOD_SODR (SAM_PIOD_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOD_CODR (SAM_PIOD_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOD_ODSR (SAM_PIOD_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOD_PDSR (SAM_PIOD_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOD_IER (SAM_PIOD_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOD_IDR (SAM_PIOD_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOD_IMR (SAM_PIOD_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOD_ISR (SAM_PIOD_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOD_MDER (SAM_PIOD_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOD_MDDR (SAM_PIOD_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOD_MDSR (SAM_PIOD_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOD_PUDR (SAM_PIOD_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOD_PUER (SAM_PIOD_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOD_PUSR (SAM_PIOD_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOD_ABSR (SAM_PIOD_BASE+SAM_PIO_ABSR_OFFSET) +# define SAM_PIOD_SCIFSR (SAM_PIOD_BASE+SAM_PIO_SCIFSR_OFFSET) +# define SAM_PIOD_DIFSR (SAM_PIOD_BASE+SAM_PIO_DIFSR_OFFSET) +# define SAM_PIOD_IFDGSR (SAM_PIOD_BASE+SAM_PIO_IFDGSR_OFFSET) +# define SAM_PIOD_SCDR (SAM_PIOD_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOD_OWER (SAM_PIOD_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOD_OWDR (SAM_PIOD_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOD_OWSR (SAM_PIOD_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOD_AIMER (SAM_PIOD_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOD_AIMDR (SAM_PIOD_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOD_AIMMR (SAM_PIOD_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOD_ESR (SAM_PIOD_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOD_LSR (SAM_PIOD_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOD_ELSR (SAM_PIOD_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOD_FELLSR (SAM_PIOD_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOD_REHLSR (SAM_PIOD_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOD_FRLHSR (SAM_PIOD_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOD_LOCKSR (SAM_PIOD_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOD_WPMR (SAM_PIOD_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOD_WPSR (SAM_PIOD_BASE+SAM_PIO_WPSR_OFFSET) + +# define SAM_PIOE_PER (SAM_PIOE_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOE_PDR (SAM_PIOE_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOE_PSR (SAM_PIOE_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOE_OER (SAM_PIOE_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOE_ODR (SAM_PIOE_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOE_OSR (SAM_PIOE_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOE_IFER (SAM_PIOE_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOE_IFDR (SAM_PIOE_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOE_IFSR (SAM_PIOE_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOE_SODR (SAM_PIOE_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOE_CODR (SAM_PIOE_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOE_ODSR (SAM_PIOE_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOE_PDSR (SAM_PIOE_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOE_IER (SAM_PIOE_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOE_IDR (SAM_PIOE_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOE_IMR (SAM_PIOE_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOE_ISR (SAM_PIOE_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOE_MDER (SAM_PIOE_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOE_MDDR (SAM_PIOE_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOE_MDSR (SAM_PIOE_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOE_PUDR (SAM_PIOE_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOE_PUER (SAM_PIOE_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOE_PUSR (SAM_PIOE_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOE_ABSR (SAM_PIOE_BASE+SAM_PIO_ABSR_OFFSET) +# define SAM_PIOE_SCIFSR (SAM_PIOE_BASE+SAM_PIO_SCIFSR_OFFSET) +# define SAM_PIOE_DIFSR (SAM_PIOE_BASE+SAM_PIO_DIFSR_OFFSET) +# define SAM_PIOE_IFDGSR (SAM_PIOE_BASE+SAM_PIO_IFDGSR_OFFSET) +# define SAM_PIOE_SCDR (SAM_PIOE_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOE_OWER (SAM_PIOE_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOE_OWDR (SAM_PIOE_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOE_OWSR (SAM_PIOE_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOE_AIMER (SAM_PIOE_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOE_AIMDR (SAM_PIOE_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOE_AIMMR (SAM_PIOE_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOE_ESR (SAM_PIOE_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOE_LSR (SAM_PIOE_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOE_ELSR (SAM_PIOE_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOE_FELLSR (SAM_PIOE_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOE_REHLSR (SAM_PIOE_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOE_FRLHSR (SAM_PIOE_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOE_LOCKSR (SAM_PIOE_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOE_WPMR (SAM_PIOE_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOE_WPSR (SAM_PIOE_BASE+SAM_PIO_WPSR_OFFSET) + +# define SAM_PIOF_PER (SAM_PIOF_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOF_PDR (SAM_PIOF_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOF_PSR (SAM_PIOF_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOF_OER (SAM_PIOF_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOF_ODR (SAM_PIOF_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOF_OSR (SAM_PIOF_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOF_IFER (SAM_PIOF_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOF_IFDR (SAM_PIOF_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOF_IFSR (SAM_PIOF_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOF_SODR (SAM_PIOF_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOF_CODR (SAM_PIOF_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOF_ODSR (SAM_PIOF_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOF_PDSR (SAM_PIOF_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOF_IER (SAM_PIOF_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOF_IDR (SAM_PIOF_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOF_IMR (SAM_PIOF_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOF_ISR (SAM_PIOF_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOF_MDER (SAM_PIOF_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOF_MDDR (SAM_PIOF_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOF_MDSR (SAM_PIOF_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOF_PUDR (SAM_PIOF_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOF_PUER (SAM_PIOF_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOF_PUSR (SAM_PIOF_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOF_ABSR (SAM_PIOF_BASE+SAM_PIO_ABSR_OFFSET) +# define SAM_PIOF_SCIFSR (SAM_PIOF_BASE+SAM_PIO_SCIFSR_OFFSET) +# define SAM_PIOF_DIFSR (SAM_PIOF_BASE+SAM_PIO_DIFSR_OFFSET) +# define SAM_PIOF_IFDGSR (SAM_PIOF_BASE+SAM_PIO_IFDGSR_OFFSET) +# define SAM_PIOF_SCDR (SAM_PIOF_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOF_OWER (SAM_PIOF_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOF_OWDR (SAM_PIOF_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOF_OWSR (SAM_PIOF_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOF_AIMER (SAM_PIOF_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOF_AIMDR (SAM_PIOF_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOF_AIMMR (SAM_PIOF_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOF_ESR (SAM_PIOF_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOF_LSR (SAM_PIOF_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOF_ELSR (SAM_PIOF_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOF_FELLSR (SAM_PIOF_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOF_REHLSR (SAM_PIOF_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOF_FRLHSR (SAM_PIOF_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOF_LOCKSR (SAM_PIOF_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOF_WPMR (SAM_PIOF_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOF_WPSR (SAM_PIOF_BASE+SAM_PIO_WPSR_OFFSET) +#endif + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for ALMOST all IO registers (exceptions follow) */ + +#define PIO(n) (1<<(n)) /* Bit n: PIO n */ + +/* PIO Write Protect Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PIO_WPMR_WPKEY_MASK (0xffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x50494f << PIO_WPMR_WPKEY_SHIFT) + +/* PIO Write Protect Status Register */ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PIO_H */ diff --git a/arch/arm/src/sam34/chip/sam3u_vectors.h b/arch/arm/src/sam34/chip/sam3u_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..cd60941f2136d4dd8407fd2264ef937593a2b498 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3u_vectors.h @@ -0,0 +1,87 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam3u_vectors.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that + * supplies ach SAM3U vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/sam/sam3u_irq.h. + * sam_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 30 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 30 + +#else + VECTOR(sam_supc, SAM_IRQ_SUPC) /* Vector 16+0: Supply Controller */ + VECTOR(sam_rstc, SAM_IRQ_RSTC) /* Vector 16+1: Reset Controller */ + VECTOR(sam_rtc, SAM_IRQ_RTC) /* Vector 16+2: Real Time Clock */ + VECTOR(sam_rtt, SAM_IRQ_RTT) /* Vector 16+3: Real Time Timer */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+4: Watchdog Timer */ + VECTOR(sam_pmc, SAM_IRQ_PMC) /* Vector 16+5: Power Management Controller */ + VECTOR(sam_eefc0, SAM_IRQ_EEFC0) /* Vector 16+6: Enhanced Embedded Flash Controller 0 */ + VECTOR(sam_eefc1, SAM_IRQ_EEFC1) /* Vector 16+7: Enhanced Embedded Flash Controller 1 */ + VECTOR(sam_uart0, SAM_IRQ_UART0) /* Vector 16+8: Universal Asynchronous Receiver Transmitter */ + VECTOR(sam_smc, SAM_IRQ_SMC) /* Vector 16+9: Static Memory Controller */ + VECTOR(sam_pioa, SAM_IRQ_PIOA) /* Vector 16+10: Parallel I/O Controller A */ + VECTOR(sam_piob, SAM_IRQ_PIOB) /* Vector 16+11: Parallel I/O Controller B */ + VECTOR(sam_pioc, SAM_IRQ_PIOC) /* Vector 16+12: Parallel I/O Controller C */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+13: USART 0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+14: USART 1 */ + VECTOR(sam_usart2, SAM_IRQ_USART2) /* Vector 16+15: USART 2 */ + VECTOR(sam_usart3, SAM_IRQ_USART3) /* Vector 16+16: USART 3 */ + VECTOR(sam_hsmci, SAM_IRQ_HSMCI) /* Vector 16+17: High Speed Multimedia Card Interface */ + VECTOR(sam_twi0, SAM_IRQ_TWI0) /* Vector 16+18: Two-Wire Interface 0 */ + VECTOR(sam_twi1, SAM_IRQ_TWI1) /* Vector 16+19: Two-Wire Interface 1 */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+20: Serial Peripheral Interface */ + VECTOR(sam_ssc, SAM_IRQ_SSC) /* Vector 16+21: Synchronous Serial Controller */ + VECTOR(sam_tc0, SAM_IRQ_TC0) /* Vector 16+22: Timer Counter 0 */ + VECTOR(sam_tc1, SAM_IRQ_TC1) /* Vector 16+23: Timer Counter 1 */ + VECTOR(sam_tc2, SAM_IRQ_TC2) /* Vector 16+24: Timer Counter 2 */ + VECTOR(sam_pwm, SAM_IRQ_PWM) /* Vector 16+25: Pulse Width Modulation Controller */ + VECTOR(sam_adc12b, SAM_IRQ_ADC12B) /* Vector 16+26: 12-bit ADC Controller */ + VECTOR(sam_adc, SAM_IRQ_ADC) /* Vector 16+27: 10-bit ADC Controller */ + VECTOR(sam_dmac, SAM_IRQ_DMAC) /* Vector 16+28: DMA Controller */ + VECTOR(sam_udphs, SAM_IRQ_UDPHS) /* Vector 16+29: USB Device High Speed */ +#endif diff --git a/arch/arm/src/sam34/chip/sam3x_memorymap.h b/arch/arm/src/sam34/chip/sam3x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..e32e6ec226e60cd99928514b628ca2b945a006e7 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3x_memorymap.h @@ -0,0 +1,173 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam3x_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_EXTRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External RAM */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x003fffff: Boot Memory */ +#define SAM_INTFLASH0_BASE 0x00080000 /* 0x00080000-0x000fffff: Internal FLASH 0 */ +#define SAM_INTFLASH1_BASE (0x00080000 + SAM34_FLASH_SIZE/2) +#define SAM_INTROM_BASE 0x00100000 /* 0x00100000-0x001fffff: Internal ROM */ + /* 0x00200000-0x1fffffff: Reserved */ +/* Internal SRAM memory region */ + +#define SAM_INTSRAM0_BASE 0x20000000 /* 0x20000000-0x2007ffff: Internal SRAM 0 */ +#define SAM_INTSRAM1_BASE 0x20080000 /* 0x20080000-0x200fffff: Internal SRAM 1 */ +#define SAM_NFCSRAM_BASE 0x20100000 /* 0x20100000-0x2017ffff: NAND FLASH controller (SRAM) */ +#define SAM_UOTGHSRAM_BASE 0x20180000 /* 0x20100000-0x201fffff: UOTGHS controller (DMA) */ + /* 0x20200000-0x201fffff: Undefined */ +#define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32Mb bit-band alias */ + /* 0x24000000-0x3fffffff: Undefined */ +/* Peripherals address region */ + +#define SAM_HSMCI_BASE 0x40000000 /* 0x40000000-0x400003ff: High Speed Multimedia Card Interface */ +#define SAM_SSC_BASE 0x40004000 /* 0x40004000-0x40007fff: Synchronous Serial Controller */ +#define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface 0 */ +#define SAM_SPI1_BASE 0x4000c000 /* 0x40008000-0x4007ffff: Serial Peripheral Interface 1 */ +#define SAM_TC_BASE 0x40080000 /* 0x40080000-0x4008bfff: Timer Counters */ +# define SAM_TC0_BASE 0x40080000 /* 0x40080000-0x4008003f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x40080040 /* 0x40080040-0x4008007f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x40080080 /* 0x40080080-0x400800bf: Timer Counter 2 */ + /* 0x400800c0-0x40083fff Reserved */ +# define SAM_TC3_BASE 0x40084000 /* 0x40084000-0x4008403f: Timer Counter 0 */ +# define SAM_TC4_BASE 0x40084040 /* 0x40084040-0x4008407f: Timer Counter 1 */ +# define SAM_TC5_BASE 0x40084080 /* 0x40084080-0x400840bf: Timer Counter 2 */ + /* 0x400840c0-0x40087fff Reserved */ +# define SAM_TC6_BASE 0x40088000 /* 0x40088000-0x4008803f: Timer Counter 3 */ +# define SAM_TC7_BASE 0x40088040 /* 0x40088040-0x4008807f: Timer Counter 4 */ +# define SAM_TC8_BASE 0x40088080 /* 0x40088080-0x400880bf: Timer Counter 5 */ + /* 0x400880c0-0x4008ffff Reserved */ +#define SAM_TWI_BASE 0x4008c000 /* 0x4008c000-0x4001ffff: Two-Wire Interface */ +# define SAM_TWI0_BASE 0x4008c000 /* 0x4008c000-0x4008ffff: Two-Wire Interface 0 */ +# define SAM_TWI1_BASE 0x40090000 /* 0x40090000-0x40093fff: Two-Wire Interface 1 */ +#define SAM_PWM_BASE 0x40094000 /* 0x40020000-0x4003ffff: Pulse Width Modulation */ +#define SAM_USART_BASE 0x40098000 /* 0x40098000-0x4002bfff: USART */ +# define SAM_USART0_BASE 0x40098000 /* 0x40098000-0x400a7fff: USART0 */ +# define SAM_USART1_BASE 0x4009c000 /* 0x4009c000-0x400bffff: USART1 */ +# define SAM_USART2_BASE 0x400a0000 /* 0x40028000-0x400a3fff: USART2 */ +# define SAM_USART3_BASE 0x400a4000 /* 0x40028000-0x400a7fff: USART3 */ + /* 0x400a8000-0x400ac000: Reserved */ +#define SAM_UOTGHS_BASE 0x40034000 /* 0x40034000-0x400affff: USB OTG High Speed */ +#define SAM_EMAC_BASE 0x400b0000 /* 0x400b0000-0x400b3fff: Ethernet MAC */ +#define SAM_CAN_BASE 0x400b4000 /* 0x400b4000-0x400bbfff: CAN */ +#define SAM_CAN0_BASE 0x400b4000 /* 0x400b4000-0x400b7fff: CAN0 */ +#define SAM_CAN1_BASE 0x400b8000 /* 0x400b8000-0x400bbfff: CAN1 */ +#define SAM_TRNG_BASE 0x400bc000 /* 0x400bc000-0x400bffff: True Random Number Generator */ +#define SAM_ADC_BASE 0x400c0000 /* 0x400c0000-0x400c3fff: Analog To Digital Converter */ +#define SAM_DMAC_BASE 0x400c4000 /* 0x400c4000-0x400c7fff: DMA controller */ +#define SAM_DACC_BASE 0x400c8000 /* 0x400c8000-0x400cffff: Digital To Analog Converter */ + /* 0x400d0000-0x400dffff: Reserved */ +#define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x4007ffff: System Controller */ + /* 0x40080000-0x40ffffff: Reserved */ + /* 0x41000000-0x41ffffff: Undefined */ +#define SAM_BBPERIPH_BASE 0x42000000 /* 0x42000000-0x43ffffff: 32Mb bit-band alias */ + /* 0x44000000-0x5fffffff: Undefined */ +/* System Controller Register Blocks: 0x400e0000-0x4007ffff */ + +#define SAM_SMC_BASE 0x400e0000 /* 0x400e0000-0x400e01ff: Static Memory Controller */ +#define SAM_SDRAMC_BASE 0x400e0200 /* 0x400e0200-0x400e03ff: SDRAM Controller */ +#define SAM_MATRIX_BASE 0x400e0400 /* 0x400e0400-0x400E05ff: MATRIX */ +#define SAM_PMC_BASE 0x400e0600 /* 0x400e0600-0x400e07ff: Power Management Controller */ +#define SAM_UART0_BASE 0x400e0800 /* 0x400e0800-0x400e093f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0940 /* 0x400e0940-0x400e09ff: CHIP ID */ +#define SAM_EEFC_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controllers*/ +# define SAM_EEFC0_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controller 0 */ +# define SAM_EEFC1_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Enhanced Embedded Flash Controller 1 */ +#define SAM_PIO_BASE 0x400e0e00 /* 0x400e0e00-0x400e13ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0e00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1200 /* 0x400e1200-0x400e13ff: Parallel I/O Controller C */ +# define SAM_PIOD_BASE 0x400e1400 /* 0x400e1400-0x400e15ff: Parallel I/O Controller D */ +# define SAM_PIOE_BASE 0x400e1600 /* 0x400e1600-0x400e17ff: Parallel I/O Controller E */ +# define SAM_PIOF_BASE 0x400e1800 /* 0x400e1800-0x400e19ff: Parallel I/O Controller F */ +#define SAM_RSTC_BASE 0x400e1a00 /* 0x400e1a00-0x400e1a0f: Reset Controller */ +#define SAM_SUPC_BASE 0x400e1a10 /* 0x400e1a10-0x400e1a2f: Supply Controller */ +#define SAM_RTT_BASE 0x400e1a30 /* 0x400e1a30-0x400e1a4f: Real Time Timer */ +#define SAM_WDT_BASE 0x400e1a50 /* 0x400e1a50-0x400e1a5f: Watchdog Timer */ +#define SAM_RTC_BASE 0x400e1a60 /* 0x400e1a60-0x400e1a8f: Real Time Clock */ +#define SAM_GPBR_BASE 0x400e1a90 /* 0x400e1a90-0x400e1aaf: GPBR */ + /* 0x400e1ab0-0x4007ffff: Reserved */ +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */ +# define SAM_EXTCSN_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x61ffffff: Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */ +# define SAM_EXTCS4_BASE 0x64000000 /* 0x64000000-0x64ffffff: Chip select 3 */ +# define SAM_EXTCS5_BASE 0x65000000 /* 0x65000000-0x65ffffff: Chip select 3 */ +# define SAM_EXTCS6_BASE 0x66000000 /* 0x66000000-0x66ffffff: Chip select 3 */ +# define SAM_EXTCS7_BASE 0x67000000 /* 0x67000000-0x67ffffff: Chip select 3 */ +#define SAM_NFC_BASE 0x68000000 /* 0x68000000-0x68ffffff: NFC */ + /* 0x69000000-0x6fffffff: Reserved */ +#define SAM_SDRAMCS_BASE 0x70000000 /* 0x70000000-0x7fffffff: SDRAM chip select */ + /* 0x80000000-0x9fffffff: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam3x_pinmap.h b/arch/arm/src/sam34/chip/sam3x_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..4b886dd53ffd86b883376d5476d79c171562bb6b --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3x_pinmap.h @@ -0,0 +1,459 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam3x_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the PWM0 Output high on PE15, then the following definition should appear + * in the board.h header file for that board: + * + * #define GPIO_PWM0_H GPIO_PWM0_H_1 + * + * The driver will then automatically configre RE15 as the PWM0 H pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* 12-bit Analog-to-Digital Conververt (ADC) */ + +#define GPIO_ADC0_AD0 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_ADC0_AD1 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_ADC0_AD2 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_ADC0_AD3 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_ADC0_AD4 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_ADC0_AD5 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_ADC0_AD6 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_ADC0_AD7 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_ADC0_AD8 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_ADC0_AD9 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_ADC0_AD10 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN17) +#define GPIO_ADC0_AD11 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN18) +#define GPIO_ADC0_AD12 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN19) +#define GPIO_ADC0_AD13 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN20) +#define GPIO_ADC0_AD14 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN21) +#define GPIO_ADC0_ADTRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) + +/* Digital-to-Analog Convert (DAC) */ + +#define GPIO_DAC0 (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN15) +#define GPIO_DAC1 (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN16) +#define GPIO_DATRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) + +/* CAN */ + +#define GPIO_CAN0_RX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_CAN0_TX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_CAN1_RX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN15) +#define GPIO_CAN1_TX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) + +/* Ethernet MAC */ + +#define GPIO_EMAC_COL (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_EMAC_CRS (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_EMAC_CRSDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_EMAC_MDC (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN8) +#define GPIO_EMAC_MDIO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN9) +#define GPIO_EMAC_REFCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_EMAC_RX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_EMAC_RX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_EMAC_RX2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_EMAC_RX3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_EMAC_RXCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_EMAC_RXDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_EMAC_RXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_EMAC_TX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_EMAC_TX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_EMAC_TX2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_EMAC_TX3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_EMAC_TXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_EMAC_TXEN (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_EMAC_TXER (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN17) + +/* High-Speed Multimedia Card Interface (HSMCI) */ + +#define GPIO_HSMCIA_CD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_HSMCIA_DAT0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_HSMCIA_DAT1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_HSMCIA_DAT2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_HSMCIA_DAT3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_HSMCIA_DAT4 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_HSMCIA_DAT5 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_HSMCIA_DAT6 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_HSMCIA_DAT7 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_HSMCIB_CD (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN20) +#define GPIO_HSMCIB_DAT0 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN22) +#define GPIO_HSMCIB_DAT1 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN24) +#define GPIO_HSMCIB_DAT2 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN26) +#define GPIO_HSMCIB_DAT3 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN27) +#define GPIO_HSMCI_CK (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PCK0_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN22) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWM0_FI (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_PWM0_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN15) +#define GPIO_PWM0_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_PWM0_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWM0_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_PWM0_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN18) +#define GPIO_PWM0_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PWM0_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN16) +#define GPIO_PWM0_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWM1_FI (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_PWM1_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN16) +#define GPIO_PWM1_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWM1_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWM1_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_PWM1_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWM1_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN17) +#define GPIO_PWM1_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_PWM2_FI (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_PWM2_H_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWM2_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_PWM2_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_PWM2_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN17) +#define GPIO_PWM2_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWM2_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN18) +#define GPIO_PWM2_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_PWM3_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN3) +#define GPIO_PWM3_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWM3_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN15) +#define GPIO_PWM3_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_PWM3_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWM3_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN19) +#define GPIO_PWM3_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_PWM4_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN20) +#define GPIO_PWM4_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWM4_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN19) +#define GPIO_PWM4_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_PWM4_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWM5_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN22) +#define GPIO_PWM5_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWM5_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN21) +#define GPIO_PWM5_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_PWM5_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWM6_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN24) +#define GPIO_PWM6_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWM6_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN23) +#define GPIO_PWM6_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN8) +#define GPIO_PWM6_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_PWM7_H (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN26) +#define GPIO_PWM7_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN25) +#define GPIO_PWM7_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN9) +#define GPIO_PWM7_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) + +/* Static Memory Controller (SMC) */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A5_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A5_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN17) +#define GPIO_SMC_A6_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A6_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SMC_A7_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A7_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_SMC_A8_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A8_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_SMC_A9_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A9_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_SMC_A10_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_SMC_A10_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_SMC_A11_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_SMC_A11_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_SMC_A12_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_SMC_A12_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_SMC_A13_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_SMC_A13_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_SMC_A14_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_SMC_A14_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_SMC_A15_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_SMC_A15_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_SMC_A16_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_SMC_A16_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_SMC_A17_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN29) +#define GPIO_SMC_A17_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_SMC_A18_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_SMC_A18_2 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_A18_3 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOB | GPIO_PIN10) +#define GPIO_SMC_A19_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN0) +#define GPIO_SMC_A19_2 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_SMC_A19_3 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOB | GPIO_PIN11) +#define GPIO_SMC_A20_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN1) +#define GPIO_SMC_A20_2 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A20_3 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_SMC_A21_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_SMC_A21_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_SMC_A22_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_SMC_A22_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_SMC_A23 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_D8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_D9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_D10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_D11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_D12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_D13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_D14 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_D15 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NCS0 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_SMC_NCS1 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_SMC_NCS2 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOB | GPIO_PIN24) +#define GPIO_SMC_NCS3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOB | GPIO_PIN27) +#define GPIO_SMC_NCS4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_SMC_NCS5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN6) +#define GPIO_SMC_NCS6 (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN18) +#define GPIO_SMC_NCS7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN27) +#define GPIO_SMC_NRD (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_SMC_NWAIT (GPIO_PERIPHB | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_NWR0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_NWR1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN10) + +/* NAND Interface */ + +#define GPIO_NAND_ALE_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_NAND_ALE_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_NAND_CLE_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_NAND_CLE_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_NAND_OE (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_NAND_RDY (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_NAND_WE (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) + +/* SDRAM Controller */ + +#define GPIO_SDRAM_BA0_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_SDRAM_BA0_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_SDRAM_BA1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN29) +#define GPIO_SDRAM_BA1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_SDRAM_CAS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_SDRAM_NBS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SDRAM_NBS1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_SDRAM_RAS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_SDRAM_SDA10 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_SDRAM_SDCKE (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_SDRAM_SDCS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_SDRAM_SDWE (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SPI0_MOSI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN20) +#define GPIO_SPI0_NPCS2_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_SPI0_NPCS2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN21) +#define GPIO_SPI0_NPCS3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN23) +#define GPIO_SPI0_SPCK_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_SPI0_SPCK_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_SPI1_MISO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN28) +#define GPIO_SPI1_MOSI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN29) +#define GPIO_SPI1_NPCS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN31) +#define GPIO_SPI1_NPCS1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN0) +#define GPIO_SPI1_NPCS2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN1) +#define GPIO_SPI1_NPCS3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN2) +#define GPIO_SPI1_SPCK_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_SPI1_SPCK_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN30) + +/* Synchronous Serial Controller (SSC) */ + +#define GPIO_SSC_RD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN18) +#define GPIO_SSC_RF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN17) +#define GPIO_SSC_RK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN19) +#define GPIO_SSC_TD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_SSC_TF (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SSC_TK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN26) +#define GPIO_TC0_IOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN25) +#define GPIO_TC0_IOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN27) +#define GPIO_TC1_CLK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC1_IOA (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_TC1_IOB (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TC2_CLK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_TC2_IOA (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_TC2_IOB (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_TC3_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_TC3_IOA_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN9) +#define GPIO_TC3_IOA_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_TC3_IOB_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN10) +#define GPIO_TC3_IOB_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_TC4_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_TC4_IOA_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN11) +#define GPIO_TC4_IOA_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_TC4_IOB_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN12) +#define GPIO_TC4_IOB_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_TC5_CLK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN16) +#define GPIO_TC5_IOA_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN13) +#define GPIO_TC5_IOA_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_TC5_IOB_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN14) +#define GPIO_TC5_IOB_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TC6_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC6_IOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC6_IOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC7_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_TC7_IOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC7_IOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC8_CLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_TC8_IOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_TC8_IOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) + +/* Two Wire Interface (TWI) */ + +#define GPIO_TWI0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_TWI0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_TWI1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_TWI1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN26) +#define GPIO_USART0_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN25) +#define GPIO_USART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_USART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_USART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_USART2_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN23) +#define GPIO_USART2_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN22) +#define GPIO_USART2_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN21) +#define GPIO_USART2_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN24) +#define GPIO_USART2_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN20) +#define GPIO_USART3_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN4) +#define GPIO_USART3_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOF | GPIO_PIN5) +#define GPIO_USART3_RXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_USART3_SCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN16) +#define GPIO_USART3_TXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) + +/* USB OTG High Speed */ + +#define GPIO_USBOTGHS_ID (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN11) +#define GPIO_USBOTGHS_VBOF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN10) + +/* Debug */ + +#define GPIO_JTAG_TCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN28) +#define GPIO_JTAG_TDI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN29_| +#define GPIO_JTAG_TDO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN30) +#define GPIO_JTAG_TMS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN31) + +#define GPIO_SWI_SSWCLK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN28) +#define GPIO_SWI_SWDIO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN31) +#define GPIO_SWI_TRACESWO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN30) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3X_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam3x_vectors.h b/arch/arm/src/sam34/chip/sam3x_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..f448088df628ad7572d789670864311791e582cf --- /dev/null +++ b/arch/arm/src/sam34/chip/sam3x_vectors.h @@ -0,0 +1,102 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam3x_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that + * supplies ach SAM3U vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/sam/sam3u_irq.h. + * sam_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 45 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 45 + +#else + VECTOR(sam_supc, SAM_IRQ_SUPC) /* Vector 16+0: Supply Controller */ + VECTOR(sam_rstc, SAM_IRQ_RSTC) /* Vector 16+1: Reset Controller */ + VECTOR(sam_rtc, SAM_IRQ_RTC) /* Vector 16+2: Real Time Clock */ + VECTOR(sam_rtt, SAM_IRQ_RTT) /* Vector 16+3: Real Time Timer */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+4: Watchdog Timer */ + VECTOR(sam_pmc, SAM_IRQ_PMC) /* Vector 16+5: Power Management Controller */ + VECTOR(sam_eefc0, SAM_IRQ_EEFC0) /* Vector 16+6: Enhanced Embedded Flash Controller 0 */ + VECTOR(sam_eefc1, SAM_IRQ_EEFC1) /* Vector 16+7: Enhanced Embedded Flash Controller 1 */ + VECTOR(sam_uart0, SAM_IRQ_UART0) /* Vector 16+8: Universal Asynchronous Receiver Transmitter */ + VECTOR(sam_smc, SAM_IRQ_SMC) /* Vector 16+9: Static Memory Controller */ + VECTOR(sam_sdramc, SAM_IRQ_SDRAMC) /* Vector 16+10: Synchronous Dynamic RAM Controller */ + VECTOR(sam_pioa, SAM_IRQ_PIOA) /* Vector 16+11: Parallel I/O Controller A */ + VECTOR(sam_piob, SAM_IRQ_PIOB) /* Vector 16+12: Parallel I/O Controller B */ + VECTOR(sam_pioc, SAM_IRQ_PIOC) /* Vector 16+13: Parallel I/O Controller C */ + VECTOR(sam_piod, SAM_IRQ_PIOD) /* Vector 16+14: Parallel I/O Controller D */ + VECTOR(sam_pioe, SAM_IRQ_PIOE) /* Vector 16+15: Parallel I/O Controller E */ + VECTOR(sam_piof, SAM_IRQ_PIOF) /* Vector 16+16: Parallel I/O Controller F */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+17: USART 0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+18: USART 1 */ + VECTOR(sam_usart2, SAM_IRQ_USART2) /* Vector 16+19: USART 2 */ + VECTOR(sam_usart3, SAM_IRQ_USART3) /* Vector 16+20: USART 3 */ + VECTOR(sam_hsmci, SAM_IRQ_HSMCI) /* Vector 16+21: High Speed Multimedia Card Interface */ + VECTOR(sam_twi0, SAM_IRQ_TWI0) /* Vector 16+22: Two-Wire Interface 0 */ + VECTOR(sam_twi1, SAM_IRQ_TWI1) /* Vector 16+23: Two-Wire Interface 1 */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+24: Serial Peripheral Interface 0 */ + VECTOR(sam_spi1, SAM_IRQ_SPI1) /* Vector 16+25: Serial Peripheral Interface 1 */ + VECTOR(sam_ssc, SAM_IRQ_SSC) /* Vector 16+26: Synchronous Serial Controller */ + VECTOR(sam_tc0, SAM_IRQ_TC0) /* Vector 16+27: Timer Counter 0 */ + VECTOR(sam_tc1, SAM_IRQ_TC1) /* Vector 16+28: Timer Counter 1 */ + VECTOR(sam_tc2, SAM_IRQ_TC2) /* Vector 16+29: Timer Counter 2 */ + VECTOR(sam_tc3, SAM_IRQ_TC3) /* Vector 16+30: Timer Counter 3 */ + VECTOR(sam_tc4, SAM_IRQ_TC4) /* Vector 16+31: Timer Counter 4 */ + VECTOR(sam_tc5, SAM_IRQ_TC5) /* Vector 16+32: Timer Counter 5 */ + VECTOR(sam_tc6, SAM_IRQ_TC6) /* Vector 16+33: Timer Counter 6 */ + VECTOR(sam_tc7, SAM_IRQ_TC7) /* Vector 16+34: Timer Counter 7 */ + VECTOR(sam_tc8, SAM_IRQ_TC8) /* Vector 16+35: Timer Counter 8 */ + VECTOR(sam_pwm, SAM_IRQ_PWM) /* Vector 16+36: Pulse Width Modulation Controller */ + VECTOR(sam_adc, SAM_IRQ_ADC) /* Vector 16+37: ADC Controller */ + VECTOR(sam_dacc, SAM_IRQ_DACC) /* Vector 16+38: DAC Controller */ + VECTOR(sam_dmac, SAM_IRQ_DMAC) /* Vector 16+39: DMA Controller */ + VECTOR(sam_uotghs, SAM_IRQ_UOTGHS) /* Vector 16+40: USB OTG High Speed */ + VECTOR(sam_trng, SAM_IRQ_TRNG) /* Vector 16+41: True Random Number Generator */ + VECTOR(sam_emac, SAM_IRQ_EMAC) /* Vector 16+42: Ethernet MAC */ + VECTOR(sam_can0, SAM_IRQ_CAN0) /* Vector 16+43: CAN Controller 0 */ + VECTOR(sam_can1, SAM_IRQ_CAN1) /* Vector 16+44: CAN Controller 1 */ +#endif diff --git a/arch/arm/src/sam34/chip/sam4cm_aes.h b/arch/arm/src/sam34/chip/sam4cm_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..051318dd170c7eb3e8f3aa15fae0582399ab4094 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_aes.h @@ -0,0 +1,139 @@ +/******************************************************************************************** + * arch/arm/src/sam34/chip/sam4cm_aes.h + * AES hardware accelerator for SAM4CM + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_AES_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_AES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* AES register offsets *********************************************************************/ + +#define SAM_AES_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_AES_MR_OFFSET 0x0004 /* Control Register */ +#define SAM_AES_IER_OFFSET 0x0010 /* Interrupt Enable Register */ +#define SAM_AES_IDR_OFFSET 0x0014 /* Interrupt Disable Register */ +#define SAM_AES_IMR_OFFSET 0x0018 /* Interrupt Mask Register */ +#define SAM_AES_ISR_OFFSET 0x001C /* Interrupt Status Register */ +#define SAM_AES_KEYWR_OFFSET 0x0020 /* Key Word Register */ +#define SAM_AES_IDATAR_OFFSET 0x0040 /* Input Data Register */ +#define SAM_AES_ODATAR_OFFSET 0x0050 /* Output Data Register */ +#define SAM_AES_IVR_OFFSET 0x0060 /* Initialization Vector Register */ +#define SAM_AES_AADLENR_OFFSET 0x0070 /* Additional Authenticated Data Length Register */ +#define SAM_AES_CLENR_OFFSET 0x0074 /* Plaintext/Ciphertext Length Register */ +#define SAM_AES_GHASHR_OFFSET 0x0078 /* GCM Intermediate Hash Word Register */ +#define SAM_AES_TAGR_OFFSET 0x0088 /* GCM Authentication Tag Word Register */ +#define SAM_AES_CTRR_OFFSET 0x0098 /* GCM Encryption Counter Value Register */ +#define SAM_AES_GCMHR_OFFSET 0x009C /* GCM H World Register */ + +/* AES register addresses *******************************************************************/ + +#define SAM_AES_CR (SAM_AES_BASE + SAM_AES_CR_OFFSET) +#define SAM_AES_MR (SAM_AES_BASE + SAM_AES_MR_OFFSET) +#define SAM_AES_IER (SAM_AES_BASE + SAM_AES_IER_OFFSET) +#define SAM_AES_IDR (SAM_AES_BASE + SAM_AES_IDR_OFFSET) +#define SAM_AES_IMR (SAM_AES_BASE + SAM_AES_IMR_OFFSET) +#define SAM_AES_ISR (SAM_AES_BASE + SAM_AES_ISR_OFFSET) +#define SAM_AES_KEYWR (SAM_AES_BASE + SAM_AES_KEYWR_OFFSET) +#define SAM_AES_IDATAR (SAM_AES_BASE + SAM_AES_IDATAR_OFFSET) +#define SAM_AES_ODATAR (SAM_AES_BASE + SAM_AES_ODATAR_OFFSET) +#define SAM_AES_IVR (SAM_AES_BASE + SAM_AES_IVR_OFFSET) +#define SAM_AES_AADLENR (SAM_AES_BASE + SAM_AES_AADLENR_OFFSET) +#define SAM_AES_CLENR (SAM_AES_BASE + SAM_AES_CLENR_OFFSET) +#define SAM_AES_GHASHR (SAM_AES_BASE + SAM_AES_GHASHR_OFFSET) +#define SAM_AES_TAGR (SAM_AES_BASE + SAM_AES_TAGR_OFFSET) +#define SAM_AES_CTRR (SAM_AES_BASE + SAM_AES_CTRR_OFFSET) +#define SAM_AES_GCMHR (SAM_AES_BASE + SAM_AES_GCMHR_OFFSET) + +/* AES register bit definitions *************************************************************/ + +/* AES Control Register */ + +#define AES_CR_START (1 << 0) /* Start Processing */ +#define AES_CR_SWRST (1 << 8) /* Software Reset */ + +/* AES Mode Register */ + +#define AES_MR_CIPHER_OFSET (0) +#define AES_MR_CIPHER_MASK (0x1 << AES_MR_CIPHER_OFSET) +# define AES_MR_CIPHER_DECRYPT (0 << AES_MR_CIPHER_OFSET) +# define AES_MR_CIPHER_ENCRYPT (1 << AES_MR_CIPHER_OFSET) +#define AES_MR_GTAGEN (1 << 1) /* GCM Automatic Tag Generation Enable */ +#define AES_MR_DUALBUFF (1 << 3) /* Dual Input Buffer (requires SMOD = 0x2) */ +#define AES_MR_PROCDLY(n) ((n) << 4) /* Processing Time = 12 × ( PROCDLY + 1 ) */ +#define AES_MR_SMOD_OFSET (8) +#define AES_MR_SMOD_MASK (0x3 << AES_MR_SMOD_OFSET) +# define AES_MR_SMOD_MANUAL_START (0 << AES_MR_SMOD_OFSET) /* Manual Mode */ +# define AES_MR_SMOD_AUTO_START (1 << AES_MR_SMOD_OFSET) /* Auto Mode */ +# define AES_MR_SMOD_IDATAR0_START (2 << AES_MR_SMOD_OFSET) /* AES_IDATAR0 access only Auto Mode */ +#define AES_MR_KEYSIZE_OFFSET (10) +#define AES_MR_KEYSIZE_MASK (0x3 << AES_MR_KEYSIZE_OFFSET) +# define AES_MR_KEYSIZE_AES128 (0 << AES_MR_KEYSIZE_OFFSET) /* AES Key Size is 128 bits */ +# define AES_MR_KEYSIZE_AES192 (1 << AES_MR_KEYSIZE_OFFSET) /* AES Key Size is 192 bits */ +# define AES_MR_KEYSIZE_AES256 (2 << AES_MR_KEYSIZE_OFFSET) /* AES Key Size is 256 bits */ +#define AES_MR_OPMOD_OFFSET (12) +#define AES_MR_OPMOD_MASK (0x7 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_ECB (0 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_CBC (1 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_OFB (2 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_CFB (3 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_CTR (4 << AES_MR_OPMOD_OFFSET) +# define AES_MR_OPMOD_GCM (5 << AES_MR_OPMOD_OFFSET) +#define AES_MR_LOD (1 << 15) /* Last Output Data Mode */ +#define AES_MR_CFBS_OFFSET (16) /* Cipher Feedback Data Size */ +#define AES_MR_CFBS_MASK (0x7 << AES_MR_CFBS_OFFSET) +# define AES_MR_CFBS_SIZE_128BIT (0 << AES_MR_CFBS_OFFSET) +# define AES_MR_CFBS_SIZE_64BIT (1 << AES_MR_CFBS_OFFSET) +# define AES_MR_CFBS_SIZE_32BIT (2 << AES_MR_CFBS_OFFSET) +# define AES_MR_CFBS_SIZE_16BIT (3 << AES_MR_CFBS_OFFSET) +# define AES_MR_CFBS_SIZE_8BIT (4 << AES_MR_CFBS_OFFSET) +#define AES_MR_CKEY (0xE << 20) + +/* AES Interrupt Status Register */ + +#define AES_ISR_DATRDY (1 << 0) + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_AES_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_ipc.h b/arch/arm/src/sam34/chip/sam4cm_ipc.h new file mode 100644 index 0000000000000000000000000000000000000000..a4d9d3ec3a23c5bb109c3b1525d9f462b039549a --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_ipc.h @@ -0,0 +1,80 @@ +/*********************************************************************************** + * arch/arm/src/sam34/chip/sam4cm_ipc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***********************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_IPC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_IPC_H + +/*********************************************************************************** + * Included Files + ***********************************************************************************/ + +#include +#include "chip.h" + +/*********************************************************************************** + * Pre-processor Definitions + ***********************************************************************************/ + +/* IPC register offsets ************************************************************/ + +#define SAM_SLCDC_CR_OFFSET 0x0000 /* Control Register */ + +#define SAM_IPC_ISCR_OFFSET 0x0000 /* Interrupt Set Command Register */ +#define SAM_IPC_ICCR_OFFSET 0x0004 /* Interrupt Clear Command Register */ +#define SAM_IPC_IPR_OFFSET 0x0008 /* Interrupt Pending Register */ +#define SAM_IPC_IECR_OFFSET 0x000C /* Interrupt Enable Command Register */ +#define SAM_IPC_IDCR_OFFSET 0x0010 /* Interrupt Disable Command Register */ +#define SAM_IPC_IMR_OFFSET 0x0014 /* Interrupt Mask Register */ +#define SAM_IPC_ISR_OFFSET 0x0018 /* Interrupt Status Register */ + +/* IPC register addresses **********************************************************/ + +#define SAM_IPC0_ISCR (SAM_IPC0_BASE + SAM_IPC_ISCR_OFFSET) +#define SAM_IPC0_ICCR (SAM_IPC0_BASE + SAM_IPC_ICCR_OFFSET) +#define SAM_IPC0_IPR (SAM_IPC0_BASE + SAM_IPC_IPR_OFFSET) +#define SAM_IPC0_IECR (SAM_IPC0_BASE + SAM_IPC_IECR_OFFSET) +#define SAM_IPC0_IDCR (SAM_IPC0_BASE + SAM_IPC_IDCR_OFFSET) +#define SAM_IPC0_IMR (SAM_IPC0_BASE + SAM_IPC_IMR_OFFSET) +#define SAM_IPC0_ISR (SAM_IPC0_BASE + SAM_IPC_ISR_OFFSET) + +#define SAM_IPC1_ISCR (SAM_IPC1_BASE + SAM_IPC_ISCR_OFFSET) +#define SAM_IPC1_ICCR (SAM_IPC1_BASE + SAM_IPC_ICCR_OFFSET) +#define SAM_IPC1_IPR (SAM_IPC1_BASE + SAM_IPC_IPR_OFFSET) +#define SAM_IPC1_IECR (SAM_IPC1_BASE + SAM_IPC_IECR_OFFSET) +#define SAM_IPC1_IDCR (SAM_IPC1_BASE + SAM_IPC_IDCR_OFFSET) +#define SAM_IPC1_IMR (SAM_IPC1_BASE + SAM_IPC_IMR_OFFSET) +#define SAM_IPC1_ISR (SAM_IPC1_BASE + SAM_IPC_ISR_OFFSET) + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_IPC_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_memorymap.h b/arch/arm/src/sam34/chip/sam4cm_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..155052388455e3cf26bd1eb135a91006e34323ca --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_memorymap.h @@ -0,0 +1,175 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4cm_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_EXTRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External RAM */ +#define SAM_EXTDEV_BASE 0xa0000000 /* 0xa0000000-0xdfffffff: External device */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x00ffffff: Boot Memory */ +#define SAM_INTFLASH_BASE 0x01000000 /* 0x01000000-0x01ffffff: Internal FLASH */ +#define SAM_INTROM_BASE 0x02000000 /* 0x02000000-0x02ffffff: Internal ROM */ + +/* Internal SRAM memory region */ + +#define SAM_INTSRAM0_BASE 0x20000000 /* For SAM3U compatibility */ +#define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32MB bit-band region */ + /* 0x24000000-0x3fffffff: Undefined */ +/* Peripherals address region */ + +#define SAM_AES_BASE 0x40000000 +#define SAM_SPI0_BASE 0x40008000 +#define SAM_TC0_BASE 0x40010000 +#define SAM_TC1_BASE 0x40010040 +#define SAM_TC2_BASE 0x40010080 +#define SAM_TC3_BASE 0x40014000 +#define SAM_TC4_BASE 0x40014040 +#define SAM_TC5_BASE 0x40014080 +#define SAM_TWI0_BASE 0x40018000 +#define SAM_TWI1_BASE 0x4001C000 +#define SAM_USART0_BASE 0x40024000 +#define SAM_USART1_BASE 0x40028000 +#define SAM_USART2_BASE 0x4002C000 +#define SAM_USART3_BASE 0x40030000 +#define SAM_ADC_BASE 0x40038000 +#define SAM_SLCDC_BASE 0x4003C000 +#define SAM_CPKCC_BASE 0x40040000 +#define SAM_ICM_BASE 0x40044000 +#define SAM_TRNG_BASE 0x40048000 +#define SAM_IPC0_BASE 0x4004C000 +#define SAM_CMCC0_BASE 0x4007C000 +#define SAM_SMC0_BASE 0x400E0000 +#define SAM_MATRIX_BASE 0x400E0200 +# define SAM_MATRIX0_BASE 0x400E0200 +#define SAM_PMC_BASE 0x400E0400 +#define SAM_UART0_BASE 0x400E0600 +#define SAM_CHIPID_BASE 0x400E0740 +#define SAM_EEFC0_BASE 0x400E0A00 +#define SAM_EEFC1_BASE 0x400E0C00 +#define SAM_PIOA_BASE 0x400E0E00 +#define SAM_PIOB_BASE 0x400E1000 +#define SAM_RSTC_BASE 0x400E1400 +#define SAM_SUPC_BASE 0x400E1410 +#define SAM_RTT_BASE 0x400E1430 +#define SAM_WDT_BASE 0x400E1450 +#define SAM_RTC_BASE 0x400E1460 +#define SAM_GPBR_BASE 0x400E1490 +#define SAM_UART1_BASE 0x48004000 +#define SAM_PWM_BASE 0x48008000 +#define SAM_PIOC_BASE 0x4800C000 +#define SAM_MATRIX1_BASE 0x48010000 +#define SAM_IPC1_BASE 0x48014000 +#define SAM_CMCC1_BASE 0x48018000 +#define SAM_SMC1_BASE 0x4801C000 + +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */ +# define SAM_EXTCSN_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */ + /* 0x64000000-0x9fffffff: Reserved */ +/* System memory region */ + +#define SAM_PRIVPERIPH_BASE 0xe0000000 /* 0xe0000000-0xe00fffff: Private peripheral bus */ +#define SAM_VENDOR_BASE 0xe0100000 /* 0ex0100000-0xffffffff: Vendor-specific memory */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +static inline unsigned long SAM_PION_BASE(int n) +{ + switch(n) { + case 0: + return SAM_PIOA_BASE; + case 1: + return SAM_PIOB_BASE; + case 2: + return SAM_PIOC_BASE; + default: + return 0; + } +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_pinmap.h b/arch/arm/src/sam34/chip/sam4cm_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..1cf999b3ef7c86ce1c692b04e75b00290f51b2ed --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_pinmap.h @@ -0,0 +1,322 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam4cm_pinmap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the programmable clock output PCK0 on PA6, then the following definition + * should appear in the board.h header file for that board: + * + * #define GPIO_PCK0 GPIO_PCK0_1 + * + * The driver will then automatically configure PA6 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* 12-bit Analog-to-Digital Converter (ADC) */ + +#define GPIO_ADC0_AD0 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_ADC0_AD1 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_ADC0_AD2 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_ADC0_AD3 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_PCK0_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PCK2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWM0_FI (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWM0_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWM0_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_PWM0_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWM0_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWM0_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWM0_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWM0_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_PWM0_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_PWM0_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_PWM1_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PWM1_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_PWM1_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWM1_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PWM1_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWM1_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_PWM1_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWM1_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWM1_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_PWM2_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_PWM2_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWM2_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_PWM2_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_PWM2_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWM2_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWM2_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWM2_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWM2_L_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_PWM3_H_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWM3_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_PWM3_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_PWM3_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWM3_H_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PWM3_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWM3_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_PWM3_L_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) + +/* Static Memory Controller (SMC) */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_SMC_A14 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A15 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SMC_A16 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SMC_A17 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SMC_A18 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SMC_A19 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SMC_A20 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SMC_A21 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_A22 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_A23 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_NANDALE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_NANDCLE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NANDOE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_NANDWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_NCS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_NCS1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_NCS2 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SMC_NCS3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_NRD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_NWAIT (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_SPI0_MOSI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_SPI0_NPCS1_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_SPI0_NPCS1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SPI0_NPCS2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SPI0_NPCS2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_SPI0_NPCS2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS3_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SPI0_NPCS3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_SPI0_NPCS3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_SPI0_SPCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +/* Synchronous Serial Controller (SSC) */ + +#define GPIO_SSC_RD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SSC_RF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SSC_RK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SSC_TD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_SSC_TF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SSC_TK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC0_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_TC0_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_TC1_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_TC1_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_TC1_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_TC2_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_TC2_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_TC2_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_TC3_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC3_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_TC3_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_TC4_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC4_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC4_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC5_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_TC5_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC5_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) + +/* Two Wire Interface (TWI) */ + +#define GPIO_TWI0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TWI0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TWI1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TWI1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_UART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_UART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_USART0_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_USART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_USART0_SCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_USART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) + +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_USART1_DCD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_USART1_DSR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_USART1_DTR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_USART1_RI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) + +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_USART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) + +/* Segment LCD Controller (SLCDC) */ +//TODO: add rest of segment pins + +#define GPIO_SLCDC_COM0 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SLCDC_COM1 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SLCDC_COM2 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_SLCDC_COM3 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_SLCDC_COM4 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_SLCDC_COM5 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN5) + +#define GPIO_SLCDC_SEG0 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_SLCDC_SEG1 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_SLCDC_SEG2 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_SLCDC_SEG3 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_SLCDC_SEG4 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SLCDC_SEG5 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_SLCDC_SEG6 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_SLCDC_SEG7 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_SLCDC_SEG8 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_SLCDC_SEG9 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SLCDC_SEG10 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_SLCDC_SEG11 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_SLCDC_SEG12 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SLCDC_SEG13 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SLCDC_SEG14 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SLCDC_SEG15 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_SLCDC_SEG16 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SLCDC_SEG17 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SLCDC_SEG18 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SLCDC_SEG19 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SLCDC_SEG20 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_SLCDC_SEG21 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_SLCDC_SEG22 (GPIO_PERIPHD | GPIO_PORT_PIOA | GPIO_PIN28) + + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_slcdc.h b/arch/arm/src/sam34/chip/sam4cm_slcdc.h new file mode 100644 index 0000000000000000000000000000000000000000..2575119d5cf341958ac61a93825a5bc6e3c1de9e --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_slcdc.h @@ -0,0 +1,182 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4cm_slcdc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SLCDC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SLCDC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SLCDC register offsets ************************************************************/ + +#define SAM_SLCDC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SLCDC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_SLCDC_FRR_OFFSET 0x0008 /* Frame Rate Register */ +#define SAM_SLCDC_DR_OFFSET 0x000C /* Display Register */ +#define SAM_SLCDC_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_SLCDC_IER_OFFSET 0x0020 /* Interrupt Enable Register */ +#define SAM_SLCDC_IDR_OFFSET 0x0024 /* Interrupt Disable Register */ +#define SAM_SLCDC_IMR_OFFSET 0x0028 /* Interrupt Mask Register */ +#define SAM_SLCDC_ISR_OFFSET 0x002C /* Interrupt Status Register */ +#define SAM_SLCDC_SMR0_OFFSET 0x0030 /* Segment Map Register 0 */ +#define SAM_SLCDC_SMR1_OFFSET 0x0034 /* Segment Map Register 1 */ +# define SAM_SLCDC_SMR_OFFSET(n) (SAM_SLCDC_SMR0_OFFSET + (n) * 4) +#define SAM_SLCDC_WPMR_OFFSET 0x0034 /* Write Protect Mode Register */ +#define SAM_SLCDC_WPSR_OFFSET 0x0034 /* Write Protect Status Register */ + +#define SAM_SLCDC_LMEMR_OFFSET(com) (0x200 + (com)*8 + 0x0) +#define SAM_SLCDC_MMEMR_OFFSET(com) (0x200 + (com)*8 + 0x4) + +/* SLCDC register adresses ***********************************************************/ + +#define SAM_SLCDC_CR (SAM_SLCDC_BASE + SAM_SLCDC_CR_OFFSET) +#define SAM_SLCDC_MR (SAM_SLCDC_BASE + SAM_SLCDC_MR_OFFSET) +#define SAM_SLCDC_FRR (SAM_SLCDC_BASE + SAM_SLCDC_FRR_OFFSET) +#define SAM_SLCDC_DR (SAM_SLCDC_BASE + SAM_SLCDC_DR_OFFSET) +#define SAM_SLCDC_SR (SAM_SLCDC_BASE + SAM_SLCDC_SR_OFFSET) +#define SAM_SLCDC_IER (SAM_SLCDC_BASE + SAM_SLCDC_IER_OFFSET) +#define SAM_SLCDC_IDR (SAM_SLCDC_BASE + SAM_SLCDC_IDR_OFFSET) +#define SAM_SLCDC_IMR (SAM_SLCDC_BASE + SAM_SLCDC_IMR_OFFSET) +#define SAM_SLCDC_ISR (SAM_SLCDC_BASE + SAM_SLCDC_ISR_OFFSET) +#define SAM_SLCDC_SMR0 (SAM_SLCDC_BASE + SAM_SLCDC_SMR0_OFFSET) +#define SAM_SLCDC_SMR1 (SAM_SLCDC_BASE + SAM_SLCDC_SMR1_OFFSET) +# define SAM_SLCDC_SMR(n) (SAM_SLCDC_BASE + SAM_SLCDC_SMR_OFFSET(n)) +#define SAM_SLCDC_WPMR (SAM_SLCDC_BASE + SAM_SLCDC_WPMR_OFFSET) +#define SAM_SLCDC_WPSR (SAM_SLCDC_BASE + SAM_SLCDC_WPSR_OFFSET) + +#define SAM_SLCDC_LMEMR(com) (SAM_SLCDC_BASE + SAM_SLCDC_LMEMR_OFFSET(com)) +#define SAM_SLCDC_MMEMR(com) (SAM_SLCDC_BASE + SAM_SLCDC_MMEMR_OFFSET(com)) + +/* SLCDC register bit definitions ****************************************************/ + +/* Control Register */ + +#define SLCDC_CR_LCDEN (1 << 0) +#define SLCDC_CR_LCDDIS (1 << 1) +#define SLCDC_CR_SWRST (1 << 3) + +/* Mode Register */ + +#define SLCDC_MR_COMSEL(N) (((N) - 1) << 0) +#define SLCDC_MR_SEGSEL(N) (((N) - 1) << 8) + +#define SLCDC_MR_BUFFTIME_OFFSET (16) +#define SLCDC_MR_BUFFTIME_MASK (0xF << SLCDC_MR_BUFFTIME_OFFSET) +# define SLCDC_MR_BUFFTIME_OFF (0 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 0% of SCLK period */ +# define SLCDC_MR_BUFFTIME_X2_SCLK (1 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 2 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X4_SCLK (2 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 4 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X8_SCLK (3 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 8 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X16_SCLK (4 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 16 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X32_SCLK (5 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 32 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X64_SCLK (6 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 64 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_X128_SCLK (7 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 128 periods of SCLK clock */ +# define SLCDC_MR_BUFFTIME_PERCENT_50 (8 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 50% of SCLK period */ +# define SLCDC_MR_BUFFTIME_PERCENT_100 (9 << SLCDC_MR_BUFFTIME_OFFSET) /* Nominal drive time is 100% of SCLK period */ + +#define SLCDC_MR_BIAS_OFFSET (20) +#define SLCDC_MR_BIAS_MASK (0x3 << SLCDC_MR_BIAS_OFFSET) +# define SLCDC_MR_BIAS_STATIC (0 << SLCDC_MR_BIAS_OFFSET) /* Static */ +# define SLCDC_MR_BIAS_1_2 (1 << SLCDC_MR_BIAS_OFFSET) /* Bias 1/2 */ +# define SLCDC_MR_BIAS_1_3 (2 << SLCDC_MR_BIAS_OFFSET) /* Bias 1/3 */ + +#define SLCD_MR_LPMODE_LOW_POWER (1 << 24) + +/* Frame Rate Register */ + +#define SLCDC_FRR_PRESC_OFFSET (0) +#define SLCDC_FRR_PRESC_MASK (0x7 << SLCDC_FRR_PRESC_OFFSET) +# define SLCDC_FRR_PRESC_SCLK_DIV8 (0x0 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 8 */ +# define SLCDC_FRR_PRESC_SCLK_DIV16 (0x1 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 16 */ +# define SLCDC_FRR_PRESC_SCLK_DIV32 (0x2 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 32 */ +# define SLCDC_FRR_PRESC_SCLK_DIV64 (0x3 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 64 */ +# define SLCDC_FRR_PRESC_SCLK_DIV128 (0x4 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 128 */ +# define SLCDC_FRR_PRESC_SCLK_DIV256 (0x5 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 256 */ +# define SLCDC_FRR_PRESC_SCLK_DIV512 (0x6 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 512 */ +# define SLCDC_FRR_PRESC_SCLK_DIV1024 (0x7 << SLCDC_FRR_PRESC_OFFSET) /* Slow clock is divided by 1024 */ + +#define SLCDC_FRR_DIV_OFFSET (8) +#define SLCDC_FRR_DIV_MASK (0x7 << SLCDC_FRR_DIV_OFFSET) +# define SLCDC_FRR_DIV(N) (((N) - 1) << SLCDC_FRR_DIV_OFFSET) /* Clock output from prescaler is divided by N */ + +/* Display Register */ + +#define SLCDC_DR_DISPMODE_OFFSET (0) +#define SLCDC_DR_DISPMODE_MASK (0x7 << SLCDC_DR_DISPMODE_OFFSET) +# define SLCDC_DR_DISPMODE_NORMAL (0x0 << SLCDC_DR_DISPMODE_OFFSET) /* Latched data are displayed */ +# define SLCDC_DR_DISPMODE_FORCE_OFF (0x1 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are invisible. (The SLCDC memory is unchanged.) */ +# define SLCDC_DR_DISPMODE_FORCE_ON (0x2 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are visible. (The SLCDC memory is unchanged.) */ +# define SLCDC_DR_DISPMODE_BLINKING (0x3 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are alternately turned off to the predefined state in SLCDC memory at LCDBLKFREQ frequency */ +# define SLCDC_DR_DISPMODE_INVERTED (0x4 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are set in the inverted state as defined in SLCDC memory */ +# define SLCDC_DR_DISPMODE_INVERTED_BLINK (0x5 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are alternately turned off to the predefined opposite state in SLCDC memory at LCDBLKFREQ frequency */ +# define SLCDC_DR_DISPMODE_USER_BUFFER_LOAD (0x6 << SLCDC_DR_DISPMODE_OFFSET) /* Blocks the automatic transfer from User Buffer to Display Buffer */ +# define SLCDC_DR_DISPMODE_BUFFERS_SWAP (0x7 << SLCDC_DR_DISPMODE_OFFSET) /* All pixels are alternatively assigned to the state defined in the User Buffer, then to the state defined in the Display Buffer at LCDBLKFREQ frequency */ + +#define SLCDC_DR_LCDBLKFREQ(F) ((F) << 8) /* Blinking frequency = Frame Frequency/F */ + +/* Status Register */ + +#define SLCDC_SR_ENA (1 << 0) /* The SLCDC is enabled/disabled */ + +/* Interrupt Enable Register */ + +#define SLCDC_IER_ENDFRAME (1 << 0) /* End of Frame Interrupt Enable */ +#define SLCDC_IER_DIS (1 << 2) /* Enables the "Disable" interrupt */ + +/* Interrupt Disable Register */ + +#define SLCDC_IDR_ENDFRAME (1 << 0) /* End of Frame Interrupt Disable */ +#define SLCDC_IDR_DIS (1 << 2) /* Disables the "Disable" interrupt */ + +/* Interrupt Mask Register */ + +#define SLCDC_IMR_ENDFRAME (1 << 0) /* End of Frame Interrupt mask (0 - disable, 1 - enable) */ +#define SLCDC_IMR_DIS (1 << 2) /* The "Disable" interrupt mask (0 - disable, 1 - enable) */ + +/* Interrupt Status Register */ + +#define SLCDC_ISR_ENDFRAME (1 << 0) /* End of Frame Interrupt occurred */ +#define SLCDC_ISR_DIS (1 << 2) /* The "Disable" interrupt occurred */ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SLCDC_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_supc.h b/arch/arm/src/sam34/chip/sam4cm_supc.h new file mode 100644 index 0000000000000000000000000000000000000000..54945823123a72ce356d5757b32c13a0813b96f7 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_supc.h @@ -0,0 +1,177 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4cm_supc.h + * Supply Controller (SUPC) definitions for the SAM4CM + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SUPC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SUPC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SUPC register offsets ****************************************************************/ + +#define SAM_SUPC_CR_OFFSET 0x00 /* Supply Controller Control Register */ +#define SAM_SUPC_SMMR_OFFSET 0x04 /* Supply Controller Supply Monitor Mode Register */ +#define SAM_SUPC_MR_OFFSET 0x08 /* Supply Controller Mode Register */ +#define SAM_SUPC_WUMR_OFFSET 0x0c /* Supply Controller Wake Up Mode Register */ +#define SAM_SUPC_WUIR_OFFSET 0x10 /* Supply Controller Wake Up Inputs Register */ +#define SAM_SUPC_SR_OFFSET 0x14 /* Supply Controller Status Register */ + +/* SUPC register adresses ***************************************************************/ + +#define SAM_SUPC_CR (SAM_SUPC_BASE+SAM_SUPC_CR_OFFSET) +#define SAM_SUPC_SMMR (SAM_SUPC_BASE+SAM_SUPC_SMMR_OFFSET) +#define SAM_SUPC_MR (SAM_SUPC_BASE+SAM_SUPC_MR_OFFSET) +#define SAM_SUPC_WUMR (SAM_SUPC_BASE+SAM_SUPC_WUMR_OFFSET) +#define SAM_SUPC_WUIR (SAM_SUPC_BASE+SAM_SUPC_WUIR_OFFSET) +#define SAM_SUPC_SR (SAM_SUPC_BASE+SAM_SUPC_SR_OFFSET) + +/* SUPC register bit definitions ********************************************************/ +/* Supply Controller Control Register */ + +#define SUPC_CR_VROFF (1 << 2) /* Bit 2: Voltage Regulator Off */ +#define SUPC_CR_XTALSEL (1 << 3) /* Bit 3: Crystal Oscillator Select */ +#define SUPC_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define SUPC_CR_KEY_MASK (0xff << SUPC_CR_KEY_SHIFT) +# define SUPR_CR_KEY (0xa5 << SUPC_CR_KEY_SHIFT) + +/* Supply Controller Supply Monitor Mode Register */ + +#define SUPC_SMMR_SMTH_SHIFT (0) /* Bits 0-3: Supply Monitor Threshold */ +#define SUPC_SMMR_SMTH_MASK (15 << SUPC_SMMR_SMTH_SHIFT) +# define SUPC_SMMR_SMTH_1p6V (0 << SUPC_SMMR_SMTH_SHIFT) /* 1.56 < 1.6 < 1.64 */ +# define SUPC_SMMR_SMTH_1p7V (1 << SUPC_SMMR_SMTH_SHIFT) /* 1.68 < 1.72 < 1.76 */ +# define SUPC_SMMR_SMTH_1p8V (2 << SUPC_SMMR_SMTH_SHIFT) /* 1.79 < 1.84 < 1.89 */ +# define SUPC_SMMR_SMTH_2p0V (3 << SUPC_SMMR_SMTH_SHIFT) /* 1.91 < 1.96 < 2.01 */ +# define SUPC_SMMR_SMTH_2p1V (4 << SUPC_SMMR_SMTH_SHIFT) /* 2.03 < 2.08 < 2.13 */ +# define SUPC_SMMR_SMTH_2p2V (5 << SUPC_SMMR_SMTH_SHIFT) /* 2.15 < 2.2 < 2.23 */ +# define SUPC_SMMR_SMTH_2p3V (6 << SUPC_SMMR_SMTH_SHIFT) /* 2.26 < 2.32 < 2.38 */ +# define SUPC_SMMR_SMTH_2p4V (7 << SUPC_SMMR_SMTH_SHIFT) /* 2.38 < 2.44 < 2.50 */ +# define SUPC_SMMR_SMTH_2p6V (8 << SUPC_SMMR_SMTH_SHIFT) /* 2.50 < 2.56 < 2.62 */ +# define SUPC_SMMR_SMTH_2p7V (9 << SUPC_SMMR_SMTH_SHIFT) /* 2.61 < 2.68 < 2.75 */ +# define SUPC_SMMR_SMTH_2p8V (10 << SUPC_SMMR_SMTH_SHIFT) /* 2.73 < 2.8 < 2.87 */ +# define SUPC_SMMR_SMTH_2p9V (11 << SUPC_SMMR_SMTH_SHIFT) /* 2.85 < 2.92 < 2.99 */ +# define SUPC_SMMR_SMTH_3p0V (12 << SUPC_SMMR_SMTH_SHIFT) /* 2.96 < 3.04 < 3.12 */ +# define SUPC_SMMR_SMTH_3p2V (13 << SUPC_SMMR_SMTH_SHIFT) /* 3.08 < 3.16 < 3.24 */ +# define SUPC_SMMR_SMTH_3p3V (14 << SUPC_SMMR_SMTH_SHIFT) /* 3.20 < 3.28 < 3.36 */ +# define SUPC_SMMR_SMTH_3p4V (15 << SUPC_SMMR_SMTH_SHIFT) /* 3.32 < 3.4 < 3.49 */ + +#define SUPC_SMMR_SMSMPL_SHIFT (8) /* Bits 8-10: Supply Monitor Sampling Period */ +#define SUPC_SMMR_SMSMPL_MASK (7 << SUPC_SMMR_SMSMPL_SHIFT) +# define SUPC_SMMR_SMSMPL_SMD (0 << SUPC_SMMR_SMSMPL_SHIFT) /* Supply Monitor disabled */ +# define SUPC_SMMR_SMSMPL_CSM (1 << SUPC_SMMR_SMSMPL_SHIFT) /* Continuous Supply Monitor */ +# define SUPC_SMMR_SMSMPL_32SLCK (2 << SUPC_SMMR_SMSMPL_SHIFT) /* Eevery 32 SLCK periods */ +# define SUPC_SMMR_SMSMPL_256SLCK (3 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 256 SLCK periods */ +# define SUPC_SMMR_SMSMPL_2048SLCK (4 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 2,048 SLCK periods */ +#define SUPC_SMMR_SMRSTEN (1 << 12) /* Bit 12: Supply Monitor Reset Enable */ +#define SUPC_SMMR_SMIEN (1 << 13) /* Bit 13: Supply Monitor Interrupt Enable */ + +/* Supply Controller Mode Register */ + +#define SUPC_MR_ +#define SUPC_MR_BODRSTEN (1 << 12) /* Bit 12: Brownout Detector Reset Enable */ +#define SUPC_MR_BODDIS (1 << 13) /* Bit 13: Brownout Detector Disable */ +#define SUPC_MR_OSCBYPASS (1 << 20) /* Bit 20: Oscillator Bypass */ +#define SUPC_MR_KEY_SHIFT (24) /* Bits 24-31: Password Key */ +#define SUPC_MR_KEY_MASK (0xff << SUPC_MR_KEY_SHIFT) +# define SUPR_MR_KEY (0xa5 << SUPC_MR_KEY_SHIFT) + +/* Supply Controller Wake Up Mode Register */ + +#define SUPC_WUMR_FWUPEN (1 << 0) /* Bit 0: Force Wake Up Enable */ +#define SUPC_WUMR_SMEN (1 << 1) /* Bit 1: Supply Monitor Wake Up Enable */ +#define SUPC_WUMR_RTTEN (1 << 2) /* Bit 2: Real Time Timer Wake Up Enable */ +#define SUPC_WUMR_RTCEN (1 << 3) /* Bit 3: Real Time Clock Wake Up Enable */ +#define SUPC_WUMR_FWUPDBC_SHIFT (8) /* Bits 8-10: Force Wake Up Debouncer */ +#define SUPC_WUMR_FWUPDBC_MASK (7 << SUPC_WUMR_FWUPDBC_SHIFT) +# define SUPC_WUMR_FWUPDBC_1SCLK (0 << SUPC_WUMR_FWUPDBC_SHIFT) /* Immediate, no debouncing */ +# define SUPC_WUMR_FWUPDBC_3SCLK (1 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 3 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_32SCLK (2 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 32 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_512SCLK (3 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 512 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_4096SCLK (4 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 4096 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_32768SCLK (5 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 32768 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_SHIFT (12) /* Bits 12-14: Wake Up Inputs Debouncer */ +#define SUPC_WUMR_WKUPDBC_MASK (7 << SUPC_WUMR_WKUPDBC_SHIFT) +# define SUPC_WUMR_WKUPDBC_1SCLK (0 << SUPC_WUMR_WKUPDBC_SHIFT) /* Immediate, no debouncing */ +# define SUPC_WUMR_WKUPDBC_3SCLK (1 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 3 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32SCLK (2 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_512SCLK (3 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 512 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_4096SCLK (4 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 4096 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32768SCLK (5 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32768 SLCK periods */ + +/* System Controller Wake Up Inputs Register */ + +#define SUPC_WUIR_WKUPEN_SHIFT (0) /* Bits 0-15: Wake Up Input Enable 0 to 15 */ +#define SUPC_WUIR_WKUPEN_MASK (0xffff << SUPC_WUIR_WKUPEN_SHIFT) +# define SUPC_WUIR_WKUPEN(n) ((1 << (n)) << SUPC_WUIR_WKUPEN_SHIFT) +#define SUPC_WUIR_WKUPT_SHIFT (16) /* Bits 16-31 Wake Up Input Transition 0 to 15 */ +#define SUPC_WUIR_WKUPT_MASK (0xffff << SUPC_WUIR_WKUPT_SHIFT) +# define SUPC_WUIR_WKUPT(n) ((1 << (n)) << SUPC_WUIR_WKUPT_SHIFT) + +/* Supply Controller Status Register */ + +#define SUPC_SR_WKUPS (1 << 1) /* Bit 1: WKUP Wake Up Status */ +#define SUPC_SR_SMWS (1 << 2) /* Bit 2: Supply Monitor Detection Wake Up Status */ +#define SUPC_SR_BODRSTS (1 << 3) /* Bit 3: Brownout Detector Reset Status */ +#define SUPC_SR_SMRSTS (1 << 4) /* Bit 4: Supply Monitor Reset Status */ +#define SUPC_SR_SMS (1 << 5) /* Bit 5: Supply Monitor Status */ +#define SUPC_SR_SMOS (1 << 6) /* Bit 6: Supply Monitor Output Status */ +#define SUPC_SR_OSCSEL (1 << 7) /* Bit 7: 32-kHz Oscillator Selection Status */ +#define SUPC_SR_WKUPIS_SHIFT (16) /* Bits 16-31: WKUP Input Status 0 to 15 */ +#define SUPC_SR_WKUPIS_MASK (0xffff << SUPC_SR_WKUPIS_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4CM_SUPC_H */ diff --git a/arch/arm/src/sam34/chip/sam4cm_vectors.h b/arch/arm/src/sam34/chip/sam4cm_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..9afd594ef94b51910e6cc0fd48866cbd5dcb29dc --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4cm_vectors.h @@ -0,0 +1,101 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4cm_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that + * supplies ach SAM3U vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/sam/sam3u_irq.h. + * sam_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 35 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 35 + +#else + VECTOR(sam_supc, SAM_IRQ_SUPC) /* Vector 16+0: Supply Controller */ + VECTOR(sam_rstc, SAM_IRQ_RSTC) /* Vector 16+1: Reset Controller */ + VECTOR(sam_rtc, SAM_IRQ_RTC) /* Vector 16+2: Real Time Clock */ + VECTOR(sam_rtt, SAM_IRQ_RTT) /* Vector 16+3: Real Time Timer */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+4: Watchdog Timer */ + VECTOR(sam_pmc, SAM_IRQ_PMC) /* Vector 16+5: Power Management Controller */ + VECTOR(sam_eefc0, SAM_IRQ_EEFC0) /* Vector 16+6: Enhanced Embedded Flash Controller 0 */ + UNUSED(SAM_IRQ_RESERVED_7) /* Vector 16+7: Reserved */ + VECTOR(sam_uart0, SAM_IRQ_UART0) /* Vector 16+8: Universal Asynchronous Receiver Transmitter 0 */ + UNUSED(SAM_IRQ_RESERVED_9) /* Vector 16+9: Reserved */ + UNUSED(SAM_IRQ_RESERVED_10) /* Vector 16+10: Unused */ + VECTOR(sam_pioa, SAM_IRQ_PIOA) /* Vector 16+11: Parallel I/O Controller A */ + VECTOR(sam_piob, SAM_IRQ_PIOB) /* Vector 16+12: Parallel I/O Controller B */ + UNUSED(SAM_IRQ_RESERVED_13) /* Vector 16+13: Reserved */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+14: USART 0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+15: USART 1 */ + VECTOR(sam_usart2, SAM_IRQ_USART2) /* Vector 16+16: USART 2 */ + VECTOR(sam_usart3, SAM_IRQ_USART3) /* Vector 16+17: USART 3 */ + UNUSED(SAM_IRQ_RESERVED_18) /* Vector 16+18: Reserved */ + VECTOR(sam_twi0, SAM_IRQ_TWI0) /* Vector 16+19: Two-Wire Interface 0 */ + VECTOR(sam_twi1, SAM_IRQ_TWI1) /* Vector 16+20: Two-Wire Interface 1 */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+21: Serial Peripheral Interface */ + UNUSED(SAM_IRQ_RESERVED_22) /* Vector 16+22: Reserved */ + VECTOR(sam_tc0, SAM_IRQ_TC0) /* Vector 16+23: Timer Counter 0 */ + VECTOR(sam_tc1, SAM_IRQ_TC1) /* Vector 16+24: Timer Counter 1 */ + VECTOR(sam_tc2, SAM_IRQ_TC2) /* Vector 16+25: Timer Counter 2 */ + VECTOR(sam_tc3, SAM_IRQ_TC3) /* Vector 16+26: Timer Counter 3 */ + VECTOR(sam_tc4, SAM_IRQ_TC4) /* Vector 16+27: Timer Counter 4 */ + VECTOR(sam_tc5, SAM_IRQ_TC5) /* Vector 16+28: Timer Counter 5 */ + VECTOR(sam_adc, SAM_IRQ_ADC) /* Vector 16+29: Analog To Digital Converter */ + VECTOR(sam_arm, SAM_IRQ_ARM) /* Vector 16+30: FPU signals (only on CM4P1 core): FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + VECTOR(sam_ipc0, SAM_IRQ_IPC0) /* Vector 16+31: Interprocessor communication 0 */ + VECTOR(sam_slcdc, SAM_IRQ_SLCDC) /* Vector 16+32: Segment LCD Controller */ + VECTOR(sam_trng, SAM_IRQ_TRNG) /* Vector 16+33: True Random Generator */ + VECTOR(sam_icm, SAM_IRQ_ICM) /* Vector 16+34: Integrity Check Module */ + VECTOR(sam_cpkcc, SAM_IRQ_CPKCC) /* Vector 16+35: Classical Public Key Cryptography Controller */ + VECTOR(sam_aes, SAM_IRQ_AES) /* Vector 16+36: Advanced Enhanced Standard */ + VECTOR(sam_pioc, SAM_IRQ_PIOC) /* Vector 16+37: Parallel I/O Controller C */ + VECTOR(sam_uart1, SAM_IRQ_UART1) /* Vector 16+38: Universal Asynchronous Receiver Transmitter 1 */ + VECTOR(sam_ipc1, SAM_IRQ_IPC1) /* Vector 16+39: Interprocessor communication 1 */ + UNUSED(SAM_IRQ_RESERVED_40) /* Vector 16+40: Reserved */ + VECTOR(sam_pwm, SAM_IRQ_PWM) /* Vector 16+41: Pulse Width Modulation */ +//VECTOR(sam_sram, SAM_IRQ_SRAM) /* Vector 16+42: SRAM1 (I/D Code bus of CM4P1), SRAM2 (Systembus of CM4P1) */ +//VECTOR(sam_smc1, SAM_IRQ_SMC1) /* Vector 16+43: Static Memory Controller 1 */ +#endif \ No newline at end of file diff --git a/arch/arm/src/sam34/chip/sam4e_memorymap.h b/arch/arm/src/sam34/chip/sam4e_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..95bfdef2eb719fadef4816b4282709db19742b4d --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4e_memorymap.h @@ -0,0 +1,178 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4e_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_EXTRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External RAM */ + /* 0xa0000000-0xdfffffff: Reserved */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x003fffff: Boot Memory */ +#define SAM_INTFLASH_BASE 0x00400000 /* 0x00400000-0x007fffff: Internal FLASH */ +#define SAM_INTROM_BASE 0x00800000 /* 0x00180000-0x00bfffff: Internal ROM */ + /* 0x00c00000-0x1fffffff: Reserved */ +/* Internal SRAM memory region */ + +#define SAM_INTSRAM0_BASE 0x20000000 /* For SAM3U compatibility */ + /* 0x20400000-0x207fffff: Reserved */ + /* 0x20800000-0x3fffffff: Undefined (abort) */ + +#define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32MB bit-band region */ + +/* Peripherals address region */ + +#define SAM_PWM_BASE 0x40000000 /* 0x40000000-0x40003fff: Pulse Width Modulation */ +#define SAM_AES_BASE 0x40004000 /* 0x40004000-0x40007fff: AES */ + /* 0x40008000-0x40010000: Reserved */ +#define SAM_CAN0_BASE 0x40010000 /* 0x40010000-0x40013fff: CAN0 */ +#define SAM_CAN1_BASE 0x40014000 /* 0x40014000-0x40017fff: CAN1 */ + /* 0x40018000-0x40033fff: Reserved */ +#define SAM_EMAC_BASE 0x40034000 /* 0x40034000-0x40037fff: EMAC */ + /* 0x40038000-0x4005ffff: Reserved */ +#define SAM_MPSYSCTRL_BASE 0x40060000 /* 0x40060000-0x4007ffff: MP Sys Controller */ +# define SAM_SMC_BASE 0x40060000 /* 0x40060000-0x400601ff: Static Memory Controller */ + /* 0x40060200-0x400605ff: Reserved */ +# define SAM_UART1_BASE 0x40060600 /* 0x40060600-0x400607ff: UART 1 */ + /* 0x40060900-0x4007ffff: Reserved */ +#define SAM_HSMCI_BASE 0x40080000 /* 0x40080000-0x40083fff: High Speed Multimedia Card Interface */ +#define SAM_UDP_BASE 0x40084000 /* 0x40084000-0x40087fff: USB device */ +#define SAM_SPI0_BASE 0x40088000 /* 0x40088000-0x4008bfff: Serial Peripheral Interface */ + /* 0x4008c000-0x4008ffff: Reserved */ +#define SAM_TC012_BASE 0x40090000 /* 0x40090000-0x40097fff: Timer Counters 0-2 */ +# define SAM_TC0_BASE 0x40090000 /* 0x40090000-0x4009003f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x40090040 /* 0x40090040-0x4009007f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x40090080 /* 0x40090080-0x400900bf: Timer Counter 2 */ + /* 0x400900c0-0x40093fff Reserved */ +#define SAM_TC345_BASE 0x40094000 /* 0x40094000-0x40094fff: Timer Counters 3-5 */ +# define SAM_TC3_BASE 0x40094000 /* 0x40094000-0x4009403f: Timer Counter 3 */ +# define SAM_TC4_BASE 0x40094040 /* 0x40094040-0x4009407f: Timer Counter 4 */ +# define SAM_TC5_BASE 0x40094080 /* 0x40094080-0x400940bf: Timer Counter 5 */ + /* 0x400940c0-0x40097fff Reserved */ +#define SAM_TC678_BASE 0x40098000 /* 0x40098000-0x40097fff: Timer Counters 6-8 */ +# define SAM_TC6_BASE 0x40098000 /* 0x40098000-0x4009003f: Timer Counter 6 */ +# define SAM_TC7_BASE 0x40098040 /* 0x40098040-0x4009007f: Timer Counter 7 */ +# define SAM_TC8_BASE 0x40098080 /* 0x40098080-0x400900bf: Timer Counter 8 */ + /* 0x4009c000-0x4009ffff: Reserved */ +#define SAM_USART_BASE 0x400a0000 /* 0x400a0000-0x400abfff: USART */ +# define SAM_USART0_BASE 0x400a0000 /* 0x400a0000-0x400a3fff: USART0 */ +# define SAM_USART1_BASE 0x400a4000 /* 0x400a4000-0x400abfff: USART1 */ +#define SAM_TWI_BASE 0x400a8000 /* 0x400a8000-0x400affff: Two-Wire Interface */ +# define SAM_TWI0_BASE 0x400a8000 /* 0x400a8000-0x400abfff: Two-Wire Interface 0 */ +# define SAM_TWI1_BASE 0x400ac000 /* 0x400ac000-0x400affff: Two-Wire Interface 1 */ +#define SAM_AFEC_BASE 0x400b0000 /* 0x400b0000-0x400b7fff: Analog Front End */ +# define SAM_AFEC0_BASE 0x400b0000 /* 0x400b0000-0x400b3fff: Analog Front End 0 */ +# define SAM_AFEC1_BASE 0x400b4000 /* 0x400b4000-0x400b7fff: Analog Front End 1 */ +#define SAM_DACC_BASE 0x400b8000 /* 0x400b8000-0x400bbfff: Digital To Analog Converter */ +#define SAM_ACC_BASE 0x400bc000 /* 0x400bc000-0x400bffff: Analog Comparator */ +#define SAM_DMAC_BASE 0x400c0000 /* 0x400c0000-0x400c3fff: DMA controller */ +#define SAM_CMCC_BASE 0x400c4000 /* 0x400c4000-0x400c7fff: Cortex-M Cache Controller */ + /* 0x400c8000-0x400dffff: Reserved */ +#define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e25ff: System Controller */ + /* 0x400e2600-0x5fffffff: Reserved */ + +#define SAM_BBPERIPH_BASE 0x42000000 /* 0x42000000-0x43ffffff: 32MB bit-band region */ + +/* System Controller Register Blocks: 0x400e0000-0x4007ffff */ + + /* 0x400e0000-0x400e01ff: Reserved */ +#define SAM_MATRIX_BASE 0x400e0200 /* 0x400e0200-0x400e03ff: MATRIX */ +#define SAM_PMC_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: Power Management Controller */ +#define SAM_UART0_BASE 0x400e0600 /* 0x400e0600-0x400e073f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0740 /* 0x400e0740-0x400e07ff: CHIP ID */ + /* 0x400e0800-0x400e09ff: Reserved */ +#define SAM_EEFC_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controller */ +# define SAM_EEFC0_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: (For compatibility) */ + /* 0x400e0c00-0x400e0dff: Reserved */ +#define SAM_PIO_BASE 0x400e0e00 /* 0x400e0e00-0x400e13ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0e00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1200 /* 0x400e1200-0x400e13ff: Parallel I/O Controller C */ +# define SAM_PIOD_BASE 0x400e1400 /* 0x400e1400-0x400e15ff: Parallel I/O Controller C */ +# define SAM_PIOE_BASE 0x400e1600 /* 0x400e1600-0x400e17ff: Parallel I/O Controller C */ +#define SAM_RSTC_BASE 0x400e1800 /* 0x400e1800-0x400e180f: Reset Controller */ +#define SAM_SUPC_BASE 0x400e1810 /* 0x400e1810-0x400e182f: Supply Controller */ +#define SAM_RTT_BASE 0x400e1830 /* 0x400e1830-0x400e184f: Real Time Timer */ +#define SAM_WDT_BASE 0x400e1850 /* 0x400e1850-0x400e185f: Watchdog Timer */ +#define SAM_RTC_BASE 0x400e1860 /* 0x400e1860-0x400e188f: Real Time Clock */ +#define SAM_GPBR_BASE 0x400e1890 /* 0x400e1890-0x400e18ff: GPBR */ +#define SAM_RSWDT_BASE 0x400e1900 /* 0x400e1900-??????????: Reinforced Safety Watchdog Timer */ + +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */ +# define SAM_EXTCSN_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */ + /* 0x64000000-0x9fffffff: Reserved */ +/* System memory region */ + +#define SAM_PRIVPERIPH_BASE 0xe0000000 /* 0xe0000000-0xe00fffff: Private peripheral bus */ +#define SAM_VENDOR_BASE 0xe0100000 /* 0ex0100000-0xffffffff: Vendor-specific memory */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4e_pinmap.h b/arch/arm/src/sam34/chip/sam4e_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..c97111e4e46dd26b9d92c9ba8e535a2064269c62 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4e_pinmap.h @@ -0,0 +1,337 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam4e_pinmap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the programmable clock output PCK0 on PA6, then the following definition + * should appear in the board.h header file for that board: + * + * #define GPIO_PCK0 GPIO_PCK0_1 + * + * The driver will then automatically configure PA6 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog Front End (AFE) */ + +#define GPIO_AFE0_ADTRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) + +/* CAN */ + +#define GPIO_CAN_RX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_CAN_RX1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_CAN_TX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_CAN_TX1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) + +/* Digital-to-Analog Convert (DAC) */ + +#define GPIO_DAC_DATRG (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) + +/* Ethernet MAC Controller (EMAC) */ + +#define GPIO_EMAC_COL (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_EMAC_CRS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_EMAC_CRSDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_EMAC_MDC (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_EMAC_MDIO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_EMAC_REFCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_EMAC_RX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_EMAC_RX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_EMAC_RX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_EMAC_RX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_EMAC_RXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) +#define GPIO_EMAC_RXDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_EMAC_RXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_EMAC_TX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_EMAC_TX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_EMAC_TX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_EMAC_TX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_EMAC_TXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_EMAC_TXEN (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_EMAC_TXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) + +/* High-Speed Multimedia Card Interface (HSMCI) */ + +#define GPIO_HSMCI_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_HSMCI_DA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_HSMCI_DAT0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_HSMCI_DAT1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_HSMCI_DAT2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_HSMCI_DAT3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_PCK0_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PCK2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWM0_F (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWM0_H_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWM0_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWM0_H_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_PWM0_H_4 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_PWM0_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWM0_H_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWM0_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_PWM0_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWM0_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_PWM0_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_PWM0_L_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_PWM1_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PWM1_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_PWM1_H_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_PWM1_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWM1_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PWM1_H_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWM1_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWM1_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_PWM1_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWM1_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_PWM1_L_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_PWM2_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_PWM2_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_PWM2_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWM2_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_PWM2_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_PWM2_H_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWM2_L_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_PWM2_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWM2_L_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWM2_L_4 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_PWM2_L_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWM3_H_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PWM3_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_PWM3_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWM3_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_PWM3_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_PWM3_H_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWM3_L_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_PWM3_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_PWM3_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWM3_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) + +/* Static Memory Controller (SMC) */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_SMC_A14 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A15 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SMC_A16 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SMC_A17 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SMC_A18 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SMC_A19 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SMC_A20 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SMC_A21 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_A22 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_A23 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_NANDALE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_NANDCLE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NANDOE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_NANDWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_NCS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_NCS1_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_NCS1_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SMC_NCS2 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SMC_NCS3_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_NCS3_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_SMC_NRD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_NWAIT (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_SPI0_MOSI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_SPI0_SPCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_SPI0_NPCS1_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_SPI0_NPCS1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SPI0_NPCS2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SPI0_NPCS2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_SPI0_NPCS2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS3_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SPI0_NPCS3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_SPI0_NPCS3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC0_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_TC0_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_TC1_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_TC1_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_TC1_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_TC2_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_TC2_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_TC2_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_TC3_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC3_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_TC3_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_TC4_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC4_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC4_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC5_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_TC5_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC5_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_TC6_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_TC6_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_TC6_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_TC7_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_TC7_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_TC7_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_TC8_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_TC8_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_TC8_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) + +/* Two Wire Interface (TWI) */ + +#define GPIO_TWI0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TWI0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TWI1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TWI1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_UART1_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_UART1_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_USART0_RTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_USART0_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_USART0_SCK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_USART0_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) + +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_USART1_DCD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_USART1_DSR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_USART1_DTR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_USART1_RI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_USART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4e_pio.h b/arch/arm/src/sam34/chip/sam4e_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..3918583a52777b5706be42b71450f3880e86b428 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4e_pio.h @@ -0,0 +1,554 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4e_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PIO_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */ +#define SAM_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */ +#define SAM_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */ + /* 0x000c: Reserved */ +#define SAM_PIO_OER_OFFSET 0x0010 /* Output Enable Register */ +#define SAM_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */ +#define SAM_PIO_OSR_OFFSET 0x0018 /* Output Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */ +#define SAM_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */ +#define SAM_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */ + /* 0x002c: Reserved */ +#define SAM_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */ +#define SAM_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */ +#define SAM_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define SAM_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */ +#define SAM_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */ +#define SAM_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */ + /* 0x005c: Reserved */ +#define SAM_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */ +#define SAM_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */ +#define SAM_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */ + /* 0x006c: Reserved */ +#define SAM_PIO_ABCDSR1_OFFSET 0x0070 /* Peripheral Select Register 1 */ +#define SAM_PIO_ABCDSR2_OFFSET 0x0074 /* Peripheral Select Register 2 */ + /* 0x0078-0x007c: Reserved */ +#define SAM_PIO_IFSCDR_OFFSET 0x0080 /* Input Filter Slow Clock Disable Register */ +#define SAM_PIO_IFSCER_OFFSET 0x0084 /* Input Filter Slow Clock Enable Register */ +#define SAM_PIO_IFSCSR_OFFSET 0x0088 /* Input Filter Slow Clock Status Register */ +#define SAM_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */ +#define SAM_PIO_PPDDR_OFFSET 0x0090 /* Pad Pull Down Disable Register */ +#define SAM_PIO_PPDER_OFFSET 0x0094 /* PIO Pad Pull Down Enable Register */ +#define SAM_PIO_PPDSR_OFFSET 0x0098 /* PIO Pad Pull Down Status Register */ + /* 0x009c: Reserved */ +#define SAM_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */ +#define SAM_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */ +#define SAM_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */ + /* 0x00ac: Reserved */ +#define SAM_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */ +#define SAM_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */ +#define SAM_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */ + /* 0x00bc: Reserved */ +#define SAM_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */ +#define SAM_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */ +#define SAM_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */ + /* 0x00cc: Reserved */ +#define SAM_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */ +#define SAM_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */ +#define SAM_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */ + /* 0x00dc: Reserved */ +#define SAM_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */ +#define SAM_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8: Reserved */ +#define SAM_PIO_SCHMITT_OFFSET 0x0100 /* Schmitt Trigger Register */ + /* 0x0104-0x10c: Reserved */ +#define SAM_PIO_DELAYR_OFFSET 0x0110 /* IO Delay Register */ + /* 0x0114-0x14c: Reserved */ +#define SAM_PIO_PCMR_OFFSET 0x0150 /* Parallel Capture Mode Register */ +#define SAM_PIO_PCIER_OFFSET 0x0154 /* Parallel Capture Interrupt Enable Register */ +#define SAM_PIO_PCIDR_OFFSET 0x0158 /* Parallel Capture Interrupt Disable Register */ +#define SAM_PIO_PCIMR_OFFSET 0x015c /* Parallel Capture Interrupt Mask Register */ +#define SAM_PIO_PCISR_OFFSET 0x0160 /* Parallel Capture Interrupt Status Register */ +#define SAM_PIO_PCRHR_OFFSET 0x0164 /* Parallel Capture Reception Holding Register */ + /* 0x0168-0x018c: Reserved for PDC registers */ + +/* PIO register addresses ***************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define NPIO (3) + +#define SAM_PIO_PER(n) (SAM_PIO_BASE(n)+SAM_PIO_PER_OFFSET) +#define SAM_PIO_PDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDR_OFFSET) +#define SAM_PIO_PSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PSR_OFFSET) +#define SAM_PIO_OER(n) (SAM_PIO_BASE(n)+SAM_PIO_OER_OFFSET) +#define SAM_PIO_ODR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODR_OFFSET) +#define SAM_PIO_OSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OSR_OFFSET) +#define SAM_PIO_IFER(n) (SAM_PIO_BASE(n)+SAM_PIO_IFER_OFFSET) +#define SAM_PIO_IFDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFDR_OFFSET) +#define SAM_PIO_IFSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSR_OFFSET) +#define SAM_PIO_SODR(n) (SAM_PIO_BASE(n)+SAM_PIO_SODR_OFFSET) +#define SAM_PIO_CODR(n) (SAM_PIO_BASE(n)+SAM_PIO_CODR_OFFSET) +#define SAM_PIO_ODSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODSR_OFFSET) +#define SAM_PIO_PDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDSR_OFFSET) +#define SAM_PIO_IER(n) (SAM_PIO_BASE(n)+SAM_PIO_IER_OFFSET) +#define SAM_PIO_IDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IDR_OFFSET) +#define SAM_PIO_IMR(n) (SAM_PIO_BASE(n)+SAM_PIO_IMR_OFFSET) +#define SAM_PIO_ISR(n) (SAM_PIO_BASE(n)+SAM_PIO_ISR_OFFSET) +#define SAM_PIO_MDER(n) (SAM_PIO_BASE(n)+SAM_PIO_MDER_OFFSET) +#define SAM_PIO_MDDR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDDR_OFFSET) +#define SAM_PIO_MDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDSR_OFFSET) +#define SAM_PIO_PUDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUDR_OFFSET) +#define SAM_PIO_PUER(n) (SAM_PIO_BASE(n)+SAM_PIO_PUER_OFFSET) +#define SAM_PIO_PUSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUSR_OFFSET) +#define SAM_PIO_ABCDSR1(n) (SAM_PIO_BASE(n)+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIO_ABCDSR2(n) (SAM_PIO_BASE(n)+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIO_IFSCDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIO_IFSCER(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIO_IFSCSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIO_SCDR(n) (SAM_PIO_BASE(n)+SAM_PIO_SCDR_OFFSET) +#define SAM_PIO_PPDDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIO_PPDER(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDER_OFFSET) +#define SAM_PIO_PPDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIO_OWER(n) (SAM_PIO_BASE(n)+SAM_PIO_OWER_OFFSET) +#define SAM_PIO_OWDR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWDR_OFFSET) +#define SAM_PIO_OWSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWSR_OFFSET) +#define SAM_PIO_AIMER(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMER_OFFSET) +#define SAM_PIO_AIMDR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIO_AIMMR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIO_ESR(n) (SAM_PIO_BASE(n)+SAM_PIO_ESR_OFFSET) +#define SAM_PIO_LSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LSR_OFFSET) +#define SAM_PIO_ELSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ELSR_OFFSET) +#define SAM_PIO_FELLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIO_REHLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIO_FRLHSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIO_LOCKSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIO_WPMR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPMR_OFFSET) +#define SAM_PIO_WPSR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPSR_OFFSET) +#define SAM_PIO_SCHMITT(n) (SAM_PIO_BASE(n)+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIO_DELAYR(n) (SAM_PIO_BASE(n)+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIO_PCMR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCMR_OFFSET) +#define SAM_PIO_PCIER(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIER_OFFSET) +#define SAM_PIO_PCIDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIO_PCIMR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIO_PCISR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCISR_OFFSET) +#define SAM_PIO_PCRHR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOA_PER (SAM_PIOA_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOA_PDR (SAM_PIOA_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOA_PSR (SAM_PIOA_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOA_OER (SAM_PIOA_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOA_ODR (SAM_PIOA_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOA_OSR (SAM_PIOA_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOA_IFER (SAM_PIOA_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOA_IFDR (SAM_PIOA_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOA_IFSR (SAM_PIOA_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIOA_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIOA_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIOA_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIOA_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIOA_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIOA_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIOA_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIOA_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_MDER (SAM_PIOA_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOA_MDDR (SAM_PIOA_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOA_MDSR (SAM_PIOA_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOA_PUDR (SAM_PIOA_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOA_PUER (SAM_PIOA_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOA_PUSR (SAM_PIOA_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOA_ABCDSR1 (SAM_PIOA_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOA_ABCDSR2 (SAM_PIOA_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOA_IFSCDR (SAM_PIOA_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOA_IFSCER (SAM_PIOA_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOA_IFSCSR (SAM_PIOA_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOA_SCDR (SAM_PIOA_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOA_PPDDR (SAM_PIOA_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOA_PPDER (SAM_PIOA_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOA_PPDSR (SAM_PIOA_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOA_OWER (SAM_PIOA_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOA_OWDR (SAM_PIOA_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOA_OWSR (SAM_PIOA_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOA_AIMER (SAM_PIOA_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOA_AIMDR (SAM_PIOA_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOA_AIMMR (SAM_PIOA_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOA_ESR (SAM_PIOA_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOA_LSR (SAM_PIOA_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOA_ELSR (SAM_PIOA_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOA_FELLSR (SAM_PIOA_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOA_REHLSR (SAM_PIOA_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOA_FRLHSR (SAM_PIOA_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOA_LOCKSR (SAM_PIOA_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOA_WPMR (SAM_PIOA_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOA_WPSR (SAM_PIOA_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOA_SCHMITT (SAM_PIOA_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOA_DELAYR (SAM_PIOA_BASE+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIOA_PCMR (SAM_PIOA_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOA_PCIER (SAM_PIOA_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOA_PCIDR (SAM_PIOA_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOA_PCIMR (SAM_PIOA_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOA_PCISR (SAM_PIOA_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOA_PCRHR (SAM_PIOA_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOB_PER (SAM_PIOB_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOB_PDR (SAM_PIOB_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOB_PSR (SAM_PIOB_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOB_OER (SAM_PIOB_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOB_ODR (SAM_PIOB_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOB_OSR (SAM_PIOB_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOB_IFER (SAM_PIOB_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOB_IFDR (SAM_PIOB_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOB_IFSR (SAM_PIOB_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOB_SODR (SAM_PIOB_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOB_CODR (SAM_PIOB_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOB_ODSR (SAM_PIOB_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOB_PDSR (SAM_PIOB_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOB_IER (SAM_PIOB_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOB_IDR (SAM_PIOB_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOB_IMR (SAM_PIOB_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOB_ISR (SAM_PIOB_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOB_MDER (SAM_PIOB_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOB_MDDR (SAM_PIOB_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOB_MDSR (SAM_PIOB_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOB_PUDR (SAM_PIOB_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOB_PUER (SAM_PIOB_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOB_PUSR (SAM_PIOB_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOB_ABCDSR1 (SAM_PIOB_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOB_ABCDSR2 (SAM_PIOB_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOB_IFSCDR (SAM_PIOB_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOB_IFSCER (SAM_PIOB_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOB_IFSCSR (SAM_PIOB_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOB_SCDR (SAM_PIOB_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOB_PPDDR (SAM_PIOB_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOB_PPDER (SAM_PIOB_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOB_PPDSR (SAM_PIOB_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOB_OWER (SAM_PIOB_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOB_OWDR (SAM_PIOB_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOB_OWSR (SAM_PIOB_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOB_AIMER (SAM_PIOB_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOB_AIMDR (SAM_PIOB_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOB_AIMMR (SAM_PIOB_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOB_ESR (SAM_PIOB_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOB_LSR (SAM_PIOB_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOB_ELSR (SAM_PIOB_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOB_FELLSR (SAM_PIOB_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOB_REHLSR (SAM_PIOB_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOB_FRLHSR (SAM_PIOB_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOB_LOCKSR (SAM_PIOB_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOB_WPMR (SAM_PIOB_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOB_WPSR (SAM_PIOB_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOB_SCHMITT (SAM_PIOB_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOB_DELAYR (SAM_PIOB_BASE+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIOB_PCMR (SAM_PIOB_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOB_PCIER (SAM_PIOB_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOB_PCIDR (SAM_PIOB_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOB_PCIMR (SAM_PIOB_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOB_PCISR (SAM_PIOB_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOB_PCRHR (SAM_PIOB_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOC_PER (SAM_PIOC_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOC_PDR (SAM_PIOC_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOC_PSR (SAM_PIOC_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOC_OER (SAM_PIOC_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOC_ODR (SAM_PIOC_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOC_OSR (SAM_PIOC_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOC_IFER (SAM_PIOC_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOC_IFDR (SAM_PIOC_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOC_IFSR (SAM_PIOC_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOC_SODR (SAM_PIOC_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOC_CODR (SAM_PIOC_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOC_ODSR (SAM_PIOC_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOC_PDSR (SAM_PIOC_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOC_IER (SAM_PIOC_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOC_IDR (SAM_PIOC_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOC_IMR (SAM_PIOC_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOC_ISR (SAM_PIOC_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOC_MDER (SAM_PIOC_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOC_MDDR (SAM_PIOC_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOC_MDSR (SAM_PIOC_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOC_PUDR (SAM_PIOC_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOC_PUER (SAM_PIOC_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOC_PUSR (SAM_PIOC_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOC_ABCDSR1 (SAM_PIOC_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOC_ABCDSR2 (SAM_PIOC_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOC_IFSCDR (SAM_PIOC_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOC_IFSCER (SAM_PIOC_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOC_IFSCSR (SAM_PIOC_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOC_SCDR (SAM_PIOC_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOC_PPDDR (SAM_PIOC_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOC_PPDER (SAM_PIOC_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOC_PPDSR (SAM_PIOC_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOC_OWER (SAM_PIOC_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOC_OWDR (SAM_PIOC_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOC_OWSR (SAM_PIOC_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOC_AIMER (SAM_PIOC_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOC_AIMDR (SAM_PIOC_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOC_AIMMR (SAM_PIOC_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOC_ESR (SAM_PIOC_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOC_LSR (SAM_PIOC_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOC_ELSR (SAM_PIOC_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOC_FELLSR (SAM_PIOC_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOC_REHLSR (SAM_PIOC_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOC_FRLHSR (SAM_PIOC_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOC_LOCKSR (SAM_PIOC_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOC_WPMR (SAM_PIOC_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOC_WPSR (SAM_PIOC_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOC_SCHMITT (SAM_PIOC_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOC_DELAYR (SAM_PIOC_BASE+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIOC_PCMR (SAM_PIOC_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOC_PCIER (SAM_PIOC_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOC_PCIDR (SAM_PIOC_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOC_PCIMR (SAM_PIOC_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOC_PCISR (SAM_PIOC_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOC_PCRHR (SAM_PIOC_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOD_PER (SAM_PIOD_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOD_PDR (SAM_PIOD_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOD_PSR (SAM_PIOD_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOD_OER (SAM_PIOD_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOD_ODR (SAM_PIOD_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOD_OSR (SAM_PIOD_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOD_IFER (SAM_PIOD_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOD_IFDR (SAM_PIOD_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOD_IFSR (SAM_PIOD_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOD_SODR (SAM_PIOD_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOD_CODR (SAM_PIOD_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOD_ODSR (SAM_PIOD_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOD_PDSR (SAM_PIOD_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOD_IER (SAM_PIOD_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOD_IDR (SAM_PIOD_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOD_IMR (SAM_PIOD_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOD_ISR (SAM_PIOD_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOD_MDER (SAM_PIOD_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOD_MDDR (SAM_PIOD_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOD_MDSR (SAM_PIOD_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOD_PUDR (SAM_PIOD_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOD_PUER (SAM_PIOD_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOD_PUSR (SAM_PIOD_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOD_ABCDSR1 (SAM_PIOD_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOD_ABCDSR2 (SAM_PIOD_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOD_IFSCDR (SAM_PIOD_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOD_IFSCER (SAM_PIOD_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOD_IFSCSR (SAM_PIOD_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOD_SCDR (SAM_PIOD_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOD_PPDDR (SAM_PIOD_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOD_PPDER (SAM_PIOD_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOD_PPDSR (SAM_PIOD_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOD_OWER (SAM_PIOD_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOD_OWDR (SAM_PIOD_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOD_OWSR (SAM_PIOD_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOD_AIMER (SAM_PIOD_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOD_AIMDR (SAM_PIOD_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOD_AIMMR (SAM_PIOD_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOD_ESR (SAM_PIOD_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOD_LSR (SAM_PIOD_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOD_ELSR (SAM_PIOD_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOD_FELLSR (SAM_PIOD_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOD_REHLSR (SAM_PIOD_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOD_FRLHSR (SAM_PIOD_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOD_LOCKSR (SAM_PIOD_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOD_WPMR (SAM_PIOD_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOD_WPSR (SAM_PIOD_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOD_SCHMITT (SAM_PIOD_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOD_DELAYR (SAM_PIOD_BASE+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIOD_PCMR (SAM_PIOD_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOD_PCIER (SAM_PIOD_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOD_PCIDR (SAM_PIOD_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOD_PCIMR (SAM_PIOD_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOD_PCISR (SAM_PIOD_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOD_PCRHR (SAM_PIOD_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOE_PER (SAM_PIOE_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOE_PDR (SAM_PIOE_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOE_PSR (SAM_PIOE_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOE_OER (SAM_PIOE_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOE_ODR (SAM_PIOE_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOE_OSR (SAM_PIOE_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOE_IFER (SAM_PIOE_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOE_IFDR (SAM_PIOE_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOE_IFSR (SAM_PIOE_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOE_SODR (SAM_PIOE_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOE_CODR (SAM_PIOE_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOE_ODSR (SAM_PIOE_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOE_PDSR (SAM_PIOE_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOE_IER (SAM_PIOE_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOE_IDR (SAM_PIOE_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOE_IMR (SAM_PIOE_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOE_ISR (SAM_PIOE_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOE_MDER (SAM_PIOE_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOE_MDDR (SAM_PIOE_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOE_MDSR (SAM_PIOE_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOE_PUDR (SAM_PIOE_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOE_PUER (SAM_PIOE_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOE_PUSR (SAM_PIOE_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOE_ABCDSR1 (SAM_PIOE_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOE_ABCDSR2 (SAM_PIOE_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOE_IFSCDR (SAM_PIOE_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOE_IFSCER (SAM_PIOE_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOE_IFSCSR (SAM_PIOE_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOE_SCDR (SAM_PIOE_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOE_PPDDR (SAM_PIOE_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOE_PPDER (SAM_PIOE_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOE_PPDSR (SAM_PIOE_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOE_OWER (SAM_PIOE_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOE_OWDR (SAM_PIOE_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOE_OWSR (SAM_PIOE_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOE_AIMER (SAM_PIOE_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOE_AIMDR (SAM_PIOE_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOE_AIMMR (SAM_PIOE_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOE_ESR (SAM_PIOE_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOE_LSR (SAM_PIOE_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOE_ELSR (SAM_PIOE_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOE_FELLSR (SAM_PIOE_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOE_REHLSR (SAM_PIOE_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOE_FRLHSR (SAM_PIOE_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOE_LOCKSR (SAM_PIOE_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOE_WPMR (SAM_PIOE_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOE_WPSR (SAM_PIOE_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOE_SCHMITT (SAM_PIOE_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOE_DELAYR (SAM_PIOE_BASE+SAM_PIO_DELAYR_OFFSET) +#define SAM_PIOE_PCMR (SAM_PIOE_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOE_PCIER (SAM_PIOE_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOE_PCIDR (SAM_PIOE_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOE_PCIMR (SAM_PIOE_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOE_PCISR (SAM_PIOE_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOE_PCRHR (SAM_PIOE_BASE+SAM_PIO_PCRHR_OFFSET + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for ALMOST all IO registers (exceptions follow) */ + +#define PIO(n) (1 << (n)) /* Bit n: PIO n, n=0-31 */ + +/* PIO Slow Clock Divider Debouncing Register */ + +#define PIO_SCDR_MASK (0x3fff) /* Bits 0-13: Slow Clock Divider */ + +/* PIO Write Protect Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PIO_WPMR_WPKEY_MASK (0xffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x50494f << PIO_WPMR_WPKEY_SHIFT) + +/* PIO Write Protect Status Register */ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/* IO Delay Register */ + +#define PIO_DELAYR_DELAY_SHIFT(d) ((d) << 2) +#define PIO_DELAYR_DELAY_MASK(d) (15 << PIO_DELAYR_SHIFT(d)) +# define PIO_DELAYR_DELAY(d,n) ((uint32_t)(n) << PIO_DELAYR_SHIFT(d)) + +#define PIO_DELAYR_DELAY0_SHIFT (0) /* Bits 0-3: Delay 0 */ +#define PIO_DELAYR_DELAY0_MASK (15 << PIO_DELAYR_DELAY0_SHIFT) +# define PIO_DELAYR_DELAY0(n) ((uint32_t)(n) << PIO_DELAYR_DELAY0_SHIFT) +#define PIO_DELAYR_DELAY1_SHIFT (4) /* Bits 4-7: Delay 0 */ +#define PIO_DELAYR_DELAY1_MASK (15 << PIO_DELAYR_DELAY1_SHIFT) +# define PIO_DELAYR_DELAY1(n) ((uint32_t)(n) << PIO_DELAYR_DELAY1_SHIFT) +#define PIO_DELAYR_DELAY2_SHIFT (8) /* Bits 8-11: Delay 0 */ +#define PIO_DELAYR_DELAY2_MASK (15 << PIO_DELAYR_DELAY2_SHIFT) +# define PIO_DELAYR_DELAY2(n) ((uint32_t)(n) << PIO_DELAYR_DELAY2_SHIFT) +#define PIO_DELAYR_DELAY3_SHIFT (12) /* Bits 12-15: Delay 0 */ +#define PIO_DELAYR_DELAY3_MASK (15 << PIO_DELAYR_DELAY3_SHIFT) +# define PIO_DELAYR_DELAY3(n) ((uint32_t)(n) << PIO_DELAYR_DELAY3_SHIFT) +#define PIO_DELAYR_DELAY4_SHIFT (16) /* Bits 16-19: Delay 0 */ +#define PIO_DELAYR_DELAY4_MASK (15 << PIO_DELAYR_DELAY4_SHIFT) +# define PIO_DELAYR_DELAY4(n) ((uint32_t)(n) << PIO_DELAYR_DELAY4_SHIFT) +#define PIO_DELAYR_DELAY5_SHIFT (20) /* Bits 20-23: Delay 0 */ +#define PIO_DELAYR_DELAY5_MASK (15 << PIO_DELAYR_DELAY5_SHIFT) +# define PIO_DELAYR_DELAY5(n) ((uint32_t)(n) << PIO_DELAYR_DELAY5_SHIFT) +#define PIO_DELAYR_DELAY6_SHIFT (24) /* Bits 24-27: Delay 0 */ +#define PIO_DELAYR_DELAY6_MASK (15 << PIO_DELAYR_DELAY6_SHIFT) +# define PIO_DELAYR_DELAY6(n) ((uint32_t)(n) << PIO_DELAYR_DELAY6_SHIFT) +#define PIO_DELAYR_DELAY7_SHIFT (28) /* Bits 28-31: Delay 0 */ +#define PIO_DELAYR_DELAY7_MASK (15 << PIO_DELAYR_DELAY7_SHIFT) +# define PIO_DELAYR_DELAY7(n) ((uint32_t)(n) << PIO_DELAYR_DELAY7_SHIFT) + +/* PIO Parallel Capture Mode Register */ + +#define PIO_PCMR_PCEN (1 << 0) /* Bit 0: Parallel Capture Mode Enable */ +#define PIO_PCMR_DSIZE_SHIFT (4) /* Bits 4-5: Parallel Capture Mode Data Size */ +#define PIO_PCMR_DSIZE_MASK (3 << PIO_PCMR_DSIZE_SHIFT) +# define PIO_PCMR_DSIZE_BYTE (0 << PIO_PCMR_DSIZE_SHIFT) /* 8-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_HWORD (1 << PIO_PCMR_DSIZE_SHIFT) /* 16-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_WORD (2 << PIO_PCMR_DSIZE_SHIFT) /* 32-bit data in PIO_PCRHR */ +#define PIO_PCMR_ALWYS (1 << 9) /* Bit 9: Parallel Capture Mode Always Sampling */ +#define PIO_PCMR_HALFS (1 << 10) /* Bit 10: Parallel Capture Mode Half Sampling */ +#define PIO_PCMR_FRSTS (1 << 11) /* Bit 11: Parallel Capture Mode First Sample */ + +/* PIO Parallel Capture Interrupt Enable, Disable, Mask, and Status Registers */ + +#define PIOC_PCINT_DRDY (1 << 0) /* Bit 0: Parallel Capture Mode Data Ready Interrupt Enable */ +#define PIOC_PCINT_OVRE (1 << 1) /* Bit 1: Parallel Capture Mode Overrun Error Interrupt Enable */ +#define PIOC_PCINT_ENDRX (1 << 2) /* Bit 2: End of Reception Transfer Interrupt Enable */ +#define PIOC_PCINT_RXBUFF (1 << 3) /* Bit 3: Reception Buffer Full Interrupt Enable */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4E_PIO_H */ diff --git a/arch/arm/src/sam34/chip/sam4e_vectors.h b/arch/arm/src/sam34/chip/sam4e_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..5caa10fe39ac1468284a08b66518ce63218c037c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4e_vectors.h @@ -0,0 +1,103 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4e_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that supplies each SAM4E + * vector in terms of a (lower-case) ISR label and an (upper-case) IRQ number as defined in + * arch/arm/include/sam/sam3u_irq.h. sam_vectors.S will defined the VECTOR in different ways in + * order to generate the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 35 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 47 + +#else + VECTOR(sam_supc, SAM_IRQ_SUPC) /* Vector 16+0: Supply Controller */ + VECTOR(sam_rstc, SAM_IRQ_RSTC) /* Vector 16+1: Reset Controller */ + VECTOR(sam_rtc, SAM_IRQ_RTC) /* Vector 16+2: Real Time Clock */ + VECTOR(sam_rtt, SAM_IRQ_RTT) /* Vector 16+3: Real Time Timer */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+4: Watchdog Timer */ + VECTOR(sam_pmc, SAM_IRQ_PMC) /* Vector 16+5: Power Management Controller */ + VECTOR(sam_eefc0, SAM_PID_EEFC0) /* Vector 16+6: Enhanced Embedded Flash Controller */ + VECTOR(sam_uart0, SAM_IRQ_UART0) /* Vector 16+7: Universal Asynchronous Receiver Transmitter 0 */ + UNUSED(SAM_IRQ_RESERVED_8) /* Vector 16+8: Static Memory Controller (no vector) */ + VECTOR(sam_pioa, SAM_IRQ_PIOA) /* Vector 16+9: Parallel I/O Controller A */ + VECTOR(sam_piob, SAM_IRQ_PIOB) /* Vector 16+10: Parallel I/O Controller B */ + VECTOR(sam_pioc, SAM_IRQ_PIOC) /* Vector 16+11: Parallel I/O Controller C */ + VECTOR(sam_piod, SAM_IRQ_PIOD) /* Vector 16+12: Parallel I/O Controller C */ + VECTOR(sam_pioe, SAM_IRQ_PIOE) /* Vector 16+13: Parallel I/O Controller C */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+14: USART 0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+15: USART 1 */ + VECTOR(sam_hsmci, SAM_IRQ_HSMCI) /* Vector 16+16: High Speed Multimedia Card Interface */ + VECTOR(sam_twi0, SAM_IRQ_TWI0) /* Vector 16+17: Two-Wire Interface 0 */ + VECTOR(sam_twi1, SAM_IRQ_TWI1) /* Vector 16+18: Two-Wire Interface 1 */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+19: Serial Peripheral Interface */ + VECTOR(sam_dmac, SAM_IRQ_DMAC) /* Vector 16+20: DMA controller */ + VECTOR(sam_tc0, SAM_IRQ_TC0) /* Vector 16+21: Timer Counter 0 */ + VECTOR(sam_tc1, SAM_IRQ_TC1) /* Vector 16+22: Timer Counter 1 */ + VECTOR(sam_tc2, SAM_IRQ_TC2) /* Vector 16+23: Timer Counter 2 */ + VECTOR(sam_tc3, SAM_IRQ_TC3) /* Vector 16+24: Timer Counter 3 */ + VECTOR(sam_tc4, SAM_IRQ_TC4) /* Vector 16+25: Timer Counter 4 */ + VECTOR(sam_tc5, SAM_IRQ_TC5) /* Vector 16+26: Timer Counter 5 */ + VECTOR(sam_tc6, SAM_IRQ_TC6) /* Vector 16+27: Timer Counter 6 */ + VECTOR(sam_tc7, SAM_IRQ_TC7) /* Vector 16+28: Timer Counter 7 */ + VECTOR(sam_tc8, SAM_IRQ_TC8) /* Vector 16+29: Timer Counter 8 */ + VECTOR(sam_afec0, SAM_IRQ_AFEC0) /* Vector 16+30: Analog Front End 0 */ + VECTOR(sam_afec1, SAM_IRQ_AFEC1) /* Vector 16+31: Analog Front End 1 */ + VECTOR(sam_dacc, SAM_IRQ_DACC) /* Vector 16+32: Digital To Analog Converter */ + VECTOR(sam_acc, SAM_IRQ_ACC) /* Vector 16+33: Analog Comparator */ + VECTOR(sam_arm, SAM_IRQ_ARM) /* Vector 16+34: FPU signals: FPIXC, FPOFC, FPUFC, FPIOC, FPDZC,FPIDC, FPIXC */ + VECTOR(sam_udp, SAM_IRQ_UDP) /* Vector 16+35: USB Device Port */ + VECTOR(sam_pwm, SAM_IRQ_PWM) /* Vector 16+36: Pulse Width Modulation */ + VECTOR(sam_can0, SAM_IRQ_CAN0) /* Vector 16+37: CAN0 */ + VECTOR(sam_can1, SAM_IRQ_CAN1) /* Vector 16+38: CAN1 */ + VECTOR(sam_aes, SAM_IRQ_AES) /* Vector 16+39: AES */ + UNUSED(SAM_IRQ_RESERVED_40) /* Vector 16+40: Reserved */ + UNUSED(SAM_IRQ_RESERVED_41) /* Vector 16+41: Reserved */ + UNUSED(SAM_IRQ_RESERVED_42) /* Vector 16+42: Reserved */ + UNUSED(SAM_IRQ_RESERVED_43) /* Vector 16+43: Reserved */ + VECTOR(sam_emac, SAM_IRQ_EMAC) /* Vector 16+44: EMAC */ + VECTOR(sam_uart1, SAM_IRQ_UART1) /* Vector 16+45: UART1 */ + UNUSED(SAM_IRQ_RESERVED_46) /* Vector 16+46: Reserved */ +#endif diff --git a/arch/arm/src/sam34/chip/sam4l_bpm.h b/arch/arm/src/sam34/chip/sam4l_bpm.h new file mode 100644 index 0000000000000000000000000000000000000000..12dba10629bc0b0a6e85c184161b5a624075ea6c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_bpm.h @@ -0,0 +1,178 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_bpm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BPM_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BPM_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* BPM register offsets ****************************************************************/ + +#define SAM_BPM_IER_OFFSET 0x0000 /* Interrupt Enable Register */ +#define SAM_BPM_IDR_OFFSET 0x0004 /* Interrupt Disable Register */ +#define SAM_BPM_IMR_OFFSET 0x0008 /* Interrupt Mask Register */ +#define SAM_BPM_ISR_OFFSET 0x000c /* Interrupt Status Register */ +#define SAM_BPM_ICR_OFFSET 0x0010 /* Interrupt Clear Register */ +#define SAM_BPM_SR_OFFSET 0x0014 /* Status Register */ +#define SAM_BPM_UNLOCK_OFFSET 0x0018 /* Unlock Register */ +#define SAM_BPM_PMCON_OFFSET 0x001c /* Power Mode Control Register */ +#define SAM_BPM_BKUPWCAUSE_OFFSET 0x0028 /* Backup Wake up Cause Register */ +#define SAM_BPM_BKUPWEN_OFFSET 0x002c /* Backup Wake up Enable Register */ +#define SAM_BPM_BKUPPMUX_OFFSET 0x0030 /* Backup Pin Muxing Register */ +#define SAM_BPM_IORET_OFFSET 0x0034 /* Input Output Retention Register */ +#define SAM_BPM_VERSION_OFFSET 0x00fc /* Version Register */ + +/* BPM register addresses **************************************************************/ + +#define SAM_BPM_IER (SAM_BPM_BASE+SAM_BPM_IER_OFFSET) +#define SAM_BPM_IDR (SAM_BPM_BASE+SAM_BPM_IDR_OFFSET) +#define SAM_BPM_IMR (SAM_BPM_BASE+SAM_BPM_IMR_OFFSET) +#define SAM_BPM_ISR (SAM_BPM_BASE+SAM_BPM_ISR_OFFSET) +#define SAM_BPM_ICR (SAM_BPM_BASE+SAM_BPM_ICR_OFFSET) +#define SAM_BPM_SR (SAM_BPM_BASE+SAM_BPM_SR_OFFSET) +#define SAM_BPM_UNLOCK (SAM_BPM_BASE+SAM_BPM_UNLOCK_OFFSET) +#define SAM_BPM_PMCON (SAM_BPM_BASE+SAM_BPM_PMCON_OFFSET) +#define SAM_BPM_BKUPWCAUSE (SAM_BPM_BASE+SAM_BPM_BKUPWCAUSE_OFFSET) +#define SAM_BPM_BKUPWEN (SAM_BPM_BASE+SAM_BPM_BKUPWEN_OFFSET) +#define SAM_BPM_BKUPPMUX (SAM_BPM_BASE+SAM_BPM_BKUPPMUX_OFFSET) +#define SAM_BPM_IORET (SAM_BPM_BASE+SAM_BPM_IORET_OFFSET) +#define SAM_BPM_VERSION (SAM_BPM_BASE+SAM_BPM_VERSION_OFFSET) + +/* BPM register bit definitions ********************************************************/ + +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ +/* Interrupt Status Register */ +/* Interrupt Clear Register */ +/* Status Register */ + +#define BPM_INT_PSOK (1 << 0) /* Bit 0: Power Scaling OK */ +#define BPM_INT_AE (1 << 31) /* Bit 31: Access Error */ + +/* Unlock Register */ + +#define BPM_UNLOCK_ADDR_SHIFT (0) /* Bits 0-9: Unlock Address */ +#define BPM_UNLOCK_ADDR_MASK (0x3ff << BPM_UNLOCK_ADDR_SHIFT) +# define BPM_UNLOCK_ADDR(n) ((n) << BPM_UNLOCK_ADDR_SHIFT) +#define BPM_UNLOCK_KEY_SHIFT (24) /* Bits 24-31: Unlock Key */ +#define BPM_UNLOCK_KEY_MASK (0xff << BPM_UNLOCK_KEY_SHIFT) +# define BPM_UNLOCK_KEY(n) ((n) << BPM_UNLOCK_KEY_SHIFT) + +/* Power Mode Control Register */ + +#define BPM_PMCON_PS_SHIFT (0) /* Bits 0-1: Power Scaling Configuration Value */ +#define BPM_PMCON_PS_MASK (3 << BPM_PMCON_PS_SHIFT) +# define BPM_PMCON_PS0 (0 << BPM_PMCON_PS_SHIFT) +# define BPM_PMCON_PS1 (1 << BPM_PMCON_PS_SHIFT) +# define BPM_PMCON_PS2 (2 << BPM_PMCON_PS_SHIFT) +#define BPM_PMCON_PSCREQ (1 << 2) /* Bit 2: Power Scaling Change Request */ +#define BPM_PMCON_PSCM (1 << 3) /* Bit 3: Power Scaling Change Mode */ +#define BPM_PMCON_BKUP (1 << 8) /* Bit 8: BACKUP Mode */ +#define BPM_PMCON_RET (1 << 9) /* Bit 9: RETENTION Mode */ +#define BPM_PMCON_SLEEP_SHIFT (12) /* Bits 12-13: SLEEP mode Configuration */ +#define BPM_PMCON_SLEEP_MASK (3 << BPM_PMCON_SLEEP_SHIFT) +# define BPM_PMCON_SLEEP_SLEEP0 (0 << BPM_PMCON_SLEEP_SHIFT) /* CPU clock stopped */ +# define BPM_PMCON_SLEEP_SLEEP1 (1 << BPM_PMCON_SLEEP_SHIFT) /* CPU+AHB clocks stopped */ +# define BPM_PMCON_SLEEP_SLEEP2 (2 << BPM_PMCON_SLEEP_SHIFT) /* CPU+AHB+PB+GCLK clocks stopped */ +# define BPM_PMCON_SLEEP_SLEEP3 (3 << BPM_PMCON_SLEEP_SHIFT) /* CPU+AHB+PB+GCLK+sources stopped */ +#define BPM_PMCON_CK32S (1 << 16) /* Bit 16: 32kHz-1kHz Clock Source Selection */ +#define BPM_PMCON_FASTWKUP (1 << 24) /* Bit 24: Fast Wakeup */ + +/* Backup Wake up Cause Register */ + +#define BPM_BKUPWCAUSE_EIC (1 << 0) /* Bit 0: EIC */ +#define BPM_BKUPWCAUSE_AST (1 << 1) /* Bit 1: AST */ +#define BPM_BKUPWCAUSE_WDT (1 << 2) /* Bit 2: WDT interrupt */ +#define BPM_BKUPWCAUSE_BOD33 (1 << 3) /* Bit 3: BOD33 interrupt */ +#define BPM_BKUPWCAUSE_BOD18 (1 << 4) /* Bit 4: BOD18 interrupt */ +#define BPM_BKUPWCAUSE_PICOUART (1 << 5) /* Bit 5: PICOUART interrupt */ + +/* Backup Wake up Enable Register */ + +#define BPM_BKUPWEN_EICEN (1 << 0) /* Bit 0: EIC */ +#define BPM_BKUPWEN_ASTEN (1 << 1) /* Bit 1: AST */ +#define BPM_BKUPWEN_WDTEN (1 << 2) /* Bit 2: WDT interrupt */ +#define BPM_BKUPWEN_BOD33EN (1 << 3) /* Bit 3: BOD33 interrupt */ +#define BPM_BKUPWEN_BOD18EN (1 << 4) /* Bit 4: BOD18 interrupt */ +#define BPM_BKUPWEN_PICOUARTEN (1 << 5) /* Bit 5: PICOUART interrupt */ + +/* Backup Pin Muxing Register */ + +#define BPM_BKUPPMUX_EIC0 (1 << 0) /* Bit 0: PB01 EIC[0] */ +#define BPM_BKUPPMUX_EIC1 (1 << 1) /* Bit 1: PA06 EIC[1] */ +#define BPM_BKUPPMUX_EIC2 (1 << 2) /* Bit 2: PA04 EIC[2] */ +#define BPM_BKUPPMUX_EIC3 (1 << 3) /* Bit 3: PA05 EIC[3] */ +#define BPM_BKUPPMUX_EIC4 (1 << 4) /* Bit 4: PA07 EIC[4] */ +#define BPM_BKUPPMUX_EIC5 (1 << 5) /* Bit 5: PC03 EIC[5] */ +#define BPM_BKUPPMUX_EIC6 (1 << 6) /* Bit 6: PC04 EIC[6] */ +#define BPM_BKUPPMUX_EIC7 (1 << 7) /* Bit 7: PC05 EIC[7] */ +#define BPM_BKUPPMUX_EIC8 (1 << 8) /* Bit 8: PC06 EIC[8] */ + +/* Input Output Retention Register */ + +#define BPM_IORET_RET (1 << 0) /* Bit 0: : Retention on I/O lines after wakeup */ + +/* Version Register */ + +#define BPM_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define BPM_VERSION_MASK (0xfff << BPM_VERSION_VERSION_SHIFT) +#define BPM_VERSION_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define BPM_VERSION_VARIANT_MASK (15 << BPM_VERSION_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BPM_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_bscif.h b/arch/arm/src/sam34/chip/sam4l_bscif.h new file mode 100644 index 0000000000000000000000000000000000000000..6389e05d6e4830c495d55737ca684a39740a9565 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_bscif.h @@ -0,0 +1,316 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_bscif.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BSCIF_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BSCIF_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* BSCIF register offsets ***************************************************************/ + +#define SAM_BSCIF_IER_OFFSET 0x0000 /* Interrupt Enable Register */ +#define SAM_BSCIF_IDR_OFFSET 0x0004 /* Interrupt Disable Register */ +#define SAM_BSCIF_IMR_OFFSET 0x0008 /* Interrupt Mask Register */ +#define SAM_BSCIF_ISR_OFFSET 0x000c /* Interrupt Status Register */ +#define SAM_BSCIF_ICR_OFFSET 0x0010 /* Interrupt Clear Register */ +#define SAM_BSCIF_PCLKSR_OFFSET 0x0014 /* Power and Clocks Status Register */ +#define SAM_BSCIF_UNLOCK_OFFSET 0x0018 /* Unlock Register */ +#define SAM_BSCIF_CSCR_OFFSET 0x001c /* Chip Specific Configuration Register */ +#define SAM_BSCIF_OSCCTRL32_OFFSET 0x0020 /* Oscillator 32 Control Register */ +#define SAM_BSCIF_RC32KCR_OFFSET 0x0024 /* 32kHz RC Oscillator Control Register */ +#define SAM_BSCIF_RC32KTUNE_OFFSET 0x0028 /* 32kHz RC Oscillator Tuning Register */ +#define SAM_BSCIF_BOD33CTRL_OFFSET 0x002c /* BOD33 Control Register */ +#define SAM_BSCIF_BOD33LEVEL_OFFSET 0x0030 /* BOD33 Level Register */ +#define SAM_BSCIF_BOD33SAMPLING_OFFSET 0x0034 /* BOD33 Sampling Control Register */ +#define SAM_BSCIF_BOD18CTRL_OFFSET 0x0038 /* BOD18 Control Register */ +#define SAM_BSCIF_BOD18LEVEL_OFFSET 0x003c /* BOD18 Level Register */ +#define SAM_BSCIF_BOD18SAMPLING_OFFSET 0x0040 /* BOD18 Sampling Control Register */ +#define SAM_BSCIF_VREGCR_OFFSET 0x0044 /* Voltage Regulator Configuration Register */ +#define SAM_BSCIF_RC1MCR_OFFSET 0x0058 /* 1MHz RC Clock Configuration Register */ +#define SAM_BSCIF_BGCTRL_OFFSET 0x0060 /* Bandgap Control Register */ +#define SAM_BSCIF_BGS_OFFSET 0x0064 /* Bandgap Status Register */ +#define SAM_BSCIF_BR_OFFSET(n) (0x0078+((n)<<2) /* 0x0078-0x0084 Backup register n=0..3 */ +#define SAM_BSCIF_BR0_OFFSET 0x0078 /* Backup register 0 */ +#define SAM_BSCIF_BR1_OFFSET 0x007c /* Backup register 1 */ +#define SAM_BSCIF_BR2_OFFSET 0x0080 /* Backup register 2 */ +#define SAM_BSCIF_BR3_OFFSET 0x0004 /* Backup register 3 */ +#define SAM_BSCIF_BRIFBVERSION_OFFSET 0x03e4 /* Backup Register Interface Version Register */ +#define SAM_BSCIF_BGREFIFBVERSION_OFFSET 0x03e8 /* BGREFIF Version Register */ +#define SAM_BSCIF_VREGIFGVERSION_OFFSET 0x03ec /* Voltage Regulator Version Register */ +#define SAM_BSCIF_BODIFCVERSION_OFFSET 0x03f0 /* BOD Version Register */ +#define SAM_BSCIF_RC32KIFBVERSION_OFFSET 0x03f4 /* 32kHz RC Oscillator Version Register */ +#define SAM_BSCIF_OSC32IFAVERSION_OFFSET 0x03f8 /* 32 kHz Oscillator Version Register */ +#define SAM_BSCIF_VERSION_OFFSET 0x03fc /* BSCIF Version Register */ + +/* BSCIF register addresses *************************************************************/ + +#define SAM_BSCIF_IER (SAM_BSCIF_BASE+SAM_BSCIF_IER_OFFSET) +#define SAM_BSCIF_IDR (SAM_BSCIF_BASE+SAM_BSCIF_IDR_OFFSET) +#define SAM_BSCIF_IMR (SAM_BSCIF_BASE+SAM_BSCIF_IMR_OFFSET) +#define SAM_BSCIF_ISR (SAM_BSCIF_BASE+SAM_BSCIF_ISR_OFFSET) +#define SAM_BSCIF_ICR (SAM_BSCIF_BASE+SAM_BSCIF_ICR_OFFSET) +#define SAM_BSCIF_PCLKSR (SAM_BSCIF_BASE+SAM_BSCIF_PCLKSR_OFFSET) +#define SAM_BSCIF_UNLOCK (SAM_BSCIF_BASE+SAM_BSCIF_UNLOCK_OFFSET) +#define SAM_BSCIF_CSCR (SAM_BSCIF_BASE+SAM_BSCIF_CSCR_OFFSET) +#define SAM_BSCIF_OSCCTRL32 (SAM_BSCIF_BASE+SAM_BSCIF_OSCCTRL32_OFFSET) +#define SAM_BSCIF_RC32KCR (SAM_BSCIF_BASE+SAM_BSCIF_RC32KCR_OFFSET) +#define SAM_BSCIF_RC32KTUNE (SAM_BSCIF_BASE+SAM_BSCIF_RC32KTUNE_OFFSET) +#define SAM_BSCIF_BOD33CTRL (SAM_BSCIF_BASE+SAM_BSCIF_BOD33CTRL_OFFSET) +#define SAM_BSCIF_BOD33LEVEL (SAM_BSCIF_BASE+SAM_BSCIF_BOD33LEVEL_OFFSET) +#define SAM_BSCIF_BOD33SAMPLING (SAM_BSCIF_BASE+SAM_BSCIF_BOD33SAMPLING_OFFSET) +#define SAM_BSCIF_BOD18CTRL (SAM_BSCIF_BASE+SAM_BSCIF_BOD18CTRL_OFFSET) +#define SAM_BSCIF_BOD18LEVEL (SAM_BSCIF_BASE+SAM_BSCIF_BOD18LEVEL_OFFSET) +#define SAM_BSCIF_BOD18SAMPLING (SAM_BSCIF_BASE+SAM_BSCIF_BOD18SAMPLING_OFFSET) +#define SAM_BSCIF_VREGCR (SAM_BSCIF_BASE+SAM_BSCIF_VREGCR_OFFSET) +#define SAM_BSCIF_RC1MCR (SAM_BSCIF_BASE+SAM_BSCIF_RC1MCR_OFFSET) +#define SAM_BSCIF_BGCTRL (SAM_BSCIF_BASE+SAM_BSCIF_BGCTRL_OFFSET) +#define SAM_BSCIF_BGS (SAM_BSCIF_BASE+SAM_BSCIF_BGS_OFFSET) +#define SAM_BSCIF_BR(n) (SAM_BSCIF_BASE+SAM_BSCIF_BR_OFFSET(n)) +#define SAM_BSCIF_BR0 (SAM_BSCIF_BASE+SAM_BSCIF_BR0_OFFSET) +#define SAM_BSCIF_BR1 (SAM_BSCIF_BASE+SAM_BSCIF_BR1_OFFSET) +#define SAM_BSCIF_BR2 (SAM_BSCIF_BASE+SAM_BSCIF_BR2_OFFSET) +#define SAM_BSCIF_BR3 (SAM_BSCIF_BASE+SAM_BSCIF_BR3_OFFSET) +#define SAM_BSCIF_BRIFBVERSION (SAM_BSCIF_BASE+SAM_BSCIF_BRIFBVERSION_OFFSET) +#define SAM_BSCIF_BGREFIFBVERSION (SAM_BSCIF_BASE+SAM_BSCIF_BGREFIFBVERSION_OFFSET) +#define SAM_BSCIF_VREGIFGVERSION (SAM_BSCIF_BASE+SAM_BSCIF_VREGIFGVERSION_OFFSET) +#define SAM_BSCIF_BODIFCVERSION (SAM_BSCIF_BASE+SAM_BSCIF_BODIFCVERSION_OFFSET) +#define SAM_BSCIF_RC32KIFBVERSION (SAM_BSCIF_BASE+SAM_BSCIF_RC32KIFBVERSION_OFFSET) +#define SAM_BSCIF_OSC32IFAVERSION (SAM_BSCIF_BASE+SAM_BSCIF_OSC32IFAVERSION_OFFSET) +#define SAM_BSCIF_VERSION (SAM_BSCIF_BASE+SAM_BSCIF_VERSION_OFFSET) + +/* BSCIF register bit definitions *******************************************************/ + +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ +/* Interrupt Status Register */ +/* Interrupt Clear Register */ + +#define BSCIF_INT_OSC32RDY (1 << 0) /* Bit 0 */ +#define BSCIF_INT_RC32KRDY (1 << 1) /* Bit 1 */ +#define BSCIF_INT_RC32KLOCK (1 << 2) /* Bit 2 */ +#define BSCIF_INT_RC32KREFE (1 << 3) /* Bit 3 */ +#define BSCIF_INT_RC32KSAT (1 << 4) /* Bit 4 */ +#define BSCIF_INT_BOD33DET (1 << 5) /* Bit 5 */ +#define BSCIF_INT_BOD18DET (1 << 6) /* Bit 6 */ +#define BSCIF_INT_BOD33SYNRDY (1 << 7) /* Bit 7 */ +#define BSCIF_INT_BOD18SYNRDY (1 << 8) /* Bit 8 */ +#define BSCIF_INT_SSWRDY (1 << 9) /* Bit 9: Buck voltage regulator has stopped switching */ +#define BSCIF_INT_VREGOK (1 << 10) /* Bit 10 */ +#define BSCIF_INT_LPBGRDY (1 << 12) /* Bit 12 */ +#define BSCIF_INT_AE (1 << 31) /* Bit 31 */ + +/* Power and Clocks Status Register */ + +#define BSCIF_PCLKSR_OSC32RDY (1 << 0) /* Bit 0 */ +#define BSCIF_PCLKSR_RC32KRDY (1 << 1) /* Bit 1 */ +#define BSCIF_PCLKSR_RC32KLOCK (1 << 2) /* Bit 2 */ +#define BSCIF_PCLKSR_RC32KREFE (1 << 3) /* Bit 3 */ +#define BSCIF_PCLKSR_RC32KSAT (1 << 4) /* Bit 4 */ +#define BSCIF_PCLKSR_BOD33DET (1 << 5) /* Bit 5 */ +#define BSCIF_PCLKSR_BOD18DET (1 << 6) /* Bit 6 */ +#define BSCIF_PCLKSR_BOD33SYNRDY (1 << 7) /* Bit 7 */ +#define BSCIF_PCLKSR_BOD18SYNRDY (1 << 8) /* Bit 8 */ +#define BSCIF_PCLKSR_SSWRDY (1 << 9) /* Bit 9: Buck voltage regulator has stopped switching */ +#define BSCIF_PCLKSR_VREGOK (1 << 10) /* Bit 10 */ +#define BSCIF_PCLKSR_RC1MRDY (1 << 11) /* Bit 11 */ +#define BSCIF_PCLKSR_LPBGRDY (1 << 12) /* Bit 12 */ + +/* Unlock Register */ + +#define BSCIF_UNLOCK_ADDR_SHIFT (0) /* Bits 0-9: Unlock Address */ +#define BSCIF_UNLOCK_ADDR_MASK (0x3ff << BSCIF_UNLOCK_ADDR_SHIFT) +# define BSCIF_UNLOCK_ADDR(n) ((n) << BSCIF_UNLOCK_ADDR_SHIFT) +#define BSCIF_UNLOCK_KEY_SHIFT (24) /* Bits 24-31: Unlock Key */ +#define BSCIF_UNLOCK_KEY_MASK (0xff << BSCIF_UNLOCK_KEY_SHIFT) +# define BSCIF_UNLOCK_KEY(n) ((n) << BSCIF_UNLOCK_KEY_SHIFT) + +/* Chip Specific Configuration Register */ + +/* Oscillator 32 Control Register */ + +#define BSCIF_OSCCTRL32_OSC32EN (1 << 0) /* Bit 0: 32 KHz Oscillator Enable */ +#define BSCIF_OSCCTRL32_EN32K (1 << 2) /* Bit 2: 32 KHz output Enable */ +#define BSCIF_OSCCTRL32_EN1K (1 << 3) /* Bit 3: 1 KHz output Enable */ +#define BSCIF_OSCCTRL32_MODE_SHIFT (8) /* Bits 8-10: Oscillator Mode */ +#define BSCIF_OSCCTRL32_MODE_MASK (7 << BSCIF_OSCCTRL32_MODE_SHIFT) +# define BSCIF_OSCCTRL32_MODE_EXTCLK (0 << BSCIF_OSCCTRL32_MODE_SHIFT) /* External clock */ +# define BSCIF_OSCCTRL32_MODE_XTAL (1 << BSCIF_OSCCTRL32_MODE_SHIFT) /* Crystal mode */ +# define BSCIF_OSCCTRL32_MODE_XTALAC (3 << BSCIF_OSCCTRL32_MODE_SHIFT) /* Crystal + amplitude controlled mode */ +# define BSCIF_OSCCTRL32_MODE_XTALHC (4 << BSCIF_OSCCTRL32_MODE_SHIFT) /* Crystal + high current mode */ +# define BSCIF_OSCCTRL32_MODE_XTALHCAC (5 << BSCIF_OSCCTRL32_MODE_SHIFT) /* Crystal + high current + amplitude controlled mode */ +#define BSCIF_OSCCTRL32_SELCURR_SHIFT (12) /* Bits 12-15: Current Selection */ +#define BSCIF_OSCCTRL32_SELCURR_MASK (15 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_50 (0 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_75 (1 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_100 (2 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_125 (3 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_150 (4 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_175 (5 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_200 (6 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_225 (7 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_250 (8 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_275 (9 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_300 (10 << BSCIF_OSCCTRL32_SELCURR_SHIFT) /* (recommended value) */ +# define BSCIF_OSCCTRL32_SELCURR_325 (11 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_350 (12 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_375 (13 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_400 (14 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +# define BSCIF_OSCCTRL32_SELCURR_425 (15 << BSCIF_OSCCTRL32_SELCURR_SHIFT) +#define BSCIF_OSCCTRL32_STARTUP_SHIFT (16) /* Bits 16-18: Oscillator Start-up Time */ +#define BSCIF_OSCCTRL32_STARTUP_MASK (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) +# define BSCIF_OSCCTRL32_STARTUP_0 (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) +# define BSCIF_OSCCTRL32_STARTUP_128 (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 128 1.1 ms */ +# define BSCIF_OSCCTRL32_STARTUP_8K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 8192 72.3 ms */ +# define BSCIF_OSCCTRL32_STARTUP_16K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 16384 143 ms */ +# define BSCIF_OSCCTRL32_STARTUP_64K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 65536 570 ms */ +# define BSCIF_OSCCTRL32_STARTUP_128K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 131072 1.1 s */ +# define BSCIF_OSCCTRL32_STARTUP_256K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 262144 2.3 s */ +# define BSCIF_OSCCTRL32_STARTUP_512K (7 << BSCIF_OSCCTRL32_STARTUP_SHIFT) /* 524288 4.6 s */ +#define BSCIF_OSCCTRL32_RESERVED (1 << 31) /* Bit 31: Reserved, must always be written as zero */ + +/* 32kHz RC Oscillator Control Register */ + +#define BSCIF_RC32KCR_EN (1 << 0) /* Bit 0: Enable as Generic clock source */ +#define BSCIF_RC32KCR_TCEN (1 << 1) /* Bit 1: Temperature Compensation Enable */ +#define BSCIF_RC32KCR_EN32K (1 << 2) /* Bit 2: Enable 32 KHz output */ +#define BSCIF_RC32KCR_EN1K (1 << 3) /* Bit 3: Enable 1 kHz output */ +#define BSCIF_RC32KCR_MODE (1 << 4) /* Bit 4: Mode Selection */ +#define BSCIF_RC32KCR_REF (1 << 5) /* Bit 5: Reference select */ +#define BSCIF_RC32KCR_FCD (1 << 7) /* Bit 7: Flash calibration done */ + +/* 32kHz RC Oscillator Tuning Register */ + +#define BSCIF_RC32KTUNE_FINE_SHIFT (0) /* Bits 0-5: Fine Value */ +#define BSCIF_RC32KTUNE_FINE_MASK (0x3f << BSCIF_RC32KTUNE_FINE_SHIFT) +#define BSCIF_RC32KTUNE_COARSE_SHIFT (16) /* Bits 16-22: Coarse value */ +#define BSCIF_RC32KTUNE_COARSE_MASK (0x7f << BSCIF_RC32KTUNE_COARSE_SHIFT) + +/* BOD33 Control Register */ +/* BOD18 Control Register */ + +#define BSCIF_BODCTRL_EN (1 << 0) /* Bit 0: Enable */ +#define BSCIF_BODCTRL_HYST (1 << 1) /* Bit 1: BOD Hysteresis */ +#define BSCIF_BODCTRL_ACTION_SHIFT (8) /* Bits 8-9: Action */ +# define BSCIF_BODCTRL_ACTION_RESET (1 << BSCIF_BODCTRL_ACTION_SHIFT) /* The BOD generates a reset */ +# define BSCIF_BODCTRL_ACTION_INTR (2 << BSCIF_BODCTRL_ACTION_SHIFT) /* The BOD generates an interrupt */ +#define BSCIF_BODCTRL_MODE (1 << 0) /* Bit 0: Operation modes */ +#define BSCIF_BODCTRL_FCD (1 << 0) /* Bit 0: BOD Fuse Calibration Done */ +#define BSCIF_BODCTRL_SFV (1 << 0) /* Bit 0: BOD Control Register Store Final Value */ + +/* BOD33 Level Register */ +/* BOD18 Level Register */ + +#define BSCIF_BODLEVEL_CEN (1 << 0) /* Bit 0: Clock Enable */ +#define BSCIF_BODLEVEL_CSSEL (1 << 1) /* Bit 1: Clock Source Select */ +#define BSCIF_BODLEVEL_PSEL_SHIFT (8) /* Bits 8-11: Prescaler Select */ +#define BSCIF_BODLEVEL_PSEL_MASK (15 << BSCIF_BODLEVEL_PSEL_SHIFT) + +/* BOD33 Sampling Control Register */ +/* BOD18 Sampling Control Register */ + +#define BSCIF_BODSAMPLING_VAL_SHIFT (0) /* Bits 0-5: BOD Value */ +#define BSCIF_BODSAMPLING_VAL_MASK (0x3f << BSCIF_BODSAMPLING_VAL_SHIFT) +#define BSCIF_BODSAMPLING_RANGE (1 << 31) /* Bit 31: BOD Threshold Range (available for BOD18 only */ + +/* Voltage Regulator Configuration Register */ + +#define BSCIF_VREGCR_DIS (1 << 0) /* Bit 0: Voltage Regulator disable */ +#define BSCIF_VREGCR_SSG (1 << 8) /* Bit 8: Spread Spectrum Generator Enable */ +#define BSCIF_VREGCR_SSW (1 << 9) /* Bit 9: Stop Switching */ +#define BSCIF_VREGCR_SSWEVT (1 << 10) /* Bit 10: Stop Switching On Event Enable */ +#define BSCIF_VREGCR_SFV (1 << 31) /* Bit 31: Store Final Value */ + +/* 1MHz RC Clock Configuration Register */ + +#define BSCIF_RC1MCR_FCD (1 << 0) /* Bit 0: Flash Calibration Done */ +#define BSCIF_RC1MCR_CLKOEN (1 << 7) /* Bit 7: 1MHz RC Osc Clock Output Enable */ +#define BSCIF_RC1MCR_CLKCAL_SHIFT (8) /* Bits 8-12: 1MHz RC Osc Calibration */ +#define BSCIF_RC1MCR_CLKCAL_MASK (31 << BSCIF_RC1MCR_CLKCAL_SHIFT) + +/* Bandgap Control Register */ + +#define BSCIF_BGCTRL_ADCISEL_SHIFT (0) /* Bits 0-1: ADC Input Selection */ +#define BSCIF_BGCTRL_ADCISEL_MASK (3 << BSCIF_BGCTRL_ADCISEL_SHIFT) +#define BSCIF_BGCTRL_TSEN (1 << 8) + +/* Bandgap Status Register */ + +#define BSCIF_BGS_BGBUFRDY_SHIFT (0) /* Bits 0-7: Bandgap Buffer Ready */ +#define BSCIF_BGS_BGBUFRDY_MASK (0xff << BSCIF_BGS_BGBUFRDY_SHIFT) +#define BSCIF_BGS_BGRDY (1 << 16) /* Bit 16: Bandgap Voltage Reference Ready */ +#define BSCIF_BGS_LPBGRDY (1 << 17) /* Bit 17: Low Power Bandgap Voltage Reference Ready */ +#define BSCIF_BGS_VREF_SHIFT (18) /* Bits 18-19: Voltage Reference Used by the System */ +#define BSCIF_BGS_VREF_MASK (3 << BSCIF_BGS_VREF_SHIFT) + +/* 0x0078-0x0084 Backup register n=0..3 (32-bit data) */ + +/* Backup Register Interface Version Register */ +/* BGREFIF Version Register */ +/* Voltage Regulator Version Register */ +/* BOD Version Register */ +/* 32kHz RC Oscillator Version Register */ +/* 32 kHz Oscillator Version Register */ +/* BSCIF Version Register */ + +#define BSCIF_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define BSCIF_VERSION_MASK (0xfff << BSCIF_VERSION_VERSION_SHIFT) +#define BSCIF_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define BSCIF_VARIANT_MASK (15 << BSCIF_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_BSCIF_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_flashcalw.h b/arch/arm/src/sam34/chip/sam4l_flashcalw.h new file mode 100644 index 0000000000000000000000000000000000000000..6902578d77b1e85881368d3d9cf8359996efa140 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_flashcalw.h @@ -0,0 +1,379 @@ +/************************************************************************************ + * arch/avr/src/sam34/sam4l_flashcalw.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_flashc.h. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ +/* Relative to SAM_FLASHCALW_BASE */ + +#define SAM_FLASHCALW_FCR_OFFSET 0x0000 /* Flash Control Register */ +#define SAM_FLASHCALW_FCMD_OFFSET 0x0004 /* Flash Command Register */ +#define SAM_FLASHCALW_FSR_OFFSET 0x0008 /* Flash Status Register */ +#define SAM_FLASHCALW_FPR_OFFSET 0x000c /* Flash Parameter Register */ +#define SAM_FLASHCALW_FVR_OFFSET 0x0010 /* Flash Version Register */ +#define SAM_FLASHCALW_FGPFRHI_OFFSET 0x0014 /* Flash General Purpose Fuse Register Hi */ +#define SAM_FLASHCALW_FGPFRLO_OFFSET 0x0018 /* Flash General Purpose Fuse Register Lo */ + +/* Relative to SAM_PICOCACHE_BASE */ + +#define SAM_PICOCACHE_CTRL_OFFSET 0x0008 /* PicoCache Control Register */ +#define SAM_PICOCACHE_SR_OFFSET 0x000c /* PicoCache Status Register */ +#define SAM_PICOCACHE_MAINT0_OFFSET 0x0020 /* PicoCache Maintenance Register 0 */ +#define SAM_PICOCACHE_MAINT1_OFFSET 0x0024 /* PicoCache Maintenance Register 1 */ +#define SAM_PICOCACHE_MCFG_OFFSET 0x0028 /* PicoCache Monitor Configuration Register */ +#define SAM_PICOCACHE_MEN_OFFSET 0x002c /* PicoCache Monitor Enable Register */ +#define SAM_PICOCACHE_MCTRL_OFFSET 0x0030 /* PicoCache Monitor Control Register */ +#define SAM_PICOCACHE_MSR_OFFSET 0x0034 /* PicoCache Monitor Status Register */ +#define SAM_PICOCACHE_PVR_OFFSET 0x00fc /* Version Register */ + +/* Register Addresses ***************************************************************/ + +#define SAM_FLASHCALW_FCR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FCR_OFFSET) +#define SAM_FLASHCALW_FCMD (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FCMD_OFFSET) +#define SAM_FLASHCALW_FSR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FSR_OFFSET) +#define SAM_FLASHCALW_FPR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FPR_OFFSET) +#define SAM_FLASHCALW_FVR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FVR_OFFSET) +#define SAM_FLASHCALW_FGPFRHI (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FGPFRHI_OFFSET) +#define SAM_FLASHCALW_FGPFRLO (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FGPFRLO_OFFSET) + +#define SAM_PICOCACHE_CTRL (SAM_PICOCACHE_BASE+SAM_PICOCACHE_CTRL_OFFSET) +#define SAM_PICOCACHE_SR (SAM_PICOCACHE_BASE+SAM_PICOCACHE_SR_OFFSET) +#define SAM_PICOCACHE_MAINT0 (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MAINT0_OFFSET) +#define SAM_PICOCACHE_MAINT1 (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MAINT1_OFFSET) +#define SAM_PICOCACHE_MCFG (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MCFG_OFFSET) +#define SAM_PICOCACHE_MEN (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MEN_OFFSET) +#define SAM_PICOCACHE_MCTRL (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MCTRL_OFFSET) +#define SAM_PICOCACHE_MSR (SAM_PICOCACHE_BASE+SAM_PICOCACHE_MSR_OFFSET) +#define SAM_PICOCACHE_PVR (SAM_PICOCACHE_BASE+SAM_PICOCACHE_PVR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Flash Control Register */ + +#define FLASHCALW_FCR_FRDY (1 << 0) /* Bit 0: Flash Ready Interrupt Enable */ +#define FLASHCALW_FCR_LOCKE (1 << 2) /* Bit 2: Lock Error Interrupt Enable */ +#define FLASHCALW_FCR_PROGE (1 << 3) /* Bit 3: Programming Error Interrupt Enable */ +#define FLASHCALW_FCR_ECCE (1 << 4) /* Bit 4: ECC Error Interrupt Enable */ +#define FLASHCALW_FCR_FWS (1 << 6) /* Bit 6: Flash Wait State */ +#define FLASHCALW_FCR_WS1OPT (1 << 7) /* Bit 7: Wait State 1 Optimization */ + +/* Flash Command Register */ + +#define FLASHCALW_FCMD_CMD_SHIFT (0) /* Bits 0-5: Command */ +#define FLASHCALW_FCMD_CMD_MASK (0x3f << FLASHCALW_FCMD_CMD_SHIFT) +# define FLASHCALW_FCMD_CMD_NOP (0 << FLASHCALW_FCMD_CMD_SHIFT) /* No operation */ +# define FLASHCALW_FCMD_CMD_WP (1 << FLASHCALW_FCMD_CMD_SHIFT) /* Write Page */ +# define FLASHCALW_FCMD_CMD_EP (2 << FLASHCALW_FCMD_CMD_SHIFT) /* Erase Page */ +# define FLASHCALW_FCMD_CMD_CPB (3 << FLASHCALW_FCMD_CMD_SHIFT) /* Clear Page Buffer */ +# define FLASHCALW_FCMD_CMD_LP (4 << FLASHCALW_FCMD_CMD_SHIFT) /* Lock region containing given Page */ +# define FLASHCALW_FCMD_CMD_UP (5 << FLASHCALW_FCMD_CMD_SHIFT) /* Unlock region containing given Page */ +# define FLASHCALW_FCMD_CMD_EA (6 << FLASHCALW_FCMD_CMD_SHIFT) /* Erase All */ +# define FLASHCALW_FCMD_CMD_WGPB (7 << FLASHCALW_FCMD_CMD_SHIFT) /* Write General-Purpose Fuse Bit */ +# define FLASHCALW_FCMD_CMD_EGPB (8 << FLASHCALW_FCMD_CMD_SHIFT) /* Erase General-Purpose Fuse Bit */ +# define FLASHCALW_FCMD_CMD_SSB (9 << FLASHCALW_FCMD_CMD_SHIFT) /* Set Security Fuses */ +# define FLASHCALW_FCMD_CMD_PGPFB (10 << FLASHCALW_FCMD_CMD_SHIFT) /* Program GP Fuse Byte */ +# define FLASHCALW_FCMD_CMD_EAGPF (11 << FLASHCALW_FCMD_CMD_SHIFT) /* Erase All GPFuses */ +# define FLASHCALW_FCMD_CMD_QPR (12 << FLASHCALW_FCMD_CMD_SHIFT) /* Quick Page Read */ +# define FLASHCALW_FCMD_CMD_WUP (13 << FLASHCALW_FCMD_CMD_SHIFT) /* Write User Page */ +# define FLASHCALW_FCMD_CMD_EUP (14 << FLASHCALW_FCMD_CMD_SHIFT) /* Erase User Page */ +# define FLASHCALW_FCMD_CMD_QPRUP (15 << FLASHCALW_FCMD_CMD_SHIFT) /* Quick Page Read User Page */ +# define FLASHCALW_FCMD_CMD_HSEN (16 << FLASHCALW_FCMD_CMD_SHIFT) /* High Speed Mode Enable */ +# define FLASHCALW_FCMD_CMD_HSDIS (17 << FLASHCALW_FCMD_CMD_SHIFT) /* High Speed Mode Disable */ +#define FLASHCALW_FCMD_PAGEN_SHIFT (8) /* Bits 8-23: Page number */ +#define FLASHCALW_FCMD_PAGEN_MASK (0xffff << FLASHCALW_FCMD_PAGEN_SHIFT) +#define FLASHCALW_FCMD_KEY_SHIFT (14) /* Bits 24-31: Write protection key */ +#define FLASHCALW_FCMD_KEY_MASK (0xff << FLASHCALW_FCMD_KEY_SHIFT) +# define FLASHCALW_FCMD_KEY (0xa5 << FLASHCALW_FCMD_KEY_SHIFT) + +/* Flash Status Register */ + +#define FLASHCALW_FSR_FRDY (1 << 0) /* Bit 0: Flash Ready Status */ +#define FLASHCALW_FSR_LOCKE (1 << 2) /* Bit 2: Lock Error Status */ +#define FLASHCALW_FSR_PROGE (1 << 3) /* Bit 3: Programming Error Status */ +#define FLASHCALW_FSR_SECURITY (1 << 4) /* Bit 4: Security Bit Status */ +#define FLASHCALW_FSR_QPRR (1 << 5) /* Bit 5: Quick Page Read Result */ +#define FLASHCALW_FSR_HSMODE (1 << 6) /* Bit 6: High-Speed Mode */ +#define FLASHCALW_FSR_ECCERR_SHIFT (8) /* Bits 8-0: ECC Error Status */ +#define FLASHCALW_FSR_ECCERR_MASK (3 << FLASHCALW_FSR_ECCERR_SHIFT) +#define FLASHCALW_FSR_LOCK(n) (1 << ((n)+16) +#define FLASHCALW_FSR_LOCK0 (1 << 16) /* Bit 16: Lock Region 0 Lock Status */ +#define FLASHCALW_FSR_LOCK1 (1 << 17) /* Bit 17: Lock Region 1 Lock Status */ +#define FLASHCALW_FSR_LOCK2 (1 << 18) /* Bit 18: Lock Region 2 Lock Status */ +#define FLASHCALW_FSR_LOCK3 (1 << 19) /* Bit 19: Lock Region 3 Lock Status */ +#define FLASHCALW_FSR_LOCK4 (1 << 20) /* Bit 20: Lock Region 4 Lock Status */ +#define FLASHCALW_FSR_LOCK5 (1 << 21) /* Bit 21: Lock Region 5 Lock Status */ +#define FLASHCALW_FSR_LOCK6 (1 << 22) /* Bit 22: Lock Region 6 Lock Status */ +#define FLASHCALW_FSR_LOCK7 (1 << 23) /* Bit 23: Lock Region 7 Lock Status */ +#define FLASHCALW_FSR_LOCK8 (1 << 24) /* Bit 24: Lock Region 8 Lock Status */ +#define FLASHCALW_FSR_LOCK9 (1 << 25) /* Bit 25: Lock Region 9 Lock Status */ +#define FLASHCALW_FSR_LOCK10 (1 << 26) /* Bit 26: Lock Region 10 Lock Status */ +#define FLASHCALW_FSR_LOCK11 (1 << 27) /* Bit 27: Lock Region 11 Lock Status */ +#define FLASHCALW_FSR_LOCK12 (1 << 28) /* Bit 28: Lock Region 12 Lock Status */ +#define FLASHCALW_FSR_LOCK13 (1 << 29) /* Bit 29: Lock Region 13 Lock Status */ +#define FLASHCALW_FSR_LOCK14 (1 << 30) /* Bit 30: Lock Region 14 Lock Status */ +#define FLASHCALW_FSR_LOCK15 (1 << 31) /* Bit 31: Lock Region 15 Lock Status */ + +/* Flash Parameter Register */ + +#define FLASHCALW_FPR_FSZ_SHIFT (0) /* Bits 0-3: Flash Size */ +#define FLASHCALW_FPR_FSZ_MASK (15 << FLASHCALW_FPR_FSZ_SHIFT) +# define FLASHCALW_FPR_FSZ_4KB (0 << FLASHCALW_FPR_FSZ_SHIFT) /* 4 Kbytes */ +# define FLASHCALW_FPR_FSZ_8KB (1 << FLASHCALW_FPR_FSZ_SHIFT) /* 8 Kbytes */ +# define FLASHCALW_FPR_FSZ_16KB (2 << FLASHCALW_FPR_FSZ_SHIFT) /* 16 Kbytes */ +# define FLASHCALW_FPR_FSZ_32KB (3 << FLASHCALW_FPR_FSZ_SHIFT) /* 32 Kbytes */ +# define FLASHCALW_FPR_FSZ_48KB (4 << FLASHCALW_FPR_FSZ_SHIFT) /* 48 Kbytes */ +# define FLASHCALW_FPR_FSZ_64KB (5 << FLASHCALW_FPR_FSZ_SHIFT) /* 64 Kbytes */ +# define FLASHCALW_FPR_FSZ_96KB (6 << FLASHCALW_FPR_FSZ_SHIFT) /* 96 Kbytes */ +# define FLASHCALW_FPR_FSZ_128KB (7 << FLASHCALW_FPR_FSZ_SHIFT) /* 128 Kbytes */ +# define FLASHCALW_FPR_FSZ_192KB (8 << FLASHCALW_FPR_FSZ_SHIFT) /* 192 Kbytes */ +# define FLASHCALW_FPR_FSZ_256KB (9 << FLASHCALW_FPR_FSZ_SHIFT) /* 256 Kbytes */ +# define FLASHCALW_FPR_FSZ_384KB (10 << FLASHCALW_FPR_FSZ_SHIFT) /* 384 Kbytes */ +# define FLASHCALW_FPR_FSZ_512KB (11 << FLASHCALW_FPR_FSZ_SHIFT) /* 512 Kbytes */ +# define FLASHCALW_FPR_FSZ_768KB (12 << FLASHCALW_FPR_FSZ_SHIFT) /* 768 Kbytes */ +# define FLASHCALW_FPR_FSZ_1MB (13 << FLASHCALW_FPR_FSZ_SHIFT) /* 1024 Kbytes */ +# define FLASHCALW_FPR_FSZ_2MB (14 << FLASHCALW_FPR_FSZ_SHIFT) /* 2048 Kbytes */ +#define FLASHCALW_FPR_PSZ_SHIFT (8) /* Bits 8-9: Page Size */ +#define FLASHCALW_FPR_PSZ_MASK (7 << FLASHCALW_FPR_PSZ_SHIFT) +# define FLASHCALW_FPR_PSZ_32KB (0 << FLASHCALW_FPR_PSZ_SHIFT) /* 32 Kbytes */ +# define FLASHCALW_FPR_PSZ_64KB (1 << FLASHCALW_FPR_PSZ_SHIFT) /* 64 Kbytes */ +# define FLASHCALW_FPR_PSZ_128KB (2 << FLASHCALW_FPR_PSZ_SHIFT) /* 128 Kbytes */ +# define FLASHCALW_FPR_PSZ_256KB (3 << FLASHCALW_FPR_PSZ_SHIFT) /* 256 Kbytes */ +# define FLASHCALW_FPR_PSZ_512KGB (4 << FLASHCALW_FPR_PSZ_SHIFT) /* 512 Kbytes */ +# define FLASHCALW_FPR_PSZ_1MB (5 << FLASHCALW_FPR_PSZ_SHIFT) /* 1024 Kbytes */ +# define FLASHCALW_FPR_PSZ_2MB (6 << FLASHCALW_FPR_PSZ_SHIFT) /* 2048 Kbytes */ +# define FLASHCALW_FPR_PSZ_4MB (7 << FLASHCALW_FPR_PSZ_SHIFT) /* 4096 Kbytes */ + +/* Flash Version Register */ + +#define FLASHCALW_FVR_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define FLASHCALW_FVR_VERSION_MASK (0xfff << FLASHCALW_FVR_VERSION_SHIFT) +#define FLASHCALW_FVR_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define FLASHCALW_FVR_VARIANT_MASK (15 << FLASHCALW_FVR_VARIANT_SHIFT) + +/* Flash General Purpose Fuse Register Hi */ + +#define FLASHCALW_FGPFRHI(n) (1 << ((n)-32)) +#define FLASHCALW_FGPFRHI32 (1 << 0) /* Bit 0: General Purpose Fuse 32 */ +#define FLASHCALW_FGPFRHI33 (1 << 1) /* Bit 1: General Purpose Fuse 33 */ +#define FLASHCALW_FGPFRHI34 (1 << 2) /* Bit 2: General Purpose Fuse 34 */ +#define FLASHCALW_FGPFRHI35 (1 << 3) /* Bit 3: General Purpose Fuse 35 */ +#define FLASHCALW_FGPFRHI36 (1 << 4) /* Bit 4: General Purpose Fuse 36 */ +#define FLASHCALW_FGPFRHI37 (1 << 5) /* Bit 5: General Purpose Fuse 37 */ +#define FLASHCALW_FGPFRHI38 (1 << 6) /* Bit 6: General Purpose Fuse 38 */ +#define FLASHCALW_FGPFRHI39 (1 << 7) /* Bit 7: General Purpose Fuse 39 */ +#define FLASHCALW_FGPFRHI40 (1 << 8) /* Bit 8: General Purpose Fuse 40 */ +#define FLASHCALW_FGPFRHI41 (1 << 9) /* Bit 9: General Purpose Fuse 41 */ +#define FLASHCALW_FGPFRHI42 (1 << 10) /* Bit 10: General Purpose Fuse 42 */ +#define FLASHCALW_FGPFRHI43 (1 << 11) /* Bit 11: General Purpose Fuse 43 */ +#define FLASHCALW_FGPFRHI44 (1 << 12) /* Bit 12: General Purpose Fuse 44 */ +#define FLASHCALW_FGPFRHI45 (1 << 13) /* Bit 13: General Purpose Fuse 45 */ +#define FLASHCALW_FGPFRHI46 (1 << 14) /* Bit 14: General Purpose Fuse 46 */ +#define FLASHCALW_FGPFRHI47 (1 << 15) /* Bit 15: General Purpose Fuse 47 */ +#define FLASHCALW_FGPFRHI48 (1 << 16) /* Bit 16: General Purpose Fuse 48 */ +#define FLASHCALW_FGPFRHI49 (1 << 17) /* Bit 17: General Purpose Fuse 49 */ +#define FLASHCALW_FGPFRHI50 (1 << 18) /* Bit 18: General Purpose Fuse 50 */ +#define FLASHCALW_FGPFRHI51 (1 << 19) /* Bit 19: General Purpose Fuse 51 */ +#define FLASHCALW_FGPFRHI52 (1 << 20) /* Bit 20: General Purpose Fuse 52 */ +#define FLASHCALW_FGPFRHI53 (1 << 21) /* Bit 21: General Purpose Fuse 53 */ +#define FLASHCALW_FGPFRHI54 (1 << 22) /* Bit 22: General Purpose Fuse 54 */ +#define FLASHCALW_FGPFRHI55 (1 << 23) /* Bit 23: General Purpose Fuse 55 */ +#define FLASHCALW_FGPFRHI56 (1 << 24) /* Bit 24: General Purpose Fuse 56 */ +#define FLASHCALW_FGPFRHI57 (1 << 25) /* Bit 25: General Purpose Fuse 57 */ +#define FLASHCALW_FGPFRHI58 (1 << 26) /* Bit 26: General Purpose Fuse 58 */ +#define FLASHCALW_FGPFRHI59 (1 << 27) /* Bit 27: General Purpose Fuse 59 */ +#define FLASHCALW_FGPFRHI60 (1 << 28) /* Bit 28: General Purpose Fuse 60 */ +#define FLASHCALW_FGPFRHI61 (1 << 29) /* Bit 29: General Purpose Fuse 61 */ +#define FLASHCALW_FGPFRHI62 (1 << 30) /* Bit 30: General Purpose Fuse 62 */ +#define FLASHCALW_FGPFRHI63 (1 << 31) /* Bit 31: General Purpose Fuse 63 */ + +/* Flash General Purpose Fuse Register Lo */ + +#define FLASHCALW_FGPFRLO(n) (1 << (n)) +#define FLASHCALW_FGPFRLO00 (1 << 0) /* Bit 0: General Purpose Fuse 00 */ +#define FLASHCALW_FGPFRLO01 (1 << 1) /* Bit 1: General Purpose Fuse 01 */ +#define FLASHCALW_FGPFRLO02 (1 << 2) /* Bit 2: General Purpose Fuse 02 */ +#define FLASHCALW_FGPFRLO03 (1 << 3) /* Bit 3: General Purpose Fuse 03 */ +#define FLASHCALW_FGPFRLO04 (1 << 4) /* Bit 4: General Purpose Fuse 04 */ +#define FLASHCALW_FGPFRLO05 (1 << 5) /* Bit 5: General Purpose Fuse 05 */ +#define FLASHCALW_FGPFRLO06 (1 << 6) /* Bit 6: General Purpose Fuse 06 */ +#define FLASHCALW_FGPFRLO07 (1 << 7) /* Bit 7: General Purpose Fuse 07 */ +#define FLASHCALW_FGPFRLO08 (1 << 8) /* Bit 8: General Purpose Fuse 08 */ +#define FLASHCALW_FGPFRLO09 (1 << 9) /* Bit 9: General Purpose Fuse 09 */ +#define FLASHCALW_FGPFRLO10 (1 << 10) /* Bit 10: General Purpose Fuse 10 */ +#define FLASHCALW_FGPFRLO11 (1 << 11) /* Bit 11: General Purpose Fuse 11 */ +#define FLASHCALW_FGPFRLO12 (1 << 12) /* Bit 12: General Purpose Fuse 12 */ +#define FLASHCALW_FGPFRLO13 (1 << 13) /* Bit 13: General Purpose Fuse 13 */ +#define FLASHCALW_FGPFRLO14 (1 << 14) /* Bit 14: General Purpose Fuse 14 */ +#define FLASHCALW_FGPFRLO15 (1 << 15) /* Bit 15: General Purpose Fuse 15 */ +#define FLASHCALW_FGPFRLO16 (1 << 16) /* Bit 16: General Purpose Fuse 16 */ +#define FLASHCALW_FGPFRLO17 (1 << 17) /* Bit 17: General Purpose Fuse 17 */ +#define FLASHCALW_FGPFRLO18 (1 << 18) /* Bit 18: General Purpose Fuse 18 */ +#define FLASHCALW_FGPFRLO19 (1 << 19) /* Bit 19: General Purpose Fuse 19 */ +#define FLASHCALW_FGPFRLO20 (1 << 20) /* Bit 20: General Purpose Fuse 20 */ +#define FLASHCALW_FGPFRLO21 (1 << 21) /* Bit 21: General Purpose Fuse 21 */ +#define FLASHCALW_FGPFRLO22 (1 << 22) /* Bit 22: General Purpose Fuse 22 */ +#define FLASHCALW_FGPFRLO23 (1 << 23) /* Bit 23: General Purpose Fuse 23 */ +#define FLASHCALW_FGPFRLO24 (1 << 24) /* Bit 24: General Purpose Fuse 24 */ +#define FLASHCALW_FGPFRLO25 (1 << 25) /* Bit 25: General Purpose Fuse 25 */ +#define FLASHCALW_FGPFRLO26 (1 << 26) /* Bit 26: General Purpose Fuse 26 */ +#define FLASHCALW_FGPFRLO27 (1 << 27) /* Bit 27: General Purpose Fuse 27 */ +#define FLASHCALW_FGPFRLO28 (1 << 28) /* Bit 28: General Purpose Fuse 28 */ +#define FLASHCALW_FGPFRLO29 (1 << 29) /* Bit 29: General Purpose Fuse 29 */ +#define FLASHCALW_FGPFRLO30 (1 << 30) /* Bit 30: General Purpose Fuse 30 */ +#define FLASHCALW_FGPFRLO31 (1 << 31) /* Bit 31: General Purpose Fuse 31 */ + +/* PicoCache Control Register */ + +#define PICOCACHE_CTRL_CEN (1 << 0) /* Bit 0: Cache Enable */ + +/* PicoCache Status Register */ + +#define PICOCACHE_SR_CSTS (1 << 0) /* Bit 0: Cache Controller Status */ + +/* PicoCache Maintenance Register 0 */ + +#define PICOCACHE_MAINT0_INVALL (1 << 0) /* Bit 0: Cache Controller Invalidate All */ + +/* PicoCache Maintenance Register 1 */ + +#define PICOCACHE_MAINT1_INDEX_SHIFT (4) /* Bits 4-7: Invalidate Index */ +#define PICOCACHE_MAINT1_INDEX_MASK (15 << PICOCACHE_MAINT1_INDEX_SHIFT) + +/* PicoCache Monitor Configuration Register */ + +#define PICOCACHE_MCFG_MODE_SHIFT (0) /* Bits 0-1: Cache Controller Monitor Counter Mode */ +#define PICOCACHE_MCFG_MODE_MASK (3 << PICOCACHE_MCFG_MODE_SHIFT) +# define PICOCACHE_MCFG_MODE_CYCLE (0 << PICOCACHE_MCFG_MODE_SHIFT) /* CYCLE_COUNT cycle counter */ +# define PICOCACHE_MCFG_MODE_IHIT (1 << PICOCACHE_MCFG_MODE_SHIFT) /* IHIT_COUNT instruction hit counter */ +# define PICOCACHE_MCFG_MODE_DHIT (2 << PICOCACHE_MCFG_MODE_SHIFT) /* DHIT_COUNT data hit counter */ + +/* PicoCache Monitor Enable Register */ + +#define PICOCACHE_MEN_MENABLE (1 << 0) /* Bit 0: Monitor Enable */ + +/* PicoCache Monitor Control Register */ + +#define PICOCACHE_MCTRL_SWRST (1 << 0) /* Bit 0: Monitor Software Reset */ + +/* PicoCache Monitor Status Register (32-bit event count) */ + +/* Version Register */ + +#define PICOCACHE_PVR_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define PICOCACHE_PVR_VERSION_MASK (0xfff << PICOCACHE_PVR_FVR_VERSION_SHIFT) +#define PICOCACHE_PVR_MFN_SHIFT (16) /* Bits 16-19: MFN */ +#define PICOCACHE_PVR_MFN_MASK (15 << PICOCACHE_PVR_FVR_MFN_SHIFT) + +/* Flash Command Set ****************************************************************/ + +#define FLASH_CMD_NOP 0 /* No operation */ +#define FLASH_CMD_WP 1 /* Write Page */ +#define FLASH_CMD_EP 2 /* Erase Page */ +#define FLASH_CMD_CPB 3 /* Clear Page Buffer */ +#define FLASH_CMD_LP 4 /* Lock region containing given Page */ +#define FLASH_CMD_UP 5 /* Unlock region containing given Page */ +#define FLASH_CMD_EA 6 /* Erase All */ +#define FLASH_CMD_WGPB 7 /* Write General-Purpose Fuse Bit */ +#define FLASH_CMD_EGPB 8 /* Erase General-Purpose Fuse Bit */ +#define FLASH_CMD_SSB 9 /* Set Security Fuses */ +#define FLASH_CMD_PGPFB 10 /* Program GP Fuse Byte */ +#define FLASH_CMD_EAGPF 11 /* Erase All GPFuses */ +#define FLASH_CMD_QPR 12 /* Quick Page Read */ +#define FLASH_CMD_WUP 13 /* Write User Page */ +#define FLASH_CMD_EUP 14 /* Erase User Page */ +#define FLASH_CMD_QPRUP 15 /* Quick Page Read User Page */ +#define FLASH_CMD_HSEN 16 /* High Speed Mode Enable */ +#define FLASH_CMD_HSDIS 17 /* High Speed Mode Disable */ + +/* Maximum CPU frequency for 0 and 1 FLASH wait states (FWS) in various modes + * (Table 42-30 in the big data sheet). + * + * ------- ------------------- ---------- ---------- + * Power Flash Read Mode Flash Maximum + * Sclaing Wait Operating + * Mode HSEN HSDIS FASTWKUP States Frequency + * ------- ---- ----- -------- ---------- ---------- + * PS0 X X 1 12MHz + * " " X 0 18MHz + * " " X 1 36MHz + * PS1 X X 1 12MHz + * " " X 0 8MHz + * " " X 1 12MHz + * PS2 X 0 24Mhz + * " " X 1 48MHz + * ------- ---- ----- -------- ---------- ---------- + */ + +#define FLASH_MAXFREQ_PS0_HSDIS_FASTWKUP_FWS1 (12000000ul) +#define FLASH_MAXFREQ_PS0_HSDIS_FWS0 (18000000ul) +#define FLASH_MAXFREQ_PS0_HSDIS_FWS1 (36000000ul) + +#define FLASH_MAXFREQ_PS1_HSDIS_FASTWKUP_FWS1 (12000000ul) +#define FLASH_MAXFREQ_PS1_HSDIS_FWS0 (8000000ul) +#define FLASH_MAXFREQ_PS1_HSDIS_FWS1 (12000000ul) + +#define FLASH_MAXFREQ_PS2_HSEN_FWS0 (24000000ul) +#define FLASH_MAXFREQ_PS2_HSEN_FWS1 (48000000ul) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H */ + diff --git a/arch/arm/src/sam34/chip/sam4l_gpio.h b/arch/arm/src/sam34/chip/sam4l_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..bda888c0ae2361a0ded810ac98937e53cf35e0ca --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_gpio.h @@ -0,0 +1,595 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_GPIO_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_GPIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PIO register offsets *****************************************************************/ + +#define SAM_GPIO_GPER_OFFSET 0x0000 /* GPIO Enable Register Read/Write */ +#define SAM_GPIO_GPERS_OFFSET 0x0004 /* GPIO Enable Register Set */ +#define SAM_GPIO_GPERC_OFFSET 0x0008 /* GPIO Enable Register Clear */ +#define SAM_GPIO_GPERT_OFFSET 0x000c /* GPIO Enable Register Toggle */ + +/* {PMR2, PMR1, PMR0} Selected Peripheral Function + * + * 000 A 100 E + * 001 B 101 F + * 010 C 110 G + * 011 D 111 H + * + * NOTE: Labeling in the data sheet is inconsistent. In the pin multiplexing table, + * It shows GPIO functions A-G with 000 apparently corresponding to the GPIO. In the + * register description, it should A-H with presumably A corresponding to 000. Here + * we adopt the above convention. + */ + +#define SAM_GPIO_PMR0_OFFSET 0x0010 /* Peripheral Mux Register 0 Read/Write */ +#define SAM_GPIO_PMR0S_OFFSET 0x0014 /* Peripheral Mux Register 0 Set */ +#define SAM_GPIO_PMR0C_OFFSET 0x0018 /* Peripheral Mux Register 0 Clear */ +#define SAM_GPIO_PMR0T_OFFSET 0x001c /* Peripheral Mux Register 0 Toggle */ + +#define SAM_GPIO_PMR1_OFFSET 0x0020 /* Peripheral Mux Register 1 Read/Write */ +#define SAM_GPIO_PMR1S_OFFSET 0x0024 /* Peripheral Mux Register 1 Set */ +#define SAM_GPIO_PMR1C_OFFSET 0x0028 /* Peripheral Mux Register 1 Clear */ +#define SAM_GPIO_PMR1T_OFFSET 0x002c /* Peripheral Mux Register 1 Toggle */ + +#define SAM_GPIO_PMR2_OFFSET 0x0030 /* Peripheral Mux Register 2 Read/Write */ +#define SAM_GPIO_PMR2S_OFFSET 0x0034 /* Peripheral Mux Register 2 Set */ +#define SAM_GPIO_PMR2C_OFFSET 0x0038 /* Peripheral Mux Register 2 Clear */ +#define SAM_GPIO_PMR2T_OFFSET 0x003c /* Peripheral Mux Register 2 Toggle */ + +#define SAM_GPIO_ODER_OFFSET 0x0040 /* Output Driver Enable Register Read/Write */ +#define SAM_GPIO_ODERS_OFFSET 0x0044 /* Output Driver Enable Register Set */ +#define SAM_GPIO_ODERC_OFFSET 0x0048 /* Output Driver Enable Register Clear */ +#define SAM_GPIO_ODERT_OFFSET 0x004c /* Output Driver Enable Register Toggle */ + +#define SAM_GPIO_OVR_OFFSET 0x0050 /* Output Value Register Read/Write */ +#define SAM_GPIO_OVRS_OFFSET 0x0054 /* Output Value Register Set */ +#define SAM_GPIO_OVRC_OFFSET 0x0058 /* Output Value Register Clear */ +#define SAM_GPIO_OVRT_OFFSET 0x005c /* Output Value Register Toggle */ + +#define SAM_GPIO_PVR_OFFSET 0x0060 /* Pin Value Register Read */ + +/* {PUER, PDER} Selected Function + * + * 00 Disabled + * 01 Pull-down enabled + * 10 Pull-up enabled + * 11 Buskeeper enabled + */ + +#define SAM_GPIO_PUER_OFFSET 0x0070 /* Pull-up Enable Register Read/Write */ +#define SAM_GPIO_PUERS_OFFSET 0x0074 /* Pull-up Enable Register Set */ +#define SAM_GPIO_PUERC_OFFSET 0x0078 /* Pull-up Enable Register Clear */ +#define SAM_GPIO_PUERT_OFFSET 0x007c /* Pull-up Enable Register Toggle */ + +#define SAM_GPIO_PDER_OFFSET 0x0080 /* Pull-down Enable Register Read/Write */ +#define SAM_GPIO_PDERS_OFFSET 0x0084 /* Pull-down Enable Register Set */ +#define SAM_GPIO_PDERC_OFFSET 0x0088 /* Pull-down Enable Register Clear */ +#define SAM_GPIO_PDERT_OFFSET 0x008c /* Pull-down Enable Register Toggle */ + +#define SAM_GPIO_IER_OFFSET 0x0090 /* Interrupt Enable Register Read/Write */ +#define SAM_GPIO_IERS_OFFSET 0x0094 /* Interrupt Enable Register Set */ +#define SAM_GPIO_IERC_OFFSET 0x0098 /* Interrupt Enable Register Clear */ +#define SAM_GPIO_IERT_OFFSET 0x009c /* Interrupt Enable Register Toggle */ + +/* {IMR1, IMR0} Interrupt Mode + * + * 00 Pin Change + * 01 Rising Edge + * 10 Falling Edge + * 11 Reserved + */ + +#define SAM_GPIO_IMR0_OFFSET 0x00a0 /* Interrupt Mode Register 0 Read/Write */ +#define SAM_GPIO_IMR0S_OFFSET 0x00a4 /* Interrupt Mode Register 0 Set */ +#define SAM_GPIO_IMR0C_OFFSET 0x00a8 /* Interrupt Mode Register 0 Clear */ +#define SAM_GPIO_IMR0T_OFFSET 0x00ac /* Interrupt Mode Register 0 Toggle */ + +#define SAM_GPIO_IMR1_OFFSET 0x00b0 /* Interrupt Mode Register 1 Read/Write */ +#define SAM_GPIO_IMR1S_OFFSET 0x00b4 /* Interrupt Mode Register 1 Set */ +#define SAM_GPIO_IMR1C_OFFSET 0x00b8 /* Interrupt Mode Register 1 Clear */ +#define SAM_GPIO_IMR1T_OFFSET 0x00bc /* Interrupt Mode Register 1 Toggle */ + +#define SAM_GPIO_GFER_OFFSET 0x00c0 /* Glitch Filter Enable Register Read/Write */ +#define SAM_GPIO_GFERS_OFFSET 0x00c4 /* Glitch Filter Enable Register Set */ +#define SAM_GPIO_GFERC_OFFSET 0x00c8 /* Glitch Filter Enable Register Clear */ +#define SAM_GPIO_GFERT_OFFSET 0x00cc /* Glitch Filter Enable Register Toggle */ + +#define SAM_GPIO_IFR_OFFSET 0x00d0 /* Interrupt Flag Register 0 Read */ +#define SAM_GPIO_IFRC_OFFSET 0x00d8 /* Interrupt Flag Register 0 Clear */ + +/* {ODCR1, ODCR0} Output drive strength + * + * 00 Lowest drive strength + * 01 ... + * 10 ... + * 11 Highest drive strength + */ + +#define SAM_GPIO_ODCR0_OFFSET 0x0100 /* Output Driving Capability Register 0 Read/Write */ +#define SAM_GPIO_ODCR0S_OFFSET 0x0104 /* Output Driving Capability Register 0 Set */ +#define SAM_GPIO_ODCR0C_OFFSET 0x0108 /* Output Driving Capability Register 0 Clear */ +#define SAM_GPIO_ODCR0T_OFFSET 0x010c /* Output Driving Capability Register 0 Toggle */ + +#define SAM_GPIO_ODCR1_OFFSET 0x0110 /* Output Driving Capability Register 1 Read */ +#define SAM_GPIO_ODCR1S_OFFSET 0x0114 /* Output Driving Capability Register 1 Set */ +#define SAM_GPIO_ODCR1C_OFFSET 0x0118 /* Output Driving Capability Register 1 Clear */ +#define SAM_GPIO_ODCR1T_OFFSET 0x011c /* Output Driving Capability Register 1 Toggle */ + +#define SAM_GPIO_OSRR0_OFFSET 0x0130 /* Output Slew Rate Register 0 Read */ +#define SAM_GPIO_OSRR0S_OFFSET 0x0134 /* Output Slew Rate Register 0 Set */ +#define SAM_GPIO_OSRR0C_OFFSET 0x0138 /* Output Slew Rate Register 0 Clear */ +#define SAM_GPIO_OSRR0T_OFFSET 0x013c /* Output Slew Rate Register 0 Toggle */ + +#define SAM_GPIO_STER_OFFSET 0x0160 /* Schmitt Trigger Enable Register Read */ +#define SAM_GPIO_STERS_OFFSET 0x0164 /* Schmitt Trigger Enable Register Set */ +#define SAM_GPIO_STERC_OFFSET 0x0168 /* Schmitt Trigger Enable Register Clear */ +#define SAM_GPIO_STERT_OFFSET 0x016c /* Schmitt Trigger Enable Register Toggle */ + +#define SAM_GPIO_EVER_OFFSET 0x0180 /* Event Enable Register Read */ +#define SAM_GPIO_EVERS_OFFSET 0x0184 /* Event Enable Register Set */ +#define SAM_GPIO_EVERC_OFFSET 0x0188 /* Event Enable Register Clear */ +#define SAM_GPIO_EVERT_OFFSET 0x018c /* Event Enable Register Toggle */ + +#define SAM_GPIO_PARAMETER_OFFSET 0x01f8 /* Parameter Register Read */ +#define SAM_GPIO_VERSION_OFFSET 0x01fc /* Version Register Read */ + +/* GPIO port offsets and addresses ******************************************************/ + +#define SAM_GPIOA 0 +#define SAM_GPIOB 1 +#define SAM_GPIOC 2 + +#define SAM_GPIO_PORTSIZE 0x200 +#define SAM_GPION_OFFSET(n) ((n) << 9) +#define SAM_GPION_BASE(n) (SAM_GPIO_BASE+SAM_GPION_OFFSET(n)) +#define SAM_GPIOA_BASE SAM_GPION_BASE(SAM_GPIOA) +#define SAM_GPIOB_BASE SAM_GPION_BASE(SAM_GPIOB) +#define SAM_GPIOC_BASE SAM_GPION_BASE(SAM_GPIOC) + +/* GPIO register addresses **************************************************************/ + +#define SAM_GPIO_GPER(n) (SAM_GPION_BASE(n)+SAM_GPIO_GPER_OFFSET) +#define SAM_GPIO_GPERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_GPERS_OFFSET) +#define SAM_GPIO_GPERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_GPERC_OFFSET) +#define SAM_GPIO_GPERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_GPERT_OFFSET) + +#define SAM_GPIO_PMR0(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR0_OFFSET) +#define SAM_GPIO_PMR0S(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR0S_OFFSET) +#define SAM_GPIO_PMR0C(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR0C_OFFSET) +#define SAM_GPIO_PMR0T(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR0T_OFFSET_ + +#define SAM_GPIO_PMR1(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR1_OFFSET) +#define SAM_GPIO_PMR1S(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR1S_OFFSET) +#define SAM_GPIO_PMR1C(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR1C_OFFSET) +#define SAM_GPIO_PMR1T(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR1T_OFFSET) + +#define SAM_GPIO_PMR2(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR2_OFFSET) +#define SAM_GPIO_PMR2S(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR2S_OFFSET) +#define SAM_GPIO_PMR2C(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR2C_OFFSET) +#define SAM_GPIO_PMR2T(n) (SAM_GPION_BASE(n)+SAM_GPIO_PMR2T_OFFSET) + +#define SAM_GPIO_ODER(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODER_OFFSET) +#define SAM_GPIO_ODERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODERS_OFFSET) +#define SAM_GPIO_ODERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODERC_OFFSET) +#define SAM_GPIO_ODERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODERT_OFFSET) + +#define SAM_GPIO_OVR(n) (SAM_GPION_BASE(n)+SAM_GPIO_OVR_OFFSET) +#define SAM_GPIO_OVRS(n) (SAM_GPION_BASE(n)+SAM_GPIO_OVRS_OFFSET) +#define SAM_GPIO_OVRC(n) (SAM_GPION_BASE(n)+SAM_GPIO_OVRC_OFFSET) +#define SAM_GPIO_OVRT(n) (SAM_GPION_BASE(n)+SAM_GPIO_OVRT_OFFSET) + +#define SAM_GPIO_PVR(n) (SAM_GPION_BASE(n)+SAM_GPIO_PVR_OFFSET) + +#define SAM_GPIO_PUER(n) (SAM_GPION_BASE(n)+SAM_GPIO_PUER_OFFSET) +#define SAM_GPIO_PUERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_PUERS_OFFSET) +#define SAM_GPIO_PUERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_PUERC_OFFSET) +#define SAM_GPIO_PUERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_PUERT_OFFSET) + +#define SAM_GPIO_PDER(n) (SAM_GPION_BASE(n)+SAM_GPIO_PDER_OFFSET) +#define SAM_GPIO_PDERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_PDERS_OFFSET) +#define SAM_GPIO_PDERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_PDERC_OFFSET) +#define SAM_GPIO_PDERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_PDERT_OFFSET) + +#define SAM_GPIO_IER(n) (SAM_GPION_BASE(n)+SAM_GPIO_IER_OFFSET) +#define SAM_GPIO_IERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_IERS_OFFSET) +#define SAM_GPIO_IERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_IERC_OFFSET) +#define SAM_GPIO_IERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_IERT_OFFSET) + +#define SAM_GPIO_IMR0(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR0_OFFSET) +#define SAM_GPIO_IMR0S(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR0S_OFFSET) +#define SAM_GPIO_IMR0C(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR0C_OFFSET) +#define SAM_GPIO_IMR0T(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR0T_OFFSET) + +#define SAM_GPIO_IMR1(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR1_OFFSET) +#define SAM_GPIO_IMR1S(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR1S_OFFSET) +#define SAM_GPIO_IMR1C(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR1C_OFFSET) +#define SAM_GPIO_IMR1T(n) (SAM_GPION_BASE(n)+SAM_GPIO_IMR1T_OFFSET) + +#define SAM_GPIO_GFER(n) (SAM_GPION_BASE(n)+SAM_GPIO_GFER_OFFSET) +#define SAM_GPIO_GFERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_GFERS_OFFSET) +#define SAM_GPIO_GFERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_GFERC_OFFSET) +#define SAM_GPIO_GFERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_GFERT_OFFSET) + +#define SAM_GPIO_IFR(n) (SAM_GPION_BASE(n)+SAM_GPIO_IFR_OFFSET) +#define SAM_GPIO_IFRC(n) (SAM_GPION_BASE(n)+SAM_GPIO_IFRC_OFFSET) + +#define SAM_GPIO_ODCR0(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR0_OFFSET) +#define SAM_GPIO_ODCR0S(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR0S_OFFSET) +#define SAM_GPIO_ODCR0C(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR0C_OFFSET) +#define SAM_GPIO_ODCR0T(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR0T_OFFSET) + +#define SAM_GPIO_ODCR1(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR1_OFFSET) +#define SAM_GPIO_ODCR1S(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR1S_OFFSET) +#define SAM_GPIO_ODCR1C(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR1C_OFFSET) +#define SAM_GPIO_ODCR1T(n) (SAM_GPION_BASE(n)+SAM_GPIO_ODCR1T_OFFSET) + +#define SAM_GPIO_OSRR0(n) (SAM_GPION_BASE(n)+SAM_GPIO_OSRR0_OFFSET) +#define SAM_GPIO_OSRR0S(n) (SAM_GPION_BASE(n)+SAM_GPIO_OSRR0S_OFFSET) +#define SAM_GPIO_OSRR0C(n) (SAM_GPION_BASE(n)+SAM_GPIO_OSRR0C_OFFSET) +#define SAM_GPIO_OSRR0T(n) (SAM_GPION_BASE(n)+SAM_GPIO_OSRR0T_OFFSET) + +#define SAM_GPIO_STER(n) (SAM_GPION_BASE(n)+SAM_GPIO_STER_OFFSET) +#define SAM_GPIO_STERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_STERS_OFFSET) +#define SAM_GPIO_STERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_STERC_OFFSET) +#define SAM_GPIO_STERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_STERT_OFFSET) + +#define SAM_GPIO_EVER(n) (SAM_GPION_BASE(n)+SAM_GPIO_EVER_OFFSET) +#define SAM_GPIO_EVERS(n) (SAM_GPION_BASE(n)+SAM_GPIO_EVERS_OFFSET) +#define SAM_GPIO_EVERC(n) (SAM_GPION_BASE(n)+SAM_GPIO_EVERC_OFFSET) +#define SAM_GPIO_EVERT(n) (SAM_GPION_BASE(n)+SAM_GPIO_EVERT_OFFSET) + +#define SAM_GPIO_PARAMETER(n) (SAM_GPION_BASE(n)+SAM_GPIO_PARAMETER_OFFSET) +#define SAM_GPIO_VERSION (n) (SAM_GPION_BASE(n)+SAM_GPIO_VERSION_OFFSET) + +/* GPIO PORTA register addresses ********************************************************/ + +#define SAM_GPIOA_GPER (SAM_GPIOA_BASE+SAM_GPIO_GPER_OFFSET) +#define SAM_GPIOA_GPERS (SAM_GPIOA_BASE+SAM_GPIO_GPERS_OFFSET) +#define SAM_GPIOA_GPERC (SAM_GPIOA_BASE+SAM_GPIO_GPERC_OFFSET) +#define SAM_GPIOA_GPERT (SAM_GPIOA_BASE+SAM_GPIO_GPERT_OFFSET) + +#define SAM_GPIOA_PMR0 (SAM_GPIOA_BASE+SAM_GPIO_PMR0_OFFSET) +#define SAM_GPIOA_PMR0S (SAM_GPIOA_BASE+SAM_GPIO_PMR0S_OFFSET) +#define SAM_GPIOA_PMR0C (SAM_GPIOA_BASE+SAM_GPIO_PMR0C_OFFSET) +#define SAM_GPIOA_PMR0T (SAM_GPIOA_BASE+SAM_GPIO_PMR0T_OFFSET_ + +#define SAM_GPIOA_PMR1 (SAM_GPIOA_BASE+SAM_GPIO_PMR1_OFFSET) +#define SAM_GPIOA_PMR1S (SAM_GPIOA_BASE+SAM_GPIO_PMR1S_OFFSET) +#define SAM_GPIOA_PMR1C (SAM_GPIOA_BASE+SAM_GPIO_PMR1C_OFFSET) +#define SAM_GPIOA_PMR1T (SAM_GPIOA_BASE+SAM_GPIO_PMR1T_OFFSET) + +#define SAM_GPIOA_PMR2 (SAM_GPIOA_BASE+SAM_GPIO_PMR2_OFFSET) +#define SAM_GPIOA_PMR2S (SAM_GPIOA_BASE+SAM_GPIO_PMR2S_OFFSET) +#define SAM_GPIOA_PMR2C (SAM_GPIOA_BASE+SAM_GPIO_PMR2C_OFFSET) +#define SAM_GPIOA_PMR2T (SAM_GPIOA_BASE+SAM_GPIO_PMR2T_OFFSET) + +#define SAM_GPIOA_ODER (SAM_GPIOA_BASE+SAM_GPIO_ODER_OFFSET) +#define SAM_GPIOA_ODERS (SAM_GPIOA_BASE+SAM_GPIO_ODERS_OFFSET) +#define SAM_GPIOA_ODERC (SAM_GPIOA_BASE+SAM_GPIO_ODERC_OFFSET) +#define SAM_GPIOA_ODERT (SAM_GPIOA_BASE+SAM_GPIO_ODERT_OFFSET) + +#define SAM_GPIOA_OVR (SAM_GPIOA_BASE+SAM_GPIO_OVR_OFFSET) +#define SAM_GPIOA_OVRS (SAM_GPIOA_BASE+SAM_GPIO_OVRS_OFFSET) +#define SAM_GPIOA_OVRC (SAM_GPIOA_BASE+SAM_GPIO_OVRC_OFFSET) +#define SAM_GPIOA_OVRT (SAM_GPIOA_BASE+SAM_GPIO_OVRT_OFFSET) + +#define SAM_GPIOA_PVR (SAM_GPIOA_BASE+SAM_GPIO_PVR_OFFSET) + +#define SAM_GPIOA_PUER (SAM_GPIOA_BASE+SAM_GPIO_PUER_OFFSET) +#define SAM_GPIOA_PUERS (SAM_GPIOA_BASE+SAM_GPIO_PUERS_OFFSET) +#define SAM_GPIOA_PUERC (SAM_GPIOA_BASE+SAM_GPIO_PUERC_OFFSET) +#define SAM_GPIOA_PUERT (SAM_GPIOA_BASE+SAM_GPIO_PUERT_OFFSET) + +#define SAM_GPIOA_PDER (SAM_GPIOA_BASE+SAM_GPIO_PDER_OFFSET) +#define SAM_GPIOA_PDERS (SAM_GPIOA_BASE+SAM_GPIO_PDERS_OFFSET) +#define SAM_GPIOA_PDERC (SAM_GPIOA_BASE+SAM_GPIO_PDERC_OFFSET) +#define SAM_GPIOA_PDERT (SAM_GPIOA_BASE+SAM_GPIO_PDERT_OFFSET) + +#define SAM_GPIOA_IER (SAM_GPIOA_BASE+SAM_GPIO_IER_OFFSET) +#define SAM_GPIOA_IERS (SAM_GPIOA_BASE+SAM_GPIO_IERS_OFFSET) +#define SAM_GPIOA_IERC (SAM_GPIOA_BASE+SAM_GPIO_IERC_OFFSET) +#define SAM_GPIOA_IERT (SAM_GPIOA_BASE+SAM_GPIO_IERT_OFFSET) + +#define SAM_GPIOA_IMR0 (SAM_GPIOA_BASE+SAM_GPIO_IMR0_OFFSET) +#define SAM_GPIOA_IMR0S (SAM_GPIOA_BASE+SAM_GPIO_IMR0S_OFFSET) +#define SAM_GPIOA_IMR0C (SAM_GPIOA_BASE+SAM_GPIO_IMR0C_OFFSET) +#define SAM_GPIOA_IMR0T (SAM_GPIOA_BASE+SAM_GPIO_IMR0T_OFFSET) + +#define SAM_GPIOA_IMR1 (SAM_GPIOA_BASE+SAM_GPIO_IMR1_OFFSET) +#define SAM_GPIOA_IMR1S (SAM_GPIOA_BASE+SAM_GPIO_IMR1S_OFFSET) +#define SAM_GPIOA_IMR1C (SAM_GPIOA_BASE+SAM_GPIO_IMR1C_OFFSET) +#define SAM_GPIOA_IMR1T (SAM_GPIOA_BASE+SAM_GPIO_IMR1T_OFFSET) + +#define SAM_GPIOA_GFER (SAM_GPIOA_BASE+SAM_GPIO_GFER_OFFSET) +#define SAM_GPIOA_GFERS (SAM_GPIOA_BASE+SAM_GPIO_GFERS_OFFSET) +#define SAM_GPIOA_GFERC (SAM_GPIOA_BASE+SAM_GPIO_GFERC_OFFSET) +#define SAM_GPIOA_GFERT (SAM_GPIOA_BASE+SAM_GPIO_GFERT_OFFSET) + +#define SAM_GPIOA_IFR (SAM_GPIOA_BASE+SAM_GPIO_IFR_OFFSET) +#define SAM_GPIOA_IFRC (SAM_GPIOA_BASE+SAM_GPIO_IFRC_OFFSET) + +#define SAM_GPIOA_ODCR0 (SAM_GPIOA_BASE+SAM_GPIO_ODCR0_OFFSET) +#define SAM_GPIOA_ODCR0S (SAM_GPIOA_BASE+SAM_GPIO_ODCR0S_OFFSET) +#define SAM_GPIOA_ODCR0C (SAM_GPIOA_BASE+SAM_GPIO_ODCR0C_OFFSET) +#define SAM_GPIOA_ODCR0T (SAM_GPIOA_BASE+SAM_GPIO_ODCR0T_OFFSET) + +#define SAM_GPIOA_ODCR1 (SAM_GPIOA_BASE+SAM_GPIO_ODCR1_OFFSET) +#define SAM_GPIOA_ODCR1S (SAM_GPIOA_BASE+SAM_GPIO_ODCR1S_OFFSET) +#define SAM_GPIOA_ODCR1C (SAM_GPIOA_BASE+SAM_GPIO_ODCR1C_OFFSET) +#define SAM_GPIOA_ODCR1T (SAM_GPIOA_BASE+SAM_GPIO_ODCR1T_OFFSET) + +#define SAM_GPIOA_OSRR0 (SAM_GPIOA_BASE+SAM_GPIO_OSRR0_OFFSET) +#define SAM_GPIOA_OSRR0S (SAM_GPIOA_BASE+SAM_GPIO_OSRR0S_OFFSET) +#define SAM_GPIOA_OSRR0C (SAM_GPIOA_BASE+SAM_GPIO_OSRR0C_OFFSET) +#define SAM_GPIOA_OSRR0T (SAM_GPIOA_BASE+SAM_GPIO_OSRR0T_OFFSET) + +#define SAM_GPIOA_STER (SAM_GPIOA_BASE+SAM_GPIO_STER_OFFSET) +#define SAM_GPIOA_STERS (SAM_GPIOA_BASE+SAM_GPIO_STERS_OFFSET) +#define SAM_GPIOA_STERC (SAM_GPIOA_BASE+SAM_GPIO_STERC_OFFSET) +#define SAM_GPIOA_STERT (SAM_GPIOA_BASE+SAM_GPIO_STERT_OFFSET) + +#define SAM_GPIOA_EVER (SAM_GPIOA_BASE+SAM_GPIO_EVER_OFFSET) +#define SAM_GPIOA_EVERS (SAM_GPIOA_BASE+SAM_GPIO_EVERS_OFFSET) +#define SAM_GPIOA_EVERC (SAM_GPIOA_BASE+SAM_GPIO_EVERC_OFFSET) +#define SAM_GPIOA_EVERT (SAM_GPIOA_BASE+SAM_GPIO_EVERT_OFFSET) + +#define SAM_GPIOA_PARAMETER (SAM_GPIOA_BASE+SAM_GPIO_PARAMETER_OFFSET) +#define SAM_GPIOA_VERSION (SAM_GPIOA_BASE+SAM_GPIO_VERSION_OFFSET) + +/* GPIO PORTB register addresses ********************************************************/ + +#define SAM_GPIOB_GPER (SAM_GPIOB_BASE+SAM_GPIO_GPER_OFFSET) +#define SAM_GPIOB_GPERS (SAM_GPIOB_BASE+SAM_GPIO_GPERS_OFFSET) +#define SAM_GPIOB_GPERC (SAM_GPIOB_BASE+SAM_GPIO_GPERC_OFFSET) +#define SAM_GPIOB_GPERT (SAM_GPIOB_BASE+SAM_GPIO_GPERT_OFFSET) + +#define SAM_GPIOB_PMR0 (SAM_GPIOB_BASE+SAM_GPIO_PMR0_OFFSET) +#define SAM_GPIOB_PMR0S (SAM_GPIOB_BASE+SAM_GPIO_PMR0S_OFFSET) +#define SAM_GPIOB_PMR0C (SAM_GPIOB_BASE+SAM_GPIO_PMR0C_OFFSET) +#define SAM_GPIOB_PMR0T (SAM_GPIOB_BASE+SAM_GPIO_PMR0T_OFFSET_ + +#define SAM_GPIOB_PMR1 (SAM_GPIOB_BASE+SAM_GPIO_PMR1_OFFSET) +#define SAM_GPIOB_PMR1S (SAM_GPIOB_BASE+SAM_GPIO_PMR1S_OFFSET) +#define SAM_GPIOB_PMR1C (SAM_GPIOB_BASE+SAM_GPIO_PMR1C_OFFSET) +#define SAM_GPIOB_PMR1T (SAM_GPIOB_BASE+SAM_GPIO_PMR1T_OFFSET) + +#define SAM_GPIOB_PMR2 (SAM_GPIOB_BASE+SAM_GPIO_PMR2_OFFSET) +#define SAM_GPIOB_PMR2S (SAM_GPIOB_BASE+SAM_GPIO_PMR2S_OFFSET) +#define SAM_GPIOB_PMR2C (SAM_GPIOB_BASE+SAM_GPIO_PMR2C_OFFSET) +#define SAM_GPIOB_PMR2T (SAM_GPIOB_BASE+SAM_GPIO_PMR2T_OFFSET) + +#define SAM_GPIOB_ODER (SAM_GPIOB_BASE+SAM_GPIO_ODER_OFFSET) +#define SAM_GPIOB_ODERS (SAM_GPIOB_BASE+SAM_GPIO_ODERS_OFFSET) +#define SAM_GPIOB_ODERC (SAM_GPIOB_BASE+SAM_GPIO_ODERC_OFFSET) +#define SAM_GPIOB_ODERT (SAM_GPIOB_BASE+SAM_GPIO_ODERT_OFFSET) + +#define SAM_GPIOB_OVR (SAM_GPIOB_BASE+SAM_GPIO_OVR_OFFSET) +#define SAM_GPIOB_OVRS (SAM_GPIOB_BASE+SAM_GPIO_OVRS_OFFSET) +#define SAM_GPIOB_OVRC (SAM_GPIOB_BASE+SAM_GPIO_OVRC_OFFSET) +#define SAM_GPIOB_OVRT (SAM_GPIOB_BASE+SAM_GPIO_OVRT_OFFSET) + +#define SAM_GPIOB_PVR (SAM_GPIOB_BASE+SAM_GPIO_PVR_OFFSET) + +#define SAM_GPIOB_PUER (SAM_GPIOB_BASE+SAM_GPIO_PUER_OFFSET) +#define SAM_GPIOB_PUERS (SAM_GPIOB_BASE+SAM_GPIO_PUERS_OFFSET) +#define SAM_GPIOB_PUERC (SAM_GPIOB_BASE+SAM_GPIO_PUERC_OFFSET) +#define SAM_GPIOB_PUERT (SAM_GPIOB_BASE+SAM_GPIO_PUERT_OFFSET) + +#define SAM_GPIOB_PDER (SAM_GPIOB_BASE+SAM_GPIO_PDER_OFFSET) +#define SAM_GPIOB_PDERS (SAM_GPIOB_BASE+SAM_GPIO_PDERS_OFFSET) +#define SAM_GPIOB_PDERC (SAM_GPIOB_BASE+SAM_GPIO_PDERC_OFFSET) +#define SAM_GPIOB_PDERT (SAM_GPIOB_BASE+SAM_GPIO_PDERT_OFFSET) + +#define SAM_GPIOB_IER (SAM_GPIOB_BASE+SAM_GPIO_IER_OFFSET) +#define SAM_GPIOB_IERS (SAM_GPIOB_BASE+SAM_GPIO_IERS_OFFSET) +#define SAM_GPIOB_IERC (SAM_GPIOB_BASE+SAM_GPIO_IERC_OFFSET) +#define SAM_GPIOB_IERT (SAM_GPIOB_BASE+SAM_GPIO_IERT_OFFSET) + +#define SAM_GPIOB_IMR0 (SAM_GPIOB_BASE+SAM_GPIO_IMR0_OFFSET) +#define SAM_GPIOB_IMR0S (SAM_GPIOB_BASE+SAM_GPIO_IMR0S_OFFSET) +#define SAM_GPIOB_IMR0C (SAM_GPIOB_BASE+SAM_GPIO_IMR0C_OFFSET) +#define SAM_GPIOB_IMR0T (SAM_GPIOB_BASE+SAM_GPIO_IMR0T_OFFSET) + +#define SAM_GPIOB_IMR1 (SAM_GPIOB_BASE+SAM_GPIO_IMR1_OFFSET) +#define SAM_GPIOB_IMR1S (SAM_GPIOB_BASE+SAM_GPIO_IMR1S_OFFSET) +#define SAM_GPIOB_IMR1C (SAM_GPIOB_BASE+SAM_GPIO_IMR1C_OFFSET) +#define SAM_GPIOB_IMR1T (SAM_GPIOB_BASE+SAM_GPIO_IMR1T_OFFSET) + +#define SAM_GPIOB_GFER (SAM_GPIOB_BASE+SAM_GPIO_GFER_OFFSET) +#define SAM_GPIOB_GFERS (SAM_GPIOB_BASE+SAM_GPIO_GFERS_OFFSET) +#define SAM_GPIOB_GFERC (SAM_GPIOB_BASE+SAM_GPIO_GFERC_OFFSET) +#define SAM_GPIOB_GFERT (SAM_GPIOB_BASE+SAM_GPIO_GFERT_OFFSET) + +#define SAM_GPIOB_IFR (SAM_GPIOB_BASE+SAM_GPIO_IFR_OFFSET) +#define SAM_GPIOB_IFRC (SAM_GPIOB_BASE+SAM_GPIO_IFRC_OFFSET) + +#define SAM_GPIOB_ODCR0 (SAM_GPIOB_BASE+SAM_GPIO_ODCR0_OFFSET) +#define SAM_GPIOB_ODCR0S (SAM_GPIOB_BASE+SAM_GPIO_ODCR0S_OFFSET) +#define SAM_GPIOB_ODCR0C (SAM_GPIOB_BASE+SAM_GPIO_ODCR0C_OFFSET) +#define SAM_GPIOB_ODCR0T (SAM_GPIOB_BASE+SAM_GPIO_ODCR0T_OFFSET) + +#define SAM_GPIOB_ODCR1 (SAM_GPIOB_BASE+SAM_GPIO_ODCR1_OFFSET) +#define SAM_GPIOB_ODCR1S (SAM_GPIOB_BASE+SAM_GPIO_ODCR1S_OFFSET) +#define SAM_GPIOB_ODCR1C (SAM_GPIOB_BASE+SAM_GPIO_ODCR1C_OFFSET) +#define SAM_GPIOB_ODCR1T (SAM_GPIOB_BASE+SAM_GPIO_ODCR1T_OFFSET) + +#define SAM_GPIOB_OSRR0 (SAM_GPIOB_BASE+SAM_GPIO_OSRR0_OFFSET) +#define SAM_GPIOB_OSRR0S (SAM_GPIOB_BASE+SAM_GPIO_OSRR0S_OFFSET) +#define SAM_GPIOB_OSRR0C (SAM_GPIOB_BASE+SAM_GPIO_OSRR0C_OFFSET) +#define SAM_GPIOB_OSRR0T (SAM_GPIOB_BASE+SAM_GPIO_OSRR0T_OFFSET) + +#define SAM_GPIOB_STER (SAM_GPIOB_BASE+SAM_GPIO_STER_OFFSET) +#define SAM_GPIOB_STERS (SAM_GPIOB_BASE+SAM_GPIO_STERS_OFFSET) +#define SAM_GPIOB_STERC (SAM_GPIOB_BASE+SAM_GPIO_STERC_OFFSET) +#define SAM_GPIOB_STERT (SAM_GPIOB_BASE+SAM_GPIO_STERT_OFFSET) + +#define SAM_GPIOB_EVER (SAM_GPIOB_BASE+SAM_GPIO_EVER_OFFSET) +#define SAM_GPIOB_EVERS (SAM_GPIOB_BASE+SAM_GPIO_EVERS_OFFSET) +#define SAM_GPIOB_EVERC (SAM_GPIOB_BASE+SAM_GPIO_EVERC_OFFSET) +#define SAM_GPIOB_EVERT (SAM_GPIOB_BASE+SAM_GPIO_EVERT_OFFSET) + +#define SAM_GPIOB_PARAMETER (SAM_GPIOB_BASE+SAM_GPIO_PARAMETER_OFFSET) +#define SAM_GPIOB_VERSION (SAM_GPIOB_BASE+SAM_GPIO_VERSION_OFFSET) + +/* GPIO PORTC register addresses ********************************************************/ + +#define SAM_GPIOC_GPER (SAM_GPIOC_BASE+SAM_GPIO_GPER_OFFSET) +#define SAM_GPIOC_GPERS (SAM_GPIOC_BASE+SAM_GPIO_GPERS_OFFSET) +#define SAM_GPIOC_GPERC (SAM_GPIOC_BASE+SAM_GPIO_GPERC_OFFSET) +#define SAM_GPIOC_GPERT (SAM_GPIOC_BASE+SAM_GPIO_GPERT_OFFSET) + +#define SAM_GPIOC_PMR0 (SAM_GPIOC_BASE+SAM_GPIO_PMR0_OFFSET) +#define SAM_GPIOC_PMR0S (SAM_GPIOC_BASE+SAM_GPIO_PMR0S_OFFSET) +#define SAM_GPIOC_PMR0C (SAM_GPIOC_BASE+SAM_GPIO_PMR0C_OFFSET) +#define SAM_GPIOC_PMR0T (SAM_GPIOC_BASE+SAM_GPIO_PMR0T_OFFSET_ + +#define SAM_GPIOC_PMR1 (SAM_GPIOC_BASE+SAM_GPIO_PMR1_OFFSET) +#define SAM_GPIOC_PMR1S (SAM_GPIOC_BASE+SAM_GPIO_PMR1S_OFFSET) +#define SAM_GPIOC_PMR1C (SAM_GPIOC_BASE+SAM_GPIO_PMR1C_OFFSET) +#define SAM_GPIOC_PMR1T (SAM_GPIOC_BASE+SAM_GPIO_PMR1T_OFFSET) + +#define SAM_GPIOC_PMR2 (SAM_GPIOC_BASE+SAM_GPIO_PMR2_OFFSET) +#define SAM_GPIOC_PMR2S (SAM_GPIOC_BASE+SAM_GPIO_PMR2S_OFFSET) +#define SAM_GPIOC_PMR2C (SAM_GPIOC_BASE+SAM_GPIO_PMR2C_OFFSET) +#define SAM_GPIOC_PMR2T (SAM_GPIOC_BASE+SAM_GPIO_PMR2T_OFFSET) + +#define SAM_GPIOC_ODER (SAM_GPIOC_BASE+SAM_GPIO_ODER_OFFSET) +#define SAM_GPIOC_ODERS (SAM_GPIOC_BASE+SAM_GPIO_ODERS_OFFSET) +#define SAM_GPIOC_ODERC (SAM_GPIOC_BASE+SAM_GPIO_ODERC_OFFSET) +#define SAM_GPIOC_ODERT (SAM_GPIOC_BASE+SAM_GPIO_ODERT_OFFSET) + +#define SAM_GPIOC_OVR (SAM_GPIOC_BASE+SAM_GPIO_OVR_OFFSET) +#define SAM_GPIOC_OVRS (SAM_GPIOC_BASE+SAM_GPIO_OVRS_OFFSET) +#define SAM_GPIOC_OVRC (SAM_GPIOC_BASE+SAM_GPIO_OVRC_OFFSET) +#define SAM_GPIOC_OVRT (SAM_GPIOC_BASE+SAM_GPIO_OVRT_OFFSET) + +#define SAM_GPIOC_PVR (SAM_GPIOC_BASE+SAM_GPIO_PVR_OFFSET) + +#define SAM_GPIOC_PUER (SAM_GPIOC_BASE+SAM_GPIO_PUER_OFFSET) +#define SAM_GPIOC_PUERS (SAM_GPIOC_BASE+SAM_GPIO_PUERS_OFFSET) +#define SAM_GPIOC_PUERC (SAM_GPIOC_BASE+SAM_GPIO_PUERC_OFFSET) +#define SAM_GPIOC_PUERT (SAM_GPIOC_BASE+SAM_GPIO_PUERT_OFFSET) + +#define SAM_GPIOC_PDER (SAM_GPIOC_BASE+SAM_GPIO_PDER_OFFSET) +#define SAM_GPIOC_PDERS (SAM_GPIOC_BASE+SAM_GPIO_PDERS_OFFSET) +#define SAM_GPIOC_PDERC (SAM_GPIOC_BASE+SAM_GPIO_PDERC_OFFSET) +#define SAM_GPIOC_PDERT (SAM_GPIOC_BASE+SAM_GPIO_PDERT_OFFSET) + +#define SAM_GPIOC_IER (SAM_GPIOC_BASE+SAM_GPIO_IER_OFFSET) +#define SAM_GPIOC_IERS (SAM_GPIOC_BASE+SAM_GPIO_IERS_OFFSET) +#define SAM_GPIOC_IERC (SAM_GPIOC_BASE+SAM_GPIO_IERC_OFFSET) +#define SAM_GPIOC_IERT (SAM_GPIOC_BASE+SAM_GPIO_IERT_OFFSET) + +#define SAM_GPIOC_IMR0 (SAM_GPIOC_BASE+SAM_GPIO_IMR0_OFFSET) +#define SAM_GPIOC_IMR0S (SAM_GPIOC_BASE+SAM_GPIO_IMR0S_OFFSET) +#define SAM_GPIOC_IMR0C (SAM_GPIOC_BASE+SAM_GPIO_IMR0C_OFFSET) +#define SAM_GPIOC_IMR0T (SAM_GPIOC_BASE+SAM_GPIO_IMR0T_OFFSET) + +#define SAM_GPIOC_IMR1 (SAM_GPIOC_BASE+SAM_GPIO_IMR1_OFFSET) +#define SAM_GPIOC_IMR1S (SAM_GPIOC_BASE+SAM_GPIO_IMR1S_OFFSET) +#define SAM_GPIOC_IMR1C (SAM_GPIOC_BASE+SAM_GPIO_IMR1C_OFFSET) +#define SAM_GPIOC_IMR1T (SAM_GPIOC_BASE+SAM_GPIO_IMR1T_OFFSET) + +#define SAM_GPIOC_GFER (SAM_GPIOC_BASE+SAM_GPIO_GFER_OFFSET) +#define SAM_GPIOC_GFERS (SAM_GPIOC_BASE+SAM_GPIO_GFERS_OFFSET) +#define SAM_GPIOC_GFERC (SAM_GPIOC_BASE+SAM_GPIO_GFERC_OFFSET) +#define SAM_GPIOC_GFERT (SAM_GPIOC_BASE+SAM_GPIO_GFERT_OFFSET) + +#define SAM_GPIOC_IFR (SAM_GPIOC_BASE+SAM_GPIO_IFR_OFFSET) +#define SAM_GPIOC_IFRC (SAM_GPIOC_BASE+SAM_GPIO_IFRC_OFFSET) + +#define SAM_GPIOC_ODCR0 (SAM_GPIOC_BASE+SAM_GPIO_ODCR0_OFFSET) +#define SAM_GPIOC_ODCR0S (SAM_GPIOC_BASE+SAM_GPIO_ODCR0S_OFFSET) +#define SAM_GPIOC_ODCR0C (SAM_GPIOC_BASE+SAM_GPIO_ODCR0C_OFFSET) +#define SAM_GPIOC_ODCR0T (SAM_GPIOC_BASE+SAM_GPIO_ODCR0T_OFFSET) + +#define SAM_GPIOC_ODCR1 (SAM_GPIOC_BASE+SAM_GPIO_ODCR1_OFFSET) +#define SAM_GPIOC_ODCR1S (SAM_GPIOC_BASE+SAM_GPIO_ODCR1S_OFFSET) +#define SAM_GPIOC_ODCR1C (SAM_GPIOC_BASE+SAM_GPIO_ODCR1C_OFFSET) +#define SAM_GPIOC_ODCR1T (SAM_GPIOC_BASE+SAM_GPIO_ODCR1T_OFFSET) + +#define SAM_GPIOC_OSRR0 (SAM_GPIOC_BASE+SAM_GPIO_OSRR0_OFFSET) +#define SAM_GPIOC_OSRR0S (SAM_GPIOC_BASE+SAM_GPIO_OSRR0S_OFFSET) +#define SAM_GPIOC_OSRR0C (SAM_GPIOC_BASE+SAM_GPIO_OSRR0C_OFFSET) +#define SAM_GPIOC_OSRR0T (SAM_GPIOC_BASE+SAM_GPIO_OSRR0T_OFFSET) + +#define SAM_GPIOC_STER (SAM_GPIOC_BASE+SAM_GPIO_STER_OFFSET) +#define SAM_GPIOC_STERS (SAM_GPIOC_BASE+SAM_GPIO_STERS_OFFSET) +#define SAM_GPIOC_STERC (SAM_GPIOC_BASE+SAM_GPIO_STERC_OFFSET) +#define SAM_GPIOC_STERT (SAM_GPIOC_BASE+SAM_GPIO_STERT_OFFSET) + +#define SAM_GPIOC_EVER (SAM_GPIOC_BASE+SAM_GPIO_EVER_OFFSET) +#define SAM_GPIOC_EVERS (SAM_GPIOC_BASE+SAM_GPIO_EVERS_OFFSET) +#define SAM_GPIOC_EVERC (SAM_GPIOC_BASE+SAM_GPIO_EVERC_OFFSET) +#define SAM_GPIOC_EVERT (SAM_GPIOC_BASE+SAM_GPIO_EVERT_OFFSET) + +#define SAM_GPIOC_PARAMETER (SAM_GPIOC_BASE+SAM_GPIO_PARAMETER_OFFSET) +#define SAM_GPIOC_VERSION (SAM_GPIOC_BASE+SAM_GPIO_VERSION_OFFSET) + +/* GPIO register bit definitions ********************************************************/ + +/* Common bit definitions for all GPIO registers */ + +#define PIN(n) (1 << (n)) /* Bit n: PIO n */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_GPIO_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_lcdca.h b/arch/arm/src/sam34/chip/sam4l_lcdca.h new file mode 100644 index 0000000000000000000000000000000000000000..7255ecda18ef2d28e392a7d7afb3ca365cb47c7f --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_lcdca.h @@ -0,0 +1,384 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_lcdca.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_LCDCA_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_LCDCA_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* LCDCA register offsets ************************************************************/ + +#define SAM_LCDCA_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_LCDCA_CFG_OFFSET 0x0004 /* Configuration Register */ +#define SAM_LCDCA_TIM_OFFSET 0x0008 /* Timing Register */ +#define SAM_LCDCA_SR_OFFSET 0x000c /* Status Register */ +#define SAM_LCDCA_SCR_OFFSET 0x0010 /* Status Clear Register */ + +#define SAM_LCDCA_DRL_OFFSET(n) (0x0014+((n)<<3)) +#define SAM_LCDCA_DRH_OFFSET(n) (0x0018+((n)<<3)) +#define SAM_LCDCA_DRL0_OFFSET 0x0014 /* Data Register Low 0 */ +#define SAM_LCDCA_DRH0_OFFSET 0x0018 /* Data Register High 0 */ +#define SAM_LCDCA_DRL1_OFFSET 0x001c /* Data Register Low 1 */ +#define SAM_LCDCA_DRH1_OFFSET 0x0020 /* Data Register High 1 */ +#define SAM_LCDCA_DRL2_OFFSET 0x0024 /* Data Register Low 2 */ +#define SAM_LCDCA_DRH2_OFFSET 0x0028 /* Data Register High 2 */ +#define SAM_LCDCA_DRL3_OFFSET 0x002c /* Data Register Low 3 */ +#define SAM_LCDCA_DRH3_OFFSET 0x0030 /* Data Register High 3 */ + +#define SAM_LCDCA_IADR_OFFSET 0x0034 /* Indirect Access Data Register */ +#define SAM_LCDCA_BCFG_OFFSET 0x0038 /* Blink Configuration Register */ +#define SAM_LCDCA_CSRCFG_OFFSET 0x003c /* Circular Shift Register Configuration */ +#define SAM_LCDCA_CMCFG_OFFSET 0x0040 /* Character Mapping Configuration Register */ +#define SAM_LCDCA_CMDR_OFFSET 0x0044 /* Character Mapping Data Register */ +#define SAM_LCDCA_ACMCFG_OFFSET 0x0048 /* Automated Character Mapping Configuration Register */ +#define SAM_LCDCA_ACMDR_OFFSET 0x004c /* Automated Character Mapping Data Register */ +#define SAM_LCDCA_ABMCFG_OFFSET 0x0050 /* Automated Bit Mapping Configuration Register */ +#define SAM_LCDCA_ABMDR_OFFSET 0x0054 /* Automated Bit Mapping Data Register */ +#define SAM_LCDCA_IER_OFFSET 0x0058 /* Interrupt Enable Register */ +#define SAM_LCDCA_IDR_OFFSET 0x005c /* Interrupt Disable Register */ +#define SAM_LCDCA_IMR_OFFSET 0x0060 /* Interrupt Mask Register */ +#define SAM_LCDCA_VERSION_OFFSET 0x0064 /* Version Register */ + +/* LCDCA register addresses **********************************************************/ + +#define SAM_LCDCA_CR (SAM_LCDCA_BASE+SAM_LCDCA_CR_OFFSET) +#define SAM_LCDCA_CFG (SAM_LCDCA_BASE+SAM_LCDCA_CFG_OFFSET) +#define SAM_LCDCA_TIM (SAM_LCDCA_BASE+SAM_LCDCA_TIM_OFFSET) +#define SAM_LCDCA_SR (SAM_LCDCA_BASE+SAM_LCDCA_SR_OFFSET) +#define SAM_LCDCA_SCR (SAM_LCDCA_BASE+SAM_LCDCA_SCR_OFFSET) + +#define SAM_LCDCA_DRL(n) (SAM_LCDCA_BASE+SAM_LCDCA_DRL_OFFSET(n)) +#define SAM_LCDCA_DRH(n) (SAM_LCDCA_BASE+SAM_LCDCA_DRH_OFFSET(n)) +#define SAM_LCDCA_DRL0 (SAM_LCDCA_BASE+SAM_LCDCA_DRL0_OFFSET) +#define SAM_LCDCA_DRH0 (SAM_LCDCA_BASE+SAM_LCDCA_DRH0_OFFSET) +#define SAM_LCDCA_DRL1 (SAM_LCDCA_BASE+SAM_LCDCA_DRL1_OFFSET) +#define SAM_LCDCA_DRH1 (SAM_LCDCA_BASE+SAM_LCDCA_DRH1_OFFSET) +#define SAM_LCDCA_DRL2 (SAM_LCDCA_BASE+SAM_LCDCA_DRL2_OFFSET) +#define SAM_LCDCA_DRH2 (SAM_LCDCA_BASE+SAM_LCDCA_DRH2_OFFSET) +#define SAM_LCDCA_DRL3 (SAM_LCDCA_BASE+SAM_LCDCA_DRL3_OFFSET) +#define SAM_LCDCA_DRH3 (SAM_LCDCA_BASE+SAM_LCDCA_DRH3_OFFSET) + +#define SAM_LCDCA_IADR (SAM_LCDCA_BASE+SAM_LCDCA_IADR_OFFSET) +#define SAM_LCDCA_BCFG (SAM_LCDCA_BASE+SAM_LCDCA_BCFG_OFFSET) +#define SAM_LCDCA_CSRCFG (SAM_LCDCA_BASE+SAM_LCDCA_CSRCFG_OFFSET) +#define SAM_LCDCA_CMCFG (SAM_LCDCA_BASE+SAM_LCDCA_CMCFG_OFFSET) +#define SAM_LCDCA_CMDR (SAM_LCDCA_BASE+SAM_LCDCA_CMDR_OFFSET) +#define SAM_LCDCA_ACMCFG (SAM_LCDCA_BASE+SAM_LCDCA_ACMCFG_OFFSET) +#define SAM_LCDCA_ACMDR (SAM_LCDCA_BASE+SAM_LCDCA_ACMDR_OFFSET) +#define SAM_LCDCA_ABMCFG (SAM_LCDCA_BASE+SAM_LCDCA_ABMCFG_OFFSET) +#define SAM_LCDCA_ABMDR (SAM_LCDCA_BASE+SAM_LCDCA_ABMDR_OFFSET) +#define SAM_LCDCA_IER (SAM_LCDCA_BASE+SAM_LCDCA_IER_OFFSET) +#define SAM_LCDCA_IDR (SAM_LCDCA_BASE+SAM_LCDCA_IDR_OFFSET) +#define SAM_LCDCA_IMR (SAM_LCDCA_BASE+SAM_LCDCA_IMR_OFFSET) +#define SAM_LCDCA_VERSION (SAM_LCDCA_BASE+SAM_LCDCA_VERSION_OFFSET) + +/* LCDCA register bit definitions ****************************************************/ + +/* Control Register */ + +#define LCDCA_CR_DIS (1 << 0) /* Bit 0: Disable */ +#define LCDCA_CR_EN (1 << 1) /* Bit 1: Enable */ +#define LCDCA_CR_FC0DIS (1 << 2) /* Bit 2: Frame Counter 0 Disable */ +#define LCDCA_CR_FC0EN (1 << 3) /* Bit 3: Frame Counter 0 Enable */ +#define LCDCA_CR_FC1DIS (1 << 4) /* Bit 4: Frame Counter 1 Disable */ +#define LCDCA_CR_FC1EN (1 << 5) /* Bit 5: Frame Counter 1 Enable */ +#define LCDCA_CR_FC2DIS (1 << 6) /* Bit 6: Frame Counter 2 Disable */ +#define LCDCA_CR_FC2EN (1 << 7) /* Bit 7: Frame Counter 2 Enable */ +#define LCDCA_CR_CDM (1 << 8) /* Bit 8: Clear Display Memory */ +#define LCDCA_CR_WDIS (1 << 9) /* Bit 9: Wake up Disable */ +#define LCDCA_CR_WEN (1 << 10) /* Bit 10: Wake up Enable */ +#define LCDCA_CR_BSTART (1 << 11) /* Bit 11: Blinking Start */ +#define LCDCA_CR_BSTOP (1 << 12) /* Bit 12: Blinking Stop */ +#define LCDCA_CR_CSTART (1 << 13) /* Bit 13: Circular Shift Start */ +#define LCDCA_CR_CSTOP (1 << 14) /* Bit 13: Circular Shift Stop */ + +/* Configuration Register */ + +#define LCDCA_CFG_XBIAS (1 << 0) /* Bit 0: External Bias Generation */ +#define LCDCA_CFG_WMOD (1 << 1) /* Bit 1: Waveform Mode */ +#define LCDCA_CFG_BLANK (1 << 2) /* Bit 2: Blank LCD */ +#define LCDCA_CFG_LOCK (1 << 3) /* Bit 3: Lock */ +#define LCDCA_CFG_DUTY_SHIFT (8) /* Bits 8-9: Duty Select */ +#define LCDCA_CFG_DUTY_MASK (3 << LCDCA_CFG_DUTY_SHIFT) +# define LCDCA_CFG_DUTY_1TO4 (0 << LCDCA_CFG_DUTY_SHIFT) /* 1/4, 1/3, COM[0:3] */ +# define LCDCA_CFG_DUTY_STATIC (1 << LCDCA_CFG_DUTY_SHIFT) /* Static, Static, COM0 */ +# define LCDCA_CFG_DUTY_1TO2 (2 << LCDCA_CFG_DUTY_SHIFT) /* 1/2, 1/3, COM[0:1] */ +# define LCDCA_CFG_DUTY_1TO3 (3 << LCDCA_CFG_DUTY_SHIFT) /* 1/3, 1/3, COM[0:2] */ +#define LCDCA_CFG_FCST_SHIFT (16) /* Bits 16-21: Fine Contrast */ +#define LCDCA_CFG_FCST_MASK (63 << LCDCA_CFG_FCST_SHIFT) +# define LCDCA_CFG_FCST(n) (((uint32_t)(n) & 63) << LCDCA_CFG_FCST_SHIFT) /* n = -32..31 */ +#define LCDCA_CFG_NSU_SHIFT (24) /* Bits 24-29: Number of Segment Terminals in Use */ +#define LCDCA_CFG_NSU_MASK (63 << LCDCA_CFG_NSU_SHIFT) +# define LCDCA_CFG_NSU(n) ((n) << LCDCA_CFG_NSU_SHIFT) /* n=0-40 */ + +/* Timing Register */ + +#define LCDCA_TIM_PRESC (1 << 0) /* Bit 0: LCD Prescaler Select */ +#define LCDCA_TIM_CLKDIV_SHIFT (1) /* Bits 1-3: LCD Clock Division */ +#define LCDCA_TIM_CLKDIV_MASK (7 << LCDCA_TIM_CLKDIV_SHIFT) +# define LCDCA_TIM_CLKDIV(n) (((n)-1) << LCDCA_TIM_CLKDIV_SHIFT) /* n=1..8 */ +#define LCDCA_TIM_FC0_SHIFT (8) /* Bits 8-12: Frame Counter 0 */ +#define LCDCA_TIM_FC0_MASK (31 << LCDCA_TIM_FC0_SHIFT) +# define LCDCA_TIM_FC0(n) ((n) << LCDCA_TIM_FC0_SHIFT) /* n=0-31 */ +#define LCDCA_TIM_FC0PB (1 << 13) /* Bit 13: Frame Counter 0 Prescaler Bypass */ +#define LCDCA_TIM_FC1_SHIFT (16) /* Bits 16-20: Frame Counter 1 */ +#define LCDCA_TIM_FC1_MASK (31 << LCDCA_TIM_FC1_SHIFT) +# define LCDCA_TIM_FC1(n) ((n) << LCDCA_TIM_FC1_SHIFT) /* n=0-31 */ +#define LCDCA_TIM_FC2_SHIFT (24) /* Bits 24-28: Frame Counter 2 */ +#define LCDCA_TIM_FC2_MASK (31 << LCDCA_TIM_FC2_SHIFT) +# define LCDCA_TIM_FC2(n) ((n) << LCDCA_TIM_FC2_SHIFT) /* n=0-31 */ + +/* Status Register */ + +#define LCDCA_SR_FC0R (1 << 0) /* Bit 0: Frame Counter 0 Rollover */ +#define LCDCA_SR_FC0S (1 << 1) /* Bit 1: Frame Counter 0 Status */ +#define LCDCA_SR_FC1S (1 << 2) /* Bit 2: Frame Counter 1 Status */ +#define LCDCA_SR_FC2S (1 << 3) /* Bit 3: Frame Counter 2 Status */ +#define LCDCA_SR_EN (1 << 4) /* Bit 4: LCDCA Status */ +#define LCDCA_SR_WEN (1 << 5) /* Bit 5: Wake up Status */ +#define LCDCA_SR_BLKS (1 << 6) /* Bit 6: Blink Status */ +#define LCDCA_SR_CSRS (1 << 7) /* Bit 7: Circular Shift Register Status */ +#define LCDCA_SR_CPS (1 << 8) /* Bit 8: Charge Pump Status */ + +/* Status Clear Register */ + +#define LCDCA_SCR_FC0R (1 << 0) /* Bit 0: Frame Counter 0 Rollover */ + +/* Data Register Low 0-3 (32-bit data, each bit defines a segment value in display + * memory for segments 0-31). + */ + +#define LCDCA_DRL_MASK 0xffffffff + +/* Data Register High 0-3 (8 bits data, each bit defines a segment value in display + * memory for segments 32-39) + */ + +#define LCDCA_DRH_MASK 0xff + +/* Indirect Access Data Register */ + +#define LCDCA_IADR_DATA_SHIFT (0) /* Bits 0-7: Segments Value */ +#define LCDCA_IADR_DATA_MASK (0xff << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA(n) ((n) << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA0 (0x01 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA1 (0x02 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA2 (0x04 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA3 (0x08 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA4 (0x10 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA5 (0x20 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA6 (0x40 << LCDCA_IADR_DATA_SHIFT) +# define LCDCA_IADR_DATA7 (0x80 << LCDCA_IADR_DATA_SHIFT) +#define LCDCA_IADR_DMASK_SHIFT (8) /* Bits 8-15: Data Mask */ +#define LCDCA_IADR_DMASK_MASK (0xff << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK(n) ((n) << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK0 (0x01 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK1 (0x02 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK2 (0x04 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK3 (0x08 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK4 (0x10 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK5 (0x20 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK6 (0x40 << LCDCA_IADR_DMASK_SHIFT) +# define LCDCA_IADR_DMASK7 (0x80 << LCDCA_IADR_DMASK_SHIFT) +#define LCDCA_IADR_OFF_SHIFT (16) /* Bits 16-20: Byte Offset */ +#define LCDCA_IADR_OFF_MASK (31 << LCDCA_IADR_OFF_SHIFT) +# define LCDCA_IADR_OFF(n) (31 << LCDCA_IADR_OFF_SHIFT) + +/* Blink Configuration Register */ + +#define LCDCA_BCFG_MODE (1 << 0) /* Bit 0: Blinking Mode */ +#define LCDCA_BCFG_FCS_SHIFT (1) /* Bits 1-2: Frame Counter Selection */ +#define LCDCA_BCFG_FCS_MASK (3 << LCDCA_BCFG_FCS_SHIFT) +# define LCDCA_BCFG_FCS(n) ((n) << LCDCA_BCFG_FCS_SHIFT) /* n=0-2 */ +# define LCDCA_BCFG_FCS0 (0 << LCDCA_BCFG_FCS_SHIFT) +# define LCDCA_BCFG_FCS1 (1 << LCDCA_BCFG_FCS_SHIFT) +# define LCDCA_BCFG_FCS2 (2 << LCDCA_BCFG_FCS_SHIFT) +#define LCDCA_BCFG_BSS0_SHIFT (8) /* Bits 8-11: Blink Segment Selection 0 */ +#define LCDCA_BCFG_BSS0_MASK (15 << LCDCA_BCFG_BSS0_SHIFT) +# define LCDCA_BCFG_BSS0(n) ((n) << LCDCA_BCFG_BSS0_SHIFT) /* n=bitset */ +# define LCDCA_BCFG_BSS00 (0 << LCDCA_BCFG_BSS0_SHIFT) /* Segment SEG0/COM0 selected */ +# define LCDCA_BCFG_BSS01 (0 << LCDCA_BCFG_BSS0_SHIFT) /* Segment SEG0/COM1 selected */ +# define LCDCA_BCFG_BSS02 (0 << LCDCA_BCFG_BSS0_SHIFT) /* Segment SEG0/COM2 selected */ +# define LCDCA_BCFG_BSS03 (0 << LCDCA_BCFG_BSS0_SHIFT) /* Segment SEG0/COM3 selected */ +#define LCDCA_BCFG_BSS1_SHIFT (12) /* Bits 12-15: Blink Segment Selection 1 */ +#define LCDCA_BCFG_BSS1_MASK (15 << LCDCA_BCFG_BSS1_SHIFT) +# define LCDCA_BCFG_BSS1(n) ((n) << LCDCA_BCFG_BSS1_SHIFT) /* n=bitset */ +# define LCDCA_BCFG_BSS10 (0 << LCDCA_BCFG_BSS1_SHIFT) /* Segment SEG1/COM0 selected */ +# define LCDCA_BCFG_BSS11 (0 << LCDCA_BCFG_BSS1_SHIFT) /* Segment SEG1/COM1 selected */ +# define LCDCA_BCFG_BSS12 (0 << LCDCA_BCFG_BSS1_SHIFT) /* Segment SEG1/COM2 selected */ +# define LCDCA_BCFG_BSS13 (0 << LCDCA_BCFG_BSS1_SHIFT) /* Segment SEG1/COM3 selected */ + +/* Circular Shift Register Configuration */ + +#define LCDCA_CSRCFG_DIR (1 << 0) /* Bit 0: Direction */ +#define LCDCA_CSRCFG_FCS_SHIFT (1) /* Bits 1-2: Frame Counter Selection */ +#define LCDCA_CSRCFG_FCS_MASK (3 << LCDCA_CSRCFG_FCS_SHIFT) +# define LCDCA_CSRCFG_FCS(n) ((n) << LCDCA_CSRCFG_FCS_SHIFT) /* n=0-2 */ +# define LCDCA_CSRCFG_FCS0 (0 << LCDCA_CSRCFG_FCS_SHIFT) +# define LCDCA_CSRCFG_FCS1 (1 << LCDCA_CSRCFG_FCS_SHIFT) +# define LCDCA_CSRCFG_FCS2 (2 << LCDCA_CSRCFG_FCS_SHIFT) +#define LCDCA_CSRCFG_SIZE_SHIFT (3) /* Bits 3-5: Size */ +#define LCDCA_CSRCFG_SIZE_MASK (7 << LCDCA_CSRCFG_SIZE_SHIFT) +# define LCDCA_CSRCFG_SIZE(n) (((n)-1) << LCDCA_CSRCFG_SIZE_SHIFT) /* n=1..8 */ +#define LCDCA_CSRCFG_DATA_SHIFT (8) /* Bits 8-15: Circular Shift Register Value */ +#define LCDCA_CSRCFG_DATA_MASK (0xff << LCDCA_CSRCFG_DATA_SHIFT) +# define LCDCA_CSRCFG_DATA(n) ((n) << LCDCA_CSRCFG_DATA_SHIFT) + +/* Character Mapping Configuration Register */ + +#define LCDCA_CMCFG_DREV (1 << 0) /* Bit 0: Digit Reverse Mode */ +#define LCDCA_CMCFG_TDG_SHIFT (1) /* Bits 1-2: Type of Digit */ +#define LCDCA_CMCFG_TDG_MASK (3 << LCDCA_CMCFG_TDG_SHIFT) +# define LCDCA_CMCFG_TDG_7S3C (0 << LCDCA_CMCFG_TDG_SHIFT) /* 7-segment with 3 common terminals */ +# define LCDCA_CMCFG_TDG_7S4C (1 << LCDCA_CMCFG_TDG_SHIFT) /* 7-segment with 4 common terminals */ +# define LCDCA_CMCFG_TDG_14S4C (2 << LCDCA_CMCFG_TDG_SHIFT) /* 14-segment with 4 common terminals */ +# define LCDCA_CMCFG_TDG_14S3C (3 << LCDCA_CMCFG_TDG_SHIFT) /* 16-segment with 3 common terminals */ +#define LCDCA_CMCFG_STSEG_SHIFT (8) /* Bits 8-13: Start Segment */ +#define LCDCA_CMCFG_STSEG_MASK (63 << LCDCA_CMCFG_STSEG_SHIFT) +# define LCDCA_CMCFG_STSEG(n) ((n) << LCDCA_CMCFG_STSEG_SHIFT) + +/* Character Mapping Data Register */ + +#define LCDCA_CMDR_MASK 0x7f + +/* Automated Character Mapping Configuration Register */ + +#define LCDCA_ACMCFG_EN (1 << 0) /* Bit 0: Enable */ +#define LCDCA_ACMCFG_FCS_SHIFT (1) /* Bits 1-2: Frame Counter Selection */ +#define LCDCA_ACMCFG_FCS_MASK (3 << LCDCA_ACMCFG_FCS_SHIFT) +# define LCDCA_ACMCFG_FCS(n) ((n) << LCDCA_ACMCFG_FCS_SHIFT) /* n=0-2 */ +# define LCDCA_ACMCFG_FCS0 (0 << LCDCA_ACMCFG_FCS_SHIFT) +# define LCDCA_ACMCFG_FCS1 (1 << LCDCA_ACMCFG_FCS_SHIFT) +# define LCDCA_ACMCFG_FCS2 (2 << LCDCA_ACMCFG_FCS_SHIFT) +#define LCDCA_ACMCFG_MODE (1 << 3) /* Bit 3: Mode */ +#define LCDCA_ACMCFG_DREV (1 << 4) /* Bit 4: Digit Reverse */ +#define LCDCA_ACMCFG_TDG_SHIFT (5) /* Bits 5-6: Type of Digit */ +#define LCDCA_ACMCFG_TDG_MASK (3 << LCDCA_ACMCFG_TDG_SHIFT) +# define LCDCA_ACMCFG_TDG_7S3C (0 << LCDCA_ACMCFG_TDG_SHIFT) /* 7-segment with 3 common terminals */ +# define LCDCA_ACMCFG_TDG_7S4C (1 << LCDCA_ACMCFG_TDG_SHIFT) /* 7-segment with 4 common terminals */ +# define LCDCA_ACMCFG_TDG_14S4C (2 << LCDCA_ACMCFG_TDG_SHIFT) /* 14-segment with 4 common terminals */ +# define LCDCA_ACMCFG_TDG_14S3C (3 << LCDCA_ACMCFG_TDG_SHIFT) /* 16-segment with 3 common terminals */ +#define LCDCA_ACMCFG_STSEG_SHIFT (8) /* Bits 8-13: Start Segment */ +#define LCDCA_ACMCFG_STSEG_MASK (63 << LCDCA_ACMCFG_STSEG_SHIFT) +# define LCDCA_ACMCFG_STSEG(n) ((n) << LCDCA_ACMCFG_STSEG_SHIFT) +#define LCDCA_ACMCFG_STEPS_SHIFT (16) /* Bits 16-23: Scrolling Steps */ +#define LCDCA_ACMCFG_STEPS_MASK (0xff << LCDCA_ACMCFG_STEPS_SHIFT) +# define LCDCA_ACMCFG_STEPS(n) ((n) << LCDCA_ACMCFG_STEPS_SHIFT) /* n = string length - DIGN + 1 */ +#define LCDCA_ACMCFG_DIGN_SHIFT (24) /* Bits 24-27: Digit Number */ +#define LCDCA_ACMCFG_DIGN_MASK (15 << LCDCA_ACMCFG_DIGN_SHIFT) +# define LCDCA_ACMCFG_DIGN(n) ((n) << LCDCA_ACMCFG_DIGN_SHIFT) /* n=1..15 */ + +/* Automated Character Mapping Data Register */ + +#define LCDCA_ACMDR_MASK 0x7f + +/* Automated Bit Mapping Configuration Register */ + +#define LCDCA_ABMCFG_EN (1 << 0) /* Bit 0: Enable */ +#define LCDCA_ABMCFG_FCS_SHIFT (1) /* Bits 1-2: Frame Counter Selection */ +#define LCDCA_ABMCFG_FCS_MASK (3 << LCDCA_ABMCFG_FCS_SHIFT) +# define LCDCA_ABMCFG_FCS(n) ((n) << LCDCA_ABMCFG_FCS_SHIFT) /* n=0-2 */ +# define LCDCA_ABMCFG_FCS0 (0 << LCDCA_ABMCFG_FCS_SHIFT) +# define LCDCA_ABMCFG_FCS1 (1 << LCDCA_ABMCFG_FCS_SHIFT) +# define LCDCA_ABMCFG_FCS2 (2 << LCDCA_ABMCFG_FCS_SHIFT) +#define LCDCA_ABMCFG_SIZE_SHIFT (8) /* Bits 8-12: Size */ +#define LCDCA_ABMCFG_SIZE_MASK (31 << LCDCA_ABMCFG_SIZE_SHIFT) +# define LCDCA_ABMCFG_SIZE(n) (((n)-1) << LCDCA_ABMCFG_SIZE_SHIFT) /* n=1..31 */ + +/* Automated Bit Mapping Data Register */ + +#define LCDCA_ABMDR_DATA_SHIFT (0) /* Bits 0-7: Segments Value */ +#define LCDCA_ABMDR_DATA_MASK (0xff << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA(n) ((n) << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA0 (0x01 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA1 (0x02 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA2 (0x04 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA3 (0x08 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA4 (0x10 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA5 (0x20 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA6 (0x40 << LCDCA_ABMDR_DATA_SHIFT) +# define LCDCA_ABMDR_DATA7 (0x80 << LCDCA_ABMDR_DATA_SHIFT) +#define LCDCA_ABMDR_DMASK_SHIFT (8) /* Bits 8-15: Data Mask */ +#define LCDCA_ABMDR_DMASK_MASK (0xff << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK(n) ((n) << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK0 (0x01 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK1 (0x02 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK2 (0x04 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK3 (0x08 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK4 (0x10 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK5 (0x20 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK6 (0x40 << LCDCA_ABMDR_DMASK_SHIFT) +# define LCDCA_ABMDR_DMASK7 (0x80 << LCDCA_ABMDR_DMASK_SHIFT) +#define LCDCA_ABMDR_OFF_SHIFT (16) /* Bits 16-20: Byte Offset */ +#define LCDCA_ABMDR_OFF_MASK (31 << LCDCA_ABMDR_OFF_SHIFT) +# define LCDCA_ABMDR_OFF(n) (31 << LCDCA_ABMDR_OFF_SHIFT) + +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ + +#define LCDCA_INT_FC0R (1 << 0) /* Bit 0: Frame Counter 0 Rollover */ + +/* Version Register */ + +#define LCDCA_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define LCDCA_VERSION_MASK (0xfff << LCDCA_VERSION_VERSION_SHIFT) +#define LCDCA_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define LCDCA_VARIANT_MASK (15 << LCDCA_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_LCDCA_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_memorymap.h b/arch/arm/src/sam34/chip/sam4l_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..56810fe442cde2fdf5045573e44ba0e5389243c9 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_memorymap.h @@ -0,0 +1,162 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4l_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Global Memory Space */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ + /* 0x22000000-0x3fffffff: Undefined */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ + /* 0x60000000-0xdfffffff: Reserved */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code Space */ + +#define SAM_INTFLASH_BASE 0x00000000 /* 0x00000000-0x003fffff: Internal FLASH */ + /* 0x00400000-0x1fffffff: Reserved */ +/* Internal SRAM Space */ + +#define SAM_INTSRAM0_BASE 0x20000000 /* 0x20000000-0x2007ffff: HRAMC0 (see chip.h) */ + /* 0x20008000-0x20ffffff: Reserved */ +#define SAM_INTSRAM1_BASE 0x21000000 /* 0x21000000-0x210007ff: HRAMC1 (see chip.h) */ + /* 0x21000800-0x21ffffff: Reserved */ +/* Peripherals Space */ + +#define SAM_PERIPHA_BASE 0x40000000 /* 0x40000000-0x4009ffff: Peripheral Bridge A */ +#define SAM_PERIPHB_BASE 0x400a0000 /* 0x400a0000-0x400affff: Peripheral Bridge B */ +#define SAM_AESA_BASE 0x400b0000 /* 0x400b0000-0x400b00ff: AESA */ + /* 0x400b0100-0x400dffff: Reserved */ +#define SAM_PERIPHC_BASE 0x400e0000 /* 0x400e0000-0x400effff: Peripheral Bridge C */ +#define SAM_PERIPHD_BASE 0x400e0000 /* 0x400f0000-0x400fffff: Peripheral Bridge D */ + /* 0x40100000-0x5fffffff: Reserved */ +/* Peripheral Bridge A */ + /* 0x40000000-0x40003fff: Reserved */ +#define SAM_I2SC_BASE 0x40004000 /* 0x40004000-0x40007fff: I2S Controller */ +#define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface */ + /* 0x4000c000-0x4000ffff: Reserved */ +#define SAM_TC0_BASE 0x40100000 /* 0x40100000-0x4013ffff: Timer Counter 0 */ +#define SAM_TC1_BASE 0x40140000 /* 0x40180000-0x4017ffff: Timer Counter 1 */ +#define SAM_TWIMS0_BASE 0x40180000 /* 0x40180000-0x401bffff: Two-wire Master/Slave Interface 0 */ +#define SAM_TWIMS1_BASE 0x401c0000 /* 0x401c0000-0x401fffff: Two-wire Master/Slave Interface 1 */ + /* 0x40020000-0x40023fff: Reserved */ +#define SAM_USARTN_BASE(n) (0x40024000+((n)<<14)) +#define SAM_USART0_BASE 0x40024000 /* 0x40024000-0x40027fff: USART0 */ +#define SAM_USART1_BASE 0x40028000 /* 0x40028000-0x4002bfff: USART1 */ +#define SAM_USART2_BASE 0x4002c000 /* 0x4002c000-0x4002ffff: USART2 */ +#define SAM_USART3_BASE 0x40030000 /* 0x40030000-0x40033fff: USART3 */ + /* 0x40034000-0x40037fff: Reserved */ +#define SAM_ADCIFE_BASE 0x40038000 /* 0x40038000-0x4003bfff: ADC controller interface */ +#define SAM_DACC_BASE 0x4003c000 /* 0x4003c000-0x4003ffff: DAC Controller */ +#define SAM_ACIF_BASE 0x40040000 /* 0x40040000-0x40043fff: Analog Comparator Interface */ + /* 0x40044000-0x4005ffff: Reserved */ +#define SAM_GLOC_BASE 0x40040000 /* 0x40060000-0x40063fff: GLOC */ +#define SAM_ABDACB_BASE 0x40040000 /* 0x40064000-0x40067fff: Audio Bitstream DAC */ +#define SAM_TRNG_BASE 0x40068000 /* 0x40064000-0x4006bfff: True Random Number Generator */ +#define SAM_PARC_BASE 0x4006c000 /* 0x4006c000-0x4006ffff: Parallel Capture */ +#define SAM_CATB_BASE 0x40070000 /* 0x4006c000-0x40073fff: Capacitive Touch Module B */ + /* 0x40074000-0x40077fff: Reserved */ +#define SAM_TWIM2_BASE 0x40078000 /* 0x40078000-0x4007bfff: Two-wire Master Interface 2 */ +#define SAM_TWIM3_BASE 0x4007c000 /* 0x4007c000-0x4007ffff: Two-wire Master Interface 3 */ +#define SAM_LCDCA_BASE 0x40080000 /* 0x40080000-0x40083fff: LCD Controller A */ + /* 0x40084000-0x4009ffff: Reserved */ +/* Peripheral Bridge B */ + +#define SAM_FLASHCALW_BASE 0x400a0000 /* 0x400a0000-0x400a03ff: FLASHCALW */ +#define SAM_PICOCACHE_BASE 0x400a0400 /* 0x400a0400-0x400a0fff: PICOCACHE */ +#define SAM_HMATRIX_BASE 0x400a1000 /* 0x400a1000-0x400a1fff: HMATRIX */ +#define SAM_PDCA_BASE 0x400a2000 /* 0x400a2000-0x400a2fff: Peripheral DMA Controller */ +#define SAM_SMAP_BASE 0x400a3000 /* 0x400a3000-0x400a3fff: SMAP */ +#define SAM_CRCCU_BASE 0x400a4000 /* 0x400a4000-0x400a4fff: CRC Calculation Unit */ +#define SAM_USBC_BASE 0x400a5000 /* 0x400a5000-0x400a5fff: USB 2.0 Interface */ +#define SAM_PEVC_BASE 0x400a6000 /* 0x400a6000-0x400a63ff: Peripheral Event Controller */ + /* 0x400a6400-0x400affff: Reserved */ +/* Peripheral Bridge C */ + +#define SAM_PM_BASE 0x400e0000 /* 0x400e0000-0x400e073f: Power Manager */ +#define SAM_CHIPID_BASE 0x400e0740 /* 0x400e0740-0x400e07ff: CHIPID */ +#define SAM_SCIF_BASE 0x400e0800 /* 0x400e0800-0x400e0bff: System Control Interface */ +#define SAM_FREQM_BASE 0x400e0c00 /* 0x400e0c00-0x400e0fff: Frequency Meter */ +#define SAM_GPIO_BASE 0x400e1000 /* 0x400e1000-0x400e17ff: GPIO */ + /* 0x400e1800-0x400effff: Reserved */ +/* Peripheral Bridge D */ + +#define SAM_BPM_BASE 0x400f0000 /* 0x400f0000-0x400f03ff: Backup Power Manager */ +#define SAM_BSCIF_BASE 0x400f0400 /* 0x400f0400-0x400f07ff: Backup System Control Interface */ +#define SAM_AST_BASE 0x400f0800 /* 0x400f0800-0x400f0bff: Asynchronous Timer */ +#define SAM_WDT_BASE 0x400f0c00 /* 0x400f0c00-0x400f0fff: Watchdog Timer */ +#define SAM_EIC_BASE 0x400f1000 /* 0x400f1000-0x400f13ff: External Interrupt Controller */ +#define SAM_PICOUART_BASE 0x400f1400 /* 0x400f1400-0x400f17ff: PICOUART */ + /* 0x400f1800-0x400fffff: Reserved */ +/* System Space */ + +#define SAM_ITM_BASE 0xe0000000 /* 0xe0000000-0xe0000fff: ITM */ +#define SAM_DWT_BASE 0xe0001000 /* 0xe0001000-0xe0001fff: DWT */ +#define SAM_FPB_BASE 0xe0002000 /* 0xe0002000-0xe0002fff: FPB */ + /* 0xe0003000-0xe000dfff: Reserved */ +#define SAM_SCS_BASE 0xe000e000 /* 0xe000e000-0xe000efff: SCS */ + /* 0xe000f000-0xe003ffff: Reserved */ +#define SAM_TPIU_BASE 0xe0040000 /* 0xe0040000-0xe0040fff: TPIU */ + /* 0xe0041000-0xe0041fff: Reserved */ +#define SAM_EXTPPB_BASE 0xe0042000 /* 0xe0042000-0xe00fefff: External PPB */ +#define SAM_ROMTAB_BASE 0xe00ff000 /* 0xe00ff000-0xe00fffff: ROM Table */ + /* 0xe0100000-0xffffffff: Reserved */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_pdca.h b/arch/arm/src/sam34/chip/sam4l_pdca.h new file mode 100644 index 0000000000000000000000000000000000000000..14b947de42019b744a56e507484361cab2212857 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_pdca.h @@ -0,0 +1,204 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_pdca.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PDCA_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PDCA_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PDCA channel offsets *****************************************************************/ + +#define SAM_PDCA_CHAN_OFFSET(n) ((n) << 6) +#define SAM_PDCA_CHAN0_OFFSET 0x0000 +#define SAM_PDCA_CHAN1_OFFSET 0x0040 +#define SAM_PDCA_CHAN2_OFFSET 0x0080 +#define SAM_PDCA_CHAN3_OFFSET 0x00c0 +#define SAM_PDCA_CHAN4_OFFSET 0x0100 +#define SAM_PDCA_CHAN5_OFFSET 0x0140 +#define SAM_PDCA_CHAN6_OFFSET 0x0180 +#define SAM_PDCA_CHAN7_OFFSET 0x01c0 +#define SAM_PDCA_CHAN8_OFFSET 0x0200 +#define SAM_PDCA_CHAN9_OFFSET 0x0240 +#define SAM_PDCA_CHAN10_OFFSET 0x0280 +#define SAM_PDCA_CHAN11_OFFSET 0x02c0 +#define SAM_PDCA_CHAN12_OFFSET 0x0300 +#define SAM_PDCA_CHAN13_OFFSET 0x0340 +#define SAM_PDCA_CHAN14_OFFSET 0x0380 +#define SAM_PDCA_CHAN15_OFFSET 0x03c0 + +/* PDCA register offsets ****************************************************************/ +/* Channel register offsets */ + +#define SAM_PDCA_MAR_OFFSET 0x0000 /* Memory Address Register */ +#define SAM_PDCA_PSR_OFFSET 0x0004 /* Peripheral Select Register */ +#define SAM_PDCA_TCR_OFFSET 0x0008 /* Transfer Counter Register */ +#define SAM_PDCA_MARR_OFFSET 0x000c /* Memory Address Reload Register */ +#define SAM_PDCA_TCRR_OFFSET 0x0010 /* Transfer Counter Reload Register */ +#define SAM_PDCA_CR_OFFSET 0x0014 /* Control Register */ +#define SAM_PDCA_MR_OFFSET 0x0018 /* Mode Register */ +#define SAM_PDCA_SR_OFFSET 0x001c /* Status Register */ +#define SAM_PDCA_IER_OFFSET 0x0020 /* Interrupt Enable Register */ +#define SAM_PDCA_IDR_OFFSET 0x0024 /* Interrupt Disable Register */ +#define SAM_PDCA_IMR_OFFSET 0x0028 /* Interrupt Mask Register */ +#define SAM_PDCA_ISR_OFFSET 0x002c /* Interrupt Status Register */ + +/* Global register offsets */ + +#define SAM_PDCA_VERSION_OFFSET 0x834 /* Version Register */ + +/* PDCA channel addresses ***************************************************************/ +/* Channel register base addresses */ + +#define SAM_PDCA_CHAN(n) (SAM_PDCA_BASE+SAM_PDCA_CHAN_OFFSET(n)) +#define SAM_PDCA_CHAN0 (SAM_PDCA_BASE+SAM_PDCA_CHAN0_OFFSET) +#define SAM_PDCA_CHAN1 (SAM_PDCA_BASE+SAM_PDCA_CHAN1_OFFSET) +#define SAM_PDCA_CHAN2 (SAM_PDCA_BASE+SAM_PDCA_CHAN2_OFFSET) +#define SAM_PDCA_CHAN3 (SAM_PDCA_BASE+SAM_PDCA_CHAN3_OFFSET) +#define SAM_PDCA_CHAN4 (SAM_PDCA_BASE+SAM_PDCA_CHAN4_OFFSET) +#define SAM_PDCA_CHAN5 (SAM_PDCA_BASE+SAM_PDCA_CHAN5_OFFSET) +#define SAM_PDCA_CHAN6 (SAM_PDCA_BASE+SAM_PDCA_CHAN6_OFFSET) +#define SAM_PDCA_CHAN7 (SAM_PDCA_BASE+SAM_PDCA_CHAN7_OFFSET) +#define SAM_PDCA_CHAN8 (SAM_PDCA_BASE+SAM_PDCA_CHAN8_OFFSET) +#define SAM_PDCA_CHAN9 (SAM_PDCA_BASE+SAM_PDCA_CHAN9_OFFSET) +#define SAM_PDCA_CHAN10 (SAM_PDCA_BASE+SAM_PDCA_CHAN10_OFFSET) +#define SAM_PDCA_CHAN11 (SAM_PDCA_BASE+SAM_PDCA_CHAN11_OFFSET) +#define SAM_PDCA_CHAN12 (SAM_PDCA_BASE+SAM_PDCA_CHAN12_OFFSET) +#define SAM_PDCA_CHAN13 (SAM_PDCA_BASE+SAM_PDCA_CHAN13_OFFSET) +#define SAM_PDCA_CHAN14 (SAM_PDCA_BASE+SAM_PDCA_CHAN14_OFFSET) +#define SAM_PDCA_CHAN15 (SAM_PDCA_BASE+SAM_PDCA_CHAN15_OFFSET) + +/* PDCA register addresses **************************************************************/ +/* Channel register addresses */ + +#define SAM_PDCA_MAR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_MAR_OFFSET) +#define SAM_PDCA_PSR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_PSR_OFFSET) +#define SAM_PDCA_TCR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_TCR_OFFSET) +#define SAM_PDCA_MARR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_MARR_OFFSET) +#define SAM_PDCA_TCRR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_TCRR_OFFSET) +#define SAM_PDCA_CR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_CR_OFFSET) +#define SAM_PDCA_MR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_MR_OFFSET) +#define SAM_PDCA_SR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_SR_OFFSET) +#define SAM_PDCA_IER(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_IER_OFFSET) +#define SAM_PDCA_IDR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_IDR_OFFSET) +#define SAM_PDCA_IMR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_IMR_OFFSET) +#define SAM_PDCA_ISR(n) (SAM_PDCA_CHAN(n)+SAM_PDCA_ISR_OFFSET) + +/* Global register offsets */ + +#define SAM_PDCA_VERSION (SAM_PDCA_BASE+SAM_PDCA_VERSION_OFFSET) + +/* PDCA register bit definitions ********************************************************/ + +/* Memory Address Register (32-bit address) */ + +/* Peripheral Select Register */ + +#define PDCA_PSR_MASK 0xff /* Bit 0-7: Peripheral identifier */ + +/* Transfer Counter Register */ + +#define PDCA_TCR_MASK 0xffff /* Bits 0-15: Transfer Counter Value + +/* Memory Address Reload Register (32-bit address) */ + +/* Transfer Counter Reload Register */ + +#define PDCA_TCRR_MASK 0xffff /* Bits 0-15: Transfer Counter Reload Value */ + +/* Control Register */ + +#define PDCA_CR_TEN (1 << 0) /* Bit 0: Transfer Enable */ +#define PDCA_CR_TDIS (1 << 1) /* Bit 1: Transfer Disable */ +#define PDCA_CR_ECLR (1 << 8) /* Bit 8: Transfer Error Clear */ + +/* Mode Register */ + +#define PDCA_MR_SIZE_SHIFT (0) /* Bits 0-1: Size of Transfer */ +#define PDCA_MR_SIZE_MASK (3 << PDCA_MR_SIZE_SHIFT) +# define PDCA_MR_SIZE_BYTE (0 << PDCA_MR_SIZE_SHIFT) +# define PDCA_MR_SIZE_HWORD (1 << PDCA_MR_SIZE_SHIFT) +# define PDCA_MR_SIZE_WORD (2 << PDCA_MR_SIZE_SHIFT) +#define PDCA_MR_ETRIG (1 << 2) /* Bit 2: Event Trigger */ +#define PDCA_MR_RING (1 << 3) /* Bit 3: Ring Buffer */ + +/* Status Register */ + +#define PDCA_SR_TEN (1 << 0) /* Bit 0: Transfer Enabled */ + +/* Interrupt Enable Register */ + +#define PDCA_IER_ + +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ +/* Interrupt Status Register */ + +#define PDCA_INT_RCZ (1 << 2) /* Bit 0: Reload Counter Zero */ +#define PDCA_INT_TRC (1 << 2) /* Bit 1: Transfer Complete */ +#define PDCA_INT_TERR (1 << 2) /* Bit 2: Transfer Error */ + +/* Global register offsets */ + +/* Version Register */ + +#define PDCA_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define PDCA_VERSION_MASK (0xfff << PDCA_VERSION_VERSION_SHIFT) +#define PDCA_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define PDCA_VARIANT_MASK (15 << PDCA_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PDCA_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_picouart.h b/arch/arm/src/sam34/chip/sam4l_picouart.h new file mode 100644 index 0000000000000000000000000000000000000000..50e2d1fbbd4f79eadfbc7233fd5a2390d89f11d9 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_picouart.h @@ -0,0 +1,121 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_picouart.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PICOUART_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PICOUART_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PICOUART register offsets ************************************************************/ + +#define SAM_PICOUART_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_PICOUART_CFG_OFFSET 0x0004 /* Configuration Register */ +#define SAM_PICOUART_SR_OFFSET 0x0008 /* Status Register */ +#define SAM_PICOUART_RHR_OFFSET 0x000c /* Receive Holding Register */ +#define SAM_PICOUART_VERSION_OFFSET 0x0020 /* Version Register */ + +/* PICOUART register addresses **********************************************************/ + +#define SAM_PICOUART_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_PICOUART_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_PICOUART_CFG_OFFSET 0x0004 /* Configuration Register */ +#define SAM_PICOUART_CFG_OFFSET 0x0004 /* Configuration Register */ +#define SAM_PICOUART_SR_OFFSET 0x0008 /* Status Register */ +#define SAM_PICOUART_SR_OFFSET 0x0008 /* Status Register */ +#define SAM_PICOUART_RHR_OFFSET 0x000c /* Receive Holding Register */ +#define SAM_PICOUART_RHR_OFFSET 0x000c /* Receive Holding Register */ +#define SAM_PICOUART_VERSION_OFFSET 0x0020 /* Version Register */ +#define SAM_PICOUART_VERSION_OFFSET 0x0020 /* Version Register */ + +/* PICOUART register bit definitions ****************************************************/ + +/* Control Register */ + +#define PICOUART_CR_EN (1 << 0) /* Bit 0: Enable */ +#define PICOUART_CR_DIS (1 << 1) /* Bit 1: Disable */ + +/* Configuration Register */ + +#define PICOUART_CFG_SOURCE_SHIFT (0) /* Bit 0-1: Source Enable Mode */ +#define PICOUART_CFG_SOURCE_MASK (3 << PICOUART_CFG_SOURCE_SHIFT) +# define PICOUART_CFG_SOURCE_WE (0 << PICOUART_CFG_SOURCE_SHIFT) /* Wake up and event disable */ +# define PICOUART_CFG_SOURCE_WESB (1 << PICOUART_CFG_SOURCE_SHIFT) /* Wake up or event enable on start bit detection */ +# define PICOUART_CFG_SOURCE_WEFF (2 << PICOUART_CFG_SOURCE_SHIFT) /* Wake up or event enable on full frame reception */ +# define PICOUART_CFG_SOURCE_WECH (3 << PICOUART_CFG_SOURCE_SHIFT) /* Wake up or event enable on character recognition */ +#define PICOUART_CFG_ACTION (1 << 0) /* Bit 0: Action to perform */ +#define PICOUART_CFG_MATCH_SHIFT (8) /* Bit 8-15: Data Match */ +#define PICOUART_CFG_MATCH_SHIFT (8) /* Bit 8-15: Data Match */ +#define PICOUART_CFG_MATCH_MASK (0xff << PICOUART_CFG_MATCH_SHIFT) + +/* Status Register */ + +#define PICOUART_SR_EN (1 << 0) /* Bit 0: Enable Status */ +#define PICOUART_SR_DRDY (1 << 1) /* Bit 1: Data Ready */ + +/* Receive Holding Register */ + +#define PICOUART_RHR_MASK 0xff + +/* Version Register */ + +#define PICOUART_VERSION_SHIFT (0) /* Bits 0-11: Macrocell version number */ +#define PICOUART_VERSION_MASK (0xfff << PICOUART_VERSION_SHIFT) +#define PICOUART_VARIANT_SHIFT (16) /* Bits 16-18: Reserved */ +#define PICOUART_VARIANT_MASK (7 << PICOUART_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PICOUART_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_pinmap.h b/arch/arm/src/sam34/chip/sam4l_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..7cf80dd4ac1ddaf6dd0b453d349701a0c6edc8f7 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_pinmap.h @@ -0,0 +1,579 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam3u_pinmap.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * SPI MSIO connects vis PA21 on some board, then the following definition should + * appear in the board.h header file for that board: + * + * #define GPIO_SPI_MISO GPIO_SPI_MISO_1 + * + * The driver will then automatically configre PA21 as the SPI MISO pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Audio Bitstream DAC */ + +#define GPIO_ABDACB_CLK_1 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN31) +#define GPIO_ABDACB_CLK_2 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN12) +#define GPIO_ABDACB_DAC0_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN17) +#define GPIO_ABDACB_DAC0_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN27) +#define GPIO_ABDACB_DAC0_3 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN2) +#define GPIO_ABDACB_DAC0_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN9) +#define GPIO_ABDACB_DAC1_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN19) +#define GPIO_ABDACB_DAC1_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN29) +#define GPIO_ABDACB_DAC1_3 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN4) +#define GPIO_ABDACB_DAC1_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN13) +#define GPIO_ABDACB_DACN0_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN18) +#define GPIO_ABDACB_DACN0_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN28) +#define GPIO_ABDACB_DACN0_3 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN3) +#define GPIO_ABDACB_DACN0_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN10) +#define GPIO_ABDACB_DACN1_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN20) +#define GPIO_ABDACB_DACN1_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN30) +#define GPIO_ABDACB_DACN1_3 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN5) +#define GPIO_ABDACB_DACN1_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN14) + +/* Analog Comparator Interface */ + +#define GPIO_ACIFC_ACAN0 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN6) +#define GPIO_ACIFC_ACAN1 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN9) +#define GPIO_ACIFC_ACAP0 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN7) +#define GPIO_ACIFC_ACAP1 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN10) +#define GPIO_ACIFC_ACBN0 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN2) +#define GPIO_ACIFC_ACBN1 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN13) +#define GPIO_ACIFC_ACBP0 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN3) +#define GPIO_ACIFC_ACBP1 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN14) + +/* ADC controller interface */ + +#define GPIO_ADCIFE_AD0 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN4) +#define GPIO_ADCIFE_AD1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN5) +#define GPIO_ADCIFE_AD2 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN7) +#define GPIO_ADCIFE_AD3 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN2) +#define GPIO_ADCIFE_AD4 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN3) +#define GPIO_ADCIFE_AD5 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN4) +#define GPIO_ADCIFE_AD6 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN5) +#define GPIO_ADCIFE_AD7 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN7) +#define GPIO_ADCIFE_AD8 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN8) +#define GPIO_ADCIFE_AD9 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN9) +#define GPIO_ADCIFE_AD10 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN10) +#define GPIO_ADCIFE_AD11 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN11) +#define GPIO_ADCIFE_AD12 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN12) +#define GPIO_ADCIFE_AD13 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN13) +#define GPIO_ADCIFE_AD14 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN14) +#define GPIO_ADCIFE_TRIGGER (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN5) + +/* Capacitive Touch Module B */ + +#define GPIO_CATB_DIS_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN12) +#define GPIO_CATB_DIS_2 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN2) +#define GPIO_CATB_DIS_3 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN23) +#define GPIO_CATB_DIS_4 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN31) +#define GPIO_CATB_DIS_5 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN12) +#define GPIO_CATB_DIS_6 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN3) +#define GPIO_CATB_DIS_7 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN14) +#define GPIO_CATB_DIS_8 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN23) +#define GPIO_CATB_DIS_9 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN5) +#define GPIO_CATB_SENSE0_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN27) +#define GPIO_CATB_SENSE0_2 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN4) +#define GPIO_CATB_SENSE0_3 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN13) +#define GPIO_CATB_SENSE1_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN28) +#define GPIO_CATB_SENSE1_2 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN5) +#define GPIO_CATB_SENSE1_3 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN14) +#define GPIO_CATB_SENSE2_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN29) +#define GPIO_CATB_SENSE2_2 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN6) +#define GPIO_CATB_SENSE2_3 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN15) +#define GPIO_CATB_SENSE3_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN30) +#define GPIO_CATB_SENSE3_2 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN7) +#define GPIO_CATB_SENSE3_3 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN0) +#define GPIO_CATB_SENSE4_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN8) +#define GPIO_CATB_SENSE4_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN1) +#define GPIO_CATB_SENSE5_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN9) +#define GPIO_CATB_SENSE5_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN2) +#define GPIO_CATB_SENSE6_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN10) +#define GPIO_CATB_SENSE6_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN3) +#define GPIO_CATB_SENSE7_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN11) +#define GPIO_CATB_SENSE7_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN4) +#define GPIO_CATB_SENSE8_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN13) +#define GPIO_CATB_SENSE8_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN6) +#define GPIO_CATB_SENSE9_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN14) +#define GPIO_CATB_SENSE9_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN7) +#define GPIO_CATB_SENSE10_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN15) +#define GPIO_CATB_SENSE10_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN8) +#define GPIO_CATB_SENSE11_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN16) +#define GPIO_CATB_SENSE11_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN9) +#define GPIO_CATB_SENSE12_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN17) +#define GPIO_CATB_SENSE12_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN10) +#define GPIO_CATB_SENSE13_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN18) +#define GPIO_CATB_SENSE13_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN11) +#define GPIO_CATB_SENSE14_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN19) +#define GPIO_CATB_SENSE14_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN12) +#define GPIO_CATB_SENSE15_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN20) +#define GPIO_CATB_SENSE15_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN13) +#define GPIO_CATB_SENSE16_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN21) +#define GPIO_CATB_SENSE16_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN15) +#define GPIO_CATB_SENSE17_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN22) +#define GPIO_CATB_SENSE17_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN16) +#define GPIO_CATB_SENSE18_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN24) +#define GPIO_CATB_SENSE18_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN17) +#define GPIO_CATB_SENSE19_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN25) +#define GPIO_CATB_SENSE19_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN18) +#define GPIO_CATB_SENSE20_1 (GPIO_FUNCG | GPIO_PORTA | GPIO_PIN26) +#define GPIO_CATB_SENSE20_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN19) +#define GPIO_CATB_SENSE21_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN0) +#define GPIO_CATB_SENSE21_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN20) +#define GPIO_CATB_SENSE22_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN1) +#define GPIO_CATB_SENSE22_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN21) +#define GPIO_CATB_SENSE23_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN2) +#define GPIO_CATB_SENSE23_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN22) +#define GPIO_CATB_SENSE24_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN4) +#define GPIO_CATB_SENSE24_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN24) +#define GPIO_CATB_SENSE25_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN5) +#define GPIO_CATB_SENSE25_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN25) +#define GPIO_CATB_SENSE26_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN6) +#define GPIO_CATB_SENSE26_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN26) +#define GPIO_CATB_SENSE27_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN7) +#define GPIO_CATB_SENSE27_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN27) +#define GPIO_CATB_SENSE28_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN8) +#define GPIO_CATB_SENSE28_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN28) +#define GPIO_CATB_SENSE29_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN9) +#define GPIO_CATB_SENSE29_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN29) +#define GPIO_CATB_SENSE30_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN10) +#define GPIO_CATB_SENSE30_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN30) +#define GPIO_CATB_SENSE31_1 (GPIO_FUNCG | GPIO_PORTB | GPIO_PIN11) +#define GPIO_CATB_SENSE31_2 (GPIO_FUNCG | GPIO_PORTC | GPIO_PIN31) + +/* DAC Controller */ + +#define GPIO_DACC_EXT_TRIG0 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN4) +#define GPIO_DACC_VOUT (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN6) +#define GPIO_EIC_EXTINT0 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN1) +#define GPIO_EIC_EXTINT1_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN24) +#define GPIO_EIC_EXTINT1_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN16) +#define GPIO_EIC_EXTINT1_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN6) +#define GPIO_EIC_EXTINT2_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN25) +#define GPIO_EIC_EXTINT2_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN17) +#define GPIO_EIC_EXTINT2_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN4) +#define GPIO_EIC_EXTINT3_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN26) +#define GPIO_EIC_EXTINT3_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN18) +#define GPIO_EIC_EXTINT3_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN5) +#define GPIO_EIC_EXTINT4_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN27) +#define GPIO_EIC_EXTINT4_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN19) +#define GPIO_EIC_EXTINT4_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN7) +#define GPIO_EIC_EXTINT5_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN3) +#define GPIO_EIC_EXTINT5_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN20) +#define GPIO_EIC_EXTINT6_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN4) +#define GPIO_EIC_EXTINT6_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN21) +#define GPIO_EIC_EXTINT7_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN5) +#define GPIO_EIC_EXTINT7_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN22) +#define GPIO_EIC_EXTINT8_1 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN6) +#define GPIO_EIC_EXTINT8_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN23) + +/* Glue Logic Controller */ + +#define GPIO_GLOC_IN0_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN20) +#define GPIO_GLOC_IN0_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN6) +#define GPIO_GLOC_IN1_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN21) +#define GPIO_GLOC_IN1_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN4) +#define GPIO_GLOC_IN2_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN22) +#define GPIO_GLOC_IN2_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN5) +#define GPIO_GLOC_IN3_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN23) +#define GPIO_GLOC_IN3_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN7) +#define GPIO_GLOC_IN4_1 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN6) +#define GPIO_GLOC_IN4_2 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN28) +#define GPIO_GLOC_IN4_3 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN27) +#define GPIO_GLOC_IN4_4 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN15) +#define GPIO_GLOC_IN5_1 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN7) +#define GPIO_GLOC_IN5_2 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN29) +#define GPIO_GLOC_IN5_3 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN28) +#define GPIO_GLOC_IN5_4 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN16) +#define GPIO_GLOC_IN6_1 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN8) +#define GPIO_GLOC_IN6_2 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN30) +#define GPIO_GLOC_IN6_3 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN29) +#define GPIO_GLOC_IN6_4 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN17) +#define GPIO_GLOC_IN7_1 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN9) +#define GPIO_GLOC_IN7_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN30) +#define GPIO_GLOC_IN7_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN18) +#define GPIO_GLOC_OUT0_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN24) +#define GPIO_GLOC_OUT0_2 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN8) +#define GPIO_GLOC_OUT1_1 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN10) +#define GPIO_GLOC_OUT1_2 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN31) +#define GPIO_GLOC_OUT1_3 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN31) +#define GPIO_GLOC_OUT1_4 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN19) + +/* Inter-IC Sound (I2S) Controller */ + +#define GPIO_IISC_IMCK_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN31) +#define GPIO_IISC_IMCK_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN5) +#define GPIO_IISC_IMCK_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN14) +#define GPIO_IISC_ISCK_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN27) +#define GPIO_IISC_ISCK_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN2) +#define GPIO_IISC_ISCK_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN9) +#define GPIO_IISC_ISDI_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN28) +#define GPIO_IISC_ISDI_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN3) +#define GPIO_IISC_ISDI_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN10) +#define GPIO_IISC_ISDO_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN30) +#define GPIO_IISC_ISDO_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN4) +#define GPIO_IISC_ISDO_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN13) +#define GPIO_IISC_IWS_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN29) +#define GPIO_IISC_IWS_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN6) +#define GPIO_IISC_IWS_3 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN12) + +/* LCD Controller A */ + +#define GPIO_LCDCA_COM0 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN12) +#define GPIO_LCDCA_COM1 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN11) +#define GPIO_LCDCA_COM2 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN10) +#define GPIO_LCDCA_COM3 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN9) +#define GPIO_LCDCA_SEG0 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN15) +#define GPIO_LCDCA_SEG1 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN16) +#define GPIO_LCDCA_SEG2 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN17) +#define GPIO_LCDCA_SEG3 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN18) +#define GPIO_LCDCA_SEG4 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN19) +#define GPIO_LCDCA_SEG5 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN13) +#define GPIO_LCDCA_SEG6 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN14) +#define GPIO_LCDCA_SEG7 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN15) +#define GPIO_LCDCA_SEG8 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN16) +#define GPIO_LCDCA_SEG9 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN17) +#define GPIO_LCDCA_SEG10 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN20) +#define GPIO_LCDCA_SEG11 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN21) +#define GPIO_LCDCA_SEG12 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN22) +#define GPIO_LCDCA_SEG13 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN23) +#define GPIO_LCDCA_SEG14 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN8) +#define GPIO_LCDCA_SEG15 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN9) +#define GPIO_LCDCA_SEG16 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN10) +#define GPIO_LCDCA_SEG17 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN11) +#define GPIO_LCDCA_SEG18 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN18) +#define GPIO_LCDCA_SEG19 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN19) +#define GPIO_LCDCA_SEG20 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN20) +#define GPIO_LCDCA_SEG21 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN7) +#define GPIO_LCDCA_SEG22 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN6) +#define GPIO_LCDCA_SEG23 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN8) +#define GPIO_LCDCA_SEG24 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN24) +#define GPIO_LCDCA_SEG25 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN25) +#define GPIO_LCDCA_SEG26 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN26) +#define GPIO_LCDCA_SEG27 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN27) +#define GPIO_LCDCA_SEG28 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN28) +#define GPIO_LCDCA_SEG29 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN29) +#define GPIO_LCDCA_SEG30 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN30) +#define GPIO_LCDCA_SEG31 (GPIO_FUNCF | GPIO_PORTC | GPIO_PIN31) +#define GPIO_LCDCA_SEG32 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN12) +#define GPIO_LCDCA_SEG33 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN13) +#define GPIO_LCDCA_SEG34 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN21) +#define GPIO_LCDCA_SEG35 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN22) +#define GPIO_LCDCA_SEG36 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN14) +#define GPIO_LCDCA_SEG37 (GPIO_FUNCF | GPIO_PORTB | GPIO_PIN15) +#define GPIO_LCDCA_SEG38 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN23) +#define GPIO_LCDCA_SEG39 (GPIO_FUNCF | GPIO_PORTA | GPIO_PIN24) + +/* Parallel Capture */ + +#define GPIO_PARC_PCCK_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN17) +#define GPIO_PARC_PCCK_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN21) +#define GPIO_PARC_PCDATA0_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN9) +#define GPIO_PARC_PCDATA0_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN24) +#define GPIO_PARC_PCDATA1_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN10) +#define GPIO_PARC_PCDATA1_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN25) +#define GPIO_PARC_PCDATA2_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN11) +#define GPIO_PARC_PCDATA2_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN26) +#define GPIO_PARC_PCDATA3_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN12) +#define GPIO_PARC_PCDATA3_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN27) +#define GPIO_PARC_PCDATA4_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN13) +#define GPIO_PARC_PCDATA4_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN28) +#define GPIO_PARC_PCDATA5_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN14) +#define GPIO_PARC_PCDATA5_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN29) +#define GPIO_PARC_PCDATA6_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN15) +#define GPIO_PARC_PCDATA6_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN30) +#define GPIO_PARC_PCDATA7_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN16) +#define GPIO_PARC_PCDATA7_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN31) +#define GPIO_PARC_PCEN1_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN18) +#define GPIO_PARC_PCEN1_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN22) +#define GPIO_PARC_PCEN2_1 (GPIO_FUNCD | GPIO_PORTA | GPIO_PIN19) +#define GPIO_PARC_PCEN2_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN23) + +/* Peripheral Event Controller */ + +#define GPIO_PEVC_PAD_EVT0_1 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN8) +#define GPIO_PEVC_PAD_EVT0_2 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN12) +#define GPIO_PEVC_PAD_EVT0_3 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN24) +#define GPIO_PEVC_PAD_EVT0_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN7) +#define GPIO_PEVC_PAD_EVT1_1 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN9) +#define GPIO_PEVC_PAD_EVT1_2 (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN13) +#define GPIO_PEVC_PAD_EVT1_3 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN25) +#define GPIO_PEVC_PAD_EVT1_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN8) +#define GPIO_PEVC_PAD_EVT2_1 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN9) +#define GPIO_PEVC_PAD_EVT2_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN10) +#define GPIO_PEVC_PAD_EVT2_3 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN11) +#define GPIO_PEVC_PAD_EVT2_4 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN26) +#define GPIO_PEVC_PAD_EVT3_1 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN10) +#define GPIO_PEVC_PAD_EVT3_2 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN11) +#define GPIO_PEVC_PAD_EVT3_3 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN27) + +/* System Control Interface */ + +#define GPIO_SCIF_GCLK0_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN2) +#define GPIO_SCIF_GCLK0_2 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN19) +#define GPIO_SCIF_GCLK0_3 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN10) +#define GPIO_SCIF_GCLK0_4 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN26) +#define GPIO_SCIF_GCLK1_1 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN20) +#define GPIO_SCIF_GCLK1_2 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN11) +#define GPIO_SCIF_GCLK1_3 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN27) +#define GPIO_SCIF_GCLK2_1 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN12) +#define GPIO_SCIF_GCLK2_2 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN28) +#define GPIO_SCIF_GCLK3_1 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN13) +#define GPIO_SCIF_GCLK3_2 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN29) +#define GPIO_SCIF_GCLK_IN0_1 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN23) +#define GPIO_SCIF_GCLK_IN0_2 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN14) +#define GPIO_SCIF_GCLK_IN0_3 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN30) +#define GPIO_SCIF_GCLK_IN1_1 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN24) +#define GPIO_SCIF_GCLK_IN1_2 (GPIO_FUNCE | GPIO_PORTB | GPIO_PIN15) +#define GPIO_SCIF_GCLK_IN1_3 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN31) + +/* Serial Peripheral Interface */ + +#define GPIO_SPI0_MISO_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN21) +#define GPIO_SPI0_MISO_2 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN27) +#define GPIO_SPI0_MISO_3 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN4) +#define GPIO_SPI0_MISO_4 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN3) +#define GPIO_SPI0_MISO_5 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN14) +#define GPIO_SPI0_MISO_6 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN28) +#define GPIO_SPI0_MOSI_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN22) +#define GPIO_SPI0_MOSI_2 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN28) +#define GPIO_SPI0_MOSI_3 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN5) +#define GPIO_SPI0_MOSI_4 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN15) +#define GPIO_SPI0_MOSI_5 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN29) +#define GPIO_SPI0_NPCS0_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN24) +#define GPIO_SPI0_NPCS0_2 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN30) +#define GPIO_SPI0_NPCS0_3 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN3) +#define GPIO_SPI0_NPCS0_4 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN2) +#define GPIO_SPI0_NPCS0_5 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN2) +#define GPIO_SPI0_NPCS1_3 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN13) +#define GPIO_SPI0_NPCS1_4 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN13) +#define GPIO_SPI0_NPCS2_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN0) +#define GPIO_SPI0_NPCS2_2 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN11) +#define GPIO_SPI0_NPCS2_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN14) +#define GPIO_SPI0_NPCS3_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN1) +#define GPIO_SPI0_NPCS3_2 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN12) +#define GPIO_SPI0_NPCS3_3 (GPIO_FUNCC | GPIO_PORTA | GPIO_PIN15) +#define GPIO_SPI0_SPCK_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN23) +#define GPIO_SPI0_SPCK_2 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN29) +#define GPIO_SPI0_SPCK_3 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN6) +#define GPIO_SPI0_SPCK_4 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN30) + +/* Timer/Counters */ + +#define GPIO_TC0_A0_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN8) +#define GPIO_TC0_A0_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN7) +#define GPIO_TC0_A1_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN10) +#define GPIO_TC0_A1_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TC0_A2_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN12) +#define GPIO_TC0_A2_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN11) +#define GPIO_TC0_B0_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN9) +#define GPIO_TC0_B0_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TC0_B1_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN11) +#define GPIO_TC0_B1_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TC0_B2_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN13) +#define GPIO_TC0_B2_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TC0_CLK0_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN14) +#define GPIO_TC0_CLK0_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN13) +#define GPIO_TC0_CLK1_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN15) +#define GPIO_TC0_CLK1_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TC0_CLK2_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN16) +#define GPIO_TC0_CLK2_2 (GPIO_FUNCD | GPIO_PORTB | GPIO_PIN15) + +#define GPIO_TC1_A0_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN15) +#define GPIO_TC1_A0_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN0) +#define GPIO_TC1_A1_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN17) +#define GPIO_TC1_A1_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN2) +#define GPIO_TC1_A2_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN19) +#define GPIO_TC1_A2_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN4) +#define GPIO_TC1_B0_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN16) +#define GPIO_TC1_B0_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN1) +#define GPIO_TC1_B1_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN18) +#define GPIO_TC1_B1_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN3) +#define GPIO_TC1_B2_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN20) +#define GPIO_TC1_B2_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN5) +#define GPIO_TC1_CLK0_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN21) +#define GPIO_TC1_CLK0_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN6) +#define GPIO_TC1_CLK1_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN22) +#define GPIO_TC1_CLK1_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN7) +#define GPIO_TC1_CLK2_1 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN23) +#define GPIO_TC1_CLK2_2 (GPIO_FUNCD | GPIO_PORTC | GPIO_PIN8) + +/* Two-wire Master Interface */ + +#define GPIO_TWIM2_TWCK (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN22) +#define GPIO_TWIM2_TWD (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN21) +#define GPIO_TWIM3_TWCK (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN15) +#define GPIO_TWIM3_TWD (GPIO_FUNCC | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TWIMS0_TWCK (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN24) +#define GPIO_TWIMS0_TWD (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN23) +#define GPIO_TWIMS1_TWCK (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TWIMS1_TWD (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN0) + +/* USARTs */ + +#define GPIO_USART0_CLK_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN10) +#define GPIO_USART0_CLK_2 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN13) +#define GPIO_USART0_CLK_3 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN4) +#define GPIO_USART0_CLK_4 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN0) +#define GPIO_USART0_CTS_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN9) +#define GPIO_USART0_CTS_2 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN11) +#define GPIO_USART0_CTS_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN2) +#define GPIO_USART0_RTS_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN8) +#define GPIO_USART0_RTS_2 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN12) +#define GPIO_USART0_RTS_3 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN6) +#define GPIO_USART0_RTS_4 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN1) +#define GPIO_USART0_RXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USART0_RXD_2 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN14) +#define GPIO_USART0_RXD_3 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN5) +#define GPIO_USART0_RXD_4 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN0) +#define GPIO_USART0_RXD_5 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN2) +#define GPIO_USART0_TXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN12) +#define GPIO_USART0_TXD_2 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN15) +#define GPIO_USART0_TXD_3 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN7) +#define GPIO_USART0_TXD_4 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN1) +#define GPIO_USART0_TXD_5 (GPIO_FUNCC | GPIO_PORTC | GPIO_PIN3) + +#define GPIO_USART1_CLK_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN14) +#define GPIO_USART1_CLK_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN25) +#define GPIO_USART1_CLK_3 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN3) +#define GPIO_USART1_CTS (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN21) +#define GPIO_USART1_RTS_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN13) +#define GPIO_USART1_RTS_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN24) +#define GPIO_USART1_RTS_3 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN2) +#define GPIO_USART1_RXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN15) +#define GPIO_USART1_RXD_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN26) +#define GPIO_USART1_RXD_3 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN4) +#define GPIO_USART1_TXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN16) +#define GPIO_USART1_TXD_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN27) +#define GPIO_USART1_TXD_3 (GPIO_FUNCB | GPIO_PORTB | GPIO_PIN5) + +#define GPIO_USART2_CLK_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN18) +#define GPIO_USART2_CLK_2 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN8) +#define GPIO_USART2_CTS_1 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN22) +#define GPIO_USART2_CTS_2 (GPIO_FUNCE | GPIO_PORTC | GPIO_PIN8) +#define GPIO_USART2_RTS_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN17) +#define GPIO_USART2_RTS_2 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN7) +#define GPIO_USART2_RXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN19) +#define GPIO_USART2_RXD_2 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN25) +#define GPIO_USART2_RXD_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN11) +#define GPIO_USART2_TXD_1 (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN20) +#define GPIO_USART2_TXD_2 (GPIO_FUNCB | GPIO_PORTA | GPIO_PIN26) +#define GPIO_USART2_TXD_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN12) + +#define GPIO_USART3_CLK_1 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN8) +#define GPIO_USART3_CLK_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN31) +#define GPIO_USART3_CLK_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN14) +#define GPIO_USART3_CLK_4 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN29) +#define GPIO_USART3_CTS_1 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN7) +#define GPIO_USART3_CTS_2 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN28) +#define GPIO_USART3_RTS_1 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN6) +#define GPIO_USART3_RTS_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN30) +#define GPIO_USART3_RTS_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN13) +#define GPIO_USART3_RTS_4 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN27) +#define GPIO_USART3_RXD_1 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN9) +#define GPIO_USART3_RXD_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN28) +#define GPIO_USART3_RXD_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN9) +#define GPIO_USART3_RXD_4 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN30) +#define GPIO_USART3_TXD_1 (GPIO_FUNCA | GPIO_PORTB | GPIO_PIN10) +#define GPIO_USART3_TXD_2 (GPIO_FUNCA | GPIO_PORTC | GPIO_PIN29) +#define GPIO_USART3_TXD_3 (GPIO_FUNCB | GPIO_PORTC | GPIO_PIN10) +#define GPIO_USART3_TXD_4 (GPIO_FUNCE | GPIO_PORTA | GPIO_PIN31) + +/* USB 2.0 Interface */ + +#define GPIO_USBC_DM (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN25) +#define GPIO_USBC_DP (GPIO_FUNCA | GPIO_PORTA | GPIO_PIN26) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_pm.h b/arch/arm/src/sam34/chip/sam4l_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..86a55af8dc1404463bb0479c3869cb353a424f7c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_pm.h @@ -0,0 +1,351 @@ +/************************************************************************************ + * arch/avr/src/sam34/sam4l_pm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_pm.h. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define SAM_PM_MCCTRL_OFFSET 0x0000 /* Main Clock Control Register */ +#define SAM_PM_CPUSEL_OFFSET 0x0004 /* CPU Clock Select Register */ +#define SAM_PM_PBASEL_OFFSET 0x000c /* PBA Clock Select Register */ +#define SAM_PM_PBBSEL_OFFSET 0x0010 /* PBB Clock Select Register */ +#define SAM_PM_PBCSEL_OFFSET 0x0014 /* PBC Clock Select Register */ +#define SAM_PM_PBDSEL_OFFSET 0x0018 /* PBD Clock Select Register */ +#define SAM_PM_CPUMASK_OFFSET 0x0020 /* CPU Mask Register */ +#define SAM_PM_HSBMASK_OFFSET 0x0024 /* HSB Mask Register */ +#define SAM_PM_PBAMASK_OFFSET 0x0028 /* PBA Mask Register */ +#define SAM_PM_PBBMASK_OFFSET 0x002c /* PBB Mask Register */ +#define SAM_PM_PBCMASK_OFFSET 0x0030 /* PBC Mask Register */ +#define SAM_PM_PBDMASK_OFFSET 0x0034 /* PBD Mask Register */ +#define SAM_PM_PBADIVMASK_OFFSET 0x0040 /* PBA Divided Mask */ +#define SAM_PM_CFDCTRL_OFFSET 0x0054 /* Clock Failure Detector Control */ +#define SAM_PM_UNLOCK_OFFSET 0x0058 /* Unlock Register */ +#define SAM_PM_IER_OFFSET 0x00c0 /* Interrupt Enable Register */ +#define SAM_PM_IDR_OFFSET 0x00c4 /* Interrupt Disable Register */ +#define SAM_PM_IMR_OFFSET 0x00c8 /* Interrupt Mask Register */ +#define SAM_PM_ISR_OFFSET 0x00cc /* Interrupt Status Register */ +#define SAM_PM_ICR_OFFSET 0x00d0 /* Interrupt Clear Register */ +#define SAM_PM_SR_OFFSET 0x00d4 /* Status Register Register */ +#define SAM_PM_PPCR_OFFSET 0x0160 /* Peripheral Power Control Register */ +#define SAM_PM_RCAUSE_OFFSET 0x0180 /* Reset Cause Register */ +#define SAM_PM_WCAUSE_OFFSET 0x0184 /* Wake Cause Register */ +#define SAM_PM_AWEN_OFFSET 0x0188 /* Asynchronous Wake Up Enable Register */ +#define SAM_PM_PROTCTRL_OFFSET 0x018c /* Protection Control Register */ +#define SAM_PM_FASTSLEEP_OFFSET 0x0194 /* Fast Sleep Register */ +#define SAM_PM_CONFIG_OFFSET 0x03f8 /* Configuration Register */ +#define SAM_PM_VERSION_OFFSET 0x03fc /* Version Register */ + +/* Register Addresses ***************************************************************/ + +#define SAM_PM_MCCTRL (SAM_PM_BASE+SAM_PM_MCCTRL_OFFSET) +#define SAM_PM_CPUSEL (SAM_PM_BASE+SAM_PM_CPUSEL_OFFSET) +#define SAM_PM_PBASEL (SAM_PM_BASE+SAM_PM_PBASEL_OFFSET) +#define SAM_PM_PBBSEL (SAM_PM_BASE+SAM_PM_PBBSEL_OFFSET) +#define SAM_PM_PBCSEL (SAM_PM_BASE+SAM_PM_PBCSEL_OFFSET) +#define SAM_PM_PBDSEL (SAM_PM_BASE+SAM_PM_PBDSEL_OFFSET) +#define SAM_PM_CPUMASK (SAM_PM_BASE+SAM_PM_CPUMASK_OFFSET) +#define SAM_PM_HSBMASK (SAM_PM_BASE+SAM_PM_HSBMASK_OFFSET) +#define SAM_PM_PBAMASK (SAM_PM_BASE+SAM_PM_PBAMASK_OFFSET) +#define SAM_PM_PBBMASK (SAM_PM_BASE+SAM_PM_PBBMASK_OFFSET) +#define SAM_PM_PBCMASK (SAM_PM_BASE+SAM_PM_PBCMASK_OFFSET) +#define SAM_PM_PBDMASK (SAM_PM_BASE+SAM_PM_PBDMASK_OFFSET) +#define SAM_PM_PBADIVMASK (SAM_PM_BASE+SAM_PM_PBADIVMASK_OFFSET) +#define SAM_PM_CFDCTRL (SAM_PM_BASE+SAM_PM_CFDCTRL_OFFSET) +#define SAM_PM_UNLOCK (SAM_PM_BASE+SAM_PM_UNLOCK_OFFSET) +#define SAM_PM_IER (SAM_PM_BASE+SAM_PM_IER_OFFSET) +#define SAM_PM_IDR (SAM_PM_BASE+SAM_PM_IDR_OFFSET) +#define SAM_PM_IMR (SAM_PM_BASE+SAM_PM_IMR_OFFSET) +#define SAM_PM_ISR (SAM_PM_BASE+SAM_PM_ISR_OFFSET) +#define SAM_PM_ICR (SAM_PM_BASE+SAM_PM_ICR_OFFSET) +#define SAM_PM_SR (SAM_PM_BASE+SAM_PM_SR_OFFSET) +#define SAM_PM_PPCR (SAM_PM_BASE+SAM_PM_PPCR_OFFSET) +#define SAM_PM_RCAUSE (SAM_PM_BASE+SAM_PM_RCAUSE_OFFSET) +#define SAM_PM_WCAUSE (SAM_PM_BASE+SAM_PM_WCAUSE_OFFSET) +#define SAM_PM_AWEN (SAM_PM_BASE+SAM_PM_AWEN_OFFSET) +#define SAM_PM_PROTCTRL (SAM_PM_BASE+SAM_PM_PROTCTRL_OFFSET) +#define SAM_PM_FASTSLEEP (SAM_PM_BASE+SAM_PM_FASTSLEEP_OFFSET) +#define SAM_PM_CONFIG (SAM_PM_BASE+SAM_PM_CONFIG_OFFSET) +#define SAM_PM_VERSION (SAM_PM_BASE+SAM_PM_VERSION_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Main Clock Control Register Bit-field Definitions */ + +#define PM_MCCTRL_MCSEL_SHIFT (0) /* Bits 0-2: Main Clock Select */ +#define PM_MCCTRL_MCSEL_MASK (7 << PM_MCCTRL_MCSEL_SHIFT) +# define PM_MCCTRL_MCSEL_RCSYS (0 << PM_MCCTRL_MCSEL_SHIFT) /* System RC oscillator */ +# define PM_MCCTRL_MCSEL_OSC0 (1 << PM_MCCTRL_MCSEL_SHIFT) /* Oscillator0 */ +# define PM_MCCTRL_MCSEL_PLL (2 << PM_MCCTRL_MCSEL_SHIFT) /* PLL */ +# define PM_MCCTRL_MCSEL_DFLL (3 << PM_MCCTRL_MCSEL_SHIFT) /* DFLL */ +# define PM_MCCTRL_MCSEL_RC80M (4 << PM_MCCTRL_MCSEL_SHIFT) /* 80MHz RC oscillator */ +# define PM_MCCTRL_MCSEL_RCFAST (5 << PM_MCCTRL_MCSEL_SHIFT) /* 4/8/12 MHz RC oscillator */ +# define PM_MCCTRL_MCSEL_RC1M (6 << PM_MCCTRL_MCSEL_SHIFT) /* 1 MHz RC oscillator */ + +/* CPU Clock Select Register Bit-field Definitions */ + +#define PM_CPUSEL_SHIFT (0) /* Bits 0-2: CPU Clock Select */ +#define PM_CPUSEL_MASK (7 << PM_CPUSEL_SHIFT) +# define PM_CPUSEL(n) ((n) << PM_CPUSEL_SHIFT) +#define PM_CPUSEL_DIV (1 << 7) /* Bit 7: CPU Division */ + +/* PBA/PBB/PBC/PBD Clock Select Register Bit-field Definitions */ + +#define PM_PBSEL_SHIFT (0) /* Bits 0-2: PBx Clock Select */ +#define PM_PBSEL_MASK (7 << PM_PBSEL_SHIFT) +# define PM_PBSEL(n) ((n) << PM_PBSEL_SHIFT) +#define PM_PBSEL_DIV (1 << 7) /* Bit 7: PBx Division */ + +/* CPU Mask Register Bit-field Definitions */ + +#define PM_CPUMASK_OCD (1 << 0) /* Bit 0: On-Chip Debug */ + +/* HSB Mask Register Bit-field Definitions */ + +#define PM_HSBMASK_PDCA (1 << 0) /* Bit 0: PDCA */ +#define PM_HSBMASK_FLASHCALW (1 << 1) /* Bit 1: FLASHCALW */ +#define PM_HSBMASK_HRAMC1 (1 << 2) /* Bit 2: HRAMC1 (picoCache RAM) */ +#define PM_HSBMASK_USBC (1 << 3) /* Bit 3: USBC */ +#define PM_HSBMASK_CRCCU (1 << 4) /* Bit 4: CRCCU */ +#define PM_HSBMASK_APBA (1 << 5) /* Bit 5: APBA bridge */ +#define PM_HSBMASK_APBB (1 << 6) /* Bit 5: APBB bridge */ +#define PM_HSBMASK_APBC (1 << 7) /* Bit 5: APBC bridge */ +#define PM_HSBMASK_APBD (1 << 8) /* Bit 5: APBD bridge */ +#define PM_HSBMASK_AESA (1 << 9) /* Bit 5: AESA */ + +/* PBA Mask Register Bit-field Definitions */ + +#define PM_PBAMASK_IISC (1 << 0) /* Bit 0: IISC */ +#define PM_PBAMASK_SPI (1 << 1) /* Bit 1: SPI */ +#define PM_PBAMASK_TC0 (1 << 2) /* Bit 2: TC0 */ +#define PM_PBAMASK_TC1 (1 << 3) /* Bit 3: TC1 */ +#define PM_PBAMASK_TWIM0 (1 << 4) /* Bit 4: TWIM0 */ +#define PM_PBAMASK_TWIS0 (1 << 5) /* Bit 5: TWIS0 */ +#define PM_PBAMASK_TWIM1 (1 << 6) /* Bit 6: TWIM1 */ +#define PM_PBAMASK_TWIS1 (1 << 7) /* Bit 7: TWIS1 */ +#define PM_PBAMASK_USART0 (1 << 8) /* Bit 8: USART0 */ +#define PM_PBAMASK_USART1 (1 << 9) /* Bit 9: USART1 */ +#define PM_PBAMASK_USART2 (1 << 10) /* Bit 10: USART2 */ +#define PM_PBAMASK_USART3 (1 << 11) /* Bit 11: USART3 */ +#define PM_PBAMASK_ADCIFE (1 << 12) /* Bit 12: ADCIFE */ +#define PM_PBAMASK_DACC (1 << 13) /* Bit 13: DACC */ +#define PM_PBAMASK_ACIFC (1 << 14) /* Bit 14: ACIFC */ +#define PM_PBAMASK_GLOC (1 << 15) /* Bit 15: GLOC */ +#define PM_PBAMASK_ABDACB (1 << 16) /* Bit 16: ABDACB */ +#define PM_PBAMASK_TRNG (1 << 17) /* Bit 17: TRNG */ +#define PM_PBAMASK_PARC (1 << 18) /* Bit 18: PARC */ +#define PM_PBAMASK_CATB (1 << 19) /* Bit 19: CATB */ +#define PM_PBAMASK_TWIM2 (1 << 21) /* Bit 21: TWIM2 */ +#define PM_PBAMASK_TWIM3 (1 << 22) /* Bit 22: TWIM3 */ +#define PM_PBAMASK_LCDCA (1 << 23) /* Bit 23: LCDCA*/ + +/* These are the PBMA peripherals that use divided clocks enabled in the + * PBADIVMASK register. + */ + +#define PM_PBAMASK_TIMERS (PM_PBAMASK_TC0 | PM_PBAMASK_TC1) +#define PM_PBAMASK_UARTS (PM_PBAMASK_USART0 | PM_PBAMASK_USART1 | \ + PM_PBAMASK_USART2 | PM_PBAMASK_USART3) + +/* PBB Mask Register Bit-field Definitions */ + +#define PM_PBBMASK_FLASHCALW (1 << 0) /* Bit 0: FLASHCALW */ +#define PM_PBBMASK_HRAMC1 (1 << 1) /* Bit 1: HRAMC1 */ +#define PM_PBBMASK_HMATRIX (1 << 2) /* Bit 2: HMATRIX */ +#define PM_PBBMASK_PDCA (1 << 3) /* Bit 3: PDCA */ +#define PM_PBBMASK_CRCCU (1 << 4) /* Bit 4: CRCCU */ +#define PM_PBBMASK_USBC (1 << 5) /* Bit 5: USBC */ +#define PM_PBBMASK_PEVC (1 << 6) /* Bit 6: PEVC */ + +/* PBC Mask Register Bit-field Definitions */ + +#define PM_PBCMASK_PM (1 << 0) /* Bit 0: PM */ +#define PM_PBCMASK_CHIPID (1 << 1) /* Bit 1: CHIPID */ +#define PM_PBCMASK_SCIF (1 << 2) /* Bit 2: SCIF */ +#define PM_PBCMASK_FREQM (1 << 3) /* Bit 3: FREQM */ +#define PM_PBCMASK_GPIO (1 << 4) /* Bit 4: GPIO */ + +/* PBD Mask Register Bit-field Definitions */ + +#define PM_PBDMASK_BPM (1 << 0) /* Bit 0: BPM */ +#define PM_PBDMASK_BSCIF (1 << 1) /* Bit 1: BSCIF */ +#define PM_PBDMASK_AST (1 << 2) /* Bit 2: AST */ +#define PM_PBDMASK_WDT (1 << 3) /* Bit 3: WDT */ +#define PM_PBDMASK_EIC (1 << 4) /* Bit 4: EIC */ +#define PM_PBDMASK_PICOUART (1 << 5) /* Bit 5: PICOUART */ + +/* PBA Divided Mask */ + +#define PM_PBADIVMASK_TIMER_CLOCK2 (1 << 0) /* Bit 0: TIMER_CLOCK2 (TC0-1) */ +#define PM_PBADIVMASK_CLK_USART (1 << 2) /* Bit 2: CLK_USART/DIV (USART0-3) */ +#define PM_PBADIVMASK_TIMER_CLOCK3 (1 << 2) /* Bit 2: TIMER_CLOCK3 (TC0-1) */ +#define PM_PBADIVMASK_TIMER_CLOCK4 (1 << 4) /* Bit 4: TIMER_CLOCK4 (TC0-1) */ +#define PM_PBADIVMASK_TIMER_CLOCK5 (1 << 6) /* Bit 5: TIMER_CLOCK5 (TC0-1) */ + +#define PM_PBADIVMASK_TIMER_CLOCKS \ + (PM_PBADIVMASK_TIMER_CLOCK2 | PM_PBADIVMASK_TIMER_CLOCK3 | \ + PM_PBADIVMASK_TIMER_CLOCK4 | PM_PBADIVMASK_TIMER_CLOCK5) + +/* Clock Failure Detector Control */ + +#define PM_CFDCTRL_CFDEN (1 << 0) /* Bit 0: Clock Failure Detection Enable */ +#define PM_CFDCTRL_SFV (1 << 31) /* Bit 31: Store Final Value */ + +/* Unlock Register */ + +#define PM_UNLOCK_ADDR_SHIFT (0) /* Bits 0-9: Unlock Address */ +#define PM_UNLOCK_ADDR_MASK (0x3ff << PM_UNLOCK_ADDR_SHIFT) +# define PM_UNLOCK_ADDR(n) ((n) << PM_UNLOCK_ADDR_SHIFT) +#define PM_UNLOCK_KEY_SHIFT (24) /* Bits 24-31: Unlock Key */ +#define PM_UNLOCK_KEY_MASK (0xff << PM_UNLOCK_KEY_SHIFT) +# define PM_UNLOCK_KEY(n) ((n) << PM_UNLOCK_KEY_SHIFT) + +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ +/* Interrupt Status Register Bit-field Definitions */ +/* Interrupt Clear Register Bit-field Definitions */ +/* Status Register Register */ + +#define PM_INT_CFD (1 << 0) /* Bit 0: CFD */ +#define PM_INT_CKRDY (1 << 5) /* Bit 5: CKRDY */ +#define PM_INT_WAKE (1 << 8) /* Bit 8: WAKE */ + +/* Peripheral Power Control Register */ + +#define PM_PPCR_RSTPUN (1 << 0) /* Bit 0: Reset Pullup */ +#define PM_PPCR_CATBRCMASK (1 << 1) /* Bit 1: CAT Request Clock Mask */ +#define PM_PPCR_ACIFCRCMASK (1 << 2) /* Bit 2: ACIFC Request Clock Mask */ +#define PM_PPCR_ASTRCMASK (1 << 3) /* Bit 3: AST Request Clock Mask */ +#define PM_PPCR_TWIS0RCMASK (1 << 4) /* Bit 4: TWIS0 Request Clock Mask */ +#define PM_PPCR_TWIS1RCMASK (1 << 5) /* Bit 5: TWIS1 Request Clock Mask */ +#define PM_PPCR_PEVCRCMASK (1 << 6) /* Bit 6: PEVC Request Clock Mask */ +#define PM_PPCR_ADCIFERCMASK (1 << 7) /* Bit 7: ADCIFE Request Clock Mask */ +#define PM_PPCR_VREGRCMASK (1 << 8) /* Bit 8: VREG Request Clock Mask */ +#define PM_PPCR_FWBGREF (1 << 9) /* Bit 9: Flash Wait BGREF */ +#define PM_PPCR_FWBOD18 (1 << 10) /* Bit 10: Flash Wait BOD18 */ + +/* Reset Cause Register */ + +#define PM_RCAUSE_POR (1 << 0) /* Bit 0: Power-on Reset */ +#define PM_RCAUSE_BOD (1 << 1) /* Bit 1: Brown-out Reset */ +#define PM_RCAUSE_EXT (1 << 2) /* Bit 2: External Reset Pin */ +#define PM_RCAUSE_WDT (1 << 3) /* Bit 3: Watchdog Reset */ +#define PM_RCAUSE_BKUP (1 << 6) /* Bit 6: Backup reset */ +#define PM_RCAUSE_OCDRST (1 << 8) /* Bit 8: OCD Reset */ +#define PM_RCAUSE_POR33 (1 << 10) /* Bit 10: Power-on 3.3v Reset */ +#define PM_RCAUSE_BOD33 (1 << 13) /* Bit 13: Brown-out 3.3v Reset */ + +/* Wake Cause Register */ + +#define PM_WCAUSE_TWIS0 (1 << 0) /* Bit 0: 0 TWI Slave 0 */ +#define PM_WCAUSE_TWIS1 (1 << 1) /* Bit 1: 1 TWI Slave 1 */ +#define PM_WCAUSE_USBC (1 << 2) /* Bit 2: 2 USBC */ +#define PM_WCAUSE_PSOK (1 << 3) /* Bit 3: 3 PSOK */ +#define PM_WCAUSE_BOD18 (1 << 4) /* Bit 4: 4 BOD18 IRQ */ +#define PM_WCAUSE_BOD33 (1 << 5) /* Bit 5: 5 BOD33 IRQ */ +#define PM_WCAUSE_PICOUART (1 << 6) /* Bit 6: 6 PICOUART */ +#define PM_WCAUSE_LCDCA (1 << 7) /* Bit 7: 7 LCDCA */ +#define PM_WCAUSE_EIC (1 << 16) /* Bit 16: 16 EIC */ +#define PM_WCAUSE_AST (1 << 17) /* Bit 17: 17 AST */ + +/* Asynchronous Wake Up Enable Register Bit-field Definitions */ + +#define PM_AWEN_TWIS0 (1 << 0) /* Bit 0: TWI Slave 0 */ +#define PM_AWEN_TWIS1 (1 << 1) /* Bit 1: TWI Slave 1 */ +#define PM_AWEN_USBC (1 << 2) /* Bit 2: USBC */ +#define PM_AWEN_PSOK (1 << 3) /* Bit 3: PSOK */ +#define PM_AWEN_BOD18 (1 << 4) /* Bit 4: BOD18 IRQ */ +#define PM_AWEN_BOD33 (1 << 5) /* Bit 5: BOD33 IRQ */ +#define PM_AWEN_PICOUART (1 << 6) /* Bit 6: PICOUART */ +#define PM_AWEN_LCDCA (1 << 7) /* Bit 7: LCDCA */ + +/* Protection Control Register */ + +/* Fast Sleep Register */ +#define PM_FASTSLEEP_ +#define PM_FASTSLEEP_OSC (1 << 0) /* Bit 0: Oscillator */ +#define PM_FASTSLEEP_PLL (1 << 0) /* Bit 0: PLL */ +#define PM_FASTSLEEP_FASTRCOSC_SHIFT (0) /* Bits 0-9: FASTRCOSC */ +#define PM_FASTSLEEP_FASTRCOSC_MASK (31 << PM_FASTSLEEP_FASTRCOSC_SHIFT) +# define PM_FASTSLEEP_RC80 (1 << PM_FASTSLEEP_FASTRCOSC_SHIFT) +# define PM_FASTSLEEP_RCFAST (2 << PM_FASTSLEEP_FASTRCOSC_SHIFT) +# define PM_FASTSLEEP_RC1M (4 << PM_FASTSLEEP_FASTRCOSC_SHIFT) +#define PM_FASTSLEEP_DFLL (1 << 0) /* Bit 0: DFLL */ + +/* Configuration Register */ + +#define PM_CONFIG_PBA (1 << 0) /* Bit 0: APBA Implemented */ +#define PM_CONFIG_PBB (1 << 1) /* Bit 1: APBB Implemented */ +#define PM_CONFIG_PBC (1 << 2) /* Bit 2: APBC Implemented */ +#define PM_CONFIG_PBD (1 << 3) /* Bit 3: APBD Implemented */ +#define PM_CONFIG_HSBPEVC (1 << 7) /* Bit 7: HSB PEVC Clock Implemented */ + +/* Version Register */ + +#define PM_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define PM_VERSION_MASK (0xfff << PM_VERSION_VERSION_SHIFT) +#define PM_VERSION_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define PM_VERSION_VARIANT_MASK (15 << PM_VERSION_VARIANT_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H */ + diff --git a/arch/arm/src/sam34/chip/sam4l_scif.h b/arch/arm/src/sam34/chip/sam4l_scif.h new file mode 100644 index 0000000000000000000000000000000000000000..191d786bc3ff965fa112aebcf85ba878378cafd5 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_scif.h @@ -0,0 +1,432 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_scif.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_SCIF_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_SCIF_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SCIF register offsets ****************************************************************/ + +#define SAM_SCIF_IER_OFFSET 0x0000 /* Interrupt Enable Register */ +#define SAM_SCIF_IDR_OFFSET 0x0004 /* Interrupt Disable Register */ +#define SAM_SCIF_IMR_OFFSET 0x0008 /* Interrupt Mask Register */ +#define SAM_SCIF_ISR_OFFSET 0x000c /* Interrupt Status Register */ +#define SAM_SCIF_ICR_OFFSET 0x0010 /* Interrupt Clear Register */ +#define SAM_SCIF_PCLKSR_OFFSET 0x0014 /* Power and Clocks Status Register */ +#define SAM_SCIF_UNLOCK_OFFSET 0x0018 /* Unlock Register */ +#define SAM_SCIF_CSCR_OFFSET 0x001c /* Chip Specific Configuration Register */ +#define SAM_SCIF_OSCCTRL0_OFFSET 0x0020 /* Oscillator Control Register */ +#define SAM_SCIF_PLL0_OFFSET 0x0024 /* PLL0 Control Register */ +#define SAM_SCIF_DFLL0CONF_OFFSET 0x0028 /* DFLL0 Config Register */ +#define SAM_SCIF_DFLL0VAL_OFFSET 0x002c /* DFLL Value Register */ +#define SAM_SCIF_DFLL0MUL_OFFSET 0x0030 /* DFLL0 Multiplier Register */ +#define SAM_SCIF_DFLL0STEP_OFFSET 0x0034 /* DFLL0 Step Register */ +#define SAM_SCIF_DFLL0SSG_OFFSET 0x0038 /* DFLL0 Spread Spectrum Generator Control Register */ +#define SAM_SCIF_DFLL0RATIO_OFFSET 0x003c /* DFLL0 Ratio Register */ +#define SAM_SCIF_DFLL0SYNC_OFFSET 0x0040 /* DFLL0 Synchronization Register */ +#define SAM_SCIF_RCCR_OFFSET 0x0044 /* System RC Oscillator Calibration Register */ +#define SAM_SCIF_RCFASTCFG_OFFSET 0x0048 /* 4/8/12MHz RC Oscillator Configuration Register */ +#define SAM_SCIF_RCFASTSR_OFFSET 0x004c /* 4/8/12MHz RC Oscillator Status Register */ +#define SAM_SCIF_RC80MCR_OFFSET 0x0050 /* 80MHz RC Oscillator Register */ +#define SAM_SCIF_HRPCR_OFFSET 0x0064 /* High Resolution Prescaler Control Register */ +#define SAM_SCIF_FPCR_OFFSET 0x0068 /* Fractional Prescaler Control Register */ +#define SAM_SCIF_FPMUL_OFFSET 0x006c /* Fractional Prescaler Multiplier Register */ +#define SAM_SCIF_FPDIV_OFFSET 0x0070 /* Fractional Prescaler DIVIDER Register */ +#define SAM_SCIF_GCCTRL0_OFFSET 0x0074 /* Generic Clock Control0 */ +#define SAM_SCIF_GCCTRL1_OFFSET 0x0078 /* Generic Clock Control1 */ +#define SAM_SCIF_GCCTRL2_OFFSET 0x007c /* Generic Clock Control2 */ +#define SAM_SCIF_GCCTRL3_OFFSET 0x0080 /* Generic Clock Control3 */ +#define SAM_SCIF_GCCTRL4_OFFSET 0x0084 /* Generic Clock Control4 */ +#define SAM_SCIF_GCCTRL5_OFFSET 0x0088 /* Generic Clock Control5 */ +#define SAM_SCIF_GCCTRL6_OFFSET 0x008c /* Generic Clock Control6 */ +#define SAM_SCIF_GCCTRL7_OFFSET 0x0090 /* Generic Clock Control7 */ +#define SAM_SCIF_GCCTRL8_OFFSET 0x0094 /* Generic Clock Control8 */ +#define SAM_SCIF_GCCTRL9_OFFSET 0x0098 /* Generic Clock Control9 */ +#define SAM_SCIF_GCCTRL10_OFFSET 0x009c /* Generic Clock Control10 */ +#define SAM_SCIF_GCCTRL11_OFFSET 0x00a0 /* Generic Clock Control11 */ +#define SAM_SCIF_RCFASTVERSION_OFFSET 0x03d8 /* 4/8/12MHz RC Oscillator Version Register */ +#define SAM_SCIF_GCLKPRESCVERSION_OFFSET 0x03dc /* Generic Clock Prescaler Version Register */ +#define SAM_SCIF_PLLIFAVERSION_OFFSET 0x03e0 /* PLL Version Register */ +#define SAM_SCIF_OSCIFAVERSION_OFFSET 0x03e4 /* Oscillator0 Version Register */ +#define SAM_SCIF_DFLLIFBVERSION_OFFSET 0x03e8 /* DFLL Version Register */ +#define SAM_SCIF_RCOSCIFAVERSION_OFFSET 0x03ec /* System RC Oscillator Version Register */ +#define SAM_SCIF_RC80MVERSION_OFFSET 0x03f4 /* 80MHz RC Oscillator Version Register */ +#define SAM_SCIF_GCLKVERSION_OFFSET 0x03f8 /* Generic Clock Version Register */ +#define SAM_SCIF_VERSION_OFFSET 0x03fc /* SCIF Version Register */ + +/* SCIF register addresses **************************************************************/ + +#define SAM_SCIF_IER (SAM_SCIF_BASE+SAM_SCIF_IER_OFFSET) +#define SAM_SCIF_IDR (SAM_SCIF_BASE+SAM_SCIF_IDR_OFFSET) +#define SAM_SCIF_IMR (SAM_SCIF_BASE+SAM_SCIF_IMR_OFFSET) +#define SAM_SCIF_ISR (SAM_SCIF_BASE+SAM_SCIF_ISR_OFFSET) +#define SAM_SCIF_ICR (SAM_SCIF_BASE+SAM_SCIF_ICR_OFFSET) +#define SAM_SCIF_PCLKSR (SAM_SCIF_BASE+SAM_SCIF_PCLKSR_OFFSET) +#define SAM_SCIF_UNLOCK (SAM_SCIF_BASE+SAM_SCIF_UNLOCK_OFFSET) +#define SAM_SCIF_CSCR (SAM_SCIF_BASE+SAM_SCIF_CSCR_OFFSET) +#define SAM_SCIF_OSCCTRL0 (SAM_SCIF_BASE+SAM_SCIF_OSCCTRL0_OFFSET) +#define SAM_SCIF_PLL0 (SAM_SCIF_BASE+SAM_SCIF_PLL0_OFFSET) +#define SAM_SCIF_DFLL0CONF (SAM_SCIF_BASE+SAM_SCIF_DFLL0CONF_OFFSET) +#define SAM_SCIF_DFLL0VAL (SAM_SCIF_BASE+SAM_SCIF_DFLL0VAL_OFFSET) +#define SAM_SCIF_DFLL0MUL (SAM_SCIF_BASE+SAM_SCIF_DFLL0MUL_OFFSET) +#define SAM_SCIF_DFLL0STEP (SAM_SCIF_BASE+SAM_SCIF_DFLL0STEP_OFFSET) +#define SAM_SCIF_DFLL0SSG (SAM_SCIF_BASE+SAM_SCIF_DFLL0SSG_OFFSET) +#define SAM_SCIF_DFLL0RATIO (SAM_SCIF_BASE+SAM_SCIF_DFLL0RATIO_OFFSET) +#define SAM_SCIF_DFLL0SYNC (SAM_SCIF_BASE+SAM_SCIF_DFLL0SYNC_OFFSET) +#define SAM_SCIF_RCCR (SAM_SCIF_BASE+SAM_SCIF_RCCR_OFFSET) +#define SAM_SCIF_RCFASTCFG (SAM_SCIF_BASE+SAM_SCIF_RCFASTCFG_OFFSET) +#define SAM_SCIF_RCFASTSR (SAM_SCIF_BASE+SAM_SCIF_RCFASTSR_OFFSET) +#define SAM_SCIF_RC80MCR (SAM_SCIF_BASE+SAM_SCIF_RC80MCR_OFFSET) +#define SAM_SCIF_HRPCR (SAM_SCIF_BASE+SAM_SCIF_HRPCR_OFFSET) +#define SAM_SCIF_FPCR (SAM_SCIF_BASE+SAM_SCIF_FPCR_OFFSET) +#define SAM_SCIF_FPMUL (SAM_SCIF_BASE+SAM_SCIF_FPMUL_OFFSET) +#define SAM_SCIF_FPDIV (SAM_SCIF_BASE+SAM_SCIF_FPDIV_OFFSET) +#define SAM_SCIF_GCCTRL0 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL0_OFFSET) +#define SAM_SCIF_GCCTRL1 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL1_OFFSET) +#define SAM_SCIF_GCCTRL2 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL2_OFFSET) +#define SAM_SCIF_GCCTRL3 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL3_OFFSET) +#define SAM_SCIF_GCCTRL4 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL4_OFFSET) +#define SAM_SCIF_GCCTRL5 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL5_OFFSET) +#define SAM_SCIF_GCCTRL6 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL6_OFFSET) +#define SAM_SCIF_GCCTRL7 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL7_OFFSET) +#define SAM_SCIF_GCCTRL8 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL8_OFFSET) +#define SAM_SCIF_GCCTRL9 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL9_OFFSET) +#define SAM_SCIF_GCCTRL10 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL10_OFFSET) +#define SAM_SCIF_GCCTRL11 (SAM_SCIF_BASE+SAM_SCIF_GCCTRL11_OFFSET) +#define SAM_SCIF_RCFASTVERSION (SAM_SCIF_BASE+SAM_SCIF_RCFASTVERSION_OFFSET) +#define SAM_SCIF_GCLKPRESCVERSION (SAM_SCIF_BASE+SAM_SCIF_GCLKPRESCVERSION_OFFSET) +#define SAM_SCIF_PLLIFAVERSION (SAM_SCIF_BASE+SAM_SCIF_PLLIFAVERSION_OFFSET) +#define SAM_SCIF_OSCIFAVERSION (SAM_SCIF_BASE+SAM_SCIF_OSCIFAVERSION_OFFSET) +#define SAM_SCIF_DFLLIFBVERSION (SAM_SCIF_BASE+SAM_SCIF_DFLLIFBVERSION_OFFSET) +#define SAM_SCIF_RCOSCIFAVERSION (SAM_SCIF_BASE+SAM_SCIF_RCOSCIFAVERSION_OFFSET) +#define SAM_SCIF_RC80MVERSION (SAM_SCIF_BASE+SAM_SCIF_RC80MVERSION_OFFSET) +#define SAM_SCIF_GCLKVERSION (SAM_SCIF_BASE+SAM_SCIF_GCLKVERSION_OFFSET) +#define SAM_SCIF_VERSION (SAM_SCIF_BASE+SAM_SCIF_VERSION_OFFSET) + +/* SCIF register bit definitions ********************************************************/ + +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ +/* Interrupt Status Register */ +/* Interrupt Clear Register */ +/* Power and Clocks Status Register */ + +#define SCIF_INT_OSC0RDY (1 << 0) /* Bit 0: OSC0 Ready */ +#define SCIF_INT_DFLL0LOCKC (1 << 1) /* Bit 1: DFLL0 Locked on Coarse Value */ +#define SCIF_INT_DFLL0LOCKF (1 << 2) /* Bit 2: DFLL0 Locked on Fine Value */ +#define SCIF_INT_DFLL0RDY (1 << 3) /* Bit 3: DFLL0 Synchronization Ready */ +#define SCIF_INT_DFLL0RCS (1 << 4) /* Bit 4: DFLL0 Reference Clock Stopped */ +#define SCIF_INT_PLL0LOCK (1 << 6) /* Bit 6: PLL0 Locked on Accurate value */ +#define SCIF_INT_PLL0LOCKLOST (1 << 7) /* Bit 7: PLL0 lock lost value */ +#define SCIF_INT_RCFASTLOCK (1 << 13) /* Bit 13: RCFAST Locked on Accurate value */ +#define SCIF_INT_RCFASTLOCKLOST (1 << 14) /* Bit 14: RCFAST lock lost value */ + +/* Unlock Register */ + +#define SCIF_UNLOCK_ADDR_SHIFT (0) /* Bits 0-9: Unlock Address */ +#define SCIF_UNLOCK_ADDR_MASK (0x3ff << SCIF_UNLOCK_ADDR_SHIFT) +# define SCIF_UNLOCK_ADDR(n) ((n) << SCIF_UNLOCK_ADDR_SHIFT) +#define SCIF_UNLOCK_KEY_SHIFT (24) /* Bits 24-31: Unlock Key */ +#define SCIF_UNLOCK_KEY_MASK (0xff << SCIF_UNLOCK_KEY_SHIFT) +# define SCIF_UNLOCK_KEY(n) ((n) << SCIF_UNLOCK_KEY_SHIFT) + +/* Chip Specific Configuration Register */ + +/* Oscillator Control Register */ + +#define SCIF_OSCCTRL0_MODE (1 << 0) /* Bit 0: Oscillator Mode */ +#define SCIF_OSCCTRL0_GAIN_SHIFT (1) /* Bits 1-2: Gain */ +#define SCIF_OSCCTRL0_GAIN_MASK (3 << SCIF_OSCCTRL0_GAIN_SHIFT) +# define SCIF_OSCCTRL0_GAIN(n) ((n) << SCIF_OSCCTRL0_GAIN_SHIFT) +#define SCIF_OSCCTRL0_AGC (1 << 3) /* Bit 3: Automatic Gain Control */ +#define SCIF_OSCCTRL0_STARTUP_SHIFT (9) /* Bits 8-11: Oscillator Start-up Time */ +#define SCIF_OSCCTRL0_STARTUP_MASK (15 << SCIF_OSCCTRL0_STARTUP_SHIFT) +# define SCIF_OSCCTRL0_STARTUP_0 (0 << SCIF_OSCCTRL0_STARTUP_SHIFT) +# define SCIF_OSCCTRL0_STARTUP_64 (1 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 64 557 us */ +# define SCIF_OSCCTRL0_STARTUP_128 (2 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 128 1.1 ms */ +# define SCIF_OSCCTRL0_STARTUP_2K (3 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 2048 18 ms */ +# define SCIF_OSCCTRL0_STARTUP_4K (4 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 4096 36 ms */ +# define SCIF_OSCCTRL0_STARTUP_8K (5 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 8192 71 ms */ +# define SCIF_OSCCTRL0_STARTUP_16K (6 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 16384 143 ms */ +# define SCIF_OSCCTRL0_STARTUP_32K (7 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 32768 285 ms */ +# define SCIF_OSCCTRL0_STARTUP_4 (8 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 4 35 us */ +# define SCIF_OSCCTRL0_STARTUP_8 (9 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 8 70 us */ +# define SCIF_OSCCTRL0_STARTUP_16 (10 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 16 139 us */ +# define SCIF_OSCCTRL0_STARTUP_32 (11 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 32 278 us */ +# define SCIF_OSCCTRL0_STARTUP_256 (12 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 256 2.2 ms */ +# define SCIF_OSCCTRL0_STARTUP_512 (13 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 512 4.5 ms */ +# define SCIF_OSCCTRL0_STARTUP_1K (14 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 1024 8.9 ms */ +# define SCIF_OSCCTRL0_STARTUP_32K2 (15 << SCIF_OSCCTRL0_STARTUP_SHIFT) /* 2768 285 ms */ +#define SCIF_OSCCTRL0_OSCEN (1 << 16) /* Bit 16: Oscillator Enable */ + +/* PLL0 Control Register */ + +#define SCIF_PLL0_PLLEN (1 << 0) /* Bit 0: PLL Enable */ +#define SCIF_PLL0_PLLOSC_SHIFT (1) /* Bits 1-2: PLL Oscillator Select */ +#define SCIF_PLL0_PLLOSC_MASK (3 << SCIF_PLL0_PLLOSC_SHIFT) +# define SCIF_PLL0_PLLOSC_OSC0 (0 << SCIF_PLL0_PLLOSC_SHIFT) /* Output clock from Oscillator0 */ +# define SCIF_PLL0_PLLOSC_GCLK9 (1 << SCIF_PLL0_PLLOSC_SHIFT) /* Generic clock 9 */ +#define SCIF_PLL0_PLLOPT_SHIFT (3) /* Bits 3-5: PLL Option */ +#define SCIF_PLL0_PLLOPT_MASK (7 << SCIF_PLL0_PLLOPT_SHIFT) +# define SCIF_PLL0_PLLOPT_FVO (1 << SCIF_PLL0_PLLOPT_SHIFT) /* Selects the VCO frequency range (fvco) */ +# define SCIF_PLL0_PLLOPT_DIV2 (2 << SCIF_PLL0_PLLOPT_SHIFT) /* Divides the output frequency by 2 */ +# define SCIF_PLL0_PLLOPT_WBM (4 << SCIF_PLL0_PLLOPT_SHIFT) /* Wide-Bandwidth mode */ +#define SCIF_PLL0_PLLDIV_SHIFT (8) /* Bits 8-11: PLL Division Factor */ +#define SCIF_PLL0_PLLDIV_MASK (15 << SCIF_PLL0_PLLDIV_SHIFT) +#define SCIF_PLL0_PLLMUL_SHIFT (16) /* Bits 16-19: PLL Multiply Factor */ +#define SCIF_PLL0_PLLMUL_MASK (15 << SCIF_PLL0_PLLMUL_SHIFT) +#define SCIF_PLL0_PLLCOUNT_SHIFT (24) /* Bits 24-24: PLL Count */ +#define SCIF_PLL0_PLLCOUNT_MASK (63 << SCIF_PLL0_PLLCOUNT_SHIFT) +# define SCIF_PLL0_PLLCOUNT_MAX (63 << SCIF_PLL0_PLLCOUNT_SHIFT) + +/* PLL0 operates in two frequency ranges as determined by SCIF_PLL0_PLLOPT_FVO: + * + * 0: 80MHz < fvco < 180MHz + * 1: 160MHz < fvco < 240MHz + * + * These ranges and recommend threshold value are defined below: + */ + +#define SCIF_PLL0_VCO_RANGE1_MINFREQ 160000000 +#define SCIF_PLL0_VCO_RANGE1_MAXFREQ 240000000 +#define SCIF_PLL0_VCO_RANGE0_MINFREQ 80000000 +#define SCIF_PLL0_VCO_RANGE0_MAXFREQ 180000000 + +#define SAM_PLL0_VCO_RANGE_THRESHOLD \ + ((SCIF_PLL0_VCO_RANGE1_MINFREQ + SCIF_PLL0_VCO_RANGE0_MAXFREQ) >> 1) + +/* DFLL0 Config Register */ + +#define SCIF_DFLL0CONF_EN (1 << 0) /* Bit 0: Enable */ +#define SCIF_DFLL0CONF_MODE (1 << 1) /* Bit 1: Mode Selection */ +#define SCIF_DFLL0CONF_STABLE (1 << 2) /* Bit 2: Stable DFLL Frequency */ +#define SCIF_DFLL0CONF_LLAW (1 << 3) /* Bit 3: Lose Lock After Wake */ +#define SCIF_DFLL0CONF_CCDIS (1 << 5) /* Bit 5: Chill Cycle Disable */ +#define SCIF_DFLL0CONF_QLDIS (1 << 6) /* Bit 6: Quick Lock Disable */ +#define SCIF_DFLL0CONF_RANGE_SHIFT (16) /* Bits 16-17: Range Value */ +#define SCIF_DFLL0CONF_RANGE_MASK (3 << SCIF_DFLL0CONF_RANGE_SHIFT) +# define SCIF_DFLL0CONF_RANGE(n) ((n) << SCIF_DFLL0CONF_RANGE_SHIFT) +# define SCIF_DFLL0CONF_RANGE0 (0 << SCIF_DFLL0CONF_RANGE_SHIFT) /* 96-150MHz */ +# define SCIF_DFLL0CONF_RANGE1 (1 << SCIF_DFLL0CONF_RANGE_SHIFT) /* 50-110MHz */ +# define SCIF_DFLL0CONF_RANGE2 (2 << SCIF_DFLL0CONF_RANGE_SHIFT) /* 25-55MHz */ +# define SCIF_DFLL0CONF_RANGE3 (3 << SCIF_DFLL0CONF_RANGE_SHIFT) /* 20-30MHz */ +#define SCIF_DFLL0CONF_FCD (1 << 23) /* Bit 23: Fuse Calibration Done */ +#define SCIF_DFLL0CONF_CALIB_SHIFT (24) /* Bits 24-27: Calibration Value */ +#define SCIF_DFLL0CONF_CALIB_MASK (15 << SCIF_DFLL0CONF_CALIB_SHIFT) + +/* Min/max frequencies for each DFLL0 range */ + +#define SCIF_DFLL0CONF_MAX_RANGE0 (150000000) +#define SCIF_DFLL0CONF_MIN_RANGE0 (96000000) +#define SCIF_DFLL0CONF_MAX_RANGE1 (110000000) +#define SCIF_DFLL0CONF_MIN_RANGE1 (50000000) +#define SCIF_DFLL0CONF_MAX_RANGE2 (55000000) +#define SCIF_DFLL0CONF_MIN_RANGE2 (25000000) +#define SCIF_DFLL0CONF_MAX_RANGE3 (30000000) +#define SCIF_DFLL0CONF_MIN_RANGE3 (20000000) + +/* DFLL Value Register */ + +#define SCIF_DFLL0VAL_FINE_SHIFT (0) /* Bits 0-7: Fine Value */ +#define SCIF_DFLL0VAL_FINE_MASK (0xff << SCIF_DFLL0VAL_FINE_SHIFT) +#define SCIF_DFLL0VAL_COARSE_SHIFT (16) /* Bits 16-20: Coarse value */ +#define SCIF_DFLL0VAL_COARSE_MASK (31 << SCIF_DFLL0VAL_COARSE_SHIFT) + +/* DFLL0 Multiplier Register */ + +#define SCIF_DFLL0MUL_MASK 0xffff + +/* DFLL0 Step Register */ + +#define SCIF_DFLL0STEP_FSTEP_SHIFT (0) /* Bits 0-7: Fine Maximum Step */ +#define SCIF_DFLL0STEP_FSTEP_MASK (0xff << SCIF_DFLL0STEP_FSTEP_SHIFT) +# define SCIF_DFLL0STEP_FSTEP(n) ((n) << SCIF_DFLL0STEP_FSTEP_SHIFT) +#define SCIF_DFLL0STEP_CSTEP_SHIFT (16) /* Bits 16-20: Coarse Maximum Step */ +#define SCIF_DFLL0STEP_CSTEP_MASK (31 << SCIF_DFLL0STEP_CSTEP_SHIFT) +# define SCIF_DFLL0STEP_CSTEP(n) ((n) << SCIF_DFLL0STEP_CSTEP_SHIFT) + +/* DFLL0 Spread Spectrum Generator Control Register */ + +#define SCIF_DFLL0SSG_EN (1 << 0) /* Bit 0: Enable */ +#define SCIF_DFLL0SSG_PRBS (1 << 1) /* Bit 1: Pseudo Random Bit Sequence */ +#define SCIF_DFLL0SSG_AMPLITUDE_SHIFT (8) /* Bits 8-12: SSG Amplitude */ +#define SCIF_DFLL0SSG_AMPLITUDE_MASK (31 << SCIF_DFLL0SSG_AMPLITUDE_SHIFT) +#define SCIF_DFLL0SSG_STEPSIZE_SHIFT (16) /* Bits 16-20: SSG Step Size */ +#define SCIF_DFLL0SSG_STEPSIZE_MASK (31 << SCIF_DFLL0SSG_STEPSIZE_SHIFT) + +/* DFLL0 Ratio Register */ + +#define SCIF_DFLL0RATIO_MASK 0xffff + +/* DFLL0 Synchronization Register */ + +#define SCIF_DFLL0SYNC_SYNC (1 << 0) /* Bit 0: Synchronization */ + +/* System RC Oscillator Calibration Register */ + +#define SCIF_RCCR_CALIB_SHIFT (0) /* Bits 0-9: Calibration Value */ +#define SCIF_RCCR_CALIB_MASK (0x3ff << SCIF_RCCR_CALIB_SHIFT) +#define SCIF_RCCR_FCD (1 << 16) /* Bit 16: Flash Calibration Done */ + +/* 4/8/12MHz RC Oscillator Configuration Register */ + +#define SCIF_RCFASTCFG_EN (1 << 0) /* Bit 0: Oscillator Enable */ +#define SCIF_RCFASTCFG_TUNEEN (1 << 1) /* Bit 1: Tuner Enable */ +#define SCIF_RCFASTCFG_JITMODE (1 << 2) /* Bit 2: Jitter Mode */ +#define SCIF_RCFASTCFG_NBPERIODS_SHIFT (4) /* Bits 4-6: Number of 32kHz Periods */ +#define SCIF_RCFASTCFG_NBPERIODS_MASK (7 << SCIF_RCFASTCFG_NBPERIODS_SHIFT) +#define SCIF_RCFASTCFG_FCD (1 << 7) /* Bit 7: RCFAST Fuse Calibration Done */ +#define SCIF_RCFASTCFG_FRANGE_SHIFT (8) /* Bits 8-9: Frequency Range */ +#define SCIF_RCFASTCFG_FRANGE_MASK (3 << SCIF_RCFASTCFG_FRANGE_SHIFT) +# define SCIF_RCFASTCFG_FRANGE_4MHZ (0 << SCIF_RCFASTCFG_FRANGE_SHIFT) /* 4MHz range selected */ +# define SCIF_RCFASTCFG_FRANGE_8MHZ (1 << SCIF_RCFASTCFG_FRANGE_SHIFT) /* 8MHz range selected */ +# define SCIF_RCFASTCFG_FRANGE_12MHZ (2 << SCIF_RCFASTCFG_FRANGE_SHIFT) /* 12MHz range selected */ +#define SCIF_RCFASTCFG_LOCKMARGIN_SHIFT (12) /* Bits 12-15: Accepted Count Error for Lock */ +#define SCIF_RCFASTCFG_LOCKMARGIN_MASK (15 << SCIF_RCFASTCFG_LOCKMARGIN_SHIFT) +#define SCIF_RCFASTCFG_CALIB_SHIFT (16) /* Bits 16-22: Oscillator Calibration Value */ +#define SCIF_RCFASTCFG_CALIB_MASK (0x7f << SCIF_RCFASTCFG_CALIB_SHIFT) + +/* 4/8/12MHz RC Oscillator Status Register */ + +#define SCIF_RCFASTSR_CURTRIM_SHIFT (0) /* Bits 0-6: Current Trim Value */ +#define SCIF_RCFASTSR_CURTRIM_MASK (0x7f << SCIF_RCFASTSR_CURTRIM_SHIFT) +#define SCIF_RCFASTSR_CNTERR_SHIFT (16) /* Bits 16-20: Current Count Error */ +#define SCIF_RCFASTSR_CNTERR_MASK (31 << SCIF_RCFASTSR_CNTERR_SHIFT) +#define SCIF_RCFASTSR_SIGN (1 << 21) /* Bit 21: Sign of Current Count Error */ +#define SCIF_RCFASTSR_LOCK (1 << 24) /* Bit 24: Lock */ +#define SCIF_RCFASTSR_LOCKLOST (1 << 25) /* Bit 25: Lock Lost */ +#define SCIF_RCFASTSR_UPDATED (1 << 31) /* Bit 31: Current Trim Value Updated */ + +/* 80MHz RC Oscillator Register */ + +#define SCIF_RC80MCR_EN (1 << 0) /* Bit 0: Enable */ +#define SCIF_RC80MCR_FCD (1 << 7) /* Bit 7: Flash Calibration Done */ +#define SCIF_RC80MCR_CALIB_SHIFT (16) /* Bits 16-17: Calibration Value */ +#define SCIF_RC80MCR_CALIB_MASK (3 << SCIF_RC80MCR_CALIB_SHIFT) + +/* High Resolution Prescaler Control Register */ + +#define SCIF_HRPCR_HRPEN (1 << 0) /* Bit 0: High Resolution Prescaler Enable */ +#define SCIF_HRPCR_CKSEL_SHIFT (1) /* Bits 1-3: Clock input selection */ +#define SCIF_HRPCR_CKSEL_MASK (7 << SCIF_HRPCR_CKSEL_SHIFT) +#define SCIF_HRPCR_HRCOUNT_SHIFT (8) /* Bits 8-31: High Resolution Counter */ +#define SCIF_HRPCR_HRCOUNT_MASK (0xffffff << SCIF_HRPCR_HRCOUNT_SHIFT) + +/* Fractional Prescaler Control Register */ + +#define SCIF_FPCR_FPEN (1 << 0) /* Bit 0: High Resolution Prescaler Enable */ +#define SCIF_FPCR_CKSEL_SHIFT (1) /* Bits 1-3: Clock input selection */ +#define SCIF_FPCR_CKSEL_MASK (7 << SCIF_FPCR_CKSEL_SHIFT) + +/* Fractional Prescaler Multiplier Register */ + +#define SCIF_FPMUL_MASK 0xffff + +/* Fractional Prescaler DIVIDER Register */ + +#define SCIF_FPDIV_MASK 0xffff + +/* Generic Clock Control0-11 */ + +#define SCIF_GCCTRL_CEN (1 << 0) /* Bit 0: Clock Enable */ +#define SCIF_GCCTRL_DIVEN (1 << 1) /* Bit 1: Divide Enable */ +#define SCIF_GCCTRL_OSCSEL_SHIFT (8) /* Bits 8-12: Oscillator Select */ +#define SCIF_GCCTRL_OSCSEL_MASK (31 << SCIF_GCCTRL_OSCSEL_SHIFT) +# define SCIF_GCCTRL_OSCSEL_RCSYS (0 << SCIF_GCCTRL_OSCSEL_SHIFT) /* System RC oscillator */ +# define SCIF_GCCTRL_OSCSEL_OSC32K (1 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from OSC32K */ +# define SCIF_GCCTRL_OSCSEL_DFLL0 (2 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from DFLL0 */ +# define SCIF_GCCTRL_OSCSEL_OSC0 (3 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from Oscillator0 */ +# define SCIF_GCCTRL_OSCSEL_RC80M (4 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 80MHz RCOSC */ +# define SCIF_GCCTRL_OSCSEL_RCFAST (5 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 4,8,12MHz RCFAST */ +# define SCIF_GCCTRL_OSCSEL_RC1M (6 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 1MHz RC1M */ +# define SCIF_GCCTRL_OSCSEL_CPUCLK (7 << SCIF_GCCTRL_OSCSEL_SHIFT) /* The CPU clock */ +# define SCIF_GCCTRL_OSCSEL_HSBCLK (8 << SCIF_GCCTRL_OSCSEL_SHIFT) /* High Speed Bus clock */ +# define SCIF_GCCTRL_OSCSEL_PBACLK (9 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus A clock */ +# define SCIF_GCCTRL_OSCSEL_PBBCLK (10 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus B clock */ +# define SCIF_GCCTRL_OSCSEL_PBCCLK (11 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus C clock */ +# define SCIF_GCCTRL_OSCSEL_PBDCLK (12 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus D clock */ +# define SCIF_GCCTRL_OSCSEL_RC32K (13 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 32kHz RCOSC */ +# define SCIF_GCCTRL_OSCSEL_1K (15 << SCIF_GCCTRL_OSCSEL_SHIFT) /* 1 kHz output from OSC32K */ +# define SCIF_GCCTRL_OSCSEL_PLL0 (16 << SCIF_GCCTRL_OSCSEL_SHIFT) /* PLL0 */ +# define SCIF_GCCTRL_OSCSEL_HRPCLK (17 << SCIF_GCCTRL_OSCSEL_SHIFT) /* High resolution prescaler */ +# define SCIF_GCCTRL_OSCSEL_FPCLK (18 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Fractional prescaler */ +# define SCIF_GCCTRL_OSCSEL_GCLKIN0 (19 << SCIF_GCCTRL_OSCSEL_SHIFT) /* GCLKIN0 */ +# define SCIF_GCCTRL_OSCSEL_GCLKIN1 (20 << SCIF_GCCTRL_OSCSEL_SHIFT) /* GCLKIN1 */ +# define SCIF_GCCTRL_OSCSEL_GCLK11 (21 << SCIF_GCCTRL_OSCSEL_SHIFT) /* GCLK11 */ +#define SCIF_GCCTRL_DIV_SHIFT (16) /* Bits 16-31: Division Factor */ +#define SCIF_GCCTRL_DIV_MASK (0xffff << SCIF_GCCTRL_DIV_SHIFT) +# define SCIF_GCCTRL_DIV(n) ((n) << SCIF_GCCTRL_DIV_SHIFT) + +/* 4/8/12MHz RC Oscillator Version Register */ +/* Generic Clock Prescaler Version Register */ +/* PLL Version Register */ +/* Oscillator0 Version Register */ +/* DFLL Version Register */ +/* System RC Oscillator Version Register */ +/* 80MHz RC Oscillator Version Register */ +/* Generic Clock Version Register */ +/* SCIF Version Register */ + +#define SCIF_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define SCIF_VERSION_MASK (0xfff << SCIF_VERSION_VERSION_SHIFT) +#define SCIF_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define SCIF_VARIANT_MASK (15 << SCIF_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_SCIF_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_usart.h b/arch/arm/src/sam34/chip/sam4l_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..3c5bbd21ff473977d5d1a18b1d7d90c8b16e6da7 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_usart.h @@ -0,0 +1,448 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4l_uart.h + * Universal Synchronous Asynchronous Receiver Transmitter (USART) definitions for the SAM4L + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_UART_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_UART_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* USART register offsets ***********************************************************************/ + +#define SAM_UART_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_UART_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_UART_IER_OFFSET 0x0008 /* Interrupt Enable Register */ +#define SAM_UART_IDR_OFFSET 0x000c /* Interrupt Disable Register */ +#define SAM_UART_IMR_OFFSET 0x0010 /* Interrupt Mask Register */ +#define SAM_UART_SR_OFFSET 0x0014 /* Channel Status Register */ +#define SAM_UART_RHR_OFFSET 0x0018 /* Receive Holding Register */ +#define SAM_UART_THR_OFFSET 0x001c /* Transmit Holding Register */ +#define SAM_UART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register */ +#define SAM_UART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register */ +#define SAM_UART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register */ + /* 0x002c-0x003c: Reserved */ +#define SAM_UART_FIDI_OFFSET 0x0040 /* FI DI Ratio Register */ +#define SAM_UART_NER_OFFSET 0x0044 /* Number of Errors Register */ + /* 0x0048: Reserved */ +#define SAM_UART_IFR_OFFSET 0x004c /* IrDA Filter Register */ +#define SAM_UART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register */ +#define SAM_UART_LINMR_OFFSET 0x0054 /* LIN Mode Register */ +#define SAM_UART_LINIR_OFFSET 0x0058 /* LIN Identifier Register */ +#define SAM_UART_LINBR_OFFSET 0x005c /* LIN Baud Rate Register */ + /* 0x0060-0x00e0: Reserved */ +#define SAM_UART_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_UART_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x005c-0xf008: Reserved */ +#define SAM_UART_VERSION_OFFSET 0x00fc /* Version Register */ + /* 0x0100-0x0124: PDC Area */ + +/* USART register addresses *********************************************************************/ + +#define SAM_USART_CR(n) (SAM_USARTN_BASE(n)+SAM_UART_CR_OFFSET) +#define SAM_USART_MR(n) (SAM_USARTN_BASE(n)+SAM_UART_MR_OFFSET) +#define SAM_USART_IER(n) (SAM_USARTN_BASE(n)+SAM_UART_IER_OFFSET) +#define SAM_USART_IDR(n) (SAM_USARTN_BASE(n)+SAM_UART_IDR_OFFSET) +#define SAM_USART_IMR(n) (SAM_USARTN_BASE(n)+SAM_UART_IMR_OFFSET) +#define SAM_USART_SR(n) (SAM_USARTN_BASE(n)+SAM_UART_SR_OFFSET) +#define SAM_USART_RHR(n) (SAM_USARTN_BASE(n)+SAM_UART_RHR_OFFSET) +#define SAM_USART_THR(n) (SAM_USARTN_BASE(n)+SAM_UART_THR_OFFSET) +#define SAM_USART_BRGR(n) (SAM_USARTN_BASE(n)+SAM_UART_BRGR_OFFSET) +#define SAM_USART_RTOR(n) (SAM_USARTN_BASE(n)+SAM_UART_RTOR_OFFSET) +#define SAM_USART_TTGR(n) (SAM_USARTN_BASE(n)+SAM_UART_TTGR_OFFSET) +#define SAM_USART_FIDI(n) (SAM_USARTN_BASE(n)+SAM_UART_FIDI_OFFSET) +#define SAM_USART_NER(n) (SAM_USARTN_BASE(n)+SAM_UART_NER_OFFSET) +#define SAM_USART_IFR(n) (SAM_USARTN_BASE(n)+SAM_UART_IFR_OFFSET) +#define SAM_USART_MAN(n) (SAM_USARTN_BASE(n)+SAM_UART_MAN_OFFSET) +#define SAM_USART_LINMR(n) (SAM_USARTN_BASE(n)+SAM_UART_LINMR_OFFSET) +#define SAM_USART_LINIR(n) (SAM_USARTN_BASE(n)+SAM_UART_LINIR_OFFSET) +#define SAM_USART_LINBR(n) (SAM_USARTN_BASE(n)+UART_LINBR_OFFSET) +#define SAM_USART_WPMR(n) (SAM_USARTN_BASE(n)+SAM_UART_WPMR_OFFSET) +#define SAM_USART_WPSR(n) (SAM_USARTN_BASE(n)+SAM_UART_WPSR_OFFSET) +#define SAM_USART_VERSION(n) (SAM_USARTN_BASE(n)+SAM_UART_VERSION_OFFSET) + +#define SAM_USART0_CR (SAM_USART0_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART0_MR (SAM_USART0_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART0_IER (SAM_USART0_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART0_IDR (SAM_USART0_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART0_IMR (SAM_USART0_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART0_SR (SAM_USART0_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART0_RHR (SAM_USART0_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART0_THR (SAM_USART0_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART0_BRGR (SAM_USART0_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART0_RTOR (SAM_USART0_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART0_TTGR (SAM_USART0_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART0_FIDI (SAM_USART0_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART0_NER (SAM_USART0_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART0_IFR (SAM_USART0_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART0_MAN (SAM_USART0_BASE+SAM_UART_MAN_OFFSET) +#define SAM_USART0_LINMR (SAM_USART0_BASE+SAM_UART_LINMR_OFFSET) +#define SAM_USART0_LINIR (SAM_USART0_BASE+SAM_UART_LINIR_OFFSET) +#define SAM_USART0_LINBR (SAM_USART0_BASE+UART_LINBR_OFFSET) +#define SAM_USART0_WPMR (SAM_USART0_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART0_WPSR (SAM_USART0_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART0_VERSION (SAM_USART0_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART1_CR (SAM_USART1_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART1_MR (SAM_USART1_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART1_IER (SAM_USART1_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART1_IDR (SAM_USART1_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART1_IMR (SAM_USART1_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART1_SR (SAM_USART1_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART1_RHR (SAM_USART1_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART1_THR (SAM_USART1_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART1_BRGR (SAM_USART1_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART1_RTOR (SAM_USART1_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART1_TTGR (SAM_USART1_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART1_FIDI (SAM_USART1_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART1_NER (SAM_USART1_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART1_IFR (SAM_USART1_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART1_MAN (SAM_USART1_BASE+SAM_UART_MAN_OFFSET) +#define SAM_USART1_LINMR (SAM_USART1_BASE+SAM_UART_LINMR_OFFSET) +#define SAM_USART1_LINIR (SAM_USART1_BASE+SAM_UART_LINIR_OFFSET) +#define SAM_USART1_LINBR (SAM_USART1_BASE+UART_LINBR_OFFSET) +#define SAM_USART1_WPMR (SAM_USART1_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART1_WPSR (SAM_USART1_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART1_VERSION (SAM_USART1_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART2_CR (SAM_USART2_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART2_MR (SAM_USART2_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART2_IER (SAM_USART2_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART2_IDR (SAM_USART2_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART2_IMR (SAM_USART2_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART2_SR (SAM_USART2_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART2_RHR (SAM_USART2_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART2_THR (SAM_USART2_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART2_BRGR (SAM_USART2_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART2_RTOR (SAM_USART2_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART2_TTGR (SAM_USART2_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART2_FIDI (SAM_USART2_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART2_NER (SAM_USART2_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART2_IFR (SAM_USART2_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART2_MAN (SAM_USART2_BASE+SAM_UART_MAN_OFFSET) +#define SAM_USART2_LINMR (SAM_USART2_BASE+SAM_UART_LINMR_OFFSET) +#define SAM_USART2_LINIR (SAM_USART2_BASE+SAM_UART_LINIR_OFFSET) +#define SAM_USART2_LINBR (SAM_USART2_BASE+UART_LINBR_OFFSET) +#define SAM_USART2_WPMR (SAM_USART2_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART2_WPSR (SAM_USART2_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART2_VERSION (SAM_USART2_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART3_CR (SAM_USART3_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART3_MR (SAM_USART3_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART3_IER (SAM_USART3_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART3_IDR (SAM_USART3_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART3_IMR (SAM_USART3_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART3_SR (SAM_USART3_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART3_RHR (SAM_USART3_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART3_THR (SAM_USART3_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART3_BRGR (SAM_USART3_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART3_RTOR (SAM_USART3_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART3_TTGR (SAM_USART3_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART3_FIDI (SAM_USART3_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART3_NER (SAM_USART3_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART3_IFR (SAM_USART3_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART3_MAN (SAM_USART3_BASE+SAM_UART_MAN_OFFSET) +#define SAM_USART3_LINMR (SAM_USART3_BASE+SAM_UART_LINMR_OFFSET) +#define SAM_USART3_LINIR (SAM_USART3_BASE+SAM_UART_LINIR_OFFSET) +#define SAM_USART3_LINBR (SAM_USART3_BASE+UART_LINBR_OFFSET) +#define SAM_USART3_WPMR (SAM_USART3_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART3_WPSR (SAM_USART3_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART3_VERSION (SAM_USART3_BASE+SAM_UART_VERSION_OFFSET) + +/* USART register bit definitions ***************************************************************/ + +/* USART Control Register */ + +#define UART_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver */ +#define UART_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter */ +#define UART_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable */ +#define UART_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable */ +#define UART_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable */ +#define UART_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable */ +#define UART_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits */ +#define UART_CR_STTBRK (1 << 9) /* Bit 9: Start Break */ +#define UART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break */ +#define UART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out */ +#define UART_CR_SENDA (1 << 12) /* Bit 12: Send Address */ +#define UART_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations */ +#define UART_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge */ +#define UART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out */ +#define UART_CR_DTREN (1 << 16) /* Bit 16: Data Terminal Ready Enable */ +#define UART_CR_DTRDIS (1 << 17) /* Bit 17: Data Terminal Ready Disable */ +#define UART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable */ +#define UART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select */ +#define UART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable */ +#define UART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select */ +#define UART_CR_LINABT (1 << 20) /* Bit 20: Abort LIN Transmission */ +#define UART_CR_LINWKUP (1 << 21) /* Bit 21: Send LIN Wakeup Signal */ + +/* USART Mode Register */ + +#define UART_MR_MODE_SHIFT (0) /* Bits 0-3: */ +#define UART_MR_MODE_MASK (15 << UART_MR_MODE_SHIFT) +# define UART_MR_MODE_NORMAL (0 << UART_MR_MODE_SHIFT) /* Normal */ +# define UART_MR_MODE_RS485 (1 << UART_MR_MODE_SHIFT) /* RS485 */ +# define UART_MR_MODE_HWHS (2 << UART_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define UART_MR_MODE_ISO7816_0 (4 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */ +# define UART_MR_MODE_ISO7816_1 (6 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */ +# define UART_MR_MODE_IRDA (8 << UART_MR_MODE_SHIFT) /* IrDA */ +# define UART_MR_MODE_SPIMSTR (14 << UART_MR_MODE_SHIFT) /* SPI Master */ +# define UART_MR_MODE_SPISLV (15 << UART_MR_MODE_SHIFT) /* SPI Slave */ +#define UART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection */ +#define UART_MR_USCLKS_MASK (3 << UART_MR_USCLKS_SHIFT) +# define UART_MR_USCLKS_USART (0 << UART_MR_USCLKS_SHIFT) /* CLK_USART */ +# define UART_MR_USCLKS_USARTDIV (0 << UART_MR_USCLKS_SHIFT) /* CLK_USART/DIV(1) */ +# define UART_MR_USCLKS_CLK (0 << UART_MR_USCLKS_SHIFT) /* CLK */ +#define UART_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length */ +#define UART_MR_CHRL_MASK (3 << UART_MR_CHRL_SHIFT) +# define UART_MR_CHRL_5BITS (0 << UART_MR_CHRL_SHIFT) /* 5 bits */ +# define UART_MR_CHRL_6BITS (1 << UART_MR_CHRL_SHIFT) /* 6 bits */ +# define UART_MR_CHRL_7BITS (2 << UART_MR_CHRL_SHIFT) /* 7 bits */ +# define UART_MR_CHRL_8BITS (3 << UART_MR_CHRL_SHIFT) /* 8 bits */ +#define UART_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select */ +#define UART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase */ +#define UART_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type */ +#define UART_MR_PAR_MASK (7 << UART_MR_PAR_SHIFT) +# define UART_MR_PAR_EVEN (0 << UART_MR_PAR_SHIFT) /* Even parity */ +# define UART_MR_PAR_ODD (1 << UART_MR_PAR_SHIFT) /* Odd parity */ +# define UART_MR_PAR_SPACE (2 << UART_MR_PAR_SHIFT) /* Space: parity forced to 0 */ +# define UART_MR_PAR_MARK (3 << UART_MR_PAR_SHIFT) /* Mark: parity forced to 1 */ +# define UART_MR_PAR_NONE (4 << UART_MR_PAR_SHIFT) /* No parity */ +# define UART_MR_PAR_MULTIDROP (6 << UART_MR_PAR_SHIFT) /* Multidrop mode */ +#define UART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits */ +#define UART_MR_NBSTOP_MASK (3 << UART_MR_NBSTOP_SHIFT) +# define UART_MR_NBSTOP_1 (0 << UART_MR_NBSTOP_SHIFT) /* 1 stop bit 1 stop bit */ +# define UART_MR_NBSTOP_1p5 (1 << UART_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define UART_MR_NBSTOP_2 (2 << UART_MR_NBSTOP_SHIFT) /* 2 stop bits 2 stop bits */ +#define UART_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode */ +#define UART_MR_CHMODE_MASK (3 << UART_MR_CHMODE_SHIFT) +# define UART_MR_CHMODE_NORMAL (0 << UART_MR_CHMODE_SHIFT) /* Normal Mode */ +# define UART_MR_CHMODE_ECHO (1 << UART_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define UART_MR_CHMODE_LLPBK (2 << UART_MR_CHMODE_SHIFT) /* Local Loopback */ +# define UART_MR_CHMODE_RLPBK (3 << UART_MR_CHMODE_SHIFT) /* Remote Loopback */ +#define UART_MR_MSBF (1 << 16) /* Bit 16: Most Significant Bit first */ +#define UART_MR_CPOL (1 << 16) /* Bit 16: SPI Clock Polarity */ +#define UART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length */ +#define UART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select */ +#define UART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode */ +#define UART_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge */ +#define UART_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK */ +#define UART_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter */ +#define UART_MR_INVDATA (1 << 23) /* Bit 23: INverted Data */ +#define UART_MR_MAXITER_SHIFT (24) /* Bits 24-26: Max iterations (ISO7816 T=0 */ +#define UART_MR_MAXITER_MASK (7 << UART_MR_MAXITER_SHIFT) +#define UART_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter */ +#define UART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable */ +#define UART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode */ +#define UART_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector */ + +/* USART Interrupt Enable Register, USART Interrupt Disable Register, USART Interrupt Mask + * Register, and USART Status Register common bit field definitions. + * + * - Bits that provide interrupts with UART_INT_ + * - Bits unique to the USART status register begin with UART_SR_ + */ +#define UART_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt */ +#define UART_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt */ +#define UART_INT_RXBRK (1 << 2) /* Bit 2: Break Received/End of Break */ +#define UART_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt */ +#define UART_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt */ +#define UART_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt */ +#define UART_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt */ +#define UART_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt */ +#define UART_INT_ITER (1 << 10) /* Bit 10: Iteration Interrupt */ +#define UART_INT_UNRE (1 << 10) /* Bit 10: SPI Underrun Error Interrupt */ +#define UART_INT_RXBUFF (1 << 12) /* Bit 12: Buffer Full Interrupt */ +#define UART_INT_NACK (1 << 13) /* Bit 13: Non Acknowledge Interrupt */ +#define UART_INT_LINBK (1 << 13) /* Bit 13: LIN Break */ +#define UART_INT_LINID (1 << 14) /* Bit 14: LIN Identifier */ +#define UART_INT_LINTC (1 << 15) /* Bit 15: LIN Transfer Completed */ +#define UART_INT_RIIC (1 << 16) /* Bit 16: Ring Indicator Input Change Flag */ +#define UART_INT_DSRIC (1 << 17) /* Bit 17: DSR Input Change Flag */ +#define UART_INT_DCDIC (1 << 18) /* Bit 18: DCD Input Change Flag */ +#define UART_INT_CTSIC (1 << 19) /* Bit 19: CTS Input Change Interrupt */ +#define UART_SR_RI (1 << 20) /* Bit 20: Image of RI Input (Status only) */ +#define UART_SR_DSR (1 << 21) /* Bit 21: Image of DSR Input (Status only) */ +#define UART_SR_DCD (1 << 22) /* Bit 22: Image of DCD Input (Status only) */ +#define UART_SR_CTS (1 << 23) /* Bit 23: Image of CTS Input (Status only) */ +#define UART_SR_LINBLS (1 << 23) /* Bit 23: ILIN Bus Line Status (Status only) */ +#define UART_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt */ +#define UART_INT_LINBE (1 << 25) /* Bit 25: LIN Bit Error */ +#define UART_INT_LINISFE (1 << 26) /* Bit 26: LIN Inconsistent Sync Field Error */ +#define UART_INT_LINIPE (1 << 27) /* Bit 27: LIN Identifier Parity Error */ +#define UART_INT_LINCE (1 << 28) /* Bit 28: LIN Checksum Error */ +#define UART_INT_LINSNRE (1 << 29) /* Bit 29: LIN Slave Not Responding Error */ +#define UART_INT_LINSTE (1 << 30) /* Bit 30: LIN Sync Tolerance Error */ +#define UART_INT_LINHTE (1 << 31) /* Bit 31: LIN Header Time-out Error */ + +#define UART_INT_ALLINTS 0xff0ff7e7 + +/* USART Receiver Holding Register */ + +#define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character */ +#define UART_RHR_RXCHR_MASK (0x1ff << UART_RHR_RXCHR_SHIFT) +#define UART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync */ + +/* USART Transmit Holding Register */ + +#define UART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted */ +#define UART_THR_TXCHR_MASK (0x1ff << UART_THR_TXCHR_SHIFT) +#define UART_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be tran */ + +/* USART Baud Rate Generator Register */ + +#define UART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor */ +#define UART_BRGR_CD_MASK (0xffff << UART_BRGR_CD_SHIFT) +#define UART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part */ +#define UART_BRGR_FP_MASK (7 << UART_BRGR_FP_SHIFT) + +/* USART Receiver Time-out Register */ + +#define UART_RTOR_TO_SHIFT (0) /* Bits 0-16: Time-out Value */ +#define UART_RTOR_TO_MASK (0x1ffff << UART_RTOR_TO_SHIFT) + +/* USART Transmitter Timeguard Register */ + +#define UART_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value */ +#define UART_TTGR_TG_MASK (0xff << UART_TTGR_TG_SHIFT) + +/* USART FI DI RATIO Register */ + +#define UART_FIDI_RATIO_SHIFT (0) /* Bits 0-10: FI Over DI Ratio Value */ +#define UART_FIDI_RATIO_MASK (0x7ff << UART_FIDI_RATIO_SHIFT) + +/* USART Number of Errors Register */ + +#define UART_NER_NBERRORS_SHIFT (0) /* Bits 0-7: Number of Errrors */ +#define UART_NER_NBERRORS_MASK (0xff << UART_NER_NBERRORS_SHIFT) + +/* USART IrDA FILTER Register */ + +#define UART_IFR_IRDAFILTER_SHIFT (0) /* Bits 0-7: IrDA Filter */ +#define UART_IFR_IRDAFILTER_MASK (0xff << UART_IFR_IRDAFILTER_SHIFT) + +/* USART Manchester Configuration Register */ + +#define UART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length */ +#define UART_MAN_TXPL_MASK (15 << UART_MAN_TXPL_SHIFT) +#define UART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern */ +#define UART_MAN_TXPP_MASK (3 << UART_MAN_TXPP_SHIFT) +# define UART_MAN_TXPP_ALLONE (0 << UART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_TXPP_ALLZERO (1 << UART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_TXPP_ZEROONE (2 << UART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_TXPP_ONEZERO (3 << UART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity */ +#define UART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length */ +#define UART_MAN_RXPL_MASK (15 << UART_MAN_RXPL_SHIFT) +#define UART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected */ +#define UART_MAN_RXPP_MASK (3 << UART_MAN_RXPP_SHIFT) +# define UART_MAN_RXPP_ALLONE (0 << UART_MAN_RXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_RXPP_ALLZERO (1 << UART_MAN_RXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_RXPP_ZEROONE (2 << UART_MAN_RXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_RXPP_ONEZERO (3 << UART_MAN_RXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity */ +#define UART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation */ + +/* USART LIN Mode Register */ + +#define UART_LINMR_NACT_SHIFT (0) /* Bits 0-1: LIN Node Action */ +#define UART_LINMR_NACT_MASK (3 << UART_LINMR_NACT_SHIFT) +# define UART_LINMR_NACT_PUBLISH (0 << UART_LINMR_NACT_SHIFT) /* USART transmits response */ +# define UART_LINMR_NACT_SUBSCRIBE (1 << UART_LINMR_NACT_SHIFT) /* USART receives response */ +# define UART_LINMR_NACT_IGNORE (2 << UART_LINMR_NACT_SHIFT) /* USART does neither */ +#define UART_LINMR_PARDIS (1 << 2) /* Bit 0: Parity Disable */ +#define UART_LINMR_CHKDIS (1 << 3) /* Bit 0: Checksum Disable */ +#define UART_LINMR_CHKTYP (1 << 4) /* Bit 0: Checksum Type */ +#define UART_LINMR_DLM (1 << 5) /* Bit 0: Data Length Mode */ +#define UART_LINMR_FSDIS (1 << 6) /* Bit 0: Frame Slot Mode Disable */ +#define UART_LINMR_WKUPTYP (1 << 7) /* Bit 0: Wakeup Signal Type */ +#define UART_LINMR_DLC_SHIFT (8) /* Bits 8-15: Data Length Control */ +#define UART_LINMR_DLC_MASK (0xff << UART_LINMR_DLC_SHIFT) +#define UART_LINMR_PDCM (1 << 16) /* Bit 16: Peripheral DMA Controller Mode */ +#define UART_LINMR_SYNCDIS (1 << 17) /* Bit 17: Synchronization Disable */ + +/* USART LIN Identifier Register */ + +#define UART_LINIR_MASK 0xff /* Bits 0-7: Identifer character */ + +/* USART LIN Baud Rate Register */ + +#define UART_LINBR_LINCD_SHIFT (0) /* Bit 0-15:LIN Clock Divider after Synchronization */ +#define UART_LINBR_LINCD_MASK (0xffff << UART_LINBR_LINCD_SHIFT) +#define UART_LINBR_LINFP_SHIFT (16) /* Bits 16-18: LIN Fractional Part after Synchronization */ +#define UART_LINBR_LINFP_MASK (7 << UART_LINBR_LINFP_SHIFT) + +/* USART Write Protect Mode Register */ + +#define UART_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define UART_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define UART_WPMR_WPKEY_MASK (0x00ffffff << UART_WPMR_WPKEY_SHIFT) + +/* USART Write Protect Status Register */ + +#define UART_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define UART_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define UART_WPSR_WPVSRC_MASK (0xffff << UART_WPSR_WPVSRC_SHIFT) + +/* USART Version Register */ + +#define UART_VERSION_VERSION_SHIFT (0) /* Bits 0-11: Macrocell version number */ +#define UART_VERSION_VERSION_MASK (0xfff << UART_VERSION_VERSION_SHIFT) +#define UART_VERSION_MFN_SHIFT (16) /* Bits 16-18: Reserved */ +#define UART_VERSION_MFN_MASK (7 << UART_VERSION_MFN_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_UART_H */ diff --git a/arch/arm/src/sam34/chip/sam4l_vectors.h b/arch/arm/src/sam34/chip/sam4l_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..15948d3c83600e0e774f7b793749d1d5996b9bfa --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_vectors.h @@ -0,0 +1,136 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4l_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that + * supplies ach SAM3U vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/sam/sam4l_irq.h. + * sam_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 80 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 80 + +#else + VECTOR(sam_hflashc, SAM_IRQ_HFLASHC) /* Vector 16+0: Flash Controller */ + VECTOR(sam_pdca0, SAM_IRQ_PDCA0) /* Vector 16+1: Peripheral DMA Controller 0 */ + VECTOR(sam_pdca1, SAM_IRQ_PDCA1) /* Vector 16+2: Peripheral DMA Controller 1 */ + VECTOR(sam_pdca2, SAM_IRQ_PDCA2) /* Vector 16+3: Peripheral DMA Controller 2 */ + VECTOR(sam_pdca3, SAM_IRQ_PDCA3) /* Vector 16+4: Peripheral DMA Controller 3 */ + VECTOR(sam_pdca4, SAM_IRQ_PDCA4) /* Vector 16+5: Peripheral DMA Controller 4 */ + VECTOR(sam_pdca5, SAM_IRQ_PDCA5) /* Vector 16+6: Peripheral DMA Controller 5 */ + VECTOR(sam_pdca6, SAM_IRQ_PDCA6) /* Vector 16+7: Peripheral DMA Controller 6 */ + VECTOR(sam_pdca7, SAM_IRQ_PDCA7) /* Vector 16+8: Peripheral DMA Controller 7 */ + VECTOR(sam_pdca8, SAM_IRQ_PDCA8) /* Vector 16+9: Peripheral DMA Controller 8 */ + VECTOR(sam_pdca9, SAM_IRQ_PDCA9) /* Vector 16+10: Peripheral DMA Controller 9 */ + VECTOR(sam_pdca10, SAM_IRQ_PDCA10) /* Vector 16+11: Peripheral DMA Controller 10 */ + VECTOR(sam_pdca11, SAM_IRQ_PDCA11) /* Vector 16+12: Peripheral DMA Controller 11 */ + VECTOR(sam_pdca12, SAM_IRQ_PDCA12) /* Vector 16+13: Peripheral DMA Controller 12 */ + VECTOR(sam_pdca13, SAM_IRQ_PDCA13) /* Vector 16+14: Peripheral DMA Controller 13 */ + VECTOR(sam_pdca14, SAM_IRQ_PDCA14) /* Vector 16+15: Peripheral DMA Controller 14 */ + VECTOR(sam_pdca15, SAM_IRQ_PDCA15) /* Vector 16+16: Peripheral DMA Controller 15 */ + VECTOR(sam_crccu, SAM_IRQ_CRCCU) /* Vector 16+17: CRC Calculation Unit */ + VECTOR(sam_usbc, SAM_IRQ_USBC) /* Vector 16+18: USB 2.0 Interface */ + VECTOR(sam_pevc_tr, SAM_IRQ_PEVC_TR) /* Vector 16+19: Peripheral Event Controller TR */ + VECTOR(sam_pevc_ov, SAM_IRQ_PEVC_OV) /* Vector 16+20: Peripheral Event Controller OV */ + VECTOR(sam_aesa, SAM_IRQ_AESA) /* Vector 16+21: Advanced Encryption Standard */ + VECTOR(sam_pm, SAM_IRQ_PM) /* Vector 16+22: Power Manager */ + VECTOR(sam_scif, SAM_IRQ_SCIF) /* Vector 16+23: System Control Interface */ + VECTOR(sam_freqm, SAM_IRQ_FREQM) /* Vector 16+24: Frequency Meter */ + VECTOR(sam_gpio0, SAM_IRQ_GPIO0) /* Vector 16+25: General-Purpose Input/Output Controller 0 */ + VECTOR(sam_gpio1, SAM_IRQ_GPIO1) /* Vector 16+26: General-Purpose Input/Output Controller 1 */ + VECTOR(sam_gpio2, SAM_IRQ_GPIO2) /* Vector 16+27: General-Purpose Input/Output Controller 2 */ + VECTOR(sam_gpio3, SAM_IRQ_GPIO3) /* Vector 16+28: General-Purpose Input/Output Controller 3 */ + VECTOR(sam_gpio4, SAM_IRQ_GPIO4) /* Vector 16+29: General-Purpose Input/Output Controller 4 */ + VECTOR(sam_gpio5, SAM_IRQ_GPIO5) /* Vector 16+30: General-Purpose Input/Output Controller 5 */ + VECTOR(sam_gpio6, SAM_IRQ_GPIO6) /* Vector 16+31: General-Purpose Input/Output Controller 6 */ + VECTOR(sam_gpio7, SAM_IRQ_GPIO7) /* Vector 16+32: General-Purpose Input/Output Controller 7 */ + VECTOR(sam_gpio8, SAM_IRQ_GPIO8) /* Vector 16+33: General-Purpose Input/Output Controller 8 */ + VECTOR(sam_gpio9, SAM_IRQ_GPIO9) /* Vector 16+34: General-Purpose Input/Output Controller 9 */ + VECTOR(sam_gpio10, SAM_IRQ_GPIO10) /* Vector 16+35: General-Purpose Input/Output Controller 10 */ + VECTOR(sam_gpio11, SAM_IRQ_GPIO11) /* Vector 16+36: General-Purpose Input/Output Controller 11 */ + VECTOR(sam_bpm, SAM_IRQ_BPM) /* Vector 16+37: Backup Power Manager */ + VECTOR(sam_bscif, SAM_IRQ_BSCIF) /* Vector 16+38: Backup System Control Interface */ + VECTOR(sam_ast_alarm, SAM_IRQ_AST_ALARM) /* Vector 16+39: Asynchronous Timer ALARM */ + VECTOR(sam_ast_per, SAM_IRQ_AST_PER) /* Vector 16+40: Asynchronous Timer PER */ + VECTOR(sam_ast_ovf, SAM_IRQ_AST_OVF) /* Vector 16+41: Asynchronous Timer OVF */ + VECTOR(sam_ast_ready, SAM_IRQ_AST_READY) /* Vector 16+42: Asynchronous Timer READY */ + VECTOR(sam_ast_clkready, SAM_IRQ_AST_CLKREADY) /* Vector 16+43: Asynchronous Timer CLKREADY */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+44: Watchdog Timer */ + VECTOR(sam_eic1, SAM_IRQ_EIC1) /* Vector 16+45: External Interrupt Controller 1 */ + VECTOR(sam_eic2, SAM_IRQ_EIC2) /* Vector 16+46: External Interrupt Controller 2 */ + VECTOR(sam_eic3, SAM_IRQ_EIC3) /* Vector 16+47: External Interrupt Controller 3 */ + VECTOR(sam_eic4, SAM_IRQ_EIC4) /* Vector 16+48: External Interrupt Controller 4 */ + VECTOR(sam_eic5, SAM_IRQ_EIC5) /* Vector 16+49: External Interrupt Controller 5 */ + VECTOR(sam_eic6, SAM_IRQ_EIC6) /* Vector 16+50: External Interrupt Controller 6 */ + VECTOR(sam_eic7, SAM_IRQ_EIC7) /* Vector 16+51: External Interrupt Controller 7 */ + VECTOR(sam_eic8, SAM_IRQ_EIC8) /* Vector 16+52: External Interrupt Controller 8 */ + VECTOR(sam_iisc, SAM_IRQ_IISC) /* Vector 16+53: Inter-IC Sound (I2S) Controller */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+54: Serial Peripheral Interface */ + VECTOR(sam_tc00, SAM_IRQ_TC00) /* Vector 16+55: Timer/Counter 0 */ + VECTOR(sam_tc01, SAM_IRQ_TC01) /* Vector 16+56: Timer/Counter 1 */ + VECTOR(sam_tc02, SAM_IRQ_TC02) /* Vector 16+57: Timer/Counter 2 */ + VECTOR(sam_tc10, SAM_IRQ_TC10) /* Vector 16+58: Timer/Counter 10 */ + VECTOR(sam_tc11, SAM_IRQ_TC11) /* Vector 16+59: Timer/Counter 11 */ + VECTOR(sam_tc12, SAM_IRQ_TC12) /* Vector 16+60: Timer/Counter 12 */ + VECTOR(sam_twim0, SAM_IRQ_TWIM0) /* Vector 16+61: Two-wire Master Interface TWIM0 */ + VECTOR(sam_twis0, SAM_IRQ_TWIS0) /* Vector 16+62: Two-wire Slave Interface TWIS0 */ + VECTOR(sam_twim1, SAM_IRQ_TWIM1) /* Vector 16+63: Two-wire Master Interface TWIM1 */ + VECTOR(sam_twis1, SAM_IRQ_TWIS1) /* Vector 16+64: Two-wire Slave Interface TWIS1 */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+65: USART0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+66: USART1 */ + VECTOR(sam_usart2, SAM_IRQ_USART2) /* Vector 16+67: USART2 */ + VECTOR(sam_usart3, SAM_IRQ_USART3) /* Vector 16+68: USART3 */ + VECTOR(sam_adcife, SAM_IRQ_ADCIFE) /* Vector 16+69: ADC controller interface */ + VECTOR(sam_dacc, SAM_IRQ_DACC) /* Vector 16+70: DAC Controller */ + VECTOR(sam_acifc, SAM_IRQ_ACIFC) /* Vector 16+71: Analog Comparator Interface */ + VECTOR(sam_abdacb, SAM_IRQ_ABDACB) /* Vector 16+72: Audio Bitstream DAC */ + VECTOR(sam_trng, SAM_IRQ_TRNG) /* Vector 16+73: True Random Number Generator */ + VECTOR(sam_parc, SAM_IRQ_PARC) /* Vector 16+74: Parallel Capture */ + VECTOR(sam_catb, SAM_IRQ_CATB) /* Vector 16+75: Capacitive Touch Module B */ + VECTOR(sam_twim2, SAM_IRQ_TWIM2) /* Vector 16+77: Two-wire Master Interface */ + VECTOR(sam_twim3, SAM_IRQ_TWIM3) /* Vector 16+78: Two-wire Master Interface */ + VECTOR(sam_lcdca, SAM_IRQ_LCDCA) /* Vector 16+79: LCD Controller A */ +#endif diff --git a/arch/arm/src/sam34/chip/sam4l_wdt.h b/arch/arm/src/sam34/chip/sam4l_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..9c37c922a9962ff99b70da503e849256ad583050 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4l_wdt.h @@ -0,0 +1,137 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4l_wdt.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_WDT_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_WDT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* WDT register offsets ****************************************************************/ + +#define SAM_WDT_CTRL_OFFSET 0x0000 /* Control Register */ +#define SAM_WDT_CLR_OFFSET 0x0004 /* Clear Register */ +#define SAM_WDT_SR_OFFSET 0x0008 /* Status Register */ +#define SAM_WDT_IER_OFFSET 0x000c /* Interrupt Enable Register */ +#define SAM_WDT_IDR_OFFSET 0x0010 /* Interrupt Disable Register */ +#define SAM_WDT_IMR_OFFSET 0x0014 /* Interrupt Mask Register */ +#define SAM_WDT_ISR_OFFSET 0x0018 /* Interrupt Status Register */ +#define SAM_WDT_ICR_OFFSET 0x001c /* Interrupt Clear Register */ +#define SAM_WDT_VERSION_OFFSET 0x03fc /* Version Register */ + +/* WDT register addresses **************************************************************/ + +#define SAM_WDT_CTRL (SAM_WDT_BASE+SAM_WDT_CTRL_OFFSET) +#define SAM_WDT_CLR (SAM_WDT_BASE+SAM_WDT_CLR_OFFSET) +#define SAM_WDT_SR (SAM_WDT_BASE+SAM_WDT_SR_OFFSET) +#define SAM_WDT_IER (SAM_WDT_BASE+SAM_WDT_IER_OFFSET) +#define SAM_WDT_IDR (SAM_WDT_BASE+SAM_WDT_IDR_OFFSET) +#define SAM_WDT_IMR (SAM_WDT_BASE+SAM_WDT_IMR_OFFSET) +#define SAM_WDT_ISR (SAM_WDT_BASE+SAM_WDT_ISR_OFFSET) +#define SAM_WDT_ICR (SAM_WDT_BASE+SAM_WDT_ICR_OFFSET) +#define SAM_WDT_VERSION (SAM_WDT_BASE+SAM_WDT_VERSION_OFFSET) + +/* WDT register bit definitions ********************************************************/ + +/* Control Register */ + +#define WDT_CTRL_EN (1 << 0) /* Bit 0: WDT Enable */ +#define WDT_CTRL_DAR (1 << 1) /* Bit 1: WDT Disable After Reset */ +#define WDT_CTRL_MODE (1 << 2) /* Bit 2: WDT Mode */ +#define WDT_CTRL_SFV (1 << 3) /* Bit 3: WDT Control Register Store Final Value */ +#define WDT_CTRL_IM (1 << 4) /* Bit 4: Interrupt Mode */ +#define WDT_CTRL_FCD (1 << 7) /* Bit 7: Flash Calibration Done */ +#define WDT_CTRL_PSEL_SHIFT (8) /* Bits 8-12: Time Out Prescale Select */ +#define WDT_CTRL_PSEL_MASK (31 << WDT_CTRL_PSEL_SHIFT) +#define WDT_CTRL_CEN (1 << 16) /* Bit 16: Clock Enable */ +#define WDT_CTRL_CSSEL (1 << 17) /* Bit 17: Clock Source Select */ +#define WDT_CTRL_TBAN_SHIFT (18) /* Bits 18-22: Time Ban Prescale Select */ +#define WDT_CTRL_TBAN_MASK (31 << WDT_CTRL_TBAN_SHIFT) +#define WDT_CTRL_KEY_SHIFT (24) /* Bits 24-31: Key */ +#define WDT_CTRL_KEY_MASK (0xff << WDT_CTRL_KEY_SHIFT) +# define WDT_CTRL_KEY_FIRST (0x55 << WDT_CTRL_KEY_SHIFT) +# define WDT_CTRL_KEY_SECOND (0xaa << WDT_CTRL_KEY_SHIFT) + +/* Clear Register */ + +#define WDT_CLR_WDTCLR (1 << 0) /* Bit 0: Watchdog Clear */ +#define WDT_CLR_KEY_SHIFT (24) /* Bits 24-31: Key */ +#define WDT_CLR_KEY_MASK (0xff << WDT_CLR_KEY_SHIFT) +# define WDT_CLR_KEY_FIRST (0x55 << WDT_CLR_KEY_SHIFT) +# define WDT_CLR_KEY_SECOND (0xaa << WDT_CLR_KEY_SHIFT) + +/* Status Register */ + +#define WDT_SR_WINDOW (1 << 0) /* Bit 0: Within Window */ +#define WDT_SR_CLEARED (1 << 1) /* Bit 1: WDT Counter Cleared */ + +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ +/* Interrupt Status Register */ +/* Interrupt Clear Register */ + +#define WDT_WINT (1 << 2) /* Bit 2: WINT */ + +/* Version Register */ + +#define WDT_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define WDT_VERSION_MASK (0xfff << WDT_VERSION_VERSION_SHIFT) +#define WDT_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define WDT_VARIANT_MASK (15 << WDT_VARIANT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_WDT_H */ diff --git a/arch/arm/src/sam34/chip/sam4s_memorymap.h b/arch/arm/src/sam34/chip/sam4s_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..0ebf658866cc71050d88fd44a62a333f387767ac --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4s_memorymap.h @@ -0,0 +1,155 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4s_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_EXTRAM_BASE 0x60000000 /* 0x60000000-0x9fffffff: External RAM */ +#define SAM_EXTDEV_BASE 0xa0000000 /* 0xa0000000-0xdfffffff: External device */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x003fffff: Boot Memory */ +#define SAM_INTFLASH_BASE 0x00400000 /* 0x00400000-0x007fffff: Internal FLASH */ +#define SAM_INTROM_BASE 0x00800000 /* 0x00180000-0x00bfffff: Internal ROM */ + /* 0x00c00000-0x1fffffff: Reserved */ +/* Internal SRAM memory region */ + +#define SAM_INTSRAM0_BASE 0x20000000 /* For SAM3U compatibility */ +#define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32MB bit-band region */ + /* 0x24000000-0x3fffffff: Undefined */ +/* Peripherals address region */ + +#define SAM_HSMCI_BASE 0x40000000 /* 0x40000000-0x400003ff: High Speed Multimedia Card Interface */ +#define SAM_SSC_BASE 0x40004000 /* 0x40004000-0x40007fff: Synchronous Serial Controller */ +#define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface */ + /* 0x4000c000-0x4000ffff: Reserved */ +#define SAM_TC012_BASE 0x40010000 /* 0x40010000-0x400100bf: Timer Counters 0-2 */ +# define SAM_TC0_BASE 0x40010000 /* 0x40010000-0x4001003f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x40010040 /* 0x40010040-0x4001007f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x40010080 /* 0x40010080-0x400100bf: Timer Counter 2 */ + /* 0x400100c0-0x40013fff Reserved */ +#define SAM_TC345_BASE 0x40014000 /* 0x40014000-0x400140bf: Timer Counters 3-5 */ +# define SAM_TC3_BASE 0x40014000 /* 0x40014000-0x4001403f: Timer Counter 3 */ +# define SAM_TC4_BASE 0x40014040 /* 0x40014040-0x4001407f: Timer Counter 4 */ +# define SAM_TC5_BASE 0x40014080 /* 0x40014080-0x400140bf: Timer Counter 5 */ + +#define SAM_TWI_BASE 0x40018000 /* 0x40018000-0x4001ffff: Two-Wire Interface */ +# define SAM_TWI0_BASE 0x40018000 /* 0x40018000-0x4001bfff: Two-Wire Interface 0 */ +# define SAM_TWI1_BASE 0x4001c000 /* 0x4001c000-0x4001ffff: Two-Wire Interface 1 */ +#define SAM_PWM_BASE 0x40020000 /* 0x40020000-0x4003ffff: Pulse Width Modulation */ +#define SAM_USART_BASE 0x40024000 /* 0x40024000-0x4002bfff: USART */ +# define SAM_USART0_BASE 0x40024000 /* 0x40024000-0x40023fff: USART0 */ +# define SAM_USART1_BASE 0x40028000 /* 0x40028000-0x4002bfff: USART1 */ + /* 0x4002C000-0x4002ffff: Reserved */ + /* 0x40030000-0x40033fff: Reserved */ +#define SAM_UDP_BASE 0x40034000 /* 0x40034000-0x40037fff: USB 2.0 Device */ +#define SAM_ADC_BASE 0x40038000 /* 0x40038000-0x4003bfff: Analog To Digital Converter */ +#define SAM_DACC_BASE 0x4003c000 /* 0x4003c000-0x4003ffff: Digital To Analog Converter */ +#define SAM_ACC_BASE 0x40040000 /* 0x40040000-0x40043fff: Analog Comparator */ +#define SAM_CRCCU_BASE 0x40044000 /* 0x40040000-0x40047fff: CRC Calculation Unit */ + /* 0x40048000-0x400dffff: Reserved */ +#define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e25ff: System Controller */ + /* 0x400e2600-0x400fffff: Reserved */ + /* 0x40100000-0x4002ffff: Reserved */ +#define SAM_BBPERIPH_BASE 0x42000000 /* 0x42000000-0x43ffffff: 32MB bit-band region */ + /* 0x44000000-0x5fffffff: Reserved */ +/* System Controller Register Blocks: 0x400e0000-0x4007ffff */ + +#define SAM_SMC_BASE 0x400e0000 /* 0x400e0000-0x400e01ff: Static Memory Controller */ +#define SAM_MATRIX_BASE 0x400e0200 /* 0x400e0200-0x400e03ff: MATRIX */ +#define SAM_PMC_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: Power Management Controller */ +#define SAM_UART0_BASE 0x400e0600 /* 0x400e0600-0x400e073f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0740 /* 0x400e0740-0x400e07ff: CHIP ID */ +#define SAM_UART1_BASE 0x400e0800 /* 0x400e0800-0x400e0bff: UART 1 */ +#define SAM_EEFC_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controllers*/ +# define SAM_EEFC0_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: Enhanced Embedded Flash Controller 0 */ +# define SAM_EEFC1_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Enhanced Embedded Flash Controller 1 */ +#define SAM_PIO_BASE 0x400e0e00 /* 0x400e0e00-0x400e13ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0e00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1200 /* 0x400e1200-0x400e13ff: Parallel I/O Controller C */ +#define SAM_RSTC_BASE 0x400e1400 /* 0x400e1400-0x400e140f: Reset Controller */ +#define SAM_SUPC_BASE 0x400e1410 /* 0x400e1410-0x400e142f: Supply Controller */ +#define SAM_RTT_BASE 0x400e1430 /* 0x400e1430-0x400e144f: Real Time Timer */ +#define SAM_WDT_BASE 0x400e1450 /* 0x400e1250-0x400e145f: Watchdog Timer */ +#define SAM_RTC_BASE 0x400e1460 /* 0x400e1460-0x400e148f: Real Time Clock */ +#define SAM_GPBR_BASE 0x400e1490 /* 0x400e1490-0x400e15ff: GPBR */ + /* 0x400e1600-0x4007ffff: Reserved */ +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x63ffffff: Chip selects */ +# define SAM_EXTCSN_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x63ffffff: Chip select 3 */ + /* 0x64000000-0x9fffffff: Reserved */ +/* System memory region */ + +#define SAM_PRIVPERIPH_BASE 0xe0000000 /* 0xe0000000-0xe00fffff: Private peripheral bus */ +#define SAM_VENDOR_BASE 0xe0100000 /* 0ex0100000-0xffffffff: Vendor-specific memory */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_MEMORYMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4s_pinmap.h b/arch/arm/src/sam34/chip/sam4s_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..b8fd5c46eccd07154c3e8f773bb190781125c925 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4s_pinmap.h @@ -0,0 +1,314 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam4s_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the programmable clock output PCK0 on PA6, then the following definition + * should appear in the board.h header file for that board: + * + * #define GPIO_PCK0 GPIO_PCK0_1 + * + * The driver will then automatically configure PA6 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* 12-bit Analog-to-Digital Converter (ADC) */ + +#define GPIO_ADC0_AD0 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_ADC0_AD1 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_ADC0_AD2 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_ADC0_AD3 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_ADC0_AD4 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_ADC0_AD5 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_ADC0_AD6 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_ADC0_AD7 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_ADC0_AD8 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_ADC0_AD9 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_ADC0_AD10 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_ADC0_AD11 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_ADC0_AD12 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_ADC0_AD13 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_ADC0_AD14 (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_ADC0_ADTRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) + +/* Digital-to-Analog Convert (DAC) */ + +#define GPIO_DAC0 (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_DAC1 (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_DAC_DATRG (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) + +/* High-Speed Multimedia Card Interface (HSMCI) */ + +#define GPIO_HSMCI_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_HSMCI_DA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_HSMCI_DAT0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_HSMCI_DAT1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_HSMCI_DAT2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_HSMCI_DAT3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_PCK0_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PCK2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWM0_FI (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWM0_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWM0_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_PWM0_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWM0_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWM0_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWM0_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWM0_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_PWM0_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_PWM0_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_PWM1_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PWM1_H_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_PWM1_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWM1_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PWM1_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWM1_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_PWM1_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWM1_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWM1_L_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_PWM2_H_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_PWM2_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWM2_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_PWM2_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_PWM2_H_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWM2_L_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWM2_L_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWM2_L_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWM2_L_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_PWM3_H_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWM3_H_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_PWM3_H_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_PWM3_H_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWM3_H_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PWM3_L_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWM3_L_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_PWM3_L_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) + +/* Static Memory Controller (SMC) */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_SMC_A14 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A15 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SMC_A16 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SMC_A17 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SMC_A18 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SMC_A19 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SMC_A20 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SMC_A21 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_A22 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_A23 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_NANDALE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_NANDCLE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NANDOE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_NANDWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_NCS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_NCS1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_NCS2 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SMC_NCS3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_NRD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_NWAIT (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_SPI0_MOSI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN14) +#define GPIO_SPI0_NPCS1_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_SPI0_NPCS1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SPI0_NPCS2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SPI0_NPCS2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_SPI0_NPCS2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS3_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SPI0_NPCS3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_SPI0_NPCS3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_SPI0_SPCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +/* Synchronous Serial Controller (SSC) */ + +#define GPIO_SSC_RD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SSC_RF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SSC_RK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SSC_TD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_SSC_TF (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SSC_TK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC0_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_TC0_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_TC1_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_TC1_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_TC1_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_TC2_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_TC2_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_TC2_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_TC3_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC3_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_TC3_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_TC4_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC4_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC4_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC5_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_TC5_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC5_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) + +/* Two Wire Interface (TWI) */ + +#define GPIO_TWI0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TWI0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TWI1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TWI1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_UART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_UART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_USART0_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_USART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_USART0_SCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_USART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) + +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_USART1_DCD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_USART1_DSR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_USART1_DTR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_USART1_RI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) + +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_USART1_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PINMAP_H */ diff --git a/arch/arm/src/sam34/chip/sam4s_pio.h b/arch/arm/src/sam34/chip/sam4s_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..be65af3b57b7af9e60c1073be1784fdbc6e0405c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4s_pio.h @@ -0,0 +1,401 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam4s_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAM4S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PIO_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */ +#define SAM_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */ +#define SAM_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */ + /* 0x000c: Reserved */ +#define SAM_PIO_OER_OFFSET 0x0010 /* Output Enable Register */ +#define SAM_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */ +#define SAM_PIO_OSR_OFFSET 0x0018 /* Output Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */ +#define SAM_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */ +#define SAM_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */ + /* 0x002c: Reserved */ +#define SAM_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */ +#define SAM_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */ +#define SAM_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define SAM_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */ +#define SAM_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */ +#define SAM_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */ + /* 0x005c: Reserved */ +#define SAM_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */ +#define SAM_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */ +#define SAM_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */ + /* 0x006c: Reserved */ +#define SAM_PIO_ABCDSR1_OFFSET 0x0070 /* Peripheral Select Register 1 */ +#define SAM_PIO_ABCDSR2_OFFSET 0x0074 /* Peripheral Select Register 2 */ + /* 0x0078-0x007c: Reserved */ +#define SAM_PIO_IFSCDR_OFFSET 0x0080 /* Input Filter Slow Clock Disable Register */ +#define SAM_PIO_IFSCER_OFFSET 0x0084 /* Input Filter Slow Clock Enable Register */ +#define SAM_PIO_IFSCSR_OFFSET 0x0088 /* Input Filter Slow Clock Status Register */ +#define SAM_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */ +#define SAM_PIO_PPDDR_OFFSET 0x0090 /* Pad Pull Down Disable Register */ +#define SAM_PIO_PPDER_OFFSET 0x0094 /* PIO Pad Pull Down Enable Register */ +#define SAM_PIO_PPDSR_OFFSET 0x0098 /* PIO Pad Pull Down Status Register */ + /* 0x009c: Reserved */ +#define SAM_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */ +#define SAM_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */ +#define SAM_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */ + /* 0x00ac: Reserved */ +#define SAM_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */ +#define SAM_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */ +#define SAM_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */ + /* 0x00bc: Reserved */ +#define SAM_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */ +#define SAM_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */ +#define SAM_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */ + /* 0x00cc: Reserved */ +#define SAM_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */ +#define SAM_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */ +#define SAM_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */ + /* 0x00dc: Reserved */ +#define SAM_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */ +#define SAM_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8: Reserved */ +#define SAM_PIO_SCHMITT_OFFSET 0x0100 /* Schmitt Trigger Register */ + /* 0x0104-0x14c: Reserved */ +#define SAM_PIO_PCMR_OFFSET 0x0150 /* Parallel Capture Mode Register */ +#define SAM_PIO_PCIER_OFFSET 0x0154 /* Parallel Capture Interrupt Enable Register */ +#define SAM_PIO_PCIDR_OFFSET 0x0158 /* Parallel Capture Interrupt Disable Register */ +#define SAM_PIO_PCIMR_OFFSET 0x015c /* Parallel Capture Interrupt Mask Register */ +#define SAM_PIO_PCISR_OFFSET 0x0160 /* Parallel Capture Interrupt Status Register */ +#define SAM_PIO_PCRHR_OFFSET 0x0164 /* Parallel Capture Reception Holding Register */ + /* 0x0168-0x018c: Reserved for PDC registers */ + +/* PIO register addresses ***************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define NPIO (3) + +#define SAM_PIO_PER(n) (SAM_PIO_BASE(n)+SAM_PIO_PER_OFFSET) +#define SAM_PIO_PDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDR_OFFSET) +#define SAM_PIO_PSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PSR_OFFSET) +#define SAM_PIO_OER(n) (SAM_PIO_BASE(n)+SAM_PIO_OER_OFFSET) +#define SAM_PIO_ODR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODR_OFFSET) +#define SAM_PIO_OSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OSR_OFFSET) +#define SAM_PIO_IFER(n) (SAM_PIO_BASE(n)+SAM_PIO_IFER_OFFSET) +#define SAM_PIO_IFDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFDR_OFFSET) +#define SAM_PIO_IFSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSR_OFFSET) +#define SAM_PIO_SODR(n) (SAM_PIO_BASE(n)+SAM_PIO_SODR_OFFSET) +#define SAM_PIO_CODR(n) (SAM_PIO_BASE(n)+SAM_PIO_CODR_OFFSET) +#define SAM_PIO_ODSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ODSR_OFFSET) +#define SAM_PIO_PDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PDSR_OFFSET) +#define SAM_PIO_IER(n) (SAM_PIO_BASE(n)+SAM_PIO_IER_OFFSET) +#define SAM_PIO_IDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IDR_OFFSET) +#define SAM_PIO_IMR(n) (SAM_PIO_BASE(n)+SAM_PIO_IMR_OFFSET) +#define SAM_PIO_ISR(n) (SAM_PIO_BASE(n)+SAM_PIO_ISR_OFFSET) +#define SAM_PIO_MDER(n) (SAM_PIO_BASE(n)+SAM_PIO_MDER_OFFSET) +#define SAM_PIO_MDDR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDDR_OFFSET) +#define SAM_PIO_MDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_MDSR_OFFSET) +#define SAM_PIO_PUDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUDR_OFFSET) +#define SAM_PIO_PUER(n) (SAM_PIO_BASE(n)+SAM_PIO_PUER_OFFSET) +#define SAM_PIO_PUSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PUSR_OFFSET) +#define SAM_PIO_ABCDSR1(n) (SAM_PIO_BASE(n)+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIO_ABCDSR2(n) (SAM_PIO_BASE(n)+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIO_IFSCDR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIO_IFSCER(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIO_IFSCSR(n) (SAM_PIO_BASE(n)+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIO_SCDR(n) (SAM_PIO_BASE(n)+SAM_PIO_SCDR_OFFSET) +#define SAM_PIO_PPDDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIO_PPDER(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDER_OFFSET) +#define SAM_PIO_PPDSR(n) (SAM_PIO_BASE(n)+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIO_OWER(n) (SAM_PIO_BASE(n)+SAM_PIO_OWER_OFFSET) +#define SAM_PIO_OWDR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWDR_OFFSET) +#define SAM_PIO_OWSR(n) (SAM_PIO_BASE(n)+SAM_PIO_OWSR_OFFSET) +#define SAM_PIO_AIMER(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMER_OFFSET) +#define SAM_PIO_AIMDR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIO_AIMMR(n) (SAM_PIO_BASE(n)+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIO_ESR(n) (SAM_PIO_BASE(n)+SAM_PIO_ESR_OFFSET) +#define SAM_PIO_LSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LSR_OFFSET) +#define SAM_PIO_ELSR(n) (SAM_PIO_BASE(n)+SAM_PIO_ELSR_OFFSET) +#define SAM_PIO_FELLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIO_REHLSR(n) (SAM_PIO_BASE(n)+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIO_FRLHSR(n) (SAM_PIO_BASE(n)+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIO_LOCKSR(n) (SAM_PIO_BASE(n)+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIO_WPMR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPMR_OFFSET) +#define SAM_PIO_WPSR(n) (SAM_PIO_BASE(n)+SAM_PIO_WPSR_OFFSET) +#define SAM_PIO_SCHMITT(n) (SAM_PIO_BASE(n)+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIO_PCMR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCMR_OFFSET) +#define SAM_PIO_PCIER(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIER_OFFSET) +#define SAM_PIO_PCIDR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIO_PCIMR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIO_PCISR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCISR_OFFSET) +#define SAM_PIO_PCRHR(n) (SAM_PIO_BASE(n)+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOA_PER (SAM_PIOA_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOA_PDR (SAM_PIOA_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOA_PSR (SAM_PIOA_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOA_OER (SAM_PIOA_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOA_ODR (SAM_PIOA_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOA_OSR (SAM_PIOA_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOA_IFER (SAM_PIOA_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOA_IFDR (SAM_PIOA_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOA_IFSR (SAM_PIOA_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIOA_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIOA_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIOA_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIOA_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIOA_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIOA_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIOA_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIOA_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_MDER (SAM_PIOA_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOA_MDDR (SAM_PIOA_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOA_MDSR (SAM_PIOA_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOA_PUDR (SAM_PIOA_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOA_PUER (SAM_PIOA_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOA_PUSR (SAM_PIOA_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOA_ABCDSR1 (SAM_PIOA_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOA_ABCDSR2 (SAM_PIOA_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOA_IFSCDR (SAM_PIOA_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOA_IFSCER (SAM_PIOA_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOA_IFSCSR (SAM_PIOA_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOA_SCDR (SAM_PIOA_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOA_PPDDR (SAM_PIOA_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOA_PPDER (SAM_PIOA_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOA_PPDSR (SAM_PIOA_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOA_OWER (SAM_PIOA_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOA_OWDR (SAM_PIOA_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOA_OWSR (SAM_PIOA_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOA_AIMER (SAM_PIOA_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOA_AIMDR (SAM_PIOA_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOA_AIMMR (SAM_PIOA_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOA_ESR (SAM_PIOA_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOA_LSR (SAM_PIOA_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOA_ELSR (SAM_PIOA_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOA_FELLSR (SAM_PIOA_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOA_REHLSR (SAM_PIOA_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOA_FRLHSR (SAM_PIOA_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOA_LOCKSR (SAM_PIOA_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOA_WPMR (SAM_PIOA_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOA_WPSR (SAM_PIOA_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOA_SCHMITT (SAM_PIOA_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOA_PCMR (SAM_PIOA_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOA_PCIER (SAM_PIOA_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOA_PCIDR (SAM_PIOA_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOA_PCIMR (SAM_PIOA_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOA_PCISR (SAM_PIOA_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOA_PCRHR (SAM_PIOA_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOB_PER (SAM_PIOB_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOB_PDR (SAM_PIOB_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOB_PSR (SAM_PIOB_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOB_OER (SAM_PIOB_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOB_ODR (SAM_PIOB_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOB_OSR (SAM_PIOB_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOB_IFER (SAM_PIOB_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOB_IFDR (SAM_PIOB_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOB_IFSR (SAM_PIOB_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOB_SODR (SAM_PIOB_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOB_CODR (SAM_PIOB_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOB_ODSR (SAM_PIOB_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOB_PDSR (SAM_PIOB_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOB_IER (SAM_PIOB_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOB_IDR (SAM_PIOB_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOB_IMR (SAM_PIOB_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOB_ISR (SAM_PIOB_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOB_MDER (SAM_PIOB_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOB_MDDR (SAM_PIOB_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOB_MDSR (SAM_PIOB_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOB_PUDR (SAM_PIOB_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOB_PUER (SAM_PIOB_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOB_PUSR (SAM_PIOB_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOB_ABCDSR1 (SAM_PIOB_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOB_ABCDSR2 (SAM_PIOB_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOB_IFSCDR (SAM_PIOB_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOB_IFSCER (SAM_PIOB_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOB_IFSCSR (SAM_PIOB_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOB_SCDR (SAM_PIOB_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOB_PPDDR (SAM_PIOB_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOB_PPDER (SAM_PIOB_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOB_PPDSR (SAM_PIOB_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOB_OWER (SAM_PIOB_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOB_OWDR (SAM_PIOB_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOB_OWSR (SAM_PIOB_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOB_AIMER (SAM_PIOB_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOB_AIMDR (SAM_PIOB_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOB_AIMMR (SAM_PIOB_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOB_ESR (SAM_PIOB_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOB_LSR (SAM_PIOB_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOB_ELSR (SAM_PIOB_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOB_FELLSR (SAM_PIOB_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOB_REHLSR (SAM_PIOB_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOB_FRLHSR (SAM_PIOB_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOB_LOCKSR (SAM_PIOB_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOB_WPMR (SAM_PIOB_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOB_WPSR (SAM_PIOB_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOB_SCHMITT (SAM_PIOB_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOB_PCMR (SAM_PIOB_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOB_PCIER (SAM_PIOB_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOB_PCIDR (SAM_PIOB_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOB_PCIMR (SAM_PIOB_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOB_PCISR (SAM_PIOB_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOB_PCRHR (SAM_PIOB_BASE+SAM_PIO_PCRHR_OFFSET + +#define SAM_PIOC_PER (SAM_PIOC_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOC_PDR (SAM_PIOC_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOC_PSR (SAM_PIOC_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOC_OER (SAM_PIOC_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOC_ODR (SAM_PIOC_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOC_OSR (SAM_PIOC_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOC_IFER (SAM_PIOC_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOC_IFDR (SAM_PIOC_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOC_IFSR (SAM_PIOC_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOC_SODR (SAM_PIOC_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOC_CODR (SAM_PIOC_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOC_ODSR (SAM_PIOC_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOC_PDSR (SAM_PIOC_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOC_IER (SAM_PIOC_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOC_IDR (SAM_PIOC_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOC_IMR (SAM_PIOC_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOC_ISR (SAM_PIOC_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOC_MDER (SAM_PIOC_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOC_MDDR (SAM_PIOC_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOC_MDSR (SAM_PIOC_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOC_PUDR (SAM_PIOC_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOC_PUER (SAM_PIOC_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOC_PUSR (SAM_PIOC_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOC_ABCDSR1 (SAM_PIOC_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOC_ABCDSR2 (SAM_PIOC_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOC_IFSCDR (SAM_PIOC_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOC_IFSCER (SAM_PIOC_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOC_IFSCSR (SAM_PIOC_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOC_SCDR (SAM_PIOC_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOC_PPDDR (SAM_PIOC_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOC_PPDER (SAM_PIOC_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOC_PPDSR (SAM_PIOC_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOC_OWER (SAM_PIOC_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOC_OWDR (SAM_PIOC_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOC_OWSR (SAM_PIOC_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOC_AIMER (SAM_PIOC_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOC_AIMDR (SAM_PIOC_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOC_AIMMR (SAM_PIOC_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOC_ESR (SAM_PIOC_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOC_LSR (SAM_PIOC_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOC_ELSR (SAM_PIOC_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOC_FELLSR (SAM_PIOC_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOC_REHLSR (SAM_PIOC_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOC_FRLHSR (SAM_PIOC_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOC_LOCKSR (SAM_PIOC_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOC_WPMR (SAM_PIOC_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOC_WPSR (SAM_PIOC_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOC_SCHMITT (SAM_PIOC_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOC_PCMR (SAM_PIOC_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOC_PCIER (SAM_PIOC_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOC_PCIDR (SAM_PIOC_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOC_PCIMR (SAM_PIOC_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOC_PCISR (SAM_PIOC_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOC_PCRHR (SAM_PIOC_BASE+SAM_PIO_PCRHR_OFFSET + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for ALMOST all IO registers (exceptions follow) */ + +#define PIO(n) (1 << (n)) /* Bit n: PIO n */ + +/* PIO Write Protect Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PIO_WPMR_WPKEY_MASK (0xffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x50494f << PIO_WPMR_WPKEY_SHIFT) + +/* PIO Write Protect Status Register */ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/* PIO Parallel Capture Mode Register */ + +#define PIO_PCMR_PCEN (1 << 0) /* Bit 0: Parallel Capture Mode Enable */ +#define PIO_PCMR_DSIZE_SHIFT (4) /* Bits 4-5: Parallel Capture Mode Data Size */ +#define PIO_PCMR_DSIZE_MASK (3 << PIO_PCMR_DSIZE_SHIFT) +# define PIO_PCMR_DSIZE_BYTE (0 << PIO_PCMR_DSIZE_SHIFT) /* 8-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_HWORD (1 << PIO_PCMR_DSIZE_SHIFT) /* 16-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_WORD (2 << PIO_PCMR_DSIZE_SHIFT) /* 32-bit data in PIO_PCRHR */ +#define PIO_PCMR_ALWYS (1 << 9) /* Bit 9: Parallel Capture Mode Always Sampling */ +#define PIO_PCMR_HALFS (1 << 10) /* Bit 10: Parallel Capture Mode Half Sampling */ +#define PIO_PCMR_FRSTS (1 << 11) /* Bit 11: Parallel Capture Mode First Sample */ + +/* PIO Parallel Capture Interrupt Enable, Disable, Mask, and Status Registers */ + +#define PIOC_PCINT_DRDY (1 << 0) /* Bit 0: Parallel Capture Mode Data Ready Interrupt Enable */ +#define PIOC_PCINT_OVRE (1 << 1) /* Bit 1: Parallel Capture Mode Overrun Error Interrupt Enable */ +#define PIOC_PCINT_ENDRX (1 << 2) /* Bit 2: End of Reception Transfer Interrupt Enable */ +#define PIOC_PCINT_RXBUFF (1 << 3) /* Bit 3: Reception Buffer Full Interrupt Enable */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4S_PIO_H */ diff --git a/arch/arm/src/sam34/chip/sam4s_vectors.h b/arch/arm/src/sam34/chip/sam4s_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..420dbfcb6d69593370c1f38f83f72ae657115d41 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam4s_vectors.h @@ -0,0 +1,92 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam4s_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* This file is included by sam_vectors.S. It provides the macro VECTOR that + * supplies ach SAM4S vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/sam/sam3u_irq.h. + * sam_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 35 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 35 + +#else + VECTOR(sam_supc, SAM_IRQ_SUPC) /* Vector 16+0: Supply Controller */ + VECTOR(sam_rstc, SAM_IRQ_RSTC) /* Vector 16+1: Reset Controller */ + VECTOR(sam_rtc, SAM_IRQ_RTC) /* Vector 16+2: Real Time Clock */ + VECTOR(sam_rtt, SAM_IRQ_RTT) /* Vector 16+3: Real Time Timer */ + VECTOR(sam_wdt, SAM_IRQ_WDT) /* Vector 16+4: Watchdog Timer */ + VECTOR(sam_pmc, SAM_IRQ_PMC) /* Vector 16+5: Power Management Controller */ + VECTOR(sam_eefc0, SAM_IRQ_EEFC0) /* Vector 16+6: Enhanced Embedded Flash Controller 0 */ + VECTOR(sam_eefc1, SAM_IRQ_EEFC1) /* Vector 16+7: Enhanced Embedded Flash Controller 1 */ + VECTOR(sam_uart0, SAM_IRQ_UART0) /* Vector 16+8: Universal Asynchronous Receiver Transmitter 0 */ + VECTOR(sam_uart1, SAM_IRQ_UART1) /* Vector 16+9: Universal Asynchronous Receiver Transmitter 1 */ + VECTOR(sam_smc, SAM_IRQ_SMC) /* Vector 16+10: Static Memory Controller */ + VECTOR(sam_pioa, SAM_IRQ_PIOA) /* Vector 16+11: Parallel I/O Controller A */ + VECTOR(sam_piob, SAM_IRQ_PIOB) /* Vector 16+12: Parallel I/O Controller B */ + VECTOR(sam_pioc, SAM_IRQ_PIOC) /* Vector 16+13: Parallel I/O Controller C */ + VECTOR(sam_usart0, SAM_IRQ_USART0) /* Vector 16+14: USART 0 */ + VECTOR(sam_usart1, SAM_IRQ_USART1) /* Vector 16+15: USART 1 */ + UNUSED(SAM_IRQ_RESERVED_16) /* Vector 16+16: Reserved */ + UNUSED(SAM_IRQ_RESERVED_17) /* Vector 16+17: Reserved */ + VECTOR(sam_hsmci, SAM_IRQ_HSMCI) /* Vector 16+18: High Speed Multimedia Card Interface */ + VECTOR(sam_twi0, SAM_IRQ_TWI0) /* Vector 16+19: Two-Wire Interface 0 */ + VECTOR(sam_twi1, SAM_IRQ_TWI1) /* Vector 16+20: Two-Wire Interface 1 */ + VECTOR(sam_spi0, SAM_IRQ_SPI0) /* Vector 16+21: Serial Peripheral Interface */ + VECTOR(sam_ssc, SAM_IRQ_SSC) /* Vector 16+22: Synchronous Serial Controller */ + VECTOR(sam_tc0, SAM_IRQ_TC0) /* Vector 16+23: Timer Counter 0 */ + VECTOR(sam_tc1, SAM_IRQ_TC1) /* Vector 16+24: Timer Counter 1 */ + VECTOR(sam_tc2, SAM_IRQ_TC2) /* Vector 16+25: Timer Counter 2 */ + VECTOR(sam_tc3, SAM_IRQ_TC3) /* Vector 16+26: Timer Counter 3 */ + VECTOR(sam_tc4, SAM_IRQ_TC4) /* Vector 16+27: Timer Counter 4 */ + VECTOR(sam_tc5, SAM_IRQ_TC5) /* Vector 16+28: Timer Counter 5 */ + VECTOR(sam_adc, SAM_IRQ_ADC) /* Vector 16+29: Analog To Digital Converter */ + VECTOR(sam_dacc, SAM_IRQ_DACC) /* Vector 16+30: Digital To Analog Converter */ + VECTOR(sam_pwm, SAM_IRQ_PWM) /* Vector 16+31: Pulse Width Modulation */ + VECTOR(sam_crccu, SAM_IRQ_CRCCU) /* Vector 16+32: CRC Calculation Unit */ + VECTOR(sam_acc, SAM_IRQ_ACC) /* Vector 16+33: Analog Comparator */ + VECTOR(sam_udp, SAM_IRQ_UDP) /* Vector 16+34: USB Device Port */ +#endif diff --git a/arch/arm/src/sam34/chip/sam_acc.h b/arch/arm/src/sam34/chip/sam_acc.h new file mode 100644 index 0000000000000000000000000000000000000000..1e546ac14a7afc36d332f342ad35e75bb743f6c9 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_acc.h @@ -0,0 +1,154 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_rtt.h + *Analog Comparator Controller (ACC) definitions for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_ACC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_ACC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* ACC register offsets *****************************************************************/ + +#define SAM_ACC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_ACC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_ACC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_ACC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_ACC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_ACC_ISR_OFFSET 0x0030 /* Interrupt Status Register */ +#define SAM_ACC_ACR_OFFSET 0x0094 /* Analog Control Register */ +#define SAM_ACC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_ACC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + +/* ACC register addresses **************************************************************/ + +#define SAM_ACC_CR (SAM_ACC_BASE+SAM_ACC_CR_OFFSET) +#define SAM_ACC_MR (SAM_ACC_BASE+SAM_ACC_MR_OFFSET) +#define SAM_ACC_IER (SAM_ACC_BASE+SAM_ACC_IER_OFFSET) +#define SAM_ACC_IDR (SAM_ACC_BASE+SAM_ACC_IDR_OFFSET) +#define SAM_ACC_IMR (SAM_ACC_BASE+SAM_ACC_IMR_OFFSET) +#define SAM_ACC_ISR (SAM_ACC_BASE+SAM_ACC_ISR_OFFSET) +#define SAM_ACC_ACR (SAM_ACC_BASE+SAM_ACC_ACR_OFFSET +#define SAM_ACC_WPMR (SAM_ACC_BASE+SAM_ACC_WPMR_OFFSET) +#define SAM_ACC_WPSR (SAM_ACC_BASE+SAM_ACC_WPSR_OFFSET + +/* ACC register bit definitions ********************************************************/ + +/* Control Register */ + +#define ACC_CR_SWRST (1 << 0) /* Bit 0: Software reset */ + +/* Mode Register */ + +#define ACC_MR_SELMINUS_SHIFT (0) /* Bits 0-2: Selection for minus comparator input */ +#define ACC_MR_SELMINUS_MASK (7 << ACC_MR_SELMINUS_SHIFT) +# define ACC_MR_SELMINUS_TS (0 << ACC_MR_SELMINUS_SHIFT) /* Select TS */ +# define ACC_MR_SELMINUS_ADVREF (1 << ACC_MR_SELMINUS_SHIFT) /* Select ADVREF */ +# define ACC_MR_SELMINUS_DAC0 (2 << ACC_MR_SELMINUS_SHIFT) /* Select DAC0 */ +# define ACC_MR_SELMINUS_DAC1 (3 << ACC_MR_SELMINUS_SHIFT) /* Select DAC1 */ +# define ACC_MR_SELMINUS_AD0 (4 << ACC_MR_SELMINUS_SHIFT) /* Select AD0 */ +# define ACC_MR_SELMINUS_AD1 (5 << ACC_MR_SELMINUS_SHIFT) /* Select AD1 */ +# define ACC_MR_SELMINUS_AD2 (6 << ACC_MR_SELMINUS_SHIFT) /* Select AD2 */ +# define ACC_MR_SELMINUS_AD3 (7 << ACC_MR_SELMINUS_SHIFT) /* Select AD3 */ +#define ACC_MR_SELPLUS_SHIFT (4) /* Bits 4-6: Selection for plus comparator input */ +#define ACC_MR_SELPLUS_MASK (7 << ACC_MR_SELPLUS_SHIFT) +# define ACC_MR_SELPLUS_AD(n) ((uint32_t)(n) << ACC_MR_SELPLUS_SHIFT) /* Select ADn, n=0-7 */ +# define ACC_MR_SELPLUS_AD0 (0 << ACC_MR_SELPLUS_SHIFT) /* Select AD0 */ +# define ACC_MR_SELPLUS_AD1 (1 << ACC_MR_SELPLUS_SHIFT) /* Select AD1 */ +# define ACC_MR_SELPLUS_AD2 (2 << ACC_MR_SELPLUS_SHIFT) /* Select AD2 */ +# define ACC_MR_SELPLUS_AD3 (3 << ACC_MR_SELPLUS_SHIFT) /* Select AD3 */ +# define ACC_MR_SELPLUS_AD4 (4 << ACC_MR_SELPLUS_SHIFT) /* Select AD4 */ +# define ACC_MR_SELPLUS_AD5 (5 << ACC_MR_SELPLUS_SHIFT) /* Select AD5 */ +# define ACC_MR_SELPLUS_AD6 (6 << ACC_MR_SELPLUS_SHIFT) /* Select AD6 */ +# define ACC_MR_SELPLUS_AD7 (7 << ACC_MR_SELPLUS_SHIFT) /* Select AD7 */ +#define ACC_MR_ACEN (1 << 8) /* Bit 8: Analog comparator enable */ +#define ACC_MR_EDGETYP_SHIFT (9) /* Bits 9-10: Edge type */ +#define ACC_MR_EDGETYP_MASK (3 << ACC_MR_EDGETYP_SHIFT) +# define ACC_MR_EDGETYP_RISING (0 << ACC_MR_EDGETYP_SHIFT) /* Only rising edge of comparator output */ +# define ACC_MR_EDGETYP_FALLING (1 << ACC_MR_EDGETYP_SHIFT) /* Falling edge of comparator output */ +# define ACC_MR_EDGETYP_ANY (2 << ACC_MR_EDGETYP_SHIFT) /* Any edge of comparator output */ +#define ACC_MR_INV (1 << 12) /* Bit 12: Invert comparator output */ +#define ACC_MR_SELFS (1 << 13) /* Bit 13: Selection of fault source */ +#define ACC_MR_FE (1 << 14) /* Bit 14: Fault enable */ + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask, and Interrupt Status */ + +#define ACC_INT_CE (1 << 0) /* Bit 0: Comparison edge interrupt */ + +/* Interrupt Status Register (only) */ + +#define ACC_ISR_SCO (1 << 1) /* Bit 1: Synchronized Comparator Output */ +#define ACC_ISR_MASK (1 << 31) + +/* Analog Control Register */ + +#define ACC_ACR_ISEL (1 << 0) /* Bit 0: Current selection */ +#define ACC_ACR_HYST_SHIFT (1) /* Bits 1-2: Hysteresis selection */ +#define ACC_ACR_HYST_MASK (3 << ACC_ACR_HYST_SHIFT) + +/* Write Protect Mode Register */ + +#define ACC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define ACC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define ACC_WPMR_WPKEY_MASK (0x00ffffff << ACC_WPMR_WPKEY_SHIFT) +# define ACC_WPMR_WPKEY (0x00414343 << ACC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define ACC_WPSR_WPROTERR (1 << 0) /* Bit 0: Write protection error */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_ACC_H */ diff --git a/arch/arm/src/sam34/chip/sam_adc.h b/arch/arm/src/sam34/chip/sam_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..dd53ba4012e186464eed983e453c617f1c9ac982 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_adc.h @@ -0,0 +1,247 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_adc.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_ADC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_ADC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_ADC_NCHANNELS 8 /* 8 ADC Channels */ + +/* ADC register offsets *****************************************************************/ + +#define SAM_ADC_CR_OFFSET 0x00 /* Control Register (Both) */ +#define SAM_ADC_MR_OFFSET 0x04 /* Mode Register (Both) */ + /* 0x08: Reserved */ + /* 0x0c: Reserved */ +#define SAM_ADC_CHER_OFFSET 0x10 /* Channel Enable Register (Both) */ +#define SAM_ADC_CHDR_OFFSET 0x14 /* Channel Disable Register (Both) */ +#define SAM_ADC_CHSR_OFFSET 0x18 /* Channel Status Register (Both) */ +#define SAM_ADC_SR_OFFSET 0x1c /* Status Register (Both) */ +#define SAM_ADC_LCDR_OFFSET 0x20 /* Last Converted Data Register (Both) */ +#define SAM_ADC_IER_OFFSET 0x24 /* Interrupt Enable Register (Both) */ +#define SAM_ADC_IDR_OFFSET 0x28 /* Interrupt Disable Register (Both) */ +#define SAM_ADC_IMR_OFFSET 0x2c /* Interrupt Mask Register (Both) */ +#define SAM_ADC_CDR_OFFSET(n) (0x30+((n)<<2)) +# define SAM_ADC_CDR0_OFFSET 0x30 /* Channel Data Register 0 (Both) */ +# define SAM_ADC_CDR1_OFFSET 0x34 /* Channel Data Register 1 (Both) */ +# define SAM_ADC_CDR2_OFFSET 0x38 /* Channel Data Register 2 (Both) */ +# define SAM_ADC_CDR3_OFFSET 0x3c /* Channel Data Register 3 (Both) */ +# define SAM_ADC_CDR4_OFFSET 0x40 /* Channel Data Register 4 (Both) */ +# define SAM_ADC_CDR5_OFFSET 0x44 /* Channel Data Register 5 (Both) */ +# define SAM_ADC_CDR6_OFFSET 0x48 /* Channel Data Register 6 (Both) */ +# define SAM_ADC_CDR7_OFFSET 0x4c /* Channel Data Register 7 (Both) */ +#define SAM_ADC12B_ACR_OFFSET 0x64 /* Analog Control Register (ADC12B only) */ +#define SAM_ADC12B_EMR_OFFSET 0x68 /* Extended Mode Register (ADC12B only) */ + +/* ADC register addresses ***************************************************************/ + +#define SAM_ADC12B_CR (SAM_ADC12B_BASE+SAM_ADC_CR_OFFSET) +#define SAM_ADC12B_MR (SAM_ADC12B_BASE+SAM_ADC_MR_OFFSET) +#define SAM_ADC12B_CHER (SAM_ADC12B_BASE+SAM_ADC_CHER_OFFSET) +#define SAM_ADC12B_CHDR (SAM_ADC12B_BASE+SAM_ADC_CHDR_OFFSET) +#define SAM_ADC12B_CHSR (SAM_ADC12B_BASE+SAM_ADC_CHSR_OFFSET) +#define SAM_ADC12B_SR (SAM_ADC12B_BASE+SAM_ADC_SR_OFFSET) +#define SAM_ADC12B_LCDR (SAM_ADC12B_BASE+SAM_ADC_LCDR_OFFSET) +#define SAM_ADC12B_IER (SAM_ADC12B_BASE+SAM_ADC_IER_OFFSET) +#define SAM_ADC12B_IDR (SAM_ADC12B_BASE+SAM_ADC_IDR_OFFSET) +#define SAM_ADC12B_IMR (SAM_ADC12B_BASE+SAM_ADC_IMR_OFFSET) +#define SAM_ADC12B_CDR(n) (SAM_ADC12B_BASE+SAM_ADC_CDR_OFFSET(n)) +# define SAM_ADC12B_CDR0 (SAM_ADC12B_BASE+SAM_ADC_CDR0_OFFSET) +# define SAM_ADC12B_CDR1 (SAM_ADC12B_BASE+SAM_ADC_CDR1_OFFSET) +# define SAM_ADC12B_CDR2 (SAM_ADC12B_BASE+SAM_ADC_CDR2_OFFSET) +# define SAM_ADC12B_CDR3 (SAM_ADC12B_BASE+SAM_ADC_CDR3_OFFSET) +# define SAM_ADC12B_CDR4 (SAM_ADC12B_BASE+SAM_ADC_CDR4_OFFSET) +# define SAM_ADC12B_CDR5 (SAM_ADC12B_BASE+SAM_ADC_CDR5_OFFSET) +# define SAM_ADC12B_CDR6 (SAM_ADC12B_BASE+SAM_ADC_CDR6_OFFSET) +# define SAM_ADC12B_CDR7 (SAM_ADC12B_BASE+SAM_ADC_CDR7_OFFSET) +#define SAM_ADC12B_ACR (SAM_ADC12B_BASE+SAM_ADC12B_ACR_OFFSET) +#define SAM_ADC12B_EMR (SAM_ADC12B_BASE+SAM_ADC12B_EMR_OFFSET) + +#define SAM_ADC_CR (SAM_ADC_BASE+SAM_ADC_CR_OFFSET) +#define SAM_ADC_MR (SAM_ADC_BASE+SAM_ADC_MR_OFFSET) +#define SAM_ADC_CHER (SAM_ADC_BASE+SAM_ADC_CHER_OFFSET) +#define SAM_ADC_CHDR (SAM_ADC_BASE+SAM_ADC_CHDR_OFFSET) +#define SAM_ADC_CHSR (SAM_ADC_BASE+SAM_ADC_CHSR_OFFSET) +#define SAM_ADC_SR (SAM_ADC_BASE+SAM_ADC_SR_OFFSET) +#define SAM_ADC_LCDR (SAM_ADC_BASE+SAM_ADC_LCDR_OFFSET) +#define SAM_ADC_IER (SAM_ADC_BASE+SAM_ADC_IER_OFFSET) +#define SAM_ADC_IDR (SAM_ADC_BASE+SAM_ADC_IDR_OFFSET) +#define SAM_ADC_IMR (SAM_ADC_BASE+SAM_ADC_IMR_OFFSET) +#define SAM_ADC_CDR(n) (SAM_ADC_BASE+SAM_ADC_CDR_OFFSET(n)) +# define SAM_ADC_CDR0 (SAM_ADC_BASE+SAM_ADC_CDR0_OFFSET) +# define SAM_ADC_CDR1 (SAM_ADC_BASE+SAM_ADC_CDR1_OFFSET) +# define SAM_ADC_CDR2 (SAM_ADC_BASE+SAM_ADC_CDR2_OFFSET) +# define SAM_ADC_CDR3 (SAM_ADC_BASE+SAM_ADC_CDR3_OFFSET) +# define SAM_ADC_CDR4 (SAM_ADC_BASE+SAM_ADC_CDR4_OFFSET) +# define SAM_ADC_CDR5 (SAM_ADC_BASE+SAM_ADC_CDR5_OFFSET) +# define SAM_ADC_CDR6 (SAM_ADC_BASE+SAM_ADC_CDR6_OFFSET) +# define SAM_ADC_CDR7 (SAM_ADC_BASE+SAM_ADC_CDR7_OFFSET) + +/* ADC register bit definitions *********************************************************/ + +/* ADC12B Control Register and ADC(10B) Control Register common bit-field definitions */ + +#define ADC_CR_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define ADC_CR_START (1 << 1) /* Bit 1: Start Conversion */ + +/* ADC12B Mode Register and ADC(10B) Mode Register common bit-field definitions */ + +#define ADC_MR_TRGEN (1 << 0) /* Bit 0: Trigger Enable */ +#define ADC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define ADC_MR_TRGSEL_MASK (7 << ADC_MR_TRGSEL_SHIFT) +# define ADC_MR_TRGSEL(n) ((uint32_t)(n) << ADC_MR_TRGSEL_SHIFT) +#define ADC_MR_LOWRES (1 << 4) /* Bit 4: Resolution */ +#define ADC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ +#define ADC_MR_PRESCAL_SHIFT (8) /* Bits 8-15: Prescaler Rate Selection */ +#define ADC_MR_PRESCAL_MASK (0xff << ADC_MR_PRESCAL_SHIFT) +# define ADC_MR_PRESCAL(n) ((uint32_t)(n) << ADC_MR_PRESCAL_SHIFT) +#define ADB12B_MR_STARTUP_SHIFT (16) /* Bits 16-23: Start Up Time (ADC12B) */ +#define ADB12B_MR_STARTUP_MASK (0xff << ADB12B_MR_STARTUP_SHIFT +# define ADB12B_MR_STARTUP(n) ((uint32_t)(n) << ADB12B_MR_STARTUP_SHIFT +#define ADB10B_MR_STARTUP_SHIFT (16) /* Bits 16-22: Start Up Time (ADC10B) */ +#define ADB10B_MR_STARTUP_MASK (0x7f << ADB10B_MR_STARTUP_SHIFT) +# define ADB10B_MR_STARTUP(n) ((uint32_t)(n) << ADB10B_MR_STARTUP_SHIFT) +#define ADC_MR_SHTIM_SHIFT (24) /* Bits 24-27: Sample & Hold Time */ +#define ADC_MR_SHTIM_MASK (15 << ADC_MR_SHTIM_SHIFT) +# define ADC_MR_SHTIM(n) ((uint32_t)(n) << ADC_MR_SHTIM_SHIFT) + +/* ADC12B Channel Enable Register, ADC12B Channel Disable Register, ADC12B Channel + * Status Register, ADC(10B) Channel Enable Register, ADC(10B) Channel Disable Register, + * and ADC(10B) Channel Status Register common bit-field definitions + */ + +#define ADC_CH(n) (1 << (n)) +# define ADC_CH0 (1 << 0) /* Bit 0: Channel 0 Enable */ +# define ADC_CH1 (1 << 1) /* Bit 1: Channel 1 Enable */ +# define ADC_CH2 (1 << 2) /* Bit 2: Channel 2 Enable */ +# define ADC_CH3 (1 << 3) /* Bit 3: Channel 3 Enable */ +# define ADC_CH4 (1 << 4) /* Bit 4: Channel 4 Enable */ +# define ADC_CH5 (1 << 5) /* Bit 5: Channel 5 Enable */ +# define ADC_CH6 (1 << 6) /* Bit 6: Channel 6 Enable */ +# define ADC_CH7 (1 << 7) /* Bit 7: Channel 7 Enable */ + +/* ADC12B Analog Control Register (ADC12B only) */ + +#define ADC12B_ACR_GAIN_SHIFT (0) /* Bits 0-1: Input Gain */ +#define ADC12B_ACR_GAIN_MASK (3 << ADC12B_ACR_GAIN_SHIFT) +# define ADC12B_ACR_GAIN(n) ((uint32_t)(n) << ADC12B_ACR_GAIN_SHIFT) +#define ADC12B_ACR_IBCTL_SHIFT (8) /* Bits 8-9: Bias Current Control */ +#define ADC12B_ACR_IBCTL_MASK (3 << ADC12B_ACR_IBCTL_SHIFT) +# define ADC12B_ACR_IBCTL(n) ((uint32_t)(n) << ADC12B_ACR_IBCTL_SHIFT) +#define ADC12B_ACR_DIFF (1 << 16) /* Bit 16: Differential Mode */ +#define ADC12B_ACR_OFFSET (1 << 17) /* Bit 17: Input OFFSET */ + +/* ADC12B Extended Mode Register (ADC12B only) */ + +#define ADC12B_EMR_OFFMODES (1 << 0) /* Bit 0: Off Mode if Sleep Bit (ADC12B_MR) = 1 */ +#define ADC12B_EMR_OFFMSTIME_SHIFT (16) /* Bits 16-23: Startup Time */ +#define ADC12B_EMR_OFFMSTIME_MASK (0xff << ADC12B_EMR_OFFMSTIME_SHIFT) +# define ADC12B_EMR_OFFMSTIME(n) ((uint32_t)(n) << ADC12B_EMR_OFFMSTIME_SHIFT) + +/* ADC12B Status Register , ADC12B Interrupt Enable Register, ADC12B Interrupt + * Disable Register, ADC12B Interrupt Mask Register, ADC(10B) Status Register, + * ADC(10B) Interrupt Enable Register, ADC(10B) Interrupt Disable Register, and + * ADC(10B) Interrupt Mask Register common bit-field definitions + */ + +#define ADC_INT_EOC(n) (1 << (n)) +# define ADC_INT_EOC0 (1 << 0) /* Bit 0: End of Conversion 0 */ +# define ADC_INT_EOC1 (1 << 1) /* Bit 1: End of Conversion 1 */ +# define ADC_INT_EOC2 (1 << 2) /* Bit 2: End of Conversion 2 */ +# define ADC_INT_EOC3 (1 << 3) /* Bit 3: End of Conversion 3 */ +# define ADC_INT_EOC4 (1 << 4) /* Bit 4: End of Conversion 4 */ +# define ADC_INT_EOC5 (1 << 5) /* Bit 5: End of Conversion 5 */ +# define ADC_INT_EOC6 (1 << 6) /* Bit 6: End of Conversion 6 */ +# define ADC_INT_EOC7 (1 << 7) /* Bit 7: End of Conversion 7 */ +#define ADC_INT_OVRE(n) (1 << ((n)+8)) +# define ADC_INT_OVRE0 (1 << 8) /* Bit 8: Overrun Error 0 */ +# define ADC_INT_OVRE1 (1 << 9) /* Bit 9: Overrun Error 1 */ +# define ADC_INT_OVRE2 (1 << 10) /* Bit 10: Overrun Error 2 */ +# define ADC_INT_OVRE3 (1 << 11) /* Bit 11: Overrun Error 3 */ +# define ADC_INT_OVRE4 (1 << 12) /* Bit 12: Overrun Error 4 */ +# define ADC_INT_OVRE5 (1 << 13) /* Bit 13: Overrun Error 5 */ +# define ADC_INT_OVRE6 (1 << 14) /* Bit 14: Overrun Error 6 */ +# define ADC_INT_OVRE7 (1 << 15) /* Bit 15: Overrun Error 7 */ +#define ADC_INT_DRDY (1 << 16) /* Bit 16: Data Ready */ +#define ADC_INT_GOVRE (1 << 17) /* Bit 17: General Overrun Error */ +#define ADC_INT_ENDRX (1 << 18) /* Bit 18: End of RX Buffer */ +#define ADC_INT_RXBUFF (1 << 19) /* Bit 19: RX Buffer Full */ + +/* ADC12B Last Converted Data Register */ + +#define ADC12B_LCDR_DATA_SHIFT (0) /* Bits 0-11: Last Data Converted */ +#define ADC12B_LCDR_DATA_MASK (0xfff << ADC12B_LCDR_DATA_SHIFT) + +/* ADC(10B) Last Converted Data Register */ + +#define ADC10B_LCDR_DATA_SHIFT (0) /* Bits 0-9: Last Data Converted */ +#define ADC10B_LCDR_DATA_MASK (0x1ff << ADC10B_LCDR_DATA_SHIFT) + +/* ADC12B Channel Data Register */ + +#define ADC12B_CDR_DATA_SHIFT (0) /* Bits 0-11: Converted Data */ +#define ADC12B_CDR_DATA_MASK (0xfff << ADC12B_CDR_DATA_SHIFT) + +/* ADC(10B) Channel Data Register */ + +#define ADC10B_CDR_DATA_SHIFT (0) /* Bits 0-9: Converted Data */ +#define ADC10B_CDR_DATA_MASK (0x1ff << ADC10B_CDR_DATA_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_ADC_H */ diff --git a/arch/arm/src/sam34/chip/sam_aes.h b/arch/arm/src/sam34/chip/sam_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..c5ef7ad9a677d9e97d2f72bd82e9abdde4de2bc1 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_aes.h @@ -0,0 +1,188 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_aes.h + * Advanced Encryption Standard (AES) for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_AES_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_AES_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* AES register offsets *****************************************************************/ + +#define SAM_AES_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_AES_MR_OFFSET 0x0004 /* Mode Register */ + /* 0x0008-0x000c: Reserved */ +#define SAM_AES_IER_OFFSET 0x0010 /* Interrupt Enable Register */ +#define SAM_AES_IDR_OFFSET 0x0014 /* Interrupt Disable Register */ +#define SAM_AES_IMR_OFFSET 0x0018 /* Interrupt Mask Register */ +#define SAM_AES_ISR_OFFSET 0x001c /* Interrupt Status Register */ +#define SAM_AES_KEYWR0_OFFSET 0x0020 /* Key Word Register 0 */ +#define SAM_AES_KEYWR1_OFFSET 0x0024 /* Key Word Register 1 */ +#define SAM_AES_KEYWR2_OFFSET 0x0028 /* Key Word Register 2 */ +#define SAM_AES_KEYWR3_OFFSET 0x002c /* Key Word Register 3 */ +#define SAM_AES_KEYWR4_OFFSET 0x0030 /* Key Word Register 4 */ +#define SAM_AES_KEYWR5_OFFSET 0x0034 /* Key Word Register 5 */ +#define SAM_AES_KEYWR6_OFFSET 0x0038 /* Key Word Register 6 */ +#define SAM_AES_KEYWR7_OFFSET 0x003c /* Key Word Register 7 */ +#define SAM_AES_IDATAR0_OFFSET 0x0040 /* Input Data Register 0 */ +#define SAM_AES_IDATAR1_OFFSET 0x0044 /* Input Data Register 1 */ +#define SAM_AES_IDATAR2_OFFSET 0x0048 /* Input Data Register 2 */ +#define SAM_AES_IDATAR3_OFFSET 0x004c /* Input Data Register 3 */ +#define SAM_AES_ODATAR0_OFFSET 0x0050 /* Output Data Register 0 */ +#define SAM_AES_ODATAR1_OFFSET 0x0054 /* Output Data Register 1 */ +#define SAM_AES_ODATAR2_OFFSET 0x0058 /* Output Data Register 2 */ +#define SAM_AES_ODATAR3_OFFSET 0x005c /* Output Data Register 3 */ +#define SAM_AES_IVR0_OFFSET 0x0060 /* Initialization Vector Register 0 */ +#define SAM_AES_IVR1_OFFSET 0x0064 /* Initialization Vector Register 1 */ +#define SAM_AES_IVR2_OFFSET 0x0068 /* Initialization Vector Register 2 */ +#define SAM_AES_IVR3_OFFSET 0x006c /* Initialization Vector Register 3 */ + /* 0x0070-0x00fc: Reserved */ + +/* AES register addresses ***************************************************************/ + +#define SAM_AES_CR (SAM_AES_BASE+SAM_AES_CR_OFFSET) +#define SAM_AES_MR (SAM_AES_BASE+SAM_AES_MR_OFFSET) +#define SAM_AES_IER (SAM_AES_BASE+SAM_AES_IER_OFFSET) +#define SAM_AES_IDR (SAM_AES_BASE+SAM_AES_IDR_OFFSET) +#define SAM_AES_IMR (SAM_AES_BASE+SAM_AES_IMR_OFFSET) +#define SAM_AES_ISR (SAM_AES_BASE+SAM_AES_ISR_OFFSET) +#define SAM_AES_KEYWR0 (SAM_AES_BASE+SAM_AES_KEYWR0_OFFSET) +#define SAM_AES_KEYWR1 (SAM_AES_BASE+SAM_AES_KEYWR1_OFFSET) +#define SAM_AES_KEYWR2 (SAM_AES_BASE+SAM_AES_KEYWR2_OFFSET) +#define SAM_AES_KEYWR3 (SAM_AES_BASE+SAM_AES_KEYWR3_OFFSET) +#define SAM_AES_KEYWR4 (SAM_AES_BASE+SAM_AES_KEYWR4_OFFSET) +#define SAM_AES_KEYWR5 (SAM_AES_BASE+SAM_AES_KEYWR5_OFFSET) +#define SAM_AES_KEYWR6 (SAM_AES_BASE+SAM_AES_KEYWR6_OFFSET) +#define SAM_AES_KEYWR7 (SAM_AES_BASE+SAM_AES_KEYWR7_OFFSET) +#define SAM_AES_IDATAR0 (SAM_AES_BASE+SAM_AES_IDATAR0_OFFSET) +#define SAM_AES_IDATAR1 (SAM_AES_BASE+SAM_AES_IDATAR1_OFFSET) +#define SAM_AES_IDATAR2 (SAM_AES_BASE+SAM_AES_IDATAR2_OFFSET) +#define SAM_AES_IDATAR3 (SAM_AES_BASE+SAM_AES_IDATAR3_OFFSET) +#define SAM_AES_ODATAR0 (SAM_AES_BASE+SAM_AES_ODATAR0_OFFSET) +#define SAM_AES_ODATAR1 (SAM_AES_BASE+SAM_AES_ODATAR1_OFFSET) +#define SAM_AES_ODATAR2 (SAM_AES_BASE+SAM_AES_ODATAR2_OFFSET) +#define SAM_AES_ODATAR3 (SAM_AES_BASE+SAM_AES_ODATAR3_OFFSET) +#define SAM_AES_IVR0 (SAM_AES_BASE+SAM_AES_IVR0_OFFSET) +#define SAM_AES_IVR1 (SAM_AES_BASE+SAM_AES_IVR1_OFFSET) +#define SAM_AES_IVR2 (SAM_AES_BASE+SAM_AES_IVR2_OFFSET) +#define SAM_AES_IVR3 (SAM_AES_BASE+SAM_AES_IVR3_OFFSET) + +/* AES register bit definitions ********************************************************/ + +/* Control Register */ + +#define AES_CR_START (1 << 0) /* Bit 0: Start Processing */ +#define AES_CR_SWRST (1 << 8) /* Bit 8: Software Reset */ + +/* Mode Register */ + +#define AES_MR_CIPHER (1 << 0) /* Bit 0: Processing Mode */ +#define AES_MR_DUALBUFF (1 << 3) /* Bit 3: Dual input buffer */ +#define AES_MR_PROCDLY_SHIFT (4) /* Bits 4-7: Processing delay */ +#define AES_MR_PROCDLY_MASK (15 << AES_MR_PROCDLY_SHIFT) +# define AES_MR_PROCDLY(n) ((uint32_t)(n) << AES_MR_PROCDLY_SHIFT) +#define AES_MR_SMOD_SHIFT (8) /* Bits 8-9: Start mode */ +#define AES_MR_SMOD_MASK (3 << AES_MR_SMOD_SHIFT) +# define AES_MR_SMOD_MANUAL (0 << AES_MR_SMOD_SHIFT) /* Manual Mode */ +# define AES_MR_SMOD_AUTO (1 << AES_MR_SMOD_SHIFT) /* Auto Mode */ +# define AES_MR_SMOD_IDATR0 (2 << AES_MR_SMOD_SHIFT) /* AES_IDATAR0 access only Auto Mode */ +#define AES_MR_KEYSIZE_SHIFT (10) /* Bits 10-11: Key Size */ +#define AES_MR_KEYSIZE_MASK (2 << AES_MR_KEYSIZE_SHIFT) +# define AES_MR_KEYSIZE_AES128 (0 << AES_MR_KEYSIZE_SHIFT) /* AES Key Size is 128 bits */ +# define AES_MR_KEYSIZE_AES192 (1 << AES_MR_KEYSIZE_SHIFT) /* AES Key Size is 192 bits */ +# define AES_MR_KEYSIZE_AES256 (2 << AES_MR_KEYSIZE_SHIFT) /* AES Key Size is 256 bits */ +#define AES_MR_OPMOD_SHIFT (12) /* Bits 12-14: Operation Mode */ +#define AES_MR_OPMOD_MASK (7 << AES_MR_OPMOD_SHIFT) +# define AES_MR_OPMOD_ECB (0 << AES_MR_OPMOD_SHIFT) /* ECB: Electronic Code Book mode */ +# define AES_MR_OPMOD_CBC (1 << AES_MR_OPMOD_SHIFT) /* CBC: Cipher Block Chaining mode */ +# define AES_MR_OPMOD_OFB (2 << AES_MR_OPMOD_SHIFT) /* OFB: Output Feedback mode */ +# define AES_MR_OPMOD_CFB (3 << AES_MR_OPMOD_SHIFT) /* CFB: Cipher Feedback mode */ +# define AES_MR_OPMOD_CTR (4 << AES_MR_OPMOD_SHIFT) /* CTR: Counter mode (16-bit counter) */ +#define AES_MR_LOD (1 << 15) /* Bit 15: Last Output Data Mode */ +#define AES_MR_CFBS_SHIFT (16) /* Bits 16-18: Cipher Feedback Data Size */ +#define AES_MR_CFBS_MASK (7 << AES_MR_CFBS_SHIFT) +# define AES_MR_CFBS_128BIT (0 << AES_MR_CFBS_SHIFT) /* 128-bit */ +# define AES_MR_CFBS_64BIT (1 << AES_MR_CFBS_SHIFT) /* 64-bit */ +# define AES_MR_CFBS_32BIT (2 << AES_MR_CFBS_SHIFT) /* 32-bit */ +# define AES_MR_CFBS_16BIT (3 << AES_MR_CFBS_SHIFT) /* 16-bit */ +# define AES_MR_CFBS_8BIT (4 << AES_MR_CFBS_SHIFT) /* 8-bit */ +#define AES_MR_CKEY_SHIFT (20) /* Bits 20-23: Key */ +#define AES_MR_CKEY_MASK (15 << AES_MR_CKEY_SHIFT) +# define AES_MR_CKEY (14 << AES_MR_CKEY_SHIFT) + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask, and Interrupt Status Register */ + +#define AES_INT_DATRDY (1 << 0) /* Bit 0: Data Ready Interrupt */ +#define AES_INT_URAD (1 << 8) /* Bit 8: Unspecified Register Access Detection Interrupt */ + +/* Interrupt Status Register (only) */ + +#define AES_ISR_URAT_SHIFT (12) /* Bits 12-15: Unspecified Register Access */ +#define AES_ISR_URAT_MASK (15 << AES_ISR_URAT_SHIFT) +# define AES_ISR_URAT_IDRWRPROC (0 << AES_ISR_URAT_SHIFT) /* IDATAR written during data processing */ +# define AES_ISR_URAT_ODRRDPROC (1 << AES_ISR_URAT_SHIFT) /* ODATAR read during data processing */ +# define AES_ISR_URAT_MRWRPROC (2 << AES_ISR_URAT_SHIFT) /* MR written during the data processing */ +# define AES_ISR_URAT_ODRRDSUBKG (3 << AES_ISR_URAT_SHIFT) /* ODATAR read during the sub-keys generation */ +# define AES_ISR_URAT_MRWRSUBKG (4 << AES_ISR_URAT_SHIFT) /* MR written during the sub-keys generation */ +# define AES_ISR_URAT_WORRDACC (5 << AES_ISR_URAT_SHIFT) /* WRONLY register read access */ + +/* Key Word Register 0-7 (32-bit value) */ +/* Input Data Register 0-7 (32-bit value) */ +/* Initialization Vector Register 0-7 (32-bit value) */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_AES_H */ diff --git a/arch/arm/src/sam34/chip/sam_afec.h b/arch/arm/src/sam34/chip/sam_afec.h new file mode 100644 index 0000000000000000000000000000000000000000..9e779a1e4c16f5ce9dc1f4d12e39cc0eeb51cd81 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_afec.h @@ -0,0 +1,538 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_afec.h + * Analog-Front-End Controller (AFEC) definitions for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_AFEC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_AFEC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_ADC_NCHANNELS 16 /* 16 ADC Channels */ + +/* AFEC register offsets ****************************************************************/ + +#define SAM_AFEC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_AFEC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_AFEC_EMR_OFFSET 0x0008 /* Extended Mode Register */ +#define SAM_AFEC_SEQ1R_OFFSET 0x000c /* Channel Sequence 1 Register */ +#define SAM_AFEC_SEQ2R_OFFSET 0x0010 /* Channel Sequence 2 Register */ +#define SAM_AFEC_CHER_OFFSET 0x0014 /* Channel Enable Register */ +#define SAM_AFEC_CHDR_OFFSET 0x0018 /* Channel Disable Register */ +#define SAM_AFEC_CHSR_OFFSET 0x001c /* Channel Status Register */ +#define SAM_AFEC_LCDR_OFFSET 0x0020 /* Last Converted Data Register */ +#define SAM_AFEC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_AFEC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_AFEC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_AFEC_ISR_OFFSET 0x0030 /* Interrupt Status Register */ + /* 0x0034-0x0040 Reserved */ + /* 0x0044-0x0048 Reserved */ +#define SAM_AFEC_OVER_OFFSET 0x004c /* Overrun Status Register */ +#define SAM_AFEC_CWR_OFFSET 0x0050 /* Compare Window Register */ +#define SAM_AFEC_CGR_OFFSET 0x0054 /* Channel Gain Register */ +#define SAM_AFEC_CDOR_OFFSET 0x005c /* Channel Calibration DC Offset Register */ +#define SAM_AFEC_DIFFR_OFFSET 0x0060 /* Channel Differential Register */ +#define SAM_AFEC_CSELR_OFFSET 0x0064 /* Channel Register Selection */ +#define SAM_AFEC_CDR_OFFSET 0x0068 /* Channel Data Register */ +#define SAM_AFEC_COCR_OFFSET 0x006c /* Channel Offset Compensation Register */ +#define SAM_AFEC_TEMPMR_OFFSET 0x0070 /* Temperature Sensor Mode Register */ +#define SAM_AFEC_TEMPCWR_OFFSET 0x0074 /* Temperature Compare Window Register */ +#define SAM_AFEC_ACR_OFFSET 0x0094 /* Analog Control Register */ + /* 0x0098-0x00ac Reserved */ + /* 0x00c4-0x00e0 Reserved */ +#define SAM_AFEC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_AFEC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8 Reserved */ + /* 0x0fc Reserved */ + /* 0x0100-0x0124 Reserved for PDC */ + +/* AFEC register addresses **************************************************************/ + +#define SAM_AFEC0_CR (SAM_AFEC0_BASE+SAM_AFEC_CR_OFFSET) +#define SAM_AFEC0_MR (SAM_AFEC0_BASE+SAM_AFEC_MR_OFFSET) +#define SAM_AFEC0_EMR (SAM_AFEC0_BASE+SAM_AFEC_EMR_OFFSET) +#define SAM_AFEC0_SEQ1R (SAM_AFEC0_BASE+SAM_AFEC_SEQ1R_OFFSET) +#define SAM_AFEC0_SEQ2R (SAM_AFEC0_BASE+SAM_AFEC_SEQ2R_OFFSET) +#define SAM_AFEC0_CHER (SAM_AFEC0_BASE+SAM_AFEC_CHER_OFFSET) +#define SAM_AFEC0_CHDR (SAM_AFEC0_BASE+SAM_AFEC_CHDR_OFFSET) +#define SAM_AFEC0_CHSR (SAM_AFEC0_BASE+SAM_AFEC_CHSR_OFFSET) +#define SAM_AFEC0_LCDR (SAM_AFEC0_BASE+SAM_AFEC_LCDR_OFFSET) +#define SAM_AFEC0_IER (SAM_AFEC0_BASE+SAM_AFEC_IER_OFFSET) +#define SAM_AFEC0_IDR (SAM_AFEC0_BASE+SAM_AFEC_IDR_OFFSET) +#define SAM_AFEC0_IMR (SAM_AFEC0_BASE+SAM_AFEC_IMR_OFFSET) +#define SAM_AFEC0_ISR (SAM_AFEC0_BASE+SAM_AFEC_ISR_OFFSET) +#define SAM_AFEC0_OVER (SAM_AFEC0_BASE+SAM_AFEC_OVER_OFFSET) +#define SAM_AFEC0_CWR (SAM_AFEC0_BASE+SAM_AFEC_CWR_OFFSET) +#define SAM_AFEC0_CGR (SAM_AFEC0_BASE+SAM_AFEC_CGR_OFFSET) +#define SAM_AFEC0_CDOR (SAM_AFEC0_BASE+SAM_AFEC_CDOR_OFFSET) +#define SAM_AFEC0_DIFFR (SAM_AFEC0_BASE+SAM_AFEC_DIFFR_OFFSET) +#define SAM_AFEC0_CSELR (SAM_AFEC0_BASE+SAM_AFEC_CSELR_OFFSET) +#define SAM_AFEC0_CDR (SAM_AFEC0_BASE+SAM_AFEC_CDR_OFFSET) +#define SAM_AFEC0_COCR (SAM_AFEC0_BASE+SAM_AFEC_COCR_OFFSET) +#define SAM_AFEC0_TEMPMR (SAM_AFEC0_BASE+SAM_AFEC_TEMPMR_OFFSET) +#define SAM_AFEC0_TEMPCWR (SAM_AFEC0_BASE+SAM_AFEC_TEMPCWR_OFFSET) +#define SAM_AFEC0_ACR (SAM_AFEC0_BASE+SAM_AFEC_ACR_OFFSET) +#define SAM_AFEC0_WPMR (SAM_AFEC0_BASE+SAM_AFEC_WPMR_OFFSET) +#define SAM_AFEC0_WPSR (SAM_AFEC0_BASE+SAM_AFEC_WPSR_OFFSET) + +#define SAM_AFEC1_CR (SAM_AFEC1_BASE+SAM_AFEC_CR_OFFSET) +#define SAM_AFEC1_MR (SAM_AFEC1_BASE+SAM_AFEC_MR_OFFSET) +#define SAM_AFEC1_EMR (SAM_AFEC1_BASE+SAM_AFEC_EMR_OFFSET) +#define SAM_AFEC1_SEQ1R (SAM_AFEC1_BASE+SAM_AFEC_SEQ1R_OFFSET) +#define SAM_AFEC1_SEQ2R (SAM_AFEC1_BASE+SAM_AFEC_SEQ2R_OFFSET) +#define SAM_AFEC1_CHER (SAM_AFEC1_BASE+SAM_AFEC_CHER_OFFSET) +#define SAM_AFEC1_CHDR (SAM_AFEC1_BASE+SAM_AFEC_CHDR_OFFSET) +#define SAM_AFEC1_CHSR (SAM_AFEC1_BASE+SAM_AFEC_CHSR_OFFSET) +#define SAM_AFEC1_LCDR (SAM_AFEC1_BASE+SAM_AFEC_LCDR_OFFSET) +#define SAM_AFEC1_IER (SAM_AFEC1_BASE+SAM_AFEC_IER_OFFSET) +#define SAM_AFEC1_IDR (SAM_AFEC1_BASE+SAM_AFEC_IDR_OFFSET) +#define SAM_AFEC1_IMR (SAM_AFEC1_BASE+SAM_AFEC_IMR_OFFSET) +#define SAM_AFEC1_ISR (SAM_AFEC1_BASE+SAM_AFEC_ISR_OFFSET) +#define SAM_AFEC1_OVER (SAM_AFEC1_BASE+SAM_AFEC_OVER_OFFSET) +#define SAM_AFEC1_CWR (SAM_AFEC1_BASE+SAM_AFEC_CWR_OFFSET) +#define SAM_AFEC1_CGR (SAM_AFEC1_BASE+SAM_AFEC_CGR_OFFSET) +#define SAM_AFEC1_CDOR (SAM_AFEC1_BASE+SAM_AFEC_CDOR_OFFSET) +#define SAM_AFEC1_DIFFR (SAM_AFEC1_BASE+SAM_AFEC_DIFFR_OFFSET) +#define SAM_AFEC1_CSELR (SAM_AFEC1_BASE+SAM_AFEC_CSELR_OFFSET) +#define SAM_AFEC1_CDR (SAM_AFEC1_BASE+SAM_AFEC_CDR_OFFSET) +#define SAM_AFEC1_COCR (SAM_AFEC1_BASE+SAM_AFEC_COCR_OFFSET) +#define SAM_AFEC1_TEMPMR (SAM_AFEC1_BASE+SAM_AFEC_TEMPMR_OFFSET) +#define SAM_AFEC1_TEMPCWR (SAM_AFEC1_BASE+SAM_AFEC_TEMPCWR_OFFSET) +#define SAM_AFEC1_ACR (SAM_AFEC1_BASE+SAM_AFEC_ACR_OFFSET) +#define SAM_AFEC1_WPMR (SAM_AFEC1_BASE+SAM_AFEC_WPMR_OFFSET) +#define SAM_AFEC1_WPSR (SAM_AFEC1_BASE+SAM_AFEC_WPSR_OFFSET) + +/* AFEC register bit definitions *******************************************************/ + +/* Control Register */ + +#define AFEC_CR_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define AFEC_CR_START (1 << 1) /* Bit 1: Start Conversion */ +#define AFEC_CR_AUTOCAL (1 << 3) /* Bit 3: Automatic Calibration of AFEC */ + +/* Mode Register */ + +#define AFEC_MR_TRGEN (1 << 0) /* Bit 0: Trigger Enable */ +#define AFEC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define AFEC_MR_TRGSEL_MASK (7 << AFEC_MR_TRGSEL_SHIFT) +# define AFEC_MR_TRGSEL_ADTRG (0 << AFEC_MR_TRGSEL_SHIFT) /* ADTRG */ +# define AFEC_MR_TRGSEL_TIOA0 (1 << AFEC_MR_TRGSEL_SHIFT) /* TIOA0 */ +# define AFEC_MR_TRGSEL_TIOA1 (2 << AFEC_MR_TRGSEL_SHIFT) /* TIOA1 */ +# define AFEC_MR_TRGSEL_TIOA2 (3 << AFEC_MR_TRGSEL_SHIFT) /* TIOA2 */ +# define AFEC_MR_TRGSEL_PWM0 (4 << AFEC_MR_TRGSEL_SHIFT) /* PWM Event Line 0 */ +# define AFEC_MR_TRGSEL_PWM1 (5 << AFEC_MR_TRGSEL_SHIFT) /* PWM Event Line 1 */ +#define AFEC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ +#define AFEC_MR_FWUP (1 << 6) /* Bit 6: Fast Wake Up */ +#define AFEC_MR_FREERUN (1 << 7) /* Bit 7: Free Run Mode */ +#define AFEC_MR_PRESCAL_SHIFT (8) /* Bits 8-15: Prescaler Rate Selection */ +#define AFEC_MR_PRESCAL_MASK (0xff << AFEC_MR_PRESCAL_SHIFT) +# define AFEC_MR_PRESCAL(n) ((uint32_t)(n) << AFEC_MR_PRESCAL_SHIFT) +#define AFEC_MR_STARTUP_SHIFT (16) /* Bits 16-19: Start Up Time */ +#define AFEC_MR_STARTUP_MASK (15 << AFEC_MR_STARTUP_SHIFT) +# define AFEC_MR_STARTUP_0 (0 << AFEC_MR_STARTUP_SHIFT) /* 0 periods of ADCClock */ +# define AFEC_MR_STARTUP_8 (1 << AFEC_MR_STARTUP_SHIFT) /* 8 periods of ADCClock */ +# define AFEC_MR_STARTUP_16 (2 << AFEC_MR_STARTUP_SHIFT) /* 16 periods of ADCClock */ +# define AFEC_MR_STARTUP_24 (3 << AFEC_MR_STARTUP_SHIFT) /* 24 periods of ADCClock */ +# define AFEC_MR_STARTUP_64 (4 << AFEC_MR_STARTUP_SHIFT) /* 64 periods of ADCClock */ +# define AFEC_MR_STARTUP_80 (5 << AFEC_MR_STARTUP_SHIFT) /* 80 periods of ADCClock */ +# define AFEC_MR_STARTUP_96 (6 << AFEC_MR_STARTUP_SHIFT) /* 96 periods of ADCClock */ +# define AFEC_MR_STARTUP_112 (7 << AFEC_MR_STARTUP_SHIFT) /* 112 periods of ADCClock */ +# define AFEC_MR_STARTUP_512 (8 << AFEC_MR_STARTUP_SHIFT) /* 512 periods of ADCClock */ +# define AFEC_MR_STARTUP_576 (9 << AFEC_MR_STARTUP_SHIFT) /* 576 periods of ADCClock */ +# define AFEC_MR_STARTUP_640 (10 << AFEC_MR_STARTUP_SHIFT) /* 640 periods of ADCClock */ +# define AFEC_MR_STARTUP_704 (11 << AFEC_MR_STARTUP_SHIFT) /* 704 periods of ADCClock */ +# define AFEC_MR_STARTUP_768 (12 << AFEC_MR_STARTUP_SHIFT) /* 768 periods of ADCClock */ +# define AFEC_MR_STARTUP_832 (13 << AFEC_MR_STARTUP_SHIFT) /* 832 periods of ADCClock */ +# define AFEC_MR_STARTUP_896 (14 << AFEC_MR_STARTUP_SHIFT) /* 896 periods of ADCClock */ +# define AFEC_MR_STARTUP_960 (15 << AFEC_MR_STARTUP_SHIFT) /* 960 periods of ADCClock */ +#define AFEC_MR_SETTLING_SHIFT (20) /* Bits 20-21: Analog Settling Time */ +#define AFEC_MR_SETTLING_MASK (15 << AFEC_MR_SETTLING_SHIFT) +# define AFEC_MR_SETTLING_3 (0 << AFEC_MR_SETTLING_SHIFT) /* 3 periods of ADCClock */ +# define AFEC_MR_SETTLING_5 (1 << AFEC_MR_SETTLING_SHIFT) /* 5 periods of ADCClock */ +# define AFEC_MR_SETTLING_9 (2 << AFEC_MR_SETTLING_SHIFT) /* 9 periods of ADCClock */ +# define AFEC_MR_SETTLING_17 (3 << AFEC_MR_SETTLING_SHIFT) /* 17 periods of ADCClock */ +#define AFEC_MR_ANACH (1 << 23) /* Bit 23: Analog Change */ +#define AFEC_MR_TRACKTIM_SHIFT (24) /* Bits 24-27: Tracking Time */ +#define AFEC_MR_TRACKTIM_MASK (15 << AFEC_MR_TRACKTIM_SHIFT) +# define AFEC_MR_TRACKTIM(n) ((uint32_t)(n) << AFEC_MR_TRACKTIM_SHIFT) +#define AFEC_MR_TRANSFER_SHIFT (28) /* Bits 28-29: Transfer Period */ +#define AFEC_MR_TRANSFER_MASK (3 << AFEC_MR_TRANSFER_SHIFT) +# define AFEC_MR_TRANSFER(n) ((uint32_t)(n) << AFEC_MR_TRANSFER_SHIFT) +#define AFEC_MR_USEQ (1 << 31) /* Bit 31: Use Sequence Enable */ + +/* Extended Mode Register */ + +#define AFEC_EMR_CMPMODE_SHIFT (0) /* Bit 0-1: Comparison Mode */ +#define AFEC_EMR_CMPMODE_MASK (3 << AFEC_EMR_CMPMODE_SHIFT) +# define AFEC_EMR_CMPMODE_LOW (0 << AFEC_EMR_CMPMODE_SHIFT) /* Event when lower than low window threshold */ +# define AFEC_EMR_CMPMODE_HIGH (1 << AFEC_EMR_CMPMODE_SHIFT) /* Event when higher than high window threshold */ +# define AFEC_EMR_CMPMODE_IN (2 << AFEC_EMR_CMPMODE_SHIFT) /* Event when in comparison window */ +# define AFEC_EMR_CMPMODE_OUT (3 << AFEC_EMR_CMPMODE_SHIFT) /* Event when out of comparison window */ +#define AFEC_EMR_CMPSEL_SHIFT (4) /* Bit 4-7: Comparison Selected Channel */ +#define AFEC_EMR_CMPSEL_MASK (15 << AFEC_EMR_CMPSEL_SHIFT) +# define AFEC_EMR_CMPSEL(n) ((uint32_t)(n) << AFEC_EMR_CMPSEL_SHIFT) +#define AFEC_EMR_CMPALL (1 << 9) /* Bit 9: Compare All Channels */ +#define AFEC_EMR_CMPFILTER_SHIFT (12) /* Bits 12-13: Compare Event Filtering */ +#define AFEC_EMR_CMPFILTER_MASK (3 << AFEC_EMR_CMPFILTER_SHIFT) +# define AFEC_EMR_CMPFILTER(n) ((uint32_t)(n) << AFEC_EMR_CMPFILTER_SHIFT) +#define AFEC_EMR_RES_SHIFT (16) /* Bits 16-18: Resolution */ +#define AFEC_EMR_RES_MASK (7 << AFEC_EMR_RES_SHIFT) +# define AFEC_EMR_RES_NOAVG (0 << AFEC_EMR_RES_SHIFT) /* 12-bit resolution, AFEC sample rate is maximum (no averaging) */ +# define AFEC_EMR_RES_LOWRES (1 << AFEC_EMR_RES_SHIFT) /* 10-bit resolution, AFEC sample rate is maximum (no averaging) */ +# define AFEC_EMR_RES_OSR4 (2 << AFEC_EMR_RES_SHIFT) /* 13-bit resolution, AFEC sample rate divided by 4 (averaging) */ +# define AFEC_EMR_RES_OSR16 (3 << AFEC_EMR_RES_SHIFT) /* 14-bit resolution, AFEC sample rate divided by 16 (averaging) */ +# define AFEC_EMR_RES_OSR64 (4 << AFEC_EMR_RES_SHIFT) /* 15-bit resolution, AFEC sample rate divided by 64 (averaging) */ +# define AFEC_EMR_RES_OSR256 (5 << AFEC_EMR_RES_SHIFT) /* 16-bit resolution, AFEC sample rate divided by 256 (averaging) */ +#define AFEC_EMR_TAG (1 << 24) /* Bit 24: TAG of the AFEC_LDCR register */ +#define AFEC_EMR_STM (1 << 25) /* Bit 25: Single Trigger Mode */ + +/* Channel Sequence 1 Register */ + +#define AFEC_SEQ1R_USCH_SHIFT(n) ((n) << 2) /* n=0..7 */ +#define AFEC_SEQ1R_USCH_MASK(n) (15 << AFEC_SEQ1R_USCH_SHIFT(n)) +# define AFEC_SEQ1R_USCH(n,v) ((uint32_t)(v) << AFEC_SEQ1R_USCH_SHIFT(n)) +#define AFEC_SEQ1R_USCH0_SHIFT (0) /* Bits 0-3: User sequence number 0 */ +#define AFEC_SEQ1R_USCH0_MASK (15 << AFEC_SEQ1R_USCH0_SHIFT) +# define AFEC_SEQ1R_USCH0(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH0_SHIFT) +#define AFEC_SEQ1R_USCH1_SHIFT (4) /* Bits 4-7: User sequence number 1 */ +#define AFEC_SEQ1R_USCH1_MASK (15 << AFEC_SEQ1R_USCH1_SHIFT) +# define AFEC_SEQ1R_USCH1(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH1_SHIFT) +#define AFEC_SEQ1R_USCH2_SHIFT (8) /* Bits 8-11: User sequence number 2 */ +#define AFEC_SEQ1R_USCH2_MASK (15 << AFEC_SEQ1R_USCH2_SHIFT) +# define AFEC_SEQ1R_USCH2(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH2_SHIFT) +#define AFEC_SEQ1R_USCH3_SHIFT (12) /* Bits 12-15: User sequence number 3 */ +#define AFEC_SEQ1R_USCH3_MASK (15 << AFEC_SEQ1R_USCH3_SHIFT) +# define AFEC_SEQ1R_USCH3(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH3_SHIFT) +#define AFEC_SEQ1R_USCH4_SHIFT (16) /* Bits 16-19: User sequence number 4 */ +#define AFEC_SEQ1R_USCH4_MASK (15 << AFEC_SEQ1R_USCH4_SHIFT) +# define AFEC_SEQ1R_USCH4(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH4_SHIFT) +#define AFEC_SEQ1R_USCH5_SHIFT (20) /* Bits 20-23: User sequence number 5 */ +#define AFEC_SEQ1R_USCH5_MASK (15 << AFEC_SEQ1R_USCH5_SHIFT) +# define AFEC_SEQ1R_USCH5(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH5_SHIFT) +#define AFEC_SEQ1R_USCH6_SHIFT (24) /* Bits 24-27: User sequence number 6 */ +#define AFEC_SEQ1R_USCH6_MASK (15 << AFEC_SEQ1R_USCH6_SHIFT) +# define AFEC_SEQ1R_USCH6(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH6_SHIFT) +#define AFEC_SEQ1R_USCH7_SHIFT (28) /* Bits 28-31: User sequence number 7 */ +#define AFEC_SEQ1R_USCH7_MASK (15 << AFEC_SEQ1R_USCH7_SHIFT) +# define AFEC_SEQ1R_USCH7(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH7_SHIFT) + +/* Channel Sequence 2 Register */ + +#define AFEC_SEQ2R_USCH_SHIFT(n) (((n)-8) << 2) /* n=8..15 */ +#define AFEC_SEQ2R_USCH_MASK(n) (15 << AFEC_SEQ2R_USCH_SHIFT(n)) +# define AFEC_SEQ2R_USCH(n,v) ((uint32_t)(v) << AFEC_SEQ2R_USCH_SHIFT(n)) +#define AFEC_SEQ2R_USCH8_SHIFT (0) /* Bits 0-3: User sequence number 8 */ +#define AFEC_SEQ2R_USCH8_MASK (15 << AFEC_SEQ2R_USCH8_SHIFT) +# define AFEC_SEQ2R_USCH8(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH8_SHIFT) +#define AFEC_SEQ2R_USCH9_SHIFT (4) /* Bits 4-7: User sequence number 9 */ +#define AFEC_SEQ2R_USCH9_MASK (15 << AFEC_SEQ2R_USCH9_SHIFT) +# define AFEC_SEQ2R_USCH9(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH9_SHIFT) +#define AFEC_SEQ2R_USCH10_SHIFT (8) /* Bits 8-11: User sequence number 10 */ +#define AFEC_SEQ2R_USCH10_MASK (15 << AFEC_SEQ2R_USCH10_SHIFT) +# define AFEC_SEQ2R_USCH10(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH10_SHIFT) +#define AFEC_SEQ2R_USCH11_SHIFT (12) /* Bits 12-15: User sequence number 11 */ +#define AFEC_SEQ2R_USCH11_MASK (15 << AFEC_SEQ2R_USCH11_SHIFT) +# define AFEC_SEQ2R_USCH11(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH11_SHIFT) +#define AFEC_SEQ2R_USCH12_SHIFT (16) /* Bits 16-19: User sequence number 12 */ +#define AFEC_SEQ2R_USCH12_MASK (15 << AFEC_SEQ2R_USCH12_SHIFT) +# define AFEC_SEQ2R_USCH12(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH12_SHIFT) +#define AFEC_SEQ2R_USCH13_SHIFT (20) /* Bits 20-23: User sequence number 13 */ +#define AFEC_SEQ2R_USCH13_MASK (15 << AFEC_SEQ2R_USCH13_SHIFT) +# define AFEC_SEQ2R_USCH13(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH13_SHIFT) +#define AFEC_SEQ2R_USCH14_SHIFT (24) /* Bits 24-27: User sequence number 14 */ +#define AFEC_SEQ2R_USCH14_MASK (15 << AFEC_SEQ2R_USCH14_SHIFT) +# define AFEC_SEQ2R_USCH14(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH14_SHIFT) +#define AFEC_SEQ2R_USCH15_SHIFT (28) /* Bits 28-31: User sequence number 15 */ +#define AFEC_SEQ2R_USCH15_MASK (15 << AFEC_SEQ2R_USCH15_SHIFT) +# define AFEC_SEQ2R_USCH15(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH15_SHIFT) + +/* Channel Enable, Channel Disable, and Channel Status Registers */ + +#define AFEC_CH(n) (1 << (n)) +# define AFEC_CH0 (1 << 0) /* Bit 0: Channel 0 Enable */ +# define AFEC_CH1 (1 << 1) /* Bit 1: Channel 1 Enable */ +# define AFEC_CH2 (1 << 2) /* Bit 2: Channel 2 Enable */ +# define AFEC_CH3 (1 << 3) /* Bit 3: Channel 3 Enable */ +# define AFEC_CH4 (1 << 4) /* Bit 4: Channel 4 Enable */ +# define AFEC_CH5 (1 << 5) /* Bit 5: Channel 5 Enable */ +# define AFEC_CH6 (1 << 6) /* Bit 6: Channel 6 Enable */ +# define AFEC_CH7 (1 << 7) /* Bit 7: Channel 7 Enable */ +# define AFEC_CH8 (1 << 8) /* Bit 8: Channel 8 Enable */ +# define AFEC_CH9 (1 << 9) /* Bit 9: Channel 9 Enable */ +# define AFEC_CH10 (1 << 10) /* Bit 10: Channel 10 Enable */ +# define AFEC_CH11 (1 << 11) /* Bit 11: Channel 11 Enable */ +# define AFEC_CH12 (1 << 12) /* Bit 11: Channel 12 Enable */ +# define AFEC_CH13 (1 << 13) /* Bit 11: Channel 13 Enable */ +# define AFEC_CH14 (1 << 14) /* Bit 11: Channel 14 Enable */ +# define AFEC_CH15 (1 << 15) /* Bit 11: Channel 15 Enable */ +# define AFEC_CHALL (0x0000ffff) + +/* Last Converted Data Register */ + +#define AFEC_LCDR_LDATA_SHIFT (0) /* Bits 0-15: Last Data Converted */ +#define AFEC_LCDR_LDATA_MASK (0xffff << AFEC_LCDR_LDATA_SHIFT) +#define AFEC_LCDR_CHANB_SHIFT (24) /* Bits 24-27: Channel number */ +#define AFEC_LCDR_CHANB_MASK (15 << AFEC_LCDR_CHANB_SHIFT) + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask, and Interrupt Status Registers */ + +#define AFEC_INT_EOC(n) (1 << (n)) +# define AFEC_INT_EOC0 (1 << 0) /* Bit 0: End of Conversion 0 */ +# define AFEC_INT_EOC1 (1 << 1) /* Bit 1: End of Conversion 1 */ +# define AFEC_INT_EOC2 (1 << 2) /* Bit 2: End of Conversion 2 */ +# define AFEC_INT_EOC3 (1 << 3) /* Bit 3: End of Conversion 3 */ +# define AFEC_INT_EOC4 (1 << 4) /* Bit 4: End of Conversion 4 */ +# define AFEC_INT_EOC5 (1 << 5) /* Bit 5: End of Conversion 5 */ +# define AFEC_INT_EOC6 (1 << 6) /* Bit 6: End of Conversion 6 */ +# define AFEC_INT_EOC7 (1 << 7) /* Bit 7: End of Conversion 7 */ +# define AFEC_INT_EOC8 (1 << 8) /* Bit 8: End of Conversion 8 */ +# define AFEC_INT_EOC9 (1 << 9) /* Bit 9: End of Conversion 9 */ +# define AFEC_INT_EOC10 (1 << 10) /* Bit 10: End of Conversion 10 */ +# define AFEC_INT_EOC11 (1 << 11) /* Bit 11: End of Conversion 11 */ +# define AFEC_INT_EOC12 (1 << 12) /* Bit 12: End of Conversion 12 */ +# define AFEC_INT_EOC13 (1 << 13) /* Bit 13: End of Conversion 13 */ +# define AFEC_INT_EOC14 (1 << 14) /* Bit 14: End of Conversion 14 */ +# define AFEC_INT_EOC15 (1 << 15) /* Bit 15: End of Conversion 15 */ +# define AFEC_INT_EOCALL (0x0000ffff) + +#define AFEC_INT_DRDY (1 << 24) /* Bit 24: Data Ready Interrupt */ +#define AFEC_INT_GOVRE (1 << 25) /* Bit 25: General Overrun Error */ +#define AFEC_INT_COMPE (1 << 26) /* Bit 26: Comparison Event Interrupt */ +#define AFEC_INT_ENDRX (1 << 27) /* Bit 27: End of Receive Buffer Interrupt */ +#define AFEC_INT_RXBUFF (1 << 28) /* Bit 28: Receive Buffer Full Interrupt */ +#define AFEC_INT_TEMPCHG (1 << 30) /* Bit 30: Temperature Change Interrupt */ +#define AFEC_INT_EOCAL (1 << 31) /* Bit 31: End of Calibration Sequence Interrupt */ + +#define AFEC_INT_ALL (0xdf00ffff) + +/* Overrun Status Register */ + +#define AFEC_OVER_OVRE(n) (1 << (n)) +# define AFEC_OVER_OVRE0 (1 << 0) /* Bit 0: Overrun Error 0 */ +# define AFEC_OVER_OVRE1 (1 << 1) /* Bit 1: Overrun Error 1 */ +# define AFEC_OVER_OVRE2 (1 << 2) /* Bit 2: Overrun Error 2 */ +# define AFEC_OVER_OVRE3 (1 << 3) /* Bit 3: Overrun Error 3 */ +# define AFEC_OVER_OVRE4 (1 << 4) /* Bit 4: Overrun Error 4 */ +# define AFEC_OVER_OVRE5 (1 << 5) /* Bit 5: Overrun Error 5 */ +# define AFEC_OVER_OVRE6 (1 << 6) /* Bit 6: Overrun Error 6 */ +# define AFEC_OVER_OVRE7 (1 << 7) /* Bit 7: Overrun Error 7 */ +# define AFEC_OVER_OVRE8 (1 << 8) /* Bit 8: Overrun Error 8 */ +# define AFEC_OVER_OVRE9 (1 << 9) /* Bit 9: Overrun Error 9 */ +# define AFEC_OVER_OVRE10 (1 << 10) /* Bit 10: Overrun Error 10 */ +# define AFEC_OVER_OVRE11 (1 << 11) /* Bit 11: Overrun Error 11 */ +# define AFEC_OVER_OVRE12 (1 << 12) /* Bit 12: Overrun Error 12 */ +# define AFEC_OVER_OVRE13 (1 << 13) /* Bit 13: Overrun Error 13 */ +# define AFEC_OVER_OVRE14 (1 << 14) /* Bit 14: Overrun Error 14 */ +# define AFEC_OVER_OVRE15 (1 << 15) /* Bit 15: Overrun Error 15 */ + +/* Compare Window Register */ + +#define AFEC_CWR_LOWTHRES_SHIFT (0) /* Bits 0-11: Low Threshold */ +#define AFEC_CWR_LOWTHRES_MASK (0xfff << AFEC_CWR_LOWTHRES_SHIFT) +# define AFEC_CWR_LOWTHRES(n) ((uint32_t)(n) << AFEC_CWR_LOWTHRES_SHIFT) +#define AFEC_CWR_HIGHTHRES_SHIFT (16) /* Bits 16-27: High Threshold */ +#define AFEC_CWR_HIGHTHRES_MASK (0xfff << AFEC_CWR_LOWTHRES_SHIFT) +# define AFEC_CWR_HIGHTHRES(n)K ((uint32_t)(n) << AFEC_CWR_LOWTHRES_SHIFT) + +/* Channel Gain Register */ + +#define AFEC_CGR_GAIN_SHIFT(n) ((n) << 1) /* n=0..15 */ +#define AFEC_CGR_GAIN_MASK(n) (3 << AFEC_CGR_GAIN_SHIFT(n)) +# define AFEC_CGR_GAIN(n,v) ((uint32_t)(v) << AFEC_CGR_GAIN_SHIFT(n)) +#define AFEC_CGR_GAIN0_SHIFT (0) /* Bits 0-1: Gain for channel 0 */ +#define AFEC_CGR_GAIN0_MASK (3 << AFEC_CGR_GAIN0_SHIFT) +# define AFEC_CGR_GAIN0(v) ((uint32_t)(v) << AFEC_CGR_GAIN0_SHIFT) +#define AFEC_CGR_GAIN1_SHIFT (2) /* Bits 2-3: Gain for channel 1 */ +#define AFEC_CGR_GAIN1_MASK (3 << AFEC_CGR_GAIN1_SHIFT) +# define AFEC_CGR_GAIN1(v) ((uint32_t)(v) << AFEC_CGR_GAIN1_SHIFT) +#define AFEC_CGR_GAIN2_SHIFT (4) /* Bits 4-5: Gain for channel 2 */ +#define AFEC_CGR_GAIN2_MASK (3 << AFEC_CGR_GAIN2_SHIFT) +# define AFEC_CGR_GAIN2(v) ((uint32_t)(v) << AFEC_CGR_GAIN2_SHIFT) +#define AFEC_CGR_GAIN3_SHIFT (6) /* Bits 6-7: Gain for channel 3 */ +#define AFEC_CGR_GAIN3_MASK (3 << AFEC_CGR_GAIN3_SHIFT) +# define AFEC_CGR_GAIN3(v) ((uint32_t)(v) << AFEC_CGR_GAIN3_SHIFT) +#define AFEC_CGR_GAIN4_SHIFT (8) /* Bits 8-9: Gain for channel 4 */ +#define AFEC_CGR_GAIN4_MASK (3 << AFEC_CGR_GAIN4_SHIFT) +# define AFEC_CGR_GAIN4(v) ((uint32_t)(v) << AFEC_CGR_GAIN4_SHIFT) +#define AFEC_CGR_GAIN5_SHIFT (10) /* Bits 10-11: Gain for channel 5 */ +#define AFEC_CGR_GAIN5_MASK (3 << AFEC_CGR_GAIN5_SHIFT) +# define AFEC_CGR_GAIN5(v) ((uint32_t)(v) << AFEC_CGR_GAIN5_SHIFT) +#define AFEC_CGR_GAIN6_SHIFT (12) /* Bits 12-13: Gain for channel 6 */ +#define AFEC_CGR_GAIN6_MASK (3 << AFEC_CGR_GAIN6_SHIFT) +# define AFEC_CGR_GAIN6(v) ((uint32_t)(v) << AFEC_CGR_GAIN6_SHIFT) +#define AFEC_CGR_GAIN7_SHIFT (14) /* Bits 14-15: Gain for channel 7 */ +#define AFEC_CGR_GAIN7_MASK (3 << AFEC_CGR_GAIN7_SHIFT) +# define AFEC_CGR_GAIN7(v) ((uint32_t)(v) << AFEC_CGR_GAIN7_SHIFT) +#define AFEC_CGR_GAIN8_SHIFT (16) /* Bits 16-17: Gain for channel 8 */ +#define AFEC_CGR_GAIN8_MASK (3 << AFEC_CGR_GAIN8_SHIFT) +# define AFEC_CGR_GAIN8(v) ((uint32_t)(v) << AFEC_CGR_GAIN8_SHIFT) +#define AFEC_CGR_GAIN9_SHIFT (18) /* Bits 18-19: Gain for channel 9 */ +#define AFEC_CGR_GAIN9_MASK (3 << AFEC_CGR_GAIN9_SHIFT) +# define AFEC_CGR_GAIN9(v) ((uint32_t)(v) << AFEC_CGR_GAIN9_SHIFT) +#define AFEC_CGR_GAIN10_SHIFT (20) /* Bits 20-21: Gain for channel 10 */ +#define AFEC_CGR_GAIN10_MASK (3 << AFEC_CGR_GAIN10_SHIFT) +# define AFEC_CGR_GAIN10(v) ((uint32_t)(v) << AFEC_CGR_GAIN10_SHIFT) +#define AFEC_CGR_GAIN11_SHIFT (22) /* Bits 22-23: Gain for channel 11 */ +#define AFEC_CGR_GAIN11_MASK (3 << AFEC_CGR_GAIN11_SHIFT) +# define AFEC_CGR_GAIN11(v) ((uint32_t)(v) << AFEC_CGR_GAIN11_SHIFT) +#define AFEC_CGR_GAIN12_SHIFT (24) /* Bits 24-25: Gain for channel 12 */ +#define AFEC_CGR_GAIN12_MASK (3 << AFEC_CGR_GAIN12_SHIFT) +# define AFEC_CGR_GAIN12(v) ((uint32_t)(v) << AFEC_CGR_GAIN12_SHIFT) +#define AFEC_CGR_GAIN13_SHIFT (26) /* Bits 26-27: Gain for channel 13 */ +#define AFEC_CGR_GAIN13_MASK (3 << AFEC_CGR_GAIN13_SHIFT) +# define AFEC_CGR_GAIN13(v) ((uint32_t)(v) << AFEC_CGR_GAIN13_SHIFT) +#define AFEC_CGR_GAIN14_SHIFT (28) /* Bits 28-29: Gain for channel 14 */ +#define AFEC_CGR_GAIN14_MASK (3 << AFEC_CGR_GAIN14_SHIFT) +# define AFEC_CGR_GAIN14(v) ((uint32_t)(v) << AFEC_CGR_GAIN14_SHIFT) +#define AFEC_CGR_GAIN15_SHIFT (30) /* Bits 30-31: Gain for channel 15 */ +#define AFEC_CGR_GAIN15_MASK (3 << AFEC_CGR_GAIN15_SHIFT) +# define AFEC_CGR_GAIN15(v) ((uint32_t)(v) << AFEC_CGR_GAIN15_SHIFT) + +/* Channel Calibration DC Offset Register (Used in Automatic Calibration Procedure) */ + +#define AFEC_CDOR_OFF(n) (1 << (n)) +# define AFEC_CDOR_OFF0 (1 << 0) /* Bit 0: Offset for channel 0 */ +# define AFEC_CDOR_OFF1 (1 << 1) /* Bit 1: Offset for channel 1 */ +# define AFEC_CDOR_OFF2 (1 << 2) /* Bit 2: Offset for channel 2 */ +# define AFEC_CDOR_OFF3 (1 << 3) /* Bit 3: Offset for channel 3 */ +# define AFEC_CDOR_OFF4 (1 << 4) /* Bit 4: Offset for channel 4 */ +# define AFEC_CDOR_OFF5 (1 << 5) /* Bit 5: Offset for channel 5 */ +# define AFEC_CDOR_OFF6 (1 << 6) /* Bit 6: Offset for channel 6 */ +# define AFEC_CDOR_OFF7 (1 << 7) /* Bit 7: Offset for channel 7 */ +# define AFEC_CDOR_OFF8 (1 << 8) /* Bit 8: Offset for channel 8 */ +# define AFEC_CDOR_OFF9 (1 << 9) /* Bit 9: Offset for channel 9 */ +# define AFEC_CDOR_OFF10 (1 << 10) /* Bit 10: Offset for channel 10 */ +# define AFEC_CDOR_OFF11 (1 << 11) /* Bit 11: Offset for channel 11 */ +# define AFEC_CDOR_OFF12 (1 << 12) /* Bit 12: Offset for channel 12 */ +# define AFEC_CDOR_OFF13 (1 << 13) /* Bit 13: Offset for channel 13 */ +# define AFEC_CDOR_OFF14 (1 << 14) /* Bit 14: Offset for channel 14 */ +# define AFEC_CDOR_OFF15 (1 << 15) /* Bit 15: Offset for channel 15 */ + +/* Channel Differential Register */ + +#define AFEC_DIFFR_DIFF(n) (1 << (n)) +# define AFEC_DIFFR_DIFF0 (1 << 0) /* Bit 0: Differential inputs for channel 0 */ +# define AFEC_DIFFR_DIFF1 (1 << 1) /* Bit 1: Differential inputs for channel 1 */ +# define AFEC_DIFFR_DIFF2 (1 << 2) /* Bit 2: Differential inputs for channel 2 */ +# define AFEC_DIFFR_DIFF3 (1 << 3) /* Bit 3: Differential inputs for channel 3 */ +# define AFEC_DIFFR_DIFF4 (1 << 4) /* Bit 4: Differential inputs for channel 4 */ +# define AFEC_DIFFR_DIFF5 (1 << 5) /* Bit 5: Differential inputs for channel 5 */ +# define AFEC_DIFFR_DIFF6 (1 << 6) /* Bit 6: Differential inputs for channel 6 */ +# define AFEC_DIFFR_DIFF7 (1 << 7) /* Bit 7: Differential inputs for channel 7 */ +# define AFEC_DIFFR_DIFF8 (1 << 8) /* Bit 8: Differential inputs for channel 8 */ +# define AFEC_DIFFR_DIFF9 (1 << 9) /* Bit 9: Differential inputs for channel 9 */ +# define AFEC_DIFFR_DIFF10 (1 << 10) /* Bit 10: Differential inputs for channel 10 */ +# define AFEC_DIFFR_DIFF11 (1 << 11) /* Bit 11: Differential inputs for channel 11 */ +# define AFEC_DIFFR_DIFF12 (1 << 12) /* Bit 12: Differential inputs for channel 12 */ +# define AFEC_DIFFR_DIFF13 (1 << 13) /* Bit 13: Differential inputs for channel 13 */ +# define AFEC_DIFFR_DIFF14 (1 << 14) /* Bit 14: Differential inputs for channel 14 */ +# define AFEC_DIFFR_DIFF15 (1 << 15) /* Bit 15: Differential inputs for channel 15 */ + +/* Channel Register Selection */ + +#define AFEC_CSELR_CSEL_SHIFT (0) /* Bits 0-3: Channel Selection */ +#define AFEC_CSELR_CSEL_MASK (15 << AFEC_CSELR_CSEL_SHIFT) +# define AFEC_CSELR_CSEL(n) ((uint32_t)(n) << AFEC_CSELR_CSEL_SHIFT) + +/* Channel Data Register */ + +#define AFEC_CDR_MASK (0x00000fff) /* Bits 0-12: Converted Data */ + +/* Channel Offset Compensation Register */ + +#define AFEC_COCR_MASK (0x00000fff) /* Bits 0-12: Analog Offset */ + +/* Temperature Sensor Mode Register */ + +#define AFEC_TEMPMR_RTCT (1 << 0) /* Bit 0: Temperature Sensor RTC Trigger mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_SHIFT (4) /* Bits 4-5: Temperature Comparison Mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_MASK (3 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) +# define AFEC_TEMPMR_TEMPCMPMOD_LOW (0 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is lower than low threshold */ +# define AFEC_TEMPMR_TEMPCMPMOD_HIGH (1 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is higher than high threshold */ +# define AFEC_TEMPMR_TEMPCMPMOD_IN (2 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is in the comparison window */ +# define AFEC_TEMPMR_TEMPCMPMOD_OUT (3 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is out of the comparison window */ + +/* Temperature Compare Window Register */ + +#define AFEC_TEMPCWR_TLOWTHRES_SHIFT (0) /* Bits 0-15: Temperature Low Threshold */ +#define AFEC_TEMPCWR_TLOWTHRES_MASK (0xffff << AFEC_TEMPCWR_TLOWTHRES_SHIFT) +# define AFEC_TEMPCWR_TLOWTHRES(n) (0xffff << AFEC_TEMPCWR_TLOWTHRES_SHIFT) +#define AFEC_TEMPCWR_THIGHTHRES_SHIFT (16) /* Bits 16-31: Temperature High Threshold */ +#define AFEC_TEMPCWR_THIGHTHRES_MASK (0xffff << AFEC_TEMPCWR_THIGHTHRES_SHIFT) +# define AFEC_TEMPCWR_THIGHTHRES(n) ((uint32_t)(n) << AFEC_TEMPCWR_THIGHTHRES_SHIFT) + +/* Analog Control Register */ + +#define AFEC_ACR_IBCTL_SHIFT (9) /* Bits 8-9: AFEC Bias Current Control */ +#define AFEC_ACR_IBCTL_MASK (3 << AFEC_ACR_IBCTL_SHIFT) +# define AFEC_ACR_IBCTL(n) ((uint32_t)(n) << AFEC_ACR_IBCTL_SHIFT) + +/* Write Protect Mode Register */ + +#define AFEC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define AFEC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define AFEC_WPMR_WPKEY_MASK (0x00ffffff << AFEC_WPMR_WPKEY_SHIFT) +# define AFEC_WPMR_WPKEY (0x00414443 << AFEC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define AFEC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define AFEC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define AFEC_WPSR_WPVSRC_MASK (0x0000ffff << AFEC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_AFEC_H */ diff --git a/arch/arm/src/sam34/chip/sam_can.h b/arch/arm/src/sam34/chip/sam_can.h new file mode 100644 index 0000000000000000000000000000000000000000..22548314e7dd91890dd0576871729faa0e045786 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_can.h @@ -0,0 +1,319 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_can.h + * Controller Area Network (CAN) for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_CAN_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_CAN_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +#define SAM_CAN_NMBOXES 8 /* 8 Mailboxes */ +#define SAM_CAN_MBOX(n) (n) +#define SAM_CAN_MBOX0 0 +#define SAM_CAN_MBOX1 1 +#define SAM_CAN_MBOX2 2 +#define SAM_CAN_MBOX3 3 +#define SAM_CAN_MBOX4 4 +#define SAM_CAN_MBOX5 5 +#define SAM_CAN_MBOX6 6 +#define SAM_CAN_MBOX7 7 + +/* CAN register offsets *****************************************************************/ + +#define SAM_CAN_MR_OFFSET 0x0000 /* Mode Register */ +#define SAM_CAN_IER_OFFSET 0x0004 /* Interrupt Enable Register */ +#define SAM_CAN_IDR_OFFSET 0x0008 /* Interrupt Disable Register */ +#define SAM_CAN_IMR_OFFSET 0x000c /* Interrupt Mask Register */ +#define SAM_CAN_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_CAN_BR_OFFSET 0x0014 /* Baudrate Register */ +#define SAM_CAN_TIM_OFFSET 0x0018 /* Timer Register */ +#define SAM_CAN_TIMESTP_OFFSET 0x001c /* Timestamp Register */ +#define SAM_CAN_ECR_OFFSET 0x0020 /* Error Counter Register */ +#define SAM_CAN_TCR_OFFSET 0x0024 /* Transfer Command Register */ +#define SAM_CAN_ACR_OFFSET 0x0028 /* Abort Command Register */ + /* 0x002c-0x00e0: Reserved */ +#define SAM_CAN_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_CAN_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00eC-0x01fc: Reserved */ +/* Mailbox Registers */ + +#define SAM_CAN_MBOX_OFFSET(n) (0x0200+((n) << 5)) +#define SAM_CAN_MMR_OFFSET 0x0000 /* Mailbox Mode Register */ +#define SAM_CAN_MAM_OFFSET 0x0004 /* Mailbox Acceptance Mask Register */ +#define SAM_CAN_MID_OFFSET 0x0008 /* Mailbox ID Register */ +#define SAM_CAN_MFID_OFFSET 0x000c /* Mailbox Family ID Register */ +#define SAM_CAN_MSR_OFFSET 0x0010 /* Mailbox Status Register */ +#define SAM_CAN_MDL_OFFSET 0x0014 /* Mailbox Data Low Register */ +#define SAM_CAN_MDH_OFFSET 0x0018 /* Mailbox Data High Register */ +#define SAM_CAN_MCR_OFFSET 0x001c /* Mailbox Control Register */ + +/* CAN register addresses ***************************************************************/ + +#define SAM_CAN0_MR (SAM_CAN0_BASE+SAM_CAN_MR_OFFSET) +#define SAM_CAN0_IER (SAM_CAN0_BASE+SAM_CAN_IER_OFFSET) +#define SAM_CAN0_IDR (SAM_CAN0_BASE+SAM_CAN_IDR_OFFSET) +#define SAM_CAN0_IMR (SAM_CAN0_BASE+SAM_CAN_IMR_OFFSET) +#define SAM_CAN0_SR (SAM_CAN0_BASE+SAM_CAN_SR_OFFSET) +#define SAM_CAN0_BR (SAM_CAN0_BASE+SAM_CAN_BR_OFFSET) +#define SAM_CAN0_TIM (SAM_CAN0_BASE+SAM_CAN_TIM_OFFSET) +#define SAM_CAN0_TIMESTP (SAM_CAN0_BASE+SAM_CAN_TIMESTP_OFFSET) +#define SAM_CAN0_ECR (SAM_CAN0_BASE+SAM_CAN_ECR_OFFSET) +#define SAM_CAN0_TCR (SAM_CAN0_BASE+SAM_CAN_TCR_OFFSET) +#define SAM_CAN0_ACR (SAM_CAN0_BASE+SAM_CAN_ACR_OFFSET) +#define SAM_CAN0_WPMR (SAM_CAN0_BASE+SAM_CAN_WPMR_OFFSET) +#define SAM_CAN0_WPSR (SAM_CAN0_BASE+SAM_CAN_WPSR_OFFSET) + +/* Mailbox Registers */ + +#define SAM_CAN0_MBOX_BASE(n) (SAM_CAN0_BASE+SAM_CAN_MBOX_OFFSET(n)) +#define SAM_CAN0_MMR(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MMR_OFFSET) +#define SAM_CAN0_MAM(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MAM_OFFSET) +#define SAM_CAN0_MID(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MID_OFFSET) +#define SAM_CAN0_MFID(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MFID_OFFSET) +#define SAM_CAN0_MSR(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MSR_OFFSET) +#define SAM_CAN0_MDL(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MDL_OFFSET) +#define SAM_CAN0_MDH(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MDH_OFFSET) +#define SAM_CAN0_MCR(n) (SAM_CAN0_MBOX_BASE(n)+SAM_CAN_MCR_OFFSET) + +#define SAM_CAN1_MR (SAM_CAN1_BASE+SAM_CAN_MR_OFFSET) +#define SAM_CAN1_IER (SAM_CAN1_BASE+SAM_CAN_IER_OFFSET) +#define SAM_CAN1_IDR (SAM_CAN1_BASE+SAM_CAN_IDR_OFFSET) +#define SAM_CAN1_IMR (SAM_CAN1_BASE+SAM_CAN_IMR_OFFSET) +#define SAM_CAN1_SR (SAM_CAN1_BASE+SAM_CAN_SR_OFFSET) +#define SAM_CAN1_BR (SAM_CAN1_BASE+SAM_CAN_BR_OFFSET) +#define SAM_CAN1_TIM (SAM_CAN1_BASE+SAM_CAN_TIM_OFFSET) +#define SAM_CAN1_TIMESTP (SAM_CAN1_BASE+SAM_CAN_TIMESTP_OFFSET) +#define SAM_CAN1_ECR (SAM_CAN1_BASE+SAM_CAN_ECR_OFFSET) +#define SAM_CAN1_TCR (SAM_CAN1_BASE+SAM_CAN_TCR_OFFSET) +#define SAM_CAN1_ACR (SAM_CAN1_BASE+SAM_CAN_ACR_OFFSET) +#define SAM_CAN1_WPMR (SAM_CAN1_BASE+SAM_CAN_WPMR_OFFSET) +#define SAM_CAN1_WPSR (SAM_CAN1_BASE+SAM_CAN_WPSR_OFFSET) + +/* Mailbox Registers */ + +#define SAM_CAN1_MBOX_BASE(n) (SAM_CAN1_BASE+SAM_CAN_MBOX_OFFSET(n)) +#define SAM_CAN1_MMR(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MMR_OFFSET) +#define SAM_CAN1_MAM(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MAM_OFFSET) +#define SAM_CAN1_MID(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MID_OFFSET) +#define SAM_CAN1_MFID(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MFID_OFFSET) +#define SAM_CAN1_MSR(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MSR_OFFSET) +#define SAM_CAN1_MDL(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MDL_OFFSET) +#define SAM_CAN1_MDH(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MDH_OFFSET) +#define SAM_CAN1_MCR(n) (SAM_CAN1_MBOX_BASE(n)+SAM_CAN_MCR_OFFSET) + +/* CAN register bit definitions *********************************************************/ + +/* Mode Register */ + +#define CAN_MR_CANEN (1 << 0) /* Bit 0: CAN controller enable */ +#define CAN_MR_LPM (1 << 1) /* Bit 1: Disable/enable low power mode */ +#define CAN_MR_ABM (1 << 2) /* Bit 2: Disable/enable autobaud/listen mode */ +#define CAN_MR_OVL (1 << 3) /* Bit 3: Disable/enable overload frame */ +#define CAN_MR_TEOF (1 << 4) /* Bit 4: Timestamp messages at each end of frame */ +#define CAN_MR_TTM (1 << 5) /* Bit 5: Disable/enable time triggered mode */ +#define CAN_MR_TIMFRZ (1 << 6) /* Bit 6: Enable timer freeze */ +#define CAN_MR_DRPT (1 << 7) /* Bit 7: Disable repeat */ + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask and Status Register */ + +#define CAN_INT_MB(n) (1 << (n)) /* Bit n: Mailbox n Interrupt */ +#define CAN_INT_ERRA (1 << 16) /* Bit 16: Error Active Mode Interrupt */ +#define CAN_INT_WARN (1 << 17) /* Bit 17: Warning Limit Interrupt */ +#define CAN_INT_ERRP (1 << 18) /* Bit 18: Error Passive Mode Interrupt */ +#define CAN_INT_BOFF (1 << 19) /* Bit 19: Bus Off Mode Interrupt */ +#define CAN_INT_SLEEP (1 << 20) /* Bit 20: Sleep Interrupt */ +#define CAN_INT_WAKEUP (1 << 21) /* Bit 21: Wake-up Interrupt */ +#define CAN_INT_TOVF (1 << 22) /* Bit 22: Timer Overflow Interrupt */ +#define CAN_INT_TSTP (1 << 23) /* Bit 23: TimeStamp Interrupt */ +#define CAN_INT_CERR (1 << 24) /* Bit 24: CRC Error Interrupt */ +#define CAN_INT_SERR (1 << 25) /* Bit 25: Stuffing Error Interrupt */ +#define CAN_INT_AERR (1 << 26) /* Bit 26: Acknowledgement Error Interrupt */ +#define CAN_INT_FERR (1 << 27) /* Bit 27: Form Error Interrupt */ +#define CAN_INT_BERR (1 << 28) /* Bit 28: Bit Error Interrupt */ + +#define CAN_SR_RBSY (1 << 29) /* Bit 29: Receiver busy (SR only) */ +#define CAN_SR_TBSY (1 << 30) /* Bit 30: Transmitter busy (SR only) */ +#define CAN_SR_OVLSY (1 << 31) /* Bit 31: Overload busy (SR only) */ + +/* Baudrate Register */ + +#define CAN_BR_PHASE2_SHIFT (0) /* Bits 0-2: Phase 2 segment */ +#define CAN_BR_PHASE2_MASK (7 << CAN_BR_PHASE2_SHIFT) +# define CAN_BR_PHASE2(n) ((uint32_t)(n) << CAN_BR_PHASE2_SHIFT) +#define CAN_BR_PHASE1_SHIFT (4) /* Bits 4-6: Phase 1 segment */ +#define CAN_BR_PHASE1_MASK (7 << CAN_BR_PHASE1_SHIFT) +# define CAN_BR_PHASE1(n) ((uint32_t)(n) << CAN_BR_PHASE1_SHIFT) +#define CAN_BR_PROPAG_SHIFT (8) /* Bits 8-10: Programming time segment */ +#define CAN_BR_PROPAG_MASK (7 << CAN_BR_PROPAG_SHIFT) +# define CAN_BR_PROPAG(n) ((uint32_t)(n) << CAN_BR_PROPAG_SHIFT) +#define CAN_BR_SJW_SHIFT (12) /* Bits 12-13: Re-synchronization jump width */ +#define CAN_BR_SJW_MASK (3 << CAN_BR_SJW_SHIFT) +# define CAN_BR_SJW(n) ((uint32_t)(n) << CAN_BR_SJW_SHIFT) +#define CAN_BR_BRP_SHIFT (16) /* Bits 16-22: Baudrate Prescaler */ +#define CAN_BR_BRP_MASK (127 << CAN_BR_BRP_SHIFT) +# define CAN_BR_BRP(n) ((uint32_t)(n) << CAN_BR_BRP_SHIFT) +#define CAN_BR_SMP (1 << 24) /* Bit 24: Sampling Mode + +/* Timer Register */ + +#define CAN_TIM_MASK (0x0000ffff) /* Bits 0-15: Timer */ + +/* Timestamp Register */ + +#define CAN_TIMESTP_MASK (0x0000ffff) /* Bits 0-15: Timestamp */ + +/* Error Counter Register */ + +#define CAN_ECR_REC_SHIFT (0) /* Bits 0-7: Receive Error Counter */ +#define CAN_ECR_REC_MASK (0xff << CAN_ECR_REC_SHIFT) +# define CAN_ECR_REC(n) ((uint32_t)(n) << CAN_ECR_REC_SHIFT) +#define CAN_ECR_TEC_SHIFT (16) /* Bits 16-23: Transmit Error Counter */ +#define CAN_ECR_TEC_MASK (0xff << CAN_ECR_TEC_SHIFT) +# define CAN_ECR_TEC(n) ((uint32_t)(n) << CAN_ECR_TEC_SHIFT) + +/* Transfer Command Register */ + +#define CAN_TCR_MB(n) (1 << (n)) /* Bit (n): Transfer Request for Mailbox n */ +#define CAN_TCR_TIMRST (1 << 31) /* Bit 31: Timer Reset */ + +/* Abort Command Register */ + +#define CAN_ACR_MB(n) (1 << (n)) /* Bit (n): Abort Request for Mailbox n */ + +/* Write Protect Mode Register */ + +#define CAN_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define CAN_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: SPI Write Protection Key Password */ +#define CAN_WPMR_WPKEY_MASK (0x00ffffff << CAN_WPMR_WPKEY_SHIFT) +# define CAN_WPMR_WPKEY (0x0043414e << CAN_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define CAN_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define CAN_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define CAN_WPSR_WPVSRC_MASK (0x0000ffff << CAN_WPSR_WPVSRC_SHIFT) + +/* Mailbox Registers */ + +/* Mailbox Mode Register */ + +#define CAN_MMR_MTIMEMARK_SHIFT (0) /* Bits 0-15: Mailbox Timemark */ +#define CAN_MMR_MTIMEMARK_MASK (0x0000ffff << CAN_MMR_MTIMEMARK_SHIFT) +# define CAN_MMR_MTIMEMARK(n) ((uint32_t)(n) << CAN_MMR_MTIMEMARK_SHIFT) +#define CAN_MMR_PRIOR_SHIFT (16) /* Bits 16-19: Mailbox Priority */ +#define CAN_MMR_PRIOR_MASK (15 << CAN_MMR_PRIOR_SHIFT) +# define CAN_MMR_PRIOR(n) ((uint32_t)(n) << CAN_MMR_PRIOR_SHIFT) +#define CAN_MMR_MOT_SHIFT (24) /* Bits 24-26: Mailbox Object Type */ +#define CAN_MMR_MOT_MASK (7 << CAN_MMR_MOT_SHIFT) +# define CAN_MMR_MOT_DISABLED (0 << CAN_MMR_MOT_SHIFT) /* Mailbox is disabled */ +# define CAN_MMR_MOT_RX (1 << CAN_MMR_MOT_SHIFT) /* Reception Mailbox */ +# define CAN_MMR_MOT_RXOVR (2 << CAN_MMR_MOT_SHIFT) /* Reception mailbox with overwrite */ +# define CAN_MMR_MOT_TX (3 << CAN_MMR_MOT_SHIFT) /* Transmit mailbox */ +# define CAN_MMR_MOT_CONSUMER (4 << CAN_MMR_MOT_SHIFT) /* Consumer Mailbox */ +# define CAN_MMR_MOT_PRODUCER (5 << CAN_MMR_MOT_SHIFT) /* Producer Mailbox */ + +/* Mailbox Acceptance Mask Register */ + +#define CAN_MAM_MIDvB_SHIFT (0) /* Bits 0-18: Complementary bits for ID in extended frame mode */ +#define CAN_MAM_MIDvB_MASK (0x0003ffff << CAN_MAM_MIDvB_SHIFT) +# define CAN_MAM_MIDvB(n) ((uint32_t)(n) << CAN_MAM_MIDvB_SHIFT) +#define CAN_MAM_MIDvA_SHIFT (18) /* Bits 18-28: ID for standard frame mode */ +#define CAN_MAM_MIDvA_MASK (0x000007ff << CAN_MAM_MIDvA_SHIFT) +# define CAN_MAM_MIDvA(n) ((uint32_t)(n) << CAN_MAM_MIDvA_SHIFT) +#define CAN_MAM_MIDE (1 << 29) /* Bit 29: ID Version */ + +/* Mailbox ID Register */ + +#define CAN_MID_MIDvB_SHIFT (0) /* Bits 0-18: Complementary bits for ID in extended frame mode */ +#define CAN_MID_MIDvB_MASK (0x0003ffff << CAN_MID_MIDvB_SHIFT) +# define CAN_MID_MIDvB(n) ((uint32_t)(n) << CAN_MID_MIDvB_SHIFT) +#define CAN_MID_MIDvA_SHIFT (18) /* Bits 18-28: ID for standard frame mode */ +#define CAN_MID_MIDvA_MASK (0x000007ff << CAN_MID_MIDvA_SHIFT) +# define CAN_MID_MIDvA(n) ((uint32_t)(n) << CAN_MID_MIDvA_SHIFT) +#define CAN_MID_MIDE (1 << 29) /* Bit 29: ID Version */ + +/* Mailbox Family ID Register */ + +#define CAN_MFID_MASK (0x1fffffff) /* Bit 0-28: Family ID */ + +/* Mailbox Status Register */ + +#define CAN_MSR_MTIMESTAMP_SHIFT (0) /* Bits 0-15: Timer value */ +#define CAN_MSR_MTIMESTAMP_MASK (0x0000ffff << CAN_MSR_MTIMESTAMP_SHIFT) +# define CAN_MSR_MTIMESTAMP(n) ((uint32_t)(n) << CAN_MSR_MTIMESTAMP_SHIFT) +#define CAN_MSR_MDLC_SHIFT (16) /* Bits 16-19: Mailbox Data Length Code */ +#define CAN_MSR_MDLC_MASK (15 << CAN_MSR_MDLC_SHIFT) +# define CAN_MSR_MDLC(n) ((uint32_t)(n) << CAN_MSR_MDLC_SHIFT) +#define CAN_MSR_MRTR (1 << 20) /* Bit 20: Mailbox Remote Transmission Request */ +#define CAN_MSR_MABT (1 << 22) /* Bit 22: Mailbox Message Abort */ +#define CAN_MSR_MRDY (1 << 23) /* Bit 23: Mailbox Ready */ +#define CAN_MSR_MMI (1 << 24) /* Bit 24: Mailbox Message Ignored */ + +/* Mailbox Data Low Register (32-bit value) */ +/* Mailbox Data High Register (32-bit value) */ + +/* Mailbox Control Register */ + +#define CAN_MCR_MDLC_SHIFT (16) /* Bits 16-19: Mailbox Data Length Code */ +#define CAN_MCR_MDLC_MASK (15 << CAN_MCR_MDLC_SHIFT) +# define CAN_MCR_MDLC(n) ((uint32_t)(n) << CAN_MCR_MDLC_SHIFT) +#define CAN_MCR_MRTR (1 << 20) /* Bit 20: Mailbox Remote Transmission Request */ +#define CAN_MCR_MACR (1 << 22) /* Bit 22: Abort Request for Mailbox n */ +#define CAN_MCR_MTCR (1 << 23) /* Bit 23: Mailbox Transfer Command */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_CAN_H */ diff --git a/arch/arm/src/sam34/chip/sam_chipid.h b/arch/arm/src/sam34/chip/sam_chipid.h new file mode 100644 index 0000000000000000000000000000000000000000..c09e538367e7955a8c3482ae4b38551a09f6add5 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_chipid.h @@ -0,0 +1,201 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_chipid.h + * CHIPID Register Definitions for the SAM3U, SAM4S, and SAM4L + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_CHIPID_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_CHIPID_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* CHIPID register offsets **************************************************************/ + +#define SAM_CHIPID_CIDR 0x00 /* Chip ID Register */ +#define SAM_CHIPID_EXID 0x04 /* Chip ID Extension Register */ + +/* CHIPID register addresses ************************************************************/ + +#define SAM_CHIPID_CIDR (SAM_CHIPID_BASE+SAM_CHIPID_CIDR) +#define SAM_CHIPID_EXID (SAM_CHIPID_BASE+SAM_CHIPID_EXID) + +/* CHIPID register bit definitions ******************************************************/ + +#define CHIPID_CIDR_VERSION_SHIFT (0) /* Bits 0-4: Version of the Device */ +#define CHIPID_CIDR_VERSION_MASK (0x1f << CHIPID_CIDR_VERSION_SHIFT) +#define CHIPID_CIDR_EPROC_SHIFT (5) /* Bits 5-7: Embedded Processor */ +#define CHIPID_CIDR_EPROC_MASK (7 << CHIPID_CIDR_EPROC_SHIFT) +# define CHIPID_CIDR_EPROC_ARM946ES (1 << CHIPID_CIDR_EPROC_SHIFT) /* ARM946E-S */ +# define CHIPID_CIDR_EPROC_ARM7TDMI (2 << CHIPID_CIDR_EPROC_SHIFT) /* ARM7TDMI */ +# define CHIPID_CIDR_EPROC_CORTEXM3 (3 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-M3 */ +# define CHIPID_CIDR_EPROC_ARM920T (4 << CHIPID_CIDR_EPROC_SHIFT) /* ARM920T */ +# define CHIPID_CIDR_EPROC_ARM926EJS (5 << CHIPID_CIDR_EPROC_SHIFT) /* ARM926EJ-S */ +# define CHIPID_CIDR_EPROC_CORTEXA5 (6 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-A5 */ +# define CHIPID_CIDR_EPROC_CORTEXM4 (7 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-M4 */ +#define CHIPID_CIDR_NVPSIZ_SHIFT (8) /* Bits 8-11: Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ_MASK (15 << CHIPID_CIDR_NVPSIZ_SHIFT) +# define CHIPID_CIDR_NVPSIZ_NONE (0 << CHIPID_CIDR_NVPSIZ_SHIFT) /* None */ +# define CHIPID_CIDR_NVPSIZ_8KB (1 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_NVPSIZ_16KB (2 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_NVPSIZ_32KB (3 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_NVPSIZ_64KB (5 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_NVPSIZ_128KB (7 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_NVPSIZ_256KB (9 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_NVPSIZ_512KB (10 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 512K bytes */ +# define CHIPID_CIDR_NVPSIZ_1MB (12 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 1024K bytes */ +# define CHIPID_CIDR_NVPSIZ_2MB (14 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 2048K bytes */ +#define CHIPID_CIDR_NVPSIZ2_SHIFT (12) /* Bits 12-15: Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ2_MASK (15 << CHIPID_CIDR_NVPSIZ_SHIFT) +# define CHIPID_CIDR_NVPSIZ2_NONE (0 << CHIPID_CIDR_NVPSIZ_SHIFT) /* None */ +# define CHIPID_CIDR_NVPSIZ2_8KB (1 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_NVPSIZ2_16KB (2 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_NVPSIZ2_32KB (3 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_NVPSIZ2_64KB (5 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_NVPSIZ2_128KB (7 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_NVPSIZ2_256KB (9 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_NVPSIZ2_512KB (10 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 512K bytes */ +# define CHIPID_CIDR_NVPSIZ2_1MB (12 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 1024K bytes */ +# define CHIPID_CIDR_NVPSIZ2_2MB (14 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 2048K bytes */ +#define CHIPID_CIDR_SRAMSIZ_SHIFT (16) /* Bits 16-19: Internal SRAM Size */ +#define CHIPID_CIDR_SRAMSIZ_MASK (15 << CHIPID_CIDR_SRAMSIZ_SHIFT) +# define CHIPID_CIDR_SRAMSIZ_48KB (0 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 48K bytes */ +# define CHIPID_CIDR_SRAMSIZ_1KB (1 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 1K bytes */ +# define CHIPID_CIDR_SRAMSIZ_192KB (1 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 192K bytes (SAM4S) */ +# define CHIPID_CIDR_SRAMSIZ_2KB (2 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 2K bytes */ +# define CHIPID_CIDR_SRAMSIZ_6KB (3 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 6K bytes */ +# define CHIPID_CIDR_SRAMSIZ_112KB (4 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 112K bytes */ +# define CHIPID_CIDR_SRAMSIZ_24KB (4 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 24K bytes (SAM4S, SAM4L) */ +# define CHIPID_CIDR_SRAMSIZ_4KB (5 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 4K bytes */ +# define CHIPID_CIDR_SRAMSIZ_80KB (6 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 80K bytes */ +# define CHIPID_CIDR_SRAMSIZ_160KB (7 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 160K bytes */ +# define CHIPID_CIDR_SRAMSIZ_8KB (8 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_SRAMSIZ_16KB (9 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_SRAMSIZ_32KB (10 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_SRAMSIZ_64KB (11 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_SRAMSIZ_128KB (12 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_SRAMSIZ_256KB (13 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_SRAMSIZ_96KB (14 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 96K bytes */ +# define CHIPID_CIDR_SRAMSIZ_512KB (15 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 512K bytes */ +#define CHIPID_CIDR_ARCH_SHIFT (20) /* Bits 20-27: Architecture Identifier */ +#define CHIPID_CIDR_ARCH_MASK (0xff << CHIPID_CIDR_ARCH_SHIFT) +# define CHIPID_CIDR_ARCH_AT91SAM9XX (0x19 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM9xx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM9XEXX (0x29 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM9XExx Series */ +# define CHIPID_CIDR_ARCH_AT91X34 (0x34 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x34 Series */ +# define CHIPID_CIDR_ARCH_CAP7 (0x37 << CHIPID_CIDR_ARCH_SHIFT) /* CAP7 Series */ +# define CHIPID_CIDR_ARCH_CAP9 (0x39 << CHIPID_CIDR_ARCH_SHIFT) /* CAP9 Series */ +# define CHIPID_CIDR_ARCH_CAP11 (0x3b << CHIPID_CIDR_ARCH_SHIFT) /* CAP11 Series */ +# define CHIPID_CIDR_ARCH_AT91X40 (0x40 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x40 Series */ +# define CHIPID_CIDR_ARCH_AT91X42 (0x42 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x42 Series */ +# define CHIPID_CIDR_ARCH_AT91X55 (0x55 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x55 Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7AXX (0x60 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Axx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7AQXX (0x61 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7AQxx Series */ +# define CHIPID_CIDR_ARCH_AT91X63 (0x63 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x63 Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SXX (0x70 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Sxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7XCXX (0x71 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7XCxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SEXX (0x72 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7SExx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7LXX (0x73 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Lxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7XXX (0x75 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Xxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SLXX (0x76 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7SLxx Series */ +# define CHIPID_CIDR_ARCH_SAM3UXC (0x80 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3UxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3UXE (0x81 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3UxE Series (144-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3AXC (0x83 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3AxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXC (0x84 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXE (0x85 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxE Series (144-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXG (0x86 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxG Series (208/217-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXA (0x88 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXA (0x88 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4SxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXB (0x89 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXB (0x89 << CHIPID_CIDR_ARCH_SHIFT) /* SAM34xB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXC (0x8a << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXC (0x8a << CHIPID_CIDR_ARCH_SHIFT) /* SAM4SxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_AT91X92 (0x92 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x92 Series */ +# define CHIPID_CIDR_ARCH_SAM3NXA (0x93 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3NXB (0x94 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3NXC (0x95 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3DXB (0x99 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SDxB SAM3SDxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SDXC (0x9a << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SDxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM5A (0xa5 << CHIPID_CIDR_ARCH_SHIFT) /* SAM5A */ +# define CHIPID_CIDR_ARCH_SAM4LA (0xb0 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxA Series */ +# define CHIPID_CIDR_ARCH_SAM4LB (0xb1 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxB Series */ +# define CHIPID_CIDR_ARCH_SAM4LC (0xb2 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxC Series */ +# define CHIPID_CIDR_ARCH_AT75CXX (0xf0 << CHIPID_CIDR_ARCH_SHIFT) /* AT75Cxx Series */ +#define CHIPID_CIDR_NVPTYP_SHIFT (28) /* Bits 28-30: Nonvolatile Program Memory Type */ +#define CHIPID_CIDR_NVPTYP_MASK (7 << CHIPID_CIDR_NVPTYP_SHIFT) +# define CHIPID_CIDR_NVPTYP_ROM (0 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROM */ +# define CHIPID_CIDR_NVPTYP_FLASH (1 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROMless or on-chip Flash */ +# define CHIPID_CIDR_NVPTYP_SRAM (4 << CHIPID_CIDR_NVPTYP_SHIFT) /* SRAM emulating ROM */ +# define CHIPID_CIDR_NVPTYP_EFLASH (2 << CHIPID_CIDR_NVPTYP_SHIFT) /* Embedded Flash Memory */ +# define CHIPID_CIDR_NVPTYP_REFLASH (3 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROM and Embedded Flash Memory */ +#define CHIPID_CIDR_EXT (1 << 31) /* Bit 31: Extension Flag */ + +/* Chip ID Extension Register (32-bit value for SAM3U and SAM4S) */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define CHIPID_EXID_AES (1 << 0) /* Bit 0: AES Option */ +# define CHIPID_EXID_USB (1 << 1) /* Bit 1: USB Configuration */ +# define CHIPID_EXID_USBFULL (1 << 2) /* Bit 2: USB Option */ +# define CHIPID_EXID_LCD (1 << 3) /* Bit 3: LCD Option */ +# define CHIPID_EXID_PACKAGE_SHIFT (24) /* Bits 24-26: Package Type */ +# define CHIPID_EXID_PACKAGE_MASK (7 << CHIPID_EXID_PACKAGE_SHIFT) +# define CHIPID_EXID_PACKAGE_24PIN (0 << CHIPID_EXID_PACKAGE_SHIFT) /* 24-pin package */ +# define CHIPID_EXID_PACKAGE_32PIN (1 << CHIPID_EXID_PACKAGE_SHIFT) /* 32-pin package */ +# define CHIPID_EXID_PACKAGE_48PIN (2 << CHIPID_EXID_PACKAGE_SHIFT) /* 48-pin package */ +# define CHIPID_EXID_PACKAGE_64PIN (3 << CHIPID_EXID_PACKAGE_SHIFT) /* 64-pin package */ +# define CHIPID_EXID_PACKAGE_100PIN (4 << CHIPID_EXID_PACKAGE_SHIFT) /* 100-pin package */ +# define CHIPID_EXID_PACKAGE_144PIN (5 << CHIPID_EXID_PACKAGE_SHIFT) /* 144-pin package */ +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_CHIPID_H */ diff --git a/arch/arm/src/sam34/chip/sam_cmcc.h b/arch/arm/src/sam34/chip/sam_cmcc.h new file mode 100644 index 0000000000000000000000000000000000000000..0d0d96b9161b1fcaceaee6149a192db8d692b87d --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_cmcc.h @@ -0,0 +1,181 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_cmcc.h + * Cortex M Cache Controller (CMCC) for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_CMCC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_CMCC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* This information is available in the Cache Type Register. How every, it is more + * efficient if we do not to do the decoding on each cache access. + * + * CacheSize = CacheLineSize * NCacheLines * NWays + * CacheAddressRange = CacheLineSize * NCacheLines = CacheSize / NWays + */ + +#ifdef CONFIG_ARCH_CHIP_SAM4E +# define CMCC_CACHE_SIZE 2048 +# define CMCC_CACHE_LINE_SIZE 16 +# define CMCC_NWAYS 4 +#endif + +/* CMCC register offsets ****************************************************************/ + +#define SAM_CMCC_TYPE_OFFSET 0x0000 /* Cache Type Register */ +#define SAM_CMCC_CFG_OFFSET 0x0004 /* Cache Configuration Register */ +#define SAM_CMCC_CTRL_OFFSET 0x0008 /* Cache Control Register */ +#define SAM_CMCC_SR_OFFSET 0x000c /* Cache Status Register */ + /* 0x0010-0x001c Reserved */ +#define SAM_CMCC_MAINT0_OFFSET 0x0020 /* Cache Maintenance Register 0 */ +#define SAM_CMCC_MAINT1_OFFSET 0x0024 /* Cache Maintenance Register 1 */ +#define SAM_CMCC_MCFG_OFFSET 0x0028 /* Cache Monitor Configuration Register */ +#define SAM_CMCC_MEN_OFFSET 0x002c /* Cache Monitor Enable Register */ +#define SAM_CMCC_MCTRL_OFFSET 0x0030 /* Cache Monitor Control Register */ +#define SAM_CMCC_MSR_OFFSET 0x0034 /* Cache Monitor Status Register */ + /* 0x0038-0x00fc Reserved */ + +/* CMCC register addresses **************************************************************/ + +#define SAM_CMCC_TYPE (SAM_CMCC_BASE+SAM_CMCC_TYPE_OFFSET) +#define SAM_CMCC_CFG (SAM_CMCC_BASE+SAM_CMCC_CFG_OFFSET) +#define SAM_CMCC_CTRL (SAM_CMCC_BASE+SAM_CMCC_CTRL_OFFSET) +#define SAM_CMCC_SR (SAM_CMCC_BASE+SAM_CMCC_SR_OFFSET) +#define SAM_CMCC_MAINT0 (SAM_CMCC_BASE+SAM_CMCC_MAINT0_OFFSET) +#define SAM_CMCC_MAINT1 (SAM_CMCC_BASE+SAM_CMCC_MAINT1_OFFSET) +#define SAM_CMCC_MCFG (SAM_CMCC_BASE+SAM_CMCC_MCFG_OFFSET) +#define SAM_CMCC_MEN (SAM_CMCC_BASE+SAM_CMCC_MEN_OFFSET) +#define SAM_CMCC_MCTRL (SAM_CMCC_BASE+SAM_CMCC_MCTRL_OFFSET) +#define SAM_CMCC_MSR (SAM_CMCC_BASE+SAM_CMCC_MSR_OFFSET) + +/* CMCC register bit definitions ********************************************************/ + +/* Cache Type Register */ + +#define CMCC_TYPE_AP (1 << 0) /* Bit 0: Access Port Access Allowed */ +#define CMCC_TYPE_GCLK (1 << 1) /* Bit 1: Dynamic Clock Gating Supported */ +#define CMCC_TYPE_RANDP (1 << 2) /* Bit 2: Random Selection Policy Supported */ +#define CMCC_TYPE_LRUP (1 << 3) /* Bit 3: Least Recently Used Policy Supported */ +#define CMCC_TYPE_RRP (1 << 4) /* Bit 4: Random Selection Policy Supported */ +#define CMCC_TYPE_WAYNUM_SHIFT (5) /* Bits 5-6: Number of Way */ +#define CMCC_TYPE_WAYNUM_MASK (3 << CMCC_TYPE_WAYNUM_SHIFT) +# define CMCC_TYPE_WAYNUM_DMAPPED (0 << CMCC_TYPE_WAYNUM_SHIFT) /* Direct Mapped Cache */ +# define CMCC_TYPE_WAYNUM_ARCH2WAY (1 << CMCC_TYPE_WAYNUM_SHIFT) /* 2-WAY set associative */ +# define CMCC_TYPE_WAYNUM_ARCH4WAY (2 << CMCC_TYPE_WAYNUM_SHIFT) /* 4-WAY set associative */ +# define CMCC_TYPE_WAYNUM_ARCH8WAY (3 << CMCC_TYPE_WAYNUM_SHIFT) /* 8-WAY set associative */ +#define CMCC_TYPE_LCKDOWN (1 << 7) /* Bit 7: Lock Down Supported */ +#define CMCC_TYPE_CSIZE_SHIFT (8) /* Bits 8-10: Cache Size */ +#define CMCC_TYPE_CSIZE_MASK (7 << CMCC_TYPE_CSIZE_SHIFT) +# define CMCC_TYPE_CSIZE_1KB (0 << CMCC_TYPE_CSIZE_SHIFT) /* Cache Size 1 Kbytes */ +# define CMCC_TYPE_CSIZE_2KB (1 << CMCC_TYPE_CSIZE_SHIFT) /* Cache Size 2 Kbytes */ +# define CMCC_TYPE_CSIZE_4KB (2 << CMCC_TYPE_CSIZE_SHIFT) /* Cache Size 4 Kbytes */ +# define CMCC_TYPE_CSIZE_8KB (3 << CMCC_TYPE_CSIZE_SHIFT) /* Cache Size 8 Kbytes */ +#define CMCC_TYPE_CLSIZE_SHIFT (11) /* Bits 11-13: Cache Line Size */ +#define CMCC_TYPE_CLSIZE_MASK (7 << CMCC_TYPE_CLSIZE_SHIFT) +# define CMCC_TYPE_CLSIZE_4B (0 << CMCC_TYPE_CLSIZE_SHIFT) /* 4 Bytes */ +# define CMCC_TYPE_CLSIZE_8B (1 << CMCC_TYPE_CLSIZE_SHIFT) /* 8 Bytes */ +# define CMCC_TYPE_CLSIZE_16B (2 << CMCC_TYPE_CLSIZE_SHIFT) /* 16 Bytes */ +# define CMCC_TYPE_CLSIZE_32B (3 << CMCC_TYPE_CLSIZE_SHIFT) /* 32 Bytes */ + +/* Cache Configuration Register */ + +#define CMCC_CFG_GCLKDIS (1 << 0) /* Bit 0: Disable Clock Gating */ + +/* Cache Control Register */ + +#define CMCC_CTRL_CEN (1 << 0) /* Bit 0: Cache Controller Enable */ + +/* Cache Status Register */ + +#define CMCC_SR_CSTS (1 << 0) /* Bit 0: Cache Controller Status */ + +/* Cache Maintenance Register 0 */ + +#define CMCC_MAINT0_INVALL (1 << 0) /* Bit 0: Cache Controller Invalidate All */ + +/* Cache Maintenance Register 1 */ + +#define CMCC_MAINT1_INDEX_SHIFT (4) /* Bits 4-8: Invalidate Index */ +#define CMCC_MAINT1_INDEX_MASK (31 << CMCC_MAINT1_INDEX_SHIFT) +# define CMCC_MAINT1_INDEX(n) ((uint32_t)(n) << CMCC_MAINT1_INDEX_SHIFT) +#define CMCC_MAINT1_WAY_SHIFT (30) /* Bits 30-31: Invalidate Way */ +#define CMCC_MAINT1_WAY_MASK (3 << CMCC_MAINT1_WAY_SHIFT) +# define CMCC_MAINT1_WAY(n) ((uint32_t)(n) << CMCC_MAINT1_WAY_SHIFT) +# define CMCC_MAINT1_WAY0 (0 << CMCC_MAINT1_WAY_SHIFT) /* Way 0 selected */ +# define CMCC_MAINT1_WAY1 (1 << CMCC_MAINT1_WAY_SHIFT) /* Way 1 selected */ +# define CMCC_MAINT1_WAY2 (2 << CMCC_MAINT1_WAY_SHIFT) /* Way 2 selected */ +# define CMCC_MAINT1_WAY3 (3 << CMCC_MAINT1_WAY_SHIFT) /* Way 3 selected */ + +/* Cache Monitor Configuration Register */ + +#define CMCC_MCFG_MODE_SHIFT (0) /* Bits 0-1: Cache Controller Monitor Counter Mode */ +#define CMCC_MCFG_MODE_MASK (3 << CMCC_MCFG_MODE_SHIFT) +# define CMCC_MCFG_MODE_CYCLECOUNT (0 << CMCC_MCFG_MODE_SHIFT) /* Cycle counter */ +# define CMCC_MCFG_MODE_IHITCOUNT (1 << CMCC_MCFG_MODE_SHIFT) /* Instruction hit counter */ +# define CMCC_MCFG_MODE_DHITCOUNT (2 << CMCC_MCFG_MODE_SHIFT) /* Data hit counter */ + +/* Cache Monitor Enable Register */ + +#define CMCC_MEN_MENABLE (1 << 0) /* Bit 0: Cache Controller Monitor Enable */ + +/* Cache Monitor Control Register */ + +#define CMCC_MCTRL_SWRST (1 << 0) /* Bit 0: Monitor */ + +/* Cache Monitor Status Register -- 32-bit event count */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_CMCC_H */ diff --git a/arch/arm/src/sam34/chip/sam_dacc.h b/arch/arm/src/sam34/chip/sam_dacc.h new file mode 100644 index 0000000000000000000000000000000000000000..4581289edae6b27b4a6f78da6a3868b6718fbf4f --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_dacc.h @@ -0,0 +1,232 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_dacc.h + * Digital-to-Analog Converter Controller (DACC) for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_DACC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_DACC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* DACC register offsets *****************************************************************/ + +#define SAM_DACC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_DACC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_DACC_CHER_OFFSET 0x0010 /* Channel Enable Register */ +#define SAM_DACC_CHDR_OFFSET 0x0014 /* Channel Disable Register */ +#define SAM_DACC_CHSR_OFFSET 0x0018 /* Channel Status Register */ +#define SAM_DACC_CDR_OFFSET 0x0020 /* Conversion Data Register */ +#define SAM_DACC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_DACC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_DACC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_DACC_ISR_OFFSET 0x0030 /* Interrupt Status Register */ +#define SAM_DACC_ACR_OFFSET 0x0094 /* Analog Current Register */ +#define SAM_DACC_WPMR_OFFSET 0x00e4 /* Write Protect Mode register */ +#define SAM_DACC_WPSR_OFFSET 0x00e8 /* Write Protect Status register */ + +/* DACC register addresses **************************************************************/ + +#define SAM_DACC_CR (SAM_DACC_BASE+SAM_DACC_CR_OFFSET) +#define SAM_DACC_MR (SAM_DACC_BASE+SAM_DACC_MR_OFFSET) +#define SAM_DACC_CHER (SAM_DACC_BASE+SAM_DACC_CHER_OFFSET) +#define SAM_DACC_CHDR (SAM_DACC_BASE+SAM_DACC_CHDR_OFFSET) +#define SAM_DACC_CHSR (SAM_DACC_BASE+SAM_DACC_CHSR_OFFSET) +#define SAM_DACC_CDR (SAM_DACC_BASE+SAM_DACC_CDR_OFFSET) +#define SAM_DACC_IER (SAM_DACC_BASE+SAM_DACC_IER_OFFSET) +#define SAM_DACC_IDR (SAM_DACC_BASE+SAM_DACC_IDR_OFFSET) +#define SAM_DACC_IMR (SAM_DACC_BASE+SAM_DACC_IMR_OFFSET) +#define SAM_DACC_ISR (SAM_DACC_BASE+SAM_DACC_ISR_OFFSET) +#define SAM_DACC_ACR (SAM_DACC_BASE+SAM_DACC_ACR_OFFSET) +#define SAM_DACC_WPMR (SAM_DACC_BASE+SAM_DACC_WPMR_OFFSET) +#define SAM_DACC_WPSR (SAM_DACC_BASE+SAM_DACC_WPSR_OFFSET) + +/* DACC register bit definitions ********************************************************/ + +/* Control Register */ + +#define DACC_CR_SWRST (1 << 0) /* Bit 0: Software reset */ + +/* Mode Register */ + +#define DACC_MR_TRGEN (1 << 0) /* Bit 0: Trigger Enable */ +#define DACC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define DACC_MR_TRGSEL_MASK (7 << DACC_MR_TRGSEL_SHIFT) +# define DACC_MR_TRGSEL_EXTERN (0 << DACC_MR_TRGSEL_SHIFT) /* External trigger */ +# define DACC_MR_TRGSEL_TIO0 (1 << DACC_MR_TRGSEL_SHIFT) /* TIO Output of the TC Channel 0 */ +# define DACC_MR_TRGSEL_TIO1 (2 << DACC_MR_TRGSEL_SHIFT) /* TIO Output of the TC Channel 1 */ +# define DACC_MR_TRGSEL_TIO2 (3 << DACC_MR_TRGSEL_SHIFT) /* TIO Output of the TC Channel 2 */ +# define DACC_MR_TRGSEL_PWM0 (4 << DACC_MR_TRGSEL_SHIFT) /* PWM Event Line 0 */ +# define DACC_MR_TRGSEL_PWM1 (5 << DACC_MR_TRGSEL_SHIFT) /* PWM Event Line 1 */ +#define DACC_MR_WORD (1 << 4) /* Bit 4: Word Transfer */ +#define DACC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ +#define DACC_MR_FASTWKUP (1 << 6) /* Bit 6: Fast Wake up Mode */ +#define DACC_MR_REFRESH_SHIFT (8) /* Bits 8-15: Refresh Period */ +#define DACC_MR_REFRESH_MASK (0xff << DACC_MR_REFRESH_SHIFT) +#define DACC_MR_USERSEL_SHIFT (16) /* Bits 16-17: User Channel Selection */ +#define DACC_MR_USERSEL_MASK (3 << DACC_MR_USERSEL_SHIFT) +# define DACC_MR_USERSEL_CHAN0 (0 << DACC_MR_USERSEL_SHIFT) /* Channel 0 */ +# define DACC_MR_USERSEL_CHAN1 (1 << DACC_MR_USERSEL_SHIFT) /* Channel 1 */ +#define DACC_MR_TAG (1 << 20) /* Bit 20: Tag Selection Mode */ +#define DACC_MR_MAXS (1 << 21) /* Bit 21: Max Speed Mode */ +#define DACC_MR_CLKDIV (1 << 22) /* Bit 22: Clock Divider */ +# define DACC_MR_CLKDIV_2 (0) /* DAC clock is MCK divided by 2 */ +# define DACC_MR_CLKDIV_4 DACC_MR_CLKDIV /* DAC clock is MCK divided by 4 */ +#define DACC_MR_STARTUP_SHIFT (24) /* Bits 24-29: Startup Time Select */ +#define DACC_MR_STARTUP_MASK (63 << DACC_MR_STARTUP_SHIFT) +# define DACC_MR_STARTUP_0 (0 << DACC_MR_STARTUP_SHIFT) /* 0 periods of DACClock */ +# define DACC_MR_STARTUP_8 (1 << DACC_MR_STARTUP_SHIFT) /* 8 periods of DACClock */ +# define DACC_MR_STARTUP_16 (2 << DACC_MR_STARTUP_SHIFT) /* 16 periods of DACClock */ +# define DACC_MR_STARTUP_24 (3 << DACC_MR_STARTUP_SHIFT) /* 24 periods of DACClock */ +# define DACC_MR_STARTUP_64 (4 << DACC_MR_STARTUP_SHIFT) /* 64 periods of DACClock */ +# define DACC_MR_STARTUP_80 (5 << DACC_MR_STARTUP_SHIFT) /* 80 periods of DACClock */ +# define DACC_MR_STARTUP_96 (6 << DACC_MR_STARTUP_SHIFT) /* 96 periods of DACClock */ +# define DACC_MR_STARTUP_112 (7 << DACC_MR_STARTUP_SHIFT) /* 112 periods of DACClock */ +# define DACC_MR_STARTUP_512 (8 << DACC_MR_STARTUP_SHIFT) /* 512 periods of DACClock */ +# define DACC_MR_STARTUP_576 (9 << DACC_MR_STARTUP_SHIFT) /* 576 periods of DACClock */ +# define DACC_MR_STARTUP_640 (10 << DACC_MR_STARTUP_SHIFT) /* 640 periods of DACClock */ +# define DACC_MR_STARTUP_704 (11 << DACC_MR_STARTUP_SHIFT) /* 704 periods of DACClock */ +# define DACC_MR_STARTUP_768 (12 << DACC_MR_STARTUP_SHIFT) /* 768 periods of DACClock */ +# define DACC_MR_STARTUP_832 (13 << DACC_MR_STARTUP_SHIFT) /* 832 periods of DACClock */ +# define DACC_MR_STARTUP_896 (14 << DACC_MR_STARTUP_SHIFT) /* 896 periods of DACClock */ +# define DACC_MR_STARTUP_960 (51 << DACC_MR_STARTUP_SHIFT) /* 960 periods of DACClock */ +# define DACC_MR_STARTUP_1024 (16 << DACC_MR_STARTUP_SHIFT) /* 1024 periods of DACClock */ +# define DACC_MR_STARTUP_1088 (17 << DACC_MR_STARTUP_SHIFT) /* 1088 periods of DACClock */ +# define DACC_MR_STARTUP_1152 (18 << DACC_MR_STARTUP_SHIFT) /* 1152 periods of DACClock */ +# define DACC_MR_STARTUP_1216 (19 << DACC_MR_STARTUP_SHIFT) /* 1216 periods of DACClock */ +# define DACC_MR_STARTUP_1280 (20 << DACC_MR_STARTUP_SHIFT) /* 1280 periods of DACClock */ +# define DACC_MR_STARTUP_1344 (21 << DACC_MR_STARTUP_SHIFT) /* 1344 periods of DACClock */ +# define DACC_MR_STARTUP_1408 (22 << DACC_MR_STARTUP_SHIFT) /* 1408 periods of DACClock */ +# define DACC_MR_STARTUP_1472 (23 << DACC_MR_STARTUP_SHIFT) /* 1472 periods of DACClock */ +# define DACC_MR_STARTUP_1536 (24 << DACC_MR_STARTUP_SHIFT) /* 1536 periods of DACClock */ +# define DACC_MR_STARTUP_1600 (25 << DACC_MR_STARTUP_SHIFT) /* 1600 periods of DACClock */ +# define DACC_MR_STARTUP_1664 (26 << DACC_MR_STARTUP_SHIFT) /* 1664 periods of DACClock */ +# define DACC_MR_STARTUP_1728 (27 << DACC_MR_STARTUP_SHIFT) /* 1728 periods of DACClock */ +# define DACC_MR_STARTUP_1792 (28 << DACC_MR_STARTUP_SHIFT) /* 1792 periods of DACClock */ +# define DACC_MR_STARTUP_1856 (29 << DACC_MR_STARTUP_SHIFT) /* 1856 periods of DACClock */ +# define DACC_MR_STARTUP_1920 (30 << DACC_MR_STARTUP_SHIFT) /* 1920 periods of DACClock */ +# define DACC_MR_STARTUP_1984 (31 << DACC_MR_STARTUP_SHIFT) /* 1984 periods of DACClock */ +# define DACC_MR_STARTUP_2048 (32 << DACC_MR_STARTUP_SHIFT) /* 2048 periods of DACClock */ +# define DACC_MR_STARTUP_2112 (33 << DACC_MR_STARTUP_SHIFT) /* 2112 periods of DACClock */ +# define DACC_MR_STARTUP_2176 (34 << DACC_MR_STARTUP_SHIFT) /* 2176 periods of DACClock */ +# define DACC_MR_STARTUP_2240 (35 << DACC_MR_STARTUP_SHIFT) /* 2240 periods of DACClock */ +# define DACC_MR_STARTUP_2304 (36 << DACC_MR_STARTUP_SHIFT) /* 2304 periods of DACClock */ +# define DACC_MR_STARTUP_2368 (37 << DACC_MR_STARTUP_SHIFT) /* 2368 periods of DACClock */ +# define DACC_MR_STARTUP_2432 (38 << DACC_MR_STARTUP_SHIFT) /* 2432 periods of DACClock */ +# define DACC_MR_STARTUP_2496 (39 << DACC_MR_STARTUP_SHIFT) /* 2496 periods of DACClock */ +# define DACC_MR_STARTUP_2560 (40 << DACC_MR_STARTUP_SHIFT) /* 2560 periods of DACClock */ +# define DACC_MR_STARTUP_2624 (41 << DACC_MR_STARTUP_SHIFT) /* 2624 periods of DACClock */ +# define DACC_MR_STARTUP_2688 (42 << DACC_MR_STARTUP_SHIFT) /* 2688 periods of DACClock */ +# define DACC_MR_STARTUP_2752 (43 << DACC_MR_STARTUP_SHIFT) /* 2752 periods of DACClock */ +# define DACC_MR_STARTUP_2816 (44 << DACC_MR_STARTUP_SHIFT) /* 2816 periods of DACClock */ +# define DACC_MR_STARTUP_2880 (45 << DACC_MR_STARTUP_SHIFT) /* 2880 periods of DACClock */ +# define DACC_MR_STARTUP_2944 (46 << DACC_MR_STARTUP_SHIFT) /* 2944 periods of DACClock */ +# define DACC_MR_STARTUP_3008 (47 << DACC_MR_STARTUP_SHIFT) /* 3008 periods of DACClock */ +# define DACC_MR_STARTUP_3072 (48 << DACC_MR_STARTUP_SHIFT) /* 3072 periods of DACClock */ +# define DACC_MR_STARTUP_3136 (49 << DACC_MR_STARTUP_SHIFT) /* 3136 periods of DACClock */ +# define DACC_MR_STARTUP_3200 (50 << DACC_MR_STARTUP_SHIFT) /* 3200 periods of DACClock */ +# define DACC_MR_STARTUP_3264 (51 << DACC_MR_STARTUP_SHIFT) /* 3264 periods of DACClock */ +# define DACC_MR_STARTUP_3328 (52 << DACC_MR_STARTUP_SHIFT) /* 3328 periods of DACClock */ +# define DACC_MR_STARTUP_3392 (53 << DACC_MR_STARTUP_SHIFT) /* 3392 periods of DACClock */ +# define DACC_MR_STARTUP_3456 (54 << DACC_MR_STARTUP_SHIFT) /* 3456 periods of DACClock */ +# define DACC_MR_STARTUP_3520 (55 << DACC_MR_STARTUP_SHIFT) /* 3520 periods of DACClock */ +# define DACC_MR_STARTUP_3584 (56 << DACC_MR_STARTUP_SHIFT) /* 3584 periods of DACClock */ +# define DACC_MR_STARTUP_3648 (57 << DACC_MR_STARTUP_SHIFT) /* 3648 periods of DACClock */ +# define DACC_MR_STARTUP_3712 (58 << DACC_MR_STARTUP_SHIFT) /* 3712 periods of DACClock */ +# define DACC_MR_STARTUP_3776 (59 << DACC_MR_STARTUP_SHIFT) /* 3776 periods of DACClock */ +# define DACC_MR_STARTUP_3840 (60 << DACC_MR_STARTUP_SHIFT) /* 3840 periods of DACClock */ +# define DACC_MR_STARTUP_3940 (61 << DACC_MR_STARTUP_SHIFT) /* 3904 periods of DACClock */ +# define DACC_MR_STARTUP_3968 (62 << DACC_MR_STARTUP_SHIFT) /* 3968 periods of DACClock */ +# define DACC_MR_STARTUP_4032 (63 << DACC_MR_STARTUP_SHIFT) /* 4032 periods of DACClock */ + +/* Channel Enable, Channel Disable, and Channel Status Registers */ + +#define DACC_CH0 (1 << 0) /* Bit 0: Channel 0 */ +#define DACC_CH1 (1 << 1) /* Bit 1: Channel 1 */ + +/* Conversion Data Register -- 32-bit data */ + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask, and Interrupt Status Register */ + +#define DACC_INT_TXRDY (1 << 0) /* Bit 0: Transmit Ready Interrupt */ +#define DACC_INT_EOC (1 << 1) /* Bit 1: End of Conversion Interrupt Flag */ +#define DACC_INT_ENDTX (1 << 2) /* Bit 2: End of DMA Interrupt Flag */ +#define DACC_INT_TXBUFE (1 << 3) /* Bit 3: Transmit Buffer Empty */ + +/* Analog Current Register */ + +#define DACC_ACR_IBCTLCH_SHIFT (0) /* Bits 0-1: Analog Output Current Control */ +#define DACC_ACR_IBCTLCH_MASK (3 << DACC_ACR_IBCTLCH_SHIFT +#define DACC_ACR_IBCTLCH0 (1 << 0) /* Bit 0: Analog Output Current Control 0 */ +#define DACC_ACR_IBCTLCH1 (1 << 1) /* Bit 1: Analog Output Current Control 1 */ +#define DACC_ACR_IBCTLDACCORE_SHIFT (8) /* Bits 8-9: Bias Current Control for DAC Core */ +#define DACC_ACR_IBCTLDACCORE_MASK (3 << DACC_ACR_IBCTLDACCORE_SHIFT) +# define DACC_ACR_IBCTLDACCORE(n) ((uint32_t)(n) << DACC_ACR_IBCTLDACCORE_SHIFT) + +/* Write Protect Mode register */ + +#define DACC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define DACC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define DACC_WPMR_WPKEY_MASK (0x00ffffff << DACC_WPMR_WPKEY_SHIFT) +# define DACC_WPMR_WPKEY_MASK (0x00444143 << DACC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status register */ + +#define DACC_WPSR_WPROTERR (1 << 0) /* Bit 0: Write protection error */ +#define DACC_WPSR_WPROTADDR_SHIFT (8) /* Bits 8-15: Write protection error address */ +#define DACC_WPSR_WPROTADDR_MASK (0xff << DACC_WPSR_WPROTADDR_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_DACC_H */ diff --git a/arch/arm/src/sam34/chip/sam_dmac.h b/arch/arm/src/sam34/chip/sam_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..90c4e9dea24e32c59ef7da616508c739fc257148 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_dmac.h @@ -0,0 +1,538 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_dmac.h + * DMA Controller (DMAC) definitions for the SAM3U, SAM3X, SAM3A, and SAM4E + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_DMAC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_DMAC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* DMAC register offsets ****************************************************************/ + +/* Global Registers */ + +#define SAM_DMAC_GCFG_OFFSET 0x0000 /* DMAC Global Configuration Register */ +#define SAM_DMAC_EN_OFFSET 0x0004 /* DMAC Enable Register */ +#define SAM_DMAC_SREQ_OFFSET 0x0008 /* DMAC Software Single Request Register */ +#define SAM_DMAC_CREQ_OFFSET 0x000c /* DMAC Software Chunk Transfer Request Register */ +#define SAM_DMAC_LAST_OFFSET 0x0010 /* DMAC Software Last Transfer Flag Register */ + /* 0x014: Reserved */ +#define SAM_DMAC_EBCIER_OFFSET 0x0018 /* DMAC Error Enable */ +#define SAM_DMAC_EBCIDR_OFFSET 0x001C /* DMAC Error Disable */ +#define SAM_DMAC_EBCIMR_OFFSET 0x0020 /* DMAC Error Mask */ +#define SAM_DMAC_EBCISR_OFFSET 0x0024 /* DMAC Error Status */ +#define SAM_DMAC_CHER_OFFSET 0x0028 /* DMAC Channel Handler Enable Register */ +#define SAM_DMAC_CHDR_OFFSET 0x002c /* DMAC Channel Handler Disable Register */ +#define SAM_DMAC_CHSR_OFFSET 0x0030 /* DMAC Channel Handler Status Register */ + /* 0x034-0x38: Reserved */ +/* DMA channel registers */ + +#define SAM_DMACHAN_OFFSET(n) (0x003c+((n)*0x28)) +#define SAM_DMACHAN0_OFFSET 0x003c /* 0x003c-0x0060: Channel 0 */ +#define SAM_DMACHAN1_OFFSET 0x0064 /* 0x0064-0x0088: Channel 1 */ +#define SAM_DMACHAN2_OFFSET 0x008c /* 0x008c-0x00b0: Channel 2 */ +#define SAM_DMACHAN3_OFFSET 0x00b4 /* 0x00b4-0x00d8: Channel 3 */ +#define SAM_DMACHAN4_OFFSET 0x00dc /* 0x00dc-0x0103: Channel 4 */ +#define SAM_DMACHAN5_OFFSET 0x0104 /* 0x0104-0x0128: Channel 5 */ + +#define SAM_DMACHAN_SADDR_OFFSET 0x0000 /* DMAC Channel Source Address Register */ +#define SAM_DMACHAN_DADDR_OFFSET 0x0004 /* DMAC Channel Destination Address Register */ +#define SAM_DMACHAN_DSCR_OFFSET 0x0008 /* DMAC Channel Descriptor Address Register */ +#define SAM_DMACHAN_CTRLA_OFFSET 0x000c /* DMAC Channel Control A Register */ +#define SAM_DMACHAN_CTRLB_OFFSET 0x0010 /* DMAC Channel Control B Register */ +#define SAM_DMACHAN_CFG_OFFSET 0x0014 /* DMAC Channel Configuration Register */ + /* 0x18-0x24: Reserved */ + +/* More Global Registers */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_DMAC_WPMR_OFFSET 0x01e4 /* DMAC Write Protect Mode Register */ +# define SAM_DMAC_WPSR_OFFSET 0x01e8 /* DMAC Write Protect Status Register DMAC_WPSR */ +#endif + +/* DMAC register addresses **************************************************************/ + +/* Global Registers */ + +#define SAM_DMAC_GCFG (SAM_DMAC_BASE+SAM_DMAC_GCFG_OFFSET) +#define SAM_DMAC_EN (SAM_DMAC_BASE+SAM_DMAC_EN_OFFSET) +#define SAM_DMAC_SREQ (SAM_DMAC_BASE+SAM_DMAC_SREQ_OFFSET) +#define SAM_DMAC_CREQ (SAM_DMAC_BASE+SAM_DMAC_CREQ_OFFSET) +#define SAM_DMAC_LAST (SAM_DMAC_BASE+SAM_DMAC_LAST_OFFSET) +#define SAM_DMAC_EBCIER (SAM_DMAC_BASE+SAM_DMAC_EBCIER_OFFSET) +#define SAM_DMAC_EBCIDR (SAM_DMAC_BASE+SAM_DMAC_EBCIDR_OFFSET) +#define SAM_DMAC_EBCIMR (SAM_DMAC_BASE+SAM_DMAC_EBCIMR_OFFSET) +#define SAM_DMAC_EBCISR (SAM_DMAC_BASE+SAM_DMAC_EBCISR_OFFSET) +#define SAM_DMAC_CHER (SAM_DMAC_BASE+SAM_DMAC_CHER_OFFSET) +#define SAM_DMAC_CHDR (SAM_DMAC_BASE+SAM_DMAC_CHDR_OFFSET) +#define SAM_DMAC_CHSR (SAM_DMAC_BASE+SAM_DMAC_CHSR_OFFSET) + +/* DMA channel registers */ + +#define SAM_DMACHAN_BASE(n) (SAM_DMAC_BASE+SAM_DMACHAN_OFFSET(n)) +#define SAM_DMACHAN0_BASE (SAM_DMAC_BASE+SAM_DMACHAN0_OFFSET) +#define SAM_DMACHAN1_BASE (SAM_DMAC_BASE+SAM_DMACHAN1_OFFSET) +#define SAM_DMACHAN2_BASE (SAM_DMAC_BASE+SAM_DMACHAN2_OFFSET) +#define SAM_DMACHAN3_BASE (SAM_DMAC_BASE+SAM_DMACHAN3_OFFSET) +#define SAM_DMACHAN4_BASE (SAM_DMAC_BASE+SAM_DMACHAN4_OFFSET) +#define SAM_DMACHAN5_BASE (SAM_DMAC_BASE+SAM_DMACHAN5_OFFSET) + +#define SAM_DMACHAN_SADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_SADDR_OFFSET) +#define SAM_DMACHAN_DADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DADDR_OFFSET) +#define SAM_DMACHAN_DSCR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DSCR_OFFSET) +#define SAM_DMACHAN_CTRLA(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CTRLA_OFFSET) +#define SAM_DMACHAN_CTRLB(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CTRLB_OFFSET) +#define SAM_DMACHAN_CFG(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CFG_OFFSET) + +#define SAM_DMACHAN0_SADDR (SAM_DMACHAN0_BASE+SAM_DMACHAN_SADDR_OFFSET) +#define SAM_DMACHAN0_DADDR (SAM_DMACHAN0_BASE+SAM_DMACHAN_DADDR_OFFSET) +#define SAM_DMACHAN0_DSCR (SAM_DMACHAN0_BASE+SAM_DMACHAN_DSCR_OFFSET) +#define SAM_DMACHAN0_CTRLA (SAM_DMACHAN0_BASE+SAM_DMACHAN_CTRLA_OFFSET) +#define SAM_DMACHAN0_CTRLB (SAM_DMACHAN0_BASE+SAM_DMACHAN_CTRLB_OFFSET) +#define SAM_DMACHAN0_CFG (SAM_DMACHAN0_BASE+SAM_DMACHAN_CFG_OFFSET) + +#define SAM_DMACHAN1_SADDR (SAM_DMACHAN1_BASE+SAM_DMACHAN_SADDR_OFFSET) +#define SAM_DMACHAN1_DADDR (SAM_DMACHAN1_BASE+SAM_DMACHAN_DADDR_OFFSET) +#define SAM_DMACHAN1_DSCR (SAM_DMACHAN1_BASE+SAM_DMACHAN_DSCR_OFFSET) +#define SAM_DMACHAN1_CTRLA (SAM_DMACHAN1_BASE+SAM_DMACHAN_CTRLA_OFFSET) +#define SAM_DMACHAN1_CTRLB (SAM_DMACHAN1_BASE+SAM_DMACHAN_CTRLB_OFFSET) +#define SAM_DMACHAN1_CFG (SAM_DMACHAN1_BASE+SAM_DMACHAN_CFG_OFFSET) + +#define SAM_DMACHAN2_SADDR (SAM_DMACHAN2_BASE+SAM_DMACHAN_SADDR_OFFSET) +#define SAM_DMACHAN2_DADDR (SAM_DMACHAN2_BASE+SAM_DMACHAN_DADDR_OFFSET) +#define SAM_DMACHAN2_DSCR (SAM_DMACHAN2_BASE+SAM_DMACHAN_DSCR_OFFSET) +#define SAM_DMACHAN2_CTRLA (SAM_DMACHAN2_BASE+SAM_DMACHAN_CTRLA_OFFSET) +#define SAM_DMACHAN2_CTRLB (SAM_DMACHAN2_BASE+SAM_DMACHAN_CTRLB_OFFSET) +#define SAM_DMACHAN2_CFG (SAM_DMACHAN2_BASE+SAM_DMACHAN_CFG_OFFSET) + +#define SAM_DMACHAN3_SADDR (SAM_DMACHAN3_BASE+SAM_DMACHAN_SADDR_OFFSET) +#define SAM_DMACHAN3_DADDR (SAM_DMACHAN3_BASE+SAM_DMACHAN_DADDR_OFFSET) +#define SAM_DMACHAN3_DSCR (SAM_DMACHAN3_BASE+SAM_DMACHAN_DSCR_OFFSET) +#define SAM_DMACHAN3_CTRLA (SAM_DMACHAN3_BASE+SAM_DMACHAN_CTRLA_OFFSET) +#define SAM_DMACHAN3_CTRLB (SAM_DMACHAN3_BASE+SAM_DMACHAN_CTRLB_OFFSET) +#define SAM_DMACHAN3_CFG (SAM_DMACHAN3_BASE+SAM_DMACHAN_CFG_OFFSET) + +/* More Global Registers */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_DMAC_WPMR (SAM_DMAC_BASE+SAM_DMAC_WPMR_OFFSET) +# define SAM_DMAC_WPSR (SAM_DMAC_BASE+SAM_DMAC_WPSR_OFFSET) +#endif + +/* DMAC register bit definitions ********************************************************/ + +/* Global Registers */ + +/* DMAC Global Configuration Register */ + +#define DMAC_GCFG_ARB_CFG (1 << 4) /* Bit 4: Round robin (vs fixed) arbiter */ + +/* DMAC Enable Register */ + +#define DMAC_EN_ENABLE (1 << 0) /* Bit 0: DMA controller enable */ + +/* DMAC Software Single Request Register */ + +#define DMAC_SREQ_SHIFT(n) ((n)<<1) +#define DMAC_SREQ_MASK(n) (3 << DMAC_SREQ_SHIFT(n)) +# define DMAC_SREQ0_SHIFT (0) /* Bits 0-1: Channel 0 */ +# define DMAC_SREQ0_MASK (3 << DMAC_SREQ0_SHIFT) +# define DMAC_SREQ1_SHIFT (2) /* Bits 2-3: Channel 1 */ +# define DMAC_SREQ1_MASK (3 << DMAC_SREQ1_SHIFT) +# define DMAC_SREQ2_SHIFT (4) /* Bits 4-5: Channel 2 */ +# define DMAC_SREQ2_MASK (3 << DMAC_SREQ2_SHIFT) +# define DMAC_SREQ3_SHIFT (6) /* Bits 6-7: Channel 3 */ +# define DMAC_SREQ3_MASK (3 << DMAC_SREQ3_SHIFT) + +#define DMAC_SREQ_SSREQ_SHIFT (0) /* Bits 0, 2, 4, 6: Request a source single transfer */ +# define DMAC_SREQ_SSREQ(n) (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ_SHIFT(n))) +# define DMAC_SREQ_SSREQ0 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ0_SHIFT) +# define DMAC_SREQ_SSREQ1 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ1_SHIFT) +# define DMAC_SREQ_SSREQ2 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ2_SHIFT) +# define DMAC_SREQ_SSREQ3 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ3_SHIFT) +#define DMAC_SREQ_DSREQ_SHIFT (1) /* Bits 1, 3, 5, 7: Request a destination single transfer */ +# define DMAC_SREQ_DSREQ(n) (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ_SHIFT(n)))) +# define DMAC_SREQ_DSREQ0 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ0_SHIFT) +# define DMAC_SREQ_DSREQ1 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ1_SHIFT) +# define DMAC_SREQ_DSREQ2 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ2_SHIFT) +# define DMAC_SREQ_DSREQ3 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ3_SHIFT) + +/* DMAC Software Chunk Transfer Request Register */ + +#define DMAC_CREQ_SHIFT(n) ((n)<<1) +#define DMAC_CREQ_MASK(n) (3 << DMAC_CREQ_SHIFT(n)) +# define DMAC_CREQ0_SHIFT (0) /* Bits 0-1: Channel 0 */ +# define DMAC_CREQ0_MASK (3 << DMAC_CREQ0_SHIFT) +# define DMAC_CREQ1_SHIFT (2) /* Bits 2-3: Channel 1 */ +# define DMAC_CREQ1_MASK (3 << DMAC_CREQ1_SHIFT) +# define DMAC_CREQ2_SHIFT (4) /* Bits 4-5: Channel 2 */ +# define DMAC_CREQ2_MASK (3 << DMAC_CREQ2_SHIFT) +# define DMAC_CREQ3_SHIFT (6) /* Bits 6-7: Channel 3 */ +# define DMAC_CREQ3_MASK (3 << DMAC_CREQ3_SHIFT) + +#define DMAC_CREQ_SCREQ_SHIFT (0) /* Bits 0, 2, 4, 6: Request a source chunk transfer */ +# define DMAC_CREQ_SCREQ(n) (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ_SHIFT(n))) +# define DMAC_CREQ_SCREQ0 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ0_SHIFT)) +# define DMAC_CREQ_SCREQ1 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ1_SHIFT)) +# define DMAC_CREQ_SCREQ2 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ2_SHIFT)) +# define DMAC_CREQ_SCREQ3 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ3_SHIFT)) +#define DMAC_CREQ_DCREQ_SHIFT (1) /* Bits 1, 3, 5, 7: Request a destination chunk transfer */ +# define DMAC_CREQ_DCREQ(n) (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ_SHIFT(n))) +# define DMAC_CREQ_DCREQ0 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ0_SHIFT)) +# define DMAC_CREQ_DCREQ1 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ1_SHIFT)) +# define DMAC_CREQ_DCREQ2 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ2_SHIFT)) +# define DMAC_CREQ_DCREQ3 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ3_SHIFT)) + +/* DMAC Software Last Transfer Flag Register */ + +#define DMAC_LAST_SHIFT(n) ((n)<<1) +#define DMAC_LAST_MASK(n) (3 << DMAC_LAST_SHIFT(n)) +# define DMAC_LAST0_SHIFT (0) /* Bits 0-1: Channel 0 */ +# define DMAC_LAST0_MASK (3 << DMAC_LAST0_SHIFT) +# define DMAC_LAST1_SHIFT (2) /* Bits 2-3: Channel 1 */ +# define DMAC_LAST1_MASK (3 << DMAC_LAST1_SHIFT) +# define DMAC_LAST2_SHIFT (4) /* Bits 4-5: Channel 2 */ +# define DMAC_LAST2_MASK (3 << DMAC_LAST2_SHIFT) +# define DMAC_LAST3_SHIFT (6) /* Bits 6-7: Channel 3 */ +# define DMAC_LAST3_MASK (3 << DMAC_LAST3_SHIFT) + +#define DMAC_LAST_SLAST_SHIFT (0) /* Bits 0, 2, 4, 6: Indicates the last transfer */ +# define DMAC_LAST_SLAST(n) (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST_SHIFT(n))) +# define DMAC_LAST_SLAST0 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST0_SHIFT) +# define DMAC_LAST_SLAST1 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST1_SHIFT) +# define DMAC_LAST_SLAST2 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST2_SHIFT) +# define DMAC_LAST_SLAST3 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST3_SHIFT) +#define DMAC_LAST_DLAST_SHIFT (1) /* Bits 1, 3, 5, 7: Indicates the last transfer */ +# define DMAC_LAST_DLAST(n) (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST_SHIFT(n)))) +# define DMAC_LAST_DLAST0 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST0_SHIFT) +# define DMAC_LAST_DLAST1 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST1_SHIFT) +# define DMAC_LAST_DLAST2 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST2_SHIFT) +# define DMAC_LAST_DLAST3 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST3_SHIFT) + +/* DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Enable Register, + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Disable Register, + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Mask Register, and + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Status Register common + * bit field definitions + */ + +#define DMAC_EBC_BTC_SHIFT (0) /* Bits 0-3: Buffer Transfer Completed Interrupt Enable */ +#define DMAC_EBC_BTC_MASK (15 << DMAC_EBC_BTC_SHIFT) +# define DMAC_EBC_BTC(n) (1 << (DMAC_EBC_BTC_SHIFT+(n))) +# define DMAC_EBC_BTC0 (1 << (DMAC_EBC_BTC_SHIFT+0)) +# define DMAC_EBC_BTC1 (1 << (DMAC_EBC_BTC_SHIFT+1)) +# define DMAC_EBC_BTC2 (1 << (DMAC_EBC_BTC_SHIFT+2)) +# define DMAC_EBC_BTC3 (1 << (DMAC_EBC_BTC_SHIFT+3)) +#define DMAC_EBC_CBTC_SHIFT (8) /* Bits 8-11: Chained Buffer Transfer Completed Interrupt Enable */ +#define DMAC_EBC_CBTC_MASK (15 << DMAC_EBC_CBTC_SHIFT) +# define DMAC_EBC_CBTC(n) (1 << (DMAC_EBC_CBTC_SHIFT+(n))) +# define DMAC_EBC_CBTC0 (1 << (DMAC_EBC_CBTC_SHIFT+0)) +# define DMAC_EBC_CBTC1 (1 << (DMAC_EBC_CBTC_SHIFT+1)) +# define DMAC_EBC_CBTC2 (1 << (DMAC_EBC_CBTC_SHIFT+2)) +# define DMAC_EBC_CBTC3 (1 << (DMAC_EBC_CBTC_SHIFT+3)) +#define DMAC_EBC_ERR_SHIFT (16) /* Bits 16-19: Access Error Interrupt Enable */ +#define DMAC_EBC_ERR_MASK (15 << DMAC_EBC_ERR_SHIFT) +# define DMAC_EBC_ERR(n) (1 << (DMAC_EBC_ERR_SHIFT+(n))) +# define DMAC_EBC_ERR0 (1 << (DMAC_EBC_ERR_SHIFT+0)) +# define DMAC_EBC_ERR1 (1 << (DMAC_EBC_ERR_SHIFT+1)) +# define DMAC_EBC_ERR2 (1 << (DMAC_EBC_ERR_SHIFT+2)) +# define DMAC_EBC_ERR3 (1 << (DMAC_EBC_ERR_SHIFT+3)) + +#define DMAC_EBC_BTCINTS(n) (0x00010001 << (n)) /* BTC + ERR interrupts */ +#define DMAC_EBC_CBTCINTS(n) (0x00010100 << (n)) /* CBT + ERR interrupts */ +#define DMAC_EBC_CHANINTS(n) (0x00010101 << (n)) /* All channel interrupts */ +#define DMAC_EBC_ALLINTS (0x000f0f0f) /* All interrupts */ + +/* DMAC Channel Handler Enable Register */ + +#define DMAC_CHER_ENA_SHIFT (0) /* Bits 0-3: Enable channel */ +#define DMAC_CHER_ENA_MASK (15 << DMAC_CHER_ENA_SHIFT) +# define DMAC_CHER_ENA(n) (1 << (DMAC_CHER_ENA_SHIFT+(n))) +# define DMAC_CHER_ENA0 (1 << (DMAC_CHER_ENA_SHIFT+0)) +# define DMAC_CHER_ENA1 (1 << (DMAC_CHER_ENA_SHIFT+1)) +# define DMAC_CHER_ENA2 (1 << (DMAC_CHER_ENA_SHIFT+2)) +# define DMAC_CHER_ENA3 (1 << (DMAC_CHER_ENA_SHIFT+3)) +#define DMAC_CHER_SUSP_SHIFT (8) /* Bits 8-11: Freeze channel and its context */ +#define DMAC_CHER_SUSP_MASK (15 << DMAC_CHER_SUSP_SHIFT) +# define DMAC_CHER_SUSP(n) (1 << (DMAC_CHER_SUSP_SHIFT+(n))) +# define DMAC_CHER_SUSP0 (1 << (DMAC_CHER_SUSP_SHIFT+0)) +# define DMAC_CHER_SUSP1 (1 << (DMAC_CHER_SUSP_SHIFT+1)) +# define DMAC_CHER_SUSP2 (1 << (DMAC_CHER_SUSP_SHIFT+2)) +# define DMAC_CHER_SUSP3 (1 << (DMAC_CHER_SUSP_SHIFT+3)) +#define DMAC_CHER_KEEP_SHIFT (24) /* Bits 24-27: Resume channel from automatic stall */ +#define DMAC_CHER_KEEP_MASK (15 << DMAC_CHER_KEEP_SHIFT) +# define DMAC_CHER_KEEP(n) (1 << (DMAC_CHER_KEEP_SHIFT+(n))) +# define DMAC_CHER_KEEP0 (1 << (DMAC_CHER_KEEP_SHIFT+0)) +# define DMAC_CHER_KEEP1 (1 << (DMAC_CHER_KEEP_SHIFT+1)) +# define DMAC_CHER_KEEP2 (1 << (DMAC_CHER_KEEP_SHIFT+2)) +# define DMAC_CHER_KEEP3 (1 << (DMAC_CHER_KEEP_SHIFT+3)) + +/* DMAC Channel Handler Disable Register */ + +#define DMAC_CHDR_DIS_SHIFT (0) /* Bits 0-3: Disable DMAC channel */ +#define DMAC_CHDR_DIS_MASK (15 << DMAC_CHDR_DIS_SHIFT) +# define DMAC_CHDR_DIS(n) (1 << (DMAC_CHDR_DIS_SHIFT+(n))) +# define DMAC_CHDR_DIS0 (1 << (DMAC_CHDR_DIS_SHIFT+0)) +# define DMAC_CHDR_DIS1 (1 << (DMAC_CHDR_DIS_SHIFT+1)) +# define DMAC_CHDR_DIS2 (1 << (DMAC_CHDR_DIS_SHIFT+2)) +# define DMAC_CHDR_DIS3 (1 << (DMAC_CHDR_DIS_SHIFT+3)) +# define DMAC_CHDR_DIS_ALL DMAC_CHDR_DIS_MASK +#define DMAC_CHDR_RES_SHIFT (8) /* Bits 8-11: Resume trasnfer, restoring context */ +#define DMAC_CHDR_RES_MASK (15 << DMAC_CHDR_RES_SHIFT) +# define DMAC_CHDR_RES(n) (1 << (DMAC_CHDR_RES_SHIFT+(n))) +# define DMAC_CHDR_RES0 (1 << (DMAC_CHDR_RES_SHIFT+0)) +# define DMAC_CHDR_RES1 (1 << (DMAC_CHDR_RES_SHIFT+1)) +# define DMAC_CHDR_RES2 (1 << (DMAC_CHDR_RES_SHIFT+2)) +# define DMAC_CHDR_RES3 (1 << (DMAC_CHDR_RES_SHIFT+3)) + +/* DMAC Channel Handler Status Register */ + +#define DMAC_CHSR_ENA_SHIFT (0) /* Bits 0-3: Indicates that the channel is stalling */ +#define DMAC_CHSR_ENA_MASK (15 << DMAC_CHSR_ENA_SHIFT) +# define DMAC_CHSR_ENA(n) (1 << (DMAC_CHSR_ENA_SHIFT+(n))) +# define DMAC_CHSR_ENA0 (1 << (DMAC_CHSR_ENA_SHIFT+0)) +# define DMAC_CHSR_ENA1 (1 << (DMAC_CHSR_ENA_SHIFT+1)) +# define DMAC_CHSR_ENA2 (1 << (DMAC_CHSR_ENA_SHIFT+2)) +# define DMAC_CHSR_ENA3 (1 << (DMAC_CHSR_ENA_SHIFT+3)) +#define DMAC_CHSR_SUSP_SHIFT (8) /* Bits 8-11: Indicates that the channel is empty */ +#define DMAC_CHSR_SUSP_MASK (15 << DMAC_CHSR_SUSP_SHIFT) +# define DMAC_CHSR_SUSP(n) (1 << (DMAC_CHSR_SUSP_SHIFT+(n))) +# define DMAC_CHSR_SUSP0 (1 << (DMAC_CHSR_SUSP_SHIFT+0)) +# define DMAC_CHSR_SUSP1 (1 << (DMAC_CHSR_SUSP_SHIFT+1)) +# define DMAC_CHSR_SUSP2 (1 << (DMAC_CHSR_SUSP_SHIFT+2)) +# define DMAC_CHSR_SUSP3 (1 << (DMAC_CHSR_SUSP_SHIFT+3)) +#define DMAC_CHSR_EMPT_SHIFT (16) /* Bits 16-19: Access Error Interrupt Enable */ +#define DMAC_CHSR_EMPT_MASK (15 << DMAC_CHSR_EMPT_SHIFT) +# define DMAC_CHSR_EMPT(n) (1 << (DMAC_CHSR_EMPT_SHIFT+(n))) +# define DMAC_CHSR_EMPT0 (1 << (DMAC_CHSR_EMPT_SHIFT+0)) +# define DMAC_CHSR_EMPT1 (1 << (DMAC_CHSR_EMPT_SHIFT+1)) +# define DMAC_CHSR_EMPT2 (1 << (DMAC_CHSR_EMPT_SHIFT+2)) +# define DMAC_CHSR_EMPT3 (1 << (DMAC_CHSR_EMPT_SHIFT+3)) +#define DMAC_CHSR_STAL_SHIFT (24) /* Bits 24-27: Access Error Interrupt Enable */ +#define DMAC_CHSR_STAL_MASK (15 << DMAC_CHSR_STAL_SHIFT) +# define DMAC_CHSR_STAL(n) (1 << (DMAC_CHSR_STAL_SHIFT+(n))) +# define DMAC_CHSR_STAL0 (1 << (DMAC_CHSR_STAL_SHIFT+0)) +# define DMAC_CHSR_STAL1 (1 << (DMAC_CHSR_STAL_SHIFT+1)) +# define DMAC_CHSR_STAL2 (1 << (DMAC_CHSR_STAL_SHIFT+2)) +# define DMAC_CHSR_STAL3 (1 << (DMAC_CHSR_STAL_SHIFT+3)) + +/* DMA channel registers */ +/* DMAC Channel n [n = 0..3] Source Address Register -- 32-bit address*/ +/* DMAC Channel n [n = 0..3] Destination Address Register -- 32-bit address*/ +/* DMAC Channel n [n = 0..3] Descriptor Address Register -- 32-bit address*/ +/* DMAC Channel n [n = 0..3] Control A Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define DMACHAN_CTRLA_BTSIZE_MAX (0xfff) +# define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */ +# define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT) +# define DMACHAN_CTRLA_BTSIZE(n) ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT) +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define DMACHAN_CTRLA_BTSIZE_MAX (0xffff) +# define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-15: Buffer Transfer Size */ +# define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT) +# define DMACHAN_CTRLA_BTSIZE(n) ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define DMACHAN_CTRLA_SCSIZE (1 << 16) /* Bit 16: Source Chunk Transfer Size */ +# define DMACHAN_CTRLA_SCSIZE_1 (0) +# define DMACHAN_CTRLA_SCSIZE_4 DMACHAN_CTRLA_SCSIZE +# define DMACHAN_CTRLA_DCSIZE (1 << 20) /* Bit 20: Destination Chunk Transfer size */ +# define DMACHAN_CTRLA_DCSIZE_1 (0) +# define DMACHAN_CTRLA_DCSIZE_4 DMACHAN_CTRLA_DCSIZE +#endif + +#define DMACHAN_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */ +#define DMACHAN_CTRLA_SRCWIDTH_MASK (3 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) +# define DMACHAN_CTRLA_SRCWIDTH_BYTE (0 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) +# define DMACHAN_CTRLA_SRCWIDTH_HWORD (1 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) +# define DMACHAN_CTRLA_SRCWIDTH_WORD (2 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) +#define DMACHAN_CTRLA_DSTWIDTH_SHIFT (28) /* Bits 28-29 */ +#define DMACHAN_CTRLA_DSTWIDTH_MASK (3 << DMACHAN_CTRLA_DSTWIDTH_SHIFT) +# define DMACHAN_CTRLA_DSTWIDTH_BYTE (0 << DMACHAN_CTRLA_DSTWIDTH_SHIFT) +# define DMACHAN_CTRLA_DSTWIDTH_HWORD (1 << DMACHAN_CTRLA_DSTWIDTH_SHIFT) +# define DMACHAN_CTRLA_DSTWIDTH_WORD (2 << DMACHAN_CTRLA_DSTWIDTH_SHIFT) +#define DMACHAN_CTRLA_DONE (1 << 31) /* Bit 31: Auto disable DMAC */ + +/* DMAC Channel n [n = 0..3] Control B Register */ + +#define DMACHAN_CTRLB_SRCDSCR (1 << 16) /* Bit 16: Source buffer descriptor fetch operation disabled */ +#define DMACHAN_CTRLB_DSTDSCR (1 << 20) /* Bit 20: Dest buffer descriptor fetch operation disabled */ +#define DMACHAN_CTRLB_FC_SHIFT (21) /* Bits 21-22: Flow controller */ +#define DMACHAN_CTRLB_FC_MASK (3 << DMACHAN_CTRLB_FC_SHIFT) +# define DMACHAN_CTRLB_FC_M2M (0 << DMACHAN_CTRLB_FC_SHIFT) /* Memory-to-Memory */ +# define DMACHAN_CTRLB_FC_M2P (1 << DMACHAN_CTRLB_FC_SHIFT) /* Memory-to-Peripheral */ +# define DMACHAN_CTRLB_FC_P2M (2 << DMACHAN_CTRLB_FC_SHIFT) /* Peripheral-to-Memory */ +# define DMACHAN_CTRLB_FC_P2P (3 << DMACHAN_CTRLB_FC_SHIFT) /* Peripheral-to-Peripheral */ +#define DMACHAN_CTRLB_SRCINCR_SHIFT (24) /* Bits 24-25 */ +#define DMACHAN_CTRLB_SRCINCR_MASK (3 << DMACHAN_CTRLB_SRCINCR_SHIFT) +# define DMACHAN_CTRLB_SRCINCR_INCR (0 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Incrementing address */ +# if defined(CONFIG_ARCH_CHIP_SAM4E) +# define DMACHAN_CTRLB_SRCINCR_DECR (1 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Decrementing address */ +# endif +# define DMACHAN_CTRLB_SRCINCR_FIXED (2 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Fixed address */ +#define DMACHAN_CTRLB_DSTINCR_SHIFT (28) /* Bits 28-29 */ +#define DMACHAN_CTRLB_DSTINCR_MASK (3 << DMACHAN_CTRLB_DSTINCR_SHIFT) +# define DMACHAN_CTRLB_DSTINCR_INCR (0 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Incrementing address */ +# if defined(CONFIG_ARCH_CHIP_SAM4E) +# define DMACHAN_CTRLB_DSTINCR_DECR (1 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Decrementing address */ +# endif +# define DMACHAN_CTRLB_DSTINCR_FIXED (2 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Fixed address */ +#define DMACHAN_CTRLB_IEN (1 << 30) /* Bit 30: Clear sets BTC[n] flag in EBCISR */ + +/* DMAC Channel n [n = 0..3] Configuration Register */ + +#define DMACHAN_CFG_SRCPER_SHIFT (0) /* Bits 0-3: Channel source associated with peripheral ID */ +#define DMACHAN_CFG_SRCPER_MASK (15 << DMACHAN_CFG_SRCPER_SHIFT) +#define DMACHAN_CFG_DSTPER_SHIFT (4) /* Bits 4-7: Channel dest associated with peripheral ID */ +#define DMACHAN_CFG_DSTPER_MASK (15 << DMACHAN_CFG_DSTPER_SHIFT) +#define DMACHAN_CFG_SRCH2SEL (1 << 9) /* Bit 9: HW handshake triggers transfer */ +#define DMACHAN_CFG_DSTH2SEL (1 << 13) /* Bit 13: HW handshake trigger transfer */ +#define DMACHAN_CFG_SOD (1 << 16) /* Bit 16: Stop on done */ +#define DMACHAN_CFG_LOCKIF (1 << 20) /* Bit 20: Enable lock interface capability */ +#define DMACHAN_CFG_LOCKB (1 << 21) /* Bit 21: Enable AHB Bus Locking capability */ +#define DMACHAN_CFG_LOCKIFL (1 << 22) /* Bit 22: Lock Master Interface Arbiter */ +#define DMACHAN_CFG_AHBPROT_SHIFT (24) /* Bits 24-26: Bus access privilege */ +#define DMACHAN_CFG_AHBPROT_MASK (7 << DMACHAN_CFG_AHBPROT_SHIFT) +# define DMACHAN_CFG_AHBPROT_PRIV (1 << DMACHAN_CFG_AHBPROT_SHIFT) +# define DMACHAN_CFG_AHBPROT_BUFF (2 << DMACHAN_CFG_AHBPROT_SHIFT) +# define DMACHAN_CFG_AHBPROT_CACHE (4 << DMACHAN_CFG_AHBPROT_SHIFT) +#define DMACHAN_CFG_FIFOCFG_SHIFT (28) /* Bits 28-29 */ +#define DMACHAN_CFG_FIFOCFG_MASK (3 << DMACHAN_CFG_FIFOCFG_SHIFT) +# define DMACHAN_CFG_FIFOCFG_LARGEST (0 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Largest length AHB burst */ +# define DMACHAN_CFG_FIFOCFG_HALF (1 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Half FIFO size */ +# define DMACHAN_CFG_FIFOCFG_SINGLE (2 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Single AHB access */ + +/* More Global Registers */ + +/* DMAC Write Protect Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define DMAC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +# define DMAC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +# define DMAC_WPMR_WPKEY_MASK (0x00ffffff << DMAC_WPMR_WPKEY_SHIFT) +# define DMAC_WPMR_WPKEY (0x00444d41 << DMAC_WPMR_WPKEY_SHIFT) +#endif + +/* DMAC Write Protect Status Register DMAC_WPSR */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define DMAC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +# define DMAC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +# define DMAC_WPSR_WPVSRC_MASK (0xffff << DMAC_WPSR_WPVSRC_SHIFT) +#endif + +/* DMA Hardware interface numbers *******************************************************/ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + +# define DMACHAN_INTF_HSMCI0 0 +# define DMACHAN_INTF_SPI0TX 1 /* SPI0 Transmit */ +# define DMACHAN_INTF_SPI0RX 2 /* SPI0 Receive */ +# define DMACHAN_INTF_SSC0TX 3 /* SSC0 Transmit */ +# define DMACHAN_INTF_SSC0RX 4 /* SSC0 Receive */ +# define DMACHAN_INTF_PWM0EV0 5 /* PWM0 Event Line 0 */ +# define DMACHAN_INTF_PWM0EV1 6 /* PWM0 Event Line 1 */ +# define DMACHAN_INTF_TIO0 7 /* TIO Output of TC Ch. 0 */ + +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) + +# define DMACHAN_INTF_HSMCI0 0 /* HSMCI0 Transmit/Receive */ +# define DMACHAN_INTF_SPI0TX 1 /* SPI0 Transmit */ +# define DMACHAN_INTF_SPI0RX 2 /* SPI0 Receive */ +# define DMACHAN_INTF_SSC0TX 3 /* SSC0 Transmit */ +# define DMACHAN_INTF_SSC0RX 4 /* SSC0 Receive */ +# define DMACHAN_INTF_SPI0TX 5 /* SPI1 Transmit */ +# define DMACHAN_INTF_SPI0RX 6 /* SPI1 Receive */ +# define DMACHAN_INTF_USART0TX 11 /* USART0 Transmit */ +# define DMACHAN_INTF_USART0RX 12 /* USART0 Receive */ +# define DMACHAN_INTF_USART1TX 13 /* USART1 Transmit */ +# define DMACHAN_INTF_USART1RX 14 /* USART1 Receive */ +# define DMACHAN_INTF_PWM0TX 15 /* PWM0 Transmit */ + +#elif defined(CONFIG_ARCH_CHIP_SAM4E) + +# define DMACHAN_INTF_HSMCI0 0 /* HSMCI Transmit/Receive */ +# define DMACHAN_INTF_SPI0TX 1 /* SPI Transmit */ +# define DMACHAN_INTF_SPI0RX 2 /* SPI Receive */ +# define DMACHAN_INTF_USART0TX 3 /* USART0 Transmit */ +# define DMACHAN_INTF_USART0RX 4 /* USART0 Receive */ +# define DMACHAN_INTF_USART1TX 5 /* USART1 Transmit */ +# define DMACHAN_INTF_USART1RX 6 /* USART1 Receive */ +# define DMACHAN_INTF_AESTX 11 /* AES Transmit */ +# define DMACHAN_INTF_AESRX 12 /* AES Receive */ +# define DMACHAN_INTF_PWM0TX 13 /* PWM0 Transmit */ + +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/* DMA multi buffer transfer link list entry structure */ + +struct dma_linklist_s +{ + uint32_t src; /* Source address */ + uint32_t dest; /* Destination address */ + uint32_t ctrla; /* Control A value */ + uint32_t ctrlb; /* Control B value */ + uint32_t next; /* Next descriptor address */ +}; + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_DMAC_H */ diff --git a/arch/arm/src/sam34/chip/sam_eefc.h b/arch/arm/src/sam34/chip/sam_eefc.h new file mode 100644 index 0000000000000000000000000000000000000000..e247465f1c1426b7fc5c04b414f941add53af9cf --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_eefc.h @@ -0,0 +1,167 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_eefc.h + * Enhanced Embedded Flash Controller (EEFC) definitions for the SAM3U, SAM3X, SAM3A, + * SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_EEFC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_EEFC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* EEFC register offsets ****************************************************************/ + +#define SAM_EEFC_FMR_OFFSET 0x00 /* EEFC Flash Mode Register */ +#define SAM_EEFC_FCR_OFFSET 0x04 /* EEFC Flash Command Register */ +#define SAM_EEFC_FSR_OFFSET 0x08 /* EEFC Flash Status Register */ +#define SAM_EEFC_FRR_OFFSET 0x0c /* EEFC Flash Result Register */ + +/* EEFC register addresses **************************************************************/ + +#define SAM_EEFC_FMR(n) (SAM_EEFCN_BASE(n)+SAM_EEFC_FMR_OFFSET) +#define SAM_EEFC_FCR(n) (SAM_EEFCN_BASE(n)+SAM_EEFC_FCR_OFFSET) +#define SAM_EEFC_FSR(n) (SAM_EEFCN_BASE(n)+SAM_EEFC_FSR_OFFSET) +#define SAM_EEFC_FRR(n) (SAM_EEFCN_BASE(n)+SAM_EEFC_FRR_OFFSET) + +#define SAM_EEFC0_FMR (SAM_EEFC0_BASE+SAM_EEFC_FMR_OFFSET) +#define SAM_EEFC0_FCR (SAM_EEFC0_BASE+SAM_EEFC_FCR_OFFSET) +#define SAM_EEFC0_FSR (SAM_EEFC0_BASE+SAM_EEFC_FSR_OFFSET) +#define SAM_EEFC0_FRR (SAM_EEFC0_BASE+SAM_EEFC_FRR_OFFSET) + +#if !defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_EEFC1_FMR (SAM_EEFC1_BASE+SAM_EEFC_FMR_OFFSET) +# define SAM_EEFC1_FCR (SAM_EEFC1_BASE+SAM_EEFC_FCR_OFFSET) +# define SAM_EEFC1_FSR (SAM_EEFC1_BASE+SAM_EEFC_FSR_OFFSET) +# define SAM_EEFC1_FRR (SAM_EEFC1_BASE+SAM_EEFC_FRR_OFFSET) +#endif + +/* EEFC register bit definitions ********************************************************/ +/* EEFC Flash Mode Register */ + +#define EEFC_FMR_FRDY (1 << 0) /* Bit 0: Ready Interrupt Enable */ +#define EEFC_FMR_FWS_SHIFT (8) /* Bits 8-11: Flash Wait State */ +#define EEFC_FMR_FWS_MASK (15 << EEFC_FMR_FWS_SHIFT) +# define EEFC_FMR_FWS(n) ((n) << EEFC_FMR_FWS_SHIFT) + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FMR_SCOD (1 << 16) /* Bit 16: Sequential Code Optimization Disable */ +#endif + +#define EEFC_FMR_FAM (1 << 24) /* Bit 24: Flash Access Mode */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FMR_CLOE (1 << 26) /* Bit 26: Code Loops Optimization Enable */ +#endif + +/* EEFC Flash Command Register */ + +#define EEFC_FCR_FCMD_SHIFT (0) /* Bits 0-7: Flash Command */ +#define EEFC_FCR_FCMD_MASK (0xff << EEFC_FCR_FCMD_SHIFT) + +# define EEFC_FCR_FCMD_GETD (0 << EEFC_FCR_FCMD_SHIFT) /* Get Flash Descriptor */ +# define EEFC_FCR_FCMD_WP (1 << EEFC_FCR_FCMD_SHIFT) /* Write page */ +# define EEFC_FCR_FCMD_WPL (2 << EEFC_FCR_FCMD_SHIFT) /* Write page and lock */ +# define EEFC_FCR_FCMD_EWP (3 << EEFC_FCR_FCMD_SHIFT) /* Erase page and write page */ +# define EEFC_FCR_FCMD_EWPL (4 << EEFC_FCR_FCMD_SHIFT) /* Erase page and write page then lock */ +# define EEFC_FCR_FCMD_EA (5 << EEFC_FCR_FCMD_SHIFT) /* Erase all */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FCR_FCMD_EPA (7 << EEFC_FCR_FCMD_SHIFT) /* Erase Pages */ +#endif + +# define EEFC_FCR_FCMD_SLB (8 << EEFC_FCR_FCMD_SHIFT) /* Set Lock Bit */ +# define EEFC_FCR_FCMD_CLB (9 << EEFC_FCR_FCMD_SHIFT) /* Clear Lock Bit */ +# define EEFC_FCR_FCMD_GLB (10 << EEFC_FCR_FCMD_SHIFT) /* Get Lock Bit */ +# define EEFC_FCR_FCMD_SGPB (11 << EEFC_FCR_FCMD_SHIFT) /* Set GPNVM Bit */ +# define EEFC_FCR_FCMD_CGPB (12 << EEFC_FCR_FCMD_SHIFT) /* Clear GPNVM Bit */ +# define EEFC_FCR_FCMD_GGPB (13 << EEFC_FCR_FCMD_SHIFT) /* Get GPNVM Bit */ +# define EEFC_FCR_FCMD_STUI (14 << EEFC_FCR_FCMD_SHIFT) /* Start Read Unique Identifier */ +# define EEFC_FCR_FCMD_SPUI (15 << EEFC_FCR_FCMD_SHIFT) /* Stop Read Unique Identifier */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FCR_FCMD_GCALB (16 << EEFC_FCR_FCMD_SHIFT) /* Get CALIB Bit */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FCR_FCMD_ES (17 << EEFC_FCR_FCMD_SHIFT) /* Erase Sector */ +# define EEFC_FCR_FCMD_WUS (18 << EEFC_FCR_FCMD_SHIFT) /* Write User Signature */ +# define EEFC_FCR_FCMD_EUS (19 << EEFC_FCR_FCMD_SHIFT) /* Erase User Signature */ +# define EEFC_FCR_FCMD_STUS (20 << EEFC_FCR_FCMD_SHIFT) /* Start Read User Signature */ +# define EEFC_FCR_FCMD_SPUS (21 << EEFC_FCR_FCMD_SHIFT) /* Stop Read User Signature */ +#endif + +#define EEFC_FCR_FARG_SHIFT (8) /* Bits 8-23: Flash Command Argument */ +#define EEFC_FCR_FARG_MASK (0xffff << EEFC_FCR_FARG_SHIFT) +# define EEFC_FCR_FARG(n) ((uint32_t)(n) << EEFC_FCR_FARG_SHIFT) +#define EEFC_FCR_FKEY_SHIFT (24) /* Bits 24-31: Flash Writing Protection Key */ +#define EEFC_FCR_FKEY_MASK (0xff << EEFC_FCR_FKEY_SHIFT) +# define EEFC_FCR_FKEY_PASSWD (0x5a << EEFC_FCR_FKEY_SHIFT) + +/* EEFC Flash Status Register */ + +#define EEFC_FSR_FRDY (1 << 0) /* Bit 0: Flash Ready Status */ +#define EEFC_FSR_FCMDE (1 << 1) /* Bit 1: Flash Command Error Status */ +#define EEFC_FSR_FLOCKE (1 << 2) /* Bit 2: Flash Lock Error Status */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define EEFC_FSR_FLERR (1 << 3) /* Bit 3: Flash Error Status */ +#endif + +/* EEFC Flash Result Register -- 32-bit value */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_EEFC_H */ diff --git a/arch/arm/src/sam34/chip/sam_emac.h b/arch/arm/src/sam34/chip/sam_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..d5e8bf037e909dc7a51e8cbc9ab87b1d731f07ea --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_emac.h @@ -0,0 +1,671 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam_emac.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_EMAC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_EMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* EMAC Register Offsets ************************************************************/ + +#define SAM_EMAC_NCR_OFFSET 0x0000 /* Network Control Register */ +#define SAM_EMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */ +#define SAM_EMAC_NSR_OFFSET 0x0008 /* Network Status Register */ +#define SAM_EMAC_UR_OFFSET 0x000c /* User Register */ +#define SAM_EMAC_DCFGR_OFFSET 0x0010 /* DMA Configuration Register */ +#define SAM_EMAC_TSR_OFFSET 0x0014 /* Transmit Status Register */ +#define SAM_EMAC_RBQB_OFFSET 0x0018 /* Receive Buffer Queue Base Address */ +#define SAM_EMAC_TBQB_OFFSET 0x001c /* Transmit Buffer Queue Base Address */ +#define SAM_EMAC_RSR_OFFSET 0x0020 /* Receive Status Register */ +#define SAM_EMAC_ISR_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_EMAC_IER_OFFSET 0x0028 /* Interrupt Enable Register */ +#define SAM_EMAC_IDR_OFFSET 0x002c /* Interrupt Disable Register */ +#define SAM_EMAC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_EMAC_MAN_OFFSET 0x0034 /* PHY Maintenance Register */ +#define SAM_EMAC_RPQ_OFFSET 0x0038 /* Received Pause Quantum Register */ +#define SAM_EMAC_TPQ_OFFSET 0x003c /* Transmit Pause Quantum Register */ + /* 0x0040-0x007c: Reserved */ +#define SAM_EMAC_HRB_OFFSET 0x0080 /* Hash Register Bottom [31:0] Register */ +#define SAM_EMAC_HRT_OFFSET 0x0084 /* Hash Register Top [63:32] Register */ +#define SAM_EMAC_SAB1_OFFSET 0x0088 /* Specific Address 1 Bottom Register */ +#define SAM_EMAC_SAT1_OFFSET 0x008c /* Specific Address 1 Top Register */ +#define SAM_EMAC_SAB2_OFFSET 0x0090 /* Specific Address 2 Bottom Register */ +#define SAM_EMAC_SAT2_OFFSET 0x0094 /* Specific Address 2 Top Register */ +#define SAM_EMAC_SAB3_OFFSET 0x0098 /* Specific Address 3 Bottom Register */ +#define SAM_EMAC_SAT3_OFFSET 0x009c /* Specific Address 3 Top Register */ +#define SAM_EMAC_SAB4_OFFSET 0x00a0 /* Specific Address 4 Bottom Register */ +#define SAM_EMAC_SAT4_OFFSET 0x00a4 /* Specific Address 4 Top Register */ +#define SAM_EMAC_TIDM1_OFFSET 0x00a8 /* Type ID Match 1 Register */ +#define SAM_EMAC_TIDM2_OFFSET 0x00ac /* Type ID Match 2 Register */ +#define SAM_EMAC_TIDM3_OFFSET 0x00b0 /* Type ID Match 3 Register */ +#define SAM_EMAC_TIDM4_OFFSET 0x00b4 /* Type ID Match 4 Register */ + +#define SAM_EMAC_IPGS_OFFSET 0x00bc /* IPG Stretch Register */ +#define SAM_EMAC_SVLAN_OFFSET 0x00c0 /* Stacked VLAN Register */ +#define SAM_EMAC_TPFCP_OFFSET 0x00c4 /* Transmit PFC Pause Register */ +#define SAM_EMAC_SAMB1_OFFSET 0x00c8 /* Specific Address 1 Mask Bottom [31:0] Register */ +#define SAM_EMAC_SAMT1_OFFSET 0x00cc /* Specific Address 1 Mask Top [47:32] Register */ + /* 0x00fc: Reserved */ +/* Statistics registers */ + +#define SAM_EMAC_OTLO_OFFSET 0x0100 /* Octets Transmitted [31:0] Register */ +#define SAM_EMAC_OTHI_OFFSET 0x0104 /* Octets Transmitted [47:32] Register */ +#define SAM_EMAC_FT_OFFSET 0x0108 /* Frames Transmitted Register */ +#define SAM_EMAC_BCFT_OFFSET 0x010c /* Broadcast Frames Transmitted Register */ +#define SAM_EMAC_MFT_OFFSET 0x0110 /* Multicast Frames Transmitted Register */ +#define SAM_EMAC_PFT_OFFSET 0x0114 /* Pause Frames Transmitted Register */ +#define SAM_EMAC_BFT64_OFFSET 0x0118 /* 64 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT127_OFFSET 0x011c /* 65 to 127 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT255_OFFSET 0x0120 /* 128 to 255 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT511_OFFSET 0x0124 /* 256 to 511 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1023_OFFSET 0x0128 /* 512 to 1023 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1518_OFFSET 0x012c /* 1024 to 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_GTBFT1518_OFFSET 0x0130 /* Greater Than 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_TUR_OFFSET 0x0134 /* Transmit Under Runs Register */ +#define SAM_EMAC_SCF_OFFSET 0x0138 /* Single Collision Frames Register */ +#define SAM_EMAC_MCF_OFFSET 0x013c /* Multiple Collision Frames Register */ +#define SAM_EMAC_EC_OFFSET 0x0140 /* Excessive Collisions Register */ +#define SAM_EMAC_LC_OFFSET 0x0144 /* Late Collisions Register */ +#define SAM_EMAC_DTF_OFFSET 0x0148 /* Deferred Transmission Frames Register */ +#define SAM_EMAC_CSE_OFFSET 0x014c /* Carrier Sense Errors Register */ +#define SAM_EMAC_ORLO_OFFSET 0x0150 /* Octets Received [31:0] Received */ +#define SAM_EMAC_ORHI_OFFSET 0x0154 /* Octets Received [47:32] Received */ +#define SAM_EMAC_FR_OFFSET 0x0158 /* Frames Received Register */ +#define SAM_EMAC_BCFR_OFFSET 0x015C /* Broadcast Frames Received Register */ +#define SAM_EMAC_MFR_OFFSET 0x0160 /* Multicast Frames Received Register */ +#define SAM_EMAC_PFR_OFFSET 0x0164 /* Pause Frames Received Register */ +#define SAM_EMAC_BFR64_OFFSET 0x0168 /* 64 Byte Frames Received Register */ +#define SAM_EMAC_TBFR127_OFFSET 0x016c /* 65 to 127 Byte Frames Received Register */ +#define SAM_EMAC_TBFR255_OFFSET 0x0170 /* 128 to 255 Byte Frames Received Register */ +#define SAM_EMAC_TBFR511_OFFSET 0x0174 /* 256 to 511Byte Frames Received Register */ +#define SAM_EMAC_TBFR1023_OFFSET 0x0178 /* 512 to 1023 Byte Frames Received Register */ +#define SAM_EMAC_TBFR1518_OFFSET 0x017c /* 1024 to 1518 Byte Frames Received Register */ +#define SAM_EMAC_TMXBFR_OFFSET 0x0180 /* 1519 to Maximum Byte Frames Received Register */ +#define SAM_EMAC_UFR_OFFSET 0x0184 /* Undersize Frames Received Register */ +#define SAM_EMAC_OFR_OFFSET 0x0188 /* Oversize Frames Received Register */ +#define SAM_EMAC_JR_OFFSET 0x018c /* Jabbers Received Register */ +#define SAM_EMAC_FCSE_OFFSET 0x0190 /* Frame Check Sequence Errors Register */ +#define SAM_EMAC_LFFE_OFFSET 0x0194 /* Length Field Frame Errors Register */ +#define SAM_EMAC_RSE_OFFSET 0x0198 /* Receive Symbol Errors Register */ +#define SAM_EMAC_AE_OFFSET 0x019c /* Alignment Errors Register */ +#define SAM_EMAC_RRE_OFFSET 0x01a0 /* Receive Resource Errors Register */ +#define SAM_EMAC_ROE_OFFSET 0x01a4 /* Receive Overrun Register */ +#define SAM_EMAC_IHCE_OFFSET 0x01a8 /* IP Header Checksum Errors Register */ +#define SAM_EMAC_TCE_OFFSET 0x01ac /* TCP Checksum Errors Register */ +#define SAM_EMAC_UCE_OFFSET 0x01b0 /* UDP Checksum Errors Register */ + +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC_TSSS_OFFSET 0x01c8 /* 1588 Timer Sync Strobe Seconds Register */ +#define SAM_EMAC_TSSN_OFFSET 0x01cc /* 1588 Timer Sync Strobe Nanoseconds Register */ +#define SAM_EMAC_TS_OFFSET 0x01d0 /* 1588 Timer Seconds Register */ +#define SAM_EMAC_TN_OFFSET 0x01d4 /* 1588 Timer Nanoseconds Register */ +#define SAM_EMAC_TA_OFFSET 0x01d8 /* 1588 Timer Adjust Register */ +#define SAM_EMAC_TI_OFFSET 0x01dc /* 1588 Timer Increment Register */ +#define SAM_EMAC_EFTS_OFFSET 0x01e0 /* PTP Event Frame Transmitted Seconds */ +#define SAM_EMAC_EFTN_OFFSET 0x01e4 /* PTP Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_EFRS_OFFSET 0x01e8 /* PTP Event Frame Received Seconds */ +#define SAM_EMAC_EFRN_OFFSET 0x01ec /* PTP Event Frame Received Nanoseconds */ +#define SAM_EMAC_PEFTS_OFFSET 0x01f0 /* PTP Peer Event Frame Transmitted Seconds */ +#define SAM_EMAC_PEFTN_OFFSET 0x01f4 /* PTP Peer Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_PEFRS_OFFSET 0x01f8 /* PTP Peer Event Frame Received Seconds */ +#define SAM_EMAC_PEFRN_OFFSET 0x01fc /* PTP Peer Event Frame Received Nanoseconds */ + /* 0x0280-0x0298: Reserved */ + +/* EMAC Register Addresses **********************************************************/ + +#define SAM_EMAC_NCR (SAM_EMAC_BASE+SAM_EMAC_NCR_OFFSET) +#define SAM_EMAC_NCFGR (SAM_EMAC_BASE+SAM_EMAC_NCFGR_OFFSET) +#define SAM_EMAC_NSR (SAM_EMAC_BASE+SAM_EMAC_NSR_OFFSET) +#define SAM_EMAC_TSR (SAM_EMAC_BASE+SAM_EMAC_TSR_OFFSET) +#define SAM_EMAC_UR (SAM_EMAC_BASE+SAM_EMAC_UR_OFFSET) +#define SAM_EMAC_DCFGR (SAM_EMAC_BASE+SAM_EMAC_DCFGR_OFFSET) +#define SAM_EMAC_RBQB (SAM_EMAC_BASE+SAM_EMAC_RBQB_OFFSET) +#define SAM_EMAC_TBQB (SAM_EMAC_BASE+SAM_EMAC_TBQB_OFFSET) +#define SAM_EMAC_RSR (SAM_EMAC_BASE+SAM_EMAC_RSR_OFFSET) +#define SAM_EMAC_ISR (SAM_EMAC_BASE+SAM_EMAC_ISR_OFFSET) +#define SAM_EMAC_IER (SAM_EMAC_BASE+SAM_EMAC_IER_OFFSET) +#define SAM_EMAC_IDR (SAM_EMAC_BASE+SAM_EMAC_IDR_OFFSET) +#define SAM_EMAC_IMR (SAM_EMAC_BASE+SAM_EMAC_IMR_OFFSET) +#define SAM_EMAC_MAN (SAM_EMAC_BASE+SAM_EMAC_MAN_OFFSET) +#define SAM_EMAC_RPQ (SAM_EMAC_BASE+SAM_EMAC_RPQ_OFFSET) +#define SAM_EMAC_TPQ (SAM_EMAC_BASE+SAM_EMAC_TPQ_OFFSET) +#define SAM_EMAC_HRB (SAM_EMAC_BASE+SAM_EMAC_HRB_OFFSET) +#define SAM_EMAC_HRT (SAM_EMAC_BASE+SAM_EMAC_HRT_OFFSET) +#define SAM_EMAC_SAB1 (SAM_EMAC_BASE+SAM_EMAC_SAB1_OFFSET) +#define SAM_EMAC_SAT1 (SAM_EMAC_BASE+SAM_EMAC_SAT1_OFFSET) +#define SAM_EMAC_SAB2 (SAM_EMAC_BASE+SAM_EMAC_SAB2_OFFSET) +#define SAM_EMAC_SAT2 (SAM_EMAC_BASE+SAM_EMAC_SAT2_OFFSET) +#define SAM_EMAC_SAB3 (SAM_EMAC_BASE+SAM_EMAC_SAB3_OFFSET) +#define SAM_EMAC_SAT3 (SAM_EMAC_BASE+SAM_EMAC_SAT3_OFFSET) +#define SAM_EMAC_SAB4 (SAM_EMAC_BASE+SAM_EMAC_SAB4_OFFSET) +#define SAM_EMAC_SAT4 (SAM_EMAC_BASE+SAM_EMAC_SAT4_OFFSET) +#define SAM_EMAC_TIDM1 (SAM_EMAC_BASE+SAM_EMAC_TIDM1_OFFSET) +#define SAM_EMAC_TIDM2 (SAM_EMAC_BASE+SAM_EMAC_TIDM2_OFFSET) +#define SAM_EMAC_TIDM3 (SAM_EMAC_BASE+SAM_EMAC_TIDM3_OFFSET) +#define SAM_EMAC_TIDM4 (SAM_EMAC_BASE+SAM_EMAC_TIDM4_OFFSET) +#define SAM_EMAC_IPGS (SAM_EMAC_BASE+SAM_EMAC_IPGS_OFFSET) +#define SAM_EMAC_SVLAN (SAM_EMAC_BASE+SAM_EMAC_SVLAN_OFFSET) +#define SAM_EMAC_TPFCP (SAM_EMAC_BASE+SAM_EMAC_TPFCP_OFFSET) +#define SAM_EMAC_SAMB1 (SAM_EMAC_BASE+SAM_EMAC_SAMB1_OFFSET) +#define SAM_EMAC_SAMT1 (SAM_EMAC_BASE+SAM_EMAC_SAMT1_OFFSET) + +/* Statistics registers */ + +#define SAM_EMAC_OTLO (SAM_EMAC_BASE+SAM_EMAC_OTLO_OFFSET) +#define SAM_EMAC_OTHI (SAM_EMAC_BASE+SAM_EMAC_OTHI_OFFSET) +#define SAM_EMAC_FT (SAM_EMAC_BASE+SAM_EMAC_FT_OFFSET) +#define SAM_EMAC_BCFT (SAM_EMAC_BASE+SAM_EMAC_BCFT_OFFSET) +#define SAM_EMAC_MFT (SAM_EMAC_BASE+SAM_EMAC_MFT_OFFSET) +#define SAM_EMAC_PFT (SAM_EMAC_BASE+SAM_EMAC_PFT_OFFSET) +#define SAM_EMAC_BFT64 (SAM_EMAC_BASE+SAM_EMAC_BFT64_OFFSET) +#define SAM_EMAC_TBFT127 (SAM_EMAC_BASE+SAM_EMAC_TBFT127_OFFSET) +#define SAM_EMAC_TBFT255 (SAM_EMAC_BASE+SAM_EMAC_TBFT255_OFFSET) +#define SAM_EMAC_TBFT511 (SAM_EMAC_BASE+SAM_EMAC_TBFT511_OFFSET) +#define SAM_EMAC_TBFT1023 (SAM_EMAC_BASE+SAM_EMAC_TBFT1023_OFFSET) +#define SAM_EMAC_TBFT1518 (SAM_EMAC_BASE+SAM_EMAC_TBFT1518_OFFSET) +#define SAM_EMAC_GTBFT1518 (SAM_EMAC_BASE+SAM_EMAC_GTBFT1518_OFFSET) +#define SAM_EMAC_TUR (SAM_EMAC_BASE+SAM_EMAC_TUR_OFFSET) +#define SAM_EMAC_SCF (SAM_EMAC_BASE+SAM_EMAC_SCF_OFFSET) +#define SAM_EMAC_MCF (SAM_EMAC_BASE+SAM_EMAC_MCF_OFFSET) +#define SAM_EMAC_EC (SAM_EMAC_BASE+SAM_EMAC_EC_OFFSET) +#define SAM_EMAC_LC (SAM_EMAC_BASE+SAM_EMAC_LC_OFFSET) +#define SAM_EMAC_DTF (SAM_EMAC_BASE+SAM_EMAC_DTF_OFFSET) +#define SAM_EMAC_CSE (SAM_EMAC_BASE+SAM_EMAC_CSE_OFFSET) +#define SAM_EMAC_ORLO (SAM_EMAC_BASE+SAM_EMAC_ORLO_OFFSET) +#define SAM_EMAC_ORHI (SAM_EMAC_BASE+SAM_EMAC_ORHI_OFFSET) +#define SAM_EMAC_FR (SAM_EMAC_BASE+SAM_EMAC_FR_OFFSET) +#define SAM_EMAC_BCFR (SAM_EMAC_BASE+SAM_EMAC_BCFR_OFFSET) +#define SAM_EMAC_MFR (SAM_EMAC_BASE+SAM_EMAC_MFR_OFFSET) +#define SAM_EMAC_PFR (SAM_EMAC_BASE+SAM_EMAC_PFR_OFFSET) +#define SAM_EMAC_BFR64 (SAM_EMAC_BASE+SAM_EMAC_BFR64_OFFSET) +#define SAM_EMAC_TBFR127 (SAM_EMAC_BASE+SAM_EMAC_TBFR127_OFFSET) +#define SAM_EMAC_TBFR255 (SAM_EMAC_BASE+SAM_EMAC_TBFR255_OFFSET) +#define SAM_EMAC_TBFR511 (SAM_EMAC_BASE+SAM_EMAC_TBFR511_OFFSET) +#define SAM_EMAC_TBFR1023 (SAM_EMAC_BASE+SAM_EMAC_TBFR1023_OFFSET) +#define SAM_EMAC_TBFR1518 (SAM_EMAC_BASE+SAM_EMAC_TBFR1518_OFFSET) +#define SAM_EMAC_TMXBFR (SAM_EMAC_BASE+SAM_EMAC_TMXBFR_OFFSET) +#define SAM_EMAC_UFR (SAM_EMAC_BASE+SAM_EMAC_UFR_OFFSET) +#define SAM_EMAC_OFR (SAM_EMAC_BASE+SAM_EMAC_OFR_OFFSET) +#define SAM_EMAC_JR (SAM_EMAC_BASE+SAM_EMAC_JR_OFFSET) +#define SAM_EMAC_FCSE (SAM_EMAC_BASE+SAM_EMAC_FCSE_OFFSET) +#define SAM_EMAC_LFFE (SAM_EMAC_BASE+SAM_EMAC_LFFE_OFFSET) +#define SAM_EMAC_RSE (SAM_EMAC_BASE+SAM_EMAC_RSE_OFFSET) +#define SAM_EMAC_AE (SAM_EMAC_BASE+SAM_EMAC_AE_OFFSET) +#define SAM_EMAC_RRE (SAM_EMAC_BASE+SAM_EMAC_RRE_OFFSET) +#define SAM_EMAC_ROE (SAM_EMAC_BASE+SAM_EMAC_ROE_OFFSET) +#define SAM_EMAC_IHCE (SAM_EMAC_BASE+SAM_EMAC_IHCE_OFFSET) +#define SAM_EMAC_TCE (SAM_EMAC_BASE+SAM_EMAC_TCE_OFFSET) +#define SAM_EMAC_UCE (SAM_EMAC_BASE+SAM_EMAC_UCE_OFFSET) + +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC_TSSS (SAM_EMAC_BASE+SAM_EMAC_TSSS_OFFSET) +#define SAM_EMAC_TSSN (SAM_EMAC_BASE+SAM_EMAC_TSSN_OFFSET) +#define SAM_EMAC_TS (SAM_EMAC_BASE+SAM_EMAC_TS_OFFSET) +#define SAM_EMAC_TN (SAM_EMAC_BASE+SAM_EMAC_TN_OFFSET) +#define SAM_EMAC_TA (SAM_EMAC_BASE+SAM_EMAC_TA_OFFSET) +#define SAM_EMAC_TI (SAM_EMAC_BASE+SAM_EMAC_TI_OFFSET) +#define SAM_EMAC_EFTS (SAM_EMAC_BASE+SAM_EMAC_EFTS_OFFSET) +#define SAM_EMAC_EFTN (SAM_EMAC_BASE+SAM_EMAC_EFTN_OFFSET) +#define SAM_EMAC_EFRS (SAM_EMAC_BASE+SAM_EMAC_EFRS_OFFSET) +#define SAM_EMAC_EFRN (SAM_EMAC_BASE+SAM_EMAC_EFRN_OFFSET) +#define SAM_EMAC_PEFTS (SAM_EMAC_BASE+SAM_EMAC_PEFTS_OFFSET) +#define SAM_EMAC_PEFTN (SAM_EMAC_BASE+SAM_EMAC_PEFTN_OFFSET) +#define SAM_EMAC_PEFRS (SAM_EMAC_BASE+SAM_EMAC_PEFRS_OFFSET) +#define SAM_EMAC_PEFRN (SAM_EMAC_BASE+SAM_EMAC_PEFRN_OFFSET) + +/* EMAC Register Bit Definitions ****************************************************/ + +/* Network Control Register */ + +#define EMAC_NCR_LBL (1 << 1) /* Bit 1: Loopback local */ +#define EMAC_NCR_RXEN (1 << 2) /* Bit 2: Receive enable */ +#define EMAC_NCR_TXEN (1 << 3) /* Bit 3: Transmit enable */ +#define EMAC_NCR_MPE (1 << 4) /* Bit 4: Management port enable */ +#define EMAC_NCR_CLRSTAT (1 << 5) /* Bit 5: Clear statistics registers */ +#define EMAC_NCR_INCSTAT (1 << 6) /* Bit 6: Increment statistics registers */ +#define EMAC_NCR_WESTAT (1 << 7) /* Bit 7: Write enable for statistics registers */ +#define EMAC_NCR_BP (1 << 8) /* Bit 8: Back pressure */ +#define EMAC_NCR_TSTART (1 << 9) /* Bit 9: Start transmission */ +#define EMAC_NCR_THALT (1 << 10) /* Bit 10: Transmit halt */ +#define EMAC_TXPF (1 << 11) /* Bit 11: Transmit Pause Frame */ +#define EMAC_TXZQPF (1 << 12) /* Bit 12: Transmit Zero Quantum Pause Frame */ +#define EMAC_RDS (1 << 14) /* Bit 14: Read Snapshot */ +#define EMAC_SRTSM (1 << 15) /* Bit 15: Store Receive Time Stamp to Memory */ +#define EMAC_ENPBPR (1 << 16) /* Bit 16: Enable PFC Priority-based Pause Reception */ +#define EMAC_TXPBPF (1 << 17) /* Bit 17: Transmit PFC Priority-based Pause Frame */ +#define EMAC_FNP (1 << 18) /* Bit 18: Flush Next Packet */ + +/* Network Configuration Register */ + +#define EMAC_NCFGR_SPD (1 << 0) /* Bit 0: Speed */ +#define EMAC_NCFGR_FD (1 << 1) /* Bit 1: Full Duplex */ +#define EMAC_NCFGR_DNVLAN (1 << 2) /* Bit 2: Discard Non-VLAN FRAMES */ +#define EMAC_NCFGR_JFRAME (1 << 3) /* Bit 3: Jumbo Frames */ +#define EMAC_NCFGR_CAF (1 << 4) /* Bit 4: Copy All Frames */ +#define EMAC_NCFGR_NBC (1 << 5) /* Bit 5: No Broadcast */ +#define EMAC_NCFGR_MTIHEN (1 << 6) /* Bit 6: Multicast Hash Enable */ +#define EMAC_NCFGR_UNIHEN (1 << 7) /* Bit 7: Unicast Hash Enable */ +#define EMAC_NCFGR_MAXFS (1 << 8) /* Bit 8: 1536 Maximum Frame Size */ +#define EMAC_NCFGR_RTY (1 << 12) /* Bit 12: Retry test */ +#define EMAC_NCFGR_PEN (1 << 13) /* Bit 13: Pause Enable */ +#define EMAC_NCFGR_RXBUFO_SHIFT (14) /* Bits 14-15: Receive Buffer Offset */ +#define EMAC_NCFGR_RXBUFO_MASK (3 << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO(n) ((uint32_t)(n) << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO_NONE (0 << EMAC_NCFGR_RXBUFO_SHIFT) /* No offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_1 (1 << EMAC_NCFGR_RXBUFO_SHIFT) /* One-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_2 (2 << EMAC_NCFGR_RXBUFO_SHIFT) /* Two-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_3 (3 << EMAC_NCFGR_RXBUFO_SHIFT) /* Three-byte offset fromRX buffer start */ +#define EMAC_NCFGR_LFERD (1 << 16) /* Bit 16: Length Field Error Frame Discard */ +#define EMAC_NCFGR_RFCS (1 << 17) /* Bit 17: Remove FCS */ +#define EMAC_NCFGR_CLK_SHIFT (18) /* Bits 18-20: MDC clock divider */ +#define EMAC_NCFGR_CLK_MASK (7 << EMAC_NCFGR_CLK_SHIFT) +# define EMAC_NCFGR_CLK_DIV8 (0 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 8 (MCK up to 20 MHz) */ +# define EMAC_NCFGR_CLK_DIV16 (1 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 16 (MCK up to 40 MHz) */ +# define EMAC_NCFGR_CLK_DIV32 (2 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */ +# define EMAC_NCFGR_CLK_DIV48 (3 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 48 (MCK up to 120 MHz) */ +# define EMAC_NCFGR_CLK_DIV64 (4 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */ +# define EMAC_NCFGR_CLK_DIV96 (5 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 96 (MCK up to 240 MHz) */ +#define EMAC_NCFGR_DBW_SHIFT (21) /* Bit 21-22: Data Bus Width */ +#define EMAC_NCFGR_DBW_MASK (3 << EMAC_NCFGR_DBW_SHIFT) +# define EMAC_NCFGR_DBW_ZERO (0 << EMAC_NCFGR_DBW_SHIFT) /* Must be zero */ +#define EMAC_NCFGR_DCPF (1 << 23) /* Bit 23: Disable Copy of Pause Frames */ +#define EMAC_NCFGR_RXCOEN (1 << 24) /* Bit 24: Receive Checksum Offload Enable */ +#define EMAC_NCFGR_EFRHD (1 << 25) /* Bit 25: Enable Frames Received in Half Duplex */ +#define EMAC_NCFGR_IRXFCS (1 << 26) /* Bit 26: Ignore RX FCS */ +#define EMAC_NCFGR_IPGSEN (1 << 28) /* Bit 28: IP Stretch Enable */ +#define EMAC_NCFGR_RXBP (1 << 29) /* Bit 29: Receive Bad Preamble */ +#define EMAC_NCFGR_IRXER (1 << 30) /* Bit 30: Ignore IPG GRXER */ + +/* Network Status Register */ + +#define EMAC_NSR_MDIO (1 << 1) /* Bit 1: Status of the MDIO input pin */ +#define EMAC_NSR_IDLE (1 << 2) /* Bit 2: PHY management logic is idle */ + +/* User Register */ + +#define EMAC_UR_MII (1 << 0) /* Bit 0: MII mode*/ + +/* DMA Configuration Register */ + +#define EMAC_DCFGR_FBLDO_SHIFT (0) /* Bits 0-4: Fixed Burst Length for DMA Data Operations */ +#define EMAC_DCFGR_FBLDO_MASK (31 << EMAC_DCFGR_FBLDO_SHIFT) +# define EMAC_DCFGR_FBLDO_SINGLE (1 << EMAC_DCFGR_FBLDO_SHIFT) /* Always use SINGLE AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR4 (4 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR4 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR8 (8 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR8 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR16 (16 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR16 AHB bursts */ +#define EMAC_DCFGR_ESMA (1 << 6) /* Bit 6: Endian Swap Mode Enable for Management Descriptor Accesses */ +#define EMAC_DCFGR_ESPA (1 << 7) /* Bit 7: Endian Swap Mode Enable for Packet Data Accesses */ +#define EMAC_DCFGR_TXCOEN (1 << 11) /* Bit 11: Transmitter Checksum Generation Offload Enable */ +#define EMAC_DCFGR_DRBS_SHIFT (16) /* Bits 16-24: DMA Receive Buffer Size */ +#define EMAC_DCFGR_DRBS_MASK (0x1ff << EMAC_DCFGR_DRBS_SHIFT) +# define EMAC_DCFGR_DRBS(n) ((uint32_t)(n) << EMAC_DCFGR_DRBS_SHIFT) + +/* Transmit Status Register */ + +#define EMAC_TSR_UBR (1 << 0) /* Bit 0: Used Bit Read */ +#define EMAC_TSR_COL (1 << 1) /* Bit 1: Collision Occurred */ +#define EMAC_TSR_RLE (1 << 2) /* Bit 2: Retry Limit exceeded */ +#define EMAC_TSR_TXGO (1 << 3) /* Bit 3: Transmit Go */ +#define EMAC_TSR_TFC (1 << 4) /* Bit 4: Transmit Frame Corruption due to AHB error */ +#define EMAC_TSR_TXCOMP (1 << 5) /* Bit 5: Transmit Complete */ +#define EMAC_TSR_UND (1 << 6) /* Bit 6: Transmit Underrun */ + +/* Receive Buffer Queue Pointer Register */ + +#define EMAC_RBQB_MASK (0xfffffffc) /* Bits 2-31: Receive buffer queue pointer address */ + +/* Transmit Buffer Queue Pointer Register */ + +#define EMAC_TBQB_MASK (0xfffffffc) /* Bits 2-31: Transmit buffer queue pointer address */ + +/* Receive Status Register */ + +#define EMAC_RSR_BNA (1 << 0) /* Bit 0: Buffer Not Available */ +#define EMAC_RSR_REC (1 << 1) /* Bit 1: Frame Received */ +#define EMAC_RSR_RXOVR (1 << 2) /* Bit 2: Receive Overrun */ +#define EMAC_RSR_HNO (1 << 3) /* Bit 3: HRESP Not OK */ + +/* Interrupt Status Register (ISR), Interrupt Enable Register (IER), Interrupt Disable Register (IDR) and Interrupt Mask Register (IMR) */ + +#define EMAC_INT_MFS (1 << 0) /* Bit 0: Management Frame Sent */ +#define EMAC_INT_RCOMP (1 << 1) /* Bit 1: Receive Complete */ +#define EMAC_INT_RXUBR (1 << 2) /* Bit 2: Receive Used Bit Read */ +#define EMAC_INT_TXUBR (1 << 3) /* Bit 3: Transmit Used Bit Read */ +#define EMAC_INT_TUR (1 << 4) /* Bit 4: Ethernet Transmit Buffer Underrun */ +#define EMAC_INT_RLEX (1 << 5) /* Bit 5: Retry Limit Exceeded */ +#define EMAC_INT_TFC (1 << 6) /* Bit 6: Transmit Frame Corruption due to AHB error */ +#define EMAC_INT_TCOMP (1 << 7) /* Bit 7: Transmit Complete */ +#define EMAC_INT_ROVR (1 << 10) /* Bit 10: Receive Overrun */ +#define EMAC_INT_HRESP (1 << 11) /* Bit 11: Hresp not OK */ +#define EMAC_INT_PFNZ (1 << 12) /* Bit 12: Pause Frame with Non-zero Pause Quantum Received */ +#define EMAC_INT_PTZ (1 << 13) /* Bit 13: Pause Time Zero */ +#define EMAC_INT_PTFR (1 << 14) /* Bit 14: Pause Frame Transmitted */ +#define EMAC_INT_EXINT (1 << 15) /* Bit 15: External Interrupt (not (SR) */ +#define EMAC_INT_DRQFR (1 << 18) /* Bit 18: PTP Delay Request Frame Received */ +#define EMAC_INT_SFR (1 << 19) /* Bit 19: PTP Sync Frame Received */ +#define EMAC_INT_DRQFT (1 << 20) /* Bit 20: PTP Delay Request Frame Transmitted */ +#define EMAC_INT_SFT (1 << 21) /* Bit 21: PTP Sync Frame Transmitted */ +#define EMAC_INT_PDRQFR (1 << 22) /* Bit 22: PDelay Request Frame Received */ +#define EMAC_INT_PDRSFR (1 << 23) /* Bit 23: PDelay Response Frame Received */ +#define EMAC_INT_PDRQFT (1 << 24) /* Bit 24: PDelay Request Frame Transmitted */ +#define EMAC_INT_PDRSFT (1 << 25) /* Bit 25: PDelay Response Frame Transmitted */ +#define EMAC_INT_SRI (1 << 26) /* Bit 26: TSU Seconds Register Increment (not IMR) */ +#define EMAC_INT_WOL (1 << 28) /* Bit 28: Wake On LAN (not IMR) */ + +#define EMAC_INT_ALL (0x17fcfcff) +#define EMAC_INT_UNUSED (0xe8030300) + +/* PHY Maintenance Register */ + +#define EMAC_MAN_DATA_SHIFT (0) /* Bits 0-15: Read/write data */ +#define EMAC_MAN_DATA_MASK (0x0000ffff << EMAC_MAN_DATA_SHIFT) +# define EMAC_MAN_DATA(n) ((uint32_t)(n) << EMAC_MAN_DATA_SHIFT) +#define EMAC_MAN_WTN_SHIFT (16) /* Bits 16-17: Must be written to b10 */ +#define EMAC_MAN_WTN_MASK (3 << EMAC_MAN_WTN_SHIFT) +# define EMAC_MAN_WTN (2 << EMAC_MAN_WTN_SHIFT) +#define EMAC_MAN_REGA_SHIFT (18) /* Bits 18-22: Register Address */ +#define EMAC_MAN_REGA_MASK (31 << EMAC_MAN_REGA_SHIFT) +# define EMAC_MAN_REGA(n) ((uint32_t)(n) << EMAC_MAN_REGA_SHIFT) +#define EMAC_MAN_PHYA_SHIFT (23) /* Bits 23-27: PHY Address */ +#define EMAC_MAN_PHYA_MASK (31 << EMAC_MAN_PHYA_SHIFT) +# define EMAC_MAN_PHYA(n) ((uint32_t)(n) << EMAC_MAN_PHYA_SHIFT) +#define EMAC_MAN_OP_SHIFT (28) /* Bits 28-29: Operation */ +#define EMAC_MAN_OP_MASK (3 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_READ (2 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_WRITE (1 << EMAC_MAN_OP_SHIFT) +#define EMAC_MAN_CLTTO (1 << 30) /* Bit 30: Clause 22 Operation */ +#define EMAC_MAN_WZO (0) /* Bit 31: Write ZERO */ + +/* Pause Time Register */ + +#define EMAC_RPQ_MASK (0x0000ffff) /* Bits 0-15: Received Pause Quantum */ + +/* Pause Frames Received Register */ + +#define EMAC_TPQ_MASK (0x0000ffff) /* Bits 0-15: Transmit Pause Quantum */ + +/* Hash Register Bottom [31:0] Register (LS 32-bit hash address) */ +/* Hash Register Top [63:32] Register (MS 32-bit hash address) */ + +/* Specific Address 1 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Top [47:32] Register */ + +#define EMAC_SAT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 2 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 2 Top [47:32] Register */ + +#define EMAC_SAT2_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 3 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 3 Top [47:32] Register */ + +#define EMAC_SAT3_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 4 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 4 Top [47:32] Register */ + +#define EMAC_SAT4_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Type ID Match Registers */ + +#define EMAC_TIDM_MASK (0x0000ffff) /* Bits 0-15: Type ID Match n */ + +/* Type ID Checking Register */ + +#define EMAC_TID_MASK (0x0000ffff) /* Bits 0-15: For comparisons with received frames TypeID/Length field */ + +/* IPG Stretch Register */ + +#define EMAC_IPGS_FL_MASK (0x0000ffff) /* Bit 0-15: Frame Length */ + +/* Stacked VLAN Register */ + +#define EMAC_SVLAN_VLANTYPE_SHIFT (0) /* Bits 0-15: User Defined VLAN_TYPE Field */ +#define EMAC_SVLAN_VLANTYPE_MASK (0x0000ffff << EMAC_SVLAN_VLANTYPE_SHIFT) +# define EMAC_SVLAN_VLANTYPE(n) ((uint32_t)(n) << EMAC_SVLAN_VLANTYPE_SHIFT) +#define EMAC_SVLAN_ESVLAN (1 << 31) /* Bit 31: Enable Stacked VLAN Processing Mode */ + +/* Transmit PFC Pause Register */ + +#define EMAC_TPFCP_PEV_SHIFT (0) /* Bits 0-7: Priority Enable Vector */ +#define EMAC_TPFCP_PEV_MASK (0xff << EMAC_TPFCP_PEV_SHIFT) +#define EMAC_TPFCP_PQ_SHIFT (8) /* Bits 8-15: Pause Quantum */ +#define EMAC_TPFCP_PQ_MASK (0xff << EMAC_TPFCP_PQ_SHIFT) + +/* Specific Address 1 Mask Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Mask Top [47:32] Register (MS 16-bit address) */ + +#define EMAC_SAMT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of Specific Address 1 Mask */ + +/* Statistics registers. Only masking is needed. + * + * Octets Transmitted [31:0] Register (OTLO) 32-bit + * Octets Transmitted [47:32] Register (OTHI) 16-bit + * Frames Transmitted Register (FT) 32-bit + * Broadcast Frames Transmitted Register (BCFT) 32-bit + * Multicast Frames Transmitted Register (MFT) 32-bit + * Pause Frames Transmitted Register (PFT) 16-bit + * 64 Byte Frames Transmitted Register (BFT64) 32-bit + * 65 to 127 Byte Frames Transmitted Register (TBFT127) 32-bit + * 128 to 255 Byte Frames Transmitted Register (TBFT255) 32-bit + * 256 to 511 Byte Frames Transmitted Register (TBFT511) 32-bit + * 512 to 1023 Byte Frames Transmitted Register (TBFT1023) 32-bit + * 1024 to 1518 Byte Frames Transmitted Register (TBFT1518) 32-bit + * Greater Than 1518 Byte Frames Transmitted Register (GTBFT1518) 32-bit + * Transmit Under Runs Register (TUR) 10-bit + * Single Collision Frames Register (SCF) 18-bit + * Multiple Collision Frames Register (MCF) 18-bit + * Excessive Collisions Register (EC) 10-bit + * Late Collisions Register (LC) 10-bit + * Deferred Transmission Frames Register (DTF) 18-bit + * Carrier Sense Errors Register (CSE) 10-bit + * Octets Received [31:0] Received (ORLO) 32-bit + * Octets Received [47:32] Received (ORHI) 16-bit + * Frames Received Register (FR) 32-bit + * Broadcast Frames Received Register (BCFR) 32-bit + * Multicast Frames Received Register (MFR) 32-bit + * Pause Frames Received Register (PFR) 32-bit + * 64 Byte Frames Received Register (BFR64) 32-bit + * 65 to 127 Byte Frames Received Register (TBFR127) 32-bit + * 128 to 255 Byte Frames Received Register (TBFR255) 32-bit + * 256 to 511Byte Frames Received Register (TBFR511) 32-bit + * 512 to 1023 Byte Frames Received Register (TBFR1023) 32-bit + * 1024 to 1518 Byte Frames Received Register (TBFR1518) 32-bit + * 1519 to Maximum Byte Frames Received Register (TMXBFR) 32-bit + * Undersize Frames Received Register (UFR) 10-bit + * Oversize Frames Received Register (OFR) 10-bit + * Jabbers Received Register (JR) 10-bit + * Frame Check Sequence Errors Register (FCSE) 10-bit + * Length Field Frame Errors Register (LFFE) 10-bit + * Receive Symbol Errors Register (RSE) 10-bit + * Alignment Errors Register (AE) 10-bit + * Receive Resource Errors Register (RRE) 18-bit + * Receive Overrun Register (ROE) 10-bit + * IP Header Checksum Errors Register (IHCE) 8-bit + * TCP Checksum Errors Register (TCE) 8-bit + * UDP Checksum Errors Register (UCE) 8-bit + */ + +/* PTP/1588 Timer Registers */ + +/* 1588 Timer Sync Strobe Seconds Register (32-bit timer value) */ +/* 1588 Timer Sync Strobe Nanoseconds Register (30-bit timer value) */ + +#define EMAC_TSSN_MASK (0x3fffffff) /* Bit 0-29: Value Timer Nanoseconds Register Capture */ + +/* 1588 Timer Seconds Register (32-bit timer value) */ +/* 1588 Timer Nanoseconds Register (30-bit timer value) */ + +#define EMAC_TN_MASK (0x3fffffff) /* Bit 0-29: Timer Count in Nanoseconds */ + +/* 1588 Timer Adjust Register */ + +#define EMAC_TA_ITDT_SHIFT (0) /* Bits 0-29: Increment/Decrement */ +#define EMAC_TA_ITDT_MASK (0x3fffffff << EMAC_TA_ITDT_SHIFT) +# define EMAC_TA_ITDT(n) ((uint32_t)(n) << EMAC_TA_ITDT_SHIFT) +#define EMAC_TA_ADJ (1 << 31) /* Bit 31: Adjust 1588 Timer */ + +/* 1588 Timer Increment Register */ + +#define EMAC_TI_CNS_SHIFT (0) /* Bits 0-7: Count Nanoseconds */ +#define EMAC_TI_CNS_MASK (0xff << EMAC_TI_CNS_SHIFT) +# define EMAC_TI_CNS(n) ((uint32_t)(n) << EMAC_TI_CNS_SHIFT) +#define EMAC_TI_ACNS_SHIFT (8) /* Bits 8-15: Alternative Count Nanoseconds */ +#define EMAC_TI_ACNS_MASK (0xff << EMAC_TI_ACNS_SHIFT) +# define EMAC_TI_ACNS(n) ((uint32_t)(n) << EMAC_TI_ACNS_SHIFT) +#define EMAC_TI_NIT_SHIFT (16) /* Bits 16-23: Number of Increments */ +#define EMAC_TI_NIT_MASK (0xff << EMAC_TI_NIT_SHIFT) +# define EMAC_TI_NIT(n) ((uint32_t)(n) << EMAC_TI_NIT_SHIFT) + +/* PTP Event Frame Transmitted Seconds (32-bit timer value) */ +/* PTP Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_EFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Event Frame Received Seconds (32-bit timer value) */ +/* PTP Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_EFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Transmitted Seconds (32-bit timer value) */ +/* PTP Peer Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Received Seconds (32-bit timer value) */ +/* PTP Peer Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* Descriptors **********************************************************************/ + +/* Receive buffer descriptor: Address word */ + +#define EMACRXD_ADDR_OWNER (1 << 0) /* Bit 0: 1=Software owns; 0=EMAC owns */ +#define EMACRXD_ADDR_WRAP (1 << 1) /* Bit 1: Last descriptor in list */ +#define EMACRXD_ADDR_MASK (0xfffffffc) /* Bits 2-31: Aligned buffer address */ + +/* Receive buffer descriptor: Control word */ + +#define EMACRXD_STA_FRLEN_SHIFT (0) /* Bits 0-12: Length of frame (not jumbo)*/ +#define EMACRXD_STA_FRLEN_MASK (0x00001fff << EMACRXD_STA_FRLEN_SHIFT) +#define EMACRXD_STA_JFRLEN_SHIFT (0) /* Bits 0-13: Length of frame (jumbo)*/ +#define EMACRXD_STA_JFRLEN_MASK (0x00003fff << EMACRXD_STA_JFRLEN_SHIFT) +#define EMACRXD_STA_BADFCS (1 << 13) /* Bit 13: Frame had bad FCS (not jumbo) */ +#define EMACRXD_STA_SOF (1 << 14) /* Bit 14: Start of frame */ +#define EMACRXD_STA_EOF (1 << 15) /* Bit 15: End of frame */ +#define EMACRXD_STA_CFI (1 << 16) /* Bit 16: Concatenation format indicator (CFI) bit */ +#define EMACRXD_STA_VLPRIO_SHIFT (17) /* Bits 17-19: VLAN priority */ +#define EMACRXD_STA_VLPRIO_MASK (7 << EMACRXD_STA_VLANPRIO_SHIFT) +#define EMACRXD_STA_PRIODET (1 << 20) /* Bit 20: Priority tag detected */ +#define EMACRXD_STA_VLANTAG (1 << 21) /* Bit 21: VLAN tag detected */ +#define EMACRXD_STA_TYPEID_SHIFT (22) /* Bit 22-23: Specific address register */ +#define EMACRXD_STA_TYPEID_MASK (3 << EMACRXD_STA_TYPEID_SHIFT) +# define EMACRXD_STA_TYPEID1 (0 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 1 match */ +# define EMACRXD_STA_TYPEID2 (1 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 2 match */ +# define EMACRXD_STA_TYPEID3 (2 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 3 match */ +# define EMACRXD_STA_TYPEID4 (3 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 4 match */ +#define EMACRXD_STA_TYPEIDMATCH (1 << 24) /* Bit 24: Type ID register match found */ +#define EMACRXD_STA_SNAP (1 << 24) /* Bit 24: Frame was SNAP encoded */ +#define EMACRXD_STA_ADDR_SHIFT (25) /* Bit 25-26: Specific address register */ +#define EMACRXD_STA_ADDR_MASK (3 << EMACRXD_STA_ADDR_SHIFT) +# define EMACRXD_STA_ADDR1 (0 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 1 match */ +# define EMACRXD_STA_ADDR2 (1 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 2 match */ +# define EMACRXD_STA_ADDR3 (2 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 3 match */ +# define EMACRXD_STA_ADDR4 (3 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 4 match */ +#define EMACRXD_STA_ADDRMATCH (1 << 27) /* Bit 27: Specific address match found */ + /* Bit 28: Reserved */ +#define EMACRXD_STA_UCAST (1 << 29) /* Bit 29: Unicast hash match */ +#define EMACRXD_STA_MCAST (1 << 30) /* Bit 30: Multicast hash match */ +#define EMACRXD_STA_BCAST (1 << 31) /* Bit 31: Global all ones broadcast address detected */ + +/* Transmit buffer descriptor: Address word (un-aligned, 32-bit address */ +/* Transmit buffer descriptor: Control word */ + +#define EMACTXD_STA_BUFLEN_SHIFT (0) /* Bits 0-13: Length of buffer */ +#define EMACTXD_STA_BUFLEN_MASK (0x00003fff << EMACTXD_STA_BUFLEN_SHIFT) + /* Bit 14: Reserved */ +#define EMACTXD_STA_LAST (1 << 15) /* Bit 15: Last buffer in the current frame */ +#define EMACTXD_STA_NOCRC (1 << 16) /* Bit 16: No CRC */ + /* Bits 17-19: Reserved */ +#define EMACTXD_STA_CHKERR_SHIFT (20) /* Bits 20-22: Transmit IP/TCP/UDP checksum generation offload errors */ +#define EMACTXD_STA_CHKERR_MASK (7 << EMACTXD_STA_CHKERR_SHIFT) +# define EMACTXD_STA_CHKERR_NONE (0 << EMACTXD_STA_CHKERR_SHIFT) /* No Error */ +# define EMACTXD_STA_CHKERR_BADVLAN (1 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous VLAN type */ +# define EMACTXD_STA_CHKERR_BADSNAP (2 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous SNAP type */ +# define EMACTXD_STA_CHKERR_NOTIP (3 << EMACTXD_STA_CHKERR_SHIFT) /* Not IP or invalid IP type */ +# define EMACTXD_STA_CHKERR_UNREC (4 << EMACTXD_STA_CHKERR_SHIFT) /* Not VLAN, SNAP, or IP */ +# define EMACTXD_STA_CHKERR_BADFRAG (5 << EMACTXD_STA_CHKERR_SHIFT) /* Unsupported fragmentation */ +# define EMACTXD_STA_CHKERR_PKTTYPE (6 << EMACTXD_STA_CHKERR_SHIFT) /* Not TCP or UDP */ +# define EMACTXD_STA_CHKERR_EPKT (7 << EMACTXD_STA_CHKERR_SHIFT) /* Premature end of packet */ + /* Bits 23-25: Reserved */ +#define EMACTXD_STA_LCOL (1 << 26) /* Bit 26: Late collision, transmit error detected */ +#define EMACTXD_STA_TFC (1 << 27) /* Bit 27: Transmit frame corruption due to AHB error */ +#define EMACTXD_STA_TXUR (1 << 28) /* Bit 28: Transmit underrun */ +#define EMACTXD_STA_TXERR (1 << 29) /* Bit 29: Retry limit exceeded, transmit error detected */ +#define EMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */ +#define EMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the EMAC to read from buffer */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Receive buffer descriptor */ + +struct emac_rxdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* RX status and controls */ +}; + +/* Transmit buffer descriptor */ + +struct emac_txdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* TX status and controls */ +}; + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_EMAC_H */ diff --git a/arch/arm/src/sam34/chip/sam_gpbr.h b/arch/arm/src/sam34/chip/sam_gpbr.h new file mode 100644 index 0000000000000000000000000000000000000000..8e20925501ff7d333590b6639de72373ac49b526 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_gpbr.h @@ -0,0 +1,122 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_gpbr.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_GPBR_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_GPBR_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* GPBR register offsets ****************************************************************/ + +#define SAM_GPBR_OFFSET(n) ((n)<<2) /* General purpose back-up registers */ +#define SAM_GPBR0_OFFSET 0x00 +#define SAM_GPBR1_OFFSET 0x04 +#define SAM_GPBR2_OFFSET 0x08 +#define SAM_GPBR3_OFFSET 0x0c +#define SAM_GPBR4_OFFSET 0x10 +#define SAM_GPBR5_OFFSET 0x14 +#define SAM_GPBR6_OFFSET 0x18 +#define SAM_GPBR7_OFFSET 0x1c + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_GPBR8_OFFSET 0x20 +# define SAM_GPBR9_OFFSET 0x24 +# define SAM_GPBR10_OFFSET 0x28 +# define SAM_GPBR11_OFFSET 0x2c +# define SAM_GPBR12_OFFSET 0x30 +# define SAM_GPBR13_OFFSET 0x34 +# define SAM_GPBR14_OFFSET 0x38 +# define SAM_GPBR15_OFFSET 0x3c +# define SAM_GPBR16_OFFSET 0x40 +# define SAM_GPBR17_OFFSET 0x44 +# define SAM_GPBR18_OFFSET 0x48 +# define SAM_GPBR19_OFFSET 0x4c +#endif + +/* GPBR register addresses **************************************************************/ + +#define SAM_GPBR(n)) (SAM_GPBR_BASE+SAM_GPBR_OFFSET(n)) +#define SAM_GPBR0 (SAM_GPBR_BASE+SAM_GPBR0_OFFSET) +#define SAM_GPBR1 (SAM_GPBR_BASE+SAM_GPBR1_OFFSET) +#define SAM_GPBR2 (SAM_GPBR_BASE+SAM_GPBR2_OFFSET) +#define SAM_GPBR3 (SAM_GPBR_BASE+SAM_GPBR3_OFFSET) +#define SAM_GPBR4 (SAM_GPBR_BASE+SAM_GPBR4_OFFSET) +#define SAM_GPBR5 (SAM_GPBR_BASE+SAM_GPBR5_OFFSET) +#define SAM_GPBR6 (SAM_GPBR_BASE+SAM_GPBR6_OFFSET) +#define SAM_GPBR7 (SAM_GPBR_BASE+SAM_GPBR7_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_GPBR8 (SAM_GPBR_BASE+SAM_GPBR8_OFFSET) +# define SAM_GPBR9 (SAM_GPBR_BASE+SAM_GPBR9_OFFSET) +# define SAM_GPBR10 (SAM_GPBR_BASE+SAM_GPBR10_OFFSET) +# define SAM_GPBR11 (SAM_GPBR_BASE+SAM_GPBR11_OFFSET) +# define SAM_GPBR12 (SAM_GPBR_BASE+SAM_GPBR12_OFFSET) +# define SAM_GPBR13 (SAM_GPBR_BASE+SAM_GPBR13_OFFSET) +# define SAM_GPBR14 (SAM_GPBR_BASE+SAM_GPBR14_OFFSET) +# define SAM_GPBR15 (SAM_GPBR_BASE+SAM_GPBR15_OFFSET) +# define SAM_GPBR16 (SAM_GPBR_BASE+SAM_GPBR16_OFFSET) +# define SAM_GPBR17 (SAM_GPBR_BASE+SAM_GPBR17_OFFSET) +# define SAM_GPBR18 (SAM_GPBR_BASE+SAM_GPBR18_OFFSET) +# define SAM_GPBR19 (SAM_GPBR_BASE+SAM_GPBR19_OFFSET) +#endif + +/* GPBR register bit definitions ********************************************************/ + +/* All 32-bit values */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_GPBR_H */ diff --git a/arch/arm/src/sam34/chip/sam_hsmci.h b/arch/arm/src/sam34/chip/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..fa3b375b7ac6abf5570804f283cbfc07106d2d0e --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_hsmci.h @@ -0,0 +1,366 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_hsmci.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_HSMCI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_pdc.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* HSMCI register offsets ***************************************************************/ + +#define SAM_HSMCI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_HSMCI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_HSMCI_DTOR_OFFSET 0x0008 /* Data Timeout Register */ +#define SAM_HSMCI_SDCR_OFFSET 0x000c /* SD/SDIO Card Register */ +#define SAM_HSMCI_ARGR_OFFSET 0x0010 /* Argument Register */ +#define SAM_HSMCI_CMDR_OFFSET 0x0014 /* Command Register */ +#define SAM_HSMCI_BLKR_OFFSET 0x0018 /* Block Register */ +#define SAM_HSMCI_CSTOR_OFFSET 0x001c /* Completion Signal Timeout Register */ +#define SAM_HSMCI_RSPR0_OFFSET 0x0020 /* Response Register 0 */ +#define SAM_HSMCI_RSPR1_OFFSET 0x0024 /* Response Register 1 */ +#define SAM_HSMCI_RSPR2_OFFSET 0x0028 /* Response Register 2 */ +#define SAM_HSMCI_RSPR3_OFFSET 0x002c /* Response Register 3 */ +#define SAM_HSMCI_RDR_OFFSET 0x0030 /* Receive Data Register */ +#define SAM_HSMCI_TDR_OFFSET 0x0034 /* Transmit Data Register */ + /* 0x0038-0x003c: Reserved */ +#define SAM_HSMCI_SR_OFFSET 0x0040 /* Status Register */ +#define SAM_HSMCI_IER_OFFSET 0x0044 /* Interrupt Enable Register */ +#define SAM_HSMCI_IDR_OFFSET 0x0048 /* Interrupt Disable Register */ +#define SAM_HSMCI_IMR_OFFSET 0x004c /* Interrupt Mask Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_HSMCI_DMA_OFFSET 0x0050 /* DMA Configuration Register */ +#endif + +#define SAM_HSMCI_CFG_OFFSET 0x0054 /* Configuration Register */ + /* 0x0058-0x00e0: Reserved */ +#define SAM_HSMCI_WPMR_OFFSET 0x00e4 /* Write Protection Mode Register */ +#define SAM_HSMCI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0x00ec-0x00fc: Reserved */ + /* 0x0100-0x0124: Reserved for PCD registers */ +#define SAM_HSMCI_FIFO_OFFSET 0x0200 /* 0x0200-0x3ffc FIFO Memory Aperture */ + +/* HSMCI register addresses *************************************************************/ + +#define SAM_HSMCI_CR (SAM_HSMCI_BASE+SAM_HSMCI_CR_OFFSET) +#define SAM_HSMCI_MR (SAM_HSMCI_BASE+SAM_HSMCI_MR_OFFSET) +#define SAM_HSMCI_DTOR (SAM_HSMCI_BASE+SAM_HSMCI_DTOR_OFFSET) +#define SAM_HSMCI_SDCR (SAM_HSMCI_BASE+SAM_HSMCI_SDCR_OFFSET) +#define SAM_HSMCI_ARGR (SAM_HSMCI_BASE+SAM_HSMCI_ARGR_OFFSET) +#define SAM_HSMCI_CMDR (SAM_HSMCI_BASE+SAM_HSMCI_CMDR_OFFSET) +#define SAM_HSMCI_BLKR (SAM_HSMCI_BASE+SAM_HSMCI_BLKR_OFFSET) +#define SAM_HSMCI_CSTOR (SAM_HSMCI_BASE+SAM_HSMCI_CSTOR_OFFSET) +#define SAM_HSMCI_RSPR0 (SAM_HSMCI_BASE+SAM_HSMCI_RSPR0_OFFSET) +#define SAM_HSMCI_RSPR1 (SAM_HSMCI_BASE+SAM_HSMCI_RSPR1_OFFSET) +#define SAM_HSMCI_RSPR2 (SAM_HSMCI_BASE+SAM_HSMCI_RSPR2_OFFSET) +#define SAM_HSMCI_RSPR3 (SAM_HSMCI_BASE+SAM_HSMCI_RSPR3_OFFSET) +#define SAM_HSMCI_RDR (SAM_HSMCI_BASE+SAM_HSMCI_RDR_OFFSET) +#define SAM_HSMCI_TDR (SAM_HSMCI_BASE+SAM_HSMCI_TDR_OFFSET) +#define SAM_HSMCI_SR (SAM_HSMCI_BASE+SAM_HSMCI_SR_OFFSET) +#define SAM_HSMCI_IER (SAM_HSMCI_BASE+SAM_HSMCI_IER_OFFSET) +#define SAM_HSMCI_IDR (SAM_HSMCI_BASE+SAM_HSMCI_IDR_OFFSET) +#define SAM_HSMCI_IMR (SAM_HSMCI_BASE+SAM_HSMCI_IMR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_HSMCI_DMA (SAM_HSMCI_BASE+SAM_HSMCI_DMA_OFFSET) +#endif + +#define SAM_HSMCI_CFG (SAM_HSMCI_BASE+SAM_HSMCI_CFG_OFFSET) +#define SAM_HSMCI_WPMR (SAM_HSMCI_BASE+SAM_HSMCI_WPMR_OFFSET) +#define SAM_HSMCI_WPSR (SAM_HSMCI_BASE+SAM_HSMCI_WPSR_OFFSET) +#define SAM_HSMCI_FIFO (SAM_HSMCI_BASE+SAM_HSMCI_FIFO_OFFSET) + +#if (defined(CONFIG_ARCH_CHIP_SAM4S) && defined(CONFIG_SAM34_PDCA)) +# define SAM_HSMCI_PDC_RPR (SAM_HSMCI_BASE+SAM_PDC_RPR_OFFSET) +# define SAM_HSMCI_PDC_RCR (SAM_HSMCI_BASE+SAM_PDC_RCR_OFFSET) +# define SAM_HSMCI_PDC_TPR (SAM_HSMCI_BASE+SAM_PDC_TPR_OFFSET) +# define SAM_HSMCI_PDC_TCR (SAM_HSMCI_BASE+SAM_PDC_TCR_OFFSET) +# define SAM_HSMCI_PDC_RNPR (SAM_HSMCI_BASE+SAM_PDC_RNPR_OFFSET) +# define SAM_HSMCI_PDC_RNCR (SAM_HSMCI_BASE+SAM_PDC_RNCR_OFFSET) +# define SAM_HSMCI_PDC_TNPR (SAM_HSMCI_BASE+SAM_PDC_TNPR_OFFSET) +# define SAM_HSMCI_PDC_TNCR (SAM_HSMCI_BASE+SAM_PDC_TNCR_OFFSET) +# define SAM_HSMCI_PDC_PTCR (SAM_HSMCI_BASE+SAM_PDC_PTCR_OFFSET) +# define SAM_HSMCI_PDC_PTSR (SAM_HSMCI_BASE+SAM_PDC_PTSR_OFFSET) +#endif + +/* HSMCI register bit definitions *******************************************************/ + +/* HSMCI Control Register */ + +#define HSMCI_CR_MCIEN (1 << 0) /* Bit 0: Multi-Media Interface Enable */ +#define HSMCI_CR_MCIDIS (1 << 1) /* Bit 1: Multi-Media Interface Disable */ +#define HSMCI_CR_PWSEN (1 << 2) /* Bit 2: Power Save Mode Enable */ +#define HSMCI_CR_PWSDIS (1 << 3) /* Bit 3: Power Save Mode Disable */ +#define HSMCI_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ + +/* HSMCI Mode Register */ + +#define HSMCI_MR_CLKDIV_SHIFT (0) /* Bits 0-7: Clock Divider */ +#define HSMCI_MR_CLKDIV_MASK (0xff << HSMCI_MR_CLKDIV_SHIFT) +# define HSMCI_MR_CLKDIV(n) ((uint32_t)(n) << HSMCI_MR_CLKDIV_SHIFT) +#define HSMCI_MR_PWSDIV_SHIFT (8) /* Bits 8-10: Power Saving Divider */ +#define HSMCI_MR_PWSDIV_MASK (7 << HSMCI_MR_PWSDIV_SHIFT) +# define HSMCI_MR_PWSDIV(n) ((uint32_t)(n) << HSMCI_MR_PWSDIV_SHIFT) +# define HSMCI_MR_PWSDIV_MAX (7 << HSMCI_MR_PWSDIV_SHIFT) +#define HSMCI_MR_RDPROOF (1 << 11) /* Bit 11: Read Proof Enable */ +#define HSMCI_MR_WRPROOF (1 << 12) /* Bit 12: Write Proof Enable */ +#define HSMCI_MR_FBYTE (1 << 13) /* Bit 13: Force Byte Transfer */ +#define HSMCI_MR_PADV (1 << 14) /* Bit 14: Padding Value */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define HSMCI_MR_PDCMODE (1 << 15) /* Bit 15: PDC-oriented Mode */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define HSMCI_MR_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */ +# define HSMCI_MR_BLKLEN_MASK (0xffff << HSMCI_MR_BLKLEN_SHIFT) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define HSMCI_MR_CLKODD (1 << 16) /* Bit 16: Clock divider is odd */ +#endif + +/* HSMCI Data Timeout Register */ + +#define HSMCI_DTOR_DTOCYC_SHIFT (0) /* Bits 0-3: Data Timeout Cycle Number */ +#define HSMCI_DTOR_DTOCYC_MASK (15 << HSMCI_DTOR_DTOCYC_SHIFT) +# define HSMCI_DTOR_DTOCYC(n) ((uint32_t)(n) << HSMCI_DTOR_DTOCYC_SHIFT) +# define HSMCI_DTOR_DTOCYC_MAX (15 << HSMCI_DTOR_DTOCYC_SHIFT) +#define HSMCI_DTOR_DTOMUL_SHIFT (4) /* Bits 4-6: Data Timeout Multiplier */ +#define HSMCI_DTOR_DTOMUL_MASK (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1 (0 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_16 (1 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_128 (2 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_256 (3 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1024 (4 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_4096 (5 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_65536 (6 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1048576 (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_MAX (7 << HSMCI_DTOR_DTOMUL_SHIFT) + +/* HSMCI SDCard/SDIO Register */ + +#define HSMCI_SDCR_SDCSEL_SHIFT (0) /* Bits 0-1: SDCard/SDIO Slot */ +#define HSMCI_SDCR_SDCSEL_MASK (3 << HSMCI_SDCR_SDCSEL_SHIFT) +# define HSMCI_SDCR_SDCSEL_SLOTA (0 << HSMCI_SDCR_SDCSEL_SHIFT) +#define HSMCI_SDCR_SDCBUS_SHIFT (6) /* Bits 6-7: SDCard/SDIO Bus Width */ +#define HSMCI_SDCR_SDCBUS_MASK (3 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_1BIT (0 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_4BIT (2 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_8BIT (3 << HSMCI_SDCR_SDCBUS_SHIFT) + +/* HSMCI Argument Register (32-bit value) */ + +/* HSMCI Command Register */ + +#define HSMCI_CMDR_CMDNB_SHIFT (0) /* Bits 0-5: Command Number */ +#define HSMCI_CMDR_CMDNB_MASK (63 << HSMCI_CMDR_CMDNB_SHIFT) +# define HSMCI_CMDR_CMDNB(n) ((uint32_t)(n) << HSMCI_CMDR_CMDNB_SHIFT) +#define HSMCI_CMDR_RSPTYP_SHIFT (6) /* Bits 6-7: Response Type */ +#define HSMCI_CMDR_RSPTYP_MASK (3 << HSMCI_CMDR_RSPTYP_SHIFT) +# define HSMCI_CMDR_RSPTYP_NONE (0 << HSMCI_CMDR_RSPTYP_SHIFT) /* No response */ +# define HSMCI_CMDR_RSPTYP_48BIT (1 << HSMCI_CMDR_RSPTYP_SHIFT) /* 48-bit response */ +# define HSMCI_CMDR_RSPTYP_136BIT (2 << HSMCI_CMDR_RSPTYP_SHIFT) /* 136-bit response */ +# define HSMCI_CMDR_RSPTYP_R1B (3 << HSMCI_CMDR_RSPTYP_SHIFT) /* R1b response type */ +#define HSMCI_CMDR_SPCMD_SHIFT (8) /* Bits 8-10: Special Command */ +#define HSMCI_CMDR_SPCMD_MASK (7 << HSMCI_CMDR_SPCMD_SHIFT) +# define HSMCI_CMDR_SPCMD_NORMAL (0 << HSMCI_CMDR_SPCMD_SHIFT) /* Not a special CMD */ +# define HSMCI_CMDR_SPCMD_INIT (1 << HSMCI_CMDR_SPCMD_SHIFT) /* Initialization CMD */ +# define HSMCI_CMDR_SPCMD_SYNC (2 << HSMCI_CMDR_SPCMD_SHIFT) /* Synchronized CMD */ +# define HSMCI_CMDR_SPCMD_CEATAC (3 << HSMCI_CMDR_SPCMD_SHIFT) /* CE-ATA Completion Signal disable CMD */ +# define HSMCI_CMDR_SPCMD_INTCMD (4 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt command */ +# define HSMCI_CMDR_SPCMD_INTRESP (5 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt response */ +# define HSMCI_CMDR_SPCMD_BOOTOP (6 << HSMCI_CMDR_SPCMD_SHIFT) /* Boot Operation Request */ +# define HSMCI_CMDR_SPCMD_BOOTEND (7 << HSMCI_CMDR_SPCMD_SHIFT) /* End Boot Operation */ +#define HSMCI_CMDR_OPDCMD (1 << 11) /* Bit 11: Open Drain Command */ +#define HSMCI_CMDR_MAXLAT (1 << 12) /* Bit 12: Max Latency for Command to Response */ +#define HSMCI_CMDR_TRCMD_SHIFT (16) /* Bits 16-17: Transfer Command */ +#define HSMCI_CMDR_TRCMD_MASK (3 << HSMCI_CMDR_TRCMD_SHIFT) +# define HSMCI_CMDR_TRCMD_NONE (0 << HSMCI_CMDR_TRCMD_SHIFT) /* No data transfer */ +# define HSMCI_CMDR_TRCMD_START (1 << HSMCI_CMDR_TRCMD_SHIFT) /* Start data transfer */ +# define HSMCI_CMDR_TRCMD_STOP (2 << HSMCI_CMDR_TRCMD_SHIFT) /* Stop data transfer */ +#define HSMCI_CMDR_TRDIR (1 << 18) /* Bit 18: Transfer Direction */ +# define HSMCI_CMDR_TRDIR_WRITE (0 << 18) +# define HSMCI_CMDR_TRDIR_READ (1 << 18) +#define HSMCI_CMDR_TRTYP_SHIFT (19) /* Bits 19-21: Transfer Type */ +#define HSMCI_CMDR_TRTYP_MASK (7 << HSMCI_CMDR_TRTYP_SHIFT) +# define HSMCI_CMDR_TRTYP_SINGLE (0 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Single Block */ +# define HSMCI_CMDR_TRTYP_MULTI (1 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Multiple Block */ +# define HSMCI_CMDR_TRTYP_STREAM (2 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC Stream */ +# define HSMCI_CMDR_TRTYP_SDIOBYTE (4 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Byte */ +# define HSMCI_CMDR_TRTYP_SDIOBLK (5 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Block */ +#define HSMCI_CMDR_IOSPCMD_SHIFT (24) /* Bits 24-25: SDIO Special Command */ +#define HSMCI_CMDR_IOSPCMD_MASK (3 << HSMCI_CMDR_IOSPCMD_SHIFT) +# define HSMCI_CMDR_IOSPCMD_NORMAL (0 << HSMCI_CMDR_IOSPCMD_SHIFT) /* Not an SDIO Special Command */ +# define HSMCI_CMDR_IOSPCMD_SUSP (1 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Suspend Command */ +# define HSMCI_CMDR_IOSPCMD_RESUME (2 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Resume Command */ +#define HSMCI_CMDR_ATACS (1 << 26) /* Bit 26: ATA with Command Completion Signal */ +#define HSMCI_CMDR_BOOTACK (1 << 27) /* Bit 27: Boot Operation Acknowledge */ + +/* HSMCI Block Register */ + +#define HSMCI_BLKR_BCNT_SHIFT (0) /* Bits 0-15: MMC/SDIO Block Count - SDIO Byte Count */ +#define HSMCI_BLKR_BCNT_MASK (0xffff << HSMCI_BLKR_BCNT_SHIFT) +# define HSMCI_BLKR_BCNT(n) ((uint32_t)(n) << HSMCI_BLKR_BCNT_SHIFT) +#define HSMCI_BLKR_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */ +#define HSMCI_BLKR_BLKLEN_MASK (0xffff << HSMCI_BLKR_BLKLEN_SHIFT) +# define HSMCI_BLKR_BLKLEN(n) ((uint32_t)(n) << HSMCI_BLKR_BLKLEN_SHIFT) + +/* HSMCI Completion Signal Timeout Register */ + +#define HSMCI_CSTOR_CSTOCYC_SHIFT (0) /* Bits 0-3: Completion Signal Timeout Cycle Number */ +#define HSMCI_CSTOR_CSTOCYC_MASK (15 << HSMCI_CSTOR_CSTOCYC_SHIFT) +# define HSMCI_CSTOR_CSTOCYC(n) ((uint32_t)(n) << HSMCI_CSTOR_CSTOCYC_SHIFT) +#define HSMCI_CSTOR_CSTOMUL_SHIFT (4) /* Bits 4-6: Completion Signal Timeout Multiplier */ +#define HSMCI_CSTOR_CSTOMUL_MASK (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1 (0 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_16 (1 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_128 (2 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_256 (3 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1024 (4 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_4096 (5 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_65536 (6 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1048576 (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) + +/* HSMCI Response Registers (32-bit data) */ +/* HSMCI Receive Data Registers (32-bit data) */ +/* HSMCI Transmit Data Registers (32-bit data) */ + +/* HSMCI Status Register, HSMCI Interrupt Enable Register, HSMCI Interrupt Disable + * Register, and HSMCI Interrupt Mask Register common bit-field definitions + */ + +#define HSMCI_INT_CMDRDY (1 << 0) /* Bit 0: Command Ready */ +#define HSMCI_INT_RXRDY (1 << 1) /* Bit 1: Receiver Ready */ +#define HSMCI_INT_TXRDY (1 << 2) /* Bit 2: Transmit Ready */ +#define HSMCI_INT_BLKE (1 << 3) /* Bit 3: Data Block Ended */ +#define HSMCI_INT_DTIP (1 << 4) /* Bit 4: Data Transfer in Progress */ +#define HSMCI_INT_NOTBUSY (1 << 5) /* Bit 6: HSMCI Not Busy */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define HSMCI_INT_ENDRX (1 << 6) /* Bit 6: End of RX Buffer */ +# define HSMCI_INT_ENDTX (1 << 7) /* Bit 7: End of TX Buffer */ +#endif + +#define HSMCI_INT_SDIOIRQA (1 << 8) /* Bit 8: SDIO Interrupt for Slot A */ +#define HSMCI_INT_SDIOWAIT (1 << 12) /* Bit 12: SDIO Read Wait Operation Status */ +#define HSMCI_INT_CSRCV (1 << 13) /* Bit 13: CE-ATA Completion Signal Received */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define HSMCI_INT_RXBUFF (1 << 14) /* Bit 14: RXBUFF: RX Buffer Full */ +# define HSMCI_INT_TXBUFE (1 << 15) /* Bit 15: TXBUFE: TX Buffer Empty */ +#endif + +#define HSMCI_INT_RINDE (1 << 16) /* Bit 16: Response Index Error */ +#define HSMCI_INT_RDIRE (1 << 17) /* Bit 17: Response Direction Error */ +#define HSMCI_INT_RCRCE (1 << 18) /* Bit 18: Response CRC Error */ +#define HSMCI_INT_RENDE (1 << 19) /* Bit 19: Response End Bit Error */ +#define HSMCI_INT_RTOE (1 << 20) /* Bit 20: Response Time-out */ +#define HSMCI_INT_DCRCE (1 << 21) /* Bit 21: Data CRC Error */ +#define HSMCI_INT_DTOE (1 << 22) /* Bit 22: Data Time-out Error */ +#define HSMCI_INT_CSTOE (1 << 23) /* Bit 23: Completion Signal Time-out Error */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define HSMCI_INT_BLKOVRE (1 << 24) /* Bit 24: DMA Block Overrun Error */ +# define HSMCI_INT_DMADONE (1 << 25) /* Bit 25: DMA Transfer done */ +#endif + +#define HSMCI_INT_FIFOEMPTY (1 << 26) /* Bit 26: FIFO empty flag */ +#define HSMCI_INT_XFRDONE (1 << 27) /* Bit 27: Transfer Done flag */ +#define HSMCI_INT_ACKRCV (1 << 28) /* Bit 28: Boot Operation Acknowledge Received */ +#define HSMCI_INT_ACKRCVE (1 << 29) /* Bit 29: Boot Operation Acknowledge Error */ +#define HSMCI_INT_OVRE (1 << 30) /* Bit 30: Overrun */ +#define HSMCI_INT_UNRE (1 << 31) /* Bit 31: Underrun */ + +/* HSMCI DMA Configuration Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define HSMCI_DMA_OFFSET_SHIFT (0) /* Bits 0-1: DMA Write Buffer Offset */ +# define HSMCI_DMA_OFFSET_MASK (3 << HSMCI_DMA_OFFSET_SHIFT) +# define HSMCI_DMA_CHKSIZE (1 << 4) /* Bit 4: DMA Channel Read and Write Chunk Size */ +# define HSMCI_DMA_DMAEN (1 << 8) /* Bit 8: DMA Hardware Handshaking Enable */ +# define HSMCI_DMA_ROPT (1 << 12) /* Bit 12: Read Optimization with padding */ +#endif + +/* HSMCI Configuration Register */ + +#define HSMCI_CFG_FIFOMODE (1 << 0) /* Bit 0: HSMCI Internal FIFO control mode */ +#define HSMCI_CFG_FERRCTRL (1 << 4) /* Bit 4: Flow Error flag reset control mode */ +#define HSMCI_CFG_HSMODE (1 << 8) /* Bit 8: High Speed Mode */ +#define HSMCI_CFG_LSYNC (1 << 12) /* Bit 12: Synchronize on the last block */ + +/* HSMCI Write Protect Mode Register */ + +#define HSMCI_WPMR_WP_EN (1 << 0) /* Bit 0: Write Protection Enable */ +#define HSMCI_WPMR_WP_KEY_SHIFT (8) /* Bits 8-31: Write Protection Key password */ +#define HSMCI_WPMR_WP_KEY_MASK (0x00ffffff << HSMCI_WPMR_WP_KEY_SHIFT) +# define HSMCI_WPMR_WP_KEY (0x004d4349 << HSMCI_WPMR_WP_KEY_SHIFT) + +/* HSMCI Write Protect Status Register */ + +#define HSMCI_WPSR_VS_SHIFT (0) /* Bits 0-3: Write Protection Violation Status */ +#define HSMCI_WPSR_VS_MASK (15 << HSMCI_WPSR_VS_SHIFT) +# define HSMCI_WPSR_VS_NONE (0 << HSMCI_WPSR_VS_SHIFT) +# define HSMCI_WPSR_VS_WRITE (1 << HSMCI_WPSR_VS_SHIFT) +# define HSMCI_WPSR_VS_RESET (2 << HSMCI_WPSR_VS_SHIFT) +# define HSMCI_WPSR_VS_BOTH (3 << HSMCI_WPSR_VS_SHIFT) +#define HSMCI_WPSR_VSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define HSMCI_WPSR_VSRC_MASK (0xffff << HSMCI_WPSR_VSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_HSMCI_H */ diff --git a/arch/arm/src/sam34/chip/sam_matrix.h b/arch/arm/src/sam34/chip/sam_matrix.h new file mode 100644 index 0000000000000000000000000000000000000000..f519d5c63322de0b7dfca4e6c88c25d64d8ace60 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_matrix.h @@ -0,0 +1,371 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_matrix.h + * Bux matrix definitions for the SAM3U, SAM3X, SAM3A, SAM4E, and SAM4S + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_MATRIX_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_MATRIX_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* MATRIX register offsets **************************************************************/ + +#define SAM_MATRIX_MCFG_OFFSET(n) ((n)<<2) +#define SAM_MATRIX_MCFG0_OFFSET 0x0000 /* Master Configuration Register 0 */ +#define SAM_MATRIX_MCFG1_OFFSET 0x0004 /* Master Configuration Register 1 */ +#define SAM_MATRIX_MCFG2_OFFSET 0x0008 /* Master Configuration Register 2 */ +#define SAM_MATRIX_MCFG3_OFFSET 0x000c /* Master Configuration Register 3 */ +#define SAM_MATRIX_MCFG4_OFFSET 0x0010 /* Master Configuration Register 4 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MCFG5_OFFSET 0x0014 /* Master Configuration Register 5 */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MCFG6_OFFSET 0x0018 /* Master Configuration Register 6 */ +#endif + /* 0x0018-0x003c: Reserved */ +#define SAM_MATRIX_SCFG_OFFSET(n) (0x0040+((n)<<2)) +#define SAM_MATRIX_SCFG0_OFFSET 0x0040 /* Slave Configuration Register 0 */ +#define SAM_MATRIX_SCFG1_OFFSET 0x0044 /* Slave Configuration Register 1 */ +#define SAM_MATRIX_SCFG2_OFFSET 0x0048 /* Slave Configuration Register 2 */ +#define SAM_MATRIX_SCFG3_OFFSET 0x004c /* Slave Configuration Register 3 */ +#define SAM_MATRIX_SCFG4_OFFSET 0x0050 /* Slave Configuration Register 4 */ +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_SCFG5_OFFSET 0x0054 /* Slave Configuration Register 5 */ +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_MATRIX_SCFG6_OFFSET 0x0058 /* Slave Configuration Register 6 */ +# define SAM_MATRIX_SCFG7_OFFSET 0x005c /* Slave Configuration Register 7 */ +# define SAM_MATRIX_SCFG8_OFFSET 0x0060 /* Slave Configuration Register 8 */ +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_MATRIX_SCFG9_OFFSET 0x0064 /* Slave Configuration Register 9 */ +#endif + +#define SAM_MATRIX_PRAS_OFFSET(n) (0x0080+((n)<<3)) +#define SAM_MATRIX_PRAS0_OFFSET 0x0080 /* Priority Register A for Slave 0 */ +#define SAM_MATRIX_PRAS1_OFFSET 0x0088 /* Priority Register A for Slave 1 */ +#define SAM_MATRIX_PRAS2_OFFSET 0x0090 /* Priority Register A for Slave 2 */ +#define SAM_MATRIX_PRAS3_OFFSET 0x0098 /* Priority Register A for Slave 3 */ +#define SAM_MATRIX_PRAS4_OFFSET 0x00a0 /* Priority Register A for Slave 4 */ +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_PRAS5_OFFSET 0x00a8 /* Priority Register A for Slave 5 */ +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_MATRIX_PRAS6_OFFSET 0x00b0 /* Priority Register A for Slave 6 */ +# define SAM_MATRIX_PRAS7_OFFSET 0x00b8 /* Priority Register A for Slave 7 */ +# define SAM_MATRIX_PRAS8_OFFSET 0x00c0 /* Priority Register A for Slave 8 */ +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_MATRIX_PRAS9_OFFSET 0x00c8 /* Priority Register A for Slave 9 */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MRCR_OFFSET 0x0100 /* Master Remap Control Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_CCFG_SYSIO_OFFSET 0x0114 /* System I/O Configuration Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_CCFG_SMCNFCS_OFFSET 0x011c /* SMC Chip Select NAND Flash Assignment Register */ +#endif + +#define SAM_MATRIX_WPMR_OFFSET 0x01e4 /* Write Protect Mode Register */ +#define SAM_MATRIX_WPSR_OFFSET 0x01e8 /* Write Protect Status Register */ + /* 0x0110 - 0x01fc: Reserved */ + +/* MATRIX register addresses ************************************************************/ + +#define SAM_MATRIX_MCFG(n)) (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n)) +#define SAM_MATRIX_MCFG0 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG0_OFFSET) +#define SAM_MATRIX_MCFG1 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG1_OFFSET) +#define SAM_MATRIX_MCFG2 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG2_OFFSET) +#define SAM_MATRIX_MCFG3 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG3_OFFSET) +#define SAM_MATRIX_MCFG4 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG4_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MCFG5 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG5_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MCFG6 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG6_OFFSET) +#endif + +#define SAM_MATRIX_SCFG(n) (SAM_MATRIX_BASE+SAM_MATRIX_SCFG_OFFSET(n)) +#define SAM_MATRIX_SCFG0 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG0_OFFSET) +#define SAM_MATRIX_SCFG1 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG1_OFFSET) +#define SAM_MATRIX_SCFG2 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG2_OFFSET) +#define SAM_MATRIX_SCFG3 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG3_OFFSET) +#define SAM_MATRIX_SCFG4 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG4_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_SCFG5 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG5_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_MATRIX_SCFG6 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG6_OFFSET) +# define SAM_MATRIX_SCFG7 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG7_OFFSET) +# define SAM_MATRIX_SCFG8 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG8_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_MATRIX_SCFG9 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG9_OFFSET) +#endif + +#define SAM_MATRIX_PRAS(n) (SAM_MATRIX_BASE+SAM_MATRIX_PRAS_OFFSET(n)) +#define SAM_MATRIX_PRAS0 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS0_OFFSET) +#define SAM_MATRIX_PRAS1 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS1_OFFSET) +#define SAM_MATRIX_PRAS2 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS2_OFFSET) +#define SAM_MATRIX_PRAS3 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS3_OFFSET) +#define SAM_MATRIX_PRAS4 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS4_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_PRAS5 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS5_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_MATRIX_PRAS6 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS6_OFFSET) +# define SAM_MATRIX_PRAS7 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS7_OFFSET) +# define SAM_MATRIX_PRAS8 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS8_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_MATRIX_PRAS9 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS9_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_MRCR (SAM_MATRIX_BASE+SAM_MATRIX_MRCR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_CCFG_SYSIO (SAM_MATRIX_BASE+SAM_MATRIX_CCFG_SYSIO_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MATRIX_CCFG_SMCNFCS (SAM_MATRIX_BASE+SAM_MATRIX_CCFG_SMCNFCS_OFFSET) +#endif + +#define SAM_MATRIX_WPMR (SAM_MATRIX_BASE+SAM_MATRIX_WPMR_OFFSET) +#define SAM_MATRIX_WPSR (SAM_MATRIX_BASE+SAM_MATRIX_WPSR_OFFSET) + +/* MATRIX register bit definitions ******************************************************/ +/* Master Configuration Registers */ + +#define MATRIX_MCFG_ULBT_SHIFT (0) /* Bits 0-2: Undefined Length Burst Type */ +#define MATRIX_MCFG_ULBT_MASK (7 << MATRIX_MCFG_ULBT_SHIFT) +# define MATRIX_MCFG_ULBT_INF (0 << MATRIX_MCFG_ULBT_SHIFT) /* Infinite Length Burst */ +# define MATRIX_MCFG_ULBT_SINGLE (1 << MATRIX_MCFG_ULBT_SHIFT) /* Single Access */ +# define MATRIX_MCFG_ULBT_4BEAT (2 << MATRIX_MCFG_ULBT_SHIFT) /* 4-beat Burst */ +# define MATRIX_MCFG_ULBT_8BEAT (3 << MATRIX_MCFG_ULBT_SHIFT) /* 8-beat Burst */ +# define MATRIX_MCFG_ULBT_16BEAT (4 << MATRIX_MCFG_ULBT_SHIFT) /* 16-beat Burst */ +# if defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_MCFG_ULBT_32BEAT (5 << MATRIX_MCFG_ULBT_SHIFT) /* 32-beat Burst */ +# define MATRIX_MCFG_ULBT_64BEAT (6 << MATRIX_MCFG_ULBT_SHIFT) /* 64-beat Burst */ +# define MATRIX_MCFG_ULBT_128BEAT (7 << MATRIX_MCFG_ULBT_SHIFT) /* 128-beat Burst */ +# endif + +/* Bus Matrix Slave Configuration Registers */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_SCFG_SLOTCYCLE_SHIFT (0) /* Bits 0-8: Maximum Number of Allowed Cycles for a Burst */ +# define MATRIX_SCFG_SLOTCYCLE_MASK (0x1ff << MATRIX_SCFG_SLOTCYCLE_SHIFT) +# define MATRIX_SCFG_SLOTCYCLE(n) ((uint32_t)(n) << MATRIX_SCFG_SLOTCYCLE_SHIFT) +#else +# define MATRIX_SCFG_SLOTCYCLE_SHIFT (0) /* Bits 0-7: Maximum Number of Allowed Cycles for a Burst */ +# define MATRIX_SCFG_SLOTCYCLE_MASK (0xff << MATRIX_SCFG_SLOTCYCLE_SHIFT) +# define MATRIX_SCFG_SLOTCYCLE(n) ((uint32_t)(n) << MATRIX_SCFG_SLOTCYCLE_SHIFT) +#endif + +#define MATRIX_SCFG_DEFMSTRTYPE_SHIFT (16) /* Bits 16-17: Default Master Type */ +#define MATRIX_SCFG_DEFMSTRTYPE_MASK (3 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_NONE (0 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_LAST (1 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_FIXED (2 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) + +#define MATRIX_SCFG_FIXEDDEFMSTR_SHIFT (18) /* Bits 18-20: Fixed Default Master */ +#define MATRIX_SCFG_FIXEDDEFMSTR_MASK (7 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG0_FIXEDDEFMSTR(n) ((uint32_t)(n) << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG0_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG1_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG2_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG3_FIXEDDEFMSTR_ARMC (0 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG4_FIXEDDEFMSTR_ARMC (0 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG5_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG6_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG7_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG8_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG8_FIXEDDEFMSTR_HDMA (4 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG9_FIXEDDEFMSTR_ARMS (1 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG9_FIXEDDEFMSTR_HDMA (4 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) + +#if !defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_SCFG_ARBT_SHIFT (24) /* Bits 24-25: Arbitration Type */ +# define MATRIX_SCFG_ARBT_MASK (3 << MATRIX_SCFG_ARBT_SHIFT) +# define MATRIX_SCFG_ARBT_RR (0 << MATRIX_SCFG_ARBT_SHIFT) /* Round-Robin Arbitration */ +# define MATRIX_SCFG_ARBT_FIXED (1 << MATRIX_SCFG_ARBT_SHIFT) /* Fixed Priority Arbitration */ +#endif + +/* Bus Matrix Priority Registers For Slaves */ + +#define MATRIX_PRAS_MPR_SHIFT(x) ((n)<<2) +#define MATRIX_PRAS_MPR_MASK(x) (3 << MATRIX_PRAS_MPR_SHIFT(x)) +# define MATRIX_PRAS_M0PR_SHIFT (0) /* Bits 0-1: Master 0 Priority */ +# define MATRIX_PRAS_M0PR_MASK (3 << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M0PR(n) ((uint32_t)(n) << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M1PR_SHIFT (4) /* Bits 4-5: Master 1 Priority */ +# define MATRIX_PRAS_M1PR_MASK (3 << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M1PR(n) ((uint32_t)(n) << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M2PR_SHIFT (8) /* Bits 8-9: Master 2 Priority */ +# define MATRIX_PRAS_M2PR_MASK (3 << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M2PR(n) ((uint32_t)(n) << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M3PR_SHIFT (12) /* Bits 12-13: Master 3 Priority */ +# define MATRIX_PRAS_M3PR_MASK (3 << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M3PR(n) ((uint32_t)(n) << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M4PR_SHIFT (16) /* Bits 16-17: Master 4 Priority */ +# define MATRIX_PRAS_M4PR_MASK (3 << MATRIX_PRAS_M4PR_SHIFT) +# define MATRIX_PRAS_M4PR(n) ((uint32_t)(n) << MATRIX_PRAS_M4PR_SHIFT) +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_PRAS_M5PR_SHIFT (20) /* Bits 20-21: Master 5 Priority */ +# define MATRIX_PRAS_M5PR_MASK (3 << MATRIX_PRAS_M5PR_SHIFT) +# define MATRIX_PRAS_M5PR(n) ((uint32_t)(n) << MATRIX_PRAS_M5PR_SHIFT) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_PRAS_M6PR_SHIFT (24) /* Bits 24-25: Master 6 Priority */ +# define MATRIX_PRAS_M6PR_MASK (3 << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M6PR(n) ((uint32_t)(n) << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M7PR_SHIFT (28) /* Bits 28-29: Master 7 Priority */ +# define MATRIX_PRAS_M7PR_MASK (3 << MATRIX_PRAS_M7PR_SHIFT) +# define MATRIX_PRAS_M7PR(n) ((uint32_t)(n) << MATRIX_PRAS_M7PR_SHIFT) +#endif + +/* System I/O Configuration Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_CCFG_SYSIO_SYSIO4 (1 << 4) /* Bit 4: PB4 or TDI Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO5 (1 << 5) /* Bit 5: PB5 or TDO/TRACESWO Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO6 (1 << 6) /* Bit 6: PB6 or TMS/SWDIO Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO7 (1 << 7) /* Bit 7: PB7 or TCK/SWCLK Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO10 (1 << 10) /* Bit 10: PB10 or DDM Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO11 (1 << 11) /* Bit 11: PB11 or DDP Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO12 (1 << 12) /* Bit 12: PB12 or ERASE Assignment */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define MATRIX_CCFG_SYSIO_SYSIO12 (1 << 12) /* Bit 12: PC0 or ERASE Assignment */ +#endif + +/* SMC Chip Select NAND Flash Assignment Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS0 (1 << 0) /* Bit 0: SMC NAND Flash Chip Select 0 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS1 (1 << 1) /* Bit 1: SMC NAND Flash Chip Select 2 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS2 (1 << 2) /* Bit 2: SMC NAND Flash Chip Select 2 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS3 (1 << 3) /* Bit 3: SMC NAND Flash Chip Select 3 Assignment */ +#endif + +/* Master Remap Control Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_MRCR_RCB(x) (1 << (x)) +# define MATRIX_MRCR_RCB0 (1 << 0) /* Bit 0: Remap Command Bit for AHB Master 0 */ +# define MATRIX_MRCR_RCB1 (1 << 1) /* Bit 1: Remap Command Bit for AHB Master 1 */ +# define MATRIX_MRCR_RCB2 (1 << 2) /* Bit 2: Remap Command Bit for AHB Master 2 */ +# define MATRIX_MRCR_RCB3 (1 << 3) /* Bit 3: Remap Command Bit for AHB Master 3 */ +# define MATRIX_MRCR_RCB4 (1 << 4) /* Bit 4: Remap Command Bit for AHB Master 4 */ +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_MRCR_RCB5 (1 << 5) /* Bit 5: Remap Command Bit for AHB Master 5 */ +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define MATRIX_MRCR_RCB6 (1 << 6) /* Bit 6: Remap Command Bit for AHB Master 6 */ +# define MATRIX_MRCR_RCB7 (1 << 7) /* Bit 7: Remap Command Bit for AHB Master 7 */ +# define MATRIX_MRCR_RCB8 (1 << 8) /* Bit 8: Remap Command Bit for AHB Master 8 */ +# define MATRIX_MRCR_RCB9 (1 << 9) /* Bit 9: Remap Command Bit for AHB Master 9 */ +# define MATRIX_MRCR_RCB10 (1 << 10) /* Bit 10: Remap Command Bit for AHB Master 10 */ +# define MATRIX_MRCR_RCB11 (1 << 11) /* Bit 11: Remap Command Bit for AHB Master 11 */ +# define MATRIX_MRCR_RCB12 (1 << 12) /* Bit 12: Remap Command Bit for AHB Master 12 */ +# define MATRIX_MRCR_RCB13 (1 << 13) /* Bit 13: Remap Command Bit for AHB Master 13 */ +# define MATRIX_MRCR_RCB14 (1 << 14) /* Bit 14: Remap Command Bit for AHB Master 14 */ +# define MATRIX_MRCR_RCB15 (1 << 15) /* Bit 15: Remap Command Bit for AHB Master 15 */ +#endif +#endif + +/* Write Protect Mode Register */ + +#define MATRIX_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define MATRIX_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (Write-only) */ +#define MATRIX_WPMR_WPKEY_MASK (0x00ffffff << MATRIX_WPMR_WPKEY_SHIFT) +# define MATRIX_WPMR_WPKEY (0x004d4154 << MATRIX_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define MATRIX_WPSR_WPVS (1 << 0) /* Bit 0: Enable Write Protect */ +#define MATRIX_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define MATRIX_WPSR_WPVSRC_MASK (0xffff << MATRIX_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_MATRIX_H */ diff --git a/arch/arm/src/sam34/chip/sam_memorymap.h b/arch/arm/src/sam34/chip/sam_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..8ec74f3b2df09930cd0e57e5576c3f29a2c1726c --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_memorymap.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam_memorymap.h + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "chip/sam3u_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3x_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "chip/sam4cm_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_memorymap.h" +#else +# error Unrecognized SAM architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_MEMORYMAP_H */ + diff --git a/arch/arm/src/sam34/chip/sam_pdc.h b/arch/arm/src/sam34/chip/sam_pdc.h new file mode 100644 index 0000000000000000000000000000000000000000..2654508c13acc7f42c50099a7c43b9cda6406840 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_pdc.h @@ -0,0 +1,119 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_pdc.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_PDC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_PDC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PDC register offsets *****************************************************************/ + +#define SAM_PDC_RPR_OFFSET 0x100 /* Receive Pointer Register */ +#define SAM_PDC_RCR_OFFSET 0x104 /* Receive Counter Register */ +#define SAM_PDC_TPR_OFFSET 0x108 /* Transmit Pointer Register */ +#define SAM_PDC_TCR_OFFSET 0x10c /* Transmit Counter Register */ +#define SAM_PDC_RNPR_OFFSET 0x110 /* Receive Next Pointer Register */ +#define SAM_PDC_RNCR_OFFSET 0x114 /* Receive Next Counter Register */ +#define SAM_PDC_TNPR_OFFSET 0x118 /* Transmit Next Pointer Register */ +#define SAM_PDC_TNCR_OFFSET 0x11c /* Transmit Next Counter Register */ +#define SAM_PDC_PTCR_OFFSET 0x120 /* Transfer Control Register */ +#define SAM_PDC_PTSR_OFFSET 0x124 /* Transfer Status Register */ + +/* PDC register addresses ***************************************************************/ + +/* These 10 registers are mapped in the peripheral memory space at the same offset. */ + +/* PDC register bit definitions *********************************************************/ + +/* Receive Pointer Register -- 32-bit address value */ +/* Receive Counter Register -- 16-bit counter value */ + +#define PDC_RCR_RXCTR_SHIFT (0) /* Bits 0-15: Receive Counter Register */ +#define PDC_RCR_RXCTR_MASK (0xffff << PDC_RCR_RXCTR_SHIFT) + +/* Transmit Pointer Register -- 32-bit address value */ +/* Transmit Counter Register -- 16-bit counter value */ + +#define PDC_TCR_TXCTR_SHIFT (0) /* Bits 0-15: Transmit Counter Register */ +#define PDC_TCR_TXCTR_MASK (0xffff << PDC_TCR_TXCTR_SHIFT) + +/* Receive Next Pointer Register -- 32-bit address value */ +/* Receive Next Counter Register -- 16-bit counter value */ + +#define PDC_RNCR_RXNCTR_SHIFT (0) /* Bits 0-15: Receive Next Counter */ +#define PDC_RNCR_RXNCTR_MASK (0xffff << PDC_RNCR_RXNCTR_SHIFT) + +/* Transmit Next Pointer Register -- 32-bit address value */ +/* Transmit Next Counter Register -- 16-bit counter value */ + +#define PDC_TNCR_TXNCTR_SHIFT (0) /* Bits 0-15: Transmit Counter Next */ +#define PDC_TNCR_TXNCTR_MASK (0xffff << PDC_TNCR_TXNCTR_SHIFT) + +/* Transfer Control Register */ + +#define PDC_PTCR_RXTEN (1 << 0) /* Bit 0: Receiver Transfer Enable */ +#define PDC_PTCR_RXTDIS (1 << 1) /* Bit 1: Receiver Transfer Disable */ +#define PDC_PTCR_TXTEN (1 << 8) /* Bit 8: Transmitter Transfer Enable */ +#define PDC_PTCR_TXTDIS (1 << 9) /* Bit 9: Transmitter Transfer Disable */ + +/* Transfer Status Register */ + +#define PDC_PTSR_RXTEN (1 << 0) /* Bit 0: Receiver Transfer Enable */ +#define PDC_PTSR_TXTEN (1 << 8) /* Bit 8: Transmitter Transfer Enable */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_PDC_H */ diff --git a/arch/arm/src/sam34/chip/sam_pinmap.h b/arch/arm/src/sam34/chip/sam_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..bf79625e88aa4124f9513cef72457a116e37f803 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_pinmap.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/sam34/chip/sam_pinmap.h + * + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_PINMAP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "chip/sam3u_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3x_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "chip/sam4cm_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_pinmap.h" +#else +# error Unrecognized SAM architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_PINMAP_H */ + diff --git a/arch/arm/src/sam34/chip/sam_pmc.h b/arch/arm/src/sam34/chip/sam_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..6514d1f42e433ec1e55021276330afbd159b8e90 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_pmc.h @@ -0,0 +1,624 @@ +/******************************************************************************************** + * arch/arm/src/sam34/chip/sam_pmc.h + * Power Management Controller (PMC) for the SAM3U, SAM3X, SAM3A, SAM4CM, SAM4E, and + * SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_PMC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_PMC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* PMC register offsets *********************************************************************/ + +#define SAM_PMC_SCER_OFFSET 0x0000 /* System Clock Enable Register */ +#define SAM_PMC_SCDR_OFFSET 0x0004 /* System Clock Disable Register */ +#define SAM_PMC_SCSR_OFFSET 0x0008 /* System Clock Status Register */ + /* 0x000c: Reserved */ +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_PCER0_OFFSET 0x0010 /* Peripheral Clock Enable Register 0 */ +# define SAM_PMC_PCDR0_OFFSET 0x0014 /* Peripheral Clock Disable Register 0 */ +# define SAM_PMC_PCSR0_OFFSET 0x0018 /* Peripheral Clock Status Register 0 */ +#elif defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_PMC_PCER_OFFSET 0x0010 /* Peripheral Clock Enable Register */ +# define SAM_PMC_PCDR_OFFSET 0x0014 /* Peripheral Clock Disable Register */ +# define SAM_PMC_PCSR_OFFSET 0x0018 /* Peripheral Clock Status Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_PMC_CKGR_UCKR_OFFSET 0x001c /* UTMI Clock Register */ +#endif + /* 0x001c: Reserved (SAM4S)*/ +#define SAM_PMC_CKGR_MOR_OFFSET 0x0020 /* Main Oscillator Register */ +#define SAM_PMC_CKGR_MCFR_OFFSET 0x0024 /* Main Clock Frequency Register */ +#define SAM_PMC_CKGR_PLLAR_OFFSET 0x0028 /* PLLA Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define SAM_PMC_CKGR_PLLBR_OFFSET 0x002c /* PLLB Register */ +#endif + /* 0x002c: Reserved (SAM3U)*/ +#define SAM_PMC_MCKR_OFFSET 0x0030 /* Master Clock Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) + /* 0x0034 Reserved */ +# define SAM_PMC_USB_OFFSET 0x0038 /* USB Clock Register PMC_USB */ + /* 0x003c Reserved */ +#endif + /* 0x0034-0x003c Reserved (SAM3U) */ +#define SAM_PMC_PCK_OFFSET(n) (0x0040 + ((n) << 2)) +# define SAM_PMC_PCK0_OFFSET 0x0040 /* Programmable Clock 0 Register */ +# define SAM_PMC_PCK1_OFFSET 0x0044 /* Programmable Clock 1 Register */ +# define SAM_PMC_PCK2_OFFSET 0x0048 /* Programmable Clock 2 Register */ + /* 0x004c-0x005c: Reserved */ +#define SAM_PMC_IER_OFFSET 0x0060 /* Interrupt Enable Register */ +#define SAM_PMC_IDR_OFFSET 0x0064 /* Interrupt Disable Register */ +#define SAM_PMC_SR_OFFSET 0x0068 /* Status Register */ +#define SAM_PMC_IMR_OFFSET 0x006c /* Interrupt Mask Register */ +#define SAM_PMC_FSMR_OFFSET 0x0070 /* Fast Startup Mode Register */ +#define SAM_PMC_FSPR_OFFSET 0x0074 /* Fast Startup Polarity Register */ +#define SAM_PMC_FOCR_OFFSET 0x0078 /* Fault Output Clear Register */ + /* 0x007c-0x00e0: Reserved */ +#define SAM_PMC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PMC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) + /* 0x00ec-0x00fc Reserved */ +# define SAM_PMC_PCER1_OFFSET 0x0100 /* Peripheral Clock Enable Register 1 */ +# define SAM_PMC_PCDR1_OFFSET 0x0104 /* Peripheral Clock Disable Register 1 */ +# define SAM_PMC_PCSR1_OFFSET 0x0108 /* Peripheral Clock Status Register 1 */ +#endif + /* 0x010c Reserved */ +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_PMC_PCR_OFFSET 0x010c /* Peripheral Control Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_OCR_OFFSET 0x0110 /* Oscillator Calibration Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_PMMR_OFFSET 0x0130 /* PLL Maximum Multiplier Value Register */ +#endif + +/* PMC register addresses *******************************************************************/ + +#define SAM_PMC_SCER (SAM_PMC_BASE+SAM_PMC_SCER_OFFSET) +#define SAM_PMC_SCDR (SAM_PMC_BASE+SAM_PMC_SCDR_OFFSET) +#define SAM_PMC_SCSR (SAM_PMC_BASE+SAM_PMC_SCSR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_PCER0 (SAM_PMC_BASE+SAM_PMC_PCER0_OFFSET) +# define SAM_PMC_PCDR0 (SAM_PMC_BASE+SAM_PMC_PCDR0_OFFSET) +# define SAM_PMC_PCSR0 (SAM_PMC_BASE+SAM_PMC_PCSR0_OFFSET) +#elif defined(CONFIG_ARCH_CHIP_SAM3U) +# define SAM_PMC_PCER (SAM_PMC_BASE+SAM_PMC_PCER_OFFSET) +# define SAM_PMC_PCDR (SAM_PMC_BASE+SAM_PMC_PCDR_OFFSET) +# define SAM_PMC_PCSR (SAM_PMC_BASE+SAM_PMC_PCSR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_PMC_CKGR_UCKR (SAM_PMC_BASE+SAM_PMC_CKGR_UCKR_OFFSET) +#endif + +#define SAM_PMC_CKGR_MOR (SAM_PMC_BASE+SAM_PMC_CKGR_MOR_OFFSET) +#define SAM_PMC_CKGR_MCFR (SAM_PMC_BASE+SAM_PMC_CKGR_MCFR_OFFSET) +#define SAM_PMC_CKGR_PLLAR (SAM_PMC_BASE+SAM_PMC_CKGR_PLLAR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define SAM_PMC_CKGR_PLLBR (SAM_PMC_BASE+SAM_PMC_CKGR_PLLBR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_USB (SAM_PMC_BASE+SAM_PMC_USB_OFFSET) +#endif + +#define SAM_PMC_MCKR (SAM_PMC_BASE+SAM_PMC_MCKR_OFFSET) +#define SAM_PMC_PCK(n) (SAM_PMC_BASE+SAM_PMC_PCK_OFFSET(n)) +#define SAM_PMC_PCK0 (SAM_PMC_BASE+SAM_PMC_PCK0_OFFSET) +#define SAM_PMC_PCK1 (SAM_PMC_BASE+SAM_PMC_PCK1_OFFSET) +#define SAM_PMC_PCK2 (SAM_PMC_BASE+SAM_PMC_PCK2_OFFSET) +#define SAM_PMC_IER (SAM_PMC_BASE+SAM_PMC_IER_OFFSET) +#define SAM_PMC_IDR (SAM_PMC_BASE+SAM_PMC_IDR_OFFSET) +#define SAM_PMC_SR (SAM_PMC_BASE+SAM_PMC_SR_OFFSET) +#define SAM_PMC_IMR (SAM_PMC_BASE+SAM_PMC_IMR_OFFSET) +#define SAM_PMC_FSMR (SAM_PMC_BASE+SAM_PMC_FSMR_OFFSET) +#define SAM_PMC_FSPR (SAM_PMC_BASE+SAM_PMC_FSPR_OFFSET) +#define SAM_PMC_FOCR (SAM_PMC_BASE+SAM_PMC_FOCR_OFFSET) +#define SAM_PMC_WPMR (SAM_PMC_BASE+SAM_PMC_WPMR_OFFSET) +#define SAM_PMC_WPSR (SAM_PMC_BASE+SAM_PMC_WPSR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_PCER1 (SAM_PMC_BASE+SAM_PMC_PCER1_OFFSET) +# define SAM_PMC_PCDR1 (SAM_PMC_BASE+SAM_PMC_PCDR1_OFFSET) +# define SAM_PMC_PCSR1 (SAM_PMC_BASE+SAM_PMC_PCSR1_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_PMC_PCR (SAM_PMC_BASE+SAM_PMC_PCR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_OCR (SAM_PMC_BASE+SAM_PMC_OCR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PMC_PMMR (SAM_PMC_BASE+SAM_PMC_PMMR_OFFSET) +#endif + +/* PMC register bit definitions *************************************************************/ + +/* PMC System Clock Enable Register, PMC System Clock Disable Register, and PMC System + * Clock Status Register common bit-field definitions + */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_UOTGCLK (1 << 5) /* Bit 5: Enable USB OTG Clock (48 MHz, USB_48M) for UTMI */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_UDP (1 << 7) /* Bit 7: USB Device Port Clock Enable */ +#endif + +#define PMC_PCK(n) (1 << ((n) + 8) +#define PMC_PCK0 (1 << 8) /* Bit 8: Programmable Clock 0 Output Enable */ +#define PMC_PCK1 (1 << 9) /* Bit 9: Programmable Clock 1 Output Enable */ +#define PMC_PCK2 (1 << 10) /* Bit 10: Programmable Clock 2 Output Enable */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define PMC_CPCK (1 << 16) +# define PMC_CPBMCK (1 << 17) +# define PMC_CPKEY (0xa << 20) +#endif + +/* PMC Peripheral Clock Enable Register, PMC Peripheral Clock Disable Register, and PMC + * Peripheral Clock Status Register common bit-field definitions. + */ + +#define PMC_PIDL(n) (1 << (n)) +#define PMC_PID2 (1 << 2) /* Bit 2: Peripheral Clock 2 Enable */ +#define PMC_PID3 (1 << 3) /* Bit 3: Peripheral Clock 3 Enable */ +#define PMC_PID4 (1 << 4) /* Bit 4: Peripheral Clock 4 Enable */ +#define PMC_PID5 (1 << 5) /* Bit 5: Peripheral Clock 5 Enable */ +#define PMC_PID6 (1 << 6) /* Bit 6: Peripheral Clock 6 Enable */ +#define PMC_PID7 (1 << 7) /* Bit 7: Peripheral Clock 7 Enable */ +#define PMC_PID8 (1 << 8) /* Bit 8: Peripheral Clock 8 Enable */ +#define PMC_PID9 (1 << 9) /* Bit 9: Peripheral Clock 9 Enable */ +#define PMC_PID10 (1 << 10) /* Bit 10: Peripheral Clock 10 Enable */ +#define PMC_PID11 (1 << 11) /* Bit 11: Peripheral Clock 11 Enable */ +#define PMC_PID12 (1 << 12) /* Bit 12: Peripheral Clock 12 Enable */ +#define PMC_PID13 (1 << 13) /* Bit 13: Peripheral Clock 13 Enable */ +#define PMC_PID14 (1 << 14) /* Bit 14: Peripheral Clock 14 Enable */ +#define PMC_PID15 (1 << 15) /* Bit 15: Peripheral Clock 15 Enable */ +#define PMC_PID16 (1 << 16) /* Bit 16: Peripheral Clock 16 Enable */ +#define PMC_PID17 (1 << 17) /* Bit 17: Peripheral Clock 17 Enable */ +#define PMC_PID18 (1 << 18) /* Bit 18: Peripheral Clock 18 Enable */ +#define PMC_PID19 (1 << 19) /* Bit 19: Peripheral Clock 19 Enable */ +#define PMC_PID20 (1 << 20) /* Bit 20: Peripheral Clock 20 Enable */ +#define PMC_PID21 (1 << 21) /* Bit 21: Peripheral Clock 21 Enable */ +#define PMC_PID22 (1 << 22) /* Bit 22: Peripheral Clock 22 Enable */ +#define PMC_PID23 (1 << 23) /* Bit 23: Peripheral Clock 23 Enable */ +#define PMC_PID24 (1 << 24) /* Bit 24: Peripheral Clock 24 Enable */ +#define PMC_PID25 (1 << 25) /* Bit 25: Peripheral Clock 25 Enable */ +#define PMC_PID26 (1 << 26) /* Bit 26: Peripheral Clock 26 Enable */ +#define PMC_PID27 (1 << 27) /* Bit 27: Peripheral Clock 27 Enable */ +#define PMC_PID28 (1 << 28) /* Bit 28: Peripheral Clock 28 Enable */ +#define PMC_PID29 (1 << 29) /* Bit 29: Peripheral Clock 29 Enable */ +#define PMC_PID30 (1 << 30) /* Bit 30: Peripheral Clock 30 Enable */ +#define PMC_PID31 (1 << 31) /* Bit 31: Peripheral Clock 31 Enable */ + +/* PMC UTMI Clock Configuration Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define PMC_CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */ +# define PMC_CKGR_UCKR_UPLLCOUNT_SHIFT (20) /* Bits 20-23: UTMI PLL Start-up Time */ +# define PMC_CKGR_UCKR_UPLLCOUNT_MASK (15 << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) +#endif + +/* PMC Clock Generator Main Oscillator Register */ + +#define PMC_CKGR_MOR_MOSCXTEN (1 << 0) /* Bit 0: Main Crystal Oscillator Enable */ +#define PMC_CKGR_MOR_MOSCXTBY (1 << 1) /* Bit 1: Main Crystal Oscillator Bypass */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_CKGR_MOR_WAITMODE (1 << 2) /* Bit 2: Wait Mode Command */ +#endif + +#define PMC_CKGR_MOR_MOSCRCEN (1 << 3) /* Bit 3: Main On-Chip RC Oscillator Enable */ +#define PMC_CKGR_MOR_MOSCRCF_SHIFT (4) /* Bits 4-6: Main On-Chip RC Oscillator Frequency Selection */ +#define PMC_CKGR_MOR_MOSCRCF_MASK (7 << PMC_CKGR_MOR_MOSCRCF_SHIFT) +# define PMC_CKGR_MOR_MOSCRCF_4MHz (0 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 4MHz (default) */ +# define PMC_CKGR_MOR_MOSCRCF_8MHz (1 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 8MHz */ +# define PMC_CKGR_MOR_MOSCRCF_12MHz (2 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 12MHz */ +#define PMC_CKGR_MOR_MOSCXTST_SHIFT (8) /* Bits 8-15: Main Crystal Oscillator Start-up Time */ +#define PMC_CKGR_MOR_MOSCXTST_MASK (0xff << PMC_CKGR_MOR_MOSCXTST_SHIFT) +# define PMC_CKGR_MOR_MOSCXTST(n) ((uint32_t)(n) << PMC_CKGR_MOR_MOSCXTST_SHIFT) +#define PMC_CKGR_MOR_KEY_SHIFT (16) /* Bits 16-23: Password */ +#define PMC_CKGR_MOR_KEY_MASK (0xff << PMC_CKGR_MOR_KEY_SHIFT) +# define PMC_CKGR_MOR_KEY (0x37 << PMC_CKGR_MOR_KEY_SHIFT) +#define PMC_CKGR_MOR_MOSCSEL (1 << 24) /* Bit 24: Main Oscillator Selection */ +#define PMC_CKGR_MOR_CFDEN (1 << 25) /* Bit 25: Clock Failure Detector Enable */ + +/* PMC Clock Generator Main Clock Frequency Register */ + +#define PMC_CKGR_MCFR_MAINF_SHIFT (0) /* Bits 0-15: Main Clock Frequency */ +#define PMC_CKGR_MCFR_MAINF_MASK (0xffff << PMC_CKGR_MCFR_MAINF_SHIFT) +# define PMC_CKGR_MCFR_MAINF(n) ((uint32_t)(n) << PMC_CKGR_MCFR_MAINF_SHIFT) +#define PMC_CKGR_MCFR_MAINFRDY (1 << 16) /* Bit 16: Main Clock Ready */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_CKGR_MCFR_RCMEAS (1 << 20) /* Bit 20: RC Oscillator Frequency Measure (write-only) */ +#endif + +/* PMC Clock Generator PLLA Register */ + +#define PMC_CKGR_PLLAR_DIV_SHIFT (0) /* Bits 0-7: Divider */ +#define PMC_CKGR_PLLAR_DIV_MASK (0xff << PMC_CKGR_PLLAR_DIV_SHIFT) +# define PMC_CKGR_PLLAR_DIV_ZERO (0 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is 0 */ +# define PMC_CKGR_PLLAR_DIV_BYPASS (1 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider is bypassed (DIV=1) */ +# define PMC_CKGR_PLLAR_DIV(n) ((n) << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is DIV=n, n=2..255 */ + +#define PMC_CKGR_PLLAR_COUNT_SHIFT (8) /* Bits 8-13: PLLA Counter */ +#define PMC_CKGR_PLLAR_COUNT_MASK (63 << PMC_CKGR_PLLAR_COUNT_SHIFT) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define PMC_CKGR_PLLAR_STMODE_SHIFT (14) /* Bits 14-15: Start Mode */ +# define PMC_CKGR_PLLAR_STMODE_MASK (3 << PMC_CKGR_PLLAR_STMODE_SHIFT) +# define PMC_CKGR_PLLAR_STMODE_FAST (0 << PMC_CKGR_PLLAR_STMODE_SHIFT) /* Fast Startup */ +# define PMC_CKGR_PLLAR_STMODE_NORMAL (2 << PMC_CKGR_PLLAR_STMODE_SHIFT) /* Normal Startup */ +#endif + +#define PMC_CKGR_PLLAR_MUL_SHIFT (16) /* Bits 16-26: PLLA Multiplier */ +#define PMC_CKGR_PLLAR_MUL_MASK (0x7ff << PMC_CKGR_PLLAR_MUL_SHIFT) +#define PMC_CKGR_PLLAR_ONE (1 << 29) /* Bit 29: Always one */ + +/* PLLB Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_CKGR_PLLBR_DIV_SHIFT (0) /* Bits 0-7: Divider */ +# define PMC_CKGR_PLLBR_DIV_MASK (0xff << PMC_CKGR_PLLBR_DIV_SHIFT) +# define PMC_CKGR_PLLBR_DIV_ZERO (0 << PMC_CKGR_PLLBR_DIV_SHIFT) /* Divider output is 0 */ +# define PMC_CKGR_PLLBR_DIV_BYPASS (1 << PMC_CKGR_PLLBR_DIV_SHIFT) /* Divider is bypassed (DIV=1) */ +# define PMC_CKGR_PLLBR_DIV(n) ((n) << PMC_CKGR_PLLBR_DIV_SHIFT) /* Divider output is DIV=n, n=2..255 */ +# define PMC_CKGR_PLLBR_COUNT_SHIFT (8) /* Bits 8-13: PLLA Counter */ +# define PMC_CKGR_PLLBR_COUNT_MASK (63 << PMC_CKGR_PLLBR_COUNT_SHIFT) +# define PMC_CKGR_PLLBR_MUL_SHIFT (16) /* Bits 16-26: PLLA Multiplier */ +# define PMC_CKGR_PLLBR_MUL_MASK (0x7ff << PMC_CKGR_PLLBR_MUL_SHIFT) + +# if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define PMC_CKGR_PLLBR_SRCB_SHIFT (29) +# define PMC_CKGR_PLLBR_SRCB_MASK (1 << PMC_CKGR_PLLBR_SRCB_SHIFT) +# define PMC_CKGR_PLLBR_SRCB_MAIN (0 << PMC_CKGR_PLLBR_SRCB_SHIFT) +# define PMC_CKGR_PLLBR_SRCB_PLLA (1 << PMC_CKGR_PLLBR_SRCB_SHIFT) +# endif +#endif + +/* USB Clock Register PMC_USB */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# if defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_USB_USBS (1 << 0) /* Bit 0: USB Input Clock Selection */ +# define PMC_USB_USBS_PLLA (0) +# define PMC_USB_USBS_PLLB PMC_USB_USBS +# endif +# define PMC_USB_USBDIV_SHIFT (8) /* Bits 8-11: Divider for USB Clock */ +# define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT) +#endif + +/* PMC Master Clock Register */ + +#define PMC_MCKR_CSS_SHIFT (0) /* Bits 0-1: Master Clock Source Selection */ +#define PMC_MCKR_CSS_MASK (3 << PMC_MCKR_CSS_SHIFT) +# define PMC_MCKR_CSS_SLOW (0 << PMC_MCKR_CSS_SHIFT) /* Slow Clock */ +# define PMC_MCKR_CSS_MAIN (1 << PMC_MCKR_CSS_SHIFT) /* Main Clock */ +# define PMC_MCKR_CSS_PLLA (2 << PMC_MCKR_CSS_SHIFT) /* PLLA Clock */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_MCKR_CSS_PLLB (3 << PMC_MCKR_CSS_SHIFT) /* PLLB Clock */ +#elif defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define PMC_MCKR_CSS_UPLL (3 << PMC_MCKR_CSS_SHIFT) /* UPLL Clock */ +#endif + +#define PMC_MCKR_PRES_SHIFT (4) /* Bits 4-6: Processor Clock Prescaler */ +#define PMC_MCKR_PRES_MASK (7 << PMC_MCKR_PRES_SHIFT) +# define PMC_MCKR_PRES_DIV1 (0 << PMC_MCKR_PRES_SHIFT) /* Selected clock */ +# define PMC_MCKR_PRES_DIV2 (1 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 2 */ +# define PMC_MCKR_PRES_DIV4 (2 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 4 */ +# define PMC_MCKR_PRES_DIV8 (3 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 8 */ +# define PMC_MCKR_PRES_DIV16 (4 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 16 */ +# define PMC_MCKR_PRES_DIV32 (5 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 32 */ +# define PMC_MCKR_PRES_DIV64 (6 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 64 */ +# define PMC_MCKR_PRES_DIV3 (7 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 3 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_MCKR_PLLADIV2 (1 << 12) /* Bit 12: PLLA Divider */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_MCKR_PLLBDIV2 (1 << 13) /* Bit 13: PLLB Divider */ +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM3U) +# define PMC_MCKR_UPLLDIV2 (1 << 13) /* Bit 13: UPLL Divider */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define PMC_MCKR_CPCSS_SHIFT (16) +# define PMC_MCKR_CPCSS_MASK (0x7 << PMC_MCKR_CPCSS_SHIFT) +# define PMC_MCKR_CPCSS_SLOW (0 << PMC_MCKR_CPCSS_SHIFT) /* Slow Clock */ +# define PMC_MCKR_CCPSS_MAIN (1 << PMC_MCKR_CPCSS_SHIFT) /* Main Clock */ +# define PMC_MCKR_CCPSS_PLLA (2 << PMC_MCKR_CPCSS_SHIFT) /* PLLA Clock */ +# define PMC_MCKR_CCPSS_PLLB (3 << PMC_MCKR_CPCSS_SHIFT) /* PLLB Clock */ +# define PMC_MCKR_CCPSS_MCK (4 << PMC_MCKR_CPCSS_SHIFT) /* Master Clock */ +# define PMC_MCKR_CPPRES_SHIFT (20) +# define PMC_MCKR_CPPRES_MASK (0xF << PMC_MCKR_CPPRES_SHIFT) +# define PMC_MCKR_CPPRES(D) (((D) - 1) << PMC_MCKR_CPPRES_SHIFT) +#endif + +/* PMC Programmable Clock Register (0,1,2) */ + +#define PMC_PCK_CSS_SHIFT (0) /* Bits 0-2: Master Clock Source Selection */ +#define PMC_PCK_CSS_MASK (7 << PMC_PCK_CSS_SHIFT) +# define PMC_PCK_CSS_SLOW (0 << PMC_PCK_CSS_SHIFT) /* Slow Clock */ +# define PMC_PCK_CSS_MAIN (1 << PMC_PCK_CSS_SHIFT) /* Main Clock */ +# define PMC_PCK_CSS_PLLA (2 << PMC_PCK_CSS_SHIFT) /* PLLA Clock */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_PCK_CSS_PLLB (3 << PMC_PCK_CSS_SHIFT) /* PLLB Clock */ +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM3U) +# define PMC_PCK_CSS_UPLL (3 << PMC_PCK_CSS_SHIFT) /* UPLL Clock */ +#endif + +# define PMC_PCK_CSS_MCK (4 << PMC_PCK_CSS_SHIFT) /* Master Clock */ + +#define PMC_PCK_PRES_SHIFT (4) /* Bits 4-6: Programmable Clock Prescaler */ +#define PMC_PCK_PRES_MASK (7 << PMC_PCK_PRES_SHIFT) +# define PMC_PCK_PRES_DIV1 (0 << PMC_PCK_PRES_SHIFT) /* Selected clock */ +# define PMC_PCK_PRES_DIV2 (1 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 2 */ +# define PMC_PCK_PRES_DIV4 (2 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 4 */ +# define PMC_PCK_PRES_DIV8 (3 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 8 */ +# define PMC_PCK_PRES_DIV16 (4 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 16 */ +# define PMC_PCK_PRES_DIV32 (5 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 32 */ +# define PMC_PCK_PRES_DIV64 (6 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 64 */ + +/* PMC Interrupt Enable Register, PMC Interrupt Disable Register, PMC Status Register, + * and PMC Interrupt Mask Register common bit-field definitions + */ + +#define PMC_INT_MOSCXTS (1 << 0) /* Bit 0: Main Crystal Oscillator Status Interrupt */ +#define PMC_INT_LOCKA (1 << 1) /* Bit 1: PLL A Lock Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# define PMC_INT_LOCKB (1 << 2) /* Bit 2: PLL B Lock Interrupt */ +#endif + +#define PMC_INT_MCKRDY (1 << 3) /* Bit 3: Master Clock Ready Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM3U) +# define PMC_INT_LOCKU (1 << 6) /* Bit 6: UTMI PLL Lock Interrupt */ +#endif + +#define PMC_SR_OSCSELS (1 << 7) /* Bit 7: Slow Clock Oscillator Selection (SR only) */ +#define PMC_INT_PCKRDY(n) (1 << ((n)+8) +# define PMC_INT_PCKRDY0 (1 << 8) /* Bit 8: Programmable Clock Ready 0 Interrupt */ +# define PMC_INT_PCKRDY1 (1 << 9) /* Bit 9: Programmable Clock Ready 1 Interrupt */ +# define PMC_INT_PCKRDY2 (1 << 10) /* Bit 10: Programmable Clock Ready 2 Interrupt */ +#define PMC_INT_MOSCSELS (1 << 16) /* Bit 16: Main Oscillator Selection Status Interrupt */ +#define PMC_INT_MOSCRCS (1 << 17) /* Bit 17: Main On-Chip RC Status Interrupt */ +#define PMC_INT_CFDEV (1 << 18) /* Bit 18: Clock Failure Detector Event Interrupt */ +#define PMC_SR_CFDS (1 << 19) /* Bit 19: Clock Failure Detector Status (SR only) */ +#define PMC_SR_FOS (1 << 20) /* Bit 20: Clock Failure Detector Fault Output Status (SR only) */ + +/* PMC Fast Startup Mode Register and PMC Fast Startup Polarity Register common bit-field + * definitions + */ + +#define PMC_FSTI(n) (1 << (n)) +# define PMC_FSTI0 (1 << 0) /* Bit 0: Fast Startup Input 0 */ +# define PMC_FSTI1 (1 << 1) /* Bit 1: Fast Startup Input 1 */ +# define PMC_FSTI2 (1 << 2) /* Bit 2: Fast Startup Input 2 */ +# define PMC_FSTI3 (1 << 3) /* Bit 3: Fast Startup Input 3 */ +# define PMC_FSTI4 (1 << 4) /* Bit 4: Fast Startup Input 4 */ +# define PMC_FSTI5 (1 << 5) /* Bit 5: Fast Startup Input 5 */ +# define PMC_FSTI6 (1 << 6) /* Bit 6: Fast Startup Input 6 */ +# define PMC_FSTI7 (1 << 7) /* Bit 7: Fast Startup Input 7 */ +# define PMC_FSTI8 (1 << 8) /* Bit 8: Fast Startup Input 8 */ +# define PMC_FSTI9 (1 << 9) /* Bit 9: Fast Startup Input 9 */ +# define PMC_FSTI10 (1 << 10) /* Bit 10: Fast Startup Input 10 */ +# define PMC_FSTI11 (1 << 11) /* Bit 11: Fast Startup Input 11 */ +# define PMC_FSTI12 (1 << 12) /* Bit 12: Fast Startup Input 12 */ +# define PMC_FSTI13 (1 << 13) /* Bit 13: Fast Startup Input 13 */ +# define PMC_FSTI14 (1 << 14) /* Bit 14: Fast Startup Input 14 */ +# define PMC_FSTI15 (1 << 15) /* Bit 15: Fast Startup Input 15 */ +#define PMC_FSMR_RTTAL (1 << 16) /* Bit 16: RTT Alarm Enable (MR only) */ +#define PMC_FSMR_RTCAL (1 << 17) /* Bit 17: RTC Alarm Enable (MR only) */ +#define PMC_FSMR_USBAL (1 << 18) /* Bit 18: USB Alarm Enable (MR only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_FSMR_LPM (1 << 20) /* Bit 20: Low Power Mode (MR only) */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_FSMR_FLPM_SHIFT (21) /* Bit 21-22: Low Power Mode (MR only) */ +# define PMC_FSMR_FLPM_MASK (3 << PMC_FSMR_FLPM_SHIFT) +# define PMC_FSMR_FLPM_STANDBY (0 << PMC_FSMR_FLPM_SHIFT) /* Flash Standby Mode */ +# define PMC_FSMR_FLPM_PWRDOWN (1 << PMC_FSMR_FLPM_SHIFT) /* Flash deep power down mode */ +# define PMC_FSMR_FLPM_IDLE (2 << PMC_FSMR_FLPM_SHIFT) /* Idle mode */ +#endif + +/* Fast Startup Polarity Register */ + +#define PMC_FSTP(n) (1 << (n)) /* Fast Startup Input Polarity n, n=0..15 */ +# define PMC_FSTP0 (1 << 0) /* Bit 0: Fast Startup Input Polarity 0 */ +# define PMC_FSTP1 (1 << 1) /* Bit 1: Fast Startup Input Polarity 1 */ +# define PMC_FSTP2 (1 << 2) /* Bit 2: Fast Startup Input Polarity 2 */ +# define PMC_FSTP3 (1 << 3) /* Bit 3: Fast Startup Input Polarity 3 */ +# define PMC_FSTP4 (1 << 4) /* Bit 4: Fast Startup Input Polarity 4 */ +# define PMC_FSTP5 (1 << 5) /* Bit 5: Fast Startup Input Polarity 5 */ +# define PMC_FSTP6 (1 << 6) /* Bit 6: Fast Startup Input Polarity 6 */ +# define PMC_FSTP7 (1 << 7) /* Bit 7: Fast Startup Input Polarity 7 */ +# define PMC_FSTP8 (1 << 8) /* Bit 8: Fast Startup Input Polarity 8 */ +# define PMC_FSTP9 (1 << 9) /* Bit 9: Fast Startup Input Polarity 9 */ +# define PMC_FSTP10 (1 << 10) /* Bit 10: Fast Startup Input Polarity 10 */ +# define PMC_FSTP11 (1 << 11) /* Bit 11: Fast Startup Input Polarity 11 */ +# define PMC_FSTP12 (1 << 12) /* Bit 12: Fast Startup Input Polarity 12 */ +# define PMC_FSTP13 (1 << 13) /* Bit 13: Fast Startup Input Polarity 13 */ +# define PMC_FSTP14 (1 << 14) /* Bit 14: Fast Startup Input Polarity 14 */ +# define PMC_FSTP15 (1 << 15) /* Bit 15: Fast Startup Input Polarity 15 */ + +/* PMC Fault Output Clear Register */ + +#define PMC_FOCLR (1 << 0) /* Bit 0: Fault Output Clear */ + +/* PMC Write Protect Mode Register */ + +#define PMC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PMC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PMC_WPMR_WPKEY_MASK (0x00ffffff << PMC_WPMR_WPKEY_SHIFT) +# define PMC_WPMR_WPKEY (0x00504d43 << PMC_WPMR_WPKEY_SHIFT) + +/* PMC Write Protect Status Register */ + +#define PMC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PMC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PMC_WPSR_WPVSRC_MASK (0xffff << PMC_WPSR_WPVSRC_SHIFT) + +/* Peripheral Clock Enable Register 1 */ +/* Peripheral Clock Disable Register 1 */ +/* Peripheral Clock Status Register 1 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_PIDH(n) (1 << ((n) - 32)) +# define PMC_PID32 (1 << 0) /* Bit 0: PID32 */ +# define PMC_PID33 (1 << 1) /* Bit 1: PID33 */ +# define PMC_PID34 (1 << 2) /* Bit 2: PID34 */ +# if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_PID35 (1 << 3) /* Bit 3: PID35 */ +# define PMC_PID36 (1 << 4) /* Bit 4: PID36 */ +# define PMC_PID37 (1 << 5) /* Bit 5: PID37 */ +# define PMC_PID38 (1 << 6) /* Bit 6: PID38 */ +# define PMC_PID39 (1 << 7) /* Bit 7: PID39 */ +# define PMC_PID40 (1 << 8) /* Bit 8: PID40 */ +# define PMC_PID41 (1 << 9) /* Bit 9: PID41 */ +# define PMC_PID42 (1 << 10) /* Bit 10: PID42 */ +# define PMC_PID43 (1 << 11) /* Bit 11: PID43 */ +# define PMC_PID44 (1 << 12) /* Bit 12: PID44 */ +# endif +# if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_PID45 (1 << 13) /* Bit 13: PID45 */ +# define PMC_PID46 (1 << 14) /* Bit 14: PID46 */ +# define PMC_PID47 (1 << 15) /* Bit 15: PID47 */ +# endif +#endif + +/* Peripheral Control Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define PMC_PCR_PID_SHIFT (0) /* Bits 0-5: Peripheral ID */ +# define PMC_PCR_PID_MASK (63 < PMC_PCR_PID_SHIFT) +# define PMC_PCR_CMD (1 << 12) /* Bit 12: Command */ +# define PMC_PCR_DIV_SHIFT (16) /* Bits 16-17: Divisor Value */ +# define PMC_PCR_DIV_MASK (3 < PMC_PCR_DIV_SHIFT) +# define PMC_PCR_DIV1 (0 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK */ +# define PMC_PCR_DIV2 (1 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/2 */ +# define PMC_PCR_DIV4 (2 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/4 */ +# define PMC_PCR_EN (1 << 28) /* Bit 28: Enable */ +#endif + +/* Oscillator Calibration Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_OCR_CAL4_SHIFT (0) /* Bits 0-6: 4MHzRC Oscillator Calibration */ +# define PMC_OCR_CAL4_MASK (0x7f << PMC_OCR_CAL4_SHIFT) +# define PMC_OCR_CAL4(n) ((uint32_t)(n) << PMC_OCR_CAL4_SHIFT) +# define PMC_OCR_SEL4 (1 << 7) /* Bit 7: Select 4MHz RC Oscillator Calibration */ +# define PMC_OCR_CAL8_SHIFT (8) /* Bits 8-14: 8MHzRC Oscillator Calibration */ +# define PMC_OCR_CAL8_MASK (0x7f << PMC_OCR_CAL8_SHIFT) +# define PMC_OCR_CAL8(n) ((uint32_t)(n) << PMC_OCR_CAL8_SHIFT) +# define PMC_OCR_SEL8 (1 << 15) /* Bit 15: Select 8MHz RC Oscillator Calibration */ +# define PMC_OCR_CAL12_SHIFT (16) /* Bits 16-22: 12MHzRC Oscillator Calibration */ +# define PMC_OCR_CAL12_MASK (0x7f << PMC_OCR_CAL12_SHIFT) +# define PMC_OCR_CAL12(n) ((uint32_t)(n) << PMC_OCR_CAL12_SHIFT) +# define PMC_OCR_SEL12 (1 << 23) /* Bit 23: Select 12MHz RC Oscillator Calibration */ +#endif + +/* PLL Maximum Multiplier Value Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PMC_PMMR_MASK (0x7ff) /* Bits 0-10: PLLA Maximum Allowed Multiplier */ +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_PMC_H */ diff --git a/arch/arm/src/sam34/chip/sam_pwm.h b/arch/arm/src/sam34/chip/sam_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..79b9aa043a9a36174f773ce207864d713dcfde3d --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_pwm.h @@ -0,0 +1,849 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_pwm.h + * Pulse Width Modulation Controller (PWM) definitions for the SAM3U, SAM4E and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_PWM_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_PWM_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* PWM register offsets *****************************************************************/ + +#define SAM_PWM_CLK_OFFSET 0x000 /* PWM Clock Register */ +#define SAM_PWM_ENA_OFFSET 0x004 /* PWM Enable Register */ +#define SAM_PWM_DIS_OFFSET 0x008 /* PWM Disable Register */ +#define SAM_PWM_SR_OFFSET 0x00c /* PWM Status Register */ +#define SAM_PWM_IER1_OFFSET 0x010 /* PWM Interrupt Enable Register 1 */ +#define SAM_PWM_IDR1_OFFSET 0x014 /* PWM Interrupt Disable Register 1 */ +#define SAM_PWM_IMR1_OFFSET 0x018 /* PWM Interrupt Mask Register 1 */ +#define SAM_PWM_ISR1_OFFSET 0x01c /* PWM Interrupt Status Register 1 */ +#define SAM_PWM_SCM_OFFSET 0x020 /* PWM Sync Channels Mode Register */ + /* 0x024: Reserved */ +#define SAM_PWM_SCUC_OFFSET 0x028 /* PWM Sync Channels Update Control Register */ +#define SAM_PWM_SCUP_OFFSET 0x02c /* PWM Sync Channels Update Period Register */ +#define SAM_PWM_SCUPUPD_OFFSET 0x030 /* PWM Sync Channels Update Period Update Register */ +#define SAM_PWM_IER2_OFFSET 0x034 /* PWM Interrupt Enable Register 2 */ +#define SAM_PWM_IDR2_OFFSET 0x038 /* PWM Interrupt Disable Register 2 */ +#define SAM_PWM_IMR2_OFFSET 0x03c /* PWM Interrupt Mask Register 2 */ +#define SAM_PWM_ISR2_OFFSET 0x040 /* PWM Interrupt Status Register 2 */ +#define SAM_PWM_OOV_OFFSET 0x044 /* PWM Output Override Value Register */ +#define SAM_PWM_OS_OFFSET 0x048 /* PWM Output Selection Register */ +#define SAM_PWM_OSS_OFFSET 0x04c /* PWM Output Selection Set Register */ +#define SAM_PWM_OSC_OFFSET 0x050 /* PWM Output Selection Clear Register */ +#define SAM_PWM_OSSUPD_OFFSET 0x054 /* PWM Output Selection Set Update Register */ +#define SAM_PWM_OSCUPD_OFFSET 0x058 /* PWM Output Selection Clear Update Register */ +#define SAM_PWM_FMR_OFFSET 0x05c /* PWM Fault Mode Register */ +#define SAM_PWM_FSR_OFFSET 0x060 /* PWM Fault Status Register */ +#define SAM_PWM_FCR_OFFSET 0x064 /* PWM Fault Clear Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_FPV1_OFFSET 0x068 /* PWM Fault Protection Value Register 1 */ +#else +# define SAM_PWM_FPV_OFFSET 0x068 /* PWM Fault Protection Value Register */ +#endif + +#define SAM_PWM_FPE_OFFSET 0x06c /* PWM Fault Protection Enable Register */ + /* 0x070-0x078: Reserved */ +#define SAM_PWM_ELMR0_OFFSET 0x07c /* PWM Event Line 0 Mode Register */ +#define SAM_PWM_ELMR1_OFFSET 0x080 /* PWM Event Line 1 Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_SSPR_OFFSET 0x0a0 /* PWM Spread Spectrum Register */ +# define SAM_PWM_SSPUP_OFFSET 0x0a4 /* PWM Spread Spectrum Update Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_SMMR_OFFSET 0x0b0 /* PWM Stepper Motor Mode Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_FPV2_OFFSET 0x0c0 /* PWM Fault Protection Value 2 Register */ +#endif + +#define SAM_PWM_WPCR_OFFSET 0x0e4 /* PWM Write Protect Control Register */ +#define SAM_PWM_WPSR_OFFSET 0x0e8 /* PWM Write Protect Status Register */ + /* 0x100-0x128: Reserved for PDC registers */ + /* 0x12c: Reserved */ +/* PWM Comparison Registers */ + +#define SAM_PWMCMP_OFFSET(n) (0x130+((n)<<4)) +#define SAM_PWMCMP_V_OFFSET 0x00 /* PWM Comparison Value Register */ +#define SAM_PWMCMP_VUPD_OFFSET 0x04 /* PWM Comparison Value Update Register */ +#define SAM_PWMCMP_M_OFFSET 0x08 /* PWM Comparison Mode Register */ +#define SAM_PWMCMP_MUPD_OFFSET 0x0c /* PWM Comparison Mode Update Register */ + +#define SAM_PWMCMP0_V_OFFSET 0x130 /* PWM Comparison 0 Value Register */ +#define SAM_PWMCMP0_VUPD_OFFSET 0x134 /* PWM Comparison 0 Value Update Register */ +#define SAM_PWMCMP0_M_OFFSET 0x138 /* PWM Comparison 0 Mode Register */ +#define SAM_PWMCMP0_MUPD_OFFSET 0x13c /* PWM Comparison 0 Mode Update Register */ + +#define SAM_PWMCMP1_V_OFFSET 0x140 /* PWM Comparison 1 Value Register */ +#define SAM_PWMCMP1_VUPD_OFFSET 0x144 /* PWM Comparison 1 Value Update Register */ +#define SAM_PWMCMP1_M_OFFSET 0x148 /* PWM Comparison 1 Mode Register */ +#define SAM_PWMCMP1_MUPD_OFFSET 0x14c /* PWM Comparison 1 Mode Update Register */ + +#define SAM_PWMCMP2_V_OFFSET 0x150 /* PWM Comparison 2 Value Register */ +#define SAM_PWMCMP2_VUPD_OFFSET 0x154 /* PWM Comparison 2 Value Update Register */ +#define SAM_PWMCMP2_M_OFFSET 0x158 /* PWM Comparison 2 Mode Register */ +#define SAM_PWMCMP2_MUPD_OFFSET 0x15c /* PWM Comparison 2 Mode Update Register */ + +#define SAM_PWMCMP3_V_OFFSET 0x160 /* PWM Comparison 3 Value Register */ +#define SAM_PWMCMP3_VUPD_OFFSET 0x164 /* PWM Comparison 3 Value Update Register */ +#define SAM_PWMCMP3_M_OFFSET 0x168 /* PWM Comparison 3 Mode Register */ +#define SAM_PWMCMP3_MUPD_OFFSET 0x16c /* PWM Comparison 3 Mode Update Register */ + +#define SAM_PWMCMP4_V_OFFSET 0x170 /* PWM Comparison 4 Value Register */ +#define SAM_PWMCMP4_VUPD_OFFSET 0x174 /* PWM Comparison 4 Value Update Register */ +#define SAM_PWMCMP4_M_OFFSET 0x178 /* PWM Comparison 4 Mode Register */ +#define SAM_PWMCMP4_MUPD_OFFSET 0x17c /* PWM Comparison 4 Mode Update Register */ + +#define SAM_PWMCMP5_V_OFFSET 0x180 /* PWM Comparison 5 Value Register */ +#define SAM_PWMCMP5_VUPD_OFFSET 0x184 /* PWM Comparison 5 Value Update Register */ +#define SAM_PWMCMP5_M_OFFSET 0x188 /* PWM Comparison 5 Mode Register */ +#define SAM_PWMCMP5_MUPD_OFFSET 0x18c /* PWM Comparison 5 Mode Update Register */ + +#define SAM_PWMCMP6_V_OFFSET 0x190 /* PWM Comparison 6 Value Register */ +#define SAM_PWMCMP6_VUPD_OFFSET 0x194 /* PWM Comparison 6 Value Update Register */ +#define SAM_PWMCMP6_M_OFFSET 0x198 /* PWM Comparison 6 Mode Register */ +#define SAM_PWMCMP6_MUPD_OFFSET 0x19c /* PWM Comparison 6 Mode Update Register */ + +#define SAM_PWMCMP7_V_OFFSET 0x1a0 /* PWM Comparison 7 Value Register */ +#define SAM_PWMCMP7_VUPD_OFFSET 0x1a4 /* PWM Comparison 7 Value Update Register */ +#define SAM_PWMCMP7_M_OFFSET 0x1a8 /* PWM Comparison 7 Mode Register */ +#define SAM_PWMCMP7_MUPD_OFFSET 0x1ac /* PWM Comparison 7 Mode Update Register */ + /* 0x1b0-0x1fc: Reserved */ +/* PWM Channel Registers */ + +#define SAM_PWMCH_OFFSET(n) (0x200+((n)<< 5)) +#define SAM_PWMCH_MR_OFFSET 0x00 /* PWM Channel Mode Register */ +#define SAM_PWMCH_DTY_OFFSET 0x04 /* PWM Channel Duty Cycle Register */ +#define SAM_PWMCH_DTYUPD_OFFSET 0x08 /* PWM Channel Duty Cycle Update Register */ +#define SAM_PWMCH_PRD_OFFSET 0x0c /* PWM Channel Period Register */ +#define SAM_PWMCH_PRDUPD_OFFSET 0x10 /* PWM Channel Period Update Register */ +#define SAM_PWMCH_CCNT_OFFSET 0x14 /* PWM Channel Counter Register */ +#define SAM_PWMCH_DT_OFFSET 0x18 /* PWM Channel Dead Time Register */ +#define SAM_PWMCH_DTUPD_OFFSET 0x1c /* PWM Channel Dead Time Update Register */ + +#define SAM_PWMCH0_MR_OFFSET 0x200 /* PWM Channel 0 Mode Register */ +#define SAM_PWMCH0_DTY_OFFSET 0x204 /* PWM Channel 0 Duty Cycle Register */ +#define SAM_PWMCH0_DTYUPD_OFFSET 0x208 /* PWM Channel 0 Duty Cycle Update Register */ +#define SAM_PWMCH0_PRD_OFFSET 0x20c /* PWM Channel 0 Period Register */ +#define SAM_PWMCH0_PRDUPD_OFFSET 0x210 /* PWM Channel 0 Period Update Register */ +#define SAM_PWMCH0_CCNT_OFFSET 0x214 /* PWM Channel 0 Counter Register */ +#define SAM_PWMCH0_DT_OFFSET 0x218 /* PWM Channel 0 Dead Time Register */ +#define SAM_PWMCH0_DTUPD_OFFSET 0x21c /* PWM Channel 0 Dead Time Update Register */ + +#define SAM_PWMCH1_MR_OFFSET 0x220 /* PWM Channel 1 Mode Register */ +#define SAM_PWMCH1_DTY_OFFSET 0x224 /* PWM Channel 1 Duty Cycle Register */ +#define SAM_PWMCH1_DTYUPD_OFFSET 0x228 /* PWM Channel 1 Duty Cycle Update Register */ +#define SAM_PWMCH1_PRD_OFFSET 0x22c /* PWM Channel 1 Period Register */ +#define SAM_PWMCH1_PRDUPD_OFFSET 0x230 /* PWM Channel 1 Period Update Register */ +#define SAM_PWMCH1_CCNT_OFFSET 0x234 /* PWM Channel 1 Counter Register */ +#define SAM_PWMCH1_DT_OFFSET 0x238 /* PWM Channel 1 Dead Time Register */ +#define SAM_PWMCH1_DTUPD_OFFSET 0x23c /* PWM Channel 1 Dead Time Update Register */ + +#define SAM_PWMCH2_MR_OFFSET 0x240 /* PWM Channel 2 Mode Register */ +#define SAM_PWMCH2_DTY_OFFSET 0x244 /* PWM Channel 2 Duty Cycle Register */ +#define SAM_PWMCH2_DTYUPD_OFFSET 0x248 /* PWM Channel 2 Duty Cycle Update Register */ +#define SAM_PWMCH2_PRD_OFFSET 0x24c /* PWM Channel 2 Period Register */ +#define SAM_PWMCH2_PRDUPD_OFFSET 0x250 /* PWM Channel 2 Period Update Register */ +#define SAM_PWMCH2_CCNT_OFFSET 0x254 /* PWM Channel 2 Counter Register */ +#define SAM_PWMCH2_DT_OFFSET 0x258 /* PWM Channel 2 Dead Time Register */ +#define SAM_PWMCH2_DTUPD_OFFSET 0x25c /* PWM Channel 2 Dead Time Update Register */ + +#define SAM_PWMCH3_MR_OFFSET 0x260 /* PWM Channel 3 Mode Register */ +#define SAM_PWMCH3_DTY_OFFSET 0x264 /* PWM Channel 3 Duty Cycle Register */ +#define SAM_PWMCH3_DTYUPD_OFFSET 0x268 /* PWM Channel 3 Duty Cycle Update Register */ +#define SAM_PWMCH3_PRD_OFFSET 0x26c /* PWM Channel 3 Period Register */ +#define SAM_PWMCH3_PRDUPD_OFFSET 0x270 /* PWM Channel 3 Period Update Register */ +#define SAM_PWMCH3_CCNT_OFFSET 0x274 /* PWM Channel 3 Counter Register */ +#define SAM_PWMCH3_DT_OFFSET 0x278 /* PWM Channel 3 Dead Time Register */ +#define SAM_PWMCH3_DTUPD_OFFSET 0x27c /* PWM Channel 3 Dead Time Update Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWMCH_OFFSET2(n) (0x400+((n)<< 5)) +# define SAM_PWMCH_CMUPD_OFFSET 0x0000 /* PWM Channel Mode Update Register */ +# define SAM_PWMCH_CAE_OFFSET 0x0004 /* PWM Channel Additional Edge Register */ +# define SAM_PWMCH_CAEUPD_OFFSET 0x0008 /* PWM Channel Additional Edge Update Register */ + +# define SAM_PWMCH0_CMUPD_OFFSET 0x0400 /* PWM Channel 0 Mode Update Register */ +# define SAM_PWMCH0_CAE_OFFSET 0x0404 /* PWM Channel 0 Additional Edge Register */ +# define SAM_PWMCH0_CAEUPD_OFFSET 0x0408 /* PWM Channel 0 Additional Edge Update Register */ + +# define SAM_PWMCH1_CMUPD_OFFSET 0x0420 /* PWM Channel 1 Mode Update Register */ +# define SAM_PWMCH1_CAE_OFFSET 0x0424 /* PWM Channel 1 Additional Edge Register */ +# define SAM_PWMCH1_CAEUPD_OFFSET 0x0428 /* PWM Channel 1 Additional Edge Update Register */ + +# define SAM_PWMCH2_CMUPD_OFFSET 0x0440 /* PWM Channel 2 Mode Update Register */ +# define SAM_PWMCH2_CAE_OFFSET 0x0444 /* PWM Channel 2 Additional Edge Register */ +# define SAM_PWMCH2_CAEUPD_OFFSET 0x0448 /* PWM Channel 2 Additional Edge Update Register */ + +# define SAM_PWMCH3_CMUPD_OFFSET 0x0460 /* PWM Channel 3 Mode Update Register */ +# define SAM_PWMCH3_CAE_OFFSET 0x0464 /* PWM Channel 3 Additional Edge Register */ +# define SAM_PWMCH3_CAEUPD_OFFSET 0x0468 /* PWM Channel 3 Additional Edge Update Register */ +#endif + +/* PWM register addresses ***************************************************************/ + +#define SAM_PWM_CLK (SAM_PWM_BASE+SAM_PWM_CLK_OFFSET) +#define SAM_PWM_ENA (SAM_PWM_BASE+SAM_PWM_ENA_OFFSET) +#define SAM_PWM_DIS (SAM_PWM_BASE+SAM_PWM_DIS_OFFSET) +#define SAM_PWM_SR (SAM_PWM_BASE+SAM_PWM_SR_OFFSET) +#define SAM_PWM_IER1 (SAM_PWM_BASE+SAM_PWM_IER1_OFFSET) +#define SAM_PWM_IDR1 (SAM_PWM_BASE+SAM_PWM_IDR1_OFFSET) +#define SAM_PWM_IMR1 (SAM_PWM_BASE+SAM_PWM_IMR1_OFFSET) +#define SAM_PWM_ISR1 (SAM_PWM_BASE+SAM_PWM_ISR1_OFFSET) +#define SAM_PWM_SCM (SAM_PWM_BASE+SAM_PWM_SCM_OFFSET) +#define SAM_PWM_SCUC (SAM_PWM_BASE+SAM_PWM_SCUC_OFFSET) +#define SAM_PWM_SCUP (SAM_PWM_BASE+SAM_PWM_SCUP_OFFSET) +#define SAM_PWM_SCUPUPD (SAM_PWM_BASE+SAM_PWM_SCUPUPD_OFFSET) +#define SAM_PWM_IER2 (SAM_PWM_BASE+SAM_PWM_IER2_OFFSET) +#define SAM_PWM_IDR2 (SAM_PWM_BASE+SAM_PWM_IDR2_OFFSET) +#define SAM_PWM_IMR2 (SAM_PWM_BASE+SAM_PWM_IMR2_OFFSET) +#define SAM_PWM_ISR2 (SAM_PWM_BASE+SAM_PWM_ISR2_OFFSET) +#define SAM_PWM_OOV (SAM_PWM_BASE+SAM_PWM_OOV_OFFSET) +#define SAM_PWM_OS (SAM_PWM_BASE+SAM_PWM_OS_OFFSET) +#define SAM_PWM_OSS (SAM_PWM_BASE+SAM_PWM_OSS_OFFSET) +#define SAM_PWM_OSC (SAM_PWM_BASE+SAM_PWM_OSC_OFFSET) +#define SAM_PWM_OSSUPD (SAM_PWM_BASE+SAM_PWM_OSSUPD_OFFSET) +#define SAM_PWM_OSCUPD (SAM_PWM_BASE+SAM_PWM_OSCUPD_OFFSET) +#define SAM_PWM_FMR (SAM_PWM_BASE+SAM_PWM_FMR_OFFSET) +#define SAM_PWM_FSR (SAM_PWM_BASE+SAM_PWM_FSR_OFFSET) +#define SAM_PWM_FCR (SAM_PWM_BASE+SAM_PWM_FCR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_FPV1 (SAM_PWM_BASE+SAM_PWM_FPV1_OFFSET) +#else +# define SAM_PWM_FPV (SAM_PWM_BASE+SAM_PWM_FPV_OFFSET) +#endif + +#define SAM_PWM_FPE (SAM_PWM_BASE+SAM_PWM_FPE_OFFSET) +#define SAM_PWM_ELMR0 (SAM_PWM_BASE+SAM_PWM_ELMR0_OFFSET) +#define SAM_PWM_ELMR1 (SAM_PWM_BASE+SAM_PWM_ELMR1_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_SSPR (SAM_PWM_BASE+SAM_PWM_SSPR_OFFSET) +# define SAM_PWM_SSPUP (SAM_PWM_BASE+SAM_PWM_SSPUP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_SMMR (SAM_PWM_BASE+SAM_PWM_SMMR_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWM_FPV2 (SAM_PWM_BASE+SAM_PWM_FPV2_OFFSET) +#endif + +#define SAM_PWM_WPCR (SAM_PWM_BASE+SAM_PWM_WPCR_OFFSET) +#define SAM_PWM_WPSR (SAM_PWM_BASE+SAM_PWM_WPSR_OFFSET) + +/* PWM Comparison Registers */ + +#define SAM_PWCMP_BASE(n) (SAM_PWM_BASE+SAM_PWCMP_OFFSET(n)) +#define SAM_PWMCMP0_BASE (SAM_PWM_BASE+0x0130) +#define SAM_PWMCMP1_BASE (SAM_PWM_BASE+0x0140) +#define SAM_PWMCMP2_BASE (SAM_PWM_BASE+0x0150) +#define SAM_PWMCMP3_BASE (SAM_PWM_BASE+0x0160) +#define SAM_PWMCMP4_BASE (SAM_PWM_BASE+0x0170) +#define SAM_PWMCMP5_BASE (SAM_PWM_BASE+0x0180) +#define SAM_PWMCMP6_BASE (SAM_PWM_BASE+0x0190) +#define SAM_PWMCMP7_BASE (SAM_PWM_BASE+0x01a0) + +#define SAM_PWMCMP0_V (SAM_PWMCMP0_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP0_VUPD (SAM_PWMCMP0_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP0_M (SAM_PWMCMP0_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP0_MUPD (SAM_PWMCMP0_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP1_V (SAM_PWMCMP1_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP1_VUPD (SAM_PWMCMP1_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP1_M (SAM_PWMCMP1_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP1_MUPD (SAM_PWMCMP1_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP2_V (SAM_PWMCMP2_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP2_VUPD (SAM_PWMCMP2_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP2_M (SAM_PWMCMP2_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP2_MUPD (SAM_PWMCMP2_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP3_V (SAM_PWMCMP3_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP3_VUPD (SAM_PWMCMP3_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP3_M (SAM_PWMCMP3_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP3_MUPD (SAM_PWMCMP3_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP4_V (SAM_PWMCMP4_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP4_VUPD (SAM_PWMCMP4_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP4_M (SAM_PWMCMP4_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP4_MUPD (SAM_PWMCMP4_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP5_V (SAM_PWMCMP5_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP5_VUPD (SAM_PWMCMP5_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP5_M (SAM_PWMCMP5_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP5_MUPD (SAM_PWMCMP5_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP6_V (SAM_PWMCMP6_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP6_VUPD (SAM_PWMCMP6_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP6_M (SAM_PWMCMP6_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP6_MUPD (SAM_PWMCMP6_BASE+SAM_PWMCMP_MUPD_OFFSET) + +#define SAM_PWMCMP7_V (SAM_PWMCMP7_BASE+SAM_PWMCMP_V_OFFSET) +#define SAM_PWMCMP7_VUPD (SAM_PWMCMP7_BASE+SAM_PWMCMP_VUPD_OFFSET) +#define SAM_PWMCMP7_M (SAM_PWMCMP7_BASE+SAM_PWMCMP_M_OFFSET) +#define SAM_PWMCMP7_MUPD (SAM_PWMCMP7_BASE+SAM_PWMCMP_MUPD_OFFSET) + +/* PWM Channel Registers */ + +#define SAM_PWCH_BASE(n) (SAM_PWM_BASE+SAM_PWCH_OFFSET(n)) +#define SAM_PWMCH0_BASE (SAM_PWM_BASE+0x0200) +#define SAM_PWMCH1_BASE (SAM_PWM_BASE+0x0220) +#define SAM_PWMCH2_BASE (SAM_PWM_BASE+0x0240) +#define SAM_PWMCH3_BASE (SAM_PWM_BASE+0x0260) + +#define SAM_PWMCH0_MR (SAM_PWMCH0_BASE+SAM_PWMCH_MR_OFFSET) +#define SAM_PWMCH0_DTY (SAM_PWMCH0_BASE+SAM_PWMCH_DTY_OFFSET) +#define SAM_PWMCH0_DTYUPD (SAM_PWMCH0_BASE+SAM_PWMCH_DTYUPD_OFFSET) +#define SAM_PWMCH0_PRD (SAM_PWMCH0_BASE+SAM_PWMCH_PRD_OFFSET) +#define SAM_PWMCH0_PRDUPD (SAM_PWMCH0_BASE+SAM_PWMCH_PRDUPD_OFFSET) +#define SAM_PWMCH0_CCNT (SAM_PWMCH0_BASE+SAM_PWMCH_CCNT_OFFSET) +#define SAM_PWMCH0_DT (SAM_PWMCH0_BASE+SAM_PWMCH_DT_OFFSET) +#define SAM_PWMCH0_DTUPD (SAM_PWMCH0_BASE+SAM_PWMCH_DTUPD_OFFSET) + +#define SAM_PWMCH1_MR (SAM_PWMCH1_BASE+SAM_PWMCH_MR_OFFSET) +#define SAM_PWMCH1_DTY (SAM_PWMCH1_BASE+SAM_PWMCH_DTY_OFFSET) +#define SAM_PWMCH1_DTYUPD (SAM_PWMCH1_BASE+SAM_PWMCH_DTYUPD_OFFSET) +#define SAM_PWMCH1_PRD (SAM_PWMCH1_BASE+SAM_PWMCH_PRD_OFFSET) +#define SAM_PWMCH1_PRDUPD (SAM_PWMCH1_BASE+SAM_PWMCH_PRDUPD_OFFSET) +#define SAM_PWMCH1_CCNT (SAM_PWMCH1_BASE+SAM_PWMCH_CCNT_OFFSET) +#define SAM_PWMCH1_DT (SAM_PWMCH1_BASE+SAM_PWMCH_DT_OFFSET) +#define SAM_PWMCH1_DTUPD (SAM_PWMCH1_BASE+SAM_PWMCH_DTUPD_OFFSET) + +#define SAM_PWMCH2_MR (SAM_PWMCH2_BASE+SAM_PWMCH_MR_OFFSET) +#define SAM_PWMCH2_DTY (SAM_PWMCH2_BASE+SAM_PWMCH_DTY_OFFSET) +#define SAM_PWMCH2_DTYUPD (SAM_PWMCH2_BASE+SAM_PWMCH_DTYUPD_OFFSET) +#define SAM_PWMCH2_PRD (SAM_PWMCH2_BASE+SAM_PWMCH_PRD_OFFSET) +#define SAM_PWMCH2_PRDUPD (SAM_PWMCH2_BASE+SAM_PWMCH_PRDUPD_OFFSET) +#define SAM_PWMCH2_CCNT (SAM_PWMCH2_BASE+SAM_PWMCH_CCNT_OFFSET) +#define SAM_PWMCH2_DT (SAM_PWMCH2_BASE+SAM_PWMCH_DT_OFFSET) +#define SAM_PWMCH2_DTUPD (SAM_PWMCH2_BASE+SAM_PWMCH_DTUPD_OFFSET) + +#define SAM_PWMCH3_MR (SAM_PWMCH3_BASE+SAM_PWMCH_MR_OFFSET) +#define SAM_PWMCH3_DTY (SAM_PWMCH3_BASE+SAM_PWMCH_DTY_OFFSET) +#define SAM_PWMCH3_DTYUPD (SAM_PWMCH3_BASE+SAM_PWMCH_DTYUPD_OFFSET) +#define SAM_PWMCH3_PRD (SAM_PWMCH3_BASE+SAM_PWMCH_PRD_OFFSET) +#define SAM_PWMCH3_PRDUPD (SAM_PWMCH3_BASE+SAM_PWMCH_PRDUPD_OFFSET) +#define SAM_PWMCH3_CCNT (SAM_PWMCH3_BASE+SAM_PWMCH_CCNT_OFFSET) +#define SAM_PWMCH3_DT (SAM_PWMCH3_BASE+SAM_PWMCH_DT_OFFSET) +#define SAM_PWMCH3_DTUPD (SAM_PWMCH3_BASE+SAM_PWMCH_DTUPD_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_PWMCH_BASE2(n) (SAM_PWM_BASE+SAM_PWMCH_OFFSET2(n)) +# define SAM_PWMCH0_BASE2 (SAM_PWM_BASE+0x0400) +# define SAM_PWMCH1_BASE2 (SAM_PWM_BASE+0x0420) +# define SAM_PWMCH2_BASE2 (SAM_PWM_BASE+0x0440) +# define SAM_PWMCH3_BASE2 (SAM_PWM_BASE+0x0450) + +# define SAM_PWMCH_CMUPD(n) (SAM_PWMCH_BASE2(n)+SAM_PWMCH_CMUPD_OFFSET) +# define SAM_PWMCH_CAE(n) (SAM_PWMCH_BASE2(n)+SAM_PWMCH_CAE_OFFSET) +# define SAM_PWMCH_CAEUPD(n) (SAM_PWMCH_BASE2(n)+SAM_PWMCH_CAEUPD_OFFSET) + +# define SAM_PWMCH0_CMUPD (SAM_PWMCH0_BASE2+SAM_PWMCH0_CMUPD_OFFSET) +# define SAM_PWMCH0_CAE (SAM_PWMCH0_BASE2+SAM_PWMCH0_CAE_OFFSET) +# define SAM_PWMCH0_CAEUPD (SAM_PWMCH0_BASE2+SAM_PWMCH0_CAEUPD_OFFSET) + +# define SAM_PWMCH1_CMUPD (SAM_PWMCH1_BASE2+SAM_PWMCH0_CMUPD_OFFSET) +# define SAM_PWMCH1_CAE (SAM_PWMCH1_BASE2+SAM_PWMCH0_CAE_OFFSET) +# define SAM_PWMCH1_CAEUPD (SAM_PWMCH1_BASE2+SAM_PWMCH0_CAEUPD_OFFSET) + +# define SAM_PWMCH2_CMUPD (SAM_PWMCH2_BASE2+SAM_PWMCH0_CMUPD_OFFSET) +# define SAM_PWMCH2_CAE (SAM_PWMCH2_BASE2+SAM_PWMCH0_CAE_OFFSET) +# define SAM_PWMCH2_CAEUPD (SAM_PWMCH2_BASE2+SAM_PWMCH0_CAEUPD_OFFSET) + +# define SAM_PWMCH3_CMUPD (SAM_PWMCH3_BASE2+SAM_PWMCH0_CMUPD_OFFSET) +# define SAM_PWMCH3_CAE (SAM_PWMCH3_BASE2+SAM_PWMCH0_CAE_OFFSET) +# define SAM_PWMCH3_CAEUPD (SAM_PWMCH3_BASE2+SAM_PWMCH0_CAEUPD_OFFSET) +#endif + +/* PWM register bit definitions *********************************************************/ + +/* PWM Clock Register */ + +#define PWM_CLK_DIVA_SHIFT (0) /* Bits 0-7: CLKA Divide Factor */ +#define PWM_CLK_DIVA_MASK (0xff << PWM_CLK_DIVA_SHIFT) +# define PWM_CLK_DIVA_OFF (0 << PWM_CLK_DIVA_SHIFT) +# define PWM_CLK_DIVA_NONE (1 << PWM_CLK_DIVA_SHIFT) +# define PWM_CLK_DIVA(n) ((uint32_t)(n) << PWM_CLK_DIVA_SHIFT) +#define PWM_CLK_PREA_SHIFT (8) /* Bits 8-11: CLKA Source Clock Selection */ +#define PWM_CLK_PREA_MASK (15 << PWM_CLK_PREA_SHIFT) +# define PWM_CLK_PREA_MCK (0 << PWM_CLK_PREA_SHIFT) /* MCK */ +# define PWM_CLK_PREA_MCKDIV2 (1 << PWM_CLK_PREA_SHIFT) /* MCK/2 */ +# define PWM_CLK_PREA_MCKDIV4 (2 << PWM_CLK_PREA_SHIFT) /* MCK/4 */ +# define PWM_CLK_PREA_MCKDIV8 (3 << PWM_CLK_PREA_SHIFT) /* MCK/8 */ +# define PWM_CLK_PREA_MCKDIV16 (4 << PWM_CLK_PREA_SHIFT) /* MCK/16 */ +# define PWM_CLK_PREA_MCKDIV32 (5 << PWM_CLK_PREA_SHIFT) /* MCK/32 */ +# define PWM_CLK_PREA_MCKDIV64 (6 << PWM_CLK_PREA_SHIFT) /* MCK/64 */ +# define PWM_CLK_PREA_MCKDIV128 (7 << PWM_CLK_PREA_SHIFT) /* MCK/128 */ +# define PWM_CLK_PREA_MCKDIV256 (8 << PWM_CLK_PREA_SHIFT) /* MCK/256 */ +# define PWM_CLK_PREA_MCKDIV512 (9 << PWM_CLK_PREA_SHIFT) /* MCK/512 */ +# define PWM_CLK_PREA_MCKDIV1024 (10 << PWM_CLK_PREA_SHIFT) /* MCK/1024 */ +#define PWM_CLK_DIVB_SHIFT (16) /* Bits 16-23: CLKB Divide Factor */ +#define PWM_CLK_DIVB_MASK (0xff << PWM_CLK_DIVB_SHIFT) +# define PWM_CLK_DIVB_OFF (0 << PWM_CLK_DIVB_SHIFT) +# define PWM_CLK_DIVB_NONE (1 << PWM_CLK_DIVB_SHIFT) +# define PWM_CLK_DIVB(n) ((uint32_t)(n) << PWM_CLK_DIVB_SHIFT) +#define PWM_CLK_PREB_SHIFT (24) /* Bit 24-27: CLKB Source Clock Selection */ +#define PWM_CLK_PREB_MASK (15 << PWM_CLK_PREB_SHIFT) +# define PWM_CLK_PREB_MCK (0 << PWM_CLK_PREB_SHIFT) /* MCK */ +# define PWM_CLK_PREB_MCKDIV2 (1 << PWM_CLK_PREB_SHIFT) /* MCK/2 */ +# define PWM_CLK_PREB_MCKDIV4 (2 << PWM_CLK_PREB_SHIFT) /* MCK/4 */ +# define PWM_CLK_PREB_MCKDIV8 (3 << PWM_CLK_PREB_SHIFT) /* MCK/8 */ +# define PWM_CLK_PREB_MCKDIV16 (4 << PWM_CLK_PREB_SHIFT) /* MCK/16 */ +# define PWM_CLK_PREB_MCKDIV32 (5 << PWM_CLK_PREB_SHIFT) /* MCK/32 */ +# define PWM_CLK_PREB_MCKDIV64 (6 << PWM_CLK_PREB_SHIFT) /* MCK/64 */ +# define PWM_CLK_PREB_MCKDIV128 (7 << PWM_CLK_PREB_SHIFT) /* MCK/128 */ +# define PWM_CLK_PREB_MCKDIV256 (8 << PWM_CLK_PREB_SHIFT) /* MCK/256 */ +# define PWM_CLK_PREB_MCKDIV512 (9 << PWM_CLK_PREB_SHIFT) /* MCK/512 */ +# define PWM_CLK_PREB_MCKDIV1024 (10 << PWM_CLK_PREB_SHIFT) /* MCK/1024 */ + +/* PWM Enable Register, PWM Disable Register, and PWM Status Register common bit-field definitions */ + +#define SAM_ENAB_CHID(n) (1 << ((n)) +# define SAM_ENAB_CHID0 (1 << 0) /* Bit 0: Counter Event Channel 0 Interrupt */ +# define SAM_ENAB_CHID1 (1 << 1) /* Bit 1: Counter Event Channel 1 Interrupt */ +# define SAM_ENAB_CHID2 (1 << 2) /* Bit 2: Counter Event Channel 2 Interrupt */ +# define SAM_ENAB_CHID3 (1 << 3) /* Bit 3: Counter Event Channel 3 Interrupt */ + +/* PWM Interrupt Enable Register 1, PWM Interrupt Disable Register 1, PWM Interrupt + * Mask Register 1, and PWM Interrupt Status Register 1 common bit definitions + */ + +#define SAM_INT_CHID(n) (1 << (n)) +# define SAM_INT_CHID0 (1 << 0) /* Bit 0: Counter Event Channel 0 Interrupt */ +# define SAM_INT_CHID1 (1 << 1) /* Bit 1: Counter Event Channel 1 Interrupt */ +# define SAM_INT_CHID2 (1 << 2) /* Bit 2: Counter Event Channel 2 Interrupt */ +# define SAM_INT_CHID3 (1 << 3) /* Bit 3: Counter Event Channel 3 Interrupt */ +#define SAM_INT_FCHID(n) (1 << ((n)+16)) +# define SAM_INT_FCHID0 (1 << 16) /* Bit 16: Fault Protection Trigger Channel 0 Interrupt */ +# define SAM_INT_FCHID1 (1 << 17) /* Bit 17: Fault Protection Trigger Channel 1 Interrupt */ +# define SAM_INT_FCHID2 (1 << 18) /* Bit 18: Fault Protection Trigger Channel 2 Interrupt */ +# define SAM_INT_FCHID3 (1 << 19) /* Bit 19: Fault Protection Trigger Channel 3 Interrupt */ + +/* PWM Sync Channels Mode Register */ + +#define PWM_SCM_SYNC(n) (1 << (n)) +# define PWM_SCM_SYNC0 (1 << 0) /* Bit 0: Synchronous Channel 0 */ +# define PWM_SCM_SYNC1 (1 << 1) /* Bit 1: Synchronous Channel 1 */ +# define PWM_SCM_SYNC2 (1 << 2) /* Bit 2: Synchronous Channel 2 */ +# define PWM_SCM_SYNC3 (1 << 3) /* Bit 3: Synchronous Channel 3 */ +#define PWM_SCM_UPDM_SHIFT (16) /* Bits 16-17: Synchronous Channels Update Mode */ +#define PWM_SCM_UPDM_MASK (3 << PWM_SCM_UPDM_SHIFT) +# define PWM_SCM_UPDM_MANMAN (0 << PWM_SCM_UPDM_SHIFT) /* Manual write/manual update */ +# define PWM_SCM_UPDM_MANAUTO (1 << PWM_SCM_UPDM_SHIFT) /* Manual write/automatic update */ +# define PWM_SCM_UPDM_AUTOAUTO (2 << PWM_SCM_UPDM_SHIFT) /* Auto write/automatic update */ +#define PWM_SCM_PTRM (1 << 20) /* Bit 20: PDC Transfer Request Mode */ +#define PWM_SCM_PTRCS_SHIFT (21) /* Bits 21-23: PDC Transfer Request Comparison Selection */ +#define PWM_SCM_PTRCS_MASK (7 << PWM_SCM_PTRCS_SHIFT) +# define PWM_SCM_PTRCS(n) ((uint32_t)(n) << PWM_SCM_PTRCS_SHIFT) + +/* PWM Sync Channels Update Control Register */ + +#define PWM_SCUC_UPDULOCK (1 << 0) /* Bit 0: Synchronous Channels Update Unlock */ + +/* PWM Sync Channels Update Period Register */ + +#define PWM_SCUP_UPR_SHIFT (0) /* Bits 0-3: Update Period */ +#define PWM_SCUP_UPR_MASK (15 << PWM_SCUP_UPR_MASK) +# define PWM_SCUP_UPR(n) ((uint32_t)(n) << PWM_SCUP_UPR_MASK) +#define PWM_SCUP_UPRCNT_SHIFT (4) /* Bits 4-7: Update Period Counter */ +#define PWM_SCUP_UPRCNT_MASK (15 << PWM_SCUP_UPRCNT_SHIFT) +# define PWM_SCUP_UPRCNT(n) ((uint32_t)(n) << PWM_SCUP_UPRCNT_SHIFT) + +/* PWM Sync Channels Update Period Update Register */ + +#define PWM_SCUPUPD_SHIFT (0) /* Bits 0-3: Update Period Update */ +#define PWM_SCUPUPD_MASK (15 << PWM_SCUPUPD_SHIFT) +# define PWM_SCUPUPD(n) ((uint32_t)(n) << PWM_SCUPUPD_SHIFT) + +/* PWM Interrupt Enable Register 2, PWM Interrupt Disable Register 2, PWM Interrupt Mask Register 2, and PWM Interrupt Status Register 2 common bit-field definitions */ + +#define SAM_INT_WRDY (1 << 0) /* Bit 0: Write Ready Update Interrupt */ +#define SAM_INT_ENDTX (1 << 1) /* Bit 1: PDC End of TX Buffer Interrupt */ +#define SAM_INT_TXBUFE (1 << 2) /* Bit 2: PDC TX Buffer Empty Interrupt */ +#define SAM_INT_UNRE (1 << 3) /* Bit 3: Synch Update Underrun Error Interrupt */ +#define SAM_INT_CMPM(n) (1 << ((n)+8)) +# define SAM_INT_CMPM0 (1 << 8) /* Bit 8: Comparison 0 Match Interrupt */ +# define SAM_INT_CMPM1 (1 << 9) /* Bit 9: Comparison 1 Match Interrupt */ +# define SAM_INT_CMPM2 (1 << 10) /* Bit 10: Comparison 2 Match Interrupt */ +# define SAM_INT_CMPM3 (1 << 11) /* Bit 11: Comparison 3 Match Interrupt */ +# define SAM_INT_CMPM4 (1 << 12) /* Bit 12: Comparison 4 Match Interrupt */ +# define SAM_INT_CMPM5 (1 << 13) /* Bit 13: Comparison 5 Match Interrupt */ +# define SAM_INT_CMPM6 (1 << 14) /* Bit 14: Comparison 6 Match Interrupt */ +# define SAM_INT_CMPM7 (1 << 15) /* Bit 15: Comparison 7 Match Interrupt */ +#define SAM_INT_CMPU(n) (1 << ((n)+16)) +# define SAM_INT_CMPU0 (1 << 16) /* Bit 16: Comparison o Update Interrupt */ +# define SAM_INT_CMPU1 (1 << 17) /* Bit 17: Comparison 1 Update Interrupt */ +# define SAM_INT_CMPU2 (1 << 18) /* Bit 18: Comparison 2 Update Interrupt */ +# define SAM_INT_CMPU3 (1 << 19) /* Bit 19: Comparison 3 Update Interrupt */ +# define SAM_INT_CMPU4 (1 << 20) /* Bit 20: Comparison 4 Update Interrupt */ +# define SAM_INT_CMPU5 (1 << 21) /* Bit 21: Comparison 5 Update Interrupt */ +# define SAM_INT_CMPU6 (1 << 22) /* Bit 22: Comparison 6 Update Interrupt */ +# define SAM_INT_CMPU7 (1 << 23) /* Bit 23: Comparison 7 Update Interrupt */ + +/* PWM Output Override Value Register, PWM Output Selection Register, PWM Output + * Selection Set Register, PWM Output Selection Clear Register, PWM Output Selection + * Set Update Register, and PWM Output Selection Clear Update Register common bit-field + * definitions + */ + +#define PWM_OUT_OH(n) (1 << (n)) +# define PWM_OUT_OH0 (1 << 0) /* Bit 0: Value for PWMH output of the channel 0 */ +# define PWM_OUT_OH1 (1 << 1) /* Bit 1: Value for PWMH output of the channel 1 */ +# define PWM_OUT_OH2 (1 << 2) /* Bit 2: Value for PWMH output of the channel 2 */ +# define PWM_OUT_OH3 (1 << 3) /* Bit 3: Value for PWMH output of the channel 3 */ +#define PWM_OUT_OL(n) (1 << ((n)+16)) +# define PWM_OUT_OL0 (1 << 16) /* Bit 16: Value for PWML output of the channel 0 */ +# define PWM_OUT_OL1 (1 << 17) /* Bit 17: Value for PWML output of the channel 1 */ +# define PWM_OUT_OL2 (1 << 18) /* Bit 18: Value for PWML output of the channel 2 */ +# define PWM_OUT_OL3 (1 << 19) /* Bit 19: Value for PWML output of the channel 3 */ + +/* PWM Fault Mode Register */ + +#define PWM_FMR_FPOL(n) (1 << (n)) +# define PWM_FMR_FPOL0 (1 << 0) /* Bit 0: Fault 0 Polarity */ +# define PWM_FMR_FPOL1 (1 << 1) /* Bit 1: Fault 1 Polarity */ +# define PWM_FMR_FPOL2 (1 << 2) /* Bit 2: Fault 2 Polarity */ +# define PWM_FMR_FPOL3 (1 << 3) /* Bit 3: Fault 3 Polarity */ +# define PWM_FMR_FPOL4 (1 << 4) /* Bit 4: Fault 4 Polarity */ +# define PWM_FMR_FPOL5 (1 << 5) /* Bit 5: Fault 5 Polarity */ +# define PWM_FMR_FPOL6 (1 << 6) /* Bit 6: Fault 6 Polarity */ +# define PWM_FMR_FPOL7 (1 << 7) /* Bit 7: Fault 7 Polarity */ +#define PWM_FMR_FMOD(n) (1 << ((n)+8)) +# define PWM_FMR_FMOD0 (1 << 8) /* Bit 8: Fault 0 Activation Mode */ +# define PWM_FMR_FMOD1 (1 << 9) /* Bit 9: Fault 1 Activation Mode */ +# define PWM_FMR_FMOD2 (1 << 10) /* Bit 10: Fault 2 Activation Mode */ +# define PWM_FMR_FMOD3 (1 << 11) /* Bit 11: Fault 3 Activation Mode */ +# define PWM_FMR_FMOD4 (1 << 12) /* Bit 12: Fault 4 Activation Mode */ +# define PWM_FMR_FMOD5 (1 << 13) /* Bit 13: Fault 5 Activation Mode */ +# define PWM_FMR_FMOD6 (1 << 14) /* Bit 14: Fault 6 Activation Mode */ +# define PWM_FMR_FMOD7 (1 << 15) /* Bit 15: Fault 7 Activation Mode */ +#define PWM_FMR_FFIL(n) (1 << ((n)+16)) +#define PWM_FMR_FFIL0 (1 << 16) /* Bit 16: Fault 0 Filter */ +#define PWM_FMR_FFIL1 (1 << 17) /* Bit 17: Fault 1 Filter */ +#define PWM_FMR_FFIL2 (1 << 18) /* Bit 18: Fault 2 Filter */ +#define PWM_FMR_FFIL3 (1 << 19) /* Bit 19: Fault 3 Filter */ +#define PWM_FMR_FFIL4 (1 << 20) /* Bit 20: Fault 4 Filter */ +#define PWM_FMR_FFIL5 (1 << 21) /* Bit 21: Fault 5 Filter */ +#define PWM_FMR_FFIL6 (1 << 22) /* Bit 22: Fault 6 Filter */ +#define PWM_FMR_FFIL7 (1 << 23) /* Bit 23: Fault 7 Filter */ + +/* PWM Fault Status Register */ + +#define PWM_FSR_FIV(n) (1 << (n)) +# define PWM_FSR_FIV0 (1 << 0) /* Bit 0: Fault Input 0 Value */ +# define PWM_FSR_FIV1 (1 << 1) /* Bit 1: Fault Input 1 Value */ +# define PWM_FSR_FIV2 (1 << 2) /* Bit 2: Fault Input 2 Value */ +# define PWM_FSR_FIV3 (1 << 3) /* Bit 3: Fault Input 3 Value */ +# define PWM_FSR_FIV4 (1 << 4) /* Bit 4: Fault Input 4 Value */ +# define PWM_FSR_FIV5 (1 << 5) /* Bit 5: Fault Input 5 Value */ +# define PWM_FSR_FIV6 (1 << 6) /* Bit 6: Fault Input 6 Value */ +# define PWM_FSR_FIV7 (1 << 7) /* Bit 7: Fault Input 7 Value */ +#define PWM_FSR_FS(n) (1 << ((n)+8)) +# define PWM_FSR_FS0 (1 << 8) /* Bit 8: Fault 0 Status */ +# define PWM_FSR_FS1 (1 << 9) /* Bit 9: Fault 1 Status */ +# define PWM_FSR_FS2 (1 << 10) /* Bit 10: Fault 2 Status */ +# define PWM_FSR_FS3 (1 << 11) /* Bit 11: Fault 3 Status */ +# define PWM_FSR_FS4 (1 << 12) /* Bit 12: Fault 4 Status */ +# define PWM_FSR_FS5 (1 << 13) /* Bit 13: Fault 5 Status */ +# define PWM_FSR_FS6 (1 << 14) /* Bit 14: Fault 6 Status */ +# define PWM_FSR_FS7 (1 << 15) /* Bit 15: Fault 7 Status */ + +/* PWM Fault Clear Register */ + +#define PWM_FCR_FCLR(n) (1 << (n)) +# define PWM_FCR_FCLR0 (1 << 0) /* Bit 0: Fault 0 Clear */ +# define PWM_FCR_FCLR1 (1 << 1) /* Bit 1: Fault 1 Clear */ +# define PWM_FCR_FCLR2 (1 << 2) /* Bit 2: Fault 2 Clear */ +# define PWM_FCR_FCLR3 (1 << 3) /* Bit 3: Fault 3 Clear */ +# define PWM_FCR_FCLR4 (1 << 4) /* Bit 4: Fault 4 Clear */ +# define PWM_FCR_FCLR5 (1 << 5) /* Bit 5: Fault 5 Clear */ +# define PWM_FCR_FCLR6 (1 << 6) /* Bit 6: Fault 6 Clear */ +# define PWM_FCR_FCLR7 (1 << 7) /* Bit 7: Fault 7 Clear */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +/* PWM Fault Protection Value Register 1 */ + +# define PWM_FPV1_FPVH(n) (1 << (n)) +# define PWM_FPV1_FPVH0 (1 << 0) /* Bit 0: Fault Protection Value PWMH output channel 0 */ +# define PWM_FPV1_FPVH1 (1 << 1) /* Bit 1: Fault Protection Value PWMH output channel 1 */ +# define PWM_FPV1_FPVH2 (1 << 2) /* Bit 2: Fault Protection Value PWMH output channel 2 */ +# define PWM_FPV1_FPVH3 (1 << 3) /* Bit 3: Fault Protection Value PWMH output channel 3 */ +# define PWM_FPV1_FPVL(n) (1 << ((n)+16)) +# define PWM_FPV1_FPVL0 (1 << 16) /* Bit 16: Fault Protection Value PWML output channel 0 */ +# define PWM_FPV1_FPVL1 (1 << 17) /* Bit 17: Fault Protection Value PWML output channel 1 */ +# define PWM_FPV1_FPVL2 (1 << 18) /* Bit 18: Fault Protection Value PWML output channel 2 */ +# define PWM_FPV1_FPVL3 (1 << 19) /* Bit 19: Fault Protection Value PWML output channel 3 */ + +#else +/* PWM Fault Protection Value Register */ + +# define PWM_FPV_FPVH(n) (1 << (n)) +# define PWM_FPV_FPVH0 (1 << 0) /* Bit 0: Fault Protection Value PWMH output channel 0 */ +# define PWM_FPV_FPVH1 (1 << 1) /* Bit 1: Fault Protection Value PWMH output channel 1 */ +# define PWM_FPV_FPVH2 (1 << 2) /* Bit 2: Fault Protection Value PWMH output channel 2 */ +# define PWM_FPV_FPVH3 (1 << 3) /* Bit 3: Fault Protection Value PWMH output channel 3 */ +# define PWM_FPV_FPVL(n) (1 << ((n)+16)) +# define PWM_FPV_FPVL0 (1 << 16) /* Bit 16: Fault Protection Value PWML output channel 0 */ +# define PWM_FPV_FPVL1 (1 << 17) /* Bit 17: Fault Protection Value PWML output channel 1 */ +# define PWM_FPV_FPVL2 (1 << 18) /* Bit 18: Fault Protection Value PWML output channel 2 */ +# define PWM_FPV_FPVL3 (1 << 19) /* Bit 19: Fault Protection Value PWML output channel 3 */ +#endif + +/* PWM Fault Protection Enable Register */ + +#define PWM_FPE_FPEN(n,y) (1 << (((n)<<8)+y)) +# define PWM_FPE_FPE0(y) (1 << (y)) /* Bits 0-7: Fault Protection Enable Fault=y chan=0 */ +# define PWM_FPE_FPE1(y) (1 << ((y)+8)) /* Bits 8-15: Fault Protection Enable Fault=y chan=1 */ +# define PWM_FPE_FPE2(y) (1 << ((y)+16)) /* Bits 16-23: Fault Protection Enable Fault=y chan=2 */ +# define PWM_FPE_FPE3(y) (1 << ((y)+24) /* Bits 24-31: Fault Protection Enable Fault=y chan=3 */ + +/* PWM Event Line 1/2 Register */ + +#define PWM_ELMR_CSEL(n) (1 << (n)) +# define PWM_ELMR_CSEL0 (1 << 0) /* Bit 0: Comparison 0 Selection */ +# define PWM_ELMR_CSEL1 (1 << 1) /* Bit 1: Comparison 1 Selection */ +# define PWM_ELMR_CSEL2 (1 << 2) /* Bit 2: Comparison 2 Selection */ +# define PWM_ELMR_CSEL3 (1 << 3) /* Bit 3: Comparison 3 Selection */ +# define PWM_ELMR_CSEL4 (1 << 4) /* Bit 4: Comparison 4 Selection */ +# define PWM_ELMR_CSEL5 (1 << 5) /* Bit 5: Comparison 5 Selection */ +# define PWM_ELMR_CSEL6 (1 << 6) /* Bit 6: Comparison 6 Selection */ +# define PWM_ELMR_CSEL7 (1 << 7) /* Bit 7: Comparison 7 Selection */ + +/* PWM Spread Spectrum Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWM_SSPR_SPRD_SHIFT (0) /* Bits 0-23: Spread Spectrum Limit Value */ +# define PWM_SSPR_SPRD_MASK (0x00ffffff << PWM_SSPR_SPRD_SHIFT) +# define PWM_SSPR_SPRD(n) ((uint32_t)(n) << PWM_SSPR_SPRD_SHIFT) +# define PWM_SSPR_SPRDM (1 << 24) /* Bit 24: Spread Spectrum Counter Mode */ +#endif + +/* PWM Spread Spectrum Update Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWM_SSPUP_MASK (0x00ffffff) /* Bits 0-23: Spread Spectrum Limit Value Update */ +#endif + +/* PWM Stepper Motor Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWM_SMMR_GCEN_SHIFT (0) /* Bits 0-1: Gray Count ENable */ +# define PWM_SMMR_GCEN_MASK (3 << PWM_SMMR_GCEN_SHIFT) +# define PWM_SMMR_GCEN0 (1 << 0) /* Bit 0: Gray Count ENable on PWML/H 0/1 */ +# define PWM_SMMR_GCEN1 (1 << 1) /* Bit 1: Gray Count ENable on PWML/H 2/3 */ +# define PWM_SMMR_DOWN_SHIFT (16) /* Bits 16-17: DOWN Count */ +# define PWM_SMMR_DOWN_MASK (3 << PWM_SMMR_DOWN_SHIFT) +# define PWM_SMMR_DOWN0 (1 << 16) /* Bit 16: DOWN Counter on PWML/H 0/1 */ +# define PWM_SMMR_DOWN1 (1 << 17) /* Bit 17: DOWN Counter on PWML/H 2/3 */ +#endif + +/* PWM Fault Protection Value 2 Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWM_FPV2_FPVH(n) (1 << (n)) +# define PWM_FPV2_FPZH0 (1 << 0) /* Bit 0: Fault Protection to Hi-Z PWMH output channel 0 */ +# define PWM_FPV2_FPZH1 (1 << 1) /* Bit 1: Fault Protection to Hi-Z PWMH output channel 1 */ +# define PWM_FPV2_FPZH2 (1 << 2) /* Bit 2: Fault Protection to Hi-Z PWMH output channel 2 */ +# define PWM_FPV2_FPZH3 (1 << 3) /* Bit 3: Fault Protection to Hi-Z PWMH output channel 3 */ +# define PWM_FPV2_FPVL(n) (1 << ((n)+16)) +# define PWM_FPV2_FPZL0 (1 << 16) /* Bit 16: Fault Protection to Hi-Z PWML output channel 0 */ +# define PWM_FPV2_FPZL1 (1 << 17) /* Bit 17: Fault Protection to Hi-Z PWML output channel 1 */ +# define PWM_FPV2_FPZL2 (1 << 18) /* Bit 18: Fault Protection to Hi-Z PWML output channel 2 */ +# define PWM_FPV2_FPZL3 (1 << 19) /* Bit 19: Fault Protection to Hi-Z PWML output channel 3 */ +#endif + +/* PWM Write Protect Control Register */ + +#define PWM_WPCR_WPCMD_SHIFT (0) /* Bits 0-1: Write Protect Command */ +#define PWM_WPCR_WPCMD_MASK (3 << PWM_WPCR_WPCMD_SHIFT) +# define PWM_WPCR_WPRG(n) (1 << ((n)+2)) +# define PWM_WPCR_WPRG0 (1 << 2) /* Bit 2: Write Protect Register Group 0 */ +# define PWM_WPCR_WPRG1 (1 << 3) /* Bit 3: Write Protect Register Group 1 */ +# define PWM_WPCR_WPRG2 (1 << 4) /* Bit 4: Write Protect Register Group 2 */ +# define PWM_WPCR_WPRG3 (1 << 5) /* Bit 5: Write Protect Register Group 3 */ +# define PWM_WPCR_WPRG4 (1 << 6) /* Bit 6: Write Protect Register Group 4 */ +# define PWM_WPCR_WPRG5 (1 << 7) /* Bit 7: Write Protect Register Group 5 */ +#define PWM_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect Key */ +#define PWM_WPCR_WPKEY_MASK (0x00ffffff << PWM_WPCR_WPKEY_SHIFT) +# define PWM_WPCR_WPKEY (0x0050574d << PWM_WPCR_WPKEY_SHIFT) + +/* PWM Write Protect Status Register */ + +#define PWM_WPSR_WPSWS(n) (1 << (n)) +# define PWM_WPSR_WPSWS0 (1 << 0) /* Bit 0: Write Protect SW Status */ +# define PWM_WPSR_WPSWS1 (1 << 1) /* Bit 1: Write Protect SW Status */ +# define PWM_WPSR_WPSWS2 (1 << 2) /* Bit 2: Write Protect SW Status */ +# define PWM_WPSR_WPSWS3 (1 << 3) /* Bit 3: Write Protect SW Status */ +# define PWM_WPSR_WPSWS4 (1 << 4) /* Bit 4: Write Protect SW Status */ +# define PWM_WPSR_WPSWS5 (1 << 5) /* Bit 5: Write Protect SW Status */ +#define PWM_WPSR_WPVS (1 << 7) /* Bit 7: Write Protect Violation Status */ +#define PWM_WPSR_WPHWS(n) (1 << ((n)+8)) +# define PWM_WPSR_WPHWS0 (1 << 8) /* Bit 8: Write Protect HW Status */ +# define PWM_WPSR_WPHWS1 (1 << 9) /* Bit 9: Write Protect HW Status */ +# define PWM_WPSR_WPHWS2 (1 << 10) /* Bit 10: Write Protect HW Status */ +# define PWM_WPSR_WPHWS3 (1 << 11) /* Bit 11: Write Protect HW Status */ +# define PWM_WPSR_WPHWS4 (1 << 12) /* Bit 12: Write Protect HW Status */ +# define PWM_WPSR_WPHWS5 (1 << 13) /* Bit 13: Write Protect HW Status */ +#define PWM_WPSR_WPVSRC_SHIFT (16) /* Bits 16-31: Write Protect Violation Source */ +#define PWM_WPSR_WPVSRC_MASK (0xffff << PWM_WPSR_WPVSRC_SHIFT) + +/* PWM Comparison x Value Register and PWM Comparison x Value Update Register */ + +#define PWMCMP_CV_SHIFT (0) /* Bits 0-23: Comparison x Value */ +#define PWMCMP_CV_MASK (0x00ffffff << PWMCMP_CV_SHIFT) +#define PWMCMP_CVM (1 << 24) /* Bit 24: Comparison x Value Mode */ + +/* PWM Comparison x Mode Register and PWM Comparison x Mode Update Register */ + +#define PWMCMP_CEN (1 << 0) /* Bit 0: Comparison x Enable */ +#define PWMCMP_CTR_SHIFT (4) /* Bits 4-7: Comparison x Trigger */ +#define PWMCMP_CTR_MASK (15 << PWMCMP_CTR_SHIFT) +# define PWMCMP_CTR(n) ((uint32_t)(n) << PWMCMP_CTR_SHIFT) +#define PWMCMP_CPR_SHIFT (8) /* Bits 8-11: Comparison x Period */ +#define PWMCMP_CPR_MASK (15 << PWMCMP_CPR_SHIFT) +# define PWMCMP_CPR(n) ((uint32_t)(n) << PWMCMP_CPR_SHIFT) +#define PWMCMP_M_CPRCNT_SHIFT (12) /* Bits 12-15: Comparison x Period Count (M only) */ +#define PWMCMP_M_CPRCNT_MASK (15 << PWMCMP_M_CPRCNT_SHIFT) +# define PWMCMP_M_CPRCNT(n) ((uint32_t)(n) << PWMCMP_M_CPRCNT_SHIFT) +#define PWMCMP_CUPR_SHIFT (16) /* Bits 16-19: Comparison x Update Period */ +#define PWMCMP_CUPR_MASK (15 << PWMCMP_CUPR_SHIFT) +# define PWMCMP_CUPR(n) ((uint32_t)(n) << PWMCMP_CUPR_SHIFT) +#define PWMCMP_M_CUPRCNT_SHIFT (20) /* Bits 20-23: Comparison x Update Period Counter (M only) */ +#define PWMCMP_M_CUPRCNT_MASK (15 << PWMCMP_M_CUPRCNT_SHIFT) +# define PWMCMP_M_CUPRCNT(n) ((uint32_t)(n) << PWMCMP_M_CUPRCNT_SHIFT) + +/* PWM Channel Mode Register */ + +#define PWMCH_MR_CPRE_SHIFT (0) /* Bits 0-3: Channel Pre-scaler */ +#define PWMCH_MR_CPRE_MASK (15 << PWMCH_MR_CPRE_SHIFT) +# define PWMCH_MR_CPRE_MCK (0 << PWMCH_MR_CPRE_SHIFT) /* MCK */ +# define PWMCH_MR_CPRE_MCKDIV2 (1 << PWMCH_MR_CPRE_SHIFT) /* MCK/2 */ +# define PWMCH_MR_CPRE_MCKDIV4 (2 << PWMCH_MR_CPRE_SHIFT) /* MCK/4 */ +# define PWMCH_MR_CPRE_MCKDIV8 (3 << PWMCH_MR_CPRE_SHIFT) /* MCK/8 */ +# define PWMCH_MR_CPRE_MCKDIV16 (4 << PWMCH_MR_CPRE_SHIFT) /* MCK/16 */ +# define PWMCH_MR_CPRE_MCKDIV32 (5 << PWMCH_MR_CPRE_SHIFT) /* MCK/32 */ +# define PWMCH_MR_CPRE_MCKDIV64 (6 << PWMCH_MR_CPRE_SHIFT) /* MCK/64 */ +# define PWMCH_MR_CPRE_MCKDIV128 (7 << PWMCH_MR_CPRE_SHIFT) /* MCK/128 */ +# define PWMCH_MR_CPRE_MCKDIV256 (8 << PWMCH_MR_CPRE_SHIFT) /* MCK/256 */ +# define PWMCH_MR_CPRE_MCKDIV512 (9 << PWMCH_MR_CPRE_SHIFT) /* MCK/512 */ +# define PWMCH_MR_CPRE_MCKDIV1024 (10 << PWMCH_MR_CPRE_SHIFT) /* MCK/1024 */ +# define PWMCH_MR_CPRE_CLKA (11 << PWMCH_MR_CPRE_SHIFT) /*CLKA */ +# define PWMCH_MR_CPRE_CLKB (12 << PWMCH_MR_CPRE_SHIFT) /* CLKB */ +#define PWMCH_MR_CALG (1 << 8) /* Bit 8: Channel Alignment */ +#define PWMCH_MR_CPOL (1 << 9) /* Bit 9: Channel Polarity */ +#define PWMCH_MR_CES (1 << 10) /* Bit 10: Counter Event Selection */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWMCH_MR_UPDS (1 << 11) /* Bit 11: Update Selection */ +#endif + +#define PWMCH_MR_DTE (1 << 16) /* Bit 16: Dead-Time Generator Enable */ +#define PWMCH_MR_DTHI (1 << 17) /* Bit 17: Dead-Time PWMHx Output Inverted */ +#define PWMCH_MR_DTLI (1 << 18) /* Bit 18: Dead-Time PWMLx Output Inverted */ + +/* PWM Channel Duty Cycle Register and PWM Channel Duty Cycle Update Register common bit-field definitions */ + +#define PWMCH_DTY_SHIFT (0) /* Bits 0-23: Channel Duty-Cycle */ +#define PWMCH_DTY_MASK (0x00ffffff << PWMCH_DTY_SHIFT) + +/* PWM Channel Period Register and PWM Channel Period Update Register common bit-field definitions */ + +#define PWMCH_PRD_SHIFT (0) /* Bits 0-23: Channel Period */ +#define PWMCH_PRD_MASK (0x00ffffff << PWMCH_PRD_SHIFT) + +/* PWM Channel Counter Register */ + +#define PWMCH_CCNT_SHIFT (0) /* Bits 0-23: Channel Counter Register */ +#define PWMCH_CCNT_MASK (0x00ffffff << PWMCH_CCNT_SHIFT) + +/* PWM Channel Dead Time Register and PWM Channel Dead Time Update Register common bit-field definitions */ + +#define PWMCH_DTH_SHIFT (0) /* Bits 0-15: Dead-Time Value for PWMHx Output */ +#define PWMCH_DTH_MASK (0xffff << PWMCH_DTH_SHIFT) +# define PWMCH_DTH(n) ((uint32_t)(n) << PWMCH_DTH_SHIFT) +#define PWMCH_DTL_SHIFT (16) /* Bits 16-31: Dead-Time Value for PWMLx Output */ +#define PWMCH_DTL_MASK (0xffff << PWMCH_DTL_SHIFT) +# define PWMCH_DTL(n) ((uint32_t)(n) << PWMCH_DTL_SHIFT) + +/* PWM Channel Mode Update Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWMCH_CMUPD_CPOLUP (1 << 9) /* Bit 9: Channel Polarity Update */ +# define PWMCH_CMUPD_CPOLINVUP (1 << 13) /* Bit 13: Channel Polarity Inversion Update */ +#endif + +/* PWM Channel Additional Edge Register and PWM Channel Additional Edge Update Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define PWMCH_CAE_ADEDGV_SHIFT (0) /* Bits 0-23: Channel Additional Edge Value */ +# define PWMCH_CAE_ADEDGV_MASK (0x00ffffff << PWMCH_CAE_ADEDGV_SHIFT) +# define PWMCH_CAE_ADEDGV(n) ((uint32_t)(n) << PWMCH_CAE_ADEDGV_SHIFT) +# define PWMCH_CAE_ADEDGM_SHIFT (24) /* Bits 24-25: Channel Additional Edge Mode */ +# define PWMCH_CAE_ADEDGM_MASK (3 << PWMCH_CAE_ADEDGM_SHIFT) +# define PWMCH_CAE_ADEDGM_INC (0 << PWMCH_CAE_ADEDGM_SHIFT) +# define PWMCH_CAE_ADEDGM_DEC (1 << PWMCH_CAE_ADEDGM_SHIFT) +# define PWMCH_CAE_ADEDGM_BOTH (2 << PWMCH_CAE_ADEDGM_SHIFT) +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_PWM_H */ diff --git a/arch/arm/src/sam34/chip/sam_rstc.h b/arch/arm/src/sam34/chip/sam_rstc.h new file mode 100644 index 0000000000000000000000000000000000000000..60250ef832f7137cbba9ca4480f6ba7520b430f2 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_rstc.h @@ -0,0 +1,128 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_rstc.h + * Reset Controller (RSTC) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSTC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSTC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RSTC register offsets ****************************************************************/ + +#define SAM_RSTC_CR_OFFSET 0x00 /* Control Register */ +#define SAM_RSTC_SR_OFFSET 0x04 /* Status Register */ +#define SAM_RSTC_MR_OFFSET 0x08 /* Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define SAM_RSTC_CPMR_OFFSET 0x0c /* Coprocessor Mode Register */ +#endif + +/* RSTC register addresses **************************************************************/ + +#define SAM_RSTC_CR (SAM_RSTC_BASE+SAM_RSTC_CR_OFFSET) +#define SAM_RSTC_SR (SAM_RSTC_BASE+SAM_RSTC_SR_OFFSET) +#define SAM_RSTC_MR (SAM_RSTC_BASE+SAM_RSTC_MR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define SAM_RSTC_CPMR (SAM_RSTC_BASE+SAM_RSTC_CPMR_OFFSET) +#endif + +/* RSTC register bit definitions ********************************************************/ + +/* Reset Controller Control Register */ + +#define RSTC_CR_PROCRST (1 << 0) /* Bit 0: Processor Reset */ +#define RSTC_CR_PERRST (1 << 2) /* Bit 2: Peripheral Reset */ +#define RSTC_CR_EXTRST (1 << 3) /* Bit 3: External Reset */ +#define RSTC_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define RSTC_CR_KEY_MASK (0xff << RSTC_CR_KEY_SHIFT) +# define RSTC_CR_KEY (0xa5 << RSTC_CR_KEY_SHIFT) + +/* Reset Controller Status Register */ + +#define RSTC_SR_URSTS (1 << 0) /* Bit 0: User Reset Status */ +#define RSTC_SR_RSTTYP_SHIFT (8) /* Bits 8-10: Reset Type */ +#define RSTC_SR_RSTTYP_MASK (7 << RSTC_SR_RSTTYP_SHIFT) +# define RSTC_SR_RSTTYP_PWRUP (0 << RSTC_SR_RSTTYP_SHIFT) /* General Reset */ +# define RSTC_SR_RSTTYP_BACKUP (1 << RSTC_SR_RSTTYP_SHIFT) /* Backup Reset */ +# define RSTC_SR_RSTTYP_WDOG (2 << RSTC_SR_RSTTYP_SHIFT) /* Watchdog Reset */ +# define RSTC_SR_RSTTYP_SWRST (3 << RSTC_SR_RSTTYP_SHIFT) /* Software Reset */ +# define RSTC_SR_RSTTYP_NRST (4 << RSTC_SR_RSTTYP_SHIFT) /* User Reset NRST pin */ +#define RSTC_SR_NRSTL (1 << 16) /* Bit 16: NRST Pin Level */ +#define RSTC_SR_SRCMP (1 << 17) /* Bit 17: Software Reset Command in Progress */ + +/* Reset Controller Mode Register */ + +#define RSTC_MR_URSTEN (1 << 0) /* Bit 0: User Reset Enable */ +#define RSTC_MR_URSTIEN (1 << 4) /* Bit 4: User Reset Interrupt Enable */ +#define RSTC_MR_ERSTL_SHIFT (8) /* Bits 8-11: External Reset Length */ +#define RSTC_MR_ERSTL_MASK (15 << RSTC_MR_ERSTL_SHIFT) +# define RSTC_MR_ERSTL(n) ((uint32_t)(n) << RSTC_MR_ERSTL_SHIFT) +#define RSTC_MR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define RSTC_MR_KEY_MASK (0xff << RSTC_CR_KEY_SHIFT) +# define RSTC_MR_KEY (0xa5 << RSTC_CR_KEY_SHIFT) + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +/* Coprocessor Mode Register */ + +# define RSTC_CPMR_CPROCEN (1 << 0) /* Coprocessor (second processor) Enable */ +# define RSTC_CPMR_CPEREN (1 << 4) /* Coprocessor Peripheral Enable */ +# define RSTC_CPMR_CPKEY (0x5a << 24) /* Key */ +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSTC_H */ diff --git a/arch/arm/src/sam34/chip/sam_rswdt.h b/arch/arm/src/sam34/chip/sam_rswdt.h new file mode 100644 index 0000000000000000000000000000000000000000..69ed294ea575d9725df207aef6870f3f2d6b91ec --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_rswdt.h @@ -0,0 +1,105 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_rswdt.h + * Reinforced Safety Watchdog Timer (RSWDT) for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSWDT_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSWDT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RSWDT register offsets ***************************************************************/ + +#define SAM_RSWDT_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_RSWDT_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_RSWDT_SR_OFFSET 0x0008 /* Status Register */ + +/* RSWDT register addresses *************************************************************/ + +#define SAM_RSWDT_CR (SAM_RSWDT_BASE+SAM_RSWDT_CR_OFFSET) +#define SAM_RSWDT_MR (SAM_RSWDT_BASE+SAM_RSWDT_MR_OFFSET) +#define SAM_RSWDT_SR (SAM_RSWDT_BASE+SAM_RSWDT_SR_OFFSET) + +/* RSWDT register bit definitions *******************************************************/ +/* Watchdog Timer Control Register */ + +#define RSWDT_CR_WDRSTT (1 << 0) /* Bit 0: Watchdog Rest */ +#define RSWDT_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define RSWDT_CR_KEY_MASK (0xff << RSWDT_CR_KEY_SHIFT) +# define RSWDT_CR_KEY (0xc4 << RSWDT_CR_KEY_SHIFT) + +/* Watchdog Timer Mode Register */ + +#define RSWDT_MR_WDV_SHIFT (0) /* Bits 0-11: Watchdog Counter Value */ +#define RSWDT_MR_WDV_MASK (0xfff << RSWDT_MR_WDV_SHIFT) +# define RSWDT_MR_WDV(n) ((uint32_t)(n) << RSWDT_MR_WDV_SHIFT) +#define RSWDT_MR_WDFIEN (1 << 12) /* Bit 12: Watchdog Fault Interrupt Enable */ +#define RSWDT_MR_WDRSTEN (1 << 13) /* Bit 13: Watchdog Reset Enable */ +#define RSWDT_MR_WDRPROC (1 << 14) /* Bit 14: Watchdog Reset Processor */ +#define RSWDT_MR_WDDIS (1 << 15) /* Bit 15: Watchdog Disable */ +#define RSWDT_MR_WDD_SHIFT (16) /* Bits 16-27: Watchdog Delta Value */ +#define RSWDT_MR_WDD_MASK (0xfff << RSWDT_MR_WDD_SHIFT) +# define RSWDT_MR_WDD(n) ((uint32_t)(n) << RSWDT_MR_WDD_SHIFT) +#define RSWDT_MR_WDDBGHLT (1 << 28) /* Bit 28: Watchdog Debug Halt */ +#define RSWDT_MR_WDIDLEHLT (1 << 29) /* Bit 29: Watchdog Idle Halt */ + +/* Watchdog Timer Status Register */ + +#define RSWDT_SR_WDUNF (1 << 0) /* Bit 0: Watchdog Underflow */ +#define RSWDT_SR_WDERR (1 << 1) /* Bit 1: Watchdog Error */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_RSWDT_H */ diff --git a/arch/arm/src/sam34/chip/sam_rtc.h b/arch/arm/src/sam34/chip/sam_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..b15cba7009b2273e25939b88ed6091a07cf311cb --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_rtc.h @@ -0,0 +1,283 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_rtc.h + * Real-time Clock (RTC) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RTC register offsets *****************************************************************/ + +#define SAM_RTC_CR_OFFSET 0x00 /* Control Register */ +#define SAM_RTC_MR_OFFSET 0x04 /* Mode Register */ +#define SAM_RTC_TIMR_OFFSET 0x08 /* Time Register */ +#define SAM_RTC_CALR_OFFSET 0x0c /* Calendar Register */ +#define SAM_RTC_TIMALR_OFFSET 0x10 /* Time Alarm Register */ +#define SAM_RTC_CALALR_OFFSET 0x14 /* Calendar Alarm Register */ +#define SAM_RTC_SR_OFFSET 0x18 /* Status Register */ +#define SAM_RTC_SCCR_OFFSET 0x1c /* Status Clear Command Register */ +#define SAM_RTC_IER_OFFSET 0x20 /* Interrupt Enable Register */ +#define SAM_RTC_IDR_OFFSET 0x24 /* Interrupt Disable Register */ +#define SAM_RTC_IMR_OFFSET 0x28 /* Interrupt Mask Register */ +#define SAM_RTC_VER_OFFSET 0x2c /* Valid Entry Register */ + +/* RTC register addresses ***************************************************************/ + +#define SAM_RTC_CR (SAM_RTC_BASE+SAM_RTC_CR_OFFSET) +#define SAM_RTC_MR (SAM_RTC_BASE+SAM_RTC_MR_OFFSET) +#define SAM_RTC_TIMR (SAM_RTC_BASE+SAM_RTC_TIMR_OFFSET) +#define SAM_RTC_CALR (SAM_RTC_BASE+SAM_RTC_CALR_OFFSET) +#define SAM_RTC_TIMALR (SAM_RTC_BASE+SAM_RTC_TIMALR_OFFSET) +#define SAM_RTC_CALALR (SAM_RTC_BASE+SAM_RTC_CALALR_OFFSET) +#define SAM_RTC_SR (SAM_RTC_BASE+SAM_RTC_SR_OFFSET) +#define SAM_RTC_SCCR (SAM_RTC_BASE+SAM_RTC_SCCR_OFFSET) +#define SAM_RTC_IER (SAM_RTC_BASE+SAM_RTC_IER_OFFSET) +#define SAM_RTC_IDR (SAM_RTC_BASE+SAM_RTC_IDR_OFFSET) +#define SAM_RTC_IMR (SAM_RTC_BASE+SAM_RTC_IMR_OFFSET) +#define SAM_RTC_VER (SAM_RTC_BASE+SAM_RTC_VER_OFFSET) + +/* RTC register bit definitions *********************************************************/ + +/* RTC Control Register */ + +#define RTC_CR_UPDTIM (1 << 0) /* Bit 0: Update Request Time Register */ +#define RTC_CR_UPDCAL (1 << 1) /* Bit 1: Update Request Calendar Register */ +#define RTC_CR_TIMEVSEL_SHIFT (8) /* Bits 8-9: Time Event Selection */ +#define RTC_CR_TIMEVSEL_MASK (3 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIN (0 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_HOUR (1 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIDNIGHT (2 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_NOON (3 << RTC_CR_TIMEVSEL_SHIFT) +#define RTC_CR_CALEVSEL_SHIFT (16) /* Bits 16-17: Calendar Event Selection */ +#define RTC_CR_CALEVSEL_MASK (3 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_WEEK (0 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_MONTH (1 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_YEAR (2 << RTC_CR_CALEVSEL_SHIFT) + +/* RTC Mode Register */ + +#define RTC_MR_HRMOD (1 << 0) /* Bit 0: 12-/24-hour Mode */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTC_MR_PERSIAN (1 << 1) /* Bit 1: PERSIAN Calendar */ +# define RTC_MR_NEGPPM (1 << 4) /* Bit 4: Negative PPM Correction */ +# define RTC_MR_CORRECTION_SHIFT (8) /* Bits 8-14: Slow Clock Correction */ +# define RTC_MR_CORRECTION_MASK (0x7f << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_CORRECTION(n) ((uint32_t)(n) << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_HIGHPPM (1 << 15) /* Bit 15: HIGH PPM Correction */ +# define RTC_MR_OUT0_SHIFT (16) /* Bits 16-18: RTCOUT0 Output Source Selection */ +# define RTC_MR_OUT0_MASK (7 << RTC_MR_OUT0_SHIFT) +# define RTC_MR_OUT0_NOWAVE (0 << RTC_MR_OUT0_SHIFT) /* No waveform, stuck at 0 */ +# define RTC_MR_OUT0_FREQ1HZ (1 << RTC_MR_OUT0_SHIFT) /* 1Hz square wave */ +# define RTC_MR_OUT0_FREQ32HZ (2 << RTC_MR_OUT0_SHIFT) /* 32Hz square wave */ +# define RTC_MR_OUT0_FREQ64HZ (3 << RTC_MR_OUT0_SHIFT) /* 64Hz square wave */ +# define RTC_MR_OUT0_FREQ512HZ (4 << RTC_MR_OUT0_SHIFT) /* 512Hz square wave */ +# define RTC_MR_OUT0_ALARM_TOGGLE (5 << RTC_MR_OUT0_SHIFT) /* Output toggles when alarm flag rises */ +# define RTC_MR_OUT0_ALARM_FLAG (6 << RTC_MR_OUT0_SHIFT) /* Output is a copy of the alarm flag */ +# define RTC_MR_OUT0_PROG_PULSE (7 << RTC_MR_OUT0_SHIFT) /* Duty cycle programmable pulse */ +# define RTC_MR_OUT1_SHIFT (20) /* Bits 20-22: RTCOUT1 Output Source Selection */ +# define RTC_MR_OUT1_MASK (7 << RTC_MR_OUT1_SHIFT) +# define RTC_MR_OUT1_NOWAVE (0 << RTC_MR_OUT1_SHIFT) /* No waveform, stuck at 0 */ +# define RTC_MR_OUT1_FREQ1HZ (1 << RTC_MR_OUT1_SHIFT) /* 1Hz square wave */ +# define RTC_MR_OUT1_FREQ32HZ (2 << RTC_MR_OUT1_SHIFT) /* 32Hz square wave */ +# define RTC_MR_OUT1_FREQ64HZ (3 << RTC_MR_OUT1_SHIFT) /* 64Hz square wave */ +# define RTC_MR_OUT1_FREQ512HZ (4 << RTC_MR_OUT1_SHIFT) /* 512Hz square wave */ +# define RTC_MR_OUT1_ALARM_TOGGLE (5 << RTC_MR_OUT1_SHIFT) /* Output toggles when alarm flag rises */ +# define RTC_MR_OUT1_ALARM_FLAG (6 << RTC_MR_OUT1_SHIFT) /* Output is a copy of the alarm flag */ +# define RTC_MR_OUT1_PROG_PULSE (7 << RTC_MR_OUT1_SHIFT) /* Duty cycle programmable pulse */ +# define RTC_MR_THIGH_SHIFT (24) /* Bits 24-26: High Duration of the Output Pulse */ +# define RTC_MR_THIGH_MASK (7 << RTC_MR_THIGH_SHIFT) +# define RTC_MR_THIGH_31MS (0 << RTC_MR_THIGH_SHIFT) /* 31.2 ms */ +# define RTC_MR_THIGH_16MS (1 << RTC_MR_THIGH_SHIFT) /* 15.6 ms */ +# define RTC_MR_THIGH_4MS (2 << RTC_MR_THIGH_SHIFT) /* 3.91 ms */ +# define RTC_MR_THIGH_976US (3 << RTC_MR_THIGH_SHIFT) /* 976 µs */ +# define RTC_MR_THIGH_488US (4 << RTC_MR_THIGH_SHIFT) /* 488 µs */ +# define RTC_MR_THIGH_22US (5 << RTC_MR_THIGH_SHIFT) /* 122 µs */ +# define RTC_MR_THIGH_0US (6 << RTC_MR_THIGH_SHIFT) /* 30.5 µs */ +# define RTC_MR_THIGH_15US (7 << RTC_MR_THIGH_SHIFT) /* 15.2 µs */ +# define RTC_MR_TPERIOD_SHIFT (28) /* Bits 28-29: Period of the Output Pulse */ +# define RTC_MR_TPERIOD_MASK (3 << RTC_MR_TPERIOD_SHIFT) +# define RTC_MR_TPERIOD_1S (0 << RTC_MR_TPERIOD_SHIFT) /* 1 second */ +# define RTC_MR_TPERIOD_500MS (1 << RTC_MR_TPERIOD_SHIFT) /* 500 ms */ +# define RTC_MR_TPERIOD_250MS (2 << RTC_MR_TPERIOD_SHIFT) /* 250 ms */ +# define RTC_MR_TPERIOD_125MS (3 << RTC_MR_TPERIOD_SHIFT) /* 125 ms */ +#endif + +/* RTC Time Register */ + +#define RTC_TIMR_SEC_SHIFT (0) /* Bits 0-6: Current Second */ +#define RTC_TIMR_SEC_MASK (0x7f << RTC_TIMR_SEC_SHIFT) +# define RTC_TIMR_SEC(n) ((uint32_t)(n) << RTC_TIMR_SEC_SHIFT) +#define RTC_TIMR_MIN_SHIFT (8) /* Bits 8-14: Current Minute */ +#define RTC_TIMR_MIN_MASK (0x7f << RTC_TIMR_MIN_SHIFT) +# define RTC_TIMR_MIN(n) ((uint32_t)(n) << RTC_TIMR_MIN_SHIFT) +#define RTC_TIMR_HOUR_SHIFT (16) /* Bits 16-21: Current Hour */ +#define RTC_TIMR_HOUR_MASK (0x3f << RTC_TIMR_HOUR_SHIFT) +# define RTC_TIMR_HOUR(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_TIMR_AMPM (1 << 22) /* Bit 22: Ante Meridiem Post Meridiem Indicator */ + +/* RTC Calendar Register */ + +#define RTC_CALR_CENT_SHIFT (0) /* Bits 0-6: Current Century */ +#define RTC_CALR_CENT_MASK (0x7f << RTC_CALR_CENT_SHIFT) +# define RTC_CALR_CENT(n) ((uint32_t)(n) << RTC_CALR_CENT_SHIFT) +#define RTC_CALR_YEAR_SHIFT (8) /* Bits 8-15: Current Year */ +#define RTC_CALR_YEAR_MASK (0xff << RTC_CALR_YEAR_SHIFT) +# define RTC_CALR_YEAR(n) ((uint32_t)(n) << RTC_CALR_YEAR_SHIFT) +#define RTC_CALR_MONTH_SHIFT (16) /* Bits 16-20: Current Month */ +#define RTC_CALR_MONTH_MASK (0x1f << RTC_CALR_MONTH_SHIFT) +# define RTC_CALR_MONTH(n) ((uint32_t)(n) << RTC_CALR_MONTH_SHIFT) +#define RTC_CALR_DAY_SHIFT (21) /* Bits 21-23: Current Day in Current Week */ +#define RTC_CALR_DAY_MASK (7 << RTC_CALR_DAY_SHIFT) +# define RTC_CALR_DAY(n) ((uint32_t)(n)7 << RTC_CALR_DAY_SHIFT) +#define RTC_CALR_DATE_SHIFT (24) /* Bits 24-29: Current Day in Current Month */ +#define RTC_CALR_DATE_MASK (0x3f << RTC_CALR_DATE_SHIFT) +# define RTC_CALR_DATE(n) ((uint32_t)(n) << RTC_CALR_DATE_SHIFT) + +/* RTC Time Alarm Register */ + +#define RTC_TIMALR_SEC_SHIFT (0) /* Bits 0-6: Second Alarm */ +#define RTC_TIMALR_SEC_MASK (0x7f << RTC_TIMALR_SEC_SHIFT) +# define RTC_TIMALR_SEC(n) ((uint32_t)(n) << RTC_TIMALR_SEC_SHIFT) +#define RTC_TIMALR_SECEN (1 << 7) /* Bit 7: Second Alarm Enable */ +#define RTC_TIMALR_MIN_SHIFT (8) /* Bits 8-14: Minute Alarm */ +#define RTC_TIMALR_MIN_MASK (0x7f << RTC_TIMALR_MIN_SHIFT) +# define RTC_TIMALR_MIN(n) ((uint32_t)(n) << RTC_TIMALR_MIN_SHIFT) +#define RTC_TIMALR_MINEN (1 << 15) /* Bit 15: Minute Alarm Enable */ +#define RTC_TIMALR_HOUR_SHIFT (16) /* Bits 16-21: Hour Alarm */ +#define RTC_TIMALR_HOUR_MASK (0x3f << RTC_TIMALR_HOUR_SHIFT) +# define RTC_TIMALR_HOUR(n) ((uint32_t)(n) << RTC_TIMALR_HOUR_SHIFT) +#define RTC_TIMALR_AMPM (1 << 22) /* Bit 22: AM/PM Indicator */ +#define RTC_TIMALR_HOUREN (1 << 23) /* Bit 23: Hour Alarm Enable */ + +/* RTC Calendar Alarm Register */ + +#define RTC_CALALR_MONTH_SHIFT (16) /* Bits 16-20: Month Alarm */ +#define RTC_CALALR_MONTH_MASK (0x1f << RTC_CALALR_MONTH_SHIFT) +# define RTC_CALALR_MONTH(n) ((uint32_t)(n) << RTC_CALALR_MONTH_SHIFT) +#define RTC_CALALR_MTHEN (1 << 23) /* Bit 23: Month Alarm Enable */ +#define RTC_CALALR_DATE_SHIFT (24) /* Bits 24-29: Date Alarm */ +#define RTC_CALALR_DATE_MASK (0x3f << RTC_CALALR_DATE_SHIFT) +# define RTC_CALALR_DATE(n) ((uint32_t)(n) << RTC_CALALR_DATE_SHIFT) +#define RTC_CALALR_DATEEN (1 << 31) /* Bit 31: Date Alarm Enable */ + +/* RTC Status Register */ + +#define RTC_SR_ACKUPD (1 << 0) /* Bit 0: Acknowledge for Update */ +#define RTC_SR_ALARM (1 << 1) /* Bit 1: Alarm Flag */ +#define RTC_SR_SEC (1 << 2) /* Bit 2: Second Event */ +#define RTC_SR_TIMEV (1 << 3) /* Bit 3: Time Event */ +#define RTC_SR_CALEV (1 << 4) /* Bit 4: Calendar Event */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTC_SR_TDERR (1 << 5) /* Bit 5: Time and/or Date Free Running Error */ +#endif + +/* RTC Status Clear Command Register */ + +#define RTC_SCCR_ACKCLR (1 << 0) /* Bit 0: Acknowledge Clear */ +#define RTC_SCCR_ALRCLR (1 << 1) /* Bit 1: Alarm Clear */ +#define RTC_SCCR_SECCLR (1 << 2) /* Bit 2: Second Clear */ +#define RTC_SCCR_TIMCLR (1 << 3) /* Bit 3: Time Clear */ +#define RTC_SCCR_CALCLR (1 << 4) /* Bit 4: Calendar Clear */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTC_SR_TDERRCLR (1 << 5) /* Bit 5: Time and/or Date Free Running Error Clear */ +#endif + +/* RTC Interrupt Enable Register */ + +#define RTC_IER_ACKEN (1 << 0) /* Bit 0: Acknowledge Update Interrupt Enable */ +#define RTC_IER_ALREN (1 << 1) /* Bit 1: Alarm Interrupt Enable */ +#define RTC_IER_SECEN (1 << 2) /* Bit 2: Second Event Interrupt Enable */ +#define RTC_IER_TIMEN (1 << 3) /* Bit 3: Time Event Interrupt Enable */ +#define RTC_IER_CALEN (1 << 4) /* Bit 4: Calendar Event Interrupt Enable */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTC_SR_TDERREN (1 << 5) /* Bit 5: Time and/or Date Error Interrupt Enable */ +#endif + +/* RTC Interrupt Disable Register */ + +#define RTC_IDR_ACKDIS (1 << 0) /* Bit 0: Acknowledge Update Interrupt Disable */ +#define RTC_IDR_ALRDIS (1 << 1) /* Bit 1: Alarm Interrupt Disable */ +#define RTC_IDR_SECDIS (1 << 2) /* Bit 2: Second Event Interrupt Disable */ +#define RTC_IDR_TIMDIS (1 << 3) /* Bit 3: Time Event Interrupt Disable */ +#define RTC_IDR_CALDIS (1 << 4) /* Bit 4: Calendar Event Interrupt Disable */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTC_SR_TDERRDIS (1 << 5) /* Bit 5: Time and/or Date Error Interrupt Disable */ +#endif + +/* RTC Interrupt Mask Register */ + +#define RTC_IMR_ACK (1 << 0) /* Bit 0: Acknowledge Update Interrupt Mask */ +#define RTC_IMR_ALR (1 << 1) /* Bit 1: Alarm Interrupt Mask */ +#define RTC_IMR_SEC (1 << 2) /* Bit 2: Second Event Interrupt Mask */ +#define RTC_IMR_TIM (1 << 3) /* Bit 3: Time Event Interrupt Mask */ +#define RTC_IMR_CAL (1 << 4) /* Bit 4: Calendar Event Interrupt Mask */ + +/* RTC Valid Entry Register */ + +#define RTC_VER_NVTIM (1 << 0) /* Bit 0: Non-valid Time */ +#define RTC_VER_NVCAL (1 << 1) /* Bit 1: Non-valid Calendar */ +#define RTC_VER_NVTIMALR (1 << 2) /* Bit 2: Non-valid Time Alarm */ +#define RTC_VER_NVCALALR (1 << 3) /* Bit 3: Non-valid Calendar Alarm */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTC_H */ diff --git a/arch/arm/src/sam34/chip/sam_rtt.h b/arch/arm/src/sam34/chip/sam_rtt.h new file mode 100644 index 0000000000000000000000000000000000000000..b0ddcb621bede13f3033b29cc6c2c76436fd01f4 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_rtt.h @@ -0,0 +1,103 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_rtt.h + * Real-time Timer (RTT) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTT_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RTT register offsets *****************************************************************/ + +#define SAM_RTT_MR_OFFSET 0x00 /* Mode Register */ +#define SAM_RTT_AR_OFFSET 0x04 /* Alarm Register */ +#define SAM_RTT_VR_OFFSET 0x08 /* Value Register */ +#define SAM_RTT_SR_OFFSET 0x0c /* Status Register */ + +/* RTT register addresses ***************************************************************/ + +#define SAM_RTT_MR (SAM_RTT_BASE+SAM_RTT_MR_OFFSET) +#define SAM_RTT_AR (SAM_RTT_BASE+SAM_RTT_AR_OFFSET) +#define SAM_RTT_VR (SAM_RTT_BASE+SAM_RTT_VR_OFFSET) +#define SAM_RTT_SR (SAM_RTT_BASE+SAM_RTT_SR_OFFSET) + +/* RTT register bit definitions ********************************************************/ + +/* Real-time Timer Mode Register */ + +#define RTT_MR_RTPRES_SHIFT (0) /* Bits 0-15: Real-time Timer Prescaler Value */ +#define RTT_MR_RTPRES_MASK (0xffff << RTT_MR_RTPRES_SHIFT) +# define RTT_MR_RTPRES(n) ((uint32_t)(n) << RTT_MR_RTPRES_SHIFT) +#define RTT_MR_ALMIEN (1 << 16) /* Bit 16: Alarm Interrupt Enable */ +#define RTT_MR_RTTINCIEN (1 << 17) /* Bit 17: Real-time Timer Increment Int Enable */ +#define RTT_MR_RTTRST (1 << 18) /* Bit 18: Real-time Timer Restart */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define RTT_MR_RTTDIS (1 << 20) /* Bit 20: Real-time Timer Disable */ +# define RTT_MR_RTC1HZ (1 << 24) /* Bit 24: Real-Time Clock 1Hz Clock Selection */ +#endif + +/* Real-time Timer Alarm Register (32-bit alarm value) */ +/* Real-time Timer Value Register (32-bit timer value) */ + +/* Real-time Timer Status Register */ + +#define RTT_SR_ALMS (1 << 0) /* Bit 0: Real-time Alarm Status */ +#define RTT_SR_RTTINC (1 << 1) /* Bit 1: Real-time Timer Increment */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_RTT_H */ diff --git a/arch/arm/src/sam34/chip/sam_smc.h b/arch/arm/src/sam34/chip/sam_smc.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed0ea98d982cadffd838efa82031e37fd7f30db --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_smc.h @@ -0,0 +1,616 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_smc.h + * Static Memory Controller (SMC) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_SMC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_SMC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SMC register offsets *****************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMC_CFG_OFFSET 0x0000 /* SMC NFC Configuration Register */ +# define SAM_SMC_CTRL_OFFSET 0x0004 /* SMC NFC Control Register */ +# define SAM_SMC_SR_OFFSET 0x0008 /* SMC NFC Status Register */ +# define SAM_SMC_IER_OFFSET 0x000c /* SMC NFC Interrupt Enable Register */ +# define SAM_SMC_IDR_OFFSET 0x0010 /* SMC NFC Interrupt Disable Register */ +# define SAM_SMC_IMR_OFFSET 0x0014 /* SMC NFC Interrupt Mask Register */ +# define SAM_SMC_ADDR_OFFSET 0x0018 /* SMC NFC Address Cycle Zero Register */ +# define SAM_SMC_BANK_OFFSET 0x001c /* SMC Bank Address Register */ +# define SAM_SMC_ECCCTRL_OFFSET 0x0020 /* SMC ECC Control Register */ +# define SAM_SMC_ECCMD_OFFSET 0x0024 /* SMC ECC Mode Register */ +# define SAM_SMC_ECCSR1_OFFSET 0x0028 /* SMC ECC Status 1 Register */ +# define SAM_SMC_ECCPR0_OFFSET 0x002c /* SMC ECC parity 0 Register */ +# define SAM_SMC_ECCPR1_OFFSET 0x0030 /* SMC ECC parity 1 Register */ +# define SAM_SMC_ECCSR2_OFFSET 0x0034 /* SMC ECC status 2 Register */ +# define SAM_SMC_ECCPR2_OFFSET 0x0038 /* SMC ECC parity 2 Register */ +# define SAM_SMC_ECCPR3_OFFSET 0x003c /* SMC ECC parity 3 Register */ +# define SAM_SMC_ECCPR4_OFFSET 0x0040 /* SMC ECC parity 4 Register */ +# define SAM_SMC_ECCPR5_OFFSET 0x0044 /* SMC ECC parity 5 Register */ +# define SAM_SMC_ECCPR6_OFFSET 0x0048 /* SMC ECC parity 6 Register */ +# define SAM_SMC_ECCPR7_OFFSET 0x004c /* SMC ECC parity 7 Register */ +# define SAM_SMC_ECCPR8_OFFSET 0x0050 /* SMC ECC parity 8 Register */ +# define SAM_SMC_ECCPR9_OFFSET 0x0054 /* SMC ECC parity 9 Register */ +# define SAM_SMC_ECCPR10_OFFSET 0x0058 /* SMC ECC parity 10 Register */ +# define SAM_SMC_ECCPR11_OFFSET 0x005c /* SMC ECC parity 11 Register */ +# define SAM_SMC_ECCPR12_OFFSET 0x0060 /* SMC ECC parity 12 Register */ +# define SAM_SMC_ECCPR13_OFFSET 0x0064 /* SMC ECC parity 13 Register */ +# define SAM_SMC_ECCPR14_OFFSET 0x0068 /* SMC ECC parity 14 Register */ +# define SAM_SMC_ECCPR15_OFFSET 0x006c /* SMC ECC parity 15 Register */ + +# define SAM_SMCCS_OFFSET(n) (0x0070+((n)*0x014)) +# define SAM_SMCCS0_OFFSET 0x0070 /* SMC CS0 offset */ +# define SAM_SMCCS1_OFFSET 0x0084 /* SMC CS1 offset */ +# define SAM_SMCCS2_OFFSET 0x0098 /* SMC CS2 offset */ +# define SAM_SMCCS3_OFFSET 0x00ac /* SMC CS3 offset */ + +# define SAM_SMCCS_SETUP_OFFSET 0x0000 /* SMC Setup register */ +# define SAM_SMCCS_PULSE_OFFSET 0x0004 /* SMC Pulse Register */ +# define SAM_SMCCS_CYCLE_OFFSET 0x0008 /* SMC Cycle Register */ +# define SAM_SMCCS_TIMINGS_OFFSET 0x000c /* SMC Timings Register */ +# define SAM_SMCCS_MODE_OFFSET 0x0010 /* SMC Mode Register */ + +# define SAM_SMC_OCMS_OFFSET 0x0110 /* SMC OCMS Mode Register */ +# define SAM_SMC_KEY1_OFFSET 0x0114 /* SMC KEY1 Register */ +# define SAM_SMC_KEY2_OFFSET 0x0118 /* SMC KEY2 Register */ +# define SAM_SMC_WPCR_OFFSET 0x01e4 /* Write Protection Control Register */ +# define SAM_SMC_WPSR_OFFSET 0x01e8 /* Write Protection Status Register */ + +#elif defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_SMCCS_OFFSET(n) ((n) << 4) +# define SAM_SMCCS0_OFFSET 0x0000 /* SMC CS0 offset */ +# define SAM_SMCCS1_OFFSET 0x0010 /* SMC CS1 offset */ +# define SAM_SMCCS2_OFFSET 0x0020 /* SMC CS2 offset */ +# define SAM_SMCCS3_OFFSET 0x0030 /* SMC CS3 offset */ + +# define SAM_SMCCS_SETUP_OFFSET 0x0000 /* SMC Setup Register */ +# define SAM_SMCCS_PULSE_OFFSET 0x0004 /* SMC Pulse Register */ +# define SAM_SMCCS_CYCLE_OFFSET 0x0008 /* SMC Cycle Register */ +# define SAM_SMCCS_MODE_OFFSET 0x000c /* SMC Mode Register */ + +# define SAM_SMC_OCMS_OFFSET 0x0080 /* SMC OCMS Mode Register */ +# define SAM_SMC_KEY1_OFFSET 0x0084 /* SMC KEY1 Register */ +# define SAM_SMC_KEY2_OFFSET 0x0088 /* SMC KEY2 Register */ +# define SAM_SMC_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +# define SAM_SMC_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + +#else +# error Unrecognized SAM architecture +#endif + +/* SMC register addresses ***************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMC_CFG (SAM_SMC_BASE+SAM_SMC_CFG_OFFSET) +# define SAM_SMC_CTRL (SAM_SMC_BASE+SAM_SMC_CTRL_OFFSET) +# define SAM_SMC_SR (SAM_SMC_BASE+SAM_SMC_SR_OFFSET) +# define SAM_SMC_IER (SAM_SMC_BASE+SAM_SMC_IER_OFFSET) +# define SAM_SMC_IDR (SAM_SMC_BASE+SAM_SMC_IDR_OFFSET) +# define SAM_SMC_IMR (SAM_SMC_BASE+SAM_SMC_IMR_OFFSET) +# define SAM_SMC_ADDR (SAM_SMC_BASE+SAM_SMC_ADDR_OFFSET) +# define SAM_SMC_BANK (SAM_SMC_BASE+SAM_SMC_BANK_OFFSET) +# define SAM_SMC_ECCCTRL (SAM_SMC_BASE+SAM_SMC_ECCCTRL_OFFSET) +# define SAM_SMC_ECCMD (SAM_SMC_BASE+SAM_SMC_ECCMD_OFFSET) +# define SAM_SMC_ECCSR1 (SAM_SMC_BASE+SAM_SMC_ECCSR1_OFFSET) +# define SAM_SMC_ECCPR0 (SAM_SMC_BASE+SAM_SMC_ECCPR0_OFFSET) +# define SAM_SMC_ECCPR1 (SAM_SMC_BASE+SAM_SMC_ECCPR1_OFFSET) +# define SAM_SMC_ECCSR2 (SAM_SMC_BASE+SAM_SMC_ECCSR2_OFFSET) +# define SAM_SMC_ECCPR2 (SAM_SMC_BASE+SAM_SMC_ECCPR2_OFFSET) +# define SAM_SMC_ECCPR3 (SAM_SMC_BASE+SAM_SMC_ECCPR3_OFFSET) +# define SAM_SMC_ECCPR4 (SAM_SMC_BASE+SAM_SMC_ECCPR4_OFFSET) +# define SAM_SMC_ECCPR5 (SAM_SMC_BASE+SAM_SMC_ECCPR5_OFFSET) +# define SAM_SMC_ECCPR6 (SAM_SMC_BASE+SAM_SMC_ECCPR6_OFFSET) +# define SAM_SMC_ECCPR7 (SAM_SMC_BASE+SAM_SMC_ECCPR7_OFFSET) +# define SAM_SMC_ECCPR8 (SAM_SMC_BASE+SAM_SMC_ECCPR8_OFFSET) +# define SAM_SMC_ECCPR9 (SAM_SMC_BASE+SAM_SMC_ECCPR9_OFFSET) +# define SAM_SMC_ECCPR10 (SAM_SMC_BASE+SAM_SMC_ECCPR10_OFFSET) +# define SAM_SMC_ECCPR11 (SAM_SMC_BASE+SAM_SMC_ECCPR11_OFFSET) +# define SAM_SMC_ECCPR12 (SAM_SMC_BASE+SAM_SMC_ECCPR12_OFFSET) +# define SAM_SMC_ECCPR13 (SAM_SMC_BASE+SAM_SMC_ECCPR13_OFFSET) +# define SAM_SMC_ECCPR14 (SAM_SMC_BASE+SAM_SMC_ECCPR14_OFFSET) +# define SAM_SMC_ECCPR15 (SAM_SMC_BASE+SAM_SMC_ECCPR15_OFFSET) +#endif + +#define SAM_SMCCS_BASE(n) (SAM_SMC_BASE+SAM_SMCCS_OFFSET(n)) +# define SAM_SMC_CS0_BASE (SAM_SMC_BASE+SAM_SMCCS0_OFFSET) +# define SAM_SMC_CS1_BASE (SAM_SMC_BASE+SAM_SMCCS1_OFFSET) +# define SAM_SMC_CS2_BASE (SAM_SMC_BASE+SAM_SMCCS2_OFFSET) +# define SAM_SMC_CS3_BASE (SAM_SMC_BASE+SAM_SMCCS3_OFFSET) + +#define SAM_SMCCS_SETUP(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS_PULSE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS_CYCLE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_CYCLE_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMCCS_TIMINGS(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_TIMINGS_OFFSET) +#endif + +#define SAM_SMCCS_MODE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_MODE_OFFSET) + +# define SAM_SMCCS0_SETUP (SAM_SMC_CS0_BASE+SAM_SMCCS_SETUP_OFFSET) +# define SAM_SMCCS0_PULSE (SAM_SMC_CS0_BASE+SAM_SMCCS_PULSE_OFFSET) +# define SAM_SMCCS0_CYCLE (SAM_SMC_CS0_BASE+SAM_SMCCS_CYCLE_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMCCS0_TIMINGS (SAM_SMC_CS0_BASE+SAM_SMCCS_TIMINGS_OFFSET) +# endif + +# define SAM_SMCCS0_MODE (SAM_SMC_CS0_BASE+SAM_SMCCS_MODE_OFFSET) + +# define SAM_SMCCS1_SETUP (SAM_SMC_CS1_BASE+SAM_SMCCS_SETUP_OFFSET) +# define SAM_SMCCS1_PULSE (SAM_SMC_CS1_BASE+SAM_SMCCS_PULSE_OFFSET) +# define SAM_SMCCS1_CYCLE (SAM_SMC_CS1_BASE+SAM_SMCCS_CYCLE_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMCCS1_TIMINGS (SAM_SMC_CS1_BASE+SAM_SMCCS_TIMINGS_OFFSET) +# endif + +# define SAM_SMCCS1_MODE (SAM_SMC_CS1_BASE+SAM_SMCCS_MODE_OFFSET) + +# define SAM_SMCCS2_SETUP (SAM_SMC_CS2_BASE+SAM_SMCCS_SETUP_OFFSET) +# define SAM_SMCCS2_PULSE (SAM_SMC_CS2_BASE+SAM_SMCCS_PULSE_OFFSET) +# define SAM_SMCCS2_CYCLE (SAM_SMC_CS2_BASE+SAM_SMCCS_CYCLE_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMCCS2_TIMINGS (SAM_SMC_CS2_BASE+SAM_SMCCS_TIMINGS_OFFSET) +# endif + +# define SAM_SMCCS2_MODE (SAM_SMC_CS2_BASE+SAM_SMCCS_MODE_OFFSET) + +# define SAM_SMCCS3_SETUP (SAM_SMC_CS3_BASE+SAM_SMCCS_SETUP_OFFSET) +# define SAM_SMCCS3_PULSE (SAM_SMC_CS3_BASE+SAM_SMCCS_PULSE_OFFSET) +# define SAM_SMCCS3_CYCLE (SAM_SMC_CS3_BASE+SAM_SMCCS_CYCLE_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SMCCS3_TIMINGS (SAM_SMC_CS3_BASE+SAM_SMCCS_TIMINGS_OFFSET) +# endif + +# define SAM_SMCCS3_MODE (SAM_SMC_CS3_BASE+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMC_OCMS (SAM_SMC_BASE+SAM_SMC_OCMS_OFFSET) +#define SAM_SMC_KEY1 (SAM_SMC_BASE+SAM_SMC_KEY1_OFFSET) +#define SAM_SMC_KEY2 (SAM_SMC_BASE+SAM_SMC_KEY2_OFFSET) +#define SAM_SMC_WPCR (SAM_SMC_BASE+SAM_SMC_WPCR_OFFSET) +#define SAM_SMC_WPSR (SAM_SMC_BASE+SAM_SMC_WPSR_OFFSET) + +/* SMC register bit definitions *********************************************************/ + +/* SMC NFC Configuration Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_CFG_PAGESIZE_SHIFT (0) /* Bits 0-1: Page size of NAND Flash device */ +# define SMC_CFG_PAGESIZE_MASK (3 << SMC_CFG_PAGESIZE_SHIFT) +# define SMC_CFG_PAGESIZE_528 (0 << SMC_CFG_PAGESIZE_SHIFT) /* 512 bytes + 16 byte spare */ +# define SMC_CFG_PAGESIZE_1056 (1 << SMC_CFG_PAGESIZE_SHIFT) /* 1024 Bytes + 32 bytes spare */ +# define SMC_CFG_PAGESIZE_2122 (2 << SMC_CFG_PAGESIZE_SHIFT) /* 2048 Bytes + 64 bytes spare */ +# define SMC_CFG_PAGESIZE_4224 (3 << SMC_CFG_PAGESIZE_SHIFT) /* 4096 Bytes + 128 bytes spare */ +# define SMC_CFG_WSPARE (1 << 8) /* Bit 8: Write Spare Area */ +# define SMC_CFG_RSPARE (1 << 9) /* Bit 9: Read Spare Area */ +# define SMC_CFG_EDGECTRL (1 << 12) /* Bit 12: Rising/Falling Edge Detection Control */ +# define SMC_CFG_RBEDGE (1 << 13) /* Bit 13: Ready/Busy Signal Edge Detection */ +# define SMC_CFG_DTOCYC_SHIFT (16) /* Bits 16-19: Data Timeout Cycle Number */ +# define SMC_CFG_DTOCYC_MASK (15 << SMC_CFG_DTOCYC_SHIFT) +# define SMC_CFG_DTOMUL_SHIFT (20) /* Bits 20-22: Data Timeout Multiplier */ +# define SMC_CFG_DTOMUL_MASK (7 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_1 (0 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_16 (1 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_128 (2 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_256 (3 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_1024 (4 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_4096 (5 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_65536 (6 << SMC_CFG_DTOMUL_SHIFT) +# define SMC_CFG_DTOMUL_1048576 (7 << SMC_CFG_DTOMUL_SHIFT) +#endif + +/* SMC NFC Control Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_CTRL_NFCEN (1 << 0) /* Bit 0: NAND Flash Controller Enable */ +# define SMC_CTRL_NFCDIS (1 << 1) /* Bit 1: NAND Flash Controller Disable */ +#endif + +/* SMC NFC Status Register, SMC NFC Interrupt Enable Register, SMC NFC Interrupt + * Disable Register, and SMC NFC Interrupt Mask Register common bit-field definitions + */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_SR_SMCSTS (1 << 0) /* Bit 0: NAND Flash Controller status (SR only) */ +# define SMC_INT_RBRISE (1 << 4) /* Bit 4: Ready Busy Rising Edge Detection Interrupt */ +# define SMC_INT_RBFALL (1 << 5) /* Bit 5: Ready Busy Falling Edge Detection Interrupt */ +# define SMC_SR_NFCBUSY (1 << 8) /* Bit 8: NFC Busy (SR only) */ +# define SMC_SR_NFCWR (1 << 11) /* Bit 11: NFC Write/Read Operation (SR only) */ +# define SMC_SR_NFCSID_SHIFT (12) /* Bits 12-14: NFC Chip Select ID (SR only) */ +# define SMC_SR_NFCSID_MASK (7 << SMC_SR_NFCSID_SHIFT) +# define SMC_INT_XFRDONE (1 << 16) /* Bit 16: Transfer Done Interrupt */ +# define SMC_INT_CMDDONE (1 << 17) /* Bit 17: Command Done Interrupt */ +# define SMC_INT_DTOE (1 << 20) /* Bit 20: Data Timeout Error Interrupt */ +# define SMC_INT_UNDEF (1 << 21) /* Bit 21: Undefined Area Access Interrupt */ +# define SMC_INT_AWB (1 << 22) /* Bit 22: Accessing While Busy Interrupt */ +# define SMC_INT_NFCASE (1 << 23) /* Bit 23: NFC Access Size Error Interrupt */ +#ifdef CONFIG_ARCH_CHIP_SAM3U +# define SMC_INT_RBEDGE(n) (1<<((n)+24)) +# define SMC_INT_RB_EDGE0 (1 << 24) /* Bit 24: Ready/Busy Line 0 Interrupt */ +# define SMC_INT_RB_EDGE1 (1 << 25) /* Bit 25: Ready/Busy Line 1 Interrupt */ +# define SMC_INT_RB_EDGE2 (1 << 26) /* Bit 26: Ready/Busy Line 2 Interrupt */ +# define SMC_INT_RB_EDGE3 (1 << 27) /* Bit 27: Ready/Busy Line 3 Interrupt */ +# define SMC_INT_RB_EDGE4 (1 << 28) /* Bit 28: Ready/Busy Line 4 Interrupt */ +# define SMC_INT_RB_EDGE5 (1 << 29) /* Bit 29: Ready/Busy Line 5 Interrupt */ +# define SMC_INT_RB_EDGE6 (1 << 30) /* Bit 30: Ready/Busy Line 6 Interrupt */ +# define SMC_INT_RB_EDGE7 (1 << 31) /* Bit 31: Ready/Busy Line 7 Interrupt */ +#else +# define SMC_INT_RB_EDGE0 (1 << 24) /* Bit 24: Ready/Busy Line 0 Interrupt */ +#endif +#endif + +/* SMC NFC Address Cycle Zero Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ADDR_CYCLE0_SHIFT (3) /* Bits 0-7: NAND Flash Array Address cycle 0 */ +# define SMC_ADDR_CYCLE0_MASK (0xff << SMC_ADDR_CYCLE0_SHIFT) +#endif + +/* SMC NFC Bank Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_BANK_SHIFT (0) /* Bits 0-2: Bank identifier */ +# define SMC_BANK_MASK (7 << SMC_BANK_SHIFT) +#endif + +/* SMC ECC Control Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCCTRL_RST (1 << 0) /* Bit 0: Reset ECC */ +# define SMC_ECCCTRL_SWRST (1 << 1) /* Bit 1: Software Reset */ +#endif + +/* SMC ECC MODE Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCMD_ECC_PAGESIZE_SHIFT (0) /* Bits 0-1 */ +# define SMC_ECCMD_ECC_PAGESIZE_MASK (3 << SMC_ECCMD_ECC_PAGESIZE_SHIFT) +# define SMC_ECCMD_ECC_PAGESIZE_528 (0 << SMC_ECCMD_ECC_PAGESIZE_SHIFT) /* 512 bytes + 16 byte spare */ +# define SMC_ECCMD_ECC_PAGESIZE_1056 (1 << SMC_ECCMD_ECC_PAGESIZE_SHIFT) /* 1024 Bytes + 32 bytes spare */ +# define SMC_ECCMD_ECC_PAGESIZE_2112 (2 << SMC_ECCMD_ECC_PAGESIZE_SHIFT) /* 2048 Bytes + 64 bytes spare */ +# define SMC_ECCMD_ECC_PAGESIZE_4224 (3 << SMC_ECCMD_ECC_PAGESIZE_SHIFT) /* 4096 Bytes + 128 bytes spare */ +# define SMC_ECCMD_TYPCORREC_SHIFT (4) /* Bits 4-5: type of correction */ +# define SMC_ECCMD_TYPCORREC_MASK (3 << SMC_ECCMD_TYPCORREC_SHIFT) +# define SMC_ECCMD_TYPCORREC_PAGE (0 << SMC_ECCMD_TYPCORREC_SHIFT) /* 1 bit correction for a page */ +# define SMC_ECCMD_TYPCORREC_256 (1 << SMC_ECCMD_TYPCORREC_SHIFT) /* 1 bit correction for 256 bytes */ +# define SMC_ECCMD_TYPCORREC_512 (2 << SMC_ECCMD_TYPCORREC_SHIFT) /* 1 bit correction for 512 bytes */ +#endif + +/* SMC ECC Status Register 1 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define _RECERR (0) /* Recoverable Error */ +# define _ECCERR (1) /* ECC Error */ +# define _MULERR (2) /* Multiple Error */ + +# define SMC_ECCSR1_RECERR(n) (1 << (((n)<<4)+_RECERR)) +# define SMC_ECCSR1_ECCERR(n) (1 << (((n)<<4)+_ECCERR)) +# define SMC_ECCSR1_MULERR(n) (1 << (((n)<<4)+_MULERR)) + +# define SMC_ECCSR1_RECERR0 SMC_ECCSR1_RECERR(0) +# define SMC_ECCSR1_ECCERR0 SMC_ECCSR1_ECCERR(0) +# define SMC_ECCSR1_MULERR0 SMC_ECCSR1_MULERR(0) +# define SMC_ECCSR1_RECERR1 SMC_ECCSR1_RECERR(1) +# define SMC_ECCSR1_ECCERR1 SMC_ECCSR1_ECCERR(1) +# define SMC_ECCSR1_MULERR1 SMC_ECCSR1_MULERR(1) +# define SMC_ECCSR1_RECERR2 SMC_ECCSR1_RECERR(2) +# define SMC_ECCSR1_ECCERR2 SMC_ECCSR1_ECCERR(2) +# define SMC_ECCSR1_MULERR2 SMC_ECCSR1_MULERR(2) +# define SMC_ECCSR1_RECERR3 SMC_ECCSR1_RECERR(3) +# define SMC_ECCSR1_ECCERR3 SMC_ECCSR1_ECCERR(3) +# define SMC_ECCSR1_MULERR3 SMC_ECCSR1_MULERR(3) +# define SMC_ECCSR1_RECERR4 SMC_ECCSR1_RECERR(4) +# define SMC_ECCSR1_ECCERR4 SMC_ECCSR1_ECCERR(4) +# define SMC_ECCSR1_MULERR4 SMC_ECCSR1_MULERR(4) +# define SMC_ECCSR1_RECERR5 SMC_ECCSR1_RECERR(5) +# define SMC_ECCSR1_ECCERR5 SMC_ECCSR1_ECCERR(5) +# define SMC_ECCSR1_MULERR5 SMC_ECCSR1_MULERR(5) +# define SMC_ECCSR1_RECERR6 SMC_ECCSR1_RECERR(6) +# define SMC_ECCSR1_ECCERR6 SMC_ECCSR1_ECCERR(6) +# define SMC_ECCSR1_MULERR6 SMC_ECCSR1_MULERR(6) +# define SMC_ECCSR1_RECERR7 SMC_ECCSR1_RECERR(7) +# define SMC_ECCSR1_ECCERR7 SMC_ECCSR1_ECCERR(7) +# define SMC_ECCSR1_MULERR7 SMC_ECCSR1_MULERR(7) +#endif + +/* SMC ECC Status Register 2 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCSR2_RECERR(n) (1 << ((((n)-8)<<4)+_RECERR)) +# define SMC_ECCSR2_ECCERR(n) (1 << ((((n)-8)<<4)+_ECCERR)) +# define SMC_ECCSR2_MULERR(n) (1 << ((((n)-8)<<4)+_MULERR)) + +# define SMC_ECCSR2_RECERR8 SMC_ECCSR2_RECERR(8) +# define SMC_ECCSR2_ECCERR8 SMC_ECCSR2_ECCERR(8) +# define SMC_ECCSR2_MULERR8 SMC_ECCSR2_MULERR(8) +# define SMC_ECCSR2_RECERR9 SMC_ECCSR2_RECERR(9) +# define SMC_ECCSR2_ECCERR9 SMC_ECCSR2_ECCERR(9) +# define SMC_ECCSR2_MULERR9 SMC_ECCSR2_MULERR(9) +# define SMC_ECCSR2_RECERR10 SMC_ECCSR2_RECERR(10) +# define SMC_ECCSR2_ECCERR10 SMC_ECCSR2_ECCERR(10) +# define SMC_ECCSR2_MULERR10 SMC_ECCSR2_MULERR(10) +# define SMC_ECCSR2_RECERR11 SMC_ECCSR2_RECERR(11) +# define SMC_ECCSR2_ECCERR11 SMC_ECCSR2_ECCERR(11) +# define SMC_ECCSR2_MULERR11 SMC_ECCSR2_MULERR(11) +# define SMC_ECCSR2_RECERR12 SMC_ECCSR2_RECERR(12) +# define SMC_ECCSR2_ECCERR12 SMC_ECCSR2_ECCERR(12) +# define SMC_ECCSR2_MULERR12 SMC_ECCSR2_MULERR(12) +# define SMC_ECCSR2_RECERR13 SMC_ECCSR2_RECERR(13) +# define SMC_ECCSR2_ECCERR13 SMC_ECCSR2_ECCERR(13) +# define SMC_ECCSR2_MULERR13 SMC_ECCSR2_MULERR(13) +# define SMC_ECCSR1_RECERR14 SMC_ECCSR2_RECERR(14) +# define SMC_ECCSR1_ECCERR14 SMC_ECCSR2_ECCERR(14) +# define SMC_ECCSR1_MULERR14 SMC_ECCSR2_MULERR(14) +# define SMC_ECCSR1_RECERR15 SMC_ECCSR2_RECERR(15) +# define SMC_ECCSR1_ECCERR15 SMC_ECCSR2_ECCERR(15) +# define SMC_ECCSR1_MULERR15 SMC_ECCSR2_MULERR(15) +#endif + +/* Registers for 1 ECC for a page of 512/1024/2048/4096 bytes */ +/* SMC_ECC_PR0 */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCPR0_BITADDR_SHIFT (0) /* Bits 0-3: Bit Address */ +# define SMC_ECCPR0_BITADDR_MASK (15 << SMC_ECCPR0_BITADDR_SHIFT) +# define SMC_ECCPR0_WORDADDR_SHIFT (4) /* Bits 4-15: Word Address */ +# define SMC_ECCPR0_WORDADDR_MASK (0xfff << SMC_ECCPR0_WORDADDR_SHIFT) + +#ifdef CONFIG_ARCH_CHIP_SAM3U +# define SMC_ECCPR1_NPARITY_SHIFT (0) /* Bits 0-15 */ +# define SMC_ECCPR1_NPARITY_MASK (0xffff << SMC_ECCPR1_NPARITY_SHIFT) +#endif +#endif + +/* Registers for 1 ECC per 512 bytes for a page of 512/2048/4096 bytes, 8-bit word */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCPR512_BITADDR_SHIFT (0) /* Bits 0-3: Bit Address */ +# define SMC_ECCPR512_BITADDR_MASK (15 << SMC_ECCPR512_BITADDR_SHIFT) +# define SMC_ECCPR512_WORDADDR_SHIFT (4) /* Bits 4-15: Word Address */ +# define SMC_ECCPR512_WORDADDR_MASK (0xfff << SMC_ECCPR512_WORDADDR_SHIFT) +# define SMC_ECCPR512_NPARITY_SHIFT (12) /* Bits 12-23 (or is it 31?) */ +# define SMC_ECCPR512_NPARITY_MASK (0xfff << SMC_ECCPR512_NPARITY_SHIFT) +#endif + +/* Registers for 1 ECC per 256 bytes for a page of 512/2048/4096 bytes, 8-bit word */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_ECCPR256_BITADDR_SHIFT (0) /* Bits 0-2: Bit Address */ +# define SMC_ECCPR256_BITADDR_MASK (7 << SMC_ECCPR256_BITADDR_SHIFT) +# define SMC_ECCPR256_WORDADDR_SHIFT (4) /* Bits 4-10: Word Address */ +# define SMC_ECCPR256_WORDADDR_MASK (0x7f << SMC_ECCPR256_WORDADDR_SHIFT) +# define SMC_ECCPR256_NPARITY_SHIFT (12) /* Bits 12-22 */ +# define SMC_ECCPR256_NPARITY_MASK (0x7ff << SMC_ECCPR256_NPARITY_SHIFT) +#endif + +/* SMC Setup Register */ + +#define SMCCS_SETUP_NWESETUP_SHIFT (0) /* Bits 0-5: NWE Setup length */ +#define SMCCS_SETUP_NWESETUP_MASK (63 << SMCCS_SETUP_NWESETUP_SHIFT) +# define SMCCS_SETUP_NWESETUP(n) ((n) << SMCCS_SETUP_NWESETUP_SHIFT) +#define SMCCS_SETUP_NCSWRSETUP_SHIFT (8) /* Bits 8-13: NCS Setup length in Write access */ +#define SMCCS_SETUP_NCSWRSETUP_MASK (63 << SMCCS_SETUP_NCSWRSETUP_SHIFT) +# define SMCCS_SETUP_NCSWRSETUP(n) ((n) << SMCCS_SETUP_NCSWRSETUP_SHIFT) +#define SMCCS_SETUP_NRDSETUP_SHIFT (16) /* Bits 16-21: NRD Setup length */ +#define SMCCS_SETUP_NRDSETUP_MASK (63 << SMCCS_SETUP_NRDSETUP_SHIFT) +# define SMCCS_SETUP_NRDSETUP(n) ((n) << SMCCS_SETUP_NRDSETUP_SHIFT) +#define SMCCS_SETUP_NCSRDSETUP_SHIFT (24) /* Bits 24-29: NCS Setup length in Read access */ +#define SMCCS_SETUP_NCSRDSETUP_MASK (63 << SMCCS_SETUP_NCSRDSETUP_SHIFT) +# define SMCCS_SETUP_NCSRDSETUP(n) ((n) << SMCCS_SETUP_NCSRDSETUP_SHIFT) + +/* SMC Pulse Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SMCCS_PULSE_NWEPULSE_SHIFT (0) /* Bits 0-6: NWE Pulse Length */ +# define SMCCS_PULSE_NWEPULSE_MASK (127 << SMCCS_PULSE_NWEPULSE_SHIFT) +# define SMCCS_PULSE_NWEPULSE(n) ((n) << SMCCS_PULSE_NWEPULSE_SHIFT) +# define SMCCS_PULSE_NCSWRPULSE_SHIFT (8) /* Bits 8-14: NCS Pulse Length in WRITE Access */ +# define SMCCS_PULSE_NCSWRPULSE_MASK (127 << SMCCS_PULSE_NCSWRPULSE_SHIFT) +# define SMCCS_PULSE_NCSWRPULSE(n) ((n) << SMCCS_PULSE_NCSWRPULSE_SHIFT) +# define SMCCS_PULSE_NRDPULSE_SHIFT (16) /* Bits 16-22: NRD Pulse Length */ +# define SMCCS_PULSE_NRDPULSE_MASK (127 << SMCCS_PULSE_NRDPULSE_SHIFT) +# define SMCCS_PULSE_NRDPULSE(n) ((n) << SMCCS_PULSE_NRDPULSE_SHIFT) +# define SMCCS_PULSE_NCSRDPULSE_SHIFT (24) /* Bits 24-30: NCS Pulse Length in READ Access */ +# define SMCCS_PULSE_NCSRDPULSE_MASK (127 << SMCCS_PULSE_NCSRDPULSE_SHIFT) +# define SMCCS_PULSE_NCSRDPULSE(n) ((n) << SMCCS_PULSE_NCSRDPULSE_SHIFT) +#else +# define SMCCS_PULSE_NWEPULSE_SHIFT (0) /* Bits 0-5: NWE Pulse Length */ +# define SMCCS_PULSE_NWEPULSE_MASK (63 << SMCCS_PULSE_NWEPULSE_SHIFT) +# define SMCCS_PULSE_NWEPULSE(n) ((n) << SMCCS_PULSE_NWEPULSE_SHIFT) +# define SMCCS_PULSE_NCSWRPULSE_SHIFT (8) /* Bits 8-13: NCS Pulse Length in WRITE Access */ +# define SMCCS_PULSE_NCSWRPULSE_MASK (63 << SMCCS_PULSE_NCSWRPULSE_SHIFT) +# define SMCCS_PULSE_NCSWRPULSE(n) ((n) << SMCCS_PULSE_NCSWRPULSE_SHIFT) +# define SMCCS_PULSE_NRDPULSE_SHIFT (16) /* Bits 16-21: NRD Pulse Length */ +# define SMCCS_PULSE_NRDPULSE_MASK (63 << SMCCS_PULSE_NRDPULSE_SHIFT) +# define SMCCS_PULSE_NRDPULSE(n) ((n) << SMCCS_PULSE_NRDPULSE_SHIFT) +# define SMCCS_PULSE_NCSRDPULSE_SHIFT (24) /* Bits 24-29: NCS Pulse Length in READ Access */ +# define SMCCS_PULSE_NCSRDPULSE_MASK (63 << SMCCS_PULSE_NCSRDPULSE_SHIFT) +# define SMCCS_PULSE_NCSRDPULSE(n) ((n) << SMCCS_PULSE_NCSRDPULSE_SHIFT) +#endif + +/* SMC Cycle Register */ + +#define SMCCS_CYCLE_NWECYCLE_SHIFT (0) /* Bits 0-8: Total Write Cycle Length */ +#define SMCCS_CYCLE_NWECYCLE_MASK (0x1ff << SMCCS_CYCLE_NWECYCLE_SHIFT) +# define SMCCS_CYCLE_NWECYCLE(n) ((n) << SMCCS_CYCLE_NWECYCLE_SHIFT) +#define SMCCS_CYCLE_NRDCYCLE_SHIFT (16) /* Bits 16-24: Total Read Cycle Length */ +#define SMCCS_CYCLE_NRDCYCLE_MASK (0x1ff << SMCCS_CYCLE_NRDCYCLE_SHIFT) +# define SMCCS_CYCLE_NRDCYCLE(n) ((n) << SMCCS_CYCLE_NRDCYCLE_SHIFT) + +/* SMC Timings Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMCCS_TIMINGS_TCLR_SHIFT (0) /* Bits 0-3: CLE to REN Low Delay */ +# define SMCCS_TIMINGS_TCLR_MASK (15 << SMCCS_TIMINGS_TCLR_SHIFT) +# define SMCCS_TIMINGS_TADL_SHIFT (4) /* Bits 4-7: ALE to Data Start */ +# define SMCCS_TIMINGS_TADL_MASK (15 << SMCCS_TIMINGS_TADL_SHIFT) +# define SMCCS_TIMINGS_TAR_SHIFT (8) /* Bits 8-11: ALE to REN Low Delay */ +# define SMCCS_TIMINGS_TAR_MASK (15 << SMCCS_TIMINGS_TAR_SHIFT) +# define SMCCS_TIMINGS_OCMS (1 << 12) /* Bit 12: Off Chip Memory Scrambling Enable */ +# define SMCCS_TIMINGS_TRR_SHIFT (16) /* Bits 16-19: Ready to REN Low Delay */ +# define SMCCS_TIMINGS_TRR_MASK (15 << SMCCS_TIMINGS_TRR_SHIFT) +# define SMCCS_TIMINGS_TWB_SHIFT (24) /* Bits 24-27: WEN High to REN to Busy */ +# define SMCCS_TIMINGS_TWB_MASK (15 << SMCCS_TIMINGS_TWB_SHIFT) +# define SMCCS_TIMINGS_RBNSEL_SHIFT (28) /* Bits 28-30: Ready/Busy Line Selection */ +# define SMCCS_TIMINGS_RBNSEL_MASK (7 << SMCCS_TIMINGS_RBNSEL_SHIFT) +# define SMCCS_TIMINGS_NFSEL (1 << 31) /* Bit 31: NAND Flash Selection */ +#endif + +/* SMC Mode Register */ + +#define SMCCS_MODE_READMODE (1 << 0) /* Bit 0: Read mode */ +#define SMCCS_MODE_WRITEMODE (1 << 1) /* Bit 1: Write mode */ +#define SMCCS_MODE_EXNWMODE_SHIFT (4) /* Bits 4-5: NWAIT Mode */ +#define SMCCS_MODE_EXNWMODE_MASK (3 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_DISABLED (0 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_FROZEN (2 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_READY (3 << SMCCS_MODE_EXNWMODE_SHIFT) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMCCS_MODE_BAT (1 << 8) /* Bit 8: Byte Access Type */ +# define SMCCS_MODE_DBW_SHIFT (12) /* Bits 12-13: Data Bus Width */ +# define SMCCS_MODE_DBW_MASK (3 << SMCCS_MODE_DBW_SHIFT) +# define SMCCS_MODE_DBW_8BITS (0 << 12) /* 8 bits */ +# define SMCCS_MODE_DBW_16BITS (1 << 12) /* 16 bits */ +# define SMCCS_MODE_DBW_32BITS (2 << 12) /* 32 bits */ +#endif + +#define SMCCS_MODE_TDFCYCLES_SHIFT (16) /* Bits 16-19: Data Float Time */ +#define SMCCS_MODE_TDFCYCLES_MASK (15 << SMCCS_MODE_TDFCYCLES_SHIFT) +# define SMCCS_MODE_TDFCYCLES(n) ((uint32_t)(n) << SMCCS_MODE_TDFCYCLES_SHIFT) +#define SMCCS_MODE_TDFMODE (1 << 20) /* Bit 20: TDF Optimization */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SMCCS_MODE_PMEN (1 << 24) /* Bit 24: Page Mode Enabled */ +# define SMCCS_MODE_PS_SHIFT (28) /* Bits 28-29: Page Size */ +# define SMCCS_MODE_PS_MASK (3 << SMCCS_MODE_PS_SHIFT) +# define SMCCS_MODE_PS_SIZE_4BYTES (0 << SMCCS_MODE_PS_SHIFT) /* 4 bytes */ +# define SMCCS_MODE_PS_SIZE_8BYTES (1 << SMCCS_MODE_PS_SHIFT) /* 8 bytes */ +# define SMCCS_MODE_PS_SIZE_16BYTES (2 << SMCCS_MODE_PS_SHIFT) /* 16 bytes */ +# define SMCCS_MODE_PS_SIZE_32BYTES (3 << SMCCS_MODE_PS_SHIFT) /* 32 bytes */ +#endif + +/* SMC OCMS Mode Register */ + +#define SMC_OCMS_SMSE (1 << 0) /* Bit 0: Static Memory Controller Scrambling Enable */ + +#if !defined(CONFIG_ARCH_CHIP_SAM4E) +# define SMC_OCMS_SRSE (1 << 1) /* Bit 1: SRAM Scrambling Enable */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SMC_OCMS_CSSE(n) (1 << ((n)+16)) /* Chip Select (n=0-3) Scrambling Enable */ +# define SMC_OCMS_CS0SE (1 << 16) /* Bit 16: Chip Select 0 Scrambling Enable */ +# define SMC_OCMS_CS1SE (1 << 17) /* Bit 17: Chip Select 1 Scrambling Enable */ +# define SMC_OCMS_CS2SE (1 << 18) /* Bit 18: Chip Select 2 Scrambling Enable */ +# define SMC_OCMS_CS3SE (1 << 19) /* Bit 19: Chip Select 3 Scrambling Enable */ +#endif + +/* SMC KEY1/2 Registers (32-bit data) */ + +/* SMC Write Protect Mode Register */ + +#define SMC_WPCR_WPPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define SMC_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection KEY password */ +#define SMC_WPCR_WPKEY_MASK (0x00ffffff << SMC_WPCR_WPKEY_SHIFT) +# define SMC_WPCR_WPKEY (0x00534d43 << SMC_WPCR_WPKEY_SHIFT) + +/* SMC Write Protection Status */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SMC_WPSR_PVS_SHIFT (0) /* Bits 0-3: Write Protection Violation Status */ +# define SMC_WPSR_PVS_MASK (15 << SMC_WPSR_PVS_SHIFT) +# define SMC_WPSR_PVS_NONE (0 << SMC_WPSR_PVS_SHIFT) /* No Write Protection Violation */ +# define SMC_WPSR_PVS_ RCREG (1 << SMC_WPSR_PVS_SHIFT) /* Attempt to write a control reg */ +# define SMC_WPSR_PVS_RESET (2 << SMC_WPSR_PVS_SHIFT) /* Software reset */ +# define SMC_WPSR_PVS_BOTH (3 << SMC_WPSR_PVS_SHIFT) /* Write + reset */ +#elif defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SMC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Source */ +#endif + +#define SMC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define SMC_WPSR_WPVSRC_MASK (0xffff << SMC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_SMC_H */ diff --git a/arch/arm/src/sam34/chip/sam_spi.h b/arch/arm/src/sam34/chip/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..ce740c22e55e1739c7df4fc38f0ff2fc465dc1aa --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_spi.h @@ -0,0 +1,290 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_spi.h + * Serial Peripheral Interface (SPI) definitions for the SAM3U, SAM4S, SAM4E, and SAM4L + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_SPI_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_SPI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_SPI_NCS 4 /* Four chip selects */ + +/* SPI register offsets *****************************************************************/ + +#define SAM_SPI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SPI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_SPI_RDR_OFFSET 0x0008 /* Receive Data Register */ +#define SAM_SPI_TDR_OFFSET 0x000c /* Transmit Data Register */ +#define SAM_SPI_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_SPI_IER_OFFSET 0x0014 /* Interrupt Enable Register */ +#define SAM_SPI_IDR_OFFSET 0x0018 /* Interrupt Disable Register */ +#define SAM_SPI_IMR_OFFSET 0x001c /* Interrupt Mask Register */ + /* 0x20-0x2c: Reserved */ +#define SAM_SPI_CSR0_OFFSET 0x0030 /* Chip Select Register 0 */ +#define SAM_SPI_CSR1_OFFSET 0x0034 /* Chip Select Register 1 */ +#define SAM_SPI_CSR2_OFFSET 0x0038 /* Chip Select Register 2 */ +#define SAM_SPI_CSR3_OFFSET 0x003c /* Chip Select Register 3 */ + /* 0x40-0xe0: Reserved */ +#define SAM_SPI_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +#define SAM_SPI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0xec-0xf4: Reserved */ +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SAM_SPI_FEATURES_OFFSET 0x00f8 /* Features Register */ +# define SAM_SPI_VERSION_OFFSET 0x00fc /* Version Register */ +#endif + /* 0x100-0x124 Reserved for PDC Registers */ + +/* SPI register addresses ***************************************************************/ + +#define SAM_SPI0_CR (SAM_SPI0_BASE+SAM_SPI_CR_OFFSET) /* Control Register */ +#define SAM_SPI0_MR (SAM_SPI0_BASE+SAM_SPI_MR_OFFSET) /* Mode Register */ +#define SAM_SPI0_RDR (SAM_SPI0_BASE+SAM_SPI_RDR_OFFSET) /* Receive Data Register */ +#define SAM_SPI0_TDR (SAM_SPI0_BASE+SAM_SPI_TDR_OFFSET) /* Transmit Data Register */ +#define SAM_SPI0_SR (SAM_SPI0_BASE+SAM_SPI_SR_OFFSET) /* Status Register */ +#define SAM_SPI0_IER (SAM_SPI0_BASE+SAM_SPI_IER_OFFSET) /* Interrupt Enable Register */ +#define SAM_SPI0_IDR (SAM_SPI0_BASE+SAM_SPI_IDR_OFFSET) /* Interrupt Disable Register */ +#define SAM_SPI0_IMR (SAM_SPI0_BASE+SAM_SPI_IMR_OFFSET) /* Interrupt Mask Register */ +#define SAM_SPI0_CSR0 (SAM_SPI0_BASE+SAM_SPI_CSR0_OFFSET) /* Chip Select Register 0 */ +#define SAM_SPI0_CSR1 (SAM_SPI0_BASE+SAM_SPI_CSR1_OFFSET) /* Chip Select Register 1 */ +#define SAM_SPI0_CSR2 (SAM_SPI0_BASE+SAM_SPI_CSR2_OFFSET) /* Chip Select Register 2 */ +#define SAM_SPI0_CSR3 (SAM_SPI0_BASE+SAM_SPI_CSR3_OFFSET) /* Chip Select Register 3 */ +#define SAM_SPI0_WPCR (SAM_SPI0_BASE+SAM_SPI_WPCR_OFFSET) /* Write Protection Control Register */ +#define SAM_SPI0_WPSR (SAM_SPI0_BASE+SAM_SPI_WPSR_OFFSET) /* Write Protection Status Register */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SAM_SPI0_FEATURES (SAM_SPI0_BASE+SAM_SPI_FEATURES_OFFSET) +# define SAM_SPI0_VERSION (SAM_SPI0_BASE+SAM_SPI_VERSION_OFFSET) +#endif + +#define SAM_SPI1_CR (SAM_SPI1_BASE+SAM_SPI_CR_OFFSET) /* Control Register */ +#define SAM_SPI1_MR (SAM_SPI1_BASE+SAM_SPI_MR_OFFSET) /* Mode Register */ +#define SAM_SPI1_RDR (SAM_SPI1_BASE+SAM_SPI_RDR_OFFSET) /* Receive Data Register */ +#define SAM_SPI1_TDR (SAM_SPI1_BASE+SAM_SPI_TDR_OFFSET) /* Transmit Data Register */ +#define SAM_SPI1_SR (SAM_SPI1_BASE+SAM_SPI_SR_OFFSET) /* Status Register */ +#define SAM_SPI1_IER (SAM_SPI1_BASE+SAM_SPI_IER_OFFSET) /* Interrupt Enable Register */ +#define SAM_SPI1_IDR (SAM_SPI1_BASE+SAM_SPI_IDR_OFFSET) /* Interrupt Disable Register */ +#define SAM_SPI1_IMR (SAM_SPI1_BASE+SAM_SPI_IMR_OFFSET) /* Interrupt Mask Register */ +#define SAM_SPI1_CSR0 (SAM_SPI1_BASE+SAM_SPI_CSR0_OFFSET) /* Chip Select Register 0 */ +#define SAM_SPI1_CSR1 (SAM_SPI1_BASE+SAM_SPI_CSR1_OFFSET) /* Chip Select Register 1 */ +#define SAM_SPI1_CSR2 (SAM_SPI1_BASE+SAM_SPI_CSR2_OFFSET) /* Chip Select Register 2 */ +#define SAM_SPI1_CSR3 (SAM_SPI1_BASE+SAM_SPI_CSR3_OFFSET) /* Chip Select Register 3 */ +#define SAM_SPI1_WPCR (SAM_SPI1_BASE+SAM_SPI_WPCR_OFFSET) /* Write Protection Control Register */ +#define SAM_SPI1_WPSR (SAM_SPI1_BASE+SAM_SPI_WPSR_OFFSET) /* Write Protection Status Register */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SAM_SPI1_FEATURES (SAM_SPI1_BASE+SAM_SPI_FEATURES_OFFSET) +# define SAM_SPI1_VERSION (SAM_SPI1_BASE+SAM_SPI_VERSION_OFFSET) +#endif + +/* SPI register bit definitions *********************************************************/ + +/* SPI Control Register */ + +#define SPI_CR_SPIEN (1 << 0) /* Bit 0: SPI Enable */ +#define SPI_CR_SPIDIS (1 << 1) /* Bit 1: SPI Disable */ +#define SPI_CR_SWRST (1 << 7) /* Bit 7: SPI Software Reset */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SPI_CR_FLUSHFIFO (1 << 8) /* Bit 8: Flush Fifo Command */ +#endif + +#define SPI_CR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Mode Register */ + +#define SPI_MR_MSTR (1 << 0) /* Bit 0: Master/Slave Mode */ +#define SPI_MR_PS (1 << 1) /* Bit 1: Peripheral Select */ +#define SPI_MR_PCSDEC (1 << 2) /* Bit 2: Chip Select Decode */ +#define SPI_MR_MODFDIS (1 << 4) /* Bit 4: Mode Fault Detection */ +#define SPI_MR_WDRBT (1 << 5) /* Bit 5: Wait Data Read Before Transfer */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SPI_MR_RXFIFOEN (1 << 6) /* Bit 6: FIFO in Reception Enable */ +#endif + +#define SPI_MR_LLB (1 << 7) /* Bit 7: Local Loopback Enable */ +#define SPI_MR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_MR_PCS_MASK (15 << SPI_MR_PCS_SHIFT) +# define SPI_MR_PCS0 (0 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_MR_PCS1 (1 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_MR_PCS2 (3 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_MR_PCS3 (7 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_MR_DLYBCS_SHIFT (24) /* Bits 24-31: Delay Between Chip Selects */ +#define SPI_MR_DLYBCS_MASK (0xff << SPI_MR_DLYBCS_SHIFT) + +/* SPI Receive Data Register */ + +#define SPI_RDR_RD_SHIFT (0) /* Bits 0-15: Receive Data */ +#define SPI_RDR_RD_MASK (0xffff << SPI_RDR_RD_SHIFT) +#define SPI_RDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_RDR_PCS_MASK (15 << SPI_RDR_PCS_SHIFT) +# define SPI_RDR_PCS0 (0 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_RDR_PCS1 (1 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_RDR_PCS2 (3 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_RDR_PCS3 (7 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ + +/* SPI Transmit Data Register */ + +#define SPI_TDR_TD_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define SPI_TDR_TD_MASK (0xffff << SPI_TDR_TD_SHIFT) +#define SPI_TDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_TDR_PCS_MASK (15 << SPI_TDR_PCS_SHIFT) +# define SPI_TDR_PCS0 (0 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_TDR_PCS1 (1 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_TDR_PCS2 (3 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_TDR_PCS3 (7 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_TDR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Status Register, SPI Interrupt Enable Register, SPI Interrupt Disable Register, + * and SPI Interrupt Mask Register (common bit fields) + */ + +#define SPI_INT_RDRF (1 << 0) /* Bit 0: Receive Data Register Full Interrupt */ +#define SPI_INT_TDRE (1 << 1) /* Bit 1: Transmit Data Register Empty Interrupt */ +#define SPI_INT_MODF (1 << 2) /* Bit 2: Mode Fault Error Interrupt */ +#define SPI_INT_OVRES (1 << 3) /* Bit 3: Overrun Error Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SPI_INT_ENDRX (1 << 4) /* Bit 4: End of RX buffer */ +# define SPI_INT_ENDTX (1 << 5) /* Bit 5: End of TX buffer */ +# define SPI_INT_RXBUFF (1 << 6) /* Bit 6: RX Buffer Full */ +# define SPI_INT_TXBUFE (1 << 7) /* Bit 7: TX Buffer Empty */ +#endif + +#define SPI_INT_NSSR (1 << 8) /* Bit 8: NSS Rising Interrupt */ +#define SPI_INT_TXEMPTY (1 << 9) /* Bit 9: Transmission Registers Empty Interrupt */ +#define SPI_INT_UNDES (1 << 10) /* Bit 10: Underrun Error Status Interrupt (slave) */ +#define SPI_SR_SPIENS (1 << 16) /* Bit 16: SPI Enable Status (SR only) */ + +/* SPI Chip Select Registers 0-3 */ + +#define SPI_CSR_CPOL (1 << 0) /* Bit 0: Clock Polarity */ +#define SPI_CSR_NCPHA (1 << 1) /* Bit 1: Clock Phase */ +#define SPI_CSR_CSNAAT (1 << 2) /* Bit 2: Chip Select Not Active After Transfer */ +#define SPI_CSR_CSAAT (1 << 3) /* Bit 3: Chip Select Active After Transfer */ +#define SPI_CSR_BITS_SHIFT (4) /* Bits 4-7: Bits Per Transfer */ +#define SPI_CSR_BITS_MASK (15 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_BITS(n) (((n)-8) << SPI_CSR_BITS_SHIFT) /* n, n=8-16 */ +# define SPI_CSR_BITS8 (0 << SPI_CSR_BITS_SHIFT) /* 8 */ +# define SPI_CSR_BITS9 (1 << SPI_CSR_BITS_SHIFT) /* 9 */ +# define SPI_CSR_BITS10 (2 << SPI_CSR_BITS_SHIFT) /* 10 */ +# define SPI_CSR_BITS11 (3 << SPI_CSR_BITS_SHIFT) /* 11 */ +# define SPI_CSR_BITS12 (4 << SPI_CSR_BITS_SHIFT) /* 12 */ +# define SPI_CSR_BITS13 (5 << SPI_CSR_BITS_SHIFT) /* 13 */ +# define SPI_CSR_BITS14 (6 << SPI_CSR_BITS_SHIFT) /* 14 */ +# define SPI_CSR_BITS15 (7 << SPI_CSR_BITS_SHIFT) /* 15 */ +# define SPI_CSR_BITS16 (8 << SPI_CSR_BITS_SHIFT) /* 16 */ +#define SPI_CSR_SCBR_SHIFT (8) /* Bits 8-15: Serial Clock Baud Rate */ +#define SPI_CSR_SCBR_MASK (0xff << SPI_CSR_SCBR_SHIFT) +# define SPI_CSR_SCBR(n) ((uint32_t)(n) << SPI_CSR_SCBR_SHIFT) +#define SPI_CSR_DLYBS_SHIFT (16) /* Bits 16-23: Delay Before SPCK */ +#define SPI_CSR_DLYBS_MASK (0xff << SPI_CSR_DLYBS_SHIFT) +# define SPI_CSR_DLYBS(n) ((uint32_t)(n) << SPI_CSR_DLYBS_SHIFT) +#define SPI_CSR_DLYBCT_SHIFT (24) /* Bits 24-31: Delay Between Consecutive Transfers */ +#define SPI_CSR_DLYBCT_MASK (0xff << SPI_CSR_DLYBCT_SHIFT) +# define SPI_CSR_DLYBCT(n) ((uint32_t)(n) << SPI_CSR_DLYBCT_SHIFT) + +/* SPI Write Protection Control Register */ + +#define SPI_WPCR_WPEN (1 << 0) /* Bit 0: SPI Write Protection Enable */ +#define SPI_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: SPI Write Protection Key Password */ +#define SPI_WPCR_WPKEY_MASK (0x00ffffff << SPI_WPCR_WPKEY_SHIFT) +# define SPI_WPCR_WPKEY (0x00535049 << SPI_WPCR_WPKEY_SHIFT) + +/* SPI Write Protection Status Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SPI_WPSR_WPVS (1 << 0) /* Bit 0: SPI Write Protection Violation Status */ +#else +# define SPI_WPSR_WPVS_SHIFT (0) /* Bits 0-2: SPI Write Protection Violation Status */ +# define SPI_WPSR_WPVS_MASK (7 << SPI_WPSR_WPVS_SHIFT) +#endif + +#define SPI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-15: SPI Write Protection Violation Source */ +#define SPI_WPSR_WPVSRC_MASK (0xff << SPI_WPSR_WPVSRC_SHIFT) + +/* Features Register */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SPI_FEATURES_NCS_SHIFT (0) /* Bits 0-3: Number of Chip Selects */ +# define SPI_FEATURES_NCS_MASK (15 << SPI_FEATURES_NCS_SHIFT) +# define SPI_FEATURES_PCONF (1 << 4) /* Bit 4: Polarity Configurable */ +# define SPI_FEATURES_PPNCONF (1 << 5) /* Bit 5: Polarity Positive if Polarity not Configurable */ +# define SPI_FEATURES_PHCONF (1 << 6) /* Bit 6: Phase Configurable */ +# define SPI_FEATURES_PHZNCONF (1 << 7) /* Bit 7: Phase is Zero if Phase not Configurable */ +# define SPI_FEATURES_LENCONF (1 << 8) /* Bit 8: Character Length Configurable */ +# define SPI_FEATURES_LENNCONF_SHIFT (9) /* Bits 9-15: Character Length if not Configurable */ +# define SPI_FEATURES_LENNCONF_MASK (0x7f << SPI_FEATURES_LENNCONF_SHIFT) +# define SPI_FEATURES_EXTDEC (1 << 16) /* Bit 16: External Decoder True */ +# define SPI_FEATURES_CSNAATIMPL (1 << 17) /* Bit 17: CSNAAT Features Implemented */ +# define SPI_FEATURES_BRPBHSB (1 << 18) /* Bit 18: Bridge Type is PB to HSB */ +# define SPI_FEATURES_FIFORIMPL (1 << 19) /* Bit 19: FIFO in Reception Implemented */ +# define SPI_FEATURES_SWIMPL (1 << 20) /* Bit 20: Spurious Write Protection Implemented */ +#endif + +/* Version Register */ + +#ifdef CONFIG_ARCH_CHIP_SAM4L +# define SPI_VERSION_VERSION_SHIFT (0) /* Bits 0-11: Module version number */ +# define SPI_VERSION_VERSION_MASK (0xfff << SPI_VERSION_VERSION_SHIFT) +# define SPI_VERSION_MFN_SHIFT (16) /* Bits 16-18: Reserved */ +# define SPI_VERSION_MFN_MASK (7 << SPI_VERSION_MFN_SHIFT) +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_SPI_H */ diff --git a/arch/arm/src/sam34/chip/sam_ssc.h b/arch/arm/src/sam34/chip/sam_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..c1b6fd7ce362ac5c36120d24605c87941bfcb474 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_ssc.h @@ -0,0 +1,295 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_ssc.h + * Synchronous Serial Controller (SSC) definitions for the SAM3U and SAM4S + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_SSC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_SSC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SSC register offsets *****************************************************************/ + +#define SAM_SSC_CR_OFFSET 0x000 /* Control Register */ +#define SAM_SSC_CMR_OFFSET 0x004 /* Clock Mode Register */ + /* 0x008: Reserved */ + /* 0x00c: Reserved */ +#define SAM_SSC_RCMR_OFFSET 0x010 /* Receive Clock Mode Register */ +#define SAM_SSC_RFMR_OFFSET 0x014 /* Receive Frame Mode Register */ +#define SAM_SSC_TCMR_OFFSET 0x018 /* Transmit Clock Mode Register */ +#define SAM_SSC_TFMR_OFFSET 0x01c /* Transmit Frame Mode Register */ +#define SAM_SSC_RHR_OFFSET 0x020 /* Receive Holding Register */ +#define SAM_SSC_THR_OFFSET 0x024 /* Transmit Holding Register */ + /* 0x028: Reserved */ + /* 0x02c: Reserved */ +#define SAM_SSC_RSHR_OFFSET 0x030 /* Receive Sync. Holding Register */ +#define SAM_SSC_TSHR_OFFSET 0x034 /* Transmit Sync. Holding Register */ +#define SAM_SSC_RC0R_OFFSET 0x038 /* Receive Compare 0 Register */ +#define SAM_SSC_RC1R_OFFSET 0x03c /* Receive Compare 1 Register */ +#define SAM_SSC_SR_OFFSET 0x040 /* Status Register */ +#define SAM_SSC_IER_OFFSET 0x044 /* Interrupt Enable Register */ +#define SAM_SSC_IDR_OFFSET 0x048 /* Interrupt Disable Register */ +#define SAM_SSC_IMR_OFFSET 0x04c /* Interrupt Mask Register */ +#define SAM_SSC_WPMR_OFFSET 0x0e4 /* Write Protect Mode Register */ +#define SAM_SSC_WPSR_OFFSET 0x0e8 /* Write Protect Status Register */ + /* 0x050-0x0fc: Reserved */ + /* 0x100-0x124: Reserved for PDC registers */ + +/* SSC register addresses ***************************************************************/ + +#define SAM_SSC_CR (SAM_SSC_BASE+SAM_SSC_CR_OFFSET) +#define SAM_SSC_CMR (SAM_SSC_BASE+SAM_SSC_CMR_OFFSET) +#define SAM_SSC_RCMR (SAM_SSC_BASE+SAM_SSC_RCMR_OFFSET) +#define SAM_SSC_RFMR (SAM_SSC_BASE+SAM_SSC_RFMR_OFFSET) +#define SAM_SSC_TCMR (SAM_SSC_BASE+SAM_SSC_TCMR_OFFSET) +#define SAM_SSC_TFMR (SAM_SSC_BASE+SAM_SSC_TFMR_OFFSET) +#define SAM_SSC_RHR (SAM_SSC_BASE+SAM_SSC_RHR_OFFSET) +#define SAM_SSC_THR (SAM_SSC_BASE+SAM_SSC_THR_OFFSET) +#define SAM_SSC_RSHR (SAM_SSC_BASE+SAM_SSC_RSHR_OFFSET) +#define SAM_SSC_TSHR (SAM_SSC_BASE+SAM_SSC_TSHR_OFFSET) +#define SAM_SSC_RC0R (SAM_SSC_BASE+SAM_SSC_RC0R_OFFSET) +#define SAM_SSC_RC1R (SAM_SSC_BASE+SAM_SSC_RC1R_OFFSET) +#define SAM_SSC_SR (SAM_SSC_BASE+SAM_SSC_SR_OFFSET) +#define SAM_SSC_IER (SAM_SSC_BASE+SAM_SSC_IER_OFFSET) +#define SAM_SSC_IDR (SAM_SSC_BASE+SAM_SSC_IDR_OFFSET) +#define SAM_SSC_IMR (SAM_SSC_BASE+SAM_SSC_IMR_OFFSET) +#define SAM_SSC_WPMR (SAM_SSC_BASE+SAM_SSC_WPMR_OFFSET) +#define SAM_SSC_WPSR (SAM_SSC_BASE+SAM_SSC_WPSR_OFFSET) + +/* SSC register bit definitions *********************************************************/ + +/* SSC Control Register */ + +#define SSC_CR_RXEN (1 << 0) /* Bit 0: Receive Enable */ +#define SSC_CR_RXDIS (1 << 1) /* Bit 1: Receive Disable */ +#define SSC_CR_TXEN (1 << 8) /* Bit 8: Transmit Enable */ +#define SSC_CR_TXDIS (1 << 9) /* Bit 9: Transmit Disable */ +#define SSC_CR_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* SSC Clock Mode Register */ + +#define SSC_CMR_DIV_SHIFT (0) /* Bits 0-11: Clock Divider */ +#define SSC_CMR_DIV_MASK (0xfff << SSC_CMR_DIV_SHIFT) + +/* SSC Receive Clock Mode Register */ + +#define SSC_RCMR_CKS_SHIFT (0) /* Bits 0-1: Receive Clock Selection */ +#define SSC_RCMR_CKS_MASK (3 << SSC_RCMR_CKS_SHIFT) +# define SSC_RCMR_CKS_DIVIDED (0 << SSC_RCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_RCMR_CKS_TK (1 << SSC_RCMR_CKS_SHIFT) /* TK Clock signal */ +# define SSC_RCMR_CKS_RK (2 << SSC_RCMR_CKS_SHIFT) /* RK pin */ +#define SSC_RCMR_CKO_SHIFT (2) /* Bits 2-4: Receive Clock Output Mode Selection */ +#define SSC_RCMR_CKO_MASK (7 << SSC_RCMR_CKO_SHIFT) +# define SSC_RCMR_CKO_NONE (0 << SSC_RCMR_CKO_SHIFT) /* None */ +# define SSC_RCMR_CKO_CONTINUOUS (1 << SSC_RCMR_CKO_SHIFT) /* Continuous Receive Clock */ +# define SSC_RCMR_CKO_XFERS (2 << SSC_RCMR_CKO_SHIFT) /* Receive Clock only during data transfers */ +#define SSC_RCMR_CKI (1 << 5) /* Bit 5: Receive Clock Inversion */ +#define SSC_RCMR_CKG_SHIFT (6) /* Bits 6-7: Receive Clock Gating Selection */ +#define SSC_RCMR_CKG_MASK (3 << SSC_RCMR_CKG_SHIFT) +# define SSC_RCMR_CKG_NONE (0 << SSC_RCMR_CKG_SHIFT) /* None, continuous clock */ +# define SSC_RCMR_CKG_RFLOW (1 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF Low */ +# define SSC_RCMR_CKG_RFHIGH (2 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF High */ +#define SSC_RCMR_START_SHIFT (8) /* Bits 8-11: Receive Start Selection */ +#define SSC_RCMR_START_MASK (15 << SSC_RCMR_START_SHIFT) +# define SSC_RCMR_START_CONTINOUS (0 << SSC_RCMR_START_SHIFT) /* Continuous */ +# define SSC_RCMR_START_START (1 << SSC_RCMR_START_SHIFT) /* Transmit start */ +# define SSC_RCMR_START_RFLOW (2 << SSC_RCMR_START_SHIFT) /* Low level on RF signal */ +# define SSC_RCMR_START_RFHIGH (3 << SSC_RCMR_START_SHIFT) /* High level on RF signal */ +# define SSC_RCMR_START_RFFALL (4 << SSC_RCMR_START_SHIFT) /* Falling edge on RF signal */ +# define SSC_RCMR_START_RFRISE (5 << SSC_RCMR_START_SHIFT) /* Rising edge on RF signal */ +# define SSC_RCMR_START_ANYLEVEL (6 << SSC_RCMR_START_SHIFT) /* Any level change on RF signal */ +# define SSC_RCMR_START_ANYEDGE (7 << SSC_RCMR_START_SHIFT) /* Any edge on RF signal */ +# define SSC_RCMR_START_CMP0 (8 << SSC_RCMR_START_SHIFT) /* Compare 0 */ +#define SSC_RCMR_STOP (1 << 12) /* Bit 12: Receive Stop Select */ +#define SSC_RCMR_STTDLY_SHIFT (16) /* Bits 16-23: Receive Start Delay */ +#define SSC_RCMR_STTDLY_MASK (0xff << SSC_RCMR_STTDLY_SHIFT) +#define SSC_RCMR_PERIOD_SHIFT (24) /* Bits 24-31: Receive Period Divider Selection */ +#define SSC_RCMR_PERIOD_MASK (0xff << SSC_RCMR_PERIOD_SHIFT) + +/* SSC Receive Frame Mode Register */ + +#define SSC_RFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_RFMR_DATLEN_MASK (31 << SSC_RFMR_DATLEN_SHIFT) +#define SSC_RFMR_LOOP (1 << 5) /* Bit 5: Loop Mode */ +#define SSC_RFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_RFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per Frame */ +#define SSC_RFMR_DATNB_MASK (15 << SSC_RFMR_DATNB_SHIFT) +#define SSC_RFMR_FSLEN_SHIFT (16) /* Bits 16-19: Receive Frame Sync Length */ +#define SSC_RFMR_FSLEN_MASK (15 << SSC_RFMR_FSLEN_SHIFT) +#define SSC_RFMR_FSOS_SHIFT (20) /* Bits 20-22: Receive Frame Sync Output Selection */ +#define SSC_RFMR_FSOS_MASK (7 << SSC_RFMR_FSOS_SHIFT) +# define SSC_RFMR_FSOS_NONE (0 << SSC_RFMR_FSOS_SHIFT) /* None */ +# define SSC_RFMR_FSOS_NEG (1 << SSC_RFMR_FSOS_SHIFT) /* 0x1 Negative Pulse */ +# define SSC_RFMR_FSOS_POS (2 << SSC_RFMR_FSOS_SHIFT) /* 0x2 Positive Pulse */ +# define SSC_RFMR_FSOS_LOW (3 << SSC_RFMR_FSOS_SHIFT) /* 0x3 Driven Low during data transfer */ +# define SSC_RFMR_FSOS_HIGH (4 << SSC_RFMR_FSOS_SHIFT) /* 0x4 Driven High during data transfer */ +# define SSC_RFMR_FSOS_TOGGLE (5 << SSC_RFMR_FSOS_SHIFT) /* 0x5 Toggling at each start of data transfer */ +#define SSC_RFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detect */ +#define SSC_RFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_RFMR_FSLENEXT_MASK (15 << SSC_RFMR_FSLENEXT_SHIFT) + +/* SSC Transmit Clock Mode Register */ + +#define SSC_TCMR_CKS_SHIFT (0) /* Bits 0-1: Transmit Clock Selection */ +#define SSC_TCMR_CKS_MASK (3 << SSC_TCMR_CKS_SHIFT) +# define SSC_TCMR_CKS_DIVIDED (0 << SSC_TCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_TCMR_CKS_RK (2 << SSC_TCMR_CKS_SHIFT) /* RK Clock signal */ +# define SSC_TCMR_CKS_TK (1 << SSC_TCMR_CKS_SHIFT) /* TK Pin */ +#define SSC_TCMR_CKO_SHIFT (2) /* Bits 2-4: Transmit Clock Output Mode Selection */ +#define SSC_TCMR_CKO_MASK (7 << SSC_TCMR_CKO_SHIFT) +# define SSC_TCMR_CKO_NONE (0 << SSC_TCMR_CKO_SHIFT) /* None */ +# define SSC_TCMR_CKO_CONTINUOUS (1 << SSC_TCMR_CKO_SHIFT) /* Continuous Transmit Clock */ +# define SSC_TCMR_CKO_XFERS (2 << SSC_TCMR_CKO_SHIFT) /* Transmit Clock only during data transfers */ +#define SSC_TCMR_CKI (1 << 5) /* Bit 5: Transmit Clock Inversion */ +#define SSC_TCMR_CKG_SHIFT (6) /* Bits 6-7: Transmit Clock Gating Selection */ +#define SSC_TCMR_CKG_MASK (3 << SSC_TCMR_CKG_SHIFT) +# define SSC_TCMR_CKG_NONE (0 << SSC_TCMR_CKG_SHIFT) /* None, continuous clock */ +# define SSC_tCMR_CKG_TFLOW (1 << SSC_TCMR_CKG_SHIFT) /* Receive Clock enabled only if TF Low */ +# define SSC_TCMR_CKG_TFHIGH (2 << SSC_TCMR_CKG_SHIFT) /* Receive Clock enabled only if TF High */ +#define SSC_TCMR_START_SHIFT (8) /* Bits 8-11: Transmit Start Selection */ +#define SSC_TCMR_START_MASK (15 << SSC_TCMR_START_SHIFT) +# define SSC_TCMR_START_CONTINOUS (0 << SSC_TCMR_START_SHIFT) /* Continuous */ +# define SSC_TCMR_START_START (1 << SSC_TCMR_START_SHIFT) /* Receive start */ +# define SSC_TCMR_START_TFLOW (2 << SSC_TCMR_START_SHIFT) /* Low level on TF signal */ +# define SSC_TCMR_START_TFHIGH (3 << SSC_TCMR_START_SHIFT) /* High level on TF signal */ +# define SSC_TCMR_START_TFFALL (4 << SSC_TCMR_START_SHIFT) /* Falling edge on TF signal */ +# define SSC_TCMR_START_TFRISE (5 << SSC_TCMR_START_SHIFT) /* Rising edge on TF signal */ +# define SSC_TCMR_START_ANYLEVEL (6 << SSC_TCMR_START_SHIFT) /* Any level change on TF signal */ +# define SSC_TCMR_START_ANYEDGE (7 << SSC_TCMR_START_SHIFT) /* Any edge on TF signal */ +#define SSC_TCMR_STTDLY_SHIFT (16) /* Bits 16-23: Transmit Start Delay */ +#define SSC_TCMR_STTDLY_MASK (0xff << SSC_TCMR_STTDLY_SHIFT) +#define SSC_TCMR_PERIOD_SHIFT (24) /* Bits 24-31: Transmit Period Divider Selection */ +#define SSC_TCMR_PERIOD_MASK (0xff << SSC_TCMR_PERIOD_SHIFT) + +/* SSC Transmit Frame Mode Register */ + +#define SSC_TFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_TFMR_DATLEN_MASK (31 << SSC_TFMR_DATLEN_SHIFT) +#define SSC_TFMR_DATDEF (1 << 5) /* Bit 5: Data Default Value */ +#define SSC_TFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_TFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per frame */ +#define SSC_TFMR_DATNB_MASK (15 << SSC_TFMR_DATNB_SHIFT) +#define SSC_TFMR_FSLEN_SHIFT (16) /* Bits 16-19: Transmit Frame Syn Length */ +#define SSC_TFMR_FSLEN_MASK (15 << SSC_TFMR_FSLEN_SHIFT) +#define SSC_TFMR_FSOS_SHIFT (20) /* Bits 20-22: Transmit Frame Sync Output Selection */ +#define SSC_TFMR_FSOS_MASK (7 << SSC_TFMR_FSOS_SHIFT) +# define SSC_TFMR_FSOS_NONE (0 << SSC_TFMR_FSOS_SHIFT) /* None */ +# define SSC_TFMR_FSOS_NEG (1 << SSC_TFMR_FSOS_SHIFT) /* 0x1 Negative Pulse */ +# define SSC_TFMR_FSOS_POS (2 << SSC_TFMR_FSOS_SHIFT) /* 0x2 Positive Pulse */ +# define SSC_TFMR_FSOS_LOW (3 << SSC_TFMR_FSOS_SHIFT) /* 0x3 Driven Low during data transfer */ +# define SSC_TFMR_FSOS_HIGH (4 << SSC_TFMR_FSOS_SHIFT) /* 0x4 Driven High during data transfer */ +# define SSC_TFMR_FSOS_TOGGLE (5 << SSC_TFMR_FSOS_SHIFT) /* 0x5 Toggling at each start of data transfer */ +#define SSC_TFMR_FSDEN (1 << 23) /* Bit 23: Frame Sync Data Enable */ +#define SSC_TFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detection */ +#define SSC_TFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_TFMR_FSLENEXT_MASK (15 << SSC_TFMR_FSLENEXT_SHIFT) + +/* SSC Receive/Transmit Holding Registers (32-bit data) */ + +/* SSC Receive Synchronization Holding Register */ + +#define SSC_RSHR_RSDAT_SHIFT (0) /* Bits 0-15: Receive Synchronization Data */ +#define SSC_RSHR_RSDAT_MASK (0xffff << SSC_RSHR_RSDAT_SHIFT) + +/* SSC Transmit Synchronization Holding Register */ + +#define SSC_TSHR_TSDAT_SHIFT (0) /* Bits 0-15: Transmit Synchronization Data */ +#define SSC_TSHR_TSDAT_MASK (0xffff << SSC_TSHR_TSDAT_SHIFT) + +/* SSC Receive Compare 0 Register */ + +#define SSC_RC0R_CP0_SHIFT (0) /* Bits 0-15: Receive Compare Data 0 */ +#define SSC_RC0R_CP0_MASK (0xffff << SSC_RC0R_CP0_SHIFT) + +/* SSC Receive Compare 1 Register */ + +#define SSC_RC1R_CP1_SHIFT (0) /* Bits 0-15: Receive Compare Data 1 */ +#define SSC_RC1R_CP1_MASK (0xffff << SSC_RC1R_CP1_SHIFT) + +/* SSC Status Register, SSC Interrupt Enable Register, SSC Interrupt Disable + * Register, and SSC Interrupt Mask Register commin bit-field definitions + */ + +#define SSC_INT_TXRDY (1 << 0) /* Bit 0: Transmit Ready */ +#define SSC_INT_TXEMPTY (1 << 1) /* Bit 1: Transmit Empty */ +#define SSC_INT_ENDTX (1 << 2) /* Bit 2: End of Transmission */ +#define SSC_INT_TXBUFE (1 << 3) /* Bit 3: Transmit Buffer Empty */ +#define SSC_INT_RXRDY (1 << 4) /* Bit 4: Receive Ready */ +#define SSC_INT_OVRUN (1 << 5) /* Bit 5: Receive Overrun */ +#define SSC_INT_ENDRX (1 << 6) /* Bit 6: End of Reception */ +#define SSC_INT_RXBUFF (1 << 7) /* Bit 7: Receive Buffer Full */ +#define SSC_INT_CP0 (1 << 8) /* Bit 8: Compare 0 */ +#define SSC_INT_CP1 (1 << 9) /* Bit 9: Compare 1 */ +#define SSC_INT_TXSYN (1 << 10) /* Bit 10: Transmit Sync */ +#define SSC_INT_RXSYN (1 << 11) /* Bit 11: Receive Sync */ +#define SSC_SR_TXEN (1 << 16) /* Bit 16: Transmit Enable (SR only) */ +#define SSC_SR_RXEN (1 << 17) /* Bit 17: Receive Enable (SR only) */ + +/* SSC Write Protect Mode Register */ + +#define SSC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define SSC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define SSC_WPMR_WPKEY_MASK (0x00ffffff << SSC_WPMR_WPKEY_SHIFT) +# define SSC_WPMR_WPKEY (0x00535343 << SSC_WPMR_WPKEY_SHIFT) + +/* SSC Write Protect Status Register */ + +#define SSC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define SSC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define SSC_WPSR_WPVSRC_MASK (0xffff << SSC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_SSC_H */ diff --git a/arch/arm/src/sam34/chip/sam_supc.h b/arch/arm/src/sam34/chip/sam_supc.h new file mode 100644 index 0000000000000000000000000000000000000000..d0095f42a69dbc4542d608c7ef4ec5a328a952d5 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_supc.h @@ -0,0 +1,287 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_supc.h + * Supply Controller (SUPC) definitions for the SAM3U, SAM3X, SAM3A, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_SUPC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_SUPC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SUPC register offsets ****************************************************************/ + +#define SAM_SUPC_CR_OFFSET 0x00 /* Supply Controller Control Register */ +#define SAM_SUPC_SMMR_OFFSET 0x04 /* Supply Controller Supply Monitor Mode Register */ +#define SAM_SUPC_MR_OFFSET 0x08 /* Supply Controller Mode Register */ +#define SAM_SUPC_WUMR_OFFSET 0x0c /* Supply Controller Wake Up Mode Register */ +#define SAM_SUPC_WUIR_OFFSET 0x10 /* Supply Controller Wake Up Inputs Register */ +#define SAM_SUPC_SR_OFFSET 0x14 /* Supply Controller Status Register */ + +/* SUPC register addresses **************************************************************/ + +#define SAM_SUPC_CR (SAM_SUPC_BASE+SAM_SUPC_CR_OFFSET) +#define SAM_SUPC_SMMR (SAM_SUPC_BASE+SAM_SUPC_SMMR_OFFSET) +#define SAM_SUPC_MR (SAM_SUPC_BASE+SAM_SUPC_MR_OFFSET) +#define SAM_SUPC_WUMR (SAM_SUPC_BASE+SAM_SUPC_WUMR_OFFSET) +#define SAM_SUPC_WUIR (SAM_SUPC_BASE+SAM_SUPC_WUIR_OFFSET) +#define SAM_SUPC_SR (SAM_SUPC_BASE+SAM_SUPC_SR_OFFSET) + +/* SUPC register bit definitions ********************************************************/ +/* Supply Controller Control Register */ + +#define SUPC_CR_VROFF (1 << 2) /* Bit 2: Voltage Regulator Off */ +#define SUPC_CR_XTALSEL (1 << 3) /* Bit 3: Crystal Oscillator Select */ +#define SUPC_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define SUPC_CR_KEY_MASK (0xff << SUPC_CR_KEY_SHIFT) +# define SUPR_CR_KEY (0xa5 << SUPC_CR_KEY_SHIFT) + +/* Supply Controller Supply Monitor Mode Register */ + +#define SUPC_SMMR_SMTH_SHIFT (0) /* Bits 0-3: Supply Monitor Threshold */ +#define SUPC_SMMR_SMTH_MASK (15 << SUPC_SMMR_SMTH_SHIFT) +# define SUPC_SMMR_SMTH(n) ((uint32_t)(n) << SUPC_SMMR_SMTH_SHIFT) + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_SMMR_SMTH_1p6V (0 << SUPC_SMMR_SMTH_SHIFT) /* 1.56 < 1.6 < 1.64 */ +# define SUPC_SMMR_SMTH_1p7V (1 << SUPC_SMMR_SMTH_SHIFT) /* 1.68 < 1.72 < 1.76 */ +# define SUPC_SMMR_SMTH_1p8V (2 << SUPC_SMMR_SMTH_SHIFT) /* 1.79 < 1.84 < 1.89 */ +# define SUPC_SMMR_SMTH_2p0V (3 << SUPC_SMMR_SMTH_SHIFT) /* 1.91 < 1.96 < 2.01 */ +# define SUPC_SMMR_SMTH_2p1V (4 << SUPC_SMMR_SMTH_SHIFT) /* 2.03 < 2.08 < 2.13 */ +# define SUPC_SMMR_SMTH_2p2V (5 << SUPC_SMMR_SMTH_SHIFT) /* 2.15 < 2.2 < 2.23 */ +# define SUPC_SMMR_SMTH_2p3V (6 << SUPC_SMMR_SMTH_SHIFT) /* 2.26 < 2.32 < 2.38 */ +# define SUPC_SMMR_SMTH_2p4V (7 << SUPC_SMMR_SMTH_SHIFT) /* 2.38 < 2.44 < 2.50 */ +# define SUPC_SMMR_SMTH_2p6V (8 << SUPC_SMMR_SMTH_SHIFT) /* 2.50 < 2.56 < 2.62 */ +# define SUPC_SMMR_SMTH_2p7V (9 << SUPC_SMMR_SMTH_SHIFT) /* 2.61 < 2.68 < 2.75 */ +# define SUPC_SMMR_SMTH_2p8V (10 << SUPC_SMMR_SMTH_SHIFT) /* 2.73 < 2.8 < 2.87 */ +# define SUPC_SMMR_SMTH_2p9V (11 << SUPC_SMMR_SMTH_SHIFT) /* 2.85 < 2.92 < 2.99 */ +# define SUPC_SMMR_SMTH_3p0V (12 << SUPC_SMMR_SMTH_SHIFT) /* 2.96 < 3.04 < 3.12 */ +# define SUPC_SMMR_SMTH_3p2V (13 << SUPC_SMMR_SMTH_SHIFT) /* 3.08 < 3.16 < 3.24 */ +# define SUPC_SMMR_SMTH_3p3V (14 << SUPC_SMMR_SMTH_SHIFT) /* 3.20 < 3.28 < 3.36 */ +# define SUPC_SMMR_SMTH_3p4V (15 << SUPC_SMMR_SMTH_SHIFT) /* 3.32 < 3.4 < 3.49 */ +#elif defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SUPC_SMMR_SMTH_1p9V (0 << SUPC_SMMR_SMTH_SHIFT) /* 1.9V */ +# define SUPC_SMMR_SMTH_2p0V (1 << SUPC_SMMR_SMTH_SHIFT) /* 2.0V */ +# define SUPC_SMMR_SMTH_2p1V (2 << SUPC_SMMR_SMTH_SHIFT) /* 2.1V */ +# define SUPC_SMMR_SMTH_2p2V (3 << SUPC_SMMR_SMTH_SHIFT) /* 2.2V */ +# define SUPC_SMMR_SMTH_2p3V (4 << SUPC_SMMR_SMTH_SHIFT) /* 2.3V */ +# define SUPC_SMMR_SMTH_2p4V (5 << SUPC_SMMR_SMTH_SHIFT) /* 2.4V */ +# define SUPC_SMMR_SMTH_2p5V (6 << SUPC_SMMR_SMTH_SHIFT) /* 2.5V */ +# define SUPC_SMMR_SMTH_2p6V (7 << SUPC_SMMR_SMTH_SHIFT) /* 2.6V */ +# define SUPC_SMMR_SMTH_2p7V (8 << SUPC_SMMR_SMTH_SHIFT) /* 2.7V */ +# define SUPC_SMMR_SMTH_2p8V (9 << SUPC_SMMR_SMTH_SHIFT) /* 2.8V */ +# define SUPC_SMMR_SMTH_2p9V (10 << SUPC_SMMR_SMTH_SHIFT) /* 2.9V */ +# define SUPC_SMMR_SMTH_3p0V (11 << SUPC_SMMR_SMTH_SHIFT) /* 3.0V */ +# define SUPC_SMMR_SMTH_3p1V (12 << SUPC_SMMR_SMTH_SHIFT) /* 3.1V */ +# define SUPC_SMMR_SMTH_3p2V (13 << SUPC_SMMR_SMTH_SHIFT) /* 3.2V */ +# define SUPC_SMMR_SMTH_3p3V (14 << SUPC_SMMR_SMTH_SHIFT) /* 3.3V */ +# define SUPC_SMMR_SMTH_3p4V (15 << SUPC_SMMR_SMTH_SHIFT) /* 3.4V */ +#endif + +#define SUPC_SMMR_SMSMPL_SHIFT (8) /* Bits 8-10: Supply Monitor Sampling Period */ +#define SUPC_SMMR_SMSMPL_MASK (7 << SUPC_SMMR_SMSMPL_SHIFT) +# define SUPC_SMMR_SMSMPL_SMD (0 << SUPC_SMMR_SMSMPL_SHIFT) /* Supply Monitor disabled */ +# define SUPC_SMMR_SMSMPL_CSM (1 << SUPC_SMMR_SMSMPL_SHIFT) /* Continuous Supply Monitor */ +# define SUPC_SMMR_SMSMPL_32SLCK (2 << SUPC_SMMR_SMSMPL_SHIFT) /* Eevery 32 SLCK periods */ +# define SUPC_SMMR_SMSMPL_256SLCK (3 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 256 SLCK periods */ +# define SUPC_SMMR_SMSMPL_2048SLCK (4 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 2,048 SLCK periods */ +#define SUPC_SMMR_SMRSTEN (1 << 12) /* Bit 12: Supply Monitor Reset Enable */ +#define SUPC_SMMR_SMIEN (1 << 13) /* Bit 13: Supply Monitor Interrupt Enable */ + +/* Supply Controller Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) + +#define SUPC_MR_LCDVROUT_SHIFT (0) +#define SUPC_MR_LCDVROUT_MASK (15 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p92V (0 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p85V (1 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p77V (2 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p70V (3 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p63V (4 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p55V (5 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p48V (6 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_2p41V (7 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p51V (8 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p44V (9 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p36V (10 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p29V (11 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p22V (12 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p14V (13 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p07V (14 << SUPC_MR_LCDVROUT_SHIFT) +# define SUPC_MR_LCDVROUT_3p00V (15 << SUPC_MR_LCDVROUT_SHIFT) + +#define SUPC_MR_LCDMODE_SHIFT (4) +#define SUPC_MR_LCDMODE_MASK (3 << SUPC_MR_LCDMODE_SHIFT) +# define SUPC_MR_LCDMODE_LCDOFF (0 << SUPC_MR_LCDMODE_SHIFT) /* The internal supply source and the external supply source are both deselected */ +# define SUPC_MR_LCDMODE_LCDON_EXTVR (2 << SUPC_MR_LCDMODE_SHIFT) /* The external supply source for LCD (VDDLCD) is selected (the LCD voltage regulator is in Hi-Z Mode) */ +# define SUPC_MR_LCDMODE_LCDON_INVR (3 << SUPC_MR_LCDMODE_SHIFT) /* The internal supply source for LCD (the LCD Voltage Regulator) is selected (Active Mode) */ + +#endif + +#define SUPC_MR_BODRSTEN (1 << 12) /* Bit 12: Brownout Detector Reset Enable */ +#define SUPC_MR_BODDIS (1 << 13) /* Bit 13: Brownout Detector Disable */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_MR_ONREG (1 << 14) /* Bit 14: Voltage Regulator enable */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SUPC_MR_VDDIORDY (1 << 14) /* Bit 14: VDDIO Ready */ +#endif + +#define SUPC_MR_OSCBYPASS (1 << 20) /* Bit 20: Oscillator Bypass */ +#define SUPC_MR_KEY_SHIFT (24) /* Bits 24-31: Password Key */ +#define SUPC_MR_KEY_MASK (0xff << SUPC_MR_KEY_SHIFT) +# define SUPC_MR_KEY (0xa5 << SUPC_MR_KEY_SHIFT) + +/* Supply Controller Wake Up Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_WUMR_FWUPEN (1 << 0) /* Bit 0: Force Wake Up Enable */ +#endif + +#define SUPC_WUMR_SMEN (1 << 1) /* Bit 1: Supply Monitor Wake Up Enable */ +#define SUPC_WUMR_RTTEN (1 << 2) /* Bit 2: Real Time Timer Wake Up Enable */ +#define SUPC_WUMR_RTCEN (1 << 3) /* Bit 3: Real Time Clock Wake Up Enable */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_WUMR_LPDBCEN0 (1 << 5) /* Bit 5: Low power Debouncer ENable WKUP0 */ +# define SUPC_WUMR_LPDBCEN1 (1 << 6) /* Bit 6: Low power Debouncer ENable WKUP1 */ +# define SUPC_WUMR_LPDBCCLR (1 << 7) /* Bit 7: Low power Debouncer Clear */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_WUMR_FWUPDBC_SHIFT (8) /* Bits 8-10: Force Wake Up Debouncer */ +# define SUPC_WUMR_FWUPDBC_MASK (7 << SUPC_WUMR_FWUPDBC_SHIFT) +# define SUPC_WUMR_FWUPDBC_1SCLK (0 << SUPC_WUMR_FWUPDBC_SHIFT) /* Immediate, no debouncing */ +# define SUPC_WUMR_FWUPDBC_3SCLK (1 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 3 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_32SCLK (2 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 32 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_512SCLK (3 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 512 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_4096SCLK (4 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 4096 SLCK periods */ +# define SUPC_WUMR_FWUPDBC_32768SCLK (5 << SUPC_WUMR_FWUPDBC_SHIFT) /* FWUP at least 32768 SLCK periods */ +#endif + +#define SUPC_WUMR_WKUPDBC_SHIFT (12) /* Bits 12-14: Wake Up Inputs Debouncer */ +#define SUPC_WUMR_WKUPDBC_MASK (7 << SUPC_WUMR_WKUPDBC_SHIFT) +# define SUPC_WUMR_WKUPDBC_1SCLK (0 << SUPC_WUMR_WKUPDBC_SHIFT) /* Immediate, no debouncing */ +# define SUPC_WUMR_WKUPDBC_3SCLK (1 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 3 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32SCLK (2 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_512SCLK (3 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 512 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_4096SCLK (4 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 4096 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32768SCLK (5 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32768 SLCK periods */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_WUMR_LPDBC_SHIFT (16) /* Bits 16-18: Low Power Debouncer Period */ +# define SUPC_WUMR_LPDBC_MASK (7 << SUPC_WUMR_LPDBC_SHIFT) +# define SUPC_WUMR_LPDBC_DISABLE (0 << SUPC_WUMR_LPDBC_SHIFT) /* Disable low power debouncer */ +# define SUPC_WUMR_LPDBC_2_RTCOUT0 (1 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 2 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_3_RTCOUT0 (2 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 3 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_4_RTCOUT0 (3 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 4 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_5_RTCOUT0 (4 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 5 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_6_RTCOUT0 (5 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 6 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_7_RTCOUT0 (6 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 7 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_8_RTCOUT0 (7 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 8 RTCOUT0 */ +#endif + +/* System Controller Wake Up Inputs Register */ + +#define SUPC_WUIR_WKUPEN_SHIFT (0) /* Bits 0-15: Wake Up Input Enable 0 to 15 */ +#define SUPC_WUIR_WKUPEN_MASK (0xffff << SUPC_WUIR_WKUPEN_SHIFT) +# define SUPC_WUIR_WKUPEN(n) ((1 << (n)) << SUPC_WUIR_WKUPEN_SHIFT) +#define SUPC_WUIR_WKUPT_SHIFT (16) /* Bits 16-31 Wake Up Input Transition 0 to 15 */ +#define SUPC_WUIR_WKUPT_MASK (0xffff << SUPC_WUIR_WKUPT_SHIFT) +# define SUPC_WUIR_WKUPT(n) ((1 << (n)) << SUPC_WUIR_WKUPT_SHIFT) + +/* Supply Controller Status Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_SR_FWUPS (1 << 0) /* Bit 0: FWUP Wake Up Status */ +#endif + +#define SUPC_SR_WKUPS (1 << 1) /* Bit 1: WKUP Wake Up Status */ +#define SUPC_SR_SMWS (1 << 2) /* Bit 2: Supply Monitor Detection Wake Up Status */ +#define SUPC_SR_BODRSTS (1 << 3) /* Bit 3: Brownout Detector Reset Status */ +#define SUPC_SR_SMRSTS (1 << 4) /* Bit 4: Supply Monitor Reset Status */ +#define SUPC_SR_SMS (1 << 5) /* Bit 5: Supply Monitor Status */ +#define SUPC_SR_SMOS (1 << 6) /* Bit 6: Supply Monitor Output Status */ +#define SUPC_SR_OSCSEL (1 << 7) /* Bit 7: 32-kHz Oscillator Selection Status */ + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) +# define SUPC_SR_LCDS (1 << 8) /* Bit 8: LCD Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_SR_FWUPIS (1 << 12) /* Bit 12: FWUP Input Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SUPC_SR_LPDBCS0 (1 << 13) /* Bit 13: Low Power Debouncer Wake Up Status on WKUP0 */ +# define SUPC_SR_LPDBCS1 (1 << 14) /* Bit 14: Low Power Debouncer Wake Up Status on WKUP1 */ +#endif + +#define SUPC_SR_WKUPIS_SHIFT (16) /* Bits 16-31: WKUP Input Status 0 to 15 */ +#define SUPC_SR_WKUPIS_MASK (0xffff << SUPC_SR_WKUPIS_SHIFT) +# define SUPC_SR_WKUPIS(n) (1 << (SUPC_SR_WKUPIS_SHIFT+(n))) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_SUPC_H */ diff --git a/arch/arm/src/sam34/chip/sam_tc.h b/arch/arm/src/sam34/chip/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..bb1bd15f0c132d277837a8dedd659e37fbcd6fa1 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_tc.h @@ -0,0 +1,603 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam_tc.h + * Timer Counter (TC) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_TC_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_TC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* TC register offsets **************************************************************************/ + +/* Timer channel offsets (with respect to timer base offset at 0x00, 0x40, and 0x80 */ + +#define SAM_TC_CCR_OFFSET 0x0000 /* Channel Control Register */ +#define SAM_TC_CMR_OFFSET 0x0004 /* Channel Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC_SMMR_OFFSET 0x0008 /* Stepper Motor Mode Register */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC_RAB_OFFSET 0x000c /* Register AB */ +#endif + /* 0x0c Reserved */ +#define SAM_TC_CV_OFFSET 0x0010 /* Counter Value */ +#define SAM_TC_RA_OFFSET 0x0014 /* Register A */ +#define SAM_TC_RB_OFFSET 0x0018 /* Register B */ +#define SAM_TC_RC_OFFSET 0x001c /* Register C */ +#define SAM_TC_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC_EMR_OFFSET 0x0030 /* Extended Mode Register */ +#endif + +/* Timer common registers */ + +#define SAM_TC_BCR_OFFSET 0x00c0 /* Block Control Register */ +#define SAM_TC_BMR_OFFSET 0x00c4 /* Block Mode Register */ +#define SAM_TC_QIER_OFFSET 0x00c8 /* QDEC Interrupt Enable Register */ +#define SAM_TC_QIDR_OFFSET 0x00cc /* QDEC Interrupt Disable Register */ +#define SAM_TC_QIMR_OFFSET 0x00d0 /* QDEC Interrupt Mask Register */ +#define SAM_TC_QISR_OFFSET 0x00d4 /* QDEC Interrupt Status Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC_FMR_OFFSET 0xd8 /* Fault Mode Register */ +# define SAM_TC_WPMR_OFFSET 0xe4 /* Write Protect Mode Register */ +#endif + +/* TC register addresses ************************************************************************/ + +#define SAM_TC0_CCR (SAM_TC0_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC0_CMR (SAM_TC0_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC0_SMMR (SAM_TC0_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC0_RAB (SAM_TC0_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC0_CV (SAM_TC0_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC0_RA (SAM_TC0_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC0_RB (SAM_TC0_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC0_RC (SAM_TC0_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC0_SR (SAM_TC0_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC0_IER (SAM_TC0_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC0_IDR (SAM_TC0_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC0_IMR (SAM_TC0_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC0_EMR (SAM_TC0_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC1_CCR (SAM_TC1_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC1_CMR (SAM_TC1_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC1_SMMR (SAM_TC1_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC1_RAB (SAM_TC1_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC1_CV (SAM_TC1_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC1_RA (SAM_TC1_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC1_RB (SAM_TC1_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC1_RC (SAM_TC1_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC1_SR (SAM_TC1_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC1_IER (SAM_TC1_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC1_IDR (SAM_TC1_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC1_IMR (SAM_TC1_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC1_EMR (SAM_TC1_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC2_CCR (SAM_TC2_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC2_CMR (SAM_TC2_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC2_SMMR (SAM_TC2_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC2_RAB (SAM_TC2_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC2_CV (SAM_TC2_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC2_RA (SAM_TC2_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC2_RB (SAM_TC2_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC2_RC (SAM_TC2_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC2_SR (SAM_TC2_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC2_IER (SAM_TC2_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC2_IDR (SAM_TC2_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC2_IMR (SAM_TC2_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC2_EMR (SAM_TC2_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC3_CCR (SAM_TC3_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC3_CMR (SAM_TC3_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC3_SMMR (SAM_TC3_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC3_RAB (SAM_TC3_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC3_CV (SAM_TC3_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC3_RA (SAM_TC3_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC3_RB (SAM_TC3_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC3_RC (SAM_TC3_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC3_SR (SAM_TC3_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC3_IER (SAM_TC3_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC3_IDR (SAM_TC3_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC3_IMR (SAM_TC3_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC3_EMR (SAM_TC3_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC4_CCR (SAM_TC4_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC4_CMR (SAM_TC4_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC4_SMMR (SAM_TC4_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC4_RAB (SAM_TC4_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC4_CV (SAM_TC4_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC4_RA (SAM_TC4_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC4_RB (SAM_TC4_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC4_RC (SAM_TC4_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC4_SR (SAM_TC4_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC4_IER (SAM_TC4_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC4_IDR (SAM_TC4_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC4_IMR (SAM_TC4_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC4_EMR (SAM_TC4_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC5_CCR (SAM_TC5_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC5_CMR (SAM_TC5_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC5_SMMR (SAM_TC5_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC5_RAB (SAM_TC5_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC5_CV (SAM_TC5_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC5_RA (SAM_TC5_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC5_RB (SAM_TC5_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC5_RC (SAM_TC5_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC5_SR (SAM_TC5_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC5_IER (SAM_TC5_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC5_IDR (SAM_TC5_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC5_IMR (SAM_TC5_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC5_EMR (SAM_TC5_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC6_CCR (SAM_TC6_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC6_CMR (SAM_TC6_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC6_SMMR (SAM_TC6_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC6_RAB (SAM_TC6_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC6_CV (SAM_TC6_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC6_RA (SAM_TC6_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC6_RB (SAM_TC6_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC6_RC (SAM_TC6_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC6_SR (SAM_TC6_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC6_IER (SAM_TC6_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC6_IDR (SAM_TC6_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC6_IMR (SAM_TC6_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC6_EMR (SAM_TC6_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC7_CCR (SAM_TC7_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC7_CMR (SAM_TC7_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC7_SMMR (SAM_TC7_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC7_RAB (SAM_TC7_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC7_CV (SAM_TC7_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC7_RA (SAM_TC7_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC7_RB (SAM_TC7_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC7_RC (SAM_TC7_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC7_SR (SAM_TC7_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC7_IER (SAM_TC7_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC7_IDR (SAM_TC7_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC7_IMR (SAM_TC7_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC7_EMR (SAM_TC7_BASE+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC8_CCR (SAM_TC8_BASE+SAM_TC_CCR_OFFSET) +#define SAM_TC8_CMR (SAM_TC8_BASE+SAM_TC_CMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC8_SMMR (SAM_TC8_BASE+SAM_TC_SMMR_OFFSET) +#endif +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC8_RAB (SAM_TC8_BASE+SAM_TC_RAB_OFFSET) +#endif +#define SAM_TC8_CV (SAM_TC8_BASE+SAM_TC_CV_OFFSET) +#define SAM_TC8_RA (SAM_TC8_BASE+SAM_TC_RA_OFFSET) +#define SAM_TC8_RB (SAM_TC8_BASE+SAM_TC_RB_OFFSET) +#define SAM_TC8_RC (SAM_TC8_BASE+SAM_TC_RC_OFFSET) +#define SAM_TC8_SR (SAM_TC8_BASE+SAM_TC_SR_OFFSET) +#define SAM_TC8_IER (SAM_TC8_BASE+SAM_TC_IER_OFFSET) +#define SAM_TC8_IDR (SAM_TC8_BASE+SAM_TC_IDR_OFFSET) +#define SAM_TC8_IMR (SAM_TC8_BASE+SAM_TC_IMR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC8_EMR (SAM_TC8_BASE+SAM_TC_EMR_OFFSET) +#endif + +/* Timer common registers */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TC0_BCR (SAM_TC012_BASE+SAM_TC_BCR_OFFSET) +# define SAM_TC0_BMR (SAM_TC012_BASE+SAM_TC_BMR_OFFSET) +# define SAM_TC0_QIER (SAM_TC012_BASE+SAM_TC_QIER_OFFSET) +# define SAM_TC0_QIDR (SAM_TC012_BASE+SAM_TC_QIDR_OFFSET) +# define SAM_TC0_QIMR (SAM_TC012_BASE+SAM_TC_QIMR_OFFSET) +# define SAM_TC0_QISR (SAM_TC012_BASE+SAM_TC_QISR_OFFSET) +# define SAM_TC0_FMR (SAM_TC012_BASE+SAM_TC_FMR_OFFSET) +# define SAM_TC0_WPMR (SAM_TC012_BASE+SAM_TC_WPMR_OFFSET) + +# define SAM_TC1_BCR (SAM_TC345_BASE+SAM_TC_BCR_OFFSET) +# define SAM_TC1_BMR (SAM_TC345_BASE+SAM_TC_BMR_OFFSET) +# define SAM_TC1_QIER (SAM_TC345_BASE+SAM_TC_QIER_OFFSET) +# define SAM_TC1_QIDR (SAM_TC345_BASE+SAM_TC_QIDR_OFFSET) +# define SAM_TC1_QIMR (SAM_TC345_BASE+SAM_TC_QIMR_OFFSET) +# define SAM_TC1_QISR (SAM_TC345_BASE+SAM_TC_QISR_OFFSET) +# define SAM_TC1_FMR (SAM_TC345_BASE+SAM_TC_FMR_OFFSET) +# define SAM_TC1_WPMR (SAM_TC345_BASE+SAM_TC_WPMR_OFFSET) + +# define SAM_TC2_BCR (SAM_TC678_BASE+SAM_TC_BCR_OFFSET) +# define SAM_TC2_BMR (SAM_TC678_BASE+SAM_TC_BMR_OFFSET) +# define SAM_TC2_QIER (SAM_TC678_BASE+SAM_TC_QIER_OFFSET) +# define SAM_TC2_QIDR (SAM_TC678_BASE+SAM_TC_QIDR_OFFSET) +# define SAM_TC2_QIMR (SAM_TC678_BASE+SAM_TC_QIMR_OFFSET) +# define SAM_TC2_QISR (SAM_TC678_BASE+SAM_TC_QISR_OFFSET) +# define SAM_TC2_FMR (SAM_TC678_BASE+SAM_TC_FMR_OFFSET) +# define SAM_TC2_WPMR (SAM_TC678_BASE+SAM_TC_WPMR_OFFSET) +#else +# define SAM_TC_BCR (SAM_TC_BASE+SAM_TC_BCR_OFFSET) +# define SAM_TC_BMR (SAM_TC_BASE+SAM_TC_BMR_OFFSET) +# define SAM_TC_QIER (SAM_TC_BASE+SAM_TC_QIER_OFFSET) +# define SAM_TC_QIDR (SAM_TC_BASE+SAM_TC_QIDR_OFFSET) +# define SAM_TC_QIMR (SAM_TC_BASE+SAM_TC_QIMR_OFFSET) +# define SAM_TC_QISR (SAM_TC_BASE+SAM_TC_QISR_OFFSET) +#endif + +/* TC register bit definitions ******************************************************************/ +/* Timer channel registers **********************************************************************/ + +/* TC Channel Control Register */ + +#define TC_CCR_CLKEN (1 << 0) /* Bit 0: Counter Clock Enable Command */ +#define TC_CCR_CLKDIS (1 << 1) /* Bit 1: Counter Clock Disable Command */ +#define TC_CCR_SWTRG (1 << 2) /* Bit 2: Software Trigger Command */ + +/* TC Channel Mode Register -- Common */ + +#define TC_CMR_TCCLKS_SHIFT (0) /* Bits 0-2: Clock Selection */ +#define TC_CMR_TCCLKS_MASK (7 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS(n) ((uint32_t)(n) << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TIMERCLOCK1 (0 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TIMERCLOCK2 (1 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TIMERCLOCK3 (2 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TIMERCLOCK4 (3 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TIMERCLOCK5 (4 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_XC0 (5 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_XC1 (6 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_XC2 (7 << TC_CMR_TCCLKS_SHIFT) +#define TC_CMR_CLKI (1 << 3) /* Bit 3: Clock Invert */ +#define TC_CMR_BURST_SHIFT (4) /* Bits 4-5: Burst Signal Selection */ +#define TC_CMR_BURST_MASK (3 << TC_CMR_BURST_SHIFT) +# define TC_CMR_BURST_NOTGATED (0 << TC_CMR_BURST_SHIFT) /* Nott gated by external signal */ +# define TC_CMR_BURST_XC0 (1 << TC_CMR_BURST_SHIFT) /* XC0 ANDed with selected clock */ +# define TC_CMR_BURST_XC1 (2 << TC_CMR_BURST_SHIFT) /* XC1 ANDed with selected clock */ +# define TC_CMR_BURST_XC2 (3 << TC_CMR_BURST_SHIFT) /* XC2 ANDed with selected clock */ +#define TC_CMR_WAVE (1 << 15) /* Bit 15: Waveform Mode */ + +/* TC Channel Mode Register -- Capture mode only */ + +#define TC_CMR_LDBSTOP (1 << 6) /* Bit 6: Counter stopped with RB Loading */ +#define TC_CMR_LDBDIS (1 << 7) /* Bit 7: Counter disable with RB Loading */ +#define TC_CMR_ETRGEDG_SHIFT (8) /* Bits 8-9: External Trigger Edge Selection */ +#define TC_CMR_ETRGEDG_MASK (3 << TC_CMR_ETRGEDG_SHIFT) +# define TC_CMR_ETRGEDG_NONE (0 << TC_CMR_ETRGEDG_SHIFT) /* None */ +# define TC_CMR_ETRGEDG_REDGE (1 << TC_CMR_ETRGEDG_SHIFT) /* Rising edge */ +# define TC_CMR_ETRGEDG_FEDGE (2 << TC_CMR_ETRGEDG_SHIFT) /* Falling edge */ +# define TC_CMR_ETRGEDG_EACH (3 << TC_CMR_ETRGEDG_SHIFT) /* Each */ +#define TC_CMR_ABETRG (1 << 10) /* Bit 10: TIOA or TIOB External Trigger Selection */ +#define TC_CMR_CPCTRG (1 << 14) /* Bit 14: RC Compare Trigger Enable */ +#define TC_CMR_LDRA_SHIFT (16) /* Bits 16-17: RA Loading Selection */ +#define TC_CMR_LDRA_MASK (3 << TC_CMR_LDRA_SHIFT) +# define TC_CMR_LDRA_NONE (0 << TC_CMR_LDRA_SHIFT) /* None */ +# define TC_CMR_LDRA_REDGE (1 << TC_CMR_LDRA_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRA_FEDGE (2 << TC_CMR_LDRA_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRA_EACH (3 << TC_CMR_LDRA_SHIFT) /* Each edge of TIOA */ +#define TC_CMR_LDRB_SHIFT (18) /* Bits 18-19: RB Loading Selection */ +#define TC_CMR_LDRB_MASK (3 << TC_CMR_LDRB_SHIFT) +# define TC_CMR_LDRB_NONE (0 << TC_CMR_LDRB_SHIFT) /* None */ +# define TC_CMR_LDRB_REDGE (1 << TC_CMR_LDRB_SHIFT) /* Rising edge of TIOB */ +# define TC_CMR_LDRB_FEDGE (2 << TC_CMR_LDRB_SHIFT) /* Falling edge of TIOB */ +# define TC_CMR_LDRB_EACH (3 << TC_CMR_LDRB_SHIFT) /* Each edge of TIOB */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +#define TC_CMR_SBSMPLR_SHIFT (20) /* Bits 20-22: Loading Edge Subsampling Ratio */ +#define TC_CMR_SBSMPLR_MASK (7 << TC_CMR_SBSMPLR_SHIFT) +# define TC_CMR_SBSMPLR_ONE (0 << TC_CMR_SBSMPLR_SHIFT) /* Load on each selected edge */ +# define TC_CMR_SBSMPLR_HALF (1 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 2 selected edges */ +# define TC_CMR_SBSMPLR_4TH (2 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 4 selected edges */ +# define TC_CMR_SBSMPLR_8TH (3 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 8 selected edges */ +# define TC_CMR_SBSMPLR_16TH (4 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 16 selected edges */ +#endif + +/* TC Channel Mode Register -- Waveform mode only */ + +#define TC_CMR_CPCSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RC Compare (Waveform mode) */ +#define TC_CMR_CPCDIS (1 << 7) /* Bit 7: Counter Clock Disable with RC Compare (Waveform mode) */ +#define TC_CMR_EEVTEDG_SHIFT (8) /* Bits 8-9: External Event Edge Selection (Waveform mode) */ +#define TC_CMR_EEVTEDG_MASK (3 << TC_CMR_EEVTEDG_SHIFT) +# define TC_CMR_EEVTEDG_NONE (0 << TC_CMR_EEVTEDG_SHIFT) /* None */ +# define TC_CMR_EEVTEDG_REDGE (1 << TC_CMR_EEVTEDG_SHIFT) /* Rising edge */ +# define TC_CMR_EEVTEDG_FEDGE (2 << TC_CMR_EEVTEDG_SHIFT) /* Falling edge */ +# define TC_CMR_EEVTEDG_EACH (3 << TC_CMR_EEVTEDG_SHIFT) /* Each edge */ +#define TC_CMR_EEVT_SHIFT (10) /* Bits 10-11: External Event Selection (Waveform mode) */ +#define TC_CMR_EEVT_MASK (3 << TC_CMR_EEVT_SHIFT) +# define TC_CMR_EEVT_TIOB (0 << TC_CMR_EEVT_SHIFT) /* TIOB input */ +# define TC_CMR_EEVT_XC0 (1 << TC_CMR_EEVT_SHIFT) /* XC0 output */ +# define TC_CMR_EEVT_XC1 (2 << TC_CMR_EEVT_SHIFT) /* XC1 output */ +# define TC_CMR_EEVT_XC2 (3 << TC_CMR_EEVT_SHIFT) /* XC2 output */ +#define TC_CMR_ENETRG (1 << 12) /* Bit 12: External Event Trigger Enable (Waveform mode) */ +#define TC_CMR_WAVSEL_SHIFT (13) /* Bits 13-14: Waveform Selection (Waveform mode) */ +#define TC_CMR_WAVSEL_MASK (3 << TC_CMR_WAVSEL_SHIFT) +# define TC_CMR_WAVSEL_UP (0 << TC_CMR_WAVSEL_SHIFT) /* UP mode w/o auto trigger (Waveform mode) */ +# define TC_CMR_WAVSEL_UPDWN (1 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode w/o auto trigger (Waveform mode) */ +# define TC_CMR_WAVSEL_UPAUTO (2 << TC_CMR_WAVSEL_SHIFT) /* UP mode with auto trigger (Waveform mode) */ +# define TC_CMR_WAVSEL_UPDWNAUTO (3 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode with auto trigger (Waveform mode) */ +#define TC_CMR_ACPA_SHIFT (16) /* Bits 16-17: RA Compare Effect on TIOA (Waveform mode) */ +#define TC_CMR_ACPA_MASK (3 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_NONE (0 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_SET (1 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_CLEAR (2 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_TOGGLE (3 << TC_CMR_ACPA_SHIFT) +#define TC_CMR_ACPC_SHIFT (18) /* Bits 18-19: RC Compare Effect on TIOA (Waveform mode) */ +#define TC_CMR_ACPC_MASK (3 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_NONE (0 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_SET (1 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_CLEAR (2 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_TOGGLE (3 << TC_CMR_ACPC_SHIFT) +#define TC_CMR_AEEVT_SHIFT (20) /* Bits 20-21: External Event Effect on TIOA (Waveform mode) */ +#define TC_CMR_AEEVT_MASK (3 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_NONE (0 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_SET (1 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_CLEAR (2 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_TOGGLE (3 << TC_CMR_AEEVT_SHIFT) +#define TC_CMR_ASWTRG_SHIFT (22) /* Bits 22-23: Software Trigger Effect on TIOA (Waveform mode) */ +#define TC_CMR_ASWTRG_MASK (3 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_NONE (0 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_SET (1 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_CLEAR (2 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_TOGGLE (3 << TC_CMR_ASWTRG_SHIFT) +#define TC_CMR_BCPB_SHIFT (24) /* Bits 24-25: RB Compare Effect on TIOB (Waveform mode) */ +#define TC_CMR_BCPB_MASK (3 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_NONE (0 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_SET (1 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_CLEAR (2 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_TOGGLE (3 << TC_CMR_BCPB_SHIFT) +#define TC_CMR_BCPC_SHIFT (26) /* Bits 26-27: RC Compare Effect on TIOB (Waveform mode) */ +#define TC_CMR_BCPC_MASK (3 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_NONE (0 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_SET (1 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_CLEAR (2 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_TOGGLE (3 << TC_CMR_BCPC_SHIFT) +#define TC_CMR_BEEVT_SHIFT (28) /* Bits 28-29: External Event Effect on TIOB (Waveform mode) */ +#define TC_CMR_BEEVT_MASK (3 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_NONE (0 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_SET (1 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_CLEAR (2 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_TOGGLE (3 << TC_CMR_BEEVT_SHIFT) +#define TC_CMR_BSWTRG_SHIFT (30) /* Bits 30-31: Software Trigger Effect on TIOB (Waveform mode) */ +#define TC_CMR_BSWTRG_MASK (3 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_NONE (0 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_SET (1 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_CLEAR (2 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_TOGGLE (3 << TC_CMR_BSWTRG_SHIFT) + +/* Stepper Motor Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_SMMR_GCEN (1 << 0) /* Bit 0: Gray Count Enable */ +# define TC_SMMR_DOWN (1 << 1) /* Bit 1: DOWN Count */ +#endif + +/* Register AB -- 32-bit value */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_RAB_MASK (0xffffffff) +#endif + +/* TC Counter Value Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_CV_MASK (0xffffffff) +#else +# define TC_CV_MASK (0x0000ffff) +#endif + +/* TC Register A, B, C */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_RVALUE_MASK (0xffffffff) +#else +# define TC_RVALUE_MASK (0x0000ffff) +#endif + +/* TC Status Register, TC Interrupt Enable Register, TC Interrupt Disable Register, and TC Interrupt Mask Register common bit-field definitions */ + +#define TC_INT_COVFS (1 << 0) /* Bit 0: Counter Overflow */ +#define TC_INT_LOVRS (1 << 1) /* Bit 1: Load Overrun */ +#define TC_INT_CPAS (1 << 2) /* Bit 2: RA Compare */ +#define TC_INT_CPBS (1 << 3) /* Bit 3: RB Compare */ +#define TC_INT_CPCS (1 << 4) /* Bit 4: RC Compare */ +#define TC_INT_LDRAS (1 << 5) /* Bit 5: RA Loading */ +#define TC_INT_LDRBS (1 << 6) /* Bit 6: RB Loading */ +#define TC_INT_ETRGS (1 << 7) /* Bit 7: External Trigger */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_INT_ENDRX (1 << 8) /* Bit 8: End of Receiver Transfer */ +# define TC_INT_RXBUFF (1 << 9) /* Bit 9: Reception Buffer Full */ +# define TC_INT_ALL (TC_INT_COVFS + TC_INT_LOVRS + TC_INT_CPAS + TC_INT_CPBS + TC_INT_CPCS + TC_INT_LDRAS + TC_INT_LDRBS + TC_INT_ETRGS + TC_INT_ENDRX + TC_INT_RXBUFF) +#else +# define TC_INT_ALL (TC_INT_COVFS + TC_INT_LOVRS + TC_INT_CPAS + TC_INT_CPBS + TC_INT_CPCS + TC_INT_LDRAS + TC_INT_LDRBS + TC_INT_ETRGS) +#endif + +#define TC_INT_CLKSTA (1 << 16) /* Bit 16: Clock Enabling (SR only) */ +#define TC_SR_MTIOA (1 << 17) /* Bit 17: TIOA Mirror (SR only) */ +#define TC_SR_MTIOB (1 << 18) /* Bit 18: TIOB Mirror (SR only)*/ + +/* Extended Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_EMR_TRIGSRCA_SHIFT (0) /* Bits 0-1: Trigger source for input A */ +# define TC_EMR_TRIGSRCA_MASK (3 << TC_EMR_TRIGSRCA_SHIFT) +# define TC_EMR_TRIGSRCA_TIOA (0 << TC_EMR_TRIGSRCA_SHIFT) /* Input A driven by pin TIOAx */ +# define TC_EMR_TRIGSRCA_PWM (1 << TC_EMR_TRIGSRCA_SHIFT) /* Input A driven by PWMx */ +# define TC_EMR_TRIGSRCB_SHIFT (5) /* Bits 4-5: Trigger source for input B */ +# define TC_EMR_TRIGSRCB_MASK (3 << TC_EMR_TRIGSRCB_SHIFT) +# define TC_EMR_TRIGSRCB_TIOA (0 << TC_EMR_TRIGSRCB_SHIFT) /* Input B driven by pin TIOBx */ +# define TC_EMR_TRIGSRCB_PWM (1 << TC_EMR_TRIGSRCB_SHIFT) /* Input B driven by PWMx */ +# define TC_EMR_NODIVCLK (1 << 8) /* Bit 8: NO DIVided CLocK */ +#endif + +/* Timer common registers ***********************************************************************/ +/* TC Block Control Register */ + +#define TC_BCR_SYNC (1 << 0) /* Bit 0: Synchro Command */ + +/* TC Block Mode Register */ + +#define TC_BMR_TC0XC0S_SHIFT (0) /* Bits 0-1: External Clock Signal 0 Selection */ +#define TC_BMR_TC0XC0S_MASK (3 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_TCLK0 (0 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_NONE (1 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_TIOA1 (2 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_TIOA2 (3 << TC_BMR_TC0XC0S_SHIFT) +#define TC_BMR_TC1XC1S_SHIFT (2) /* Bits 2-3: External Clock Signal 1 Selection */ +#define TC_BMR_TC1XC1S_MASK (3 << TC_BMR_TC1XC1S_MASK) +# define TC_BMR_TC1XC1S_TCLK1 (0 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC1XC1S_NONE (1 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC1XC1S_TIOA0 (2 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC1XC1S_TIOA2 (3 << TC_BMR_TC1XC1S_SHIFT) +#define TC_BMR_TC2XC2S_SHIFT (4) /* Bits 4-5: External Clock Signal 2 Selection */ +#define TC_BMR_TC2XC2S_MASK (3 << TC_BMR_TC2XC2S_SHIFT) +#if defined(CONFIG_ARCH_CHIP_SAM4s) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TIOA1 (2 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TIOA2 (3 << TC_BMR_TC2XC2S_SHIFT) +#else +# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_NONE (1 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TIOA0 (2 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TIOA1 (3 << TC_BMR_TC2XC2S_SHIFT) +#endif +#define TC_BMR_QDEN (1 << 8) /* Bit 8: Quadrature Decoder Enabled */ +#define TC_BMR_POSEN (1 << 9) /* Bit 9: Position Enabled */ +#define TC_BMR_SPEEDEN (1 << 10) /* Bit 10: Speed Enabled */ +#define TC_BMR_QDTRANS (1 << 11) /* Bit 11: Quadrature Decoding Transparent */ +#define TC_BMR_EDGPHA (1 << 12) /* Bit 12: Edge on PHA count mode */ +#define TC_BMR_INVA (1 << 13) /* Bit 13: Inverted PHA */ +#define TC_BMR_INVB (1 << 14) /* Bit 14: Inverted PHB */ +#define TC_BMR_INVIDX (1 << 15) /* Bit 15: Inverted Index */ +#define TC_BMR_SWAP (1 << 16) /* Bit 16: Swap PHA and PHB */ +#define TC_BMR_IDXPHB (1 << 17) /* Bit 17: Index pin is PHB pin */ +#define TC_BMR_FILTER (1 << 19) /* Bit 19 */ +#define TC_BMR_MAXFILT_SHIFT (20) /* Bits 20-25: Maximum Filter */ +#define TC_BMR_MAXFILT_MASK (63 << TC_BMR_MAXFILT_SHIFT) +# define TC_BMR_MAXFILT(n) ((uint32_t)(n) << TC_BMR_MAXFILT_SHIFT) + +/* TC QDEC Interrupt Enable Register, TC QDEC Interrupt Disable Register, + * TC QDEC Interrupt Mask Register, TC QDEC Interrupt Status Register common + * bit field definitions + */ + +#define TC_QINT_IDX (1 << 0) /* Bit 0: Index (Common) */ +#define TC_QINT_DIRCHG (1 << 1) /* Bit 1: Direction Change (Common) */ +#define TC_QINT_QERR (1 << 2) /* Bit 2: Quadrature Error (Common) */ +#define TC_QISR_DIR (1 << 8) /* Bit 8: Direction (QISR only) */ + +/* Fault Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_FMR_ENCF0 (1 << 0) /* Bit 0: Enable compare fault channel 0 */ +# define TC_FMR_ENCF1 (1 << 1) /* Bit 1: Enable compare fault channel 1 */ +#endif + +/* Write Protect Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define TC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +# define TC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +# define TC_WPMR_WPKEY_MASK (0x00ffffff << TC_WPMR_WPKEY_SHIFT) +# define TC_WPMR_WPKEY (0x0054494d << TC_WPMR_WPKEY_SHIFT) +#endif + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_TC_H */ diff --git a/arch/arm/src/sam34/chip/sam_twi.h b/arch/arm/src/sam34/chip/sam_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..8ad5a0f8aeb79aa5c0e84c090f08515f2d7d8c73 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_twi.h @@ -0,0 +1,228 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_twi.h + * Two-wire Interface (TWI) definitions for the SAM3U, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_TWI_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_TWI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* TWI register offsets *****************************************************************/ + +#define SAM_TWI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_TWI_MMR_OFFSET 0x0004 /* Master Mode Register */ +#define SAM_TWI_SMR_OFFSET 0x0008 /* Slave Mode Register */ +#define SAM_TWI_IADR_OFFSET 0x000c /* Internal Address Register */ +#define SAM_TWI_CWGR_OFFSET 0x0010 /* Clock Waveform Generator Register */ +#define SAM_TWI_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TWI_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TWI_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TWI_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_TWI_RHR_OFFSET 0x0030 /* Receive Holding Register */ +#define SAM_TWI_THR_OFFSET 0x0034 /* Transmit Holding Register */ + /* 0x38-0xfc: Reserved */ +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TWI_WPMR_OFFSET 0x00e4 /* Protection Mode Register */ +# define SAM_TWI_WPSR_OFFSET 0x00e8 /* Protection Status Register */ +#endif + +/* TWI register addresses ***************************************************************/ + +#define SAM_TWI_CR(n) (SAM_TWIN_BASE(n)+SAM_TWI_CR_OFFSET) +#define SAM_TWI_MMR(n) (SAM_TWIN_BASE(n)+SAM_TWI_MMR_OFFSET) +#define SAM_TWI_SMR(n) (SAM_TWIN_BASE(n)+SAM_TWI_SMR_OFFSET) +#define SAM_TWI_IADR(n) (SAM_TWIN_BASE(n)+SAM_TWI_IADR_OFFSET) +#define SAM_TWI_CWGR(n) (SAM_TWIN_BASE(n)+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI_SR(n) (SAM_TWIN_BASE(n)+SAM_TWI_SR_OFFSET) +#define SAM_TWI_IER(n) (SAM_TWIN_BASE(n)+SAM_TWI_IER_OFFSET) +#define SAM_TWI_IDR(n) (SAM_TWIN_BASE(n)+SAM_TWI_IDR_OFFSET) +#define SAM_TWI_IMR(n) (SAM_TWIN_BASE(n)+SAM_TWI_IMR_OFFSET) +#define SAM_TWI_RHR(n) (SAM_TWIN_BASE(n)+SAM_TWI_RHR_OFFSET) +#define SAM_TWI_THR(n) (SAM_TWIN_BASE(n)+SAM_TWI_THR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TWI_WPMR(n) (SAM_TWIN_BASE(n)+SAM_TWI_WPMR_OFFSET) +# define SAM_TWI_WPSR(n) (SAM_TWIN_BASE(n)+SAM_TWI_WPSR_OFFSET) +#endif + +#define SAM_TWI0_CR (SAM_TWI0_BASE+SAM_TWI_CR_OFFSET) +#define SAM_TWI0_MMR (SAM_TWI0_BASE+SAM_TWI_MMR_OFFSET) +#define SAM_TWI0_SMR (SAM_TWI0_BASE+SAM_TWI_SMR_OFFSET) +#define SAM_TWI0_IADR (SAM_TWI0_BASE+SAM_TWI_IADR_OFFSET) +#define SAM_TWI0_CWGR (SAM_TWI0_BASE+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI0_SR (SAM_TWI0_BASE+SAM_TWI_SR_OFFSET) +#define SAM_TWI0_IER (SAM_TWI0_BASE+SAM_TWI_IER_OFFSET) +#define SAM_TWI0_IDR (SAM_TWI0_BASE+SAM_TWI_IDR_OFFSET) +#define SAM_TWI0_IMR (SAM_TWI0_BASE+SAM_TWI_IMR_OFFSET) +#define SAM_TWI0_RHR (SAM_TWI0_BASE+SAM_TWI_RHR_OFFSET) +#define SAM_TWI0_THR (SAM_TWI0_BASE+SAM_TWI_THR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TWI0_WPMR (SAM_TWI0_BASE+SAM_TWI_WPMR_OFFSET) +# define SAM_TWI0_WPSR (SAM_TWI0_BASE)+SAM_TWI_WPSR_OFFSET) +#endif + +#define SAM_TWI1_CR (SAM_TWI1_BASE+SAM_TWI_CR_OFFSET) +#define SAM_TWI1_MMR (SAM_TWI1_BASE+SAM_TWI_MMR_OFFSET) +#define SAM_TWI1_SMR (SAM_TWI1_BASE+SAM_TWI_SMR_OFFSET) +#define SAM_TWI1_IADR (SAM_TWI1_BASE+SAM_TWI_IADR_OFFSET) +#define SAM_TWI1_CWGR (SAM_TWI1_BASE+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI1_SR (SAM_TWI1_BASE+SAM_TWI_SR_OFFSET) +#define SAM_TWI1_IER (SAM_TWI1_BASE+SAM_TWI_IER_OFFSET) +#define SAM_TWI1_IDR (SAM_TWI1_BASE+SAM_TWI_IDR_OFFSET) +#define SAM_TWI1_IMR (SAM_TWI1_BASE+SAM_TWI_IMR_OFFSET) +#define SAM_TWI1_RHR (SAM_TWI1_BASE+SAM_TWI_RHR_OFFSET) +#define SAM_TWI1_THR (SAM_TWI1_BASE+SAM_TWI_THR_OFFSET) +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_TWI1_WPMR (SAM_TWI1_BASE+SAM_TWI_WPMR_OFFSET) +# define SAM_TWI1_WPSR (SAM_TWI1_BASE)+SAM_TWI_WPSR_OFFSET) +#endif + +/* TWI register bit definitions *********************************************************/ + +/* TWI Control Register */ + +#define TWI_CR_START (1 << 0) /* Bit 0: Send a START Condition */ +#define TWI_CR_STOP (1 << 1) /* Bit 1: Send a STOP Condition */ +#define TWI_CR_MSEN (1 << 2) /* Bit 2: TWI Master Mode Enabled */ +#define TWI_CR_MSDIS (1 << 3) /* Bit 3: TWI Master Mode Disabled */ +#define TWI_CR_SVEN (1 << 4) /* Bit 4: TWI Slave Mode Enabled */ +#define TWI_CR_SVDIS (1 << 5) /* Bit 5: TWI Slave Mode Disabled */ +#define TWI_CR_QUICK (1 << 6) /* Bit 6: SMBUS Quick Command */ +#define TWI_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ + +/* TWI Master Mode Register */ + +#define TWI_MMR_IADRSZ_SHIFT (8) /* Bits 8-9: Internal Device Address Size */ +#define TWI_MMR_IADRSZ_MASK (3 << TWI_MMR_IADRSZ_SHIFT) +# define TWI_MMR_IADRSZ_NONE (0 << TWI_MMR_IADRSZ_SHIFT) /* No internal device address */ +# define TWI_MMR_IADRSZ_1BYTE (1 << TWI_MMR_IADRSZ_SHIFT) /* One-byte internal device address */ +# define TWI_MMR_IADRSZ_2BYTE (2 << TWI_MMR_IADRSZ_SHIFT) /* Two-byte internal device address */ +# define TWI_MMR_IADRSZ_3BYTE (3 << TWI_MMR_IADRSZ_SHIFT) /* Three-byte internal device address */ +#define TWI_MMR_MREAD (1 << 12) /* Bit 12: Master Read Direction */ +#define TWI_MMR_DADR_SHIFT (16) /* Bits 16-22: Device Address */ +#define TWI_MMR_DADR_MASK (0x7f << TWI_MMR_DADR_SHIFT) + +/* TWI Slave Mode Register */ + +#define TWI_SMR_SADR_SHIFT (16) /* Bits 16-22: Slave Address */ +#define TWI_SMR_SADR_MASK (0x7f << TWI_SMR_SADR_SHIFT) + +/* TWI Internal Address Register */ + +#define TWI_IADR_SHIFT (0) /* Bits 0-23: Internal Address */ +#define TWI_IADR_MASK (0x00ffffff << TWI_IADR_SHIFT) + +/* TWI Clock Waveform Generator Register */ + +#define TWI_CWGR_CLDIV_SHIFT (0) /* Bits 0-7: Clock Low Divider */ +#define TWI_CWGR_CLDIV_MASK (0xff << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CLDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) +#define TWI_CWGR_CHDIV_SHIFT (8) /* Bits 8-15: Clock High Divider */ +#define TWI_CWGR_CHDIV_MASK (0xff << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CHDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) +#define TWI_CWGR_CKDIV_SHIFT (16) /* Bits 16-18: Clock Divider */ +#define TWI_CWGR_CKDIV_MASK (7 << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CKDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) + +/* TWI Status Register, TWI Interrupt Enable Register, TWI Interrupt Disable + * Register, and TWI Interrupt Mask Register common bit fields. + */ + +#define TWI_INT_TXCOMP (1 << 0) /* Bit 0: Transmission Completed */ +#define TWI_INT_RXRDY (1 << 1) /* Bit 1: Receive Holding Register */ +#define TWI_INT_TXRDY (1 << 2) /* Bit 2: Transmit Holding Register Ready */ +#define TWI_SR_SVREAD (1 << 3) /* Bit 3: Slave Read (SR only) */ +#define TWI_INT_SVACC (1 << 4) /* Bit 4: Slave Access */ +#define TWI_INT_GACC (1 << 5) /* Bit 5: General Call Access */ +#define TWI_INT_OVRE (1 << 6) /* Bit 6: Overrun Error */ +#define TWI_INT_NACK (1 << 8) /* Bit 8: Not Acknowledged */ +#define TWI_INT_ARBLST (1 << 9) /* Bit 9: Arbitration Lost */ +#define TWI_INT_SCLWS (1 << 10) /* Bit 10: Clock Wait State */ +#define TWI_INT_EOSACC (1 << 11) /* Bit 11: End Of Slave Access */ +#define TWI_INT_ENDRX (1 << 12) /* Bit 12: End of RX buffer */ +#define TWI_INT_ENDTX (1 << 13) /* Bit 13: End of TX buffer */ +#define TWI_INT_RXBUFF (1 << 14) /* Bit 14: RX Buffer */ +#define TWI_INT_TXBUFE (1 << 15) /* Bit 15: TX Buffer Empty */ + +/* TWI Receive Holding Register */ + +#define TWI_RHR_RXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Receive Holding Data */ +#define TWI_RHR_RXDATA_MASK (0xff << TWI_RHR_RXDATA_SHIFT) + +/* TWI Transmit Holding Register */ + +#define TWI_THR_TXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Transmit Holding Data */ +#define TWI_THR_TXDATA_MASK (0xff << TWI_THR_TXDATA_SHIFT) + +/* Protection Mode Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define TWI_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +# define TWI_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect Key */ +# define TWI_WPMR_WPKEY_MASK (0x00ffffff << TWI_WPMR_WPKEY_SHIFT) +# define TWI_WPMR_WPKEY (0x00545749 << TWI_WPMR_WPKEY_SHIFT) +#endif + +/* Protection Status Register */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define TWI_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +# define TWI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +# define TWI_WPSR_WPVSRC_MASK (0xffff << TWI_WPSR_WPVSRC_SHIFT) +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_TWI_H */ diff --git a/arch/arm/src/sam34/chip/sam_uart.h b/arch/arm/src/sam34/chip/sam_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..a80a898704eb82db9e6e94a989c8702ce91d0bab --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_uart.h @@ -0,0 +1,572 @@ +/************************************************************************************************ + * arch/arm/src/sam34/chip/sam_uart.h + * Universal Asynchronous Receiver Transmitter (UART) and Universal Synchronous Asynchronous + * Receiver Transmitter (USART) definitions for the SAM3U, SAM3X, SAM3A, SAM4S and SAM4E + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_UART_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_UART_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* UART register offsets ************************************************************************/ + +#define SAM_UART_CR_OFFSET 0x0000 /* Control Register (Common) */ +#define SAM_UART_MR_OFFSET 0x0004 /* Mode Register (Common) */ +#define SAM_UART_IER_OFFSET 0x0008 /* Interrupt Enable Register (Common) */ +#define SAM_UART_IDR_OFFSET 0x000c /* Interrupt Disable Register (Common) */ +#define SAM_UART_IMR_OFFSET 0x0010 /* Interrupt Mask Register (Common) */ +#define SAM_UART_SR_OFFSET 0x0014 /* [Channel] Status Register (Common) */ +#define SAM_UART_RHR_OFFSET 0x0018 /* Receive Holding Register (Common) */ +#define SAM_UART_THR_OFFSET 0x001c /* Transmit Holding Register (Common) */ +#define SAM_UART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register (Common) */ + /* 0x0024-0x003c: Reserved (UART) */ +#define SAM_UART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register (USART only) */ +#define SAM_UART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register (USART only) */ + /* 0x002c-0x003c: Reserved (USART) */ +#define SAM_UART_FIDI_OFFSET 0x0040 /* FI DI Ratio Register (USART only) */ +#define SAM_UART_NER_OFFSET 0x0044 /* Number of Errors Register ((USART only) */ + /* 0x0048: Reserved (USART) */ +#define SAM_UART_IFR_OFFSET 0x004c /* IrDA Filter Register (USART only) */ +#define SAM_UART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_UART_LINMR_OFFSET 0x0054 /* LIN Mode Register (USART only) */ +# define SAM_UART_LINIR_OFFSET 0x0058 /* LIN Identifier Register (USART only) */ +#endif + +#define SAM_UART_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register (USART only) */ +#define SAM_UART_WPSR_OFFSET 0x00e8 /* Write Protect Status Register (USART only) */ + /* 0x005c-0xf8: Reserved (USART) */ +#define SAM_UART_VERSION_OFFSET 0x00fc /* Version Register (USART only, Not SAM4E) */ + /* 0x0100-0x0124: PDC Area (Common) */ + +/* UART register addresses **********************************************************************/ + +#define SAM_UART0_CR (SAM_UART0_BASE+SAM_UART_CR_OFFSET) +#define SAM_UART0_MR (SAM_UART0_BASE+SAM_UART_MR_OFFSET) +#define SAM_UART0_IER (SAM_UART0_BASE+SAM_UART_IER_OFFSET) +#define SAM_UART0_IDR (SAM_UART0_BASE+SAM_UART_IDR_OFFSET) +#define SAM_UART0_IMR (SAM_UART0_BASE+SAM_UART_IMR_OFFSET) +#define SAM_UART0_SR (SAM_UART0_BASE+SAM_UART_SR_OFFSET) +#define SAM_UART0_RHR (SAM_UART0_BASE+SAM_UART_RHR_OFFSET) +#define SAM_UART0_THR (SAM_UART0_BASE+SAM_UART_THR_OFFSET) +#define SAM_UART0_BRGR (SAM_UART0_BASE+SAM_UART_BRGR_OFFSET) + +#define SAM_UART1_CR (SAM_UART1_BASE+SAM_UART_CR_OFFSET) +#define SAM_UART1_MR (SAM_UART1_BASE+SAM_UART_MR_OFFSET) +#define SAM_UART1_IER (SAM_UART1_BASE+SAM_UART_IER_OFFSET) +#define SAM_UART1_IDR (SAM_UART1_BASE+SAM_UART_IDR_OFFSET) +#define SAM_UART1_IMR (SAM_UART1_BASE+SAM_UART_IMR_OFFSET) +#define SAM_UART1_SR (SAM_UART1_BASE+SAM_UART_SR_OFFSET) +#define SAM_UART1_RHR (SAM_UART1_BASE+SAM_UART_RHR_OFFSET) +#define SAM_UART1_THR (SAM_UART1_BASE+SAM_UART_THR_OFFSET) +#define SAM_UART1_BRGR (SAM_UART1_BASE+SAM_UART_BRGR_OFFSET) + +#define SAM_USART_CR(n) (SAM_USARTN_BASE(n)+SAM_UART_CR_OFFSET) +#define SAM_USART_MR(n) (SAM_USARTN_BASE(n)+SAM_UART_MR_OFFSET) +#define SAM_USART_IER(n) (SAM_USARTN_BASE(n)+SAM_UART_IER_OFFSET) +#define SAM_USART_IDR(n) (SAM_USARTN_BASE(n)+SAM_UART_IDR_OFFSET) +#define SAM_USART_IMR(n) (SAM_USARTN_BASE(n)+SAM_UART_IMR_OFFSET) +#define SAM_USART_SR(n) (SAM_USARTN_BASE(n)+SAM_UART_SR_OFFSET) +#define SAM_USART_RHR(n) (SAM_USARTN_BASE(n)+SAM_UART_RHR_OFFSET) +#define SAM_USART_THR(n) (SAM_USARTN_BASE(n)+SAM_UART_THR_OFFSET) +#define SAM_USART_BRGR(n) (SAM_USARTN_BASE(n)+SAM_UART_BRGR_OFFSET) +#define SAM_USART_RTOR(n) (SAM_USARTN_BASE(n)+SAM_UART_RTOR_OFFSET) +#define SAM_USART_TTGR(n) (SAM_USARTN_BASE(n)+SAM_UART_TTGR_OFFSET) +#define SAM_USART_FIDI(n) (SAM_USARTN_BASE(n)+SAM_UART_FIDI_OFFSET) +#define SAM_USART_NER(n) (SAM_USARTN_BASE(n)+SAM_UART_NER_OFFSET) +#define SAM_USART_IFR(n) (SAM_USARTN_BASE(n)+SAM_UART_IFR_OFFSET) +#define SAM_USART_MAN(n) (SAM_USARTN_BASE(n)+SAM_UART_MAN_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_USART_LINMR(n) (SAM_USARTN_BASE(n)+SAM_UART_LINMR_OFFSET) +# define SAM_USART_LINIR(n) (SAM_USARTN_BASE(n)+SAM_UART_LINIR_OFFSET) +#endif + +#define SAM_USART_WPMR(n) (SAM_USARTN_BASE(n)+SAM_UART_WPMR_OFFSET) +#define SAM_USART_WPSR(n) (SAM_USARTN_BASE(n)+SAM_UART_WPSR_OFFSET) +#define SAM_USART_VERSION(n) (SAM_USARTN_BASE(n)+SAM_UART_VERSION_OFFSET) + +#define SAM_USART0_CR (SAM_USART0_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART0_MR (SAM_USART0_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART0_IER (SAM_USART0_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART0_IDR (SAM_USART0_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART0_IMR (SAM_USART0_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART0_SR (SAM_USART0_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART0_RHR (SAM_USART0_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART0_THR (SAM_USART0_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART0_BRGR (SAM_USART0_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART0_RTOR (SAM_USART0_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART0_TTGR (SAM_USART0_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART0_FIDI (SAM_USART0_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART0_NER (SAM_USART0_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART0_IFR (SAM_USART0_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART0_MAN (SAM_USART0_BASE+SAM_UART_MAN_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_USART0_LINMR (SAM_USART0_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART0_LINIR (SAM_USART0_BASE+SAM_UART_LINIR_OFFSET) +#endif + +#define SAM_USART0_WPMR (SAM_USART0_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART0_WPSR (SAM_USART0_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART0_VERSION (SAM_USART0_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART1_CR (SAM_USART1_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART1_MR (SAM_USART1_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART1_IER (SAM_USART1_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART1_IDR (SAM_USART1_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART1_IMR (SAM_USART1_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART1_SR (SAM_USART1_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART1_RHR (SAM_USART1_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART1_THR (SAM_USART1_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART1_BRGR (SAM_USART1_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART1_RTOR (SAM_USART1_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART1_TTGR (SAM_USART1_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART1_FIDI (SAM_USART1_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART1_NER (SAM_USART1_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART1_IFR (SAM_USART1_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART1_MAN (SAM_USART1_BASE+SAM_UART_MAN_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_USART1_LINMR (SAM_USART1_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART1_LINIR (SAM_USART1_BASE+SAM_UART_LINIR_OFFSET) +#endif + +#define SAM_USART1_WPMR (SAM_USART1_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART1_WPSR (SAM_USART1_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART1_VERSION (SAM_USART1_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART2_CR (SAM_USART2_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART2_MR (SAM_USART2_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART2_IER (SAM_USART2_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART2_IDR (SAM_USART2_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART2_IMR (SAM_USART2_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART2_SR (SAM_USART2_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART2_RHR (SAM_USART2_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART2_THR (SAM_USART2_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART2_BRGR (SAM_USART2_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART2_RTOR (SAM_USART2_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART2_TTGR (SAM_USART2_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART2_FIDI (SAM_USART2_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART2_NER (SAM_USART2_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART2_IFR (SAM_USART2_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART2_MAN (SAM_USART2_BASE+SAM_UART_MAN_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_USART2_LINMR (SAM_USART2_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART2_LINIR (SAM_USART2_BASE+SAM_UART_LINIR_OFFSET) +#endif + +#define SAM_USART2_WPMR (SAM_USART2_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART2_WPSR (SAM_USART2_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART2_VERSION (SAM_USART2_BASE+SAM_UART_VERSION_OFFSET) + +#define SAM_USART3_CR (SAM_USART3_BASE+SAM_UART_CR_OFFSET) +#define SAM_USART3_MR (SAM_USART3_BASE+SAM_UART_MR_OFFSET) +#define SAM_USART3_IER (SAM_USART3_BASE+SAM_UART_IER_OFFSET) +#define SAM_USART3_IDR (SAM_USART3_BASE+SAM_UART_IDR_OFFSET) +#define SAM_USART3_IMR (SAM_USART3_BASE+SAM_UART_IMR_OFFSET) +#define SAM_USART3_SR (SAM_USART3_BASE+SAM_UART_SR_OFFSET) +#define SAM_USART3_RHR (SAM_USART3_BASE+SAM_UART_RHR_OFFSET) +#define SAM_USART3_THR (SAM_USART3_BASE+SAM_UART_THR_OFFSET) +#define SAM_USART3_BRGR (SAM_USART3_BASE+SAM_UART_BRGR_OFFSET) +#define SAM_USART3_RTOR (SAM_USART3_BASE+SAM_UART_RTOR_OFFSET) +#define SAM_USART3_TTGR (SAM_USART3_BASE+SAM_UART_TTGR_OFFSET) +#define SAM_USART3_FIDI (SAM_USART3_BASE+SAM_UART_FIDI_OFFSET) +#define SAM_USART3_NER (SAM_USART3_BASE+SAM_UART_NER_OFFSET) +#define SAM_USART3_IFR (SAM_USART3_BASE+SAM_UART_IFR_OFFSET) +#define SAM_USART3_MAN (SAM_USART3_BASE+SAM_UART_MAN_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_USART3_LINMR (SAM_USART3_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART3_LINIR (SAM_USART3_BASE+SAM_UART_LINIR_OFFSET) +#endif + +#define SAM_USART3_WPMR (SAM_USART3_BASE+SAM_UART_WPMR_OFFSET) +#define SAM_USART3_WPSR (SAM_USART3_BASE+SAM_UART_WPSR_OFFSET) +#define SAM_USART3_VERSION (SAM_USART3_BASE+SAM_UART_VERSION_OFFSET) + +/* UART register bit definitions ****************************************************************/ + +/* UART Control Register */ + +#define UART_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver (Common) */ +#define UART_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter (Common) */ +#define UART_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable (Common) */ +#define UART_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable (Common) */ +#define UART_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable (Common) */ +#define UART_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable (Common) */ +#define UART_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits (Common) */ +#define UART_CR_STTBRK (1 << 9) /* Bit 9: Start Break (USART only) */ +#define UART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break (USART only) */ +#define UART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out (USART only) */ +#define UART_CR_SENDA (1 << 12) /* Bit 12: Send Address (USART only) */ +#define UART_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations (USART only) */ +#define UART_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge (USART only) */ +#define UART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out (USART only) */ +#define UART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable (USART only) */ +#define UART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select (USART SPI mode only) */ +#define UART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable (USART only) */ +#define UART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select (USART SPI mode only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_CR_LINABT (1 << 20) /* Bit 20: Abort LIN Transmission */ +# define UART_CR_LINWKUP (1 << 21) /* Bit 21: Send LIN Wakeup Signal */ +#endif + +/* UART Mode Register and USART Mode Register (UART MODE) */ + +#ifdef CONFIG_ARCH_CHIP_SAM4CM +# define UART_MR_OPT_EN (1 << 0) /* Bit 0: UART Optical Interface Enable (UART only) */ +# define UART_MR_OPT_RXINV (1 << 1) /* Bit 1: UART Receive Data Inverted (UART only) */ +# define UART_MR_OPT_MDINV (1 << 2) /* Bit 2: UART Modulated Data Inverted (UART only) */ +#endif + +#define UART_MR_MODE_SHIFT (0) /* Bits 0-3: (USART only) */ +#define UART_MR_MODE_MASK (15 << UART_MR_MODE_SHIFT) +# define UART_MR_MODE_NORMAL (0 << UART_MR_MODE_SHIFT) /* Normal */ +# define UART_MR_MODE_RS485 (1 << UART_MR_MODE_SHIFT) /* RS485 */ +# define UART_MR_MODE_HWHS (2 << UART_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define UART_MR_MODE_ISO7816_0 (4 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */ +# define UART_MR_MODE_ISO7816_1 (6 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */ +# define UART_MR_MODE_IRDA (8 << UART_MR_MODE_SHIFT) /* IrDA */ +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_MR_MODE_LINMSTR (10 << UART_MR_MODE_SHIFT) /* LIN Master */ +# define UART_MR_MODE_LINSLV (11 << UART_MR_MODE_SHIFT) /* LIN Slave */ +#endif +# define UART_MR_MODE_SPIMSTR (14 << UART_MR_MODE_SHIFT) /* SPI Master (SPI mode only) */ +# define UART_MR_MODE_SPISLV (15 << UART_MR_MODE_SHIFT) /* SPI Slave (SPI mode only) */ + +#define UART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection (USART only) */ +#define UART_MR_USCLKS_MASK (3 << UART_MR_USCLKS_SHIFT) +# define UART_MR_USCLKS_MCK (0 << UART_MR_USCLKS_SHIFT) /* MCK */ +# define UART_MR_USCLKS_MCKDIV (1 << UART_MR_USCLKS_SHIFT) /* MCK/DIV (DIV = 8) */ +# define UART_MR_USCLKS_SCK (3 << UART_MR_USCLKS_SHIFT) /* SCK */ +#define UART_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length (USART only) */ +#define UART_MR_CHRL_MASK (3 << UART_MR_CHRL_SHIFT) +# define UART_MR_CHRL_5BITS (0 << UART_MR_CHRL_SHIFT) /* 5 bits */ +# define UART_MR_CHRL_6BITS (1 << UART_MR_CHRL_SHIFT) /* 6 bits */ +# define UART_MR_CHRL_7BITS (2 << UART_MR_CHRL_SHIFT) /* 7 bits */ +# define UART_MR_CHRL_8BITS (3 << UART_MR_CHRL_SHIFT) /* 8 bits */ +#define UART_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select (USART only) */ +#define UART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase (USART SPI mode only) */ +#define UART_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type (Common) */ +#define UART_MR_PAR_MASK (7 << UART_MR_PAR_SHIFT) +# define UART_MR_PAR_EVEN (0 << UART_MR_PAR_SHIFT) /* Even parity (Common) */ +# define UART_MR_PAR_ODD (1 << UART_MR_PAR_SHIFT) /* Odd parity (Common) */ +# define UART_MR_PAR_SPACE (2 << UART_MR_PAR_SHIFT) /* Space: parity forced to 0 (Common) */ +# define UART_MR_PAR_MARK (3 << UART_MR_PAR_SHIFT) /* Mark: parity forced to 1 (Common) */ +# define UART_MR_PAR_NONE (4 << UART_MR_PAR_SHIFT) /* No parity (Common) */ +# define UART_MR_PAR_MULTIDROP (6 << UART_MR_PAR_SHIFT) /* Multidrop mode (USART only) */ +#define UART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits (USART only) */ +#define UART_MR_NBSTOP_MASK (3 << UART_MR_NBSTOP_SHIFT) +# define UART_MR_NBSTOP_1 (0 << UART_MR_NBSTOP_SHIFT) /* 1 stop bit 1 stop bit */ +# define UART_MR_NBSTOP_1p5 (1 << UART_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define UART_MR_NBSTOP_2 (2 << UART_MR_NBSTOP_SHIFT) /* 2 stop bits 2 stop bits */ +#define UART_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode (Common) */ +#define UART_MR_CHMODE_MASK (3 << UART_MR_CHMODE_SHIFT) +# define UART_MR_CHMODE_NORMAL (0 << UART_MR_CHMODE_SHIFT) /* Normal Mode */ +# define UART_MR_CHMODE_ECHO (1 << UART_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define UART_MR_CHMODE_LLPBK (2 << UART_MR_CHMODE_SHIFT) /* Local Loopback */ +# define UART_MR_CHMODE_RLPBK (3 << UART_MR_CHMODE_SHIFT) /* Remote Loopback */ +#ifdef CONFIG_ARCH_CHIP_SAM4CM +# define UART_MR_OPT_CLKDIV_SHIFT (16) /* Bits 16-20: Optical Link Clock Divider (UART only) */ +# define UART_MR_OPT_CLKDIV_MASK (31 << UART_MR_OPT_CLKDIV_SHIFT) +#endif +#define UART_MR_MSBF (1 << 16) /* Bit 16: Most Significant Bit first (USART only) */ +#define UART_MR_CPOL (1 << 16) /* Bit 16: SPI Clock Polarity (USART SPI mode only) */ +#define UART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length (USART only) */ +#define UART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select (USART only) */ +#define UART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode (USART only) */ +#define UART_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define UART_MR_WRDBT (1 << 20) /* Bit 20: Wait Read Data Before Transfer (SPI mode only) */ +#endif + +#define UART_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK (USART only) */ +#define UART_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter (USART only) */ +#define UART_MR_INVDATA (1 << 23) /* Bit 23: INverted Data (USART only) */ + +#ifdef CONFIG_ARCH_CHIP_SAM4CM +# define UART_MR_OPT_OPT_DUTY_SHIFT (24) /* Bits 24-26: Optical Link Modulation Clock Duty Cycle (UART only) */ +# define UART_MR_OPT_OPT_DUTY_MASK (7 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_50 (0 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_43P75 (1 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_37P5 (2 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_31P25 (3 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_25 (4 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_18P75 (5 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_12P5 (6 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_OPT_DUTY_6P25 (7 << UART_MR_OPT_OPT_DUTY_SHIFT) +# define UART_MR_OPT_CMPTH_SHIFT (28) +# define UART_MR_OPT_CMPTH_MASK (7 << UART_MR_OPT_CMPTH_SHIFT) +# define UART_MR_OPT_CMPTH_VDDIO_DIV2 (0 << UART_MR_OPT_CMPTH_SHIFT) +# define UART_MR_OPT_CMPTH_VDDIO_DIV2P5 (1 << UART_MR_OPT_CMPTH_SHIFT) +# define UART_MR_OPT_CMPTH_VDDIO_DIV3P3 (2 << UART_MR_OPT_CMPTH_SHIFT) +# define UART_MR_OPT_CMPTH_VDDIO_DIV5 (3 << UART_MR_OPT_CMPTH_SHIFT) +# define UART_MR_OPT_CMPTH_VDDIO_DIV10 (4 << UART_MR_OPT_CMPTH_SHIFT) +#endif + +#define UART_MR_MAXITER_SHIFT (24) /* Bits 24-26: Max iterations (ISO7816 T=0 (USART only) */ +#define UART_MR_MAXITER_MASK (7 << UART_MR_MAXITER_SHIFT) +# define UART_MR_MAXITER(n) ((uint32_t)(n) << UART_MR_MAXITER_SHIFT) +#define UART_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter (USART only) */ +#define UART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable (USART only) */ +#define UART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode (USART only) */ +#define UART_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector (USART only) */ + +/* UART Interrupt Enable Register, UART Interrupt Disable Register, UART Interrupt Mask + * Register, and UART Status Register common bit field definitions + */ + +#define UART_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt (Common) */ +#define UART_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt (Common) */ +#define UART_INT_RXBRK (1 << 2) /* Bit 2: Break Received/End of Break */ +#define UART_INT_ENDRX (1 << 3) /* Bit 3: End of Receive Transfer Interrupt (Common) */ +#define UART_INT_ENDTX (1 << 4) /* Bit 4: End of Transmit Interrupt (Common) */ +#define UART_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt (Common) */ +#define UART_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt (Common) */ +#define UART_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt (Common) */ +#define UART_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt (USART only) */ +#define UART_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt (Common) */ +#define UART_INT_ITER (1 << 10) /* Bit 10: Iteration Interrupt (USART only) */ +#define UART_INT_UNRE (1 << 10) /* Bit 10: SPI Underrun Error Interrupt (USART SPI mode only) */ +#define UART_INT_TXBUFE (1 << 11) /* Bit 11: Buffer Empty Interrupt (Common) */ +#define UART_INT_RXBUFF (1 << 12) /* Bit 12: Buffer Full Interrupt (Common) */ +#define UART_INT_NACK (1 << 13) /* Bit 13: Non Acknowledge Interrupt (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_INT_LINBK (1 << 13) /* Bit 13: LIN Break Sent or Break Received Interrupt */ +# define UART_INT_LINID (1 << 14) /* Bit 14: LIN Identifier Sent or Identifier Received Interrupt */ +# define UART_INT_LINTC (1 << 15) /* Bit 15: LIN Transfer Completed Interrupt */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define UART_INT_RIIC (1 << 16) /* Bit 16: Ring Indicator Input Change */ +# define UART_INT_DSRIC (1 << 17) /* Bit 17: Data Set Ready Input Change */ +# define UART_INT_DCDIC (1 << 18) /* Bit 18: Data Carrier Detect Input Change Interrupt */ +#endif + +#define UART_INT_CTSIC (1 << 19) /* Bit 19: Clear to Send Input Change Interrupt (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define UART_SR_RI (1 << 20) /* Bit 20: Image of RI Input */ +# define UART_SR_DSR (1 << 21) /* Bit 21: Image of DSR Input */ +# define UART_SR_DCD (1 << 22) /* Bit 22: Image of DCD Input */ +# define UART_SR_CTS (1 << 23) /* Bit 23: Image of CTS Input */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_SR_CTS (1 << 23) /* Bit 23: Image of CTS Input */ +# define UART_SR_LINBLS (1 << 23) /* Bit 23: LIN Bus Line Status */ +#endif + +#define UART_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_INT_LINBE (1 << 25) /* Bit 25: LIN Bus Error Interrupt */ +# define UART_INT_LINISFE (1 << 26) /* Bit 26: LIN Inconsistent Synch Field Error Interrupt */ +# define UART_INT_LINIPE (1 << 27) /* Bit 27: LIN Identifier Parity Interrupt */ +# define UART_INT_LINCE (1 << 28) /* Bit 28: LIN Checksum Error Interrupt */ +# define UART_INT_LINSNRE (1 << 29) /* Bit 29: LIN Slave Not Responding Error Interrupt */ +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_INT_ALLINTS 0x3f08ffff +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# define UART_INT_ALLINTS 0x010f3fff /* USART - UART only has 0x001AFB? does it matter? */ +#else +# define UART_INT_ALLINTS 0x01083fff +#endif + +/* UART Receiver Holding Register */ + +#if 0 +# define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character (UART only) */ +# define UART_RHR_RXCHR_MASK (0xff << UART_RHR_RXCHR_SHIFT) +#endif +#define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character (USART only) */ +#define UART_RHR_RXCHR_MASK (0x1ff << UART_RHR_RXCHR_SHIFT) +#define UART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync (USART only) */ + +/* UART Transmit Holding Register */ + +#if 0 +# define UART_THR_TXCHR_SHIFT (0) /* Bits 0-7: Character to be Transmitted (UART only) */ +# define UART_THR_TXCHR_MASK (0xff << UART_THR_TXCHR_SHIFT) +#endif +#define UART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted (USART only) */ +#define UART_THR_TXCHR_MASK (0x1ff << UART_THR_TXCHR_SHIFT) +#define UART_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be tran (USART only) */ + +/* UART Baud Rate Generator Register */ + +#define UART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor (Common) */ +#define UART_BRGR_CD_MASK (0xffff << UART_BRGR_CD_SHIFT) +#define UART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part (USART only) */ +#define UART_BRGR_FP_MASK (7 << UART_BRGR_FP_SHIFT) + +/* USART Receiver Time-out Register (USART only) */ + +#define UART_RTOR_TO_SHIFT (0) /* Bits 0-15: Time-out Value (USART only) */ +#define UART_RTOR_TO_MASK (0xffff << UART_RTOR_TO_SHIFT) + +/* USART Transmitter Timeguard Register (USART only) */ + +#define UART_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value (USART only) */ +#define UART_TTGR_TG_MASK (0xff << UART_TTGR_TG_SHIFT) + +/* USART FI DI RATIO Register (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM4E) +# define UART_FIDI_RATIO_SHIFT (0) /* Bits 0-15: FI Over DI Ratio Value (USART only) */ +# define UART_FIDI_RATIO_MASK (0xffff << UART_FIDI_RATIO_SHIFT) +#else +# define UART_FIDI_RATIO_SHIFT (0) /* Bits 0-10: FI Over DI Ratio Value (USART only) */ +# define UART_FIDI_RATIO_MASK (0x7ff << UART_FIDI_RATIO_SHIFT) +#endif + +/* USART Number of Errors Register (USART only) */ + +#define UART_NER_NBERRORS_SHIFT (0) /* Bits 0-7: Number of Errrors (USART only) */ +#define UART_NER_NBERRORS_MASK (0xff << UART_NER_NBERRORS_SHIFT) + +/* USART IrDA FILTER Register (USART only) */ + +#define UART_IFR_IRDAFILTER_SHIFT (0) /* Bits 0-7: IrDA Filter (USART only) */ +#define UART_IFR_IRDAFILTER_MASK (0xff << UART_IFR_IRDAFILTER_SHIFT) + +/* USART Manchester Configuration Register (USART only) */ + +#define UART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length (USART only) */ +#define UART_MAN_TXPL_MASK (15 << UART_MAN_TXPL_SHIFT) +# define UART_MAN_TXPL(n) ((uint32_t)(n) << UART_MAN_TXPL_SHIFT) +#define UART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern (USART only) */ +#define UART_MAN_TXPP_MASK (3 << UART_MAN_TXPP_SHIFT) +# define UART_MAN_TXPP_ALLONE (0 << UART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_TXPP_ALLZERO (1 << UART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_TXPP_ZEROONE (2 << UART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_TXPP_ONEZERO (3 << UART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity (USART only) */ +#define UART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length (USART only) */ +#define UART_MAN_RXPL_MASK (15 << UART_MAN_RXPL_SHIFT) +# define UART_MAN_RXPL(n) ((uint32_t)(n) << UART_MAN_RXPL_SHIFT) +#define UART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected (USART only) */ +#define UART_MAN_RXPP_MASK (3 << UART_MAN_RXPP_SHIFT) +# define UART_MAN_RXPP_ALLONE (0 << UART_MAN_RXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_RXPP_ALLZERO (1 << UART_MAN_RXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_RXPP_ZEROONE (2 << UART_MAN_RXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_RXPP_ONEZERO (3 << UART_MAN_RXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define UART_MAN_ONE (1 << 29) /* Bit 29: Must Be Set to 1 */ +#endif + +#define UART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation (USART only) */ + +/* LIN Mode Register (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_LINMR_NACT_SHIFT (0) /* Bits 0-1: LIN Node Action */ +# define UART_LINMR_NACT_MASK (3 << UART_LINMR_NACT_SHIFT) +# define UART_LINMR_NACT_PUBLISH (0 << UART_LINMR_NACT_SHIFT) /* USART transmits response */ +# define UART_LINMR_NACT_SUBSCRIBE (1 << UART_LINMR_NACT_SHIFT) /* USART receives response */ +# define UART_LINMR_NACT_IGNORE (2 << UART_LINMR_NACT_SHIFT) /* USART does not transmit or receive response */ +# define UART_LINMR_PARDIS (1 << 2) /* Bit 2: Parity Disable */ +# define UART_LINMR_CHKDIS (1 << 3) /* Bit 3: Checksum Disable */ +# define UART_LINMR_CHKTYP (1 << 4) /* Bit 4: Checksum Type */ +# define UART_LINMR_DLM (1 << 5) /* Bit 5: Data Length Mode */ +# define UART_LINMR_FSDIS (1 << 6) /* Bit 6: Frame Slot Mode Disable */ +# define UART_LINMR_WKUPTYP (1 << 7) /* Bit 7: Wakeup Signal Type */ +# define UART_LINMR_DLC_SHIFT (8) /* Bits 8-15: Data Length Control */ +# define UART_LINMR_DLC_MASK (0xff << UART_LINMR_DLC_SHIFT) +# define UART_LINMR_DLC(n) ((uint32_t)(n) << UART_LINMR_DLC_SHIFT) +# define UART_LINMR_PDCM (1 << 16) /* Bit 16: PDC Mode */ +#endif + +/* LIN Identifier Register (USART only) */ + +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# define UART_LINIR_MASK 0xff /* Bits 0-7: Identifier Character */ +#endif + +/* USART Write Protect Mode Register (USART only) */ + +#define UART_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable (USART only) */ +#define UART_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (USART only) */ +#define UART_WPMR_WPKEY_MASK (0x00ffffff << UART_WPMR_WPKEY_SHIFT) +# define UART_WPMR_WPKEY (0x00554152 << UART_WPMR_WPKEY_SHIFT) +# define USART_WPMR_WPKEY (0x00555341 << UART_WPMR_WPKEY_SHIFT) + +/* USART Write Protect Status Register (USART only) */ + +#define UART_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status (USART only) */ +#define UART_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source (USART only) */ +#define UART_WPSR_WPVSRC_MASK (0xffff << UART_WPSR_WPVSRC_SHIFT) + +/* USART Version Register */ + +#define UART_VERSION_VERSION_SHIFT (0) /* Bits 0-11: Macrocell version number (USART only) */ +#define UART_VERSION_VERSION_MASK (0xfff << UART_VERSION_VERSION_SHIFT) +#define UART_VERSION_MFN_SHIFT (16) /* Bits 16-18: Reserved (USART only) */ +#define UART_VERSION_MFN_MASK (7 << UART_VERSION_MFN_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_UART_H */ diff --git a/arch/arm/src/sam34/chip/sam_udp.h b/arch/arm/src/sam34/chip/sam_udp.h new file mode 100644 index 0000000000000000000000000000000000000000..267bcc43ae8fcff692f94c235d4013e0482d27c4 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_udp.h @@ -0,0 +1,261 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_udp.h + * USB Device Port (UDP) definitions for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDP_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDP_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General Definitions ******************************************************************/ +/* Capabilities and characteristics of endpoints + * + * EP EP BANKS EP SIZE EP TYPE + * --- --------- --------- --------- + * 0 1 64 Control/Bulk/Interrupt + * 1 2 64 Bulk/Iso/Interrupt + * 2 2 64 Bulk/Iso/Interrupt + * 3 1 64 Control/Bulk/Interrupt + * 4 2 512 Bulk/Iso/Interrupt + * 5 2 512 Bulk/Iso/Interrupt + * 6 2 64 Bulk/Iso/Interrupt + * 7 2 64 Bulk/Iso/Interrupt + */ + +#define SAM_UDP_NENDPOINTS 8 /* EP0-7 */ +#define SAM_UDP_MAXPACKETSIZE(ep) ((((unsigned)(ep) & 6) == 4) ? 512 : 64) +#define SAM_UDP_NBANKS(ep) (((unsigned)(ep) == 0 || (unsigned)(ep) == 3) ? 1 : 2) +#define SAM_UDP_CONTROL(ep) (((unsigned)(ep) == 0 || (unsigned)(ep) == 3)) +#define SAM_UDP_BULK(ep) (true) +#define SAM_UDP_ISOCHRONOUS(ep) (((unsigned)(ep) != 0 && (unsigned)(ep) != 3)) +#define SAM_UDP_INTERRUPT(ep) (true) + +/* UDP register offsets *****************************************************************/ + +/* Global Registers */ + +#define SAM_UDP_FRMNUM_OFFSET 0x0000 /* UDP Frame Number Register */ +#define SAM_UDP_GLBSTAT_OFFSET 0x0004 /* UDP Global State Register */ +#define SAM_UDP_FADDR_OFFSET 0x0008 /* UDP Function Address Register */ + /* 0x000c: Reserved */ +#define SAM_UDP_IER_OFFSET 0x0010 /* UDP Interrupt Enable Register */ +#define SAM_UDP_IDR_OFFSET 0x0014 /* UDP Interrupt Disable Register */ +#define SAM_UDP_IMR_OFFSET 0x0018 /* UDP Interrupt Mask Register */ +#define SAM_UDP_ISR_OFFSET 0x001c /* UDP Interrupt Status Register */ +#define SAM_UDP_ICR_OFFSET 0x0020 /* UDP Interrupt Clear Register */ + /* 0x0024: Reserved */ +#define SAM_UDP_RSTEP_OFFSET 0x0028 /* UDP Reset Endpoint Register */ + /* 0x002c: Reserved */ +/* Endpoint registers */ + +#define SAM_UDPEP_CSR_OFFSET(n) (0x0030+((n)<<2)) +# define SAM_UDPEP_CSR0_OFFSET 0x0030 /* Endpoint Control and Status Register 0 */ +# define SAM_UDPEP_CSR1_OFFSET 0x0034 /* Endpoint Control and Status Register 1 */ +# define SAM_UDPEP_CSR2_OFFSET 0x0038 /* Endpoint Control and Status Register 2 */ +# define SAM_UDPEP_CSR3_OFFSET 0x003c /* Endpoint Control and Status Register 3 */ +# define SAM_UDPEP_CSR4_OFFSET 0x0040 /* Endpoint Control and Status Register 4 */ +# define SAM_UDPEP_CSR5_OFFSET 0x0044 /* Endpoint Control and Status Register 5 */ +# define SAM_UDPEP_CSR6_OFFSET 0x0048 /* Endpoint Control and Status Register 6 */ +# define SAM_UDPEP_CSR7_OFFSET 0x004c /* Endpoint Control and Status Register 7 */ +#define SAM_UDPEP_FDR_OFFSET(n) (0x0050+((n)<<2)) +# define SAM_UDPEP_FDR0_OFFSET 0x0050 /* Endpoint FIFO Data Register 0 */ +# define SAM_UDPEP_FDR1_OFFSET 0x0054 /* Endpoint FIFO Data Register 1 */ +# define SAM_UDPEP_FDR2_OFFSET 0x0058 /* Endpoint FIFO Data Register 2 */ +# define SAM_UDPEP_FDR3_OFFSET 0x005c /* Endpoint FIFO Data Register 3 */ +# define SAM_UDPEP_FDR4_OFFSET 0x0060 /* Endpoint FIFO Data Register 4 */ +# define SAM_UDPEP_FDR5_OFFSET 0x0064 /* Endpoint FIFO Data Register 5 */ +# define SAM_UDPEP_FDR6_OFFSET 0x0068 /* Endpoint FIFO Data Register 6 */ +# define SAM_UDPEP_FDR7_OFFSET 0x006c /* Endpoint FIFO Data Register 7 */ + /* 0x0070: Reserved */ +#define SAM_UDP_TXVC_OFFSET 0x0074 /* Transceiver Control Register */ + /* 0x0078-0x00fc: Reserved */ + +/* UDP register addresses ***************************************************************/ + +/* Global Registers */ + +#define SAM_UDP_FRMNUM (SAM_UDP_BASE+SAM_UDP_FRMNUM_OFFSET) +#define SAM_UDP_GLBSTAT (SAM_UDP_BASE+SAM_UDP_GLBSTAT_OFFSET) +#define SAM_UDP_FADDR (SAM_UDP_BASE+SAM_UDP_FADDR_OFFSET) +#define SAM_UDP_IER (SAM_UDP_BASE+SAM_UDP_IER_OFFSET) +#define SAM_UDP_IDR (SAM_UDP_BASE+SAM_UDP_IDR_OFFSET) +#define SAM_UDP_IMR (SAM_UDP_BASE+SAM_UDP_IMR_OFFSET) +#define SAM_UDP_ISR (SAM_UDP_BASE+SAM_UDP_ISR_OFFSET) +#define SAM_UDP_ICR (SAM_UDP_BASE+SAM_UDP_ICR_OFFSET) +#define SAM_UDP_RSTEP (SAM_UDP_BASE+SAM_UDP_RSTEP_OFFSET) + +/* Endpoint registers */ + +#define SAM_UDPEP_CSR(n) (SAM_UDP_BASE+SAM_UDPEP_CSR_OFFSET(n)) +# define SAM_UDPEP_CSR0 (SAM_UDP_BASE+SAM_UDPEP_CSR0_OFFSET) +# define SAM_UDPEP_CSR1 (SAM_UDP_BASE+SAM_UDPEP_CSR1_OFFSET) +# define SAM_UDPEP_CSR2 (SAM_UDP_BASE+SAM_UDPEP_CSR2_OFFSET) +# define SAM_UDPEP_CSR3 (SAM_UDP_BASE+SAM_UDPEP_CSR3_OFFSET) +# define SAM_UDPEP_CSR4 (SAM_UDP_BASE+SAM_UDPEP_CSR4_OFFSET) +# define SAM_UDPEP_CSR5 (SAM_UDP_BASE+SAM_UDPEP_CSR5_OFFSET) +# define SAM_UDPEP_CSR6 (SAM_UDP_BASE+SAM_UDPEP_CSR6_OFFSET) +# define SAM_UDPEP_CSR7 (SAM_UDP_BASE+SAM_UDPEP_CSR7_OFFSET) +#define SAM_UDPEP_FDR(n) (SAM_UDP_BASE+SAM_UDPEP_FDR_OFFSET(n)) +# define SAM_UDPEP_FDR0 (SAM_UDP_BASE+SAM_UDPEP_FDR0_OFFSET) +# define SAM_UDPEP_FDR1 (SAM_UDP_BASE+SAM_UDPEP_FDR1_OFFSET) +# define SAM_UDPEP_FDR2 (SAM_UDP_BASE+SAM_UDPEP_FDR2_OFFSET) +# define SAM_UDPEP_FDR3 (SAM_UDP_BASE+SAM_UDPEP_FDR3_OFFSET) +# define SAM_UDPEP_FDR4 (SAM_UDP_BASE+SAM_UDPEP_FDR4_OFFSET) +# define SAM_UDPEP_FDR5 (SAM_UDP_BASE+SAM_UDPEP_FDR5_OFFSET) +# define SAM_UDPEP_FDR6 (SAM_UDP_BASE+SAM_UDPEP_FDR6_OFFSET) +# define SAM_UDPEP_FDR7 (SAM_UDP_BASE+SAM_UDPEP_FDR7_OFFSET) + +#define SAM_UDP_TXVC (SAM_UDP_BASE+SAM_UDP_TXVC_OFFSET) + +/* UDP register bit definitions *********************************************************/ + +/* Global Registers */ + +/* UDP Frame Number Register */ + +#define UDP_FRMNUM_SHIFT (0) /* Bits 0-10: Frame Number in Packet Field Formats */ +#define UDP_FRMNUM_MASK (0x000007ff) +#define UDP_FRMNUM_FRMERR (1 << 16) /* Bit 16: Frame Error */ +#define UDP_FRMNUM_FRMOK (1 << 17) /* Bit 17: Frame OK */ + +/* UDP Global State Register */ + +#define UDP_GLBSTAT_FADDEN (1 << 0) /* Bit 0: Function Address Enable */ +#define UDP_GLBSTAT_CONFG (1 << 1) /* Bit 1: Configured */ +#define UDP_GLBSTAT_ESR (1 << 2) /* Bit 2: Enable Send Resume */ +#define UDP_GLBSTAT_RSMINPR (1 << 3) /* Bit 3: */ +#define UDP_GLBSTAT_RMWUPE (1 << 4) /* Bit 4: Remote Wake-up Enable */ + +/* UDP Function Address Register */ + +#define UDP_FADDR_SHIFT (0) /* Bits 0-6: Function Address Value */ +#define UDP_FADDR_MASK (0x0000007f) +# define UDP_FADDR(n) ((uint32_t)(n)) +#define UDP_FADDR_FEN (1 << 8) /* Bit 8: Function Enable */ + +/* UDP Interrupt Enable, UDP Interrupt Disable, UDP Interrupt Mask, UDP Interrupt + * Status, and UDP Interrupt Clear Registers. + */ + +#define UDP_INT_EP_MASK (0x000000ff) +#define UDP_INT_EP(n) (1 << (n)) +# define UDP_INT_EP0 (1 << 0) /* Bit 0: Endpoint 0 Interrupt (Not ICR) */ +# define UDP_INT_EP1 (1 << 1) /* Bit 1: Endpoint 1 Interrupt (Not ICR) */ +# define UDP_INT_EP2 (1 << 2) /* Bit 2: Endpoint 2 Interrupt (Not ICR) */ +# define UDP_INT_EP3 (1 << 3) /* Bit 3: Endpoint 3 Interrupt (Not ICR) */ +# define UDP_INT_EP4 (1 << 4) /* Bit 4: Endpoint 4 Interrupt (Not ICR) */ +# define UDP_INT_EP5 (1 << 5) /* Bit 5: Endpoint 5 Interrupt (Not ICR) */ +# define UDP_INT_EP6 (1 << 6) /* Bit 6: Endpoint 6 Interrupt (Not ICR) */ +# define UDP_INT_EP7 (1 << 7) /* Bit 7: Endpoint 7 Interrupt (Not ICR) */ +#define UDP_INT_RXSUSP (1 << 8) /* Bit 8: UDP Suspend Interrupt */ +#define UDP_INT_RXRSM (1 << 9) /* Bit 9: UDP Resume Interrupt */ +#define UDP_INT_EXTRSM (1 << 10) /* Bit 10: */ +#define UDP_INT_SOF (1 << 11) /* Bit 11: Start Of Frame Interrupt */ +#define UDP_ISR_ENDBUSRES (1 << 12) /* Bit 12: End of BUS Reset Interrupt Status (ISR and ICR only) */ +#define UDP_INT_WAKEUP (1 << 13) /* Bit 13: UDP bus Wake-up Interrupt */ + +#define UDP_INT_ALL (0x00003fff) + +/* UDP Reset Endpoint Register */ + +#define UDP_RSTEP(n) (1 << (n)) +# define UDP_RSTEP0 (1 << 0) /* Bit 0: Reset Endpoint 0 */ +# define UDP_RSTEP1 (1 << 1) /* Bit 1: Reset Endpoint 1 */ +# define UDP_RSTEP2 (1 << 2) /* Bit 2: Reset Endpoint 2 */ +# define UDP_RSTEP3 (1 << 3) /* Bit 3: Reset Endpoint 3 */ +# define UDP_RSTEP4 (1 << 4) /* Bit 4: Reset Endpoint 4 */ +# define UDP_RSTEP5 (1 << 5) /* Bit 5: Reset Endpoint 5 */ +# define UDP_RSTEP6 (1 << 6) /* Bit 6: Reset Endpoint 6 */ +# define UDP_RSTEP7 (1 << 7) /* Bit 7: Reset Endpoint 7 */ + +/* Endpoint registers */ +/* Endpoint Control and Status Registers */ + +#define UDPEP_CSR_TXCOMP (1 << 0) /* Bit 0: Generates an IN packet with data */ +#define UDPEP_CSR_RXDATABK0 (1 << 1) /* Bit 1: Receive Data Bank 0 */ +#define UDPEP_CSR_RXSETUP (1 << 2) /* Bit 2: Received Setup */ +#define UDPEP_CSR_STALLSENT (1 << 3) /* Bit 3: Stall Sent */ +#define UDPEP_CSR_ISOERROR (1 << 3) /* Bit 3: CRC error in isochronous transfer */ +#define UDPEP_CSR_TXPKTRDY (1 << 4) /* Bit 4: Transmit Packet Ready */ +#define UDPEP_CSR_FORCESTALL (1 << 5) /* Bit 5: Force Stall */ +#define UDPEP_CSR_RXDATABK1 (1 << 6) /* Bit 6: Receive Data Bank 1 */ +#define UDPEP_CSR_DIR_SHIFT (7) /* Bit 7: Transfer Direction */ +#define UDPEP_CSR_DIR (1 << 7) /* Bit 7: Transfer Direction */ +#define UDPEP_CSR_EPTYPE_SHIFT (8) /* Bit 8-10: Endpoint type */ +#define UDPEP_CSR_EPTYPE_MASK (7 << UDPEP_CSR_EPTYPE_SHIFT) +# define UDPEP_CSR_EPTYPE_CTRL (0 << UDPEP_CSR_EPTYPE_SHIFT) /* Control */ +# define UDPEP_CSR_EPTYPE_ISOOUT (1 << UDPEP_CSR_EPTYPE_SHIFT) /* Isochronous OUT */ +# define UDPEP_CSR_EPTYPE_ISOIN (5 << UDPEP_CSR_EPTYPE_SHIFT) /* Isochronous IN */ +# define UDPEP_CSR_EPTYPE_BULKOUT (2 << UDPEP_CSR_EPTYPE_SHIFT) /* Bulk OUT */ +# define UDPEP_CSR_EPTYPE_BULKIN (6 << UDPEP_CSR_EPTYPE_SHIFT) /* Bulk IN */ +# define UDPEP_CSR_EPTYPE_INTOUT (3 << UDPEP_CSR_EPTYPE_SHIFT) /* Interrupt OUT */ +# define UDPEP_CSR_EPTYPE_INTIN (7 << UDPEP_CSR_EPTYPE_SHIFT) /* Interrupt IN */ +#define UDPEP_CSR_DTGLE (1 << 11) /* Bit 11: Data Toggle */ +#define UDPEP_CSR_EPEDS (1 << 15) /* Bit 15: Endpoint Enable Disable */ +#define UDPEP_CSR_RXBYTECNT_SHIFT (16) /* Bits 16-26: Number of Bytes Available in the FIFO */ +#define UDPEP_CSR_RXBYTECNT_MASK (0x7ff << UDPEP_CSR_RXBYTECNT_SHIFT) + +/* Endpoint FIFO Data Registers */ + +#define UDPEP_FDR_MASK (0xff) /* Bits 0-7: FIFO data value */ + +/* Transceiver Control Register */ + +#define UDP_TXVC_TXVDIS (1 << 8) /* Bit 8: Transceiver Disable */ +#define UDP_TXVC_PUON (1 << 9) /* Bit 9: Pull-up On */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDP_H */ diff --git a/arch/arm/src/sam34/chip/sam_udphs.h b/arch/arm/src/sam34/chip/sam_udphs.h new file mode 100644 index 0000000000000000000000000000000000000000..e359c555588a38eb4b5e0b7cdb8f42f616c9bc89 --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_udphs.h @@ -0,0 +1,371 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_udphs.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDPHS_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDPHS_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* UDPHS register offsets ***************************************************************/ + +#define SAM_UDPHS_CTRL_OFFSET 0x00 /* UDPHS Control Register */ +#define SAM_UDPHS_FNUM_OFFSET 0x04 /* UDPHS Frame Number Register */ + /* 0x08-0x0C: Reserved */ +#define SAM_UDPHS_IEN_OFFSET 0x10 /* UDPHS Interrupt Enable Register */ +#define SAM_UDPHS_INTSTA_OFFSET 0x14 /* UDPHS Interrupt Status Register */ +#define SAM_UDPHS_CLRINT_OFFSET 0x18 /* UDPHS Clear Interrupt Register */ +#define SAM_UDPHS_EPTRST_OFFSET 0x1c /* UDPHS Endpoints Reset Register */ + /* 0x20-0xcc: Reserved */ +#define SAM_UDPHS_TST_OFFSET 0xe0 /* UDPHS Test Register */ + /* 0xE4-0xE8: Reserved */ +#define SAM_UDPHS_IPNAME1_OFFSET 0xf0 /* UDPHS Name1 Register */ +#define SAM_UDPHS_IPNAME2_OFFSET 0xf4 /* UDPHS Name2 Register */ +#define SAM_UDPHS_IPFEATURES_OFFSET 0xf8 /* UDPHS Features Register */ + +/* Endpoint registers: Offsets for Endpoints 0-6: 0x100, 0x120, 0x140, 0x160, 0x180, + * 0x1a0, and 0x1c0 + */ + +#define SAM_UDPHSEP_OFFSET(n) (0x100+((n)<<5)) +#define SAM_UDPHSEP_CFG_OFFSET 0x00 /* UDPHS Endpoint Configuration Register */ +#define SAM_UDPHSEP_CTLENB_OFFSET 0x04 /* UDPHS Endpoint Control Enable Register */ +#define SAM_UDPHSEP_CTLDIS_OFFSET 0x08 /* UDPHS Endpoint Control Disable Register */ +#define SAM_UDPHSEP_CTL_OFFSET 0x0c /* UDPHS Endpoint Control Register */ + /* 0x10: Reserved */ +#define SAM_UDPHSEP_SETSTA_OFFSET 0x14 /* UDPHS Endpoint Set Status Register */ +#define SAM_UDPHSEP_CLRSTA_OFFSET 0x18 /* UDPHS Endpoint Clear Status Register */ +#define SAM_UDPHSEP_STA_OFFSET 0x1c /* UDPHS Endpoint Status Register */ + /* 0x1e0-0x300: Reserved */ + /* 0x300-0x30c: Reserved */ +/* DMA Channel Registers: Offsets for DMA channels 1-6 0x320, 0x330, 0x340, 0x350, and + * 0x360. NOTE that there is no DMA channel 0. + */ + +#define SAM_UDPHSDMA_OFFSET(n) (0x310+((n)<<4)) +#define SAM_UDPHSDMA_NXTDSC_OFFSET 0x00 /* UDPHS DMA Next Descriptor Address Register */ +#define SAM_UDPHSDMA_ADDRESS_OFFSET 0x04 /* UDPHS DMA Channel Address Register */ +#define SAM_UDPHSDMA_CONTROL_OFFSET 0x08 /* UDPHS DMA Channel Control Register */ +#define SAM_UDPHSDMA_STATUS_OFFSET 0x0c /* UDPHS DMA Channel Status Register */ + +/* UDPHS register addresses *************************************************************/ + +#define SAM_UDPHS_CTRL (SAM_UDPHS_BASE+SAM_UDPHS_CTRL_OFFSET) +#define SAM_UDPHS_FNUM (SAM_UDPHS_BASE+SAM_UDPHS_FNUM_OFFSET) +#define SAM_UDPHS_IEN (SAM_UDPHS_BASE+SAM_UDPHS_IEN_OFFSET) +#define SAM_UDPHS_INTSTA (SAM_UDPHS_BASE+SAM_UDPHS_INTSTA_OFFSET) +#define SAM_UDPHS_CLRINT (SAM_UDPHS_BASE+ SAM_UDPHS_CLRINT_OFFSET) +#define SAM_UDPHS_EPTRST (SAM_UDPHS_BASE+SAM_UDPHS_EPTRST_OFFSET) +#define SAM_UDPHS_TST (SAM_UDPHS_BASE+SAM_UDPHS_TST_OFFSET) +#define SAM_UDPHS_IPNAME1 (SAM_UDPHS_BASE+SAM_UDPHS_IPNAME1_OFFSET) +#define SAM_UDPHS_IPNAME2 (SAM_UDPHS_BASE+SAM_UDPHS_IPNAME2_OFFSET) +#define SAM_UDPHS_IPFEATURES (SAM_UDPHS_BASE+SAM_UDPHS_IPFEATURES_OFFSET) + +/* Endpoint registers */ + +#define SAM_UDPHSEP_BASE(n)) (SAM_UDPHS_BASE+SAM_UDPHSEP_OFFSET(n)) +#define SAM_UDPHSEP_CFG(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_CFG_OFFSET) +#define SAM_UDPHSEP_CTLENB(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_CTLENB_OFFSET) +#define SAM_UDPHSEP_CTLDIS(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_CTLDIS_OFFSET) +#define SAM_UDPHSEP_CTL(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_CTL_OFFSET) +#define SAM_UDPHSEP_SETSTA(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_SETSTA_OFFSET) +#define SAM_UDPHSEP_CLRSTA(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_CLRSTA_OFFSET) +#define SAM_UDPHSEP_STA(n) (SAM_UDPHSEP_BASE(n)+SAM_UDPHSEP_STA_OFFSET) + +/* DMA Channel Registers*/ + +#define SAM_UDPHSDMA_BASE(n) (SAM_UDPHS_BASE+SAM_UDPHSDMA_OFFSET(n)) +#define SAM_UDPHSDMA_NXTDSC(n) (SAM_UDPHSDMA_BASE(n)+SAM_UDPHSDMA_NXTDSC_OFFSET) +#define SAM_UDPHSDMA_ADDRESS(n) (SAM_UDPHSDMA_BASE(n)+SAM_UDPHSDMA_ADDRESS_OFFSET) +#define SAM_UDPHSDMA_CONTROL(n) (SAM_UDPHSDMA_BASE(n)+SAM_UDPHSDMA_CONTROL_OFFSET) +#define SAM_UDPHSDMA_STATUS(n) (SAM_UDPHSDMA_BASE(n)+SAM_UDPHSDMA_STATUS_OFFSET) + +/* UDPHS register bit definitions *******************************************************/ +/* UDPHS Control Register */ + +#define UDPHS_CTRL_DEVADDR_SHIFT (0) /* Bits 0-6: UDPHS Address */ +#define UDPHS_CTRL_DEVADDR_MASK (0x7f << UDPHS_CTRL_DEVADDR_SHIFT) +#define UDPHS_CTRL_FADDREN (1 << 7) /* Bit 7: Function Address Enable */ +#define UDPHS_CTRL_ENUDPHS (1 << 8) /* Bit 8: UDPHS Enable */ +#define UDPHS_CTRL_DETACH (1 << 9) /* Bit 9: Detach Command */ +#define UDPHS_CTRL_REWAKEUP (1 << 10) /* Bit 10: Send Remote Wake Up */ +#define UDPHS_CTRL_PULLDDIS (1 << 11) /* Bit 11: Pull-Down Disable */ + +/* UDPHS Frame Number Register */ + +#define UDPHS_FNUM_MICROFRAMENUM_SHIFT (0) /* Bits 0-2: Microframe Num */ +#define UDPHS_FNUM_MICROFRAMENUM_MASK (7 << UDPHS_FNUM_MICROFRAMENUM_SHIFT) +#define UDPHS_FNUM_FRAMENUMBER_SHIFT (3) /* Bits 3-7: Frame Number in Packet Field Formats */ +#define UDPHS_FNUM_FRAMENUMBER_MASK (31 << UDPHS_FNUM_FRAMENUMBER_SHIFT) +#define UDPHS_FNUM_FNUMERR_SHIFT (8) /* Bits 8-13: Frame Number CRC Error */ +#define UDPHS_FNUM_FNUMERR_MASK (63 << UDPHS_FNUM_FNUMERR_SHIFT) + +/* UDPHS Interrupt Enable Register, UDPHS Interrupt Status Register, and UDPHS Clear + * Interrupt Register common bit-field definitions + */ + +#define USBPHS_INT_DETSUSPD (1 << 1) /* Bit 1: Suspend Interrupt (Common) */ +#define USBPHS_INT_MICROSOF (1 << 2) /* Bit 2: Micro-SOF Interrupt (Common) */ +#define USBPHS_INT_INTSOF (1 << 3) /* Bit 3: SOF Interrupt (Common) */ +#define USBPHS_INT_ENDRESET (1 << 4) /* Bit 4: End Of Reset Interrupt (Common) */ +#define USBPHS_INT_WAKEUP (1 << 5) /* Bit 5: Wake Up CPU Interrupt (Common) */ +#define USBPHS_INT_ENDOFRSM (1 << 6) /* Bit 6: End Of Resume Interrupt (Common) */ +#define USBPHS_INT_UPSTRRES (1 << 7) /* Bit 7: Upstream Resume Interrupt (Common) */ +#define USBPHS_INT_EPT(n) (1 << ((n)+8)) +#define USBPHS_INT_EPT0 (1 << 8) /* Bit 8: Endpoint 0 Interrupt (not Clear) */ +#define USBPHS_INT_EPT1 (1 << 9) /* Bit 9: Endpoint 1 Interrupt (not Clear) */ +#define USBPHS_INT_EPT2 (1 << 10) /* Bit 10: Endpoint 2 Interrupt (not Clear) */ +#define USBPHS_INT_EPT3 (1 << 11) /* Bit 11: Endpoint 3 Interrupt (not Clear) */ +#define USBPHS_INT_EPT4 (1 << 12) /* Bit 12: Endpoint 4 Interrupt (not Clear) */ +#define USBPHS_INT_EPT5 (1 << 13) /* Bit 13: Endpoint 5 Interrupt (not Clear) */ +#define USBPHS_INT_EPT6 (1 << 13) /* Bit 14: Endpoint 6 Interrupt (not Clear) */ +#define USBPHS_INT_DMA(n) (1<<((n)+24)) +#define USBPHS_INT_DMA1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt (not Clear) */ +#define USBPHS_INT_DMA2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt (not Clear) */ +#define USBPHS_INT_DMA3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt (not Clear) */ +#define USBPHS_INT_DMA4 (1 << 28) /* Bit 28: DMA Channel 4 Interrupt (not Clear) */ +#define USBPHS_INT_DMA5 (1 << 29) /* Bit 29: DMA Channel 5 Interrupt (not Clear) */ +#define USBPHS_INT_DMA6 (1 << 30) /* Bit 30: DMA Channel 6 Interrupt (not Clear) */ + +/* UDPHS Endpoints Reset Register */ + +#define UDPHS_EPTRST_EPT(n) (1<<(n)) /* Bit 0-6: Endpoint n Reset */ + +/* UDPHS Test Register */ + +#define UDPHS_TST_SPEEDCFG_SHIFT (0) /* Bits 0-1: Speed Configuration */ +#define UDPHS_TST_SPEEDCFG_MASK (3 << UDPHS_TST_SPEEDCFG_SHIFT) +# define UDPHS_TST_SPEEDCFG_NORMAL (0 << UDPHS_TST_SPEEDCFG_SHIFT) /* Normal Mode */ +# define UDPHS_TST_SPEEDCFG_HIGH (2 << UDPHS_TST_SPEEDCFG_SHIFT) /* Force High Speed */ +# define UDPHS_TST_SPEEDCFG_FULL (3 << UDPHS_TST_SPEEDCFG_SHIFT) /* Force Full Speed */ +#define UDPHS_TST_TSTJ (1 << 2) /* Bit 2: Test J Mode */ +#define UDPHS_TST_TSTK (1 << 3) /* Bit 3: Test K Mode */ +#define UDPHS_TST_TSTPKT (1 << 4) /* Bit 4: Test Packet Mo */ +#define UDPHS_TST_OPMODE2 (1 << 5) /* Bit 5: OpMode2 */ + +/* UDPHS Features Register */ + +#define UDPHS_IPFEATURES_EPTNBRMAX_SHIFT (0) /* Bits 0-3: Max Number of Endpoints */ +#define UDPHS_IPFEATURES_EPTNBRMAX_MASK (15 << UDPHS_IPFEATURES_EPTNBRMAX_SHIFT) +#define UDPHS_IPFEATURES_DMACHANNELNBR_SHIFT (4) /* Bits 4-6: Number of DMA Channels */ +#define UDPHS_IPFEATURES_DMACHANNELNBR_MASK (7 << UDPHS_IPFEATURES_DMACHANNELNBR_SHIFT) +#define UDPHS_IPFEATURES_DMABSIZ (1 << 7) /* Bit 7: DMA Buffer Size */ +#define UDPHS_IPFEATURES_DMAFIFOWDDEPTH_SHIFT (8) /* Bits 8-11: DMA FIFO Depth in Words */ +#define UDPHS_IPFEATURES_DMAFIFOWDDEPTH_MASK (15 << UDPHS_IPFEATURES_DMAFIFOWDDEPTH_SHIFT) +# define UDPHS_IPFEATURES_DMAFIFOWDDEPTH(n) ((n)&15) +#define UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT (12) /* Bits 12-14: DPRAM Size */ +#define UDPHS_IPFEATURES_FIFOMAXSIZE_MASK (7 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) +# define UDPHS_IPFEATURES_FIFOMAXSIZE_128b (0 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 128 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_256b (1 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 256 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_512b (2 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 512 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_1Kb (3 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 1024 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_2Kb (4 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 2048 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_4Kb (5 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 4096 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_8Kb (6 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 8192 bytes */ +# define UDPHS_IPFEATURES_FIFOMAXSIZE_16Kb (7 << UDPHS_IPFEATURES_FIFOMAXSIZE_SHIFT) /* DPRAM 16384 bytes */ +#define UDPHS_IPFEATURES_BWDPRAM (1 << 15) /* Bit 15: DPRAM Byte Write Capability */ +#define UDPHS_IPFEATURES_DATAB168 (1 << 15) /* Bit 15: UTMI DataBus16_8 */ +#define UDPHS_IPFEATURES_ISOEPT(n) (1<<((n)+16) +#define UDPHS_IPFEATURES_ISOEPT1 (1 << 17) /* Bit 17: EP1 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT2 (1 << 18) /* Bit 18: EP2 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT3 (1 << 19) /* Bit 19: EP3 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT4 (1 << 20) /* Bit 20: EP4 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT5 (1 << 21) /* Bit 21: EP5 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT6 (1 << 22) /* Bit 22: EP6 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT7 (1 << 23) /* Bit 23: EP7 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT8 (1 << 24) /* Bit 24: EP8 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT9 (1 << 25) /* Bit 25: EP9 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT10 (1 << 26) /* Bit 26: EP10 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT11 (1 << 27) /* Bit 27: EP11 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT12 (1 << 28) /* Bit 28: EP12 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT13 (1 << 29) /* Bit 29: EP13 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT14 (1 << 30) /* Bit 30: EP14 High B/W Isoc Capability */ +#define UDPHS_IPFEATURES_ISOEPT15 (1 << 31) /* Bit 31: EP15 High B/W Isoc Capability */ + +/* UDPHS Endpoint Configuration Register (0-6) */ + +#define UDPHSEP_CFG_SIZE_SHIFT (0) /* Bits 0-2: Endpoint Size */ +#define UDPHSEP_CFG_SIZE_MASK (7 << UDPHSEP_CFG_SIZE_SHIFT) +# define UDPHSEP_CFG_SIZE_8b (0 << UDPHSEP_CFG_SIZE_SHIFT) /* 8 bytes */ +# define UDPHSEP_CFG_SIZE_16b (1 << UDPHSEP_CFG_SIZE_SHIFT) /* 16 bytes */ +# define UDPHSEP_CFG_SIZE_32b (2 << UDPHSEP_CFG_SIZE_SHIFT) /* 32 bytes */ +# define UDPHSEP_CFG_SIZE_64b (3 << UDPHSEP_CFG_SIZE_SHIFT) /* 64 bytes */ +# define UDPHSEP_CFG_SIZE_128b (4 << UDPHSEP_CFG_SIZE_SHIFT) /* 128 bytes */ +# define UDPHSEP_CFG_SIZE_256b (5 << UDPHSEP_CFG_SIZE_SHIFT) /* 256 bytes */ +# define UDPHSEP_CFG_SIZE_512b (6 << UDPHSEP_CFG_SIZE_SHIFT) /* 512 bytes */ +# define UDPHSEP_CFG_SIZE_1Kb (7 << UDPHSEP_CFG_SIZE_SHIFT) /* 1024 bytes */ +#define UDPHSEP_CFG_DIR (1 << 3) /* Bit 3: Endpoint Direction */ +#define UDPHSEP_CFG_TYPE_SHIFT (4) /* Bits 4-5: Endpoint Type */ +#define UDPHSEP_CFG_TYPE_MASK (3 << UDPHSEP_CFG_TYPE_SHIFT) +# define UDPHSEP_CFG_TYPE_CNTRL (0 << UDPHSEP_CFG_TYPE_SHIFT) /* Control endpoint */ +# define UDPHSEP_CFG_TYPE_ISOC (1 << UDPHSEP_CFG_TYPE_SHIFT) /* Isochronous endpoint */ +# define UDPHSEP_CFG_TYPE_BULK (2 << UDPHSEP_CFG_TYPE_SHIFT) /* Bulk endpoint */ +# define UDPHSEP_CFG_TYPE_INTR (3 << UDPHSEP_CFG_TYPE_SHIFT) /* Interrupt endpoint */ +#define UDPHSEP_CFG_BKNUMBER_SHIFT (6) /* Bits 6-7: Number of Banks */ +#define UDPHSEP_CFG_BKNUMBER_MASK (3 << UDPHSEP_CFG_BKNUMBER_SHIFT) +# define UDPHSEP_CFG_BKNUMBER_0BANK (0 << UDPHSEP_CFG_BKNUMBER_SHIFT) /* Zero bank (unmapped) */ +# define UDPHSEP_CFG_BKNUMBER_1BANK (1 << UDPHSEP_CFG_BKNUMBER_SHIFT) /* One bank (bank 0) */ +# define UDPHSEP_CFG_BKNUMBER_2BANK (2 << UDPHSEP_CFG_BKNUMBER_SHIFT) /* Double bank (bank 0-1) */ +# define UDPHSEP_CFG_BKNUMBER_3BANK (3 << UDPHSEP_CFG_BKNUMBER_SHIFT) /* Triple bank (bank 0-2) */ +#define UDPHSEP_CFG_NBTRANS_SHIFT (8) /* Bits 8-9: Number Of Transaction per Microframe */ +#define UDPHSEP_CFG_NBTRANS_MASK (3 << UDPHSEP_CFG_NBTRANS_SHIFT) +#define UDPHSEP_CFG_MAPD (1 << 31) /*Bit 31: Endpoint Mapped */ + +/* UDPHS Endpoint Control Enable Register, UDPHS Endpoint Control Disable Register, + * and UDPHS Endpoint Control Register common bit-field definitions + */ + +#define UDPHSEP_INT_EPT (1 << 0) /* Bit 0: Endpoint Enable/Disable */ +#define UDPHSEP_INT_AUTOVALID (1 << 1) /* Bit 1: Packet Auto-Valid */ +#define UDPHSEP_INT_INTDISDMA (1 << 3) /* Bit 3: Interrupts Disable DMA */ +#define UDPHSEP_INT_NYETDIS (1 << 4) /* Bit 4: NYET Disable (HS Bulk OUT EPs) */ +#define UDPHSEP_INT_DATAXRX (1 << 6) /* Bit 6: DATAx Interrupt Enable (High B/W Isoc OUT EPs) */ +#define UDPHSEP_INT_MDATARX (1 << 7) /* Bit 7: MDATA Interrupt Enable (High B/W Isoc OUT EPs) */ +#define UDPHSEP_INT_ERROVFLW (1 << 8) /* Bit 8: Overflow Error Interrupt */ +#define UDPHSEP_INT_RXBKRDY (1 << 9) /* Bit 9: Received OUT Data Interrupt */ +#define UDPHSEP_INT_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete Interrupt */ +#define UDPHSEP_INT_TXPKRDY (1 << 11) /* Bit 11: TX Packet Ready Interrupt */ +#define UDPHSEP_INT_ERRTRANS (1 << 11) /* Bit 11: Transaction Error Interrupt */ +#define UDPHSEP_INT_RXSETUP (1 << 12) /* Bit 12: Received SETUP Interrupt */ +#define UDPHSEP_INT_ERRFLISO (1 << 12) /* Bit 12: Error Flow Interrupt */ +#define UDPHSEP_INT_STALLSNT (1 << 13) /* Bit 13: Stall Sent Interrupt */ +#define UDPHSEP_INT_ERRCRISO (1 << 13) /* Bit 13: ISO CRC Error Error Interrupt */ +#define UDPHSEP_INT_ERRNBTRA (1 << 13) /* Bit 13: Number of Transaction Error Interrupt */ +#define UDPHSEP_INT_NAKIN (1 << 14) /* Bit 14: NAKIN Interrupt */ +#define UDPHSEP_INT_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error Interrupt */ +#define UDPHSEP_INT_NAKOUT (1 << 15) /* Bit 15: NAKOUT Interrupt */ +#define UDPHSEP_INT_BUSYBANK (1 << 18) /* Bit 18: Busy Bank Interrupt */ +#define UDPHSEP_INT_SHRTPCKT (1 << 31) /* Bit 31: Short Packet Send/Short Packet Interrupt */ + +/* UDPHS Endpoint Set Status Register */ + +#define UDPHSEP_SETSTA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request Set */ +#define UDPHSEP_SETSTA_KILLBANK (1 << 9) /* Bit 9: KILL Bank Set (for IN Endpoint) */ +#define UDPHSEP_SETSTA_TXPKRDY (1 << 11) /* Bit 11: TX Packet Ready Set */ + +/* UDPHS Endpoint Clear Status Register */ + +#define UDPHSEP_CLRSTA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request Clear */ +#define UDPHSEP_CLRSTA_TOGGLESQ (1 << 6) /* Bit 6: Data Toggle Clear */ +#define UDPHSEP_CLRSTA_RXBKRDY (1 << 9) /* Bit 9: Received OUT Data Clear */ +#define UDPHSEP_CLRSTA_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete Clear */ +#define UDPHSEP_CLRSTA_RXSETUP (1 << 12) /* Bit 12: Received SETUP Clear */ +#define UDPHSEP_CLRSTA_ERRFLISO (1 << 12) /* Bit 12: Error Flow Clear */ +#define UDPHSEP_CLRSTA_STALL_NT (1 << 13) /* Bit 13: Stall Sent Clear */ +#define UDPHSEP_CLRSTA_ERRNBTRA (1 << 13) /* Bit 13: Number of Transaction Error Clear */ +#define UDPHSEP_CLRSTA_NAKIN (1 << 14) /* Bit 14: NAKIN Clear */ +#define UDPHSEP_CLRSTA_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error Clear */ +#define UDPHSEP_CLRSTA_NAKOUT (1 << 15) /* Bit 15: NAKOUT Clear */ + +/* UDPHS Endpoint Status Register */ + +#define UDPHSEP_STA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request */ +#define UDPHSEP_STA_TOGGLESQSTA_SHIFT (6) /* Bits 6-7: Toggle Sequencing */ +#define UDPHSEP_STA_TOGGLESQSTA_MASK (3 << UDPHSEP_STA_TOGGLESQSTA_SHIFT) +# define UDPHSEP_STA_TOGGLESQSTA_DATA0 (0 << UDPHSEP_STA_TOGGLESQSTA_SHIFT) /* Data0 */ +# define UDPHSEP_STA_TOGGLESQSTA_DATA1 (1 << UDPHSEP_STA_TOGGLESQSTA_SHIFT) /* Data1 */ +# define UDPHSEP_STA_TOGGLESQSTA_DATA2 (2 << UDPHSEP_STA_TOGGLESQSTA_SHIFT) /* Data2 (High B/W Isoc EP) */ +# define UDPHSEP_STA_TOGGLESQSTA_MDATA (3 << UDPHSEP_STA_TOGGLESQSTA_SHIFT) /* MData (High B/W Isoc EP) */ +#define UDPHSEP_STA_ERROVFLW (1 << 8) /* Bit 8: Overflow Error */ +#define UDPHSEP_STA_RXBKRDY (1 << 9) /* Bit 9: Received OUT Data */ +#define UDPHSEP_STA_KILLBANK (1 << 9) /* Bit 9: KILL Bank */ +#define UDPHSEP_STA_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete */ +#define UDPHSEP_STA_TXPKRDY (1 << 11) /* Bit 11: TX Packet Ready */ +#define UDPHSEP_STA_ERRTRANS (1 << 11) /* Bit 11: Transaction Error */ +#define UDPHSEP_STA_RXSETUP (1 << 12) /* Bit 12: Received SETUP */ +#define UDPHSEP_STA_ERRFLISO (1 << 12) /* Bit 12: Error Flow */ +#define UDPHSEP_STA_STALLSNT (1 << 13) /* Bit 13: Stall Sent */ +#define UDPHSEP_STA_ERRCRISO (1 << 13) /* Bit 13: CRC ISO Error */ +#define UDPHSEP_STA_ERRNBTRA (1 << 13) /* Bit 13: Number of Transaction Error */ +#define UDPHSEP_STA_NAKIN (1 << 14) /* Bit 14: NAK IN */ +#define UDPHSEP_STA_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error */ +#define UDPHSEP_STA_NAKOUT (1 << 15) /* Bit 15: NAK OUT */ +#define UDPHSEP_STA_CURRENTBANK_SHIFT (16) /* Bits 16-17: Current Bank */ +#define UDPHSEP_STA_CURRENTBANK_MASK (3 << UDPHSEP_STA_CURRENTBANK_MASK) +#define UDPHSEP_STA_CONTROLDIR_SHIFT (16) /* Bits 16-17: Control Direction */ +#define UDPHSEP_STA_CONTROLDIR_MASK (3 << UDPHSEP_STA_CONTROLDIR_SHIFT) +#define UDPHSEP_STA_BUSYBANKSTA_SHIFT (18) /* Bits 18-19: Busy Bank Number */ +#define UDPHSEP_STA_BUSYBANKSTA_MASK (3 << UDPHSEP_STA_BUSYBANKSTA_SHIFT) +#define UDPHSEP_STA_BYTECOUNT_SHIFT (20) /* Bits 20-23: UDPHS Byte Count */ +#define UDPHSEP_STA_BYTECOUNT_MASK (15 << UDPHSEP_STA_BYTECOUNT_SHIFT) +#define UDPHSEP_STA_SHRTPCKT (1 << 31) /* Bit 31: Short Packet */ + +/* UDPHS DMA Channel Control Register */ + +#define UDPHSDMA_CONTROL_CHANNENB (1 << 0) /* Bit 0: Channel Enable Command */ +#define UDPHSDMA_CONTROL_LDNXTDSC (1 << 1) /* Bit 1: Load Next Channel Xfr Desc Enable (Command) */ +#define UDPHSDMA_CONTROL_ENDTREN (1 << 2) /* Bit 2: End of Transfer Enable (Control) */ +#define UDPHSDMA_CONTROL_ENDBEN (1 << 3) /* Bit 3: End of Buffer Enable (Control) */ +#define UDPHSDMA_CONTROL_ENDTRIT (1 << 4) /* Bit 4: End of Transfer Interrupt Enable */ +#define UDPHSDMA_CONTROL_ENDBUFFIT (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define UDPHSDMA_CONTROL_DESCLDIT (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enab */ +#define UDPHSDMA_CONTROL_BURSTLCK (1 << 7) /* Bit 7: Burst Lock Ena */ +#define UDPHSDMA_CONTROL_BUFFLENGTH_SHIFT (16) /* Bits 16-31: Buffer Byte Length (Write-only) */ +#define UDPHSDMA_CONTROL_BUFFLENGTH_MASK (0xffff << UDPHSDMA_CONTROL_BUFFLENGTH_SHIFT) + +/* UDPHS DMA Channel Status Register */ + +#define UDPHSDMA_STATUS_CHANNENB (1 << 0) /* Bit 0: Channel Enable Status */ +#define UDPHSDMA_STATUS_CHANNACT (1 << 1) /* Bit 1: Channel Active Status */ +#define UDPHSDMA_STATUS_ENDTRST (1 << 4) /* Bit 4: End of Channel Transfer Status */ +#define UDPHSDMA_STATUS_ENDBFST (1 << 5) /* Bit 5: End of Channel Buffer Status */ +#define UDPHSDMA_STATUS_DESCLDST (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define UDPHSDMA_STATUS_BUFFCOUNT_SHIFT (16) /* Bits 16-31: Buffer Byte Count */ +#define UDPHSDMA_STATUS_BUFFCOUNT_MASK (0xffff << UDPHSDMA_STATUS_BUFFCOUNT_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_UDPHS_H */ + diff --git a/arch/arm/src/sam34/chip/sam_wdt.h b/arch/arm/src/sam34/chip/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..b2dd810b9d93cc60f3f5ed5205678331896c102d --- /dev/null +++ b/arch/arm/src/sam34/chip/sam_wdt.h @@ -0,0 +1,107 @@ +/**************************************************************************************** + * arch/arm/src/sam34/chip/sam_wdt.h + * Watchdog Timer (WDT) definitions for the SAM3U, SAM3X, SAM3A, SAM4E, and SAM4S + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM_WDT_H +#define __ARCH_ARM_SRC_SAM34_CHIP_SAM_WDT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* WDT register offsets *****************************************************************/ + +#define SAM_WDT_CR_OFFSET 0x00 /* Control Register */ +#define SAM_WDT_MR_OFFSET 0x04 /* Mode Register */ +#define SAM_WDT_SR_OFFSET 0x08 /* Status Register */ + +/* WDT register addresses ***************************************************************/ + +#define SAM_WDT_CR (SAM_WDT_BASE+SAM_WDT_CR_OFFSET) +#define SAM_WDT_MR (SAM_WDT_BASE+SAM_WDT_MR_OFFSET) +#define SAM_WDT_SR (SAM_WDT_BASE+SAM_WDT_SR_OFFSET) + +/* WDT register bit definitions *********************************************************/ +/* Watchdog Timer Control Register */ + +#define WDT_CR_WDRSTT (1 << 0) /* Bit 0: Watchdog Rest */ +#define WDT_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define WDT_CR_KEY_MASK (0xff << WDT_CR_KEY_SHIFT) +# define WDT_CR_KEY (0xa5 << WDT_CR_KEY_SHIFT) + +/* Watchdog Timer Mode Register */ + +#define WDT_MR_WDV_SHIFT (0) /* Bits 0-11: Watchdog Counter Value */ +#define WDT_MR_WDV_MAX 0xfff +#define WDT_MR_WDV_MASK (WDT_MR_WDV_MAX << WDT_MR_WDV_SHIFT) +# define WDT_MR_WDV(n) ((uint32_t)(n) << WDT_MR_WDV_SHIFT) +#define WDT_MR_WDFIEN (1 << 12) /* Bit 12: Watchdog Fault Interrupt Enable */ +#define WDT_MR_WDRSTEN (1 << 13) /* Bit 13: Watchdog Reset Enable */ +#define WDT_MR_WDRPROC (1 << 14) /* Bit 14: Watchdog Reset Processor */ +#define WDT_MR_WDDIS (1 << 15) /* Bit 15: Watchdog Disable */ +#define WDT_MR_WDD_SHIFT (16) /* Bits 16-27: Watchdog Delta Value */ +#define WDT_MR_WDD_MAX 0xfff +#define WDT_MR_WDD_MASK (WDT_MR_WDD_MAX << WDT_MR_WDD_SHIFT) +# define WDT_MR_WDD(n) ((uint32_t)(n) << WDT_MR_WDD_SHIFT) +#define WDT_MR_WDDBGHLT (1 << 28) /* Bit 28: Watchdog Debug Halt */ +#define WDT_MR_WDIDLEHLT (1 << 29) /* Bit 29: Watchdog Idle Halt */ + +/* Watchdog Timer Status Register */ + +#define WDT_SR_WDUNF (1 << 0) /* Bit 0: Watchdog Underflow */ +#define WDT_SR_WDERR (1 << 1) /* Bit 1: Watchdog Error */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM_WDT_H */ diff --git a/arch/arm/src/sam34/sam3u_gpio.h b/arch/arm/src/sam34/sam3u_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..6d31b3087f8ee6b7aa0b2d11e3530d044bbde408 --- /dev/null +++ b/arch/arm/src/sam34/sam3u_gpio.h @@ -0,0 +1,202 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam3u_gpio.h + * General Purpose Input/Output (GPIO) definitions for the SAM3U + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM3U_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM3U_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#undef GPIO_HAVE_PULLDOWN +#undef GPIO_HAVE_PERIPHCD +#undef GPIO_HAVE_SCHMITT +#undef GPIO_HAVE_DELAYR + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 16-bit Encoding: + * + * MMCC CIII VPPB BBBB + */ + +/* Input/Output mode: + * + * MM.. .... .... .... + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: GPIO mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Output */ +# define GPIO_PERIPHA (2 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (3 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ + +/* These bits set the configuration of the pin: + * + * ..CC C... .... .... + */ + +#define GPIO_CFG_SHIFT (11) /* Bits 11-13: GPIO configuration bits */ +#define GPIO_CFG_MASK (7 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_DEGLITCH (2 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (4 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ + +/* Additional interrupt modes: + * + * .... .III .... .... + */ + +#define GPIO_INT_SHIFT (8) /* Bits 8-10: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... V... .... + */ + +#define GPIO_OUTPUT_SET (1 << 7) /* Bit 7: Inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * .... .... .PP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 16-bit encoding */ + +typedef uint16_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM3U_GPIO_H */ diff --git a/arch/arm/src/sam34/sam3u_periphclks.h b/arch/arm/src/sam34/sam3u_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..145ebe4ac4812a5a4ce459d57fa53c7ece0ec7d2 --- /dev/null +++ b/arch/arm/src/sam34/sam3u_periphclks.h @@ -0,0 +1,149 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam3u_periphclks.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM3U_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM3U_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperipheral(s) putreg32((1 << (s)), SAM_PMC_PCER) +#define sam_disableperipheral(s) putreg32((1 << (s)), SAM_PMC_PCDR) + +#define sam_supc_enableclk() sam_enableperipheral(SAM_PID_SUPC) +#define sam_rstc_enableclk() sam_enableperipheral(SAM_PID_RSTC) +#define sam_rtc_enableclk() sam_enableperipheral(SAM_PID_RTC) +#define sam_rtt_enableclk() sam_enableperipheral(SAM_PID_RTT) +#define sam_wdt_enableclk() sam_enableperipheral(SAM_PID_WDT) +#define sam_pmc_enableclk() sam_enableperipheral(SAM_PID_PMC) +#define sam_eefc0_enableclk() sam_enableperipheral(SAM_PID_EEFC0) +#define sam_eefc1_enableclk() sam_enableperipheral(SAM_PID_EEFC1) +#define sam_uart0_enableclk() sam_enableperipheral(SAM_PID_UART0) +#define sam_smc_enableclk() sam_enableperipheral(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperipheral(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperipheral(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperipheral(SAM_PID_PIOC) +#define sam_usart0_enableclk() sam_enableperipheral(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperipheral(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperipheral(SAM_PID_USART2) +#define sam_usart3_enableclk() sam_enableperipheral(SAM_PID_USART3) +#define sam_hsmci_enableclk() sam_enableperipheral(SAM_PID_HSMCI) +#define sam_twi0_enableclk() sam_enableperipheral(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperipheral(SAM_PID_TWI1) +#define sam_spi0_enableclk() sam_enableperipheral(SAM_PID_SPI0) +#define sam_ssc_enableclk() sam_enableperipheral(SAM_PID_SSC) +#define sam_tc0_enableclk() sam_enableperipheral(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperipheral(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperipheral(SAM_PID_TC2) +#define sam_pwm_enableclk() sam_enableperipheral(SAM_PID_PWM) +#define sam_adc12b_enableclk() sam_enableperipheral(SAM_PID_ADC12B) +#define sam_dmac_enableclk() sam_enableperipheral(SAM_PID_DMAC) +#define sam_udphs_enableclk() sam_enableperipheral(SAM_PID_UDPHS) + +#define sam_supc_disableclk() sam_disableperipheral(SAM_PID_SUPC) +#define sam_rstc_disableclk() sam_disableperipheral(SAM_PID_RSTC) +#define sam_rtc_disableclk() sam_disableperipheral(SAM_PID_RTC) +#define sam_rtt_disableclk() sam_disableperipheral(SAM_PID_RTT) +#define sam_wdt_disableclk() sam_disableperipheral(SAM_PID_WDT) +#define sam_pmc_disableclk() sam_disableperipheral(SAM_PID_PMC) +#define sam_eefc0_disableclk() sam_disableperipheral(SAM_PID_EEFC0) +#define sam_eefc1_disableclk() sam_disableperipheral(SAM_PID_EEFC1) +#define sam_uart0_disableclk() sam_disableperipheral(SAM_PID_UART0) +#define sam_smc_disableclk() sam_disableperipheral(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperipheral(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperipheral(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperipheral(SAM_PID_PIOC) +#define sam_usart0_disableclk() sam_disableperipheral(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperipheral(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperipheral(SAM_PID_USART2) +#define sam_usart3_disableclk() sam_disableperipheral(SAM_PID_USART3) +#define sam_hsmci_disableclk() sam_disableperipheral(SAM_PID_HSMCI) +#define sam_twi0_disableclk() sam_disableperipheral(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperipheral(SAM_PID_TWI1) +#define sam_spi0_disableclk() sam_disableperipheral(SAM_PID_SPI0) +#define sam_ssc_disableclk() sam_disableperipheral(SAM_PID_SSC) +#define sam_tc0_disableclk() sam_disableperipheral(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperipheral(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperipheral(SAM_PID_TC2) +#define sam_pwm_disableclk() sam_disableperipheral(SAM_PID_PWM) +#define sam_adc12b_disableclk() sam_disableperipheral(SAM_PID_ADC12B) +#define sam_dmac_disableclk() sam_disableperipheral(SAM_PID_DMAC) +#define sam_udphs_disableclk() sam_disableperipheral(SAM_PID_UDPHS) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM3U_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam3x_gpio.h b/arch/arm/src/sam34/sam3x_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..0519f2c8091bcc9fc2c250752953e01becf16e04 --- /dev/null +++ b/arch/arm/src/sam34/sam3x_gpio.h @@ -0,0 +1,205 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam3x_gpio.h + * General Purpose Input/Output (GPIO) definitions for the SAM3X + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM3X_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM3X_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#undef GPIO_HAVE_PULLDOWN +#undef GPIO_HAVE_PERIPHCD +#undef GPIO_HAVE_SCHMITT +#undef GPIO_HAVE_DELAYR + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 32-bit Encoding: + * + * ..MM .CCC IIIV PPPB BBBB + */ + +/* Input/Output mode: + * + * ..MM .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (16) /* Bits 16-17: GPIO mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Output */ +# define GPIO_PERIPHA (2 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (3 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ + +/* These bits set the configuration of the pin: + * + * .... .CCC .... .... .... + */ + +#define GPIO_CFG_SHIFT (12) /* Bits 12-14: GPIO configuration bits */ +#define GPIO_CFG_MASK (7 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_DEGLITCH (2 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (4 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ + +/* Additional interrupt modes: + * + * .... .... III. .... .... + */ + +#define GPIO_INT_SHIFT (9) /* Bits 9-11: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: Inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * .... .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOE (4 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOF (5 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM3X_GPIO_H */ diff --git a/arch/arm/src/sam34/sam3x_periphclks.h b/arch/arm/src/sam34/sam3x_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..f20a86a0e8de741bcac11ab0483548a1d9f06cc5 --- /dev/null +++ b/arch/arm/src/sam34/sam3x_periphclks.h @@ -0,0 +1,183 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam3x_periphclks.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM3X_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM3X_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() sam_enableperiph0(SAM_PID_SUPC) +#define sam_rstc_enableclk() sam_enableperiph0(SAM_PID_RSTC) +#define sam_rtc_enableclk() sam_enableperiph0(SAM_PID_RTC) +#define sam_rtt_enableclk() sam_enableperiph0(SAM_PID_RTT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_pmc_enableclk() sam_enableperiph0(SAM_PID_PMC) +#define sam_eefc0_enableclk() sam_enableperiph0(SAM_PID_EEFC0) +#define sam_eefc1_enableclk() sam_enableperiph0(SAM_PID_EEFC1) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_sdramc_enableclk() sam_enableperiph0(SAM_PID_SDRAMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_piof_enableclk() sam_enableperiph0(SAM_PID_PIOF) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_usart3_enableclk() sam_enableperiph0(SAM_PID_USART3) +#define sam_hsmci_enableclk() sam_enableperiph0(SAM_PID_HSMCI) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_spi1_enableclk() sam_enableperiph0(SAM_PID_SPI1) +#define sam_ssc_enableclk() sam_enableperiph0(SAM_PID_SSC) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph1(SAM_PID_TC5) +#define sam_tc6_enableclk() sam_enableperiph1(SAM_PID_TC6) +#define sam_tc7_enableclk() sam_enableperiph1(SAM_PID_TC7) +#define sam_tc8_enableclk() sam_enableperiph1(SAM_PID_TC8) +#define sam_pwm_enableclk() sam_enableperiph1(SAM_PID_PWM) +#define sam_adc_enableclk() sam_enableperiph1(SAM_PID_ADC) +#define sam_dacc_enableclk() sam_enableperiph1(SAM_PID_DACC) +#define sam_dmac_enableclk() sam_enableperiph1(SAM_PID_DMAC) +#define sam_uotghs_enableclk() sam_enableperiph1(SAM_PID_UOTGHS) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_emac_enableclk() sam_enableperiph1(SAM_PID_EMAC) +#define sam_can0_enableclk() sam_enableperiph1(SAM_PID_CAN0) +#define sam_can1_enableclk() sam_enableperiph1(SAM_PID_CAN1) + +#define sam_supc_disableclk() sam_disableperiph0(SAM_PID_SUPC) +#define sam_rstc_disableclk() sam_disableperiph0(SAM_PID_RSTC) +#define sam_rtc_disableclk() sam_disableperiph0(SAM_PID_RTC) +#define sam_rtt_disableclk() sam_disableperiph0(SAM_PID_RTT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_pmc_disableclk() sam_disableperiph0(SAM_PID_PMC) +#define sam_eefc0_disableclk() sam_disableperiph0(SAM_PID_EEFC0) +#define sam_eefc1_disableclk() sam_disableperiph0(SAM_PID_EEFC1) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_sdramc_disableclk() sam_disableperiph0(SAM_PID_SDRAMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_piof_disableclk() sam_disableperiph0(SAM_PID_PIOF) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_usart3_disableclk() sam_disableperiph0(SAM_PID_USART3) +#define sam_hsmci_disableclk() sam_disableperiph0(SAM_PID_HSMCI) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_spi1_disableclk() sam_disableperiph0(SAM_PID_SPI1) +#define sam_ssc_disableclk() sam_disableperiph0(SAM_PID_SSC) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph1(SAM_PID_TC5) +#define sam_tc6_disableclk() sam_disableperiph1(SAM_PID_TC6) +#define sam_tc7_disableclk() sam_disableperiph1(SAM_PID_TC7) +#define sam_tc8_disableclk() sam_disableperiph1(SAM_PID_TC8) +#define sam_pwm_disableclk() sam_disableperiph1(SAM_PID_PWM) +#define sam_adc_disableclk() sam_disableperiph1(SAM_PID_ADC) +#define sam_dacc_disableclk() sam_disableperiph1(SAM_PID_DACC) +#define sam_dmac_disableclk() sam_disableperiph1(SAM_PID_DMAC) +#define sam_uotghs_disableclk() sam_disableperiph1(SAM_PID_UOTGHS) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_emac_disableclk() sam_disableperiph1(SAM_PID_EMAC) +#define sam_can0_disableclk() sam_disableperiph1(SAM_PID_CAN0) +#define sam_can1_disableclk() sam_disableperiph1(SAM_PID_CAN1) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM3X_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam4cm_freerun.c b/arch/arm/src/sam34/sam4cm_freerun.c new file mode 100644 index 0000000000000000000000000000000000000000..63bcea20315f4e43701f461926d6a376ee1f2bc0 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_freerun.c @@ -0,0 +1,319 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_freerun.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam4cm_freerun.h" + +#ifdef CONFIG_SAM34_ONESHOT + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_freerun_handler + * + * Description: + * Timer interrupt callback. When the freerun timer counter overflows, + * this interrupt will occur. We will just increment an overflow count. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_freerun_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_freerun_s *freerun = (struct sam_freerun_s *)arg; + DEBUGASSERT(freerun && freerun->overflow < UINT32_MAX); + freerun->overflow++; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sam34/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t divisor; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(freerun && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_divisor(frequency, &divisor, &cmr); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_divisor failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, divisor=%u, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)divisor, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * CMR_TCCLKS - Returned by sam_tc_divisor + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=0 - Don't stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UP - TC_CV is incremented from 0 to 0xffffffff + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NOTGATED | TC_CMR_EEVTEDG_NONE | TC_CMR_EEVT_TIOB | + TC_CMR_WAVSEL_UP | TC_CMR_WAVE | TC_CMR_ACPA_NONE | + TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | TC_CMR_ASWTRG_NONE | + TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | TC_CMR_BEEVT_NONE | + TC_CMR_BSWTRG_NONE); + + freerun->tch = sam_tc_allocate(chan, cmr); + if (!freerun->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + freerun->chan = chan; + freerun->running = false; + freerun->overflow = 0; + + /* Set up to receive the callback when the counter overflow occurs */ + + (void)sam_tc_attach(freerun->tch, sam_freerun_handler, freerun, + TC_INT_COVFS); + + /* Start the counter */ + + sam_tc_start(freerun->tch); + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time from the free-running + * timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts) +{ + uint64_t usec; + uint32_t counter; + uint32_t verify; + uint32_t sr; + uint32_t overflow; + uint32_t sec; + irqstate_t flags; + + DEBUGASSERT(freerun && freerun->tch && ts); + + /* Temporarily disable the overflow counter. NOTE that we have to be careful + * here because sam_tc_getpending() will reset the pending interrupt status. + * If we do not handle the overflow here then, it will be lost. + */ + + flags = enter_critical_section(); + overflow = freerun->overflow; + counter = sam_tc_getcounter(freerun->tch); + sr = sam_tc_getpending(freerun->tch); + verify = sam_tc_getcounter(freerun->tch); + + /* If an interrupt was pending before we re-enabled interrupts, + * then the overflow needs to be incremented. + */ + + if ((sr & TC_INT_COVFS) != 0) + { + /* Increment the overflow count and use the value of the + * guaranteed to be AFTER the overflow occurred. + */ + + overflow++; + counter = verify; + + /* Update freerun overflow counter. */ + + freerun->overflow = overflow; + } + + leave_critical_section(flags); + + tcvdbg("counter=%lu (%lu) overflow=%lu, sr=%08lx\n", + (unsigned long)counter, (unsigned long)verify, + (unsigned long)overflow, (unsigned long)sr); + + /* Convert the whole thing to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = ((((uint64_t)overflow << 16) + (uint64_t)counter) * USEC_PER_SEC) / + sam_tc_divfreq(freerun->tch); + + /* And return the value of the timer */ + + sec = (uint32_t)(usec / USEC_PER_SEC); + ts->tv_sec = sec; + ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + tcvdbg("usec=%llu ts=(%lu, %lu)\n", + usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun) +{ + DEBUGASSERT(freerun && freerun->tch); + + /* Now we can disable the timer interrupt and disable the timer. */ + + sam_tc_attach(freerun->tch, NULL, NULL, 0); + sam_tc_stop(freerun->tch); + + /* Free the timer */ + + sam_tc_free(freerun->tch); + freerun->tch = NULL; + return OK; +} + +#endif /* CONFIG_SAM34_ONESHOT */ diff --git a/arch/arm/src/sam34/sam4cm_freerun.h b/arch/arm/src/sam34/sam4cm_freerun.h new file mode 100644 index 0000000000000000000000000000000000000000..e9266c2195f21e33d42f942470619182f6b02ed3 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_freerun.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_freerun.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_FREERUN_H +#define __ARCH_ARM_SRC_SAM34_SAM_FREERUN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam4cm_tc.h" + +#ifdef CONFIG_SAM34_FREERUN + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FREERUN_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The freerun client must allocate an instance of this structure and called + * sam_freerun_initialize() before using the freerun facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_freerun_s +{ + uint8_t chan; /* The timer/counter in use */ + bool running; /* True: the timer is running */ + uint32_t overflow; /* Timer counter overflow */ + TC_HANDLE tch; /* Handle returned by sam_tc_initialize() */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution); + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts); + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAM34_FREERUN */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_FREERUN_H */ diff --git a/arch/arm/src/sam34/sam4cm_gpio.h b/arch/arm/src/sam34/sam4cm_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..b103e6d7044e236924702d46177f21fcaef4c15e --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_gpio.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4cm_gpio.h + * General Purpose Input/Output (GPIO) definitions for the SAM4CM + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4CM_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM4CM_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#define GPIO_HAVE_PULLDOWN 1 +#define GPIO_HAVE_PERIPHCD 1 +#define GPIO_HAVE_SCHMITT 1 +#undef GPIO_HAVE_DELAYR + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 32-bit Encoding: + * + * MMMC CCCC III. VPPB BBBB + */ + +/* Input/Output mode: + * + * MMM. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (17) /* Bits 17-19: GPIO mode */ +#define GPIO_MODE_MASK (7 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Output */ +# define GPIO_PERIPHA (2 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (3 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define GPIO_PERIPHC (4 << GPIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define GPIO_PERIPHD (5 << GPIO_MODE_SHIFT) /* Controlled by periph D signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * ...C CCCC .... .... .... + */ + +#define GPIO_CFG_SHIFT (12) /* Bits 12-16: GPIO configuration bits */ +#define GPIO_CFG_MASK (31 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_PULLDOWN (2 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-down */ +# define GPIO_CFG_DEGLITCH (4 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (8 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ +# define GPIO_CFG_SCHMITT (16 << GPIO_CFG_SHIFT) /* Bit 13: Schmitt trigger */ + +/* Additional interrupt modes: + * + * .... .... III. .... .... + */ + +#define GPIO_INT_SHIFT (9) /* Bits 9-11: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... .... V... .... + */ + +#define GPIO_OUTPUT_SET (1 << 7) /* Bit 7: Initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * .... .... .... .PP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4S_GPIO_H */ diff --git a/arch/arm/src/sam34/sam4cm_oneshot.c b/arch/arm/src/sam34/sam4cm_oneshot.c new file mode 100644 index 0000000000000000000000000000000000000000..a793350d66cc387057cfc4e7164f152fb1be0da4 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_oneshot.c @@ -0,0 +1,448 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam4cm_oneshot.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam4cm_oneshot.h" + +#ifdef CONFIG_SAM34_ONESHOT + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Timer interrupt callback. When the oneshot timer interrupt expires, + * this function will be called. It will forward the call to the next + * level up. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_oneshot_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_oneshot_s *oneshot = (struct sam_oneshot_s *)arg; + oneshot_handler_t oneshot_handler; + void *oneshot_arg; + + tcllvdbg("Expired...\n"); + DEBUGASSERT(oneshot && oneshot->handler); + + /* The clock was stopped, but not disabled when the RC match occurred. + * Disable the TC now and disable any further interrupts. + */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + /* The timer is no longer running */ + + oneshot->running = false; + + /* Forward the event, clearing out any vestiges */ + + oneshot_handler = (oneshot_handler_t)oneshot->handler; + oneshot->handler = NULL; + oneshot_arg = (void *)oneshot->arg; + oneshot->arg = NULL; + + oneshot_handler(oneshot_arg); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sam34/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t divisor; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(oneshot && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_divisor(frequency, &divisor, &cmr); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_divisor failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, divisor=%lu, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)divisor, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * CMR_TCCLKS - Returned by sam_tc_divisor + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=1 - Stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UPRC - TC_CV is incremented from 0 to the value of RC, + * then automatically reset on a RC Compare + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NOTGATED | TC_CMR_CPCSTOP | TC_CMR_EEVTEDG_NONE | + TC_CMR_EEVT_TIOB | TC_CMR_WAVSEL_UPAUTO | TC_CMR_WAVE | + TC_CMR_ACPA_NONE | TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | + TC_CMR_ASWTRG_NONE | TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | + TC_CMR_BEEVT_NONE | TC_CMR_BSWTRG_NONE); + + oneshot->tch = sam_tc_allocate(chan, cmr); + if (!oneshot->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + oneshot->chan = chan; + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_max_delay + * + * Description: + * Determine the maximum delay of the one-shot timer (in microseconds) + * + ****************************************************************************/ + +int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec) +{ + DEBUGASSERT(oneshot && usec); + *usec = (0xffffull * USEC_PER_SEC) / (uint64_t)sam_tc_divfreq(oneshot->tch); + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts) +{ + uint64_t usec; + uint64_t regval; + irqstate_t flags; + + tcvdbg("handler=%p arg=%p, ts=(%lu, %lu)\n", + handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + DEBUGASSERT(oneshot && handler && ts); + + /* Was the oneshot already running? */ + + flags = enter_critical_section(); + if (oneshot->running) + { + /* Yes.. then cancel it */ + + tcvdbg("Already running... cancelling\n"); + (void)sam_oneshot_cancel(oneshot, NULL); + } + + /* Save the new handler and its argument */ + + oneshot->handler = handler; + oneshot->arg = arg; + + /* Express the delay in microseconds */ + + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); + + /* Get the timer counter frequency and determine the number of counts need to achieve the requested delay. + * + * frequency = ticks / second + * ticks = seconds * frequency + * = (usecs * frequency) / USEC_PER_SEC; + */ + + regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / USEC_PER_SEC; + + tcvdbg("usec=%llu regval=%08llx\n", usec, regval); + DEBUGASSERT(regval <= UINT16_MAX); + + /* Set up to receive the callback when the interrupt occurs */ + + (void)sam_tc_attach(oneshot->tch, sam_oneshot_handler, oneshot, + TC_INT_CPCS); + + /* Set RC so that an event will be triggered when TC_CV register counts + * up to RC. + */ + + sam_tc_setregister(oneshot->tch, TC_REGC, (uint32_t)regval); + + /* Start the counter */ + + sam_tc_start(oneshot->tch); + + /* Enable interrupts. We should get the callback when the interrupt + * occurs. + */ + + oneshot->running = true; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. ts may be zero in which case the time remaining + * is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts) +{ + irqstate_t flags; + uint64_t usec; + uint64_t sec; + uint64_t nsec; + uint32_t count; + uint32_t rc; + + /* Was the timer running? */ + + flags = enter_critical_section(); + if (!oneshot->running) + { + /* No.. Just return zero timer remaining and successful cancellation. + * This function may execute at a high rate with no timer running + * (as when pre-emption is enabled and disabled). + */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + leave_critical_section(flags); + return OK; + } + + /* Yes.. Get the timer counter and rc registers and stop the counter. If + * the counter expires while we are doing this, the counter clock will be + * stopped, but the clock will not be disabled. + * + * The expected behavior is that the the counter register will freezes at + * a value equal to the RC register when the timer expires. The counter + * should have values between 0 and RC in all other cased. + * + * REVISIT: This does not appear to be the case. + */ + + tcvdbg("Cancelling...\n"); + + count = sam_tc_getcounter(oneshot->tch); + rc = sam_tc_getregister(oneshot->tch, TC_REGC); + + /* Now we can disable the interrupt and stop the timer. */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + leave_critical_section(flags); + + /* Did the caller provide us with a location to return the time + * remaining? + */ + + if (ts) + { + /* Yes.. then calculate and return the time remaining on the + * oneshot timer. + */ + + tcvdbg("rc=%lu count=%lu usec=%lu\n", + (unsigned long)rc, (unsigned long)count, (unsigned long)usec); + + /* REVISIT: I am not certain why the timer counter value sometimes + * exceeds RC. Might be a bug, or perhaps the counter does not stop + * in all cases. + */ + + if (count >= rc) + { + /* No time remaining (?) */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + else + { + /* The total time remaining is the difference. Convert the that + * to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = (((uint64_t)(rc - count)) * USEC_PER_SEC) / + sam_tc_divfreq(oneshot->tch); + + /* Return the time remaining in the correct form */ + + sec = usec / USEC_PER_SEC; + nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + ts->tv_sec = (time_t)sec; + ts->tv_nsec = (unsigned long)nsec; + } + + tcvdbg("remaining (%lu, %lu)\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + } + + return OK; +} + +#endif /* CONFIG_SAM34_ONESHOT */ diff --git a/arch/arm/src/sam34/sam4cm_oneshot.h b/arch/arm/src/sam34/sam4cm_oneshot.h new file mode 100644 index 0000000000000000000000000000000000000000..3c3266b5db6bd711e01ed5d7c248fa8a71817f88 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_oneshot.h @@ -0,0 +1,184 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_oneshot.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_ONESHOT_H +#define __ARCH_ARM_SRC_SAM34_SAM_ONESHOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam4cm_tc.h" + +#ifdef CONFIG_SAM34_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ONESHOT_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the callback function that will be invoked when the oneshot + * timer expires. The oneshot fires, the client will receive: + * + * arg - The opaque argument provided when the interrupt was registered + */ + +typedef void (*oneshot_handler_t)(void *arg); + +/* The oneshot client must allocate an instance of this structure and called + * sam_oneshot_initialize() before using the oneshot facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_oneshot_s +{ + uint8_t chan; /* The timer/counter in use */ + volatile bool running; /* True: the timer is running */ + TC_HANDLE tch; /* Handle returned by + * sam_tc_initialize() */ + volatile oneshot_handler_t handler; /* Oneshot expiration callback */ + volatile void *arg; /* The argument that will accompany + * the callback */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution); + +int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec); + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts); + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAM34_ONESHOT */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_ONESHOT_H */ diff --git a/arch/arm/src/sam34/sam4cm_periphclks.h b/arch/arm/src/sam34/sam4cm_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..9584c891705b26aae87a3d423c803bfee810f7a9 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_periphclks.h @@ -0,0 +1,169 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4cm_periphclks.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4CM_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM4CM_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() sam_enableperiph0(SAM_PID_SUPC) +#define sam_rstc_enableclk() sam_enableperiph0(SAM_PID_RSTC) +#define sam_rtc_enableclk() sam_enableperiph0(SAM_PID_RTC) +#define sam_rtt_enableclk() sam_enableperiph0(SAM_PID_RTT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_pmc_enableclk() sam_enableperiph0(SAM_PID_PMC) +#define sam_eefc0_enableclk() sam_enableperiph0(SAM_PID_EEFC0) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_usart3_enableclk() sam_enableperiph0(SAM_PID_USART3) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph0(SAM_PID_TC5) +#define sam_adc_enableclk() sam_enableperiph0(SAM_PID_ADC) +#define sam_arm_enableclk() sam_enableperiph0(SAM_PID_ARM) +#define sam_ipc0_enableclk() sam_enableperiph0(SAM_PID_IPC0) +#define sam_slcdc_enableclk() sam_enableperiph1(SAM_PID_SLCDC) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_icm_enableclk() sam_enableperiph1(SAM_PID_ICM) +#define sam_cpkcc_enableclk() sam_enableperiph1(SAM_PID_CPKCC) +#define sam_aes_enableclk() sam_enableperiph1(SAM_PID_AES) +#define sam_pioc_enableclk() sam_enableperiph1(SAM_PID_PIOC) +#define sam_uart1_enableclk() sam_enableperiph1(SAM_PID_UART1) +#define sam_ipc1_enableclk() sam_enableperiph1(SAM_PID_IPC1) +#define sam_pwm_enableclk() sam_enableperiph1(SAM_PID_PWM) +#define sam_sram_enableclk() sam_enableperiph1(SAM_PID_SRAM) +#define sam_smc1_enableclk() sam_enableperiph1(SAM_PID_SMC1) + +#define sam_supc_disableclk() sam_disableperiph0(SAM_PID_SUPC) +#define sam_rstc_disableclk() sam_disableperiph0(SAM_PID_RSTC) +#define sam_rtc_disableclk() sam_disableperiph0(SAM_PID_RTC) +#define sam_rtt_disableclk() sam_disableperiph0(SAM_PID_RTT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_pmc_disableclk() sam_disableperiph0(SAM_PID_PMC) +#define sam_eefc0_disableclk() sam_disableperiph0(SAM_PID_EEFC0) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_usart3_disableclk() sam_disableperiph0(SAM_PID_USART3) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph0(SAM_PID_TC5) +#define sam_adc_disableclk() sam_disableperiph0(SAM_PID_ADC) +#define sam_arm_disableclk() sam_disableperiph0(SAM_PID_ARM) +#define sam_ipc0_disableclk() sam_disableperiph0(SAM_PID_IPC0) +#define sam_slcdc_disableclk() sam_disableperiph1(SAM_PID_SLCDC) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_icm_disableclk() sam_disableperiph1(SAM_PID_ICM) +#define sam_cpkcc_disableclk() sam_disableperiph1(SAM_PID_CPKCC) +#define sam_aes_disableclk() sam_disableperiph1(SAM_PID_AES) +#define sam_pioc_disableclk() sam_disableperiph1(SAM_PID_PIOC) +#define sam_uart1_disableclk() sam_disableperiph1(SAM_PID_UART1) +#define sam_ipc1_disableclk() sam_disableperiph1(SAM_PID_IPC1) +#define sam_pwm_disableclk() sam_disableperiph1(SAM_PID_PWM) +#define sam_sram_disableclk() sam_disableperiph1(SAM_PID_SRAM) +#define sam_smc1_disableclk() sam_disableperiph1(SAM_PID_SMC1) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4S_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam4cm_supc.c b/arch/arm/src/sam34/sam4cm_supc.c new file mode 100644 index 0000000000000000000000000000000000000000..468466b80fe6c4f58881e4d234b80e1f705f5ace --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_supc.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam4cm_supc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "chip/sam_supc.h" + +#include "sam4cm_supc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t supc_get_slcd_power_mode(void) +{ + return getreg32(SAM_SUPC_MR) & SUPC_MR_LCDMODE_MASK; +} + +void supc_set_slcd_power_mode(uint32_t mode) +{ + uint32_t regval = getreg32(SAM_SUPC_MR); + regval &= ~SUPC_MR_LCDMODE_MASK; + regval |= SUPC_MR_KEY | mode; + putreg32(regval, SAM_SUPC_MR); + + if (mode == SUPC_MR_LCDMODE_LCDOFF) + { + while (getreg32(SAM_SUPC_SR) & SUPC_SR_LCDS); + } + else + { + while (!(getreg32(SAM_SUPC_SR) & SUPC_SR_LCDS)); + } +} + +void supc_set_slcd_ldo_output(uint32_t vrout) +{ + uint32_t regval = getreg32(SAM_SUPC_MR); + regval &= ~SUPC_MR_LCDVROUT_MASK; + regval |= SUPC_MR_KEY | vrout; + putreg32(regval, SAM_SUPC_MR); +} diff --git a/arch/arm/src/sam34/sam4cm_supc.h b/arch/arm/src/sam34/sam4cm_supc.h new file mode 100644 index 0000000000000000000000000000000000000000..7554dc9c285d11c5f8a8515b2deecc5649cdde18 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_supc.h @@ -0,0 +1,84 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_rtc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4CM_SUPC_H +#define __ARCH_ARM_SRC_SAM34_SAM4CM_SUPC_H + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_CHIP_SAM4CM) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +uint32_t supc_get_slcd_power_mode(void); +void supc_set_slcd_power_mode(uint32_t mode); +void supc_set_slcd_ldo_output(uint32_t vrout); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM3U_SUPC_H */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4CM_SUPC_H */ diff --git a/arch/arm/src/sam34/sam4cm_tc.c b/arch/arm/src/sam34/sam4cm_tc.c new file mode 100644 index 0000000000000000000000000000000000000000..91ab9c3ca2e86957eb10d6108be31127a1e12b57 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_tc.c @@ -0,0 +1,1288 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_tc.c + * + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_periphclks.h" +#include "chip/sam_pinmap.h" +#include "chip/sam_pmc.h" +#include "sam_gpio.h" + +#include "sam4cm_tc.h" + +#if defined(CONFIG_SAM34_TC0) || defined(CONFIG_SAM34_TC1) || \ + defined(CONFIG_SAM34_TC2) || defined(CONFIG_SAM34_TC3) || \ + defined(CONFIG_SAM34_TC4) || defined(CONFIG_SAM34_TC5) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes the static configuration of a TC channel */ + +struct sam_chconfig_s +{ + uintptr_t base; /* Channel register base address */ + uint8_t pid; /* Peripheral ID number */ + uint8_t irq; /* Channel IRQ number */ + uint8_t chan; + gpio_pinset_t clkset; /* CLK input PIO configuration */ + gpio_pinset_t tioaset; /* Output A PIO configuration */ + gpio_pinset_t tiobset; /* Output B PIO configuration */ +}; + +/* This structure describes one timer counter channel */ + +struct sam_chan_s +{ + struct sam_tc_s *tc; /* Parent timer/counter */ + uintptr_t base; /* Channel register base address */ + uint8_t pid; /* Peripheral ID number */ + uint8_t irq; /* Channel IRQ number */ + tc_handler_t handler; /* Attached interrupt handler */ + void *arg; /* Interrupt handler argument */ + uint8_t chan; /* Channel number (0, 1, or 2 OR 3, 4, or 5) */ + sem_t exclsem; /* Assures mutually exclusive access to TC */ + bool initialized; /* True: channel data has been initialized */ + bool inuse; /* True: channel is in use */ + + /* Debug stuff */ + +#ifdef CONFIG_SAM34_TC_REGDEBUG + bool wr; /* True:Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_chan_s *chan); +#define sam_givesem(chan) (sem_post(&chan->exclsem)) + +#ifdef CONFIG_SAM34_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg); +static bool sam_checkreg(struct sam_chan_s *chan, bool wr, uint32_t regaddr, + uint32_t regval); +#else +# define sam_regdump(chan,msg) +# define sam_checkreg(chan,wr,regaddr,regval) (false) +#endif + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset); +static inline void sam_chan_putreg(struct sam_chan_s *chan, + unsigned int offset, uint32_t regval); + +/* Interrupt Handling *******************************************************/ + +static int sam_tc_interrupt(struct sam_chan_s *tc); +static int sam_raw_interrupt(int irq, void *context); + +/* Initialization ***********************************************************/ + +static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx); +static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx); +static inline struct sam_chan_s *sam_tc_initialize(int channel); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Static timer configuration */ + +static const struct sam_chconfig_s g_configs[] = +{ +#ifdef CONFIG_SAM34_TC0 + { + .chan = 0, + .base = SAM_TC0_BASE, + .pid = SAM_PID_TC0, + .irq = SAM_IRQ_TC0, +#ifdef CONFIG_SAM34_TC0_CLK + .clkset = PIO_TC0_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC0_TIOA + .tioaset = PIO_TC0_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC0_TIOB + .tiobset = PIO_TC0_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC0 */ + +#ifdef CONFIG_SAM34_TC1 + { + .chan = 1, + .base = SAM_TC1_BASE, + .pid = SAM_PID_TC1, + .irq = SAM_IRQ_TC1, +#ifdef CONFIG_SAM34_TC1_CLK + .clkset = PIO_TC1_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC1_TIOA + .tioaset = PIO_TC1_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC1_TIOB + .tiobset = PIO_TC1_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC1 */ + +#ifdef CONFIG_SAM34_TC2 + { + .chan = 2, + .base = SAM_TC2_BASE, + .pid = SAM_PID_TC2, + .irq = SAM_IRQ_TC2, +#ifdef CONFIG_SAM34_TC2_CLK + .clkset = PIO_TC2_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC2_TIOA + .tioaset = PIO_TC2_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC2_TIOB + .tiobset = PIO_TC2_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC2 */ + +#ifdef CONFIG_SAM34_TC3 + { + .chan = 3, + .base = SAM_TC3_BASE, + .pid = SAM_PID_TC3, + .irq = SAM_IRQ_TC3, +#ifdef CONFIG_SAM34_TC3_CLK + .clkset = PIO_TC3_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC3_TIOA + .tioaset = PIO_TC3_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC3_TIOB + .tiobset = PIO_TC3_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC3 */ + +#ifdef CONFIG_SAM34_TC4 + { + .chan = 4, + .base = SAM_TC4_BASE, + .pid = SAM_PID_TC4, + .irq = SAM_IRQ_TC4, +#ifdef CONFIG_SAM34_TC4_CLK + .clkset = PIO_TC4_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC4_TIOA + .tioaset = PIO_TC4_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC4_TIOB + .tiobset = PIO_TC4_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC4 */ + +#ifdef CONFIG_SAM34_TC5 + { + .chan = 5, + .base = SAM_TC5_BASE, + .pid = SAM_PID_TC5, + .irq = SAM_IRQ_TC5, +#ifdef CONFIG_SAM34_TC5_CLK + .clkset = PIO_TC5_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAM34_TC5_TIOA + .tioaset = PIO_TC5_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAM34_TC5_TIOB + .tiobset = PIO_TC5_IOB, +#else + .tiobset = 0, +#endif + }, +#endif /* CONFIG_SAM34_TC5 */ +}; + +#define ENABLED_CHANNELS (sizeof(g_configs)/sizeof(struct sam_chconfig_s)) + +static struct sam_chan_s g_channels[ENABLED_CHANNELS]; + +/* TC frequency data. This table provides the frequency for each selection of TCCLK */ + +#define TC_NDIVIDERS 4 +#define TC_NDIVOPTIONS 5 + +/* This is the list of divider values: divider = (1 << value) */ + +static const uint8_t g_log2divider[TC_NDIVIDERS] = +{ + 1, /* TIMER_CLOCK1 -> div2 */ + 3, /* TIMER_CLOCK2 -> div8 */ + 5, /* TIMER_CLOCK3 -> div32 */ + 7 /* TIMER_CLOCK4 -> div128 */ +}; + +/* TC register lookup used by sam_tc_setregister */ + +#define TC_NREGISTERS 3 + +static const uint8_t g_regoffset[TC_NREGISTERS] = +{ + SAM_TC_RA_OFFSET, /* Register A */ + SAM_TC_RB_OFFSET, /* Register B */ + SAM_TC_RC_OFFSET /* Register C */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_chan_s *chan) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&chan->exclsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_regdump + * + * Description: + * Dump all timer/counter channel and global registers + * + * Input Parameters: + * chan - The timer/counter channel state + * msg - Message to print with the data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg) +{ + uintptr_t base; + + base = chan->base; + lldbg("TC%d [%08x]: %s\n", chan->chan, (int)base, msg); + lldbg(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n", + getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET), + getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET)); + + base = chan->base; + lldbg("TC%d Channel %d [%08x]: %s\n", chan->chan, chan->chan, (int)base, msg); + lldbg(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n", + getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET), + getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET)); + lldbg(" RA: %08x RB: %08x RC: %08x SR: %08x\n", + getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET), + getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_SR_OFFSET)); + lldbg(" IMR: %08x\n", + getreg32(base+SAM_TC_IMR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * chan - The timer/counter peripheral state + * wr - True:write access false:read access + * regval - The register value associated with the access + * regaddr - The address of the register being accessed + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TC_REGDEBUG +static bool sam_checkreg(struct sam_chan_s *chan, bool wr, uint32_t regaddr, + uint32_t regval) +{ + if (wr == chan->wr && /* Same kind of access? */ + regaddr == chan->regaddr && /* Same register address? */ + regval == chan->regval) /* Same register value? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + chan->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (chan->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", chan->ntimes); + } + + /* Save information about the new access */ + + chan->wr = wr; + chan->regval = regval; + chan->regaddr = regaddr; + chan->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_chan_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset) +{ + uint32_t regaddr = chan->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAM34_TC_REGDEBUG + if (sam_checkreg(chan, false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_chan_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset, + uint32_t regval) +{ + uint32_t regaddr = chan->base + offset; + +#ifdef CONFIG_SAM34_TC_REGDEBUG + if (sam_checkreg(chan, true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_interrupt + * + * Description: + * Common timer channel interrupt handling. + * + * Input Parameters: + * tc Timer status instance + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +static int sam_tc_interrupt(struct sam_chan_s *chan) +{ + uint32_t sr; + uint32_t imr; + uint32_t pending; + + /* Process interrupts */ + + /* Get the interrupt status for this channel */ + + sr = sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + imr = sam_chan_getreg(chan, SAM_TC_IMR_OFFSET); + pending = sr & imr; + + /* Are there any pending interrupts for this channel? */ + + if (pending) + { + /* Yes... if we have pending interrupts then interrupts must be + * enabled and we must have a handler attached. + */ + + DEBUGASSERT(chan->handler); + if (chan->handler) + { + /* Execute the callback */ + + chan->handler(chan, chan->arg, sr); + } + else + { + /* Should never happen */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_raw_interrupt + * + * Description: + * Timer block interrupt handlers + * + * Input Parameters: + * irq + * context + * + * Returned Value: + * + ****************************************************************************/ + +static int sam_raw_interrupt(int irq, void *context) +{ + int i; + struct sam_chan_s *chan; + + for (i = 0; i < ENABLED_CHANNELS; i++) + { + chan = &g_channels[i]; + + if (chan->irq == irq) + { + return sam_tc_interrupt(chan); + } + } + + return OK; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_mckdivider + * + * Description: + * Return the TC clock input divider value. One of n=0..3 corresponding + * to divider values of {1, 2, 4, 8}. + * + * NOTE: The SAMA5D4 has no clock input divider + * + * Input Parameters: + * mck - The MCK frequency to be divider. + * + * Returned Value: + * Log2 of the TC clock divider. + * + ****************************************************************************/ + +#ifdef SAM34_HAVE_PMC_PCR_DIV +static int sam_tc_mckdivider(uint32_t mck) +{ + if (mck <= SAM_TC_MAXPERCLK) + { + return 0; + } + else if ((mck >> 1) <= SAM_TC_MAXPERCLK) + { + return 1; + } + else if ((mck >> 2) <= SAM_TC_MAXPERCLK) + { + return 2; + } + else /* if ((mck >> 3) <= SAM_TC_MAXPERCLK) */ + { + DEBUGASSERT((mck >> 3) <= SAM_TC_MAXPERCLK); + return 3; + } +} +#endif + +/**************************************************************************** + * Name: sam_tc_freqdiv_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the value of + * the Ftcin divider. + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The Ftcin input divider value + * + ****************************************************************************/ + +static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx) +{ + /* The final option is to use the SLOW clock */ + + if (ndx >= TC_NDIVIDERS) + { + /* Not really a divider. In this case, the board is actually driven + * by the 32.768KHz slow clock. This returns a value that looks like + * correct divider if MCK were the input. + */ + + return ftcin / BOARD_SLOWCLK_FREQUENCY; + } + else + { + return 1 << g_log2divider[ndx]; + } +} + +/**************************************************************************** + * Name: sam_tc_divfreq_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the + * value of the divided frequency + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The divided frequency value + * + ****************************************************************************/ + +static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx) +{ + /* The final option is to use the SLOW clock */ + + if (ndx >= TC_NDIVIDERS) + { + return BOARD_SLOWCLK_FREQUENCY; + } + else + { + return ftcin >> g_log2divider[ndx]; + } +} + +/**************************************************************************** + * Name: sam_tc_initialize + * + * Description: + * There is no global, one-time initialization of timer/counter data + * structures. Rather, this function is called each time that a channel + * is allocated and, if the channel has not been initialized, it will be + * initialized then. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +static inline struct sam_chan_s *sam_tc_initialize(int channel) +{ + struct sam_chan_s *chan; + const struct sam_chconfig_s *chconfig; + irqstate_t flags; + int i; + + /* Select the timer/counter and get the index associated with the + * channel. + */ + + chan = NULL; + for (i = 0; i < ENABLED_CHANNELS; i++) + { + if (g_configs[i].chan == channel) + { + chan = &g_channels[i]; + chconfig = &g_configs[i]; + break; + } + } + + if (!chan) + { + /* Timer/counter is not invalid or not enabled */ + + tcdbg("ERROR: Bad channel number: %d\n", channel); + return NULL; + } + + /* Has the timer counter been initialized. We have to be careful here + * because there is no semaphore protection. + */ + + flags = enter_critical_section(); + if (!chan->initialized) + { + /* Initialize the channel. */ + + tcdbg("Initializing TC%d\n", chconfig->chan); + + memset(chan, 0, sizeof(struct sam_chan_s)); + sem_init(&chan->exclsem, 0, 1); + chan->base = chconfig->base; + chan->pid = chconfig->pid; + chan->irq = chconfig->irq; + + /* Configure channel input/output pins */ + + if (chconfig->clkset) + { + /* Configure clock input pin */ + + sam_configgpio(chconfig->clkset); + } + + if (chconfig->tioaset) + { + /* Configure output A pin */ + + sam_configgpio(chconfig->tioaset); + } + + if (chconfig->tiobset) + { + /* Configure output B pin */ + + sam_configgpio(chconfig->tiobset); + } + + /* Disable and clear all channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* Enable clocking to the timer counter */ + + sam_enableperiph0(chan->pid); + + /* Attach the timer interrupt handler and enable the timer interrupts */ + + (void)irq_attach(chan->irq, sam_raw_interrupt); + up_enable_irq(chan->irq); + + /* Now the channel is initialized */ + + chan->initialized = true; + } + + /* Get exclusive access to the timer/count data structure */ + + sam_takesem(chan); + leave_critical_section(flags); + + /* Is it available? */ + + if (chan->inuse) + { + /* No.. return a failure */ + + tcdbg("Channel %d is in-used\n", channel); + sam_givesem(chan); + return NULL; + } + + /* Mark the channel "inuse" */ + + chan->inuse = true; + + /* And return the channel with the semaphore locked */ + + sam_regdump(chan, "Initialized"); + return chan; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode) +{ + struct sam_chan_s *chan; + + /* Initialize the timer/counter data (if necessary) and get exclusive + * access to the requested channel. + */ + + tcvdbg("channel=%d mode=%08x\n", channel, mode); + + chan = sam_tc_initialize(channel); + if (chan) + { + /* Disable TC clock */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + + /* Disable channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + + /* Clear and pending status */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* And set the requested mode */ + + sam_chan_putreg(chan, SAM_TC_CMR_OFFSET, mode); + sam_regdump(chan, "Allocated"); + sam_givesem(chan); + } + + /* Return an opaque reference to the channel */ + + tcvdbg("Returning %p\n", chan); + return (TC_HANDLE)chan; +} + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Freeing %p channel=%d inuse=%d\n", chan, chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Make sure that interrupts are detached and disabled and that the channel + * is stopped and disabled. + */ + + sam_tc_attach(handle, NULL, NULL, 0); + sam_tc_stop(handle); + + /* Mark the channel as available */ + + chan->inuse = false; +} + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Starting channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Read the SR to clear any pending interrupts on this channel */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* Then enable the timer (by setting the CLKEN bit). Setting SWTRIG + * will also reset the timer counter and starting the timer. + */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKEN | TC_CCR_SWTRG); + sam_regdump(chan, "Started"); +} + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Stopping channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + sam_regdump(chan, "Stopped"); +} + +/**************************************************************************** + * Name: sam_tc_attach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. + * + * Returned Value: + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + tc_handler_t oldhandler; + irqstate_t flags; + + DEBUGASSERT(chan); + + /* Remember the old interrupt handler and set the new handler */ + + flags = enter_critical_section(); + oldhandler = chan->handler; + chan->handler = handler; + + /* Don't enable interrupt if we are detaching no matter what the caller + * says. + */ + + if (!handler) + { + arg = NULL; + mask = 0; + } + + chan->arg = arg; + + /* Now enable interrupt as requested */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL & ~mask); + sam_chan_putreg(chan, SAM_TC_IER_OFFSET, TC_INT_ALL & mask); + leave_critical_section(flags); + + return oldhandler; +} + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrupt status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_SR_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + DEBUGASSERT(chan && regid < TC_NREGISTERS); + + tcvdbg("Channel %d: Set register RC%d to %08lx\n", + chan->chan, regid, (unsigned long)regval); + + sam_chan_putreg(chan, g_regoffset[regid], regval); + sam_regdump(chan, "Set register"); +} + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, g_regoffset[regid]); +} + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_CV_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_infreq + * + * Description: + * Return the timer input frequency (Ftcin), that is, the MCK frequency + * divided down so that the timer/counter is driven within its maximum + * frequency. + * + * Input Parameters: + * None + * + * Returned Value: + * The timer input frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_infreq(void) +{ + return BOARD_MCK_FREQUENCY; +} + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + uint32_t ftcin = sam_tc_infreq(); + uint32_t regval; + int tcclks; + + DEBUGASSERT(chan); + + /* Get the the TC_CMR register contents for this channel and extract the + * TCCLKS index. + */ + + regval = sam_chan_getreg(chan, SAM_TC_CMR_OFFSET); + tcclks = (regval & TC_CMR_TCCLKS_MASK) >> TC_CMR_TCCLKS_SHIFT; + + /* And use the TCCLKS index to calculate the timer counter frequency */ + + return sam_tc_divfreq_lookup(ftcin, tcclks); +} + +/**************************************************************************** + * Name: sam_tc_divisor + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / dev) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * div Divisor value. + * tcclks TCCLKS field value for divisor. + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks) +{ + uint32_t ftcin = sam_tc_infreq(); + int ndx = 0; + + tcvdbg("frequency=%d\n", frequency); + + /* Satisfy lower bound. That is, the value of the divider such that: + * + * frequency >= (tc_input_frequency * 65536) / divider. + */ + + while (frequency < (sam_tc_divfreq_lookup(ftcin, ndx) >> 16)) + { + if (++ndx > TC_NDIVOPTIONS) + { + /* If no divisor can be found, return -ERANGE */ + + tcdbg("Lower bound search failed\n"); + return -ERANGE; + } + } + + /* Try to maximize DIV while still satisfying upper bound. That the + * value of the divider such that: + * + * frequency < tc_input_frequency / divider. + */ + + for (; ndx < (TC_NDIVOPTIONS-1); ndx++) + { + if (frequency > sam_tc_divfreq_lookup(ftcin, ndx + 1)) + { + break; + } + } + + /* Return the divider value */ + + if (div) + { + uint32_t value = sam_tc_freqdiv_lookup(ftcin, ndx); + tcvdbg("return div=%lu\n", (unsigned long)value); + *div = value; + } + + /* Return the TCCLKS selection */ + + if (tcclks) + { + tcvdbg("return tcclks=%08lx\n", (unsigned long)TC_CMR_TCCLKS(ndx)); + *tcclks = TC_CMR_TCCLKS(ndx); + } + + return OK; +} + +#endif diff --git a/arch/arm/src/sam34/sam4cm_tc.h b/arch/arm/src/sam34/sam4cm_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..85520d84d935c7b89e3ccc52166ea976351c4397 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_tc.h @@ -0,0 +1,362 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam4cm_tc.h + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4CM_TC_H +#define __ARCH_ARM_SRC_SAM34_SAM4CM_TC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "chip/sam_tc.h" + +#if defined(CONFIG_SAM34_TC0) || defined(CONFIG_SAM34_TC1) || defined(CONFIG_SAM34_TC2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The timer/counter and channel arguments to sam_tc_allocate() */ + +#define TC_CHAN0 0 /* TC0 */ +#define TC_CHAN1 1 +#define TC_CHAN2 2 +#define TC_CHAN3 3 /* TC1 */ +#define TC_CHAN4 4 +#define TC_CHAN5 5 + +/* Register identifier used with sam_tc_setregister */ + +#define TC_REGA 0 +#define TC_REGB 1 +#define TC_REGC 2 + +/* Timer debug is enabled if any timer client is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_ANALOG +# undef CONFIG_SAMA5_TC_REGDEBUG +#endif + +#if !defined(CONFIG_SAM34_TC_DEBUG) && defined(CONFIG_SAM34_ADC) && defined(CONFIG_DEBUG_ANALOG) +# define CONFIG_SAM34_TC_DEBUG 1 +#endif + +/* Timer/counter debug output */ + +#ifdef CONFIG_SAM34_TC_DEBUG +# define tcdbg dbg +# define tcvdbg vdbg +# define tclldbg lldbg +# define tcllvdbg llvdbg +#else +# define tcdbg(x...) +# define tcvdbg(x...) +# define tclldbg(x...) +# define tcllvdbg(x...) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* An opaque handle used to represent a timer channel */ + +typedef void *TC_HANDLE; + +/* Timer interrupt callback. When a timer interrupt expires, the client will + * receive: + * + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + */ + +typedef void (*tc_handler_t)(TC_HANDLE tch, void *arg, uint32_t sr); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode); + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_attach/sam_tc_detach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. Ignored if handler is NULL. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. Ignored if handler is + * NULL. + * + * Returned Value: + * The address of the previous handler, if any. + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask); + +#define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0) + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrutp status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval); + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid); + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_infreq + * + * Description: + * Return the timer input frequency, that is, the MCK frequency divided + * down so that the timer/counter is driven within its maximum frequency. + * + * Input Parameters: + * None + * + * Returned Value: + * The timer input frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_infreq(void); + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_divisor + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / div) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * div Divisor value. + * tcclks TCCLKS field value for divisor. + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_TC0 || CONFIG_SAMA5_TC1 || CONFIG_SAMA5_TC2 */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TC_H */ diff --git a/arch/arm/src/sam34/sam4cm_tickless.c b/arch/arm/src/sam34/sam4cm_tickless.c new file mode 100644 index 0000000000000000000000000000000000000000..04952413314af219058d9af5327d6bc45a913dd0 --- /dev/null +++ b/arch/arm/src/sam34/sam4cm_tickless.c @@ -0,0 +1,404 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_tickless.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Tickless OS Support. + * + * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts + * is suppressed and the platform specific code is expected to provide the + * following custom functions. + * + * void up_timer_initialize(void): Initializes the timer facilities. Called + * early in the initialization sequence (by up_intialize()). + * int up_timer_gettime(FAR struct timespec *ts): Returns the current + * time from the platform specific time source. + * int up_timer_cancel(void): Cancels the interval timer. + * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts) + * the interval timer. + * + * The RTOS will provide the following interfaces for use by the platform- + * specific interval timer implementation: + * + * void sched_timer_expiration(void): Called by the platform-specific + * logic when the interval timer expires. + * + ****************************************************************************/ +/**************************************************************************** + * SAM34 Timer Usage + * + * This current implementation uses two timers: A one-shot timer to provide + * the timed events and a free running timer to provide the current time. + * Since timers are a limited resource, that could be an issue on some + * systems. + * + * We could do the job with a single timer if we were to keep the single + * timer in a free-running at all times. The SAM34 timer/counters have + * 16-bit counters with the capability to generate a compare interrupt when + * the timer matches a compare value but also to continue counting without + * stopping (giving another, different interrupt when the timer rolls over + * from 0xffff to zero). So we could potentially just set the compare + * at the number of ticks you want PLUS the current value of timer. Then + * you could have both with a single timer: An interval timer and a free- + * running counter with the same timer! + * + * Patches are welcome! + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "sam4cm_oneshot.h" +#include "sam4cm_freerun.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SAM34_TC +# error Timer/counters must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAM34_ONESHOT +# error CONFIG_SAM34_ONESHOT must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAM34_FREERUN +# error CONFIG_SAM34_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAM34_TICKLESS_FREERUN +# error CONFIG_SAM34_TICKLESS_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAM34_TICKLESS_ONESHOT +# error CONFIG_SAM34_TICKLESS_ONESHOT must be selected for the Tickless OS option +#endif + +#if CONFIG_SAM34_TICKLESS_ONESHOT == 0 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 0 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_ONESHOT == 1 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 1 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_ONESHOT == 2 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 2 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_ONESHOT == 3 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 3 && CONFIG_SAM34_TC1 not selected +#elif CONFIG_SAM34_TICKLESS_ONESHOT == 4 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 4 && CONFIG_SAM34_TC1 not selected +#elif CONFIG_SAM34_TICKLESS_ONESHOT == 5 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_ONESHOT == 5 && CONFIG_SAM34_TC1 not selected +#endif + +#if CONFIG_SAM34_TICKLESS_ONESHOT < 0 || CONFIG_SAM34_TICKLESS_ONESHOT > 5 +# error CONFIG_SAMA5_TICKLESS_ONESHOT is not valid +#endif + +#if CONFIG_SAM34_TICKLESS_FREERUN == 0 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_FREERUN == 0 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_FREERUN == 1 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_FREERUN == 1 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_FREERUN == 2 && !defined(CONFIG_SAM34_TC0) +# error CONFIG_SAM34_TICKLESS_FREERUN == 2 && CONFIG_SAM34_TC0 not selected +#elif CONFIG_SAM34_TICKLESS_FREERUN == 3 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_FREERUN == 3 && CONFIG_SAM34_TC1 not selected +#elif CONFIG_SAM34_TICKLESS_FREERUN == 4 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_FREERUN == 4 && CONFIG_SAM34_TC1 not selected +#elif CONFIG_SAM34_TICKLESS_FREERUN == 5 && !defined(CONFIG_SAM34_TC1) +# error CONFIG_SAM34_TICKLESS_FREERUN == 5 && CONFIG_SAM34_TC1 not selected +#endif + +#if CONFIG_SAM34_TICKLESS_FREERUN < 0 || CONFIG_SAM34_TICKLESS_FREERUN > 5 +# error CONFIG_SAM34_TICKLESS_FREERUN is not valid +#endif + +#if CONFIG_SAM34_TICKLESS_FREERUN == CONFIG_SAM34_TICKLESS_ONESHOT +# error CONFIG_SAM34_TICKLESS_FREERUN is the same as CONFIG_SAM34_TICKLESS_ONESHOT +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sam_tickless_s +{ + struct sam_oneshot_s oneshot; + struct sam_freerun_s freerun; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct sam_tickless_s g_tickless; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Called when the one shot timer expires + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +static void sam_oneshot_handler(void *arg) +{ + tcllvdbg("Expired...\n"); + sched_timer_expiration(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Initializes all platform-specific timer facilities. This function is + * called early in the initialization sequence by up_intialize(). + * On return, the current up-time should be available from + * up_timer_gettime() and the interval timer is ready for use (but not + * actively timing. + * + * Provided by platform-specific code and called from the architecture- + * specific logic. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + uint64_t max_delay; +#endif + int ret; + + /* Initialize the one-shot timer */ + + ret = sam_oneshot_initialize(&g_tickless.oneshot, + CONFIG_SAM34_TICKLESS_ONESHOT, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_oneshot_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(ONESHOT_INITIALIZED(&g_tickless.oneshot)); + +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + /* Get the maximum delay of the one-shot timer in microseconds */ + + ret = sam_oneshot_max_delay(&g_tickless.oneshot, &max_delay); + if (ret < 0) + { + tclldbg("ERROR: sam_oneshot_max_delay failed\n"); + PANIC(); + } + + /* Convert this to configured clock ticks for use by the OS timer logic */ + + max_delay /= CONFIG_USEC_PER_TICK; + if (max_delay > UINT32_MAX) + { + g_oneshot_maxticks = UINT32_MAX; + } + else + { + g_oneshot_maxticks = max_delay; + } +#endif + + /* Initialize the free-running timer */ + + ret = sam_freerun_initialize(&g_tickless.freerun, + CONFIG_SAM34_TICKLESS_FREERUN, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_freerun_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(FREERUN_INITIALIZED(&g_tickless.freerun)); +} + +/**************************************************************************** + * Name: up_timer_gettime + * + * Description: + * Return the elapsed time since power-up (or, more correctly, since + * up_timer_initialize() was called). This function is functionally + * equivalent to: + * + * int clock_gettime(clockid_t clockid, FAR struct timespec *ts); + * + * when clockid is CLOCK_MONOTONIC. + * + * This function provides the basis for reporting the current time and + * also is used to eliminate error build-up from small errors in interval + * time calculations. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the location in which to return the up-time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * Called from the the normal tasking context. The implementation must + * provide whatever mutual exclusion is necessary for correct operation. + * This can include disabling interrupts in order to assure atomic register + * operations. + * + ****************************************************************************/ + +int up_timer_gettime(FAR struct timespec *ts) +{ + return FREERUN_INITIALIZED(&g_tickless.freerun) ? + sam_freerun_counter(&g_tickless.freerun, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_cancel + * + * Description: + * Cancel the interval timer and return the time remaining on the timer. + * These two steps need to be as nearly atomic as possible. + * sched_timer_expiration() will not be called unless the timer is + * restarted with up_timer_start(). + * + * If, as a race condition, the timer has already expired when this + * function is called, then that pending interrupt must be cleared so + * that up_timer_start() and the remaining time of zero should be + * returned. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Location to return the remaining time. Zero should be returned + * if the timer is not active. ts may be zero in which case the + * time remaining is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_cancel(FAR struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_cancel(&g_tickless.oneshot, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_start + * + * Description: + * Start the interval timer. sched_timer_expiration() will be + * called at the completion of the timeout (unless up_timer_cancel + * is called to stop the timing. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the time interval until sched_timer_expiration() is + * called. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_start(FAR const struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_start(&g_tickless.oneshot, sam_oneshot_handler, NULL, ts) : + -EAGAIN; +} +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/sam34/sam4e_gpio.h b/arch/arm/src/sam34/sam4e_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..c475886103c8f4f718802dfc050810dc394eaffc --- /dev/null +++ b/arch/arm/src/sam34/sam4e_gpio.h @@ -0,0 +1,209 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4e_gpio.h + * General Purpose Input/Output (GPIO) definitions for the SAM4E + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4E_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM4E_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#define GPIO_HAVE_PULLDOWN 1 +#define GPIO_HAVE_PERIPHCD 1 +#define GPIO_HAVE_SCHMITT 1 +#define GPIO_HAVE_DELAYR 1 + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 32-bit Encoding: + * + * MMMC CCCC IIIV PPPB BBBB + */ + +/* Input/Output mode: + * + * MMM. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (17) /* Bits 17-19: GPIO mode */ +#define GPIO_MODE_MASK (7 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Output */ +# define GPIO_PERIPHA (2 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (3 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define GPIO_PERIPHC (4 << GPIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define GPIO_PERIPHD (5 << GPIO_MODE_SHIFT) /* Controlled by periph D signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * ...C CCCC .... .... .... + */ + +#define GPIO_CFG_SHIFT (12) /* Bits 12-16: GPIO configuration bits */ +#define GPIO_CFG_MASK (31 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_PULLDOWN (2 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-down */ +# define GPIO_CFG_DEGLITCH (4 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (8 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ +# define GPIO_CFG_SCHMITT (16 << GPIO_CFG_SHIFT) /* Bit 13: Schmitt trigger */ + +/* Additional interrupt modes: + * + * .... .... III. .... .... + */ + +#define GPIO_INT_SHIFT (9) /* Bits 9-11: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * .... .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOE (4 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4E_GPIO_H */ diff --git a/arch/arm/src/sam34/sam4e_periphclks.h b/arch/arm/src/sam34/sam4e_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..5f41fee35fb9731f21270790d5d89a0aa975a824 --- /dev/null +++ b/arch/arm/src/sam34/sam4e_periphclks.h @@ -0,0 +1,179 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4e_periphclks.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4E_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM4E_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() sam_enableperiph0(SAM_PID_SUPC) +#define sam_rstc_enableclk() sam_enableperiph0(SAM_PID_RSTC) +#define sam_rtc_enableclk() sam_enableperiph0(SAM_PID_RTC) +#define sam_rtt_enableclk() sam_enableperiph0(SAM_PID_RTT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_pmc_enableclk() sam_enableperiph0(SAM_PID_PMC) +#define sam_eefc0_enableclk() sam_enableperiph0(SAM_PID_EEFC0) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_hsmci_enableclk() sam_enableperiph0(SAM_PID_HSMCI) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_dmac_enableclk() sam_enableperiph0(SAM_PID_DMAC) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph0(SAM_PID_TC5) +#define sam_tc6_enableclk() sam_enableperiph0(SAM_PID_TC6) +#define sam_tc7_enableclk() sam_enableperiph0(SAM_PID_TC7) +#define sam_tc8_enableclk() sam_enableperiph0(SAM_PID_TC8) +#define sam_afec0_enableclk() sam_enableperiph0(SAM_PID_AFEC0) +#define sam_afec1_enableclk() sam_enableperiph0(SAM_PID_AFEC1) + +#define sam_dacc_enableclk() sam_enableperiph1(SAM_PID_DACC) +#define sam_acc_enableclk() sam_enableperiph1(SAM_PID_ACC) +#define sam_arm_enableclk() sam_enableperiph1(SAM_PID_ARM) +#define sam_udp_enableclk() sam_enableperiph1(SAM_PID_UDP) +#define sam_pwm_enableclk() sam_enableperiph1(SAM_PID_PWM) +#define sam_can0_enableclk() sam_enableperiph1(SAM_PID_CAN0) +#define sam_can1_enableclk() sam_enableperiph1(SAM_PID_CAN1) +#define sam_aes_enableclk() sam_enableperiph1(SAM_PID_AES) +#define sam_emac_enableclk() sam_enableperiph1(SAM_PID_EMAC) +#define sam_uart1_enableclk() sam_enableperiph1(SAM_PID_UART1) + +#define sam_supc_disableclk() sam_disableperiph0(SAM_PID_SUPC) +#define sam_rstc_disableclk() sam_disableperiph0(SAM_PID_RSTC) +#define sam_rtc_disableclk() sam_disableperiph0(SAM_PID_RTC) +#define sam_rtt_disableclk() sam_disableperiph0(SAM_PID_RTT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_pmc_disableclk() sam_disableperiph0(SAM_PID_PMC) +#define sam_eefc0_disableclk() sam_disableperiph0(SAM_PID_EEFC0) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_hsmci_disableclk() sam_disableperiph0(SAM_PID_HSMCI) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_dmac_disableclk() sam_disableperiph0(SAM_PID_DMAC) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph0(SAM_PID_TC5) +#define sam_tc6_disableclk() sam_disableperiph0(SAM_PID_TC6) +#define sam_tc7_disableclk() sam_disableperiph0(SAM_PID_TC7) +#define sam_tc8_disableclk() sam_disableperiph0(SAM_PID_TC8) +#define sam_afec0_disableclk() sam_disableperiph0(SAM_PID_AFEC0) +#define sam_afec1_disableclk() sam_disableperiph0(SAM_PID_AFEC1) + +#define sam_dacc_disableclk() sam_disableperiph1(SAM_PID_DACC) +#define sam_acc_disableclk() sam_disableperiph1(SAM_PID_ACC) +#define sam_arm_disableclk() sam_disableperiph1(SAM_PID_ARM) +#define sam_udp_disableclk() sam_disableperiph1(SAM_PID_UDP) +#define sam_pwm_disableclk() sam_disableperiph1(SAM_PID_PWM) +#define sam_can0_disableclk() sam_disableperiph1(SAM_PID_CAN0) +#define sam_can1_disableclk() sam_disableperiph1(SAM_PID_CAN1) +#define sam_aes_disableclk() sam_disableperiph1(SAM_PID_AES) +#define sam_emac_disableclk() sam_disableperiph1(SAM_PID_EMAC) +#define sam_uart1_disableclk() sam_disableperiph1(SAM_PID_UART1) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4E_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam4l_clockconfig.c b/arch/arm/src/sam34/sam4l_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..3b6ec2a70130fba8a22bf67d19fa8d7af80aa762 --- /dev/null +++ b/arch/arm/src/sam34/sam4l_clockconfig.c @@ -0,0 +1,1434 @@ +/**************************************************************************** + * arch/avr/src/sam34/sam4l_clockconfig.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_clkinit.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "up_internal.h" +#include "chip/sam4l_pm.h" +#include "chip/sam4l_scif.h" +#include "chip/sam4l_bpm.h" +#include "chip/sam4l_bscif.h" +#include "chip/sam4l_flashcalw.h" + +#include "sam4l_periphclks.h" +#include "sam_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ARCH_RAMFUNCS +# error "CONFIG_ARCH_RAMFUNCS must be defined" +#endif + +/* Board/Clock Setup *******************************************************/ +/* Verify dividers */ + +#if ((BOARD_CPU_SHIFT > BOARD_PBA_SHIFT) || (BOARD_CPU_SHIFT > BOARD_PBB_SHIFT) || \ + (BOARD_CPU_SHIFT > BOARD_PBC_SHIFT) || (BOARD_CPU_SHIFT > BOARD_PBD_SHIFT)) +# error BOARD_PBx_SHIFT must be greater than or equal to BOARD_CPU_SHIFT +#endif + +/* Nominal frequencies in on-chip RC oscillators. These may frequencies + * may vary with temperature changes. + */ + +#define SAM_RCSYS_FREQUENCY 115000 /* Nominal frequency of RCSYS (Hz) */ +#define SAM_RC32K_FREQUENCY 32768 /* Nominal frequency of RC32K (Hz) */ +#define SAM_RC80M_FREQUENCY 80000000 /* Nominal frequency of RC80M (Hz) */ +#define SAM_RCFAST4M_FREQUENCY 4000000 /* Nominal frequency of RCFAST4M (Hz) */ +#define SAM_RCFAST8M_FREQUENCY 8000000 /* Nominal frequency of RCFAST8M (Hz) */ +#define SAM_RCFAST12M_FREQUENCY 12000000 /* Nominal frequency of RCFAST12M (Hz) */ +#define SAM_RC1M_FREQUENCY 1000000 /* Nominal frequency of RC1M (Hz) */ + +/* Oscillator 0. This might be the system clock or the source clock for + * either PLL0 or DFPLL. It might also be needed if OSC0 is the source + * clock for GCLK9. + * + * By selecting CONFIG_SAM34_OSC0, you can also force the clock to be enabled + * at boot time. + */ + +#if defined(CONFIG_SAM34_OSC0) || defined(BOARD_SYSCLK_SOURCE_OSC0) || \ + defined(BOARD_DFLL0_SOURCE_OSC0) || defined(BOARD_PLL0_SOURCE_OSC0) || \ + defined(BOARD_GLCK9_SOURCE_OSC0) +# define NEED_OSC0 1 +#endif + +#ifdef NEED_OSC0 +# if !defined(BOARD_OSC0_STARTUP_US) +# error BOARD_OSC0_STARTUP_US is not defined +# elif BOARD_OSC0_STARTUP_US == 0 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_0 +# define SAM_OSC0_STARTUP_TIMEOUT 8 +# elif BOARD_OSC0_STARTUP_US <= 557 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_64 +# define SAM_OSC0_STARTUP_TIMEOUT 80 +# elif BOARD_OSC0_STARTUP_US <= 1100 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_128 +# define SAM_OSC0_STARTUP_TIMEOUT 160 +# elif BOARD_OSC0_STARTUP_US <= 18000 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_2K +# define SAM_OSC0_STARTUP_TIMEOUT 2560 +# elif BOARD_OSC0_STARTUP_US <= 36000 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_4K +# define SAM_OSC0_STARTUP_TIMEOUT 5120 +# elif BOARD_OSC0_STARTUP_US <= 71000 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_8K +# define SAM_OSC0_STARTUP_TIMEOUT 10240 +# elif BOARD_OSC0_STARTUP_US <= 143000 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_16K +# define SAM_OSC0_STARTUP_TIMEOUT 20480 +# elif BOARD_OSC0_STARTUP_US <= 285000 +# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_32K +# define SAM_OSC0_STARTUP_TIMEOUT 40960 +# else +# error BOARD_OSC0_STARTUP_US is out of range +# endif + +# ifdef BOARD_OSC0_ISXTAL +# define SAM_OSC0_MODE_VALUE SCIF_OSCCTRL0_MODE +# if BOARD_OSC0_FREQUENCY < 2000000 +# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(0) +# elif BOARD_OSC0_FREQUENCY < 4000000 +# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(1) +# elif BOARD_OSC0_FREQUENCY < 8000000 +# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(2) +# elif BOARD_OSC0_FREQUENCY < 16000000 +# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(3) +# else +# define SAM_OSC0_GAIN_VALUE ((0x1u << 4) | SCIF_OSCCTRL0_GAIN(0)) +# endif +# else +# define SAM_OSC0_MODE_VALUE 0 +# define SAM_OSC0_GAIN_VALUE 0 +# endif +#endif + +/* OSC32. The 32K oscillator may be the source clock for DFPLL0 or + * the source clock for GLK9 that might be used to driver PLL0. + * + * By selecting CONFIG_SAM34_OSC32K, you can also force the clock to be + * enabled at boot time. OSC32 may needed by other devices as well + * (AST, WDT, PICUART, RTC). + */ + +#if defined(CONFIG_SAM34_OSC32K) || defined(BOARD_DFLL0_SOURCE_OSC32K) || \ + defined(BOARD_GLCK9_SOURCE_OSC32K) +# define NEED_OSC32K 1 +#endif + +#ifdef NEED_OSC32K +# if !defined(BOARD_OSC32_STARTUP_US) +# error BOARD_OSC32_STARTUP_US is not defined +# elif BOARD_OSC32_STARTUP_US == 0 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_0 +# elif BOARD_OSC32_STARTUP_US <= 1100 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128 +# elif BOARD_OSC32_STARTUP_US <= 72300 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_8K +# elif BOARD_OSC32_STARTUP_US <= 143000 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_16K +# elif BOARD_OSC32_STARTUP_US <= 570000 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_64K +# elif BOARD_OSC32_STARTUP_US <= 1100000 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128K +# elif BOARD_OSC32_STARTUP_US <= 2300000 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_256K +# elif BOARD_OSC32_STARTUP_US <= 4600000 +# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_512K +# else +# error BOARD_OSC32_STARTUP_US is out of range +# endif + +# ifdef BOARD_OSC32_ISXTAL +# define SAM_OSC32_MODE_VALUE BSCIF_OSCCTRL32_MODE_XTAL +# else +# define SAM_OSC32_MODE_VALUE BSCIF_OSCCTRL32_MODE_EXTCLK +# endif + +# ifndef BOARD_OSC32_SELCURR +# define BOARD_OSC32_SELCURR BSCIF_OSCCTRL32_SELCURR_300 +# endif +#endif + +/* RC80M. This might be the system clock or the source clock for the DFPLL + * or it could be the source for GCLK9 that drives PLL0. + * + * By selecting CONFIG_SAM34_RC80M, you can also force the clock to be enabled + * at boot time. + */ + +#if defined(CONFIG_SAM34_RC80M) || defined(BOARD_SYSCLK_SOURCE_RC80M) || \ + defined(BOARD_DFLL0_SOURCE_RC80M) || defined(BOARD_GLCK9_SOURCE_RC80M) +# define NEED_RC80M 1 +#endif + +/* RCFAST. The 12/8/4 fast RC oscillator may be used as the system clock + * or as the source for GLCK9 that drives PLL0. + * If not then, it may be enabled by setting the CONFIG_SAM34_RCFASTxM + * configuration variable. + */ + +#if defined(CONFIG_SAM34_RCFAST12M) +# undef CONFIG_SAM34_RCFAST8M +# undef CONFIG_SAM34_RCFAST4M +#elif defined(CONFIG_SAM34_RCFAST8M) +# undef CONFIG_SAM34_RCFAST4M +#endif + +#if defined(BOARD_SYSCLK_SOURCE_FCFAST12M) +# if defined(CONFIG_SAM34_RCFAST8M) || defined(CONFIG_SAM34_RCFAST4M) +# error BOARD_SYSCLK_SOURCE_FCFAST12M inconsistent with CONFIG_SAM34_RCFAST8/4M +# endif +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST12M_FREQUENCY +#elif defined(BOARD_SYSCLK_SOURCE_FCFAST8M) +# if defined(CONFIG_SAM34_RCFAST12M) || defined(CONFIG_SAM34_RCFAST4M) +# error BOARD_SYSCLK_SOURCE_FCFAST8M inconsistent with CONFIG_SAM34_RCFAST12/4M +# endif +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST8M_FREQUENCY +#elif defined(BOARD_SYSCLK_SOURCE_FCFAST4M) +# if defined(CONFIG_SAM34_RCFAST12M) || defined(CONFIG_SAM34_RCFAST8M) +# error BOARD_SYSCLK_SOURCE_FCFAST4M inconsistent with CONFIG_SAM34_RCFAST12/8M +# endif +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST4M_FREQUENCY +#elif defined(CONFIG_SAM34_RCFAST12M) +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST12M_FREQUENCY +#elif defined(CONFIG_SAM34_RCFAST8M) +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST8M_FREQUENCY +#elif defined(CONFIG_SAM34_RCFAST4M) +# define NEED_RCFAST 1 +# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ +# define SAM_RCFAST_FREQUENCY SAM_RCFAST4M_FREQUENCY +#endif + +/* RC1M. The 1M RC oscillator may be used as the system block or + * may be the source clock for GLCK9 that drives PLL0 + * + * By selecting CONFIG_SAM34_RC1M, you can also force the clock to be + * enabled at boot time. + */ + +#if defined(CONFIG_SAM34_RC1M) || defined(BOARD_SYSCLK_SOURCE_RC1M) || \ + defined(BOARD_GLCK9_SOURCE_RC1M) +# define NEED_RC1M 1 +#endif + +/* RC32K. The 32KHz RC oscillator may be used as the input to DFLL0 + * or as the input to GCLK9 that drives PLL0. + * + * By selecting CONFIG_SAM34_RC32K, you can also force the clock to be + * enabled at boot time. + */ + +#if defined(CONFIG_SAM34_RC32K) || defined(BOARD_DFLL0_SOURCE_RC32K) || \ + defined(BOARD_GLCK9_SOURCE_RC32K) +# define NEED_RC32K 1 +#endif + +/* GCLK9. May used as a source clock for PLL0 */ + +#ifdef BOARD_PLL0_SOURCE_GCLK9 +# define NEED_GLCK9 1 +#endif + +#ifdef NEED_GLCK9 +# if defined(BOARD_GLCK9_SOURCE_RCSYS) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RCSYS +# define SAM_GCLK9_FREQUENCY SAM_RCSYS_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_OSC32K) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_OSC32K +# define SAM_GCLK9_FREQUENCY BOARD_OSC32_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_DFLL0) +# error BOARD_GLCK9_SOURCE_DFLL0 is not supported +# elif defined(BOARD_GLCK9_SOURCE_OSC0) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_OSC0 +# define SAM_GCLK9_FREQUENCY BOARD_OSC0_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_RC80M) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC80M +# define SAM_GCLK9_FREQUENCY SAM_RC80M_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_RCFAST) +# error BOARD_GLCK9_SOURCE_RCFAST is not supported (needs RCFAST configuration) +# elif defined(BOARD_GLCK9_SOURCE_RC1M) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC1M +# define SAM_GCLK9_FREQUENCY SAM_RCFAST_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_CPUCLK) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_CPUCLK +# define SAM_GCLK9_FREQUENCY BOARD_CPU_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_HSBCLK) +# error BOARD_GLCK9_SOURCE_HSBCLK is not supported (REVISIT) +# elif defined(BOARD_GLCK9_SOURCE_PBACLK) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBACLK +# define SAM_GCLK9_FREQUENCY BOARD_PBA_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_PBBCLK) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBBCLK +# define SAM_GCLK9_FREQUENCY BOARD_PBB_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_PBCCLK) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBCCLK +# define SAM_GCLK9_FREQUENCY BOARD_PBC_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_PBDCLK) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBDCLK +# define SAM_GCLK9_FREQUENCY BOARD_PBD_FREQUENCY +# elif defined(BOARD_GLCK9_SOURCE_RC32K) +# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC32K +# define SAM_GCLK9_FREQUENCY SAM_RC32K_FREQUENCY +# else +# error Missing GCLK9 source +# endif +#endif + +/* PLL0 */ + +#ifdef BOARD_SYSCLK_SOURCE_PLL0 +/* PLL0 source */ + +# if defined(BOARD_PLL0_SOURCE_OSC0) +# define SAM_PLL0_SOURCE SCIF_PLL0_PLLOSC_OSC0 +# define SAM_PLL0_SOURCE_FREQUENCY BOARD_OSC0_FREQUENCY +# elif defined(BOARD_PLL0_SOURCE_GCLK9) +# define SAM_PLL0_SOURCE SCIF_PLL0_PLLOSC_GCLK9 +# define SAM_PLL0_SOURCE_FREQUENCY SAM_GCLK9_FREQUENCY +# else +# error Missing PLL0 source +# endif + +/* PLL0 Multipler and Divider */ + +# if !defined(BOARD_PLL0_MUL) +# error BOARD_PLL0_MUL is not defined +# elif BOARD_PLL0_MUL <= 2 || BOARD_PLL0_MUL > 16 +# error BOARD_PLL0_MUL is out of range +# endif + +# if !defined(BOARD_PLL0_DIV) +# error BOARD_PLL0_DIV is not defined +# elif BOARD_PLL0_DIV < 1 || BOARD_PLL0_DIV > 15 +# error BOARD_PLL0_DIV is out of range +# endif + +/* PLL0 frequency ranges */ + +# define SAM_PLL0_MIN_FREQUENCY 40000000 +# define SAM_PLL0_MAX_FREQUENCY 240000000 + +/* PLL0 VCO frequency */ + +# define SAM_PLL0_VCO_DIV1_FREQUENCY \ + (SAM_PLL0_SOURCE_FREQUENCY * BOARD_PLL0_MUL / BOARD_PLL0_DIV) + +# if (SAM_PLL0_VCO_DIV1_FREQUENCY < SAM_PLL0_MIN_FREQUENCY) || \ + (SAM_PLL0_VCO_DIV1_FREQUENCY > SAM_PLL0_MAX_FREQUENCY) +# error PLL0 VCO frequency is out of range +# endif + +/* PLL0 Options: + * + * PLL0 supports an option to divide the frequency output by 2. We + * will do this division to bring the internal VCO frequency up to the + * minimum value + * + * PLL0 operates in two frequency ranges as determined by + * SCIF_PLL0_PLLOPT_FVO: + * + * 0: 80MHz < fvco < 180MHz + * 1: 160MHz < fvco < 240MHz + * + * Select the correct frequncy range using the recommended threshold + * value. + */ + +# if SAM_PLL0_VCO_DIV1_FREQUENCY < (2*SAM_PLL0_MIN_FREQUENCY) && BOARD_PLL0_MUL <= 8 +# define SAM_PLL0_VCO_FREQUENCY (2 * SAM_PLL0_VCO_DIV1_FREQUENCY) +# define SAM_PLL0_MUL (2 * BOARD_PLL0_MUL) + +# if SAM_PLL0_VCO_FREQUENCY > (SAM_PLL0_VCO_RANGE_THRESHOLD / 2) +# define SAM_PLL0_OPTIONS (SCIF_PLL0_PLLOPT_DIV2 | SCIF_PLL0_PLLOPT_FVO) +# else +# define SAM_PLL0_OPTIONS SCIF_PLL0_PLLOPT_DIV2 +# endif + +# else +# define SAM_PLL0_VCO_FREQUENCY SAM_PLL0_VCO_DIV1_FREQUENCY +# define SAM_PLL0_MUL BOARD_PLL0_MUL + +# if SAM_PLL0_VCO_FREQUENCY > SAM_PLL0_VCO_RANGE_THRESHOLD +# define SAM_PLL0_OPTIONS SCIF_PLL0_PLLOPT_FVO +# else +# define SAM_PLL0_OPTIONS 0 +# endif +# endif +#endif + +/* DFLL0 */ + +#ifdef BOARD_SYSCLK_SOURCE_DFLL0 +/* DFLL0 reference clock */ + +# if defined(BOARD_DFLL0_SOURCE_RCSYS) +# define SAM_DFLLO_REFCLK SCIF_GCCTRL_OSCSEL_RCSYS +# elif defined(BOARD_DFLL0_SOURCE_OSC32K) +# define SAM_DFLLO_REFCLK SCIF_GCCTRL_OSCSEL_OSC32K +# elif defined(BOARD_DFLL0_SOURCE_OSC0) +# define SAM_DFLLO_REFCLK SCIF_GCCTRL_OSCSEL_OSC0 +# elif defined(BOARD_DFLL0_SOURCE_RC80M) +# define SAM_DFLLO_REFCLK SCIF_GCCTRL_OSCSEL_RC80M +# elif defined(BOARD_DFLL0_SOURCE_RC32K) +# define SAM_DFLLO_REFCLK SCIF_GCCTRL_OSCSEL_RC32K +# else +# error No DFLL0 source for reference clock defined +# endif + +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_picocache + * + * Description: + * Initialiaze the PICOCACHE. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_PICOCACHE +static inline void sam_picocache(void) +{ + /* Enable clocking to the PICOCACHE */ + + sam_hsb_enableperipheral(PM_HSBMASK_HRAMC1); + sam_pbb_enableperipheral(PM_PBBMASK_HRAMC1); + + /* Enable the PICOCACHE and wait for it to become ready */ + + putreg32(PICOCACHE_CTRL_CEN, SAM_PICOCACHE_CTRL); + while ((getreg32(SAM_PICOCACHE_SR) & PICOCACHE_SR_CSTS) == 0); +} +#else +# define sam_picocache() +#endif + +/**************************************************************************** + * Name: sam_enableosc0 + * + * Description: + * Initialiaze OSC0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef NEED_OSC0 +static inline void sam_enableosc0(void) +{ + uint32_t regval; + + /* Enable and configure OSC0 */ + + regval = SAM_OSC0_STARTUP_VALUE | SAM_OSC0_GAIN_VALUE | SAM_OSC0_MODE_VALUE | + SCIF_OSCCTRL0_OSCEN; + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_OSCCTRL0_OFFSET), + SAM_SCIF_UNLOCK); + putreg32(regval, SAM_SCIF_OSCCTRL0); + + /* Wait for OSC0 to be ready */ + + while (getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_OSC0RDY) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enableosc32 + * + * Description: + * Initialiaze the 32KHz oscillator per settings in the board.h header + * file. + * + ****************************************************************************/ + +#ifdef NEED_OSC32K +static inline void sam_enableosc32(void) +{ + uint32_t regval; + + /* Set up the OSCCTRL32 register using settings from the board.h file. + * Also enable the oscillator and provide bother the 32KHz and 1KHz output. + */ + + regval = SAM_OSC32_STARTUP_VALUE | BOARD_OSC32_SELCURR | SAM_OSC32_MODE_VALUE | + BSCIF_OSCCTRL32_EN1K | BSCIF_OSCCTRL32_EN32K | + BSCIF_OSCCTRL32_OSC32EN; + + putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_OSCCTRL32_OFFSET), + SAM_BSCIF_UNLOCK); + putreg32(regval, SAM_BSCIF_OSCCTRL32); + + /* Wait for OSC32 to be ready */ + + while ((getreg32(SAM_BSCIF_PCLKSR) & BSCIF_INT_OSC32RDY) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enablerc80m + * + * Description: + * Initialiaze the 80 MHz RC oscillator per settings in the board.h header + * file. + * + ****************************************************************************/ + +#ifdef NEED_RC80M +static inline void sam_enablerc80m(void) +{ + uint32_t regval; + + /* Configure and enable RC80M */ + + regval = getreg32(SAM_SCIF_RC80MCR); + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RC80MCR_OFFSET), + SAM_SCIF_UNLOCK); + putreg32(regval | SCIF_RC80MCR_EN, SAM_SCIF_RC80MCR); + + /* Wait for OSC32 to be ready */ + + while (getreg32(SAM_SCIF_RC80MCR) & SCIF_RC80MCR_EN) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enablerc80m + * + * Description: + * Initialiaze the 12/8/4 RC fast oscillator per settings in the board.h + * header file. + * + ****************************************************************************/ + +#ifdef NEED_RCFAST +static inline void sam_enablercfast(void) +{ + uint32_t regval; + + /* Configure and enable RCFAST */ + + regval = getreg32(SAM_SCIF_RCFASTCFG); + regval &= ~SCIF_RCFASTCFG_FRANGE_MASK; + regval |= (SAM_RCFAST_RANGE | SCIF_RCFASTCFG_EN); + + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RCFASTCFG_OFFSET), + SAM_SCIF_UNLOCK); + putreg32(regval, SAM_SCIF_RCFASTCFG); + + /* Wait for RCFAST to be ready */ + + while (getreg32(SAM_SCIF_RCFASTCFG) & SCIF_RCFASTCFG_EN) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enablerc1m + * + * Description: + * Initialiaze the 1M RC oscillator per settings in the board.h header + * file. + * + ****************************************************************************/ + +#ifdef NEED_RC1M +static inline void sam_enablerc1m(void) +{ + uint32_t regval; + + /* Configure and enable RC1M */ + + regval = getreg32(SAM_BSCIF_RC1MCR); + regval &= ~BSCIF_RCFASTCFG_FRANGE_MASK; + regval |= (SAM_RCFAST_RANGE | BSCIF_RCFASTCFG_EN); + + putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_RC1MCR_OFFSET), + SAM_BSCIF_UNLOCK); + putreg32(regval | BSCIF_RC1MCR_CLKOEN, SAM_BSCIF_RC1MCR); + + /* Wait for RCFAST to be ready */ + + while (getreg32(SAM_BSCIF_RC1MCR) & BSCIF_RC1MCR_CLKOEN) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enablerc32k + * + * Description: + * Initialiaze the 23KHz RC oscillator per settings in the board.h header + * file. + * + ****************************************************************************/ + +#ifdef NEED_RC32K +static inline void sam_enablerc32k(void) +{ + uint32_t regval; + + /* Configure and enable RC32K */ + + regval = getreg32(SAM_BSCIF_RC32KCR); + putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_RC32KCR_OFFSET), + SAM_BSCIF_UNLOCK); + putreg32(regval | BSCIF_RC32KCR_EN32K | BSCIF_RC32KCR_EN, SAM_BSCIF_RC32KCR); + + /* Wait for RCFAST to be ready */ + + while (getreg32(SAM_BSCIF_RC32KCR) & BSCIF_RC32KCR_EN) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enableglck9 + * + * Description: + * Enable GLCK9. + * + ****************************************************************************/ + +#ifdef NEED_GLCK9 +static inline void sam_enableglck9(void) +{ + /* Enable the generic clock using the source specified in the board.h + * file. No division is used so that the GCLK9 frequency is the same + * as the source frequency. + */ + + putreg32(SAM_GCLK9_SOURCE_VALUE | SCIF_GCCTRL_CEN, SAM_SCIF_GCCTRL9); +} +#endif + +/**************************************************************************** + * Name: sam_enablepll0 (and its helper sam_pll0putreg()) + * + * Description: + * Initialiaze PLL0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef BOARD_SYSCLK_SOURCE_PLL0 +static inline void sam_pll0putreg(uint32_t regval, uint32_t regaddr, + uint32_t regoffset) +{ + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(regoffset), + SAM_SCIF_UNLOCK); + putreg32(regval, regaddr); +} + +static inline void sam_enablepll0(void) +{ + uint32_t regval; + + /* Clear the PLL0 control register */ + + sam_pll0putreg(0, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET); + + /* Write the selected options */ + + regval = getreg32(SAM_SCIF_PLL0); + regval &= SCIF_PLL0_PLLOPT_MASK; + regval |= SAM_PLL0_OPTIONS; + sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET); + + /* Set up the multiers and dividers */ + + regval = getreg32(SAM_SCIF_PLL0); + regval &= ~(SCIF_PLL0_PLLOSC_MASK | SCIF_PLL0_PLLDIV_MASK | SCIF_PLL0_PLLMUL_MASK); + regval |= ((SAM_PLL0_MUL - 1) << SCIF_PLL0_PLLMUL_SHIFT) | + (BOARD_DFLL0_DIV << SCIF_PLL0_PLLDIV_SHIFT) | + SCIF_PLL0_PLLCOUNT_MAX | SAM_PLL0_SOURCE; + sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET); + + /* And, finally, enable PLL0 */ + + regval = getreg32(SAM_SCIF_PLL0); + regval |= SCIF_PLL_PLLEN; + sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET); + + /* Wait for PLL0 to become locked */ + + while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_PLL0LOCK) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enabledfll0 (and its helper sam_dfll0_putreg32()) + * + * Description: + * Initialiaze DFLL0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef BOARD_SYSCLK_SOURCE_DFLL0 +static inline void sam_dfll0_putreg32(uint32_t regval, uint32_t regaddr, + uint32_t regoffset) +{ + /* Wait until DFLL0 is completes the last setting */ + + while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_DFLL0RDY) == 0); + + /* Then unlock the register and write the next value */ + + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(regoffset), + SAM_SCIF_UNLOCK); + putreg32(regval, regaddr); +} + +static inline void sam_enabledfll0(void) +{ + uint32_t regval; + uint32_t conf; + + /* Set up generic clock source with specified reference clock + * and divider. + */ + + putreg32(0, SAM_SCIF_GCCTRL0); + + /* Set the generic clock 0 source */ + + regval = getreg32(SAM_SCIF_GCCTRL0); + regval &= ~SCIF_GCCTRL_OSCSEL_MASK; + regval |= SAM_DFLLO_REFCLK; + putreg32(regval, SAM_SCIF_GCCTRL0); + + /* Get the generic clock 0 divider */ + + regval = getreg32(SAM_SCIF_GCCTRL0); + regval &= ~(SCIF_GCCTRL_DIVEN | SCIF_GCCTRL_DIV_MASK); + +#if BOARD_DFLL0_DIV > 1 + regval |= SCIF_GCCTRL_DIVEN; + regval |= SCIF_GCCTRL_DIV(((BOARD_DFLL0_DIV + 1) / 2) - 1); +#endif + + putreg32(regval, SAM_SCIF_GCCTRL0); + + /* Sync before reading a dfll conf register */ + + putreg32(SCIF_DFLL0SYNC_SYNC, SAM_SCIF_DFLL0SYNC); + while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_DFLL0RDY) == 0); + + /* Select Closed Loop Mode */ + + conf = getreg32(SAM_SCIF_DFLL0CONF); + conf &= ~SCIF_DFLL0CONF_RANGE_MASK; + conf |= SCIF_DFLL0CONF_MODE; + + /* Select the DFLL0 Frequency Range */ + +#if BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE3 + conf |= SCIF_DFLL0CONF_RANGE3; +#elif BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE2 + conf |= SCIF_DFLL0CONF_RANGE2; +#elif BOARD_DFLL0_FREQUENCY < SCIF_DFLL0CONF_MAX_RANGE1 + conf |= SCIF_DFLL0CONF_RANGE1; +#else + conf |= SCIF_DFLL0CONF_RANGE0; +#endif + + /* Enable the reference generic clock 0 */ + + regval = getreg32(SAM_SCIF_GCCTRL0); + regval |= SCIF_GCCTRL_CEN; + putreg32(regval, SAM_SCIF_GCCTRL0); + + /* Enable DFLL0. Here we assume DFLL0RDY because the DFLL was disabled + * before this function was called. + */ + + putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_DFLL0CONF_OFFSET), + SAM_SCIF_UNLOCK); + putreg32(SCIF_DFLL0CONF_EN, SAM_SCIF_DFLL0CONF); + + /* Configure DFLL0. Note that now we do have to wait for DFLL0RDY before + * every write. + * + * Set the initial coarse and fine step lengths to 4. If this is set + * too high, DFLL0 may fail to lock. + */ + + sam_dfll0_putreg32(SCIF_DFLL0STEP_CSTEP(4) | SCIF_DFLL0STEP_FSTEP(4), + SAM_SCIF_DFLL0STEP, + SAM_SCIF_DFLL0STEP_OFFSET); + + /* Set the DFLL0 multipler register */ + + sam_dfll0_putreg32(BOARD_DFLL0_MUL, SAM_SCIF_DFLL0MUL, + SAM_SCIF_DFLL0MUL_OFFSET); + + /* Set the multipler and spread spectrum generator control registers */ + + sam_dfll0_putreg32(0, SAM_SCIF_DFLL0SSG, SAM_SCIF_DFLL0SSG_OFFSET); + + /* Finally, set the DFLL0 configuration */ + + sam_dfll0_putreg32(conf | SCIF_DFLL0CONF_EN, + SAM_SCIF_DFLL0CONF, SAM_SCIF_DFLL0CONF_OFFSET); + + /* Wait until we are locked on the fine value */ + + while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_DFLL0LOCKF) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_setdividers + * + * Description: + * Configure derived clocks. + * + ****************************************************************************/ + +static inline void sam_setdividers(void) +{ + uint32_t cpusel; + uint32_t pbasel; + uint32_t pbbsel; + uint32_t pbcsel; + uint32_t pbdsel; + + /* Get the register setting for each divider value */ + +#if BOARD_CPU_SHIFT > 0 + cpusel = (PM_CPUSEL(BOARD_CPU_SHIFT - 1)) | PM_CPUSEL_DIV; +#else + cpusel = 0; +#endif + +#if BOARD_PBA_SHIFT > 0 + pbasel = (PM_PBSEL(BOARD_PBA_SHIFT - 1)) | PM_PBSEL_DIV; +#else + pbasel = 0; +#endif + +#if BOARD_PBB_SHIFT >0 + pbbsel = (PM_PBSEL(BOARD_PBB_SHIFT - 1)) | PM_PBSEL_DIV; +#else + pbbsel = 0; +#endif + +#if BOARD_PBC_SHIFT > 0 + pbcsel = (PM_PBSEL(BOARD_PBC_SHIFT - 1)) | PM_PBSEL_DIV; +#else + pbcsel = 0; +#endif + +#if BOARD_PBD_SHIFT > 0 + pbdsel = (PM_PBSEL(BOARD_PBD_SHIFT - 1)) | PM_PBSEL_DIV; +#else + pbdsel = 0; +#endif + + /* Then set the divider values. */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_CPUSEL_OFFSET), SAM_PM_UNLOCK); + putreg32(cpusel, SAM_PM_CPUSEL); + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBASEL_OFFSET), SAM_PM_UNLOCK); + putreg32(pbasel, SAM_PM_PBASEL); + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBBSEL_OFFSET), SAM_PM_UNLOCK); + putreg32(pbbsel, SAM_PM_PBBSEL); + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBCSEL_OFFSET), SAM_PM_UNLOCK); + putreg32(pbcsel, SAM_PM_PBCSEL); + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBDSEL_OFFSET), SAM_PM_UNLOCK); + putreg32(pbdsel, SAM_PM_PBDSEL); +} + +/**************************************************************************** + * Name: sam_enable_fastwakeup + * + * Description: + * Enable FLASH fast wakeup mode. + * + ****************************************************************************/ + +static inline void sam_enable_fastwakeup(void) +{ + uint32_t regval; + + regval = getreg32(SAM_BPM_PMCON); + regval |= BPM_PMCON_FASTWKUP; + putreg32(BPM_UNLOCK_KEY(0xaa) | BPM_UNLOCK_ADDR(SAM_BPM_PMCON_OFFSET), + SAM_BPM_UNLOCK); + putreg32(regval, SAM_BPM_PMCON); +} + +/**************************************************************************** + * Name: set_flash_waitstate + * + * Description: + * Setup one or two FLASH wait states. + * + ****************************************************************************/ + +static inline void set_flash_waitstate(bool waitstate) +{ + uint32_t regval; + + /* Set or clear the FLASH wait state (FWS) bit in the FLASH control + * register (FCR). + */ + + regval = getreg32(SAM_FLASHCALW_FCR); + + if (waitstate) + { + regval |= FLASHCALW_FCR_FWS; + } + else + { + regval &= ~FLASHCALW_FCR_FWS; + } + + putreg32(regval, SAM_FLASHCALW_FCR); +} + +/**************************************************************************** + * Name: sam_flash_readmode + * + * Description: + * Send a FLASH command to enable to disable high speed FLASH read mode. + * + ****************************************************************************/ + +static inline void sam_flash_readmode(uint32_t command) +{ + uint32_t regval; + + /* Make sure that any previous FLASH operation is completed */ + + while ((getreg32(SAM_FLASHCALW_FSR) & FLASHCALW_FSR_FRDY) == 0); + + /* Write the specified FLASH command to the FCMD register */ + + regval = getreg32(SAM_FLASHCALW_FCMD); + regval &= ~FLASHCALW_FCMD_CMD_MASK; + regval |= (FLASHCALW_FCMD_KEY | command); + putreg32(regval, SAM_FLASHCALW_FCMD); + + /* Wait for this FLASH operation to complete */ + + while ((getreg32(SAM_FLASHCALW_FSR) & FLASHCALW_FSR_FRDY) == 0); +} + +/**************************************************************************** + * Name: sam_flash_config + * + * Description: + * Configure FLASH read mode and wait states. + * + * Maximum CPU frequency for 0 and 1 FLASH wait states (FWS) in various modes + * (Table 42-30 in the big data sheet). + * + * ------- ------------------- ---------- ---------- + * Power Flash Read Mode Flash Maximum + * Sclaing Wait Operating + * Mode HSEN HSDIS FASTWKUP States Frequency + * ------- ---- ----- -------- ---------- ---------- + * PS0 X X 1 12MHz + * " " X 0 18MHz + * " " X 1 36MHz + * PS1 X X 1 12MHz + * " " X 0 8MHz + * " " X 1 12MHz + * PS2 X 0 24Mhz + * " " X 1 48MHz + * ------- ---- ----- -------- ---------- ---------- + * + ****************************************************************************/ + +static inline void sam_flash_config(uint32_t cpuclock, uint32_t psm, bool fastwkup) +{ + bool waitstate; + uint32_t command; + +#ifdef CONFIG_SAM34_FLASH_HSEN + /* High speed flash read mode (with power scaling mode == 2). Set one + * wait state if the CPU clock frequency exceeds the threshold value + * and enable high speed read mode. + */ + + waitstate = (cpuclock > FLASH_MAXFREQ_PS2_HSEN_FWS0); + command = FLASHCALW_FCMD_CMD_HSEN; +#else + /* Assume that we will select no wait states and that we will disable high- + * speed read mode. + */ + + waitstate = false; + command = FLASHCALW_FCMD_CMD_HSDIS; + + /* Handle power scaling mode == 0 FLASH configuration */ + + if (psm == 0) + { + /* Power scaling mode 0. We need to set wait state the CPU clock if + * the CPU frequency exceeds a threshold. + */ + + if (cpuclock > FLASH_MAXFREQ_PS0_HSDIS_FWS0) + { + /* Set one wait state */ + + waitstate = true; + + /* Enable high speed read mode if the frequency exceed the maximum + * for the low speed configuration. This mode is not documented + * in the data sheet, but I see that they do this in some Atmel + * code examples. + */ + + if (cpuclock > FLASH_MAXFREQ_PS0_HSDIS_FWS1) + { + /* Enable high speed read mode. */ + + command = FLASHCALW_FCMD_CMD_HSEN; + } + } + + /* The is below the threshold that requires one wait state. But we + * have to check a few more things. + */ + + else + { + /* If FLASH wake-up mode is selected and the we are in the lower + * operating frequency for this mode, then set 1 waitate and + * disable high speed read mode. + */ + + if ((fastwkup == true) && + (cpuclock <= FLASH_MAXFREQ_PS1_HSDIS_FASTWKUP_FWS1)) + { + /* Set one wait state */ + + waitstate = true; + } + } + } + + /* Otherwise, this is power scaling mode 1 */ + + else /* if (psm == 1) */ + { + /* If we are in the lower operating frequency range, then select + * zero wait states. Otherwise, select one wait state. + */ + + if (cpuclock > FLASH_MAXFREQ_PS1_HSDIS_FWS0) + { + /* Set one wait state */ + + waitstate = true; + } + } + +#endif + + /* Set 0 or 1 waitstates */ + + set_flash_waitstate(waitstate); + + /* Enable/disable the high-speed read mode. */ + + sam_flash_readmode(command); +} + +/**************************************************************************** + * Name: sam_mainclk + * + * Description: + * Select the main clock. + * + ****************************************************************************/ + +static inline void sam_mainclk(uint32_t mcsel) +{ + uint32_t regval; + + regval = getreg32(SAM_PM_MCCTRL); + regval &= ~PM_MCCTRL_MCSEL_MASK; + regval |= mcsel; + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_MCCTRL_OFFSET), + SAM_PM_UNLOCK); + putreg32(regval, SAM_PM_MCCTRL); +} + +/**************************************************************************** + * Name: sam_setpsm (and its helper, sam_instantiatepsm()) + * + * Description: + * Switch to the selected power scaling mode. + * + ****************************************************************************/ + +static __ramfunc__ void sam_instantiatepsm(uint32_t regval) +{ + /* Set the BMP PCOM register (containing the new power scaling mode) */ + + putreg32(BPM_UNLOCK_KEY(0xaa) | BPM_UNLOCK_ADDR(SAM_BPM_PMCON_OFFSET), + SAM_BPM_UNLOCK); + putreg32(regval, SAM_BPM_PMCON); + + /* Wait for new power scaling mode to become active. There should be + * timeout on this wait. + */ + + while ((getreg32(SAM_BPM_SR) & BPM_INT_PSOK) == 0); +} + +static inline void sam_setpsm(uint32_t psm) +{ + uint32_t regval; + + /* Setup the PMCON register content fo the new power scaling mode */ + + regval = getreg32(SAM_BPM_PMCON); + regval &= ~BPM_PMCON_PS_MASK; + regval |= (psm | BPM_PMCON_PSCM | BPM_PMCON_PSCREQ); + + /* Then call the RAMFUNC sam_setpsm() to set the new power scaling mode */ + + sam_instantiatepsm(regval); +} + +/**************************************************************************** + * Name: sam_usbclock + * + * Description: + * Setup the USBB GCLK. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV +static inline void sam_usbclock(void) +{ + uint32_t regval = 0; + +#if defined(SAM_CLOCK_USB_PLL0) || defined(SAM_CLOCK_USB_PLL1) + regval |= PM_GCCTRL_PLLSEL; +#endif +#if defined(SAM_CLOCK_USB_OSC1) || defined(SAM_CLOCK_USB_PLL1) + regval |= PM_GCCTRL_OSCSEL; +#endif +#if SAM_CLOCK_USB_DIV > 0 + + + u_avr32_pm_gcctrl.GCCTRL.diven = diven; + u_avr32_pm_gcctrl.GCCTRL.div = div; +#endif + putreg32(regval, SAM_PM_GCCTRL(SAM_PM_GCLK_USBB)) + + /* Enable USB GCLK */ + + regval = getreg32(SAM_PM_GCCTRL(SAM_PM_GCLK_USBB)) + regval |= PM_GCCTRL_CEN; + putreg32(regval, SAM_PM_GCCTRL(SAM_PM_GCLK_USBB)) +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void sam_clockconfig(void) +{ + uint32_t psm; + bool fastwkup; + + /* Enable clocking to the PICOCACHE */ + + sam_picocache(); + + /* Configure dividers for derived clocks. These divider definitions must + * be provided in the board.h header file. + */ + + sam_setdividers(); + + /* Select a power scaling mode and possible fast wakeup so that we get the + * best possible flash performance. The following table shows the maximum + * CPU frequency for 0 and 1 FLASH wait states (FWS) in various modes + * (Table 42-30 in the big data sheet). + * + * ------- ------------------- ---------- ---------- + * Power Flash Read Mode Flash Maximum + * Sclaing Wait Operating + * Mode HSEN HSDIS FASTWKUP States Frequency + * ------- ---- ----- -------- ---------- ---------- + * PS0 X X 1 12MHz + * " " X 0 18MHz + * " " X 1 36MHz + * PS1 X X 1 12MHz + * " " X 0 8MHz + * " " X 1 12MHz + * PS2 X 0 24Mhz + * " " X 1 48MHz + * ------- ---- ----- -------- ---------- ---------- + */ + +#ifdef CONFIG_SAM34_FLASH_HSEN + /* The high speed FLASH mode has been enabled. Select power scaling + * mode 2, no fast wakeup. + */ + + psm = BPM_PMCON_PS2; + fastwkup = false; + +#elif BOARD_CPU_FREQUENCY <= FLASH_MAXFREQ_PS1_HSDIS_FWS1 + /* Not high speed mode and frequency is below the thrshold. We can go to + * power scaling mode 1. + */ + + psm = BPM_PMCON_PS1; + +# if BOARD_CPU_FREQUENCY > FLASH_MAXFREQ_PS1_HSDIS_FWS0 + /* We need to enable fast wakeup */ + + sam_enable_fastwakeup() + fastwkup = true; +# endif +#else + /* Power scaling mode 0, disable high speed mode, no fast wakeup */ + + psm = BPM_PMCON_PS0; + fastwkup = false; +#endif + + /* Enable clock sources: + * + * OSC0: Might by the system clock or the source clock for PLL0 or DFLL0 + * OSC32: Might be source clock for DFLL0 + */ + +#ifdef NEED_OSC0 + /* Enable OSC0 using the settings in board.h */ + + sam_enableosc0(); +#endif + +#ifdef NEED_OSC32K + /* Enable the 32KHz oscillator using the settings in board.h */ + + sam_enableosc32(); +#endif + +#ifdef NEED_RC80M + /* Enable the 32KHz oscillator using the settings in board.h */ + + sam_enablerc80m(); +#endif + +#ifdef NEED_RCFAST + /* Enable the 12/8/4MHz RC fast oscillator using the settings in board.h */ + + sam_enablercrcfast(); +#endif + +#ifdef NEED_RC1M + /* Enable the 1MHz RC oscillator using the settings in board.h */ + + sam_enablerc1m(); +#endif + +#ifdef NEED_RC32K + /* Enable the 32KHz RC oscillator using the settings in board.h */ + + sam_enablerc32k(); +#endif + +#ifdef NEED_GLCK9 + /* Enable the GLCK9 */ + + sam_enableglck9(); +#endif + + /* Switch to the system clock selected by the settings in the board.h + * header file. + */ + +#if defined(BOARD_SYSCLK_SOURCE_RCSYS) + /* Since this function only executes at power up, we know that we are + * already running from RCSYS. + */ + + // sam_mainclk(PM_MCCTRL_MCSEL_RCSYS); +#elif defined(BOARD_SYSCLK_SOURCE_OSC0) + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to OSC0 */ + + sam_mainclk(PM_MCCTRL_MCSEL_OSC0); + +#elif defined(BOARD_SYSCLK_SOURCE_PLL0) + + /* Enable PLL0 using the settings in board.h */ + + sam_enablepll0(); + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to PLL0 */ + + sam_mainclk(PM_MCCTRL_MCSEL_PLL); + +#elif defined(BOARD_SYSCLK_SOURCE_DFLL0) + + /* Enable PLL0 using the settings in board.h */ + + sam_enabledfll0(); + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to DFLL0 */ + + sam_mainclk(PM_MCCTRL_MCSEL_DFLL); + +#elif defined(BOARD_SYSCLK_SOURCE_RC80M) + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to RCM80 */ + + sam_mainclk(PM_MCCTRL_MCSEL_RC80M); + +#elif defined(BOARD_SYSCLK_SOURCE_FCFAST12M) || defined(BOARD_SYSCLK_SOURCE_FCFAST8M) || \ + defined(BOARD_SYSCLK_SOURCE_FCFAST4M) + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to RCFAST */ + + sam_mainclk(PM_MCCTRL_MCSEL_RCFAST); + +#elif defined(BOARD_SYSCLK_SOURCE_RC1M) + + /* Configure FLASH read mode and wait states */ + + sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup); + + /* Then switch the main clock to RC1M */ + + sam_mainclk(PM_MCCTRL_MCSEL_RC1M); + +#else +# error "No SYSCLK source provided" +#endif + + /* Switch to the selected power scaling mode */ + + sam_setpsm(psm); + + /* Enable all selected peripheral cloks */ + + sam_init_periphclks(); + + /* Configure clocking to the USB controller */ + +#ifdef CONFIG_USBDEV + sam_usbc_enableclk(); +#endif +} diff --git a/arch/arm/src/sam34/sam4l_gpio.c b/arch/arm/src/sam34/sam4l_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..4dcefcef55e1a5e3ee8e3fe614a674829377d7b9 --- /dev/null +++ b/arch/arm/src/sam34/sam4l_gpio.c @@ -0,0 +1,563 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam4l_gpio.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_gpio.h" +#include "chip/sam4l_gpio.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +static const char g_portchar[4] = { 'A', 'B', 'C', 'D' }; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpiobase + * + * Description: + * Return the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uintptr_t sam_gpiobase(gpio_pinset_t cfgset) +{ + int port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + return SAM_GPION_BASE(port); +} + +/**************************************************************************** + * Name: sam_gpiopin + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline int sam_gpiopin(gpio_pinset_t cfgset) +{ + return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * This function serves the dual role of putting all pins into a known, + * initial state. Hence, it is overkill for what really needs to be done. + * + ****************************************************************************/ + +static int sam_configinput(uintptr_t base, uint32_t pin, gpio_pinset_t cfgset) +{ + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_GPIO_IERC_OFFSET); + + /* Disable the output driver and select the GPIO function */ + + putreg32(pin, base + SAM_GPIO_ODERC_OFFSET); + putreg32(pin, base + SAM_GPIO_GPERS_OFFSET); + + /* Clear peripheral-only settings (just to make debug easier) */ + + putreg32(pin, base + SAM_GPIO_PMR0C_OFFSET); + putreg32(pin, base + SAM_GPIO_PMR1C_OFFSET); + putreg32(pin, base + SAM_GPIO_PMR2C_OFFSET); + putreg32(pin, base + SAM_GPIO_EVERC_OFFSET); + + /* Clear output-only settings (just to make debug easier) */ + + putreg32(pin, base + SAM_GPIO_ODCR0C_OFFSET); + putreg32(pin, base + SAM_GPIO_ODCR1C_OFFSET); + putreg32(pin, base + SAM_GPIO_OSRR0C_OFFSET); + + /* Clear the interrupt configuration (just to make debug easier) */ + + putreg32(pin, base + SAM_GPIO_IMR0C_OFFSET); + putreg32(pin, base + SAM_GPIO_IMR1C_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_PULL_UP) != 0) + { + putreg32(pin, base + SAM_GPIO_PUERS_OFFSET); + } + else + { + putreg32(pin, base + SAM_GPIO_PUERC_OFFSET); + } + + if ((cfgset & GPIO_PULL_DOWN) != 0) + { + putreg32(pin, base + SAM_GPIO_PDERS_OFFSET); + } + else + { + putreg32(pin, base + SAM_GPIO_PDERC_OFFSET); + } + + /* Check if glitch filtering should be enabled */ + + if ((cfgset & GPIO_GLITCH_FILTER) != 0) + { + putreg32(pin, base + SAM_GPIO_GFERS_OFFSET); + } + else + { + putreg32(pin, base + SAM_GPIO_GFERC_OFFSET); + } + + /* Check if the input Schmitt trigger should be enabled */ + + if ((cfgset & GPIO_SCHMITT_TRIGGER) != 0) + { + putreg32(pin, base + SAM_GPIO_STERS_OFFSET); + } + else + { + putreg32(pin, base + SAM_GPIO_STERC_OFFSET); + } + + return OK; +} + +/**************************************************************************** + * Name: sam_configinterrupt + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configinterrupt(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + int ret; + + /* Just configure the pin as an input, then set the interrupt configuration. + * Here we exploit the fact that sam_configinput() enabled both rising and + * falling edges. + */ + + ret = sam_configinput(base, pin, cfgset); + if (ret == OK) + { + /* Disable rising and falling edge interrupts as requested + * {IMR1, IMR0} Interrupt Mode + * + * 00 Pin Change <-- We already have this + * 01 Rising Edge <-- GPIO_INT_RISING + * 10 Falling Edge <-- GPIO_INT_FALLING + * 11 Reserved + */ + + gpio_pinset_t edges = (cfgset & GPIO_INT_MASK); + + if (edges == GPIO_INT_RISING) + { + /* Rising only.. disable interrupts on the falling edge */ + + putreg32(pin, base + SAM_GPIO_IMR0S_OFFSET); + } + else if (edges == GPIO_INT_FALLING) + { + /* Falling only.. disable interrupts on the rising edge */ + + putreg32(pin, base + SAM_GPIO_IMR1S_OFFSET); + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + * Assumption: + * sam_configinput has been called to put the pin into the default input + * state: + * + * GPER -> GPIO + * PMD0-2 -> zeroed + * ODER -> disabled + * PUER+PDER -> No pull up- or down. + * IER -> Interrupt disabled + * IMR0-1 -> zeroed + * Glitch filter -> disabled + * Output drive -> lowest + * Slew control -> disabled + * Schmitt trigger -> disabled + * Peripheral events -> disabled + * + ****************************************************************************/ + +static inline int sam_configoutput(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + /* Set the output drive strength + * + * {ODCR1, ODCR0} Output drive strength + * + * 00 Lowest drive strength + * 01 ... + * 10 ... + * 11 Highest drive strength + */ + + switch (cfgset & GPIO_DRIVE_MASK) + { + default: + case GPIO_DRIVE_LOW: /* OCDR1=0 OCDR0=0 */ + break; /* This is the current setting */ + + case GPIO_DRIVE_MEDLOW: /* OCDR1=0 OCDR0=1 */ + putreg32(pin, base + SAM_GPIO_ODCR0S_OFFSET); + break; + + case GPIO_DRIVE_MEDHIGH: /* OCDR1=1 OCDR0=0 */ + putreg32(pin, base + SAM_GPIO_ODCR1S_OFFSET); + break; + + case GPIO_DRIVE_HIGH: /* OCDR1=1 OCDR0=1 */ + putreg32(pin, base + SAM_GPIO_ODCR0S_OFFSET); + putreg32(pin, base + SAM_GPIO_ODCR1S_OFFSET); + break; + } + + /* Set the output slew control is requested */ + + if ((cfgset & GPIO_SLEW) != 0) + { + putreg32(pin, base + SAM_GPIO_OSRR0S_OFFSET); + } + + /* Enable the output driver */ + + putreg32(pin, base + SAM_GPIO_ODERS_OFFSET); + + /* And set the initial value of the output */ + + sam_gpiowrite(cfgset, ((cfgset & GPIO_OUTPUT_SET) != 0)); + return OK; +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a GPIO pin driven by a peripheral based on bit-encoded + * description of the pin. + * + * Assumption: + * sam_configinput has been called to put the pin into the default input + * state: + * + * GPER -> GPIO + * PMD0-2 -> zeroed + * ODER -> disabled + * PUER+PDER -> No pull up- or down. + * IER -> Interrupt disabled + * IMR0-1 -> zeroed + * Glitch filter -> disabled + * Output drive -> lowest + * Slew control -> disabled + * Schmitt trigger -> disabled + * Peripheral events -> disabled + * + ****************************************************************************/ + +static inline int sam_configperiph(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + gpio_pinset_t edges; + + /* Select the peripheral function. + * + * {PMR2, PMR1, PMR0} selects peripheral function: + * + * 000 A 100 E + * 001 B 101 F + * 010 C 110 G + * 011 D 111 H + */ + + switch (cfgset & GPIO_FUNC_MASK) + { + default: + case _GPIO_FUNCA: /* Function A 000 */ + break; /* We already have this configuration */ + + case _GPIO_FUNCD: /* Function D 011 */ + putreg32(pin, base + SAM_GPIO_PMR1S_OFFSET); + break; + case _GPIO_FUNCB: /* Function B 001 */ + putreg32(pin, base + SAM_GPIO_PMR0S_OFFSET); + break; + + case _GPIO_FUNCG: /* Function G 110 */ + putreg32(pin, base + SAM_GPIO_PMR2S_OFFSET); + case _GPIO_FUNCC: /* Function C 010 */ + putreg32(pin, base + SAM_GPIO_PMR1S_OFFSET); + break; + + case _GPIO_FUNCE: /* Function E 100 */ + putreg32(pin, base + SAM_GPIO_PMR2S_OFFSET); + break; + case _GPIO_FUNCF: /* Function F 101 */ + putreg32(pin, base + SAM_GPIO_PMR0S_OFFSET); + break; + + case _GPIO_FUNCH: /* Function H 111 */ + putreg32(pin, base + SAM_GPIO_PMR0S_OFFSET); + putreg32(pin, base + SAM_GPIO_PMR1S_OFFSET); + putreg32(pin, base + SAM_GPIO_PMR2S_OFFSET); + break; + } + + /* Check if glitch filtering should be enabled */ + + if ((cfgset & GPIO_GLITCH_FILTER) != 0) + { + putreg32(pin, base + SAM_GPIO_GFERS_OFFSET); + } + + /* Disable rising and falling edge events as requested (of course, + * these do nothing unless events are also enabled. + * + * {IMR1, IMR0} Interrupt Mode + * + * 00 Pin Change <-- We already have this + * 01 Rising Edge <-- GPIO_INT_RISING + * 10 Falling Edge <-- GPIO_INT_FALLING + * 11 Reserved + */ + + edges = (cfgset & GPIO_INT_MASK); + if (edges == GPIO_INT_RISING) + { + /* Rising only.. disable interrupts on the falling edge */ + + putreg32(pin, base + SAM_GPIO_IMR0S_OFFSET); + } + else if (edges == GPIO_INT_FALLING) + { + /* Falling only.. disable interrupts on the rising edge */ + + putreg32(pin, base + SAM_GPIO_IMR1S_OFFSET); + } + + /* REVISIT: Should event generation be enabled now? I am assuming so */ + + if ((cfgset & GPIO_PERIPH_EVENTS) != 0) + { + /* Rising only.. disable interrupts on the falling edge */ + + putreg32(pin, base + SAM_GPIO_EVERS_OFFSET); + } + + /* Finally, drive the pen from the peripheral */ + + putreg32(pin, base + SAM_GPIO_GPERC_OFFSET); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configgpio(gpio_pinset_t cfgset) +{ + gpio_pinset_t inputset; + uintptr_t base = sam_gpiobase(cfgset); + uint32_t pin = sam_gpiopin(cfgset); + int ret; + + /* Put the GPIO in a known state. A generic GPIO input pin. */ + + inputset = GPIO_INPUT | (cfgset & (GPIO_PORT_MASK | GPIO_PIN_MASK)); + ret = sam_configinput(base, pin, inputset); + if (ret == OK) + { + /* Then put the GPIO into the requested state */ + + switch (cfgset & GPIO_MODE_MASK) + { + case GPIO_INPUT: + ret = sam_configinput(base, pin, cfgset); + break; + + case GPIO_OUTPUT: + ret = sam_configoutput(base, pin, cfgset); + break; + + case GPIO_PERIPHERAL: + ret = sam_configperiph(base, pin, cfgset); + break; + + case GPIO_INTERRUPT: + ret = sam_configinterrupt(base, pin, cfgset); + break; + + default: + ret = -EINVAL; + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void sam_gpiowrite(gpio_pinset_t pinset, bool value) +{ + uintptr_t base = sam_gpiobase(pinset); + uint32_t pin = sam_gpiopin(pinset); + + if (value) + { + putreg32(pin, base + SAM_GPIO_OVRS_OFFSET); + } + else + { + putreg32(pin, base + SAM_GPIO_OVRC_OFFSET); + } +} + +/**************************************************************************** + * Name: sam_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool sam_gpioread(gpio_pinset_t pinset) +{ + uintptr_t base = sam_gpiobase(pinset); + uint32_t pin = sam_gpiopin(pinset); + + return (getreg32(base + SAM_GPIO_PVR_OFFSET) & pin) != 0; +} + +/************************************************************************************ + * Function: sam_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int pin; + unsigned int port; + + /* Get the base address associated with the PIO port */ + + pin = sam_gpiopin(pinset); + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = SAM_GPION_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" GPER: %08x PMR0: %08x PMR1: %08x PMR2: %08x\n", + getreg32(base + SAM_GPIO_GPER_OFFSET), getreg32(base + SAM_GPIO_PMR0_OFFSET), + getreg32(base + SAM_GPIO_PMR1_OFFSET), getreg32(base + SAM_GPIO_PMR2_OFFSET)); + lldbg(" ODER: %08x OVR: %08x PVR: %08x PUER: %08x\n", + getreg32(base + SAM_GPIO_ODER_OFFSET), getreg32(base + SAM_GPIO_OVR_OFFSET), + getreg32(base + SAM_GPIO_PVR_OFFSET), getreg32(base + SAM_GPIO_PUER_OFFSET)); + lldbg(" PDER: %08x IER: %08x IMR0: %08x IMR1: %08x\n", + getreg32(base + SAM_GPIO_PDER_OFFSET), getreg32(base + SAM_GPIO_IER_OFFSET), + getreg32(base + SAM_GPIO_IMR0_OFFSET), getreg32(base + SAM_GPIO_IMR1_OFFSET)); + lldbg(" GFER: %08x IFR: %08x ODCR0: %08x ODCR1: %08x\n", + getreg32(base + SAM_GPIO_GFER_OFFSET), getreg32(base + SAM_GPIO_IFR_OFFSET), + getreg32(base + SAM_GPIO_ODCR0_OFFSET), getreg32(base + SAM_GPIO_ODCR1_OFFSET)); + lldbg(" OSRR0: %08x EVER: %08x PARAM: %08x VERS: %08x\n", + getreg32(base + SAM_GPIO_OSRR0_OFFSET), getreg32(base + SAM_GPIO_EVER_OFFSET), + getreg32(base + SAM_GPIO_PARAMETER_OFFSET), getreg32(base + SAM_GPIO_VERSION_OFFSET)); + leave_critical_section(flags); + return OK; +} +#endif + diff --git a/arch/arm/src/sam34/sam4l_gpio.h b/arch/arm/src/sam34/sam4l_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..af9dbb27ecc18fc27df834f271b8a4cd2d15cd3e --- /dev/null +++ b/arch/arm/src/sam34/sam4l_gpio.h @@ -0,0 +1,365 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4l_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4L_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM4L_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 24-bit Encoding. This could be compacted into 16-bits by making the bit usage + * mode specific. However, by giving each bit field a unique position, we handle + * bad combinations of properties safely. + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: MMRR .... .... IIGT .PPB BBBB + * GPIO Output: MM.. .... DDSV .... .PPB BBBB + * Peripheral: MM.. FFFE .... IIG. .PPB BBBB + * ------------ ----------------------------- + * MMRR FFFE DDSV IIGT .PPB BBBB + */ + +/* Input/output/peripheral mode: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: MM.. .... .... .... .... .... + * GPIO Output: MM.. .... .... .... .... .... + * Peripheral: MM.. .... .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (22) /* Bits 22-23: GPIO mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* GPIO Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* GPIO Output */ +# define GPIO_PERIPHERAL (2 << GPIO_MODE_SHIFT) /* Controlled by peripheral */ +# define GPIO_INTERRUPT (3 << GPIO_MODE_SHIFT) /* Interrupting input */ + +/* Pull-up/down resistor control for inputs + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: ..RR .... .... .... .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define GPIO_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */ +#define GPIO_PULL_MASK (3 << GPIO_PULL_SHIFT) +# define GPIO_PULL_NONE (0 << GPIO_PULL_SHIFT) +# define GPIO_PULL_UP (1 << GPIO_PULL_SHIFT) +# define GPIO_PULL_DOWN (2 << GPIO_PULL_SHIFT) +# define GPIO_PULL_BUSKEEPER (3 << GPIO_PULL_SHIFT) + +/* Peripheral Function + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... FFF. .... .... .... .... + */ + +#define GPIO_FUNC_SHIFT (17) /* Bits 17-19: Peripheral function */ +#define GPIO_FUNC_MASK (7 << GPIO_FUNC_SHIFT) +# define _GPIO_FUNCA (0 << GPIO_FUNC_SHIFT) /* Function A */ +# define _GPIO_FUNCB (1 << GPIO_FUNC_SHIFT) /* Function B */ +# define _GPIO_FUNCC (2 << GPIO_FUNC_SHIFT) /* Function C */ +# define _GPIO_FUNCD (3 << GPIO_FUNC_SHIFT) /* Function D */ +# define _GPIO_FUNCE (4 << GPIO_FUNC_SHIFT) /* Function E */ +# define _GPIO_FUNCF (5 << GPIO_FUNC_SHIFT) /* Function F */ +# define _GPIO_FUNCG (6 << GPIO_FUNC_SHIFT) /* Function G */ +# define _GPIO_FUNCH (7 << GPIO_FUNC_SHIFT) /* Function H */ + +/* Extended input/output/peripheral mode: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: MM.. FFF. .... .... .... .... + */ + +#define GPIO_FUNCA (GPIO_PERIPHERAL | _GPIO_FUNCA) /* Function A */ +#define GPIO_FUNCB (GPIO_PERIPHERAL | _GPIO_FUNCB) /* Function B */ +#define GPIO_FUNCC (GPIO_PERIPHERAL | _GPIO_FUNCC) /* Function C */ +#define GPIO_FUNCD (GPIO_PERIPHERAL | _GPIO_FUNCD) /* Function D */ +#define GPIO_FUNCE (GPIO_PERIPHERAL | _GPIO_FUNCE) /* Function E */ +#define GPIO_FUNCF (GPIO_PERIPHERAL | _GPIO_FUNCF) /* Function F */ +#define GPIO_FUNCG (GPIO_PERIPHERAL | _GPIO_FUNCG) /* Function G */ +#define GPIO_FUNCH (GPIO_PERIPHERAL | _GPIO_FUNCH) /* Function H */ + +/* Peripheral event control + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... ...E .... .... .... .... + */ + +#define GPIO_PERIPH_EVENTS (1 << 16) /* Bit 16: Enable peripheral events */ + +/* Output drive control + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... DD.. .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define GPIO_DRIVE_SHIFT (14) /* Bits 14-15: Interrupting input control */ +#define GPIO_DRIVE_MASK (3 << GPIO_INT_SHIFT) /* Lowest drive strength*/ +# define GPIO_DRIVE_LOW (0 << GPIO_INT_SHIFT) +# define GPIO_DRIVE_MEDLOW (1 << GPIO_INT_SHIFT) +# define GPIO_DRIVE_MEDHIGH (2 << GPIO_INT_SHIFT) +# define GPIO_DRIVE_HIGH (3 << GPIO_INT_SHIFT) /* Highest drive strength */ + +/* Output slew rate control + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... ..S. .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define GPIO_SLEW (1 << 13) /* Bit 13: Enable output slew control */ + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .... .... + * GPIO Output: .... .... ...V .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 12) /* Bit 12: Inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* Selections for an interrupting input and peripheral events: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... II.. .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... .... .... II.. .... .... + */ + +#define GPIO_INT_SHIFT (10) /* Bits 10-11: Interrupting input control */ +#define GPIO_INT_MASK (3 << GPIO_INT_SHIFT) +# define GPIO_INT_CHANGE (0 << GPIO_INT_SHIFT) /* Pin change */ +# define GPIO_INT_RISING (1 << GPIO_INT_SHIFT) /* Rising edge */ +# define GPIO_INT_FALLING (2 << GPIO_INT_SHIFT) /* Falling edge */ + +/* These combinations control events. These help to clean up pin definitions. */ + +#define GPIO_EVENT_CHANGE (GPIO_PERIPH_EVENTS | GPIO_INT_CHANGE) /* Pin change */ +#define GPIO_EVENT_RISING (GPIO_PERIPH_EVENTS | GPIO_INT_RISING) /* Rising edge */ +#define GPIO_EVENT_FALLING (GPIO_PERIPH_EVENTS | GPIO_INT_FALLING) /* Falling edge */ + +/* Enable input/periphal glitch filter + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... ..G. .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... .... .... ..G. .... .... + */ + +#define GPIO_GLITCH_FILTER (1 << 9) /* Bit 9: Enable input/peripheral glitch filter */ + +/* Input Schmitt trigger + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... ...T .... .... + * GPIO Output: .... .... .... .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define GPIO_SCHMITT_TRIGGER (1 << 8) /* Bit 8: Enable Input Schmitt trigger */ + +/* This identifies the GPIO port: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... .PP. .... + * GPIO Output: .... .... .... .... .PP. .... + * Peripheral: .... .... .... .... .PP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * GPIO Input: .... .... .... .... ...B BBBB + * GPIO Output: .... .... .... .... ...B BBBB + * Peripheral: .... .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 24-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4L_GPIO_H */ diff --git a/arch/arm/src/sam34/sam4l_periphclks.c b/arch/arm/src/sam34/sam4l_periphclks.c new file mode 100644 index 0000000000000000000000000000000000000000..29e9d3cbf3a04f93d634e1109e04a5fb63382ef1 --- /dev/null +++ b/arch/arm/src/sam34/sam4l_periphclks.c @@ -0,0 +1,691 @@ +/**************************************************************************** + * arch/avr/src/sam34/sam4l_periphclks.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_clkinit.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_arch.h" + +#include "up_internal.h" +#include "chip/sam4l_pm.h" + +#include "sam4l_periphclks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USBC source clock selection */ + +#ifdef CONFIG_SAM34_USBC +# if defined(BOARD_USBC_SRC_OSC0) +# define SAM_USBC_GCLK_SOURCE SCIF_GCCTRL_OSCSEL_OSC0 +# elif defined(BOARD_USBC_SRC_PLL0) +# define SAM_USBC_GCLK_SOURCE SCIF_GCCTRL_OSCSEL_PLL0 +# elif defined(BOARD_USBC_SRC_DFLL) +# define SAM_USBC_GCLK_SOURCE SCIF_GCCTRL_OSCSEL_DFLL0 +# elif defined(BOARD_USBC_SRC_GCLKIN0) +# define SAM_USBC_GCLK_SOURCE SCIF_GCCTRL_OSCSEL_GCLKIN0 +# else +# error No USBC GCLK7 source clock defined +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_init_cpumask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * CPU mask register. + * + ****************************************************************************/ + +static inline void sam_init_cpumask(void) +{ + uint32_t mask = 0; + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_OCD + mask |= PM_CPUMASK_OCD; /* On-Chip Debug */ +#endif +#endif + + /* Save the new CPU mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_CPUMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_CPUMASK); +} + +/**************************************************************************** + * Name: sam_init_hsbmask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * HSB mask register. + * + ****************************************************************************/ + +static inline void sam_init_hsbmask(void) +{ + /* Select the non-optional peripherals */ + + uint32_t mask = (PM_HSBMASK_FLASHCALW | PM_HSBMASK_APBB | + PM_HSBMASK_APBC | PM_HSBMASK_APBD); + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_PDCA + mask |= PM_HSBMASK_PDCA; /* PDCA */ +#endif +#ifdef CONFIG_SAM34_HRAMC1 + mask |= PM_HSBMASK_HRAMC1; /* HRAMC1 (picoCache RAM) */ +#endif +#ifdef CONFIG_SAM34_USBC + mask |= PM_HSBMASK_USBC; /* USBC */ +#endif +#ifdef CONFIG_SAM34_CRCCU + mask |= PM_HSBMASK_CRCCU; /* CRCCU */ +#endif +#ifdef CONFIG_SAM34_APBA + mask |= PM_HSBMASK_APBA; /* APBA bridge */ +#endif +#ifdef CONFIG_SAM34_AESA + mask |= PM_HSBMASK_AESA; /* AESA */ +#endif +#endif + + /* Save the new HSB mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_HSBMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_HSBMASK); +} + +/**************************************************************************** + * Name: sam_init_pbamask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * PBA mask register. + * + ****************************************************************************/ + +static inline void sam_init_pbamask(void) +{ + /* Select the non-optional peripherals */ + + uint32_t mask = 0; + uint32_t divmask = 0; + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_IISC + mask |= PM_PBAMASK_IISC; /* IISC */ +#endif +#ifdef CONFIG_SAM34_SPI0 + mask |= PM_PBAMASK_SPI; /* SPI */ +#endif +#ifdef CONFIG_SAM34_TC0 + mask |= PM_PBAMASK_TC0; /* TC0 */ + divmask |= PM_PBADIVMASK_TIMER_CLOCKS; +#endif +#ifdef CONFIG_SAM34_TC1 + mask |= PM_PBAMASK_TC1; /* TC1 */ + divmask |= PM_PBADIVMASK_TIMER_CLOCKS; +#endif +#ifdef CONFIG_SAM34_TWIM0 + mask |= PM_PBAMASK_TWIM0; /* TWIM0 */ +#endif +#ifdef CONFIG_SAM34_TWIS0 + mask |= PM_PBAMASK_TWIS0; /* TWIS0 */ +#endif +#ifdef CONFIG_SAM34_TWIM1 + mask |= PM_PBAMASK_TWIM1; /* TWIM1 */ +#endif +#ifdef CONFIG_SAM34_TWIS1 + mask |= PM_PBAMASK_TWIS1; /* TWIS1 */ +#endif +#ifdef CONFIG_SAM34_USART0 + mask |= PM_PBAMASK_USART0; /* USART0 */ + divmask |= PM_PBADIVMASK_CLK_USART; +#endif +#ifdef CONFIG_SAM34_USART1 + mask |= PM_PBAMASK_USART1; /* USART1 */ + divmask |= PM_PBADIVMASK_CLK_USART; +#endif +#ifdef CONFIG_SAM34_USART2 + mask |= PM_PBAMASK_USART2; /* USART2 */ + divmask |= PM_PBADIVMASK_CLK_USART; +#endif +#ifdef CONFIG_SAM34_USART3 + mask |= PM_PBAMASK_USART3; /* USART3 */ + divmask |= PM_PBADIVMASK_CLK_USART; +#endif +#ifdef CONFIG_SAM34_ADCIFE + mask |= PM_PBAMASK_ADCIFE; /* ADCIFE */ +#endif +#ifdef CONFIG_SAM34_DACC + mask |= PM_PBAMASK_DACC; /* DACC */ +#endif +#ifdef CONFIG_SAM34_ACIFC + mask |= PM_PBAMASK_ACIFC; /* ACIFC */ +#endif +#ifdef CONFIG_SAM34_GLOC + mask |= PM_PBAMASK_GLOC; /* GLOC */ +#endif +#ifdef CONFIG_SAM34_ABDACB + mask |= PM_PBAMASK_ABDACB; /* ABDACB */ +#endif +#ifdef CONFIG_SAM34_TRNG + mask |= PM_PBAMASK_TRNG; /* TRNG */ +#endif +#ifdef CONFIG_SAM34_PARC + mask |= PM_PBAMASK_PARC; /* PARC */ +#endif +#ifdef CONFIG_SAM34_CATB + mask |= PM_PBAMASK_CATB; /* CATB */ +#endif +#ifdef CONFIG_SAM34_TWIM2 + mask |= PM_PBAMASK_TWIM2; /* TWIM2 */ +#endif +#ifdef CONFIG_SAM34_TWIM3 + mask |= PM_PBAMASK_TWIM3; /* TWIM3 */ +#endif +#ifdef CONFIG_SAM34_LCDCA + mask |= PM_PBAMASK_LCDCA; /* LCDCA */ +#endif +#endif + + /* Save the new PBA mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBAMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_PBAMASK); + + /* Set the peripheral divider mask as necessary */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBADIVMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(divmask, SAM_PM_PBADIVMASK); +} + +/**************************************************************************** + * Name: sam_init_pbbmask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * PBB mask register. + * + ****************************************************************************/ + +static inline void sam_init_pbbmask(void) +{ + /* Select the non-optional peripherals */ + + uint32_t mask = PM_PBBMASK_FLASHCALW; + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_HRAMC1 + mask |= PM_PBBMASK_HRAMC1; /* HRAMC1 */ +#endif +#ifdef CONFIG_SAM34_HMATRIX + mask |= PM_PBBMASK_HMATRIX; /* HMATRIX */ +#endif +#ifdef CONFIG_SAM34_PDCA + mask |= PM_PBBMASK_PDCA; /* PDCA */ +#endif +#ifdef CONFIG_SAM34_CRCCU + mask |= PM_PBBMASK_CRCCU; /* CRCCU */ +#endif +#ifdef CONFIG_SAM34_USBC + mask |= PM_PBBMASK_USBC; /* USBC */ +#endif +#ifdef CONFIG_SAM34_PEVC + mask |= PM_PBBMASK_PEVC; /* PEVC */ +#endif +#endif + + /* Save the new PBB mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBBMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_PBBMASK); +} + +/**************************************************************************** + * Name: sam_init_pbcmask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * PBC mask register. + * + ****************************************************************************/ + +static inline void sam_init_pbcmask(void) +{ + /* Select the non-optional peripherals */ + + uint32_t mask = (PM_PBCMASK_PM | PM_PBCMASK_SCIF | PM_PBCMASK_GPIO); + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_CHIPID + mask |= PM_PBCMASK_CHIPID; /* CHIPID */ +#endif +#ifdef CONFIG_SAM34_FREQM + mask |= PM_PBCMASK_FREQM; /* FREQM */ +#endif +#endif + + /* Save the new PBC mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBCMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_PBCMASK); +} + +/**************************************************************************** + * Name: sam_init_pbdmask + * + * Description: + * Called during boot to enable clocking on selected peripherals in the + * PBD mask register. + * + ****************************************************************************/ + +static inline void sam_init_pbdmask(void) +{ + /* Select the non-optional peripherals */ + + uint32_t mask = (PM_PBDMASK_BPM | PM_PBDMASK_BSCIF); + + /* OR in the user selected peripherals */ + +#ifdef CONFIG_SAM34_RESET_PERIPHCLKS +#ifdef CONFIG_SAM34_AST + mask |= PM_PBDMASK_AST; /* AST */ +#endif +#ifdef CONFIG_SAM34_WDT + mask |= PM_PBDMASK_WDT; /* WDT */ +#endif +#ifdef CONFIG_SAM34_EIC + mask |= PM_PBDMASK_EIC; /* EIC */ +#endif +#ifdef CONFIG_SAM34_PICOUART + mask |= PM_PBDMASK_PICOUART; /* PICOUART */ +#endif +#endif + + /* Save the new PBD mask */ + + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBDMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(mask, SAM_PM_PBDMASK); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_init_periphclks + * + * Description: + * Called during boot to enable clocking on all selected peripherals. + * + ****************************************************************************/ + +void sam_init_periphclks(void) +{ + sam_init_cpumask(); + sam_init_hsbmask(); + sam_init_pbamask(); + sam_init_pbbmask(); + sam_init_pbcmask(); + sam_init_pbdmask(); +} + +/**************************************************************************** + * Name: sam_modifyperipheral + * + * Description: + * This is a convenience function that is intended to be used to enable + * or disable peripheral module clocking. + * + ****************************************************************************/ + +void sam_modifyperipheral(uintptr_t regaddr, uint32_t clrbits, + uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + /* Make sure that the following operations are atomic */ + + flags = enter_critical_section(); + + /* Enable/disabling clocking */ + + regval = getreg32(regaddr); + regval &= ~clrbits; + regval |= setbits; + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(regaddr - SAM_PM_BASE), + SAM_PM_UNLOCK); + putreg32(regval, regaddr); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_pba_modifydivmask + * + * Description: + * This is a convenience function that is intended to be used to modify + * bits in the PBA divided clock (DIVMASK) register. + * + ****************************************************************************/ + +void sam_pba_modifydivmask(uint32_t clrbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + /* Make sure that the following operations are atomic */ + + flags = enter_critical_section(); + + /* Modify the PBA DIVMASK */ + + regval = getreg32(SAM_PM_PBADIVMASK); + regval &= ~clrbits; + regval |= setbits; + putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBADIVMASK_OFFSET), + SAM_PM_UNLOCK); + putreg32(regval, SAM_PM_PBADIVMASK); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_pba_enableperipheral + * + * Description: + * This is a convenience function to enable a peripheral on the APBA + * bridge. + * + ****************************************************************************/ + +void sam_pba_enableperipheral(uint32_t bitset) +{ + irqstate_t flags; + + /* The following operations must be atomic */ + + flags = enter_critical_section(); + + /* Enable the APBA bridge if necessary */ + + if (getreg32(SAM_PM_PBAMASK) == 0) + { + sam_hsb_enableperipheral(PM_HSBMASK_APBA); + } + + leave_critical_section(flags); + + /* Enable the module */ + + sam_enableperipheral(SAM_PM_PBAMASK, bitset); +} + +/**************************************************************************** + * Name: sam_pba_disableperipheral + * + * Description: + * This is a convenience function to disable a peripheral on the APBA + * bridge. + * + ****************************************************************************/ + +void sam_pba_disableperipheral(uint32_t bitset) +{ + irqstate_t flags; + + /* Disable clocking to the module */ + + sam_disableperipheral(SAM_PM_PBAMASK, bitset); + + /* Disable the APBA bridge if possible */ + + flags = enter_critical_section(); + + if (getreg32(SAM_PM_PBAMASK) == 0) + { + sam_hsb_disableperipheral(PM_HSBMASK_APBA); + } + + /* Disable PBA UART divided clock if none of the UARTS are in use */ + + if ((getreg32(SAM_PM_PBAMASK) & PM_PBAMASK_UARTS) == 0) + { + sam_pba_disabledivmask(PM_PBADIVMASK_CLK_USART); + } + + /* Disable PBA TIMER divided clocks if none of the UARTS are in use */ + + if ((getreg32(SAM_PM_PBAMASK) & PM_PBAMASK_TIMERS) == 0) + { + sam_pba_disabledivmask(PM_PBADIVMASK_TIMER_CLOCKS); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_pbb_enableperipheral + * + * Description: + * This is a convenience function to enable a peripheral on the APBB + * bridge. + * + ****************************************************************************/ + +void sam_pbb_enableperipheral(uint32_t bitset) +{ + irqstate_t flags; + + /* The following operations must be atomic */ + + flags = enter_critical_section(); + + /* Enable the APBB bridge if necessary */ + + if (getreg32(SAM_PM_PBBMASK) == 0) + { + sam_hsb_enableperipheral(PM_HSBMASK_APBB); + } + + leave_critical_section(flags); + + /* Enable the module */ + + sam_enableperipheral(SAM_PM_PBBMASK, bitset); +} + +/**************************************************************************** + * Name: sam_pbb_disableperipheral + * + * Description: + * This is a convenience function to disable a peripheral on the APBA + * bridge. + * + ****************************************************************************/ + +void sam_pbb_disableperipheral(uint32_t bitset) +{ + irqstate_t flags; + + /* Disable clocking to the peripheral module */ + + sam_disableperipheral(SAM_PM_PBBMASK, bitset); + + /* Disable the APBB bridge if possible */ + + flags = enter_critical_section(); + + if (getreg32(SAM_PM_PBBMASK) == 0) + { + sam_hsb_disableperipheral(PM_HSBMASK_APBB); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_usbc_enableclk + * + * Description: + * Enable clocking for the USBC using settings from the board.h header files. + * + * "The USBC has two bus clocks connected: One High Speed Bus clock + * (CLK_USBC_AHB) and one Peripheral Bus clock (CLK_USBC_APB). These clocks + * are generated by the Power Manager. Both clocks are enabled at reset + * and can be disabled by the Power Manager. It is recommended to disable + * the USBC before disabling the clocks, to avoid freezing the USBC in + * an undefined state. + * + * "To follow the usb data rate at 12Mbit/s in full-speed mode, the + * CLK_USBC_AHB clock should be at minimum 12MHz. + * + * "The 48MHz USB clock is generated by a dedicated generic clock from + * the SCIF module. Before using the USB, the user must ensure that the + * USB generic clock (GCLK_USBC) is enabled at 48MHz in the SCIF module." + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_USBC +void sam_usbc_enableclk(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Enable USBC clocking (possibly along with the PBB peripheral bridge) */ + + flags = enter_critical_section(); + sam_hsb_enableperipheral(PM_HSBMASK_USBC); + sam_pbb_enableperipheral(PM_PBBMASK_USBC); + + /* Reset generic clock 7 */ + + putreg32(0, SAM_SCIF_GCCTRL7); + + /* Set the generic clock source */ + + regval = getreg32(SAM_SCIF_GCCTRL7); + regval &= ~SCIF_GCCTRL_OSCSEL_MASK; + regval |= SAM_USBC_GCLK_SOURCE; + putreg32(regval, SAM_SCIF_GCCTRL7); + + /* Set the generic clock divider */ + + regval = getreg32(SAM_SCIF_GCCTRL7); + regval &= ~(SCIF_GCCTRL_DIVEN | SCIF_GCCTRL_DIV_MASK); + +#if BOARD_USBC_GCLK_DIV > 1 + regval |= SCIF_GCCTRL_DIVEN; + regval |= SCIF_GCCTRL_DIV(((divider + 1) / 2) - 1); +#endif + + putreg32(regval, SAM_SCIF_GCCTRL7); + + /* Enable the generic clock */ + + regval = getreg32(SAM_SCIF_GCCTRL7); + regval |= SCIF_GCCTRL_CEN; + putreg32(regval, SAM_SCIF_GCCTRL7); + leave_critical_section(flags); +} +#endif /* CONFIG_SAM34_USBC */ + +/**************************************************************************** + * Name: sam_usbc_disableclk + * + * Description: + * Disable clocking to the USBC. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_USBC +void sam_usbc_disableclk(void) +{ + putreg32(0, SAM_SCIF_GCCTRL7); + sam_pbb_enableperipheral(PM_PBBMASK_USBC); + sam_hsb_enableperipheral(PM_HSBMASK_USBC); +} +#endif /* CONFIG_SAM34_USBC */ diff --git a/arch/arm/src/sam34/sam4l_periphclks.h b/arch/arm/src/sam34/sam4l_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..c092e243aa4fb6b8e3d622d4b4f368132e9ecb08 --- /dev/null +++ b/arch/arm/src/sam34/sam4l_periphclks.h @@ -0,0 +1,374 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4l_periphclks.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4L_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM4L_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip/sam4l_pm.h" + +#ifdef CONFIG_ARCH_CHIP_SAM4L + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* SAM4L helper macros */ + +#define sam_enableperipheral(a,s) sam_modifyperipheral(a,0,s) +#define sam_disableperipheral(a,s) sam_modifyperipheral(a,s,0) + +#define sam_cpu_enableperipheral(s) sam_enableperipheral(SAM_PM_CPUMASK,s) +#define sam_hsb_enableperipheral(s) sam_enableperipheral(SAM_PM_HSBMASK,s) +#define sam_pbc_enableperipheral(s) sam_enableperipheral(SAM_PM_PBCMASK,s) +#define sam_pbd_enableperipheral(s) sam_enableperipheral(SAM_PM_PBDMASK,s) + +#define sam_cpu_disableperipheral(s) sam_disableperipheral(SAM_PM_CPUMASK,s) +#define sam_hsb_disableperipheral(s) sam_disableperipheral(SAM_PM_HSBMASK,s) +#define sam_pbc_enableperipheral(s) sam_enableperipheral(SAM_PM_PBCMASK,s) +#define sam_pbd_enableperipheral(s) sam_enableperipheral(SAM_PM_PBDMASK,s) + +#define sam_pba_enabledivmask(s) sam_pba_modifydivmask(0,s) +#define sam_pba_disabledivmask(s) sam_pba_modifydivmask(s,0) + +/* Macros to enable clocking to individual peripherals */ + +#define sam_aesa_enableclk() sam_hsb_enableperipheral(PM_HSBMASK_AESA) +#define sam_iisc_enableclk() sam_pba_enableperipheral(PM_PBAMASK_IISC) +#define sam_spi0_enableclk() sam_pba_enableperipheral(PM_PBAMASK_SPI) + +#define sam_tc0_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_TC0); \ + sam_pba_enabledivmask(PM_PBADIVMASK_TIMER_CLOCKS); \ + } while (0) + +#define sam_tc1_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_TC1); \ + sam_pba_enabledivmask(PM_PBADIVMASK_TIMER_CLOCKS); \ + } while (0) + +#define sam_twim0_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIM0) +#define sam_twis0_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIS0) +#define sam_twim1_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIM1) +#define sam_twis1_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIS1) + +#define sam_usart0_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_USART0); \ + sam_pba_enabledivmask(PM_PBADIVMASK_CLK_USART); \ + } while (0) + +#define sam_usart1_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_USART1); \ + sam_pba_enabledivmask(PM_PBADIVMASK_CLK_USART); \ + } while (0) + +#define sam_usart2_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_USART2); \ + sam_pba_enabledivmask(PBA_DIVMASK_CLK_USART); \ + } while (0) + +#define sam_usart3_enableclk() \ + do { \ + sam_pba_enableperipheral(PM_PBAMASK_USART3); \ + sam_pba_enabledivmask(PBA_DIVMASK_CLK_USART); \ + } while (0) + +#define sam_adcife_enableclk() sam_pba_enableperipheral(PM_PBAMASK_ADCIFE) +#define sam_dacc_enableclk() sam_pba_enableperipheral(PM_PBAMASK_DACC) +#define sam_acifc_enableclk() sam_pba_enableperipheral(PM_PBAMASK_ACIFC) +#define sam_gloc_enableclk() sam_pba_enableperipheral(PM_PBAMASK_GLOC) +#define sam_abdacb_enableclk() sam_pba_enableperipheral(PM_PBAMASK_ABDACB) +#define sam_trng_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TRNG) +#define sam_parc_enableclk() sam_pba_enableperipheral(PM_PBAMASK_PARC) +#define sam_catb_enableclk() sam_pba_enableperipheral(PM_PBAMASK_CATB) +#define sam_twim2_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIM2) +#define sam_twim3_enableclk() sam_pba_enableperipheral(PM_PBAMASK_TWIM3) +#define sam_lcdca_enableclk() sam_pba_enableperipheral(PM_PBAMASK_LCDCA) + +#define sam_flashcalw_enableclk() \ + do { \ + sam_hsb_enableperipheral(PM_HSBMASK_FLASHCALW); \ + sam_pbb_enableperipheral(PM_PBBMASK_FLASHCALW); \ + } while (0) + +#define sam_picocache_enableclk() \ + do { \ + sam_hsb_enableperipheral(PM_HSBMASK_HRAMC1); \ + sam_pbb_enableperipheral(PM_PBBMASK_HRAMC1); \ + } while (0) + +#define sam_hmatrix_enableclk() sam_pbb_enableperipheral(PM_PBBMASK_HMATRIX) + +#define sam_pdca_enableclk() \ + do { \ + sam_hsb_enableperipheral(PM_HSBMASK_PDCA); \ + sam_pbb_enableperipheral(PM_PBBMASK_PDCA); \ + } while (0) + +#define sam_crccu_enableclk() \ + do { \ + sam_hsb_enableperipheral(PM_HSBMASK_CRCCU); \ + sam_pbb_enableperipheral(PM_PBBMASK_CRCCU); \ + } while (0) + +#define sam_pevc_enableclk() sam_pbb_enableperipheral(PM_PBBMASK_PEVC) +#define sam_pm_enableclk() sam_pbc_enableperipheral(PM_PBCMASK_PM) +#define sam_chipid_enableclk() sam_pbc_enableperipheral(PM_PBCMASK_CHIPID) +#define sam_scif_enableclk() sam_pbc_enableperipheral(PM_PBCMASK_SCIF) +#define sam_freqm_enableclk() sam_pbc_enableperipheral(PM_PBCMASK_FREQM) +#define sam_gpio_enableclk() sam_pbc_enableperipheral(PM_PBCMASK_GPIO) +#define sam_bpm_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_BPM) +#define sam_bscif_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_BSCIF) +#define sam_ast_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_AST) +#define sam_wdt_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_WDT) +#define sam_eic_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_EIC) +#define sam_picouart_enableclk() sam_pbd_enableperipheral(PM_PBDMASK_PICOUART) + +/* Macros to disable clocking to individual peripherals */ + +#define sam_aesa_disableclk() sam_hsb_disableperipheral(PM_HSBMASK_AESA) +#define sam_iisc_disableclk() sam_pba_disableperipheral(PM_PBAMASK_IISC) +#define sam_spi0_disableclk() sam_pba_disableperipheral(PM_PBAMASK_SPI) +#define sam_tc0_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TC0) +#define sam_tc1_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TC1) +#define sam_twim0_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIM0) +#define sam_twis0_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIS0) +#define sam_twim1_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIM1) +#define sam_twis1_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIS1) +#define sam_usart0_disableclk() sam_pba_disableperipheral(PM_PBAMASK_USART0) +#define sam_usart1_disableclk() sam_pba_disableperipheral(PM_PBAMASK_USART1) +#define sam_usart2_disableclk() sam_pba_disableperipheral(PM_PBAMASK_USART2) +#define sam_usart3_disableclk() sam_pba_disableperipheral(PM_PBAMASK_USART3) +#define sam_adcife_disableclk() sam_pba_disableperipheral(PM_PBAMASK_ADCIFE) +#define sam_dacc_disableclk() sam_pba_disableperipheral(PM_PBAMASK_DACC) +#define sam_acifc_disableclk() sam_pba_disableperipheral(PM_PBAMASK_ACIFC) +#define sam_gloc_disableclk() sam_pba_disableperipheral(PM_PBAMASK_GLOC) +#define sam_abdacb_disableclk() sam_pba_disableperipheral(PM_PBAMASK_ABDACB) +#define sam_trng_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TRNG) +#define sam_parc_disableclk() sam_pba_disableperipheral(PM_PBAMASK_PARC) +#define sam_catb_disableclk() sam_pba_disableperipheral(PM_PBAMASK_CATB) +#define sam_twim2_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIM2) +#define sam_twim3_disableclk() sam_pba_disableperipheral(PM_PBAMASK_TWIM3) +#define sam_lcdca_disableclk() sam_pba_disableperipheral(PM_PBAMASK_LCDCA) +#define sam_flashcalw_disableclk() sam_pba_disableperipheral(PM_HSBMASK_FLASHCALW) + +#define sam_picocache_disableclk() \ + do { \ + sam_hsb_disableperipheral(PM_HSBMASK_HRAMC1); \ + sam_pbb_disableperipheral(PM_PBBMASK_HRAMC1); \ + } while (0) + +#define sam_hmatrix_disableclk() sam_pbb_disableperipheral(PM_PBBMASK_HMATRIX) + +#define sam_pdca_disableclk() \ + do { \ + sam_hsb_disableperipheral(PM_HSBMASK_PDCA); \ + sam_pbb_disableperipheral(PM_PBBMASK_PDCA); \ + } while (0) + +#define sam_crccu_disableclk() \ + do { \ + sam_hsb_disableperipheral(PM_HSBMASK_CRCCU); \ + sam_pbb_disableperipheral(PM_PBBMASK_CRCCU); \ + } while (0) + +#define sam_pevc_disableclk() sam_pbb_disableperipheral(PM_PBBMASK_PEVC) +#define sam_pm_disableclk() sam_pbc_disableperipheral(PM_PBCMASK_PM) +#define sam_chipid_disableclk() sam_pbc_disableperipheral(PM_PBCMASK_CHIPID) +#define sam_scif_disableclk() sam_pbc_disableperipheral(PM_PBCMASK_SCIF) +#define sam_freqm_disableclk() sam_pbc_disableperipheral(PM_PBCMASK_FREQM) +#define sam_gpio_disableclk() sam_pbc_disableperipheral(PM_PBCMASK_GPIO) +#define sam_bpm_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_BPM) +#define sam_bscif_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_BSCIF) +#define sam_ast_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_AST) +#define sam_wdt_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_WDT) +#define sam_eic_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_EIC) +#define sam_picouart_disableclk() sam_pbd_disableperipheral(PM_PBDMASK_PICOUART) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_init_periphclks + * + * Description: + * Called during boot to enable clocking on all selected peripherals. + * + ************************************************************************************/ + +void sam_init_periphclks(void); + +/************************************************************************************ + * Name: sam_modifyperipheral + * + * Description: + * This is a convenience function that is intended to be used to enable or disable + * module clocking. + * + ************************************************************************************/ + +void sam_modifyperipheral(uintptr_t regaddr, uint32_t clrbits, uint32_t setbits); + +/************************************************************************************ + * Name: sam_pba_modifydivmask + * + * Description: + * This is a convenience function that is intended to be used to modify bits in + * the PBA divided clock (DIVMASK) register. + * + ************************************************************************************/ + +void sam_pba_modifydivmask(uint32_t clrbits, uint32_t setbits); + +/************************************************************************************ + * Name: sam_pba_enableperipheral + * + * Description: + * This is a convenience function to enable a peripheral on the APBA bridge. + * + ************************************************************************************/ + +void sam_pba_enableperipheral(uint32_t bitset); + +/************************************************************************************ + * Name: sam_pba_disableperipheral + * + * Description: + * This is a convenience function to disable a peripheral on the APBA bridge. + * + ************************************************************************************/ + +void sam_pba_disableperipheral(uint32_t bitset); + +/************************************************************************************ + * Name: sam_pbb_enableperipheral + * + * Description: + * This is a convenience function to enable a peripheral on the APBB bridge. + * + ************************************************************************************/ + +void sam_pbb_enableperipheral(uint32_t bitset); + +/************************************************************************************ + * Name: sam_pbb_disableperipheral + * + * Description: + * This is a convenience function to disable a peripheral on the APBA bridge. + * + ************************************************************************************/ + +void sam_pbb_disableperipheral(uint32_t bitset); + +/************************************************************************************ + * Name: sam_usbc_enableclk + * + * Description: + * Enable clocking for the USBC using settings from the board.h header files. + * + * "The USBC has two bus clocks connected: One High Speed Bus clock + * (CLK_USBC_AHB) and one Peripheral Bus clock (CLK_USBC_APB). These clocks + * are generated by the Power Manager. Both clocks are enabled at reset + * and can be disabled by the Power Manager. It is recommended to disable + * the USBC before disabling the clocks, to avoid freezing the USBC in + * an undefined state. + * + * "To follow the usb data rate at 12Mbit/s in full-speed mode, the + * CLK_USBC_AHB clock should be at minimum 12MHz. + * + * "The 48MHz USB clock is generated by a dedicated generic clock from + * the SCIF module. Before using the USB, the user must ensure that the + * USB generic clock (GCLK_USBC) is enabled at 48MHz in the SCIF module." + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_USBC +void sam_usbc_enableclk(void); +#endif + +/************************************************************************************ + * Name: sam_usbc_disableclk + * + * Description: + * Disable clocking to the USBC. + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_USBC +void sam_usbc_disableclk(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_ARCH_CHIP_SAM4L */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4L_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam4s_gpio.h b/arch/arm/src/sam34/sam4s_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..34ffc0aa314f3156917846a1279b53219304ee67 --- /dev/null +++ b/arch/arm/src/sam34/sam4s_gpio.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4s_gpio.h + * General Purpose Input/Output (GPIO) definitions for the SAM4S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4S_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM4S_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#define GPIO_HAVE_PULLDOWN 1 +#define GPIO_HAVE_PERIPHCD 1 +#define GPIO_HAVE_SCHMITT 1 +#undef GPIO_HAVE_DELAYR + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 32-bit Encoding: + * + * MMMC CCCC III. VPPB BBBB + */ + +/* Input/Output mode: + * + * MMM. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (17) /* Bits 17-19: GPIO mode */ +#define GPIO_MODE_MASK (7 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Output */ +# define GPIO_PERIPHA (2 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (3 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define GPIO_PERIPHC (4 << GPIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define GPIO_PERIPHD (5 << GPIO_MODE_SHIFT) /* Controlled by periph D signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * ...C CCCC .... .... .... + */ + +#define GPIO_CFG_SHIFT (12) /* Bits 12-16: GPIO configuration bits */ +#define GPIO_CFG_MASK (31 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_PULLDOWN (2 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-down */ +# define GPIO_CFG_DEGLITCH (4 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (8 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ +# define GPIO_CFG_SCHMITT (16 << GPIO_CFG_SHIFT) /* Bit 13: Schmitt trigger */ + +/* Additional interrupt modes: + * + * .... .... III. .... .... + */ + +#define GPIO_INT_SHIFT (9) /* Bits 9-11: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... .... V... .... + */ + +#define GPIO_OUTPUT_SET (1 << 7) /* Bit 7: Initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * .... .... .... .PP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4S_GPIO_H */ diff --git a/arch/arm/src/sam34/sam4s_periphclks.h b/arch/arm/src/sam34/sam4s_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..1477ef2532cff0fd193b7b9be99d107515558a82 --- /dev/null +++ b/arch/arm/src/sam34/sam4s_periphclks.h @@ -0,0 +1,159 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4s_periphclks.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM4S_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM4S_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() sam_enableperiph0(SAM_PID_SUPC) +#define sam_rstc_enableclk() sam_enableperiph0(SAM_PID_RSTC) +#define sam_rtc_enableclk() sam_enableperiph0(SAM_PID_RTC) +#define sam_rtt_enableclk() sam_enableperiph0(SAM_PID_RTT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_pmc_enableclk() sam_enableperiph0(SAM_PID_PMC) +#define sam_eefc0_enableclk() sam_enableperiph0(SAM_PID_EEFC0) +#define sam_eefc1_enableclk() sam_enableperiph0(SAM_PID_EEFC1) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_hsmci_enableclk() sam_enableperiph0(SAM_PID_HSMCI) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_ssc_enableclk() sam_enableperiph0(SAM_PID_SSC) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph0(SAM_PID_TC5) +#define sam_adc12b_enableclk() sam_enableperiph0(SAM_PID_ADC12B) +#define sam_dacc_enableclk() sam_enableperiph0(SAM_PID_DACC) +#define sam_pwm_enableclk() sam_enableperiph0(SAM_PID_PWM) +#define sam_crccu_enableclk() sam_enableperiph1(SAM_PID_CRCCU) +#define sam_acc_enableclk() sam_enableperiph1(SAM_PID_ACC) +#define sam_udp_enableclk() sam_enableperiph1(SAM_PID_UDP) + +#define sam_supc_disableclk() sam_disableperiph0(SAM_PID_SUPC) +#define sam_rstc_disableclk() sam_disableperiph0(SAM_PID_RSTC) +#define sam_rtc_disableclk() sam_disableperiph0(SAM_PID_RTC) +#define sam_rtt_disableclk() sam_disableperiph0(SAM_PID_RTT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_pmc_disableclk() sam_disableperiph0(SAM_PID_PMC) +#define sam_eefc0_disableclk() sam_disableperiph0(SAM_PID_EEFC0) +#define sam_eefc1_disableclk() sam_disableperiph0(SAM_PID_EEFC1) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_hsmci_disableclk() sam_disableperiph0(SAM_PID_HSMCI) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_ssc_disableclk() sam_disableperiph0(SAM_PID_SSC) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph0(SAM_PID_TC5) +#define sam_adc12b_disableclk() sam_disableperiph0(SAM_PID_ADC) +#define sam_dacc_disableclk() sam_disableperiph0(SAM_PID_DACC) +#define sam_pwm_disableclk() sam_disableperiph0(SAM_PID_PWM) +#define sam_crccu_disableclk() sam_disableperiph1(SAM_PID_CRCCU) +#define sam_acc_disableclk() sam_disableperiph1(SAM_PID_ACC) +#define sam_udp_disableclk() sam_disableperiph1(SAM_PID_UDP) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM4S_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam_aes.c b/arch/arm/src/sam34/sam_aes.c new file mode 100644 index 0000000000000000000000000000000000000000..29634e69c7738c3b67d14d16d5f94b04d2028c90 --- /dev/null +++ b/arch/arm/src/sam34/sam_aes.c @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_aes.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Max Nekludov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_periphclks.h" +#include "sam_aes.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AES_BLOCK_SIZE 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t lock; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void aes_lock(void) +{ + sem_wait(&lock); +} + +static void aes_unlock(void) +{ + sem_post(&lock); +} + +static void aes_memcpy(void *out, const void *in, size_t size) +{ + size_t i; + size_t wcount = size / 4; + for (i = 0; i < wcount; i++, out = (uint8_t *)out + 4, in = (uint8_t *)in + 4) + { + *(uint32_t *)out = *(uint32_t *)in; + } +} + +static void aes_encryptblock(void *out, const void *in) +{ + aes_memcpy((void *)SAM_AES_IDATAR, in, AES_BLOCK_SIZE); + + putreg32(AES_CR_START, SAM_AES_CR); + + while (!(getreg32(SAM_AES_ISR) & AES_ISR_DATRDY)); + + if (out) + { + aes_memcpy(out, (void *)SAM_AES_ODATAR, AES_BLOCK_SIZE); + } +} + +static int aes_setup_mr(uint32_t keysize, int mode, int encrypt) +{ + uint32_t regval = AES_MR_SMOD_MANUAL_START | AES_MR_CKEY; + + if (encrypt) + { + regval |= AES_MR_CIPHER_ENCRYPT; + } + else + { + regval |= AES_MR_CIPHER_DECRYPT; + } + + switch (keysize) + { + case 16: + regval |= AES_MR_KEYSIZE_AES128; + break; + case 24: + regval |= AES_MR_KEYSIZE_AES192; + break; + case 32: + regval |= AES_MR_KEYSIZE_AES256; + break; + default: + return -EINVAL; + } + + switch (mode) + { + case AES_MODE_ECB: + regval |= AES_MR_OPMOD_ECB; + break; + case AES_MODE_CBC: + regval |= AES_MR_OPMOD_CBC; + break; + case AES_MODE_CTR: + regval |= AES_MR_OPMOD_CTR; + break; + case AES_MODE_CFB: + regval |= AES_MR_OPMOD_CFB; + break; + default: + return -EINVAL; + } + + putreg32(regval, SAM_AES_MR); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int aes_cypher(void *out, const void *in, uint32_t size, const void *iv, + const void *key, uint32_t keysize, int mode, int encrypt) +{ + int res = OK; + + if (size % 16) + { + return -EINVAL; + } + + aes_lock(); + + res = aes_setup_mr(keysize, mode & AES_MODE_MASK, encrypt); + if (res) + { + aes_unlock(); + return res; + } + + aes_memcpy((void *)SAM_AES_KEYWR, key, keysize); + if (iv) + { + aes_memcpy((void *)SAM_AES_IVR, iv, AES_BLOCK_SIZE); + } + + while (size) + { + if ((mode & AES_MODE_MAC) == 0) + { + aes_encryptblock(out, in); + out = (char *)out + AES_BLOCK_SIZE; + } + else if (size == AES_BLOCK_SIZE) + { + aes_encryptblock(out, in); + } + else + { + aes_encryptblock(NULL, in); + } + + in = (char *)in + AES_BLOCK_SIZE; + size -= AES_BLOCK_SIZE; + } + + aes_unlock(); + return res; +} + +int up_aesinitialize() +{ + sem_init(&lock, 0, 1); + sam_aes_enableclk(); + putreg32(AES_CR_SWRST, SAM_AES_CR); + return OK; +} diff --git a/arch/arm/src/sam34/sam_aes.h b/arch/arm/src/sam34/sam_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..e0e6f114e2308fc03121c93b5511d2a691ba0a66 --- /dev/null +++ b/arch/arm/src/sam34/sam_aes.h @@ -0,0 +1,67 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam4cm_aes.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Max Nekludov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_AES_H +#define __ARCH_ARM_SRC_SAM34_SAM_AES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_CHIP_SAM4CM +# include "chip/sam4cm_aes.h" +#else +# error "Unknown chip for AES" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAM34_SAM_AES_H */ \ No newline at end of file diff --git a/arch/arm/src/sam34/sam_allocateheap.c b/arch/arm/src/sam34/sam_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..3e1d5e6efe9a612b207d782b6c6febdeeaf2a56e --- /dev/null +++ b/arch/arm/src/sam34/sam_allocateheap.c @@ -0,0 +1,385 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_allocateheap.c + * + * Copyright (C) 2010, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "sam_mpuinit.h" +#include "sam_periphclks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* All SAM's have SRAM0. The SAM3U family also have SRAM1 and possibly + * NFCSRAM. NFCSRAM may not be used, however, if NAND support is enabled. + * In addition, the SAM3U and SAM4S have external SRAM at CS0 (EXTSRAM0). + * Support for external SRAM at CS1-3 is not fully implemented. + */ + +#undef HAVE_SRAM1_REGION /* Assume no internal SRAM1 */ +#undef HAVE_NFCSRAM_REGION /* Assume no NFC SRAM */ +#undef HAVE_EXTSRAM0_REGION /* Assume no external SRAM at CS0 */ +#undef HAVE_EXTSRAM1_REGION /* Assume no external SRAM at CS1 */ +#undef HAVE_EXTSRAM2_REGION /* Assume no external SRAM at CS2 */ +#undef HAVE_EXTSRAM3_REGION /* Assume no external SRAM at CS3 */ + +/* Check if external SRAM is supported and, if so, it is is intended + * to be used as heap. + */ + +#if !defined(CONFIG_SAM34_EXTSRAM0) || !defined(CONFIG_SAM34_EXTSRAM0HEAP) +# undef CONFIG_SAM34_EXTSRAM0SIZE +# define CONFIG_SAM34_EXTSRAM0SIZE 0 +#endif + +#if !defined(CONFIG_SAM34_EXTSRAM1) || !defined(CONFIG_SAM34_EXTSRAM1HEAP) +# undef CONFIG_SAM34_EXTSRAM1SIZE +# define CONFIG_SAM34_EXTSRAM1SIZE 0 +#endif + +#if !defined(CONFIG_SAM34_EXTSRAM2) || !defined(CONFIG_SAM34_EXTSRAM2HEAP) +# undef CONFIG_SAM34_EXTSRAM2SIZE +# define CONFIG_SAM34_EXTSRAM2SIZE 0 +#endif + +#if !defined(CONFIG_SAM34_EXTSRAM3) || !defined(CONFIG_SAM34_EXTSRAM3HEAP) +# undef CONFIG_SAM34_EXTSRAM3SIZE +# define CONFIG_SAM34_EXTSRAM3SIZE 0 +#endif + +/* SAM3U, SAM3X, and SAM3A Unique memory configurations */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# ifdef CONFIG_SAM34_NAND +# undef SAM34_NFCSRAM_SIZE +# define SAM34_NFCSRAM_SIZE 0 +# endif + +# if SAM34_SRAM1_SIZE > 0 +# if CONFIG_MM_REGIONS > 1 +# define HAVE_SRAM1_REGION 1 +# else +# warning "CONFIG_MM_REGIONS < 2: SRAM1 not included in HEAP" +# endif +# endif + +# if SAM34_NFCSRAM_SIZE > 0 +# if CONFIG_MM_REGIONS > 2 +# define HAVE_NFCSRAM_REGION +# else +# warning "CONFIG_MM_REGIONS < 3: NFC SRAM not included in HEAP" +# endif + +# if CONFIG_SAM34_EXTSRAM0SIZE > 0 +# if CONFIG_MM_REGIONS > 3 +# define HAVE_EXTSRAM0_REGION 1 +# else +# warning "CONFIG_MM_REGIONS < 4: External SRAM not included in HEAP" +# endif +# endif + +# elif CONFIG_SAM34_EXTSRAM0SIZE > 0 +# if CONFIG_MM_REGIONS > 2 +# define HAVE_EXTSRAM0_REGION 1 +# else +# warning "CONFIG_MM_REGIONS < 3: External SRAM not included in HEAP" +# endif +# endif +#else + +/* The SAM4S and SAM4L may have only internal SRAM0 and external SRAM0 */ + +# if CONFIG_SAM34_EXTSRAM0SIZE > 0 +# if CONFIG_MM_REGIONS > 1 +# define HAVE_EXTSRAM0_REGION 1 +# else +# warning "CONFIG_MM_REGIONS < 2: External SRAM not included in HEAP" +# endif +# endif +#endif + +/* Check common SRAM0 configuration */ + +#if CONFIG_RAM_END > (SAM_INTSRAM0_BASE+SAM34_SRAM0_SIZE) +# error "CONFIG_RAM_END is beyond the end of SRAM0" +# undef CONFIG_RAM_END +# define CONFIG_RAM_END (SAM_INTSRAM0_BASE+SAM34_SRAM0_SIZE) +#elif CONFIG_RAM_END < (SAM_INTSRAM0_BASE+SAM34_SRAM0_SIZE) +# warning "CONFIG_RAM_END is before end of SRAM0... not all of SRAM0 used" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + sam_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + /* The SAM3U also have SRAM1 and NFCSRAM, We will add these as regions + * the first two additional memory regions if we have them. + */ + +#ifdef HAVE_SRAM1_REGION + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_INTSRAM1_BASE, SAM34_SRAM1_SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_INTSRAM1_BASE, SAM34_SRAM1_SIZE); + +#endif /* HAVE_SRAM1_REGION */ + +#ifdef HAVE_NFCSRAM_REGION +#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) + /* In the 3X/3A family I note that clocking must appled to the SMC module + * in order for the NFCS SRAM to be functional. I don't recall such an + * issue with the 3U. + */ + + sam_smc_enableclk(); +#endif + + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_NFCSRAM_BASE, SAM34_NFCSRAM_SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_NFCSRAM_BASE, SAM34_NFCSRAM_SIZE); + +#endif /* HAVE_NFCSRAM_REGION */ + +#ifdef HAVE_EXTSRAM0_REGION + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS0_BASE, CONFIG_SAM34_EXTSRAM0SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS0_BASE, CONFIG_SAM34_EXTSRAM0SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#ifdef HAVE_EXTSRAM1_REGION + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS1_BASE, CONFIG_SAM34_EXTSRAM1SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS1_BASE, CONFIG_SAM34_EXTSRAM1SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#ifdef HAVE_EXTSRAM2_REGION + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS2_BASE, CONFIG_SAM34_EXTSRAM2SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS2_BASE, CONFIG_SAM34_EXTSRAM2SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#ifdef HAVE_EXTSRAM3_REGION + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS3_BASE, CONFIG_SAM34_EXTSRAM3SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS3_BASE, CONFIG_SAM34_EXTSRAM3SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ +} +#endif /* CONFIG_MM_REGIONS > 1 */ diff --git a/arch/arm/src/sam34/sam_clockconfig.c b/arch/arm/src/sam34/sam_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..3dce96b02e5530e9db55cc6a469195176ce3def2 --- /dev/null +++ b/arch/arm/src/sam34/sam_clockconfig.c @@ -0,0 +1,392 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_clockconfig.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_clockconfig.h" +#include "chip/sam_pmc.h" +#include "chip/sam_eefc.h" +#include "chip/sam_wdt.h" +#include "chip/sam_supc.h" +#include "chip/sam_matrix.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* PMC register settings based on the board configuration values defined + * in board.h + */ + +#define BOARD_CKGR_MOR (PMC_CKGR_MOR_KEY | BOARD_CKGR_MOR_MOSCXTST | \ + PMC_CKGR_MOR_MOSCRCEN | PMC_CKGR_MOR_MOSCXTEN) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# define BOARD_CKGR_PLLAR (PMC_CKGR_PLLAR_ONE | BOARD_CKGR_PLLAR_MUL | \ + BOARD_CKGR_PLLAR_STMODE | BOARD_CKGR_PLLAR_COUNT | \ + BOARD_CKGR_PLLAR_DIV) +#elif defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM3X) +# define BOARD_CKGR_PLLAR (PMC_CKGR_PLLAR_ONE | BOARD_CKGR_PLLAR_MUL | \ + BOARD_CKGR_PLLAR_COUNT | BOARD_CKGR_PLLAR_DIV) +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# define BOARD_CKGR_PLLAR (PMC_CKGR_PLLAR_ONE | BOARD_CKGR_PLLAR_MUL | \ + BOARD_CKGR_PLLAR_COUNT | BOARD_CKGR_PLLAR_DIV) +# define BOARD_CKGR_PLLBR (BOARD_CKGR_PLLBR_DIV | BOARD_CKGR_PLLBR_MUL | \ + BOARD_CKGR_PLLBR_COUNT | BOARD_CKGR_PLLBR_SRCB) +#elif defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define BOARD_CKGR_PLLAR (PMC_CKGR_PLLAR_ONE | BOARD_CKGR_PLLAR_MUL | \ + BOARD_CKGR_PLLAR_COUNT | BOARD_CKGR_PLLAR_DIV) +#endif + +#define BOARD_PMC_MCKR_FAST (BOARD_PMC_MCKR_PRES | PMC_MCKR_CSS_MAIN) +#define BOARD_PMC_MCKR (BOARD_PMC_MCKR_PRES | BOARD_PMC_MCKR_CSS) + +#define BOARD_CKGR_UCKR (BOARD_CKGR_UCKR_UPLLCOUNT | PMC_CKGR_UCKR_UPLLEN) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_efcsetup + * + * Description: + * Configure 2 waitstates for embedded flash access + * + ****************************************************************************/ + +static inline void sam_efcsetup(void) +{ +#if defined(EEFC_FMR_CLOE) + putreg32(EEFC_FMR_CLOE | (BOARD_FWS << EEFC_FMR_FWS_SHIFT), SAM_EEFC0_FMR); +#else + putreg32((BOARD_FWS << EEFC_FMR_FWS_SHIFT), SAM_EEFC0_FMR); +#endif +#if !defined(CONFIG_ARCH_CHIP_SAM4E) + putreg32((BOARD_FWS << EEFC_FMR_FWS_SHIFT), SAM_EEFC1_FMR); +#endif +} + +/**************************************************************************** + * Name: sam_wdtsetup + * + * Description: + * Disable the watchdog timer + * + ****************************************************************************/ + +static inline void sam_wdtsetup(void) +{ +#if !defined(CONFIG_SAM34_WDT) || (defined(CONFIG_WDT_ENABLED_ON_RESET) && defined(CONFIG_WDT_DISABLE_ON_RESET)) + putreg32(WDT_MR_WDDIS, SAM_WDT_MR); +#endif +} + +/**************************************************************************** + * Name: sam_supcsetup + * + * Description: + * Select the external slow clock + * + ****************************************************************************/ + +static inline void sam_supcsetup(void) +{ + /* Check if the 32-kHz is already selected */ + + if ((getreg32(SAM_SUPC_SR) & SUPC_SR_OSCSEL) == 0) + { + uint32_t delay; + + putreg32((SUPC_CR_XTALSEL | SUPR_CR_KEY), SAM_SUPC_CR); + for (delay = 0; + (getreg32(SAM_SUPC_SR) & SUPC_SR_OSCSEL) == 0 && delay < UINT32_MAX; + delay++); + } +} + +/**************************************************************************** + * Name: sam_pmcwait + * + * Description: + * Wait for the specified PMC status bit to become "1" + * + ****************************************************************************/ + +static void sam_pmcwait(uint32_t bit) +{ + volatile uint32_t delay; + + for (delay = 0; + (getreg32(SAM_PMC_SR) & bit) == 0 && delay < UINT32_MAX; + delay++); +} + +/**************************************************************************** + * Name: sam_pmcsetup + * + * Description: + * Initialize clocking + * + ****************************************************************************/ + +static inline void sam_pmcsetup(void) +{ + uint32_t regval; + + /* Enable main oscillator (if it has not already been selected) */ + + if ((getreg32(SAM_PMC_CKGR_MOR) & PMC_CKGR_MOR_MOSCSEL) == 0) + { + /* "When the MOSCXTEN bit and the MOSCXTCNT are written in CKGR_MOR to + * enable the main oscillator, the MOSCXTS bit in the Power Management + * Controller Status Register (PMC_SR) is cleared and the counter starts + * counting down on the slow clock divided by 8 from the MOSCXTCNT + * value. ... When the counter reaches 0, the MOSCXTS bit is set, + * indicating that the main clock is valid." + */ + + putreg32(BOARD_CKGR_MOR, SAM_PMC_CKGR_MOR); + sam_pmcwait(PMC_INT_MOSCXTS); + } + + /* "Switch to the main oscillator. The selection is made by writing the + * MOSCSEL bit in the Main Oscillator Register (CKGR_MOR). The switch of + * the Main Clock source is glitch free, so there is no need to run out + * of SLCK, PLLACK or UPLLCK in order to change the selection. The MOSCSELS + * bit of the power Management Controller Status Register (PMC_SR) allows + * knowing when the switch sequence is done." + * + * MOSCSELS: Main Oscillator Selection Status + * 0 = Selection is done + * 1 = Selection is in progress + */ + + putreg32((BOARD_CKGR_MOR | PMC_CKGR_MOR_MOSCSEL), SAM_PMC_CKGR_MOR); + sam_pmcwait(PMC_INT_MOSCSELS); + + /* "Select the master clock. "The Master Clock selection is made by writing + * the CSS field (Clock Source Selection) in PMC_MCKR (Master Clock Register). + * The prescaler supports the division by a power of 2 of the selected clock + * between 1 and 64, and the division by 3. The PRES field in PMC_MCKR programs + * the prescaler. Each time PMC_MCKR is written to define a new Master Clock, + * the MCKRDY bit is cleared in PMC_SR. It reads 0 until the Master Clock is + * established. + */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_CSS_MASK; + regval |= PMC_MCKR_CSS_MAIN; + putreg32(regval, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); + +#if defined(CONFIG_ARCH_CHIP_SAM4E) + /* Setup the maximum value for the PLLAR multiplier. The PMMR register + * "defines the maximum value of multiplication factor that can be sent to + * PLLA. Any value of the MULA bitfield ... above PLLA_MMAX is saturated + * to PLLA_MMAX. + */ + + //putreg32(PMC_PMMR_MASK, SAM_PMC_PMMR); +#endif + + /* Setup PLLA and wait for LOCKA */ + + putreg32(BOARD_CKGR_PLLAR, SAM_PMC_CKGR_PLLAR); + sam_pmcwait(PMC_INT_LOCKA); + +#ifdef CONFIG_ARCH_CHIP_SAM4CM + /* Setup PLLB and wait for LOCKB */ + + putreg32(BOARD_CKGR_PLLBR, SAM_PMC_CKGR_PLLBR); + sam_pmcwait(PMC_INT_LOCKB); +#endif + +#ifdef CONFIG_USBDEV + /* Setup UTMI for USB and wait for LOCKU */ + +#ifdef SAM_PMC_CKGR_UCKR + /* This MCU has a USB PLL. Configure the UPLL and wait for it to lock. */ + + regval = getreg32(SAM_PMC_CKGR_UCKR); + regval |= BOARD_CKGR_UCKR; + putreg32(regval, SAM_PMC_CKGR_UCKR); + sam_pmcwait(PMC_INT_LOCKU); + +#else + /* This board does not have a UPLL. Use the output of PLLA or PLLA + * (depending on USBS) and setup the PLL divisor to generate the 48MHz + * USB clock. + */ + + regval = (BOARD_PMC_USBS | BOARD_PMC_USBDIV); + putreg32(regval, SAM_PMC_USB); + +#if 0 /* Done in the UDP driver */ + /* Set the UDP bit in the SCER register to enable the USB clock output */ + + regval = getreg32(SAM_PMC_SCER); + regval |= PMC_UDP; + putreg32(regval, SAM_PMC_SCER); + +#endif /* 0 */ +#endif /* SAM_PMC_CKGR_UCKR */ +#endif /* CONFIG_USBDEV */ + + /* Switch to the fast clock and wait for MCKRDY */ + + putreg32(BOARD_PMC_MCKR_FAST, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); + + putreg32(BOARD_PMC_MCKR, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); +} + +/**************************************************************************** + * Name: sam_enabledefaultmaster and sam_disabledefaultmaster + * + * Description: + * Enable/disable default master access + * + ****************************************************************************/ + +static inline void sam_enabledefaultmaster(void) +{ + uint32_t regval; + + /* Set default master: SRAM0 -> Cortex-M3 System */ + + regval = getreg32(SAM_MATRIX_SCFG0); + regval |= (MATRIX_SCFG0_FIXEDDEFMSTR_ARMS | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG0); + + /* Set default master: SRAM1 -> Cortex-M3 System */ + + regval = getreg32(SAM_MATRIX_SCFG1); + regval |= (MATRIX_SCFG1_FIXEDDEFMSTR_ARMS | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG1); + + /* Set default master: Internal flash0 -> Cortex-M3 Instruction/Data */ + + regval = getreg32(SAM_MATRIX_SCFG3); + regval |= (MATRIX_SCFG3_FIXEDDEFMSTR_ARMC | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG3); +} + +#if 0 /* Not used */ +static inline void sam_disabledefaultmaster(void) +{ + uint32_t regval; + + /* Clear default master: SRAM0 -> Cortex-M3 System */ + + regval = getreg32(SAM_MATRIX_SCFG0); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG0); + + /* Clear default master: SRAM1 -> Cortex-M3 System */ + + regval = getreg32(SAM_MATRIX_SCFG1); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG1); + + /* Clear default master: Internal flash0 -> Cortex-M3 Instruction/Data */ + + regval = getreg32(SAM_MATRIX_SCFG3); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG3); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. (After power-on reset, the SAM3/4 is initially running on + * a 4MHz internal RC clock). This function also performs other low-level chip + * initialization of the chip including EFC, master clock, IRQ & watchdog + * configuration. + * + ************************************************************************************/ + +void sam_clockconfig(void) +{ + /* Configure embedded flash access */ + + sam_efcsetup(); + + /* Configure the watchdog timer */ + + sam_wdtsetup(); + + /* Setup the supply controller to use the external slow clock */ + + sam_supcsetup(); + + /* Initialize clocking */ + + sam_pmcsetup(); + + /* Optimize CPU setting for speed */ + + sam_enabledefaultmaster(); +} diff --git a/arch/arm/src/sam34/sam_clockconfig.h b/arch/arm/src/sam34/sam_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..fb3d3f6eeb27e6f7be4f09d8d3f4609a104fb7df --- /dev/null +++ b/arch/arm/src/sam34/sam_clockconfig.h @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_clockconfig.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_SAM34_SAM_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void sam_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_CLOCKCONFIG_H */ diff --git a/arch/arm/src/sam34/sam_cmcc.c b/arch/arm/src/sam34/sam_cmcc.c new file mode 100644 index 0000000000000000000000000000000000000000..3ffee694749644306e3020b0f938390c73f3b68b --- /dev/null +++ b/arch/arm/src/sam34/sam_cmcc.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_cmcc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" +#include "chip/sam_cmcc.h" +#include "sam_cmcc.h" + +#ifdef CONFIG_SAM34_CMCC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CMCC_MASK (CMCC_CACHE_LINE_SIZE-1) + +#if CMCC_CACHE_LINE_SIZE == 4 +# define CMCC_SHIFT 2 +#elif CMCC_CACHE_LINE_SIZE == 8 +# define CMCC_SHIFT 3 +#elif CMCC_CACHE_LINE_SIZE == 16 +# define CMCC_SHIFT 4 +#elif CMCC_CACHE_LINE_SIZE == 32 +# define CMCC_SHIFT 5 +#else +# error Unknown cache line size +#endif + +#define ALIGN_UP(a) (((a)+CMCC_MASK) & ~CMCC_MASK) +#define ALIGN_DOWN(a) ((a) & ~CMCC_MASK) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_cmcc_enable + * + * Description: + * Enable the Cortex-M Cache Controller + * + ****************************************************************************/ + +void sam_cmcc_enable(void) +{ + /* "On reset, the cache controller data entries are all invalidated and the + * cache is disabled. The cache is transparent to processor operations. The + * cache controller is activated with its configuration registers. The + * configuration interface is memory mapped in the private peripheral bus. + * + * "Use the following sequence to enable the cache controller. + * + * "1. Verify that the cache controller is disabled, reading the value of the + * CSTS (cache status) field of the CMCC_SR register. + * "2. Enable the cache controller, writing 1 to the CEN (cache enable) field + * of the CMCC_CTRL register." + */ + + if ((getreg32(SAM_CMCC_SR) & CMCC_SR_CSTS) == 0) + { + putreg32(CMCC_CTRL_CEN, SAM_CMCC_CTRL); + } +} + +/**************************************************************************** + * Name: sam_cmcc_disable + * + * Description: + * Disable the Cortex-M Cache Controller + * + ****************************************************************************/ + +void sam_cmcc_disable(void) +{ + /* "1. Disable the cache controller, writing 0 to the CEN field of the + * CMCC_CTRL register. + * "2. Check CSTS field of the CMCC_SR to verify that the cache is + * successfully disabled. + */ + + putreg32(0, SAM_CMCC_CTRL); + while ((getreg32(SAM_CMCC_SR) & CMCC_SR_CSTS) != 0); +} + +/**************************************************************************** + * Name: sam_cmcc_invalidate + * + * Description: + * Invalidate a range of addresses. Note: These addresses should be + * aligned with the beginning and end of cache lines. Otherwise, values + * at the edges of the region will also be invalidated! + * + ****************************************************************************/ + +void sam_cmcc_invalidate(uintptr_t start, uintptr_t end) +{ + uintptr_t addr; + uint32_t regval; + ssize_t size; + int index; + int way; + + /* Get the aligned addresses and size (in bytes) for the memory region + * to be invalidated. + */ + + start = ALIGN_DOWN(start); + end = ALIGN_UP(end); + size = end - start + 1; + + /* If this is a large region (as big as the cache), then just invalidate + * the entire cache the easy way. + * + * CacheSize = CacheLineSize * NCacheLines * NWays + * CacheAddressRange = CacheLineSize * NCacheLines = CacheSize / NWays + * + * Example: CacheSize = 2048, CacheLineSize=16, NWays=4: + * + * CacheAddressRange = 2048 / 4 = 512 + * NCacheLines = 32 + */ + + if (size >= (CMCC_CACHE_SIZE / CMCC_NWAYS)) + { + sam_cmcc_invalidateall(); + return; + } + + /* "When an invalidate by line command is issued the cache controller resets + * the valid bit information of the decoded cache line. As the line is no + * longer valid the replacement counter points to that line. + * + * "Use the following sequence to invalidate one line of cache. + * + * "1. Disable the cache controller, writing 0 to the CEN field of the + * CMCC_CTRL register. + * "2. Check CSTS field of the CMCC_SR to verify that the cache is + * successfully disabled. + * "3. Perform an invalidate by line writing the bit set {index, way} in + * the CMCC_MAINT1 register. + * "4. Enable the cache controller, writing 1 to the CEN field of the + * CMCC_CTRL register." + */ + + /* Disable the cache controller */ + + sam_cmcc_disable(); + + /* Invalidate the address region */ + + for (addr = start, index = (int)(start >> CMCC_SHIFT); + addr <= end; + addr += CMCC_CACHE_LINE_SIZE, index++) + { + regval = CMCC_MAINT1_INDEX(index); + for (way = 0; way < CMCC_NWAYS; way++) + { + putreg32(regval | CMCC_MAINT1_WAY(way), SAM_CMCC_MAINT1); + } + } + + /* Re-enable the cache controller */ + + sam_cmcc_enable(); +} + +/**************************************************************************** + * Name: sam_cmcc_invalidateall + * + * Description: + * Invalidate the entire cache + * + ****************************************************************************/ + +void sam_cmcc_invalidateall(void) +{ + /* "To invalidate all cache entries: + * + * " Write 1 to the INVALL field of the CMCC_MAINT0 register." + */ + + putreg32(CMCC_MAINT0_INVALL, SAM_CMCC_MAINT0); +} + +#endif /* CONFIG_SAM34_CMCC */ diff --git a/arch/arm/src/sam34/sam_cmcc.h b/arch/arm/src/sam34/sam_cmcc.h new file mode 100644 index 0000000000000000000000000000000000000000..6593ef6fe157c3866f59499eb93f3787d6cb654b --- /dev/null +++ b/arch/arm/src/sam34/sam_cmcc.h @@ -0,0 +1,136 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_cmcc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_CMCC_H +#define __ARCH_ARM_SRC_SAM34_SAM_CMCC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#ifdef CONFIG_SAM34_CMCC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_cmcc_enable + * + * Description: + * Enable the Cortex-M Cache Controller + * + ****************************************************************************/ + +void sam_cmcc_enable(void); + +/**************************************************************************** + * Name: sam_cmcc_disable + * + * Description: + * Disable the Cortex-M Cache Controller + * + ****************************************************************************/ + +void sam_cmcc_disable(void); + +/**************************************************************************** + * Name: sam_cmcc_invalidate + * + * Description: + * Invalidate a range of addresses. Note: These addresses should be + * aligned with the beginning and end of cache lines. Otherwise, values + * at the edges of the region will also be invalidated! + * + ****************************************************************************/ + +void sam_cmcc_invalidate(uintptr_t start, uintptr_t end); + +/**************************************************************************** + * Name: sam_cmcc_invalidateall + * + * Description: + * Invalidate the entire cache + * + ****************************************************************************/ + +void sam_cmcc_invalidateall(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#else /* CONFIG_SAM34_CMCC */ + +/* Stubs so that we don't have to put condition compilation in driver source */ + +# define sam_cmcc_invalidate(start, end) +# define sam_cmcc_invalidateall() + +#endif /* CONFIG_SAM34_CMCC */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_CMCC_H */ diff --git a/arch/arm/src/sam34/sam_dmac.c b/arch/arm/src/sam34/sam_dmac.c new file mode 100644 index 0000000000000000000000000000000000000000..26bd9c3a4986b43f5477379cc5d06c5a8b0a657d --- /dev/null +++ b/arch/arm/src/sam34/sam_dmac.c @@ -0,0 +1,1801 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_dmac.c + * + * Copyright (C) 2010, 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" + +#include "sam_dmac.h" +#include "sam_periphclks.h" +#include "chip/sam_pmc.h" +#include "chip/sam_dmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Condition out the whole file unless DMA is selected in the configuration */ + +#ifdef CONFIG_SAM34_DMAC0 + +/* If SAM3/4 support is enabled, then OS DMA support should also be enabled */ + +#ifndef CONFIG_ARCH_DMA +# warning "SAM3/4 DMA enabled but CONFIG_ARCH_DMA disabled" +#endif + +/* Check the number of link list descriptors to allocate */ + +#ifndef CONFIG_SAM34_NLLDESC +# define CONFIG_SAM34_NLLDESC SAM34_NDMACHAN +#endif + +#if CONFIG_SAM34_NLLDESC < SAM34_NDMACHAN +# warning "At least SAM34_NDMACHAN descriptors must be allocated" + +# undef CONFIG_SAM34_NLLDESC +# define CONFIG_SAM34_NLLDESC SAM34_NDMACHAN +#endif + +/* Register values **********************************************************/ + +#define DMACHAN_CTRLB_BOTHDSCR \ + (DMACHAN_CTRLB_SRCDSCR | DMACHAN_CTRLB_DSTDSCR) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one DMA channel */ + +struct sam_dma_s +{ + uint8_t chan; /* DMA channel number (0-6) */ + bool inuse; /* TRUE: The DMA channel is in use */ + uint32_t flags; /* DMA channel flags */ + uint32_t base; /* DMA register channel base address */ + uint32_t cfg; /* Pre-calculated CFG register for transfer */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ + struct dma_linklist_s *llhead; /* DMA link list head */ + struct dma_linklist_s *lltail; /* DMA link list head */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These semaphores protect the DMA channel and descriptor tables */ + +static sem_t g_chsem; +static sem_t g_dsem; + +/* CTRLA field lookups */ + +static const uint32_t g_srcwidth[3] = +{ + DMACHAN_CTRLA_SRCWIDTH_BYTE, + DMACHAN_CTRLA_SRCWIDTH_HWORD, + DMACHAN_CTRLA_SRCWIDTH_WORD +}; + +static const uint32_t g_destwidth[3] = +{ + DMACHAN_CTRLA_DSTWIDTH_BYTE, + DMACHAN_CTRLA_DSTWIDTH_HWORD, + DMACHAN_CTRLA_DSTWIDTH_WORD +}; + +static const uint32_t g_fifocfg[3] = +{ + DMACHAN_CFG_FIFOCFG_LARGEST, + DMACHAN_CFG_FIFOCFG_HALF, + DMACHAN_CFG_FIFOCFG_SINGLE +}; + +/* This array describes the available link list descriptors */ + +static struct dma_linklist_s g_linklist[CONFIG_SAM34_NLLDESC]; + +/* This array describes the state of each DMA */ + +static struct sam_dma_s g_dma[SAM34_NDMACHAN] = +{ +#if defined(CONFIG_ARCH_CHIP_SAM3U) + /* The SAM3U has four DMA channels. The FIFOs for channels 0-2 are + * 8 bytes in size; channel 3 is 32 bytes. + */ + +#if SAM34_NDMACHAN != 4 +# error "Logic here assumes SAM34_NDMACHAN is 4" +#endif + + { + .chan = 0, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN0_BASE, + }, + { + .chan = 1, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN1_BASE, + }, + { + .chan = 2, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN2_BASE, + }, + { + .chan = 3, + .flags = DMACH_FLAG_FIFO_32BYTES, + .base = SAM_DMACHAN3_BASE, + } + +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) + /* The SAM3A/X have six DMA channels. The FIFOs for channels 0-2 are + * 8 bytes in size; channel 3 is 32 bytes. + */ + +#if SAM34_NDMACHAN != 6 +# error "Logic here assumes SAM34_NDMACHAN is 6" +#endif + + { + .chan = 0, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN0_BASE, + }, + { + .chan = 1, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN1_BASE, + }, + { + .chan = 2, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN2_BASE, + }, + { + .chan = 3, + .flags = DMACH_FLAG_FIFO_32BYTES, + .base = SAM_DMACHAN3_BASE, + } + { + .chan = 4, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN4_BASE, + } + { + .chan = 5, + .flags = DMACH_FLAG_FIFO_32BYTES, + .base = SAM_DMACHAN5_BASE, + } + +#elif defined(CONFIG_ARCH_CHIP_SAM4E) + /* The SAM4E16E, SAM4E8E, SAM4E16C, and SAM4E8C have four DMA channels. + * + * REVISIT: I have not yet found any documentation for the per-channel + * FIFO depth. Here I am assuming that the FIFO characteristics are + * the same as for the SAM3U. + */ + +#if SAM34_NDMACHAN != 4 +# error "Logic here assumes SAM34_NDMACHAN is 4" +#endif + + { + .chan = 0, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN0_BASE, + }, + { + .chan = 1, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN1_BASE, + }, + { + .chan = 2, + .flags = DMACH_FLAG_FIFO_8BYTES, + .base = SAM_DMACHAN2_BASE, + }, + { + .chan = 3, + .flags = DMACH_FLAG_FIFO_32BYTES, + .base = SAM_DMACHAN3_BASE, + } + +#else +# error "Nothing is known about the DMA channels for this device" +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_takechsem() and sam_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table + * + ****************************************************************************/ + +static void sam_takechsem(void) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_chsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givechsem(void) +{ + (void)sem_post(&g_chsem); +} + +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +static void sam_takedsem(void) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(void) +{ + (void)sem_post(&g_dsem); +} + +/**************************************************************************** + * Name: sam_fifosize + * + * Description: + * Decode the FIFO size from the flags + * + ****************************************************************************/ + +static unsigned int sam_fifosize(uint8_t chflags) +{ + chflags &= DMACH_FLAG_FIFOSIZE_MASK; + if (chflags == DMACH_FLAG_FIFO_8BYTES) + { + return 8; + } + else /* if (chflags == DMACH_FLAG_FIFO_32BYTES) */ + { + return 32; + } +} + +/**************************************************************************** + * Name: sam_fifocfg + * + * Description: + * Decode the FIFO config from the flags + * + ****************************************************************************/ + +static inline uint32_t sam_fifocfg(struct sam_dma_s *dmach) +{ + unsigned int ndx = (dmach->flags & DMACH_FLAG_FIFOCFG_MASK) >> DMACH_FLAG_FIFOCFG_SHIFT; + DEBUGASSERT(ndx < 3); + return g_fifocfg[ndx]; +} + +/**************************************************************************** + * Name: sam_txcfg + * + * Description: + * Decode the flags to get the correct CFG register bit settings for + * a transmit (memory to peripheral) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_txcfg(struct sam_dma_s *dmach) +{ + uint32_t regval; + + /* Set transfer (memory to peripheral) DMA channel configuration register */ + + regval = DMACHAN_CFG_SOD; + regval |= (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT); + regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMACHAN_CFG_SRCH2SEL : 0; + regval |= (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT) << DMACHAN_CFG_DSTPER_SHIFT); + regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMACHAN_CFG_DSTH2SEL : 0; + regval |= sam_fifocfg(dmach); + return regval; +} + +/**************************************************************************** + * Name: sam_rxcfg + * + * Description: + * Decode the flags to get the correct CFG register bit settings for + * a receive (peripheral to memory) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_rxcfg(struct sam_dma_s *dmach) +{ + uint32_t regval; + + /* Set received (peripheral to memory) DMA channel config */ + + regval = DMACHAN_CFG_SOD; + regval |= (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT); + regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMACHAN_CFG_SRCH2SEL : 0; + regval |= (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT) << DMACHAN_CFG_DSTPER_SHIFT); + regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMACHAN_CFG_DSTH2SEL : 0; + regval |= sam_fifocfg(dmach); + return regval; +} + +/**************************************************************************** + * Name: sam_txctrlabits + * + * Description: + * Decode the flags to get the correct CTRLA register bit settings for + * a transmit (memory to peripheral) transfer. These are only the "fixed" + * CTRLA values and need to be updated with the actual transfer size before + * being written to CTRLA sam_txctrla). + * + ****************************************************************************/ + +static inline uint32_t +sam_txctrlabits(struct sam_dma_s *dmach) +{ + uint32_t regval; + unsigned int ndx; + + DEBUGASSERT(dmach); + + /* Since this is a transmit, the source is described by the memory selections. + * Set the source width (memory width). + */ + + ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT; + DEBUGASSERT(ndx < 3); + regval = g_srcwidth[ndx]; + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) + /* Set the source chunk size (memory chunk size) */ + + if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4) + { + regval |= DMACHAN_CTRLA_SCSIZE_4; + } +#if 0 /* DMACHAN_CTRLA_SCSIZE_1 is zero */ + else + { + regval |= DMACHAN_CTRLA_SCSIZE_1; + } +#endif +#endif + + /* Since this is a transmit, the destination is described by the peripheral selections. + * Set the destination width (peripheral width). + */ + + ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + DEBUGASSERT(ndx < 3); + regval |= g_destwidth[ndx]; + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) + /* Set the destination chunk size (peripheral chunk size) */ + + if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4) + { + regval |= DMACHAN_CTRLA_DCSIZE_4; + } +#if 0 /* DMACHAN_CTRLA_DCSIZE_1 is zero */ + else + { + regval |= DMACHAN_CTRLA_DCSIZE_1; + } +#endif +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_maxtxtransfer + * + * Description: + * Maximum number of bytes that can be sent in on transfer + * + ****************************************************************************/ + +static size_t sam_maxtxtransfer(struct sam_dma_s *dmach) +{ + unsigned int srcwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes. BTSIZE is "the number of + * transfers to be performed, that is, for writes it refers to the number + * of source width transfers to perform when DMAC is flow controller. For + * Reads, BTSIZE refers to the number of transfers completed on the Source + * Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) + >> DMACH_FLAG_MEMWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = DMACHAN_CTRLA_BTSIZE_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * DMACHAN_CTRLA_BTSIZE_MAX; + break; + + case 2: /* 32 bits 4 bytes */ + maxtransfer = 4 * DMACHAN_CTRLA_BTSIZE_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_txctrla + * + * Description: + * Or in the variable CTRLA bits + * + ****************************************************************************/ + +static inline uint32_t sam_txctrla(struct sam_dma_s *dmach, + uint32_t ctrla, uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + srcwidth = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) + >> DMACH_FLAG_MEMWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + } + + DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX); + return (ctrla & ~DMACHAN_CTRLA_BTSIZE_MASK) | + (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT); +} + +/**************************************************************************** + * Name: sam_rxctrlabits + * + * Description: + * Decode the flags to get the correct CTRLA register bit settings for + * a read (peripheral to memory) transfer. These are only the "fixed" CTRLA + * values and need to be updated with the actual transfer size before being + * written to CTRLA sam_rxctrla). + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrlabits(struct sam_dma_s *dmach) +{ + uint32_t regval; + unsigned int ndx; + + DEBUGASSERT(dmach); + + /* Since this is a receive, the source is described by the peripheral + * selections. Set the source width (peripheral width). + */ + + ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + DEBUGASSERT(ndx < 3); + regval = g_srcwidth[ndx]; + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) + /* Set the source chunk size (peripheral chunk size) */ + + if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4) + { + regval |= DMACHAN_CTRLA_SCSIZE_4; + } +#if 0 /* DMACHAN_CTRLA_SCSIZE_1 is zero */ + else + { + regval |= DMACHAN_CTRLA_SCSIZE_1; + } +#endif +#endif + + /* Since this is a receive, the destination is described by the memory selections. + * Set the destination width (memory width). + */ + + ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT; + DEBUGASSERT(ndx < 3); + regval |= g_destwidth[ndx]; + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) + /* Set the destination chunk size (memory chunk size) */ + + if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4) + { + regval |= DMACHAN_CTRLA_DCSIZE_4; + } +#if 0 /* DMACHAN_CTRLA_DCSIZE_1 is zero */ + else + { + regval |= DMACHAN_CTRLA_DCSIZE_1; + } +#endif +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_maxrxtransfer + * + * Description: + * Maximum number of bytes that can be sent in on transfer + * + ****************************************************************************/ + +static size_t sam_maxrxtransfer(struct sam_dma_s *dmach) +{ + unsigned int srcwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes. BTSIZE is "the number of + * transfers to be performed, that is, for writes it refers to the number + * of source width transfers to perform when DMAC is flow controller. For + * Reads, BTSIZE refers to the number of transfers completed on the Source + * Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) + >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = DMACHAN_CTRLA_BTSIZE_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * DMACHAN_CTRLA_BTSIZE_MAX; + break; + + case 2: /* 32 bits, 4 bytes */ + maxtransfer = 4 * DMACHAN_CTRLA_BTSIZE_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_rxctrla + * + * Description: + * 'OR' in the variable CTRLA bits + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrla(struct sam_dma_s *dmach, + uint32_t ctrla, uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + srcwidth = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) + >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + } + + DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX); + return (ctrla & ~DMACHAN_CTRLA_BTSIZE_MASK) | + (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT); +} + +/**************************************************************************** + * Name: sam_txctrlb + * + * Description: + * Decode the flags to get the correct CTRLB register bit settings for + * a transmit (memory to peripheral) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_txctrlb(struct sam_dma_s *dmach) +{ + uint32_t regval; + + /* Assume that we will not be using the link list and disable the source + * and destination descriptors. The default will be single transfer mode. + */ + + regval = DMACHAN_CTRLB_BOTHDSCR; + + /* Select flow control (even if the channel doesn't support it). The + * naming convention from TX is memory to peripheral, but that is really be + * determined by bits in the DMA flags. + */ + + /* Is the memory source really a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. is the peripheral destination also a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral-to-peripheral flow control */ + + regval |= DMACHAN_CTRLB_FC_P2P; + } + else + { + /* No.. Use peripheral-to-memory flow control */ + + regval |= DMACHAN_CTRLB_FC_P2M; + } + } + else + { + /* No, the source is memory. Is the peripheral destination a + * peripheral + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use memory-to-peripheral flow control */ + + regval |= DMACHAN_CTRLB_FC_M2P; + } + else + { + /* No.. Use memory-to-memory flow control */ + + regval |= DMACHAN_CTRLB_FC_M2M; + } + } + + /* Select source address incrementing */ + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) == 0) + { + regval |= DMACHAN_CTRLB_SRCINCR_FIXED; + } + + /* Select destination address incrementing */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) == 0) + { + regval |= DMACHAN_CTRLB_DSTINCR_FIXED; + } + return regval; +} + +/**************************************************************************** + * Name: sam_rxctrlb + * + * Description: + * Decode the flags to get the correct CTRLB register bit settings for + * a receive (peripheral to memory) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrlb(struct sam_dma_s *dmach) +{ + uint32_t regval; + + /* Assume that we will not be using the link list and disable the source and + * destination descriptors. The default will be single transfer mode. + */ + + regval = DMACHAN_CTRLB_BOTHDSCR; + + /* Select flow control (even if the channel doesn't support it). The + * naming convention from RX is peripheral to memory, but that is really be + * determined by bits in the DMA flags. + */ + + /* Is the peripheral source really a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. is the memory destination also a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. Use peripheral-to-peripheral flow control */ + + regval |= DMACHAN_CTRLB_FC_P2P; + } + else + { + /* No.. Use peripheral-to-memory flow control */ + + regval |= DMACHAN_CTRLB_FC_P2M; + } + } + else + { + /* No, the peripheral source is memory. Is the memory destination + * a peripheral + */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. Use memory-to-peripheral flow control */ + + regval |= DMACHAN_CTRLB_FC_M2P; + } + else + { + /* No.. Use memory-to-memory flow control */ + + regval |= DMACHAN_CTRLB_FC_M2M; + } + } + + /* Select source address incrementing */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) == 0) + { + regval |= DMACHAN_CTRLB_SRCINCR_FIXED; + } + + /* Select address incrementing */ + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) == 0) + { + regval |= DMACHAN_CTRLB_DSTINCR_FIXED; + } + + return regval; +} + +/**************************************************************************** + * Name: sam_allocdesc + * + * Description: + * Allocate and add one descriptor to the DMA channel's link list. + * + * NOTE: link list entries are freed by the DMA interrupt handler. However, + * since the setting/clearing of the 'in use' indication is atomic, no + * special actions need be performed. It would be a good thing to add logic + * to handle the case where all of the entries are exhausted and we could + * wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct dma_linklist_s * +sam_allocdesc(struct sam_dma_s *dmach, struct dma_linklist_s *prev, + uint32_t src, uint32_t dest, uint32_t ctrla, uint32_t ctrlb) +{ + struct dma_linklist_s *desc = NULL; + int i; + + /* Sanity check -- src == 0 is the indication that the link is unused. + * Obviously setting it to zero would break that usage. + */ + +#ifdef CONFIG_DEBUG + if (src != 0) +#endif + { + /* Table a descriptor table semaphore count. When we get one, then there + * is at least one free descriptor in the table and it is ours. + */ + + sam_takedsem(); + + /* Examine each link list entry to find an available one -- i.e., one + * with src == 0. That src field is set to zero by the DMA transfer + * complete interrupt handler. The following should be safe because + * that is an atomic operation. + */ + + sam_takechsem(); + for (i = 0; i < CONFIG_SAM34_NLLDESC; i++) + { + if (g_linklist[i].src == 0) + { + /* We have it. Initialize the new link list entry */ + + desc = &g_linklist[i]; + desc->src = src; /* Source address */ + desc->dest = dest; /* Destination address */ + desc->ctrla = ctrla; /* Control A value */ + desc->ctrlb = ctrlb; /* Control B value */ + desc->next = 0; /* Next descriptor address */ + + /* And then hook it at the tail of the link list */ + + if (!prev) + { + /* There is no previous link. This is the new head of + * the list + */ + + DEBUGASSERT(dmach->llhead == NULL && dmach->lltail == NULL); + dmach->llhead = desc; + } + else + { + DEBUGASSERT(dmach->llhead != NULL && dmach->lltail == prev); + + /* When the second link is added to the list, that is the + * cue that we are going to do the link list transfer. + * + * Enable the source and destination descriptor in the link + * list entry just before this one. We assume that both + * source and destination buffers are non-continuous, but + * this should work even if that is not the case. + */ + + prev->ctrlb &= ~DMACHAN_CTRLB_BOTHDSCR; + + /* Link the previous tail to the new tail */ + + prev->next = (uint32_t)desc; + } + + /* In any event, this is the new tail of the list. The source + * and destination descriptors must be disabled for the last entry + * in the link list. */ + + desc->ctrlb |= DMACHAN_CTRLB_BOTHDSCR; + dmach->lltail = desc; + break; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + sam_givechsem(); + DEBUGASSERT(desc != NULL); + } + + return desc; +} + +/**************************************************************************** + * Name: sam_freelinklist + * + * Description: + * Free all descriptors in the DMA channel's link list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_freelinklist(struct sam_dma_s *dmach) +{ + struct dma_linklist_s *desc; + struct dma_linklist_s *next; + + /* Get the head of the link list and detach the link list from the DMA + * channel + */ + + desc = dmach->llhead; + dmach->llhead = NULL; + dmach->lltail = NULL; + + /* Reset each descriptor in the link list (thereby freeing them) */ + + while (desc != NULL) + { + next = (struct dma_linklist_s *)desc->next; + DEBUGASSERT(desc->src != 0); + memset(desc, 0, sizeof(struct dma_linklist_s)); + sam_givedsem(); + desc = next; + } +} + +/**************************************************************************** + * Name: sam_txbuffer + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_txbuffer(struct sam_dma_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t regval; + uint32_t ctrla; + uint32_t ctrlb; + + /* If we are appending a buffer to a linklist, then re-use the CTRLA/B + * values. Otherwise, create them from the properties of the transfer. + */ + + if (dmach->llhead) + { + regval = dmach->llhead->ctrla; + ctrlb = dmach->llhead->ctrlb; + } + else + { + regval = sam_txctrlabits(dmach); + ctrlb = sam_txctrlb(dmach); + } + + ctrla = sam_txctrla(dmach, regval, nbytes); + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, maddr, paddr, ctrla, ctrlb)) + { + return -ENOMEM; + } + + /* Pre-calculate the transmit CFG register setting (it won't be used until + * the DMA is started). + */ + + dmach->cfg = sam_txcfg(dmach); + return OK; +} + +/**************************************************************************** + * Name: sam_rxbuffer + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_rxbuffer(struct sam_dma_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t regval; + uint32_t ctrla; + uint32_t ctrlb; + + /* If we are appending a buffer to a linklist, then re-use the CTRLA/B + * values. Otherwise, create them from the properties of the transfer. + */ + + if (dmach->llhead) + { + regval = dmach->llhead->ctrla; + ctrlb = dmach->llhead->ctrlb; + } + else + { + regval = sam_rxctrlabits(dmach); + ctrlb = sam_rxctrlb(dmach); + } + + ctrla = sam_rxctrla(dmach, regval, nbytes); + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, paddr, maddr, ctrla, ctrlb)) + { + return -ENOMEM; + } + + /* Pre-calculate the receive CFG register setting (it won't be used until + * the DMA is started). + */ + + dmach->cfg = sam_rxcfg(dmach); + return OK; +} + +/**************************************************************************** + * Name: sam_single + * + * Description: + * Start a single buffer DMA. + * + ****************************************************************************/ + +static inline int sam_single(struct sam_dma_s *dmach) +{ + struct dma_linklist_s *llhead = dmach->llhead; + + /* Clear any pending interrupts from any previous DMAC transfer by reading + * the interrupt status register. + * + * REVISIT: If DMAC interrupts are disabled at the NVIKC, then reading the + * EBCISR register could cause a loss of interrupts! + */ + + (void)getreg32(SAM_DMAC_EBCISR); + + /* Write the starting source address in the SADDR register */ + + DEBUGASSERT(llhead != NULL && llhead->src != 0); + putreg32(llhead->src, dmach->base + SAM_DMACHAN_SADDR_OFFSET); + + /* Write the starting destination address in the DADDR register */ + + putreg32(llhead->dest, dmach->base + SAM_DMACHAN_DADDR_OFFSET); + + /* Clear the next descriptor address register */ + + putreg32(0, dmach->base + SAM_DMACHAN_DSCR_OFFSET); + + /* Set up the CTRLA register */ + + putreg32(llhead->ctrla, dmach->base + SAM_DMACHAN_CTRLA_OFFSET); + + /* Set up the CTRLB register */ + + putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLB_OFFSET); + + /* Both the DST and SRC DSCR bits should be '1' in CTRLB */ + + DEBUGASSERT((llhead->ctrlb & DMACHAN_CTRLB_BOTHDSCR) == DMACHAN_CTRLB_BOTHDSCR); + + /* Set up the CFG register */ + + putreg32(dmach->cfg, dmach->base + SAM_DMACHAN_CFG_OFFSET); + + /* Enable the channel by writing a ‘1’ to the CHER enable bit */ + + putreg32(DMAC_CHER_ENA(dmach->chan), SAM_DMAC_CHER); + + /* The DMA has been started. Once the transfer completes, hardware sets the + * interrupts and disables the channel. We will received buffer complete and + * transfer complete interrupts. + * + * Enable error, buffer complete and transfer complete interrupts. + * (Since there is only a single buffer, we don't need the buffer complete + * interrupt). + */ + + putreg32(DMAC_EBC_CBTCINTS(dmach->chan), SAM_DMAC_EBCIER); + return OK; +} + +/**************************************************************************** + * Name: sam_multiple + * + * Description: + * Start a multiple buffer DMA. + * + ****************************************************************************/ + +static inline int sam_multiple(struct sam_dma_s *dmach) +{ + struct dma_linklist_s *llhead = dmach->llhead; + + DEBUGASSERT(llhead != NULL && llhead->src != 0); + + /* Check the first and last CTRLB values */ + + DEBUGASSERT((llhead->ctrlb & DMACHAN_CTRLB_BOTHDSCR) == 0); + DEBUGASSERT((dmach->lltail->ctrlb & DMACHAN_CTRLB_BOTHDSCR) == DMACHAN_CTRLB_BOTHDSCR); + + /* Clear any pending interrupts from any previous DMAC transfer by reading the + * status register + * + * REVISIT: If DMAC interrupts are disabled at the NVIKC, then reading the + * EBCISR register could cause a loss of interrupts! + */ + + (void)getreg32(SAM_DMAC_EBCISR); + + /* Set up the initial CTRLA register */ + + putreg32(llhead->ctrla, dmach->base + SAM_DMACHAN_CTRLA_OFFSET); + + /* Set up the CTRLB register (will enable descriptors) */ + + putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLB_OFFSET); + + /* Write the channel configuration information into the CFG register */ + + putreg32(dmach->cfg, dmach->base + SAM_DMACHAN_CFG_OFFSET); + + /* Program the DSCR register with the pointer to the firstlink list entry. */ + + putreg32((uint32_t)llhead, dmach->base + SAM_DMACHAN_DSCR_OFFSET); + + /* Finally, enable the channel by writing a ‘1’ to the CHER enable */ + + putreg32(DMAC_CHER_ENA(dmach->chan), SAM_DMAC_CHER); + + /* As each buffer of data is transferred, the CTRLA register is written back + * into the link list entry. The CTRLA contains updated BTSIZE and DONE bits. + * Additionally, the CTRLA DONE bit is asserted when the buffer transfer has completed. + * + * The DMAC transfer continues until the CTRLB register disables the descriptor + * (DSCR bits) registers at the final buffer transfer. + * + * Enable error, buffer complete and transfer complete interrupts. We + * don't really need the buffer complete interrupts, but we will take them + * just to handle stall conditions. + */ + + putreg32(DMAC_EBC_CHANINTS(dmach->chan), SAM_DMAC_EBCIER); + return OK; +} + +/**************************************************************************** + * Name: sam_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void sam_dmaterminate(struct sam_dma_s *dmach, int result) +{ + /* Disable all channel interrupts */ + + putreg32(DMAC_EBC_CHANINTS(dmach->chan), SAM_DMAC_EBCIDR); + + /* Disable the channel by writing one to the write-only channel disable register */ + + putreg32(DMAC_CHDR_DIS(dmach->chan), SAM_DMAC_CHDR); + + /* Free the linklist */ + + sam_freelinklist(dmach); + + /* Perform the DMA complete callback */ + + if (dmach->callback) + { + dmach->callback((DMA_HANDLE)dmach, dmach->arg, result); + } + + dmach->callback = NULL; + dmach->arg = NULL; +} + +/**************************************************************************** + * Name: sam_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int sam_dmainterrupt(int irq, void *context) +{ + struct sam_dma_s *dmach; + unsigned int chndx; + uint32_t regval; + + /* Get the DMAC status register value. Ignore all masked interrupt + * status bits. + */ + + regval = getreg32(SAM_DMAC_EBCISR) & getreg32(SAM_DMAC_EBCIMR); + + /* Check if the any transfer has completed or any errors have occurred */ + + if ((regval & DMAC_EBC_ALLINTS) != 0) + { + /* Yes.. Check each bit to see which channel has interrupted */ + + for (chndx = 0; chndx < SAM34_NDMACHAN; chndx++) + { + /* Are any interrupts pending for this channel? */ + + if ((regval & DMAC_EBC_CHANINTS(chndx)) != 0) + { + dmach = &g_dma[chndx]; + + /* Yes.. Did an error occur? */ + + if ((regval & DMAC_EBC_ERR(chndx)) != 0) + { + /* Yes... Terminate the transfer with an error? */ + + sam_dmaterminate(dmach, -EIO); + } + + /* Is the transfer complete? */ + + else if ((regval & DMAC_EBC_CBTC(chndx)) != 0) + { + /* Yes.. Terminate the transfer with success */ + + sam_dmaterminate(dmach, OK); + } + + /* Otherwise, this must be a Buffer Transfer Complete (BTC) + * interrupt as part of a multiple buffer transfer. + */ + + else /* if ((regval & DMAC_EBC_BTC(chndx)) != 0) */ + { + /* Write the KEEPON field to clear the STALL states */ + + putreg32(DMAC_CHER_KEEP(dmach->chan), SAM_DMAC_CHER); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + dmallvdbg("Initialize DMAC0\n"); + + /* Enable peripheral clock */ + + sam_dmac_enableclk(); + + /* Disable all DMA interrupts */ + + putreg32(DMAC_EBC_ALLINTS, SAM_DMAC_EBCIDR); + + /* Disable all DMA channels */ + + putreg32(DMAC_CHDR_DIS_ALL, SAM_DMAC_CHDR); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_DMAC, sam_dmainterrupt); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_DMAC); + + /* Enable the DMA controller */ + + putreg32(DMAC_EN_ENABLE, SAM_DMAC_EN); + + /* Initialize semaphores */ + + sem_init(&g_chsem, 0, 1); + sem_init(&g_dsem, 0, CONFIG_SAM34_NLLDESC); +} + +/**************************************************************************** + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel with + * the required FIFO size and flow control capabilities (determined by + * dma_flags) then gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. Howerver, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel if the required FIFO size is available, this function + * returns a non-NULL, void* DMA channel handle. NULL is returned on any + * failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint32_t chflags) +{ + struct sam_dma_s *dmach; + unsigned int fifosize; + unsigned int chndx; + + /* Get the search parameters */ + + fifosize = sam_fifosize(chflags); + + /* Search for an available DMA channel with at least the requested FIFO + * size. + */ + + dmach = NULL; + sam_takechsem(); + + for (chndx = 0; chndx < SAM34_NDMACHAN; chndx++) + { + struct sam_dma_s *candidate = &g_dma[chndx]; + if (!candidate->inuse && + (sam_fifosize(candidate->flags) >= fifosize)) + { + dmach = candidate; + dmach->inuse = true; + + /* Read the status register to clear any pending interrupts on the + * channel + * + * REVISIT: If DMAC interrupts are disabled at the NVIKC, then + * reading the EBCISR register could cause a loss of interrupts! + */ + + (void)getreg32(SAM_DMAC_EBCISR); + + /* Disable the channel by writing one to the write-only channel + * disable register + */ + + putreg32(DMAC_CHDR_DIS(chndx), SAM_DMAC_CHDR); + + /* Set the DMA channel flags, retaining the fifo size setting + * which is an inherent properties of the FIFO and cannot be + * changed. + */ + + dmach->flags &= DMACH_FLAG_FIFOSIZE_MASK; + dmach->flags |= (chflags & ~DMACH_FLAG_FIFOSIZE_MASK); + break; + } + } + + sam_givechsem(); + + dmavdbg("chflags: %08x returning dmach: %p\n", (int)chflags, dmach); + return (DMA_HANDLE)dmach; +} + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + + /* Set the new DMA channel flags. */ + + dmavdbg("chflags: %08x\n", (int)chflags); + dmach->flags = chflags; +} + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT((dmach != NULL) && (dmach->inuse)); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + dmach->flags &= DMACH_FLAG_FIFOSIZE_MASK; + dmach->inuse = false; /* No longer in use */ +} + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + ssize_t remaining = (ssize_t)nbytes; + size_t maxtransfer; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtxtransfer(dmach); + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_txbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do do). + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_txbuffer(dmach, paddr, maddr, remaining); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + ssize_t remaining = (ssize_t)nbytes; + size_t maxtransfer; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxrxtransfer(dmach); + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_rxbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do do). + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_rxbuffer(dmach, paddr, maddr, remaining); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + int ret = -EINVAL; + + dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg); + DEBUGASSERT(dmach != NULL); + + /* Verify that the DMA has been setup (i.e., at least one entry in the + * link list). + */ + + if (dmach->llhead) + { + /* Save the callback info. This will be invoked when the DMA completes */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Is this a single block transfer? Or a multiple block transfer? */ + + if (dmach->llhead == dmach->lltail) + { + ret = sam_single(dmach); + } + else + { + ret = sam_multiple(dmach); + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + irqstate_t flags; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT(dmach != NULL); + + flags = enter_critical_section(); + sam_dmaterminate(dmach, -EINTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + irqstate_t flags; + + /* Sample global registers. NOTE: reading EBCISR clears interrupts, but + * that should be okay IF interrupts are enabled when this function is + * called. But there is a race condition where this instrumentation could + * cause lost interrupts. + */ + + flags = enter_critical_section(); + regs->gcfg = getreg32(SAM_DMAC_GCFG); + regs->en = getreg32(SAM_DMAC_EN); + regs->sreq = getreg32(SAM_DMAC_SREQ); + regs->creq = getreg32(SAM_DMAC_CREQ); + regs->last = getreg32(SAM_DMAC_LAST); + regs->ebcimr = getreg32(SAM_DMAC_EBCIMR); + regs->chsr = getreg32(SAM_DMAC_CHSR); + + /* Sample channel registers */ + + regs->saddr = getreg32(dmach->base + SAM_DMACHAN_SADDR_OFFSET); + regs->daddr = getreg32(dmach->base + SAM_DMACHAN_DADDR_OFFSET); + regs->dscr = getreg32(dmach->base + SAM_DMACHAN_DSCR_OFFSET); + regs->ctrla = getreg32(dmach->base + SAM_DMACHAN_CTRLA_OFFSET); + regs->ctrlb = getreg32(dmach->base + SAM_DMACHAN_CTRLB_OFFSET); + regs->cfg = getreg32(dmach->base + SAM_DMACHAN_CFG_OFFSET); + leave_critical_section(flags); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg) +{ + struct sam_dma_s *dmach = (struct sam_dma_s *)handle; + + dmadbg("%s\n", msg); + dmadbg(" DMA Global Registers:\n"); + dmadbg(" GCFG[%08x]: %08x\n", SAM_DMAC_GCFG, regs->gcfg); + dmadbg(" EN[%08x]: %08x\n", SAM_DMAC_EN, regs->en); + dmadbg(" SREQ[%08x]: %08x\n", SAM_DMAC_SREQ, regs->sreq); + dmadbg(" CREQ[%08x]: %08x\n", SAM_DMAC_CREQ, regs->creq); + dmadbg(" LAST[%08x]: %08x\n", SAM_DMAC_LAST, regs->last); + dmadbg(" EBCIMR[%08x]: %08x\n", SAM_DMAC_EBCIMR, regs->ebcimr); + dmadbg(" CHSR[%08x]: %08x\n", SAM_DMAC_CHSR, regs->chsr); + dmadbg(" DMA Channel Registers:\n"); + dmadbg(" SADDR[%08x]: %08x\n", dmach->base + SAM_DMACHAN_SADDR_OFFSET, regs->saddr); + dmadbg(" DADDR[%08x]: %08x\n", dmach->base + SAM_DMACHAN_DADDR_OFFSET, regs->daddr); + dmadbg(" DSCR[%08x]: %08x\n", dmach->base + SAM_DMACHAN_DSCR_OFFSET, regs->dscr); + dmadbg(" CTRLA[%08x]: %08x\n", dmach->base + SAM_DMACHAN_CTRLA_OFFSET, regs->ctrla); + dmadbg(" CTRLB[%08x]: %08x\n", dmach->base + SAM_DMACHAN_CTRLB_OFFSET, regs->ctrlb); + dmadbg(" CFG[%08x]: %08x\n", dmach->base + SAM_DMACHAN_CFG_OFFSET, regs->cfg); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_SAM34_DMAC0 */ diff --git a/arch/arm/src/sam34/sam_dmac.h b/arch/arm/src/sam34/sam_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..0ff4f2e14485f92635e190cf0fab525f7ad3f973 --- /dev/null +++ b/arch/arm/src/sam34/sam_dmac.h @@ -0,0 +1,315 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_dmac.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_DMAC_H +#define __ARCH_ARM_SRC_SAM34_SAM_DMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +#endif + +/* DMA ******************************************************************************/ + +/* Flags used to characterize the desired DMA channel. The naming convention is that + * one side is the peripheral and the other is memory (however, the interface could still + * be used if, for example, both sides were memory although the naming would be awkward) + */ + +/* Unchange-able properties of the channel */ + + /* Bit 0: Not used */ +#define DMACH_FLAG_FIFOSIZE_SHIFT (1) /* Bit 1: Size of DMA FIFO */ +#define DMACH_FLAG_FIFOSIZE_MASK (1 << DMACH_FLAG_FIFOSIZE_SHIFT) +# define DMACH_FLAG_FIFO_8BYTES (0 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 8 bytes */ +# define DMACH_FLAG_FIFO_32BYTES (1 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 32 bytes */ + +/* Configurable properties of the channel */ + +#define DMACH_FLAG_BURST_LARGEST 0 /* Largest length AHB burst */ +#define DMACH_FLAG_BURST_HALF 1 /* Half FIFO size */ +#define DMACH_FLAG_BURST_SINGLE 2 /* Single AHB access */ + +#define DMACH_FLAG_FIFOCFG_SHIFT (2) /* Bits 2-3: FIFO configuration */ +#define DMACH_FLAG_FIFOCFG_MASK (3 << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_LARGEST (DMACH_FLAG_BURST_LARGEST << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_HALF (DMACH_FLAG_BURST_HALF << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_SINGLE (DMACH_FLAG_BURST_SINGLE << DMACH_FLAG_FIFOCFG_SHIFT) + +/* Peripheral endpoint characteristics */ + +#define DMACH_FLAG_PERIPHPID_SHIFT (4) /* Bits 4-7: Peripheral PID */ +#define DMACH_FLAG_PERIPHPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT) +#define DMACH_FLAG_PERIPHH2SEL (1 << 8) /* Bits 8: HW handshaking */ +#define DMACH_FLAG_PERIPHISPERIPH (1 << 9) /* Bits 9: 0=memory; 1=peripheral */ +#define DMACH_FLAG_PERIPHWIDTH_SHIFT (10) /* Bits 10-11: Peripheral width */ +#define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) +# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */ +#define DMACH_FLAG_PERIPHINCREMENT (1 << 12) /* Bit 12: Autoincrement peripheral address */ +#define DMACH_FLAG_PERIPHCHUNKSIZE (1 << 13) /* Bit 13: Peripheral chunk size */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0) /* Peripheral chunksize = 1 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_4 DMACH_FLAG_PERIPHCHUNKSIZE /* Peripheral chunksize = 4 */ + +/* Memory endpoint characteristics */ + +#define DMACH_FLAG_MEMPID_SHIFT (14) /* Bits 14-17: Memory PID */ +#define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_MEMPID_SHIFT) +#define DMACH_FLAG_MEMH2SEL (1 << 18) /* Bits 18: HW handshaking */ +#define DMACH_FLAG_MEMISPERIPH (1 << 19) /* Bits 19: 0=memory; 1=peripheral */ +#define DMACH_FLAG_MEMWIDTH_SHIFT (20) /* Bits 20-21: Memory width */ +#define DMACH_FLAG_MEMWIDTH_MASK (3 << DMACH_FLAG_MEMWIDTH_SHIFT) +# define DMACH_FLAG_MEMWIDTH_8BITS (0 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */ +#define DMACH_FLAG_MEMINCREMENT (1 << 22) /* Bit 22: Autoincrement memory address */ +#define DMACH_FLAG_MEMCHUNKSIZE (1 << 23) /* Bit 23: Memory chunk size */ +# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Memory chunksize = 1 */ +# define DMACH_FLAG_MEMCHUNKSIZE_4 DMACH_FLAG_MEMCHUNKSIZE /* Memory chunksize = 4 */ + /* Bits 24-31: Not used */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct sam_dmaregs_s +{ + /* Global Registers */ + + uint32_t gcfg; /* DMAC Global Configuration Register */ + uint32_t en; /* DMAC Enable Register */ + uint32_t sreq; /* DMAC Software Single Request Register */ + uint32_t creq; /* DMAC Software Chunk Transfer Request Register */ + uint32_t last; /* DMAC Software Last Transfer Flag Register */ + uint32_t ebcimr; /* DMAC Error Mask */ + uint32_t chsr; /* DMAC Channel Handler Status Register */ + + /* Channel Registers */ + + uint32_t saddr; /* DMAC Channel Source Address Register */ + uint32_t daddr; /* DMAC Channel Destination Address Register */ + uint32_t dscr; /* DMAC Channel Descriptor Address Register */ + uint32_t ctrla; /* DMAC Channel Control A Register */ + uint32_t ctrlb; /* DMAC Channel Control B Register */ + uint32_t cfg; /* DMAC Channel Configuration Register */ +}; +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel with + * the required FIFO size and flow control capabilities (determined by + * dma_flags) then gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. Howerver, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel if the required FIFO size is available, this function + * returns a non-NULL, void* DMA channel handle. NULL is returned on any + * failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint32_t dmach_flags); + +/**************************************************************************** + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and + * configured in one step. This is the typical case where a DMA channel + * performs a constant role. The alternative is (2) where the DMA channel + * is reconfigured on the fly. In this case, the chflags provided to + * sam_dmachannel are not used and sam_dmaconfig() is called before each + * DMA to configure the DMA channel appropriately. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags); + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes); + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes); + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs); +#else +# define sam_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg); +#else +# define sam_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_DMAC_H */ diff --git a/arch/arm/src/sam34/sam_emac.c b/arch/arm/src/sam34/sam_emac.c new file mode 100644 index 0000000000000000000000000000000000000000..d33f1d8aabb83151e6e9ee31b1cef566679c2a52 --- /dev/null +++ b/arch/arm/src/sam34/sam_emac.c @@ -0,0 +1,3892 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_emac.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This logic derives from the SAM34D3 Ethernet driver. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Which used Atmel NoOS sample code for reference (only). That Atmel + * sample code has a BSD compatible license that requires this copyright + * notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/sam_pinmap.h" +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "sam_cmcc.h" +#include "sam_emac.h" + +#include + +#if defined(CONFIG_NET) && defined(CONFIG_SAM34_EMAC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +/* Number of buffer for RX */ + +#ifndef CONFIG_SAM34_EMAC_NRXBUFFERS +# define CONFIG_SAM34_EMAC_NRXBUFFERS 16 +#endif + +/* Number of buffer for TX */ + +#ifndef CONFIG_SAM34_EMAC_NTXBUFFERS +# define CONFIG_SAM34_EMAC_NTXBUFFERS 8 +#endif + +#undef CONFIG_SAM34_EMAC_NBC + +#ifndef CONFIG_SAM34_EMAC_PHYADDR +# error "CONFIG_SAM34_EMAC_PHYADDR must be defined in the NuttX configuration" +#endif + +#if !defined(CONFIG_SAM34_EMAC_MII) && !defined(CONFIG_SAM34_EMAC_RMII) +# warning "Neither CONFIG_SAM34_EMAC_MII nor CONFIG_SAM34_EMAC_RMII defined" +#endif + +#if defined(CONFIG_SAM34_EMAC_MII) && defined(CONFIG_SAM34_EMAC_RMII) +# error "Both CONFIG_SAM34_EMAC_MII and CONFIG_SAM34_EMAC_RMII defined" +#endif + +#ifdef CONFIG_SAM34_EMAC_AUTONEG +# ifndef CONFIG_SAM34_EMAC_PHYSR +# error "CONFIG_SAM34_EMAC_PHYSR must be defined in the NuttX configuration" +# endif +# ifdef CONFIG_SAM34_EMAC_PHYSR_ALTCONFIG +# ifndef CONFIG_SAM34_EMAC_PHYSR_ALTMODE +# error "CONFIG_SAM34_EMAC_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_10HD +# error "CONFIG_SAM34_EMAC_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_100HD +# error "CONFIG_SAM34_EMAC_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_10FD +# error "CONFIG_SAM34_EMAC_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_100FD +# error "CONFIG_SAM34_EMAC_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAM34_EMAC_PHYSR_SPEED +# error "CONFIG_SAM34_EMAC_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_100MBPS +# error "CONFIG_SAM34_EMAC_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_MODE +# error "CONFIG_SAM34_EMAC_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAM34_EMAC_PHYSR_FULLDUPLEX +# error "CONFIG_SAM34_EMAC_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +#endif + +/* PHY definitions */ + +#if defined(CONFIG_ETH0_PHY_DM9161) +# define MII_OUI_MSB 0x0181 +# define MII_OUI_LSB 0x2e +#elif defined(CONFIG_ETH0_PHY_LAN8700) +# define MII_OUI_MSB 0x0007 +# define MII_OUI_LSB 0x30 +#elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define MII_OUI_MSB 0x0022 +# define MII_OUI_LSB 0x05 +#else +# error EMAC PHY unrecognized +#endif + +#ifdef CONFIG_SAM34_EMAC_PHYSR_ALTCONFIG + +# define PHYSR_MODE(sr) ((sr) & CONFIG_SAM34_EMAC_PHYSR_ALTMODE) +# define PHYSR_ISMODE(sr,m) (PHYSR_MODE(sr) == (m)) + +# define PHYSR_IS10HDX(sr) PHYSR_ISMODE(sr,CONFIG_SAM34_EMAC_PHYSR_10HD) +# define PHYSR_IS100HDX(sr) PHYSR_ISMODE(sr,CONFIG_SAM34_EMAC_PHYSR_100HD) +# define PHYSR_IS10FDX(sr) PHYSR_ISMODE(sr,CONFIG_SAM34_EMAC_PHYSR_10FD) +# define PHYSR_IS100FDX(sr) PHYSR_ISMODE(sr,CONFIG_SAM34_EMAC_PHYSR_100FD) + +#else + +# define PHYSR_MODESPEED (CONFIG_PHYSR_MODE | CONFIG_PHYSR_SPEED) +# define PHYSR_10HDX (0) +# define PHYSR_100HDX (CONFIG_PHYSR_100MBPS) +# define PHYSR_10FDX (CONFIG_PHYSR_FULLDUPLEX) +# define PHYSR_100FDX (CONFIG_PHYSR_FULLDUPLEX | CONFIG_PHYSR_100MBPS) + +# define PHYSR_IS10HDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_10HDX) +# define PHYSR_IS100HDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_100HDX) +# define PHYSR_IS10FDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_10FDX) +# define PHYSR_IS100FDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_100FDX) + +#endif + +/* EMAC buffer sizes, number of buffers, and number of descriptors. + * + * REVISIT: The CONFIG_NET_MULTIBUFFER might be useful. It might be possible + * to use this option to send and receive messages directly into the DMA + * buffers, saving a copy. There might be complications on the receiving + * side, however, where buffers may wrap and where the size of the received + * frame will typically be smaller than a full packet. + */ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER must not be set +#endif + +#define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ +#define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ + +/* We need at least one more free buffer than transmit buffers */ + +#define SAM_EMAC_NFREEBUFFERS (CONFIG_SAM34_EMAC_NTXBUFFERS+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAM34_EMAC_REGDEBUG +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define sam_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define SAM_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SAM_TXTIMEOUT (60*CLK_TCK) + +/* PHY read/write delays in loop counts */ + +#define PHY_RETRY_MAX 1000000 + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the EMAC + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The sam_emac_s encapsulates all state information for the EMAC peripheral */ + +struct sam_emac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */ + uint16_t txhead; /* Circular buffer head index */ + uint16_t txtail; /* Circular buffer tail index */ + uint16_t rxndx; /* RX index for current processing RX descriptor */ + + uint8_t *rxbuffer; /* Allocated RX buffers */ + uint8_t *txbuffer; /* Allocated TX buffers */ + struct emac_rxdesc_s *rxdesc; /* Allocated RX descriptors */ + struct emac_txdesc_s *txdesc; /* Allocated TX descriptors */ + + /* Debug stuff */ + +#ifdef CONFIG_SAM34_EMAC_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The driver state singleton */ + +static struct sam_emac_s g_emac; + +#ifdef CONFIG_SAM34_EMAC_PREALLOCATE +/* Preallocated data */ +/* TX descriptors list */ + +static struct emac_txdesc_s g_txdesc[CONFIG_SAM34_EMAC_NTXBUFFERS] + __attribute__((aligned(8))); + +/* RX descriptors list */ + +static struct emac_rxdesc_s g_rxdesc[CONFIG_SAM34_EMAC_NRXBUFFERS] + __attribute__((aligned(8))); + +/* Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_txbuffer[CONFIG_SAM34_EMAC_NTXBUFFERS * EMAC_TX_UNITSIZE]; + __attribute__((aligned(8))) + +/* Receive Buffers */ + +static uint8_t g_rxbuffer[CONFIG_SAM34_EMAC_NRXBUFFERS * EMAC_RX_UNITSIZE] + __attribute__((aligned(8))); + +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAM34_EMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, + uint32_t regval, uintptr_t address); +static uint32_t sam_getreg(struct sam_emac_s *priv, uintptr_t addr); +static void sam_putreg(struct sam_emac_s *priv, uintptr_t addr, uint32_t val); +#else +# define sam_getreg(priv,addr) getreg32(addr) +# define sam_putreg(priv,addr,val) putreg32(val,addr) +#endif + +/* Buffer management */ + +static uint16_t sam_txinuse(struct sam_emac_s *priv); +static uint16_t sam_txfree(struct sam_emac_s *priv); +static int sam_buffer_initialize(struct sam_emac_s *priv); +static void sam_buffer_free(struct sam_emac_s *priv); + +/* Common TX logic */ + +static int sam_transmit(struct sam_emac_s *priv); +static int sam_txpoll(struct net_driver_s *dev); +static void sam_dopoll(struct sam_emac_s *priv); + +/* Interrupt handling */ + +static int sam_recvframe(struct sam_emac_s *priv); +static void sam_receive(struct sam_emac_s *priv); +static void sam_txdone(struct sam_emac_s *priv); +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg); +#endif +static int sam_emac_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg); +#endif +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void sam_poll_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg); +#endif +static void sam_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int sam_ifup(struct net_driver_s *dev); +static int sam_ifdown(struct net_driver_s *dev); + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg); +#endif +static int sam_txavail(struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac); +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY Initialization */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv); +#else +# define sam_phydump(priv) +#endif + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv); +#endif +static int sam_phywait(struct sam_emac_s *priv); +static int sam_phyreset(struct sam_emac_s *priv); +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr); +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval); +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval); +static int sam_autonegotiate(struct sam_emac_s *priv); +static bool sam_linkup(struct sam_emac_s *priv); +static int sam_phyinit(struct sam_emac_s *priv); + +/* EMAC Initialization */ + +static void sam_txreset(struct sam_emac_s *priv); +static void sam_rxreset(struct sam_emac_s *priv); +static void sam_emac_reset(struct sam_emac_s *priv); +static void sam_macaddress(struct sam_emac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv); +#endif +static int sam_emac_configure(struct sam_emac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_EMAC_REGDEBUG +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, uint32_t regval, + uintptr_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_EMAC_REGDEBUG +static uint32_t sam_getreg(struct sam_emac_s *priv, uintptr_t address) +{ + uint32_t regval = getreg32(address); + + if (sam_checkreg(priv, false, regval, address)) + { + lldbg("%08x->%08x\n", address, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_EMAC_REGDEBUG +static void sam_putreg(struct sam_emac_s *priv, uintptr_t address, + uint32_t regval) +{ + if (sam_checkreg(priv, true, regval, address)) + { + lldbg("%08x<-%08x\n", address, regval); + } + + putreg32(regval, address); +} +#endif + +/**************************************************************************** + * Function: sam_txinuse + * + * Description: + * Return the number of TX buffers in-use + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers in-use + * + ****************************************************************************/ + +static uint16_t sam_txinuse(struct sam_emac_s *priv) +{ + uint32_t txhead32 = (uint32_t)priv->txhead; + if ((uint32_t)priv->txtail > txhead32) + { + txhead32 += CONFIG_SAM34_EMAC_NTXBUFFERS; + } + + return (uint16_t)(txhead32 - (uint32_t)priv->txtail); +} + +/**************************************************************************** + * Function: sam_txfree + * + * Description: + * Return the number of TX buffers available + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers available + * + ****************************************************************************/ + +static uint16_t sam_txfree(struct sam_emac_s *priv) +{ + /* The number available is equal to the total number of buffers, minus the + * number of buffers in use. Notice that that actual number of buffers is + * the configured size minus 1. + */ + + return (CONFIG_SAM34_EMAC_NTXBUFFERS-1) - sam_txinuse(priv); +} + +/**************************************************************************** + * Function: sam_buffer_initialize + * + * Description: + * Allocate aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function degenerates to a few assignements. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +static int sam_buffer_initialize(struct sam_emac_s *priv) +{ +#ifdef CONFIG_SAM34_EMAC_PREALLOCATE + /* Use pre-allocated buffers */ + + priv->txdesc = g_txdesc; + priv->rxdesc = g_rxdesc; + priv->txbuffer = g_txbuffer; + priv->rxbuffer = g_rxbuffer; + +#else + size_t allocsize; + + /* Allocate buffers */ + + allocsize = CONFIG_SAM34_EMAC_NTXBUFFERS * sizeof(struct emac_txdesc_s); + priv->txdesc = (struct emac_txdesc_s *)kmm_memalign(8, allocsize); + if (!priv->txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->txdesc, 0, allocsize); + + allocsize = CONFIG_SAM34_EMAC_NRXBUFFERS * sizeof(struct emac_rxdesc_s); + priv->rxdesc = (struct emac_rxdesc_s *)kmm_memalign(8, allocsize); + if (!priv->rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->rxdesc, 0, allocsize); + + allocsize = CONFIG_SAM34_EMAC_NTXBUFFERS * EMAC_TX_UNITSIZE; + priv->txbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + allocsize = CONFIG_SAM34_EMAC_NRXBUFFERS * EMAC_RX_UNITSIZE; + priv->rxbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + +#endif + + DEBUGASSERT(((uintptr_t)priv->rxdesc & 7) == 0 && + ((uintptr_t)priv->rxbuffer & 7) == 0 && + ((uintptr_t)priv->txdesc & 7) == 0 && + ((uintptr_t)priv->txbuffer & 7) == 0); + return OK; +} + +/**************************************************************************** + * Function: sam_buffer_free + * + * Description: + * Free aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function does nothing. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_buffer_free(struct sam_emac_s *priv) +{ +#ifndef CONFIG_SAM34_EMAC_PREALLOCATE + /* Free allocated buffers */ + + if (priv->txdesc) + { + kmm_free(priv->txdesc); + priv->txdesc = NULL; + } + + if (priv->rxdesc) + { + kmm_free(priv->rxdesc); + priv->rxdesc = NULL; + } + + if (priv->txbuffer) + { + kmm_free(priv->txbuffer); + priv->txbuffer = NULL; + } + + if (priv->rxbuffer) + { + kmm_free(priv->rxbuffer); + priv->rxbuffer = NULL; + } +#endif +} + +/**************************************************************************** + * Function: sam_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_transmit(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + volatile struct emac_txdesc_s *txdesc; + uint32_t regval; + uint32_t status; + + nllvdbg("d_len: %d txhead: %d\n", dev->d_len, priv->txhead); + sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len); + + /* Check parameter */ + + if (dev->d_len > EMAC_TX_UNITSIZE) + { + nlldbg("ERROR: Packet too big: %d\n", dev->d_len); + return -EINVAL; + } + + /* Pointer to the current TX descriptor */ + + txdesc = &priv->txdesc[priv->txhead]; + + /* If no free TX descriptor, buffer can't be sent */ + + if (sam_txfree(priv) < 1) + { + nlldbg("ERROR: No free TX descriptors\n"); + return -EBUSY; + } + + /* Setup/Copy data to transmission buffer */ + + if (dev->d_len > 0) + { + /* Driver managed the ring buffer */ + + memcpy((void *)txdesc->addr, dev->d_buf, dev->d_len); + } + + /* Update TX descriptor status. */ + + status = dev->d_len | EMACTXD_STA_LAST; + if (priv->txhead == CONFIG_SAM34_EMAC_NTXBUFFERS-1) + { + status |= EMACTXD_STA_WRAP; + } + + /* Update the descriptor status */ + + txdesc->status = status; + + /* Increment the head index */ + + if (++priv->txhead >= CONFIG_SAM34_EMAC_NTXBUFFERS) + { + priv->txhead = 0; + } + + /* Now start transmission (if it is not already done) */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_TSTART; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SAM_TXTIMEOUT, sam_txtimeout_expiry, 1, + (uint32_t)priv); + + /* Set d_len to zero meaning that the d_buf[] packet buffer is again + * available. + */ + + dev->d_len = 0; + + /* If we have no more available TX descriptors, then we must disable the + * RCOMP interrupt to stop further RX processing. Why? Because EACH RX + * packet that is dispatched is also an opportunity to reply with a TX + * packet. So, if we cannot handle an RX packet reply, then we disable + * all RX packet processing. + */ + + if (sam_txfree(priv) < 1) + { + nllvdbg("Disabling RX interrupts\n"); + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_RCOMP); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_txpoll(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + sam_transmit(priv); + + /* Check if the there are any free TX descriptors. We cannot perform + * the TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) == 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: sam_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (sam_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_dopoll(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. */ + + (void)devif_poll(dev, sam_txpoll); + } +} + +/**************************************************************************** + * Function: sam_recvframe + * + * Description: + * The function is called when a frame is received. It scans the RX + * descriptors of the received frame and assembles the full packet/ + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * - Global interrupts are disabled by interrupt handling logic. + * - The RX descriptor D-cache list has been invalided to force fetching + * from RAM. + * + ****************************************************************************/ + +static int sam_recvframe(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc; + struct net_driver_s *dev; + const uint8_t *src; + uint8_t *dest; + uint32_t rxndx; + uint32_t pktlen; + uint16_t copylen; + bool isframe; + + /* Process received RX descriptor. The ownership bit is set by the EMAC + * once it has successfully written a frame to memory. + */ + + dev = &priv->dev; + dev->d_len = 0; + + dest = dev->d_buf; + pktlen = 0; + + rxndx = priv->rxndx; + rxdesc = &priv->rxdesc[rxndx]; + isframe = false; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + sam_cmcc_invalidate((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + + nllvdbg("rxndx: %d\n", rxndx); + + while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0) + { + /* The start of frame bit indicates the beginning of a frame. Discard + * any previous fragments. + */ + + if ((rxdesc->status & EMACRXD_STA_SOF) != 0) + { + /* Skip previous fragments */ + + while (rxndx != priv->rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAM34_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Reset the packet data pointer and packet length */ + + dest = dev->d_buf; + pktlen = 0; + + /* Start to gather buffers into the packet buffer */ + + isframe = true; + } + + /* Increment the working index */ + + if (++rxndx >= CONFIG_SAM34_EMAC_NRXBUFFERS) + { + rxndx = 0; + } + + /* Copy data into the packet buffer */ + + if (isframe) + { + if (rxndx == priv->rxndx) + { + nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n"); + do + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAM34_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + while (rxndx != priv->rxndx); + return -EIO; + } + + /* Get the number of bytes to copy from the buffer */ + + copylen = EMAC_RX_UNITSIZE; + if ((pktlen + copylen) > CONFIG_NET_ETH_MTU) + { + copylen = CONFIG_NET_ETH_MTU - pktlen; + } + + /* Get the data source. Invalidate the source memory region to + * force reload from RAM. + */ + + src = (const uint8_t *)(rxdesc->addr & EMACRXD_ADDR_MASK); + sam_cmcc_invalidate((uintptr_t)src, (uintptr_t)src + copylen); + + /* And do the copy */ + + memcpy(dest, src, copylen); + dest += copylen; + pktlen += copylen; + + /* If the end of frame has been received, return the data */ + + if ((rxdesc->status & EMACRXD_STA_EOF) != 0) + { + /* Frame size from the EMAC */ + + dev->d_len = (rxdesc->status & EMACRXD_STA_FRLEN_MASK); + nllvdbg("packet %d-%d (%d)\n", priv->rxndx, rxndx, dev->d_len); + + /* All data have been copied in the application frame buffer, + * release the RX descriptor + */ + + while (priv->rxndx != rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAM34_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Check if the device packet buffer was large enough to accept + * all of the data. + */ + + nllvdbg("rxndx: %d d_len: %d\n", priv->rxndx, dev->d_len); + + if (pktlen < dev->d_len) + { + nlldbg("ERROR: Buffer size %d; frame size %d\n", dev->d_len, pktlen); + return -E2BIG; + } + + return OK; + } + } + + /* We have not encount the SOF yet... discard this fragment and keep looking */ + + else + { + /* Give ownership back to the EMAC */ + + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + priv->rxndx = rxndx; + } + + /* Process the next buffer */ + + rxdesc = &priv->rxdesc[rxndx]; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + sam_cmcc_invalidate((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + } + + /* No packet was found */ + + priv->rxndx = rxndx; + nllvdbg("rxndx: %d\n", priv->rxndx); + return -EAGAIN; +} + +/**************************************************************************** + * Function: sam_receive + * + * Description: + * An interrupt was received indicating the availability of one or more + * new RX packets in FIFO memory. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_receive(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while sam_recvframe() successfully retrieves valid + * EMAC frames. + */ + + while (sam_recvframe(priv) == OK) + { + sam_dumppacket("Received packet", dev->d_buf, dev->d_len); + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + sam_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + } +} + +/**************************************************************************** + * Function: sam_txdone + * + * Description: + * An interrupt was received indicating that one or more frames have + * completed transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txdone(struct sam_emac_s *priv) +{ + struct emac_txdesc_s *txdesc; + + /* Are there any outstanding transmissions? Loop until either (1) all of + * the TX descriptors have been examined, or (2) until we encounter the + * first descriptor that is still in use by the hardware. + */ + + while (priv->txhead != priv->txtail) + { + /* Yes.. check the next buffer at the tail of the list */ + + txdesc = &priv->txdesc[priv->txtail]; + sam_cmcc_invalidate((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Is this TX descriptor still in use? */ + + if ((txdesc->status & EMACTXD_STA_USED) == 0) + { + /* Yes.. the descriptor is still in use. However, I have seen a + * case (only repeatable on start-up) where the USED bit is never + * set. Yikes! If we have encountered the first still busy + * descriptor, then we should also have TQBD equal to the descriptor + * address. If it is not, then treat is as used anyway. + */ + +#if 0 /* The issue does not exist in the current configuration, but may return */ +#warning REVISIT + if (priv->txtail == 0 && + sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv, SAM_EMAC_TBQB)) + { + txdesc->status = (uint32_t)EMACTXD_STA_USED; + } + else +#endif + { + /* Otherwise, the descriptor is truly in use. Break out of the + * loop now. + */ + + break; + } + } + + /* Increment the tail index */ + + if (++priv->txtail >= CONFIG_SAM34_EMAC_NTXBUFFERS) + { + /* Wrap to the beginning of the TX descriptor list */ + + priv->txtail = 0; + } + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_EMAC_IER, EMAC_INT_RCOMP); + } + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv) +{ + uint32_t isr; + uint32_t rsr; + uint32_t tsr; + uint32_t imr; + uint32_t regval; + uint32_t pending; + uint32_t clrbits; + + isr = sam_getreg(priv, SAM_EMAC_ISR); + rsr = sam_getreg(priv, SAM_EMAC_RSR); + tsr = sam_getreg(priv, SAM_EMAC_TSR); + imr = sam_getreg(priv, SAM_EMAC_IMR); + + pending = isr & ~(imr | EMAC_INT_UNUSED); + nllvdbg("isr: %08x pending: %08x\n", isr, pending); + + /* Check for the completion of a transmission. This should be done before + * checking for received data (because receiving can cause another transmission + * before we had a chance to handle the last one). + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read. + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + if ((pending & EMAC_INT_TCOMP) != 0 || (tsr & EMAC_TSR_TXCOMP) != 0) + { + /* A frame has been transmitted */ + + clrbits = EMAC_TSR_TXCOMP; + + /* Check for Retry Limit Exceeded (RLE) */ + + if ((tsr & EMAC_TSR_RLE) != 0) + { + /* Status RLE & Number of discarded buffers */ + + clrbits = EMAC_TSR_RLE | sam_txinuse(priv); + sam_txreset(priv); + + nlldbg("ERROR: Retry Limit Exceeded TSR: %08x\n", tsr); + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + + /* Check Collision Occurred (COL) */ + + if ((tsr & EMAC_TSR_COL) != 0) + { + nlldbg("ERROR: Collision occurred TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_COL; + } + + /* Check Transmit Frame Corruption due to AHB error (TFC) */ + + if ((tsr & EMAC_TSR_TFC) != 0) + { + nlldbg("ERROR: Transmit Frame Corruption due to AHB error: %08x\n", tsr); + clrbits |= EMAC_TSR_TFC; + } + + /* Check for Transmit Underrun (UND) + * + * ISR:UND is set transmit DMA was not able to read data from memory, + * either because the bus was not granted in time, because a not + * OK hresp(bus error) was returned or because a used bit was read + * midway through frame transmission. If this occurs, the + * transmitter forces bad CRC. Cleared by writing a one to this bit. + */ + + if ((tsr & EMAC_TSR_UND) != 0) + { + nlldbg("ERROR: Transmit Underrun TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_UND; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_TSR, clrbits); + + /* And handle the TX done event */ + + sam_txdone(priv); + } + + /* Check for the receipt of an RX packet. + * + * RXCOMP indicates that a packet has been received and stored in memory. + * The RXCOMP bit is cleared whent he interrupt status register was read. + * RSR:REC indicates that one or more frames have been received and placed + * in memory. This indication is cleared by writing a one to this bit. + */ + + if ((pending & EMAC_INT_RCOMP) != 0 || (rsr & EMAC_RSR_REC) != 0) + { + clrbits = EMAC_RSR_REC; + + /* Check for Receive Overrun. + * + * RSR:RXOVR will be set if the RX FIFO is not able to store the + * receive frame due to a FIFO overflow, or if the receive status + * was not taken at the end of the frame. This bit is also set in + * DMA packet buffer mode if the packet buffer overflows. For DMA + * operation, the buffer will be recovered if an overrun occurs. This + * bit is cleared when set to 1. + */ + + if ((rsr & EMAC_RSR_RXOVR) != 0) + { + nlldbg("ERROR: Receiver overrun RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_RXOVR; + } + + /* Check for buffer not available (BNA) + * + * RSR:BNA means that an attempt was made to get a new buffer and the + * pointer indicated that it was owned by the processor. The DMA will + * reread the pointer each time an end of frame is received until a + * valid pointer is found. This bit is set following each descriptor + * read attempt that fails, even if consecutive pointers are + * unsuccessful and software has in the mean time cleared the status + * flag. Cleared by writing a one to this bit. + */ + + if ((rsr & EMAC_RSR_BNA) != 0) + { + nlldbg("ERROR: Buffer not available RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_BNA; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_RSR, clrbits); + + /* Handle the received packet */ + + sam_receive(priv); + } + +#ifdef CONFIG_DEBUG_NET + /* Check for PAUSE Frame received (PFRE). + * + * ISR:PFRE indicates that a pause frame has been received with non-zero + * pause quantum. Cleared on a read. + */ + + if ((pending & EMAC_INT_PFNZ) != 0) + { + nlldbg("Pause frame received\n"); + } + + /* Check for Pause Time Zero (PTZ) + * + * ISR:PTZ is set Pause Time Zero + */ + + if ((pending & EMAC_INT_PTZ) != 0) + { + nlldbg("Pause TO!\n"); + } +#endif +} + +/**************************************************************************** + * Function: sam_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts */ + + up_enable_irq(SAM_IRQ_EMAC); +} +#endif + +/**************************************************************************** + * Function: sam_emac_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_interrupt(int irq, void *context) +{ + struct sam_emac_s *priv = &g_emac; + +#ifdef CONFIG_NET_NOINTS + uint32_t tsr; + + /* Disable further Ethernet interrupts. Because Ethernet interrupts are + * also disabled if the TX timeout event occurs, there can be no race + * condition here. + */ + + up_disable_irq(SAM_IRQ_EMAC); + + /* Check for the completion of a transmission. Careful: + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read (so + * we cannot read it here). + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + tsr = sam_getreg(priv, SAM_EMAC_TSR); + if ((tsr & EMAC_TSR_TXCOMP) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be do race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_interrupt_work, priv, 0); + +#else + /* Process the interrupt now */ + + sam_interrupt_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: sam_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv) +{ + nlldbg("Timeout!\n"); + + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + sam_ifdown(&priv->dev); + sam_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + */ + + up_disable_irq(SAM_IRQ_EMAC); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txtimeout_work, priv, 0); +#else + /* Process the timeout now */ + + sam_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_poll_process(FAR struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* Update TCP timing states and poll uIP for new XMIT data. */ + + (void)devif_timer(dev, sam_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: sam_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg); + } + +#else + /* Process the interrupt now */ + + sam_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_ifup + * + * Description: + * NuttX Callback: Bring up the EMAC interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifup(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + nlldbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Configure the EMAC interface for normal operation. */ + + nllvdbg("Initialize the EMAC\n"); + sam_emac_configure(priv); + + /* Set the MAC address (should have been configured while we were down) */ + + sam_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + sam_ipv6multicast(priv); +#endif + + /* Initialize for PHY access */ + + ret = sam_phyinit(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phyinit failed: %d\n", ret); + return ret; + } + + /* Auto Negotiate, working in RMII mode */ + + ret = sam_autonegotiate(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_autonegotiate failed: %d\n", ret); + return ret; + } + + while (sam_linkup(priv) == 0); + nllvdbg("Link detected \n"); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, (uint32_t)priv); + + /* Enable the EMAC interrupt */ + + priv->ifup = true; + up_enable_irq(SAM_IRQ_EMAC); + return OK; +} + +/**************************************************************************** + * Function: sam_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifdown(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + irqstate_t flags; + + nlldbg("Taking the network down\n"); + + /* Disable the EMAC interrupt */ + + flags = enter_critical_section(); + up_disable_irq(SAM_IRQ_EMAC); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the sam_ifup() always + * successfully brings the interface back up. + */ + + sam_emac_reset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: sam_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv) +{ + nllvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + sam_dopoll(priv); + } +} + +/**************************************************************************** + * Function: sam_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int sam_txavail(struct net_driver_s *dev) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + sam_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_hashindx + * + * Description: + * Cacuclate the hash address register index. The hash address register + * is 64 bits long and takes up two locations in the memory map. The + * destination address is reduced to a 6-bit index into the 64-bit Hash + * Register using the following hash function: The hash function is an XOR + * of every sixth bit of the destination address. + * + * ndx:05 = da:05 ^ da:11 ^ da:17 ^ da:23 ^ da:29 ^ da:35 ^ da:41 ^ da:47 + * ndx:04 = da:04 ^ da:10 ^ da:16 ^ da:22 ^ da:28 ^ da:34 ^ da:40 ^ da:46 + * ndx:03 = da:03 ^ da:09 ^ da:15 ^ da:21 ^ da:27 ^ da:33 ^ da:39 ^ da:45 + * ndx:02 = da:02 ^ da:08 ^ da:14 ^ da:20 ^ da:26 ^ da:32 ^ da:38 ^ da:44 + * ndx:01 = da:01 ^ da:07 ^ da:13 ^ da:19 ^ da:25 ^ da:31 ^ da:37 ^ da:43 + * ndx:00 = da:00 ^ da:06 ^ da:12 ^ da:18 ^ da:24 ^ da:30 ^ da:36 ^ da:42 + * + * Where da:00 represents the least significant bit of the first byte + * received and da:47 represents the most significant bit of the last byte + * received. + * + * Input Parameters: + * mac - The multicast address to be hashed + * + * Returned Value: + * The 6-bit hash table index + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac) +{ + unsigned int ndx; + + /* Isolate: mac[0] + * ... 05 04 03 02 01 00] */ + + ndx = mac[0]; + + /* Isolate: mac[1] mac[0] + * ...11 10 09 08] [07 06 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + */ + + ndx ^= (mac[1] << 2) | (mac[0] >> 6); + + /* Isolate: mac[2] mac[1] + * ... 17 16] [15 14 13 12 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + */ + + ndx ^= (mac[2] << 4) | (mac[1] >> 4); + + /* Isolate: mac[2] + * [23 22 21 20 19 18 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + */ + + ndx ^= (mac[2] >> 2); + + /* Isolate: mac[3] + * ... 29 28 27 26 25 24] + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + */ + + ndx ^= mac[3]; + + /* Isolate: mac[4] mac[3] + * ... 35 34 33 32] [31 30 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + */ + + ndx ^= (mac[4] << 2) | (mac[3] >> 6); + + /* Isolate: mac[5] mac[4] + * ... 41 40] [39 38 37 36 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + */ + + ndx ^= (mac[5] << 4) | (mac[4] >> 4); + + /* Isolate: mac[5] + * [47 46 45 44 43 42 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + * XOR: 47 46 45 44 43 42 + */ + + ndx ^= (mac[5] >> 2); + + /* Mask out the garbage bits and return the 6-bit index */ + + return ndx & 0x3f; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uintptr_t regaddr; + uint32_t regval; + unsigned int ndx; + unsigned int bit; + + UNUSED(priv); + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Add the multicast address to the hardware multicast hash table */ + + if (ndx >= 32) + { + regaddr = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr); + regval |= bit; + sam_putreg(priv, regaddr, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~EMAC_NCFGR_UNIHEN; /* Disable unicast matching */ + regval |= EMAC_NCFGR_MTIHEN; /* Enable multicast matching */ + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + return OK; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regaddr1; + unsigned int regaddr2; + unsigned int ndx; + unsigned int bit; + + UNUSED(priv); + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Remove the multicast address to the hardware multicast hast table */ + + if (ndx >= 32) + { + regaddr1 = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + regaddr2 = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr1 = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + regaddr2 = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr1); + regval &= ~bit; + sam_putreg(priv, regaddr1, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + /* Are all multicast address matches disabled? */ + + if (regval == 0 && sam_getreg(priv, regaddr2) == 0) + { + /* Yes.. disable all address matching */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_UNIHEN | EMAC_NCFGR_MTIHEN); + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_ioctl + * + * Description: + * Handles driver ioctl calls: + * + * SIOCMIINOTIFY - Set up to received notifications from PHY interrupting + * events. + * + * SIOCGMIIPHY, SIOCGMIIREG, and SIOCSMIIREG: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = sam_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = priv->phyaddr; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Read from the requested register */ + + ret = sam_phyread(priv, req->phy_id, req->reg_num, &req->val_out); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Write to the requested register */ + + ret = sam_phywrite(priv, req->phy_id, req->reg_num, req->val_in); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: sam_phydump + * + * Description: + * Dump the contents of PHY registers + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + +#ifdef CONFIG_SAM34_EMAC_RMII + nllvdbg("RMII Registers (Address %02x)\n", priv->phyaddr); +#else /* defined(CONFIG_SAM34_EMAC_MII) */ + nllvdbg("MII Registers (Address %02x)\n", priv->phyaddr); +#endif + + sam_phyread(priv, priv->phyaddr, MII_MCR, &phyval); + nllvdbg(" MCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_MSR, &phyval); + nllvdbg(" MSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_ADVERTISE, &phyval); + nllvdbg(" ADVERTISE: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_LPA, &phyval); + nllvdbg(" LPR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, CONFIG_SAM34_EMAC_PHYSR, &phyval); + nllvdbg(" PHYSR: %04x\n", phyval); + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); +} +#endif + +/**************************************************************************** + * Function: sam_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv) +{ +#if defined(CONFIG_ETH0_PHY_KSZ8051) || defined(CONFIG_ETH0_PHY_KSZ8081) + uint32_t regval; + uint16_t phyval; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Read the interrupt status register in order to clear any pending + * interrupts + */ + + ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval); + if (ret == OK) + { + /* Enable link up/down interrupts */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, + (MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); + } + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; + +#else +# warning Missing logic + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Function: sam_phywait + * + * Description: + * Wait for the PHY to become IDLE + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +static int sam_phywait(struct sam_emac_s *priv) +{ + volatile unsigned int retries; + + /* Loop for the configured number of attempts */ + + for (retries = 0; retries < PHY_RETRY_MAX; retries++) + { + /* Is the PHY IDLE */ + + if ((sam_getreg(priv, SAM_EMAC_NSR) & EMAC_NSR_IDLE) != 0) + { + return OK; + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: sam_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyreset(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t mcr; + int timeout; + int ret; + + nllvdbg(" sam_phyreset\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Reset the PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + nlldbg("ERROR: sam_phywrite failed: %d\n", ret); + } + + /* Wait for the PHY reset to complete */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < 10; timeout++) + { + mcr = MII_MCR_RESET; + int result = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (result < 0) + { + nlldbg("ERROR: Failed to read the MCR register: %d\n", ret); + ret = result; + } + else if ((mcr & MII_MCR_RESET) == 0) + { + ret = OK; + break; + } + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyfind + * + * Description: + * Verify the PHY address and, if it is bad, try to one that works. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr) +{ + uint32_t regval; + uint16_t phyval; + uint8_t candidate; + unsigned int offset; + int ret = -ESRCH; + + nllvdbg("Find a valid PHY address\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + candidate = *phyaddr; + + /* Check current candidate address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == MII_OUI_MSB) + { + *phyaddr = candidate; + ret = OK; + } + + /* The current address does not work... try another */ + + else + { + nlldbg("ERROR: sam_phyread failed for PHY address %02x: %d\n", + candidate, ret); + + for (offset = 0; offset < 32; offset++) + { + /* Get the next candidate PHY address */ + + candidate = (candidate + 1) & 0x1f; + + /* Try reading the PHY ID from the candidate PHY address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == MII_OUI_MSB) + { + ret = OK; + break; + } + } + } + + if (ret == OK) + { + nllvdbg(" PHYID1: %04x PHY addr: %d\n", phyval, candidate); + *phyaddr = candidate; + sam_phyread(priv, candidate, CONFIG_SAM34_EMAC_PHYSR, &phyval); + nllvdbg(" PHYSR: %04x PHY addr: %d\n", phyval, candidate); + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(0) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_READ | EMAC_MAN_WZO; + +#ifndef CONFIG_SAM34_EMAC_CLAUSE45 + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, bit + * 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; +#endif + + sam_putreg(priv, SAM_EMAC_MAN, regval); + + /* Wait until the PHY is again idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Return data */ + + *phyval = (uint16_t)(sam_getreg(priv, SAM_EMAC_MAN) & EMAC_MAN_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: sam_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The 16-bit value to write to the PHY register. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(phyval) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_WRITE | EMAC_MAN_WZO; + +#ifndef CONFIG_SAM34_EMAC_CLAUSE45 + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, bit + * 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; +#endif + + sam_putreg(priv, SAM_EMAC_MAN, regval); + + /* Wait until the PHY is again IDLE */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Function: sam_autonegotiate + * + * Description: + * Autonegotiate speed and duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_autonegotiate(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyid1; + uint16_t phyid2; + uint16_t mcr; + uint16_t msr; + uint16_t advertise; + uint16_t lpa; + int timeout; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Verify tht we can read the PHYID register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID1, &phyid1); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID1\n"); + goto errout; + } + + nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr); + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID2, &phyid2); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID2\n"); + goto errout; + } + + nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr); + + if (phyid1 == MII_OUI_MSB && + ((phyid2 & MII_PHYID2_OUI_MASK) >> MII_PHYID2_OUI_SHIFT) == MII_OUI_LSB) + { + nllvdbg(" Vendor Model Number: %04x\n", + (phyid2 & MII_PHYID2_MODEL_MASK) >> MII_PHYID2_MODEL_SHIFT); + nllvdbg(" Model Revision Number: %04x\n", + (phyid2 & MII_PHYID2_REV_MASK) >> MII_PHYID2_REV_SHIFT); + } + else + { + nlldbg("ERROR: PHY not recognized\n"); + } + + /* Setup control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr &= ~MII_MCR_ANENABLE; /* Remove autonegotiation enable */ + mcr &= ~(MII_MCR_LOOPBACK | MII_MCR_PDOWN); + mcr |= MII_MCR_ISOLATE; /* Electrically isolate PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Set the Auto_negotiation Advertisement Register MII advertising for + * Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 + */ + + advertise = MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_8023; + + ret = sam_phywrite(priv, priv->phyaddr, MII_ADVERTISE, advertise); + if (ret < 0) + { + nlldbg("ERROR: Failed to write ANAR\n"); + goto errout; + } + + /* Read and modify control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr |= (MII_MCR_SPEED100 | MII_MCR_ANENABLE | MII_MCR_FULLDPLX); + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Restart Auto_negotiation */ + + mcr |= MII_MCR_ANRESTART; + mcr &= ~MII_MCR_ISOLATE; + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + nllvdbg(" MCR: %04x\n", mcr); + + /* Check AutoNegotiate complete */ + + timeout = 0; + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR\n"); + goto errout; + } + + /* Completed successfully? */ + + if ((msr & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. break out of the loop */ + + nllvdbg("AutoNegotiate complete\n"); + break; + } + + /* No.. check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Get the AutoNeg Link partner base page */ + + ret = sam_phyread(priv, priv->phyaddr, MII_LPA, &lpa); + if (ret < 0) + { + nlldbg("ERROR: Failed to read ANLPAR\n"); + goto errout; + } + + /* Setup the EMAC link speed */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if (((advertise & lpa) & MII_ADVERTISE_100BASETXFULL) != 0) + { + /* Set MII for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXFULL) != 0) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + else if (((advertise & lpa) & MII_ADVERTISE_100BASETXHALF) != 0) + { + /* Set MII for 100BaseTX and half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } +#if 0 + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXHALF) != 0) + { + /* set MII for 10BaseT and half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Select RMII/MII */ + + regval = sam_getreg(priv, SAM_EMAC_UR); +#ifdef CONFIG_SAM34_EMAC_RMII + regval &= ~EMAC_UR_MII; +#else /* defined(CONFIG_SAM34_EMAC_MII) */ + regval |= EMAC_UR_MII; +#endif + sam_putreg(priv, SAM_EMAC_UR, regval); + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_linkup + * + * Description: + * Check if the link is up + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * true: The link is up + * + ****************************************************************************/ + +static bool sam_linkup(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t msr; + uint16_t physr; + bool linkup = false; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR: %d\n", ret); + goto errout; + } + + if ((msr & MII_MSR_LINKSTATUS) == 0) + { + nlldbg("ERROR: MSR LinkStatus: %04x\n", msr); + goto errout; + } + + /* Re-configure Link speed */ + + ret = sam_phyread(priv, priv->phyaddr, CONFIG_SAM34_EMAC_PHYSR, &physr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYSR: %d\n", ret); + goto errout; + } + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if ((msr & MII_MSR_100BASETXFULL) != 0 && PHYSR_IS100FDX(physr)) + { + /* Set EMAC for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if ((msr & MII_MSR_10BASETXFULL) != 0 && PHYSR_IS10FDX(physr)) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + + else if ((msr & MII_MSR_100BASETXHALF) != 0 && PHYSR_IS100HDX(physr)) + { + /* Set MII for 100BaseTX and Half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } + +#if 0 + else if ((msr & MII_MSR_10BASETXHALF) != 0 && PHYSR_IS10HDX(physr)) + { + /* Set MII for 10BaseT and Half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Start the EMAC transfers */ + + nllvdbg("Link is up\n"); + linkup = true; + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + return linkup; +} + +/**************************************************************************** + * Function: sam_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_phyinit(struct sam_emac_s *priv) +{ + uint32_t regval; + int ret; + + /* Configure PHY clocking */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~EMAC_NCFGR_CLK_MASK; + +#if BOARD_MCK_FREQUENCY > (160*1000*1000) +# error Supported MCK frequency +#elif BOARD_MCK_FREQUENCY > (80*1000*1000) + regval |= EMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */ +#elif BOARD_MCK_FREQUENCY > (40*1000*1000) + regval |= EMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */ +#elif BOARD_MCK_FREQUENCY > (20*1000*1000) + regval |= EMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */ +#else + regval |= EMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */ +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Check the PHY Address */ + + priv->phyaddr = CONFIG_SAM34_EMAC_PHYADDR; + ret = sam_phyfind(priv, &priv->phyaddr); + if (ret < 0) + { + nlldbg("ERROR: sam_phyfind failed: %d\n", ret); + return ret; + } + + if (priv->phyaddr != CONFIG_SAM34_EMAC_PHYADDR) + { + sam_phyreset(priv); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_ethgpioconfig + * + * Description: + * Configure GPIOs for the EMAC MII interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_ethgpioconfig(struct sam_emac_s *priv) +{ + /* Configure PIO pins to support EMAC in MII mode */ + + sam_configgpio(GPIO_EMAC_TXCK); /* Transmit Clock (or Reference Clock) */ + sam_configgpio(GPIO_EMAC_TXEN); /* Transmit Enable */ + sam_configgpio(GPIO_EMAC_TX0); /* Transmit data TXD0 */ + sam_configgpio(GPIO_EMAC_TX1); /* Transmit data TXD1 */ + sam_configgpio(GPIO_EMAC_TX2); /* Transmit data TXD2 */ + sam_configgpio(GPIO_EMAC_TX3); /* Transmit data TXD3 */ +//sam_configgpio(GPIO_EMAC_TXER); /* Transmit Coding Error */ + sam_configgpio(GPIO_EMAC_RXCK); /* Receive Clock */ + sam_configgpio(GPIO_EMAC_RXDV); /* Receive Data Valid */ + sam_configgpio(GPIO_EMAC_RX0); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC_RX1); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC_RX2); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC_RX3); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC_RXER); /* Receive Error */ + sam_configgpio(GPIO_EMAC_CRS); /* Carrier Sense and Data Valid */ + sam_configgpio(GPIO_EMAC_COL); /* Collision Detect */ + sam_configgpio(GPIO_EMAC_MDC); /* Management Data Clock */ + sam_configgpio(GPIO_EMAC_MDIO); /* Management Data Input/Output */ +} + +/**************************************************************************** + * Function: sam_txreset + * + * Description: + * Reset the transmit logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_txreset(struct sam_emac_s *priv) +{ + uint8_t *txbuffer = priv->txbuffer; + struct emac_txdesc_s *txdesc = priv->txdesc; + uintptr_t bufaddr; + uint32_t regval; + int ndx; + + /* Disable TX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Configure the TX descriptors. */ + + priv->txhead = 0; + priv->txtail = 0; + + for (ndx = 0; ndx < CONFIG_SAM34_EMAC_NTXBUFFERS; ndx++) + { + bufaddr = (uint32_t)(&(txbuffer[ndx * EMAC_TX_UNITSIZE])); + + /* Set the buffer address and mark the descriptor as in used by firmware */ + + txdesc[ndx].addr = bufaddr; + txdesc[ndx].status = EMACTXD_STA_USED; + } + + /* Mark the final descriptor in the list */ + + txdesc[CONFIG_SAM34_EMAC_NTXBUFFERS - 1].status = + EMACTXD_STA_USED | EMACTXD_STA_WRAP; + + /* Set the Transmit Buffer Queue Pointer Register */ + + sam_putreg(priv, SAM_EMAC_TBQB, (uintptr_t)txdesc); +} + +/**************************************************************************** + * Function: sam_rxreset + * + * Description: + * Reset the receive logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_rxreset(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc = priv->rxdesc; + uint8_t *rxbuffer = priv->rxbuffer; + uint32_t bufaddr; + uint32_t regval; + int ndx; + + /* Disable RX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_RXEN; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Configure the RX descriptors. */ + + priv->rxndx = 0; + for (ndx = 0; ndx < CONFIG_SAM34_EMAC_NRXBUFFERS; ndx++) + { + bufaddr = (uintptr_t)(&(rxbuffer[ndx * EMAC_RX_UNITSIZE])); + DEBUGASSERT((bufaddr & ~EMACRXD_ADDR_MASK) == 0); + + /* Set the buffer address and remove EMACRXD_ADDR_OWNER and + * EMACRXD_ADDR_WRAP. + */ + + rxdesc[ndx].addr = bufaddr; + rxdesc[ndx].status = 0; + } + + /* Mark the final descriptor in the list */ + + rxdesc[CONFIG_SAM34_EMAC_NRXBUFFERS - 1].addr |= EMACRXD_ADDR_WRAP; + + /* Set the Receive Buffer Queue Pointer Register */ + + sam_putreg(priv, SAM_EMAC_RBQB, (uintptr_t)rxdesc); +} + +/**************************************************************************** + * Function: sam_emac_reset + * + * Description: + * Reset the EMAC block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_reset(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NETDEV_PHY_IOCTL + uint32_t regval; + + /* We are supporting PHY IOCTLs, then do not reset the MAC. If we do, + * then we cannot communicate with the PHY. So, instead, just disable + * interrupts, cancel timers, and disable TX and RX. + */ + + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Disable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~(EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR, regval); + +#else + + /* Disable all EMAC interrupts */ + + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Make sure that RX and TX are disabled; clear statistics registers */ + + sam_putreg(priv, SAM_EMAC_NCR, EMAC_NCR_CLRSTAT); + + /* Disable clocking to the EMAC peripheral */ + + sam_emac_disableclk(); + +#endif +} + +/**************************************************************************** + * Function: sam_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_macaddress(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address */ + + regval = (uint32_t)dev->d_mac.ether_addr_octet[0] | + (uint32_t)dev->d_mac.ether_addr_octet[1] << 8 | + (uint32_t)dev->d_mac.ether_addr_octet[2] << 16 | + (uint32_t)dev->d_mac.ether_addr_octet[3] << 24; + sam_putreg(priv, SAM_EMAC_SAB1, regval); + + regval = (uint32_t)dev->d_mac.ether_addr_octet[4] | + (uint32_t)dev->d_mac.ether_addr_octet[5] << 8; + sam_putreg(priv, SAM_EMAC_SAT1, regval); +} + +/**************************************************************************** + * Function: sam_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)sam_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_emac_configure + * + * Description: + * Configure the EMAC interface for normal operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_configure(struct sam_emac_s *priv) +{ + uint32_t regval; + + nllvdbg("Entry\n"); + + /* Enable clocking to the EMAC peripheral */ + + sam_emac_enableclk(); + + /* Disable TX, RX, clear statistics. Disable all interrupts. */ + + sam_putreg(priv, SAM_EMAC_NCR, EMAC_NCR_CLRSTAT); + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Clear all status bits in the receive status register. */ + + regval = (EMAC_RSR_RXOVR | EMAC_RSR_REC | EMAC_RSR_BNA); + sam_putreg(priv, SAM_EMAC_RSR, regval); + + /* Clear all status bits in the transmit status register */ + + regval = (EMAC_TSR_UBR | EMAC_TSR_COL | EMAC_TSR_RLE | EMAC_TSR_TFC | + EMAC_TSR_TXCOMP | EMAC_TSR_UND); + sam_putreg(priv, SAM_EMAC_TSR, regval); + + /* Clear any pending interrupts */ + + (void)sam_getreg(priv, SAM_EMAC_ISR); + + /* Enable/disable the copy of data into the buffers, ignore broadcasts. + * Don't copy FCS. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval |= (EMAC_NCFGR_RFCS | EMAC_NCFGR_PEN); + +#ifdef CONFIG_NET_PROMISCUOUS + regval |= EMAC_NCFGR_CAF; +#else + regval &= ~EMAC_NCFGR_CAF; +#endif + +#ifdef CONFIG_SAM34_EMAC_NBC + regval |= EMAC_NCFGR_NBC; +#else + regval &= ~EMAC_NCFGR_NBC; +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Reset TX and RX */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Enable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= (EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Setup the interrupts for TX events, RX events, and error events */ + + regval = (EMAC_INT_RCOMP | EMAC_INT_RXUBR | EMAC_INT_TUR | EMAC_INT_RLEX | + EMAC_INT_TFC | EMAC_INT_TCOMP | EMAC_INT_ROVR | EMAC_INT_HRESP | + EMAC_INT_PFNZ | EMAC_INT_PTZ); + sam_putreg(priv, SAM_EMAC_IER, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +void up_netinitialize(void) +{ + struct sam_emac_s *priv = &g_emac; + int ret; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct sam_emac_s)); + priv->dev.d_ifup = sam_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = sam_ifdown; /* I/F down callback */ + priv->dev.d_txavail = sam_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = sam_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = sam_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = sam_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)&g_emac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); + if (!priv->txpoll) + { + nlldbg("ERROR: Failed to create periodic poll timer\n"); + return; + } + + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + if (!priv->txtimeout) + { + nlldbg("ERROR: Failed to create periodic poll timer\n"); + goto errout_with_txpoll; + } + + /* Configure PIO pins to support EMAC MII */ + + sam_ethgpioconfig(priv); + + /* Allocate buffers */ + + ret = sam_buffer_initialize(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_buffer_initialize failed: %d\n", ret); + goto errout_with_txtimeout; + } + + /* Attach the IRQ to the driver. It will not be enabled at the AIC until + * the interface is in the 'up' state. + */ + + ret = irq_attach(SAM_IRQ_EMAC, sam_emac_interrupt); + if (ret < 0) + { + nlldbg("ERROR: Failed to attach the handler to the IRQ%d\n", SAM_IRQ_EMAC); + goto errout_with_buffers; + } + + /* Enable clocking to the EMAC peripheral (just for sam_ifdown()) */ + + sam_emac_enableclk(); + + /* Put the interface in the down state (disabling clocking again). */ + + ret = sam_ifdown(&priv->dev); + if (ret < 0) + { + nlldbg("ERROR: Failed to put the interface in the down state: %d\n", ret); + goto errout_with_buffers; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + ret = netdev_register(&priv->dev, NET_LL_ETHERNET); + if (ret >= 0) + { + return; + } + + nlldbg("ERROR: netdev_register() failed: %d\n", ret); + +errout_with_buffers: + sam_buffer_free(priv); +errout_with_txtimeout: + wd_delete(priv->txtimeout); +errout_with_txpoll: + wd_delete(priv->txpoll); +} + +#endif /* CONFIG_NET && CONFIG_SAM34_EMAC */ diff --git a/arch/arm/src/sam34/sam_emac.h b/arch/arm/src/sam34/sam_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..d8dc0160b6d80517c4698a0773f654251f9ff9fa --- /dev/null +++ b/arch/arm/src/sam34/sam_emac.h @@ -0,0 +1,124 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_ethernet.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_ETHERNET_H +#define __ARCH_ARM_SRC_SAM34_SAM_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_emac.h" + +#ifdef CONFIG_SAM34_EMAC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Definitions for use with sam_phy_boardinitialize */ + +#define EMAC_INTF 0 + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * Initialize the EMAC driver. Also prototyped in up_internal.h. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +void up_netinitialize(void); + +/************************************************************************************ + * Function: sam_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_SAM34_PHYINIT is defined in the configuration then the board specific + * logic must provide sam_phyinitialize(); The SAM34 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_PHYINIT +int sam_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAM34_EMAC */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_ETHERNET_H */ + diff --git a/arch/arm/src/sam34/sam_gpio.c b/arch/arm/src/sam34/sam_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..b0f45e89e7ba95b4baa96feceb1b4dd55e19e124 --- /dev/null +++ b/arch/arm/src/sam34/sam_gpio.c @@ -0,0 +1,532 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_gpio.c + * General Purpose Input/Output (GPIO) logic for the SAM3U, SAM4S and SAM4E + * + * Copyright (C) 2010, 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_gpio.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3u_pio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_pio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_pio.h" +#else +# error Unrecognized SAM architecture +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +static const char g_portchar[4] = { 'A', 'B', 'C', 'D' }; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpiobase + * + * Description: + * Return the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uintptr_t sam_gpiobase(gpio_pinset_t cfgset) +{ + int port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + return SAM_PION_BASE(port); +} + +/**************************************************************************** + * Name: sam_gpiopin + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline int sam_gpiopin(gpio_pinset_t cfgset) +{ + return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configinput(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ +#ifdef GPIO_HAVE_SCHMITT + uint32_t regval; +#endif + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Check if filtering should be enabled */ + + if ((cfgset & GPIO_CFG_DEGLITCH) != 0) + { + putreg32(pin, base + SAM_PIO_IFER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_IFDR_OFFSET); + } + +#ifdef GPIO_HAVE_SCHMITT + /* Enable/disable the Schmitt trigger */ + + regval = getreg32(base + SAM_PIO_SCHMITT_OFFSET); + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + regval |= pin; + } + else + { + regval &= ~pin; + } + putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET); +#endif + + /* Configure the pin as an input and enable the GPIO function */ + + putreg32(pin, base + SAM_PIO_ODR_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + + /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and + * IFDGSR registers. This would probably best be done with + * another, new API... perhaps sam_configfilter() + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configoutput(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Enable the open drain driver if requrested */ + + if ((cfgset & GPIO_CFG_OPENDRAIN) != 0) + { + putreg32(pin, base + SAM_PIO_MDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_MDDR_OFFSET); + } + + /* Set default value */ + + if ((cfgset & GPIO_OUTPUT_SET) != 0) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + + /* Configure the pin as an output and enable the GPIO function */ + + putreg32(pin, base + SAM_PIO_OER_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a GPIO pin driven by a peripheral A or B signal based on + * bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configperiph(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + uint32_t regval; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + +#ifdef GPIO_HAVE_PERIPHCD + /* Configure pin, depending upon the peripheral A, B, C or D + * + * PERIPHA: ABCDSR1[n] = 0 ABCDSR2[n] = 0 + * PERIPHB: ABCDSR1[n] = 1 ABCDSR2[n] = 0 + * PERIPHC: ABCDSR1[n] = 0 ABCDSR2[n] = 1 + * PERIPHD: ABCDSR1[n] = 1 ABCDSR2[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABCDSR1_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || + (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHC) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(regval, base + SAM_PIO_ABCDSR1_OFFSET); + + regval = getreg32(base + SAM_PIO_ABCDSR2_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || + (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHB) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(regval, base + SAM_PIO_ABCDSR2_OFFSET); + +#else + /* Configure pin, depending upon the peripheral A or B: + * + * PERIPHA: ABSR[n] = 0 + * PERIPHB: ABSR[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABSR_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(regval, base + SAM_PIO_ABSR_OFFSET); +#endif + + /* Disable PIO functionality */ + + putreg32(pin, base + SAM_PIO_PDR_OFFSET); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configgpio(gpio_pinset_t cfgset) +{ + uintptr_t base = sam_gpiobase(cfgset); + uint32_t pin = sam_gpiopin(cfgset); + irqstate_t flags; + int ret; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Enable writing to GPIO registers */ + + putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + + /* Handle the pin configuration according to pin type */ + + switch (cfgset & GPIO_MODE_MASK) + { + case GPIO_INPUT: + ret = sam_configinput(base, pin, cfgset); + break; + + case GPIO_OUTPUT: + ret = sam_configoutput(base, pin, cfgset); + break; + + case GPIO_PERIPHA: + case GPIO_PERIPHB: +#ifdef GPIO_HAVE_PERIPHCD + case GPIO_PERIPHC: + case GPIO_PERIPHD: +#endif + ret = sam_configperiph(base, pin, cfgset); + break; + + default: + ret = -EINVAL; + break; + } + + /* Disable writing to GPIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: sam_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void sam_gpiowrite(gpio_pinset_t pinset, bool value) +{ + uintptr_t base = sam_gpiobase(pinset); + uint32_t pin = sam_gpiopin(pinset); + + if (value) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } +} + +/**************************************************************************** + * Name: sam_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool sam_gpioread(gpio_pinset_t pinset) +{ + uintptr_t base = sam_gpiobase(pinset); + uint32_t pin = sam_gpiopin(pinset); + uint32_t regval; + + if ((pinset & GPIO_MODE_MASK) == GPIO_OUTPUT) + { + regval = getreg32(base + SAM_PIO_ODSR_OFFSET); + } + else + { + regval = getreg32(base + SAM_PIO_PDSR_OFFSET); + } + + return (regval & pin) != 0; +} + +/************************************************************************************ + * Function: sam_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int port; + + /* Get the base address associated with the PIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = SAM_PION_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + lldbg("PIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" PSR: %08x OSR: %08x IFSR: %08x ODSR: %08x\n", + getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_OSR_OFFSET), + getreg32(base + SAM_PIO_IFSR_OFFSET), getreg32(base + SAM_PIO_ODSR_OFFSET)); + lldbg(" PDSR: %08x IMR: %08x ISR: %08x MDSR: %08x\n", + getreg32(base + SAM_PIO_PDSR_OFFSET), getreg32(base + SAM_PIO_IMR_OFFSET), + getreg32(base + SAM_PIO_ISR_OFFSET), getreg32(base + SAM_PIO_MDSR_OFFSET)); +#if defined(CONFIG_ARCH_CHIP_SAM3U) + lldbg(" ABSR: %08x SCIFSR: %08x DIFSR: %08x IFDGSR: %08x\n", + getreg32(base + SAM_PIO_ABSR_OFFSET), getreg32(base + SAM_PIO_SCIFSR_OFFSET), + getreg32(base + SAM_PIO_DIFSR_OFFSET), getreg32(base + SAM_PIO_IFDGSR_OFFSET)); +#elif defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) + lldbg(" ABCDSR: %08x %08x IFSCSR: %08x PPDSR: %08x\n", + getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET), + getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIO_PPDSR_OFFSET)); +#endif + lldbg(" PUSR: %08x SCDR: %08x OWSR: %08x AIMMR: %08x\n", + getreg32(base + SAM_PIO_PUSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET), + getreg32(base + SAM_PIO_OWSR_OFFSET), getreg32(base + SAM_PIO_AIMMR_OFFSET)); + lldbg(" ESR: %08x LSR: %08x ELSR: %08x FELLSR: %08x\n", + getreg32(base + SAM_PIO_ESR_OFFSET), getreg32(base + SAM_PIO_LSR_OFFSET), + getreg32(base + SAM_PIO_ELSR_OFFSET), getreg32(base + SAM_PIO_FELLSR_OFFSET)); + lldbg(" FRLHSR: %08x LOCKSR: %08x WPMR: %08x WPSR: %08x\n", + getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET), + getreg32(base + SAM_PIO_WPMR_OFFSET), getreg32(base + SAM_PIO_WPSR_OFFSET)); +#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) + lldbg(" PCMR: %08x PCIMR: %08x PCISR: %08x PCRHR: %08x\n", + getreg32(base + SAM_PIO_PCMR_OFFSET), getreg32(base + SAM_PIO_PCIMR_OFFSET), + getreg32(base + SAM_PIO_PCISR_OFFSET), getreg32(base + SAM_PIO_PCRHR_OFFSET)); +#ifdef CONFIG_ARCH_CHIP_SAM4E + lldbg("SCHMITT: %08x DELAYR:%08x\n", + getreg32(base + SAM_PIO_SCHMITT_OFFSET), getreg32(base + SAM_PIO_DELAYR_OFFSET)); +#else + lldbg("SCHMITT: %08x\n", + getreg32(base + SAM_PIO_SCHMITT_OFFSET)); +#endif +#endif + leave_critical_section(flags); + return OK; +} +#endif diff --git a/arch/arm/src/sam34/sam_gpio.h b/arch/arm/src/sam34/sam_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..f8f267ef5e39a95025affce1248a5e82c06d9707 --- /dev/null +++ b/arch/arm/src/sam34/sam_gpio.h @@ -0,0 +1,217 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_gpio.h + * + * Copyright (C) 2009-2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_GPIO_H +#define __ARCH_ARM_SRC_SAM34_SAM_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "sam3u_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "sam3x_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "sam4cm_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "sam4e_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "sam4l_gpio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "sam4s_gpio.h" +#else +# error Unrecognized SAM architecture +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +#if defined(CONFIG_SAM34_GPIOA_IRQ) || defined(CONFIG_SAM34_GPIOB_IRQ) || \ + defined(CONFIG_SAM34_GPIOC_IRQ) || defined(CONFIG_SAM34_GPIOD_IRQ) || \ + defined(CONFIG_SAM34_GPIOE_IRQ) || defined(CONFIG_SAM34_GPIOF_IRQ) +# define CONFIG_SAM34_GPIO_IRQ 1 +#else +# undef CONFIG_SAM34_GPIO_IRQ +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_GPIO_IRQ +void sam_gpioirqinitialize(void); +#else +# define sam_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: sam_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int sam_configgpio(gpio_pinset_t cfgset); + +/************************************************************************************ + * Name: sam_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void sam_gpiowrite(gpio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: sam_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool sam_gpioread(gpio_pinset_t pinset); + +/************************************************************************************ + * Name: sam_gpioirq + * + * Description: + * Configure an interrupt for the specified GPIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_GPIO_IRQ +void sam_gpioirq(gpio_pinset_t pinset); +#else +# define sam_gpioirq(pinset) +#endif + +/************************************************************************************ + * Name: sam_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_GPIO_IRQ +void sam_gpioirqenable(int irq); +#else +# define sam_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: sam_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAM34_GPIO_IRQ +void sam_gpioirqdisable(int irq); +#else +# define sam_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: sam_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumpgpio(uint32_t pinset, const char *msg); +#else +# define sam_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_GPIO_H */ diff --git a/arch/arm/src/sam34/sam_gpioirq.c b/arch/arm/src/sam34/sam_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..4367e81463498a37a2076a7f32e595e8073a9cf3 --- /dev/null +++ b/arch/arm/src/sam34/sam_gpioirq.c @@ -0,0 +1,472 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_gpioirq.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "chip/sam_pmc.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3u_pio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_pio.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) || defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_pio.h" +#else +# error Unrecognized SAM architecture +#endif + +#ifdef CONFIG_SAM34_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpiobase + * + * Description: + * Return the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uint32_t sam_gpiobase(gpio_pinset_t pinset) +{ + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + return SAM_PION_BASE(port >> GPIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: sam_gpiopin + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline int sam_gpiopin(gpio_pinset_t pinset) +{ + return 1 << ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_irqbase + * + * Description: + * Return gpio information associated with this IRQ + * + ****************************************************************************/ + +static int sam_irqbase(int irq, uint32_t *base, int *pin) +{ + if (irq >= SAM_IRQ_NIRQS) + { +#ifdef CONFIG_SAM34_GPIOA_IRQ + if (irq <= SAM_IRQ_PA31) + { + *base = SAM_PIOA_BASE; + *pin = irq - SAM_IRQ_PA0; + return OK; + } +#endif +#ifdef CONFIG_SAM34_GPIOB_IRQ + if (irq <= SAM_IRQ_PB31) + { + *base = SAM_PIOB_BASE; + *pin = irq - SAM_IRQ_PB0; + return OK; + } +#endif +#ifdef CONFIG_SAM34_GPIOC_IRQ + if (irq <= SAM_IRQ_PC31) + { + *base = SAM_PIOC_BASE; + *pin = irq - SAM_IRQ_PC0; + return OK; + } +#endif +#ifdef CONFIG_SAM34_GPIOD_IRQ + if (irq <= SAM_IRQ_PD31) + { + *base = SAM_PIOD_BASE; + *pin = irq - SAM_IRQ_PD0; + return OK; + } +#endif +#ifdef CONFIG_SAM34_GPIOE_IRQ + if (irq <= SAM_IRQ_PE31) + { + *base = SAM_PIOE_BASE; + *pin = irq - SAM_IRQ_PE0; + return OK; + } +#endif +#ifdef CONFIG_SAM34_GPIOF_IRQ + if (irq <= SAM_IRQ_PF31) + { + *base = SAM_PIOF_BASE; + *pin = irq - SAM_IRQ_PF0; + return OK; + } +#endif + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: sam_gpioa/b/cinterrupt + * + * Description: + * Receive GPIOA/B/C interrupts + * + ****************************************************************************/ + +static int sam_gpiointerrupt(uint32_t base, int irq0, void *context) +{ + uint32_t pending; + uint32_t bit; + int irq; + + pending = getreg32(base + SAM_PIO_ISR_OFFSET) & getreg32(base + SAM_PIO_IMR_OFFSET); + for (bit = 1, irq = irq0; pending != 0; bit <<= 1, irq++) + { + if ((pending & bit) != 0) + { + /* Re-deliver the IRQ (recurses! We got here from irq_dispatch!) */ + + irq_dispatch(irq, context); + + /* Remove this from the set of pending interrupts */ + + pending &= ~bit; + } + } + return OK; +} + +#ifdef CONFIG_SAM34_GPIOA_IRQ +static int sam_gpioainterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOA_BASE, SAM_IRQ_PA0, context); +} +#endif + +#ifdef CONFIG_SAM34_GPIOB_IRQ +static int sam_gpiobinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOB_BASE, SAM_IRQ_PB0, context); +} +#endif + +#ifdef CONFIG_SAM34_GPIOC_IRQ +static int sam_gpiocinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOC_BASE, SAM_IRQ_PC0, context); +} +#endif + +#ifdef CONFIG_SAM34_GPIOD_IRQ +static int sam_gpiodinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOD_BASE, SAM_IRQ_PD0, context); +} +#endif + +#ifdef CONFIG_SAM34_GPIOE_IRQ +static int sam_gpioeinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOE_BASE, SAM_IRQ_PE0, context); +} +#endif + +#ifdef CONFIG_SAM34_GPIOF_IRQ +static int sam_gpiofinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOF_BASE, SAM_IRQ_PF0, context); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void sam_gpioirqinitialize(void) +{ + /* Configure GPIOA interrupts */ + +#ifdef CONFIG_SAM34_GPIOA_IRQ + /* Enable GPIOA clocking */ + + sam_pioa_enableclk(); + + /* Clear and disable all GPIOA interrupts */ + + (void)getreg32(SAM_PIOA_ISR); + putreg32(0xffffffff, SAM_PIOA_IDR); + + /* Attach and enable the GPIOA IRQ */ + + (void)irq_attach(SAM_IRQ_PIOA, sam_gpioainterrupt); + up_enable_irq(SAM_IRQ_PIOA); +#endif + + /* Configure GPIOB interrupts */ + +#ifdef CONFIG_SAM34_GPIOB_IRQ + /* Enable GPIOB clocking */ + + sam_piob_enableclk(); + + /* Clear and disable all GPIOB interrupts */ + + (void)getreg32(SAM_PIOB_ISR); + putreg32(0xffffffff, SAM_PIOB_IDR); + + /* Attach and enable the GPIOB IRQ */ + + (void)irq_attach(SAM_IRQ_PIOB, sam_gpiobinterrupt); + up_enable_irq(SAM_IRQ_PIOB); +#endif + + /* Configure GPIOC interrupts */ + +#ifdef CONFIG_SAM34_GPIOC_IRQ + /* Enable GPIOC clocking */ + + sam_pioc_enableclk(); + + /* Clear and disable all GPIOC interrupts */ + + (void)getreg32(SAM_PIOC_ISR); + putreg32(0xffffffff, SAM_PIOC_IDR); + + /* Attach and enable the GPIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOC, sam_gpiocinterrupt); + up_enable_irq(SAM_IRQ_PIOC); +#endif + + /* Configure GPIOD interrupts */ + +#ifdef CONFIG_SAM34_GPIOD_IRQ + /* Enable GPIOD clocking */ + + sam_piod_enableclk(); + + /* Clear and disable all GPIOD interrupts */ + + (void)getreg32(SAM_PIOD_ISR); + putreg32(0xffffffff, SAM_PIOD_IDR); + + /* Attach and enable the GPIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOD, sam_gpiodinterrupt); + up_enable_irq(SAM_IRQ_PIOD); +#endif + + /* Configure GPIOE interrupts */ + +#ifdef CONFIG_SAM34_GPIOE_IRQ + /* Enable GPIOE clocking */ + + sam_pioe_enableclk(); + + /* Clear and disable all GPIOE interrupts */ + + (void)getreg32(SAM_PIOE_ISR); + putreg32(0xffffffff, SAM_PIOE_IDR); + + /* Attach and enable the GPIOE IRQ */ + + (void)irq_attach(SAM_IRQ_PIOE, sam_gpioeinterrupt); + up_enable_irq(SAM_IRQ_PIOE); +#endif + + /* Configure GPIOF interrupts */ + +#ifdef CONFIG_SAM34_GPIOF_IRQ + /* Enable GPIOF clocking */ + + sam_piof_enableclk(); + + /* Clear and disable all GPIOF interrupts */ + + (void)getreg32(SAM_PIOF_ISR); + putreg32(0xffffffff, SAM_PIOF_IDR); + + /* Attach and enable the GPIOF IRQ */ + + (void)irq_attach(SAM_IRQ_PIOF, sam_gpiofinterrupt); + up_enable_irq(SAM_IRQ_PIOF); +#endif +} + +/************************************************************************************ + * Name: sam_gpioirq + * + * Description: + * Configure an interrupt for the specified GPIO pin. + * + ************************************************************************************/ + +void sam_gpioirq(gpio_pinset_t pinset) +{ + uint32_t base = sam_gpiobase(pinset); + int pin = sam_gpiopin(pinset); + + /* Are any additional interrupt modes selected? */ + + if ((pinset & _GIO_INT_AIM) != 0) + { + /* Yes.. Enable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMER_OFFSET); + + /* Level or edge detected interrupt? */ + + if ((pinset & _GPIO_INT_LEVEL) != 0) + { + putreg32(pin, base + SAM_PIO_LSR_OFFSET); /* Level */ + } + else + { + putreg32(pin, base + SAM_PIO_ESR_OFFSET); /* Edge */ + } + + /* High level/rising edge or low level /falling edge? */ + + if ((pinset & _GPIO_INT_RH) != 0) + { + putreg32(pin, base + SAM_PIO_REHLSR_OFFSET); /* High level/Rising edge */ + } + else + { + putreg32(pin, base + SAM_PIO_FELLSR_OFFSET); /* Low level/Falling edge */ + } + } + else + { + /* No.. Disable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMDR_OFFSET); + } +} + +/************************************************************************************ + * Name: sam_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +void sam_gpioirqenable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Clear (all) pending interrupts and enable this pin interrupt */ + + //(void)getreg32(base + SAM_PIO_ISR_OFFSET); + putreg32((1 << pin), base + SAM_PIO_IER_OFFSET); + } +} + +/************************************************************************************ + * Name: sam_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +void sam_gpioirqdisable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Disable this pin interrupt */ + + putreg32((1 << pin), base + SAM_PIO_IDR_OFFSET); + } +} + +#endif /* CONFIG_SAM34_GPIO_IRQ */ diff --git a/arch/arm/src/sam34/sam_hsmci.c b/arch/arm/src/sam34/sam_hsmci.c new file mode 100644 index 0000000000000000000000000000000000000000..21e9098cd5aecc3804eab568f5d86e75a9424c4a --- /dev/null +++ b/arch/arm/src/sam34/sam_hsmci.c @@ -0,0 +1,2792 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_hsmci.c + * + * Copyright (C) 2010, 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "sam_gpio.h" +#include "sam_cmcc.h" +#include "sam_hsmci.h" +#include "sam_periphclks.h" + +#ifdef CONFIG_SAM34_DMAC +# include "sam_dmac.h" +#endif + +#include "chip/sam_pmc.h" +#include "chip/sam_hsmci.h" +#include "chip/sam_pinmap.h" + +#ifdef CONFIG_SAM34_DMAC +# include "chip/sam_dmac.h" +#endif +#ifdef CONFIG_SAM34_PDCA +# include "chip/sam_pdc.h" +#endif + +#ifdef CONFIG_SAM34_HSMCI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#if !(defined(CONFIG_SAM34_DMAC0) || defined(CONFIG_SAM34_PDCA)) +# warning "HSMCI driver requires CONFIG_SAM34_DMAC0 or CONFIG_SAM34_PDCA" +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_SDIO_BLOCKSETUP +# error "This driver requires CONFIG_SDIO_BLOCKSETUP" +#endif + +/* Nested interrupts not supported */ + +#define SAM34_HSMCI_PRIO NVIC_SYSH_PRIORITY_DEFAULT + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE) +# undef CONFIG_SAM34_HSMCI_CMDDEBUG +# undef CONFIG_SAM34_HSMCI_XFRDEBUG +#endif + +#ifdef CONFIG_SAM34_HSMCI_RDPROOF +# ifdef CONFIG_SAM34_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS (HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF) +# else +# define HSMCU_PROOF_BITS HSMCI_MR_RDPROOF +# endif +#else +# ifdef CONFIG_SAM34_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS HSMCI_MR_WRPROOF +# else +# define HSMCU_PROOF_BITS (0) +# endif +#endif + +/* Timing */ + +#define HSMCI_CMDTIMEOUT (100000) +#define HSMCI_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define HSMCI_DTIMER_DATATIMEOUT (0x000fffff) + +#ifdef CONFIG_SAM34_DMAC0 +/* DMA configuration flags */ + +#define DMA_FLAGS \ + (DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \ + (DMACHAN_INTF_HSMCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \ + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \ + DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_4) +#endif + +/* Status errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_STATUS_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | \ + HSMCI_INT_RCRCE | HSMCI_INT_RDIRE | HSMCI_INT_RINDE) + +/* Response errors: + * + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_RESPONSE_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RCRCE | \ + HSMCI_INT_RDIRE | HSMCI_INT_RINDE) + +#define HSMCI_RESPONSE_NOCRC_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RDIRE | \ + HSMCI_INT_RINDE) + +#define HSMCI_RESPONSE_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE) + +/* Data transfer errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + */ + +#ifdef CONFIG_SAM34_DMAC0 +# if defined(CONFIG_ARCH_CHIP_SAM3U) +# define HSMCI_DATA_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE) +# else +# define HSMCI_DATA_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \ + HSMCI_INT_DCRCE) +# endif +#else + #define HSMCI_DATA_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \ + HSMCI_INT_DCRCE) +#endif + +#define HSMCI_DATA_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_DTOE) + +#ifdef CONFIG_SAM34_DMAC0 +# if defined(CONFIG_ARCH_CHIP_SAM3U) +# define HSMCI_DATA_DMARECV_ERRORS \ + (HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \ + HSMCI_INT_DCRCE) +# else +# define HSMCI_DATA_DMARECV_ERRORS \ + (HSMCI_INT_OVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | HSMCI_INT_DCRCE) +# endif +#endif + +#ifdef CONFIG_SAM34_PDCA +# define HSMCI_DATA_DMARECV_ERRORS \ + (HSMCI_INT_OVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | HSMCI_INT_DCRCE) +#endif + +#define HSMCI_DATA_DMASEND_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | HSMCI_INT_DCRCE) + +/* Data transfer status and interrupt mask bits. + * + * The XFRDONE flag in the HSMCI_SR indicates exactly when the read or + * write sequence is finished. + * + * 0: A transfer is in progress. + * 1: Command register is ready to operate and the data bus is in the idle state. + * + * DMADONE: DMA Transfer done + * + * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 1: DMA buffer transfer has completed. + */ + +#ifdef CONFIG_SAM34_DMAC0 +# define HSMCI_DMARECV_INTS \ + (HSMCI_DATA_DMARECV_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) +# define HSMCI_DMASEND_INTS \ + (HSMCI_DATA_DMASEND_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) +#endif + +#ifdef CONFIG_SAM34_PDCA + #define HSMCI_DMARECV_INTS \ + (HSMCI_DATA_DMARECV_ERRORS | HSMCI_INT_ENDRX) + #define HSMCI_DMASEND_INTS \ + (HSMCI_DATA_DMASEND_ERRORS | HSMCI_INT_ENDTX) +#endif + +/* Event waiting interrupt mask bits. + * + * CMDRDY (Command Ready): + * + * 0: A command is in progress + * 1: The last command has been sent. The CMDRDY flag is released 8 bits + * after the end of the card response. Cleared when writing in the HSMCI_CMDR + */ + +#define HSMCI_CMDRESP_INTS \ + (HSMCI_RESPONSE_ERRORS | HSMCI_INT_CMDRDY) +#define HSMCI_CMDRESP_NOCRC_INTS \ + (HSMCI_RESPONSE_NOCRC_ERRORS | HSMCI_INT_CMDRDY) + +/* Register logging support */ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +# ifdef CONFIG_DEBUG_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define DEBUG_NDMASAMPLES 5 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define DEBUG_NDMASAMPLES 3 +# endif +#endif + +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +# define SAMPLENDX_AFTER_CMDR 0 +# define SAMPLENDX_AT_WAKEUP 1 +# define DEBUG_NCMDSAMPLES 2 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure defines the state of the SAM3/4 HSMCI interface */ + +struct sam_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* SAM3/4-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ +#ifdef CONFIG_SAM34_DMAC0 + bool dmabusy; /* TRUE: DMA is in progress */ +#endif + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ +#ifdef CONFIG_SAM34_DMAC0 + DMA_HANDLE dma; /* Handle for DMA channel */ +#endif +}; + +/* Register logging support */ + +#if defined(CONFIG_SAM34_HSMCI_XFRDEBUG) || defined(CONFIG_SAM34_HSMCI_CMDDEBUG) +struct sam_hsmciregs_s +{ + uint32_t mr; /* Mode Register */ + uint32_t dtor; /* Data Timeout Register */ + uint32_t sdcr; /* SD/SDIO Card Register */ + uint32_t argr; /* Argument Register */ + uint32_t blkr; /* Block Register */ + uint32_t cstor; /* Completion Signal Timeout Register */ + uint32_t rsp0; /* Response Register 0 */ + uint32_t rsp1; /* Response Register 1 */ + uint32_t rsp2; /* Response Register 2 */ + uint32_t rsp3; /* Response Register 3 */ + uint32_t sr; /* Status Register */ + uint32_t imr; /* Interrupt Mask Register */ +#if defined(CONFIG_ARCH_CHIP_SAM3U) + uint32_t dma; /* DMA Configuration Register */ +#endif + uint32_t cfg; /* Configuration Register */ + uint32_t wpmr; /* Write Protection Mode Register */ + uint32_t wpsr; /* Write Protection Status Register */ + +#ifdef CONFIG_SAM34_PDCA + uint32_t pdc_rpr; /* Receive Pointer Register */ + uint32_t pdc_rcr; /* Receive Counter Register */ + uint32_t pdc_tpr; /* Transmit Pointer Register */ + uint32_t pdc_tcr; /* Transmit Counter Register */ + uint32_t pdc_rnpr; /* Receive Next Pointer Register */ + uint32_t pdc_rncr; /* Receive Next Counter Register */ + uint32_t pdc_tnpr; /* Transmit Next Pointer Register */ + uint32_t pdc_tncr; /* Transmit Next Counter Register */ +//uint32_t pdc_ptcr; /* Transfer Control Register */ + uint32_t pdc_ptsr; /* Transfer Status Register */ +#endif +}; +#endif + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +struct sam_xfrregs_s +{ + struct sam_hsmciregs_s hsmci; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SAM34_DMAC0) + struct sam_dmaregs_s dma; +#endif +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_dev_s *priv); +#define sam_givesem(priv) (sem_post(&priv->waitsem)) + +static void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents); +static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevents); +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static void sam_disablexfrints(struct sam_dev_s *priv); +static void sam_enableints(struct sam_dev_s *priv); + +static inline void sam_disable(void); +static inline void sam_enable(void); + +/* Register Sampling ********************************************************/ + +#if defined(CONFIG_SAM34_HSMCI_XFRDEBUG) || defined(CONFIG_SAM34_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_hsmciregs_s *regs); +static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg); +#endif + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(void); +static void sam_xfrsample(struct sam_dev_s *priv, int index); +static void sam_xfrdumpone(struct sam_dev_s *priv, + struct sam_xfrregs_s *regs, const char *msg); +static void sam_xfrdump(struct sam_dev_s *priv); +#else +# define sam_xfrsampleinit() +# define sam_xfrsample(priv,index) +# define sam_xfrdump(priv) +#endif + +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(void); +static inline void sam_cmdsample1(int index3); +static inline void sam_cmdsample2(int index, uint32_t sr); +static void sam_cmddump(void); +#else +# define sam_cmdsampleinit() +# define sam_cmdsample1(index) +# define sam_cmdsample2(index,sr) +# define sam_cmddump() +#endif + +#ifdef CONFIG_SAM34_DMAC0 +/* DMA Helpers **************************************************************/ + +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result); +#endif + +/* Data Transfer Helpers ****************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg); +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_notransfer(struct sam_dev_s *priv); + +/* Interrupt Handling *******************************************************/ + +static int sam_interrupt(int irq, void *context); + +/* SDIO interface methods ***************************************************/ + +/* Initialization/setup */ + +static void sam_reset(FAR struct sdio_dev_s *dev); +static uint8_t sam_status(FAR struct sdio_dev_s *dev); +static void sam_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void sam_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int sam_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks); +static int sam_cancel(FAR struct sdio_dev_s *dev); +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev); +#endif +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); + +/* Initialization/uninitialization/reset ************************************/ + +static void sam_callback(void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct sam_dev_s g_sdiodev = +{ + .dev = + { + .reset = sam_reset, + .status = sam_status, + .widebus = sam_widebus, + .clock = sam_clock, + .attach = sam_attach, + .sendcmd = sam_sendcmd, + .blocksetup = sam_blocksetup, + .recvsetup = sam_dmarecvsetup, + .sendsetup = sam_dmasendsetup, + .cancel = sam_cancel, + .waitresponse = sam_waitresponse, + .recvR1 = sam_recvshort, + .recvR2 = sam_recvlong, + .recvR3 = sam_recvshort, + .recvR4 = sam_recvnotimpl, + .recvR5 = sam_recvnotimpl, + .recvR6 = sam_recvshort, + .recvR7 = sam_recvshort, + .waitenable = sam_waitenable, + .eventwait = sam_eventwait, + .callbackenable = sam_callbackenable, + .registercallback = sam_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = sam_dmasupported, + .dmarecvsetup = sam_dmarecvsetup, + .dmasendsetup = sam_dmasendsetup, +#endif + }, +}; + +/* Register logging support */ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static struct sam_xfrregs_s g_xfrsamples[DEBUG_NDMASAMPLES]; +#endif +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +static struct sam_hsmciregs_s g_cmdsamples[DEBUG_NCMDSAMPLES]; +#endif +#if defined(CONFIG_SAM34_HSMCI_XFRDEBUG) && defined(CONFIG_SAM34_HSMCI_CMDDEBUG) +static bool g_xfrinitialized; +static bool g_cmdinitialized; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_configwaitints + * + * Description: + * Configure HSMCI interrupts needed to support the wait function. Wait + * interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * waitmask - The set of bits in the HSMCI MASK register to set + * waitevents - Waited for events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents) +{ + irqstate_t flags; + + /* Save all of the data in one, atomic operation. */ + + flags = enter_critical_section(); + priv->waitevents = waitevents; + priv->wkupevent = 0; + priv->waitmask = waitmask; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_disablewaitints + * + * Description: + * Disable HSMCI interrupts and save wakeup event. Called + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * wkupevent - Wake-up event(s) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + + flags = enter_critical_section(); + priv->waitevents = 0; + priv->wkupevent = wkupevent; + priv->waitmask = 0; + putreg32(~priv->xfrmask, SAM_HSMCI_IDR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_configxfrints + * + * Description: + * Configure HSMCI interrupts needed to support the data transfer. Data + * transfer interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +{ + priv->xfrmask = xfrmask; +} + +/**************************************************************************** + * Name: sam_disablexfrints + * + * Description: + * Disable HSMCI interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablexfrints(struct sam_dev_s *priv) +{ + irqstate_t flags = enter_critical_section(); + priv->xfrmask = 0; + putreg32(~priv->waitmask, SAM_HSMCI_IDR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_enableints + * + * Description: + * Enable the previously configured HSMCI interrupts needed to suport the + * wait and transfer functions. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_enableints(struct sam_dev_s *priv) +{ + /* Enable all interrupts associated with the waited-for event */ + + putreg32(priv->xfrmask | priv->waitmask, SAM_HSMCI_IER); +} + +/**************************************************************************** + * Name: sam_disable + * + * Description: + * Disable the HSMCI + * + ****************************************************************************/ + +static inline void sam_disable(void) +{ + /* Disable the MCI peripheral clock */ + + sam_hsmci_disableclk(); + + /* Disable the MCI */ + + putreg32(HSMCI_CR_MCIDIS, SAM_HSMCI_CR); + + /* Disable all the interrupts */ + + putreg32(0xffffffff, SAM_HSMCI_IDR); +} + +/**************************************************************************** + * Name: sam_enable + * + * Description: + * Enable the HSMCI + * + ****************************************************************************/ + +static inline void sam_enable(void) +{ + /* Enable the MCI peripheral clock */ + + sam_hsmci_enableclk(); + + /* Enable the MCI and the Power Saving */ + + putreg32(HSMCI_CR_MCIEN, SAM_HSMCI_CR); +} + +/**************************************************************************** + * Register Sampling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmcisample + * + * Description: + * Sample HSMCI registers + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_HSMCI_XFRDEBUG) || defined(CONFIG_SAM34_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_hsmciregs_s *regs) +{ + regs->mr = getreg32(SAM_HSMCI_MR); + regs->dtor = getreg32(SAM_HSMCI_DTOR); + regs->sdcr = getreg32(SAM_HSMCI_SDCR); + regs->argr = getreg32(SAM_HSMCI_ARGR); + regs->blkr = getreg32(SAM_HSMCI_BLKR); + regs->cstor = getreg32(SAM_HSMCI_CSTOR); + regs->rsp0 = getreg32(SAM_HSMCI_RSPR0); + regs->rsp1 = getreg32(SAM_HSMCI_RSPR1); + regs->rsp2 = getreg32(SAM_HSMCI_RSPR2); + regs->rsp3 = getreg32(SAM_HSMCI_RSPR3); + regs->sr = getreg32(SAM_HSMCI_SR); + regs->imr = getreg32(SAM_HSMCI_IMR); +#if defined(CONFIG_ARCH_CHIP_SAM3U) + regs->dma = getreg32(SAM_HSMCI_DMA); +#endif + regs->cfg = getreg32(SAM_HSMCI_CFG); + regs->wpmr = getreg32(SAM_HSMCI_WPMR); + regs->wpsr = getreg32(SAM_HSMCI_WPSR); + +#ifdef CONFIG_SAM34_PDCA + regs->pdc_rpr = getreg32(SAM_HSMCI_PDC_RPR); + regs->pdc_rcr = getreg32(SAM_HSMCI_PDC_RCR); + regs->pdc_tpr = getreg32(SAM_HSMCI_PDC_TPR); + regs->pdc_tcr = getreg32(SAM_HSMCI_PDC_TCR); + regs->pdc_rnpr = getreg32(SAM_HSMCI_PDC_RNPR); + regs->pdc_rncr = getreg32(SAM_HSMCI_PDC_RNCR); + regs->pdc_tnpr = getreg32(SAM_HSMCI_PDC_TNPR); + regs->pdc_tncr = getreg32(SAM_HSMCI_PDC_TNCR); +//regs->pdc_ptcr = getreg32(SAM_HSMCI_PDC_PTCR); + regs->pdc_ptsr = getreg32(SAM_HSMCI_PDC_PTSR); +#endif +} +#endif + +/**************************************************************************** + * Name: sam_hsmcidump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_HSMCI_XFRDEBUG) || defined(CONFIG_SAM34_HSMCI_CMDDEBUG) +static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg) +{ + fdbg("HSMCI Registers: %s\n", msg); + fdbg(" MR[%08x]: %08x\n", SAM_HSMCI_MR, regs->mr); + fdbg(" DTOR[%08x]: %08x\n", SAM_HSMCI_DTOR, regs->dtor); + fdbg(" SDCR[%08x]: %08x\n", SAM_HSMCI_SDCR, regs->sdcr); + fdbg(" ARGR[%08x]: %08x\n", SAM_HSMCI_ARGR, regs->argr); + fdbg(" BLKR[%08x]: %08x\n", SAM_HSMCI_BLKR, regs->blkr); + fdbg(" CSTOR[%08x]: %08x\n", SAM_HSMCI_CSTOR, regs->cstor); + fdbg(" RSPR0[%08x]: %08x\n", SAM_HSMCI_RSPR0, regs->rsp0); + fdbg(" RSPR1[%08x]: %08x\n", SAM_HSMCI_RSPR1, regs->rsp1); + fdbg(" RSPR2[%08x]: %08x\n", SAM_HSMCI_RSPR2, regs->rsp2); + fdbg(" RSPR3[%08x]: %08x\n", SAM_HSMCI_RSPR3, regs->rsp3); + fdbg(" SR[%08x]: %08x\n", SAM_HSMCI_SR, regs->sr); + fdbg(" IMR[%08x]: %08x\n", SAM_HSMCI_IMR, regs->imr); +#if defined(CONFIG_ARCH_CHIP_SAM3U) + fdbg(" DMA[%08x]: %08x\n", SAM_HSMCI_DMA, regs->dma); +#endif + fdbg(" CFG[%08x]: %08x\n", SAM_HSMCI_CFG, regs->cfg); + fdbg(" WPMR[%08x]: %08x\n", SAM_HSMCI_WPMR, regs->wpmr); + fdbg(" WPSR[%08x]: %08x\n", SAM_HSMCI_WPSR, regs->wpsr); + +#ifdef CONFIG_SAM34_PDCA + fdbg("HSMCI PDC Registers:\n"); + fdbg(" RPR[%08x]: %08x\n", SAM_HSMCI_PDC_RPR, regs->pdc_rpr); + fdbg(" RCR[%08x]: %08x\n", SAM_HSMCI_PDC_RCR, regs->pdc_rcr); + fdbg(" TPR[%08x]: %08x\n", SAM_HSMCI_PDC_TPR, regs->pdc_tpr); + fdbg(" TCR[%08x]: %08x\n", SAM_HSMCI_PDC_TCR, regs->pdc_tcr); + fdbg(" RNPR[%08x]: %08x\n", SAM_HSMCI_PDC_RNPR, regs->pdc_rnpr); + fdbg(" RNCR[%08x]: %08x\n", SAM_HSMCI_PDC_RNCR, regs->pdc_rncr); + fdbg(" TNPR[%08x]: %08x\n", SAM_HSMCI_PDC_TNPR, regs->pdc_tnpr); + fdbg(" TNCR[%08x]: %08x\n", SAM_HSMCI_PDC_TNCR, regs->pdc_tncr); +//fdbg(" TCR[%08x]: %08x\n", SAM_HSMCI_PDC_PTCR, regs->pdc_ptcr); + fdbg(" PTSR[%08x]: %08x\n", SAM_HSMCI_PDC_PTSR, regs->pdc_ptsr); +#endif +} +#endif + +/**************************************************************************** + * Name: sam_xfrsample + * + * Description: + * Sample HSMCI/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static void sam_xfrsample(struct sam_dev_s *priv, int index) +{ + struct sam_xfrregs_s *regs = &g_xfrsamples[index]; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SAM34_DMAC0) + sam_dmasample(priv->dma, ®s->dma); +#endif + sam_hsmcisample(®s->hsmci); +} +#endif + +/**************************************************************************** + * Name: sam_xfrsampleinit + * + * Description: + * Setup prior to collecting transfer samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(void) +{ + memset(g_xfrsamples, 0xff, DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s)); +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG + g_xfrinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_xfrdumpone + * + * Description: + * Dump one transfer register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static void sam_xfrdumpone(struct sam_dev_s *priv, + struct sam_xfrregs_s *regs, const char *msg) +{ +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SAM34_DMAC0) + sam_dmadump(priv->dma, ®s->dma, msg); +#endif + sam_hsmcidump(®s->hsmci, msg); +} +#endif + +/**************************************************************************** + * Name: sam_xfrdump + * + * Description: + * Dump all transfer-related, sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG +static void sam_xfrdump(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG + if (g_xfrinitialized) +#endif + { + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_SETUP], "Before setup"); +#ifdef CONFIG_DEBUG_DMA + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); +#endif + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_AFTER_SETUP], "After setup"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_END_TRANSFER], "End of transfer"); +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SAM34_DMAC0) + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); +#endif +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG + g_xfrinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * Name: sam_cmdsampleinit + * + * Description: + * Setup prior to collecting command/response samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(void) +{ + memset(g_cmdsamples, 0xff, DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s)); +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG + g_cmdinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_cmdsample1 & 2 + * + * Description: + * Sample command/response registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +static inline void sam_cmdsample1(int index) +{ + sam_hsmcisample(&g_cmdsamples[index]); +} + +static inline void sam_cmdsample2(int index, uint32_t sr) +{ + sam_hsmcisample(&g_cmdsamples[index]); + g_cmdsamples[index].sr = sr; +} +#endif + +/**************************************************************************** + * Name: sam_cmddump + * + * Description: + * Dump all comand/response register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_HSMCI_CMDDEBUG +static void sam_cmddump(void) +{ +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG + if (g_cmdinitialized) +#endif + { + sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AFTER_CMDR], "After command setup"); + sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AT_WAKEUP], "After wakeup"); +#ifdef CONFIG_SAM34_HSMCI_XFRDEBUG + g_cmdinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dmacallback + * + * Description: + * Called when HSMCI DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_DMAC0 +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + + /* We don't really do anything at the completion of DMA. The termination + * of the transfer is driven by the HSMCI interrupts. + * + * Mark the DMA not busy. + */ + + priv->dmabusy = false; + + sam_xfrsample((struct sam_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); +} +#endif + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + + DEBUGASSERT(argc == 1 && priv != NULL); + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0); + + /* Is a data transfer complete event expected? */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + sam_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("Timeout\n"); + } +} + +/**************************************************************************** + * Name: sam_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts and save wakeup event */ + + sam_disablewaitints(priv, wkupevent); + + /* Wake up the waiting thread */ + + sam_givesem(priv); +} + +/**************************************************************************** + * Name: sam_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the HSMCI interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + sam_disablexfrints(priv); + + /* No data transfer */ + + sam_notransfer(priv); + + /* DMA debug instrumentation */ + + sam_xfrsample(priv, SAMPLENDX_END_TRANSFER); + +#ifdef CONFIG_SAM34_DMAC0 + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + */ + + sam_dmastop(priv->dma); + priv->dmabusy = false; + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + /* Disable the DMA handshaking */ + + putreg32(0, SAM_HSMCI_DMA); +#endif +#endif + +#ifdef CONFIG_SAM34_PDCA + putreg32(PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS, SAM_HSMCI_PDC_PTCR); +#endif + + /* Is a thread wait for these data transfer complete events? */ + + if ((priv->waitevents & wkupevent) != 0) + { + /* Yes.. wake up any waiting threads */ + + sam_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Name: sam_notransfer + * + * Description: + * Setup for no transfer. This is the default setup that is overriddden + * by sam_dmarecvsetup or sam_dmasendsetup + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_notransfer(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAM34_DMAC0 + uint32_t regval; + + regval = getreg32(SAM_HSMCI_MR); + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_BLKLEN_MASK); +#else + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); +#endif + + putreg32(regval, SAM_HSMCI_MR); +#endif + +#ifdef CONFIG_SAM34_PDCA + modifyreg32(SAM_HSMCI_MR, HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | + HSMCI_MR_PDCMODE, 0); +#endif +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * HSMCI interrupt handler + * + * Input Parameters: + * irq - IRQ number of the interrupts + * context - Saved machine context at the time of the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_interrupt(int irq, void *context) +{ + struct sam_dev_s *priv = &g_sdiodev; + uint32_t sr; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. */ + + for (; ; ) + { + /* Check the HSMCI status register. Mask out all bits that don't + * correspond to enabled interrupts. (This depends on the fact that + * bits are ordered the same in both the SR and IMR registers). If + * there are non-zero bits remaining, then we have work to do here. + */ + + sr = getreg32(SAM_HSMCI_SR); + enabled = sr & getreg32(SAM_HSMCI_IMR); + + if (enabled == 0) + { + break; + } + + /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal the end a data transfer? */ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { + /* Yes.. the transfer is complete. Did it complete with an error? */ + + if ((pending & HSMCI_DATA_ERRORS) != 0) + { + /* Yes.. Was it some kind of timeout error? */ + + flldbg("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) + { + /* Yes.. Terminate with a timeout. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + else + { + /* No.. Terminate with an I/O error. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + else + { + /* No.. Then the transfer must have completed successfully */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + sdio_eventset_t wkupevent = 0; + + /* Is this a Command-Response sequence completion event? */ + + if ((pending & priv->cmdrmask) != 0) + { + sam_cmdsample2(SAMPLENDX_AT_WAKEUP, sr); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fllvdbg("ERROR: events: %08x SR: %08x\n", + priv->cmdrmask, enabled); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. signal a timeout error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + } + else + { + /* No.. signal some generic I/O error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + } + + /* Yes.. Is there a thread waiting for this event set? */ + + wkupevent &= priv->waitevents; + if (wkupevent != 0) + { + /* Yes.. wake the thread up */ + + sam_endwait(priv, wkupevent); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ +/**************************************************************************** + * Name: sam_reset + * + * Description: + * Reset the HSMCI controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)dev; + irqstate_t flags; + + /* Enable the MCI clock */ + + flags = enter_critical_section(); + sam_hsmci_enableclk(); + + /* Reset the MCI */ + + putreg32(HSMCI_CR_SWRST, SAM_HSMCI_CR); + + /* Disable the MCI */ + + putreg32(HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS, SAM_HSMCI_CR); + + /* Disable all the interrupts */ + + putreg32(0xffffffff, SAM_HSMCI_IDR); + + /* Set the Data Timeout Register */ + + putreg32(HSMCI_DTOR_DTOCYC_MAX | HSMCI_DTOR_DTOMUL_MAX, SAM_HSMCI_DTOR); + + /* Set the Mode Register for ID mode frequency (probably 400KHz) */ + + sam_clock(dev, CLOCK_IDMODE); + + /* Set the SDCard Register */ + + putreg32(HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_1BIT, SAM_HSMCI_SDCR); + + /* Enable the MCI controller */ + + putreg32(HSMCI_CR_MCIEN, SAM_HSMCI_CR); + + /* Disable the DMA interface */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + putreg32(0, SAM_HSMCI_DMA); +#endif + +#ifdef CONFIG_SAM34_PDCA + putreg32(PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS, SAM_HSMCI_PDC_PTCR); +#endif + + /* Configure MCI */ + + putreg32(HSMCI_CFG_FIFOMODE, SAM_HSMCI_CFG); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ +#ifdef CONFIG_SAM34_DMAC0 + priv->dmabusy = false; /* No DMA in progress */ +#endif + + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see sam_status_* defines) + * + ****************************************************************************/ + +static uint8_t sam_status(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: sam_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + + /* Set 1-bit or 4-bit bus by configuring the SDCBUS field of the SDCR register */ + + regval = getreg32(SAM_HSMCI_SDCR); + regval &= ~HSMCI_SDCR_SDCBUS_MASK; + regval |= wide ? HSMCI_SDCR_SDCBUS_4BIT : HSMCI_SDCR_SDCBUS_1BIT; + putreg32(regval, SAM_HSMCI_SDCR); + + /* Remember the setting */ + + priv->widebus = wide; +} + +/**************************************************************************** + * Name: sam_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t regval; + bool enable = true; + + /* Fetch the current mode register and mask out the clkdiv (and pwsdiv) */ + + regval = getreg32(SAM_HSMCI_MR); + + /* Does this HSMCI support the CLOCKODD bit? */ + +#ifdef HSMCI_MR_CLKODD + regval &= ~(HSMCI_MR_CLKDIV_MASK | HSMCI_MR_PWSDIV_MASK | HSMCI_MR_CLKODD); +#else + regval &= ~(HSMCI_MR_CLKDIV_MASK | HSMCI_MR_PWSDIV_MASK); +#endif + + /* These clock devisor values that must be defined in the board-specific + * board.h header file: HSMCI_INIT_CLKDIV, HSMCI_MMCXFR_CLKDIV, + * HSMCI_SDXFR_CLKDIV, and HSMCI_SDWIDEXFR_CLKDIV. + */ + + switch (rate) + { + default: + case CLOCK_SDIO_DISABLED: /* Clock is disabled */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + enable = false; + return; + + case CLOCK_IDMODE: /* Initial ID mode clocking (<400KHz) */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_MMC_TRANSFER: /* MMC normal operation clocking */ + regval |= HSMCI_MMCXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_1BIT: /* SD normal operation clocking (narrow 1-bit mode) */ + regval |= HSMCI_SDXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_4BIT: /* SD normal operation clocking (wide 4-bit mode) */ + regval |= HSMCI_SDWIDEXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + }; + + /* Set the new clock diver and make sure that the clock is enabled or + * disabled, whichever the case. + */ + + putreg32(regval, SAM_HSMCI_MR); + if (enable) + { + sam_enable(); + } + else + { + sam_disable(); + } +} + +/**************************************************************************** + * Name: sam_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int sam_attach(FAR struct sdio_dev_s *dev) +{ + int ret; + + /* Attach the HSMCI interrupt handler */ + + ret = irq_attach(SAM_IRQ_HSMCI, sam_interrupt); + if (ret == OK) + { + + /* Disable all interrupts at the HSMCI controller and clear (most) static + * interrupt flags by reading the status register. + */ + + putreg32(0xffffffff, SAM_HSMCI_IDR); + (void)getreg32(SAM_HSMCI_SR); + + /* Enable HSMCI interrupts at the NVIC. They can now be enabled at + * the HSMCI controller as needed. + */ + + up_enable_irq(SAM_IRQ_HSMCI); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(SAM_IRQ_HSMCI, SAM34_HSMCI_PRIO); +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: sam_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + uint32_t cmdidx; + + sam_cmdsampleinit(); + + /* Set the HSMCI Argument value */ + + putreg32(arg, SAM_HSMCI_ARGR); + + /* Construct the command valid, starting with the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval = cmdidx << HSMCI_CMDR_CMDNB_SHIFT; + + /* 'OR' in response related bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + /* No response */ + + case MMCSD_NO_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= HSMCI_CMDR_RSPTYP_NONE; + + break; + + /* 48-bit response with CRC */ + + case MMCSD_R1_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + case MMCSD_R1B_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + break; + + /* 48-bit response without CRC */ + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + /* 136-bit response with CRC */ + + case MMCSD_R2_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + break; + } + + /* 'OR' in data transfer related bits */ + + switch (cmd & MMCSD_DATAXFR_MASK) + { +#if 0 /* No MMC support */ + case MMCSD_RDSTREAM: /* MMC Read stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + break; + + case MMCSD_WRSTREAM: /* MMC Write stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + break; +#endif + + case MMCSD_RDDATAXFR: /* Read block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_WRDATAXFR: /* Write block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_NODATAXFR: + default: + if ((cmd & MMCSD_STOPXFR) != 0) + { + regval |= HSMCI_CMDR_TRCMD_STOP; + } + break; + } + + /* 'OR' in Open Drain option */ + +#if 0 /* No MMC support */ + if ((cmd & MMCSD_OPENDRAIN) != 0) + { + regval |= HSMCI_CMDR_OPDCMD; + } +#endif + + /* Write the fully decorated command to CMDR */ + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + putreg32(regval, SAM_HSMCI_CMDR); + sam_cmdsample1(SAMPLENDX_AFTER_CMDR); + return OK; +} + +/**************************************************************************** + * Name: sam_blocksetup + * + * Description: + * Some hardward needs to be informed of the selected blocksize. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * blocklen - The selected block size. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks) +{ + uint32_t regval; + + DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535 && blocklen < 65535); + + /* When TRTYP - Single or Multi, blocklen must be 1-511, 0-512 */ + + DEBUGASSERT(blocklen <= 512); + + /* Set the block size. Clear bits followed by set */ + + regval = getreg32(SAM_HSMCI_MR); + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_BLKLEN_MASK); + regval |= HSMCU_PROOF_BITS; + regval |= (blocklen << HSMCI_MR_BLKLEN_SHIFT); +#else + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); + regval |= HSMCU_PROOF_BITS; +#endif + + putreg32(regval, SAM_HSMCI_MR); + + /* Set the block count register */ + + regval = HSMCI_BLKR_BLKLEN(blocklen) | HSMCI_BLKR_BCNT(nblocks); + putreg32(regval, SAM_HSMCI_BLKR); +} + +/**************************************************************************** + * Name: sam_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_cancel(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + sam_disablexfrints(priv); + sam_disablewaitints(priv, 0); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Clearing (most) pending interrupt status by reading the status register */ + + (void)getreg32(SAM_HSMCI_SR); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + */ + +#ifdef CONFIG_SAM34_DMAC0 + sam_dmastop(priv->dma); + priv->dmabusy = false; +#endif + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + /* Disable the DMA handshaking */ + + putreg32(0, SAM_HSMCI_DMA); +#endif + +#ifdef CONFIG_SAM34_PDCA + putreg32(PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS, SAM_HSMCI_PDC_PTCR); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t sr; + uint32_t pending; + int32_t timeout; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + timeout = HSMCI_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_NO_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + timeout = HSMCI_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + for (; ; ) + { + /* Did a Command-Response sequence termination evernt occur? */ + + sr = getreg32(SAM_HSMCI_SR); + pending = sr & priv->cmdrmask; + + if (pending != 0) + { + sam_cmdsample2(SAMPLENDX_AT_WAKEUP, sr); + sam_cmddump(); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fdbg("ERROR: cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. return a timeout error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + else + { + /* No.. return some generic I/O error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + return -EIO; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + return OK; + } + } + else if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + priv->wkupevent = SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + } +} + +/**************************************************************************** + * Name: sam_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a failure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intact and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int sam_recvshort(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rshort) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* These responses could have CRC errors: + * + * R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * But there is no parity on the R3 response and parity errors should + * be ignored. + * + * R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + ret = -EIO; + } + + /* Return the R1/R6 response */ + + else if (rshort) + { + *rshort = getreg32(SAM_HSMCI_RSPR0); + } + + priv->wkupevent = 0; + return ret; +} + +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + ret = -EIO; + } + + /* Return the long response */ + + else if (rlong) + { + rlong[0] = getreg32(SAM_HSMCI_RSPR0); + rlong[1] = getreg32(SAM_HSMCI_RSPR1); + rlong[2] = getreg32(SAM_HSMCI_RSPR2); + rlong[3] = getreg32(SAM_HSMCI_RSPR3); + } + + priv->wkupevent = 0; + return ret; +} + +/* MMC responses not supported */ + +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rnotimpl) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + priv->wkupevent = 0; + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling either calling SDIO_DMARECVSETUP, + * SDIO_DMASENDSETUP, or or SDIO_WAITEVENT. This is the recommended + * ordering: + * + * SDIO_WAITENABLE: Discard any pending interrupts, enable event(s) + * of interest + * SDIO_DMARECVSETUP/ + * SDIO_DMASENDSETUP: Setup the logic that will trigger the event the + * event(s) of interest + * SDIO_WAITEVENT: Wait for the event of interest (which might + * already have occurred) + * + * This sequency should eliminate race conditions between the command/trasnfer + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + sam_disablewaitints(priv, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + + waitmask = 0; + if ((eventset & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0) + { + waitmask |= priv->cmdrmask; + } + + /* Clear (most) pending interrupts by reading the status register. + * No interrupts should be lost (assuming that interrupts were enabled + * before sam_waitenable() was called). Any interrupts that become + * pending after this point must be valid event indications. + */ + + (void)getreg32(SAM_HSMCI_SR); + + /* Wait interrupts are configured here, but not enabled until + * sam_eventwait() is called. Why? Because the XFRDONE interrupt is + * always pending until start the data transfer. + */ + + sam_configwaitints(priv, waitmask, eventset); +} + +/**************************************************************************** + * Name: sam_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when sam_eventwait + * returns. SDIO_WAITEVENTS must be called again before sam_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + int ret; + + /* Since interrupts not been enabled to this point, any relevant events + * are pending and should not yet have occurred. + */ + + DEBUGASSERT(priv->waitevents != 0 && priv->wkupevent == 0); + + /* Now enable event-related interrupts. If the events are pending, they + * may happen immediately here before entering the loop. + */ + + sam_enableints(priv); + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevents will + * be non-zero (and, hopefully, the semaphore count will also be non-zero). + */ + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + return SDIOWAIT_TIMEOUT; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)sam_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling sam_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + sam_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + * When wkupevent becomes non-zero, further interrupts will have already + * been disabled. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + sam_cmddump(); + sam_xfrdump(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: sam_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in sam_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methods. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + sam_callback(priv); +} + +/**************************************************************************** + * Name: sam_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE. + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: sam_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: sam_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Setup register sampling */ + + sam_xfrsampleinit(); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + +#ifdef CONFIG_SAM34_DMAC0 + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->dma, SAM_HSMCI_RDR, (uint32_t)buffer, buflen); + + /* Invalidate the buffer memory to force re-fetching from RAM when the DMA + * completes + */ + + sam_cmcc_invalidate((uintptr_t)buffer, (uintptr_t)buffer + buflen); + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + /* Enable DMA handshaking */ + + putreg32(HSMCI_DMA_DMAEN, SAM_HSMCI_DMA); +#endif + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + sam_dmastart(priv->dma, sam_dmacallback, priv); +#endif + +#ifdef CONFIG_SAM34_PDCA + modifyreg32(SAM_HSMCI_MR, 0, HSMCI_MR_PDCMODE); + fdbg("SAM_HSMCI_MR = 0x%08X\n", getreg32(SAM_HSMCI_MR)); + putreg32((uint32_t)buffer, SAM_HSMCI_PDC_RPR); + putreg32(buflen/4, SAM_HSMCI_PDC_RCR); + putreg32(PDC_PTCR_RXTEN, SAM_HSMCI_PDC_PTCR); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); +#endif + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is stard with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMARECV_INTS); + return OK; +} + +/**************************************************************************** + * Name: sam_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Setup register sampling */ + + sam_xfrsampleinit(); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + +#ifdef CONFIG_SAM34_DMAC0 + /* Configure the TX DMA */ + + sam_dmatxsetup(priv->dma, SAM_HSMCI_TDR, (uint32_t)buffer, buflen); + +#if defined(CONFIG_ARCH_CHIP_SAM3U) + /* Enable DMA handshaking */ + + putreg32(HSMCI_DMA_DMAEN, SAM_HSMCI_DMA); +#endif + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + sam_dmastart(priv->dma, sam_dmacallback, priv); +#endif + +#ifdef CONFIG_SAM34_PDCA + modifyreg32(SAM_HSMCI_MR, 0, HSMCI_MR_PDCMODE); + fdbg("SAM_HSMCI_MR = 0x%08X\n", getreg32(SAM_HSMCI_MR)); + putreg32((uint32_t)buffer, SAM_HSMCI_PDC_TPR); + putreg32(buflen/4, SAM_HSMCI_PDC_TCR); + putreg32(PDC_PTCR_TXTEN, SAM_HSMCI_PDC_PTCR); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); +#endif + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is stard with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMASEND_INTS); + return OK; +} + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: sam_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void sam_callback(void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* Callbacks cannot be performed in the context of an interrupt handler. + * If we are in an interrupt handler, then queue the callback to be + * performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + fllvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + (void)work_queue(LPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + } + else + { + /* No.. then just call the callback here */ + + fvdbg("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SD for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + /* There is only one slot */ + + struct sam_dev_s *priv = &g_sdiodev; + + fdbg("slotno: %d\n", slotno); + + /* Initialize the HSMCI slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + +#ifdef CONFIG_SAM34_DMAC0 + /* Allocate a DMA channel. A FIFO size of 8 is sufficient. */ + + priv->dma = sam_dmachannel(DMA_FLAGS); + DEBUGASSERT(priv->dma); +#endif + + /* Configure GPIOs for 4-bit, wide-bus operation. NOTE: (1) the chip is capable of + * 8-bit wide bus operation but D4-D7 are not configured, (2) any card detection + * GPIOs must be set up in board-specific logic. + */ + + sam_configgpio(GPIO_HSMCI_DAT0); /* Data 0 of Slot A */ + sam_configgpio(GPIO_HSMCI_DAT1); /* Data 1 of Slot A */ + sam_configgpio(GPIO_HSMCI_DAT2); /* Data 2 of Slot A */ + sam_configgpio(GPIO_HSMCI_DAT3); /* Data 3 of Slot A */ + sam_configgpio(GPIO_HSMCI_CK); /* SD clock */ + sam_configgpio(GPIO_HSMCI_DA); /* Command/Response */ + +#ifdef CONFIG_DEBUG_FS + sam_dumpgpio(GPIO_PORT_PIOA, "Pins: 3-8"); + sam_dumpgpio(GPIO_PORT_PIOB, "Pins: 28-31"); +#endif + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + sam_reset(&priv->dev); + return &g_sdiodev.dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + fllvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + sam_callback(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} +#endif /* CONFIG_SAM34_HSMCI */ diff --git a/arch/arm/src/sam34/sam_hsmci.h b/arch/arm/src/sam34/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..3339c2d2958abf25b50c903c1dd0bc8436eb7d5a --- /dev/null +++ b/arch/arm/src/sam34/sam_hsmci.h @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_hsmci.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAM34_SAM_HSMCI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_HSMCI_H */ diff --git a/arch/arm/src/sam34/sam_irq.c b/arch/arm/src/sam34/sam_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..2a8b2f990ed4c6b582a9dca47e5d907927e4e606 --- /dev/null +++ b/arch/arm/src/sam34/sam_irq.c @@ -0,0 +1,652 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_irq.c + * + * Copyright (C) 2009, 2011, 2013-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#ifdef CONFIG_SAM34_GPIO_IRQ +# include "sam_gpio.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void sam_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); +#if SAM_IRQ_NEXTINT > 15 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 31 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 47 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 63 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 79 +# warning Missing logic +#endif + leave_critical_section(flags); +} +#else +# define sam_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: sam_nmi, sam_busfault, sam_usagefault, sam_pendsv, sam_dbgmonitor, + * sam_pendsv, sam_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int sam_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int sam_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int sam_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int sam_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int sam_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int sam_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: sam_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void sam_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: sam_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int sam_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + unsigned int extint = irq - SAM_IRQ_EXTINT; + + DEBUGASSERT(irq >= SAM_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= SAM_IRQ_EXTINT) + { +#if SAM_IRQ_NEXTINT <= 32 + if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else +#elif SAM_IRQ_NEXTINT <= 64 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else +#elif SAM_IRQ_NEXTINT <= 96 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else +#else +# warning Missing logic +#endif + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == SAM_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == SAM_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == SAM_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == SAM_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + uint32_t regval; +#endif + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(SAM_IRQ_SVCALL, up_svcall); + irq_attach(SAM_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(SAM_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + sam_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(SAM_IRQ_MEMFAULT, up_memfault); + up_enable_irq(SAM_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(SAM_IRQ_NMI, sam_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(SAM_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(SAM_IRQ_BUSFAULT, sam_busfault); + irq_attach(SAM_IRQ_USAGEFAULT, sam_usagefault); + irq_attach(SAM_IRQ_PENDSV, sam_pendsv); + irq_attach(SAM_IRQ_DBGMONITOR, sam_dbgmonitor); + irq_attach(SAM_IRQ_RESERVED, sam_reserved); +#endif + + sam_dumpnvic("initial", SAM_IRQ_NIRQS); + + /* If a debugger is connected, try to prevent it from catching hardfaults. + * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal + * operation. + */ + +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + regval = getreg32(NVIC_DEMCR); + regval &= ~NVIC_DEMCR_VCHARDERR; + putreg32(regval, NVIC_DEMCR); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_SAM34_GPIO_IRQ + sam_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (sam_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= SAM_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_SAM34_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqdisable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + sam_dumpnvic("disable", irq); +#endif +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (sam_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= SAM_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_SAM34_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqenable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + sam_dumpnvic("enable", irq); +#endif +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= SAM_IRQ_MEMFAULT && irq < SAM_IRQ_NIRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < SAM_IRQ_EXTINT) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= SAM_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + sam_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/sam34/sam_lowputc.c b/arch/arm/src/sam34/sam_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..88be9f0752c86e4699a95bfe67e61a831ba3189c --- /dev/null +++ b/arch/arm/src/sam34/sam_lowputc.c @@ -0,0 +1,455 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_lowputc.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "sam_lowputc.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4CM) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam_uart.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_usart.h" +#else +# error Unknown UART +#endif + +/* The board.h file may redefine pin configurations defined in sam_pinmap.h */ + +#include "chip/sam_pinmap.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* If the USART is not being used as a UART, then it really isn't enabled + * for our purposes. + */ + +#ifndef CONFIG_USART0_ISUART +# undef CONFIG_SAM34_USART0 +#endif +#ifndef CONFIG_USART1_ISUART +# undef CONFIG_SAM34_USART1 +#endif +#ifndef CONFIG_USART2_ISUART +# undef CONFIG_SAM34_USART2 +#endif +#ifndef CONFIG_USART3_ISUART +# undef CONFIG_SAM34_USART3 +#endif + +/* Is there a serial console? It could be on UART0-1 or USART0-3 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_SAM34_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_SAM34_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART0) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#else +# if !defined(CONFIG_NO_SERIAL_CONSOLE) +# warning "No valid CONFIG_USARTn_SERIAL_CONSOLE Setting" +# endif +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef HAVE_CONSOLE +#endif + +#if defined(HAVE_CONSOLE) + + /* Select MCU-specific settings + * + * For the SAM3U, SAM3A, SAM3X, SAM4E and SAM4S the USARTs are driven by the + * main clock. (This could also be the MCK/8 or an external clock but + * those options have not yet been necessary). + * For the SAM4L, the USARTs are driven by CLK_USART (undivided) which is + * selected by the PBADIVMASK register. + */ + +# if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4CM) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MR_USCLKS UART_MR_USCLKS_MCK /* Source = Main clock */ +# define SAM_USART_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ +# elif defined(CONFIG_ARCH_CHIP_SAM4L) +# define SAM_MR_USCLKS UART_MR_USCLKS_USART /* Source = USART_CLK (undefined) */ +# define SAM_USART_CLOCK BOARD_PBA_FREQUENCY /* PBA frequency is undivided */ +# else +# error Unrecognized SAM architecture +# endif + +/* Select USART parameters for the selected console */ + +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART0_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART0_2STOP +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART1_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART0_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART0_2STOP +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART1_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART1_2STOP +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART2_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART2_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART2_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART2_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART2_2STOP +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART3_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART3_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART3_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART3_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART3_2STOP +# else +# error "No CONFIG_U[S]ARTn_SERIAL_CONSOLE Setting" +# endif + +/* Select the settings for the mode register */ + +# if SAM_CONSOLE_BITS == 5 +# define MR_CHRL_VALUE UART_MR_CHRL_5BITS /* 5 bits */ +# elif SAM_CONSOLE_BITS == 6 +# define MR_CHRL_VALUE UART_MR_CHRL_6BITS /* 6 bits */ +# elif SAM_CONSOLE_BITS == 7 +# define MR_CHRL_VALUE UART_MR_CHRL_7BITS /* 7 bits */ +# elif SAM_CONSOLE_BITS == 8 +# define MR_CHRL_VALUE UART_MR_CHRL_8BITS /* 8 bits */ +# elif SAM_CONSOLE_BITS == 9 && !defined(CONFIG_UART0_SERIAL_CONSOLE) && \ + !defined(CONFIG_UART1_SERIAL_CONSOLE) +# define MR_CHRL_VALUE UART_MR_MODE9 +# else +# error "Invalid number of bits" +# endif + +# if SAM_CONSOLE_PARITY == 1 +# define MR_PAR_VALUE UART_MR_PAR_ODD +# elif SAM_CONSOLE_PARITY == 2 +# define MR_PAR_VALUE UART_MR_PAR_EVEN +# else +# define MR_PAR_VALUE UART_MR_PAR_NONE +# endif + +# if SAM_CONSOLE_2STOP != 0 +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_2 +# else +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_1 +# endif + +# define MR_VALUE (UART_MR_MODE_NORMAL | SAM_MR_USCLKS | \ + MR_CHRL_VALUE | MR_PAR_VALUE | MR_NBSTOP_VALUE) + +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, SAM_CONSOLE_BASE + SAM_UART_THR_OFFSET); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } +#endif +} + + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void sam_lowsetup(void) +{ + /* Enable clocking for all selected UART/USARTs */ + +#ifdef CONFIG_SAM34_UART0 + sam_uart0_enableclk(); +#endif +#ifdef CONFIG_SAM34_UART1 + sam_uart1_enableclk(); +#endif +#ifdef CONFIG_SAM34_USART0 + sam_usart0_enableclk(); +#endif +#ifdef CONFIG_SAM34_USART1 + sam_usart1_enableclk(); +#endif +#ifdef CONFIG_SAM34_USART2 + sam_usart2_enableclk(); +#endif +#ifdef CONFIG_SAM34_USART3 + sam_usart3_enableclk(); +#endif + + /* Configure UART pins for all selected UART/USARTs */ + +#ifdef CONFIG_SAM34_UART0 + (void)sam_configgpio(GPIO_UART0_RXD); + (void)sam_configgpio(GPIO_UART0_TXD); +#endif + +#ifdef CONFIG_SAM34_UART1 + (void)sam_configgpio(GPIO_UART1_RXD); + (void)sam_configgpio(GPIO_UART1_TXD); +#endif + +#ifdef CONFIG_SAM34_USART0 + (void)sam_configgpio(GPIO_USART0_RXD); + (void)sam_configgpio(GPIO_USART0_TXD); +#ifdef CONFIG_USART0_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART0_CTS); +#endif +#ifdef CONFIG_USART0_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART0_RTS); +#endif +#endif + +#ifdef CONFIG_SAM34_USART1 + (void)sam_configgpio(GPIO_USART1_RXD); + (void)sam_configgpio(GPIO_USART1_TXD); +#ifdef CONFIG_USART1_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART1_CTS); +#endif +#ifdef CONFIG_USART1_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART1_RTS); +#endif +#endif + +#ifdef CONFIG_SAM34_USART2 + (void)sam_configgpio(GPIO_USART2_RXD); + (void)sam_configgpio(GPIO_USART2_TXD); +#ifdef CONFIG_USART2_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART2_CTS); +#endif +#ifdef CONFIG_USART2_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART2_RTS); +#endif +#endif + +#ifdef CONFIG_SAM34_USART3 + (void)sam_configgpio(GPIO_USART3_RXD); + (void)sam_configgpio(GPIO_USART3_TXD); +#ifdef CONFIG_USART3_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART3_CTS); +#endif +#ifdef CONFIG_USART3_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART3_RTS); +#endif +#endif + + /* Configure the console (only) */ +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Reset and disable receiver and transmitter */ + + putreg32((UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS), + SAM_CONSOLE_BASE + SAM_UART_CR_OFFSET); + + /* Disable all interrupts */ + + putreg32(0xffffffff, SAM_CONSOLE_BASE + SAM_UART_IDR_OFFSET); + + /* Set up the mode register */ + + putreg32(MR_VALUE, SAM_CONSOLE_BASE + SAM_UART_MR_OFFSET); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower USART clocks. + */ + + putreg32(((SAM_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) / (SAM_CONSOLE_BAUD << 4)), + SAM_CONSOLE_BASE + SAM_UART_BRGR_OFFSET); + + /* Enable receiver & transmitter */ + + putreg32((UART_CR_RXEN | UART_CR_TXEN), + SAM_CONSOLE_BASE + SAM_UART_CR_OFFSET); +#endif +} diff --git a/arch/arm/src/sam34/sam_lowputc.h b/arch/arm/src/sam34/sam_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..c201b374b40b80eea548a9635ea9e66af453d784 --- /dev/null +++ b/arch/arm/src/sam34/sam_lowputc.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_lowputc.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_LOWPUTC_H +#define __ARCH_ARM_SRC_SAM34_SAM_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void sam_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_LOWPUTC_H */ diff --git a/arch/arm/src/sam34/sam_mpuinit.c b/arch/arm/src/sam34/sam_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..f49bb68d10a88cbcc40d24c5b78aa7cab036e7ef --- /dev/null +++ b/arch/arm/src/sam34/sam_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/common/sam_mpuinit.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "sam_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3/4 + * resources. + * + ****************************************************************************/ + +void sam_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: sam_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void sam_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/sam34/sam_mpuinit.h b/arch/arm/src/sam34/sam_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..104e235958f174ff20c66607e1001a012c5b270b --- /dev/null +++ b/arch/arm/src/sam34/sam_mpuinit.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_mpuinit.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_MPUINIT_H +#define __ARCH_ARM_SRC_SAM34_SAM_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted SAM3/4 + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_mpuinitialize(void); +#else +# define sam_mpuinitialize() +#endif + +/**************************************************************************** + * Name: sam_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_mpu_uheap(uintptr_t start, size_t size); +#else +# define sam_mpu_uheap(start,size) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_MPUINIT_H */ diff --git a/arch/arm/src/sam34/sam_periphclks.h b/arch/arm/src/sam34/sam_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..656279e7c2d37bd70cd7a75417ad6e2d934ebbcb --- /dev/null +++ b/arch/arm/src/sam34/sam_periphclks.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_periphclks.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAM34_SAM_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "sam3u_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "sam3x_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "sam4cm_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "sam4e_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "sam4l_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "sam4s_periphclks.h" +#else +# error Unknown SAM chip +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_PERIPHCLKS_H */ diff --git a/arch/arm/src/sam34/sam_rtc.c b/arch/arm/src/sam34/sam_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..8dbe4e9e1af6602dddee528887cabf0772b44745 --- /dev/null +++ b/arch/arm/src/sam34/sam_rtc.c @@ -0,0 +1,806 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_rtc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sam_rtc.h" + +#if defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTT) +# include "sam_rtt.h" +# include "sam_periphclks.h" +#endif + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_RTC_HIRES +# if !defined(CONFIG_SAM34_RTT) +# error RTT is required to emulate high resolution RTC +# endif +# if (CONFIG_RTC_FREQUENCY > 32768) || ((32768 % CONFIG_RTC_FREQUENCY) != 0) +# error CONFIG_RTC_FREQUENCY must be an integer division of 32768 +# endif +#endif + +#if defined(CONFIG_RTC_ALARM) && !defined(CONFIG_SCHED_WORKQUEUE) +# error CONFIG_RTC_ALARM requires CONFIG_SCHED_WORKQUEUE +#endif + +#define RTC_MAGIC 0xdeadbeef + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +/* Constants ************************************************************************/ + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +struct work_s g_alarmwork; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/* g_rtt_offset holds the rtt->rtc count offset */ + +#if defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTT) +uint32_t g_rtt_offset = 0; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" CR: %08x\n", getreg32(SAM_RTC_CR)); + rtclldbg(" MR: %08x\n", getreg32(SAM_RTC_MR)); + rtclldbg(" TIMR: %08x\n", getreg32(SAM_RTC_TIMR)); + rtclldbg(" CALR: %08x\n", getreg32(SAM_RTC_CALR)); + rtclldbg(" TIMALR: %08x\n", getreg32(SAM_RTC_TIMALR)); + rtclldbg(" CALALR: %08x\n", getreg32(SAM_RTC_CALALR)); + rtclldbg(" SR: %08x\n", getreg32(SAM_RTC_SR)); + rtclldbg(" IMR: %08x\n", getreg32(SAM_RTC_IMR)); + rtclldbg(" VER: %08x\n", getreg32(SAM_RTC_VER)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint32_t rtc_bin2bcd(int value) +{ + uint32_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint32_t value) +{ + uint32_t tens = (value >> 4) * 10; + return (int)(tens + (value & 0x0f)); +} + +/************************************************************************************ + * Name: rtc_worker + * + * Description: + * Perform alarm callback + * + * Input Parameters: + * Standard work callbacks + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static void rtc_worker(FAR void *arg) +{ + /* Sample once (atomically) */ + + alarmcb_t alarmcb = g_alarmcb; + + /* Is there a subscriber to the alarm? */ + + if (alarmcb) + { + /* Yes.. perform the callback */ + + alarmcb(); + } +} +#endif + +/************************************************************************************ + * Name: rtc_interrupt + * + * Description: + * RTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_interrupt(int irq, void *context) +{ + int ret; + + /* Schedule the callback to occur on the low-priority worker thread */ + + DEBUGASSERT(work_available(&g_alarmwork)); + ret = work_queue(LPWORK, &g_alarmwork, rtc_worker, NULL, 0); + if (ret < 0) + { + rtclldbg("ERRPR: work_queue failed: %d\n", ret); + } + + /* Disable any further alarm interrupts */ + + putreg32(RTC_IDR_ALRDIS, SAM_RTC_IDR); + + /* Clear any pending alarm interrupts */ + + putreg32(RTC_SCCR_ALRCLR, SAM_RTC_SCCR); + return OK; +} +#endif + +/************************************************************************************ + * Name: rtc_sync + * + * Description: + * Waits and returns immediately after 1 sec tick. For best accuracy, + * call with interrupts disabled. + * + * Returns value of the TIMR register + * + ************************************************************************************/ + +static uint32_t rtc_sync(void) +{ + uint32_t r0, r1; + + /* Get start second (stable) */ + + do + { + r0 = getreg32(SAM_RTC_TIMR); + } + while (r0 != getreg32(SAM_RTC_TIMR)); + + /* Now read until it changes */ + + do + { + r1 = getreg32(SAM_RTC_TIMR); + } + while (r1 == r0); + + return r1; +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + uint32_t ver; + + rtc_dumpregs("On reset"); + + /* No clocking setup need be performed. The Real-time Clock is continuously clocked + * at 32768 Hz (SCLK). The Power Management Controller has no effect on RTC + * behavior. + */ + + /* Set the 24 hour format */ + + putreg32(0, SAM_RTC_MR); + + /* Has the RTC been initialized? */ + + ver = getreg32(SAM_RTC_VER); + g_rtc_enabled = ((ver & (RTC_VER_NVTIM | RTC_VER_NVCAL)) == 0); + +#ifdef CONFIG_RTC_ALARM + /* Then attach the ALARM interrupt handler */ + + irq_attach(SAM_IRQ_RTC, rtc_interrupt); + + /* Should RTC alarm interrupt be enabled at the peripheral? Let's assume so + * for now. Let's say yes if the time is valid and a valid alarm has been + * programmed. + */ + + if (g_rtc_enabled && (ver & (RTC_VER_NVTIMALR | RTC_VER_NVCALALR)) == 0) + { + /* Enable the alarm interrupt at the RTC */ + + putreg32(RTC_IER_ALREN, SAM_RTC_IER); + } + else + { + /* Disable the alarm interrupt at the RTC */ + + putreg32(RTC_IDR_ALRDIS, SAM_RTC_IDR); + } + + /* Enable RTC interrupts */ + + up_enable_irq(SAM_IRQ_RTC); + +#endif + +#if defined(CONFIG_RTC_HIRES) && defined(CONFIG_SAM34_RTT) + /* Using the RTT for subsecond ticks. */ + + sam_rtt_enableclk(); + + /* Disable ints, set prescaler, start counter */ + + putreg32(RTT_MR_RTPRES(32768/CONFIG_RTC_FREQUENCY) | RTT_MR_RTTRST, SAM_RTT_MR); + + /* wait for a second tick to get the RTT offset. + * Interrupts are assumed to still be off at this point. + */ + + rtc_sync(); + + /* Probably safe to read the RTT_VR register now since the clock just ticked, + * but we'll be careful anyway. + */ + + do + { + g_rtt_offset = getreg32(SAM_RTT_VR); + } + while (getreg32(SAM_RTT_VR) != g_rtt_offset); +#endif + + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + uint32_t timr; + uint32_t calr; + uint32_t cent; + uint32_t year; + uint32_t tmp; + + /* Sample the data time registers. There is a race condition here... If we sample + * the time just before midnight on December 31, the date could be wrong because + * the day rolled over while were sampling. + */ + + do + { + calr = getreg32(SAM_RTC_CALR); + timr = getreg32(SAM_RTC_TIMR); + tmp = getreg32(SAM_RTC_CALR); + } + while (tmp != calr); + + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time register fields to struct tm format. + * + * struct tm TIMR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + tmp = (timr & RTC_TIMR_SEC_MASK) >> RTC_TIMR_SEC_SHIFT; + tp->tm_sec = rtc_bcd2bin(tmp); + + tmp = (timr & RTC_TIMR_MIN_MASK) >> RTC_TIMR_MIN_SHIFT; + tp->tm_min = rtc_bcd2bin(tmp); + + tmp = (timr & RTC_TIMR_HOUR_MASK) >> RTC_TIMR_HOUR_SHIFT; + tp->tm_hour = rtc_bcd2bin(tmp); + + /* Convert the RTC date register fields to struct tm format. + * + * struct tm TIMR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported + */ + + tmp = (calr & RTC_CALR_DATE_MASK) >> RTC_CALR_DATE_SHIFT; + tp->tm_mday = rtc_bcd2bin(tmp); + + tmp = (calr & RTC_CALR_MONTH_MASK) >> RTC_CALR_MONTH_SHIFT; + tp->tm_mon = rtc_bcd2bin(tmp) - 1; + + tmp = (calr & RTC_CALR_CENT_MASK) >> RTC_CALR_CENT_SHIFT; + cent = rtc_bcd2bin(tmp); + tmp = (calr & RTC_CALR_YEAR_MASK) >> RTC_CALR_YEAR_SHIFT; + year = rtc_bcd2bin(tmp); + tp->tm_year = cent * 100 + year - 1900; + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + uint32_t regval; + uint32_t timr; + uint32_t calr; + uint32_t cent; + uint32_t year; + + /* Break out the time values (note that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + rtc_dumptime(&newtime, "Setting time"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. + * + * struct tm TIMR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + timr = (rtc_bin2bcd(newtime.tm_sec) << RTC_TIMR_SEC_SHIFT) & RTC_TIMR_SEC_MASK; + timr |= (rtc_bin2bcd(newtime.tm_min) << RTC_TIMR_MIN_SHIFT) & RTC_TIMR_MIN_MASK; + timr |= (rtc_bin2bcd(newtime.tm_hour) << RTC_TIMR_HOUR_SHIFT) & RTC_TIMR_HOUR_MASK; + + /* Convert the struct tm format to RTC date register fields. + * + * struct tm CALR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported. Set to Monday. + */ + + calr = (rtc_bin2bcd(newtime.tm_mday) << RTC_CALR_DATE_SHIFT) & RTC_CALR_DATE_MASK; + calr |= (rtc_bin2bcd(1) << RTC_CALR_DAY_SHIFT) & RTC_CALR_DAY_MASK; + calr |= (rtc_bin2bcd(newtime.tm_mon+1) << RTC_CALR_MONTH_SHIFT) & RTC_CALR_MONTH_MASK; + + cent = newtime.tm_year / 100 + 19; + year = newtime.tm_year % 100; + + calr |= (rtc_bin2bcd(year) << RTC_CALR_YEAR_SHIFT) & RTC_CALR_YEAR_MASK; + calr |= (rtc_bin2bcd(cent) << RTC_CALR_CENT_SHIFT) & RTC_CALR_CENT_MASK; + + /* Stop RTC time and date counting */ + + regval = getreg32(SAM_RTC_CR); + regval |= (RTC_CR_UPDTIM | RTC_CR_UPDCAL); + putreg32(regval, SAM_RTC_CR); + + /* Wait until the RTC has stopped so that we can update the time */ + + while ((getreg32(SAM_RTC_SR) & RTC_SR_ACKUPD) != RTC_SR_ACKUPD); + + /* Clear the ACKUPD bit in the status register */ + + putreg32(RTC_SCCR_ACKCLR, SAM_RTC_SCCR); + + /* Set the new date */ + + putreg32(calr, SAM_RTC_CALR); + + /* Write the new time */ + + putreg32(timr, SAM_RTC_TIMR); + + /* Resume RTC date/time counting */ + + regval = getreg32(SAM_RTC_CR); + regval &= ~(RTC_CR_UPDTIM | RTC_CR_UPDCAL); + putreg32(regval, SAM_RTC_CR); + + /* Clear the SEC status in the SR */ + + regval = getreg32(SAM_RTC_SCCR); + regval = RTC_SCCR_SECCLR; + putreg32(regval, SAM_RTC_SCCR); + + /* The RTC should now be enabled */ + + g_rtc_enabled = ((getreg32(SAM_RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL)) == 0); + DEBUGASSERT(g_rtc_enabled); + + rtc_dumpregs("New time setting"); + return OK; +} + +/************************************************************************************ + * Name: sam_rtc_setalarm + * + * Description: + * Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B). + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int sam_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + FAR struct tm newalarm; + irqstate_t flags; + uint32_t timalr; + uint32_t calalr; + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + flags = enter_critical_section(); + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Clear any pending alarm interrupts */ + + putreg32(RTC_SCCR_ALRCLR, SAM_RTC_SCCR); + + /* Break out the time values (note that the time is set only to units + * of seconds) + */ + + (void)gmtime_r(&tp->tv_sec, &newalarm); + rtc_dumptime(&newalarm, "Setting alarm"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. + * + * struct tm TIMALR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + timalr = (rtc_bin2bcd(newalarm.tm_sec) << RTC_TIMALR_SEC_SHIFT) & RTC_TIMALR_SEC_MASK; + timalr |= (rtc_bin2bcd(newalarm.tm_min) << RTC_TIMALR_MIN_SHIFT) & RTC_TIMALR_MIN_MASK; + timalr |= (rtc_bin2bcd(newalarm.tm_hour) << RTC_TIMALR_HOUR_SHIFT) & RTC_TIMALR_HOUR_MASK; + timalr |= (RTC_TIMALR_SECEN | RTC_TIMALR_MINEN | RTC_TIMALR_HOUREN); + + /* Convert the struct tm format to RTC date register fields. + * + * struct tm CALALR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported + */ + + calalr = (rtc_bin2bcd(newalarm.tm_mday) << RTC_CALALR_DATE_SHIFT) & RTC_CALALR_DATE_MASK; + calalr |= (rtc_bin2bcd(newalarm.tm_mon+1) << RTC_CALALR_MONTH_SHIFT) & RTC_CALALR_MONTH_MASK; + calalr |= (RTC_CALALR_MTHEN | RTC_CALALR_DATEEN); + + /* Set the new date */ + + putreg32(calalr, SAM_RTC_CALALR); + + /* Write the new time */ + + putreg32(timalr, SAM_RTC_TIMALR); + + DEBUGASSERT((getreg32(SAM_RTC_VER) & RTC_VER_NVTIMALR) == 0); + DEBUGASSERT((getreg32(SAM_RTC_VER) & RTC_VER_NVCALALR) == 0); + + rtc_dumpregs("New alarm setting"); + + /* Enable alarm interrupts */ + + putreg32(RTC_IER_ALREN, SAM_RTC_IER); + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + + +/************************************************************************************ + * Name: up_rtc_gettime + * + * Description: + * Get the current time from the high resolution RTC clock/counter. This interface + * is only supported by the high-resolution RTC/counter hardware implementation. + * It is used to replace the system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#if defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTT) +int up_rtc_gettime(FAR struct timespec *tp) +{ + /* This is a hack to emulate a high resolution rtc using the rtt */ + + uint32_t rtc_cal, rtc_tim, rtt_val; + struct tm t; + + do + { + rtc_cal = getreg32(SAM_RTC_CALR); + rtc_tim = getreg32(SAM_RTC_TIMR); + rtt_val = getreg32(SAM_RTT_VR); + } + while (rtc_cal != getreg32(SAM_RTC_CALR) || + rtc_tim != getreg32(SAM_RTC_TIMR) || + rtt_val != getreg32(SAM_RTT_VR)); + + t.tm_sec = rtc_bcd2bin((rtc_tim & RTC_TIMR_SEC_MASK) >> RTC_TIMR_SEC_SHIFT); + t.tm_min = rtc_bcd2bin((rtc_tim & RTC_TIMR_MIN_MASK) >> RTC_TIMR_MIN_SHIFT); + t.tm_hour = rtc_bcd2bin((rtc_tim & RTC_TIMR_HOUR_MASK) >> RTC_TIMR_HOUR_SHIFT); + t.tm_mday = rtc_bcd2bin((rtc_cal & RTC_CALR_DATE_MASK) >> RTC_CALR_DATE_SHIFT); + t.tm_mon = rtc_bcd2bin((rtc_cal & RTC_CALR_MONTH_MASK) >> RTC_CALR_MONTH_SHIFT); + t.tm_year = (rtc_bcd2bin((rtc_cal & RTC_CALR_CENT_MASK) >> RTC_CALR_CENT_SHIFT) * 100) + + rtc_bcd2bin((rtc_cal & RTC_CALR_YEAR_MASK) >> RTC_CALR_YEAR_SHIFT) + - 1900; + + tp->tv_sec = mktime(&t); + tp->tv_nsec = (((rtt_val-g_rtt_offset) & (CONFIG_RTC_FREQUENCY-1)) * 1000000000ULL) / + CONFIG_RTC_FREQUENCY; + + return OK; +} +#endif + +#endif /* CONFIG_RTC */ diff --git a/arch/arm/src/sam34/sam_rtc.h b/arch/arm/src/sam34/sam_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..03ab31669350af81d0bf14c9279ebb88484ac84a --- /dev/null +++ b/arch/arm/src/sam34/sam_rtc.h @@ -0,0 +1,105 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_rtc.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_RTC_H +#define __ARCH_ARM_SRC_SAM34_SAM_RTC_H + +#include + +#include "chip.h" +#include "chip/sam_rtc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* The form of an alarm callback */ + +typedef void (*alarmcb_t)(void); + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct timespec; +int sam_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_RTC_H */ diff --git a/arch/arm/src/sam34/sam_rtt.c b/arch/arm/src/sam34/sam_rtt.c new file mode 100644 index 0000000000000000000000000000000000000000..a0c94f7ef77e0323eafb6009fec459100fa06603 --- /dev/null +++ b/arch/arm/src/sam34/sam_rtt.c @@ -0,0 +1,676 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_rtt.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Dioron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_rtt.h" +#include "sam_periphclks.h" + +#if defined(CONFIG_TIMER) && (defined(CONFIG_SAM34_RTT)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Clocking *****************************************************************/ + +#if defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTC) +# define RTT_PRES (32768/CONFIG_RTC_FREQUENCY) +#else +/* TODO: Allow prescaler selection. */ +# define RTT_PRES 1 +#endif + +#define RTT_FCLK (BOARD_SCLK_FREQUENCY/RTT_PRES) +#define RTT_MAXTIMEOUT ((1000000ULL * (0x100000000ULL)) / RTT_FCLK) + +/* Configuration ************************************************************/ + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the timer + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_RTT +# define rttdbg lldbg +# define rttvdbg llvdbg +#else +# define rttdbg(x...) +# define rttvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct sam34_lowerhalf_s +{ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + + /* Private data */ + + tccb_t handler; /* Current user interrupt handler */ + uint32_t timeout; /* The current timeout value (us) */ + uint32_t clkticks; /* actual clock ticks for current interval */ + uint32_t val; /* rtt value of current timeout */ + uint32_t adjustment; /* time lost due to clock resolution truncation (us) */ + bool started; /* The timer has been started */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAM34_RTT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr); +static void sam34_putreg(uint32_t val, uint32_t addr); +#else +# define sam34_getreg(addr) getreg32(addr) +# define sam34_putreg(val,addr) putreg32(val,addr) +#endif + +/* Interrupt handling *******************************************************/ + +static int sam34_interrupt(int irq, FAR void *context); + +/* "Lower half" driver methods **********************************************/ + +static int sam34_start(FAR struct timer_lowerhalf_s *lower); +static int sam34_stop(FAR struct timer_lowerhalf_s *lower); +static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status); +static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout); +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler); +static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_tcops = +{ + .start = sam34_start, + .stop = sam34_stop, + .getstatus = sam34_getstatus, + .settimeout = sam34_settimeout, + .sethandler = sam34_sethandler, + .ioctl = sam34_ioctl, +}; + +/* "Lower half" driver state */ + +static struct sam34_lowerhalf_s g_tcdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam34_readvr + * + * Description: + * Get the contents of the value register. + * + ****************************************************************************/ +static inline uint32_t sam34_readvr(void) +{ + register uint32_t v; + + /* Async counter, read until two consecutive reads match */ + + do + { + v = getreg32(SAM_RTT_VR); + } + while (v != getreg32(SAM_RTT_VR)); + + return v; +} + +/**************************************************************************** + * Name: sam34_getreg + * + * Description: + * Get the contents of a register + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_RTT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08lx->%08lx\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: sam34_putreg + * + * Description: + * Set the contents of an SAM34 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_RTT_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam34_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08lx<-%08lx\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: sam34_interrupt + * + * Description: + * TC interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +static int sam34_interrupt(int irq, FAR void *context) +{ + FAR struct sam34_lowerhalf_s *priv = &g_tcdev; + + rttvdbg("Entry\n"); + DEBUGASSERT(irq == SAM_IRQ_RTT); + + /* Check if the interrupt is really pending */ + + if ((sam34_getreg(SAM_RTT_SR) & RTT_SR_ALMS) != 0) + { + uint32_t timeout; + uint32_t mrval; + uint32_t vr; + uint32_t lateticks; + + /* Is there a registered handler? */ + + if (priv->handler && priv->handler(&priv->timeout)) + { + /* Disable int before writing new alarm */ + + mrval = sam34_getreg(SAM_RTT_MR); + sam34_putreg(mrval & ~RTT_MR_ALMIEN, SAM_RTT_MR); + + /* Calculate new ticks / dither adjustment */ + + vr = sam34_readvr(); + priv->clkticks = + ((uint64_t)(priv->adjustment + priv->timeout)) * RTT_FCLK / 1000000; + + /* Subtract off how late we are, but only up to half an interval. + * TODO calculate lost ticks? + */ + + lateticks = vr - priv->val; + if (lateticks <= (priv->clkticks >> 1)) + { + priv->clkticks -= lateticks; + } + + /* Set next interval interval. */ + + priv->val = vr + priv->clkticks; + sam34_putreg(priv->val-1, SAM_RTT_AR); + + /* Re-enable alarm */ + + sam34_putreg(mrval, SAM_RTT_MR); + + /* Truncated timeout */ + + timeout = (1000000ULL * priv->clkticks) / RTT_FCLK; + + /* Truncated time to be added to next interval (dither) */ + + priv->adjustment = (priv->adjustment + priv->timeout) - timeout; + } + else /* stop */ + { + sam34_stop((FAR struct timer_lowerhalf_s *)priv); + } + + /* RTT_SR_ALMS is cleared by reading SAM_RTT_SR */ + } + + return OK; +} + +/**************************************************************************** + * Name: sam34_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_start(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t mr; + uint32_t vr; + + rttvdbg("Entry\n"); + DEBUGASSERT(priv); + + if (priv->started) + { + return -EINVAL; + } + +#if defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTC) + /* RTT is started with the RTC and always on */ + + mr = sam34_getreg(SAM_RTT_MR) & ~RTT_MR_ALMIEN; + sam34_putreg(mr, SAM_RTT_MR); + vr = sam34_readvr(); + +#else + sam_rtt_enableclk(); /* Enable peripheral clock */ + mr = RTT_MR_RTPRES(RTT_PRES); + sam34_putreg(mr, SAM_RTT_MR); /* Set prescaler, disable ints */ + vr = 0; /* we're going to reset the counter */ +#endif + + priv->val = vr + priv->clkticks; /* value at end of interval */ + sam34_putreg(priv->val-1, SAM_RTT_AR); /* Set interval */ + + if (priv->handler) + { + /* Clear status and enable interrupt */ + + sam34_getreg(SAM_RTT_SR); + mr |= RTT_MR_ALMIEN; + sam34_putreg(mr, SAM_RTT_MR); + } + +#if !(defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTC)) + sam34_putreg(mr | RTT_MR_RTTRST, SAM_RTT_MR); /* Start counter */ +#endif /* !(CONFIG_RTC_HIRES && CONFIG_SAM34_RTC) */ + + priv->started = true; + return OK; +} + +/**************************************************************************** + * Name: sam34_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_stop(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + rttvdbg("Entry\n"); + DEBUGASSERT(priv); + + if (!priv->started) + { + return -EINVAL; + } + +#if !(defined(CONFIG_RTC_HIRES) && defined (CONFIG_SAM34_RTC)) +#if defined(RTT_MR_RTTDIS) + sam34_putreg(RTT_MR_RTTDIS, SAM_RTT_MR); /* Disable RTT */ +#endif + sam_rtt_disableclk(); /* Disable peripheral clock */ +#endif + + priv->started = false; + + return OK; +} + +/**************************************************************************** + * Name: sam34_getstatus + * + * Description: + * Get the current timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + + rttvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = 0; + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->handler) + { + status->flags |= TCFLAGS_HANDLER; + } + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the timer expires (in microseconds) */ + + status->timeleft = 1000000ULL*(sam34_getreg(SAM_RTT_AR) - sam34_readvr())/RTT_FCLK; + + rttvdbg(" flags : %08x\n", status->flags); + rttvdbg(" timeout : %d\n", status->timeout); + rttvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam34_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in milliseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + + DEBUGASSERT(priv); + rttvdbg("Entry: timeout=%d\n", timeout); + + if (priv->started) + { + return -EPERM; + } + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > RTT_MAXTIMEOUT) + { + rttdbg("Cannot represent timeout=%lu > %lu\n", + timeout, RTT_MAXTIMEOUT); + return -ERANGE; + } + + priv->timeout = timeout; /* Intended timeout */ + priv->clkticks = (((uint64_t)timeout * RTT_FCLK) / 1000000); /* Actual clock ticks */ + timeout = (1000000ULL * priv->clkticks) / RTT_FCLK; /* Truncated timeout */ + priv->adjustment = priv->timeout - timeout; /* Truncated time to be added to next interval (dither) */ + + rttvdbg("fclk=%d clkticks=%d timout=%d, adjustment=%d\n", + RTT_FCLK, priv->clkticks, priv->timeout, priv->adjustment); + + return OK; +} + +/**************************************************************************** + * Name: sam34_sethandler + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + irqstate_t flags; + tccb_t oldhandler; + + flags = enter_critical_section(); + + DEBUGASSERT(priv); + rttvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + leave_critical_section(flags); + return oldhandler; +} + +/**************************************************************************** + * Name: sam34_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctl command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + int ret = -ENOTTY; + + DEBUGASSERT(priv); + rttvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg); + UNUSED(priv); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_rttinitialize + * + * Description: + * Initialize the timer. The timer is initialized and registers as + * 'devpath'. + * + * Input Parameters: + * devpath - The full path to the timer. This should be of the form + * /dev/rtt0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sam_rttinitialize(FAR const char *devpath) +{ + FAR struct sam34_lowerhalf_s *priv = &g_tcdev; + + rttvdbg("Entry: devpath=%s\n", devpath); + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_tcops; + + (void)irq_attach(SAM_IRQ_RTT, sam34_interrupt); + + /* Enable NVIC interrupt. */ + + up_enable_irq(SAM_IRQ_RTT); + + /* Register the timer driver as /dev/timerX */ + + (void)timer_register(devpath, (FAR struct timer_lowerhalf_s *)priv); +} + +#endif /* CONFIG_TIMER && CONFIG_SAM34_TCx */ diff --git a/arch/arm/src/sam34/sam_rtt.h b/arch/arm/src/sam34/sam_rtt.h new file mode 100644 index 0000000000000000000000000000000000000000..f300747efb3f5aff624ff55f42156273a86f878c --- /dev/null +++ b/arch/arm/src/sam34/sam_rtt.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_rtt.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_RTT_H +#define __ARCH_ARM_SRC_SAM34_RTT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_rtt.h" + +#ifdef CONFIG_TIMER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if defined(CONFIG_SAM34_RTT) + +/**************************************************************************** + * Name: sam_rttinitialize + * + * Description: + * Initialize the timer. The timer is initialized and registers as + * 'devpath. The initial state of the timer is disabled. + * + * Input Parameters: + * devpath - The full path to the timer. This should be of the form + * /dev/rtt0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sam_rttinitialize(FAR const char *devpath); + +#endif // CONFIG_SAM34_RTT + + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_TIMER */ +#endif /* __ARCH_ARM_SRC_SAM34_RTT_H */ diff --git a/arch/arm/src/sam34/sam_serial.c b/arch/arm/src/sam34/sam_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..306a1210ea5d597e566704ab212f308dcb9a527d --- /dev/null +++ b/arch/arm/src/sam34/sam_serial.c @@ -0,0 +1,1452 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_serial.c + * + * Copyright (C) 2010, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4CM) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam_uart.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_usart.h" +#else +# error Unknown UART +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* If the USART is not being used as a UART, then it really isn't enabled + * for our purposes. + */ + +#ifndef CONFIG_USART0_ISUART +# undef CONFIG_SAM34_USART0 +#endif +#ifndef CONFIG_USART1_ISUART +# undef CONFIG_SAM34_USART1 +#endif +#ifndef CONFIG_USART2_ISUART +# undef CONFIG_SAM34_USART2 +#endif +#ifndef CONFIG_USART3_ISUART +# undef CONFIG_SAM34_USART3 +#endif + +/* Is there a USART/USART enabled? */ + +#if !defined(CONFIG_SAM34_UART0) && !defined(CONFIG_SAM34_UART1) && \ + !defined(CONFIG_SAM34_USART0) && !defined(CONFIG_SAM34_USART1) && \ + !defined(CONFIG_SAM34_USART2) && !defined(CONFIG_SAM34_USART3) +# error "No USARTs enabled" +#endif + +#if defined(CONFIG_SAM34_USART0) || defined(CONFIG_SAM34_USART1) ||\ + defined(CONFIG_SAM34_USART2) || defined(CONFIG_SAM34_USART3) +# define HAVE_USART +#endif + +/* Hardware flow control requires using the PDC or DMAC channel for reception */ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +# warning PDC or DMAC support is required for RTS hardware flow control +# undef CONFIG_SERIAL_IFLOWCONTROL +# undef CONFIG_USART0_IFLOWCONTROL +# undef CONFIG_USART1_IFLOWCONTROL +# undef CONFIG_USART2_IFLOWCONTROL +# undef CONFIG_USART3_IFLOWCONTROL +#endif + +/* Is there a serial console? It could be on UART0-1 or USART0-3 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_SAM34_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_SAM34_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART0) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_SAM34_USART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#else +# ifndef CONFIG_NO_SERIAL_CONSOLE +# warning "No valid CONFIG_USARTn_SERIAL_CONSOLE Setting" +# endif + +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef HAVE_CONSOLE +#endif + +#ifdef USE_SERIALDRIVER + +/* Which UART/USART with be tty0/console and which tty1? tty2? tty3? tty4? tty5? */ + +/* First pick the console and ttys0. This could be any of UART0-1, USART0-3 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart3port /* USART3 is console */ +# define TTYS5_DEV g_usart3port /* USART3 is ttyS0 */ +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_SAM34_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_SAM34_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_SAM34_USART0) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +# elif defined(CONFIG_SAM34_USART1) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +# elif defined(CONFIG_SAM34_USART2) +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +# elif defined(CONFIG_SAM34_USART3) +# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */ +# define USART3_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-1, USART0-3 excluding the console UART. */ + +#if defined(CONFIG_SAM34_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_SAM34_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART0) && !defined(USART0_ASSIGNED) +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART1) && !defined(USART1_ASSIGNED) +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART2) && !defined(USART2_ASSIGNED) +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART3) && !defined(USART3_ASSIGNED) +# define TTYS1_DEV g_usart3port /* USART3 is ttyS1 */ +# define USART3_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1 or USART0-3. It can't be UART0 + * because that was either assigned as ttyS0 or ttys1. One of these + * could also be the console. + */ + +#if defined(CONFIG_SAM34_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART0) && !defined(USART0_ASSIGNED) +# define TTYS2_DEV g_usart0port /* USART0 is ttyS2 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART1) && !defined(USART1_ASSIGNED) +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART2) && !defined(USART2_ASSIGNED) +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART3) && !defined(USART3_ASSIGNED) +# define TTYS2_DEV g_usart3port /* USART3 is ttyS2 */ +# define USART3_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of USART0-3. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * USART0-3 could also be the console. + */ + +#if defined(CONFIG_SAM34_USART0) && !defined(USART0_ASSIGNED) +# define TTYS3_DEV g_usart0port /* USART0 is ttyS3 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART1) && !defined(USART1_ASSIGNED) +# define TTYS3_DEV g_usart1port /* USART1 is ttyS3 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART2) && !defined(USART2_ASSIGNED) +# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART3) && !defined(USART3_ASSIGNED) +# define TTYS3_DEV g_usart3port /* USART3 is ttyS3 */ +# define USART3_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of USART1-3. It can't be UART0-1 or USART0 + * because those have already been assigned to ttsyS0, 1, 2 or 3. One of + * USART1-3 could also be the console. + */ + +#if defined(CONFIG_SAM34_USART1) && !defined(USART1_ASSIGNED) +# define TTYS4_DEV g_usart1port /* USART1 is ttyS4 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART2) && !defined(USART2_ASSIGNED) +# define TTYS4_DEV g_usart2port /* USART2 is ttyS4 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART3) && !defined(USART3_ASSIGNED) +# define TTYS4_DEV g_usart3port /* USART3 is ttyS4 */ +# define USART3_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of USART2-3. It can't be UART0-1 or + * USART0-1 because those have already been assigned to ttsyS0, 1, 2, + * 3 or 4. One of USART2-3 could also be the console. + */ + +#if defined(CONFIG_SAM34_USART2) && !defined(USART2_ASSIGNED) +# define TTYS5_DEV g_usart2port /* USART2 is ttyS5 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_SAM34_USART3) && !defined(USART3_ASSIGNED) +# define TTYS5_DEV g_usart3port /* USART3 is ttyS5 */ +# define USART3_ASSIGNED 1 +#endif + +/* Select MCU-specific settings + * + * For the SAM3U, SAM3A, SAM3X, SAM4E and SAM4S the USARTs are driven by the + * main clock. (This could also be the MCK/8 or an external clock but + * those options have not yet been necessary). + * For the SAM4L, the USARTs are driven by CLK_USART (undivided) which is + * selected by the PBADIVMASK register. + */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4CM) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_MR_USCLKS UART_MR_USCLKS_MCK /* Source = Main clock */ +# define SAM_USART_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# define SAM_MR_USCLKS UART_MR_USCLKS_USART /* Source = USART_CLK (undefined) */ +# define SAM_USART_CLOCK BOARD_PBA_FREQUENCY /* PBA frequency is undivided */ +#else +# error Unrecognized SAM architecture +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + const uint32_t usartbase; /* Base address of USART registers */ + uint32_t baud; /* Configured baud */ + uint32_t sr; /* Saved status bits */ + uint8_t irq; /* IRQ associated with this USART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-9) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; /* input flow control (RTS) enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_SAM34_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAM34_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAM34_USART0 +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAM34_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAM34_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAM34_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif + +/* This describes the state of the UART0 port. */ + +#ifdef CONFIG_SAM34_UART0 +static struct up_dev_s g_uart0priv = +{ + .usartbase = SAM_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = SAM_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the UART1 port. */ + +#ifdef CONFIG_SAM34_UART1 +static struct up_dev_s g_uart1priv = +{ + .usartbase = SAM_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = SAM_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the USART0 port. */ + +#ifdef CONFIG_SAM34_USART0 +static struct up_dev_s g_usart0priv = +{ + .usartbase = SAM_USART0_BASE, + .baud = CONFIG_USART0_BAUD, + .irq = SAM_IRQ_USART0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +#if defined(CONFIG_USART0_OFLOWCONTROL) || defined(CONFIG_USART0_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the USART1 port. */ + +#ifdef CONFIG_SAM34_USART1 +static struct up_dev_s g_usart1priv = +{ + .usartbase = SAM_USART1_BASE, + .baud = CONFIG_USART1_BAUD, + .irq = SAM_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, +#if defined(CONFIG_USART1_OFLOWCONTROL) || defined(CONFIG_USART1_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the USART2 port. */ + +#ifdef CONFIG_SAM34_USART2 +static struct up_dev_s g_usart2priv = +{ + .usartbase = SAM_USART2_BASE, + .baud = CONFIG_USART2_BAUD, + .irq = SAM_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +#if defined(CONFIG_USART2_OFLOWCONTROL) || defined(CONFIG_USART2_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/* This describes the state of the USART3 port. */ + +#ifdef CONFIG_SAM34_USART3 +static struct up_dev_s g_usart3priv = +{ + .usartbase = SAM_USART3_BASE, + .baud = CONFIG_USART3_BAUD, + .irq = SAM_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, +#if defined(CONFIG_USART3_OFLOWCONTROL) || defined(CONFIG_USART3_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart3port = +{ + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart3priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static inline void up_restoreusartint(struct up_dev_s *priv, uint32_t imr) +{ + /* Re-enable previously disabled interrupts state (assuming all interrupts + * disabled) + */ + + up_serialout(priv, SAM_UART_IER_OFFSET, imr); +} + +/**************************************************************************** + * Name: up_disableallints + ****************************************************************************/ + +static void up_disableallints(struct up_dev_s *priv, uint32_t *imr) +{ + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + if (imr) + { + /* Return the current interrupt mask */ + + *imr = up_serialin(priv, SAM_UART_IMR_OFFSET); + } + + /* Disable all interrupts */ + + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_ALLINTS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + uint32_t imr; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled and the pins were configured in sam_lowsetup(). + */ + + /* The shutdown method will put the UART in a known, disabled state */ + + up_disableallints(priv, &imr); + up_shutdown(dev); + + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source + */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + /* "Setting the USART to operate with hardware handshaking is performed by + * writing the USART_MODE field in the Mode Register (US_MR) to the value + * 0x2. ... Using this mode requires using the PDC or DMAC channel for + * reception. The transmitter can handle hardware handshaking in any case." + */ + + if (priv->flowc) + { + /* Enable hardware flow control and MCK as the timing source */ + + regval = (UART_MR_MODE_HWHS | SAM_MR_USCLKS); + } + else +#endif + { + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source + */ + + regval = (UART_MR_MODE_NORMAL | SAM_MR_USCLKS); + } + + /* OR in settings for the selected number of bits */ + + if (priv->bits == 5) + { + regval |= UART_MR_CHRL_5BITS; /* 5 bits */ + } + else if (priv->bits == 6) + { + regval |= UART_MR_CHRL_6BITS; /* 6 bits */ + } + else if (priv->bits == 7) + { + regval |= UART_MR_CHRL_7BITS; /* 7 bits */ + } +#ifdef HAVE_USART + else if (priv->bits == 9 +#if defined(CONFIG_SAM34_UART0) + && priv->usartbase != SAM_UART0_BASE +#endif +#if defined(CONFIG_SAM34_UART1) + && priv->usartbase != SAM_UART1_BASE +#endif + ) + { + regval |= UART_MR_MODE9; /* 9 bits */ + } +#endif + else /* if (priv->bits == 8) */ + { + regval |= UART_MR_CHRL_8BITS; /* 8 bits (default) */ + } + + /* OR in settings for the selected parity */ + + if (priv->parity == 1) + { + regval |= UART_MR_PAR_ODD; + } + else if (priv->parity == 2) + { + regval |= UART_MR_PAR_EVEN; + } + else + { + regval |= UART_MR_PAR_NONE; + } + + /* OR in settings for the number of stop bits */ + + if (priv->stopbits2) + { + regval |= UART_MR_NBSTOP_2; + } + else + { + regval |= UART_MR_NBSTOP_1; + } + +#ifdef CONFIG_SAM34_UART1_OPTICAL + if (priv == &g_uart1priv) + { + /* Enable optical mode. */ + + regval |= UART_MR_OPT_EN; + } +#endif + + /* And save the new mode register value */ + + up_serialout(priv, SAM_UART_MR_OFFSET, regval); + + /* Configure the console baud: + * + * Fbaud = USART_CLOCK / (16 * divisor) + * divisor = USART_CLOCK / (16 * Fbaud) + * + * NOTE: Oversampling by 8 is not supported. This may limit BAUD rates + * for lower USART clocks. + */ + + regval = (SAM_USART_CLOCK + (priv->baud << 3))/(priv->baud << 4); + up_serialout(priv, SAM_UART_BRGR_OFFSET, regval); + + /* Enable receiver & transmitter */ + + up_serialout(priv, SAM_UART_CR_OFFSET, (UART_CR_RXEN | UART_CR_TXEN)); + up_restoreusartint(priv, imr); + +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Reset and disable receiver and transmitter */ + + up_serialout(priv, SAM_UART_CR_OFFSET, + (UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | + UART_CR_TXDIS)); + + /* Disable all interrupts */ + + up_disableallints(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t pending; + uint32_t imr; + int passes; + bool handled; + +#ifdef CONFIG_SAM34_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_SAM34_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_SAM34_USART0 + if (g_usart0priv.irq == irq) + { + dev = &g_usart0port; + } + else +#endif +#ifdef CONFIG_SAM34_USART1 + if (g_usart1priv.irq == irq) + { + dev = &g_usart1port; + } + else +#endif +#ifdef CONFIG_SAM34_USART2 + if (g_usart2priv.irq == irq) + { + dev = &g_usart2port; + } + else +#endif +#ifdef CONFIG_SAM34_USART3 + if (g_usart3priv.irq == irq) + { + dev = &g_usart3port; + } + else +#endif + { + PANIC(); + } + + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the UART/USART status (we are only interested in the unmasked interrupts). */ + + priv->sr = up_serialin(priv, SAM_UART_SR_OFFSET); /* Save for error reporting */ + imr = up_serialin(priv, SAM_UART_IMR_OFFSET); /* Interrupt mask */ + pending = priv->sr & imr; /* Mask out disabled interrupt sources */ + + /* Handle an incoming, receive byte. RXRDY: At least one complete character + * has been received and US_RHR has not yet been read. + */ + + if ((pending & UART_INT_RXRDY) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes. TXRDY: There is no character in the + * US_THR. + */ + + if ((pending & UART_INT_TXRDY) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Return baud */ + + cfsetispeed(termiosp, priv->baud); + + /* Return parity */ + + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; + + /* Return flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= (priv->flowc) ? (CCTS_OFLOW | CRTS_IFLOW): 0; +#endif + /* Return number of bits */ + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + default: + case 8: + termiosp->c_cflag |= CS8; + break; + + case 9: + termiosp->c_cflag |= CS8 /* CS9 */; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t baud; + uint32_t imr; + uint8_t parity; + uint8_t nbits; + bool stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; +#endif + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Decode baud. */ + + ret = OK; + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + nbits = 5; + break; + + case CS6: + nbits = 6; + break; + + case CS7: + nbits = 7; + break; + + case CS8: + nbits = 8; + break; +#if 0 + case CS9: + nbits = 9; + break; +#endif + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) != 0; + + /* Decode flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + flowc = (termiosp->c_cflag & (CCTS_OFLOW | CRTS_IFLOW)) != 0; +#endif + /* Verify that all settings are valid before committing */ + + if (ret == OK) + { + /* Commit */ + + priv->baud = baud; + priv->parity = parity; + priv->bits = nbits; + priv->stopbits2 = stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flowc = flowc; +#endif + /* effect the changes immediately - note that we do not + * implement TCSADRAIN / TCSAFLUSH + */ + + up_disableallints(priv, &imr); + ret = up_setup(dev); + + /* Restore the interrupt state */ + + up_restoreusartint(priv, imr); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return the error information in the saved status */ + + *status = priv->sr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return (int)(up_serialin(priv, SAM_UART_RHR_OFFSET) & 0xff); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_RXRDY); +#endif + } + else + { + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_RXRDY); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_RXRDY) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART/USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, SAM_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_TXRDY); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + +#endif + } + else + { + /* Disable the TX interrupt */ + + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_TXRDY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXRDY) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* NOTE: All GPIO configuration for the USARTs was performed in + * sam_lowsetup + */ + + /* Disable all USARTS */ + + up_disableallints(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableallints(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + up_disableallints(TTYS2_DEV.priv, NULL); +#endif +#ifdef TTYS3_DEV + up_disableallints(TTYS3_DEV.priv, NULL); +#endif +#ifdef TTYS4_DEV + up_disableallints(TTYS4_DEV.priv, NULL); +#endif +#ifdef TTYS5_DEV + up_disableallints(TTYS5_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/sam34/sam_spi.c b/arch/arm/src/sam34/sam_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..424d9218449e6f8185d098442a54e03398f7c69c --- /dev/null +++ b/arch/arm/src/sam34/sam_spi.c @@ -0,0 +1,1931 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_spi.c + * + * Copyright (C) 2011, 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_gpio.h" +#include "sam_dmac.h" +#include "sam_cmcc.h" +#include "sam_periphclks.h" +#include "sam_spi.h" +#include "chip/sam_pmc.h" +#include "chip/sam_dmac.h" +#include "chip/sam_spi.h" +#include "chip/sam_pinmap.h" + +#if defined(CONFIG_SAM34_SPI0) || defined(CONFIG_SAM34_SPI1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* When SPI DMA is enabled, small DMA transfers will still be performed by + * polling logic. But we need a threshold value to determine what is small. + * That value is provided by CONFIG_SAM34_SPI_DMATHRESHOLD. + */ + +#ifndef CONFIG_SAM34_SPI_DMATHRESHOLD +# define CONFIG_SAM34_SPI_DMATHRESHOLD 4 +#endif + +#ifdef CONFIG_SAM34_SPI_DMA + +# if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_DMAC0) +# define SAM34_SPI0_DMA true +# else +# define SAM34_SPI0_DMA false +# endif + +# if defined(CONFIG_SAM34_SPI1) && defined(CONFIG_SAM34_DMAC1) +# define SAM34_SPI1_DMA true +# else +# define SAM34_SPI1_DMA false +# endif +#endif + +#ifndef CONFIG_SAM34_SPI_DMA +# undef CONFIG_SAM34_SPI_DMADEBUG +#endif + +/* Clocking *****************************************************************/ +/* Select MCU-specific settings + * + * For the SAM3U, SAM3A, SAM3X, SAM4E and SAM4S SPI is driven by the main + * clock. + * For the SAM4L, SPI is driven by CLK_SPI which is the PBB clock. + */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) || defined(CONFIG_ARCH_CHIP_SAM4S) || \ + defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_SPI_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# define SAM_SPI_CLOCK BOARD_PBB_FREQUENCY /* PBB frequency */ +#else +# error Unrecognized SAM architecture +#endif + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* Debug *******************************************************************/ +/* Check if SPI debut is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_SAM34_SPI_DMADEBUG +# undef CONFIG_SAM34_SPI_REGDEBUG +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAM34_SPI_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the one SPI chip select */ + +struct sam_spics_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + +#if defined(CONFIG_SAM34_SPI0) || defined(CONFIG_SAM34_SPI1) + uint8_t spino; /* SPI controller number (0 or 1) */ +#endif + uint8_t cs; /* Chip select number */ + +#ifdef CONFIG_SAM34_SPI_DMA + bool candma; /* DMA is supported */ + sem_t dmawait; /* Used to wait for DMA completion */ + WDOG_ID dmadog; /* Watchdog that handles DMA timeouts */ + int result; /* DMA result */ + DMA_HANDLE rxdma; /* SPI RX DMA handle */ + DMA_HANDLE txdma; /* SPI TX DMA handle */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAM34_SPI_DMADEBUG + struct sam_dmaregs_s rxdmaregs[DMA_NSAMPLES]; + struct sam_dmaregs_s txdmaregs[DMA_NSAMPLES]; +#endif +}; + +/* Type of board-specific SPI status function */ + +typedef void (*select_t)(enum spi_dev_e devid, bool selected); + +/* Chip select register offsetrs */ + +/* The overall state of one SPI controller */ + +struct sam_spidev_s +{ + uint32_t base; /* SPI controller register base address */ + sem_t spisem; /* Assures mutually exclusive access to SPI */ + select_t select; /* SPI select call-out */ + bool initialized; /* TRUE: Controller has been initialized */ +#ifdef CONFIG_SAM34_SPI_DMA + uint8_t rxintf; /* RX hardware interface number */ + uint8_t txintf; /* TX hardware interface number */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAM34_SPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addresslast; /* Last address */ + uint32_t valuelast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAM34_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, + uint32_t value, uint32_t address); +#else +# define spi_checkreg(spi,wr,value,address) (false) +#endif + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset); +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset); +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg); +#else +# define spi_dumpregs(spi,msg) +#endif + +static inline void spi_flush(struct sam_spidev_s *spi); +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics); + +/* DMA support */ + +#ifdef CONFIG_SAM34_SPI_DMA + +#ifdef CONFIG_SAM34_SPI_DMADEBUG +# define spi_rxdma_sample(s,i) sam_dmasample((s)->rxdma, &(s)->rxdmaregs[i]) +# define spi_txdma_sample(s,i) sam_dmasample((s)->txdma, &(s)->txdmaregs[i]) +static void spi_dma_sampleinit(struct sam_spics_s *spics); +static void spi_dma_sampledone(struct sam_spics_s *spics); + +#else +# define spi_rxdma_sample(s,i) +# define spi_txdma_sample(s,i) +# define spi_dma_sampleinit(s) +# define spi_dma_sampledone(s) + +#endif + +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result); +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t spi_regaddr(struct sam_spics_s *spics, + unsigned int offset); +#endif + +/* SPI methods */ + +static int spi_lock(struct spi_dev_s *dev, bool lock); +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch); +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, + const void *txbuffer, void *rxbuffer, size_t nwords); +#endif +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, + const void *buffer, size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps chip select numbers (0-3) to CSR register offsets */ + +static const uint8_t g_csroffset[4] = +{ + SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET, + SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET +}; + +#ifdef CONFIG_SAM34_SPI0 +/* SPI0 driver operations */ + +static const struct spi_ops_s g_spi0ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = sam_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi0dev = +{ + .base = SAM_SPI0_BASE, + .select = sam_spi0select, +#ifdef CONFIG_SAM34_SPI_DMA + .rxintf = DMACHAN_INTF_SPI0RX, + .txintf = DMACHAN_INTF_SPI0TX, +#endif +}; +#endif + +#ifdef CONFIG_SAM34_SPI1 +/* SPI1 driver operations */ + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi1dev = +{ + .base = SAM_SPI1_BASE, + .select = sam_spi1select, +#ifdef CONFIG_SAM34_SPI_DMA + .rxintf = DMACHAN_INTF_SPI1RX, + .txintf = DMACHAN_INTF_SPI1TX, +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == spi->wrlast && /* Same kind of access? */ + value == spi->valuelast && /* Same value? */ + address == spi->addresslast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + spi->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (spi->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", spi->ntimes); + } + + /* Save information about the new access */ + + spi->wrlast = wr; + spi->valuelast = value; + spi->addresslast = address; + spi->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAM34_SPI_REGDEBUG + if (spi_checkreg(spi, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + +#ifdef CONFIG_SAM34_SPI_REGDEBUG + if (spi_checkreg(spi, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * spi - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" MR:%08x SR:%08x IMR:%08x\n", + getreg32(spi->base + SAM_SPI_MR_OFFSET), + getreg32(spi->base + SAM_SPI_SR_OFFSET), + getreg32(spi->base + SAM_SPI_IMR_OFFSET)); + spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n", + getreg32(spi->base + SAM_SPI_CSR0_OFFSET), + getreg32(spi->base + SAM_SPI_CSR1_OFFSET), + getreg32(spi->base + SAM_SPI_CSR2_OFFSET), + getreg32(spi->base + SAM_SPI_CSR3_OFFSET)); + spivdbg(" WPCR:%08x WPSR:%08x\n", + getreg32(spi->base + SAM_SPI_WPCR_OFFSET), + getreg32(spi->base + SAM_SPI_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_device + * + * Description: + * Given a chip select instance, return a pointer to the parent SPI + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics) +{ +#if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_SPI1) + return spics->spino ? &g_spi1dev : &g_spi0dev; +#elif defined(CONFIG_SAM34_SPI0) + return &g_spi0dev; +#else + return &g_spi1dev; +#endif +} + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Make sure that there are now dangling SPI transfer in progress + * + * Input Parameters: + * spi - SPI controller state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_flush(struct sam_spidev_s *spi) +{ + /* Make sure the no TX activity is in progress... waiting if necessary */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TXEMPTY) == 0); + + /* Then make sure that there is no pending RX data .. reading as + * discarding as necessary. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) != 0) + { + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + } +} + +/**************************************************************************** + * Name: spi_cs2pcs + * + * Description: + * Map the chip select number to the bit-set PCS field used in the SPI + * registers. A chip select number is used for indexing and identifying + * chip selects. However, the chip select information is represented by + * a bit set in the SPI registers. This function maps those chip select + * numbers to the correct bit set: + * + * CS Returned Spec Effective + * No. PCS Value NPCS + * ---- -------- -------- -------- + * 0 0000 xxx0 1110 + * 1 0001 xx01 1101 + * 2 0011 x011 1011 + * 3 0111 0111 0111 + * + * Input Parameters: + * spics - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics) +{ + return ((uint32_t)1 << (spics->cs)) - 1; +} + +/**************************************************************************** + * Name: spi_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAM34_SPI_DMADEBUG) + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMADEBUG +static void spi_dma_sampleinit(struct sam_spics_s *spics) +{ + /* Put contents of register samples into a known state */ + + memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: spi_dma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMADEBUG +static void spi_dma_sampledone(struct sam_spics_s *spics) +{ + /* Sample the final registers */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL], + "TX: Initial Registers"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL], + "RX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_SETUP], + "TX: After DMA Setup"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_SETUP], + "RX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_START], + "TX: After DMA Start"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_START], + "RX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timed out, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_CALLBACK], + "TX: At DMA callback"); + + /* Register values at the end of the DMA */ + + if (spics->result == -ETIMEDOUT) + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_TIMEOUT], + "RX: At DMA timeout"); + } + else + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_CALLBACK], + "RX: At DMA callback"); + } + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER], + "TX: At End-of-Transfer"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER], + "RX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: spi_dmatimeout + * + * Description: + * The watchdog timeout setup when a has expired without completion of a + * DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_dmatimeout(int argc, uint32_t arg) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Sample DMA registers at the time of the timeout */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report timeout result, perhaps overwriting any failure reports from + * the TX callback. + */ + + spics->result = -ETIMEDOUT; + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_rxcallback + * + * Description: + * This callback function is invoked at the completion of the SPI RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select structure + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Sample DMA registers at the time of the callback */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report the result of the transfer only if the TX callback has not already + * reported an error. + */ + + if (spics->result == -EBUSY) + { + /* Save the result of the transfer if no error was previously reported */ + + spics->result = result; + } + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_txcallback + * + * Description: + * This callback function is invoked at the completion of the SPI TX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select structure + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + spi_txdma_sample(spics, DMA_CALLBACK); + + /* Do nothing on the TX callback unless an error is reported. This + * callback is not really important because the SPI exchange is not + * complete until the RX callback is received. + */ + + if (result != OK && spics->result == -EBUSY) + { + /* Save the result of the transfer if an error is reported */ + + spics->result = result; + } +} +#endif + +/**************************************************************************** + * Name: spi_regaddr + * + * Description: + * Return the address of an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMA +static inline uintptr_t spi_regaddr(struct sam_spics_s *spics, + unsigned int offset) +{ + struct sam_spidev_s *spi = spi_device(spics); + return spi->base + offset; +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(struct spi_dev_s *dev, bool lock) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&spi->spisem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&spi->spisem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_select + * + * Description: + * This function does not actually set the chip select line. Rather, it + * simply maps the device ID into a chip select number and retains that + * chip select number for later use. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + + /* Are we selecting or de-selecting the device? */ + + spivdbg("selected=%d\n", selected); + if (selected) + { + spivdbg("cs=%d\n", spics->cs); + + /* Before writing the TDR, the PCS field in the SPI_MR register must be set + * in order to select a slave. + */ + + regval = spi_getreg(spi, SAM_SPI_MR_OFFSET); + regval &= ~SPI_MR_PCS_MASK; + regval |= (spi_cs2pcs(spics) << SPI_MR_PCS_SHIFT); + spi_putreg(spi, regval, SAM_SPI_MR_OFFSET); + } + + /* Perform any board-specific chip select operations. PIO chip select + * pins may be programmed by the board specific logic in one of two + * different ways. First, the pins may be programmed as SPI peripherals. + * In that case, the pins are completely controlled by the SPI driver. + * The sam_spi[0|1]select methods still needs to be provided, but they + * may be only stubs. + * + * An alternative way to program the PIO chip select pins is as normal + * PIO outputs. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + */ + + spi->select(devid, selected); +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t actual; + uint32_t scbr; + uint32_t dlybs; + uint32_t dlybct; + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d frequency=%d\n", spics->cs, frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (spics->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return spics->actual; + } + + /* Configure SPI to a frequency as close as possible to the requested frequency. + * + * SPCK frequency = SPI_CLK / SCBR, or SCBR = SPI_CLK / frequency + */ + + scbr = SAM_SPI_CLOCK / frequency; + + if (scbr < 8) + { + scbr = 8; + } + else if (scbr > 254) + { + scbr = 254; + } + + scbr = (scbr + 1) & ~1; + + /* Save the new scbr value */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK); + regval |= scbr << SPI_CSR_SCBR_SHIFT; + + /* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the + * first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK + * transition is 1/2 the SPCK clock period. Otherwise, the following equations + * determine the delay: + * + * Delay Before SPCK = DLYBS / SPI_CLK + * + * For a 2uS delay + * + * DLYBS = SPI_CLK * 0.000002 = SPI_CLK / 500000 + */ + + dlybs = SAM_SPI_CLOCK / 500000; + regval |= dlybs << SPI_CSR_DLYBS_SHIFT; + + /* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay + * between two consecutive transfers with the same peripheral without removing + * the chip select. The delay is always inserted after each transfer and + * before removing the chip select if needed. + * + * Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK + * + * For a 5uS delay: + * + * DLYBCT = SPI_CLK * 0.000005 / 32 = SPI_CLK / 200000 / 32 + */ + + dlybct = SAM_SPI_CLOCK / 200000 / 32; + regval |= dlybct << SPI_CSR_DLYBCT_SHIFT; + spi_putreg(spi, regval, offset); + + /* Calculate the new actual frequency */ + + actual = SAM_SPI_CLOCK / scbr; + spivdbg("csr[offset=%02x]=%08x actual=%d\n", offset, regval, actual); + + /* Save the frequency setting */ + + spics->frequency = frequency; + spics->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d mode=%d\n", spics->cs, mode); + + /* Has the mode changed? */ + + if (mode != spics->mode) + { + /* Yes... Set the mode appropriately: + * + * SPI CPOL NCPHA + * MODE + * 0 0 1 + * 1 0 0 + * 2 1 1 + * 3 1 0 + */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; NCPHA=1 */ + regval |= SPI_CSR_NCPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; NCPHA=0 */ + break; + + case SPIDEV_MODE2: /* CPOL=1; NCPHA=1 */ + regval |= (SPI_CSR_CPOL | SPI_CSR_NCPHA); + break; + + case SPIDEV_MODE3: /* CPOL=1; NCPHA=0 */ + regval |= SPI_CSR_CPOL; + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(spi, regval, offset); + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + spics->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d nbits=%d\n", spics->cs, nbits); + DEBUGASSERT(spics && nbits > 7 && nbits < 17); + + /* Has the number of bits changed? */ + + if (nbits != spics->nbits) + { + /* Yes... Set number of bits appropriately */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~SPI_CSR_BITS_MASK; + regval |= SPI_CSR_BITS(nbits); + spi_putreg(spi, regval, offset); + + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + spics->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd) +{ + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange can do this. Note: right now, this only deals with 8-bit + * words. If the SPI interface were configured for words of other sizes, + * this would fail. + */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange(dev, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; +} + +/**************************************************************************** + * Name: spi_exchange (and spi_exchange_nodma) + * + * Description: + * Exchange a block of data from SPI. There are two versions of this + * function: (1) One that is enabled only when CONFIG_SAM34_SPI_DMA=y + * that performs DMA SPI transfers, but only when a larger block of + * data is being transferred. And (2) another version that does polled + * SPI transfers. When CONFIG_SAM34_SPI_DMA=n the latter is the only + * version avaialable; when CONFIG_SAM34_SPI_DMA=y, this version is only + * used for short SPI transfers and gets renamed as spi_exchange_nodma). + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#else +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#endif +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t pcs; + uint32_t data; + uint16_t *rxptr16; + uint16_t *txptr16; + uint8_t *rxptr8; + uint8_t *txptr8; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Set up PCS bits */ + + pcs = spi_cs2pcs(spics) << SPI_TDR_PCS_SHIFT; + + /* Set up working pointers */ + + if (spics->nbits > 8) + { + rxptr16 = (uint16_t *)rxbuffer; + txptr16 = (uint16_t *)txbuffer; + rxptr8 = NULL; + txptr8 = NULL; + } + else + { + rxptr16 = NULL; + txptr16 = NULL; + rxptr8 = (uint8_t *)rxbuffer; + txptr8 = (uint8_t *)txbuffer; + } + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Loop, sending each word in the user-provided data buffer. + * + * Note 1: Good SPI performance would require that we implement DMA + * transfers! + * Note 2: This loop might be made more efficient. Would logic + * like the following improve the throughput? Or would it + * just add the risk of overruns? + * + * Get word 1; + * Send word 1; Now word 1 is "in flight" + * nwords--; + * for ( ; nwords > 0; nwords--) + * { + * Get word N. + * Wait for TDRE meaning that word N-1 has moved to the shift + * register. + * Disable interrupts to keep the following atomic + * Send word N. Now both work N-1 and N are "in flight" + * Wait for RDRF meaning that word N-1 is available + * Read word N-1. + * Re-enable interrupts. + * Save word N-1. + * } + * Wait for RDRF meaning that the final word is available + * Read the final word. + * Save the final word. + */ + + for (; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source). */ + + if (txptr8) + { + data = (uint32_t)*txptr8++; + } + else if (txptr16) + { + data = (uint32_t)*txptr16++; + } + else + { + data = 0xffff; + } + + /* Set the PCS field in the value written to the TDR */ + + data |= pcs; + + /* Do we need to set the LASTXFER bit in the TDR value too? */ + +#ifdef CONFIG_SPI_VARSELECT + if (nwords == 1) + { + data |= SPI_TDR_LASTXFER; + } +#endif + + /* Wait for any previous data written to the TDR to be transferred + * to the serializer. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TDRE) == 0); + + /* Write the data to transmitted to the Transmit Data Register (TDR) */ + + spi_putreg(spi, data, SAM_SPI_TDR_OFFSET); + + /* Wait for the read data to be available in the RDR. + * TODO: Data transfer rates would be improved using the RX FIFO + * (and also DMA) + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) == 0); + + /* Read the received data from the SPI Data Register. */ + + data = spi_getreg(spi, SAM_SPI_RDR_OFFSET); + if (rxptr8) + { + *rxptr8++ = (uint8_t)data; + } + else if (rxptr16) + { + *rxptr16++ = (uint16_t)data; + } + } +} + +#ifdef CONFIG_SAM34_SPI_DMA +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t rxflags; + uint32_t txflags; + uint32_t txdummy; + uint32_t rxdummy; + uint32_t regaddr; + uint32_t memaddr; + uint32_t width; + size_t nbytes; + int ret; + + /* Convert the number of word to a number of bytes */ + + nbytes = (spics->nbits > 8) ? nwords << 1 : nwords; + + /* If we cannot do DMA -OR- if this is a small SPI transfer, then let + * spi_exchange_nodma() do the work. + */ + + if (!spics->candma || nbytes <= CONFIG_SAM34_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + spics = (struct sam_spics_s *)dev; + spi = spi_device(spics); + DEBUGASSERT(spics && spi); + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Sample initial DMA registers */ + + spi_dma_sampleinit(spics); + + /* Select the source and destination width bits */ + + if (spics->nbits > 8) + { + width = (DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_MEMWIDTH_16BITS); + } + else + { + width = (DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_MEMWIDTH_8BITS); + } + + /* Configure the DMA channels. There are four different cases: + * + * 1) A true exchange with the memory address incrementing on both + * RX and TX channels, + * 2) A read operation with the memory address incrementing only on + * the receive channel, + * 3) A write operation where the memory address increments only on + * the receive channel, and + * 4) A corner case where there the memory address does not increment + * on either channel. This case might be used in certain cases + * where you want to assure that certain number of clocks are + * provided on the SPI bus. + */ + + /* Configure the RX DMA channel */ + + rxflags = DMACH_FLAG_FIFOCFG_LARGEST | + ((uint32_t)spi->rxintf << DMACH_FLAG_PERIPHPID_SHIFT) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | + ((uint32_t)(15) << DMACH_FLAG_MEMPID_SHIFT) | + DMACH_FLAG_MEMCHUNKSIZE_1; + + /* Set the source and destination width bits */ + + rxflags |= width; + + /* Handle the case where there is no sink buffer */ + + if (!rxbuffer) + { + /* No sink data buffer. Point to our dummy buffer and leave + * the rxflags so that no address increment is performed. + */ + + rxbuffer = (void *)&rxdummy; + } + else + { + /* A receive buffer is available. + * + * Invalidate the RX buffer memory to force re-fetching from RAM when + * the DMA completes + */ + + sam_cmcc_invalidate((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes); + + /* Use normal RX memory incrementing. */ + + rxflags |= DMACH_FLAG_MEMINCREMENT; + } + + /* Configure the TX DMA channel */ + + txflags = DMACH_FLAG_FIFOCFG_LARGEST | + ((uint32_t)spi->txintf << DMACH_FLAG_PERIPHPID_SHIFT) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | + ((uint32_t)(15) << DMACH_FLAG_MEMPID_SHIFT) | + DMACH_FLAG_MEMCHUNKSIZE_1; + + /* Set the source and destination width bits */ + + txflags |= width; + + /* Handle the case where there is no source buffer */ + + if (!txbuffer) + { + /* No source data buffer. Point to our dummy buffer and leave + * the txflags so that no address increment is performed. + */ + + txdummy = 0xffffffff; + txbuffer = (const void *)&txdummy; + } + else + { + /* Source data is available. Use normal TX memory incrementing. */ + + txflags |= DMACH_FLAG_MEMINCREMENT; + } + + /* Then configure the DMA channels to make it so */ + + sam_dmaconfig(spics->rxdma, rxflags); + sam_dmaconfig(spics->txdma, txflags); + + /* Configure the RX side of the exchange transfer */ + + regaddr = spi_regaddr(spics, SAM_SPI_RDR_OFFSET); + memaddr = (uintptr_t)rxbuffer; + + ret = sam_dmarxsetup(spics->rxdma, regaddr, memaddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmarxsetup failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_SETUP); + + /* Configure the TX side of the exchange transfer */ + + regaddr = spi_regaddr(spics, SAM_SPI_TDR_OFFSET); + memaddr = (uintptr_t)txbuffer; + + ret = sam_dmatxsetup(spics->txdma, regaddr, memaddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmatxsetup failed: %d\n", ret); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_SETUP); + + /* Start the DMA transfer */ + + spics->result = -EBUSY; + ret = sam_dmastart(spics->rxdma, spi_rxcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_START); + + ret = sam_dmastart(spics->txdma, spi_txcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + sam_dmastop(spics->rxdma); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_START); + + /* Wait for DMA completion. This is done in a loop because there may be + * false alarm semaphore counts that cause sam_wait() not fail to wait + * or to wake-up prematurely (for example due to the receipt of a signal). + * We know that the DMA has completed when the result is anything other + * that -EBUSY. + */ + + do + { + /* Start (or re-start) the watchdog timeout */ + + ret = wd_start(spics->dmadog, DMA_TIMEOUT_TICKS, + (wdentry_t)spi_dmatimeout, 1, (uint32_t)spics); + if (ret != OK) + { + spidbg("ERROR: wd_start failed: %d\n", ret); + } + + /* Wait for the DMA complete */ + + ret = sem_wait(&spics->dmawait); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Check if we were awakened by an error of some kind */ + + if (ret < 0) + { + /* EINTR is not a failure. That simply means that the wait + * was awakened by a signal. + */ + + int errorcode = errno; + if (errorcode != EINTR) + { + DEBUGPANIC(); + return; + } + } + + /* Not that we might be awakened before the wait is over due to + * residual counts on the semaphore. So, to handle, that case, + * we loop until something changes the DMA result to any value other + * than -EBUSY. + */ + } + while (spics->result == -EBUSY); + + /* Dump the sampled DMA registers */ + + spi_dma_sampledone(spics); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + sam_dmastop(spics->rxdma); + sam_dmastop(spics->txdma); + + /* All we can do is complain if the DMA fails */ + + if (spics->result) + { + spidbg("ERROR: DMA failed with result: %d\n", spics->result); + } +} +#endif /* CONFIG_SAM34_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, + size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port) +{ + struct sam_spidev_s *spi; + struct sam_spics_s *spics; + int csno = (port & __SPI_CS_MASK) >> __SPI_CS_SHIFT; + int spino = (port & __SPI_SPI_MASK) >> __SPI_SPI_SHIFT; + irqstate_t flags; + uint32_t regval; + unsigned int offset; + + /* The support SAM parts have only a single SPI port */ + + spivdbg("port: %d csno: %d spino: %d\n", port, csno, spino); + DEBUGASSERT(csno >= 0 && csno <= SAM_SPI_NCS); + +#if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_SPI1) + DEBUGASSERT(spino >= 0 && spino <= 1); +#elif defined(CONFIG_SAM34_SPI0) + DEBUGASSERT(spino == 0); +#else + DEBUGASSERT(spino == 1); +#endif + + /* Allocate a new state structure for this chip select. NOTE that there + * is no protection if the same chip select is used in two different + * chip select structures. + */ + + spics = (struct sam_spics_s *)zalloc(sizeof(struct sam_spics_s)); + if (!spics) + { + spidbg("ERROR: Failed to allocate a chip select structure\n"); + return NULL; + } + + /* Set up the initial state for this chip select structure. Other fields + * were zeroed by zalloc(). + */ + +#ifdef CONFIG_SAM34_SPI_DMA + /* Can we do DMA on this peripheral? */ + + spics->candma = spino ? SAM34_SPI1_DMA : SAM34_SPI0_DMA; + + /* Pre-allocate DMA channels. These allocations exploit that fact that + * SPI0 is managed by DMAC0 and SPI1 is managed by DMAC1. Hence, + * the SPI number (spino) is the same as the DMAC number. + */ + + if (spics->candma) + { + spics->rxdma = sam_dmachannel(0); + if (!spics->rxdma) + { + spidbg("ERROR: Failed to allocate the RX DMA channel\n"); + spics->candma = false; + } + } + + if (spics->candma) + { + spics->txdma = sam_dmachannel(0); + if (!spics->txdma) + { + spidbg("ERROR: Failed to allocate the TX DMA channel\n"); + sam_dmafree(spics->rxdma); + spics->rxdma = NULL; + spics->candma = false; + } + } +#endif + + /* Select the SPI operations */ + +#if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_SPI1) + spics->spidev.ops = spino ? &g_spi1ops : &g_spi0ops; +#elif defined(CONFIG_SAM34_SPI0) + spics->spidev.ops = &g_spi0ops; +#else + spics->spidev.ops = &g_spi1ops; +#endif + + /* Save the chip select and SPI controller numbers */ + + spics->cs = csno; +#if defined(CONFIG_SAM34_SPI0) || defined(CONFIG_SAM34_SPI1) + spics->spino = spino; +#endif + + /* Get the SPI device structure associated with the chip select */ + + spi = spi_device(spics); + + /* Has the SPI hardware been initialized? */ + + if (!spi->initialized) + { + /* Enable clocking to the SPI block */ + + flags = enter_critical_section(); +#if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_SPI1) + if (spino == 0) +#endif +#if defined(CONFIG_SAM34_SPI0) + { + sam_spi0_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configgpio(GPIO_SPI0_MISO); + sam_configgpio(GPIO_SPI0_MOSI); + sam_configgpio(GPIO_SPI0_SPCK); + } +#endif +#if defined(CONFIG_SAM34_SPI0) && defined(CONFIG_SAM34_SPI1) + else +#endif +#if defined(CONFIG_SAM34_SPI1) + { + sam_spi1_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configgpio(GPIO_SPI1_MISO); + sam_configgpio(GPIO_SPI1_MOSI); + sam_configgpio(GPIO_SPI1_SPCK); + } +#endif + + /* Disable SPI clocking */ + + spi_putreg(spi, SPI_CR_SPIDIS, SAM_SPI_CR_OFFSET); + + /* Execute a software reset of the SPI (twice) */ + + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + leave_critical_section(flags); + + /* Configure the SPI mode register */ + + spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS, SAM_SPI_MR_OFFSET); + + /* And enable the SPI */ + + spi_putreg(spi, SPI_CR_SPIEN, SAM_SPI_CR_OFFSET); + up_mdelay(20); + + /* Flush any pending transfers */ + + (void)spi_getreg(spi, SAM_SPI_SR_OFFSET); + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + + /* Initialize the SPI semaphore that enforces mutually exclusive + * access to the SPI registers. + */ + + sem_init(&spi->spisem, 0, 1); + spi->initialized = true; + +#ifdef CONFIG_SAM34_SPI_DMA + /* Initialize the SPI semaphore that is used to wake up the waiting + * thread when the DMA transfer completes. + */ + + sem_init(&spics->dmawait, 0, 0); + + /* Create a watchdog time to catch DMA timeouts */ + + spics->dmadog = wd_create(); + DEBUGASSERT(spics->dmadog); +#endif + + spi_dumpregs(spi, "After initialization"); + } + + /* Set to mode=0 and nbits=8 and impossible frequency. The SPI will only + * be reconfigured if there is a change. + */ + + offset = (unsigned int)g_csroffset[csno]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK); + regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8)); + spi_putreg(spi, regval, offset); + + spics->nbits = 8; + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + return &spics->spidev; +} +#endif /* CONFIG_SAM34_SPI0 || CONFIG_SAM34_SPI1 */ diff --git a/arch/arm/src/sam34/sam_spi.h b/arch/arm/src/sam34/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..1d37d340d4e3edc78456394bc00754e176519df9 --- /dev/null +++ b/arch/arm/src/sam34/sam_spi.h @@ -0,0 +1,259 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_spi.h + * + * Copyright (C) 2009-2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_SPI_H +#define __ARCH_ARM_SRC_SAM34_SAM_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "chip/sam_spi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The SPI port number used as an input to sam_spibus_initialize encodes + * information about the SPI controller (0 or 1) and the SPI chip select + * (0-3). + * + * NOTE that this is this is backward compatible with older implementations + * that support only SPI0 and provide only the chip select number to + * sam_spibus_initialize(). + */ + +#define __SPI_CS_SHIFT (0) /* Bits 0-1: SPI chip select number */ +#define __SPI_CS_MASK (3 << __SPI_CS_SHIFT) +# define __SPI_CS0 (0 << __SPI_CS_SHIFT) +# define __SPI_CS1 (1 << __SPI_CS_SHIFT) +# define __SPI_CS2 (2 << __SPI_CS_SHIFT) +# define __SPI_CS3 (3 << __SPI_CS_SHIFT) +#define __SPI_SPI_SHIFT (2) /* Bit 2: SPI controller number */ +#define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT) +# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */ +# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */ + +#define SPI0_CS0 (__SPI_SPI0 | __SPI_CS0) +#define SPI0_CS1 (__SPI_SPI0 | __SPI_CS1) +#define SPI0_CS2 (__SPI_SPI0 | __SPI_CS2) +#define SPI0_CS3 (__SPI_SPI0 | __SPI_CS3) + +#define SPI1_CS0 (__SPI_SPI1 | __SPI_CS0) +#define SPI1_CS1 (__SPI_SPI1 | __SPI_CS1) +#define SPI1_CS2 (__SPI_SPI1 | __SPI_CS2) +#define SPI1_CS3 (__SPI_SPI1 | __SPI_CS3) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port); + +/**************************************************************************** + * Name: sam_spi[0|1]select, sam_spi[0|1]status, and sam_spi[0|1]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. + * They include: + * + * o sam_spi[0|1]select is a functions tomanage the board-specific chip + * selects + * o sam_spi[0|1]status and sam_spi[0|1]cmddata: Implementations of the + * status and cmddata methods of the SPI interface defined by struct + * spi_ops_ (see include/nuttx/spi/spi.h). All other methods including + * sam_spibus_initialize()) are provided by common SAM3/4 logic. + * + * To use this common SPI logic on your board: + * + * 1. Provide logic in sam_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in + * our board-specific logic. These functions will perform chip selection + * and status operations using PIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * sam_spi[0|1]cmddata() functions in your board-specific logic. This + * function will perform cmd/data selection operations using PIOs in + * the way your board is configured. + * 3. Add a call to sam_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by sam_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spi[0|1]select + * + * Description: + * PIO chip select pins may be programmed by the board specific logic in + * one of two different ways. First, the pins may be programmed as SPI + * peripherals. In that case, the pins are completely controlled by the + * SPI driver. This method still needs to be provided, but it may be only + * a stub. + * + * An alternative way to program the PIO chip select pins is as a normal + * PIO output. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * selected - TRUE:Select the device, FALSE:De-select the device + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI0 +void sam_spi0select(enum spi_dev_e devid, bool selected); +#endif +#ifdef CONFIG_SAM34_SPI1 +void sam_spi1select(enum spi_dev_e devid, bool selected); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]status + * + * Description: + * Return status information associated with the SPI device. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Bit-encoded SPI status (see include/nuttx/spi/spi.h. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_SPI0 +uint8_t sam_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif +#ifdef CONFIG_SAM34_SPI1 +uint8_t sam_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]cmddata + * + * Description: + * Some SPI devices require an additional control to determine if the SPI + * data being sent is a command or is data. If CONFIG_SPI_CMDDATA then + * this function will be called to different be command and data transfers. + * + * This is often needed, for example, by LCD drivers. Some LCD hardware + * may be configured to use 9-bit data transfers with the 9th bit + * indicating command or data. That same hardware may be configurable, + * instead, to use 8-bit data but to require an additional, board- + * specific PIO control to distinguish command and data. This function + * would be needed in that latter case. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Zero on success; a negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_SAM34_SPI0 +int sam_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#ifdef CONFIG_SAM34_SPI1 +int sam_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_SPI_H */ diff --git a/arch/arm/src/sam34/sam_start.c b/arch/arm/src/sam34/sam_start.c new file mode 100644 index 0000000000000000000000000000000000000000..dc1d449808ab653ad2d43a1d5730a745c740451b --- /dev/null +++ b/arch/arm/src/sam34/sam_start.c @@ -0,0 +1,344 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_start.c + * + * Copyright (C) 2009-2010, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_clockconfig.h" +#include "sam_lowputc.h" +#include "sam_cmcc.h" +#include "sam_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void sam_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* We need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Name: sam_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void sam_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void sam_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define sam_fpuconfig() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is geive by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initalization code + * at _framfuncs. This must be done before sam_clockconfig() can be + * called (at least for the SAM4L family). + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + sam_clockconfig(); + sam_fpuconfig(); + sam_lowsetup(); + showprogress('A'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('B'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segements. + */ + +#ifdef CONFIG_BUILD_PROTECTED + sam_userspace(); + showprogress('C'); +#endif + + /* Initialize onboard resources */ + + sam_boardinitialize(); + showprogress('D'); + +#ifdef CONFIG_SAM34_CMCC + /* Enable the Cortex-M Cache + * + * REVISIT: This logic is complete but I have not yet tried to enable it. + * I have some questions about how the cache will effect memory mapped + * register accesses. + */ + + sam_cmcc_enable(); +#endif + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); + +#else + /* Call os_start() */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/sam34/sam_tc.c b/arch/arm/src/sam34/sam_tc.c new file mode 100644 index 0000000000000000000000000000000000000000..a95fa495273d1f392a2491705ea48ec45f254790 --- /dev/null +++ b/arch/arm/src/sam34/sam_tc.c @@ -0,0 +1,674 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_tc.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Dioron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_tc.h" +#include "sam_periphclks.h" + +#if defined(CONFIG_TIMER) && (defined(CONFIG_SAM34_TC0) || \ + defined(CONFIG_SAM34_TC1) || defined(CONFIG_SAM34_TC2) || \ + defined(CONFIG_SAM34_TC3) || defined(CONFIG_SAM34_TC4) || \ + defined(CONFIG_SAM34_TC5)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Clocking *****************************************************************/ + +/* TODO: Allow selection of any of the input clocks */ + +#define TC_FCLK (BOARD_SCLK_FREQUENCY) +#define TC_MAXTIMEOUT ((1000000ULL * (1ULL + TC_RVALUE_MASK)) / TC_FCLK) + +/* Configuration ************************************************************/ + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the timer + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_TIMER +# define tcdbg lldbg +# define tcvdbg llvdbg +#else +# define tcdbg(x...) +# define tcvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct sam34_lowerhalf_s +{ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + + /* Private data */ + + uint32_t base; /* Base address of the timer */ + tccb_t handler; /* Current user interrupt handler */ + uint32_t timeout; /* The current timeout value (us) */ + uint32_t adjustment; /* time lost due to clock resolution truncation (us) */ + uint32_t clkticks; /* actual clock ticks for current interval */ + bool started; /* The timer has been started */ + uint16_t periphid; /* peripheral id */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAM34_TC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr); +static void sam34_putreg(uint32_t val, uint32_t addr); +#else +# define sam34_getreg(addr) getreg32(addr) +# define sam34_putreg(val,addr) putreg32(val,addr) +#endif + +/* Interrupt handling *******************************************************/ + +static int sam34_interrupt(int irq, FAR void *context); + +/* "Lower half" driver methods **********************************************/ + +static int sam34_start(FAR struct timer_lowerhalf_s *lower); +static int sam34_stop(FAR struct timer_lowerhalf_s *lower); +static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status); +static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout); +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler); +static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_tcops = +{ + .start = sam34_start, + .stop = sam34_stop, + .getstatus = sam34_getstatus, + .settimeout = sam34_settimeout, + .sethandler = sam34_sethandler, + .ioctl = sam34_ioctl, +}; + +/* "Lower half" driver state */ + +/* TODO - allocating all 6 now, even though we might not need them. + * May want to allocate the right number to not be wasteful. + */ + +static struct sam34_lowerhalf_s g_tcdevs[6]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam34_getreg + * + * Description: + * Get the contents of a register + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_TC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08lx->%08lx\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: sam34_putreg + * + * Description: + * Set the contents of an SAM34 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_TC_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam34_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08lx<-%08lx\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: sam34_interrupt + * + * Description: + * TC interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +static int sam34_interrupt(int irq, FAR void *context) +{ + FAR struct sam34_lowerhalf_s *priv = &g_tcdevs[irq-SAM_IRQ_TC0]; + + tcvdbg("Entry\n"); + DEBUGASSERT((irq >= SAM_IRQ_TC0) && (irq <= SAM_IRQ_TC5)); + + /* Check if the interrupt is really pending */ + + if ((sam34_getreg(priv->base + SAM_TC_SR_OFFSET) & TC_INT_CPCS) != 0) + { + uint32_t timeout; + + /* Is there a registered handler? If the handler has been nullified, + * the timer will be stopped. + */ + + if (priv->handler && priv->handler(&priv->timeout)) + { + /* Calculate new ticks / dither adjustment */ + + priv->clkticks = ((uint64_t)(priv->adjustment + priv->timeout))*TC_FCLK / 1000000; + + /* Set next interval interval. TODO: make sure the interval is not so soon it will be missed! */ + + sam34_putreg(priv->clkticks, priv->base + SAM_TC_RC_OFFSET); + + timeout = (1000000ULL * priv->clkticks) / TC_FCLK; /* trucated timeout */ + priv->adjustment = (priv->adjustment + priv->timeout) - timeout; /* truncated time to be added to next interval (dither) */ + } + else + { + /* No handler or the handler returned false.. stop the timer */ + + sam34_stop((FAR struct timer_lowerhalf_s *)priv); + tcvdbg("Stopped\n"); + } + + /* TC_INT_CPCS is cleared by reading SAM_TCx_SR */ + } + + return OK; +} + +/**************************************************************************** + * Name: sam34_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_start(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t mr_val; + + tcvdbg("Entry\n"); + DEBUGASSERT(priv); + + if (priv->started) + { + return -EINVAL; + } + + sam_enableperiph0(priv->periphid); /* Enable peripheral clock */ + sam34_putreg(TC_CCR_CLKDIS, priv->base + SAM_TC_CCR_OFFSET); /* Disable counter */ + sam34_putreg(0, priv->base + SAM_TC_CV_OFFSET); /* clear counter */ + + /* TC_CMR_WAVE - waveform mode + * TC_CMR_WAVSEL_UPAUTO - reset on RC compare (interval timer) + * TC_CMR_TCCLKS_TIMERCLOCK5 = SCLK + */ + + mr_val = (TC_CMR_WAVE + TC_CMR_WAVSEL_UPAUTO + TC_CMR_TCCLKS_TIMERCLOCK5); + sam34_putreg(mr_val, priv->base + SAM_TC_CMR_OFFSET); + + sam34_putreg(priv->clkticks, priv->base + SAM_TC_RC_OFFSET); /* Set interval */ + + if (priv->handler) + { + /* Clear status and enable interrupt */ + + sam34_getreg(priv->base + SAM_TC_SR_OFFSET); /* Clear status */ + sam34_putreg(TC_INT_CPCS, priv->base + SAM_TC_IER_OFFSET); /* Enable interrupt */ + } + + sam34_putreg(TC_CCR_SWTRG + TC_CCR_CLKEN, priv->base + SAM_TC_CCR_OFFSET); /* Start counter */ + + priv->started = true; + return OK; +} + +/**************************************************************************** + * Name: sam34_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_stop(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + tcvdbg("Entry\n"); + DEBUGASSERT(priv); + + if (!priv->started) + { + return -EINVAL; + } + + sam34_putreg(TC_CCR_CLKDIS, priv->base + SAM_TC_CCR_OFFSET); /* Disable counter */ + sam34_putreg(TC_INT_ALL, priv->base + SAM_TC_IDR_OFFSET); /* Disable all ints */ + sam_disableperiph0(priv->periphid); /* Disable peripheral clock */ + + priv->started = false; + + return OK; +} + +/**************************************************************************** + * Name: sam34_getstatus + * + * Description: + * Get the current timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t elapsed; + + tcvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = 0; + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->handler) + { + status->flags |= TCFLAGS_HANDLER; + } + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the timer expires (in microseconds) */ + + elapsed = sam34_getreg(priv->base + SAM_TC_CV_OFFSET); + status->timeleft = ((uint64_t)priv->timeout * elapsed) / (priv->clkticks + 1); /* TODO - check on this +1 */ + + tcvdbg(" flags : %08x\n", status->flags); + tcvdbg(" timeout : %d\n", status->timeout); + tcvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam34_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in milliseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + + DEBUGASSERT(priv); + + if (priv->started) + { + return -EPERM; + } + + tcvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > TC_MAXTIMEOUT) + { + tcdbg("Cannot represent timeout=%lu > %lu\n", + timeout, TC_MAXTIMEOUT); + return -ERANGE; + } + + priv->timeout = timeout; /* Intended timeout */ + priv->clkticks = (((uint64_t)timeout * TC_FCLK) / 1000000); /* Actual clock ticks */ + timeout = (1000000ULL * priv->clkticks) / TC_FCLK; /* Truncated timeout */ + priv->adjustment = priv->timeout - timeout; /* Truncated time to be added to next interval (dither) */ + + tcvdbg("fclk=%d clkticks=%d timout=%d, adjustment=%d\n", + TC_FCLK, priv->clkticks, priv->timeout, priv->adjustment); + + return OK; +} + +/**************************************************************************** + * Name: sam34_sethandler + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + irqstate_t flags; + tccb_t oldhandler; + + flags = enter_critical_section(); + + DEBUGASSERT(priv); + tcvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + leave_critical_section(flags); + return oldhandler; +} + +/**************************************************************************** + * Name: sam34_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctl command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + int ret = -ENOTTY; + + DEBUGASSERT(priv); + tcvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg); + UNUSED(priv); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tcinitialize + * + * Description: + * Initialize the timer. The timer is initialized and + * registers as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the timer. This should be of the form + * /dev/tc0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sam_tcinitialize(FAR const char *devpath, int irq) +{ + FAR struct sam34_lowerhalf_s *priv = &g_tcdevs[irq-SAM_IRQ_TC0]; + + tcvdbg("Entry: devpath=%s\n", devpath); + DEBUGASSERT((irq >= SAM_IRQ_TC0) && (irq <= SAM_IRQ_TC5)); + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + switch (irq) + { +#if defined(CONFIG_SAM34_TC0) + case SAM_IRQ_TC0: + priv->base = SAM_TC0_BASE; + priv->periphid = SAM_PID_TC0; + break; +#endif + +#if defined(CONFIG_SAM34_TC1) + case SAM_IRQ_TC1: + priv->base = SAM_TC1_BASE; + priv->periphid = SAM_PID_TC1; + break; +#endif + +#if defined(CONFIG_SAM34_TC2) + case SAM_IRQ_TC2: + priv->base = SAM_TC2_BASE; + priv->periphid = SAM_PID_TC2; + break; +#endif + +#if defined(CONFIG_SAM34_TC3) + case SAM_IRQ_TC3: + priv->base = SAM_TC3_BASE; + priv->periphid = SAM_PID_TC3; + break; +#endif + +#if defined(CONFIG_SAM34_TC4) + case SAM_IRQ_TC4: + priv->base = SAM_TC4_BASE; + priv->periphid = SAM_PID_TC4; + break; +#endif + +#if defined(CONFIG_SAM34_TC5) + case SAM_IRQ_TC5: + priv->base = SAM_TC5_BASE; + priv->periphid = SAM_PID_TC5; + break; +#endif + + default: + ASSERT(0); + } + + priv->ops = &g_tcops; + + (void)irq_attach(irq, sam34_interrupt); + + /* Enable NVIC interrupt. */ + + up_enable_irq(irq); + + /* Register the timer driver as /dev/timerX */ + + (void)timer_register(devpath, (FAR struct timer_lowerhalf_s *)priv); +} + +#endif /* CONFIG_TIMER && CONFIG_SAM34_TCx */ diff --git a/arch/arm/src/sam34/sam_tc.h b/arch/arm/src/sam34/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..df7b3caf29011e8e006039bcd58965744577ae79 --- /dev/null +++ b/arch/arm/src/sam34/sam_tc.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_tc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_TC_H +#define __ARCH_ARM_SRC_SAM34_TC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_tc.h" + +#ifdef CONFIG_TIMER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tcinitialize + * + * Description: + * Initialize the timer. The timer is initialized and + * registers as 'devpath. The initial state of the timer is + * disabled. + * + * Input Parameters: + * devpath - The full path to the timer. This should be of the form + * /dev/tc0 + * irq - irq associated with the timer + * Returned Values: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_TC0) || defined(CONFIG_SAM34_TC1) || \ + defined(CONFIG_SAM34_TC2) || defined(CONFIG_SAM34_TC3) || \ + defined(CONFIG_SAM34_TC4) || defined(CONFIG_SAM34_TC5) +void sam_tcinitialize(FAR const char *devpath, int irq); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_TIMER */ +#endif /* __ARCH_ARM_SRC_SAM34_TC_H */ diff --git a/arch/arm/src/sam34/sam_timerisr.c b/arch/arm/src/sam34/sam_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..6ebdc2ffd4c09393ebffb23647f88d16e685b576 --- /dev/null +++ b/arch/arm/src/sam34/sam_timerisr.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_timerisr.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Select MCU-specific settings + * + * For the SAM3U, SAM3A, and SAM3X, Systick is driven by the main clock + * (This could be the MCK/8 but that option has not yet been necessary). + * For the SAM4L, SAM4S, and SAM4E, Systick is driven by the CPU clock which + * is just the main clock divided down. + */ + +#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \ + defined(CONFIG_ARCH_CHIP_SAM3A) +# define SAM_SYSTICK_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ +#elif defined(CONFIG_ARCH_CHIP_SAM4L) || defined(CONFIG_ARCH_CHIP_SAM4CM) || \ + defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) +# define SAM_SYSTICK_CLOCK BOARD_CPU_FREQUENCY /* CPU frequency */ +#else +# error Unrecognized SAM architecture +#endif + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The SAM3U feeds the Cortex System Timer (SysTick) with the MCK clock or + * the MCK clock divided by 8, configurable with the CLKSOURCE bit in the + * SysTick Control and Status register. + */ + +#undef CONFIG_SAM34_SYSTICK_HCLKd8 /* Power up default is MCK, not MCK/8 */ + +#ifdef CONFIG_SAM34_SYSTICK_HCLKd8 +# define SYSTICK_RELOAD ((SAM_SYSTICK_CLOCK / 8 / CLK_TCK) - 1) +#else +# define SYSTICK_RELOAD ((SAM_SYSTICK_CLOCK / CLK_TCK) - 1) +#endif + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set correctly */ + +#if 0 /* Does not work. Comes up with HCLK source and I can't change it */ + regval = getreg32(NVIC_SYSTICK_CTRL); +#ifdef CONFIG_SAM34_SYSTICK_HCLKd8 + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + putreg32(0, NVIC_SYSTICK_CURRENT); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(SAM_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(SAM_IRQ_SYSTICK); +} diff --git a/arch/arm/src/sam34/sam_twi.c b/arch/arm/src/sam34/sam_twi.c new file mode 100644 index 0000000000000000000000000000000000000000..a71525b62762288e761e9a34f1ff37259335ed25 --- /dev/null +++ b/arch/arm/src/sam34/sam_twi.c @@ -0,0 +1,1053 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_twi.c + * + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA34 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/sam_pmc.h" +#include "chip/sam_pinmap.h" + +#include "sam_periphclks.h" +#include "sam_gpio.h" +#include "sam_twi.h" + +#if defined(CONFIG_SAM34_TWI0) || defined(CONFIG_SAM34_TWI1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_SAM34_TWI0_FREQUENCY +# define CONFIG_SAM34_TWI0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAM34_TWI1_FREQUENCY +# define CONFIG_SAM34_TWI1_FREQUENCY 100000 +#endif + +/* Driver internal definitions *************************************************/ + +#define TWI_TIMEOUT ((100 * CLK_TCK) / 1000) /* 100 mS */ + +/* Clocking to the TWO module(s) is provided by the main clocked, divided down + * as necessary. + */ + +#define TWI_MAX_FREQUENCY 66000000 /* Maximum TWI frequency */ + +/* Debug ***********************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +# define i2clldbg lldbg +# define i2cllvdbg llvdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +# define i2clldbg(x...) +# define i2cllvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct twi_dev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + struct i2c_msg_s *msg; /* Message list */ + uintptr_t base; /* Base address of registers */ + uint32_t clkin; /* TWI input clock frequency */ + uint32_t i2cfreq; /* Selected TWI frequency */ + uint16_t irq; /* IRQ number for this device */ + uint8_t msgc; /* Number of message in the message list */ + uint8_t twi; /* TWI peripheral number (for debug output) */ + uint8_t pid; /* TWI peripheral ID */ + + sem_t exclsem; /* Only one thread can access at a time */ + sem_t waitsem; /* Wait for TWI transfer completion */ + WDOG_ID timeout; /* Watchdog to recover from bus hangs */ + volatile int result; /* The result of the transfer */ + volatile int xfrd; /* Number of bytes transfers */ + + /* Debug stuff */ + +#ifdef CONFIG_SAM34_TWI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helper functions */ + +static void twi_takesem(sem_t *sem); +#define twi_givesem(sem) (sem_post(sem)) + +#ifdef CONFIG_SAM34_TWI_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, + uint32_t value, uintptr_t address); +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address); +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value); +#else +# define twi_checkreg(priv,wr,value,address) (false) +# define twi_putabs(p,a,v) putreg32(v,a) +# define twi_getabs(p,a) getreg32(a) +#endif + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, + unsigned int offset); +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value); + +/* I2C transfer helper functions */ + +static int twi_wait(struct twi_dev_s *priv); +static void twi_wakeup(struct twi_dev_s *priv, int result); +static int twi_interrupt(struct twi_dev_s *priv); +#ifdef CONFIG_SAM34_TWI0 +static int twi0_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAM34_TWI1 +static int twi1_interrupt(int irq, FAR void *context); +#endif +static void twi_timeout(int argc, uint32_t arg, ...); + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg); + +/* I2C device operations */ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s * dev); +#endif + +/* Initialization */ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency); +static void twi_hw_initialize(struct twi_dev_s *priv, unsigned int pid, + uint32_t frequency); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TWI0 +static struct twi_dev_s g_twi0; +#endif + +#ifdef CONFIG_SAM34_TWI1 +static struct twi_dev_s g_twi1; +#endif + +static const struct i2c_ops_s g_twiops = +{ + .transfer = twi_transfer +#ifdef CONFIG_I2C_RESET + , .reset = twi_reset +#endif +}; + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: twi_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wake-ups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void twi_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: twi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * false: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TWI_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = value; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: twi_getabs + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TWI_REGDEBUG +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address) +{ + uint32_t value = getreg32(address); + + if (twi_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } + + return value; +} +#endif + +/**************************************************************************** + * Name: twi_putabs + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_TWI_REGDEBUG +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value) +{ + if (twi_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } + + putreg32(value, address); +} +#endif + +/**************************************************************************** + * Name: twi_getrel + * + * Description: + * Read a TWI register using an offset relative to the TWI base address + * + ****************************************************************************/ + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, unsigned int offset) +{ + return twi_getabs(priv, priv->base + offset); +} + +/**************************************************************************** + * Name: twi_putrel + * + * Description: + * Write a value to a TWI register using an offset relative to the TWI base + * address. + * + ****************************************************************************/ + +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value) +{ + twi_putabs(priv, priv->base + offset, value); +} + +/**************************************************************************** + * I2C transfer helper functions + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_wait + * + * Description: + * Perform a I2C transfer start + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +static int twi_wait(struct twi_dev_s *priv) +{ + /* Start a timeout to avoid hangs */ + + wd_start(priv->timeout, TWI_TIMEOUT, twi_timeout, 1, (uint32_t)priv); + + /* Wait for either the TWI transfer or the timeout to complete */ + + do + { + i2clldbg("TWI%d Waiting...\n", priv->twi); + twi_takesem(&priv->waitsem); + i2clldbg("TWI%d Awakened with result: %d\n", priv->twi, priv->result); + } + while (priv->result == -EBUSY); + + /* We get here via twi_wakeup. The watchdog timer has been disabled and + * all further interrupts for the TWI have been disabled. + */ + + return priv->result; +} + +/**************************************************************************** + * Name: twi_wakeup + * + * Description: + * A terminal event has occurred. Wake-up the waiting thread + * + ****************************************************************************/ + +static void twi_wakeup(struct twi_dev_s *priv, int result) +{ + /* Cancel any pending timeout */ + + wd_cancel(priv->timeout); + + /* Disable any further TWI interrupts */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_ALL); + + /* Wake up the waiting thread with the result of the transfer */ + + priv->result = result; + twi_givesem(&priv->waitsem); +} + +/**************************************************************************** + * Name: twi_interrupt + * + * Description: + * The TWI Interrupt Handler + * + ****************************************************************************/ + +static int twi_interrupt(struct twi_dev_s *priv) +{ + struct i2c_msg_s *msg; + uint32_t sr; + uint32_t imr; + uint32_t pending; + uint32_t regval; + + /* Retrieve masked interrupt status */ + + sr = twi_getrel(priv, SAM_TWI_SR_OFFSET); + imr = twi_getrel(priv, SAM_TWI_IMR_OFFSET); + pending = sr & imr; + + i2cllvdbg("TWI%d pending: %08x\n", priv->twi, pending); + + msg = priv->msg; + + /* Check for errors */ + + if ((pending & TWI_INT_ERRORS) != 0) + { + /* Wake up the thread with an I/O error indication */ + + i2clldbg("ERROR: TWI%d pending: %08x\n", priv->twi, pending); + twi_wakeup(priv, -EIO); + } + + /* Byte received */ + + else if ((pending & TWI_INT_RXRDY) != 0) + { + msg->buffer[priv->xfrd] = twi_getrel(priv, SAM_TWI_RHR_OFFSET); + priv->xfrd++; + + /* Check for transfer complete */ + + if (priv->xfrd >= msg->length) + { + /* The transfer is complete. Disable the RXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_RXRDY); + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP); + } + + /* Not yet complete, but will the next be the last byte? */ + + else if (priv->xfrd == (msg->length - 1)) + { + /* Yes, set the stop signal */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP); + } + } + + /* Byte sent */ + + else if ((pending & TWI_INT_TXRDY) != 0) + { + /* Transfer finished? */ + + if (priv->xfrd >= msg->length) + { + /* The transfer is complete. Disable the TXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXRDY); + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP); + + /* Send the STOP condition */ + + regval = twi_getrel(priv, SAM_TWI_CR_OFFSET); + regval |= TWI_CR_STOP; + twi_putrel(priv, SAM_TWI_CR_OFFSET, regval); + } + + /* No, there are more bytes remaining to be sent */ + + else + { + twi_putrel(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd]); + priv->xfrd++; + } + } + + /* Transfer complete */ + + else if ((pending & TWI_INT_TXCOMP) != 0) + { + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP); + + /* Is there another message to send? */ + + if (priv->msgc > 1) + { + /* Yes... start the next message */ + + priv->msg++; + priv->msgc--; + twi_startmessage(priv, priv->msg); + } + else + { + /* No.. we made it to the end of the message list with no errors. + * Cancel any timeout and wake up the waiting thread with a + * success indication. + */ + + twi_wakeup(priv, OK); + } + } + + return OK; +} + +#ifdef CONFIG_SAM34_TWI0 +static int twi0_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi0); +} +#endif + +#ifdef CONFIG_SAM34_TWI1 +static int twi1_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi1); +} +#endif + +/**************************************************************************** + * Name: twi_timeout + * + * Description: + * Watchdog timer for timeout of TWI operation + * + * Assumptions: + * Called from the timer interrupt handler with interrupts disabled. + * + ****************************************************************************/ + +static void twi_timeout(int argc, uint32_t arg, ...) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)arg; + + i2clldbg("TWI%d Timeout!\n", priv->twi); + twi_wakeup(priv, -ETIMEDOUT); +} + +/**************************************************************************** + * Name: twi_startread + * + * Description: + * Start the next read message + * + ****************************************************************************/ + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set STOP signal if only one byte is sent */ + + if (msg->length == 1) + { + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP); + } + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWI_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_MREAD | TWI_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWI_IADR_OFFSET, 0); + + /* Enable read interrupt and send the START condition */ + + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_RXRDY | TWI_INT_ERRORS); + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_START); +} + +/**************************************************************************** + * Name: twi_startwrite + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWI_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWI_IADR_OFFSET, 0); + + /* Write first byte to send. */ + + twi_putrel(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd++]); + + /* Enable write interrupt */ + + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXRDY | TWI_INT_ERRORS); +} + +/**************************************************************************** + * Name: twi_startmessage + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + if ((msg->flags & I2C_M_READ) == 0) + { + twi_startread(priv, msg); + } + else + { + twi_startwrite(priv, msg); + } +} + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_transfer + * + * Description: + * Receive a block of data on I2C using the previously selected I2C + * frequency and slave address. + * + ****************************************************************************/ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)dev; + irqstate_t flags; + int ret; + + DEBUGASSERT(dev != NULL); + i2cvdbg("TWI%d count: %d\n", priv->twi, count); + + /* Get exclusive access to the device */ + + twi_takesem(&priv->exclsem); + + /* Setup the message transfer */ + + priv->msg = msgs; + priv->msgc = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + twi_setfrequency(priv, msgs->frequency); + + /* Initiate the transfer. The rest will be handled from interrupt + * logic. Interrupts must be disabled to prevent re-entrance from the + * interrupt level. + */ + + flags = enter_critical_section(); + twi_startmessage(priv, msgs); + + /* And wait for the transfers to complete. Interrupts will be re-enabled + * while we are waiting. + */ + + ret = twi_wait(priv); + if (ret < 0) + { + i2cdbg("ERROR: Transfer failed: %d\n", ret); + } + + leave_critical_section(flags); + twi_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: twi_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Initialization + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency) +{ + unsigned int ckdiv; + unsigned int cldiv; + uint32_t regval; + + if (frequency != priv->i2cfreq) + { + /* Configure TWI output clocking, trying each value of CKDIV {0..7} */ + + for (ckdiv = 0; ckdiv < 8; ckdiv++) + { + /* Calulate the CLDIV value using the current CKDIV guess */ + + cldiv = ((priv->clkin / (frequency << 1)) - 4) / (1 << ckdiv); + + /* Is CLDIV in range? */ + + if (cldiv <= 255) + { + /* Yes, break out and use it */ + + break; + } + } + + /* Then setup the TWI Clock Waveform Generator Register, using the same + * value for CLDIV and CHDIV (for 1:1 duty). + */ + + twi_putrel(priv, SAM_TWI_CWGR_OFFSET, 0); + + regval = ((uint32_t)ckdiv << TWI_CWGR_CKDIV_SHIFT) | + ((uint32_t)cldiv << TWI_CWGR_CHDIV_SHIFT) | + ((uint32_t)cldiv << TWI_CWGR_CLDIV_SHIFT); + twi_putrel(priv, SAM_TWI_CWGR_OFFSET, regval); + + /* Remember the selected frequency for error recovery */ + + priv->i2cfreq = frequency; + } +} + +/**************************************************************************** + * Name: twi_hw_initialize + * + * Description: + * Initialize one TWI peripheral for I2C operation + * + ****************************************************************************/ + +static void twi_hw_initialize(struct twi_dev_s *priv, unsigned int pid, + uint32_t frequency) +{ +#if 0 + uint32_t regval; + uint32_t mck; +#endif + + i2cvdbg("TWI%d Initializing\n", priv->twi); + + /* SVEN: TWI Slave Mode Enabled */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SVEN); + + /* Reset the TWI */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SWRST); + (void)twi_getrel(priv, SAM_TWI_RHR_OFFSET); + + /* TWI Slave Mode Disabled, TWI Master Mode Disabled. */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SVDIS); + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSDIS); + + /* Set master mode */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSEN); + + /* Set base frequency */ + + priv->clkin = BOARD_MCK_FREQUENCY; + +#if 0 + /* Determine the maximum valid frequency setting */ + + mck = BOARD_MCK_FREQUENCY; + DEBUGASSERT((mck >> 3) <= TWI_MAX_FREQUENCY); + + if (mck <= TWI_MAX_FREQUENCY) + { + priv->clkin = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= TWI_MAX_FREQUENCY) + { + priv->clkin = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= TWI_MAX_FREQUENCY) + { + priv->clkin = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else /* if ((mck >> 3) <= TWI_MAX_FREQUENCY) */ + { + priv->clkin = (mck >> 3); + regval = PMC_PCR_DIV8; + } + + /* Set the TWI peripheral input clock to the maximum, valid frequency */ + + regval |= PMC_PCR_PID(pid) | PMC_PCR_CMD | PMC_PCR_EN; + twi_putabs(priv, SAM_PMC_PCR, regval); +#endif + + /* Set the initial TWI data transfer frequency */ + + twi_setfrequency(priv, frequency); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize a TWI device for I2C operation + * + ****************************************************************************/ + +struct i2c_master_s *sam_i2cbus_initialize(int bus) +{ + struct twi_dev_s *priv; + xcpt_t handler; + irqstate_t flags; + uint32_t frequency; + unsigned int pid; + + i2cvdbg("Initializing TWI%d\n", bus); + + flags = enter_critical_section(); + +#ifdef CONFIG_SAM34_TWI0 + if (bus == 0) + { + /* Set up TWI0 register base address and IRQ number */ + + priv = &g_twi0; + priv->base = SAM_TWI0_BASE; + priv->irq = SAM_IRQ_TWI0; + priv->twi = 0; + + /* Enable peripheral clocking */ + + sam_twi0_enableclk(); + + /* Configure PIO pins */ + + sam_configgpio(GPIO_TWI0_CK); + sam_configgpio(GPIO_TWI0_D); + + /* Select the interrupt handler, TWI frequency, and peripheral ID */ + + handler = twi0_interrupt; + frequency = CONFIG_SAM34_TWI0_FREQUENCY; + pid = SAM_PID_TWI0; + } + else +#endif +#ifdef CONFIG_SAM34_TWI1 + if (bus == 1) + { + /* Set up TWI1 register base address and IRQ number */ + + priv = &g_twi1; + priv->base = SAM_TWI0_BASE; + priv->irq = SAM_IRQ_TWI1; + priv->twi = 1; + + /* Enable peripheral clocking */ + + sam_twi1_enableclk(); + + /* Configure PIO pins */ + + sam_configgpio(GPIO_TWI1_CK); + sam_configgpio(GPIO_TWI1_D); + + /* Select the interrupt handler, TWI frequency, and peripheral ID */ + + handler = twi1_interrupt; + frequency = CONFIG_SAMA5_TWI1_FREQUENCY; + pid = SAM_PID_TWI1; + } + else +#endif + { + leave_critical_section(flags); + i2cdbg("ERROR: Unsupported bus: TWI%d\n", bus); + return NULL; + } + + /* Initialize the device structure */ + + priv->dev.ops = &g_twiops; + + sem_init(&priv->exclsem, 0, 1); + sem_init(&priv->waitsem, 0, 0); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Configure and enable the TWI hardware */ + + priv->pid = pid; + twi_hw_initialize(priv, pid, frequency); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irq, handler); + + /* Enable Interrupts */ + + up_enable_irq(priv->irq); + leave_critical_section(flags); + return &priv->dev; +} + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct twi_dev_s *priv = (struct twi_dev_s *) dev; + + i2cvdbg("TWI%d Un-initializing\n", priv->twi); + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Reset data structures */ + + sem_destroy(&priv->exclsem); + sem_destroy(&priv->waitsem); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Detach Interrupt Handler */ + + irq_detach(priv->irq); + return OK; +} + +#endif /* CONFIG_SAM34_TWI0 || CONFIG_SAM34_TWI1 */ diff --git a/arch/arm/src/sam34/sam_twi.h b/arch/arm/src/sam34/sam_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..87c31b30321b70017756d42cd83ecb15c9ce5b53 --- /dev/null +++ b/arch/arm/src/sam34/sam_twi.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_twi.h + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_TWI_H +#define __ARCH_ARM_SRC_SAM34_SAM_TWI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip/sam_twi.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *sam_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the sam_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_SAM34_SAM_TWI_H */ diff --git a/arch/arm/src/sam34/sam_udp.c b/arch/arm/src/sam34/sam_udp.c new file mode 100644 index 0000000000000000000000000000000000000000..0a74f5ba243bdaaddb41da57dc7ac2d50296e472 --- /dev/null +++ b/arch/arm/src/sam34/sam_udp.c @@ -0,0 +1,4043 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_udp.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This driver derives in a small part from the SAMA5D3 UDP driver: + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Atmel sample code was used as a reference (only) in the SAMA5D3 driver + * development. The Atmel sample code has a BSD compatible license that + * requires this copyright notice: + * + * Copyright (c) 2009, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_periphclks.h" +#include "chip/sam_udp.h" +#include "sam_udp.h" + +#if defined(CONFIG_USBDEV) && defined(CONFIG_SAM34_UDP) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAM34_UDP_REGDEBUG +#endif + +/* Driver Definitions *******************************************************/ +/* Initial interrupt mask: Reset + Suspend + Correct Transfer */ + +#define SAM_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_CTRM) + +/* Endpoint definitions (Assuming 8 endpoints) */ + +#define EP0 (0) +#define SAM_EPSET_ALL (0xff) /* All endpoints */ +#define SAM_EPSET_NOTEP0 (0xfe) /* All endpoints except EP0 */ +#define SAM_EP_BIT(ep) (1 << (ep)) +#define SAM_EP0_MAXPACKET (64) /* EP0 Max. packet size */ + +/* Bitmap for all status bits in CSR that are not effected by a value 1 */ + +#define CSR_NOEFFECT_BITS (UDPEP_CSR_RXDATABK0 | UDPEP_CSR_RXDATABK1 | \ + UDPEP_CSR_STALLSENT | UDPEP_CSR_RXSETUP | \ + UDPEP_CSR_TXCOMP) + +#define nop() __asm__ __volatile__ ("nop") + +/* USB-related masks */ + +#define REQRECIPIENT_MASK (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK) + +/* Endpoint register masks (handling toggle fields) */ + +#define EPR_NOTOG_MASK (USB_EPR_CTR_RX | USB_EPR_SETUP | USB_EPR_EPTYPE_MASK |\ + USB_EPR_EP_KIND | USB_EPR_CTR_TX | USB_EPR_EA_MASK) +#define EPR_TXDTOG_MASK (USB_EPR_STATTX_MASK | EPR_NOTOG_MASK) +#define EPR_RXDTOG_MASK (USB_EPR_STATRX_MASK | EPR_NOTOG_MASK) + +/* Request queue operations *************************************************/ + +#define sam_rqempty(q) ((q)->head == NULL) +#define sam_rqpeek(q) ((q)->head) + +/* USB trace ****************************************************************/ +/* Trace error codes */ + +#define SAM_TRACEERR_ALLOCFAIL 0x0001 +#define SAM_TRACEERR_BADCLEARFEATURE 0x0002 +#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003 +#define SAM_TRACEERR_BADEPGETSTATUS 0x0004 +#define SAM_TRACEERR_BADEOBSTATE 0x0005 +#define SAM_TRACEERR_BADEPNO 0x0006 +#define SAM_TRACEERR_BADEPTYPE 0x0007 +#define SAM_TRACEERR_BADGETCONFIG 0x0008 +#define SAM_TRACEERR_BADGETSETDESC 0x0009 +#define SAM_TRACEERR_BADGETSTATUS 0x000a +#define SAM_TRACEERR_BADSETADDRESS 0x000b +#define SAM_TRACEERR_BADSETCONFIG 0x000c +#define SAM_TRACEERR_BADSETFEATURE 0x000d +#define SAM_TRACEERR_BINDFAILED 0x000e +#define SAM_TRACEERR_DISPATCHSTALL 0x000f +#define SAM_TRACEERR_DRIVER 0x0010 +#define SAM_TRACEERR_DRIVERREGISTERED 0x0011 +#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0012 +#define SAM_TRACEERR_EP0SETUPSTALLED 0x0013 +#define SAM_TRACEERR_EPOUTNULLPACKET 0x0014 +#define SAM_TRACEERR_EPRESERVE 0x0015 +#define SAM_TRACEERR_INVALIDCTRLREQ 0x0016 +#define SAM_TRACEERR_INVALIDPARMS 0x0017 +#define SAM_TRACEERR_IRQREGISTRATION 0x0018 +#define SAM_TRACEERR_NOTCONFIGURED 0x0019 +#define SAM_TRACEERR_REQABORTED 0x001a +#define SAM_TRACEERR_RXDATABKERR 0x001b +#define SAM_TRACEERR_TXCOMPERR 0x001c +#define SAM_TRACEERR_UNSUPPEPTYPE 0x001d + +/* Trace interrupt codes */ + +#define SAM_TRACEINTID_ADDRESSED 0x0001 +#define SAM_TRACEINTID_CLEARFEATURE 0x0002 +#define SAM_TRACEINTID_RXSUSP 0x0003 +#define SAM_TRACEINTID_DEVGETSTATUS 0x0004 +#define SAM_TRACEINTID_DISPATCH 0x0005 +#define SAM_TRACEINTID_ENDBUSRES 0x0006 +#define SAM_TRACEINTID_EP 0x0007 +#define SAM_TRACEINTID_EP0SETUPIN 0x0008 +#define SAM_TRACEINTID_EP0SETUPOUT 0x0009 +#define SAM_TRACEINTID_EP0SETUPSETADDRESS 0x000a +#define SAM_TRACEINTID_EPGETSTATUS 0x000b +#define SAM_TRACEINTID_EPINQEMPTY 0x000c +#define SAM_TRACEINTID_EPOUTQEMPTY 0x000d +#define SAM_TRACEINTID_GETCONFIG 0x000e +#define SAM_TRACEINTID_GETSETDESC 0x000f +#define SAM_TRACEINTID_GETSETIF 0x0010 +#define SAM_TRACEINTID_GETSTATUS 0x0011 +#define SAM_TRACEINTID_IFGETSTATUS 0x0012 +#define SAM_TRACEINTID_INTERRUPT 0x0013 +#define SAM_TRACEINTID_SOF 0x0014 +#define SAM_TRACEINTID_NOSTDREQ 0x0015 +#define SAM_TRACEINTID_PENDING 0x0016 +#define SAM_TRACEINTID_RXDATABK0 0x0017 +#define SAM_TRACEINTID_RXDATABK1 0x0018 +#define SAM_TRACEINTID_RXSETUP 0x0019 +#define SAM_TRACEINTID_SETCONFIG 0x001a +#define SAM_TRACEINTID_SETFEATURE 0x001b +#define SAM_TRACEINTID_STALLSNT 0x001c +#define SAM_TRACEINTID_SYNCHFRAME 0x001d +#define SAM_TRACEINTID_TXCOMP 0x001e +#define SAM_TRACEINTID_UPSTRRES 0x001f +#define SAM_TRACEINTID_WAKEUP 0x0020 + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/* Byte ordering in host-based values */ + +#ifdef CONFIG_ENDIAN_BIG +# define LSB 1 +# define MSB 0 +#else +# define LSB 0 +# define MSB 1 +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ +/* State of an endpoint */ + +enum sam_epstate_e +{ + /* --- All Endpoints --- */ + UDP_EPSTATE_DISABLED = 0, /* Endpoint is disabled */ + UDP_EPSTATE_STALLED, /* Endpoint is stalled */ + UDP_EPSTATE_IDLE, /* Endpoint is idle (i.e. ready for transmission) */ + UDP_EPSTATE_SENDING, /* Endpoint is sending data */ + UDP_EPSTATE_RXSTOPPED, /* OUT endpoint is stopped waiting for a read request */ + /* --- Endpoint 0 Only --- */ + UDP_EPSTATE_EP0DATAOUT, /* Endpoint 0 is receiving SETUP OUT data */ + UDP_EPSTATE_EP0STATUSIN, /* Endpoint 0 is sending SETUP status */ + UDP_EPSTATE_EP0ADDRESS /* Address change is pending completion of status */ +}; + +/* The overall state of the device */ + +enum sam_devstate_e +{ + UDP_DEVSTATE_SUSPENDED = 0, /* The device is currently suspended */ + UDP_DEVSTATE_POWERED, /* Host is providing +5V through the USB cable */ + UDP_DEVSTATE_DEFAULT, /* Device has been reset */ + UDP_DEVSTATE_ADDRESSED, /* The device has been given an address on the bus */ + UDP_DEVSTATE_CONFIGURED /* A valid configuration has been selected. */ +}; + +/* The result of EP0 SETUP processing */ + +enum sam_ep0setup_e +{ + UDP_EP0SETUP_SUCCESS = 0, /* The SETUP was handle without incident */ + UDP_EP0SETUP_DISPATCHED, /* The SETUP was forwarded to the class driver */ + UDP_EP0SETUP_ADDRESS, /* A new device address is pending */ + UDP_EP0SETUP_STALL /* An error occurred */ +}; + +union wb_u +{ + uint16_t w; + uint8_t b[2]; +}; + +/* A container for a request so that the request make be retained in a list */ + +struct sam_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct sam_req_s *flink; /* Supports a singly linked list */ + uint16_t inflight; /* Number of TX bytes written to FIFO */ +}; + +/* The head of a queue of requests */ + +struct sam_rqhead_s +{ + struct sam_req_s *head; /* Requests are added to the head of the list */ + struct sam_req_s *tail; /* Requests are removed from the tail of the list */ +}; + +/* This is the internal representation of an endpoint */ + +struct sam_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct sam_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* SAM34-specific fields */ + + struct sam_usbdev_s *dev; /* Reference to private driver data */ + struct sam_rqhead_s reqq; /* Read/write request queue */ + struct sam_rqhead_s pendq; /* Write requests pending stall sent */ + volatile uint8_t epstate; /* State of the endpoint (see enum sam_epstate_e) */ + uint8_t stalled:1; /* true: Endpoint is stalled */ + uint8_t pending:1; /* true: IN Endpoint stall is pending */ + uint8_t halted:1; /* true: Endpoint feature halted */ + uint8_t zlpneeded:1; /* Zero length packet needed at end of transfer */ + uint8_t zlpsent:1; /* Zero length packet has been sent */ + uint8_t txbusy:1; /* Write request queue is busy (recursion avoidance kludge) */ +}; + +struct sam_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structsam_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* UDP-specific fields */ + + struct usb_ctrlreq_s ctrl; /* Last EP0 request */ + uint8_t devstate; /* State of the device (see enum sam_devstate_e) */ + uint8_t prevstate; /* Previous state of the device before SUSPEND */ + uint8_t devaddr; /* Assigned device address */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint16_t epavail; /* Bitset of available endpoints */ + + /* The endpoint list */ + + struct sam_ep_s eplist[SAM_UDP_NENDPOINTS]; + + /* EP0 data buffer. For data that is included in an EP0 SETUP OUT + * transaction. In this case, no request is in place from the class + * driver and the incoming data is caught in this buffer. The size + * of valid dat in the buffer is given by ctrlreg.len[]. For the + * case of EP0 SETUP IN transaction, the normal request mechanism is + * used and the class driver provides the buffering. + */ + + uint8_t ep0out[SAM_EP0_MAXPACKET]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_SAM34_UDP_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +static void sam_dumpep(struct sam_usbdev_s *priv, uint8_t epno); +#else +static inline uint32_t sam_getreg(uintptr_t regaddr); +static inline void sam_putreg(uint32_t regval, uintptr_t regaddr); +# define sam_dumpep(priv,epno) +#endif + +static void sam_csr_setbits(uint8_t epno, uint32_t setbits); +static void sam_csr_clrbits(uint8_t epno, uint32_t clrbits); + +/* Suspend/Resume Helpers ***************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv); +static void sam_resume(struct sam_usbdev_s *priv); + +/* Request Helpers **********************************************************/ + +static struct sam_req_s * + sam_req_dequeue(struct sam_rqhead_s *queue); +static void sam_req_enqueue(struct sam_rqhead_s *queue, + struct sam_req_s *req); +static void sam_req_complete(struct sam_ep_s *privep, int16_t result); +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); +static int sam_req_write(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static int sam_req_read(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, uint16_t recvsize, + int bank); +static void sam_req_cancel(struct sam_ep_s *privep, int16_t status); + +/* Interrupt level processing ***********************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen); +static void sam_ep0_wrstatus(const uint8_t *buffer, size_t buflen); +static void sam_ep0_dispatch(struct sam_usbdev_s *priv); +static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t value); +static void sam_ep0_setup(struct sam_usbdev_s *priv); +static void sam_ep_bankinterrupt(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, uint32_t csr, int bank); +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno); +static int sam_udp_interrupt(int irq, void *context); + +/* Endpoint helpers *********************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno); +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset); +static int sam_ep_stall(struct sam_ep_s *privep); +static int sam_ep_resume(struct sam_ep_s *privep); +static inline struct sam_ep_s * + sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset); +static inline void + sam_ep_unreserve(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static inline bool + sam_ep_reserved(struct sam_usbdev_s *priv, int epno); +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc); + +/* Endpoint operations ******************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int sam_ep_disable(struct usbdev_ep_s *ep); +static struct usbdev_req_s * + sam_ep_allocreq(struct usbdev_ep_s *ep); +static void sam_ep_freereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes); +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf); +#endif +static int sam_ep_submit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_cancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_stallresume(struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations *****************************************/ + +static struct usbdev_ep_s * + sam_allocep(struct usbdev_s *dev, uint8_t epno, bool in, + uint8_t eptype); +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep); +static int sam_getframe(struct usbdev_s *dev); +static int sam_wakeup(struct usbdev_s *dev); +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int sam_pullup(FAR struct usbdev_s *dev, bool enable); + +/* Initialization/Reset *****************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv); +static void sam_enableclks(void); +static void sam_disableclks(void); +static void sam_hw_setup(struct sam_usbdev_s *priv); +static void sam_sw_setup(struct sam_usbdev_s *priv); +static void sam_hw_shutdown(struct sam_usbdev_s *priv); +static void sam_sw_shutdown(struct sam_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct sam_usbdev_s g_udp; + +static const struct usbdev_epops_s g_epops = +{ + .configure = sam_ep_configure, + .disable = sam_ep_disable, + .allocreq = sam_ep_allocreq, + .freereq = sam_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = sam_ep_allocbuffer, + .freebuffer = sam_ep_freebuffer, +#endif + .submit = sam_ep_submit, + .cancel = sam_ep_cancel, + .stall = sam_ep_stallresume, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = sam_allocep, + .freeep = sam_freeep, + .getframe = sam_getframe, + .wakeup = sam_wakeup, + .selfpowered = sam_selfpowered, + .pullup = sam_pullup, +}; + +/* This describes endpoint 0 */ + +static const struct usb_epdesc_s g_ep0desc = +{ + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = EP0, + .attr = USB_EP_ATTR_XFER_CONTROL, + .mxpacketsize = {64, 0}, + .interval = 0 +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(SAM_TRACEERR_ALLOCFAIL), + TRACE_STR(SAM_TRACEERR_BADCLEARFEATURE), + TRACE_STR(SAM_TRACEERR_BADDEVGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEOBSTATE), + TRACE_STR(SAM_TRACEERR_BADEPNO), + TRACE_STR(SAM_TRACEERR_BADEPTYPE), + TRACE_STR(SAM_TRACEERR_BADGETCONFIG), + TRACE_STR(SAM_TRACEERR_BADGETSETDESC), + TRACE_STR(SAM_TRACEERR_BADGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADSETADDRESS), + TRACE_STR(SAM_TRACEERR_BADSETCONFIG), + TRACE_STR(SAM_TRACEERR_BADSETFEATURE), + TRACE_STR(SAM_TRACEERR_BINDFAILED), + TRACE_STR(SAM_TRACEERR_DISPATCHSTALL), + TRACE_STR(SAM_TRACEERR_DRIVER), + TRACE_STR(SAM_TRACEERR_DRIVERREGISTERED), + TRACE_STR(SAM_TRACEERR_EP0SETUPOUTSIZE), + TRACE_STR(SAM_TRACEERR_EP0SETUPSTALLED), + TRACE_STR(SAM_TRACEERR_EPOUTNULLPACKET), + TRACE_STR(SAM_TRACEERR_EPRESERVE), + TRACE_STR(SAM_TRACEERR_INVALIDCTRLREQ), + TRACE_STR(SAM_TRACEERR_INVALIDPARMS), + TRACE_STR(SAM_TRACEERR_IRQREGISTRATION), + TRACE_STR(SAM_TRACEERR_NOTCONFIGURED), + TRACE_STR(SAM_TRACEERR_REQABORTED), + TRACE_STR(SAM_TRACEERR_RXDATABKERR), + TRACE_STR(SAM_TRACEERR_TXCOMPERR), + TRACE_STR(SAM_TRACEERR_UNSUPPEPTYPE), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(SAM_TRACEINTID_ADDRESSED), + TRACE_STR(SAM_TRACEINTID_CLEARFEATURE), + TRACE_STR(SAM_TRACEINTID_RXSUSP), + TRACE_STR(SAM_TRACEINTID_DEVGETSTATUS), + TRACE_STR(SAM_TRACEINTID_DISPATCH), + TRACE_STR(SAM_TRACEINTID_ENDBUSRES), + TRACE_STR(SAM_TRACEINTID_EP), + TRACE_STR(SAM_TRACEINTID_EP0SETUPIN), + TRACE_STR(SAM_TRACEINTID_EP0SETUPOUT), + TRACE_STR(SAM_TRACEINTID_EP0SETUPSETADDRESS), + TRACE_STR(SAM_TRACEINTID_EPGETSTATUS), + TRACE_STR(SAM_TRACEINTID_EPINQEMPTY), + TRACE_STR(SAM_TRACEINTID_EPOUTQEMPTY), + TRACE_STR(SAM_TRACEINTID_GETCONFIG), + TRACE_STR(SAM_TRACEINTID_GETSETDESC), + TRACE_STR(SAM_TRACEINTID_GETSETIF), + TRACE_STR(SAM_TRACEINTID_GETSTATUS), + TRACE_STR(SAM_TRACEINTID_IFGETSTATUS), + TRACE_STR(SAM_TRACEINTID_INTERRUPT), + TRACE_STR(SAM_TRACEINTID_SOF), + TRACE_STR(SAM_TRACEINTID_NOSTDREQ), + TRACE_STR(SAM_TRACEINTID_PENDING), + TRACE_STR(SAM_TRACEINTID_RXDATABK0), + TRACE_STR(SAM_TRACEINTID_RXDATABK1), + TRACE_STR(SAM_TRACEINTID_RXSETUP), + TRACE_STR(SAM_TRACEINTID_SETCONFIG), + TRACE_STR(SAM_TRACEINTID_SETFEATURE), + TRACE_STR(SAM_TRACEINTID_STALLSNT), + TRACE_STR(SAM_TRACEINTID_SYNCHFRAME), + TRACE_STR(SAM_TRACEINTID_TXCOMP), + TRACE_STR(SAM_TRACEINTID_UPSTRRES), + TRACE_STR(SAM_TRACEINTID_WAKEUP), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_printreg + * + * Description: + * Print the contents of a SAM34 UDP registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_UDP_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + lldbg("%p%s%08x\n", regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a SAM34 + * UDP registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_UDP_REGDEBUG +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + static uintptr_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + sam_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + sam_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAM34 register + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_UDP_REGDEBUG +static uint32_t sam_getreg(uintptr_t regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t sam_getreg(uintptr_t regaddr) +{ + return getreg32(regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAM34 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_UDP_REGDEBUG +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, true); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#else +static inline void sam_putreg(uint32_t regval, uint32_t regaddr) +{ + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_dumpep + ****************************************************************************/ + +#if defined(CONFIG_SAM34_UDP_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_dumpep(struct sam_usbdev_s *priv, uint8_t epno) +{ + /* Global Registers */ + + lldbg("Global Registers:\n"); + lldbg(" FRMNUM: %08x\n", sam_getreg(SAM_UDP_FRMNUM)); + lldbg("GLBSTAT: %08x\n", sam_getreg(SAM_UDP_GLBSTAT)); + lldbg(" FADDR: %08x\n", sam_getreg(SAM_UDP_FADDR)); + lldbg(" IMR: %08x\n", sam_getreg(SAM_UDP_IMR)); + lldbg(" ISR: %08x\n", sam_getreg(SAM_UDP_ISR)); + lldbg(" RSTEP: %08x\n", sam_getreg(SAM_UDP_RSTEP)); + lldbg(" TXVC: %08x\n", sam_getreg(SAM_UDP_TXVC)); + lldbg(" CSR[%d]: %08x\n", epno, sam_getreg(SAM_UDPEP_CSR(epno))); +} +#endif + +/**************************************************************************** + * Request Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_req_dequeue + ****************************************************************************/ + +static struct sam_req_s *sam_req_dequeue(struct sam_rqhead_s *queue) +{ + struct sam_req_s *ret = queue->head; + + if (ret) + { + queue->head = ret->flink; + if (!queue->head) + { + queue->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_req_enqueue + ****************************************************************************/ + +static void sam_req_enqueue(struct sam_rqhead_s *queue, struct sam_req_s *req) +{ + req->flink = NULL; + if (!queue->head) + { + queue->head = req; + queue->tail = req; + } + else + { + queue->tail->flink = req; + queue->tail = req; + } +} + +/**************************************************************************** + * Name: sam_req_complete + ****************************************************************************/ + +static void sam_req_complete(struct sam_ep_s *privep, int16_t result) +{ + struct sam_req_s *privreq; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = sam_req_dequeue(&privep->reqq); + leave_critical_section(flags); + + if (privreq) + { + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Reset the endpoint state and restore the stalled indication */ + + privep->epstate = UDP_EPSTATE_IDLE; + privep->zlpneeded = false; + privep->zlpsent = false; + } +} + +/**************************************************************************** + * Name: sam_req_wrsetup + * + * Description: + * Process the next queued write request. + * + ****************************************************************************/ + +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + const uint8_t *buf; + volatile uint32_t *fifo; + uint8_t epno; + int nbytes; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Write access to the FIFO is not possible if TXDRY is set */ + + DEBUGASSERT((sam_getreg(SAM_UDPEP_CSR(epno)) & UDPEP_CSR_TXPKTRDY) == 0); + + /* Get the number of bytes remaining to be sent. */ + + DEBUGASSERT(privreq->req.xfrd < privreq->req.len); + nbytes = privreq->req.len - privreq->req.xfrd; + + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + + /* This is the new number of bytes "in-flight" */ + + privreq->inflight = nbytes; + usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes); + + /* The new buffer pointer is the start of the buffer plus the number of + * bytes successfully transferred plus the number of bytes previously + * "in-flight". + */ + + buf = privreq->req.buf + privreq->req.xfrd; + + /* Write packet in the FIFO buffer */ + + fifo = (volatile uint32_t *)SAM_UDPEP_FDR(epno); + for (; nbytes; nbytes--) + { + *fifo = (uint32_t)(*buf++); + } + + /* Indicate that there we are in the sending state (even if this is a + * zero-length packet) . This indication will be need in interrupt + * processing in order to properly terminate the request. + */ + + privep->epstate = UDP_EPSTATE_SENDING; + + /* Set TXPKTRDY to notify the USB hardware that there is TX data in the + * endpoint FIFO. We will be notified that the endpoint’s FIFO has been + * released by the USB device when TXCOMP in the endpoint’s UDPEP_CSRx + * register has been set. + */ + + sam_csr_setbits(epno, UDPEP_CSR_TXPKTRDY); +} + +/**************************************************************************** + * Name: sam_req_write + * + * Description: + * Process the next queued write request. This function is called in one + * of three contexts: (1) When the endpoint is IDLE and a new write request + * is submitted (with interrupts disabled), (2) from TXCOMP interrupt + * handling when the current FIFO Tx transfer completes, or (3) when resuming + * a stalled IN or control endpoint. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is the number of bytes + * to transfer and 'xfrd' and 'inflight' must be zero. + * + * When this function starts a transfer it will update the request + * 'inflight' field to indicate the size of the transfer. + * + * When the transfer completes, the 'inflight' field must hold the + * number of bytes that have completed the transfer. This function will + * update 'xfrd' with the new size of the transfer. + * + ****************************************************************************/ + +static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + struct sam_req_s *privreq; + uint8_t epno; + int bytesleft; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* We get here when an IN endpoint interrupt occurs. So now we know that + * there is no TX transfer in progress (epstate should be IDLE). + */ + + DEBUGASSERT(privep->epstate == UDP_EPSTATE_IDLE); + while (privep->epstate == UDP_EPSTATE_IDLE) + { + /* Check the request from the head of the endpoint request queue */ + + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* There is no TX transfer in progress and no new pending TX + * requests to send. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPINQEMPTY), 0); + + /* Was there a pending endpoint stall? */ + + if (privep->pending) + { + /* Yes... stall the endpoint now */ + + (void)sam_ep_stall(privep); + } + + return -ENOENT; + } + + ullvdbg("epno=%d req=%p: len=%d xfrd=%d inflight=%d zlpneeded=%d\n", + epno, privreq, privreq->req.len, privreq->req.xfrd, + privreq->inflight, privep->zlpneeded); + + /* Handle any bytes in flight. */ + + privreq->req.xfrd += privreq->inflight; + privreq->inflight = 0; + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + if (bytesleft > 0) + { + /* If the size is exactly a full packet, then note if we need to + * send a zero length packet next. + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* Next time we get here, bytesleft will be zero and zlpneeded + * will be set. + */ + + privep->zlpneeded = true; + } + else + { + /* No zero packet is forthcoming (maybe later) */ + + privep->zlpneeded = false; + } + + /* Perform the write operation. epstate will become SENDING. */ + + sam_req_wrsetup(priv, privep, privreq); + } + + /* No data to send... This can happen on one of two ways: + * (1) The last packet sent was the final packet of a transfer. + * If it was also exactly maxpacketsize and the protocol expects + * a zero length packet to follow then privep->zlpneeded will be + * set. Or (2) we called with a request packet that has + * len == 0 (privep->zlpneeded will not be set). Either case + * means that it is time to send a zero length packet and complete + * this transfer. + */ + + else if ((privreq->req.len == 0 || privep->zlpneeded) && !privep->zlpsent) + { + /* If we get here, then we sent the last of the data on the + * previous pass and we need to send the zero length packet now. + * + * A Zero Length Packet can be sent by setting just the TXPTKRDY flag + * in the UDP_EPTSETSTAx register + */ + + privep->epstate = UDP_EPSTATE_SENDING; + privep->zlpneeded = false; + privep->zlpsent = true; + privreq->inflight = 0; + + /* Set TXPKTRDY to notify the USB hardware that there is (null) + * TX packet available. We will be notified that the endpoint’s + * FIFO has been released by the USB device when TXCOMP in the + * endpoint’s UDPEP_CSRx register has been set. + */ + + usbtrace(TRACE_WRITE(epno), 0); + sam_csr_setbits(epno, UDPEP_CSR_TXPKTRDY); + } + + /* If all of the bytes were sent (including any final zero length + * packet) then we are finished with the request buffer and we can + * return the request buffer to the class driver. The state will + * remain IDLE only if nothing else was put in flight. + * + * Note that we will then loop to check to check the next queued + * write request. + */ + + if (privep->epstate == UDP_EPSTATE_IDLE) + { + /* Return the write request to the class driver. Set the txbusy + * bit to prevent being called recursively from any new submission + * generated by returning the write request. + */ + + usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd); + DEBUGASSERT(privreq->req.len == privreq->req.xfrd); + + privep->txbusy = true; + sam_req_complete(privep, OK); + privep->txbusy = false; + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_req_read + * + * Description: + * Complete the last read request by transferring the data from the RX FIFO + * to the request buffer, return the completed read request to the class + * implementation, and try to start the next queued read request. + * + * This function is called in one of two contexts: The normal case is (1) + * from interrupt handling when the current RX FIFO transfer completes. + * But there is also a special case (2) when the OUT endpoint is stopped + * because there are no available read requests. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is size of the request + * buffer. Any OUT request can be received that will fit in this + * buffer. 'xfrd' and 'inflight' in the request must be zero + * If sam_req_read() is called to start a new transfer, the recvsize + * parameter must be zero. + * + * When the transfer completes, the 'recvsize' is the number of bytes + * waiting in the FIFO to be read. + * + * bank indicates the bit in the CSR register that must be cleared + * after the data has been read from the RX FIFO + * + ****************************************************************************/ + +static int sam_req_read(struct sam_usbdev_s *priv, struct sam_ep_s *privep, + uint16_t recvsize, int bank) +{ + struct sam_req_s *privreq; + volatile const uint32_t *fifo; + uint8_t *dest; + int remaining; + int readlen; + int epno; + + DEBUGASSERT(priv && privep && privep->epstate == UDP_EPSTATE_IDLE); + + /* Check the request from the head of the endpoint request queue */ + + epno = USB_EPNO(privep->ep.eplog); + do + { + /* Peek at the next read request in the request queue */ + + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* No read request to receive data */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPOUTQEMPTY), epno); + + /* Disable further interrupts from this endpoint. The RXDATABK0/1 + * interrupt will pend until either another read request is received + * from the class driver or until the endpoint is reset because of + * no response. Set a flag so that we know that we are in this + * perverse state and can re-enable endpoint interrupts when the + * next read request is received. + */ + + sam_putreg(UDP_INT_EP(epno), SAM_UDP_IDR); + privep->epstate = UDP_EPSTATE_RXSTOPPED; + return -ENOENT; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + epno, privreq->req.len, privreq->req.xfrd); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPOUTNULLPACKET), 0); + sam_req_complete(privep, OK); + privreq = NULL; + } + } + while (privreq == NULL); + + usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), recvsize); + + /* Get the number of bytes that can be received. This is the size + * of the user-provided request buffer, minus the number of bytes + * already transferred to the user-buffer. + */ + + remaining = privreq->req.len - privreq->req.xfrd; + + /* Read the smaller of the number of bytes available in FIFO and the + * size remaining in the request buffer provided by the caller. + */ + + readlen = MIN(remaining, recvsize); + recvsize = 0; + + /* Get the source and destination transfer addresses */ + + fifo = (volatile const uint32_t *)SAM_UDPEP_FDR(epno); + dest = privreq->req.buf + privreq->req.xfrd; + + /* Update the total number of bytes transferred */ + + privreq->req.xfrd += readlen; + privreq->inflight = 0; + + /* Retrieve packet from the endpoint FIFO */ + + for (; readlen > 0; readlen--) + { + *dest++ = (uint8_t)(*fifo); + } + + /* We get here when an RXDATABK0/1 interrupt occurs. That interrupt + * cannot be cleared until all of the data has been taken from the RX + * FIFO. But we can + */ + + sam_csr_clrbits(epno, bank ? UDPEP_CSR_RXDATABK1 : UDPEP_CSR_RXDATABK0); + + /* Complete the transfer immediately and give the data to the class + * driver. The idea is that we will let the receiving be in-charge of + * re-assembling data fragments. + */ + + usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd); + sam_req_complete(privep, OK); + return OK; +} + +/**************************************************************************** + * Name: sam_req_cancel + ****************************************************************************/ + +static void sam_req_cancel(struct sam_ep_s *privep, int16_t result) +{ + /* Complete every queued request with the specified status */ + + while (!sam_rqempty(&privep->reqq)) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + (sam_rqpeek(&privep->reqq))->req.xfrd); + sam_req_complete(privep, result); + } +} + +/**************************************************************************** + * Interrupt Level Processing + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep0_read + * + * Description: + * Read a general USB request from the UDP FIFO + * + ****************************************************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen) +{ + volatile const uint32_t *fifo; + + usbtrace(TRACE_READ(EP0), buflen); + + /* Retrieve packet from the FIFO */ + + fifo = (volatile const uint32_t *)SAM_UDPEP_FDR(EP0); + for (; buflen > 0; buflen--) + { + *buffer++ = (uint8_t)*fifo; + } +} + +/**************************************************************************** + * Name: sam_ep0_wrstatus + * + * Description: + * Process the next queued write request. + * + ****************************************************************************/ + +static void sam_ep0_wrstatus(const uint8_t *buffer, size_t buflen) +{ + volatile uint32_t *fifo; + + /* Write packet in the FIFO buffer */ + + fifo = (volatile uint32_t *)SAM_UDPEP_FDR(EP0); + for (; buflen > 0; buflen--) + { + *fifo = (uint32_t)(*buffer++); + } + + /* Set TXPKTRDY to notify the USB hardware that there is TX data in the + * endpoint FIFO. We will be notified that the endpoint’s FIFO has been + * released by the USB device when TXCOMP in the endpoint’s UDPEP_CSRx + * register has been set. + */ + + sam_csr_setbits(EP0, UDPEP_CSR_TXPKTRDY); +} + +/**************************************************************************** + * Name: sam_ep0_dispatch + ****************************************************************************/ + +static void sam_ep0_dispatch(struct sam_usbdev_s *priv) +{ + uint8_t *dataout; + size_t outlen; + int ret; + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Assume IN SETUP (or OUT SETUP with no data) */ + + dataout = NULL; + outlen = 0; + + /* Was this an OUT SETUP command? */ + + if (USB_REQ_ISOUT(priv->ctrl.type)) + { + uint16_t tmplen = GETUINT16(priv->ctrl.len); + if (tmplen > 0) + { + dataout = priv->ep0out; + outlen = tmplen; + } + } + + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, + dataout, outlen); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DISPATCHSTALL), 0); + (void)sam_ep_stall(&priv->eplist[EP0]); + } + } +} + +/**************************************************************************** + * Name: sam_setdevaddr + * + * Description: + * This function is called after the completion of the STATUS phase to + * instantiate the device address that was received during the SETUP + * phase. This enters the ADDRESSED state from either the DEFAULT or the + * CONFIGURED states. + * + * If called with address == 0, then function will revert to the DEFAULT, + * un-configured and un-addressed state. + * + ****************************************************************************/ + +static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t address) +{ + uint32_t regval; + + DEBUGASSERT(address <= 0x7f); + if (address) + { + /* Enable the address */ + + regval = UDP_FADDR(address) | UDP_FADDR_FEN; + sam_putreg(regval, SAM_UDP_FADDR); + + /* Go to the addressed but not configured state */ + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval |= UDP_GLBSTAT_FADDEN; + regval &= ~UDP_GLBSTAT_CONFG; + sam_putreg(regval, SAM_UDP_GLBSTAT); + + priv->devstate = UDP_DEVSTATE_ADDRESSED; + } + else + { + /* Set address to zero. The FEN bit still must be set in order to + * receive or send data packets from or to the host. + */ + + sam_putreg(UDP_FADDR_FEN, SAM_UDP_FADDR); + + /* Make sure that we are not in either the configured or addressed + * states + */ + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval &= ~(UDP_GLBSTAT_FADDEN | UDP_GLBSTAT_CONFG); + sam_putreg(regval, SAM_UDP_GLBSTAT); + + /* Revert to the un-addressed, default state */ + + priv->devstate = UDP_DEVSTATE_DEFAULT; + } +} + +/**************************************************************************** + * Name: sam_ep0_setup + ****************************************************************************/ + +static void sam_ep0_setup(struct sam_usbdev_s *priv) +{ + struct sam_ep_s *ep0 = &priv->eplist[EP0]; + struct sam_ep_s *privep; + union wb_u value; + union wb_u index; + union wb_u len; + union wb_u response; + enum sam_ep0setup_e ep0result; + uint8_t epno; + int nbytes = 0; /* Assume zero-length packet */ + int ret; + + /* Terminate any pending requests */ + + sam_req_cancel(ep0, -EPROTO); + + /* Assume NOT stalled; no TX in progress */ + + ep0->stalled = false; + ep0->pending = false; + ep0->epstate = UDP_EPSTATE_IDLE; + + /* And extract the little-endian 16-bit values to host order */ + + value.w = GETUINT16(priv->ctrl.value); + index.w = GETUINT16(priv->ctrl.index); + len.w = GETUINT16(priv->ctrl.len); + + ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + + /* Dispatch any non-standard requests */ + + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standard requests */ + + sam_ep0_dispatch(priv); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + ep0result = UDP_EP0SETUP_SUCCESS; + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), 0); + ep0result = UDP_EP0SETUP_STALL; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPGETSTATUS), epno); + if (epno >= SAM_UDP_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), epno); + ep0result = UDP_EP0SETUP_STALL; + } + else + { + privep = &priv->eplist[epno]; + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ + + if (privep->stalled) + { + /* Endpoint stalled */ + + response.b[LSB] = 1; /* Stalled */ + } + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADDEVGETSTATUS), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSTATUS), 0); + ep0result = UDP_EP0SETUP_STALL; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* Let the class implementation handle all recipients (except for the + * endpoint recipient) + */ + + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + else + { + /* Endpoint recipient */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_UDP_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = false; + + ret = sam_ep_resume(privep); + if (ret < 0) + { + ep0result = UDP_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADCLEARFEATURE), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETFEATURE), priv->ctrl.type); + if (((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + ullvdbg("test mode: %d\n", index.w); + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* The class driver handles all recipients except recipient=endpoint */ + + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + else + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_UDP_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = true; + + ret = sam_ep_stall(privep); + if (ret < 0) + { + ep0result = UDP_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETFEATURE), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETADDRESS), 0); + ep0result = UDP_EP0SETUP_STALL; + } + else + { + /* Note that setting of the device address will be deferred. A + * zero-length packet will be sent and the device address will + * be set when the zero-length packet transfer completes. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPSETADDRESS), value.w); + priv->devaddr = value.w; + ep0result = UDP_EP0SETUP_ADDRESS; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSETDESC), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETCONFIG), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index.w == 0 && len.w == 0) + { + /* The request seems valid... let the class implementation handle it. + * If the class implementation accepts it new configuration, it will + * call sam_ep_configure() to configure the endpoints. + */ + + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETCONFIG), 0); + ep0result = UDP_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETIF), priv->ctrl.type); + sam_ep0_dispatch(priv); + ep0result = UDP_EP0SETUP_DISPATCHED; + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); + ep0result = UDP_EP0SETUP_STALL; + } + break; + } + + /* Restrict the data length to the length requested in the setup packet */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* At this point, the request has been handled and there are three + * (or four) possible outcomes: + * + * 1a. ep0result == UDP_EP0SETUP_SUCCESS + * + * The setup request was successfully handled above and a response + * packet must be sent (may be a zero length packet). + * + * 1b. ep0result == UDP_EP0SETUP_ADDRESS + * + * A special case is the case where epstate=UDP_EPSTATE_EP0ADDRESS. + * This means that the above processing generated an additional state + * where we need to wait until we complete the status phase before + * applying the new device address. + * + * 2. ep0result == UDP_EP0SETUP_DISPATCHED; + * + * The request was forwarded to the class implementation. In case, + * EP0 IN data may have already been sent and the EP0 IN response + * has already been queued? Or perhaps the endpoint has already + * been stalled? This is all under the control of the class driver. + * + * NOTE that for the case of non-standard SETUP requested, those + * requests were forwarded to the class driver and we don't even get + * to this logic. + * + * 3. ep0result == UDP_EP0SETUP_STALL; + * + * An error was detected in either the above logic or by the class + * implementation logic. + */ + + switch (ep0result) + { + case UDP_EP0SETUP_SUCCESS: + { + /* Send the response (might be a zero-length packet) */ + + ep0->epstate = UDP_EPSTATE_EP0STATUSIN; + sam_ep0_wrstatus(response.b, nbytes); + } + break; + + case UDP_EP0SETUP_ADDRESS: + { + /* Send the response (might be a zero-length packet) */ + + ep0->epstate = UDP_EPSTATE_EP0ADDRESS; + sam_ep0_wrstatus(response.b, nbytes); + } + break; + + case UDP_EP0SETUP_STALL: + { + /* Stall EP0 */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPSTALLED), + priv->ctrl.req); + + (void)sam_ep_stall(&priv->eplist[EP0]); + } + break; + + case UDP_EP0SETUP_DISPATCHED: + default: + break; + } +} + +/**************************************************************************** + * Name: sam_ep_bankinterrupt + * + * Description: + * OUT data has been received on either bank 0 or bank 1 + * + ****************************************************************************/ + +static void sam_ep_bankinterrupt(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + uint32_t csr, int bank) +{ + uint32_t eptype; + uint16_t pktsize; + uint8_t epno; + + /* Get the endpoint type */ + + eptype = csr & UDPEP_CSR_EPTYPE_MASK; + epno = USB_EPNO(privep->ep.eplog); + + /* Are we receiving data for a read request? EP0 does not receive data + * using read requests. + */ + + if (privep->epstate == UDP_EPSTATE_IDLE && epno != 0) + { + /* Yes, get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((csr & UDPEP_CSR_RXBYTECNT_MASK) >> UDPEP_CSR_RXBYTECNT_SHIFT); + + /* And continue processing the read request. sam_req_read will + * clear the RXDATABK1 interrupt once that data has been + * transferred from the FIFO. + */ + + privep->epstate = UDP_EPSTATE_IDLE; + (void)sam_req_read(priv, privep, pktsize, bank); + } + + /* Did we just receive the data associated with an OUT SETUP command? */ + + else if (privep->epstate == UDP_EPSTATE_EP0DATAOUT) + { + uint16_t len; + + DEBUGASSERT(epno == EP0 && bank == 0); + + /* Yes.. back to the IDLE state */ + + privep->epstate = UDP_EPSTATE_IDLE; + + /* Get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((csr & UDPEP_CSR_RXBYTECNT_MASK) >> UDPEP_CSR_RXBYTECNT_SHIFT); + + /* Get the size that we expected to receive */ + + len = GETUINT16(priv->ctrl.len); + if (len == pktsize) + { + /* Copy the OUT data from the EP0 FIFO into a special EP0 buffer. */ + + sam_ep0_read(priv->ep0out, len); + + /* Clear the RX Data Bank 0 interrupt (should not be bank 1!). */ + + sam_csr_clrbits(EP0, UDPEP_CSR_RXDATABK0); + + /* And handle the EP0 SETUP now. */ + + sam_ep0_setup(priv); + } + else + { + /* Clear the RX Data Bank 0 interrupt (should not be bank 1!). + * Then stall. + */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPOUTSIZE), pktsize); + sam_csr_clrbits(EP0, UDPEP_CSR_RXDATABK0); + (void)sam_ep_stall(privep); + } + } + + /* Check for a EP0 STATUS packet returned by the host at the end of a + * SETUP status phase + */ + + else if (eptype == UDPEP_CSR_EPTYPE_CTRL && + (csr & UDPEP_CSR_RXBYTECNT_MASK) == 0) + { + DEBUGASSERT(epno == EP0 && bank == 0); + + /* Clear the RX Data Bank 0 interrupt */ + + sam_csr_clrbits(EP0, UDPEP_CSR_RXDATABK0); + } + + /* Otherwise there is a problem. Complain an clear the interrupt */ + + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_RXDATABKERR), privep->epstate); + sam_csr_clrbits(epno, bank ? UDPEP_CSR_RXDATABK1 : UDPEP_CSR_RXDATABK0); + } +} + +/**************************************************************************** + * Name: sam_ep_interrupt + * + * Description: + * Handle the UDP endpoint interrupt + * + ****************************************************************************/ + +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno) +{ + struct sam_ep_s *privep; + uintptr_t regaddr; + uint32_t csr; + + DEBUGASSERT((unsigned)epno < SAM_UDP_NENDPOINTS); + + /* Get the endpoint structure */ + + privep = &priv->eplist[epno]; + + /* Get the endpoint status */ + + regaddr = SAM_UDPEP_CSR(epno); + csr = sam_getreg(regaddr); + + /* TXCOMP: IN packet sent and acknowledged by the host */ + + if ((csr & UDPEP_CSR_TXCOMP) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_TXCOMP), (uint16_t)csr); + + /* Clear the TXCOMP interrupt */ + + sam_csr_clrbits(epno, UDPEP_CSR_TXCOMP); + + /* Sending state. This is the completion of a "normal" write request + * transfer. In this case, we need to resume request processing in + * order to send the next outgoing packet. + */ + + if (privep->epstate == UDP_EPSTATE_SENDING || + privep->epstate == UDP_EPSTATE_EP0STATUSIN) + { + /* Continue/resume processing the write requests */ + + privep->epstate = UDP_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + + /* Setting of the device address is a special case. The address was + * obtained when a preceding SETADDRESS SETUP command was processed. + * But the address is not set until the final SETUP status phase + * completes. This interrupt indicates the completion of that status + * phase and now we set the address. + */ + + else if (privep->epstate == UDP_EPSTATE_EP0ADDRESS) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ADDRESSED), priv->devaddr); + DEBUGASSERT(epno == EP0); + + /* Set the device address */ + + privep->epstate = UDP_EPSTATE_IDLE; + sam_setdevaddr(priv, priv->devaddr); + } + else + { + /* Unexpected TXCOMP interrupt */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_TXCOMPERR), privep->epstate); + } + } + + /* OUT packet received in data bank 0 */ + + if ((csr & UDPEP_CSR_RXDATABK0) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXDATABK0), (uint16_t)csr); + + /* Handle data received on Bank 0. sam_ep_bankinterrupt will + * clear the RXDATABK0 interrupt once that data has been + * transferred from the FIFO. + */ + + sam_ep_bankinterrupt(priv, privep, csr, 0); + } + + /* OUT packet received in data bank 1 */ + + else if ((csr & UDPEP_CSR_RXDATABK1) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXDATABK1), (uint16_t)csr); + DEBUGASSERT(SAM_UDP_NBANKS(epno) > 1); + + /* Handle data received on Bank 1. sam_ep_bankinterrupt will + * clear the RXDATABK1 interrupt once that data has been + * transferred from the FIFO. + */ + + sam_ep_bankinterrupt(priv, privep, csr, 1); + } + + /* STALL sent */ + + if ((csr & UDPEP_CSR_STALLSENT) != 0) + { +#ifdef CONFIG_USBDEV_ISOCHRONOUS + uint32_t eptype; +#endif + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_STALLSNT), (uint16_t)csr); + + /* Clear the STALLSENT interrupt */ + + sam_csr_clrbits(epno, UDPEP_CSR_STALLSENT); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + /* Get the endpoint type */ + + eptype = csr & UDPEP_CSR_EPTYPE_MASK; + + /* ISO error */ + + if (eptype == UDPEP_CSR_EPTYPE_ISOIN || eptype == UDPEP_CSR_EPTYPE_ISOOUT) + { + privep->epstate = UDP_EPSTATE_IDLE; + sam_req_complete(privep, -EIO); + } + else +#endif + + /* If EP is not halted, clear STALL */ + + if (privep->epstate != UDP_EPSTATE_STALLED) + { + sam_csr_clrbits(epno, UDPEP_CSR_FORCESTALL); + } + } + + /* SETUP packet received */ + + if ((csr & UDPEP_CSR_RXSETUP) != 0) + { + uint16_t len; + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXSETUP), (uint16_t)csr); + + /* If a write request transfer was pending, complete it. */ + + if (privep->epstate == UDP_EPSTATE_SENDING) + { + sam_req_complete(privep, -EPROTO); + } + + /* Copy SETUP data from the EP0 FIFO into the driver structure. */ + + sam_ep0_read((uint8_t *)&priv->ctrl, USB_SIZEOF_CTRLREQ); + + /* Check for a SETUP IN transaction with data. */ + + len = GETUINT16(priv->ctrl.len); + if (USB_REQ_ISOUT(priv->ctrl.type) && len > 0) + { + /* Yes.. then we have to wait for the OUT data phase to complete + * before processing the SETUP command. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPOUT), priv->ctrl.req); + privep->epstate = UDP_EPSTATE_EP0DATAOUT; + + /* Clear the CSR:DIR bit to support the host-to-device data OUT + * data transfer. This bit must be cleared before CSR:RXSETUP is + * cleared at the end of the SETUP stage. + * + * NOTE: Clearing this bit seems to be unnecessary. I think it must + * be cleared when RXSETUP is set. + */ + + sam_csr_clrbits(epno, UDPEP_CSR_DIR); + + /* Clear the RXSETUP indication. RXSETUP cannot be cleared before the + * SETUP packet has been read in from the FIFO. Otherwise, the USB + * device would accept the next Data OUT transfer and overwrite the + * SETUP packet in the FIFO. + */ + + sam_csr_clrbits(epno, UDPEP_CSR_RXSETUP); + } + else + { + /* This is an SETUP IN command (or a SETUP IN with no data). */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPIN), len); + privep->epstate = UDP_EPSTATE_IDLE; + + /* Set the CSR:DIR bit to support the device-to-host data IN + * data transfer. This bit must be set before CSR:RXSETUP is + * cleared at the end of the SETUP stage. + */ + + sam_csr_setbits(epno, UDPEP_CSR_DIR); + + /* Clear the RXSETUP indication. */ + + sam_csr_clrbits(epno, UDPEP_CSR_RXSETUP); + + /* Handle the SETUP OUT command now */ + + sam_ep0_setup(priv); + } + } +} + +/**************************************************************************** + * Name: sam_udp_interrupt + * + * Description: + * Handle the UDP interrupt + * + ****************************************************************************/ + +static int sam_udp_interrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple UDP controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udp; + uint32_t isr; + uint32_t pending; + uint32_t regval; + int i; + + /* Get the set of pending interrupts */ + + isr = sam_getreg(SAM_UDP_ISR); + usbtrace(TRACE_INTENTRY(SAM_TRACEINTID_INTERRUPT), isr); + + regval = sam_getreg(SAM_UDP_IMR); + pending = isr & regval; + + /* Handle all pending UDP interrupts (and new interrupts that become + * pending) + */ + + while (pending) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_PENDING), (uint16_t)pending); + + /* Suspend, treated last */ + + if (pending == UDP_INT_RXSUSP) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXSUSP), + (uint16_t)pending); + + /* Enable wakeup interrupts */ + + sam_putreg(UDP_INT_RXSUSP, SAM_UDP_IDR); + sam_putreg(UDP_INT_WAKEUP | UDP_INT_RXRSM, SAM_UDP_IER); + + /* Clear the pending suspend (and any wakeup) interrupts */ + + sam_putreg(UDP_INT_RXSUSP | UDP_INT_WAKEUP, SAM_UDP_ICR); + + /* Perform board-specific suspend operations. The USB device + * peripheral clocks can be switched off. Resume event is + * asynchronously detected. MCK and UDPCK can be switched off in + * the Power Management controller and the USB transceiver can + * be disabled by setting the TXVDIS field in the UDP_TXVC + * register. Other board-specific operations could also be + * performed. + */ + + sam_suspend(priv); + } + + /* SOF interrupt */ + + else if ((pending & UDP_INT_SOF) != 0) + { + /* Clear the pending SOF interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SOF), + (uint16_t)pending); + sam_putreg(UDP_INT_SOF, SAM_UDP_ICR); + } + + /* Resume or wakeup. REVISIT: Treat the same? */ + + else if ((pending & (UDP_INT_WAKEUP | UDP_INT_RXRSM)) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_WAKEUP), + (uint16_t)pending); + sam_resume(priv); + + /* Clear the pending wakeup, resume, (and any suspend) interrupts */ + + sam_putreg(UDP_INT_WAKEUP | UDP_INT_RXRSM | UDP_INT_RXSUSP, + SAM_UDP_ICR); + + /* Enable suspend interrupts */ + + sam_putreg(UDP_INT_WAKEUP | UDP_INT_RXRSM, SAM_UDP_IDR); + sam_putreg(UDP_INT_RXSUSP, SAM_UDP_IER); + } + + /* End of Reset. Set by hardware when an End Of Reset has been + * detected by the UDP controller. Automatically enabled after USB + * reset. + * + * "After its connection to a USB host, the USB device waits for an + * end-of-bus reset. The unmaskable flag ENDBUSRES is set in the + * register UDP_ISR and an interrupt is triggered. Once the + * ENDBUSRES interrupt has been triggered, the device enters Default + * State. In this state, the UDP software must: + * + * - "Enable the default endpoint, setting the EPEDS flag in the + * UDPEP_CSR[0] register and, optionally, enabling the interrupt + * for endpoint 0 by writing 1 to the UDP_IER register. The + * enumeration then begins by a control transfer. + * - "Configure the interrupt mask register which has been reset by + * the USB reset detection + * - "Enable the transceiver clearing the TXVDIS flag in the UDP_TXVC + * register. + * + * In this state UDPCK and MCK must be enabled. + * + * Warning: Each time an ENDBUSRES interrupt is triggered, the Interrupt + * Mask Register and UDPEP_CSR registers have been reset. + */ + + if ((pending & UDP_ISR_ENDBUSRES) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ENDBUSRES), + (uint16_t)pending); + + /* Clear the end-of-reset interrupt */ + + sam_putreg(UDP_ISR_ENDBUSRES, SAM_UDP_ICR); + + /* Handle the reset */ + + sam_reset(priv); + + /* Set the device speed */ + + priv->usbdev.speed = USB_SPEED_FULL; + } + + /* Endpoint Interrupts */ + + else if ((pending & UDP_INT_EP_MASK) != 0) + { + for (i = 0; i < SAM_UDP_NENDPOINTS; i++) + { + if ((pending & UDP_INT_EP(i)) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP), (uint16_t)i); + sam_ep_interrupt(priv, i); + } + } + } + + /* Re-sample the set of pending interrupts */ + + isr = sam_getreg(SAM_UDP_ISR); + regval = sam_getreg(SAM_UDP_IMR); + pending = isr & regval; + } + + usbtrace(TRACE_INTEXIT(SAM_TRACEINTID_INTERRUPT), isr); + return OK; +} + +/**************************************************************************** + * Name: sam_suspend + * + * Description: + * Sets the specified bit(s) in the UDPEP_CSR register. + * + ****************************************************************************/ + +static void sam_csr_setbits(uint8_t epno, uint32_t setbits) +{ + uintptr_t regaddr; + uint32_t regval; + int count; + + /* Set the specified bits */ + + regaddr = SAM_UDPEP_CSR(epno); + regval = sam_getreg(regaddr); + regval |= CSR_NOEFFECT_BITS; + regval |= setbits; + sam_putreg(regval, regaddr); + + /* Followed by 15 nops (plus loop overhead). After any bit is changed in + * the CSR, a wait of 1 UDPCK clock cycle and 1 peripheral clock cycle is + * required. However, RX_DATA_BK0, TXPKTRDY, RX_DATA_BK1 require wait + * times of 3 UDPCK clock cycles and 5 peripheral clock cycles before + * accessing DPR. + */ + + for (count = 0; count < 15; count++) + { + nop(); + } +} + +/**************************************************************************** + * Name: sam_suspend + * + * Description: + * Clears the specified bit(s) in the UDPEP_CSR register. + * + ****************************************************************************/ + +static void sam_csr_clrbits(uint8_t epno, uint32_t clrbits) +{ + uintptr_t regaddr; + uint32_t regval; + int count; + + /* Clear the specified bits */ + + regaddr = SAM_UDPEP_CSR(epno); + regval = sam_getreg(regaddr); + regval |= CSR_NOEFFECT_BITS; + regval &= ~clrbits; + sam_putreg(regval, regaddr); + + /* Followed by 15 nops (plus loop overhead). After any bit is changed in + * the CSR, a wait of 1 UDPCK clock cycle and 1 peripheral clock cycle is + * required. However, RX_DATA_BK0, TXPKTRDY, RX_DATA_BK1 require wait + * times of 3 UDPCK clock cycles and 5 peripheral clock cycles before + * accessing DPR. + */ + + for (count = 0; count < 15; count++) + { + nop(); + } +} + +/**************************************************************************** + * Suspend/Resume Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_suspend + ****************************************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv) +{ + /* Don't do anything if the device is already suspended */ + + if (priv->devstate != UDP_DEVSTATE_SUSPENDED) + { + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* Switch to the Suspended state */ + + priv->prevstate = priv->devstate; + priv->devstate = UDP_DEVSTATE_SUSPENDED; + + /* Disable clocking to the UDP peripheral */ + + sam_disableclks(); + + /* Let the board-specific logic know that we have entered the + * suspend state. This may trigger additional reduced power + * consumption measures. + */ + + sam_udp_suspend((struct usbdev_s *)priv, false); + } +} + +/**************************************************************************** + * Name: sam_resume + ****************************************************************************/ + +static void sam_resume(struct sam_usbdev_s *priv) +{ + /* This function is called when either (1) a WKUP interrupt is received from + * the host PC, or (2) the class device implementation calls the wakeup() + * method. + */ + + /* Don't do anything if the device was not suspended */ + + if (priv->devstate == UDP_DEVSTATE_SUSPENDED) + { + /* Revert to the previous state */ + + priv->devstate = priv->prevstate; + + /* Restore clocking to the UDP peripheral */ + + sam_enableclks(); + + /* Restore full power -- whatever that means for this particular board */ + + sam_udp_suspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + } +} + +/**************************************************************************** + * Endpoint Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ep_reset + * + * Description + * Reset and disable one endpoints. + * + ****************************************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno) +{ + struct sam_ep_s *privep = &priv->eplist[epno]; + + /* Disable endpoint interrupt */ + + sam_putreg(UDP_INT_EP(epno), SAM_UDP_IDR); + + /* Cancel any queued requests. Since they are cancelled with status + * -ESHUTDOWN, then will not be requeued until the configuration is reset. + * NOTE: This should not be necessary... the CLASS_DISCONNECT above + * should result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Reset the endpoint FIFO */ + + sam_putreg(UDP_RSTEP(epno), SAM_UDP_RSTEP); + sam_putreg(0, SAM_UDP_RSTEP); + + /* Reset endpoint status */ + + privep->epstate = UDP_EPSTATE_DISABLED; + privep->stalled = false; + privep->pending = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + privep->txbusy = false; +} + +/**************************************************************************** + * Name: sam_epset_reset + * + * Description + * Reset and disable a set of endpoints. + * + ****************************************************************************/ + +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset) +{ + uint32_t bit; + int epno; + + /* Reset each endpoint in the set */ + + for (epno = 0, bit = 1, epset &= SAM_EPSET_ALL; + epno < SAM_UDP_NENDPOINTS && epset != 0; + epno++, bit <<= 1) + { + /* Is this endpoint in the set? */ + + if ((epset & bit) != 0) + { + /* Yes.. reset and disable it */ + + sam_ep_reset(priv, epno); + epset &= ~bit; + } + } +} + +/**************************************************************************** + * Name: sam_ep_stall + ****************************************************************************/ + +static int sam_ep_stall(struct sam_ep_s *privep) +{ + irqstate_t flags; + uint8_t epno; + + /* Check that endpoint is in Idle state */ + + DEBUGASSERT(/* privep->epstate == UDP_EPSTATE_IDLE && */ privep->dev); + + /* Check that endpoint is enabled and not already in Halt state */ + + flags = enter_critical_section(); + if ((privep->epstate != UDP_EPSTATE_DISABLED) && + (privep->epstate != UDP_EPSTATE_STALLED)) + { + epno = USB_EPNO(privep->ep.eplog); + usbtrace(TRACE_EPSTALL, epno); + + /* If this is an IN endpoint (or endpoint 0), then cancel any + * write requests in progress. + */ + + if (epno == 0 || USB_ISEPIN(privep->ep.eplog)) + { + sam_req_cancel(privep, -EPERM); + } + + /* Put endpoint into stalled state */ + + privep->epstate = UDP_EPSTATE_STALLED; + privep->stalled = true; + privep->pending = false; + + sam_csr_setbits(epno, UDPEP_CSR_FORCESTALL); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_resume + ****************************************************************************/ + +static int sam_ep_resume(struct sam_ep_s *privep) +{ + struct sam_usbdev_s *priv; + struct sam_req_s *req; + irqstate_t flags; + uint8_t epno; + + /* Check that endpoint is in Idle state */ + + DEBUGASSERT(/* privep->epstate == UDP_EPSTATE_IDLE && */ privep->dev); + + flags = enter_critical_section(); + + /* Check if the endpoint is stalled */ + + if (privep->epstate == UDP_EPSTATE_STALLED) + { + epno = USB_EPNO(privep->ep.eplog); + usbtrace(TRACE_EPRESUME, epno); + + priv = (struct sam_usbdev_s *)privep->dev; + + /* Return endpoint to Idle state */ + + privep->stalled = false; + privep->pending = false; + privep->epstate = UDP_EPSTATE_IDLE; + + /* Clear FORCESTALL request */ + + sam_csr_clrbits(epno, UDPEP_CSR_FORCESTALL); + + /* Reset the endpoint FIFO */ + + sam_putreg(UDP_RSTEP(epno), SAM_UDP_RSTEP); + sam_putreg(0, SAM_UDP_RSTEP); + + /* Copy any requests in the pending request queue to the working + * request queue. + */ + + while ((req = sam_req_dequeue(&privep->pendq)) != NULL) + { + sam_req_enqueue(&privep->reqq, req); + } + + /* Resuming any blocked data transfers on the endpoint */ + + if (epno == 0 || USB_ISEPIN(privep->ep.eplog)) + { + /* IN endpoint (or EP0). Restart any queued write requests */ + + (void)sam_req_write(priv, privep); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_reserve + * + * Description: + * Find and un-reserved endpoint number and reserve it for the caller. + * + ****************************************************************************/ + +static inline struct sam_ep_s * +sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset) +{ + struct sam_ep_s *privep = NULL; + irqstate_t flags; + int epndx = 0; + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints + * (skipping EP0) + */ + + for (epndx = 1; epndx < SAM_UDP_NENDPOINTS; epndx++) + { + uint8_t bit = SAM_EP_BIT(epndx); + if ((epset & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail &= ~bit; + + /* And return the pointer to the standard endpoint structure */ + + privep = &priv->eplist[epndx]; + break; + } + } + } + + leave_critical_section(flags); + return privep; +} + +/**************************************************************************** + * Name: sam_ep_unreserve + * + * Description: + * The endpoint is no long in-used. It will be unreserved and can be + * re-used if needed. + * + ****************************************************************************/ + +static inline void +sam_ep_unreserve(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= SAM_EP_BIT(USB_EPNO(privep->ep.eplog)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_ep_reserved + * + * Description: + * Check if the endpoint has already been allocated. + * + ****************************************************************************/ + +static inline bool +sam_ep_reserved(struct sam_usbdev_s *priv, int epno) +{ + return ((priv->epavail & SAM_EP_BIT(epno)) == 0); +} + +/**************************************************************************** + * Name: sam_ep_configure_internal + * + * Description: + * This is the internal implementation of the endpoint configuration logic + * and implements the endpoint configuration method of the usbdev_ep_s + * interface. As an internal interface, it will be used to configure + * endpoint 0 which is not available to the class implementation. + * + ****************************************************************************/ + +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc) +{ + uintptr_t csr; + uint32_t regval; + uint16_t maxpacket; + uint8_t epno; + uint8_t eptype; + bool dirin; + + DEBUGASSERT(privep && privep->dev && desc); + + uvdbg("len: %02x type: %02x addr: %02x attr: %02x " + "maxpacketsize: %02x %02x interval: %02x\n", + desc->len, desc->type, desc->addr, desc->attr, + desc->mxpacketsize[0], desc->mxpacketsize[1], + desc->interval); + + /* Decode the endpoint descriptor */ + + epno = USB_EPNO(desc->addr); + dirin = (desc->addr & USB_DIR_MASK) == USB_REQ_DIR_IN; + eptype = (desc->attr & USB_EP_ATTR_XFERTYPE_MASK); + maxpacket = GETUINT16(desc->mxpacketsize); + + DEBUGASSERT(maxpacket <= SAM_UDP_MAXPACKETSIZE(epno)); + + /* Initialize the endpoint structure */ + + privep->ep.eplog = desc->addr; /* Includes direction */ + privep->ep.maxpacket = maxpacket; + privep->epstate = UDP_EPSTATE_IDLE; + + /* Initialize the endpoint hardware */ + /* Disable the endpoint */ + + csr = SAM_UDPEP_CSR(epno); + sam_putreg(0, csr); + + /* Reset the endpoint FIFO */ + + sam_putreg(UDP_RSTEP(epno), SAM_UDP_RSTEP); + sam_putreg(0, SAM_UDP_RSTEP); + + /* Disable endpoint interrupts now */ + + sam_putreg(UDP_INT_EP(epno), SAM_UDP_IDR); + + /* Configure and enable the endpoint */ + + regval = UDPEP_CSR_EPEDS; + switch (eptype) + { + case USB_EP_ATTR_XFER_CONTROL: + if (!SAM_UDP_CONTROL(epno)) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_UNSUPPEPTYPE), + eptype >> USB_EP_ATTR_XFERTYPE_SHIFT); + return -ENOSYS; + } + else + { + regval |= UDPEP_CSR_EPTYPE_CTRL; + } + break; + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + case USB_EP_ATTR_XFER_ISOC: + if (!SAM_UDP_ISOCHRONOUS(epno)) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_UNSUPPEPTYPE), + eptype >> USB_EP_ATTR_XFERTYPE_SHIFT); + return -ENOSYS; + } + else if (dirin) + { + regval |= UDPEP_CSR_EPTYPE_ISOIN; + } + else + { + regval |= UDPEP_CSR_EPTYPE_ISOOUT; + } + break; +#endif + + case USB_EP_ATTR_XFER_BULK: + if (!SAM_UDP_BULK(epno)) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_UNSUPPEPTYPE), + eptype >> USB_EP_ATTR_XFERTYPE_SHIFT); + return -ENOSYS; + } + else if (dirin) + { + regval |= UDPEP_CSR_EPTYPE_BULKIN; + } + else + { + regval |= UDPEP_CSR_EPTYPE_BULKOUT; + } + break; + + case USB_EP_ATTR_XFER_INT: + if (!SAM_UDP_INTERRUPT(epno)) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_UNSUPPEPTYPE), + eptype >> USB_EP_ATTR_XFERTYPE_SHIFT); + return -ENOSYS; + } + else if (dirin) + { + regval |= UDPEP_CSR_EPTYPE_INTIN; + } + else + { + regval |= UDPEP_CSR_EPTYPE_INTOUT; + } + break; + + default: + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPTYPE), + eptype >> USB_EP_ATTR_XFERTYPE_SHIFT); + return -EINVAL; + } + + sam_putreg(regval, csr); + + /* Enable endpoint interrupts */ + + sam_putreg(UDP_INT_EP(epno), SAM_UDP_IER); + sam_dumpep(privep->dev, epno); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep_configure + * + * Description: + * This is the endpoint configuration method of the usbdev_ep_s interface. + * + ****************************************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + int ret; + + /* Verify parameters. Endpoint 0 is not available at this interface */ + +#if defined(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE) + uint8_t epno = USB_EPNO(desc->addr); + usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno); + + DEBUGASSERT(ep && desc && epno > 0 && epno < SAM_UDP_NENDPOINTS); + DEBUGASSERT(epno == USB_EPNO(ep->eplog)); +#endif + + /* This logic is implemented in sam_ep_configure_internal */ + + ret = sam_ep_configure_internal(privep, desc); + + /* If this was the last endpoint, then the class driver is fully + * configured. + */ + + if (ret == OK && last) + { + struct sam_usbdev_s *priv = privep->dev; + uint32_t regval; + + /* Go to the configured state (we should have been in the addressed + * state) + */ + + DEBUGASSERT(priv && priv->devstate == UDP_DEVSTATE_ADDRESSED); + priv->devstate = UDP_DEVSTATE_CONFIGURED; + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval |= UDP_GLBSTAT_CONFG; + sam_putreg(regval, SAM_UDP_GLBSTAT); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_ep_disable + * + * Description: + * This is the disable() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_disable(struct usbdev_ep_s *ep) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p\n", ep); + return -EINVAL; + } +#endif + + epno = USB_EPNO(ep->eplog); + usbtrace(TRACE_EPDISABLE, epno); + + /* Reset the endpoint and cancel any ongoing activity */ + + flags = enter_critical_section(); + priv = privep->dev; + sam_ep_reset(priv, epno); + + /* Revert to the addressed-but-not-configured state */ + + sam_setdevaddr(priv, priv->devaddr); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_allocreq + * + * Description: + * This is the allocreq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static struct usbdev_req_s *sam_ep_allocreq(struct usbdev_ep_s *ep) +{ + struct sam_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, USB_EPNO(ep->eplog)); + + privreq = (struct sam_req_s *)kmm_malloc(sizeof(struct sam_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct sam_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: sam_ep_freereq + * + * Description: + * This is the freereq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static void sam_ep_freereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, USB_EPNO(ep->eplog)); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: sam_ep_allocbuffer + * + * Description: + * This is the allocbuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes) +{ + /* There is not special buffer allocation requirement */ + + return kumm_malloc(nbytes); +} +#endif + +/**************************************************************************** + * Name: sam_ep_freebuffer + * + * Description: + * This is the freebuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf) +{ + /* There is not special buffer allocation requirement */ + + kumm_free(buf); +} +#endif + +/**************************************************************************** + * Name: sam_ep_submit + * + * Description: + * This is the submit() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + ulldbg("ERROR: driver=%p\n", priv->driver); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + epno = USB_EPNO(ep->eplog); + req->result = -EINPROGRESS; + req->xfrd = 0; + privreq->inflight = 0; + flags = enter_critical_section(); + + /* Handle IN (device-to-host) requests. NOTE: If the class device is + * using the bi-directional EP0, then we assume that they intend the EP0 + * IN functionality (EP0 SETUP OUT data receipt does not use requests). + */ + + if (USB_ISEPIN(ep->eplog) || epno == EP0) + { + /* Check if the endpoint is stalled (or there is a stall pending) */ + + if (privep->stalled || privep->pending) + { + /* Yes.. in this case, save the new they will get in a special + * "pending" they will get queue until the stall is cleared. + */ + + ulldbg("Pending stall clear\n"); + sam_req_enqueue(&privep->pendq, privreq); + usbtrace(TRACE_INREQQUEUED(epno), req->len); + ret = OK; + } + + else + { + /* Add the new request to the request queue for the IN endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_INREQQUEUED(epno), req->len); + + /* If the IN endpoint is IDLE and there is not write queue + * processing in progress, then transfer the data now. + */ + + if (privep->epstate == UDP_EPSTATE_IDLE && !privep->txbusy) + { + ret = sam_req_write(priv, privep); + } + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_OUTREQQUEUED(epno), req->len); + + /* Check if we have stopped RX receipt due to lack of read + * read requests. If that is the case for this endpoint, then + * re-enable endpoint interrupts now. + */ + + if (privep->epstate == UDP_EPSTATE_RXSTOPPED) + { + /* Un-stop the OUT endpoint be re-enabling endpoint interrupts. + * There should be a pending RXDATABK0/1 interrupt or, if a long + * time has elapsed since the endpoint was stopped, an ENDBUSRES + * interrupt. + */ + + privep->epstate = UDP_EPSTATE_IDLE; + sam_putreg(UDP_INT_EP(epno), SAM_UDP_IER); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_ep_cancel + ****************************************************************************/ + +static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); + + flags = enter_critical_section(); + sam_req_cancel(privep, -EAGAIN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_stallresume + ****************************************************************************/ + +static int sam_ep_stallresume(struct usbdev_ep_s *ep, bool resume) +{ + struct sam_ep_s *privep; + uint8_t epno; + irqstate_t flags; + int ret; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Handle the resume condition */ + + privep = (struct sam_ep_s *)ep; + if (resume) + { + ret = sam_ep_resume(privep); + } + + /* Handle the stall condition */ + + else + { + /* If this is an IN endpoint (and not EP0) and if there are queued + * write requests, then we cannot stall now. Perhaps this is a + * protocol stall. In that case, we will need to drain the write + * requests before sending the stall. + */ + + flags = enter_critical_section(); + epno = USB_EPNO(ep->eplog); + if (epno != 0 && USB_ISEPIN(ep->eplog)) + { + /* Are there any unfinished write requests in the request queue? */ + + if (!sam_rqempty(&privep->reqq)) + { + /* Just set a flag to indicate that the endpoint must be + * stalled on the next TXCOMP interrupt when the request + * queue becomes empty. + */ + + privep->pending = true; + leave_critical_section(flags); + return OK; + } + } + + /* Not an IN endpoint, endpoint 0, or no pending write requests. + * Stall the endpoint now. + */ + + ret = sam_ep_stall(privep); + leave_critical_section(flags); + } + + return ret; +} + +/**************************************************************************** + * Device Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_allocep + * + * Description: + * This is the allocep() method of the USB device driver interface + * + ****************************************************************************/ + +static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno, + bool in, uint8_t eptype) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + struct sam_ep_s *privep = NULL; + uint16_t epset = SAM_EPSET_NOTEP0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epno >= SAM_UDP_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset = SAM_EP_BIT(epno); + } + + /* Check if the selected endpoint number is available */ + + privep = sam_ep_reserve(priv, epset); + if (!privep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPRESERVE), (uint16_t)epset); + return NULL; + } + + return &privep->ep; +} + +/**************************************************************************** + * Name: sam_freeep + * + * Description: + * This is the freeep() method of the USB device driver interface + * + ****************************************************************************/ + +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) +{ + struct sam_usbdev_s *priv; + struct sam_ep_s *privep; + +#ifdef CONFIG_DEBUG + if (!dev || !ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + priv = (struct sam_usbdev_s *)dev; + privep = (struct sam_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)USB_EPNO(ep->eplog)); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + sam_ep_unreserve(priv, privep); + } +} + +/**************************************************************************** + * Name: sam_getframe + * + * Description: + * This is the getframe() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + uint16_t frameno; + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Return the last frame number detected by the hardware */ + + regval = sam_getreg(SAM_UDP_FRMNUM); + frameno = (regval & UDP_FRMNUM_MASK) >> UDP_FRMNUM_SHIFT; + + usbtrace(TRACE_DEVGETFRAME, frameno); + return frameno; +} + +/**************************************************************************** + * Name: sam_wakeup + * + * Description: + * This is the wakeup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_wakeup(struct usbdev_s *dev) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + irqstate_t flags; + uint32_t regval; + + usbtrace(TRACE_DEVWAKEUP, 0); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Resume normal operation */ + + flags = enter_critical_section(); + sam_resume(priv); + + /* Activate a remote wakeup. Setting the Enable Send Resume (ESR) bit + * starts the Remote Wake Up procedure if this bit value was 0 and if + * RMWUPE is enabled. + * + * "In Suspend state it is possible to wake up the host sending an external + * resume. + * + * - "The device must wait at least 5 ms after being entered in suspend + * before sending an external resume. + * - "The device has 10 ms from the moment it starts to drain current and + * it forces a K state to resume the host. + * - "The device must force a K state from 1 to 15 ms to resume the host + * + * "Before sending a K state to the host, MCK, UDPCK and the transceiver + * must be enabled. Then to enable the remote wake-up feature, the RMWUPE bit + * in the UDP_GLB_STAT register must be enabled. To force the K state on the + * line, a transition of the ESR bit from 0 to 1 has to be done in the + * UDP_GLB_STAT register. This transition must be accomplished by first + * writing a 0 in the ESR bit and then writing a 1. + * + * " The K state is automatically generated and released according to the USB + * 2.0 specification." + */ + + /* Make sure that the ESR bit is zero */ + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval |= UDP_GLBSTAT_RMWUPE; /* Should already be set */ + regval &= ~UDP_GLBSTAT_ESR; + sam_putreg(regval, SAM_UDP_GLBSTAT); + + /* Wait 5msec in case we just entered the resume state */ + + usleep(5*1000); + + /* Set the ESR bit to send the remote resume */ + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval |= UDP_GLBSTAT_ESR; + sam_putreg(regval, SAM_UDP_GLBSTAT); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_selfpowered + * + * Description: + * This is the selfpowered() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: sam_pullup + * + * Description: + * This is the pullup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_pullup(FAR struct usbdev_s *dev, bool enable) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + /* Enable/disable the UDP pull-up resistor */ + + regval = sam_getreg(SAM_UDP_TXVC); + + if (enable) + { + /* Connect the 1.5 KOhm integrated pull-up on DDP */ + + regval |= UDP_TXVC_PUON; + } + else + { + /* Disconnect the 1.5 KOhm integrated pull-up on DDP */ + + regval &= ~UDP_TXVC_PUON; + + /* Device returns to the Powered state */ + + if (priv->devstate > UDP_DEVSTATE_POWERED) + { + priv->devstate = UDP_DEVSTATE_POWERED; + } + } + + sam_putreg(regval, SAM_UDP_TXVC); + return OK; +} + +/**************************************************************************** + * Initialization/Reset + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_reset + ****************************************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv) +{ + uint32_t regval; + uint8_t epno; + + /* Make sure that clocking is enabled to the UDP peripheral. */ + + sam_enableclks(); + + /* Tell the class driver that we are disconnected. The class driver + * should then accept any new configurations. + */ + + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + + /* The device enters the Default state (un-addressed and un-configured) */ + + priv->devaddr = 0; + sam_setdevaddr(priv, 0); + + priv->devstate = UDP_DEVSTATE_DEFAULT; + + /* Reset and disable all endpoints other. Then re-configure EP0 */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + sam_ep_configure_internal(&priv->eplist[EP0], &g_ep0desc); + + /* Reset endpoint data structures */ + + for (epno = 0; epno < SAM_UDP_NENDPOINTS; epno++) + { + struct sam_ep_s *privep = &priv->eplist[epno]; + + /* Cancel any queued requests. Since they are cancelled + * with status -ESHUTDOWN, then will not be requeued + * until the configuration is reset. NOTE: This should + * not be necessary... the CLASS_DISCONNECT above should + * result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->pending = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + privep->txbusy = false; + } + + /* Re-configure the USB controller in its initial, unconnected state */ + + priv->usbdev.speed = USB_SPEED_FULL; + + /* Clear all pending interrupt status */ + + regval = UDP_INT_WAKEUP | UDP_ISR_ENDBUSRES | UDP_INT_SOF | UDP_INT_RXSUSP; + sam_putreg(regval, SAM_UDP_ICR); + + /* Enable normal operational interrupts (including endpoint 0) */ + + regval = UDP_INT_WAKEUP | UDP_INT_RXSUSP | UDP_INT_EP0; + sam_putreg(regval, SAM_UDP_IER); + + sam_dumpep(priv, EP0); +} + +/**************************************************************************** + * Name: sam_enableclks + ****************************************************************************/ + +static void sam_enableclks(void) +{ + uint32_t regval; + + /* To use the UDP, the programmer must first configuration the USB clock + * input, in the PMC_UCKR register if the MCU has a UPLL or in the PMC_USB + * register if PLLA or PLLB is divided down to generated the clock. In + * either case, the UDP Clock must in the PMC_PCER register. + */ + + /* Set the UDP bit in the PMC_PCER1 register in order to enable the MCK + * clock to the UDP peripheral. This is necessary in order to access + * the UDP registers. + */ + + sam_udp_enableclk(); + + /* Set the UDP bit in the SCER register to enable the USB clock output + * to the UDP peripheral. + */ + + regval = getreg32(SAM_PMC_SCER); + regval |= PMC_UDP; + putreg32(regval, SAM_PMC_SCER); + + /* Make sure that the UDP transceiver is not disabled */ + + regval = getreg32(SAM_UDP_TXVC); + regval &= ~UDP_TXVC_TXVDIS; + putreg32(regval, SAM_UDP_TXVC); +} + +/**************************************************************************** + * Name: sam_disableclks + ****************************************************************************/ + +static void sam_disableclks(void) +{ + uint32_t regval; + + /* Disable the UDP transceiver */ + + regval = getreg32(SAM_UDP_TXVC); + regval |= UDP_TXVC_TXVDIS; + putreg32(regval, SAM_UDP_TXVC); + + /* Clear the UDP bit in the SCER register to disable the USB clock output */ + + regval = getreg32(SAM_PMC_SCER); + regval &= ~PMC_UDP; + putreg32(regval, SAM_PMC_SCER); + + /* Clear the UDP bit in the PMC_PCER1 register in order to disable the MCK + * clock to the UDP peripheral. We can no longer access UDP registers. + */ + + sam_udp_disableclk(); +} + +/**************************************************************************** + * Name: sam_hw_setup + ****************************************************************************/ + +static void sam_hw_setup(struct sam_usbdev_s *priv) +{ + uint32_t regval; + int i; + + /* To use the UDP, the programmer must first configuration the USB clock + * input, in the PMC_UCKR register if the MCU has a UPLL or in the PMC_USB + * register if PLLA or PLLB is divided down to generated the clock. In + * either case, the UDP Clock must in the PMC_PCER register. + */ + + sam_enableclks(); + + /* Configure PIO pins -- nothing needs to be done. + * + * By default, the USB function is activated and pins DDP and DDM are used + * for USB. The USB device interface also has an interrupt line for VBUS + * sensing that is connected to the Interrupt Controller. + */ + + /* Reset and disable endpoints */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + + /* Initialize Endpoints */ + + for (i = 0; i < SAM_UDP_NENDPOINTS; i++) + { + /* Reset endpoint configuration */ + + sam_putreg(0, SAM_UDPEP_CSR(i)); + } + + /* Enable the remote wakeup feature */ + + regval = sam_getreg(SAM_UDP_GLBSTAT); + regval |= UDP_GLBSTAT_RMWUPE; + sam_putreg(regval, SAM_UDP_GLBSTAT); + + /* Disable all interrupts */ + + sam_putreg(UDP_INT_ALL, SAM_UDP_IDR); + + /* Disable the 1.5 KOhm integrated pull-up on DDP and make sure that the UDP + * transceiver is not disabled + */ + + sam_putreg(0, SAM_UDP_TXVC); +} + +/**************************************************************************** + * Name: sam_sw_setup + ****************************************************************************/ + +static void sam_sw_setup(struct sam_usbdev_s *priv) +{ + int epno; + + /* Initialize the device state structure. NOTE: many fields + * have the initial value of zero and, hence, are not explicitly + * initialized here. + */ + + memset(priv, 0, sizeof(struct sam_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[EP0].ep; + priv->epavail = SAM_EPSET_ALL & ~SAM_EP_BIT(EP0); + priv->devstate = UDP_DEVSTATE_SUSPENDED; + priv->prevstate = UDP_DEVSTATE_POWERED; + + /* Initialize the endpoint list */ + + for (epno = 0; epno < SAM_UDP_NENDPOINTS; epno++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the (physical) endpoint number which is just the index to the + * endpoint. + */ + + priv->eplist[epno].ep.ops = &g_epops; + priv->eplist[epno].dev = priv; + priv->eplist[epno].ep.eplog = epno; + + /* We will use a maxpacket size for supported for each endpoint */ + + priv->eplist[epno].ep.maxpacket = SAM_UDP_MAXPACKETSIZE(epno); + } +} + +/**************************************************************************** + * Name: sam_hw_shutdown + ****************************************************************************/ + +static void sam_hw_shutdown(struct sam_usbdev_s *priv) +{ + uint32_t regval; + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable all interrupts */ + + sam_putreg(UDP_INT_ALL, SAM_UDP_IDR); + + /* Clear all pending interrupt status */ + + regval = UDP_INT_WAKEUP | UDP_ISR_ENDBUSRES | UDP_INT_SOF | UDP_INT_RXSUSP; + sam_putreg(regval, SAM_UDP_ICR); + + /* Disconnect the device / disable the pull-up */ + + sam_pullup(&priv->usbdev, false); + + /* Disable clocking to the UDP peripheral */ + + sam_disableclks(); +} + +/**************************************************************************** + * Name: sam_sw_shutdown + ****************************************************************************/ + +static void sam_sw_shutdown(struct sam_usbdev_s *priv) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_usbinitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udp; + + usbtrace(TRACE_DEVINIT, 0); + + /* Software initialization */ + + sam_sw_setup(priv); + + /* Power up and initialize USB controller. Interrupts from the UDP + * controller are initialized here, but will not be enabled at the AIC + * until the class driver is installed. + */ + + sam_hw_setup(priv); + + /* Attach USB controller interrupt handlers. The hardware will not be + * initialized and interrupts will not be enabled until the class device + * driver is bound. Getting the IRQs here only makes sure that we have + * them when we need them later. + */ + + if (irq_attach(SAM_IRQ_UDP, sam_udp_interrupt) != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_IRQREGISTRATION), + (uint16_t)SAM_IRQ_UDP); + goto errout; + } + + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udp; + irqstate_t flags; + + flags = enter_critical_section(); + usbtrace(TRACE_DEVUNINIT, 0); + + /* Disable and detach the UDP IRQ */ + + up_disable_irq(SAM_IRQ_UDP); + irq_detach(SAM_IRQ_UDP); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Put the hardware in an inactive state */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udp; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts at the AIC. + * + * NOTE that interrupts and clocking are left disabled in the UDP + * peripheral. The ENDBUSRES interrupt will automatically be enabled + * when the bus reset occurs. The normal operating configuration will + * be established at that time. + */ + + up_enable_irq(SAM_IRQ_UDP); + + /* Enable pull-up to connect the device. The host should enumerate us + * some time after this. The next thing we expect is the ENDBUSRES + * interrupt. + */ + + sam_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver. If the USB device is connected to a + * USB host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udp; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts (but keep them attached) */ + + up_disable_irq(SAM_IRQ_UDP); + + /* Put the hardware in an inactive state. Then bring the hardware back up + * in the initial state. This is essentially the same state as we were + * in when up_usbinitialize() was first called. + */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + + sam_sw_setup(priv); + sam_hw_setup(priv); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_SAM34_UDP */ diff --git a/arch/arm/src/sam34/sam_udp.h b/arch/arm/src/sam34/sam_udp.h new file mode 100644 index 0000000000000000000000000000000000000000..38b665f865f193a1d6be2c3d0fe2e3f5c68c7910 --- /dev/null +++ b/arch/arm/src/sam34/sam_udp.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_udp.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_UDP_H +#define __ARCH_ARM_SRC_SAM34_SAM_UDP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/sam_udp.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: sam_udp_suspend + * + * Description: + * Board logic must provide the sam_udp_suspend logic if the UDP driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * + * When 'resume' is false, this function call provides an opportunity to perform + * board-specific power-saving actions so that less power is consumed while the + * USB is suspended. + * + * Certain power-saving operations are performed by the UDP driver when it enters + * suspend mode: The USB device peripheral clocks are be switched off. MCK and + * UDPCK are switched off and the USB transceiver is disabled. + * + * When 'resume' is true, normal clocking and operations must all be restored. + * + ************************************************************************************/ + +void sam_udp_suspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_UDP_H */ + diff --git a/arch/arm/src/sam34/sam_userspace.c b/arch/arm/src/sam34/sam_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..a399d84a7208b6b5a3919e639fae8d7113c43d3c --- /dev/null +++ b/arch/arm/src/sam34/sam_userspace.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_userspace.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "sam_mpuinit.h" +#include "sam_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void sam_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + sam_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/sam34/sam_userspace.h b/arch/arm/src/sam34/sam_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..86d235cf14b21afa5e002fd4e0badd7d61a73cf5 --- /dev/null +++ b/arch/arm/src/sam34/sam_userspace.h @@ -0,0 +1,105 @@ +/************************************************************************************ + * arch/arm/src/sam34/sam_userspace.h + * + * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_SAM_USERSPACE_H +#define __ARCH_ARM_SRC_SAM34_SAM_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_userspace(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAM34_SAM_USERSPACE_H */ diff --git a/arch/arm/src/sam34/sam_vectors.S b/arch/arm/src/sam34/sam_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..9765f614749cb8d8d96da48c4d101b31fc1c95af --- /dev/null +++ b/arch/arm/src/sam34/sam_vectors.S @@ -0,0 +1,511 @@ +/************************************************************************************************ + * arch/arm/src/sam34/sam_vectors.S + * + * Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include + +#include "exc_return.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ +/* Configuration ********************************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the + * stack pointer of the interrupted thread. If the interrupted thread was a privileged + * thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the + * value of the MSP will be invalid when the interrupt handler returns because it will be a + * pointer to an old position in the unprivileged stack. Then when the high priority + * interrupt occurs and uses this stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt handler will + * always set the the MSP to the interrupt stack. So when the high priority interrupt occurs, + * it will either use the MSP of the last privileged thread to run or, in the case of the + * nested interrupt, the interrupt stack if no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************************/ +/* + * 0x0800:0000 - Beginning of FLASH. Address of vectors. Mapped to address 0x0000:0000 at boot + * time. + * 0x0803:ffff - End of flash + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap. NOTE + * that the ARM uses a decrement before store stack so that the correct initial + * value is the end of the stack + 4; + * 0x2000:bfff - End of SRAM and end of heap + */ + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************************ + * Public Symbols + ************************************************************************************************/ + + .syntax unified + .thumb + .file "sam_vectors.S" + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + .globl __start + +/************************************************************************************************ + * Macros + ************************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + + .macro HANDLER, label, irqno + .thumb_func +\label: + mov r0, #\irqno + b exception_common + .endm + +/************************************************************************************************ + * Vectors + ************************************************************************************************/ + + .section .vectors, "ax" + .code 16 + .align 2 + .globl _vectors + .type _vectors, function + +_vectors: + +/* Processor Exceptions */ + + .word IDLE_STACK /* Vector 0: Reset stack pointer */ + .word __start /* Vector 1: Reset vector */ + .word sam_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + .word sam_hardfault /* Vector 3: Hard fault */ + .word sam_mpu /* Vector 4: Memory management (MPU) */ + .word sam_busfault /* Vector 5: Bus fault */ + .word sam_usagefault /* Vector 6: Usage fault */ + .word sam_reserved /* Vector 7: Reserved */ + .word sam_reserved /* Vector 8: Reserved */ + .word sam_reserved /* Vector 9: Reserved */ + .word sam_reserved /* Vector 10: Reserved */ + .word sam_svcall /* Vector 11: SVC call */ + .word sam_dbgmonitor /* Vector 12: Debug monitor */ + .word sam_reserved /* Vector 13: Reserved */ + .word sam_pendsv /* Vector 14: Pendable system service request */ + .word sam_systick /* Vector 15: System tick */ + +/* External Interrupts */ + +#undef VECTOR +#define VECTOR(l,i) .word l + +#undef UNUSED +#define UNUSED(i) .word sam_reserved + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "chip/sam3u_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3x_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "chip/sam4cm_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_vectors.h" +#else +# error Unrecognized SAM architecture +#endif + + .size _vectors, .-_vectors + +/************************************************************************************************ + * .text + ************************************************************************************************/ + + .text + .type handlers, function + .thumb_func +handlers: + HANDLER sam_reserved, SAM_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER sam_nmi, SAM_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER sam_hardfault, SAM_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER sam_mpu, SAM_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER sam_busfault, SAM_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER sam_usagefault, SAM_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER sam_svcall, SAM_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER sam_dbgmonitor, SAM_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER sam_pendsv, SAM_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER sam_systick, SAM_IRQ_SYSTICK /* Vector 15: System tick */ + +#undef VECTOR +#define VECTOR(l,i) HANDLER l, i + +#undef UNUSED +#define UNUSED(i) + +#if defined(CONFIG_ARCH_CHIP_SAM3U) +# include "chip/sam3u_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) +# include "chip/sam3x_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4CM) +# include "chip/sam4cm_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4E) +# include "chip/sam4e_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4L) +# include "chip/sam4l_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_SAM4S) +# include "chip/sam4s_vectors.h" +#else +# error Unrecognized SAM architecture +#endif + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .globl exception_common + .type exception_common, function + +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size handlers, .-handlers + +/************************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************************ + * .rodata + ************************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/sam34/sam_wdt.c b/arch/arm/src/sam34/sam_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..dbb3f6f895ec5136cc1aa17dea21a364840dc9da --- /dev/null +++ b/arch/arm/src/sam34/sam_wdt.c @@ -0,0 +1,715 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_wdt.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_wdt.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SAM34_WDT) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Clocking *****************************************************************/ +/* The minimum frequency of the WWDG clock is: + * + * So the maximum delay (in milliseconds) is then: + * + * 1000 * (WDT_CR_WDV_MAX+1) / WDT_FCLK + * + * For example, if SCLK = 32768MHz, then the maximum delay is: + * + * Fmin = 1281.74 + * 1000 * 64 / Fmin = 49.93 msec + */ + +#define WDT_FCLK (BOARD_SCLK_FREQUENCY / 128) +#define WDT_MAXTIMEOUT ((1000 * (WDT_MR_WDV_MAX+1)) / WDT_FCLK) + +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAM34_WDT_DEFTIMOUT +# define CONFIG_SAM34_WDT_DEFTIMOUT WDT_MAXTIMEOUT +#endif + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct sam34_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ + xcpt_t handler; /* Current EWI interrupt handler */ + uint32_t timeout; /* The actual timeout value */ + bool started; /* The timer has been started */ + uint16_t reload; /* The 12-bit reload field reset value (WDV) */ + uint16_t window; /* The 12-bit window field value (WDD) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAM34_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr); +static void sam34_putreg(uint32_t val, uint32_t addr); +#else +# define sam34_getreg(addr) getreg32(addr) +# define sam34_putreg(val,addr) putreg32(val,addr) +#endif + +/* Interrupt handling *******************************************************/ + +static int sam34_interrupt(int irq, FAR void *context); + +/* "Lower half" driver methods **********************************************/ + +static int sam34_start(FAR struct watchdog_lowerhalf_s *lower); +static int sam34_stop(FAR struct watchdog_lowerhalf_s *lower); +static int sam34_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int sam34_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int sam34_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); +static xcpt_t sam34_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler); +static int sam34_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = sam34_start, + .stop = sam34_stop, + .keepalive = sam34_keepalive, + .getstatus = sam34_getstatus, + .settimeout = sam34_settimeout, + .capture = sam34_capture, + .ioctl = sam34_ioctl, +}; + +/* "Lower half" driver state */ + +static struct sam34_lowerhalf_s g_wdgdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam34_getreg + * + * Description: + * Get the contents of a register + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam34_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: sam34_putreg + * + * Description: + * Set the contents of an SAM34 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAM34_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam34_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: sam34_interrupt + * + * Description: + * WDT interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +static int sam34_interrupt(int irq, FAR void *context) +{ + FAR struct sam34_lowerhalf_s *priv = &g_wdgdev; + uint16_t regval; + + /* Check if the EWI interrupt is really pending */ + + regval = sam34_getreg(SAM_WDT_SR); + if ((regval & (WDT_SR_WDUNF | WDT_SR_WDERR)) != 0) + { + /* Is there a registered handler? */ + + if (priv->handler) + { + /* Yes... NOTE: This interrupt service routine (ISR) must reload + * the WWDG counter to prevent the reset. Otherwise, we will reset + * upon return. + */ + + priv->handler(irq, context); + } + + /* The EWI interrupt is cleared by the WDT_SR register. */ + } + + return OK; +} + +/**************************************************************************** + * Name: sam34_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t mr_val = 0; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* The watchdog is always disabled after a reset. It is enabled by setting + * the WDGA bit in the WWDG_CR register, then it cannot be disabled again + * except by a reset. + */ + +#if defined(CONFIG_SAM34_JTAG_FULL_ENABLE) || \ + defined(CONFIG_SAM34_JTAG_NOJNTRST_ENABLE) || \ + defined(CONFIG_SAM34_JTAG_SW_ENABLE) + { + mr_val |= (WDT_MR_WDDBGHLT|WDT_MR_WDIDLEHLT); + } +#endif + + /* TODO: WDT_MR_WDFIEN if handler available? WDT_MR_WDRPROC? */ + + mr_val |= (WDT_MR_WDD(priv->window) | WDT_MR_WDV(priv->reload) | WDT_MR_WDRSTEN); + sam34_putreg(mr_val, SAM_WDT_MR); + priv->started = true; + return OK; +} + +/**************************************************************************** + * Name: sam34_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* The watchdog is always disabled after a reset. It is enabled by clearing + * the WDDIS bit in the WDT_CR register, then it cannot be disabled again + * except by a reset. + */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam34_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the watchdog timer or "petting the dog". + * + * The application program must write in the WDT_CR register at regular + * intervals during normal operation to prevent an MCU reset. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + wdvdbg("Entry\n"); + + sam34_putreg((WDT_CR_KEY | WDT_CR_WDRSTT), SAM_WDT_CR); + return OK; +} + +/**************************************************************************** + * Name: sam34_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t elapsed; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + + if (priv->handler) + { + status->flags |= WDFLAGS_CAPTURE; + } + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the watchdog expires (in milliseconds) */ + /* REVISIT: not sure if you can read this... */ + + elapsed = ((sam34_getreg(SAM_WDT_MR) & WDT_MR_WDV_MASK) >> WDT_MR_WDV_SHIFT); + + status->timeleft = (priv->timeout * elapsed) / (priv->reload + 1); + + wdvdbg("Status : %08x\n", sam34_getreg(SAM_WDT_SR)); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam34_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in millisecnds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + uint32_t reload; + + DEBUGASSERT(priv); + wdvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > WDT_MAXTIMEOUT) + { + wddbg("Cannot represent timeout=%d > %d\n", + timeout, WDT_MAXTIMEOUT); + return -ERANGE; + } + + + reload = ((timeout * WDT_FCLK) / 1000) - 1; + + /* Make sure that the final reload value is within range */ + + if (reload > WDT_MR_WDV_MAX) + { + reload = WDT_MR_WDV_MAX; + } + + /* Calculate and save the actual timeout value in milliseconds: + * + * timeout = 1000 * (reload + 1) / Fwdt + */ + + priv->timeout = 1000 * (reload + 1) / WDT_FCLK; + + /* Remember the selected values */ + + priv->reload = reload; + + wdvdbg("fwdt=%d reload=%d timout=%d\n", + WDT_FCLK, reload, priv->timeout); + + /* Don't commit to MR register until started! */ + + return OK; +} + +/**************************************************************************** + * Name: sam34_capture + * + * Description: + * Don't reset on watchdog timer timeout; instead, call this user provider + * timeout handler. NOTE: Providing handler==NULL will restore the reset + * behavior. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new watchdog expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous watchdog expiration function pointer or NULL is there was + * no previous function pointer, i.e., if the previous behavior was + * reset-on-expiration (NULL is also returned if an error occurs). + * + ****************************************************************************/ + +static xcpt_t sam34_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler) +{ +#if 0 /* TODO */ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + irqstate_t flags; + xcpt_t oldhandler; + uint16_t regval; + + DEBUGASSERT(priv); + wdvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + flags = enter_critical_section(); + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + /* Are we attaching or detaching the handler? */ + + regval = sam34_getreg(SAM_WDT_CFR); + if (handler) + { + /* Attaching... Enable the EWI interrupt */ + + regval |= WWDG_CFR_EWI; + sam34_putreg(regval, SAM_WDT_CFR); + + up_enable_irq(STM32_IRQ_WWDG); + } + else + { + /* Detaching... Disable the EWI interrupt */ + + regval &= ~WWDG_CFR_EWI; + sam34_putreg(regval, SAM_WDT_CFR); + + up_disable_irq(STM32_IRQ_WWDG); + } + + leave_critical_section(flags); + return oldhandler; + +#endif + ASSERT(0); + return NULL; +} + +/**************************************************************************** + * Name: sam34_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctl command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam34_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower; + int ret = -ENOTTY; + + DEBUGASSERT(priv); + wdvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg); + + /* WDIOC_MINTIME: Set the minimum ping time. If two keepalive ioctls + * are received within this time, a reset event will be generated. + * Argument: A 32-bit time value in milliseconds. + */ + + if (cmd == WDIOC_MINTIME) + { + uint32_t mintime = (uint32_t)arg; + + ret = -EINVAL; + if (priv->started) + { + ret = -ENOSYS; /* can't write the MR more than once! */ + } + + /* The minimum time should be strictly less than the total delay + * which, in turn, will be less than or equal to WDT_CR_MAX + */ + + else if (mintime < priv->timeout) + { + uint32_t window = (((priv->timeout - mintime) * WDT_FCLK) / 1000) - 1; + DEBUGASSERT(window <= priv->reload); + priv->window = window; + ret = OK; + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_wdtinitialize + * + * Description: + * Initialize the WDT watchdog timer. The watchdog timer is initialized and + * registers as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_WDT_DISABLE_ON_RESET +void sam_wdtinitialize(FAR const char *devpath) +{ + FAR struct sam34_lowerhalf_s *priv = &g_wdgdev; + uint32_t mr_val; + + /* Enable watchdog with 5 sec timeout */ + + mr_val = (WDT_MR_WDD((5) * WDT_FCLK) | WDT_MR_WDV((5) * WDT_FCLK) | + WDT_MR_WDRSTEN); + sam34_putreg(mr_val, SAM_WDT_MR); + + wdvdbg("Entry: devpath=%s\n", devpath); + + /* NOTE we assume that clocking to the IWDG has already been provided by + * the RCC initialization logic. + */ + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_wdgops; + + /* Attach our EWI interrupt handler (But don't enable it yet) */ + + (void)irq_attach(SAM_IRQ_WDT, sam34_interrupt); + + /* Select an arbitrary initial timeout value. But don't start the watchdog + * yet. NOTE: If the "Hardware watchdog" feature is enabled through the + * device option bits, the watchdog is automatically enabled at power-on. + */ + + sam34_settimeout((FAR struct watchdog_lowerhalf_s *)priv, + CONFIG_WDT_TIMEOUT); + + /* Disable minimum time feature for now. */ + + priv->window = priv->reload; + + /* Register the watchdog driver as /dev/watchdog0 */ + + (void)watchdog_register(devpath, (FAR struct watchdog_lowerhalf_s *)priv); + +} +#endif /* CONFIG_WDT_DISABLE_ON_RESET */ + +#endif /* CONFIG_WATCHDOG && CONFIG_SAM34_WDT */ diff --git a/arch/arm/src/sam34/sam_wdt.h b/arch/arm/src/sam34/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..234f4e25204273d54d7344673331afe12e1a3634 --- /dev/null +++ b/arch/arm/src/sam34/sam_wdt.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/arm/src/sam34/sam_wdt.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Bob Doiron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAM34_WDT_H +#define __ARCH_ARM_SRC_SAM34_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_wdt.h" + +#ifdef CONFIG_WATCHDOG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_wdtinitialize + * + * Description: + * Initialize the watchdog timer. The watchdog timer is initialized and + * registers as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAM34_WDT +void sam_wdtinitialize(FAR const char *devpath); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_WATCHDOG */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_WDG_H */ diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..351a5bebe859439420681cea1d83a71625cd137c --- /dev/null +++ b/arch/arm/src/sama5/Kconfig @@ -0,0 +1,5046 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_SAMA5 + +comment "SAMA5 Configuration Options" + +# Chip Capabilities + +config SAMA5_HAVE_AESB + bool + default n + +config SAMA5_HAVE_ICM + bool + default n + +config SAMA5_HAVE_RXLP + bool + default n + +config SAMA5_HAVE_UART0 + bool + default n + +config SAMA5_HAVE_UART1 + bool + default n + +config SAMA5_HAVE_UART2 + bool + default n + +config SAMA5_HAVE_UART3 + bool + default n + +config SAMA5_HAVE_UART4 + bool + default n + +config SAMA5_HAVE_USART0 + bool + default n + +config SAMA5_HAVE_USART1 + bool + default n + +config SAMA5_HAVE_USART2 + bool + default n + +config SAMA5_HAVE_USART3 + bool + default n + +config SAMA5_HAVE_USART4 + bool + default n + +config SAMA5_HAVE_FLEXCOM0 + bool + default n + +config SAMA5_HAVE_FLEXCOM1 + bool + default n + +config SAMA5_HAVE_FLEXCOM2 + bool + default n + +config SAMA5_HAVE_FLEXCOM3 + bool + default n + +config SAMA5_HAVE_FLEXCOM4 + bool + default n + +config SAMA5_HAVE_CAN0 + bool + default n + +config SAMA5_HAVE_CAN1 + bool + default n + +config SAMA5_HAVE_DMA + bool + default n + +config SAMA5_HAVE_DDR32 + bool + default n + +config SAMA5_HAVE_XDMA + bool + default n + +config SAMA5_HAVE_LCDC + bool + default n + +config SAMA5_HAVE_GMAC + bool + default n + +config SAMA5_HAVE_EMACA + bool + default n + +config SAMA5_HAVE_EMACB + bool + default n + +config SAMA5_HAVE_EMAC1 + bool + default n + +config SAMA5_HAVE_HSMCI2 + bool + default n + +config SAMA5_HAVE_PIOE + bool + default n + +config SAMA5_HAVE_SAIC + bool + default n + +config SAMA5_HAVE_SBM + bool + default n + +config SAMA5_HAVE_SFC + bool + default n + +config SAMA5_HAVE_SPI2 + bool + default n + +config SAMA5_HAVE_TC + bool + default n + +config SAMA5_HAVE_TC1 + bool + default n + +config SAMA5_HAVE_TC2 + bool + default n + +config SAMA5_HAVE_TWI3 + bool + default n + +config SAMA5_HAVE_VDEC + bool + default n + +# Summary configuratinos + +config SAMA5_FLEXCOM + bool + default n + +config SAMA5_FLEXCOM_USART + bool + default n + +config SAMA5_FLEXCOM_SPI + bool + default n + +config SAMA5_FLEXCOM_TWI + bool + default n + +# Chip Selection + +config ARCH_CHIP_SAMA5D2 + bool + default n + select ARMV7A_HAVE_L2CC_PL310 + select SAMA5_HAVE_AESB + select ARCH_NAND_HWECC + select SAMA5_HAVE_EMACB + select SAMA5_HAVE_ICM + select SAMA5_HAVE_LCDC + select SAMA5_HAVE_RXLP + select SAMA5_HAVE_UART0 + select SAMA5_HAVE_UART1 + select SAMA5_HAVE_UART2 + select SAMA5_HAVE_UART3 + select SAMA5_HAVE_UART4 + select SAMA5_HAVE_FLEXCOM0 + select SAMA5_HAVE_FLEXCOM1 + select SAMA5_HAVE_FLEXCOM2 + select SAMA5_HAVE_FLEXCOM3 + select SAMA5_HAVE_FLEXCOM4 + select SAMA5_HAVE_QSPI + select SAMA5_HAVE_XDMA + select SAMA5_HAVE_SAIC + select SAMA5_HAVE_SFC + select SAMA5_HAVE_SPI2 + select SAMA5_HAVE_TC1 + select ARCH_HAVE_TRUSTZONE + +config ARCH_CHIP_SAMA5D3 + bool + default n + select SAMA5_HAVE_DMA + select SAMA5_HAVE_PIOE + select SAMA5_HAVE_USART0 + select SAMA5_HAVE_USART1 + select SAMA5_HAVE_USART2 + select SAMA5_HAVE_USART3 + +config ARCH_CHIP_SAMA5D4 + bool + default n + select ARMV7A_HAVE_L2CC_PL310 + select ARCH_NAND_HWECC + select SAMA5_HAVE_AESB + select SAMA5_HAVE_EMACB + select SAMA5_HAVE_EMAC1 + select SAMA5_HAVE_ICM + select SAMA5_HAVE_LCDC + select SAMA5_HAVE_UART0 + select SAMA5_HAVE_UART1 + select SAMA5_HAVE_USART0 + select SAMA5_HAVE_USART1 + select SAMA5_HAVE_USART2 + select SAMA5_HAVE_USART3 + select SAMA5_HAVE_USART4 + select SAMA5_HAVE_XDMA + select SAMA5_HAVE_PIOE + select SAMA5_HAVE_SAIC + select SAMA5_HAVE_SBM + select SAMA5_HAVE_SFC + select SAMA5_HAVE_SPI2 + select SAMA5_HAVE_TC1 + select SAMA5_HAVE_TC2 + select ARCH_HAVE_TRUSTZONE + select SAMA5_HAVE_TWI3 + +choice + prompt "Atmel AT91SAMA5 Chip Selection" + default ARCH_CHIP_ATSAMA5D33 + +config ARCH_CHIP_ATSAMA5D21 + bool "Atmel ATSAMA5D21" + select ARCH_CHIP_SAMA5D2 + +config ARCH_CHIP_ATSAMA5D22 + bool "Atmel ATSAMA5D22" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_CAN0 + +config ARCH_CHIP_ATSAMA5D23 + bool "Atmel ATSAMA5D23" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_CAN0 + +config ARCH_CHIP_ATSAMA5D24 + bool "Atmel ATSAMA5D24" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_DDR32 + +config ARCH_CHIP_ATSAMA5D26 + bool "Atmel ATSAMA5D26" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_DDR32 + +config ARCH_CHIP_ATSAMA5D27 + bool "Atmel ATSAMA5D27" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_CAN0 + select SAMA5_HAVE_CAN1 + select SAMA5_HAVE_DDR32 + +config ARCH_CHIP_ATSAMA5D28 + bool "Atmel ATSAMA5D28" + select ARCH_CHIP_SAMA5D2 + select SAMA5_HAVE_CAN0 + select SAMA5_HAVE_CAN1 + select SAMA5_HAVE_DDR32 + +config ARCH_CHIP_ATSAMA5D31 + bool "Atmel ATSAMA5D31" + select ARCH_CHIP_SAMA5D3 + select SAMA5_HAVE_EMACA + select SAMA5_HAVE_HSMCI2 + select SAMA5_HAVE_LCDC + select SAMA5_HAVE_UART0 + select SAMA5_HAVE_UART1 + select ARCH_NAND_HWECC + +config ARCH_CHIP_ATSAMA5D33 + bool "Atmel ATSAMA5D33" + select ARCH_CHIP_SAMA5D3 + select SAMA5_HAVE_GMAC + select SAMA5_HAVE_LCDC + select ARCH_NAND_HWECC + +config ARCH_CHIP_ATSAMA5D34 + bool "Atmel ATSAMA5D34" + select ARCH_CHIP_SAMA5D3 + select SAMA5_HAVE_GMAC + select SAMA5_HAVE_HSMCI2 + select SAMA5_HAVE_LCDC + select SAMA5_HAVE_CAN0 + select SAMA5_HAVE_CAN1 + select ARCH_NAND_HWECC + +config ARCH_CHIP_ATSAMA5D35 + bool "Atmel ATSAMA5D35" + select ARCH_CHIP_SAMA5D3 + select SAMA5_HAVE_EMACA + select SAMA5_HAVE_GMAC + select SAMA5_HAVE_HSMCI2 + select SAMA5_HAVE_UART0 + select SAMA5_HAVE_UART1 + select SAMA5_HAVE_CAN0 + select SAMA5_HAVE_CAN1 + select SAMA5_HAVE_TC1 + select ARCH_NAND_HWECC + +config ARCH_CHIP_ATSAMA5D36 + bool "Atmel ATSAMA5D356" + select ARCH_CHIP_SAMA5D3 + select SAMA5_HAVE_EMACA + select SAMA5_HAVE_GMAC + select SAMA5_HAVE_HSMCI2 + select SAMA5_HAVE_LCDC + select SAMA5_HAVE_UART0 + select SAMA5_HAVE_UART1 + select SAMA5_HAVE_CAN0 + select SAMA5_HAVE_CAN1 + select SAMA5_HAVE_TC1 + select ARCH_NAND_HWECC + +config ARCH_CHIP_ATSAMA5D41 + bool "Atmel ATSAMA5D41" + select ARCH_CHIP_SAMA5D4 + +config ARCH_CHIP_ATSAMA5D42 + bool "Atmel ATSAMA5D42" + select ARCH_CHIP_SAMA5D4 + select SAMA5_HAVE_DDR32 + +config ARCH_CHIP_ATSAMA5D43 + bool "Atmel ATSAMA5D43" + select ARCH_CHIP_SAMA5D4 + select SAMA5_HAVE_VDEC + +config ARCH_CHIP_ATSAMA5D44 + bool "Atmel ATSAMA5D44" + select ARCH_CHIP_SAMA5D4 + select SAMA5_HAVE_DDR32 + select SAMA5_HAVE_VDEC + +endchoice # Atmel AT91SAMA5 Chip Selection + +menu "SAMA5 Peripheral Support" + +config SAMA5_AES + bool "Advanced Encryption Standard (AES)" + default n + +config SAMA5_TDES + bool "Triple Data Encryption Standard (TDES)" + default n + +config SAMA5_AESB + bool "Advanced Encryption Bridge (AESB)" + default n + depends on SAMA5_HAVE_AESB + +config SAMA5_DBGU + bool "Debug Unit (DBGU)" + default n + select ARCH_HAVE_OTHER_UART + +config SAMA5_PIT + bool "Periodic Interval Timer (PIT)" + default n + +config SAMA5_WDT + bool "Watchdog timer (WDT)" + default n + select WATCHDOG + +config SAMA5_RTC + bool "Real time clock calendar (RTC)" + default n + select RTC + select RTC_DATETIME + +config SAMA5_ICM + bool "Integrity Check Monitor (ICM)" + default n + depends on SAMA5_HAVE_ICM + +config SAMA5_HSMC + bool "Static Memory Controller (HSMC)" + default n + +config SAMA5_SMD + bool "SMD Soft Modem (SMD)" + default n + +config SAMA5_SAIC + bool "Secure Advanced Interrupt Controller (SAIC)" + default n + depends on SAMA5_HAVE_SAIC + select ARMV7A_DECODEFIQ + +config SAMA5_RXLP + bool "Low power asynchronous receiver" + default y + depends on SAMA5_HAVE_RXLP + +config SAMA5_UART0 + bool "UART 0" + default y + depends on SAMA5_HAVE_UART0 + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_UART1 + bool "UART 1" + default n + depends on SAMA5_HAVE_UART1 + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_UART2 + bool "UART 2" + default n + depends on SAMA5_HAVE_UART2 + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_UART3 + bool "UART 3" + default n + depends on SAMA5_HAVE_UART3 + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_UART4 + bool "UART 4" + default n + depends on SAMA5_HAVE_UART4 + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_USART0 + bool "USART 0" + default n + depends on SAMA5_HAVE_USART0 + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_USART1 + bool "USART 1" + default n + depends on SAMA5_HAVE_USART1 + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_USART2 + bool "USART 2" + default n + depends on SAMA5_HAVE_USART2 + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_USART3 + bool "USART 3" + default n + depends on SAMA5_HAVE_USART3 + select ARCH_HAVE_USART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_USART4 + bool "USART 4" + default n + depends on SAMA5_HAVE_USART4 + select ARCH_HAVE_USART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM0 + bool "FLEXCOM 0" + default n + depends on SAMA5_HAVE_FLEXCOM0 + select SAMA5_FLEXCOM + +config SAMA5_FLEXCOM1 + bool "FLEXCOM 1" + default n + depends on SAMA5_HAVE_FLEXCOM1 + select SAMA5_FLEXCOM + +config SAMA5_FLEXCOM2 + bool "FLEXCOM 2" + default n + depends on SAMA5_HAVE_FLEXCOM2 + select SAMA5_FLEXCOM + +config SAMA5_FLEXCOM3 + bool "FLEXCOM 3" + default n + depends on SAMA5_HAVE_FLEXCOM3 + select SAMA5_FLEXCOM + +config SAMA5_FLEXCOM4 + bool "FLEXCOM 4" + default n + depends on SAMA5_HAVE_FLEXCOM4 + select SAMA5_FLEXCOM + +config SAMA5_TWI0 + bool "Two-Wire Interface 0 (TWI0)" + default n + +config SAMA5_TWI1 + bool "Two-Wire Interface 1 (TWI1)" + default n + +config SAMA5_TWI2 + bool "Two-Wire Interface 2 (TWI2)" + default n + +config SAMA5_TWI3 + bool "Two-Wire Interface 3 (TWI3)" + default n + depends on SAMA5_HAVE_TWI3 + +config SAMA5_HSMCI0 + bool "High Speed Multimedia Card Interface 0 (HSMCI0)" + default n + select ARCH_HAVE_SDIO + +config SAMA5_HSMCI1 + bool "High Speed Multimedia Card Interface 1 (HSMCI1)" + default n + select ARCH_HAVE_SDIO + +config SAMA5_HSMCI2 + bool "High Speed Multimedia Card Interface 2 (HSMCI2)" + default n + depends on SAMA5_HAVE_HSMCI2 + select ARCH_HAVE_SDIO + +config SAMA5_SBM + bool "Secure Box Module (SBM)" + default n + depends on SAMA5_HAVE_SBM + +config SAMA5_SFC + bool "Secure Fuse Controller (SFC)" + default n + depends on SAMA5_HAVE_SFC + +config SAMA5_SPI0 + bool "Serial Peripheral Interface 0 (SPI0)" + default n + +config SAMA5_SPI1 + bool "Serial Peripheral Interface 1 (SPI1)" + default n + +config SAMA5_SPI2 + bool "Serial Peripheral Interface 2 (SPI2)" + default n + depends on SAMA5_HAVE_SPI2 + +config SAMA5_TC0 + bool "Timer Counter 0 (ch. 0, 1, 2) (TC0)" + default n + select SAMA5_HAVE_TC + +config SAMA5_TC1 + bool "Timer Counter 1 (ch. 3, 4, 5) (TC1)" + default n + depends on SAMA5_HAVE_TC1 + select SAMA5_HAVE_TC + +config SAMA5_TC2 + bool "Timer Counter 2 (ch. 6, 7, 8) (TC2)" + default n + depends on SAMA5_HAVE_TC2 + select SAMA5_HAVE_TC + +config SAMA5_PWM + bool "Pulse Width Modulation Controller (PWM)" + default n + select PWM + +config SAMA5_ADC + bool "Touch Screen / ADC Controller (ADC)" + default n + select ANALOG + select ADC + +config SAMA5_DMAC0 + bool "DMA Controller 0 (DMAC0)" + default n + select ARCH_DMA + depends on SAMA5_HAVE_DMA + +config SAMA5_DMAC1 + bool "DMA Controller 1 (DMAC1)" + default n + select ARCH_DMA + depends on SAMA5_HAVE_DMA + +config SAMA5_XDMAC0 + bool "XDMA Controller (XDMAC0, always secure)" + default n + select ARCH_DMA + depends on SAMA5_HAVE_XDMA + +config SAMA5_XDMAC1 + bool "XDMA Controller (XDMAC1, never secure)" + default n + select ARCH_DMA + depends on SAMA5_HAVE_XDMA + +config SAMA5_UHPHS + bool "USB Host High Speed (UHPHS)" + default n + +config SAMA5_UDPHS + bool "USB Device High Speed (UDPHS)" + default n + +config SAMA5_GMAC + bool "Gigabit Ethernet MAC (GMAC)" + default n + depends on SAMA5_HAVE_GMAC + select NETDEVICES + select NETDEV_MULTINIC if SAMA5_EMAC + select ARCH_HAVE_PHY + +config SAMA5_EMACA + bool "10/100MBps Ethernet MAC (EMAC)" + default n + depends on SAMA5_HAVE_EMACA + select NETDEVICES + select NETDEV_MULTINIC if SAMA5_GMAC + select ARCH_HAVE_PHY + +config SAMA5_EMACB + bool + default n + +config SAMA5_EMAC0 + bool "10/100MBps Ethernet MAC (EMAC0)" + default n + depends on SAMA5_HAVE_EMACB + select SAMA5_EMACB + select NETDEVICES + select NETDEV_MULTINIC if SAMA5_EMAC1 + select ARCH_HAVE_PHY + +config SAMA5_EMAC1 + bool "10/100MBps Ethernet MAC (EMAC1)" + default n + depends on SAMA5_HAVE_EMACB && SAMA5_HAVE_EMAC1 + select SAMA5_EMACB + select NETDEVICES + select NETDEV_MULTINIC if SAMA5_EMAC0 + select ARCH_HAVE_PHY + +config SAMA5_LCDC + bool "LCD Controller (LCDC)" + default n + depends on SAMA5_HAVE_LCDC + +config SAMA5_ISI + bool "Image Sensor Interface (ISI)" + default n + +config SAMA5_SSC0 + bool "Synchronous Serial Controller 0 (SSC0)" + default n + select I2S + depends on SAMA5_DMAC0 || SAMA5_XDMAC0 || SAMA5_XDMAC1 + select AUDIO + +config SAMA5_SSC1 + bool "Synchronous Serial Controller 1 (SSC1)" + default n + select I2S + depends on SAMA5_DMAC1 || SAMA5_XDMAC0 || SAMA5_XDMAC1 + select AUDIO + +config SAMA5_CAN0 + bool "CAN controller 0 (CAN0)" + default n + select CAN + depends on SAMA5_HAVE_CAN0 + +config SAMA5_CAN1 + bool "CAN controller 1 (CAN1)" + default n + select CAN + depends on SAMA5_HAVE_CAN1 + +config SAMA5_SHA + bool "Secure Hash Algorithm (SHA)" + default n + +config SAMA5_TRNG + bool "True Random Number Generator (TRNG)" + default n + select ARCH_HAVE_RNG + +config SAMA5_ARM + bool "Performance Monitor Unit (ARM)" + default n + +config SAMA5_FUSE + bool "Fuse Controller (FUSE)" + default n + +config SAMA5_MPDDRC + bool "MPDDR controller (MPDDRC)" + default n + +config SAMA5_VDEC + bool "Video decoder (VDEC)" + default n + depends on SAMA5_HAVE_VDEC + +endmenu # SAMA5 Peripheral Support + +config SAMA5_PIO_IRQ + bool "PIO pin interrupts" + ---help--- + Enable support for interrupting PIO pins + +if SAMA5_PIO_IRQ + +config SAMA5_PIOA_IRQ + bool "PIOA interrupts" + default n + +config SAMA5_PIOB_IRQ + bool "PIOB interrupts" + default n + +config SAMA5_PIOC_IRQ + bool "PIOC interrupts" + default n + +config SAMA5_PIOD_IRQ + bool "PIOD interrupts" + default n + +config SAMA5_PIOE_IRQ + bool "PIOE interrupts" + default n + depends on SAMA5_HAVE_PIOE + +endif # PIO_IRQ + +menu "Flexcom Configuration" + depends on SAMA5_FLEXCOM + +choice + prompt "FLEXCOM0 Configuration" + default SAMA5_FLEXCOM0_USART + depends on SAMA5_FLEXCOM0 + +config SAMA5_FLEXCOM0_USART + bool "USART" + select SAMA5_FLEXCOM_USART + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM0_SPI + bool "SPI" + select SAMA5_FLEXCOM_SPI + +config SAMA5_FLEXCOM0_SPI + bool "TWI" + select SAMA5_FLEXCOM_TWI + +endchoice # FLEXCOM0 Configuration + +choice + prompt "FLEXCOM1 Configuration" + default SAMA5_FLEXCOM1_USART + depends on SAMA5_FLEXCOM1 + +config SAMA5_FLEXCOM1_USART + bool "USART" + select SAMA5_FLEXCOM_USART + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM1_SPI + bool "SPI" + select SAMA5_FLEXCOM_SPI + +config SAMA5_FLEXCOM1_SPI + bool "TWI" + select SAMA5_FLEXCOM_TWI + +endchoice # FLEXCOM1 Configuration + +choice + prompt "FLEXCOM2 Configuration" + default SAMA5_FLEXCOM2_USART + depends on SAMA5_FLEXCOM2 + +config SAMA5_FLEXCOM2_USART + bool "USART" + select SAMA5_FLEXCOM_USART + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM2_SPI + bool "SPI" + select SAMA5_FLEXCOM_SPI + +config SAMA5_FLEXCOM2_SPI + bool "TWI" + select SAMA5_FLEXCOM_TWI + +endchoice # FLEXCOM2 Configuration + +choice + prompt "FLEXCOM3 Configuration" + default SAMA5_FLEXCOM3_USART + depends on SAMA5_FLEXCOM3 + +config SAMA5_FLEXCOM3_USART + bool "USART" + select SAMA5_FLEXCOM_USART + +config SAMA5_FLEXCOM3_SPI + bool "SPI" + select SAMA5_FLEXCOM_SPI + select ARCH_HAVE_USART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM3_SPI + bool "TWI" + select SAMA5_FLEXCOM_TWI + +endchoice # FLEXCOM3 Configuration + +choice + prompt "FLEXCOM4 Configuration" + default SAMA5_FLEXCOM4_USART + depends on SAMA5_FLEXCOM4 + +config SAMA5_FLEXCOM4_USART + bool "USART" + select SAMA5_FLEXCOM_USART + select ARCH_HAVE_USART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMA5_FLEXCOM4_SPI + bool "SPI" + select SAMA5_FLEXCOM_SPI + +config SAMA5_FLEXCOM4_SPI + bool "TWI" + select SAMA5_FLEXCOM_TWI + +endchoice # FLEXCOM4 Configuration +endmenu # Flexcom Configuration + +menu "DBGU Configuration" + depends on SAMA5_DBGU + +config SAMA5_DBGU_CONSOLE + bool "DBGU serial console" + ---help--- + Select to use the DBGU as the serial console. + +config SAMA5_DBGU_RXBUFSIZE + int "Receive buffer size" + default 256 + ---help--- + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config SAMA5_DBGU_TXBUFSIZE + int "Transmit buffer size" + default 256 + ---help--- + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config SAMA5_DBGU_NOCONFIG + bool "Suppress DBGU configuration" + default n + depends on SAMA5_BOOT_SDRAM && SAMA5_DBGU_CONSOLE + ---help--- + The DBGU is often used by bootloaders to provide the bootloader + interface. If the DBGU is also used as the NuttX console, then it + would be best to avoid reconfiguring the DBGU so that the user + experience is seamless going from the bootloader to the NuttX + console. + +if !SAMA5_DBGU_NOCONFIG + +config SAMA5_DBGU_BAUD + int "BAUD rate" + default 115200 + ---help--- + The configured BAUD of the UART. + +config SAMA5_DBGU_PARITY + int "Parity setting" + default 0 + range 0 2 + ---help--- + 0=no parity, 1=odd parity, 2=even parity + +endif # !SAMA5_DBGU_NOCONFIG +endmenu #DBGU Configuration + +if SAMA5_LCDC +menu "LCDC Configuration" + +config SAMA5_LCDC_BACKLIGHT + bool "Backlight support" + default y + +config SAMA5_LCDC_DEFBACKLIGHT + hex "Default backlight level" + default 0xf0 + +config SAMA5_LCDC_BACKCOLOR + hex "Background color" + default 0x0 + +config SAMA5_LCDC_FB_VBASE + hex "Framebuffer memory start address (virtual)" + ---help--- + If you are using the the LCDC, then you must provide the virtual + address of the start of the framebuffer. This address must be + aligned to a 1MB bounder (i.e., the last five "digits" of the + hexadecimal address must be zero). + +config SAMA5_LCDC_FB_PBASE + hex "Framebuffer memory start address (virtual)" + ---help--- + If you are using the the LCDC, then you must provide the physical + address of the start of the framebuffer. This address must be + aligned to a 1MB bounder (i.e., the last five "digits" of the + hexadecimal address must be zero). + +config SAMA5_LCDC_FB_SIZE + int "Framebuffer memory size (bytes)" + default 0 + +comment "Base layer configuration" + +choice + prompt "Base layer rotation" + default SAMA5_LCDC_BASE_ROT0 + +config SAMA5_LCDC_BASE_ROT0 + bool "No rotation" + +config SAMA5_LCDC_BASE_ROT90 + bool "90 degrees" + +config SAMA5_LCDC_BASE_ROT180 + bool "180 degrees" + +config SAMA5_LCDC_BASE_ROT270 + bool "270 degrees" + +endchoice # Base layer rotation + +choice + prompt "Base layer color format" + default SAMA5_LCDC_BASE_RGB565 + +config SAMA5_LCDC_BASE_RGB444 + bool "12 bpp RGB 444" + +config SAMA5_LCDC_BASE_ARGB4444 + bool "16 bpp ARGB 4444" + +config SAMA5_LCDC_BASE_RGBA4444 + bool "16 bpp RGBA 4444" + +config SAMA5_LCDC_BASE_RGB565 + bool "16 bpp RGB 565" + +config SAMA5_LCDC_BASE_TRGB1555 + bool "16 bpp TRGB 1555" + +config SAMA5_LCDC_BASE_RGB666 + bool "18 bpp RGB 666" + +config SAMA5_LCDC_BASE_RGB666P + bool "18 bpp RGB 666 packed" + +config SAMA5_LCDC_BASE_TRGB1666 + bool "19 bpp TRGB 1666" + +config SAMA5_LCDC_BASE_TRGBP + bool "19 bpp TRGB 1666 packed" + +config SAMA5_LCDC_BASE_RGB888 + bool "24 bpp RGB 888" + +config SAMA5_LCDC_BASE_RGB888P + bool "24 bpp RGB 888 packed" + +config SAMA5_LCDC_BASE_TRGB1888 + bool "25 bpp TRGB 1888" + +config SAMA5_LCDC_BASE_ARGB8888 + bool "32 bpp ARGB 8888" + +config SAMA5_LCDC_BASE_RGBA8888 + bool "32 bpp RGBA 8888" + +endchoice # Base layer color format + +menuconfig SAMA5_LCDC_OVR1 + bool "Enable overlay 1 window" + default n + depends on EXPERIMENTAL + +if SAMA5_LCDC_OVR1 + +config SAMA5_LCDC_OVR1_MAXHEIGHT + int "Overlay 1 height (rows)" + default 480 + +config SAMA5_LCDC_OVR1_MAXWIDTH + int "Overlay 1 width (pixels)" + default 800 + +config SAMA5_LCDC_OVR1_BOTTOMUP + bool "Raster bottom-up" + default n + +config SAMA5_LCDC_OVR1_RIGHTLEFT + bool "Raster right-to-left" + default n + +choice + prompt "Overlay 1 rotation" + default SAMA5_LCDC_OVR1_ROT0 + +config SAMA5_LCDC_OVR1_ROT0 + bool "No rotation" + +config SAMA5_LCDC_OVR1_ROT90 + bool "90 degrees" + +config SAMA5_LCDC_OVR1_ROT180 + bool "180 degrees" + +config SAMA5_LCDC_OVR1_ROT270 + bool "270 degrees" + +endchoice # Overlay 1 rotation + +choice + prompt "Overlay 1 color format" + default SAMA5_LCDC_OVR1_RGB565 + +config SAMA5_LCDC_OVR1_RGB444 + bool "12 bpp RGB 444" + +config SAMA5_LCDC_OVR1_ARGB4444 + bool "16 bpp ARGB 4444" + +config SAMA5_LCDC_OVR1_RGBA4444 + bool "16 bpp RGBA 4444" + +config SAMA5_LCDC_OVR1_RGB565 + bool "16 bpp RGB 565" + +config SAMA5_LCDC_OVR1_TRGB1555 + bool "16 bpp TRGB 1555" + +config SAMA5_LCDC_OVR1_RGB666 + bool "18 bpp RGB 666" + +config SAMA5_LCDC_OVR1_RGB666P + bool "18 bpp RGB 666 packed" + +config SAMA5_LCDC_OVR1_TRGB1666 + bool "19 bpp TRGB 1666" + +config SAMA5_LCDC_OVR1_TRGBP + bool "19 bpp TRGB 1666 packed" + +config SAMA5_LCDC_OVR1_RGB888 + bool "24 bpp RGB 888" + +config SAMA5_LCDC_OVR1_RGB888P + bool "24 bpp RGB 888 packed" + +config SAMA5_LCDC_OVR1_TRGB1888 + bool "25 bpp TRGB 1888" + +config SAMA5_LCDC_OVR1_ARGB8888 + bool "32 bpp ARGB 8888" + +config SAMA5_LCDC_OVR1_RGBA8888 + bool "32 bpp RGBA 8888" + +endchoice # Base layer color format +endif # SAMA5_LCDC_OVR1 + +menuconfig SAMA5_LCDC_OVR2 + bool "Enable overlay 2 window" + default n + depends on EXPERIMENTAL + +if SAMA5_LCDC_OVR2 + +config SAMA5_LCDC_OVR2_MAXHEIGHT + int "Overlay 2 height (rows)" + default 480 + +config SAMA5_LCDC_OVR2_MAXWIDTH + int "Overlay 2 width (pixels)" + default 800 + +config SAMA5_LCDC_OVR2_BOTTOMUP + bool "Raster bottom-up" + default n + +config SAMA5_LCDC_OVR2_RIGHTLEFT + bool "Raster right-to-left" + default n + +choice + prompt "Overlay 2 rotation" + default SAMA5_LCDC_OVR2_ROT0 + +config SAMA5_LCDC_OVR2_ROT0 + bool "No rotation" + +config SAMA5_LCDC_OVR2_ROT90 + bool "90 degrees" + +config SAMA5_LCDC_OVR2_ROT180 + bool "180 degrees" + +config SAMA5_LCDC_OVR2_ROT270 + bool "270 degrees" + +endchoice # Overlay 2 rotation + +choice + prompt "Overlay 2 layer color format" + default SAMA5_LCDC_OVR2_RGB565 + +config SAMA5_LCDC_OVR2_RGB444 + bool "12 bpp RGB 444" + +config SAMA5_LCDC_OVR2_ARGB4444 + bool "16 bpp ARGB 4444" + +config SAMA5_LCDC_OVR2_RGBA4444 + bool "16 bpp RGBA 4444" + +config SAMA5_LCDC_OVR2_RGB565 + bool "16 bpp RGB 565" + +config SAMA5_LCDC_OVR2_TRGB1555 + bool "16 bpp TRGB 1555" + +config SAMA5_LCDC_OVR2_RGB666 + bool "18 bpp RGB 666" + +config SAMA5_LCDC_OVR2_RGB666P + bool "18 bpp RGB 666 packed" + +config SAMA5_LCDC_OVR2_TRGB1666 + bool "19 bpp TRGB 1666" + +config SAMA5_LCDC_OVR2_TRGBP + bool "19 bpp TRGB 1666 packed" + +config SAMA5_LCDC_OVR2_RGB888 + bool "24 bpp RGB 888" + +config SAMA5_LCDC_OVR2_RGB888P + bool "24 bpp RGB 888 packed" + +config SAMA5_LCDC_OVR2_TRGB1888 + bool "25 bpp TRGB 1888" + +config SAMA5_LCDC_OVR2_ARGB8888 + bool "32 bpp ARGB 8888" + +config SAMA5_LCDC_OVR2_RGBA8888 + bool "32 bpp RGBA 8888" + +endchoice # Base layer color format +endif # SAMA5 LCDC_OVR2 + +config SAMA5_LCDC_HEO + bool "High end overlay (HEO) window" + default n + depends on EXPERIMENTAL + +if SAMA5_LCDC_HEO + +config SAMA5_LCDC_HEO_MAXHEIGHT + int "HEO layer height (rows)" + default 480 + +config SAMA5_LCDC_HEO_MAXWIDTH + int "HEO layer width (pixels)" + default 800 + +config SAMA5_LCDC_HEO_BOTTOMUP + bool "Raster bottom-up" + default n + +config SAMA5_LCDC_HEO_RIGHTLEFT + bool "Raster right-to-left" + default n + +choice + prompt "HEO layer rotation" + default SAMA5_LCDC_HEO_ROT0 + +config SAMA5_LCDC_HEO_ROT0 + bool "No rotation" + +config SAMA5_LCDC_HEO_ROT90 + bool "90 degrees" + +config SAMA5_LCDC_HEO_ROT180 + bool "180 degrees" + +config SAMA5_LCDC_HEO_ROT270 + bool "270 degrees" + +endchoice # HEO layer rotation + +choice + prompt "HEO layer color format" + default SAMA5_LCDC_HEO_RGB565 + +config SAMA5_LCDC_HEO_RGB444 + bool "12 bpp RGB 444" + +config SAMA5_LCDC_HEO_ARGB4444 + bool "16 bpp ARGB 4444" + +config SAMA5_LCDC_HEO_RGBA4444 + bool "16 bpp RGBA 4444" + +config SAMA5_LCDC_HEO_RGB565 + bool "16 bpp RGB 565" + +config SAMA5_LCDC_HEO_TRGB1555 + bool "16 bpp TRGB 1555" + +config SAMA5_LCDC_HEO_RGB666 + bool "18 bpp RGB 666" + +config SAMA5_LCDC_HEO_RGB666P + bool "18 bpp RGB 666 packed" + +config SAMA5_LCDC_HEO_TRGB1666 + bool "19 bpp TRGB 1666" + +config SAMA5_LCDC_HEO_TRGBP + bool "19 bpp TRGB 1666 packed" + +config SAMA5_LCDC_HEO_RGB888 + bool "24 bpp RGB 888" + +config SAMA5_LCDC_HEO_RGB888P + bool "24 bpp RGB 888 packed" + +config SAMA5_LCDC_HEO_TRGB1888 + bool "25 bpp TRGB 1888" + +config SAMA5_LCDC_HEO_ARGB8888 + bool "32 bpp ARGB 8888" + +config SAMA5_LCDC_HEO_RGBA8888 + bool "32 bpp RGBA 8888" + +endchoice # Base layer color format +endif # SAMA5_LCDC_HEO + +config SAMA5_LCDC_HCR + bool "Enable hardware cursor (HCR)" + default n + depends on EXPERIMENTAL && FB_HWCURSOR + +if SAMA5_LCDC_HCR + +config SAMA5_LCDC_HCR_MAXHEIGHT + int "Hardware cursor height (rows)" + default 32 + +config SAMA5_LCDC_HCR_MAXWIDTH + int "Hardware cursor width (pixels)" + default 32 + +choice + prompt "Hardware cursor rotation" + default SAMA5_LCDC_HCR_ROT0 + +config SAMA5_LCDC_HCR_ROT0 + bool "No rotation" + +config SAMA5_LCDC_HCR_ROT90 + bool "90 degrees" + +config SAMA5_LCDC_HCR_ROT180 + bool "180 degrees" + +config SAMA5_LCDC_HCR_ROT270 + bool "270 degrees" + +endchoice # Hardware cursor rotation + +choice + prompt "Hardware cursor layer color format" + default SAMA5_LCDC_HCR_RGB565 + +config SAMA5_LCDC_HCR_RGB444 + bool "12 bpp RGB 444" + +config SAMA5_LCDC_HCR_ARGB4444 + bool "16 bpp ARGB 4444" + +config SAMA5_LCDC_HCR_RGBA4444 + bool "16 bpp RGBA 4444" + +config SAMA5_LCDC_HCR_RGB565 + bool "16 bpp RGB 565" + +config SAMA5_LCDC_HCR_TRGB1555 + bool "16 bpp TRGB 1555" + +config SAMA5_LCDC_HCR_RGB666 + bool "18 bpp RGB 666" + +config SAMA5_LCDC_HCR_RGB666P + bool "18 bpp RGB 666 packed" + +config SAMA5_LCDC_HCR_TRGB1666 + bool "19 bpp TRGB 1666" + +config SAMA5_LCDC_HCR_TRGBP + bool "19 bpp TRGB 1666 packed" + +config SAMA5_LCDC_HCR_RGB888 + bool "24 bpp RGB 888" + +config SAMA5_LCDC_HCR_RGB888P + bool "24 bpp RGB 888 packed" + +config SAMA5_LCDC_HCR_TRGB1888 + bool "25 bpp TRGB 1888" + +config SAMA5_LCDC_HCR_ARGB8888 + bool "32 bpp ARGB 8888" + +config SAMA5_LCDC_HCR_RGBA8888 + bool "32 bpp RGBA 8888" + +endchoice # Base layer color format +endif # SAMA5_LCDC_HCR + +config SAMA5_LCDC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # LCDC configuration +endif # SAMA5_LCDC + +if SAMA5_GMAC + +menu "GMAC device driver options" + +config SAMA5_GMAC_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + GMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAMA5_GMAC_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + GMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAMA5_GMAC_PREALLOCATE + bool "Preallocate buffers" + default n + ---help--- + Buffer an descriptor many may either be allocated from the memory + pool or pre-allocated to lie in .bss. This options selected pre- + allocated buffer memory. + +config SAMA5_GMAC_NBC + bool "Disable Broadcast" + default n + ---help--- + Select to disable receipt of broadcast packets. + +config SAMA5_GMAC_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAMA5_GMAC_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAMA5_GMAC_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAMA5 GMAC driver will call this function + one time before it first uses the PHY. + +config SAMA5_GMAC_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +if !SAMA5_GMAC_AUTONEG + +config SAMA5_GMAC_ETHFD + bool "Full duplex" + default n + ---help--- + If SAMA5_GMAC_AUTONEG is not defined, then this may be defined to + select full duplex mode. Default: half-duplex + +choice + prompt "GMAC Speed" + default SAMA5_GMAC_ETH100MBPS + ---help--- + If autonegotiation is not used, then you must select the fixed speed + of the PHY + +config SAMA5_GMAC_ETH10MBPS + bool "10 Mbps" + ---help--- + If SAMA5_GMAC_AUTONEG is not defined, then this may be defined to select 10 MBps + speed. Default: 100 Mbps + +config SAMA5_GMAC_ETH100MBPS + bool "100 Mbps" + ---help--- + If SAMA5_GMAC_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 100 Mbps + +config SAMA5_GMAC_ETH1000MBPS + bool "1000 Mbps" + ---help--- + If SAMA5_GMAC_AUTONEG is not defined, then this may be defined to select 1000 MBps + speed. Default: 100 Mbps + +endchoice # GMAC speed +endif # !SAMA5_GMAC_AUTONEG + +config SAMA5_GMAC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # GMAC device driver options +endif # SAMA5_GMAC + +if SAMA5_EMACA + +menu "EMAC device driver options" + +config SAMA5_EMAC_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + EMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAMA5_EMAC_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + EMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAMA5_EMAC_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAMA5_EMAC_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAMA5_EMAC_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAMA5 EMAC driver will call this function + one time before it first uses the PHY. + +config SAMA5_EMAC_MII + bool "Use MII interface" + default n + ---help--- + Support Ethernet MII interface (vs RMII). + +config SAMA5_EMAC_RMII + bool + default y if !SAMA5_EMAC_MII + default n if SAMA5_EMAC_MII + +config SAMA5_EMAC_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config SAMA5_EMAC_ETHFD + bool "Full duplex" + default n + depends on !SAMA5_EMAC_AUTONEG + ---help--- + If SAMA5_EMAC_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config SAMA5_EMAC_ETH100MBPS + bool "100 Mbps" + default n + depends on !SAMA5_EMAC_AUTONEG + ---help--- + If SAMA5_EMAC_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config SAMA5_EMAC_PHYSR + int "PHY Status Register Address (decimal)" + depends on SAMA5_EMAC_AUTONEG + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config SAMA5_EMAC_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on SAMA5_EMAC_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +if SAMA5_EMAC_AUTONEG +if SAMA5_EMAC_PHYSR_ALTCONFIG + +config SAMA5_EMAC_PHYSR_ALTMODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config SAMA5_EMAC_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config SAMA5_EMAC_PHYSR_100HD + hex "100Base-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config SAMA5_EMAC_PHYSR_10FD + hex "10Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config SAMA5_EMAC_PHYSR_100FD + hex "100Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +endif # SAMA5_EMAC_PHYSR_ALTCONFIG +if !SAMA5_EMAC_PHYSR_ALTCONFIG + +config SAMA5_EMAC_PHYSR_SPEED + hex "PHY Speed Mask" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config SAMA5_EMAC_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config SAMA5_EMAC_PHYSR_MODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config SAMA5_EMAC_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + ---help--- + This must be provided if SAMA5_EMAC_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +endif # !SAMA5_EMAC_PHYSR_ALTCONFIG +endif # SAMA5_EMAC_AUTONEG + +config SAMA5_EMACA_PREALLOCATE + bool "Preallocate buffers" + default n + ---help--- + Buffer an descriptor many may either be allocated from the memory + pool or pre-allocated to lie in .bss. This options selected pre- + allocated buffer memory. + +config SAMA5_EMACA_NBC + bool "Disable Broadcast" + default n + ---help--- + Select to disable receipt of broadcast packets. + +config SAMA5_EMACA_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # EMAC device driver options +endif # SAMA5_EMACA + +if SAMA5_EMACB + +menu "EMAC device driver options" + +if SAMA5_EMAC0 + +menu "EMAC0 device driver options" + +config SAMA5_EMAC0_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + EMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAMA5_EMAC0_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + EMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAMA5_EMAC0_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAMA5_EMAC0_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAMA5_EMAC0_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAMA5 EMAC driver will call this function + one time before it first uses the PHY. + +choice + prompt "PHY interface" + default SAMA5_EMAC0_MII + +config SAMA5_EMAC0_MII + bool "MII" + ---help--- + Support Ethernet MII interface (vs RMII). + +config SAMA5_EMAC0_RMII + bool "RMII" + depends on !ARCH_CHIP_SAM4E + ---help--- + Support Ethernet RMII interface (vs MII). + +endchoice # PHY interface + +config SAMA5_EMAC0_CLAUSE45 + bool "Clause 45 MII" + depends on SAMA5_EMAC0_MII + ---help--- + MDIO was originally defined in Clause 22 of IEEE RFC802.3. In the + original specification, a single MDIO interface is able to access up + to 32 registers in 32 different PHY devices. To meet the needs the + expanding needs of 10-Gigabit Ethernet devices, Clause 45 of the + 802.3ae specification provided the following additions to MDIO: + + - Ability to access 65,536 registers in 32 different devices on + 32 different ports + - Additional OP-code and ST-code for Indirect Address register + access for 10 Gigabit Ethernet + - End-to-end fault signaling + - Multiple loopback points + - Low voltage electrical specification + + By default, Clause 22 PHYs will be supported unless this option is + selected. + +config SAMA5_EMAC0_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config SAMA5_EMAC0_ETHFD + bool "Full duplex" + default n + depends on !SAMA5_EMAC0_AUTONEG + ---help--- + If SAMA5_EMAC0_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config SAMA5_EMAC0_ETH100MBPS + bool "100 Mbps" + default n + depends on !SAMA5_EMAC0_AUTONEG + ---help--- + If SAMA5_EMAC0_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config SAMA5_EMAC0_PHYSR + int "PHY Status Register Address (decimal)" + depends on SAMA5_EMAC0_AUTONEG + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config SAMA5_EMAC0_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on SAMA5_EMAC0_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +if SAMA5_EMAC0_AUTONEG +if SAMA5_EMAC0_PHYSR_ALTCONFIG + +config SAMA5_EMAC0_PHYSR_ALTMODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config SAMA5_EMAC0_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config SAMA5_EMAC0_PHYSR_100HD + hex "100Base-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config SAMA5_EMAC0_PHYSR_10FD + hex "10Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config SAMA5_EMAC0_PHYSR_100FD + hex "100Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +endif # SAMA5_EMAC0_PHYSR_ALTCONFIG +if !SAMA5_EMAC0_PHYSR_ALTCONFIG + +config SAMA5_EMAC0_PHYSR_SPEED + hex "PHY Speed Mask" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config SAMA5_EMAC0_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config SAMA5_EMAC0_PHYSR_MODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This provides the + bit mask for isolating the full or half duplex mode bits. + +config SAMA5_EMAC0_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + ---help--- + This must be provided if SAMA5_EMAC0_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +endif # !SAMA5_EMAC0_PHYSR_ALTCONFIG +endif # SAMA5_EMAC0_AUTONEG +endmenu # EMAC0 device driver options +endif # SAMA5_EMAC0 + +if SAMA5_EMAC1 + +menu "EMAC1 device driver options" + +config SAMA5_EMAC1_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + EMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAMA5_EMAC1_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + EMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAMA5_EMAC1_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAMA5_EMAC1_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAMA5_EMAC1_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAMA5 EMAC driver will call this function + one time before it first uses the PHY. + +choice + prompt "PHY interface" + default SAMA5_EMAC1_MII + +config SAMA5_EMAC1_MII + bool "MII" + ---help--- + Support Ethernet MII interface (vs RMII). + +config SAMA5_EMAC1_RMII + bool "RMII" + depends on !ARCH_CHIP_SAM4E + ---help--- + Support Ethernet RMII interface (vs MII). + +endchoice # PHY interface + +config SAMA5_EMAC1_CLAUSE45 + bool "Clause 45 MII" + depends on SAMA5_EMAC1_MII + ---help--- + MDIO was originally defined in Clause 22 of IEEE RFC802.3. In the + original specification, a single MDIO interface is able to access up + to 32 registers in 32 different PHY devices. To meet the needs the + expanding needs of 10-Gigabit Ethernet devices, Clause 45 of the + 802.3ae specification provided the following additions to MDIO: + + - Ability to access 65,536 registers in 32 different devices on + 32 different ports + - Additional OP-code and ST-code for Indirect Address register + access for 10 Gigabit Ethernet + - End-to-end fault signaling + - Multiple loopback points + - Low voltage electrical specification + + By default, Clause 22 PHYs will be supported unless this option is + selected. + +config SAMA5_EMAC1_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config SAMA5_EMAC1_ETHFD + bool "Full duplex" + default n + depends on !SAMA5_EMAC1_AUTONEG + ---help--- + If SAMA5_EMAC1_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config SAMA5_EMAC1_ETH100MBPS + bool "100 Mbps" + default n + depends on !SAMA5_EMAC1_AUTONEG + ---help--- + If SAMA5_EMAC1_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config SAMA5_EMAC1_PHYSR + int "PHY Status Register Address (decimal)" + depends on SAMA5_EMAC1_AUTONEG + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config SAMA5_EMAC1_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on SAMA5_EMAC1_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +if SAMA5_EMAC1_AUTONEG +if SAMA5_EMAC1_PHYSR_ALTCONFIG + +config SAMA5_EMAC1_PHYSR_ALTMODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config SAMA5_EMAC1_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config SAMA5_EMAC1_PHYSR_100HD + hex "100Base-T Half Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config SAMA5_EMAC1_PHYSR_10FD + hex "10Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config SAMA5_EMAC1_PHYSR_100FD + hex "100Base-T Full Duplex Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +endif # SAMA5_EMAC1_PHYSR_ALTCONFIG +if !SAMA5_EMAC1_PHYSR_ALTCONFIG + +config SAMA5_EMAC1_PHYSR_SPEED + hex "PHY Speed Mask" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config SAMA5_EMAC1_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config SAMA5_EMAC1_PHYSR_MODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config SAMA5_EMAC1_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + ---help--- + This must be provided if SAMA5_EMAC1_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +endif # !SAMA5_EMAC1_PHYSR_ALTCONFIG +endif # SAMA5_EMAC1_AUTONEG +endmenu # EMAC1 device driver options +endif # SAMA5_EMAC1 + +# These apply to both EMAC0 and EMAC1 + +config SAMA5_EMACB_PREALLOCATE + bool "Preallocate buffers" + default n + ---help--- + Buffer an descriptor many may either be allocated from the memory + pool or pre-allocated to lie in .bss. This options selected pre- + allocated buffer memory. + +config SAMA5_EMACB_NBC + bool "Disable Broadcast" + default n + ---help--- + Select to disable receipt of broadcast packets. + +config SAMA5_EMACB_DEBUG + bool "Force EMAC0/1 DEBUG" + default n + depends on DEBUG && !DEBUG_NET + ---help--- + This option will force debug output from EMAC driver even without + network debug output enabled. This is not normally something + that would want to do but is convenient if you are debugging the + driver and do not want to get overloaded with other + network-related debug output. + +config SAMA5_EMACB_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # EMAC device driver options +endif # SAMA5_EMACB + +if SAMA5_EMACA || SAMA5_EMAC0 || SAMA5_EMAC1 || SAMA5_GMAC +choice + prompt "Which device is eth0" + default SAMA5_GMAC_ISETH0 if SAMA5_GMAC + default SAMA5_EMAC_ISETH0 if SAMA5_EMACA && !SAMA5_GMAC + default SAMA5_EMAC0_ISETH0 if SAMA5_EMAC0 && !SAM_EMAC && !SAMA5_GMAC + default SAMA5_EMAC1_ISETH0 if SAMA5_EMAC1 && !SAM_EMAC && !SAMA5_EMAC0 && !SAMA5_GMAC + +config SAMA5_EMAC_ISETH0 + bool "EMAC is eth0" + depends on SAMA5_EMACA + +config SAMA5_EMAC0_ISETH0 + bool "EMAC0 is eth0" + depends on SAMA5_EMAC0 + +config SAMA5_EMAC1_ISETH0 + bool "EMAC1 is eth0" + depends on SAMA5_EMAC1 + +config SAMA5_GMAC_ISETH0 + bool "GMAC is ETH0" + depends on SAMA5_GMAC + +endchoice # Which device is eth0 +endif # SAMA4_EMAC || SAMA5_EMAC0 || SAMA5_EMAC1 || SAMA5_GMAC + +if SAMA5_CAN0 || SAMA5_CAN1 + +menu "CAN device driver options" + +if SAMA5_CAN0 + +config SAMA5_CAN0_BAUD + int "CAN0 BAUD" + default 250000 + depends on SAMA5_CAN0 + ---help--- + CAN0 BAUD rate. Required if SAMA5_CAN0 is defined. + +config SAMA5_CAN0_NRECVMB + int "Number of receive mailboxes" + default 1 + range 1 3 + ---help--- + The SAMA5 CAN0 peripheral supports 8 mailboxes that can be used for + sending and receiving messages. Up the three of these can be set + aside statically for message reception. The remainder can be + configured dynamically to send CAN messages. Multiple receive + mailboxes might needed to either (1) receive bursts of messages, or + (2) to support multiple groups of messages filtered on message ID. + + NOTE: The maximum of 3 is a completely arbitrary design decision + and can certainly be changed if you need more. + +config SAMA5_CAN0_ADDR0 + hex "Mailbox 0 address" + ---help--- + This setting defines the address for receive mailbox 0. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + +config SAMA5_CAN0_MASK0 + hex "Mailbox 0 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 0. And + address matching SAMA5_CAN0_ADDR0 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + +config SAMA5_CAN0_ADDR1 + hex "Mailbox 1 address" + ---help--- + This setting defines the address for receive mailbox 1. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN0_NRECVMB is less than 2. + +config SAMA5_CAN0_MASK1 + hex "Mailbox 1 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 1. And + address matching SAMA5_CAN0_ADDR1 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN0_NRECVMB is less than 2. + +config SAMA5_CAN0_ADDR2 + hex "Mailbox 2 address" + ---help--- + This setting defines the address for receive mailbox 2. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN0_NRECVMB is less than 3. + +config SAMA5_CAN0_MASK2 + hex "Mailbox 1 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 2. And + address matching SAMA5_CAN0_ADDR2 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN0_NRECVMB is less than 2. + +endif # SAMA5_CAN0 + +if SAMA5_CAN1 + +config SAMA5_CAN1_BAUD + int "CAN1 BAUD" + default 250000 + depends on SAMA5_CAN1 + ---help--- + CAN1 BAUD rate. Required if SAMA5_CAN1 is defined. + +config SAMA5_CAN1_NRECVMB + int "Number of receive mailboxes" + default 1 + range 1 3 + ---help--- + The SAMA5 CAN1 peripheral supports 8 mailboxes that can be used for + sending and receiving messages. Up the three of these can be set + aside statically for message reception. The remainder can be + configured dynamically to send CAN messages. Multiple receive + mailboxes might needed to either (1) receive bursts of messages, or + (2) to support multiple groups of messages filtered on message ID. + + NOTE: The maximum of 3 is a completely arbitrary design decision + and can certainly be changed if you need more. + +config SAMA5_CAN1_ADDR0 + hex "Mailbox 0 address" + ---help--- + This setting defines the address for receive mailbox 0. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + +config SAMA5_CAN1_MASK0 + hex "Mailbox 0 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 0. And + address matching SAMA5_CAN1_ADDR0 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + +config SAMA5_CAN1_ADDR1 + hex "Mailbox 1 address" + ---help--- + This setting defines the address for receive mailbox 1. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN0_NRECVMB is less than 2. + +config SAMA5_CAN1_MASK1 + hex "Mailbox 1 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 1. And + address matching SAMA5_CAN1_ADDR1 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN1_NRECVMB is less than 2. + +config SAMA5_CAN1_ADDR2 + hex "Mailbox 2 address" + ---help--- + This setting defines the address for receive mailbox 2. If CAN_EXTID + is defined, this should be a 29-bit extended CAN address; otherwise + it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN1_NRECVMB is less than 3. + +config SAMA5_CAN1_MASK2 + hex "Mailbox 2 address mask" + default 0x7fff if !CAN_EXTID + default 0x1fffffff if CAN_EXTID + ---help--- + This setting defines the address mask for receive mailbox 2. And + address matching SAMA5_CAN1_ADDR2 under this mask are accepted. The + default, all ones, forces an exact match. A value of zero will accept + any address. + + If CAN_EXTID is defined, this should be a 29-bit extended CAN address + mask; otherwise it should be an 11-bit standard CAN address. + + This setting is ignored if SAMA5_CAN1_NRECVMB is less than 3. + +endif # SAMA5_CAN1 + +config SAMA5_CAN_AUTOBAUD + bool "Enable auto-baud" + default n + depends on EXPERIMENTAL + ---help--- + Enable the SAMA5 auto-baud feature. NOTE: This feature is not yet + fully implemented. + +config SAMA5_CAN_REGDEBUG + bool "CAN Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level CAN device debug information. + Requires also DEBUG. + +endmenu # CAN device driver options +endif # SAMA5_CAN0 || SAMA5_CAN1 + +if SAMA5_SPI0 || SAMA5_SPI1 + +menu "SPI device driver options" + +config SAMA5_SPI_DMA + bool "SPI DMA" + default n + depends on (SAMA5_DMAC0 && SAMA5_SPI0) || (SAMA5_DMAC1 && SAMA5_SPI1) + ---help--- + Use DMA to improve SPI transfer performance. + +config SAMA5_SPI_DMATHRESHOLD + int "SPI DMA threshold" + default 4 + depends on SAMA5_SPI_DMA + ---help--- + When SPI DMA is enabled, small DMA transfers will still be performed + by polling logic. But we need a threshold value to determine what + is small. That value is provided by SAMA5_SPI_DMATHRESHOLD. + +config SAMA5_SPI_DMADEBUG + bool "SPI DMA transfer debug" + depends on SAMA5_SPI_DMA && DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze SPI DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAMA5_SPI_REGDEBUG + bool "SPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. + Requires also DEBUG. + +endmenu # SPI device driver options +endif # SAMA5_SPI0 || SAMA5_SPI1 + +if SAMA5_TWI0 || SAMA5_TWI1 || SAMA5_TWI2 || SAMA5_TWI3 + +menu "TWI device driver options" + +config SAMA5_TWI0_FREQUENCY + int "TWI0 Frequency" + default 100000 + depends on SAMA5_TWI0 + +config SAMA5_TWI1_FREQUENCY + int "TWI1 Frequency" + default 100000 + depends on SAMA5_TWI1 + +config SAMA5_TWI2_FREQUENCY + int "TWI2 Frequency" + default 100000 + depends on SAMA5_TWI2 + +config SAMA5_TWI3_FREQUENCY + int "TWI3 Frequency" + default 100000 + depends on SAMA5_TWI3 + +config SAMA5_TWI_REGDEBUG + bool "TWI register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level TWI device debug information. + Very invasive! Requires also DEBUG. + +endmenu # TWI device driver options +endif # SAMA5_TWI0 || SAMA5_TWI1 || SAMA5_TWI2 || SAMA5_TWI3 + +if SAMA5_SSC0 || SAMA5_SSC1 +menu "SSC Configuration" + +config SAMA5_SSC_MAXINFLIGHT + int "SSC queue size" + default 16 + ---help--- + This is the total number of transfers, both RX and TX, that can be + enqueue before the caller is required to wait. This setting + determines the number certain queue data structures that will be + pre-allocated. + +if SAMA5_SSC0 +comment "SSC0 Configuration" + +config SAMA5_SSC0_DATALEN + int "Data width (bits)" + default 16 + ---help--- + Data width in bits. This is a default value and may be change + via the I2S interface + +config SAMA5_SSC0_RX + bool "Enable I2C receiver" + default n + ---help--- + Enable I2S receipt logic + +if SAMA5_SSC0_RX + +choice + prompt "Receiver clock source" + default SAMA5_SSC0_RX_MCKDIV + +config SAMA5_SSC0_RX_RKINPUT + bool "RK input" + ---help--- + The SSC receiver clock is an external clock provided on the RK input + pin. Sample rate determined by the external clock frequency. + +config SAMA5_SSC0_RX_TXCLK + bool "Transmitter Clock" + ---help--- + The SSC receiver clock is transmitter clock. RX sample rate is the same + as the TX sample rate. + +config SAMA5_SSC0_RX_MCKDIV + bool "MCK/2" + ---help--- + The SSC receiver clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Receiver clock source + +if !SAMA5_SSC0_RX_RKINPUT +choice + prompt "Receiver output clock" + default SAMA5_SSC0_RX_RKOUTPUT_NONE + +config SAMA5_SSC0_RX_RKOUTPUT_NONE + bool "None" + +config SAMA5_SSC0_RX_RKOUTPUT_CONT + bool "Continuous" + +config SAMA5_SSC0_RX_RKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMA5_SSC0_RX_RKINPUT + +config SAMA5_SSC0_RX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 1 255 + ---help--- + This setting determines the pulse length of the Receive Frame Sync + signal in units of receive clock periods. + +config SAMA5_SSC0_RX_STTDLY + int "Receive Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + receive clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMA5_SSC0_RX + +config SAMA5_SSC0_TX + bool "Enable I2C transmitter" + default n + ---help--- + Enable I2S transmission logic + +if SAMA5_SSC0_TX + +choice + prompt "Transmitter clock source" + default SAMA5_SSC0_TX_MCKDIV + +config SAMA5_SSC0_TX_TKINPUT + bool "TK input" + ---help--- + The SSC transmitter clock is an external clock provided on the TK input + pin. Sample rate determined by the external clock frequency. + +config SAMA5_SSC0_TX_RXCLK + bool "Receiver Clock" + ---help--- + The SSC transmitter clock is receiver clock. TX sample rate is the same + as the RX sample rate. + +config SAMA5_SSC0_TX_MCKDIV + bool "MCK/2" + ---help--- + The SSC transmitter clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Transmitter clock source + +if !SAMA5_SSC0_TX_TKINPUT +choice + prompt "Transmitter output clock" + default SAMA5_SSC0_TX_TKOUTPUT_NONE + +config SAMA5_SSC0_TX_TKOUTPUT_NONE + bool "None" + +config SAMA5_SSC0_TX_TKOUTPUT_CONT + bool "Continuous" + +config SAMA5_SSC0_TX_TKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMA5_SSC0_TX_TKINPUT + +config SAMA5_SSC0_TX_FSLEN + int "Transmit Frame Sync Length" + default 1 + range 0 255 + ---help--- + This setting define the length of the Transmit Frame Sync signal in + units of transmit clock periods. A value of zero disables this + feature. In that case the TD line is driven with the default value + during the Transmit Frame Sync signal. + +config SAMA5_SSC0_TX_STTDLY + int "Transmit Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + transmit clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMA5_SSC0_TX + +config SAMA5_SSC0_MCKDIV_SAMPLERATE + int "Sample rate" + default 48000 + depends on SAMA5_SSC0_RX_MCKDIV || SAMA5_SSC0_TX_MCKDIV + ---help--- + If the either the receiver or transmitter clock is provided by MCK/2 divided + down, then the sample rate must be provided. The bit rate will be the product + of the sample rate and the data width. The SSC driver will determine the best + divider to obtain that bit rate (up to 4095). If the bit rate can be realized + by dividing down the MCK/2, a compile time error will occur. + +config SAMA5_SSC0_LOOPBACK + bool "Loopback mode" + default n + depends on SAMA5_SSC0_TX && SAMA5_SSC0_RX + ---help--- + If both the receiver and transmitter are enabled, then the SSC can + be configured in loopback mode. This setting selects SSC loopback + and will cause the LOOP bit to be set in the SSC_RFMR register. In + this case, RD is connected to TD, RF is connected to TF and RK is + connected to TK. + +endif # SAMA5_SSC0 + +if SAMA5_SSC1 +comment "SSC1 Configuration" + +config SAMA5_SSC1_DATALEN + int "Data width (bits)" + default 16 + ---help--- + Data width in bits. This is a default value and may be change + via the I2S interface + +config SAMA5_SSC1_RX + bool "Enable I2C receiver" + default n + ---help--- + Enable I2S receipt logic + +if SAMA5_SSC1_RX + +choice + prompt "Receiver clock source" + default SAMA5_SSC1_RX_MCKDIV + +config SAMA5_SSC1_RX_RKINPUT + bool "RK input" + ---help--- + The SSC receiver clock is an external clock provided on the RK input + pin. Sample rate determined by the external clock frequency. + +config SAMA5_SSC1_RX_TXCLK + bool "Transmitter Clock" + ---help--- + The SSC receiver clock is transmitter clock. RX sample rate is the same + as the TX sample rate. + +config SAMA5_SSC1_RX_MCKDIV + bool "MCK/2" + ---help--- + The SSC receiver clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Receiver clock source + +if !SAMA5_SSC1_RX_RKINPUT +choice + prompt "Receiver output clock" + default SAMA5_SSC1_RX_RKOUTPUT_NONE + +config SAMA5_SSC1_RX_RKOUTPUT_NONE + bool "None" + +config SAMA5_SSC1_RX_RKOUTPUT_CONT + bool "Continuous" + +config SAMA5_SSC1_RX_RKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMA5_SSC1_RX_RKINPUT + +config SAMA5_SSC1_RX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 1 255 + ---help--- + This setting determines the pulse length of the Receive Frame Sync + signal in units of receive clock periods. + +config SAMA5_SSC1_RX_STTDLY + int "Receive Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data of + receive clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMA5_SSC1_RX + +config SAMA5_SSC1_TX + bool "Enable I2C transmitter" + default n + ---help--- + Enable I2S transmission logic + +if SAMA5_SSC1_TX + +choice + prompt "Transmitter clock source" + default SAMA5_SSC1_TX_MCKDIV + +config SAMA5_SSC1_TX_TKINPUT + bool "TK input" + ---help--- + The SSC transmitter clock is an external clock provided on the TK input + pin. Sample rate determined by the external clock frequency. + +config SAMA5_SSC1_TX_RXCLK + bool "Receiver Clock" + ---help--- + The SSC transmitter clock is receiver clock. TX sample rate is the same + as the RX sample rate. + +config SAMA5_SSC1_TX_MCKDIV + bool "MCK/2" + ---help--- + The SSC transmitter clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Transmitter clock source + +if !SAMA5_SSC1_TX_TKINPUT +choice + prompt "Transmitter output clock" + default SAMA5_SSC1_TX_TKOUTPUT_NONE + +config SAMA5_SSC1_TX_TKOUTPUT_NONE + bool "None" + +config SAMA5_SSC1_TX_TKOUTPUT_CONT + bool "Continuous" + +config SAMA5_SSC1_TX_TKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMA5_SSC1_TX_TKINPUT + +config SAMA5_SSC1_TX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 0 255 + ---help--- + This setting define the length of the Transmit Frame Sync signal in + units of transmit clock periods. A value of zero disables this + feature. In that case the TD line is driven with the default value + during the Transmit Frame Sync signal. + +config SAMA5_SSC1_TX_STTDLY + int "Transmit Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + transmit clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMA5_SSC1_TX + +config SAMA5_SSC1_MCKDIV_SAMPLERATE + int "Sample rate" + default 48000 + depends on SAMA5_SSC1_RX_MCKDIV || SAMA5_SSC1_TX_MCKDIV + ---help--- + If the either the receiver or transmitter clock is provided by MCK/2 divided + down, then the sample rate must be provided. The bit rate will be the product + of the sample rate and the data width. The SSC driver will determine the best + divider to obtain that bit rate (up to 4095). If the bit rate can be realized + by dividing down the MCK/2, a compile time error will occur. + +config SAMA5_SSC1_LOOPBACK + bool "Loopback mode" + default n + depends on SAMA5_SSC1_TX && SAMA5_SSC1_RX + ---help--- + If both the receiver and transmitter are enabled, then the SSC can + be configured in loopback mode. This setting selects SSC loopback + and will cause the LOOP bit to be set in the SSC_RFMR register. In + this case, RD is connected to TD, RF is connected to TF and RK is + connected to TK. + +endif # SAMA5_SSC1 + +config SAMA5_SSC_DMADEBUG + bool "SSC DMA transfer debug" + depends on DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze SSC DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAMA5_SSC_REGDEBUG + bool "SSC Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SSC device debug information. + Very invasive! Requires also DEBUG. + +config SAMA5_SSC_QDEBUG + bool "SSC Queue debug" + depends on DEBUG_I2S + default n + ---help--- + Enable instrumentation to debug audio buffer queue logic. + +config SAMA5_SSC_DUMPBUFFERS + bool "Dump Buffers" + depends on DEBUG_I2S + default n + ---help--- + Enable instrumentation to dump TX and RX buffers. + +endmenu # SSC Configuration +endif # SAMA5_SSC0 || SAMA5_SSC1 + +if SAMA5_HSMCI0 || SAMA5_HSMCI1 || SAMA5_HSMCI2 +menu "HSMCI device driver options" + +if SAMA5_XDMAC0 || SAMA5_XDMAC1 + +choice + prompt "HSMCI0 XDMAC Selection" + default SAMA5_HSMCI0_XDMAC0 if SAMA5_XDMAC0 + default SAMA5_HSMCI0_XDMAC1 if !SAMA5_XDMAC0 && SAMA5_XDMAC1 + depends on SAMA5_HSMCI0 + +config SAMA5_HSMCI0_XDMAC0 + bool "XDMAC0 (always secure)" + depends on SAMA5_XDMAC0 + +config SAMA5_HSMCI0_XDMAC1 + bool "XDMAC1 (never secure)" + depends on SAMA5_XDMAC1 + +endchoice # HSMCI0 XDMAC Selection + +choice + prompt "HSMCI1 XDMAC Selection" + default SAMA5_HSMCI1_XDMAC0 if SAMA5_XDMAC0 + default SAMA5_HSMCI1_XDMAC1 if !SAMA5_XDMAC0 && SAMA5_XDMAC1 + depends on SAMA5_HSMCI1 + +config SAMA5_HSMCI1_XDMAC0 + bool "XDMAC0 (always secure)" + depends on SAMA5_XDMAC0 + +config SAMA5_HSMCI1_XDMAC1 + bool "XDMAC1 (never secure)" + depends on SAMA5_XDMAC1 + +endchoice # HSMCI1 XDMAC Selection + +# There is no HSMCI2 on the platforms that support XDMAC +endif # SAMA5_XDMAC0 || SAMA5_XDMAC1 + +config SAMA5_HSMCI_RDPROOF + bool "Read Proof Enable" + default n + ---help--- + Enabling Read Proof allows to stop the HSMCI Clock during read + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAMA5_HSMCI_WRPROOF + bool "Write Proof Enable" + default n + ---help--- + Enabling Write Proof allows to stop the HSMCI Clock during write + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAMA5_HSMCI_XFRDEBUG + bool "HSMCI transfer debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI data transfers. + This logic is as non-invasive as possible: It samples HSMCI + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. If DEBUG_DMA is also + enabled, then DMA register will be collected as well. Requires also + DEBUG_FS and DEBUG_VERBOSE. + +config SAMA5_HSMCI_CMDDEBUG + bool "HSMCI command debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI commands. This + logic is as non-invasive as possible: It samples HSMCI registers at + key points in the data transfer and then dumps all of the registers + at the end of the transfer. If DEBUG_DMA is also enabled, then DMA + register will be collected as well. Requires also DEBUG_FS and + DEBUG_VERBOSE. + +config SAMA5_HSMCI_REGDEBUG + bool "HSMCI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level HSCMI device debug information. + Very invasive! Requires also DEBUG. + +endmenu # HSMCI device driver options +endif # SAMA5_HSMCI0 || SAMA5_HSMCI1 || SAMA5_HSMCI2 + +if SAMA5_UDPHS +menu "USB High Speed Device Controller driver (DCD) options" + +config SAMA5_UDPHS_SCATTERGATHER + bool + default n + depends on EXPERIMENTAL + ---help--- + Scatter gather DMA is not yet supported + +config SAMA5_UDPHS_NDTDS + int "Number of UDPHS DMA transfer descriptors" + default 8 + ---help--- + DMA transfer descriptors are allocated in a pool at boot time. This + setting provides the number of DMA transfer descriptors to be + allocated. + +config SAMA5_UDPHS_PREALLOCATE + bool "Pre-allocate DMA transfer descriptors" + default y + ---help--- + If this option is selected then DMA transfer descriptors will be + pre-allocated in .bss. Otherwise, the descriptors will be allocated + at start-up time with kmm_malloc(). This might be important if a larger + memory pool is available after startup. + +config SAMA5_UDPHS_REGDEBUG + bool "Enable low-level UDPHS register debug" + default n + depends on DEBUG + +endmenu # USB High Speed Device Controller driver (DCD) options +endif # SAMA5_UDPHS + +if SAMA5_UHPHS +menu "USB High Speed Host Controller driver (HCD) options" + +config SAMA5_OHCI + bool "Full/low speed OHCI support" + default n + select USBHOST + select USBHOST_HAVE_ASYNCH + ---help--- + Build support for the SAMA5 USB full speed Open Host Controller + Interface (OHCI). + +if SAMA5_OHCI +config SAMA5_OHCI_NEDS + int "Number of endpoint descriptors" + default 6 + +config SAMA5_OHCI_NTDS + int "Number of transfer descriptors" + default 9 + +config SAMA5_OHCI_TDBUFFERS + int "Number of transfer descriptor buffers" + default 6 + +config SAMA5_OHCI_TDBUFSIZE + int "Size of one transfer descriptor buffer" + default 128 + ---help--- + The size of one transfer descriptor (TD) buffer in bytes. The TD + buffer size must be an even number of 32-bit words + +config SAMA5_OHCI_REGDEBUG + bool "Enable low-level OHCI register debug" + default n + depends on DEBUG + +endif # SAMA5_OHCI + +config SAMA5_EHCI + bool "High speed EHCI support" + default n + select USBHOST + select USBHOST_HAVE_ASYNCH + ---help--- + Build support for the SAMA5 USB high speed Enhanced Host Controller + Interface (EHCI). If low/full speed is needed too, then you must + also enable the OHCI controller. + +if SAMA5_EHCI + +config SAMA5_EHCI_NQHS + int "Number of Queue Head (QH) structures" + default 4 + ---help--- + Configurable number of Queue Head (QH) structures. The default is + one per Root hub port plus one for EP0 (4). + +config SAMA5_EHCI_NQTDS + int "Number of Queue Element Transfer Descriptor (qTDs)" + default 6 + ---help--- + Configurable number of Queue Element Transfer Descriptor (qTDs). + The default is one per root hub plus three from EP0 (6). + +config SAMA5_EHCI_BUFSIZE + int "Size of one request/descriptor buffer" + default 128 + ---help--- + The size of one request/descriptor buffer in bytes. The TD buffe + size must be an even number of 32-bit words and must be large enough + to hangle the largest transfer via a SETUP request. + +config SAMA5_EHCI_PREALLOCATE + bool "Preallocate descriptor pool" + default y + ---help--- + Select this option to pre-allocate EHCI queue and descriptor + structure pools in .bss. Otherwise, these pools will be + dynamically allocated using kmm_memalign(). + +config SAMA5_EHCI_REGDEBUG + bool "Enable low-level EHCI register debug" + default n + depends on DEBUG + +endif # SAMA5_EHCI + +if SAMA5_OHCI || SAMA5_EHCI + +config SAMA5_UHPHS_RHPORT1 + bool "Use Port A" + default y + depends on !SAMA5_UDPHS + +config SAMA5_UHPHS_RHPORT2 + bool "Use Port B" + default y + +config SAMA5_UHPHS_RHPORT3 + bool "Use Port C" + default y + +endif # SAMA5_OHCI || SAMA5_EHCI + +endmenu # USB High Speed Host Controller driver (HCD) options +endif # SAMA5_UHPHS + +if SAMA5_ADC +menu "ADC configuration" + +config SAMA5_ADC_HAVE_CHAN + bool + default n + +menu "ADC Channel selection" + +config SAMA5_ADC_CHAN0 + bool "Channel 0" + default n + depends on !SAMA5_TSD + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 0 + +config SAMA5_ADC_CHAN1 + bool "Channel 1" + default n + depends on !SAMA5_TSD + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 1 + +config SAMA5_ADC_CHAN2 + bool "Channel 2" + default n + depends on !SAMA5_TSD + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 2 + +config SAMA5_ADC_CHAN3 + bool "Channel 3" + default n + depends on !SAMA5_TSD + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 3 + +config SAMA5_ADC_CHAN4 + bool "Channel 4" + default n + depends on !SAMA5_TSD || !SAMA5_TSD_5WIRE + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 4 + +config SAMA5_ADC_CHAN5 + bool "Channel 5" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 5 + +config SAMA5_ADC_CHAN6 + bool "Channel 6" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 6 + +config SAMA5_ADC_CHAN7 + bool "Channel 7" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 7 + +config SAMA5_ADC_CHAN8 + bool "Channel 8" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 8 + +config SAMA5_ADC_CHAN9 + bool "Channel 9" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 9 + +config SAMA5_ADC_CHAN10 + bool "Channel 10" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 10 + +config SAMA5_ADC_CHAN11 + bool "Channel 11" + default n + select SAMA5_ADC_HAVE_CHAN + ---help--- + Enable ADC sampling on ADC channel 11 + +endmenu # ADC Channel selection + +if SAMA5_ADC_HAVE_CHAN + +config SAMA5_ADC_DMA + bool "DMA Support" + default n + depends on SAMA5_DMAC1 + ---help--- + Enable DMA transfers of converted data. This option is only + useful if you have numerous DMA channels enabled. The end result + is that there will be one DMA interrupt per conversion sequence vs. + one interrupt per conversion. + +config SAMA5_ADC_DMASAMPLES + int "Number of DMA samples" + default 2 + depends on SAMA5_ADC_DMA + ---help--- + If DMA is enabled, then this will specify the number of sample to + collect before the DMA completes. This is actually the number of + triggers; the number of collected samples will be this value times + the number of channels that are enabled. You should also enable the + sequencer if you are DMAing multiple channels. + + A value of "1" would DMA one set of samples. That is not advised. + In that case the processing and data transfer overhead would be + greater than if DMA were disabled. A value of 2 or more should be + selected. + + The DMA logic uses ping-pong buffers, so the total buffering + requirement will be + + 2 Buffers * Number_of_ADC_Channels * SAMA5_ADC_DMASAMPLES * sizeof(uint16_t) + + So, for example, if you had 8 ADC channels and 8 triggers per DMA + transfer, then the total DMA buffering requirment would be: + + 2 * 8 * 8 * 2 = 256 bytes. + +config SAMA5_ADC_AUTOCALIB + bool "ADC auto-calibration" + default n + ---help--- + Perform ADC auto-calibration during the ADC initialization sequence + +config SAMA5_ADC_SEQUENCER + bool "ADC sequencer" + default n + ---help--- + Enable the sequencer to perform ADC conversions. Recommended if you + enable several ADC channels. + +config SAMA5_ADC_ANARCH + bool "Analog changes" + default n + ---help--- + This option allows you to select different gain, offset, and single + vs. differential modes for each channel. + +if SAMA5_ADC_ANARCH + +menu "Channel gain" + +config SAMA5_ADC_GAIN0 + int "Channel 0 gain" + default 1 + depends on SAMA5_ADC_CHAN0 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN1 + int "Channel 1 gain" + default 1 + depends on SAMA5_ADC_CHAN1 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN2 + int "Channel 2 gain" + default 1 + depends on SAMA5_ADC_CHAN2 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN3 + int "Channel 3 gain" + default 1 + depends on SAMA5_ADC_CHAN3 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN4 + int "Channel 4 gain" + default 1 + depends on SAMA5_ADC_CHAN4 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN5 + int "Channel 5 gain" + default 1 + depends on SAMA5_ADC_CHAN5 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN6 + int "Channel 6 gain" + default 1 + depends on SAMA5_ADC_CHAN6 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN7 + int "Channel 7 gain" + default 1 + depends on SAMA5_ADC_CHAN7 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN8 + int "Channel 8 gain" + default 1 + depends on SAMA5_ADC_CHAN8 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN9 + int "Channel 9 gain" + default 1 + depends on SAMA5_ADC_CHAN9 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN10 + int "Channel 10 gain" + default 1 + depends on SAMA5_ADC_CHAN10 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +config SAMA5_ADC_GAIN11 + int "Channel 11 gain" + default 1 + depends on SAMA5_ADC_CHAN11 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channel is configured for single ended + mode or as {0.5, 1, 2, 2} if the channel is configured for + differential mode. + +endmenu # Channel gain + +menu "Channel offsets" + +config SAMA5_ADC_OFFSET0 + bool "Channel 0 offset" + default n + depends on SAMA5_ADC_CHAN0 + ---help--- + Center the channel 0 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET1 + bool "Channel 1 offset" + default n + depends on SAMA5_ADC_CHAN1 + ---help--- + Center the channel 1 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET2 + bool "Channel 2 offset" + default n + depends on SAMA5_ADC_CHAN2 + ---help--- + Center the channel 2 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET3 + bool "Channel 3 offset" + default n + depends on SAMA5_ADC_CHAN3 + ---help--- + Center the channel 3 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET4 + bool "Channel 4 offset" + default n + depends on SAMA5_ADC_CHAN4 + ---help--- + Center the channel 4 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET5 + bool "Channel 5 offset" + default n + depends on SAMA5_ADC_CHAN5 + ---help--- + Center the channel 5 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET6 + bool "Channel 6 offset" + default n + depends on SAMA5_ADC_CHAN6 + ---help--- + Center the channel 6 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET7 + bool "Channel 7 offset" + default n + depends on SAMA5_ADC_CHAN7 + ---help--- + Center the channel 7 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET8 + bool "Channel 8 offset" + default n + depends on SAMA5_ADC_CHAN8 + ---help--- + Center the channel 8 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET9 + bool "Channel 9 offset" + default n + depends on SAMA5_ADC_CHAN9 + ---help--- + Center the channel 9 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET10 + bool "Channel 10 offset" + default n + depends on SAMA5_ADC_CHAN10 + ---help--- + Center the channel 10 analog signal on Vrefin/2 before the gain + scaling. + +config SAMA5_ADC_OFFSET11 + bool "Channel 11 offset" + default n + depends on SAMA5_ADC_CHAN11 + ---help--- + Center the channel 11 analog signal on Vrefin/2 before the gain + scaling. + +endmenu # Channel offsets + +menu "Channel differential mode" + +config SAMA5_ADC_DIFFMODE0 + bool "Channel 0 differential mode" + default n + depends on SAMA5_ADC_CHAN0 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 0 + +config SAMA5_ADC_DIFFMODE1 + bool "Channel 1 differential mode" + default n + depends on SAMA5_ADC_CHAN1 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 1 + +config SAMA5_ADC_DIFFMODE2 + bool "Channel 2 differential mode" + default n + depends on SAMA5_ADC_CHAN2 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 2 + +config SAMA5_ADC_DIFFMODE3 + bool "Channel 3 differential mode" + default n + depends on SAMA5_ADC_CHAN3 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 3 + +config SAMA5_ADC_DIFFMODE4 + bool "Channel 4 differential mode" + default n + depends on SAMA5_ADC_CHAN4 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 4 + +config SAMA5_ADC_DIFFMODE5 + bool "Channel 5 differential mode" + default n + depends on SAMA5_ADC_CHAN5 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 5 + +config SAMA5_ADC_DIFFMODE6 + bool "Channel 6 differential mode" + default n + depends on SAMA5_ADC_CHAN6 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 6 + +config SAMA5_ADC_DIFFMODE7 + bool "Channel 7 differential mode" + default n + depends on SAMA5_ADC_CHAN7 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 7 + +config SAMA5_ADC_DIFFMODE8 + bool "Channel 8 differential mode" + default n + depends on SAMA5_ADC_CHAN8 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 8 + +config SAMA5_ADC_DIFFMODE9 + bool "Channel 9 differential mode" + default n + depends on SAMA5_ADC_CHAN9 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 9 + +config SAMA5_ADC_DIFFMODE10 + bool "Channel 10 differential mode" + default n + depends on SAMA5_ADC_CHAN10 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 10 + +config SAMA5_ADC_DIFFMODE11 + bool "Channel 11 differential mode" + default n + depends on SAMA5_ADC_CHAN11 + ---help--- + Selects differential (vs. single-ended mode) for ADC channel 11 + +endmenu # Differential mode +endif # SAMA5_ADC_ANARCH + +if !SAMA5_ADC_ANARCH + +config SAMA5_ADC_GAIN + int "Analog gain" + default 1 + depends on SAMA5_ADC_CHAN0 + range 0 3 + ---help--- + Valid gain settings are {0, 1, 2, 3} which may be interpreted as + either {1, 1, 2, 4} if the channels are configured for single ended + mode or as {0.5, 1, 2, 2} if the channels are configured for + differential mode. + +config SAMA5_ADC_OFFSET + bool "Offset" + default n + ---help--- + Center the analog signal on Vrefin/2 before the gain scaling. + +config SAMA5_ADC_DIFFMODE + bool "Differential mode" + default n + ---help--- + Selects differential (vs. single-ended mode) + +endif # !SAMA5_ADC_ANARCH + +menu "ADC Trigger Selection" + +choice + prompt "ADC trigger mode" + default SAMA5_ADC_SWTRIG + ---help--- + Select the event that will trigger the A-to-D conversion sequence. + +config SAMA5_ADC_SWTRIG + bool "Software trigger" + ---help--- + A-to-D Conversion is initiated only by sofware via an ioctl() + +config SAMA5_ADC_ADTRG + bool "External trigger via the ADTRG pin" + ---help--- + A-to-D Conversion is initiated an event on the ADTRG pin. + +config SAMA5_ADC_TIOATRIG + bool "TC0 output A trigger" + depends on SAMA5_TC0 + ---help--- + A-to-D Conversion is initiated the A output from one of + Timer/Counter 0 channels. + +endchoice # Trigger mode + +choice + prompt "ADTRG edge" + default SAMA5_ADC_ADTRG_BOTH + depends on SAMA5_ADC_ADTRG + +config SAMA5_ADC_ADTRG_RISING + bool "Rising edge" + ---help--- + Trigger A-to-D conversion on the rising edge of the ADTRG signal. + +config SAMA5_ADC_ADTRG_FALLING + bool "Falling edge" + ---help--- + Trigger A-to-D conversion on the falling edge of the ADTRG signal. + +config SAMA5_ADC_ADTRG_BOTH + bool "Both edges" + ---help--- + Trigger A-to-D conversion on both edges of the ADTRG signal + +endchoice # ADTRG edge + +if SAMA5_ADC_TIOATRIG + +config SAMA5_ADC_TIOAFREQ + int "ADC sampling frequency" + default 1 + ---help--- + This setting provides the rate at which the timer will driver ADC + sampling. + +choice + prompt "TC0 channel" + default SAMA5_ADC_TIOA0TRIG + +config SAMA5_ADC_TIOA0TRIG + bool "TC0 Channel 0 Output A" + select SAMA5_TC0_TIOA0 + ---help--- + A-to-D conversion is triggered by the TC0 channel 0 output A signal. + This output must be enabled independently in the Timer/Counter + driver configuration for this to work. + +config SAMA5_ADC_TIOA1TRIG + bool "TC0 Channel 1 Output A" + select SAMA5_TC0_TIOA1 + ---help--- + A-to-D conversion is triggered by the TC0 channel 1 output A signal. + This output must be enabled independently in the Timer/Counter + driver configuration for this to work. + +config SAMA5_ADC_TIOA2TRIG + bool "TC0 Channel 2 Output A" + select SAMA5_TC0_TIOA2 + ---help--- + A-to-D conversion is triggered by the TC0 channel 2 output A signal. + This output must be enabled independently in the Timer/Counter + driver configuration for this to work. + +endchoice # TC0 channel + +choice + prompt "TIOAx edge" + default SAMA5_ADC_TIOA_BOTH + depends on SAMA5_ADC_TIOATRIG + +config SAMA5_ADC_TIOA_RISING + bool "Rising edge" + ---help--- + Trigger A-to-D conversion on the rising edge of the TIOAx signal. + +config SAMA5_ADC_TIOA_FALLING + bool "Falling edge" + ---help--- + Trigger A-to-D conversion on the falling edge of the TIOAx signal. + +config SAMA5_ADC_TIOA_BOTH + bool "Both edges" + ---help--- + Trigger A-to-D conversion on both edges of the TIOAx signal + +endchoice # ADTRG edge +endif # SAMA5_ADC_TIOATRIG +endmenu # ADC Trigger Selection +endif # SAMA5_ADC_HAVE_CHAN + +config SAMA5_ADC_REGDEBUG + bool "Enable register-level ADC/touchscreen debug" + default n + depends on DEBUG + ---help--- + Enable very low register-level debug output. + +endmenu # ADC Configuration + +menu "Touchscreen configuration" + +config SAMA5_TSD + bool "Touchscreen support" + default n +# depends on !SAMA5_ADC_HAVE_CHAN || EXPERIMENTAL + select INPUT + ---help--- + Configure the ADC to support a touchscreen + +if SAMA5_TSD + +choice + prompt "Touchscreen interface" + default SAMA5_TSD_4WIRE + ---help--- + Select the type of physical interface to the touchscreen + +config SAMA5_TSD_4WIRE + bool "4-wire interface (with pressure)" + +config SAMA5_TSD_4WIRENPM + bool "4-wire interface (without pressure)" + +config SAMA5_TSD_5WIRE + bool "5-wire interface" + +endchoice # Touchscreen interface + +config SAMA5_TSD_SWAPXY + bool "Swap X/Y" + default n + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config SAMA5_TSD_THRESHX + int "X threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduces data rate for some + loss in dragging accuracy. For 12-bit values so the raw ranges are + 0-4095. So for example, if your display is 320x240, then THRESHX=13 + and THRESHY=17 would correspond to one pixel. Default: 12 + +config SAMA5_TSD_THRESHY + int "Y threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduces data rate for some + loss in dragging accuracy. For 12-bit values so the raw ranges are + 0-4095. So for example, if your display is 320x240, then THRESHX=13 + and THRESHY=17 would correspond to one pixel. Default: 12 + +config SAMA_TSD_RXP + int "X-panel resistance" + default 6 + depends on SAMA5_TSD_4WIRE + ---help--- + The method to measure the pressure (Rp) applied to the touchscreen is + based on the known resistance of the X-Panel resistance (Rxp). + +config SAMA5_TSD_NPOLLWAITERS + int "Number poll waiters" + default 4 + depends on !DISABLE_POLL + ---help--- + Maximum number of threads that can be waiting on poll() + +endif # SAMA5_TSD +endmenu # Touchscreen Configuration +endif # SAMA5_ADC + +if SAMA5_HAVE_TC +menu "Timer/counter Configuration" + +if SAMA5_TC0 + +config SAMA5_TC0_CLK0 + bool "Enable TC0 channel 0 clock input pin" + default n + +config SAMA5_TC0_TIOA0 + bool "Enable TC0 channel 0 output A" + default n + +config SAMA5_TC0_TIOB0 + bool "Enable TC0 channel 0 output B" + default n + +config SAMA5_TC0_CLK1 + bool "Enable TC0 channel 1 clock input pin" + default n + +config SAMA5_TC0_TIOA1 + bool "Enable TC0 channel 1 output A" + default n + +config SAMA5_TC0_TIOB1 + bool "Enable TC0 channel 1 output B" + default n + +config SAMA5_TC0_CLK2 + bool "Enable TC0 channel 2 clock input pin" + default n + +config SAMA5_TC0_TIOA2 + bool "Enable TC0 channel 2 output A" + default n + +config SAMA5_TC0_TIOB2 + bool "Enable TC0 channel 2 output B" + default n + +endif # SAMA5_TC0 + +if SAMA5_TC1 + +config SAMA5_TC1_CLK3 + bool "Enable TC1 channel 3 clock input pin" + default n + +config SAMA5_TC1_TIOA3 + bool "Enable TC1 channel 3 output A" + default n + +config SAMA5_TC1_TIOB3 + bool "Enable TC1 channel 3 output B" + default n + +config SAMA5_TC1_CLK4 + bool "Enable TC1 channel 4 clock input pin" + default n + +config SAMA5_TC1_TIOA4 + bool "Enable TC1 channel 4 output A" + default n + +config SAMA5_TC1_TIOB4 + bool "Enable TC1 channel 4 output B" + default n + +config SAMA5_TC1_CLK5 + bool "Enable TC1 channel 5 clock input pin" + default n + +config SAMA5_TC1_TIOA5 + bool "Enable TC1 channel 5 output A" + default n + +config SAMA5_TC1_TIOB5 + bool "Enable TC1 channel 5 output B" + default n + +endif # SAMA5_TC1 + +if SAMA5_TC2 + +config SAMA5_TC2_CLK6 + bool "Enable TC2 channel 6 clock input pin" + default n + +config SAMA5_TC2_TIOA6 + bool "Enable TC2 channel 6 output A" + default n + +config SAMA5_TC2_TIOB6 + bool "Enable TC2 channel 6 output B" + default n + +config SAMA5_TC2_CLK7 + bool "Enable TC2 channel 7 clock input pin" + default n + +config SAMA5_TC2_TIOA7 + bool "Enable TC2 channel 7 output A" + default n + +config SAMA5_TC2_TIOB7 + bool "Enable TC2 channel 7 output B" + default n + +config SAMA5_TC2_CLK8 + bool "Enable TC2 channel 8 clock input pin" + default n + +config SAMA5_TC2_TIOA8 + bool "Enable TC2 channel 8 output A" + default n + +config SAMA5_TC2_TIOB8 + bool "Enable TC2 channel 8 output B" + default n + +endif # SAMA5_TC2 + +config SAMA5_ONESHOT + bool "TC one-shot wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config SAMA5_FREERUN + bool "TC free-running wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support a free-running timer. + +if SCHED_TICKLESS + +config SAMA5_TICKLESS_ONESHOT + int "Tickless one-shot timer channel" + default 0 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the one-shot timer needed by the OS. + +config SAMA5_TICKLESS_FREERUN + int "Tickless free-running timer channel" + default 1 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the free-running timer needed by the OS. + +endif + +config SAMA5_TC_DEBUG + bool "TC debug" + depends on DEBUG + default n + ---help--- + Output high level Timer/Counter device debug information. + Requires also DEBUG. If this option AND DEBUG_VERBOSE are + enabled, then the system will be overwhelmed the timer debug + output. If DEBUG_VERBOSE is disabled, then debug output will + only indicate if/when timer-related errors occur. This + latter mode is completely usable. + +config SAMA5_TC_REGDEBUG + bool "TC register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level Timer/Counter device debug + information. Very invasive! Requires also DEBUG. + +endmenu # Timer/counter Configuration +endif # SAMA5_HAVE_TC + +if SAMA5_PWM +menu "PWM configuration" + +config SAMA5_PWM_CLKA + bool "Enable PWM CLKA" + default n + ---help--- + Enable the PWM CLKA source. + +config SAMA5_PWM_CLKA_FREQUENCY + int "CLKA frequency" + default 1000 + depends on SAMA5_PWM_CLKA + ---help--- + If the CLKA source is enabled, then you must also provide the + frequency of the CLKA. This frequency will be derived from from MCK + using a prescaler and divider. Therefore, a wide range of + frequencies are possible. + +config SAMA5_PWM_CLKB + bool "Enable PWM CLKB" + default n + ---help--- + Enable the PWM CLKB source. + +config SAMA5_PWM_CLKB_FREQUENCY + int "CLKB frequency" + default 1000 + depends on SAMA5_PWM_CLKB + ---help--- + If the CLKB source is enabled, then you must also provide the + frequency of the CLKB. This frequency will be derived from from MCK + using a prescaler and divider. Therefore, a wide range of + frequencies are possible. + +config SAMA5_PWM_CHAN0 + bool "Enable PWM channel 0" + default n + +if SAMA5_PWM_CHAN0 + +choice + prompt "PWM channel 0 clock source" + default SAMA5_PWM_CHAN0_MCK + +config SAMA5_PWM_CHAN0_MCK + bool "MCK (divided)" + +config SAMA5_PWM_CHAN0_CLKA + bool "CLKA" + depends on SAMA5_PWM_CLKA + +config SAMA5_PWM_CHAN0_CLKB + bool "CLKB" + depends on SAMA5_PWM_CLKB + +endchoice # PWM channel 0 clock source + +config SAMA5_PWM_CHAN0_MCKDIV + int "MCK divider" + default 1 + depends on SAMA5_PWM_CHAN0_MCK + ---help--- + If source clock for the PWM channel is the MCK, then you must also + specify the MCK divider to use with the MCK. The only valid options + are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other + selections will cause compile time errors. + +config SAMA5_PWM_CHAN0_OUTPUTH + bool "Configure OUTPUT H pin" + default y + +config SAMA5_PWM_CHAN0_OUTPUTL + bool "Configure OUTPUT L pin" + default n + +config SAMA5_PWM_CHAN0_FAULTINPUT + bool "Configure Fault Input pin" + default n + +endif # SAMA5_PWM_CHAN0 + +config SAMA5_PWM_CHAN1 + bool "Enable PWM channel 1" + default n + +if SAMA5_PWM_CHAN1 + +choice + prompt "PWM channel 1 clock source" + default SAMA5_PWM_CHAN1_MCK + +config SAMA5_PWM_CHAN1_MCK + bool "MCK (divided)" + +config SAMA5_PWM_CHAN1_CLKA + bool "CLKA" + depends on SAMA5_PWM_CLKA + +config SAMA5_PWM_CHAN1_CLKB + bool "CLKB" + depends on SAMA5_PWM_CLKB + +endchoice # PWM channel 1 clock source + +config SAMA5_PWM_CHAN1_MCKDIV + int "MCK divider" + default 1 + depends on SAMA5_PWM_CHAN1_MCK + ---help--- + If source clock for the PWM channel is the MCK, then you must also + specify the MCK divider to use with the MCK. The only valid options + are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other + selections will cause compile time errors. + +config SAMA5_PWM_CHAN1_OUTPUTH + bool "Configure OUTPUT H pin" + default y + +config SAMA5_PWM_CHAN1_OUTPUTL + bool "Configure OUTPUT L pin" + default n + +config SAMA5_PWM_CHAN1_FAULTINPUT + bool "Configure Fault Input pin" + default n + +endif # SAMA5_PWM_CHAN1 + +config SAMA5_PWM_CHAN2 + bool "Enable PWM channel 2" + default n + +if SAMA5_PWM_CHAN2 + +choice + prompt "PWM channel 2 clock source" + default SAMA5_PWM_CHAN2_MCK + +config SAMA5_PWM_CHAN2_MCK + bool "MCK (divided)" + +config SAMA5_PWM_CHAN2_CLKA + bool "CLKA" + depends on SAMA5_PWM_CLKA + +config SAMA5_PWM_CHAN2_CLKB + bool "CLKB" + depends on SAMA5_PWM_CLKB + +endchoice # PWM channel 2 clock source + +config SAMA5_PWM_CHAN2_MCKDIV + int "MCK divider" + default 1 + depends on SAMA5_PWM_CHAN2_MCK + ---help--- + If source clock for the PWM channel is the MCK, then you must also + specify the MCK divider to use with the MCK. The only valid options + are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other + selections will cause compile time errors. + +config SAMA5_PWM_CHAN2_OUTPUTH + bool "Configure OUTPUT H pin" + default y + +config SAMA5_PWM_CHAN2_OUTPUTL + bool "Configure OUTPUT L pin" + default n + +config SAMA5_PWM_CHAN2_FAULTINPUT + bool "Configure Fault Input pin" + default n + +endif # SAMA5_PWM_CHAN2 + +config SAMA5_PWM_CHAN3 + bool "Enable PWM channel 3" + default n + +if SAMA5_PWM_CHAN3 + +choice + prompt "PWM channel 3 clock source" + default SAMA5_PWM_CHAN3_MCK + +config SAMA5_PWM_CHAN3_MCK + bool "MCK (divided)" + +config SAMA5_PWM_CHAN3_CLKA + bool "CLKA" + depends on SAMA5_PWM_CLKA + +config SAMA5_PWM_CHAN3_CLKB + bool "CLKB" + depends on SAMA5_PWM_CLKB + +endchoice # PWM channel 3 clock source + +config SAMA5_PWM_CHAN3_MCKDIV + int "MCK divider" + default 1 + depends on SAMA5_PWM_CHAN3_MCK + ---help--- + If source clock for the PWM channel is the MCK, then you must also + specify the MCK divider to use with the MCK. The only valid options + are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other + selections will cause compile time errors. + +config SAMA5_PWM_CHAN3_OUTPUTH + bool "Configure OUTPUT H pin" + default y + +config SAMA5_PWM_CHAN3_OUTPUTL + bool "Configure OUTPUT L pin" + default n + +config SAMA5_PWM_CHAN3_FAULTINPUT + bool "Configure Fault Input pin" + default n + +endif # SAMA5_PWM_CHAN3 + +config SAMA5_PWM_REGDEBUG + bool "Enable register-level PWM debug" + default n + depends on DEBUG + ---help--- + Enable very low register-level debug output. + +endmenu # PWM configuration +endif # SAMA5_PWM + +if SAMA5_WDT + +menu "Watchdog Configuration" + +config SAMA5_WDT_INTERRUPT + bool "Interrupt on timeout" + default n + ---help--- + The normal behavior is to reset everything when a watchdog timeout + occurs. An alternative behavior is to simply interrupt when the + timeout occurs. This setting enables that alternative behavior. + +config SAMA5_WDT_DEBUGHALT + bool "Halt on DEBUG" + default y if DEBUG + default n if !DEBUG + ---help--- + Halt the watchdog timer in the debug state + +config SAMA5_WDT_IDLEHALT + bool "Halt in IDLE" + default y + ---help--- + Halt the watchdog timer in the IDLE state + +config SAMA5_WDT_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enable low-level register debug output + +endmenu # Watchdog configuration +endif # SAMA5_WDT + +menu "External Memory Configuration" + +config SAMA5_DDRCS + bool "External DDR-SDRAM Memory" + default n + depends on SAMA5_MPDDRC + select ARCH_HAVE_SDRAM + ---help--- + Build in support for DDR-SDRAM memory resources. + +if SAMA5_DDRCS + +config SAMA5_DDRCS_SIZE + int "DDR-SDRAM Memory size" + default 0 + ---help--- + Mapped size of the DDR-SDRAM memory region. + +choice + prompt "DDR-SDRAM Memory Type" + default SAMA5_DDRCS_LPDDR1 + ---help--- + Select the type of DDR-SDRAM memory present + +config SAMA5_DDRCS_LPDDR1 + bool "Low-power DDR1-SDRAM (LPDDR1)" + +config SAMA5_DDRCS_LPDDR2 + bool "Low-power DDR2-SDRAM-S4 (LPDDR2)" + +endchoice # DDR-SDRAM Memory Type +endif # SAMA5_DDRCS + +config SAMA5_EBICS0 + bool "External CS0 Memory" + default n + depends on SAMA5_HSMC + ---help--- + Build in support for memory resources in the chip select 0 (CS0) + memory region. + +if SAMA5_EBICS0 + +config SAMA5_EBICS0_SIZE + int "CS0 Memory size" + default 0 + ---help--- + Mapped size of the memory region at CS0. + +choice + prompt "CS0 Memory Type" + default SAMA5_EBICS0_NOR + ---help--- + Select the type of memory present on CS0 + +config SAMA5_EBICS0_SRAM + bool "SRAM" + +config SAMA5_EBICS0_PSRAM + bool "PSRAM" + +config SAMA5_EBICS0_PROM + bool "PROM" + +config SAMA5_EBICS0_EEPROM + bool "EEPROM" + +config SAMA5_EBICS0_EPROM + bool "EPROM" + +config SAMA5_EBICS0_LCD + bool "LCD" + +config SAMA5_EBICS0_NOR + bool "NOR Flash" + +# CS0 cannot support NAND +# config SAMA5_EBICS0_NAND +# bool "NAND Flash" +# select MTD +# select MTD_NAND +# select SAMA5_HAVE_NAND + +endchoice # CS0 Memory Type + +# CS0 cannot support NAND +# choice +# prompt "NAND ECC type" +# default SAMA5_EBICS0_ECCNONE +# depends on SAMA5_EBICS0_NAND +# +# config SAMA5_EBICS0_ECCNONE +# bool "No ECC" +# ---help--- +# Only raw transfers to/from NAND are supported +# +# config SAMA5_EBICS0_SWECC +# bool "Software ECC" +# depends on MTD_NAND_SWECC +# ---help--- +# ECC is performed by higher level software logic +# +# config SAMA5_EBICS0_PMECC +# bool "NAND H/W PMECC Support" +# depends on MTD_NAND_HWECC +# select SAMA5_HAVE_PMECC +# ---help--- +# Enable hardware assisted support for ECC calculations +# +# config SAMA5_EBICS0_CHIPECC +# bool "Embedded chip ECC" +# depends on MTD_NAND_EMBEDDEDECC +# ---help--- +# Some NAND devices have internal, embedded ECC function. +# +# endchoice # NAND ECC type +endif # SAMA5_EBICS0 + +config SAMA5_EBICS1 + bool "External CS1 Memory" + default n + depends on SAMA5_HSMC + ---help--- + Build in support for memory resources in the chip select 1 (CS1) + memory region. + +if SAMA5_EBICS1 + +config SAMA5_EBICS1_SIZE + int "CS1 Memory size" + default 0 + ---help--- + Mapped size of the memory region at CS1. + +choice + prompt "CS1 Memory Type" + default SAMA5_EBICS1_NOR + ---help--- + Select the type of memory present on CS1 + +config SAMA5_EBICS1_SRAM + bool "SRAM" + +config SAMA5_EBICS1_PSRAM + bool "PSRAM" + +config SAMA5_EBICS1_PROM + bool "PROM" + +config SAMA5_EBICS1_EEPROM + bool "EEPROM" + +config SAMA5_EBICS1_EPROM + bool "EPROM" + +config SAMA5_EBICS1_LCD + bool "LCD" + +config SAMA5_EBICS1_NOR + bool "NOR Flash" + +# CS1 cannot support NAND +# config SAMA5_EBICS1_NAND +# bool "NAND Flash" +# select MTD +# select MTD_NAND +# select SAMA5_HAVE_NAND + +endchoice # CS1 Memory Type + +# CS1 cannot support NAND +# choice +# prompt "NAND ECC type" +# default SAMA5_EBICS1_ECCNONE +# depends on SAMA5_EBICS1_NAND +# +# config SAMA5_EBICS1_ECCNONE +# bool "No ECC" +# ---help--- +# Only raw transfers to/from NAND are supported +# +# config SAMA5_EBICS1_SWECC +# bool "Software ECC" +# depends on MTD_NAND_SWECC +# ---help--- +# ECC is performed by higher level software logic +# +# config SAMA5_EBICS1_PMECC +# bool "NAND H/W PMECC Support" +# depends on MTD_NAND_HWECC +# select SAMA5_HAVE_PMECC +# ---help--- +# Enable hardware assisted support for ECC calculations +# +# config SAMA5_EBICS1_CHIPECC +# bool "Embedded chip ECC" +# depends on MTD_NAND_EMBEDDEDECC +# ---help--- +# Some NAND devices have internal, embedded ECC function. +# +# endchoice # NAND ECC type +endif # SAMA5_EBICS1 + +config SAMA5_EBICS2 + bool "External CS2 Memory" + depends on SAMA5_HSMC + default n + ---help--- + Build in support for memory resources in the chip select 2 (CS2) + memory region. + +if SAMA5_EBICS2 + +config SAMA5_EBICS2_SIZE + int "CS2 Memory size" + default 0 + ---help--- + Mapped size of the memory region at CS2. + +choice + prompt "CS2 Memory Type" + default SAMA5_EBICS2_NOR + ---help--- + Select the type of memory present on CS2 + +config SAMA5_EBICS2_SRAM + bool "SRAM" + +config SAMA5_EBICS2_PSRAM + bool "PSRAM" + +config SAMA5_EBICS2_PROM + bool "PROM" + +config SAMA5_EBICS2_EEPROM + bool "EEPROM" + +config SAMA5_EBICS2_EPROM + bool "EPROM" + +config SAMA5_EBICS2_LCD + bool "LCD" + +config SAMA5_EBICS2_NOR + bool "NOR Flash" + +# CS2 cannot support NAND +# config SAMA5_EBICS2_NAND +# bool "NAND Flash" +# select MTD +# select MTD_NAND +# select SAMA5_HAVE_NAND + +endchoice # CS2 Memory Type + +# CS2 cannot support NAND +# choice +# prompt "NAND ECC type" +# default SAMA5_EBICS2_ECCNONE +# depends on SAMA5_EBICS2_NAND +# +# config SAMA5_EBICS2_ECCNONE +# bool "No ECC" +# ---help--- +# Only raw transfers to/from NAND are supported +# +# config SAMA5_EBICS2_SWECC +# bool "Software ECC" +# depends on MTD_NAND_SWECC +# ---help--- +# ECC is performed by higher level software logic +# +# config SAMA5_EBICS2_PMECC +# bool "NAND H/W PMECC Support" +# depends on MTD_NAND_HWECC +# select SAMA5_HAVE_PMECC +# ---help--- +# Enable hardware assisted support for ECC calculations +# +# config SAMA5_EBICS2_CHIPECC +# bool "Embedded chip ECC" +# depends on MTD_NAND_EMBEDDEDECC +# ---help--- +# Some NAND devices have internal, embedded ECC function. +# +# endchoice # NAND ECC type +endif # SAMA5_EBICS2 + +config SAMA5_EBICS3 + bool "External CS3 Memory" + default n + depends on SAMA5_HSMC + ---help--- + Build in support for memory resources in the chip select 3 (CS3) + memory region. + +if SAMA5_EBICS3 + +config SAMA5_EBICS3_SIZE + int "CS3 Memory size" + default 0 + ---help--- + Mapped size of the memory region at CS3. + +choice + prompt "CS3 Memory Type" + default SAMA5_EBICS3_NOR + ---help--- + Select the type of memory present on CS3 + +config SAMA5_EBICS3_SRAM + bool "SRAM" + +config SAMA5_EBICS3_PSRAM + bool "PSRAM" + +config SAMA5_EBICS3_PROM + bool "PROM" + +config SAMA5_EBICS3_EEPROM + bool "EEPROM" + +config SAMA5_EBICS3_EPROM + bool "EPROM" + +config SAMA5_EBICS3_LCD + bool "LCD" + +config SAMA5_EBICS3_NOR + bool "NOR Flash" + +config SAMA5_EBICS3_NAND + bool "NAND Flash" + select MTD + select MTD_NAND + select SAMA5_HAVE_NAND + +endchoice # CS3 Memory Type + +choice + prompt "NAND ECC type" + default SAMA5_EBICS3_ECCNONE + depends on SAMA5_EBICS3_NAND + +config SAMA5_EBICS3_ECCNONE + bool "No ECC" + ---help--- + Only raw transfers to/from NAND are supported + +config SAMA5_EBICS3_SWECC + bool "Software ECC" + depends on MTD_NAND_SWECC + ---help--- + ECC is performed by higher level software logic + +config SAMA5_EBICS3_PMECC + bool "NAND H/W PMECC Support" + depends on MTD_NAND_HWECC + select SAMA5_HAVE_PMECC + ---help--- + Enable hardware assisted support for ECC calculations + +config SAMA5_EBICS3_CHIPECC + bool "Embedded chip ECC" + depends on MTD_NAND_EMBEDDEDECC + ---help--- + Some NAND devices have internal, embedded ECC function. + +endchoice # NAND ECC type +endif # SAMA5_EBICS3 + +config SAMA5_HAVE_NAND +bool +default n + +config SAMA5_HAVE_PMECC +bool +default n + +if SAMA5_HAVE_NAND + +config SAMA5_NAND_DMA + bool "NAND DMA Transfers" + default y + depends on SAMA5_DMAC0 + ---help--- + Use memory-to-memory DMA to perform NAND data transfers. NOTE that + DMAC0 must be selected (DMAC1 cannot access NFC SRAM). + +config SAMA5_NAND_DMA_THRESHOLD + int "DMA threshold" + default 784 + depends on SAMA5_NAND_DMA + ---help--- + Defines a threshold value for performing memory-to-memory DMA. + + If memory-to-memory DMAs are used, then two context switches will + occur: (1) when the NAND logic waits for the DMA to complete, and + (2) again when the DMA completes and the NAND logic is re-awakened. + Each context switch will required saving and restoring a set of + registers defining the task state. Those register include the PSR, + 16 general purpose registers, and 32 floating point registers or + about 196 bytes per task state. That is then 392*2 bytes per + context and 784 bytes for both. Plus there is processing overhead. + So certainly, there is no reason to use a memory-to-memory DMA + transfer for much smaller blocks of data. + +config SAMA5_NAND_READYBUSY + bool "NAND Ready/Busy" + default n + ---help--- + Board logic supports and interface to detect NAND Busy/Ready signal. + If defined, the board must provide: + + bool board_nand_busy(int cs); + +config SAMA5_NAND_CE + bool "NAND Chip Enable" + default n + ---help--- + Board logic supports and interface to control the NAND Chip Enable signal. + If defined, the board must provide: + + void board_nand_ce(int cs, bool enable); + +if SAMA5_HAVE_PMECC + +config MTD_NAND_MAX_PMECCSIZE + int "Max H/W ECC size" + default 200 + ---help--- + Maximum HW ECC size + +config SAMA5_PMECC_TRIMPAGE + bool "Trim page support" + default n + ---help--- + Support page trimming. This behavior was found to fix both UBI and + JFFS2 images written to cleanly erased NAND partitions. NOTE: + Nothing in the code base now uses these trim pages. Option support + is provided in case it becomes necessary in the future. + +config SAMA5_PMECC_EMBEDDEDALGO + bool "ROM ECC detection/correction" + default y + ---help--- + The SAMA5D3 ROM code embeds the software used in the process of ECC + detection/correction: function pmecc_correctionalgo(). If this + option is selected, the ROM code will be used. If not, then the an + implementation pmecc_correctionalgo() will be built into the NuttX + image. + +config SAMA5_PMECC_EMBEDDEDALGO_ADDR + hex "Address of ROM ECC detection/correction" + default 0x00104510 + depends on SAMA5_PMECC_EMBEDDEDALGO + ---help--- + The ROM code embeds the software used in the process of ECC + detection/correction at this address. Don't change this address + unless you know what you are doing. + +config SAMA5_PMECC_GALOIS_ROMTABLES + bool "ROM Galois Tables" + default y + ---help--- + Support the PMECC algorithm using Galois tables in ROM. + +if SAMA5_PMECC_GALOIS_ROMTABLES + +config SAMA5_PMECC_GALOIS_TABLE512_ROMADDR + hex "Address of Galois Table 512" + default 0x00110000 + ---help--- + Address of Galois Field Table 512 mapping in ROM. Don't change this + address unless you know what you are doing. + +config SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR + hex "Address of Galois Table 1024" + default 0x00118000 + ---help--- + Address of Galois Field Table 1024 mapping in ROM. Don't change this + address unless you know what you are doing. + +endif # SAMA5_PMECC_GALOIS_ROMTABLES + +config SAMA5_PMECC_GALOIS_CUSTOM + bool "Custom Galois Tables" + default n + ---help--- + Build in support to build Galois tables on-the-fly. No current used + by any NuttX logic. + +endif # SAMA5_HAVE_PMECC + +config SAMA5_NAND_DMADEBUG + bool "NAND DMA transfer debug" + depends on SAMA5_NAND_DMA && DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze NAND DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAMA5_NAND_REGDEBUG + bool "Register-Level NAND Debug" + default n + depends on DEBUG && DEBUG_FS + ---help--- + Enable very low-level register access debug. Depends on DEBUG and + DEBUG_FS. + +config SAMA5_NAND_DUMP + bool "NAND data dump" + default n + depends on DEBUG && DEBUG_FS + ---help--- + Dump the contents of all data read and written to FLAH. Depends on + DEBUG and DEBUG_FS. + +endif # SAMA5_HAVE_NAND +endmenu # External Memory Configuration + +choice + prompt "SAMA5 Boot Configuration" + default SAMA5_BOOT_ISRAM + ---help--- + The startup code needs to know if the code is running from internal SRAM, + external SRAM, or CS0-3 in order to initialize properly. Note that the + boot device is not specified for cases where the code is copied into + internal SRAM; those cases are all covered by SAMA5_BOOT_ISRAM. + +config SAMA5_BOOT_ISRAM + bool "Running from internal SRAM" + +config SAMA5_BOOT_SDRAM + bool "Running from external SDRAM" + +config SAMA5_BOOT_CS0FLASH + bool "Running in external FLASH CS0" + depends on SAMA5_EBICS0_NOR + select ARCH_HAVE_RAMFUNCS + +config SAMA5_BOOT_CS0SRAM + bool "Running in external FLASH CS0" + depends on SAMA5_EBICS0_SRAM || SAMA5_EBICS0_PSRAM + +config SAMA5_BOOT_CS1FLASH + bool "Running in external FLASH CS1" + depends on SAMA5_EBICS1_NOR + +config SAMA5_BOOT_CS1SRAM + bool "Running in external FLASH CS1" + depends on SAMA5_EBICS1_SRAM || SAMA5_EBICS1_PSRAM + +config SAMA5_BOOT_CS2FLASH + bool "Running in external FLASH CS2" + depends on SAMA5_EBICS2_NOR + +config SAMA5_BOOT_CS2SRAM + bool "Running in external FLASH CS2" + depends on SAMA5_EBICS2_SRAM || SAMA5_EBICS2_PSRAM + +config SAMA5_BOOT_CS2FLASH + bool "Running in external FLASH CS3" + depends on SAMA5_EBICS3_NOR + +config SAMA5_BOOT_CS3SRAM + bool "Running in external FLASH CS3" + depends on SAMA5_EBICS3_SRAM || SAMA5_EBICS3_PSRAM + +endchoice # SAMA5 Boot Configuration + +menu "Heap Configuration" + +config SAMA5_ISRAM_HEAP + bool "Include ISRAM in heap" + default y + depends on !SAMA5_BOOT_ISRAM + ---help--- + Include the internal SRAM memory in the heap. + + NOTE: MM_REGIONS must also be set to indicate the total number of + memory regions to be added to the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM INTERNAL SRAM!! ** + In this case, the remaining ISRAM will automatically be added to the + heap (using RAM_END). + + *** RAMFUNCS WARNING ** + If you execute from NOR FLASH, RAM functions will be enabled. The + RAM functions will be positioned in SRAM in the same location as the + ISRAM heap and, as a result, those RAM functions will be destroyed + after the heap is initialized. That is not a problem now since + these RAM functions are only used in the early boot phase. If, + however, you should wish to preserve the RAM functions, then you + should also disable SAMA5_ISRAM_HEAP so that the RAM functions are + preserved beyond the boot phase. + +config SAMA5_DDRCS_HEAP + bool "Include DDR-SDRAM in heap" + default y + depends on SAMA5_DDRCS && !SAMA5_BOOT_SDRAM + ---help--- + Include a portion of DDR-SDRAM memory in the heap. + + NOTE: MM_REGIONS must also be set to indicate the total number of + memory regions to be added to the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM SDRAM!!** + In this case, the remaining SDRAM will automatically be added to the + heap. + +if SAMA5_DDRCS_HEAP + +config SAMA5_DDRCS_HEAP_OFFSET + int "DDR-SDRAM heap offset" + default 0 + ---help--- + Preserve this number of bytes at the beginning of SDRAM. The + portion of DRAM beginning at this offset from the DDRCS base will + be added to the heap. + + NOTE: If you are using a page cache in DRAM (via SAMA5_DDRCS_PGHEAP), + then the memory regions defined by SAMA5_DDRCS_HEAP_OFFSET and + SAMA5_DDRCS_HEAP_SIZE must not overlap the memory region defined by + SAMA5_DDRCS_PGHEAP_OFFSET and SAMA5_DDRCS_PGHEAP_SIZE. + +config SAMA5_DDRCS_HEAP_SIZE + int "DDR-SDRAM heap size" + default 0 + ---help--- + Add the region of DDR-SDRAM beginning at SAMA5_DDRCS_HEAP_OFFSET + and of size SAMA5_DDRCS_HEAP_SIZE to the heap. + + NOTE: If you are using a page cache in DRAM (via SAMA5_DDRCS_PGHEAP), + then the memory regions defined by SAMA5_DDRCS_HEAP_OFFSET and + SAMA5_DDRCS_HEAP_SIZE must not overlap the memory region defined by + SAMA5_DDRCS_PGHEAP_OFFSET and SAMA5_DDRCS_PGHEAP_SIZE. + +endif # SAMA5_DDRCS_HEAP + +config SAMA5_DDRCS_RESERVE + bool "Reserve DDR-SDRAM" + default n + depends on SAMA5_BOOT_SDRAM + ---help--- + This option is available only we are executing out of SDRAM. In + this case, by default, all of DRAM available from the end of the + program through the end of DRAM (RAM_START + RAM_END) is + automatically added to the heap. However, there are certain cases + where you may want to reserve a block of DRAM for other purposes + such a large DMA buffer or an LCD framebuffer or a page cache. In + those cases, you can select this option to specify the end of the + DRAM memory to add to the heap; DRAM after this address will not + be part of the heap and so will be available for other purposes. + + NOTE: There is way to reserve memory before the start of the + program in DRAM using this mechanism. That configuration is + possible, but not using this configuration setting. + +if SAMA5_DDRCS_RESERVE + +config SAMA5_DDRCS_HEAP_END + hex "DDR-SDRAM heap end" + default 0x30000000 + ---help--- + Add the region of DDR-SDRAM beginning at the first available byte + after the memory used by the DRAM probably through this virtual + address (minus one). This will reserve the memory starting at + this address through RAM_SIZE + RAM_END for other purposes. + + NOTE: If you are using a page cache in DRAM (via SAMA5_DDRCS_PGHEAP), + then the memory regions below by SAMA5_DDRCS_HEAP_END must not + overlap the memory region defined by SAMA5_DDRCS_PGHEAP_OFFSET and + SAMA5_DDRCS_PGHEAP_SIZE. + +endif # SAMA5_DDRCS_RESERVE + +config SAMA5_DDRCS_PGHEAP + bool "Include DDR-SDRAM in page cache" + default y + depends on (SAMA5_DDRCS || SAMA5_BOOT_SDRAM) && ARCH_ADDRENV + ---help--- + Include a portion of DDR-SDRAM memory in the page cache. + +if SAMA5_DDRCS_PGHEAP + +config SAMA5_DDRCS_PGHEAP_OFFSET + hex "DDR-SDRAM heap offset" + default 0x0 + ---help--- + Preserve this number of bytes at the beginning of SDRAM. The + portion of DRAM beginning at this offset from the DDRCS base will + be added to the heap. + + If you are executing from DRAM, then you must have already reserved + this region with SAMA5_DDRCS_RESERVE, setting SAMA5_DDRCS_HEAP_END + so that this page cache region defined by SAMA5_DDRCS_PGHEAP_OFFSET + and SAMA5_DDRCS_PGHEAP_SIZE does not overlap the the region of DRAM + that is added to the heap. If you are not executing from DRAM, then + you must have excluding this page cache region from the heap ether + by (1) not selecting SAMA5_DDRCS_HEAP, or (2) selecting + SAMA5_DDRCS_HEAP_OFFSET and SAMA5_DDRCS_HEAP_SIZE so that the page + cache region does not overlapy the region of DRAM that is added to + the heap. + +config SAMA5_DDRCS_PGHEAP_SIZE + int "DDR-SDRAM heap size" + default 0 + ---help--- + Add the region of DDR-SDRAM beginning at SAMA5_DDRCS_PGHEAP_OFFSET + and of size SAMA5_DDRCS_PGHEAP_SIZE to the heap. + + If you are executing from DRAM, then you must have already reserved + this region with SAMA5_DDRCS_RESERVE, setting SAMA5_DDRCS_HEAP_END + so that this page cache region defined by SAMA5_DDRCS_PGHEAP_OFFSET + and SAMA5_DDRCS_PGHEAP_SIZE does not overlap the the region of DRAM + that is added to the heap. If you are not executing from DRAM, then + you must have excluding this page cache region from the heap ether + by (1) not selecting SAMA5_DDRCS_HEAP, or (2) selecting + SAMA5_DDRCS_HEAP_OFFSET and SAMA5_DDRCS_HEAP_SIZE so that the page + cache region does not overlapy the region of DRAM that is added to + the heap. + +endif # SAMA5_DDRCS_PGHEAP + +config SAMA5_EBICS0_HEAP + bool "Include EBICS0 SRAM/PSRAM in heap" + default y + depends on (SAMA5_EBICS0_SRAM || SAMA5_EBICS0_PSRAM) && !SAMA5_BOOT_CS0SRAM + ---help--- + Include the CS0 SRAM/PSREAM memory in the heap. + + NOTE: MM_REGIONS must also be set to indicate the total number of + memory regions to be added to the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM CS0 SRAM!!** + In this case, the remaining SRAM will automatically be added to the + heap (using RAM_END). + +if SAMA5_EBICS0_HEAP +config SAMA5_EBICS0_HEAP_OFFSET + int "EBICS0 RAM offset" + default 0 + ---help--- + Preserve this number of bytes at the beginning of RAM. The + portion of RAM beginning at this offset from the EBICS0 base will + be added to the heap. + +config SAMA5_EBICS0_HEAP_SIZE + int "EBICS0 RAM size" + default 0 + ---help--- + Add the region of RAM beginning at SAMA5_EBICS0_HEAP_OFFSET + and of size SAMA5_EBICS0_HEAP_SIZE to the heap. + +endif #SAMA5_EBICS0_HEAP + +config SAMA5_EBICS1_HEAP + bool "Include EBICS1 SRAM/PSRAM in heap" + default y + depends on (SAMA5_EBICS1_SRAM || SAMA5_EBICS1_PSRAM) && !SAMA5_BOOT_CS1SRAM + ---help--- + Include the CS1 SRAM/PSREAM memory in the heap. + + NOTE: MM_REGIONS must also be set to indicate the total number of + memory regions to be added to the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM CS1 SRAM!!** + In this case, the remaining SRAM will automatically be added to the + heap (using RAM_END). + +if SAMA5_EBICS1_HEAP +config SAMA5_EBICS1_HEAP_OFFSET + int "EBICS1 RAM offset" + default 0 + ---help--- + Preserve this number of bytes at the beginning of RAM. The + portion of DRAM beginning at this offset from the EBICS1 base will + be added to the heap. + +config SAMA5_EBICS1_HEAP_SIZE + int "EBICS1 RAM size" + default 0 + ---help--- + Add the region of RAM beginning at SAMA5_EBICS1_HEAP_OFFSET + and of size SAMA5_EBICS1_HEAP_SIZE to the heap. + +endif #SAMA5_EBICS1_HEAP + +config SAMA5_EBICS2_HEAP + bool "Include EBICS2 SRAM/PSRAM in heap" + default y + depends on (SAMA5_EBICS2_SRAM || SAMA5_EBICS2_PSRAM) && !SAMA5_BOOT_CS2SRAM + ---help--- + Include the CS2 SRAM/PSREAM memory in the heap. + + NOTE: MM_REGIONS must also be set to indicate the total number of + memory regions to be added to the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM CS2 SRAM!!** + In this case, the remaining SRAM will automatically be added to the + heap (using RAM_END). + +if SAMA5_EBICS2_HEAP +config SAMA5_EBICS2_HEAP_OFFSET + int "EBICS2 RAM offset" + default 0 + ---help--- + Preserve this number of bytes at the beginning of RAM. The + portion of DRAM beginning at this offset from the EBICS2 base will + be added to the heap. + +config SAMA5_EBICS2_HEAP_SIZE + int "EBICS2 RAM size" + default 0 + ---help--- + Add the region of RAM beginning at SAMA5_EBICS2_HEAP_OFFSET + and of size SAMA5_EBICS2_HEAP_SIZE to the heap. + +endif #SAMA5_EBICS2_HEAP + +config SAMA5_EBICS3_HEAP + bool "Include EBICS3 SRAM/PSRAM in heap" + default y + depends on (SAMA5_EBICS3_SRAM || SAMA5_EBICS3_PSRAM) && !SAMA5_BOOT_CS3SRAM + ---help--- + Include the CS3 SRAM/PSREAM memory in the heap. + + *** DO NOT SELECT THIS OPTION IF YOU ARE EXECUTING FROM CS3 SRAM!!** + In this case, the remaining SRAM will automatically be added to the + heap (using RAM_END). + +if SAMA5_EBICS3_HEAP +config SAMA5_EBICS3_HEAP_OFFSET + int "EBICS3 RAM offset" + default 0 + ---help--- + Preserve this number of bytes at the beginning of RAM. The + portion of DRAM beginning at this offset from the EBICS3 base will + be added to the heap. + +config SAMA5_EBICS3_HEAP_SIZE + int "EBICS3 RAM size" + default 0 + ---help--- + Add the region of RAM beginning at SAMA5_EBICS3_HEAP_OFFSET + and of size SAMA5_EBICS3_HEAP_SIZE to the heap. + +endif #SAMA5_EBICS3_HEAP +endmenu # Heap Configuration +endif # ARCH_CHIP_SAMA5 diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..cfe0d0a3deaf21e098f85003c2fa7aec1d0c25ea --- /dev/null +++ b/arch/arm/src/sama5/Make.defs @@ -0,0 +1,319 @@ +############################################################################ +# arch/arm/sama5/Make.defs +# +# Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The vector table is the "head" object, i.e., the one that must forced into +# the link in order to draw in all of the other components + +HEAD_ASRC = arm_vectortab.S + +ifeq ($(CONFIG_BUILD_KERNEL),y) +STARTUP_OBJS = crt0$(OBJEXT) +endif + +# Force the start-up logic to be at the beginning of the .text to simplify +# debug. + +ifeq ($(CONFIG_PAGING),y) +CMN_ASRCS = arm_pghead.S +else +CMN_ASRCS = arm_head.S +endif + +# Common assembly language files + +CMN_ASRCS += arm_vectors.S arm_fpuconfig.S arm_fullcontextrestore.S +CMN_ASRCS += arm_saveusercontext.S arm_vectoraddrexcptn.S arm_vfork.S +CMN_ASRCS += arm_testset.S +CMN_ASRCS += cp15_coherent_dcache.S cp15_invalidate_dcache.S +CMN_ASRCS += cp15_clean_dcache.S cp15_flush_dcache.S cp15_invalidate_dcache_all.S + +# Configuration dependent assembly language files + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += arm_memcpy.S +endif + +# Common C source files + +CMN_CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_exit.c +CMN_CSRCS += up_createstack.c up_releasestack.c up_usestack.c up_vfork.c +CMN_CSRCS += up_puts.c up_mdelay.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c +CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_mmu.c arm_prefetchabort.c +CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c +CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c + +# Configuration dependent C files + +ifeq ($(CONFIG_ARMV7A_L2CC_PL310),y) +CMN_CSRCS += arm_l2cc_pl310.c +endif + +ifeq ($(CONFIG_PAGING),y) +CMN_CSRCS += arm_allocpage.c arm_checkmapping.c arm_pginitialize.c +CMN_CSRCS += arm_va2pte.c +endif + +ifeq ($(CONFIG_BUILD_KERNEL),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c arm_signal_dispatch.c +endif + +ifeq ($(CONFIG_ARCH_ADDRENV),y) +CMN_CSRCS += arm_addrenv.c arm_addrenv_utils.c arm_pgalloc.c +ifeq ($(CONFIG_ARCH_STACK_DYNAMIC),y) +CMN_CSRCS += arm_addrenv_ustack.c +endif +ifeq ($(CONFIG_ARCH_KERNEL_STACK),y) +CMN_CSRCS += arm_addrenv_kstack.c +endif +ifeq ($(CONFIG_MM_SHM),y) +CMN_CSRCS += arm_addrenv_shm.c +endif +endif + +ifeq ($(CONFIG_MM_PGALLOC),y) +CMN_CSRCS += arm_physpgaddr.c +ifeq ($(CONFIG_ARCH_PGPOOL_MAPPING),y) +CMN_CSRCS += arm_virtpgaddr.c +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_savefpu.S arm_restorefpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# SAMA5-specific assembly language files + +CHIP_ASRCS = + +# SAMA5-specific C source files + +CHIP_CSRCS = sam_allocateheap.c sam_boot.c sam_clockconfig.c sam_irq.c +CHIP_CSRCS += sam_lowputc.c sam_memories.c sam_memorymap.c sam_pck.c +CHIP_CSRCS += sam_pio.c sam_pmc.c sam_sckc.c sam_serial.c sam_serialinit.c + +# Configuration dependent C and assembly language files + +ifeq ($(CONFIG_MM_PGALLOC),y) +CHIP_CSRCS += sam_pgalloc.c +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_timerisr.c +endif + +ifeq ($(CONFIG_SAMA5_DMAC0),y) +CHIP_CSRCS += sam_dmac.c +else +ifeq ($(CONFIG_SAMA5_DMAC1),y) +CHIP_CSRCS += sam_dmac.c +endif +endif + +ifeq ($(CONFIG_SAMA5_XDMAC0),y) +CHIP_CSRCS += sam_xdmac.c +else +ifeq ($(CONFIG_SAMA5_XDMAC1),y) +CHIP_CSRCS += sam_xdmac.c +endif +endif + +ifeq ($(CONFIG_SAMA5_PIO_IRQ),y) +CHIP_CSRCS += sam_pioirq.c +endif + +ifeq ($(CONFIG_SAMA5_RTC),y) +CHIP_CSRCS += sam_rtc.c +endif + +ifeq ($(CONFIG_SAMA5_WDT),y) +CHIP_CSRCS += sam_wdt.c +endif + +ifeq ($(CONFIG_SAMA5_DBGU),y) +CHIP_CSRCS += sam_dbgu.c +endif + +ifeq ($(CONFIG_SAMA5_TRNG),y) +CHIP_CSRCS += sam_trng.c +endif + +ifeq ($(CONFIG_SAMA5_FLEXCOM_USART),y) +CHIP_CSRCS += sam_flexcom_serial.c +endif + +ifeq ($(CONFIG_SAMA5_SPI0),y) +CHIP_CSRCS += sam_spi.c +else +ifeq ($(CONFIG_SAMA5_SPI1),y) +CHIP_CSRCS += sam_spi.c +else +endif +endif + +ifeq ($(CONFIG_SAMA5_SSC0),y) +CHIP_CSRCS += sam_ssc.c +else +ifeq ($(CONFIG_SAMA5_SSC1),y) +CHIP_CSRCS += sam_ssc.c +else +endif +endif + +ifeq ($(CONFIG_SAMA5_LCDC),y) +CHIP_CSRCS += sam_lcd.c +endif + +ifeq ($(CONFIG_SAMA5_UHPHS),y) +ifeq ($(CONFIG_SAMA5_OHCI),y) +CHIP_CSRCS += sam_ohci.c +endif +ifeq ($(CONFIG_SAMA5_EHCI),y) +CHIP_CSRCS += sam_ehci.c +endif +endif + +ifeq ($(CONFIG_SAMA5_UDPHS),y) +CHIP_CSRCS += sam_udphs.c +endif + +ifeq ($(CONFIG_USBHOST),y) +ifeq ($(CONFIG_USBHOST_TRACE),y) +CHIP_CSRCS += sam_usbhost.c +else +ifeq ($(CONFIG_DEBUG_USB),y) +CHIP_CSRCS += sam_usbhost.c +endif +endif +endif + +ifeq ($(CONFIG_SAMA5_HSMCI0),y) +CHIP_CSRCS += sam_hsmci.c sam_hsmci_clkdiv.c +else +ifeq ($(CONFIG_SAMA5_HSMCI1),y) +CHIP_CSRCS += sam_hsmci.c sam_hsmci_clkdiv.c +else +ifeq ($(CONFIG_SAMA5_HSMCI2),y) +CHIP_CSRCS += sam_hsmci.c sam_hsmci_clkdiv.c +endif +endif +endif + +ifeq ($(CONFIG_NET),y) +CHIP_CSRCS += sam_ethernet.c +ifeq ($(CONFIG_SAMA5_EMACA),y) +CHIP_CSRCS += sam_emaca.c +endif +ifeq ($(CONFIG_SAMA5_EMACB),y) +CHIP_CSRCS += sam_emacb.c +endif +ifeq ($(CONFIG_SAMA5_GMAC),y) +CHIP_CSRCS += sam_gmac.c +endif +endif + +ifeq ($(CONFIG_SAMA5_CAN0),y) +CHIP_CSRCS += sam_can.c +else +ifeq ($(CONFIG_SAMA5_CAN1),y) +CHIP_CSRCS += sam_can.c +endif +endif + +ifeq ($(CONFIG_SAMA5_TWI0),y) +CHIP_CSRCS += sam_twi.c +else +ifeq ($(CONFIG_SAMA5_TWI1),y) +CHIP_CSRCS += sam_twi.c +else +ifeq ($(CONFIG_SAMA5_TWI2),y) +CHIP_CSRCS += sam_twi.c +endif +endif +endif + +ifeq ($(CONFIG_SAMA5_ADC),y) +CHIP_CSRCS += sam_adc.c +ifeq ($(CONFIG_SAMA5_TSD),y) +CHIP_CSRCS += sam_tsd.c +endif +endif + +ifeq ($(CONFIG_SAMA5_PWM),y) +CHIP_CSRCS += sam_pwm.c +endif + +ifeq ($(CONFIG_SAMA5_HAVE_TC),y) +CHIP_CSRCS += sam_tc.c +ifeq ($(CONFIG_SAMA5_ONESHOT),y) +CHIP_CSRCS += sam_oneshot.c +endif +ifeq ($(CONFIG_SAMA5_FREERUN),y) +CHIP_CSRCS += sam_freerun.c +endif +ifeq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_tickless.c +endif +endif + +ifeq ($(CONFIG_SAMA5_EBICS0_NAND),y) +CHIP_CSRCS += sam_nand.c sam_pmecc.c sam_gf512.c sam_gf1024.c +else +ifeq ($(CONFIG_SAMA5_EBICS1_NAND),y) +CHIP_CSRCS += sam_nand.c sam_pmecc.c sam_gf512.c sam_gf1024.c +else +ifeq ($(CONFIG_SAMA5_EBICS2_NAND),y) +CHIP_CSRCS += sam_nand.c sam_pmecc.c sam_gf512.c sam_gf1024.c +else +ifeq ($(CONFIG_SAMA5_EBICS3_NAND),y) +CHIP_CSRCS += sam_nand.c sam_pmecc.c sam_gf512.c sam_gf1024.c +endif +endif +endif +endif diff --git a/arch/arm/src/sama5/chip.h b/arch/arm/src/sama5/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..8928a48c33ede24838116584f792cb8a523fc56f --- /dev/null +++ b/arch/arm/src/sama5/chip.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* arch/arm/src/armv7-a/l2cc_pl310.h includes this file and expects it to provide the + * address of the L2CC-PL310 implementation. + */ + +#define L2CC_VBASE SAM_L2CC_VSECTION + +/* Cache line sizes (in bytes)for the SAVA5Dx */ + +#define ARMV7A_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7A_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d2x_memorymap.h b/arch/arm/src/sama5/chip/_sama5d2x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..03a6ecfee68d1e98fc35564209fd872907763c3a --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d2x_memorymap.h @@ -0,0 +1,887 @@ +/************************************************************************************ + * arch/arm/src/sama5/_sama5d2x_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + +/* Overview: + * + * SAMA5 Physical (unmapped) Memory Map + * - SAMA5 Internal Memories + * - SAMA5 Internal Peripheral Offsets + * - System Controller Peripheral Offsets + * Sizes of memory regions in bytes + * Sizes of memory regions in sections + * Section MMU Flags + * SAMA5 Virtual (mapped) Memory Map + * - Peripheral virtual base addresses + * - NuttX vitual base address + * MMU Page Table Location + * Page table start addresses + * Base address of the interrupt vector table + */ + +/* SAMA5D2 Physical (unmapped) Memory Map */ + +#define SAM_INTMEM_PSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_EBICS0_PSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip Select 0 */ +#define SAM_DDRCS_PSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDR Chip Select */ +#define SAM_DDRAESCS_PSECTION 0x40000000 /* 0x40000000-0x5fffffff: EBI DDR AES Chip Select */ +#define SAM_EBICS1_PSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip select 1 */ +#define SAM_EBICS2_PSECTION 0x70000000 /* 0x70000000-0x7fffffff: EBI Chip select 2 */ +#define SAM_EBICS3_PSECTION 0x80000000 /* 0x80000000-0x8fffffff: EBI Chip select 3 */ +#define SAM_QSPI0AES_PSECTION 0x90000000 /* 0x90000000-0x97ffffff: QSPI0 AES Memory */ +#define SAM_QSPI1AES_PSECTION 0x98000000 /* 0x98000000-0x9fffffff: QSPI1 AES Memory */ +#define SAM_SDMMC0_PSECTION 0xa0000000 /* 0xa0000000-0xafffffff: SDMMC0 */ +#define SAM_SDMMC1_PSECTION 0xb0000000 /* 0xb0000000-0xbfffffff: SDMMC1 */ +#define SAM_NFCCR_PSECTION 0xc0000000 /* 0xc0000000-0xcfffffff: NFC Command Registers */ +#define SAM_QSPI0_PSECTION 0xd0000000 /* 0xd0000000-0xd7ffffff: QSPI0 Memory */ +#define SAM_QSPI1_PSECTION 0xd8000000 /* 0xd8000000-0xdfffffff: QSPI1 Memory */ + /* 0xe0000000-0xefffffff: Undefined */ +#define SAM_PERIPH_PSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ + +/* SAMA5D2 Internal Memories */ + +#define SAM_ROM_PSECTION 0x00000000 /* 0x00000000-0x0003ffff: ROM */ +#define SAM_SRAMREMAP_PSECTION 0x00000000 /* 0x00000000-0x0003ffff: Remapped ISRAM */ +#define SAM_ECCROM_PSECTION 0x00040000 /* 0x00040000-0x000fffff: EEC ROM */ +#define SAM_NFCSRAM_PSECTION 0x00100000 /* 0x00100000-0x001fffff: NFC SRAM */ +#define SAM_ISRAM_PSECTION 0x00200000 /* 0x00200000-0x002fffff: SRAM */ +# define SAM_ISRAM0_PADDR 0x00200000 /* 0x00200000-0x0021ffff: SRAM0 */ +# define SAM_ISRAM1_PADDR 0x00220000 /* 0x00220000-0x002fffff: SRAM1 */ +#define SAM_UDPHSRAM_PSECTION 0x00300000 /* 0x00300000-0x004fffff: UDPH SRAM */ +#define SAM_UHPOHCI_PSECTION 0x00400000 /* 0x00400000-0x005fffff: UHP OHCI */ +#define SAM_UHPEHCI_PSECTION 0x00500000 /* 0x00500000-0x005fffff: UHP EHCI */ +#define SAM_AXIMX_PSECTION 0x00600000 /* 0x00600000-0x006fffff: AXI Matrix */ +#define SAM_DAP_PSECTION 0x00700000 /* 0x00700000-0x007fffff: DAP */ + /* 0x00800000-0x009fffff: Reserved */ +#define SAM_L2CC_PSECTION 0x00a00000 /* 0x00a00000-0x00bfffff: L2CC */ + /* 0x00c00000-0x00ffffff: Undefined (Abort) */ + +/* SAMA5D2 Internal Peripheral Offsets */ + +#define SAM_PERIPHA_PSECTION 0xf0000000 /* 0xf0000000-0xf7ffffff: Internal Peripherals A */ +# define SAM_LCDC_OFFSET 0x00000000 /* 0x00000000-0x00003fff: LCDC */ +# define SAM_XDMAC1_OFFSET 0x00004000 /* 0x00004000-0x00007fff: XDMAC1 */ +# define SAM_ISC_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: ISC */ +# define SAM_MPDDRC_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: MPDDRC */ +# define SAM_XDMAC0_OFFSET 0x00010000 /* 0x00010000-0x00013fff: XDMAC0 */ +# define SAM_PMC_OFFSET 0x00014000 /* 0x00014000-0x00017fff: PMC */ +# define SAM_MATRIX0_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: MATRIX0 */ +# define SAM_AESB_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: AESB */ +# define SAM_QSPI0_OFFSET 0x00020000 /* 0x00020000-0x00023fff: QSPI0 */ +# define SAM_QSPI1_OFFSET 0x00024000 /* 0x00024000-0x00027fff: QSPI1 */ +# define SAM_SHA_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: SHA */ +# define SAM_AES_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: AES */ + /* 0x00030000-0xf7ffffff: Reserved */ + +#define SAM_PERIPHB_PSECTION 0xf8000000 /* 0xf8000000-0xfbffffff: Internal Peripherals B */ +# define SAM_SPI0_OFFSET 0x00000000 /* 0x00000000-0x00003fff: SPI0 */ +# define SAM_SSC0_OFFSET 0x00004000 /* 0x00004000-0x00007fff: SSC0 */ +# define SAM_EMAC0_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: GMAC 0 */ +# define SAM_TC012_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: TC channels 0, 1, and 2 */ +# define SAM_TC345_OFFSET 0x00010000 /* 0x00010000-0x00013fff: TC channels 3, 4, and 5 */ +# define SAM_HSMC_OFFSET 0x00014000 /* 0x00014000-0x00017fff: HSMC */ +# define SAM_PDMIC_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: HSMC */ +# define SAM_UART0_OFFSET 0x00020000 /* 0x00020000-0x0001ffff: UART0 */ +# define SAM_UART1_OFFSET 0x00022000 /* 0x00022000-0x00023fff: UART1 */ +# define SAM_UART2_OFFSET 0x00024000 /* 0x00024000-0x00027fff: UART2 */ +# define SAM_TWI0_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: TWIHS0 */ +# define SAM_PWMC_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: PWMC */ +# define SAM_SFR_OFFSET 0x00030000 /* 0x00030000-0x00033fff: SFR */ +# define SAM_FLEXCOM0_OFFSET 0x00034000 /* 0x00034000-0x00037fff: FLEXCOM0 */ +# define SAM_FLEXCOM1_OFFSET 0x00038000 /* 0x00038000-0x0003bfff: FLEXCOM1 */ +# define SAM_SAIC_OFFSET 0x0003C000 /* 0x0003C000-0x0003ffff: SAIC */ +# define SAM_ICM_OFFSET 0x00040000 /* 0x00040000-0x00043fff: ICM */ +# define SAM_SECURAM_OFFSET 0x00044000 /* 0x00044000-0x00044fff: SECURAM */ +# define SAM_SYSC_OFFSET 0x00048000 /* 0x00048000-0x00048fff: System Controller peripherals */ +# define SAM_RSTC_OFFSET 0x00048000 /* 0x00048000-0x0004800f: RSTC */ +# define SAM_SHDWC_OFFSET 0x00048010 /* 0x00048010-0x0004802f: SHDWC */ +# define SAM_PITC_OFFSET 0x00048030 /* 0x00048030-0x0004803f: PITC */ +# define SAM_WDT_OFFSET 0x00048040 /* 0x00048040-0x0004804f: WDT */ +# define SAM_SCKCR_OFFSET 0x00048050 /* 0x00048050-0x000480af: SCKCR */ +# define SAM_RTCC_OFFSET 0x000480b0 /* 0x000480b0-0x00048fff: RTCC */ +# define SAM_RXLP_OFFSET 0x00049000 /* 0x00049000-0x00049fff: RXLP */ +# define SAM_ACC_OFFSET 0x0004a000 /* 0x0004a000-0x0004afff: ACC */ + /* 0x0004b000-0x0004bfff: Reserved */ +# define SAM_SFC_OFFSET 0x0004c000 /* 0x0004c000-0x0004ffff: SFC */ +# define SAM_I2SC0_OFFSET 0x00050000 /* 0x00050000-0x00053fff: I2SC0 */ +# define SAM_CAN0_OFFSET 0x00054000 /* 0x00054000-0x00057fff: CAN0 */ + +#define SAM_PERIPHC_PSECTION 0xfc000000 /* 0xfc000000-0xffffffff: Internal Peripherals C */ +# define SAM_SPI1_OFFSET 0x00000000 /* 0x00000000-0x00003fff: SPI1 */ +# define SAM_SSC1_OFFSET 0x00004000 /* 0x00004000-0x00007fff: SSC1 */ +# define SAM_UART3_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: UART3 */ +# define SAM_UART4_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: UART4 */ +# define SAM_FLEXCOM2_OFFSET 0x00010000 /* 0x00010000-0x00013fff: FLEXCOM2 */ +# define SAM_FLEXCOM3_OFFSET 0x00014000 /* 0x00014000-0x00017fff: FLEXCOM3 */ +# define SAM_FLEXCOM4_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: FLEXCOM4 */ +# define SAM_TRNG_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: TRNG */ +# define SAM_AIC_OFFSET 0x00020000 /* 0x00020000-0x00023fff: AIC */ + /* 0x00024000-0x00027fff: Reserved */ +# define SAM_TWI1_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: TWIHS1 */ +# define SAM_UDPHS_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: UDPHS */ +# define SAM_ADC_OFFSET 0x00030000 /* 0x00030000-0x00033fff: ADC */ + /* 0x00034000-0x00037fff: Reserved */ +# define SAM_PIO_OFFSET 0x00038000 /* 0x00038000-0x0003bfff: PIOA-D */ +# define SAM_MATRIX1_OFFSET 0x0003c000 /* 0x0003c000-0x0003ffff: MATRIX1 */ +# define SAM_SECUMOD_OFFSET 0x00040000 /* 0x00040000-0x00043fff: SECUMOD */ +# define SAM_TDES_OFFSET 0x00044000 /* 0x00044000-0x00047fff: TDES */ +# define SAM_CLASSD_OFFSET 0x00048000 /* 0x00048000-0x0004bfff: Class D */ +# define SAM_I2SC1_OFFSET 0x0004c000 /* 0x0004c000-0x0004ffff: I2SC1 */ +# define SAM_CAN1_OFFSET 0x00050000 /* 0x00050000-0x00053fff: CAN1 */ +# define SAM_UTMI_OFFSET 0x00054000 /* 0x00054000-0x00057fff: UTMI */ + /* 0x00058000-0x0005bfff: Reserved */ +# define SAM_SFRBU_OFFSET 0x0005c000 /* 0x0005c000-0x0005ffff: SFRBU */ + /* 0x00060000-0x00068fff: Reserved */ +# define SAM_CHIPID_OFFSET 0x00069000 /* 0x00069000-0x0006bfff: SFRBU */ + /* 0x0006a000-0xffffffff: Reserved */ + +/* Sizes of memory regions in bytes. + * + * These sizes exclude the undefined addresses at the end of the memory + * region. The implemented sizes of the EBI CS0-3 and DDRCS regions + * are not known apriori and must be specified with configuration settings. + */ + /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_ROM_SIZE (256*1024) /* 0x00000000-0x0003ffff: ROM */ +#ifdef CONFIG_ARMV7A_L2CC_PL310 +# define SAM_SRAMREMAP_SIZE (128*1024) /* 0x00000000-0x0001ffff: Remapped ISRAM0 */ +#else +# define SAM_SRAMREMAP_SIZE (256*1024) /* 0x00000000-0x0003ffff: Remapped ISRAM0+1 */ +#endif +#define SAM_ECCROM_SIZE (768*1024) /* 0x00040000-0x000fffff: EEC ROM */ +#define SAM_NFCSRAM_SIZE (1*1024*1024) /* 0x00100000-0x001fffff: NFC SRAM */ +#ifdef CONFIG_ARMV7A_L2CC_PL310 +# define SAM_ISRAM_SIZE (128*1024) /* 0x00200000-0x0001ffff: SRAM0 */ +#else +# define SAM_ISRAM_SIZE (256*1024) /* 0x00200000-0x0003ffff: SRAM0+1 */ +#endif +#define SAM_UDPHSRAM_SIZE (1*1024*1024) /* 0x00300000-0x004fffff: UDPH SRAM */ +#define SAM_UHPOHCI_SIZE (1*1024*1024) /* 0x00400000-0x005fffff: UHP OHCI */ +#define SAM_UHPEHCI_SIZE (1*1024*1024) /* 0x00500000-0x005fffff: UHP EHCI */ +#define SAM_AXIMX_SIZE (4) /* 0x00600000-0x006fffff: AXI Matrix */ +#define SAM_DAP_SIZE (1*1024*1024) /* 0x00700000-0x007fffff: DAP */ +#define SAM_L2CC_SIZE (1*1024*1024) /* 0x00a00000-0x00bfffff: L2CC */ +#define SAM_NFCCR_SIZE (256*1024*1024) /* 0xc0000000-0xcfffffff: NFC Command Registers */ + /* 0xf0000000-0xffffffff: Internal Peripherals */ +#define SAM_PERIPHA_SIZE (192*1024) /* 0xf0000000-0xf002ffff: Internal Peripherals A */ +#define SAM_PERIPHB_SIZE (352*1024) /* 0xf8000000-0xf8057fff: Internal Peripherals B */ +#define SAM_PERIPHC_SIZE (431*1024) /* 0xfc000000-0xfc06bfff: Internal Peripherals C */ + +/* Force configured sizes that might exceed 2GB to be unsigned long */ + +#define SAMA5_EBICS0_SIZE MKULONG(CONFIG_SAMA5_EBICS0_SIZE) +#define SAMA5_DDRCS_SIZE MKULONG(CONFIG_SAMA5_DDRCS_SIZE) +#define SAMA5_DDRAESCS_SIZE MKULONG(CONFIG_SAMA5_DDRAESCS_SIZE) +#define SAMA5_EBICS1_SIZE MKULONG(CONFIG_SAMA5_EBICS1_SIZE) +#define SAMA5_EBICS2_SIZE MKULONG(CONFIG_SAMA5_EBICS2_SIZE) +#define SAMA5_EBICS3_SIZE MKULONG(CONFIG_SAMA5_EBICS3_SIZE) +#define SAMA5_QSPI0AES_SIZE MKULONG(CONFIG_SAMA5_QSPI0AES_SIZE) +#define SAMA5_QSPI1AES_SIZE MKULONG(CONFIG_SAMA5_QSPI1AES_SIZE) +#define SAMA5_SDMMC0_SIZE MKULONG(CONFIG_SAMA5_SDMMC0_SIZE) +#define SAMA5_SDMMC1_SIZE MKULONG(CONFIG_SAMA5_SDMMC1_SIZE) +#define SAMA5_QSPI0_SIZE MKULONG(CONFIG_SAMA5_QSPI0_SIZE) +#define SAMA5_QSPI1_SIZE MKULONG(CONFIG_SAMA5_QSPI1_SIZE) + +#define SAMA5_EBICS0_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS0_HEAP_OFFSET) +#define SAMA5_DDRCS_HEAP_OFFSET MKULONG(CONFIG_SAMA5_DDRCS_HEAP_OFFSET) +#define SAMA5_DDRAES_HEAP_OFFSET MKULONG(CONFIG_SAMA5_DDRAES_HEAP_OFFSET) +#define SAMA5_EBICS1_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS1_HEAP_OFFSET) +#define SAMA5_EBICS2_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS2_HEAP_OFFSET) +#define SAMA5_EBICS3_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS3_HEAP_OFFSET) +#define SAMA5_QSPI0AES_HEAP_OFFSET MKULONG(CONFIG_SAMA5_QSPI0AES_HEAP_OFFSET) +#define SAMA5_QSPI1AES_HEAP_OFFSET MKULONG(CONFIG_SAMA5_QSPI1AES_HEAP_OFFSET) +#define SAMA5_SDMMC0_HEAP_OFFSET MKULONG(CONFIG_SAMA5_SDMMC0_HEAP_OFFSET) +#define SAMA5_SDMMC1_HEAP_OFFSET MKULONG(CONFIG_SAMA5_SDMMC1_HEAP_OFFSET) +#define SAMA5_QSPI0_HEAP_OFFSET MKULONG(CONFIG_SAMA5_QSPI0_HEAP_OFFSET) +#define SAMA5_QSPI1_HEAP_OFFSET MKULONG(CONFIG_SAMA5_QSPI1_HEAP_OFFSET) + +#define SAMA5_EBICS0_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS0_HEAP_SIZE) +#define SAMA5_DDRCS_HEAP_SIZE MKULONG(CONFIG_SAMA5_DDRCS_HEAP_SIZE) +#define SAMA5_DDRAESCS_HEAP_SIZE MKULONG(CONFIG_SAMA5_DDRAESCS_HEAP_SIZE) +#define SAMA5_EBICS1_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS1_HEAP_SIZE) +#define SAMA5_EBICS2_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS2_HEAP_SIZE) +#define SAMA5_EBICS3_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS3_HEAP_SIZE) +#define SAMA5_QSPI0AES_HEAP_SIZE MKULONG(CONFIG_SAMA5_QSPI0AES_HEAP_SIZE) +#define SAMA5_QSPI1AES_HEAP_SIZE MKULONG(CONFIG_SAMA5_QSPI1AES_HEAP_SIZE) +#define SAMA5_SDMMC0_HEAP_SIZE MKULONG(CONFIG_SAMA5_SDMMC0_HEAP_SIZE) +#define SAMA5_SDMMC1_HEAP_SIZE MKULONG(CONFIG_SAMA5_SDMMC1_HEAP_SIZE) +#define SAMA5_QSPI0_HEAP_SIZE MKULONG(CONFIG_SAMA5_QSPI0_HEAP_SIZE) +#define SAMA5_QSPI1_HEAP_SIZE MKULONG(CONFIG_SAMA5_QSPI1_HEAP_SIZE) + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of memory regions in sections. + * + * The boot logic in sam_boot.c, will select 1Mb level 1 MMU mappings to + * span the entire physical address space. The definitions below specify + * the number of 1Mb entries that are required to span a particular address + * region. + */ + +#define SAM_ROM_NSECTIONS _NSECTIONS(SAM_ROM_SIZE) +#define SAM_SRAMREMAP_NSECTIONS _NSECTIONS(SAM_SRAMREMAP_SIZE) +#define SAM_ECCROM_NSECTIONS _NSECTIONS(SAM_ECCROM_SIZE) +#define SAM_NFCSRAM_NSECTIONS _NSECTIONS(SAM_NFCSRAM_SIZE) +#define SAM_ISRAM_NSECTIONS _NSECTIONS(SAM_ISRAM_SIZE) +#define SAM_UDPHSRAM_NSECTIONS _NSECTIONS(SAM_UDPHSRAM_SIZE) +#define SAM_UHPOHCI_NSECTIONS _NSECTIONS(SAM_UHPOHCI_SIZE) +#define SAM_UHPEHCI_NSECTIONS _NSECTIONS(SAM_UHPEHCI_SIZE) +#define SAM_AXIMX_NSECTIONS _NSECTIONS(SAM_AXIMX_SIZE) +#define SAM_DAP_NSECTIONS _NSECTIONS(SAM_DAP_SIZE) +#define SAM_L2CC_NSECTIONS _NSECTIONS(SAM_L2CC_SIZE) + +#define SAM_EBICS0_NSECTIONS _NSECTIONS(SAMA5_EBICS0_SIZE) +#define SAM_DDRCS_NSECTIONS _NSECTIONS(SAMA5_DDRCS_SIZE) +#define SAM_DDRAESCS_NSECTIONS _NSECTIONS(SAMA5_DDRAESCS_SIZE) +#define SAM_EBICS1_NSECTIONS _NSECTIONS(SAMA5_EBICS1_SIZE) +#define SAM_EBICS2_NSECTIONS _NSECTIONS(SAMA5_EBICS2_SIZE) +#define SAM_EBICS3_NSECTIONS _NSECTIONS(SAMA5_EBICS3_SIZE) +#define SAM_QSPI0AES_NSECTIONS _NSECTIONS(SAMA5_QSPI0AES_SIZE) +#define SAM_QSPI1AES_NSECTIONS _NSECTIONS(SAMA5_QSPI1AES_SIZE) +#define SAM_SDMMC0_NSECTIONS _NSECTIONS(SAMA5_SDMMC0_SIZE) +#define SAM_SDMMC1_NSECTIONS _NSECTIONS(SAMA5_SDMMC1_SIZE) +#define SAM_QSPI0_NSECTIONS _NSECTIONS(SAMA5_QSPI0_SIZE) +#define SAM_QSPI1_NSECTIONS _NSECTIONS(SAMA5_QSPI1_SIZE) +#define SAM_NFCCR_NSECTIONS _NSECTIONS(SAM_NFCCR_SIZE) + +#define SAM_PERIPHA_NSECTIONS _NSECTIONS(SAM_PERIPHA_SIZE) +#define SAM_PERIPHB_NSECTIONS _NSECTIONS(SAM_PERIPHB_SIZE) +#define SAM_PERIPHC_NSECTIONS _NSECTIONS(SAM_PERIPHC_SIZE) + +/* Section MMU Flags */ + +#define SAM_ROM_MMUFLAGS MMU_ROMFLAGS +#define SAM_SRAMREMAP_MMUFLAGS MMU_MEMFLAGS +#define SAM_ECCROM_MMUFLAGS MMU_ROMFLAGS +#define SAM_ISRAM_MMUFLAGS MMU_MEMFLAGS +#define SAM_UDPHSRAM_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPOHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPEHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_AXIMX_MMUFLAGS MMU_IOFLAGS +#define SAM_DAP_MMUFLAGS MMU_IOFLAGS +#define SAM_L2CC_MMUFLAGS MMU_IOFLAGS + +/* If the NFC is not being used, the NFC SRAM can be used as general purpose + * SRAM (cached). If the NFC is used, then the NFC SRAM should be treated + * as an I/O devices (uncached). + */ + +#ifdef CONFIG_SAMA5_HAVE_NAND +# define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_NFCSRAM_MMUFLAGS MMU_MEMFLAGS +#endif + +/* SDRAM is a special case because it requires non-cached access of its + * initial configuration, then cached access thereafter. + */ + +#define SAM_DDRCS_MMUFLAGS MMU_MEMFLAGS +#define SAM_DDRAESCS_MMUFLAGS MMU_MEMFLAGS + +/* The external memory regions may support all access if they host SRAM, + * PSRAM, or SDRAM. NAND memory requires write access for NAND control and + * so should be uncached. + */ + +#if defined(CONFIG_SAMA5_EBICS0_SRAM) || defined(CONFIG_SAMA5_EBICS0_PSRAM) || \ + defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS0_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS1_SRAM) || defined(CONFIG_SAMA5_EBICS1_PSRAM) +# define SAM_EBICS1_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS1_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS1_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS2_SRAM) || defined(CONFIG_SAMA5_EBICS2_PSRAM) +# define SAM_EBICS2_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS2_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS2_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS3_SRAM) || defined(CONFIG_SAMA5_EBICS3_PSRAM) +# define SAM_EBICS3_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS3_NAND) +# define SAM_EBICS3_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS3_MMUFLAGS MMU_ROMFLAGS +#endif + +#define SAM_QSPI0AES MMU_IOFLAGS +#define SAM_QSPI1AES MMU_IOFLAGS +#define SAM_SDMMC0 MMU_IOFLAGS +#define SAM_SDMMC1 MMU_IOFLAGS +#define SAM_QSPI0 MMU_IOFLAGS +#define SAM_QSPI1 MMU_IOFLAGS +#define SAM_NFCCR_MMUFLAGS MMU_IOFLAGS + +#define SAM_PERIPHA_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHB_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHC_MMUFLAGS MMU_IOFLAGS + +/* SAMA5 Virtual (mapped) Memory Map + * + * board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* SAMA5 Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + +/* Notice that these mappings are a simple 1-to-1 mapping *unless* + * CONFIG_ARCH_LOWVECTORS is not defined. In the high vector case, the + * register system controls register area is moved out 0f 0xffff:000 where + * the high vectors must reside. + */ + +#define SAM_INTMEM_VSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +# define SAM_ROM_VSECTION 0x00000000 /* 0x00000000-0x0003ffff: ROM */ +# define SAM_SRAMREMAP_VSECTION 0x00000000 /* 0x00000000-0x0003ffff: Remapped ISRAM */ +# define SAM_ECCROM_VSECTION 0x00040000 /* 0x00040000-0x000fffff: EEC ROM */ +# define SAM_NFCSRAM_VSECTION 0x00100000 /* 0x00100000-0x001fffff: NFC SRAM */ +# define SAM_ISRAM_VSECTION 0x00200000 /* 0x00200000-0x002fffff: SRAM */ +# define SAM_ISRAM0_VADDR 0x00200000 /* 0x00200000-0x0021ffff: SRAM0 */ +# define SAM_ISRAM1_VADDR 0x00220000 /* 0x00220000-0x002fffff: SRAM1 */ +# define SAM_UDPHSRAM_VSECTION 0x00300000 /* 0x00300000-0x004fffff: UDPH SRAM */ +# define SAM_UHPOHCI_VSECTION 0x00400000 /* 0x00400000-0x005fffff: UHP OHCI */ +# define SAM_UHPEHCI_VSECTION 0x00500000 /* 0x00500000-0x005fffff: UHP EHCI */ +# define SAM_AXIMX_VSECTION 0x00600000 /* 0x00600000-0x006fffff: AXI Matrix */ +# define SAM_DAP_VSECTION 0x00700000 /* 0x00700000-0x007fffff: DAP */ +# define SAM_L2CC_VSECTION 0x00a00000 /* 0x00a00000-0x00bfffff: L2CC */ +#define SAM_EBICS0_VSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip select 0 */ +#define SAM_DDRCS_VSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDR Chip Select */ +#define SAM_DDRAESCS_VSECTION 0x40000000 /* 0x40000000-0x5fffffff: EBI DDR AES Chip Select */ +#define SAM_EBICS1_VSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip Select 1 */ +#define SAM_EBICS2_VSECTION 0x70000000 /* 0x70000000-0x7fffffff: EBI Chip Select 2 */ +#define SAM_EBICS3_VSECTION 0x80000000 /* 0x80000000-0x8fffffff: EBI Chip Select 3 */ +#define SAM_QSPI0AES_VSECTION 0x90000000 /* 0x90000000-0x9fffffff: QSPI0 AES Memory */ +#define SAM_QSPI1AES_VSECTION 0xa0000000 /* 0xa0000000-0xafffffff: QSPI1 AES Memory */ +#define SAM_SDMMC0_VSECTION 0xa0000000 /* 0xa0000000-0xafffffff: SDMMC0 */ +#define SAM_SDMMC1_VSECTION 0xb0000000 /* 0xb0000000-0xbfffffff: SDMMC1 */ +#define SAM_NFCCR_VSECTION 0xc0000000 /* 0xc0000000-0xcfffffff: NFC Command Registers */ +#define SAM_QSPI0_VSECTION 0xd0000000 /* 0xd0000000-0xd7ffffff: QSPI0 Memory */ +#define SAM_QSPI1_VSECTION 0xd8000000 /* 0xd8000000-0xdfffffff: QSPI1 Memory */ + /* 0x80000000-0xefffffff: Undefined */ + +/* If CONFIG_ARCH_LOWVECTORS is not defined, then move the system control + * registers out of the way. + */ + +#ifdef CONFIG_ARCH_LOWVECTORS +#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf7ffffff: Internal Peripherals A */ +# define SAM_PERIPHB_VSECTION 0xf8000000 /* 0xf8000000-0xfbffffff: Internal Peripherals B */ +# define SAM_PERIPHC_VSECTION 0xfc000000 /* 0xfc000000-0xffffffff: Internal Peripherals C */ +#else +#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf00fffff: Internal Peripherals A */ +# define SAM_PERIPHB_VSECTION 0xf1000000 /* 0xf1000000-0xf10fffff: Internal Peripherals B */ +# define SAM_PERIPHB_VSECTION 0xf2000000 /* 0xf2000000-0xf20fffff: Internal Peripherals C */ +#endif +#endif + +/* Peripheral virtual base addresses */ + +#define SAM_LCDC_VBASE (SAM_PERIPHA_VSECTION+SAM_LCDC_OFFSET) +#define SAM_XDMAC1_VBASE (SAM_PERIPHA_VSECTION+SAM_XDMAC1_OFFSET) +#define SAM_ISC_VBASE (SAM_PERIPHA_VSECTION+SAM_ISC_OFFSET) +#define SAM_MPDDRC_VBASE (SAM_PERIPHA_VSECTION+SAM_MPDDRC_OFFSET) +#define SAM_XDMAC0_VBASE (SAM_PERIPHA_VSECTION+SAM_XDMAC0_OFFSET) +#define SAM_PMC_VBASE (SAM_PERIPHA_VSECTION+SAM_PMC_OFFSET) +#define SAM_MATRIX0_VBASE (SAM_PERIPHA_VSECTION+SAM_MATRIX0_OFFSET) +#define SAM_AESB_VBASE (SAM_PERIPHA_VSECTION+SAM_AESB_OFFSET) +#define SAM_QSPI0_VBASE (SAM_PERIPHA_VSECTION+SAM_QSPI0_OFFSET) +#define SAM_QSPI1_VBASE (SAM_PERIPHA_VSECTION+SAM_QSPI1_OFFSET) +#define SAM_SHA_VBASE (SAM_PERIPHA_VSECTION+SAM_SHA_OFFSET) +#define SAM_AES_VBASE (SAM_PERIPHA_VSECTION+SAM_AES_OFFSET) + +#define SAM_SPI0_VBASE (SAM_PERIPHB_VSECTION+SAM_SPI0_OFFSET) +#define SAM_SSC0_VBASE (SAM_PERIPHB_VSECTION+SAM_SSC0_OFFSET) +#define SAM_EMAC0_VBASE (SAM_PERIPHB_VSECTION+SAM_EMAC0_OFFSET) +#define SAM_TC012_VBASE (SAM_PERIPHB_VSECTION+SAM_TC012_OFFSET) +#define SAM_TC345_VBASE (SAM_PERIPHB_VSECTION+SAM_TC345_OFFSET) +#define SAM_HSMC_VBASE (SAM_PERIPHB_VSECTION+SAM_HSMC_OFFSET) +#define SAM_PDMIC_VBASE (SAM_PERIPHB_VSECTION+SAM_PDMIC_OFFSET) +#define SAM_UART0_VBASE (SAM_PERIPHB_VSECTION+SAM_UART0_OFFSET) +#define SAM_UART1_VBASE (SAM_PERIPHB_VSECTION+SAM_UART1_OFFSET) +#define SAM_UART2_VBASE (SAM_PERIPHB_VSECTION+SAM_UART2_OFFSET) +#define SAM_TWI0_VBASE (SAM_PERIPHB_VSECTION+SAM_TWI0_OFFSET) +#define SAM_PWMC_VBASE (SAM_PERIPHB_VSECTION+SAM_PWMC_OFFSET) +#define SAM_SFR_VBASE (SAM_PERIPHB_VSECTION+SAM_SFR_OFFSET) +#define SAM_FLEXCOM0_VBASE (SAM_PERIPHB_VSECTION+SAM_FLEXCOM0_OFFSET) +#define SAM_FLEXCOM1_VBASE (SAM_PERIPHB_VSECTION+SAM_FLEXCOM1_OFFSET) +#define SAM_SAIC_VBASE (SAM_PERIPHB_VSECTION+SAM_SAIC_OFFSET) +#define SAM_ICM_VBASE (SAM_PERIPHB_VSECTION+SAM_ICM_OFFSET) +#define SAM_SECURAM_VBASE (SAM_PERIPHB_VSECTION+SAM_SECURAM_OFFSET) +#define SAM_SYSC_VBASE (SAM_PERIPHB_VSECTION+SAM_SYSC_OFFSET) +#define SAM_RSTC_VBASE (SAM_PERIPHB_VSECTION+SAM_RSTC_OFFSET) +#define SAM_SHDWC_VBASE (SAM_PERIPHB_VSECTION+SAM_SHDWC_OFFSET) +#define SAM_PITC_VBASE (SAM_PERIPHB_VSECTION+SAM_PITC_OFFSET) +#define SAM_WDT_VBASE (SAM_PERIPHB_VSECTION+SAM_WDT_OFFSET) +#define SAM_SCKCR_VBASE (SAM_PERIPHB_VSECTION+SAM_SCKCR_OFFSET) +#define SAM_RTCC_VBASE (SAM_PERIPHB_VSECTION+SAM_RTCC_OFFSET) +#define SAM_RXLP_VBASE (SAM_PERIPHB_VSECTION+SAM_RXLP_OFFSET) +#define SAM_ACC_VBASE (SAM_PERIPHB_VSECTION+SAM_ACC_OFFSET) +#define SAM_SFC_VBASE (SAM_PERIPHB_VSECTION+SAM_SFC_OFFSET) +#define SAM_I2SC0_VBASE (SAM_PERIPHB_VSECTION+SAM_I2SC0_OFFSET) +#define SAM_CAN0_VBASE (SAM_PERIPHB_VSECTION+SAM_CAN0_OFFSET) + +#define SAM_SPI1_VBASE (SAM_PERIPHC_VSECTION+SAM_SPI1_OFFSET) +#define SAM_SSC1_VBASE (SAM_PERIPHC_VSECTION+SAM_SSC1_OFFSET) +#define SAM_UART3_VBASE (SAM_PERIPHC_VSECTION+SAM_UART3_OFFSET) +#define SAM_UART4_VBASE (SAM_PERIPHC_VSECTION+SAM_UART4_OFFSET) +#define SAM_FLEXCOM2_VBASE (SAM_PERIPHC_VSECTION+SAM_FLEXCOM2_OFFSET) +#define SAM_FLEXCOM3_VBASE (SAM_PERIPHC_VSECTION+SAM_FLEXCOM3_OFFSET) +#define SAM_FLEXCOM4_VBASE (SAM_PERIPHC_VSECTION+SAM_FLEXCOM4_OFFSET) +#define SAM_TRNG_VBASE (SAM_PERIPHC_VSECTION+SAM_TRNG_OFFSET) +#define SAM_AIC_VBASE (SAM_PERIPHC_VSECTION+SAM_AIC_OFFSET) +#define SAM_TWI1_VBASE (SAM_PERIPHC_VSECTION+SAM_TWI1_OFFSET) +#define SAM_UDPHS_VBASE (SAM_PERIPHC_VSECTION+SAM_UDPHS_OFFSET) +#define SAM_ADC_VBASE (SAM_PERIPHC_VSECTION+SAM_ADC_OFFSET) +#define SAM_PIO_VBASE (SAM_PERIPHC_VSECTION+SAM_PIO_OFFSET) +#define SAM_MATRIX1_VBASE (SAM_PERIPHC_VSECTION+SAM_MATRIX1_OFFSET) +#define SAM_SECUMOD_VBASE (SAM_PERIPHC_VSECTION+SAM_SECUMOD_OFFSET) +#define SAM_TDES_VBASE (SAM_PERIPHC_VSECTION+SAM_TDES_OFFSET) +#define SAM_CLASSD_VBASE (SAM_PERIPHC_VSECTION+SAM_CLASSD_OFFSET) +#define SAM_I2SC1_VBASE (SAM_PERIPHC_VSECTION+SAM_I2SC1_OFFSET) +#define SAM_CAN1_VBASE (SAM_PERIPHC_VSECTION+SAM_CAN1_OFFSET) +#define SAM_UTMI_VBASE (SAM_PERIPHC_VSECTION+SAM_UTMI_OFFSET) +#define SAM_SFRBU_VBASE (SAM_PERIPHC_VSECTION+SAM_SFRBU_OFFSET) +#define SAM_CHIPID_VBASE (SAM_PERIPHC_VSECTION+SAM_CHIPID_OFFSET) + +/* NuttX virtual base address + * + * The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX could be running from NOR FLASH, + * SDRAM, external SRAM, or internal SRAM. If we are running from FLASH, + * then we must have a separate mapping for the non-contiguous RAM region. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) + +/* Some sanity checks. If we are running from FLASH, then one of the + * external chip selects must be configured to boot from NOR flash. + * And, if so, then its size must agree with the configured size. + */ + +# if defined(CONFIG_SAMA5_EBICS0) && defined(CONFIG_SAMA5_EBICS0_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS0FLASH) + +# if CONFIG_SAMA5_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS0 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS1) && defined(CONFIG_SAMA5_EBICS1_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS1FLASH) + +# if CONFIG_SAMA5_EBICS1_SIZE != CONFIG_FLASH_SIZE +# error CS1 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS2) && defined(CONFIG_SAMA5_EBICS2_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS2FLASH) + +# if CONFIG_SAMA2_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS2 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS3) && defined(CONFIG_SAMA5_EBICS3_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS3FLASH) + +# if CONFIG_SAMA5_EBICS3_SIZE != CONFIG_FLASH_SIZE +# error CS3 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH + +# else +# error CONFIG_BOOT_RUNFROMFLASH=y, but no bootable NOR flash defined + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# endif + + /* Set up the NOR FLASH region as the NUTTX .text region */ + +# define NUTTX_TEXT_VADDR (CONFIG_FLASH_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_FLASH_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_FLASH_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + + /* In the default configuration, the primary RAM used for .bss and .data + * is the internal SRAM. + */ + +# define NUTTX_RAM_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_RAM_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_RAM_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_RAM_SIZE (NUTTX_RAM_PEND - NUTTX_RAM_PADDR) + +#else /* CONFIG_BOOT_RUNFROMFLASH */ + + /* Otherwise we are running from some kind of RAM (ISRAM or SDRAM). + * Setup the RAM region as the NUTTX .txt, .bss, and .data region. + */ + +# define NUTTX_TEXT_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + +#endif /* CONFIG_BOOT_RUNFROMFLASH */ + +/* MMU Page Table Location + * + * Determine the address of the MMU page table. Regardless of the memory + * configuration, we will keep the page table in the SAMA5's internal SRAM. + * We will always attempt to use the bottom 16KB of internal SRAM for the + * page table, but there are a few conditions that affect this: + * + * 1) If CONFIG_ARCH_ROMPGTABLE, then the page table resides in ROM and we + * will not use any page table in RAM. + * 2) We are executing out of SRAM. In this case, vectors will reside at + * the bottom of SRAM, following by .text, .data, .bss, and heep. The + * page table will be squeezed into the end of internal SRAM in this + * case. + * + * Or... the user may specify the address of the page table explicitly be defining + * PGTABLE_BASE_VADDR and PGTABLE_BASE_PADDR in the board.h file. + */ + +#undef PGTABLE_IN_HIGHSRAM +#undef PGTABLE_IN_LOWSRAM +#undef ARMV7A_PGTABLE_MAPPING + +#if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. In that case PGTABLE_BASE_VADDR is defined + * in the file mmu.h + * + * We must declare the page table at the bottom or at the top of internal + * SRAM. We pick the bottom of internal SRAM *unless* there are vectors + * in the way at that position. + */ + +# if defined(CONFIG_SAMA5_BOOT_ISRAM) && defined(CONFIG_ARCH_LOWVECTORS) + + /* In this case, page table must lie at the top 16Kb of ISRAM1 (or ISRAM0 + * if ISRAM1 is not available in this architecture) + * + * If CONFIG_PAGING is defined, then mmu.h assign the virtual address + * of the page table. + */ + +# if SAM_ISRAM1_SIZE > 0 +# define PGTABLE_BASE_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# endif +# else +# define PGTABLE_BASE_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# endif +# endif +# define PGTABLE_IN_HIGHSRAM 1 + + /* If we execute from SRAM but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the vector table, + * lying between the vector table and the page table. We don't really + * know how much memory to set aside for the vector table, but 4KiB should + * be much more than enough + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + 0x0001000) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + 0x0001000) +# endif + +# else /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps + * elsewhere in internal SRAM). The page table will then be positioned at + * the first 16Kb of ISRAM0. + */ + +# define PGTABLE_BASE_PADDR SAM_ISRAM0_PADDR +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR SAM_ISRAM0_VADDR +# endif +# define PGTABLE_IN_LOWSRAM 1 + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) +# endif + +# endif /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* In either case, the page table lies in ISRAM. If ISRAM is not the + * primary RAM region, then we will need to set-up a special mapping for + * the page table at boot time. + */ + +# if defined(CONFIG_BOOT_RUNFROMFLASH) + /* If we are running from FLASH, then the primary memory region is + * given by NUTTX_RAM_PADDR. + */ + +# if NUTTX_RAM_PADDR != SAM_ISRAM_PSECTION +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +/* Otherwise, we are running from RAM and that RAM is also the primary + * RAM. + */ + +# elif !defined(CONFIG_SAMA5_BOOT_ISRAM) +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +#else /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + + /* Sanity check.. if one is defined, both should be defined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "One of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is undefined" +# endif + + /* If we execute from SRAM but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the page table + * in ISRAM. + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + PGTABLE_SIZE) +# endif + +#endif /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + +/* Level 2 Page table start addresses. + * + * 16Kb of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation). There is this large whole in the physcal address space + * for which there will never be level 1 mappings: + * + * 0x80000000-0xefffffff: Undefined (1.75 GB) + * + * That is the offset where the main L2 page tables will be positioned. This + * corresponds to page table offsets 0x000002000 up to 0x000003c00. That + * is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual + * address space) + * + * Up to two L2 page tables may be used: + * + * 1) One mapping the vector table. However, L2 page tables must be aligned + * to 1KB address boundaries, so the minimum L2 page table size is then + * 1KB, mapping up a full megabyte of virtual address space. + * + * This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not* + * defined. The SAMA5 boot-up logic will map the beginning of the boot + * memory to address 0x0000:0000 using both the MMU and the AXI matrix + * REMAP register. So no L2 page table is required. + * + * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional + * L2 page table is needed. This page table will use the remainder of + * the address space. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Vector L2 page table offset/size */ + +# define VECTOR_L2_OFFSET 0x000002000 +# define VECTOR_L2_SIZE 0x000000400 + + /* Vector L2 page table base addresses */ + +# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET) +# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET) + + /* Vector L2 page table end addresses */ + +# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE) +# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE) + + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002400 +# define PGTABLE_L2_SIZE 0x000001800 + +#else + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002000 +# define PGTABLE_L2_SIZE 0x000001c00 +#endif + +/* Paging L2 page table base addresses + * + * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +/* Paging L2 page table end addresses */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE) + +/* Base address of the interrupt vector table. + * + * SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * SAM_VECTOR_VSRAM - Virtual address of vector table in SRAM + * SAM_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + +#define VECTOR_TABLE_SIZE 0x00010000 + +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + +# define SAM_VECTOR_PADDR SAM_ISRAM0_PADDR +# define SAM_VECTOR_VSRAM SAM_ISRAM0_VADDR +# define SAM_VECTOR_VADDR 0x00000000 + +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ + +# ifdef SAM_ISRAM1_SIZE >= VECTOR_TABLE_SIZE +# define SAM_VECTOR_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# else +# define SAM_VECTOR_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# endif +# define SAM_VECTOR_VADDR 0xffff0000 + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_MEMORYMAP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d2x_pinmap.h b/arch/arm/src/sama5/chip/_sama5d2x_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..1b4553cdc02a76572d014833d122eb826b44a36d --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d2x_pinmap.h @@ -0,0 +1,804 @@ +/************************************************************************************************************ + * arch/arm/src/sama5/chip/_sama5d2x_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PINMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PINMAP_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_pio.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ + +/* PIO pin definitions **************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, however, will + * use the pin selection without the numeric suffix. Additional definitions are required in the board.h + * file. For example, if we wanted the PCK0 on PB26, then the following definition should appear in the + * board.h header file for that board: + * + * #define PIO_PMC_PCK0 PIO_PMC_PCK0_1 + * + * The PCK logic will then automatically configure PB26 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific PIO options such as frequency, open-drain/push-pull, + * and pull-up/down! Just the basics are defined for most pins in this file at the present time. + */ + +/* Analog-to-Digital Converter - ADC */ + +#define PIO_ADC_AD0 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_ADC_AD1 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_ADC_AD2 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_ADC_AD3 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_ADC_AD4 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_ADC_AD5 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_ADC_AD6 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN25) +#define PIO_ADC_AD7 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_ADC_AD8 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) +#define PIO_ADC_AD9 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) +#define PIO_ADC_AD10 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_ADC_AD11 (PIO_ANALOG | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) +#define PIO_ADC_TRG (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN31) + +/* Advanced Interrupt Controller - AIC */ + +#define PIO_FIQ_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_FIQ_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_FIQ_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_FIQ_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_IRQ_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_IRQ_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_IRQ_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_IRQ_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) + +/* Control Area Network - CAN */ + +#define PIO_CAN0_RX_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_CAN0_RX_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_CAN0_TX_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_CAN0_TX_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_CAN1_RX (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_CAN1_TX (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) + +/* Audio Class Amplifier - Class D */ + +#define PIO_CLASSD_L0 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_CLASSD_L1 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_CLASSD_L2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_CLASSD_L3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) +#define PIO_CLASSD_R0 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_CLASSD_R1 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_CLASSD_R2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_CLASSD_R3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) + +/* External Bus Interface - EBI */ + +#define PIO_EBI_A0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_EBI_A0_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_EBI_A1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_EBI_A1_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_EBI_A2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_EBI_A2_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_EBI_A3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_EBI_A3_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_EBI_A4_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_EBI_A4_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_EBI_A5_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_EBI_A5_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_EBI_A6_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_EBI_A6_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_EBI_A7_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_EBI_A7_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_EBI_A8_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_EBI_A8_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_EBI_A9_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_EBI_A9_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_EBI_A10_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_EBI_A10_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_EBI_A11_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_EBI_A11_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_EBI_A12_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_EBI_A12_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_EBI_A13_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_EBI_A13_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_EBI_A14_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_EBI_A14_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_EBI_A15_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_EBI_A15_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) +#define PIO_EBI_A16_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_EBI_A16_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_EBI_A17_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_EBI_A17_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_EBI_A18_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_EBI_A18_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_EBI_A19_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_EBI_A19_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) +#define PIO_EBI_A20_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_EBI_A20_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_EBI_A21_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_EBI_A21_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_EBI_A22_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_EBI_A22_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_EBI_A23_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_EBI_A23_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_EBI_A24_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_EBI_A24_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN1) +#define PIO_EBI_A25_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_EBI_A25_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN2) + +#define PIO_EBI_D0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_EBI_D0_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_EBI_D1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_EBI_D1_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_EBI_D2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_EBI_D2_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_EBI_D3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_EBI_D3_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_EBI_D4_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) +#define PIO_EBI_D4_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_EBI_D5_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_EBI_D5_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_EBI_D6_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_EBI_D6_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_EBI_D7_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_EBI_D7_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_EBI_D8_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_EBI_D8_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_EBI_D9_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_EBI_D9_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_EBI_D10_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_EBI_D10_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_EBI_D11_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_EBI_D11_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_EBI_D12_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_EBI_D12_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_EBI_D13_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_EBI_D13_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_EBI_D14_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_EBI_D14_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_EBI_D15_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_EBI_D15_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) + +#define PIO_EBI_NWAIT_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_EBI_NWAIT_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) + +/* FLEXCOM */ + +#define PIO_FLEXCOM0_IO0 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_FLEXCOM0_IO1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_FLEXCOM0_IO2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_FLEXCOM0_IO3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_FLEXCOM0_IO4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) + +#define PIO_FLEXCOM1_IO0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_FLEXCOM1_IO1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_FLEXCOM1_IO2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_FLEXCOM1_IO3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_FLEXCOM1_IO4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) + +#define PIO_FLEXCOM2_IO0_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_FLEXCOM2_IO0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_FLEXCOM2_IO1_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) +#define PIO_FLEXCOM2_IO1_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_FLEXCOM2_IO2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) +#define PIO_FLEXCOM2_IO3_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_FLEXCOM2_IO3_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_FLEXCOM2_IO4_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) +#define PIO_FLEXCOM2_IO4_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) + +#define PIO_FLEXCOM3_IO0_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_FLEXCOM3_IO0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_FLEXCOM3_IO0_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_FLEXCOM3_IO1_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_FLEXCOM3_IO1_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_FLEXCOM3_IO1_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_FLEXCOM3_IO2_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_FLEXCOM3_IO2_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_FLEXCOM3_IO2_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_FLEXCOM3_IO3_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_FLEXCOM3_IO3_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_FLEXCOM3_IO3_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_FLEXCOM3_IO4_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_FLEXCOM3_IO4_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_FLEXCOM3_IO4_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) + +#define PIO_FLEXCOM4_IO0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_FLEXCOM4_IO0_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_FLEXCOM4_IO0_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_FLEXCOM4_IO1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_FLEXCOM4_IO1_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_FLEXCOM4_IO1_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_FLEXCOM4_IO2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) +#define PIO_FLEXCOM4_IO2_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_FLEXCOM4_IO2_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_FLEXCOM4_IO3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_FLEXCOM4_IO3_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_FLEXCOM4_IO3_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_FLEXCOM4_IO4_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_FLEXCOM4_IO4_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_FLEXCOM4_IO4_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN25) + +/* Ethernet MAC -- EMAC0 */ + +#define PIO_EMAC0_COL_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_EMAC0_COL_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_EMAC0_COL_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_EMAC0_CRS_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_EMAC0_CRS_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_EMAC0_CRS_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_EMAC0_MDC_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_EMAC0_MDC_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_EMAC0_MDC_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_EMAC0_MDIO_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_EMAC0_MDIO_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_EMAC0_MDIO_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_EMAC0_RX0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_EMAC0_RX0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_EMAC0_RX0_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_EMAC0_RX1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_EMAC0_RX1_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_EMAC0_RX1_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_EMAC0_RX2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_EMAC0_RX2_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_EMAC0_RX2_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_EMAC0_RX3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_EMAC0_RX3_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_EMAC0_RX3_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_EMAC0_RXCK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_EMAC0_RXCK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN1) +#define PIO_EMAC0_RXCK_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_EMAC0_RXDV_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_EMAC0_RXDV_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_EMAC0_RXDV_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_EMAC0_RXER_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_EMAC0_RXER_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_EMAC0_RXER_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_EMAC0_TSUCOMP_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_EMAC0_TSUCOMP_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_EMAC0_TSUCOMP_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_EMAC0_TX0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_EMAC0_TX0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_EMAC0_TX0_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_EMAC0_TX1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_EMAC0_TX1_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_EMAC0_TX1_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_EMAC0_TX2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) +#define PIO_EMAC0_TX2_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_EMAC0_TX2_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_EMAC0_TX3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_EMAC0_TX3_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_EMAC0_TX3_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_EMAC0_TXCK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_EMAC0_TXCK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_EMAC0_TXCK_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_EMAC0_TXEN_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_EMAC0_TXEN_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_EMAC0_TXEN_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_EMAC0_TXER_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_EMAC0_TXER_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN2) +#define PIO_EMAC0_TXER_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) + +/* Static Memory Controller - HSMC */ + +#define PIO_NANDALE_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_NANDALE_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_NANDCLE_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_NANDCLE_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_NANDOE_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_NANDOE_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_NANDRDY_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_NANDRDY_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_NANDWE (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_NBS0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_NBS0_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_NBS1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_NBS1_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_NCS0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_NCS0_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_NCS1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_NCS1_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_NCS2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_NCS2_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_NCS3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) +#define PIO_NCS3_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_NRD_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_NRD_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_NWE (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_NWR1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_NWR1_2 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) + +/* Inter-IC Sound Controller - I2SC */ + +#define PIO_I2SC0_CK_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_I2SC0_CK_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_I2SC0_DI0_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_I2SC0_DI0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_I2SC0_DO0_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_I2SC0_DO0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_I2SC0_MCK_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_I2SC0_MCK_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_I2SC0_WS_1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_I2SC0_WS_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) + +#define PIO_I2SC1_CK_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_I2SC1_CK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_I2SC1_DI0_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_I2SC1_DI0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_I2SC1_DO0_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_I2SC1_DO0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_I2SC1_MCK_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_I2SC1_MCK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_I2SC1_WS_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_I2SC1_WS_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) + +/* Image Sensor Controller - ISC */ + +#define PIO_ISC_D0_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_ISC_D0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_ISC_D0_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_ISC_D1_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_ISC_D1_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_ISC_D1_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_ISC_D2_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_ISC_D2_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_ISC_D2_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_ISC_D3_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_ISC_D3_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_ISC_D3_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_ISC_D4_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_ISC_D4_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_ISC_D4_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_ISC_D4_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_ISC_D5_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_ISC_D5_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_ISC_D5_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_ISC_D5_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_ISC_D6_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_ISC_D6_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_ISC_D6_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_ISC_D6_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_ISC_D7_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_ISC_D7_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_ISC_D7_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_ISC_D7_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_ISC_D8_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_ISC_D8_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_ISC_D8_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_ISC_D8_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_ISC_D9_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_ISC_D9_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_ISC_D9_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_ISC_D9_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_ISC_D10_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_ISC_D10_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_ISC_D10_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_ISC_D10_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_ISC_D11_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_ISC_D11_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_ISC_D11_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_ISC_D11_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_ISC_FIELD_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_ISC_FIELD_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_ISC_FIELD_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_ISC_FIELD_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_ISC_HSYNC_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_ISC_HSYNC_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_ISC_HSYNC_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_ISC_HSYNC_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_ISC_MCK_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_ISC_MCK_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN2) +#define PIO_ISC_MCK_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_ISC_MCK_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_ISC_PCK_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_ISC_PCK_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_ISC_PCK_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_ISC_PCK_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_ISC_VSYNC_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_ISC_VSYNC_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_ISC_VSYNC_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_ISC_VSYNC_4 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) + +/* ICE and JTAG */ + +#define PIO_JTAG_TCK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_JTAG_TCK_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_JTAG_TCK_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) +#define PIO_JTAG_TCK_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_JTAG_TDI_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_JTAG_TDI_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) +#define PIO_JTAG_TDI_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) +#define PIO_JTAG_TDI_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_JTAG_TDO_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_JTAG_TDO_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_JTAG_TDO_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_JTAG_TDO_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_JTAG_TMS_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_JTAG_TMS_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_JTAG_TMS_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) +#define PIO_JTAG_TMS_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) + +/* LCD Controller - LCDC */ + +#define PIO_LCD_DAT0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_LCD_DAT1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_LCD_DAT2_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_LCD_DAT2_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_LCD_DAT3_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_LCD_DAT3_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_LCD_DAT4_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_LCD_DAT4_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_LCD_DAT5_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_LCD_DAT5_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_LCD_DAT6_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_LCD_DAT6_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_LCD_DAT7_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_LCD_DAT7_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_LCD_DAT8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_LCD_DAT9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_LCD_DAT10_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_LCD_DAT10_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_LCD_DAT11_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_LCD_DAT11_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_LCD_DAT12_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_LCD_DAT12_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_LCD_DAT13_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_LCD_DAT13_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_LCD_DAT14_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_LCD_DAT14_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_LCD_DAT15_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_LCD_DAT15_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_LCD_DAT16 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_LCD_DAT17 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_LCD_DAT18_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_LCD_DAT18_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_LCD_DAT19_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_LCD_DAT19_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_LCD_DAT20_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_LCD_DAT20_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_LCD_DAT21_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_LCD_DAT21_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_LCD_DAT22_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_LCD_DAT22_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) +#define PIO_LCD_DAT23_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_LCD_DAT23_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_LCD_DEN_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_LCD_DEN_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN1) +#define PIO_LCD_DISP_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_LCD_DISP_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_LCD_HSYNC_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_LCD_HSYNC_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_LCD_PCK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_LCD_PCK_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_LCD_PWM_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_LCD_PWM_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_LCD_VSYNC_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) +#define PIO_LCD_VSYNC_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) + +/* Clocks, Oscillators and PLLs */ + +#define PIO_PMC_PCK0_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_PMC_PCK0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_PMC_PCK0_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) +#define PIO_PMC_PCK1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) +#define PIO_PMC_PCK1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_PMC_PCK1_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_PMC_PCK1_4 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_PMC_PCK2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_PMC_PCK2_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_PMC_PCK2_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) + +/* Pulse Density Modulation Interface Controller - PDMIC */ + +#define PIO_PDMIC_CLK_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_PDMIC_CLK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_PDMIC_DAT_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_PDMIC_DAT_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) + + +/* Pulse Width Modulation Controller - PWM */ + +#define PIO_PWM0_EXTRG0 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_PWM0_EXTRG1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_PWM0_FI0 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_PWM0_FI1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_PWM0_H0 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_PWM0_H1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_PWM0_H2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_PWM0_H3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_PWM0_L0 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) +#define PIO_PWM0_L1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_PWM0_L2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_PWM0_L3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) + +/* Reset Control -- RSTC */ + +#define PIO_RSTC_NTRST_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_RSTC_NTRST_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_RSTC_NTRST_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) +#define PIO_RSTC_NTRST_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) + +/* Quad IO SPI - QSPI */ + +#define PIO_QSPI0_CS_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_QSPI0_CS_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_QSPI0_CS_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_QSPI0_IO0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_QSPI0_IO0_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_QSPI0_IO0_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_QSPI0_IO1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_QSPI0_IO1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_QSPI0_IO1_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_QSPI0_IO2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_QSPI0_IO2_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_QSPI0_IO2_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) +#define PIO_QSPI0_IO3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_QSPI0_IO3_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_QSPI0_IO3_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_QSPI0_SCK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_QSPI0_SCK_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_QSPI0_SCK_3 (PIO_PERIPHF | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) + +#define PIO_QSPI1_CS_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_QSPI1_CS_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_QSPI1_CS_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_QSPI1_IO0_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_QSPI1_IO0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_QSPI1_IO0_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_QSPI1_IO1_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_QSPI1_IO1_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_QSPI1_IO2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_QSPI1_IO2_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_QSPI1_IO2_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_QSPI1_IO3_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_QSPI1_IO3_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_QSPI1_IO3_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_QSPI1_SCK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_QSPI1_SCK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_QSPI1_SCK_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) + +/* Secure Data Memory Card - SDMMC */ + +#define PIO_SDMMC0_CD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_SDMMC0_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_SDMMC0_CMD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_SDMMC0_DAT0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_SDMMC0_DAT1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_SDMMC0_DAT2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_SDMMC0_DAT3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_SDMMC0_DAT4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_SDMMC0_DAT5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_SDMMC0_DAT6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_SDMMC0_DAT7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_SDMMC0_RSTN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_SDMMC0_VDDSEL (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_SDMMC0_WP (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) + +#define PIO_SDMMC1_CD (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_SDMMC1_CK (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_SDMMC1_CMD (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_SDMMC1_DAT0 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_SDMMC1_DAT1 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_SDMMC1_DAT2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) +#define PIO_SDMMC1_DAT3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_SDMMC1_RSTN (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_SDMMC1_WP (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) + +/* Serial Peripheral Interface - SPI */ + +#define PIO_SPI0_MISO_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_SPI0_MISO_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) +#define PIO_SPI0_MOSI_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_SPI0_MOSI_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_SPI0_NPCS0_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_SPI0_NPCS0_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) +#define PIO_SPI0_NPCS1_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_SPI0_NPCS1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_SPI0_NPCS2_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_SPI0_NPCS2_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_SPI0_NPCS3_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) +#define PIO_SPI0_NPCS3_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_SPI0_SPCK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_SPI0_SPCK_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) + +#define PIO_SPI1_MISO_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) +#define PIO_SPI1_MISO_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_SPI1_MISO_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_SPI1_MOSI_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_SPI1_MOSI_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_SPI1_MOSI_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_SPI1_NPCS0_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) +#define PIO_SPI1_NPCS0_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_SPI1_NPCS0_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_SPI1_NPCS1_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_SPI1_NPCS1_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) +#define PIO_SPI1_NPCS1_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_SPI1_NPCS2_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) +#define PIO_SPI1_NPCS2_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_SPI1_NPCS2_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_SPI1_NPCS3_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_SPI1_NPCS3_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_SPI1_SPCK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN25) +#define PIO_SPI1_SPCK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_SPI1_SPCK_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) + +/* Synchronous Serial Controller - SSC */ + +#define PIO_SSC0_RD_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_SSC0_RD_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_SSC0_RF_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_SSC0_RF_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_SSC0_RK_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_SSC0_RK_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_SSC0_TD0_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_SSC0_TD0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_SSC0_TF0_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_SSC0_TF0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_SSC0_TK0_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_SSC0_TK0_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) + +#define PIO_SSC1_RD_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_SSC1_RD_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_SSC1_RF_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_SSC1_RF_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_SSC1_RK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_SSC1_RK_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_SSC1_TD1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_SSC1_TD1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_SSC1_TF1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_SSC1_TF1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_SSC1_TK1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_SSC1_TK1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) + +/* Timer/Counter - TC */ + +#define PIO_TC0_CLK (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_TC0_IOA (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_TC0_IOB (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) + +#define PIO_TC1_CLK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_TC1_CLK_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_TC1_CLK_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_TC1_IOA_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_TC1_IOA_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_TC1_IOA_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_TC1_IOB_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_TC1_IOB_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_TC1_IOB_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) + +#define PIO_TC2_CLK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_TC2_CLK_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_TC2_CLK_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_TC2_IOA_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_TC2_IOA_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_TC2_IOA_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_TC2_IOB_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_TC2_IOB_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_TC2_IOB_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) + +#define PIO_TC3_CLK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_TC3_CLK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_TC3_CLK_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) +#define PIO_TC3_IOA_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_TC3_IOA_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_TC3_IOA_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_TC3_IOB_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_TC3_IOB_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_TC3_IOB_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) + +#define PIO_TC4_CLK_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_TC4_CLK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_TC4_IOA_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_TC4_IOA_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_TC4_IOB_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_TC4_IOB_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) + +#define PIO_TC5_CLK_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOa | PIO_PIN8) +#define PIO_TC5_CLK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_TC5_IOA_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_TC5_IOA_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_TC5_IOB_1 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_TC5_IOB_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) + +/* Two-Wire Interface - TWI */ + +#define PIO_TWI0_CK_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_TWI0_CK_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_TWI0_CK_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_TWI0_CK_4 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) +#define PIO_TWI0_D_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_TWI0_D_2 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_TWI0_D_3 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_TWI0_D_4 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) + +#define PIO_TWI1_CK_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_TWI1_CK_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_TWI1_CK_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_TWI1_D_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_TWI1_D_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_TWI1_D_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) + +/* Universal Asynchronous Receiver Transmitter - UART */ + +#define PIO_UART0_TXD (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_UART0_RXD (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) + +#define PIO_UART1_RXD_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN2) +#define PIO_UART1_RXD_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_UART1_TXD_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) +#define PIO_UART1_TXD_2 (PIO_PERIPHE | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) + +#define PIO_UART2_RXD_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_UART2_RXD_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) +#define PIO_UART2_RXD_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_UART2_TXD_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_UART2_TXD_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) +#define PIO_UART2_TXD_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) + +#define PIO_UART3_RXD_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_UART3_RXD_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_UART3_RXD_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_UART3_TXD_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_UART3_TXD_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) +#define PIO_UART3_TXD_3 (PIO_PERIPHD | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) + +#define PIO_UART4_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_UART4_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) + +/* UTMI */ + +#define PIO_UTMI_CDRBISTEN (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_UTMI_CDRCPDIVEN (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_UTMI_CDRCPSEL0 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_UTMI_CDRCPSEL1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_UTMI_CDRCPSELDIV (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_UTMI_HDIS (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_UTMI_LS0 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_UTMI_LS1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_UTMI_RXACT (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_UTMI_RXERR (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_UTMI_RXVAL (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PINMAP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d2x_pio.h b/arch/arm/src/sama5/chip/_sama5d2x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..a821e56d84bec73a2626fd78a3c535945a22c3a3 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d2x_pio.h @@ -0,0 +1,337 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/_sama5d2x_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAMA5D2 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PIO_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* Misc Helper Definitions **************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define PIOD (3) +#define PIOE (4) + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_IOGROUP_OFFSET(n) (0x0000 + ((n) << 6)) +# define SAM_PIO_IOGROUPA_OFFSET 0x0000 +# define SAM_PIO_IOGROUPB_OFFSET 0x0040 +# define SAM_PIO_IOGROUPC_OFFSET 0x0080 +# define SAM_PIO_IOGROUPD_OFFSET 0x00c0 + +#define SAM_PIO_MSKR_OFFSET 0x0000 /* PIO Mask Register */ +#define SAM_PIO_CFGR_OFFSET 0x0004 /* PIO Configuration Register */ +#define SAM_PIO_PDSR_OFFSET 0x0008 /* PIO Pin Data Status Register */ +#define SAM_PIO_LOCKSR_OFFSET 0x000c /* PIO Lock Status Register */ +#define SAM_PIO_SODR_OFFSET 0x0010 /* PIO Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0014 /* PIO Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0018 /* PIO Output Data Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IER_OFFSET 0x0020 /* PIO Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0024 /* PIO Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0028 /* PIO Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x002c /* PIO Interrupt Status Register */ + /* 0x0030-0x0038: Reserved */ +#define SAM_PIO_IOFR_OFFSET 0x003c /* PIO I/O Freeze Register */ + /* 0x0040-0x05dc: Reserved */ + +#define SAM_PIO_WPMR_OFFSET 0x05e0 /* PIO Write Protection Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x05e4 /* PIO Write Protection Status Register */ + /* 0x05e8–0x0ffc: Reserved */ + +#define SAM_SPIO_IOGROUP_OFFSET(n) (0x1000 + ((n) << 6)) +# define SAM_SPIO_IOGROUPA_OFFSET 0x1000 +# define SAM_SPIO_IOGROUPB_OFFSET 0x1040 +# define SAM_SPIO_IOGROUPC_OFFSET 0x1080 +# define SAM_SPIO_IOGROUPD_OFFSET 0x10c0 + +#define SAM_SPIO_MSKR_OFFSET 0x0000 /* Secure PIO Mask Register */ +#define SAM_SPIO_CFGR_OFFSET 0x0004 /* Secure PIO Configuration Register */ +#define SAM_SPIO_PDSR_OFFSET 0x0008 /* Secure PIO Pin Data Status Register */ +#define SAM_SPIO_LOCKSR_OFFSET 0x000c /* Secure PIO Lock Status Register */ +#define SAM_SPIO_SODR_OFFSET 0x0010 /* Secure PIO Set Output Data Register */ +#define SAM_SPIO_CODR_OFFSET 0x0014 /* Secure PIO Clear Output Data Register */ +#define SAM_SPIO_ODSR_OFFSET 0x0018 /* Secure PIO Output Data Status Register */ + /* 0x001c: Reserved */ +#define SAM_SPIO_IER_OFFSET 0x0020 /* Secure PIO Interrupt Enable Register */ +#define SAM_SPIO_IDR_OFFSET 0x0024 /* Secure PIO Interrupt Disable Register */ +#define SAM_SPIO_IMR_OFFSET 0x0028 /* Secure PIO Interrupt Mask Register */ +#define SAM_SPIO_ISR_OFFSET 0x002c /* Secure PIO Interrupt Status Register */ +#define SAM_SPIO_SIONR_OFFSET 0x0030 /* Secure PIO Set I/O Non-Secure Register */ +#define SAM_SPIO_SIOSR_OFFSET 0x0034 /* Secure PIO Set I/O Secure Register */ +#define SAM_SPIO_IOSSR_OFFSET 0x0038 /* Secure PIO I/O Security Status Register */ +#define SAM_SPIO_IOFR_OFFSET 0x003c /* Secure PIO I/O Freeze Register */ + /* 0x1400–0x14fc: Reserved */ + +#define SAM_SPIO_SCDR_OFFSET 0x1500 /* Secure PIO Slow Clock Divider Debouncing Register */ + /* 0x1504-0x15dc: Reserved */ +#define SAM_SPIO_WPMR_OFFSET 0x15e0 /* Secure PIO Write Protection Mode Register */ +#define SAM_SPIO_WPSR_OFFSET 0x15e4 /* Secure PIO Write Protection Status Register */ + +/* PIO register addresses ***************************************************************/ + +#define SAM_PIO_IOGROUP_VBASE(n) (SAM_PIO_VBASE+SAM_PIO_IOGROUP_OFFSET(n)) +# define SAM_PIO_IOGROUPA_VBASE (SAM_PIO_VBASE+SAM_PIO_IOGROUPA_OFFSET) +# define SAM_PIO_IOGROUPB_VBASE (SAM_PIO_VBASE+SAM_PIO_IOGROUPB_OFFSET) +# define SAM_PIO_IOGROUPC_VBASE (SAM_PIO_VBASE+SAM_PIO_IOGROUPC_OFFSET) +# define SAM_PIO_IOGROUPD_VBASE (SAM_PIO_VBASE+SAM_PIO_IOGROUPD_OFFSET) + +#define SAM_PIOA_MSKR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_MSKR_OFFSET) +#define SAM_PIOA_CFGR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_CFGR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_LOCKSR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_IOFR (SAM_PIO_IOGROUPA_VBASE+SAM_PIO_IOFR_OFFSET) + +#define SAM_PIOB_MSKR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_MSKR_OFFSET) +#define SAM_PIOB_CFGR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_CFGR_OFFSET) +#define SAM_PIOB_PDSR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOB_LOCKSR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOB_SODR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOB_CODR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOB_ODSR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOB_IER (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOB_IDR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOB_IMR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOB_ISR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOB_IOFR (SAM_PIO_IOGROUPB_VBASE+SAM_PIO_IOFR_OFFSET) + +#define SAM_PIOC_MSKR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_MSKR_OFFSET) +#define SAM_PIOC_CFGR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_CFGR_OFFSET) +#define SAM_PIOC_PDSR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOC_LOCKSR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOC_SODR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOC_CODR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOC_ODSR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOC_IER (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOC_IDR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOC_IMR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOC_ISR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOC_IOFR (SAM_PIO_IOGROUPC_VBASE+SAM_PIO_IOFR_OFFSET) + +#define SAM_PIOD_MSKR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_MSKR_OFFSET) +#define SAM_PIOD_CFGR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_CFGR_OFFSET) +#define SAM_PIOD_PDSR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOD_LOCKSR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOD_SODR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOD_CODR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOD_ODSR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOD_IER (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOD_IDR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOD_IMR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOD_ISR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOD_IOFR (SAM_PIO_IOGROUPD_VBASE+SAM_PIO_IOFR_OFFSET) + +#define SAM_PIO_WPMR (SAM_PIO_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIO_WPSR (SAM_PIO_VBASE+SAM_PIO_WPSR_OFFSET) + +#define SAM_SPIO_IOGROUP_VBASE(n) (SAM_PIO_VBASE+SAM_SPIO_IOGROUP_OFFSET(n)) +# define SAM_SPIO_IOGROUPA_VBASE (SAM_PIO_VBASE+SAM_SPIO_IOGROUPA_OFFSET) +# define SAM_SPIO_IOGROUPB_VBASE (SAM_PIO_VBASE+SAM_SPIO_IOGROUPB_OFFSET) +# define SAM_SPIO_IOGROUPC_VBASE (SAM_PIO_VBASE+SAM_SPIO_IOGROUPC_OFFSET) +# define SAM_SPIO_IOGROUPD_VBASE (SAM_PIO_VBASE+SAM_SPIO_IOGROUPD_OFFSET) + +#define SAM_SPIOA_MSKR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_MSKR_OFFSET) +#define SAM_SPIOA_CFGR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_CFGR_OFFSET) +#define SAM_SPIOA_PDSR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_PDSR_OFFSET) +#define SAM_SPIOA_LOCKSR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_LOCKSR_OFFSET) +#define SAM_SPIOA_SODR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_SODR_OFFSET) +#define SAM_SPIOA_CODR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_CODR_OFFSET) +#define SAM_SPIOA_ODSR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_ODSR_OFFSET) +#define SAM_SPIOA_IER (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_IER_OFFSET) +#define SAM_SPIOA_IDR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_IDR_OFFSET) +#define SAM_SPIOA_IMR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_IMR_OFFSET) +#define SAM_SPIOA_ISR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_ISR_OFFSET) +#define SAM_SPIOA_SIONR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_SIONR_OFFSET) +#define SAM_SPIOA_SIOSR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_SIOSR_OFFSET) +#define SAM_SPIOA_IOSSR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_IOSSR_OFFSET) +#define SAM_SPIOA_IOFR (SAM_PIO_IOGROUPA_VBASE+SAM_SPIO_IOFR_OFFSET) + +#define SAM_SPIOB_MSKR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_MSKR_OFFSET) +#define SAM_SPIOB_CFGR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_CFGR_OFFSET) +#define SAM_SPIOB_PDSR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_PDSR_OFFSET) +#define SAM_SPIOB_LOCKSR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_LOCKSR_OFFSET) +#define SAM_SPIOB_SODR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_SODR_OFFSET) +#define SAM_SPIOB_CODR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_CODR_OFFSET) +#define SAM_SPIOB_ODSR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_ODSR_OFFSET) +#define SAM_SPIOB_IER (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_IER_OFFSET) +#define SAM_SPIOB_IDR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_IDR_OFFSET) +#define SAM_SPIOB_IMR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_IMR_OFFSET) +#define SAM_SPIOB_ISR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_ISR_OFFSET) +#define SAM_SPIOB_SIONR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_SIONR_OFFSET) +#define SAM_SPIOB_SIOSR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_SIOSR_OFFSET) +#define SAM_SPIOB_IOSSR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_IOSSR_OFFSET) +#define SAM_SPIOB_IOFR (SAM_PIO_IOGROUPB_VBASE+SAM_SPIO_IOFR_OFFSET) + +#define SAM_SPIOC_MSKR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_MSKR_OFFSET) +#define SAM_SPIOC_CFGR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_CFGR_OFFSET) +#define SAM_SPIOC_PDSR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_PDSR_OFFSET) +#define SAM_SPIOC_LOCKSR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_LOCKSR_OFFSET) +#define SAM_SPIOC_SODR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_SODR_OFFSET) +#define SAM_SPIOC_CODR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_CODR_OFFSET) +#define SAM_SPIOC_ODSR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_ODSR_OFFSET) +#define SAM_SPIOC_IER (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_IER_OFFSET) +#define SAM_SPIOC_IDR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_IDR_OFFSET) +#define SAM_SPIOC_IMR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_IMR_OFFSET) +#define SAM_SPIOC_ISR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_ISR_OFFSET) +#define SAM_SPIOC_SIONR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_SIONR_OFFSET) +#define SAM_SPIOC_SIOSR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_SIOSR_OFFSET) +#define SAM_SPIOC_IOSSR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_IOSSR_OFFSET) +#define SAM_SPIOC_IOFR (SAM_PIO_IOGROUPC_VBASE+SAM_SPIO_IOFR_OFFSET) + +#define SAM_SPIOD_MSKR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_MSKR_OFFSET) +#define SAM_SPIOD_CFGR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_CFGR_OFFSET) +#define SAM_SPIOD_PDSR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_PDSR_OFFSET) +#define SAM_SPIOD_LOCKSR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_LOCKSR_OFFSET) +#define SAM_SPIOD_SODR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_SODR_OFFSET) +#define SAM_SPIOD_CODR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_CODR_OFFSET) +#define SAM_SPIOD_ODSR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_ODSR_OFFSET) +#define SAM_SPIOD_IER (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_IER_OFFSET) +#define SAM_SPIOD_IDR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_IDR_OFFSET) +#define SAM_SPIOD_IMR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_IMR_OFFSET) +#define SAM_SPIOD_ISR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_ISR_OFFSET) +#define SAM_SPIOD_SIONR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_SIONR_OFFSET) +#define SAM_SPIOD_SIOSR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_SIOSR_OFFSET) +#define SAM_SPIOD_IOSSR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_IOSSR_OFFSET) +#define SAM_SPIOD_IOFR (SAM_PIO_IOGROUPD_VBASE+SAM_SPIO_IOFR_OFFSET) + +#define SAM_SPIO_SCDR (SAM_PIO_VBASE+SAM_SPIO_SCDR_OFFSET) +#define SAM_SPIO_WPMR (SAM_PIO_VBASE+SAM_SPIO_WPMR_OFFSET) +#define SAM_SPIO_WPSR (SAM_PIO_VBASE+SAM_SPIO_WPSR_OFFSET) + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for many IO registers (exceptions follow) */ + +#define PIO(n) (1 << (n)) /* Bit n: PIO n, n=0-31 */ + +/* PIO Configuration Register and Secure PIO Configuration Register */ + +#define PIO_CFGR_FUNC_SHIFT (0) /* Bits 0-2: I/O Line Function */ +#define PIO_CFGR_FUNC_MASK (7 << PIO_CFGR_FUNC_SHIFT) +# define PIO_CFGR_FUNC_GPIO (0 << PIO_CFGR_FUNC_SHIFT) /* Select PIO mode */ +# define PIO_CFGR_FUNC_PERIPH(n) ((uint32_t)(n) << PIO_CFGR_FUNC_SHIFT) +# define PIO_CFGR_FUNC_PERIPHA (1 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral A */ +# define PIO_CFGR_FUNC_PERIPHB (2 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral B */ +# define PIO_CFGR_FUNC_PERIPHC (3 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral C */ +# define PIO_CFGR_FUNC_PERIPHD (4 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral D */ +# define PIO_CFGR_FUNC_PERIPHE (5 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral E */ +# define PIO_CFGR_FUNC_PERIPHF (6 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral F */ +# define PIO_CFGR_FUNC_PERIPHG (7 << PIO_CFGR_FUNC_SHIFT) /* Select peripheral G */ +#define PIO_CFGR_DIR (1 << 8) /* Bit 8: Direction */ +# define PIO_CFGR_DIR_INPUT (0) /* 0=Input */ +# define PIO_CFGR_DIR_OUTPUT (1 << 8) /* 1=Output */ +#define PIO_CFGR_PUEN (1 << 9) /* Bit 9: Pull-Up Enable */ +#define PIO_CFGR_PDEN (1 << 10) /* Bit 10: Pull-Down Enable */ +#define PIO_CFGR_IFEN (1 << 12) /* Bit 12: Input Filter Enable */ +#define PIO_CFGR_IFSCEN (1 << 13) /* Bit 13: Input Filter Slow Clock Enable */ +#define PIO_CFGR_OPD (1 << 14) /* Bit 14: Open-Drain */ +#define PIO_CFGR_SCHMITT (1 << 15) /* Bit 15: Schmitt Trigger */ +#define PIO_CFGR_DRVSTR_SHIFT (16) /* Bits 16-17: Drive Strength */ +#define PIO_CFGR_DRVSTR_MASK (3 << PIO_CFGR_DRVSTR_SHIFT) +# define PIO_CFGR_DRVSTR_LOW (0 << PIO_CFGR_DRVSTR_SHIFT) /* Low drive */ +# define PIO_CFGR_DRVSTR_MED (2 << PIO_CFGR_DRVSTR_SHIFT) /* Medium drive */ +# define PIO_CFGR_DRVSTR_HIGH (3 << PIO_CFGR_DRVSTR_SHIFT) /* High drive */ +#define PIO_CFGR_EVTSEL_SHIFT (24) /* Bits 24-26: Event Selection */ +#define PIO_CFGR_EVTSEL_MASK (7 << PIO_CFGR_EVTSEL_SHIFT) +# define PIO_CFGR_EVTSEL_FALLING (0 << PIO_CFGR_EVTSEL_SHIFT) /* Event detection on input falling edge */ +# define PIO_CFGR_EVTSEL_RISING (1 << PIO_CFGR_EVTSEL_SHIFT) /* Event detection on input rising edge */ +# define PIO_CFGR_EVTSEL_BOTH (2 << PIO_CFGR_EVTSEL_SHIFT) /* Event detection on input both edge */ +# define PIO_CFGR_EVTSEL_LOW (3 << PIO_CFGR_EVTSEL_SHIFT) /* Event detection on low level input */ +# define PIO_CFGR_EVTSEL_HIGH (4 << PIO_CFGR_EVTSEL_SHIFT) /* Event detection on high level input */ +#define PIO_CFGR_PCFS (1 << 29) /* Bit 29: Physical Configuration Freeze Status */ +#define PIO_CFGR_ICFS (1 << 30) /* Bit 30: Interrupt Configuration Freeze Status */ + +/* PIO I/O Freeze Register and Secure PIO I/O Freeze Register */ + +#define PIO_IOFR_FPHY (1 << 0) /* Bit 0: Freeze Physical Configuration */ +#define PIO_IOFR_FINT (1 << 1) /* Bit 1: Freeze Interrupt Configuration */ +#define PIO_IOFR_FRZKEY_SHIFT (8) /* Bits 8-31: Freeze Key */ +#define PIO_IOFR_FRZKEY_MASK (0x00ffffff << PIO_IOFR_FRZKEY_SHIFT) +# define PIO_IOFR_FRZKEY (0x00494F46 << PIO_IOFR_FRZKEY_SHIFT) /* ""IOF" */ + +/* PIO Write Protection Mode Register and Secure PIO Write Protection Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define PIO_WPMR_WPITEN (1 << 1) /* Bit 1: Write Protection Interrupt Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection Key */ +#define PIO_WPMR_WPKEY_MASK (0x00ffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x0050494f << PIO_WPMR_WPKEY_SHIFT) /* "PIO" */ + +/* PIO Write Protection Status Register and Secure PIO Write Protection Status Register*/ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/* Secure PIO Slow Clock Divider Debouncing Register */ + +#define SPIO_SCDR_DIV_SHIFT (0) /* Bits 0-13: Slow Clock Divider Selection for Debouncing */ +#define SPIO_SCDR_DIV_MASK (0x3fff << SPIO_SCDR_DIV_SHIFT) +# define SPIO_SCDR_DIV(n) ((uint32_t)(n) << SPIO_SCDR_DIV_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D2X_PIO_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d3x4x_pio.h b/arch/arm/src/sama5/chip/_sama5d3x4x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..0516d6981ed62ebd14ae55ca0c70a36b2b99c849 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d3x4x_pio.h @@ -0,0 +1,648 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/_sama5d3x4x_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAMA5D3x and SAMA5D4x + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3DX4X_PIO_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3DX4X_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* Misc Helper Definitions **************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define PIOD (3) +#define PIOE (4) + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */ +#define SAM_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */ +#define SAM_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */ + +#ifdef ATSAMA5D4 +# define SAM_PIO_ISLR_OFFSET 0x000c /* PIO Interrupt Security Level Register */ +#endif + +#define SAM_PIO_OER_OFFSET 0x0010 /* Output Enable Register */ +#define SAM_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */ +#define SAM_PIO_OSR_OFFSET 0x0018 /* Output Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */ +#define SAM_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */ +#define SAM_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */ + /* 0x002c: Reserved */ +#define SAM_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */ +#define SAM_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */ +#define SAM_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define SAM_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */ +#define SAM_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */ +#define SAM_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */ + /* 0x005c: Reserved */ +#define SAM_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */ +#define SAM_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */ +#define SAM_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */ + /* 0x006c: Reserved */ +#define SAM_PIO_ABCDSR1_OFFSET 0x0070 /* Peripheral Select Register 1 */ +#define SAM_PIO_ABCDSR2_OFFSET 0x0074 /* Peripheral Select Register 2 */ + /* 0x0078-0x007c: Reserved */ +#define SAM_PIO_IFSCDR_OFFSET 0x0080 /* Input Filter Slow Clock Disable Register */ +#define SAM_PIO_IFSCER_OFFSET 0x0084 /* Input Filter Slow Clock Enable Register */ +#define SAM_PIO_IFSCSR_OFFSET 0x0088 /* Input Filter Slow Clock Status Register */ +#define SAM_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */ +#define SAM_PIO_PPDDR_OFFSET 0x0090 /* Pad Pull Down Disable Register */ +#define SAM_PIO_PPDER_OFFSET 0x0094 /* PIO Pad Pull Down Enable Register */ +#define SAM_PIO_PPDSR_OFFSET 0x0098 /* PIO Pad Pull Down Status Register */ + /* 0x009c: Reserved */ +#define SAM_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */ +#define SAM_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */ +#define SAM_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */ + /* 0x00ac: Reserved */ +#define SAM_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */ +#define SAM_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */ +#define SAM_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */ + /* 0x00bc: Reserved */ +#define SAM_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */ +#define SAM_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */ +#define SAM_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */ + /* 0x00cc: Reserved */ +#define SAM_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */ +#define SAM_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */ +#define SAM_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */ + /* 0x00dc: Reserved */ +#ifdef ATSAMA5D3 +# define SAM_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */ +#endif + +#define SAM_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8: Reserved */ +#define SAM_PIO_SCHMITT_OFFSET 0x0100 /* Schmitt Trigger Register */ + /* 0x0104-0x114: Reserved */ +#define SAM_PIO_DRIVER1_OFFSET 0x0118 /* I/O Drive Register 1 */ +#define SAM_PIO_DRIVER2_OFFSET 0x011c /* I/O Drive Register 2 */ + /* 0x0120-0x14c: Reserved */ + +/* PIO register addresses ***************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define NPIO (3) + +#define SAM_PIO_PER(n) (SAM_PIO_VBASE(n)+SAM_PIO_PER_OFFSET) +#define SAM_PIO_PDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PDR_OFFSET) +#define SAM_PIO_PSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIO_ISLR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIO_OER(n) (SAM_PIO_VBASE(n)+SAM_PIO_OER_OFFSET) +#define SAM_PIO_ODR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ODR_OFFSET) +#define SAM_PIO_OSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_OSR_OFFSET) +#define SAM_PIO_IFER(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFER_OFFSET) +#define SAM_PIO_IFDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFDR_OFFSET) +#define SAM_PIO_IFSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFSR_OFFSET) +#define SAM_PIO_SODR(n) (SAM_PIO_VBASE(n)+SAM_PIO_SODR_OFFSET) +#define SAM_PIO_CODR(n) (SAM_PIO_VBASE(n)+SAM_PIO_CODR_OFFSET) +#define SAM_PIO_ODSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ODSR_OFFSET) +#define SAM_PIO_PDSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PDSR_OFFSET) +#define SAM_PIO_IER(n) (SAM_PIO_VBASE(n)+SAM_PIO_IER_OFFSET) +#define SAM_PIO_IDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IDR_OFFSET) +#define SAM_PIO_IMR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IMR_OFFSET) +#define SAM_PIO_ISR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ISR_OFFSET) +#define SAM_PIO_MDER(n) (SAM_PIO_VBASE(n)+SAM_PIO_MDER_OFFSET) +#define SAM_PIO_MDDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_MDDR_OFFSET) +#define SAM_PIO_MDSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_MDSR_OFFSET) +#define SAM_PIO_PUDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PUDR_OFFSET) +#define SAM_PIO_PUER(n) (SAM_PIO_VBASE(n)+SAM_PIO_PUER_OFFSET) +#define SAM_PIO_PUSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PUSR_OFFSET) +#define SAM_PIO_ABCDSR1(n) (SAM_PIO_VBASE(n)+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIO_ABCDSR2(n) (SAM_PIO_VBASE(n)+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIO_IFSCDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIO_IFSCER(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIO_IFSCSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIO_SCDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_SCDR_OFFSET) +#define SAM_PIO_PPDDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIO_PPDER(n) (SAM_PIO_VBASE(n)+SAM_PIO_PPDER_OFFSET) +#define SAM_PIO_PPDSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIO_OWER(n) (SAM_PIO_VBASE(n)+SAM_PIO_OWER_OFFSET) +#define SAM_PIO_OWDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_OWDR_OFFSET) +#define SAM_PIO_OWSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_OWSR_OFFSET) +#define SAM_PIO_AIMER(n) (SAM_PIO_VBASE(n)+SAM_PIO_AIMER_OFFSET) +#define SAM_PIO_AIMDR(n) (SAM_PIO_VBASE(n)+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIO_AIMMR(n) (SAM_PIO_VBASE(n)+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIO_ESR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ESR_OFFSET) +#define SAM_PIO_LSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_LSR_OFFSET) +#define SAM_PIO_ELSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_ELSR_OFFSET) +#define SAM_PIO_FELLSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIO_REHLSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIO_FRLHSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIO_LOCKSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIO_WPMR(n) (SAM_PIO_VBASE(n)+SAM_PIO_WPMR_OFFSET) +#define SAM_PIO_WPSR(n) (SAM_PIO_VBASE(n)+SAM_PIO_WPSR_OFFSET) +#define SAM_PIO_SCHMITT(n) (SAM_PIO_VBASE(n)+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIO_DRIVER1(n) (SAM_PIO_VBASE(n)+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIO_DRIVER2(n) (SAM_PIO_VBASE(n)+SAM_PIO_DRIVER2_OFFSET) + +#define SAM_PIOA_PER (SAM_PIOA_VBASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOA_PDR (SAM_PIOA_VBASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOA_PSR (SAM_PIOA_VBASE+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIOA_ISLR (SAM_PIOA_VBASE+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIOA_OER (SAM_PIOA_VBASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOA_ODR (SAM_PIOA_VBASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOA_OSR (SAM_PIOA_VBASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOA_IFER (SAM_PIOA_VBASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOA_IFDR (SAM_PIOA_VBASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOA_IFSR (SAM_PIOA_VBASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIOA_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIOA_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIOA_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIOA_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIOA_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIOA_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIOA_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIOA_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_MDER (SAM_PIOA_VBASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOA_MDDR (SAM_PIOA_VBASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOA_MDSR (SAM_PIOA_VBASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOA_PUDR (SAM_PIOA_VBASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOA_PUER (SAM_PIOA_VBASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOA_PUSR (SAM_PIOA_VBASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOA_ABCDSR1 (SAM_PIOA_VBASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOA_ABCDSR2 (SAM_PIOA_VBASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOA_IFSCDR (SAM_PIOA_VBASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOA_IFSCER (SAM_PIOA_VBASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOA_IFSCSR (SAM_PIOA_VBASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOA_SCDR (SAM_PIOA_VBASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOA_PPDDR (SAM_PIOA_VBASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOA_PPDER (SAM_PIOA_VBASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOA_PPDSR (SAM_PIOA_VBASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOA_OWER (SAM_PIOA_VBASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOA_OWDR (SAM_PIOA_VBASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOA_OWSR (SAM_PIOA_VBASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOA_AIMER (SAM_PIOA_VBASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOA_AIMDR (SAM_PIOA_VBASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOA_AIMMR (SAM_PIOA_VBASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOA_ESR (SAM_PIOA_VBASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOA_LSR (SAM_PIOA_VBASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOA_ELSR (SAM_PIOA_VBASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOA_FELLSR (SAM_PIOA_VBASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOA_REHLSR (SAM_PIOA_VBASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOA_FRLHSR (SAM_PIOA_VBASE+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIOA_LOCKSR (SAM_PIOA_VBASE+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIOA_WPMR (SAM_PIOA_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOA_WPSR (SAM_PIOA_VBASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOA_SCHMITT (SAM_PIOA_VBASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOA_DRIVER1 (SAM_PIOA_VBASE+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIOA_DRIVER2 (SAM_PIOA_VBASE+SAM_PIO_DRIVER2_OFFSET) + +#define SAM_PIOB_PER (SAM_PIOB_VBASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOB_PDR (SAM_PIOB_VBASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOB_PSR (SAM_PIOB_VBASE+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIOB_ISLR (SAM_PIOB_VBASE+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIOB_OER (SAM_PIOB_VBASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOB_ODR (SAM_PIOB_VBASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOB_OSR (SAM_PIOB_VBASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOB_IFER (SAM_PIOB_VBASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOB_IFDR (SAM_PIOB_VBASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOB_IFSR (SAM_PIOB_VBASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOB_SODR (SAM_PIOB_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOB_CODR (SAM_PIOB_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOB_ODSR (SAM_PIOB_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOB_PDSR (SAM_PIOB_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOB_IER (SAM_PIOB_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOB_IDR (SAM_PIOB_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOB_IMR (SAM_PIOB_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOB_ISR (SAM_PIOB_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOB_MDER (SAM_PIOB_VBASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOB_MDDR (SAM_PIOB_VBASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOB_MDSR (SAM_PIOB_VBASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOB_PUDR (SAM_PIOB_VBASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOB_PUER (SAM_PIOB_VBASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOB_PUSR (SAM_PIOB_VBASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOB_ABCDSR1 (SAM_PIOB_VBASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOB_ABCDSR2 (SAM_PIOB_VBASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOB_IFSCDR (SAM_PIOB_VBASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOB_IFSCER (SAM_PIOB_VBASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOB_IFSCSR (SAM_PIOB_VBASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOB_SCDR (SAM_PIOB_VBASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOB_PPDDR (SAM_PIOB_VBASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOB_PPDER (SAM_PIOB_VBASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOB_PPDSR (SAM_PIOB_VBASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOB_OWER (SAM_PIOB_VBASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOB_OWDR (SAM_PIOB_VBASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOB_OWSR (SAM_PIOB_VBASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOB_AIMER (SAM_PIOB_VBASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOB_AIMDR (SAM_PIOB_VBASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOB_AIMMR (SAM_PIOB_VBASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOB_ESR (SAM_PIOB_VBASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOB_LSR (SAM_PIOB_VBASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOB_ELSR (SAM_PIOB_VBASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOB_FELLSR (SAM_PIOB_VBASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOB_REHLSR (SAM_PIOB_VBASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOB_FRLHSR (SAM_PIOB_VBASE+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIOB_LOCKSR (SAM_PIOB_VBASE+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIOB_WPMR (SAM_PIOB_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOB_WPSR (SAM_PIOB_VBASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOB_SCHMITT (SAM_PIOB_VBASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOB_DRIVER1 (SAM_PIOB_VBASE+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIOB_DRIVER2 (SAM_PIOB_VBASE+SAM_PIO_DRIVER2_OFFSET) + +#define SAM_PIOC_PER (SAM_PIOC_VBASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOC_PDR (SAM_PIOC_VBASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOC_PSR (SAM_PIOC_VBASE+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIOC_ISLR (SAM_PIOC_VBASE+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIOC_OER (SAM_PIOC_VBASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOC_ODR (SAM_PIOC_VBASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOC_OSR (SAM_PIOC_VBASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOC_IFER (SAM_PIOC_VBASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOC_IFDR (SAM_PIOC_VBASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOC_IFSR (SAM_PIOC_VBASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOC_SODR (SAM_PIOC_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOC_CODR (SAM_PIOC_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOC_ODSR (SAM_PIOC_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOC_PDSR (SAM_PIOC_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOC_IER (SAM_PIOC_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOC_IDR (SAM_PIOC_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOC_IMR (SAM_PIOC_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOC_ISR (SAM_PIOC_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOC_MDER (SAM_PIOC_VBASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOC_MDDR (SAM_PIOC_VBASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOC_MDSR (SAM_PIOC_VBASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOC_PUDR (SAM_PIOC_VBASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOC_PUER (SAM_PIOC_VBASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOC_PUSR (SAM_PIOC_VBASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOC_ABCDSR1 (SAM_PIOC_VBASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOC_ABCDSR2 (SAM_PIOC_VBASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOC_IFSCDR (SAM_PIOC_VBASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOC_IFSCER (SAM_PIOC_VBASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOC_IFSCSR (SAM_PIOC_VBASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOC_SCDR (SAM_PIOC_VBASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOC_PPDDR (SAM_PIOC_VBASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOC_PPDER (SAM_PIOC_VBASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOC_PPDSR (SAM_PIOC_VBASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOC_OWER (SAM_PIOC_VBASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOC_OWDR (SAM_PIOC_VBASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOC_OWSR (SAM_PIOC_VBASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOC_AIMER (SAM_PIOC_VBASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOC_AIMDR (SAM_PIOC_VBASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOC_AIMMR (SAM_PIOC_VBASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOC_ESR (SAM_PIOC_VBASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOC_LSR (SAM_PIOC_VBASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOC_ELSR (SAM_PIOC_VBASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOC_FELLSR (SAM_PIOC_VBASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOC_REHLSR (SAM_PIOC_VBASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOC_FRLHSR (SAM_PIOC_VBASE+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIOC_LOCKSR (SAM_PIOC_VBASE+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIOC_WPMR (SAM_PIOC_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOC_WPSR (SAM_PIOC_VBASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOC_SCHMITT (SAM_PIOC_VBASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOC_DRIVER1 (SAM_PIOC_VBASE+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIOC_DRIVER2 (SAM_PIOC_VBASE+SAM_PIO_DRIVER2_OFFSET) + +#define SAM_PIOD_PER (SAM_PIOD_VBASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOD_PDR (SAM_PIOD_VBASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOD_PSR (SAM_PIOD_VBASE+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIOD_ISLR (SAM_PIOD_VBASE+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIOD_OER (SAM_PIOD_VBASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOD_ODR (SAM_PIOD_VBASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOD_OSR (SAM_PIOD_VBASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOD_IFER (SAM_PIOD_VBASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOD_IFDR (SAM_PIOD_VBASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOD_IFSR (SAM_PIOD_VBASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOD_SODR (SAM_PIOD_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOD_CODR (SAM_PIOD_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOD_ODSR (SAM_PIOD_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOD_PDSR (SAM_PIOD_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOD_IER (SAM_PIOD_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOD_IDR (SAM_PIOD_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOD_IMR (SAM_PIOD_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOD_ISR (SAM_PIOD_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOD_MDER (SAM_PIOD_VBASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOD_MDDR (SAM_PIOD_VBASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOD_MDSR (SAM_PIOD_VBASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOD_PUDR (SAM_PIOD_VBASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOD_PUER (SAM_PIOD_VBASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOD_PUSR (SAM_PIOD_VBASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOD_ABCDSR1 (SAM_PIOD_VBASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOD_ABCDSR2 (SAM_PIOD_VBASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOD_IFSCDR (SAM_PIOD_VBASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOD_IFSCER (SAM_PIOD_VBASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOD_IFSCSR (SAM_PIOD_VBASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOD_SCDR (SAM_PIOD_VBASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOD_PPDDR (SAM_PIOD_VBASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOD_PPDER (SAM_PIOD_VBASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOD_PPDSR (SAM_PIOD_VBASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOD_OWER (SAM_PIOD_VBASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOD_OWDR (SAM_PIOD_VBASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOD_OWSR (SAM_PIOD_VBASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOD_AIMER (SAM_PIOD_VBASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOD_AIMDR (SAM_PIOD_VBASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOD_AIMMR (SAM_PIOD_VBASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOD_ESR (SAM_PIOD_VBASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOD_LSR (SAM_PIOD_VBASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOD_ELSR (SAM_PIOD_VBASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOD_FELLSR (SAM_PIOD_VBASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOD_REHLSR (SAM_PIOD_VBASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOD_FRLHSR (SAM_PIOD_VBASE+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIOD_LOCKSR (SAM_PIOD_VBASE+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIOD_WPMR (SAM_PIOD_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOD_WPSR (SAM_PIOD_VBASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOD_SCHMITT (SAM_PIOD_VBASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOD_DRIVER1 (SAM_PIOD_VBASE+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIOD_DRIVER2 (SAM_PIOD_VBASE+SAM_PIO_DRIVER2_OFFSET) + +#define SAM_PIOE_PER (SAM_PIOE_VBASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOE_PDR (SAM_PIOE_VBASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOE_PSR (SAM_PIOE_VBASE+SAM_PIO_PSR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PIOE_ISLR (SAM_PIOE_VBASE+SAM_PIO_ISLR_OFFSET) +#endif + +#define SAM_PIOE_OER (SAM_PIOE_VBASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOE_ODR (SAM_PIOE_VBASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOE_OSR (SAM_PIOE_VBASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOE_IFER (SAM_PIOE_VBASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOE_IFDR (SAM_PIOE_VBASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOE_IFSR (SAM_PIOE_VBASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOE_SODR (SAM_PIOE_VBASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOE_CODR (SAM_PIOE_VBASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOE_ODSR (SAM_PIOE_VBASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOE_PDSR (SAM_PIOE_VBASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOE_IER (SAM_PIOE_VBASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOE_IDR (SAM_PIOE_VBASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOE_IMR (SAM_PIOE_VBASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOE_ISR (SAM_PIOE_VBASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOE_MDER (SAM_PIOE_VBASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOE_MDDR (SAM_PIOE_VBASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOE_MDSR (SAM_PIOE_VBASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOE_PUDR (SAM_PIOE_VBASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOE_PUER (SAM_PIOE_VBASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOE_PUSR (SAM_PIOE_VBASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOE_ABCDSR1 (SAM_PIOE_VBASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOE_ABCDSR2 (SAM_PIOE_VBASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOE_IFSCDR (SAM_PIOE_VBASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOE_IFSCER (SAM_PIOE_VBASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOE_IFSCSR (SAM_PIOE_VBASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOE_SCDR (SAM_PIOE_VBASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOE_PPDDR (SAM_PIOE_VBASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOE_PPDER (SAM_PIOE_VBASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOE_PPDSR (SAM_PIOE_VBASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOE_OWER (SAM_PIOE_VBASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOE_OWDR (SAM_PIOE_VBASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOE_OWSR (SAM_PIOE_VBASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOE_AIMER (SAM_PIOE_VBASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOE_AIMDR (SAM_PIOE_VBASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOE_AIMMR (SAM_PIOE_VBASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOE_ESR (SAM_PIOE_VBASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOE_LSR (SAM_PIOE_VBASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOE_ELSR (SAM_PIOE_VBASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOE_FELLSR (SAM_PIOE_VBASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOE_REHLSR (SAM_PIOE_VBASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOE_FRLHSR (SAM_PIOE_VBASE+SAM_PIO_FRLHSR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_PIOE_LOCKSR (SAM_PIOE_VBASE+SAM_PIO_LOCKSR_OFFSET) +#endif + +#define SAM_PIOE_WPMR (SAM_PIOE_VBASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOE_WPSR (SAM_PIOE_VBASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOE_SCHMITT (SAM_PIOE_VBASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOE_DRIVER1 (SAM_PIOE_VBASE+SAM_PIO_DRIVER1_OFFSET) +#define SAM_PIOE_DRIVER2 (SAM_PIOE_VBASE+SAM_PIO_DRIVER2_OFFSET) + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for ALMOST all IO registers (exceptions follow) */ + +#define PIO(n) (1 << (n)) /* Bit n: PIO n */ + +/* PIO Slow Clock Divider Debouncing Register */ + +#define PIO_SCDR_MASK (0x3fff) /* Bit 0-13: Slow Clock Divider Selection for Debouncing */ + +/* PIO Write Protect Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PIO_WPMR_WPKEY_MASK (0x00ffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x0050494f << PIO_WPMR_WPKEY_SHIFT) + +/* PIO Write Protect Status Register */ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/* I/O Drive Register 1 */ + +#define PIO_LO_DRIVE (0) /* Low drive */ +#define PIO_ME_DRIVE (2) /* Medium drive */ +#define PIO_HI_DRIVE (3) /* High drive */ + +#define PIO_DRIVER1_LINE_SHIFT(n) ((n) << 1) +#define PIO_DRIVER1_LINE_MASK(n) (3 << PIO_DRIVER1_LINE_SHIFT(n)) +# define PIO_DRIVER1_LINE(n,d) ((d) << PIO_DRIVER1_LINE_SHIFT(n)) +#define PIO_DRIVER1_LINE0_SHIFT (0) /* Bit 0-1: Line 0 drive */ +#define PIO_DRIVER1_LINE0_MASK (3 < + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + +/* Overview: + * + * SAMA5 Physical (unmapped) Memory Map + * - SAMA5 Internal Memories + * - SAMA5 Internal Peripheral Offsets + * - System Controller Peripheral Offsets + * Sizes of memory regions in bytes + * Sizes of memory regions in sections + * Section MMU Flags + * SAMA5 Virtual (mapped) Memory Map + * - Peripheral virtual base addresses + * - NuttX vitual base address + * MMU Page Table Location + * Page table start addresses + * Base address of the interrupt vector table + */ + +/* SAMA5 Physical (unmapped) Memory Map */ + +#define SAM_INTMEM_PSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_EBICS0_PSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip select 0 */ +#define SAM_DDRCS_PSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDRCS */ +#define SAM_EBICS1_PSECTION 0x40000000 /* 0x40000000-0x4fffffff: EBI Chip select 1 */ +#define SAM_EBICS2_PSECTION 0x50000000 /* 0x50000000-0x5fffffff: EBI Chip select 2 */ +#define SAM_EBICS3_PSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip select 2 */ +#define SAM_NFCCR_PSECTION 0x70000000 /* 0x70000000-0x7fffffff: NFC Command Registers */ + /* 0x80000000-0xefffffff: Undefined */ +#define SAM_PERIPH_PSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ + +/* SAMA5 Internal Memories */ + +#define SAM_BOOTMEM_PSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ +#define SAM_ROM_PSECTION 0x00100000 /* 0x00100000-0x001fffff: ROM */ +#define SAM_NFCSRAM_PSECTION 0x00200000 /* 0x00200000-0x002fffff: NFC SRAM */ +#define SAM_ISRAM_PSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM */ +# define SAM_ISRAM0_PADDR 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ +# define SAM_ISRAM1_PADDR 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ +#define SAM_SMD_PSECTION 0x00400000 /* 0x00400000-0x004fffff: SMD */ +#define SAM_UDPHSRAM_PSECTION 0x00500000 /* 0x00500000-0x005fffff: UDPH SRAM */ +#define SAM_UHPOHCI_PSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP OHCI */ +#define SAM_UHPEHCI_PSECTION 0x00700000 /* 0x00700000-0x007fffff: UHP EHCI */ +#define SAM_AXIMX_PSECTION 0x00800000 /* 0x00800000-0x008fffff: AXI Matr */ +#define SAM_DAP_PSECTION 0x00900000 /* 0x00900000-0x009fffff: DAP */ + /* 0x00a00000-0x0fffffff: Undefined */ +/* SAMA5 Internal Peripheral Offsets */ + +#define SAM_PERIPHA_PSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_HSMCI0_OFFSET 0x00000000 /* 0x00000000-0x00003fff: HSMCI0 */ +# define SAM_SPI0_OFFSET 0x00004000 /* 0x00004000-0x00007fff: SPI0 */ +# define SAM_SSC0_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: SSC0 */ +# define SAM_CAN0_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: CAN0 */ +# define SAM_TC012_OFFSET 0x00010000 /* 0x00010000-0x00013fff: TC channels 0, 1, and 2 */ +# define SAM_TWI0_OFFSET 0x00014000 /* 0x00014000-0x00017fff: TWI0 */ +# define SAM_TWI1_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: TWI1 */ +# define SAM_USART0_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: USART0 */ +# define SAM_USART1_OFFSET 0x00020000 /* 0x00020000-0x00023fff: USART1 */ +# define SAM_UART0_OFFSET 0x00024000 /* 0x00024000-0x00027fff: UART0 */ +# define SAM_GMAC_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: GMAC */ +# define SAM_PWMC_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: PWMC */ +# define SAM_LCDC_OFFSET 0x00030000 /* 0x00030000-0x00033fff: LCDC */ +# define SAM_ISI_OFFSET 0x00034000 /* 0x00034000-0x00037fff: ISI */ +# define SAM_SFR_OFFSET 0x00038000 /* 0x00038000-0x0003bfff: SFR */ + /* 0x0003c000-0x07ffffff: Reserved */ + +#define SAM_PERIPHB_PSECTION 0xf8000000 /* 0xf8000000-0xffffbfff: Internal Peripherals B */ +# define SAM_HSMCI1_OFFSET 0x00000000 /* 0x00000000-0x00000fff: HSMCI1 */ +# define SAM_HSMCI2_OFFSET 0x00004000 /* 0x00004000-0x00007fff: HSMCI2 */ +# define SAM_SPI1_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: SPI1 */ +# define SAM_SSC1_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: SSC1 */ +# define SAM_CAN1_OFFSET 0x00010000 /* 0x00010000-0x00013fff: CAN1 */ +# define SAM_TC345_OFFSET 0x00014000 /* 0x00014000-0x00017fff: TC channels 3, 4, and 5 */ +# define SAM_TSADC_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: TSADC */ +# define SAM_TWI2_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: TWI2 */ +# define SAM_USART2_OFFSET 0x00020000 /* 0x00020000-0x00023fff: USART2 */ +# define SAM_USART3_OFFSET 0x00024000 /* 0x00024000-0x00027fff: USART3 */ +# define SAM_UART1_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: UART1 */ +# define SAM_EMAC_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: EMAC */ +# define SAM_UDPHS_OFFSET 0x00030000 /* 0x00030000-0x00033fff: UDPHS */ +# define SAM_SHA_OFFSET 0x00034000 /* 0x00034000-0x00037fff: SHA */ +# define SAM_AES_OFFSET 0x00038000 /* 0x00038000-0x0003bfff: AES */ +# define SAM_TDES_OFFSET 0x0003c000 /* 0x0003c000-0x0003ffff: TDES */ +# define SAM_TRNG_OFFSET 0x00040000 /* 0x00040000-0x00043fff: TRNG */ + /* 0x00044000-0x00ffbfff: Reserved */ +#define SAM_SYSC_PSECTION 0xfff00000 /* 0xfff00000-0xffffffff: System Controller */ +#define SAM_SYSC_PADDR 0xffffc000 /* 0xffffc000-0xffffffff: System Controller */ +# define SAM_SYSC_OFFSET 0x00000000 /* 0x0fffc000-0x0fffffff: System Controller */ + +/* System Controller Peripheral Offsets. All relative to the beginning of the + * 16KB virtual or physical SYSC region (SAM_SYSC_VADDR or SAM_SYSC_PADDR). + */ + +#define SAM_HSMC_OFFSET 0x00000000 /* 0x00000000-0x00000fff: HSMC */ + /* 0x00001000-0x000023ff: Reserved */ +#define SAM_FUSE_OFFSET 0x00002400 /* 0x00002400-0x000025ff: FUSE */ +#define SAM_DMAC0_OFFSET 0x00002600 /* 0x00002600-0x000027ff: DMAC0 */ +#define SAM_DMAC1_OFFSET 0x00002800 /* 0x00002800-0x000029ff: DMAC1 */ +#define SAM_MPDDRC_OFFSET 0x00002a00 /* 0x00002a00-0x00002bff: MPDDRC */ +#define SAM_MATRIX_OFFSET 0x00002c00 /* 0x00002c00-0x00002dff: MATRIX */ +#define SAM_DBGU_OFFSET 0x00002e00 /* 0x00002e00-0x00002fff: DBGU */ +#define SAM_AIC_OFFSET 0x00003000 /* 0x00003000-0x000031ff: AIC */ +#define SAM_PION_OFFSET(n) (0x00003200+((n) << 9)) +#define SAM_PIOA_OFFSET 0x00003200 /* 0x00003200-0x000033ff: PIOA */ +#define SAM_PIOB_OFFSET 0x00003400 /* 0x00003400-0x000035ff: PIOB */ +#define SAM_PIOC_OFFSET 0x00003600 /* 0x00003600-0x000037ff: PIOC */ +#define SAM_PIOD_OFFSET 0x00003800 /* 0x00003800-0x000039ff: PIOD */ +#define SAM_PIOE_OFFSET 0x00003a00 /* 0x00003a00-0x00003bff: PIOE */ +#define SAM_PMC_OFFSET 0x00003c00 /* 0x00003c00-0x00003dff: PMC */ +#define SAM_RSTC_OFFSET 0x00003e00 /* 0x00003e00-0x00003e0f: RSTC */ +#define SAM_SHDC_OFFSET 0x00003e10 /* 0x00003e10-0x00003e1f: SHDC */ + /* 0x00003e20-0x00003e2f: Reserved */ +#define SAM_PITC_OFFSET 0x00003e30 /* 0x00003e30-0x00003e3f: PITC */ +#define SAM_WDT_OFFSET 0x00003e40 /* 0x00003e40-0x00003e4f: WDT */ +#define SAM_SCKCR_OFFSET 0x00003e50 /* 0x00003e50-0x00003e53: SCKCR */ +#define SAM_BSC_OFFSET 0x00003e54 /* 0x00003e54-0x00003e5f: BSC */ +#define SAM_GPBR_OFFSET 0x00003e60 /* 0x00003e60-0x00003e6f: GPBR */ + /* 0x00003e70-0x00003eaf: Reserved */ +#define SAM_RTCC_OFFSET 0x00003eb0 /* 0x00003eb0-0x00003edf: RTCC */ + /* 0x00003ee0-0x00003fff: Reserved */ + +/* Sizes of memory regions in bytes. + * + * These sizes exclude the undefined addresses at the end of the memory + * region. The implemented sizes of the EBI CS0-3 and DDRCS regions + * are not known apriori and must be specified with configuration settings. + */ + /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_BOOTMEM_SIZE (1*1024*1024) /* 0x00000000-0x000fffff: Boot memory */ +#define SAM_ROM_SIZE (1*1024*1024) /* 0x00100000-0x001fffff: ROM */ +#define SAM_NFCSRAM_SIZE (1*1024*1024) /* 0x00200000-0x002fffff: NFC SRAM */ + /* 0x00300000-0x003fffff: SRAM0 and SRAM1 */ +#define SAM_ISRAM_SIZE (64*1024 + SAM_ISRAM1_SIZE) +#define SAM_SMD_SIZE (1*1024*1024) /* 0x00400000-0x004fffff: SMD */ +#define SAM_UDPHSRAM_SIZE (1*1024*1024) /* 0x00500000-0x005fffff: UDPH SRAM */ +#define SAM_UHPOHCI_SIZE (1*1024*1024) /* 0x00600000-0x006fffff: UHP OHCI */ +#define SAM_UHPEHCI_SIZE (1*1024*1024) /* 0x00700000-0x007fffff: UHP EHCI */ +#define SAM_AXIMX_SIZE (4) /* 0x00800000-0x008fffff: AXI Matr */ +#define SAM_DAP_SIZE (1*1024*1024) /* 0x00900000-0x009fffff: DAP */ +#define SAM_NFCCR_SIZE (256*1024*1024) /* 0x70000000-0x7fffffff: NFC Command Registers */ + /* 0xf0000000-0xffffffff: Internal Peripherals */ +#define SAM_PERIPHA_SIZE (240*1024) /* 0xf0000000-0xf003bfff: Internal Peripherals */ +#define SAM_PERIPHB_SIZE (272*1024) /* 0xf8000000-0xf8043fff: Internal Peripherals */ +#define SAM_SYSC_SIZE (1*1024*1024) /* 0xfff00000-0x0ffffedf: Internal Peripherals */ + +/* Force configured sizes that might exceed 2GB to be unsigned long */ + +#define SAMA5_EBICS0_SIZE MKULONG(CONFIG_SAMA5_EBICS0_SIZE) +#define SAMA5_DDRCS_SIZE MKULONG(CONFIG_SAMA5_DDRCS_SIZE) +#define SAMA5_EBICS1_SIZE MKULONG(CONFIG_SAMA5_EBICS1_SIZE) +#define SAMA5_EBICS2_SIZE MKULONG(CONFIG_SAMA5_EBICS2_SIZE) +#define SAMA5_EBICS3_SIZE MKULONG(CONFIG_SAMA5_EBICS3_SIZE) + +#define SAMA5_EBICS0_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS0_HEAP_OFFSET) +#define SAMA5_DDRCS_HEAP_OFFSET MKULONG(CONFIG_SAMA5_DDRCS_HEAP_OFFSET) +#define SAMA5_EBICS1_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS1_HEAP_OFFSET) +#define SAMA5_EBICS2_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS2_HEAP_OFFSET) +#define SAMA5_EBICS3_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS3_HEAP_OFFSET) + +#define SAMA5_EBICS0_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS0_HEAP_SIZE) +#define SAMA5_DDRCS_HEAP_SIZE MKULONG(CONFIG_SAMA5_DDRCS_HEAP_SIZE) +#define SAMA5_EBICS1_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS1_HEAP_SIZE) +#define SAMA5_EBICS2_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS2_HEAP_SIZE) +#define SAMA5_EBICS3_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS3_HEAP_SIZE) + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of memory regions in sections. + * + * The boot logic in sam_boot.c, will select 1Mb level 1 MMU mappings to + * span the entire physical address space. The definitions below specify + * the number of 1Mb entries that are required to span a particular address + * region. + */ + +#define SAM_BOOTMEM_NSECTIONS _NSECTIONS(SAM_BOOTMEM_SIZE) +#define SAM_ROM_NSECTIONS _NSECTIONS(SAM_ROM_SIZE) +#define SAM_NFCSRAM_NSECTIONS _NSECTIONS(SAM_NFCSRAM_SIZE) +#define SAM_ISRAM_NSECTIONS _NSECTIONS(SAM_ISRAM_SIZE) +#define SAM_SMD_NSECTIONS _NSECTIONS(SAM_SMD_SIZE) +#define SAM_UDPHSRAM_NSECTIONS _NSECTIONS(SAM_UDPHSRAM_SIZE) +#define SAM_UHPOHCI_NSECTIONS _NSECTIONS(SAM_UHPOHCI_SIZE) +#define SAM_UHPEHCI_NSECTIONS _NSECTIONS(SAM_UHPEHCI_SIZE) +#define SAM_AXIMX_NSECTIONS _NSECTIONS(SAM_AXIMX_SIZE) +#define SAM_DAP_NSECTIONS _NSECTIONS(SAM_DAP_SIZE) + +#define SAM_EBICS0_NSECTIONS _NSECTIONS(SAMA5_EBICS0_SIZE) +#define SAM_DDRCS_NSECTIONS _NSECTIONS(SAMA5_DDRCS_SIZE) +#define SAM_EBICS1_NSECTIONS _NSECTIONS(SAMA5_EBICS1_SIZE) +#define SAM_EBICS2_NSECTIONS _NSECTIONS(SAMA5_EBICS2_SIZE) +#define SAM_EBICS3_NSECTIONS _NSECTIONS(SAMA5_EBICS3_SIZE) +#define SAM_NFCCR_NSECTIONS _NSECTIONS(SAM_NFCCR_SIZE) + +#define SAM_PERIPHA_NSECTIONS _NSECTIONS(SAM_PERIPHA_SIZE) +#define SAM_PERIPHB_NSECTIONS _NSECTIONS(SAM_PERIPHB_SIZE) +#define SAM_SYSC_NSECTIONS _NSECTIONS(SAM_SYSC_SIZE) + +/* Section MMU Flags */ + +#define SAM_BOOTMEM_MMUFLAGS MMU_ROMFLAGS +#define SAM_ROM_MMUFLAGS MMU_ROMFLAGS +#define SAM_ISRAM_MMUFLAGS MMU_MEMFLAGS +#define SAM_SMD_MMUFLAGS MMU_MEMFLAGS +#define SAM_UDPHSRAM_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPOHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPEHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_AXIMX_MMUFLAGS MMU_IOFLAGS +#define SAM_DAP_MMUFLAGS MMU_IOFLAGS + +/* If the NFC is not being used, the NFC SRAM can be used as general purpose + * SRAM (cached). If the NFC is used, then the NFC SRAM should be treated + * as an I/O devices (uncached). + */ + +#ifdef CONFIG_SAMA5_HAVE_NAND +# define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_NFCSRAM_MMUFLAGS MMU_MEMFLAGS +#endif + +/* SDRAM is a special case because it requires non-cached access of its + * initial configuration, then cached access thereafter. + */ + +#define SAM_DDRCS_MMUFLAGS MMU_MEMFLAGS + +/* The external memory regions may support all access if they host SRAM, + * PSRAM, or SDRAM. NAND memory requires write access for NAND control and + * so should be uncached. + */ + +#if defined(CONFIG_SAMA5_EBICS0_SRAM) || defined(CONFIG_SAMA5_EBICS0_PSRAM) || \ + defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS0_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS1_SRAM) || defined(CONFIG_SAMA5_EBICS1_PSRAM) +# define SAM_EBICS1_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS1_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS1_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS2_SRAM) || defined(CONFIG_SAMA5_EBICS2_PSRAM) +# define SAM_EBICS2_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS2_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS2_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS3_SRAM) || defined(CONFIG_SAMA5_EBICS3_PSRAM) +# define SAM_EBICS3_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS3_NAND) +# define SAM_EBICS3_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS3_MMUFLAGS MMU_ROMFLAGS +#endif + +#define SAM_NFCCR_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHA_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHB_MMUFLAGS MMU_IOFLAGS +#define SAM_SYSC_MMUFLAGS MMU_IOFLAGS + +/* SAMA5 Virtual (mapped) Memory Map + * + * board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* SAMA5 Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + +/* Notice that these mappings are a simple 1-to-1 mapping *unless* + * CONFIG_ARCH_LOWVECTORS is not defined. In the high vector case, the + * register system controls register area is moved out 0f 0xffff:000 where + * the high vectors must reside. + */ + +#define SAM_INTMEM_VSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +# define SAM_BOOTMEM_VSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ +# define SAM_ROM_VSECTION 0x00100000 /* 0x00100000-0x001fffff: ROM */ +# define SAM_NFCSRAM_VSECTION 0x00200000 /* 0x00200000-0x002fffff: NFC SRAM */ +# define SAM_ISRAM_VSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM */ +# define SAM_ISRAM0_VADDR 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ +# define SAM_ISRAM1_VADDR 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ +# define SAM_SMD_VSECTION 0x00400000 /* 0x00400000-0x004fffff: SMD */ +# define SAM_UDPHSRAM_VSECTION 0x00500000 /* 0x00500000-0x005fffff: UDPH SRAM */ +# define SAM_UHPOHCI_VSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP OHCI */ +# define SAM_UHPEHCI_VSECTION 0x00700000 /* 0x00700000-0x007fffff: UHP EHCI */ +# define SAM_AXIMX_VSECTION 0x00800000 /* 0x00800000-0x008fffff: AXI Matrix */ +# define SAM_DAP_VSECTION 0x00900000 /* 0x00900000-0x009fffff: DAP */ +#define SAM_EBICS0_VSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip select 0 */ +#define SAM_DDRCS_VSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDRCS */ +#define SAM_EBICS1_VSECTION 0x40000000 /* 0x40000000-0x4fffffff: EBI Chip select 1 */ +#define SAM_EBICS2_VSECTION 0x50000000 /* 0x50000000-0x5fffffff: EBI Chip select 2 */ +#define SAM_EBICS3_VSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip select 2 */ +#define SAM_NFCCR_VSECTION 0x70000000 /* 0x70000000-0x7fffffff: NFC Command Registers */ + /* 0x80000000-0xefffffff: Undefined */ + +/* If CONFIG_ARCH_LOWVECTORS is not defined, then move the system control + * registers out of the way. + */ + +#ifdef CONFIG_ARCH_LOWVECTORS +#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf7ffffff: Internal Peripherals A */ +# define SAM_PERIPHB_VSECTION 0xf8000000 /* 0xf8000000-0xffefffff: Internal Peripherals B */ +# define SAM_SYSC_VSECTION 0xfff00000 /* 0xfff00000-0xffffbfff: System Controller */ +# define SAM_SYSC_VADDR 0xffffc000 /* 0xffffc000-0xffffffff: System Controller */ +#else +#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf00fffff: Internal Peripherals A */ +# define SAM_PERIPHB_VSECTION 0xf1000000 /* 0xf1000000-0xf10fffff: Internal Peripherals B */ +# define SAM_SYSC_VSECTION 0xf2000000 /* 0xf2000000-0xf20fffff: System Controller */ +# define SAM_SYSC_VADDR 0xf20fc000 /* 0xf20fc000-0xf20fffff: System Controller */ +#endif +#endif + +/* Peripheral virtual base addresses */ + +#define SAM_HSMCI0_VBASE (SAM_PERIPHA_VSECTION+SAM_HSMCI0_OFFSET) +#define SAM_SPI0_VBASE (SAM_PERIPHA_VSECTION+SAM_SPI0_OFFSET) +#define SAM_SSC0_VBASE (SAM_PERIPHA_VSECTION+SAM_SSC0_OFFSET) +#define SAM_CAN0_VBASE (SAM_PERIPHA_VSECTION+SAM_CAN0_OFFSET) +#define SAM_TC012_VBASE (SAM_PERIPHA_VSECTION+SAM_TC012_OFFSET) +#define SAM_TWI0_VBASE (SAM_PERIPHA_VSECTION+SAM_TWI0_OFFSET) +#define SAM_TWI1_VBASE (SAM_PERIPHA_VSECTION+SAM_TWI1_OFFSET) +#define SAM_USART0_VBASE (SAM_PERIPHA_VSECTION+SAM_USART0_OFFSET) +#define SAM_USART1_VBASE (SAM_PERIPHA_VSECTION+SAM_USART1_OFFSET) +#define SAM_UART0_VBASE (SAM_PERIPHA_VSECTION+SAM_UART0_OFFSET) +#define SAM_GMAC_VBASE (SAM_PERIPHA_VSECTION+SAM_GMAC_OFFSET) +#define SAM_PWMC_VBASE (SAM_PERIPHA_VSECTION+SAM_PWMC_OFFSET) +#define SAM_LCDC_VBASE (SAM_PERIPHA_VSECTION+SAM_LCDC_OFFSET) +#define SAM_ISI_VBASE (SAM_PERIPHA_VSECTION+SAM_ISI_OFFSET) +#define SAM_SFR_VBASE (SAM_PERIPHA_VSECTION+SAM_SFR_OFFSET) + +#define SAM_HSMCI1_VBASE (SAM_PERIPHB_VSECTION+SAM_HSMCI1_OFFSET) +#define SAM_HSMCI2_VBASE (SAM_PERIPHB_VSECTION+SAM_HSMCI2_OFFSET) +#define SAM_SPI1_VBASE (SAM_PERIPHB_VSECTION+SAM_SPI1_OFFSET) +#define SAM_SSC1_VBASE (SAM_PERIPHB_VSECTION+SAM_SSC1_OFFSET) +#define SAM_CAN1_VBASE (SAM_PERIPHB_VSECTION+SAM_CAN1_OFFSET) +#define SAM_TC345_VBASE (SAM_PERIPHB_VSECTION+SAM_TC345_OFFSET) +#define SAM_TSADC_VBASE (SAM_PERIPHB_VSECTION+SAM_TSADC_OFFSET) +#define SAM_TWI2_VBASE (SAM_PERIPHB_VSECTION+SAM_TWI2_OFFSET) +#define SAM_USART2_VBASE (SAM_PERIPHB_VSECTION+SAM_USART2_OFFSET) +#define SAM_USART3_VBASE (SAM_PERIPHB_VSECTION+SAM_USART3_OFFSET) +#define SAM_UART1_VBASE (SAM_PERIPHB_VSECTION+SAM_UART1_OFFSET) +#define SAM_EMAC_VBASE (SAM_PERIPHB_VSECTION+SAM_EMAC_OFFSET) +#define SAM_UDPHS_VBASE (SAM_PERIPHB_VSECTION+SAM_UDPHS_OFFSET) +#define SAM_SHA_VBASE (SAM_PERIPHB_VSECTION+SAM_SHA_OFFSET) +#define SAM_AES_VBASE (SAM_PERIPHB_VSECTION+SAM_AES_OFFSET) +#define SAM_TDES_VBASE (SAM_PERIPHB_VSECTION+SAM_TDES_OFFSET) +#define SAM_TRNG_VBASE (SAM_PERIPHB_VSECTION+SAM_TRNG_OFFSET) + +#define SAM_HSMC_VBASE (SAM_SYSC_VADDR+SAM_HSMC_OFFSET) +#define SAM_FUSE_VBASE (SAM_SYSC_VADDR+SAM_FUSE_OFFSET) +#define SAM_DMAC0_VBASE (SAM_SYSC_VADDR+SAM_DMAC0_OFFSET) +#define SAM_DMAC1_VBASE (SAM_SYSC_VADDR+SAM_DMAC1_OFFSET) +#define SAM_MPDDRC_VBASE (SAM_SYSC_VADDR+SAM_MPDDRC_OFFSET) +#define SAM_MATRIX_VBASE (SAM_SYSC_VADDR+SAM_MATRIX_OFFSET) +#define SAM_DBGU_VBASE (SAM_SYSC_VADDR+SAM_DBGU_OFFSET) +#define SAM_AIC_VBASE (SAM_SYSC_VADDR+SAM_AIC_OFFSET) +#define SAM_PION_VBASE(n) (SAM_SYSC_VADDR+SAM_PION_OFFSET(n)) +#define SAM_PIOA_VBASE (SAM_SYSC_VADDR+SAM_PIOA_OFFSET) +#define SAM_PIOB_VBASE (SAM_SYSC_VADDR+SAM_PIOB_OFFSET) +#define SAM_PIOC_VBASE (SAM_SYSC_VADDR+SAM_PIOC_OFFSET) +#define SAM_PIOD_VBASE (SAM_SYSC_VADDR+SAM_PIOD_OFFSET) +#define SAM_PIOE_VBASE (SAM_SYSC_VADDR+SAM_PIOE_OFFSET) +#define SAM_PMC_VBASE (SAM_SYSC_VADDR+SAM_PMC_OFFSET) +#define SAM_RSTC_VBASE (SAM_SYSC_VADDR+SAM_RSTC_OFFSET) +#define SAM_SHDC_VBASE (SAM_SYSC_VADDR+SAM_SHDC_OFFSET) +#define SAM_PITC_VBASE (SAM_SYSC_VADDR+SAM_PITC_OFFSET) +#define SAM_WDT_VBASE (SAM_SYSC_VADDR+SAM_WDT_OFFSET) +#define SAM_SCKCR_VBASE (SAM_SYSC_VADDR+SAM_SCKCR_OFFSET) +#define SAM_BSC_VBASE (SAM_SYSC_VADDR+SAM_BSC_OFFSET) +#define SAM_GPBR_VBASE (SAM_SYSC_VADDR+SAM_GPBR_OFFSET) +#define SAM_RTCC_VBASE (SAM_SYSC_VADDR+SAM_RTCC_OFFSET) + +/* NuttX vitual base address + * + * The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX could be running from NOR FLASH, + * SDRAM, external SRAM, or internal SRAM. If we are running from FLASH, + * then we must have a separate mapping for the non-contiguous RAM region. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) + +/* Some sanity checks. If we are running from FLASH, then one of the + * external chip selects must be configured to boot from NOR flash. + * And, if so, then its size must agree with the configured size. + */ + +# if defined(CONFIG_SAMA5_EBICS0) && defined(CONFIG_SAMA5_EBICS0_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS0FLASH) + +# if CONFIG_SAMA5_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS0 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS1) && defined(CONFIG_SAMA5_EBICS1_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS1FLASH) + +# if CONFIG_SAMA5_EBICS1_SIZE != CONFIG_FLASH_SIZE +# error CS1 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS2) && defined(CONFIG_SAMA5_EBICS2_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS2FLASH) + +# if CONFIG_SAMA2_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS2 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS3) && defined(CONFIG_SAMA5_EBICS3_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS3FLASH) + +# if CONFIG_SAMA5_EBICS3_SIZE != CONFIG_FLASH_SIZE +# error CS3 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH + +# else +# error CONFIG_BOOT_RUNFROMFLASH=y, but no bootable NOR flash defined + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# endif + + /* Set up the NOR FLASH region as the NUTTX .text region */ + +# define NUTTX_TEXT_VADDR (CONFIG_FLASH_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_FLASH_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_FLASH_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + + /* In the default configuration, the primary RAM use for .bss and .data + * is the internal SRAM. + */ + +# define NUTTX_RAM_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_RAM_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_RAM_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_RAM_SIZE (NUTTX_RAM_PEND - NUTTX_RAM_PADDR) + +#else /* CONFIG_BOOT_RUNFROMFLASH */ + + /* Otherwise we are running from some kind of RAM (ISRAM or SDRAM). + * Setup the RAM region as the NUTTX .txt, .bss, and .data region. + */ + +# define NUTTX_TEXT_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + +#endif /* CONFIG_BOOT_RUNFROMFLASH */ + +/* MMU Page Table Location + * + * Determine the address of the MMU page table. Regardless of the memory + * configuration, we will keep the page table in the SAMA5's internal SRAM. + * We will always attempt to use the bottom 16KB of internal SRAM for the + * page table, but there are a few conditions that affect this: + * + * 1) If CONFIG_ARCH_ROMPGTABLE, then the page table resides in ROM and we + * will not use any page table in RAM. + * 2) We are executing out of SRAM. In this case, vectors will reside at + * the bottom of SRAM, following by .text, .data, .bss, and heep. The + * page table will be squeezed into the end of internal SRAM in this + * case. + * + * Or... the user may specify the address of the page table explicitly be defining + * PGTABLE_BASE_VADDR and PGTABLE_BASE_PADDR in the board.h file. + */ + +#undef PGTABLE_IN_HIGHSRAM +#undef PGTABLE_IN_LOWSRAM +#undef ARMV7A_PGTABLE_MAPPING + +#if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. In that case PGTABLE_BASE_VADDR is defined + * in the file mmu.h + * + * We must declare the page table at the bottom or at the top of internal + * SRAM. We pick the bottom of internal SRAM *unless* there are vectors + * in the way at that position. + */ + +# if defined(CONFIG_SAMA5_BOOT_ISRAM) && defined(CONFIG_ARCH_LOWVECTORS) + + /* In this case, page table must lie at the top 16Kb of ISRAM1 (or ISRAM0 + * if ISRAM1 is not available in this architecture) + * + * If CONFIG_PAGING is defined, then mmu.h assign the virtual address + * of the page table. + */ + +# if SAM_ISRAM1_SIZE > 0 +# define PGTABLE_BASE_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# endif +# else +# define PGTABLE_BASE_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# endif +# endif +# define PGTABLE_IN_HIGHSRAM 1 + + /* If we execute from SRAM but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the vector table, + * lying between the vector table and the page table. We don't really + * know how much memory to set aside for the vector table, but 4KiB should + * be much more than enough + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + 0x0001000) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + 0x0001000) +# endif + +# else /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps + * elsewhere in internal SRAM). The page table will then be positioned at + * the first 16Kb of ISRAM0. + */ + +# define PGTABLE_BASE_PADDR SAM_ISRAM0_PADDR +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR SAM_ISRAM0_VADDR +# endif +# define PGTABLE_IN_LOWSRAM 1 + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) +# endif + +# endif /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* In either case, the page table lies in ISRAM. If ISRAM is not the + * primary RAM region, then we will need to set-up a special mapping for + * the page table at boot time. + */ + +# if defined(CONFIG_BOOT_RUNFROMFLASH) + /* If we are running from FLASH, than the primary memory region is + * given by NUTTX_RAM_PADDR. + */ + +# if NUTTX_RAM_PADDR != SAM_ISRAM_PSECTION +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +/* Otherwise, we are running from RAM and that RAM is also the primary + * RAM. + */ + +# elif !defined(CONFIG_SAMA5_BOOT_ISRAM) +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +#else /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + + /* Sanity check.. if one is defined, both should be defined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "One of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is undefined" +# endif + + /* If we execute from SRAM but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the page table + * in ISRAM. + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + PGTABLE_SIZE) +# endif + +#endif /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + +/* Level 2 Page table start addresses. + * + * 16Kb of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation). There is this large whole in the physcal address space + * for which there will never be level 1 mappings: + * + * 0x80000000-0xefffffff: Undefined (1.75 GB) + * + * That is the offset where the main L2 page tables will be positioned. This + * corresponds to page table offsets 0x000002000 up to 0x000003c00. That + * is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual + * address space) + * + * Up to two L2 page tables may be used: + * + * 1) One mapping the vector table. However, L2 page tables must be aligned + * to 1KB address boundaries, so the minimum L2 page table size is then + * 1KB, mapping up a full megabyte of virtual address space. + * + * This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not* + * defined. The SAMA5 boot-up logic will map the beginning of the boot + * memory to address 0x0000:0000 using both the MMU and the AXI matrix + * REMAP register. So no L2 page table is required. + * + * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional + * L2 page table is needed. This page table will use the remainder of + * the address space. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Vector L2 page table offset/size */ + +# define VECTOR_L2_OFFSET 0x000002000 +# define VECTOR_L2_SIZE 0x000000400 + + /* Vector L2 page table base addresses */ + +# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET) +# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET) + + /* Vector L2 page table end addresses */ + +# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE) +# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE) + + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002400 +# define PGTABLE_L2_SIZE 0x000001800 + +#else + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002000 +# define PGTABLE_L2_SIZE 0x000001c00 +#endif + +/* Paging L2 page table base addresses + * + * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +/* Paging L2 page table end addresses */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE) + +/* Base address of the interrupt vector table. + * + * SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * SAM_VECTOR_VSRAM - Virtual address of vector table in SRAM + * SAM_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + +#define VECTOR_TABLE_SIZE 0x00010000 + +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + +# define SAM_VECTOR_PADDR SAM_ISRAM0_PADDR +# define SAM_VECTOR_VSRAM SAM_ISRAM0_VADDR +# define SAM_VECTOR_VADDR 0x00000000 + +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ + +# ifdef SAM_ISRAM1_SIZE >= VECTOR_TABLE_SIZE +# define SAM_VECTOR_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# else +# define SAM_VECTOR_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# endif +# define SAM_VECTOR_VADDR 0xffff0000 + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MEMORYMAP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d3x_mpddrc.h b/arch/arm/src/sama5/chip/_sama5d3x_mpddrc.h new file mode 100644 index 0000000000000000000000000000000000000000..bbf21ce46424bcd83b6295c11d053d06af3e1718 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d3x_mpddrc.h @@ -0,0 +1,405 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/_sama5d3x_mpddrc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MPDDRC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MPDDRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* MPDDRC Register Offsets **********************************************************/ + +#define SAM_MPDDRC_MR_OFFSET 0x0000 /* MPDDRC Mode Register */ +#define SAM_MPDDRC_RTR_OFFSET 0x0004 /* MPDDRC Refresh Timer Register */ +#define SAM_MPDDRC_CR_OFFSET 0x0008 /* MPDDRC Configuration Register */ +#define SAM_MPDDRC_TPR0_OFFSET 0x000c /* MPDDRC Timing Parameter 0 Register */ +#define SAM_MPDDRC_TPR1_OFFSET 0x0010 /* MPDDRC Timing Parameter 1 Register */ +#define SAM_MPDDRC_TPR2_OFFSET 0x0014 /* MPDDRC Timing Parameter 2 Register */ + /* 0x0018 Reserved */ +#define SAM_MPDDRC_LPR_OFFSET 0x001c /* MPDDRC Low-power Register */ +#define SAM_MPDDRC_MD_OFFSET 0x0020 /* MPDDRC Memory Device Register */ +#define SAM_MPDDRC_HS_OFFSET 0x0024 /* MPDDRC High Speed Register */ +#define SAM_MPDDRC_LPDDR2_LPR_OFFSET 0x0028 /* MPDDRC LPDDR2 Low-power Register */ +#define SAM_MPDDRC_LPDDR2_CALMR4_OFFSET 0x002c /* MPDDRC LPDDR2 Calibration and MR4 Register */ +#define SAM_MPDDRC_LPDDR2_TIMCAL_OFFSET 0x0030 /* MPDDRC LPDDR2 Timing Calibration Register */ +#define SAM_MPDDRC_IO_CALIBR_OFFSET 0x0034 /* MPDDRC IO Calibration */ +#define SAM_MPDDRC_OCMS_OFFSET 0x0038 /* MPDDRC OCMS Register */ +#define SAM_MPDDRC_OCMS_KEY1_OFFSET 0x003c /* MPDDRC OCMS KEY1 Register */ +#define SAM_MPDDRC_OCMS_KEY2_OFFSET 0x0040 /* MPDDRC OCMS KEY2 Register */ + /* 0x0044-0x0070 Reserved */ +#define SAM_MPDDRC_DLL_MOR_OFFSET 0x0074 /* MPDDRC DLL Master Offset Register */ +#define SAM_MPDDRC_DLL_SOR_OFFSET 0x0078 /* MPDDRC DLL Slave Offset Register */ +#define SAM_MPDDRC_DLL_MS_OFFSET 0x007c /* MPDDRC DLL Status Master Register */ +#define SAM_MPDDRC_DLL_SS0_OFFSET 0x0080 /* MPDDRC DLL Status Slave 0 Register */ +#define SAM_MPDDRC_DLL_SS1_OFFSET 0x0084 /* MPDDRC DLL Status Slave 1 Register */ +#define SAM_MPDDRC_DLL_SS2_OFFSET 0x0088 /* MPDDRC DLL Status Slave 2 Register */ +#define SAM_MPDDRC_DLL_SS3_OFFSET 0x008c /* MPDDRC DLL Status Slave 3 Register */ + /* 0x0094-0x00e0 Reserved */ +#define SAM_MPDDRC_WPCR_OFFSET 0x00e4 /* MPDDRC Write Protect Control Register */ +#define SAM_MPDDRC_WPSR_OFFSET 0x00e8 /* MPDDRC Write Protect Status Register */ + /* 0x158-0x1cc Reserved */ + /* 0x1dc-0x1f8 Reserved */ + +/* MPDDRC Register Addresses ********************************************************/ + +#define SAM_MPDDRC_MR (SAM_MPDDRC_VBASE+SAM_MPDDRC_MR_OFFSET) +#define SAM_MPDDRC_RTR (SAM_MPDDRC_VBASE+SAM_MPDDRC_RTR_OFFSET) +#define SAM_MPDDRC_CR (SAM_MPDDRC_VBASE+SAM_MPDDRC_CR_OFFSET) +#define SAM_MPDDRC_TPR0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR0_OFFSET) +#define SAM_MPDDRC_TPR1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR1_OFFSET) +#define SAM_MPDDRC_TPR2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR2_OFFSET) +#define SAM_MPDDRC_LPR (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPR_OFFSET) +#define SAM_MPDDRC_MD (SAM_MPDDRC_VBASE+SAM_MPDDRC_MD_OFFSET) +#define SAM_MPDDRC_HS (SAM_MPDDRC_VBASE+SAM_MPDDRC_HS_OFFSET) +#define SAM_MPDDRC_LPDDR2_LPR (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_LPR_OFFSET) +#define SAM_MPDDRC_LPDDR2_CALMR4 (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_CALMR4_OFFSET) +#define SAM_MPDDRC_LPDDR2_TIMCAL (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_TIMCAL_OFFSET) +#define SAM_MPDDRC_IO_CALIBR (SAM_MPDDRC_VBASE+SAM_MPDDRC_IO_CALIBR_OFFSET) +#define SAM_MPDDRC_OCMS (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_OFFSET) +#define SAM_MPDDRC_OCMS_KEY1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_KEY1_OFFSET) +#define SAM_MPDDRC_OCMS_KEY2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_KEY2_OFFSET) +#define SAM_MPDDRC_DLL_MOR (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_MOR_OFFSET) +#define SAM_MPDDRC_DLL_SOR (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SOR_OFFSET) +#define SAM_MPDDRC_DLL_MS (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_MS_OFFSET) +#define SAM_MPDDRC_DLL_SS0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SS0_OFFSET) +#define SAM_MPDDRC_DLL_SS1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SS1_OFFSET) +#define SAM_MPDDRC_DLL_SS2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SS2_OFFSET) +#define SAM_MPDDRC_DLL_SS3 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SS3_OFFSET) +#define SAM_MPDDRC_WPCR (SAM_MPDDRC_VBASE+SAM_MPDDRC_WPCR_OFFSET) +#define SAM_MPDDRC_WPSR (SAM_MPDDRC_VBASE+SAM_MPDDRC_WPSR_OFFSET) + +/* MPDDRC Register Bit Definitions **************************************************/ + +/* MPDDRC Mode Register */ + +#define MPDDRC_MR_MODE_SHIFT (0) /* Bits 0-2: MPDDRC Command Mode */ +#define MPDDRC_MR_MODE_MASK (7 << MPDDRC_MR_MODE_SHIFT) +# define MPDDRC_MR_MODE_NORMAL (0 << MPDDRC_MR_MODE_SHIFT) /* Normal Mode */ +# define MPDDRC_MR_MODE_NOP (1 << MPDDRC_MR_MODE_SHIFT) /* NOP when device accessed */ +# define MPDDRC_MR_MODE_PRCGALL (2 << MPDDRC_MR_MODE_SHIFT) /* 'All Banks Precharge' when device accessed */ +# define MPDDRC_MR_MODE_LMR (3 << MPDDRC_MR_MODE_SHIFT) /* 'Load Mode Register' command when device accessed */ +# define MPDDRC_MR_MODE_RFSH (4 << MPDDRC_MR_MODE_SHIFT) /* 'Auto-Refresh' when device accessed */ +# define MPDDRC_MR_MODE_EXTLMR (5 << MPDDRC_MR_MODE_SHIFT) /* 'Extended Load Mode Register' when device accessed */ +# define MPDDRC_MR_MODE_DEEP (6 << MPDDRC_MR_MODE_SHIFT) /* Deep power mode */ +# define MPDDRC_MR_MODE_LPDDR2 (7 << MPDDRC_MR_MODE_SHIFT) /* LPDDR2 Mode Register' when device accessed */ +#define MPDDRC_MR_MRS_SHIFT (8) /* Bits 8-15: Mode Register Select LPDDR2 */ +#define MPDDRC_MR_MRS_MASK (0xff << MPDDRC_MR_MRS_SHIFT) +# define MPDDRC_MR_MRS(n) ((n) << MPDDRC_MR_MRS_SHIFT) + +/* MPDDRC Refresh Timer Register */ + +#define MPDDRC_RTR_COUNT_SHIFT (0) /* Bits 0-11: MPDDRC Refresh Timer Count */ +#define MPDDRC_RTR_COUNT_MASK (0xfff << MPDDRC_RTR_COUNT_SHIFT) +# define MPDDRC_RTR_COUNT(n) ((n) << MPDDRC_RTR_COUNT_SHIFT) +#define MPDDRC_RTR_ADJ_REF (1 << 16) /* Bit 16: Adjust Refresh Rate */ +#define MPDDRC_RTR_REF_PB (1 << 17) /* Bit 17: Refresh Per Bank */ +#define MPDDRC_RTR_MR4_VALUE_SHIFT (20) /* Bits 20-22: Content of MR4 Register */ +#define MPDDRC_RTR_MR4_VALUE_MASK (7 << MPDDRC_RTR_MR4_VALUE_SHIFT) +# define MPDDRC_RTR_MR4_VALUE(n) ((n) << MPDDRC_RTR_MR4_VALUE_SHIFT) + +/* MPDDRC Configuration Register */ + +#define MPDDRC_CR_NC_SHIFT (0) /* Bits 0-1: Number of Column Bits */ +#define MPDDRC_CR_NC_MASK (3 << MPDDRC_CR_NC_SHIFT) +# define MPDDRC_CR_NC_9 (0 << MPDDRC_CR_NC_SHIFT) /* 9 DDR column bits */ +# define MPDDRC_CR_NC_10 (1 << MPDDRC_CR_NC_SHIFT) /* 10 DDR column bits */ +# define MPDDRC_CR_NC_11 (2 << MPDDRC_CR_NC_SHIFT) /* 11 DDR column bits */ +# define MPDDRC_CR_NC_12 (3 << MPDDRC_CR_NC_SHIFT) /* 12 DDR column bits */ +#define MPDDRC_CR_NR_SHIFT (2) /* Bits 2-3: Number of Row Bits */ +#define MPDDRC_CR_NR_MASK (3 << MPDDRC_CR_NR_SHIFT) +# define MPDDRC_CR_NR_11 (0 << MPDDRC_CR_NR_SHIFT) /* 00 ROW_11 11 row bits */ +# define MPDDRC_CR_NR_12 (1 << MPDDRC_CR_NR_SHIFT) /* 01 ROW_12 12 row bits */ +# define MPDDRC_CR_NR_13 (2 << MPDDRC_CR_NR_SHIFT) /* 10 ROW_13 13 row bits */ +# define MPDDRC_CR_NR_14 (3 << MPDDRC_CR_NR_SHIFT) /* 11 ROW_14 14 row bits */ +#define MPDDRC_CR_CAS_SHIFT (4) /* Bits 4-6: CAS Latency */ +#define MPDDRC_CR_CAS_MASK (7 << MPDDRC_CR_CAS_SHIFT) +# define MPDDRC_CR_CAS_2 (2 << MPDDRC_CR_CAS_SHIFT) /* 010 DDR_CAS2 LPDDR1 CAS Latency 2 */ +# define MPDDRC_CR_CAS_3 (3 << MPDDRC_CR_CAS_SHIFT) /* 011 DDR_CAS3 DDR2/LPDDR2/LPDDR1 CAS Latency 3 */ +# define MPDDRC_CR_CAS_4 (4 << MPDDRC_CR_CAS_SHIFT) /* 100 DDR_CAS4 DDR2/LPDDR2 CAS Latency 4 */ +# define MPDDRC_CR_CAS_5 (5 << MPDDRC_CR_CAS_SHIFT) /* 101 DDR_CAS5 DDR2/LPDDR2 CAS Latency 5 */ +# define MPDDRC_CR_CAS_6 (6 << MPDDRC_CR_CAS_SHIFT) /* 110 DDR_CAS6 DDR2 CAS Latency 6 */ +#define MPDDRC_CR_DLL (1 << 7) /* Bit 7: Reset DLL */ +#define MPDDRC_CR_DIC_DS (1 << 8) /* Bit 8: Output Driver Impedance Control (Drive Strength) */ +#define MPDDRC_CR_DIS_DLL (1 << 9) /* Bit 9: Disable DLL */ +#define MPDDRC_CR_ZQ_SHIFT (10) /* Bits 10-11: ZQ Calibration */ +#define MPDDRC_CR_ZQ_MASK (3 << MPDDRC_CR_ZQ_SHIFT) +# define MPDDRC_CR_ZQ_INIT (0 << MPDDRC_CR_ZQ_SHIFT) /* Calibration command after initialization */ +# define MPDDRC_CR_ZQ_LONG (1 << MPDDRC_CR_ZQ_SHIFT) /* Long calibration */ +# define MPDDRC_CR_ZQ_SHORT (2 << MPDDRC_CR_ZQ_SHIFT) /* Short calibration */ +# define MPDDRC_CR_ZQ_RESET (3 << MPDDRC_CR_ZQ_SHIFT) /* ZQ Reset */ +#define MPDDRC_CR_OCD_SHIFT (12) /* Bits 12-14: Off-chip Driver */ +#define MPDDRC_CR_OCD_MASK (7 << MPDDRC_CR_OCD_SHIFT) +# define MPDDRC_CR_OCD_EXIT (0 << MPDDRC_CR_OCD_SHIFT) /* OCD calibration mode exit, maintain setting */ +# define MPDDRC_CR_OCD_DEFAULT (7 << MPDDRC_CR_OCD_SHIFT) /* OCD calibration default */ +#define MPDDRC_CR_DQMS (1 << 16) /* Bit 16: Mask Data is Shared */ +#define MPDDRC_CR_ENRDM (1 << 17) /* Bit 17: Enable Read Measure */ +#define MPDDRC_CR_NB (1 << 20) /* Bit 20: Number of Banks */ +# define MPDDRC_CR_4BANKS (0) /* 4 banks */ +# define MPDDRC_CR_8BANKS MPDDRC_CR_NB /* 8 banks */ +#define MPDDRC_CR_NDQS (1 << 21) /* Bit 21: Not DQS */ +#define MPDDRC_CR_DECOD (1 << 22) /* Bit 22: Type of Decoding */ +#define MPDDRC_CR_UNAL (1 << 23) /* Bit 23: Support Unaligned Access */ + +/* MPDDRC Timing Parameter 0 Register */ + +#define MPDDRC_TPR0_TRAS_SHIFT (0) /* Bits 0-3: Active to Precharge Delay */ +#define MPDDRC_TPR0_TRAS_MASK (15 << MPDDRC_TPR0_TRAS_SHIFT) +# define MPDDRC_TPR0_TRAS(n) ((n) << MPDDRC_TPR0_TRAS_SHIFT) +#define MPDDRC_TPR0_TRCD_SHIFT (4) /* Bits 4-7: Row to Column Delay */ +#define MPDDRC_TPR0_TRCD_MASK (15 << MPDDRC_TPR0_TRCD_SHIFT) +# define MPDDRC_TPR0_TRCD(n) ((n) << MPDDRC_TPR0_TRCD_SHIFT) +#define MPDDRC_TPR0_TWR_SHIFT (8) /* Bits 8-11: Write Recovery Delay */ +#define MPDDRC_TPR0_TWR_MASK (15 << MPDDRC_TPR0_TWR_SHIFT) +# define MPDDRC_TPR0_TWR(n) ((n) << MPDDRC_TPR0_TWR_SHIFT) +#define MPDDRC_TPR0_TRC_SHIFT (12) /* Bits 12-15: Row Cycle Delay */ +#define MPDDRC_TPR0_TRC_MASK (15 << MPDDRC_TPR0_TRC_SHIFT) +# define MPDDRC_TPR0_TRC(n) ((n) << MPDDRC_TPR0_TRC_SHIFT) +#define MPDDRC_TPR0_TRP_SHIFT (16) /* Bits 16-19: Row Precharge Delay */ +#define MPDDRC_TPR0_TRP_MASK (15 << MPDDRC_TPR0_TRP_SHIFT) +# define MPDDRC_TPR0_TRP(n) ((n) << MPDDRC_TPR0_TRP_SHIFT) +#define MPDDRC_TPR0_TRRD_SHIFT (20) /* Bits 20-23: Active BankA to Active BankB */ +#define MPDDRC_TPR0_TRRD_MASK (15 << MPDDRC_TPR0_TRRD_SHIFT) +# define MPDDRC_TPR0_TRRD(n) ((n) << MPDDRC_TPR0_TRRD_SHIFT) +#define MPDDRC_TPR0_TWTR_SHIFT (24) /* Bits 24-26: Internal Write to Read Delay */ +#define MPDDRC_TPR0_TWTR_MASK (7 << MPDDRC_TPR0_TWTR_SHIFT) +# define MPDDRC_TPR0_TWTR(n) ((n) << MPDDRC_TPR0_TWTR_SHIFT) +#define MPDDRC_TPR0_RDC_WRRD (1 << 27) /* Bit 27: Reduce Write to Read Delay */ +#define MPDDRC_TPR0_TMRD_SHIFT (28) /* Bits 18-31: Load Mode Register Command to Activate or Refresh Command */ +#define MPDDRC_TPR0_TMRD_MASK (15 << MPDDRC_TPR0_TMRD_SHIFT) +# define MPDDRC_TPR0_TMRD(n) ((n) << MPDDRC_TPR0_TMRD_SHIFT) + +/* MPDDRC Timing Parameter 1 Register */ + +#define MPDDRC_TPR1_TRFC_SHIFT (0) /* Bits 0-6: Row Cycle Delay */ +#define MPDDRC_TPR1_TRFC_MASK (0x7f << MPDDRC_TPR1_TRFC_SHIFT) +# define MPDDRC_TPR1_TRFC(n) ((n) << MPDDRC_TPR1_TRFC_SHIFT) +#define MPDDRC_TPR1_TXSNR_SHIFT (8) /* Bits 8-15: Exit Self Refresh Delay to Non Read Command */ +#define MPDDRC_TPR1_TXSNR_MASK (0xff << MPDDRC_TPR1_TXSNR_SHIFT) +# define MPDDRC_TPR1_TXSNR(n) ((n) << MPDDRC_TPR1_TXSNR_SHIFT) +#define MPDDRC_TPR1_TXSRD_SHIFT (16) /* Bits 16-23: Exit Self Refresh Delay to Read Command */ +#define MPDDRC_TPR1_TXSRD_MASK (0xff << MPDDRC_TPR1_TXSRD_SHIFT) +# define MPDDRC_TPR1_TXSRD(n) ((n) << MPDDRC_TPR1_TXSRD_SHIFT) +#define MPDDRC_TPR1_TXP_SHIFT (24) /* Bits 24-27: Exit Power-down Delay to First Command */ +#define MPDDRC_TPR1_TXP_MASK (15 << MPDDRC_TPR1_TXP_SHIFT) +# define MPDDRC_TPR1_TXP(n) ((n) << MPDDRC_TPR1_TXP_SHIFT) + +/* MPDDRC Timing Parameter 2 Register */ + +#define MPDDRC_TPR2_TXARD_SHIFT (0) /* Bits 0-3: Exit Active Power Down Delay to Read Command in Mode 'Fast Exit' */ +#define MPDDRC_TPR2_TXARD_MASK (15 << MPDDRC_TPR2_TXARD_SHIFT) +# define MPDDRC_TPR2_TXARD(n) ((n) << MPDDRC_TPR2_TXARD_SHIFT) +#define MPDDRC_TPR2_TXARDS_SHIFT (4) /* Bits 4-7: Exit Active Power Down Delay to Read Command in Mode 'Slow Exit' */ +#define MPDDRC_TPR2_TXARDS_MASK (15 << MPDDRC_TPR2_TXARDS_SHIFT) +# define MPDDRC_TPR2_TXARDS(n) ((n) << MPDDRC_TPR2_TXARDS_SHIFT) +#define MPDDRC_TPR2_TRPA_SHIFT (8) /* Bits 8-11: Row Precharge All Delay */ +#define MPDDRC_TPR2_TRPA_MASK (15 << MPDDRC_TPR2_TRPA_SHIFT) +# define MPDDRC_TPR2_TRPA(n) ((n) << MPDDRC_TPR2_TRPA_SHIFT) +#define MPDDRC_TPR2_TRTP_SHIFT (12) /* Bits 12-14: Read to Precharge */ +#define MPDDRC_TPR2_TRTP_MASK (7 << MPDDRC_TPR2_TRTP_SHIFT) +# define MPDDRC_TPR2_TRTP(n) ((n) << MPDDRC_TPR2_TRTP_SHIFT) +#define MPDDRC_TPR2_TFAW_SHIFT (16) /* Bits 16-19: Four Active Windows */ +#define MPDDRC_TPR2_TFAW_MASK (15 << MPDDRC_TPR2_TFAW_SHIFT) +# define MPDDRC_TPR2_TFAW(n) ((n) << MPDDRC_TPR2_TFAW_SHIFT) + +/* MPDDRC Low-power Register */ + +#define MPDDRC_LPR_LPCB_SHIFT (0) /* Bits 0-1: Low-power Command*/ +#define MPDDRC_LPR_LPCB_MASK (3 << MPDDRC_LPR_LPCB_SHIFT) +# define MPDDRC_LPR_LPCB_DISABLED (0 << MPDDRC_LPR_LPCB_SHIFT) /* Low-power Feature is inhibited */ +# define MPDDRC_LPR_LPCB_SELFREFRESH (1 << MPDDRC_LPR_LPCB_SHIFT) /* Issues a 'Self Refresh' to device, clocks deactivated */ +# define MPDDRC_LPR_LPCB_POWERDOWN (2 << MPDDRC_LPR_LPCB_SHIFT) /* Issues a 'Power-down' to device after each access */ +# define MPDDRC_LPR_LPCB_DEEPPWD (3 << MPDDRC_LPR_LPCB_SHIFT) /* TIssues a 'Deep Power-down' to Low-power device */ +#define MPDDRC_LPR_CLK_FR (1 << 2) /* Bit 2: Clock Frozen Command */ +#define MPDDRC_LPR_LPDDR2_PWOFF (1 << 3) /* Bit 3: LPDDR2 Power Off */ +#define MPDDRC_LPR_PASR_SHIFT (4) /* Bits 4-6: Partial Array Self Refresh */ +#define MPDDRC_LPR_PASR_MASK (7 << MPDDRC_LPR_PASR_SHIFT) +# define MPDDRC_LPR_PASR(n) ((n) << MPDDRC_LPR_PASR_SHIFT) +#define MPDDRC_LPR_DS_SHIFT (8) /* Bits 8-10: Drive Strength */ +#define MPDDRC_LPR_DS_MASK (7 << MPDDRC_LPR_DS_SHIFT) +# define MPDDRC_LPR_DS(n) ((n) << MPDDRC_LPR_DS_SHIFT) +#define MPDDRC_LPR_TIMEOUT_SHIFT (12) /* Bits 12-13: Enter Low-power Mode */ +#define MPDDRC_LPR_TIMEOUT_MASK (3 << MPDDRC_LPR_TIMEOUT_SHIFT) +# define MPDDRC_LPR_TIMEOUT_0CLKS (0 << MPDDRC_LPR_TIMEOUT_SHIFT) /* Activates low-power mode after the end of transfer */ +# define MPDDRC_LPR_TIMEOUT_64CLKS (1 << MPDDRC_LPR_TIMEOUT_SHIFT) /* Activates low-power mode 64 clocks after the end of transfer */ +# define MPDDRC_LPR_TIMEOUT_128CLKS (2 << MPDDRC_LPR_TIMEOUT_SHIFT) /* 28 Activates low-power mode 128 clocks after the end of transfer */ +#define MPDDRC_LPR_APDE (1 << 16) /* Bit 16: ctive Power Down Exit Time */ +# define MPDDRC_LPR_APDE_FAST (0) +# define MPDDRC_LPR_APDE_SLOW MPDDRC_LPR_APDE +#define MPDDRC_LPR_UPD_MR_SHIFT (20) /* Bits 20-21: Update Load Mode Register and Extended Mode Register */ +#define MPDDRC_LPR_UPD_MR_MASK (3 << MPDDRC_LPR_UPD_MR_SHIFT) +# define MPDDRC_LPR_UPD_MR_DISABLED (0 << MPDDRC_LPR_UPD_MR_SHIFT) /* DISABLED Update is disabled */ +# define MPDDRC_LPR_UPD_MR_SHARED (1 << MPDDRC_LPR_UPD_MR_SHIFT) /* MPDDRC shares external bus */ +# define MPDDRC_LPR_UPD_MR_UNSHARED (2 << MPDDRC_LPR_UPD_MR_SHIFT) /* MPDDRC does not share external bus */ + +/* MPDDRC Memory Device Register */ + +#define MPDDRC_MD_SHIFT (0) /* Bits 0-2: Memory Device */ +#define MPDDRC_MD_MASK (7 << MPDDRC_MD_SHIFT) +# define MPDDRC_MD_LPDDR_SDRAM (2 << MPDDRC_MD_SHIFT) /* Low-power DDR1-SDRAM */ +# define MPDDRC_MD_DDR2_SDRAM (6 << MPDDRC_MD_SHIFT) /* DDR2-SDRAM */ +# define MPDDRC_MD_LPDDR2_SDRAM (7 << MPDDRC_MD_SHIFT) /* Low-Power DDR2-SDRAM */ +#define MPDDRC_MD_DBW (1 << 4) /* Bit 4: Data Bus Width */ +# define MPDDRC_MD_DBW32 (0) /* Data bus width is 32 bits */ +# define MPDDRC_MD_DBW16 MPDDRC_MD_DBW /* Data bus width is 16 bits */ + +/* MPDDRC High Speed Register */ + +#define MPDDRC_HS_DIS_ANTICIP_READ (1 << 2) /* Bit 2: Disable Anticip Read Access */ +#define MPDDRC_HS_AUTOREFRESH_CAL (1 << 5) /* Bit 5: calibration during autorefresh (REVISIT) */ + +/* MPDDRC LPDDR2 Low-power Register */ + +#define MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT (0) /* Bits 0-7: Bank Mask Bit/PASR */ +#define MPDDRC_LPDDR2_LPR_BK_MASK_PASR_MASK (0xff << MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT) +# define MPDDRC_LPDDR2_LPR_BK_MASK_PASR(n) ((n) << MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT) +#define MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT (8) /* Bits 8-23: Segment Mask*/ +#define MPDDRC_LPDDR2_LPR_SEG_MASK_MASK (0xffff << MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT) +# define MPDDRC_LPDDR2_LPR_SEG_MASK(n) ((n) << MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT) +#define MPDDRC_LPDDR2_LPR_DS_SHIFT (24) /* Bits 24-27: Drive strength */ +#define MPDDRC_LPDDR2_LPR_DS_MASK (15 << MPDDRC_LPDDR2_LPR_DS_SHIFT) +# define MPDDRC_LPDDR2_LPR_DS(n) ((n) << MPDDRC_LPDDR2_LPR_DS_SHIFT) +#define MPDDRC_LPDDR2_LPR_SR_SHIFT (28) /* Bits 28-31: Slew Rate (REVISIT) */ +#define MPDDRC_LPDDR2_LPR_SR_MASK (15 << MPDDRC_LPDDR2_LPR_SR_SHIFT) +# define MPDDRC_LPDDR2_LPR_SR(n) ((n) << MPDDRC_LPDDR2_LPR_SR_SHIFT) + +/* MPDDRC LPDDR2 Calibration and MR4 Register */ + +#define MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT (0) /* Bits 0-15: LPDDR2 Calibration Timer Count */ +#define MPDDRC_LPDDR2_CALMR4_COUNT_CAL_MASK (0xffff << MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT) +# define MPDDRC_LPDDR2_CALMR4_COUNT_CAL(n) ((n) << MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT) +#define MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT (16) /* Bits 16-31: Mode Register 4 Read Interval */ +#define MPDDRC_LPDDR2_CALMR4_MR4_READ_MASK (0xffff << MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT) +# define MPDDRC_LPDDR2_CALMR4_MR4_READ(n) ((n) << MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT) + +/* MPDDRC LPDDR2 Timing Calibration Register */ + +#define MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT (0) /* Bits 0-7: ZQ Calibration Short */ +#define MPDDRC_LPDDR2_TIMCAL_ZQCS_MASK (0xff << MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT) +# define MPDDRC_LPDDR2_TIMCAL_ZQCS(n) ((n) << MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT) + +/* MPDDRC IO Calibration */ + +#define MPDDRC_IO_CALIBR_RDIV_SHIFT (0) /* Bits 0-2: Resistor Divider, Output Driver Impedance */ +#define MPDDRC_IO_CALIBR_RDIV_MASK (7 << MPDDRC_IO_CALIBR_RDIV_SHIFT) +# define MPDDRC_IO_CALIBR_RZQ34_NA (1 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2 RZQ = 34.3 Ohm DDR2/LPDDR1: Not applicable */ +# define MPDDRC_IO_CALIBR_RZQ40_33 (2 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 40 Ohm DDR2/LPDDR1: RZQ = 33.3 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ48_40 (3 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 48 Ohm DDR2/LPDDR1: RZQ = 40 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ60_50 (4 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 60 Ohm DDR2/LPDDR1: RZQ = 50 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ80_67 (6 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2 RZQ = 80 Ohm DDR2/LPDDR1: RZQ = 66.7 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ120_100 (7 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 120 Oh m DDR2/LPDDR1: RZQ = 100 Ohm */ +#define MPDDRC_IO_CALIBR_TZQIO_SHIFT (8) /* Bits 8-10: IO Calibration */ +#define MPDDRC_IO_CALIBR_TZQIO_MASK (7 << MPDDRC_IO_CALIBR_TZQIO_SHIFT) +# define MPDDRC_IO_CALIBR_TZQIO(n) ((n) << MPDDRC_IO_CALIBR_TZQIO_SHIFT) +#define MPDDRC_IO_CALIBR_CALCODEP_SHIFT (16) /* Bits 16-19: Number of Transistor P */ +#define MPDDRC_IO_CALIBR_CALCODEP_MASK (15 << MPDDRC_IO_CALIBR_CALCODEP_SHIFT) +# define MPDDRC_IO_CALIBR_CALCODEP(n) ((n) << MPDDRC_IO_CALIBR_CALCODEP_SHIFT) +#define MPDDRC_IO_CALIBR_CALCODEN_SHIFT (20) /* Bits 20-23: Number of Transistor N */ +#define MPDDRC_IO_CALIBR_CALCODEN_MASK (15 << MPDDRC_IO_CALIBR_CALCODEN_SHIFT) +# define MPDDRC_IO_CALIBR_CALCODEN(n) ((n) << MPDDRC_IO_CALIBR_CALCODEN_SHIFT) + +/* MPDDRC OCMS Register */ + +#define MPDDRC_OCMS_SCR_EN (1 << 0) /* Bit 0: Scrambling enable */ + +/* MPDDRC OCMS KEY1 Register (32-bit key value) */ +/* MPDDRC OCMS KEY2 Register (32-bit key value) */ + +/* MPDDRC DLL Master Offset Register */ + +#define MPDDRC_DLL_MOR_MOFF_SHIFT (0) /* Bits 0-3: DLL Master Delay Line Offset */ +#define MPDDRC_DLL_MOR_MOFF_MASK (15 << MPDDRC_DLL_MOR_MOFF_SHIFT) +# define MPDDRC_DLL_MOR_MOFF(n) ((n) << MPDDRC_DLL_MOR_MOFF_SHIFT) +#define MPDDRC_DLL_MOR_CLK90OFF_SHIFT (8) /* Bits 8-12: DLL CLK90 Delay Line Offset */ +#define MPDDRC_DLL_MOR_CLK90OFF_MASK (31 << MPDDRC_DLL_MOR_CLK90OFF_SHIFT) +# define MPDDRC_DLL_MOR_CLK90OFF(n) ((n) << MPDDRC_DLL_MOR_CLK90OFF_SHIFT) +#define MPDDRC_DLL_MOR_SELOFF (1 << 16) /* Bit 16: DLL Offset Selection */ +#define MPDDRC_DLL_MOR_KEY_SHIFT (24) /* Bits 24-31: DLL CLK90 Delay Line Offset (REVISIT) */ +#define MPDDRC_DLL_MOR_KEY_MASK (0xff << MPDDRC_DLL_MOR_KEY_SHIFT) +# define MPDDRC_DLL_MOR_KEY (0xc5 << MPDDRC_DLL_MOR_KEY_SHIFT) + +/* MPDDRC DLL Slave Offset Register */ + +#define MPDDRC_DLL_SOR_S0OFF_SHIFT (0) /* Bits 0-4: DLL Slave 0 Delay Line Offset */ +#define MPDDRC_DLL_SOR_S0OFF_MASK (31 << MPDDRC_DLL_SOR_S0OFF_SHIFT) +# define MPDDRC_DLL_SOR_S0OFF(n) ((n) << MPDDRC_DLL_SOR_S0OFF_SHIFT) +#define MPDDRC_DLL_SOR_S1OFF_SHIFT (8) /* Bits 8-12: DLL Slave 1 Delay Line Offset */ +#define MPDDRC_DLL_SOR_S1OFF_MASK (31 << MPDDRC_DLL_SOR_S1OFF_SHIFT) +# define MPDDRC_DLL_SOR_S1OFF(n) ((n) << MPDDRC_DLL_SOR_S1OFF_SHIFT) +#define MPDDRC_DLL_SOR_S2OFF_SHIFT (16) /* Bits 16-20: DLL Slave 2 Delay Line Offset */ +#define MPDDRC_DLL_SOR_S2OFF_MASK (31 << MPDDRC_DLL_SOR_S2OFF_SHIFT) +# define MPDDRC_DLL_SOR_S2OFF(n) ((n) << MPDDRC_DLL_SOR_S2OFF_SHIFT) +#define MPDDRC_DLL_SOR_S3OFF_SHIFT (24) /* Bits 24-28: DLL Slave 3 Delay Line Offset */ +#define MPDDRC_DLL_SOR_S3OFF_MASK (31 << MPDDRC_DLL_SOR_S3OFF_SHIFT) +# define MPDDRC_DLL_SOR_S3OFF(n) ((n) << MPDDRC_DLL_SOR_S3OFF_SHIFT) + +/* MPDDRC DLL Status Master Register */ + +#define MPDDRC_DLL_MS_MDINC (1 << 0) /* Bit 0: DLL Master Delay Increment */ +#define MPDDRC_DLL_MS_MDDEC (1 << 1) /* Bit 1: DLL Master Delay Decrement */ +#define MPDDRC_DLL_MS_MDOVF (1 << 2) /* Bit 2: DLL Master Delay Overflow */ +#define MPDDRC_DLL_MS_MDVAL_SHIFT (8) /* Bits 8-15: DLL Master Delay Value */ +#define MPDDRC_DLL_MS_MDVAL_MASK (0xff << MPDDRC_DLL_MS_MDVAL_SHIFT) + +/* MPDDRC DLL Status Slave 0-3 Registers */ + +#define MPDDRC_DLL_SS_SDCOVF (1 << 0) /* Bit 0: DLL Slave x Delay Correction Overflow */ +#define MPDDRC_DLL_SS_SDCUDF (1 << 1) /* Bit 1: DLL Slave x Delay Correction Underflow */ +#define MPDDRC_DLL_SS_SDERF (1 << 2) /* Bit 2: DLL Slave x Delay Correction Error */ +#define MPDDRC_DLL_SS_SDVAL_SHIFT (8) /* Bits 8-15: DLL Slave x Delay Value */ +#define MPDDRC_DLL_SS_SDVAL_MASK (0xff << MPDDRC_DLL_SS_SDVAL_SHIFT) +#define MPDDRC_DLL_SS_SDCVAL_SHIFT (16) /* Bits 16-23: DLL Slave x Delay Correction Value */ +#define MPDDRC_DLL_SS_SDCVAL_MASK (0xff << MPDDRC_DLL_SS_SDCVAL_SHIFT) + +/* MPDDRC Write Protect Control Register */ + +#define MPDDRC_WPCR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define MPDDRC_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection KEY */ +#define MPDDRC_WPCR_WPKEY_MASK (0x00ffffff << MPDDRC_WPCR_WPKEY_SHIFT) + #define MPDDRC_WPCR_WPKEY (0x00444452 << MPDDRC_WPCR_WPKEY_SHIFT) + +/* MPDDRC Write Protect Status Register */ + +#define MPDDRC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Enable */ +#define MPDDRC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define MPDDRC_WPSR_WPVSRC_MASK (0xffff << MPDDRC_WPSR_WPVSRC_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_MPDDRC_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d3x_pinmap.h b/arch/arm/src/sama5/chip/_sama5d3x_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..a18e7272aa5db0f30220ed5c2a9dc3ba676b8126 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d3x_pinmap.h @@ -0,0 +1,413 @@ +/************************************************************************************************************ + * arch/arm/src/sama5/chip/_sama5d3x_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_PINMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_PINMAP_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_pio.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ + +/* PIO pin definitions **************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, however, will + * use the pin selection without the numeric suffix. Additional definitions are required in the board.h + * file. For example, if we wanted the LCD data bit 16 on PA16, then the following definition should appear + * in the board.h header file for that board: + * + * #define PIO_LCD_DAT16 PIO_LCD_DAT16_1 + * + * The LCD driver will then automatically configre PA16 as the DAT16 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific PIO options such as frequency, open-drain/push-pull, + * and pull-up/down! Just the basics are defined for most pins in this file at the present time. + */ + +/* Touch Screen Analog-to-Digital Converter - ADC */ + +#define PIO_ADC_AD0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) /* Type: GPIO_ANA */ +#define PIO_ADC_AD1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) /* Type: GPIO_ANA */ +#define PIO_ADC_AD2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) /* Type: GPIO_ANA */ +#define PIO_ADC_AD3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) /* Type: GPIO_ANA */ +#define PIO_ADC_AD4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN24) /* Type: GPIO_ANA */ +#define PIO_ADC_AD5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN25) /* Type: GPIO_ANA */ +#define PIO_ADC_AD6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN26) /* Type: GPIO_ANA */ +#define PIO_ADC_AD7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) /* Type: GPIO_ANA */ +#define PIO_ADC_AD8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) /* Type: GPIO_ANA */ +#define PIO_ADC_AD9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) /* Type: GPIO_ANA */ +#define PIO_ADC_AD10 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) /* Type: GPIO_ANA */ +#define PIO_ADC_AD11 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) /* Type: GPIO_ANA */ +#define PIO_ADC_TRG (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) /* Type: GPIO */ + +/* Advanced Interrupt Controller - AIC */ + +#define PIO_AIC_FIQ (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) /* Type: GPIO */ +#define PIO_AIC_IRQ (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN31) /* Type: EBI */ + +/* CAN controller - CANx */ + +#define PIO_CAN0_RX (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) /* Type: GPIO */ +#define PIO_CAN0_TX (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) /* Type: GPIO */ + +#define PIO_CAN1_RX (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) /* Type: GMAC */ +#define PIO_CAN1_TX (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) /* Type: GMAC */ + +/* Debug Unit - DBGU */ + +#define PIO_DBGU_DRXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) /* Type: GPIO */ +#define PIO_DBGU_DTXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) /* Type: GPIO */ + +/* External Bus Interface - EBI */ + +#define PIO_EBI_A0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) /* Type: EBI */ +#define PIO_EBI_A1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN1) /* Type: EBI */ +#define PIO_EBI_A10 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN10) /* Type: EBI */ +#define PIO_EBI_A11 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN11) /* Type: EBI */ +#define PIO_EBI_A12 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN12) /* Type: EBI */ +#define PIO_EBI_A13 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN13) /* Type: EBI */ +#define PIO_EBI_A14 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN14) /* Type: EBI */ +#define PIO_EBI_A15 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN15) /* Type: EBI */ +#define PIO_EBI_A16 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN16) /* Type: EBI */ +#define PIO_EBI_A17 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN17) /* Type: EBI */ +#define PIO_EBI_A18 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN18) /* Type: EBI */ +#define PIO_EBI_A19 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN19) /* Type: EBI */ +#define PIO_EBI_A2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN2) /* Type: EBI */ +#define PIO_EBI_A20 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN20) /* Type: EBI */ +#define PIO_EBI_A21 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN21) /* Type: EBI */ +#define PIO_EBI_A22 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN22) /* Type: EBI */ +#define PIO_EBI_A23 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN23) /* Type: EBI */ +#define PIO_EBI_A24 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN24) /* Type: EBI */ +#define PIO_EBI_A25 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN25) /* Type: EBI */ +#define PIO_EBI_A3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN3) /* Type: EBI */ +#define PIO_EBI_A4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN4) /* Type: EBI */ +#define PIO_EBI_A5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN5) /* Type: EBI */ +#define PIO_EBI_A6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN6) /* Type: EBI */ +#define PIO_EBI_A7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN7) /* Type: EBI */ +#define PIO_EBI_A8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN8) /* Type: EBI */ +#define PIO_EBI_A9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN9) /* Type: EBI */ +#define PIO_EBI_NWAIT (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN30) /* Type: EBI */ + +/* RMII Ethernet 10/100 - EMAC */ + +#define PIO_EMAC_CRSDV (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) /* Type: GPIO */ +#define PIO_EMAC_MDC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) /* Type: GPIO */ +#define PIO_EMAC_MDIO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) /* Type: GPIO */ +#define PIO_EMAC_REFCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) /* Type: GPIO */ +#define PIO_EMAC_RX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) /* Type: GPIO */ +#define PIO_EMAC_RX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) /* Type: GPIO */ +#define PIO_EMAC_RXER (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) /* Type: GPIO */ +#define PIO_EMAC_TX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) /* Type: GPIO */ +#define PIO_EMAC_TX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) /* Type: GPIO */ +#define PIO_EMAC_TXEN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) /* Type: GPIO */ + +/* GIgabit Ethernet 10/100/1000 - GMAC */ + +#define PIO_GMAC_125CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) /* Type: GMAC */ +#define PIO_GMAC_125CKO (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) /* Type: GPIO */ +#define PIO_GMAC_COL (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) /* Type: GMAC */ +#define PIO_GMAC_CRS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) /* Type: GMAC */ +#define PIO_GMAC_MDC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) /* Type: GMAC */ +#define PIO_GMAC_MDIO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) /* Type: GMAC */ +#define PIO_GMAC_RX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) /* Type: GMAC */ +#define PIO_GMAC_RX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) /* Type: GMAC */ +#define PIO_GMAC_RX2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) /* Type: GMAC */ +#define PIO_GMAC_RX3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) /* Type: GMAC */ +#define PIO_GMAC_RX4 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) /* Type: GMAC */ +#define PIO_GMAC_RX5 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) /* Type: GMAC */ +#define PIO_GMAC_RX6 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) /* Type: GMAC */ +#define PIO_GMAC_RX7 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) /* Type: GMAC */ +#define PIO_GMAC_RXCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) /* Type: GMAC */ +#define PIO_GMAC_RXDV (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) /* Type: GMAC */ +#define PIO_GMAC_RXER (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) /* Type: GMAC */ +#define PIO_GMAC_TX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) /* Type: GMAC */ +#define PIO_GMAC_TX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) /* Type: GMAC */ +#define PIO_GMAC_TX2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) /* Type: GMAC */ +#define PIO_GMAC_TX3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) /* Type: GMAC */ +#define PIO_GMAC_TX4 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) /* Type: GMAC */ +#define PIO_GMAC_TX5 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) /* Type: GMAC */ +#define PIO_GMAC_TX6 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) /* Type: GMAC */ +#define PIO_GMAC_TX7 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) /* Type: GMAC */ +#define PIO_GMAC_TXCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) /* Type: GMAC */ +#define PIO_GMAC_TXEN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) /* Type: GMAC */ +#define PIO_GMAC_TXER (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) /* Type: GMAC */ + +/* Static Memory Controller - HSMC */ + +#define PIO_HSMC_NANDALE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN21) /* Type: EBI */ +#define PIO_HSMC_NANDCLE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN22) /* Type: EBI */ +#define PIO_HSMC_NBS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) /* Type: EBI */ +#define PIO_HSMC_NBS1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) /* Type: EBI */ +#define PIO_HSMC_NCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN26) /* Type: EBI */ +#define PIO_HSMC_NCS1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) /* Type: EBI */ +#define PIO_HSMC_NCS2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) /* Type: EBI */ +#define PIO_HSMC_NWR1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) /* Type: EBI */ + +/* Image Sensor Interface - ISI */ + +#define PIO_ISI_D0 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) /* Type: GPIO */ +#define PIO_ISI_D1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) /* Type: GPIO */ +#define PIO_ISI_D2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) /* Type: GPIO */ +#define PIO_ISI_D3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) /* Type: GPIO */ +#define PIO_ISI_D4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) /* Type: GPIO */ +#define PIO_ISI_D5 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) /* Type: GPIO */ +#define PIO_ISI_D6 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) /* Type: GPIO */ +#define PIO_ISI_D7 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) /* Type: GPIO */ +#define PIO_ISI_D8 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) /* Type: GPIO */ +#define PIO_ISI_D9 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) /* Type: GPIO */ +#define PIO_ISI_D10 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) /* Type: GPIO */ +#define PIO_ISI_D11 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) /* Type: GPIO */ +#define PIO_ISI_HSYNC (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) /* Type: GPIO */ +#define PIO_ISI_PCK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) /* Type: GPIO */ +#define PIO_ISI_VSYNC (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) /* Type: GPIO */ + +/* LCD Controller - LCDC */ + +#define PIO_LCD_DAT0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) /* Type: GPIO */ +#define PIO_LCD_DAT2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) /* Type: GPIO */ +#define PIO_LCD_DAT1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN1) /* Type: GPIO */ +#define PIO_LCD_DAT3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) /* Type: GPIO */ +#define PIO_LCD_DAT4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) /* Type: GPIO */ +#define PIO_LCD_DAT5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) /* Type: GPIO */ +#define PIO_LCD_DAT6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) /* Type: GPIO */ +#define PIO_LCD_DAT7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) /* Type: GPIO */ +#define PIO_LCD_DAT8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN8) /* Type: GPIO */ +#define PIO_LCD_DAT9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) /* Type: GPIO */ +#define PIO_LCD_DAT10 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) /* Type: GPIO */ +#define PIO_LCD_DAT11 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) /* Type: GPIO */ +#define PIO_LCD_DAT12 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) /* Type: GPIO */ +#define PIO_LCD_DAT13 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) /* Type: GPIO */ +#define PIO_LCD_DAT14 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) /* Type: GPIO */ +#define PIO_LCD_DAT15 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) /* Type: GPIO */ +#define PIO_LCD_DAT16_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) /* Type: GPIO */ +#define PIO_LCD_DAT16_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) /* Type: GPIO */ +#define PIO_LCD_DAT17_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) /* Type: GPIO */ +#define PIO_LCD_DAT17_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) /* Type: GPIO */ +#define PIO_LCD_DAT18_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) /* Type: GPIO */ +#define PIO_LCD_DAT18_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) /* Type: GPIO */ +#define PIO_LCD_DAT19_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) /* Type: GPIO */ +#define PIO_LCD_DAT19_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) /* Type: GPIO */ +#define PIO_LCD_DAT20_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) /* Type: GPIO */ +#define PIO_LCD_DAT20_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) /* Type: GPIO */ +#define PIO_LCD_DAT21_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) /* Type: GPIO */ +#define PIO_LCD_DAT21_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) /* Type: MCI_CLK */ +#define PIO_LCD_DAT22_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) /* Type: EBI */ +#define PIO_LCD_DAT22_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) /* Type: GPIO */ +#define PIO_LCD_DAT23_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) /* Type: EBI */ +#define PIO_LCD_DAT23_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) /* Type: GPIO */ +#define PIO_LCD_DEN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) /* Type: GPIO */ +#define PIO_LCD_DISP (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) /* Type: GPIO */ +#define PIO_LCD_HSYNC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) /* Type: GPIO */ +#define PIO_LCD_PCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) /* Type: GPIO_CLK2 */ +#define PIO_LCD_PWM (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) /* Type: GPIO */ +#define PIO_LCD_VSYNC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) /* Type: GPIO */ + +/* High Speed Multimedia Card Interface - HSMCI0-2 */ + +#define PIO_MCI0_CDA (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN0) /* Type: GPIO */ +#define PIO_MCI0_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) /* Type: MCI_CLK */ +#define PIO_MCI0_DA0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN1) /* Type: GPIO */ +#define PIO_MCI0_DA1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN2) /* Type: GPIO */ +#define PIO_MCI0_DA2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN3) /* Type: GPIO */ +#define PIO_MCI0_DA3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN4) /* Type: GPIO */ +#define PIO_MCI0_DA4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) /* Type: GPIO */ +#define PIO_MCI0_DA5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) /* Type: GPIO */ +#define PIO_MCI0_DA6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) /* Type: GPIO */ +#define PIO_MCI0_DA7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) /* Type: GPIO */ + +#define PIO_MCI1_CDA (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) /* Type: GMAC */ +#define PIO_MCI1_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) /* Type: GMAC */ +#define PIO_MCI1_DA0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) /* Type: GMAC */ +#define PIO_MCI1_DA1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) /* Type: GMAC */ +#define PIO_MCI1_DA2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) /* Type: GMAC */ +#define PIO_MCI1_DA3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) /* Type: GMAC */ + +#define PIO_MCI2_CDA (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) /* Type: GPIO */ +#define PIO_MCI2_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) /* Type: MCI_CLK */ +#define PIO_MCI2_DA0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) /* Type: GPIO */ +#define PIO_MCI2_DA1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) /* Type: GPIO */ +#define PIO_MCI2_DA2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) /* Type: GPIO */ +#define PIO_MCI2_DA3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) /* Type: GPIO */ + +/* Clocks, Oscillators and PLLs */ + +#define PIO_PMC_PCK0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN30) /* Type: GPIO_ANA */ +#define PIO_PMC_PCK1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) /* Type: GPIO_ANA */ +#define PIO_PMC_PCK2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) /* Type: MCI_CLK */ + +/* Pulse Width Modulation Controller- PWMC */ + +#define PIO_PWM0_FI (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) /* Type: GPIO */ +#define PIO_PWM0_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) /* Type: GMAC */ +#define PIO_PWM0_H_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) /* Type: GPIO */ +#define PIO_PWM0_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) /* Type: GMAC */ +#define PIO_PWM0_L_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) /* Type: GPIO */ + +#define PIO_PWM1_FI (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) /* Type: GPIO */ +#define PIO_PWM1_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) /* Type: GMAC */ +#define PIO_PWM1_H_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) /* Type: GPIO */ +#define PIO_PWM1_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) /* Type: GMAC */ +#define PIO_PWM1_L_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN31) /* Type: EBI */ +#define PIO_PWM1_L_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) /* Type: GPIO */ + +#define PIO_PWM2_FI (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) /* Type: GPIO */ +#define PIO_PWM2_H_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) /* Type: GPIO */ +#define PIO_PWM2_H_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) /* Type: GMAC */ +#define PIO_PWM2_L_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) /* Type: GPIO */ +#define PIO_PWM2_L_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) /* Type: GMAC */ + +#define PIO_PWM3_FI (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) /* Type: GPIO */ +#define PIO_PWM3_H_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) /* Type: GPIO */ +#define PIO_PWM3_H_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) /* Type: GMAC */ +#define PIO_PWM3_L_1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) /* Type: GPIO */ +#define PIO_PWM3_L_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) /* Type: GMAC */ + +/* Serial Peripheral Interface - SPIx [1..0] */ + +#define PIO_SPI0_MISO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) /* Type: GPIO */ +#define PIO_SPI0_MOSI (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) /* Type: GPIO */ +#define PIO_SPI0_NPCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) /* Type: GPIO */ +#define PIO_SPI0_NPCS1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) /* Type: GPIO */ +#define PIO_SPI0_NPCS2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) /* Type: GPIO */ +#define PIO_SPI0_NPCS3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) /* Type: GPIO */ +#define PIO_SPI0_SPCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) /* Type: GPIO_CLK */ + +#define PIO_SPI1_MISO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) /* Type: GPIO */ +#define PIO_SPI1_MOSI (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) /* Type: GPIO */ +#define PIO_SPI1_NPCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) /* Type: GPIO */ +#define PIO_SPI1_NPCS1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) /* Type: GPIO */ +#define PIO_SPI1_NPCS2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) /* Type: GPIO */ +#define PIO_SPI1_NPCS3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) /* Type: GPIO */ +#define PIO_SPI1_SPCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) /* Type: GPIO_CLK */ + +/* Synchronous Serial Controller - SSCx [1..0] */ + +#define PIO_SSC0_RD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) /* Type: GPIO */ +#define PIO_SSC0_RF (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) /* Type: GPIO */ +#define PIO_SSC0_RK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) /* Type: GPIO */ +#define PIO_SSC0_TD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) /* Type: GPIO */ +#define PIO_SSC0_TF (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) /* Type: GPIO */ +#define PIO_SSC0_TK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) /* Type: GPIO */ + +#define PIO_SSC1_RD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) /* Type: GMAC */ +#define PIO_SSC1_RF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) /* Type: GMAC */ +#define PIO_SSC1_RK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) /* Type: GMAC */ +#define PIO_SSC1_TD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) /* Type: GMAC */ +#define PIO_SSC1_TF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) /* Type: GMAC */ +#define PIO_SSC1_TK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) /* Type: GMAC */ + +/* Timer/Counter - TCx [5..0] */ + +#define PIO_TC0_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN7) /* Type: GPIO */ +#define PIO_TC0_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN5) /* Type: GPIO */ +#define PIO_TC0_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN6) /* Type: GPIO */ + +#define PIO_TC1_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) /* Type: GPIO */ +#define PIO_TC1_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) /* Type: GPIO */ +#define PIO_TC1_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) /* Type: GPIO */ + +#define PIO_TC2_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) /* Type: EBI */ +#define PIO_TC2_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) /* Type: EBI */ +#define PIO_TC2_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) /* Type: EBI */ + +#define PIO_TC3_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) /* Type: GPIO */ +#define PIO_TC3_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) /* Type: GPIO */ +#define PIO_TC3_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) /* Type: GPIO */ + +#define PIO_TC4_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) /* Type: GPIO */ +#define PIO_TC4_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) /* Type: GPIO */ +#define PIO_TC4_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) /* Type: GPIO */ + +#define PIO_TC5_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) /* Type: GPIO */ +#define PIO_TC5_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) /* Type: GPIO */ +#define PIO_TC5_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) /* Type: GPIO */ + +/* Two-Wire Interface -TWIx [2..0] */ + +#define PIO_TWI0_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) /* Type: GPIO */ +#define PIO_TWI0_D (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) /* Type: GPIO */ + +#define PIO_TWI1_CK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) /* Type: GPIO */ +#define PIO_TWI1_D (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) /* Type: GPIO */ + +#define PIO_TWI2_CK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) /* Type: GPIO */ +#define PIO_TWI2_D (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) /* Type: GPIO */ + +/* Universal Asynchronous Receiver Transmitter - UARTx [1..0] */ + +#define PIO_UART0_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) /* Type: GPIO */ +#define PIO_UART0_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) /* Type: GPIO */ + +#define PIO_UART1_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) /* Type: GPIO */ +#define PIO_UART1_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) /* Type: GPIO */ + +/* Universal Synchronous Asynchronous Receiver Transmitter- USART0-3 */ + +#define PIO_USART0_CTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) /* Type: GPIO */ +#define PIO_USART0_RTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) /* Type: GPIO */ +#define PIO_USART0_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) /* Type: GPIO */ +#define PIO_USART0_SCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) /* Type: GPIO */ +#define PIO_USART0_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) /* Type: GPIO */ + +#define PIO_USART1_CTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) /* Type: GMAC */ +#define PIO_USART1_RTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) /* Type: GPIO */ +#define PIO_USART1_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) /* Type: GPIO */ +#define PIO_USART1_SCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) /* Type: GMAC */ +#define PIO_USART1_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) /* Type: GPIO */ + +#define PIO_USART2_CTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN23) /* Type: EBI */ +#define PIO_USART2_RTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN24) /* Type: EBI */ +#define PIO_USART2_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN25) /* Type: EBI */ +#define PIO_USART2_SCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN20) /* Type: EBI */ +#define PIO_USART2_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN26) /* Type: EBI */ + +#define PIO_USART3_CTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN16) /* Type: EBI */ +#define PIO_USART3_RTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN17) /* Type: EBI */ +#define PIO_USART3_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN18) /* Type: EBI */ +#define PIO_USART3_SCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN15) /* Type: EBI */ +#define PIO_USART3_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN19) /* Type: EBI */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D3X_PINMAP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d4x_memorymap.h b/arch/arm/src/sama5/chip/_sama5d4x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..46c203a29362a3d9a42f455c7310782fb912bfd2 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d4x_memorymap.h @@ -0,0 +1,805 @@ +/************************************************************************************ + * arch/arm/src/sama5/_sama5d4x_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + +/* Overview: + * + * SAMA5 Physical (unmapped) Memory Map + * - SAMA5 Internal Memories + * - SAMA5 Internal Peripheral Offsets + * - System Controller Peripheral Offsets + * Sizes of memory regions in bytes + * Sizes of memory regions in sections + * Section MMU Flags + * SAMA5 Virtual (mapped) Memory Map + * - Peripheral virtual base addresses + * - NuttX virtual base address + * MMU Page Table Location + * Page table start addresses + * Base address of the interrupt vector table + */ + +/* SAMA5 Physical (unmapped) Memory Map */ + +#define SAM_INTMEM_PSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_EBICS0_PSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip Select 0 */ +#define SAM_DDRCS_PSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDR Chip Select */ +#define SAM_EBICS1_PSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip Select 1 */ +#define SAM_EBICS2_PSECTION 0x70000000 /* 0x70000000-0x7fffffff: EBI Chip Select 2 */ +#define SAM_EBICS3_PSECTION 0x80000000 /* 0x80000000-0x8fffffff: EBI Chip Select 3 */ +#define SAM_NFCCR_PSECTION 0x90000000 /* 0x90000000-0x9fffffff: NFC Command Registers */ + /* 0x80000000-0xefffffff: Undefined */ +#define SAM_PERIPH_PSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ + +/* SAMA5 Internal Memories */ + +#define SAM_BOOTMEM_PSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ +#define SAM_ROM_PSECTION 0x00000000 /* 0x00000000-0x000fffff: ROM */ +#define SAM_NFCSRAM_PSECTION 0x00100000 /* 0x00100000-0x001fffff: NFC SRAM */ +#define SAM_ISRAM_PSECTION 0x00200000 /* 0x00200000-0x0020ffff: SRAM */ +# define SAM_ISRAM0_PADDR 0x00200000 /* 0x00200000-0x0020ffff: SRAM0 */ +# define SAM_ISRAM1_PADDR 0x00210000 /* 0x00210000-0x002fffff: SRAM1 */ +#define SAM_VDEC_PSECTION 0x00300000 /* 0x00300000-0x0030ffff: VDEC */ +#define SAM_UDPHSRAM_PSECTION 0x00400000 /* 0x00400000-0x004fffff: UDPH SRAM */ +#define SAM_UHPOHCI_PSECTION 0x00500000 /* 0x00500000-0x005fffff: UHP OHCI */ +#define SAM_UHPEHCI_PSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP EHCI */ +#define SAM_AXIMX_PSECTION 0x00700000 /* 0x00700000-0x007fffff: AXI Matr */ +#define SAM_DAP_PSECTION 0x00800000 /* 0x00800000-0x008fffff: DAP */ +#define SAM_SMD_PSECTION 0x00900000 /* 0x00900000-0x009fffff: SMD */ +#define SAM_L2CC_PSECTION 0x00a00000 /* 0x00a00000-0x00afffff: L2CC */ + /* 0x00a00000-0x0fffffff: Undefined */ +/* SAMA5 Internal Peripheral Offsets */ + +#define SAM_PERIPHA_PSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */ +# define SAM_LCDC_OFFSET 0x00000000 /* 0x00000000-0x00003fff: LCDC */ +# define SAM_XDMAC1_OFFSET 0x00004000 /* 0x00004000-0x00007fff: XDMAC1 */ +# define SAM_ISI_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: ISI */ +# define SAM_PKCC_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: PKCC */ +# define SAM_MPDDRC_OFFSET 0x00010000 /* 0x00010000-0x00013fff: MPDDRC */ +# define SAM_XDMAC0_OFFSET 0x00014000 /* 0x00014000-0x00017fff: XDMAC0 */ +# define SAM_PMC_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: PMC */ +# define SAM_MATRIX64_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: MATRIX64 */ +# define SAM_AESB_OFFSET 0x00020000 /* 0x00020000-0x00023fff: AESB */ + +#define SAM_PERIPHB_PSECTION 0xf8000000 /* 0xf8000000-0xffffbfff: Internal Peripherals B */ +# define SAM_HSMCI0_OFFSET 0x00000000 /* 0x00000000-0x00003fff: HSMCI0 */ +# define SAM_UART0_OFFSET 0x00004000 /* 0x00004000-0x00007fff: UART0 */ +# define SAM_SSC0_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: SSC0 */ +# define SAM_PWMC_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: PWMC */ +# define SAM_SPI0_OFFSET 0x00010000 /* 0x00010000-0x00013fff: SPI0 */ +# define SAM_TWI0_OFFSET 0x00014000 /* 0x00014000-0x00017fff: TWI0 */ +# define SAM_TWI1_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: TWI1 */ +# define SAM_TC012_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: TC channels 0, 1, and 2 */ +# define SAM_EMAC0_OFFSET 0x00020000 /* 0x00020000-0x00023fff: GMAC 0 */ +# define SAM_TWI2_OFFSET 0x00024000 /* 0x00024000-0x00027fff: TWI2 */ +# define SAM_SFR_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: SFR */ +# define SAM_USART0_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: USART0 */ +# define SAM_USART1_OFFSET 0x00030000 /* 0x00030000-0x00033fff: USART1 */ +# define SAM_CATB_OFFSET 0x0003c000 /* 0x0003c000-0x0003ffff: CATB */ + +#define SAM_PERIPHC_PSECTION 0xfc000000 /* 0xfc000000-0xfc06f000: Internal Peripherals C */ +# define SAM_HSMCI1_OFFSET 0x00000000 /* 0x00000000-0x00003fff: HSMCI1 */ +# define SAM_UART1_OFFSET 0x00004000 /* 0x00004000-0x00007fff: UART1 */ +# define SAM_USART2_OFFSET 0x00008000 /* 0x00008000-0x0000bfff: USART2 */ +# define SAM_USART3_OFFSET 0x0000c000 /* 0x0000c000-0x0000ffff: USART3 */ +# define SAM_USART4_OFFSET 0x00010000 /* 0x00010000-0x00013fff: USART4 */ +# define SAM_SSC1_OFFSET 0x00014000 /* 0x00014000-0x00017fff: SSC1 */ +# define SAM_SPI1_OFFSET 0x00018000 /* 0x00018000-0x0001bfff: SPI1 */ +# define SAM_SPI2_OFFSET 0x0001c000 /* 0x0001c000-0x0001ffff: SPI2 */ +# define SAM_TC345_OFFSET 0x00020000 /* 0x00020000-0x00023fff: TC channels 3, 4, and 5 */ +# define SAM_TC678_OFFSET 0x00024000 /* 0x00024000-0x00027fff: TC channels 6, 7, and 8 */ +# define SAM_EMAC1_OFFSET 0x00028000 /* 0x00028000-0x0002bfff: GMAC 1 */ +# define SAM_UDPHS_OFFSET 0x0002c000 /* 0x0002c000-0x0002ffff: UDPHS */ +# define SAM_TRNG_OFFSET 0x00030000 /* 0x00030000-0x0003efff: TRNG */ +# define SAM_ADC_OFFSET 0x00034000 /* 0x00034000-0x00037fff: ADC */ +# define SAM_TWI3_OFFSET 0x00038000 /* 0x00038000-0x0003bfff: TWI3 */ +# define SAM_ICM_OFFSET 0x00040000 /* 0x00040000-0x00043fff: ICM */ +# define SAM_AES_OFFSET 0x00044000 /* 0x00044000-0x00047fff: AES */ +# define SAM_TDES_OFFSET 0x00048000 /* 0x00048000-0x0004bfff: TDES */ +# define SAM_SHA_OFFSET 0x00050000 /* 0x00050000-0x00053fff: SHA */ +# define SAM_MATRIX32_OFFSET 0x00054000 /* 0x00054000-0x00057fff: MATRIX32 */ +# define SAM_HSMC_OFFSET 0x0005c000 /* 0x0005c000-0x0005ffff: SMC */ +# define SAM_SFC_OFFSET 0x00060000 /* 0x00060000-0x00063fff: SFC */ +# define SAM_PIOD_OFFSET 0x00068000 /* 0x00068000-0x0006bfff: PIOD */ +# define SAM_SBM_OFFSET 0x00068200 /* 0x00068200-0x000683ff: SBM */ +# define SAM_SAIC_OFFSET 0x00068400 /* 0x00068400-0x000685ff: SAIC */ +# define SAM_RSTC_OFFSET 0x00068600 /* 0x00068600-0x0006860f: RSTC */ +# define SAM_SHDC_OFFSET 0x00068610 /* 0x00068610-0x0006862f: SHDC */ +# define SAM_PITC_OFFSET 0x00068630 /* 0x00068630-0x0006863f: PITC */ +# define SAM_WDT_OFFSET 0x00068640 /* 0x00068640-0x0006864f: WDTC */ +# define SAM_SCKCR_OFFSET 0x00068650 /* 0x00068650-0x000686af: SCKCR */ +# define SAM_RTCC_OFFSET 0x000686b0 /* 0x000686b0-0x000688cf: RTCC */ +# define SAM_DBGU_OFFSET 0x00069000 /* 0x00069000-0x0006bfff: DBGU */ +# define SAM_PIOA_OFFSET 0x0006a000 /* 0x0006a000-0x0006afff: PIOA */ +# define SAM_PIOB_OFFSET 0x0006b000 /* 0x0006b000-0x0006bfff: PIOB */ +# define SAM_PIOC_OFFSET 0x0006c000 /* 0x0006c000-0x0006cfff: PIOC */ +# define SAM_PIOE_OFFSET 0x0006d000 /* 0x0006d000-0x0006dfff: PIOE */ +# define SAM_AIC_OFFSET 0x0006e000 /* 0x0006e000-0x0006efff: AIC */ + +/* Sizes of memory regions in bytes. + * + * These sizes exclude the undefined addresses at the end of the memory + * region. The implemented sizes of the EBI CS0-3 and DDRCS regions + * are not known apriori and must be specified with configuration settings. + */ + /* 0x00000000-0x0fffffff: Internal Memories */ +#define SAM_BOOTMEM_SIZE (1*1024*1024) /* 0x00000000-0x000fffff: Boot memory */ +#define SAM_ROM_SIZE (1*1024*1024) /* 0x00000000-0x000fffff: ROM */ +#define SAM_NFCSRAM_SIZE (1*1024*1024) /* 0x00100000-0x001fffff: NFC SRAM */ + /* 0x00200000-0x002fffff: SRAM0 and SRAM1 */ +#define SAM_ISRAM_SIZE (64*1024 + SAM_ISRAM1_SIZE) +#define SAM_VDEC_SIZE (1*1024*1024) /* 0x00300000-0x0030ffff: VDEC */ +#define SAM_UDPHSRAM_SIZE (1*1024*1024) /* 0x00400000-0x004fffff: UDPH SRAM */ +#define SAM_UHPOHCI_SIZE (1*1024*1024) /* 0x00500000-0x005fffff: UHP OHCI */ +#define SAM_UHPEHCI_SIZE (1*1024*1024) /* 0x00600000-0x006fffff: UHP EHCI */ +#define SAM_AXIMX_SIZE (4) /* 0x00700000-0x007fffff: AXI Matrix */ +#define SAM_DAP_SIZE (1*1024*1024) /* 0x00800000-0x008fffff: DAP */ +#define SAM_SMD_SIZE (1*1024*1024) /* 0x00900000-0x009fffff: SMD */ +#define SAM_L2CC_SIZE (1*1024*1024) /* 0x00a00000-0x00afffff: L2CC */ +#define SAM_NFCCR_SIZE (256*1024*1024) /* 0x70000000-0x7fffffff: NFC Command Registers */ + /* 0xf0000000-0xffffffff: Internal Peripherals */ +#define SAM_PERIPHA_SIZE (144*1024) /* 0xf0000000-0xf0023fff: Internal Peripherals */ +#define SAM_PERIPHB_SIZE (241*1024) /* 0xf8000000-0xf803c3ff: Internal Peripherals */ +#define SAM_PERIPHC_SIZE (444*1024) /* 0xfc000000-0xfc06efff: Internal Peripherals */ + +/* Force configured sizes that might exceed 2GB to be unsigned long */ + +#define SAMA5_EBICS0_SIZE MKULONG(CONFIG_SAMA5_EBICS0_SIZE) +#define SAMA5_DDRCS_SIZE MKULONG(CONFIG_SAMA5_DDRCS_SIZE) +#define SAMA5_EBICS1_SIZE MKULONG(CONFIG_SAMA5_EBICS1_SIZE) +#define SAMA5_EBICS2_SIZE MKULONG(CONFIG_SAMA5_EBICS2_SIZE) +#define SAMA5_EBICS3_SIZE MKULONG(CONFIG_SAMA5_EBICS3_SIZE) + +#define SAMA5_EBICS0_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS0_HEAP_OFFSET) +#define SAMA5_DDRCS_HEAP_OFFSET MKULONG(CONFIG_SAMA5_DDRCS_HEAP_OFFSET) +#define SAMA5_EBICS1_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS1_HEAP_OFFSET) +#define SAMA5_EBICS2_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS2_HEAP_OFFSET) +#define SAMA5_EBICS3_HEAP_OFFSET MKULONG(CONFIG_SAMA5_EBICS3_HEAP_OFFSET) + +#define SAMA5_EBICS0_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS0_HEAP_SIZE) +#define SAMA5_DDRCS_HEAP_SIZE MKULONG(CONFIG_SAMA5_DDRCS_HEAP_SIZE) +#define SAMA5_EBICS1_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS1_HEAP_SIZE) +#define SAMA5_EBICS2_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS2_HEAP_SIZE) +#define SAMA5_EBICS3_HEAP_SIZE MKULONG(CONFIG_SAMA5_EBICS3_HEAP_SIZE) + +/* Convert size in bytes to number of sections (in Mb). */ + +#define _NSECTIONS(b) (((b)+0x000fffff) >> 20) + +/* Sizes of memory regions in sections. + * + * The boot logic in sam_boot.c, will select 1Mb level 1 MMU mappings to + * span the entire physical address space. The definitions below specify + * the number of 1Mb entries that are required to span a particular address + * region. + */ + +#define SAM_BOOTMEM_NSECTIONS _NSECTIONS(SAM_BOOTMEM_SIZE) +#define SAM_ROM_NSECTIONS _NSECTIONS(SAM_ROM_SIZE) +#define SAM_NFCSRAM_NSECTIONS _NSECTIONS(SAM_NFCSRAM_SIZE) +#define SAM_ISRAM_NSECTIONS _NSECTIONS(SAM_ISRAM_SIZE) +#define SAM_VDEC_NSECTIONS _NSECTIONS(SAM_VDEC_SIZE) +#define SAM_UDPHSRAM_NSECTIONS _NSECTIONS(SAM_UDPHSRAM_SIZE) +#define SAM_UHPOHCI_NSECTIONS _NSECTIONS(SAM_UHPOHCI_SIZE) +#define SAM_UHPEHCI_NSECTIONS _NSECTIONS(SAM_UHPEHCI_SIZE) +#define SAM_AXIMX_NSECTIONS _NSECTIONS(SAM_AXIMX_SIZE) +#define SAM_DAP_NSECTIONS _NSECTIONS(SAM_DAP_SIZE) +#define SAM_SMD_NSECTIONS _NSECTIONS(SAM_SMD_SIZE) +#define SAM_L2CC_NSECTIONS _NSECTIONS(SAM_L2CC_SIZE) + +#define SAM_EBICS0_NSECTIONS _NSECTIONS(SAMA5_EBICS0_SIZE) +#define SAM_DDRCS_NSECTIONS _NSECTIONS(SAMA5_DDRCS_SIZE) +#define SAM_EBICS1_NSECTIONS _NSECTIONS(SAMA5_EBICS1_SIZE) +#define SAM_EBICS2_NSECTIONS _NSECTIONS(SAMA5_EBICS2_SIZE) +#define SAM_EBICS3_NSECTIONS _NSECTIONS(SAMA5_EBICS3_SIZE) +#define SAM_NFCCR_NSECTIONS _NSECTIONS(SAM_NFCCR_SIZE) + +#define SAM_PERIPHA_NSECTIONS _NSECTIONS(SAM_PERIPHA_SIZE) +#define SAM_PERIPHB_NSECTIONS _NSECTIONS(SAM_PERIPHB_SIZE) +#define SAM_PERIPHC_NSECTIONS _NSECTIONS(SAM_PERIPHC_SIZE) + +/* Section MMU Flags */ + +#define SAM_BOOTMEM_MMUFLAGS MMU_ROMFLAGS +#define SAM_ROM_MMUFLAGS MMU_ROMFLAGS +#define SAM_ISRAM_MMUFLAGS MMU_MEMFLAGS +#define SAM_VDEC_MMUFLAGS MMU_IOFLAGS +#define SAM_UDPHSRAM_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPOHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_UHPEHCI_MMUFLAGS MMU_IOFLAGS +#define SAM_AXIMX_MMUFLAGS MMU_IOFLAGS +#define SAM_DAP_MMUFLAGS MMU_IOFLAGS +#define SAM_SMD_MMUFLAGS MMU_MEMFLAGS +#define SAM_L2CC_MMUFLAGS MMU_IOFLAGS + +/* If the NFC is not being used, the NFC SRAM can be used as general purpose + * SRAM (cached). If the NFC is used, then the NFC SRAM should be treated + * as an I/O devices (uncached). + */ + +#ifdef CONFIG_SAMA5_HAVE_NAND +# define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_NFCSRAM_MMUFLAGS MMU_MEMFLAGS +#endif + +/* SDRAM is a special case because it requires non-cached access of its + * initial configuration, then cached access thereafter. + */ + +#define SAM_DDRCS_MMUFLAGS MMU_MEMFLAGS + +/* The external memory regions may support all access if they host SRAM, + * PSRAM, or SDRAM. NAND memory requires write access for NAND control and + * so should be uncached. + */ + +#if defined(CONFIG_SAMA5_EBICS0_SRAM) || defined(CONFIG_SAMA5_EBICS0_PSRAM) || \ + defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS0_NAND) +# define SAM_EBICS0_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS0_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS1_SRAM) || defined(CONFIG_SAMA5_EBICS1_PSRAM) +# define SAM_EBICS1_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS1_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS1_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS2_SRAM) || defined(CONFIG_SAMA5_EBICS2_PSRAM) +# define SAM_EBICS2_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS2_NAND) +# define SAM_EBICS2_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS2_MMUFLAGS MMU_ROMFLAGS +#endif + +#if defined(CONFIG_SAMA5_EBICS3_SRAM) || defined(CONFIG_SAMA5_EBICS3_PSRAM) +# define SAM_EBICS3_MMUFLAGS MMU_MEMFLAGS +#elif defined(CONFIG_SAMA5_EBICS3_NAND) +# define SAM_EBICS3_MMUFLAGS MMU_IOFLAGS +#else +# define SAM_EBICS3_MMUFLAGS MMU_ROMFLAGS +#endif + +#define SAM_NFCCR_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHA_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHB_MMUFLAGS MMU_IOFLAGS +#define SAM_PERIPHC_MMUFLAGS MMU_IOFLAGS + +/* SAMA5 Virtual (mapped) Memory Map + * + * board_memorymap.h contains special mappings that are needed when a ROM + * memory map is used. It is included in this odd location becaue it depends + * on some the virtual address definitions provided above. + */ + +#include + +/* SAMA5 Virtual (mapped) Memory Map. These are the mappings that will + * be created if the page table lies in RAM. If the platform has another, + * read-only, pre-initialized page table (perhaps in ROM), then the board.h + * file must provide these definitions. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + +/* Notice that these mappings are a simple 1-to-1 mapping *unless* + * CONFIG_ARCH_LOWVECTORS is not defined. In the high vector case, the + * register system controls register area is moved out 0f 0xffff:000 where + * the high vectors must reside. + */ + +# define SAM_INTMEM_VSECTION 0x00000000 /* 0x00000000-0x0fffffff: Internal Memories */ +# define SAM_BOOTMEM_VSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ +# define SAM_ROM_VSECTION 0x00000000 /* 0x00000000-0x000fffff: ROM */ +# define SAM_NFCSRAM_VSECTION 0x00100000 /* 0x00100000-0x001fffff: NFC SRAM */ +# define SAM_ISRAM_VSECTION 0x00200000 /* 0x00200000-0x0020ffff: SRAM */ +# define SAM_ISRAM0_VADDR 0x00200000 /* 0x00200000-0x0020ffff: SRAM0 */ +# define SAM_ISRAM1_VADDR 0x00210000 /* 0x00210000-0x002fffff: SRAM1 */ +# define SAM_VDEC_VSECTION 0x00300000 /* 0x00300000-0x0030ffff: VDEC */ +# define SAM_UDPHSRAM_VSECTION 0x00400000 /* 0x00400000-0x004fffff: UDPH SRAM */ +# define SAM_UHPOHCI_VSECTION 0x00500000 /* 0x00500000-0x005fffff: UHP OHCI */ +# define SAM_UHPEHCI_VSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP EHCI */ +# define SAM_AXIMX_VSECTION 0x00700000 /* 0x00700000-0x007fffff: AXI Matr */ +# define SAM_DAP_VSECTION 0x00800000 /* 0x00800000-0x008fffff: DAP */ +# define SAM_SMD_VSECTION 0x00900000 /* 0x00900000-0x009fffff: SMD */ +# define SAM_L2CC_VSECTION 0x00a00000 /* 0x00a00000-0x00afffff: L2CC */ +# define SAM_EBICS0_VSECTION 0x10000000 /* 0x10000000-0x1fffffff: EBI Chip Select 0 */ +# define SAM_DDRCS_VSECTION 0x20000000 /* 0x20000000-0x3fffffff: EBI DDR Chip Select */ +# define SAM_EBICS1_VSECTION 0x60000000 /* 0x60000000-0x6fffffff: EBI Chip Select 1 */ +# define SAM_EBICS2_VSECTION 0x70000000 /* 0x70000000-0x7fffffff: EBI Chip Select 2 */ +# define SAM_EBICS3_VSECTION 0x80000000 /* 0x80000000-0x8fffffff: EBI Chip Select 3 */ +# define SAM_NFCCR_VSECTION 0x90000000 /* 0x90000000-0x9fffffff: NFC Command Registers */ +# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf0023fff: Internal Peripherals A */ +# define SAM_PERIPHB_VSECTION 0xf8000000 /* 0xf8000000-0xf803c3ff: Internal Peripherals B */ +# define SAM_PERIPHC_VSECTION 0xfc000000 /* 0xfc000000-0xfc06efff: Internal Peripherals C */ +#endif /* !CONFIG_ARCH_ROMPGTABLE */ + +/* Peripheral virtual base addresses */ + +#define SAM_LCDC_VBASE (SAM_PERIPHA_VSECTION+SAM_LCDC_OFFSET) +#define SAM_XDMAC1_VBASE (SAM_PERIPHA_VSECTION+SAM_XDMAC1_OFFSET) +#define SAM_ISI_VBASE (SAM_PERIPHA_VSECTION+SAM_ISI_OFFSET) +#define SAM_PKCC_VBASE (SAM_PERIPHA_VSECTION+SAM_PKCC_OFFSET) +#define SAM_MPDDRC_VBASE (SAM_PERIPHA_VSECTION+SAM_MPDDRC_OFFSET) +#define SAM_XDMAC0_VBASE (SAM_PERIPHA_VSECTION+SAM_XDMAC0_OFFSET) +#define SAM_PMC_VBASE (SAM_PERIPHA_VSECTION+SAM_PMC_OFFSET) +#define SAM_MATRIX64_VBASE (SAM_PERIPHA_VSECTION+SAM_MATRIX64_OFFSET) +#define SAM_AESB_VBASE (SAM_PERIPHA_VSECTION+SAM_AESB_OFFSET) + +#define SAM_HSMCI0_VBASE (SAM_PERIPHB_VSECTION+SAM_HSMCI0_OFFSET) +#define SAM_UART0_VBASE (SAM_PERIPHB_VSECTION+SAM_UART0_OFFSET) +#define SAM_SSC0_VBASE (SAM_PERIPHB_VSECTION+SAM_SSC0_OFFSET) +#define SAM_PWMC_VBASE (SAM_PERIPHB_VSECTION+SAM_PWMC_OFFSET) +#define SAM_SPI0_VBASE (SAM_PERIPHB_VSECTION+SAM_SPI0_OFFSET) +#define SAM_TWI0_VBASE (SAM_PERIPHB_VSECTION+SAM_TWI0_OFFSET) +#define SAM_TWI1_VBASE (SAM_PERIPHB_VSECTION+SAM_TWI1_OFFSET) +#define SAM_TC012_VBASE (SAM_PERIPHB_VSECTION+SAM_TC012_OFFSET) +#define SAM_EMAC0_VBASE (SAM_PERIPHB_VSECTION+SAM_EMAC0_OFFSET) +#define SAM_TWI2_VBASE (SAM_PERIPHB_VSECTION+SAM_TWI2_OFFSET) +#define SAM_SFR_VBASE (SAM_PERIPHB_VSECTION+SAM_SFR_OFFSET) +#define SAM_USART0_VBASE (SAM_PERIPHB_VSECTION+SAM_USART0_OFFSET) +#define SAM_USART1_VBASE (SAM_PERIPHB_VSECTION+SAM_USART1_OFFSET) +#define SAM_CATB_VBASE (SAM_PERIPHB_VSECTION+SAM_CATB_OFFSET) + +#define SAM_HSMCI1_VBASE (SAM_PERIPHC_VSECTION+SAM_HSMCI1_OFFSET) +#define SAM_UART1_VBASE (SAM_PERIPHC_VSECTION+SAM_UART1_OFFSET) +#define SAM_USART2_VBASE (SAM_PERIPHC_VSECTION+SAM_USART2_OFFSET) +#define SAM_USART3_VBASE (SAM_PERIPHC_VSECTION+SAM_USART3_OFFSET) +#define SAM_USART4_VBASE (SAM_PERIPHC_VSECTION+SAM_USART4_OFFSET) +#define SAM_SSC1_VBASE (SAM_PERIPHC_VSECTION+SAM_SSC1_OFFSET) +#define SAM_SPI1_VBASE (SAM_PERIPHC_VSECTION+SAM_SPI1_OFFSET) +#define SAM_SPI2_VBASE (SAM_PERIPHC_VSECTION+SAM_SPI2_OFFSET) +#define SAM_TC345_VBASE (SAM_PERIPHC_VSECTION+SAM_TC345_OFFSET) +#define SAM_TC678_VBASE (SAM_PERIPHC_VSECTION+SAM_TC678_OFFSET) +#define SAM_EMAC1_VBASE (SAM_PERIPHC_VSECTION+SAM_EMAC1_OFFSET) +#define SAM_UDPHS_VBASE (SAM_PERIPHC_VSECTION+SAM_UDPHS_OFFSET) +#define SAM_TRNG_VBASE (SAM_PERIPHC_VSECTION+SAM_TRNG_OFFSET) +#define SAM_ADC_VBASE (SAM_PERIPHC_VSECTION+SAM_ADC_OFFSET) +#define SAM_TWI3_VBASE (SAM_PERIPHC_VSECTION+SAM_TWI3_OFFSET) +#define SAM_ICM_VBASE (SAM_PERIPHC_VSECTION+SAM_ICM_OFFSET) +#define SAM_AES_VBASE (SAM_PERIPHC_VSECTION+SAM_AES_OFFSET) +#define SAM_TDES_VBASE (SAM_PERIPHC_VSECTION+SAM_TDES_OFFSET) +#define SAM_SHA_VBASE (SAM_PERIPHC_VSECTION+SAM_SHA_OFFSET) +#define SAM_MATRIX32_VBASE (SAM_PERIPHC_VSECTION+SAM_MATRIX32_OFFSET) +#define SAM_HSMC_VBASE (SAM_PERIPHC_VSECTION+SAM_HSMC_OFFSET) +#define SAM_SFC_VBASE (SAM_PERIPHC_VSECTION+SAM_SFC_OFFSET) +#define SAM_PIOD_VBASE (SAM_PERIPHC_VSECTION+SAM_PIOD_OFFSET) +#define SAM_SBM_VBASE (SAM_PERIPHC_VSECTION+SAM_SBM_OFFSET) +#define SAM_SAIC_VBASE (SAM_PERIPHC_VSECTION+SAM_SAIC_OFFSET) +#define SAM_RSTC_VBASE (SAM_PERIPHC_VSECTION+SAM_RSTC_OFFSET) +#define SAM_SHDC_VBASE (SAM_PERIPHC_VSECTION+SAM_SHDC_OFFSET) +#define SAM_PITC_VBASE (SAM_PERIPHC_VSECTION+SAM_PITC_OFFSET) +#define SAM_WDT_VBASE (SAM_PERIPHC_VSECTION+SAM_WDT_OFFSET) +#define SAM_SCKCR_VBASE (SAM_PERIPHC_VSECTION+SAM_SCKCR_OFFSET) +#define SAM_RTCC_VBASE (SAM_PERIPHC_VSECTION+SAM_RTCC_OFFSET) +#define SAM_DBGU_VBASE (SAM_PERIPHC_VSECTION+SAM_DBGU_OFFSET) +#define SAM_PIOA_VBASE (SAM_PERIPHC_VSECTION+SAM_PIOA_OFFSET) +#define SAM_PIOB_VBASE (SAM_PERIPHC_VSECTION+SAM_PIOB_OFFSET) +#define SAM_PIOC_VBASE (SAM_PERIPHC_VSECTION+SAM_PIOC_OFFSET) +#define SAM_PIOE_VBASE (SAM_PERIPHC_VSECTION+SAM_PIOE_OFFSET) +#define SAM_AIC_VBASE (SAM_PERIPHC_VSECTION+SAM_AIC_OFFSET) + +/* NuttX virtual base address + * + * The boot logic will create a temporarily mapping based on where NuttX is + * executing in memory. In this case, NuttX could be running from NOR FLASH, + * SDRAM, external SRAM, or internal SRAM. If we are running from FLASH, + * then we must have a separate mapping for the non-contiguous RAM region. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) + +/* Some sanity checks. If we are running from FLASH, then one of the + * external chip selects must be configured to boot from NOR flash. + * And, if so, then its size must agree with the configured size. + */ + +# if defined(CONFIG_SAMA5_EBICS0) && defined(CONFIG_SAMA5_EBICS0_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS0FLASH) + +# if CONFIG_SAMA5_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS0 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS1) && defined(CONFIG_SAMA5_EBICS1_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS1FLASH) + +# if CONFIG_SAMA5_EBICS1_SIZE != CONFIG_FLASH_SIZE +# error CS1 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS2) && defined(CONFIG_SAMA5_EBICS2_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS2FLASH) + +# if CONFIG_SAMA2_EBICS0_SIZE != CONFIG_FLASH_SIZE +# error CS2 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# elif defined(CONFIG_SAMA5_EBICS3) && defined(CONFIG_SAMA5_EBICS3_NOR) && \ + defined (CONFIG_SAMA5_BOOT_CS3FLASH) + +# if CONFIG_SAMA5_EBICS3_SIZE != CONFIG_FLASH_SIZE +# error CS3 FLASH size disagreement +# endif + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH + +# else +# error CONFIG_BOOT_RUNFROMFLASH=y, but no bootable NOR flash defined + +# undef CONFIG_SAMA5_BOOT_CS0FLASH +# undef CONFIG_SAMA5_BOOT_CS1FLASH +# undef CONFIG_SAMA5_BOOT_CS2FLASH +# undef CONFIG_SAMA5_BOOT_CS3FLASH + +# endif + + /* Set up the NOR FLASH region as the NUTTX .text region */ + +# define NUTTX_TEXT_VADDR (CONFIG_FLASH_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_FLASH_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_FLASH_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + + /* In the default configuration, the primary RAM use for .bss and .data + * is the internal SRAM. + */ + +# define NUTTX_RAM_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_RAM_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_RAM_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_RAM_SIZE (NUTTX_RAM_PEND - NUTTX_RAM_PADDR) + +#else /* CONFIG_BOOT_RUNFROMFLASH */ + + /* Otherwise we are running from some kind of RAM (ISRAM or SDRAM). + * Setup the RAM region as the NUTTX .txt, .bss, and .data region. + */ + +# define NUTTX_TEXT_VADDR (CONFIG_RAM_VSTART & 0xfff00000) +# define NUTTX_TEXT_PADDR (CONFIG_RAM_START & 0xfff00000) +# define NUTTX_TEXT_PEND ((CONFIG_RAM_END + 0x000fffff) & 0xfff00000) +# define NUTTX_TEXT_SIZE (NUTTX_TEXT_PEND - NUTTX_TEXT_PADDR) + +#endif /* CONFIG_BOOT_RUNFROMFLASH */ + +/* MMU Page Table Location + * + * Determine the address of the MMU page table. Regardless of the memory + * configuration, we will keep the page table in the SAMA5's internal SRAM. + * We will always attempt to use the bottom 16KB of internal SRAM for the + * page table, but there are a few conditions that affect this: + * + * 1) If CONFIG_ARCH_ROMPGTABLE, then the page table resides in ROM and we + * will not use any page table in RAM. + * 2) We are executing out of SRAM. In this case, vectors will reside at + * the bottom of SRAM, following by .text, .data, .bss, and heep. The + * page table will be squeezed into the end of internal SRAM in this + * case. + * + * Or... the user may specify the address of the page table explicitly be defining + * PGTABLE_BASE_VADDR and PGTABLE_BASE_PADDR in the board.h file. + */ + +#undef PGTABLE_IN_HIGHSRAM +#undef PGTABLE_IN_LOWSRAM +#undef ARMV7A_PGTABLE_MAPPING + +#if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) + + /* Sanity check.. if one is undefined, both should be undefined */ + +# if defined(PGTABLE_BASE_PADDR) || defined(PGTABLE_BASE_VADDR) +# error "Only one of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is defined" +# endif + + /* A sanity check, if the configuration says that the page table is read-only + * and pre-initialized (maybe ROM), then it should have also defined both of + * the page table base addresses. + */ + +# ifdef CONFIG_ARCH_ROMPGTABLE +# error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. In that case PGTABLE_BASE_VADDR is defined + * in the file mmu.h + * + * We must declare the page table at the bottom or at the top of internal + * SRAM. We pick the bottom of internal SRAM *unless* there are vectors + * in the way at that position. + */ + +# if defined(CONFIG_SAMA5_BOOT_ISRAM) && defined(CONFIG_ARCH_LOWVECTORS) + + /* In this case, page table must lie at the top 16Kb of ISRAM1 (or ISRAM0 + * if ISRAM1 is not available in this architecture) + * + * If CONFIG_PAGING is defined, then mmu.h assign the virtual address + * of the page table. + */ + +# if SAM_ISRAM1_SIZE > 0 +# define PGTABLE_BASE_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# endif +# else +# define PGTABLE_BASE_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# endif +# endif +# define PGTABLE_IN_HIGHSRAM 1 + + /* If we execute from SRAM, but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the vector table, + * lying between the vector table and the page table. We don't really + * know how much memory to set aside for the vector table, but 4KiB should + * be much more than enough + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + 0x0001000) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + 0x0001000) +# endif + +# else /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps + * elsewhere in internal SRAM). The page table will then be positioned at + * the first 16Kb of ISRAM0. + */ + +# define PGTABLE_BASE_PADDR SAM_ISRAM0_PADDR +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR SAM_ISRAM0_VADDR +# endif +# define PGTABLE_IN_LOWSRAM 1 + + /* If we execute from SRAM, but keep data in SDRAM, then we will also have + * to position the initial, IDLE stack in SRAM. SDRAM will not be ready + * soon enough to serve as the stack. + * + * In this case, the initial IDLE stack can just follow the page table + * in ISRAM. + */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) +# endif + +# endif /* CONFIG_SAMA5_BOOT_ISRAM && CONFIG_ARCH_LOWVECTORS */ + + /* In either case, the page table lies in ISRAM. If ISRAM is not the + * primary RAM region, then we will need to set-up a special mapping for + * the page table at boot time. + */ + +# if defined(CONFIG_BOOT_RUNFROMFLASH) + /* If we are running from FLASH, than the primary memory region is + * given by NUTTX_RAM_PADDR. + */ + +# if NUTTX_RAM_PADDR != SAM_ISRAM_PSECTION +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +/* Otherwise, we are running from RAM and that RAM is also the primary + * RAM. + */ + +# elif !defined(CONFIG_SAMA5_BOOT_ISRAM) +# define ARMV7A_PGTABLE_MAPPING 1 +# endif + +#else /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + + /* Sanity check.. if one is defined, both should be defined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "One of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is undefined" +# endif + + /* If data is in SDRAM, then the IDLE stack at the beginning of ISRAM */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + PGTABLE_SIZE) +# endif + +#endif /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + +/* Level 2 Page table start addresses. + * + * 16Kb of memory is reserved hold the page table for the virtual mappings. A + * portion of this table is not accessible in the virtual address space (for + * normal operation). There is this large whole in the physcal address space + * for which there will never be level 1 mappings: + * + * 0x80000000-0xefffffff: Undefined (1.75 GB) + * + * That is the offset where the main L2 page tables will be positioned. This + * corresponds to page table offsets 0x000002000 up to 0x000003c00. That + * is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual + * address space) + * + * Up to two L2 page tables may be used: + * + * 1) One mapping the vector table. However, L2 page tables must be aligned + * to 1KB address boundaries, so the minimum L2 page table size is then + * 1KB, mapping up a full megabyte of virtual address space. + * + * This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not* + * defined. The SAMA5 boot-up logic will map the beginning of the boot + * memory to address 0x0000:0000 using both the MMU and the AXI matrix + * REMAP register. So no L2 page table is required. + * + * 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional + * L2 page table is needed. This page table will use the remainder of + * the address space. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + /* Vector L2 page table offset/size */ + +# define VECTOR_L2_OFFSET 0x000002000 +# define VECTOR_L2_SIZE 0x000000400 + + /* Vector L2 page table base addresses */ + +# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET) +# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET) + + /* Vector L2 page table end addresses */ + +# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE) +# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE) + + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002400 +# define PGTABLE_L2_SIZE 0x000001800 + +#else + /* Paging L2 page table offset/size */ + +# define PGTABLE_L2_OFFSET 0x000002000 +# define PGTABLE_L2_SIZE 0x000001c00 +#endif /* CONFIG_ARCH_LOWVECTORS */ + +/* Paging L2 page table base addresses + * + * NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual + * address of the page table. + */ + +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +/* Paging L2 page table end addresses */ + +#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE) +#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE) + +/* Base address of the interrupt vector table. + * + * SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * SAM_VECTOR_VSRAM - Virtual address of vector table in SRAM + * SAM_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + +#define VECTOR_TABLE_SIZE 0x00010000 + +#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + +# define SAM_VECTOR_PADDR SAM_ISRAM0_PADDR +# define SAM_VECTOR_VSRAM SAM_ISRAM0_VADDR +# define SAM_VECTOR_VADDR 0x00000000 + +#else /* Vectors located at 0xffff:0000 -- this probably does not work */ + +# ifdef SAM_ISRAM1_SIZE >= VECTOR_TABLE_SIZE +# define SAM_VECTOR_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# else +# define SAM_VECTOR_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# endif +# define SAM_VECTOR_VADDR 0xffff0000 + +#endif /* CONFIG_ARCH_LOWVECTORS */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MEMORYMAP_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d4x_mpddrc.h b/arch/arm/src/sama5/chip/_sama5d4x_mpddrc.h new file mode 100644 index 0000000000000000000000000000000000000000..24880165bf7a0a47d252c5dfe05059a4745d36ac --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d4x_mpddrc.h @@ -0,0 +1,690 @@ +/******************************************************************************************** + * arch/arm/src/sama5/chip/_sama5d4x_mpddrc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MPDDRC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MPDDRC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* MPDDRC Register Offsets ******************************************************************/ + +#define SAM_MPDDRC_MR_OFFSET 0x0000 /* MPDDRC Mode Register */ +#define SAM_MPDDRC_RTR_OFFSET 0x0004 /* MPDDRC Refresh Timer Register */ +#define SAM_MPDDRC_CR_OFFSET 0x0008 /* MPDDRC Configuration Register */ +#define SAM_MPDDRC_TPR0_OFFSET 0x000c /* MPDDRC Timing Parameter 0 Register */ +#define SAM_MPDDRC_TPR1_OFFSET 0x0010 /* MPDDRC Timing Parameter 1 Register */ +#define SAM_MPDDRC_TPR2_OFFSET 0x0014 /* MPDDRC Timing Parameter 2 Register */ + /* 0x0018 Reserved */ +#define SAM_MPDDRC_LPR_OFFSET 0x001c /* MPDDRC Low-power Register */ +#define SAM_MPDDRC_MD_OFFSET 0x0020 /* MPDDRC Memory Device Register */ + /* 0x0024 Reserved */ +#define SAM_MPDDRC_LPDDR2_LPR_OFFSET 0x0028 /* MPDDRC LPDDR2 Low-power Register */ +#define SAM_MPDDRC_LPDDR2_CALMR4_OFFSET 0x002c /* MPDDRC LPDDR2 Calibration and MR4 Register */ +#define SAM_MPDDRC_LPDDR2_TIMCAL_OFFSET 0x0030 /* MPDDRC LPDDR2 Timing Calibration Register */ +#define SAM_MPDDRC_IO_CALIBR_OFFSET 0x0034 /* MPDDRC IO Calibration */ +#define SAM_MPDDRC_OCMS_OFFSET 0x0038 /* MPDDRC OCMS Register */ +#define SAM_MPDDRC_OCMS_KEY1_OFFSET 0x003c /* MPDDRC OCMS KEY1 Register */ +#define SAM_MPDDRC_OCMS_KEY2_OFFSET 0x0040 /* MPDDRC OCMS KEY2 Register */ +#define SAM_MPDDRC_CONF_ARBITER_OFFSET 0x0044 /* MPDDRC Configuration Arbiter Register */ +#define SAM_MPDDRC_TIMEOUT_OFFSET 0x0048 /* MPDDRC Time-out Port 0/1/2/3 Register */ +#define SAM_MPDDRC_REQ_PORT_0123_OFFSET 0x004c /* MPDDRC Request Port 0/1/2/3 Register */ +#define SAM_MPDDRC_REQ_PORT_4567_OFFSET 0x0050 /* MPDDRC Request Port 4/5/6/7 Register */ +#define SAM_MPDDRC_BDW_PORT_0123_OFFSET 0x0054 /* MPDDRC Bandwidth Port 0/1/2/3 Register */ +#define SAM_MPDDRC_BDW_PORT_4567_OFFSET 0x0058 /* MPDDRC Bandwidth Port 4/5/6/7 Register */ +#define SAM_MPDDRC_RD_DATA_PATH_OFFSET 0x005c /* MPDDRC Read Datapath Register */ + +#define SAM_MPPDRC_SAW_OFFSET(n) (0x0060+((n) << 2)) +#define SAM_MPDDRC_SAW0_OFFSET 0x0060 /* MPDDRC Smart Adaptation Wrapper 0 Register */ +#define SAM_MPDDRC_SAW1_OFFSET 0x0064 /* MPDDRC Smart Adaptation Wrapper 1 Register */ +#define SAM_MPDDRC_SAW2_OFFSET 0x0068 /* MPDDRC Smart Adaptation Wrapper 2 Register */ +#define SAM_MPDDRC_SAW3_OFFSET 0x006c /* MPDDRC Smart Adaptation Wrapper 3 Register */ + /* 0x0060-0x00e0 Reserved */ +#define SAM_MPDDRC_WPCR_OFFSET 0x00e4 /* MPDDRC Write Protect Control Register */ +#define SAM_MPDDRC_WPSR_OFFSET 0x00e8 /* MPDDRC Write Protect Status Register */ + +#define SAM_MPDDRC_DLL_OS_OFFSET 0x0100 /* MPDDRC DLL Offset Selection Register */ +#define SAM_MPDDRC_DLL_MO_OFFSET 0x0104 /* MPDDRC DLL MASTER Offset Register */ +#define SAM_MPDDRC_DLL_SO0_OFFSET 0x0108 /* MPDDRC DLL SLAVE Offset 0 Register */ +#define SAM_MPDDRC_DLL_SO1_OFFSET 0x010c /* MPDDRC DLL SLAVE Offset 1 Register */ +#define SAM_MPDDRC_DLL_WRO_OFFSET 0x0110 /* MPDDRC DLL CLKWR Offset Register */ +#define SAM_MPDDRC_DLL_ADO_OFFSET 0x0114 /* MPDDRC DLL CLKAD Offset Register */ + +#define SAM_MPDDRC_DLL_SM_OFFSET(n) (0x0118+((n)<<2)) +#define SAM_MPDDRC_DLL_SM0_OFFSET 0x0118 /* MPDDRC DLL Status MASTER0 Register */ +#define SAM_MPDDRC_DLL_SM1_OFFSET 0x011c /* MPDDRC DLL Status MASTER1 Register */ +#define SAM_MPDDRC_DLL_SM2_OFFSET 0x0120 /* MPDDRC DLL Status MASTER2 Register */ +#define SAM_MPDDRC_DLL_SM3_OFFSET 0x0124 /* MPDDRC DLL Status MASTER3 Register */ + +#define SAM_MPDDRC_DLL_SSL_OFFSET(n) (0x0128+((n)<<2)) +#define SAM_MPDDRC_DLL_SSL0_OFFSET 0x0128 /* MPDDRC DLL Status SLAVE0 Register */ +#define SAM_MPDDRC_DLL_SSL1_OFFSET 0x012c /* MPDDRC DLL Status SLAVE1 Register */ +#define SAM_MPDDRC_DLL_SSL2_OFFSET 0x0130 /* MPDDRC DLL Status SLAVE2 Register */ +#define SAM_MPDDRC_DLL_SSL3_OFFSET 0x0134 /* MPDDRC DLL Status SLAVE3 Register */ +#define SAM_MPDDRC_DLL_SSL4_OFFSET 0x0138 /* MPDDRC DLL Status SLAVE4 Register */ +#define SAM_MPDDRC_DLL_SSL5_OFFSET 0x013c /* MPDDRC DLL Status SLAVE5 Register */ +#define SAM_MPDDRC_DLL_SSL6_OFFSET 0x0140 /* MPDDRC DLL Status SLAVE6 Register */ +#define SAM_MPDDRC_DLL_SSL7_OFFSET 0x0144 /* MPDDRC DLL Status SLAVE7 Register */ + +#define SAM_MPDDRC_DLL_SWR_OFFSET(n) (0x0148+((n)<<2)) +#define SAM_MPDDRC_DLL_SWR0_OFFSET 0x0148 /* MPDDRC DLL Status CLKWR0 Register */ +#define SAM_MPDDRC_DLL_SWR1_OFFSET 0x014c /* MPDDRC DLL Status CLKWR1 Register */ +#define SAM_MPDDRC_DLL_SWR2_OFFSET 0x0150 /* MPDDRC DLL StatusCLKWR2 Register */ +#define SAM_MPDDRC_DLL_SWR3_OFFSET 0x0154 /* MPDDRC DLL Status CLKWR3 Register */ + +#define SAM_MPDDRC_DLL_SAD_OFFSET 0x0158 /* MPDDRC DLL Status CLKAD Register */ + /* 0x015c-0x01fxc Reserved */ + +/* MPDDRC Register Addresses ****************************************************************/ + +#define SAM_MPDDRC_MR (SAM_MPDDRC_VBASE+SAM_MPDDRC_MR_OFFSET) +#define SAM_MPDDRC_RTR (SAM_MPDDRC_VBASE+SAM_MPDDRC_RTR_OFFSET) +#define SAM_MPDDRC_CR (SAM_MPDDRC_VBASE+SAM_MPDDRC_CR_OFFSET) +#define SAM_MPDDRC_TPR0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR0_OFFSET) +#define SAM_MPDDRC_TPR1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR1_OFFSET) +#define SAM_MPDDRC_TPR2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_TPR2_OFFSET) +#define SAM_MPDDRC_LPR (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPR_OFFSET) +#define SAM_MPDDRC_MD (SAM_MPDDRC_VBASE+SAM_MPDDRC_MD_OFFSET) +#define SAM_MPDDRC_LPDDR2_LPR (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_LPR_OFFSET) +#define SAM_MPDDRC_LPDDR2_CALMR4 (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_CALMR4_OFFSET) +#define SAM_MPDDRC_LPDDR2_TIMCAL (SAM_MPDDRC_VBASE+SAM_MPDDRC_LPDDR2_TIMCAL_OFFSET) +#define SAM_MPDDRC_IO_CALIBR (SAM_MPDDRC_VBASE+SAM_MPDDRC_IO_CALIBR_OFFSET) +#define SAM_MPDDRC_OCMS (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_OFFSET) +#define SAM_MPDDRC_OCMS_KEY1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_KEY1_OFFSET) +#define SAM_MPDDRC_OCMS_KEY2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_OCMS_KEY2_OFFSET) +#define SAM_MPDDRC_CONF_ARBITER (SAM_MPDDRC_VBASE+SAM_MPDDRC_CONF_ARBITER_OFFSET) +#define SAM_MPDDRC_TIMEOUT (SAM_MPDDRC_VBASE+SAM_MPDDRC_TIMEOUT_OFFSET) +#define SAM_MPDDRC_REQ_PORT_0123 (SAM_MPDDRC_VBASE+SAM_MPDDRC_REQ_PORT_0123_OFFSET) +#define SAM_MPDDRC_REQ_PORT_4567 (SAM_MPDDRC_VBASE+SAM_MPDDRC_REQ_PORT_4567_OFFSET) +#define SAM_MPDDRC_BDW_PORT_0123 (SAM_MPDDRC_VBASE+SAM_MPDDRC_BDW_PORT_0123_OFFSET) +#define SAM_MPDDRC_BDW_PORT_4567 (SAM_MPDDRC_VBASE+SAM_MPDDRC_BDW_PORT_4567_OFFSET) +#define SAM_MPDDRC_RD_DATA_PATH (SAM_MPDDRC_VBASE+SAM_MPDDRC_RD_DATA_PATH_OFFSET) + +#define SAM_MPPDRC_SAW(n) (SAM_MPDDRC_VBASE+SAM_MPPDRC_SAW_OFFSET(n) +#define SAM_MPDDRC_SAW0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_SAW0_OFFSET) +#define SAM_MPDDRC_SAW1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_SAW1_OFFSET) +#define SAM_MPDDRC_SAW2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_SAW2_OFFSET) +#define SAM_MPDDRC_SAW3 (SAM_MPDDRC_VBASE+SAM_MPDDRC_SAW3_OFFSET) + +#define SAM_MPDDRC_WPCR (SAM_MPDDRC_VBASE+SAM_MPDDRC_WPCR_OFFSET) +#define SAM_MPDDRC_WPSR (SAM_MPDDRC_VBASE+SAM_MPDDRC_WPSR_OFFSET) + +#define SAM_MPDDRC_DLL_OS (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_OS_OFFSET) +#define SAM_MPDDRC_DLL_MO (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_MO_OFFSET) +#define SAM_MPDDRC_DLL_SO0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SO0_OFFSET) +#define SAM_MPDDRC_DLL_SO1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SO1_OFFSET) +#define SAM_MPDDRC_DLL_WRO (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_WRO_OFFSET) +#define SAM_MPDDRC_DLL_ADO (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_ADO_OFFSET) + +#define SAM_MPDDRC_DLL_SM(n) (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SM_OFFSET(n)) +#define SAM_MPDDRC_DLL_SM0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SM0_OFFSET) +#define SAM_MPDDRC_DLL_SM1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SM1_OFFSET) +#define SAM_MPDDRC_DLL_SM2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SM2_OFFSET) +#define SAM_MPDDRC_DLL_SM3 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SM3_OFFSET) + +#define SAM_MPDDRC_DLL_SSL(n) (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL_OFFSET(n)) +#define SAM_MPDDRC_DLL_SSL0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL0_OFFSET) +#define SAM_MPDDRC_DLL_SSL1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL1_OFFSET) +#define SAM_MPDDRC_DLL_SSL2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL2_OFFSET) +#define SAM_MPDDRC_DLL_SSL3 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL3_OFFSET) +#define SAM_MPDDRC_DLL_SSL4 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL4_OFFSET) +#define SAM_MPDDRC_DLL_SSL5 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL5_OFFSET) +#define SAM_MPDDRC_DLL_SSL6 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL6_OFFSET) +#define SAM_MPDDRC_DLL_SSL7 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SSL7_OFFSET) + +#define SAM_MPDDRC_DLL_SWR(n) (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SWR_OFFSET(n)) +#define SAM_MPDDRC_DLL_SWR0 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SWR0_OFFSET) +#define SAM_MPDDRC_DLL_SWR1 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SWR1_OFFSET) +#define SAM_MPDDRC_DLL_SWR2 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SWR2_OFFSET) +#define SAM_MPDDRC_DLL_SWR3 (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SWR3_OFFSET) + +#define SAM_MPDDRC_DLL_SAD (SAM_MPDDRC_VBASE+SAM_MPDDRC_DLL_SAD_OFFSET) + +/* MPDDRC Register Bit Definitions **********************************************************/ + +/* MPDDRC Mode Register */ + +#define MPDDRC_MR_MODE_SHIFT (0) /* Bits 0-2: MPDDRC Command Mode */ +#define MPDDRC_MR_MODE_MASK (7 << MPDDRC_MR_MODE_SHIFT) +# define MPDDRC_MR_MODE_NORMAL (0 << MPDDRC_MR_MODE_SHIFT) /* Normal Mode */ +# define MPDDRC_MR_MODE_NOP (1 << MPDDRC_MR_MODE_SHIFT) /* NOP when device accessed */ +# define MPDDRC_MR_MODE_PRCGALL (2 << MPDDRC_MR_MODE_SHIFT) /* 'All Banks Precharge' when device accessed */ +# define MPDDRC_MR_MODE_LMR (3 << MPDDRC_MR_MODE_SHIFT) /* 'Load Mode Register' command when device accessed */ +# define MPDDRC_MR_MODE_RFSH (4 << MPDDRC_MR_MODE_SHIFT) /* 'Auto-Refresh' when device accessed */ +# define MPDDRC_MR_MODE_EXTLMR (5 << MPDDRC_MR_MODE_SHIFT) /* 'Extended Load Mode Register' when device accessed */ +# define MPDDRC_MR_MODE_DEEP (6 << MPDDRC_MR_MODE_SHIFT) /* Deep power mode */ +# define MPDDRC_MR_MODE_LPDDR2 (7 << MPDDRC_MR_MODE_SHIFT) /* LPDDR2 Mode Register' when device accessed */ +#define MPDDRC_MR_MRS_SHIFT (8) /* Bits 8-15: Mode Register Select LPDDR2 */ +#define MPDDRC_MR_MRS_MASK (0xff << MPDDRC_MR_MRS_SHIFT) +# define MPDDRC_MR_MRS(n) ((n) << MPDDRC_MR_MRS_SHIFT) + +/* MPDDRC Refresh Timer Register */ + +#define MPDDRC_RTR_COUNT_SHIFT (0) /* Bits 0-11: MPDDRC Refresh Timer Count */ +#define MPDDRC_RTR_COUNT_MASK (0xfff << MPDDRC_RTR_COUNT_SHIFT) +# define MPDDRC_RTR_COUNT(n) ((n) << MPDDRC_RTR_COUNT_SHIFT) +#define MPDDRC_RTR_ADJ_REF (1 << 16) /* Bit 16: Adjust Refresh Rate */ +#define MPDDRC_RTR_REF_PB (1 << 17) /* Bit 17: Refresh Per Bank */ +#define MPDDRC_RTR_MR4_VALUE_SHIFT (20) /* Bits 20-22: Content of MR4 Register */ +#define MPDDRC_RTR_MR4_VALUE_MASK (7 << MPDDRC_RTR_MR4_VALUE_SHIFT) +# define MPDDRC_RTR_MR4_VALUE(n) ((n) << MPDDRC_RTR_MR4_VALUE_SHIFT) + +/* MPDDRC Configuration Register */ + +#define MPDDRC_CR_NC_SHIFT (0) /* Bits 0-1: Number of Column Bits */ +#define MPDDRC_CR_NC_MASK (3 << MPDDRC_CR_NC_SHIFT) +# define MPDDRC_CR_NC_9 (0 << MPDDRC_CR_NC_SHIFT) /* 9 DDR column bits */ +# define MPDDRC_CR_NC_10 (1 << MPDDRC_CR_NC_SHIFT) /* 10 DDR column bits */ +# define MPDDRC_CR_NC_11 (2 << MPDDRC_CR_NC_SHIFT) /* 11 DDR column bits */ +# define MPDDRC_CR_NC_12 (3 << MPDDRC_CR_NC_SHIFT) /* 12 DDR column bits */ +#define MPDDRC_CR_NR_SHIFT (2) /* Bits 2-3: Number of Row Bits */ +#define MPDDRC_CR_NR_MASK (3 << MPDDRC_CR_NR_SHIFT) +# define MPDDRC_CR_NR_11 (0 << MPDDRC_CR_NR_SHIFT) /* 00 ROW_11 11 row bits */ +# define MPDDRC_CR_NR_12 (1 << MPDDRC_CR_NR_SHIFT) /* 01 ROW_12 12 row bits */ +# define MPDDRC_CR_NR_13 (2 << MPDDRC_CR_NR_SHIFT) /* 10 ROW_13 13 row bits */ +# define MPDDRC_CR_NR_14 (3 << MPDDRC_CR_NR_SHIFT) /* 11 ROW_14 14 row bits */ +#define MPDDRC_CR_CAS_SHIFT (4) /* Bits 4-6: CAS Latency */ +#define MPDDRC_CR_CAS_MASK (7 << MPDDRC_CR_CAS_SHIFT) +# define MPDDRC_CR_CAS_2 (2 << MPDDRC_CR_CAS_SHIFT) /* 010 DDR_CAS2 LPDDR1 CAS Latency 2 */ +# define MPDDRC_CR_CAS_3 (3 << MPDDRC_CR_CAS_SHIFT) /* 011 DDR_CAS3 DDR2/LPDDR2/LPDDR1 CAS Latency 3 */ +# define MPDDRC_CR_CAS_4 (4 << MPDDRC_CR_CAS_SHIFT) /* 100 DDR_CAS4 DDR2/LPDDR2 CAS Latency 4 */ +# define MPDDRC_CR_CAS_5 (5 << MPDDRC_CR_CAS_SHIFT) /* 101 DDR_CAS5 DDR2/LPDDR2 CAS Latency 5 */ +# define MPDDRC_CR_CAS_6 (6 << MPDDRC_CR_CAS_SHIFT) /* 110 DDR_CAS6 DDR2 CAS Latency 6 */ +#define MPDDRC_CR_DLL (1 << 7) /* Bit 7: Reset DLL */ +#define MPDDRC_CR_DIC_DS (1 << 8) /* Bit 8: Output Driver Impedance Control(Drive Strength) */ +#define MPDDRC_CR_DIS_DLL (1 << 9) /* Bit 9: Disable DLL */ +#define MPDDRC_CR_ZQ_SHIFT (10) /* Bits 10-11: ZQ Calibration */ +#define MPDDRC_CR_ZQ_MASK (3 << MPDDRC_CR_ZQ_SHIFT) +# define MPDDRC_CR_ZQ_INIT (0 << MPDDRC_CR_ZQ_SHIFT) /* Calibration command after initialization */ +# define MPDDRC_CR_ZQ_LONG (1 << MPDDRC_CR_ZQ_SHIFT) /* Long calibration */ +# define MPDDRC_CR_ZQ_SHORT (2 << MPDDRC_CR_ZQ_SHIFT) /* Short calibration */ +# define MPDDRC_CR_ZQ_RESET (3 << MPDDRC_CR_ZQ_SHIFT) /* ZQ Reset */ +#define MPDDRC_CR_OCD_SHIFT (12) /* Bits 12-14: Off-chip Driver */ +#define MPDDRC_CR_OCD_MASK (7 << MPDDRC_CR_OCD_SHIFT) +# define MPDDRC_CR_OCD_EXIT (0 << MPDDRC_CR_OCD_SHIFT) /* OCD calibration mode exit, maintain setting */ +# define MPDDRC_CR_OCD_DEFAULT (7 << MPDDRC_CR_OCD_SHIFT) /* OCD calibration default */ +#define MPDDRC_CR_DQMS (1 << 16) /* Bit 16: Mask Data is Shared */ +#define MPDDRC_CR_ENRDM (1 << 17) /* Bit 17: Enable Read Measure */ +#define MPDDRC_CR_LC_LPDDR1 (1 << 19) /* Bit 19: Low-cost Low-power DDR1 */ +#define MPDDRC_CR_NB (1 << 20) /* Bit 20: Number of Banks */ +# define MPDDRC_CR_4BANKS (0) /* 4 banks */ +# define MPDDRC_CR_8BANKS MPDDRC_CR_NB /* 8 banks */ +#define MPDDRC_CR_NDQS (1 << 21) /* Bit 21: Not DQS */ +#define MPDDRC_CR_DECOD (1 << 22) /* Bit 22: Type of Decoding */ +#define MPDDRC_CR_UNAL (1 << 23) /* Bit 23: Support Unaligned Access */ + +/* MPDDRC Timing Parameter 0 Register */ + +#define MPDDRC_TPR0_TRAS_SHIFT (0) /* Bits 0-3: Active to Precharge Delay */ +#define MPDDRC_TPR0_TRAS_MASK (15 << MPDDRC_TPR0_TRAS_SHIFT) +# define MPDDRC_TPR0_TRAS(n) ((n) << MPDDRC_TPR0_TRAS_SHIFT) +#define MPDDRC_TPR0_TRCD_SHIFT (4) /* Bits 4-7: Row to Column Delay */ +#define MPDDRC_TPR0_TRCD_MASK (15 << MPDDRC_TPR0_TRCD_SHIFT) +# define MPDDRC_TPR0_TRCD(n) ((n) << MPDDRC_TPR0_TRCD_SHIFT) +#define MPDDRC_TPR0_TWR_SHIFT (8) /* Bits 8-11: Write Recovery Delay */ +#define MPDDRC_TPR0_TWR_MASK (15 << MPDDRC_TPR0_TWR_SHIFT) +# define MPDDRC_TPR0_TWR(n) ((n) << MPDDRC_TPR0_TWR_SHIFT) +#define MPDDRC_TPR0_TRC_SHIFT (12) /* Bits 12-15: Row Cycle Delay */ +#define MPDDRC_TPR0_TRC_MASK (15 << MPDDRC_TPR0_TRC_SHIFT) +# define MPDDRC_TPR0_TRC(n) ((n) << MPDDRC_TPR0_TRC_SHIFT) +#define MPDDRC_TPR0_TRP_SHIFT (16) /* Bits 16-19: Row Precharge Delay */ +#define MPDDRC_TPR0_TRP_MASK (15 << MPDDRC_TPR0_TRP_SHIFT) +# define MPDDRC_TPR0_TRP(n) ((n) << MPDDRC_TPR0_TRP_SHIFT) +#define MPDDRC_TPR0_TRRD_SHIFT (20) /* Bits 20-23: Active BankA to Active BankB */ +#define MPDDRC_TPR0_TRRD_MASK (15 << MPDDRC_TPR0_TRRD_SHIFT) +# define MPDDRC_TPR0_TRRD(n) ((n) << MPDDRC_TPR0_TRRD_SHIFT) +#define MPDDRC_TPR0_TWTR_SHIFT (24) /* Bits 24-26: Internal Write to Read Delay */ +#define MPDDRC_TPR0_TWTR_MASK (7 << MPDDRC_TPR0_TWTR_SHIFT) +# define MPDDRC_TPR0_TWTR(n) ((n) << MPDDRC_TPR0_TWTR_SHIFT) +#define MPDDRC_TPR0_RDC_WRRD (1 << 27) /* Bit 27: Reduce Write to Read Delay */ +#define MPDDRC_TPR0_TMRD_SHIFT (28) /* Bits 18-31: Load Mode Register Command to Activate or Refresh Command */ +#define MPDDRC_TPR0_TMRD_MASK (15 << MPDDRC_TPR0_TMRD_SHIFT) +# define MPDDRC_TPR0_TMRD(n) ((n) << MPDDRC_TPR0_TMRD_SHIFT) + +/* MPDDRC Timing Parameter 1 Register */ + +#define MPDDRC_TPR1_TRFC_SHIFT (0) /* Bits 0-6: Row Cycle Delay */ +#define MPDDRC_TPR1_TRFC_MASK (0x7f << MPDDRC_TPR1_TRFC_SHIFT) +# define MPDDRC_TPR1_TRFC(n) ((n) << MPDDRC_TPR1_TRFC_SHIFT) +#define MPDDRC_TPR1_TXSNR_SHIFT (8) /* Bits 8-15: Exit Self Refresh Delay to Non Read Command */ +#define MPDDRC_TPR1_TXSNR_MASK (0xff << MPDDRC_TPR1_TXSNR_SHIFT) +# define MPDDRC_TPR1_TXSNR(n) ((n) << MPDDRC_TPR1_TXSNR_SHIFT) +#define MPDDRC_TPR1_TXSRD_SHIFT (16) /* Bits 16-23: Exit Self Refresh Delay to Read Command */ +#define MPDDRC_TPR1_TXSRD_MASK (0xff << MPDDRC_TPR1_TXSRD_SHIFT) +# define MPDDRC_TPR1_TXSRD(n) ((n) << MPDDRC_TPR1_TXSRD_SHIFT) +#define MPDDRC_TPR1_TXP_SHIFT (24) /* Bits 24-27: Exit Power-down Delay to First Command */ +#define MPDDRC_TPR1_TXP_MASK (15 << MPDDRC_TPR1_TXP_SHIFT) +# define MPDDRC_TPR1_TXP(n) ((n) << MPDDRC_TPR1_TXP_SHIFT) + +/* MPDDRC Timing Parameter 2 Register */ + +#define MPDDRC_TPR2_TXARD_SHIFT (0) /* Bits 0-3: Exit Active Power Down Delay to Read Command in Mode 'Fast Exit' */ +#define MPDDRC_TPR2_TXARD_MASK (15 << MPDDRC_TPR2_TXARD_SHIFT) +# define MPDDRC_TPR2_TXARD(n) ((n) << MPDDRC_TPR2_TXARD_SHIFT) +#define MPDDRC_TPR2_TXARDS_SHIFT (4) /* Bits 4-7: Exit Active Power Down Delay to Read Command in Mode 'Slow Exit' */ +#define MPDDRC_TPR2_TXARDS_MASK (15 << MPDDRC_TPR2_TXARDS_SHIFT) +# define MPDDRC_TPR2_TXARDS(n) ((n) << MPDDRC_TPR2_TXARDS_SHIFT) +#define MPDDRC_TPR2_TRPA_SHIFT (8) /* Bits 8-11: Row Precharge All Delay */ +#define MPDDRC_TPR2_TRPA_MASK (15 << MPDDRC_TPR2_TRPA_SHIFT) +# define MPDDRC_TPR2_TRPA(n) ((n) << MPDDRC_TPR2_TRPA_SHIFT) +#define MPDDRC_TPR2_TRTP_SHIFT (12) /* Bits 12-14: Read to Precharge */ +#define MPDDRC_TPR2_TRTP_MASK (7 << MPDDRC_TPR2_TRTP_SHIFT) +# define MPDDRC_TPR2_TRTP(n) ((n) << MPDDRC_TPR2_TRTP_SHIFT) +#define MPDDRC_TPR2_TFAW_SHIFT (16) /* Bits 16-19: Four Active Windows */ +#define MPDDRC_TPR2_TFAW_MASK (15 << MPDDRC_TPR2_TFAW_SHIFT) +# define MPDDRC_TPR2_TFAW(n) ((n) << MPDDRC_TPR2_TFAW_SHIFT) + +/* MPDDRC Low-power Register */ + +#define MPDDRC_LPR_LPCB_SHIFT (0) /* Bits 0-1: Low-power Command*/ +#define MPDDRC_LPR_LPCB_MASK (3 << MPDDRC_LPR_LPCB_SHIFT) +# define MPDDRC_LPR_LPCB_DISABLED (0 << MPDDRC_LPR_LPCB_SHIFT) /* Low-power Feature is inhibited */ +# define MPDDRC_LPR_LPCB_SELFREFRESH (1 << MPDDRC_LPR_LPCB_SHIFT) /* Issues a 'Self Refresh' to device, clocks deactivated */ +# define MPDDRC_LPR_LPCB_POWERDOWN (2 << MPDDRC_LPR_LPCB_SHIFT) /* Issues a 'Power-down' to device after each access */ +# define MPDDRC_LPR_LPCB_DEEPPWD (3 << MPDDRC_LPR_LPCB_SHIFT) /* TIssues a 'Deep Power-down' to Low-power device */ +#define MPDDRC_LPR_CLK_FR (1 << 2) /* Bit 2: Clock Frozen Command */ +#define MPDDRC_LPR_LPDDR2_PWOFF (1 << 3) /* Bit 3: LPDDR2 Power Off */ +#define MPDDRC_LPR_PASR_SHIFT (4) /* Bits 4-6: Partial Array Self Refresh */ +#define MPDDRC_LPR_PASR_MASK (7 << MPDDRC_LPR_PASR_SHIFT) +# define MPDDRC_LPR_PASR(n) ((n) << MPDDRC_LPR_PASR_SHIFT) +#define MPDDRC_LPR_DS_SHIFT (8) /* Bits 8-10: Drive Strength */ +#define MPDDRC_LPR_DS_MASK (7 << MPDDRC_LPR_DS_SHIFT) +# define MPDDRC_LPR_DS(n) ((n) << MPDDRC_LPR_DS_SHIFT) +#define MPDDRC_LPR_TIMEOUT_SHIFT (12) /* Bits 12-13: Enter Low-power Mode */ +#define MPDDRC_LPR_TIMEOUT_MASK (3 << MPDDRC_LPR_TIMEOUT_SHIFT) +# define MPDDRC_LPR_TIMEOUT_0CLKS (0 << MPDDRC_LPR_TIMEOUT_SHIFT) /* Activates low-power mode after the end of transfer */ +# define MPDDRC_LPR_TIMEOUT_64CLKS (1 << MPDDRC_LPR_TIMEOUT_SHIFT) /* Activates low-power mode 64 clocks after the end of transfer */ +# define MPDDRC_LPR_TIMEOUT_128CLKS (2 << MPDDRC_LPR_TIMEOUT_SHIFT) /* 28 Activates low-power mode 128 clocks after the end of transfer */ +#define MPDDRC_LPR_APDE (1 << 16) /* Bit 16: ctive Power Down Exit Time */ +# define MPDDRC_LPR_APDE_FAST (0) +# define MPDDRC_LPR_APDE_SLOW MPDDRC_LPR_APDE +#define MPDDRC_LPR_UPD_MR_SHIFT (20) /* Bits 20-21: Update Load Mode Register and Extended Mode Register */ +#define MPDDRC_LPR_UPD_MR_MASK (3 << MPDDRC_LPR_UPD_MR_SHIFT) +# define MPDDRC_LPR_UPD_MR_DISABLED (0 << MPDDRC_LPR_UPD_MR_SHIFT) /* DISABLED Update is disabled */ +# define MPDDRC_LPR_UPD_MR_SHARED (1 << MPDDRC_LPR_UPD_MR_SHIFT) /* MPDDRC shares external bus */ +# define MPDDRC_LPR_UPD_MR_UNSHARED (2 << MPDDRC_LPR_UPD_MR_SHIFT) /* MPDDRC does not share external bus */ + +/* MPDDRC Memory Device Register */ + +#define MPDDRC_MD_SHIFT (0) /* Bits 0-2: Memory Device */ +#define MPDDRC_MD_MASK (7 << MPDDRC_MD_SHIFT) +# define MPDDRC_MD_DDR_SDRAM (2 << MPDDRC_MD_SHIFT) /* DDR1-SDRAM */ +# define MPDDRC_MD_LPDDR_SDRAM (3 << MPDDRC_MD_SHIFT) /* Low-power DDR1-SDRAM */ +# define MPDDRC_MD_DDR2_SDRAM (6 << MPDDRC_MD_SHIFT) /* DDR2-SDRAM */ +# define MPDDRC_MD_LPDDR2_SDRAM (7 << MPDDRC_MD_SHIFT) /* Low-power DDR2-SDRAM */ +#define MPDDRC_MD_DBW (1 << 4) /* Bit 4: Data Bus Width */ +# define MPDDRC_MD_DBW32 (0) /* Data bus width is 32 bits */ +# define MPDDRC_MD_DBW16 MPDDRC_MD_DBW /* Data bus width is 16 bits */ + +/* MPDDRC LPDDR2 Low-power Register */ + +#define MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT (0) /* Bits 0-7: Bank Mask Bit/PASR */ +#define MPDDRC_LPDDR2_LPR_BK_MASK_PASR_MASK (0xff << MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT) +# define MPDDRC_LPDDR2_LPR_BK_MASK_PASR(n) ((n) << MPDDRC_LPDDR2_LPR_BK_MASK_PASR_SHIFT) +#define MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT (8) /* Bits 8-23: Segment Mask*/ +#define MPDDRC_LPDDR2_LPR_SEG_MASK_MASK (0xffff << MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT) +# define MPDDRC_LPDDR2_LPR_SEG_MASK(n) ((n) << MPDDRC_LPDDR2_LPR_SEG_MASK_SHIFT) +#define MPDDRC_LPDDR2_LPR_DS_SHIFT (24) /* Bits 24-27: Drive strength */ +#define MPDDRC_LPDDR2_LPR_DS_MASK (15 << MPDDRC_LPDDR2_LPR_DS_SHIFT) +# define MPDDRC_LPDDR2_LPR_DS(n) ((n) << MPDDRC_LPDDR2_LPR_DS_SHIFT) + +/* MPDDRC LPDDR2 Calibration and MR4 Register */ + +#define MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT (0) /* Bits 0-15: LPDDR2 Calibration Timer Count */ +#define MPDDRC_LPDDR2_CALMR4_COUNT_CAL_MASK (0xffff << MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT) +# define MPDDRC_LPDDR2_CALMR4_COUNT_CAL(n) ((n) << MPDDRC_LPDDR2_CALMR4_COUNT_CAL_SHIFT) +#define MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT (16) /* Bits 16-31: Mode Register 4 Read Interval */ +#define MPDDRC_LPDDR2_CALMR4_MR4_READ_MASK (0xffff << MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT) +# define MPDDRC_LPDDR2_CALMR4_MR4_READ(n) ((n) << MPDDRC_LPDDR2_CALMR4_MR4_READ_SHIFT) + +/* MPDDRC LPDDR2 Timing Calibration Register */ + +#define MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT (0) /* Bits 0-7: ZQ Calibration Short */ +#define MPDDRC_LPDDR2_TIMCAL_ZQCS_MASK (0xff << MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT) +# define MPDDRC_LPDDR2_TIMCAL_ZQCS(n) ((n) << MPDDRC_LPDDR2_TIMCAL_ZQCS_SHIFT) + +/* MPDDRC IO Calibration */ + +#define MPDDRC_IO_CALIBR_RDIV_SHIFT (0) /* Bits 0-2: Resistor Divider, Output Driver Impedance */ +#define MPDDRC_IO_CALIBR_RDIV_MASK (7 << MPDDRC_IO_CALIBR_RDIV_SHIFT) +# define MPDDRC_IO_CALIBR_RZQ34_NA (1 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2 RZQ = 34.3 Ohm DDR2/LPDDR1: Not applicable */ +# define MPDDRC_IO_CALIBR_RZQ40_33 (2 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 40 Ohm DDR2/LPDDR1: RZQ = 33.3 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ48_40 (3 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 48 Ohm DDR2/LPDDR1: RZQ = 40 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ60_50 (4 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 60 Ohm DDR2/LPDDR1: RZQ = 50 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ80_67 (6 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2 RZQ = 80 Ohm DDR2/LPDDR1: RZQ = 66.7 Ohm */ +# define MPDDRC_IO_CALIBR_RZQ120_100 (7 << MPDDRC_IO_CALIBR_RDIV_SHIFT) /* LPDDR2:RZQ = 120 Oh m DDR2/LPDDR1: RZQ = 100 Ohm */ +#define MPDDRC_IO_CALIBR_EN_CALIB (1 << 4) /* Bit 4: Enable of the Calibration */ +#define MPDDRC_IO_CALIBR_TZQIO_SHIFT (8) /* Bits 8-10: IO Calibration */ +#define MPDDRC_IO_CALIBR_TZQIO_MASK (7 << MPDDRC_IO_CALIBR_TZQIO_SHIFT) +# define MPDDRC_IO_CALIBR_TZQIO(n) ((n) << MPDDRC_IO_CALIBR_TZQIO_SHIFT) +#define MPDDRC_IO_CALIBR_CALCODEP_SHIFT (16) /* Bits 16-19: Number of Transistor P */ +#define MPDDRC_IO_CALIBR_CALCODEP_MASK (15 << MPDDRC_IO_CALIBR_CALCODEP_SHIFT) +# define MPDDRC_IO_CALIBR_CALCODEP(n) ((n) << MPDDRC_IO_CALIBR_CALCODEP_SHIFT) +#define MPDDRC_IO_CALIBR_CALCODEN_SHIFT (20) /* Bits 20-23: Number of Transistor N */ +#define MPDDRC_IO_CALIBR_CALCODEN_MASK (15 << MPDDRC_IO_CALIBR_CALCODEN_SHIFT) +# define MPDDRC_IO_CALIBR_CALCODEN(n) ((n) << MPDDRC_IO_CALIBR_CALCODEN_SHIFT) + +/* MPDDRC OCMS Register */ + +#define MPDDRC_OCMS_SCR_EN (1 << 0) /* Bit 0: Scrambling enable */ + +/* MPDDRC OCMS KEY1 Register (32-bit key value) */ +/* MPDDRC OCMS KEY2 Register (32-bit key value) */ + +/* MPDDRC Configuration Arbiter Register */ + +#define MPDDRC_CONF_ARBITER_ARB_SHIFT (0) /* Bits 0-1: Type of Arbitration */ +#define MPDDRC_CONF_ARBITER_ARB_MASK (3 << MPDDRC_CONF_ARBITER_ARB_SHIFT) +# define MPDDRC_CONF_ARBITER_ARB_ROUND (0 << MPDDRC_CONF_ARBITER_ARB_SHIFT) /* Round Robin */ +# define MPDDRC_CONF_ARBITER_ARB_NB_REQUEST (1 << MPDDRC_CONF_ARBITER_ARB_SHIFT) /* Request Policy */ +# define MPDDRC_CONF_ARBITER_ARB_BANDWIDTH (2 << MPDDRC_CONF_ARBITER_ARB_SHIFT) /* Bandwidth Policy */ +#define MPDDRC_CONF_ARBITER_BDW_BURST (1 << 2) /* Bit 2: Bandwidth is Reached or Bandwidth and Current Burst Access is Ended */ +#define MPDDRC_CONF_ARBITER_BDW_MAX_CUR (1 << 3) /* Bit 3: Bandwidth Max or Current */ +#define MPDDRC_CONF_ARBITER_RQ_WD_P(n) (1 << ((n)+8) /* Bits 8-15: Request or Word from Port n */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P0 (1 << 8) /* Bit 8: Request or Word from Port 0 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P1 (1 << 9) /* Bit 9: Request or Word from Port 1 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P2 (1 << 10) /* Bit 10: Request or Word from Port 2 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P3 (1 << 11) /* Bit 11: Request or Word from Port 3 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P4 (1 << 12) /* Bit 12: Request or Word from Port 4 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P5 (1 << 13) /* Bit 13: Request or Word from Port 5 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P6 (1 << 14) /* Bit 14: Request or Word from Port 6 */ +# define MPDDRC_CONF_ARBITER_RQ_WD_P7 (1 << 15) /* Bit 15: Request or Word from Port 7 */ +#define MPDDRC_CONF_ARBITER_MA_PR_P(n) (1 << ((n)+16)) /* Bits 16-23: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P0 (1 << 16) /* Bit 16: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P1 (1 << 17) /* Bit 17: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P2 (1 << 18) /* Bit 18: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P3 (1 << 19) /* Bit 19: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P4 (1 << 20) /* Bit 20: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P5 (1 << 21) /* Bit 21: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P6 (1 << 22) /* Bit 22: Master or Software Provide Information */ +# define MPDDRC_CONF_ARBITER_MA_PR_P7 (1 << 23) /* Bit 23: Master or Software Provide Information */ + +/* MPDDRC Time-out Port 0/1/2/3 Register */ + +#define MPDDRC_TIMEOUT_TIMEOUT_P_SHIFT(n) ((n)<<4) /* Time-out for Port n, n=0..7 */ +#define MPDDRC_TIMEOUT_TIMEOUT_P_MASK(n) (15 << MPDDRC_TIMEOUT_TIMEOUT_P_SHIFT(n)) +# define MPDDRC_TIMEOUT_TIMEOUT_P(n,v) ((uint32_t)(v) << MPDDRC_TIMEOUT_TIMEOUT_P_SHIFT(n)) +# define MPDDRC_TIMEOUT_TIMEOUT_P0_SHIFT (0) /* Bits 4-7: Time-out for Port 0 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P0_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P0_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P0(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P0_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P1_SHIFT (4) /* Bits 0-3: Time-out for Port 1 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P1_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P1_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P1(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P1_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P2_SHIFT (8) /* Bits 8-7: Time-out for Port 2 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P2_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P2_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P2(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P2_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P3_SHIFT (12) /* Bits 12-15: Time-out for Port 3 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P3_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P3_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P3(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P3_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P4_SHIFT (16) /* Bits 16-19: Time-out for Port 4 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P4_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P4_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P4(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P4_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P5_SHIFT (20) /* Bits 20-23: Time-out for Port 5 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P5_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P5_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P5(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P5_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P6_SHIFT (24) /* Bits 24-27: Time-out for Port 6 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P6_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P6_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P6(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P6_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P7_SHIFT (28) /* Bits 28-31: Time-out for Port 7 */ +# define MPDDRC_TIMEOUT_TIMEOUT_P7_MASK (15 << MPDDRC_TIMEOUT_TIMEOUT_P7_SHIFT) +# define MPDDRC_TIMEOUT_TIMEOUT_P7(n) ((uint32_t)(n) << MPDDRC_TIMEOUT_TIMEOUT_P7_SHIFT) + +/* MPDDRC Request Port 0/1/2/3 Register */ + +#define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P_SHIFT(n) ((n)<<8) /* Number of Requests/Words/Allocation from Port n, n=0..3 */ +#define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P_MASK(n) (0xff << PDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P_SHIFT(n)) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P(n,v) ((uint32_t)(v) << PDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P_SHIFT(n)) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P0_SHIFT (0) /* Bits 0-7: Number of Requests/Words/Allocation from Port 0 */ +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P0_MASK (0xff << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P0_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P0(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P0_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P1_SHIFT (8) /* Bits 8-15: Number of Requests/Words/Allocation from Port 1 */ +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P1_MASK (0xff << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P1_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P1(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P1_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P2_SHIFT (16) /* Bits 16-23: Number of Requests/Words/Allocation from Port 2 */ +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P2_MASK (0xff << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P2_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P2(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P2_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P3_SHIFT (24) /* Bits 24-31: Number of Requests/Words/Allocation from Port 3 */ +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P3_MASK (0xff << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P3_SHIFT) +# define MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P3(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_0123_NRQ_NWD_BDW_P3_SHIFT) + +/* MPDDRC Request Port 4/5/6/7 Register */ + +#define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P_SHIFT(n) ((n)<<8) /* Number of Requests/Words/Allocation from port n, n=4..7 */ +#define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P_MASK(n) (0xff << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P_SHIFT(n)) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P(n,v) ((uint32_t)(v) << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P_SHIFT(n)) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P4_SHIFT (0) /* Bits 0-7: Number of Requests/Words/Allocation from port 4 */ +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P4_MASK (0xff << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P4_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P4(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P4_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P5_SHIFT (8) /* Bits 8-15: Number of Requests/Words/Allocation from port 5 */ +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P5_MASK (0xff << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P5_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P5(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P5_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P6_SHIFT (16) /* Bits 16-23: Number of Requests/Words/Allocation from port 6 */ +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P6_MASK (0xff << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P6_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P6(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P6_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P7_SHIFT (24) /* Bits 24-31: Number of Requests/Words/Allocation from port 7 */ +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P7_MASK (0xff << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P7_SHIFT) +# define MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P7(n) ((uint32_t)(n) << MPDDRC_REQ_PORT_4567_NRQ_NWD_BDW_P7_SHIFT) + +/* MPDDRC Bandwidth Port 0/1/2/3 Register */ + +#define MPDDRC_BDW_PORT_0123_BDW_P_SHIFT(n) ((n)<<8) /* Current/Maximum Bandwidth from Port n, n=0..3 */ +#define MPDDRC_BDW_PORT_0123_BDW_P_MASK(n) (0x7f << PDDRC_BDW_PORT_0123_BDW_P_SHIFT(n)) +# define MPDDRC_BDW_PORT_0123_BDW_P(n,v) ((uint32_t)(v) << PDDRC_BDW_PORT_0123_BDW_P_SHIFT(n)) +# define MPDDRC_BDW_PORT_0123_BDW_P0_SHIFT (0) /* Bits 0-6: Current/Maximum Bandwidth from Port 0 */ +# define MPDDRC_BDW_PORT_0123_BDW_P0_MASK (0x7f << MPDDRC_BDW_PORT_0123_BDW_P0_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P0(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_0123_BDW_P0_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P1_SHIFT (8) /* Bits 8-14: Current/Maximum Bandwidth from Port 1 */ +# define MPDDRC_BDW_PORT_0123_BDW_P1_MASK (0x7f << MPDDRC_BDW_PORT_0123_BDW_P1_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P1(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_0123_BDW_P1_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P2_SHIFT (16) /* Bits 16-22: Current/Maximum Bandwidth from Port 2 */ +# define MPDDRC_BDW_PORT_0123_BDW_P2_MASK (0x7f << MPDDRC_BDW_PORT_0123_BDW_P2_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P2(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_0123_BDW_P2_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P3_SHIFT (24) /* Bits 24-30: Current/Maximum Bandwidth from Port 3 */ +# define MPDDRC_BDW_PORT_0123_BDW_P3_MASK (0x7f << MPDDRC_BDW_PORT_0123_BDW_P3_SHIFT) +# define MPDDRC_BDW_PORT_0123_BDW_P3(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_0123_BDW_P3_SHIFT) + +/* MPDDRC Bandwidth Port 4/5/6/7 Register */ + +#define MPDDRC_BDW_PORT_4567_BDW_P_SHIFT(n) ((n)<<8) /* Current/Maximum Bandwidth from Port n, n=4..7 */ +#define MPDDRC_BDW_PORT_4567_BDW_P_MASK(n) (0x7f << PDDRC_BDW_PORT_4567_BDW_P_SHIFT(n)) +# define MPDDRC_BDW_PORT_4567_BDW_P(n,v) ((uint32_t)(v) << PDDRC_BDW_PORT_4567_BDW_P_SHIFT(n)) +# define MPDDRC_BDW_PORT_4567_BDW_P4_SHIFT (0) /* Bits 0-6: Current/Maximum Bandwidth from Port 4 */ +# define MPDDRC_BDW_PORT_4567_BDW_P4_MASK (0x7f << MPDDRC_BDW_PORT_4567_BDW_P4_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P4(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_4567_BDW_P4_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P5_SHIFT (8) /* Bits 8-14: Current/Maximum Bandwidth from Port 5 */ +# define MPDDRC_BDW_PORT_4567_BDW_P5_MASK (0x7f << MPDDRC_BDW_PORT_4567_BDW_P5_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P5(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_4567_BDW_P5_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P6_SHIFT (16) /* Bits 16-22: Current/Maximum Bandwidth from Port 6 */ +# define MPDDRC_BDW_PORT_4567_BDW_P6_MASK (0x7f << MPDDRC_BDW_PORT_4567_BDW_P6_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P6(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_4567_BDW_P6_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P7_SHIFT (24) /* Bits 24-30: Current/Maximum Bandwidth from Port 7 */ +# define MPDDRC_BDW_PORT_4567_BDW_P7_MASK (0x7f << MPDDRC_BDW_PORT_4567_BDW_P7_SHIFT) +# define MPDDRC_BDW_PORT_4567_BDW_P7(n) ((uint32_t)(n) << MPDDRC_BDW_PORT_4567_BDW_P7_SHIFT) + +/* MPDDRC Read Datapath Register */ + +#define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT (0) /* Bits 0-1: Shift Sampling Point of Data */ +#define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_MASK (3 << MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT) +# define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_NONE (0 << MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT) /* Initial sampling point */ +# define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_1CYCLE (1 << MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT) /* Sampling shifted by 1 cycle */ +# define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_2CYCLES (2 << MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT) /* Sampling point shifted by 2 cycles */ +# define MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_3CYCLES (3 << MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING_SHIFT) /* Sampling point shifted by 3 cycles */ + +/* MPDDRC Smart Adaptation Wrapper 0-3 Register */ + +#define MPDDRC_SAW_FLUSH_MAX_SHIFT (0) /* Bits 0-7: Clears FIFO Content */ +#define MPDDRC_SAW_FLUSH_MAX_MASK (0xff << MPDDRC_SAW_FLUSH_MAX_SHIFT) +# define MPDDRC_SAW_FLUSH_MAX(n) ((uint32_t)(n) << MPDDRC_SAW_FLUSH_MAX_SHIFT) +#define MPDDRC_SAW_INCR_THRESH_SHIFT (8) /* Bits 8-13: Incremental Threshold */ +#define MPDDRC_SAW_INCR_THRESH_MASK (0x3f << MPDDRC_SAW_INCR_THRESH_SHIFT) +# define MPDDRC_SAW_INCR_THRESH_1WORD (1 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 1 word/dword max */ +# define MPDDRC_SAW_INCR_THRESH_2WORDS (2 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 2 word/dword max */ +# define MPDDRC_SAW_INCR_THRESH_4WORDS (4 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 4 word/dword max */ +# define MPDDRC_SAW_INCR_THRESH_8WORDS (8 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 8 word/dword max */ +# define MPDDRC_SAW_INCR_THRESH_16WORDS (16 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 16 word/dword max */ +# define MPDDRC_SAW_INCR_THRESH_32WORDS (21 << MPDDRC_SAW_INCR_THRESH_SHIFT) /* 32 word/dword max */ +#define MPDDRC_SAW_PFCH_THRESH_SHIFT (16) /* Bits 16-21: Prefetch Threshold */ +#define MPDDRC_SAW_PFCH_THRESH_MASK (0x3f << MPDDRC_SAW_PFCH_THRESH_SHIFT) +# define MPDDRC_SAW_PFCH_THRESH_2WORDS (2 << MPDDRC_SAW_PFCH_THRESH_SHIFT) /* 2 word/dword max */ +# define MPDDRC_SAW_PFCH_THRESH_4WORDS (4 << MPDDRC_SAW_PFCH_THRESH_SHIFT) /* 4 word/dword max */ +# define MPDDRC_SAW_PFCH_THRESH_8WORDS (8 << MPDDRC_SAW_PFCH_THRESH_SHIFT) /* 8 word/dword max */ + +/* MPDDRC Write Protect Control Register */ + +#define MPDDRC_WPCR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define MPDDRC_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection KEY */ +#define MPDDRC_WPCR_WPKEY_MASK (0x00ffffff << MPDDRC_WPCR_WPKEY_SHIFT) + #define MPDDRC_WPCR_WPKEY (0x00444452 << MPDDRC_WPCR_WPKEY_SHIFT) + +/* MPDDRC Write Protect Status Register */ + +#define MPDDRC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Enable */ +#define MPDDRC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define MPDDRC_WPSR_WPVSRC_MASK (0xffff << MPDDRC_WPSR_WPVSRC_SHIFT) + +/* MPDDRC DLL Offset Selection Register */ + +#define MPDDRC_DLL_OS_SELOFF (1 << 0) /* Bit 0: Offset Selection */ + +/* MPDDRC DLL MASTER Offset Register */ + +#define MPDDRC_DLL_MO_M0OFF_SHIFT (0) /* Bits 0-7: Master 0 Delay Line Offset */ +#define MPDDRC_DLL_MO_M0OFF_MASK (0xff < MPDDRC_DLL_MO_M0OFF_SHIFT) +# define MPDDRC_DLL_MO_M0OFF(n) ((uint32_t)(n) < MPDDRC_DLL_MO_M0OFF_SHIFT) + +/* MPDDRC DLL SLAVE Offset 0 Register */ + +#define MPDDRC_DLL_SO0_SOFF_SHIFT(n) (0) /* SLAVEn Delay Line Offset, n=0..3 */ +#define MPDDRC_DLL_SO0_SOFF_MASK(n) (0xff < MPDDRC_DLL_SO0_SOFF_SHIFT(n)) +# define MPDDRC_DLL_SO0_SOFF(n,v) ((uint32_t)(v) < MPDDRC_DLL_SO0_SOFF_SHIFT(n)) +# define MPDDRC_DLL_SO0_S0OFF_SHIFT (0) /* Bits 0-7: SLAVE0 Delay Line Offset */ +# define MPDDRC_DLL_SO0_S0OFF_MASK (0xff < MPDDRC_DLL_SO0_S0OFF_SHIFT) +# define MPDDRC_DLL_SO0_S0OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO0_S0OFF_SHIFT) +# define MPDDRC_DLL_SO0_S1OFF_SHIFT (8) /* Bits 8-15: SLAVE1 Delay Line Offset */ +# define MPDDRC_DLL_SO0_S1OFF_MASK (0xff < MPDDRC_DLL_SO0_S1OFF_SHIFT) +# define MPDDRC_DLL_SO0_S1OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO0_S1OFF_SHIFT) +# define MPDDRC_DLL_SO0_S2OFF_SHIFT (16) /* Bits 16-23: SLAVE2 Delay Line Offset */ +# define MPDDRC_DLL_SO0_S2OFF_MASK (0xff < MPDDRC_DLL_SO0_S2OFF_SHIFT) +# define MPDDRC_DLL_SO0_S2OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO0_S2OFF_SHIFT) +# define MPDDRC_DLL_SO0_S3OFF_SHIFT (24) /* Bits 24-31: SLAVE3 Delay Line Offset */ +# define MPDDRC_DLL_SO0_S3OFF_MASK (0xff < MPDDRC_DLL_SO0_S3OFF_SHIFT) +# define MPDDRC_DLL_SO0_S3OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO0_S3OFF_SHIFT) + +/* MPDDRC DLL SLAVE Offset 1 Register */ + +#define MPDDRC_DLL_SO1_SOFF_SHIFT(n) (0) /* SLAVEn Delay Line Offset, n=4..7 */ +#define MPDDRC_DLL_SO1_SOFF_MASK(n) (0xff < MPDDRC_DLL_SO1_SOFF_SHIFT(n)) +# define MPDDRC_DLL_SO1_SOFF(n,v) ((uint32_t)(v) < MPDDRC_DLL_SO1_SOFF_SHIFT(n)) +# define MPDDRC_DLL_SO1_S4OFF_SHIFT (0) /* Bits 0-7: SLAVE4 Delay Line Offset */ +# define MPDDRC_DLL_SO1_S4OFF_MASK (0xff < MPDDRC_DLL_SO1_S4OFF_SHIFT) +# define MPDDRC_DLL_SO1_S4OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO1_S4OFF_SHIFT) +# define MPDDRC_DLL_SO1_S5OFF_SHIFT (8) /* Bits 8-15: SLAVE5 Delay Line Offset */ +# define MPDDRC_DLL_SO1_S5OFF_MASK (0xff < MPDDRC_DLL_SO1_S5OFF_SHIFT) +# define MPDDRC_DLL_SO1_S5OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO1_S5OFF_SHIFT) +# define MPDDRC_DLL_SO1_S6OFF_SHIFT (16) /* Bits 16-23: SLAVE6 Delay Line Offset */ +# define MPDDRC_DLL_SO1_S6OFF_MASK (0xff < MPDDRC_DLL_SO1_S6OFF_SHIFT) +# define MPDDRC_DLL_SO1_S6OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO1_S6OFF_SHIFT) +# define MPDDRC_DLL_SO1_S7OFF_SHIFT (24) /* Bits 24-31: SLAVE7 Delay Line Offset */ +# define MPDDRC_DLL_SO1_S7OFF_MASK (0xff < MPDDRC_DLL_SO1_S7OFF_SHIFT) +# define MPDDRC_DLL_SO1_S7OFF(n) ((uint32_t)(n) < MPDDRC_DLL_SO1_S7OFF_SHIFT) + +/* MPDDRC DLL CLKWR Offset Register */ + +#define MPDDRC_DLL_WRO_WROFF_SHIFT(n) (0) /* CLKWRn Delay Line Offset, n=0..3 */ +#define MPDDRC_DLL_WRO_WROFF_MASK(n) (0xff < MPDDRC_DLL_WRO_WROFF_SHIFT(n)) +# define MPDDRC_DLL_WRO_WROFF(n,v) ((uint32_t)(n) < MPDDRC_DLL_WRO_WROFF_SHIFT(n)) +# define MPDDRC_DLL_WRO_WR0OFF_SHIFT (0) /* Bits 0-7: CLKWR0 Delay Line Offset */ +# define MPDDRC_DLL_WRO_WR0OFF_MASK (0xff < MPDDRC_DLL_WRO_WR0OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR0OFF(n) ((uint32_t)(n) < MPDDRC_DLL_WRO_WR0OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR1OFF_SHIFT (8) /* Bits 8-15: CLKWR1 Delay Line Offset */ +# define MPDDRC_DLL_WRO_WR1OFF_MASK (0xff < MPDDRC_DLL_WRO_WR1OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR1OFF(n) ((uint32_t)(n) < MPDDRC_DLL_WRO_WR1OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR2OFF_SHIFT (16) /* Bits 16-23: CLKWR2 Delay Line Offset */ +# define MPDDRC_DLL_WRO_WR2OFF_MASK (0xff < MPDDRC_DLL_WRO_WR2OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR2OFF(n) ((uint32_t)(n) < MPDDRC_DLL_WRO_WR2OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR3OFF_SHIFT (24) /* Bits 24-31: CLKWR3 Delay Line Offset */ +# define MPDDRC_DLL_WRO_WR3OFF_MASK (0xff < MPDDRC_DLL_WRO_WR3OFF_SHIFT) +# define MPDDRC_DLL_WRO_WR3OFF(n) ((uint32_t)(n) < MPDDRC_DLL_WRO_WR3OFF_SHIFT) + +/* MPDDRC DLL CLKAD Offset Register */ + +#define MPDDRC_DLL_ADO_ADOFF_SHIFT (0) /* Bits 0-7: CLKAD Delay Line Offset */ +#define MPDDRC_DLL_ADO_ADOFF_MASK (0xff < MPDDRC_DLL_ADO_ADOFF_SHIFT) +# define MPDDRC_DLL_ADO_ADOFF(n) ((uint32_t)(n) < MPDDRC_DLL_ADO_ADOFF_SHIFT) + +/* MPDDRC DLL Status MASTER 0..3 Register */ + +#define MPDDRC_DLL_SM_MDINC (1 << 0) /* Bit 0: MASTER Delay Increment */ +#define MPDDRC_DLL_SM_MDDEC (1 << 1) /* Bit 1: MASTER Delay Decrement */ +#define MPDDRC_DLL_SM_MDOVF (1 << 2) /* Bit 2: MASTER Delay Overflow Flag */ +#define MPDDRC_DLL_SM_MDLVAL_SHIFT (8) /* Bits 8-15: MASTER Delay Lock Value */ +#define MPDDRC_DLL_SM_MDLVAL_MASK (0xff < MPDDRC_DLL_SM_MDLVAL_SHIFT) +# define MPDDRC_DLL_SM_MDLVAL(n) ((uint32_t)(n) < MPDDRC_DLL_SM_MDLVAL_SHIFT) +#define MPDDRC_DLL_SM_MDCNT_SHIFT (20) /* Bits 20-27: MASTER Delay Counter Value */ +#define MPDDRC_DLL_SM_MDCNT_MASK (0xff < MPDDRC_DLL_SM_MDCNT_SHIFT) +# define MPDDRC_DLL_SM_MDCNT(n) ((uint32_t)(n) < MPDDRC_DLL_SM_MDCNT_SHIFT) + +/* MPDDRC DLL Status SLAVE 0..7 Register */ + +#define MPDDRC_DLL_SSL_SDCOVF (1 << 0) /* Bit 0: SLAVE Delay Correction Overflow Flag */ +#define MPDDRC_DLL_SSL_SDCUDF (1 << 1) /* Bit 1: SLAVE Delay Correction Underflow Flag */ +#define MPDDRC_DLL_SSL_SDERF (1 << 2) /* Bit 2: SLAVE Delay Correction Error Flag */ +#define MPDDRC_DLL_SSL_SDCNT_SHIFT (8) /* Bits 8-15: SLAVE Delay Counter Value */ +#define MPDDRC_DLL_SSL_SDCNT_MASK (0xff < MPDDRC_DLL_SSL_SDCNT_SHIFT) +# define MPDDRC_DLL_SSL_SDCNT(n) ((uint32_t)(n) < MPDDRC_DLL_SSL_SDCNT_SHIFT) +#define MPDDRC_DLL_SSL_SDCVAL_SHIFT (20) /* Bits 20-27: SLAVE Delay Correction Value */ +#define MPDDRC_DLL_SSL_SDCVAL_MASK (0xff < MPDDRC_DLL_SSL_SDCVAL_SHIFT) +# define MPDDRC_DLL_SSL_SDCVAL(n) ((uint32_t)(n) < MPDDRC_DLL_SSL_SDCVAL_SHIFT) + +/* MPDDRC DLL Status CLKWR 0..3 Register */ + +#define MPDDRC_DLL_SWR_WRDCNT_SHIFT (0) /* Bits 0-7: CLKWRx Delay Counter Value */ +#define MPDDRC_DLL_SWR_WRDCNT_MASK (0xff < MPDDRC_DLL_SWR_WRDCNT_SHIFT) +# define MPDDRC_DLL_SWR_WRDCNT(n) ((uint32_t)(n) < MPDDRC_DLL_SWR_WRDCNT_SHIFT) + +/* MPDDRC DLL Status CLKAD Register */ + +#define MPDDRC_DLL_SAD_ADDCNT_SHIFT (0) /* Bits 0-7: CLKAD Delay Counter Value */ +#define MPDDRC_DLL_SAD_ADDCNT_MASK (0xff < MPDDRC_DLL_SAD_ADDCNT_SHIFT) +# define MPDDRC_DLL_SAD_ADDCNT(n) ((uint32_t)(n) < MPDDRC_DLL_SAD_ADDCNT_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_MPDDRC_H */ diff --git a/arch/arm/src/sama5/chip/_sama5d4x_pinmap.h b/arch/arm/src/sama5/chip/_sama5d4x_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..1262fa9c15e20d030263f16611f98128f34a51f5 --- /dev/null +++ b/arch/arm/src/sama5/chip/_sama5d4x_pinmap.h @@ -0,0 +1,476 @@ +/************************************************************************************************************ + * arch/arm/src/sama5/chip/_sama5d4x_pinmap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_PINMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_PINMAP_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_pio.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ + +/* PIO pin definitions **************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. Drivers, however, will + * use the pin selection without the numeric suffix. Additional definitions are required in the board.h + * file. For example, if we wanted the PCK0 on PB26, then the following definition should appear in the + * board.h header file for that board: + * + * #define PIO_PMC_PCK0 PIO_PMC_PCK0_1 + * + * The PCK logic will then automatically configure PB26 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific PIO options such as frequency, open-drain/push-pull, + * and pull-up/down! Just the basics are defined for most pins in this file at the present time. + */ + +/* Analog-to-Digital Converter - ADC */ + +#define PIO_ADC_AD0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_ADC_AD1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_ADC_AD2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_ADC_AD3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) +#define PIO_ADC_AD4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_ADC_TRG (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN31) + +/* Advanced Interrupt Controller - AIC */ + +#define PIO_AIC_FIQ (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN9) +#define PIO_AIC_IRQ (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN25) + +/* Capacitive Touch Module - CATB */ + +#define PIO_CATB_DIS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_CATB_SENSE0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN18) +#define PIO_CATB_SENSE1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN19) +#define PIO_CATB_SENSE2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN20) +#define PIO_CATB_SENSE3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN21) +#define PIO_CATB_SENSE4 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN22) +#define PIO_CATB_SENSE5 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN23) +#define PIO_CATB_SENSE6 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN24) +#define PIO_CATB_SENSE7 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN25) +#define PIO_CATB_SENSE8 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN26) +#define PIO_CATB_SENSE9 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN27) + +/* Debug Unit - DBGU */ + +#define PIO_DBGU_DRXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_DBGU_DTXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) + +/* External Bus Interface - EBI */ + +#define PIO_EBI_A0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_EBI_A1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN1) +#define PIO_EBI_A2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN2) +#define PIO_EBI_A3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN3) +#define PIO_EBI_A4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN4) +#define PIO_EBI_A5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN5) +#define PIO_EBI_A6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN6) +#define PIO_EBI_A7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN7) +#define PIO_EBI_A8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN8) +#define PIO_EBI_A9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN9) +#define PIO_EBI_A10 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN10) +#define PIO_EBI_A11 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN11) +#define PIO_EBI_A12 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN12) +#define PIO_EBI_A13 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN13) +#define PIO_EBI_A14 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN14) +#define PIO_EBI_A15 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN15) +#define PIO_EBI_A16 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN16) +#define PIO_EBI_A17 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN17) +#define PIO_EBI_A18_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN18) +#define PIO_EBI_A18_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN26) +#define PIO_EBI_A19_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN19) +#define PIO_EBI_A19_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) +#define PIO_EBI_A20 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN20) +#define PIO_EBI_A21 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_EBI_A22 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_EBI_A23 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN21) +#define PIO_EBI_A24 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN22) +#define PIO_EBI_A25 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN23) +#define PIO_EBI_D0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_EBI_D1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_EBI_D2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_EBI_D3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_EBI_D4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_EBI_D5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_EBI_D6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_EBI_D7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_EBI_D8 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_EBI_D9 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_EBI_D10 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) +#define PIO_EBI_D11 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_EBI_D12 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_EBI_D13 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_EBI_D14 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_EBI_D15 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_EBI_NWAIT (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) + +/* RMII Ethernet 10/100 - EMAC0 */ + +#define PIO_EMAC0_COL (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) +#define PIO_EMAC0_CRS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_EMAC0_MDC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN16) +#define PIO_EMAC0_MDIO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN17) +#define PIO_EMAC0_RX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN8) +#define PIO_EMAC0_RX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN9) +#define PIO_EMAC0_RX2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_EMAC0_RX3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_EMAC0_RXCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_EMAC0_RXDV (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN6) +#define PIO_EMAC0_RXER (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN7) +#define PIO_EMAC0_TX0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN12) +#define PIO_EMAC0_TX1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN13) +#define PIO_EMAC0_TX2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_EMAC0_TX3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_EMAC0_TXCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN0) +#define PIO_EMAC0_TXEN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN2) +#define PIO_EMAC0_TXER (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) + +/* RMII Ethernet 10/100 - EMAC1 */ + +#define PIO_EMAC1_COL (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_EMAC1_CRS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_EMAC1_MDC (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_EMAC1_MDIO (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_EMAC1_RX0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_EMAC1_RX1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_EMAC1_RX2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_EMAC1_RX3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_EMAC1_RXCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_EMAC1_RXDV (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_EMAC1_RXER (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_EMAC1_TX0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_EMAC1_TX1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_EMAC1_TX2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) +#define PIO_EMAC1_TX3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_EMAC1_TXCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_EMAC1_TXEN (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_EMAC1_TXER (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) + +/* Static Memory Controller - HSMC */ + +#define PIO_HSMC_NANDALE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN17) +#define PIO_HSMC_NANDCLE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN18) +#define PIO_HSMC_NANDOE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_HSMC_NANDRDY (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN16) +#define PIO_HSMC_NANDWE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_HSMC_NBS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_HSMC_NBS1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) +#define PIO_HSMC_NCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN24) +#define PIO_HSMC_NCS1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN25) +#define PIO_HSMC_NCS2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN26) +#define PIO_HSMC_NCS3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN15) +#define PIO_HSMC_NRD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_HSMC_NWE (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN14) +#define PIO_HSMC_NWR1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) + +/* Image Sensor Interface - ISI */ + +#define PIO_ISI_D0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) +#define PIO_ISI_D1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_ISI_D2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_ISI_D3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_ISI_D4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_ISI_D5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_ISI_D6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_ISI_D7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) +#define PIO_ISI_D8 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_ISI_D9 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_ISI_D10 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_ISI_D11 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_ISI_HSYNC (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_ISI_PCK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_ISI_VSYNC (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) + +/* JTAG/SWI */ + +#define PIO_JTAG_SWCLK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_JTAG_TCK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_JTAG_TDO (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN25) +#define PIO_JTAG_TMS (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) + +/* LCD Controller - LCDC */ + +#define PIO_LCD_DAT0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN0) +#define PIO_LCD_DAT1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN1) +#define PIO_LCD_DAT2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN2) +#define PIO_LCD_DAT3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN3) +#define PIO_LCD_DAT4 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN4) +#define PIO_LCD_DAT5 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN5) +#define PIO_LCD_DAT6 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN6) +#define PIO_LCD_DAT7 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN7) +#define PIO_LCD_DAT8 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN8) +#define PIO_LCD_DAT9 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN9) +#define PIO_LCD_DAT10 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN10) +#define PIO_LCD_DAT11 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN11) +#define PIO_LCD_DAT12 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN12) +#define PIO_LCD_DAT13 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN13) +#define PIO_LCD_DAT14 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN14) +#define PIO_LCD_DAT15 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN15) +#define PIO_LCD_DAT16 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) +#define PIO_LCD_DAT17 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN17) +#define PIO_LCD_DAT18 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN18) +#define PIO_LCD_DAT19 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN19) +#define PIO_LCD_DAT20 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN20) +#define PIO_LCD_DAT21 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN21) +#define PIO_LCD_DAT22 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN22) +#define PIO_LCD_DAT23 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN23) +#define PIO_LCD_DEN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_LCD_DISP (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_LCD_HSYNC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_LCD_PCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_LCD_PWM (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_LCD_VSYNC (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) + +/* High Speed Multimedia Card Interface - HSMCI0-1 */ + +#define PIO_MCI0_CDA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN5) +#define PIO_MCI0_CDB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_MCI0_CK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_MCI0_DA0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN6) +#define PIO_MCI0_DA1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN7) +#define PIO_MCI0_DA2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN8) +#define PIO_MCI0_DA3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN9) +#define PIO_MCI0_DA4 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN10) +#define PIO_MCI0_DA5 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN11) +#define PIO_MCI0_DA6 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN12) +#define PIO_MCI0_DA7 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN13) +#define PIO_MCI0_DB0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN1) +#define PIO_MCI0_DB1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN2) +#define PIO_MCI0_DB2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN3) +#define PIO_MCI0_DB3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN4) + +#define PIO_MCI1_CDA (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN19) +#define PIO_MCI1_CK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN18) +#define PIO_MCI1_DA0 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN20) +#define PIO_MCI1_DA1 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN21) +#define PIO_MCI1_DA2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN22) +#define PIO_MCI1_DA3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN23) + +/* Clocks, Oscillators and PLLs */ + +#define PIO_PMC_PCK0_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_PMC_PCK0_2 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN8) +#define PIO_PMC_PCK0_3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN24) +#define PIO_PMC_PCK1_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) +#define PIO_PMC_PCK1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_PMC_PCK1_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_PMC_PCK2_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_PMC_PCK2_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) + +/* Pulse Width Modulation Controller- PWMC */ + +#define PIO_PWM0_FI (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_PWM0_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) +#define PIO_PWM0_H_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_PWM0_H_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_PWM0_H_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN30) +#define PIO_PWM0_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_PWM0_L_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_PWM0_L_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_PWM0_L_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) + +#define PIO_PWM1_FI (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN7) +#define PIO_PWM1_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_PWM1_H_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_PWM1_H_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_PWM1_H_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN31) +#define PIO_PWM1_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN29) +#define PIO_PWM1_L_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN10) +#define PIO_PWM1_L_3 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_PWM1_L_4 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) + +#define PIO_PWM2_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_PWM2_H_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN12) +#define PIO_PWM2_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_PWM2_L_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN13) + +#define PIO_PWM3_H_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) +#define PIO_PWM3_H_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN14) +#define PIO_PWM3_L_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_PWM3_L_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN8) + +/* Reset Control -- RSTC */ + +#define PIO_RSTC_NTRST (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN16) + +/* Softe Modem - SMD */ + +#define PIO_SMD_DIBN (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN30) +#define PIO_SMD_DIBP (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) + +/* Serial Peripheral Interface - SPIx [1..0] */ + +#define PIO_SPI0_MISO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN0) +#define PIO_SPI0_MOSI (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN1) +#define PIO_SPI0_NPCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN3) +#define PIO_SPI0_NPCS1_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN4) +#define PIO_SPI0_NPCS1_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN27) +#define PIO_SPI0_NPCS2_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN31) +#define PIO_SPI0_NPCS2_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN28) +#define PIO_SPI0_NPCS3 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN29) +#define PIO_SPI0_SPCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN2) + +#define PIO_SPI1_MISO (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN18) +#define PIO_SPI1_MOSI (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN19) +#define PIO_SPI1_NPCS0 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN21) +#define PIO_SPI1_NPCS1_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN22) +#define PIO_SPI1_NPCS1_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN26) +#define PIO_SPI1_NPCS2_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN23) +#define PIO_SPI1_NPCS2_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN27) +#define PIO_SPI1_NPCS3_1 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) +#define PIO_SPI1_NPCS3_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN28) +#define PIO_SPI1_SPCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN20) + +#define PIO_SPI2_MISO (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_SPI2_MOSI (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) +#define PIO_SPI2_NPCS0 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) +#define PIO_SPI2_NPCS1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN14) +#define PIO_SPI2_NPCS2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN15) +#define PIO_SPI2_NPCS3 (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_SPI2_SPCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) + +/* Synchronous Serial Controller - SSCx [1..0] */ + +#define PIO_SSC0_RD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) +#define PIO_SSC0_RF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_SSC0_RK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN26) +#define PIO_SSC0_TD_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN25) +#define PIO_SSC0_TD_2 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN28) +#define PIO_SSC0_TF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN31) +#define PIO_SSC0_TK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN27) + +#define PIO_SSC1_RD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN23) +#define PIO_SSC1_RF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN22) +#define PIO_SSC1_RK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN24) +#define PIO_SSC1_TD_1 (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN21) +#define PIO_SSC1_TD_2 (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN24) +#define PIO_SSC1_TF (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN20) +#define PIO_SSC1_TK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN19) + +/* Timer/Counter - TCx [5..0] */ + +#define PIO_TC0_CLK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN17) +#define PIO_TC0_IOA (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN15) +#define PIO_TC0_IOB (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN16) + +#define PIO_TC1_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN14) +#define PIO_TC1_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN12) +#define PIO_TC1_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN13) + +#define PIO_TC2_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN11) +#define PIO_TC2_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN9) +#define PIO_TC2_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN10) + +#define PIO_TC3_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN8) +#define PIO_TC3_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN6) +#define PIO_TC3_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN7) + +#define PIO_TC4_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN23) +#define PIO_TC4_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN21) +#define PIO_TC4_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN22) + +#define PIO_TC5_CLK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN20) +#define PIO_TC5_IOA (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN18) +#define PIO_TC5_IOB (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN19) + +/* What about TC6-8? */ + +/* Two-Wire Interface -TWIx [3..0] */ + +#define PIO_TWI0_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN31) +#define PIO_TWI0_D (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOA | PIO_PIN30) + +#define PIO_TWI1_CK (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN30) +#define PIO_TWI1_D (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) + +#define PIO_TWI2_CK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN30) +#define PIO_TWI2_D (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN29) + +#define PIO_TWI3_CK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) +#define PIO_TWI3_D (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) + +/* Universal Asynchronous Receiver Transmitter - UARTx [1..0] */ + +#define PIO_UART0_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN29) +#define PIO_UART0_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN30) + +#define PIO_UART1_RXD (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN25) +#define PIO_UART1_TXD (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOC | PIO_PIN26) + +/* Universal Synchronous Asynchronous Receiver Transmitter- USART0-4 */ + +#define PIO_USART0_CTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN10) +#define PIO_USART0_RTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN11) +#define PIO_USART0_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN12) +#define PIO_USART0_SCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN28) +#define PIO_USART0_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN13) + +#define PIO_USART1_CTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN14) +#define PIO_USART1_RTS (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN15) +#define PIO_USART1_RXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN16) +#define PIO_USART1_SCK (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN29) +#define PIO_USART1_TXD (PIO_PERIPHA | PIO_CFG_DEFAULT | PIO_PORT_PIOD | PIO_PIN17) + +#define PIO_USART2_CTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN3) +#define PIO_USART2_RTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN11) +#define PIO_USART2_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN4) +#define PIO_USART2_SCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN1) +#define PIO_USART2_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOB | PIO_PIN5) + +#define PIO_USART3_CTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN5) +#define PIO_USART3_RTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN24) +#define PIO_USART3_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN16) +#define PIO_USART3_SCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN15) +#define PIO_USART3_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN17) + +#define PIO_USART4_CTS (PIO_PERIPHC | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN0) +#define PIO_USART4_RTS (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN28) +#define PIO_USART4_RXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN26) +#define PIO_USART4_SCK (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN25) +#define PIO_USART4_TXD (PIO_PERIPHB | PIO_CFG_DEFAULT | PIO_PORT_PIOE | PIO_PIN27) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP__SAMA5D4X_PINMAP_H */ diff --git a/arch/arm/src/sama5/chip/sam_adc.h b/arch/arm/src/sama5/chip/sam_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..3d65aa214e853e84db24b597b356f467b59fddeb --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_adc.h @@ -0,0 +1,606 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_adc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ADC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ADC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#if defined(ATSAMA5D3) +# define SAM_ADC_NCHANNELS 12 /* 12 ADC Channels */ +#elif defined(ATSAMA5D4) +# define SAM_ADC_NCHANNELS 5 /* 5 ADC Channels */ +#endif + +#define SAM_ADC_MAXPERCLK 66000000 /* Maximum peripheral clock frequency */ +#define SAM_ADC_CLOCKMAX 20000000 /* Maximum ADC Clock Frequency (Hz) */ + +/* ADC register offsets ****************************************************************/ + +#define SAM_ADC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_ADC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_ADC_SEQR1_OFFSET 0x0008 /* Channel Sequence Register 1 */ +#define SAM_ADC_SEQR2_OFFSET 0x000c /* Channel Sequence Register 2 */ +#define SAM_ADC_CHER_OFFSET 0x0010 /* Channel Enable Register */ +#define SAM_ADC_CHDR_OFFSET 0x0014 /* Channel Disable Register */ +#define SAM_ADC_CHSR_OFFSET 0x0018 /* Channel Status Register */ + /* 0x001c Reserved */ +#define SAM_ADC_LCDR_OFFSET 0x0020 /* Last Converted Data Register */ +#define SAM_ADC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_ADC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_ADC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_ADC_ISR_OFFSET 0x0030 /* Interrupt Status Register */ + /* 0x0034-38 Reserved */ +#define SAM_ADC_OVER_OFFSET 0x003c /* Overrun Status Register */ +#define SAM_ADC_EMR_OFFSET 0x0040 /* Extended Mode Register */ +#define SAM_ADC_CWR_OFFSET 0x0044 /* Compare Window Register */ + +#ifdef ATSAMA5D3 +# define SAM_ADC_CGR_OFFSET 0x0048 /* Channel Gain Register */ +# define SAM_ADC_COR_OFFSET 0x004c /* Channel Offset Register */ +#endif + +#define SAM_ADC_CDR_OFFSET(n) (0x0050+((n)<<2)) +#define SAM_ADC_CDR0_OFFSET 0x0050 /* Channel Data Register 0 */ +#define SAM_ADC_CDR1_OFFSET 0x0054 /* Channel Data Register 1 */ +#define SAM_ADC_CDR2_OFFSET 0x0058 /* Channel Data Register 2 */ +#define SAM_ADC_CDR3_OFFSET 0x005c /* Channel Data Register 3 */ +#define SAM_ADC_CDR4_OFFSET 0x0060 /* Channel Data Register 4 */ + +#ifdef ATSAMA5D3 +# define SAM_ADC_CDR5_OFFSET 0x0064 /* Channel Data Register 5 */ +# define SAM_ADC_CDR6_OFFSET 0x0068 /* Channel Data Register 6 */ +# define SAM_ADC_CDR7_OFFSET 0x006c /* Channel Data Register 7 */ +# define SAM_ADC_CDR8_OFFSET 0x0070 /* Channel Data Register 8 */ +# define SAM_ADC_CDR9_OFFSET 0x0074 /* Channel Data Register 9 */ +# define SAM_ADC_CDR10_OFFSET 0x0078 /* Channel Data Register 10 */ +# define SAM_ADC_CDR11_OFFSET 0x007c /* Channel Data Register 11 */ +#endif + /* 0x0080-90 Reserved */ +#define SAM_ADC_ACR_OFFSET 0x0094 /* Analog Control Register */ + /* 0x0098-ac Reserved */ +#define SAM_ADC_TSMR_OFFSET 0x00b0 /* Touchscreen Mode Register */ +#define SAM_ADC_XPOSR_OFFSET 0x00b4 /* Touchscreen X Position Register */ +#define SAM_ADC_YPOSR_OFFSET 0x00b8 /* Touchscreen Y Position Register */ +#define SAM_ADC_PRESSR_OFFSET 0x00bc /* Touchscreen Pressure Register */ +#define SAM_ADC_TRGR_OFFSET 0x00c0 /* Trigger Register */ + /* 0x00c4-e0 Reserved */ +#define SAM_ADC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_ADC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-fc Reserved */ + +/* ADC register adresses ***************************************************************/ + +#define SAM_ADC_CR (SAM_TSADC_VBASE+SAM_ADC_CR_OFFSET) +#define SAM_ADC_MR (SAM_TSADC_VBASE+SAM_ADC_MR_OFFSET) +#define SAM_ADC_SEQR1 (SAM_TSADC_VBASE+SAM_ADC_SEQR1_OFFSET) +#define SAM_ADC_SEQR2 (SAM_TSADC_VBASE+SAM_ADC_SEQR2_OFFSET) +#define SAM_ADC_CHER (SAM_TSADC_VBASE+SAM_ADC_CHER_OFFSET) +#define SAM_ADC_CHDR (SAM_TSADC_VBASE+SAM_ADC_CHDR_OFFSET) +#define SAM_ADC_CHSR (SAM_TSADC_VBASE+SAM_ADC_CHSR_OFFSET) +#define SAM_ADC_LCDR (SAM_TSADC_VBASE+SAM_ADC_LCDR_OFFSET) +#define SAM_ADC_IER (SAM_TSADC_VBASE+SAM_ADC_IER_OFFSET) +#define SAM_ADC_IDR (SAM_TSADC_VBASE+SAM_ADC_IDR_OFFSET) +#define SAM_ADC_IMR (SAM_TSADC_VBASE+SAM_ADC_IMR_OFFSET) +#define SAM_ADC_ISR (SAM_TSADC_VBASE+SAM_ADC_ISR_OFFSET) +#define SAM_ADC_OVER (SAM_TSADC_VBASE+SAM_ADC_OVER_OFFSET) +#define SAM_ADC_EMR (SAM_TSADC_VBASE+SAM_ADC_EMR_OFFSET) +#define SAM_ADC_CWR (SAM_TSADC_VBASE+SAM_ADC_CWR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_ADC_CGR (SAM_TSADC_VBASE+SAM_ADC_CGR_OFFSET) +# define SAM_ADC_COR (SAM_TSADC_VBASE+SAM_ADC_COR_OFFSET) +#endif + +#define SAM_ADC_CDR(n) (SAM_TSADC_VBASE+SAM_ADC_CDR_OFFSET(n)) +#define SAM_ADC_CDR0 (SAM_TSADC_VBASE+SAM_ADC_CDR0_OFFSET) +#define SAM_ADC_CDR1 (SAM_TSADC_VBASE+SAM_ADC_CDR1_OFFSET) +#define SAM_ADC_CDR2 (SAM_TSADC_VBASE+SAM_ADC_CDR2_OFFSET) +#define SAM_ADC_CDR3 (SAM_TSADC_VBASE+SAM_ADC_CDR3_OFFSET) +#define SAM_ADC_CDR4 (SAM_TSADC_VBASE+SAM_ADC_CDR4_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_ADC_CDR5 (SAM_TSADC_VBASE+SAM_ADC_CDR5_OFFSET) +# define SAM_ADC_CDR6 (SAM_TSADC_VBASE+SAM_ADC_CDR6_OFFSET) +# define SAM_ADC_CDR7 (SAM_TSADC_VBASE+SAM_ADC_CDR7_OFFSET) +# define SAM_ADC_CDR8 (SAM_TSADC_VBASE+SAM_ADC_CDR8_OFFSET) +# define SAM_ADC_CDR9 (SAM_TSADC_VBASE+SAM_ADC_CDR9_OFFSET) +# define SAM_ADC_CDR10 (SAM_TSADC_VBASE+SAM_ADC_CDR10_OFFSET) +# define SAM_ADC_CDR11 (SAM_TSADC_VBASE+SAM_ADC_CDR11_OFFSET) +#endif + +#define SAM_ADC_ACR (SAM_TSADC_VBASE+SAM_ADC_ACR_OFFSET) +#define SAM_ADC_TSMR (SAM_TSADC_VBASE+SAM_ADC_TSMR_OFFSET) +#define SAM_ADC_XPOSR (SAM_TSADC_VBASE+SAM_ADC_XPOSR_OFFSET) +#define SAM_ADC_YPOSR (SAM_TSADC_VBASE+SAM_ADC_YPOSR_OFFSET) +#define SAM_ADC_PRESSR (SAM_TSADC_VBASE+SAM_ADC_PRESSR_OFFSET) +#define SAM_ADC_TRGR (SAM_TSADC_VBASE+SAM_ADC_TRGR_OFFSET) +#define SAM_ADC_WPMR (SAM_TSADC_VBASE+SAM_ADC_WPMR_OFFSET) +#define SAM_ADC_WPSR (SAM_TSADC_VBASE+SAM_ADC_WPSR_OFFSET) + +/* ADC register bit definitions ********************************************************/ + +/* Control Register and ADC Control Register common bit-field definitions */ + +#define ADC_CR_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define ADC_CR_START (1 << 1) /* Bit 1: Start Conversion */ +#define ADC_CR_TSCALIB (1 << 2) /* Bit 2: Touchscreen Calibration */ + +#ifdef ATSAMA5D3 +# define ADC_CR_AUTOCAL (1 << 3) /* Bit 3: Automatic Calibration of ADC */ +#endif + +/* Mode Register and ADC Mode Register common bit-field definitions */ + +#define ADC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define ADC_MR_TRGSEL_MASK (7 << ADC_MR_TRGSEL_SHIFT) +# define ADC_MR_TRGSEL_ADTRG (0 << ADC_MR_TRGSEL_SHIFT) /* ADTRG */ +# define ADC_MR_TRGSEL_TIOA0 (1 << ADC_MR_TRGSEL_SHIFT) /* TIOA0 */ +# define ADC_MR_TRGSEL_TIOA1 (2 << ADC_MR_TRGSEL_SHIFT) /* TIOA1 */ +# define ADC_MR_TRGSEL_TIOA2 (3 << ADC_MR_TRGSEL_SHIFT) /* TIOA2 */ +# define ADC_MR_TRGSEL_PWM0 (4 << ADC_MR_TRGSEL_SHIFT) /* PWM Event Line 0 */ +# define ADC_MR_TRGSEL_PWM1 (5 << ADC_MR_TRGSEL_SHIFT) /* PWM Event Line 1 */ + +#ifdef ATSAMA5D4 +# define ADC_MR_LOWRES (1 << 4) /* Bit 4: LOWRES: Resolution */ +#endif + +#define ADC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ + +#ifdef ATSAMA5D3 +# define ADC_MR_FWUP (1 << 6) /* Bit 6: Fast Wake Up */ +#endif + +#define ADC_MR_PRESCAL_SHIFT (8) /* Bits 8-15: Prescaler Rate Selection */ +#define ADC_MR_PRESCAL_MASK (0xff << ADC_MR_PRESCAL_SHIFT) +# define ADC_MR_PRESCAL(n) ((uint32_t)(n) << ADC_MR_PRESCAL_SHIFT) +#define ADC_MR_STARTUP_SHIFT (16) /* Bits 16-19: Start Up Time */ +#define ADC_MR_STARTUP_MASK (15 << ADC_MR_STARTUP_SHIFT) +# define ADC_MR_STARTUP_0 (0 << ADC_MR_STARTUP_SHIFT) /* 0 periods of ADCClock */ +# define ADC_MR_STARTUP_8 (1 << ADC_MR_STARTUP_SHIFT) /* 8 periods of ADCClock */ +# define ADC_MR_STARTUP_16 (2 << ADC_MR_STARTUP_SHIFT) /* 16 periods of ADCClock */ +# define ADC_MR_STARTUP_24 (3 << ADC_MR_STARTUP_SHIFT) /* 24 periods of ADCClock */ +# define ADC_MR_STARTUP_64 (4 << ADC_MR_STARTUP_SHIFT) /* 64 periods of ADCClock */ +# define ADC_MR_STARTUP_80 (5 << ADC_MR_STARTUP_SHIFT) /* 80 periods of ADCClock */ +# define ADC_MR_STARTUP_96 (6 << ADC_MR_STARTUP_SHIFT) /* 96 periods of ADCClock */ +# define ADC_MR_STARTUP_112 (7 << ADC_MR_STARTUP_SHIFT) /* 112 periods of ADCClock */ +# define ADC_MR_STARTUP_512 (8 << ADC_MR_STARTUP_SHIFT) /* 512 periods of ADCClock */ +# define ADC_MR_STARTUP_576 (9 << ADC_MR_STARTUP_SHIFT) /* 576 periods of ADCClock */ +# define ADC_MR_STARTUP_640 (10 << ADC_MR_STARTUP_SHIFT) /* 640 periods of ADCClock */ +# define ADC_MR_STARTUP_704 (11 << ADC_MR_STARTUP_SHIFT) /* 704 periods of ADCClock */ +# define ADC_MR_STARTUP_768 (12 << ADC_MR_STARTUP_SHIFT) /* 768 periods of ADCClock */ +# define ADC_MR_STARTUP_832 (13 << ADC_MR_STARTUP_SHIFT) /* 832 periods of ADCClock */ +# define ADC_MR_STARTUP_896 (14 << ADC_MR_STARTUP_SHIFT) /* 896 periods of ADCClock */ +# define ADC_MR_STARTUP_960 (15 << ADC_MR_STARTUP_SHIFT) /* 960 periods of ADCClock */ + +#ifdef ATSAMA5D3 +# define ADC_MR_SETTLING_SHIFT (20) /* Bits 20-21: Analog Settling Time */ +# define ADC_MR_SETTLING_MASK (15 << ADC_MR_SETTLING_SHIFT) +# define ADC_MR_SETTLING_3 (0 << ADC_MR_SETTLING_SHIFT) /* 3 periods of ADCClock */ +# define ADC_MR_SETTLING_5 (1 << ADC_MR_SETTLING_SHIFT) /* 5 periods of ADCClock */ +# define ADC_MR_SETTLING_9 (2 << ADC_MR_SETTLING_SHIFT) /* 9 periods of ADCClock */ +# define ADC_MR_SETTLING_17 (3 << ADC_MR_SETTLING_SHIFT) /* 17 periods of ADCClock */ +# define ADC_MR_ANACH (1 << 23) /* Bit 23: Analog Change */ +#endif + +#define ADC_MR_TRACKTIM_SHIFT (24) /* Bits 24-27: Tracking Time */ +#define ADC_MR_TRACKTIM_MASK (15 << ADC_MR_TRACKTIM_SHIFT) +# define ADC_MR_TRACKTIM(n) ((uint32_t)(n) << ADC_MR_TRACKTIM_SHIFT) + +#ifdef ATSAMA5D3 +# define ADC_MR_TRANSFER_SHIFT (28) /* Bits 28-29: Transfer Period */ +# define ADC_MR_TRANSFER_MASK (3 << ADC_MR_TRANSFER_SHIFT) +# define ADC_MR_TRANSFER (2 << ADC_MR_TRANSFER_SHIFT) /* Must be 2 */ +#endif + +#define ADC_MR_USEQ (1 << 31) /* Bit 31: Use Sequence Enable */ + +/* Channel Sequence Register 1 */ + +#define ADC_SEQR1_USCH_SHIFT(n) (((n)-1) << 2) /* n=1..8 */ +#define ADC_SEQR1_USCH_MASK(n) (15 << ADC_SEQR1_USCH_SHIFT(n)) +# define ADC_SEQR1_USCH(n,v) ((uint32_t)(v) << ADC_SEQR1_USCH_SHIFT(n)) +#define ADC_SEQR1_USCH1_SHIFT (0) /* Bits 0-3: User sequence number 1 */ +#define ADC_SEQR1_USCH1_MASK (15 << ADC_SEQR1_USCH1_SHIFT) +# define ADC_SEQR1_USCH1(v) ((uint32_t)(v) << ADC_SEQR1_USCH1_SHIFT) +#define ADC_SEQR1_USCH2_SHIFT (4) /* Bits 4-7: User sequence number 2 */ +#define ADC_SEQR1_USCH2_MASK (15 << ADC_SEQR1_USCH2_SHIFT) +# define ADC_SEQR1_USCH2(v) ((uint32_t)(v) << ADC_SEQR1_USCH2_SHIFT) +#define ADC_SEQR1_USCH3_SHIFT (8) /* Bits 8-11: User sequence number 3 */ +#define ADC_SEQR1_USCH3_MASK (15 << ADC_SEQR1_USCH3_SHIFT) +# define ADC_SEQR1_USCH3(v) ((uint32_t)(v) << ADC_SEQR1_USCH3_SHIFT) +#define ADC_SEQR1_USCH4_SHIFT (12) /* Bits 12-15: User sequence number 4 */ +#define ADC_SEQR1_USCH4_MASK (15 << ADC_SEQR1_USCH4_SHIFT) +# define ADC_SEQR1_USCH4(v) ((uint32_t)(v) << ADC_SEQR1_USCH4_SHIFT) + +#ifdef ATSAMA5D3 +# define ADC_SEQR1_USCH5_SHIFT (16) /* Bits 16-19: User sequence number 5 */ +# define ADC_SEQR1_USCH5_MASK (15 << ADC_SEQR1_USCH5_SHIFT) +# define ADC_SEQR1_USCH5(v) ((uint32_t)(v) << ADC_SEQR1_USCH5_SHIFT) +# define ADC_SEQR1_USCH6_SHIFT (20) /* Bits 20-23: User sequence number 6 */ +# define ADC_SEQR1_USCH6_MASK (15 << ADC_SEQR1_USCH6_SHIFT) +# define ADC_SEQR1_USCH6(v) ((uint32_t)(v) << ADC_SEQR1_USCH6_SHIFT) +# define ADC_SEQR1_USCH7_SHIFT (24) /* Bits 24-27: User sequence number 7 */ +# define ADC_SEQR1_USCH7_MASK (15 << ADC_SEQR1_USCH7_SHIFT) +# define ADC_SEQR1_USCH7(v) ((uint32_t)(v) << ADC_SEQR1_USCH7_SHIFT) +# define ADC_SEQR1_USCH8_SHIFT (28) /* Bits 28-31: User sequence number 8 */ +# define ADC_SEQR1_USCH8_MASK (15 << ADC_SEQR1_USCH8_SHIFT) +# define ADC_SEQR1_USCH8(v) ((uint32_t)(v) << ADC_SEQR1_USCH8_SHIFT) +#endif + +#ifdef ATSAMA5D3 +/* Channel Sequence Register 2 */ + +# define ADC_SEQR2_USCH_SHIFT(n) (((n)-9) << 2) /* n=9..11 */ +# define ADC_SEQR2_USCH_MASK(n) (15 << ADC_SEQR2_USCH_SHIFT(n)) +# define ADC_SEQR2_USCH(n,v) ((uint32_t)(v) << ADC_SEQR2_USCH_SHIFT(n)) +# define ADC_SEQR2_USCH9_SHIFT (0) /* Bits 0-3: User sequence number 9 */ +# define ADC_SEQR2_USCH9_MASK (15 << ADC_SEQR2_USCH9_SHIFT) +# define ADC_SEQR2_USCH9(v) ((uint32_t)(v) << ADC_SEQR2_USCH9_SHIFT) +# define ADC_SEQR2_USCH10_SHIFT (4) /* Bits 4-7: User sequence number 10 */ +# define ADC_SEQR2_USCH10_MASK (15 << ADC_SEQR2_USCH10_SHIFT) +# define ADC_SEQR2_USCH10(v) ((uint32_t)(v) << ADC_SEQR2_USCH10_SHIFT) +# define ADC_SEQR2_USCH11_SHIFT (8) /* Bits 8-11: User sequence number 11 */ +# define ADC_SEQR2_USCH11_MASK (15 << ADC_SEQR2_USCH11_SHIFT) +# define ADC_SEQR2_USCH11(v) ((uint32_t)(v) << ADC_SEQR2_USCH11_SHIFT) +#endif + +/* Channel Enable Register, Channel Disable Register, Channel + * Status Register, ADC Channel Enable Register, ADC Channel Disable Register, + * and ADC Channel Status Register common bit-field definitions + */ + +#define ADC_CH(n) (1 << (n)) +#define ADC_CH0 (1 << 0) /* Bit 0: Channel 0 Enable */ +#define ADC_CH1 (1 << 1) /* Bit 1: Channel 1 Enable */ +#define ADC_CH2 (1 << 2) /* Bit 2: Channel 2 Enable */ +#define ADC_CH3 (1 << 3) /* Bit 3: Channel 3 Enable */ +#define ADC_CH4 (1 << 4) /* Bit 4: Channel 4 Enable */ +#define ADC_CH5 (1 << 5) /* Bit 5: Channel 5 Enable */ + +#ifdef ATSAMA5D3 +# define ADC_CH6 (1 << 6) /* Bit 6: Channel 6 Enable */ +# define ADC_CH7 (1 << 7) /* Bit 7: Channel 7 Enable */ +# define ADC_CH8 (1 << 8) /* Bit 8: Channel 8 Enable */ +# define ADC_CH9 (1 << 9) /* Bit 9: Channel 9 Enable */ +# define ADC_CH10 (1 << 10) /* Bit 10: Channel 10 Enable */ +# define ADC_CH11 (1 << 11) /* Bit 11: Channel 11 Enable */ +#endif + +#define TSD_4WIRE_ALL (0x0000000f) +#define TSD_5WIRE_ALL (0x0000001f) + +#if defined(ATSAMA5D3) +# define ADC_CHALL (0x00000fff) +#elif defined(ATSAMA5D4) +# define ADC_CHALL (0x0000001f) +#endif + +/* Last Converted Data Register */ + +#define ADC_LCDR_DATA_SHIFT (0) /* Bits 0-11: Last Data Converted */ +#define ADC_LCDR_DATA_MASK (0xfff << ADC_LCDR_DATA_SHIFT) +#define ADC_LCDR_CHANB_SHIFT (12) /* Bits 12-15: Channel number */ +#define ADC_LCDR_CHANB_MASK (15 << ADC_LCDR_CHANB_SHIFT) + +/* Status Register , Interrupt Enable Register, Interrupt + * Disable Register, Interrupt Mask Register, ADC Status Register, + * ADC Interrupt Enable Register, ADC Interrupt Disable Register, and + * ADC Interrupt Mask Register common bit-field definitions + */ + +#define ADC_INT_EOC(n) (1 << (n)) +#define ADC_INT_EOC0 (1 << 0) /* Bit 0: End of Conversion 0 */ +#define ADC_INT_EOC1 (1 << 1) /* Bit 1: End of Conversion 1 */ +#define ADC_INT_EOC2 (1 << 2) /* Bit 2: End of Conversion 2 */ +#define ADC_INT_EOC3 (1 << 3) /* Bit 3: End of Conversion 3 */ +#define ADC_INT_EOC4 (1 << 4) /* Bit 4: End of Conversion 4 */ + +#if defined(ATSAMA5D3) +# define ADC_INT_EOC5 (1 << 5) /* Bit 5: End of Conversion 5 */ +# define ADC_INT_EOC6 (1 << 6) /* Bit 6: End of Conversion 6 */ +# define ADC_INT_EOC7 (1 << 7) /* Bit 7: End of Conversion 7 */ +# define ADC_INT_EOC8 (1 << 8) /* Bit 8: End of Conversion 8 */ +# define ADC_INT_EOC9 (1 << 9) /* Bit 9: End of Conversion 9 */ +# define ADC_INT_EOC10 (1 << 10) /* Bit 10: End of Conversion 10 */ +# define ADC_INT_EOC11 (1 << 11) /* Bit 11: End of Conversion 11 */ +# define ADC_INT_EOCALL (0x00000fff) +#elif defined(ATSAMA5D4) +# define ADC_INT_EOCALL (0x0000001f) +#endif + +#define ADC_INT_XRDY (1 << 20) /* Bit 20: TS Measure XPOS Ready Interrupt */ +#define ADC_INT_YRDY (1 << 21) /* Bit 21: TS Measure YPOS Ready Interrupt */ +#define ADC_INT_PRDY (1 << 22) /* Bit 22: TS Measure Pressure Ready Interrupt */ + +#ifdef ATSAMA5D3 +# define ADC_INT_EOCAL (1 << 23) /* Bit 23: End of Calibration Sequence */ +#endif + +#define ADC_INT_DRDY (1 << 24) /* Bit 24: Data Ready Interrupt */ +#define ADC_INT_GOVRE (1 << 25) /* Bit 25: General Overrun Error */ +#define ADC_INT_COMPE (1 << 26) /* Bit 26: Comparison Event Interrupt */ +#define ADC_INT_PEN (1 << 29) /* Bit 29: Pen Contact Interrupt */ +#define ADC_INT_NOPEN (1 << 30) /* Bit 30: No Pen Contact Interrupt */ +#define ADC_SR_PENS (1 << 31) /* Bit 31: Pen detect Status (SR only) */ + +#define ADC_INT_ALL (0xe7f00fff) + +/* Overrun Status Register */ + +#define ADC_OVER_OVRE(n) (1 << (n)) +#define ADC_OVER_OVRE0 (1 << 0) /* Bit 0: Overrun Error 0 */ +#define ADC_OVER_OVRE1 (1 << 1) /* Bit 1: Overrun Error 1 */ +#define ADC_OVER_OVRE2 (1 << 2) /* Bit 2: Overrun Error 2 */ +#define ADC_OVER_OVRE3 (1 << 3) /* Bit 3: Overrun Error 3 */ +#define ADC_OVER_OVRE4 (1 << 4) /* Bit 4: Overrun Error 4 */ + +#ifdef ATSAMA5D3 +# define ADC_OVER_OVRE5 (1 << 5) /* Bit 5: Overrun Error 5 */ +# define ADC_OVER_OVRE6 (1 << 6) /* Bit 6: Overrun Error 6 */ +# define ADC_OVER_OVRE7 (1 << 7) /* Bit 7: Overrun Error 7 */ +# define ADC_OVER_OVRE8 (1 << 8) /* Bit 8: Overrun Error 8 */ +# define ADC_OVER_OVRE9 (1 << 9) /* Bit 9: Overrun Error 9 */ +# define ADC_OVER_OVRE10 (1 << 10) /* Bit 10: Overrun Error 10 */ +# define ADC_OVER_OVRE11 (1 << 11) /* Bit 11: Overrun Error 11 */ +#endif + +/* Extended Mode Register */ + +#define ADC_EMR_CMPMODE_SHIFT (0) /* Bit 0-1: Comparison Mode */ +#define ADC_EMR_CMPMODE_MASK (3 << ADC_EMR_CMPMODE_SHIFT) +# define ADC_EMR_CMPMODE_LOW (0 << ADC_EMR_CMPMODE_SHIFT) /* Event when lower than low window threshold */ +# define ADC_EMR_CMPMODE_HIGH (1 << ADC_EMR_CMPMODE_SHIFT) /* Event when higher than high window threshold */ +# define ADC_EMR_CMPMODE_IN (2 << ADC_EMR_CMPMODE_SHIFT) /* Event when in comparison window */ +# define ADC_EMR_CMPMODE_OUT (3 << ADC_EMR_CMPMODE_SHIFT) /* Event when out of comparison window */ +#define ADC_EMR_CMPSEL_SHIFT (4) /* Bit 4-7: Comparison Selected Channel */ +#define ADC_EMR_CMPSEL_MASK (15 << ADC_EMR_CMPSEL_SHIFT) +# define ADC_EMR_CMPSEL(n) ((uint32_t)(n) << ADC_EMR_CMPSEL_SHIFT) +#define ADC_EMR_CMPALL (1 << 9) /* Bit 9: Compare All Channels */ +#define ADC_EMR_CMPFILTER_SHIFT (12) /* Bit 12-13: Compare Event Filtering */ +#define ADC_EMR_CMPFILTER_MASK (3 << ADC_EMR_CMPFILTER_SHIFT) +# define ADC_EMR_CMPFILTER(n) ((uint32_t)(n) << ADC_EMR_CMPFILTER_SHIFT) + +#ifdef ATSAMA5D4 +# define ADC_EMR_OSR_SHIFT (16) /* Bit 16-17: Compare Event Filtering */ +# define ADC_EMR_OSR_MASK (3 << ADC_EMR_OSR_SHIFT) +# define ADC_EMR_OSR_NOAVG (0 << ADC_EMR_OSR_SHIFT) /* No averaging */ +# define ADC_EMR_OSR_OSR4 (1 << ADC_EMR_OSR_SHIFT) /* 1-bit averaging. ADC sample rate / 4 */ +# define ADC_EMR_OSR_OSR16 (2 << ADC_EMR_OSR_SHIFT) /* 2-bit averaging. ADC sample rate / 16 */ +# define ADC_EMR_ASTE (1 << 10) /* Bit 10: Averaging on Single Trigger Event */ +#endif + +#define ADC_EMR_TAG (1 << 24) /* Bit 24: TAG of the ADC_LDCR register */ + +#ifdef ATSAMA5D3 +/* Channel Gain Register */ + +# define ADC_CGR_GAIN_SHIFT(n) ((n) << 1) /* n=0..11 */ +# define ADC_CGR_GAIN_MASK(n) (3 << ADC_CGR_GAIN_SHIFT(n)) +# define ADC_CGR_GAIN(n,v) ((uint32_t)(v) << ADC_CGR_GAIN_SHIFT(n)) +# define ADC_CGR_GAIN0_SHIFT (0) /* Bits 0-1: Gain for channel 0 */ +# define ADC_CGR_GAIN0_MASK (3 << ADC_CGR_GAIN0_SHIFT) +# define ADC_CGR_GAIN0(v) ((uint32_t)(v) << ADC_CGR_GAIN0_SHIFT) +# define ADC_CGR_GAIN1_SHIFT (2) /* Bits 2-3: Gain for channel 1 */ +# define ADC_CGR_GAIN1_MASK (3 << ADC_CGR_GAIN1_SHIFT) +# define ADC_CGR_GAIN1(v) ((uint32_t)(v) << ADC_CGR_GAIN1_SHIFT) +# define ADC_CGR_GAIN2_SHIFT (4) /* Bits 4-5: Gain for channel 2 */ +# define ADC_CGR_GAIN2_MASK (3 << ADC_CGR_GAIN2_SHIFT) +# define ADC_CGR_GAIN2(v) ((uint32_t)(v) << ADC_CGR_GAIN2_SHIFT) +# define ADC_CGR_GAIN3_SHIFT (6) /* Bits 6-7: Gain for channel 3 */ +# define ADC_CGR_GAIN3_MASK (3 << ADC_CGR_GAIN3_SHIFT) +# define ADC_CGR_GAIN3(v) ((uint32_t)(v) << ADC_CGR_GAIN3_SHIFT) +# define ADC_CGR_GAIN4_SHIFT (8) /* Bits 8-9: Gain for channel 4 */ +# define ADC_CGR_GAIN4_MASK (3 << ADC_CGR_GAIN4_SHIFT) +# define ADC_CGR_GAIN4(v) ((uint32_t)(v) << ADC_CGR_GAIN4_SHIFT) +# define ADC_CGR_GAIN5_SHIFT (10) /* Bits 10-11: Gain for channel 5 */ +# define ADC_CGR_GAIN5_MASK (3 << ADC_CGR_GAIN5_SHIFT) +# define ADC_CGR_GAIN5(v) ((uint32_t)(v) << ADC_CGR_GAIN5_SHIFT) +# define ADC_CGR_GAIN6_SHIFT (12) /* Bits 12-13: Gain for channel 6 */ +# define ADC_CGR_GAIN6_MASK (3 << ADC_CGR_GAIN6_SHIFT) +# define ADC_CGR_GAIN6(v) ((uint32_t)(v) << ADC_CGR_GAIN6_SHIFT) +# define ADC_CGR_GAIN7_SHIFT (14) /* Bits 14-15: Gain for channel 7 */ +# define ADC_CGR_GAIN7_MASK (3 << ADC_CGR_GAIN7_SHIFT) +# define ADC_CGR_GAIN7(v) ((uint32_t)(v) << ADC_CGR_GAIN7_SHIFT) +# define ADC_CGR_GAIN8_SHIFT (16) /* Bits 16-17: Gain for channel 8 */ +# define ADC_CGR_GAIN8_MASK (3 << ADC_CGR_GAIN8_SHIFT) +# define ADC_CGR_GAIN8(v) ((uint32_t)(v) << ADC_CGR_GAIN8_SHIFT) +# define ADC_CGR_GAIN9_SHIFT (18) /* Bits 18-19: Gain for channel 9 */ +# define ADC_CGR_GAIN9_MASK (3 << ADC_CGR_GAIN9_SHIFT) +# define ADC_CGR_GAIN9(v) ((uint32_t)(v) << ADC_CGR_GAIN9_SHIFT) +# define ADC_CGR_GAIN10_SHIFT (20) /* Bits 20-21: Gain for channel 10 */ +# define ADC_CGR_GAIN10_MASK (3 << ADC_CGR_GAIN10_SHIFT) +# define ADC_CGR_GAIN10(v) ((uint32_t)(v) << ADC_CGR_GAIN10_SHIFT) +# define ADC_CGR_GAIN11_SHIFT (22) /* Bits 22-23: Gain for channel 11 */ +# define ADC_CGR_GAIN11_MASK (3 << ADC_CGR_GAIN11_SHIFT) +# define ADC_CGR_GAIN11(v) ((uint32_t)(v) << ADC_CGR_GAIN11_SHIFT) +#endif + +#ifdef ATSAMA5D3 +/* Channel Offset Register */ + +# define ADC_COR_OFF(n) (1 << (n)) +# define ADC_COR_OFF0 (1 << 0) /* Bit 0: Offset for channel 0 */ +# define ADC_COR_OFF1 (1 << 1) /* Bit 1: Offset for channel 1 */ +# define ADC_COR_OFF2 (1 << 2) /* Bit 2: Offset for channel 2 */ +# define ADC_COR_OFF3 (1 << 3) /* Bit 3: Offset for channel 3 */ +# define ADC_COR_OFF4 (1 << 4) /* Bit 4: Offset for channel 4 */ +# define ADC_COR_OFF5 (1 << 5) /* Bit 5: Offset for channel 5 */ +# define ADC_COR_OFF6 (1 << 6) /* Bit 6: Offset for channel 6 */ +# define ADC_COR_OFF7 (1 << 7) /* Bit 7: Offset for channel 7 */ +# define ADC_COR_OFF8 (1 << 8) /* Bit 8: Offset for channel 8 */ +# define ADC_COR_OFF9 (1 << 9) /* Bit 9: Offset for channel 9 */ +# define ADC_COR_OFF10 (1 << 10) /* Bit 10: Offset for channel 10 */ +# define ADC_COR_OFF11 (1 << 11) /* Bit 11: Offset for channel 11 */ + +# define ADC_COR_DIFF(n) (1 << ((n)+16)) +# define ADC_COR_DIFF0 (1 << 16) /* Bit 16: Offset for channel 0 */ +# define ADC_COR_DIFF1 (1 << 17) /* Bit 17: Offset for channel 1 */ +# define ADC_COR_DIFF2 (1 << 18) /* Bit 18: Offset for channel 2 */ +# define ADC_COR_DIFF3 (1 << 19) /* Bit 19: Offset for channel 3 */ +# define ADC_COR_DIFF4 (1 << 20) /* Bit 20: Offset for channel 4 */ +# define ADC_COR_DIFF5 (1 << 21) /* Bit 21: Offset for channel 5 */ +# define ADC_COR_DIFF6 (1 << 22) /* Bit 22: Offset for channel 6 */ +# define ADC_COR_DIFF7 (1 << 23) /* Bit 23: Offset for channel 7 */ +# define ADC_COR_DIFF8 (1 << 24) /* Bit 24: Offset for channel 8 */ +# define ADC_COR_DIFF9 (1 << 25) /* Bit 25: Offset for channel 9 */ +# define ADC_COR_DIFF10 (1 << 26) /* Bit 26: Offset for channel 10 */ +# define ADC_COR_DIFF11 (1 << 27) /* Bit 27: Offset for channel 11 */ +#endif + +/* Channel Data Register */ + +#define ADC_CDR_DATA_SHIFT (0) /* Bits 0-11: Converted Data */ +#define ADC_CDR_DATA_MASK (0xfff << ADC_CDR_DATA_SHIFT) + +/* Compare Window Register */ + +#define ADC_CWR_LOWTHRES_SHIFT (0) /* Bit 0-11: Low Threshold */ +#define ADC_CWR_LOWTHRES_MASK (0xfff << ADC_CWR_LOWTHRES_SHIFT) +# define ADC_CWR_LOWTHRES(n) ((uint32_t)(n) << ADC_CWR_LOWTHRES_SHIFT) +#define ADC_CWR_HIGHTHRES_SHIFT (16) /* Bit 16-27: High Threshold */ +#define ADC_CWR_HIGHTHRES_MASK (0xfff << ADC_CWR_HIGHTHRES_SHIFT) +# define ADC_CWR_HIGHTHRES(n) ((uint32_t)(n) << ADC_CWR_HIGHTHRES_SHIFT) + +/* Analog Control Register */ + +#define ADC_ACR_PENDETSENS_SHIFT (0) /* Bits 0-1: Pen Detection Sensitivity */ +#define ADC_ACR_PENDETSENS_MASK (3 << ADC_ACR_PENDETSENS_SHIFT) +# define ADC_ACR_PENDETSENS(n) ((uint32_t)(n) << ADC_ACR_PENDETSENS_SHIFT) + +/* Touchscreen Mode Register */ + +#define ADC_TSMR_TSMODE_SHIFT (0) /* Bit 0-1: Touchscreen Mode */ +#define ADC_TSMR_TSMODE_MASK (3 << ADC_TSMR_TSMODE_SHIFT) +# define ADC_TSMR_TSMODE_NONE (0 << ADC_TSMR_TSMODE_SHIFT) /* No Touchscreen */ +# define ADC_TSMR_TSMODE_4WIRENPM (1 << ADC_TSMR_TSMODE_SHIFT) /* 4-wire TS w/o pressure measurement */ +# define ADC_TSMR_TSMODE_4WIRE (2 << ADC_TSMR_TSMODE_SHIFT) /* 4-wire TS w/ pressure measurement */ +# define ADC_TSMR_TSMODE_5WIRE (3 << ADC_TSMR_TSMODE_SHIFT) /* 5-wire Touchscreen */ +#define ADC_TSMR_TSAV_SHIFT (4) /* Bit 4-5: Touchscreen Average */ +#define ADC_TSMR_TSAV_MASK (3 << ADC_TSMR_TSAV_SHIFT) +# define ADC_TSMR_TSAV_NOFILTER (0 << ADC_TSMR_TSAV_SHIFT) /* No Filtering */ +# define ADC_TSMR_TSAV_2CONV (1 << ADC_TSMR_TSAV_SHIFT) /* Average 2 ADC conversions */ +# define ADC_TSMR_TSAV_4CONV (2 << ADC_TSMR_TSAV_SHIFT) /* Average 4 ADC conversions */ +# define ADC_TSMR_TSAV_8CONV (3 << ADC_TSMR_TSAV_SHIFT) /* Averages 8 ADC conversions */ +#define ADC_TSMR_TSFREQ_SHIFT (8) /* Bit 8-11: Touchscreen Frequency */ +#define ADC_TSMR_TSFREQ_MASK (15 << ADC_TSMR_TSFREQ_SHIFT) +# define ADC_TSMR_TSFREQ_DIV1 (0 << ADC_TSMR_TSFREQ_SHIFT) /* TS freq = trigger freq */ +# define ADC_TSMR_TSFREQ_DIV2 (1 << ADC_TSMR_TSFREQ_SHIFT) /* TS freq = trigger freq / 2 */ +# define ADC_TSMR_TSFREQ_DIV4 (2 << ADC_TSMR_TSFREQ_SHIFT) /* TS freq = trigger freq / 4 */ +# define ADC_TSMR_TSFREQ_DIV8 (3 << ADC_TSMR_TSFREQ_SHIFT) /* TS freq = trigger freq / 8 */ +# define ADC_TSMR_TSFREQ(n) ((uint32_t)(n) << ADC_TSMR_TSFREQ_SHIFT) +#define ADC_TSMR_TSSCTIM_SHIFT (16) /* Bit 16-19: Touchscreen Switches Closure Time */ +#define ADC_TSMR_TSSCTIM_MASK (15 << ADC_TSMR_TSSCTIM_SHIFT) +# define ADC_TSMR_TSSCTIM(n) ((uint32_t)(n) << ADC_TSMR_TSSCTIM_SHIFT) +#define ADC_TSMR_NOTSDMA (1 << 22) /* Bit 22: No TouchScreen DMA */ +#define ADC_TSMR_PENDET (1 << 24) /* Bit 24: Pen Contact Detection Enable */ +#define ADC_TSMR_PENDBC_SHIFT (28) /* Bit 28-31: Pen Detect Debouncing Period */ +#define ADC_TSMR_PENDBC_MASK (15 << ADC_TSMR_PENDBC_SHIFT) +# define ADC_TSMR_PENDBC(n) ((uint32_t)(n) << ADC_TSMR_PENDBC_SHIFT) + +/* Touchscreen X Position Register */ + +#define ADC_XPOSR_XPOS_SHIFT (0) /* Bit 0-11: X Position */ +#define ADC_XPOSR_XPOS_MASK (0xfff << ADC_XPOSR_XPOS_SHIFT) +#define ADC_XPOSR_XSCALE_SHIFT (16) /* Bit 16-27: Scale of XPOS */ +#define ADC_XPOSR_XSCALE_MASK (0xfff << ADC_XPOSR_XSCALE_SHIFT) + +/* Touchscreen Y Position Register */ + +#define ADC_YPOSR_YPOS_SHIFT (0) /* Bit 0-11: Y Position */ +#define ADC_YPOSR_YPOS_MASK (0xfff << ADC_YPOSR_YPOS_SHIFT) +#define ADC_YPOSR_YSCALE_SHIFT (16) /* Bit 16-27: Scale of YPOS */ +#define ADC_YPOSR_YSCALE_MASK (0xfff << ADC_YPOSR_YSCALE_SHIFT) + +/* Touchscreen Pressure Register */ + +#define ADC_PRESSR_Z1_SHIFT (0) /* Bit 0-11: Data of Z1 Measurement */ +#define ADC_PRESSR_Z1_MASK (0xfff << ADC_PRESSR_Z1_SHIFT) +#define ADC_PRESSR_Z2_SHIFT (16) /* Bit 16-27: Data of Z2 Measuremen */ +#define ADC_PRESSR_Z2_MASK (0xfff << ADC_PRESSR_Z2_SHIFT) + +/* Trigger Register */ + +#define ADC_TRGR_TRGMOD_SHIFT (0) /* Bit 0-2: Trigger Mode */ +#define ADC_TRGR_TRGMOD_MASK (7 << ADC_TRGR_TRGMOD_SHIFT) +# define ADC_TRGR_TRGMOD_NOTRIG (0 << ADC_TRGR_TRGMOD_SHIFT) /* No trigger */ +# define ADC_TRGR_TRGMOD_EXTRISE (1 << ADC_TRGR_TRGMOD_SHIFT) /* External Trigger Rising Edge */ +# define ADC_TRGR_TRGMOD_EXTFALL (2 << ADC_TRGR_TRGMOD_SHIFT) /* External Trigger Falling Edge */ +# define ADC_TRGR_TRGMOD_EXTBOTH (3 << ADC_TRGR_TRGMOD_SHIFT) /* External Trigger Any Edge */ +# define ADC_TRGR_TRGMOD_PEN (4 << ADC_TRGR_TRGMOD_SHIFT) /* Pen Detect Trigger */ +# define ADC_TRGR_TRGMOD_PERIOD (5 << ADC_TRGR_TRGMOD_SHIFT) /* Periodic Trigger */ +# define ADC_TRGR_TRGMOD_CONT (6 << ADC_TRGR_TRGMOD_SHIFT) /* Continuous Mode */ +#define ADC_TRGR_TRGPER_SHIFT (16) /* Bit 16-31: Trigger Period */ +#define ADC_TRGR_TRGPER_MASK (0xffff << ADC_TRGR_TRGPER_SHIFT) +# define ADC_TRGR_TRGPER(n) ((uint32_t)(n) << ADC_TRGR_TRGPER_SHIFT) + +/* Write Protect Mode Register */ + +#define ADC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define ADC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define ADC_WPMR_WPKEY_MASK (0x00ffffff << ADC_WPMR_WPKEY_SHIFT) +# define ADC_WPMR_WPKEY (0x00414443 << ADC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define ADC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define ADC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define ADC_WPSR_WPVSRC_MASK (0xffff << ADC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ADC_H */ diff --git a/arch/arm/src/sama5/chip/sam_aic.h b/arch/arm/src/sama5/chip/sam_aic.h new file mode 100644 index 0000000000000000000000000000000000000000..776b74f6c3a5fa0362e59c8ff2752ac218c74262 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_aic.h @@ -0,0 +1,234 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_aic.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AIC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* AIC Register Offsets *************************************************************/ + +#define SAM_AIC_SSR_OFFSET 0x0000 /* Source Select Register */ +#define SAM_AIC_SMR_OFFSET 0x0004 /* Source Mode Register */ +#define SAM_AIC_SVR_OFFSET 0x0008 /* Source Vector Register */ +#define SAM_AIC_IVR_OFFSET 0x0010 /* Interrupt Vector Register */ +#define SAM_AIC_FVR_OFFSET 0x0014 /* FIQ Interrupt Vector Register */ +#define SAM_AIC_ISR_OFFSET 0x0018 /* Interrupt Status Register */ +#define SAM_AIC_IPR0_OFFSET 0x0020 /* Interrupt Pending Register 0 */ +#define SAM_AIC_IPR1_OFFSET 0x0024 /* Interrupt Pending Register 1 */ +#define SAM_AIC_IPR2_OFFSET 0x0028 /* Interrupt Pending Register 2 */ +#define SAM_AIC_IPR3_OFFSET 0x002c /* Interrupt Pending Register 3 */ +#define SAM_AIC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_AIC_CISR_OFFSET 0x0034 /* Core Interrupt Status Register */ +#define SAM_AIC_EOICR_OFFSET 0x0038 /* End of Interrupt Command Register */ +#define SAM_AIC_SPU_OFFSET 0x003c /* Spurious Interrupt Vector Register */ +#define SAM_AIC_IECR_OFFSET 0x0040 /* Interrupt Enable Command Register */ +#define SAM_AIC_IDCR_OFFSET 0x0044 /* Interrupt Disable Command Register */ +#define SAM_AIC_ICCR_OFFSET 0x0048 /* Interrupt Clear Command Register */ +#define SAM_AIC_ISCR_OFFSET 0x004c /* Interrupt Set Command Register */ + +#ifdef ATSAMA5D3 +# define SAM_AIC_FFER_OFFSET 0x0050 /* Fast Forcing Enable Register */ +# define SAM_AIC_FFDR_OFFSET 0x0054 /* Fast Forcing Disable Register */ +# define SAM_AIC_FFSR_OFFSET 0x0058 /* Fast Forcing Status Register */ +#endif + +#define SAM_AIC_DCR_OFFSET 0x006c /* Debug Control Register */ +#define SAM_AIC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_AIC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + +/* AIC Register Addresses ***********************************************************/ + +#define SAM_AIC_SSR (SAM_AIC_VBASE+SAM_AIC_SSR_OFFSET) +#define SAM_AIC_SMR (SAM_AIC_VBASE+SAM_AIC_SMR_OFFSET) +#define SAM_AIC_SVR (SAM_AIC_VBASE+SAM_AIC_SVR_OFFSET) +#define SAM_AIC_IVR (SAM_AIC_VBASE+SAM_AIC_IVR_OFFSET) +#define SAM_AIC_FVR (SAM_AIC_VBASE+SAM_AIC_FVR_OFFSET) +#define SAM_AIC_ISR (SAM_AIC_VBASE+SAM_AIC_ISR_OFFSET) +#define SAM_AIC_IPR0 (SAM_AIC_VBASE+SAM_AIC_IPR0_OFFSET) +#define SAM_AIC_IPR1 (SAM_AIC_VBASE+SAM_AIC_IPR1_OFFSET) +#define SAM_AIC_IPR2 (SAM_AIC_VBASE+SAM_AIC_IPR2_OFFSET) +#define SAM_AIC_IPR3 (SAM_AIC_VBASE+SAM_AIC_IPR3_OFFSET) +#define SAM_AIC_IMR (SAM_AIC_VBASE+SAM_AIC_IMR_OFFSET) +#define SAM_AIC_CISR (SAM_AIC_VBASE+SAM_AIC_CISR_OFFSET) +#define SAM_AIC_EOICR (SAM_AIC_VBASE+SAM_AIC_EOICR_OFFSET) +#define SAM_AIC_SPU (SAM_AIC_VBASE+SAM_AIC_SPU_OFFSET) +#define SAM_AIC_IECR (SAM_AIC_VBASE+SAM_AIC_IECR_OFFSET) +#define SAM_AIC_IDCR (SAM_AIC_VBASE+SAM_AIC_IDCR_OFFSET) +#define SAM_AIC_ICCR (SAM_AIC_VBASE+SAM_AIC_ICCR_OFFSET) +#define SAM_AIC_ISCR (SAM_AIC_VBASE+SAM_AIC_ISCR_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_AIC_FFER (SAM_AIC_VBASE+SAM_AIC_FFER_OFFSET) +# define SAM_AIC_FFDR (SAM_AIC_VBASE+SAM_AIC_FFDR_OFFSET) +# define SAM_AIC_FFSR (SAM_AIC_VBASE+SAM_AIC_FFSR_OFFSET) +#endif + +#define SAM_AIC_DCR (SAM_AIC_VBASE+SAM_AIC_DCR_OFFSET) +#define SAM_AIC_WPMR (SAM_AIC_VBASE+SAM_AIC_WPMR_OFFSET) +#define SAM_AIC_WPSR (SAM_AIC_VBASE+SAM_AIC_WPSR_OFFSET) + +#ifdef CONFIG_SAMA5_HAVE_SAIC +# define SAM_SAIC_SSR (SAM_SAIC_VBASE+SAM_AIC_SSR_OFFSET) +# define SAM_SAIC_SMR (SAM_SAIC_VBASE+SAM_AIC_SMR_OFFSET) +# define SAM_SAIC_SVR (SAM_SAIC_VBASE+SAM_AIC_SVR_OFFSET) +# define SAM_SAIC_IVR (SAM_SAIC_VBASE+SAM_AIC_IVR_OFFSET) +# define SAM_SAIC_FVR (SAM_SAIC_VBASE+SAM_AIC_FVR_OFFSET) +# define SAM_SAIC_ISR (SAM_SAIC_VBASE+SAM_AIC_ISR_OFFSET) +# define SAM_SAIC_IPR0 (SAM_SAIC_VBASE+SAM_AIC_IPR0_OFFSET) +# define SAM_SAIC_IPR1 (SAM_SAIC_VBASE+SAM_AIC_IPR1_OFFSET) +# define SAM_SAIC_IPR2 (SAM_SAIC_VBASE+SAM_AIC_IPR2_OFFSET) +# define SAM_SAIC_IPR3 (SAM_SAIC_VBASE+SAM_AIC_IPR3_OFFSET) +# define SAM_SAIC_IMR (SAM_SAIC_VBASE+SAM_AIC_IMR_OFFSET) +# define SAM_SAIC_CISR (SAM_SAIC_VBASE+SAM_AIC_CISR_OFFSET) +# define SAM_SAIC_EOICR (SAM_SAIC_VBASE+SAM_AIC_EOICR_OFFSET) +# define SAM_SAIC_SPU (SAM_SAIC_VBASE+SAM_AIC_SPU_OFFSET) +# define SAM_SAIC_IECR (SAM_SAIC_VBASE+SAM_AIC_IECR_OFFSET) +# define SAM_SAIC_IDCR (SAM_SAIC_VBASE+SAM_AIC_IDCR_OFFSET) +# define SAM_SAIC_ICCR (SAM_SAIC_VBASE+SAM_AIC_ICCR_OFFSET) +# define SAM_SAIC_ISCR (SAM_SAIC_VBASE+SAM_AIC_ISCR_OFFSET) +# define SAM_SAIC_DCR (SAM_SAIC_VBASE+SAM_AIC_DCR_OFFSET) +# define SAM_SAIC_WPMR (SAM_SAIC_VBASE+SAM_AIC_WPMR_OFFSET) +# define SAM_SAIC_WPSR (SAM_SAIC_VBASE+SAM_AIC_WPSR_OFFSET) +#endif + +/* AIC Register Bit Definitions *****************************************************/ + +/* Source Select Register */ + +#define AIC_SSR_MASK (0x7f) /* Bits 0-6: Interrupt line Selection */ + +/* Source Mode Register */ + +#define AIC_SMR_PRIOR_SHIFT (0) /* Bits 0-2: Priority level */ +#define AIC_SMR_PRIOR_MASK (7 << AIC_SMR_PRIOR_SHIFT) +# define AIC_SMR_PRIOR_MIN (0) +# define AIC_SMR_PRIOR_MAX (7) +#define AIC_SMR_SRCTYPE_SHIFT (5) /* Bits 5-6: Interrupt source type */ +#define AIC_SMR_SRCTYPE_MASK (3 << AIC_SMR_SRCTYPE_SHIFT) +# define AIC_SMR_SRCTYPE_IHIGH (0 << AIC_SMR_SRCTYPE_SHIFT) /* Internal high level */ +# define AIC_SMR_SRCTYPE_XLOW (0 << AIC_SMR_SRCTYPE_SHIFT) /* External low level */ +# define AIC_SMR_SRCTYPE_IRISING (1 << AIC_SMR_SRCTYPE_SHIFT) /* Internal positive edge */ +# define AIC_SMR_SRCTYPE_XFALLING (1 << AIC_SMR_SRCTYPE_SHIFT) /* External negative edge */ +# define AIC_SMR_SRCTYPE_XHIGH (2 << AIC_SMR_SRCTYPE_SHIFT) /* External high level */ +# define AIC_SMR_SRCTYPE_XRISING (3 << AIC_SMR_SRCTYPE_SHIFT) /* External rising edge */ + +/* Source Vector Register (32-bit address) */ +/* Interrupt Vector Register (32-bit address) */ +/* FIQ Interrupt Vector Register (32-bit address) */ + +/* Interrupt Status Register */ + +#define AIC_ISR_MASK (0x7f) /* Bits 0-6: Current Interrupt Identifier */ + +/* Interrupt Pending Register 0-3 */ + +#define AIC_IPR0(pid) (1 << (pid)) +#define AIC_IPR1(pid) (1 << ((pid) - 32) +#define AIC_IPR2(pid) (1 << ((pid) - 64) +#define AIC_IPR3(pid) (1 << ((pid) - 96) + +/* Interrupt Mask Register */ + +#define AIC_IMR_INTM (1 << 0) /* Bit 0: Interrupt Mask */ + +/* Core Interrupt Status Register */ + +#define AIC_CISR_NFIQ (1 << 0) /* Bit 0: NFIQ Status */ +#define AIC_CISR_NIRQ (1 << 1) /* Bit 1: NIRQ Status */ + +/* End of Interrupt Command Register */ + +#define AIC_EOICR_ENDIT (1 << 0) /* Bit 0: Interrupt Processing Complete Command */ + +/* Spurious Interrupt Vector Register (32-bit address) */ + +/* Interrupt Enable Command Register */ + +#define AIC_IECR_INTEN (1 << 0) /* Bit 0: Interrupt Enable */ + +/* Interrupt Disable Command Register */ + +#define AIC_IDCR_INTD (1 << 0) /* Bit 0: Interrupt Disable */ + +/* Interrupt Clear Command Register */ + +#define AIC_ICCR_INTCLR (1 << 0) /* Bit 0: Interrupt Clear */ + +/* Interrupt Set Command Register */ + +#define AIC_ISCR_INTSET (1 << 0) /* Bit 0: Interrupt Set */ + +#ifdef ATSAMA5D3 +/* Fast Forcing Enable Register */ + +# define AIC_FFER_FFEN (1 << 0) /* Bit 0: Fast Forcing Enable */ + +/* Fast Forcing Disable Register */ + +# define AIC_FFDR_FFDIS (1 << 0) /* Bit 0: Fast Forcing Disable */ + +/* Fast Forcing Status Register */ + +# define AIC_FFSR_FFS (1 << 0) /* Bit 0: Fast Forcing Status */ +#endif + +/* Debug Control Register */ + +#define AIC_DCR_PROT (1 << 0) /* Bit 0: Protection Mode */ +#define AIC_DCR_GMSK (1 << 1) /* Bit 1: General Mask */ + +/* Write Protect Mode Register */ + +#define AIC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define AIC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define AIC_WPMR_WPKEY_MASK (0x00ffffff << AIC_WPMR_WPKEY_SHIFT) +# define AIC_WPMR_WPKEY (0x00414943 << AIC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define AIC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define AIC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define AIC_WPSR_WPVSRC_MASK (0x0000ffff << AIC_WPSR_WPVSRC_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AIC_H */ diff --git a/arch/arm/src/sama5/chip/sam_aximx.h b/arch/arm/src/sama5/chip/sam_aximx.h new file mode 100644 index 0000000000000000000000000000000000000000..7f86cc15e907e15ee0377fcf062c296490b00ae9 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_aximx.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_aximx.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AXIMX_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AXIMX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* AXIMX Register Offsets ***********************************************************/ + +#define SAM_AXIMX_REMAP_OFFSET 0x0000 /* Remap Register */ + +/* AXIMX Register Addresses *********************************************************/ + +#define SAM_AXIMX_REMAP (SAM_AXIMX_VSECTION+SAM_AXIMX_REMAP_OFFSET) + +/* AXIMX Register Bit Definitions ***************************************************/ + +/* Remap Register + * + * Boot state: ROM is seen at address 0x00000000 + * Remap State 0: SRAM is seen at address 0x00000000 (through AHB slave interface) + * instead of ROM. + * Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave interface) + * instead of ROM for external boot. + */ + +#define AXIMX_REMAP_REMAP0 (1 << 0) /* Remap State 0 */ + +#ifdef ATSAMA5D3 +# define AXIMX_REMAP_REMAP1 (1 << 1) /* Remap State 1 */ +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_AXIMX_H */ diff --git a/arch/arm/src/sama5/chip/sam_bsc.h b/arch/arm/src/sama5/chip/sam_bsc.h new file mode 100644 index 0000000000000000000000000000000000000000..c51710feda9d98552a3cb988b4e16b861b8882d1 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_bsc.h @@ -0,0 +1,67 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_bsc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_BSC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_BSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* BSC Register Offsets *************************************************************/ + +#define SAM_BSC_CR_OFFSET 0x0000 /* Boot Sequence Configuration Register */ + +/* BSC Register Addresses ***********************************************************/ + +#define SAM_BSC_CR (SAM_BSC_VBASE+SAM_BSC_CR_OFFSET) + +/* BSC Register Bit Definitions *****************************************************/ + +/* Boot Sequence Configuration Register */ + +#define BSC_CR_BOOT_SHIFT (0) /* Bits 0-7: Boot Media Sequence */ +#define BSC_CR_BOOT_MASK (0xff << BSC_CR_BOOT_SHIFT) +#define BSC_CR_BOOTKEY_SHIFT (16) /* Bits 16-31: Book key */ +#define BSC_CR_BOOTKEY_MASK (0xffff << BSC_CR_BOOTKEY_SHIFT) +# define BSC_CR_BOOTKEY (0x6683 << BSC_CR_BOOTKEY_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_BSC_H */ diff --git a/arch/arm/src/sama5/chip/sam_can.h b/arch/arm/src/sama5/chip/sam_can.h new file mode 100644 index 0000000000000000000000000000000000000000..8efbbd51c63713b52f399528d9e5bf3a1d9f8eab --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_can.h @@ -0,0 +1,377 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_can.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_CAN_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_CAN_NMAILBOXES 8 +#define SAM_CAN_MAXPERCLK 66000000 + +/* CAN Register Offsets *************************************************************/ + +#define SAM_CAN_MR_OFFSET 0x0000 /* Mode Register */ +#define SAM_CAN_IER_OFFSET 0x0004 /* Interrupt Enable Register */ +#define SAM_CAN_IDR_OFFSET 0x0008 /* Interrupt Disable Register */ +#define SAM_CAN_IMR_OFFSET 0x000c /* Interrupt Mask Register */ +#define SAM_CAN_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_CAN_BR_OFFSET 0x0014 /* Baudrate Register */ +#define SAM_CAN_TIM_OFFSET 0x0018 /* Timer Register */ +#define SAM_CAN_TIMESTP_OFFSET 0x001c /* Timestamp Register */ +#define SAM_CAN_ECR_OFFSET 0x0020 /* Error Counter Register */ +#define SAM_CAN_TCR_OFFSET 0x0024 /* Transfer Command Register */ +#define SAM_CAN_ACR_OFFSET 0x0028 /* Abort Command Register */ + +#define SAM_CAN_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_CAN_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + +#define SAM_CAN_MBn_OFFSET(n) (0x0200 + ((n) << 5)) +#define SAM_CAN_MMR_OFFSET 0x0000 /* Mailbox Mode Register */ +#define SAM_CAN_MAM_OFFSET 0x0004 /* Mailbox Acceptance Mask Register */ +#define SAM_CAN_MID_OFFSET 0x0008 /* Mailbox ID Register */ +#define SAM_CAN_MFID_OFFSET 0x000c /* Mailbox Family ID Register */ +#define SAM_CAN_MSR_OFFSET 0x0010 /* Mailbox Status Register */ +#define SAM_CAN_MDL_OFFSET 0x0014 /* Mailbox Data Low Register */ +#define SAM_CAN_MDH_OFFSET 0x0018 /* Mailbox Data High Register */ +#define SAM_CAN_MCR_OFFSET 0x001c /* Mailbox Control Register */ + +#define SAM_CAN_MnMR_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MMR_OFFSET) +#define SAM_CAN_MnAM_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MAM_OFFSET) +#define SAM_CAN_MnID_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MID_OFFSET) +#define SAM_CAN_MnFID_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MFID_OFFSET) +#define SAM_CAN_MnSR_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MSR_OFFSET) +#define SAM_CAN_MnDL_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MDL_OFFSET) +#define SAM_CAN_MnDH_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MDH_OFFSET) +#define SAM_CAN_MnCR_OFFSET(n) (SAM_CAN_MBn_OFFSET(n)+SAM_CAN_MCR_OFFSET) + +/* CAN Register Addresses ***********************************************************/ + +#define SAM_CAN0_MR (SAM_CAN0_VBASE+SAM_CAN_MR_OFFSET) +#define SAM_CAN0_IER (SAM_CAN0_VBASE+SAM_CAN_IER_OFFSET) +#define SAM_CAN0_IDR (SAM_CAN0_VBASE+SAM_CAN_IDR_OFFSET) +#define SAM_CAN0_IMR (SAM_CAN0_VBASE+SAM_CAN_IMR_OFFSET) +#define SAM_CAN0_SR (SAM_CAN0_VBASE+SAM_CAN_SR_OFFSET) +#define SAM_CAN0_BR (SAM_CAN0_VBASE+SAM_CAN_BR_OFFSET) +#define SAM_CAN0_TIM (SAM_CAN0_VBASE+SAM_CAN_TIM_OFFSET) +#define SAM_CAN0_TIMESTP (SAM_CAN0_VBASE+SAM_CAN_TIMESTP_OFFSET) +#define SAM_CAN0_ECR (SAM_CAN0_VBASE+SAM_CAN_ECR_OFFSET) +#define SAM_CAN0_TCR (SAM_CAN0_VBASE+SAM_CAN_TCR_OFFSET) +#define SAM_CAN0_ACR (SAM_CAN0_VBASE+SAM_CAN_ACR_OFFSET) + +#define SAM_CAN0_WPMR (SAM_CAN0_VBASE+SAM_CAN_WPMR_OFFSET) +#define SAM_CAN0_WPSR (SAM_CAN0_VBASE+SAM_CAN_WPSR_OFFSET) + +#define SAM_CAN0_MB_BASE(n) (SAM_CAN0_VBASE+SAM_CAN_MBn_OFFSET(n)) +#define SAM_CAN0_MMR(n) (SAM_CAN0_VBASE+SAM_CAN_MnMR_OFFSET(n)) +#define SAM_CAN0_MAM(n) (SAM_CAN0_VBASE+SAM_CAN_MnAM_OFFSET(n)) +#define SAM_CAN0_MID(n) (SAM_CAN0_VBASE+SAM_CAN_MnID_OFFSET(n)) +#define SAM_CAN0_MFID(n) (SAM_CAN0_VBASE+SAM_CAN_MnFID_OFFSET(n)) +#define SAM_CAN0_MSR(n) (SAM_CAN0_VBASE+SAM_CAN_MnSR_OFFSET(n)) +#define SAM_CAN0_MDL(n) (SAM_CAN0_VBASE+SAM_CAN_MnDL_OFFSET(n)) +#define SAM_CAN0_MDH(n) (SAM_CAN0_VBASE+SAM_CAN_MnDH_OFFSET(n)) +#define SAM_CAN0_MCR(n) (SAM_CAN0_VBASE+SAM_CAN_MnCR_OFFSET(n)) + +#define SAM_CAN1_MR (SAM_CAN1_VBASE+SAM_CAN_MR_OFFSET) +#define SAM_CAN1_IER (SAM_CAN1_VBASE+SAM_CAN_IER_OFFSET) +#define SAM_CAN1_IDR (SAM_CAN1_VBASE+SAM_CAN_IDR_OFFSET) +#define SAM_CAN1_IMR (SAM_CAN1_VBASE+SAM_CAN_IMR_OFFSET) +#define SAM_CAN1_SR (SAM_CAN1_VBASE+SAM_CAN_SR_OFFSET) +#define SAM_CAN1_BR (SAM_CAN1_VBASE+SAM_CAN_BR_OFFSET) +#define SAM_CAN1_TIM (SAM_CAN1_VBASE+SAM_CAN_TIM_OFFSET) +#define SAM_CAN1_TIMESTP (SAM_CAN1_VBASE+SAM_CAN_TIMESTP_OFFSET) +#define SAM_CAN1_ECR (SAM_CAN1_VBASE+SAM_CAN_ECR_OFFSET) +#define SAM_CAN1_TCR (SAM_CAN1_VBASE+SAM_CAN_TCR_OFFSET) +#define SAM_CAN1_ACR (SAM_CAN1_VBASE+SAM_CAN_ACR_OFFSET) + +#define SAM_CAN1_WPMR (SAM_CAN1_VBASE+SAM_CAN_WPMR_OFFSET) +#define SAM_CAN1_WPSR (SAM_CAN1_VBASE+SAM_CAN_WPSR_OFFSET) + +#define SAM_CAN1_MB_BASE(n) (SAM_CAN1_VBASE+SAM_CAN_MBn_OFFSET(n)) +#define SAM_CAN1_MMR(n) (SAM_CAN1_VBASE+SAM_CAN_MnMR_OFFSET(n)) +#define SAM_CAN1_MAM(n) (SAM_CAN1_VBASE+SAM_CAN_MnAM_OFFSET(n)) +#define SAM_CAN1_MID(n) (SAM_CAN1_VBASE+SAM_CAN_MnID_OFFSET(n)) +#define SAM_CAN1_MFID(n) (SAM_CAN1_VBASE+SAM_CAN_MnFID_OFFSET(n)) +#define SAM_CAN1_MSR(n) (SAM_CAN1_VBASE+SAM_CAN_MnSR_OFFSET(n)) +#define SAM_CAN1_MDL(n) (SAM_CAN1_VBASE+SAM_CAN_MnDL_OFFSET(n)) +#define SAM_CAN1_MDH(n) (SAM_CAN1_VBASE+SAM_CAN_MnDH_OFFSET(n)) +#define SAM_CAN1_MCR(n) (SAM_CAN1_VBASE+SAM_CAN_MnCR_OFFSET(n)) + +/* CAN Register Bit Definitions *****************************************************/ + +/* Mode Register */ + +#define CAN_MR_CANEN (1 << 0) /* Bit 0: CAN Controller Enable */ +#define CAN_MR_LPM (1 << 1) /* Bit 1: Disable/Enable Low-power Mode */ +#define CAN_MR_ABM (1 << 2) /* Bit 2: Disable/Enable Autobaud/Listen mode */ +#define CAN_MR_OVL (1 << 3) /* Bit 3: Disable/Enable Overload Frame */ +#define CAN_MR_TEOF (1 << 4) /* Bit 4: Timestamp Messages at each End of Frame */ +#define CAN_MR_TTM (1 << 5) /* Bit 5: Disable/Enable Time Triggered Mode */ +#define CAN_MR_TIMFRZ (1 << 6) /* Bit 6: Enable Timer Freeze */ +#define CAN_MR_DRPT (1 << 7) /* Bit 7: Disable Repeat */ + +/* Interrupt Enable Register, Interrupt Disable Register, Interrupt Mask Register, + * and Status Register + */ + +#define CAN_INT_MB(n) (1 << (n)) /* Bit n: Mailbox n Event */ +#define CAN_INT_MB0 (1 << 0) /* Bit 0: Mailbox 0 Event */ +#define CAN_INT_MB1 (1 << 1) /* Bit 1: Mailbox 1 Event */ +#define CAN_INT_MB2 (1 << 2) /* Bit 2: Mailbox 2 Event */ +#define CAN_INT_MB3 (1 << 3) /* Bit 3: Mailbox 3 Event */ +#define CAN_INT_MB4 (1 << 4) /* Bit 4: Mailbox 4 Event */ +#define CAN_INT_MB5 (1 << 5) /* Bit 5: Mailbox 5 Event */ +#define CAN_INT_MB6 (1 << 6) /* Bit 6: Mailbox 6 Event */ +#define CAN_INT_MB7 (1 << 7) /* Bit 7: Mailbox 7 Event */ +#define CAN_INT_MBALL (0x000000ff) + +#define CAN_INT_ERRA (1 << 16) /* Bit 16: Error Active Mode */ +#define CAN_INT_WARN (1 << 17) /* Bit 17: Warning Limit */ +#define CAN_INT_ERRP (1 << 18) /* Bit 18: Error Passive Mode */ +#define CAN_INT_BOFF (1 << 19) /* Bit 19: Bus Off Mode */ +#define CAN_INT_SLEEP (1 << 20) /* Bit 20: CAN Controller in Low-power Mode */ +#define CAN_INT_WAKEUP (1 << 21) /* Bit 21: Wake-up Interrupt */ +#define CAN_INT_TOVF (1 << 22) /* Bit 22: Timer Overflow */ +#define CAN_INT_TSTP (1 << 23) /* Bit 23: Timestamp */ +#define CAN_INT_CERR (1 << 24) /* Bit 24: Mailbox CRC Error */ +#define CAN_INT_SERR (1 << 25) /* Bit 25: Mailbox Stuffing Error */ +#define CAN_INT_AERR (1 << 26) /* Bit 26: Acknowledgment Error */ +#define CAN_INT_FERR (1 << 27) /* Bit 27: Form Error */ +#define CAN_INT_BERR (1 << 28) /* Bit 28: Bit Error */ +#define CAN_INT_ALLERRORS (0x1f000000) +#define CAN_INT_ALL (0x1fff00ff) + +#define CAN_SR_RBSY (1 << 29) /* Bit 29: Receiver busy */ +#define CAN_SR_TBSY (1 << 30) /* Bit 30: Transmitter busy */ +#define CAN_SR_OVLSY (1 << 31) /* Bit 31: Overload busy */ + +/* Baudrate Register */ + +#define CAN_BR_PHASE2_SHIFT (0) /* Bits 0-2: Phase 2 segment */ +#define CAN_BR_PHASE2_MASK (7 << CAN_BR_PHASE2_SHIFT) +# define CAN_BR_PHASE2(n) ((uint32_t)(n) << CAN_BR_PHASE2_SHIFT) +#define CAN_BR_PHASE1_SHIFT (4) /* Bits 4-6: Phase 1 segment */ +#define CAN_BR_PHASE1_MASK (7 << CAN_BR_PHASE1_SHIFT) +# define CAN_BR_PHASE1(n) ((uint32_t)(n) << CAN_BR_PHASE1_SHIFT) +#define CAN_BR_PROPAG_SHIFT (8) /* Bits 8-10: Programming time segment */ +#define CAN_BR_PROPAG_MASK (7 << CAN_BR_PROPAG_SHIFT) +# define CAN_BR_PROPAG(n) ((uint32_t)(n) << CAN_BR_PROPAG_SHIFT) +#define CAN_BR_SJW_SHIFT (12) /* Bits 12-13: Re-synchronization jump width */ +#define CAN_BR_SJW_MASK (3 << CAN_BR_SJW_SHIFT) +# define CAN_BR_SJW(n) ((uint32_t)(n) << CAN_BR_SJW_SHIFT) +#define CAN_BR_BRP_SHIFT (16) /* Bits 16-22: Baudrate Prescaler */ +#define CAN_BR_BRP_MASK (0x7f << CAN_BR_BRP_SHIFT) +# define CAN_BR_BRP(n) ((uint32_t)(n) << CAN_BR_BRP_SHIFT) +#define CAN_BR_SMP (1 << 24) /* Bit 24: Sampling Mode */ +# define CAN_BR_ONCE (0) /* Bit 24: 0:Bit stream sampled once at sample point */ +# define CAN_BR_THREE CAN_BR_SMP /* Bit 24: 1:Sampling three times */ + +/* Timer Register */ + +#define CAN_TIM_MASK (0xffff) /* Bit 0-15: Timer */ + +/* Timestamp Register */ + +#define CAN_TIMESTP_MASK (0xffff) /* Bit 0-15: Timestamp */ + +/* Error Counter Register */ + +#define CAN_ECR_REC_SHIFT (0) /* Bits 0-7: Receive Error Counter */ +#define CAN_ECR_REC_MASK (0xff << CAN_ECR_REC_SHIFT) +#define CAN_ECR_TEC_SHIFT (16) /* Bits 16-24: Transmit Error Counter */ +#define CAN_ECR_TEC_MASK (0x1ff << CAN_ECR_TEC_SHIFT) + +/* Transfer Command Register */ + +#define CAN_TCR_MB(n) (1 << (n)) /* Bit n: Transfer Request for Mailbox n */ +#define CAN_TCR_MB0 (1 << 0) /* Bit 0: Transfer Request for Mailbox 0 */ +#define CAN_TCR_MB1 (1 << 1) /* Bit 1: Transfer Request for Mailbox 1 */ +#define CAN_TCR_MB2 (1 << 2) /* Bit 2: Transfer Request for Mailbox 2 */ +#define CAN_TCR_MB3 (1 << 3) /* Bit 3: Transfer Request for Mailbox 3 */ +#define CAN_TCR_MB4 (1 << 4) /* Bit 4: Transfer Request for Mailbox 4 */ +#define CAN_TCR_MB5 (1 << 5) /* Bit 5: Transfer Request for Mailbox 5 */ +#define CAN_TCR_MB6 (1 << 6) /* Bit 6: Transfer Request for Mailbox 6 */ +#define CAN_TCR_MB7 (1 << 7) /* Bit 7: Transfer Request for Mailbox 7 */ +#define CAN_TCR_TIMRST (1 << 31) /* Bit 31: Timer Reset */ + +/* Abort Command Register */ + +#define CAN_ACR_MB(n) (1 << (n)) /* Bit n: Abort Request for Mailbox n */ +#define CAN_ACR_MB0 (1 << 0) /* Bit 0: Abort Request for Mailbox 0 */ +#define CAN_ACR_MB1 (1 << 1) /* Bit 1: Abort Request for Mailbox 1 */ +#define CAN_ACR_MB2 (1 << 2) /* Bit 2: Abort Request for Mailbox 2 */ +#define CAN_ACR_MB3 (1 << 3) /* Bit 3: Abort Request for Mailbox 3 */ +#define CAN_ACR_MB4 (1 << 4) /* Bit 4: Abort Request for Mailbox 4 */ +#define CAN_ACR_MB5 (1 << 5) /* Bit 5: Abort Request for Mailbox 5 */ +#define CAN_ACR_MB6 (1 << 6) /* Bit 6: Abort Request for Mailbox 6 */ +#define CAN_ACR_MB7 (1 << 7) /* Bit 6: Abort Request for Mailbox 7 */ + +/* Write Protect Mode Register */ + +#define CAN_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define CAN_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: CAN Write Protection Key Password */ +#define CAN_WPMR_WPKEY_MASK (0xffffff << CAN_WPMR_WPKEY_SHIFT) +# define CAN_WPMR_WPKEY (0x43414e << CAN_WPMR_WPKEY_SHIFT) /* "CAN" in ASCII */ + +/* Write Protect Status Register */ + +#define CAN_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define CAN_WPSR_WPVSRC_SHIFT (8) /* Bits 8-15: Write Protection Violation Source */ +#define CAN_WPSR_WPVSRC_MASK (0xff << CAN_WPSR_WPVSRC_SHIFT) + +/* Mailbox Mode Register */ + +#define CAN_MMR_MTIMEMARK_SHIFT (0) /* Bits 0-15: Mailbox Timemark */ +#define CAN_MMR_MTIMEMARK_MASK (0xffff << CAN_MMR_MTIMEMARK_SHIFT) +# define CAN_MMR_MTIMEMARK(n) ((uint32_t)(n) << 19) +#define CAN_MMR_PRIOR_SHIFT (16) /* Bits 16-19: Mailbox Priority */ +#define CAN_MMR_PRIOR_MASK (15 << CAN_MMR_PRIOR_SHIFT) +# define CAN_MMR_PRIOR(n) ((uint32_t)(n) << CAN_MMR_PRIOR_SHIFT) +#define CAN_MMR_MOT_SHIFT (24) /* Bits 24-26: Mailbox Object Type */ +#define CAN_MMR_MOT_MASK (7 << CAN_MMR_MOT_SHIFT) +# define CAN_MMR_MOT_DISABLED (0 << CAN_MMR_MOT_SHIFT) /* Mailbox is disabled */ +# define CAN_MMR_MOT_RX (1 << CAN_MMR_MOT_SHIFT) /* Reception Mailbox */ +# define CAN_MMR_MOT_RXOVRWR (2 << CAN_MMR_MOT_SHIFT) /* Reception mailbox with overwrite */ +# define CAN_MMR_MOT_TX (3 << CAN_MMR_MOT_SHIFT) /* Transmit mailbox */ +# define CAN_MMR_MOT_CONSUMER (4 << CAN_MMR_MOT_SHIFT) /* Consumer Mailbox */ +# define CAN_MMR_MOT_PRODUCER (5 << CAN_MMR_MOT_SHIFT) /* Producer Mailbox */ + +/* Mailbox Acceptance Mask Register */ + +#define CAN_MAM_MIDvB_SHIFT (0) /* Bits 0-17: Complementary bits for identifier */ +#define CAN_MAM_MIDvB_MASK (0x3ffff << CAN_MAM_MIDvB_SHIFT) +# define CAN_MAM_MIDvB(n) ((uint32_t)(n) << CAN_MAM_MIDvB_SHIFT) +#define CAN_MAM_MIDvA_SHIFT (18) /* Bits 18-28: Identifier for standard frame mode */ +#define CAN_MAM_MIDvA_MASK (0x7ff << CAN_MAM_MIDvA_SHIFT) +# define CAN_MAM_MIDvA(n) ((uint32_t)(n) << CAN_MAM_MIDvA_SHIFT) +#define CAN_MAM_MIDE (1 << 29) /* Bit 29: Identifier Version */ + +#define CAN_MAM_EXTID_SHIFT (0) /* Bits 0-28: 29-bit extended address */ +#define CAN_MAM_EXTID_MASK (0x1fffffff << CAN_MAM_EXTID_SHIFT) +# define CAN_MAM_EXTID(n) (((uint32_t)(n) << CAN_MAM_EXTID_SHIFT) | CAN_MAM_MIDE) +#define CAN_MAM_STDID_SHIFT (18) /* Bits 18-28: 11-bit standard address */ +#define CAN_MAM_STDID_MASK (0x7ff << CAN_MAM_STDID_SHIFT) +# define CAN_MAM_STDID(n) ((uint32_t)(n) << CAN_MAM_STDID_SHIFT) + +/* Mailbox ID Register */ + +#define CAN_MID_MIDvB_SHIFT (0) /* Bits 0-17: Complementary bits for identifier */ +#define CAN_MID_MIDvB_MASK (0x3ffff << CAN_MID_MIDvB_SHIFT) +# define CAN_MID_MIDvB(n) ((uint32_t)(n) << CAN_MID_MIDvB_SHIFT) +#define CAN_MID_MIDvA_SHIFT (18) /* Bits 18-28: Identifier for standard frame mode */ +#define CAN_MID_MIDvA_MASK (0x7ff << CAN_MID_MIDvA_SHIFT) +# define CAN_MID_MIDvA(n) ((uint32_t)(n) << CAN_MID_MIDvA_SHIFT) +#define CAN_MID_MIDE (1 << 29) /* Bit 19: Identifier Version */ + +#define CAN_MID_EXTID_SHIFT (0) /* Bits 0-28: 29-bit extended address */ +#define CAN_MID_EXTID_MASK (0x1fffffff << CAN_MID_EXTID_SHIFT) +# define CAN_MID_EXTID(n) (((uint32_t)(n) << CAN_MID_EXTID_SHIFT) | CAN_MID_MIDE) +#define CAN_MID_STDID_SHIFT (18) /* Bits 18-28: 11-bit standard address */ +#define CAN_MID_STDID_MASK (0x7ff << CAN_MID_STDID_SHIFT) +# define CAN_MID_STDID(n) ((uint32_t)(n) << CAN_MID_STDID_SHIFT) + +/* Mailbox Family ID Register */ + +#define CAN_MFID_MASK (0x1fffffff) + +/* Mailbox Status Register */ + +#define CAN_MSR_MTIMESTAMP_SHIFT (0) /* Bits 0-15: Timer value */ +#define CAN_MSR_MTIMESTAMP_MASK (0xffff << CAN_MSR_MTIMESTAMP_SHIFT) +#define CAN_MSR_MDLC_SHIFT (16) /* Bits 16-19: Mailbox Data Length Code */ +#define CAN_MSR_MDLC_MASK (15 << CAN_MSR_MDLC_SHIFT) +#define CAN_MSR_MRTR (1 << 20) /* Bit 20: Mailbox Remote Transmission Request */ +#define CAN_MSR_MABT (1 << 22) /* Bit 22: Mailbox Message Abort */ +#define CAN_MSR_MRDY (1 << 23) /* Bit 23: Mailbox Ready */ +#define CAN_MSR_MMI (1 << 24) /* Bit 24: Mailbox Message Ignored */ + +/* Mailbox Data Low Register and Mailbox Data High Register. + * Bytes are received/sent on the bus in the following order: + * + * 1. CAN_MDL[7:0] + * 2. CAN_MDL[15:8] + * 3. CAN_MDL[23:16] + * 4. CAN_MDL[31:24] + * 5. CAN_MDH[7:0] + * 6. CAN_MDH[15:8] + * 7. CAN_MDH[23:16] + * 8. CAN_MDH[31:24] + */ + +#define CAN_MDL0_SHIFT (0) /* Bits 0-7: Byte 0 */ +#define CAN_MDL0_MASK (0xff << CAN_MDL0_SHIFT) +# define CAN_MDL0(n) ((uint32_t)(n) << CAN_MDL0_SHIFT) +#define CAN_MDL1_SHIFT (8) /* Bits 8-15: Byte 1 */ +#define CAN_MDL1_MASK (0xff << CAN_MDL1_SHIFT) +# define CAN_MDL1(n) ((uint32_t)(n) << CAN_MDL1_SHIFT) +#define CAN_MDL2_SHIFT (16) /* Bits 16-23: Byte 2 */ +#define CAN_MDL2_MASK (0xff << CAN_MDL2_SHIFT) +# define CAN_MDL2(n) ((uint32_t)(n) << CAN_MDL2_SHIFT) +#define CAN_MDL3_SHIFT (24) /* Bits 24-31: Byte 3 */ +#define CAN_MDL3_MASK (0xff << CAN_MDL3_SHIFT) +# define CAN_MDL3(n) ((uint32_t)(n) << CAN_MDL3_SHIFT) + +#define CAN_MDH4_SHIFT (0) /* Bits 0-7: Byte 4 */ +#define CAN_MDH4_MASK (0xff << CAN_MDH4_SHIFT) +# define CAN_MDH4(n) ((uint32_t)(n) << CAN_MDH4_SHIFT) +#define CAN_MDH5_SHIFT (8) /* Bits 8-15: Byte 5 */ +#define CAN_MDH5_MASK (0xff << CAN_MDH5_SHIFT) +# define CAN_MDH5(n) ((uint32_t)(n) << CAN_MDH5_SHIFT) +#define CAN_MDH6_SHIFT (16) /* Bits 16-23: Byte 6 */ +#define CAN_MDH6_MASK (0xff << CAN_MDH6_SHIFT) +# define CAN_MDH6(n) ((uint32_t)(n) << CAN_MDH6_SHIFT) +#define CAN_MDH7_SHIFT (24) /* Bits 24-31: Byte 7 */ +#define CAN_MDH7_MASK (0xff << CAN_MDH7_SHIFT) +# define CAN_MDH7(n) ((uint32_t)(n) << CAN_MDH7_SHIFT) + +/* Mailbox Control Register */ + +#define CAN_MCR_MDLC_SHIFT (16) /* Bits 16-19: Mailbox Data Length Code */ +#define CAN_MCR_MDLC_MASK (15 << CAN_MCR_MDLC_SHIFT) +# define CAN_MCR_MDLC(n) ((uint32_t)(n) << CAN_MCR_MDLC_SHIFT) +#define CAN_MCR_MRTR (1 << 20) /* Bit 20: Mailbox Remote Transmission Request */ +#define CAN_MCR_MACR (1 << 22) /* Bit 22: Abort Request for Mailbox n */ +#define CAN_MCR_MTCR (1 << 23) /* Bit 23: Mailbox Transfer Command */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_CAN_H */ diff --git a/arch/arm/src/sama5/chip/sam_dbgu.h b/arch/arm/src/sama5/chip/sam_dbgu.h new file mode 100644 index 0000000000000000000000000000000000000000..a2a11d18c411533e98f6b2ed937950900d4b36d8 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_dbgu.h @@ -0,0 +1,267 @@ +/************************************************************************************************ + * arch/arm/src/sama5/chip/sam3u_uart.h + * Debug Unit (DBGU) definitions for the SAMA5D3 + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DBGU_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DBGU_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* DBGU register offsets ************************************************************************/ + +#define SAM_DBGU_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_DBGU_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_DBGU_IER_OFFSET 0x0008 /* Interrupt Enable Register */ +#define SAM_DBGU_IDR_OFFSET 0x000c /* Interrupt Disable Register */ +#define SAM_DBGU_IMR_OFFSET 0x0010 /* Interrupt Mask Register */ +#define SAM_DBGU_SR_OFFSET 0x0014 /* [Channel] Status Register */ +#define SAM_DBGU_RHR_OFFSET 0x0018 /* Receive Holding Register */ +#define SAM_DBGU_THR_OFFSET 0x001c /* Transmit Holding Register */ +#define SAM_DBGU_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register */ + /* 0x0024-0x003c: Reserved */ +#define SAM_DBGU_CIDR_OFFSET 0x0040 /* Chip ID Register */ +#define SAM_DBGU_EXID_OFFSET 0x0044 /* Chip ID Extension Register */ +#define SAM_DBGU_FNR_OFFSET 0x0048 /* Force NTRST Register */ + /* 0x004c-0x00fc: Reserved */ + +/* DBGU register addresses **********************************************************************/ + +#define SAM_DBGU_CR (SAM_DBGU_VBASE+SAM_DBGU_CR_OFFSET) +#define SAM_DBGU_MR (SAM_DBGU_VBASE+SAM_DBGU_MR_OFFSET) +#define SAM_DBGU_IER (SAM_DBGU_VBASE+SAM_DBGU_IER_OFFSET) +#define SAM_DBGU_IDR (SAM_DBGU_VBASE+SAM_DBGU_IDR_OFFSET) +#define SAM_DBGU_IMR (SAM_DBGU_VBASE+SAM_DBGU_IMR_OFFSET) +#define SAM_DBGU_SR (SAM_DBGU_VBASE+SAM_DBGU_SR_OFFSET) +#define SAM_DBGU_RHR (SAM_DBGU_VBASE+SAM_DBGU_RHR_OFFSET) +#define SAM_DBGU_THR (SAM_DBGU_VBASE+SAM_DBGU_THR_OFFSET) +#define SAM_DBGU_BRGR (SAM_DBGU_VBASE+SAM_DBGU_BRGR_OFFSET) +#define SAM_DBGU_CIDR (SAM_DBGU_VBASE+SAM_DBGU_CIDR_OFFSET) +#define SAM_DBGU_EXID (SAM_DBGU_VBASE+SAM_DBGU_EXID_OFFSET) +#define SAM_DBGU_FNR (SAM_DBGU_VBASE+SAM_DBGU_FNR_OFFSET) + +/* DBGU register bit definitions ****************************************************************/ + +/* DBGU Control Register */ + +#define DBGU_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver */ +#define DBGU_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter */ +#define DBGU_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable */ +#define DBGU_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable */ +#define DBGU_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable */ +#define DBGU_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable */ +#define DBGU_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits */ + +/* DBGU Mode Register */ + +#ifdef ATSAMA5D4 +# define DBGU_MR_FILTER_SHIFT (1 << 4) /* Bit 4: FILTER: Receiver Digital Filter */ +#endif + +#define DBGU_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type */ +#define DBGU_MR_PAR_MASK (7 << DBGU_MR_PAR_SHIFT) +# define DBGU_MR_PAR_EVEN (0 << DBGU_MR_PAR_SHIFT) /* Even parity */ +# define DBGU_MR_PAR_ODD (1 << DBGU_MR_PAR_SHIFT) /* Odd parity */ +# define DBGU_MR_PAR_SPACE (2 << DBGU_MR_PAR_SHIFT) /* Space: parity forced to 0 */ +# define DBGU_MR_PAR_MARK (3 << DBGU_MR_PAR_SHIFT) /* Mark: parity forced to 1 */ +# define DBGU_MR_PAR_NONE (4 << DBGU_MR_PAR_SHIFT) /* No parity */ +#define DBGU_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode */ +#define DBGU_MR_CHMODE_MASK (3 << DBGU_MR_CHMODE_SHIFT) +# define DBGU_MR_CHMODE_NORMAL (0 << DBGU_MR_CHMODE_SHIFT) /* Normal Mode */ +# define DBGU_MR_CHMODE_ECHO (1 << DBGU_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define DBGU_MR_CHMODE_LLPBK (2 << DBGU_MR_CHMODE_SHIFT) /* Local Loopback */ +# define DBGU_MR_CHMODE_RLPBK (3 << DBGU_MR_CHMODE_SHIFT) /* Remote Loopback */ + +/* DBGU Interrupt Enable Register, DBGU Interrupt Disable Register, DBGU Interrupt Mask + * Register, and DBGU Status Register common bit field definitions + */ + +#define DBGU_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt */ +#define DBGU_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt */ +#define DBGU_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt */ +#define DBGU_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt */ +#define DBGU_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt */ +#define DBGU_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt */ +#define DBGU_INT_COMMTX (1 << 30) /* Bit 30: COMMTX (from ARM) Interrupt */ +#define DBGU_INT_COMMRX (1 << 31) /* Bit 31: COMMRX (from ARM) Interrupt */ + +#define DBGU_INT_ALLINTS (0xc00002e3) + +/* DBGU Receiver Holding Register */ + +#define DBGU_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character */ +#define DBGU_RHR_RXCHR_MASK (0xff << DBGU_RHR_RXCHR_SHIFT) + +/* DBGU Transmit Holding Register */ + +#define DBGU_THR_TXCHR_SHIFT (0) /* Bits 0-7: Character to be Transmitted (DBGU only) */ +#define DBGU_THR_TXCHR_MASK (0xff << DBGU_THR_TXCHR_SHIFT) + +/* DBGU Baud Rate Generator Register */ + +#define DBGU_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor */ +#define DBGU_BRGR_CD_MASK (0xffff << DBGU_BRGR_CD_SHIFT) +# define DBGU_BRGR_CD_DISABLE (0 << DBGU_BRGR_CD_SHIFT) +# define DBGU_BRGR_CD(n) ((uint32_t)(n) << DBGU_BRGR_CD_SHIFT) + +/* Chip ID Register */ + +#define DBGU_CIDR_VERSION_SHIFT (0) /* Bits 0-4: Version of the Device */ +#define DBGU_CIDR_VERSION_MASK (31 << DBGU_CIDR_VERSION_SHIFT) +#define DBGU_CIDR_EPROC_SHIFT (5) /* Bits 5-7: Embedded Processor */ +#define DBGU_CIDR_EPROC_MASK (7 << DBGU_CIDR_EPROC_SHIFT) +# define DBGU_CIDR_EPROC_ARM946ES (1 << DBGU_CIDR_EPROC_SHIFT) /* ARM946ES */ +# define DBGU_CIDR_EPROC_ARM7TDMI (2 << DBGU_CIDR_EPROC_SHIFT) /* ARM7TDMI */ +# define DBGU_CIDR_EPROC_CM3 (3 << DBGU_CIDR_EPROC_SHIFT) /* Cortex-M3 */ +# define DBGU_CIDR_EPROC_ARM920T (4 << DBGU_CIDR_EPROC_SHIFT) /* ARM920T */ +# define DBGU_CIDR_EPROC_ARM926EJS (5 << DBGU_CIDR_EPROC_SHIFT) /* ARM926EJS */ +# define DBGU_CIDR_EPROC_CA5 (6 << DBGU_CIDR_EPROC_SHIFT) /* Cortex-A5 */ +#define DBGU_CIDR_NVPSIZ_SHIFT (8) /* Bits 8-11: Nonvolatile Program Memory Size */ +#define DBGU_CIDR_NVPSIZ_MASK (15 << DBGU_CIDR_NVPSIZ_SHIFT) +# define DBGU_CIDR_NVPSIZ_NONE (0 << DBGU_CIDR_NVPSIZ_SHIFT) /* None */ +# define DBGU_CIDR_NVPSIZ_8K (1 << DBGU_CIDR_NVPSIZ_SHIFT) /* 8 Kbytes */ +# define DBGU_CIDR_NVPSIZ_16K (2 << DBGU_CIDR_NVPSIZ_SHIFT) /* 16 Kbytes */ +# define DBGU_CIDR_NVPSIZ_32K (3 << DBGU_CIDR_NVPSIZ_SHIFT) /* 32 Kbytes */ +# define DBGU_CIDR_NVPSIZ_64K (5 << DBGU_CIDR_NVPSIZ_SHIFT) /* 64 Kbytes */ +# define DBGU_CIDR_NVPSIZ_128K (7 << DBGU_CIDR_NVPSIZ_SHIFT) /* 128 Kbytes */ +# define DBGU_CIDR_NVPSIZ_256K (9 << DBGU_CIDR_NVPSIZ_SHIFT) /* 256 Kbytes */ +# define DBGU_CIDR_NVPSIZ_512K (10 << DBGU_CIDR_NVPSIZ_SHIFT) /* 512 Kbytes */ +# define DBGU_CIDR_NVPSIZ_1M (12 << DBGU_CIDR_NVPSIZ_SHIFT) /* 1024 Kbytes */ +# define DBGU_CIDR_NVPSIZ_2M (14 << DBGU_CIDR_NVPSIZ_SHIFT) /* 2048 Kbytes */ +#define DBGU_CIDR_NVPSIZ2_SHIFT (12) /* Bits 12-15: Second Nonvolatile Program Memory Size */ +#define DBGU_CIDR_NVPSIZ2_MASK (15 << DBGU_CIDR_NVPSIZ2_SHIFT) +# define DBGU_CIDR_NVPSIZ2_NONE (0 << DBGU_CIDR_NVPSIZ2_SHIFT) /* None */ +# define DBGU_CIDR_NVPSIZ2_8K (1 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 8 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_16K (2 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 16 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_32K (3 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 32 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_64K (5 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 64 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_128K (7 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 128 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_256K (9 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 256 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_512K (10 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 512 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_1M (12 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 1024 Kbytes */ +# define DBGU_CIDR_NVPSIZ2_2M (14 << DBGU_CIDR_NVPSIZ2_SHIFT) /* 2048 Kbytes */ +#define DBGU_CIDR_SRAMSIZ_SHIFT (16) /* Bits 16-19: Internal SRAM Size */ +#define DBGU_CIDR_SRAMSIZ_MASK (15 << DBGU_CIDR_SRAMSIZ_SHIFT) +# define DBGU_CIDR_SRAMSIZ_1K (1 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 1 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_2K (2 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 2 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_6K (3 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 6 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_112K (4 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 112 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_4K (5 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 4 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_80K (6 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 80 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_160K (7 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 160 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_8K (8 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 8 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_16K (9 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 16 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_32K (10 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 32 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_64K (11 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 64 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_128K (12 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 128 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_256K (13 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 256 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_96K (14 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 96 Kbytes */ +# define DBGU_CIDR_SRAMSIZ_512K (15 << DBGU_CIDR_SRAMSIZ_SHIFT) /* 512 Kbytes */ +#define DBGU_CIDR_ARCH_SHIFT (20) /* Bits 20-23: Architecture Identifier */ +#define DBGU_CIDR_ARCH_MASK (15 << DBGU_CIDR_ARCH_SHIFT) +# define DBGU_CIDR_ARCH_AT91SAM9xx (0x19 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM9xx Series */ +# define DBGU_CIDR_ARCH_AT91SAM9XExx (0x29 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM9XExx Series */ +# define DBGU_CIDR_ARCH_AT91x34 (0x34 << DBGU_CIDR_ARCH_SHIFT) /* AT91x34 Series */ +# define DBGU_CIDR_ARCH_CAP7 (0x37 << DBGU_CIDR_ARCH_SHIFT) /* CAP7 Series */ +# define DBGU_CIDR_ARCH_CAP9 (0x39 << DBGU_CIDR_ARCH_SHIFT) /* CAP9 Series */ +# define DBGU_CIDR_ARCH_CAP11 (0x3b << DBGU_CIDR_ARCH_SHIFT) /* CAP11 Series */ +# define DBGU_CIDR_ARCH_AT91x40 (0x40 << DBGU_CIDR_ARCH_SHIFT) /* AT91x40 Series */ +# define DBGU_CIDR_ARCH_AT91x42 (0x42 << DBGU_CIDR_ARCH_SHIFT) /* AT91x42 Series */ +# define DBGU_CIDR_ARCH_AT91x55 (0x55 << DBGU_CIDR_ARCH_SHIFT) /* AT91x55 Series */ +# define DBGU_CIDR_ARCH_AT91SAM7Axx (0x60 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7Axx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7AQxx (0x61 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7AQxx Series */ +# define DBGU_CIDR_ARCH_AT91x63 (0x63 << DBGU_CIDR_ARCH_SHIFT) /* AT91x63 Series */ +# define DBGU_CIDR_ARCH_AT91SAM7Sxx (0x70 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7Sxx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7XCxx (0x71 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7XCxx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7SExx (0x72 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7SExx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7Lxx (0x73 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7Lxx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7Xxx (0x75 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7Xxx Series */ +# define DBGU_CIDR_ARCH_AT91SAM7SLxx (0x76 << DBGU_CIDR_ARCH_SHIFT) /* AT91SAM7SLxx Series */ +# define DBGU_CIDR_ARCH_ATSAM3UxC (0x80 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3UxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3UxE (0x81 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3UxE Series (144-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3AxC (0x83 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3AxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3XxC (0x84 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3XxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3XxE (0x85 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3XxE Series (144-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3XxG (0x86 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3XxG Series (208/217-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SxA (0x88 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SxA Series (48-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SxB (0x89 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SxB Series (64-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SxC (0x8a << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_AT91x92 (0x92 << DBGU_CIDR_ARCH_SHIFT) /* AT91x92 Series */ +# define DBGU_CIDR_ARCH_ATSAM3NxA (0x93 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3NxA Series (48-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3NxB (0x94 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3NxB Series (64-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3NxC (0x95 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3NxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SDxA (0x98 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SDxA Series (48-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SDxB (0x99 << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SDxB Series (64-pin) */ +# define DBGU_CIDR_ARCH_ATSAM3SDxC (0x9a << DBGU_CIDR_ARCH_SHIFT) /* ATSAM3SDxC Series (100-pin) */ +# define DBGU_CIDR_ARCH_ATSAMA5xx (0xa5 << DBGU_CIDR_ARCH_SHIFT) /* ATSAMA5xx Series */ +# define DBGU_CIDR_ARCH_AT75Cxx (0xf0 << DBGU_CIDR_ARCH_SHIFT) /* AT75Cxx Series */ +#define DBGU_CIDR_NVPTYP_SHIFT (28) /* Bits 28-30: Nonvolatile Program Memory Type */ +#define DBGU_CIDR_NVPTYP_MASK (7 << DBGU_CIDR_NVPTYP_SHIFT) +# define DBGU_CIDR_NVPTYP_ROM (0 << DBGU_CIDR_NVPTYP_SHIFT) /* ROM */ +# define DBGU_CIDR_NVPTYP_ROMLESS (1 << DBGU_CIDR_NVPTYP_SHIFT) /* ROMless or on-chip Flash */ +# define DBGU_CIDR_NVPTYP_SRAM (4 << DBGU_CIDR_NVPTYP_SHIFT) /* SRAM emulating ROM */ +# define DBGU_CIDR_NVPTYP_FLASH (2 << DBGU_CIDR_NVPTYP_SHIFT) /* Embedded Flash Memory */ +# define DBGU_CIDR_NVPTYP_ROMFLASH (3 << DBGU_CIDR_NVPTYP_SHIFT) /* ROM and Embedded Flash Memory */ +#define DBGU_CIDR_EXT (1 << 31) /* Bit 31: Extension Flag */ + +/* Chip ID Extension Register (32-bit ID */ + +/* Force NTRST Register */ + +#define DBGU_FNR_FNTRST (1 << 0) /* Bit 0: Force NTRST */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DBGU_H */ diff --git a/arch/arm/src/sama5/chip/sam_dmac.h b/arch/arm/src/sama5/chip/sam_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..3dc39d3d4dda0b13f65442f93c96511d67891511 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_dmac.h @@ -0,0 +1,842 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_dmac.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DMAC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DMAC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* DMAC register offsets ****************************************************************/ + +/* Global Registers */ + +#define SAM_DMAC_GCFG_OFFSET 0x0000 /* DMAC Global Configuration Register */ +#define SAM_DMAC_EN_OFFSET 0x0004 /* DMAC Enable Register */ +#define SAM_DMAC_SREQ_OFFSET 0x0008 /* DMAC Software Single Request Register */ +#define SAM_DMAC_CREQ_OFFSET 0x000c /* DMAC Software Chunk Transfer Request Register */ +#define SAM_DMAC_LAST_OFFSET 0x0010 /* DMAC Software Last Transfer Flag Register */ + /* 0x014: Reserved */ +#define SAM_DMAC_EBCIER_OFFSET 0x0018 /* DMAC Error Interrupt Enable */ +#define SAM_DMAC_EBCIDR_OFFSET 0x001c /* DMAC Error Interrupt Disable */ +#define SAM_DMAC_EBCIMR_OFFSET 0x0020 /* DMAC Error Interrupt Mask */ +#define SAM_DMAC_EBCISR_OFFSET 0x0024 /* DMAC Error Status */ +#define SAM_DMAC_CHER_OFFSET 0x0028 /* DMAC Channel Handler Enable Register */ +#define SAM_DMAC_CHDR_OFFSET 0x002c /* DMAC Channel Handler Disable Register */ +#define SAM_DMAC_CHSR_OFFSET 0x0030 /* DMAC Channel Handler Status Register */ + /* 0x034-0x38: Reserved */ +/* DMA channel registers */ + +#define SAM_DMAC_CH_OFFSET(n) (0x003c+((n)*0x0028)) +#define SAM_DMAC_CH0_OFFSET 0x003c /* 0x3c-0x60: Channel 0 */ +#define SAM_DMAC_CH1_OFFSET 0x0064 /* 0x64-0x88: Channel 1 */ +#define SAM_DMAC_CH2_OFFSET 0x008c /* 0x8c-0xb0: Channel 2 */ +#define SAM_DMAC_CH3_OFFSET 0x00b4 /* 0xb4-0xd8: Channel 3 */ +#define SAM_DMAC_CH4_OFFSET 0x00dc /* 0xb4-0xd8: Channel 4 */ +#define SAM_DMAC_CH5_OFFSET 0x0104 /* 0xb4-0xd8: Channel 5 */ +#define SAM_DMAC_CH6_OFFSET 0x012c /* 0xb4-0xd8: Channel 6 */ +#define SAM_DMAC_CH7_OFFSET 0x0154 /* 0xb4-0xd8: Channel 7 */ + +#define SAM_DMAC_CH_SADDR_OFFSET 0x0000 /* DMAC Channel Source Address Register */ +#define SAM_DMAC_CH_DADDR_OFFSET 0x0004 /* DMAC Channel Destination Address Register */ +#define SAM_DMAC_CH_DSCR_OFFSET 0x0008 /* DMAC Channel Descriptor Address Register */ +#define SAM_DMAC_CH_CTRLA_OFFSET 0x000c /* DMAC Channel Control A Register */ +#define SAM_DMAC_CH_CTRLB_OFFSET 0x0010 /* DMAC Channel Control B Register */ +#define SAM_DMAC_CH_CFG_OFFSET 0x0014 /* DMAC Channel Configuration Register */ +#define SAM_DMAC_CH_SPIP_OFFSET 0x0018 /* DMAC Channel Source PinP Configuration Register */ +#define SAM_DMAC_CH_DPIP_OFFSET 0x001c /* DMAC Channel Destination PinP Configuration Register */ + /* 0x20-0x24: Reserved */ +#define SAM_DMAC_WPMR_OFFSET 0x01e4 /* DMAC Write Protect Mode Register */ +#define SAM_DMAC_WPSR_OFFSET 0x01e8 /* DMAC Write Protect Status Register */ + /* 0x01ec-0x1fc: Reserved */ + +/* DMAC0 register adresses **************************************************************/ +/* DMAC0 Global Registers */ + +#define SAM_DMAC0_GCFG (SAM_DMAC0_VBASE+SAM_DMAC_GCFG_OFFSET) +#define SAM_DMAC0_EN (SAM_DMAC0_VBASE+SAM_DMAC_EN_OFFSET) +#define SAM_DMAC0_SREQ (SAM_DMAC0_VBASE+SAM_DMAC_SREQ_OFFSET) +#define SAM_DMAC0_CREQ (SAM_DMAC0_VBASE+SAM_DMAC_CREQ_OFFSET) +#define SAM_DMAC0_LAST (SAM_DMAC0_VBASE+SAM_DMAC_LAST_OFFSET) +#define SAM_DMAC0_EBCIER (SAM_DMAC0_VBASE+SAM_DMAC_EBCIER_OFFSET) +#define SAM_DMAC0_EBCIDR (SAM_DMAC0_VBASE+SAM_DMAC_EBCIDR_OFFSET) +#define SAM_DMAC0_EBCIMR (SAM_DMAC0_VBASE+SAM_DMAC_EBCIMR_OFFSET) +#define SAM_DMAC0_EBCISR (SAM_DMAC0_VBASE+SAM_DMAC_EBCISR_OFFSET) +#define SAM_DMAC0_CHER (SAM_DMAC0_VBASE+SAM_DMAC_CHER_OFFSET) +#define SAM_DMAC0_CHDR (SAM_DMAC0_VBASE+SAM_DMAC_CHDR_OFFSET) +#define SAM_DMAC0_CHSR (SAM_DMAC0_VBASE+SAM_DMAC_CHSR_OFFSET) + +#define SAM_DMAC0_WPMR (SAM_DMAC0_VBASE+SAM_DMAC_WPMR_OFFSET) +#define SAM_DMAC0_WPSR (SAM_DMAC0_VBASE+SAM_DMAC_WPSR_OFFSET) + +/* DMAC0 channel registers */ + +#define SAM_DMAC0_CH_BASE(n) (SAM_DMAC0_VBASE+SAM_DMAC_CH_OFFSET(n)) +#define SAM_DMAC0_CH0_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH0_OFFSET) +#define SAM_DMAC0_CH1_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH1_OFFSET) +#define SAM_DMAC0_CH2_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH2_OFFSET) +#define SAM_DMAC0_CH3_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH3_OFFSET) +#define SAM_DMAC0_CH4_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH4_OFFSET) +#define SAM_DMAC0_CH5_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH5_OFFSET) +#define SAM_DMAC0_CH6_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH6_OFFSET) +#define SAM_DMAC0_CH7_BASE (SAM_DMAC0_VBASE+SAM_DMAC_CH7_OFFSET) + +#define SAM_DMAC0_CH_SADDR(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH_DADDR(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH_DSCR(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH_CTRLA(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH_CTRLB(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH_CFG(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH_SPIP(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH_DPIP(n) (SAM_DMAC0_CH_BASE(n)+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH0_SADDR (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH0_DADDR (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH0_DSCR (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH0_CTRLA (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH0_CTRLB (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH0_CFG (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH0_SPIP (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH0_DPIP (SAM_DMAC0_CH0_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH1_SADDR (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH1_DADDR (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH1_DSCR (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH1_CTRLA (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH1_CTRLB (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH1_CFG (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH1_SPIP (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH1_DPIP (SAM_DMAC0_CH1_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH2_SADDR (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH2_DADDR (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH2_DSCR (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH2_CTRLA (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH2_CTRLB (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH2_CFG (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH2_SPIP (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH2_DPIP (SAM_DMAC0_CH2_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH3_SADDR (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH3_DADDR (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH3_DSCR (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH3_CTRLA (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH3_CTRLB (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH3_CFG (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH3_SPIP (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH3_DPIP (SAM_DMAC0_CH3_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH4_SADDR (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH4_DADDR (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH4_DSCR (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH4_CTRLA (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH4_CTRLB (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH4_CFG (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH4_SPIP (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH4_DPIP (SAM_DMAC0_CH4_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH5_SADDR (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH5_DADDR (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH5_DSCR (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH5_CTRLA (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH5_CTRLB (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH5_CFG (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH5_SPIP (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH5_DPIP (SAM_DMAC0_CH5_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH6_SADDR (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH6_DADDR (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH6_DSCR (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH6_CTRLA (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH6_CTRLB (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH6_CFG (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH6_SPIP (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH6_DPIP (SAM_DMAC0_CH6_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC0_CH7_SADDR (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC0_CH7_DADDR (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC0_CH7_DSCR (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC0_CH7_CTRLA (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC0_CH7_CTRLB (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC0_CH7_CFG (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC0_CH7_SPIP (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC0_CH7_DPIP (SAM_DMAC0_CH7_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +/* DMAC1 register adresses **************************************************************/ +/* DMAC1 Global Registers */ + +#define SAM_DMAC1_GCFG (SAM_DMAC1_VBASE+SAM_DMAC_GCFG_OFFSET) +#define SAM_DMAC1_EN (SAM_DMAC1_VBASE+SAM_DMAC_EN_OFFSET) +#define SAM_DMAC1_SREQ (SAM_DMAC1_VBASE+SAM_DMAC_SREQ_OFFSET) +#define SAM_DMAC1_CREQ (SAM_DMAC1_VBASE+SAM_DMAC_CREQ_OFFSET) +#define SAM_DMAC1_LAST (SAM_DMAC1_VBASE+SAM_DMAC_LAST_OFFSET) +#define SAM_DMAC1_EBCIER (SAM_DMAC1_VBASE+SAM_DMAC_EBCIER_OFFSET) +#define SAM_DMAC1_EBCIDR (SAM_DMAC1_VBASE+SAM_DMAC_EBCIDR_OFFSET) +#define SAM_DMAC1_EBCIMR (SAM_DMAC1_VBASE+SAM_DMAC_EBCIMR_OFFSET) +#define SAM_DMAC1_EBCISR (SAM_DMAC1_VBASE+SAM_DMAC_EBCISR_OFFSET) +#define SAM_DMAC1_CHER (SAM_DMAC1_VBASE+SAM_DMAC_CHER_OFFSET) +#define SAM_DMAC1_CHDR (SAM_DMAC1_VBASE+SAM_DMAC_CHDR_OFFSET) +#define SAM_DMAC1_CHSR (SAM_DMAC1_VBASE+SAM_DMAC_CHSR_OFFSET) + +#define SAM_DMAC1_WPMR (SAM_DMAC1_VBASE+SAM_DMAC_WPMR_OFFSET) +#define SAM_DMAC1_WPSR (SAM_DMAC1_VBASE+SAM_DMAC_WPSR_OFFSET) + +/* DMAC1 channel registers */ + +#define SAM_DMAC1_CH_BASE(n) (SAM_DMAC1_VBASE+SAM_DMAC_CH_OFFSET(n)) +#define SAM_DMAC1_CH0_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH0_OFFSET) +#define SAM_DMAC1_CH1_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH1_OFFSET) +#define SAM_DMAC1_CH2_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH2_OFFSET) +#define SAM_DMAC1_CH3_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH3_OFFSET) +#define SAM_DMAC1_CH4_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH4_OFFSET) +#define SAM_DMAC1_CH5_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH5_OFFSET) +#define SAM_DMAC1_CH6_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH6_OFFSET) +#define SAM_DMAC1_CH7_BASE (SAM_DMAC1_VBASE+SAM_DMAC_CH7_OFFSET) + +#define SAM_DMAC1_CH_SADDR(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH_DADDR(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH_DSCR(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH_CTRLA(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH_CTRLB(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH_CFG(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH_SPIP(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH_DPIP(n) (SAM_DMAC1_CH_BASE(n)+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH0_SADDR (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH0_DADDR (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH0_DSCR (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH0_CTRLA (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH0_CTRLB (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH0_CFG (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH0_SPIP (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH0_DPIP (SAM_DMAC1_CH0_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH1_SADDR (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH1_DADDR (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH1_DSCR (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH1_CTRLA (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH1_CTRLB (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH1_CFG (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH1_SPIP (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH1_DPIP (SAM_DMAC1_CH1_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH2_SADDR (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH2_DADDR (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH2_DSCR (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH2_CTRLA (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH2_CTRLB (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH2_CFG (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH2_SPIP (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH2_DPIP (SAM_DMAC1_CH2_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH3_SADDR (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH3_DADDR (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH3_DSCR (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH3_CTRLA (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH3_CTRLB (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH3_CFG (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH3_SPIP (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH3_DPIP (SAM_DMAC1_CH3_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH4_SADDR (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH4_DADDR (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH4_DSCR (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH4_CTRLA (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH4_CTRLB (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH4_CFG (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH4_SPIP (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH4_DPIP (SAM_DMAC1_CH4_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH5_SADDR (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH5_DADDR (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH5_DSCR (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH5_CTRLA (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH5_CTRLB (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH5_CFG (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH5_SPIP (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH5_DPIP (SAM_DMAC1_CH5_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH6_SADDR (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH6_DADDR (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH6_DSCR (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH6_CTRLA (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH6_CTRLB (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH6_CFG (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH6_SPIP (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH6_DPIP (SAM_DMAC1_CH6_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +#define SAM_DMAC1_CH7_SADDR (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_SADDR_OFFSET) +#define SAM_DMAC1_CH7_DADDR (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_DADDR_OFFSET) +#define SAM_DMAC1_CH7_DSCR (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_DSCR_OFFSET) +#define SAM_DMAC1_CH7_CTRLA (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_CTRLA_OFFSET) +#define SAM_DMAC1_CH7_CTRLB (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_CTRLB_OFFSET) +#define SAM_DMAC1_CH7_CFG (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_CFG_OFFSET) +#define SAM_DMAC1_CH7_SPIP (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_SPIP_OFFSET) +#define SAM_DMAC1_CH7_DPIP (SAM_DMAC1_CH7_BASE+SAM_DMAC_CH_DPIP_OFFSET) + +/* DMAC register bit definitions ********************************************************/ + +/* Global Registers */ + +/* DMAC Global Configuration Register */ + +#define DMAC_GCFG_ARB_CFG (1 << 4) /* Bit 4: Arbiter Configuration */ +# define DMAC_GCFG_ARB_FIXED (0) /* Bit 4=0: Fixed priority arbiter */ +# define DMAC_GCFG_ARB_ROUNDROBIN (1 << 4) /* Bit 4=1: Round robin arbiter */ +#define DMAC_DICEN (1 << 8) /* Bit 8: Descriptor Integrity Check */ + +/* DMAC Enable Register */ + +#define DMAC_EN_ENABLE (1 << 0) /* Bit 0: DMA controller enable */ + +/* DMAC Software Single Request Register */ + +#define DMAC_SREQ_SHIFT(n) ((n)<<1) +#define DMAC_SREQ_MASK(n) (3 << DMAC_SREQ_SHIFT(n)) +#define DMAC_SREQ0_SHIFT (0) /* Bits 0-1: Channel 0 */ +#define DMAC_SREQ0_MASK (3 << DMAC_SREQ0_SHIFT) +#define DMAC_SREQ1_SHIFT (2) /* Bits 2-3: Channel 1 */ +#define DMAC_SREQ1_MASK (3 << DMAC_SREQ1_SHIFT) +#define DMAC_SREQ2_SHIFT (4) /* Bits 4-5: Channel 2 */ +#define DMAC_SREQ2_MASK (3 << DMAC_SREQ2_SHIFT) +#define DMAC_SREQ3_SHIFT (6) /* Bits 6-7: Channel 3 */ +#define DMAC_SREQ3_MASK (3 << DMAC_SREQ3_SHIFT) +#define DMAC_SREQ4_SHIFT (8) /* Bits 8-9: Channel 4 */ +#define DMAC_SREQ4_MASK (3 << DMAC_SREQ4_SHIFT) +#define DMAC_SREQ5_SHIFT (10) /* Bits 10-11: Channel 5 */ +#define DMAC_SREQ5_MASK (3 << DMAC_SREQ5_SHIFT) +#define DMAC_SREQ6_SHIFT (12) /* Bits 12-13: Channel 6 */ +#define DMAC_SREQ6_MASK (3 << DMAC_SREQ6_SHIFT) +#define DMAC_SREQ7_SHIFT (14) /* Bits 14-15: Channel 7 */ +#define DMAC_SREQ7_MASK (3 << DMAC_SREQ7_SHIFT) + +#define DMAC_SREQ_SSREQ_SHIFT (0) /* Even bits: Request a source single transfer */ +# define DMAC_SREQ_SSREQ(n) (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ_SHIFT(n))) +# define DMAC_SREQ_SSREQ0 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ0_SHIFT)) +# define DMAC_SREQ_SSREQ1 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ1_SHIFT)) +# define DMAC_SREQ_SSREQ2 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ2_SHIFT)) +# define DMAC_SREQ_SSREQ3 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ3_SHIFT)) +# define DMAC_SREQ_SSREQ4 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ4_SHIFT)) +# define DMAC_SREQ_SSREQ5 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ5_SHIFT)) +# define DMAC_SREQ_SSREQ6 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ6_SHIFT)) +# define DMAC_SREQ_SSREQ7 (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ7_SHIFT)) +#define DMAC_SREQ_DSREQ_SHIFT (1) /* Odd bits: Request a destination single transfer */ +# define DMAC_SREQ_DSREQ(n) (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ_SHIFT(n)))) +# define DMAC_SREQ_DSREQ0 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ0_SHIFT)) +# define DMAC_SREQ_DSREQ1 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ1_SHIFT)) +# define DMAC_SREQ_DSREQ2 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ2_SHIFT)) +# define DMAC_SREQ_DSREQ3 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ3_SHIFT)) +# define DMAC_SREQ_DSREQ4 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ4_SHIFT)) +# define DMAC_SREQ_DSREQ5 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ5_SHIFT)) +# define DMAC_SREQ_DSREQ6 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ6_SHIFT)) +# define DMAC_SREQ_DSREQ7 (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ7_SHIFT)) + +/* DMAC Software Chunk Transfer Request Register */ + +#define DMAC_CREQ_SHIFT(n) ((n)<<1) +#define DMAC_CREQ_MASK(n) (3 << DMAC_CREQ_SHIFT(n)) +#define DMAC_CREQ0_SHIFT (0) /* Bits 0-1: Channel 0 */ +#define DMAC_CREQ0_MASK (3 << DMAC_CREQ0_SHIFT) +#define DMAC_CREQ1_SHIFT (2) /* Bits 2-3: Channel 1 */ +#define DMAC_CREQ1_MASK (3 << DMAC_CREQ1_SHIFT) +#define DMAC_CREQ2_SHIFT (4) /* Bits 4-5: Channel 2 */ +#define DMAC_CREQ2_MASK (3 << DMAC_CREQ2_SHIFT) +#define DMAC_CREQ3_SHIFT (6) /* Bits 6-7: Channel 3 */ +#define DMAC_CREQ3_MASK (3 << DMAC_CREQ3_SHIFT) +#define DMAC_CREQ4_SHIFT (8) /* Bits 8-9: Channel 4 */ +#define DMAC_CREQ4_MASK (3 << DMAC_CREQ4_SHIFT) +#define DMAC_CREQ5_SHIFT (10) /* Bits 10-11: Channel 5 */ +#define DMAC_CREQ5_MASK (3 << DMAC_CREQ5_SHIFT) +#define DMAC_CREQ6_SHIFT (12) /* Bits 12-13: Channel 6 */ +#define DMAC_CREQ6_MASK (3 << DMAC_CREQ6_SHIFT) +#define DMAC_CREQ7_SHIFT (14) /* Bits 14-15: Channel 7 */ +#define DMAC_CREQ7_MASK (3 << DMAC_CREQ7_SHIFT) + +#define DMAC_CREQ_SCREQ_SHIFT (0) /* Even bits: Request a source chunk transfer */ +# define DMAC_CREQ_SCREQ(n) (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ_SHIFT(n))) +# define DMAC_CREQ_SCREQ0 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ0_SHIFT)) +# define DMAC_CREQ_SCREQ1 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ1_SHIFT)) +# define DMAC_CREQ_SCREQ2 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ2_SHIFT)) +# define DMAC_CREQ_SCREQ3 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ3_SHIFT)) +# define DMAC_CREQ_SCREQ4 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ4_SHIFT)) +# define DMAC_CREQ_SCREQ5 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ5_SHIFT)) +# define DMAC_CREQ_SCREQ6 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ6_SHIFT)) +# define DMAC_CREQ_SCREQ7 (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ7_SHIFT)) +#define DMAC_CREQ_DCREQ_SHIFT (1) /* Odd bits: Request a destination chunk transfer */ +# define DMAC_CREQ_DCREQ(n) (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ_SHIFT(n))) +# define DMAC_CREQ_DCREQ0 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ0_SHIFT)) +# define DMAC_CREQ_DCREQ1 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ1_SHIFT)) +# define DMAC_CREQ_DCREQ2 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ2_SHIFT)) +# define DMAC_CREQ_DCREQ3 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ3_SHIFT)) +# define DMAC_CREQ_DCREQ4 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ4_SHIFT)) +# define DMAC_CREQ_DCREQ5 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ5_SHIFT)) +# define DMAC_CREQ_DCREQ6 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ6_SHIFT)) +# define DMAC_CREQ_DCREQ7 (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ7_SHIFT)) + +/* DMAC Software Last Transfer Flag Register */ + +#define DMAC_LAST_SHIFT(n) ((n)<<1) +#define DMAC_LAST_MASK(n) (3 << DMAC_LAST_SHIFT(n)) +#define DMAC_LAST0_SHIFT (0) /* Bits 0-1: Channel 0 */ +#define DMAC_LAST0_MASK (3 << DMAC_LAST0_SHIFT) +#define DMAC_LAST1_SHIFT (2) /* Bits 2-3: Channel 1 */ +#define DMAC_LAST1_MASK (3 << DMAC_LAST1_SHIFT) +#define DMAC_LAST2_SHIFT (4) /* Bits 4-5: Channel 2 */ +#define DMAC_LAST2_MASK (3 << DMAC_LAST2_SHIFT) +#define DMAC_LAST3_SHIFT (6) /* Bits 6-7: Channel 3 */ +#define DMAC_LAST3_MASK (3 << DMAC_LAST3_SHIFT) +#define DMAC_LAST4_SHIFT (8) /* Bits 8-9: Channel 4 */ +#define DMAC_LAST4_MASK (3 << DMAC_LAST4_SHIFT) +#define DMAC_LAST5_SHIFT (10) /* Bits 10-11: Channel 5 */ +#define DMAC_LAST5_MASK (3 << DMAC_LAST5_SHIFT) +#define DMAC_LAST6_SHIFT (12) /* Bits 12-13: Channel 6 */ +#define DMAC_LAST6_MASK (3 << DMAC_LAST6_SHIFT) +#define DMAC_LAST7_SHIFT (14) /* Bits 14-15: Channel 7 */ +#define DMAC_LAST7_MASK (3 << DMAC_LAST7_SHIFT) + +#define DMAC_LAST_SLAST_SHIFT (0) /* Bits 0, 2, 4, 6: Indicates the last transfer */ +# define DMAC_LAST_SLAST(n) (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST_SHIFT(n))) +# define DMAC_LAST_SLAST0 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST0_SHIFT)) +# define DMAC_LAST_SLAST1 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST1_SHIFT)) +# define DMAC_LAST_SLAST2 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST2_SHIFT)) +# define DMAC_LAST_SLAST3 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST3_SHIFT)) +# define DMAC_LAST_SLAST4 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST4_SHIFT)) +# define DMAC_LAST_SLAST5 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST5_SHIFT)) +# define DMAC_LAST_SLAST6 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST6_SHIFT)) +# define DMAC_LAST_SLAST7 (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST7_SHIFT)) +#define DMAC_LAST_DLAST_SHIFT (1) /* Bits 1, 3, 5, 7: Indicates the last transfer */ +# define DMAC_LAST_DLAST(n) (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST_SHIFT(n)))) +# define DMAC_LAST_DLAST0 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST0_SHIFT)) +# define DMAC_LAST_DLAST1 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST1_SHIFT)) +# define DMAC_LAST_DLAST2 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST2_SHIFT)) +# define DMAC_LAST_DLAST3 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST3_SHIFT)) +# define DMAC_LAST_DLAST4 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST4_SHIFT)) +# define DMAC_LAST_DLAST5 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST5_SHIFT)) +# define DMAC_LAST_DLAST6 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST6_SHIFT)) +# define DMAC_LAST_DLAST7 (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST7_SHIFT)) + +/* DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Enable Register, + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Disable Register, + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Mask Register, and + * DMAC Error, Buffer Transfer and Chained Buffer Transfer Status Register common + * bit field definitions + */ + +#define DMAC_EBC_BTC_SHIFT (0) /* Bits 0-7: Buffer Transfer Completed */ +#define DMAC_EBC_BTC_MASK (0xff << DMAC_EBC_BTC_SHIFT) +# define DMAC_EBC_BTC(n) (1 << (DMAC_EBC_BTC_SHIFT+(n))) +# define DMAC_EBC_BTC0 (1 << (DMAC_EBC_BTC_SHIFT+0)) +# define DMAC_EBC_BTC1 (1 << (DMAC_EBC_BTC_SHIFT+1)) +# define DMAC_EBC_BTC2 (1 << (DMAC_EBC_BTC_SHIFT+2)) +# define DMAC_EBC_BTC3 (1 << (DMAC_EBC_BTC_SHIFT+3)) +# define DMAC_EBC_BTC4 (1 << (DMAC_EBC_BTC_SHIFT+4)) +# define DMAC_EBC_BTC5 (1 << (DMAC_EBC_BTC_SHIFT+5)) +# define DMAC_EBC_BTC6 (1 << (DMAC_EBC_BTC_SHIFT+6)) +# define DMAC_EBC_BTC7 (1 << (DMAC_EBC_BTC_SHIFT+7)) +#define DMAC_EBC_CBTC_SHIFT (8) /* Bits 8-15: Chained Buffer Transfer Completed */ +#define DMAC_EBC_CBTC_MASK (0xff << DMAC_EBC_CBTC_SHIFT) +# define DMAC_EBC_CBTC(n) (1 << (DMAC_EBC_CBTC_SHIFT+(n))) +# define DMAC_EBC_CBTC0 (1 << (DMAC_EBC_CBTC_SHIFT+0)) +# define DMAC_EBC_CBTC1 (1 << (DMAC_EBC_CBTC_SHIFT+1)) +# define DMAC_EBC_CBTC2 (1 << (DMAC_EBC_CBTC_SHIFT+2)) +# define DMAC_EBC_CBTC3 (1 << (DMAC_EBC_CBTC_SHIFT+3)) +# define DMAC_EBC_CBTC4 (1 << (DMAC_EBC_CBTC_SHIFT+4)) +# define DMAC_EBC_CBTC5 (1 << (DMAC_EBC_CBTC_SHIFT+5)) +# define DMAC_EBC_CBTC6 (1 << (DMAC_EBC_CBTC_SHIFT+6)) +# define DMAC_EBC_CBTC7 (1 << (DMAC_EBC_CBTC_SHIFT+7)) +#define DMAC_EBC_ERR_SHIFT (16) /* Bits 16-23: Access Error */ +#define DMAC_EBC_ERR_MASK (0xff << DMAC_EBC_ERR_SHIFT) +# define DMAC_EBC_ERR(n) (1 << (DMAC_EBC_ERR_SHIFT+(n))) +# define DMAC_EBC_ERR0 (1 << (DMAC_EBC_ERR_SHIFT+0)) +# define DMAC_EBC_ERR1 (1 << (DMAC_EBC_ERR_SHIFT+1)) +# define DMAC_EBC_ERR2 (1 << (DMAC_EBC_ERR_SHIFT+2)) +# define DMAC_EBC_ERR3 (1 << (DMAC_EBC_ERR_SHIFT+3)) +# define DMAC_EBC_ERR4 (1 << (DMAC_EBC_ERR_SHIFT+4)) +# define DMAC_EBC_ERR5 (1 << (DMAC_EBC_ERR_SHIFT+5)) +# define DMAC_EBC_ERR6 (1 << (DMAC_EBC_ERR_SHIFT+6)) +# define DMAC_EBC_ERR7 (1 << (DMAC_EBC_ERR_SHIFT+7)) +#define DMAC_EBC_DICERR_SHIFT (24) /* Bits 24-31: Descriptor Integrity Check Error */ +#define DMAC_EBC_DICERR_MASK (0xff << DMAC_EBC_DICERR_SHIFT) +# define DMAC_EBC_DICERR(n) (1 << (DMAC_EBC_DICERR_SHIFT+(n))) +# define DMAC_EBC_DICERR0 (1 << (DMAC_EBC_DICERR_SHIFT+0)) +# define DMAC_EBC_DICERR1 (1 << (DMAC_EBC_DICERR_SHIFT+1)) +# define DMAC_EBC_DICERR2 (1 << (DMAC_EBC_DICERR_SHIFT+2)) +# define DMAC_EBC_DICERR3 (1 << (DMAC_EBC_DICERR_SHIFT+3)) +# define DMAC_EBC_DICERR4 (1 << (DMAC_EBC_DICERR_SHIFT+4)) +# define DMAC_EBC_DICERR5 (1 << (DMAC_EBC_DICERR_SHIFT+5)) +# define DMAC_EBC_DICERR6 (1 << (DMAC_EBC_DICERR_SHIFT+6)) +# define DMAC_EBC_DICERR7 (1 << (DMAC_EBC_DICERR_SHIFT+7)) + +#define DMAC_EBC_CBTCINTS(n) (0x00010100 << (n)) /* CBT+ERR interrupts */ +#define DMAC_EBC_CHANINTS(n) (0x00010101 << (n)) /* BTC+CBT+ERR interrupts */ +#define DMAC_EBC_ALLCHANINTS (0x00ffffff) /* All BTC+CBT+ERR interrupts */ +#define DMAC_EBC_ALLINTS (0xffffffff) /* All channel interrupts */ + +/* DMAC Channel Handler Enable Register */ + +#define DMAC_CHER_ENA_SHIFT (0) /* Bits 0-7: Enable channel */ +#define DMAC_CHER_ENA_MASK (0xff << DMAC_CHER_ENA_SHIFT) +# define DMAC_CHER_ENA(n) (1 << (DMAC_CHER_ENA_SHIFT+(n))) +# define DMAC_CHER_ENA0 (1 << (DMAC_CHER_ENA_SHIFT+0)) +# define DMAC_CHER_ENA1 (1 << (DMAC_CHER_ENA_SHIFT+1)) +# define DMAC_CHER_ENA2 (1 << (DMAC_CHER_ENA_SHIFT+2)) +# define DMAC_CHER_ENA3 (1 << (DMAC_CHER_ENA_SHIFT+3)) +# define DMAC_CHER_ENA4 (1 << (DMAC_CHER_ENA_SHIFT+4)) +# define DMAC_CHER_ENA5 (1 << (DMAC_CHER_ENA_SHIFT+5)) +# define DMAC_CHER_ENA6 (1 << (DMAC_CHER_ENA_SHIFT+6)) +# define DMAC_CHER_ENA7 (1 << (DMAC_CHER_ENA_SHIFT+7)) +#define DMAC_CHER_SUSP_SHIFT (8) /* Bits 8-15: Freeze channel and its context */ +#define DMAC_CHER_SUSP_MASK (0xff << DMAC_CHER_SUSP_SHIFT) +# define DMAC_CHER_SUSP(n) (1 << (DMAC_CHER_SUSP_SHIFT+(n))) +# define DMAC_CHER_SUSP0 (1 << (DMAC_CHER_SUSP_SHIFT+0)) +# define DMAC_CHER_SUSP1 (1 << (DMAC_CHER_SUSP_SHIFT+1)) +# define DMAC_CHER_SUSP2 (1 << (DMAC_CHER_SUSP_SHIFT+2)) +# define DMAC_CHER_SUSP3 (1 << (DMAC_CHER_SUSP_SHIFT+3)) +# define DMAC_CHER_SUSP4 (1 << (DMAC_CHER_SUSP_SHIFT+4)) +# define DMAC_CHER_SUSP5 (1 << (DMAC_CHER_SUSP_SHIFT+5)) +# define DMAC_CHER_SUSP6 (1 << (DMAC_CHER_SUSP_SHIFT+6)) +# define DMAC_CHER_SUSP7 (1 << (DMAC_CHER_SUSP_SHIFT+7)) +#define DMAC_CHER_KEEP_SHIFT (24) /* Bits 24-31: Resume channel from automatic stall */ +#define DMAC_CHER_KEEP_MASK (0xff << DMAC_CHER_KEEP_SHIFT) +# define DMAC_CHER_KEEP(n) (1 << (DMAC_CHER_KEEP_SHIFT+(n))) +# define DMAC_CHER_KEEP0 (1 << (DMAC_CHER_KEEP_SHIFT+0)) +# define DMAC_CHER_KEEP1 (1 << (DMAC_CHER_KEEP_SHIFT+1)) +# define DMAC_CHER_KEEP2 (1 << (DMAC_CHER_KEEP_SHIFT+2)) +# define DMAC_CHER_KEEP3 (1 << (DMAC_CHER_KEEP_SHIFT+3)) +# define DMAC_CHER_KEEP4 (1 << (DMAC_CHER_KEEP_SHIFT+4)) +# define DMAC_CHER_KEEP5 (1 << (DMAC_CHER_KEEP_SHIFT+5)) +# define DMAC_CHER_KEEP6 (1 << (DMAC_CHER_KEEP_SHIFT+6)) +# define DMAC_CHER_KEEP7 (1 << (DMAC_CHER_KEEP_SHIFT+7)) + +/* DMAC Channel Handler Disable Register */ + +#define DMAC_CHDR_DIS_SHIFT (0) /* Bits 0-7: Disable DMAC channel */ +#define DMAC_CHDR_DIS_MASK (0xff << DMAC_CHDR_DIS_SHIFT) +# define DMAC_CHDR_DIS(n) (1 << (DMAC_CHDR_DIS_SHIFT+(n))) +# define DMAC_CHDR_DIS0 (1 << (DMAC_CHDR_DIS_SHIFT+0)) +# define DMAC_CHDR_DIS1 (1 << (DMAC_CHDR_DIS_SHIFT+1)) +# define DMAC_CHDR_DIS2 (1 << (DMAC_CHDR_DIS_SHIFT+2)) +# define DMAC_CHDR_DIS3 (1 << (DMAC_CHDR_DIS_SHIFT+3)) +# define DMAC_CHDR_DIS4 (1 << (DMAC_CHDR_DIS_SHIFT+4)) +# define DMAC_CHDR_DIS5 (1 << (DMAC_CHDR_DIS_SHIFT+5)) +# define DMAC_CHDR_DIS6 (1 << (DMAC_CHDR_DIS_SHIFT+6)) +# define DMAC_CHDR_DIS7 (1 << (DMAC_CHDR_DIS_SHIFT+7)) +# define DMAC_CHDR_DIS_ALL DMAC_CHDR_DIS_MASK +#define DMAC_CHDR_RES_SHIFT (8) /* Bits 8-15: Resume trasnfer, restoring context */ +#define DMAC_CHDR_RES_MASK (0xff << DMAC_CHDR_RES_SHIFT) +# define DMAC_CHDR_RES(n) (1 << (DMAC_CHDR_RES_SHIFT+(n))) +# define DMAC_CHDR_RES0 (1 << (DMAC_CHDR_RES_SHIFT+0)) +# define DMAC_CHDR_RES1 (1 << (DMAC_CHDR_RES_SHIFT+1)) +# define DMAC_CHDR_RES2 (1 << (DMAC_CHDR_RES_SHIFT+2)) +# define DMAC_CHDR_RES3 (1 << (DMAC_CHDR_RES_SHIFT+3)) +# define DMAC_CHDR_RES4 (1 << (DMAC_CHDR_RES_SHIFT+4)) +# define DMAC_CHDR_RES5 (1 << (DMAC_CHDR_RES_SHIFT+5)) +# define DMAC_CHDR_RES6 (1 << (DMAC_CHDR_RES_SHIFT+6)) +# define DMAC_CHDR_RES7 (1 << (DMAC_CHDR_RES_SHIFT+7)) + +/* DMAC Channel Handler Status Register */ + +#define DMAC_CHSR_ENA_SHIFT (0) /* Bits 0-7: Indicates that the channel is stalling */ +#define DMAC_CHSR_ENA_MASK (0xff << DMAC_CHSR_ENA_SHIFT) +# define DMAC_CHSR_ENA(n) (1 << (DMAC_CHSR_ENA_SHIFT+(n))) +# define DMAC_CHSR_ENA0 (1 << (DMAC_CHSR_ENA_SHIFT+0)) +# define DMAC_CHSR_ENA1 (1 << (DMAC_CHSR_ENA_SHIFT+1)) +# define DMAC_CHSR_ENA2 (1 << (DMAC_CHSR_ENA_SHIFT+2)) +# define DMAC_CHSR_ENA3 (1 << (DMAC_CHSR_ENA_SHIFT+3)) +# define DMAC_CHSR_ENA4 (1 << (DMAC_CHSR_ENA_SHIFT+4)) +# define DMAC_CHSR_ENA5 (1 << (DMAC_CHSR_ENA_SHIFT+5)) +# define DMAC_CHSR_ENA6 (1 << (DMAC_CHSR_ENA_SHIFT+6)) +# define DMAC_CHSR_ENA7 (1 << (DMAC_CHSR_ENA_SHIFT+7)) +#define DMAC_CHSR_SUSP_SHIFT (8) /* Bits 8-15: Indicates that the channel is empty */ +#define DMAC_CHSR_SUSP_MASK (0xff << DMAC_CHSR_SUSP_SHIFT) +# define DMAC_CHSR_SUSP(n) (1 << (DMAC_CHSR_SUSP_SHIFT+(n))) +# define DMAC_CHSR_SUSP0 (1 << (DMAC_CHSR_SUSP_SHIFT+0)) +# define DMAC_CHSR_SUSP1 (1 << (DMAC_CHSR_SUSP_SHIFT+1)) +# define DMAC_CHSR_SUSP2 (1 << (DMAC_CHSR_SUSP_SHIFT+2)) +# define DMAC_CHSR_SUSP3 (1 << (DMAC_CHSR_SUSP_SHIFT+3)) +# define DMAC_CHSR_SUSP4 (1 << (DMAC_CHSR_SUSP_SHIFT+4)) +# define DMAC_CHSR_SUSP5 (1 << (DMAC_CHSR_SUSP_SHIFT+5)) +# define DMAC_CHSR_SUSP6 (1 << (DMAC_CHSR_SUSP_SHIFT+6)) +# define DMAC_CHSR_SUSP7 (1 << (DMAC_CHSR_SUSP_SHIFT+7)) +#define DMAC_CHSR_EMPT_SHIFT (16) /* Bits 16-23: Access Error Interrupt Enable */ +#define DMAC_CHSR_EMPT_MASK (0xff << DMAC_CHSR_EMPT_SHIFT) +# define DMAC_CHSR_EMPT(n) (1 << (DMAC_CHSR_EMPT_SHIFT+(n))) +# define DMAC_CHSR_EMPT0 (1 << (DMAC_CHSR_EMPT_SHIFT+0)) +# define DMAC_CHSR_EMPT1 (1 << (DMAC_CHSR_EMPT_SHIFT+1)) +# define DMAC_CHSR_EMPT2 (1 << (DMAC_CHSR_EMPT_SHIFT+2)) +# define DMAC_CHSR_EMPT3 (1 << (DMAC_CHSR_EMPT_SHIFT+3)) +# define DMAC_CHSR_EMPT4 (1 << (DMAC_CHSR_EMPT_SHIFT+4)) +# define DMAC_CHSR_EMPT5 (1 << (DMAC_CHSR_EMPT_SHIFT+5)) +# define DMAC_CHSR_EMPT6 (1 << (DMAC_CHSR_EMPT_SHIFT+6)) +# define DMAC_CHSR_EMPT7 (1 << (DMAC_CHSR_EMPT_SHIFT+7)) +#define DMAC_CHSR_STAL_SHIFT (24) /* Bits 24-31: Access Error Interrupt Enable */ +#define DMAC_CHSR_STAL_MASK (0xff << DMAC_CHSR_STAL_SHIFT) +# define DMAC_CHSR_STAL(n) (1 << (DMAC_CHSR_STAL_SHIFT+(n))) +# define DMAC_CHSR_STAL0 (1 << (DMAC_CHSR_STAL_SHIFT+0)) +# define DMAC_CHSR_STAL1 (1 << (DMAC_CHSR_STAL_SHIFT+1)) +# define DMAC_CHSR_STAL2 (1 << (DMAC_CHSR_STAL_SHIFT+2)) +# define DMAC_CHSR_STAL3 (1 << (DMAC_CHSR_STAL_SHIFT+3)) +# define DMAC_CHSR_STAL4 (1 << (DMAC_CHSR_STAL_SHIFT+4)) +# define DMAC_CHSR_STAL5 (1 << (DMAC_CHSR_STAL_SHIFT+5)) +# define DMAC_CHSR_STAL6 (1 << (DMAC_CHSR_STAL_SHIFT+6)) +# define DMAC_CHSR_STAL7 (1 << (DMAC_CHSR_STAL_SHIFT+7)) + +/* DMA channel registers */ +/* DMAC Channel x [x = 0..7] Source Address Register (32-bit address) */ +/* DMAC Channel x [x = 0..7] Destination Address Register (32-bit address) */ + +/* DMAC Channel x [x = 0..7] Descriptor Address Register */ + +#define DMAC_CH_DSCR_IF_SHIFT (0) /* Bits 0-1: Descriptor Interface Selection */ +#define DMAC_CH_DSCR_IF_MASK (3 << DMAC_CH_DSCR_IF_SHIFT) +# define DMAC_CH_DSCR_AHB_IF0 (0 << DMAC_CH_DSCR_IF_SHIFT) /* Fetched via AHB-Lite Interface 0 */ +# define DMAC_CH_DSCR_AHB_IF1 (1 << DMAC_CH_DSCR_IF_SHIFT) /* Fetched via AHB-Lite Interface 1 */ +# define DMAC_CH_DSCR_AHB_IF2 (2 << DMAC_CH_DSCR_IF_SHIFT) /* Fetched via AHB-Lite Interface 2 */ +#define DMAC_CH_DSCR_MASK (0xfffffffc) /* Bits 2-31: Buffer Transfer Descriptor Address */ + +/* DMAC Channel n [n = 0..7] Control A Register */ + +#define DMAC_CH_CTRLA_BTSIZE_MAX (0xffff) +#define DMAC_CH_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-15: Buffer Transfer Size */ +#define DMAC_CH_CTRLA_BTSIZE_MASK (DMAC_CH_CTRLA_BTSIZE_MAX << DMAC_CH_CTRLA_BTSIZE_SHIFT) +#define DMAC_CH_CTRLA_SCSIZE_SHIFT (16) /* Bits 16-18: Source Chunk Transfer Size */ +#define DMAC_CH_CTRLA_SCSIZE_MASK (7 << DMAC_CH_CTRLA_SCSIZE_SHIFT) +# define DMAC_CH_CTRLA_SCSIZE_1 (0 << DMAC_CH_CTRLA_SCSIZE_SHIFT) +# define DMAC_CH_CTRLA_SCSIZE_4 (1 << DMAC_CH_CTRLA_SCSIZE_SHIFT) +# define DMAC_CH_CTRLA_SCSIZE_8 (2 << DMAC_CH_CTRLA_SCSIZE_SHIFT) +# define DMAC_CH_CTRLA_SCSIZE_16 (3 << DMAC_CH_CTRLA_SCSIZE_SHIFT) +#define DMAC_CH_CTRLA_DCSIZE_SHIFT (20) /* Bits 20-21: Destination Chunk Transfer size */ +#define DMAC_CH_CTRLA_DCSIZE_MASK (7 << DMAC_CH_CTRLA_DCSIZE_SHIFT) +# define DMAC_CH_CTRLA_DCSIZE_1 (0 << DMAC_CH_CTRLA_DCSIZE_SHIFT) +# define DMAC_CH_CTRLA_DCSIZE_4 (1 << DMAC_CH_CTRLA_DCSIZE_SHIFT) +# define DMAC_CH_CTRLA_DCSIZE_8 (2 << DMAC_CH_CTRLA_DCSIZE_SHIFT) +# define DMAC_CH_CTRLA_DCSIZE_16 (3 << DMAC_CH_CTRLA_DCSIZE_SHIFT) +#define DMAC_CH_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */ +#define DMAC_CH_CTRLA_SRCWIDTH_MASK (3 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT) +# define DMAC_CH_CTRLA_SRCWIDTH_BYTE (0 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT) +# define DMAC_CH_CTRLA_SRCWIDTH_HWORD (1 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT) +# define DMAC_CH_CTRLA_SRCWIDTH_WORD (2 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT) +# define DMAC_CH_CTRLA_SRCWIDTH_DWORD (3 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT) +#define DMAC_CH_CTRLA_DSTWIDTH_SHIFT (28) /* Bits 28-29 */ +#define DMAC_CH_CTRLA_DSTWIDTH_MASK (3 << DMAC_CH_CTRLA_DSTWIDTH_SHIFT) +# define DMAC_CH_CTRLA_DSTWIDTH_BYTE (0 << DMAC_CH_CTRLA_DSTWIDTH_SHIFT) +# define DMAC_CH_CTRLA_DSTWIDTH_HWORD (1 << DMAC_CH_CTRLA_DSTWIDTH_SHIFT) +# define DMAC_CH_CTRLA_DSTWIDTH_WORD (2 << DMAC_CH_CTRLA_DSTWIDTH_SHIFT) +# define DMAC_CH_CTRLA_DSTWIDTH_DWORD (3 << DMAC_CH_CTRLA_DSTWIDTH_SHIFT) +#define DMAC_CH_CTRLA_DONE (1 << 31) /* Bit 31: Auto disable DMAC */ + +/* DMAC Channel n [n = 0..7] Control B Register */ + +#define DMAC_CH_CTRLB_SIF_SHIFT (0) /* Bits 0-1: Source Interface Selection Field */ +#define DMAC_CH_CTRLB_SIF_MASK (3 << DMAC_CH_CTRLB_SIF_SHIFT) +# define DMAC_CH_CTRLB_SIF_IF0 (0 << DMAC_CH_CTRLB_SIF_SHIFT) /* Via AHB-Lite Interface 0 */ +# define DMAC_CH_CTRLB_SIF_IF1 (1 << DMAC_CH_CTRLB_SIF_SHIFT) /* Via AHB-Lite Interface 1 */ +# define DMAC_CH_CTRLB_SIF_IF2 (2 << DMAC_CH_CTRLB_SIF_SHIFT) /* Via AHB-Lite Interface 2 */ +#define DMAC_CH_CTRLB_DIF_SHIFT (4) /* Bits 4-5: Destination Interface Selection Field */ +#define DMAC_CH_CTRLB_DIF_MASK (3 << DMAC_CH_CTRLB_DIF_SHIFT) +# define DMAC_CH_CTRLB_DIF_IF0 (0 << DMAC_CH_CTRLB_DIF_SHIFT) /* Via AHB-Lite Interface 0 */ +# define DMAC_CH_CTRLB_DIF_IF1 (1 << DMAC_CH_CTRLB_DIF_SHIFT) /* Via AHB-Lite Interface 1 */ +# define DMAC_CH_CTRLB_DIF_IF2 (2 << DMAC_CH_CTRLB_DIF_SHIFT) /* Via AHB-Lite Interface 2 */ +#define DMAC_CH_CTRLB_SRC_PIP (1 << 8) /* Bit 8: Source Picture-in-Picture Mode */ +#define DMAC_CH_CTRLB_DST_PIP (1 << 12) /* Bit 12: Destination Picture-in-Picture Mode */ +#define DMAC_CH_CTRLB_SRCDSCR (1 << 16) /* Bit 16: Source buffer descriptor fetch operation disabled */ +#define DMAC_CH_CTRLB_DSTDSCR (1 << 20) /* Bit 20: Dest buffer descriptor fetch operation disabled */ +#define DMAC_CH_CTRLB_FC_SHIFT (21) /* Bits 21-22: Flow controller */ +#define DMAC_CH_CTRLB_FC_MASK (3 << DMAC_CH_CTRLB_FC_SHIFT) +# define DMAC_CH_CTRLB_FC_M2M (0 << DMAC_CH_CTRLB_FC_SHIFT) /* Memory-to-Memory */ +# define DMAC_CH_CTRLB_FC_M2P (1 << DMAC_CH_CTRLB_FC_SHIFT) /* Memory-to-Peripheral */ +# define DMAC_CH_CTRLB_FC_P2M (2 << DMAC_CH_CTRLB_FC_SHIFT) /* Peripheral-to-Memory */ +# define DMAC_CH_CTRLB_FC_P2P (3 << DMAC_CH_CTRLB_FC_SHIFT) /* Peripheral-to-Peripheral */ +#define DMAC_CH_CTRLB_SRCINCR_SHIFT (24) /* Bits 24-25 */ +#define DMAC_CH_CTRLB_SRCINCR_MASK (3 << DMAC_CH_CTRLB_SRCINCR_SHIFT) +# define DMAC_CH_CTRLB_SRCINCR_INCR (0 << DMAC_CH_CTRLB_SRCINCR_SHIFT) /* Incrementing address */ +# define DMAC_CH_CTRLB_SRCINCR_DECR (1 << DMAC_CH_CTRLB_SRCINCR_SHIFT) /* Decrementing address */ +# define DMAC_CH_CTRLB_SRCINCR_FIXED (2 << DMAC_CH_CTRLB_SRCINCR_SHIFT) /* Fixed address */ +#define DMAC_CH_CTRLB_DSTINCR_SHIFT (28) /* Bits 28-29 */ +#define DMAC_CH_CTRLB_DSTINCR_MASK (3 << DMAC_CH_CTRLB_DSTINCR_SHIFT) +# define DMAC_CH_CTRLB_DSTINCR_INCR (0 << DMAC_CH_CTRLB_DSTINCR_SHIFT) /* Incrementing address */ +# define DMAC_CH_CTRLB_DSTINCR_DECR (1 << DMAC_CH_CTRLB_DSTINCR_SHIFT) /* Decrementing address */ +# define DMAC_CH_CTRLB_DSTINCR_FIXED (2 << DMAC_CH_CTRLB_DSTINCR_SHIFT) /* Fixed address */ +#define DMAC_CH_CTRLB_IEN (1 << 30) /* Bit 30: Interrupt Enable Not */ +#define DMAC_CH_CTRLB_AUTO (1 << 31) /* Bit 31: Automatic Multiple Buffer Transfer*/ + +/* DMAC Channel n [n = 0..7] Configuration Register */ + +#define DMAC_CH_CFG_SRCPER_SHIFT (0) /* Bits 0-3: Source with Peripheral identifier */ +#define DMAC_CH_CFG_SRCPER_MASK (0xff << DMAC_CH_CFG_SRCPER_SHIFT) +#define DMAC_CH_CFG_DSTPER_SHIFT (4) /* Bits 4-7: Destination with Peripheral identifier */ +#define DMAC_CH_CFG_DSTPER_MASK (0xff << DMAC_CH_CFG_DSTPER_SHIFT) +#define DMAC_CH_CFG_SRCREP (1 << 8) /* Bit 8: Source Reloaded from Previous */ +#define DMAC_CH_CFG_SRCH2SEL (1 << 9) /* Bit 9: HW handshake triggers transfer */ +#define DMAC_CH_CFG_SRCPERMSB_SHIFT (10) /* Bits 10-11: SRC_PER Most Significant Bits */ +#define DMAC_CH_CFG_SRCPERMSB_MASK (3 << DMAC_CH_CFG_SRCPERMSB_SHIFT) +#define DMAC_CH_CFG_DSTREP (1 << 8) /* Bit 12: Destination Reloaded from Previous */ +#define DMAC_CH_CFG_DSTH2SEL (1 << 13) /* Bit 13: HW handshake trigger transfer */ +#define DMAC_CH_CFG_DSTPERMSB_SHIFT (14) /* Bits 14-15: SRC_PER Most Significant Bits */ +#define DMAC_CH_CFG_DSTPERMSB_MASK (3 << DMAC_CH_CFG_DSTPERMSB_SHIFT) +#define DMAC_CH_CFG_SOD (1 << 16) /* Bit 16: Stop on done */ +#define DMAC_CH_CFG_LOCKIF (1 << 20) /* Bit 20: Enable lock interface capability */ +#define DMAC_CH_CFG_LOCKB (1 << 21) /* Bit 21: Enable AHB Bus Locking capability */ +#define DMAC_CH_CFG_LOCKIFL (1 << 22) /* Bit 22: Lock Master Interface Arbiter */ +#define DMAC_CH_CFG_AHBPROT_SHIFT (24) /* Bits 24-26: AHB access privilege */ +#define DMAC_CH_CFG_AHBPROT_MASK (7 << DMAC_CH_CFG_AHBPROT_SHIFT) +# define DMAC_CH_CFG_AHBPROT_PRIV (1 << DMAC_CH_CFG_AHBPROT_SHIFT) /* Privileged Access */ +# define DMAC_CH_CFG_AHBPROT_BUFF (2 << DMAC_CH_CFG_AHBPROT_SHIFT) /* Bufferable */ +# define DMAC_CH_CFG_AHBPROT_CACHE (4 << DMAC_CH_CFG_AHBPROT_SHIFT) /* Cacheable */ +#define DMAC_CH_CFG_FIFOCFG_SHIFT (28) /* Bits 28-29: FIFO Configuration */ +#define DMAC_CH_CFG_FIFOCFG_MASK (3 << DMAC_CH_CFG_FIFOCFG_SHIFT) +# define DMAC_CH_CFG_FIFOCFG_ALAP (0 << DMAC_CH_CFG_FIFOCFG_SHIFT) /* Largest length AHB burst */ +# define DMAC_CH_CFG_FIFOCFG_HALF (1 << DMAC_CH_CFG_FIFOCFG_SHIFT) /* Half FIFO size */ +# define DMAC_CH_CFG_FIFOCFG_ASAP (2 << DMAC_CH_CFG_FIFOCFG_SHIFT) /* Single AHB access ASAP */ + +/* DMAC Channel n [n = 0..7] Source Picture-in-Picture Configuration Register */ + +#define DMAC_CH_SPIP_HOLE_SHIFT (0) /* Bits 0-15: Source Picture-in-Picture Hole */ +#define DMAC_CH_SPIP_HOLE_MASK (0xffff << DMAC_CH_SPIP_HOLE_SHIFT) +#define DMAC_CH_SPIP_BOUNDARY_SHIFT (16) /* Bits 16-25: Source Picture-in-Picture Boundary */ +#define DMAC_CH_SPIP_BOUNDARY_MASK (0x3ff << DMAC_CH_SPIP_BOUNDARY_SHIFT) + +/* DMAC Channel n [n = 0..7] Destination Picture-in-Picture Configuration Register */ + +#define DMAC_CH_DPIP_HOLE_SHIFT (0) /* Bits 0-15: Destination Picture-in-Picture Hole */ +#define DMAC_CH_DPIP_HOLE_MASK (0xffff << DMAC_CH_DPIP_HOLE_SHIFT) +#define DMAC_CH_DPIP_BOUNDARY_SHIFT (16) /* Bits 16-25: Destination Picture-in-Picture Boundary */ +#define DMAC_CH_DPIP_BOUNDARY_MASK (0x3ff << DMAC_CH_DPIP_BOUNDARY_SHIFT) + +/* DMAC Write Protect Mode Register */ + +#define DMAC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define DMAC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define DMAC_WPMR_WPKEY_MASK (0xffffff << DMAC_WPMR_WPKEY_SHIFT) +#define DMAC_WPMR_WPKEY (0x444d41 << DMAC_WPMR_WPKEY_SHIFT) + +/* DMAC Write Protect Status Register */ + +#define DMAC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define DMAC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define DMAC_WPSR_WPVSRC_MASK (0xffff << DMAC_WPSR_WPVSRC_SHIFT) + +/* DMA Channel Definitions **************************************************************/ +/* DMA Controller 0 Channel Definitions */ + +#define DMAC0_CH_HSMCI0 (0) /* HSMCI0 Receive/transmit */ +#define DMAC0_CH_SPI0_TX (1) /* SPI0 Transmit */ +#define DMAC0_CH_SPI0_RX (2) /* SPI0 Receive */ +#define DMAC0_CH_USART0_TX (3) /* USART0 Transmit */ +#define DMAC0_CH_USART0_RX (4) /* USART0 Receive */ +#define DMAC0_CH_USART1_TX (5) /* USART1 Transmit */ +#define DMAC0_CH_USART1_RX (6) /* USART1 Receive */ +#define DMAC0_CH_TWI0_TX (7) /* TWI0 Transmit */ +#define DMAC0_CH_TWI0_RX (8) /* TWI0 Receive */ +#define DMAC0_CH_TWI1_TX (9) /* TWI1 Transmit */ +#define DMAC0_CH_TWI1_RX (10) /* TWI1 Receive */ +#define DMAC0_CH_UART0_TX (11) /* UART0 Transmit */ +#define DMAC0_CH_UART0_RX (12) /* UART0 Receive */ +#define DMAC0_CH_SSC0_TX (13) /* SSC0 Transmit */ +#define DMAC0_CH_SSC0_RX (14) /* SSC0 Receive */ +#define DMAC0_CH_SMD_TX (15) /* SMD Transmit */ +#define DMAC0_CH_SMD_RX (16) /* SMD Receive */ + +/* DMA Controller 1 Channel Definitions */ + +#define DMAC1_CH_HSMCI1 (0) /* HSMCI1 Receive/transmit */ +#define DMAC1_CH_HSMCI2 (1) /* HSMCI2 Receive/transmit */ +#define DMAC1_CH_ADC_RX (2) /* ADC Receive */ +#define DMAC1_CH_SSC1_TX (3) /* SSC1 Transmit */ +#define DMAC1_CH_SSC1_RX (4) /* SSC1 Receive */ +#define DMAC1_CH_UART1_TX (5) /* UART1 Transmit */ +#define DMAC1_CH_UART1_RX (6) /* UART1 Receive */ +#define DMAC1_CH_USART2_TX (7) /* USART2 Transmit */ +#define DMAC1_CH_USART2_RX (8) /* USART2 Receive */ +#define DMAC1_CH_USART3_TX (9) /* USART3 Transmit */ +#define DMAC1_CH_USART3_RX (10) /* USART3 Receive */ +#define DMAC1_CH_TWI2_TX (11) /* TWI2 Transmit */ +#define DMAC1_CH_TWI2_RX (12) /* TWI2 Receive */ +#define DMAC1_CH_DBGU_TX (13) /* DBGU Transmit */ +#define DMAC1_CH_DBGU_RX (14) /* DBGU Receive */ +#define DMAC1_CH_SPI1_TX (15) /* SPI1 Transmit */ +#define DMAC1_CH_SPI1_RX (16) /* SPI1 Receive */ +#define DMAC1_CH_SHA_TX (17) /* SHA Transmit */ +#define DMAC1_CH_AES_TX (18) /* AES Transmit */ +#define DMAC1_CH_AES_RX (19) /* AES Receive */ +#define DMAC1_CH_TDES_TX (20) /* TDES Transmit */ +#define DMAC1_CH_TDES_RX (21) /* TDES Receive */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/* DMA multi buffer transfer link list entry structure */ + +struct dma_linklist_s +{ + uint32_t saddr; /* 0 Source address */ + uint32_t daddr; /* 4 Destination address */ + uint32_t ctrla; /* 8 Control A value */ + uint32_t ctrlb; /* 12 Control B value */ + uint32_t dscr; /* 16 Next descriptor address */ +}; + +/* Linked List with CRC16 Attached */ + +struct dma_crc16_linklist_s +{ + uint32_t saddr; /* 0 Source address */ + uint32_t daddr; /* 4 Destination address */ + uint32_t ctrla; /* 8 Control A value */ + uint32_t ctrlb; /* 12 Control B value */ + uint32_t dscr; /* 16 Next descriptor address */ + uint32_t crc16; /* 20 CRC */ +}; + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_DMAC_H */ diff --git a/arch/arm/src/sama5/chip/sam_ehci.h b/arch/arm/src/sama5/chip/sam_ehci.h new file mode 100644 index 0000000000000000000000000000000000000000..e564b1ecc35bb5403fa76e6e6fadec5dceb1bf3a --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_ehci.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/sama5/chip/sam_ehci.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EHCI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EHCI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The SAMA5 supports 3 root hub ports */ + +#define SAM_EHCI_NRHPORT 3 + +/* Registers ****************************************************************/ +/* Traditionally, NuttX specifies register locations using individual + * register offsets from a base address. That tradition is broken here and, + * instead, register blocks are represented as structures. This is done here + * because, in principle, EHCI operational register address may not be known + * at compile time; the operational registers lie at an offset specified in + * the 'caplength' byte of the Host Controller Capability Registers. + * + * However, for the case of the SAMA5 EHCI, we know apriori that the value + * of 'caplength' is 0x10. We keep this structure, however, to faciltate + * porting this driver to other environments where, perhaps, such knowledge + * is not available. + */ + +/* Host Controller Capability Registers */ + +#define HCCR ((struct ehci_hccr_s *)SAM_UHPEHCI_VSECTION) + +/* Host Controller Operational Registers */ + +#define HCOR ((volatile struct ehci_hcor_s *)(SAM_UHPEHCI_VSECTION + 0x10)) + +/* USB2 Debug Port Register Interface. These are not documented, but I was + * able to find these by registers by peeking at EHCI memory. + */ + +#define HDEBUG ((volatile struct ehci_debug_s *)(SAM_UHPEHCI_VSECTION + 0x90)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EHCI_H */ diff --git a/arch/arm/src/sama5/chip/sam_emac.h b/arch/arm/src/sama5/chip/sam_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..d131e51dc758075359323f119bcdae77fd37cb90 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_emac.h @@ -0,0 +1,58 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_emac.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMAC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* These two EMAC implementations differ in naming and in register layout but are + * functionally equivalent. Here they are distinguished as 'A' and 'B'. For now, + * the 'A' and 'B' drivers are kept separate (mostly because the 'B' driver needs + * to support two EMAC blocks. But the 'B' driver should replace the 'A' driver + * someday. + */ + +#if defined(CONFIG_SAMA5_EMACA) +# include "chip/sam_emaca.h" +#elif defined(CONFIG_SAMA5_EMACB) +# include "chip/sam_emacb.h" +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMAC_H */ diff --git a/arch/arm/src/sama5/chip/sam_emaca.h b/arch/arm/src/sama5/chip/sam_emaca.h new file mode 100644 index 0000000000000000000000000000000000000000..536b0cc91447c7080dec04d6b5dc08da7a9954fb --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_emaca.h @@ -0,0 +1,457 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_emaca.h + * This is the form of the EMAC interface used the the SAMA5D3 + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACA_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* EMAC Register Offsets ************************************************************/ + +#define SAM_EMAC_NCR_OFFSET 0x0000 /* Network Control Register */ +#define SAM_EMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */ +#define SAM_EMAC_NSR_OFFSET 0x0008 /* Network Status Register */ + /* 0x000c-0x0010 Reserved */ +#define SAM_EMAC_TSR_OFFSET 0x0014 /* Transmit Status Register */ +#define SAM_EMAC_RBQP_OFFSET 0x0018 /* Receive Buffer Queue Pointer Register */ +#define SAM_EMAC_TBQP_OFFSET 0x001c /* Transmit Buffer Queue Pointer Register */ +#define SAM_EMAC_RSR_OFFSET 0x0020 /* Receive Status Register */ +#define SAM_EMAC_ISR_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_EMAC_IER_OFFSET 0x0028 /* Interrupt Enable Register */ +#define SAM_EMAC_IDR_OFFSET 0x002c /* Interrupt Disable Register */ +#define SAM_EMAC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_EMAC_MAN_OFFSET 0x0034 /* Phy Maintenance Register */ +#define SAM_EMAC_PTR_OFFSET 0x0038 /* Pause Time Register */ +#define SAM_EMAC_PFR_OFFSET 0x003c /* Pause Frames Received Register */ +#define SAM_EMAC_FTO_OFFSET 0x0040 /* Frames Transmitted Ok Register */ +#define SAM_EMAC_SCF_OFFSET 0x0044 /* Single Collision Frames Register */ +#define SAM_EMAC_MCF_OFFSET 0x0048 /* Multiple Collision Frames Register */ +#define SAM_EMAC_FRO_OFFSET 0x004c /* Frames Received Ok Register */ +#define SAM_EMAC_FCSE_OFFSET 0x0050 /* Frame Check Sequence Errors Register */ +#define SAM_EMAC_ALE_OFFSET 0x0054 /* Alignment Errors Register */ +#define SAM_EMAC_DTF_OFFSET 0x0058 /* Deferred Transmission Frames Register */ +#define SAM_EMAC_LCOL_OFFSET 0x005c /* Late Collisions Register */ +#define SAM_EMAC_ECOL_OFFSET 0x0060 /* Excessive Collisions Register */ +#define SAM_EMAC_TUND_OFFSET 0x0064 /* Transmit Underrun Errors Register */ +#define SAM_EMAC_CSE_OFFSET 0x0068 /* Carrier Sense Errors Register */ +#define SAM_EMAC_RRE_OFFSET 0x006c /* Receive Resource Errors Register */ +#define SAM_EMAC_ROV_OFFSET 0x0070 /* Receive Overrun Errors Register */ +#define SAM_EMAC_RSE_OFFSET 0x0074 /* Receive Symbol Errors Register */ +#define SAM_EMAC_ELE_OFFSET 0x0078 /* Excessive Length Errors Register */ +#define SAM_EMAC_RJA_OFFSET 0x007c /* Receive Jabbers Register */ +#define SAM_EMAC_USF_OFFSET 0x0080 /* Undersize Frames Register */ +#define SAM_EMAC_STE_OFFSET 0x0084 /* SQE Test Errors Register */ +#define SAM_EMAC_RLE_OFFSET 0x0088 /* Received Length Field Mismatch Register */ +#define SAM_EMAC_HRB_OFFSET 0x0090 /* Hash Register Bottom [31:0] Register */ +#define SAM_EMAC_HRT_OFFSET 0x0094 /* Hash Register Top [63:32] Register */ +#define SAM_EMAC_SA1B_OFFSET 0x0098 /* Specific Address 1 Bottom Register */ +#define SAM_EMAC_SA1T_OFFSET 0x009c /* Specific Address 1 Top Register */ +#define SAM_EMAC_SA2B_OFFSET 0x00a0 /* Specific Address 2 Bottom Register */ +#define SAM_EMAC_SA2T_OFFSET 0x00a4 /* Specific Address 2 Top Register */ +#define SAM_EMAC_SA3B_OFFSET 0x00a8 /* Specific Address 3 Bottom Register */ +#define SAM_EMAC_SA3T_OFFSET 0x00ac /* Specific Address 3 Top Register */ +#define SAM_EMAC_SA4B_OFFSET 0x00b0 /* Specific Address 4 Bottom Register */ +#define SAM_EMAC_SA4T_OFFSET 0x00b4 /* Specific Address 4 Top Register */ +#define SAM_EMAC_TID_OFFSET 0x00b8 /* Type ID Checking Register */ +#define SAM_EMAC_USRIO_OFFSET 0x00c0 /* User Input/Output Register */ +#define SAM_EMAC_WOL_OFFSET 0x00c4 /* Wake on LAN Register */ + /* 0x00c8-0x00fc Reserved */ + +/* EMAC Register Addresses **********************************************************/ + +#define SAM_EMAC_NCR (SAM_EMAC_VBASE+SAM_EMAC_NCR_OFFSET) +#define SAM_EMAC_NCFGR (SAM_EMAC_VBASE+SAM_EMAC_NCFGR_OFFSET) +#define SAM_EMAC_NSR (SAM_EMAC_VBASE+SAM_EMAC_NSR_OFFSET) +#define SAM_EMAC_TSR (SAM_EMAC_VBASE+SAM_EMAC_TSR_OFFSET) +#define SAM_EMAC_RBQP (SAM_EMAC_VBASE+SAM_EMAC_RBQP_OFFSET) +#define SAM_EMAC_TBQP (SAM_EMAC_VBASE+SAM_EMAC_TBQP_OFFSET) +#define SAM_EMAC_RSR (SAM_EMAC_VBASE+SAM_EMAC_RSR_OFFSET) +#define SAM_EMAC_ISR (SAM_EMAC_VBASE+SAM_EMAC_ISR_OFFSET) +#define SAM_EMAC_IER (SAM_EMAC_VBASE+SAM_EMAC_IER_OFFSET) +#define SAM_EMAC_IDR (SAM_EMAC_VBASE+SAM_EMAC_IDR_OFFSET) +#define SAM_EMAC_IMR (SAM_EMAC_VBASE+SAM_EMAC_IMR_OFFSET) +#define SAM_EMAC_MAN (SAM_EMAC_VBASE+SAM_EMAC_MAN_OFFSET) +#define SAM_EMAC_PTR (SAM_EMAC_VBASE+SAM_EMAC_PTR_OFFSET) +#define SAM_EMAC_PFR (SAM_EMAC_VBASE+SAM_EMAC_PFR_OFFSET) +#define SAM_EMAC_FTO (SAM_EMAC_VBASE+SAM_EMAC_FTO_OFFSET) +#define SAM_EMAC_SCF (SAM_EMAC_VBASE+SAM_EMAC_SCF_OFFSET) +#define SAM_EMAC_MCF (SAM_EMAC_VBASE+SAM_EMAC_MCF_OFFSET) +#define SAM_EMAC_FRO (SAM_EMAC_VBASE+SAM_EMAC_FRO_OFFSET) +#define SAM_EMAC_FCSE (SAM_EMAC_VBASE+SAM_EMAC_FCSE_OFFSET) +#define SAM_EMAC_ALE (SAM_EMAC_VBASE+SAM_EMAC_ALE_OFFSET) +#define SAM_EMAC_DTF (SAM_EMAC_VBASE+SAM_EMAC_DTF_OFFSET) +#define SAM_EMAC_LCOL (SAM_EMAC_VBASE+SAM_EMAC_LCOL_OFFSET) +#define SAM_EMAC_ECOL (SAM_EMAC_VBASE+SAM_EMAC_ECOL_OFFSET) +#define SAM_EMAC_TUND (SAM_EMAC_VBASE+SAM_EMAC_TUND_OFFSET) +#define SAM_EMAC_CSE (SAM_EMAC_VBASE+SAM_EMAC_CSE_OFFSET) +#define SAM_EMAC_RRE (SAM_EMAC_VBASE+SAM_EMAC_RRE_OFFSET) +#define SAM_EMAC_ROV (SAM_EMAC_VBASE+SAM_EMAC_ROV_OFFSET) +#define SAM_EMAC_RSE (SAM_EMAC_VBASE+SAM_EMAC_RSE_OFFSET) +#define SAM_EMAC_ELE (SAM_EMAC_VBASE+SAM_EMAC_ELE_OFFSET) +#define SAM_EMAC_RJA (SAM_EMAC_VBASE+SAM_EMAC_RJA_OFFSET) +#define SAM_EMAC_USF (SAM_EMAC_VBASE+SAM_EMAC_USF_OFFSET) +#define SAM_EMAC_STE (SAM_EMAC_VBASE+SAM_EMAC_STE_OFFSET) +#define SAM_EMAC_RLE (SAM_EMAC_VBASE+SAM_EMAC_RLE_OFFSET) +#define SAM_EMAC_HRB (SAM_EMAC_VBASE+SAM_EMAC_HRB_OFFSET) +#define SAM_EMAC_HRT (SAM_EMAC_VBASE+SAM_EMAC_HRT_OFFSET) +#define SAM_EMAC_SA1B (SAM_EMAC_VBASE+SAM_EMAC_SA1B_OFFSET) +#define SAM_EMAC_SA1T (SAM_EMAC_VBASE+SAM_EMAC_SA1T_OFFSET) +#define SAM_EMAC_SA2B (SAM_EMAC_VBASE+SAM_EMAC_SA2B_OFFSET) +#define SAM_EMAC_SA2T (SAM_EMAC_VBASE+SAM_EMAC_SA2T_OFFSET) +#define SAM_EMAC_SA3B (SAM_EMAC_VBASE+SAM_EMAC_SA3B_OFFSET) +#define SAM_EMAC_SA3T (SAM_EMAC_VBASE+SAM_EMAC_SA3T_OFFSET) +#define SAM_EMAC_SA4B (SAM_EMAC_VBASE+SAM_EMAC_SA4B_OFFSET) +#define SAM_EMAC_SA4T (SAM_EMAC_VBASE+SAM_EMAC_SA4T_OFFSET) +#define SAM_EMAC_TID (SAM_EMAC_VBASE+SAM_EMAC_TID_OFFSET) +#define SAM_EMAC_USRIO (SAM_EMAC_VBASE+SAM_EMAC_USRIO_OFFSET) +#define SAM_EMAC_WOL (SAM_EMAC_VBASE+SAM_EMAC_WOL_OFFSET) + +/* EMAC Register Bit Definitions ****************************************************/ + +/* Network Control Register */ + +#define EMAC_NCR_LB (1 << 0) /* Bit 0: LoopBack */ +#define EMAC_NCR_LLB (1 << 1) /* Bit 1: Loopback local */ +#define EMAC_NCR_RE (1 << 2) /* Bit 2: Receive enable */ +#define EMAC_NCR_TE (1 << 3) /* Bit 3: Transmit enable */ +#define EMAC_NCR_MPE (1 << 4) /* Bit 4: Management port enable */ +#define EMAC_NCR_CLRSTAT (1 << 5) /* Bit 5: Clear statistics registers */ +#define EMAC_NCR_INCSTAT (1 << 6) /* Bit 6: Increment statistics registers */ +#define EMAC_NCR_WESTAT (1 << 7) /* Bit 7: Write enable for statistics registers */ +#define EMAC_NCR_BP (1 << 8) /* Bit 8: Back pressure */ +#define EMAC_NCR_TSTART (1 << 9) /* Bit 9: Start transmission */ +#define EMAC_NCR_THALT (1 << 10) /* Bit 10: Transmit halt */ + +/* Network Configuration Register */ + +#define EMAC_NCFGR_SPD (1 << 0) /* Bit 0: Speed */ +#define EMAC_NCFGR_FD (1 << 1) /* Bit 1: Full Duplex */ +#define EMAC_NCFGR_JFRAME (1 << 3) /* Bit 3: Jumbo Frames */ +#define EMAC_NCFGR_CAF (1 << 4) /* Bit 4: Copy All Frames */ +#define EMAC_NCFGR_NBC (1 << 5) /* Bit 5: No Broadcast */ +#define EMAC_NCFGR_MTI (1 << 6) /* Bit 6: Multicast Hash Enable */ +#define EMAC_NCFGR_UNI (1 << 7) /* Bit 7: Unicast Hash Enable */ +#define EMAC_NCFGR_BIG (1 << 8) /* Bit 8: Receive 1536 bytes frames */ +#define EMAC_NCFGR_CLK_SHIFT (10) /* Bits 10-11: MDC clock divider */ +#define EMAC_NCFGR_CLK_MASK (3 << EMAC_NCFGR_CLK_SHIFT) +# define EMAC_NCFGR_CLK_DIV8 (0 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 8 (MCK up to 20 MHz) */ +# define EMAC_NCFGR_CLK_DIV16 (1 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 16 (MCK up to 40 MHz) */ +# define EMAC_NCFGR_CLK_DIV32 (2 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */ +# define EMAC_NCFGR_CLK_DIV64 (3 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */ +#define EMAC_NCFGR_RTY (1 << 12) /* Bit 12: Retry test */ +#define EMAC_NCFGR_PAE (1 << 13) /* Bit 13: Pause Enable */ +#define EMAC_NCFGR_RBOF_SHIFT (14) /* Bits 14-15: Receive Buffer Offset */ +#define EMAC_NCFGR_RBOF_MASK (3 << EMAC_NCFGR_RBOF_SHIFT) +# define EMAC_NCFGR_RBOF_NONE (0 << EMAC_NCFGR_RBOF_SHIFT) /* No offset from RX buffer start */ +# define EMAC_NCFGR_RBOF_1 (1 << EMAC_NCFGR_RBOF_SHIFT) /* One-byte offset from RX buffer start */ +# define EMAC_NCFGR_RBOF_2 (2 << EMAC_NCFGR_RBOF_SHIFT) /* Two-byte offset from RX buffer start */ +# define EMAC_NCFGR_RBOF_3 (3 << EMAC_NCFGR_RBOF_SHIFT) /* Three-byte offset fromRX buffer start */ +#define EMAC_NCFGR_RLCE (1 << 16) /* Bit 16: Receive Length field Checking Enable */ +#define EMAC_NCFGR_DRFCS (1 << 17) /* Bit 17: Discard Receive FCS */ +#define EMAC_NCFGR_EFRHD (1 << 18) /* Bit 18: Enable RX frames in HD mode while transmitting */ +#define EMAC_NCFGR_IRXFCS (1 << 19) /* Bit 19: Ignore RX FCS */ + +/* Network Status Register */ + +#define EMAC_NSR_MDIO (1 << 1) /* Bit 1: Status of the mdio_in pin */ +#define EMAC_NSR_IDLE (1 << 2) /* Bit 2: PHY management logic is idle */ + +/* Transmit Status Register */ + +#define EMAC_TSR_UBR (1 << 0) /* Bit 0: Used Bit Read */ +#define EMAC_TSR_COL (1 << 1) /* Bit 1: Collision Occurred */ +#define EMAC_TSR_RLES (1 << 2) /* Bit 2: Retry Limit exceeded */ +#define EMAC_TSR_TGO (1 << 3) /* Bit 3: Transmit Go */ +#define EMAC_TSR_BEX (1 << 4) /* Bit 4: Buffers exhausted mid frame */ +#define EMAC_TSR_COMP (1 << 5) /* Bit 5: Transmit Complete */ +#define EMAC_TSR_UND (1 << 6) /* Bit 6: Transmit Underrun */ + +/* Receive Buffer Queue Pointer Register */ + +#define EMAC_RBQP_MASK (0xfffffffc) /* Bits 2-31: Receive buffer queue pointer address */ + +/* Transmit Buffer Queue Pointer Register */ + +#define EMAC_TBQP_MASK (0xfffffffc) /* Bits 2-31: Transmit buffer queue pointer address */ + +/* Receive Status Register */ + +#define EMAC_RSR_BNA (1 << 0) /* Bit 0: Buffer Not Available */ +#define EMAC_RSR_REC (1 << 1) /* Bit 1: Frame Received */ +#define EMAC_RSR_OVR (1 << 2) /* Bit 2: Receive Overrun */ + +/* Interrupt Status Register (ISR), Interrupt Enable Register (IER), Interrupt Disable Register (IDR) and Interrupt Mask Register (IMR) */ + +#define EMAC_INT_MFD (1 << 0) /* Bit 0: Management Frame Done */ +#define EMAC_INT_RCOMP (1 << 1) /* Bit 1: Receive Complete */ +#define EMAC_INT_RXUBR (1 << 2) /* Bit 2: Receive Used Bit Read */ +#define EMAC_INT_TXUBR (1 << 3) /* Bit 3: Transmit Used Bit Read */ +#define EMAC_INT_TUND (1 << 4) /* Bit 4: Ethernet Transmit Buffer Underrun */ +#define EMAC_INT_RLE (1 << 5) /* Bit 5: Retry Limit Exceeded */ +#define EMAC_INT_TXERR (1 << 6) /* Bit 6: Transmit Error */ +#define EMAC_INT_TCOMP (1 << 7) /* Bit 7: Transmit Complete */ +#define EMAC_INT_ROVR (1 << 10) /* Bit 10: Receive Overrun */ +#define EMAC_INT_HRESP (1 << 11) /* Bit 11: Hresp not OK */ +#define EMAC_INT_PFR (1 << 12) /* Bit 12: Pause Frame Received */ +#define EMAC_INT_PTZ (1 << 13) /* Bit 13: Pause Time Zero */ +#define EMAC_INT_WOL (1 << 14) /* Bit 14: Wake On LAN */ + +#define EMAC_INT_ALL (0x00007cff) +#define EMAC_INT_UNUSED (0xffff8300) + +/* Phy Maintenance Register */ + +#define EMAC_MAN_DATA_SHIFT (0) /* Bits 0-15: Read/write data */ +#define EMAC_MAN_DATA_MASK (0x0000ffff << EMAC_MAN_DATA_SHIFT) +# define EMAC_MAN_DATA(n) ((uint32_t)(n) << EMAC_MAN_DATA_SHIFT) +#define EMAC_MAN_CODE_SHIFT (16) /* Bits 16-17: Must be written to b10 */ +#define EMAC_MAN_CODE_MASK (3 << EMAC_MAN_CODE_SHIFT) +# define EMAC_MAN_CODE (2 << EMAC_MAN_CODE_SHIFT) +#define EMAC_MAN_REGA_SHIFT (18) /* Bits 18-22: Register Address */ +#define EMAC_MAN_REGA_MASK (31 << EMAC_MAN_REGA_SHIFT) +# define EMAC_MAN_REGA(n) ((uint32_t)(n) << EMAC_MAN_REGA_SHIFT) +#define EMAC_MAN_PHYA_SHIFT (23) /* Bits 23-27: PHY Address */ +#define EMAC_MAN_PHYA_MASK (31 << EMAC_MAN_PHYA_SHIFT) +# define EMAC_MAN_PHYA(n) ((uint32_t)(n) << EMAC_MAN_PHYA_SHIFT) +#define EMAC_MAN_RW_SHIFT (28) /* Bits 28-29: Read-write */ +#define EMAC_MAN_RW_MASK (3 << EMAC_MAN_RW_SHIFT) +# define EMAC_MAN_READ (2 << EMAC_MAN_RW_SHIFT) +# define EMAC_MAN_WRITE (1 << EMAC_MAN_RW_SHIFT) +#define EMAC_MAN_SOF_SHIFT (30) /* Bits 30-31: Start of frame */ +#define EMAC_MAN_SOF_MASK (3 << EMAC_MAN_SOF_SHIFT) +# define EMAC_MAN_SOF (1 << EMAC_MAN_SOF_SHIFT) /* Must be written b01 */ + +/* Pause Time Register */ + +#define EMAC_PTR_MASK (0x0000ffff) /* Bits 0-15: Pause Time */ + +/* Pause Frames Received Register */ + +#define EMAC_PFR_MASK (0x0000ffff) /* Bits 0-15: Pause Frames received OK */ + +/* Frames Transmitted Ok Register */ + +#define EMAC_FTO_MASK (0x00ffffff) /* Bits 0-23: Frames Transmitted OK */ + +/* Single Collision Frames Register */ + +#define EMAC_SCF_MASK (0x0000ffff) /* Bits 0-15: Single Collision Frames */ + +/* Multiple Collision Frames Register */ + +#define EMAC_MCF_MASK (0x0000ffff) /* Bits 0-15: Multicollision Frames */ + +/* Frames Received Ok Register */ + +#define EMAC_FRO_MASK (0x00ffffff) /* Bits 0-23: Frames received OK */ + +/* Frame Check Sequence Errors Register */ + +#define EMAC_FCSE_MASK (0x000000ff) /* Bits 0-7:Frame Check Sequence Errors */ + +/* Alignment Errors Register */ + +#define EMAC_ALE_MASK (0x000000ff) /* Bits 0-7:Alignment Errors */ + +/* Deferred Transmission Frames Register */ + +#define EMAC_DTF_MASK (0x0000ffff) /* Bits 0-15: Deferred Transmission Frames */ + +/* Late Collisions Register */ + +#define EMAC_LCOL_MASK (0x000000ff) /* Bits 0-7: Late Collisions */ + +/* Excessive Collisions Register */ + +#define EMAC_ECOL_MASK (0x000000ff) /* Bits 0-7: Excessive Collisions Register */ + +/* Transmit Underrun Errors Register */ + +#define EMAC_TUND_MASK (0x000000ff) /* Bits 0-7: Transmit Underruns */ + +/* Carrier Sense Errors Register */ + +#define EMAC_CSE_MASK (0x000000ff) /* Bits 0-7: Carrier Sense Errors */ + +/* Receive Resource Errors Register */ + +#define EMAC_RRE_MASK (0x0000ffff) /* Bits 0-15: Receive Resource Errors */ + +/* Receive Overrun Errors Register */ + +#define EMAC_ROV_MASK (0x000000ff) /* Bits 0-7: Receive Overrun */ + +/* Receive Symbol Errors Register */ + +#define EMAC_RSE_MASK (0x000000ff) /* Bits 0-7: Receive Symbol Errors */ + +/* Excessive Length Errors Register */ + +#define EMAC_ELE_MASK (0x000000ff) /* Bits 0-7: Excessive Length Errors */ + +/* Receive Jabbers Register */ + +#define EMAC_RJA_MASK (0x000000ff) /* Bits 0-7: Receive Jabbers */ + +/* Undersize Frames Register */ + +#define EMAC_USF_MASK (0x000000ff) /* Bits 0-7: Undersize frames */ + +/* SQE Test Errors Register */ + +#define EMAC_STE_MASK (0x000000ff) /* Bits 0-7: SQE test errors */ + +/* Received Length Field Mismatch Register */ + +#define EMAC_RLE_MASK (0x000000ff) /* Bits 0-7: Receive Length Field Mismatch */ + +/* Hash Register Bottom [31:0] Register (LS 32-bit hash address) */ +/* Hash Register Top [63:32] Register (MS 32-bit hash address) */ + +/* Specific Address 1 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Top [47:32] Register */ + +#define EMAC_SA1T_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 2 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 2 Top [47:32] Register */ + +#define EMAC_SA2T_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 3 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 3 Top [47:32] Register */ + +#define EMAC_SA3T_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 4 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 4 Top [47:32] Register */ + +#define EMAC_SA4T_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Type ID Checking Register */ + +#define EMAC_TID_MASK (0x0000ffff) /* Bits 0-15: For comparisons with received frames TypeID/Length field. */ + +/* User Input/Output Register */ + +#define EMAC_USRIO_RMII (1 << 0) /* Bit 0: Reduce MII */ +#define EMAC_USRIO_CLKEN (1 << 1) /* Bit 1: Clock Enable */ + +/* Wake on LAN Register */ + +#define EMAC_WOL_IP_SHIFT (0) /* Bits 0-15: ARP request IP address */ +#define EMAC_WOL_IP_MASK (0x0000ffff << EMAC_WOL_IP_SHIFT) +#define EMAC_WOL_MAG (1 << 16) /* Bit 16: Magic packet event enable */ +#define EMAC_WOL_ARP (1 << 17) /* Bit 17: ARP request event enable */ +#define EMAC_WOL_SA1 (1 << 18) /* Bit 18: Specific address register 1 event enable */ +#define EMAC_WOL_MTI (1 << 19) /* Bit 19: Multicast hash event enable */ + +/* Descriptors **********************************************************************/ + +/* Receive buffer descriptor: Address word */ + +#define EMACRXD_ADDR_OWNER (1 << 0) /* Bit 0: 1=Software owns; 0=EMAC owns */ +#define EMACRXD_ADDR_WRAP (1 << 1) /* Bit 1: Last descriptor in list */ +#define EMACRXD_ADDR_MASK (0xfffffffc) /* Bits 2-31: Aligned buffer address */ + +/* Receive buffer descriptor: Control word */ + +#define EMACRXD_STA_FRLEN_SHIFT (0) /* Bits 0-11: Length of frame */ +#define EMACRXD_STA_FRLEN_MASK (0x000007ff << EMACRXD_STA_FRLEN_SHIFT) +#define EMACRXD_STA_BOFFS_SHIFT (12) /* Bits 12-13: Receive buffer offset */ +#define EMACRXD_STA_BOFFS_MASK (3 << EMACRXD_STA_BOFFS_SHIFT) +#define EMACRXD_STA_SOF (1 << 14) /* Bit 14: Start of frame */ +#define EMACRXD_STA_EOF (1 << 15) /* Bit 15: End of frame */ +#define EMACRXD_STA_CFI (1 << 16) /* Bit 16: Concatenation format indicator (CFI) bit */ +#define EMACRXD_STA_VLPRIO_SHIFT (17) /* Bits 17-19: VLAN priority */ +#define EMACRXD_STA_VLPRIO_MASK (7 << EMACRXD_STA_VLANPRIO_SHIFT) +#define EMACRXD_STA_PRIODET (1 << 20) /* Bit 20: Priority tag detected */ +#define EMACRXD_STA_VLANTAG (1 << 21) /* Bit 21: VLAN tag detected */ +#define EMACRXD_STA_TYPEID (1 << 22) /* Bit 22: Type ID match */ +#define EMACRXD_STA_ADDR4 (1 << 23) /* Bit 23: Specific address register 4 match */ +#define EMACRXD_STA_ADDR3 (1 << 24) /* Bit 24: Specific address register 3 match */ +#define EMACRXD_STA_ADDR2 (1 << 25) /* Bit 25: Specific address register 2 match */ +#define EMACRXD_STA_ADDR1 (1 << 26) /* Bit 26: Specific address register 1 match */ + /* Bit 27: Reserved */ +#define EMACRXD_STA_EXTADDR (1 << 28) /* Bit 28: External address match */ +#define EMACRXD_STA_UCAST (1 << 29) /* Bit 29: Unicast hash match */ +#define EMACRXD_STA_MCAST (1 << 30) /* Bit 30: Multicast hash match */ +#define EMACRXD_STA_BCAST (1 << 31) /* Bit 31: Global all ones broadcast address detected */ + +/* Transmit buffer descriptor: Address word (un-aligned, 32-bit address */ + +/* Transmit buffer descriptor: Control word */ + +#define EMACTXD_STA_BUFLEN_SHIFT (0) /* Bits 0-10: Length of buffer */ +#define EMACTXD_STA_BUFLEN_MASK (0x000003ff << EMACTXD_STA_BUFLEN_SHIFT) + /* Bits 11-14: Reserved */ +#define EMACTXD_STA_LAST (1 << 15) /* Bit 15: Last buffer in the current frame */ +#define EMACTXD_STA_NOCRC (1 << 16) /* Bit 16: No CRC */ + /* Bits 17-26: Reserved */ +#define EMACTXD_STA_NOBUFFER (1 << 27) /* Bit 27: Buffers exhausted in mid frame */ +#define EMACTXD_STA_TXUR (1 << 28) /* Bit 28: Transmit underrun */ +#define EMACTXD_STA_TXERR (1 << 29) /* Bit 29: Retry limit exceeded, transmit error detected */ +#define EMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */ +#define EMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the EMAC to read from buffer */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Receive buffer descriptor */ + +struct emac_rxdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* RX status and controls */ +}; + +/* Transmit buffer descriptor */ + +struct emac_txdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* TX status and controls */ +}; + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACA_H */ diff --git a/arch/arm/src/sama5/chip/sam_emacb.h b/arch/arm/src/sama5/chip/sam_emacb.h new file mode 100644 index 0000000000000000000000000000000000000000..6b11086d3102644fb96a4fded8adb700083b79bf --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_emacb.h @@ -0,0 +1,792 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_emacb.h + * This is the form of the EMAC interface used the the SAMA5D4 (and also the SAM43). + * This is referred as GMAC in the documentation even though it does not support + * Gibabit Ethernet. + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACB_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* EMAC Register Offsets ************************************************************/ + +#define SAM_EMAC_NCR_OFFSET 0x0000 /* Network Control Register */ +#define SAM_EMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */ +#define SAM_EMAC_NSR_OFFSET 0x0008 /* Network Status Register */ +#define SAM_EMAC_UR_OFFSET 0x000c /* User Register */ +#define SAM_EMAC_DCFGR_OFFSET 0x0010 /* DMA Configuration Register */ +#define SAM_EMAC_TSR_OFFSET 0x0014 /* Transmit Status Register */ +#define SAM_EMAC_RBQB_OFFSET 0x0018 /* Receive Buffer Queue Base Address */ +#define SAM_EMAC_TBQB_OFFSET 0x001c /* Transmit Buffer Queue Base Address */ +#define SAM_EMAC_RSR_OFFSET 0x0020 /* Receive Status Register */ +#define SAM_EMAC_ISR_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_EMAC_IER_OFFSET 0x0028 /* Interrupt Enable Register */ +#define SAM_EMAC_IDR_OFFSET 0x002c /* Interrupt Disable Register */ +#define SAM_EMAC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_EMAC_MAN_OFFSET 0x0034 /* PHY Maintenance Register */ +#define SAM_EMAC_RPQ_OFFSET 0x0038 /* Received Pause Quantum Register */ +#define SAM_EMAC_TPQ_OFFSET 0x003c /* Transmit Pause Quantum Register */ + /* 0x0040-0x007c: Reserved */ +#define SAM_EMAC_HRB_OFFSET 0x0080 /* Hash Register Bottom [31:0] Register */ +#define SAM_EMAC_HRT_OFFSET 0x0084 /* Hash Register Top [63:32] Register */ +#define SAM_EMAC_SAB1_OFFSET 0x0088 /* Specific Address 1 Bottom Register */ +#define SAM_EMAC_SAT1_OFFSET 0x008c /* Specific Address 1 Top Register */ +#define SAM_EMAC_SAB2_OFFSET 0x0090 /* Specific Address 2 Bottom Register */ +#define SAM_EMAC_SAT2_OFFSET 0x0094 /* Specific Address 2 Top Register */ +#define SAM_EMAC_SAB3_OFFSET 0x0098 /* Specific Address 3 Bottom Register */ +#define SAM_EMAC_SAT3_OFFSET 0x009c /* Specific Address 3 Top Register */ +#define SAM_EMAC_SAB4_OFFSET 0x00a0 /* Specific Address 4 Bottom Register */ +#define SAM_EMAC_SAT4_OFFSET 0x00a4 /* Specific Address 4 Top Register */ +#define SAM_EMAC_TIDM1_OFFSET 0x00a8 /* Type ID Match 1 Register */ +#define SAM_EMAC_TIDM2_OFFSET 0x00ac /* Type ID Match 2 Register */ +#define SAM_EMAC_TIDM3_OFFSET 0x00b0 /* Type ID Match 3 Register */ +#define SAM_EMAC_TIDM4_OFFSET 0x00b4 /* Type ID Match 4 Register */ +#define SAM_EMAC_WOL_OFFSET 0x00b8 /* Wake on LAN Register */ +#define SAM_EMAC_IPGS_OFFSET 0x00bc /* IPG Stretch Register */ +#define SAM_EMAC_SVLAN_OFFSET 0x00c0 /* Stacked VLAN Register */ +#define SAM_EMAC_TPFCP_OFFSET 0x00c4 /* Transmit PFC Pause Register */ +#define SAM_EMAC_SAMB1_OFFSET 0x00c8 /* Specific Address 1 Mask Bottom [31:0] Register */ +#define SAM_EMAC_SAMT1_OFFSET 0x00cc /* Specific Address 1 Mask Top [47:32] Register */ + /* 0x00fc: Reserved */ +/* Statistics registers */ + +#define SAM_EMAC_OTLO_OFFSET 0x0100 /* Octets Transmitted [31:0] Register */ +#define SAM_EMAC_OTHI_OFFSET 0x0104 /* Octets Transmitted [47:32] Register */ +#define SAM_EMAC_FT_OFFSET 0x0108 /* Frames Transmitted Register */ +#define SAM_EMAC_BCFT_OFFSET 0x010c /* Broadcast Frames Transmitted Register */ +#define SAM_EMAC_MFT_OFFSET 0x0110 /* Multicast Frames Transmitted Register */ +#define SAM_EMAC_PFT_OFFSET 0x0114 /* Pause Frames Transmitted Register */ +#define SAM_EMAC_BFT64_OFFSET 0x0118 /* 64 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT127_OFFSET 0x011c /* 65 to 127 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT255_OFFSET 0x0120 /* 128 to 255 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT511_OFFSET 0x0124 /* 256 to 511 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1023_OFFSET 0x0128 /* 512 to 1023 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1518_OFFSET 0x012c /* 1024 to 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_GTBFT1518_OFFSET 0x0130 /* Greater Than 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_TUR_OFFSET 0x0134 /* Transmit Under Runs Register */ +#define SAM_EMAC_SCF_OFFSET 0x0138 /* Single Collision Frames Register */ +#define SAM_EMAC_MCF_OFFSET 0x013c /* Multiple Collision Frames Register */ +#define SAM_EMAC_EC_OFFSET 0x0140 /* Excessive Collisions Register */ +#define SAM_EMAC_LC_OFFSET 0x0144 /* Late Collisions Register */ +#define SAM_EMAC_DTF_OFFSET 0x0148 /* Deferred Transmission Frames Register */ +#define SAM_EMAC_CSE_OFFSET 0x014c /* Carrier Sense Errors Register */ +#define SAM_EMAC_ORLO_OFFSET 0x0150 /* Octets Received [31:0] Received */ +#define SAM_EMAC_ORHI_OFFSET 0x0154 /* Octets Received [47:32] Received */ +#define SAM_EMAC_FR_OFFSET 0x0158 /* Frames Received Register */ +#define SAM_EMAC_BCFR_OFFSET 0x015C /* Broadcast Frames Received Register */ +#define SAM_EMAC_MFR_OFFSET 0x0160 /* Multicast Frames Received Register */ +#define SAM_EMAC_PFR_OFFSET 0x0164 /* Pause Frames Received Register */ +#define SAM_EMAC_BFR64_OFFSET 0x0168 /* 64 Byte Frames Received Register */ +#define SAM_EMAC_TBFR127_OFFSET 0x016c /* 65 to 127 Byte Frames Received Register */ +#define SAM_EMAC_TBFR255_OFFSET 0x0170 /* 128 to 255 Byte Frames Received Register */ +#define SAM_EMAC_TBFR511_OFFSET 0x0174 /* 256 to 511Byte Frames Received Register */ +#define SAM_EMAC_TBFR1023_OFFSET 0x0178 /* 512 to 1023 Byte Frames Received Register */ +#define SAM_EMAC_TBFR1518_OFFSET 0x017c /* 1024 to 1518 Byte Frames Received Register */ +#define SAM_EMAC_TMXBFR_OFFSET 0x0180 /* 1519 to Maximum Byte Frames Received Register */ +#define SAM_EMAC_UFR_OFFSET 0x0184 /* Undersize Frames Received Register */ +#define SAM_EMAC_OFR_OFFSET 0x0188 /* Oversize Frames Received Register */ +#define SAM_EMAC_JR_OFFSET 0x018c /* Jabbers Received Register */ +#define SAM_EMAC_FCSE_OFFSET 0x0190 /* Frame Check Sequence Errors Register */ +#define SAM_EMAC_LFFE_OFFSET 0x0194 /* Length Field Frame Errors Register */ +#define SAM_EMAC_RSE_OFFSET 0x0198 /* Receive Symbol Errors Register */ +#define SAM_EMAC_AE_OFFSET 0x019c /* Alignment Errors Register */ +#define SAM_EMAC_RRE_OFFSET 0x01a0 /* Receive Resource Errors Register */ +#define SAM_EMAC_ROE_OFFSET 0x01a4 /* Receive Overrun Register */ +#define SAM_EMAC_IHCE_OFFSET 0x01a8 /* IP Header Checksum Errors Register */ +#define SAM_EMAC_TCE_OFFSET 0x01ac /* TCP Checksum Errors Register */ +#define SAM_EMAC_UCE_OFFSET 0x01b0 /* UDP Checksum Errors Register */ + +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC_TSSS_OFFSET 0x01c8 /* 1588 Timer Sync Strobe Seconds Register */ +#define SAM_EMAC_TSSN_OFFSET 0x01cc /* 1588 Timer Sync Strobe Nanoseconds Register */ +#define SAM_EMAC_TS_OFFSET 0x01d0 /* 1588 Timer Seconds Register */ +#define SAM_EMAC_TN_OFFSET 0x01d4 /* 1588 Timer Nanoseconds Register */ +#define SAM_EMAC_TA_OFFSET 0x01d8 /* 1588 Timer Adjust Register */ +#define SAM_EMAC_TI_OFFSET 0x01dc /* 1588 Timer Increment Register */ +#define SAM_EMAC_EFTS_OFFSET 0x01e0 /* PTP Event Frame Transmitted Seconds */ +#define SAM_EMAC_EFTN_OFFSET 0x01e4 /* PTP Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_EFRS_OFFSET 0x01e8 /* PTP Event Frame Received Seconds */ +#define SAM_EMAC_EFRN_OFFSET 0x01ec /* PTP Event Frame Received Nanoseconds */ +#define SAM_EMAC_PEFTS_OFFSET 0x01f0 /* PTP Peer Event Frame Transmitted Seconds */ +#define SAM_EMAC_PEFTN_OFFSET 0x01f4 /* PTP Peer Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_PEFRS_OFFSET 0x01f8 /* PTP Peer Event Frame Received Seconds */ +#define SAM_EMAC_PEFRN_OFFSET 0x01fc /* PTP Peer Event Frame Received Nanoseconds */ + /* 0x0280-0x0298: Reserved */ + +/* EMAC Register Addresses **********************************************************/ + +#ifdef CONFIG_SAMA5_EMAC0 +/* EMAC0 base addresses */ + +# define SAM_EMAC0_NCR (SAM_EMAC0_BASE+SAM_EMAC_NCR_OFFSET) +# define SAM_EMAC0_NCFGR (SAM_EMAC0_BASE+SAM_EMAC_NCFGR_OFFSET) +# define SAM_EMAC0_NSR (SAM_EMAC0_BASE+SAM_EMAC_NSR_OFFSET) +# define SAM_EMAC0_TSR (SAM_EMAC0_BASE+SAM_EMAC_TSR_OFFSET) +# define SAM_EMAC0_UR (SAM_EMAC0_BASE+SAM_EMAC_UR_OFFSET) +# define SAM_EMAC0_DCFGR (SAM_EMAC0_BASE+SAM_EMAC_DCFGR_OFFSET) +# define SAM_EMAC0_RBQB (SAM_EMAC0_BASE+SAM_EMAC_RBQB_OFFSET) +# define SAM_EMAC0_TBQB (SAM_EMAC0_BASE+SAM_EMAC_TBQB_OFFSET) +# define SAM_EMAC0_RSR (SAM_EMAC0_BASE+SAM_EMAC_RSR_OFFSET) +# define SAM_EMAC0_ISR (SAM_EMAC0_BASE+SAM_EMAC_ISR_OFFSET) +# define SAM_EMAC0_IER (SAM_EMAC0_BASE+SAM_EMAC_IER_OFFSET) +# define SAM_EMAC0_IDR (SAM_EMAC0_BASE+SAM_EMAC_IDR_OFFSET) +# define SAM_EMAC0_IMR (SAM_EMAC0_BASE+SAM_EMAC_IMR_OFFSET) +# define SAM_EMAC0_MAN (SAM_EMAC0_BASE+SAM_EMAC_MAN_OFFSET) +# define SAM_EMAC0_RPQ (SAM_EMAC0_BASE+SAM_EMAC_RPQ_OFFSET) +# define SAM_EMAC0_TPQ (SAM_EMAC0_BASE+SAM_EMAC_TPQ_OFFSET) +# define SAM_EMAC0_HRB (SAM_EMAC0_BASE+SAM_EMAC_HRB_OFFSET) +# define SAM_EMAC0_HRT (SAM_EMAC0_BASE+SAM_EMAC_HRT_OFFSET) +# define SAM_EMAC0_SAB1 (SAM_EMAC0_BASE+SAM_EMAC_SAB1_OFFSET) +# define SAM_EMAC0_SAT1 (SAM_EMAC0_BASE+SAM_EMAC_SAT1_OFFSET) +# define SAM_EMAC0_SAB2 (SAM_EMAC0_BASE+SAM_EMAC_SAB2_OFFSET) +# define SAM_EMAC0_SAT2 (SAM_EMAC0_BASE+SAM_EMAC_SAT2_OFFSET) +# define SAM_EMAC0_SAB3 (SAM_EMAC0_BASE+SAM_EMAC_SAB3_OFFSET) +# define SAM_EMAC0_SAT3 (SAM_EMAC0_BASE+SAM_EMAC_SAT3_OFFSET) +# define SAM_EMAC0_SAB4 (SAM_EMAC0_BASE+SAM_EMAC_SAB4_OFFSET) +# define SAM_EMAC0_SAT4 (SAM_EMAC0_BASE+SAM_EMAC_SAT4_OFFSET) +# define SAM_EMAC0_TIDM1 (SAM_EMAC0_BASE+SAM_EMAC_TIDM1_OFFSET) +# define SAM_EMAC0_TIDM2 (SAM_EMAC0_BASE+SAM_EMAC_TIDM2_OFFSET) +# define SAM_EMAC0_TIDM3 (SAM_EMAC0_BASE+SAM_EMAC_TIDM3_OFFSET) +# define SAM_EMAC0_TIDM4 (SAM_EMAC0_BASE+SAM_EMAC_TIDM4_OFFSET) +# define SAM_EMAC0_IPGS (SAM_EMAC0_BASE+SAM_EMAC_IPGS_OFFSET) +# define SAM_EMAC0_SVLAN (SAM_EMAC0_BASE+SAM_EMAC_SVLAN_OFFSET) +# define SAM_EMAC0_TPFCP (SAM_EMAC0_BASE+SAM_EMAC_TPFCP_OFFSET) +# define SAM_EMAC0_SAMB1 (SAM_EMAC0_BASE+SAM_EMAC_SAMB1_OFFSET) +# define SAM_EMAC0_SAMT1 (SAM_EMAC0_BASE+SAM_EMAC_SAMT1_OFFSET) + +/* Statistics registers */ + +# define SAM_EMAC0_OTLO (SAM_EMAC0_BASE+SAM_EMAC_OTLO_OFFSET) +# define SAM_EMAC0_OTHI (SAM_EMAC0_BASE+SAM_EMAC_OTHI_OFFSET) +# define SAM_EMAC0_FT (SAM_EMAC0_BASE+SAM_EMAC_FT_OFFSET) +# define SAM_EMAC0_BCFT (SAM_EMAC0_BASE+SAM_EMAC_BCFT_OFFSET) +# define SAM_EMAC0_MFT (SAM_EMAC0_BASE+SAM_EMAC_MFT_OFFSET) +# define SAM_EMAC0_PFT (SAM_EMAC0_BASE+SAM_EMAC_PFT_OFFSET) +# define SAM_EMAC0_BFT64 (SAM_EMAC0_BASE+SAM_EMAC_BFT64_OFFSET) +# define SAM_EMAC0_TBFT127 (SAM_EMAC0_BASE+SAM_EMAC_TBFT127_OFFSET) +# define SAM_EMAC0_TBFT255 (SAM_EMAC0_BASE+SAM_EMAC_TBFT255_OFFSET) +# define SAM_EMAC0_TBFT511 (SAM_EMAC0_BASE+SAM_EMAC_TBFT511_OFFSET) +# define SAM_EMAC0_TBFT1023 (SAM_EMAC0_BASE+SAM_EMAC_TBFT1023_OFFSET) +# define SAM_EMAC0_TBFT1518 (SAM_EMAC0_BASE+SAM_EMAC_TBFT1518_OFFSET) +# define SAM_EMAC0_GTBFT1518 (SAM_EMAC0_BASE+SAM_EMAC_GTBFT1518_OFFSET) +# define SAM_EMAC0_TUR (SAM_EMAC0_BASE+SAM_EMAC_TUR_OFFSET) +# define SAM_EMAC0_SCF (SAM_EMAC0_BASE+SAM_EMAC_SCF_OFFSET) +# define SAM_EMAC0_MCF (SAM_EMAC0_BASE+SAM_EMAC_MCF_OFFSET) +# define SAM_EMAC0_EC (SAM_EMAC0_BASE+SAM_EMAC_EC_OFFSET) +# define SAM_EMAC0_LC (SAM_EMAC0_BASE+SAM_EMAC_LC_OFFSET) +# define SAM_EMAC0_DTF (SAM_EMAC0_BASE+SAM_EMAC_DTF_OFFSET) +# define SAM_EMAC0_CSE (SAM_EMAC0_BASE+SAM_EMAC_CSE_OFFSET) +# define SAM_EMAC0_ORLO (SAM_EMAC0_BASE+SAM_EMAC_ORLO_OFFSET) +# define SAM_EMAC0_ORHI (SAM_EMAC0_BASE+SAM_EMAC_ORHI_OFFSET) +# define SAM_EMAC0_FR (SAM_EMAC0_BASE+SAM_EMAC_FR_OFFSET) +# define SAM_EMAC0_BCFR (SAM_EMAC0_BASE+SAM_EMAC_BCFR_OFFSET) +# define SAM_EMAC0_MFR (SAM_EMAC0_BASE+SAM_EMAC_MFR_OFFSET) +# define SAM_EMAC0_PFR (SAM_EMAC0_BASE+SAM_EMAC_PFR_OFFSET) +# define SAM_EMAC0_BFR64 (SAM_EMAC0_BASE+SAM_EMAC_BFR64_OFFSET) +# define SAM_EMAC0_TBFR127 (SAM_EMAC0_BASE+SAM_EMAC_TBFR127_OFFSET) +# define SAM_EMAC0_TBFR255 (SAM_EMAC0_BASE+SAM_EMAC_TBFR255_OFFSET) +# define SAM_EMAC0_TBFR511 (SAM_EMAC0_BASE+SAM_EMAC_TBFR511_OFFSET) +# define SAM_EMAC0_TBFR1023 (SAM_EMAC0_BASE+SAM_EMAC_TBFR1023_OFFSET) +# define SAM_EMAC0_TBFR1518 (SAM_EMAC0_BASE+SAM_EMAC_TBFR1518_OFFSET) +# define SAM_EMAC0_TMXBFR (SAM_EMAC0_BASE+SAM_EMAC_TMXBFR_OFFSET) +# define SAM_EMAC0_UFR (SAM_EMAC0_BASE+SAM_EMAC_UFR_OFFSET) +# define SAM_EMAC0_OFR (SAM_EMAC0_BASE+SAM_EMAC_OFR_OFFSET) +# define SAM_EMAC0_JR (SAM_EMAC0_BASE+SAM_EMAC_JR_OFFSET) +# define SAM_EMAC0_FCSE (SAM_EMAC0_BASE+SAM_EMAC_FCSE_OFFSET) +# define SAM_EMAC0_LFFE (SAM_EMAC0_BASE+SAM_EMAC_LFFE_OFFSET) +# define SAM_EMAC0_RSE (SAM_EMAC0_BASE+SAM_EMAC_RSE_OFFSET) +# define SAM_EMAC0_AE (SAM_EMAC0_BASE+SAM_EMAC_AE_OFFSET) +# define SAM_EMAC0_RRE (SAM_EMAC0_BASE+SAM_EMAC_RRE_OFFSET) +# define SAM_EMAC0_ROE (SAM_EMAC0_BASE+SAM_EMAC_ROE_OFFSET) +# define SAM_EMAC0_IHCE (SAM_EMAC0_BASE+SAM_EMAC_IHCE_OFFSET) +# define SAM_EMAC0_TCE (SAM_EMAC0_BASE+SAM_EMAC_TCE_OFFSET) +# define SAM_EMAC0_UCE (SAM_EMAC0_BASE+SAM_EMAC_UCE_OFFSET) + +/* PTP/1588 Timer Registers */ + +# define SAM_EMAC0_TSSS (SAM_EMAC0_BASE+SAM_EMAC_TSSS_OFFSET) +# define SAM_EMAC0_TSSN (SAM_EMAC0_BASE+SAM_EMAC_TSSN_OFFSET) +# define SAM_EMAC0_TS (SAM_EMAC0_BASE+SAM_EMAC_TS_OFFSET) +# define SAM_EMAC0_TN (SAM_EMAC0_BASE+SAM_EMAC_TN_OFFSET) +# define SAM_EMAC0_TA (SAM_EMAC0_BASE+SAM_EMAC_TA_OFFSET) +# define SAM_EMAC0_TI (SAM_EMAC0_BASE+SAM_EMAC_TI_OFFSET) +# define SAM_EMAC0_EFTS (SAM_EMAC0_BASE+SAM_EMAC_EFTS_OFFSET) +# define SAM_EMAC0_EFTN (SAM_EMAC0_BASE+SAM_EMAC_EFTN_OFFSET) +# define SAM_EMAC0_EFRS (SAM_EMAC0_BASE+SAM_EMAC_EFRS_OFFSET) +# define SAM_EMAC0_EFRN (SAM_EMAC0_BASE+SAM_EMAC_EFRN_OFFSET) +# define SAM_EMAC0_PEFTS (SAM_EMAC0_BASE+SAM_EMAC_PEFTS_OFFSET) +# define SAM_EMAC0_PEFTN (SAM_EMAC0_BASE+SAM_EMAC_PEFTN_OFFSET) +# define SAM_EMAC0_PEFRS (SAM_EMAC0_BASE+SAM_EMAC_PEFRS_OFFSET) +# define SAM_EMAC0_PEFRN (SAM_EMAC0_BASE+SAM_EMAC_PEFRN_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_EMAC1 +/* EMAC1 base addresses */ + +# define SAM_EMAC1_NCR (SAM_EMAC1_BASE+SAM_EMAC_NCR_OFFSET) +# define SAM_EMAC1_NCFGR (SAM_EMAC1_BASE+SAM_EMAC_NCFGR_OFFSET) +# define SAM_EMAC1_NSR (SAM_EMAC1_BASE+SAM_EMAC_NSR_OFFSET) +# define SAM_EMAC1_TSR (SAM_EMAC1_BASE+SAM_EMAC_TSR_OFFSET) +# define SAM_EMAC1_UR (SAM_EMAC1_BASE+SAM_EMAC_UR_OFFSET) +# define SAM_EMAC1_DCFGR (SAM_EMAC1_BASE+SAM_EMAC_DCFGR_OFFSET) +# define SAM_EMAC1_RBQB (SAM_EMAC1_BASE+SAM_EMAC_RBQB_OFFSET) +# define SAM_EMAC1_TBQB (SAM_EMAC1_BASE+SAM_EMAC_TBQB_OFFSET) +# define SAM_EMAC1_RSR (SAM_EMAC1_BASE+SAM_EMAC_RSR_OFFSET) +# define SAM_EMAC1_ISR (SAM_EMAC1_BASE+SAM_EMAC_ISR_OFFSET) +# define SAM_EMAC1_IER (SAM_EMAC1_BASE+SAM_EMAC_IER_OFFSET) +# define SAM_EMAC1_IDR (SAM_EMAC1_BASE+SAM_EMAC_IDR_OFFSET) +# define SAM_EMAC1_IMR (SAM_EMAC1_BASE+SAM_EMAC_IMR_OFFSET) +# define SAM_EMAC1_MAN (SAM_EMAC1_BASE+SAM_EMAC_MAN_OFFSET) +# define SAM_EMAC1_RPQ (SAM_EMAC1_BASE+SAM_EMAC_RPQ_OFFSET) +# define SAM_EMAC1_TPQ (SAM_EMAC1_BASE+SAM_EMAC_TPQ_OFFSET) +# define SAM_EMAC1_HRB (SAM_EMAC1_BASE+SAM_EMAC_HRB_OFFSET) +# define SAM_EMAC1_HRT (SAM_EMAC1_BASE+SAM_EMAC_HRT_OFFSET) +# define SAM_EMAC1_SAB1 (SAM_EMAC1_BASE+SAM_EMAC_SAB1_OFFSET) +# define SAM_EMAC1_SAT1 (SAM_EMAC1_BASE+SAM_EMAC_SAT1_OFFSET) +# define SAM_EMAC1_SAB2 (SAM_EMAC1_BASE+SAM_EMAC_SAB2_OFFSET) +# define SAM_EMAC1_SAT2 (SAM_EMAC1_BASE+SAM_EMAC_SAT2_OFFSET) +# define SAM_EMAC1_SAB3 (SAM_EMAC1_BASE+SAM_EMAC_SAB3_OFFSET) +# define SAM_EMAC1_SAT3 (SAM_EMAC1_BASE+SAM_EMAC_SAT3_OFFSET) +# define SAM_EMAC1_SAB4 (SAM_EMAC1_BASE+SAM_EMAC_SAB4_OFFSET) +# define SAM_EMAC1_SAT4 (SAM_EMAC1_BASE+SAM_EMAC_SAT4_OFFSET) +# define SAM_EMAC1_TIDM1 (SAM_EMAC1_BASE+SAM_EMAC_TIDM1_OFFSET) +# define SAM_EMAC1_TIDM2 (SAM_EMAC1_BASE+SAM_EMAC_TIDM2_OFFSET) +# define SAM_EMAC1_TIDM3 (SAM_EMAC1_BASE+SAM_EMAC_TIDM3_OFFSET) +# define SAM_EMAC1_TIDM4 (SAM_EMAC1_BASE+SAM_EMAC_TIDM4_OFFSET) +# define SAM_EMAC1_IPGS (SAM_EMAC1_BASE+SAM_EMAC_IPGS_OFFSET) +# define SAM_EMAC1_SVLAN (SAM_EMAC1_BASE+SAM_EMAC_SVLAN_OFFSET) +# define SAM_EMAC1_TPFCP (SAM_EMAC1_BASE+SAM_EMAC_TPFCP_OFFSET) +# define SAM_EMAC1_SAMB1 (SAM_EMAC1_BASE+SAM_EMAC_SAMB1_OFFSET) +# define SAM_EMAC1_SAMT1 (SAM_EMAC1_BASE+SAM_EMAC_SAMT1_OFFSET) + +/* Statistics registers */ + +# define SAM_EMAC1_OTLO (SAM_EMAC1_BASE+SAM_EMAC_OTLO_OFFSET) +# define SAM_EMAC1_OTHI (SAM_EMAC1_BASE+SAM_EMAC_OTHI_OFFSET) +# define SAM_EMAC1_FT (SAM_EMAC1_BASE+SAM_EMAC_FT_OFFSET) +# define SAM_EMAC1_BCFT (SAM_EMAC1_BASE+SAM_EMAC_BCFT_OFFSET) +# define SAM_EMAC1_MFT (SAM_EMAC1_BASE+SAM_EMAC_MFT_OFFSET) +# define SAM_EMAC1_PFT (SAM_EMAC1_BASE+SAM_EMAC_PFT_OFFSET) +# define SAM_EMAC1_BFT64 (SAM_EMAC1_BASE+SAM_EMAC_BFT64_OFFSET) +# define SAM_EMAC1_TBFT127 (SAM_EMAC1_BASE+SAM_EMAC_TBFT127_OFFSET) +# define SAM_EMAC1_TBFT255 (SAM_EMAC1_BASE+SAM_EMAC_TBFT255_OFFSET) +# define SAM_EMAC1_TBFT511 (SAM_EMAC1_BASE+SAM_EMAC_TBFT511_OFFSET) +# define SAM_EMAC1_TBFT1023 (SAM_EMAC1_BASE+SAM_EMAC_TBFT1023_OFFSET) +# define SAM_EMAC1_TBFT1518 (SAM_EMAC1_BASE+SAM_EMAC_TBFT1518_OFFSET) +# define SAM_EMAC1_GTBFT1518 (SAM_EMAC1_BASE+SAM_EMAC_GTBFT1518_OFFSET) +# define SAM_EMAC1_TUR (SAM_EMAC1_BASE+SAM_EMAC_TUR_OFFSET) +# define SAM_EMAC1_SCF (SAM_EMAC1_BASE+SAM_EMAC_SCF_OFFSET) +# define SAM_EMAC1_MCF (SAM_EMAC1_BASE+SAM_EMAC_MCF_OFFSET) +# define SAM_EMAC1_EC (SAM_EMAC1_BASE+SAM_EMAC_EC_OFFSET) +# define SAM_EMAC1_LC (SAM_EMAC1_BASE+SAM_EMAC_LC_OFFSET) +# define SAM_EMAC1_DTF (SAM_EMAC1_BASE+SAM_EMAC_DTF_OFFSET) +# define SAM_EMAC1_CSE (SAM_EMAC1_BASE+SAM_EMAC_CSE_OFFSET) +# define SAM_EMAC1_ORLO (SAM_EMAC1_BASE+SAM_EMAC_ORLO_OFFSET) +# define SAM_EMAC1_ORHI (SAM_EMAC1_BASE+SAM_EMAC_ORHI_OFFSET) +# define SAM_EMAC1_FR (SAM_EMAC1_BASE+SAM_EMAC_FR_OFFSET) +# define SAM_EMAC1_BCFR (SAM_EMAC1_BASE+SAM_EMAC_BCFR_OFFSET) +# define SAM_EMAC1_MFR (SAM_EMAC1_BASE+SAM_EMAC_MFR_OFFSET) +# define SAM_EMAC1_PFR (SAM_EMAC1_BASE+SAM_EMAC_PFR_OFFSET) +# define SAM_EMAC1_BFR64 (SAM_EMAC1_BASE+SAM_EMAC_BFR64_OFFSET) +# define SAM_EMAC1_TBFR127 (SAM_EMAC1_BASE+SAM_EMAC_TBFR127_OFFSET) +# define SAM_EMAC1_TBFR255 (SAM_EMAC1_BASE+SAM_EMAC_TBFR255_OFFSET) +# define SAM_EMAC1_TBFR511 (SAM_EMAC1_BASE+SAM_EMAC_TBFR511_OFFSET) +# define SAM_EMAC1_TBFR1023 (SAM_EMAC1_BASE+SAM_EMAC_TBFR1023_OFFSET) +# define SAM_EMAC1_TBFR1518 (SAM_EMAC1_BASE+SAM_EMAC_TBFR1518_OFFSET) +# define SAM_EMAC1_TMXBFR (SAM_EMAC1_BASE+SAM_EMAC_TMXBFR_OFFSET) +# define SAM_EMAC1_UFR (SAM_EMAC1_BASE+SAM_EMAC_UFR_OFFSET) +# define SAM_EMAC1_OFR (SAM_EMAC1_BASE+SAM_EMAC_OFR_OFFSET) +# define SAM_EMAC1_JR (SAM_EMAC1_BASE+SAM_EMAC_JR_OFFSET) +# define SAM_EMAC1_FCSE (SAM_EMAC1_BASE+SAM_EMAC_FCSE_OFFSET) +# define SAM_EMAC1_LFFE (SAM_EMAC1_BASE+SAM_EMAC_LFFE_OFFSET) +# define SAM_EMAC1_RSE (SAM_EMAC1_BASE+SAM_EMAC_RSE_OFFSET) +# define SAM_EMAC1_AE (SAM_EMAC1_BASE+SAM_EMAC_AE_OFFSET) +# define SAM_EMAC1_RRE (SAM_EMAC1_BASE+SAM_EMAC_RRE_OFFSET) +# define SAM_EMAC1_ROE (SAM_EMAC1_BASE+SAM_EMAC_ROE_OFFSET) +# define SAM_EMAC1_IHCE (SAM_EMAC1_BASE+SAM_EMAC_IHCE_OFFSET) +# define SAM_EMAC1_TCE (SAM_EMAC1_BASE+SAM_EMAC_TCE_OFFSET) +# define SAM_EMAC1_UCE (SAM_EMAC1_BASE+SAM_EMAC_UCE_OFFSET) + +/* PTP/1588 Timer Registers */ + +# define SAM_EMAC1_TSSS (SAM_EMAC1_BASE+SAM_EMAC_TSSS_OFFSET) +# define SAM_EMAC1_TSSN (SAM_EMAC1_BASE+SAM_EMAC_TSSN_OFFSET) +# define SAM_EMAC1_TS (SAM_EMAC1_BASE+SAM_EMAC_TS_OFFSET) +# define SAM_EMAC1_TN (SAM_EMAC1_BASE+SAM_EMAC_TN_OFFSET) +# define SAM_EMAC1_TA (SAM_EMAC1_BASE+SAM_EMAC_TA_OFFSET) +# define SAM_EMAC1_TI (SAM_EMAC1_BASE+SAM_EMAC_TI_OFFSET) +# define SAM_EMAC1_EFTS (SAM_EMAC1_BASE+SAM_EMAC_EFTS_OFFSET) +# define SAM_EMAC1_EFTN (SAM_EMAC1_BASE+SAM_EMAC_EFTN_OFFSET) +# define SAM_EMAC1_EFRS (SAM_EMAC1_BASE+SAM_EMAC_EFRS_OFFSET) +# define SAM_EMAC1_EFRN (SAM_EMAC1_BASE+SAM_EMAC_EFRN_OFFSET) +# define SAM_EMAC1_PEFTS (SAM_EMAC1_BASE+SAM_EMAC_PEFTS_OFFSET) +# define SAM_EMAC1_PEFTN (SAM_EMAC1_BASE+SAM_EMAC_PEFTN_OFFSET) +# define SAM_EMAC1_PEFRS (SAM_EMAC1_BASE+SAM_EMAC_PEFRS_OFFSET) +# define SAM_EMAC1_PEFRN (SAM_EMAC1_BASE+SAM_EMAC_PEFRN_OFFSET) +#endif + +/* EMAC Register Bit Definitions ****************************************************/ + +/* Network Control Register */ + +#define EMAC_NCR_LBL (1 << 1) /* Bit 1: Loopback local */ +#define EMAC_NCR_RXEN (1 << 2) /* Bit 2: Receive enable */ +#define EMAC_NCR_TXEN (1 << 3) /* Bit 3: Transmit enable */ +#define EMAC_NCR_MPE (1 << 4) /* Bit 4: Management port enable */ +#define EMAC_NCR_CLRSTAT (1 << 5) /* Bit 5: Clear statistics registers */ +#define EMAC_NCR_INCSTAT (1 << 6) /* Bit 6: Increment statistics registers */ +#define EMAC_NCR_WESTAT (1 << 7) /* Bit 7: Write enable for statistics registers */ +#define EMAC_NCR_BP (1 << 8) /* Bit 8: Back pressure */ +#define EMAC_NCR_TSTART (1 << 9) /* Bit 9: Start transmission */ +#define EMAC_NCR_THALT (1 << 10) /* Bit 10: Transmit halt */ +#define EMAC_TXPF (1 << 11) /* Bit 11: Transmit Pause Frame */ +#define EMAC_TXZQPF (1 << 12) /* Bit 12: Transmit Zero Quantum Pause Frame */ +#define EMAC_SRTSM (1 << 15) /* Bit 15: Store Receive Time Stamp to Memory */ +#define EMAC_ENPBPR (1 << 16) /* Bit 16: Enable PFC Priority-based Pause Reception */ +#define EMAC_TXPBPF (1 << 17) /* Bit 17: Transmit PFC Priority-based Pause Frame */ +#define EMAC_FNP (1 << 18) /* Bit 18: Flush Next Packet */ + +/* Network Configuration Register */ + +#define EMAC_NCFGR_SPD (1 << 0) /* Bit 0: Speed */ +#define EMAC_NCFGR_FD (1 << 1) /* Bit 1: Full Duplex */ +#define EMAC_NCFGR_DNVLAN (1 << 2) /* Bit 2: Discard Non-VLAN FRAMES */ +#define EMAC_NCFGR_JFRAME (1 << 3) /* Bit 3: Jumbo Frames */ +#define EMAC_NCFGR_CAF (1 << 4) /* Bit 4: Copy All Frames */ +#define EMAC_NCFGR_NBC (1 << 5) /* Bit 5: No Broadcast */ +#define EMAC_NCFGR_MTIHEN (1 << 6) /* Bit 6: Multicast Hash Enable */ +#define EMAC_NCFGR_UNIHEN (1 << 7) /* Bit 7: Unicast Hash Enable */ +#define EMAC_NCFGR_MAXFS (1 << 8) /* Bit 8: 1536 Maximum Frame Size */ +#define EMAC_NCFGR_RTY (1 << 12) /* Bit 12: Retry test */ +#define EMAC_NCFGR_PEN (1 << 13) /* Bit 13: Pause Enable */ +#define EMAC_NCFGR_RXBUFO_SHIFT (14) /* Bits 14-15: Receive Buffer Offset */ +#define EMAC_NCFGR_RXBUFO_MASK (3 << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO(n) ((uint32_t)(n) << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO_NONE (0 << EMAC_NCFGR_RXBUFO_SHIFT) /* No offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_1 (1 << EMAC_NCFGR_RXBUFO_SHIFT) /* One-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_2 (2 << EMAC_NCFGR_RXBUFO_SHIFT) /* Two-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_3 (3 << EMAC_NCFGR_RXBUFO_SHIFT) /* Three-byte offset fromRX buffer start */ +#define EMAC_NCFGR_LFERD (1 << 16) /* Bit 16: Length Field Error Frame Discard */ +#define EMAC_NCFGR_RFCS (1 << 17) /* Bit 17: Remove FCS */ +#define EMAC_NCFGR_CLK_SHIFT (18) /* Bits 18-20: MDC clock divider */ +#define EMAC_NCFGR_CLK_MASK (7 << EMAC_NCFGR_CLK_SHIFT) +# define EMAC_NCFGR_CLK_DIV8 (0 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 8 (MCK up to 20 MHz) */ +# define EMAC_NCFGR_CLK_DIV16 (1 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 16 (MCK up to 40 MHz) */ +# define EMAC_NCFGR_CLK_DIV32 (2 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */ +# define EMAC_NCFGR_CLK_DIV48 (3 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 48 (MCK up to 120 MHz) */ +# define EMAC_NCFGR_CLK_DIV64 (4 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */ +# define EMAC_NCFGR_CLK_DIV96 (5 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 96 (MCK up to 240 MHz) */ +#define EMAC_NCFGR_DBW_SHIFT (21) /* Bit 21-22: Data Bus Width */ +#define EMAC_NCFGR_DBW_MASK (3 << EMAC_NCFGR_DBW_SHIFT) +# define EMAC_NCFGR_DBW_ZERO (0 << EMAC_NCFGR_DBW_SHIFT) /* Must be zero */ +#define EMAC_NCFGR_DCPF (1 << 23) /* Bit 23: Disable Copy of Pause Frames */ +#define EMAC_NCFGR_RXCOEN (1 << 24) /* Bit 24: Receive Checksum Offload Enable */ +#define EMAC_NCFGR_EFRHD (1 << 25) /* Bit 25: Enable Frames Received in Half Duplex */ +#define EMAC_NCFGR_IRXFCS (1 << 26) /* Bit 26: Ignore RX FCS */ +#define EMAC_NCFGR_IPGSEN (1 << 28) /* Bit 28: IP Stretch Enable */ +#define EMAC_NCFGR_RXBP (1 << 29) /* Bit 29: Receive Bad Preamble */ +#define EMAC_NCFGR_IRXER (1 << 30) /* Bit 30: Ignore IPG GRXER */ + +/* Network Status Register */ + +#define EMAC_NSR_MDIO (1 << 1) /* Bit 1: Status of the MDIO input pin */ +#define EMAC_NSR_IDLE (1 << 2) /* Bit 2: PHY management logic is idle */ + +/* User Register */ + +#define EMAC_UR_RMII (1 << 0) /* Bit 0: Reduced MII Mode */ + +/* DMA Configuration Register */ + +#define EMAC_DCFGR_FBLDO_SHIFT (0) /* Bits 0-4: Fixed Burst Length for DMA Data Operations */ +#define EMAC_DCFGR_FBLDO_MASK (31 << EMAC_DCFGR_FBLDO_SHIFT) +# define EMAC_DCFGR_FBLDO_SINGLE (1 << EMAC_DCFGR_FBLDO_SHIFT) /* Always use SINGLE AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR4 (4 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR4 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR8 (8 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR8 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR16 (16 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR16 AHB bursts */ +#define EMAC_DCFGR_ESMA (1 << 6) /* Bit 6: Endian Swap Mode Enable for Management Descriptor Accesses */ +#define EMAC_DCFGR_ESPA (1 << 7) /* Bit 7: Endian Swap Mode Enable for Packet Data Accesses */ +#define EMAC_DCFGR_DRBS_SHIFT (16) /* Bits 16-23: DMA Receive Buffer Size */ +#define EMAC_DCFGR_DRBS_MASK (0xff << EMAC_DCFGR_DRBS_SHIFT) +# define EMAC_DCFGR_DRBS(n) ((uint32_t)(n) << EMAC_DCFGR_DRBS_SHIFT) + +/* Transmit Status Register */ + +#define EMAC_TSR_UBR (1 << 0) /* Bit 0: Used Bit Read */ +#define EMAC_TSR_COL (1 << 1) /* Bit 1: Collision Occurred */ +#define EMAC_TSR_RLE (1 << 2) /* Bit 2: Retry Limit exceeded */ +#define EMAC_TSR_TXGO (1 << 3) /* Bit 3: Transmit Go */ +#define EMAC_TSR_TFC (1 << 4) /* Bit 4: Transmit Frame Corruption due to AHB error */ +#define EMAC_TSR_TXCOMP (1 << 5) /* Bit 5: Transmit Complete */ +#define EMAC_TSR_UND (1 << 6) /* Bit 6: Transmit Underrun */ +#define EMAC_TSR_HRESP (1 << 8) /* Bit 8: HRESP Not OK */ + +/* Receive Buffer Queue Pointer Register */ + +#define EMAC_RBQB_MASK (0xfffffffc) /* Bits 2-31: Receive buffer queue pointer address */ + +/* Transmit Buffer Queue Pointer Register */ + +#define EMAC_TBQB_MASK (0xfffffffc) /* Bits 2-31: Transmit buffer queue pointer address */ + +/* Receive Status Register */ + +#define EMAC_RSR_BNA (1 << 0) /* Bit 0: Buffer Not Available */ +#define EMAC_RSR_REC (1 << 1) /* Bit 1: Frame Received */ +#define EMAC_RSR_RXOVR (1 << 2) /* Bit 2: Receive Overrun */ +#define EMAC_RSR_HNO (1 << 3) /* Bit 3: HRESP Not OK */ + +/* Interrupt Status Register (ISR), Interrupt Enable Register (IER), Interrupt Disable Register (IDR) and Interrupt Mask Register (IMR) */ + +#define EMAC_INT_MFS (1 << 0) /* Bit 0: Management Frame Sent */ +#define EMAC_INT_RCOMP (1 << 1) /* Bit 1: Receive Complete */ +#define EMAC_INT_RXUBR (1 << 2) /* Bit 2: Receive Used Bit Read */ +#define EMAC_INT_TXUBR (1 << 3) /* Bit 3: Transmit Used Bit Read */ +#define EMAC_INT_TUR (1 << 4) /* Bit 4: Ethernet Transmit Buffer Underrun */ +#define EMAC_INT_RLEX (1 << 5) /* Bit 5: Retry Limit Exceeded */ +#define EMAC_INT_TFC (1 << 6) /* Bit 6: Transmit Frame Corruption due to AHB error */ +#define EMAC_INT_TCOMP (1 << 7) /* Bit 7: Transmit Complete */ +#define EMAC_INT_ROVR (1 << 10) /* Bit 10: Receive Overrun */ +#define EMAC_INT_HRESP (1 << 11) /* Bit 11: Hresp not OK */ +#define EMAC_INT_PFNZ (1 << 12) /* Bit 12: Pause Frame with Non-zero Pause Quantum Received */ +#define EMAC_INT_PTZ (1 << 13) /* Bit 13: Pause Time Zero */ +#define EMAC_INT_PTFR (1 << 14) /* Bit 14: Pause Frame Transmitted */ +#define EMAC_INT_EXINT (1 << 15) /* Bit 15: External Interrupt (not SR) */ +#define EMAC_INT_DRQFR (1 << 18) /* Bit 18: PTP Delay Request Frame Received */ +#define EMAC_INT_SFR (1 << 19) /* Bit 19: PTP Sync Frame Received */ +#define EMAC_INT_DRQFT (1 << 20) /* Bit 20: PTP Delay Request Frame Transmitted */ +#define EMAC_INT_SFT (1 << 21) /* Bit 21: PTP Sync Frame Transmitted */ +#define EMAC_INT_PDRQFR (1 << 22) /* Bit 22: PDelay Request Frame Received */ +#define EMAC_INT_PDRSFR (1 << 23) /* Bit 23: PDelay Response Frame Received */ +#define EMAC_INT_PDRQFT (1 << 24) /* Bit 24: PDelay Request Frame Transmitted */ +#define EMAC_INT_PDRSFT (1 << 25) /* Bit 25: PDelay Response Frame Transmitted */ +#define EMAC_INT_SRI (1 << 26) /* Bit 26: TSU Seconds Register Increment (not IMR) */ +#define EMAC_INT_WOL (1 << 28) /* Bit 28: Wake On LAN (not IMR) */ + +#define EMAC_INT_ALL (0x17fcfcff) +#define EMAC_INT_UNUSED (0xe8030300) + +/* PHY Maintenance Register */ + +#define EMAC_MAN_DATA_SHIFT (0) /* Bits 0-15: Read/write data */ +#define EMAC_MAN_DATA_MASK (0x0000ffff << EMAC_MAN_DATA_SHIFT) +# define EMAC_MAN_DATA(n) ((uint32_t)(n) << EMAC_MAN_DATA_SHIFT) +#define EMAC_MAN_WTN_SHIFT (16) /* Bits 16-17: Must be written to b10 */ +#define EMAC_MAN_WTN_MASK (3 << EMAC_MAN_WTN_SHIFT) +# define EMAC_MAN_WTN (2 << EMAC_MAN_WTN_SHIFT) +#define EMAC_MAN_REGA_SHIFT (18) /* Bits 18-22: Register Address */ +#define EMAC_MAN_REGA_MASK (31 << EMAC_MAN_REGA_SHIFT) +# define EMAC_MAN_REGA(n) ((uint32_t)(n) << EMAC_MAN_REGA_SHIFT) +#define EMAC_MAN_PHYA_SHIFT (23) /* Bits 23-27: PHY Address */ +#define EMAC_MAN_PHYA_MASK (31 << EMAC_MAN_PHYA_SHIFT) +# define EMAC_MAN_PHYA(n) ((uint32_t)(n) << EMAC_MAN_PHYA_SHIFT) +#define EMAC_MAN_OP_SHIFT (28) /* Bits 28-29: Operation */ +#define EMAC_MAN_OP_MASK (3 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_READ (2 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_WRITE (1 << EMAC_MAN_OP_SHIFT) +#define EMAC_MAN_CLTTO (1 << 30) /* Bit 30: Clause 22 Operation */ +#define EMAC_MAN_WZO (0) /* Bit 31: Write ZERO */ + +/* Pause Time Register */ + +#define EMAC_RPQ_MASK (0x0000ffff) /* Bits 0-15: Received Pause Quantum */ + +/* Pause Frames Received Register */ + +#define EMAC_TPQ_MASK (0x0000ffff) /* Bits 0-15: Transmit Pause Quantum */ + +/* Hash Register Bottom [31:0] Register (LS 32-bit hash address) */ +/* Hash Register Top [63:32] Register (MS 32-bit hash address) */ + +/* Specific Address 1 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Top [47:32] Register */ + +#define EMAC_SAT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 2 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 2 Top [47:32] Register */ + +#define EMAC_SAT2_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 3 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 3 Top [47:32] Register */ + +#define EMAC_SAT3_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 4 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 4 Top [47:32] Register */ + +#define EMAC_SAT4_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Type ID Match Registers */ + +#define EMAC_TIDM_MASK (0x0000ffff) /* Bits 0-15: Type ID Match n */ + +/* Type ID Checking Register */ + +#define EMAC_TID_MASK (0x0000ffff) /* Bits 0-15: For comparisons with received frames TypeID/Length field */ + +/* Wake-up on LAN Register */ + +#define EMAC_WOL_IP_SHIFT (0) /* Bits 0-15: ARP Request IP Address */ +#define EMAC_WOL_IP_MASK (0x0000ffff << EMAC_WOL_IP_SHIFT) +# define EMAC_WOL_IP(n) ((uin32_t)(n) << EMAC_WOL_IP_SHIFT) +#define EMAC_WOL_MAG (1 << 16) /* Bit 16: Magic Packet Event Enable */ +#define EMAC_WOL_ARP (1 << 17) /* Bit 17: ARP Request Event Enable */ +#define EMAC_WOL_SA1 (1 << 18) /* Bit 18: Specific Address Register 1 Event Enable */ +#define EMAC_WOL_MTI (1 << 19) /* Bit 19: Multicast Hash Event Enable */ + +/* IPG Stretch Register */ + +#define EMAC_IPGS_FL_MASK (0x0000ffff) /* Bit 0-15: Frame Length */ + +/* Stacked VLAN Register */ + +#define EMAC_SVLAN_VLANTYPE_SHIFT (0) /* Bits 0-15: User Defined VLAN_TYPE Field */ +#define EMAC_SVLAN_VLANTYPE_MASK (0x0000ffff << EMAC_SVLAN_VLANTYPE_SHIFT) +# define EMAC_SVLAN_VLANTYPE(n) ((uint32_t)(n) << EMAC_SVLAN_VLANTYPE_SHIFT) +#define EMAC_SVLAN_ESVLAN (1 << 31) /* Bit 31: Enable Stacked VLAN Processing Mode */ + +/* Transmit PFC Pause Register */ + +#define EMAC_TPFCP_PEV_SHIFT (0) /* Bits 0-7: Priority Enable Vector */ +#define EMAC_TPFCP_PEV_MASK (0xff << EMAC_TPFCP_PEV_SHIFT) +#define EMAC_TPFCP_PQ_SHIFT (8) /* Bits 8-15: Pause Quantum */ +#define EMAC_TPFCP_PQ_MASK (0xff << EMAC_TPFCP_PQ_SHIFT) + +/* Specific Address 1 Mask Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Mask Top [47:32] Register (MS 16-bit address) */ + +#define EMAC_SAMT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of Specific Address 1 Mask */ + +/* Statistics registers. Only masking is needed. + * + * Octets Transmitted [31:0] Register (OTLO) 32-bit + * Octets Transmitted [47:32] Register (OTHI) 16-bit + * Frames Transmitted Register (FT) 32-bit + * Broadcast Frames Transmitted Register (BCFT) 32-bit + * Multicast Frames Transmitted Register (MFT) 32-bit + * Pause Frames Transmitted Register (PFT) 16-bit + * 64 Byte Frames Transmitted Register (BFT64) 32-bit + * 65 to 127 Byte Frames Transmitted Register (TBFT127) 32-bit + * 128 to 255 Byte Frames Transmitted Register (TBFT255) 32-bit + * 256 to 511 Byte Frames Transmitted Register (TBFT511) 32-bit + * 512 to 1023 Byte Frames Transmitted Register (TBFT1023) 32-bit + * 1024 to 1518 Byte Frames Transmitted Register (TBFT1518) 32-bit + * Greater Than 1518 Byte Frames Transmitted Register (GTBFT1518) 32-bit + * Transmit Under Runs Register (TUR) 10-bit + * Single Collision Frames Register (SCF) 18-bit + * Multiple Collision Frames Register (MCF) 18-bit + * Excessive Collisions Register (EC) 10-bit + * Late Collisions Register (LC) 10-bit + * Deferred Transmission Frames Register (DTF) 18-bit + * Carrier Sense Errors Register (CSE) 10-bit + * Octets Received [31:0] Received (ORLO) 32-bit + * Octets Received [47:32] Received (ORHI) 16-bit + * Frames Received Register (FR) 32-bit + * Broadcast Frames Received Register (BCFR) 32-bit + * Multicast Frames Received Register (MFR) 32-bit + * Pause Frames Received Register (PFR) 32-bit + * 64 Byte Frames Received Register (BFR64) 32-bit + * 65 to 127 Byte Frames Received Register (TBFR127) 32-bit + * 128 to 255 Byte Frames Received Register (TBFR255) 32-bit + * 256 to 511Byte Frames Received Register (TBFR511) 32-bit + * 512 to 1023 Byte Frames Received Register (TBFR1023) 32-bit + * 1024 to 1518 Byte Frames Received Register (TBFR1518) 32-bit + * 1519 to Maximum Byte Frames Received Register (TMXBFR) 32-bit + * Undersize Frames Received Register (UFR) 10-bit + * Oversize Frames Received Register (OFR) 10-bit + * Jabbers Received Register (JR) 10-bit + * Frame Check Sequence Errors Register (FCSE) 10-bit + * Length Field Frame Errors Register (LFFE) 10-bit + * Receive Symbol Errors Register (RSE) 10-bit + * Alignment Errors Register (AE) 10-bit + * Receive Resource Errors Register (RRE) 18-bit + * Receive Overrun Register (ROE) 10-bit + * IP Header Checksum Errors Register (IHCE) 8-bit + * TCP Checksum Errors Register (TCE) 8-bit + * UDP Checksum Errors Register (UCE) 8-bit + */ + +/* PTP/1588 Timer Registers */ + +/* 1588 Timer Sync Strobe Seconds Register (32-bit timer value) */ +/* 1588 Timer Sync Strobe Nanoseconds Register (30-bit timer value) */ + +#define EMAC_TSSN_MASK (0x3fffffff) /* Bit 0-29: Value Timer Nanoseconds Register Capture */ + +/* 1588 Timer Seconds Register (32-bit timer value) */ +/* 1588 Timer Nanoseconds Register (30-bit timer value) */ + +#define EMAC_TN_MASK (0x3fffffff) /* Bit 0-29: Timer Count in Nanoseconds */ + +/* 1588 Timer Adjust Register */ + +#define EMAC_TA_ITDT_SHIFT (0) /* Bits 0-29: Increment/Decrement */ +#define EMAC_TA_ITDT_MASK (0x3fffffff << EMAC_TA_ITDT_SHIFT) +# define EMAC_TA_ITDT(n) ((uint32_t)(n) << EMAC_TA_ITDT_SHIFT) +#define EMAC_TA_ADJ (1 << 31) /* Bit 31: Adjust 1588 Timer */ + +/* 1588 Timer Increment Register */ + +#define EMAC_TI_CNS_SHIFT (0) /* Bits 0-7: Count Nanoseconds */ +#define EMAC_TI_CNS_MASK (0xff << EMAC_TI_CNS_SHIFT) +# define EMAC_TI_CNS(n) ((uint32_t)(n) << EMAC_TI_CNS_SHIFT) +#define EMAC_TI_ACNS_SHIFT (8) /* Bits 8-15: Alternative Count Nanoseconds */ +#define EMAC_TI_ACNS_MASK (0xff << EMAC_TI_ACNS_SHIFT) +# define EMAC_TI_ACNS(n) ((uint32_t)(n) << EMAC_TI_ACNS_SHIFT) +#define EMAC_TI_NIT_SHIFT (16) /* Bits 16-23: Number of Increments */ +#define EMAC_TI_NIT_MASK (0xff << EMAC_TI_NIT_SHIFT) +# define EMAC_TI_NIT(n) ((uint32_t)(n) << EMAC_TI_NIT_SHIFT) + +/* PTP Event Frame Transmitted Seconds (32-bit timer value) */ +/* PTP Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_EFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Event Frame Received Seconds (32-bit timer value) */ +/* PTP Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_EFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Transmitted Seconds (32-bit timer value) */ +/* PTP Peer Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Received Seconds (32-bit timer value) */ +/* PTP Peer Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* Descriptors **********************************************************************/ + +/* Receive buffer descriptor: Address word */ + +#define EMACRXD_ADDR_OWNER (1 << 0) /* Bit 0: 1=Software owns; 0=EMAC owns */ +#define EMACRXD_ADDR_WRAP (1 << 1) /* Bit 1: Last descriptor in list */ +#define EMACRXD_ADDR_MASK (0xfffffffc) /* Bits 2-31: Aligned buffer address */ + +/* Receive buffer descriptor: Control word */ + +#define EMACRXD_STA_FRLEN_SHIFT (0) /* Bits 0-12: Length of frame (not jumbo)*/ +#define EMACRXD_STA_FRLEN_MASK (0x00001fff << EMACRXD_STA_FRLEN_SHIFT) +#define EMACRXD_STA_JFRLEN_SHIFT (0) /* Bits 0-13: Length of frame (jumbo)*/ +#define EMACRXD_STA_JFRLEN_MASK (0x00003fff << EMACRXD_STA_JFRLEN_SHIFT) +#define EMACRXD_STA_BADFCS (1 << 13) /* Bit 13: Frame had bad FCS (not jumbo) */ +#define EMACRXD_STA_SOF (1 << 14) /* Bit 14: Start of frame */ +#define EMACRXD_STA_EOF (1 << 15) /* Bit 15: End of frame */ +#define EMACRXD_STA_CFI (1 << 16) /* Bit 16: Concatenation format indicator (CFI) bit */ +#define EMACRXD_STA_VLPRIO_SHIFT (17) /* Bits 17-19: VLAN priority */ +#define EMACRXD_STA_VLPRIO_MASK (7 << EMACRXD_STA_VLANPRIO_SHIFT) +#define EMACRXD_STA_PRIODET (1 << 20) /* Bit 20: Priority tag detected */ +#define EMACRXD_STA_VLANTAG (1 << 21) /* Bit 21: VLAN tag detected */ +#define EMACRXD_STA_TYPEID_SHIFT (22) /* Bit 22-23: Specific address register */ +#define EMACRXD_STA_TYPEID_MASK (3 << EMACRXD_STA_TYPEID_SHIFT) +# define EMACRXD_STA_TYPEID1 (0 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 1 match */ +# define EMACRXD_STA_TYPEID2 (1 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 2 match */ +# define EMACRXD_STA_TYPEID3 (2 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 3 match */ +# define EMACRXD_STA_TYPEID4 (3 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 4 match */ +#define EMACRXD_STA_TYPEIDMATCH (1 << 24) /* Bit 24: Type ID register match found */ +#define EMACRXD_STA_SNAP (1 << 24) /* Bit 24: Frame was SNAP encoded */ +#define EMACRXD_STA_ADDR_SHIFT (25) /* Bit 25-26: Specific address register */ +#define EMACRXD_STA_ADDR_MASK (3 << EMACRXD_STA_ADDR_SHIFT) +# define EMACRXD_STA_ADDR1 (0 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 1 match */ +# define EMACRXD_STA_ADDR2 (1 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 2 match */ +# define EMACRXD_STA_ADDR3 (2 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 3 match */ +# define EMACRXD_STA_ADDR4 (3 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 4 match */ +#define EMACRXD_STA_ADDRMATCH (1 << 27) /* Bit 27: Specific address match found */ + /* Bit 28: Reserved */ +#define EMACRXD_STA_UCAST (1 << 29) /* Bit 29: Unicast hash match */ +#define EMACRXD_STA_MCAST (1 << 30) /* Bit 30: Multicast hash match */ +#define EMACRXD_STA_BCAST (1 << 31) /* Bit 31: Global all ones broadcast address detected */ + +/* Transmit buffer descriptor: Address word (un-aligned, 32-bit address */ +/* Transmit buffer descriptor: Control word */ + +#define EMACTXD_STA_BUFLEN_SHIFT (0) /* Bits 0-13: Length of buffer */ +#define EMACTXD_STA_BUFLEN_MASK (0x00003fff << EMACTXD_STA_BUFLEN_SHIFT) + /* Bit 14: Reserved */ +#define EMACTXD_STA_LAST (1 << 15) /* Bit 15: Last buffer in the current frame */ +#define EMACTXD_STA_NOCRC (1 << 16) /* Bit 16: No CRC */ + /* Bits 17-19: Reserved */ +#define EMACTXD_STA_CHKERR_SHIFT (20) /* Bits 20-22: Transmit IP/TCP/UDP checksum generation offload errors */ +#define EMACTXD_STA_CHKERR_MASK (7 << EMACTXD_STA_CHKERR_SHIFT) +# define EMACTXD_STA_CHKERR_NONE (0 << EMACTXD_STA_CHKERR_SHIFT) /* No Error */ +# define EMACTXD_STA_CHKERR_BADVLAN (1 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous VLAN type */ +# define EMACTXD_STA_CHKERR_BADSNAP (2 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous SNAP type */ +# define EMACTXD_STA_CHKERR_NOTIP (3 << EMACTXD_STA_CHKERR_SHIFT) /* Not IP or invalid IP type */ +# define EMACTXD_STA_CHKERR_UNREC (4 << EMACTXD_STA_CHKERR_SHIFT) /* Not VLAN, SNAP, or IP */ +# define EMACTXD_STA_CHKERR_BADFRAG (5 << EMACTXD_STA_CHKERR_SHIFT) /* Unsupported fragmentation */ +# define EMACTXD_STA_CHKERR_PKTTYPE (6 << EMACTXD_STA_CHKERR_SHIFT) /* Not TCP or UDP */ +# define EMACTXD_STA_CHKERR_EPKT (7 << EMACTXD_STA_CHKERR_SHIFT) /* Premature end of packet */ + /* Bits 23-25: Reserved */ +#define EMACTXD_STA_LCOL (1 << 26) /* Bit 26: Late collision, transmit error detected */ +#define EMACTXD_STA_TFC (1 << 27) /* Bit 27: Transmit frame corruption due to AHB error */ +#define EMACTXD_STA_TXUR (1 << 28) /* Bit 28: Transmit underrun */ +#define EMACTXD_STA_TXERR (1 << 29) /* Bit 29: Retry limit exceeded, transmit error detected */ +#define EMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */ +#define EMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the EMAC to read from buffer */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Receive buffer descriptor */ + +struct emac_rxdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* RX status and controls */ +}; + +/* Transmit buffer descriptor */ + +struct emac_txdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* TX status and controls */ +}; + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_EMACB_H */ diff --git a/arch/arm/src/sama5/chip/sam_flexcom.h b/arch/arm/src/sama5/chip/sam_flexcom.h new file mode 100644 index 0000000000000000000000000000000000000000..1e690d1ba55c67eb5d5f776cf8bcaff7e18a5817 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_flexcom.h @@ -0,0 +1,127 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_flexcom.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Common Flexcom Register Offsets **************************************************/ + +#define SAM_FLEX_MR_OFFSET 0x000 /* FLEXCOM Mode Register */ + /* 0x0004–0x000c Reserved */ +#define SAM_FLEX_RHR_OFFSET 0x010 /* FLEXCOM Receive Holding Register */ + /* 0x0014–0x001c Reserved */ +#define SAM_FLEX_THR_OFFSET 0x020 /* FLEXCOM Transmit Holding Register */ + /* 0x0024–0x01fc Reserved */ + /* 0x0200-0x03ff: Flexcom USART register */ + /* 0x0400-0x05ff: Flexcom USART register */ + /* 0x0600-0x07ff: Flexcom USART register */ + +/* Common Flexcom Register Addresses ************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM0 +# define SAM_FLEX0_MR (SAM_FLEXCOM0_VBASE+SAM_FLEX_MR_OFFSET) +# define SAM_FLEX0_RHR (SAM_FLEXCOM0_VBASE+SAM_FLEX_RHR_OFFSET) +# define SAM_FLEX0_THR (SAM_FLEXCOM0_VBASE+SAM_FLEX_THR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM1 +# define SAM_FLEX1_MR (SAM_FLEXCOM1_VBASE+SAM_FLEX_MR_OFFSET) +# define SAM_FLEX1_RHR (SAM_FLEXCOM1_VBASE+SAM_FLEX_RHR_OFFSET) +# define SAM_FLEX1_THR (SAM_FLEXCOM1_VBASE+SAM_FLEX_THR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM2 +# define SAM_FLEX2_MR (SAM_FLEXCOM2_VBASE+SAM_FLEX_MR_OFFSET) +# define SAM_FLEX2_RHR (SAM_FLEXCOM2_VBASE+SAM_FLEX_RHR_OFFSET) +# define SAM_FLEX2_THR (SAM_FLEXCOM2_VBASE+SAM_FLEX_THR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM3 +# define SAM_FLEX3_MR (SAM_FLEXCOM3_VBASE+SAM_FLEX_MR_OFFSET) +# define SAM_FLEX3_RHR (SAM_FLEXCOM3_VBASE+SAM_FLEX_RHR_OFFSET) +# define SAM_FLEX3_THR (SAM_FLEXCOM3_VBASE+SAM_FLEX_THR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM4 +# define SAM_FLEX4_MR (SAM_FLEXCOM4_VBASE+SAM_FLEX_MR_OFFSET) +# define SAM_FLEX4_RHR (SAM_FLEXCOM4_VBASE+SAM_FLEX_RHR_OFFSET) +# define SAM_FLEX4_THR (SAM_FLEXCOM4_VBASE+SAM_FLEX_THR_OFFSET) +#endif + +/* Common Flexcom Register Bit Field Definitions ************************************/ + +/* FLEXCOM Mode Register */ + +#define FLEX_MR_OPMODE_SHIFT (0) /* Bits 0-1: Operating mode */ +#define FLEX_MR_OPMODE_MASK (3 << FLEX_MR_OPMODE_SHIFT) +# define FLEX_MR_OPMODE_NOCOM (0 << FLEX_MR_OPMODE_SHIFT) /* No communication */ +# define FLEX_MR_OPMODE_USART (1 << FLEX_MR_OPMODE_SHIFT) /* All UART related protocols selected */ +# define FLEX_MR_OPMODE_SPI (2 << FLEX_MR_OPMODE_SHIFT) /* SPI operating mode is selected */ +# define FLEX_MR_OPMODE_TWI (3 << FLEX_MR_OPMODE_SHIFT) /* All TWI related protocols are selected */ + +/* FLEXCOM Receive Holding Register */ + +#define FLEX_RHR_MASK (0xffff) + +/* FLEXCOM Transmit Holding Register */ + +#define FLEX_THR_MASK (0xffff) + +/* Flexcom USART Register Definitions ***********************************************/ + +#include "chip/sam_flexcom_usart.h" + +/* Flexcom SPI Register Definitions *************************************************/ + +#include "chip/sam_flexcom_spi.h" + +/* Flexcom TWI Register Definitions *************************************************/ + +#include "chip/sam_flexcom_twi.h" + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_H */ diff --git a/arch/arm/src/sama5/chip/sam_flexcom_spi.h b/arch/arm/src/sama5/chip/sam_flexcom_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc4ccc8735436beeee33542728dee6c4d3e93c5 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_flexcom_spi.h @@ -0,0 +1,58 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_flexcom_spi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_SPI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Flexcom SPI Register Offsets *****************************************************/ + +/* Flexcom SPI Register Addresses ***************************************************/ + +/* Flexcom SPI Register Bit Field Definitions ***************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_SPI_H */ diff --git a/arch/arm/src/sama5/chip/sam_flexcom_twi.h b/arch/arm/src/sama5/chip/sam_flexcom_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..69345a6decfc0d882533ff68ab2ed4d184f7dd60 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_flexcom_twi.h @@ -0,0 +1,58 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_flexcom_twi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_TWI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_TWI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Flexcom TWI Register Offsets *****************************************************/ + +/* Flexcom TWI Register Addresses ***************************************************/ + +/* Flexcom TWI Register Bit Field Definitions ***************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_TWI_H */ diff --git a/arch/arm/src/sama5/chip/sam_flexcom_usart.h b/arch/arm/src/sama5/chip/sam_flexcom_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..6331e06fb6678dafa1d2d91e1076585e1df93848 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_flexcom_usart.h @@ -0,0 +1,580 @@ +/************************************************************************************************ + * arch/arm/src/sama5/chip/sam3u_uart.h + * Universal Synchronous Asynchronous Receiver Transmitter (FLEXUS) definitions for the SAMA5D2 + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_FLEXUS_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_FLEXUS_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* USART register offsets ***********************************************************************/ + +#define SAM_FLEXUS_CR_OFFSET 0x0200 /* USART Control Register */ +#define SAM_FLEXUS_MR_OFFSET 0x0204 /* USART Mode Register */ +#define SAM_FLEXUS_IER_OFFSET 0x0208 /* USART Interrupt Enable Register */ +#define SAM_FLEXUS_IDR_OFFSET 0x020c /* USART Interrupt Disable Register */ +#define SAM_FLEXUS_IMR_OFFSET 0x0210 /* USART Interrupt Mask Register */ +#define SAM_FLEXUS_CSR_OFFSET 0x0214 /* USART Channel Status Register */ +#define SAM_FLEXUS_RHR_OFFSET 0x0218 /* USART Receive Holding Register */ +#define SAM_FLEXUS_THR_OFFSET 0x021c /* USART Transmit Holding Register */ +#define SAM_FLEXUS_BRGR_OFFSET 0x0220 /* USART Baud Rate Generator Register */ +#define SAM_FLEXUS_RTOR_OFFSET 0x0224 /* USART Receiver Time-out Register */ +#define SAM_FLEXUS_TTGR_OFFSET 0x0228 /* USART Transmitter Timeguard Register */ + /* 0x022c-0x023c: Reserved */ +#define SAM_FLEXUS_FIDI_OFFSET 0x0240 /* USART FI DI Ratio Register */ +#define SAM_FLEXUS_NER_OFFSET 0x0244 /* USART Number of Errors Register */ + /* 0x0248: Reserved (FLEXUS) */ +#define SAM_FLEXUS_IF_OFFSET 0x024c /* USART IrDA Filter Register */ +#define SAM_FLEXUS_MAN_OFFSET 0x0250 /* USART Manchester Configuration Register */ +#define SAM_FLEXUS_LINMR_OFFSET 0x0254 /* USART LIN Mode Register */ +#define SAM_FLEXUS_LINIR_OFFSET 0x0258 /* USART LIN Identifier Register */ +#define SAM_FLEXUS_LINBRR_OFFSET 0x025c /* USART LIN Baud Rate Register */ + /* 0x0260-0x028c: Reserved (FLEXUS) */ +#define SAM_FLEXUS_CMPR_OFFSET 0x0290 /* USART Comparison Register */ +#define SAM_FLEXUS_FMR_OFFSET 0x02a0 /* USART FIFO Mode Register */ +#define SAM_FLEXUS_FLR_OFFSET 0x02a4 /* USART FIFO Level Register */ +#define SAM_FLEXUS_FIER_OFFSET 0x02a8 /* USART FIFO Interrupt Enable Register */ +#define SAM_FLEXUS_FIDR_OFFSET 0x02ac /* USART FIFO Interrupt Disable Register */ +#define SAM_FLEXUS_FIMR_OFFSET 0x02b0 /* USART FIFO Interrupt Mask Register */ +#define SAM_FLEXUS_FESR_OFFSET 0x02b4 /* USART FIFO Event Status Register */ + /* 0x02b8-0x02e: Reserved */ +#define SAM_FLEXUS_WPMR_OFFSET 0x02e4 /* Write Protect Mode Register (4) */ +#define SAM_FLEXUS_WPSR_OFFSET 0x02e8 /* Write Protect Status Register (4) */ + /* 0x02ec-0x02fc: Reserved (USART) */ + +/* USART register adresses ***********************************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM0 +# define SAM_FLEXUS0_CR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_CR_OFFSET) +# define SAM_FLEXUS0_MR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_MR_OFFSET) +# define SAM_FLEXUS0_IER (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_IER_OFFSET) +# define SAM_FLEXUS0_IDR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_IDR_OFFSET) +# define SAM_FLEXUS0_IMR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_IMR_OFFSET) +# define SAM_FLEXUS0_CSR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_CSR_OFFSET) +# define SAM_FLEXUS0_RHR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_RHR_OFFSET) +# define SAM_FLEXUS0_THR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_THR_OFFSET) +# define SAM_FLEXUS0_BRGR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_BRGR_OFFSET) +# define SAM_FLEXUS0_RTOR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_RTOR_OFFSET) +# define SAM_FLEXUS0_TTGR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_TTGR_OFFSET) +# define SAM_FLEXUS0_FIDI (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FIDI_OFFSET) +# define SAM_FLEXUS0_NER (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_NER_OFFSET) +# define SAM_FLEXUS0_IF (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_IF_OFFSET) +# define SAM_FLEXUS0_MAN (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS0_LINMR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_LINMR_OFFSET) +# define SAM_FLEXUS0_LINIR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_LINIR_OFFSET) +# define SAM_FLEXUS0_LINBRR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_LINBRR_OFFSET) +# define SAM_FLEXUS0_CMPR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_CMPR_OFFSET) +# define SAM_FLEXUS0_FMR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FMR_OFFSET) +# define SAM_FLEXUS0_FLR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FLR_OFFSET) +# define SAM_FLEXUS0_FIER (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FIER_OFFSET) +# define SAM_FLEXUS0_FIDR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FIDR_OFFSET) +# define SAM_FLEXUS0_FIMR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FIMR_OFFSET) +# define SAM_FLEXUS0_FESR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_FESR_OFFSET) +# define SAM_FLEXUS0_WPMR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_WPMR_OFFSET) +# define SAM_FLEXUS0_WPSR (SAM_FLEXCOM0_VBASE+SAM_FLEXUS_WPSR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM1 +# define SAM_FLEXUS1_CR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_CR_OFFSET) +# define SAM_FLEXUS1_MR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_MR_OFFSET) +# define SAM_FLEXUS1_IER (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_IER_OFFSET) +# define SAM_FLEXUS1_IDR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_IDR_OFFSET) +# define SAM_FLEXUS1_IMR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_IMR_OFFSET) +# define SAM_FLEXUS1_CSR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_CSR_OFFSET) +# define SAM_FLEXUS1_RHR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_RHR_OFFSET) +# define SAM_FLEXUS1_THR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_THR_OFFSET) +# define SAM_FLEXUS1_BRGR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_BRGR_OFFSET) +# define SAM_FLEXUS1_RTOR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_RTOR_OFFSET) +# define SAM_FLEXUS1_TTGR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_TTGR_OFFSET) +# define SAM_FLEXUS1_FIDI (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FIDI_OFFSET) +# define SAM_FLEXUS1_NER (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_NER_OFFSET) +# define SAM_FLEXUS1_IF (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_IF_OFFSET) +# define SAM_FLEXUS1_MAN (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS1_MAN (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS1_LINMR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_LINMR_OFFSET) +# define SAM_FLEXUS1_LINIR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_LINIR_OFFSET) +# define SAM_FLEXUS1_LINBRR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_LINBRR_OFFSET) +# define SAM_FLEXUS1_CMPR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_CMPR_OFFSET) +# define SAM_FLEXUS1_FMR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FMR_OFFSET) +# define SAM_FLEXUS1_FLR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FLR_OFFSET) +# define SAM_FLEXUS1_FIER (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FIER_OFFSET) +# define SAM_FLEXUS1_FIDR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FIDR_OFFSET) +# define SAM_FLEXUS1_FIMR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FIMR_OFFSET) +# define SAM_FLEXUS1_FESR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_FESR_OFFSET) +# define SAM_FLEXUS1_WPMR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_WPMR_OFFSET) +# define SAM_FLEXUS1_WPSR (SAM_FLEXCOM1_VBASE+SAM_FLEXUS_WPSR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM2 +# define SAM_FLEXUS2_CR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_CR_OFFSET) +# define SAM_FLEXUS2_MR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_MR_OFFSET) +# define SAM_FLEXUS2_IER (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_IER_OFFSET) +# define SAM_FLEXUS2_IDR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_IDR_OFFSET) +# define SAM_FLEXUS2_IMR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_IMR_OFFSET) +# define SAM_FLEXUS2_CSR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_CSR_OFFSET) +# define SAM_FLEXUS2_RHR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_RHR_OFFSET) +# define SAM_FLEXUS2_THR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_THR_OFFSET) +# define SAM_FLEXUS2_BRGR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_BRGR_OFFSET) +# define SAM_FLEXUS2_RTOR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_RTOR_OFFSET) +# define SAM_FLEXUS2_TTGR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_TTGR_OFFSET) +# define SAM_FLEXUS2_FIDI (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FIDI_OFFSET) +# define SAM_FLEXUS2_NER (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_NER_OFFSET) +# define SAM_FLEXUS2_IF (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_IF_OFFSET) +# define SAM_FLEXUS2_MAN (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS2_MAN (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS2_LINMR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_LINMR_OFFSET) +# define SAM_FLEXUS2_LINIR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_LINIR_OFFSET) +# define SAM_FLEXUS2_LINBRR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_LINBRR_OFFSET) +# define SAM_FLEXUS2_CMPR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_CMPR_OFFSET) +# define SAM_FLEXUS2_FMR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FMR_OFFSET) +# define SAM_FLEXUS2_FLR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FLR_OFFSET) +# define SAM_FLEXUS2_FIER (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FIER_OFFSET) +# define SAM_FLEXUS2_FIDR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FIDR_OFFSET) +# define SAM_FLEXUS2_FIMR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FIMR_OFFSET) +# define SAM_FLEXUS2_FESR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_FESR_OFFSET) +# define SAM_FLEXUS2_WPMR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_WPMR_OFFSET) +# define SAM_FLEXUS2_WPSR (SAM_FLEXCOM2_VBASE+SAM_FLEXUS_WPSR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM3 +# define SAM_FLEXUS3_CR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_CR_OFFSET) +# define SAM_FLEXUS3_MR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_MR_OFFSET) +# define SAM_FLEXUS3_IER (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_IER_OFFSET) +# define SAM_FLEXUS3_IDR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_IDR_OFFSET) +# define SAM_FLEXUS3_IMR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_IMR_OFFSET) +# define SAM_FLEXUS3_CSR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_CSR_OFFSET) +# define SAM_FLEXUS3_RHR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_RHR_OFFSET) +# define SAM_FLEXUS3_THR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_THR_OFFSET) +# define SAM_FLEXUS3_BRGR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_BRGR_OFFSET) +# define SAM_FLEXUS3_RTOR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_RTOR_OFFSET) +# define SAM_FLEXUS3_TTGR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_TTGR_OFFSET) +# define SAM_FLEXUS3_FIDI (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FIDI_OFFSET) +# define SAM_FLEXUS3_NER (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_NER_OFFSET) +# define SAM_FLEXUS3_IF (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_IF_OFFSET) +# define SAM_FLEXUS3_MAN (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS3_MAN (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS3_LINMR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_LINMR_OFFSET) +# define SAM_FLEXUS3_LINIR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_LINIR_OFFSET) +# define SAM_FLEXUS3_LINBRR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_LINBRR_OFFSET) +# define SAM_FLEXUS3_CMPR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_CMPR_OFFSET) +# define SAM_FLEXUS3_FMR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FMR_OFFSET) +# define SAM_FLEXUS3_FLR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FLR_OFFSET) +# define SAM_FLEXUS3_FIER (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FIER_OFFSET) +# define SAM_FLEXUS3_FIDR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FIDR_OFFSET) +# define SAM_FLEXUS3_FIMR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FIMR_OFFSET) +# define SAM_FLEXUS3_FESR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_FESR_OFFSET) +# define SAM_FLEXUS3_WPMR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_WPMR_OFFSET) +# define SAM_FLEXUS3_WPSR (SAM_FLEXCOM3_VBASE+SAM_FLEXUS_WPSR_OFFSET) +#endif + +#ifdef CONFIG_SAMA5_HAVE_FLEXCOM4 +# define SAM_FLEXUS4_CR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_CR_OFFSET) +# define SAM_FLEXUS4_MR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_MR_OFFSET) +# define SAM_FLEXUS4_IER (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_IER_OFFSET) +# define SAM_FLEXUS4_IDR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_IDR_OFFSET) +# define SAM_FLEXUS4_IMR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_IMR_OFFSET) +# define SAM_FLEXUS4_CSR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_CSR_OFFSET) +# define SAM_FLEXUS4_RHR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_RHR_OFFSET) +# define SAM_FLEXUS4_THR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_THR_OFFSET) +# define SAM_FLEXUS4_BRGR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_BRGR_OFFSET) +# define SAM_FLEXUS4_RTOR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_RTOR_OFFSET) +# define SAM_FLEXUS4_TTGR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_TTGR_OFFSET) +# define SAM_FLEXUS4_FIDI (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FIDI_OFFSET) +# define SAM_FLEXUS4_NER (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_NER_OFFSET) +# define SAM_FLEXUS4_IF (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_IF_OFFSET) +# define SAM_FLEXUS4_MAN (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS4_MAN (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_MAN_OFFSET) +# define SAM_FLEXUS4_LINMR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_LINMR_OFFSET) +# define SAM_FLEXUS4_LINIR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_LINIR_OFFSET) +# define SAM_FLEXUS4_LINBRR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_LINBRR_OFFSET) +# define SAM_FLEXUS4_CMPR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_CMPR_OFFSET) +# define SAM_FLEXUS4_FMR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FMR_OFFSET) +# define SAM_FLEXUS4_FLR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FLR_OFFSET) +# define SAM_FLEXUS4_FIER (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FIER_OFFSET) +# define SAM_FLEXUS4_FIDR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FIDR_OFFSET) +# define SAM_FLEXUS4_FIMR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FIMR_OFFSET) +# define SAM_FLEXUS4_FESR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_FESR_OFFSET) +# define SAM_FLEXUS4_WPMR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_WPMR_OFFSET) +# define SAM_FLEXUS4_WPSR (SAM_FLEXCOM4_VBASE+SAM_FLEXUS_WPSR_OFFSET) +#endif + +/* USART register bit definitions ****************************************************************/ +/* USART Control Register */ + +#define FLEXUS_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver */ +#define FLEXUS_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter */ +#define FLEXUS_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable */ +#define FLEXUS_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable */ +#define FLEXUS_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable */ +#define FLEXUS_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable */ +#define FLEXUS_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits */ +#define FLEXUS_CR_STTBRK (1 << 9) /* Bit 9: Start Break */ +#define FLEXUS_CR_STPBRK (1 << 10) /* Bit 10: Stop Break */ +#define FLEXUS_CR_STTTO (1 << 11) /* Bit 11: Start Time-out */ +#define FLEXUS_CR_SENDA (1 << 12) /* Bit 12: Send Address */ +#define FLEXUS_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations */ +#define FLEXUS_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge */ +#define FLEXUS_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out */ +#define FLEXUS_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable */ +#define FLEXUS_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable */ +#define FLEXUS_CR_LINABT (1 << 20) /* Bit 20: Abort LIN Transmission */ +#define FLEXUS_CR_LINWKUP (1 << 21) /* Bit 21: Send LIN Wake-up Signal */ +#define FLEXUS_CR_TXFCLR (1 << 24) /* Bit 24: Transmit FIFO Clear */ +#define FLEXUS_CR_RXFCLR (1 << 25) /* Bit 25: Receive FIFO Clear */ +#define FLEXUS_CR_TXFLCLR (1 << 26) /* Bit 26: Transmit FIFO Lock CLEAR */ +#define FLEXUS_CR_REQCLR (1 << 28) /* Bit 28: Request to Clear the Comparison Trigger */ +#define FLEXUS_CR_FIFOEN (1 << 30) /* Bit 30: FIFO Enable */ +#define FLEXUS_CR_FIFODIS (1 << 31) /* Bit 31: FIFO Disable */ + +/* USART Mode Register and FLEXUS Mode Register */ + +#define FLEXUS_MR_MODE_SHIFT (0) /* Bits 0-3: USART Mode of Operation */ +#define FLEXUS_MR_MODE_MASK (15 << FLEXUS_MR_MODE_SHIFT) +# define FLEXUS_MR_MODE_NORMAL (0 << FLEXUS_MR_MODE_SHIFT) /* Normal */ +# define FLEXUS_MR_MODE_RS485 (1 << FLEXUS_MR_MODE_SHIFT) /* RS485 */ +# define FLEXUS_MR_MODE_HWHS (2 << FLEXUS_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define FLEXUS_MR_MODE_ISO7816_0 (4 << FLEXUS_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */ +# define FLEXUS_MR_MODE_ISO7816_1 (6 << FLEXUS_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */ +# define FLEXUS_MR_MODE_IRDA (8 << FLEXUS_MR_MODE_SHIFT) /* IrDA */ +# define FLEXUS_MR_MODE_LINMASTER (10 << FLEXUS_MR_MODE_SHIFT) /* LIN master */ +# define FLEXUS_MR_MODE_LINSLAVE (11 << FLEXUS_MR_MODE_SHIFT) /* LIN slave */ +#define FLEXUS_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection */ +#define FLEXUS_MR_USCLKS_MASK (3 << FLEXUS_MR_USCLKS_SHIFT) +# define FLEXUS_MR_USCLKS_MCK (0 << FLEXUS_MR_USCLKS_SHIFT) /* MCK */ +# define FLEXUS_MR_USCLKS_MCKDIV (1 << FLEXUS_MR_USCLKS_SHIFT) /* MCK/DIV (DIV = 8) */ +# define FLEXUS_MR_USCLKS_PMCPCK (2 << FLEXUS_MR_USCLKS_SHIFT) /* PMC Programmable clock */ +# define FLEXUS_MR_USCLKS_SCK (3 << FLEXUS_MR_USCLKS_SHIFT) /* ExtenaleSCK */ +#define FLEXUS_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length */ +#define FLEXUS_MR_CHRL_MASK (3 << FLEXUS_MR_CHRL_SHIFT) +# define FLEXUS_MR_CHRL_5BITS (0 << FLEXUS_MR_CHRL_SHIFT) /* 5 bits */ +# define FLEXUS_MR_CHRL_6BITS (1 << FLEXUS_MR_CHRL_SHIFT) /* 6 bits */ +# define FLEXUS_MR_CHRL_7BITS (2 << FLEXUS_MR_CHRL_SHIFT) /* 7 bits */ +# define FLEXUS_MR_CHRL_8BITS (3 << FLEXUS_MR_CHRL_SHIFT) /* 8 bits */ +#define FLEXUS_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select */ +#define FLEXUS_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type */ +#define FLEXUS_MR_PAR_MASK (7 << FLEXUS_MR_PAR_SHIFT) +# define FLEXUS_MR_PAR_EVEN (0 << FLEXUS_MR_PAR_SHIFT) /* Even parity */ +# define FLEXUS_MR_PAR_ODD (1 << FLEXUS_MR_PAR_SHIFT) /* Odd parity */ +# define FLEXUS_MR_PAR_SPACE (2 << FLEXUS_MR_PAR_SHIFT) /* Space: parity forced to 0 */ +# define FLEXUS_MR_PAR_MARK (3 << FLEXUS_MR_PAR_SHIFT) /* Mark: parity forced to 1 */ +# define FLEXUS_MR_PAR_NONE (4 << FLEXUS_MR_PAR_SHIFT) /* No parity */ +# define FLEXUS_MR_PAR_MULTIDROP (6 << FLEXUS_MR_PAR_SHIFT) /* Multidrop mode */ +#define FLEXUS_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits */ +#define FLEXUS_MR_NBSTOP_MASK (3 << FLEXUS_MR_NBSTOP_SHIFT) +# define FLEXUS_MR_NBSTOP_1 (0 << FLEXUS_MR_NBSTOP_SHIFT) /* 1 stop bit 1 stop bit */ +# define FLEXUS_MR_NBSTOP_1p5 (1 << FLEXUS_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define FLEXUS_MR_NBSTOP_2 (2 << FLEXUS_MR_NBSTOP_SHIFT) /* 2 stop bits 2 stop bits */ +#define FLEXUS_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode */ +#define FLEXUS_MR_CHMODE_MASK (3 << FLEXUS_MR_CHMODE_SHIFT) +# define FLEXUS_MR_CHMODE_NORMAL (0 << FLEXUS_MR_CHMODE_SHIFT) /* Normal Mode */ +# define FLEXUS_MR_CHMODE_ECHO (1 << FLEXUS_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define FLEXUS_MR_CHMODE_LLPBK (2 << FLEXUS_MR_CHMODE_SHIFT) /* Local Loopback */ +# define FLEXUS_MR_CHMODE_RLPBK (3 << FLEXUS_MR_CHMODE_SHIFT) /* Remote Loopback */ +#define FLEXUS_MR_MSBF (1 << 16) /* Bit 16: Most Significant Bit first */ +#define FLEXUS_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length */ +#define FLEXUS_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select */ +#define FLEXUS_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode */ +#define FLEXUS_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge */ +#define FLEXUS_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK */ +#define FLEXUS_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter */ +#define FLEXUS_MR_INVDATA (1 << 23) /* Bit 23: Inverted Data */ +#define FLEXUS_MR_MAXITER_SHIFT (24) /* Bits 24-26: Max iterations (ISO7816 T=0 */ +#define FLEXUS_MR_MAXITER_MASK (7 << FLEXUS_MR_MAXITER_SHIFT) +# define FLEXUS_MR_MAXITER(n) ((uint32_t)(n) << FLEXUS_MR_MAXITER_SHIFT) +#define FLEXUS_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter */ +#define FLEXUS_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable () */ +#define FLEXUS_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode */ +#define FLEXUS_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector */ + +/* USART Interrupt Enable Register, USART Interrupt Disable Register, USART Interrupt Mask + * Register, and USART Status Register common bit field definitions + */ + +#define FLEXUS_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt */ +#define FLEXUS_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt */ +#define FLEXUS_INT_RXBRK (1 << 2) /* Bit 2: Break Received/End of Break (USART mode) */ +#define FLEXUS_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt */ +#define FLEXUS_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt */ +#define FLEXUS_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt */ +#define FLEXUS_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt */ +#define FLEXUS_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt */ +#define FLEXUS_INT_ITER (1 << 10) /* Bit 10: Iteration Interrupt (USART mode) */ +#define FLEXUS_INT_NACK (1 << 13) /* Bit 13: Non Acknowledge Interrupt (USART mode) */ +#define FLEXUS_INT_LINBK (1 << 13) /* Bit 13: LIN Break Sent or LIN Break Received Interrupt (LIN mode) */ +#define FLEXUS_INT_LINID (1 << 14) /* Bit 14: LIN Identifier Sent or LIN Identifier Received Interrupt (LIN mode) */ +#define FLEXUS_INT_LINTC (1 << 15) /* Bit 15: LIN Transfer Completed Interrupt (Lin mode) */ +#define FLEXUS_INT_CTSIC (1 << 19) /* Bit 19: Clear to Send Input Change Interrupt (USART mode) */ +#define FLEXUS_INT_CMP (1 << 22) /* Bit 22: Comparison Interrupt (USART mode) */ +#define FLEXUS_CSR_CTS (1 << 23) /* Bit 23: Image of CTS Input (CSR only, UART mode) */ +#define FLEXUS_CSR_LINBLS (1 << 23) /* Bit 23: LIN Bus Line Status (CSR only, LIN mode) */ +#define FLEXUS_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt (USART mode) */ +#define FLEXUS_INT_LINBE (1 << 25) /* Bit 25: LIN Bus Error Interrupt (LIN mode) */ +#define FLEXUS_INT_LINISFE (1 << 26) /* Bit 26: LIN Inconsistent Synch Field Error Interrupt (LIN mode) */ +#define FLEXUS_INT_LINIPE (1 << 27) /* Bit 27: LIN Identifier Parity Interrupt (LIN mode) */ +#define FLEXUS_INT_LINCE (1 << 28) /* Bit 28: LIN Checksum Error Interrupt (LIN mode) */ +#define FLEXUS_INT_LINSNRE (1 << 29) /* Bit 29: LIN Slave Not Responding Error Interrupt (LIN mode) */ +#define FLEXUS_INT_LINSTE (1 << 30) /* Bit 30: LIN Synch Tolerance Error Interrupt (LIN mode) */ +#define FLEXUS_INT_LINHTE (1 << 31) /* Bit 31: LIN Header Timeout Error Interrupt (LIN mode) */ + +#define FLEXUS_INT_ALLINTS 0xff48e7e7 + +/* USART Receiver Holding Register */ + +#define FLEXUS_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character */ +#define FLEXUS_RHR_RXCHR_MASK (0x1ff << FLEXUS_RHR_RXCHR_SHIFT) +# define FLEXUS_RHR_RXCHR(n) ((uint32_t)(n) << FLEXUS_RHR_RXCHR_SHIFT) +#define FLEXUS_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync */ + +#define FLEXUS_RHR_RXCHR0_SHIFT (0) /* Bits 0-7: Received Character */ +#define FLEXUS_RHR_RXCHR0_MASK (0xff << FLEXUS_RHR_RXCHR0_SHIFT) +# define FLEXUS_RHR_RXCHR0(n) ((uint32_t)(n) << FLEXUS_RHR_RXCHR0_SHIFT) +#define FLEXUS_RHR_RXCHR1_SHIFT (8) /* Bits 8-15: Received Character */ +#define FLEXUS_RHR_RXCHR1_MASK (0xff << FLEXUS_RHR_RXCHR1_SHIFT) +# define FLEXUS_RHR_RXCHR1(n) ((uint32_t)(n) << FLEXUS_RHR_RXCHR1_SHIFT) +#define FLEXUS_RHR_RXCHR2_SHIFT (16) /* Bits 16-23: Received Character */ +#define FLEXUS_RHR_RXCHR2_MASK (0xff << FLEXUS_RHR_RXCHR2_SHIFT) +# define FLEXUS_RHR_RXCHR2(n) ((uint32_t)(n) << FLEXUS_RHR_RXCHR2_SHIFT) +#define FLEXUS_RHR_RXCHR3_SHIFT (24) /* Bits 24-31: Received Character */ +#define FLEXUS_RHR_RXCHR3_MASK (0xff << FLEXUS_RHR_RXCHR3_SHIFT) +# define FLEXUS_RHR_RXCHR3(n) ((uint32_t)(n) << FLEXUS_RHR_RXCHR3_SHIFT) + +/* USART Transmit Holding Register */ + +#define FLEXUS_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be transmitted */ +#define FLEXUS_THR_TXCHR_MASK (0x1ff << FLEXUS_THR_TXCHR_SHIFT) +#define FLEXUS_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be tran */ + +#define FLEXUS_THR_TXCHR0_SHIFT (0) /* Bits 0-7: Character to be transmitted */ +#define FLEXUS_THR_TXCHR0_MASK (0xff << FLEXUS_THR_TXCHR0_SHIFT) +# define FLEXUS_THR_TXCHR0(n) ((uint32_t)(n) << FLEXUS_THR_TXCHR0_SHIFT) +#define FLEXUS_THR_TXCHR1_SHIFT (8) /* Bits 8-15: Character to be transmitted */ +#define FLEXUS_THR_TXCHR1_MASK (0xff << FLEXUS_THR_TXCHR1_SHIFT) +# define FLEXUS_THR_TXCHR1(n) ((uint32_t)(n) << FLEXUS_THR_TXCHR1_SHIFT) +#define FLEXUS_THR_TXCHR2_SHIFT (16) /* Bits 16-23: Character to be transmitted */ +#define FLEXUS_THR_TXCHR2_MASK (0xff << FLEXUS_THR_TXCHR2_SHIFT) +# define FLEXUS_THR_TXCHR2(n) ((uint32_t)(n) << FLEXUS_THR_TXCHR2_SHIFT) +#define FLEXUS_THR_TXCHR3_SHIFT (24) /* Bits 24-31: Character to be transmitted */ +#define FLEXUS_THR_TXCHR3_MASK (0xff << FLEXUS_THR_TXCHR3_SHIFT) +# define FLEXUS_THR_TXCHR3(n) ((uint32_t)(n) << FLEXUS_THR_TXCHR3_SHIFT) + +/* USART Baud Rate Generator Register */ + +#define FLEXUS_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor */ +#define FLEXUS_BRGR_CD_MASK (0xffff << FLEXUS_BRGR_CD_SHIFT) +# define FLEXUS_BRGR_CD(n) ((uint32_t)(n) << FLEXUS_BRGR_CD_SHIFT) +#define FLEXUS_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part */ +#define FLEXUS_BRGR_FP_MASK (7 << FLEXUS_BRGR_FP_SHIFT) +# define FLEXUS_BRGR_FP(n) ((uint32_t)(n) << FLEXUS_BRGR_FP_SHIFT) + +/* FLEXUS Receiver Time-out Register */ + +#define FLEXUS_RTOR_TO_SHIFT (0) /* Bits 0-16: Time-out Value */ +#define FLEXUS_RTOR_TO_MASK (0x1ffff << FLEXUS_RTOR_TO_SHIFT) + +/* FLEXUS Transmitter Timeguard Register */ + +#define FLEXUS_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value */ +#define FLEXUS_TTGR_TG_MASK (0xff << FLEXUS_TTGR_TG_SHIFT) + +/* FLEXUS FI DI RATIO Register */ + +#define FLEXUS_FIDI_RATIO_SHIFT (0) /* Bits 0-15: FI Over DI Ratio Value */ +#define FLEXUS_FIDI_RATIO_MASK (0xffff << FLEXUS_FIDI_RATIO_SHIFT) + +/* FLEXUS Number of Errors Register */ + +#define FLEXUS_NER_NBERRORS_SHIFT (0) /* Bits 0-7: Number of Errrors */ +#define FLEXUS_NER_NBERRORS_MASK (0xff << FLEXUS_NER_NBERRORS_SHIFT) + +/* FLEXUS IrDA FILTER Register */ + +#define FLEXUS_IF_IRDAFILTER_SHIFT (0) /* Bits 0-7: IrDA Filter */ +#define FLEXUS_IF_IRDAFILTER_MASK (0xff << FLEXUS_IF_IRDAFILTER_SHIFT) + +/* FLEXUS Manchester Configuration Register */ + +#define FLEXUS_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length */ +#define FLEXUS_MAN_TXPL_MASK (15 << FLEXUS_MAN_TXPL_SHIFT) +# define FLEXUS_MAN_TXPL(n) ((uint32_t)(n) << FLEXUS_MAN_TXPL_SHIFT) +#define FLEXUS_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern */ +#define FLEXUS_MAN_TXPP_MASK (3 << FLEXUS_MAN_TXPP_SHIFT) +# define FLEXUS_MAN_TXPP_ALLONE (0 << FLEXUS_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define FLEXUS_MAN_TXPP_ALLZERO (1 << FLEXUS_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define FLEXUS_MAN_TXPP_ZEROONE (2 << FLEXUS_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define FLEXUS_MAN_TXPP_ONEZERO (3 << FLEXUS_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define FLEXUS_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity */ +#define FLEXUS_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length */ +#define FLEXUS_MAN_RXPL_MASK (15 << FLEXUS_MAN_RXPL_SHIFT) +# define FLEXUS_MAN_RXPL(n) ((uint32_t)(n) << FLEXUS_MAN_RXPL_SHIFT) +#define FLEXUS_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected */ +#define FLEXUS_MAN_RXPP_MASK (3 << FLEXUS_MAN_RXPP_SHIFT) +# define FLEXUS_MAN_RXPP_ALLONE (0 << FLEXUS_MAN_RXPP_SHIFT) /* ALL_ONE */ +# define FLEXUS_MAN_RXPP_ALLZERO (1 << FLEXUS_MAN_RXPP_SHIFT) /* ALL_ZERO */ +# define FLEXUS_MAN_RXPP_ZEROONE (2 << FLEXUS_MAN_RXPP_SHIFT) /* ZERO_ONE */ +# define FLEXUS_MAN_RXPP_ONEZERO (3 << FLEXUS_MAN_RXPP_SHIFT) /* ONE_ZERO */ +#define FLEXUS_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity */ +#define FLEXUS_MAN_ONE (1 << 29) /* Bit 29: Must Be Set to 1 */ +#define FLEXUS_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation */ +#define FLEXUS_MAN_RXIDLEV (1 << 31) /* Bit 31: Receiver idle value */ + +/* USART LIN Mode Register */ + +#define FLEXUS_LINMR_NACT_SHIFT (0) /* Bits 0-1: LIN Node Action */ +#define FLEXUS_LINMR_NACT_MASK (3 << FLEXUS_LINMR_NACT_SHIFT) +# define FLEXUS_LINMR_NACT_PUBLISH (0 << FLEXUS_LINMR_NACT_SHIFT) /* USART transmits response */ +# define FLEXUS_LINMR_NACT_SUBSCRIBE (1 << FLEXUS_LINMR_NACT_SHIFT) /* USART receives response */ +# define FLEXUS_LINMR_NACT_IGNORE (2 << FLEXUS_LINMR_NACT_SHIFT) /* USART does not transmit or receive response */ +#define FLEXUS_LINMR_PARDIS (1 << 2) /* Bit 2: Parity Disable */ +#define FLEXUS_LINMR_CHKDIS (1 << 3) /* Bit 3: Checksum Disable */ +#define FLEXUS_LINMR_CHKTYP (1 << 4) /* Bit 4: Checksum Type */ +#define FLEXUS_LINMR_DLM (1 << 5) /* Bit 5: Data Length Mode */ +#define FLEXUS_LINMR_FSDIS (1 << 6) /* Bit 6: Frame Slot Mode Disable */ +#define FLEXUS_LINMR_WKUPTYP (1 << 7) /* Bit 7: Wakeup Signal Type */ +#define FLEXUS_LINMR_DLC_SHIFT (8) /* Bits 8-15: Data Length Control */ +#define FLEXUS_LINMR_DLC_MASK (0xff << FLEXUS_LINMR_DLC_SHIFT) +# define FLEXUS_LINMR_DLC(n) ((uint32_t)(n) << FLEXUS_LINMR_DLC_SHIFT) +#define FLEXUS_LINMR_PDCM (1 << 16) /* Bit 16: DMAC Mode */ +#define FLEXUS_LINMR_SYNCDIS (1 << 17) /* Bit 17: Synchronization Disable */ + +/* USART LIN Identifier Register */ + +#define FLEXUS_LINIR_MASK 0xff /* Bits 0-7: Identifier Character */ + +/* USART LIN Baud Rate Register */ + +#define FLEXUS_LINBRR_LINCD_SHIFT (0) /* Bits 0-15: Clock Divider after Synchronization */ +#define FLEXUS_LINBRR_LINCD_MASK (0xffff << FLEXUS_LINBRR_LINCD_SHIFT) +# define FLEXUS_LINBRR_LINCD(n) ((uint32_t)(n) << FLEXUS_LINBRR_LINCD_SHIFT) +#define FLEXUS_LINBRR_LINFP_SHIFT (16) /* Bits 16-18: Fractional Part after Synchronization */ +#define FLEXUS_LINBRR_LINFP_MASK (7 << FLEXUS_LINBRR_LINFP_SHIFT) +# define FLEXUS_LINBRR_LINFP(n) ((uint32_t)(n) << FLEXUS_LINBRR_LINFP_SHIFT) + +/* USART Comparison Register */ + +# define FLEXUS_CMPR_VAL1_SHIFT (0) /* Bits 0-8: First Comparison Value for Received Character */ +# define FLEXUS_CMPR_VAL1_MASK (0x1ff << FLEXUS_CMPR_VAL1_SHIFT) +# define FLEXUS_CMPR_VAL1(n) ((uint32_t)(n) << FLEXUS_CMPR_VAL1_SHIFT) +# define FLEXUS_CMPR_CMPMODE (1 << 12) /* Bit 12: Comparison Mode */ +# define FLEXUS_CMPR_FLAG (0) /* Bit 12: 0=Any character + comparison function */ +# define FLEXUS_CMPR_START (1 << 12) /* Bit 12: 1=Comparison condition required to start */ +# define FLEXUS_CMPR_CMPPAR (1 << 14) /* Bit 14: Compare Parity */ +# define FLEXUS_CMPR_VAL2_SHIFT (16) /* Bits 16-24: Second Comparison Value for Received Character */ +# define FLEXUS_CMPR_VAL2_MASK (0x1ff << FLEXUS_CMPR_VAL2_SHIFT) +# define FLEXUS_CMPR_VAL2(n) ((uint32_t)(n) << FLEXUS_CMPR_VAL2_SHIFT) + +/* USART FIFO Mode Register */ + +#define FLEXUS_FMR_TXRDYM_SHIFT (0) /* Bits 0-1: Transmitter Ready Mode */ +#define FLEXUS_FMR_TXRDYM_MASK (3 << FLEXUS_FMR_TXRDYM_SHIFT) +# define FLEXUS_FMR_TXRDYM_ONE (0 << FLEXUS_FMR_TXRDYM_SHIFT) /* TXRDY level 1 when can write one data */ +# define FLEXUS_FMR_TXRDYM_TWO (1 << FLEXUS_FMR_TXRDYM_SHIFT) /* TXRDY level 1 when can write two data */ +# define FLEXUS_FMR_TXRDYM_FOUR (2 << FLEXUS_FMR_TXRDYM_SHIFT) /* TXRDY level 1 when can write four data */ +#define FLEXUS_FMR_RXRDYM_SHIFT (4) /* Bits 4-5: Receiver Ready Mode */ +#define FLEXUS_FMR_RXRDYM_MASK (3 << FLEXUS_FMR_RXRDYM_SHIFT) +# define FLEXUS_FMR_RXRDYM_ONE (0 << FLEXUS_FMR_RXRDYM_SHIFT) /* TXRDY level 1 when can read one data */ +# define FLEXUS_FMR_RXRDYM_TWO (1 << FLEXUS_FMR_RXRDYM_SHIFT) /* TXRDY level 1 when can read two data */ +# define FLEXUS_FMR_RXRDYM_FOUR (2 << FLEXUS_FMR_RXRDYM_SHIFT) /* TXRDY level 1 when can read four data */ +#define FLEXUS_FMR_FRTSC (1 << 7) /* Bit 7: FIFO RTS pin Control enable */ +#define FLEXUS_FMR_TXFTHRES_SHIFT (8) /* Bits 8-13: Transmit FIFO Threshold */ +#define FLEXUS_FMR_TXFTHRES_MASK (0x3f << FLEXUS_FMR_TXFTHRES_SHIFT) +# define FLEXUS_FMR_TXFTHRES(n) ((uint32_t)(n) << FLEXUS_FMR_TXFTHRES_SHIFT) +#define FLEXUS_FMR_RXFTHRES_SHIFT (16) /* Bits 16-21: Receive FIFO Threshold */ +#define FLEXUS_FMR_RXFTHRES_MASK (0x3f << FLEXUS_FMR_RXFTHRES_SHIFT) +# define FLEXUS_FMR_RXFTHRES(n) (0x(uint32_t)(n)3f << FLEXUS_FMR_RXFTHRES_SHIFT) +#define FLEXUS_FMR_RXFTHRES2_SHIFT (24) /* Bits 24-29: Receive FIFO Threshold 2 */ +#define FLEXUS_FMR_RXFTHRES2_MASK (0x3f << FLEXUS_FMR_RXFTHRES2_SHIFT) +# define FLEXUS_FMR_RXFTHRES2(n) ((uint32_t)(n) << FLEXUS_FMR_RXFTHRES2_SHIFT) + +/* USART FIFO Level Register */ + +#define FLEXUS_FLR_TXFL_SHIFT (0) /* Bits 0-5: Transmit FIFO Level */ +#define FLEXUS_FLR_TXFL_MASK (0x3f << FLEXUS_FLR_TXFL_SHIFT) +# define FLEXUS_FLR_TXFL(n) ((uint32_t)(n) << FLEXUS_FLR_TXFL_SHIFT) +#define FLEXUS_FLR_RXFL_SHIFT (16) /* Bits 0-21: Receive FIFO Level */ +#define FLEXUS_FLR_RXFL_MASK (0x3f << FLEXUS_FLR_RXFL_SHIFT) +# define FLEXUS_FLR_RXFL(n) ((uint32_t)(n) << FLEXUS_FLR_RXFL_SHIFT) + +/* USART FIFO Interrupt Enable Register, USART FIFO Interrupt Disable Register, USART FIFO + * Interrupt Mask Register, and USART FIFO Event Status Register. + */ + +#define FLEXUS_FINT_TXFEF (1 << 0) /* Bit 0: Transmit FIFO Empty Interrupt */ +#define FLEXUS_FINT_TXFFF (1 << 1) /* Bit 1: Transmit FIFO Full Interrupt */ +#define FLEXUS_FINT_TXFTHF (1 << 2) /* Bit 2: Transmit FIFO Threshold Interrupt */ +#define FLEXUS_FINT_RXFEF (1 << 3) /* Bit 3: Receive FIFO Empty FInterruptlag */ +#define FLEXUS_FINT_RXFFF (1 << 4) /* Bit 4: Receive FIFO Full Interrupt */ +#define FLEXUS_FINT_RXFTHF (1 << 5) /* Bit 5: Receive FIFO Threshold Interrupt */ +#define FLEXUS_FINT_TXFPTEF (1 << 6) /* Bit 6: Transmit FIFO Pointer Error Interrupt */ +#define FLEXUS_FINT_RXFPTEF (1 << 7) /* Bit 7: Receive FIFO Pointer Error Interrupt */ +#define FLEXUS_FISR_TXFLOCK (1 << 8) /* Bit 8: Transmit FIFO Lock (FESR only) */ +#define FLEXUS_FINT_RXFTHF2 (1 << 9) /* Bit 9: Receive FIFO Threshold Interrupt 2 */ + +/* USART Write Protect Mode Register (USART only) */ + +#define FLEXUS_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable (USART only) */ +#define FLEXUS_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (USART only) */ +#define FLEXUS_WPMR_WPKEY_MASK (0x00ffffff << FLEXUS_WPMR_WPKEY_SHIFT) +# define FLEXUSWPMR_WPKEY (0x00555341 << FLEXUS_WPMR_WPKEY_SHIFT) /* "USA" */ + +/* USART Write Protect Status Register (USART only) */ + +#define FLEXUS_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status (USART only) */ +#define FLEXUS_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source (USART only) */ +#define FLEXUS_WPSR_WPVSRC_MASK (0xffff << FLEXUS_WPSR_WPVSRC_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_FLEXCOM_FLEXUS_H */ diff --git a/arch/arm/src/sama5/chip/sam_gmac.h b/arch/arm/src/sama5/chip/sam_gmac.h new file mode 100644 index 0000000000000000000000000000000000000000..27496fec2ade1bd2c0f37c4ea5548aa3cfd70992 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_gmac.h @@ -0,0 +1,1014 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_gmac.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GMAC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GMAC Register Offsets ************************************************************/ + +#define SAM_GMAC_NCR_OFFSET 0x0000 /* Network Control Register */ +#define SAM_GMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */ +#define SAM_GMAC_NSR_OFFSET 0x0008 /* Network Status Register */ +#define SAM_GMAC_UR_OFFSET 0x000c /* User Register */ +#define SAM_GMAC_DCFGR_OFFSET 0x0010 /* DMA Configuration Register */ +#define SAM_GMAC_TSR_OFFSET 0x0014 /* Transmit Status Register */ +#define SAM_GMAC_RBQB_OFFSET 0x0018 /* Receive Buffer Queue Base Address */ +#define SAM_GMAC_TBQB_OFFSET 0x001c /* Transmit Buffer Queue Base Address */ +#define SAM_GMAC_RSR_OFFSET 0x0020 /* Receive Status Register */ +#define SAM_GMAC_ISR_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_GMAC_IER_OFFSET 0x0028 /* Interrupt Enable Register */ +#define SAM_GMAC_IDR_OFFSET 0x002c /* Interrupt Disable Register */ +#define SAM_GMAC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_GMAC_MAN_OFFSET 0x0034 /* PHY Maintenance Register */ +#define SAM_GMAC_RPQ_OFFSET 0x0038 /* Received Pause Quantum Register */ +#define SAM_GMAC_TPQ_OFFSET 0x003c /* Transmit Pause Quantum Register */ +#define SAM_GMAC_TPSF_OFFSET 0x0040 /* TX Partial Store and Forward Register */ +#define SAM_GMAC_RPSF_OFFSET 0x0044 /* RX Partial Store and Forward Register */ + /* 0x0048-0x007c Reserved */ +#define SAM_GMAC_HRB_OFFSET 0x0080 /* Hash Register Bottom [31:0] */ +#define SAM_GMAC_HRT_OFFSET 0x0084 /* Hash Register Top [63:32] */ +#define SAM_GMAC_SAB_OFFSET(n) (0x0088 + (((n)-1) << 3)) /* n=1..4 */ +#define SAM_GMAC_SAT_OFFSET(n) (0x008c + (((n)-1) << 3)) /* n=1..4 */ +#define SAM_GMAC_SAB1_OFFSET 0x0088 /* Specific Address 1 Bottom [31:0] Register */ +#define SAM_GMAC_SAT1_OFFSET 0x008c /* Specific Address 1 Top [47:32] Register */ +#define SAM_GMAC_SAB2_OFFSET 0x0090 /* Specific Address 2 Bottom [31:0] Register */ +#define SAM_GMAC_SAT2_OFFSET 0x0094 /* Specific Address 2 Top [47:32] Register */ +#define SAM_GMAC_SAB3_OFFSET 0x0098 /* Specific Address 3 Bottom [31:0] Register */ +#define SAM_GMAC_SAT3_OFFSET 0x009c /* Specific Address 3 Top [47:32] Register */ +#define SAM_GMAC_SAB4_OFFSET 0x00a0 /* Specific Address 4 Bottom [31:0] Register */ +#define SAM_GMAC_SAT4_OFFSET 0x00a4 /* Specific Address 4 Top [47:32] Register */ +#define SAM_GMAC_TIDM_OFFSET(n) (0x00a8 + (((n)-1) << 2)) /* n=1..4 */ +#define SAM_GMAC_TIDM1_OFFSET 0x00a8 /* Type ID Match 1 Register */ +#define SAM_GMAC_TIDM2_OFFSET 0x00ac /* Type ID Match 2 Register */ +#define SAM_GMAC_TIDM3_OFFSET 0x00b0 /* Type ID Match 3 Register */ +#define SAM_GMAC_TIDM4_OFFSET 0x00b4 /* Type ID Match 4 Register */ +#define SAM_GMAC_WOL_OFFSET 0x00b8 /* Wake on LAN Register */ +#define SAM_GMAC_IPGS_OFFSET 0x00bc /* IPG Stretch Register */ +#define SAM_GMAC_SVLAN_OFFSET 0x00c0 /* Stacked VLAN Register */ +#define SAM_GMAC_TPFCP_OFFSET 0x00c4 /* Transmit PFC Pause Register */ +#define SAM_GMAC_SAMB1_OFFSET 0x00c8 /* Specific Address 1 Mask Bottom [31:0] Register */ +#define SAM_GMAC_SAMT1_OFFSET 0x00cc /* Specific Address 1 Mask Top [47:32] Register */ + /* 0x00fc Reserved */ +#define SAM_GMAC_OTLO_OFFSET 0x0100 /* Octets Transmitted [31:0] Register */ +#define SAM_GMAC_OTHI_OFFSET 0x0104 /* Octets Transmitted [47:32] Register */ +#define SAM_GMAC_FT_OFFSET 0x0108 /* Frames Transmitted Register */ +#define SAM_GMAC_BCFT_OFFSET 0x010c /* Broadcast Frames Transmitted Register */ +#define SAM_GMAC_MFT_OFFSET 0x0110 /* Multicast Frames Transmitted Register */ +#define SAM_GMAC_PFT_OFFSET 0x0114 /* Pause Frames Transmitted Register */ +#define SAM_GMAC_BFT64_OFFSET 0x0118 /* 64 Byte Frames Transmitted Register */ +#define SAM_GMAC_TBFT127_OFFSET 0x011c /* 65 to 127 Byte Frames Transmitted Register */ +#define SAM_GMAC_TBFT255_OFFSET 0x0120 /* 128 to 255 Byte Frames Transmitted Register */ +#define SAM_GMAC_TBFT511_OFFSET 0x0124 /* 256 to 511 Byte Frames Transmitted Register */ +#define SAM_GMAC_TBFT1023_OFFSET 0x0128 /* 512 to 1023 Byte Frames Transmitted Register */ +#define SAM_GMAC_TBFT1518_OFFSET 0x012c /* 1024 to 1518 Byte Frames Transmitted Register */ +#define SAM_GMAC_GTBFT1518_OFFSET 0x0130 /* Greater Than 1518 Byte Frames Transmitted Register */ +#define SAM_GMAC_TUR_OFFSET 0x0134 /* Transmit Under Runs Register */ +#define SAM_GMAC_SCF_OFFSET 0x0138 /* Single Collision Frames Register */ +#define SAM_GMAC_MCF_OFFSET 0x013c /* Multiple Collision Frames Register */ +#define SAM_GMAC_EC_OFFSET 0x0140 /* Excessive Collisions Register */ +#define SAM_GMAC_LC_OFFSET 0x0144 /* Late Collisions Register */ +#define SAM_GMAC_DTF_OFFSET 0x0148 /* Deferred Transmission Frames Register */ +#define SAM_GMAC_CSE_OFFSET 0x014c /* Carrier Sense Errors Register */ +#define SAM_GMAC_ORLO_OFFSET 0x0150 /* Octets Received [31:0] Received */ +#define SAM_GMAC_ORHI_OFFSET 0x0154 /* Octets Received [47:32] Received */ +#define SAM_GMAC_FR_OFFSET 0x0158 /* Frames Received Register */ +#define SAM_GMAC_BCFR_OFFSET 0x015c /* Broadcast Frames Received Register */ +#define SAM_GMAC_MFR_OFFSET 0x0160 /* Multicast Frames Received Register */ +#define SAM_GMAC_PFR_OFFSET 0x0164 /* Pause Frames Received Register */ +#define SAM_GMAC_BFR64_OFFSET 0x0168 /* 64 Byte Frames Received Register */ +#define SAM_GMAC_TBFR127_OFFSET 0x016c /* 65 to 127 Byte Frames Received Register */ +#define SAM_GMAC_TBFR255_OFFSET 0x0170 /* 128 to 255 Byte Frames Received Register */ +#define SAM_GMAC_TBFR511_OFFSET 0x0174 /* 256 to 511Byte Frames Received Register */ +#define SAM_GMAC_TBFR1023_OFFSET 0x0178 /* 512 to 1023 Byte Frames Received Register */ +#define SAM_GMAC_TBFR1518_OFFSET 0x017c /* 1024 to 1518 Byte Frames Received Register */ +#define SAM_GMAC_TMXBFR_OFFSET 0x0180 /* 1519 to Maximum Byte Frames Received Register */ +#define SAM_GMAC_UFR_OFFSET 0x0184 /* Undersize Frames Received Register */ +#define SAM_GMAC_OFR_OFFSET 0x0188 /* Oversize Frames Received Register */ +#define SAM_GMAC_JR_OFFSET 0x018c /* Jabbers Received Register */ +#define SAM_GMAC_FCSE_OFFSET 0x0190 /* Frame Check Sequence Errors Register */ +#define SAM_GMAC_LFFE_OFFSET 0x0194 /* Length Field Frame Errors Register */ +#define SAM_GMAC_RSE_OFFSET 0x0198 /* Receive Symbol Errors Register */ +#define SAM_GMAC_AE_OFFSET 0x019c /* Alignment Errors Register */ +#define SAM_GMAC_RRE_OFFSET 0x01a0 /* Receive Resource Errors Register */ +#define SAM_GMAC_ROE_OFFSET 0x01a4 /* Receive Overrun Register */ +#define SAM_GMAC_IHCE_OFFSET 0x01a8 /* IP Header Checksum Errors Register */ +#define SAM_GMAC_TCE_OFFSET 0x01ac /* TCP Checksum Errors Register */ +#define SAM_GMAC_UCE_OFFSET 0x01b0 /* UDP Checksum Errors Register */ +#define SAM_GMAC_TSSS_OFFSET 0x01c8 /* 1588 Timer Sync Strobe Seconds Register */ +#define SAM_GMAC_TSSN_OFFSET 0x01cc /* 1588 Timer Sync Strobe Nanoseconds Register */ +#define SAM_GMAC_TS_OFFSET 0x01d0 /* 1588 Timer Seconds Register */ +#define SAM_GMAC_TN_OFFSET 0x01d4 /* 1588 Timer Nanoseconds Register */ +#define SAM_GMAC_TA_OFFSET 0x01d8 /* 1588 Timer Adjust Register */ +#define SAM_GMAC_TI_OFFSET 0x01dc /* 1588 Timer Increment Register */ +#define SAM_GMAC_EFTS_OFFSET 0x01e0 /* PTP Event Frame Transmitted Seconds */ +#define SAM_GMAC_EFTN_OFFSET 0x01e4 /* PTP Event Frame Transmitted Nanoseconds */ +#define SAM_GMAC_EFRS_OFFSET 0x01e8 /* PTP Event Frame Received Seconds */ +#define SAM_GMAC_EFRN_OFFSET 0x01ec /* PTP Event Frame Received Nanoseconds */ +#define SAM_GMAC_PEFTS_OFFSET 0x01f0 /* PTP Peer Event Frame Transmitted Seconds */ +#define SAM_GMAC_PEFTN_OFFSET 0x01f4 /* PTP Peer Event Frame Transmitted Nanoseconds */ +#define SAM_GMAC_PEFRS_OFFSET 0x01f8 /* PTP Peer Event Frame Received Seconds */ +#define SAM_GMAC_PEFRN_OFFSET 0x01fc /* PTP Peer Event Frame Received Nanoseconds */ + /* 0x0200-0x023c Reserved */ + /* 0x0280-0x0298 Reserved */ +#define SAM_GMAC_ISRPQ_OFFSET(n) (0x400 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_ISRPQ0_OFFSET 0x400 /* Interrupt Status Register Priority Queue 0 */ +#define SAM_GMAC_ISRPQ1_OFFSET 0x404 /* Interrupt Status Register Priority Queue 1 */ +#define SAM_GMAC_ISRPQ2_OFFSET 0x408 /* Interrupt Status Register Priority Queue 2 */ +#define SAM_GMAC_ISRPQ3_OFFSET 0x40c /* Interrupt Status Register Priority Queue 3 */ +#define SAM_GMAC_ISRPQ4_OFFSET 0x410 /* Interrupt Status Register Priority Queue 4 */ +#define SAM_GMAC_ISRPQ5_OFFSET 0x414 /* Interrupt Status Register Priority Queue 5 */ +#define SAM_GMAC_ISRPQ6_OFFSET 0x418 /* Interrupt Status Register Priority Queue 6 */ +#define SAM_GMAC_TBQBAPQ_OFFSET(n) (0x440 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_TBQBAPQ0_OFFSET 0x440 /* Transmit Buffer Queue Base Address Priority Queue 0 */ +#define SAM_GMAC_TBQBAPQ1_OFFSET 0x444 /* Transmit Buffer Queue Base Address Priority Queue 1 */ +#define SAM_GMAC_TBQBAPQ2_OFFSET 0x448 /* Transmit Buffer Queue Base Address Priority Queue 2 */ +#define SAM_GMAC_TBQBAPQ3_OFFSET 0x44c /* Transmit Buffer Queue Base Address Priority Queue 3 */ +#define SAM_GMAC_TBQBAPQ4_OFFSET 0x450 /* Transmit Buffer Queue Base Address Priority Queue 4 */ +#define SAM_GMAC_TBQBAPQ5_OFFSET 0x454 /* Transmit Buffer Queue Base Address Priority Queue 5 */ +#define SAM_GMAC_TBQBAPQ6_OFFSET 0x458 /* Transmit Buffer Queue Base Address Priority Queue 6 */ +#define SAM_GMAC_RBQBAPQ_OFFSET(n) (0x480 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_RBQBAPQ0_OFFSET 0x480 /* Receive Buffer Queue Base Address Priority Queue 0 */ +#define SAM_GMAC_RBQBAPQ1_OFFSET 0x484 /* Receive Buffer Queue Base Address Priority Queue 1 */ +#define SAM_GMAC_RBQBAPQ2_OFFSET 0x488 /* Receive Buffer Queue Base Address Priority Queue 2 */ +#define SAM_GMAC_RBQBAPQ3_OFFSET 0x48c /* Receive Buffer Queue Base Address Priority Queue 3 */ +#define SAM_GMAC_RBQBAPQ4_OFFSET 0x490 /* Receive Buffer Queue Base Address Priority Queue 4 */ +#define SAM_GMAC_RBQBAPQ5_OFFSET 0x494 /* Receive Buffer Queue Base Address Priority Queue 5 */ +#define SAM_GMAC_RBQBAPQ6_OFFSET 0x498 /* Receive Buffer Queue Base Address Priority Queue 6 */ +#define SAM_GMAC_RBSRPQ_OFFSET(n) (0x4a0 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_RBSRPQ0_OFFSET 0x4a0 /* Receive Buffer Size Register Priority Queue 0 */ +#define SAM_GMAC_RBSRPQ1_OFFSET 0x4a4 /* Receive Buffer Size Register Priority Queue 1 */ +#define SAM_GMAC_RBSRPQ2_OFFSET 0x4a8 /* Receive Buffer Size Register Priority Queue 2 */ +#define SAM_GMAC_RBSRPQ3_OFFSET 0x4ac /* Receive Buffer Size Register Priority Queue 3 */ +#define SAM_GMAC_RBSRPQ4_OFFSET 0x4b0 /* Receive Buffer Size Register Priority Queue 4 */ +#define SAM_GMAC_RBSRPQ5_OFFSET 0x4b4 /* Receive Buffer Size Register Priority Queue 5 */ +#define SAM_GMAC_RBSRPQ6_OFFSET 0x4b8 /* Receive Buffer Size Register Priority Queue 6 */ +#define SAM_GMAC_ST1RPQ_OFFSET(n) (0x500 + ((n) << 2)) /* n=0..15 */ +#define SAM_GMAC_ST1RPQ0_OFFSET 0x500 /* Screening Type1 Register Priority Queue 0 */ +#define SAM_GMAC_ST1RPQ1_OFFSET 0x504 /* Screening Type1 Register Priority Queue 1 */ +#define SAM_GMAC_ST1RPQ2_OFFSET 0x508 /* Screening Type1 Register Priority Queue 2 */ +#define SAM_GMAC_ST1RPQ3_OFFSET 0x50c /* Screening Type1 Register Priority Queue 3 */ +#define SAM_GMAC_ST1RPQ4_OFFSET 0x510 /* Screening Type1 Register Priority Queue 4 */ +#define SAM_GMAC_ST1RPQ5_OFFSET 0x514 /* Screening Type1 Register Priority Queue 5 */ +#define SAM_GMAC_ST1RPQ6_OFFSET 0x518 /* Screening Type1 Register Priority Queue 6 */ +#define SAM_GMAC_ST1RPQ7_OFFSET 0x51c /* Screening Type1 Register Priority Queue 7 */ +#define SAM_GMAC_ST1RPQ8_OFFSET 0x520 /* Screening Type1 Register Priority Queue 8 */ +#define SAM_GMAC_ST1RPQ9_OFFSET 0x524 /* Screening Type1 Register Priority Queue 9 */ +#define SAM_GMAC_ST1RPQ10_OFFSET 0x528 /* Screening Type1 Register Priority Queue 10 */ +#define SAM_GMAC_ST1RPQ11_OFFSET 0x52c /* Screening Type1 Register Priority Queue 11 */ +#define SAM_GMAC_ST1RPQ12_OFFSET 0x530 /* Screening Type1 Register Priority Queue 12 */ +#define SAM_GMAC_ST1RPQ13_OFFSET 0x534 /* Screening Type1 Register Priority Queue 13 */ +#define SAM_GMAC_ST1RPQ14_OFFSET 0x538 /* Screening Type1 Register Priority Queue 14 */ +#define SAM_GMAC_ST1RPQ15_OFFSET 0x53c /* Screening Type1 Register Priority Queue 15 */ +#define SAM_GMAC_ST2RPQ_OFFSET(n) (0x540 + ((n) << 2)) /* n=0..15 */ +#define SAM_GMAC_ST2RPQ0_OFFSET 0x540 /* Screening Type2 Register Priority Queue 0 */ +#define SAM_GMAC_ST2RPQ1_OFFSET 0x544 /* Screening Type2 Register Priority Queue 1 */ +#define SAM_GMAC_ST2RPQ2_OFFSET 0x548 /* Screening Type2 Register Priority Queue 2 */ +#define SAM_GMAC_ST2RPQ3_OFFSET 0x54c /* Screening Type2 Register Priority Queue 3 */ +#define SAM_GMAC_ST2RPQ4_OFFSET 0x550 /* Screening Type2 Register Priority Queue 4 */ +#define SAM_GMAC_ST2RPQ5_OFFSET 0x554 /* Screening Type2 Register Priority Queue 5 */ +#define SAM_GMAC_ST2RPQ6_OFFSET 0x558 /* Screening Type2 Register Priority Queue 6 */ +#define SAM_GMAC_ST2RPQ7_OFFSET 0x55c /* Screening Type2 Register Priority Queue 7 */ +#define SAM_GMAC_ST2RPQ8_OFFSET 0x560 /* Screening Type2 Register Priority Queue 8 */ +#define SAM_GMAC_ST2RPQ9_OFFSET 0x564 /* Screening Type2 Register Priority Queue 9 */ +#define SAM_GMAC_ST2RPQ10_OFFSET 0x568 /* Screening Type2 Register Priority Queue 10 */ +#define SAM_GMAC_ST2RPQ11_OFFSET 0x56c /* Screening Type2 Register Priority Queue 11 */ +#define SAM_GMAC_ST2RPQ12_OFFSET 0x570 /* Screening Type2 Register Priority Queue 12 */ +#define SAM_GMAC_ST2RPQ13_OFFSET 0x574 /* Screening Type2 Register Priority Queue 13 */ +#define SAM_GMAC_ST2RPQ14_OFFSET 0x578 /* Screening Type2 Register Priority Queue 14 */ +#define SAM_GMAC_ST2RPQ15_OFFSET 0x57c /* Screening Type2 Register Priority Queue 15 */ +#define SAM_GMAC_IERPQ_OFFSET(n) (0x600 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_IERPQ0_OFFSET 0x600 /* Interrupt Enable Register Priority Queue 0 */ +#define SAM_GMAC_IERPQ1_OFFSET 0x604 /* Interrupt Enable Register Priority Queue 1 */ +#define SAM_GMAC_IERPQ2_OFFSET 0x608 /* Interrupt Enable Register Priority Queue 2 */ +#define SAM_GMAC_IERPQ3_OFFSET 0x60c /* Interrupt Enable Register Priority Queue 3 */ +#define SAM_GMAC_IERPQ4_OFFSET 0x610 /* Interrupt Enable Register Priority Queue 4 */ +#define SAM_GMAC_IERPQ5_OFFSET 0x614 /* Interrupt Enable Register Priority Queue 5 */ +#define SAM_GMAC_IERPQ6_OFFSET 0x618 /* Interrupt Enable Register Priority Queue 6 */ +#define SAM_GMAC_IDRPQ_OFFSET(n) (0x620 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_IDRPQ0_OFFSET 0x620 /* Interrupt Disable Register Priority Queue 0 */ +#define SAM_GMAC_IDRPQ1_OFFSET 0x624 /* Interrupt Disable Register Priority Queue 1 */ +#define SAM_GMAC_IDRPQ2_OFFSET 0x628 /* Interrupt Disable Register Priority Queue 2 */ +#define SAM_GMAC_IDRPQ3_OFFSET 0x62c /* Interrupt Disable Register Priority Queue 3 */ +#define SAM_GMAC_IDRPQ4_OFFSET 0x630 /* Interrupt Disable Register Priority Queue 4 */ +#define SAM_GMAC_IDRPQ5_OFFSET 0x630 /* Interrupt Disable Register Priority Queue 5 */ +#define SAM_GMAC_IDRPQ6_OFFSET 0x638 /* Interrupt Disable Register Priority Queue 6 */ +#define SAM_GMAC_IMRPQ_OFFSET(n) (0x640 + ((n) << 2)) /* n=0..6 */ +#define SAM_GMAC_IMRPQ0_OFFSET 0x640 /* Interrupt Mask Register Priority Queue 0 */ +#define SAM_GMAC_IMRPQ1_OFFSET 0x644 /* Interrupt Mask Register Priority Queue 1 */ +#define SAM_GMAC_IMRPQ2_OFFSET 0x648 /* Interrupt Mask Register Priority Queue 2 */ +#define SAM_GMAC_IMRPQ3_OFFSET 0x64c /* Interrupt Mask Register Priority Queue 3 */ +#define SAM_GMAC_IMRPQ4_OFFSET 0x650 /* Interrupt Mask Register Priority Queue 4 */ +#define SAM_GMAC_IMRPQ5_OFFSET 0x654 /* Interrupt Mask Register Priority Queue 5 */ +#define SAM_GMAC_IMRPQ6_OFFSET 0x658 /* Interrupt Mask Register Priority Queue 6 */ + +/* GMAC Register Addresses *********************************************************/ + +#define SAM_GMAC_NCR (SAM_GMAC_VBASE+SAM_GMAC_NCR_OFFSET) +#define SAM_GMAC_NCFGR (SAM_GMAC_VBASE+SAM_GMAC_NCFGR_OFFSET) +#define SAM_GMAC_NSR (SAM_GMAC_VBASE+SAM_GMAC_NSR_OFFSET) +#define SAM_GMAC_UR (SAM_GMAC_VBASE+SAM_GMAC_UR_OFFSET) +#define SAM_GMAC_DCFGR (SAM_GMAC_VBASE+SAM_GMAC_DCFGR_OFFSET) +#define SAM_GMAC_TSR (SAM_GMAC_VBASE+SAM_GMAC_TSR_OFFSET) +#define SAM_GMAC_RBQB (SAM_GMAC_VBASE+SAM_GMAC_RBQB_OFFSET) +#define SAM_GMAC_TBQB (SAM_GMAC_VBASE+SAM_GMAC_TBQB_OFFSET) +#define SAM_GMAC_RSR (SAM_GMAC_VBASE+SAM_GMAC_RSR_OFFSET) +#define SAM_GMAC_ISR (SAM_GMAC_VBASE+SAM_GMAC_ISR_OFFSET) +#define SAM_GMAC_IER (SAM_GMAC_VBASE+SAM_GMAC_IER_OFFSET) +#define SAM_GMAC_IDR (SAM_GMAC_VBASE+SAM_GMAC_IDR_OFFSET) +#define SAM_GMAC_IMR (SAM_GMAC_VBASE+SAM_GMAC_IMR_OFFSET) +#define SAM_GMAC_MAN (SAM_GMAC_VBASE+SAM_GMAC_MAN_OFFSET) +#define SAM_GMAC_RPQ (SAM_GMAC_VBASE+SAM_GMAC_RPQ_OFFSET) +#define SAM_GMAC_TPQ (SAM_GMAC_VBASE+SAM_GMAC_TPQ_OFFSET) +#define SAM_GMAC_TPSF (SAM_GMAC_VBASE+SAM_GMAC_TPSF_OFFSET) +#define SAM_GMAC_RPSF (SAM_GMAC_VBASE+SAM_GMAC_RPSF_OFFSET) +#define SAM_GMAC_HRB (SAM_GMAC_VBASE+SAM_GMAC_HRB_OFFSET) +#define SAM_GMAC_HRT (SAM_GMAC_VBASE+SAM_GMAC_HRT_OFFSET) +#define SAM_GMAC_SAB(n) (SAM_GMAC_VBASE+SAM_GMAC_SAB_OFFSET(n)) +#define SAM_GMAC_SAT(n) (SAM_GMAC_VBASE+SAM_GMAC_SAT_OFFSET(n)) +#define SAM_GMAC_SAB1 (SAM_GMAC_VBASE+SAM_GMAC_SAB1_OFFSET) +#define SAM_GMAC_SAT1 (SAM_GMAC_VBASE+SAM_GMAC_SAT1_OFFSET) +#define SAM_GMAC_SAB2 (SAM_GMAC_VBASE+SAM_GMAC_SAB2_OFFSET) +#define SAM_GMAC_SAT2 (SAM_GMAC_VBASE+SAM_GMAC_SAT2_OFFSET) +#define SAM_GMAC_SAB3 (SAM_GMAC_VBASE+SAM_GMAC_SAB3_OFFSET) +#define SAM_GMAC_SAT3 (SAM_GMAC_VBASE+SAM_GMAC_SAT3_OFFSET) +#define SAM_GMAC_SAB4 (SAM_GMAC_VBASE+SAM_GMAC_SAB4_OFFSET) +#define SAM_GMAC_SAT4 (SAM_GMAC_VBASE+SAM_GMAC_SAT4_OFFSET) +#define SAM_GMAC_TIDM(n) (SAM_GMAC_VBASE+SAM_GMAC_TIDM_OFFSET(n)) +#define SAM_GMAC_TIDM1 (SAM_GMAC_VBASE+SAM_GMAC_TIDM1_OFFSET) +#define SAM_GMAC_TIDM2 (SAM_GMAC_VBASE+SAM_GMAC_TIDM2_OFFSET) +#define SAM_GMAC_TIDM3 (SAM_GMAC_VBASE+SAM_GMAC_TIDM3_OFFSET) +#define SAM_GMAC_TIDM4 (SAM_GMAC_VBASE+SAM_GMAC_TIDM4_OFFSET) +#define SAM_GMAC_WOL (SAM_GMAC_VBASE+SAM_GMAC_WOL_OFFSET) +#define SAM_GMAC_IPGS (SAM_GMAC_VBASE+SAM_GMAC_IPGS_OFFSET) +#define SAM_GMAC_SVLAN (SAM_GMAC_VBASE+SAM_GMAC_SVLAN_OFFSET) +#define SAM_GMAC_TPFCP (SAM_GMAC_VBASE+SAM_GMAC_TPFCP_OFFSET) +#define SAM_GMAC_SAMB1 (SAM_GMAC_VBASE+SAM_GMAC_SAMB1_OFFSET) +#define SAM_GMAC_SAMT1 (SAM_GMAC_VBASE+SAM_GMAC_SAMT1_OFFSET) +#define SAM_GMAC_OTLO (SAM_GMAC_VBASE+SAM_GMAC_OTLO_OFFSET) +#define SAM_GMAC_OTHI (SAM_GMAC_VBASE+SAM_GMAC_OTHI_OFFSET) +#define SAM_GMAC_FT (SAM_GMAC_VBASE+SAM_GMAC_FT_OFFSET) +#define SAM_GMAC_BCFT (SAM_GMAC_VBASE+SAM_GMAC_BCFT_OFFSET) +#define SAM_GMAC_MFT (SAM_GMAC_VBASE+SAM_GMAC_MFT_OFFSET) +#define SAM_GMAC_PFT (SAM_GMAC_VBASE+SAM_GMAC_PFT_OFFSET) +#define SAM_GMAC_BFT64 (SAM_GMAC_VBASE+SAM_GMAC_BFT64_OFFSET) +#define SAM_GMAC_TBFT127 (SAM_GMAC_VBASE+SAM_GMAC_TBFT127_OFFSET) +#define SAM_GMAC_TBFT255 (SAM_GMAC_VBASE+SAM_GMAC_TBFT255_OFFSET) +#define SAM_GMAC_TBFT511 (SAM_GMAC_VBASE+SAM_GMAC_TBFT511_OFFSET) +#define SAM_GMAC_TBFT1023 (SAM_GMAC_VBASE+SAM_GMAC_TBFT1023_OFFSET) +#define SAM_GMAC_TBFT1518 (SAM_GMAC_VBASE+SAM_GMAC_TBFT1518_OFFSET) +#define SAM_GMAC_GTBFT1518 (SAM_GMAC_VBASE+SAM_GMAC_GTBFT1518_OFFSET) +#define SAM_GMAC_TUR (SAM_GMAC_VBASE+SAM_GMAC_TUR_OFFSET) +#define SAM_GMAC_SCF (SAM_GMAC_VBASE+SAM_GMAC_SCF_OFFSET) +#define SAM_GMAC_MCF (SAM_GMAC_VBASE+SAM_GMAC_MCF_OFFSET) +#define SAM_GMAC_EC (SAM_GMAC_VBASE+SAM_GMAC_EC_OFFSET) +#define SAM_GMAC_LC (SAM_GMAC_VBASE+SAM_GMAC_LC_OFFSET) +#define SAM_GMAC_DTF (SAM_GMAC_VBASE+SAM_GMAC_DTF_OFFSET) +#define SAM_GMAC_CSE (SAM_GMAC_VBASE+SAM_GMAC_CSE_OFFSET) +#define SAM_GMAC_ORLO (SAM_GMAC_VBASE+SAM_GMAC_ORLO_OFFSET) +#define SAM_GMAC_ORHI (SAM_GMAC_VBASE+SAM_GMAC_ORHI_OFFSET) +#define SAM_GMAC_FR (SAM_GMAC_VBASE+SAM_GMAC_FR_OFFSET) +#define SAM_GMAC_BCFR (SAM_GMAC_VBASE+SAM_GMAC_BCFR_OFFSET) +#define SAM_GMAC_MFR (SAM_GMAC_VBASE+SAM_GMAC_MFR_OFFSET) +#define SAM_GMAC_PFR (SAM_GMAC_VBASE+SAM_GMAC_PFR_OFFSET) +#define SAM_GMAC_BFR64 (SAM_GMAC_VBASE+SAM_GMAC_BFR64_OFFSET) +#define SAM_GMAC_TBFR127 (SAM_GMAC_VBASE+SAM_GMAC_TBFR127_OFFSET) +#define SAM_GMAC_TBFR255 (SAM_GMAC_VBASE+SAM_GMAC_TBFR255_OFFSET) +#define SAM_GMAC_TBFR511 (SAM_GMAC_VBASE+SAM_GMAC_TBFR511_OFFSET) +#define SAM_GMAC_TBFR1023 (SAM_GMAC_VBASE+SAM_GMAC_TBFR1023_OFFSET) +#define SAM_GMAC_TBFR1518 (SAM_GMAC_VBASE+SAM_GMAC_TBFR1518_OFFSET) +#define SAM_GMAC_TMXBFR (SAM_GMAC_VBASE+SAM_GMAC_TMXBFR_OFFSET) +#define SAM_GMAC_UFR (SAM_GMAC_VBASE+SAM_GMAC_UFR_OFFSET) +#define SAM_GMAC_OFR (SAM_GMAC_VBASE+SAM_GMAC_OFR_OFFSET) +#define SAM_GMAC_JR (SAM_GMAC_VBASE+SAM_GMAC_JR_OFFSET) +#define SAM_GMAC_FCSE (SAM_GMAC_VBASE+SAM_GMAC_FCSE_OFFSET) +#define SAM_GMAC_LFFE (SAM_GMAC_VBASE+SAM_GMAC_LFFE_OFFSET) +#define SAM_GMAC_RSE (SAM_GMAC_VBASE+SAM_GMAC_RSE_OFFSET) +#define SAM_GMAC_AE (SAM_GMAC_VBASE+SAM_GMAC_AE_OFFSET) +#define SAM_GMAC_RRE (SAM_GMAC_VBASE+SAM_GMAC_RRE_OFFSET) +#define SAM_GMAC_ROE (SAM_GMAC_VBASE+SAM_GMAC_ROE_OFFSET) +#define SAM_GMAC_IHCE (SAM_GMAC_VBASE+SAM_GMAC_IHCE_OFFSET) +#define SAM_GMAC_TCE (SAM_GMAC_VBASE+SAM_GMAC_TCE_OFFSET) +#define SAM_GMAC_UCE (SAM_GMAC_VBASE+SAM_GMAC_UCE_OFFSET) +#define SAM_GMAC_TSSS (SAM_GMAC_VBASE+SAM_GMAC_TSSS_OFFSET) +#define SAM_GMAC_TSSN (SAM_GMAC_VBASE+SAM_GMAC_TSSN_OFFSET) +#define SAM_GMAC_TS (SAM_GMAC_VBASE+SAM_GMAC_TS_OFFSET) +#define SAM_GMAC_TN (SAM_GMAC_VBASE+SAM_GMAC_TN_OFFSET) +#define SAM_GMAC_TA (SAM_GMAC_VBASE+SAM_GMAC_TA_OFFSET) +#define SAM_GMAC_TI (SAM_GMAC_VBASE+SAM_GMAC_TI_OFFSET) +#define SAM_GMAC_EFTS (SAM_GMAC_VBASE+SAM_GMAC_EFTS_OFFSET) +#define SAM_GMAC_EFTN (SAM_GMAC_VBASE+SAM_GMAC_EFTN_OFFSET) +#define SAM_GMAC_EFRS (SAM_GMAC_VBASE+SAM_GMAC_EFRS_OFFSET) +#define SAM_GMAC_EFRN (SAM_GMAC_VBASE+SAM_GMAC_EFRN_OFFSET) +#define SAM_GMAC_PEFTS (SAM_GMAC_VBASE+SAM_GMAC_PEFTS_OFFSET) +#define SAM_GMAC_PEFTN (SAM_GMAC_VBASE+SAM_GMAC_PEFTN_OFFSET) +#define SAM_GMAC_PEFRS (SAM_GMAC_VBASE+SAM_GMAC_PEFRS_OFFSET) +#define SAM_GMAC_PEFRN (SAM_GMAC_VBASE+SAM_GMAC_PEFRN_OFFSET) +#define SAM_GMAC_ISRPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ_OFFSET(n)) +#define SAM_GMAC_ISRPQ0 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ0_OFFSET) +#define SAM_GMAC_ISRPQ1 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ1_OFFSET) +#define SAM_GMAC_ISRPQ2 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ2_OFFSET) +#define SAM_GMAC_ISRPQ3 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ3_OFFSET) +#define SAM_GMAC_ISRPQ4 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ4_OFFSET) +#define SAM_GMAC_ISRPQ5 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ5_OFFSET) +#define SAM_GMAC_ISRPQ6 (SAM_GMAC_VBASE+SAM_GMAC_ISRPQ6_OFFSET) +#define SAM_GMAC_TBQBAPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ_OFFSET(n)) +#define SAM_GMAC_TBQBAPQ0 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ0_OFFSET) +#define SAM_GMAC_TBQBAPQ1 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ1_OFFSET) +#define SAM_GMAC_TBQBAPQ2 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ2_OFFSET) +#define SAM_GMAC_TBQBAPQ3 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ3_OFFSET) +#define SAM_GMAC_TBQBAPQ4 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ4_OFFSET) +#define SAM_GMAC_TBQBAPQ5 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ5_OFFSET) +#define SAM_GMAC_TBQBAPQ6 (SAM_GMAC_VBASE+SAM_GMAC_TBQBAPQ6_OFFSET) +#define SAM_GMAC_RBQBAPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ_OFFSET(n)) +#define SAM_GMAC_RBQBAPQ0 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ0_OFFSET) +#define SAM_GMAC_RBQBAPQ1 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ1_OFFSET) +#define SAM_GMAC_RBQBAPQ2 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ2_OFFSET) +#define SAM_GMAC_RBQBAPQ3 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ3_OFFSET) +#define SAM_GMAC_RBQBAPQ4 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ4_OFFSET) +#define SAM_GMAC_RBQBAPQ5 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ5_OFFSET) +#define SAM_GMAC_RBQBAPQ6 (SAM_GMAC_VBASE+SAM_GMAC_RBQBAPQ6_OFFSET) +#define SAM_GMAC_RBSRPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ_OFFSET(n)) +#define SAM_GMAC_RBSRPQ0 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ0_OFFSET) +#define SAM_GMAC_RBSRPQ1 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ1_OFFSET) +#define SAM_GMAC_RBSRPQ2 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ2_OFFSET) +#define SAM_GMAC_RBSRPQ3 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ3_OFFSET) +#define SAM_GMAC_RBSRPQ4 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ4_OFFSET) +#define SAM_GMAC_RBSRPQ5 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ5_OFFSET) +#define SAM_GMAC_RBSRPQ6 (SAM_GMAC_VBASE+SAM_GMAC_RBSRPQ6_OFFSET) +#define SAM_GMAC_ST1RPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ_OFFSET(n)) +#define SAM_GMAC_ST1RPQ0 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ0_OFFSET) +#define SAM_GMAC_ST1RPQ1 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ1_OFFSET) +#define SAM_GMAC_ST1RPQ2 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ2_OFFSET) +#define SAM_GMAC_ST1RPQ3 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ3_OFFSET) +#define SAM_GMAC_ST1RPQ4 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ4_OFFSET) +#define SAM_GMAC_ST1RPQ5 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ5_OFFSET) +#define SAM_GMAC_ST1RPQ6 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ6_OFFSET) +#define SAM_GMAC_ST1RPQ7 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ7_OFFSET) +#define SAM_GMAC_ST1RPQ8 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ8_OFFSET) +#define SAM_GMAC_ST1RPQ9 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ9_OFFSET) +#define SAM_GMAC_ST1RPQ10 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ10_OFFSET) +#define SAM_GMAC_ST1RPQ11 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ11_OFFSET) +#define SAM_GMAC_ST1RPQ12 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ12_OFFSET) +#define SAM_GMAC_ST1RPQ13 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ13_OFFSET) +#define SAM_GMAC_ST1RPQ14 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ14_OFFSET) +#define SAM_GMAC_ST1RPQ15 (SAM_GMAC_VBASE+SAM_GMAC_ST1RPQ15_OFFSET) +#define SAM_GMAC_ST2RPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ_OFFSET(n)) +#define SAM_GMAC_ST2RPQ0 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ0_OFFSET) +#define SAM_GMAC_ST2RPQ1 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ1_OFFSET) +#define SAM_GMAC_ST2RPQ2 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ2_OFFSET) +#define SAM_GMAC_ST2RPQ3 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ3_OFFSET) +#define SAM_GMAC_ST2RPQ4 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ4_OFFSET) +#define SAM_GMAC_ST2RPQ5 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ5_OFFSET) +#define SAM_GMAC_ST2RPQ6 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ6_OFFSET) +#define SAM_GMAC_ST2RPQ7 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ7_OFFSET) +#define SAM_GMAC_ST2RPQ8 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ8_OFFSET) +#define SAM_GMAC_ST2RPQ9 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ9_OFFSET) +#define SAM_GMAC_ST2RPQ10 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ10_OFFSET) +#define SAM_GMAC_ST2RPQ11 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ11_OFFSET) +#define SAM_GMAC_ST2RPQ12 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ12_OFFSET) +#define SAM_GMAC_ST2RPQ13 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ13_OFFSET) +#define SAM_GMAC_ST2RPQ14 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ14_OFFSET) +#define SAM_GMAC_ST2RPQ15 (SAM_GMAC_VBASE+SAM_GMAC_ST2RPQ15_OFFSET) +#define SAM_GMAC_IERPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_IERPQ_OFFSET(n)) +#define SAM_GMAC_IERPQ0 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ0_OFFSET) +#define SAM_GMAC_IERPQ1 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ1_OFFSET) +#define SAM_GMAC_IERPQ2 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ2_OFFSET) +#define SAM_GMAC_IERPQ3 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ3_OFFSET) +#define SAM_GMAC_IERPQ4 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ4_OFFSET) +#define SAM_GMAC_IERPQ5 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ5_OFFSET) +#define SAM_GMAC_IERPQ6 (SAM_GMAC_VBASE+SAM_GMAC_IERPQ6_OFFSET) +#define SAM_GMAC_IDRPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ_OFFSET(n)) +#define SAM_GMAC_IDRPQ0 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ0_OFFSET) +#define SAM_GMAC_IDRPQ1 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ1_OFFSET) +#define SAM_GMAC_IDRPQ2 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ2_OFFSET) +#define SAM_GMAC_IDRPQ3 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ3_OFFSET) +#define SAM_GMAC_IDRPQ4 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ4_OFFSET) +#define SAM_GMAC_IDRPQ5 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ5_OFFSET) +#define SAM_GMAC_IDRPQ6 (SAM_GMAC_VBASE+SAM_GMAC_IDRPQ6_OFFSET) +#define SAM_GMAC_IMRPQ(n) (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ_OFFSET(n)) +#define SAM_GMAC_IMRPQ0 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ0_OFFSET) +#define SAM_GMAC_IMRPQ1 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ1_OFFSET) +#define SAM_GMAC_IMRPQ2 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ2_OFFSET) +#define SAM_GMAC_IMRPQ3 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ3_OFFSET) +#define SAM_GMAC_IMRPQ4 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ4_OFFSET) +#define SAM_GMAC_IMRPQ5 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ5_OFFSET) +#define SAM_GMAC_IMRPQ6 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ6_OFFSET) + +/* GMAC Register Bit Definitions ***************************************************/ + +/* Network Control Register */ + +#define GMAC_NCR_LBL (1 << 1) /* Bit 1: Loopback local */ +#define GMAC_NCR_RXEN (1 << 2) /* Bit 2: Receive enable */ +#define GMAC_NCR_TXEN (1 << 3) /* Bit 3: Transmit enable */ +#define GMAC_NCR_MPE (1 << 4) /* Bit 4: Management port enable */ +#define GMAC_NCR_CLRSTAT (1 << 5) /* Bit 5: Clear statistics registers */ +#define GMAC_NCR_INCSTAT (1 << 6) /* Bit 6: Increment statistics registers */ +#define GMAC_NCR_WESTAT (1 << 7) /* Bit 7: Write enable for statistics registers */ +#define GMAC_NCR_BP (1 << 8) /* Bit 8: Back pressure */ +#define GMAC_NCR_TSTART (1 << 9) /* Bit 9: Start transmission */ +#define GMAC_NCR_THALT (1 << 10) /* Bit 10: Transmit halt */ +#define GMAC_NCR_TXPF (1 << 11) /* Bit 11: Transmit Pause Frame */ +#define GMAC_NCR_TXZQPF (1 << 12) /* Bit 12: Transmit Zero Quantum Pause Frame */ +#define GMAC_NCR_RDS (1 << 14) /* Bit 14: Read Snapshot */ +#define GMAC_NCR_SRTSM (1 << 15) /* Bit 15: Store Receive Time Stamp to Memory */ +#define GMAC_NCR_ENPBPR (1 << 16) /* Bit 16: Enable PFC Priority-based Pause Reception */ +#define GMAC_NCR_TXPBPF (1 << 17) /* Bit 17: Transmit PFC Priority-based Pause Frame */ +#define GMAC_NCR_FNP (1 << 18) /* Bit 18: Flush Next Packet */ + +/* Network Configuration Register */ + +#define GMAC_NCFGR_SPD (1 << 0) /* Bit 0: Speed */ +#define GMAC_NCFGR_FD (1 << 1) /* Bit 1: Full Duplex */ +#define GMAC_NCFGR_DNVLAN (1 << 2) /* Bit 2: Discard Non-VLAN FRAMES */ +#define GMAC_NCFGR_JFRAME (1 << 3) /* Bit 3: Jumbo Frames */ +#define GMAC_NCFGR_CAF (1 << 4) /* Bit 4: Copy All Frames */ +#define GMAC_NCFGR_NBC (1 << 5) /* Bit 5: No Broadcast */ +#define GMAC_NCFGR_MTIHEN (1 << 6) /* Bit 6: Multicast Hash Enable */ +#define GMAC_NCFGR_UNIHEN (1 << 7) /* Bit 7: Unicast Hash Enable */ +#define GMAC_NCFGR_MAXFS (1 << 8) /* Bit 8: Receive 1536 bytes frames */ +#define GMAC_NCFGR_GBE (1 << 10) /* Bit 10: Gigabit Mode Enable */ +#define GMAC_NCFGR_RTY (1 << 12) /* Bit 12: Retry test */ +#define GMAC_NCFGR_PEN (1 << 13) /* Bit 13: Pause Enable */ +#define GMAC_NCFGR_RXBUFO_SHIFT (14) /* Bits 14-15: Receive Buffer Offset */ +#define GMAC_NCFGR_RXBUFO_MASK (3 << GMAC_NCFGR_RXBUFO_SHIFT) +#define GMAC_NCFGR_LFERD (1 << 16) /* Bit 16: Length Field Error Frame Discard */ +#define GMAC_NCFGR_RFCS (1 << 17) /* Bit 17: Remove FCS */ +#define GMAC_NCFGR_CLK_SHIFT (18) /* Bits 18-20: MDC clock division */ +#define GMAC_NCFGR_CLK_MASK (7 << GMAC_NCFGR_CLK_SHIFT) +# define GMAC_NCFGR_CLK_DIV8 (0 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 8 (MCK up to 20 MHz) */ +# define GMAC_NCFGR_CLK_DIV16 (1 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 16 (MCK up to 40 MHz) */ +# define GMAC_NCFGR_CLK_DIV32 (2 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */ +# define GMAC_NCFGR_CLK_DIV48 (3 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 48 (MCK up to 120 MHz) */ +# define GMAC_NCFGR_CLK_DIV64 (4 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */ +# define GMAC_NCFGR_CLK_DIV96 (5 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 96 (MCK up to 240 MHz) */ +#define GMAC_NCFGR_DBW_SHIFT (21) /* Bits 21-22: Data Bus Width */ +#define GMAC_NCFGR_DBW_MASK (3 << GMAC_NCFGR_DBW_SHIFT) +# define GMAC_NCFGR_DBW_32 (0 << GMAC_NCFGR_DBW_SHIFT) /* 32-bit data bus width */ +# define GMAC_NCFGR_DBW_64 (1 << GMAC_NCFGR_DBW_SHIFT) /* 64-bit data bus width */ +#define GMAC_NCFGR_DCPF (1 << 23) /* Bit 23: Disable Copy of Pause Frames */ +#define GMAC_NCFGR_RXCOEN (1 << 24) /* Bit 24: Receive Checksum Offload Enable */ +#define GMAC_NCFGR_EFRHD (1 << 25) /* Bit 25: Enable Frames Received in Half Duplex */ +#define GMAC_NCFGR_IRXFCS (1 << 26) /* Bit 26: Ignore RX FCS */ +#define GMAC_NCFGR_IPGSEN (1 << 28) /* Bit 28: IP Stretch Enable */ +#define GMAC_NCFGR_RXBP (1 << 29) /* Bit 29: Receive Bad Preamble */ +#define GMAC_NCFGR_IRXER (1 << 30) /* Bit 30: Ignore IPG GRXER */ + +/* Network Status Register */ + +#define GMAC_NSR_MDIO (1 << 1) /* Bit 1: MDIO Input Status */ +#define GMAC_NSR_IDLE (1 << 2) /* Bit 2: PHY management logic idle */ + +/* User Register */ + +#define GMAC_UR_RGMII (1 << 0) /* Bit 0: Reduced GMII Mode */ + +/* DMA Configuration Register */ + +#define GMAC_DCFGR_FBLDO_SHIFT (0) /* Bits 0-4: Fixed Burst Length for DMA Data Operations */ +#define GMAC_DCFGR_FBLDO_MASK (31 << GMAC_DCFGR_FBLDO_SHIFT) +# define GMAC_DCFGR_FBLDO_SINGLE (1 << GMAC_DCFGR_FBLDO_SHIFT) /* 00001: Always use SINGLE AHB bursts */ +# define GMAC_DCFGR_FBLDO_INCR4 (4 << GMAC_DCFGR_FBLDO_SHIFT) /* 001xx: Attempt to use INCR4 AHB bursts */ +# define GMAC_DCFGR_FBLDO_INCR8 (8 << GMAC_DCFGR_FBLDO_SHIFT) /* 01xxx: Attempt to use INCR8 AHB bursts */ +# define GMAC_DCFGR_FBLDO_INCR16 (16 << GMAC_DCFGR_FBLDO_SHIFT) /* 1xxxx: Attempt to use INCR16 AHB bursts */ +#define GMAC_DCFGR_ESMA (1 << 6) /* Bit 6: Endian Swap Mode Enable for Management Descriptor Accesses */ +#define GMAC_DCFGR_ESPA (1 << 7) /* Bit 7: Endian Swap Mode Enable for Packet Data Accesses */ +#define GMAC_DCFGR_RXBMS_SHIFT (8) /* Bits 8-9: Receiver Packet Buffer Memory Size Select */ +#define GMAC_DCFGR_RXBMS_MASK (3 << GMAC_DCFGR_RXBMS_SHIFT) +# define GMAC_DCFGR_RXBMS_EIGHTH (0 << GMAC_DCFGR_RXBMS_SHIFT) /* 1/2 Kbyte Memory Size */ +# define GMAC_DCFGR_RXBMS_QTR (1 << GMAC_DCFGR_RXBMS_SHIFT) /* 1Kbyte Memory Size */ +# define GMAC_DCFGR_RXBMS_HALF (2 << GMAC_DCFGR_RXBMS_SHIFT) /* 2 Kbytes Memory Size */ +# define GMAC_DCFGR_RXBMS_FULL (3 << GMAC_DCFGR_RXBMS_SHIFT) /* 4 Kbytes Memory Size */ +#define GMAC_DCFGR_TXPBMS (1 << 10) /* Bit 10: Transmitter Packet Buffer Memory Size Select */ +#define GMAC_DCFGR_TXCOEN (1 << 11) /* Bit 11: Transmitter Checksum Generation Offload Enable */ +#define GMAC_DCFGR_DRBS_SHIFT (16) /* Bits 16-23: DMA Receive Buffer Size */ +#define GMAC_DCFGR_DRBS_MASK (0xff << GMAC_DCFGR_DRBS_SHIFT) +# define GMAC_DCFGR_DRBS(n) ((uint32_t)(n) << GMAC_DCFGR_DRBS_SHIFT) +#define GMAC_DCFGR_DDRP (1 << 24) /* Bit 24: DMA Discard Receive Packets */ + +/* Transmit Status Register */ + +#define GMAC_TSR_UBR (1 << 0) /* Bit 0: Used Bit Read */ +#define GMAC_TSR_COL (1 << 1) /* Bit 1: Collision Occurred */ +#define GMAC_TSR_RLE (1 << 2) /* Bit 2: Retry Limit exceeded */ +#define GMAC_TSR_TXGO (1 << 3) /* Bit 3: Transmit Go */ +#define GMAC_TSR_TFC (1 << 4) /* Bit 4: Transmit Frame Corruption due to AHB error */ +#define GMAC_TSR_TXCOMP (1 << 5) /* Bit 5: Transmit Complete */ +#define GMAC_TSR_UND (1 << 6) /* Bit 6: Transmit Underrun */ +#define GMAC_TSR_LCO (1 << 7) /* Bit 7: Late Collision Occurred */ +#define GMAC_TSR_HRESP (1 << 8) /* Bit 8: HRESP Not OK */ + +/* Receive Buffer Queue Base Address */ + +#define GMAC_RBQB_MASK (0xfffffffc) /* Bits 2-31: Receive buffer queue base address */ + +/* Transmit Buffer Queue Base Address */ + +#define GMAC_TBQB_MASK (0xfffffffc) /* Bits 2-31: Transmit buffer queue base address */ + +/* Receive Status Register */ + +#define GMAC_RSR_BNA (1 << 0) /* Bit 0: Buffer Not Available */ +#define GMAC_RSR_REC (1 << 1) /* Bit 1: Frame Received */ +#define GMAC_RSR_RXOVR (1 << 2) /* Bit 2: Receive Overrun */ +#define GMAC_RSR_HNO (1 << 3) /* Bit 3: HRESP Not OK */ + +/* Interrupt Status Register, Interrupt Enable Register, Interrupt Disable Register */ + +#define GMAC_INT_MFS (1 << 0) /* Bit 0: Management Frame Sent */ +#define GMAC_INT_RCOMP (1 << 1) /* Bit 1: Receive Complete */ +#define GMAC_INT_RXUBR (1 << 2) /* Bit 2: Receive Used Bit Read */ +#define GMAC_INT_TXUBR (1 << 3) /* Bit 3: Transmit Used Bit Read */ +#define GMAC_INT_TUR (1 << 4) /* Bit 4: Transmit Under Run */ +#define GMAC_INT_RLEX (1 << 5) /* Bit 5: Retry Limit Exceeded or Late Collision */ +#define GMAC_INT_TFC (1 << 6) /* Bit 6: Transmit Frame Corruption due to AHB error */ +#define GMAC_INT_TCOMP (1 << 7) /* Bit 7: Transmit Complete */ +#define GMAC_INT_ROVR (1 << 10) /* Bit 10: Receive Overrun */ +#define GMAC_INT_HRESP (1 << 11) /* Bit 11: HRESP not OK */ +#define GMAC_INT_PFNZ (1 << 12) /* Bit 12: Pause Frame with Non-zero Pause Quantum */ +#define GMAC_INT_PTZ (1 << 13) /* Bit 13: Pause Time Zero */ +#define GMAC_INT_PFTR (1 << 14) /* Bit 14: Pause Frame Transmitted */ +#define GMAC_INT_EXINT (1 << 15) /* Bit 15: External Interrupt (not in ISR) */ +#define GMAC_INT_DRQFR (1 << 18) /* Bit 18: PTP Delay Request Frame Received */ +#define GMAC_INT_SFR (1 << 19) /* Bit 19: PTP Sync Frame Received */ +#define GMAC_INT_DRQFT (1 << 20) /* Bit 20: PTP Delay Request Frame Transmitted */ +#define GMAC_INT_SFT (1 << 21) /* Bit 21: PTP Sync Frame Transmitted */ +#define GMAC_INT_PDRQFR (1 << 22) /* Bit 22: PDelay Request Frame Received */ +#define GMAC_INT_PDRSFR (1 << 23) /* Bit 23: PDelay Response Frame Received */ +#define GMAC_INT_PDRQFT (1 << 24) /* Bit 24: PDelay Request Frame Transmitted */ +#define GMAC_INT_PDRSFT (1 << 25) /* Bit 25: PDelay Response Frame Transmitted */ +#define GMAC_INT_SRI (1 << 26) /* Bit 26: TSU Seconds Register Increment (not in IMR) */ +#define GMAC_INT_WOL (1 << 28) /* Bit 28: Wake On LAN (not in IMR) */ + +#define GMAC_INT_ALL (0x17fcfcff) +#define GMAC_INT_UNUSED (0xe8030300) + +/* PHY Maintenance Register */ + +#define GMAC_MAN_DATA_SHIFT (0) /* Bits 0-15: PHY data */ +#define GMAC_MAN_DATA_MASK (0x0000ffff << GMAC_MAN_DATA_SHIFT) +# define GMAC_MAN_DATA(n) ((uint32_t)(n) << GMAC_MAN_DATA_SHIFT) +#define GMAC_MAN_WTN_SHIFT (16) /* Bits 16-17: Must be written to b10 */ +#define GMAC_MAN_WTN_MASK (3 << GMAC_MAN_WTN_SHIFT) +# define GMAC_MAN_WTN (2 << GMAC_MAN_WTN_SHIFT) +#define GMAC_MAN_REGA_SHIFT (18) /* Bits 18-22: Register Address */ +#define GMAC_MAN_REGA_MASK (31 << GMAC_MAN_REGA_SHIFT) +# define GMAC_MAN_REGA(n) ((uint32_t)(n) << GMAC_MAN_REGA_SHIFT) +#define GMAC_MAN_PHYA_SHIFT (23) /* Bits 23-27: PHY Address */ +#define GMAC_MAN_PHYA_MASK (31 << GMAC_MAN_PHYA_SHIFT) +# define GMAC_MAN_PHYA(n) ((uint32_t)(n) << GMAC_MAN_PHYA_SHIFT) +#define GMAC_MAN_OP_SHIFT (28) /* Bits 28-29: Operation */ +#define GMAC_MAN_OP_MASK (3 << GMAC_MAN_OP_SHIFT) +# define GMAC_MAN_READ (2 << GMAC_MAN_OP_SHIFT) +# define GMAC_MAN_WRITE (1 << GMAC_MAN_OP_SHIFT) +#define GMAC_MAN_CLTTO (1 << 30) /* Bit 30: Clause 22 Operation */ +#define GMAC_MAN_WZO (1 << 31) /* Bit 31: Write ZERO */ + +/* Received Pause Quantum Register */ + +#define GMAC_RPQ_MASK (0x0000ffff) /* Bits 0-15: Received Pause Quantum */ + +/* Transmit Pause Quantum Register */ + +#define GMAC_TPQ_MASK (0x0000ffff) /* Bits 0-15: Transmit Pause Quantum */ + +/* TX Partial Store and Forward Register */ + +#define GMAC_TPSF_TPB1ADR_SHIFT (0) /* Bits 0-11: Transmit Partial Store and Forward Address */ +#define GMAC_TPSF_TPB1ADR_MASK (0xfff << GMAC_TPSF_TPB1ADR_SHIFT) +# define GMAC_TPSF_TPB1ADR(n) ((uint32_t)(n) << GMAC_TPSF_TPB1ADR_SHIFT) +#define GMAC_TPSF_ENTXP (1 << 31) /* Bit 31: Enable TX Partial Store and Forward Operation */ + +/* RX Partial Store and Forward Register */ + +#define GMAC_RPSF_RPB1ADR_SHIFT (0) /* Bits 0-11: Receive Partial Store and Forward Address */ +#define GMAC_RPSF_RPB1ADR_MASK (0xfff << GMAC_RPSF_RPB1ADR_SHIFT) +# define GMAC_RPSF_RPB1ADR(n) ((uint32_t)(n) << GMAC_RPSF_RPB1ADR_SHIFT) +#define GMAC_RPSF_ENRXP (1 << 31) /* Bit 31: Enable RX Partial Store and Forward Operation */ + +/* Hash Register Bottom [31:0] (32-bit value) */ +/* Hash Register Top [63:32] (32-bit value) */ + +/* Specific Address 1 Bottom [31:0] Register (32-bit value) */ +/* Specific Address 1 Top [47:32] Register */ + +#define GMAC_SAT1_MASK (0x0000ffff) /* Bits 0-15: Specific Address 1 [47:32] */ + +/* Specific Address 2 Bottom [31:0] Register (32-bit value) */ +/* Specific Address 2 Top [47:32] Register */ + +#define GMAC_SAT2_MASK (0x0000ffff) /* Bits 0-15: Specific Address 2 [47:32] */ + +/* Specific Address 3 Bottom [31:0] Register (32-bit value) */ +/* Specific Address 3 Top [47:32] Register */ + +#define GMAC_SAT3_MASK (0x0000ffff) /* Bits 0-15: Specific Address 3 [47:32] */ + +/* Specific Address 4 Bottom [31:0] Register (32-bit value) */ +/* Specific Address 4 Top [47:32] Register */ + +#define GMAC_SAT4_MASK (0x0000ffff) /* Bits 0-15: Specific Address 4 [47:32] */ + +/* Type ID Match 1 Register */ + +#define GMAC_TIDM1_MASK (0x0000ffff) /* Bits 0-15: Type ID Match 1 */ + +/* Type ID Match 2 Register */ + +#define GMAC_TIDM2_MASK (0x0000ffff) /* Bits 0-15: Type ID Match 2 */ + +/* Type ID Match 3 Register */ + +#define GMAC_TIDM3_MASK (0x0000ffff) /* Bits 0-15: Type ID Match 3 */ + +/* Type ID Match 4 Register */ + +#define GMAC_TIDM4_MASK (0x0000ffff) /* Bits 0-15: Type ID Match 4 */ + +/* Wake on LAN Register */ + +#define GMAC_WOL_IP_SHIFT (0) /* Bits 0-15: ARP request IP address */ +#define GMAC_WOL_IP_MASK (0x0000ffff << GMAC_WOL_IP_SHIFT) +#define GMAC_WOL_MAG (1 << 16) /* Bit 16: Magic packet event enable */ +#define GMAC_WOL_ARP (1 << 17) /* Bit 17: ARP request event enable */ +#define GMAC_WOL_SA1 (1 << 18) /* Bit 18: Specific address register 1 event enable */ +#define GMAC_WOL_MTI (1 << 19) /* Bit 19: Multicast hash event enable */ + +/* IPG Stretch Register */ + +#define GMAC_IPGS_MASK (0x0000ffff) /* Bits 0-15: Frame Length */ + +/* Stacked VLAN Register */ + +#define GMAC_SVLAN_VLANTYP_SHIFT (0) /* Bits 0-15: User Defined VLAN_TYPE Field */ +#define GMAC_SVLAN_VLANTYP_MASK (0xffff << GMAC_SVLAN_VLANTYP_SHIFT) +# define GMAC_SVLAN_VLANTYP(n) ((uint32_t)(n) << GMAC_SVLAN_VLANTYP_SHIFT) +#define GMAC_SVLAN_ESVLAN (1 << 31) /* Bit 31: Enable Stacked VLAN Processing Mode */ + +/* Transmit PFC Pause Register */ + +#define GMAC_TPFCP_PEV_SHIFT (0) /* Bits 0-7: Priority Enable Vector */ +#define GMAC_TPFCP_PEV_MASK (0xff << GMAC_TPFCP_PEV_SHIFT) +#define GMAC_TPFCP_PQ_SHIFT (8) /* Bits 8-15: Pause Quantum */ +#define GMAC_TPFCP_PQ_MASK (0xff << GMAC_TPFCP_PQ_SHIFT) + +/* Specific Address 1 Mask Bottom [31:0] Register (32-bit mask) */ +/* Specific Address 1 Mask Top [47:32] Register */ + +#define GMAC_SAMT1_MASK (0x0000ffff) /* Bits 0-15: Specific Address 1 Mask [47:32] */ + +/* Octets Transmitted [31:0] Register (32-bit value) */ +/* Octets Transmitted [47:32] Register */ + +#define GMAC_OTHI_MASK (0x0000ffff) /* Bits 0-15: Transmitted Octets [47:32] */ + +/* Frames Transmitted Register (32-bit value) */ +/* Broadcast Frames Transmitted Register (32-bit value) */ +/* Multicast Frames Transmitted Register (32-bit value) */ + +/* Pause Frames Transmitted Register */ + +#define GMAC_PFT_MASK (0x0000ffff) /* Bits 0-15: Pause Frames Transmitted */ + +/* 64 Byte Frames Transmitted Register (32-bit value) */ +/* 65 to 127 Byte Frames Transmitted Register (32-bit value) */ +/* 128 to 255 Byte Frames Transmitted Register (32-bit value) */ +/* 256 to 511 Byte Frames Transmitted Register (32-bit value) */ +/* 512 to 1023 Byte Frames Transmitted Register (32-bit value) */ +/* 1024 to 1518 Byte Frames Transmitted Register (32-bit value) */ +/* Greater Than 1518 Byte Frames Transmitted Register (32-bit value) */ + +/* Transmit Under Runs Register */ + +#define GMAC_TUR_MASK (0x000003ff) /* Bits 0-9: Transmit Under Runs */ + +/* Single Collision Frames Register */ + +#define GMAC_SCF_MASK (0x0003ffff) /* Bits 0-17: Single Collisions */ + +/* Multiple Collision Frames Register */ + +#define GMAC_MCF_MASK (0x0003ffff) /* Bits 0-17: Multiple Collisions */ + +/* Excessive Collisions Register */ + +#define GMAC_EC_MASK (0x000003ff) /* Bits 0-9: Excessive Collisions */ + +/* Late Collisions Register */ + +#define GMAC_LC_MASK (0x000003ff) /* Bits 0-9: Late Collisions */ + +/* Deferred Transmission Frames Register */ + +#define GMAC_DTF_MASK (0x0003ffff) /* Bits 0-17: Deferred Transmission */ + +/* Carrier Sense Errors Register */ + +#define GMAC_CSE_MASK (0x000003ff) /* Bits 0-9: Carrier Sense Error */ + +/* Octets Received [31:0] Received (32-bit value) */ +/* Octets Received [47:32] Received */ + +#define GMAC_ORHI_MASK (0x0000ffff) /* Bits 0-15: Received Octets [47:32] */ + +/* Frames Received Register (32-bit value) */ +/* Broadcast Frames Received Register (32-bit value) */ +/* Multicast Frames Received Register (32-bit value) */ +/* Pause Frames Received Register */ + +#define GMAC_PFR_MASK (0x0000ffff) /* Bits 0-15: Pause Frames Received */ + +/* 64 Byte Frames Received Register (32-bit value) */ +/* 65 to 127 Byte Frames Received Register (32-bit value) */ +/* 128 to 255 Byte Frames Received Register (32-bit value) */ +/* 256 to 511Byte Frames Received Register (32-bit value) */ +/* 512 to 1023 Byte Frames Received Register (32-bit value) */ +/* 1024 to 1518 Byte Frames Received Register (32-bit value) */ +/* 1519 to Maximum Byte Frames Received Register (32-bit value) */ + +/* Undersize Frames Received Register */ + +#define GMAC_UFR_MASK (0x000003ff) /* Bits 0-9: Undersize Frames Received */ + +/* Oversize Frames Received Register */ + +#define GMAC_OFR_MASK (0x000003ff) /* Bits 0-9: Oversized Frames Received */ + +/* Jabbers Received Register */ + +#define GMAC_JR_MASK (0x000003ff) /* Bits 0-9: Jabbers Received */ + +/* Frame Check Sequence Errors Register */ + +#define GMAC_FCSE_MASK (0x000003ff) /* Bits 0-9: Frame Check Sequence Errors */ + +/* Length Field Frame Errors Register */ + +#define GMAC_LFFE_MASK (0x000003ff) /* Bits 0-9: Length Field Frame Errors */ + +/* Receive Symbol Errors Register */ + +#define GMAC_RSE_MASK (0x000003ff) /* Bits 0-9: Receive Symbol Errors */ + +/* Alignment Errors Register */ + +#define GMAC_AE_MASK (0x000003ff) /* Bits 0-9: Alignment Errors */ + +/* Receive Resource Errors Register */ + +#define GMAC_RRE_MASK (0x0003ffff) /* Bits 0-17: Receive Resource Errors */ + +/* Receive Overrun Register */ + +#define GMAC_ROE_MASK (0x000003ff) /* Bits 0-9: Receive Overruns */ + +/* IP Header Checksum Errors Register */ + +#define GMAC_IHCE_MASK (0x000000ff) /* Bits 0-7: IP Header Checksum Errors */ + +/* TCP Checksum Errors Register */ + +#define GMAC_TCE_MASK (0x000000ff) /* Bits 0-7: TCP Header Checksum Errors */ + +/* UDP Checksum Errors Register */ + +#define GMAC_UCE_MASK (0x000000ff) /* Bits 0-7: UDP Header Checksum Errors */ + +/* 1588 Timer Sync Strobe Seconds Register (32-bit value) */ +/* 1588 Timer Sync Strobe Nanoseconds Register */ + +#define GMAC_TSSN_MASK (0x3fffffff) /* Bits 0-29: Value Timer Nanoseconds Register Capture */ + +/* 1588 Timer Seconds Register (32-bit value) */ +/* 1588 Timer Nanoseconds Register */ + +#define GMAC_TN_MASK (0x3fffffff) /* Bits 0-29: Timer Count in Nanoseconds */ + +/* 1588 Timer Adjust Register */ + +#define GMAC_TA_ITDT_SHIFT (0) /* Bits 0-29: Increment/Decrement */ +#define GMAC_TA_ITDT_MASK (0x3fffffff) +#define GMAC_TA_ADJ (1 << 31) /* Bit 31: Adjust 1588 Timer */ + +/* 1588 Timer Increment Register */ + +#define GMAC_TI_CNS_SHIFT (0) /* Bits 0-7: Count Nanoseconds */ +#define GMAC_TI_CNS_MASK (0xff << GMAC_TI_CNS_SHIFT) +# define GMAC_TI_CNS(n) ((uint32_t)(n) << GMAC_TI_CNS_SHIFT) +#define GMAC_TI_ACNS_SHIFT (8) /* Bits 8-15: Alternative Count Nanoseconds */ +#define GMAC_TI_ACNS_MASK (0xff << GMAC_TI_ACNS_SHIFT) +# define GMAC_TI_ACNS(n) ((uint32_t)(n) << GMAC_TI_ACNS_SHIFT) +#define GMAC_TI_NIT_SHIFT (16) /* Bits 16-23: Number of Increments */ +#define GMAC_TI_NIT_MASK (0xff << GMAC_TI_NIT_SHIFT) +# define GMAC_TI_NIT(n) ((uint32_t)(n) << GMAC_TI_NIT_SHIFT) + +/* PTP Event Frame Transmitted Seconds (32-bit value) */ +/* PTP Event Frame Transmitted Nanoseconds */ + +#define GMAC_EFTN_MASK (0x3fffffff) /* Bits 0-29: Register Update */ + +/* PTP Event Frame Received Seconds (32-bit value) */ +/* PTP Event Frame Received Nanoseconds */ + +#define GMAC_EFRN_MASK (0x3fffffff) /* Bits 0-29: Register Update */ + +/* PTP Peer Event Frame Transmitted Seconds (32-bit value) */ +/* PTP Peer Event Frame Transmitted Nanoseconds */ + +#define GMAC_PEFTN_MASK (0x3fffffff) /* Bits 0-29: Register Update */ + +/* PTP Peer Event Frame Received Seconds (32-bit value) */ +/* PTP Peer Event Frame Received Nanoseconds */ + +#define GMAC_PEFRS_MASK (0x3fffffff) /* Bits 0-29: Register Update */ + +/* Interrupt Status Register Priority Queue 0-6 + * Interrupt Enable Register Priority Queue 0-6 + * Interrupt Disable Register Priority Queue 0-6 + * Interrupt Mask Register Priority Queue 0-6 + * + * Use these definitions: + * + * GMAC_INT_RCOMP Bit 1: Receive Complete + * GMAC_INT_RXUBR Bit 2: Receive Used Bit Read + * GMAC_INT_RLEX Bit 5: Retry Limit Exceeded or Late Collision + * GMAC_INT_TFC Bit 6: Transmit Frame Corruption due to AHB error + * GMAC_INT_TCOMP Bit 7: Transmit Complete + * GMAC_INT_ROVR Bit 10: Receive Overrun + * GMAC_INT_HRESP Bit 11: HRESP not OK + */ + +/* Transmit Buffer Queue Base Address Priority Queue 0-6 */ + +#define GMAC_TBQBAPQ0_MASK (0xfffffffc) /* Bits 2-31: Transmit Buffer Queue Base Address */ + +/* Receive Buffer Queue Base Address Priority Queue 0-6 */ + +#define GMAC_RBQBAPQ0_MASK (0xfffffffc) /* Bits 2-31: Receive Buffer Queue Base Address */ + +/* Receive Buffer Size Register Priority Queue 0-6 */ + +#define GMAC_RBSRPQ0_MASK (0x0000ffff) /* Bits 0-15: Receive Buffer Size */ + +/* Screening Type1 Register Priority Queue 0-15 */ + +#define GMAC_ST1RPQ0_QNB_SHIFT (0) /* Bits 0-3: Que Number (0->7) */ +#define GMAC_ST1RPQ0_QNB_MASK (15 << GMAC_ST1RPQ0_QNB_SHIFT) +# define GMAC_ST1RPQ0_QNB(n) ((uint32_t)(n) << GMAC_ST1RPQ0_QNB_SHIFT) +#define GMAC_ST1RPQ0_DSTCM_SHIFT (4) /* Bits 4-11: Differentiated Services or Traffic Class Match */ +#define GMAC_ST1RPQ0_DSTCM_MASK (0xff << GMAC_ST1RPQ0_DSTCM_SHIFT) +# define GMAC_ST1RPQ0_DSTCM(n) ((uint32_t)(n) << GMAC_ST1RPQ0_DSTCM_SHIFT) +#define GMAC_ST1RPQ0_UDPM_SHIFT (12) /* Bits 12-27: UDP Port Match */ +#define GMAC_ST1RPQ0_UDPM_MASK (0xffff << GMAC_ST1RPQ0_UDPM_SHIFT) +# define GMAC_ST1RPQ0_UDPM(n) ((uint32_t)(n) << GMAC_ST1RPQ0_UDPM_SHIFT) +#define GMAC_ST1RPQ0_DSTCE (1 << 28) /* Bit 28: Differentiated Services or Traffic Class Match Enable */ +#define GMAC_ST1RPQ0_UDPE (1 << 29) /* Bit 29: UDP Port Match Enable */ + +/* Screening Type2 Register Priority Queue 0-15 */ + +#define GMAC_ST2RPQ0_QNB_SHIFT (0) /* Bits 0-3: Que Number (0->7) */ +#define GMAC_ST2RPQ0_QNB_MASK (15 << GMAC_ST2RPQ0_QNB_SHIFT) +# define GMAC_ST2RPQ0_QNB(n) ((uint32_t)(n) << GMAC_ST2RPQ0_QNB_SHIFT) +#define GMAC_ST2RPQ0_VLANP_SHIFT (4) /* Bits 4-7: VLAN Priority */ +#define GMAC_ST2RPQ0_VLANP_MASK (15 << GMAC_ST2RPQ0_VLANP_SHIFT) +# define GMAC_ST2RPQ0_VLANP(n) ((uint32_t)(n) << GMAC_ST2RPQ0_VLANP_SHIFT) +#define GMAC_ST2RPQ0_VLANE (1 << 8) /* Bit 8: VLAN Enable */ + +/* Descriptors **********************************************************************/ + +/* Receive buffer descriptor: Address word */ + +#define GMACRXD_ADDR_OWNER (1 << 0) /* Bit 0: 1=Software owns; 0=GMAC owns */ +#define GMACRXD_ADDR_WRAP (1 << 1) /* Bit 1: Last descriptor in list */ +#define GMACRXD_ADDR_MASK (0xfffffffc) /* Bits 2-31: Aligned buffer address */ + +/* Receive buffer descriptor: Control word */ + +#define GMACRXD_STA_FRLEN_SHIFT (0) /* Bits 0-12: Length of frame */ +#define GMACRXD_STA_FRLEN_MASK (0x00000fff << GMACRXD_STA_FRLEN_SHIFT) +#define GMACRXD_STA_JFRLEN_SHIFT (0) /* Bits 0-13: Length of jumbo frame */ +#define GMACRXD_STA_JFRLEN_MASK (0x00001fff << GMACRXD_STA_JFRLEN_SHIFT) +#define GMACRXD_STA_BADFCS (1 << 13) /* Bit 13: Frame had bad FCS */ +#define GMACRXD_STA_SOF (1 << 14) /* Bit 14: Start of frame */ +#define GMACRXD_STA_EOF (1 << 15) /* Bit 15: End of frame */ +#define GMACRXD_STA_CFI (1 << 16) /* Bit 16: Canonical format indicator (CFI) bit */ +#define GMACRXD_STA_VLPRIO_SHIFT (17) /* Bits 17-19: VLAN priority */ +#define GMACRXD_STA_VLPRIO_MASK (7 << GMACRXD_STA_VLANPRIO_SHIFT) +#define GMACRXD_STA_PRIODET (1 << 20) /* Bit 20: Priority tag detected */ +#define GMACRXD_STA_VLANTAG (1 << 21) /* Bit 21: VLAN tag detected */ +#define GMACRXD_STA_TYPID_SHIFT (22) /* Bits 22-23: Type ID register match */ +#define GMACRXD_STA_TYPID_MASK (3 << GMACRXD_STA_TYPID_SHIFT) +# define GMACRXD_STA_TYPID1 (0 << GMACRXD_STA_TYPID_SHIFT) /* Type ID register 1 match */ +# define GMACRXD_STA_TYPID2 (1 << GMACRXD_STA_TYPID_SHIFT) /* Type ID register 2 match */ +# define GMACRXD_STA_TYPID3 (2 << GMACRXD_STA_TYPID_SHIFT) /* Type ID register 3 match */ +# define GMACRXD_STA_TYPID4 (3 << GMACRXD_STA_TYPID_SHIFT) /* Type ID register 4 match */ +#define GMACRXD_STA_SNAP_SHIFT (22) /* Bits 22-23: Specific Address Register match */ +#define GMACRXD_STA_SNAP_MASK (3 << GMACRXD_STA_SNAP_SHIFT) +# define GMACRXD_STA_SNAP_NOCHK (0 << GMACRXD_STA_SNAP_SHIFT) /* Checksum not checked */ +# define GMACRXD_STA_SNAP_IPCHK (1 << GMACRXD_STA_SNAP_SHIFT) /* IP header checksum checked */ +# define GMACRXD_STA_SNAP_TCPCHK (2 << GMACRXD_STA_SNAP_SHIFT) /* IP header and TCP checksum checked */ +# define GMACRXD_STA_SNAP_UDPCHK (3 << GMACRXD_STA_SNAP_SHIFT) /* IP header and UDP checksum checked */ +#define GMACRXD_STA_TYPID (1 << 24) /* Bit 24: Type ID match found */ +#define GMACRXD_STA_SNAP (1 << 24) /* Bit 24: Frame was SNAP encoded */ +#define GMACRXD_STA_ADDR_SHIFT (25) /* Bits 25-26: Specific Address Register match */ +#define GMACRXD_STA_ADDR_MASK (3 << GMACRXD_STA_ADDR_SHIFT) +# define GMACRXD_STA_ADDR1_MATCH (0 << GMACRXD_STA_ADDR_SHIFT) /* Specific address register 1 match */ +# define GMACRXD_STA_ADDR2_MATCH (1 << GMACRXD_STA_ADDR_SHIFT) /* Specific address register 2 match */ +# define GMACRXD_STA_ADDR3_MATCH (2 << GMACRXD_STA_ADDR_SHIFT) /* Specific address register 3 match */ +# define GMACRXD_STA_ADDR4_MATCH (3 << GMACRXD_STA_ADDR_SHIFT) /* Specific address register 4 match */ +#define GMACRXD_STA_ADDRMATCH (1 << 27) /* Bit 27: Specific Address Register match found */ + /* Bit 28: Reserved */ +#define GMACRXD_STA_UCAST (1 << 29) /* Bit 29: Unicast hash match */ +#define GMACRXD_STA_MCAST (1 << 30) /* Bit 30: Multicast hash match */ +#define GMACRXD_STA_BCAST (1 << 31) /* Bit 31: Global all ones broadcast address detected */ + +/* Transmit buffer descriptor: Address word (un-aligned, 32-bit address */ + +/* Transmit buffer descriptor: Control word */ + +#define GMACTXD_STA_BUFLEN_SHIFT (0) /* Bits 0-13: Length of buffer */ +#define GMACTXD_STA_BUFLEN_MASK (0x00003fff << GMACTXD_STA_BUFLEN_SHIFT) + /* Bit 14: Reserved */ +#define GMACTXD_STA_LAST (1 << 15) /* Bit 15: Last buffer in the current frame */ +#define GMACTXD_STA_NOCRC (1 << 16) /* Bit 16: No CRC */ + /* Bits 17-19: Reserved */ +#define GMACTXD_STA_CKERR_SHIFT (20) /* Bits 20-22: Transmit checksum generation errors */ +#define GMACTXD_STA_CKERR_MASK (7 << GMACTXD_STA_CKERR_SHIFT) +# define GMACTXD_STA_CKERR_OK (0 << GMACTXD_STA_CKERR_SHIFT) /* No Error */ +# define GMACTXD_STA_CKERR_VLAN (1 << GMACTXD_STA_CKERR_SHIFT) /* VLAN header error */ +# define GMACTXD_STA_CKERR_SNAP (2 << GMACTXD_STA_CKERR_SHIFT) /* SNAP header error */ +# define GMACTXD_STA_CKERR_IP (3 << GMACTXD_STA_CKERR_SHIFT) /* Bad IP type */ +# define GMACTXD_STA_CKERR_UNK (4 << GMACTXD_STA_CKERR_SHIFT) /* Not VLAN, SNAP or IP */ +# define GMACTXD_STA_CKERR_FRAG (5 << GMACTXD_STA_CKERR_SHIFT) /* Bad packet fragmentation */ +# define GMACTXD_STA_CKERR_PROTO (6 << GMACTXD_STA_CKERR_SHIFT) /* Not TCP or UDP */ +# define GMACTXD_STA_CKERR_END (7 << GMACTXD_STA_CKERR_SHIFT) /* Premature end of packet */ + /* Bits 23-25: Reserved */ +#define GMACTXD_STA_LCOL (1 << 26) /* Bit 26: Late collision */ +#define GMACTXD_STA_TFC (1 << 27) /* Bit 27: Transmit Frame Corruption due to AHB error */ +#define GMACTXD_STA_TXUR (1 << 28) /* Bit 28: Transmit underrun */ +#define GMACTXD_STA_TXERR (1 << 29) /* Bit 29: Retry limit exceeded, transmit error detected */ +#define GMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */ +#define GMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the GMAC to read from buffer */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Receive buffer descriptor */ + +struct gmac_rxdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* RX status and controls */ +}; + +/* Transmit buffer descriptor */ + +struct gmac_txdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* TX status and controls */ +}; + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GMAC_H */ diff --git a/arch/arm/src/sama5/chip/sam_gpbr.h b/arch/arm/src/sama5/chip/sam_gpbr.h new file mode 100644 index 0000000000000000000000000000000000000000..e9e65880f3a2d7fc1e59450a4356fc25e56eb7e8 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_gpbr.h @@ -0,0 +1,68 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_gpbr.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GPBR_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GPBR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPBR Register Offsets ************************************************************/ + +#define SAM_SYS_GPBR_OFFSET(n) ((n) << 2) /* General Purpose Backup Register n, 1=0..3 */ +#define SAM_SYS_GPBR0_OFFSET 0x0000 /* General Purpose Backup Register 0 */ +#define SAM_SYS_GPBR1_OFFSET 0x0004 /* General Purpose Backup Register 0 */ +#define SAM_SYS_GPBR2_OFFSET 0x0008 /* General Purpose Backup Register 0 */ +#define SAM_SYS_GPBR3_OFFSET 0x000c /* General Purpose Backup Register 0 */ + +/* GPBR Register Addresses **********************************************************/ + +#define SAM_SYS_GPBR(n) (SAM_GPBR_VBASE+SAM_SYS_GPBR_OFFSET(n)) +#define SAM_SYS_GPBR0 (SAM_GPBR_VBASE+SAM_SYS_GPBR0_OFFSET) +#define SAM_SYS_GPBR1 (SAM_GPBR_VBASE+SAM_SYS_GPBR1_OFFSET) +#define SAM_SYS_GPBR2 (SAM_GPBR_VBASE+SAM_SYS_GPBR2_OFFSET) +#define SAM_SYS_GPBR3 (SAM_GPBR_VBASE+SAM_SYS_GPBR3_OFFSET) + +/* GPBR Register Bit Definitions ****************************************************/ +/* All GPBR registers hold user-defined, 32-bit values */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_GPBR_H */ diff --git a/arch/arm/src/sama5/chip/sam_hsmc.h b/arch/arm/src/sama5/chip/sam_hsmc.h new file mode 100644 index 0000000000000000000000000000000000000000..20b06294cae958fb575f354bcef262ce57af443a --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_hsmc.h @@ -0,0 +1,640 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_hsmc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Chip Select Definitions **********************************************************/ + +#define HSMC_CS0 0 +#define HSMC_CS1 1 +#define HSMC_CS2 2 +#define HSMC_CS3 3 + +#define NFCSRAM_BASE SAM_NFCSRAM_VSECTION +#define NFCCMD_BASE SAM_NFCCR_VSECTION + +/* SMC Register Offsets *************************************************************/ + +#define SAM_HSMC_CFG_OFFSET 0x0000 /* HSMC NFC Configuration Register */ +#define SAM_HSMC_CTRL_OFFSET 0x0004 /* HSMC NFC Control Register */ +#define SAM_HSMC_SR_OFFSET 0x0008 /* HSMC NFC Status Register */ +#define SAM_HSMC_IER_OFFSET 0x000c /* HSMC NFC Interrupt Enable Register */ +#define SAM_HSMC_IDR_OFFSET 0x0010 /* HSMC NFC Interrupt Disable Register */ +#define SAM_HSMC_IMR_OFFSET 0x0014 /* HSMC NFC Interrupt Mask Register */ +#define SAM_HSMC_ADDR_OFFSET 0x0018 /* HSMC NFC Address Cycle Zero Register */ +#define SAM_HSMC_BANK_OFFSET 0x001c /* HSMC Bank Address Register */ + /* 0x0020-0x006c Reserved */ +#define SAM_HSMC_PMECCFG_OFFSET 0x0070 /* PMECC Configuration Register */ +#define SAM_HSMC_PMECCSAREA_OFFSET 0x0074 /* PMECC Spare Area Size Register */ +#define SAM_HSMC_PMECCSADDR_OFFSET 0x0078 /* PMECC Start Address Register */ +#define SAM_HSMC_PMECCEADDR_OFFSET 0x007c /* PMECC End Address Register */ + /* 0x0080 Reserved */ +#define SAM_HSMC_PMECCTRL_OFFSET 0x0084 /* PMECC Control Register */ +#define SAM_HSMC_PMECCSR_OFFSET 0x0088 /* PMECC Status Register */ +#define SAM_HSMC_PMECCIER_OFFSET 0x008c /* PMECC Interrupt Enable Register */ +#define SAM_HSMC_PMECCIDR_OFFSET 0x0090 /* PMECC Interrupt Disable Register */ +#define SAM_HSMC_PMECCIMR_OFFSET 0x0094 /* PMECC Interrupt Mask Register */ +#define SAM_HSMC_PMECCISR_OFFSET 0x0098 /* PMECC Interrupt Status Register */ + /* 0x009c-0x00ac Reserved */ +#define SAM_HSMC_PMECC_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC sector offset */ +# define SAM_HSMC_PMECC0_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC Redundancy 0 Register */ +# define SAM_HSMC_PMECC1_OFFSET(n) (0x00b4 + ((n) << 6)) /* PMECC Redundancy 1 Register */ +# define SAM_HSMC_PMECC2_OFFSET(n) (0x00b8 + ((n) << 6)) /* PMECC Redundancy 2 Register */ +# define SAM_HSMC_PMECC3_OFFSET(n) (0x00bc + ((n) << 6)) /* PMECC Redundancy 3 Register */ +# define SAM_HSMC_PMECC4_OFFSET(n) (0x00c0 + ((n) << 6)) /* PMECC Redundancy 4 Register */ +# define SAM_HSMC_PMECC5_OFFSET(n) (0x00c4 + ((n) << 6)) /* PMECC Redundancy 5 Register */ +# define SAM_HSMC_PMECC6_OFFSET(n) (0x00c8 + ((n) << 6)) /* PMECC Redundancy 6 Register */ +# define SAM_HSMC_PMECC7_OFFSET(n) (0x00cc + ((n) << 6)) /* PMECC Redundancy 7 Register */ +# define SAM_HSMC_PMECC8_OFFSET(n) (0x00d0 + ((n) << 6)) /* PMECC Redundancy 8 Register */ +# define SAM_HSMC_PMECC9_OFFSET(n) (0x00d4 + ((n) << 6)) /* PMECC Redundancy 9 Register */ +# define SAM_HSMC_PMECC10_OFFSET(n) (0x00d8 + ((n) << 6)) /* PMECC Redundancy 10 Register */ +#define SAM_HSMC_REM_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder offset */ +# define SAM_HSMC_REM0_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 0 Register */ +# define SAM_HSMC_REM1_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 1 Register */ +# define SAM_HSMC_REM2_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 2 Register */ +# define SAM_HSMC_REM3_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 3 Register */ +# define SAM_HSMC_REM4_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 4 Register */ +# define SAM_HSMC_REM5_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 5 Register */ +# define SAM_HSMC_REM6_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 6 Register */ +# define SAM_HSMC_REM7_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 7 Register */ +# define SAM_HSMC_REM8_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 8 Register */ +# define SAM_HSMC_REM9_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 9 Register */ +# define SAM_HSMC_REM10_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 10 Register */ +# define SAM_HSMC_REM11_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 11 Register */ + /* 0x04a0-0x04fc Reserved */ +#define SAM_HSMC_ELCFG_OFFSET 0x0500 /* PMECC Error Location Configuration Register */ +#define SAM_HSMC_ELPRIM_OFFSET 0x0504 /* PMECC Error Location Primitive Register */ +#define SAM_HSMC_ELEN_OFFSET 0x0508 /* PMECC Error Location Enable Register */ +#define SAM_HSMC_ELDIS_OFFSET 0x050c /* PMECC Error Location Disable Register */ +#define SAM_HSMC_ELSR_OFFSET 0x0510 /* PMECC Error Location Status Register */ +#define SAM_HSMC_ELIER_OFFSET 0x0514 /* PMECC Error Location Interrupt Enable Register */ +#define SAM_HSMC_ELIDR_OFFSET 0x0518 /* PMECC Error Location Interrupt Disable Register */ +#define SAM_HSMC_ELIMR_OFFSET 0x051c /* PMECC Error Location Interrupt Mask Register */ +#define SAM_HSMC_ELISR_OFFSET 0x0520 /* PMECC Error Location Interrupt Status Register */ + /* 0x0524-0x052c Reserved */ +#define SAM_HSMC_SIGMA_OFFSET(n) (0x0528 + ((n) << 2)) /* PMECC Error Location SIGMA n Register */ +# define SAM_HSMC_SIGMA0_OFFSET 0x0528 /* PMECC Error Location SIGMA 0 Register */ +# define SAM_HSMC_SIGMA1_OFFSET 0x052c /* PMECC Error Location SIGMA 1 Register */ +# define SAM_HSMC_SIGMA2_OFFSET 0x0530 /* PMECC Error Location SIGMA 2 Register */ +# define SAM_HSMC_SIGMA3_OFFSET 0x0534 /* PMECC Error Location SIGMA 3 Register */ +# define SAM_HSMC_SIGMA4_OFFSET 0x0538 /* PMECC Error Location SIGMA 4 Register */ +# define SAM_HSMC_SIGMA5_OFFSET 0x053c /* PMECC Error Location SIGMA 5 Register */ +# define SAM_HSMC_SIGMA6_OFFSET 0x0540 /* PMECC Error Location SIGMA 6 Register */ +# define SAM_HSMC_SIGMA7_OFFSET 0x0544 /* PMECC Error Location SIGMA 7 Register */ +# define SAM_HSMC_SIGMA8_OFFSET 0x0548 /* PMECC Error Location SIGMA 8 Register */ +# define SAM_HSMC_SIGMA9_OFFSET 0x054c /* PMECC Error Location SIGMA 9 Register */ +# define SAM_HSMC_SIGMA10_OFFSET 0x0550 /* PMECC Error Location SIGMA 10 Register */ +# define SAM_HSMC_SIGMA11_OFFSET 0x0554 /* PMECC Error Location SIGMA 11 Register */ +# define SAM_HSMC_SIGMA12_OFFSET 0x0558 /* PMECC Error Location SIGMA 12 Register */ +# define SAM_HSMC_SIGMA13_OFFSET 0x055c /* PMECC Error Location SIGMA 13 Register */ +# define SAM_HSMC_SIGMA14_OFFSET 0x0560 /* PMECC Error Location SIGMA 14 Register */ +# define SAM_HSMC_SIGMA15_OFFSET 0x0564 /* PMECC Error Location SIGMA 15 Register */ +# define SAM_HSMC_SIGMA16_OFFSET 0x0568 /* PMECC Error Location SIGMA 16 Register */ +# define SAM_HSMC_SIGMA17_OFFSET 0x056c /* PMECC Error Location SIGMA 17 Register */ +# define SAM_HSMC_SIGMA18_OFFSET 0x0570 /* PMECC Error Location SIGMA 18 Register */ +# define SAM_HSMC_SIGMA19_OFFSET 0x0574 /* PMECC Error Location SIGMA 19 Register */ +# define SAM_HSMC_SIGMA20_OFFSET 0x0578 /* PMECC Error Location SIGMA 20 Register */ +# define SAM_HSMC_SIGMA21_OFFSET 0x057c /* PMECC Error Location SIGMA 21 Register */ +# define SAM_HSMC_SIGMA22_OFFSET 0x0580 /* PMECC Error Location SIGMA 22 Register */ +# define SAM_HSMC_SIGMA23_OFFSET 0x0584 /* PMECC Error Location SIGMA 23 Register */ +# define SAM_HSMC_SIGMA24_OFFSET 0x0588 /* PMECC Error Location SIGMA 24 Register */ +#define SAM_HSMC_ERRLOC_OFFSET(n) (0x058c + ((n) << 2)) /* PMECC Error Location n Register */ +# define SAM_HSMC_ERRLOC0_OFFSET 0x058c /* PMECC Error Location 0 Register */ +# define SAM_HSMC_ERRLOC1_OFFSET 0x0590 /* PMECC Error Location 1 Register */ +# define SAM_HSMC_ERRLOC2_OFFSET 0x0594 /* PMECC Error Location 2 Register */ +# define SAM_HSMC_ERRLOC3_OFFSET 0x0598 /* PMECC Error Location 3 Register */ +# define SAM_HSMC_ERRLOC4_OFFSET 0x059c /* PMECC Error Location 4 Register */ +# define SAM_HSMC_ERRLOC5_OFFSET 0x05a0 /* PMECC Error Location 5 Register */ +# define SAM_HSMC_ERRLOC6_OFFSET 0x05a4 /* PMECC Error Location 6 Register */ +# define SAM_HSMC_ERRLOC7_OFFSET 0x05a8 /* PMECC Error Location 7 Register */ +# define SAM_HSMC_ERRLOC8_OFFSET 0x05ac /* PMECC Error Location 8 Register */ +# define SAM_HSMC_ERRLOC9_OFFSET 0x05b0 /* PMECC Error Location 9 Register */ +# define SAM_HSMC_ERRLOC10_OFFSET 0x05b4 /* PMECC Error Location 10 Register */ +# define SAM_HSMC_ERRLOC11_OFFSET 0x05b0 /* PMECC Error Location 11 Register */ +# define SAM_HSMC_ERRLOC12_OFFSET 0x05bc /* PMECC Error Location 12 Register */ +# define SAM_HSMC_ERRLOC13_OFFSET 0x05c0 /* PMECC Error Location 13 Register */ +# define SAM_HSMC_ERRLOC14_OFFSET 0x05c4 /* PMECC Error Location 14 Register */ +# define SAM_HSMC_ERRLOC15_OFFSET 0x05c8 /* PMECC Error Location 15 Register */ +# define SAM_HSMC_ERRLOC16_OFFSET 0x05cc /* PMECC Error Location 16 Register */ +# define SAM_HSMC_ERRLOC17_OFFSET 0x05d0 /* PMECC Error Location 17 Register */ +# define SAM_HSMC_ERRLOC18_OFFSET 0x05d4 /* PMECC Error Location 18 Register */ +# define SAM_HSMC_ERRLOC19_OFFSET 0x05d8 /* PMECC Error Location 19 Register */ +# define SAM_HSMC_ERRLOC20_OFFSET 0x05dc /* PMECC Error Location 20 Register */ +# define SAM_HSMC_ERRLOC21_OFFSET 0x05e0 /* PMECC Error Location 21 Register */ +# define SAM_HSMC_ERRLOC22_OFFSET 0x05e4 /* PMECC Error Location 22 Register */ +# define SAM_HSMC_ERRLOC23_OFFSET 0x05e8 /* PMECC Error Location 23 Register */ + /* 0x05ec-0x05fc Reserved */ +#define SAM_HSMC_SETUP_OFFSET(n) (0x0600 + 0x14 * (n)) /* HSMC Setup Register */ +#define SAM_HSMC_PULSE_OFFSET(n) (0x0604 + 0x14 * (n)) /* HSMC Pulse Register */ +#define SAM_HSMC_CYCLE_OFFSET(n) (0x0608 + 0x14 * (n)) /* HSMC Cycle Register */ +#define SAM_HSMC_TIMINGS_OFFSET(n) (0x060c + 0x14 * (n)) /* HSMC Timings Register */ +#define SAM_HSMC_MODE_OFFSET(n) (0x0610 + 0x14 * (n)) /* HSMC Mode Register */ +#define SAM_HSMC_OCMS_OFFSET 0x06a0 /* HSMC OCMS Register */ +#define SAM_HSMC_KEY1_OFFSET 0x06a4 /* HSMC OCMS KEY1 Register */ +#define SAM_HSMC_KEY2_OFFSET 0x06a8 /* HSMC OCMS KEY2 Register */ + /* 0x06ac-0x06e0 Reserved */ +#define SAM_HSMC_WPMR_OFFSET 0x06e4 /* HSMC Write Protection Mode Register */ +#define SAM_HSMC_WPSR_OFFSET 0x06e8 /* HSMC Write Protection Status Register */ + /* 0x06fc Reserved */ + +/* SMC Register Addresses ***********************************************************/ + +#define SAM_HSMC_CFG (SAM_HSMC_VBASE+SAM_HSMC_CFG_OFFSET) +#define SAM_HSMC_CTRL (SAM_HSMC_VBASE+SAM_HSMC_CTRL_OFFSET) +#define SAM_HSMC_SR (SAM_HSMC_VBASE+SAM_HSMC_SR_OFFSET) +#define SAM_HSMC_IER (SAM_HSMC_VBASE+SAM_HSMC_IER_OFFSET) +#define SAM_HSMC_IDR (SAM_HSMC_VBASE+SAM_HSMC_IDR_OFFSET) +#define SAM_HSMC_IMR (SAM_HSMC_VBASE+SAM_HSMC_IMR_OFFSET) +#define SAM_HSMC_ADDR (SAM_HSMC_VBASE+SAM_HSMC_ADDR_OFFSET) +#define SAM_HSMC_BANK (SAM_HSMC_VBASE+SAM_HSMC_BANK_OFFSET) +#define SAM_HSMC_PMECCFG (SAM_HSMC_VBASE+SAM_HSMC_PMECCFG_OFFSET) +#define SAM_HSMC_PMECCSAREA (SAM_HSMC_VBASE+SAM_HSMC_PMECCSAREA_OFFSET) +#define SAM_HSMC_PMECCSADDR (SAM_HSMC_VBASE+SAM_HSMC_PMECCSADDR_OFFSET) +#define SAM_HSMC_PMECCEADDR (SAM_HSMC_VBASE+SAM_HSMC_PMECCEADDR_OFFSET) +#define SAM_HSMC_PMECCTRL (SAM_HSMC_VBASE+SAM_HSMC_PMECCTRL_OFFSET) +#define SAM_HSMC_PMECCSR (SAM_HSMC_VBASE+SAM_HSMC_PMECCSR_OFFSET) +#define SAM_HSMC_PMECCIER (SAM_HSMC_VBASE+SAM_HSMC_PMECCIER_OFFSET) +#define SAM_HSMC_PMECCIDR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIDR_OFFSET) +#define SAM_HSMC_PMECCIMR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIMR_OFFSET) +#define SAM_HSMC_PMECCISR (SAM_HSMC_VBASE+SAM_HSMC_PMECCISR_OFFSET) +#define SAM_HSMC_PMECC_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC_OFFSET(n)) +# define SAM_HSMC_PMECC0(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC0_OFFSET(n)) +# define SAM_HSMC_PMECC1(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC1_OFFSET(n)) +# define SAM_HSMC_PMECC2(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC2_OFFSET(n)) +# define SAM_HSMC_PMECC3(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC3_OFFSET(n)) +# define SAM_HSMC_PMECC4(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC4_OFFSET(n)) +# define SAM_HSMC_PMECC5(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC5_OFFSET(n)) +# define SAM_HSMC_PMECC6(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC6_OFFSET(n)) +# define SAM_HSMC_PMECC7(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC7_OFFSET(n)) +# define SAM_HSMC_PMECC8(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC8_OFFSET(n)) +# define SAM_HSMC_PMECC9(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC9_OFFSET(n)) +# define SAM_HSMC_PMECC10(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC10_OFFSET(n)) +#define SAM_HSMC_REM_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_REM_OFFSET(n)) +# define SAM_HSMC_REM0(n) (SAM_HSMC_VBASE+SAM_HSMC_REM0_OFFSET(n)) +# define SAM_HSMC_REM1(n) (SAM_HSMC_VBASE+SAM_HSMC_REM1_OFFSET(n)) +# define SAM_HSMC_REM2(n) (SAM_HSMC_VBASE+SAM_HSMC_REM2_OFFSET(n)) +# define SAM_HSMC_REM3(n) (SAM_HSMC_VBASE+SAM_HSMC_REM3_OFFSET(n)) +# define SAM_HSMC_REM4(n) (SAM_HSMC_VBASE+SAM_HSMC_REM4_OFFSET(n)) +# define SAM_HSMC_REM5(n) (SAM_HSMC_VBASE+SAM_HSMC_REM5_OFFSET(n)) +# define SAM_HSMC_REM6(n) (SAM_HSMC_VBASE+SAM_HSMC_REM6_OFFSET(n)) +# define SAM_HSMC_REM7(n) (SAM_HSMC_VBASE+SAM_HSMC_REM7_OFFSET(n)) +# define SAM_HSMC_REM8(n) (SAM_HSMC_VBASE+SAM_HSMC_REM8_OFFSET(n)) +# define SAM_HSMC_REM9(n) (SAM_HSMC_VBASE+SAM_HSMC_REM9_OFFSET(n)) +# define SAM_HSMC_REM10(n) (SAM_HSMC_VBASE+SAM_HSMC_REM10_OFFSET(n)) +# define SAM_HSMC_REM11(n) (SAM_HSMC_VBASE+SAM_HSMC_REM11_OFFSET(n)) +#define SAM_HSMC_ELCFG (SAM_HSMC_VBASE+SAM_HSMC_ELCFG_OFFSET) +#define SAM_HSMC_ELPRIM (SAM_HSMC_VBASE+SAM_HSMC_ELPRIM_OFFSET) +#define SAM_HSMC_ELEN (SAM_HSMC_VBASE+SAM_HSMC_ELEN_OFFSET) +#define SAM_HSMC_ELDIS (SAM_HSMC_VBASE+SAM_HSMC_ELDIS_OFFSET) +#define SAM_HSMC_ELSR (SAM_HSMC_VBASE+SAM_HSMC_ELSR_OFFSET) +#define SAM_HSMC_ELIER (SAM_HSMC_VBASE+SAM_HSMC_ELIER_OFFSET) +#define SAM_HSMC_ELIDR (SAM_HSMC_VBASE+SAM_HSMC_ELIDR_OFFSET) +#define SAM_HSMC_ELIMR (SAM_HSMC_VBASE+SAM_HSMC_ELIMR_OFFSET) +#define SAM_HSMC_ELISR (SAM_HSMC_VBASE+SAM_HSMC_ELISR_OFFSET) +#define SAM_HSMC_SIGMA_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_SIGMA_OFFSET(n)) +# define SAM_HSMC_SIGMA0 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA0_OFFSET) +# define SAM_HSMC_SIGMA1 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA1_OFFSET) +# define SAM_HSMC_SIGMA2 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA2_OFFSET) +# define SAM_HSMC_SIGMA3 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA3_OFFSET) +# define SAM_HSMC_SIGMA4 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA4_OFFSET) +# define SAM_HSMC_SIGMA5 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA5_OFFSET) +# define SAM_HSMC_SIGMA6 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA6_OFFSET) +# define SAM_HSMC_SIGMA7 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA7_OFFSET) +# define SAM_HSMC_SIGMA8 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA8_OFFSET) +# define SAM_HSMC_SIGMA9 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA9_OFFSET) +# define SAM_HSMC_SIGMA10 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA10_OFFSET) +# define SAM_HSMC_SIGMA11 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA11_OFFSET) +# define SAM_HSMC_SIGMA12 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA12_OFFSET) +# define SAM_HSMC_SIGMA13 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA13_OFFSET) +# define SAM_HSMC_SIGMA14 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA14_OFFSET) +# define SAM_HSMC_SIGMA15 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA15_OFFSET) +# define SAM_HSMC_SIGMA16 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA16_OFFSET) +# define SAM_HSMC_SIGMA17 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA17_OFFSET) +# define SAM_HSMC_SIGMA18 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA18_OFFSET) +# define SAM_HSMC_SIGMA19 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA19_OFFSET) +# define SAM_HSMC_SIGMA20 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA20_OFFSET) +# define SAM_HSMC_SIGMA21 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA21_OFFSET) +# define SAM_HSMC_SIGMA22 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA22_OFFSET) +# define SAM_HSMC_SIGMA23 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA23_OFFSET) +# define SAM_HSMC_SIGMA24 (SAM_HSMC_VBASE+SAM_HSMC_SIGMA24_OFFSET) +#define SAM_HSMC_ERRLOC_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC_OFFSET(n)) +# define SAM_HSMC_ERRLOC0 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC0_OFFSET) +# define SAM_HSMC_ERRLOC1 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC1_OFFSET) +# define SAM_HSMC_ERRLOC2 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC2_OFFSET) +# define SAM_HSMC_ERRLOC3 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC3_OFFSET) +# define SAM_HSMC_ERRLOC4 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC4_OFFSET) +# define SAM_HSMC_ERRLOC5 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC5_OFFSET) +# define SAM_HSMC_ERRLOC6 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC6_OFFSET) +# define SAM_HSMC_ERRLOC7 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC7_OFFSET) +# define SAM_HSMC_ERRLOC8 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC8_OFFSET) +# define SAM_HSMC_ERRLOC9 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC9_OFFSET) +# define SAM_HSMC_ERRLOC10 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC10_OFFSET) +# define SAM_HSMC_ERRLOC11 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC11_OFFSET) +# define SAM_HSMC_ERRLOC12 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC12_OFFSET) +# define SAM_HSMC_ERRLOC13 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC13_OFFSET) +# define SAM_HSMC_ERRLOC14 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC14_OFFSET) +# define SAM_HSMC_ERRLOC15 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC15_OFFSET) +# define SAM_HSMC_ERRLOC16 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC16_OFFSET) +# define SAM_HSMC_ERRLOC17 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC17_OFFSET) +# define SAM_HSMC_ERRLOC18 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC18_OFFSET) +# define SAM_HSMC_ERRLOC19 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC19_OFFSET) +# define SAM_HSMC_ERRLOC20 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC20_OFFSET) +# define SAM_HSMC_ERRLOC21 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC21_OFFSET) +# define SAM_HSMC_ERRLOC22 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC22_OFFSET) +# define SAM_HSMC_ERRLOC23 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC23_OFFSET) +#define SAM_HSMC_SETUP(n) (SAM_HSMC_VBASE+SAM_HSMC_SETUP_OFFSET(n)) +#define SAM_HSMC_PULSE(n) (SAM_HSMC_VBASE+SAM_HSMC_PULSE_OFFSET(n)) +#define SAM_HSMC_CYCLE(n) (SAM_HSMC_VBASE+SAM_HSMC_CYCLE_OFFSET(n)) +#define SAM_HSMC_TIMINGS(n) (SAM_HSMC_VBASE+SAM_HSMC_TIMINGS_OFFSET(n)) +#define SAM_HSMC_MODE(n) (SAM_HSMC_VBASE+SAM_HSMC_MODE_OFFSET(n)) +#define SAM_HSMC_OCMS (SAM_HSMC_VBASE+SAM_HSMC_OCMS_OFFSET) +#define SAM_HSMC_KEY1 (SAM_HSMC_VBASE+SAM_HSMC_KEY1_OFFSET) +#define SAM_HSMC_KEY2 (SAM_HSMC_VBASE+SAM_HSMC_KEY2_OFFSET) +#define SAM_HSMC_WPMR (SAM_HSMC_VBASE+SAM_HSMC_WPMR_OFFSET) +#define SAM_HSMC_WPSR (SAM_HSMC_VBASE+SAM_HSMC_WPSR_OFFSET) + +/* SMC Register Bit Definitions *****************************************************/ + +/* HSMC NFC Configuration Register */ + +#define HSMC_CFG_PAGESIZE_SHIFT (0) /* Bit 0-2: */ +#define HSMC_CFG_PAGESIZE_MASK (7 << HSMC_CFG_PAGESIZE_SHIFT) +# define HSMC_CFG_PAGESIZE_512 (0 << HSMC_CFG_PAGESIZE_SHIFT) /* Main area 512 Bytes */ +# define HSMC_CFG_PAGESIZE_1024 (1 << HSMC_CFG_PAGESIZE_SHIFT) /* Main area 1024 Bytes */ +# define HSMC_CFG_PAGESIZE_2048 (2 << HSMC_CFG_PAGESIZE_SHIFT) /* Main area 2048 Bytes */ +# define HSMC_CFG_PAGESIZE_4096 (3 << HSMC_CFG_PAGESIZE_SHIFT) /* Main area 4096 Bytes */ +# define HSMC_CFG_PAGESIZE_8192 (4 << HSMC_CFG_PAGESIZE_SHIFT) /* Main area 8192 Bytes */ +#define HSMC_CFG_WSPARE (1 << 8) /* Bit 8: Write Spare Area */ +#define HSMC_CFG_RSPARE (1 << 9) /* Bit 9: Read Spare Area */ +#define HSMC_CFG_EDGECTRL (1 << 12) /* Bit 12: Rising/Falling Edge Detection Control */ +#define HSMC_CFG_RBEDGE (1 << 13) /* Bit 13: Ready/Busy Signal Edge Detection */ +#define HSMC_CFG_DTOCYC_SHIFT (16) /* Bit 16-19: Data Timeout Cycle Number */ +#define HSMC_CFG_DTOCYC_MASK (15 << HSMC_CFG_DTOCYC_SHIFT) +# define HSMC_CFG_DTOCYC(n) ((uint32_t)(n) << HSMC_CFG_DTOCYC_SHIFT) +#define HSMC_CFG_DTOMUL_SHIFT (20) /* Bit 20-22: Data Timeout Multiplier */ +#define HSMC_CFG_DTOMUL_MASK (7 << HSMC_CFG_DTOMUL_SHIFT) +# define HSMC_CFG_DTOMUL_1 (0 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC */ +# define HSMC_CFG_DTOMUL_16 (1 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 16 */ +# define HSMC_CFG_DTOMUL_128 (2 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 128 */ +# define HSMC_CFG_DTOMUL_256 (3 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 256 */ +# define HSMC_CFG_DTOMUL_1024 (4 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 1024 */ +# define HSMC_CFG_DTOMUL_4096 (5 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 4096 */ +# define HSMC_CFG_DTOMUL_65536 (6 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 65536 */ +# define HSMC_CFG_DTOMUL_1048576 (7 << HSMC_CFG_DTOMUL_SHIFT) /* DTOCYC x 1048576 */ +#define HSMC_CFG_NFCSPARESIZE_SHIFT (24) /* Bit 24-30: NAND Flash Spare Area Size */ +#define HSMC_CFG_NFCSPARESIZE_MASK (0x7f << HSMC_CFG_NFCSPARESIZE_SHIFT) +# define HSMC_CFG_NFCSPARESIZE(n) ((uint32_t)(n) << HSMC_CFG_NFCSPARESIZE_SHIFT) + +/* HSMC NFC Control Register */ + +#define HSMC_CTRL_NFCEN (1 << 0) /* Bit 0: NAND Flash Controller Enable */ +#define HSMC_CTRL_NFCDIS (1 << 1) /* Bit 1: NAND Flash Controller Disable */ + +/* HSMC NFC Status Register */ +/* HSMC NFC Interrupt Enable Register */ +/* HSMC NFC Interrupt Disable Register */ +/* HSMC NFC Interrupt Mask Register */ + +#define HSMC_SR_SMCSTS (1 << 0) /* Bit 0: NAND Flash Controller Status (SR only) */ +#define HSMC_NFCINT_RB_RISE (1 << 4) /* Bit 4: Ready Busy Rising Edge Detection Interrupt */ +#define HSMC_NFCINT_RB_FALL (1 << 5) /* Bit 5: Ready Busy Falling Edge Detection Interrupt */ +#define HSMC_SR_NFCBUSY (1 << 8) /* Bit 8: NFC Busy (SR only) */ +#define HSMC_SR_NFCWR (1 << 11) /* Bit 11: NFC Write/Read Operation (SR only) */ +#define HSMC_SR_NFCSID_SHIFT (12) /* Bits 12-14: NFC Chip Select ID (SR only) */ +#define HSMC_SR_NFCSID_MASK (7 << HSMC_SR_NFCSID_SHIFT) +#define HSMC_NFCINT_XFRDONE (1 << 16) /* Bit 16: Transfer Done Interrupt */ +#define HSMC_NFCINT_CMDDONE (1 << 17) /* Bit 17: Command Done Interrupt */ +#define HSMC_NFCINT_DTOE (1 << 20) /* Bit 20: Data Timeout Error Interrupt Enable */ +#define HSMC_NFCINT_UNDEF (1 << 21) /* Bit 21: Undefined Area Access Interrupt */ +#define HSMC_NFCINT_AWB (1 << 22) /* Bit 22: Accessing While Busy Interrupt */ +#define HSMC_NFCINT_NFCASE (1 << 23) /* Bit 23: NFC Access Size Error Interrupt */ +#define HSMC_NFCINT_RBEDGE0 (1 << 24) /* Bit 24: Ready/Busy Line 0 Interrupt */ + +#define HSMC_NFCINT_ALL (0x01f30030) + +/* HSMC NFC Address Cycle Zero Register */ + +#define HSMC_ADDR_MASK (0xff) /* Bits 0-7: NAND Flash Array Address Cycle 0 */ + +/* HSMC Bank Address Register */ + +#define HSMC_BANK (1 << 0) /* Bit 0: Bank Identifier */ + +/* PMECC Configuration Register */ + +#define HSMC_PMECCFG_BCHERR_SHIFT (0) /* Bit 0-2: Error Correcting Capability */ +#define HSMC_PMECCFG_BCHERR_MASK (7 << HSMC_PMECCFG_BCHERR_SHIFT) +# define HSMC_PMECCFG_BCHERR_2 (0 << HSMC_PMECCFG_BCHERR_SHIFT) /* 2 errors */ +# define HSMC_PMECCFG_BCHERR_4 (1 << HSMC_PMECCFG_BCHERR_SHIFT) /* 4 errors */ +# define HSMC_PMECCFG_BCHERR_8 (2 << HSMC_PMECCFG_BCHERR_SHIFT) /* 8 errors */ +# define HSMC_PMECCFG_BCHERR_12 (3 << HSMC_PMECCFG_BCHERR_SHIFT) /* 12 errors */ +# define HSMC_PMECCFG_BCHERR_24 (4 << HSMC_PMECCFG_BCHERR_SHIFT) /* 24 errors */ +#define HSMC_PMECCFG_SECTORSZ_SHIFT (4) /* Bit 4: Sector Size */ +#define HSMC_PMECCFG_SECTORSZ_MASK (1 << HSMC_PMECCFG_SECTORSZ_SHIFT) +# define HSMC_PMECCFG_SECTORSZ_512 (0 << HSMC_PMECCFG_SECTORSZ_SHIFT) +# define HSMC_PMECCFG_SECTORSZ_1024 (1 << HSMC_PMECCFG_SECTORSZ_SHIFT) +#define HSMC_PMECCFG_PAGESIZE_SHIFT (8) /* Bit 8-9: Number of Sectors in the Page */ +#define HSMC_PMECCFG_PAGESIZE_MASK (3 << HSMC_PMECCFG_PAGESIZE_SHIFT) +# define HSMC_PMECCFG_PAGESIZE_1SEC (0 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 1 sector (5121K) */ +# define HSMC_PMECCFG_PAGESIZE_2SEC (1 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 2 sectors (1/2K) */ +# define HSMC_PMECCFG_PAGESIZE_4SEC (2 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 4 sectors (2/4K) */ +# define HSMC_PMECCFG_PAGESIZE_8SEC (3 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 8 sectors (4/8K) */ +#define HSMC_PMECCFG_NANDWR_SHIFT (12) /* Bit 12: NAND Write Access */ +#define HSMC_PMECCFG_NANDWR_MASK (1 << HSMC_PMECCFG_NANDWR_SHIFT) +# define HSMC_PMECCFG_NANDWR_READ (0 << HSMC_PMECCFG_NANDWR_SHIFT) +# define HSMC_PMECCFG_NANDWR_WRITE (1 << HSMC_PMECCFG_NANDWR_SHIFT) +#define HSMC_PMECCFG_SPAREEN_SHIFT (16) /* Bit 16: Spare Enable */ +#define HSMC_PMECCFG_SPAREEN_MASK (1 << HSMC_PMECCFG_SPAREEN_SHIFT) +# define HSMC_PMECCFG_SPARE_DISABLE (0 << HSMC_PMECCFG_SPAREEN_SHIFT) +# define HSMC_PMECCFG_SPARE_ENABLE (1 << HSMC_PMECCFG_SPAREEN_SHIFT) +#define HSMC_PMECCFG_AUTO_SHIFT (20) /* Bit 20: Automatic Mode Enable */ +#define HSMC_PMECCFG_AUTO_MASK (1 << HSMC_PMECCFG_AUTO_SHIFT) +# define HSMC_PMECCFG_AUTO_DISABLE (0 << HSMC_PMECCFG_AUTO_SHIFT) +# define HSMC_PMECCFG_AUTO_ENABLE (1 << HSMC_PMECCFG_AUTO_SHIFT) + +/* PMECC Spare Area Size Register */ + +#define HSMC_PMECCSAREA_MASK (0x1ff) /* Bits 0-8: Spare Area Size */ + +/* PMECC Start Address Register */ + +#define HSMC_PMECCSADDR_MASK (0x1ff) /* Bits 0-8: ECC Area Start Address */ + +/* PMECC End Address Register */ + +#define HSMC_PMECCEADDR_MASK (0x1ff) /* Bits 0-8: ECC Area End Address */ + +/* PMECC Control Register */ + +#define HSMC_PMECCTRL_RST (1 << 0) /* Bit 0: Reset the PMECC Module */ +#define HSMC_PMECCTRL_DATA (1 << 1) /* Bit 1: Start a Data Phase */ +#define HSMC_PMECCTRL_USER (1 << 2) /* Bit 2: Start a User Mode Phase */ +#define HSMC_PMECCTRL_ENABLE (1 << 4) /* Bit 4: PMECC Enable */ +#define HSMC_PMECCTRL_DISABLE (1 << 5) /* Bit 5: PMECC Enable */ + +/* PMECC Status Register */ + +#define HSMC_PMECCSR_BUSY (1 << 0) /* Bit 0: The kernel of the PMECC is busy */ +#define HSMC_PMECCSR_ENABLE (1 << 4) /* Bit 4: PMECC Enable bit */ + +/* PMECC Interrupt Enable Register */ +/* PMECC Interrupt Disable Register */ +/* PMECC Interrupt Mask Register */ + +#define HSMC_PMECCINT_ERRI (1 << 0) /* Bit 0: Error Interrupt */ + +/* PMECC Interrupt Status Register */ + +#define HSMC_PMECCISR_ERRIS_SHIFT (0) /* Bits 0-7: Error Interrupt Status */ +#define HSMC_PMECCISR_ERRIS_MASK (0xff << HSMC_PMECCISR_ERRIS_SHIFT) +# define HSMC_PMECCISR_ERRIS(n) (1 << (n)) /* Bits n: Error on sector n */ + +/* PMECC Redundancy x Register (32-bit ECC value) */ + +/* PMECC Remainder x Register */ + +#define HSMC_REM_REM2NP1_SHIFT (0) /* Bit 0-13: BCH Remainder 2 * N + 1 */ +#define HSMC_REM_REM2NP1_MASK (0x3fff << HSMC_REM_REM2NP1_SHIFT) +#define HSMC_REM_REM2NP3_SHIFT (16) /* Bit 16-29: BCH Remainder 2 * N + 3 */ +#define HSMC_REM_REM2NP3_MASK (0x3fff << HSMC_REM_REM2NP3_SHIFT) + +/* PMECC Error Location Configuration Register */ + +#define HSMC_ELCFG_SECTORSZ_SHIFT (0) /* Bit 0: Sector Size */ +#define HSMC_ELCFG_SECTORSZ_MASK (1 << HSMC_ELCFG_SECTORSZ_SHIFT) +# define HSMC_ELCFG_SECTORSZ_512 (0 << HSMC_ELCFG_SECTORSZ_SHIFT) +# define HSMC_ELCFG_SECTORSZ_1024 (1 << HSMC_ELCFG_SECTORSZ_SHIFT) +#define HSMC_ELCFG_ERRNUM_SHIFT (16) /* Bit 16-20: Number of Errors */ +#define HSMC_ELCFG_ERRNUM_MASK (0x1f << HSMC_ELCFG_ERRNUM_SHIFT) +# define HSMC_ELCFG_ERRNUM(n) ((uint32_t)(n) << HSMC_ELCFG_ERRNUM_SHIFT) + +/* PMECC Error Location Primitive Register */ + +#define HSMC_ELPRIM_MASK (0xffff) /* Bits 0-15: Primitive Polynomial */ + +/* PMECC Error Location Enable Register */ + +#define HSMC_ELEN_MASK (0x3fff) /* Bits 0-13: Error Location Enable */ + +/* PMECC Error Location Disable Register */ + +#define HSMC_ELDIS_DIS (1 << 0) /* Bit 0: Disable Error Location Engine */ + +/* PMECC Error Location Status Register */ + +#define HSMC_ELSR_BUSY (1 << 0) /* Bit 0: Error Location Engine Busy */ + +/* PMECC Error Location Interrupt Enable Register */ +/* PMECC Error Location Interrupt Disable Register */ +/* PMECC Error Location Interrupt Mask Register */ + +#define HSMC_ELIINT_DONE (1 << 0) /* Bit 0: Computation Terminated Interrupt */ +#define HSMC_ELISR_ERRCNT_SHIFT (8) /* Bit 8-12: Error Counter value (SR only) */ +#define HSMC_ELISR_ERRCNT_MASK (0x1f << HSMC_ELISR_ERRCNT_SHIFT) + +/* PMECC Error Location SIGMA x Register */ + +#define HSMC_SIGMA_MASK (0x3fff) /* Bits 0-13: Coefficient of degree x in the SIGMA polynomial */ + +/* PMECC Error Location x Register */ + +#define HSMC_ERRLOC_MASK (0x3fff) /* Bits 0-13: Error Position within the Set */ + +/* HSMC Setup Register */ + +#define HSMC_SETUP_NWE_SETUP_SHIFT (0) /* Bit 0-5: NWE Setup Length */ +#define HSMC_SETUP_NWE_SETUP_MASK (0x3f << HSMC_SETUP_NWE_SETUP_SHIFT) +# define HSMC_SETUP_NWE_SETUP(n) ((n) << HSMC_SETUP_NWE_SETUP_SHIFT) +#define HSMC_SETUP_NCS_WRSETUP_SHIFT (8) /* Bit 8-13: NCS Setup Length in Write Access */ +#define HSMC_SETUP_NCS_WRSETUP_MASK (0x3f << HSMC_SETUP_NCS_WRSETUP_SHIFT) +# define HSMC_SETUP_NCS_WRSETUP(n) ((n) << HSMC_SETUP_NCS_WRSETUP_SHIFT) +#define HSMC_SETUP_NRD_SETUP_SHIFT (16) /* Bit 16-21: NRD Setup Length */ +#define HSMC_SETUP_NRD_SETUP_MASK (0x3f << HSMC_SETUP_NRD_SETUP_SHIFT) +# define HSMC_SETUP_NRD_SETUP(n) ((n) << HSMC_SETUP_NRD_SETUP_SHIFT) +#define HSMC_SETUP_NCS_RDSETUP_SHIFT (24) /* Bit 24-29: NCS Setup Length in Read Access */ +#define HSMC_SETUP_NCS_RDSETUP_MASK (0x3f << HSMC_SETUP_NCS_RDSETUP_SHIFT) +# define HSMC_SETUP_NCS_RDSETUP(n) ((n) << HSMC_SETUP_NCS_RDSETUP_SHIFT) + +/* HSMC Pulse Register */ + +#define HSMC_PULSE_NWE_PULSE_SHIFT (0) /* Bit 0-5: NWE Pulse Length */ +#define HSMC_PULSE_NWE_PULSE_MASK (0x3f << HSMC_PULSE_NWE_PULSE_SHIFT) +# define HSMC_PULSE_NWE_PULSE(n) ((n) << HSMC_PULSE_NWE_PULSE_SHIFT) +#define HSMC_PULSE_NCS_WRPULSE_SHIFT (8) /* Bit 8-13: NCS Pulse Length in WRITE Access */ +#define HSMC_PULSE_NCS_WRPULSE_MASK (0x3f << HSMC_PULSE_NCS_WRPULSE_SHIFT) +# define HSMC_PULSE_NCS_WRPULSE(n) ((n) << HSMC_PULSE_NCS_WRPULSE_SHIFT) +#define HSMC_PULSE_NRD_PULSE_SHIFT (16) /* Bit 16-21: NRD Pulse Length */ +#define HSMC_PULSE_NRD_PULSE_MASK (0x3f << HSMC_PULSE_NRD_PULSE_SHIFT) +# define HSMC_PULSE_NRD_PULSE(n) ((n) << HSMC_PULSE_NRD_PULSE_SHIFT) +#define HSMC_PULSE_NCS_RDPULSE_SHIFT (24) /* Bit 24-29: NCS Pulse Length in READ Access */ +#define HSMC_PULSE_NCS_RDPULSE_MASK (0x3f << HSMC_PULSE_NCS_RDPULSE_SHIFT) +# define HSMC_PULSE_NCS_RDPULSE(n) ((n) << HSMC_PULSE_NCS_RDPULSE_SHIFT) + +/* HSMC Cycle Register */ + +#define HSMC_CYCLE_NWE_CYCLE_SHIFT (0) /* Bit 0-8: Total Write Cycle Length */ +#define HSMC_CYCLE_NWE_CYCLE_MASK (0x1ff << HSMC_CYCLE_NWE_CYCLE_SHIFT) + #define HSMC_CYCLE_NWE_CYCLE(n) ((n) << HSMC_CYCLE_NWE_CYCLE_SHIFT) +#define HSMC_CYCLE_NRD_CYCLE_SHIFT (16) /* Bit 16-24: Total Read Cycle Length */ +#define HSMC_CYCLE_NRD_CYCLE_MASK (0x1ff << HSMC_CYCLE_NRD_CYCLE_SHIFT) +# define HSMC_CYCLE_NRD_CYCLE(n) ((n) << HSMC_CYCLE_NRD_CYCLE_SHIFT) + +/* HSMC Timings Register */ + +#define HSMC_TIMINGS_TCLR_SHIFT (0) /* Bit 0-3: CLE to REN Low Delay */ +#define HSMC_TIMINGS_TCLR_MASK (15 << HSMC_TIMINGS_TCLR_SHIFT) +# define HSMC_TIMINGS_TCLR(n) ((n) << HSMC_TIMINGS_TCLR_SHIFT) +#define HSMC_TIMINGS_TADL_SHIFT (4) /* Bit 4-7: ALE to Data Start */ +#define HSMC_TIMINGS_TADL_MASK (15 << HSMC_TIMINGS_TADL_SHIFT) +# define HSMC_TIMINGS_TADL(n) ((n) << HSMC_TIMINGS_TADL_SHIFT) +#define HSMC_TIMINGS_TAR_SHIFT (8) /* Bit 8-11: ALE to REN Low Delay */ +#define HSMC_TIMINGS_TAR_MASK (15 << HSMC_TIMINGS_TAR_SHIFT) +# define HSMC_TIMINGS_TAR(n) ((n) << HSMC_TIMINGS_TAR_SHIFT) +#define HSMC_TIMINGS_OCMS (1 << 12) /* Bit 12: Off Chip Memory Scrambling Enable */ +#define HSMC_TIMINGS_TRR_SHIFT (16) /* Bit 16-19: Ready to REN Low Delay */ +#define HSMC_TIMINGS_TRR_MASK (15 << HSMC_TIMINGS_TRR_SHIFT) +# define HSMC_TIMINGS_TRR(n) ((n) << HSMC_TIMINGS_TRR_SHIFT) +#define HSMC_TIMINGS_TWB_SHIFT (24) /* Bit 24-27: WEN High to REN to Busy */ +#define HSMC_TIMINGS_TWB_MASK (15 << HSMC_TIMINGS_TWB_SHIFT) +# define HSMC_TIMINGS_TWB(n) ((n) << HSMC_TIMINGS_TWB_SHIFT) +#define HSMC_TIMINGS_RBNSEL_SHIFT (28) /* Bit 28-30: Ready/Busy Line Selection */ +#define HSMC_TIMINGS_RBNSEL_MASK (7 << HSMC_TIMINGS_RBNSEL_SHIFT) +# define HSMC_TIMINGS_RBNSEL(n) ((n) << HSMC_TIMINGS_RBNSEL_SHIFT) +#define HSMC_TIMINGS_NFSEL (1 << 31) /* Bit 31: NAND Flash Selection */ + +/* HSMC Mode Register */ + +#define HSMC_MODE_READMODE (1 << 0) /* Bit 0: */ +#define HSMC_MODE_WRITEMODE (1 << 1) /* Bit 1: */ +#define HSMC_MODE_EXNWMODE_SHIFT (4) /* Bit 4-5: NWAIT Mode */ +#define HSMC_MODE_EXNWMODE_MASK (3 << HSMC_MODE_EXNWMODE_SHIFT) +# define HSMC_MODE_EXNWMODE_DISABLED (0 << HSMC_MODE_EXNWMODE_SHIFT) /* Disabled */ +# define HSMC_MODE_EXNWMODE_FROZEN (2 << HSMC_MODE_EXNWMODE_SHIFT) /* Frozen Mode */ +# define HSMC_MODE_EXNWMODE_READY (3 << HSMC_MODE_EXNWMODE_SHIFT) /* Ready Mode */ +#define HSMC_MODE_BAT (1 << 8) /* Bit 8: Byte Access Type */ +#define HSMC_MODE_DBW (1 << 12) /* Bit 12: Data Bus Width */ +# define HSMC_MODE_BIT_8 (0) /* 0=8-bit bus */ +# define HSMC_MODE_BIT_16 HSMC_MODE_DBW /* 1=16-bit bus */ +#define HSMC_MODE_TDFCYCLES_SHIFT (16) /* Bit 16-19: Data Float Time */ +#define HSMC_MODE_TDFCYCLES_MASK (15 << HSMC_MODE_TDFCYCLES_SHIFT) +# define HSMC_MODE_TDFCYCLES(n) ((n) << HSMC_MODE_TDFCYCLES_SHIFT) +#define HSMC_MODE_TDFMODE (1 << 20) /* Bit 20: TDF Optimization */ + +/* HSMC OCMS Register */ + +#define HSMC_OCMS_SMSE (1 << 0) /* Bit 0: Static Memory Controller Scrambling Enable */ +#define HSMC_OCMS_SRSE (1 << 1) /* Bit 1: SRAM Scrambling Enable */ + +/* HSMC OCMS KEY1 Register (32-bits of 64-bit key value) */ +/* HSMC OCMS KEY2 Register (32-bits of 64-bit key value) */ + +/* HSMC Write Protection Mode Register */ + +#define HSMC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define HSMC_WPMR_WPKEY_SHIFT (8) /* Bit 8-31: Write Protection KEY password */ +#define HSMC_WPMR_WPKEY_MASK (0x00ffffff << HSMC_WPMR_WPKEY_SHIFT) +# define HSMC_WPMR_WPKEY (0x00534d43 << HSMC_WPMR_WPKEY_SHIFT) + +/* HSMC Write Protection Status Register */ + +#define HSMC_WPSR_WPVS_SHIFT (0) /* Bit 0-3: Write Protection Violation Status */ +#define HSMC_WPSR_WPVS_MASK (15 << HSMC_WPSR_WPVS_SHIFT) +#define HSMC_WPSR_WPVSRC_SHIFT (8) /* Bit 8-23: Write Protection Violation Source */ +#define HSMC_WPSR_WPVSRC_MASK (0xffff << HSMC_WPSR_WPVSRC_SHIFT) + +/* NFC Command/Data Registers *******************************************************/ + +/* NFC Command and Status Registers */ + +#define NFCADDR_CMD_CMD1_SHIFT (2) /* Bits 2-9: Command Register Value for Cycle 1 */ +#define NFCADDR_CMD_CMD1_MASK (0xff << NFCADDR_CMD_CMD1_SHIFT) +# define NFCADDR_CMD_CMD1(n) ((uint32_t)(n) << NFCADDR_CMD_CMD1_SHIFT) +#define NFCADDR_CMD_CMD2_SHIFT (10) /* Bits 10-17: Command Register Value for Cycle 1 */ +#define NFCADDR_CMD_CMD2_MASK (0xff << NFCADDR_CMD_CMD2_SHIFT) +# define NFCADDR_CMD_CMD2(n) ((uint32_t)(n) << NFCADDR_CMD_CMD2_SHIFT) +#define NFCADDR_CMD_VCMD2 (1 << 18) /* Bit 18:Valid Cycle 2 Command */ +#define NFCADDR_CMD_ACYCLE_SHIFT (19) /* Bits 19-21: Number of Address required for command */ +#define NFCADDR_CMD_ACYCLE_MASK (7 << NFCADDR_CMD_ACYCLE_SHIFT) +# define NFCADDR_CMD_ACYCLE(n) ((uint32_t)(n) << NFCADDR_CMD_ACYCLE_SHIFT) /* n address cycles, n=0-5 */ +# define NFCADDR_CMD_ACYCLE_NONE (0 << NFCADDR_CMD_ACYCLE_SHIFT) /* No address cycle */ +# define NFCADDR_CMD_ACYCLE_ONE (1 << NFCADDR_CMD_ACYCLE_SHIFT) /* One address cycle */ +# define NFCADDR_CMD_ACYCLE_TWO (2 << NFCADDR_CMD_ACYCLE_SHIFT) /* Two address cycles */ +# define NFCADDR_CMD_ACYCLE_THREE (3 << NFCADDR_CMD_ACYCLE_SHIFT) /* Three address cycles */ +# define NFCADDR_CMD_ACYCLE_FOUR (4 << NFCADDR_CMD_ACYCLE_SHIFT) /* Four address cycles */ +# define NFCADDR_CMD_ACYCLE_FIVE (5 << NFCADDR_CMD_ACYCLE_SHIFT) /* Five address cycles */ +#define NFCADDR_CMD_CSID_SHIFT (22) /* Bits 22-24: Chip Select Identifier */ +#define NFCADDR_CMD_CSID_MASK (7 << NFCADDR_CMD_CSID_SHIFT) +# define NFCADDR_CMD_CSID(n) ((uint32_t)(n) << NFCADDR_CMD_CSID_SHIFT) /* CSn, n=0-7 */ +# define NFCADDR_CMD_CSID_0 (0 << NFCADDR_CMD_CSID_SHIFT) /* CS0 */ +# define NFCADDR_CMD_CSID_1 (1 << NFCADDR_CMD_CSID_SHIFT) /* CS1 */ +# define NFCADDR_CMD_CSID_2 (2 << NFCADDR_CMD_CSID_SHIFT) /* CS2 */ +# define NFCADDR_CMD_CSID_3 (3 << NFCADDR_CMD_CSID_SHIFT) /* CS3 */ +# define NFCADDR_CMD_CSID_4 (4 << NFCADDR_CMD_CSID_SHIFT) /* CS4 */ +# define NFCADDR_CMD_CSID_5 (5 << NFCADDR_CMD_CSID_SHIFT) /* CS5 */ +# define NFCADDR_CMD_CSID_6 (6 << NFCADDR_CMD_CSID_SHIFT) /* CS6 */ +# define NFCADDR_CMD_CSID_7 (7 << NFCADDR_CMD_CSID_SHIFT) /* CS7 */ +#define NFCADDR_CMD_DATAEN (1 << 25) /* Bit 25: 1=NFC Data Enable */ +#define NFCADDR_CMD_DATADIS (0 << 25) /* Bit 25: 0=NFC Data disable */ +#define NFCADDR_CMD_NFCRD (0 << 26) /* Bit 26: 0=NFC Read Enable */ +#define NFCADDR_CMD_NFCWR (1 << 26) /* Bit 26: 1=NFC Write Enable */ +#define NFCADDR_CMD_NFCCMD (1 << 27) /* Bit 27: 1=NFC Command Enable (status only) */ + +/* NFC Data Address */ + +#define NFCDATA_ADDT_CYCLE1_SHIFT (0) /* Bits 0-7: NAND Flash Array Address Cycle 1 */ +#define NFCDATA_ADDT_CYCLE1_MASK (0xff << NFCDATA_ADDT_CYCLE1_SHIFT) +# define NFCDATA_ADDT_CYCLE1(n) ((uint32_t)(n) << NFCDATA_ADDT_CYCLE1_SHIFT) +#define NFCDATA_ADDT_CYCLE2_SHIFT (8) /* Bits 8-15: NAND Flash Array Address Cycle 2 */ +#define NFCDATA_ADDT_CYCLE2_MASK (0xff << NFCDATA_ADDT_CYCLE2_SHIFT) +# define NFCDATA_ADDT_CYCLE2(n) ((uint32_t)(n) << NFCDATA_ADDT_CYCLE2_SHIFT) +#define NFCDATA_ADDT_CYCLE3_SHIFT (16) /* Bits 16-23: NAND Flash Array Address Cycle 3 */ +#define NFCDATA_ADDT_CYCLE3_MASK (0xff << NFCDATA_ADDT_CYCLE3_SHIFT) +# define NFCDATA_ADDT_CYCLE3(n) ((uint32_t)(n) << NFCDATA_ADDT_CYCLE3_SHIFT) +#define NFCDATA_ADDT_CYCLE4_SHIFT (24) /* Bits 24-31: NAND Flash Array Address Cycle 4 */ +#define NFCDATA_ADDT_CYCLE4_MASK (0xff << NFCDATA_ADDT_CYCLE4_SHIFT) +# define NFCDATA_ADDT_CYCLE4(n) ((uint32_t)(n) << NFCDATA_ADDT_CYCLE4_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMC_H */ diff --git a/arch/arm/src/sama5/chip/sam_hsmci.h b/arch/arm/src/sama5/chip/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..6617343684746692381deaa20d36444244c776e7 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_hsmci.h @@ -0,0 +1,376 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_hsmci.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMCI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* HSMCI register offsets ***************************************************************/ + +#define SAM_HSMCI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_HSMCI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_HSMCI_DTOR_OFFSET 0x0008 /* Data Timeout Register */ +#define SAM_HSMCI_SDCR_OFFSET 0x000c /* SD/SDIO Card Register */ +#define SAM_HSMCI_ARGR_OFFSET 0x0010 /* Argument Register */ +#define SAM_HSMCI_CMDR_OFFSET 0x0014 /* Command Register */ +#define SAM_HSMCI_BLKR_OFFSET 0x0018 /* Block Register */ +#define SAM_HSMCI_CSTOR_OFFSET 0x001c /* Completion Signal Timeout Register */ +#define SAM_HSMCI_RSPR0_OFFSET 0x0020 /* Response Register 0 */ +#define SAM_HSMCI_RSPR1_OFFSET 0x0024 /* Response Register 1 */ +#define SAM_HSMCI_RSPR2_OFFSET 0x0028 /* Response Register 2 */ +#define SAM_HSMCI_RSPR3_OFFSET 0x002c /* Response Register 3 */ +#define SAM_HSMCI_RDR_OFFSET 0x0030 /* Receive Data Register */ +#define SAM_HSMCI_TDR_OFFSET 0x0034 /* Transmit Data Register */ + /* 0x0038-0x003c: Reserved */ +#define SAM_HSMCI_SR_OFFSET 0x0040 /* Status Register */ +#define SAM_HSMCI_IER_OFFSET 0x0044 /* Interrupt Enable Register */ +#define SAM_HSMCI_IDR_OFFSET 0x0048 /* Interrupt Disable Register */ +#define SAM_HSMCI_IMR_OFFSET 0x004c /* Interrupt Mask Register */ +#define SAM_HSMCI_DMA_OFFSET 0x0050 /* DMA Configuration Register */ +#define SAM_HSMCI_CFG_OFFSET 0x0054 /* Configuration Register */ + /* 0x0058-0x00e0: Reserved */ +#define SAM_HSMCI_WPMR_OFFSET 0x00e4 /* Write Protection Mode Register */ +#define SAM_HSMCI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0x00ec-0x00fc: Reserved */ + /* 0x0100-0x0124: Reserved for PCD registers */ +#define SAM_HSMCI_FIFO_OFFSET 0x0200 /* 0x0200-0x05fc FIFO Memory Aperture */ + +/* HSMCI register addresses *************************************************************/ + +#define SAM_HSMCI0_CR (SAM_HSMCI0_VBASE+SAM_HSMCI_CR_OFFSET) +#define SAM_HSMCI0_MR (SAM_HSMCI0_VBASE+SAM_HSMCI_MR_OFFSET) +#define SAM_HSMCI0_DTOR (SAM_HSMCI0_VBASE+SAM_HSMCI_DTOR_OFFSET) +#define SAM_HSMCI0_SDCR (SAM_HSMCI0_VBASE+SAM_HSMCI_SDCR_OFFSET) +#define SAM_HSMCI0_ARGR (SAM_HSMCI0_VBASE+SAM_HSMCI_ARGR_OFFSET) +#define SAM_HSMCI0_CMDR (SAM_HSMCI0_VBASE+SAM_HSMCI_CMDR_OFFSET) +#define SAM_HSMCI0_BLKR (SAM_HSMCI0_VBASE+SAM_HSMCI_BLKR_OFFSET) +#define SAM_HSMCI0_CSTOR (SAM_HSMCI0_VBASE+SAM_HSMCI_CSTOR_OFFSET) +#define SAM_HSMCI0_RSPR0 (SAM_HSMCI0_VBASE+SAM_HSMCI_RSPR0_OFFSET) +#define SAM_HSMCI0_RSPR1 (SAM_HSMCI0_VBASE+SAM_HSMCI_RSPR1_OFFSET) +#define SAM_HSMCI0_RSPR2 (SAM_HSMCI0_VBASE+SAM_HSMCI_RSPR2_OFFSET) +#define SAM_HSMCI0_RSPR3 (SAM_HSMCI0_VBASE+SAM_HSMCI_RSPR3_OFFSET) +#define SAM_HSMCI0_RDR (SAM_HSMCI0_VBASE+SAM_HSMCI_RDR_OFFSET) +#define SAM_HSMCI0_TDR (SAM_HSMCI0_VBASE+SAM_HSMCI_TDR_OFFSET) +#define SAM_HSMCI0_SR (SAM_HSMCI0_VBASE+SAM_HSMCI_SR_OFFSET) +#define SAM_HSMCI0_IER (SAM_HSMCI0_VBASE+SAM_HSMCI_IER_OFFSET) +#define SAM_HSMCI0_IDR (SAM_HSMCI0_VBASE+SAM_HSMCI_IDR_OFFSET) +#define SAM_HSMCI0_IMR (SAM_HSMCI0_VBASE+SAM_HSMCI_IMR_OFFSET) +#define SAM_HSMCI0_DMA (SAM_HSMCI0_VBASE+SAM_HSMCI_DMA_OFFSET) +#define SAM_HSMCI0_CFG (SAM_HSMCI0_VBASE+SAM_HSMCI_CFG_OFFSET) +#define SAM_HSMCI0_WPMR (SAM_HSMCI0_VBASE+SAM_HSMCI_WPMR_OFFSET) +#define SAM_HSMCI0_WPSR (SAM_HSMCI0_VBASE+SAM_HSMCI_WPSR_OFFSET) +#define SAM_HSMCI0_FIFO (SAM_HSMCI0_VBASE+SAM_HSMCI_FIFO_OFFSET) + +#define SAM_HSMCI1_CR (SAM_HSMCI1_VBASE+SAM_HSMCI_CR_OFFSET) +#define SAM_HSMCI1_MR (SAM_HSMCI1_VBASE+SAM_HSMCI_MR_OFFSET) +#define SAM_HSMCI1_DTOR (SAM_HSMCI1_VBASE+SAM_HSMCI_DTOR_OFFSET) +#define SAM_HSMCI1_SDCR (SAM_HSMCI1_VBASE+SAM_HSMCI_SDCR_OFFSET) +#define SAM_HSMCI1_ARGR (SAM_HSMCI1_VBASE+SAM_HSMCI_ARGR_OFFSET) +#define SAM_HSMCI1_CMDR (SAM_HSMCI1_VBASE+SAM_HSMCI_CMDR_OFFSET) +#define SAM_HSMCI1_BLKR (SAM_HSMCI1_VBASE+SAM_HSMCI_BLKR_OFFSET) +#define SAM_HSMCI1_CSTOR (SAM_HSMCI1_VBASE+SAM_HSMCI_CSTOR_OFFSET) +#define SAM_HSMCI1_RSPR0 (SAM_HSMCI1_VBASE+SAM_HSMCI_RSPR0_OFFSET) +#define SAM_HSMCI1_RSPR1 (SAM_HSMCI1_VBASE+SAM_HSMCI_RSPR1_OFFSET) +#define SAM_HSMCI1_RSPR2 (SAM_HSMCI1_VBASE+SAM_HSMCI_RSPR2_OFFSET) +#define SAM_HSMCI1_RSPR3 (SAM_HSMCI1_VBASE+SAM_HSMCI_RSPR3_OFFSET) +#define SAM_HSMCI1_RDR (SAM_HSMCI1_VBASE+SAM_HSMCI_RDR_OFFSET) +#define SAM_HSMCI1_TDR (SAM_HSMCI1_VBASE+SAM_HSMCI_TDR_OFFSET) +#define SAM_HSMCI1_SR (SAM_HSMCI1_VBASE+SAM_HSMCI_SR_OFFSET) +#define SAM_HSMCI1_IER (SAM_HSMCI1_VBASE+SAM_HSMCI_IER_OFFSET) +#define SAM_HSMCI1_IDR (SAM_HSMCI1_VBASE+SAM_HSMCI_IDR_OFFSET) +#define SAM_HSMCI1_IMR (SAM_HSMCI1_VBASE+SAM_HSMCI_IMR_OFFSET) +#define SAM_HSMCI1_DMA (SAM_HSMCI1_VBASE+SAM_HSMCI_DMA_OFFSET) +#define SAM_HSMCI1_CFG (SAM_HSMCI1_VBASE+SAM_HSMCI_CFG_OFFSET) +#define SAM_HSMCI1_WPMR (SAM_HSMCI1_VBASE+SAM_HSMCI_WPMR_OFFSET) +#define SAM_HSMCI1_WPSR (SAM_HSMCI1_VBASE+SAM_HSMCI_WPSR_OFFSET) +#define SAM_HSMCI1_FIFO (SAM_HSMCI1_VBASE+SAM_HSMCI_FIFO_OFFSET) + +#ifdef CONFIG_SAMA5_HAVE_HSMCI2 +# define SAM_HSMCI2_CR (SAM_HSMCI2_VBASE+SAM_HSMCI_CR_OFFSET) +# define SAM_HSMCI2_MR (SAM_HSMCI2_VBASE+SAM_HSMCI_MR_OFFSET) +# define SAM_HSMCI2_DTOR (SAM_HSMCI2_VBASE+SAM_HSMCI_DTOR_OFFSET) +# define SAM_HSMCI2_SDCR (SAM_HSMCI2_VBASE+SAM_HSMCI_SDCR_OFFSET) +# define SAM_HSMCI2_ARGR (SAM_HSMCI2_VBASE+SAM_HSMCI_ARGR_OFFSET) +# define SAM_HSMCI2_CMDR (SAM_HSMCI2_VBASE+SAM_HSMCI_CMDR_OFFSET) +# define SAM_HSMCI2_BLKR (SAM_HSMCI2_VBASE+SAM_HSMCI_BLKR_OFFSET) +# define SAM_HSMCI2_CSTOR (SAM_HSMCI2_VBASE+SAM_HSMCI_CSTOR_OFFSET) +# define SAM_HSMCI2_RSPR0 (SAM_HSMCI2_VBASE+SAM_HSMCI_RSPR0_OFFSET) +# define SAM_HSMCI2_RSPR1 (SAM_HSMCI2_VBASE+SAM_HSMCI_RSPR1_OFFSET) +# define SAM_HSMCI2_RSPR2 (SAM_HSMCI2_VBASE+SAM_HSMCI_RSPR2_OFFSET) +# define SAM_HSMCI2_RSPR3 (SAM_HSMCI2_VBASE+SAM_HSMCI_RSPR3_OFFSET) +# define SAM_HSMCI2_RDR (SAM_HSMCI2_VBASE+SAM_HSMCI_RDR_OFFSET) +# define SAM_HSMCI2_TDR (SAM_HSMCI2_VBASE+SAM_HSMCI_TDR_OFFSET) +# define SAM_HSMCI2_SR (SAM_HSMCI2_VBASE+SAM_HSMCI_SR_OFFSET) +# define SAM_HSMCI2_IER (SAM_HSMCI2_VBASE+SAM_HSMCI_IER_OFFSET) +# define SAM_HSMCI2_IDR (SAM_HSMCI2_VBASE+SAM_HSMCI_IDR_OFFSET) +# define SAM_HSMCI2_IMR (SAM_HSMCI2_VBASE+SAM_HSMCI_IMR_OFFSET) +# define SAM_HSMCI2_DMA (SAM_HSMCI2_VBASE+SAM_HSMCI_DMA_OFFSET) +# define SAM_HSMCI2_CFG (SAM_HSMCI2_VBASE+SAM_HSMCI_CFG_OFFSET) +# define SAM_HSMCI2_WPMR (SAM_HSMCI2_VBASE+SAM_HSMCI_WPMR_OFFSET) +# define SAM_HSMCI2_WPSR (SAM_HSMCI2_VBASE+SAM_HSMCI_WPSR_OFFSET) +# define SAM_HSMCI2_FIFO (SAM_HSMCI2_VBASE+SAM_HSMCI_FIFO_OFFSET) +#endif + +/* HSMCI register bit definitions *******************************************************/ + +/* HSMCI Control Register */ + +#define HSMCI_CR_MCIEN (1 << 0) /* Bit 0: Multi-Media Interface Enable */ +#define HSMCI_CR_MCIDIS (1 << 1) /* Bit 1: Multi-Media Interface Disable */ +#define HSMCI_CR_PWSEN (1 << 2) /* Bit 2: Power Save Mode Enable */ +#define HSMCI_CR_PWSDIS (1 << 3) /* Bit 3: Power Save Mode Disable */ +#define HSMCI_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ + +/* HSMCI Mode Register */ + +#define HSMCI_MR_CLKDIV_SHIFT (0) /* Bits 0-7: Clock Divider */ +#define HSMCI_MR_CLKDIV_MASK (0xff << HSMCI_MR_CLKDIV_SHIFT) +#define HSMCI_MR_PWSDIV_SHIFT (8) /* Bits 8-10: Power Saving Divider */ +#define HSMCI_MR_PWSDIV_MASK (7 << HSMCI_MR_PWSDIV_SHIFT) +# define HSMCI_MR_PWSDIV_MAX (7 << HSMCI_MR_PWSDIV_SHIFT) +#define HSMCI_MR_RDPROOF (1 << 11) /* Bit 11: Read Proof Enable */ +#define HSMCI_MR_WRPROOF (1 << 12) /* Bit 12: Write Proof Enable */ +#define HSMCI_MR_FBYTE (1 << 13) /* Bit 13: Force Byte Transfer */ +#define HSMCI_MR_PADV (1 << 14) /* Bit 14: Padding Value */ +#define HSMCI_MR_CLKODD (1 << 16) /* Bit 15: Clock divider is odd */ + +/* HSMCI Data Timeout Register */ + +#define HSMCI_DTOR_DTOCYC_SHIFT (0) /* Bits 0-3: Data Timeout Cycle Number */ +#define HSMCI_DTOR_DTOCYC_MASK (15 << HSMCI_DTOR_DTOCYC_SHIFT) +# define HSMCI_DTOR_DTOCYC_MAX (15 << HSMCI_DTOR_DTOCYC_SHIFT) +#define HSMCI_DTOR_DTOMUL_SHIFT (4) /* Bits 4-6: Data Timeout Multiplier */ +#define HSMCI_DTOR_DTOMUL_MASK (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1 (0 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_16 (1 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_128 (2 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_256 (3 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1024 (4 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_4096 (5 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_65536 (6 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1048576 (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_MAX (7 << HSMCI_DTOR_DTOMUL_SHIFT) + +/* HSMCI SDCard/SDIO Register */ + +#define HSMCI_SDCR_SDCSEL_SHIFT (0) /* Bits 0-1: SDCard/SDIO Slot */ +#define HSMCI_SDCR_SDCSEL_MASK (3 << HSMCI_SDCR_SDCSEL_SHIFT) /* Slot A is selected */ +# define HSMCI_SDCR_SDCSEL_SLOTA (0 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTB (1 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTC (2 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTD (3 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +#define HSMCI_SDCR_SDCBUS_SHIFT (6) /* Bits 6-7: SDCard/SDIO Bus Width */ +#define HSMCI_SDCR_SDCBUS_MASK (3 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_1BIT (0 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_4BIT (2 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_8BIT (3 << HSMCI_SDCR_SDCBUS_SHIFT) + +/* HSMCI Argument Register (32-bit value) */ + +/* HSMCI Command Register */ + +#define HSMCI_CMDR_CMDNB_SHIFT (0) /* Bits 0-5: Command Number */ +#define HSMCI_CMDR_CMDNB_MASK (63 << HSMCI_CMDR_CMDNB_SHIFT) +#define HSMCI_CMDR_RSPTYP_SHIFT (6) /* Bits 6-7: Response Type */ +#define HSMCI_CMDR_RSPTYP_MASK (3 << HSMCI_CMDR_RSPTYP_SHIFT) +# define HSMCI_CMDR_RSPTYP_NONE (0 << HSMCI_CMDR_RSPTYP_SHIFT) /* No response */ +# define HSMCI_CMDR_RSPTYP_48BIT (1 << HSMCI_CMDR_RSPTYP_SHIFT) /* 48-bit response */ +# define HSMCI_CMDR_RSPTYP_136BIT (2 << HSMCI_CMDR_RSPTYP_SHIFT) /* 136-bit response */ +# define HSMCI_CMDR_RSPTYP_R1B (3 << HSMCI_CMDR_RSPTYP_SHIFT) /* R1b response type */ +#define HSMCI_CMDR_SPCMD_SHIFT (8) /* Bits 8-10: Special Command */ +#define HSMCI_CMDR_SPCMD_MASK (7 << HSMCI_CMDR_SPCMD_SHIFT) +# define HSMCI_CMDR_SPCMD_STD (0 << HSMCI_CMDR_SPCMD_SHIFT) /* Not a special CMD */ +# define HSMCI_CMDR_SPCMD_INIT (1 << HSMCI_CMDR_SPCMD_SHIFT) /* Initialization CMD */ +# define HSMCI_CMDR_SPCMD_SYNC (2 << HSMCI_CMDR_SPCMD_SHIFT) /* Synchronized CMD */ +# define HSMCI_CMDR_SPCMD_CEATAC (3 << HSMCI_CMDR_SPCMD_SHIFT) /* CE-ATA Completion Signal disable CMD */ +# define HSMCI_CMDR_SPCMD_ITCMD (4 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt command */ +# define HSMCI_CMDR_SPCMD_ITRESP (5 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt response */ +# define HSMCI_CMDR_SPCMD_BOR (6 << HSMCI_CMDR_SPCMD_SHIFT) /* Boot Operation Request */ +# define HSMCI_CMDR_SPCMD_EBO (7 << HSMCI_CMDR_SPCMD_SHIFT) /* End Boot Operation */ +#define HSMCI_CMDR_OPDCMD (1 << 11) /* Bit 11: Open Drain Command */ +#define HSMCI_CMDR_MAXLAT (1 << 12) /* Bit 12: Max Latency for Command to Response */ +#define HSMCI_CMDR_TRCMD_SHIFT (16) /* Bits 16-17: Transfer Command */ +#define HSMCI_CMDR_TRCMD_MASK (3 << HSMCI_CMDR_TRCMD_SHIFT) +# define HSMCI_CMDR_TRCMD_NONE (0 << HSMCI_CMDR_TRCMD_SHIFT) /* No data transfer */ +# define HSMCI_CMDR_TRCMD_START (1 << HSMCI_CMDR_TRCMD_SHIFT) /* Start data transfer */ +# define HSMCI_CMDR_TRCMD_STOP (2 << HSMCI_CMDR_TRCMD_SHIFT) /* Stop data transfer */ +#define HSMCI_CMDR_TRDIR (1 << 18) /* Bit 18: Transfer Direction */ +# define HSMCI_CMDR_TRDIR_WRITE (0 << 18) +# define HSMCI_CMDR_TRDIR_READ (1 << 18) +#define HSMCI_CMDR_TRTYP_SHIFT (19) /* Bits 19-21: Transfer Type */ +#define HSMCI_CMDR_TRTYP_MASK (7 << HSMCI_CMDR_TRTYP_SHIFT) +# define HSMCI_CMDR_TRTYP_SINGLE (0 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Single Block */ +# define HSMCI_CMDR_TRTYP_MULTIPLE (1 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Multiple Block */ +# define HSMCI_CMDR_TRTYP_STREAM (2 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC Stream */ +# define HSMCI_CMDR_TRTYP_SDIOBYTE (4 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Byte */ +# define HSMCI_CMDR_TRTYP_SDIOBLK (5 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Block */ +#define HSMCI_CMDR_IOSPCMD_SHIFT (24) /* Bits 24-25: SDIO Special Command */ +#define HSMCI_CMDR_IOSPCMD_MASK (3 << HSMCI_CMDR_IOSPCMD_SHIFT) +# define HSMCI_CMDR_IOSPCMD_STD (0 << HSMCI_CMDR_IOSPCMD_SHIFT) /* Not an SDIO Special Command */ +# define HSMCI_CMDR_IOSPCMD_SUSPEND (1 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Suspend Command */ +# define HSMCI_CMDR_IOSPCMD_RESUME (2 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Resume Command */ +#define HSMCI_CMDR_ATACS (1 << 26) /* Bit 26: ATA with Command Completion Signal */ +#define HSMCI_CMDR_BOOTACK (1 << 27) /* Bit 27: Boot Operation Acknowledge */ + +/* HSMCI Block Register */ + +#define HSMCI_BLKR_BCNT_SHIFT (0) /* Bits 0-15: MMC/SDIO Block Count - SDIO Byte Count */ +#define HSMCI_BLKR_BCNT_MASK (0xffff << HSMCI_BLKR_BCNT_SHIFT) +# define HSMCI_BLKR_BCNT(n) ((uint32_t)(n) << HSMCI_BLKR_BCNT_SHIFT) +#define HSMCI_BLKR_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */ +#define HSMCI_BLKR_BLKLEN_MASK (0xffff << HSMCI_BLKR_BLKLEN_SHIFT) +# define HSMCI_BLKR_BLKLEN(n) ((uint32_t)(n) << HSMCI_BLKR_BLKLEN_SHIFT) + +/* HSMCI Completion Signal Timeout Register */ + +#define HSMCI_CSTOR_CSTOCYC_SHIFT (0) /* Bits 0-3: Completion Signal Timeout Cycle Number */ +#define HSMCI_CSTOR_CSTOCYC_MASK (15 << HSMCI_CSTOR_CSTOCYC_SHIFT) +# define HSMCI_CSTOR_CSTOCYC(n) ((uint32_t)(n) << HSMCI_CSTOR_CSTOCYC_SHIFT) +#define HSMCI_CSTOR_CSTOMUL_SHIFT (4) /* Bits 4-6: Completion Signal Timeout Multiplier */ +#define HSMCI_CSTOR_CSTOMUL_MASK (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1 (0 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_16 (1 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_128 (2 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_256 (3 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1024 (4 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_4096 (5 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_65536 (6 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1048576 (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) + +/* HSMCI Response Registers (32-bit data) */ +/* HSMCI Receive Data Registers (32-bit data) */ +/* HSMCI Transmit Data Registers (32-bit data) */ + +/* HSMCI Status Register, HSMCI Interrupt Enable Register, HSMCI Interrupt Disable + * Register, and HSMCI Interrupt Mask Register common bit-field definitions + */ + +#define HSMCI_INT_CMDRDY (1 << 0) /* Bit 0: Command Ready */ +#define HSMCI_INT_RXRDY (1 << 1) /* Bit 1: Receiver Ready */ +#define HSMCI_INT_TXRDY (1 << 2) /* Bit 2: Transmit Ready */ +#define HSMCI_INT_BLKE (1 << 3) /* Bit 3: Data Block Ended */ +#define HSMCI_INT_DTIP (1 << 4) /* Bit 4: Data Transfer in Progress */ +#define HSMCI_INT_NOTBUSY (1 << 5) /* Bit 6: HSMCI Not Busy */ +#define HSMCI_INT_SDIOIRQA (1 << 8) /* Bit 8: SDIO Interrupt for Slot A */ + +#ifdef ATSAMA5D4 +# define HSMCI_INT_SDIOIRQB (1 << 9) /* Bit 9: SDIO Interrupt for Slot B */ +#endif + +#define HSMCI_INT_SDIOWAIT (1 << 12) /* Bit 12: SDIO Read Wait Operation Status */ +#define HSMCI_INT_CSRCV (1 << 13) /* Bit 13: CE-ATA Completion Signal Received */ +#define HSMCI_INT_RINDE (1 << 16) /* Bit 16: Response Index Error */ +#define HSMCI_INT_RDIRE (1 << 17) /* Bit 17: Response Direction Error */ +#define HSMCI_INT_RCRCE (1 << 18) /* Bit 18: Response CRC Error */ +#define HSMCI_INT_RENDE (1 << 19) /* Bit 19: Response End Bit Error */ +#define HSMCI_INT_RTOE (1 << 20) /* Bit 20: Response Time-out */ +#define HSMCI_INT_DCRCE (1 << 21) /* Bit 21: Data CRC Error */ +#define HSMCI_INT_DTOE (1 << 22) /* Bit 22: Data Time-out Error */ +#define HSMCI_INT_CSTOE (1 << 23) /* Bit 23: Completion Signal Time-out Error */ +#define HSMCI_INT_BLKOVRE (1 << 24) /* Bit 24: DMA Block Overrun Error */ +#define HSMCI_INT_DMADONE (1 << 25) /* Bit 25: DMA Transfer done */ +#define HSMCI_INT_FIFOEMPTY (1 << 26) /* Bit 26: FIFO empty flag */ +#define HSMCI_INT_XFRDONE (1 << 27) /* Bit 27: Transfer Done flag */ +#define HSMCI_INT_ACKRCV (1 << 28) /* Bit 28: Boot Operation Acknowledge Received */ +#define HSMCI_INT_ACKRCVE (1 << 29) /* Bit 29: Boot Operation Acknowledge Error */ +#define HSMCI_INT_OVRE (1 << 30) /* Bit 30: Overrun */ +#define HSMCI_INT_UNRE (1 << 31) /* Bit 31: Underrun */ + +/* HSMCI DMA Configuration Register */ + +#ifdef ATSAMA5D3 +# define HSMCI_DMA_OFFSET_SHIFT (0) /* Bits 0-1: DMA Write Buffer Offset */ +# define HSMCI_DMA_OFFSET_MASK (3 << HSMCI_DMA_OFFSET_SHIFT) +# define HSMCI_DMA_OFFSET(n) ((uint32_t)(n) << HSMCI_DMA_OFFSET_SHIFT) +#endif + +#define HSMCI_DMA_CHKSIZE_SHIFT (4) /* Bits 4-6: DMA Channel Read and Write Chunk Size */ +#define HSMCI_DMA_CHKSIZE_MASK (7 << HSMCI_DMA_CHKSIZE_SHIFT) +# define HSMCI_DMA_CHKSIZE_1 (0 << HSMCI_DMA_CHKSIZE_SHIFT) /* 1 data available */ +# define HSMCI_DMA_CHKSIZE_4 (1 << HSMCI_DMA_CHKSIZE_SHIFT) /* 4 data available */ +# define HSMCI_DMA_CHKSIZE_8 (2 << HSMCI_DMA_CHKSIZE_SHIFT) /* 8 data available */ +# define HSMCI_DMA_CHKSIZE_16 (3 << HSMCI_DMA_CHKSIZE_SHIFT) /* 16 data available */ +# define HSMCI_DMA_CHKSIZE_32 (4 << HSMCI_DMA_CHKSIZE_SHIFT) /* 32 data available */ +#define HSMCI_DMA_DMAEN (1 << 8) /* Bit 8: DMA Hardware Handshaking Enable */ + +#ifdef ATSAMA5D3 +# define HSMCI_DMA_ROPT (1 << 12) /* Bit 12: Read Optimization with padding */ +#endif + +/* HSMCI Configuration Register */ + +#define HSMCI_CFG_FIFOMODE (1 << 0) /* Bit 0: HSMCI Internal FIFO control mode */ +#define HSMCI_CFG_FERRCTRL (1 << 4) /* Bit 4: Flow Error flag reset control mode */ +#define HSMCI_CFG_HSMODE (1 << 8) /* Bit 8: High Speed Mode */ +#define HSMCI_CFG_LSYNC (1 << 12) /* Bit 12: Synchronize on the last block */ + +/* HSMCI Write Protect Mode Register */ + +#define HSMCI_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define HSMCI_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection Key password */ +#define HSMCI_WPMR_WPKEY_MASK (0x00ffffff << HSMCI_WPMR_WPKEY_SHIFT) +# define HSMCI_WPMR_WPKEY (0x004d4349 << HSMCI_WPMR_WPKEY_SHIFT) + +/* HSMCI Write Protect Status Register */ + +#define HSMCI_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define HSMCI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define HSMCI_WPSR_WPVSRC_MASK (0xffff << HSMCI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_HSMCI_H */ diff --git a/arch/arm/src/sama5/chip/sam_isi.h b/arch/arm/src/sama5/chip/sam_isi.h new file mode 100644 index 0000000000000000000000000000000000000000..5c7605a2addfa2aedfa7b5ba95e9c1158f431db0 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_isi.h @@ -0,0 +1,344 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_isi.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ISI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ISI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* ISI Register Offsets *************************************************************/ + +#define SAM_ISI_CFG1_OFFSET 0x0000 /* ISI Configuration 1 Register */ +#define SAM_ISI_CFG2_OFFSET 0x0004 /* ISI Configuration 2 Register */ +#define SAM_ISI_PSIZE_OFFSET 0x0008 /* ISI Preview Size Register */ +#define SAM_ISI_PDECF_OFFSET 0x000c /* ISI Preview Decimation Factor Register */ +#define SAM_ISI_Y2R_SET0_OFFSET 0x0010 /* ISI CSC YCrCb To RGB Set 0 Register */ +#define SAM_ISI_Y2R_SET1_OFFSET 0x0014 /* ISI CSC YCrCb To RGB Set 1 Register */ +#define SAM_ISI_R2Y_SET0_OFFSET 0x0018 /* ISI CSC RGB To YCrCb Set 0 Register */ +#define SAM_ISI_R2Y_SET1_OFFSET 0x001c /* ISI CSC RGB To YCrCb Set 1 Register */ +#define SAM_ISI_R2Y_SET2_OFFSET 0x0020 /* ISI CSC RGB To YCrCb Set 2 Register */ +#define SAM_ISI_CR_OFFSET 0x0024 /* ISI Control Register */ +#define SAM_ISI_SR_OFFSET 0x0028 /* ISI Status Register */ +#define SAM_ISI_IER_OFFSET 0x002c /* ISI Interrupt Enable Register */ +#define SAM_ISI_IDR_OFFSET 0x0030 /* ISI Interrupt Disable Register */ +#define SAM_ISI_IMR_OFFSET 0x0034 /* ISI Interrupt Mask Register */ +#define SAM_ISI_DMA_CHER_OFFSET 0x0038 /* DMA Channel Enable Register */ +#define SAM_ISI_DMA_CHDR_OFFSET 0x003c /* DMA Channel Disable Register */ +#define SAM_ISI_DMA_CHSR_OFFSET 0x0040 /* DMA Channel Status Register */ +#define SAM_ISI_DMA_PADDR_OFFSET 0x0044 /* DMA Preview Base Address Register */ +#define SAM_ISI_DMA_PCTRL_OFFSET 0x0048 /* DMA Preview Control Register */ +#define SAM_ISI_DMA_PDSCR_OFFSET 0x004c /* DMA Preview Descriptor Address Register */ +#define SAM_ISI_DMA_CADDR_OFFSET 0x0050 /* DMA Codec Base Address Register */ +#define SAM_ISI_DMA_CCTRL_OFFSET 0x0054 /* DMA Codec Control Register */ +#define SAM_ISI_DMA_CDSCR_OFFSET 0x0058 /* DMA Codec Descriptor Address Register */ + /* 0x005c-0x00e0 Reserved */ +#define SAM_ISI_WPMR_OFFSET 0x00e4 /* Write Protection Mode Register */ +#define SAM_ISI_WPSR_OFFSET 000xe8 /* Write Protection Status Register */ + /* 0x00ec-0x00fc Reserved */ + +/* ISI Register Addresses ***********************************************************/ + +#define SAM_ISI_CFG1 (SAM_ISI_VBASE+SAM_ISI_CFG1_OFFSET) +#define SAM_ISI_CFG2 (SAM_ISI_VBASE+SAM_ISI_CFG2_OFFSET) +#define SAM_ISI_PSIZE (SAM_ISI_VBASE+SAM_ISI_PSIZE_OFFSET) +#define SAM_ISI_PDECF (SAM_ISI_VBASE+SAM_ISI_PDECF_OFFSET) +#define SAM_ISI_Y2R_SET0 (SAM_ISI_VBASE+SAM_ISI_Y2R_SET0_OFFSET) +#define SAM_ISI_Y2R_SET1 (SAM_ISI_VBASE+SAM_ISI_Y2R_SET1_OFFSET) +#define SAM_ISI_R2Y_SET0 (SAM_ISI_VBASE+SAM_ISI_R2Y_SET0_OFFSET) +#define SAM_ISI_R2Y_SET1 (SAM_ISI_VBASE+SAM_ISI_R2Y_SET1_OFFSET) +#define SAM_ISI_R2Y_SET2 (SAM_ISI_VBASE+SAM_ISI_R2Y_SET2_OFFSET) +#define SAM_ISI_CR (SAM_ISI_VBASE+SAM_ISI_CR_OFFSET) +#define SAM_ISI_SR (SAM_ISI_VBASE+SAM_ISI_SR_OFFSET) +#define SAM_ISI_IER (SAM_ISI_VBASE+SAM_ISI_IER_OFFSET) +#define SAM_ISI_IDR (SAM_ISI_VBASE+SAM_ISI_IDR_OFFSET) +#define SAM_ISI_IMR (SAM_ISI_VBASE+SAM_ISI_IMR_OFFSET) +#define SAM_ISI_DMA_CHER (SAM_ISI_VBASE+SAM_ISI_DMA_CHER_OFFSET) +#define SAM_ISI_DMA_CHDR (SAM_ISI_VBASE+SAM_ISI_DMA_CHDR_OFFSET) +#define SAM_ISI_DMA_CHSR (SAM_ISI_VBASE+SAM_ISI_DMA_CHSR_OFFSET) +#define SAM_ISI_DMA_PADDR (SAM_ISI_VBASE+SAM_ISI_DMA_PADDR_OFFSET) +#define SAM_ISI_DMA_PCTRL (SAM_ISI_VBASE+SAM_ISI_DMA_PCTRL_OFFSET) +#define SAM_ISI_DMA_PDSCR (SAM_ISI_VBASE+SAM_ISI_DMA_PDSCR_OFFSET) +#define SAM_ISI_DMA_CADDR (SAM_ISI_VBASE+SAM_ISI_DMA_CADDR_OFFSET) +#define SAM_ISI_DMA_CCTRL (SAM_ISI_VBASE+SAM_ISI_DMA_CCTRL_OFFSET) +#define SAM_ISI_DMA_CDSCR (SAM_ISI_VBASE+SAM_ISI_DMA_CDSCR_OFFSET) +#define SAM_ISI_WPMR (SAM_ISI_VBASE+SAM_ISI_WPMR_OFFSET) +#define SAM_ISI_WPSR (SAM_ISI_VBASE+SAM_ISI_WPSR_OFFSET) + +/* ISI Register Bit Definitions *****************************************************/ + +/* ISI Configuration 1 Register */ + +#define ISI_CFG1_HSYNC_POL (1 << 2) /* Bit 2: Horizontal Synchronization Polarity */ +#define ISI_CFG1_VSYNC_POL (1 << 3) /* Bit 3: Vertical Synchronization Polarity */ +#define ISI_CFG1_PIXCLK_POL (1 << 4) /* Bit 4: Pixel Clock Polarity */ +#define ISI_CFG1_EMB_SYNC (1 << 6) /* Bit 6: Embedded Synchronization */ +#define ISI_CFG1_CRC_SYNC (1 << 7) /* Bit 7: Embedded Synchronization Correction */ +#define ISI_CFG1_FRATE_SHIFT (8) /* Bits 8-10: Frame Rate [0..7] */ +#define ISI_CFG1_FRATE_MASK (7 << ISI_CFG1_FRATE_SHIFT) +# define ISI_CFG1_FRATE(n) ((uint32_t)(n) << ISI_CFG1_FRATE_SHIFT) +#define ISI_CFG1_DISCR (1 << 11) /* Bit 11: Disable Codec Request */ +#define ISI_CFG1_FULL (1 << 12) /* Bit 12: Full Mode is Allowed */ +#define ISI_CFG1_THMASK_SHIFT (13) /* Bits 13-14: Threshold Mask */ +#define ISI_CFG1_THMASK_MASK (3 << ISI_CFG1_THMASK_SHIFT) +# define ISI_CFG1_THMASK_BEATS4 (0 << ISI_CFG1_THMASK_SHIFT) /* Only 4 beats AHB burst allowed */ +# define ISI_CFG1_THMASK_BEATS8 (1 << ISI_CFG1_THMASK_SHIFT) /* Only 4 and 8 beats AHB burst allowed */ +# define ISI_CFG1_THMASK_BEATS16 (2 << ISI_CFG1_THMASK_SHIFT) /* 4, 8 and 16 beats AHB burst allowed */ +#define ISI_CFG1_SLD_SHIFT (16) /* Bits 16-23: Start of Line Delay */ +#define ISI_CFG1_SLD_MASK (0xff << ISI_CFG1_SLD_SHIFT) +# define ISI_CFG1_SLD(n) ((uint32_t)(n) << ISI_CFG1_SLD_SHIFT) +#define ISI_CFG1_SFD_SHIFT (24) /* Bits 24-31: Start of Frame Delay */ +#define ISI_CFG1_SFD_MASK (0xff << ISI_CFG1_SLD_SHIFT) +# define ISI_CFG1_SFD(n) ((uint32_t)(n) << ISI_CFG1_SLD_SHIFT) + +/* ISI Configuration 2 Register */ + +#define ISI_CFG2_IMVSIZE_SHIFT (0) /* Bits 0-10: Vertical Size of the Image Sensor [0..2047] */ +#define ISI_CFG2_IMVSIZE_MASK (0x7ff << ISI_CFG2_IMVSIZE_SHIFT) +# define ISI_CFG2_IMVSIZE(n) ((uint32_t)(n) << ISI_CFG2_IMVSIZE_SHIFT) +#define ISI_CFG2_GS_MODE (1 << 11) /* Bit 11: 1 (vs 2) pixels per word */ +# define ISI_CFG2_GS_16BPP (0) /* Bit 11: 0=2 pixels per word */ +# define ISI_CFG2_GS_32BPP (1 << 11) /* Bit 11: 1=1 pixels per word */ +#define ISI_CFG2_RGB_MODE (1 << 12) /* Bit 12: RGB Input Mode */ +# define ISI_CFG2_RGB888 (0) /* Bit 12: 0=RGB 8:8:8 24 bits */ +# define ISI_CFG2_RGB565 (1 << 12) /* Bit 12: 1=RGB 5:6:5 16 bits */ +#define ISI_CFG2_GRAYSCALE (1 << 13) /* Bit 13: Enable grayscale encoding */ +#define ISI_CFG2_RGBSWAP (1 << 14) /* Bit 14: RGB Swap */ +#define ISI_CFG2_COLSPACE (1 << 15) /* Bit 15: Color Space for the Image Data */ +#define ISI_CFG2_IMHSIZE_SHIFT (16) /* Bits 16-26: Horizontal Size of the Image Sensor */ +#define ISI_CFG2_IMHSIZE_MASK (0x7ff << ISI_CFG2_IMHSIZE_SHIFT) +# define ISI_CFG2_IMHSIZE(n) ((uint32_t)(n) << ISI_CFG2_IMHSIZE_SHIFT) +#define ISI_CFG2_YCCSWAP_SHIFT (28) /* Bits 28-29: Defines the YCC Image Data */ +#define ISI_CFG2_YCCSWAP_MASK (3 << ISI_CFG2_YCCSWAP_SHIFT) +# define ISI_CFG2_YCCSWAP_DEFAULT (0 << ISI_CFG2_YCCSWAP_SHIFT) /* Cb(i) Y(i) Cr(i) Y(i+1) */ +# define ISI_CFG2_YCCSWAP_MODE1 (1 << ISI_CFG2_YCCSWAP_SHIFT) /* Cr(i) Y(i) Cb(i) Y(i+1) */ +# define ISI_CFG2_YCCSWAP_MODE2 (2 << ISI_CFG2_YCCSWAP_SHIFT) /* Y(i) Cb(i) Y(i+1) Cr(i) */ +# define ISI_CFG2_YCCSWAP_MODE3 (3 << ISI_CFG2_YCCSWAP_SHIFT) /* Y(i) Cr(i) Y(i+1) Cb(i) */ +#define ISI_CFG2_RGBCFG_SHIFT (30) /* Bits 30-31: Defines RGB Pattern when RGB_MODE is set to 1 */ +#define ISI_CFG2_RGBCFG_MASK (3 << ISI_CFG2_RGBCFG_SHIFT) +# define ISI_CFG2_RGBCFG_DEFAULT (0 << ISI_CFG2_RGBCFG_SHIFT) /* R/G(MSB) G(LSB)/B R/G(MSB) G(LSB)/B */ +# define ISI_CFG2_RGBCFG_MODE1 (1 << ISI_CFG2_RGBCFG_SHIFT) /* B/G(MSB) G(LSB)/R B/G(MSB) G(LSB)/R */ +# define ISI_CFG2_RGBCFG_MODE2 (2 << ISI_CFG2_RGBCFG_SHIFT) /* G(LSB)/R B/G(MSB) G(LSB)/R B/G(MSB) */ +# define ISI_CFG2_RGBCFG_MODE3 (3 << ISI_CFG2_RGBCFG_SHIFT) /* G(LSB)/B R/G(MSB) G(LSB)/B R/G(MSB) */ + +/* ISI Preview Size Register */ + +#define ISI_PSIZE_PVSIZE_SHIFT (0) /* Bits 0-9: Vertical Size for the Preview Path */ +#define ISI_PSIZE_PVSIZE_MASK (0x3ff << ISI_PSIZE_PVSIZE_SHIFT) +# define ISI_PSIZE_PVSIZE(n) ((uint32_t)(n) << ISI_PSIZE_PVSIZE_SHIFT) +#define ISI_PSIZE_PHSIZE_SHIFT (16) /* Bits 16-25: Horizontal Size for the Preview Path */ +#define ISI_PSIZE_PHSIZE_MASK (0x3ff << ISI_PSIZE_PHSIZE_SHIFT) +# define ISI_PSIZE_PHSIZE(n) ((uint32_t)(n) << ISI_PSIZE_PHSIZE_SHIFT) + +/* ISI Preview Decimation Factor Register */ + +#define ISI_PDECF_MASK (0xff) /* Bits 0-7: Decimation Factor */ + +/* ISI CSC YCrCb To RGB Set 0 Register */ + +#define ISI_Y2R_SET0_C0_SHIFT (0) /* Bits 0-7: Color Space Conversion Matrix Coefficient C0 */ +#define ISI_Y2R_SET0_C0_MASK (0xff << ISI_Y2R_SET0_C0_SHIFT) +# define ISI_Y2R_SET0_C0(n) ((uint32_t)(n) << ISI_Y2R_SET0_C0_SHIFT) +#define ISI_Y2R_SET0_C1_SHIFT (8) /* Bits 8-15: Color Space Conversion Matrix Coefficient C1 */ +#define ISI_Y2R_SET0_C1_MASK (0xff << ISI_Y2R_SET0_C1_SHIFT) +# define ISI_Y2R_SET0_C1(n) ((uint32_t)(n) << ISI_Y2R_SET0_C1_SHIFT) +#define ISI_Y2R_SET0_C2_SHIFT (16) /* Bits 16-23: Color Space Conversion Matrix Coefficient C2 */ +#define ISI_Y2R_SET0_C2_MASK (0xff << ISI_Y2R_SET0_C2_SHIFT) +# define ISI_Y2R_SET0_C2(n) ((uint32_t)(n) << ISI_Y2R_SET0_C2_SHIFT) +#define ISI_Y2R_SET0_C3_SHIFT (24) /* Bits 24-31: Color Space Conversion Matrix Coefficient C3 */ +#define ISI_Y2R_SET0_C3_MASK (0xff << ISI_Y2R_SET0_C3_SHIFT) +# define ISI_Y2R_SET0_C3(n) ((uint32_t)(n) << ISI_Y2R_SET0_C3_SHIFT) + +/* ISI CSC YCrCb To RGB Set 1 Register */ + +#define ISI_Y2R_SET1_C4_SHIFT (0) /* Bits 0-8: Color Space Conversion Matrix Coefficient C4 */ +#define ISI_Y2R_SET1_C4_MASK (0x1ff << ISI_Y2R_SET1_C4_SHIFT) +# define ISI_Y2R_SET1_C4(n) ((uint32_t)(n) << ISI_Y2R_SET1_C4_SHIFT) +#define ISI_Y2R_SET1_YOFF (1 << 12) /* Bit 12: Color Space Conversion Luminance Default Offset */ +#define ISI_Y2R_SET1_CROFF (1 << 13) /* Bit 13: Color Space Conversion Red Chrominance Default Offset */ +#define ISI_Y2R_SET1_CBOFF (1 << 14) /* Bit 14: Color Space Conversion Blue Chrominance Default Offset */ + +/* ISI CSC RGB To YCrCb Set 0 Register */ + +#define ISI_R2Y_SET0_C0_SHIFT (0) /* Bits 0-6: Color Space Conversion Matrix Coefficient C0 */ +#define ISI_R2Y_SET0_C0_MASK (0x7f << ISI_R2Y_SET0_C0_SHIFT) +# define ISI_R2Y_SET0_C0(n) ((uint32_t)(n) << ISI_R2Y_SET0_C0_SHIFT) +#define ISI_R2Y_SET0_C1_SHIFT (8) /* Bits 8-14: Color Space Conversion Matrix Coefficient C1 */ +#define ISI_R2Y_SET0_C1_MASK (0x7f << ISI_R2Y_SET0_C1_SHIFT) +# define ISI_R2Y_SET0_C1(n) ((uint32_t)(n) << ISI_R2Y_SET0_C1_SHIFT) +#define ISI_R2Y_SET0_C2_SHIFT (16) /* Bits 16-22: Color Space Conversion Matrix Coefficient C2 */ +#define ISI_R2Y_SET0_C2_MASK (0x7f << ISI_R2Y_SET0_C2_SHIFT) +# define ISI_R2Y_SET0_C2(n) ((uint32_t)(n) << ISI_R2Y_SET0_C2_SHIFT) +#define ISI_R2Y_SET0_ROFF (1 << 24) /* Bit 24: Color Space Conversion Red Component Offset */ + +/* ISI CSC RGB To YCrCb Set 1 Register */ + +#define ISI_R2Y_SET1_C3_SHIFT (0) /* Bits 0-6: Color Space Conversion Matrix Coefficient C3 */ +#define ISI_R2Y_SET1_C3_MASK (0x7f << ISI_R2Y_SET1_C3_SHIFT) +# define ISI_R2Y_SET1_C3(n) ((uint32_t)(n) << ISI_R2Y_SET1_C3_SHIFT) +#define ISI_R2Y_SET1_C4_SHIFT (8) /* Bits 8-14: Color Space Conversion Matrix Coefficient C4 */ +#define ISI_R2Y_SET1_C4_MASK (0x7f << ISI_R2Y_SET1_C4_SHIFT) +# define ISI_R2Y_SET1_C4(n) ((uint32_t)(n) << ISI_R2Y_SET1_C4_SHIFT) +#define ISI_R2Y_SET1_C5_SHIFT (16) /* Bits 16-22: Color Space Conversion Matrix Coefficient C5 */ +#define ISI_R2Y_SET1_C5_MASK (0x7f << ISI_R2Y_SET1_C5_SHIFT) +# define ISI_R2Y_SET1_C5(n) ((uint32_t)(n) << ISI_R2Y_SET1_C5_SHIFT) +#define ISI_R2Y_SET1_GOFF (1 << 24) /* Bit 24: Color Space Conversion Green Component Offset */ + +/* ISI CSC RGB To YCrCb Set 2 Register */ + +#define ISI_R2Y_SET2_C6_SHIFT (0) /* Bits 0-6: Color Space Conversion Matrix Coefficient C6 */ +#define ISI_R2Y_SET2_C6_MASK (0x7f << ISI_R2Y_SET2_C6_SHIFT) +# define ISI_R2Y_SET2_C6(n) ((uint32_t)(n) << ISI_R2Y_SET2_C6_SHIFT) +#define ISI_R2Y_SET2_C7_SHIFT (8) /* Bits 8-14: Color Space Conversion Matrix Coefficient C7 */ +#define ISI_R2Y_SET2_C7_MASK (0x7f << ISI_R2Y_SET2_C7_SHIFT) +# define ISI_R2Y_SET2_C7(n) ((uint32_t)(n) << ISI_R2Y_SET2_C7_SHIFT) +#define ISI_R2Y_SET2_C8_SHIFT (16) /* Bits 16-22: Color Space Conversion Matrix Coefficient C8 */ +#define ISI_R2Y_SET2_C8_MASK (0x7f << ISI_R2Y_SET2_C8_SHIFT) +# define ISI_R2Y_SET2_C8(n) ((uint32_t)(n) << ISI_R2Y_SET2_C8_SHIFT) +#define ISI_R2Y_SET2_BOFF (1 << 24) /* Bit 24: Color Space Conversion Blue Component Offset */ + +/* ISI Control Register */ + +#define ISI_CR_ISIEN (1 << 0) /* Bit 0: ISI Module Enable Request */ +#define ISI_CR_ISIDIS (1 << 1) /* Bit 1: ISI Module Disable Request */ +#define ISI_CR_ISISRST (1 << 2) /* Bit 2: ISI Software Reset Request */ +#define ISI_CR_ISICDC (1 << 8) /* Bit 8: ISI Codec Request */ + +/* ISI Status Register, ISI Interrupt Enable Register, ISI Interrupt Disable + * Register, and ISI Interrupt Mask Register + */ + +#define ISI_SR_ENABLE (1 << 0) /* Bit 0: Module is enabled (status only) */ +#define ISI_INT_DISDONE (1 << 1) /* Bit 1: Module Disable Request has Terminated */ +#define ISI_INT_SRST (1 << 2) /* Bit 2: Module Software Reset Request has Terminated */ +#define ISI_SR_CDCPND (1 << 8) /* Bit 8: Pending Codec Request (status only) */ +#define ISI_INT_VSYNC (1 << 10) /* Bit 10: Vertical Synchronization */ +#define ISI_INT_PXFRDONE (1 << 16) /* Bit 16: Preview DMA Transfer has Terminated */ +#define ISI_INT_CXFRDONE (1 << 17) /* Bit 17: Codec DMA Transfer has Terminated */ +#define ISI_SR_SIP (1 << 19) /* Bit 19: Synchronization in Progress (status only) */ +#define ISI_INT_POVR (1 << 24) /* Bit 24: Preview Datapath Overflow */ +#define ISI_INT_COVR (1 << 25) /* Bit 25: Codec Datapath Overflow */ +#define ISI_INT_CRCERR (1 << 26) /* Bit 26: CRC Synchronization Error */ +#define ISI_INT_FROVR (1 << 27) /* Bit 27: Frame Rate Overrun */ + +/* DMA Channel Enable Register, DMA Channel Disable Register, and DMA Channel Status + * Register + */ + +#define ISI_DMA_PCH (1 << 0) /* Bit 0: Preview Channel */ +#define ISI_DMA_CCH (1 << 1) /* Bit 1: CODEC Channel */ + +/* DMA Preview Base Address Register */ + +#define ISI_DMA_PADDR_MASK (0xfffffffc) /* Bits 2-31: Preview Image Base Address */ + +/* DMA Preview Control Register */ + +#define ISI_DMA_PCTRL_PFETCH (1 << 0) /* Bit 0: Descriptor Fetch Control Field */ +#define ISI_DMA_PCTRL_PWB (1 << 1) /* Bit 1: Descriptor Writeback Control Field */ +#define ISI_DMA_PCTRL_PIEN (1 << 2) /* Bit 2: Transfer Done Flag Control */ +#define ISI_DMA_PCTRL_PDONE (1 << 3) /* Bit 3: (This field is only updated in the memory) */ + +/* DMA Preview Descriptor Address Register */ + +#define ISI_DMA_PDSCR_MASK (0xfffffffc) /* Bits 2-31: Preview Descriptor Base Address */ + +/* DMA Codec Base Address Register */ + +#define ISI_DMA_CADDR_MASK (0xfffffffc) /* Bits 2-31: Codec Image Base Address */ + +/* DMA Codec Control Register */ + +#define ISI_DMA_CCTRL_CFETCH (1 << 0) /* Bit 0: Descriptor Fetch Control Field */ +#define ISI_DMA_CCTRL_CWB (1 << 1) /* Bit 1: Descriptor Writeback Control Field */ +#define ISI_DMA_CCTRL_CIEN (1 << 2) /* Bit 2: Transfer Done flag control */ +#define ISI_DMA_CCTRL_CDONE (1 << 3) /* Bit 3: (This field is only updated in the memory) */ + +/* DMA Codec Descriptor Address Register */ + +#define ISI_DMA_CDSR_MASK (0xfffffffc) /* Bits 2-31: Codec Descriptor Base Address */ + +/* Write Protection Mode Register */ + +#define ISI_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define ISI_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection KEY Password */ +#define ISI_WPMR_WPKEY_MASK (000xffffff << ISI_WPMR_WPKEY_SHIFT) +# define ISI_WPMR_WPKEY (0x00495349 << ISI_WPMR_WPKEY_SHIFT) /* (ASCII code for "ISI") */ + +/* Write Protection Status Register */ + +#define ISI_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define ISI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define ISI_WPSR_WPVSRC_MASK (0xffff << ISI_WPSR_WPVSRC_SHIFT) +# define ISI_WPSR_WPVSRC_NONE (0 << ISI_WPSR_WPVSRC_SHIFT) /* No Write Protection Violation */ +# define ISI_WPSR_WPVSRC_CFG1 (1 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_CFG1 */ +# define ISI_WPSR_WPVSRC_CFG2 (2 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_CFG2 */ +# define ISI_WPSR_WPVSRC_PSIZE (3 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_PSIZE */ +# define ISI_WPSR_WPVSRC_PDECF (4 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_PDECF */ +# define ISI_WPSR_WPVSRC_Y2R_SET0 (5 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_Y2R_SET0 */ +# define ISI_WPSR_WPVSRC_Y2R_SET1 (6 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_Y2R_SET1 */ +# define ISI_WPSR_WPVSRC_R2Y_SET0 (7 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_R2Y_SET0 */ +# define ISI_WPSR_WPVSRC_R2Y_SET1 (8 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_R2Y_SET1 */ +# define ISI_WPSR_WPVSRC_R2Y_SET2 (9 << ISI_WPSR_WPVSRC_SHIFT) /* Write access in ISI_R2Y_SET2 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* "The destination frame buffers are defined by a series of Frame Buffer Descriptors + * (FBD). Each FBD controls the transfer of one entire frame and then optionally + * loads a further FBD to switch the DMA operation at another frame buffer address. + * + * "The FBD is defined by a series of three words. The first one defines the current + * frame buffer address (named DMA_X_ADDR register), the second defines control + * information (named DMA_X_CTRL register) and the third defines the next descriptor + * address (named DMA_X_DSCR). DMA transfer mode with linked list support is + * available for both codec and preview datapath." + */ + +struct isi_dscr_s +{ + uint32_t addr; /* Current framebuffer address */ + uint32_t ctrl; /* Control information */ + uint32_t dscr; /* Next descriptor address */ +}; + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_ISI_H */ diff --git a/arch/arm/src/sama5/chip/sam_lcdc.h b/arch/arm/src/sama5/chip/sam_lcdc.h new file mode 100644 index 0000000000000000000000000000000000000000..8d311e06f93fd97b492352dea1a083c4e8239c70 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_lcdc.h @@ -0,0 +1,1996 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_lcdc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_LCDC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_LCDC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_LCDC_NCLUT 256 /* Number of entries in the CLUTs */ + +/* LCDC Register Offsets ************************************************************/ + +#define SAM_LCDC_LCDCFG0_OFFSET 0x0000 /* LCD Controller Configuration Register 0 */ +#define SAM_LCDC_LCDCFG1_OFFSET 0x0004 /* LCD Controller Configuration Register 1 */ +#define SAM_LCDC_LCDCFG2_OFFSET 0x0008 /* LCD Controller Configuration Register 2 */ +#define SAM_LCDC_LCDCFG3_OFFSET 0x000c /* LCD Controller Configuration Register 3 */ +#define SAM_LCDC_LCDCFG4_OFFSET 0x0010 /* LCD Controller Configuration Register 4 */ +#define SAM_LCDC_LCDCFG5_OFFSET 0x0014 /* LCD Controller Configuration Register 5 */ +#define SAM_LCDC_LCDCFG6_OFFSET 0x0018 /* LCD Controller Configuration Register 6 */ + /* 0x001c Reserved */ +#define SAM_LCDC_LCDEN_OFFSET 0x0020 /* LCD Controller Enable Register */ +#define SAM_LCDC_LCDDIS_OFFSET 0x0024 /* LCD Controller Disable Register */ +#define SAM_LCDC_LCDSR_OFFSET 0x0028 /* LCD Controller Status Register */ +#define SAM_LCDC_LCDIER_OFFSET 0x002C /* LCD Controller Interrupt Enable Register */ +#define SAM_LCDC_LCDIDR_OFFSET 0x0030 /* LCD Controller Interrupt Disable Register */ +#define SAM_LCDC_LCDIMR_OFFSET 0x0034 /* LCD Controller Interrupt Mask Register */ +#define SAM_LCDC_LCDISR_OFFSET 0x0038 /* LCD Controller Interrupt Status Register */ + +#ifdef ATSAMA5D4 +# define SAM_LCDC_LCDATTR_OFFSET 0x003c /* LCD Controller Attribute Register */ +#endif + +#define SAM_LCDC_BASECHER_OFFSET 0x0040 /* Base Layer Channel Enable Register */ +#define SAM_LCDC_BASECHDR_OFFSET 0x0044 /* Base Layer Channel Disable Register */ +#define SAM_LCDC_BASECHSR_OFFSET 0x0048 /* Base Layer Channel Status Register */ +#define SAM_LCDC_BASEIER_OFFSET 0x004c /* Base Layer Interrupt Enable Register */ +#define SAM_LCDC_BASEIDR_OFFSET 0x0050 /* Base Layer Interrupt Disable Register */ +#define SAM_LCDC_BASEIMR_OFFSET 0x0054 /* Base Layer Interrupt Mask Register */ +#define SAM_LCDC_BASEISR_OFFSET 0x0058 /* Base Layer Interrupt Status Register */ +#define SAM_LCDC_BASEHEAD_OFFSET 0x005c /* Base DMA Head Register */ +#define SAM_LCDC_BASEADDR_OFFSET 0x0060 /* Base DMA Address Register */ +#define SAM_LCDC_BASECTRL_OFFSET 0x0064 /* Base DMA Control Register */ +#define SAM_LCDC_BASENEXT_OFFSET 0x0068 /* Base DMA Next Register */ +#define SAM_LCDC_BASECFG0_OFFSET 0x006c /* Base Configuration register 0 */ +#define SAM_LCDC_BASECFG1_OFFSET 0x0070 /* Base Configuration register 1 */ +#define SAM_LCDC_BASECFG2_OFFSET 0x0074 /* Base Configuration register 2 */ +#define SAM_LCDC_BASECFG3_OFFSET 0x0078 /* Base Configuration register 3 */ +#define SAM_LCDC_BASECFG4_OFFSET 0x007c /* Base Configuration register 4 */ +#define SAM_LCDC_BASECFG5_OFFSET 0x0080 /* Base Configuration register 5 */ +#define SAM_LCDC_BASECFG6_OFFSET 0x0084 /* Base Configuration register 6 */ + /* 0x0088-0x013c Reserved */ +#define SAM_LCDC_OVR1CHER_OFFSET 0x0140 /* Overlay 1 Channel Enable Register */ +#define SAM_LCDC_OVR1CHDR_OFFSET 0x0144 /* Overlay 1 Channel Disable Register */ +#define SAM_LCDC_OVR1CHSR_OFFSET 0x0148 /* Overlay 1 Channel Status Register */ +#define SAM_LCDC_OVR1IER_OFFSET 0x014c /* Overlay 1 Interrupt Enable Register */ +#define SAM_LCDC_OVR1IDR_OFFSET 0x0150 /* Overlay 1 Interrupt Disable Register */ +#define SAM_LCDC_OVR1IMR_OFFSET 0x0154 /* Overlay 1 Interrupt Mask Register */ +#define SAM_LCDC_OVR1ISR_OFFSET 0x0158 /* Overlay 1 Interrupt Status Register */ +#define SAM_LCDC_OVR1HEAD_OFFSET 0x015c /* Overlay 1 DMA Head Register */ +#define SAM_LCDC_OVR1ADDR_OFFSET 0x0160 /* Overlay 1 DMA Address Register */ +#define SAM_LCDC_OVR1CTRL_OFFSET 0x0164 /* Overlay 1 DMA Control Register */ +#define SAM_LCDC_OVR1NEXT_OFFSET 0x0168 /* Overlay 1 DMA Next Register */ +#define SAM_LCDC_OVR1CFG0_OFFSET 0x016c /* Overlay 1 Configuration 0 Register */ +#define SAM_LCDC_OVR1CFG1_OFFSET 0x0170 /* Overlay 1 Configuration 1 Register */ +#define SAM_LCDC_OVR1CFG2_OFFSET 0x0174 /* Overlay 1 Configuration 2 Register */ +#define SAM_LCDC_OVR1CFG3_OFFSET 0x0178 /* Overlay 1 Configuration 3 Register */ +#define SAM_LCDC_OVR1CFG4_OFFSET 0x017c /* Overlay 1 Configuration 4 Register */ +#define SAM_LCDC_OVR1CFG5_OFFSET 0x0180 /* Overlay 1 Configuration 5 Register */ +#define SAM_LCDC_OVR1CFG6_OFFSET 0x0184 /* Overlay 1 Configuration 6 Register */ +#define SAM_LCDC_OVR1CFG7_OFFSET 0x0188 /* Overlay 1 Configuration 7 Register */ +#define SAM_LCDC_OVR1CFG8_OFFSET 0x018c /* Overlay 1 Configuration 8 Register */ +#define SAM_LCDC_OVR1CFG9_OFFSET 0x0190 /* Overlay 1 Configuration 9 Register */ + /* 0x0194-0x023c Reserved */ +#define SAM_LCDC_OVR2CHER_OFFSET 0x0240 /* Overlay 2 Channel Enable Register */ +#define SAM_LCDC_OVR2CHDR_OFFSET 0x0244 /* Overlay 2 Channel Disable Register */ +#define SAM_LCDC_OVR2CHSR_OFFSET 0x0248 /* Overlay 2 Channel Status Register */ +#define SAM_LCDC_OVR2IER_OFFSET 0x024c /* Overlay 2 Interrupt Enable Register */ +#define SAM_LCDC_OVR2IDR_OFFSET 0x0250 /* Overlay 2 Interrupt Disable Register */ +#define SAM_LCDC_OVR2IMR_OFFSET 0x0254 /* Overlay 2 Interrupt Mask Register */ +#define SAM_LCDC_OVR2ISR_OFFSET 0x0258 /* Overlay 2 Interrupt Status Register */ +#define SAM_LCDC_OVR2HEAD_OFFSET 0x025c /* Overlay 2 DMA Head Register */ +#define SAM_LCDC_OVR2ADDR_OFFSET 0x0260 /* Overlay 2 DMA Address Register */ +#define SAM_LCDC_OVR2CTRL_OFFSET 0x0264 /* Overlay 2 DMA Control Register */ +#define SAM_LCDC_OVR2NEXT_OFFSET 0x0268 /* Overlay 2 DMA Next Register */ +#define SAM_LCDC_OVR2CFG0_OFFSET 0x026c /* Overlay 2 Configuration 0 Register */ +#define SAM_LCDC_OVR2CFG1_OFFSET 0x0270 /* Overlay 2 Configuration 1 Register */ +#define SAM_LCDC_OVR2CFG2_OFFSET 0x0274 /* Overlay 2 Configuration 2 Register */ +#define SAM_LCDC_OVR2CFG3_OFFSET 0x0278 /* Overlay 2 Configuration 3 Register */ +#define SAM_LCDC_OVR2CFG4_OFFSET 0x027c /* Overlay 2 Configuration 4 Register */ +#define SAM_LCDC_OVR2CFG5_OFFSET 0x0280 /* Overlay 2 Configuration 5 Register */ +#define SAM_LCDC_OVR2CFG6_OFFSET 0x0284 /* Overlay 2 Configuration 6 Register */ +#define SAM_LCDC_OVR2CFG7_OFFSET 0x0288 /* Overlay 2 Configuration 7 Register */ +#define SAM_LCDC_OVR2CFG8_OFFSET 0x028c /* Overlay 2 Configuration 8 Register */ +#define SAM_LCDC_OVR2CFG9_OFFSET 0x0290 /* Overlay 2 Configuration 9 Register */ + /* 0x0294-0x033c Reserved */ +#define SAM_LCDC_HEOCHER_OFFSET 0x0340 /* High-End Overlay Channel Enable Register */ +#define SAM_LCDC_HEOCHDR_OFFSET 0x0344 /* High-End Overlay Channel Disable Register */ +#define SAM_LCDC_HEOCHSR_OFFSET 0x0348 /* High-End Overlay Channel Status Register */ +#define SAM_LCDC_HEOIER_OFFSET 0x034c /* High-End Overlay Interrupt Enable Register */ +#define SAM_LCDC_HEOIDR_OFFSET 0x0350 /* High-End Overlay Interrupt Disable Register */ +#define SAM_LCDC_HEOIMR_OFFSET 0x0354 /* High-End Overlay Interrupt Mask Register */ +#define SAM_LCDC_HEOISR_OFFSET 0x0358 /* High-End Overlay Interrupt Status Register */ +#define SAM_LCDC_HEOHEAD_OFFSET 0x035c /* High-End Overlay DMA Head Register */ +#define SAM_LCDC_HEOADDR_OFFSET 0x0360 /* High-End Overlay DMA Address Register */ +#define SAM_LCDC_HEOCTRL_OFFSET 0x0364 /* High-End Overlay DMA Control Register */ +#define SAM_LCDC_HEONEXT_OFFSET 0x0368 /* High-End Overlay DMA Next Register */ +#define SAM_LCDC_HEOUHEAD_OFFSET 0x036c /* High-End Overlay U DMA Head Register */ +#define SAM_LCDC_HEOUADDR_OFFSET 0x0370 /* High-End Overlay U DMA Address Register */ +#define SAM_LCDC_HEOUCTRL_OFFSET 0x0374 /* High-End Overlay U DMA Control Register */ +#define SAM_LCDC_HEOUNEXT_OFFSET 0x0378 /* High-End Overlay U DMA Next Register */ +#define SAM_LCDC_HEOVHEAD_OFFSET 0x037c /* High-End Overlay V DMA Head Register */ +#define SAM_LCDC_HEOVADDR_OFFSET 0x0380 /* High-End Overlay V DMA Address Register */ +#define SAM_LCDC_HEOVCTRL_OFFSET 0x0384 /* High-End Overlay V DMA Control Register */ +#define SAM_LCDC_HEOVNEXT_OFFSET 0x0388 /* High-End Overlay V DMA Next Register */ +#define SAM_LCDC_HEOCFG0_OFFSET 0x038c /* High-End Overlay Configuration Register 0 */ +#define SAM_LCDC_HEOCFG1_OFFSET 0x0390 /* High-End Overlay Configuration Register 1 */ +#define SAM_LCDC_HEOCFG2_OFFSET 0x0394 /* High-End Overlay Configuration Register 2 */ +#define SAM_LCDC_HEOCFG3_OFFSET 0x0398 /* High-End Overlay Configuration Register 3 */ +#define SAM_LCDC_HEOCFG4_OFFSET 0x039c /* High-End Overlay Configuration Register 4 */ +#define SAM_LCDC_HEOCFG5_OFFSET 0x03a0 /* High-End Overlay Configuration Register 5 */ +#define SAM_LCDC_HEOCFG6_OFFSET 0x03a4 /* High-End Overlay Configuration Register 6 */ +#define SAM_LCDC_HEOCFG7_OFFSET 0x03a8 /* High-End Overlay Configuration Register 7 */ +#define SAM_LCDC_HEOCFG8_OFFSET 0x03ac /* High-End Overlay Configuration Register 8 */ +#define SAM_LCDC_HEOCFG9_OFFSET 0x03b0 /* High-End Overlay Configuration Register 9 */ +#define SAM_LCDC_HEOCFG10_OFFSET 0x03b4 /* High-End Overlay Configuration Register 10 */ +#define SAM_LCDC_HEOCFG11_OFFSET 0x03b8 /* High-End Overlay Configuration Register 11 */ +#define SAM_LCDC_HEOCFG12_OFFSET 0x03bc /* High-End Overlay Configuration Register 12 */ +#define SAM_LCDC_HEOCFG13_OFFSET 0x03c0 /* High-End Overlay Configuration Register 13 */ +#define SAM_LCDC_HEOCFG14_OFFSET 0x03c4 /* High-End Overlay Configuration Register 14 */ +#define SAM_LCDC_HEOCFG15_OFFSET 0x03c8 /* High-End Overlay Configuration Register 15 */ +#define SAM_LCDC_HEOCFG16_OFFSET 0x03cc /* High-End Overlay Configuration Register 16 */ +#define SAM_LCDC_HEOCFG17_OFFSET 0x03d0 /* High-End Overlay Configuration Register 17 */ +#define SAM_LCDC_HEOCFG18_OFFSET 0x03d4 /* High-End Overlay Configuration Register 18 */ +#define SAM_LCDC_HEOCFG19_OFFSET 0x03d8 /* High-End Overlay Configuration Register 19 */ +#define SAM_LCDC_HEOCFG20_OFFSET 0x03dc /* High-End Overlay Configuration Register 20 */ +#define SAM_LCDC_HEOCFG21_OFFSET 0x03e0 /* High-End Overlay Configuration Register 21 */ +#define SAM_LCDC_HEOCFG22_OFFSET 0x03e4 /* High-End Overlay Configuration Register 22 */ +#define SAM_LCDC_HEOCFG23_OFFSET 0x03e8 /* High-End Overlay Configuration Register 23 */ +#define SAM_LCDC_HEOCFG24_OFFSET 0x03ec /* High-End Overlay Configuration Register 24 */ +#define SAM_LCDC_HEOCFG25_OFFSET 0x03f0 /* High-End Overlay Configuration Register 25 */ +#define SAM_LCDC_HEOCFG26_OFFSET 0x03f4 /* High-End Overlay Configuration Register 26 */ +#define SAM_LCDC_HEOCFG27_OFFSET 0x03f8 /* High-End Overlay Configuration Register 27 */ +#define SAM_LCDC_HEOCFG28_OFFSET 0x03fc /* High-End Overlay Configuration Register 28 */ +#define SAM_LCDC_HEOCFG29_OFFSET 0x0400 /* High-End Overlay Configuration Register 29 */ +#define SAM_LCDC_HEOCFG30_OFFSET 0x0404 /* High-End Overlay Configuration Register 30 */ +#define SAM_LCDC_HEOCFG31_OFFSET 0x0408 /* High-End Overlay Configuration Register 31 */ +#define SAM_LCDC_HEOCFG32_OFFSET 0x040c /* High-End Overlay Configuration Register 32 */ +#define SAM_LCDC_HEOCFG33_OFFSET 0x0410 /* High-End Overlay Configuration Register 33 */ +#define SAM_LCDC_HEOCFG34_OFFSET 0x0414 /* High-End Overlay Configuration Register 34 */ +#define SAM_LCDC_HEOCFG35_OFFSET 0x0418 /* High-End Overlay Configuration Register 35 */ +#define SAM_LCDC_HEOCFG36_OFFSET 0x041c /* High-End Overlay Configuration Register 36 */ +#define SAM_LCDC_HEOCFG37_OFFSET 0x0420 /* High-End Overlay Configuration Register 37 */ +#define SAM_LCDC_HEOCFG38_OFFSET 0x0424 /* High-End Overlay Configuration Register 38 */ +#define SAM_LCDC_HEOCFG39_OFFSET 0x0428 /* High-End Overlay Configuration Register 39 */ +#define SAM_LCDC_HEOCFG40_OFFSET 0x042c /* High-End Overlay Configuration Register 40 */ +#define SAM_LCDC_HEOCFG41_OFFSET 0x0430 /* High-End Overlay Configuration Register 41 */ + /* 0x0434-0x043c Reserved */ +#ifdef ATSAMA5D3 +# define SAMA5_HAVE_LCDC_HCRCH 1 /* Supports conditional compilation */ +# define SAM_LCDC_HCRCHER_OFFSET 0x0440 /* Hardware Cursor Channel Enable Register */ +# define SAM_LCDC_HCRCHDR_OFFSET 0x0444 /* Hardware Cursor Channel Disable Register */ +# define SAM_LCDC_HCRCHSR_OFFSET 0x0448 /* Hardware Cursor Channel Status Register */ +# define SAM_LCDC_HCRIER_OFFSET 0x044c /* Hardware Cursor Interrupt Enable Register */ +# define SAM_LCDC_HCRIDR_OFFSET 0x0450 /* Hardware Cursor Interrupt Disable Register */ +# define SAM_LCDC_HCRIMR_OFFSET 0x0454 /* Hardware Cursor Interrupt Mask Register */ +# define SAM_LCDC_HCRISR_OFFSET 0x0458 /* Hardware Cursor Interrupt Status Register */ +# define SAM_LCDC_HCRHEAD_OFFSET 0x045c /* Hardware Cursor DMA Head Register */ +# define SAM_LCDC_HCRADDR_OFFSET 0x0460 /* Hardware cursor DMA Address Register */ +# define SAM_LCDC_HCRCTRL_OFFSET 0x0464 /* Hardware Cursor DMA Control Register */ +# define SAM_LCDC_HCRNEXT_OFFSET 0x0468 /* Hardware Cursor DMA Next Register */ +# define SAM_LCDC_HCRCFG0_OFFSET 0x046c /* Hardware Cursor Configuration 0 Register */ +# define SAM_LCDC_HCRCFG1_OFFSET 0x0470 /* Hardware Cursor Configuration 1 Register */ +# define SAM_LCDC_HCRCFG2_OFFSET 0x0474 /* Hardware Cursor Configuration 2 Register */ +# define SAM_LCDC_HCRCFG3_OFFSET 0x0478 /* Hardware Cursor Configuration 3 Register */ +# define SAM_LCDC_HCRCFG4_OFFSET 0x047c /* Hardware Cursor Configuration 4 Register */ + /* 0x0480 Reserved */ +# define SAM_LCDC_HCRCFG6_OFFSET 0x0484 /* Hardware Cursor Configuration 6 Register */ +# define SAM_LCDC_HCRCFG7_OFFSET 0x0488 /* Hardware Cursor Configuration 7 Register */ +# define SAM_LCDC_HCRCFG8_OFFSET 0x048c /* Hardware Cursor Configuration 8 Register */ +# define SAM_LCDC_HCRCFG9_OFFSET 0x0490 /* Hardware Cursor Configuration 9 Register */ + /* 0x0494-0x053c Reserved */ +# define SAMA5_HAVE_LCDC_PPCH 1 /* Supports conditional compilation */ +# define SAM_LCDC_PPCHER_OFFSET 0x0540 /* Post Processing Channel Enable Register */ +# define SAM_LCDC_PPCHDR_OFFSET 0x0544 /* Post Processing Channel Disable Register */ +# define SAM_LCDC_PPCHSR_OFFSET 0x0548 /* Post Processing Channel Status Register */ +# define SAM_LCDC_PPIER_OFFSET 0x054c /* Post Processing Interrupt Enable Register */ +# define SAM_LCDC_PPIDR_OFFSET 0x0550 /* Post Processing Interrupt Disable Register */ +# define SAM_LCDC_PPIMR_OFFSET 0x0554 /* Post Processing Interrupt Mask Register */ +# define SAM_LCDC_PPISR_OFFSET 0x0558 /* Post Processing Interrupt Status Register */ +# define SAM_LCDC_PPHEAD_OFFSET 0x055c /* Post Processing Head Register */ +# define SAM_LCDC_PPADDR_OFFSET 0x0560 /* Post Processing Address Register */ +# define SAM_LCDC_PPCTRL_OFFSET 0x0564 /* Post Processing Control Register */ +# define SAM_LCDC_PPNEXT_OFFSET 0x0568 /* Post Processing Next Register */ +# define SAM_LCDC_PPCFG0_OFFSET 0x056c /* Post Processing Configuration Register 0 */ +# define SAM_LCDC_PPCFG1_OFFSET 0x0570 /* Post Processing Configuration Register 1 */ +# define SAM_LCDC_PPCFG2_OFFSET 0x0574 /* Post Processing Configuration Register 2 */ +# define SAM_LCDC_PPCFG3_OFFSET 0x0578 /* Post Processing Configuration Register 3 */ +# define SAM_LCDC_PPCFG4_OFFSET 0x057c /* Post Processing Configuration Register 4 */ +# define SAM_LCDC_PPCFG5_OFFSET 0x0580 /* Post Processing Configuration Register 5 */ +#endif + /* 0x0584-0x05fc Reserved */ +/* 0x0600-0x08fc Base CLUT Registers 0-255 */ + +#define SAM_LCDC_BASECLUT_OFFSET(n) (0x0600 + ((n) << 2)) + +/* 0x0a00-0x0dfc Overlay 1 CLUT Registers 0-255 */ + +#define SAM_LCDC_OVR1CLUT_OFFSET(n) (0xa00 + ((n) << 2)) + +/* 0x0e00-0x11fc Overlay 2 CLUT Registers 0-255 */ + +#define SAM_LCDC_OVR2CLUT_OFFSET(n) (0x0e00 + ((n) << 2)) + +/* 0x1200-0x15fc High End Overlay CLUT Registers 0-255 */ + +#define SAM_LCDC_HEOCLUT_OFFSET(n) (0x1200 + ((n) << 2)) + +/* 0x1600-0x19fc Hardware Cursor CLUT Registers 0-255 */ + +#ifdef ATSAMA5D3 +# define SAM_LCDC_HCRCLUT_OFFSET(n) (0x1600 + ((n) << 2)) +#endif + /* 0x1a00-0x1fe4 Reserved */ +/* LCDC Register Addresses *********************************************************/ + +#define SAM_LCDC_LCDCFG0 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG0_OFFSET) +#define SAM_LCDC_LCDCFG1 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG1_OFFSET) +#define SAM_LCDC_LCDCFG2 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG2_OFFSET) +#define SAM_LCDC_LCDCFG3 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG3_OFFSET) +#define SAM_LCDC_LCDCFG4 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG4_OFFSET) +#define SAM_LCDC_LCDCFG5 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG5_OFFSET) +#define SAM_LCDC_LCDCFG6 (SAM_LCDC_VBASE+SAM_LCDC_LCDCFG6_OFFSET) + +#define SAM_LCDC_LCDEN (SAM_LCDC_VBASE+SAM_LCDC_LCDEN_OFFSET) +#define SAM_LCDC_LCDDIS (SAM_LCDC_VBASE+SAM_LCDC_LCDDIS_OFFSET) +#define SAM_LCDC_LCDSR (SAM_LCDC_VBASE+SAM_LCDC_LCDSR_OFFSET) +#define SAM_LCDC_LCDIER (SAM_LCDC_VBASE+SAM_LCDC_LCDIER_OFFSET) +#define SAM_LCDC_LCDIDR (SAM_LCDC_VBASE+SAM_LCDC_LCDIDR_OFFSET) +#define SAM_LCDC_LCDIMR (SAM_LCDC_VBASE+SAM_LCDC_LCDIMR_OFFSET) +#define SAM_LCDC_LCDISR (SAM_LCDC_VBASE+SAM_LCDC_LCDISR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_LCDC_LCDATTR (SAM_LCDC_VBASE+SAM_LCDC_LCDATTR_OFFSET) +#endif + +#define SAM_LCDC_BASECHER (SAM_LCDC_VBASE+SAM_LCDC_BASECHER_OFFSET) +#define SAM_LCDC_BASECHDR (SAM_LCDC_VBASE+SAM_LCDC_BASECHDR_OFFSET) +#define SAM_LCDC_BASECHSR (SAM_LCDC_VBASE+SAM_LCDC_BASECHSR_OFFSET) +#define SAM_LCDC_BASEIER (SAM_LCDC_VBASE+SAM_LCDC_BASEIER_OFFSET) +#define SAM_LCDC_BASEIDR (SAM_LCDC_VBASE+SAM_LCDC_BASEIDR_OFFSET) +#define SAM_LCDC_BASEIMR (SAM_LCDC_VBASE+SAM_LCDC_BASEIMR_OFFSET) +#define SAM_LCDC_BASEISR (SAM_LCDC_VBASE+SAM_LCDC_BASEISR_OFFSET) +#define SAM_LCDC_BASEHEAD (SAM_LCDC_VBASE+SAM_LCDC_BASEHEAD_OFFSET) +#define SAM_LCDC_BASEADDR (SAM_LCDC_VBASE+SAM_LCDC_BASEADDR_OFFSET) +#define SAM_LCDC_BASECTRL (SAM_LCDC_VBASE+SAM_LCDC_BASECTRL_OFFSET) +#define SAM_LCDC_BASENEXT (SAM_LCDC_VBASE+SAM_LCDC_BASENEXT_OFFSET) +#define SAM_LCDC_BASECFG0 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG0_OFFSET) +#define SAM_LCDC_BASECFG1 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG1_OFFSET) +#define SAM_LCDC_BASECFG2 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG2_OFFSET) +#define SAM_LCDC_BASECFG3 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG3_OFFSET) +#define SAM_LCDC_BASECFG4 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG4_OFFSET) +#define SAM_LCDC_BASECFG5 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG5_OFFSET) +#define SAM_LCDC_BASECFG6 (SAM_LCDC_VBASE+SAM_LCDC_BASECFG6_OFFSET) + +#define SAM_LCDC_OVR1CHER (SAM_LCDC_VBASE+SAM_LCDC_OVR1CHER_OFFSET) +#define SAM_LCDC_OVR1CHDR (SAM_LCDC_VBASE+SAM_LCDC_OVR1CHDR_OFFSET) +#define SAM_LCDC_OVR1CHSR (SAM_LCDC_VBASE+SAM_LCDC_OVR1CHSR_OFFSET) +#define SAM_LCDC_OVR1IER (SAM_LCDC_VBASE+SAM_LCDC_OVR1IER_OFFSET) +#define SAM_LCDC_OVR1IDR (SAM_LCDC_VBASE+SAM_LCDC_OVR1IDR_OFFSET) +#define SAM_LCDC_OVR1IMR (SAM_LCDC_VBASE+SAM_LCDC_OVR1IMR_OFFSET) +#define SAM_LCDC_OVR1ISR (SAM_LCDC_VBASE+SAM_LCDC_OVR1ISR_OFFSET) +#define SAM_LCDC_OVR1HEAD (SAM_LCDC_VBASE+SAM_LCDC_OVR1HEAD_OFFSET) +#define SAM_LCDC_OVR1ADDR (SAM_LCDC_VBASE+SAM_LCDC_OVR1ADDR_OFFSET) +#define SAM_LCDC_OVR1CTRL (SAM_LCDC_VBASE+SAM_LCDC_OVR1CTRL_OFFSET) +#define SAM_LCDC_OVR1NEXT (SAM_LCDC_VBASE+SAM_LCDC_OVR1NEXT_OFFSET) +#define SAM_LCDC_OVR1CFG0 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG0_OFFSET) +#define SAM_LCDC_OVR1CFG1 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG1_OFFSET) +#define SAM_LCDC_OVR1CFG2 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG2_OFFSET) +#define SAM_LCDC_OVR1CFG3 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG3_OFFSET) +#define SAM_LCDC_OVR1CFG4 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG4_OFFSET) +#define SAM_LCDC_OVR1CFG5 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG5_OFFSET) +#define SAM_LCDC_OVR1CFG6 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG6_OFFSET) +#define SAM_LCDC_OVR1CFG7 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG7_OFFSET) +#define SAM_LCDC_OVR1CFG8 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG8_OFFSET) +#define SAM_LCDC_OVR1CFG9 (SAM_LCDC_VBASE+SAM_LCDC_OVR1CFG9_OFFSET) + +#define SAM_LCDC_OVR2CHER (SAM_LCDC_VBASE+SAM_LCDC_OVR2CHER_OFFSET) +#define SAM_LCDC_OVR2CHDR (SAM_LCDC_VBASE+SAM_LCDC_OVR2CHDR_OFFSET) +#define SAM_LCDC_OVR2CHSR (SAM_LCDC_VBASE+SAM_LCDC_OVR2CHSR_OFFSET) +#define SAM_LCDC_OVR2IER (SAM_LCDC_VBASE+SAM_LCDC_OVR2IER_OFFSET) +#define SAM_LCDC_OVR2IDR (SAM_LCDC_VBASE+SAM_LCDC_OVR2IDR_OFFSET) +#define SAM_LCDC_OVR2IMR (SAM_LCDC_VBASE+SAM_LCDC_OVR2IMR_OFFSET) +#define SAM_LCDC_OVR2ISR (SAM_LCDC_VBASE+SAM_LCDC_OVR2ISR_OFFSET) +#define SAM_LCDC_OVR2HEAD (SAM_LCDC_VBASE+SAM_LCDC_OVR2HEAD_OFFSET) +#define SAM_LCDC_OVR2ADDR (SAM_LCDC_VBASE+SAM_LCDC_OVR2ADDR_OFFSET) +#define SAM_LCDC_OVR2CTRL (SAM_LCDC_VBASE+SAM_LCDC_OVR2CTRL_OFFSET) +#define SAM_LCDC_OVR2NEXT (SAM_LCDC_VBASE+SAM_LCDC_OVR2NEXT_OFFSET) +#define SAM_LCDC_OVR2CFG0 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG0_OFFSET) +#define SAM_LCDC_OVR2CFG1 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG1_OFFSET) +#define SAM_LCDC_OVR2CFG2 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG2_OFFSET) +#define SAM_LCDC_OVR2CFG3 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG3_OFFSET) +#define SAM_LCDC_OVR2CFG4 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG4_OFFSET) +#define SAM_LCDC_OVR2CFG5 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG5_OFFSET) +#define SAM_LCDC_OVR2CFG6 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG6_OFFSET) +#define SAM_LCDC_OVR2CFG7 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG7_OFFSET) +#define SAM_LCDC_OVR2CFG8 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG8_OFFSET) +#define SAM_LCDC_OVR2CFG9 (SAM_LCDC_VBASE+SAM_LCDC_OVR2CFG9_OFFSET) + +#define SAM_LCDC_HEOCHER (SAM_LCDC_VBASE+SAM_LCDC_HEOCHER_OFFSET) +#define SAM_LCDC_HEOCHDR (SAM_LCDC_VBASE+SAM_LCDC_HEOCHDR_OFFSET) +#define SAM_LCDC_HEOCHSR (SAM_LCDC_VBASE+SAM_LCDC_HEOCHSR_OFFSET) +#define SAM_LCDC_HEOIER (SAM_LCDC_VBASE+SAM_LCDC_HEOIER_OFFSET) +#define SAM_LCDC_HEOIDR (SAM_LCDC_VBASE+SAM_LCDC_HEOIDR_OFFSET) +#define SAM_LCDC_HEOIMR (SAM_LCDC_VBASE+SAM_LCDC_HEOIMR_OFFSET) +#define SAM_LCDC_HEOISR (SAM_LCDC_VBASE+SAM_LCDC_HEOISR_OFFSET) +#define SAM_LCDC_HEOHEAD (SAM_LCDC_VBASE+SAM_LCDC_HEOHEAD_OFFSET) +#define SAM_LCDC_HEOADDR (SAM_LCDC_VBASE+SAM_LCDC_HEOADDR_OFFSET) +#define SAM_LCDC_HEOCTRL (SAM_LCDC_VBASE+SAM_LCDC_HEOCTRL_OFFSET) +#define SAM_LCDC_HEONEXT (SAM_LCDC_VBASE+SAM_LCDC_HEONEXT_OFFSET) +#define SAM_LCDC_HEOUHEAD (SAM_LCDC_VBASE+SAM_LCDC_HEOUHEAD_OFFSET) +#define SAM_LCDC_HEOUADDR (SAM_LCDC_VBASE+SAM_LCDC_HEOUADDR_OFFSET) +#define SAM_LCDC_HEOUCTRL (SAM_LCDC_VBASE+SAM_LCDC_HEOUCTRL_OFFSET) +#define SAM_LCDC_HEOUNEXT (SAM_LCDC_VBASE+SAM_LCDC_HEOUNEXT_OFFSET) +#define SAM_LCDC_HEOVHEAD (SAM_LCDC_VBASE+SAM_LCDC_HEOVHEAD_OFFSET) +#define SAM_LCDC_HEOVADDR (SAM_LCDC_VBASE+SAM_LCDC_HEOVADDR_OFFSET) +#define SAM_LCDC_HEOVCTRL (SAM_LCDC_VBASE+SAM_LCDC_HEOVCTRL_OFFSET) +#define SAM_LCDC_HEOVNEXT (SAM_LCDC_VBASE+SAM_LCDC_HEOVNEXT_OFFSET) +#define SAM_LCDC_HEOCFG0 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG0_OFFSET) +#define SAM_LCDC_HEOCFG1 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG1_OFFSET) +#define SAM_LCDC_HEOCFG2 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG2_OFFSET) +#define SAM_LCDC_HEOCFG3 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG3_OFFSET) +#define SAM_LCDC_HEOCFG4 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG4_OFFSET) +#define SAM_LCDC_HEOCFG5 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG5_OFFSET) +#define SAM_LCDC_HEOCFG6 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG6_OFFSET) +#define SAM_LCDC_HEOCFG7 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG7_OFFSET) +#define SAM_LCDC_HEOCFG8 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG8_OFFSET) +#define SAM_LCDC_HEOCFG9 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG9_OFFSET) +#define SAM_LCDC_HEOCFG10 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG10_OFFSET) +#define SAM_LCDC_HEOCFG11 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG11_OFFSET) +#define SAM_LCDC_HEOCFG12 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG12_OFFSET) +#define SAM_LCDC_HEOCFG13 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG13_OFFSET) +#define SAM_LCDC_HEOCFG14 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG14_OFFSET) +#define SAM_LCDC_HEOCFG15 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG15_OFFSET) +#define SAM_LCDC_HEOCFG16 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG16_OFFSET) +#define SAM_LCDC_HEOCFG17 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG17_OFFSET) +#define SAM_LCDC_HEOCFG18 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG18_OFFSET) +#define SAM_LCDC_HEOCFG19 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG19_OFFSET) +#define SAM_LCDC_HEOCFG20 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG20_OFFSET) +#define SAM_LCDC_HEOCFG21 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG21_OFFSET) +#define SAM_LCDC_HEOCFG22 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG22_OFFSET) +#define SAM_LCDC_HEOCFG23 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG23_OFFSET) +#define SAM_LCDC_HEOCFG24 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG24_OFFSET) +#define SAM_LCDC_HEOCFG25 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG25_OFFSET) +#define SAM_LCDC_HEOCFG26 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG26_OFFSET) +#define SAM_LCDC_HEOCFG27 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG27_OFFSET) +#define SAM_LCDC_HEOCFG28 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG28_OFFSET) +#define SAM_LCDC_HEOCFG29 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG29_OFFSET) +#define SAM_LCDC_HEOCFG30 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG30_OFFSET) +#define SAM_LCDC_HEOCFG31 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG31_OFFSET) +#define SAM_LCDC_HEOCFG32 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG32_OFFSET) +#define SAM_LCDC_HEOCFG33 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG33_OFFSET) +#define SAM_LCDC_HEOCFG34 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG34_OFFSET) +#define SAM_LCDC_HEOCFG35 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG35_OFFSET) +#define SAM_LCDC_HEOCFG36 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG36_OFFSET) +#define SAM_LCDC_HEOCFG37 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG37_OFFSET) +#define SAM_LCDC_HEOCFG38 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG38_OFFSET) +#define SAM_LCDC_HEOCFG39 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG39_OFFSET) +#define SAM_LCDC_HEOCFG40 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG40_OFFSET) +#define SAM_LCDC_HEOCFG41 (SAM_LCDC_VBASE+SAM_LCDC_HEOCFG41_OFFSET) + +#ifdef ATSAMA5D3 +# define SAM_LCDC_HCRCHER (SAM_LCDC_VBASE+SAM_LCDC_HCRCHER_OFFSET) +# define SAM_LCDC_HCRCHDR (SAM_LCDC_VBASE+SAM_LCDC_HCRCHDR_OFFSET) +# define SAM_LCDC_HCRCHSR (SAM_LCDC_VBASE+SAM_LCDC_HCRCHSR_OFFSET) +# define SAM_LCDC_HCRIER (SAM_LCDC_VBASE+SAM_LCDC_HCRIER_OFFSET) +# define SAM_LCDC_HCRIDR (SAM_LCDC_VBASE+SAM_LCDC_HCRIDR_OFFSET) +# define SAM_LCDC_HCRIMR (SAM_LCDC_VBASE+SAM_LCDC_HCRIMR_OFFSET) +# define SAM_LCDC_HCRISR (SAM_LCDC_VBASE+SAM_LCDC_HCRISR_OFFSET) +# define SAM_LCDC_HCRHEAD (SAM_LCDC_VBASE+SAM_LCDC_HCRHEAD_OFFSET) +# define SAM_LCDC_HCRADDR (SAM_LCDC_VBASE+SAM_LCDC_HCRADDR_OFFSET) +# define SAM_LCDC_HCRCTRL (SAM_LCDC_VBASE+SAM_LCDC_HCRCTRL_OFFSET) +# define SAM_LCDC_HCRNEXT (SAM_LCDC_VBASE+SAM_LCDC_HCRNEXT_OFFSET) +# define SAM_LCDC_HCRCFG0 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG0_OFFSET) +# define SAM_LCDC_HCRCFG1 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG1_OFFSET) +# define SAM_LCDC_HCRCFG2 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG2_OFFSET) +# define SAM_LCDC_HCRCFG3 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG3_OFFSET) +# define SAM_LCDC_HCRCFG4 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG4_OFFSET) +# define SAM_LCDC_HCRCFG6 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG6_OFFSET) +# define SAM_LCDC_HCRCFG7 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG7_OFFSET) +# define SAM_LCDC_HCRCFG8 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG8_OFFSET) +# define SAM_LCDC_HCRCFG9 (SAM_LCDC_VBASE+SAM_LCDC_HCRCFG9_OFFSET) + +# define SAM_LCDC_PPCHER (SAM_LCDC_VBASE+SAM_LCDC_PPCHER_OFFSET) +# define SAM_LCDC_PPCHDR (SAM_LCDC_VBASE+SAM_LCDC_PPCHDR_OFFSET) +# define SAM_LCDC_PPCHSR (SAM_LCDC_VBASE+SAM_LCDC_PPCHSR_OFFSET) +# define SAM_LCDC_PPIER (SAM_LCDC_VBASE+SAM_LCDC_PPIER_OFFSET) +# define SAM_LCDC_PPIDR (SAM_LCDC_VBASE+SAM_LCDC_PPIDR_OFFSET) +# define SAM_LCDC_PPIMR (SAM_LCDC_VBASE+SAM_LCDC_PPIMR_OFFSET) +# define SAM_LCDC_PPISR (SAM_LCDC_VBASE+SAM_LCDC_PPISR_OFFSET) +# define SAM_LCDC_PPHEAD (SAM_LCDC_VBASE+SAM_LCDC_PPHEAD_OFFSET) +# define SAM_LCDC_PPADDR (SAM_LCDC_VBASE+SAM_LCDC_PPADDR_OFFSET) +# define SAM_LCDC_PPCTRL (SAM_LCDC_VBASE+SAM_LCDC_PPCTRL_OFFSET) +# define SAM_LCDC_PPNEXT (SAM_LCDC_VBASE+SAM_LCDC_PPNEXT_OFFSET) +# define SAM_LCDC_PPCFG0 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG0_OFFSET) +# define SAM_LCDC_PPCFG1 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG1_OFFSET) +# define SAM_LCDC_PPCFG2 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG2_OFFSET) +# define SAM_LCDC_PPCFG3 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG3_OFFSET) +# define SAM_LCDC_PPCFG4 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG4_OFFSET) +# define SAM_LCDC_PPCFG5 (SAM_LCDC_VBASE+SAM_LCDC_PPCFG5_OFFSET) +#endif + +/* 0x0600-0x08fc Base CLUT Registers 0-255 */ + +#define SAM_LCDC_BASECLUT(n) (SAM_LCDC_VBASE+SAM_LCDC_BASECLUT_OFFSET(n)) + +/* 0x0a00-0x0dfc Overlay 1 CLUT Registers 0-255 */ + +#define SAM_LCDC_OVR1CLUT(n) (SAM_LCDC_VBASE+SAM_LCDC_OVR1CLUT_OFFSET(n)) + +/* 0x0e00-0x11fc Overlay 2 CLUT Registers 0-255 */ + +#define SAM_LCDC_OVR2CLUT(n) (SAM_LCDC_VBASE+SAM_LCDC_OVR2CLUT_OFFSET(n)) + +/* 0x1200-0x15fc High End Overlay CLUT Registers 0-255 */ + +#define SAM_LCDC_HEOCLUT(n) (SAM_LCDC_VBASE+SAM_LCDC_HEOCLUT_OFFSET(n)) + +/* 0x1600-0x19fc Hardware Cursor CLUT Registers 0-255 */ + +#ifdef ATSAMA5D3 +# define SAM_LCDC_HCRCLUT(n) (SAM_LCDC_VBASE+SAM_LCDC_HCRCLUT_OFFSET(n)) +#endif + +/* LCDC Register Bit Definitions ***************************************************/ + +/* LCD Controller Configuration Register 0 */ + +#define LCDC_LCDCFG0_CLKPOL (1 << 0) /* Bit 0: LCD Controller Clock Polarity */ +#define LCDC_LCDCFG0_CLKSEL (1 << 2) /* Bit 2: LCD Controller Clock Source */ +#define LCDC_LCDCFG0_CLKPWMSEL (1 << 3) /* Bit 3: LCD Controller PWM Clock Source */ +#define LCDC_LCDCFG0_CGDISBASE (1 << 8) /* Bit 8: Clock Gating Disable Control Base */ +#define LCDC_LCDCFG0_CGDISOVR1 (1 << 9) /* Bit 9: Clock Gating Disable Control Overlay 1 */ +#define LCDC_LCDCFG0_CGDISOVR2 (1 << 10) /* Bit 10: Clock Gating Disable Control Overlay 2 */ +#define LCDC_LCDCFG0_CGDISHEO (1 << 11) /* Bit 11: Clock Gating Disable Control HE Overlay */ + +#ifdef ATSAMA5D3 +# define LCDC_LCDCFG0_CGDISHCR (1 << 12) /* Bit 12: Clock Gating Disable Control NW Cursor */ +# define LCDC_LCDCFG0_CGDISPP (1 << 13) /* Bit 13: Clock Gating Disable Control PP */ +#endif + +#define LCDC_LCDCFG0_CLKDIV_SHIFT (16) /* Bits 16-23: LCD Controller Clock Divider */ +#define LCDC_LCDCFG0_CLKDIV_MASK (0xff << LCDC_LCDCFG0_CLKDIV_SHIFT) +# define LCDC_LCDCFG0_CLKDIV(n) ((uint32_t)(n) << LCDC_LCDCFG0_CLKDIV_SHIFT) + +/* LCD Controller Configuration Register 1 */ + +#if defined(ATSAMA5D3) +# define LCDC_LCDCFG1_HSPW_SHIFT (0) /* Bits 0-5: Horizontal Sync Pulse Width */ +# define LCDC_LCDCFG1_HSPW_MASK (0x3f << LCDC_LCDCFG1_HSPW_SHIFT) +# define LCDC_LCDCFG1_HSPW(n) ((uint32_t)(n) << LCDC_LCDCFG1_HSPW_SHIFT) +# define LCDC_LCDCFG1_VSPW_SHIFT (16) /* Bits 16-21: Vertical Sync Pulse Width */ +# define LCDC_LCDCFG1_VSPW_MASK (0x3f << LCDC_LCDCFG1_VSPW_SHIFT) +# define LCDC_LCDCFG1_VSPW(n) ((uint32_t)(n) << LCDC_LCDCFG1_VSPW_SHIFT) +#elif defined(ATSAMA5D4) +# define LCDC_LCDCFG1_HSPW_SHIFT (0) /* Bits 0-7: Horizontal Sync Pulse Width */ +# define LCDC_LCDCFG1_HSPW_MASK (0xff << LCDC_LCDCFG1_HSPW_SHIFT) +# define LCDC_LCDCFG1_HSPW(n) ((uint32_t)(n) << LCDC_LCDCFG1_HSPW_SHIFT) +# define LCDC_LCDCFG1_VSPW_SHIFT (16) /* Bits 16-23: Vertical Sync Pulse Width */ +# define LCDC_LCDCFG1_VSPW_MASK (0xff << LCDC_LCDCFG1_VSPW_SHIFT) +# define LCDC_LCDCFG1_VSPW(n) ((uint32_t)(n) << LCDC_LCDCFG1_VSPW_SHIFT) +#endif + +/* LCD Controller Configuration Register 2 */ + +#if defined(ATSAMA5D3) +# define LCDC_LCDCFG2_VFPW_SHIFT (0) /* Bits 0-5: Vertical Front Porch Width */ +# define LCDC_LCDCFG2_VFPW_MASK (0x3f << LCDC_LCDCFG2_VFPW_SHIFT) +# define LCDC_LCDCFG2_VFPW(n) ((uint32_t)(n) << LCDC_LCDCFG2_VFPW_SHIFT) +# define LCDC_LCDCFG2_VBPW_SHIFT (16) /* Bits 16-21: Vertical Back Porch Width */ +# define LCDC_LCDCFG2_VBPW_MASK (0x3f << LCDC_LCDCFG2_VBPW_SHIFT) +# define LCDC_LCDCFG2_VBPW(n) ((uint32_t)(n) << LCDC_LCDCFG2_VBPW_SHIFT) +#elif defined(ATSAMA5D4) +# define LCDC_LCDCFG2_VFPW_SHIFT (0) /* Bits 0-7: Vertical Front Porch Width */ +# define LCDC_LCDCFG2_VFPW_MASK (0xff << LCDC_LCDCFG2_VFPW_SHIFT) +# define LCDC_LCDCFG2_VFPW(n) ((uint32_t)(n) << LCDC_LCDCFG2_VFPW_SHIFT) +# define LCDC_LCDCFG2_VBPW_SHIFT (16) /* Bits 16-23: Vertical Back Porch Width */ +# define LCDC_LCDCFG2_VBPW_MASK (0xff << LCDC_LCDCFG2_VBPW_SHIFT) +# define LCDC_LCDCFG2_VBPW(n) ((uint32_t)(n) << LCDC_LCDCFG2_VBPW_SHIFT) +#endif + +/* LCD Controller Configuration Register 3 */ + +#if defined(ATSAMA5D3) +# define LCDC_LCDCFG3_HFPW_SHIFT (0) /* Bits 0-8: Horizontal Front Porch Width */ +# define LCDC_LCDCFG3_HFPW_MASK (0x1ff << LCDC_LCDCFG3_HFPW_SHIFT) +# define LCDC_LCDCFG3_HFPW(n) ((uint32_t)(n) << LCDC_LCDCFG3_HFPW_SHIFT) +# define LCDC_LCDCFG3_HBPW_SHIFT (16) /* Bits 16-24: Horizontal Back Porch Width */ +# define LCDC_LCDCFG3_HBPW_MASK (0x1ff << LCDC_LCDCFG3_HBPW_SHIFT) +# define LCDC_LCDCFG3_HBPW(n) ((uint32_t)(n) << LCDC_LCDCFG3_HBPW_SHIFT) +#elif defined(ATSAMA5D4) +# define LCDC_LCDCFG3_HFPW_SHIFT (0) /* Bits 0-9: Horizontal Front Porch Width */ +# define LCDC_LCDCFG3_HFPW_MASK (0x3ff << LCDC_LCDCFG3_HFPW_SHIFT) +# define LCDC_LCDCFG3_HFPW(n) ((uint32_t)(n) << LCDC_LCDCFG3_HFPW_SHIFT) +# define LCDC_LCDCFG3_HBPW_SHIFT (16) /* Bits 16-25: Horizontal Back Porch Width */ +# define LCDC_LCDCFG3_HBPW_MASK (0x3ff << LCDC_LCDCFG3_HBPW_SHIFT) +# define LCDC_LCDCFG3_HBPW(n) ((uint32_t)(n) << LCDC_LCDCFG3_HBPW_SHIFT) +#endif + +/* LCD Controller Configuration Register 4 */ + +#define LCDC_LCDCFG4_PPL_SHIFT (0) /* Bits 0-10: Number of Pixels Per Line */ +#define LCDC_LCDCFG4_PPL_MASK (0x7ff << LCDC_LCDCFG4_PPL_SHIFT) +# define LCDC_LCDCFG4_PPL(n) ((uint32_t)(n) << LCDC_LCDCFG4_PPL_SHIFT) +#define LCDC_LCDCFG4_RPF_SHIFT (16) /* Bits 16-26: Number of Active Row Per Frame */ +#define LCDC_LCDCFG4_RPF_MASK (0x7ff << LCDC_LCDCFG4_RPF_SHIFT) +# define LCDC_LCDCFG4_RPF(n) ((uint32_t)(n) << LCDC_LCDCFG4_RPF_SHIFT) + +/* LCD Controller Configuration Register 5 */ + +#define LCDC_LCDCFG5_HSPOL (1 << 0) /* Bit 0: Horizontal Synchronization Pulse Polarity */ +#define LCDC_LCDCFG5_VSPOL (1 << 1) /* Bit 1: VSync Pulse Polarity */ +#define LCDC_LCDCFG5_VSPDLYS (1 << 2) /* Bit 2: VSync Pulse Start */ +#define LCDC_LCDCFG5_VSPDLYE (1 << 3) /* Bit 3: VSync Pulse End */ +#define LCDC_LCDCFG5_DISPPOL (1 << 4) /* Bit 4: Display Signal Polarity */ +#define LCDC_LCDCFG5_DITHER (1 << 6) /* Bit 6: LCDC Dithering */ +#define LCDC_LCDCFG5_DISPDLY (1 << 7) /* Bit 7: LCDC Power Signal Sync */ +#define LCDC_LCDCFG5_MODE_SHIFT (8) /* Bits 8-9: LCDC Output Mode */ +#define LCDC_LCDCFG5_MODE_MASK (3 << LCDC_LCDCFG5_MODE_SHIFT) +# define LCDC_LCDCFG5_MODE_12BPP (0 << LCDC_LCDCFG5_MODE_SHIFT) /* Output mode 12 bits per pixel */ +# define LCDC_LCDCFG5_MODE_16BPP (1 << LCDC_LCDCFG5_MODE_SHIFT) /* Output mode 16 bits per pixel */ +# define LCDC_LCDCFG5_MODE_18BPP (2 << LCDC_LCDCFG5_MODE_SHIFT) /* Output mode 18 bits per pixel */ +# define LCDC_LCDCFG5_MODE_24BPP (3 << LCDC_LCDCFG5_MODE_SHIFT) /* Output mode 24 bits per pixel */ + +#ifdef ATSAMA5D3 +# define LCDC_LCDCFG5_PP (1 << 10) /* Bit 10: Post Processing Enable */ +#endif + +#define LCDC_LCDCFG5_VSPSU (1 << 12) /* Bit 12: LCDC VSync Pulse Setup Configuration */ +#define LCDC_LCDCFG5_VSPHO (1 << 13) /* Bit 13: LCDC VSync Pulse Hold Configuration */ + +#if defined(ATSAMA5D3) +# define LCDC_LCDCFG5_GUARDTIME_SHIFT (16) /* Bits 16-20: LCD DISPLAY Guard Time */ +# define LCDC_LCDCFG5_GUARDTIME_MASK (0x1f << LCDC_LCDCFG5_GUARDTIME_SHIFT) +# define LCDC_LCDCFG5_GUARDTIME(n) ((uint32_t)(n) << LCDC_LCDCFG5_GUARDTIME_SHIFT) +#elif defined(ATSAMA5D4) +# define LCDC_LCDCFG5_GUARDTIME_SHIFT (16) /* Bits 16-23: LCD DISPLAY Guard Time */ +# define LCDC_LCDCFG5_GUARDTIME_MASK (0xff << LCDC_LCDCFG5_GUARDTIME_SHIFT) +# define LCDC_LCDCFG5_GUARDTIME(n) ((uint32_t)(n) << LCDC_LCDCFG5_GUARDTIME_SHIFT) +#endif + +/* LCD Controller Configuration Register 6 */ + +#define LCDC_LCDCFG6_PWMPS_SHIFT (0) /* Bits 0-2: PWM Clock Prescaler */ +#define LCDC_LCDCFG6_PWMPS_MASK (7 << LCDC_LCDCFG6_PWMPS_SHIFT) +# define LCDC_LCDCFG6_PWMPS_DIV1 (0 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock */ +# define LCDC_LCDCFG6_PWMPS_DIV2 (1 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/2 */ +# define LCDC_LCDCFG6_PWMPS_DIV4 (2 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/4 */ +# define LCDC_LCDCFG6_PWMPS_DIV8 (3 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/8 */ +# define LCDC_LCDCFG6_PWMPS_DIV16 (4 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/16 */ +# define LCDC_LCDCFG6_PWMPS_DIV32 (5 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/32 */ +# define LCDC_LCDCFG6_PWMPS_DIV64 (6 << LCDC_LCDCFG6_PWMPS_SHIFT) /* Fcounter = Fpwm_selected_clock/64 */ +#define LCDC_LCDCFG6_PWMPOL (1 << 4) /* Bit 4: LCD Controller PWM Signal Polarity */ +#define LCDC_LCDCFG6_PWMCVAL_SHIFT (8) /* Bits 8-15: LCD Controller PWM Compare Value */ +#define LCDC_LCDCFG6_PWMCVAL_MASK (0xff << LCDC_LCDCFG6_PWMCVAL_SHIFT) +# define LCDC_LCDCFG6_PWMCVAL(n) ((uint32_t)(n) << LCDC_LCDCFG6_PWMCVAL_SHIFT) + +/* LCD Controller Enable Register */ + +#define LCDC_LCDEN_CLK (1 << 0) /* Bit 0: LCDC Pixel Clock Enable */ +#define LCDC_LCDEN_SYNC (1 << 1) /* Bit 1: LCDC H/V Sync Enable */ +#define LCDC_LCDEN_DISP (1 << 2) /* Bit 2: LCDC DISP Signal Enable */ +#define LCDC_LCDEN_PWM (1 << 3) /* Bit 3: LCDC PWM Enable */ + +/* LCD Controller Disable Register */ + +#define LCDC_LCDDIS_CLK (1 << 0) /* Bit 0: LCDC Pixel Clock Disable */ +#define LCDC_LCDDIS_SYNC (1 << 1) /* Bit 1: LCDC H/V Sync Disable */ +#define LCDC_LCDDIS_DISP (1 << 2) /* Bit 2: LCDC DISP Signal Disable */ +#define LCDC_LCDDIS_PWM (1 << 3) /* Bit 3: LCDC PWM Disable */ +#define LCDC_LCDDIS_CLKRST (1 << 8) /* Bit 8: LCDC Clock Reset */ +#define LCDC_LCDDIS_SYNCRST (1 << 9) /* Bit 9: LCDC H/V Sync Reset */ +#define LCDC_LCDDIS_DISPRST (1 << 10) /* Bit 10: LCDC DISP Signal Reset */ +#define LCDC_LCDDIS_PWMRST (1 << 11) /* Bit 11: LCDC PWM Reset */ + +/* LCD Controller Status Register */ + +#define LCDC_LCDSR_CLK (1 << 0) /* Bit 0: Clock Status */ +#define LCDC_LCDSR_LCD (1 << 1) /* Bit 1: LCDC Sync Status */ +#define LCDC_LCDSR_DISP (1 << 2) /* Bit 2: LCDC DISP Signal Status */ +#define LCDC_LCDSR_PWM (1 << 3) /* Bit 3: LCDC PWM Signal Status */ +#define LCDC_LCDSR_SIP (1 << 4) /* Bit 4: Synchronization In Progress */ + +/* LCD Controller Interrupt Enable Register, LCD Controller Interrupt Disable Register, + * LCD Controller Interrupt Mask Register, and LCD Controller Interrupt Status Register + */ + +#define LCDC_LCDINT_SOF (1 << 0) /* Bit 0: Start of Frame Interrupt */ +#define LCDC_LCDINT_DIS (1 << 1) /* Bit 1: LCD Disable Interrupt */ +#define LCDC_LCDINT_DISP (1 << 2) /* Bit 2: Power-up/down Sequence Terminated */ +#define LCDC_LCDINT_FIFOERR (1 << 4) /* Bit 4: Output FIFO Error */ +#define LCDC_LCDINT_BASE (1 << 8) /* Bit 8: Base Layer Raw Interrupt */ +#define LCDC_LCDINT_OVR1 (1 << 9) /* Bit 9: Overlay 1 Raw Interrupt */ +#define LCDC_LCDINT_OVR2 (1 << 10) /* Bit 10: Overlay 2 Raw Interrupt */ +#define LCDC_LCDINT_HEO (1 << 11) /* Bit 11: High End Overlay Raw Interrupt */ + +#if defined(ATSAMA5D3) +# define LCDC_LCDINT_HCR (1 << 12) /* Bit 12: Hardware Cursor Raw Interrupt */ +# define LCDC_LCDINT_PP (1 << 13) /* Bit 13: Post Processing Raw Interrupt */ +# define LCDC_LCDINT_ALL (0x00003f17) +#elif defined(ATSAMA5D4) +# define LCDC_LCDINT_ALL (0x00000f17) +#endif + +#ifdef ATSAMA5D4 +/* LCD Controller Attribute Register */ + +# define LCDC_LCDATTR_BASE (1 << 0) /* Bit 0: Base Layer Update Attribute Register */ +# define LCDC_LCDATTR_OVR1 (1 << 1) /* Bit 1: Overlay 1 Update Attribute Register */ +# define LCDC_LCDATTR_OVR2 (1 << 2) /* Bit 2: Overlay 2 Update Attribute Register */ +# define LCDC_LCDATTR_HEO (1 << 3) /* Bit 3: High-End Overlay Update Attribute Register */ +# define LCDC_LCDATTR_BASEA2Q (1 << 8) /* Bit 8: Base Layer Update Attribute Register */ +# define LCDC_LCDATTR_OVR1A2Q (1 << 9) /* Bit 9: Overlay 1 Update Attribute Register */ +# define LCDC_LCDATTR_OVR2A2Q (1 << 10) /* Bit 10: Overlay 2 Update Attribute Register */ +# define LCDC_LCDATTR_HEOA2Q (1 << 11) /* Bit 11: High-End Overlay Update Attribute Register */ +#endif + +/* Base Layer Channel Enable Register */ + +#define LCDC_BASECHER_CH (1 << 0) /* Bit 0: Channel Enable */ +#define LCDC_BASECHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +#define LCDC_BASECHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* Base Layer Channel Disable Register */ + +#define LCDC_BASECHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +#define LCDC_BASECHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* Base Layer Channel Status Register */ + +#define LCDC_BASECHSR_CH (1 << 0) /* Bit 0: Channel Status */ +#define LCDC_BASECHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +#define LCDC_BASECHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* Base Layer Interrupt Enable Register, Base Layer Interrupt Disable Register, + * Base Layer Interrupt Mask Register, and Base Layer Interrupt Status Register. + */ + +#define LCDC_BASEINT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +#define LCDC_BASEINT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +#define LCDC_BASEINT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +#define LCDC_BASEINT_DONE (1 << 5) /* Bit 5: End of List Detected */ +#define LCDC_BASEINT_OVR (1 << 6) /* Bit 6: Overflow Detected */ + +/* Base DMA Head Register */ + +#define LCDC_BASEHEAD_MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* Base DMA Address Register (32-bit address) */ +/* Base DMA Control Register */ + +#define LCDC_BASECTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_BASECTRL_LFETCH (1 << 1) /* Bit 1: Lookup Table Fetch Enable */ +#define LCDC_BASECTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_BASECTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_BASECTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_BASECTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* Base DMA Next Register (32-bit address) */ + +/* Base Configuration register 0 */ + +#define LCDC_BASECFG0_SIF (1 << 0) /* Bit 0: Source Interface */ +#define LCDC_BASECFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +#define LCDC_BASECFG0_BLEN_MASK (3 << LCDC_BASECFG0_BLEN_SHIFT) +# define LCDC_BASECFG0_BLEN_SINGLE (0 << LCDC_BASECFG0_BLEN_SHIFT) +# define LCDC_BASECFG0_BLEN_INCR4 (1 << LCDC_BASECFG0_BLEN_SHIFT) +# define LCDC_BASECFG0_BLEN_INCR8 (2 << LCDC_BASECFG0_BLEN_SHIFT) +# define LCDC_BASECFG0_BLEN_INCR16 (3 << LCDC_BASECFG0_BLEN_SHIFT) +#define LCDC_BASECFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ + +/* Base Configuration register 1 */ + +#define LCDC_BASECFG1_CLUTEN (1 << 0) /* Bit 0: Color Lookup Table Enable */ +#define LCDC_BASECFG1_RGBMODE_SHIFT (4) /* Bits 4-7: RGB Input Mode Selection */ +#define LCDC_BASECFG1_RGBMODE_MASK (15 << LCDC_BASECFG1_RGBMODE_SHIFT) +# define LCDC_BASECFG1_12BPP_RGB444 (0 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 12 bpp RGB 444 */ +# define LCDC_BASECFG1_16BPP_ARGB4444 (1 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 16 bpp ARGB 4444 */ +# define LCDC_BASECFG1_16BPP_RGBA4444 (2 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 16 bpp RGBA 4444 */ +# define LCDC_BASECFG1_16BPP_RGB565 (3 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 16 bpp RGB 565 */ +# define LCDC_BASECFG1_16BPP_TRGB1555 (4 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 16 bpp TRGB 1555 */ +# define LCDC_BASECFG1_18BPP_RGB666 (5 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 */ +# define LCDC_BASECFG1_18BPP_RGB666P (6 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 PACKED */ +# define LCDC_BASECFG1_19BPP_TRGB1666 (7 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 */ +# define LCDC_BASECFG1_19BPP_TRGBP (8 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 PACKED */ +# define LCDC_BASECFG1_24BPP_RGB888 (9 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 */ +# define LCDC_BASECFG1_24BPP_RGB888P (10 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 PACKED */ +# define LCDC_BASECFG1_25BPP_TRGB1888 (11 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 25 bpp TRGB 1888 */ +# define LCDC_BASECFG1_32BPP_ARGB8888 (12 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 32 bpp ARGB 8888 */ +# define LCDC_BASECFG1_32BPP_RGBA8888 (13 << LCDC_BASECFG1_RGBMODE_SHIFT) /* 32 bpp RGBA 8888 */ +#define LCDC_BASECFG1_CLUTMODE_SHIFT (8) /* Bits 8-9: CLUT Input Mode Selection */ +#define LCDC_BASECFG1_CLUTMODE_MASK (3 << LCDC_BASECFG1_CLUTMODE_SHIFT) +# define LCDC_BASECFG1_CLUTMODE_1BPP (0 << LCDC_BASECFG1_CLUTMODE_SHIFT) /* CLUT input 1 bit per pixel */ +# define LCDC_BASECFG1_CLUTMODE_2BPP (1 << LCDC_BASECFG1_CLUTMODE_SHIFT) /* CLUT input 2 bits per pixel */ +# define LCDC_BASECFG1_CLUTMODE_4BPP (2 << LCDC_BASECFG1_CLUTMODE_SHIFT) /* CLUT input 4 bits per pixel */ +# define LCDC_BASECFG1_CLUTMODE_8BPP (3 << LCDC_BASECFG1_CLUTMODE_SHIFT) /* CLUT input 8 bits per pixel */ + +/* Base Configuration register 2 (32-bit value) */ +/* Base Configuration register 3 */ + +#define LCDC_BASECFG3_BDEF_SHIFT (0) /* Bits 0-7: B Default */ +#define LCDC_BASECFG3_BDEF_MASK (0xff << LCDC_BASECFG3_BDEF_SHIFT) +# define LCDC_BASECFG3_BDEF(n) ((uint32_t)(n) << LCDC_BASECFG3_BDEF_SHIFT) +#define LCDC_BASECFG3_GDEF_SHIFT (8) /* Bits 8-15: G Default */ +#define LCDC_BASECFG3_GDEF_MASK (0xff << LCDC_BASECFG3_GDEF_SHIFT) +# define LCDC_BASECFG3_GDEF(n) ((uint32_t)(n) << LCDC_BASECFG3_GDEF_SHIFT) +#define LCDC_BASECFG3_RDEF_SHIFT (16) /* Bits 16-23: R Default */ +#define LCDC_BASECFG3_RDEF_MASK (0xff << LCDC_BASECFG3_RDEF_SHIFT) +# define LCDC_BASECFG3_RDEF(n) ((uint32_t)(n) << LCDC_BASECFG3_RDEF_SHIFT) + +/* Base Configuration register 4 */ + +#define LCDC_BASECFG4_DMA (1 << 8) /* Bit 8: Use DMA Data Path */ +#define LCDC_BASECFG4_REP (1 << 9) /* Bit 9: Use Replication logic to expand RGB */ +#define LCDC_BASECFG4_DISCEN (1 << 11) /* Bit 11: Discard Area Enable */ + +/* Base Configuration register 5 */ + +#define LCDC_BASECFG5_DISCXPOS_SHIFT (0) /* Bits 0-10: Discard Area H coordinate */ +#define LCDC_BASECFG5_DISCXPOS_MASK (0x7ff << LCDC_BASECFG5_DISCXPOS_SHIFT) +# define LCDC_BASECFG5_DISCXPOS(n) ((uint32_t)(n) << LCDC_BASECFG5_DISCXPOS_SHIFT) +#define LCDC_BASECFG5_DISCYPOS_SHIFT (16) /* Bits 16-26: Discard Area V coordinate */ +#define LCDC_BASECFG5_DISCYPOS_MASK (0x7ff << LCDC_BASECFG5_DISCYPOS_SHIFT) +# define LCDC_BASECFG5_DISCYPOS(n) ((uint32_t)(n) << LCDC_BASECFG5_DISCYPOS_SHIFT) + +/* Base Configuration register 6 */ + +#define LCDC_BASECFG6_DISCXSIZE_SHIFT (0) /* Bits 0-10: Discard Area H Size */ +#define LCDC_BASECFG6_DISCXSIZE_MASK (0x7ff << LCDC_BASECFG6_DISCXSIZE_SHIFT) +# define LCDC_BASECFG6_DISCXSIZE(n) ((uint32_t)(n) << LCDC_BASECFG6_DISCXSIZE_SHIFT) +#define LCDC_BASECFG6_DISCYSIZE_SHIFT (16) /* Bits 16-26: Discard Area V Size */ +#define LCDC_BASECFG6_DISCYSIZE_MASK (0x7ff << LCDC_BASECFG6_DISCYSIZE_SHIFT) +# define LCDC_BASECFG6_DISCYSIZE(n) ((uint32_t)(n) << LCDC_BASECFG6_DISCYSIZE_SHIFT) + +/* Overlay 1 Channel Enable Register */ + +#define LCDC_OVR1CHER_CH (1 << 0) /* Bit 0: Channel Enable */ +#define LCDC_OVR1CHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +#define LCDC_OVR1CHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* Overlay 1 Channel Disable Register */ + +#define LCDC_OVR1CHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +#define LCDC_OVR1CHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* Overlay 1 Channel Status Register */ + +#define LCDC_OVR1CHSR_CH (1 << 0) /* Bit 0: Channel Status */ +#define LCDC_OVR1CHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +#define LCDC_OVR1CHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* Overlay 1 Interrupt Enable Register, Overlay 1 Interrupt Disable Register, + * Overlay 1 Interrupt Mask Register, and Overlay 1 Interrupt Status Register + */ + +#define LCDC_OVR1INT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +#define LCDC_OVR1INT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +#define LCDC_OVR1INT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +#define LCDC_OVR1INT_DONE (1 << 5) /* Bit 5: End of List Detected */ +#define LCDC_OVR1INT_OVR (1 << 6) /* Bit 6: Overflow Detected */ + +/* Overlay 1 DMA Head Register */ + +#define LCDC_OVR1HEAD_MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* Overlay 1 DMA Address Register (32-bit address) */ + +/* Overlay 1 DMA Control Register */ + +#define LCDC_OVR1CTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_OVR1CTRL_LFETCH (1 << 1) /* Bit 1: Lookup Table Fetch Enable */ +#define LCDC_OVR1CTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_OVR1CTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_OVR1CTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_OVR1CTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* Overlay 1 DMA Next Register (32-bit address) */ + +/* Overlay 1 Configuration 0 Register */ + +#define LCDC_OVR1CFG0_SIF (1 << 0) /* Bit 0: Source Interface */ +#define LCDC_OVR1CFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +#define LCDC_OVR1CFG0_BLEN_MASK (3 << LCDC_OVR1CFG0_BLEN_SHIFT) +# define LCDC_OVR1CFG0_BLEN_SINGLE (0 << LCDC_OVR1CFG0_BLEN_SHIFT) +# define LCDC_OVR1CFG0_BLEN_INCR4 (1 << LCDC_OVR1CFG0_BLEN_SHIFT) +# define LCDC_OVR1CFG0_BLEN_INCR8 (2 << LCDC_OVR1CFG0_BLEN_SHIFT) +# define LCDC_OVR1CFG0_BLEN_INCR16 (3 << LCDC_OVR1CFG0_BLEN_SHIFT) +#define LCDC_OVR1CFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ +#define LCDC_OVR1CFG0_ROTDIS (1 << 12) /* Bit 12: Hardware Rotation Optimization Disable */ +#define LCDC_OVR1CFG0_LOCKDIS (1 << 13) /* Bit 13: Hardware Rotation Lock Disable */ + +/* Overlay 1 Configuration 1 Register */ + +#define LCDC_OVR1CFG1_CLUTEN (1 << 0) /* Bit 0: Color Lookup Table Enable */ +#define LCDC_OVR1CFG1_RGBMODE_SHIFT (4) /* Bits 4-7: RGB Input Mode Selection */ +#define LCDC_OVR1CFG1_RGBMODE_MASK (15 << LCDC_OVR1CFG1_RGBMODE_SHIFT) +# define LCDC_OVR1CFG1_12BPP_RGB444 (0 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 12 bpp RGB 444 */ +# define LCDC_OVR1CFG1_16BPP_ARGB4444 (1 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 16 bpp ARGB 4444 */ +# define LCDC_OVR1CFG1_16BPP_RGBA4444 (2 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 16 bpp RGBA 4444 */ +# define LCDC_OVR1CFG1_16BPP_RGB565 (3 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 16 bpp RGB 565 */ +# define LCDC_OVR1CFG1_16BPP_TRGB1555 (4 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 16 bpp TRGB 1555 */ +# define LCDC_OVR1CFG1_18BPP_RGB666 (5 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 */ +# define LCDC_OVR1CFG1_18BPP_RGB666P (6 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 PACKED */ +# define LCDC_OVR1CFG1_19BPP_TRGB1666 (7 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 */ +# define LCDC_OVR1CFG1_19BPP_TRGBP (8 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 PACKED */ +# define LCDC_OVR1CFG1_24BPP_RGB888 (9 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 */ +# define LCDC_OVR1CFG1_24BPP_RGB888P (10 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 PACKED */ +# define LCDC_OVR1CFG1_25BPP_TRGB1888 (11 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 25 bpp TRGB 1888 */ +# define LCDC_OVR1CFG1_32BPP_ARGB8888 (12 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 32 bpp ARGB 8888 */ +# define LCDC_OVR1CFG1_32BPP_RGBA8888 (13 << LCDC_OVR1CFG1_RGBMODE_SHIFT) /* 32 bpp RGBA 8888 */ +#define LCDC_OVR1CFG1_CLUTMODE_SHIFT (8) /* Bits 8-9: CLUT Input Mode Selection */ +#define LCDC_OVR1CFG1_CLUTMODE_MASK (3 << LCDC_OVR1CFG1_CLUTMODE_SHIFT) +# define LCDC_OVR1CFG1_CLUTMODE_1BPP (0 << LCDC_OVR1CFG1_CLUTMODE_SHIFT) /* CLUT input 1 bit per pixel */ +# define LCDC_OVR1CFG1_CLUTMODE_2BPP (1 << LCDC_OVR1CFG1_CLUTMODE_SHIFT) /* CLUT input 2 bits per pixel */ +# define LCDC_OVR1CFG1_CLUTMODE_4BPP (2 << LCDC_OVR1CFG1_CLUTMODE_SHIFT) /* CLUT input 4 bits per pixel */ +# define LCDC_OVR1CFG1_CLUTMODE_8BPP (3 << LCDC_OVR1CFG1_CLUTMODE_SHIFT) /* CLUT input 8 bits per pixel */ + +/* Overlay 1 Configuration 2 Register */ + +#define LCDC_OVR1CFG2_XPOS_SHIFT (0) /* Bits 0-10: Horizontal Window Position */ +#define LCDC_OVR1CFG2_XPOS_MASK (0x7ff << LCDC_OVR1CFG2_XPOS_SHIFT) +# define LCDC_OVR1CFG2_XPOS(n) ((uint32_t)(n) << LCDC_OVR1CFG2_XPOS_SHIFT) +#define LCDC_OVR1CFG2_YPOS_SHIFT (16) /* Bits 16-26: Vertical Window Position */ +#define LCDC_OVR1CFG2_YPOS_MASK (0x7ff << LCDC_OVR1CFG2_YPOS_SHIFT) +# define LCDC_OVR1CFG2_YPOS(n) ((uint32_t)(n) << LCDC_OVR1CFG2_YPOS_SHIFT) + +/* Overlay 1 Configuration 3 Register */ + +#define LCDC_OVR1CFG3_XSIZE_SHIFT (0) /* Bits 0-10: Horizontal Window Size */ +#define LCDC_OVR1CFG3_XSIZE_MASK (0x7ff << LCDC_OVR1CFG3_XSIZE_SHIFT) +# define LCDC_OVR1CFG3_XSIZE(n) ((uint32_t)(n) << LCDC_OVR1CFG3_XSIZE_SHIFT) +#define LCDC_OVR1CFG3_YSIZE_SHIFT (16) /* Bits 16-26: Vertical Window Size */ +#define LCDC_OVR1CFG3_YSIZE_MASK (0x7ff << LCDC_OVR1CFG3_YSIZE_SHIFT) +# define LCDC_OVR1CFG3_YSIZE(n) ((uint32_t)(n) << LCDC_OVR1CFG3_YSIZE_SHIFT) + +/* Overlay 1 Configuration 4 Register (32-bit horizontal stride value) */ +/* Overlay 1 Configuration 5 Register (32-bit pixel stride value) */ + +/* Overlay 1 Configuration 6 Register */ + +#define LCDC_OVR1CFG6_BDEF_SHIFT (0) /* Bits 0-7: B Default */ +#define LCDC_OVR1CFG6_BDEF_MASK (0xff << LCDC_OVR1CFG6_BDEF_SHIFT) +# define LCDC_OVR1CFG6_BDEF(n) ((uint32_t)(n) << LCDC_OVR1CFG6_BDEF_SHIFT) +#define LCDC_OVR1CFG6_GDEF_SHIFT (8) /* Bits 8-15: G Default */ +#define LCDC_OVR1CFG6_GDEF_MASK (0xff << LCDC_OVR1CFG6_GDEF_SHIFT) +# define LCDC_OVR1CFG6_GDEF(n) ((uint32_t)(n) << LCDC_OVR1CFG6_GDEF_SHIFT) +#define LCDC_OVR1CFG6_RDEF_SHIFT (16) /* Bits 16-23: R Default */ +#define LCDC_OVR1CFG6_RDEF_MASK (0xff << LCDC_OVR1CFG6_RDEF_SHIFT) +# define LCDC_OVR1CFG6_RDEF(n) ((uint32_t)(n) << LCDC_OVR1CFG6_RDEF_SHIFT) + +/* Overlay 1 Configuration 7 Register */ + +#define LCDC_OVR1CFG7_BKEY_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key */ +#define LCDC_OVR1CFG7_BKEY_MASK (0xff << LCDC_OVR1CFG7_BKEY_SHIFT) +# define LCDC_OVR1CFG7_BKEY(n) ((uint32_t)(n) << LCDC_OVR1CFG7_BKEY_SHIFT) +#define LCDC_OVR1CFG7_GKEY_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key */ +#define LCDC_OVR1CFG7_GKEY_MASK (0xff << LCDC_OVR1CFG7_GKEY_SHIFT) +# define LCDC_OVR1CFG7_GKEY(n) ((uint32_t)(n) << LCDC_OVR1CFG7_GKEY_SHIFT) +#define LCDC_OVR1CFG7_RKEY_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key */ +#define LCDC_OVR1CFG7_RKEY_MASK (0xff << LCDC_OVR1CFG7_RKEY_SHIFT) +# define LCDC_OVR1CFG7_RKEY(n) ((uint32_t)(n) << LCDC_OVR1CFG7_RKEY_SHIFT) + +/* Overlay 1 Configuration 8 Register */ + +#define LCDC_OVR1CFG8_BMASK_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key Mask */ +#define LCDC_OVR1CFG8_BMASK_MASK (0xff << LCDC_OVR1CFG8_BMASK_SHIFT) +# define LCDC_OVR1CFG8_BMASK(n) ((uint32_t)(n) << LCDC_OVR1CFG8_BMASK_SHIFT) +#define LCDC_OVR1CFG8_GMASK_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key Mask */ +#define LCDC_OVR1CFG8_GMASK_MASK (0xff << LCDC_OVR1CFG8_GMASK_SHIFT) +# define LCDC_OVR1CFG8_GMASK(n) ((uint32_t)(n) << LCDC_OVR1CFG8_GMASK_SHIFT) +#define LCDC_OVR1CFG8_RMASK_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key Mask */ +#define LCDC_OVR1CFG8_RMASK_MASK (0xff << LCDC_OVR1CFG8_RMASK_SHIFT) +# define LCDC_OVR1CFG8_RMASK(n) ((uint32_t)(n) << LCDC_OVR1CFG8_RMASK_SHIFT) + +/* Overlay 1 Configuration 9 Register */ + +#define LCDC_OVR1CFG9_CRKEY (1 << 0) /* Bit 0: Blender Chroma Key Enable */ +#define LCDC_OVR1CFG9_INV (1 << 1) /* Bit 1: Blender Inverted Blender Output Enable */ +#define LCDC_OVR1CFG9_ITER2BL (1 << 2) /* Bit 2: Blender Iterated Color Enable */ +#define LCDC_OVR1CFG9_ITER (1 << 3) /* Bit 3: Blender Use Iterated Color */ +#define LCDC_OVR1CFG9_REVALPHA (1 << 4) /* Bit 4: Blender Reverse Alpha */ +#define LCDC_OVR1CFG9_GAEN (1 << 5) /* Bit 5: Blender Global Alpha Enable */ +#define LCDC_OVR1CFG9_LAEN (1 << 6) /* Bit 6: Blender Local Alpha Enable */ +#define LCDC_OVR1CFG9_OVR (1 << 7) /* Bit 7: Blender Overlay Layer Enable */ +#define LCDC_OVR1CFG9_DMA (1 << 8) /* Bit 8: Blender DMA Layer Enable */ +#define LCDC_OVR1CFG9_REP (1 << 9) /* Bit 9: Use Replication logic to expand RGB color */ +#define LCDC_OVR1CFG9_DSTKEY (1 << 10) /* Bit 10: Destination Chroma Keying */ +#define LCDC_OVR1CFG9_GA_SHIFT (16) /* Bits 16-23: Blender Global Alpha */ +#define LCDC_OVR1CFG9_GA_MASK (0xff << LCDC_OVR1CFG9_GA_SHIFT) +# define LCDC_OVR1CFG9_GA(n) ((uint32_t)(n) << LCDC_OVR1CFG9_GA_SHIFT) + +/* Overlay 2 Channel Enable Register */ + +#define LCDC_OVR2CHER_CH (1 << 0) /* Bit 0: Channel Enable */ +#define LCDC_OVR2CHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +#define LCDC_OVR2CHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* Overlay 2 Channel Disable Register */ + +#define LCDC_OVR2CHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +#define LCDC_OVR2CHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* Overlay 2 Channel Status Register */ + +#define LCDC_OVR2CHSR_CH (1 << 0) /* Bit 0: Channel Status */ +#define LCDC_OVR2CHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +#define LCDC_OVR2CHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* Overlay 2 Interrupt Enable Register, Overlay 2 Interrupt Disable Register, + * Overlay 2 Interrupt Mask Register, and Overlay 2 Interrupt Status Register + */ + +#define LCDC_OVR2INT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +#define LCDC_OVR2INT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +#define LCDC_OVR2INT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +#define LCDC_OVR2INT_DONE (1 << 5) /* Bit 5: End of List Detected */ +#define LCDC_OVR2INT_OVR (1 << 6) /* Bit 6: Overflow Detected */ + +/* Overlay 2 DMA Head Register */ + +#define LCDC_OVR2HEAD_MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* Overlay 2 DMA Address Register (32-bit address) */ + +/* Overlay 2 DMA Control Register */ + +#define LCDC_OVR2CTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_OVR2CTRL_LFETCH (1 << 1) /* Bit 1: Lookup Table Fetch Enable */ +#define LCDC_OVR2CTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_OVR2CTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_OVR2CTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_OVR2CTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* Overlay 2 DMA Next Register (32-bit address) */ + +/* Overlay 2 Configuration 0 Register */ + +#define LCDC_OVR2CFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +#define LCDC_OVR2CFG0_BLEN_MASK (3 << LCDC_OVR2CFG0_BLEN_SHIFT) +# define LCDC_OVR2CFG0_BLEN_SINGLE (0 << LCDC_OVR2CFG0_BLEN_SHIFT) +# define LCDC_OVR2CFG0_BLEN_INCR4 (1 << LCDC_OVR2CFG0_BLEN_SHIFT) +# define LCDC_OVR2CFG0_BLEN_INCR8 (2 << LCDC_OVR2CFG0_BLEN_SHIFT) +# define LCDC_OVR2CFG0_BLEN_INCR16 (3 << LCDC_OVR2CFG0_BLEN_SHIFT) +#define LCDC_OVR2CFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ +#define LCDC_OVR2CFG0_ROTDIS (1 << 12) /* Bit 12: Hardware Rotation Optimization Disable */ +#define LCDC_OVR2CFG0_LOCKDIS (1 << 13) /* Bit 13: Hardware Rotation Lock Disable */ + +/* Overlay 2 Configuration 1 Register */ + +#define LCDC_OVR2CFG1_CLUTEN (1 << 0) /* Bit 0: Color Lookup Table Enable */ +#define LCDC_OVR2CFG1_RGBMODE_SHIFT (4) /* Bits 4-7: RGB Input Mode Selection */ +#define LCDC_OVR2CFG1_RGBMODE_MASK (15 << LCDC_OVR2CFG1_RGBMODE_SHIFT) +# define LCDC_OVR2CFG1_12BPP_RGB444 (0 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 12 bpp RGB 444 */ +# define LCDC_OVR2CFG1_16BPP_ARGB4444 (1 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 16 bpp ARGB 4444 */ +# define LCDC_OVR2CFG1_16BPP_RGBA4444 (2 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 16 bpp RGBA 4444 */ +# define LCDC_OVR2CFG1_16BPP_RGB565 (3 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 16 bpp RGB 565 */ +# define LCDC_OVR2CFG1_16BPP_TRGB1555 (4 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 16 bpp TRGB 1555 */ +# define LCDC_OVR2CFG1_18BPP_RGB666 (5 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 */ +# define LCDC_OVR2CFG1_18BPP_RGB666P (6 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 PACKED */ +# define LCDC_OVR2CFG1_19BPP_TRGB1666 (7 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 */ +# define LCDC_OVR2CFG1_19BPP_TRGBP (8 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 PACKED */ +# define LCDC_OVR2CFG1_24BPP_RGB888 (9 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 */ +# define LCDC_OVR2CFG1_24BPP_RGB888P (10 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 PACKED */ +# define LCDC_OVR2CFG1_25BPP_TRGB1888 (11 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 25 bpp TRGB 1888 */ +# define LCDC_OVR2CFG1_32BPP_ARGB8888 (12 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 32 bpp ARGB 8888 */ +# define LCDC_OVR2CFG1_32BPP_RGBA8888 (13 << LCDC_OVR2CFG1_RGBMODE_SHIFT) /* 32 bpp RGBA 8888 */ +#define LCDC_OVR2CFG1_CLUTMODE_SHIFT (8) /* Bits 8-9: CLUT Input Mode Selection */ +#define LCDC_OVR2CFG1_CLUTMODE_MASK (3 << LCDC_OVR2CFG1_CLUTMODE_SHIFT) +# define LCDC_OVR2CFG1_CLUTMODE_1BPP (0 << LCDC_OVR2CFG1_CLUTMODE_SHIFT) /* CLUT input 1 bit per pixel */ +# define LCDC_OVR2CFG1_CLUTMODE_2BPP (1 << LCDC_OVR2CFG1_CLUTMODE_SHIFT) /* CLUT input 2 bits per pixel */ +# define LCDC_OVR2CFG1_CLUTMODE_4BPP (2 << LCDC_OVR2CFG1_CLUTMODE_SHIFT) /* CLUT input 4 bits per pixel */ +# define LCDC_OVR2CFG1_CLUTMODE_8BPP (3 << LCDC_OVR2CFG1_CLUTMODE_SHIFT) /* CLUT input 8 bits per pixel */ + +/* Overlay 2 Configuration 2 Register */ + +#define LCDC_OVR2CFG2_XPOS_SHIFT (0) /* Bits 0-10: Horizontal Window Position */ +#define LCDC_OVR2CFG2_XPOS_MASK (0x7ff << LCDC_OVR2CFG2_XPOS_SHIFT) +# define LCDC_OVR2CFG2_XPOS(n) ((uint32_t)(n) << LCDC_OVR2CFG2_XPOS_SHIFT) +#define LCDC_OVR2CFG2_YPOS_SHIFT (16) /* Bits 16-26: Vertical Window Position */ +#define LCDC_OVR2CFG2_YPOS_MASK (0x7ff << LCDC_OVR2CFG2_YPOS_SHIFT) +# define LCDC_OVR2CFG2_YPOS(n) ((uint32_t)(n) << LCDC_OVR2CFG2_YPOS_SHIFT) + +/* Overlay 2 Configuration 3 Register */ + +#define LCDC_OVR2CFG3_XSIZE_SHIFT (0) /* Bits 0-10: Horizontal Window Size */ +#define LCDC_OVR2CFG3_XSIZE_MASK (0x7ff << LCDC_OVR2CFG3_XSIZE_SHIFT) +# define LCDC_OVR2CFG3_XSIZE(n) ((uint32_t)(n) << LCDC_OVR2CFG3_XSIZE_SHIFT) +#define LCDC_OVR2CFG3_YSIZE_SHIFT (16) /* Bits 16-26: Vertical Window Size */ +#define LCDC_OVR2CFG3_YSIZE_MASK (0x7ff << LCDC_OVR2CFG3_YSIZE_SHIFT) +# define LCDC_OVR2CFG3_YSIZE(n) ((uint32_t)(n) << LCDC_OVR2CFG3_YSIZE_SHIFT) + +/* Overlay 2 Configuration 4 Register (32-bit horizontal stride value) */ +/* Overlay 2 Configuration 5 Register (32-bit pixel stride value)*/ + +/* Overlay 2 Configuration 6 Register */ + +#define LCDC_OVR2CFG6_BDEF_SHIFT (0) /* Bits 0-7: B Default */ +#define LCDC_OVR2CFG6_BDEF_MASK (0xff << LCDC_OVR2CFG6_BDEF_SHIFT) +# define LCDC_OVR2CFG6_BDEF(n) ((uint32_t)(n) << LCDC_OVR2CFG6_BDEF_SHIFT) +#define LCDC_OVR2CFG6_GDEF_SHIFT (8) /* Bits 8-15: G Default */ +#define LCDC_OVR2CFG6_GDEF_MASK (0xff << LCDC_OVR2CFG6_GDEF_SHIFT) +# define LCDC_OVR2CFG6_GDEF(n) ((uint32_t)(n) << LCDC_OVR2CFG6_GDEF_SHIFT) +#define LCDC_OVR2CFG6_RDEF_SHIFT (16) /* Bits 16-23: R Default */ +#define LCDC_OVR2CFG6_RDEF_MASK (0xff << LCDC_OVR2CFG6_RDEF_SHIFT) +# define LCDC_OVR2CFG6_RDEF(n) ((uint32_t)(n) << LCDC_OVR2CFG6_RDEF_SHIFT) + +/* Overlay 2 Configuration 7 Register */ + +#define LCDC_OVR2CFG7_BKEY_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key */ +#define LCDC_OVR2CFG7_BKEY_MASK (0xff << LCDC_OVR2CFG7_BKEY_SHIFT) +# define LCDC_OVR2CFG7_BKEY(n) ((uint32_t)(n) << LCDC_OVR2CFG7_BKEY_SHIFT) +#define LCDC_OVR2CFG7_GKEY_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key */ +#define LCDC_OVR2CFG7_GKEY_MASK (0xff << LCDC_OVR2CFG7_GKEY_SHIFT) +# define LCDC_OVR2CFG7_GKEY(n) ((uint32_t)(n) << LCDC_OVR2CFG7_GKEY_SHIFT) +#define LCDC_OVR2CFG7_RKEY_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key */ +#define LCDC_OVR2CFG7_RKEY_MASK (0xff << LCDC_OVR2CFG7_RKEY_SHIFT) +# define LCDC_OVR2CFG7_RKEY(n) ((uint32_t)(n) << LCDC_OVR2CFG7_RKEY_SHIFT) + +/* Overlay 2 Configuration 8 Register */ + +#define LCDC_OVR2CFG8_BMASK_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key Mask */ +#define LCDC_OVR2CFG8_BMASK_MASK (0xff << LCDC_OVR2CFG8_BMASK_SHIFT) +# define LCDC_OVR2CFG8_BMASK(n) ((uint32_t)(n) << LCDC_OVR2CFG8_BMASK_SHIFT) +#define LCDC_OVR2CFG8_GMASK_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key Mask */ +#define LCDC_OVR2CFG8_GMASK_MASK (0xff << LCDC_OVR2CFG8_GMASK_SHIFT) +# define LCDC_OVR2CFG8_GMASK(n) ((uint32_t)(n) << LCDC_OVR2CFG8_GMASK_SHIFT) +#define LCDC_OVR2CFG8_RMASK_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key Mask */ +#define LCDC_OVR2CFG8_RMASK_MASK (0xff << LCDC_OVR2CFG8_RMASK_SHIFT) +# define LCDC_OVR2CFG8_RMASK(n) ((uint32_t)(n) << LCDC_OVR2CFG8_RMASK_SHIFT) + +/* Overlay 2 Configuration 9 Register */ + +#define LCDC_OVR2CFG9_CRKEY (1 << 0) /* Bit 0: Blender Chroma Key Enable */ +#define LCDC_OVR2CFG9_INV (1 << 1) /* Bit 1: Blender Inverted Blender Output Enable */ +#define LCDC_OVR2CFG9_ITER2BL (1 << 2) /* Bit 2: Blender Iterated Color Enable */ +#define LCDC_OVR2CFG9_ITER (1 << 3) /* Bit 3: Blender Use Iterated Color */ +#define LCDC_OVR2CFG9_REVALPHA (1 << 4) /* Bit 4: Blender Reverse Alpha */ +#define LCDC_OVR2CFG9_GAEN (1 << 5) /* Bit 5: Blender Global Alpha Enable */ +#define LCDC_OVR2CFG9_LAEN (1 << 6) /* Bit 6: Blender Local Alpha Enable */ +#define LCDC_OVR2CFG9_OVR (1 << 7) /* Bit 7: Blender Overlay Layer Enable */ +#define LCDC_OVR2CFG9_DMA (1 << 8) /* Bit 8: Blender DMA Layer Enable */ +#define LCDC_OVR2CFG9_REP (1 << 9) /* Bit 9: Use Replication logic to expand RGB color */ +#define LCDC_OVR2CFG9_DSTKEY (1 << 10) /* Bit 10: Destination Chroma Keying */ +#define LCDC_OVR2CFG9_GA_SHIFT (16) /* Bits 16-23: Blender Global Alpha */ +#define LCDC_OVR2CFG9_GA_MASK (0xff << LCDC_OVR2CFG9_GA_SHIFT) +# define LCDC_OVR2CFG9_GA(n) ((uint32_t)(n) << LCDC_OVR2CFG9_GA_SHIFT) + +/* High-End Overlay Channel Enable Register */ + +#define LCDC_HEOCHER_CH (1 << 0) /* Bit 0: Channel Enable */ +#define LCDC_HEOCHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +#define LCDC_HEOCHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* High-End Overlay Channel Disable Register */ + +#define LCDC_HEOCHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +#define LCDC_HEOCHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* High-End Overlay Channel Status Register */ + +#define LCDC_HEOCHSR_CH (1 << 0) /* Bit 0: Channel Status */ +#define LCDC_HEOCHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +#define LCDC_HEOCHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* High-End Overlay Interrupt Enable Register, High-End Overlay Interrupt Disable Register, + * High-End Overlay Interrupt Mask Register, and High-End Overlay Interrupt Status Register + */ + +#define LCDC_HEOINT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +#define LCDC_HEOINT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +#define LCDC_HEOINT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +#define LCDC_HEOINT_DONE (1 << 5) /* Bit 5: End of List Detected */ +#define LCDC_HEOINT_OVR (1 << 6) /* Bit 6: Overflow Detected */ +#define LCDC_HEOINT_UDMA (1 << 10) /* Bit 10: End of DMA Transfer (U or UV Chrominance) */ +#define LCDC_HEOINT_UDSCR (1 << 11) /* Bit 11: DMA Descriptor Loaded (U or UV Chrominance) */ +#define LCDC_HEOINT_UADD (1 << 12) /* Bit 12: Head Descriptor Loaded (U or UV Chrominance) */ +#define LCDC_HEOINT_UDONE (1 << 13) /* Bit 13: End of List Detected (U or UV Chrominance) */ +#define LCDC_HEOINT_UOVR (1 << 14) /* Bit 14: Overflow Detected (U or UV Chrominance) */ +#define LCDC_HEOINT_VDMA (1 << 18) /* Bit 18: End of DMA Transfer (V Chrominance) */ +#define LCDC_HEOINT_VDSCR (1 << 19) /* Bit 19: DMA Descriptor Loaded (V Chrominance) */ +#define LCDC_HEOINT_VADD (1 << 20) /* Bit 20: Head Descriptor Loaded (V Chrominance) */ +#define LCDC_HEOINT_VDONE (1 << 21) /* Bit 21: End of List Detected (V Chrominance) */ +#define LCDC_HEOINT_VOVR (1 << 22) /* Bit 22: Overflow Detected (V Chrominance) */ + +/* High-End Overlay DMA Head Register */ + +#define LCDC_HEOHEAD_MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* High-End Overlay DMA Address Register (32-bit address) */ + +/* High-End Overlay DMA Control Register */ + +#define LCDC_HEOCTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_HEOCTRL_LFETCH (1 << 1) /* Bit 1: Lookup Table Fetch Enable */ +#define LCDC_HEOCTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_HEOCTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_HEOCTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_HEOCTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* High-End Overlay DMA Next Register (32-bit address) */ +/* High-End Overlay U-UV DMA Head Register (32-bit address) */ +/* High-End Overlay U-UV DMA Address Register (32-bit address) */ + +/* High-End Overlay U-UV DMA Control Register */ + +#define LCDC_HEOUCTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_HEOUCTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_HEOUCTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_HEOUCTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_HEOUCTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* High-End Overlay U-UV DMA Next Register (32-bit address) */ +/* High-End Overlay V DMA Head Register (32-bit address) */ +/* High-End Overlay V DMA Address Register )32-bit address) */ + +/* High-End Overlay V DMA Control Register */ + +#define LCDC_HEOVCTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +#define LCDC_HEOVCTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +#define LCDC_HEOVCTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +#define LCDC_HEOVCTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +#define LCDC_HEOVCTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* High-End Overlay VDMA Next Register (32-bit address) */ + +/* High-End Overlay Configuration Register 0 */ + +#define LCDC_HEOCFG0_SIF (1 << 0) /* Bit 0: Source Interface */ +#define LCDC_HEOCFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +#define LCDC_HEOCFG0_BLEN_MASK (3 << LCDC_HEOCFG0_BLEN_SHIFT) +# define LCDC_HEOCFG0_BLEN_SINGLE (0 << LCDC_HEOCFG0_BLEN_SHIFT) +# define LCDC_HEOCFG0_BLEN_INCR4 (1 << LCDC_HEOCFG0_BLEN_SHIFT) +# define LCDC_HEOCFG0_BLEN_INCR8 (2 << LCDC_HEOCFG0_BLEN_SHIFT) +# define LCDC_HEOCFG0_BLEN_INCR16 (3 << LCDC_HEOCFG0_BLEN_SHIFT) +#define LCDC_HEOCFG0_BLENUV_SHIFT (6) /* Bits 6-7: AHB Burst Length for U-V channel */ +#define LCDC_HEOCFG0_BLENUV_MASK (3 << LCDC_HEOCFG0_BLENUV_SHIFT) +# define LCDC_HEOCFG0_BLENUV_SINGLE (0 << LCDC_HEOCFG0_BLENUV_SHIFT) +# define LCDC_HEOCFG0_BLENUV_INCR4 (1 << LCDC_HEOCFG0_BLENUV_SHIFT) +# define LCDC_HEOCFG0_BLENUV_INCR8 (2 << LCDC_HEOCFG0_BLENUV_SHIFT) +# define LCDC_HEOCFG0_BLENUV_INCR16 (3 << LCDC_HEOCFG0_BLENUV_SHIFT) +#define LCDC_HEOCFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ +#define LCDC_HEOCFG0_ROTDIS (1 << 12) /* Bit 12: Hardware Rotation Optimization Disable */ +#define LCDC_HEOCFG0_LOCKDIS (1 << 13) /* Bit 13: Hardware Rotation Lock Disable */ + +/* High-End Overlay Configuration Register 1 */ + +#define LCDC_HEOCFG1_CLUTEN (1 << 0) /* Bit 0: Color Lookup Table Enable */ +#define LCDC_HEOCFG1_YUVEN (1 << 1) /* Bit 1: YUV Color Space Enable */ +#define LCDC_HEOCFG1_RGBMODE_SHIFT (4) /* Bits 4-7: RGB Input Mode Selection */ +#define LCDC_HEOCFG1_RGBMODE_MASK (15 << LCDC_HEOCFG1_RGBMODE_SHIFT) +# define LCDC_HEOCFG1_12BPP_RGB444 (0 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 12 bpp RGB 444 */ +# define LCDC_HEOCFG1_16BPP_ARGB4444 (1 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 16 bpp ARGB 4444 */ +# define LCDC_HEOCFG1_16BPP_RGBA4444 (2 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 16 bpp RGBA 4444 */ +# define LCDC_HEOCFG1_16BPP_RGB565 (3 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 16 bpp RGB 565 */ +# define LCDC_HEOCFG1_16BPP_TRGB1555 (4 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 16 bpp TRGB 1555 */ +# define LCDC_HEOCFG1_18BPP_RGB666 (5 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 */ +# define LCDC_HEOCFG1_18BPP_RGB666P (6 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 PACKED */ +# define LCDC_HEOCFG1_19BPP_TRGB1666 (7 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 */ +# define LCDC_HEOCFG1_19BPP_TRGBP (8 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 PACKED */ +# define LCDC_HEOCFG1_24BPP_RGB888 (9 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 */ +# define LCDC_HEOCFG1_24BPP_RGB888P (10 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 PACKED */ +# define LCDC_HEOCFG1_25BPP_TRGB1888 (11 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 25 bpp TRGB 1888 */ +# define LCDC_HEOCFG1_32BPP_ARGB8888 (12 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 32 bpp ARGB 8888 */ +# define LCDC_HEOCFG1_32BPP_RGBA8888 (13 << LCDC_HEOCFG1_RGBMODE_SHIFT) /* 32 bpp RGBA 8888 */ +#define LCDC_HEOCFG1_CLUTMODE_SHIFT (8) /* Bits 8-9: CLUT Input Mode Selection */ +#define LCDC_HEOCFG1_CLUTMODE_MASK (3 << LCDC_HEOCFG1_CLUTMODE_SHIFT) +# define LCDC_HEOCFG1_CLUTMODE_1BPP (0 << LCDC_HEOCFG1_CLUTMODE_SHIFT) /* CLUT input 1 bit per pixel */ +# define LCDC_HEOCFG1_CLUTMODE_2BPP (1 << LCDC_HEOCFG1_CLUTMODE_SHIFT) /* CLUT input 2 bits per pixel */ +# define LCDC_HEOCFG1_CLUTMODE_4BPP (2 << LCDC_HEOCFG1_CLUTMODE_SHIFT) /* CLUT input 4 bits per pixel */ +# define LCDC_HEOCFG1_CLUTMODE_8BPP (3 << LCDC_HEOCFG1_CLUTMODE_SHIFT) /* CLUT input 8 bits per pixel */ +#define LCDC_HEOCFG1_YUVMODE_SHIFT (12) /* Bits 12-15: YUV Mode Input Selection */ +#define LCDC_HEOCFG1_YUVMODE_MASK (15 << LCDC_HEOCFG1_YUVMODE_SHIFT) +# define LCDC_HEOCFG1_32BPP_AYCBCR (0 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 32 bpp AYCbCr 444 */ +# define LCDC_HEOCFG1_16BPP_YCBCR_MODE0 (1 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Cr(n)Y(n+1)Cb(n)Y(n) 422 */ +# define LCDC_HEOCFG1_16BPP_YCBCR_MODE1 (2 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Y(n+1)Cr(n)Y(n)Cb(n) 422 */ +# define LCDC_HEOCFG1_16BPP_YCBCR_MODE2 (3 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Cb(n)Y(+1)Cr(n)Y(n) 422 */ +# define LCDC_HEOCFG1_16BPP_YCBCR_MODE3 (4 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Y(n+1)Cb(n)Y(n)Cr(n) 422 */ +# define LCDC_HEOCFG1_16BPP_YCBCR_SEMIPLANAR (5 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Semiplanar 422 YCbCr */ +# define LCDC_HEOCFG1_16BPP_YCBCR_PLANAR (6 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 16 bpp Planar 422 YCbCr */ +# define LCDC_HEOCFG1_12BPP_YCBCR_SEMIPLANAR (7 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 12 bpp Semiplanar 420 YCbCr */ +# define LCDC_HEOCFG1_12BPP_YCBCR_PLANAR (8 << LCDC_HEOCFG1_YUVMODE_SHIFT) /* 12 bpp Planar 420 YCbCr */ +#define LCDC_HEOCFG1_YUV422ROT (1 << 16) /* Bit 16: YUV 4:2:2 Rotation */ +#define LCDC_HEOCFG1_YUV422SWP (1 << 17) /* Bit 17: YUV 4:2:2 SWAP */ +#define LCDC_HEOCFG1_DSCALEOPT (1 << 20) /* Bit 20: Down Scaling Bandwidth Optimization */ + +/* High-End Overlay Configuration Register 2 */ + +#define LCDC_HEOCFG2_XPOS_SHIFT (0) /* Bits 0-10: Horizontal Window Position */ +#define LCDC_HEOCFG2_XPOS_MASK (0x7ff << LCDC_HEOCFG2_XPOS_SHIFT) +# define LCDC_HEOCFG2_XPOS(n) ((uint32_t)(n) << LCDC_HEOCFG2_XPOS_SHIFT) +#define LCDC_HEOCFG2_YPOS_SHIFT (16) /* Bits 16-26: Vertical Window Position */ +#define LCDC_HEOCFG2_YPOS_MASK (0x7ff << LCDC_HEOCFG2_YPOS_SHIFT) +# define LCDC_HEOCFG2_YPOS(n) ((uint32_t)(n) << LCDC_HEOCFG2_YPOS_SHIFT) + +/* High-End Overlay Configuration Register 3 */ + +#define LCDC_HEOCFG3_XSIZE_SHIFT (0) /* Bits 0-10: Horizontal Window Size */ +#define LCDC_HEOCFG3_XSIZE_MASK (0x7ff << LCDC_HEOCFG3_XSIZE_SHIFT) +# define LCDC_HEOCFG3_XSIZE(n) ((uint32_t)(n) << LCDC_HEOCFG3_XSIZE_SHIFT) +#define LCDC_HEOCFG3_YSIZE_SHIFT (16) /* Bits 16-26: Vertical Window Size */ +#define LCDC_HEOCFG3_YSIZE_MASK (0x7ff << LCDC_HEOCFG3_YSIZE_SHIFT) +# define LCDC_HEOCFG3_YSIZE(n) ((uint32_t)(n) << LCDC_HEOCFG3_YSIZE_SHIFT) + +/* High-End Overlay Configuration Register 4 */ + +#define LCDC_HEOCFG4_XMEMSIZE_SHIFT (0) /* Bits 0-10: Horizontal image Size in Memory */ +#define LCDC_HEOCFG4_XMEMSIZE_MASK (0x7ff << LCDC_HEOCFG4_XMEMSIZE_SHIFT) +# define LCDC_HEOCFG4_XMEMSIZE(n) ((uint32_t)(n) << LCDC_HEOCFG4_XMEMSIZE_SHIFT) +#define LCDC_HEOCFG4_YMEMSIZE_SHIFT (16) /* Bits 16-26: Vertical image Size in Memory */ +#define LCDC_HEOCFG4_YMEMSIZE_MASK (0x7ff << LCDC_HEOCFG4_YMEMSIZE_SHIFT) +# define LCDC_HEOCFG4_YMEMSIZE(n) ((uint32_t)(n) << LCDC_HEOCFG4_YMEMSIZE_SHIFT) + +/* High-End Overlay Configuration Register 5 (32-bit horizontal stride value) */ +/* High-End Overlay Configuration Register 6 (32-bit pixel stride value) */ +/* High-End Overlay Configuration Register 7 (32-bit horizontal stride value) */ +/* High-End Overlay Configuration Register 8 (32-bit pixel stride value) */ + +/* High-End Overlay Configuration Register 9 */ + +#define LCDC_HEOCFG9_BDEF_SHIFT (0) /* Bits 0-7: B Default */ +#define LCDC_HEOCFG9_BDEF_MASK (0xff << LCDC_HEOCFG9_BDEF_SHIFT) +# define LCDC_HEOCFG9_BDEF(n) ((uint32_t)(n) << LCDC_HEOCFG9_BDEF_SHIFT) +#define LCDC_HEOCFG9_GDEF_SHIFT (8) /* Bits 8-15: G Default */ +#define LCDC_HEOCFG9_GDEF_MASK (0xff << LCDC_HEOCFG9_GDEF_SHIFT) +# define LCDC_HEOCFG9_GDEF(n) ((uint32_t)(n) << LCDC_HEOCFG9_GDEF_SHIFT) +#define LCDC_HEOCFG9_RDEF_SHIFT (16) /* Bits 16-23: R Default */ +#define LCDC_HEOCFG9_RDEF_MASK (0xff << LCDC_HEOCFG9_RDEF_SHIFT) +# define LCDC_HEOCFG9_RDEF(n) ((uint32_t)(n) << LCDC_HEOCFG9_RDEF_SHIFT) + +/* High-End Overlay Configuration Register 10 */ + +#define LCDC_HEOCFG10_BKEY_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key */ +#define LCDC_HEOCFG10_BKEY_MASK (0xff << LCDC_HEOCFG10_BKEY_SHIFT) +# define LCDC_HEOCFG10_BKEY(n) ((uint32_t)(n) << LCDC_HEOCFG10_BKEY_SHIFT) +#define LCDC_HEOCFG10_GKEY_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key */ +#define LCDC_HEOCFG10_GKEY_MASK (0xff << LCDC_HEOCFG10_GKEY_SHIFT) +# define LCDC_HEOCFG10_GKEY(n) ((uint32_t)(n) << LCDC_HEOCFG10_GKEY_SHIFT) +#define LCDC_HEOCFG10_RKEY_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key */ +#define LCDC_HEOCFG10_RKEY_MASK (0xff << LCDC_HEOCFG10_RKEY_SHIFT) +# define LCDC_HEOCFG10_RKEY(n) ((uint32_t)(n) << LCDC_HEOCFG10_RKEY_SHIFT) + +/* High-End Overlay Configuration Register 11 */ + +#define LCDC_HEOCFG11_BMASK_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key Mask */ +#define LCDC_HEOCFG11_BMASK_MASK (0xff << LCDC_HEOCFG11_BMASK_SHIFT) +# define LCDC_HEOCFG11_BMASK(n) ((uint32_t)(n) << LCDC_HEOCFG11_BMASK_SHIFT) +#define LCDC_HEOCFG11_GMASK_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key Mask */ +#define LCDC_HEOCFG11_GMASK_MASK (0xff << LCDC_HEOCFG11_GMASK_SHIFT) +# define LCDC_HEOCFG11_GMASK(n) ((uint32_t)(n) << LCDC_HEOCFG11_GMASK_SHIFT) +#define LCDC_HEOCFG11_RMASK_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key Mask */ +#define LCDC_HEOCFG11_RMASK_MASK (0xff << LCDC_HEOCFG11_RMASK_SHIFT) +# define LCDC_HEOCFG11_RMASK(n) ((uint32_t)(n) << LCDC_HEOCFG11_RMASK_SHIFT) + +/* High-End Overlay Configuration Register 12 */ + +#define LCDC_HEOCFG12_CRKEY (1 << 0) /* Bit 0: Blender Chroma Key Enable */ +#define LCDC_HEOCFG12_INV (1 << 1) /* Bit 1: Blender Inverted Blender Output Enable */ +#define LCDC_HEOCFG12_ITER2BL (1 << 2) /* Bit 2: Blender Iterated Color Enable */ +#define LCDC_HEOCFG12_ITER (1 << 3) /* Bit 3: Blender Use Iterated Color */ +#define LCDC_HEOCFG12_REVALPHA (1 << 4) /* Bit 4: Blender Reverse Alpha */ +#define LCDC_HEOCFG12_GAEN (1 << 5) /* Bit 5: Blender Global Alpha Enable */ +#define LCDC_HEOCFG12_LAEN (1 << 6) /* Bit 6: Blender Local Alpha Enable */ +#define LCDC_HEOCFG12_OVR (1 << 7) /* Bit 7: Blender Overlay Layer Enable */ +#define LCDC_HEOCFG12_DMA (1 << 8) /* Bit 8: Blender DMA Layer Enable */ +#define LCDC_HEOCFG12_REP (1 << 9) /* Bit 9: Use Replication logic to expand RGB color */ +#define LCDC_HEOCFG12_DSTKEY (1 << 10) /* Bit 10: Destination Chroma Keying */ +#define LCDC_HEOCFG12_VIDPRI (1 << 12) /* Bit 12: Video Priority */ +#define LCDC_HEOCFG12_GA_SHIFT (16) /* Bits 16-23: Blender Global Alpha */ +#define LCDC_HEOCFG12_GA_MASK (0xff << LCDC_HEOCFG12_GA_SHIFT) +# define LCDC_HEOCFG12_GA(n) ((uint32_t)(n) << LCDC_HEOCFG12_GA_SHIFT) + +/* High-End Overlay Configuration Register 13 */ + +#define LCDC_HEOCFG13_XFACTOR_SHIFT (0) /* Bits 0-13: Horizontal Scaling Factor */ +#define LCDC_HEOCFG13_XFACTOR_MASK (0x3fff << LCDC_HEOCFG13_XFACTOR_SHIFT) +# define LCDC_HEOCFG13_XFACTOR(n) ((uint32_t)(n) << LCDC_HEOCFG13_XFACTOR_SHIFT) +#define LCDC_HEOCFG13_YFACTOR_SHIFT (16) /* Bits 16-29: Vertical Scaling Factor */ +#define LCDC_HEOCFG13_YFACTOR_MASK (0x3fff << LCDC_HEOCFG13_YFACTOR_SHIFT) +# define LCDC_HEOCFG13_YFACTOR(n) ((uint32_t)(n) << LCDC_HEOCFG13_YFACTOR_SHIFT) +#define LCDC_HEOCFG13_SCALEN (1 << 31) /* Bit 31: Hardware Scaler Enable */ + +/* High-End Overlay Configuration Register 14 */ + +#define LCDC_HEOCFG14_CSCRY_SHIFT (0) /* Bits 0-9: Color Space Conversion Y coeff for R */ +#define LCDC_HEOCFG14_CSCRY_MASK (0x3ff << LCDC_HEOCFG14_CSCRY_SHIFT) +# define LCDC_HEOCFG14_CSCRY(n) ((uint32_t)(n) << LCDC_HEOCFG14_CSCRY_SHIFT) +#define LCDC_HEOCFG14_CSCRU_SHIFT (10) /* Bits 10-19: Color Space Conversion U coeff for R */ +#define LCDC_HEOCFG14_CSCRU_MASK (0x3ff << LCDC_HEOCFG14_CSCRU_SHIFT) +# define LCDC_HEOCFG14_CSCRU(n) ((uint32_t)(n) << LCDC_HEOCFG14_CSCRU_SHIFT) +#define LCDC_HEOCFG14_CSCRV_SHIFT (20) /* Bits 20-29: Color Space Conversion V coeff for R */ +#define LCDC_HEOCFG14_CSCRV_MASK (0x3ff << LCDC_HEOCFG14_CSCRV_SHIFT) +# define LCDC_HEOCFG14_CSCRV(n) ((uint32_t)(n) << LCDC_HEOCFG14_CSCRV_SHIFT) +#define LCDC_HEOCFG14_CSCYOFF (1 << 30) /* Bit 30: Color Space Conversion Offset */ + +/* High-End Overlay Configuration Register 15 */ + +#define LCDC_HEOCFG15_CSCGY_SHIFT (0) /* Bits 0-9: Color Space Conversion Y coeff for G */ +#define LCDC_HEOCFG15_CSCGY_MASK (0x3ff << LCDC_HEOCFG15_CSCGY_SHIFT) +# define LCDC_HEOCFG15_CSCGY(n) ((uint32_t)(n) << LCDC_HEOCFG15_CSCGY_SHIFT) +#define LCDC_HEOCFG15_CSCGU_SHIFT (10) /* Bits 10-19: Color Space Conversion U coeff for G */ +#define LCDC_HEOCFG15_CSCGU_MASK (0x3ff << LCDC_HEOCFG15_CSCGU_SHIFT) +# define LCDC_HEOCFG15_CSCGU(n) ((uint32_t)(n) << LCDC_HEOCFG15_CSCGU_SHIFT) +#define LCDC_HEOCFG15_CSCGV_SHIFT (20) /* Bits 20-29: Color Space Conversion V coeff for G */ +#define LCDC_HEOCFG15_CSCGV_MASK (0x3ff << LCDC_HEOCFG15_CSCGV_SHIFT) +# define LCDC_HEOCFG15_CSCGV(n) ((uint32_t)(n) << LCDC_HEOCFG15_CSCGV_SHIFT) +#define LCDC_HEOCFG15_CSCUOFF (1 << 30) /* Bit 30: Color Space Conversion Offset */ + +/* High-End Overlay Configuration Register 16 */ + +#define LCDC_HEOCFG16_CSCBY_SHIFT (0) /* Bits 0-9: Color Space Conversion Y coeff for B */ +#define LCDC_HEOCFG16_CSCBY_MASK (0x3ff << LCDC_HEOCFG16_CSCBY_SHIFT) +# define LCDC_HEOCFG16_CSCBY(n) ((uint32_t)(n) << LCDC_HEOCFG16_CSCBY_SHIFT) +#define LCDC_HEOCFG16_CSCBU_SHIFT (10) /* Bits 10-19: Color Space Conversion U coeff for B */ +#define LCDC_HEOCFG16_CSCBU_MASK (0x3ff << LCDC_HEOCFG16_CSCBU_SHIFT) +# define LCDC_HEOCFG16_CSCBU(n) ((uint32_t)(n) << LCDC_HEOCFG16_CSCBU_SHIFT) +#define LCDC_HEOCFG16_CSCBV_SHIFT (20) /* Bits 20-29: Color Space Conversion V coeff for B */ +#define LCDC_HEOCFG16_CSCBV_MASK (0x3ff << LCDC_HEOCFG16_CSCBV_SHIFT) +# define LCDC_HEOCFG16_CSCBV(n) ((uint32_t)(n) << LCDC_HEOCFG16_CSCBV_SHIFT) +#define LCDC_HEOCFG16_CSCVOFF (1 << 30) /* Bit 30: Color Space Conversion Offset */ + +/* High-End Overlay Configuration Register 17 */ + +#define LCDC_HEOCFG17_XPHI0COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 0 tap 0 */ +#define LCDC_HEOCFG17_XPHI0COEFF0_MASK (0xff << LCDC_HEOCFG17_XPHI0COEFF0_SHIFT) +# define LCDC_HEOCFG17_XPHI0COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG17_XPHI0COEFF0_SHIFT) +#define LCDC_HEOCFG17_XPHI0COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 0 tap 1 */ +#define LCDC_HEOCFG17_XPHI0COEFF1_MASK (0xff << LCDC_HEOCFG17_XPHI0COEFF1_SHIFT) +# define LCDC_HEOCFG17_XPHI0COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG17_XPHI0COEFF1_SHIFT) +#define LCDC_HEOCFG17_XPHI0COEFF2_SHIFT (16) /* Bits 16-23: Horizontal Coefficient for phase 0 tap 2 */ +#define LCDC_HEOCFG17_XPHI0COEFF2_MASK (0xff << LCDC_HEOCFG17_XPHI0COEFF2_SHIFT) +# define LCDC_HEOCFG17_XPHI0COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG17_XPHI0COEFF2_SHIFT) +#define LCDC_HEOCFG17_XPHI0COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 0 tap 3 */ +#define LCDC_HEOCFG17_XPHI0COEFF3_MASK (0xff << LCDC_HEOCFG17_XPHI0COEFF3_SHIFT) +# define LCDC_HEOCFG17_XPHI0COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG17_XPHI0COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 18 */ + +#define LCDC_HEOCFG18_XPHI0COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 0 tap 4 */ +#define LCDC_HEOCFG18_XPHI0COEFF4_MASK (0xff << LCDC_HEOCFG18_XPHI0COEFF4_SHIFT) +# define LCDC_HEOCFG18_XPHI0COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG18_XPHI0COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 19 */ + +#define LCDC_HEOCFG19_XPHI1COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 1 tap 0 */ +#define LCDC_HEOCFG19_XPHI1COEFF0_MASK (0xff << LCDC_HEOCFG19_XPHI1COEFF0_SHIFT) +# define LCDC_HEOCFG19_XPHI1COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG19_XPHI1COEFF0_SHIFT) +#define LCDC_HEOCFG19_XPHI1COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 1 tap 1 */ +#define LCDC_HEOCFG19_XPHI1COEFF1_MASK (0xff << LCDC_HEOCFG19_XPHI1COEFF1_SHIFT) +# define LCDC_HEOCFG19_XPHI1COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG19_XPHI1COEFF1_SHIFT) +#define LCDC_HEOCFG19_XPHI1COEFF2_SHIFT (16) /* Bits 16-23: Horizontal Coefficient for phase 1 tap 2 */ +#define LCDC_HEOCFG19_XPHI1COEFF2_MASK (0xff << LCDC_HEOCFG19_XPHI1COEFF2_SHIFT) +# define LCDC_HEOCFG19_XPHI1COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG19_XPHI1COEFF2_SHIFT) +#define LCDC_HEOCFG19_XPHI1COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 1 tap 3 */ +#define LCDC_HEOCFG19_XPHI1COEFF3_MASK (0xff << LCDC_HEOCFG19_XPHI1COEFF3_SHIFT) +# define LCDC_HEOCFG19_XPHI1COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG19_XPHI1COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 20 */ + +#define LCDC_HEOCFG20_XPHI1COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 1 tap 4 */ +#define LCDC_HEOCFG20_XPHI1COEFF4_MASK (0xff << LCDC_HEOCFG20_XPHI1COEFF4_SHIFT) +# define LCDC_HEOCFG20_XPHI1COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG20_XPHI1COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 21 */ + +#define LCDC_HEOCFG21_XPHI2COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 2 tap 0 */ +#define LCDC_HEOCFG21_XPHI2COEFF0_MASK (0xff << LCDC_HEOCFG21_XPHI2COEFF0_SHIFT) +# define LCDC_HEOCFG21_XPHI2COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG21_XPHI2COEFF0_SHIFT) +#define LCDC_HEOCFG21_XPHI2COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 2 tap 1 */ +#define LCDC_HEOCFG21_XPHI2COEFF1_MASK (0xff << LCDC_HEOCFG21_XPHI2COEFF1_SHIFT) +# define LCDC_HEOCFG21_XPHI2COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG21_XPHI2COEFF1_SHIFT) +#define LCDC_HEOCFG21_XPHI2COEFF2_SHIFT (16) /* Bits 16-23: Horizontal Coefficient for phase 2 tap 2 */ +#define LCDC_HEOCFG21_XPHI2COEFF2_MASK (0xff << LCDC_HEOCFG21_XPHI2COEFF2_SHIFT) +# define LCDC_HEOCFG21_XPHI2COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG21_XPHI2COEFF2_SHIFT) +#define LCDC_HEOCFG21_XPHI2COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 2 tap 3 */ +#define LCDC_HEOCFG21_XPHI2COEFF3_MASK (0xff << LCDC_HEOCFG21_XPHI2COEFF3_SHIFT) +# define LCDC_HEOCFG21_XPHI2COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG21_XPHI2COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 22 */ + +#define LCDC_HEOCFG22_XPHI2COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 2 tap 4 */ +#define LCDC_HEOCFG22_XPHI2COEFF4_MASK (0xff << LCDC_HEOCFG22_XPHI2COEFF4_SHIFT) +# define LCDC_HEOCFG22_XPHI2COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG22_XPHI2COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 23 */ + +#define LCDC_HEOCFG23_XPHI3COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 3 tap 0 */ +#define LCDC_HEOCFG23_XPHI3COEFF0_MASK (0xff << LCDC_HEOCFG23_XPHI3COEFF0_SHIFT) +# define LCDC_HEOCFG23_XPHI3COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG23_XPHI3COEFF0_SHIFT) +#define LCDC_HEOCFG23_XPHI3COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 3 tap 1 */ +#define LCDC_HEOCFG23_XPHI3COEFF1_MASK (0xff << LCDC_HEOCFG23_XPHI3COEFF1_SHIFT) +# define LCDC_HEOCFG23_XPHI3COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG23_XPHI3COEFF1_SHIFT) +#define LCDC_HEOCFG23_XPHI3COEFF2_SHIFT (16) /* Bits 16-23: Horizontal Coefficient for phase 3 tap 2 */ +#define LCDC_HEOCFG23_XPHI3COEFF2_MASK (0xff << LCDC_HEOCFG23_XPHI3COEFF2_SHIFT) +# define LCDC_HEOCFG23_XPHI3COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG23_XPHI3COEFF2_SHIFT) +#define LCDC_HEOCFG23_XPHI3COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 3 tap 3 */ +#define LCDC_HEOCFG23_XPHI3COEFF3_MASK (0xff << LCDC_HEOCFG23_XPHI3COEFF3_SHIFT) +# define LCDC_HEOCFG23_XPHI3COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG23_XPHI3COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 24 */ + +#define LCDC_HEOCFG24_XPHI3COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 3 tap 4 */ +#define LCDC_HEOCFG24_XPHI3COEFF4_MASK (0xff << LCDC_HEOCFG24_XPHI3COEFF4_SHIFT) +# define LCDC_HEOCFG24_XPHI3COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG24_XPHI3COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 25 */ + +#define LCDC_HEOCFG25_XPHI4COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 4 tap 0 */ +#define LCDC_HEOCFG25_XPHI4COEFF0_MASK (0xff << LCDC_HEOCFG25_XPHI4COEFF0_SHIFT) +# define LCDC_HEOCFG25_XPHI4COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG25_XPHI4COEFF0_SHIFT) +#define LCDC_HEOCFG25_XPHI4COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 4 tap 1 */ +#define LCDC_HEOCFG25_XPHI4COEFF1_MASK (0xff << LCDC_HEOCFG25_XPHI4COEFF1_SHIFT) +# define LCDC_HEOCFG25_XPHI4COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG25_XPHI4COEFF1_SHIFT) +#define LCDC_HEOCFG25_XPHI4COEFF2_SHIFT (16) /* Bits 16-25: Horizontal Coefficient for phase 4 tap 2 */ +#define LCDC_HEOCFG25_XPHI4COEFF2_MASK (0xff << LCDC_HEOCFG25_XPHI4COEFF2_SHIFT) +# define LCDC_HEOCFG25_XPHI4COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG25_XPHI4COEFF2_SHIFT) +#define LCDC_HEOCFG25_XPHI4COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 4 tap 3 */ +#define LCDC_HEOCFG25_XPHI4COEFF3_MASK (0xff << LCDC_HEOCFG25_XPHI4COEFF3_SHIFT) +# define LCDC_HEOCFG25_XPHI4COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG25_XPHI4COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 26 */ + +#define LCDC_HEOCFG26_XPHI4COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 4 tap 4 */ +#define LCDC_HEOCFG26_XPHI4COEFF4_MASK (0xff << LCDC_HEOCFG26_XPHI4COEFF4_SHIFT) +# define LCDC_HEOCFG26_XPHI4COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG26_XPHI4COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 27 */ + +#define LCDC_HEOCFG27_XPHI5COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 5 tap 0 */ +#define LCDC_HEOCFG27_XPHI5COEFF0_MASK (0xff << LCDC_HEOCFG27_XPHI5COEFF0_SHIFT) +# define LCDC_HEOCFG27_XPHI5COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG27_XPHI5COEFF0_SHIFT) +#define LCDC_HEOCFG27_XPHI5COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 5 tap 1 */ +#define LCDC_HEOCFG27_XPHI5COEFF1_MASK (0xff << LCDC_HEOCFG27_XPHI5COEFF1_SHIFT) +# define LCDC_HEOCFG27_XPHI5COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG27_XPHI5COEFF1_SHIFT) +#define LCDC_HEOCFG27_XPHI5COEFF2_SHIFT (16) /* Bits 16-25: Horizontal Coefficient for phase 5 tap 2 */ +#define LCDC_HEOCFG27_XPHI5COEFF2_MASK (0xff << LCDC_HEOCFG27_XPHI5COEFF2_SHIFT) +# define LCDC_HEOCFG27_XPHI5COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG27_XPHI5COEFF2_SHIFT) +#define LCDC_HEOCFG27_XPHI5COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 5 tap 3 */ +#define LCDC_HEOCFG27_XPHI5COEFF3_MASK (0xff << LCDC_HEOCFG27_XPHI5COEFF3_SHIFT) +# define LCDC_HEOCFG27_XPHI5COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG27_XPHI5COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 28 */ + +#define LCDC_HEOCFG28_XPHI5COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 5 tap 4 */ +#define LCDC_HEOCFG28_XPHI5COEFF4_MASK (0xff << LCDC_HEOCFG28_XPHI5COEFF4_SHIFT) +# define LCDC_HEOCFG28_XPHI5COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG28_XPHI5COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 29 */ + +#define LCDC_HEOCFG29_XPHI6COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 6 tap 0 */ +#define LCDC_HEOCFG29_XPHI6COEFF0_MASK (0xff << LCDC_HEOCFG29_XPHI6COEFF0_SHIFT) +# define LCDC_HEOCFG29_XPHI6COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG29_XPHI6COEFF0_SHIFT) +#define LCDC_HEOCFG29_XPHI6COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 6 tap 1 */ +#define LCDC_HEOCFG29_XPHI6COEFF1_MASK (0xff << LCDC_HEOCFG29_XPHI6COEFF1_SHIFT) +# define LCDC_HEOCFG29_XPHI6COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG29_XPHI6COEFF1_SHIFT) +#define LCDC_HEOCFG29_XPHI6COEFF2_SHIFT (16) /* Bits 16-25: Horizontal Coefficient for phase 6 tap 2 */ +#define LCDC_HEOCFG29_XPHI6COEFF2_MASK (0xff << LCDC_HEOCFG29_XPHI6COEFF2_SHIFT) +# define LCDC_HEOCFG29_XPHI6COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG29_XPHI6COEFF2_SHIFT) +#define LCDC_HEOCFG29_XPHI6COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 6 tap 3 */ +#define LCDC_HEOCFG29_XPHI6COEFF3_MASK (0xff << LCDC_HEOCFG29_XPHI6COEFF3_SHIFT) +# define LCDC_HEOCFG29_XPHI6COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG29_XPHI6COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 30 */ + +#define LCDC_HEOCFG30_XPHI6COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 6 tap 4 */ +#define LCDC_HEOCFG30_XPHI6COEFF4_MASK (0xff << LCDC_HEOCFG30_XPHI6COEFF4_SHIFT) +# define LCDC_HEOCFG30_XPHI6COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG30_XPHI6COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 31 */ + +#define LCDC_HEOCFG31_XPHI7COEFF0_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 7 tap 0 */ +#define LCDC_HEOCFG31_XPHI7COEFF0_MASK (0xff << LCDC_HEOCFG31_XPHI7COEFF0_SHIFT) +# define LCDC_HEOCFG31_XPHI7COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG31_XPHI7COEFF0_SHIFT) +#define LCDC_HEOCFG31_XPHI7COEFF1_SHIFT (8) /* Bits 8-15: Horizontal Coefficient for phase 7 tap 1 */ +#define LCDC_HEOCFG31_XPHI7COEFF1_MASK (0xff << LCDC_HEOCFG31_XPHI7COEFF1_SHIFT) +# define LCDC_HEOCFG31_XPHI7COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG31_XPHI7COEFF1_SHIFT) +#define LCDC_HEOCFG31_XPHI7COEFF2_SHIFT (16) /* Bits 16-25: Horizontal Coefficient for phase 7 tap 2 */ +#define LCDC_HEOCFG31_XPHI7COEFF2_MASK (0xff << LCDC_HEOCFG31_XPHI7COEFF2_SHIFT) +# define LCDC_HEOCFG31_XPHI7COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG31_XPHI7COEFF2_SHIFT) +#define LCDC_HEOCFG31_XPHI7COEFF3_SHIFT (24) /* Bits 24-31: Horizontal Coefficient for phase 7 tap 3 */ +#define LCDC_HEOCFG31_XPHI7COEFF3_MASK (0xff << LCDC_HEOCFG31_XPHI7COEFF3_SHIFT) +# define LCDC_HEOCFG31_XPHI7COEFF3(n) ((uint32_t)(n) << LCDC_HEOCFG31_XPHI7COEFF3_SHIFT) + +/* High-End Overlay Configuration Register 32 */ + +#define LCDC_HEOCFG30_XPHI7COEFF4_SHIFT (0) /* Bits 0-7: Horizontal Coefficient for phase 7 tap 4 */ +#define LCDC_HEOCFG30_XPHI7COEFF4_MASK (0xff << LCDC_HEOCFG30_XPHI7COEFF4_SHIFT) +# define LCDC_HEOCFG30_XPHI7COEFF4(n) ((uint32_t)(n) << LCDC_HEOCFG30_XPHI7COEFF4_SHIFT) + +/* High-End Overlay Configuration Register 33 */ + +#define LCDC_HEOCFG33_YPHI0COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 0 tap 0 */ +#define LCDC_HEOCFG33_YPHI0COEFF0_MASK (0xff << LCDC_HEOCFG33_YPHI0COEFF0_SHIFT) +# define LCDC_HEOCFG33_YPHI0COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG33_YPHI0COEFF0_SHIFT) +#define LCDC_HEOCFG33_YPHI0COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 0 tap 1 */ +#define LCDC_HEOCFG33_YPHI0COEFF1_MASK (0xff << LCDC_HEOCFG33_YPHI0COEFF1_SHIFT) +# define LCDC_HEOCFG33_YPHI0COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG33_YPHI0COEFF1_SHIFT) +#define LCDC_HEOCFG33_YPHI0COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 0 tap 2 */ +#define LCDC_HEOCFG33_YPHI0COEFF2_MASK (0xff << LCDC_HEOCFG33_YPHI0COEFF2_SHIFT) +# define LCDC_HEOCFG33_YPHI0COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG33_YPHI0COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 34 */ + +#define LCDC_HEOCFG34_YPHI1COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 1 tap 0 */ +#define LCDC_HEOCFG34_YPHI1COEFF0_MASK (0xff << LCDC_HEOCFG34_YPHI1COEFF0_SHIFT) +# define LCDC_HEOCFG34_YPHI1COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG34_YPHI1COEFF0_SHIFT) +#define LCDC_HEOCFG34_YPHI1COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 1 tap 1 */ +#define LCDC_HEOCFG34_YPHI1COEFF1_MASK (0xff << LCDC_HEOCFG34_YPHI1COEFF1_SHIFT) +# define LCDC_HEOCFG34_YPHI1COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG34_YPHI1COEFF1_SHIFT) +#define LCDC_HEOCFG34_YPHI1COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 1 tap 2 */ +#define LCDC_HEOCFG34_YPHI1COEFF2_MASK (0xff << LCDC_HEOCFG34_YPHI1COEFF2_SHIFT) +# define LCDC_HEOCFG34_YPHI1COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG34_YPHI1COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 35 */ + +#define LCDC_HEOCFG35_YPHI2COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 2 tap 0 */ +#define LCDC_HEOCFG35_YPHI2COEFF0_MASK (0xff << LCDC_HEOCFG35_YPHI2COEFF0_SHIFT) +# define LCDC_HEOCFG35_YPHI2COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG35_YPHI2COEFF0_SHIFT) +#define LCDC_HEOCFG35_YPHI2COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 2 tap 1 */ +#define LCDC_HEOCFG35_YPHI2COEFF1_MASK (0xff << LCDC_HEOCFG35_YPHI2COEFF1_SHIFT) +# define LCDC_HEOCFG35_YPHI2COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG35_YPHI2COEFF1_SHIFT) +#define LCDC_HEOCFG35_YPHI2COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 2 tap 2 */ +#define LCDC_HEOCFG35_YPHI2COEFF2_MASK (0xff << LCDC_HEOCFG35_YPHI2COEFF2_SHIFT) +# define LCDC_HEOCFG35_YPHI2COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG35_YPHI2COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 36 */ + +#define LCDC_HEOCFG36_YPHI3COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 3 tap 0 */ +#define LCDC_HEOCFG36_YPHI3COEFF0_MASK (0xff << LCDC_HEOCFG36_YPHI3COEFF0_SHIFT) +# define LCDC_HEOCFG36_YPHI3COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG36_YPHI3COEFF0_SHIFT) +#define LCDC_HEOCFG36_YPHI3COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 3 tap 1 */ +#define LCDC_HEOCFG36_YPHI3COEFF1_MASK (0xff << LCDC_HEOCFG36_YPHI3COEFF1_SHIFT) +# define LCDC_HEOCFG36_YPHI3COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG36_YPHI3COEFF1_SHIFT) +#define LCDC_HEOCFG36_YPHI3COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 3 tap 2 */ +#define LCDC_HEOCFG36_YPHI3COEFF2_MASK (0xff << LCDC_HEOCFG36_YPHI3COEFF2_SHIFT) +# define LCDC_HEOCFG36_YPHI3COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG36_YPHI3COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 37 */ + +#define LCDC_HEOCFG37_YPHI4COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 4 tap 0 */ +#define LCDC_HEOCFG37_YPHI4COEFF0_MASK (0xff << LCDC_HEOCFG37_YPHI4COEFF0_SHIFT) +# define LCDC_HEOCFG37_YPHI4COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG37_YPHI4COEFF0_SHIFT) +#define LCDC_HEOCFG37_YPHI4COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 4 tap 1 */ +#define LCDC_HEOCFG37_YPHI4COEFF1_MASK (0xff << LCDC_HEOCFG37_YPHI4COEFF1_SHIFT) +# define LCDC_HEOCFG37_YPHI4COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG37_YPHI4COEFF1_SHIFT) +#define LCDC_HEOCFG37_YPHI4COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 4 tap 2 */ +#define LCDC_HEOCFG37_YPHI4COEFF2_MASK (0xff << LCDC_HEOCFG37_YPHI4COEFF2_SHIFT) +# define LCDC_HEOCFG37_YPHI4COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG37_YPHI4COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 38 */ + +#define LCDC_HEOCFG38_YPHI5COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 5 tap 0 */ +#define LCDC_HEOCFG38_YPHI5COEFF0_MASK (0xff << LCDC_HEOCFG38_YPHI5COEFF0_SHIFT) +# define LCDC_HEOCFG38_YPHI5COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG38_YPHI5COEFF0_SHIFT) +#define LCDC_HEOCFG38_YPHI5COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 5 tap 1 */ +#define LCDC_HEOCFG38_YPHI5COEFF1_MASK (0xff << LCDC_HEOCFG38_YPHI5COEFF1_SHIFT) +# define LCDC_HEOCFG38_YPHI5COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG38_YPHI5COEFF1_SHIFT) +#define LCDC_HEOCFG38_YPHI5COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 5 tap 2 */ +#define LCDC_HEOCFG38_YPHI5COEFF2_MASK (0xff << LCDC_HEOCFG38_YPHI5COEFF2_SHIFT) +# define LCDC_HEOCFG38_YPHI5COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG38_YPHI5COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 39 */ + +#define LCDC_HEOCFG39_YPHI6COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 6 tap 0 */ +#define LCDC_HEOCFG39_YPHI6COEFF0_MASK (0xff << LCDC_HEOCFG39_YPHI6COEFF0_SHIFT) +# define LCDC_HEOCFG39_YPHI6COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG39_YPHI6COEFF0_SHIFT) +#define LCDC_HEOCFG39_YPHI6COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 6 tap 1 */ +#define LCDC_HEOCFG39_YPHI6COEFF1_MASK (0xff << LCDC_HEOCFG39_YPHI6COEFF1_SHIFT) +# define LCDC_HEOCFG39_YPHI6COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG39_YPHI6COEFF1_SHIFT) +#define LCDC_HEOCFG39_YPHI6COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 6 tap 2 */ +#define LCDC_HEOCFG39_YPHI6COEFF2_MASK (0xff << LCDC_HEOCFG39_YPHI6COEFF2_SHIFT) +# define LCDC_HEOCFG39_YPHI6COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG39_YPHI6COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 40 */ + +#define LCDC_HEOCFG40_YPHI7COEFF0_SHIFT (0) /* Bits 0-7: Vertical Coefficient for phase 7 tap 0 */ +#define LCDC_HEOCFG40_YPHI7COEFF0_MASK (0xff << LCDC_HEOCFG40_YPHI7COEFF0_SHIFT) +# define LCDC_HEOCFG40_YPHI7COEFF0(n) ((uint32_t)(n) << LCDC_HEOCFG40_YPHI7COEFF0_SHIFT) +#define LCDC_HEOCFG40_YPHI7COEFF1_SHIFT (8) /* Bits 8-15: Vertical Coefficient for phase 7 tap 1 */ +#define LCDC_HEOCFG40_YPHI7COEFF1_MASK (0xff << LCDC_HEOCFG40_YPHI7COEFF1_SHIFT) +# define LCDC_HEOCFG40_YPHI7COEFF1(n) ((uint32_t)(n) << LCDC_HEOCFG40_YPHI7COEFF1_SHIFT) +#define LCDC_HEOCFG40_YPHI7COEFF2_SHIFT (16) /* Bits 16-23: Vertical Coefficient for phase 7 tap 2 */ +#define LCDC_HEOCFG40_YPHI7COEFF2_MASK (0xff << LCDC_HEOCFG40_YPHI7COEFF2_SHIFT) +# define LCDC_HEOCFG40_YPHI7COEFF2(n) ((uint32_t)(n) << LCDC_HEOCFG40_YPHI7COEFF2_SHIFT) + +/* High-End Overlay Configuration Register 41 */ + +#define LCDC_HEOCFG41_XPHIDEF_SHIFT (0) /* Bits 0-2: Horizontal Filter Phase Offset */ +#define LCDC_HEOCFG41_XPHIDEF_MASK (7 << LCDC_HEOCFG41_XPHIDEF_SHIFT) +# define LCDC_HEOCFG41_XPHIDEF(n) ((uint32_t)(n) << LCDC_HEOCFG41_XPHIDEF_SHIFT) +#define LCDC_HEOCFG41_YPHIDEF_SHIFT (16) /* Bits 16-18: Vertical Filter Phase Offset */ +#define LCDC_HEOCFG41_YPHIDEF_MASK (7 << LCDC_HEOCFG41_YPHIDEF_SHIFT) +# define LCDC_HEOCFG41_YPHIDEF(n) ((uint32_t)(n) << LCDC_HEOCFG41_YPHIDEF_SHIFT) + +#ifdef ATSAMA5D3 +/* Hardware Cursor Channel Enable Register */ + +# define LCDC_HCRCHER_CH (1 << 0) /* Bit 0: Channel Enable */ +# define LCDC_HCRCHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +# define LCDC_HCRCHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* Hardware Cursor Channel Disable Register */ + +# define LCDC_HCRCHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +# define LCDC_HCRCHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* Hardware Cursor Channel Status Register */ + +# define LCDC_HCRCHSR_CH (1 << 0) /* Bit 0: Channel Status */ +# define LCDC_HCRCHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +# define LCDC_HCRCHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* Hardware Cursor Interrupt Enable Register, Hardware Cursor Interrupt Disable Register, + * Hardware Cursor Interrupt Mask Register, and Hardware Cursor Interrupt Status Register + */ + +# define LCDC_HCRINT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +# define LCDC_HCRINT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +# define LCDC_HCRINT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +# define LCDC_HCRINT_DONE (1 << 5) /* Bit 5: End of List Detected */ +# define LCDC_HCRINT_OVR (1 << 6) /* Bit 6: Overflow Detected */ + +/* Hardware Cursor DMA Head Register */ + +# define LCDC_HCRHEAD_MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* Hardware cursor DMA Address Register (32-bit address) */ + +/* Hardware Cursor DMA Control Register */ + +# define LCDC_HCRCTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +# define LCDC_HCRCTRL_LFETCH (1 << 1) /* Bit 1: Lookup Table Fetch Enable */ +# define LCDC_HCRCTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +# define LCDC_HCRCTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +# define LCDC_HCRCTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +# define LCDC_HCRCTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* Hardware Cursor DMA Next Register (32-bit address) */ + +/* Hardware Cursor Configuration 0 Register */ + +# define LCDC_HCRCFG0_SIF (1 << 0) /* Bit 0: Source Interface */ +# define LCDC_HCRCFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +# define LCDC_HCRCFG0_BLEN_MASK (3 << LCDC_HCRCFG0_BLEN_SHIFT) +# define LCDC_HCRCFG0_BLEN_SINGLE (0 << LCDC_HCRCFG0_BLEN_SHIFT) +# define LCDC_HCRCFG0_BLEN_INCR4 (1 << LCDC_HCRCFG0_BLEN_SHIFT) +# define LCDC_HCRCFG0_BLEN_INCR8 (2 << LCDC_HCRCFG0_BLEN_SHIFT) +# define LCDC_HCRCFG0_BLEN_INCR16 (3 << LCDC_HCRCFG0_BLEN_SHIFT) +# define LCDC_HCRCFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ + +/* Hardware Cursor Configuration 1 Register */ + +# define LCDC_HCRCFG1_CLUTEN (1 << 0) /* Bit 0: Color Lookup Table Enable */ +# define LCDC_HCRCFG1_RGBMODE_SHIFT (4) /* Bits 4-7: RGB Input Mode Selection */ +# define LCDC_HCRCFG1_RGBMODE_MASK (15 << LCDC_HCRCFG1_RGBMODE_SHIFT) +# define LCDC_HCRCFG1_12BPP_RGB444 (0 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 12 bpp RGB 444 */ +# define LCDC_HCRCFG1_16BPP_ARGB4444 (1 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 16 bpp ARGB 4444 */ +# define LCDC_HCRCFG1_16BPP_RGBA4444 (2 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 16 bpp RGBA 4444 */ +# define LCDC_HCRCFG1_16BPP_RGB565 (3 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 16 bpp RGB 565 */ +# define LCDC_HCRCFG1_16BPP_TRGB1555 (4 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 16 bpp TRGB 1555 */ +# define LCDC_HCRCFG1_18BPP_RGB666 (5 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 */ +# define LCDC_HCRCFG1_18BPP_RGB666P (6 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 18 bpp RGB 666 PACKED */ +# define LCDC_HCRCFG1_19BPP_TRGB1666 (7 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 */ +# define LCDC_HCRCFG1_19BPP_TRGBP (8 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 19 bpp TRGB 1666 PACKED */ +# define LCDC_HCRCFG1_24BPP_RGB888 (9 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 */ +# define LCDC_HCRCFG1_24BPP_RGB888P (10 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 24 bpp RGB 888 PACKED */ +# define LCDC_HCRCFG1_25BPP_TRGB1888 (11 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 25 bpp TRGB 1888 */ +# define LCDC_HCRCFG1_32BPP_ARGB8888 (12 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 32 bpp ARGB 8888 */ +# define LCDC_HCRCFG1_32BPP_RGBA8888 (13 << LCDC_HCRCFG1_RGBMODE_SHIFT) /* 32 bpp RGBA 8888 */ +# define LCDC_HCRCFG1_CLUTMODE_SHIFT (8) /* Bits 8-9: CLUT Input Mode Selection */ +# define LCDC_HCRCFG1_CLUTMODE_MASK (3 << LCDC_HCRCFG1_CLUTMODE_SHIFT) +# define LCDC_HCRCFG1_CLUTMODE_1BPP (0 << LCDC_HCRCFG1_CLUTMODE_SHIFT) /* CLUT input 1 bit per pixel */ +# define LCDC_HCRCFG1_CLUTMODE_2BPP (1 << LCDC_HCRCFG1_CLUTMODE_SHIFT) /* CLUT input 2 bits per pixel */ +# define LCDC_HCRCFG1_CLUTMODE_4BPP (2 << LCDC_HCRCFG1_CLUTMODE_SHIFT) /* CLUT input 4 bits per pixel */ +# define LCDC_HCRCFG1_CLUTMODE_8BPP (3 << LCDC_HCRCFG1_CLUTMODE_SHIFT) /* CLUT input 8 bits per pixel */ + +/* Hardware Cursor Configuration 2 Register */ + +# define LCDC_HCRCFG2_XPOS_SHIFT (0) /* Bits 0-10: Horizontal Window Position */ +# define LCDC_HCRCFG2_XPOS_MASK (0x7ff << LCDC_HCRCFG2_XPOS_SHIFT) +# define LCDC_HCRCFG2_XPOS(n) ((uint32_t)(n) << LCDC_HCRCFG2_XPOS_SHIFT) +# define LCDC_HCRCFG2_YPOS_SHIFT (16) /* Bits 16-26: Vertical Window Position */ +# define LCDC_HCRCFG2_YPOS_MASK (0x7ff << LCDC_HCRCFG2_YPOS_SHIFT) +# define LCDC_HCRCFG2_YPOS(n) ((uint32_t)(n) << LCDC_HCRCFG2_YPOS_SHIFT) + +/* Hardware Cursor Configuration 3 Register */ + +# define LCDC_HCRCFG3_XSIZE_SHIFT (0) /* Bits 0-10: Horizontal Window Size */ +# define LCDC_HCRCFG3_XSIZE_MASK (0x7ff << LCDC_HCRCFG3_XSIZE_SHIFT) +# define LCDC_HCRCFG3_XSIZE(n) ((uint32_t)(n) << LCDC_HCRCFG3_XSIZE_SHIFT) +# define LCDC_HCRCFG3_YSIZE_SHIFT (16) /* Bits 16-26: Vertical Window Size */ +# define LCDC_HCRCFG3_YSIZE_MASK (0x7ff << LCDC_HCRCFG3_YSIZE_SHIFT) +# define LCDC_HCRCFG3_YSIZE(n) ((uint32_t)(n) << LCDC_HCRCFG3_YSIZE_SHIFT) + +/* Hardware Cursor Configuration 4 Register (32-bit horizontal stride value) */ + +/* Hardware Cursor Configuration 6 Register */ + +# define LCDC_HCRCFG6_BDEF_SHIFT (0) /* Bits 0-7: B Default */ +# define LCDC_HCRCFG6_BDEF_MASK (0xff << LCDC_HCRCFG6_BDEF_SHIFT) +# define LCDC_HCRCFG6_BDEF(n) ((uint32_t)(n) << LCDC_HCRCFG6_BDEF_SHIFT) +# define LCDC_HCRCFG6_GDEF_SHIFT (8) /* Bits 8-15: G Default */ +# define LCDC_HCRCFG6_GDEF_MASK (0xff << LCDC_HCRCFG6_GDEF_SHIFT) +# define LCDC_HCRCFG6_GDEF(n) ((uint32_t)(n) << LCDC_HCRCFG6_GDEF_SHIFT) +# define LCDC_HCRCFG6_RDEF_SHIFT (16) /* Bits 16-23: R Default */ +# define LCDC_HCRCFG6_RDEF_MASK (0xff << LCDC_HCRCFG6_RDEF_SHIFT) +# define LCDC_HCRCFG6_RDEF(n) ((uint32_t)(n) << LCDC_HCRCFG6_RDEF_SHIFT) + +/* Hardware Cursor Configuration 7 Register */ + +# define LCDC_HCRCFG7_BKEY_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key */ +# define LCDC_HCRCFG7_BKEY_MASK (0xff << LCDC_HCRCFG7_BKEY_SHIFT) +# define LCDC_HCRCFG7_BKEY(n) ((uint32_t)(n) << LCDC_HCRCFG7_BKEY_SHIFT) +# define LCDC_HCRCFG7_GKEY_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key */ +# define LCDC_HCRCFG7_GKEY_MASK (0xff << LCDC_HCRCFG7_GKEY_SHIFT) +# define LCDC_HCRCFG7_GKEY(n) ((uint32_t)(n) << LCDC_HCRCFG7_GKEY_SHIFT) +# define LCDC_HCRCFG7_RKEY_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key */ +# define LCDC_HCRCFG7_RKEY_MASK (0xff << LCDC_HCRCFG7_RKEY_SHIFT) +# define LCDC_HCRCFG7_RKEY(n) ((uint32_t)(n) << LCDC_HCRCFG7_RKEY_SHIFT) + +/* Hardware Cursor Configuration 8 Register */ + +# define LCDC_HCRCFG8_BMASK_SHIFT (0) /* Bits 0-7: B Color Component Chroma Key Mask */ +# define LCDC_HCRCFG8_BMASK_MASK (0xff << LCDC_HCRCFG8_BMASK_SHIFT) +# define LCDC_HCRCFG8_BMASK(n) ((uint32_t)(n) << LCDC_HCRCFG8_BMASK_SHIFT) +# define LCDC_HCRCFG8_GMASK_SHIFT (8) /* Bits 8-15: G Color Component Chroma Key Mask */ +# define LCDC_HCRCFG8_GMASK_MASK (0xff << LCDC_HCRCFG8_GMASK_SHIFT) +# define LCDC_HCRCFG8_GMASK(n) ((uint32_t)(n) << LCDC_HCRCFG8_GMASK_SHIFT) +# define LCDC_HCRCFG8_RMASK_SHIFT (16) /* Bits 16-23: R Color Component Chroma Key Mask */ +# define LCDC_HCRCFG8_RMASK_MASK (0xff << LCDC_HCRCFG8_RMASK_SHIFT) +# define LCDC_HCRCFG8_RMASK(n) ((uint32_t)(n) << LCDC_HCRCFG8_RMASK_SHIFT) + +/* Hardware Cursor Configuration 9 Register */ + +# define LCDC_HCRCFG9_CRKEY (1 << 0) /* Bit 0: Blender Chroma Key Enable */ +# define LCDC_HCRCFG9_INV (1 << 1) /* Bit 1: Blender Inverted Blender Output Enable */ +# define LCDC_HCRCFG9_ITER2BL (1 << 2) /* Bit 2: Blender Iterated Color Enable */ +# define LCDC_HCRCFG9_ITER (1 << 3) /* Bit 3: Blender Use Iterated Color */ +# define LCDC_HCRCFG9_REVALPHA (1 << 4) /* Bit 4: Blender Reverse Alpha */ +# define LCDC_HCRCFG9_GAEN (1 << 5) /* Bit 5: Blender Global Alpha Enable */ +# define LCDC_HCRCFG9_LAEN (1 << 6) /* Bit 6: Blender Local Alpha Enable */ +# define LCDC_HCRCFG9_OVR (1 << 7) /* Bit 7: Blender Overlay Layer Enable */ +# define LCDC_HCRCFG9_DMA (1 << 8) /* Bit 8: Blender DMA Layer Enable */ +# define LCDC_HCRCFG9_REP (1 << 9) /* Bit 9: Use Replication logic to expand RGB color */ +# define LCDC_HCRCFG9_DSTKEY (1 << 10) /* Bit 10: Destination Chroma Keying */ +# define LCDC_HCRCFG9_GA_SHIFT (16) /* Bits 16-23: Blender Global Alpha */ +# define LCDC_HCRCFG9_GA_MASK (0xff << LCDC_HCRCFG9_GA_SHIFT) +# define LCDC_HCRCFG9_GA(n) ((uint32_t)(n) << LCDC_HCRCFG9_GA_SHIFT) + +/* Post Processing Channel Enable Register */ + +# define LCDC_PPCHER_CH (1 << 0) /* Bit 0: Channel Enable */ +# define LCDC_PPCHER_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes Enable */ +# define LCDC_PPCHER_A2Q (1 << 2) /* Bit 2: Add Head Pointer Enable */ + +/* Post Processing Channel Disable Register */ + +# define LCDC_PPCHDR_CH (1 << 0) /* Bit 0: Channel Disable */ +# define LCDC_PPCHDR_CHRST (1 << 8) /* Bit 8: Channel Reset */ + +/* Post Processing Channel Status Register */ + +# define LCDC_PPCHSR_CH (1 << 0) /* Bit 0: Channel Status */ +# define LCDC_PPCHSR_UPDATE (1 << 1) /* Bit 1: Update Overlay Attributes In */ +# define LCDC_PPCHSR_A2Q (1 << 2) /* Bit 2: Add To Queue Pending */ + +/* Post Processing Interrupt Enable Register, Post Processing Interrupt Disable Register, + * Post Processing Interrupt Mask Register, and Post Processing Interrupt Status Register + */ + +# define LCDC_PPINT_DMA (1 << 2) /* Bit 2: End of DMA Transfer */ +# define LCDC_PPINT_DSCR (1 << 3) /* Bit 3: DMA Descriptor Loaded */ +# define LCDC_PPINT_ADD (1 << 4) /* Bit 4: Head Descriptor Loaded */ +# define LCDC_PPINT_DONE (1 << 5) /* Bit 5: End of List Detected */ + +/* Post Processing Head Register */ + +# define LCDC_PPHEAD__MASK (0xfffffffc) /* Bits 2-31: DMA Head Pointer */ + +/* Post Processing Address Register (32-bit address) */ + +/* Post Processing Control Register */ + +# define LCDC_PPCTRL_DFETCH (1 << 0) /* Bit 0: Transfer Descriptor Fetch Enable */ +# define LCDC_PPCTRL_DMAIEN (1 << 2) /* Bit 2: End of DMA Transfer Interrupt Enable */ +# define LCDC_PPCTRL_DSCRIEN (1 << 3) /* Bit 3: Descriptor Loaded Interrupt Enable */ +# define LCDC_PPCTRL_ADDIEN (1 << 4) /* Bit 4: Add Head Descriptor to Queue Interrupt Enable */ +# define LCDC_PPCTRL_DONEIEN (1 << 5) /* Bit 5: End of List Interrupt Enable */ + +/* Post Processing Next Register (32-bit address) */ + +/* Post Processing Configuration Register 0 */ + +# define LCDC_PPCFG0_SIF (1 << 0) /* Bit 0: Source Interface */ +# define LCDC_PPCFG0_BLEN_SHIFT (4) /* Bits 4-5: AHB Burst Length */ +# define LCDC_PPCFG0_BLEN_MASK (3 << LCDC_PPCFG0_BLEN_SHIFT) +# define LCDC_PPCFG0_BLEN_SINGLE (0 << LCDC_PPCFG0_BLEN_SHIFT) +# define LCDC_PPCFG0_BLEN_INCR4 (1 << LCDC_PPCFG0_BLEN_SHIFT) +# define LCDC_PPCFG0_BLEN_INCR8 (2 << LCDC_PPCFG0_BLEN_SHIFT) +# define LCDC_PPCFG0_BLEN_INCR16 (3 << LCDC_PPCFG0_BLEN_SHIFT) +# define LCDC_PPCFG0_DLBO (1 << 8) /* Bit 8: Defined Length Burst Only */ + +/* Post Processing Configuration Register 1 */ + +# define LCDC_PPCFG1_PPMODE_SHIFT (0) /* Bits 0-2: Post Processing Output Format selection */ +# define LCDC_PPCFG1_PPMODE_MASK (7 << LCDC_PPCFG1_PPMODE_SHIFT) +# define LCDC_PPCFG1_PPMODE_RGB_16BPP (0 << LCDC_PPCFG1_PPMODE_SHIFT) /* RGB 16 bpp */ +# define LCDC_PPCFG1_PPMODE_RGB_24BPP_P (1 << LCDC_PPCFG1_PPMODE_SHIFT) /* RGB 24 bpp PACKED */ +# define LCDC_PPCFG1_PPMODE_RGB_24BPP_UNP (2 << LCDC_PPCFG1_PPMODE_SHIFT) /* RGB 24 bpp UNPACKED */ +# define LCDC_PPCFG1_PPMODE_YCBCR_422_MODE0 (3 << LCDC_PPCFG1_PPMODE_SHIFT) /* YCbCr 422 16 bpp (Mode 0) */ +# define LCDC_PPCFG1_PPMODE_YCBCR_422_MODE1 (4 << LCDC_PPCFG1_PPMODE_SHIFT) /* YCbCr 422 16 bpp (Mode 1) */ +# define LCDC_PPCFG1_PPMODE_YCBCR_422_MODE2 (5 << LCDC_PPCFG1_PPMODE_SHIFT) /* YCbCr 422 16 bpp (Mode 2) */ +# define LCDC_PPCFG1_PPMODE_YCBCR_422_MODE3 (6 << LCDC_PPCFG1_PPMODE_SHIFT) /* YCbCr 422 16 bpp (Mode 3) */ +# define LCDC_PPCFG1_ITUBT601 (1 << 4) /* Bit 4: Color Space Conversion U */ + +/* Post Processing Configuration Register 2 (32-bit horizontal stride) */ + +/* Post Processing Configuration Register 3 */ + +# define LCDC_PPCFG3_CSCYR_SHIFT (0) /* Bits 0-9: Color Space Conversion R coeff for Y */ +# define LCDC_PPCFG3_CSCYR_MASK (0x3ff << LCDC_PPCFG3_CSCYR_SHIFT) +# define LCDC_PPCFG3_CSCYR(n) ((uint32_t)(n) << LCDC_PPCFG3_CSCYR_SHIFT) +# define LCDC_PPCFG3_CSCYG_SHIFT (10) /* Bits 10-19: Color Space Conversion G coeff for Y */ +# define LCDC_PPCFG3_CSCYG_MASK (0x3ff << LCDC_PPCFG3_CSCYG_SHIFT) +# define LCDC_PPCFG3_CSCYG(n) ((uint32_t)(n) << LCDC_PPCFG3_CSCYG_SHIFT) +# define LCDC_PPCFG3_CSCYB_SHIFT (20) /* Bits 20-29: Color Space Conversion B coeff for Y */ +# define LCDC_PPCFG3_CSCYB_MASK (0x3ff << LCDC_PPCFG3_CSCYB_SHIFT) +# define LCDC_PPCFG3_CSCYB(n) ((uint32_t)(n) << LCDC_PPCFG3_CSCYB_SHIFT) +# define LCDC_PPCFG3_CSCYOFF (1 << 30) /* Bit 30: Color Space Conversion Y Offset */ + +/* Post Processing Configuration Register 4 */ + +# define LCDC_PPCFG4_CSCUR_SHIFT (0) /* Bits 0-9: Color Space Conversion R coeff for u */ +# define LCDC_PPCFG4_CSCUR_MASK (0x3ff << LCDC_PPCFG4_CSCUR_SHIFT) +# define LCDC_PPCFG4_CSCUR(n) ((uint32_t)(n) << LCDC_PPCFG4_CSCUR_SHIFT) +# define LCDC_PPCFG4_CSCUG_SHIFT (10) /* Bits 10-19: Color Space Conversion G coeff for u */ +# define LCDC_PPCFG4_CSCUG_MASK (0x3ff << LCDC_PPCFG4_CSCUG_SHIFT) +# define LCDC_PPCFG4_CSCUG(n) ((uint32_t)(n) << LCDC_PPCFG4_CSCUG_SHIFT) +# define LCDC_PPCFG4_CSCUB_SHIFT (20) /* Bits 20-29: Color Space Conversion B coeff for u */ +# define LCDC_PPCFG4_CSCUB_MASK (0x3ff << LCDC_PPCFG4_CSCUB_SHIFT) +# define LCDC_PPCFG4_CSCUB(n) ((uint32_t)(n) << LCDC_PPCFG4_CSCUB_SHIFT) +# define LCDC_PPCFG4_CSCUOFF (1 << 30) /* Bit 30: Color Space Conversion u Offset */ + +/* Post Processing Configuration Register 5 */ + +# define LCDC_PPCFG5_CSCVR_SHIFT (0) /* Bits 0-9: Color Space Conversion R coeff for v */ +# define LCDC_PPCFG5_CSCVR_MASK (0x3ff << LCDC_PPCFG5_CSCVR_SHIFT) +# define LCDC_PPCFG5_CSCVR(n) ((uint32_t)(n) << LCDC_PPCFG5_CSCVR_SHIFT) +# define LCDC_PPCFG5_CSCVG_SHIFT (10) /* Bits 10-19: Color Space Conversion G coeff for v */ +# define LCDC_PPCFG5_CSCVG_MASK (0x3ff << LCDC_PPCFG5_CSCVG_SHIFT) +# define LCDC_PPCFG5_CSCVG(n) ((uint32_t)(n) << LCDC_PPCFG5_CSCVG_SHIFT) +# define LCDC_PPCFG5_CSCVB_SHIFT (20) /* Bits 20-29: Color Space Conversion B coeff for v */ +# define LCDC_PPCFG5_CSCVB_MASK (0x3ff << LCDC_PPCFG5_CSCVB_SHIFT) +# define LCDC_PPCFG5_CSCVB(n) ((uint32_t)(n) << LCDC_PPCFG5_CSCVB_SHIFT) +# define LCDC_PPCFG5_CSCVOFF (1 << 30) /* Bit 30: Color Space Conversion v Offset */ +#endif + +/* Base CLUT Registers 0-255 */ + +#define LCDC_BASECLUT_BCLUT_SHIFT (0) /* Bits 0-7: B color entry */ +#define LCDC_BASECLUT_BCLUT_MASK (0xff << LCDC_BASECLUT_BCLUT_SHIFT) +# define LCDC_BASECLUT_BCLUT(n) ((uint32_t)(n) << LCDC_BASECLUT_BCLUT_SHIFT) +#define LCDC_BASECLUT_GCLUT_SHIFT (8) /* Bits 8-15: G color entry */ +#define LCDC_BASECLUT_GCLUT_MASK (0xff << LCDC_BASECLUT_GCLUT_SHIFT) +# define LCDC_BASECLUT_GCLUT(n) ((uint32_t)(n) << LCDC_BASECLUT_GCLUT_SHIFT) +#define LCDC_BASECLUT_RCLUT_SHIFT (16) /* Bits 16-23: R color entry */ +#define LCDC_BASECLUT_RCLUT_MASK (0xff << LCDC_BASECLUT_RCLUT_SHIFT) +# define LCDC_BASECLUT_RCLUT(n) ((uint32_t)(n) << LCDC_BASECLUT_RCLUT_SHIFT) + +/* Overlay 1 CLUT Registers 0-255 */ + +#define LCDC_OVR1CLUT_BCLUT_SHIFT (0) /* Bits 0-7: B color entry */ +#define LCDC_OVR1CLUT_BCLUT_MASK (0xff << LCDC_OVR1CLUT_BCLUT_SHIFT) +# define LCDC_OVR1CLUT_BCLUT(n) ((uint32_t)(n) << LCDC_OVR1CLUT_BCLUT_SHIFT) +#define LCDC_OVR1CLUT_GCLUT_SHIFT (8) /* Bits 8-15: G color entry */ +#define LCDC_OVR1CLUT_GCLUT_MASK (0xff << LCDC_OVR1CLUT_GCLUT_SHIFT) +# define LCDC_OVR1CLUT_GCLUT(n) ((uint32_t)(n) << LCDC_OVR1CLUT_GCLUT_SHIFT) +#define LCDC_OVR1CLUT_RCLUT_SHIFT (16) /* Bits 16-23: R color entry */ +#define LCDC_OVR1CLUT_RCLUT_MASK (0xff << LCDC_OVR1CLUT_RCLUT_SHIFT) +# define LCDC_OVR1CLUT_RCLUT(n) ((uint32_t)(n) << LCDC_OVR1CLUT_RCLUT_SHIFT) +#define LCDC_OVR1CLUT_ACLUT_SHIFT (24) /* Bits 24-31: Alpha color entry */ +#define LCDC_OVR1CLUT_ACLUT_MASK (0xff << LCDC_OVR1CLUT_ACLUT_SHIFT) +# define LCDC_OVR1CLUT_ACLUT(n) ((uint32_t)(n) << LCDC_OVR1CLUT_ACLUT_SHIFT) + +/* Overlay 2 CLUT Registers 0-255 */ + +#define LCDC_OVR2CLUT_BCLUT_SHIFT (0) /* Bits 0-7: B color entry */ +#define LCDC_OVR2CLUT_BCLUT_MASK (0xff << LCDC_OVR2CLUT_BCLUT_SHIFT) +# define LCDC_OVR2CLUT_BCLUT(n) ((uint32_t)(n) << LCDC_OVR2CLUT_BCLUT_SHIFT) +#define LCDC_OVR2CLUT_GCLUT_SHIFT (8) /* Bits 8-15: G color entry */ +#define LCDC_OVR2CLUT_GCLUT_MASK (0xff << LCDC_OVR2CLUT_GCLUT_SHIFT) +# define LCDC_OVR2CLUT_GCLUT(n) ((uint32_t)(n) << LCDC_OVR2CLUT_GCLUT_SHIFT) +#define LCDC_OVR2CLUT_RCLUT_SHIFT (16) /* Bits 16-23: R color entry */ +#define LCDC_OVR2CLUT_RCLUT_MASK (0xff << LCDC_OVR2CLUT_RCLUT_SHIFT) +# define LCDC_OVR2CLUT_RCLUT(n) ((uint32_t)(n) << LCDC_OVR2CLUT_RCLUT_SHIFT) +#define LCDC_OVR2CLUT_ACLUT_SHIFT (24) /* Bits 24-31: Alpha color entry */ +#define LCDC_OVR2CLUT_ACLUT_MASK (0xff << LCDC_OVR2CLUT_ACLUT_SHIFT) +# define LCDC_OVR2CLUT_ACLUT(n) ((uint32_t)(n) << LCDC_OVR2CLUT_ACLUT_SHIFT) + +/* High End Overlay CLUT Registers 0-255 */ + +#define LCDC_HEOCLUT_BCLUT_SHIFT (0) /* Bits 0-7: B color entry */ +#define LCDC_HEOCLUT_BCLUT_MASK (0xff << LCDC_HEOCLUT_BCLUT_SHIFT) +# define LCDC_HEOCLUT_BCLUT(n) ((uint32_t)(n) << LCDC_HEOCLUT_BCLUT_SHIFT) +#define LCDC_HEOCLUT_GCLUT_SHIFT (8) /* Bits 8-15: G color entry */ +#define LCDC_HEOCLUT_GCLUT_MASK (0xff << LCDC_HEOCLUT_GCLUT_SHIFT) +# define LCDC_HEOCLUT_GCLUT(n) ((uint32_t)(n) << LCDC_HEOCLUT_GCLUT_SHIFT) +#define LCDC_HEOCLUT_RCLUT_SHIFT (16) /* Bits 16-23: R color entry */ +#define LCDC_HEOCLUT_RCLUT_MASK (0xff << LCDC_HEOCLUT_RCLUT_SHIFT) +# define LCDC_HEOCLUT_RCLUT(n) ((uint32_t)(n) << LCDC_HEOCLUT_RCLUT_SHIFT) +#define LCDC_HEOCLUT_ACLUT_SHIFT (24) /* Bits 24-31: Alpha color entry */ +#define LCDC_HEOCLUT_ACLUT_MASK (0xff << LCDC_HEOCLUT_ACLUT_SHIFT) +# define LCDC_HEOCLUT_ACLUT(n) ((uint32_t)(n) << LCDC_HEOCLUT_ACLUT_SHIFT) + +/* Hardware Cursor CLUT Registers 0-255 */ + +#ifdef ATSAMA5D3 +# define LCDC_HCRCLUT_BCLUT_SHIFT (0) /* Bits 0-7: B color entry */ +# define LCDC_HCRCLUT_BCLUT_MASK (0xff << LCDC_HCRCLUT_BCLUT_SHIFT) +# define LCDC_HCRCLUT_BCLUT(n) ((uint32_t)(n) << LCDC_HCRCLUT_BCLUT_SHIFT) +# define LCDC_HCRCLUT_GCLUT_SHIFT (8) /* Bits 8-15: G color entry */ +# define LCDC_HCRCLUT_GCLUT_MASK (0xff << LCDC_HCRCLUT_GCLUT_SHIFT) +# define LCDC_HCRCLUT_GCLUT(n) ((uint32_t)(n) << LCDC_HCRCLUT_GCLUT_SHIFT) +# define LCDC_HCRCLUT_RCLUT_SHIFT (16) /* Bits 16-23: R color entry */ +# define LCDC_HCRCLUT_RCLUT_MASK (0xff << LCDC_HCRCLUT_RCLUT_SHIFT) +# define LCDC_HCRCLUT_RCLUT(n) ((uint32_t)(n) << LCDC_HCRCLUT_RCLUT_SHIFT) +# define LCDC_HCRCLUT_ACLUT_SHIFT (24) /* Bits 24-31: Alpha color entry */ +# define LCDC_HCRCLUT_ACLUT_MASK (0xff << LCDC_HCRCLUT_ACLUT_SHIFT) +# define LCDC_HCRCLUT_ACLUT(n) ((uint32_t)(n) << LCDC_HCRCLUT_ACLUT_SHIFT) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA channel descriptor. This descriptor must be aligned on a 64-bit boundary. */ + +struct sam_dscr_s +{ + uint32_t addr; /* Frame buffer base address register */ + uint32_t ctrl; /* Transfer Control register */ + uint32_t next; /* Next descriptor address register */ + uint32_t pad; /* Padding to assure 64-bit aligned when used as an array */ +}; +#define SIZEOF_SAM_DSCR_S 16 + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_LCDC_H */ diff --git a/arch/arm/src/sama5/chip/sam_matrix.h b/arch/arm/src/sama5/chip/sam_matrix.h new file mode 100644 index 0000000000000000000000000000000000000000..e68e85fddf9df03148ec193fa9603d96ff030328 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_matrix.h @@ -0,0 +1,1009 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_matrix.h + * Bux matrix definitions for the SAMA5 + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MATRIX_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MATRIX_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +#ifdef ATSAMA5D2 +/* These are bits maps of PIDs in the H64MX SPSELR registers. These are used by + * application code to quickly determine if a given PID is served by H32MX or H64MX + * which, in turn, is needed to know if the peripheral secured in SPSELR). + * Reference: "In Matrix" column of "Table 9-2. Peripheral identifiers." + * + * NOTE that these hard-code bit values must match the PID assignments in + * arch/arm/include/sama5/sama5*_irq.h. + */ + +/* ARM=2, XDMAC0=6, XDMAC1=7, AES=9, AESB=10, SHA=12, MPDDRC=13, MATRIX0=15, + * SDMMC0=31 + */ + +# define H64MX_SPSELR0_PIDS 0x8000b6c4 + +/* SDMMC1=32, LCDC=45, ISC=46, QSPI0=52, QSPI1=53, L2CC=63 */ + +# define H64MX_SPSELR1_PIDS 0x80306001 + +/* None */ + +# define H64MX_SPSELR2_PIDS 0x00000000 + +#endif + +#ifdef ATSAMA5D4 +# define H64MX_DDR_SLAVE_PORT0 3 + +/* These are bits maps of PIDs in the H64MX SPSELR registers. These are used by + * application code to quickly determine if a given PID is served by H32MX or H64MX + * which, in turn, is needed to know if the peripheral secured in SPSELR). + * Reference: "In Matrix" column of "Table 9-1. Peripheral identifiers." + * + * NOTE that these hard-code bit values must match the PID assignments in + * arch/arm/include/sama5/sama5*_irq.h. + */ + +/* ARM=2, XDMAC0=8, CPKCC=10, AESB=13, MPDDRC=16, MATRIX0=18, VDEC=19 */ + +# define H64MX_SPSELR0_PIDS 0x000d2504 + +/* XDMAC1=50, LCDC=51, ISI=52 */ + +# define H64MX_SPSELR1_PIDS 0x001c0000 + +/* L2CC=67 */ + +# define H64MX_SPSELR2_PIDS 0x00000008 + +#endif + +/* MATRIX register offsets **************************************************************/ + +#define SAM_MATRIX_MCFG_OFFSET(n) ((n)<<2) +#define SAM_MATRIX_MCFG0_OFFSET 0x0000 /* Master Configuration Register 0 */ +#define SAM_MATRIX_MCFG1_OFFSET 0x0004 /* Master Configuration Register 1 */ +#define SAM_MATRIX_MCFG2_OFFSET 0x0008 /* Master Configuration Register 2 */ +#define SAM_MATRIX_MCFG3_OFFSET 0x000c /* Master Configuration Register 3 */ +#define SAM_MATRIX_MCFG4_OFFSET 0x0010 /* Master Configuration Register 4 */ +#define SAM_MATRIX_MCFG5_OFFSET 0x0014 /* Master Configuration Register 5 */ +#define SAM_MATRIX_MCFG6_OFFSET 0x0018 /* Master Configuration Register 6 */ +#define SAM_MATRIX_MCFG7_OFFSET 0x001c /* Master Configuration Register 7 */ +#define SAM_MATRIX_MCFG8_OFFSET 0x0020 /* Master Configuration Register 8 */ +#define SAM_MATRIX_MCFG9_OFFSET 0x0024 /* Master Configuration Register 9 */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAM_MATRIX_MCFG10_OFFSET 0x0028 /* Master Configuration Register 10 */ +# define SAM_MATRIX_MCFG11_OFFSET 0x002c /* Master Configuration Register 11 */ +#endif + +#ifdef ATSAMA5D3 +# define SAM_MATRIX_MCFG12_OFFSET 0x0030 /* Master Configuration Register 12 */ +# define SAM_MATRIX_MCFG13_OFFSET 0x0034 /* Master Configuration Register 13 */ +# define SAM_MATRIX_MCFG14_OFFSET 0x0038 /* Master Configuration Register 14 */ +# define SAM_MATRIX_MCFG15_OFFSET 0x003c /* Master Configuration Register 15 */ +#endif + +#define SAM_MATRIX_SCFG_OFFSET(n) (0x0040+((n)<<2)) +#define SAM_MATRIX_SCFG0_OFFSET 0x0040 /* Slave Configuration Register 0 */ +#define SAM_MATRIX_SCFG1_OFFSET 0x0044 /* Slave Configuration Register 1 */ +#define SAM_MATRIX_SCFG2_OFFSET 0x0048 /* Slave Configuration Register 2 */ +#define SAM_MATRIX_SCFG3_OFFSET 0x004c /* Slave Configuration Register 3 */ +#define SAM_MATRIX_SCFG4_OFFSET 0x0050 /* Slave Configuration Register 4 */ +#define SAM_MATRIX_SCFG5_OFFSET 0x0054 /* Slave Configuration Register 5 */ +#define SAM_MATRIX_SCFG6_OFFSET 0x0058 /* Slave Configuration Register 6 */ +#define SAM_MATRIX_SCFG7_OFFSET 0x005c /* Slave Configuration Register 7 */ +#define SAM_MATRIX_SCFG8_OFFSET 0x0060 /* Slave Configuration Register 8 */ +#define SAM_MATRIX_SCFG9_OFFSET 0x0064 /* Slave Configuration Register 9 */ +#define SAM_MATRIX_SCFG10_OFFSET 0x0068 /* Slave Configuration Register 10 */ +#define SAM_MATRIX_SCFG11_OFFSET 0x006c /* Slave Configuration Register 11 */ +#define SAM_MATRIX_SCFG12_OFFSET 0x0070 /* Slave Configuration Register 12 */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAM_MATRIX_SCFG13_OFFSET 0x0074 /* Slave Configuration Register 13 */ +# define SAM_MATRIX_SCFG14_OFFSET 0x0078 /* Slave Configuration Register 14 */ +#endif + +#ifdef ATSAMA5D3 +# define SAM_MATRIX_SCFG15_OFFSET 0x007c /* Slave Configuration Register 15 */ +#endif + +#define SAM_MATRIX_PRAS_OFFSET(n) (0x0080+((n)<<3)) +#define SAM_MATRIX_PRBS_OFFSET(n) (0x0084+((n)<<3)) +#define SAM_MATRIX_PRAS0_OFFSET 0x0080 /* Priority Register A for Slave 0 */ +#define SAM_MATRIX_PRBS0_OFFSET 0x0084 /* Priority Register B for Slave 0 */ +#define SAM_MATRIX_PRAS1_OFFSET 0x0088 /* Priority Register A for Slave 1 */ +#define SAM_MATRIX_PRBS1_OFFSET 0x008c /* Priority Register B for Slave 1 */ +#define SAM_MATRIX_PRAS2_OFFSET 0x0090 /* Priority Register A for Slave 2 */ +#define SAM_MATRIX_PRBS2_OFFSET 0x0094 /* Priority Register B for Slave 2 */ +#define SAM_MATRIX_PRAS3_OFFSET 0x0098 /* Priority Register A for Slave 3 */ +#define SAM_MATRIX_PRBS3_OFFSET 0x009c /* Priority Register B for Slave 3 */ +#define SAM_MATRIX_PRAS4_OFFSET 0x00a0 /* Priority Register A for Slave 4 */ +#define SAM_MATRIX_PRBS4_OFFSET 0x00a4 /* Priority Register B for Slave 4 */ +#define SAM_MATRIX_PRAS5_OFFSET 0x00a8 /* Priority Register A for Slave 5 */ +#define SAM_MATRIX_PRBS5_OFFSET 0x00ac /* Priority Register B for Slave 5 */ +#define SAM_MATRIX_PRAS6_OFFSET 0x00b0 /* Priority Register A for Slave 6 */ +#define SAM_MATRIX_PRBS6_OFFSET 0x00b4 /* Priority Register B for Slave 6 */ +#define SAM_MATRIX_PRAS7_OFFSET 0x00b8 /* Priority Register A for Slave 7 */ +#define SAM_MATRIX_PRBS7_OFFSET 0x00bc /* Priority Register B for Slave 7 */ +#define SAM_MATRIX_PRAS8_OFFSET 0x00c0 /* Priority Register A for Slave 8 */ +#define SAM_MATRIX_PRBS8_OFFSET 0x00c4 /* Priority Register B for Slave 8 */ +#define SAM_MATRIX_PRAS9_OFFSET 0x00c8 /* Priority Register A for Slave 9 */ +#define SAM_MATRIX_PRBS9_OFFSET 0x00cc /* Priority Register B for Slave 9 */ +#define SAM_MATRIX_PRAS10_OFFSET 0x00d0 /* Priority Register A for Slave 10 */ +#define SAM_MATRIX_PRBS10_OFFSET 0x00d4 /* Priority Register B for Slave 10 */ +#define SAM_MATRIX_PRAS11_OFFSET 0x00d8 /* Priority Register A for Slave 11 */ +#define SAM_MATRIX_PRBS11_OFFSET 0x00dc /* Priority Register B for Slave 11 */ +#define SAM_MATRIX_PRAS12_OFFSET 0x00e0 /* Priority Register A for Slave 12 */ +#define SAM_MATRIX_PRBS12_OFFSET 0x00e4 /* Priority Register B for Slave 12 */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAM_MATRIX_PRAS13_OFFSET 0x00e8 /* Priority Register A for Slave 13 */ +# define SAM_MATRIX_PRBS13_OFFSET 0x00ec /* Priority Register B for Slave 13 */ +# define SAM_MATRIX_PRAS14_OFFSET 0x00f0 /* Priority Register A for Slave 14 */ +# define SAM_MATRIX_PRBS14_OFFSET 0x00f4 /* Priority Register B for Slave 14 */ +#endif + +#ifdef ATSAMA5D3 +# define SAM_MATRIX_PRAS15_OFFSET 0x00f8 /* Priority Register A for Slave 15 */ +# define SAM_MATRIX_PRBS15_OFFSET 0x00fc /* Priority Register B for Slave 15 */ +# define SAM_MATRIX_MRCR_OFFSET 0x0100 /* Master Remap Control Register */ +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_MATRIX_MEIER_OFFSET 0x0150 /* Master Error Interrupt Enable Register */ +# define SAM_MATRIX_MEIDR_OFFSET 0x0154 /* Master Error Interrupt Disable Register */ +# define SAM_MATRIX_MEIMR_OFFSET 0x0158 /* Master Error Interrupt Mask Register */ +# define SAM_MATRIX_MESR_OFFSET 0x015c /* Master Error Status Register */ + +# define SAM_MATRIX_MEAR0_OFFSET 0x0160 /* Master 0 Error Address Register */ +# define SAM_MATRIX_MEAR1_OFFSET 0x0164 /* Master 1 Error Address Register */ +# define SAM_MATRIX_MEAR2_OFFSET 0x0168 /* Master 2 Error Address Register */ +# define SAM_MATRIX_MEAR3_OFFSET 0x016c /* Master 3 Error Address Register */ +# define SAM_MATRIX_MEAR4_OFFSET 0x0170 /* Master 4 Error Address Register */ +# define SAM_MATRIX_MEAR5_OFFSET 0x0174 /* Master 5 Error Address Register */ +# define SAM_MATRIX_MEAR6_OFFSET 0x0178 /* Master 6 Error Address Register */ +# define SAM_MATRIX_MEAR7_OFFSET 0x017c /* Master 7 Error Address Register */ +# define SAM_MATRIX_MEAR8_OFFSET 0x0180 /* Master 8 Error Address Register */ +# define SAM_MATRIX_MEAR9_OFFSET 0x0184 /* Master 9 Error Address Register */ + +# ifdef ATSAMA5D2 +# define SAM_MATRIX_MEAR10_OFFSET 0x0188 /* Master 10 Error Address Register */ +# define SAM_MATRIX_MEAR11_OFFSET 0x018c /* Master 11 Error Address Register */ +# endif +#endif + +#define SAM_MATRIX_WPMR_OFFSET 0x01e4 /* Write Protect Mode Register */ +#define SAM_MATRIX_WPSR_OFFSET 0x01e8 /* Write Protect Status Register */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_MATRIX_SSR_OFFSET(n) (0x0200+((n)<<2)) +# define SAM_MATRIX_SSR0_OFFSET 0x0200 /* Security Slave 0 Register */ +# define SAM_MATRIX_SSR1_OFFSET 0x0204 /* Security Slave 1 Register */ +# define SAM_MATRIX_SSR2_OFFSET 0x0208 /* Security Slave 2 Register */ +# define SAM_MATRIX_SSR3_OFFSET 0x020c /* Security Slave 3 Register */ +# define SAM_MATRIX_SSR4_OFFSET 0x0210 /* Security Slave 4 Register */ +# define SAM_MATRIX_SSR5_OFFSET 0x0214 /* Security Slave 5 Register */ +# define SAM_MATRIX_SSR6_OFFSET 0x0218 /* Security Slave 6 Register */ +# define SAM_MATRIX_SSR7_OFFSET 0x021c /* Security Slave 7 Register */ +# define SAM_MATRIX_SSR8_OFFSET 0x0220 /* Security Slave 8 Register */ +# define SAM_MATRIX_SSR9_OFFSET 0x0224 /* Security Slave 9 Register */ +# define SAM_MATRIX_SSR10_OFFSET 0x0228 /* Security Slave 10 Register */ +# define SAM_MATRIX_SSR11_OFFSET 0x022c /* Security Slave 11 Register */ +# define SAM_MATRIX_SSR12_OFFSET 0x0230 /* Security Slave 12 Register */ + +# ifdef ATSAMA5D2 +# define SAM_MATRIX_SSR13_OFFSET 0x0234 /* Security Slave 13 Register */ +# define SAM_MATRIX_SSR14_OFFSET 0x0238 /* Security Slave 14 Register */ +# endif + +# define SAM_MATRIX_SASSR_OFFSET(n) (0x0240+((n)<<2)) +# define SAM_MATRIX_SASSR0_OFFSET 0x0240 /* Security Areas Split Slave 0 Register */ +# define SAM_MATRIX_SASSR1_OFFSET 0x0244 /* Security Areas Split Slave 1 Register */ +# define SAM_MATRIX_SASSR2_OFFSET 0x0248 /* Security Areas Split Slave 2 Register */ +# define SAM_MATRIX_SASSR3_OFFSET 0x024c /* Security Areas Split Slave 3 Register */ +# define SAM_MATRIX_SASSR4_OFFSET 0x0250 /* Security Areas Split Slave 4 Register */ +# define SAM_MATRIX_SASSR5_OFFSET 0x0254 /* Security Areas Split Slave 5 Register */ +# define SAM_MATRIX_SASSR6_OFFSET 0x0258 /* Security Areas Split Slave 6 Register */ +# define SAM_MATRIX_SASSR7_OFFSET 0x025c /* Security Areas Split Slave 7 Register */ +# define SAM_MATRIX_SASSR8_OFFSET 0x0260 /* Security Areas Split Slave 8 Register */ +# define SAM_MATRIX_SASSR9_OFFSET 0x0264 /* Security Areas Split Slave 9 Register */ +# define SAM_MATRIX_SASSR10_OFFSET 0x0268 /* Security Areas Split Slave 10 Register */ +# define SAM_MATRIX_SASSR11_OFFSET 0x026c /* Security Areas Split Slave 11 Register */ +# define SAM_MATRIX_SASSR12_OFFSET 0x0270 /* Security Areas Split Slave 12 Register */ + +# ifdef ATSAMA5D2 +# define SAM_MATRIX_SASSR13_OFFSET 0x0274 /* Security Areas Split Slave 13 Register */ +# define SAM_MATRIX_SASSR14_OFFSET 0x0275 /* Security Areas Split Slave 14 Register */ +# endif + +# define SAM_MATRIX_SRTSR_OFFSET(n) (0x0280+((n)<<2)) +# define SAM_MATRIX_SRTSR1_OFFSET 0x0284 /* Security Region Top Slave 1 Register */ +# define SAM_MATRIX_SRTSR2_OFFSET 0x0288 /* Security Region Top Slave 2 Register */ +# define SAM_MATRIX_SRTSR3_OFFSET 0x028c /* Security Region Top Slave 3 Register */ +# define SAM_MATRIX_SRTSR4_OFFSET 0x0290 /* Security Region Top Slave 4 Register */ +# define SAM_MATRIX_SRTSR5_OFFSET 0x0294 /* Security Region Top Slave 5 Register */ +# define SAM_MATRIX_SRTSR6_OFFSET 0x0298 /* Security Region Top Slave 6 Register */ +# define SAM_MATRIX_SRTSR7_OFFSET 0x029c /* Security Region Top Slave 7 Register */ +# define SAM_MATRIX_SRTSR8_OFFSET 0x02a0 /* Security Region Top Slave 8 Register */ +# define SAM_MATRIX_SRTSR9_OFFSET 0x02a4 /* Security Region Top Slave 9 Register */ +# define SAM_MATRIX_SRTSR10_OFFSET 0x02a8 /* Security Region Top Slave 10 Register */ +# define SAM_MATRIX_SRTSR11_OFFSET 0x02ac /* Security Region Top Slave 11 Register */ +# define SAM_MATRIX_SRTSR12_OFFSET 0x02b0 /* Security Region Top Slave 12 Register */ + +# ifdef ATSAMA5D2 +# define SAM_MATRIX_SRTSR13_OFFSET 0x02b4 /* Security Region Top Slave 13 Register */ +# define SAM_MATRIX_SRTSR14_OFFSET 0x02b8 /* Security Region Top Slave 14 Register */ +# endif + +# define SAM_MATRIX_SPSELR_OFFSET(n) (0x02c0 + ((n) << 2)) +# define SAM_MATRIX_SPSELR1_OFFSET 0x02c0 /* Security Peripheral Select 1 Register */ +# define SAM_MATRIX_SPSELR2_OFFSET 0x02c4 /* Security Peripheral Select 2 Register */ +# define SAM_MATRIX_SPSELR3_OFFSET 0x02c8 /* Security Peripheral Select 3 Register */ +#endif + +/* MATRIX register addresses ************************************************************/ + +#ifdef ATSAMA5D3 +# define SAM_MATRIX_MCFG(n)) (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG_OFFSET(n)) +# define SAM_MATRIX_MCFG0 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG0_OFFSET) +# define SAM_MATRIX_MCFG1 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG1_OFFSET) +# define SAM_MATRIX_MCFG2 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG2_OFFSET) +# define SAM_MATRIX_MCFG3 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG3_OFFSET) +# define SAM_MATRIX_MCFG4 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG4_OFFSET) +# define SAM_MATRIX_MCFG5 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG5_OFFSET) +# define SAM_MATRIX_MCFG6 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG6_OFFSET) +# define SAM_MATRIX_MCFG7 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG7_OFFSET) +# define SAM_MATRIX_MCFG8 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG8_OFFSET) +# define SAM_MATRIX_MCFG9 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG9_OFFSET) +# define SAM_MATRIX_MCFG10 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG10_OFFSET) +# define SAM_MATRIX_MCFG11 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG11_OFFSET) +# define SAM_MATRIX_MCFG12 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG12_OFFSET) +# define SAM_MATRIX_MCFG13 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG13_OFFSET) +# define SAM_MATRIX_MCFG14 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG14_OFFSET) +# define SAM_MATRIX_MCFG15 (SAM_MATRIX_VBASE+SAM_MATRIX_MCFG15_OFFSET) + +# define SAM_MATRIX_SCFG(n) (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG_OFFSET(n)) +# define SAM_MATRIX_SCFG0 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG0_OFFSET) +# define SAM_MATRIX_SCFG1 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG1_OFFSET) +# define SAM_MATRIX_SCFG2 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG2_OFFSET) +# define SAM_MATRIX_SCFG3 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG3_OFFSET) +# define SAM_MATRIX_SCFG4 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG4_OFFSET) +# define SAM_MATRIX_SCFG5 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG5_OFFSET) +# define SAM_MATRIX_SCFG6 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG6_OFFSET) +# define SAM_MATRIX_SCFG7 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG7_OFFSET) +# define SAM_MATRIX_SCFG8 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG8_OFFSET) +# define SAM_MATRIX_SCFG9 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG9_OFFSET) +# define SAM_MATRIX_SCFG10 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG10_OFFSET) +# define SAM_MATRIX_SCFG11 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG11_OFFSET) +# define SAM_MATRIX_SCFG12 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG12_OFFSET) +# define SAM_MATRIX_SCFG13 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG13_OFFSET) +# define SAM_MATRIX_SCFG14 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG14_OFFSET) +# define SAM_MATRIX_SCFG15 (SAM_MATRIX_VBASE+SAM_MATRIX_SCFG15_OFFSET) + +# define SAM_MATRIX_PRAS(n) (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS_OFFSET(n)) +# define SAM_MATRIX_PRBS(n) (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS_OFFSET(n)) +# define SAM_MATRIX_PRAS0 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS0_OFFSET) +# define SAM_MATRIX_PRBS0 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS0_OFFSET) +# define SAM_MATRIX_PRAS1 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS1_OFFSET) +# define SAM_MATRIX_PRBS1 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS1_OFFSET) +# define SAM_MATRIX_PRAS2 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS2_OFFSET) +# define SAM_MATRIX_PRBS2 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS2_OFFSET) +# define SAM_MATRIX_PRAS3 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS3_OFFSET) +# define SAM_MATRIX_PRBS3 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS3_OFFSET) +# define SAM_MATRIX_PRAS4 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS4_OFFSET) +# define SAM_MATRIX_PRBS4 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS4_OFFSET) +# define SAM_MATRIX_PRAS5 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS5_OFFSET) +# define SAM_MATRIX_PRBS5 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS5_OFFSET) +# define SAM_MATRIX_PRAS6 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS6_OFFSET) +# define SAM_MATRIX_PRBS6 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS6_OFFSET) +# define SAM_MATRIX_PRAS7 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS7_OFFSET) +# define SAM_MATRIX_PRBS7 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS7_OFFSET) +# define SAM_MATRIX_PRAS8 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS8_OFFSET) +# define SAM_MATRIX_PRBS8 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS8_OFFSET) +# define SAM_MATRIX_PRAS9 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS9_OFFSET) +# define SAM_MATRIX_PRBS9 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS9_OFFSET) +# define SAM_MATRIX_PRAS10 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS10_OFFSET) +# define SAM_MATRIX_PRBS10 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS10_OFFSET) +# define SAM_MATRIX_PRAS11 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS11_OFFSET) +# define SAM_MATRIX_PRBS11 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS11_OFFSET) +# define SAM_MATRIX_PRAS12 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS12_OFFSET) +# define SAM_MATRIX_PRBS12 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS12_OFFSET) + +# define SAM_MATRIX_PRAS13 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS13_OFFSET) +# define SAM_MATRIX_PRBS13 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS13_OFFSET) +# define SAM_MATRIX_PRAS14 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS14_OFFSET) +# define SAM_MATRIX_PRBS14 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS14_OFFSET) +# define SAM_MATRIX_PRAS15 (SAM_MATRIX_VBASE+SAM_MATRIX_PRAS15_OFFSET) +# define SAM_MATRIX_PRBS15 (SAM_MATRIX_VBASE+SAM_MATRIX_PRBS15_OFFSET) +# define SAM_MATRIX_MRCR (SAM_MATRIX_VBASE+SAM_MATRIX_MRCR_OFFSET) + +# define SAM_MATRIX_WPMR (SAM_MATRIX_VBASE+SAM_MATRIX_WPMR_OFFSET) +# define SAM_MATRIX_WPSR (SAM_MATRIX_VBASE+SAM_MATRIX_WPSR_OFFSET) + +#endif /* ATSAMA5D3 */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* HMATRIX0 (H64MX) */ + +# define SAM_MATRIX0_MCFG(n)) (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG_OFFSET(n)) +# define SAM_MATRIX0_MCFG0 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG0_OFFSET) +# define SAM_MATRIX0_MCFG1 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG1_OFFSET) +# define SAM_MATRIX0_MCFG2 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG2_OFFSET) +# define SAM_MATRIX0_MCFG3 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG3_OFFSET) +# define SAM_MATRIX0_MCFG4 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG4_OFFSET) +# define SAM_MATRIX0_MCFG5 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG5_OFFSET) +# define SAM_MATRIX0_MCFG6 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG6_OFFSET) +# define SAM_MATRIX0_MCFG7 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG7_OFFSET) +# define SAM_MATRIX0_MCFG8 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG8_OFFSET) +# define SAM_MATRIX0_MCFG9 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG9_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_MCFG10 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG10_OFFSET) +# define SAM_MATRIX0_MCFG11 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG11_OFFSET) +# endif + +# define SAM_MATRIX0_SCFG(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG_OFFSET(n)) +# define SAM_MATRIX0_SCFG0 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG0_OFFSET) +# define SAM_MATRIX0_SCFG1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG1_OFFSET) +# define SAM_MATRIX0_SCFG2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG2_OFFSET) +# define SAM_MATRIX0_SCFG3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG3_OFFSET) +# define SAM_MATRIX0_SCFG4 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG4_OFFSET) +# define SAM_MATRIX0_SCFG5 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG5_OFFSET) +# define SAM_MATRIX0_SCFG6 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG6_OFFSET) +# define SAM_MATRIX0_SCFG7 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG7_OFFSET) +# define SAM_MATRIX0_SCFG8 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG8_OFFSET) +# define SAM_MATRIX0_SCFG9 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG9_OFFSET) +# define SAM_MATRIX0_SCFG10 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG10_OFFSET) +# define SAM_MATRIX0_SCFG11 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG11_OFFSET) +# define SAM_MATRIX0_SCFG12 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_SCFG13 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG13_OFFSET) +# define SAM_MATRIX0_SCFG14 (SAM_MATRIX64_VBASE+SAM_MATRIX_SCFG14_OFFSET) +# endif + +# define SAM_MATRIX0_PRAS(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS_OFFSET(n)) +# define SAM_MATRIX0_PRBS(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS_OFFSET(n)) +# define SAM_MATRIX0_PRAS0 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS0_OFFSET) +# define SAM_MATRIX0_PRBS0 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS0_OFFSET) +# define SAM_MATRIX0_PRAS1 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS1_OFFSET) +# define SAM_MATRIX0_PRBS1 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS1_OFFSET) +# define SAM_MATRIX0_PRAS2 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS2_OFFSET) +# define SAM_MATRIX0_PRBS2 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS2_OFFSET) +# define SAM_MATRIX0_PRAS3 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS3_OFFSET) +# define SAM_MATRIX0_PRBS3 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS3_OFFSET) +# define SAM_MATRIX0_PRAS4 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS4_OFFSET) +# define SAM_MATRIX0_PRBS4 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS4_OFFSET) +# define SAM_MATRIX0_PRAS5 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS5_OFFSET) +# define SAM_MATRIX0_PRBS5 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS5_OFFSET) +# define SAM_MATRIX0_PRAS6 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS6_OFFSET) +# define SAM_MATRIX0_PRBS6 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS6_OFFSET) +# define SAM_MATRIX0_PRAS7 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS7_OFFSET) +# define SAM_MATRIX0_PRBS7 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS7_OFFSET) +# define SAM_MATRIX0_PRAS8 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS8_OFFSET) +# define SAM_MATRIX0_PRBS8 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS8_OFFSET) +# define SAM_MATRIX0_PRAS9 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS9_OFFSET) +# define SAM_MATRIX0_PRBS9 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS9_OFFSET) +# define SAM_MATRIX0_PRAS10 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS10_OFFSET) +# define SAM_MATRIX0_PRBS10 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS10_OFFSET) +# define SAM_MATRIX0_PRAS11 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS11_OFFSET) +# define SAM_MATRIX0_PRBS11 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS11_OFFSET) +# define SAM_MATRIX0_PRAS12 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS12_OFFSET) +# define SAM_MATRIX0_PRBS12 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_PRAS13 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS13_OFFSET) +# define SAM_MATRIX0_PRBS13 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS13_OFFSET) +# define SAM_MATRIX0_PRAS14 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRAS14_OFFSET) +# define SAM_MATRIX0_PRBS15 (SAM_MATRIX64_VBASE+SAM_MATRIX_PRBS15_OFFSET) +# endif + +# define SAM_MATRIX0_MEIER (SAM_MATRIX64_VBASE+SAM_MATRIX_MEIER_OFFSET) +# define SAM_MATRIX0_MEIDR (SAM_MATRIX64_VBASE+SAM_MATRIX_MEIDR_OFFSET +# define SAM_MATRIX0_MEIMR (SAM_MATRIX64_VBASE+SAM_MATRIX_MEIMR_OFFSET) +# define SAM_MATRIX0_MESR (SAM_MATRIX64_VBASE+SAM_MATRIX_MESR_OFFSET) + +# define SAM_MATRIX0_MEAR0 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR0_OFFSET) +# define SAM_MATRIX0_MEAR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR1_OFFSET) +# define SAM_MATRIX0_MEAR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR2_OFFSET) +# define SAM_MATRIX0_MEAR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR3_OFFSET) +# define SAM_MATRIX0_MEAR4 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR4_OFFSET) +# define SAM_MATRIX0_MEAR5 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR5_OFFSET) +# define SAM_MATRIX0_MEAR6 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR6_OFFSET) +# define SAM_MATRIX0_MEAR7 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR7_OFFSET) +# define SAM_MATRIX0_MEAR8 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR8_OFFSET) +# define SAM_MATRIX0_MEAR9 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR9_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_MEAR10 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR10_OFFSET) +# define SAM_MATRIX0_MEAR11 (SAM_MATRIX64_VBASE+SAM_MATRIX_MEAR11_OFFSET) +# endif + +# define SAM_MATRIX0_WPMR (SAM_MATRIX64_VBASE+SAM_MATRIX_WPMR_OFFSET) +# define SAM_MATRIX0_WPSR (SAM_MATRIX64_VBASE+SAM_MATRIX_WPSR_OFFSET) + +# define SAM_MATRIX0_SSR(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR_OFFSET(n)) +# define SAM_MATRIX0_SSR0 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR0_OFFSET) +# define SAM_MATRIX0_SSR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR1_OFFSET) +# define SAM_MATRIX0_SSR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR2_OFFSET) +# define SAM_MATRIX0_SSR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR3_OFFSET) +# define SAM_MATRIX0_SSR4 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR4_OFFSET) +# define SAM_MATRIX0_SSR5 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR5_OFFSET) +# define SAM_MATRIX0_SSR6 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR6_OFFSET) +# define SAM_MATRIX0_SSR7 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR7_OFFSET) +# define SAM_MATRIX0_SSR8 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR8_OFFSET) +# define SAM_MATRIX0_SSR9 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR9_OFFSET) +# define SAM_MATRIX0_SSR10 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR10_OFFSET) +# define SAM_MATRIX0_SSR11 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR11_OFFSET) +# define SAM_MATRIX0_SSR12 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_SSR13 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR13_OFFSET) +# define SAM_MATRIX0_SSR14 (SAM_MATRIX64_VBASE+SAM_MATRIX_SSR14_OFFSET) +# endif + +# define SAM_MATRIX0_SASSR(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR_OFFSET(n)) +# define SAM_MATRIX0_SASSR0 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR0_OFFSET) +# define SAM_MATRIX0_SASSR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR1_OFFSET) +# define SAM_MATRIX0_SASSR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR2_OFFSET) +# define SAM_MATRIX0_SASSR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR3_OFFSET) +# define SAM_MATRIX0_SASSR4 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR4_OFFSET) +# define SAM_MATRIX0_SASSR5 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR5_OFFSET) +# define SAM_MATRIX0_SASSR6 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR6_OFFSET) +# define SAM_MATRIX0_SASSR7 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR7_OFFSET) +# define SAM_MATRIX0_SASSR8 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR8_OFFSET) +# define SAM_MATRIX0_SASSR9 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR9_OFFSET) +# define SAM_MATRIX0_SASSR10 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR10_OFFSET) +# define SAM_MATRIX0_SASSR11 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR11_OFFSET) +# define SAM_MATRIX0_SASSR12 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_SASSR13 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR13_OFFSET) +# define SAM_MATRIX0_SASSR14 (SAM_MATRIX64_VBASE+SAM_MATRIX_SASSR14_OFFSET) +# endif + +# define SAM_MATRIX0_SRTSR(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR_OFFSET(n)) +# define SAM_MATRIX0_SRTSR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR1_OFFSET) +# define SAM_MATRIX0_SRTSR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR2_OFFSET) +# define SAM_MATRIX0_SRTSR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR3_OFFSET) +# define SAM_MATRIX0_SRTSR4 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR4_OFFSET) +# define SAM_MATRIX0_SRTSR5 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR5_OFFSET) +# define SAM_MATRIX0_SRTSR6 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR6_OFFSET) +# define SAM_MATRIX0_SRTSR7 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR7_OFFSET) +# define SAM_MATRIX0_SRTSR8 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR8_OFFSET) +# define SAM_MATRIX0_SRTSR9 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR9_OFFSET) +# define SAM_MATRIX0_SRTSR10 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR10_OFFSET) +# define SAM_MATRIX0_SRTSR11 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR11_OFFSET) +# define SAM_MATRIX0_SRTSR12 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX0_SRTSR13 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR13_OFFSET) +# define SAM_MATRIX0_SRTSR14 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR14_OFFSET) +# endif + +# define SAM_MATRIX0_SPSELR(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR_OFFSET(n)) +# define SAM_MATRIX0_SPSELR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR1_OFFSET) +# define SAM_MATRIX0_SPSELR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR2_OFFSET) +# define SAM_MATRIX0_SPSELR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR3_OFFSET) + +/* HMATRIX 1 (H32MX) */ + +# define SAM_MATRIX1_MCFG(n)) (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG_OFFSET(n)) +# define SAM_MATRIX1_MCFG0 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG0_OFFSET) +# define SAM_MATRIX1_MCFG1 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG1_OFFSET) +# define SAM_MATRIX1_MCFG2 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG2_OFFSET) +# define SAM_MATRIX1_MCFG3 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG3_OFFSET) +# define SAM_MATRIX1_MCFG4 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG4_OFFSET) +# define SAM_MATRIX1_MCFG5 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG5_OFFSET) +# define SAM_MATRIX1_MCFG6 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG6_OFFSET) +# define SAM_MATRIX1_MCFG7 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG7_OFFSET) +# define SAM_MATRIX1_MCFG8 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG8_OFFSET) +# define SAM_MATRIX1_MCFG9 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG9_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_MCFG10 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG10_OFFSET) +# define SAM_MATRIX1_MCFG11 (SAM_MATRIX32_VBASE+SAM_MATRIX_MCFG11_OFFSET) +# endif + +# define SAM_MATRIX1_SCFG(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG_OFFSET(n)) +# define SAM_MATRIX1_SCFG0 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG0_OFFSET) +# define SAM_MATRIX1_SCFG1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG1_OFFSET) +# define SAM_MATRIX1_SCFG2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG2_OFFSET) +# define SAM_MATRIX1_SCFG3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG3_OFFSET) +# define SAM_MATRIX1_SCFG4 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG4_OFFSET) +# define SAM_MATRIX1_SCFG5 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG5_OFFSET) +# define SAM_MATRIX1_SCFG6 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG6_OFFSET) +# define SAM_MATRIX1_SCFG7 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG7_OFFSET) +# define SAM_MATRIX1_SCFG8 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG8_OFFSET) +# define SAM_MATRIX1_SCFG9 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG9_OFFSET) +# define SAM_MATRIX1_SCFG10 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG10_OFFSET) +# define SAM_MATRIX1_SCFG11 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG11_OFFSET) +# define SAM_MATRIX1_SCFG12 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_SCFG13 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG13_OFFSET) +# define SAM_MATRIX1_SCFG14 (SAM_MATRIX32_VBASE+SAM_MATRIX_SCFG14_OFFSET) +# endif + +# define SAM_MATRIX1_PRAS(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS_OFFSET(n)) +# define SAM_MATRIX1_PRBS(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS_OFFSET(n)) +# define SAM_MATRIX1_PRAS0 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS0_OFFSET) +# define SAM_MATRIX1_PRBS0 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS0_OFFSET) +# define SAM_MATRIX1_PRAS1 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS1_OFFSET) +# define SAM_MATRIX1_PRBS1 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS1_OFFSET) +# define SAM_MATRIX1_PRAS2 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS2_OFFSET) +# define SAM_MATRIX1_PRBS2 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS2_OFFSET) +# define SAM_MATRIX1_PRAS3 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS3_OFFSET) +# define SAM_MATRIX1_PRBS3 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS3_OFFSET) +# define SAM_MATRIX1_PRAS4 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS4_OFFSET) +# define SAM_MATRIX1_PRBS4 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS4_OFFSET) +# define SAM_MATRIX1_PRAS5 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS5_OFFSET) +# define SAM_MATRIX1_PRBS5 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS5_OFFSET) +# define SAM_MATRIX1_PRAS6 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS6_OFFSET) +# define SAM_MATRIX1_PRBS6 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS6_OFFSET) +# define SAM_MATRIX1_PRAS7 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS7_OFFSET) +# define SAM_MATRIX1_PRBS7 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS7_OFFSET) +# define SAM_MATRIX1_PRAS8 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS8_OFFSET) +# define SAM_MATRIX1_PRBS8 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS8_OFFSET) +# define SAM_MATRIX1_PRAS9 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS9_OFFSET) +# define SAM_MATRIX1_PRBS9 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS9_OFFSET) +# define SAM_MATRIX1_PRAS10 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS10_OFFSET) +# define SAM_MATRIX1_PRBS10 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS10_OFFSET) +# define SAM_MATRIX1_PRAS11 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS11_OFFSET) +# define SAM_MATRIX1_PRBS11 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS11_OFFSET) +# define SAM_MATRIX1_PRAS12 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS12_OFFSET) +# define SAM_MATRIX1_PRBS12 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_PRAS13 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS13_OFFSET) +# define SAM_MATRIX1_PRBS13 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS13_OFFSET) +# define SAM_MATRIX1_PRAS14 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRAS14_OFFSET) +# define SAM_MATRIX1_PRBS15 (SAM_MATRIX32_VBASE+SAM_MATRIX_PRBS15_OFFSET) +# endif + +# define SAM_MATRIX1_MEIER (SAM_MATRIX32_VBASE+SAM_MATRIX_MEIER_OFFSET) +# define SAM_MATRIX1_MEIDR (SAM_MATRIX32_VBASE+SAM_MATRIX_MEIDR_OFFSET +# define SAM_MATRIX1_MEIMR (SAM_MATRIX32_VBASE+SAM_MATRIX_MEIMR_OFFSET) +# define SAM_MATRIX1_MESR (SAM_MATRIX32_VBASE+SAM_MATRIX_MESR_OFFSET) + +# define SAM_MATRIX1_MEAR0 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR0_OFFSET) +# define SAM_MATRIX1_MEAR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR1_OFFSET) +# define SAM_MATRIX1_MEAR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR2_OFFSET) +# define SAM_MATRIX1_MEAR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR3_OFFSET) +# define SAM_MATRIX1_MEAR4 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR4_OFFSET) +# define SAM_MATRIX1_MEAR5 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR5_OFFSET) +# define SAM_MATRIX1_MEAR6 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR6_OFFSET) +# define SAM_MATRIX1_MEAR7 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR7_OFFSET) +# define SAM_MATRIX1_MEAR8 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR8_OFFSET) +# define SAM_MATRIX1_MEAR9 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR9_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_MEAR10 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR10_OFFSET) +# define SAM_MATRIX1_MEAR11 (SAM_MATRIX32_VBASE+SAM_MATRIX_MEAR11_OFFSET) +# endif + +# define SAM_MATRIX1_WPMR (SAM_MATRIX32_VBASE+SAM_MATRIX_WPMR_OFFSET) +# define SAM_MATRIX1_WPSR (SAM_MATRIX32_VBASE+SAM_MATRIX_WPSR_OFFSET) + +# define SAM_MATRIX1_SSR(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR_OFFSET(n)) +# define SAM_MATRIX1_SSR0 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR0_OFFSET) +# define SAM_MATRIX1_SSR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR1_OFFSET) +# define SAM_MATRIX1_SSR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR2_OFFSET) +# define SAM_MATRIX1_SSR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR3_OFFSET) +# define SAM_MATRIX1_SSR4 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR4_OFFSET) +# define SAM_MATRIX1_SSR5 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR5_OFFSET) +# define SAM_MATRIX1_SSR6 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR6_OFFSET) +# define SAM_MATRIX1_SSR7 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR7_OFFSET) +# define SAM_MATRIX1_SSR8 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR8_OFFSET) +# define SAM_MATRIX1_SSR9 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR9_OFFSET) +# define SAM_MATRIX1_SSR10 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR10_OFFSET) +# define SAM_MATRIX1_SSR11 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR11_OFFSET) +# define SAM_MATRIX1_SSR12 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_SSR13 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR13_OFFSET) +# define SAM_MATRIX1_SSR14 (SAM_MATRIX32_VBASE+SAM_MATRIX_SSR14_OFFSET) +# endif + +# define SAM_MATRIX1_SASSR(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR_OFFSET(n)) +# define SAM_MATRIX1_SASSR0 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR0_OFFSET) +# define SAM_MATRIX1_SASSR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR1_OFFSET) +# define SAM_MATRIX1_SASSR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR2_OFFSET) +# define SAM_MATRIX1_SASSR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR3_OFFSET) +# define SAM_MATRIX1_SASSR4 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR4_OFFSET) +# define SAM_MATRIX1_SASSR5 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR5_OFFSET) +# define SAM_MATRIX1_SASSR6 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR6_OFFSET) +# define SAM_MATRIX1_SASSR7 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR7_OFFSET) +# define SAM_MATRIX1_SASSR8 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR8_OFFSET) +# define SAM_MATRIX1_SASSR9 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR9_OFFSET) +# define SAM_MATRIX1_SASSR10 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR10_OFFSET) +# define SAM_MATRIX1_SASSR11 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR11_OFFSET) +# define SAM_MATRIX1_SASSR12 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_SASSR13 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR13_OFFSET) +# define SAM_MATRIX1_SASSR14 (SAM_MATRIX32_VBASE+SAM_MATRIX_SASSR14_OFFSET) +# endif + +# define SAM_MATRIX1_SRTSR(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR_OFFSET(n)) +# define SAM_MATRIX1_SRTSR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR1_OFFSET) +# define SAM_MATRIX1_SRTSR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR2_OFFSET) +# define SAM_MATRIX1_SRTSR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR3_OFFSET) +# define SAM_MATRIX1_SRTSR4 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR4_OFFSET) +# define SAM_MATRIX1_SRTSR5 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR5_OFFSET) +# define SAM_MATRIX1_SRTSR6 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR6_OFFSET) +# define SAM_MATRIX1_SRTSR7 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR7_OFFSET) +# define SAM_MATRIX1_SRTSR8 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR8_OFFSET) +# define SAM_MATRIX1_SRTSR9 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR9_OFFSET) +# define SAM_MATRIX1_SRTSR10 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR10_OFFSET) +# define SAM_MATRIX1_SRTSR11 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR11_OFFSET) +# define SAM_MATRIX1_SRTSR12 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR12_OFFSET) + +# ifdef ATSAMA5D2 +# define SAM_MATRIX1_SRTSR13 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR13_OFFSET) +# define SAM_MATRIX1_SRTSR14 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR14_OFFSET) +# endif + +# define SAM_MATRIX1_SPSELR(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR_OFFSET(n)) +# define SAM_MATRIX1_SPSELR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR1_OFFSET) +# define SAM_MATRIX1_SPSELR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR2_OFFSET) +# define SAM_MATRIX1_SPSELR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR3_OFFSET) + +#endif /* ATSAMA5D2 || ATSAMA5D4 */ + +/* MATRIX register bit definitions ******************************************************/ +/* Master Configuration Registers */ + +#define MATRIX_MCFG_ULBT_SHIFT (0) /* Bits 0-2: Undefined Length Burst Type */ +#define MATRIX_MCFG_ULBT_MASK (7 << MATRIX_MCFG_ULBT_SHIFT) +# define MATRIX_MCFG_ULBT_INF (0 << MATRIX_MCFG_ULBT_SHIFT) /* Infinite Length Burst */ +# define MATRIX_MCFG_ULBT_SINGLE (1 << MATRIX_MCFG_ULBT_SHIFT) /* Single Access */ +# define MATRIX_MCFG_ULBT_4BEAT (2 << MATRIX_MCFG_ULBT_SHIFT) /* 4-Beat Burst */ +# define MATRIX_MCFG_ULBT_8BEAT (3 << MATRIX_MCFG_ULBT_SHIFT) /* 8-Beat Burst */ +# define MATRIX_MCFG_ULBT_16BEAT (4 << MATRIX_MCFG_ULBT_SHIFT) /* 16-Beat Burst */ +# define MATRIX_MCFG_ULBT_32BEAT (5 << MATRIX_MCFG_ULBT_SHIFT) /* 32-Beat Burst */ +# define MATRIX_MCFG_ULBT_64BEAT (6 << MATRIX_MCFG_ULBT_SHIFT) /* 64-Beat Burst */ +# define MATRIX_MCFG_ULBT_128BEAT (7 << MATRIX_MCFG_ULBT_SHIFT) /* 128-Beat Burst */ + +/* Bus Matrix Slave Configuration Registers */ + +#define MATRIX_SCFG_SLOTCYCLE_SHIFT (0) /* Bits 0-8: Maximum Number of Allowed Cycles for a Burst */ +#define MATRIX_SCFG_SLOTCYCLE_MASK (0x1ff << MATRIX_SCFG_SLOTCYCLE_SHIFT) +# define MATRIX_SCFG_SLOTCYCLE(n) ((uint32_t)(n) << MATRIX_SCFG_SLOTCYCLE_SHIFT) +#define MATRIX_SCFG_DEFMSTRTYPE_SHIFT (16) /* Bits 16-17: Default Master Type */ +#define MATRIX_SCFG_DEFMSTRTYPE_MASK (3 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_NONE (0 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_LAST (1 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_FIXED (2 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +#define MATRIX_SCFG_FIXEDDEFMSTR_SHIFT (18) /* Bits 18-21: Fixed Default Master */ +#define MATRIX_SCFG_FIXEDDEFMSTR_MASK (15 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG_FIXEDDEFMSTR(n) ((uint32_t)(n) << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) + +/* Bus Matrix Priority Registers A For Slaves */ + +#define MATRIX_PRAS_MPR_SHIFT(n) ((n)<<2) +#define MATRIX_PRAS_MPR_MASK(n) (3 << MATRIX_PRAS_MPR_SHIFT(n)) +# define MATRIX_PRAS_MPR(n,v) ((uint32_t)(v) << MATRIX_PRAS_MPR_SHIFT(n)) +# define MATRIX_PRAS_M0PR_SHIFT (0) /* Bits 0-1: Master 0 Priority */ +# define MATRIX_PRAS_M0PR_MASK (3 << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M0PR(n) ((uint32_t)(n) << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M1PR_SHIFT (4) /* Bits 4-5: Master 1 Priority */ +# define MATRIX_PRAS_M1PR_MASK (3 << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M1PR(n) ((uint32_t)(n) << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M2PR_SHIFT (8) /* Bits 8-9: Master 2 Priority */ +# define MATRIX_PRAS_M2PR_MASK (3 << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M2PR(n) ((uint32_t)(n) << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M3PR_SHIFT (12) /* Bits 12-13: Master 3 Priority */ +# define MATRIX_PRAS_M3PR_MASK (3 << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M3PR(n) ((uint32_t)(n) << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M4PR_SHIFT (16) /* Bits 16-17: Master 4 Priority */ +# define MATRIX_PRAS_M4PR_MASK (3 << MATRIX_PRAS_M4PR_SHIFT) +# define MATRIX_PRAS_M4PR(n) ((uint32_t)(n) << MATRIX_PRAS_M4PR_SHIFT) +# define MATRIX_PRAS_M5PR_SHIFT (20) /* Bits 20-21: Master 5 Priority */ +# define MATRIX_PRAS_M5PR_MASK (3 << MATRIX_PRAS_M5PR_SHIFT) +# define MATRIX_PRAS_M5PR(n) ((uint32_t)(n) << MATRIX_PRAS_M5PR_SHIFT) +# define MATRIX_PRAS_M6PR_SHIFT (24) /* Bits 24-25: Master 6 Priority */ +# define MATRIX_PRAS_M6PR_MASK (3 << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M6PR(n) ((uint32_t)(n) << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M7PR_SHIFT (28) /* Bits 28-29: Master 7 Priority */ +# define MATRIX_PRAS_M7PR_MASK (3 << MATRIX_PRAS_M7PR_SHIFT) +# define MATRIX_PRAS_M7PR(n) (((uint32_t)(v) << MATRIX_PRAS_M7PR_SHIFT) + +/* Bus Matrix Priority Registers B For Slaves */ + +#define MATRIX_PRBS_MPR_SHIFT(n) ((n)<<2) +#define MATRIX_PRBS_MPR_MASK(n) (3 << MATRIX_PRBS_MPR_SHIFT(n)) +# define MATRIX_PRBS_MPR(n,v) ((uint32_t)(v) << MATRIX_PRBS_MPR_SHIFT(n)) +# define MATRIX_PRBS_M8PR_SHIFT (0) /* Bits 0-1: Master 8 Priority */ +# define MATRIX_PRBS_M8PR_MASK (3 << MATRIX_PRBS_M8PR_SHIFT) +# define MATRIX_PRBS_M8PR(n) ((uint32_t)(n) << MATRIX_PRBS_M8PR_SHIFT) +# define MATRIX_PRBS_M9PR_SHIFT (4) /* Bits 4-5: Master 9 Priority */ +# define MATRIX_PRBS_M9PR_MASK (3 << MATRIX_PRBS_M9PR_SHIFT) +# define MATRIX_PRBS_M9PR(n) ((uint32_t)(n) << MATRIX_PRBS_M9PR_SHIFT) + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define MATRIX_PRBS_M10PR_SHIFT (8) /* Bits 8-9: Master 10 Priority */ +# define MATRIX_PRBS_M10PR_MASK (3 << MATRIX_PRBS_M10PR_SHIFT) +# define MATRIX_PRBS_M10PR(n) ((uint32_t)(n) << MATRIX_PRBS_M10PR_SHIFT) +# define MATRIX_PRBS_M11PR_SHIFT (12) /* Bits 12-13: Master 11 Priority */ +# define MATRIX_PRBS_M11PR_MASK (3 << MATRIX_PRBS_M11PR_SHIFT) +# define MATRIX_PRBS_M11PR(n) ((uint32_t)(n) << MATRIX_PRBS_M11PR_SHIFT) +#endif + +#ifdef ATSAMA5D3 +# define MATRIX_PRBS_M12PR_SHIFT (16) /* Bits 16-17: Master 12 Priority */ +# define MATRIX_PRBS_M12PR_MASK (3 << MATRIX_PRBS_M12PR_SHIFT) +# define MATRIX_PRBS_M12PR(n) ((uint32_t)(n) << MATRIX_PRBS_M12PR_SHIFT) +# define MATRIX_PRBS_M13PR_SHIFT (20) /* Bits 20-21: Master 13 Priority */ +# define MATRIX_PRBS_M13PR_MASK (3 << MATRIX_PRBS_M13PR_SHIFT) +# define MATRIX_PRBS_M13PR(n) ((uint32_t)(n) << MATRIX_PRBS_M13PR_SHIFT) +# define MATRIX_PRBS_M14PR_SHIFT (24) /* Bits 24-25: Master 14 Priority */ +# define MATRIX_PRBS_M14PR_MASK (3 << MATRIX_PRBS_M14PR_SHIFT) +# define MATRIX_PRBS_M14PR(n) ((uint32_t)(n) << MATRIX_PRBS_M14PR_SHIFT) +# define MATRIX_PRBS_M15PR_SHIFT (28) /* Bits 28-29: Master 15 Priority */ +# define MATRIX_PRBS_M15PR_MASK (3 << MATRIX_PRBS_M15PR_SHIFT) +# define MATRIX_PRBS_M15PR(n) ((uint32_t)(n) << MATRIX_PRBS_M15PR_SHIFT) +#endif + +#ifdef ATSAMA5D3 +/* Master Remap Control Register */ + +# define MATRIX_MRCR_RCB(n) (1 << (n)) +# define MATRIX_MRCR_RCB0 (1 << 0) /* Bit 0: Remap Command Bit for Master 0 */ +# define MATRIX_MRCR_RCB1 (1 << 1) /* Bit 1: Remap Command Bit for Master 1 */ +# define MATRIX_MRCR_RCB2 (1 << 2) /* Bit 2: Remap Command Bit for Master 2 */ +# define MATRIX_MRCR_RCB3 (1 << 3) /* Bit 3: Remap Command Bit for Master 3 */ +# define MATRIX_MRCR_RCB4 (1 << 4) /* Bit 4: Remap Command Bit for Master 4 */ +# define MATRIX_MRCR_RCB5 (1 << 5) /* Bit 5: Remap Command Bit for Master 5 */ +# define MATRIX_MRCR_RCB6 (1 << 6) /* Bit 6: Remap Command Bit for Master 6 */ +# define MATRIX_MRCR_RCB7 (1 << 7) /* Bit 7: Remap Command Bit for Master 7 */ +# define MATRIX_MRCR_RCB8 (1 << 8) /* Bit 8: Remap Command Bit for Master 8 */ +# define MATRIX_MRCR_RCB9 (1 << 9) /* Bit 9: Remap Command Bit for Master 9 */ +# define MATRIX_MRCR_RCB10 (1 << 10) /* Bit 10: Remap Command Bit for Master 10 */ +# define MATRIX_MRCR_RCB11 (1 << 11) /* Bit 11: Remap Command Bit for Master 11 */ +# define MATRIX_MRCR_RCB12 (1 << 12) /* Bit 12: Remap Command Bit for Master 12 */ +# define MATRIX_MRCR_RCB13 (1 << 13) /* Bit 13: Remap Command Bit for Master 13 */ +# define MATRIX_MRCR_RCB14 (1 << 14) /* Bit 14: Remap Command Bit for Master 14 */ +# define MATRIX_MRCR_RCB15 (1 << 15) /* Bit 15: Remap Command Bit for Master 15 */ +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* Master Error Interrupt Enable Register, Master Error Interrupt Disable Register, + * Master Error Interrupt Mask Register, and Master Error Status Register + */ + +# define MATRIX_MEINT_MERR(n) (1 << (n)) /* Master x Access Error, n=0..9 */ +# define MATRIX_MEINT_MERR0 (1 << 0) /* Master 0 Access Error */ +# define MATRIX_MEINT_MERR1 (1 << 1) /* Master 1 Access Error */ +# define MATRIX_MEINT_MERR2 (1 << 2) /* Master 2 Access Error */ +# define MATRIX_MEINT_MERR3 (1 << 3) /* Master 3 Access Error */ +# define MATRIX_MEINT_MERR4 (1 << 4) /* Master 4 Access Error */ +# define MATRIX_MEINT_MERR5 (1 << 5) /* Master 5 Access Error */ +# define MATRIX_MEINT_MERR6 (1 << 6) /* Master 6 Access Error */ +# define MATRIX_MEINT_MERR7 (1 << 7) /* Master 7 Access Error */ +# define MATRIX_MEINT_MERR8 (1 << 8) /* Master 8 Access Error */ +# define MATRIX_MEINT_MERR9 (1 << 9) /* Master 9 Access Error */ + +# ifdef ATSAMA5D2 +# define MATRIX_MEINT_MERR10 (1 << 10) /* Master 10 Access Error */ +# define MATRIX_MEINT_MERR11 (1 << 11) /* Master 11 Access Error */ +# endif + +/* Master 0-9 Error Address Register (32-bit addresses) */ +#endif + +/* Write Protect Mode Register */ + +#define MATRIX_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define MATRIX_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (Write-only) */ +#define MATRIX_WPMR_WPKEY_MASK (0x00ffffff << MATRIX_WPMR_WPKEY_SHIFT) +# define MATRIX_WPMR_WPKEY (0x004d4154 << MATRIX_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define MATRIX_WPSR_WPVS (1 << 0) /* Bit 0: Enable Write Protect */ +#define MATRIX_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define MATRIX_WPSR_WPVSRC_MASK (0xffff << MATRIX_WPSR_WPVSRC_SHIFT) + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* Security Slave 0-12 Registers */ + +# define MATRIX_SSR_LANSECH_SHIFT(n) (0) /* Bits 0-7: Low Area Not Secured in HSELn Security Region, n=0..7 */ +# define MATRIX_SSR_LANSECH_MASK(n) (0xff << MATRIX_SSR_LANSECH_SHIFT(n)) +# define MATRIX_SSR_LANSECH(n) (1 << (n)) +# define MATRIX_SSR_LANSECH0 (1 << 0) /* Bit 0: Low Area Not Secured in HSEL0 Security Region */ +# define MATRIX_SSR_LANSECH1 (1 << 1) /* Bit 1: Low Area Not Secured in HSEL1 Security Region */ +# define MATRIX_SSR_LANSECH2 (1 << 2) /* Bit 2: Low Area Not Secured in HSEL2 Security Region */ +# define MATRIX_SSR_LANSECH3 (1 << 3) /* Bit 3: Low Area Not Secured in HSEL3 Security Region */ +# define MATRIX_SSR_LANSECH4 (1 << 4) /* Bit 4: Low Area Not Secured in HSEL4 Security Region */ +# define MATRIX_SSR_LANSECH5 (1 << 5) /* Bit 5: Low Area Not Secured in HSEL5 Security Region */ +# define MATRIX_SSR_LANSECH6 (1 << 6) /* Bit 6: Low Area Not Secured in HSEL6 Security Region */ +# define MATRIX_SSR_LANSECH7 (1 << 7) /* Bit 7: Low Area Not Secured in HSEL7 Security Region */ +# define MATRIX_SSR_RDNSECH_SHIFT(n) (8) /* Bits 8-15: Read Not Secured for HSELn Security Region, n=0..7 */ +# define MATRIX_SSR_RDNSECH_MASK(n) (0xff << MATRIX_SSR_RDNSECH_SHIFT(n)) +# define MATRIX_SSR_RDNSECH(n) (1 << ((n)+ 8)) +# define MATRIX_SSR_RDNSECH0 (1 << 8) /* Bit 8: Read Not Secured for HSEL0 Security Region */ +# define MATRIX_SSR_RDNSECH1 (1 << 9) /* Bit 9: Read Not Secured for HSEL1 Security Region */ +# define MATRIX_SSR_RDNSECH2 (1 << 10) /* Bit 10: Read Not Secured for HSEL2 Security Region */ +# define MATRIX_SSR_RDNSECH3 (1 << 11) /* Bit 11: Read Not Secured for HSEL3 Security Region */ +# define MATRIX_SSR_RDNSECH4 (1 << 12) /* Bit 12: Read Not Secured for HSEL4 Security Region */ +# define MATRIX_SSR_RDNSECH5 (1 << 13) /* Bit 13: Read Not Secured for HSEL5 Security Region */ +# define MATRIX_SSR_RDNSECH6 (1 << 14) /* Bit 14: Read Not Secured for HSEL6 Security Region */ +# define MATRIX_SSR_RDNSECH7 (1 << 15) /* Bit 15: Read Not Secured for HSEL7 Security Region */ +# define MATRIX_SSR_WRNSECH_SHIFT(n) (16) /* Bit 16-23: Write Not Secured for HSELn Security Region, n=0..7 */ +# define MATRIX_SSR_WRNSECH_MASK(n) (0xff << MATRIX_SSR_WRNSECH_SHIFT(n)) +# define MATRIX_SSR_WRNSECH(n) (1 << ((n)+ 16)) +# define MATRIX_SSR_WRNSECH0 (1 << 16) /* Bit 16: Write Not Secured for HSEL0 Security Region */ +# define MATRIX_SSR_WRNSECH1 (1 << 17) /* Bit 17: Write Not Secured for HSEL1 Security Region */ +# define MATRIX_SSR_WRNSECH2 (1 << 18) /* Bit 18: Write Not Secured for HSEL2 Security Region */ +# define MATRIX_SSR_WRNSECH3 (1 << 19) /* Bit 19: Write Not Secured for HSEL3 Security Region */ +# define MATRIX_SSR_WRNSECH4 (1 << 20) /* Bit 20: Write Not Secured for HSEL4 Security Region */ +# define MATRIX_SSR_WRNSECH5 (1 << 21) /* Bit 21: Write Not Secured for HSEL5 Security Region */ +# define MATRIX_SSR_WRNSECH6 (1 << 22) /* Bit 22: Write Not Secured for HSEL6 Security Region */ +# define MATRIX_SSR_WRNSECH7 (1 << 23) /* Bit 23: Write Not Secured for HSEL7 Security Region */ + +/* Security Areas Split Slave 1-12 Registers */ + +# define SASSR_SASPLIT_4KB 0 /* 0x00001000 4 Kbytes */ +# define SASSR_SASPLIT_8KB 1 /* 0x00002000 8 Kbytes */ +# define SASSR_SASPLIT_16KB 2 /* 0x00004000 16 Kbytes */ +# define SASSR_SASPLIT_32KB 3 /* 0x00008000 32 Kbytes */ +# define SASSR_SASPLIT_64KB 4 /* 0x00010000 64 Kbytes */ +# define SASSR_SASPLIT_128KB 5 /* 0x00020000 128 Kbytes */ +# define SASSR_SASPLIT_256KB 6 /* 0x00040000 256 Kbytes */ +# define SASSR_SASPLIT_512KB 7 /* 0x00080000 512 Kbytes */ +# define SASSR_SASPLIT_1MB 8 /* 0x00100000 1 Mbyte */ +# define SASSR_SASPLIT_2MB 9 /* 0x00200000 2 Mbytes */ +# define SASSR_SASPLIT_4MB 10 /* 0x00400000 4 Mbytes */ +# define SASSR_SASPLIT_8MB 11 /* 0x00800000 8 Mbytes */ +# define SASSR_SASPLIT_16MB 12 /* 0x01000000 16 Mbytes */ +# define SASSR_SASPLIT_32MB 13 /* 0x02000000 32 Mbytes */ +# define SASSR_SASPLIT_64MB 14 /* 0x04000000 64 Mbytes */ +# define SASSR_SASPLIT_128MB 15 /* 0x08000000 128 Mbytes */ + +# define MATRIX_SASSR_SASPLIT_SHIFT(n) ((n) << 4) /* Security Areas Split for HSELn Security Region, n=0..7 */ +# define MATRIX_SASSR_SASPLIT_MASK(n) (15 << MATRIX_SASSR_SASPLIT_SHIFT(n)) +# define MATRIX_SASSR_SASPLIT(n,v) ((uint32_t)(v) << MATRIX_SASSR_SASPLIT_SHIFT(n)) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT0_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT0_MASK (15 << MATRIX_SASSR_SASPLIT0_SHIFT) +# define MATRIX_SASSR_SASPLIT0(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT0_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT1_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT1_MASK (15 << MATRIX_SASSR_SASPLIT1_SHIFT) +# define MATRIX_SASSR_SASPLIT1(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT1_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT2_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT2_MASK (15 << MATRIX_SASSR_SASPLIT2_SHIFT) +# define MATRIX_SASSR_SASPLIT2(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT2_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT3_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT3_MASK (15 << MATRIX_SASSR_SASPLIT3_SHIFT) +# define MATRIX_SASSR_SASPLIT3(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT3_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT4_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT4_MASK (15 << MATRIX_SASSR_SASPLIT4_SHIFT) +# define MATRIX_SASSR_SASPLIT4(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT4_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT5_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT5_MASK (15 << MATRIX_SASSR_SASPLIT5_SHIFT) +# define MATRIX_SASSR_SASPLIT5(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT5_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT6_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT6_MASK (15 << MATRIX_SASSR_SASPLIT6_SHIFT) +# define MATRIX_SASSR_SASPLIT6(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT6_SHIFT) /* See definitions above */ +# define MATRIX_SASSR_SASPLIT7_SHIFT (0) /* Bits 0-3: Security Areas Split for HSEL0 Security Region */ +# define MATRIX_SASSR_SASPLIT7_MASK (15 << MATRIX_SASSR_SASPLIT7_SHIFT) +# define MATRIX_SASSR_SASPLIT7(n) ((uint32_t)(n) << MATRIX_SASSR_SASPLIT7_SHIFT) /* See definitions above */ + +/* Security Region Top Slave 1-12 Register */ + +# define SRTSR_SRTOP_4KB 0 /* 0x00001000 4 Kbytes */ +# define SRTSR_SRTOP_8KB 1 /* 0x00002000 8 Kbytes */ +# define SRTSR_SRTOP_16KB 2 /* 0x00004000 16 Kbytes */ +# define SRTSR_SRTOP_32KB 3 /* 0x00008000 32 Kbytes */ +# define SRTSR_SRTOP_64KB 4 /* 0x00010000 64 Kbytes */ +# define SRTSR_SRTOP_128KB 5 /* 0x00020000 128 Kbytes */ +# define SRTSR_SRTOP_256KB 6 /* 0x00040000 256 Kbytes */ +# define SRTSR_SRTOP_512KB 7 /* 0x00080000 512 Kbytes */ +# define SRTSR_SRTOP_1MB 8 /* 0x00100000 1 Mbyte */ +# define SRTSR_SRTOP_2MB 9 /* 0x00200000 2 Mbytes */ +# define SRTSR_SRTOP_4MB 10 /* 0x00400000 4 Mbytes */ +# define SRTSR_SRTOP_8MB 11 /* 0x00800000 8 Mbytes */ +# define SRTSR_SRTOP_16MB 12 /* 0x01000000 16 Mbytes */ +# define SRTSR_SRTOP_32MB 13 /* 0x02000000 32 Mbytes */ +# define SRTSR_SRTOP_64MB 14 /* 0x04000000 64 Mbytes */ +# define SRTSR_SRTOP_128MB 15 /* 0x08000000 128 Mbytes */ + +# define MATRIX_SRTSR_SRTOP_SHIFT(n) ((n) << 4) /* HSELn Security Region Top, n=0..7 */ +# define MATRIX_SRTSR_SRTOP_MASK(n) (15 << MATRIX_SRTSR_SRTOP_SHIFT(n)) +# define MATRIX_SRTSR_SRTOP(n,v) ((uint32_t)(v) << MATRIX_SRTSR_SRTOP_SHIFT(n)) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP0_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP0_MASK (15 << MATRIX_SRTSR_SRTOP0_SHIFT) +# define MATRIX_SRTSR_SRTOP0(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP0_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP1_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP1_MASK (15 << MATRIX_SRTSR_SRTOP1_SHIFT) +# define MATRIX_SRTSR_SRTOP1(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP1_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP2_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP2_MASK (15 << MATRIX_SRTSR_SRTOP2_SHIFT) +# define MATRIX_SRTSR_SRTOP2(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP2_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP3_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP3_MASK (15 << MATRIX_SRTSR_SRTOP3_SHIFT) +# define MATRIX_SRTSR_SRTOP3(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP3_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP4_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP4_MASK (15 << MATRIX_SRTSR_SRTOP4_SHIFT) +# define MATRIX_SRTSR_SRTOP4(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP4_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP5_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP5_MASK (15 << MATRIX_SRTSR_SRTOP5_SHIFT) +# define MATRIX_SRTSR_SRTOP5(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP5_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP6_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP6_MASK (15 << MATRIX_SRTSR_SRTOP6_SHIFT) +# define MATRIX_SRTSR_SRTOP6(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP6_SHIFT) /* See definitions above */ +# define MATRIX_SRTSR_SRTOP7_SHIFT (0) /* Bits 0-3: HSEL0 Security Region Top */ +# define MATRIX_SRTSR_SRTOP7_MASK (15 << MATRIX_SRTSR_SRTOP7_SHIFT) +# define MATRIX_SRTSR_SRTOP7(n) ((uint32_t)(n) << MATRIX_SRTSR_SRTOP7_SHIFT) /* See definitions above */ + +/* Security Peripheral Select 1 Register */ + +# define MATRIX_SPSELR1_NSECP(n) (1 << (n)) /* PID n Not Secured Peripheral, n=0-31 */ + +/* Security Peripheral Select 2 Register */ + +# define MATRIX_SPSELR2_NSECP(n) (1 << ((n)-32)) /* PID n Not Secured Peripheral, n=32-63 */ + +/* Security Peripheral Select 3 Register */ + +# define MATRIX_SPSELR3_NSECP(n) (1 << ((n)-64)) /* PID n Not Secured Peripheral, n=64-96 */ +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MATRIX_H */ diff --git a/arch/arm/src/sama5/chip/sam_memorymap.h b/arch/arm/src/sama5/chip/sam_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..73ecf13aecd139418c8dedfb856a40306d835edc --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_memorymap.h @@ -0,0 +1,56 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_memorymap.h + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(ATSAMA5D2) +# include "chip/_sama5d2x_memorymap.h" +#elif defined(ATSAMA5D3) +# include "chip/_sama5d3x_memorymap.h" +#elif defined(ATSAMA5D4) +# include "chip/_sama5d4x_memorymap.h" +#else +# error Unrecognized SAMA5 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MEMORYMAP_H */ diff --git a/arch/arm/src/sama5/chip/sam_mpddrc.h b/arch/arm/src/sama5/chip/sam_mpddrc.h new file mode 100644 index 0000000000000000000000000000000000000000..06b217d8aaa5ea4bec505c1fc61b8645f181abab --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_mpddrc.h @@ -0,0 +1,54 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_mpddrc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MPDDRC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MPDDRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(ATSAMA5D3) +# include "chip/_sama5d3x_mpddrc.h" +#elif defined(ATSAMA5D4) +# include "chip/_sama5d4x_mpddrc.h" +#else +# error Unrecognized SAMA5 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_MPDDRC_H */ diff --git a/arch/arm/src/sama5/chip/sam_ohci.h b/arch/arm/src/sama5/chip/sam_ohci.h new file mode 100644 index 0000000000000000000000000000000000000000..4d3681de39e8475120e89847a942315f83bc9925 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_ohci.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/arm/src/sama5/chip/sam_ohci.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_OHCI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_OHCI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The SAMA5 supports 3 root hub ports */ + +#define SAM_OHCI_NRHPORT 3 + +/* Register offsets *********************************************************/ +/* See nuttx/usb/ohci.h */ + +/* Register addresses *******************************************************/ + +#define SAM_USBHOST_HCIREV (SAM_UHPOHCI_VSECTION+OHCI_HCIREV_OFFSET) +#define SAM_USBHOST_CTRL (SAM_UHPOHCI_VSECTION+OHCI_CTRL_OFFSET) +#define SAM_USBHOST_CMDST (SAM_UHPOHCI_VSECTION+OHCI_CMDST_OFFSET) +#define SAM_USBHOST_INTST (SAM_UHPOHCI_VSECTION+OHCI_INTST_OFFSET) +#define SAM_USBHOST_INTEN (SAM_UHPOHCI_VSECTION+OHCI_INTEN_OFFSET) +#define SAM_USBHOST_INTDIS (SAM_UHPOHCI_VSECTION+OHCI_INTDIS_OFFSET) + +/* Memory pointers (section 7.2) */ + +#define SAM_USBHOST_HCCA (SAM_UHPOHCI_VSECTION+OHCI_HCCA_OFFSET) +#define SAM_USBHOST_PERED (SAM_UHPOHCI_VSECTION+OHCI_PERED_OFFSET) +#define SAM_USBHOST_CTRLHEADED (SAM_UHPOHCI_VSECTION+OHCI_CTRLHEADED_OFFSET) +#define SAM_USBHOST_CTRLED (SAM_UHPOHCI_VSECTION+OHCI_CTRLED_OFFSET) +#define SAM_USBHOST_BULKHEADED (SAM_UHPOHCI_VSECTION+OHCI_BULKHEADED_OFFSET) +#define SAM_USBHOST_BULKED (SAM_UHPOHCI_VSECTION+OHCI_BULKED_OFFSET) +#define SAM_USBHOST_DONEHEAD (SAM_UHPOHCI_VSECTION+OHCI_DONEHEAD_OFFSET) + +/* Frame counters (section 7.3) */ + +#define SAM_USBHOST_FMINT (SAM_UHPOHCI_VSECTION+OHCI_FMINT_OFFSET) +#define SAM_USBHOST_FMREM (SAM_UHPOHCI_VSECTION+OHCI_FMREM_OFFSET) +#define SAM_USBHOST_FMNO (SAM_UHPOHCI_VSECTION+OHCI_FMNO_OFFSET) +#define SAM_USBHOST_PERSTART (SAM_UHPOHCI_VSECTION+OHCI_PERSTART_OFFSET) + +/* Root hub ports (section 7.4) */ + +#define SAM_USBHOST_LSTHRES (SAM_UHPOHCI_VSECTION+OHCI_LSTHRES_OFFSET) +#define SAM_USBHOST_RHDESCA (SAM_UHPOHCI_VSECTION+OHCI_RHDESCA_OFFSET) +#define SAM_USBHOST_RHDESCB (SAM_UHPOHCI_VSECTION+OHCI_RHDESCB_OFFSET) +#define SAM_USBHOST_RHSTATUS (SAM_UHPOHCI_VSECTION+OHCI_RHSTATUS_OFFSET) + +#define SAM_USBHOST_RHPORTST(n) (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST_OFFSET(n)) +#define SAM_USBHOST_RHPORTST1 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST1_OFFSET) +#define SAM_USBHOST_RHPORTST2 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST2_OFFSET) +#define SAM_USBHOST_RHPORTST3 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST3_OFFSET) + +/* Register bit definitions *************************************************/ +/* See include/nuttx/usb/ohci.h */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_OHCI_H */ diff --git a/arch/arm/src/sama5/chip/sam_pinmap.h b/arch/arm/src/sama5/chip/sam_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..461fb1f545b8dee9372e7fa01962012463a7ccd8 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_pinmap.h @@ -0,0 +1,56 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_pinmap.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PINMAP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(ATSAMA5D2) +# include "chip/_sama5d2x_pinmap.h" +#elif defined(ATSAMA5D3) +# include "chip/_sama5d3x_pinmap.h" +#elif defined(ATSAMA5D4) +# include "chip/_sama5d4x_pinmap.h" +#else +# error Unrecognized SAMA5 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PINMAP_H */ diff --git a/arch/arm/src/sama5/chip/sam_pio.h b/arch/arm/src/sama5/chip/sam_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..7a37fe6cfa0e188584df460469347c98b76eca93 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_pio.h @@ -0,0 +1,54 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_pio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIO_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(ATSAMA5D2) +# include "chip/_sama5d2x_pio.h" +#elif defined(ATSAMA5D3) || defined(ATSAMA5D4) +# include "chip/_sama5d3x4x_pio.h" +#else +# error Unrecognized SAMA5 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIO_H */ diff --git a/arch/arm/src/sama5/chip/sam_pit.h b/arch/arm/src/sama5/chip/sam_pit.h new file mode 100644 index 0000000000000000000000000000000000000000..1f93f4b75cc8e08891ba0cda67f0a05fb7ee0882 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_pit.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_pit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIT_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* PIT Register Offsets *************************************************************/ + +#define SAM_PIT_MR_OFFSET 0x0000 /* Mode Register */ +#define SAM_PIT_SR_OFFSET 0x0004 /* Status Register */ +#define SAM_PIT_PIVR_OFFSET 0x0008 /* Periodic Interval Value Register */ +#define SAM_PIT_PIIR_OFFSET 0x000c /* Periodic Interval Image Register */ + +/* PIT Register Addresses ***********************************************************/ + +#define SAM_PIT_MR (SAM_PITC_VBASE+SAM_PIT_MR_OFFSET) +#define SAM_PIT_SR (SAM_PITC_VBASE+SAM_PIT_SR_OFFSET) +#define SAM_PIT_PIVR (SAM_PITC_VBASE+SAM_PIT_PIVR_OFFSET) +#define SAM_PIT_PIIR (SAM_PITC_VBASE+SAM_PIT_PIIR_OFFSET) + +/* PIT Register Bit Definitions *****************************************************/ + +/* Mode Register */ + +#define PIT_MR_PIV_SHIFT (0) /* Bits 0-19: Periodic Interval Value */ +#define PIT_MR_PIV_MASK (0x000fffff) +# define PIT_MR_PIV(n) (n) +#define PIT_MR_PITEN (1 << 24) /* Bit 24: Period Interval Timer Enable */ +#define PIT_MR_PITIEN (1 << 25) /* Bit 25: Periodic Interval Timer Interrupt Enable */ + +/* Status Register */ + +#define PIT_SR_S (1 << 0) /* Bit 0: Periodic Interval Timer Status */ + +/* Periodic Interval Value Register */ +/* Periodic Interval Image Register */ + +#define PIT_CPIV_SHIFT (0) /* Bits 0-19: Current Periodic Interval Value */ +#define PIT_CPIV_MASK (0x000fffff) +#define PIT_PICNT_SHIFT (20) /* Bits 20-31: Periodic Interval Counter */ +#define PIT_PICNT_MASK (0xfff << PIT_PIVR_PICNT_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PIT_H */ diff --git a/arch/arm/src/sama5/chip/sam_pmc.h b/arch/arm/src/sama5/chip/sam_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..abe06ed86b1f5762e77774031797a5a94e6b787a --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_pmc.h @@ -0,0 +1,683 @@ +/******************************************************************************************** + * arch/arm/src/sama5/chip/sam_pmc.h + * Power Management Controller (PMC) for the SAMA5 + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PMC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PMC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* PMC register offsets *********************************************************************/ + +#define SAM_PMC_SCER_OFFSET 0x0000 /* System Clock Enable Register */ +#define SAM_PMC_SCDR_OFFSET 0x0004 /* System Clock Disable Register */ +#define SAM_PMC_SCSR_OFFSET 0x0008 /* System Clock Status Register */ + /* 0x000c: Reserved */ +#define SAM_PMC_PCER0_OFFSET 0x0010 /* Peripheral Clock Enable Register 0 */ +#define SAM_PMC_PCDR0_OFFSET 0x0014 /* Peripheral Clock Disable Register 0 */ +#define SAM_PMC_PCSR0_OFFSET 0x0018 /* Peripheral Clock Status Register 0 */ +#define SAM_PMC_CKGR_UCKR_OFFSET 0x001c /* UTMI Clock Register */ +#define SAM_PMC_CKGR_MOR_OFFSET 0x0020 /* Main Oscillator Register */ +#define SAM_PMC_CKGR_MCFR_OFFSET 0x0024 /* Main Clock Frequency Register */ +#define SAM_PMC_CKGR_PLLAR_OFFSET 0x0028 /* PLLA Register */ + /* 0x002c: Reserved */ +#define SAM_PMC_MCKR_OFFSET 0x0030 /* Master Clock Register */ + /* 0x0034: Reserved */ +#define SAM_PMC_USB_OFFSET 0x0038 /* USB Clock Register */ + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define SAM_PMC_SMD_OFFSET 0x003c /* Soft Modem Clock Register */ +#endif + +#define SAM_PMC_PCK0_OFFSET 0x0040 /* Programmable Clock 0 Register */ +#define SAM_PMC_PCK1_OFFSET 0x0044 /* Programmable Clock 1 Register */ +#define SAM_PMC_PCK2_OFFSET 0x0048 /* Programmable Clock 2 Register */ + /* 0x004c-0x005c: Reserved */ +#define SAM_PMC_IER_OFFSET 0x0060 /* Interrupt Enable Register */ +#define SAM_PMC_IDR_OFFSET 0x0064 /* Interrupt Disable Register */ +#define SAM_PMC_SR_OFFSET 0x0068 /* Status Register */ +#define SAM_PMC_IMR_OFFSET 0x006c /* Interrupt Mask Register */ + +#ifdef ATSAMA5D2 +# define SAM_PMC_FSMR_OFFSET 0x0070 /* Fast Startup Mode Register */ +# define SAM_PMC_FSPR_OFFSET 0x0074 /* Fast Startup Polarity Register */ +#endif + +#define SAM_PMC_FOCR_OFFSET 0x0078 /* Fault Output Clear Register */ + /* 0x007c: Reserved */ +#define SAM_PMC_PLLICPR_OFFSET 0x0080 /* PLL Charge Pump Current Register */ + /* 0x0084-0x00e0: Reserved */ +#define SAM_PMC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PMC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00fc: Reserved */ +#define SAM_PMC_PCER1_OFFSET 0x0100 /* Peripheral Clock Enable Register 1 */ +#define SAM_PMC_PCDR1_OFFSET 0x0104 /* Peripheral Clock Disable Register 1 */ +#define SAM_PMC_PCSR1_OFFSET 0x0108 /* Peripheral Clock Status Register 1 */ +#define SAM_PMC_PCR_OFFSET 0x010c /* Peripheral Control Register */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAM_PMC_OCR_OFFSET 0x0110 /* Oscillator Calibration Register */ +#endif + +#ifdef ATSAMA5D2 +# define SAM_PMC_SLPWK_ER0_OFFSET 0x0114 /* SleepWalking Enable Register 0 */ +# define SAM_PMC_SLPWK_DR0_OFFSET 0x0118 /* SleepWalking Disable Register 0 */ +# define SAM_PMC_SLPWK_SR0_OFFSET 0x011c /* SleepWalking Status Register 0 */ +# define SAM_PMC_SLPWK_ASR0_OFFSET 0x0120 /* SleepWalking Activity Status Register 0 */ + /* 0x0124-0x0130: Reserved */ +# define SAM_PMC_SLPWK_ER1_OFFSET 0x0134 /* SleepWalking Enable Register 1 */ +# define SAM_PMC_SLPWK_DR1_OFFSET 0x0138 /* SleepWalking Disable Register 1 */ +# define SAM_PMC_SLPWK_SR1_OFFSET 0x013c /* SleepWalking Status Register 1 */ +# define SAM_PMC_SLPWK_ASR1_OFFSET 0x0140 /* SleepWalking Activity Status Register 1 */ +# define SAM_PMC_SLPWK_AIPR_OFFSET 0x0144 /* SleepWalking Activity In Progress Register */ +# define SAM_PMC_SLPWKCR_OFFSET 0x0148 /* SleepWalking Control Register */ +# define SAM_PMC_AUDIO_PLL0_OFFSET 0x014c /* Audio PLL Register 0 */ +# define SAM_PMC_AUDIO_PLL1_OFFSET 0x0150 /* Audio PLL Register 1 */ +#endif + +/* PMC register addresses *******************************************************************/ + +#define SAM_PMC_SCER (SAM_PMC_VBASE+SAM_PMC_SCER_OFFSET) +#define SAM_PMC_SCDR (SAM_PMC_VBASE+SAM_PMC_SCDR_OFFSET) +#define SAM_PMC_SCSR (SAM_PMC_VBASE+SAM_PMC_SCSR_OFFSET) +#define SAM_PMC_PCER0 (SAM_PMC_VBASE+SAM_PMC_PCER0_OFFSET) +#define SAM_PMC_PCDR0 (SAM_PMC_VBASE+SAM_PMC_PCDR0_OFFSET) +#define SAM_PMC_PCSR0 (SAM_PMC_VBASE+SAM_PMC_PCSR0_OFFSET) +#define SAM_PMC_CKGR_UCKR (SAM_PMC_VBASE+SAM_PMC_CKGR_UCKR_OFFSET) +#define SAM_PMC_CKGR_MOR (SAM_PMC_VBASE+SAM_PMC_CKGR_MOR_OFFSET) +#define SAM_PMC_CKGR_MCFR (SAM_PMC_VBASE+SAM_PMC_CKGR_MCFR_OFFSET) +#define SAM_PMC_CKGR_PLLAR (SAM_PMC_VBASE+SAM_PMC_CKGR_PLLAR_OFFSET) +#define SAM_PMC_MCKR (SAM_PMC_VBASE+SAM_PMC_MCKR_OFFSET) +#define SAM_PMC_USB (SAM_PMC_VBASE+SAM_PMC_USB_OFFSET) + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define SAM_PMC_SMD (SAM_PMC_VBASE+SAM_PMC_SMD_OFFSET) +#endif + +#define SAM_PMC_PCK0 (SAM_PMC_VBASE+SAM_PMC_PCK0_OFFSET) +#define SAM_PMC_PCK1 (SAM_PMC_VBASE+SAM_PMC_PCK1_OFFSET) +#define SAM_PMC_PCK2 (SAM_PMC_VBASE+SAM_PMC_PCK2_OFFSET) +#define SAM_PMC_IER (SAM_PMC_VBASE+SAM_PMC_IER_OFFSET) +#define SAM_PMC_IDR (SAM_PMC_VBASE+SAM_PMC_IDR_OFFSET) +#define SAM_PMC_SR (SAM_PMC_VBASE+SAM_PMC_SR_OFFSET) +#define SAM_PMC_IMR (SAM_PMC_VBASE+SAM_PMC_IMR_OFFSET) + +#ifdef ATSAMA5D2 +# define SAM_PMC_FSMR (SAM_PMC_VBASE+SAM_PMC_FSMR_OFFSET) +# define SAM_PMC_FSPR (SAM_PMC_VBASE+SAM_PMC_FSPR_OFFSET) +#endif + +#define SAM_PMC_FOCR (SAM_PMC_VBASE+SAM_PMC_FOCR_OFFSET) +#define SAM_PMC_PLLICPR (SAM_PMC_VBASE+SAM_PMC_PLLICPR_OFFSET) +#define SAM_PMC_WPMR (SAM_PMC_VBASE+SAM_PMC_WPMR_OFFSET) +#define SAM_PMC_WPSR (SAM_PMC_VBASE+SAM_PMC_WPSR_OFFSET) +#define SAM_PMC_PCER1 (SAM_PMC_VBASE+SAM_PMC_PCER1_OFFSET) +#define SAM_PMC_PCDR1 (SAM_PMC_VBASE+SAM_PMC_PCDR1_OFFSET) +#define SAM_PMC_PCSR1 (SAM_PMC_VBASE+SAM_PMC_PCSR1_OFFSET) +#define SAM_PMC_PCR (SAM_PMC_VBASE+SAM_PMC_PCR_OFFSET) + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAM_PMC_OCR (SAM_PMC_VBASE+SAM_PMC_OCR_OFFSET) +#endif + +#ifdef ATSAMA5D2 +# define SAM_PMC_SLPWK_ER0 (SAM_PMC_VBASE+SAM_PMC_SLPWK_ER0_OFFSET) +# define SAM_PMC_SLPWK_DR0 (SAM_PMC_VBASE+SAM_PMC_SLPWK_DR0_OFFSET) +# define SAM_PMC_SLPWK_SR0 (SAM_PMC_VBASE+SAM_PMC_SLPWK_SR0_OFFSET) +# define SAM_PMC_SLPWK_ASR0 (SAM_PMC_VBASE+SAM_PMC_SLPWK_ASR0_OFFSET) +# define SAM_PMC_SLPWK_ER1 (SAM_PMC_VBASE+SAM_PMC_SLPWK_ER1_OFFSET) +# define SAM_PMC_SLPWK_DR1 (SAM_PMC_VBASE+SAM_PMC_SLPWK_DR1_OFFSET) +# define SAM_PMC_SLPWK_SR1 (SAM_PMC_VBASE+SAM_PMC_SLPWK_SR1_OFFSET) +# define SAM_PMC_SLPWK_ASR1 (SAM_PMC_VBASE+SAM_PMC_SLPWK_ASR1_OFFSET) +# define SAM_PMC_SLPWK_AIPR (SAM_PMC_VBASE+SAM_PMC_SLPWK_AIPR_OFFSET) +# define SAM_PMC_SLPWKCR (SAM_PMC_VBASE+SAM_PMC_SLPWKCR_OFFSET) +# define SAM_PMC_AUDIO_PLL0 (SAM_PMC_VBASE+SAM_PMC_AUDIO_PLL0_OFFSET) +# define SAM_PMC_AUDIO_PLL1 (SAM_PMC_VBASE+SAM_PMC_AUDIO_PLL1_OFFSET) +#endif + +/* PMC register bit definitions *************************************************************/ + +/* PMC System Clock Enable Register, PMC System Clock Disable Register, and PMC System + * Clock Status Register common bit-field definitions + */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define PMC_PCK (1 << 0) /* Bit 0: Processor Clock */ +#endif + +#define PMC_DDRCK (1 << 2) /* Bit 2: DDR Clock */ +#define PMC_LCDCK (1 << 3) /* Bit 3: LCD2x Clock */ + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define PMC_SMDCK (1 << 4) /* Bit 4: SMD Clock */ +#endif + +#define PMC_UHP (1 << 6) /* Bit 6: USB Host OHCI Clocks */ +#define PMC_UDP (1 << 7) /* Bit 7: USB Device Clock */ + +#define PMC_PCKN(n) (1 << ((int)(n) + 8)) +#define PMC_PCK0 (1 << 8) /* Bit 8: Programmable Clock 0 Output */ +#define PMC_PCK1 (1 << 9) /* Bit 9: Programmable Clock 1 Output */ +#define PMC_PCK2 (1 << 10) /* Bit 10: Programmable Clock 2 Output */ + +#ifdef ATSAMA5D2 +# define PMC_ISCCK (1 << 18) /* Bit 18: ISC Clock Enable */ +#endif + +/* PMC Peripheral Clock Enable Register, PMC Peripheral Clock Disable Register, and PMC + * Peripheral Clock Status Register common bit-field definitions. + */ + +#define PMC_PIDL(n) (1 << (n)) +# define PMC_PID2 (1 << 2) /* Bit 2: Peripheral Clock 2 Enable */ +# define PMC_PID3 (1 << 3) /* Bit 3: Peripheral Clock 3 Enable */ +# define PMC_PID4 (1 << 4) /* Bit 4: Peripheral Clock 4 Enable */ +# define PMC_PID5 (1 << 5) /* Bit 5: Peripheral Clock 5 Enable */ +# define PMC_PID6 (1 << 6) /* Bit 6: Peripheral Clock 6 Enable */ +# define PMC_PID7 (1 << 7) /* Bit 7: Peripheral Clock 7 Enable */ +# define PMC_PID8 (1 << 8) /* Bit 8: Peripheral Clock 8 Enable */ +# define PMC_PID9 (1 << 9) /* Bit 9: Peripheral Clock 9 Enable */ +# define PMC_PID10 (1 << 10) /* Bit 10: Peripheral Clock 10 Enable */ +# define PMC_PID11 (1 << 11) /* Bit 11: Peripheral Clock 11 Enable */ +# define PMC_PID12 (1 << 12) /* Bit 12: Peripheral Clock 12 Enable */ +# define PMC_PID13 (1 << 13) /* Bit 13: Peripheral Clock 13 Enable */ +# define PMC_PID14 (1 << 14) /* Bit 14: Peripheral Clock 14 Enable */ +# define PMC_PID15 (1 << 15) /* Bit 15: Peripheral Clock 15 Enable */ +# define PMC_PID16 (1 << 16) /* Bit 16: Peripheral Clock 16 Enable */ +# define PMC_PID17 (1 << 17) /* Bit 17: Peripheral Clock 17 Enable */ +# define PMC_PID18 (1 << 18) /* Bit 18: Peripheral Clock 18 Enable */ +# define PMC_PID19 (1 << 19) /* Bit 19: Peripheral Clock 19 Enable */ +# define PMC_PID20 (1 << 20) /* Bit 20: Peripheral Clock 20 Enable */ +# define PMC_PID21 (1 << 21) /* Bit 21: Peripheral Clock 21 Enable */ +# define PMC_PID22 (1 << 22) /* Bit 22: Peripheral Clock 22 Enable */ +# define PMC_PID23 (1 << 23) /* Bit 23: Peripheral Clock 23 Enable */ +# define PMC_PID24 (1 << 24) /* Bit 24: Peripheral Clock 24 Enable */ +# define PMC_PID25 (1 << 25) /* Bit 25: Peripheral Clock 25 Enable */ +# define PMC_PID26 (1 << 26) /* Bit 26: Peripheral Clock 26 Enable */ +# define PMC_PID27 (1 << 27) /* Bit 27: Peripheral Clock 27 Enable */ +# define PMC_PID28 (1 << 28) /* Bit 28: Peripheral Clock 28 Enable */ +# define PMC_PID29 (1 << 29) /* Bit 29: Peripheral Clock 29 Enable */ +# define PMC_PID30 (1 << 30) /* Bit 30: Peripheral Clock 30 Enable */ +# define PMC_PID31 (1 << 31) /* Bit 31: Peripheral Clock 31 Enable */ + +/* PMC UTMI Clock Configuration Register */ + +#define PMC_CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */ +#define PMC_CKGR_UCKR_UPLLCOUNT_SHIFT (20) /* Bits 20-23: UTMI PLL Start-up Time */ +#define PMC_CKGR_UCKR_UPLLCOUNT_MASK (15 << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) +# define PMC_CKGR_UCKR_UPLLCOUNT(n) ((n) << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) +#define PMC_CKGR_UCKR_BIASEN (1 << 24) /* Bit 24: UTMI BIAS Enable */ +#define PMC_CKGR_UCKR_BIASCOUNT_SHIFT (28) /* Bits 28-31: UTMI BIAS Start-up Time */ +#define PMC_CKGR_UCKR_BIASCOUNT_MASK (15 << PMC_CKGR_UCKR_BIASCOUNT_SHIFT) +# define PMC_CKGR_UCKR_BIASCOUNT(n) ((n) << PMC_CKGR_UCKR_BIASCOUNT_SHIFT) + +/* PMC Clock Generator Main Oscillator Register */ + +#define PMC_CKGR_MOR_MOSCXTEN (1 << 0) /* Bit 0: Main Crystal Oscillator Enable */ +#define PMC_CKGR_MOR_MOSCXTBY (1 << 1) /* Bit 1: Main Crystal Oscillator Bypass */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define PMC_CKGR_MOR_MOSCRCEN (1 << 3) /* Bit 3: Main On-Chip RC Oscillator Enable */ +#endif + +#define PMC_CKGR_MOR_MOSCXTST_SHIFT (8) /* Bits 8-15: Main Crystal Oscillator Start-up Time */ +#define PMC_CKGR_MOR_MOSCXTST_MASK (0xff << PMC_CKGR_MOR_MOSCXTST_SHIFT) +# define PMC_CKGR_MOR_MOSCXTST(n) ((uint32_t)(n) << PMC_CKGR_MOR_MOSCXTST_SHIFT) +#define PMC_CKGR_MOR_KEY_SHIFT (16) /* Bits 16-23: Password */ +#define PMC_CKGR_MOR_KEY_MASK (0xff << PMC_CKGR_MOR_KEY_SHIFT) +# define PMC_CKGR_MOR_KEY (0x37 << PMC_CKGR_MOR_KEY_SHIFT) +#define PMC_CKGR_MOR_MOSCSEL (1 << 24) /* Bit 24: Main Oscillator Selection */ +#define PMC_CKGR_MOR_CFDEN (1 << 25) /* Bit 25: Clock Failure Detector Enable */ + +#ifdef ATSAMA5D4 +# define PMC_CKGR_MOR_XT32KFME (1 << 26) /* Bit 26: Slow Crystal Oscillator Frequency Monitoring Enable */ +#endif + +/* PMC Clock Generator Main Clock Frequency Register */ + +#define PMC_CKGR_MCFR_MAINF_SHIFT (0) /* Bits 0-15: Main Clock Frequency */ +#define PMC_CKGR_MCFR_MAINF_MASK (0xffff << PMC_CKGR_MCFR_MAINF_SHIFT) +# define PMC_CKGR_MCFR_MAINF(n) ((uint32_t)(n) << PMC_CKGR_MCFR_MAINF_SHIFT) +#define PMC_CKGR_MCFR_MAINFRDY (1 << 16) /* Bit 16: Main Clock Ready */ +#define PMC_CKGR_MCFR_RCMEAS (1 << 20) /* Bit 20: RC Oscillator Frequency Measure (write-only) */ + +#ifdef ATSAMA5D2 +# define PMC_CKGR_MCFR_CCSS (1 << 24) /* Bit 24: Counter Clock Source Selection */ +# define PMC_CKGR_MCFR_CCSS_RCOSC (0) /* Bit 24: 0=MAINF clock is the RC osciallator */ +# define PMC_CKGR_MCFR_CCSS_XOSC (1 << 24) /* Bit 24: 1=MAINF clock is the crystal osciallator */ +#endif + +/* PMC Clock Generator PLLA Register */ + +#undef SAMA5_HAVE_PLLAR_DIV +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define PMC_CKGR_PLLAR_DIV_SHIFT (0) /* Bits 0-7: Divider */ +# define PMC_CKGR_PLLAR_DIV_MASK (0xff << PMC_CKGR_PLLAR_DIV_SHIFT) +# define PMC_CKGR_PLLAR_DIV_ZERO (0 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is 0 */ +# define PMC_CKGR_PLLAR_DIV_BYPASS (1 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider is bypassed (DIV=1) */ +# define PMC_CKGR_PLLAR_DIV(n) ((n) << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is DIV=n, n=2..255 */ +# define SAMA5_HAVE_PLLAR_DIV 1 + +/* According the preliminary documentation, there is no DIV field in the SAMA5D4 + * PLLAR register. However, through trial and error, I find that the PLL output + * is still disabled if the DIV field is set to zero. + */ + +#elif defined(ATSAMA5D4) +# define PMC_CKGR_PLLAR_DIV_BYPASS (1) /* Divider is bypassed (DIV=1) */ +#endif + +#define PMC_CKGR_PLLAR_COUNT_SHIFT (8) /* Bits 8-13: PLLA Counter */ +#define PMC_CKGR_PLLAR_COUNT_MASK (63 << PMC_CKGR_PLLAR_COUNT_SHIFT) +# define PMC_CKGR_PLLAR_COUNT(n) ((uint32_t)(n) << PMC_CKGR_PLLAR_COUNT_SHIFT) +#define PMC_CKGR_PLLAR_OUT_SHIFT (14) /* Bits 14-17: PLLA Clock Frequency Range */ +#define PMC_CKGR_PLLAR_OUT_MASK (15 << PMC_CKGR_PLLAR_OUT_SHIFT) +# define PMC_CKGR_PLLAR_OUT (0 << PMC_CKGR_PLLAR_OUT_SHIFT) /* To be programmed to 0 */ +#define PMC_CKGR_PLLAR_MUL_SHIFT (18) /* Bits 18-24: PLLA Multiplier */ +#define PMC_CKGR_PLLAR_MUL_MASK (0x7f << PMC_CKGR_PLLAR_MUL_SHIFT) +# define PMC_CKGR_PLLAR_MUL(n) ((uint32_t)(n) << PMC_CKGR_PLLAR_MUL_SHIFT) +#define PMC_CKGR_PLLAR_ONE (1 << 29) /* Bit 29: Always one */ + +/* PMC Master Clock Register */ + +#define PMC_MCKR_CSS_SHIFT (0) /* Bits 0-1: Master Clock Source Selection */ +#define PMC_MCKR_CSS_MASK (3 << PMC_MCKR_CSS_SHIFT) +# define PMC_MCKR_CSS_SLOW (0 << PMC_MCKR_CSS_SHIFT) /* Slow Clock */ +# define PMC_MCKR_CSS_MAIN (1 << PMC_MCKR_CSS_SHIFT) /* Main Clock */ +# define PMC_MCKR_CSS_PLLA (2 << PMC_MCKR_CSS_SHIFT) /* PLLA Clock */ +# define PMC_MCKR_CSS_UPLL (3 << PMC_MCKR_CSS_SHIFT) /* UPLL Clock */ +#define PMC_MCKR_PRES_SHIFT (4) /* Bits 4-6: Processor Clock Prescaler */ +#define PMC_MCKR_PRES_MASK (7 << PMC_MCKR_PRES_SHIFT) +# define PMC_MCKR_PRES_DIV1 (0 << PMC_MCKR_PRES_SHIFT) /* Selected clock */ +# define PMC_MCKR_PRES_DIV2 (1 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 2 */ +# define PMC_MCKR_PRES_DIV4 (2 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 4 */ +# define PMC_MCKR_PRES_DIV8 (3 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 8 */ +# define PMC_MCKR_PRES_DIV16 (4 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 16 */ +# define PMC_MCKR_PRES_DIV32 (5 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 32 */ +# define PMC_MCKR_PRES_DIV64 (6 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 64 */ +#define PMC_MCKR_MDIV_SHIFT (8) /* Bits 8-9: Master Clock Division */ +#define PMC_MCKR_MDIV_MASK (3 << PMC_MCKR_MDIV_SHIFT) +# define PMC_MCKR_MDIV_PCKDIV1 (0 << PMC_MCKR_MDIV_SHIFT) /* Prescaler Output Clock divided by 1 */ +# define PMC_MCKR_MDIV_PCKDIV2 (1 << PMC_MCKR_MDIV_SHIFT) /* Prescaler Output Clock divided by 2 */ +# define PMC_MCKR_MDIV_PCKDIV4 (2 << PMC_MCKR_MDIV_SHIFT) /* Prescaler Output Clock divided by 4 */ +# define PMC_MCKR_MDIV_PCKDIV3 (3 << PMC_MCKR_MDIV_SHIFT) /* Prescaler Output Clock divided by 3 */ +#define PMC_MCKR_PLLADIV2 (1 << 12) /* Bit 12: PLLA Divider */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define PMC_MCKR_H32MXDIV (1 << 24) /* Bit 24: AHB 32-bit Matrix Divisor */ +#endif + +/* USB Clock Register PMC_USB */ + +#define PMC_USB_USBS (1 << 0) /* Bit 0: USB Input Clock Selection */ +# define PMC_USB_USBS_PLLA (0) +# define PMC_USB_USBS_UPLL PMC_USB_USBS +#define PMC_USB_USBDIV_SHIFT (8) /* Bits 8-11: Divider for USB Clock */ +#define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT) +# define PMC_USB_USBDIV(a) ((a) << PMC_USB_USBDIV_SHIFT) + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +/* Soft Modem Clock Register */ + +# define PMC_SMD_SMDS (1 << 0) /* Bit 0: SMD Input Clock Selection */ +# define PMC_SMD_SMDS_PLLA (0) +# define PMC_SMD_SMDS_UPLL PMC_SMD_SMDS +# define PMC_SMD_SMDDIV_SHIFT (8) /* Bits 8-12: Divider for SMD Clock */ +# define PMC_SMD_SMDDIV_MASK (31 << PMC_SMD_SMDDIV_SHIFT) +#endif + +/* PMC Programmable Clock Register (0,1,2) */ + +#define PMC_PCK_CSS_SHIFT (0) /* Bits 0-2: Master Clock Source Selection */ +#define PMC_PCK_CSS_MASK (7 << PMC_PCK_CSS_SHIFT) +# define PMC_PCK_CSS_SLOW (0 << PMC_PCK_CSS_SHIFT) /* Slow Clock */ +# define PMC_PCK_CSS_MAIN (1 << PMC_PCK_CSS_SHIFT) /* Main Clock */ +# define PMC_PCK_CSS_PLLA (2 << PMC_PCK_CSS_SHIFT) /* PLLA Clock */ +# define PMC_PCK_CSS_UPLL (3 << PMC_PCK_CSS_SHIFT) /* UPLL Clock */ +# define PMC_PCK_CSS_MCK (4 << PMC_PCK_CSS_SHIFT) /* Master Clock */ + +#ifdef ATSAMA5D4 +# define PMC_PCK_CSS_AUDIO (5 << PMC_PCK_CSS_SHIFT) /* Audio PLL Clock */ +#endif + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# undef SAMA5_HAVE_PCK_INT_PRES /* Supports conditional compilation */ +# define PMC_PCK_PRES_SHIFT (4) /* Bits 4-6: Programmable Clock Prescaler */ +# define PMC_PCK_PRES_MASK (7 << PMC_PCK_PRES_SHIFT) +# define PMC_PCK_PRES_DIV1 (0 << PMC_PCK_PRES_SHIFT) /* Selected clock */ +# define PMC_PCK_PRES_DIV2 (1 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 2 */ +# define PMC_PCK_PRES_DIV4 (2 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 4 */ +# define PMC_PCK_PRES_DIV8 (3 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 8 */ +# define PMC_PCK_PRES_DIV16 (4 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 16 */ +# define PMC_PCK_PRES_DIV32 (5 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 32 */ +# define PMC_PCK_PRES_DIV64 (6 << PMC_PCK_PRES_SHIFT) /* Selected clock divided by 64 */ +#elif defined(ATSAMA5D2) +# define SAMA5_HAVE_PCK_INT_PRES 1 /* Supports conditional compilation */ +# define PMC_PCK_PRES_SHIFT (4) /* Bits 4-11: Programmable Clock Prescaler */ +# define PMC_PCK_PRES_MASK (0xff << PMC_PCK_PRES_SHIFT) +# define PMC_PCK_PRES(n) ((uint32_t)(n) << PMC_PCK_PRES_SHIFT) +#endif + +/* PMC Interrupt Enable Register, PMC Interrupt Disable Register, PMC Status Register, + * and PMC Interrupt Mask Register common bit-field definitions + */ + +#define PMC_INT_MOSCXTS (1 << 0) /* Bit 0: Main Crystal Oscillator Status Interrupt */ +#define PMC_INT_LOCKA (1 << 1) /* Bit 1: PLL A Lock Interrupt */ +#define PMC_INT_MCKRDY (1 << 3) /* Bit 3: Master Clock Ready Interrupt */ +#define PMC_INT_LOCKU (1 << 6) /* Bit 6: UTMI PLL Lock Interrupt */ +#define PMC_INT_PCKRDY0 (1 << 8) /* Bit 8: Programmable Clock Ready 0 Interrupt */ +#define PMC_INT_PCKRDY1 (1 << 9) /* Bit 9: Programmable Clock Ready 1 Interrupt */ +#define PMC_INT_PCKRDY2 (1 << 10) /* Bit 10: Programmable Clock Ready 2 Interrupt */ +#define PMC_INT_MOSCSELS (1 << 16) /* Bit 16: Main Oscillator Selection Status Interrupt */ + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define PMC_INT_MOSCRCS (1 << 17) /* Bit 17: Main On-Chip RC Status Interrupt */ +#elif defined(ATSAMA5D2) +# define PMC_SR_MOSCRCS (1 << 17) /* Bit 17: Main On-Chip RC Status (SR only) */ +#endif + +#define PMC_INT_CFDEV (1 << 18) /* Bit 18: Clock Failure Detector Event Interrupt */ +#define PMC_SR_CFDS (1 << 19) /* Bit 19: Clock Failure Detector Status (SR only) */ +#define PMC_SR_FOS (1 << 20) /* Bit 20: Clock Failure Detector Fault Output Status (SR only) */ + +#ifdef ATSAMA5D4 +# define PMC_SR_XT32KERR (1 << 21) /* Bit 21: Slow Crystal Oscillator Error Interrupt */ +#endif + +#ifdef ATSAMA5D2 +# define PMC_SR_GCKRDY (1 << 24) /* Bit 24: Generated Clocks Status (SR only) */ +#endif + +#ifdef ATSAMA5D2 +/* Fast Startup Mode Register */ + +# define PMC_FSMR_FSTT(n) (1 << (n)) /* Bits 0-8: Fast Startup Input Enable 0 to 8 */ +# define PMC_FSMR_FSTT0 (1 << 0) /* Bit 0: Fast Startup Input Enable 0 */ +# define PMC_FSMR_FSTT1 (1 << 1) /* Bit 1: Fast Startup Input Enable 1 */ +# define PMC_FSMR_FSTT2 (1 << 2) /* Bit 2: Fast Startup Input Enable 2 */ +# define PMC_FSMR_FSTT3 (1 << 3) /* Bit 3: Fast Startup Input Enable 3 */ +# define PMC_FSMR_FSTT4 (1 << 4) /* Bit 4: Fast Startup Input Enable 4 */ +# define PMC_FSMR_FSTT5 (1 << 5) /* Bit 5: Fast Startup Input Enable 5 */ +# define PMC_FSMR_FSTT6 (1 << 6) /* Bit 6: Fast Startup Input Enable 6 */ +# define PMC_FSMR_FSTT7 (1 << 7) /* Bit 7: Fast Startup Input Enable 7 */ +# define PMC_FSMR_FSTT8 (1 << 8) /* Bit 8: Fast Startup Input Enable 8 */ +# define PMC_FSMR_RTCAL (1 << 17) /* Bit 17: RTC Alarm Enable */ +# define PMC_FSMR_USBAL (1 << 18) /* Bit 18: USB Alarm Enable */ +# define PMC_FSMR_LPM (1 << 20) /* Bit 20: Low-power Mode */ +# define PMC_FSMR_RXLPAL (1 << 24) /* Bit 24: Lower-power Receiver Alarm */ +# define PMC_FSMR_ACCAL (1 << 25) /* Bit 25: Analog Comparator Controller Alarm */ +#endif + +#ifdef ATSAMA5D2 +/* Fast Startup Polarity Register */ + +# define PMC_FSPR_FSTP(n) (1 << (n)) /* Bits 0-8: Fast Startup Input Polarity 0 to 8 */ +# define PMC_FSPR_FSTP0 (1 << 0) /* Bit 0: Fast Startup Input Polarity 0 */ +# define PMC_FSPR_FSTP1 (1 << 1) /* Bit 1: Fast Startup Input Polarity 1 */ +# define PMC_FSPR_FSTP2 (1 << 2) /* Bit 2: Fast Startup Input Polarity 2 */ +# define PMC_FSPR_FSTP3 (1 << 3) /* Bit 3: Fast Startup Input Polarity 3 */ +# define PMC_FSPR_FSTP4 (1 << 4) /* Bit 4: Fast Startup Input Polarity 4 */ +# define PMC_FSPR_FSTP5 (1 << 5) /* Bit 5: Fast Startup Input Polarity 5 */ +# define PMC_FSPR_FSTP6 (1 << 6) /* Bit 6: Fast Startup Input Polarity 6 */ +# define PMC_FSPR_FSTP7 (1 << 7) /* Bit 7: Fast Startup Input Polarity 7 */ +# define PMC_FSPR_FSTP8 (1 << 8) /* Bit 8: Fast Startup Input Polarity 8 */ +#endif + +/* PMC Fault Output Clear Register */ + +#define PMC_FOCLR (1 << 0) /* Bit 0: Fault Output Clear */ + +/* PLL Charge Pump Current Register */ + +#define PMC_PLLICPR_ICP_PLLA_SHIFT (0) /* Bits 0-1: Charge Pump Current PLLA */ +#define PMC_PLLICPR_ICP_PLLA_MASK (3 << PMC_PLLICPR_ICP_PLLA_SHIFT) +# define PMC_PLLICPR_ICP_PLLA(n) ((uint32_t)(n) << PMC_PLLICPR_ICP_PLLA_SHIFT) +#define PMC_PLLICPR_IPLL_PLLA_SHIFT (8) /* Bits 8-10: Engineering Configuration PLLA */ +#define PMC_PLLICPR_IPLL_PLLA_MASK (7 << PMC_PLLICPR_IPLL_PLLA_SHIFT) +# define PMC_PLLICPR_IPLL_PLLA(n) ((uint32_t)(n) << PMC_PLLICPR_IPLL_PLLA_SHIFT) +#define PMC_PLLICPR_ICP_PLLU_SHIFT (16) /* Bits 16-17: Charge Pump Current PLL UTMI */ +#define PMC_PLLICPR_ICP_PLLU_MASK (3 << PMC_PLLICPR_ICP_PLLU_SHIFT) +# define PMC_PLLICPR_ICP_PLLU(n) ((uint32_t)(n) << PMC_PLLICPR_ICP_PLLU_SHIFT) +#define PMC_PLLICPR_IVCO_PLLU_SHIFT (14) /* Bits 24-25: Voltage Control Output Current PLL UTMI */ +#define PMC_PLLICPR_IVCO_PLLU_MASK (3 << PMC_PLLICPR_IVCO_PLLU_SHIFT) +# define PMC_PLLICPR_IVCO_PLLU(n) ((uint32_t)(n) << PMC_PLLICPR_IVCO_PLLU_SHIFT) + +/* PMC Write Protect Mode Register */ + +#define PMC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PMC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PMC_WPMR_WPKEY_MASK (0x00ffffff << PMC_WPMR_WPKEY_SHIFT) +# define PMC_WPMR_WPKEY (0x00504d43 << PMC_WPMR_WPKEY_SHIFT) + +/* PMC Write Protect Status Register */ + +#define PMC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PMC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PMC_WPSR_WPVSRC_MASK (0xffff << PMC_WPSR_WPVSRC_SHIFT) + +/* Peripheral Clock Enable Register 1 */ +/* Peripheral Clock Disable Register 1 */ +/* Peripheral Clock Status Register 1 */ + +#define PMC_PIDH(n) (1 << ((n) - 32)) +# define PMC_PID32 (1 << 0) /* Bit 0: PID32 */ +# define PMC_PID33 (1 << 1) /* Bit 1: PID33 */ +# define PMC_PID34 (1 << 2) /* Bit 2: PID34 */ +# define PMC_PID35 (1 << 3) /* Bit 3: PID35 */ +# define PMC_PID36 (1 << 4) /* Bit 4: PID36 */ +# define PMC_PID37 (1 << 5) /* Bit 5: PID37 */ +# define PMC_PID38 (1 << 6) /* Bit 6: PID38 */ +# define PMC_PID39 (1 << 7) /* Bit 7: PID39 */ +# define PMC_PID40 (1 << 8) /* Bit 8: PID40 */ +# define PMC_PID41 (1 << 9) /* Bit 9: PID41 */ +# define PMC_PID42 (1 << 10) /* Bit 10: PID42 */ +# define PMC_PID43 (1 << 11) /* Bit 11: PID43 */ +# define PMC_PID44 (1 << 12) /* Bit 12: PID44 */ +# define PMC_PID45 (1 << 13) /* Bit 13: PID45 */ +# define PMC_PID46 (1 << 14) /* Bit 14: PID46 */ +# define PMC_PID47 (1 << 15) /* Bit 15: PID47 */ +# define PMC_PID48 (1 << 16) /* Bit 16: PID48 */ +# define PMC_PID49 (1 << 17) /* Bit 17: PID49 */ +# define PMC_PID50 (1 << 18) /* Bit 18: PID50 */ +# define PMC_PID51 (1 << 19) /* Bit 19: PID51 */ +# define PMC_PID52 (1 << 20) /* Bit 20: PID52 */ +# define PMC_PID53 (1 << 21) /* Bit 21: PID53 */ +# define PMC_PID54 (1 << 22) /* Bit 22: PID54 */ +# define PMC_PID55 (1 << 23) /* Bit 23: PID55 */ +# define PMC_PID56 (1 << 24) /* Bit 24: PID56 */ +# define PMC_PID57 (1 << 25) /* Bit 25: PID57 */ +# define PMC_PID58 (1 << 26) /* Bit 26: PID58 */ +# define PMC_PID59 (1 << 27) /* Bit 27: PID59 */ +# define PMC_PID60 (1 << 28) /* Bit 28: PID50 */ +# define PMC_PID61 (1 << 29) /* Bit 29: PID61 */ +# define PMC_PID62 (1 << 30) /* Bit 30: PID62 */ +# define PMC_PID63 (1 << 31) /* Bit 31: PID63 */ + +/* Peripheral Control Register */ + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define PMC_PCR_PID_SHIFT (0) /* Bits 0-5: Peripheral ID */ +# define PMC_PCR_PID_MASK (0x3f << PMC_PCR_PID_SHIFT) +# define PMC_PCR_PID(n) ((n) << PMC_PCR_PID_SHIFT) +#elif defined(ATSAMA5D2) +# define PMC_PCR_PID_SHIFT (0) /* Bits 0-6: Peripheral ID */ +# define PMC_PCR_PID_MASK (0x7f << PMC_PCR_PID_SHIFT) +# define PMC_PCR_PID(n) ((n) << PMC_PCR_PID_SHIFT) +# define PMC_PCR_GCKCSS_SHIFT (8) /* Bits 8-10: GCK Clock Source Selection */ +# define PMC_PCR_GCKCSS_MASK (7 << PMC_PCR_GCKCSS_SHIFT) +# define PMC_PCR_GCKCSS_SLOW (0 << PMC_PCR_GCKCSS_SHIFT) /* Slow clock is selected */ +# define PMC_PCR_GCKCSS_MAIN (1 << PMC_PCR_GCKCSS_SHIFT) /* Main clock is selected */ +# define PMC_PCR_GCKCSS_PLLA (2 << PMC_PCR_GCKCSS_SHIFT) /* PLLACK is selected */ +# define PMC_PCR_GCKCSS_UPLL (3 << PMC_PCR_GCKCSS_SHIFT) /* UPLL Clock is selected */ +# define PMC_PCR_GCKCSS_MCK (4 << PMC_PCR_GCKCSS_SHIFT) /* Master Clock is selected */ +# define PMC_PCR_GCKCSS_AUDIO (5 << PMC_PCR_GCKCSS_SHIFT) /* Audio PLL clock is selected */ +#endif + +#define PMC_PCR_CMD (1 << 12) /* Bit 12: Command */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +# define SAMA5_HAVE_PMC_PCR_DIV 1 /* Supports conditional compilation */ +# define PMC_PCR_DIV_SHIFT (16) /* Bits 16-17: Divisor Value */ +# define PMC_PCR_DIV_MASK (3 << PMC_PCR_DIV_SHIFT) +# define PMC_PCR_DIV(n) ((uint32_t)(n) << PMC_PCR_DIV_SHIFT) +# define PMC_PCR_DIV1 (0 << PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK */ +# define PMC_PCR_DIV2 (1 << PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/2 */ +# define PMC_PCR_DIV4 (2 << PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/4 */ +# define PMC_PCR_DIV8 (3 << PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/8 */ +#endif + +#ifdef ATSAMA5D2 +# define PMC_PCR_GCKDIV_SHIFT (20) /* Bits 20-27: Generated Clock Division Ratio */ +# define PMC_PCR_GCKDIV_MASK (0xff << PMC_PCR_GCKDIV_SHIFT) +# define PMC_PCR_GCKDIV(n) ((uint32_t)(n) << PMC_PCR_GCKDIV_SHIFT) +#endif + +#define PMC_PCR_EN (1 << 28) /* Bit 28: Enable */ + +#ifdef ATSAMA5D2 +# define PMC_PCR_GCKEN (1 << 29) /* Bit 29: GCK Enable */ +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D3) +/* Oscillator Calibration Register */ + +# define PMC_OCR_CAL_SHIFT (0) /* Bits 0-6: 12 MHz RC Oscillator Calibration bits */ +# define PMC_OCR_CAL_MASK (0x7f << PMC_OCR_CAL_SHIFT) +# define PMC_OCR_CAL(n) ((uint32_t)(n) << PMC_OCR_CAL_SHIFT) +# define PMC_OCR_SEL (1 << 7) /* Bit 7: Selection of RC Oscillator Calibration bits */ +#endif + +#ifdef ATSAMA5D2 +/* SleepWalking Enable Register 0, SleepWalking Disable Register 0, and SleepWalking + * Activity Status Register 0. + */ + +# define PMC_SLPWK_ER0(n) (1 << (n)) /* Peripheral n SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID19 (1 << 19) /* Peripheral 19 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID20 (1 << 19) /* Peripheral 20 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID21 (1 << 19) /* Peripheral 21 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID22 (1 << 19) /* Peripheral 22 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID23 (1 << 19) /* Peripheral 23 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID24 (1 << 19) /* Peripheral 24 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID25 (1 << 19) /* Peripheral 25 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID26 (1 << 19) /* Peripheral 26 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID27 (1 << 19) /* Peripheral 27 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID28 (1 << 19) /* Peripheral 28 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID29 (1 << 19) /* Peripheral 29 SleepWalking Enable */ +# define PMC_SLPWK_ER0_PID30 (1 << 19) /* Peripheral 30 SleepWalking Enable */ +#endif + +#ifdef ATSAMA5D2 +/* SleepWalking Enable Register 1, SleepWalking Disable Register 1, and SleepWalking Status + * Register 1, and SleepWalking Activity Status Register 1. + */ + +# define PMC_SLPWK_ER1(n) (1 << ((n)-1)) /* Peripheral n SleepWalking Enable */ +# define PMC_SLPWK_ER1_PID33 (1 << 1) /* Peripheral 33 SleepWalking Enable */ +# define PMC_SLPWK_ER1_PID34 (1 << 2) /* Peripheral 34 SleepWalking Enable */ +# define PMC_SLPWK_ER1_PID40 (1 << 8) /* Peripheral 40 SleepWalking Enable */ +#endif + + +#ifdef ATSAMA5D2 +/* SleepWalking Activity In Progress Register */ + +# define PMC_SLPWK_AIPR_AIP (1 << 0) /* Bit 0: Activity In Progress */ +#endif + +#ifdef ATSAMA5D2 +/* SleepWalking Control Register */ + +# define PMC_SLPWKCR_PID_SHIFT (0) /* Bits 0-6: Peripheral ID */ +# define PMC_SLPWKCR_PID_MASK (0x7f << PMC_SLPWKCR_PID_SHIFT) +# define PMC_SLPWKCR_PID(n) ((uint32_t)(n) << PMC_SLPWKCR_PID_SHIFT) +# define PMC_SLPWKCR_CMD (1 << 12) /* Bit 12: Command */ +# define PMC_SLPWKCR_CMD_READ (0) /* Bit 12: 0=Read mode */ +# define PMC_SLPWKCR_CMD_WRITE (1 << 12) /* Bit 12: 1=Write mode */ +# define PMC_SLPWKCR_ASR (1 << 16) /* Bit 16: Activity Status Register */ +# define PMC_SLPWKCR_SLPWKSR (1 << 28) /* Bit 28: SleepWalking Status Register */ +#endif + +#ifdef ATSAMA5D2 +/* Audio PLL Register 0 */ + +# define PMC_AUDIO_PLL0_PLLEN (1 << 0) /* Bit 0: PLL Enable */ +# define PMC_AUDIO_PLL0_PADEN (1 << 1) /* Bit 1: Pad Clock Enable */ +# define PMC_AUDIO_PLL0_PMCEN (1 << 2) /* Bit 2: PMC Clock Enable */ +# define PMC_AUDIO_PLL0_RESETN (1 << 3) /* Bit 3: Audio PLL Reset */ +# define PMC_AUDIO_PLL0_ND_SHIFT (8) /* Bits 8-14: Loop Divider Ratio */ +# define PMC_AUDIO_PLL0_ND_MASK (0x7f << PMC_AUDIO_PLL0_ND_SHIFT) +# define PMC_AUDIO_PLL0_ND(n) ((uint32_t)(n) << PMC_AUDIO_PLL0_ND_SHIFT) +# define PMC_AUDIO_PLL0_QDPMC_SHIFT (16) /* Bitx 16-22: Output Divider Ratio for PMC Clock */ +# define PMC_AUDIO_PLL0_QDPMC_MASK (0x7f << PMC_AUDIO_PLL0_QDPMC_SHIFT) +# define PMC_AUDIO_PLL0_QDPMC(n) ((uint32_t)(n) << PMC_AUDIO_PLL0_QDPMC_SHIFT) +#endif + +#ifdef ATSAMA5D2 +/* Audio PLL Register 1 */ + +# define PMC_AUDIO_PLL1_FRACR_SHIFT (0) /* Bits 0-21: Fractional Loop Divider Setting */ +# define PMC_AUDIO_PLL1_FRACR_MASK (0x3fffff << PMC_AUDIO_PLL1_FRACR_SHIFT) +# define PMC_AUDIO_PLL1_FRACR(n) ((uint32_t)(n) << PMC_AUDIO_PLL1_FRACR_SHIFT) +# define PMC_AUDIO_PLL1_QDAUDIO_SHIFT (24) /* Bits 24-30: Output Divider Ratio for Pad Clock */ +# define PMC_AUDIO_PLL1_QDAUDIO_MASK (0x7f << PMC_AUDIO_PLL1_QDAUDIO_SHIFT) +# define PMC_AUDIO_PLL1_QDAUDIO(n) ((uint32_t)(n) << PMC_AUDIO_PLL1_QDAUDIO_SHIFT) +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PMC_H */ diff --git a/arch/arm/src/sama5/chip/sam_pwm.h b/arch/arm/src/sama5/chip/sam_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..aa5ca2ed0ff70f6cb327b825cea9d9f6804c85dc --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_pwm.h @@ -0,0 +1,750 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_pwm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PWM_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_PWM_NCHANNELS 4 /* Four channels numbered 0..3 */ + +/* PWM Register Offsets *************************************************************/ + +#define SAM_PWM_CLK_OFFSET 0x0000 /* PWM Clock Register */ +#define SAM_PWM_ENA_OFFSET 0x0004 /* PWM Enable Register */ +#define SAM_PWM_DIS_OFFSET 0x0008 /* PWM Disable Register */ +#define SAM_PWM_SR_OFFSET 0x000c /* PWM Status Register */ +#define SAM_PWM_IER1_OFFSET 0x0010 /* PWM Interrupt Enable Register 1 */ +#define SAM_PWM_IDR1_OFFSET 0x0014 /* PWM Interrupt Disable Register 1 */ +#define SAM_PWM_IMR1_OFFSET 0x0018 /* PWM Interrupt Mask Register 1 */ +#define SAM_PWM_ISR1_OFFSET 0x001c /* PWM Interrupt Status Register 1 */ +#define SAM_PWM_SCM_OFFSET 0x0020 /* PWM Sync Channels Mode Register */ + +#ifdef ATSAMA5D4 +# define SAM_PWM_DMAR_OFFSET 0x0024 /* PWM DMA Register */ +#endif + +#define SAM_PWM_SCUC_OFFSET 0x0028 /* PWM Sync Channels Update Control Register */ +#define SAM_PWM_SCUP_OFFSET 0x002c /* PWM Sync Channels Update Period Register */ +#define SAM_PWM_SCUPUPD_OFFSET 0x0030 /* PWM Sync Channels Update Period Update Register */ +#define SAM_PWM_IER2_OFFSET 0x0034 /* PWM Interrupt Enable Register 2 */ +#define SAM_PWM_IDR2_OFFSET 0x0038 /* PWM Interrupt Disable Register 2 */ +#define SAM_PWM_IMR2_OFFSET 0x003c /* PWM Interrupt Mask Register 2 */ +#define SAM_PWM_ISR2_OFFSET 0x0040 /* PWM Interrupt Status Register 2 */ +#define SAM_PWM_OOV_OFFSET 0x0044 /* PWM Output Override Value Register */ +#define SAM_PWM_OS_OFFSET 0x0048 /* PWM Output Selection Register */ +#define SAM_PWM_OSS_OFFSET 0x004c /* PWM Output Selection Set Register */ +#define SAM_PWM_OSC_OFFSET 0x0050 /* PWM Output Selection Clear Register */ +#define SAM_PWM_OSSUPD_OFFSET 0x0054 /* PWM Output Selection Set Update Register */ +#define SAM_PWM_OSCUPD_OFFSET 0x0058 /* PWM Output Selection Clear Update Register */ +#define SAM_PWM_FMR_OFFSET 0x005c /* PWM Fault Mode Register */ +#define SAM_PWM_FSR_OFFSET 0x0060 /* PWM Fault Status Register */ +#define SAM_PWM_FCR_OFFSET 0x0064 /* PWM Fault Clear Register */ +#define SAM_PWM_FPV_OFFSET 0x0068 /* PWM Fault Protection Value Register 1 */ +#define SAM_PWM_FPE_OFFSET 0x006c /* PWM Fault Protection Enable Register */ + /* 0x0070-0x0078 Reserved */ +#define SAM_PWM_ELMR0_OFFSET 0x007c /* PWM Event Line 0 Mode Register */ +#define SAM_PWM_ELMR1_OFFSET 0x0080 /* PWM Event Line 1 Mode Register */ + +#ifdef ATSAMA5D4 +# define SAM_PWM_SSPR_OFFSET 0x00a0 /* PWM Spread Spectrum Register */ +# define SAM_PWM_SSPUP_OFFSET 0x00a4 /* PWM Spread Spectrum Update Register */ +#endif + +#define SAM_PWM_SMMR_OFFSET 0x00b0 /* PWM Stepper Motor Mode Register */ + +#ifdef ATSAMA5D4 +# define SAM_PWM_FPV2_OFFSET 0x00c0 /* PWM Fault Protection Value Register 2 */ +#endif + +#define SAM_PWM_WPCR_OFFSET 0x00e4 /* PWM Write Protect Control Register */ +#define SAM_PWM_WPSR_OFFSET 0x00e8 /* PWM Write Protect Status Register */ + /* 0x00ec - 0x00fc Reserved */ + +#define SAM_PWM_CMPV_OFFSET(n) (0x0130 + ((int)(n) << 4)) /* n=0..7 */ +#define SAM_PWM_CMPVUPD_OFFSET(n) (0x0134 + ((int)(n) << 4)) /* n=0-7 */ +#define SAM_PWM_CMPM_OFFSET(n) (0x0138 + ((int)(n) << 4)) /* n=0-7 */ +#define SAM_PWM_CMPMUPD_OFFSET(n) (0x013c + ((int)(n) << 4)) /* n=0-7 */ + +#define SAM_PWM_CMPV0_OFFSET 0x0130 /* PWM Comparison 0 Value Register */ +#define SAM_PWM_CMPVUPD0_OFFSET 0x0134 /* PWM Comparison 0 Value Update Register */ +#define SAM_PWM_CMPM0_OFFSET 0x0138 /* PWM Comparison 0 Mode Register */ +#define SAM_PWM_CMPMUPD0_OFFSET 0x013c /* PWM Comparison 0 Mode Update Register */ + +#define SAM_PWM_CMPV1_OFFSET 0x0140 /* PWM Comparison 1 Value Register */ +#define SAM_PWM_CMPVUPD1_OFFSET 0x0144 /* PWM Comparison 1 Value Update Register */ +#define SAM_PWM_CMPM1_OFFSET 0x0148 /* PWM Comparison 1 Mode Register */ +#define SAM_PWM_CMPMUPD1_OFFSET 0x014c /* PWM Comparison 1 Mode Update Register */ + +#define SAM_PWM_CMPV2_OFFSET 0x0150 /* PWM Comparison 2 Value Register */ +#define SAM_PWM_CMPVUPD2_OFFSET 0x0154 /* PWM Comparison 2 Value Update Register */ +#define SAM_PWM_CMPM2_OFFSET 0x0158 /* PWM Comparison 2 Mode Register */ +#define SAM_PWM_CMPMUPD2_OFFSET 0x015c /* PWM Comparison 2 Mode Update Register */ + +#define SAM_PWM_CMPV3_OFFSET 0x0160 /* PWM Comparison 3 Value Register */ +#define SAM_PWM_CMPVUPD3_OFFSET 0x0164 /* PWM Comparison 3 Value Update Register */ +#define SAM_PWM_CMPM3_OFFSET 0x0168 /* PWM Comparison 3 Mode Register */ +#define SAM_PWM_CMPMUPD3_OFFSET 0x016c /* PWM Comparison 3 Mode Update Register */ + +#define SAM_PWM_CMPV4_OFFSET 0x0170 /* PWM Comparison 4 Value Register */ +#define SAM_PWM_CMPVUPD4_OFFSET 0x0174 /* PWM Comparison 4 Value Update Register */ +#define SAM_PWM_CMPM4_OFFSET 0x0178 /* PWM Comparison 4 Mode Register */ +#define SAM_PWM_CMPMUPD4_OFFSET 0x017c /* PWM Comparison 4 Mode Update Register */ + +#define SAM_PWM_CMPV5_OFFSET 0x0180 /* PWM Comparison 5 Value Register */ +#define SAM_PWM_CMPVUPD5_OFFSET 0x0184 /* PWM Comparison 5 Value Update Register */ +#define SAM_PWM_CMPM5_OFFSET 0x0188 /* PWM Comparison 5 Mode Register */ +#define SAM_PWM_CMPMUPD5_OFFSET 0x018c /* PWM Comparison 5 Mode Update Register */ + +#define SAM_PWM_CMPV6_OFFSET 0x0190 /* PWM Comparison 6 Value Register */ +#define SAM_PWM_CMPVUPD6_OFFSET 0x0194 /* PWM Comparison 6 Value Update Register */ +#define SAM_PWM_CMPM6_OFFSET 0x0198 /* PWM Comparison 6 Mode Register */ +#define SAM_PWM_CMPMUPD6_OFFSET 0x019c /* PWM Comparison 6 Mode Update Register */ + +#define SAM_PWM_CMPV7_OFFSET 0x01a0 /* PWM Comparison 7 Value Register */ +#define SAM_PWM_CMPVUPD7_OFFSET 0x01a4 /* PWM Comparison 7 Value Update Register */ +#define SAM_PWM_CMPM7_OFFSET 0x01a8 /* PWM Comparison 7 Mode Register */ +#define SAM_PWM_CMPMUPD7_OFFSET 0x01ac /* PWM Comparison 7 Mode Update Register */ + /* 0x01b0 - 0x01fc Reserved */ +#define SAM_PWM_CHANA_OFFSET(n) (0x0200 + ((int)(n) << 5)) /* n=0..3 */ +#define SAM_PWM_CMR_OFFSET 0x0000 /* PWM Channel Mode Register */ +#define SAM_PWM_CDTY_OFFSET 0x0004 /* PWM Channel Duty Cycle Register */ +#define SAM_PWM_CDTYUPD_OFFSET 0x0008 /* PWM Channel Duty Cycle Update Register */ +#define SAM_PWM_CPRD_OFFSET 0x000c /* PWM Channel Period Register */ +#define SAM_PWM_CPRDUPD_OFFSET 0x0010 /* PWM Channel Period Update Register */ +#define SAM_PWM_CCNT_OFFSET 0x0014 /* PWM Channel Counter Register */ +#define SAM_PWM_DT_OFFSET 0x0018 /* PWM Channel Dead Time Register */ +#define SAM_PWM_DTUPD_OFFSET 0x001c /* PWM Channel Dead Time Update Register */ + +#define SAM_PWM_CHANAB_DELTA 0x0200 /* Offset of second group from the first */ + +#ifdef ATSAMA5D4 +# define SAM_PWM_CHANB_OFFSET(n) (0x0400 + ((int)(n) << 5)) /* n=0..3 */ +# define SAM_PWM_CMUPD_OFFSET 0x0000 /* PWM Channel Mode Update Register */ +#endif + +/* PWM Register Addresses ***********************************************************/ + +#define SAM_PWM_CLK (SAM_PWMC_VBASE+SAM_PWM_CLK_OFFSET) +#define SAM_PWM_ENA (SAM_PWMC_VBASE+SAM_PWM_ENA_OFFSET) +#define SAM_PWM_DIS (SAM_PWMC_VBASE+SAM_PWM_DIS_OFFSET) +#define SAM_PWM_SR (SAM_PWMC_VBASE+SAM_PWM_SR_OFFSET) +#define SAM_PWM_IER1 (SAM_PWMC_VBASE+SAM_PWM_IER1_OFFSET) +#define SAM_PWM_IDR1 (SAM_PWMC_VBASE+SAM_PWM_IDR1_OFFSET) +#define SAM_PWM_IMR1 (SAM_PWMC_VBASE+SAM_PWM_IMR1_OFFSET) +#define SAM_PWM_ISR1 (SAM_PWMC_VBASE+SAM_PWM_ISR1_OFFSET) +#define SAM_PWM_SCM (SAM_PWMC_VBASE+SAM_PWM_SCM_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PWM_DMAR (SAM_PWMC_VBASE+SAM_PWM_DMAR_OFFSET) +#endif + +#define SAM_PWM_SCUC (SAM_PWMC_VBASE+SAM_PWM_SCUC_OFFSET) +#define SAM_PWM_SCUP (SAM_PWMC_VBASE+SAM_PWM_SCUP_OFFSET) +#define SAM_PWM_SCUPUPD (SAM_PWMC_VBASE+SAM_PWM_SCUPUPD_OFFSET) +#define SAM_PWM_IER2 (SAM_PWMC_VBASE+SAM_PWM_IER2_OFFSET) +#define SAM_PWM_IDR2 (SAM_PWMC_VBASE+SAM_PWM_IDR2_OFFSET) +#define SAM_PWM_IMR2 (SAM_PWMC_VBASE+SAM_PWM_IMR2_OFFSET) +#define SAM_PWM_ISR2 (SAM_PWMC_VBASE+SAM_PWM_ISR2_OFFSET) +#define SAM_PWM_OOV (SAM_PWMC_VBASE+SAM_PWM_OOV_OFFSET) +#define SAM_PWM_OS (SAM_PWMC_VBASE+SAM_PWM_OS_OFFSET) +#define SAM_PWM_OSS (SAM_PWMC_VBASE+SAM_PWM_OSS_OFFSET) +#define SAM_PWM_OSC (SAM_PWMC_VBASE+SAM_PWM_OSC_OFFSET) +#define SAM_PWM_OSSUPD (SAM_PWMC_VBASE+SAM_PWM_OSSUPD_OFFSET) +#define SAM_PWM_OSCUPD (SAM_PWMC_VBASE+SAM_PWM_OSCUPD_OFFSET) +#define SAM_PWM_FMR (SAM_PWMC_VBASE+SAM_PWM_FMR_OFFSET) +#define SAM_PWM_FSR (SAM_PWMC_VBASE+SAM_PWM_FSR_OFFSET) +#define SAM_PWM_FCR (SAM_PWMC_VBASE+SAM_PWM_FCR_OFFSET) +#define SAM_PWM_FPV (SAM_PWMC_VBASE+SAM_PWM_FPV_OFFSET) +#define SAM_PWM_FPE (SAM_PWMC_VBASE+SAM_PWM_FPE_OFFSET) +#define SAM_PWM_ELMR0 (SAM_PWMC_VBASE+SAM_PWM_ELMR0_OFFSET) +#define SAM_PWM_ELMR1 (SAM_PWMC_VBASE+SAM_PWM_ELMR1_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PWM_SSPR (SAM_PWMC_VBASE+SAM_PWM_SSPR_OFFSET) +# define SAM_PWM_SSPUP (SAM_PWMC_VBASE+SAM_PWM_SSPUP_OFFSET) +#endif + +#define SAM_PWM_SMMR (SAM_PWMC_VBASE+SAM_PWM_SMMR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PWM_FPV2 (SAM_PWMC_VBASE+SAM_PWM_FPV2_OFFSET) +#endif + +#define SAM_PWM_WPCR (SAM_PWMC_VBASE+SAM_PWM_WPCR_OFFSET) +#define SAM_PWM_WPSR (SAM_PWMC_VBASE+SAM_PWM_WPSR_OFFSET) + +#define SAM_PWM_CMPV(n) (SAM_PWMC_VBASE+SAM_PWM_CMPV_OFFSET(n)) +#define SAM_PWM_CMPVUPD(n) (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD_OFFSET(n)) +#define SAM_PWM_CMPM(n) (SAM_PWMC_VBASE+SAM_PWM_CMPM_OFFSET(n)) +#define SAM_PWM_CMPMUPD(n) (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD_OFFSET(n)) + +#define SAM_PWM_CMPV0 (SAM_PWMC_VBASE+SAM_PWM_CMPV0_OFFSET) +#define SAM_PWM_CMPVUPD0 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD0_OFFSET) +#define SAM_PWM_CMPM0 (SAM_PWMC_VBASE+SAM_PWM_CMPM0_OFFSET) +#define SAM_PWM_CMPMUPD0 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD0_OFFSET) + +#define SAM_PWM_CMPV1 (SAM_PWMC_VBASE+SAM_PWM_CMPV1_OFFSET) +#define SAM_PWM_CMPVUPD1 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD1_OFFSET) +#define SAM_PWM_CMPM1 (SAM_PWMC_VBASE+SAM_PWM_CMPM1_OFFSET) +#define SAM_PWM_CMPMUPD1 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD1_OFFSET) + +#define SAM_PWM_CMPV2 (SAM_PWMC_VBASE+SAM_PWM_CMPV2_OFFSET) +#define SAM_PWM_CMPVUPD2 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD2_OFFSET) +#define SAM_PWM_CMPM2 (SAM_PWMC_VBASE+SAM_PWM_CMPM2_OFFSET) +#define SAM_PWM_CMPMUPD2 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD2_OFFSET) + +#define SAM_PWM_CMPV3 (SAM_PWMC_VBASE+SAM_PWM_CMPV3_OFFSET) +#define SAM_PWM_CMPVUPD3 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD3_OFFSET) +#define SAM_PWM_CMPM3 (SAM_PWMC_VBASE+SAM_PWM_CMPM3_OFFSET) +#define SAM_PWM_CMPMUPD3 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD3_OFFSET) + +#define SAM_PWM_CMPV4 (SAM_PWMC_VBASE+SAM_PWM_CMPV4_OFFSET) +#define SAM_PWM_CMPVUPD4 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD4_OFFSET) +#define SAM_PWM_CMPM4 (SAM_PWMC_VBASE+SAM_PWM_CMPM4_OFFSET) +#define SAM_PWM_CMPMUPD4 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD4_OFFSET) + +#define SAM_PWM_CMPV5 (SAM_PWMC_VBASE+SAM_PWM_CMPV5_OFFSET) +#define SAM_PWM_CMPVUPD5 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD5_OFFSET) +#define SAM_PWM_CMPM5 (SAM_PWMC_VBASE+SAM_PWM_CMPM5_OFFSET) +#define SAM_PWM_CMPMUPD5 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD5_OFFSET) + +#define SAM_PWM_CMPV6 (SAM_PWMC_VBASE+SAM_PWM_CMPV6_OFFSET) +#define SAM_PWM_CMPVUPD6 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD6_OFFSET) +#define SAM_PWM_CMPM6 (SAM_PWMC_VBASE+SAM_PWM_CMPM6_OFFSET) +#define SAM_PWM_CMPMUPD6 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD6_OFFSET) + +#define SAM_PWM_CMPV7 (SAM_PWMC_VBASE+SAM_PWM_CMPV7_OFFSET) +#define SAM_PWM_CMPVUPD7 (SAM_PWMC_VBASE+SAM_PWM_CMPVUPD7_OFFSET) +#define SAM_PWM_CMPM7 (SAM_PWMC_VBASE+SAM_PWM_CMPM7_OFFSET) +#define SAM_PWM_CMPMUPD7 (SAM_PWMC_VBASE+SAM_PWM_CMPMUPD7_OFFSET) + +#define SAM_PWM_CHANA_BASE(n) (SAM_PWMC_VBASE+SAM_PWM_CHANA_OFFSET(n)) +#define SAM_PWM_CMR(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CMR_OFFSET) +#define SAM_PWM_CDTY(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CDTY_OFFSET) +#define SAM_PWM_CDTYUPD(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CDTYUPD_OFFSET) +#define SAM_PWM_CPRD(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CPRD_OFFSET) +#define SAM_PWM_CPRDUPD(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CPRDUPD_OFFSET) +#define SAM_PWM_CCNT(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_CCNT_OFFSET) +#define SAM_PWM_DT(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_DT_OFFSET) +#define SAM_PWM_DTUPD(n) (SAM_PWM_CHANA_BASE(n)+SAM_PWM_DTUPD_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_PWM_CHANB_BASE(n) (SAM_PWMC_VBASE+define SAM_PWM_CHANB_OFFSET(n)) +# define SAM_PWM_CMUPD(n) (SAM_PWM_CHANB_BASE(n)+SAM_PWM_CMUPD_OFFSET) +#endif + +/* PWM Register Bit Definitions *****************************************************/ + +/* PWM Clock Register */ + +#define PWM_CLK_DIVA_SHIFT (0) /* Bits 0-7: CLKA Divide Factor */ +#define PWM_CLK_DIVA_MASK (0xff << PWM_CLK_DIVA_SHIFT) +# define PWM_CLK_DIVA_OFF (0 << PWM_CLK_DIVA_SHIFT) /* CLKA clock = off */ +# define PWM_CLK_DIVA_PREA (1 << PWM_CLK_DIVA_SHIFT) /* CLKA clock = clock selected by PREA */ +# define PWM_CLK_DIVA(n) ((uint32_t)(n) << PWM_CLK_DIVA_SHIFT) /* CLKA clock = clock selected by PREA / DIVA */ +#define PWM_CLK_PREA_SHIFT (8) /* Bits 8-11: CLKA Source Clock Selection */ +#define PWM_CLK_PREA_MASK (15 << PWM_CLK_PREA_SHIFT) +# define PWM_CLK_PREA_DIV1 (0 << PWM_CLK_PREA_SHIFT) /* MCK */ +# define PWM_CLK_PREA_DIV2 (1 << PWM_CLK_PREA_SHIFT) /* MCK/2 */ +# define PWM_CLK_PREA_DIV4 (2 << PWM_CLK_PREA_SHIFT) /* MCK/4 */ +# define PWM_CLK_PREA_DIV8 (3 << PWM_CLK_PREA_SHIFT) /* MCK/8 */ +# define PWM_CLK_PREA_DIV16 (4 << PWM_CLK_PREA_SHIFT) /* MCK/16 */ +# define PWM_CLK_PREA_DIV32 (5 << PWM_CLK_PREA_SHIFT) /* MCK/32 */ +# define PWM_CLK_PREA_DIV64 (6 << PWM_CLK_PREA_SHIFT) /* MCK/64 */ +# define PWM_CLK_PREA_DIV128 (7 << PWM_CLK_PREA_SHIFT) /* MCK/128 */ +# define PWM_CLK_PREA_DIV256 (8 << PWM_CLK_PREA_SHIFT) /* MCK/256 */ +# define PWM_CLK_PREA_DIV512 (9 << PWM_CLK_PREA_SHIFT) /* MCK/512 */ +# define PWM_CLK_PREA_DIV1024 (10 << PWM_CLK_PREA_SHIFT) /* MCK/1024 */ +#define PWM_CLK_DIVB_SHIFT (16) /* Bits 16-23: CLKB Divide Factor */ +# define PWM_CLK_DIVB_OFF (0 << PWM_CLK_DIVB_SHIFT) /* CLKB clock = off */ +# define PWM_CLK_DIVB_PREB (1 << PWM_CLK_DIVB_SHIFT) /* CLKB clock = clock selected by PREB */ +# define PWM_CLK_DIVB(n) ((uint32_t)(n) << PWM_CLK_DIVB_SHIFT) /* CLKB clock = clock selected by PREB / DIVB */ +#define PWM_CLK_PREB_SHIFT (24) /* Bits 24-27: CLKB Source Clock Selection */ +#define PWM_CLK_PREB_MASK (15 << PWM_CLK_PREB_SHIFT) +# define PWM_CLK_PREB_DIV1 (0 << PWM_CLK_PREB_SHIFT) /* MCK */ +# define PWM_CLK_PREB_DIV2 (1 << PWM_CLK_PREB_SHIFT) /* MCK/2 */ +# define PWM_CLK_PREB_DIV4 (2 << PWM_CLK_PREB_SHIFT) /* MCK/4 */ +# define PWM_CLK_PREB_DIV8 (3 << PWM_CLK_PREB_SHIFT) /* MCK/8 */ +# define PWM_CLK_PREB_DIV16 (4 << PWM_CLK_PREB_SHIFT) /* MCK/16 */ +# define PWM_CLK_PREB_DIV32 (5 << PWM_CLK_PREB_SHIFT) /* MCK/32 */ +# define PWM_CLK_PREB_DIV64 (6 << PWM_CLK_PREB_SHIFT) /* MCK/64 */ +# define PWM_CLK_PREB_DIV128 (7 << PWM_CLK_PREB_SHIFT) /* MCK/128 */ +# define PWM_CLK_PREB_DIV256 (8 << PWM_CLK_PREB_SHIFT) /* MCK/256 */ +# define PWM_CLK_PREB_DIV512 (9 << PWM_CLK_PREB_SHIFT) /* MCK/512 */ +# define PWM_CLK_PREB_DIV1024 (10 << PWM_CLK_PREB_SHIFT) /* MCK/1024 */ + +/* PWM Enable Register, PWM Disable Register, and PWM Status Register */ + +#define PWM_CHID(n) (1 << (n)) /* Bits 0-3: Channel ID n, n=0..3 */ + +/* PWM Interrupt Enable Register 1, PWM Interrupt Disable Register 1, PWM Interrupt + * Mask Register 1, and PWM Interrupt Status Register 1 + */ + +#define PWM_INT1_CHID(n) (1 << (n)) /* Bits 0-3: Counter Event on Channel n Interrupt, n=0..3 */ +#define PWM_INT1_FCHID(n) (1 << ((n)+16)) /* Bits 16-19: Fault Protection Trigger on Channel n Interrupt, n=0..3 */ +#define PWM_INT1_ALL (0x000f000f) + +/* PWM Sync Channels Mode Register */ + +#define PWM_SCM_SYNC(n) (1 << (n)) /* Bits 0-3: Synchronous Channel n, n=0..3 */ +# define PWM_SCM_SYNC0 (1 << 0) /* Bits 0: Synchronous Channel 0 */ +# define PWM_SCM_SYNC1 (1 << 1) /* Bits 1: Synchronous Channel 1 */ +# define PWM_SCM_SYNC2 (1 << 2) /* Bits 2: Synchronous Channel 2 */ +# define PWM_SCM_SYNC3 (1 << 3) /* Bits 3: Synchronous Channel 3 */ +#define PWM_SCM_UPDM_SHIFT (16) /* Bits 16-17: Synchronous Channels Update Mode */ +#define PWM_SCM_UPDM_MASK (3 << PWM_SCM_UPDM_SHIFT) +# define PWM_SCM_UPDM_MODE0 (0 << PWM_SCM_UPDM_SHIFT) /* Manual double buffer / manual channel update */ +# define PWM_SCM_UPDM_MODE1 (1 << PWM_SCM_UPDM_SHIFT) /* Manual double buffer / automatic channel update */ + +#ifdef ATSAMA5D4 +# define PWM_SCM_PTRM (1 << 20) /* Bit 20: DMA Transfer Request Mode */ +# define PWM_SCM_PTRCS_SHIFT (21) /* Bits 21-23: DMA Transfer Request Comparison Selection */ +# define PWM_SCM_PTRCS_MASK (7 << PWM_SCM_PTRCS_SHIFT) +# define PWM_SCM_PTRCS(n) ((uint32_t)(n) << PWM_SCM_PTRCS_SHIFT) +#endif + +#ifdef ATSAMA5D4 +/* PWM DMA Register */ + +# define PWM_DMAR_DMADUTY_SHIFT (0) /* Bits 0-23: Duty-Cycle Holding Register for DMA Access */ +# define PWM_DMAR_DMADUTY_MASK (0x00ffffff << PWM_DMAR_DMADUTY_SHIFT) +# define PWM_DMAR_DMADUTY(n) ((uint32_t)(n) << PWM_DMAR_DMADUTY_SHIFT) +#endif + +/* PWM Sync Channels Update Control Register */ + +#define PWM_SCUC_UPDULOCK (1 << 0) /* Bit 0: Synchronous Channels Update Unlock */ + +/* PWM Sync Channels Update Period Register */ + +#define PWM_SCUP_UPR_SHIFT (0) /* Bits 0-3: Update Period */ +#define PWM_SCUP_UPR_MASK (15 << PWM_SCUP_UPR_SHIFT) +# define PWM_SCUP_UPR(n) ((uint32_t)(n) << PWM_SCUP_UPR_SHIFT) +#define PWM_SCUP_UPRCNT_SHIFT (4) /* Bits 4-7: Update Period Counter */ +#define PWM_SCUP_UPRCNT_MASK (15 << PWM_SCUP_UPRCNT_SHIFT) +# define PWM_SCUP_UPRCNT(n) ((uint32_t)(n) << PWM_SCUP_UPRCNT_SHIFT) + +/* PWM Sync Channels Update Period Update Register */ + +#define PWM_SCUPUPD_UPRUPD_SHIFT (0) /* Bits 0-3: Update Period Update */ +#define PWM_SCUPUPD_UPRUPD_MASK (15 << PWM_SCUPUPD_UPRUPD_SHIFT) +# define PWM_SCUPUPD_UPRUPD(n) ((uint32_t)(n) << PWM_SCUPUPD_UPRUPD_SHIFT) + +/* PWM Interrupt Enable Register 2, PWM Interrupt Disable Register 2, PWM Interrupt + * Mask Register 2, and PWM Interrupt Status Register 2. + */ + +#define PWM_INT2_WRDY (1 << 0) /* Bit 0: Write Ready for Synchronous Channels Update Interrupt Enable */ +#define PWM_INT2_UNRE (1 << 3) /* Bit 3: Synchronous Channels Update Underrun Error Interrupt Enable */ +#define PWM_INT2_CMPM(n) (1 << ((n)+8)) /* Bits 8-15: Comparison n Match Interrupt Enable, n=0..7 */ +# define PWM_INT2_CMPM0 (1 << 8) /* Bit 8: Comparison 0 Match Interrupt Enable */ +# define PWM_INT2_CMPM1 (1 << 9) /* Bit 9: Comparison 1 Match Interrupt Enable */ +# define PWM_INT2_CMPM2 (1 << 10) /* Bit 10: Comparison 2 Match Interrupt Enable */ +# define PWM_INT2_CMPM3 (1 << 11) /* Bit 11: Comparison 3 Match Interrupt Enable */ +# define PWM_INT2_CMPM4 (1 << 12) /* Bit 12: Comparison 4 Match Interrupt Enable */ +# define PWM_INT2_CMPM5 (1 << 13) /* Bit 13: Comparison 5 Match Interrupt Enable */ +# define PWM_INT2_CMPM6 (1 << 14) /* Bit 14: Comparison 6 Match Interrupt Enable */ +# define PWM_INT2_CMPM7 (1 << 15) /* Bit 15: Comparison 7 Match Interrupt Enable */ +#define PWM_INT2_CMPU(n) (1 << ((n)+16)) /* Bits 16-23: Comparison n Update Interrupt Enable, n=0..7 */ +# define PWM_INT2_CMPU0 (1 << 16) /* Bit 16: Comparison 0 Update Interrupt Enable */ +# define PWM_INT2_CMPU1 (1 << 17) /* Bit 17: Comparison 1 Update Interrupt Enable */ +# define PWM_INT2_CMPU2 (1 << 18) /* Bit 18: Comparison 2 Update Interrupt Enable */ +# define PWM_INT2_CMPU3 (1 << 19) /* Bit 19: Comparison 3 Update Interrupt Enable */ +# define PWM_INT2_CMPU4 (1 << 20) /* Bit 20: Comparison 4 Update Interrupt Enable */ +# define PWM_INT2_CMPU5 (1 << 21) /* Bit 21: Comparison 5 Update Interrupt Enable */ +# define PWM_INT2_CMPU6 (1 << 22) /* Bit 22: Comparison 6 Update Interrupt Enable */ +# define PWM_INT2_CMPU7 (1 << 23) /* Bit 23: Comparison 7 Update Interrupt Enable */ +#define PWM_INT2_ALL (0x00ffff09) + +/* PWM Output Override Value Register */ + +#define PWM_OOV_H(n) (1 << (n)) /* Bits 0-3: Output Override PWMH channel n, n=0..3 */ +# define PWM_OOV_H0 (1 << 0) /* Bit 0: Output Override PWMH channel 0 */ +# define PWM_OOV_H1 (1 << 1) /* Bit 1: Output Override PWMH channel 1 */ +# define PWM_OOV_H2 (1 << 2) /* Bit 2: Output Override PWMH channel 2 */ +# define PWM_OOV_H3 (1 << 3) /* Bit 3: Output Override PWMH channel 3 */ +#define PWM_OOV_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Override PWML channel n, n=0..3 */ +# define PWM_OOV_L0 (1 << 16) /* Bit 16: Output Override PWML channel 0 */ +# define PWM_OOV_L1 (1 << 17) /* Bit 17: Output Override PWML channel 1 */ +# define PWM_OOV_L2 (1 << 18) /* Bit 18: Output Override PWML channel 2 */ +# define PWM_OOV_L3 (1 << 19) /* Bit 19: Output Override PWML channel 3 */ + +/* PWM Output Selection Register */ + +#define PWM_OS_H(n) (1 << (n)) /* Bits 0-3: Output Selection for PWMH channel n, n=0..3 */ +# define PWM_OS_H0 (1 << 0) /* Bit 0: Output Selection for PWMH channel 0 */ +# define PWM_OS_H1 (1 << 1) /* Bit 0: Output Selection for PWMH channel 0 */ +# define PWM_OS_H2 (1 << 2) /* Bit 0: Output Selection for PWMH channel 0 */ +# define PWM_OS_H3 (1 << 3) /* Bit 0: Output Selection for PWMH channel 0 */ +#define PWM_OS_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Selection for PWML channel n, n=0..3 */ +# define PWM_OS_L0 (1 << 16) /* Bit 16: Output Selection for PWML channel 0 */ +# define PWM_OS_L1 (1 << 17) /* Bit 17: Output Selection for PWML channel 1 */ +# define PWM_OS_L2 (1 << 18) /* Bit 18: Output Selection for PWML channel 2 */ +# define PWM_OS_L3 (1 << 19) /* Bit 19: Output Selection for PWML channel 3 */ + +/* PWM Output Selection Set Register */ + +#define PWM_OSS_H(n) (1 << (n)) /* Bits 0-3: Output Selection Set for PWMH channel n, n=0..3 */ +# define PWM_OSS_H0 (1 << 0) /* Bit 0: Output Selection Set for PWMH channel 0 */ +# define PWM_OSS_H1 (1 << 1) /* Bit 1: Output Selection Set for PWMH channel 1 */ +# define PWM_OSS_H2 (1 << 2) /* Bit 2: Output Selection Set for PWMH channel 2 */ +# define PWM_OSS_H3 (1 << 3) /* Bit 3: Output Selection Set for PWMH channel 3 */ +#define PWM_OSS_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Selection Set for PWML channel n, n=0..3 */ +# define PWM_OSS_L0 (1 << 16) /* Bit 16: Output Selection Set for PWML channel 0 */ +# define PWM_OSS_L1 (1 << 17) /* Bit 17: Output Selection Set for PWML channel 1 */ +# define PWM_OSS_L2 (1 << 18) /* Bit 18: Output Selection Set for PWML channel 2 */ +# define PWM_OSS_L3 (1 << 19) /* Bit 19: Output Selection Set for PWML channel 3 */ + +/* PWM Output Selection Clear Register */ + +#define PWM_OSC_H(n) (1 << (n)) /* Bits 0-3: Output Selection Clear for PWMH channel n, n=0..3 */ +# define PWM_OSC_H0 (1 << 0) /* Bit 0: Output Selection Clear for PWMH channel 0 */ +# define PWM_OSC_H1 (1 << 1) /* Bit 1: Output Selection Clear for PWMH channel 1 */ +# define PWM_OSC_H2 (1 << 2) /* Bit 2: Output Selection Clear for PWMH channel 2 */ +# define PWM_OSC_H3 (1 << 3) /* Bit 3: Output Selection Clear for PWMH channel 3 */ +#define PWM_OSC_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Selection Clear for PWML channel n, n=0..3 */ +# define PWM_OSC_L0 (1 << 16) /* Bit 16: Output Selection Clear for PWML channel 0 */ +# define PWM_OSC_L1 (1 << 17) /* Bit 17: Output Selection Clear for PWML channel 1 */ +# define PWM_OSC_L2 (1 << 18) /* Bit 18: Output Selection Clear for PWML channel 2 */ +# define PWM_OSC_L3 (1 << 19) /* Bit 19: Output Selection Clear for PWML channel 3 */ + +/* PWM Output Selection Set Update Register */ + +#define PWM_OSSUPD_H(n) (1 << (n)) /* Bits 0-3: Output Selection Set for PWMH channel n, n=0..3 */ +# define PWM_OSSUPD_H0 (1 << 0) /* Bit 0: Output Selection Set for PWMH channel 0 */ +# define PWM_OSSUPD_H1 (1 << 1) /* Bit 1: Output Selection Set for PWMH channel 1 */ +# define PWM_OSSUPD_H2 (1 << 2) /* Bit 2: Output Selection Set for PWMH channel 2 */ +# define PWM_OSSUPD_H3 (1 << 3) /* Bit 3: Output Selection Set for PWMH channel 3 */ +#define PWM_OSSUPD_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Selection Set for PWML channel n, n=0..3 */ +# define PWM_OSSUPD_L0 (1 << 16) /* Bit 16: Output Selection Set for PWML channel 0 */ +# define PWM_OSSUPD_L1 (1 << 17) /* Bit 17: Output Selection Set for PWML channel 1 */ +# define PWM_OSSUPD_L2 (1 << 18) /* Bit 18: Output Selection Set for PWML channel 2 */ +# define PWM_OSSUPD_L3 (1 << 19) /* Bit 19: Output Selection Set for PWML channel 3 */ + +/* PWM Output Selection Clear Update Register */ + +#define PWM_OSCUPD_H(n) (1 << (n)) /* Bits 0-3: Output Selection Clear for PWMH channel n, n=0..3 */ +# define PWM_OSCUPD_H0 (1 << 0) /* Bit 0: Output Selection Clear for PWMH channel 0 */ +# define PWM_OSCUPD_H1 (1 << 1) /* Bit 1: Output Selection Clear for PWMH channel 1 */ +# define PWM_OSCUPD_H2 (1 << 2) /* Bit 2: Output Selection Clear for PWMH channel 2 */ +# define PWM_OSCUPD_H3 (1 << 3) /* Bit 3: Output Selection Clear for PWMH channel 3 */ +#define PWM_OSCUPD_L(n) (1 << ((n)+16)) /* Bits 16-19: Output Selection Clear for PWML channel n, n=0..3 */ +# define PWM_OSCUPD_L0 (1 << 16) /* Bit 16: Output Selection Clear for PWML channel 0 */ +# define PWM_OSCUPD_L1 (1 << 17) /* Bit 17: Output Selection Clear for PWML channel 1 */ +# define PWM_OSCUPD_L2 (1 << 18) /* Bit 18: Output Selection Clear for PWML channel 2 */ +# define PWM_OSCUPD_L3 (1 << 19) /* Bit 19: Output Selection Clear for PWML channel 3 */ + +/* PWM Fault Mode Register */ + +#define PWM_FMR_FPOL_SHIFT (0) /* Bits 0-7: Fault Polarity */ +#define PWM_FMR_FPOL_MASK (0xff << PWM_FMR_FPOL_SHIFT) +# define PWM_FMR_FPOL(n) ((uint32_t)(n) << PWM_FMR_FPOL_SHIFT) +#define PWM_FMR_FMOD_SHIFT (8) /* Bits 8-15: Fault Activation Mode */ +#define PWM_FMR_FMOD_MASK (0xff << PWM_FMR_FMOD_SHIFT) +# define PWM_FMR_FMOD(n) ((uint32_t)(n) << PWM_FMR_FMOD_SHIFT) +#define PWM_FMR_FFIL_SHIFT (16) /* Bits 16-23: Fault Filtering */ +#define PWM_FMR_FFIL_MASK (0xff << PWM_FMR_FFIL_SHIFT) +# define PWM_FMR_FFIL(n) ((uint32_t)(n) << PWM_FMR_FFIL_SHIFT) + +/* PWM Fault Status Register */ + +#define PWM_FSR_FIV_SHIFT (0) /* Bits 0-7: Fault Input Value */ +#define PWM_FSR_FIV_MASK (0xff << PWM_FSR_FIV_SHIFT) +# define PWM_FSR_FIV(n) ((uint32_t)(n) << PWM_FSR_FIV_SHIFT) +#define PWM_FSR_FS_SHIFT (8) /* Bits 8-15: Fault Status */ +#define PWM_FSR_FS_MASK (0xff << PWM_FSR_FS_SHIFT) +# define PWM_FSR_FS(n) ((uint32_t)(n) << PWM_FSR_FS_SHIFT) + +/* PWM Fault Clear Register */ + +#define PWM_FCR_FCLR_SHIFT (0) /* Bits 0-7: Fault Clear */ +#define PWM_FCR_FCLR_MASK (0xff << PWM_FCR_FCLR_SHIFT) +# define PWM_FCR_FCLR(n) (1 << (n)) /* Fault Clear n, n=0..7 */ + +/* PWM Fault Protection Value Register 1 */ + +#define PWM_FPV_H(n) (1 << (n)) /* Bits 0-3: Fault Protection PWMH output on channel n, n=0..3 */ +# define PWM_FPV_H0 (1 << 0) /* Bit 0: Fault Protection PWMH output on channel 0 */ +# define PWM_FPV_H1 (1 << 1) /* Bit 1: Fault Protection PWMH output on channel 1 */ +# define PWM_FPV_H2 (1 << 2) /* Bit 2: Fault Protection PWMH output on channel 2 */ +# define PWM_FPV_H3 (1 << 3) /* Bit 3: Fault Protection PWMH output on channel 3 */ +#define PWM_FPV_L(n) (1 << ((n)+16)) /* Bits 16-19: Fault Protection PWML output on channel n, n=0..3 */ +# define PWM_FPV_L0 (1 << 16) /* Bit 16: Fault Protection PWML output on channel 0 */ +# define PWM_FPV_L1 (1 << 17) /* Bit 17: Fault Protection PWML output on channel 1 */ +# define PWM_FPV_L2 (1 << 18) /* Bit 18: Fault Protection PWML output on channel 2 */ +# define PWM_FPV_L3 (1 << 19) /* Bit 19: Fault Protection PWML output on channel 3 */ + +/* PWM Fault Protection Enable Register */ + +#define PWM_FPE_SHIFT(n) (1 << ((n) << 3)) /* Fault Protection Enable for channel n, n=0..3 */ +#define PWM_FPE_MASK(n) (0xff << PWM_FPE_SHIFT(n)) +# define PWM_FPE(n,v) ((uint32_t)(v) << PWM_FPE_SHIFT(n)) +#define PWM_FPE0_SHIFT (0) /* Bits 0-7: Fault Protection Enable for channel 0 */ +#define PWM_FPE0_MASK (0xff << PWM_FPE0_SHIFT) +# define PWM_FPE0(n) ((uint32_t)(n) << PWM_FPE0_SHIFT) +#define PWM_FPE1_SHIFT (8) /* Bits 8-15: Fault Protection Enable for channel 1 */ +#define PWM_FPE1_MASK (0xff << PWM_FPE1_SHIFT) +# define PWM_FPE1(n) ((uint32_t)(n) << PWM_FPE1_SHIFT) +#define PWM_FPE2_SHIFT (16) /* Bits 16-23: Fault Protection Enable for channel 2 */ +#define PWM_FPE2_MASK (0xff << PWM_FPE2_SHIFT) +# define PWM_FPE2(n) ((uint32_t)(n) << PWM_FPE2_SHIFT) +#define PWM_FPE3_SHIFT (24) /* Bits 24-31: Fault Protection Enable for channel 3 */ +#define PWM_FPE3_MASK (0xff << PWM_FPE3_SHIFT) +# define PWM_FPE3(n) ((uint32_t)(n) << PWM_FPE3_SHIFT) + +/* PWM Event Line 0/1 Mode Register */ + +#define PWM_ELMR_CSEL(n) (1 << (n)) /* Bits 0-7: Comparison n Selection, n=0..7 */ +# define PWM_ELMR_CSEL0 (1 << 0) /* Bit 0: Comparison 0 Selection */ +# define PWM_ELMR_CSEL1 (1 << 1) /* Bit 1: Comparison 1 Selection */ +# define PWM_ELMR_CSEL2 (1 << 2) /* Bit 2: Comparison 2 Selection */ +# define PWM_ELMR_CSEL3 (1 << 3) /* Bit 3: Comparison 3 Selection */ +# define PWM_ELMR_CSEL4 (1 << 4) /* Bit 4: Comparison 4 Selection */ +# define PWM_ELMR_CSEL5 (1 << 5) /* Bit 5: Comparison 5 Selection */ +# define PWM_ELMR_CSEL6 (1 << 6) /* Bit 6: Comparison 6 Selection */ +# define PWM_ELMR_CSEL7 (1 << 7) /* Bit 7: Comparison 7 Selection */ + +#ifdef ATSAMA5D4 +/* PWM Spread Spectrum Register */ + +# define PWM_SSPR_SPRD_SHIFT (0) /* Bits 0-23: Spread Spectrum Limit Value */ +# define PWM_SSPR_SPRD_MASK (0x00ffffff << PWM_SSPR_SPRD_SHIFT) +# define PWM_SSPR_SPRD(n) ((uint32_t)(n) << PWM_SSPR_SPRD_SHIFT) +# define PWM_SSPR_SPRDM (1 << 24) /* Bit 24: Spread Spectrum Counter Mode */ +#endif + +#ifdef ATSAMA5D4 +/* PWM Spread Spectrum Update Register */ + +# define PWM_SSPUP_SPRDUP_SHIFT (0) /* Bits 0-23: Spread Spectrum Limit Value Update */ +# define PWM_SSPUP_SPRDUP_MASK (0x00ffffff << PWM_SSPUP_SPRDUP_SHIFT) +# define PWM_SSPUP_SPRDUP(n) ((uint32_t)(n) << PWM_SSPUP_SPRDUP_SHIFT) +#endif + +/* PWM Stepper Motor Mode Register */ + +#define PWM_SMMR_GCEN(n) (1 << (n)) /* Bits 0-1: Gray Count ENable, n=0..1 */ +# define PWM_SMMR_GCEN0 (1 << 0) /* Bit 0: Enables gray count generation on PWMH/L[0] and PWMH/L[1] */ +# define PWM_SMMR_GCEN1 (1 << 1) /* Bits 1: Enables gray count generation on PWMH/L[2] and PWMH/L[3] */ +#define PWM_SMMR_DOWN(n) (1 << ((n)+16)) /* Bits 16-17: DOWN Count, n=0..1 */ +# define PWM_SMMR_DOWN0 (1 << 16) +# define PWM_SMMR_DOWN1 (1 << 17) + +#ifdef ATSAMA5D4 +/* PWM Fault Protection Value Register 2 */ + +#define PWM_FPV2_FPZH(n) (1 << (n)) /* Bits 0-3: Fault Protection Hi-Z for PWMH channel n, n=0..3 */ +# define PWM_FPV2_FPZH0 (1 << 0) /* Bit 0: Fault Protection Hi-Z for PWMH channel 0 */ +# define PWM_FPV2_FPZH1 (1 << 1) /* Bit 1: Fault Protection Hi-Z for PWMH channel 1 */ +# define PWM_FPV2_FPZH2 (1 << 2) /* Bit 2: Fault Protection Hi-Z for PWMH channel 2 */ +# define PWM_FPV2_FPZH3 (1 << 3) /* Bit 3: Fault Protection Hi-Z for PWMH channel 3 */ +#define PWM_FPV2_L(n) (1 << ((n)+16)) /* Bits 16-19: Fault Protection Hi-Z for PWML channel n, n=0..3 */ +# define PWM_FPV2_FPZL0 (1 << 16) /* Bit 16: Fault Protection Hi-Z for PWML channel 0 */ +# define PWM_FPV2_FPZL1 (1 << 17) /* Bit 17: Fault Protection Hi-Z for PWML channel 1 */ +# define PWM_FPV2_FPZL2 (1 << 18) /* Bit 18: Fault Protection Hi-Z for PWML channel 2 */ +# define PWM_FPV2_FPZL3 (1 << 19) /* Bit 19: FFault Protection Hi-Z for PWML channel 3 */ +#endif + +/* PWM Write Protect Control Register */ + +#define PWM_WPCR_WPCMD_SHIFT (0) /* Bits 0-1: Write Protect Command */ +#define PWM_WPCR_WPCMD_MASK (3 << PWM_WPCR_WPCMD_SHIFT) +# define PWM_WPCR_WPCMD_DSWPROT (0 << PWM_WPCR_WPCMD_SHIFT) /* Disable software write protection */ +# define PWM_WPCR_WPCMD_ESWPROT (1 << PWM_WPCR_WPCMD_SHIFT) /* Enable software write protection */ +# define PWM_WPCR_WPCMD_EHWPROT (2 << PWM_WPCR_WPCMD_SHIFT) /* Enable hardware write protection */ +#define PWM_WPCR_WPRG(n) (1 << ((n)+2)) /* Bits 2-7: Write Protect Register Group n, n=0..5 */ +# define PWM_WPCR_WPRG0 (1 << 2) /* Bit 2: Write Protect Register Group 0 */ +# define PWM_WPCR_WPRG1 (1 << 3) /* Bit 3: Write Protect Register Group 1 */ +# define PWM_WPCR_WPRG2 (1 << 4) /* Bit 4: Write Protect Register Group 2 */ +# define PWM_WPCR_WPRG3 (1 << 5) /* Bit 5: Write Protect Register Group 3 */ +# define PWM_WPCR_WPRG4 (1 << 6) /* Bit 6: Write Protect Register Group 4 */ +# define PWM_WPCR_WPRG5 (1 << 7) /* Bit 7: Write Protect Register Group 5 */ +#define PWM_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect Key */ +#define PWM_WPCR_WPKEY_MASK (0x00ffffff << PWM_WPCR_WPKEY_SHIFT) +# define PWM_WPCR_WPKEY (0x0050574d << PWM_WPCR_WPKEY_SHIFT) /* "PWM" in ASCII) */ + +/* PWM Write Protect Status Register */ + +#define PWM_WPSR_WPSWS(n) (1 << (n)) /* Bits 0-5: Write Protect SW Status, n=0..5 */ +# define PWM_WPSR_WPSWS0 (1 << 0) /* Bit 0: Write Protect SW Status 0 */ +# define PWM_WPSR_WPSWS1 (1 << 1) /* Bit 1: Write Protect SW Status 1 */ +# define PWM_WPSR_WPSWS2 (1 << 2) /* Bit 2: Write Protect SW Status 2 */ +# define PWM_WPSR_WPSWS3 (1 << 3) /* Bit 3: Write Protect SW Status 3 */ +# define PWM_WPSR_WPSWS4 (1 << 4) /* Bit 4: Write Protect SW Status 4 */ +# define PWM_WPSR_WPSWS5 (1 << 5) /* Bit 5: Write Protect SW Status 5 */ +#define PWM_WPSR_WPVS (1 << 7) /* Bit 7: Write Protect Violation Status */ +#define PWM_WPSR_WPHWS(n) (1 << ((n)+8)) /* Bits 8-13: Write Protect HW Status, n=0..5 */ +# define PWM_WPSR_WPHWS0 (1 << 8) /* Bit 8: Write Protect HW Status 0 */ +# define PWM_WPSR_WPHWS1 (1 << 9) /* Bit 9: Write Protect HW Status 1 */ +# define PWM_WPSR_WPHWS2 (1 << 10) /* Bit 10: Write Protect HW Status 2 */ +# define PWM_WPSR_WPHWS3 (1 << 11) /* Bit 11: Write Protect HW Status 3 */ +# define PWM_WPSR_WPHWS4 (1 << 12) /* Bit 12: Write Protect HW Status 4 */ +# define PWM_WPSR_WPHWS5 (1 << 13) /* Bit 13: Write Protect HW Status 5 */ +#define PWM_WPSR_WPVSRC_SHIFT (16) /* Bits 16-31: Write Protect Violation Source */ +#define PWM_WPSR_WPVSRC_MASK (0xffff << PWM_WPSR_WPVSRC_SHIFT) + +/* PWM Comparison n Value Register, n=0..7 */ + +#define PWM_CMPV_CV_SHIFT (0) /* Bits 0-23: Comparison Value */ +#define PWM_CMPV_CV_MASK (0xffffff << PWM_CMPV_CV_SHIFT) +# define PWM_CMPV_CV(n) ((uint32_t)(n) << PWM_CMPV_CV_SHIFT) +#define PWM_CMPV_CVM (1 << 24) /* Bits 24: Comparison Value Mode */ + +/* PWM Comparison n Value Update Register, n=0..7 */ + +#define PWM_CMPVUPD_CVUPD_SHIFT (0) /* Bits 0-24: Comparison Value Update */ +#define PWM_CMPVUPD_CVUPD_MASK (0xffffff << PWM_CMPVUPD_CVUPD_SHIFT) +# define PWM_CMPVUPD_CVUPD(n) ((uint32_t)(n) << PWM_CMPVUPD_CVUPD_SHIFT) +#define PWM_CMPVUPD_CVMUPD (1 << 24) /* Bits 24: Comparison Value Mode Update */ + +/* PWM Comparison n Mode Register, n=0..7 */ + +#define PWM_CMPM_CEN (1 << 0)) /* Bit 0: Comparison Enable */ +#define PWM_CMPM_CTR_SHIFT (4) /* Bits 4-7: Comparison Trigger */ +#define PWM_CMPM_CTR_MASK (15 << PWM_CMPM_CTR_SHIFT) +# define PWM_CMPM_CTR(n) ((uint32_t)(n) << PWM_CMPM_CTR_SHIFT) +#define PWM_CMPM_CPR_SHIFT (8) /* Bits 8-11: Comparison Period */ +#define PWM_CMPM_CPR_MASK (15 << PWM_CMPM_CPR_SHIFT) +# define PWM_CMPM_CPR(n) ((uint32_t)(n) << PWM_CMPM_CPR_SHIFT) +#define PWM_CMPM_CPRCNT_SHIFT (12) /* Bits 12-15: Comparison Period Counter */ +#define PWM_CMPM_CPRCNT_MASK (15 << PWM_CMPM_CPRCNT_SHIFT) +# define PWM_CMPM_CPRCNT(n) ((uint32_t)(n) << PWM_CMPM_CPRCNT_SHIFT) +#define PWM_CMPM_CUPR_SHIFT (16) /* Bits 16-19: Comparison Update Period */ +#define PWM_CMPM_CUPR_MASK (15 << PWM_CMPM_CUPR_SHIFT) +# define PWM_CMPM_CUPR(n) ((uint32_t)(n) << PWM_CMPM_CUPR_SHIFT) +#define PWM_CMPM_CUPRCNT_SHIFT (20) /* Bits 20-23: Comparison Update Period Counter */ +#define PWM_CMPM_CUPRCNT_MASK (15 << PWM_CMPM_CUPRCNT_SHIFT) +# define PWM_CMPM_CUPRCNT(n) ((uint32_t)(n) << PWM_CMPM_CUPRCNT_SHIFT) + +/* PWM Comparison n Mode Update Register, n=0..7 */ + +#define PWM_CMPMUPD_CENUPD (1 << 0) /* Bit 0: Comparison Enable Update */ +#define PWM_CMPMUPD_CTRUPD_SHIFT (4) /* Bits 4-7: Comparison Trigger Update */ +#define PWM_CMPMUPD_CTRUPD_MASK (15 << PWM_CMPMUPD_CTRUPD_SHIFT) +# define PWM_CMPMUPD_CTRUPD(n) ((uint32_t)(n) << PWM_CMPMUPD_CTRUPD_SHIFT) +#define PWM_CMPMUPD_CPRUPD_SHIFT (8) /* Bits 8-11: Comparison Period Up */ +#define PWM_CMPMUPD_CPRUPD_MASK (15 << PWM_CMPMUPD_CPRUPD_SHIFT) +# define PWM_CMPMUPD_CPRUPD(n) ((uint32_t)(n) << PWM_CMPMUPD_CPRUPD_SHIFT) +#define PWM_CMPMUPD_CUPRUPD_SHIFT (16) /* Bits 16-19: Comparison xpdate Period Update */ +#define PWM_CMPMUPD_CUPRUPD_MASK (15 << PWM_CMPMUPD_CUPRUPD_SHIFT) +# define PWM_CMPMUPD_CUPRUPD(n) ((uint32_t)(n) << PWM_CMPMUPD_CUPRUPD_SHIFT) + +/* PWM Channel Mode Register */ + +#define PWM_CMR_CPRE_SHIFT (0) /* Bits 0-3: Channel Pre-scaler */ +#define PWM_CMR_CPRE_MASK (15 << PWM_CMR_CPRE_SHIFT) +# define PWM_CMR_CPRE_MCKDIV(n) ((uint32_t)(n) << PWM_CMR_CPRE_SHIFT) /* Master clock */ +# define PWM_CMR_CPRE_MCKDIV1 (0 << PWM_CMR_CPRE_SHIFT) /* Master clock/2 */ +# define PWM_CMR_CPRE_MCKDIV2 (1 << PWM_CMR_CPRE_SHIFT) /* Master clock/2 */ +# define PWM_CMR_CPRE_MCKDIV4 (2 << PWM_CMR_CPRE_SHIFT) /* Master clock/4 */ +# define PWM_CMR_CPRE_MCKDIV8 (3 << PWM_CMR_CPRE_SHIFT) /* Master clock/8 */ +# define PWM_CMR_CPRE_MCKDIV16 (4 << PWM_CMR_CPRE_SHIFT) /* Master clock/16 */ +# define PWM_CMR_CPRE_MCKDIV32 (5 << PWM_CMR_CPRE_SHIFT) /* Master clock/32 */ +# define PWM_CMR_CPRE_MCKDIV64 (6 << PWM_CMR_CPRE_SHIFT) /* Master clock/64 */ +# define PWM_CMR_CPRE_MCKDIV128 (7 << PWM_CMR_CPRE_SHIFT) /* Master clock/128 */ +# define PWM_CMR_CPRE_MCKDIV256 (8 << PWM_CMR_CPRE_SHIFT) /* Master clock/256 */ +# define PWM_CMR_CPRE_MCKDIV512 (9 << PWM_CMR_CPRE_SHIFT) /* Master clock/512 */ +# define PWM_CMR_CPRE_MCKDIV1024 (10 << PWM_CMR_CPRE_SHIFT) /* Master clock/1024 */ +# define PWM_CMR_CPRE_CLKA (11 << PWM_CMR_CPRE_SHIFT) /* Clock A */ +# define PWM_CMR_CPRE_CLKB (12 << PWM_CMR_CPRE_SHIFT) /* Clock B */ +#define PWM_CMR_CALG (1 << 8) /* Bit 8: Channel Alignment */ +#define PWM_CMR_CPOL (1 << 9) /* Bit 9: Channel Polarity */ +#define PWM_CMR_CES (1 << 10) /* Bit 10: Counter Event Selection */ + +#ifdef ATSAMA5D4 +# define PWM_CMR_UPDS (1 << 11) /* Bit 10: Update Selection */ +#endif + +#define PWM_CMR_DTE (1 << 16) /* Bit 16: Dead-Time Generator Enable */ +#define PWM_CMR_DTHI (1 << 17) /* Bit 17: Dead-Time PWMH Output Inverted */ +#define PWM_CMR_DTLI (1 << 18) /* Bit 18: Dead-Time PWML Output Inverted */ + +/* PWM Channel Duty Cycle Register */ + +#define PWM_CDTY_MASK (0x00ffffff) /* Bits 0-23: Channel Duty-Cycle */ + +/* PWM Channel Duty Cycle Update Register */ + +#define PWM_CDTYUPD_MASK (0x00ffffff) /* Bits 0-23: Channel Duty-Cycle Update */ + +/* PWM Channel Period Register */ + +#define PWM_CPRD_MASK (0x00ffffff) /* Bits 0-23: Channel Period */ + +/* PWM Channel Period Update Register */ + +#define PWM_CPRDUPD_MASK (0x00ffffff) /* Bits 0-23: Channel Period Update */ + +/* PWM Channel Counter Register */ + +#define PWM_CCNT_MASK (0x00ffffff) /* Bits 0-23:Channel Counter */ + +/* PWM Channel Dead Time Register */ + +#define PWM_DT_H_SHIFT (0) /* Bits 0-15: Dead-Time PWMH Output */ +#define PWM_DT_H_MASK (0xffff << PWM_DT_H_SHIFT) +# define PWM_DT_H(n) ((uint32_t)(n) << PWM_DT_H_SHIFT) +#define PWM_DT_L_SHIFT (16) /* Bits 16-31: Dead-Time PWML Output */ +#define PWM_DT_L_MASK (0xffff << PWM_DT_L_SHIFT) +# define PWM_DT_L(n) ((uint32_t)(n) << PWM_DT_L_SHIFT + +/* PWM Channel Dead Time Update Register */ + +#define PWM_DTUPD_H_SHIFT (0) /* Bits 0-15: Dead-Time Value Update for PWMH Output */ +#define PWM_DTUPD_H_MASK (0xffff << PWM_DTUPD_H_SHIFT) +# define PWM_DTUPD_H(n) ((uint32_t)(n) << PWM_DTUPD_H_SHIFT) +#define PWM_DTUPD_L_SHIFT (16) /* Bits 16-31: Dead-Time Value Update for PWML Output */ +#define PWM_DTUPD_L_MASK (0xffff << PWM_DTUPD_L_SHIFT) +# define PWM_DTUPD_L(n) ((uint32_t)(n) << PWM_DTUPD_L_SHIFT) + +#ifdef ATSAMA5D4 +/* PWM Channel Mode Update Register */ + +# define PWM_CMUPD_CPOLUP (1 << 9) /* Bit 9: Channel Polarity Update */ +# define PWM_CMUPD_CPOLINVUP (1 << 13) /* Bit 13: Channel Polarity Inversion Update */ +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_PWM_H */ diff --git a/arch/arm/src/sama5/chip/sam_rtc.h b/arch/arm/src/sama5/chip/sam_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..c6d81a8c3092096e5aa351ffcd699ddfb96be0c7 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_rtc.h @@ -0,0 +1,351 @@ +/**************************************************************************************** + * arch/arm/src/sama5d/chip/sam_rtc.h + * Real-time Clock (RTC) definitions for the SAMA5D3 + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RTC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RTC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RTC register offsets *****************************************************************/ + +#define SAM_RTC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_RTC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_RTC_TIMR_OFFSET 0x0008 /* Time Register */ +#define SAM_RTC_CALR_OFFSET 0x000c /* Calendar Register */ +#define SAM_RTC_TIMALR_OFFSET 0x0010 /* Time Alarm Register */ +#define SAM_RTC_CALALR_OFFSET 0x0014 /* Calendar Alarm Register */ +#define SAM_RTC_SR_OFFSET 0x0018 /* Status Register */ +#define SAM_RTC_SCCR_OFFSET 0x001c /* Status Clear Command Register */ +#define SAM_RTC_IER_OFFSET 0x0020 /* Interrupt Enable Register */ +#define SAM_RTC_IDR_OFFSET 0x0024 /* Interrupt Disable Register */ +#define SAM_RTC_IMR_OFFSET 0x0028 /* Interrupt Mask Register */ +#define SAM_RTC_VER_OFFSET 0x002c /* Valid Entry Register */ + +#ifdef ATSAMA5D4 +# define SAM_RTC_TSTR0_OFFSET 0x00b0 /* TimeStamp Time Register 0 */ +# define SAM_RTC_TSDR0_OFFSET 0x00b4 /* TimeStamp Date Register 0 */ +# define SAM_RTC_TSSR0_OFFSET 0x00b8 /* TimeStamp Source Register 0 */ +# define SAM_RTC_TSTR1_OFFSET 0x00bc /* TimeStamp Time Register 1 */ +# define SAM_RTC_TSDR1_OFFSET 0x00c0 /* TimeStamp Date Register 1 */ +# define SAM_RTC_TSSR1_OFFSET 0x00c4 /* TimeStamp Source Register 1 */ +#endif + +/* RTC register addresses ***************************************************************/ + +#define SAM_RTC_CR (SAM_RTCC_VBASE+SAM_RTC_CR_OFFSET) +#define SAM_RTC_MR (SAM_RTCC_VBASE+SAM_RTC_MR_OFFSET) +#define SAM_RTC_TIMR (SAM_RTCC_VBASE+SAM_RTC_TIMR_OFFSET) +#define SAM_RTC_CALR (SAM_RTCC_VBASE+SAM_RTC_CALR_OFFSET) +#define SAM_RTC_TIMALR (SAM_RTCC_VBASE+SAM_RTC_TIMALR_OFFSET) +#define SAM_RTC_CALALR (SAM_RTCC_VBASE+SAM_RTC_CALALR_OFFSET) +#define SAM_RTC_SR (SAM_RTCC_VBASE+SAM_RTC_SR_OFFSET) +#define SAM_RTC_SCCR (SAM_RTCC_VBASE+SAM_RTC_SCCR_OFFSET) +#define SAM_RTC_IER (SAM_RTCC_VBASE+SAM_RTC_IER_OFFSET) +#define SAM_RTC_IDR (SAM_RTCC_VBASE+SAM_RTC_IDR_OFFSET) +#define SAM_RTC_IMR (SAM_RTCC_VBASE+SAM_RTC_IMR_OFFSET) +#define SAM_RTC_VER (SAM_RTCC_VBASE+SAM_RTC_VER_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_RTC_TSTR0 (SAM_RTCC_VBASE+SAM_RTC_TSTR0_OFFSET) +# define SAM_RTC_TSDR0 (SAM_RTCC_VBASE+SAM_RTC_TSDR0_OFFSET) +# define SAM_RTC_TSSR0 (SAM_RTCC_VBASE+SAM_RTC_TSSR0_OFFSET) +# define SAM_RTC_TSTR1 (SAM_RTCC_VBASE+SAM_RTC_TSTR1_OFFSET) +# define SAM_RTC_TSDR1 (SAM_RTCC_VBASE+SAM_RTC_TSDR1_OFFSET) +# define SAM_RTC_TSSR1 (SAM_RTCC_VBASE+SAM_RTC_TSSR1_OFFSET) +#endif + +/* RTC register bit definitions *********************************************************/ + +/* RTC Control Register */ + +#define RTC_CR_UPDTIM (1 << 0) /* Bit 0: Update Request Time Register */ +#define RTC_CR_UPDCAL (1 << 1) /* Bit 1: Update Request Calendar Register */ +#define RTC_CR_TIMEVSEL_SHIFT (8) /* Bits 8-9: Time Event Selection */ +#define RTC_CR_TIMEVSEL_MASK (3 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIN (0 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_HOUR (1 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIDNIGHT (2 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_NOON (3 << RTC_CR_TIMEVSEL_SHIFT) +#define RTC_CR_CALEVSEL_SHIFT (16) /* Bits 16-17: Calendar Event Selection */ +#define RTC_CR_CALEVSEL_MASK (3 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_WEEK (0 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_MONTH (1 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_YEAR (2 << RTC_CR_CALEVSEL_SHIFT) + +/* RTC Mode Register */ + +#define RTC_MR_HRMOD (1 << 0) /* Bit 0: 12-/24-hour Mode */ + +#ifdef ATSAMA5D4 +# define RTC_MR_PERSIAN (1 << 1) /* Bit 1: PERSIAN Calendar */ +# define RTC_MR_NEGPPM (1 << 4) /* Bit 4: NEGative PPM Correction */ +# define RTC_MR_CORRECTION_SHIFT (8) /* Bits 8-14: Slow Clock Correction */ +# define RTC_MR_CORRECTION_MASK (0x7f << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_CORRECTION_NONE (0 << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_CORRECTION(n) ((uint8_t)(n) << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_HIGHPPM (1 << 15) /* Bit 15: HIGH PPM Correction */ +#endif + +/* RTC Time Register */ + +#define RTC_TIMR_SEC_SHIFT (0) /* Bits 0-6: Current Second */ +#define RTC_TIMR_SEC_MASK (0x7f << RTC_TIMR_SEC_SHIFT) +# define RTC_TIMR_SEC(n) ((uint32_t)(n) << RTC_TIMR_SEC_SHIFT) +#define RTC_TIMR_MIN_SHIFT (8) /* Bits 8-14: Current Minute */ +#define RTC_TIMR_MIN_MASK (0x7f << RTC_TIMR_MIN_SHIFT) +# define RTC_TIMR_MIN(n) ((uint32_t)(n) << RTC_TIMR_MIN_SHIFT) +#define RTC_TIMR_HOUR_SHIFT (16) /* Bits 16-21: Current Hour */ +#define RTC_TIMR_HOUR_MASK (0x3f << RTC_TIMR_HOUR_SHIFT) +# define RTC_TIMR_HOUR(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_TIMR_AMPM (1 << 22) /* Bit 22: Ante Meridiem Post Meridiem Indicator */ + +/* RTC Calendar Register */ + +#define RTC_CALR_CENT_SHIFT (0) /* Bits 0-6: Current Century */ +#define RTC_CALR_CENT_MASK (0x7f << RTC_CALR_CENT_SHIFT) +# define RTC_CALR_CENT(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_CALR_YEAR_SHIFT (8) /* Bits 8-15: Current Year */ +#define RTC_CALR_YEAR_MASK (0xff << RTC_CALR_YEAR_SHIFT) +# define RTC_CALR_YEAR(n) ((uint32_t)(n) << RTC_CALR_YEAR_SHIFT) +#define RTC_CALR_MONTH_SHIFT (16) /* Bits 16-20: Current Month */ +#define RTC_CALR_MONTH_MASK (0x1f << RTC_CALR_MONTH_SHIFT) +# define RTC_CALR_MONTH(n) ((uint32_t)(n) << RTC_CALR_MONTH_SHIFT) +#define RTC_CALR_DAY_SHIFT (21) /* Bits 21-23: Current Day in Current Week */ +#define RTC_CALR_DAY_MASK (7 << RTC_CALR_DAY_SHIFT) +# define RTC_CALR_DAY(n) ((uint32_t)(n) << RTC_CALR_DAY_SHIFT) +#define RTC_CALR_DATE_SHIFT (24) /* Bits 24-29: Current Day in Current Month */ +#define RTC_CALR_DATE_MASK (0x3f << RTC_CALR_DATE_SHIFT) +# define RTC_CALR_DATE(n) ((uint32_t)(n) << RTC_CALR_DATE_SHIFT) + +/* RTC Time Alarm Register */ + +#define RTC_TIMALR_SEC_SHIFT (0) /* Bits 0-6: Second Alarm */ +#define RTC_TIMALR_SEC_MASK (0x7f << RTC_TIMALR_SEC_SHIFT) +# define RTC_TIMALR_SEC(n) ((uint32_t)(n) << RTC_TIMALR_SEC_SHIFT) +#define RTC_TIMALR_SECEN (1 << 7) /* Bit 7: Second Alarm Enable */ +#define RTC_TIMALR_MIN_SHIFT (8) /* Bits 8-14: Minute Alarm */ +#define RTC_TIMALR_MIN_MASK (0x7f << RTC_TIMALR_MIN_SHIFT) +# define RTC_TIMALR_MIN(n) ((uint32_t)(n) << RTC_TIMALR_MIN_SHIFT) +#define RTC_TIMALR_MINEN (1 << 15) /* Bit 15: Minute Alarm Enable */ +#define RTC_TIMALR_HOUR_SHIFT (16) /* Bits 16-21: Hour Alarm */ +#define RTC_TIMALR_HOUR_MASK (0x3f << RTC_TIMALR_HOUR_SHIFT) +# define RTC_TIMALR_HOUR(n) ((uint32_t)(n) << RTC_TIMALR_HOUR_SHIFT) +#define RTC_TIMALR_AMPM (1 << 22) /* Bit 22: AM/PM Indicator */ +#define RTC_TIMALR_HOUREN (1 << 23) /* Bit 23: Hour Alarm Enable */ + +/* RTC Calendar Alarm Register */ + +#define RTC_CALALR_MONTH_SHIFT (16) /* Bits 16-20: Month Alarm */ +#define RTC_CALALR_MONTH_MASK (0x1f << RTC_CALALR_MONTH_SHIFT) +# define RTC_CALALR_MONTH(n) ((uint32_t)(n) << RTC_CALALR_MONTH_SHIFT) +#define RTC_CALALR_MTHEN (1 << 23) /* Bit 23: Month Alarm Enable */ +#define RTC_CALALR_DATE_SHIFT (24) /* Bits 24-29: Date Alarm */ +#define RTC_CALALR_DATE_MASK (0x3f << RTC_CALALR_DATE_SHIFT) +# define RTC_CALALR_DATE(n) ((uint32_t)(n) << RTC_CALALR_DATE_SHIFT) +#define RTC_CALALR_DATEEN (1 << 31) /* Bit 31: Date Alarm Enable */ + +/* RTC Status Register */ + +#define RTC_SR_ACKUPD (1 << 0) /* Bit 0: Acknowledge for Update */ +#define RTC_SR_ALARM (1 << 1) /* Bit 1: Alarm Flag */ +#define RTC_SR_SEC (1 << 2) /* Bit 2: Second Event */ +#define RTC_SR_TIMEV (1 << 3) /* Bit 3: Time Event */ +#define RTC_SR_CALEV (1 << 4) /* Bit 4: Calendar Event */ + +#ifdef ATSAMA5D4 +# define RTC_SR_TDERR (1 << 5) /* Bit 5: Time and/or Date Free Running Error */ +#endif + +/* RTC Status Clear Command Register */ + +#define RTC_SCCR_ACKCLR (1 << 0) /* Bit 0: Acknowledge Clear */ +#define RTC_SCCR_ALRCLR (1 << 1) /* Bit 1: Alarm Clear */ +#define RTC_SCCR_SECCLR (1 << 2) /* Bit 2: Second Clear */ +#define RTC_SCCR_TIMCLR (1 << 3) /* Bit 3: Time Clear */ +#define RTC_SCCR_CALCLR (1 << 4) /* Bit 4: Calendar Clear */ + +#ifdef ATSAMA5D4 +# define RTC_SCCR_TDERRCLR (1 << 5) /* Bit 5: Time and/or Date Free Running Error Clear */ +#endif + +/* RTC Interrupt Enable Register */ + +#define RTC_IER_ACKEN (1 << 0) /* Bit 0: Acknowledge Update Interrupt Enable */ +#define RTC_IER_ALREN (1 << 1) /* Bit 1: Alarm Interrupt Enable */ +#define RTC_IER_SECEN (1 << 2) /* Bit 2: Second Event Interrupt Enable */ +#define RTC_IER_TIMEN (1 << 3) /* Bit 3: Time Event Interrupt Enable */ +#define RTC_IER_CALEN (1 << 4) /* Bit 4: Calendar Event Interrupt Enable */ + +#ifdef ATSAMA5D4 +# define RTC_IER_TDERREN (1 << 5) /* Bit 5: Time and/or Date Free Running Error Enable */ +#endif + +/* RTC Interrupt Disable Register */ + +#define RTC_IDR_ACKDIS (1 << 0) /* Bit 0: Acknowledge Update Interrupt Disable */ +#define RTC_IDR_ALRDIS (1 << 1) /* Bit 1: Alarm Interrupt Disable */ +#define RTC_IDR_SECDIS (1 << 2) /* Bit 2: Second Event Interrupt Disable */ +#define RTC_IDR_TIMDIS (1 << 3) /* Bit 3: Time Event Interrupt Disable */ +#define RTC_IDR_CALDIS (1 << 4) /* Bit 4: Calendar Event Interrupt Disable */ + +#ifdef ATSAMA5D4 +# define RTC_IDR_TDERRDIS (1 << 5) /* Bit 5: Time and/or Date Free Running Error Disable */ +#endif + +/* RTC Interrupt Mask Register */ + +#define RTC_IMR_ACK (1 << 0) /* Bit 0: Acknowledge Update Interrupt Mask */ +#define RTC_IMR_ALR (1 << 1) /* Bit 1: Alarm Interrupt Mask */ +#define RTC_IMR_SEC (1 << 2) /* Bit 2: Second Event Interrupt Mask */ +#define RTC_IMR_TIM (1 << 3) /* Bit 3: Time Event Interrupt Mask */ +#define RTC_IMR_CAL (1 << 4) /* Bit 4: Calendar Event Interrupt Mask */ + +#ifdef ATSAMA5D4 +# define RTC_IMR_TDERR (1 << 5) /* Bit 5: Time and/or Date Free Running Error Mask */ +#endif + +/* RTC Valid Entry Register */ + +#define RTC_VER_NVTIM (1 << 0) /* Bit 0: Non-valid Time */ +#define RTC_VER_NVCAL (1 << 1) /* Bit 1: Non-valid Calendar */ +#define RTC_VER_NVTIMALR (1 << 2) /* Bit 2: Non-valid Time Alarm */ +#define RTC_VER_NVCALALR (1 << 3) /* Bit 3: Non-valid Calendar Alarm */ + +#ifdef ATSAMA5D4 +/* TimeStamp Time Register 0/1 */ + +# define RTC_TSTR_SEC_SHIFT (0) /* Bits 0-6: Seconds of the Tamper */ +# define RTC_TSTR_SEC_MASK (0x7f << RTC_TSTR_SEC_SHIFT) +# define RTC_TSTR_SEC(n) ((uint32_t)(n) << RTC_TSTR_SEC_SHIFT) +# define RTC_TSTR_MIN_SHIFT (8) /* Bits 8-14: Minutes of the Tamper */ +# define RTC_TSTR_MIN_MASK (0x7f << RTC_TSTR_MIN_SHIFT) +# define RTC_TSTR_MIN(n) ((uint32_t)(n) << RTC_TSTR_MIN_SHIFT) +# define RTC_TSTR_HOUR_SHIFT (16) /* Bits 16-21: Hours of the Tamper */ +# define RTC_TSTR_HOUR_MASK (0x3f << RTC_TSTR_HOUR_SHIFT) +# define RTC_TSTR_HOUR(n) ((uint32_t)(n) << RTC_TSTR_HOUR_SHIFT) +# define RTC_TSTR_AMPM (1 << 22) /* Bit 22: AM/PM Indicator of the Tamper */ + +/* Only TSTR0 has the event counter */ + +# define RTC_TSTR0_TEVCNT_SHIFT (24) /* Bits 24-27: Tamper Events Counter */ +# define RTC_TSTR0_TEVCNT_MASK (15 << RTC_TSTR0_TEVCNT_SHIFT) + +# define RTC_TSTR_BACKUP (1 << 31) /* Bit 31: System Mode of the Tamper */ +#endif + +#ifdef ATSAMA5D4 +/* TimeStamp Date Register 0 and 1 */ + +#define RTC_TSDR_CENT_SHIFT (0) /* Bits 0-6: Century of the Tamper */ +#define RTC_TSDR_CENT_MASK (0x7f << RTC_TSDR_CENT_SHIFT) +# define RTC_TSDR_CENT(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_TSDR_YEAR_SHIFT (8) /* Bits 8-15: Year of the Tamper */ +#define RTC_TSDR_YEAR_MASK (0xff << RTC_TSDR_YEAR_SHIFT) +# define RTC_TSDR_YEAR(n) ((uint32_t)(n) << RTC_TSDR_YEAR_SHIFT) +#define RTC_TSDR_MONTH_SHIFT (16) /* Bits 16-20: Month of the Tamper */ +#define RTC_TSDR_MONTH_MASK (0x1f << RTC_TSDR_MONTH_SHIFT) +# define RTC_TSDR_MONTH(n) ((uint32_t)(n) << RTC_TSDR_MONTH_SHIFT) +#define RTC_TSDR_DAY_SHIFT (21) /* Bits 21-23: Day of the Tamper */ +#define RTC_TSDR_DAY_MASK (7 << RTC_TSDR_DAY_SHIFT) +# define RTC_TSDR_DAY(n) ((uint32_t)(n) << RTC_TSDR_DAY_SHIFT) +#define RTC_TSDR_DATE_SHIFT (24) /* Bits 24-29: Date of the Tamper */ +#define RTC_TSDR_DATE_MASK (0x3f << RTC_TSDR_DATE_SHIFT) +# define RTC_TSDR_DATE(n) ((uint32_t)(n) << RTC_TSDR_DATE_SHIFT) +#endif + +#ifdef ATSAMA5D4 +/* TimeStamp Source Register 0 and 1*/ + +# define RTC_TSSR_SHLDM (1 << 0) /* Bit 0: Shield Monitor */ +# define RTC_TSSR_DBLFM (1 << 1) /* Bit 1: Double Frequency Monitor */ +# define RTC_TSSR_TST (1 << 2) /* Bit 2: Test Pin Monitor */ +# define RTC_TSSR_JTAG (1 << 3) /* Bit 3: JTAG Pins Monitor */ +# define RTC_TSSR_REGUL (1 << 4) /* Bit 4: Core Regulator Disconnection Monitor */ +# define RTC_TSSR_MCKM (1 << 5) /* Bit 5: Master Clock Monitor */ +# define RTC_TSSR_TPML (1 << 6) /* Bit 6: Low Temperature Monitor */ +# define RTC_TSSR_TPMH (1 << 7) /* Bit 7: High Temperature Monitor */ +# define RTC_TSSR_VDDBUL (1 << 8) /* Bit 8: Low VDDBU Voltage Monitor */ +# define RTC_TSSR_VDDBUH (1 << 9) /* Bit 9: High VDDBU Voltage Monitor */ +# define RTC_TSSR_VDDCOREL (1 << 10) /* Bit 10: Low VDDCORE Voltage Monitor */ +# define RTC_TSSR_VDDCOREH (1 << 11) /* Bit 11: High VDDCORE Voltage Monitor */ +# define RTC_TSSR_VDDIOL (1 << 12) /* Bit 12: Low VDDIO Voltage Monitor */ +# define RTC_TSSR_VDDIOH (1 << 13) /* Bit 13: High VDDIO Voltage Monitor */ +# define RTC_TSSR_VDDRL (1 << 14) /* Bit 14: Low VDDDDR Voltage Monitor */ +# define RTC_TSSR_VDDRH (1 << 15) /* Bit 15: High VDDDDR Voltage Monitor */ + +# define RTC_TSSR_DET(n) (1 << ((n) + 16)) +# define RTC_TSSR_DET0 (1 << 16) /* Bit 16: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET1 (1 << 17) /* Bit 17: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET2 (1 << 18) /* Bit 18: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET3 (1 << 19) /* Bit 19: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET4 (1 << 20) /* Bit 20: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET5 (1 << 21) /* Bit 21: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET6 (1 << 22) /* Bit 22: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET7 (1 << 23) /* Bit 23: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET8 (1 << 24) /* Bit 24: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET9 (1 << 25) /* Bit 25: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET10 (1 << 26) /* Bit 26: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET11 (1 << 27) /* Bit 27: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET12 (1 << 28) /* Bit 28: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET13 (1 << 29) /* Bit 29: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET14 (1 << 30) /* Bit 30: PIOBU Intrusion Detector */ +# define RTC_TSSR_DET15 (1 << 31) /* Bit 31: PIOBU Intrusion Detector */ +#endif + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RTC_H */ diff --git a/arch/arm/src/sama5/chip/sam_rxlp.h b/arch/arm/src/sama5/chip/sam_rxlp.h new file mode 100644 index 0000000000000000000000000000000000000000..b9bebee44345e36822f45e0189e2a5f635a90e2a --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_rxlp.h @@ -0,0 +1,134 @@ +/************************************************************************************************ + * arch/arm/src/sama5/chip/sam_RXLP.h + * Low Power Asynchronous Receiver (RXLP) definitions for the SAMA5D3 + * and SAMAD4 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RXLP_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RXLP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* RXLP register offsets ************************************************************************/ + +#define SAM_RXLP_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_RXLP_MR_OFFSET 0x0004 /* Mode Register */ + /* 0x0008-0x0014: Reserved */ +#define SAM_RXLP_RHR_OFFSET 0x0018 /* Receive Holding Register */ + /* 0x001c: Reserved */ +#define SAM_RXLP_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register */ +#define SAM_RXLP_CMPR_OFFSET 0x0024 /* Comparison Register */ + /* 0x0024-0x00e0: Reserved */ +#define SAM_RXLP_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register (4) */ + /* 0x00e8-0xfc: Reserved */ + +/* RXLP register adresses ***********************************************************************/ + +#define SAM_RXLP0_CR (SAM_RXLP_VBASE+SAM_RXLP_CR_OFFSET) +#define SAM_RXLP0_MR (SAM_RXLP_VBASE+SAM_RXLP_MR_OFFSET) +#define SAM_RXLP0_RHR (SAM_RXLP_VBASE+SAM_RXLP_RHR_OFFSET) +#define SAM_RXLP0_BRGR (SAM_RXLP_VBASE+SAM_RXLP_BRGR_OFFSET) +#define SAM_RXLP0_CMPR (SAM_RXLP_VBASE+SAM_RXLP_CMPR_OFFSET) +#define SAM_RXLP0_WPMR (SAM_RXLP_VBASE+SAM_RXLP_WPMR_OFFSET) + +/* RXLP register bit definitions ****************************************************************/ + +/* RXLP Control Register */ + +#define RXLP_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver (Common) */ +#define RXLP_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable (Common) */ +#define RXLP_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable (Common) */ + +/* RXLP Mode Register */ + +#define RXLP_MR_FILTER (1 << 4) /* Bit 4: Receiver Digital Filter */ +#define RXLP_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type (2) */ +#define RXLP_MR_PAR_MASK (7 << RXLP_MR_PAR_SHIFT) +# define RXLP_MR_PAR_EVEN (0 << RXLP_MR_PAR_SHIFT) /* Even parity */ +# define RXLP_MR_PAR_ODD (1 << RXLP_MR_PAR_SHIFT) /* Odd parity */ +# define RXLP_MR_PAR_SPACE (2 << RXLP_MR_PAR_SHIFT) /* Space: parity forced to 0 */ +# define RXLP_MR_PAR_MARK (3 << RXLP_MR_PAR_SHIFT) /* Mark: parity forced to 1 */ +# define RXLP_MR_PAR_NONE (4 << RXLP_MR_PAR_SHIFT) /* No parity */ + +/* RXLP Receiver Holding Register */ + +#define RXLP_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character (RXLP only) */ +#define RXLP_RHR_RXCHR_MASK (3 << RXLP_RHR_RXCHR_SHIFT) +# define RXLP_RHR_RXCHR(n) ((uint32_t)(n) << RXLP_RHR_RXCHR_SHIFT) + +/* RXLP Baud Rate Generator Register */ + +#define RXLP_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor (Common) */ +#define RXLP_BRGR_CD_MASK (0xffff << RXLP_BRGR_CD_SHIFT) + +/* Comparison Register */ + +#define RXLP_CMPR_VAL1_SHIFT (0) /* Bits 0-7: First Comparison Value for Received Character */ +#define RXLP_CMPR_VAL1_MASK (0xff << RXLP_CMPR_VAL1_SHIFT) +# define RXLP_CMPR_VAL1(n) ((uint32_t)(n) << RXLP_CMPR_VAL1_SHIFT) +#define RXLP_CMPR_VAL2_SHIFT (16) /* Bits 16-23: Second Comparison Value for Received Character */ +#define RXLP_CMPR_VAL2_MASK (0xff << RXLP_CMPR_VAL2_SHIFT) +# define RXLP_CMPR_VAL2(n) ((uint32_t)(n) << RXLP_CMPR_VAL2_SHIFT) + +/* RXLP Write Protect Mode Register */ + +#define RXLP_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define RXLP_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define RXLP_WPMR_WPKEY_MASK (0x00ffffff << RXLP_WPMR_WPKEY_SHIFT) +# define RXLP_WPMR_WPKEY (0x0052584c << RXLP_WPMR_WPKEY_SHIFT) /* "RXL" */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_RXLP_H */ diff --git a/arch/arm/src/sama5/chip/sam_sckc.h b/arch/arm/src/sama5/chip/sam_sckc.h new file mode 100644 index 0000000000000000000000000000000000000000..e9071585ae1dcc1f30d10cc5403a2082996e2acb --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_sckc.h @@ -0,0 +1,69 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_sckc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SCKC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SCKC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* SCKC Register Offsets ************************************************************/ + +#define SAM_SCKC_CR_OFFSET 0x0000 /* Slow Clock Controller Configuration Register */ + +/* SCKC Register Addresses **********************************************************/ + +#define SAM_SCKC_CR (SAM_SCKCR_VBASE+SAM_SCKC_CR_OFFSET) + +/* SCKC Register Bit Definitions ****************************************************/ + +/* Slow Clock Controller Configuration Register */ + +#ifdef ATSAMA5D3 +# define SCKC_CR_RCEN (1 << 0) /* Bit 0: Internal 32 kHz RC Oscillator */ +# define SCKC_CR_OSC32EN (1 << 1) /* Bit 1: 32768 Hz Oscillator */ +# define SCKC_CR_OSC32BYP (1 << 2) /* Bit 2: 2768Hz Oscillator Bypass */ +#endif + +#define SCKC_CR_OSCSEL (1 << 3) /* Bit 3: Slow Clock Selector */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SCKC_H */ diff --git a/arch/arm/src/sama5/chip/sam_sfr.h b/arch/arm/src/sama5/chip/sam_sfr.h new file mode 100644 index 0000000000000000000000000000000000000000..03926e7bd6246e2c60ffcb25557327073f61b254 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_sfr.h @@ -0,0 +1,313 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_sfr.h + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SFR_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SFR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* SFR Register Offsets *************************************************************/ + + /* 0x0000: Reserved */ +#define SAM_SFR_DDRCFG_OFFSET 0x0004 /* DDR Configuration register */ + /* 0x0008-0x000c: Reserved */ +#define SAM_SFR_OHCIICR_OFFSET 0x0010 /* OHCI Interrupt Configuration Register */ +#define SAM_SFR_OHCIISR_OFFSET 0x0014 /* OHCI Interrupt Status Register */ + /* 0x0018-0x001c: Reserved */ +#define SAM_SFR_SECURE_OFFSET 0x0028 /* Security Configuration Register */ + /* 0x002c: Reserved */ +#define SAM_SFR_UTMICKTRIM_OFFSET 0x0030 /* UTMI Clock Trimming Register */ + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_SFR_UTMIHSTRIM_OFFSET 0x0034 /* UTMI High Speed Trimming Register */ +# define SAM_SFR_UTMIFSTRIM_OFFSET 0x0038 /* UTMI Full Speed Trimming Register */ +# define SAM_SFR_UTMISWAP_OFFSET 0x003c /* UTMI DP/DM Pin Swapping Register */ +#endif + +#define SAM_SFR_EBICFG_OFFSET 0x0040 /* EBI Configuration Register */ + +#ifdef ATSAMA5D2 +# define SAM_SFR_ANACFG_OFFSET 0x0044 /* Analog Configuration Register */ +# define SAM_SFR_CAN_OFFSET 0x0048 /* CAN Memories Address-based Register */ +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_SFR_SN0_OFFSET 0x004c /* Serial Number 0 Register */ +# define SAM_SFR_SN1_OFFSET 0x0050 /* Serial Number 1 Register */ +# define SAM_SFR_AICREDIR_OFFSET 0x0054 /* AIC Redirection Register */ +#endif + +#ifdef ATSAMA5D2 +# define SAM_SFR_L2CCHRAMC_OFFSET 0x0044 /* L2CC HRAMC1 */ + /* 0x005c-0x008c: Reserved */ +# define SAM_SFR_I2SCLKSEL_OFFSET 0x0090 /* I2SC Register */ +# define SAM_SFR_QSPICLK_OFFSET 0x0094 /* QSPI Clock Pad Supply Select Register */ +#endif + /* 0x0098-0x3ffc: Reserved */ + +/* SFR Register Addresses ***********************************************************/ + +#define SAM_SFR_DDRCFG (SAM_SFR_VBASE+SAM_SFR_DDRCFG_OFFSET) /* REVISIT */ +#define SAM_SFR_OHCIICR (SAM_SFR_VBASE+SAM_SFR_OHCIICR_OFFSET) +#define SAM_SFR_OHCIISR (SAM_SFR_VBASE+SAM_SFR_OHCIISR_OFFSET) +#define SAM_SFR_SECURE (SAM_SFR_VBASE+SAM_SFR_SECURE_OFFSET) +#define SAM_SFR_UTMICKTRIM (SAM_SFR_VBASE+SAM_SFR_UTMICKTRIM_OFFSET) + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_SFR_UTMIHSTRIM (SAM_SFR_VBASE+SAM_SFR_UTMIHSTRIM_OFFSET) +# define SAM_SFR_UTMIFSTRIM (SAM_SFR_VBASE+SAM_SFR_UTMIFSTRIM_OFFSET) +# define SAM_SFR_UTMISWAP (SAM_SFR_VBASE+SAM_SFR_UTMISWAP_OFFSET) +#endif + +#define SAM_SFR_EBICFG (SAM_SFR_VBASE+SAM_SFR_EBICFG_OFFSET) + +#ifdef ATSAMA5D2 +# define SAM_SFR_ANACFG (SAM_SFR_VBASE+SAM_SFR_ANACFG_OFFSET) +# define SAM_SFR_CAN (SAM_SFR_VBASE+SAM_SFR_CAN_OFFSET) +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SAM_SFR_SN0 (SAM_SFR_VBASE+SAM_SFR_SN0_OFFSET) +# define SAM_SFR_SN1 (SAM_SFR_VBASE+SAM_SFR_SN1_OFFSET) +# define SAM_SFR_AICREDIR (SAM_SFR_VBASE+SAM_SFR_AICREDIR_OFFSET) +#endif + +#ifdef ATSAMA5D2 +# define SAM_SFR_L2CCHRAMC (SAM_SFR_VBASE+SAM_SFR_L2CCHRAMC_OFFSET) +# define SAM_SFR_I2SCLKSEL (SAM_SFR_VBASE+SAM_SFR_I2SCLKSEL_OFFSET) +# define SAM_SFR_QSPICLK (SAM_SFR_VBASE+SAM_SFR_QSPICLK_OFFSET) +#endif + +/* SFR Register Bit Definitions *****************************************************/ + +/* DDR Configuration register */ + +#define SFR_FDQIEN (1 << 16) /* Force DDR_DQ input buffer always on */ +#define SFR_FDQSIEN (1 << 17) /* Force DDR_DQS input buffer always on */ + +/* OHCI Interrupt Configuration Register */ + +#define SFR_OHCIICR_RES(n) (1 << (n)) /* Bit 0: USB port n reset, n=0..2 */ +# define SFR_OHCIICR_RES0 (1 << 0) /* Bit 0: USB port 0 reset */ +# define SFR_OHCIICR_RES1 (1 << 1) /* Bit 1: USB port 1 reset */ +# define SFR_OHCIICR_RES2 (1 << 2) /* Bit 2: USB port 2 reset */ +#define SFR_OHCIICR_ARIE (1 << 4) /* Bit 4: OHCI asynchronous resume interrupt enable */ +#define SFR_OHCIICR_APPSTART (0) /* Bit 5: Reserved, must write 0 */ + +#ifdef ATSAMA5D2 +# define SFR_OHCIICR_SUSPEND(n) (1 << ((n)+8)) +# define SFR_OHCIICR_SUSPENDA (1 << 8) /* Bit 8: Suspend USB port A */ +# define SFR_OHCIICR_SUSPENDB (1 << 9) /* Bit 9: Suspend USB port B */ +# define SFR_OHCIICR_SUSPENDC (1 << 10) /* Bit 10: Suspend USB port C */ +#endif + +#define SFR_OHCIICR_UDPPUDIS (1 << 23) /* Bit 23: USB device pull-up disable */ + +#ifdef ATSAMA5D2 +# define SFR_OHCIICR_HSIC_SEL (0) /* Bit 27: Reserved (must write 0) */ +#endif + +/* OHCI Interrupt Status Register */ + +#define SFR_OHCIISR_RIS0 (1 << 0) /* Bit 0: USB port 0 resume detected */ +#define SFR_OHCIISR_RIS1 (1 << 1) /* Bit 1: USB port 1 resume detected */ +#define SFR_OHCIISR_RIS2 (1 << 2) /* Bit 2: USB port 2 resume detected */ + +/* Security Configuration Register */ + +#define SFR_SECURE_ROM (1 << 0) /* Bit 0: Disable Access to ROM Code */ +#define SFR_SECURE_FUSE (1 << 8) /* Bit 8: Disable Access to Fuse Controller */ + +/* UTMI Clock Trimming Register */ + +#define SFR_UTMICKTRIM_FREQ_SHIFT (0) /* Bits 0-1: UTMI Reference Clock Frequency */ +#define SFR_UTMICKTRIM_FREQ_MASK (3 << SFR_UTMICKTRIM_FREQ_SHIFT) +# define SFR_UTMICKTRIM_FREQ_12MHZ (0 << SFR_UTMICKTRIM_FREQ_SHIFT) /* 12 MHz reference clock */ +# define SFR_UTMICKTRIM_FREQ_16MHZ (1 << SFR_UTMICKTRIM_FREQ_SHIFT) /* 16 MHz reference clock */ +# define SFR_UTMICKTRIM_FREQ_24MHZ (2 << SFR_UTMICKTRIM_FREQ_SHIFT) /* 24 MHz reference clock */ +#ifndef ATSAMA5D2 +# define SFR_UTMICKTRIM_FREQ_48MHZ (3 << SFR_UTMICKTRIM_FREQ_SHIFT) /* 48 MHz reference clock */ +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define SFR_UTMICKTRIM_VBG_SHIFT (16) /* Bits 16-19: UTMI Band Gap Voltage Trimming */ +# define SFR_UTMICKTRIM_VBG_MASK (15 << SFR_UTMICKTRIM_VBG_SHIFT) +# define SFR_UTMICKTRIM_VBG(n) ((uint32_t)(n) << SFR_UTMICKTRIM_VBG_SHIFT) +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* UTMI High Speed Trimming Register */ + +# define SFR_UTMIHSTRIM_SQUELCH_SHIFT (0) /* Bits 0-2: UTMI HS SQUELCH Voltage Trimming */ +# define SFR_UTMIHSTRIM_SQUELCH_MASK (7 << SFR_UTMIHSTRIM_SQUELCH_SHIFT) +# define SFR_UTMIHSTRIM_SQUELCH(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SQUELCH_SHIFT) +# define SFR_UTMIHSTRIM_DISC_SHIFT (4) /* Bits 4-6: UTMI Disconnect Voltage Trimming */ +# define SFR_UTMIHSTRIM_DISC_MASK (7 << SFR_UTMIHSTRIM_DISC_SHIFT) +# define SFR_UTMIHSTRIM_DISC(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_DISC_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE0_SHIFT (8) /* Bits 8-10: UTMI HS PORT0 Transceiver Slope Trimming */ +# define SFR_UTMIHSTRIM_SLOPE0_MASK (7 << SFR_UTMIHSTRIM_SLOPE0_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE0(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE0_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE1_SHIFT (12) /* Bits 12-14: UTMI HS PORT1 Transceiver Slope Trimming */ +# define SFR_UTMIHSTRIM_SLOPE1_MASK (7 << SFR_UTMIHSTRIM_SLOPE1_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE1(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE1_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE2_SHIFT (16) /* Bits 16-18: UTMI HS PORT2 Transceiver Slope Trimming */ +# define SFR_UTMIHSTRIM_SLOPE2_MASK (7 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIHSTRIM_SLOPE2(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* UTMI Full Speed Trimming Register */ + +# define SFR_UTMIFSTRIM_RISE_SHIFT (0) /* Bits 0-2: FS Transceiver Output Rising Slope Trimming */ +# define SFR_UTMIFSTRIM_RISE_MASK (7 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_RISE(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_FALL_SHIFT (4) /* Bits 4-6: FS Transceiver Output Falling Slope Trimming */ +# define SFR_UTMIFSTRIM_FALL_MASK (7 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_FALL(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_XCVR_SHIFT (8) /* Bits 8-9: FS Transceiver Crossover Voltage Trimming */ +# define SFR_UTMIFSTRIM_XCVR_MASK (3 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_XCVR(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_ZN_SHIFT (16) /* Bits 16-18: FS Transceiver NMOS Impedance Trimming */ +# define SFR_UTMIFSTRIM_ZN_MASK (7 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_ZN(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_ZP_SHIFT (20) /* Bits 20-22: FS Transceiver PMOS Impedance Trimming */ +# define SFR_UTMIFSTRIM_ZP_MASK (7 << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +# define SFR_UTMIFSTRIM_ZP(n) ((uint32_t)(n) << SFR_UTMIHSTRIM_SLOPE2_SHIFT) +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* UTMI DP/DM Pin Swapping Register */ + +# define SFR_UTMISWAP_PORT(n) (1 << (n)) /* Bit n: PORT n DP/DM Pin Swapping */ +# define SFR_UTMISWAP_PORT0 (1 << 0) /* Bit 0: PORT 0 DP/DM Pin Swapping */ +# define SFR_UTMISWAP_PORT1 (1 << 1) /* Bit 1: PORT 1 DP/DM Pin Swapping */ +# define SFR_UTMISWAP_PORT2 (1 << 2) /* Bit 2: PORT 2 DP/DM Pin Swapping */ +#endif + +/* EBI Configuration Register */ + +#define SFR_EBICFG_DRIVE_LOW (0) /* LOW Low drive level */ +#define SFR_EBICFG_DRIVE_MEDIUM (2) /* MEDIUM Medium drive level */ +#define SFR_EBICFG_DRIVE_HIGH (3) /* HIGH High drive level */ + +#define SFR_EBICFG_PULL_UP (0) /* Pull-up */ +#define SFR_EBICFG_PULL_NONE (1) /* No Pull */ +#define SFR_EBICFG_PULL_DOWN (3) /* Pull-down */ + +#define SFR_EBICFG_DRIVE0_SHIFT (0) /* Bits 0-1: EBI Pins Drive Level */ +#define SFR_EBICFG_DRIVE0_MASK (3 << SFR_EBICFG_DRIVE0_SHIFT) +# define SFR_EBICFG_DRIVE0(n) ((n) << SFR_EBICFG_DRIVE0_SHIFT) +#define SFR_EBICFG_PULL0_SHIFT (2) /* Bits 2-3: EBI Pins Pull Value */ +#define SFR_EBICFG_PULL0_MASK (3 << SFR_EBICFG_PULL0_SHIFT) +# define SFR_EBICFG_PULL0(n) ((n) << SFR_EBICFG_PULL0_SHIFT) +#define SFR_EBICFG_SCH0 (1 << 4) /* Bit 4: EBI Pins Schmitt Trigger */ +#define SFR_EBICFG_DRIVE1_SHIFT (8) /* Bits 8-9: EBI Pins Drive Level */ +#define SFR_EBICFG_DRIVE1_MASK (3 << SFR_EBICFG_DRIVE1_SHIFT) +# define SFR_EBICFG_DRIVE1(n) ((n) << SFR_EBICFG_DRIVE1_SHIFT) +#define SFR_EBICFG_PULL1_SHIFT (10) /* Bits 10-11: EBI Pins Pull Value */ +#define SFR_EBICFG_PULL1_MASK (3 << SFR_EBICFG_PULL1_SHIFT) +# define SFR_EBICFG_PULL1(n) ((n) << SFR_EBICFG_PULL1_SHIFT) +#define SFR_EBICFG_SCH1 (1 << 12) /* Bit 12: EBI Pins Schmitt Trigger */ + +#ifdef ATSAMA5D3 +# define SFR_EBICFG_BMS (1 << 16) /* Bit 16: BMS Sampled Value (Read Only) */ +#endif + +#ifdef ATSAMA5D2 +/* Analog Configuration Register */ + +# define SFR_ANACFG_SMDDREN (1 << 0) /* Bit 0: DDR Supply Monitor Enable */ +#endif + +#ifdef ATSAMA5D2 +/* CAN Memories Address-based Register */ + +# define SFR_CAN0_EXTMEMADDR_SHIFT (0) /* Bits 0-15: MSB CAN0 Base Address */ +# define SFR_CAN0_EXTMEMADDR_MASK (0xffff << SFR_CAN0_EXTMEMADDR_SHIFT) +# define SFR_CAN0_EXTMEMADDR(n) ((uint32_t)(n) << SFR_CAN0_EXTMEMADDR_SHIFT) +# define SFR_CAN1_EXTMEMADDR_SHIFT (16) /* Bits 16-31: MSB CAN0 Base Address */ +# define SFR_CAN1_EXTMEMADDR_MASK (0xffff << SFR_CAN1_EXTMEMADDR_SHIFT) +# define SFR_CAN1_EXTMEMADDR(n) ((uint32_t)(n) << SFR_CAN1_EXTMEMADDR_SHIFT) +#endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +/* Serial Number 0 Register (32-bit value) */ +/* Serial Number 1 Register (32-bit value) */ + +/* AIC Redirection Register */ + +# define SFR_AICREDIR_NSAIC (1 << 0) /* Bit 0: Interrupt redirection to Non-Secure AIC */ +# define SFR_AICREDIR_ENABLE (1 << 0) /* Bit 0: 1=All interrupts to AIC */ +# define SFR_AICREDIR_DISABLE (0) /* Bit 0: 0=Secure interrupts to SAIC */ +# define SFR_AICREDIR_KEY (0x5f67b102) /* Bits 1-31: Access key */ + +#endif + +#ifdef ATSAMA5D2 +/* L2CC HRAMC1 */ + +# define SFR_L2CCHRAMC_SRAMSEL (1 << 0) /* Bit 0: SRAM selector */ +# define SFR_L2CCHRAMC_SRAM (0) /* Bit 0: 0=Selects SRAM */ +# define SFR_L2CCHRAMC_L2CC (1 << 0) /* Bit 0: 1=Selects L2CC */ +#endif + +#ifdef ATSAMA5D2 +/* I2SC Register */ + +# define SFR_I2S_CLKSEL0 (1 << 0) /* Bit 0: Clock selection 0 */ +# define SFR_I2S_CLKSEL0_GCLK (0) /* Bit 0: 0=Selects GCLK */ +# define SFR_I2S_CLKSEL0_PCLK (1 << 0) /* Bit 0: 1=Selects PCLK */ +# define SFR_I2S_CLKSEL1 (1 << 1) /* Bit 1: Clock selection 1 */ +# define SFR_I2S_CLKSEL1_GCLK (0) /* Bit 0: 0=Selects GCLK */ +# define SFR_I2S_CLKSEL1_PCLK (1 << 1) /* Bit 0: 1=Selects PCLK */ +#endif + +#ifdef ATSAMA5D2 +/* QSPI Clock Pad Supply Select Register */ + +# define SFR_QSPICLK_SUPSEL (1 << 0) /* Bit 0: Supply selection */ +# define SFR_QSPICLK_1p8V (0) /* Bit 0: 0=1.8V */ +# define SFR_QSPICLK_3p3V (1 << 0) /* Bit 0: 1=3.3V */ +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SFR_H */ diff --git a/arch/arm/src/sama5/chip/sam_spi.h b/arch/arm/src/sama5/chip/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..b9a7bcf17cae90830efe6956499a1ee8362b99a7 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_spi.h @@ -0,0 +1,241 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_spi.h + * Serial Peripheral Interface (SPI) definitions for the SAMA5 + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SPI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SPI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_SPI_NCS 4 /* Four chip selects */ + +/* SPI register offsets *****************************************************************/ + +#define SAM_SPI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SPI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_SPI_RDR_OFFSET 0x0008 /* Receive Data Register */ +#define SAM_SPI_TDR_OFFSET 0x000c /* Transmit Data Register */ +#define SAM_SPI_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_SPI_IER_OFFSET 0x0014 /* Interrupt Enable Register */ +#define SAM_SPI_IDR_OFFSET 0x0018 /* Interrupt Disable Register */ +#define SAM_SPI_IMR_OFFSET 0x001c /* Interrupt Mask Register */ + /* 0x20-0x2c: Reserved */ +#define SAM_SPI_CSR0_OFFSET 0x0030 /* Chip Select Register 0 */ +#define SAM_SPI_CSR1_OFFSET 0x0034 /* Chip Select Register 1 */ +#define SAM_SPI_CSR2_OFFSET 0x0038 /* Chip Select Register 2 */ +#define SAM_SPI_CSR3_OFFSET 0x003c /* Chip Select Register 3 */ + /* 0x40-0xe0: Reserved */ +#define SAM_SPI_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +#define SAM_SPI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0xec-0x124: Reserved */ + +/* SPI register adresses ****************************************************************/ + +#define SAM_SPI0_CR (SAM_SPI0_VBASE+SAM_SPI_CR_OFFSET) +#define SAM_SPI0_MR (SAM_SPI0_VBASE+SAM_SPI_MR_OFFSET) +#define SAM_SPI0_RDR (SAM_SPI0_VBASE+SAM_SPI_RDR_OFFSET) +#define SAM_SPI0_TDR (SAM_SPI0_VBASE+SAM_SPI_TDR_OFFSET) +#define SAM_SPI0_SR (SAM_SPI0_VBASE+SAM_SPI_SR_OFFSET) +#define SAM_SPI0_IER (SAM_SPI0_VBASE+SAM_SPI_IER_OFFSET) +#define SAM_SPI0_IDR (SAM_SPI0_VBASE+SAM_SPI_IDR_OFFSET) +#define SAM_SPI0_IMR (SAM_SPI0_VBASE+SAM_SPI_IMR_OFFSET) +#define SAM_SPI0_CSR0 (SAM_SPI0_VBASE+SAM_SPI_CSR0_OFFSET) +#define SAM_SPI0_CSR1 (SAM_SPI0_VBASE+SAM_SPI_CSR1_OFFSET) +#define SAM_SPI0_CSR2 (SAM_SPI0_VBASE+SAM_SPI_CSR2_OFFSET) +#define SAM_SPI0_CSR3 (SAM_SPI0_VBASE+SAM_SPI_CSR3_OFFSET) +#define SAM_SPI0_WPCR (SAM_SPI0_VBASE+SAM_SPI_WPCR_OFFSET) +#define SAM_SPI0_WPSR (SAM_SPI0_VBASE+SAM_SPI_WPSR_OFFSET) + +#define SAM_SPI1_CR (SAM_SPI1_VBASE+SAM_SPI_CR_OFFSET) +#define SAM_SPI1_MR (SAM_SPI1_VBASE+SAM_SPI_MR_OFFSET) +#define SAM_SPI1_RDR (SAM_SPI1_VBASE+SAM_SPI_RDR_OFFSET) +#define SAM_SPI1_TDR (SAM_SPI1_VBASE+SAM_SPI_TDR_OFFSET) +#define SAM_SPI1_SR (SAM_SPI1_VBASE+SAM_SPI_SR_OFFSET) +#define SAM_SPI1_IER (SAM_SPI1_VBASE+SAM_SPI_IER_OFFSET) +#define SAM_SPI1_IDR (SAM_SPI1_VBASE+SAM_SPI_IDR_OFFSET) +#define SAM_SPI1_IMR (SAM_SPI1_VBASE+SAM_SPI_IMR_OFFSET) +#define SAM_SPI1_CSR0 (SAM_SPI1_VBASE+SAM_SPI_CSR0_OFFSET) +#define SAM_SPI1_CSR1 (SAM_SPI1_VBASE+SAM_SPI_CSR1_OFFSET) +#define SAM_SPI1_CSR2 (SAM_SPI1_VBASE+SAM_SPI_CSR2_OFFSET) +#define SAM_SPI1_CSR3 (SAM_SPI1_VBASE+SAM_SPI_CSR3_OFFSET) +#define SAM_SPI1_WPCR (SAM_SPI1_VBASE+SAM_SPI_WPCR_OFFSET) +#define SAM_SPI1_WPSR (SAM_SPI1_VBASE+SAM_SPI_WPSR_OFFSET) + +#ifdef CONFIG_SAMA5_HAVE_SPI2 +# define SAM_SPI2_CR (SAM_SPI2_VBASE+SAM_SPI_CR_OFFSET) +# define SAM_SPI2_MR (SAM_SPI2_VBASE+SAM_SPI_MR_OFFSET) +# define SAM_SPI2_RDR (SAM_SPI2_VBASE+SAM_SPI_RDR_OFFSET) +# define SAM_SPI2_TDR (SAM_SPI2_VBASE+SAM_SPI_TDR_OFFSET) +# define SAM_SPI2_SR (SAM_SPI2_VBASE+SAM_SPI_SR_OFFSET) +# define SAM_SPI2_IER (SAM_SPI2_VBASE+SAM_SPI_IER_OFFSET) +# define SAM_SPI2_IDR (SAM_SPI2_VBASE+SAM_SPI_IDR_OFFSET) +# define SAM_SPI2_IMR (SAM_SPI2_VBASE+SAM_SPI_IMR_OFFSET) +# define SAM_SPI2_CSR0 (SAM_SPI2_VBASE+SAM_SPI_CSR0_OFFSET) +# define SAM_SPI2_CSR1 (SAM_SPI2_VBASE+SAM_SPI_CSR1_OFFSET) +# define SAM_SPI2_CSR2 (SAM_SPI2_VBASE+SAM_SPI_CSR2_OFFSET) +# define SAM_SPI2_CSR3 (SAM_SPI2_VBASE+SAM_SPI_CSR3_OFFSET) +# define SAM_SPI2_WPCR (SAM_SPI2_VBASE+SAM_SPI_WPCR_OFFSET) +# define SAM_SPI2_WPSR (SAM_SPI2_VBASE+SAM_SPI_WPSR_OFFSET) +#endif + +/* SPI register bit definitions *********************************************************/ + +/* SPI Control Register */ + +#define SPI_CR_SPIEN (1 << 0) /* Bit 0: SPI Enable */ +#define SPI_CR_SPIDIS (1 << 1) /* Bit 1: SPI Disable */ +#define SPI_CR_SWRST (1 << 7) /* Bit 7: SPI Software Reset */ +#define SPI_CR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Mode Register */ + +#define SPI_MR_MSTR (1 << 0) /* Bit 0: Master/Slave Mode */ +#define SPI_MR_PS (1 << 1) /* Bit 1: Peripheral Select */ +#define SPI_MR_PCSDEC (1 << 2) /* Bit 2: Chip Select Decode */ +#define SPI_MR_MODFDIS (1 << 4) /* Bit 4: Mode Fault Detection */ +#define SPI_MR_WDRBT (1 << 5) /* Bit 5: Wait Data Read Before Transfer */ +#define SPI_MR_LLB (1 << 7) /* Bit 7: Local Loopback Enable */ +#define SPI_MR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_MR_PCS_MASK (15 << SPI_MR_PCS_SHIFT) +# define SPI_MR_PCS0 (0 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_MR_PCS1 (1 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_MR_PCS2 (3 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_MR_PCS3 (7 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_MR_DLYBCS_SHIFT (24) /* Bits 24-31: Delay Between Chip Selects */ +#define SPI_MR_DLYBCS_MASK (0xff << SPI_MR_DLYBCS_SHIFT) + +/* SPI Receive Data Register */ + +#define SPI_RDR_RD_SHIFT (0) /* Bits 0-15: Receive Data */ +#define SPI_RDR_RD_MASK (0xffff << SPI_RDR_RD_SHIFT) +#define SPI_RDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_RDR_PCS_MASK (15 << SPI_RDR_PCS_SHIFT) +# define SPI_RDR_PCS0 (0 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_RDR_PCS1 (1 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_RDR_PCS2 (3 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_RDR_PCS3 (7 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ + +/* SPI Transmit Data Register */ + +#define SPI_TDR_TD_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define SPI_TDR_TD_MASK (0xffff << SPI_TDR_TD_SHIFT) +#define SPI_TDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_TDR_PCS_MASK (15 << SPI_TDR_PCS_SHIFT) +# define SPI_TDR_PCS0 (0 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_TDR_PCS1 (1 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_TDR_PCS2 (3 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_TDR_PCS3 (7 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_TDR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Status Register, SPI Interrupt Enable Register, SPI Interrupt Disable Register, + * and SPI Interrupt Mask Register (common bit fields) + */ + +#define SPI_INT_RDRF (1 << 0) /* Bit 0: Receive Data Register Full Interrupt */ +#define SPI_INT_TDRE (1 << 1) /* Bit 1: Transmit Data Register Empty Interrupt */ +#define SPI_INT_MODF (1 << 2) /* Bit 2: Mode Fault Error Interrupt */ +#define SPI_INT_OVRES (1 << 3) /* Bit 3: Overrun Error Interrupt */ +#define SPI_INT_NSSR (1 << 8) /* Bit 8: NSS Rising Interrupt */ +#define SPI_INT_TXEMPTY (1 << 9) /* Bit 9: Transmission Registers Empty Interrupt */ +#define SPI_INT_UNDES (1 << 10) /* Bit 10: Underrun Error Status Interrupt (slave) */ +#define SPI_SR_SPIENS (1 << 16) /* Bit 16: SPI Enable Status (SR only) */ + +/* SPI Chip Select Registers 0-3 */ + +#define SPI_CSR_CPOL (1 << 0) /* Bit 0: Clock Polarity */ +#define SPI_CSR_NCPHA (1 << 1) /* Bit 1: Clock Phase */ +#define SPI_CSR_CSNAAT (1 << 2) /* Bit 2: Chip Select Not Active After Transfer */ +#define SPI_CSR_CSAAT (1 << 3) /* Bit 3: Chip Select Active After Transfer */ +#define SPI_CSR_BITS_SHIFT (4) /* Bits 4-7: Bits Per Transfer */ +#define SPI_CSR_BITS_MASK (15 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_BITS(n) (((n)-8) << SPI_CSR_BITS_SHIFT) /* n, n=8-16 */ +# define SPI_CSR_BITS8 (0 << SPI_CSR_BITS_SHIFT) /* 8 */ +# define SPI_CSR_BITS9 (1 << SPI_CSR_BITS_SHIFT) /* 9 */ +# define SPI_CSR_BITS10 (2 << SPI_CSR_BITS_SHIFT) /* 10 */ +# define SPI_CSR_BITS11 (3 << SPI_CSR_BITS_SHIFT) /* 11 */ +# define SPI_CSR_BITS12 (4 << SPI_CSR_BITS_SHIFT) /* 12 */ +# define SPI_CSR_BITS13 (5 << SPI_CSR_BITS_SHIFT) /* 13 */ +# define SPI_CSR_BITS14 (6 << SPI_CSR_BITS_SHIFT) /* 14 */ +# define SPI_CSR_BITS15 (7 << SPI_CSR_BITS_SHIFT) /* 15 */ +# define SPI_CSR_BITS16 (8 << SPI_CSR_BITS_SHIFT) /* 16 */ +#define SPI_CSR_SCBR_SHIFT (8) /* Bits 8-15: Serial Clock Baud Rate */ +#define SPI_CSR_SCBR_MASK (0xff << SPI_CSR_SCBR_SHIFT) +# define SPI_CSR_SCBR(n) ((uint32_t)(n) << SPI_CSR_SCBR_SHIFT) +#define SPI_CSR_DLYBS_SHIFT (16) /* Bits 16-23: Delay Before SPCK */ +#define SPI_CSR_DLYBS_MASK (0xff << SPI_CSR_DLYBS_SHIFT) +# define SPI_CSR_DLYBS(n) ((uint32_t)(n) << SPI_CSR_DLYBS_SHIFT) +#define SPI_CSR_DLYBCT_SHIFT (24) /* Bits 24-31: Delay Between Consecutive Transfers */ +#define SPI_CSR_DLYBCT_MASK (0xff << SPI_CSR_DLYBCT_SHIFT) +# define SPI_CSR_DLYBCT(n) ((uint32_t)(n) << SPI_CSR_DLYBCT_SHIFT) + +/* SPI Write Protection Control Register */ + +#define SPI_WPCR_WPEN (1 << 0) /* Bit 0: SPI Write Protection Enable */ +#define SPI_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: SPI Write Protection Key Password */ +#define SPI_WPCR_WPKEY_MASK (0x00ffffff << SPI_WPCR_WPKEY_SHIFT) +# define SPI_WPCR_WPKEY (0x00535049 << SPI_WPCR_WPKEY_SHIFT) + +/* SPI Write Protection Status Register */ + +#define SPI_WPSR_WPVS_SHIFT (0) /* Bits 0-2: SPI Write Protection Violation Status */ +#define SPI_WPSR_WPVS_MASK (7 << SPI_WPSR_WPVS_SHIFT) +#define SPI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-15: SPI Write Protection Violation Source */ +#define SPI_WPSR_WPVSRC_MASK (0xff << SPI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SPI_H */ diff --git a/arch/arm/src/sama5/chip/sam_ssc.h b/arch/arm/src/sama5/chip/sam_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..558805027cfd5c57b85d60f1dda99eb39f5bb080 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_ssc.h @@ -0,0 +1,307 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_ssc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SSC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_SSC_MAXPERCLK 66000000 /* Maximum peripheral clock frequency */ + +/* SSC Register Offsets *************************************************************/ + +#define SAM_SSC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SSC_CMR_OFFSET 0x0004 /* Clock Mode Register */ + /* 0x0008-0x000c Reserved */ +#define SAM_SSC_RCMR_OFFSET 0x0010 /* Receive Clock Mode Register */ +#define SAM_SSC_RFMR_OFFSET 0x0014 /* Receive Frame Mode Register */ +#define SAM_SSC_TCMR_OFFSET 0x0018 /* Transmit Clock Mode Register */ +#define SAM_SSC_TFMR_OFFSET 0x001c /* Transmit Frame Mode Register */ +#define SAM_SSC_RHR_OFFSET 0x0020 /* Receive Holding Register */ +#define SAM_SSC_THR_OFFSET 0x0024 /* Transmit Holding Register */ + /* 0x0028-0x002c Reserved */ +#define SAM_SSC_RSHR_OFFSET 0x0030 /* Receive Sync. Holding Register */ +#define SAM_SSC_TSHR_OFFSET 0x0034 /* Transmit Sync. Holding Register */ +#define SAM_SSC_RC0R_OFFSET 0x0038 /* Receive Compare 0 Register */ +#define SAM_SSC_RC1R_OFFSET 0x003c /* Receive Compare 1 Register */ +#define SAM_SSC_SR_OFFSET 0x0040 /* Status Register */ +#define SAM_SSC_IER_OFFSET 0x0044 /* Interrupt Enable Register */ +#define SAM_SSC_IDR_OFFSET 0x0048 /* Interrupt Disable Register */ +#define SAM_SSC_IMR_OFFSET 0x004c /* Interrupt Mask Register */ +#define SAM_SSC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_SSC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x50-0x124 Reserved */ + +/* SSC Register Addresses ***********************************************************/ + +#define SAM_SSC0_CR (SAM_SSC0_VBASE+SAM_SSC_CR_OFFSET) +#define SAM_SSC0_CMR (SAM_SSC0_VBASE+SAM_SSC_CMR_OFFSET) +#define SAM_SSC0_RCMR (SAM_SSC0_VBASE+SAM_SSC_RCMR_OFFSET) +#define SAM_SSC0_RFMR (SAM_SSC0_VBASE+SAM_SSC_RFMR_OFFSET) +#define SAM_SSC0_TCMR (SAM_SSC0_VBASE+SAM_SSC_TCMR_OFFSET) +#define SAM_SSC0_TFMR (SAM_SSC0_VBASE+SAM_SSC_TFMR_OFFSET) +#define SAM_SSC0_RHR (SAM_SSC0_VBASE+SAM_SSC_RHR_OFFSET) +#define SAM_SSC0_THR (SAM_SSC0_VBASE+SAM_SSC_THR_OFFSET) +#define SAM_SSC0_RSHR (SAM_SSC0_VBASE+SAM_SSC_RSHR_OFFSET) +#define SAM_SSC0_TSHR (SAM_SSC0_VBASE+SAM_SSC_TSHR_OFFSET) +#define SAM_SSC0_RC0R (SAM_SSC0_VBASE+SAM_SSC_RC0R_OFFSET) +#define SAM_SSC0_RC1R (SAM_SSC0_VBASE+SAM_SSC_RC1R_OFFSET) +#define SAM_SSC0_SR (SAM_SSC0_VBASE+SAM_SSC_SR_OFFSET) +#define SAM_SSC0_IER (SAM_SSC0_VBASE+SAM_SSC_IER_OFFSET) +#define SAM_SSC0_IDR (SAM_SSC0_VBASE+SAM_SSC_IDR_OFFSET) +#define SAM_SSC0_IMR (SAM_SSC0_VBASE+SAM_SSC_IMR_OFFSET) +#define SAM_SSC0_WPMR (SAM_SSC0_VBASE+SAM_SSC_WPMR_OFFSET) +#define SAM_SSC0_WPSR (SAM_SSC0_VBASE+SAM_SSC_WPSR_OFFSET) + +#define SAM_SSC1_CR (SAM_SSC1_VBASE+SAM_SSC_CR_OFFSET) +#define SAM_SSC1_CMR (SAM_SSC1_VBASE+SAM_SSC_CMR_OFFSET) +#define SAM_SSC1_RCMR (SAM_SSC1_VBASE+SAM_SSC_RCMR_OFFSET) +#define SAM_SSC1_RFMR (SAM_SSC1_VBASE+SAM_SSC_RFMR_OFFSET) +#define SAM_SSC1_TCMR (SAM_SSC1_VBASE+SAM_SSC_TCMR_OFFSET) +#define SAM_SSC1_TFMR (SAM_SSC1_VBASE+SAM_SSC_TFMR_OFFSET) +#define SAM_SSC1_RHR (SAM_SSC1_VBASE+SAM_SSC_RHR_OFFSET) +#define SAM_SSC1_THR (SAM_SSC1_VBASE+SAM_SSC_THR_OFFSET) +#define SAM_SSC1_RSHR (SAM_SSC1_VBASE+SAM_SSC_RSHR_OFFSET) +#define SAM_SSC1_TSHR (SAM_SSC1_VBASE+SAM_SSC_TSHR_OFFSET) +#define SAM_SSC1_RC0R (SAM_SSC1_VBASE+SAM_SSC_RC0R_OFFSET) +#define SAM_SSC1_RC1R (SAM_SSC1_VBASE+SAM_SSC_RC1R_OFFSET) +#define SAM_SSC1_SR (SAM_SSC1_VBASE+SAM_SSC_SR_OFFSET) +#define SAM_SSC1_IER (SAM_SSC1_VBASE+SAM_SSC_IER_OFFSET) +#define SAM_SSC1_IDR (SAM_SSC1_VBASE+SAM_SSC_IDR_OFFSET) +#define SAM_SSC1_IMR (SAM_SSC1_VBASE+SAM_SSC_IMR_OFFSET) +#define SAM_SSC1_WPMR (SAM_SSC1_VBASE+SAM_SSC_WPMR_OFFSET) +#define SAM_SSC1_WPSR (SAM_SSC1_VBASE+SAM_SSC_WPSR_OFFSET) + +/* SSC Register Bit Definitions *****************************************************/ + +/* Control Register */ + +#define SSC_CR_RXEN (1 << 0) /* Bit 0: Receive Enable */ +#define SSC_CR_RXDIS (1 << 1) /* Bit 1: Receive Disable */ +#define SSC_CR_TXEN (1 << 8) /* Bit 8: Transmit Enable */ +#define SSC_CR_TXDIS (1 << 9) /* Bit 9: Transmit Disable */ +#define SSC_CR_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* Clock Mode Register */ + +#define SSC_CMR_DIV_MASK (0x00000fff) /* Bits 0-11: DIV: Clock Divider */ + +/* Receive Clock Mode Register */ + +#define SSC_RCMR_CKS_SHIFT (0) /* Bits 0-1: Receive Clock Selection */ +#define SSC_RCMR_CKS_MASK (3 << SSC_RCMR_CKS_SHIFT) +# define SSC_RCMR_CKS_MCK (0 << SSC_RCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_RCMR_CKS_TK (1 << SSC_RCMR_CKS_SHIFT) /* TK Clock signal */ +# define SSC_RCMR_CKS_RK (2 << SSC_RCMR_CKS_SHIFT) /* RK pin */ +#define SSC_RCMR_CKO_SHIFT (2) /* Bits 2-4: Receive Clock Output Mode Selection */ +#define SSC_RCMR_CKO_MASK (7 << SSC_RCMR_CKO_SHIFT) +# define SSC_RCMR_CKO_NONE (0 << SSC_RCMR_CKO_SHIFT) /* None, RK pin is an input */ +# define SSC_RCMR_CKO_CONT (1 << SSC_RCMR_CKO_SHIFT) /* Continuous Receive Clock, RK pin is an output */ +# define SSC_RCMR_CKO_TRANSFER (2 << SSC_RCMR_CKO_SHIFT) /* Receive Clock during transfers, RK pin is an output */ +#define SSC_RCMR_CKI (1 << 5) /* Bit 5: Receive Clock Inversion */ +#define SSC_RCMR_CKG_SHIFT (6) /* Bits 6-7: Receive Clock Gating Selection */ +#define SSC_RCMR_CKG_MASK (3 << SSC_RCMR_CKG_SHIFT) +# define SSC_RCMR_CKG_CONT (0 << SSC_RCMR_CKG_SHIFT) /* None */ +# define SSC_RCMR_CKG_ENRFLOW (2 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF Pin is Low */ +# define SSC_RCMR_CKG_ENRFHIGH (3 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF Pin is High */ +#define SSC_RCMR_START_SHIFT (8) /* Bits 8-11: Receive Start Selection */ +#define SSC_RCMR_START_MASK (15 << SSC_RCMR_START_SHIFT) +# define SSC_RCMR_START_CONT (0 << SSC_RCMR_START_SHIFT) /* Continuous */ +# define SSC_RCMR_START_TRANSMIT (1 << SSC_RCMR_START_SHIFT) /* Transmit start */ +# define SSC_RCMR_START_LOW (2 << SSC_RCMR_START_SHIFT) /* Detection of a low level on RF signal */ +# define SSC_RCMR_START_HIGH (3 << SSC_RCMR_START_SHIFT) /* Detection of a high level on RF signal */ +# define SSC_RCMR_START_FALLING (4 << SSC_RCMR_START_SHIFT) /* Detection of a falling edge on RF signal */ +# define SSC_RCMR_START_RISING (5 << SSC_RCMR_START_SHIFT) /* Detection of a rising edge on RF signal */ +# define SSC_RCMR_START_LEVEL (6 << SSC_RCMR_START_SHIFT) /* Detection of any level change on RF signal */ +# define SSC_RCMR_START_EDGE (7 << SSC_RCMR_START_SHIFT) /* Detection of any edge on RF signal */ +# define SSC_RCMR_START_CMP0 (8 << SSC_RCMR_START_SHIFT) /* Compare 0 */ +#define SSC_RCMR_STOP (1 << 12) /* Bit 12: Receive Stop Selection */ +#define SSC_RCMR_STTDLY_SHIFT (16) /* Bits 16-23: Receive Start Delay */ +#define SSC_RCMR_STTDLY_MASK (0xff << SSC_RCMR_STTDLY_SHIFT) +# define SSC_RCMR_STTDLY(n) ((uint32_t)(n) << SSC_RCMR_STTDLY_SHIFT) +#define SSC_RCMR_PERIOD_SHIFT (24) /* Bits 24-31: Receive Period Divider Selection */ +#define SSC_RCMR_PERIOD_MASK (0xff << SSC_RCMR_PERIOD_SHIFT) +# define SSC_RCMR_PERIOD(n) ((uint32_t)(n) << SSC_RCMR_PERIOD_SHIFT) + +/* Receive Frame Mode Register */ + +#define SSC_RFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_RFMR_DATLEN_MASK (15 << SSC_RFMR_DATLEN_SHIFT) +# define SSC_RFMR_DATLEN(n) ((uint32_t)(n) << SSC_RFMR_DATLEN_SHIFT) +#define SSC_RFMR_LOOP (1 << 5) /* Bit 5: Loop Mode */ +#define SSC_RFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_RFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per Frame */ +#define SSC_RFMR_DATNB_MASK (15 << SSC_RFMR_DATNB_SHIFT) +# define SSC_RFMR_DATNB(n) ((uint32_t)(n) << SSC_RFMR_DATNB_SHIFT) +#define SSC_RFMR_FSLEN_SHIFT (16) /* Bits 16-19: Receive Frame Sync Length */ +#define SSC_RFMR_FSLEN_MASK (15 << SSC_RFMR_FSLEN_SHIFT) +# define SSC_RFMR_FSLEN(n) ((uint32_t)(n) << SSC_RFMR_FSLEN_SHIFT) +#define SSC_RFMR_FSOS_SHIFT (20) /* Bits 20-22: Receive Frame Sync Output Selection */ +#define SSC_RFMR_FSOS_MASK (7 << SSC_RFMR_FSOS_SHIFT) +# define SSC_RFMR_FSOS_NONE (0 << SSC_RFMR_FSOS_SHIFT) /* None, RF pin is an input */ +# define SSC_RFMR_FSOS_NEGATIVE (1 << SSC_RFMR_FSOS_SHIFT) /* Negative Pulse, RF pin is an output */ +# define SSC_RFMR_FSOS_POSITIVE (2 << SSC_RFMR_FSOS_SHIFT) /* Positive Pulse, RF pin is an output */ +# define SSC_RFMR_FSOS_LOW (3 << SSC_RFMR_FSOS_SHIFT) /* Low during transfer, RF pin is an output */ +# define SSC_RFMR_FSOS_HIGH (4 << SSC_RFMR_FSOS_SHIFT) /* High during transfer, RF pin is an output */ +# define SSC_RFMR_FSOS_TOGGLING (5 << SSC_RFMR_FSOS_SHIFT) /* Toggling each transfer, RF pin is an output */ +#define SSC_RFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detection */ +# define SSC_RFMR_FSEDGE_POS (0) /* Bit 24: 0=Positive Edge Detection */ +# define SSC_RFMR_FSEDGE_NEG (1 << 24) /* Bit 24: 1=Negative Edge Detection */ +#define SSC_RFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_RFMR_FSLENEXT_MASK (15 << SSC_RFMR_FSLENEXT_SHIFT) +# define SSC_RFMR_FSLENEXT(n) ((uint32_t)(n) << SSC_RFMR_FSLENEXT_SHIFT) + +/* Transmit Clock Mode Register */ + +#define SSC_TCMR_CKS_SHIFT (0) /* Bits 0-1: Transmit Clock Selection */ +#define SSC_TCMR_CKS_MASK (3 << SSC_TCMR_CKS_SHIFT) +# define SSC_TCMR_CKS_MCK (0 << SSC_TCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_TCMR_CKS_RK (1 << SSC_TCMR_CKS_SHIFT) /* RK Clock signal */ +# define SSC_TCMR_CKS_TK (2 << SSC_TCMR_CKS_SHIFT) /* TK pin */ +#define SSC_TCMR_CKO_SHIFT (2) /* Bits 2-4: Transmit Clock Output Mode Selection */ +#define SSC_TCMR_CKO_MASK (7 << SSC_TCMR_CKO_SHIFT) +# define SSC_TCMR_CKO_NONE (0 << SSC_TCMR_CKO_SHIFT) /* None, TK pin is an input */ +# define SSC_TCMR_CKO_CONT (1 << SSC_TCMR_CKO_SHIFT) /* Continuous Transmit Clock, TK pin is an output */ +# define SSC_TCMR_CKO_TRANSFER (2 << SSC_TCMR_CKO_SHIFT) /* Transmit Clock during transfers, TK pin is an output */ +#define SSC_TCMR_CKI (1 << 5) /* Bit 5: Transmit Clock Inversion */ +#define SSC_TCMR_CKG_SHIFT (6) /* Bits 6-7: Transmit Clock Gating Selection */ +#define SSC_TCMR_CKG_MASK (3 << SSC_TCMR_CKG_SHIFT) +# define SSC_TCMR_CKG_CONT (0 << SSC_TCMR_CKG_SHIFT) /* None */ +# define SSC_TCMR_CKG_ENTFLOW (1 << SSC_TCMR_CKG_SHIFT) /* Transmit Clock enabled only if TF pin is Low */ +# define SSC_TCMR_CKG_ENTFHIGH (2 << SSC_TCMR_CKG_SHIFT) /*Transmit Clock enabled only if TF pin is High */ +#define SSC_TCMR_START_SHIFT (8) /* Bits 8-11: Transmit Start Selection */ +#define SSC_TCMR_START_MASK (15 << SSC_TCMR_START_SHIFT) +# define SSC_TCMR_START_CONT (0 << SSC_TCMR_START_SHIFT) /* Continuous */ +# define SSC_TCMR_START_RECEIVE (1 << SSC_TCMR_START_SHIFT) /* Receive start */ +# define SSC_TCMR_START_LOW (2 << SSC_TCMR_START_SHIFT) /* Detection of a low level on TF signal */ +# define SSC_TCMR_START_HIGH (3 << SSC_TCMR_START_SHIFT) /* Detection of a high level on TF signal */ +# define SSC_TCMR_START_FALLING (4 << SSC_TCMR_START_SHIFT) /* Detection of a falling edge on TF signal */ +# define SSC_TCMR_START_RISING (5 << SSC_TCMR_START_SHIFT) /* Detection of a rising edge on TF signal */ +# define SSC_TCMR_START_LEVEL (6 << SSC_TCMR_START_SHIFT) /* Detection of any level change on TF signal */ +# define SSC_TCMR_START_EDGE (7 << SSC_TCMR_START_SHIFT) /* Detection of any edge on TF signal */ +#define SSC_TCMR_STTDLY_SHIFT (16) /* Bits 15-23: Transmit Start Delay */ +#define SSC_TCMR_STTDLY_MASK (0xff << SSC_TCMR_STTDLY_SHIFT) +# define SSC_TCMR_STTDLY(n) ((uint32_t)(n) << SSC_TCMR_STTDLY_SHIFT) +#define SSC_TCMR_PERIOD_SHIFT (24) /* Bits 24-31: Transmit Period Divider Selection */ +#define SSC_TCMR_PERIOD_MASK (0xff << SSC_TCMR_PERIOD_SHIFT) +# define SSC_TCMR_PERIOD(n) ((uint32_t)(n) << SSC_TCMR_PERIOD_SHIFT) + +/* Transmit Frame Mode Register */ + +#define SSC_TFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_TFMR_DATLEN_MASK (31 << SSC_TFMR_DATLEN_SHIFT) +# define SSC_TFMR_DATLEN(n) ((uint32_t)(n) << SSC_TFMR_DATLEN_SHIFT) +#define SSC_TFMR_DATDEF (1 << 5) /* Bit 5: Data Default Value */ +#define SSC_TFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_TFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per frame */ +#define SSC_TFMR_DATNB_MASK (15 << SSC_TFMR_DATNB_SHIFT) +# define SSC_TFMR_DATNB(n) ((uint32_t)(n) << SSC_TFMR_DATNB_SHIFT) +#define SSC_TFMR_FSLEN_SHIFT (16) /* Bits 16-19: Transmit Frame Sync Length */ +#define SSC_TFMR_FSLEN_MASK (15 << SSC_TFMR_FSLEN_SHIFT) +# define SSC_TFMR_FSLEN(n) ((uint32_t)(n) << SSC_TFMR_FSLEN_SHIFT) +#define SSC_TFMR_FSOS_SHIFT (20) /* Bits 20-22: Transmit Frame Sync Output Selection */ +#define SSC_TFMR_FSOS_MASK (7 << SSC_TFMR_FSOS_SHIFT) +# define SSC_TFMR_FSOS_NONE (0 << SSC_TFMR_FSOS_SHIFT) /* None, TF pin is an input */ +# define SSC_TFMR_FSOS_NEGATIVE (1 << SSC_TFMR_FSOS_SHIFT) /* Negative Pulse, TF pin is an output */ +# define SSC_TFMR_FSOS_POSITIVE (2 << SSC_TFMR_FSOS_SHIFT) /* Positive Pulse, TF pin is an output */ +# define SSC_TFMR_FSOS_LOW (3 << SSC_TFMR_FSOS_SHIFT) /* TF pin Driven Low during data transfer */ +# define SSC_TFMR_FSOS_HIGH (4 << SSC_TFMR_FSOS_SHIFT) /* TF pin Driven High during data transfer */ +# define SSC_TFMR_FSOS_TOGGLING (5 << SSC_TFMR_FSOS_SHIFT) /* TF pin Toggles at each start of data transfer */ +#define SSC_TFMR_FSDEN (1 << 23) /* Bit 23: Frame Sync Data Enable */ +#define SSC_TFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detection */ +# define SSC_TFMR_FSEDGE_POS (0) /* Bit 24: 0=Positive Edge Detection */ +# define SSC_TFMR_FSEDGE_NEG (1 << 24) /* Bit 24: 1=Negative Edge Detection */ +#define SSC_TFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_TFMR_FSLENEXT_MASK (15 << SSC_TFMR_FSLENEXT_SHIFT) +# define SSC_TFMR_FSLENEXT(n) ((uint32_t)(n) << SSC_TFMR_FSLENEXT_SHIFT) + +/* Receive Holding Register (32-bit data value) */ +/* Transmit Holding Register (32-bit data value) */ + +/* Receive Sync. Holding Register */ + +#define SSC_RSHR_MASK (0x0000ffff) /* Bit 0-15: Receive Synchronization Data */ + +/* Transmit Sync. Holding Register */ + +#define SSC_TSHR_MASK (0x0000ffff) /* Bit 0-15: Transmit Synchronization Data */ + +/* Receive Compare 0 Register */ + +#define SSC_RC0R_MASK (0x0000ffff) /* Bit 0-15: Receive Compare Data 0 */ + +/* Receive Compare 1 Register */ + +#define SSC_RC1R_MASK (0x0000ffff) /* Bit 0-15: Receive Compare Data 1 */ + +/* Status Register , Interrupt Enable Register, Interrupt Disable Register, and + * Interrupt Mask Register + */ + +#define SSC_INT_TXRDY (1 << 0) /* Bit 0: Transmit Ready */ +#define SSC_INT_TXEMPTY (1 << 1) /* Bit 1: Transmit Empty */ +#define SSC_INT_RXRDY (1 << 4) /* Bit 4: Receive Ready */ +#define SSC_INT_OVRUN (1 << 5) /* Bit 5: Receive Overrun */ +#define SSC_INT_CP0 (1 << 8) /* Bit 8: Compare 0 */ +#define SSC_INT_CP1 (1 << 9) /* Bit 9: Compare 1 */ +#define SSC_INT_TXSYN (1 << 10) /* Bit 10: Transmit Sync */ +#define SSC_INT_RXSYN (1 << 11) /* Bit 11: Receive Sync */ + +#define SSC_SR_TXEN (1 << 16) /* Bit 16: Transmit Enable (SR only) */ +#define SSC_SR_RXEN (1 << 17) /* Bit 17: Receive Enable (SR only) */ + +/* Write Protect Mode Register */ + +#define SSC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define SSC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define SSC_WPMR_WPKEY_MASK (0x00ffffff << SSC_WPMR_WPKEY_SHIFT) +# define SSC_WPMR_WPKEY (0x00535343 << SSC_WPMR_WPKEY_SHIFT) /* "SSC" in ASCII */ + +/* Write Protect Status Register */ + +#define SSC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define SSC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define SSC_WPSR_WPVSRC_MASK (0xffff << SSC_WPSR_WPVSRC_SHIFT) + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SSC_H */ diff --git a/arch/arm/src/sama5/chip/sam_tc.h b/arch/arm/src/sama5/chip/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..0ecc9fab449ea5248ce251bdbefc4939aca2cca9 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_tc.h @@ -0,0 +1,645 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_tc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_TC_NCHANNELS 3 /* Number of channels per TC peripheral */ +#define SAM_TC_MAXPERCLK 66000000 /* Maximum peripheral input clock frequency */ + +/* TC Register Offsets **************************************************************/ + +#define SAM_TC_CHAN_OFFSET(n) ((n) << 6) /* Channel n offset */ +#define SAM_TC_CCR_OFFSET 0x0000 /* Channel Control Register */ +#define SAM_TC_CMR_OFFSET 0x0004 /* Channel Mode Register */ +#define SAM_TC_SMMR_OFFSET 0x0008 /* Stepper Motor Mode Register */ +#define SAM_TC_RAB_OFFSET 0x000c /* Register AB */ +#define SAM_TC_CV_OFFSET 0x0010 /* Counter Value */ +#define SAM_TC_RA_OFFSET 0x0014 /* Register A */ +#define SAM_TC_RB_OFFSET 0x0018 /* Register B */ +#define SAM_TC_RC_OFFSET 0x001c /* Register C */ +#define SAM_TC_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ + +#ifdef ATSAMA5D4 +# define SAM_TC_EMR_OFFSET 0x0030 /* Extended Mode Register */ +#endif + +#define SAM_TCn_CCR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CCR_OFFSET) +#define SAM_TCn_CMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CMR_OFFSET) +#define SAM_TCn_SMMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_SMMR_OFFSET) +#define SAM_TCn_RAB_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RAB_OFFSET) +#define SAM_TCn_CV_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CV_OFFSET) +#define SAM_TCn_RA_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RA_OFFSET) +#define SAM_TCn_RB_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RB_OFFSET) +#define SAM_TCn_RC_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RC_OFFSET) +#define SAM_TCn_SR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_SR_OFFSET) +#define SAM_TCn_IER_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IER_OFFSET) +#define SAM_TCn_IDR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IDR_OFFSET) +#define SAM_TCn_IMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IMR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_TCn_EMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_EMR_OFFSET) +#endif + +#define SAM_TC0_CCR_OFFSET SAM_TCn_CCR_OFFSET(0) +#define SAM_TC0_CMR_OFFSET SAM_TCn_CMR_OFFSET(0) +#define SAM_TC0_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(0) +#define SAM_TC0_RAB_OFFSET SAM_TCn_RAB_OFFSET(0) +#define SAM_TC0_CV_OFFSET SAM_TCn_CV_OFFSET(0) +#define SAM_TC0_RA_OFFSET SAM_TCn_RA_OFFSET(0) +#define SAM_TC0_RB_OFFSET SAM_TCn_RB_OFFSET(0) +#define SAM_TC0_RC_OFFSET SAM_TCn_RC_OFFSET(0) +#define SAM_TC0_SR_OFFSET SAM_TCn_SR_OFFSET(0) +#define SAM_TC0_IER_OFFSET SAM_TCn_IER_OFFSET(0) +#define SAM_TC0_IDR_OFFSET SAM_TCn_IDR_OFFSET(0) +#define SAM_TC0_IMR_OFFSET SAM_TCn_IMR_OFFSET(0) + +#ifdef ATSAMA5D4 +# define SAM_TC0_EMR_OFFSET SAM_TCn_EMR_OFFSET(0) +#endif + +#define SAM_TC1_CCR_OFFSET SAM_TCn_CCR_OFFSET(1) +#define SAM_TC1_CMR_OFFSET SAM_TCn_CMR_OFFSET(1) +#define SAM_TC1_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(1) +#define SAM_TC1_RAB_OFFSET SAM_TCn_RAB_OFFSET(1) +#define SAM_TC1_CV_OFFSET SAM_TCn_CV_OFFSET(1) +#define SAM_TC1_RA_OFFSET SAM_TCn_RA_OFFSET(1) +#define SAM_TC1_RB_OFFSET SAM_TCn_RB_OFFSET(1) +#define SAM_TC1_RC_OFFSET SAM_TCn_RC_OFFSET(1) +#define SAM_TC1_SR_OFFSET SAM_TCn_SR_OFFSET(1) +#define SAM_TC1_IER_OFFSET SAM_TCn_IER_OFFSET(1) +#define SAM_TC1_IDR_OFFSET SAM_TCn_IDR_OFFSET(1) +#define SAM_TC1_IMR_OFFSET SAM_TCn_IMR_OFFSET(1) + +#ifdef ATSAMA5D4 +# define SAM_TC1_EMR_OFFSET SAM_TCn_EMR_OFFSET(1) +#endif + +#define SAM_TC2_CCR_OFFSET SAM_TCn_CCR_OFFSET(2) +#define SAM_TC2_CMR_OFFSET SAM_TCn_CMR_OFFSET(2) +#define SAM_TC2_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(2) +#define SAM_TC2_RAB_OFFSET SAM_TCn_RAB_OFFSET(2) +#define SAM_TC2_CV_OFFSET SAM_TCn_CV_OFFSET(2) +#define SAM_TC2_RA_OFFSET SAM_TCn_RA_OFFSET(2) +#define SAM_TC2_RB_OFFSET SAM_TCn_RB_OFFSET(2) +#define SAM_TC2_RC_OFFSET SAM_TCn_RC_OFFSET(2) +#define SAM_TC2_SR_OFFSET SAM_TCn_SR_OFFSET(2) +#define SAM_TC2_IER_OFFSET SAM_TCn_IER_OFFSET(2) +#define SAM_TC2_IDR_OFFSET SAM_TCn_IDR_OFFSET(2) +#define SAM_TC2_IMR_OFFSET SAM_TCn_IMR_OFFSET(2) + +#ifdef ATSAMA5D4 +# define SAM_TC2_EMR_OFFSET SAM_TCn_EMR_OFFSET(2) +#endif + +#define SAM_TC_BCR_OFFSET 0x00c0 /* Block Control Register */ +#define SAM_TC_BMR_OFFSET 0x00c4 /* Block Mode Register */ +#define SAM_TC_QIER_OFFSET 0x00c8 /* QDEC Interrupt Enable Register */ +#define SAM_TC_QIDR_OFFSET 0x00cc /* QDEC Interrupt Disable Register */ +#define SAM_TC_QIMR_OFFSET 0x00d0 /* QDEC Interrupt Mask Register */ +#define SAM_TC_QISR_OFFSET 0x00d4 /* QDEC Interrupt Status Register */ + +#ifdef ATSAMA5D4 +# define SAM_TC_FMR_OFFSET 0x00d8 /* Fault Mode Register */ +#endif + +#define SAM_TC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ + +/* TC Register Addresses ************************************************************/ + +#define SAM_TC012_CHAN_BASE(n) (SAM_TC012_VBASE+SAM_TC_CHAN_OFFSET(n)) + +#define SAM_TC012_CCR(n) (SAM_TC012_VBASE+SAM_TCn_CCR_OFFSET(n)) +#define SAM_TC012_CMR(n) (SAM_TC012_VBASE+SAM_TCn_CMR_OFFSET(n)) +#define SAM_TC012_SMMR(n) (SAM_TC012_VBASE+SAM_TCn_SMMR_OFFSET(n)) +#define SAM_TC012_RAB(n) (SAM_TC012_VBASE+SAM_TCn_RAB_OFFSET(n)) +#define SAM_TC012_CV(n) (SAM_TC012_VBASE+SAM_TCn_CV_OFFSET(n)) +#define SAM_TC012_RA(n) (SAM_TC012_VBASE+SAM_TCn_RA_OFFSET(n)) +#define SAM_TC012_RB(n) (SAM_TC012_VBASE+SAM_TCn_RB(n)) +#define SAM_TC012_RC(n) (SAM_TC012_VBASE+SAM_TCn_RC_OFFSET(n)) +#define SAM_TC012_SR(n) (SAM_TC012_VBASE+SAM_TCn_SR_OFFSET(n)) +#define SAM_TC012_IER(n) (SAM_TC012_VBASE+SAM_TCn_IER_OFFSET(n)) +#define SAM_TC012_IDR(n) (SAM_TC012_VBASE+SAM_TCn_IDR_OFFSET(n)) +#define SAM_TC012_IMR(n) (SAM_TC012_VBASE+SAM_TCn_IMR_OFFSET(n)) + +#ifdef ATSAMA5D4 +# define SAM_TC012_EMR(n) (SAM_TC012_VBASE+SAM_TCn_EMR_OFFSET(n)) +#endif + +#define SAM_TC0_CCR SAM_TC012_CCR(0) +#define SAM_TC0_CMR SAM_TC012_CMR(0) +#define SAM_TC0_SMMR SAM_TC012_SMMR(0) +#define SAM_TC0_RAB SAM_TC012_RAB(0) +#define SAM_TC0_CV SAM_TC012_CV(0) +#define SAM_TC0_RA SAM_TC012_RA(0) +#define SAM_TC0_RB SAM_TC012_RB(0) +#define SAM_TC0_RC SAM_TC012_RC(0) +#define SAM_TC0_SR SAM_TC012_SR(0) +#define SAM_TC0_IER SAM_TC012_IER(0) +#define SAM_TC0_IDR SAM_TC012_IDR(0) +#define SAM_TC0_IMR SAM_TC012_IMR(0) + +#ifdef ATSAMA5D4 +# define SAM_TC0_EMR SAM_TC012_EMR(0) +#endif + +#define SAM_TC1_CCR SAM_TC012_CCR(1) +#define SAM_TC1_CMR SAM_TC012_CMR(1) +#define SAM_TC1_SMMR SAM_TC012_SMMR(1) +#define SAM_TC1_RAB SAM_TC012_RAB(1) +#define SAM_TC1_CV SAM_TC012_CV(1) +#define SAM_TC1_RA SAM_TC012_RA(1) +#define SAM_TC1_RB SAM_TC012_RB(1) +#define SAM_TC1_RC SAM_TC012_RC(1) +#define SAM_TC1_SR SAM_TC012_SR(1) +#define SAM_TC1_IER SAM_TC012_IER(1) +#define SAM_TC1_IDR SAM_TC012_IDR(1) +#define SAM_TC1_IMR SAM_TC012_IMR(1) + +#ifdef ATSAMA5D4 +# define SAM_TC1_EMR SAM_TC012_EMR(1) +#endif + +#define SAM_TC2_CCR SAM_TC012_CCR(2) +#define SAM_TC2_CMR SAM_TC012_CMR(2) +#define SAM_TC2_SMMR SAM_TC012_SMMR(2) +#define SAM_TC2_RAB SAM_TC012_RAB(2) +#define SAM_TC2_CV SAM_TC012_CV(2) +#define SAM_TC2_RA SAM_TC012_RA(2) +#define SAM_TC2_RB SAM_TC012_RB(2) +#define SAM_TC2_RC SAM_TC012_RC(2) +#define SAM_TC2_SR SAM_TC012_SR(2) +#define SAM_TC2_IER SAM_TC012_IER(2) +#define SAM_TC2_IDR SAM_TC012_IDR(2) +#define SAM_TC2_IMR SAM_TC012_IMR(2) + +#ifdef ATSAMA5D4 +# define SAM_TC2_EMR SAM_TC012_EMR(2) +#endif + +#define SAM_TC012_BCR (SAM_TC012_VBASE+SAM_TC_BCR_OFFSET) +#define SAM_TC012_BMR (SAM_TC012_VBASE+SAM_TC_BMR_OFFSET) +#define SAM_TC012_QIER (SAM_TC012_VBASE+SAM_TC_QIER_OFFSET) +#define SAM_TC012_QIDR (SAM_TC012_VBASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC012_QIMR (SAM_TC012_VBASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC012_QISR (SAM_TC012_VBASE+SAM_TC_QISR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_TC012_FMR (SAM_TC012_VBASE+SAM_TC_FMR_OFFSET) +#endif + +#define SAM_TC012_WPMR (SAM_TC012_VBASE+SAM_TC_WPMR_OFFSET) + +#define SAM_TC345_CHAN_BASE(n) (SAM_TC345_VBASE+SAM_TC_CHAN_OFFSET((n)-3)) + +#define SAM_TC345_CCR(n) (SAM_TC345_VBASE+SAM_TCn_CCR_OFFSET((n)-3)) +#define SAM_TC345_CMR(n) (SAM_TC345_VBASE+SAM_TCn_CMR_OFFSET((n)-3)) +#define SAM_TC345_SMMR(n) (SAM_TC345_VBASE+SAM_TCn_SMMR_OFFSET((n)-3)) +#define SAM_TC345_RAB(n) (SAM_TC345_VBASE+SAM_TCn_RAB_OFFSET((n)-3)) +#define SAM_TC345_CV(n) (SAM_TC345_VBASE+SAM_TCn_CV_OFFSET((n)-3)) +#define SAM_TC345_RA(n) (SAM_TC345_VBASE+SAM_TCn_RA_OFFSET((n)-3)) +#define SAM_TC345_RB(n) (SAM_TC345_VBASE+SAM_TCn_RB_OFFSET((n)-3)) +#define SAM_TC345_RC(n) (SAM_TC345_VBASE+SAM_TCn_RC_OFFSET((n)-3)) +#define SAM_TC345_SR(n) (SAM_TC345_VBASE+SAM_TCn_SR_OFFSET((n)-3)) +#define SAM_TC345_IER(n) (SAM_TC345_VBASE+SAM_TCn_IER_OFFSET((n)-3)) +#define SAM_TC345_IDR(n) (SAM_TC345_VBASE+SAM_TCn_IDR_OFFSET((n)-3)) +#define SAM_TC345_IMR(n) (SAM_TC345_VBASE+SAM_TCn_IMR_OFFSET((n)-3)) + +#ifdef ATSAMA5D4 +# define SAM_TC345_EMR(n) (SAM_TC345_VBASE+SAM_TCn_EMR_OFFSET((n)-3)) +#endif + +#define SAM_TC3_CCR SAM_TC345_CCR(3) +#define SAM_TC3_CMR SAM_TC345_CMR(3) +#define SAM_TC3_SMMR SAM_TC345_SMMR(3) +#define SAM_TC3_RAB SAM_TC345_RAB(3) +#define SAM_TC3_CV SAM_TC345_CV(3) +#define SAM_TC3_RA SAM_TC345_RA(3) +#define SAM_TC3_RB SAM_TC345_RB(3) +#define SAM_TC3_RC SAM_TC345_RC(3) +#define SAM_TC3_SR SAM_TC345_SR(3) +#define SAM_TC3_IER SAM_TC345_IER(3) +#define SAM_TC3_IDR SAM_TC345_IDR(3) +#define SAM_TC3_IMR SAM_TC345_IMR(3) + +#ifdef ATSAMA5D4 +# define SAM_TC3_EMR SAM_TC345_EMR(3) +#endif + +#define SAM_TC4_CCR SAM_TC345_CCR(4) +#define SAM_TC4_CMR SAM_TC345_CMR(4) +#define SAM_TC4_SMMR SAM_TC345_SMMR(4) +#define SAM_TC4_RAB SAM_TC345_RAB(4) +#define SAM_TC4_CV SAM_TC345_CV(4) +#define SAM_TC4_RA SAM_TC345_RA(4) +#define SAM_TC4_RB SAM_TC345_RB(4) +#define SAM_TC4_RC SAM_TC345_RC(4) +#define SAM_TC4_SR SAM_TC345_SR(4) +#define SAM_TC4_IER SAM_TC345_IER(4) +#define SAM_TC4_IDR SAM_TC345_IDR(4) +#define SAM_TC4_IMR SAM_TC345_IMR(4) + +#ifdef ATSAMA5D4 +# define SAM_TC4_EMR SAM_TC345_EMR(4) +#endif + +#define SAM_TC5_CCR SAM_TC345_CCR(5) +#define SAM_TC5_CMR SAM_TC345_CMR(5) +#define SAM_TC5_SMMR SAM_TC345_SMMR(5) +#define SAM_TC5_RAB SAM_TC345_RAB(5) +#define SAM_TC5_CV SAM_TC345_CV(5) +#define SAM_TC5_RA SAM_TC345_RA(5) +#define SAM_TC5_RB SAM_TC345_RB(5) +#define SAM_TC5_RC SAM_TC345_RC(5) +#define SAM_TC5_SR SAM_TC345_SR(5) +#define SAM_TC5_IER SAM_TC345_IER(5) +#define SAM_TC5_IDR SAM_TC345_IDR(5) +#define SAM_TC5_IMR SAM_TC345_IMR(5) + +#ifdef ATSAMA5D4 +# define SAM_TC5_EMR SAM_345_EMR(5) +#endif + +#define SAM_TC345_BCR (SAM_TC345_VBASE+SAM_TC_BCR_OFFSET) +#define SAM_TC345_BMR (SAM_TC345_VBASE+SAM_TC_BMR_OFFSET) +#define SAM_TC345_QIER (SAM_TC345_VBASE+SAM_TC_QIER_OFFSET) +#define SAM_TC345_QIDR (SAM_TC345_VBASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC345_QIMR (SAM_TC345_VBASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC345_QISR (SAM_TC345_VBASE+SAM_TC_QISR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_TC345_FMR (SAM_TC345_VBASE+SAM_TC_FMR_OFFSET) +#endif + +#define SAM_TC345_WPMR (SAM_TC345_VBASE+SAM_TC_WPMR_OFFSET) + +#define SAM_TC678_CHAN_BASE(n) (SAM_TC678_VBASE+SAM_TC_CHAN_OFFSET((n)-6)) + +#define SAM_TC678_CCRn(n) (SAM_TC678_VBASE+SAM_TCn_CCR_OFFSET((n)-6)) +#define SAM_TC678_CMR(n) (SAM_TC678_VBASE+SAM_TCn_CMR_OFFSET((n)-6)) +#define SAM_TC678_SMMR(n) (SAM_TC678_VBASE+SAM_TCn_SMMR_OFFSET((n)-6)) +#define SAM_TC678_RAB(n) (SAM_TC678_VBASE+SAM_TCn_RAB_OFFSET((n)-6)) +#define SAM_TC678_CV(n) (SAM_TC678_VBASE+SAM_TCn_CV_OFFSET((n)-6)) +#define SAM_TC678_RA(n) (SAM_TC678_VBASE+SAM_TCn_RA_OFFSET((n)-6)) +#define SAM_TC678_RB(n) (SAM_TC678_VBASE+SAM_TCn_RB((n)-6)) +#define SAM_TC678_RC(n) (SAM_TC678_VBASE+SAM_TCn_RC_OFFSET((n)-6)) +#define SAM_TC678_SR(n) (SAM_TC678_VBASE+SAM_TCn_SR_OFFSET((n)-6)) +#define SAM_TC678_IER(n) (SAM_TC678_VBASE+SAM_TCn_IER_OFFSET((n)-6)) +#define SAM_TC678_IDR(n) (SAM_TC678_VBASE+SAM_TCn_IDR_OFFSET((n)-6)) +#define SAM_TC678_IMR(n) (SAM_TC678_VBASE+SAM_TCn_IMR_OFFSET((n)-6)) + +#ifdef ATSAMA5D4 +# define SAM_TC678_EMR(n) (SAM_TC678_VBASE+SAM_TCn_EMR_OFFSET((n)-6)) +#endif + +#define SAM_TC6_CCR SAM_TC678_CCR(6) +#define SAM_TC6_CMR SAM_TC678_CMR(6) +#define SAM_TC6_SMMR SAM_TC678_SMMR(6) +#define SAM_TC6_RAB SAM_TC678_RAB(6) +#define SAM_TC6_CV SAM_TC678_CV(6) +#define SAM_TC6_RA SAM_TC678_RA(6) +#define SAM_TC6_RB SAM_TC678_RB(6) +#define SAM_TC6_RC SAM_TC678_RC(6) +#define SAM_TC6_SR SAM_TC678_SR(6) +#define SAM_TC6_IER SAM_TC678_IER(6) +#define SAM_TC6_IDR SAM_TC678_IDR(6) +#define SAM_TC6_IMR SAM_TC678_IMR(6) + +#ifdef ATSAMA5D4 +# define SAM_TC6_EMR SAM_TC678_EMR(6) +#endif + +#define SAM_TC7_CCR SAM_TC678_CCR(7) +#define SAM_TC7_CMR SAM_TC678_CMR(7) +#define SAM_TC7_SMMR SAM_TC678_SMMR(7) +#define SAM_TC7_RAB SAM_TC678_RAB(7) +#define SAM_TC7_CV SAM_TC678_CV(7) +#define SAM_TC7_RA SAM_TC678_RA(7) +#define SAM_TC7_RB SAM_TC678_RB(7) +#define SAM_TC7_RC SAM_TC678_RC(7) +#define SAM_TC7_SR SAM_TC678_SR(7) +#define SAM_TC7_IER SAM_TC678_IER(7) +#define SAM_TC7_IDR SAM_TC678_IDR(7) +#define SAM_TC7_IMR SAM_TC678_IMR(7) + +#ifdef ATSAMA5D4 +# define SAM_TC7_EMR SAM_TC678_EMR(7) +#endif + +#define SAM_TC8_CCR SAM_TC678_CCR(8) +#define SAM_TC8_CMR SAM_TC678_CMR(8) +#define SAM_TC8_SMMR SAM_TC678_SMMR(8) +#define SAM_TC8_RAB SAM_TC678_RAB(8) +#define SAM_TC8_CV SAM_TC678_CV(8) +#define SAM_TC8_RA SAM_TC678_RA(8) +#define SAM_TC8_RB SAM_TC678_RB(8) +#define SAM_TC8_RC SAM_TC678_RC(8) +#define SAM_TC8_SR SAM_TC678_SR(8) +#define SAM_TC8_IER SAM_TC678_IER(8) +#define SAM_TC8_IDR SAM_TC678_IDR(8) +#define SAM_TC8_IMR SAM_TC678_IMR(8) + +#ifdef ATSAMA5D4 +# define SAM_TC8_EMR SAM_TC678_EMR(8) +#endif + +#define SAM_TC678_BCR (SAM_TC678_VBASE+SAM_TC_BCR_OFFSET) +#define SAM_TC678_BMR (SAM_TC678_VBASE+SAM_TC_BMR_OFFSET) +#define SAM_TC678_QIER (SAM_TC678_VBASE+SAM_TC_QIER_OFFSET) +#define SAM_TC678_QIDR (SAM_TC678_VBASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC678_QIMR (SAM_TC678_VBASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC678_QISR (SAM_TC678_VBASE+SAM_TC_QISR_OFFSET) + +#ifdef ATSAMA5D4 +# define SAM_TC678_FMR (SAM_TC678_VBASE+SAM_TC_FMR_OFFSET) +#endif + +#define SAM_TC678_WPMR (SAM_TC678_VBASE+SAM_TC_WPMR_OFFSET) + +/* TC Register Bit Definitions ******************************************************/ + +/* Channel Control Register */ + +#define TC_CCR_CLKEN (1 << 0) /* Bit 0: Counter Clock Enable Command */ +#define TC_CCR_CLKDIS (1 << 1) /* Bit 1: Counter Clock Disable Command */ +#define TC_CCR_SWTRG (1 << 2) /* Bit 2: Software Trigger Command */ + +/* Channel Mode Register -- All modes */ + +#define TC_CMR_TCCLKS_SHIFT (0) /* Bits 0-2: Clock Selection */ +#define TC_CMR_TCCLKS_MASK (7 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS(n) ((uint32_t)(n) << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TCLK1 (0 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK1 Clock selected */ +# define TC_CMR_TCCLKS_TCLK2 (1 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK2 Clock selected */ +# define TC_CMR_TCCLKS_TCLK3 (2 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK3 Clock selected */ +# define TC_CMR_TCCLKS_TCLK4 (3 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK4 Clock selected */ +# define TC_CMR_TCCLKS_TCLK5 (4 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK5 Clock selected */ +# define TC_CMR_TCCLKS_XC0 (5 << TC_CMR_TCCLKS_SHIFT) /* XC0 Clock selected */ +# define TC_CMR_TCCLKS_XC1 (6 << TC_CMR_TCCLKS_SHIFT) /* XC1 Clock selected */ +# define TC_CMR_TCCLKS_XC2 (7 << TC_CMR_TCCLKS_SHIFT) /* XC2 Clock selected */ +#define TC_CMR_CLKI (1 << 3) /* Bit 3: Clock Invert */ +#define TC_CMR_BURST_SHIFT (4) /* Bits 4-5: Burst Signal Selection */ +#define TC_CMR_BURST_MASK (3 << TC_CMR_BURST_SHIFT) +# define TC_CMR_BURST_NONE (0 << TC_CMR_BURST_SHIFT) /* Clock not gated by external signal */ +# define TC_CMR_BURST_XC0 (1 << TC_CMR_BURST_SHIFT) /* XXC0 ANDed with clock */ +# define TC_CMR_BURST_XC1 (2 << TC_CMR_BURST_SHIFT) /* XC1 ANDed with clock */ +# define TC_CMR_BURST_XC2 (3 << TC_CMR_BURST_SHIFT) /* XC2 ANDed with clock */ + +/* Channel Mode Register -- Capture mode */ + +#define TC_CMR_LDBSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RB Loading */ +#define TC_CMR_LDBDIS (1 << 7) /* Bit 7: Counter Clock Disable with RB Loading */ +#define TC_CMR_ETRGEDG_SHIFT (8) /* Bits 8-9: External Trigger Edge Selection */ +#define TC_CMR_ETRGEDG_MASK (3 << TC_CMR_ETRGEDG_SHIFT) +# define TC_CMR_ETRGEDG_NONE (0 << TC_CMR_ETRGEDG_SHIFT) /* Clock not gated by external signal */ +# define TC_CMR_ETRGEDG_RISING (1 << TC_CMR_ETRGEDG_SHIFT) /* Rising edge */ +# define TC_CMR_ETRGEDG_FALLING (2 << TC_CMR_ETRGEDG_SHIFT) /* Falling edge */ +# define TC_CMR_ETRGEDG_BOTH (3 << TC_CMR_ETRGEDG_SHIFT) /* EDGE Each edge */ +#define TC_CMR_ABETRG (1 << 10) /* Bit 10: TIOA or TIOB External Trigger Selection */ +#define TC_CMR_CPCTRG (1 << 14) /* Bit 14: RC Compare Trigger Enable */ +#define TC_CMR_CAPTURE (0) /* Bit 15: 0=Capture Mode */ +#define TC_CMR_LDRA_SHIFT (16) /* Bits 16-17: RA Loading Edge Selection */ +#define TC_CMR_LDRA_MASK (3 << TC_CMR_LDRA_SHIFT) +# define TC_CMR_LDRA_NONE (0 << TC_CMR_LDRA_SHIFT) /* None */ +# define TC_CMR_LDRA_RISING (1 << TC_CMR_LDRA_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRA_FALLING (2 << TC_CMR_LDRA_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRA_BOTH (3 << TC_CMR_LDRA_SHIFT) /* Each edge of TIOA */ +#define TC_CMR_LDRB_SHIFT (18) /* Bits 18-19: RB Loading Edge Selection */ +#define TC_CMR_LDRB_MASK (3 << TC_CMR_LDRB_SHIFT) +# define TC_CMR_LDRB_NONE (0 << TC_CMR_LDRB_SHIFT) /* None */ +# define TC_CMR_LDRB_RISING (1 << TC_CMR_LDRB_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRB_FALLING (2 << TC_CMR_LDRB_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRB_BOTH (3 << TC_CMR_LDRB_SHIFT) /* Each edge of TIOA */ + +#ifdef ATSAMA5D4 +# define TC_CMR_SBSMPLR_SHIFT (20) /* Bits 20-22: Loading Edge Subsampling Ratio */ +# define TC_CMR_SBSMPLR_MASK (7 << TC_CMR_SBSMPLR_SHIFT) +# define TC_CMR_SBSMPLR_ONE (0 << TC_CMR_SBSMPLR_SHIFT) /* Load on each selected edge */ +# define TC_CMR_SBSMPLR_HALF (1 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 2 selected edges */ +# define TC_CMR_SBSMPLR_4TH (2 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 4 selected edges */ +# define TC_CMR_SBSMPLR_8TH (3 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 8 selected edges */ +# define TC_CMR_SBSMPLR_16TH (4 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 16 selected edges */ +#endif + +/* Channel Mode Register -- Waveform mode */ + +#define TC_CMR_CPCSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RC Compare */ +#define TC_CMR_CPCDIS (1 << 7) /* Bit 7: Counter Clock Disable with RC Compare */ +#define TC_CMR_EEVTEDG_SHIFT (8) /* Bits 8-9: External Event Edge Selection */ +#define TC_CMR_EEVTEDG_MASK (3 << TC_CMR_EEVTEDG_SHIFT) +# define TC_CMR_EEVTEDG_NONE (0 << TC_CMR_EEVTEDG_SHIFT) /* None */ +# define TC_CMR_EEVTEDG_RISING (1 << TC_CMR_EEVTEDG_SHIFT) /* Rising edge */ +# define TC_CMR_EEVTEDG_FALLING (2 << TC_CMR_EEVTEDG_SHIFT) /* Falling edge */ +# define TC_CMR_EEVTEDG_BOTH (3 << TC_CMR_EEVTEDG_SHIFT) /* Each edge */ +#define TC_CMR_EEVT_SHIFT (10) /* Bits 10-11: External Event Selection */ +#define TC_CMR_EEVT_MASK (3 << TC_CMR_EEVT_SHIFT) +# define TC_CMR_EEVT_TIOB (0 << TC_CMR_EEVT_SHIFT) /* TIOB(1) input */ +# define TC_CMR_EEVT_XC0 (1 << TC_CMR_EEVT_SHIFT) /* XC0 output */ +# define TC_CMR_EEVT_XC1 (2 << TC_CMR_EEVT_SHIFT) /* XC1 output */ +# define TC_CMR_EEVT_XC2 (3 << TC_CMR_EEVT_SHIFT) /* XC2 output */ +#define TC_CMR_ENETRG (1 << 12) /* Bit 12: External Event Trigger Enable */ +#define TC_CMR_WAVSEL_SHIFT (13) /* Bits 13-14: Waveform Selection */ +#define TC_CMR_WAVSEL_MASK (3 << TC_CMR_WAVSEL_SHIFT) +# define TC_CMR_WAVSEL_UP (0 << TC_CMR_WAVSEL_SHIFT) /* UP mode w/o trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPDOWN (1 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode w/o trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPRC (2 << TC_CMR_WAVSEL_SHIFT) /* UP mode w/ trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPDOWNRC (3 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN w/ with trigger on RC Compare */ +#define TC_CMR_WAVE (1 << 15) /* Bit 15: 1=Waveform Mode */ +#define TC_CMR_ACPA_SHIFT (16) /* Bits 16-17: RA Compare Effect on TIOA */ +#define TC_CMR_ACPA_MASK (3 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_NONE (0 << TC_CMR_ACPA_SHIFT) /* None */ +# define TC_CMR_ACPA_SET (1 << TC_CMR_ACPA_SHIFT) /* Set */ +# define TC_CMR_ACPA_CLEAR (2 << TC_CMR_ACPA_SHIFT) /* Clear */ +# define TC_CMR_ACPA_TOGGLE (3 << TC_CMR_ACPA_SHIFT) /* Toggle */ +#define TC_CMR_ACPC_SHIFT (18) /* Bits 18-19: RC Compare Effect on TIOA */ +#define TC_CMR_ACPC_MASK (3 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_NONE (0 << TC_CMR_ACPC_SHIFT) /* None */ +# define TC_CMR_ACPC_SET (1 << TC_CMR_ACPC_SHIFT) /* Set */ +# define TC_CMR_ACPC_CLEAR (2 << TC_CMR_ACPC_SHIFT) /* Clear */ +# define TC_CMR_ACPC_TOGGLE (3 << TC_CMR_ACPC_SHIFT) /* Toggle */ +#define TC_CMR_AEEVT_SHIFT (20) /* Bits 20-21: External Event Effect on TIOA */ +#define TC_CMR_AEEVT_MASK (3 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_NONE (0 << TC_CMR_AEEVT_SHIFT) /* None */ +# define TC_CMR_AEEVT_SET (1 << TC_CMR_AEEVT_SHIFT) /* Set */ +# define TC_CMR_AEEVT_CLEAR (2 << TC_CMR_AEEVT_SHIFT) /* Clear */ +# define TC_CMR_AEEVT_TOGGLE (3 << TC_CMR_AEEVT_SHIFT) /* Toggle */ +#define TC_CMR_ASWTRG_SHIFT (22) /* Bits 22-23: Software Trigger Effect on TIOA */ +#define TC_CMR_ASWTRG_MASK (3 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_NONE (0 << TC_CMR_ASWTRG_SHIFT) /* None */ +# define TC_CMR_ASWTRG_SET (1 << TC_CMR_ASWTRG_SHIFT) /* Set */ +# define TC_CMR_ASWTRG_CLEAR (2 << TC_CMR_ASWTRG_SHIFT) /* Clear */ +# define TC_CMR_ASWTRG_TOGGLE (3 << TC_CMR_ASWTRG_SHIFT) /* Toggle */ +#define TC_CMR_BCPB_SHIFT (24) /* Bits 24-25: RB Compare Effect on TIOB */ +#define TC_CMR_BCPB_MASK (3 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_NONE (0 << TC_CMR_BCPB_SHIFT) /* None */ +# define TC_CMR_BCPB_SET (1 << TC_CMR_BCPB_SHIFT) /* Set */ +# define TC_CMR_BCPB_CLEAR (2 << TC_CMR_BCPB_SHIFT) /* Clear */ +# define TC_CMR_BCPB_TOGGLE (3 << TC_CMR_BCPB_SHIFT) /* Toggle */ +#define TC_CMR_BCPC_SHIFT (26) /* Bits 26-27: RC Compare Effect on TIOB */ +#define TC_CMR_BCPC_MASK (3 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_NONE (0 << TC_CMR_BCPC_SHIFT) /* None */ +# define TC_CMR_BCPC_SET (1 << TC_CMR_BCPC_SHIFT) /* Set */ +# define TC_CMR_BCPC_CLEAR (2 << TC_CMR_BCPC_SHIFT) /* Clear */ +# define TC_CMR_BCPC_TOGGLE (3 << TC_CMR_BCPC_SHIFT) /* Toggle */ +#define TC_CMR_BEEVT_SHIFT (28) /* Bits 28-29: External Event Effect on TIOB */ +#define TC_CMR_BEEVT_MASK (3 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_NONE (0 << TC_CMR_BEEVT_SHIFT) /* None */ +# define TC_CMR_BEEVT_SET (1 << TC_CMR_BEEVT_SHIFT) /* Set */ +# define TC_CMR_BEEVT_CLEAR (2 << TC_CMR_BEEVT_SHIFT) /* Clear */ +# define TC_CMR_BEEVT_TOGGLE (3 << TC_CMR_BEEVT_SHIFT) /* Toggle */ +#define TC_CMR_BSWTRG_SHIFT (30) /* Bits 30-31: Software Trigger Effect on TIOB */ +#define TC_CMR_BSWTRG_MASK (3 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_NONE (0 << TC_CMR_BSWTRG_SHIFT) /* None */ +# define TC_CMR_BSWTRG_SET (1 << TC_CMR_BSWTRG_SHIFT) /* Set */ +# define TC_CMR_BSWTRG_CLEAR (2 << TC_CMR_BSWTRG_SHIFT) /* Clear */ +# define TC_CMR_BSWTRG_TOGGLE (3 << TC_CMR_BSWTRG_SHIFT) /* Toggle */ + +/* Stepper Motor Mode Register */ + +#define TC_SMMR_GCEN (1 << 0) /* Bit 0: Gray Count Enable */ +#define TC_SMMR_DOWN (1 << 1) /* Bit 1: DOWN Count */ + +/* Register AB (32-bit capture value) */ +/* Counter Value (32-bit counter value) */ +/* Register A (32-bit value) */ +/* Register B (32-bit value) */ +/* Register C (32-bit value) */ + +/* Status Register, Interrupt Enable Register, Interrupt Disable Register, and + * Interrupt Mask Register + */ + +#define TC_INT_COVFS (1 << 0) /* Bit 0: Counter Overflow Status */ +#define TC_INT_LOVRS (1 << 1) /* Bit 1: Load Overrun Status */ +#define TC_INT_CPAS (1 << 2) /* Bit 2: RA Compare Status */ +#define TC_INT_CPBS (1 << 3) /* Bit 3: RB Compare Status */ +#define TC_INT_CPCS (1 << 4) /* Bit 4: RC Compare Status */ +#define TC_INT_LDRAS (1 << 5) /* Bit 5: RA Loading Status */ +#define TC_INT_LDRBS (1 << 6) /* Bit 6: RB Loading Status */ +#define TC_INT_ETRGS (1 << 7) /* Bit 7: External Trigger Status */ +#define TC_INT_ALL (0xff) + +#define TC_SR_CLKSTA (1 << 16) /* Bit 16: Clock Enabling Status */ +#define TC_SR_MTIOA (1 << 17) /* Bit 17: TIOA Mirror */ +#define TC_SR_MTIOB (1 << 18) /* Bit 18: TIOB Mirror */ + +#ifdef ATSAMA5D4 +/* Extended Mode Register */ + +# define TC_EMR_TRIGSRCA_SHIFT (0) /* Bits 0-1: Trigger source for input A */ +# define TC_EMR_TRIGSRCA_MASK (3 << TC_EMR_TRIGSRCA_SHIFT) +# define TC_EMR_TRIGSRCA_TIOA (0 << TC_EMR_TRIGSRCA_SHIFT) /* Trigger/capture input A driven by TIOAx */ +# define TC_EMR_TRIGSRCA_PWM (1 << TC_EMR_TRIGSRCA_SHIFT) /* Trigger/capture input A driven by PWMx */ +# define TC_EMR_TRIGSRCB_SHIFT (4) /* Bits 4-5: Trigger source for input B */ +# define TC_EMR_TRIGSRCB_MASK (3 << TC_EMR_TRIGSRCB_SHIFT) +# define TC_EMR_TRIGSRCB_TIOB (0 << TC_EMR_TRIGSRCB_SHIFT) /* Trigger/capture input B driven by TIOBx */ +# define TC_EMR_TRIGSRCB_PWM (1 << TC_EMR_TRIGSRCB_SHIFT) /* Trigger/capture input B driven PWMx */ +# define TC_EMR_NODIVCLK (1 << 8) /* Bit 8: No divided clock */ +#endif + +/* Block Control Register */ + +#define TC_BCR_SYNC (1 << 0) /* Bit 0: Synchro Command */ + +/* Block Mode Register */ + +#define TC_BMR_TC0XC0S_SHIFT (0) /* Bits 0-1: External Clock Signal 0 Selection */ +#define TC_BMR_TC0XC0S_MASK (3 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_TCLK0 (0 << TC_BMR_TC0XC0S_SHIFT) /* TCLK0 Signal to XC0 */ +# define TC_BMR_TC0XC0S_TIOA1 (2 << TC_BMR_TC0XC0S_SHIFT) /* TIOA1 Signal to XC0 */ +# define TC_BMR_TC0XC0S_TIOA2 (3 << TC_BMR_TC0XC0S_SHIFT) /* TIOA2 Signal to XC0 */ +#define TC_BMR_TC1XC1S_SHIFT (2) /* Bits 2-3: External Clock Signal 1 Selection */ +#define TC_BMR_TC1XC1S_MASK (3 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC1XC1S_TCLK1 (0 << TC_BMR_TC1XC1S_SHIFT) /* TCLK1 Signal to XC1 */ +# define TC_BMR_TC1XC1S_TIOA0 (2 << TC_BMR_TC1XC1S_SHIFT) /* TIOA0 Signal to XC1 */ +# define TC_BMR_TC1XC1S_TIOA2 (3 << TC_BMR_TC1XC1S_SHIFT) /* TIOA2 Signal to XC1 */ +#define TC_BMR_TC2XC2S_SHIFT (4) /* Bits 4-5: External Clock Signal 2 Selection */ +#define TC_BMR_TC2XC2S_MASK (3 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT) /* TCLK2 Signal to XC2 */ +# define TC_BMR_TC2XC2S_TIOA0 (2 << TC_BMR_TC2XC2S_SHIFT) /* TIOA0 Signal to XC2 */ +# define TC_BMR_TC2XC2S_TIOA1 (3 << TC_BMR_TC2XC2S_SHIFT) /* TIOA1 Signal to XC2 */ +#define TC_BMR_QDEN (1 << 8) /* Bit 8: Quadrature Decoder ENabled */ +#define TC_BMR_POSEN (1 << 9) /* Bit 9: POSition ENabled */ +#define TC_BMR_SPEEDEN (1 << 10) /* Bit 10: SPEED ENabled */ +#define TC_BMR_QDTRANS (1 << 11) /* Bit 11: Quadrature Decoding TRANSparent */ +#define TC_BMR_EDGPHA (1 << 12) /* Bit 12: EDGe on PHA count mode */ +#define TC_BMR_INVA (1 << 13) /* Bit 13: INVerted phA */ +#define TC_BMR_INVB (1 << 14) /* Bit 14: INVerted phB */ +#define TC_BMR_INVIDX (1 << 15) /* Bit 15: INVerted InDeX */ +#define TC_BMR_SWAP (1 << 16) /* Bit 16: SWAP PHA and PHB */ +#define TC_BMR_IDXPHB (1 << 17) /* Bit 17: InDeX pin is PHB pin */ +#define TC_BMR_FILTE (1 << 19) /* Bit 19: Filter enable */ +#define TC_BMR_MAXFILT_SHIFT (20) /* Bits 20-25: MAXimum FILTer */ +#define TC_BMR_MAXFILT_MASK (63 << TC_BMR_MAXFILT_SHIFT) +# define TC_BMR_MAXFILT(n) ((uint32_t)(n) << TC_BMR_MAXFILT_SHIFT) + +/* QDEC Interrupt Enable Register, QDEC Interrupt Disable Register, QDEC Interrupt Mask Register, and QDEC Interrupt Status Register. + */ + +#define TC_QINT_IDX (1 << 0) /* Bit 0: Index */ +#define TC_QINT_DIRCHG (1 << 1) /* Bit 1: Direction change */ +#define TC_QINT_QERR (1 << 2) /* Bit 2: Quadrature ERRor */ + +#define TC_QISR_DIRR (1 << 8) /* Bit 8: Direction */ + +#ifdef ATSAMA5D4 +/* Fault Mode Register */ + +# define TC_FMR_ENCF0 (1 << 0) /* Bit 0: ENable Compare Fault Channel 0 */ +# define TC_FMR_ENCF1 (1 << 1) /* Bit 1: ENable Compare Fault Channel 1 */ +#endif + +/* Write Protect Mode Register */ + +#define TC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define TC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define TC_WPMR_WPKEY_MASK (0xffffff << TC_WPMR_WPKEY_SHIFT) +# define TC_WPMR_WPKEY (0x54494d << TC_WPMR_WPKEY_SHIFT) /* "TIM" in ASCII */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TC_H */ diff --git a/arch/arm/src/sama5/chip/sam_trng.h b/arch/arm/src/sama5/chip/sam_trng.h new file mode 100644 index 0000000000000000000000000000000000000000..15ac49cb10592001e40e887f11b27f78fa7348a5 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_trng.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_trng.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TRNG_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TRNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* TRNG Register Offsets ************************************************************/ + +#define SAM_TRNG_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_TRNG_IER_OFFSET 0x0010 /* Interrupt Enable Register */ +#define SAM_TRNG_IDR_OFFSET 0x0014 /* Interrupt Disable Register */ +#define SAM_TRNG_IMR_OFFSET 0x0018 /* Interrupt Mask Register */ +#define SAM_TRNG_ISR_OFFSET 0x001c /* Interrupt Status Register */ +#define SAM_TRNG_ODATA_OFFSET 0x0050 /* Output Data Register */ + +/* TRNG Register Addresses **********************************************************/ + +#define SAM_TRNG_CR (SAM_TRNG_VBASE+SAM_TRNG_CR_OFFSET) +#define SAM_TRNG_IER (SAM_TRNG_VBASE+SAM_TRNG_IER_OFFSET) +#define SAM_TRNG_IDR (SAM_TRNG_VBASE+SAM_TRNG_IDR_OFFSET) +#define SAM_TRNG_IMR (SAM_TRNG_VBASE+SAM_TRNG_IMR_OFFSET) +#define SAM_TRNG_ISR (SAM_TRNG_VBASE+SAM_TRNG_ISR_OFFSET) +#define SAM_TRNG_ODATA (SAM_TRNG_VBASE+SAM_TRNG_ODATA_OFFSET) + +/* TRNG Register Bit Definitions ****************************************************/ + +/* Control Register */ + +#define TRNG_CR_ENABLE (1 << 0) /* Bit 0: 1=Enables the TRNG */ +# define TRNG_CR_DISABLE (0) /* Bit 0: 0=Disables the TRNG */ +#define TRNG_CR_KEY_SHIFT (8) /* Bits 8-31: Security key */ +#define TRNG_CR_KEY_MASK (0xffffff << TRNG_CR_KEY_SHIFT) +# define TRNG_CR_KEY (0x524e47 << TRNG_CR_KEY_SHIFT) /* RNG in ASCII */ + +/* Interrupt Enable Register, Interrupt Disable Register, Interrupt Mask Register, + * and Interrupt Status Register + */ + +#define TRNG_INT_DATRDY (1 << 0) /* Bit 0: Data ready */ + +/* Output Data Register (32-bit output data) */ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TRNG_H */ diff --git a/arch/arm/src/sama5/chip/sam_twi.h b/arch/arm/src/sama5/chip/sam_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..daf1181be5c6ae2ef334c371ede270e26a910a01 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_twi.h @@ -0,0 +1,242 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_twi.h + * Two-wire Interface (TWI) definitions for the SAMA5 + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TWI_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TWI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* TWI register offsets *****************************************************************/ + +#define SAM_TWI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_TWI_MMR_OFFSET 0x0004 /* Master Mode Register */ +#define SAM_TWI_SMR_OFFSET 0x0008 /* Slave Mode Register */ +#define SAM_TWI_IADR_OFFSET 0x000c /* Internal Address Register */ +#define SAM_TWI_CWGR_OFFSET 0x0010 /* Clock Waveform Generator Register */ + /* 0x0014-0x001c: Reserved */ +#define SAM_TWI_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TWI_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TWI_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TWI_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_TWI_RHR_OFFSET 0x0030 /* Receive Holding Register */ +#define SAM_TWI_THR_OFFSET 0x0034 /* Transmit Holding Register */ + /* 0x0038-0x00e0: Reserved */ +#define SAM_TWI_WPMR_OFFSET 0x00e4 /* Protection Mode Register */ +#define SAM_TWI_WPSR_OFFSET 0x00e8 /* Protection Status Register */ + /* 0x00ec-0x00fc: Reserved */ + +/* TWI register adresses ****************************************************************/ + +#define SAM_TWI0_CR (SAM_TWI0_VBASE+SAM_TWI_CR_OFFSET) +#define SAM_TWI0_MMR (SAM_TWI0_VBASE+SAM_TWI_MMR_OFFSET) +#define SAM_TWI0_SMR (SAM_TWI0_VBASE+SAM_TWI_SMR_OFFSET) +#define SAM_TWI0_IADR (SAM_TWI0_VBASE+SAM_TWI_IADR_OFFSET) +#define SAM_TWI0_CWGR (SAM_TWI0_VBASE+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI0_SR (SAM_TWI0_VBASE+SAM_TWI_SR_OFFSET) +#define SAM_TWI0_IER (SAM_TWI0_VBASE+SAM_TWI_IER_OFFSET) +#define SAM_TWI0_IDR (SAM_TWI0_VBASE+SAM_TWI_IDR_OFFSET) +#define SAM_TWI0_IMR (SAM_TWI0_VBASE+SAM_TWI_IMR_OFFSET) +#define SAM_TWI0_RHR (SAM_TWI0_VBASE+SAM_TWI_RHR_OFFSET) +#define SAM_TWI0_THR (SAM_TWI0_VBASE+SAM_TWI_THR_OFFSET) +#define SAM_TWI0_WPMR (SAM_TWI0_VBASE+SAM_TWI_WPMR_OFFSET) +#define SAM_TWI0_WPSR (SAM_TWI0_VBASE+SAM_TWI_WPSR_OFFSET) + +#define SAM_TWI1_CR (SAM_TWI1_VBASE+SAM_TWI_CR_OFFSET) +#define SAM_TWI1_MMR (SAM_TWI1_VBASE+SAM_TWI_MMR_OFFSET) +#define SAM_TWI1_SMR (SAM_TWI1_VBASE+SAM_TWI_SMR_OFFSET) +#define SAM_TWI1_IADR (SAM_TWI1_VBASE+SAM_TWI_IADR_OFFSET) +#define SAM_TWI1_CWGR (SAM_TWI1_VBASE+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI1_SR (SAM_TWI1_VBASE+SAM_TWI_SR_OFFSET) +#define SAM_TWI1_IER (SAM_TWI1_VBASE+SAM_TWI_IER_OFFSET) +#define SAM_TWI1_IDR (SAM_TWI1_VBASE+SAM_TWI_IDR_OFFSET) +#define SAM_TWI1_IMR (SAM_TWI1_VBASE+SAM_TWI_IMR_OFFSET) +#define SAM_TWI1_RHR (SAM_TWI1_VBASE+SAM_TWI_RHR_OFFSET) +#define SAM_TWI1_THR (SAM_TWI1_VBASE+SAM_TWI_THR_OFFSET) +#define SAM_TWI1_WPMR (SAM_TWI1_VBASE+SAM_TWI_WPMR_OFFSET) +#define SAM_TWI1_WPSR (SAM_TWI1_VBASE+SAM_TWI_WPSR_OFFSET) + +#define SAM_TWI2_CR (SAM_TWI2_VBASE+SAM_TWI_CR_OFFSET) +#define SAM_TWI2_MMR (SAM_TWI2_VBASE+SAM_TWI_MMR_OFFSET) +#define SAM_TWI2_SMR (SAM_TWI2_VBASE+SAM_TWI_SMR_OFFSET) +#define SAM_TWI2_IADR (SAM_TWI2_VBASE+SAM_TWI_IADR_OFFSET) +#define SAM_TWI2_CWGR (SAM_TWI2_VBASE+SAM_TWI_CWGR_OFFSET) +#define SAM_TWI2_SR (SAM_TWI2_VBASE+SAM_TWI_SR_OFFSET) +#define SAM_TWI2_IER (SAM_TWI2_VBASE+SAM_TWI_IER_OFFSET) +#define SAM_TWI2_IDR (SAM_TWI2_VBASE+SAM_TWI_IDR_OFFSET) +#define SAM_TWI2_IMR (SAM_TWI2_VBASE+SAM_TWI_IMR_OFFSET) +#define SAM_TWI2_RHR (SAM_TWI2_VBASE+SAM_TWI_RHR_OFFSET) +#define SAM_TWI2_THR (SAM_TWI2_VBASE+SAM_TWI_THR_OFFSET) +#define SAM_TWI2_WPMR (SAM_TWI2_VBASE+SAM_TWI_WPMR_OFFSET) +#define SAM_TWI2_WPSR (SAM_TWI2_VBASE+SAM_TWI_WPSR_OFFSET) + +#ifdef CONFIG_SAMA5_HAVE_TWI3 +# define SAM_TWI3_CR (SAM_TWI3_VBASE+SAM_TWI_CR_OFFSET) +# define SAM_TWI3_MMR (SAM_TWI3_VBASE+SAM_TWI_MMR_OFFSET) +# define SAM_TWI3_SMR (SAM_TWI3_VBASE+SAM_TWI_SMR_OFFSET) +# define SAM_TWI3_IADR (SAM_TWI3_VBASE+SAM_TWI_IADR_OFFSET) +# define SAM_TWI3_CWGR (SAM_TWI3_VBASE+SAM_TWI_CWGR_OFFSET) +# define SAM_TWI3_SR (SAM_TWI3_VBASE+SAM_TWI_SR_OFFSET) +# define SAM_TWI3_IER (SAM_TWI3_VBASE+SAM_TWI_IER_OFFSET) +# define SAM_TWI3_IDR (SAM_TWI3_VBASE+SAM_TWI_IDR_OFFSET) +# define SAM_TWI3_IMR (SAM_TWI3_VBASE+SAM_TWI_IMR_OFFSET) +# define SAM_TWI3_RHR (SAM_TWI3_VBASE+SAM_TWI_RHR_OFFSET) +# define SAM_TWI3_THR (SAM_TWI3_VBASE+SAM_TWI_THR_OFFSET) +# define SAM_TWI3_WPMR (SAM_TWI3_VBASE+SAM_TWI_WPMR_OFFSET) +# define SAM_TWI3_WPSR (SAM_TWI3_VBASE+SAM_TWI_WPSR_OFFSET) +#endif + +/* TWI register bit definitions *********************************************************/ + +/* TWI Control Register */ + +#define TWI_CR_START (1 << 0) /* Bit 0: Send a START Condition */ +#define TWI_CR_STOP (1 << 1) /* Bit 1: Send a STOP Condition */ +#define TWI_CR_MSEN (1 << 2) /* Bit 2: TWI Master Mode Enabled */ +#define TWI_CR_MSDIS (1 << 3) /* Bit 3: TWI Master Mode Disabled */ +#define TWI_CR_SVEN (1 << 4) /* Bit 4: TWI Slave Mode Enabled */ +#define TWI_CR_SVDIS (1 << 5) /* Bit 5: TWI Slave Mode Disabled */ +#define TWI_CR_QUICK (1 << 6) /* Bit 6: SMBUS Quick Command */ +#define TWI_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ + +/* TWI Master Mode Register */ + +#define TWI_MMR_IADRSZ_SHIFT (8) /* Bits 8-9: Internal Device Address Size */ +#define TWI_MMR_IADRSZ_MASK (3 << TWI_MMR_IADRSZ_SHIFT) +# define TWI_MMR_IADRSZ_NONE (0 << TWI_MMR_IADRSZ_SHIFT) /* No internal device address */ +# define TWI_MMR_IADRSZ_1BYTE (1 << TWI_MMR_IADRSZ_SHIFT) /* One-byte internal device address */ +# define TWI_MMR_IADRSZ_2BYTE (2 << TWI_MMR_IADRSZ_SHIFT) /* Two-byte internal device address */ +# define TWI_MMR_IADRSZ_3BYTE (3 << TWI_MMR_IADRSZ_SHIFT) /* Three-byte internal device address */ +#define TWI_MMR_MREAD (1 << 12) /* Bit 12: Master Read Direction */ +#define TWI_MMR_DADR_SHIFT (16) /* Bits 16-22: Device Address */ +#define TWI_MMR_DADR_MASK (0x7f << TWI_MMR_DADR_SHIFT) +# define TWI_MMR_DADR(n) ((uint32_t)(n) << TWI_MMR_DADR_SHIFT) + +/* TWI Slave Mode Register */ + +#define TWI_SMR_SADR_SHIFT (16) /* Bits 16-22: Slave Address */ +#define TWI_SMR_SADR_MASK (0x7f << TWI_SMR_SADR_SHIFT) +# define TWI_SMR_SADR(n) ((uint32_t)(n) << TWI_SMR_SADR_SHIFT) + +/* TWI Internal Address Register */ + +#define TWI_IADR_SHIFT (0) /* Bits 0-23: Internal Address */ +#define TWI_IADR_MASK (0x00ffffff << TWI_IADR_SHIFT) +# define TWI_IADR(n) ((uint32_t)(n) << TWI_IADR_SHIFT) + +/* TWI Clock Waveform Generator Register */ + +#define TWI_CWGR_CLDIV_SHIFT (0) /* Bits 0-7: Clock Low Divider */ +#define TWI_CWGR_CLDIV_MASK (0xff << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CLDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) +#define TWI_CWGR_CHDIV_SHIFT (8) /* Bits 8-15: Clock High Divider */ +#define TWI_CWGR_CHDIV_MASK (0xff << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CHDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) +#define TWI_CWGR_CKDIV_SHIFT (16) /* Bits 16-18: Clock Divider */ +#define TWI_CWGR_CKDIV_MASK (7 << TWI_CWGR_CLDIV_SHIFT) +# define TWI_CWGR_CKDIV(n) ((uint32_t)(n) << TWI_CWGR_CLDIV_SHIFT) + +#ifdef ATSAMA5D4 +# define TWI_CWGR_HOLD_SHIFT (24) /* Bits 24-28: TWD Hold Time versus TWCK falling */ +# define TWI_CWGR_HOLD_MASK (31 << TWI_CWGR_HOLD_SHIFT) +# define TWI_CWGR_HOLD(n) ((uint32_t)(n) << TWI_CWGR_HOLD_SHIFT) +#endif + +/* TWI Status Register, TWI Interrupt Enable Register, TWI Interrupt Disable + * Register, and TWI Interrupt Mask Register common bit fields. + */ + +#define TWI_INT_TXCOMP (1 << 0) /* Bit 0: Transmission Completed */ +#define TWI_INT_RXRDY (1 << 1) /* Bit 1: Receive Holding Register */ +#define TWI_INT_TXRDY (1 << 2) /* Bit 2: Transmit Holding Register Ready */ +#define TWI_SR_SVREAD (1 << 3) /* Bit 3: Slave Read (SR only) */ +#define TWI_INT_SVACC (1 << 4) /* Bit 4: Slave Access */ +#define TWI_INT_GACC (1 << 5) /* Bit 5: General Call Access */ +#define TWI_INT_OVRE (1 << 6) /* Bit 6: Overrun Error */ +#define TWI_INT_NACK (1 << 8) /* Bit 8: Not Acknowledged */ +#define TWI_INT_ARBLST (1 << 9) /* Bit 9: Arbitration Lost */ +#define TWI_INT_SCLWS (1 << 10) /* Bit 10: Clock Wait State */ +#define TWI_INT_EOSACC (1 << 11) /* Bit 11: End Of Slave Access */ + +#define TWI_INT_ERRORS (0x00000340) +#define TWI_INT_ALL (0x00000f77) + +/* TWI Receive Holding Register */ + +#define TWI_RHR_RXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Receive Holding Data */ +#define TWI_RHR_RXDATA_MASK (0xff << TWI_RHR_RXDATA_SHIFT) + +/* TWI Transmit Holding Register */ + +#define TWI_THR_TXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Transmit Holding Data */ +#define TWI_THR_TXDATA_MASK (0xff << TWI_THR_TXDATA_SHIFT) + +/* Protection Mode Register */ + +#define TWI_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define TWI_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection Key */ +#define TWI_WPMR_WPKEY_MASK (0x00ffffff << TWI_WPMR_WPKEY_SHIFT) +# define TWI_WPMR_WPKEY (0x00545749 << TWI_WPMR_WPKEY_SHIFT) + +/* Protection Status Register */ + +#define TWI_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define TWI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-31: Write Protection Violation Source */ +#define TWI_WPSR_WPVSRC_MASK (0x00ffffff << TWI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_TWI_H */ diff --git a/arch/arm/src/sama5/chip/sam_uart.h b/arch/arm/src/sama5/chip/sam_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..2ce0abbbf1bba82540f79eca374df2c3f2d26bc1 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_uart.h @@ -0,0 +1,575 @@ +/************************************************************************************************ + * arch/arm/src/sama5/chip/sam_uart.h + * Universal Asynchronous Receiver Transmitter (UART) for the SAMA5D2, SAMA5D3, and SAMA5D4 and + * Universal Synchronous Asynchronous Receiver Transmitter (USART) definitions for the SAMA5D3 + * and SAMAD4 + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UART_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UART_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* UART register offsets ************************************************************************/ +/* Key: + * (1) Common to both UART and SAMA5D3/4 USART + * (2) SAMA5D3/4 USART only + * (3) SAMA5D2 UART only + * (4) SAMA5D3/4 USART and SAMA5D2 UART only. + */ + +#define SAM_UART_CR_OFFSET 0x0000 /* Control Register (1) */ +#define SAM_UART_MR_OFFSET 0x0004 /* Mode Register (1) */ +#define SAM_UART_IER_OFFSET 0x0008 /* Interrupt Enable Register (1) */ +#define SAM_UART_IDR_OFFSET 0x000c /* Interrupt Disable Register (1) */ +#define SAM_UART_IMR_OFFSET 0x0010 /* Interrupt Mask Register (1) */ +#define SAM_UART_SR_OFFSET 0x0014 /* [Channel] Status Register (1) */ +#define SAM_UART_RHR_OFFSET 0x0018 /* Receive Holding Register (1) */ +#define SAM_UART_THR_OFFSET 0x001c /* Transmit Holding Register (1) */ +#define SAM_UART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register (1) */ + /* 0x0024-0x003c: Reserved (UART) */ + +#if defined(ATSAMA5D2) +# define SAM_UART_CMPR_OFFSET 0x0024 /* Comparison Register (3) */ +# define SAM_UART_RTOR_OFFSET 0x0028 /* Receiver Time-out Register (4) */ +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define SAM_UART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register (4) */ +# define SAM_UART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register (2) */ + /* 0x002c-0x003c: Reserved */ +# define SAM_UART_FIDI_OFFSET 0x0040 /* FI DI Ratio Register (2) */ +# define SAM_UART_NER_OFFSET 0x0044 /* Number of Errors Register (2) */ + /* 0x0048: Reserved (USART) */ +# define SAM_UART_IFR_OFFSET 0x004c /* IrDA Filter Register (2) */ +# define SAM_UART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register (2) */ +#endif + +#define SAM_UART_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register (4) */ + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define SAM_UART_WPSR_OFFSET 0x00e8 /* Write Protect Status Register (4) */ +#endif + /* 0x00ec-0xfc: Reserved (USART) */ + +/* UART register adresses ***********************************************************************/ + +#define SAM_UART0_CR (SAM_UART0_VBASE+SAM_UART_CR_OFFSET) +#define SAM_UART0_MR (SAM_UART0_VBASE+SAM_UART_MR_OFFSET) +#define SAM_UART0_IER (SAM_UART0_VBASE+SAM_UART_IER_OFFSET) +#define SAM_UART0_IDR (SAM_UART0_VBASE+SAM_UART_IDR_OFFSET) +#define SAM_UART0_IMR (SAM_UART0_VBASE+SAM_UART_IMR_OFFSET) +#define SAM_UART0_SR (SAM_UART0_VBASE+SAM_UART_SR_OFFSET) +#define SAM_UART0_RHR (SAM_UART0_VBASE+SAM_UART_RHR_OFFSET) +#define SAM_UART0_THR (SAM_UART0_VBASE+SAM_UART_THR_OFFSET) +#define SAM_UART0_BRGR (SAM_UART0_VBASE+SAM_UART_BRGR_OFFSET) +#if defined(ATSAMA5D2) +# define SAM_UART0_CMPR (SAM_UART0_VBASE+SAM_UART_CMPR_OFFSET) +# define SAM_UART0_RTOR (SAM_UART0_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_UART0_WPMR (SAM_UART0_VBASE+SAM_UART_WPMR_OFFSET) +#endif + +#define SAM_UART1_CR (SAM_UART1_VBASE+SAM_UART_CR_OFFSET) +#define SAM_UART1_MR (SAM_UART1_VBASE+SAM_UART_MR_OFFSET) +#define SAM_UART1_IER (SAM_UART1_VBASE+SAM_UART_IER_OFFSET) +#define SAM_UART1_IDR (SAM_UART1_VBASE+SAM_UART_IDR_OFFSET) +#define SAM_UART1_IMR (SAM_UART1_VBASE+SAM_UART_IMR_OFFSET) +#define SAM_UART1_SR (SAM_UART1_VBASE+SAM_UART_SR_OFFSET) +#define SAM_UART1_RHR (SAM_UART1_VBASE+SAM_UART_RHR_OFFSET) +#define SAM_UART1_THR (SAM_UART1_VBASE+SAM_UART_THR_OFFSET) +#define SAM_UART1_BRGR (SAM_UART1_VBASE+SAM_UART_BRGR_OFFSET) +#if defined(ATSAMA5D2) +# define SAM_UART1_CMPR (SAM_UART1_VBASE+SAM_UART_CMPR_OFFSET) +# define SAM_UART1_RTOR (SAM_UART1_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_UART1_WPMR (SAM_UART1_VBASE+SAM_UART_WPMR_OFFSET) +#endif + +#if defined(ATSAMA5D2) +# define SAM_UART2_CR (SAM_UART2_VBASE+SAM_UART_CR_OFFSET) +# define SAM_UART2_MR (SAM_UART2_VBASE+SAM_UART_MR_OFFSET) +# define SAM_UART2_IER (SAM_UART2_VBASE+SAM_UART_IER_OFFSET) +# define SAM_UART2_IDR (SAM_UART2_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_UART2_IMR (SAM_UART2_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_UART2_SR (SAM_UART2_VBASE+SAM_UART_SR_OFFSET) +# define SAM_UART2_RHR (SAM_UART2_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_UART2_THR (SAM_UART2_VBASE+SAM_UART_THR_OFFSET) +# define SAM_UART2_BRGR (SAM_UART2_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART2_CMPR (SAM_UART2_VBASE+SAM_UART_CMPR_OFFSET) +# define SAM_UART2_RTOR (SAM_UART2_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_UART2_WPMR (SAM_UART2_VBASE+SAM_UART_WPMR_OFFSET) + +# define SAM_UART3_CR (SAM_UART3_VBASE+SAM_UART_CR_OFFSET) +# define SAM_UART3_MR (SAM_UART3_VBASE+SAM_UART_MR_OFFSET) +# define SAM_UART3_IER (SAM_UART3_VBASE+SAM_UART_IER_OFFSET) +# define SAM_UART3_IDR (SAM_UART3_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_UART3_IMR (SAM_UART3_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_UART3_SR (SAM_UART3_VBASE+SAM_UART_SR_OFFSET) +# define SAM_UART3_RHR (SAM_UART3_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_UART3_THR (SAM_UART3_VBASE+SAM_UART_THR_OFFSET) +# define SAM_UART3_BRGR (SAM_UART3_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART3_CMPR (SAM_UART3_VBASE+SAM_UART_CMPR_OFFSET) +# define SAM_UART3_RTOR (SAM_UART3_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_UART3_WPMR (SAM_UART3_VBASE+SAM_UART_WPMR_OFFSET) + +# define SAM_UART4_CR (SAM_UART4_VBASE+SAM_UART_CR_OFFSET) +# define SAM_UART4_MR (SAM_UART4_VBASE+SAM_UART_MR_OFFSET) +# define SAM_UART4_IER (SAM_UART4_VBASE+SAM_UART_IER_OFFSET) +# define SAM_UART4_IDR (SAM_UART4_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_UART4_IMR (SAM_UART4_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_UART4_SR (SAM_UART4_VBASE+SAM_UART_SR_OFFSET) +# define SAM_UART4_RHR (SAM_UART4_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_UART4_THR (SAM_UART4_VBASE+SAM_UART_THR_OFFSET) +# define SAM_UART4_BRGR (SAM_UART4_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART4_CMPR (SAM_UART4_VBASE+SAM_UART_CMPR_OFFSET) +# define SAM_UART4_RTOR (SAM_UART4_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_UART4_WPMR (SAM_UART4_VBASE+SAM_UART_WPMR_OFFSET) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define SAM_USART_CR(n) (SAM_USARTN_VBASE(n)+SAM_UART_CR_OFFSET) +# define SAM_USART_MR(n) (SAM_USARTN_VBASE(n)+SAM_UART_MR_OFFSET) +# define SAM_USART_IER(n) (SAM_USARTN_VBASE(n)+SAM_UART_IER_OFFSET) +# define SAM_USART_IDR(n) (SAM_USARTN_VBASE(n)+SAM_UART_IDR_OFFSET) +# define SAM_USART_IMR(n) (SAM_USARTN_VBASE(n)+SAM_UART_IMR_OFFSET) +# define SAM_USART_SR(n) (SAM_USARTN_VBASE(n)+SAM_UART_SR_OFFSET) +# define SAM_USART_RHR(n) (SAM_USARTN_VBASE(n)+SAM_UART_RHR_OFFSET) +# define SAM_USART_THR(n) (SAM_USARTN_VBASE(n)+SAM_UART_THR_OFFSET) +# define SAM_USART_BRGR(n) (SAM_USARTN_VBASE(n)+SAM_UART_BRGR_OFFSET) +# define SAM_USART_RTOR(n) (SAM_USARTN_VBASE(n)+SAM_UART_RTOR_OFFSET) +# define SAM_USART_TTGR(n) (SAM_USARTN_VBASE(n)+SAM_UART_TTGR_OFFSET) +# define SAM_USART_FIDI(n) (SAM_USARTN_VBASE(n)+SAM_UART_FIDI_OFFSET) +# define SAM_USART_NER(n) (SAM_USARTN_VBASE(n)+SAM_UART_NER_OFFSET) +# define SAM_USART_IFR(n) (SAM_USARTN_VBASE(n)+SAM_UART_IFR_OFFSET) +# define SAM_USART_MAN(n) (SAM_USARTN_VBASE(n)+SAM_UART_MAN_OFFSET) +# define SAM_USART_WPMR(n) (SAM_USARTN_VBASE(n)+SAM_UART_WPMR_OFFSET) +# define SAM_USART_WPSR(n) (SAM_USARTN_VBASE(n)+SAM_UART_WPSR_OFFSET) + +# define SAM_USART0_CR (SAM_USART0_VBASE+SAM_UART_CR_OFFSET) +# define SAM_USART0_MR (SAM_USART0_VBASE+SAM_UART_MR_OFFSET) +# define SAM_USART0_IER (SAM_USART0_VBASE+SAM_UART_IER_OFFSET) +# define SAM_USART0_IDR (SAM_USART0_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_USART0_IMR (SAM_USART0_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_USART0_SR (SAM_USART0_VBASE+SAM_UART_SR_OFFSET) +# define SAM_USART0_RHR (SAM_USART0_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_USART0_THR (SAM_USART0_VBASE+SAM_UART_THR_OFFSET) +# define SAM_USART0_BRGR (SAM_USART0_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART0_RTOR (SAM_USART0_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART0_TTGR (SAM_USART0_VBASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART0_FIDI (SAM_USART0_VBASE+SAM_UART_FIDI_OFFSET) +# define SAM_USART0_NER (SAM_USART0_VBASE+SAM_UART_NER_OFFSET) +# define SAM_USART0_IFR (SAM_USART0_VBASE+SAM_UART_IFR_OFFSET) +# define SAM_USART0_MAN (SAM_USART0_VBASE+SAM_UART_MAN_OFFSET) +# define SAM_USART0_WPMR (SAM_USART0_VBASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART0_WPSR (SAM_USART0_VBASE+SAM_UART_WPSR_OFFSET) + +# define SAM_USART1_CR (SAM_USART1_VBASE+SAM_UART_CR_OFFSET) +# define SAM_USART1_MR (SAM_USART1_VBASE+SAM_UART_MR_OFFSET) +# define SAM_USART1_IER (SAM_USART1_VBASE+SAM_UART_IER_OFFSET) +# define SAM_USART1_IDR (SAM_USART1_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_USART1_IMR (SAM_USART1_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_USART1_SR (SAM_USART1_VBASE+SAM_UART_SR_OFFSET) +# define SAM_USART1_RHR (SAM_USART1_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_USART1_THR (SAM_USART1_VBASE+SAM_UART_THR_OFFSET) +# define SAM_USART1_BRGR (SAM_USART1_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART1_RTOR (SAM_USART1_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART1_TTGR (SAM_USART1_VBASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART1_FIDI (SAM_USART1_VBASE+SAM_UART_FIDI_OFFSET) +# define SAM_USART1_NER (SAM_USART1_VBASE+SAM_UART_NER_OFFSET) +# define SAM_USART1_IFR (SAM_USART1_VBASE+SAM_UART_IFR_OFFSET) +# define SAM_USART1_MAN (SAM_USART1_VBASE+SAM_UART_MAN_OFFSET) +# define SAM_USART1_WPMR (SAM_USART1_VBASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART1_WPSR (SAM_USART1_VBASE+SAM_UART_WPSR_OFFSET) + +# define SAM_USART2_CR (SAM_USART2_VBASE+SAM_UART_CR_OFFSET) +# define SAM_USART2_MR (SAM_USART2_VBASE+SAM_UART_MR_OFFSET) +# define SAM_USART2_IER (SAM_USART2_VBASE+SAM_UART_IER_OFFSET) +# define SAM_USART2_IDR (SAM_USART2_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_USART2_IMR (SAM_USART2_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_USART2_SR (SAM_USART2_VBASE+SAM_UART_SR_OFFSET) +# define SAM_USART2_RHR (SAM_USART2_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_USART2_THR (SAM_USART2_VBASE+SAM_UART_THR_OFFSET) +# define SAM_USART2_BRGR (SAM_USART2_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART2_RTOR (SAM_USART2_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART2_TTGR (SAM_USART2_VBASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART2_FIDI (SAM_USART2_VBASE+SAM_UART_FIDI_OFFSET) +# define SAM_USART2_NER (SAM_USART2_VBASE+SAM_UART_NER_OFFSET) +# define SAM_USART2_IFR (SAM_USART2_VBASE+SAM_UART_IFR_OFFSET) +# define SAM_USART2_MAN (SAM_USART2_VBASE+SAM_UART_MAN_OFFSET) +# define SAM_USART2_WPMR (SAM_USART2_VBASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART2_WPSR (SAM_USART2_VBASE+SAM_UART_WPSR_OFFSET) + +# define SAM_USART3_CR (SAM_USART3_VBASE+SAM_UART_CR_OFFSET) +# define SAM_USART3_MR (SAM_USART3_VBASE+SAM_UART_MR_OFFSET) +# define SAM_USART3_IER (SAM_USART3_VBASE+SAM_UART_IER_OFFSET) +# define SAM_USART3_IDR (SAM_USART3_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_USART3_IMR (SAM_USART3_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_USART3_SR (SAM_USART3_VBASE+SAM_UART_SR_OFFSET) +# define SAM_USART3_RHR (SAM_USART3_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_USART3_THR (SAM_USART3_VBASE+SAM_UART_THR_OFFSET) +# define SAM_USART3_BRGR (SAM_USART3_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART3_RTOR (SAM_USART3_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART3_TTGR (SAM_USART3_VBASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART3_FIDI (SAM_USART3_VBASE+SAM_UART_FIDI_OFFSET) +# define SAM_USART3_NER (SAM_USART3_VBASE+SAM_UART_NER_OFFSET) +# define SAM_USART3_IFR (SAM_USART3_VBASE+SAM_UART_IFR_OFFSET) +# define SAM_USART3_MAN (SAM_USART3_VBASE+SAM_UART_MAN_OFFSET) +# define SAM_USART3_WPMR (SAM_USART3_VBASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART3_WPSR (SAM_USART3_VBASE+SAM_UART_WPSR_OFFSET) + +# ifdef CONFIG_SAMA5_HAVE_USART4 +# define SAM_USART4_CR (SAM_USART4_VBASE+SAM_UART_CR_OFFSET) +# define SAM_USART4_MR (SAM_USART4_VBASE+SAM_UART_MR_OFFSET) +# define SAM_USART4_IER (SAM_USART4_VBASE+SAM_UART_IER_OFFSET) +# define SAM_USART4_IDR (SAM_USART4_VBASE+SAM_UART_IDR_OFFSET) +# define SAM_USART4_IMR (SAM_USART4_VBASE+SAM_UART_IMR_OFFSET) +# define SAM_USART4_SR (SAM_USART4_VBASE+SAM_UART_SR_OFFSET) +# define SAM_USART4_RHR (SAM_USART4_VBASE+SAM_UART_RHR_OFFSET) +# define SAM_USART4_THR (SAM_USART4_VBASE+SAM_UART_THR_OFFSET) +# define SAM_USART4_BRGR (SAM_USART4_VBASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART4_RTOR (SAM_USART4_VBASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART4_TTGR (SAM_USART4_VBASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART4_FIDI (SAM_USART4_VBASE+SAM_UART_FIDI_OFFSET) +# define SAM_USART4_NER (SAM_USART4_VBASE+SAM_UART_NER_OFFSET) +# define SAM_USART4_IFR (SAM_USART4_VBASE+SAM_UART_IFR_OFFSET) +# define SAM_USART4_MAN (SAM_USART4_VBASE+SAM_UART_MAN_OFFSET) +# define SAM_USART4_WPMR (SAM_USART4_VBASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART4_WPSR (SAM_USART4_VBASE+SAM_UART_WPSR_OFFSET) +# endif +#endif + +/* UART register bit definitions ****************************************************************/ + +/* UART Control Register */ + +#define UART_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver (Common) */ +#define UART_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter (Common) */ +#define UART_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable (Common) */ +#define UART_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable (Common) */ +#define UART_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable (Common) */ +#define UART_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable (Common) */ +#define UART_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits (Common) */ + +#if defined(ATSAMA5D2) +# define UART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out (USART UART mode only) */ +# define UART_REQCLR_STTBRK (1 << 12) /* Bit 12: Request Clear */ +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_CR_STTBRK (1 << 9) /* Bit 9: Start Break (USART UART mode only) */ +# define UART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break (USART UART mode only) */ +# define UART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out (USART UART mode only) */ +# define UART_CR_SENDA (1 << 12) /* Bit 12: Send Address (USART UART mode only) */ +# define UART_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations (USART UART mode only) */ +# define UART_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge (USART UART mode only) */ +# define UART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out (USART UART mode only) */ +# define UART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable (USART UART mode only) */ +# define UART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select (USART SPI mode only) */ +# define UART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable (USART UART mode only) */ +# define UART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select (USART SPI mode only) */ +#endif + +/* UART Mode Register and USART Mode Register (UART MODE) + * + * NOTES: + * (1) Common to UART and USART (all modes) + * (2) Common to UART and USART (UART mode only) + * (3) USART only (all modes) + * (4) USART only (UART mode only) + * (5) USART only (SPI mode only) + */ + +#if defined(ATSAMA5D2) +# define UART_MR_FILTER (1 << 4) /* Bit 4: Receiver Digital Filter */ +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_MR_MODE_SHIFT (0) /* Bits 0-3: (3) */ +# define UART_MR_MODE_MASK (15 << UART_MR_MODE_SHIFT) +# define UART_MR_MODE_NORMAL (0 << UART_MR_MODE_SHIFT) /* Normal */ +# define UART_MR_MODE_RS485 (1 << UART_MR_MODE_SHIFT) /* RS485 */ +# define UART_MR_MODE_HWHS (2 << UART_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define UART_MR_MODE_ISO7816_0 (4 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */ +# define UART_MR_MODE_ISO7816_1 (6 << UART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */ +# define UART_MR_MODE_IRDA (8 << UART_MR_MODE_SHIFT) /* IrDA */ +# define UART_MR_MODE_SPIMSTR (14 << UART_MR_MODE_SHIFT) /* SPI Master (SPI mode only) */ +# define UART_MR_MODE_SPISLV (15 << UART_MR_MODE_SHIFT) /* SPI Slave (SPI mode only) */ +# define UART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection (3) */ +# define UART_MR_USCLKS_MASK (3 << UART_MR_USCLKS_SHIFT) +# define UART_MR_USCLKS_MCK (0 << UART_MR_USCLKS_SHIFT) /* MCK */ +# define UART_MR_USCLKS_MCKDIV (1 << UART_MR_USCLKS_SHIFT) /* MCK/DIV (DIV = 8) */ +# define UART_MR_USCLKS_SCK (3 << UART_MR_USCLKS_SHIFT) /* SCK */ +# define UART_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length (3) */ +# define UART_MR_CHRL_MASK (3 << UART_MR_CHRL_SHIFT) +# define UART_MR_CHRL_5BITS (0 << UART_MR_CHRL_SHIFT) /* 5 bits */ +# define UART_MR_CHRL_6BITS (1 << UART_MR_CHRL_SHIFT) /* 6 bits */ +# define UART_MR_CHRL_7BITS (2 << UART_MR_CHRL_SHIFT) /* 7 bits */ +# define UART_MR_CHRL_8BITS (3 << UART_MR_CHRL_SHIFT) /* 8 bits */ +# define UART_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select (4) */ +# define UART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase (5) */ +#endif + +#define UART_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type (2) */ +#define UART_MR_PAR_MASK (7 << UART_MR_PAR_SHIFT) +# define UART_MR_PAR_EVEN (0 << UART_MR_PAR_SHIFT) /* Even parity (1) */ +# define UART_MR_PAR_ODD (1 << UART_MR_PAR_SHIFT) /* Odd parity (1) */ +# define UART_MR_PAR_SPACE (2 << UART_MR_PAR_SHIFT) /* Space: parity forced to 0 (1) */ +# define UART_MR_PAR_MARK (3 << UART_MR_PAR_SHIFT) /* Mark: parity forced to 1 (1) */ +# define UART_MR_PAR_NONE (4 << UART_MR_PAR_SHIFT) /* No parity (1) */ +# if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_MR_PAR_MULTIDROP (6 << UART_MR_PAR_SHIFT) /* Multidrop mode (2) */ +# endif + +#if defined(ATSAMA5D2) || defined(ATSAMA5D4) +# define UART_MR_BRSRCCK (1 << 12) /* Bit 12: Baud Rate Source Clock (UART only) */ +# define UART_MR_PERIPHCLK (0) /* Bit 12: 0=Peripheral clock */ +# define UART_MR_PMCPCK (1 << 12) /* Bit 12: 1=PMC programmable clock */ +#endif + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) +# define UART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits (2) */ +# define UART_MR_NBSTOP_MASK (3 << UART_MR_NBSTOP_SHIFT) +# define UART_MR_NBSTOP_1 (0 << UART_MR_NBSTOP_SHIFT) /* 1 stop bit 1 stop bit */ +# define UART_MR_NBSTOP_1p5 (1 << UART_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define UART_MR_NBSTOP_2 (2 << UART_MR_NBSTOP_SHIFT) /* 2 stop bits 2 stop bits */ +#endif + +#define UART_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode (2) */ +#define UART_MR_CHMODE_MASK (3 << UART_MR_CHMODE_SHIFT) +# define UART_MR_CHMODE_NORMAL (0 << UART_MR_CHMODE_SHIFT) /* Normal Mode */ +# define UART_MR_CHMODE_ECHO (1 << UART_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define UART_MR_CHMODE_LLPBK (2 << UART_MR_CHMODE_SHIFT) /* Local Loopback */ +# define UART_MR_CHMODE_RLPBK (3 << UART_MR_CHMODE_SHIFT) /* Remote Loopback */ + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_MR_MSBF (1 << 16) /* Bit 16: Most Significant Bit first (2) */ +# define UART_MR_CPOL (1 << 16) /* Bit 16: SPI Clock Polarity (5) */ +# define UART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length (4) */ +# define UART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select (4) */ +# define UART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode (4) */ +# define UART_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge (4) */ +# define UART_MR_WRDBT (1 << 20) /* Bit 20: Wait Read Data Before Transfer (5) */ +# define UART_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK (4) */ +# define UART_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter (4) */ +# define UART_MR_INVDATA (1 << 23) /* Bit 23: Inverted Data (4) */ +# define UART_MR_MAXITER_SHIFT (24) /* Bits 24-26: Max iterations (ISO7816 T=0 (4) */ +# define UART_MR_MAXITER_MASK (7 << UART_MR_MAXITER_SHIFT) +# define UART_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter (4) */ +# define UART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable () */ +# define UART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode (4) */ +# define UART_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector (4) */ +#endif + +/* UART Interrupt Enable Register, UART Interrupt Disable Register, UART Interrupt Mask + * Register, and UART Status Register common bit field definitions + * + * NOTES: + * (1) Common to UART and USART (all modes) + * (2) Common to UART and USART (UART mode only) + * (3) USART only (all modes) + * (4) USART only (UART mode only) + * (5) USART only (SPI mode only) + */ + +#define UART_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt (1) */ +#define UART_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt (1) */ + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_INT_RXBRK (1 << 2) /* Bit 2: Break Received/End of Break (2) */ +#endif + +#define UART_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt (2) */ +#define UART_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt (2) */ +#define UART_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt (2) */ +#define UART_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt (4) */ +#define UART_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt (1) */ + +#if defined(ATSAMA5D2) +# define UART_INT_CMP (1 << 15) /* Bit 15: Comparison Interrupt */ + +# define UART_INT_ALLINTS 0x000083e3 +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_INT_ITER (1 << 10) /* Bit 10: Iteration Interrupt (4) */ +# define UART_INT_UNRE (1 << 10) /* Bit 10: SPI Underrun Error Interrupt (5) */ +# define UART_INT_NACK (1 << 13) /* Bit 13: Non Acknowledge Interrupt (4) */ +# define UART_INT_CTSIC (1 << 19) /* Bit 19: Clear to Send Input Change Interrupt (4) */ +# define UART_SR_CTS (1 << 23) /* Bit 23: Image of CTS Input (SR only) */ +# define UART_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt (4) */ + +# define UART_INT_ALLINTS 0x018827e7 +#endif + +/* UART Receiver Holding Register */ + +#if defined(ATSAMA5D2) +# define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character (UART only) */ +# define UART_RHR_RXCHR_MASK (0xff << UART_RHR_RXCHR_SHIFT) +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character (USART only) */ +# define UART_RHR_RXCHR_MASK (0x1ff << UART_RHR_RXCHR_SHIFT) +# define UART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync (USART only) */ +#endif + +/* UART Transmit Holding Register */ + +#if defined(ATSAMA5D2) +# define UART_THR_TXCHR_SHIFT (0) /* Bits 0-7: Character to be Transmitted (UART only) */ +# define UART_THR_TXCHR_MASK (0xff << UART_THR_TXCHR_SHIFT) +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted (USART only) */ +# define UART_THR_TXCHR_MASK (0x1ff << UART_THR_TXCHR_SHIFT) +# define UART_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be tran (USART only) */ +#endif + +/* UART Baud Rate Generator Register */ + +#define UART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor (Common) */ +#define UART_BRGR_CD_MASK (0xffff << UART_BRGR_CD_SHIFT) + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part (USART only) */ +# define UART_BRGR_FP_MASK (7 << UART_BRGR_FP_SHIFT) +#endif + +#if defined(ATSAMA5D2) +/* Comparison Register */ + +# define UART_CMPR_VAL1_SHIFT (0) /* Bits 0-7: First Comparison Value for Received Character */ +# define UART_CMPR_VAL1_MASK (0xff << UART_CMPR_VAL1_SHIFT) +# define UART_CMPR_VAL1(n) ((uint32_t)(n) << UART_CMPR_VAL1_SHIFT) +# define UART_CMPR_CMPMODE (1 << 12) /* Bit 12: Comparison Mode */ +# define UART_CMPR_FLAG (0) /* Bit 12: 0=Any character + comparison function */ +# define UART_CMPR_START (1 << 12) /* Bit 12: 1=Comparison condition required to start */ +# define UART_CMPR_CMPPAR (1 << 14) /* Bit 14: Compare Parity */ +# define UART_CMPR_VAL2_SHIFT (16) /* Bits 16-23: Second Comparison Value for Received Character */ +# define UART_CMPR_VAL2_MASK (0xff << UART_CMPR_VAL2_SHIFT) +# define UART_CMPR_VAL2(n) ((uint32_t)(n) << UART_CMPR_VAL2_SHIFT) +#endif + +/* USART Receiver Time-out Register (USART only) */ + +#if defined(ATSAMA5D2) +# define UART_RTOR_TO_SHIFT (0) /* Bits 0-7: Time-out Value */ +# define UART_RTOR_TO_MASK (0xff << UART_RTOR_TO_SHIFT) +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define UART_RTOR_TO_SHIFT (0) /* Bits 0-15: Time-out Value (USART only) */ +# define UART_RTOR_TO_MASK (0xffff << UART_RTOR_TO_SHIFT) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART Transmitter Timeguard Register (USART only) */ + +# define UART_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value (USART only) */ +# define UART_TTGR_TG_MASK (0xff << UART_TTGR_TG_SHIFT) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART FI DI RATIO Register (USART only) */ + +# define UART_FIDI_RATIO_SHIFT (0) /* Bits 0-15: FI Over DI Ratio Value (USART only) */ +# define UART_FIDI_RATIO_MASK (0xffff << UART_FIDI_RATIO_SHIFT) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART Number of Errors Register (USART only) */ + +# define UART_NER_NBERRORS_SHIFT (0) /* Bits 0-7: Number of Errrors (USART only) */ +# define UART_NER_NBERRORS_MASK (0xff << UART_NER_NBERRORS_SHIFT) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART IrDA FILTER Register (USART only) */ + +# define UART_IFR_IRDAFILTER_SHIFT (0) /* Bits 0-7: IrDA Filter (USART only) */ +# define UART_IFR_IRDAFILTER_MASK (0xff << UART_IFR_IRDAFILTER_SHIFT) +#endif + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART Manchester Configuration Register (USART only) */ + +# define UART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length (USART only) */ +# define UART_MAN_TXPL_MASK (15 << UART_MAN_TXPL_SHIFT) +# define UART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern (USART only) */ +# define UART_MAN_TXPP_MASK (3 << UART_MAN_TXPP_SHIFT) +# define UART_MAN_TXPP_ALLONE (0 << UART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_TXPP_ALLZERO (1 << UART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_TXPP_ZEROONE (2 << UART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_TXPP_ONEZERO (3 << UART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +# define UART_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity (USART only) */ +# define UART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length (USART only) */ +# define UART_MAN_RXPL_MASK (15 << UART_MAN_RXPL_SHIFT) +# define UART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected (USART only) */ +# define UART_MAN_RXPP_MASK (3 << UART_MAN_RXPP_SHIFT) +# define UART_MAN_RXPP_ALLONE (0 << UART_MAN_RXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_RXPP_ALLZERO (1 << UART_MAN_RXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_RXPP_ZEROONE (2 << UART_MAN_RXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_RXPP_ONEZERO (3 << UART_MAN_RXPP_SHIFT) /* ONE_ZERO */ +# define UART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity (USART only) */ +# define UART_MAN_ONE (1 << 29) /* Bit 29: Must Be Set to 1 */ +# define UART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation (USART only) */ +# endif + +/* USART Write Protect Mode Register (USART only) */ + +#define UART_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable (USART only) */ +#define UART_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (USART only) */ +#define UART_WPMR_WPKEY_MASK (0x00ffffff << UART_WPMR_WPKEY_SHIFT) +# define USART_WPMR_WPKEY (0x00555341 << UART_WPMR_WPKEY_SHIFT) /* "USA" */ +# define UART_WPMR_WPKEY (0x00554152 << UART_WPMR_WPKEY_SHIFT) /* "UAR" */ + +#if defined(ATSAMA5D3) ||defined(ATSAMA5D4) +/* USART Write Protect Status Register (USART only) */ + +# define UART_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status (USART only) */ +# define UART_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source (USART only) */ +# define UART_WPSR_WPVSRC_MASK (0xffff << UART_WPSR_WPVSRC_SHIFT) +#endif + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UART_H */ diff --git a/arch/arm/src/sama5/chip/sam_udphs.h b/arch/arm/src/sama5/chip/sam_udphs.h new file mode 100644 index 0000000000000000000000000000000000000000..5b5becbfa4a06a49ef0f929f6c06ccfc14013d67 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_udphs.h @@ -0,0 +1,481 @@ +/******************************************************************************************** + * arch/arm/src/sama5/chip/sam_udphs.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UDPHS_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UDPHS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* General Definitions **********************************************************************/ +/* Number of endpoints and DMA channels */ + +#define SAM_UDPHS_NENDPOINTS 16 /* EP0-15 */ +#define SAM_UDPHS_NDMACHANNELS 7 /* For EP1-7 */ + +/* Capabilities and characteristics of endpoints */ + +#define SAM_UDPHS_MAXPACKETSIZE(ep) \ + (((unsigned)(ep) < 1) ? 64 : 1024) +#define SAM_UDPHS_NBANKS(ep) \ + (((unsigned)(ep) < 1) ? 1 : (((unsigned)(ep) < 3) ? 3 : 2)) +#define SAM_UDPHS_DMA(ep) \ + (((unsigned)(ep) < 1) ? false : (((unsigned)(ep) < 8) ? true : false)) + +/* Register offsets *************************************************************************/ + +/* Global Registers */ + +#define SAM_UDPHS_CTRL_OFFSET 0x0000 /* UDPHS Control Register */ +#define SAM_UDPHS_FNUM_OFFSET 0x0004 /* UDPHS Frame Number Register */ + /* 0x0008-0x000c Reserved */ +#define SAM_UDPHS_IEN_OFFSET 0x0010 /* UDPHS Interrupt Enable Register */ +#define SAM_UDPHS_INTSTA_OFFSET 0x0014 /* UDPHS Interrupt Status Register */ +#define SAM_UDPHS_CLRINT_OFFSET 0x0018 /* UDPHS Clear Interrupt Register */ +#define SAM_UDPHS_EPTRST_OFFSET 0x001c /* UDPHS Endpoints Reset Register */ + /* 0x0020-0x00cc Reserved */ +#define SAM_UDPHS_TST_OFFSET 0x00e0 /* UDPHS Test Register */ + /* 0x00e4-0x00e8 Reserved */ +/* Endpoint Offsets */ + +#define SAM_UDPHS_EP_OFFSET(ep) (0x0100+((unsigned int)(ep)<<5)) +#define SAM_UDPHS_EP0_OFFSET 0x0100 +#define SAM_UDPHS_EP1_OFFSET 0x0120 +#define SAM_UDPHS_EP2_OFFSET 0x0140 +#define SAM_UDPHS_EP3_OFFSET 0x0160 +#define SAM_UDPHS_EP4_OFFSET 0x0180 +#define SAM_UDPHS_EP5_OFFSET 0x01a0 +#define SAM_UDPHS_EP6_OFFSET 0x01c0 +#define SAM_UDPHS_EP7_OFFSET 0x01e0 +#define SAM_UDPHS_EP8_OFFSET 0x0200 +#define SAM_UDPHS_EP9_OFFSET 0x0220 +#define SAM_UDPHS_EP10_OFFSET 0x0240 +#define SAM_UDPHS_EP11_OFFSET 0x0260 +#define SAM_UDPHS_EP12_OFFSET 0x0280 +#define SAM_UDPHS_EP13_OFFSET 0x02a0 +#define SAM_UDPHS_EP14_OFFSET 0x02c0 +#define SAM_UDPHS_EP15_OFFSET 0x02e0 + +/* Endpoint registers */ + +#define SAM_UDPHS_EPTCFG_OFFSET 0x0000 /* UDPHS Endpoint Configuration Register */ +#define SAM_UDPHS_EPTCTLENB_OFFSET 0x0004 /* UDPHS Endpoint Control Enable Register */ +#define SAM_UDPHS_EPTCTLDIS_OFFSET 0x0008 /* UDPHS Endpoint Control Disable Register */ +#define SAM_UDPHS_EPTCTL_OFFSET 0x000c /* UDPHS Endpoint Control Register */ + /* 0x0010 Reserved */ +#define SAM_UDPHS_EPTSETSTA_OFFSET 0x0014 /* UDPHS Endpoint Set Status Register */ +#define SAM_UDPHS_EPTCLRSTA_OFFSET 0x0018 /* UDPHS Endpoint Clear Status Register */ +#define SAM_UDPHS_EPTSTA_OFFSET 0x001c /* UDPHS Endpoint Status Register */ + +/* DMA Channel Offsets */ + +#define SAM_UDPHS_CH_OFFSET(ch) (0x0300+((unsigned int)(ch)<<4)) +#define SAM_UDPHS_CH0_OFFSET 0x0300 +#define SAM_UDPHS_CH1_OFFSET 0x0310 +#define SAM_UDPHS_CH2_OFFSET 0x0320 +#define SAM_UDPHS_CH3_OFFSET 0x0330 +#define SAM_UDPHS_CH4_OFFSET 0x0340 +#define SAM_UDPHS_CH5_OFFSET 0x0350 +#define SAM_UDPHS_CH6_OFFSET 0x0360 + +/* DMA Channel Registers */ + +#define SAM_UDPHS_DMANXTDSC_OFFSET 0x0000 /* UDPHS DMA Next Descriptor Address Register */ +#define SAM_UDPHS_DMAADDRESS_OFFSET 0x0004 /* UDPHS DMA Channel Address Register */ +#define SAM_UDPHS_DMACONTROL_OFFSET 0x0008 /* UDPHS DMA Channel Control Register */ +#define SAM_UDPHS_DMASTATUS_OFFSET 0x000c /* UDPHS DMA Channel Status Register */ + +/* Register addresses ***********************************************************************/ + +/* Global Registers */ + +#define SAM_UDPHS_CTRL (SAM_UDPHS_VBASE+SAM_UDPHS_CTRL_OFFSET) +#define SAM_UDPHS_FNUM (SAM_UDPHS_VBASE+SAM_UDPHS_FNUM_OFFSET) +#define SAM_UDPHS_IEN (SAM_UDPHS_VBASE+SAM_UDPHS_IEN_OFFSET) +#define SAM_UDPHS_INTSTA (SAM_UDPHS_VBASE+SAM_UDPHS_INTSTA_OFFSET) +#define SAM_UDPHS_CLRINT (SAM_UDPHS_VBASE+SAM_UDPHS_CLRINT_OFFSET) +#define SAM_UDPHS_EPTRST (SAM_UDPHS_VBASE+SAM_UDPHS_EPTRST_OFFSET) +#define SAM_UDPHS_TST (SAM_UDPHS_VBASE+SAM_UDPHS_TST_OFFSET) + +/* Endpoint Base Addresses */ + +#define SAM_UDPHS_EP_BASE(ep) (SAM_UDPHS_VBASE+SAM_UDPHS_EP_OFFSET(ep)) +#define SAM_UDPHS_EP0_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP0_OFFSET) +#define SAM_UDPHS_EP1_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP1_OFFSET) +#define SAM_UDPHS_EP2_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP2_OFFSET) +#define SAM_UDPHS_EP3_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP3_OFFSET) +#define SAM_UDPHS_EP4_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP4_OFFSET) +#define SAM_UDPHS_EP5_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP5_OFFSET) +#define SAM_UDPHS_EP6_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP6_OFFSET) +#define SAM_UDPHS_EP7_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP7_OFFSET) +#define SAM_UDPHS_EP8_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP8_OFFSET) +#define SAM_UDPHS_EP9_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP9_OFFSET) +#define SAM_UDPHS_EP10_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP10_OFFSET) +#define SAM_UDPHS_EP11_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP11_OFFSET) +#define SAM_UDPHS_EP12_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP12_OFFSET) +#define SAM_UDPHS_EP13_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP13_OFFSET) +#define SAM_UDPHS_EP14_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP14_OFFSET) +#define SAM_UDPHS_EP15_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_EP15_OFFSET) + +/* Endpoint registers */ + +#define SAM_UDPHS_EPTCFG(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTCFG_OFFSET) +#define SAM_UDPHS_EPTCTLENB(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTCTLENB_OFFSET) +#define SAM_UDPHS_EPTCTLDIS(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTCTLDIS_OFFSET) +#define SAM_UDPHS_EPTCTL(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTCTL_OFFSET) +#define SAM_UDPHS_EPTSETSTA(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTSETSTA_OFFSET) +#define SAM_UDPHS_EPTCLRSTA(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTCLRSTA_OFFSET) +#define SAM_UDPHS_EPTSTA(ep) (SAM_UDPHS_EP_BASE(ep)+SAM_UDPHS_EPTSTA_OFFSET) + +/* DMA Channel Base Addresses */ + +#define SAM_UDPHS_CH_BASE(ch) (SAM_UDPHS_VBASE+SAM_UDPHS_CH_OFFSET(ch)) +#define SAM_UDPHS_CH1_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH1_OFFSET) +#define SAM_UDPHS_CH2_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH2_OFFSET) +#define SAM_UDPHS_CH3_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH3_OFFSET) +#define SAM_UDPHS_CH4_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH4_OFFSET) +#define SAM_UDPHS_CH5_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH5_OFFSET) +#define SAM_UDPHS_CH6_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH6_OFFSET) +#define SAM_UDPHS_CH7_BASE (SAM_UDPHS_VBASE+SAM_UDPHS_CH7_OFFSET) + +/* DMA Channel Registers */ + +#define SAM_UDPHS_DMANXTDSC(ch) (SAM_UDPHS_CH_BASE(ch)+SAM_UDPHS_DMANXTDSC_OFFSET) +#define SAM_UDPHS_DMAADDRESS(ch) (SAM_UDPHS_CH_BASE(ch)+SAM_UDPHS_DMAADDRESS_OFFSET) +#define SAM_UDPHS_DMACONTROL(ch) (SAM_UDPHS_CH_BASE(ch)+SAM_UDPHS_DMACONTROL_OFFSET) +#define SAM_UDPHS_DMASTATUS(ch) (SAM_UDPHS_CH_BASE(ch)+SAM_UDPHS_DMASTATUS_OFFSET) + +/* Register bit-field definitions ***********************************************************/ + +/* Global Registers */ + +/* UDPHS Control Register */ + +#define UDPHS_CTRL_DEVADDR_SHIFT (0) /* Bits 0-6: UDPHS Address */ +#define UDPHS_CTRL_DEVADDR_MASK (0x7f << UDPHS_CTRL_DEVADDR_SHIFT) +# define UDPHS_CTRL_DEVADDR(addr) ((addr) << UDPHS_CTRL_DEVADDR_SHIFT) +#define UDPHS_CTRL_FADDREN (1 << 7) /* Bit 7: Function Address Enable */ +#define UDPHS_CTRL_ENUDPHS (1 << 8) /* Bit 8: UDPHS Enable */ +#define UDPHS_CTRL_DETACH (1 << 9) /* Bit 9: Detach Command */ +#define UDPHS_CTRL_REWAKEUP (1 << 10) /* Bit 10: Send Remote Wake Up */ +#define UDPHS_CTRL_PULLDDIS (1 << 11) /* Bit 11: Pull-Down Disable */ + +/* UDPHS Frame Number Register */ + +#define UDPHS_FNUM_UFRAMENUM_SHIFT (0) /* Bits 0-2: Microframe Number */ +#define UDPHS_FNUM_UFRAMENUM_MASK (7 << UDPHS_FNUM_UFRAMENUM_SHIFT) +#define UDPHS_FNUM_FRAMENUM_SHIFT (3) /* Bits 3-13: Frame Number */ +#define UDPHS_FNUM_FRAMENUM_MASK (0x7ff << UDPHS_FNUM_FRAMENUM_SHIFT) +#define UDPHS_FNUM_FNUMERR (1 << 31) /* Bit 31: Frame Number CRC Error */ + +/* Common interrupt bits */ +/* UDPHS Interrupt Status Register (only) */ + +#define UDPHS_INTSTA_SPEED (1 << 0) /* Bit 0: Speed Status */ + +/* UDPHS Interrupt Enable Register, UDPHS Interrupt Status Register, and UDPHS Clear + * Interrupt Register + */ + +#define UDPHS_INT_DETSUSPD (1 << 1) /* Bit 1: Suspend Interrupt */ +#define UDPHS_INT_MICROSOF (1 << 2) /* Bit 2: Micro Start Of Frame Interrupt */ +#define UDPHS_INT_INTSOF (1 << 3) /* Bit 3: Start Of Frame Interrupt */ +#define UDPHS_INT_ENDRESET (1 << 4) /* Bit 4: End Of Reset Interrupt */ +#define UDPHS_INT_WAKEUP (1 << 5) /* Bit 5: Wake Up CPU Interrupt */ +#define UDPHS_INT_ENDOFRSM (1 << 6) /* Bit 6: End Of Resume Interrupt */ +#define UDPHS_INT_UPSTRRES (1 << 7) /* Bit 7: Upstream Resume Interrupt */ + +/* UDPHS Interrupt Enable Register and UDPHS Interrupt Status Register */ + +#define UDPHS_INT_EPT_SHIFT (8) /* Bits 8-23: Endpoint interrupts */ +#define UDPHS_INT_EPT_MASK (0xffff << UDPHS_INT_EPT_SHIFT) +#define UDPHS_INT_EPT(ep) (1 << +((ep)+8)) /* Endpoint ep Interrupt */ +# define UDPHS_INT_EPT0 (1 << 8) /* Bit 8: Endpoint 0 Interrupt */ +# define UDPHS_INT_EPT1 (1 << 9) /* Bit 9: Endpoint 1 Interrupt */ +# define UDPHS_INT_EPT2 (1 << 10) /* Bit 10: Endpoint 2 Interrupt */ +# define UDPHS_INT_EPT3 (1 << 11) /* Bit 11: Endpoint 3 Interrupt */ +# define UDPHS_INT_EPT4 (1 << 12) /* Bit 12: Endpoint 4 Interrupt */ +# define UDPHS_INT_EPT5 (1 << 13) /* Bit 13: Endpoint 5 Interrupt */ +# define UDPHS_INT_EPT6 (1 << 14) /* Bit 14: Endpoint 6 Interrupt */ +# define UDPHS_INT_EPT7 (1 << 15) /* Bit 15: Endpoint 7 Interrupt */ +# define UDPHS_INT_EPT8 (1 << 16) /* Bit 16: Endpoint 8 Interrupt */ +# define UDPHS_INT_EPT9 (1 << 17) /* Bit 17: Endpoint 9 Interrupt */ +# define UDPHS_INT_EPT10 (1 << 18) /* Bit 18: Endpoint 10 Interrupt */ +# define UDPHS_INT_EPT11 (1 << 19) /* Bit 19: Endpoint 11 Interrupt */ +# define UDPHS_INT_EPT12 (1 << 20) /* Bit 20: Endpoint 12 Interrupt */ +# define UDPHS_INT_EPT13 (1 << 21) /* Bit 21: Endpoint 13 Interrupt */ +# define UDPHS_INT_EPT14 (1 << 22) /* Bit 22: Endpoint 14 Interrupt */ +# define UDPHS_INT_EPT15 (1 << 23) /* Bit 23: Endpoint 15 Interrupt */ +#define UDPHS_INT_DMA_SHIFT (25) /* Bits 25-31: Endpoint interrupts */ +#define UDPHS_INT_DMA_MASK (0x7f << UDPHS_INT_DMA_SHIFT) +#define UDPHS_INT_DMA(ch) (1 << ((ch)+24)) /* DMA Channel ch Interrupt */ +# define UDPHS_INT_DMA1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt */ +# define UDPHS_INT_DMA2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt */ +# define UDPHS_INT_DMA3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt */ +# define UDPHS_INT_DMA4 (1 << 28) /* Bit 28: DMA Channel 4 Interrupt */ +# define UDPHS_INT_DMA5 (1 << 29) /* Bit 29: DMA Channel 5 Interrupt */ +# define UDPHS_INT_DMA6 (1 << 30) /* Bit 30: DMA Channel 6 Interrupt */ +# define UDPHS_INT_DMA7 (1 << 31) /* Bit 31: DMA Channel 7 Interrupt */ + +/* UDPHS Endpoints Reset Register */ + +#define UDPHS_EPTRST(ep) (1 << (ep)) /* Endpoint ep Reset */ +# define UDPHS_EPT0RST (1 << 0) /* Bit 0: Endpoint 0 Reset */ +# define UDPHS_EPT1RST (1 << 1) /* Bit 1: Endpoint 1 Reset */ +# define UDPHS_EPT2RST (1 << 2) /* Bit 2: Endpoint 2 Reset */ +# define UDPHS_EPT3RST (1 << 3) /* Bit 3: Endpoint 3 Reset */ +# define UDPHS_EPT4RST (1 << 4) /* Bit 4: Endpoint 4 Reset */ +# define UDPHS_EPT5RST (1 << 5) /* Bit 5: Endpoint 5 Reset */ +# define UDPHS_EPT6RST (1 << 6) /* Bit 6: Endpoint 6 Reset */ +# define UDPHS_EPT7RST (1 << 7) /* Bit 7: Endpoint 7 Reset */ +# define UDPHS_EPT8RST (1 << 8) /* Bit 8: Endpoint 8 Reset */ +# define UDPHS_EPT9RST (1 << 9) /* Bit 9: Endpoint 9 Reset */ +# define UDPHS_EPT10RST (1 << 10) /* Bit 10: Endpoint 10 Reset */ +# define UDPHS_EPT11RST (1 << 11) /* Bit 11: Endpoint 11 Reset */ +# define UDPHS_EPT12RST (1 << 12) /* Bit 12: Endpoint 12 Reset */ +# define UDPHS_EPT13RST (1 << 13) /* Bit 13: Endpoint 13 Reset */ +# define UDPHS_EPT14RST (1 << 14) /* Bit 14: Endpoint 14 Reset */ +# define UDPHS_EPT15RST (1 << 15) /* Bit 15: Endpoint 15 Reset */ + +/* UDPHS Test Register */ + +#define UDPHS_TST_SPEED_SHIFT (0) /* Bits 0-1: Speed Configuration */ +#define UDPHS_TST_SPEED_MASK (3 << UDPHS_TST_SPEED_SHIFT) +# define UDPHS_TST_SPEED_NORMAL (0 << UDPHS_TST_SPEED_SHIFT) /* Normal Mode */ +# define UDPHS_TST_SPEED_HIGH (2 << UDPHS_TST_SPEED_SHIFT) /* Force High Speed */ +# define UDPHS_TST_SPEED_FULL (3 << UDPHS_TST_SPEED_SHIFT) /* Force Full Speed */ +#define UDPHS_TST_TSTJ (1 << 2) /* Bit 2: Test J Mode */ +#define UDPHS_TST_TSTK (1 << 3) /* Bit 3: Test K Mode */ +#define UDPHS_TST_TSTPKT (1 << 4) /* Bit 4: Test Packet Mode */ +#define UDPHS_TST_OPMODE2 (1 << 5) /* Bit 4: OpMode2 */ + +/* Endpoint registers */ +/* UDPHS Endpoint Configuration Register */ + +#define UDPHS_EPTCFG_SIZE_SHIFT (0) /* Bits 0-2: Endpoint Size */ +#define UDPHS_EPTCFG_SIZE_MASK (7 << UDPHS_EPTCFG_SIZE_SHIFT) +# define UDPHS_EPTCFG_SIZE_8 (0 << UDPHS_EPTCFG_SIZE_SHIFT) /* 8 bytes */ +# define UDPHS_EPTCFG_SIZE_16 (1 << UDPHS_EPTCFG_SIZE_SHIFT) /* 16 bytes */ +# define UDPHS_EPTCFG_SIZE_32 (2 << UDPHS_EPTCFG_SIZE_SHIFT) /* 32 bytes */ +# define UDPHS_EPTCFG_SIZE_64 (3 << UDPHS_EPTCFG_SIZE_SHIFT) /* 64 bytes */ +# define UDPHS_EPTCFG_SIZE_128 (4 << UDPHS_EPTCFG_SIZE_SHIFT) /* 128 bytes */ +# define UDPHS_EPTCFG_SIZE_256 (5 << UDPHS_EPTCFG_SIZE_SHIFT) /* 256 bytes */ +# define UDPHS_EPTCFG_SIZE_512 (6 << UDPHS_EPTCFG_SIZE_SHIFT) /* 512 bytes */ +# define UDPHS_EPTCFG_SIZE_1024 (7 << UDPHS_EPTCFG_SIZE_SHIFT) /* 1024 bytes */ +#define UDPHS_EPTCFG_DIR (1 << 3) /* Bit 3: Endpoint Direction */ +#define UDPHS_EPTCFG_TYPE_SHIFT (4) /* Bits 4-5: Endpoint Type */ +#define UDPHS_EPTCFG_TYPE_MASK (3 << UDPHS_EPTCFG_TYPE_SHIFT) +# define UDPHS_EPTCFG_TYPE_CTRL8 (0 << UDPHS_EPTCFG_TYPE_SHIFT) /* Control endpoint */ +# define UDPHS_EPTCFG_TYPE_ISO (1 << UDPHS_EPTCFG_TYPE_SHIFT) /* Isochronous endpoint */ +# define UDPHS_EPTCFG_TYPE_BULK (2 << UDPHS_EPTCFG_TYPE_SHIFT) /* Bulk endpoint */ +# define UDPHS_EPTCFG_TYPE_INT (3 << UDPHS_EPTCFG_TYPE_SHIFT) /* Interrupt endpoint */ +#define UDPHS_EPTCFG_BKNUMBER_SHIFT (6) /* Bits 6-7: Number of Banks */ +#define UDPHS_EPTCFG_BKNUMBER_MASK (3 << UDPHS_EPTCFG_BKNUMBER_SHIFT) +#define UDPHS_EPTCFG_NBTRANS_SHIFT (8) /* Bits 8-9: Number Transaction per uframe */ +#define UDPHS_EPTCFG_NBTRANS_MASK (3 << UDPHS_EPTCFG_NBTRANS_SHIFT) +#define UDPHS_EPTCFG_MAPD (1 << 31) /* Bit 31: Endpoint Mapped */ + +/* UDPHS Endpoint Control Enable Register, UDPHS Endpoint Control Disable Register, and UDPHS + * Endpoint Control Register + */ + /* Common bits definitions */ +#define UDPHS_EPTCTL_EPTENABL (1 << 0) /* Bit 0: Endpoint Enable */ +#define UDPHS_EPTCTL_AUTOVALID (1 << 1) /* Bit 1: Packet Auto-Valid Enable */ +#define UDPHS_EPTCTL_INTDISDMA (1 << 3) /* Bit 3: Interrupts Disable DMA */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTCTL_NYETDIS (1 << 4) /* Bit 4: NYET Disable (High Speed Bulk OUT) */ + /* --- Isochronous Endpoints Only --- */ +#define UDPHS_EPTCTL_DATAXRX (1 << 8) /* Bit 8: Interrupt Enable (Isochronous OUT) */ +#define UDPHS_EPTCTL_MDATARX (1 << 9) /* Bit 9: MDATA Interrupt Enable (Isochronous OUT) */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTCTL_ERROVFLW (1 << 8) /* Bit 8: Overflow Error Interrupt Enable */ +#define UDPHS_EPTCTL_RXRDYTXKL (1 << 9) /* Bit 9: Received OUT Data Interrupt Enable */ +#define UDPHS_EPTCTL_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete Interrupt Enable */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTCTL_TXRDY (1 << 11) /* Bit 11: TX Packet Ready Interrupt Enable */ +#define UDPHS_EPTCTL_RXSETUP (1 << 12) /* Bit 12: Received SETUP */ +#define UDPHS_EPTCTL_STALLSNT (1 << 13) /* Bit 13: Stall Sent Interrupt Enable */ +#define UDPHS_EPTCTL_NAKIN (1 << 14) /* Bit 14: NAKIN Interrupt Enable */ +#define UDPHS_EPTCTL_NAKOUT (1 << 15) /* Bit 15: NAKOUT Interrupt Enable */ + /* --- Isochronous Endpoints Only --- */ +#define UDPHS_EPTCTL_TXRDYTRER (1 << 11) /* Bit 11: TX Packet Ready/Transaction Error Interrupt Enable */ +#define UDPHS_EPTCTL_ERRFLISO (1 << 12) /* Bit 12: Error Flow Interrupt Enable */ +#define UDPHS_EPTCTL_ERRCRCNTR (1 << 13) /* Bit 13: ISO CRC Error/Number of Transaction Error Interrupt Enable */ +#define UDPHS_EPTCTL_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error Interrupt Enable */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTCTL_BUSYBANK (1 << 18) /* Bit 28: Busy Bank Interrupt Enable */ +#define UDPHS_EPTCTL_SHRTPCKT (1 << 31) /* Bit 31: Short Packet Send/Short Packet Interrupt Enable */ + +/* UDPHS Endpoint Set Status Register */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTSETSTA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request Set */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTSETSTA_RXRDYTXKL (1 << 9) /* Bit 9: KILL Bank Set (IN Endpoint) */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTSETSTA_TXRDY (1 << 11) /* Bit 11: TX Packet Ready Set */ + /* --- Isochronous Endpoints Only --- */ +#define UDPHS_EPTSETSTA_TXRDYTRER (1 << 11) /* Bit 11: TX Packet Ready Set */ + +/* UDPHS Endpoint Clear Status Register */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTCLRSTA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request Clear */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTCLRSTA_TOGGLESQ (1 << 6) /* Bit 6: Data Toggle Clear */ +#define UDPHS_EPTCLRSTA_RXRDYTXKL (1 << 9) /* Bit 9: Received OUT Data Clear */ +#define UDPHS_EPTCLRSTA_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete Clear */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTCLRSTA_RXSETUP (1 << 12) /* Bit 12: Received SETUP Clear */ +#define UDPHS_EPTCLRSTA_STALLSNT (1 << 13) /* Bit 13: Stall Sent Clear */ +#define UDPHS_EPTCLRSTA_NAKIN (1 << 14) /* Bit 14: NAKIN Clear */ +#define UDPHS_EPTCLRSTA_NAKOUT (1 << 15) /* Bit 15: NAKOUT Clear */ + /* --- Isochronous Endpoints Only --- */ +#define UDPHS_EPTCLRSTA_ERRFLISO (1 << 12) /* Bit 12: Error Flow Clear */ +#define UDPHS_EPTCLRSTA_ERRCRCNTR (1 << 13) /* Bit 13: Number of Transaction Error Clear */ +#define UDPHS_EPTCLRSTA_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error Clear */ + +/* UDPHS Endpoint Status Register */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTSTA_FRCESTALL (1 << 5) /* Bit 5: Stall Handshake Request */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTSTA_TOGGLESQ_SHIFT (6) /* Bits 6-7: Toggle Sequencing */ +#define UDPHS_EPTSTA_TOGGLESQ_MASK (3 << UDPHS_EPTSTA_TOGGLESQ_SHIFT) +# define UDPHS_EPTSTA_TOGGLESQ_DATA0 (0 << UDPHS_EPTSTA_TOGGLESQ_SHIFT) /* DATA0 */ +# define UDPHS_EPTSTA_TOGGLESQ_DATA1 (1 << UDPHS_EPTSTA_TOGGLESQ_SHIFT) /* DATA1 */ +# define UDPHS_EPTSTA_TOGGLESQ_DATA2 (2 << UDPHS_EPTSTA_TOGGLESQ_SHIFT) /* Isochronous Endpoint */ +# define UDPHS_EPTSTA_TOGGLESQ_MDATA (3 << UDPHS_EPTSTA_TOGGLESQ_SHIFT) /* Isochronous Endpoint */ +#define UDPHS_EPTSTA_ERROVFLW (1 << 8) /* Bit 8: Overflow Error */ +#define UDPHS_EPTSTA_RXRDYTXKL (1 << 9) /* Bit 9: Received OUT Data/KILL Bank */ +#define UDPHS_EPTSTA_TXCOMPLT (1 << 10) /* Bit 10: Transmitted IN Data Complete */ + /*--- Control/Bulk/Interrupt --- */ +#define UDPHS_EPTSTA_TXRDY (1 << 11) /* Bit 11: TX Packet Ready */ +#define UDPHS_EPTSTA_RXSETUP (1 << 12) /* Bit 12: Received SETUP */ +#define UDPHS_EPTSTA_STALLSNT (1 << 13) /* Bit 13: Stall Sent */ +#define UDPHS_EPTSTA_NAKIN (1 << 14) /* Bit 14: NAK IN */ +#define UDPHS_EPTSTA_NAKOUT (1 << 15) /* Bit 15: NAK OUT */ + /* --- Isochronous Endpoints Only --- */ +#define UDPHS_EPTSTA_TXRDYTRER (1 << 11) /* Bit 11: TX Packet Ready/Transaction Error */ +#define UDPHS_EPTSTA_ERRFLISO (1 << 12) /* Bit 12: Error Flow */ +#define UDPHS_EPTSTA_ERRCRCNTR (1 << 13) /* Bit 13: CRC ISO Error/Number of Transaction Error */ +#define UDPHS_EPTSTA_ERRFLUSH (1 << 14) /* Bit 14: Bank Flush Error */ + /*--- Control Only --- */ +#define UDPHS_EPTSTA_CTLDIR_SHIFT (16) /* Bits 16-17: Control Direction */ +#define UDPHS_EPTSTA_CTLDIR_MASK (3 << UDPHS_EPTSTA_CTLDIR_SHIFT) +# define UDPHS_EPTSTA_CTLDIR_WRITE (0 << UDPHS_EPTSTA_CTLDIR_SHIFT) /* Control Write requested */ +# define UDPHS_EPTSTA_CTLDIR_READ (1 << UDPHS_EPTSTA_CTLDIR_SHIFT) /* Control Read requested */ + /* --- Bulk/Interrupt/Isochronous --- */ +#define UDPHS_EPTSTA_CURBK_SHIFT (16) /* Bits 16-17: Current Bank */ +#define UDPHS_EPTSTA_CURBK_MASK (3 << UDPHS_EPTSTA_CURBK_SHIFT) +# define UDPHS_EPTSTA_CURBK_BANK0 (0 << UDPHS_EPTSTA_CURBK_SHIFT) /* Bank 0 (or single bank) */ +# define UDPHS_EPTSTA_CURBK_BANK1 (1 << UDPHS_EPTSTA_CURBK_SHIFT) /* Bank 1 */ +# define UDPHS_EPTSTA_CURBK_BANK2 (2 << UDPHS_EPTSTA_CURBK_SHIFT) /* Bank 2 */ + /* --- Common Bit Definitions --- */ +#define UDPHS_EPTSTA_BUSYBANK_SHIFT (18) /* Bits 18-19: Busy Bank Number */ +#define UDPHS_EPTSTA_BUSYBANK_MASK (3 << UDPHS_EPTSTA_BUSYBANK_SHIFT) +# define UDPHS_EPTSTA_BUSYBANK_1 (0 << UDPHS_EPTSTA_BUSYBANK_SHIFT) /* 1 busy bank */ +# define UDPHS_EPTSTA_BUSYBANK_2 (1 << UDPHS_EPTSTA_BUSYBANK_SHIFT) /* 2 busy banks */ +# define UDPHS_EPTSTA_BUSYBANK_3 (2 << UDPHS_EPTSTA_BUSYBANK_SHIFT) /* 3 busy banks */ +#define UDPHS_EPTSTA_BYTECNT_SHIFT (20) /* Bits 20-30: UDPHS Byte Count */ +#define UDPHS_EPTSTA_BYTECNT_MASK (0x7ff << UDPHS_EPTSTA_BYTECNT_SHIFT) +#define UDPHS_EPTSTA_SHRTPCKT (1 << 31) /* Bit 31: Short Packet */ + +/* DMA Channel Registers */ +/* UDPHS DMA Next Descriptor Address Register (32-bit address) */ +/* UDPHS DMA Channel Address Register (32-bit address) */ + +/* UDPHS DMA Channel Control Register */ + +#define UDPHS_DMACONTROL_CHANNENB (1 << 0) /* Bit 0: Channel Enable Command */ +#define UDPHS_DMACONTROL_LDNXTDSC (1 << 1) /* Bit 1: Load Next Channel Transfer Descriptor Enable (Command) */ +#define UDPHS_DMACONTROL_ENDTREN (1 << 2) /* Bit 2: End of Transfer Enable (Control) */ +#define UDPHS_DMACONTROL_ENDBEN (1 << 3) /* Bit 3: End of Buffer Enable (Control) */ +#define UDPHS_DMACONTROL_ENDTRIT (1 << 4) /* Bit 4: End of Transfer Interrupt Enable */ +#define UDPHS_DMACONTROL_ENDBUFFIT (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define UDPHS_DMACONTROL_DESCLDIT (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enable */ +#define UDPHS_DMACONTROL_BURSTLCK (1 << 7) /* Bit 7: Burst Lock Enable */ +#define UDPHS_DMACONTROL_BUFLEN_SHIFT (16) /* Bits 16-31: Buffer Byte Length (Write-only) */ +#define UDPHS_DMACONTROL_BUFLEN_MASK (0xffff << UDPHS_DMACONTROL_BUFLEN_SHIFT) +# define UDPHS_DMACONTROL_BUFLEN(n) ((uint32_t)(n) << UDPHS_DMACONTROL_BUFLEN_SHIFT) + +/* UDPHS DMA Channel Status Register */ + +#define UDPHS_DMASTATUS_CHANNENB (1 << 0) /* Bit 0: Channel Enable Status */ +#define UDPHS_DMASTATUS_CHANNACT (1 << 1) /* Bit 1: Channel Active Status */ +#define UDPHS_DMASTATUS_ENDTRST (1 << 4) /* Bit 4: End of Channel Transfer Status */ +#define UDPHS_DMASTATUS_ENDBFST (1 << 5) /* Bit 5: End of Channel Buffer Status */ +#define UDPHS_DMASTATUS_DESCLDST (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define UDPHS_DMASTATUS_BUFCNT_SHIFT (16) /* Bits 16-31: Buffer Byte Counut */ +#define UDPHS_DMASTATUS_BUFCNT_MASK (0xffff << UDPHS_DMASTATUS_BUFCNT_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/* This structure defines the UDPHS DMA Transfer Descriptor. Instances of DMA transfer + * descriptors must by aligned to 16-byte address boundaries. + * + * Each value contains the next value of each of three UDPHS DMA registers. The first + * register value (UDPHS_DMANXTDSCx) is a link that can be used to chain sequences of + * DMA transfers. + */ + +struct udphs_dtd_s +{ + uint32_t nxtd; /* Next Descriptor Address Register: UDPHS_DMANXTDSCx */ + uint32_t addr; /* DMA Channelx Address Register: UDPHS_DMAADDRESSx */ + uint32_t ctrl; /* DMA Channelx Control Register: UDPHS_DMACONTROLx */ +}; +#define SIZEOF_USPHS_DTD_S 12 + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_UDPHS_H */ diff --git a/arch/arm/src/sama5/chip/sam_wdt.h b/arch/arm/src/sama5/chip/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..657da369879531cbc004478580d17800e27c456e --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_wdt.h @@ -0,0 +1,114 @@ +/**************************************************************************************** + * arch/arm/src/sama5/chip/sam_wdt.h + * Watchdog Timer (WDT) definitions for the SAMA5D3 + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_WDT_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_WDT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* WDT register offsets ****************************************************************/ + +#define SAM_WDT_CR_OFFSET 0x00 /* Control Register */ +#define SAM_WDT_MR_OFFSET 0x04 /* Mode Register */ +#define SAM_WDT_SR_OFFSET 0x08 /* Status Register */ + +/* WDT register adresses ***************************************************************/ + +#define SAM_WDT_CR (SAM_WDT_VBASE+SAM_WDT_CR_OFFSET) +#define SAM_WDT_MR (SAM_WDT_VBASE+SAM_WDT_MR_OFFSET) +#define SAM_WDT_SR (SAM_WDT_VBASE+SAM_WDT_SR_OFFSET) + +/* WDT register bit definitions ********************************************************/ +/* Watchdog Timer Control Register */ + +#define WDT_CR_WDRSTT (1 << 0) /* Bit 0: Watchdog Restart */ + +#ifdef ATSAMA5D2 +#define WDT_CR_LOCKMR (1 << 4) /* Bit 4: Lock Mode Register Write Access */ +#endif + +#define WDT_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define WDT_CR_KEY_MASK (0xff << WDT_CR_KEY_SHIFT) +# define WDT_CR_KEY (0xa5 << WDT_CR_KEY_SHIFT) + +/* Watchdog Timer Mode Register */ + +#define WDT_MR_WDV_SHIFT (0) /* Bits 0-11: Watchdog Counter Value */ +#define WDT_MR_WDV_MASK (0xfff << WDT_MR_WDV_SHIFT) +# define WDT_MR_WDV(n) ((uint32_t)(n) << WDT_MR_WDV_SHIFT) +#define WDT_MR_WDFIEN (1 << 12) /* Bit 12: Watchdog Fault Interrupt Enable */ +#define WDT_MR_WDRSTEN (1 << 13) /* Bit 13: Watchdog Reset Enable */ + +#ifdef ATSAMA5D3 +# define WDT_MR_WDRPROC (1 << 14) /* Bit 14: Watchdog Reset Processor */ +#endif + +#define WDT_MR_WDDIS (1 << 15) /* Bit 15: Watchdog Disable */ +#define WDT_MR_WDD_SHIFT (16) /* Bits 16-27: Watchdog Delta Value */ +#define WDT_MR_WDD_MASK (0xfff << WDT_MR_WDD_SHIFT) +# define WDT_MR_WDD(n) ((uint32_t)(n) << WDT_MR_WDD_SHIFT) +#define WDT_MR_WDDBGHLT (1 << 28) /* Bit 28: Watchdog Debug Halt */ +#define WDT_MR_WDIDLEHLT (1 << 29) /* Bit 29: Watchdog Idle Halt */ + +/* Watchdog Timer Status Register */ + +#define WDT_SR_WDUNF (1 << 0) /* Bit 0: Watchdog Underflow */ +#define WDT_SR_WDERR (1 << 1) /* Bit 1: Watchdog Error */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_WDT_H */ diff --git a/arch/arm/src/sama5/chip/sam_xdmac.h b/arch/arm/src/sama5/chip/sam_xdmac.h new file mode 100644 index 0000000000000000000000000000000000000000..06b055ccbc931994d9876d309c76b4435d88f9a1 --- /dev/null +++ b/arch/arm/src/sama5/chip/sam_xdmac.h @@ -0,0 +1,544 @@ +/************************************************************************************ + * arch/arm/src/sama5/chip/sam_xdmac.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_CHIP_SAM_XDMAC_H +#define __ARCH_ARM_SRC_SAMA5_CHIP_SAM_XDMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Included Files + ************************************************************************************/ +/* XDMAC Register Offsets ***********************************************************/ + +#define SAM_XDMAC_GTYPE_OFFSET 0x0000 /* Global Type Register */ +#define SAM_XDMAC_GCFG_OFFSET 0x0004 /* Global Configuration Register */ +#define SAM_XDMAC_GWAC_OFFSET 0x0008 /* Global Weighted Arbiter Configuration Register */ +#define SAM_XDMAC_GIE_OFFSET 0x000c /* Global Interrupt Enable Register */ +#define SAM_XDMAC_GID_OFFSET 0x0010 /* Global Interrupt Disable Register */ +#define SAM_XDMAC_GIM_OFFSET 0x0014 /* Global Interrupt Mask Register */ +#define SAM_XDMAC_GIS_OFFSET 0x0018 /* Global Interrupt Status Register */ +#define SAM_XDMAC_GE_OFFSET 0x001c /* Global Channel Enable Register */ +#define SAM_XDMAC_GD_OFFSET 0x0020 /* Global Channel Disable Register */ +#define SAM_XDMAC_GS_OFFSET 0x0024 /* Global Channel Status Register */ +#define SAM_XDMAC_GRS_OFFSET 0x0028 /* Global Channel Read Suspend Register */ +#define SAM_XDMAC_GWS_OFFSET 0x002c /* Global Channel Write Suspend Register */ +#define SAM_XDMAC_GRWS_OFFSET 0x0030 /* Global Channel Read Write Suspend Register */ +#define SAM_XDMAC_GRWR_OFFSET 0x0034 /* Global Channel Read Write Resume Register */ +#define SAM_XDMAC_GSWR_OFFSET 0x0038 /* Global Channel Software Request Register */ +#define SAM_XDMAC_GSWS_OFFSET 0x003c /* Global Channel Software Request Status Register */ +#define SAM_XDMAC_GSWF_OFFSET 0x0040 /* Global Channel Software Flush Request Register */ + /* 0x0044–0x004c Reserved */ + +/* Offsets to the base of the DMA channel registers */ + +#define SAM_XDMAC_CH_OFFSET(n) (0x0050 + ((n) << 6)) +# define SAM_XDMAC_CH0_OFFSET 0x0050 +# define SAM_XDMAC_CH1_OFFSET 0x0090 +# define SAM_XDMAC_CH2_OFFSET 0x00d0 +# define SAM_XDMAC_CH3_OFFSET 0x0110 +# define SAM_XDMAC_CH4_OFFSET 0x0150 +# define SAM_XDMAC_CH5_OFFSET 0x0190 +# define SAM_XDMAC_CH6_OFFSET 0x01d0 +# define SAM_XDMAC_CH7_OFFSET 0x0210 +# define SAM_XDMAC_CH8_OFFSET 0x0250 +# define SAM_XDMAC_CH9_OFFSET 0x0290 +# define SAM_XDMAC_CH10_OFFSET 0x02d0 +# define SAM_XDMAC_CH11_OFFSET 0x0310 +# define SAM_XDMAC_CH12_OFFSET 0x0350 +# define SAM_XDMAC_CH13_OFFSET 0x0390 +# define SAM_XDMAC_CH14_OFFSET 0x03d0 +# define SAM_XDMAC_CH15_OFFSET 0x0410 + +/* Offsets to channel registers relative to the base of the DMA channel registers */ + +#define SAM_XDMACH_CIE_OFFSET 0x0000 /* Channel Interrupt Enable Register */ +#define SAM_XDMACH_CID_OFFSET 0x0004 /* Channel Interrupt Disable Register */ +#define SAM_XDMACH_CIM_OFFSET 0x0008 /* Channel Interrupt Mask Register */ +#define SAM_XDMACH_CIS_OFFSET 0x000c /* Channel Interrupt Status Register */ +#define SAM_XDMACH_CSA_OFFSET 0x0010 /* Channel Source Address Register */ +#define SAM_XDMACH_CDA_OFFSET 0x0014 /* Channel Destination Address Register */ +#define SAM_XDMACH_CNDA_OFFSET 0x0018 /* Channel Next Descriptor Address Register */ +#define SAM_XDMACH_CNDC_OFFSET 0x001c /* Channel Next Descriptor Control Register */ +#define SAM_XDMACH_CUBC_OFFSET 0x0020 /* Channel Microblock Control Register */ +#define SAM_XDMACH_CBC_OFFSET 0x0024 /* Channel Block Control Register */ +#define SAM_XDMACH_CC_OFFSET 0x0028 /* Channel Configuration Register */ +#define SAM_XDMACH_CDSMSP_OFFSET 0x002c /* Channel Data Stride Memory Set Pattern */ +#define SAM_XDMACH_CSUS_OFFSET 0x0030 /* Channel Source Microblock Stride */ +#define SAM_XDMACH_CDUS_OFFSET 0x0034 /* Channel Destination Microblock Stride */ + /* 0x0038-0x003c Reserved */ + /* 0x0fec–0x0ffc Reserved */ + +/* XDMAC Register Addresses *********************************************************/ + +#define SAM_XDMAC0_GTYPE (SAM_XDMAC0_VBASE+SAM_XDMAC_GTYPE_OFFSET) +#define SAM_XDMAC0_GCFG (SAM_XDMAC0_VBASE+SAM_XDMAC_GCFG_OFFSET) +#define SAM_XDMAC0_GWAC (SAM_XDMAC0_VBASE+SAM_XDMAC_GWAC_OFFSET) +#define SAM_XDMAC0_GIE (SAM_XDMAC0_VBASE+SAM_XDMAC_GIE_OFFSET) +#define SAM_XDMAC0_GID (SAM_XDMAC0_VBASE+SAM_XDMAC_GID_OFFSET) +#define SAM_XDMAC0_GIM (SAM_XDMAC0_VBASE+SAM_XDMAC_GIM_OFFSET) +#define SAM_XDMAC0_GIS (SAM_XDMAC0_VBASE+SAM_XDMAC_GIS_OFFSET) +#define SAM_XDMAC0_GE (SAM_XDMAC0_VBASE+SAM_XDMAC_GE_OFFSET) +#define SAM_XDMAC0_GD (SAM_XDMAC0_VBASE+SAM_XDMAC_GD_OFFSET) +#define SAM_XDMAC0_GS (SAM_XDMAC0_VBASE+SAM_XDMAC_GS_OFFSET) +#define SAM_XDMAC0_GRS (SAM_XDMAC0_VBASE+SAM_XDMAC_GRS_OFFSET) +#define SAM_XDMAC0_GWS (SAM_XDMAC0_VBASE+SAM_XDMAC_GWS_OFFSET) +#define SAM_XDMAC0_GRWS (SAM_XDMAC0_VBASE+SAM_XDMAC_GRWS_OFFSET) +#define SAM_XDMAC0_GRWR (SAM_XDMAC0_VBASE+SAM_XDMAC_GRWR_OFFSET) +#define SAM_XDMAC0_GSWR (SAM_XDMAC0_VBASE+SAM_XDMAC_GSWR_OFFSET) +#define SAM_XDMAC0_GSWS (SAM_XDMAC0_VBASE+SAM_XDMAC_GSWS_OFFSET) +#define SAM_XDMAC0_GSWF (SAM_XDMAC0_VBASE+SAM_XDMAC_GSWF_OFFSET) + +/* Base addresses of XDMAC0 channel registers */ + +#define SAM_XDMAC0_CH_BASE(n) (SAM_XDMAC0_VBASE+SAM_XDMAC_CH_OFFSET(n)) +# define SAM_XDMAC0_CH0_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH0_OFFSET) +# define SAM_XDMAC0_CH1_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH1_OFFSET) +# define SAM_XDMAC0_CH2_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH2_OFFSET) +# define SAM_XDMAC0_CH3_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH3_OFFSET) +# define SAM_XDMAC0_CH4_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH4_OFFSET) +# define SAM_XDMAC0_CH5_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH5_OFFSET) +# define SAM_XDMAC0_CH6_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH6_OFFSET) +# define SAM_XDMAC0_CH7_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH7_OFFSET) +# define SAM_XDMAC0_CH8_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH8_OFFSET) +# define SAM_XDMAC0_CH9_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH9_OFFSET) +# define SAM_XDMAC0_CH10_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH10_OFFSET) +# define SAM_XDMAC0_CH11_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH11_OFFSET) +# define SAM_XDMAC0_CH12_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH12_OFFSET) +# define SAM_XDMAC0_CH13_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH13_OFFSET) +# define SAM_XDMAC0_CH14_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH14_OFFSET) +# define SAM_XDMAC0_CH15_BASE (SAM_XDMAC0_VBASE+SAM_XDMAC_CH15_OFFSET) + +/* Addresses of XDMAC0 channel registers */ + +#define SAM_XDMACH0_CIE(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CIE_OFFSET) +#define SAM_XDMACH0_CID(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CID_OFFSET) +#define SAM_XDMACH0_CIM(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CIM_OFFSET) +#define SAM_XDMACH0_CIS(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CIS_OFFSET) +#define SAM_XDMACH0_CSA(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CSA_OFFSET) +#define SAM_XDMACH0_CDA(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CDA_OFFSET) +#define SAM_XDMACH0_CNDA(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CNDA_OFFSET) +#define SAM_XDMACH0_CNDC(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CNDC_OFFSET) +#define SAM_XDMACH0_CUBC(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CUBC_OFFSET) +#define SAM_XDMACH0_CBC(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CBC_OFFSET) +#define SAM_XDMACH0_CC(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CC_OFFSET) +#define SAM_XDMACH0_CDSMSP(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CDSMSP_OFFSET) +#define SAM_XDMACH0_CSUS(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CSUS_OFFSET) +#define SAM_XDMACH0_CDUS(n) (SAM_XDMACH0_CH_BASE(n)+SAM_XDMACH_CDUS_OFFSET) + +#define SAM_XDMAC1_GTYPE (SAM_XDMAC1_VBASE+SAM_XDMAC_GTYPE_OFFSET) +#define SAM_XDMAC1_GCFG (SAM_XDMAC1_VBASE+SAM_XDMAC_GCFG_OFFSET) +#define SAM_XDMAC1_GWAC (SAM_XDMAC1_VBASE+SAM_XDMAC_GWAC_OFFSET) +#define SAM_XDMAC1_GIE (SAM_XDMAC1_VBASE+SAM_XDMAC_GIE_OFFSET) +#define SAM_XDMAC1_GID (SAM_XDMAC1_VBASE+SAM_XDMAC_GID_OFFSET) +#define SAM_XDMAC1_GIM (SAM_XDMAC1_VBASE+SAM_XDMAC_GIM_OFFSET) +#define SAM_XDMAC1_GIS (SAM_XDMAC1_VBASE+SAM_XDMAC_GIS_OFFSET) +#define SAM_XDMAC1_GE (SAM_XDMAC1_VBASE+SAM_XDMAC_GE_OFFSET) +#define SAM_XDMAC1_GD (SAM_XDMAC1_VBASE+SAM_XDMAC_GD_OFFSET) +#define SAM_XDMAC1_GS (SAM_XDMAC1_VBASE+SAM_XDMAC_GS_OFFSET) +#define SAM_XDMAC1_GRS (SAM_XDMAC1_VBASE+SAM_XDMAC_GRS_OFFSET) +#define SAM_XDMAC1_GWS (SAM_XDMAC1_VBASE+SAM_XDMAC_GWS_OFFSET) +#define SAM_XDMAC1_GRWS (SAM_XDMAC1_VBASE+SAM_XDMAC_GRWS_OFFSET) +#define SAM_XDMAC1_GRWR (SAM_XDMAC1_VBASE+SAM_XDMAC_GRWR_OFFSET) +#define SAM_XDMAC1_GSWR (SAM_XDMAC1_VBASE+SAM_XDMAC_GSWR_OFFSET) +#define SAM_XDMAC1_GSWS (SAM_XDMAC1_VBASE+SAM_XDMAC_GSWS_OFFSET) +#define SAM_XDMAC1_GSWF (SAM_XDMAC1_VBASE+SAM_XDMAC_GSWF_OFFSET) + +/* Base addresses of XDMAC1 channel registers */ + +#define SAM_XDMAC1_CH_BASE(n) (SAM_XDMAC1_VBASE+SAM_XDMAC_CH_OFFSET(n)) +# define SAM_XDMAC1_CH0_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH0_OFFSET) +# define SAM_XDMAC1_CH1_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH1_OFFSET) +# define SAM_XDMAC1_CH2_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH2_OFFSET) +# define SAM_XDMAC1_CH3_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH3_OFFSET) +# define SAM_XDMAC1_CH4_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH4_OFFSET) +# define SAM_XDMAC1_CH5_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH5_OFFSET) +# define SAM_XDMAC1_CH6_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH6_OFFSET) +# define SAM_XDMAC1_CH7_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH7_OFFSET) +# define SAM_XDMAC1_CH8_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH8_OFFSET) +# define SAM_XDMAC1_CH9_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH9_OFFSET) +# define SAM_XDMAC1_CH10_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH10_OFFSET) +# define SAM_XDMAC1_CH11_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH11_OFFSET) +# define SAM_XDMAC1_CH12_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH12_OFFSET) +# define SAM_XDMAC1_CH13_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH13_OFFSET) +# define SAM_XDMAC1_CH14_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH14_OFFSET) +# define SAM_XDMAC1_CH15_BASE (SAM_XDMAC1_VBASE+SAM_XDMAC_CH15_OFFSET) + +/* Addresses of XDMAC0 channel registers */ + +#define SAM_XDMACH1_CIE(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CIE_OFFSET) +#define SAM_XDMACH1_CID(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CID_OFFSET) +#define SAM_XDMACH1_CIM(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CIM_OFFSET) +#define SAM_XDMACH1_CIS(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CIS_OFFSET) +#define SAM_XDMACH1_CSA(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CSA_OFFSET) +#define SAM_XDMACH1_CDA(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CDA_OFFSET) +#define SAM_XDMACH1_CNDA(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CNDA_OFFSET) +#define SAM_XDMACH1_CNDC(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CNDC_OFFSET) +#define SAM_XDMACH1_CUBC(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CUBC_OFFSET) +#define SAM_XDMACH1_CBC(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CBC_OFFSET) +#define SAM_XDMACH1_CC(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CC_OFFSET) +#define SAM_XDMACH1_CDSMSP(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CDSMSP_OFFSET) +#define SAM_XDMACH1_CSUS(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CSUS_OFFSET) +#define SAM_XDMACH1_CDUS(n) (SAM_XDMACH1_CH_BASE(n)+SAM_XDMACH_CDUS_OFFSET) + +/* XDMAC Register Bit Definitions ***************************************************/ + +/* Global Type Register */ + +#define XDMAC_GTYPE_NB_CH_SHIFT (0) /* Bits 0-4: Number of Channels Minus One */ +#define XDMAC_GTYPE_NB_CH_MASK (31 << XDMAC_GTYPE_NB_CH_SHIFT) + #define XDMAC_GTYPE_NB_CH(n) ((uint32_t)(n) << XDMAC_GTYPE_NB_CH_SHIFT) +#define XDMAC_GTYPE_FIFO_SZ_SHIFT (5) /* Bits 5-15: Number of Bytes */ +#define XDMAC_GTYPE_FIFO_SZ_MASK (0x7ff << XDMAC_GTYPE_FIFO_SZ_SHIFT) +# define XDMAC_GTYPE_FIFO_SZ(n) ((uint32_t)(n) << XDMAC_GTYPE_FIFO_SZ_SHIFT) +#define XDMAC_GTYPE_NB_REQ_SHIFT (16) /* Bits 16-22: Number of Peripheral Requests Minus One */ +#define XDMAC_GTYPE_NB_REQ_MASK (0x7f << XDMAC_GTYPE_NB_REQ_SHIFT) +# define XDMAC_GTYPE_NB_REQ(n) ((uint32_t)(n) << XDMAC_GTYPE_NB_REQ_SHIFT) + +/* Global Configuration Register */ + +#define XDMAC_GCFG_CGDISREG (1 << 0) /* Bit 0: Configuration Registers Clock Gating Disable */ +#define XDMAC_GCFG_CGDISPIPE (1 << 1) /* Bit 1: Pipeline Clock Gating Disable */ +#define XDMAC_GCFG_CGDISFIFO (1 << 2) /* Bit 2: FIFO Clock Gating Disable */ +#define XDMAC_GCFG_CGDISIF (1 << 3) /* Bit 3: Bus Interface Clock Gating Disable */ +#define XDMAC_GCFG_BXKBEN (1 << 8) /* Bit 8: Boundary X Kilo byte Enable */ + +/* Global Weighted Arbiter Configuration Register */ + +#define XDMAC_GWAC_PW0_SHIFT (0) /* Bits 0-3: Pool Weight 0 */ +#define XDMAC_GWAC_PW0_MASK (15 << XDMAC_GWAC_PW0_SHIFT) +# define XDMAC_GWAC_PW0(n) ((uint32_t)(n) << XDMAC_GWAC_PW0_SHIFT) +#define XDMAC_GWAC_PW1_SHIFT (4) /* Bits 4-7: Pool Weight 1 */ +#define XDMAC_GWAC_PW1_MASK (15 << XDMAC_GWAC_PW1_SHIFT) +# define XDMAC_GWAC_PW1(n) ((uint32_t)(n) << XDMAC_GWAC_PW1_SHIFT) +#define XDMAC_GWAC_PW2_SHIFT (8) /* Bits 8-11: Pool Weight 2 */ +#define XDMAC_GWAC_PW2_MASK (15 << XDMAC_GWAC_PW2_SHIFT) +# define XDMAC_GWAC_PW2(n) ((uint32_t)(n) << XDMAC_GWAC_PW2_SHIFT) +#define XDMAC_GWAC_PW3_SHIFT (12) /* Bits 12-15: Pool Weight 3 */ +#define XDMAC_GWAC_PW3_MASK (15 << XDMAC_GWAC_PW3_SHIFT) +# define XDMAC_GWAC_PW3(n) ((uint32_t)(n) << XDMAC_GWAC_PW3_SHIFT) + +/* All of these registers have the same layout: + * + * - Global Interrupt Enable Register, Global Interrupt Disable Register, Interrupt + * Mask Register, and Global Interrupt Status Register. + * + * - Global Channel Enable Register, Global Channel Disable Register, and Global + * Channel Status Register + * + * - Global Channel Read Suspend Register, Global Channel Write Suspend Register, + * Channel Read Write Suspend Register, and Global Channel Read Write Resume + * Register + * + * - Global Channel Software Request Register, Global Channel Software Request + * Status Register, and Global Channel Software Flush Request Register + */ + +#define XDMAC_CHAN(n) (1 << (n)) +#define XDMAC_CHAN_ALL (0x0000ffff) + +/* Channel Interrupt Enable Register, Channel Interrupt Disable Register, Channel + * Interrupt Mask Register, and Channel Interrupt Status Register. + */ + +#define XDMAC_CHINT_BI (1 << 0) /* Bit 0: End of Block Interrupt */ +#define XDMAC_CHINT_LI (1 << 1) /* Bit 1: End of Linked List Interrupt */ +#define XDMAC_CHINT_DI (1 << 2) /* Bit 2: End of Disable Interrupt */ +#define XDMAC_CHINT_FI (1 << 3) /* Bit 3: End of Flush Interrupt */ +#define XDMAC_CHINT_RBI (1 << 4) /* Bit 4: Read Bus Error Interrupt */ +#define XDMAC_CHINT_WBI (1 << 5) /* Bit 5: Write Bus Error Interrupt */ +#define XDMAC_CHINT_ROI (1 << 6) /* Bit 6: Request Overflow Error Interrupt Disable Bit */ + +#define XDMAC_CHINT_ERRORS (0x00000070) +#define XDMAC_CHINT_ALL (0x0000007f) + +/* Channel Source Address (SA) Register (aligned 32-bit address) */ +/* Channel Destination Address (DA) Register (aligned 32-bit address) */ + +/* Channel Next Descriptor Address (CNDA) Register (aligned 32-bit address) */ + +#define XDMACH_CNDA_NDAIF (1 << 0) /* Bit 0: Channel Next Descriptor Interface */ + +/* Channel Next Descriptor Control Register */ + +#define XDMACH_CNDC_NDE (1 << 0) /* Bit 0: Channel Next Descriptor Enable */ +#define XDMACH_CNDC_NDSUP (1 << 1) /* Bit 1: Channel Next Descriptor Source Update */ +#define XDMACH_CNDC_NDDUP (1 << 2) /* Bit 2: Channel Next Descriptor Destination Update */ +#define XDMACH_CNDC_NDVIEW_SHIFT (3) /* Bits 3-4: Channel Next Descriptor View */ +#define XDMACH_CNDC_NDVIEW_MASK (3 << XDMACH_CNDC_NDVIEW_SHIFT) +# define XDMACH_CNDC_NDVIEW_NDV0 (0 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 0 */ +# define XDMACH_CNDC_NDVIEW_NDV1 (1 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 1 */ +# define XDMACH_CNDC_NDVIEW_NDV2 (2 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 2 */ +# define XDMACH_CNDC_NDVIEW_NDV3 (3 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 3 */ + +/* Channel Microblock Control Register */ + +#define XDMACH_CUBC_UBLEN_SHIFT (0) /* Bits 0-23: Channel Microblock Length */ +#define XDMACH_CUBC_UBLEN_MASK (0x00ffffff << XDMACH_CUBC_UBLEN_SHIFT) +#define XDMACH_CUBC_UBLEN_MAX (0x00ffffff) + +/* Channel Block Control Register */ + +#define XDMACH_CBC_BLEN_MASK (0x000000fff) /* Bits 0-11: Channel Block Length */ + +/* Channel Configuration Register */ + +#define XDMACH_CC_TYPE (1 << 0) /* Bit 0: Channel Transfer Type */ +#define XDMACH_CC_MBSIZE_SHIFT (1) /* Bits 1-2: Channel Memory Burst Size */ +#define XDMACH_CC_MBSIZE_MASK (3 << XDMACH_CC_MBSIZE_SHIFT) +# define XDMACH_CC_MBSIZE(n) ((uint32_t)(n) << XDMACH_CC_MBSIZE_SHIFT) /* n=0-3 */ +# define XDMACH_CC_MBSIZE_1 (0 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to one */ +# define XDMACH_CC_MBSIZE_4 (1 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to four */ +# define XDMACH_CC_MBSIZE_8 (2 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to eight */ +# define XDMACH_CC_MBSIZE_16 (3 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to sixteen */ +#define XDMACH_CC_DSYNC (1 << 4) /* Bit 4: Channel Synchronization */ +#define XDMACH_CC_PROT (1 << 5) /* Bit 5: Channel Protection */ +#define XDMACH_CC_SWREQ (1 << 6) /* Bit 6: Channel Software Request Trigger */ +#define XDMACH_CC_MEMSET (1 << 7) /* Bit 7: Channel Fill Block of memory */ +#define XDMACH_CC_CSIZE_SHIFT (8) /* Bits 8-10: Channel Chunk Size */ +#define XDMACH_CC_CSIZE_MASK (7 << XDMACH_CC_CSIZE_SHIFT) +# define XDMACH_CC_CSIZE_1 (0 << XDMACH_CC_CSIZE_SHIFT) /* 1 data transferred */ +# define XDMACH_CC_CSIZE_2 (1 << XDMACH_CC_CSIZE_SHIFT) /* 2 data transferred */ +# define XDMACH_CC_CSIZE_4 (2 << XDMACH_CC_CSIZE_SHIFT) /* 4 data transferred */ +# define XDMACH_CC_CSIZE_8 (3 << XDMACH_CC_CSIZE_SHIFT) /* 8 data transferred */ +# define XDMACH_CC_CSIZE_16 (4 << XDMACH_CC_CSIZE_SHIFT) /* 16 data transferred */ +#define XDMACH_CC_DWIDTH_SHIFT (11) /* Bits 11-12: Channel Data Width */ +#define XDMACH_CC_DWIDTH_MASK (3 << XDMACH_CC_DWIDTH_SHIFT) +# define XDMACH_CC_DWIDTH_BYTE (0 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 8 bits */ +# define XDMACH_CC_DWIDTH_HWORD (1 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 16 bits */ +# define XDMACH_CC_DWIDTH_WORD (2 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 32 bits */ +# define XDMACH_CC_DWIDTH_DWORD (3 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 64 bits */ +#define XDMACH_CC_SIF (1 << 13) /* Bit 13: Channel Source Interface Identifier */ +#define XDMACH_CC_DIF (1 << 14) /* Bit 14: Channel Destination Interface Identifier */ +#define XDMACH_CC_SAM_SHIFT (16) /* Bits 16-17: Channel Source Addressing Mode */ +#define XDMACH_CC_SAM_MASK (3 << XDMACH_CC_SAM_SHIFT) +# define XDMACH_CC_SAM_FIXED (0 << XDMACH_CC_SAM_SHIFT) /* The address remains unchanged */ +# define XDMACH_CC_SAM_INCR (1 << XDMACH_CC_SAM_SHIFT) /* Address is incremented */ +# define XDMACH_CC_SAM_UBS (2 << XDMACH_CC_SAM_SHIFT) /* Microblock stride is added */ +# define XDMACH_CC_SAM_UBSDS (3 << XDMACH_CC_SAM_SHIFT) /* Microblock stride and data stride is added */ +#define XDMACH_CC_DAM_SHIFT (18) /* Bits 18-19: Channel Destination Addressing Mode */ +#define XDMACH_CC_DAM_MASK (3 << XDMACH_CC_DAM_SHIFT) +# define XDMACH_CC_DAM_FIXED (0 << XDMACH_CC_DAM_SHIFT) /* The address remains unchanged */ +# define XDMACH_CC_DAM_INCR (1 << XDMACH_CC_DAM_SHIFT) /* Address is incremented */ +# define XDMACH_CC_DAM_UBS (2 << XDMACH_CC_DAM_SHIFT) /* Microblock stride is added */ +# define XDMACH_CC_DAM_UBSDS (3 << XDMACH_CC_DAM_SHIFT) /* Microblock stride and data stride is added */ +#define XDMACH_CC_INITD (1 << 21) /* Bit 21: Channel Initialization Terminated */ +#define XDMACH_CC_RDIP (1 << 22) /* Bit 22: Read in Progress */ +#define XDMACH_CC_WRIP (1 << 23) /* Bit 23: Write in Progress */ +#define XDMACH_CC_PERID_SHIFT (24) /* Bits 24-30: Channel Peripheral Identifier */ +#define XDMACH_CC_PERID_MASK (0x7f << XDMACH_CC_PERID_SHIFT) +# define XDMACH_CC_PERID(n) ((uint32_t)(n) << XDMACH_CC_PERID_SHIFT) + +/* Channel Data Stride Memory Set Pattern */ + +#define XDMACH_CDSMSP_SDS_MSP_SHIFT (0) /* Bits 0-15: Channel Source Data stride or Memory Set Pattern */ +#define XDMACH_CDSMSP_SDS_MSP_MASK (0xffff << XDMACH_CDSMSP_SDS_MSP_SHIFT) +# define XDMACH_CDSMSP_SDS_MSP(n) ((uint32_t)(n) << XDMACH_CDSMSP_SDS_MSP_SHIFT) +#define XDMACH_CDSMSP_DDS_MSP_SHIFT (16) /* Bits 16-31: Channel Destination Data Stride or Memory Set Pattern */ +#define XDMACH_CDSMSP_DDS_MSP_MASK (0xffff << XDMACH_CDSMSP_DDS_MSP_SHIFT) +# define XDMACH_CDSMSP_DDS_MSP(n) ((uint32_t)(n) << XDMACH_CDSMSP_DDS_MSP_SHIFT) + +/* Channel Source Microblock Stride */ + +#define XDMACH_CSUS_SUBS_MASK (0x00ffffff) /* Bits 0-23: Channel Source Microblock Stride */ + +/* Channel Destination Microblock Stride */ + +#define XDMACH_CDUS_DUBS_MASK (0x00ffffff) /* Bits 0-23: Channel Destination Microblock Stride */ + +/* XDMA Channel Definitions *************************************************************/ +/* XDMA Controller 0 Channel Definitions (always secure) */ + +#define XDMAC0_CH_HSMCI0 0 /* HSMCI0 Receive/Transmit */ +#define XDMAC0_CH_HSMCI1 1 /* HSMCI1 Receive/Transmit */ +#define XDMAC0_CH_TWI0_TX 2 /* TWI0 Transmit */ +#define XDMAC0_CH_TWI0_RX 3 /* TWI0 Receive */ +#define XDMAC0_CH_TWI1_TX 4 /* TWI1 Transmit */ +#define XDMAC0_CH_TWI1_RX 5 /* TWI1 Receive */ +#define XDMAC0_CH_TWI2_TX 6 /* TWI2 Transmit */ +#define XDMAC0_CH_TWI2_RX 7 /* TWI2 Receive */ +#define XDMAC0_CH_TWI3_TX 8 /* TWI3 Transmit */ +#define XDMAC0_CH_TWI3_RX 9 /* TWI3 Receive */ +#define XDMAC0_CH_SPI0_TX 10 /* SPI0 Transmit */ +#define XDMAC0_CH_SPI0_RX 11 /* SPI0 Receive */ +#define XDMAC0_CH_SPI1_TX 12 /* SPI1 Transmit */ +#define XDMAC0_CH_SPI1_RX 13 /* SPI1 Receive */ +#define XDMAC0_CH_SPI2_TX 14 /* SPI2 Transmit */ +#define XDMAC0_CH_SPI2_RX 15 /* SPI2 Receive */ +#define XDMAC0_CH_USART2_TX 16 /* USART2 Transmit */ +#define XDMAC0_CH_USART2_RX 17 /* USART2 Receive */ +#define XDMAC0_CH_USART3_TX 18 /* USART3 Transmit */ +#define XDMAC0_CH_USART3_RX 19 /* USART3 Receive */ +#define XDMAC0_CH_USART4_TX 20 /* USART4 Transmit */ +#define XDMAC0_CH_USART4_RX 21 /* USART4 Receive */ +#define XDMAC0_CH_UART0_TX 22 /* UART0 Transmit */ +#define XDMAC0_CH_UART0_RX 23 /* UART0 Receive */ +#define XDMAC0_CH_UART1_TX 24 /* UART1 Transmit */ +#define XDMAC0_CH_UART1_RX 25 /* UART1 Receive */ +#define XDMAC0_CH_SSC0_TX 26 /* SSC0 Transmit */ +#define XDMAC0_CH_SSC0_RX 27 /* SSC0 Receive */ +#define XDMAC0_CH_SSC1_TX 28 /* SSC1 Transmit */ +#define XDMAC0_CH_SSC1_RX 29 /* SSC1 Receive */ +#define XDMAC0_CH_DBGU_TX 30 /* DBGU Transmit */ +#define XDMAC0_CH_DBGU_RX 31 /* DBGU Receive */ +#define XDMAC0_CH_ADC_RX 32 /* ADC Receive */ +#define XDMAC0_CH_SMD_TX 33 /* SMD Transmit */ +#define XDMAC0_CH_SMD_RX 34 /* SMD Receive */ +#define XDMAC0_CH_USART0_TX 36 /* USART0 Transmit */ +#define XDMAC0_CH_USART0_RX 37 /* USART0 Receive */ +#define XDMAC0_CH_USART1_TX 38 /* USART1 Transmit */ +#define XDMAC0_CH_USART1_RX 39 /* USART1 Receive */ +#define XDMAC0_CH_AES_RX 40 /* AES Receive */ +#define XDMAC0_CH_AES_TX 41 /* AES Transmit */ +#define XDMAC0_CH_TDES_TX 42 /* TDES Transmit */ +#define XDMAC0_CH_TDES_RX 43 /* TDES Receive */ +#define XDMAC0_CH_SHA_TX 44 /* SHA Transmit */ +#define XDMAC0_CH_CATB_TX 46 /* CATB Transmit */ +#define XDMAC0_CH_CATB_RX 47 /* CATB Receive */ + +/* XDMA Controller 1 Channel Definitions (never secure) */ + +#define XDMAC1_CH_HSMCI0 0 /* HSMCI0 Receive/Transmit */ +#define XDMAC1_CH_HSMCI1 1 /* HSMCI1 Receive/Transmit */ +#define XDMAC1_CH_TWI0_TX 2 /* TWI0 Transmit */ +#define XDMAC1_CH_TWI0_RX 3 /* TWI0 Receive */ +#define XDMAC1_CH_TWI1_TX 4 /* TWI1 Transmit */ +#define XDMAC1_CH_TWI1_RX 5 /* TWI1 Receive */ +#define XDMAC1_CH_TWI2_TX 6 /* TWI2 Transmit */ +#define XDMAC1_CH_TWI2_RX 7 /* TWI2 Receive */ +#define XDMAC1_CH_TWI3_TX 8 /* TWI3 Transmit */ +#define XDMAC1_CH_TWI3_RX 9 /* TWI3 Receive */ +#define XDMAC1_CH_SPI0_TX 10 /* SPI0 Transmit */ +#define XDMAC1_CH_SPI0_RX 11 /* SPI0 Receive */ +#define XDMAC1_CH_SPI1_TX 12 /* SPI1 Transmit */ +#define XDMAC1_CH_SPI1_RX 13 /* SPI1 Receive */ +#define XDMAC1_CH_SPI2_TX 14 /* SPI2 Transmit */ +#define XDMAC1_CH_SPI2_RX 15 /* SPI2 Receive */ +#define XDMAC1_CH_USART2_TX 16 /* USART2 Transmit */ +#define XDMAC1_CH_USART2_RX 17 /* USART2 Receive */ +#define XDMAC1_CH_USART3_TX 18 /* USART3 Transmit */ +#define XDMAC1_CH_USART3_RX 19 /* USART3 Receive */ +#define XDMAC1_CH_USART4_TX 20 /* USART4 Transmit */ +#define XDMAC1_CH_USART4_RX 21 /* USART4 Receive */ +#define XDMAC1_CH_UART0_TX 22 /* UART0 Transmit */ +#define XDMAC1_CH_UART0_RX 23 /* UART0 Receive */ +#define XDMAC1_CH_UART1_TX 24 /* UART1 Transmit */ +#define XDMAC1_CH_UART1_RX 25 /* UART1 Receive */ +#define XDMAC1_CH_SSC0_TX 26 /* SSC0 Transmit */ +#define XDMAC1_CH_SSC0_RX 27 /* SSC0 Receive */ +#define XDMAC1_CH_SSC1_TX 28 /* SSC1 Transmit */ +#define XDMAC1_CH_SSC1_RX 29 /* SSC1 Receive */ +#define XDMAC1_CH_DBGU_TX 30 /* DBGU Transmit */ +#define XDMAC1_CH_DBGU_RX 31 /* DBGU Receive */ +#define XDMAC1_CH_ADC_RX 32 /* ADC Receive */ +#define XDMAC1_CH_SMD_TX 33 /* SMD Transmit */ +#define XDMAC1_CH_SMD_RX 34 /* SMD Receive */ + +/* Descriptor structure member definitions **********************************************/ + +/* Next Descriptor Address (32-bit address) */ + +/* Microblock Control */ + +#define CHNEXT_UBC_UBLEN_SHIFT (0) /* Bits 0-23: Microblock Length */ +#define CHNEXT_UBC_UBLEN_MASK (0x00ffffff << CHNEXT_UBC_UBLEN_SHIFT) +# define CHNEXT_UBC_UBLEN(n) ((uint32_t)(n) << CHNEXT_UBC_UBLEN_SHIFT) +#define CHNEXT_UBC_NDE (1 << 24) /* Bit 24: Next Descriptor Enable */ +#define CHNEXT_UBC_NSEN (1 << 25) /* Bit 25: Next Descriptor Source Update */ +#define CHNEXT_UBC_NDEN (1 << 26) /* Bit 26: Next Descriptor Destination Update */ +#define CHNEXT_UBC_NVIEW_SHIFT (27) /* Bits 27-29: Next Descriptor View */ +#define CHNEXT_UBC_NVIEW_MASK (3 << CHNEXT_UBC_NVIEW_SHIFT) +# define CHNEXT_UBC_NVIEW_0 (0 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 0 */ +# define CHNEXT_UBC_NVIEW_1 (1 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 1 */ +# define CHNEXT_UBC_NVIEW_2 (2 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 2 */ +# define CHNEXT_UBC_NVIEW_3 (3 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 3 */ + +/* Source Address (32-bit address) */ +/* Destination Address (32-bit address) */ + +/* Configuration Register */ +/* Block Control */ + +/* Data Stride (32-bit value) */ +/* Source Microblock Stride (32-bit value) */ +/* Destination Microblock Stride (32-bit value) */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +struct chnext_view0_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t cta; /* Transfer Address */ +}; + +struct chnext_view1_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ +}; + +struct chnext_view2_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ + uint32_t cc; /* Configuration Register */ +}; + +struct chnext_view3_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ + uint32_t cc; /* Configuration Register */ + uint32_t cbc; /* Block Control */ + uint32_t cds; /* Data Stride */ + uint32_t csus; /* Source Microblock Stride */ + uint32_t cdus; /* Destination Microblock Stride */ +}; + +#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_XDMAC_H */ diff --git a/arch/arm/src/sama5/sam_adc.c b/arch/arm/src/sama5/sam_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..261434229e67f1c66a66e946e447424e9e866a41 --- /dev/null +++ b/arch/arm/src/sama5/sam_adc.c @@ -0,0 +1,2175 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_adc.c + * + * Copyright (C) 2013, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "cache.h" +#include "chip/sam_adc.h" +#include "chip/sam_pmc.h" +#include "chip/sam_pinmap.h" + +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_pio.h" +#include "sam_dmac.h" +#include "sam_tc.h" +#include "sam_tsd.h" +#include "sam_adc.h" + +#if defined(CONFIG_SAMA5_ADC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Count the number of channels in use */ + +#define SAMA5_CHAN0_INUSE 0 +#define SAMA5_CHAN1_INUSE 0 +#define SAMA5_CHAN2_INUSE 0 +#define SAMA5_CHAN3_INUSE 0 +#define SAMA5_CHAN4_INUSE 0 +#define SAMA5_CHAN5_INUSE 0 +#define SAMA5_CHAN6_INUSE 0 +#define SAMA5_CHAN7_INUSE 0 +#define SAMA5_CHAN8_INUSE 0 +#define SAMA5_CHAN9_INUSE 0 +#define SAMA5_CHAN10_INUSE 0 +#define SAMA5_CHAN11_INUSE 0 + +#ifdef CONFIG_SAMA5_ADC_CHAN0 +# undef SAMA5_CHAN0_INUSE +# define SAMA5_CHAN0_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN1 +# undef SAMA5_CHAN1_INUSE +# define SAMA5_CHAN1_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN2 +# undef SAMA5_CHAN2_INUSE +# define SAMA5_CHAN2_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN3 +# undef SAMA5_CHAN3_INUSE +# define SAMA5_CHAN3_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN4 +# undef SAMA5_CHAN4_INUSE +# define SAMA5_CHAN4_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN5 +# undef SAMA5_CHAN5_INUSE +# define SAMA5_CHAN5_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN6 +# undef SAMA5_CHAN6_INUSE +# define SAMA5_CHAN6_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN7 +# undef SAMA5_CHAN7_INUSE +# define SAMA5_CHAN7_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN8 +# undef SAMA5_CHAN8_INUSE +# define SAMA5_CHAN8_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN9 +# undef SAMA5_CHAN9_INUSE +# define SAMA5_CHAN9_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN10 +# undef SAMA5_CHAN10_INUSE +# define SAMA5_CHAN10_INUSE 1 +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN11 +# undef SAMA5_CHAN11_INUSE +# define SAMA5_CHAN11_INUSE 1 +#endif + +#define SAMA5_NCHANNELS \ + (SAMA5_CHAN0_INUSE + SAMA5_CHAN1_INUSE + SAMA5_CHAN2_INUSE + \ + SAMA5_CHAN3_INUSE + SAMA5_CHAN4_INUSE + SAMA5_CHAN5_INUSE + \ + SAMA5_CHAN6_INUSE + SAMA5_CHAN7_INUSE + SAMA5_CHAN8_INUSE + \ + SAMA5_CHAN9_INUSE + SAMA5_CHAN10_INUSE + SAMA5_CHAN11_INUSE) + +/* Get the set of channel interrupts to enable */ + +#define SAMA5_CHAN0_ENABLE 0 +#define SAMA5_CHAN1_ENABLE 0 +#define SAMA5_CHAN2_ENABLE 0 +#define SAMA5_CHAN3_ENABLE 0 +#define SAMA5_CHAN4_ENABLE 0 +#define SAMA5_CHAN5_ENABLE 0 +#define SAMA5_CHAN6_ENABLE 0 +#define SAMA5_CHAN7_ENABLE 0 +#define SAMA5_CHAN8_ENABLE 0 +#define SAMA5_CHAN9_ENABLE 0 +#define SAMA5_CHAN10_ENABLE 0 +#define SAMA5_CHAN11_ENABLE 0 + +#if defined(CONFIG_SAMA5_ADC_CHAN0) +# undef SAMA5_CHAN0_ENABLE +# define SAMA5_CHAN0_ENABLE ADC_INT_EOC0 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN1) +# undef SAMA5_CHAN1_ENABLE +# define SAMA5_CHAN1_ENABLE ADC_INT_EOC1 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN2) +# undef SAMA5_CHAN2_ENABLE +# define SAMA5_CHAN2_ENABLE ADC_INT_EOC2 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN3) +# undef SAMA5_CHAN3_ENABLE +# define SAMA5_CHAN3_ENABLE ADC_INT_EOC3 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN4) +# undef SAMA5_CHAN4_ENABLE +# define SAMA5_CHAN4_ENABLE ADC_INT_EOC4 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN5) +# undef SAMA5_CHAN5_ENABLE +# define SAMA5_CHAN5_ENABLE ADC_INT_EOC5 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN6) +# undef SAMA5_CHAN6_ENABLE +# define SAMA5_CHAN6_ENABLE ADC_INT_EOC6 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN7) +# undef SAMA5_CHAN7_ENABLE +# define SAMA5_CHAN7_ENABLE ADC_INT_EOC7 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN8) +# undef SAMA5_CHAN8_ENABLE +# define SAMA5_CHAN8_ENABLE ADC_INT_EOC8 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN9) +# undef SAMA5_CHAN9_ENABLE +# define SAMA5_CHAN9_ENABLE ADC_INT_EOC9 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN10) +# undef SAMA5_CHAN10_ENABLE +# define SAMA5_CHAN10_ENABLE ADC_INT_EOC10 +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN11) +# undef SAMA5_CHAN11_ENABLE +# define SAMA5_CHAN11_ENABLE ADC_INT_EOC11 +#endif + +#define SAMA5_CHAN_ENABLE \ + (SAMA5_CHAN0_ENABLE | SAMA5_CHAN1_ENABLE | SAMA5_CHAN2_ENABLE | \ + SAMA5_CHAN3_ENABLE | SAMA5_CHAN4_ENABLE | SAMA5_CHAN5_ENABLE | \ + SAMA5_CHAN6_ENABLE | SAMA5_CHAN7_ENABLE | SAMA5_CHAN8_ENABLE | \ + SAMA5_CHAN9_ENABLE | SAMA5_CHAN10_ENABLE | SAMA5_CHAN11_ENABLE) + +/* If we are supporting the analog chang feature, then sure that there + * is a gain setting for each enabled channel. + * + * Valid gain settings are {0, 1, 2, 3} which may be interpreted as + * either {1, 1, 2, 4} if the DIFFx bit in COR register is zero or as + * {0.5, 1, 2, 2} if the DIFFx bit is set. + */ + +#ifdef CONFIG_SAMA5_ADC_ANARCH +# undef CONFIG_SAMA5_ADC_GAIN +# if defined(CONFIG_SAMA5_ADC_CHAN0) && !defined(CONFIG_SAMA5_ADC_GAIN0) +# define CONFIG_SAMA5_ADC_GAIN0 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN1) && !defined(CONFIG_SAMA5_ADC_GAIN1) +# define CONFIG_SAMA5_ADC_GAIN1 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN2) && !defined(CONFIG_SAMA5_ADC_GAIN2) +# define CONFIG_SAMA5_ADC_GAIN2 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN3) && !defined(CONFIG_SAMA5_ADC_GAIN3) +# define CONFIG_SAMA5_ADC_GAIN3 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN4) && !defined(CONFIG_SAMA5_ADC_GAIN4) +# define CONFIG_SAMA5_ADC_GAIN4 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN5) && !defined(CONFIG_SAMA5_ADC_GAIN5) +# define CONFIG_SAMA5_ADC_GAIN5 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN6) && !defined(CONFIG_SAMA5_ADC_GAIN6) +# define CONFIG_SAMA5_ADC_GAIN6 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN7) && !defined(CONFIG_SAMA5_ADC_GAIN7) +# define CONFIG_SAMA5_ADC_GAIN7 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN8) && !defined(CONFIG_SAMA5_ADC_GAIN8) +# define CONFIG_SAMA5_ADC_GAIN8 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN9) && !defined(CONFIG_SAMA5_ADC_GAIN9) +# define CONFIG_SAMA5_ADC_GAIN9 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN10) && !defined(CONFIG_SAMA5_ADC_GAIN10) +# define CONFIG_SAMA5_ADC_GAIN10 1 +# endif +# if defined(CONFIG_SAMA5_ADC_CHAN11) && !defined(CONFIG_SAMA5_ADC_GAIN11) +# define CONFIG_SAMA5_ADC_GAIN11 1 +# endif + +/* Otherwise, make sure the single global gain value is defined */ + +#else +# ifndef CONFIG_SAMA5_ADC_GAIN +# define CONFIG_SAMA5_ADC_GAIN 1 +# endif +# undef CONFIG_SAMA5_ADC_GAIN0 +# undef CONFIG_SAMA5_ADC_GAIN1 +# undef CONFIG_SAMA5_ADC_GAIN2 +# undef CONFIG_SAMA5_ADC_GAIN3 +# undef CONFIG_SAMA5_ADC_GAIN4 +# undef CONFIG_SAMA5_ADC_GAIN5 +# undef CONFIG_SAMA5_ADC_GAIN6 +# undef CONFIG_SAMA5_ADC_GAIN7 +# undef CONFIG_SAMA5_ADC_GAIN8 +# undef CONFIG_SAMA5_ADC_GAIN9 +# undef CONFIG_SAMA5_ADC_GAIN10 +# undef CONFIG_SAMA5_ADC_GAIN11 +#endif + +/* Check timer configuration */ + +#if defined(CONFIG_SAMA5_ADC_TIOATRIG) && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_ADC_TIOATRIG requires CONFIG_SAMA5_TC0 +#endif + +/* Determine the set channels that are available. Not all channels will be + * available if the touch screen is enabled + */ + +#ifdef CONFIG_SAMA5_TSD +# ifdef CONFIG_SAMA5_TSD_5WIRE +# define SAMA5_ADC_CHALL (ADC_CHALL & ~TSD_5WIRE_ALL) +# else +# define SAMA5_ADC_CHALL (ADC_CHALL & ~TSD_4WIRE_ALL) +# endif +#else +# define SAMA5_ADC_CHALL ADC_CHALL +#endif + +/* DMA configuration flags */ + +#ifdef CONFIG_SAMA5_ADC_DMA +# define DMA_FLAGS \ + DMACH_FLAG_FIFOCFG_LARGEST | \ + DMACH_FLAG_PERIPHPID(SAM_IRQ_ADC) | DMACH_FLAG_PERIPHAHB_AHB_IF2 | \ + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \ + DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | DMACH_FLAG_MEMAHB_AHB_IF0 | \ + DMACH_FLAG_MEMWIDTH_16BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4) +#endif + +/* Pick an unused channel number */ + +#if !defined(CONFIG_SAMA5_ADC_CHAN0) +# define SAMA5_ADC_UNUSED 0 +#elif !defined(CONFIG_SAMA5_ADC_CHAN1) +# define SAMA5_ADC_UNUSED 1 +#elif !defined(CONFIG_SAMA5_ADC_CHAN2) +# define SAMA5_ADC_UNUSED 2 +#elif !defined(CONFIG_SAMA5_ADC_CHAN3) +# define SAMA5_ADC_UNUSED 3 +#elif !defined(CONFIG_SAMA5_ADC_CHAN4) +# define SAMA5_ADC_UNUSED 4 +#elif !defined(CONFIG_SAMA5_ADC_CHAN5) +# define SAMA5_ADC_UNUSED 5 +#elif !defined(CONFIG_SAMA5_ADC_CHAN6) +# define SAMA5_ADC_UNUSED 6 +#elif !defined(CONFIG_SAMA5_ADC_CHAN7) +# define SAMA5_ADC_UNUSED 7 +#elif !defined(CONFIG_SAMA5_ADC_CHAN8) +# define SAMA5_ADC_UNUSED 8 +#elif !defined(CONFIG_SAMA5_ADC_CHAN9) +# define SAMA5_ADC_UNUSED 9 +#elif !defined(CONFIG_SAMA5_ADC_CHAN10) +# define SAMA5_ADC_UNUSED 10 +#elif !defined(CONFIG_SAMA5_ADC_CHAN11) +# define SAMA5_ADC_UNUSED 11 +#else +# undef SAMA5_ADC_UNUSED +#endif + +/* Number of DMA samples to collect */ + +#if !defined(CONFIG_SAMA5_ADC_DMA) +# undef CONFIG_SAMA5_ADC_DMASAMPLES +# define CONFIG_SAMA5_ADC_DMASAMPLES 1 +#elif !defined(CONFIG_SAMA5_ADC_DMASAMPLES) +# error CONFIG_SAMA5_ADC_DMASAMPLES must be defined +#elif CONFIG_SAMA5_ADC_DMASAMPLES < 2 +# warning Values of ONFIG_SAMA5_ADC_DMASAMPLES < 2 are inefficient +#endif + +#define SAMA5_ADC_SAMPLES (CONFIG_SAMA5_ADC_DMASAMPLES * SAMA5_NCHANNELS) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the overall state of the ADC */ + +struct sam_adc_s +{ + sem_t exclsem; /* Supports exclusive access to the ADC interface */ + bool initialized; /* The ADC driver is already initialized */ + uint32_t frequency; /* ADC clock frequency */ + +#ifdef SAMA5_ADC_HAVE_CHANNELS +#ifdef CONFIG_SAMA5_ADC_DMA + volatile bool odd; /* Odd buffer is in use */ + volatile bool ready; /* Worker has completed the last set of samples */ + volatile bool enabled; /* DMA data transfer is enabled */ +#endif + struct adc_dev_s *dev; /* A reference to the outer, ADC device container */ + uint32_t pending; /* Pending EOC events */ + struct work_s work; /* Supports the interrupt handling "bottom half" */ +#ifdef CONFIG_SAMA5_ADC_DMA + DMA_HANDLE dma; /* Handle for DMA channel */ +#endif +#ifdef CONFIG_SAMA5_ADC_TIOATRIG + TC_HANDLE tc; /* Handle for the timer channel */ +#endif + + /* DMA sample data buffer */ + +#ifdef CONFIG_SAMA5_ADC_DMA + uint16_t evenbuf[SAMA5_ADC_SAMPLES]; + uint16_t oddbuf[SAMA5_ADC_SAMPLES]; +#endif +#endif /* SAMA5_ADC_HAVE_CHANNELS */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_ADC_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr, + uint32_t regval, uintptr_t address); +#endif + +/* DMA helper functions */ + +#ifdef SAMA5_ADC_HAVE_CHANNELS +#ifdef CONFIG_SAMA5_ADC_DMA +static void sam_adc_dmadone(void *arg); +static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result); +static int sam_adc_dmasetup(struct sam_adc_s *priv, FAR uint8_t *buffer, + size_t buflen); +static void sam_adc_dmastart(struct sam_adc_s *priv); +#endif + +/* ADC interrupt handling */ + +static void sam_adc_endconversion(void *arg); +#endif +static int sam_adc_interrupt(int irq, void *context); + +/* ADC methods */ + +#ifdef SAMA5_ADC_HAVE_CHANNELS +static void sam_adc_reset(struct adc_dev_s *dev); +static int sam_adc_setup(struct adc_dev_s *dev); +static void sam_adc_shutdown(struct adc_dev_s *dev); +static void sam_adc_rxint(struct adc_dev_s *dev, bool enable); +static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg); + +/* Initialization/Configuration */ + +#ifdef CONFIG_SAMA5_ADC_TIOATRIG +static int sam_adc_settimer(struct sam_adc_s *priv, uint32_t frequency, + int channel); +static void sam_adc_freetimer(struct sam_adc_s *priv); +#endif +static int sam_adc_trigger(struct sam_adc_s *priv); +static void sam_adc_autocalibrate(struct sam_adc_s *priv); +static void sam_adc_offset(struct sam_adc_s *priv); +static void sam_adc_gain(struct sam_adc_s *priv); +static void sam_adc_analogchange(struct sam_adc_s *priv); +static void sam_adc_sequencer(struct sam_adc_s *priv); +static void sam_adc_channels(struct sam_adc_s *priv); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef SAMA5_ADC_HAVE_CHANNELS +/* ADC lower half device operations */ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset = sam_adc_reset, + .ao_setup = sam_adc_setup, + .ao_shutdown = sam_adc_shutdown, + .ao_rxint = sam_adc_rxint, + .ao_ioctl = sam_adc_ioctl, +}; +#endif + +/* ADC internal state */ + +static struct sam_adc_s g_adcpriv; + +#ifdef SAMA5_ADC_HAVE_CHANNELS +/* ADC device instance */ + +static struct adc_dev_s g_adcdev; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_adc_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG +static bool sam_adc_checkreg(struct sam_adc_s *priv, bool wr, + uint32_t regval, uintptr_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +#ifdef SAMA5_ADC_HAVE_CHANNELS + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_adc_dmadone + * + * Description: + * This function executes on the worker thread. It is scheduled by + * sam_adc_dmacallback at the complete of each DMA sequenece. There is + * and interlock using ping-pong buffers and boolean values to prevent + * overrunning the worker thread: + * + * oddbuf[]/evenbuf[] - Ping pong buffers are used. The DMA collects + * data in one buffer while the worker thread processes data in the + * other. + * odd - If true, then DMA is active in the oddbuf[]; evenbuf[] holds + * completed DMA data. + * ready - Ping ponging is halted while ready is false; If data overrun + * occurs, then sample data will be lost on one sequence. The worker + * thread sets ready when it has completed processing the last sample + * data. + * + * Input Parameters + * arg - The ADC private data structure cast to (void *) + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_DMA +static void sam_adc_dmadone(void *arg) +{ + struct sam_adc_s *priv = (struct sam_adc_s *)arg; + uint16_t *buffer; + uint16_t *next; + uint16_t sample; + int chan; + int i; + + avdbg("ready=%d enabled=%d\n", priv->enabled, priv->ready); + ASSERT(priv != NULL && !priv->ready); + + /* If the DMA transfer is not enabled, just ignore the data (and do not start + * the next DMA transfer). + */ + + if (priv->enabled) + { + /* Toggle to the next buffer. + * + * buffer - The buffer on which the DMA has just completed + * next - The buffer in which to start the next DMA + */ + + if (priv->odd) + { + buffer = priv->oddbuf; + next = priv->evenbuf; + priv->odd = false; + } + else + { + buffer = priv->evenbuf; + next = priv->oddbuf; + priv->odd = true; + } + + /* Restart the DMA conversion as quickly as possible using the next + * buffer. + * + * REVISIT: In the original design, toggling the ping-pong buffers and + * restarting the DMA was done in the interrupt handler so that the + * next buffer could be filling while the current buffer is being + * processed here on the worker thread. But, unfortunately, + * sam_adcm_dmasetup() cannot be called from an interrupt handler. + * + * A consequence of this is that there is a small window from the time + * that the last set of samples was taken, the worker thread runs, and + * the follow logic restarts the DMA in which samples could be lost! + * + * Without the interrupt level DMA restart logic, there is not really + * any good reason to support the ping-poing buffers at all. + */ + + sam_adc_dmasetup(priv, (FAR uint8_t *)next, + SAMA5_ADC_SAMPLES * sizeof(uint16_t)); + + + /* Invalidate the DMA buffer so that we are guaranteed to reload the + * newly DMAed data from RAM. + */ + + arch_invalidate_dcache((uintptr_t)buffer, + (uintptr_t)buffer + SAMA5_ADC_SAMPLES * sizeof(uint16_t)); + + /* Process each sample */ + + for (i = 0; i < SAMA5_ADC_SAMPLES; i++, buffer++) + { + /* Get the sample and the channel number */ + + chan = (int)((*buffer & ADC_LCDR_CHANB_MASK) >> ADC_LCDR_CHANB_SHIFT); + sample = ((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT); + + /* And give the sample data to the ADC upper half */ + + (void)adc_receive(priv->dev, chan, sample); + } + } + + /* We are ready to handle the next sample sequence */ + + priv->ready = true; +} +#endif + +/**************************************************************************** + * Name: sam_adc_dmastart + * + * Description: + * Initiate DMA sampling. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_DMA +static void sam_adc_dmastart(struct sam_adc_s *priv) +{ + /* Make sure that the worker is available and that DMA is not disabled */ + + if (priv->ready && priv->enabled) + { + priv->odd = false; /* Start with the even buffer */ + sam_adc_dmasetup(priv, (FAR uint8_t *)priv->evenbuf, + SAMA5_ADC_SAMPLES * sizeof(uint16_t)); + } +} +#endif + +/**************************************************************************** + * Name: sam_adc_dmacallback + * + * Description: + * Called when one ADC DMA sequence completes. This function defers + * processing of the samples to sam_adc_dmadone which runs on the worker + * thread. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_DMA +static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_adc_s *priv = (struct sam_adc_s *)arg; + int ret; + + allvdbg("ready=%d enabled=%d\n", priv->enabled, priv->ready); + DEBUGASSERT(priv->ready); + + /* Check of the bottom half is keeping up with us. + * + * ready == false: Would mean that the worker thready has not ran since + * the the last DMA callback. + * enabled == false: Means that the upper half has asked us nicely to stop + * transferring DMA data. + */ + + if (priv->ready && priv->enabled) + { + /* Verify that the worker is available */ + + DEBUGASSERT(priv->work.worker == NULL); + + /* Mark the work as busy and schedule the DMA done processing to + * occur on the worker thread. + */ + + priv->ready = false; + + ret = work_queue(HPWORK, &priv->work, sam_adc_dmadone, priv, 0); + if (ret != 0) + { + alldbg("ERROR: Failed to queue work: %d\n", ret); + } + } + + /* REVISIT: There used to be logic here to toggle the ping-pong buffers and + * to restart the DMA conversion. This would allow refilling one buffer + * while the worker processes the other buffer that was just filled. But, + * unfortunately, sam_adcm_dmasetup() and dma_rxsetup cannot be called + * from an interrupt handler. + * + * A consequence of this is that there is a small window from the time + * that the last set of samples was taken, the worker thread runs, and the + * logic on the worker thread restarts the DMA. Samples trigger during + * this window will be be lost! + * + * Without this logic, there is not really any strong reason to support + * the ping-poing buffers at all. + */ +} +#endif + +/**************************************************************************** + * Name: sam_adc_dmasetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * priv - An instance of the ADC device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_DMA +static int sam_adc_dmasetup(FAR struct sam_adc_s *priv, FAR uint8_t *buffer, + size_t buflen) +{ + uint32_t paddr; + uint32_t maddr; + + avdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Physical address of the ADC LCDR register and of the buffer location in + * RAM. + */ + + paddr = sam_physregaddr(SAM_ADC_LCDR); + maddr = sam_physramaddr((uintptr_t)buffer); + + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->dma, paddr, maddr, buflen); + + /* Start the DMA */ + + sam_dmastart(priv->dma, sam_adc_dmacallback, priv); + return OK; +} +#endif + +/**************************************************************************** + * ADC interrupt handling + ****************************************************************************/ +/**************************************************************************** + * Name: sam_adc_endconversion + * + * Description: + * This function executes on the worker thread. It is scheduled by + * sam_adc_interrupt whenever any enabled end-of-conversion event occurs. + * All EOC interrupts are disabled when this function runs. + * sam_adc_endconversion will re-enable EOC interrupts when it completes + * processing all pending EOC events. + * + * Input Parameters + * arg - The ADC private data structure cast to (void *) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_adc_endconversion(void *arg) +{ + struct sam_adc_s *priv = (struct sam_adc_s *)arg; + uint32_t regval; + uint32_t pending; + int chan; + + ASSERT(priv != NULL); + avdbg("pending=%08x\n", priv->pending); + + /* Get the set of unmasked, pending ADC interrupts */ + + pending = priv->pending; + + /* Get exclusive access to the driver data structure */ + + sam_adc_lock(priv); + + /* Check for the end of conversion event on each channel */ + + for (chan = 0; chan < SAM_ADC_NCHANNELS && pending != 0; chan++) + { + uint32_t bit = ADC_INT_EOC(chan); + if ((pending & bit) != 0) + { + /* Read the ADC sample and pass it to the upper half */ + + regval = sam_adc_getreg(priv, SAM_ADC_CDR(chan)); + (void)adc_receive(priv->dev, chan, regval & ADC_CDR_DATA_MASK); + pending &= ~bit; + } + } + + /* Exit, re-enabling ADC interrupts */ + + sam_adc_putreg(priv, SAM_ADC_IER, SAMA5_CHAN_ENABLE); + + /* Release our lock on the ADC structure */ + + sam_adc_unlock(priv); +} +#endif /* SAMA5_ADC_HAVE_CHANNELS */ + +/**************************************************************************** + * Name: sam_adc_interrupt + * + * Description: + * ADC interrupt handler + * + ****************************************************************************/ + +static int sam_adc_interrupt(int irq, void *context) +{ + struct sam_adc_s *priv = &g_adcpriv; + uint32_t isr; + uint32_t imr; + uint32_t pending; + + /* Get the set of unmasked, pending ADC interrupts */ + + isr = sam_adc_getreg(priv, SAM_ADC_ISR); + imr = sam_adc_getreg(priv, SAM_ADC_IMR); + pending = isr & imr; + + /* Handle pending touchscreen interrupts */ + +#ifdef CONFIG_SAMA5_TSD + if ((pending & ADC_TSD_ALLINTS) != 0) + { + /* Let the touchscreen handle its interrupts. Pass the pending + * interrupt set PLUS the pen status bit. + */ + + sam_tsd_interrupt(isr & (imr | ADC_SR_PENS)); + pending &= ~ADC_TSD_ALLINTS; + } +#endif + +#ifdef SAMA5_ADC_HAVE_CHANNELS + /* Check for end-of-conversion interrupts */ + + if ((pending & ADC_INT_EOCALL) != 0) + { + int ret; + + /* Disable further end-of-conversion interrupts. End-of-conversion + * interrupts will be re-enabled after the worker thread executes. + */ + + sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_EOCALL); + + /* Save the set of pending interrupts for the bottom half (in case any + * were cleared by reading the ISR). + */ + + priv->pending = pending; + + /* Transfer processing to the worker thread. Since end-of-conversion + * interrupts are disabled while the work is pending, no special action + * should be required to protected the work queue. + */ + + DEBUGASSERT(priv->work.worker == NULL); + ret = work_queue(HPWORK, &priv->work, sam_adc_endconversion, priv, 0); + if (ret != 0) + { + alldbg("ERROR: Failed to queue work: %d\n", ret); + } + + pending &= ~ADC_INT_EOCALL; + } +#endif + + /* Make sure that all interrupts were handled */ + + DEBUGASSERT(pending == 0); + return OK; +} + +#ifdef SAMA5_ADC_HAVE_CHANNELS + +/**************************************************************************** + * ADC methods + ****************************************************************************/ +/**************************************************************************** + * Name: sam_adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before sam_adc_setup() and on error conditions. + * + ****************************************************************************/ + +static void sam_adc_reset(struct adc_dev_s *dev) +{ +#ifdef CONFIG_SAMA5_ADC_DMA + struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv; +#endif + uint32_t regval; + + avdbg("Resetting..\n"); + + /* NOTE: We can't really reset the ADC hardware without losing the + * touchscreen configuration. + */ + + /* Stop any ongoing DMA */ + +#ifdef CONFIG_SAMA5_ADC_DMA + if (priv->dma) + { + sam_dmastop(priv->dma); + } +#endif + + /* Stop an release any timer */ + +#ifdef CONFIG_SAMA5_ADC_TIOATRIG + sam_adc_freetimer(priv); +#endif + + /* Disable all EOC interrupts */ + + sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_EOCALL); + + /* Disable all channels */ + + sam_adc_putreg(priv, SAM_ADC_CHDR, SAMA5_ADC_CHALL); + + /* Disable the sequencer and analog change */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~(ADC_MR_USEQ | ADC_MR_ANACH); + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* Reset gain, offset, differential modes */ + + sam_adc_putreg(priv, SAM_ADC_CGR, 0); + sam_adc_putreg(priv, SAM_ADC_COR, 0); + +#ifndef CONFIG_SAMA5_ADC_SWTRIG + /* Select software trigger (i.e., basically no trigger) */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_TRGSEL_MASK; + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + regval = sam_adc_getreg(priv, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_NOTRIG; + sam_adc_putreg(priv, SAM_ADC_TRGR, regval); +#endif +} + +/**************************************************************************** + * Name: sam_adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. Interrupts + * are all disabled upon return. + * + ****************************************************************************/ + +static int sam_adc_setup(struct adc_dev_s *dev) +{ + struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv; + uint32_t regval; + + avdbg("Setup\n"); + + /* Enable channel number tag. This bit will force the channel number (CHNB) + * to be included in the LDCR register content. + */ + + regval = sam_adc_getreg(priv, SAM_ADC_EMR); + regval |= ADC_EMR_TAG; + sam_adc_putreg(priv, SAM_ADC_EMR, regval); + + /* Enable (or disable) the sequencer */ + + sam_adc_sequencer(priv); + + /* Enable ADC channels */ + + sam_adc_channels(priv); + + /* Enable/disable analog change. This feature permits different settings + * per channel. + */ + + sam_adc_analogchange(priv); + + /* Set gain */ + + sam_adc_gain(priv); + + /* Set offset and single/differential mode */ + + sam_adc_offset(priv); + + /* Perform Auto Calibration */ + + sam_adc_autocalibrate(priv); + +#ifdef CONFIG_SAMA5_ADC_DMA + /* Initiate DMA transfers */ + + priv->ready = true; /* Worker is avaiable */ + priv->enabled = true; /* Transfers are enabled */ + + sam_adc_dmastart(priv); + +#else + /* Enable end-of-conversion interrupts for all enabled channels. */ + + sam_adc_putreg(priv, SAM_ADC_IER, SAMA5_CHAN_ENABLE); + +#endif + + /* Configure trigger mode and start conversion */ + + return sam_adc_trigger(priv); +} + +/**************************************************************************** + * Name: sam_adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + ****************************************************************************/ + +static void sam_adc_shutdown(struct adc_dev_s *dev) +{ +#ifdef CONFIG_SAMA5_ADC_DMA + struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv; +#endif + + avdbg("Shutdown\n"); + + /* Reset the ADC peripheral */ + + sam_adc_reset(dev); + + /* Disable ADC interrupts at the level of the AIC */ + + up_disable_irq(SAM_IRQ_ADC); + + /* Then detach the ADC interrupt handler. */ + + irq_detach(SAM_IRQ_ADC); +} + +/**************************************************************************** + * Name: sam_adc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void sam_adc_rxint(struct adc_dev_s *dev, bool enable) +{ +#ifdef CONFIG_SAMA5_ADC_DMA + struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv; +#endif + + avdbg("enable=%d\n", enable); + +#ifdef CONFIG_SAMA5_ADC_DMA + /* Ignore redundant requests */ + + if (priv->enabled != enable) + { + /* Set a flag. If disabling, the DMA sequence will terminate at the + * completion of the next DMA. + */ + + priv->enabled = enable; + + /* If enabling, then we need to restart the DMA transfer */ + + sam_adc_dmastart(priv); + } + +#else + /* Are we enabling or disabling? */ + + if (enable) + { + /* Enable channel interrupts */ + + sam_adc_putreg(priv, SAM_ADC_IER, SAMA5_CHAN_ENABLE); + } + else + { + /* Disable channel interrupts */ + + sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_EOCALL); + } +#endif +} + +/**************************************************************************** + * Name: sam_adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int sam_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SAMA5_ADC_SWTRIG + struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv; +#endif + int ret = OK; + + avdbg("cmd=%d arg=%ld\n", cmd, arg); + + switch (cmd) + { +#ifdef CONFIG_SAMA5_ADC_SWTRIG + case ANIOC_TRIGGER: /* Software trigger */ + { + sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_START); /* Start conversion */ + } + break; +#endif + + /* Unsupported or invalid command */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Initialization/Configuration + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_adc_settimer + * + * Description: + * Configure a timer to trigger the sampling periodically + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_TIOATRIG +static int sam_adc_settimer(struct sam_adc_s *priv, uint32_t frequency, + int channel) +{ + uint32_t div; + uint32_t tcclks; + uint32_t mode; + uint32_t fdiv; + uint32_t regval; + int ret; + + avdbg("frequency=%ld channel=%d\n", (long)frequency, channel); + DEBUGASSERT(priv && frequency > 0); + + /* Configure TC for a 1Hz frequency and trigger on RC compare. */ + + ret = sam_tc_divisor(frequency, &div, &tcclks); + if (ret < 0) + { + adbg("ERROR: sam_tc_divisor failed: %d\n", ret); + return ret; + } + + /* Set the timer/counter waveform mode the the clock input slected by + * sam_tc_divisor() + */ + + mode = ((tcclks << TC_CMR_TCCLKS_SHIFT) | /* Use selected TCCLKS value */ + TC_CMR_WAVSEL_UPRC | /* UP mode w/ trigger on RC Compare */ + TC_CMR_WAVE | /* Wave mode */ + TC_CMR_ACPA_CLEAR | /* RA Compare Effect on TIOA: Clear */ + TC_CMR_ACPC_SET); /* RC effect on TIOA: Set */ + + /* Now allocate and configure the channel */ + + priv->tc = sam_tc_allocate(channel, mode); + if (!priv->tc) + { + adbg("ERROR: Failed to allocate channel %d mode %08x\n", channel, mode); + return -EINVAL; + } + + /* The divider returned by sam_tc_divisor() is the reload value that will + * achieve a 1Hz rate. We need to multiply this to get the desired + * frequency. sam_tc_divisor() should have already assure that we can + * do this without overflowing a 32-bit unsigned integer. + */ + + fdiv = div * frequency; + DEBUGASSERT(div > 0 && div <= fdiv); /* Will check for integer overflow */ + + /* Calculate the actual counter value from this divider and the tc input + * frequency. + */ + + regval = sam_tc_infreq() / fdiv; + + /* Set up TC_RA and TC_RC. The frequency is determined by RA and RC: TIOA is + * cleared on RA match; TIOA is set on RC match. + */ + + sam_tc_setregister(priv->tc, TC_REGA, regval >> 1); + sam_tc_setregister(priv->tc, TC_REGC, regval); + + /* And start the timer */ + + sam_tc_start(priv->tc); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_adc_freetimer + * + * Description: + * Configure a timer to trigger the sampling periodically + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_TIOATRIG +static void sam_adc_freetimer(struct sam_adc_s *priv) +{ + /* Is a timer allocated? */ + + avdbg("tc=%p\n", priv->tc); + + if (priv->tc) + { + /* Yes.. stop it and free it */ + + sam_tc_stop(priv->tc); + sam_tc_free(priv->tc); + priv->tc = NULL; + } +} +#endif + +/**************************************************************************** + * Name: sam_adc_trigger + * + * Description: + * Configure trigger mode and start conversion. + * + ****************************************************************************/ + +static int sam_adc_trigger(struct sam_adc_s *priv) +{ + uint32_t regval; + int ret = OK; + +#if defined(CONFIG_SAMA5_ADC_SWTRIG) + avdbg("Setup software trigger\n"); + + /* Configure the software trigger */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_TRGSEL_MASK; + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* No trigger, only software trigger can start conversions */ + + regval = sam_adc_getreg(priv, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_NOTRIG; + sam_adc_putreg(priv, SAM_ADC_TRGR, regval); + +#elif defined(CONFIG_SAMA5_ADC_ADTRG) + avdbg("Setup ADTRG trigger\n"); + + /* Configure the trigger via the external ADTRG signal */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_TRGSEL_MASK; + regval |= ADC_MR_TRGSEL_ADC_ADTRIG; + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* External trigger edge selection */ + + regval = sam_adc_getreg(priv, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + +#if defined(CONFIG_SAMA5_ADC_ADTRG_RISING) + regval |= ADC_TRGR_TRGMOD_EXTRISE; +#elif defined(CONFIG_SAMA5_ADC_ADTRG_FALLING) + regval |= ADC_TRGR_TRGMOD_EXTFALL; +#elif defined(CONFIG_SAMA5_ADC_ADTRG_BOTH) + regval |= ADC_TRGR_TRGMOD_EXTBOTH; +#else +# error External trigger edge not defined +#endif + + sam_adc_putreg(priv, SAM_ADC_TRGR, regval); + +#elif defined(CONFIG_SAMA5_ADC_TIOATRIG) + avdbg("Setup timer/counter trigger\n"); + + /* Start the timer */ + +#if defined(CONFIG_SAMA5_ADC_TIOA0TRIG) + ret = sam_adc_settimer(priv, CONFIG_SAMA5_ADC_TIOAFREQ, TC_CHAN0); +#elif defined(CONFIG_SAMA5_ADC_TIOA1TRIG) + ret = sam_adc_settimer(priv, CONFIG_SAMA5_ADC_TIOAFREQ, TC_CHAN1); +#elif defined(CONFIG_SAMA5_ADC_TIOA2TRIG) + ret = sam_adc_settimer(priv, CONFIG_SAMA5_ADC_TIOAFREQ, TC_CHAN2); +#else +# error Timer/counter for trigger not defined + ret = -ENOSYS; +#endif + if (ret < 0) + { + adbg("ERROR: sam_adc_settimer failed: %d\n", ret); + return ret; + } + + /* Configure to trigger using Timer/counter 0, channel 1, 2, or 3. + * NOTE: This trigger option depends on having properly configuer + * timer/counter 0 to provide this output. That is done independently + * the the timer/counter driver. + */ + + /* Set TIOAn trigger where n=0, 1, or 2 */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_TRGSEL_MASK; + +#if defined(CONFIG_SAMA5_ADC_TIOA0TRIG) + regval |= ADC_MR_TRGSEL_TIOA0; /* Timer/counter 0 channel 0 output A */ +#elif defined(CONFIG_SAMA5_ADC_TIOA1TRIG) + regval |= ADC_MR_TRGSEL_TIOA1; /* Timer/counter 0 channel 1 output A */ +#elif defined(CONFIG_SAMA5_ADC_TIOA2TRIG) + regval |= ADC_MR_TRGSEL_TIOA2; /* Timer/counter 0 channel 2 output A */ +#else +# error Timer/counter for trigger not defined +#endif + + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* Timer trigger edge selection */ + + regval = sam_adc_getreg(priv, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + +#if defined(CONFIG_SAMA5_ADC_TIOA_RISING) + regval |= ADC_TRGR_TRGMOD_EXTRISE; +#elif defined(CONFIG_SAMA5_ADC_TIOA_FALLING) + regval |= ADC_TRGR_TRGMOD_EXTFALL; +#elif defined(CONFIG_SAMA5_ADC_TIOA_BOTH) + regval |= ADC_TRGR_TRGMOD_EXTBOTH; +#else +# error External trigger edge not defined +#endif + + sam_adc_putreg(priv, SAM_ADC_TRGR, regval); + +#else +# error "Undefined ADC trigger" +#endif + + return ret; +} + +/**************************************************************************** + * Name: sam_adc_autocalibrate + * + * Description: + * Perform ADC auto-calibration. + * + ****************************************************************************/ + +static void sam_adc_autocalibrate(struct sam_adc_s *priv) +{ +#ifdef CONFIG_SAMA5_ADC_AUTOCALIB + uint32_t regval; + + avdbg("Entry\n"); + + /* Launch an automatic calibration of the ADC cell on next sequence */ + + regval = sam_adc_getreg(priv, SAM_ADC_CR); + regval |= ADC_CR_AUTOCAL; + sam_adc_putreg(priv, SAM_ADC_CR, regval); + + /* Wait for auto calibration to complete */ + + while (sam_adc_getreg(priv, SAM_ADC_ISR) & ADC_ISR_EOCAL) != ADC_ISR_EOCAL); +#endif +} + +/**************************************************************************** + * Name: sam_adc_offset + * + * Description: + * Configure ADC offset. Also while we are modifying the COR register, + * configure differential mode if selected. + * + ****************************************************************************/ + +static void sam_adc_offset(struct sam_adc_s *priv) +{ + uint32_t regval = 0; + + avdbg("Entry\n"); + +#ifdef CONFIG_SAMA5_ADC_ANARCH + /* Set the offset for each enabled channel. This centers the analog signal + * on Vrefin/2 before the gain scaling. The Offset applied is: (G-1)Vrefin/2 + * where G is the gain applied. The default is no offset. + */ + +#if defined(CONFIG_SAMA5_ADC_CHAN0) && defined(CONFIG_SAMA5_ADC_OFFSET0) + regval |= ADC_COR_OFF0; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN1) && defined(CONFIG_SAMA5_ADC_OFFSET1) + regval |= ADC_COR_OFF1; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN2) && defined(CONFIG_SAMA5_ADC_OFFSET2) + regval |= ADC_COR_OFF2; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN3) && defined(CONFIG_SAMA5_ADC_OFFSET3) + regval |= ADC_COR_OFF3; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN4) && defined(CONFIG_SAMA5_ADC_OFFSET4) + regval |= ADC_COR_OFF4; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN5) && defined(CONFIG_SAMA5_ADC_OFFSET5) + regval |= ADC_COR_OFF5; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN6) && defined(CONFIG_SAMA5_ADC_OFFSET6) + regval |= ADC_COR_OFF6; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN7) && defined(CONFIG_SAMA5_ADC_OFFSET7) + regval |= ADC_COR_OFF7; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN8) && defined(CONFIG_SAMA5_ADC_OFFSET8) + regval |= ADC_COR_OFF8; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN9) && defined(CONFIG_SAMA5_ADC_OFFSET9) + regval |= ADC_COR_OFF9; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN10) && defined(CONFIG_SAMA5_ADC_OFFSET10) + regval |= ADC_COR_OFF10; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN11) && defined(CONFIG_SAMA5_ADC_OFFSET11) + regval |= ADC_COR_OFF11; +#endif + + /* Set the differential mode of operation for each enabled channel. + * The default is single-ended operation. + */ + +#if defined(CONFIG_SAMA5_ADC_CHAN0) && defined(CONFIG_SAMA5_ADC_DIFFMODE0) + regval |= ADC_COR_DIFF0; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN1) && defined(CONFIG_SAMA5_ADC_DIFFMODE1) + regval |= ADC_COR_DIFF1; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN2) && defined(CONFIG_SAMA5_ADC_DIFFMODE2) + regval |= ADC_COR_DIFF2; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN3) && defined(CONFIG_SAMA5_ADC_DIFFMODE3) + regval |= ADC_COR_DIFF3; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN4) && defined(CONFIG_SAMA5_ADC_DIFFMODE4) + regval |= ADC_COR_DIFF4; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN5) && defined(CONFIG_SAMA5_ADC_DIFFMODE5) + regval |= ADC_COR_DIFF5; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN6) && defined(CONFIG_SAMA5_ADC_DIFFMODE6) + regval |= ADC_COR_DIFF6; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN7) && defined(CONFIG_SAMA5_ADC_DIFFMODE7) + regval |= ADC_COR_DIFF7; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN8) && defined(CONFIG_SAMA5_ADC_DIFFMODE8) + regval |= ADC_COR_DIFF8; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN9) && defined(CONFIG_SAMA5_ADC_DIFFMODE9) + regval |= ADC_COR_DIFF9; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN10) && defined(CONFIG_SAMA5_ADC_DIFFMODE10) + regval |= ADC_COR_DIFF10; +#endif +#if defined(CONFIG_SAMA5_ADC_CHAN11) && defined(CONFIG_SAMA5_ADC_DIFFMODE11) + regval |= ADC_COR_DIFF11; +#endif + +#else + /* Set offset and differential mode only on channel 0. This will be + * used for all channel. + */ + +#ifdef CONFIG_SAMA5_ADC_OFFSET + regval |= ADC_COR_OFF0; +#endif +#ifdef CONFIG_SAMA5_ADC_DIFFMODE + regval |= ADC_COR_DIFF0; +#endif +#endif + + /* Save the updated COR register value */ + + sam_adc_putreg(priv, SAM_ADC_COR, regval); +} + +/**************************************************************************** + * Name: sam_adc_gain + * + * Description: + * Configure ADC gain. + * + ****************************************************************************/ + +static void sam_adc_gain(struct sam_adc_s *priv) +{ +#ifdef CONFIG_SAMA5_ADC_ANARCH + uint32_t regval; + + avdbg("Entry\n"); + + /* Set the gain for each enabled channel */ + + regval = 0; + +#ifdef CONFIG_SAMA5_ADC_CHAN0 + regval |= ADC_CGR_GAIN0(CONFIG_SAMA5_ADC_GAIN0); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN1 + regval |= ADC_CGR_GAIN1(CONFIG_SAMA5_ADC_GAIN1); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN2 + regval |= ADC_CGR_GAIN2(CONFIG_SAMA5_ADC_GAIN2); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN3 + regval |= ADC_CGR_GAIN3(CONFIG_SAMA5_ADC_GAIN3); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN4 + regval |= ADC_CGR_GAIN4(CONFIG_SAMA5_ADC_GAIN4); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN5 + regval |= ADC_CGR_GAIN5(CONFIG_SAMA5_ADC_GAIN5); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN6 + regval |= ADC_CGR_GAIN6(CONFIG_SAMA5_ADC_GAIN6); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN7 + regval |= ADC_CGR_GAIN7(CONFIG_SAMA5_ADC_GAIN7); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN8 + regval |= ADC_CGR_GAIN8(CONFIG_SAMA5_ADC_GAIN8); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN9 + regval |= ADC_CGR_GAIN9(CONFIG_SAMA5_ADC_GAIN9); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN10 + regval |= ADC_CGR_GAIN10(CONFIG_SAMA5_ADC_GAIN10); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN11 + regval |= ADC_CGR_GAIN11(CONFIG_SAMA5_ADC_GAIN11); +#endif + + sam_adc_putreg(priv, SAM_ADC_CGR, regval); + +#else + avdbg("Gain=%d\n", CONFIG_SAMA5_ADC_GAIN); + + /* Set GAIN0 only. GAIN0 will be used for all channels. */ + + sam_adc_putreg(priv, SAM_ADC_CGR, ADC_CGR_GAIN0(CONFIG_SAMA5_ADC_GAIN)); +#endif +} + +/**************************************************************************** + * Name: sam_adc_analogchange + * + * Description: + * Configure analog change. This features permits different analog + * settings per channel. + * + ****************************************************************************/ + +static void sam_adc_analogchange(struct sam_adc_s *priv) +{ + uint32_t regval; + + avdbg("Entry\n"); + + /* Enable/disable the analog change feature */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + +#ifdef CONFIG_SAMA5_ADC_ANARCH + /* Disable analog change: No analog change on channel switching: DIFF0, + * GAIN0 and OFF0 are used for all channels. + */ + + regval |= ADC_MR_ANACH; +#else + /* Enable analog change: Allows different analog settings for each + * channel using the ADC_CGR and ADC_COR Registers. + */ + + regval &= ~ADC_MR_ANACH; +#endif + + sam_adc_putreg(priv, SAM_ADC_MR, regval); +} + +/**************************************************************************** + * Name: sam_adc_sequencer + * + * Description: + * Configure and enable the sequencer + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_SEQUENCER +static void sam_adc_setseqr(int chan, uint32_t *seqr1, uint32_t *seqr2, int seq) +{ + if (seq > 8) + { + *seqr2 |= ADC_SEQR2_USCH(seq, chan); + } + else + { + *seqr1 |= ADC_SEQR1_USCH(seq, chan); + } + + avdbg("chan=%d seqr1=%08x seqr2=%08x seq=%d\n", chan, *seqr1, *seqr2, seq); +} +#endif + +static void sam_adc_sequencer(struct sam_adc_s *priv) +{ +#ifdef CONFIG_SAMA5_ADC_SEQUENCER + uint32_t regval; + uint32_t seqr1; + uint32_t seqr2; + int seq; + + avdbg("Setup sequencer\n"); + + /* Set user configured channel sequence */ + + seqr1 = 0; + seqr2 = 0; + seq = 1; + +#ifdef CONFIG_SAMA5_ADC_CHAN0 + sam_adc_setseqr(0, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN1 + sam_adc_setseqr(1, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN2 + sam_adc_setseqr(2, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN3 + sam_adc_setseqr(3, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN4 + sam_adc_setseqr(4, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN5 + sam_adc_setseqr(5, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN6 + sam_adc_setseqr(6, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN7 + sam_adc_setseqr(7, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN8 + sam_adc_setseqr(8, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN9 + sam_adc_setseqr(9, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN10 + sam_adc_setseqr(10, &seqr1, &seqr2, seq++); +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN11 + sam_adc_setseqr(11, &seqr1, &seqr2, seq++); +#endif + + /* If not all channels are used, then program an unused channel number + * into the remaining slots. If we don't do this, we will get multiple + * samples for the enabled channels. + */ + +#ifdef SAMA5_ADC_UNUSED + for (; seq < 9; seq++) + { + seqr1 |= ADC_SEQR1_USCH(seq, SAMA5_ADC_UNUSED); + } + + for (; seq < 12; seq++) + { + seqr2 |= ADC_SEQR2_USCH(seq, SAMA5_ADC_UNUSED); + } +#endif + + /* Save the new values to the SEQR1 and SEQR2 registers */ + + sam_adc_putreg(priv, SAM_ADC_SEQR1, seqr1); + sam_adc_putreg(priv, SAM_ADC_SEQR2, seqr2); + + /* Enable sequencer. Any channel that is not enabled will be skipped by + * the sequencer (that is why we programmed the unused channels above. + */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval |= ADC_MR_USEQ; + sam_adc_putreg(priv, SAM_ADC_MR, regval); + +#else + uint32_t regval; + + avdbg("Disable sequencer\n"); + + /* Disable the sequencer */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_USEQ; + sam_adc_putreg(priv, SAM_ADC_MR, regval); + +#endif +} + +/**************************************************************************** + * Name: sam_adc_channels + * + * Description: + * Configure and enable the channels + * + ****************************************************************************/ + +static void sam_adc_channels(struct sam_adc_s *priv) +{ + uint32_t regval; + + avdbg("Entry\n"); + + /* Enable channels. */ + + regval = 0; + +#ifdef CONFIG_SAMA5_ADC_CHAN0 + regval |= ADC_CH0; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN1 + regval |= ADC_CH1; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN2 + regval |= ADC_CH2; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN3 + regval |= ADC_CH3; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN4 + regval |= ADC_CH4; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN5 + regval |= ADC_CH5; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN6 + regval |= ADC_CH6; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN7 + regval |= ADC_CH7; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN8 + regval |= ADC_CH8; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN9 + regval |= ADC_CH9; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN10 + regval |= ADC_CH10; +#endif + +#ifdef CONFIG_SAMA5_ADC_CHAN11 + regval |= ADC_CH11; +#endif + + sam_adc_putreg(priv, SAM_ADC_CHER, regval); +} +#endif /* SAMA5_ADC_HAVE_CHANNELS */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_adc_initialize + * + * Description: + * Initialize the adc + * + * Returned Value: + * Valid can device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s *sam_adc_initialize(void) +{ + struct sam_adc_s *priv = &g_adcpriv; + uint32_t regval; + uint32_t mck; + int ret; + + /* Have we already been initialized? If yes, than just hand out the + * interface one more time. + */ + + if (!priv->initialized) + { + avdbg("Initializing...\n"); + + /* Disable ADC peripheral clock */ + + sam_adc_disableclk(); + + /* Configure ADC pins */ + +#ifdef CONFIG_SAMA5_ADC_CHAN0 + sam_configpio(PIO_ADC_AD0); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN1 + sam_configpio(PIO_ADC_AD1); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN2 + sam_configpio(PIO_ADC_AD2); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN3 + sam_configpio(PIO_ADC_AD3); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN4 + sam_configpio(PIO_ADC_AD4); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN5 + sam_configpio(PIO_ADC_AD5); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN6 + sam_configpio(PIO_ADC_AD6); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN7 + sam_configpio(PIO_ADC_AD7); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN8 + sam_configpio(PIO_ADC_AD8); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN9 + sam_configpio(PIO_ADC_AD9); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN10 + sam_configpio(PIO_ADC_AD10); +#endif +#ifdef CONFIG_SAMA5_ADC_CHAN11 + sam_configpio(PIO_ADC_AD11); +#endif + +#ifdef CONFIG_SAMA5_ADC_ADTRG + sam_configpio(PIO_ADC_TRG); +#endif + + /* Initialize the public ADC device data structure */ + + g_adcdev.ad_ops = &g_adcops; + g_adcdev.ad_priv = priv; + + /* Initialize the private ADC device data structure */ + + sem_init(&priv->exclsem, 0, 1); + priv->dev = &g_adcdev; + +#ifdef CONFIG_SAMA5_ADC_DMA + /* Allocate a DMA channel from DMAC1 */ + + priv->dma = sam_dmachannel(1, DMA_FLAGS); + DEBUGASSERT(priv->dma); +#endif + + /* Determine the maximum ADC peripheral clock frequency */ + + mck = BOARD_MCK_FREQUENCY; + if (mck <= SAM_ADC_MAXPERCLK) + { + priv->frequency = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= SAM_ADC_MAXPERCLK) + { + priv->frequency = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= SAM_ADC_MAXPERCLK) + { + priv->frequency = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else if ((mck >> 3) <= SAM_ADC_MAXPERCLK) + { + priv->frequency = (mck >> 3); + regval = PMC_PCR_DIV8; + } + else + { + adbg("ERROR: Cannot realize ADC input frequency\n"); + return NULL; + } + + /* Set the maximum ADC peripheral clock frequency */ + + regval |= PMC_PCR_PID(SAM_PID_ADC) | PMC_PCR_CMD | PMC_PCR_EN; + sam_adc_putreg(priv, SAM_PMC_PCR, regval); + + /* Enable the ADC peripheral clock */ + + sam_adc_enableclk(); + + /* Reset the ADC controller */ + + sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST); + + /* Reset Mode Register */ + + sam_adc_putreg(priv, SAM_ADC_MR, 0); + + /* Set the MCK clock prescaler: ADCClock = MCK / ((PRESCAL+1)*2) */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~ADC_MR_PRESCAL_MASK; + regval |= ADC_MR_PRESCAL(BOARD_ADC_PRESCAL); + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* Formula: + * Startup Time = startup value / ADCClock + * Transfer Time = (TRANSFER * 2 + 3) / ADCClock + * Tracking Time = (TRACKTIM + 1) / ADCClock + * Settling Time = settling value / ADCClock + * For example, ADC clock = 6MHz (166.7 ns) + * Startup time = 512 / 6MHz = 85.3 us + * Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns + * Tracking Time = (0 + 1) / 6MHz = 166.7 ns + * Settling Time = 3 / 6MHz = 500 ns + */ + + /* Set ADC timing */ + + regval = sam_adc_getreg(priv, SAM_ADC_MR); + regval &= ~(ADC_MR_STARTUP_MASK | ADC_MR_TRACKTIM_MASK | ADC_MR_SETTLING_MASK); + regval |= (ADC_MR_STARTUP_512 | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING_17); + sam_adc_putreg(priv, SAM_ADC_MR, regval); + + /* Attach the ADC interrupt */ + + ret = irq_attach(SAM_IRQ_ADC, sam_adc_interrupt); + if (ret < 0) + { + adbg("ERROR: Failed to attach IRQ %d: %d\n", SAM_IRQ_ADC, ret); + return NULL; + } + + /* Disable all ADC interrupts at the source */ + + sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_ALL); + + /* Enable the ADC interrupt at the AIC */ + + up_enable_irq(SAM_IRQ_ADC); + + /* Now we are initialized */ + + priv->initialized = true; + } + + /* Return a pointer to the device structure */ + + avdbg("Returning %p\n", &g_adcdev); + return &g_adcdev; +} + +/**************************************************************************** + * Name: sam_adc_lock + * + * Description: + * Get exclusive access to the ADC interface + * + ****************************************************************************/ + +void sam_adc_lock(FAR struct sam_adc_s *priv) +{ + int ret; + + avdbg("Locking\n"); + + do + { + ret = sem_wait(&priv->exclsem); + + /* This should only fail if the wait was canceled by an signal + * (and the worker thread will receive a lot of signals). + */ + + DEBUGASSERT(ret == OK || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: sam_adc_unlock + * + * Description: + * Relinquish the lock on the ADC interface + * + ****************************************************************************/ + +void sam_adc_unlock(FAR struct sam_adc_s *priv) +{ + avdbg("Unlocking\n"); + sem_post(&priv->exclsem); +} + +/**************************************************************************** + * Name: sam_adc_getreg + * + * Description: + * Read any 32-bit register using an absolute address. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG +uint32_t sam_adc_getreg(struct sam_adc_s *priv, uintptr_t address) +{ + uint32_t regval = getreg32(address); + + if (sam_adc_checkreg(priv, false, regval, address)) + { + lldbg("%08x->%08x\n", address, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_adc_putreg + * + * Description: + * Write to any 32-bit register using an absolute address. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG +void sam_adc_putreg(struct sam_adc_s *priv, uintptr_t address, uint32_t regval) +{ + if (sam_adc_checkreg(priv, true, regval, address)) + { + lldbg("%08x<-%08x\n", address, regval); + } + + putreg32(regval, address); +} +#endif + +#endif /* CONFIG_SAMA5_ADC */ diff --git a/arch/arm/src/sama5/sam_adc.h b/arch/arm/src/sama5/sam_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..f8ba29f157636ed0913b530aca1cf3c069bd6d32 --- /dev/null +++ b/arch/arm/src/sama5/sam_adc.h @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_adc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_ADC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_ADC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip/sam_adc.h" + +#ifdef CONFIG_SAMA5_ADC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SCHED_WORKQUEUE +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_ADC_REGDEBUG +#endif + +/* ADC channels 0-3 or 0-4 are not available to the ADC driver if touchscreen + * support is enabled. + */ + +#ifdef CONFIG_SAMA5_TSD +# undef CONFIG_SAMA5_ADC_CHAN0 +# undef CONFIG_SAMA5_ADC_CHAN1 +# undef CONFIG_SAMA5_ADC_CHAN2 +# undef CONFIG_SAMA5_ADC_CHAN3 +# ifdef CONFIG_SAMA5_TSD_5WIRE +# undef CONFIG_SAMA5_ADC_CHAN4 +# endif +#endif + +/* Do we have any ADC channels enabled? If not, then the ADC driver may + * still need to exist to support the touchscreen. + */ + +#undef SAMA5_ADC_HAVE_CHANNELS +#if defined(CONFIG_SAMA5_ADC_CHAN0) || defined(CONFIG_SAMA5_ADC_CHAN1) || \ + defined(CONFIG_SAMA5_ADC_CHAN2) || defined(CONFIG_SAMA5_ADC_CHAN3) || \ + defined(CONFIG_SAMA5_ADC_CHAN4) || defined(CONFIG_SAMA5_ADC_CHAN5) || \ + defined(CONFIG_SAMA5_ADC_CHAN6) || defined(CONFIG_SAMA5_ADC_CHAN7) || \ + defined(CONFIG_SAMA5_ADC_CHAN8) || defined(CONFIG_SAMA5_ADC_CHAN9) || \ + defined(CONFIG_SAMA5_ADC_CHAN10) || defined(CONFIG_SAMA5_ADC_CHAN11) +# define SAMA5_ADC_HAVE_CHANNELS 1 +#elif !defined(CONFIG_SAMA5_TSD) +# error "No ADC channels nor touchscreen" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_adcinitialize + * + * Description: + * Initialize the ADC + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct adc_dev_s *sam_adc_initialize(void); + +/**************************************************************************** + * Interfaces exported from the ADC to the touchscreen driver + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_adc_lock + * + * Description: + * Get exclusive access to the ADC interface + * + ****************************************************************************/ + +struct sam_adc_s; +void sam_adc_lock(FAR struct sam_adc_s *priv); + +/**************************************************************************** + * Name: sam_adc_unlock + * + * Description: + * Relinquish the lock on the ADC interface + * + ****************************************************************************/ + +void sam_adc_unlock(FAR struct sam_adc_s *priv); + +/**************************************************************************** + * Name: sam_adc_getreg + * + * Description: + * Read any 32-bit register using an absolute address. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG +uint32_t sam_adc_getreg(FAR struct sam_adc_s *priv, uintptr_t address); +#else +# define sam_adc_getreg(handle,addr) getreg32(addr) +#endif + +/**************************************************************************** + * Name: sam_adc_putreg + * + * Description: + * Write to any 32-bit register using an absolute address. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ADC_REGDEBUG +void sam_adc_putreg(FAR struct sam_adc_s *priv, uintptr_t address, + uint32_t regval); +#else +# define sam_adc_putreg(handle,addr,val) putreg32(val,addr) +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_ADC */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ADC_H */ diff --git a/arch/arm/src/sama5/sam_allocateheap.c b/arch/arm/src/sama5/sam_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..14388795f984bcd3b72bd4b7835ea6da662b7411 --- /dev/null +++ b/arch/arm/src/sama5/sam_allocateheap.c @@ -0,0 +1,406 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_allocateheap.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "mmu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Terminology. In the flat build (CONFIG_BUILD_FLAT=y), there is only a + * single heap access with the standard allocations (malloc/free). This + * heap is referred to as the user heap. In the protected build + * (CONFIG_BUILD_PROTECTED=y) where an MPU is used to protect a region of + * otherwise flat memory, there will be two allocators: One that allocates + * protected (kernel) memory and one that allocates unprotected (user) + * memory. These are referred to as the kernel and user heaps, + * respectively. + * + * The ARMv7 has no MPU but does have an MMU. With this MMU, it can support + * the kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there + * is one kernel heap but multiple user heaps: One per task group. However, + * in this case, we need only be concerned about initializing the single + * kernel heap here. + */ + +#if defined(CONFIG_BUILD_KERNEL) +# define MM_ADDREGION kmm_addregion +#else +# define MM_ADDREGION umm_addregion +#endif + +/* The Primary Heap *********************************************************/ +/* The physical address of the primary heap is defined by CONFIG_RAM_START, + * CONFIG_RAM_SIZE, and CONFIG_RAM_END where: + * + * CONFIG_RAM_END = CONFIG_RAM_START + CONFIG_RAM_SIZE + * + * and the corresponding virtual address are give by: + * + * CONFIG_RAM_VEND = CONFIG_RAM_VSTART + CONFIG_RAM_SIZE + * + * CONFIG_RAM_VSTART is the usable beginning of the RAM region. The "usable" + * start would exclude, for example, any memory at the bottom of the RAM + * region used for the 16KB page table. If we are also executing from this + * same RAM region then CONFIG_RAM_START is not used. Instead, the value of + * g_idle_stack is the used; this variable holds the first available byte of + * memory after the .text, .data, .bss, and IDLE stack allocations. + * + * CONFIG_RAM_VEND is defined in the configuration it is the usable top of + * the RAM region beginning at CONFIG_RAM_START. The "usable" top would + * exclude, for example, any memory reserved at the top of the for the 16KB + * page table. + * + * A special may occur when we execute from DRAM. In that case, + * CONFIG_RAM_VSTART must be set to the (virtual) start of DRAM and + * CONFIG_RAM_SIZE must be set to the size of the DRAM. These settings are + * necessary to provide the DRAM MMU mappings when the system boots and, by + * default, the DRAM memory will be added to the heap all the way up to + * CONFIG_RAM_VEND + * + * However, there are certain cases where you may want to reserve a block of + * DRAM for other purposes such a large DMA buffer or an LCD framebuffer. + * In those cases, the CONFIG_SAMA5_DDRCS_RESERVE can select a different end + * of the DRAM memory to add to the heap. If CONFIG_SAMA5_DDRCS_RESERVE is + * selected, then the setting CONFIG_SAMA5_DDRCS_HEAP_END provides the end + * (plus one) (virtual) address of memory to be added to the heap; DRAM after + * this address will not be part of the heap and so will be available for + * other purposes + * + * NOTE: There is way to reserve memory before the start of the program + * in DRAM using this mechanism. That configuration is possible, but + * not using this configuration setting. + */ + +/* Memory Regions ***********************************************************/ +/* Check if we have been asked to reserve memory at the end of the primary + * memory region. This option is only available if we are executing from + * DRAM and only if CONFIG_SAMA5_DDRCS_RESERVE is selected. + */ + +#ifdef CONFIG_SAMA5_DDRCS_RESERVE + + /* CONFIG_SAMA5_DDRCS_HEAP_END specifies the end (plus one) of the DRAM + * to add to the heap. Memory starting at CONFIG_SAMA5_DDRCS_HEAP_END + * and extending to CONFIG_RAM_VEND is then available for other purposes. + */ + +# if !defined(CONFIG_SAMA5_DDRCS_HEAP_END) +# error CONFIG_SAMA5_DDRCS_HEAP_END must be defined in this configuration +# elif CONFIG_SAMA5_DDRCS_HEAP_END > CONFIG_RAM_VEND +# error CONFIG_SAMA5_DDRCS_HEAP_END is beyond CONFIG_RAM_VEND +# elif CONFIG_SAMA5_DDRCS_HEAP_END < CONFIG_RAM_VSTART +# error CONFIG_SAMA5_DDRCS_HEAP_END is before CONFIG_RAM_VSTART +# endif + +# define SAMA5_PRIMARY_HEAP_END CONFIG_SAMA5_DDRCS_HEAP_END +#else + /* Otherwise, add the RAM all the way to the the end of the primary memory + * region to the heap. + */ + +# define SAMA5_PRIMARY_HEAP_END CONFIG_RAM_VEND +#endif + +/* We cannot use the memory for heap if it is not enabled. Or, if it is + * enabled, but does not hold SDRAM, SRAM, or PSRAM. + * + * We cannot add the region if it is if we are executing from it! In that + * case, the remainder of the memory will automatically be added to the heap + * based on g_idle_topstack and SAMA5_PRIMARY_HEAP_END. + */ + +#if defined(CONFIG_SAMA5_BOOT_ISRAM) +# undef CONFIG_SAMA5_ISRAM_HEAP +#endif + +#if !defined(CONFIG_SAMA5_DDRCS) || defined(CONFIG_SAMA5_BOOT_SDRAM) || \ + defined(CONFIG_BOOT_SDRAM_DATA) +# undef CONFIG_SAMA5_DDRCS_HEAP +#endif + +#if !defined(CONFIG_SAMA5_EBICS0) || defined(CONFIG_SAMA5_BOOT_CS0SRAM) || \ + (!defined(CONFIG_SAMA5_EBICS0_SRAM) && !defined(CONFIG_SAMA5_EBICS0_PSRAM)) + +# undef SAMA5_EBICS0_HEAP +#endif + +#if !defined(CONFIG_SAMA5_EBICS1) || defined(CONFIG_SAMA5_BOOT_CS1SRAM) || \ + (!defined(CONFIG_SAMA5_EBICS1_SRAM) && !defined(CONFIG_SAMA5_EBICS1_PSRAM)) + +# undef SAMA5_EBICS1_HEAP +#endif + +#if !defined(CONFIG_SAMA5_EBICS2) || defined(CONFIG_SAMA5_BOOT_CS2SRAM) || \ + (!defined(CONFIG_SAMA5_EBICS2_SRAM) && !defined(CONFIG_SAMA5_EBICS2_PSRAM)) + +# undef SAMA5_EBICS2_HEAP +#endif + +#if !defined(SAMA5_CONFIG_EBICS3) || defined(CONFIG_SAMA5_BOOT_CS3SRAM) || \ + (!defined(SAMA5_CONFIG_EBICS3_SRAM) && !defined(CONFIG_SAMA5_EBICS3_PSRAM)) + +# undef SAMA5_EBICS3_HEAP +#endif + +/* The heap space in the primary memory region is added automatically when + * up_allocate_heap is called. So if the memory region is the primary region, + * it should not be added to the heap (again). + */ + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_ISRAM0_VADDR +# undef CONFIG_SAMA5_ISRAM_HEAP +#endif + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_DDRCS_VSECTION +# undef CONFIG_SAMA5_DDRCS_HEAP +#endif + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_EBICS0_VSECTION +# undef SAMA5_EBICS0_HEAP +#endif + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_EBICS1_VSECTION +# undef SAMA5_EBICS1_HEAP +#endif + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_EBICS2_VSECTION +# undef SAMA5_EBICS2_HEAP +#endif + +#if (CONFIG_RAM_VSTART & 0xfff00000) == SAM_EBICS3_VSECTION +# undef SAMA5_EBICS3_HEAP +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap/up_allocate_kheap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * For the flat build, this heap is referred to as the user heap (for + * compatibility with other platforms). For the kernel build + * (CONFIG_BUILD_KERNEL=y) this is referred to a the kernel heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_KERNEL) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +#else +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +#endif +{ +#if defined(CONFIG_BOOT_SDRAM_DATA) + /* In this case, the IDLE stack is in ISRAM, but data is in SDRAM. The + * heap is at the end of BSS through the configured end of SDRAM. + */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)&_ebss; + *heap_size = SAMA5_PRIMARY_HEAP_END - (size_t)&_ebss; + +#else + /* Both data and the heap are in ISRAM. The heap is then from the end of + * IDLE stack through the configured end of ISRAM. + */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SAMA5_PRIMARY_HEAP_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + int nregions = CONFIG_MM_REGIONS - 1; + uintptr_t vaddr; + size_t size; + +#ifdef CONFIG_SAMA5_ISRAM_HEAP + vaddr = (uintptr_t)SAM_ISRAM0_VADDR + size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE; + + /* Add the ISRAM user heap region. */ + + MM_ADDREGION((void *)vaddr, size); + nregions--; +#endif + +#ifdef CONFIG_SAMA5_DDRCS_HEAP + if (nregions > 0) + { + vaddr = (uintptr_t)SAM_DDRCS_VSECTION + SAMA5_DDRCS_HEAP_OFFSET; + size = SAMA5_DDRCS_HEAP_SIZE; + + /* Add the DDR-SDRAM user heap region. */ + + MM_ADDREGION((void *)vaddr, size); + nregions--; + } + else + { + lldbg("ERROR: SDRAM memory not added to heap. CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS); + lldbg(" Increase the size of CONFIG_MM_NREGIONS\n"); + } +#endif + +#ifdef SAMA5_EBICS0_HEAP + if (nregions > 0) + { + vaddr = (uintptr_t)SAM_EBICS0_VSECTION + SAMA5_EBICS0_HEAP_OFFSET; + size = SAMA5_EBICS0_HEAP_SIZE; + + /* Add the EBICS0 user heap region. */ + + MM_ADDREGION((void *)vaddr, size); + nregions--; + } + else + { + lldbg("ERROR: CS0 memory not added to heap. CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS); + lldbg(" Increase the size of CONFIG_MM_NREGIONS\n"); + } +#endif + +#ifdef SAMA5_EBICS1_HEAP + if (nregions > 0) + { + vaddr = (uintptr_t)SAM_EBICS1_VSECTION + SAMA5_EBICS1_HEAP_OFFSET; + size = SAMA5_EBICS1_HEAP_SIZE; + + /* Add the EBICS1 user heap region. */ + + MM_ADDREGION((void *)vaddr, size); + nregions--; + } + else + { + lldbg("ERROR: CS1 memory not added to heap. CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS); + lldbg(" Increase the size of CONFIG_MM_NREGIONS\n"); + } +#endif + +#ifdef SAMA5_EBICS2_HEAP + if (nregions > 0) + { + vaddr = (uintptr_t)SAM_EBICS2_VSECTION + SAMA5_EBICS2_HEAP_OFFSET; + size = SAMA5_EBICS2_HEAP_SIZE; + + /* Add the EBICS2 user heap region. */ + + MM_ADDREGION((void *)vaddr, size); + nregions--; + } + else + { + lldbg("ERROR: CS2 memory not added to heap. CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS); + lldbg(" Increase the size of CONFIG_MM_NREGIONS\n"); + } +#endif + +#ifdef SAMA5_EBICS3_HEAP + if (nregions > 0) + { + vaddr = (uintptr_t)SAM_EBICS3_VSECTION + SAMA5_EBICS3_HEAP_OFFSET; + size = SAMA5_EBICS3_HEAP_SIZE; + + /* Add the EBICS3 user heap region. */ + + MM_ADDREGION(vaddr, size); + nregions--; + } + else + { + lldbg("ERROR: CS3 memory not added to heap. CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS); + lldbg(" Increase the size of CONFIG_MM_NREGIONS\n"); + } +#endif + + /* Did we add all of the requestion regions */ + + if (nregions > 0) + { + lldbg("ERROR: Not all regions added to heap: %d added, but CONFIG_MM_NREGIONS=%d\n", + CONFIG_MM_REGIONS - nregions, CONFIG_MM_REGIONS); + lldbg(" Decrease the size of CONFIG_MM_NREGIONS\n"); + } +} +#endif diff --git a/arch/arm/src/sama5/sam_boot.c b/arch/arm/src/sama5/sam_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..58cae338248d25d5aac51e88f4920783a06fd342 --- /dev/null +++ b/arch/arm/src/sama5/sam_boot.c @@ -0,0 +1,534 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_boot.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_PAGING +# include +#endif + +#include + +#include "chip.h" +#include "arm.h" +#include "mmu.h" +#include "cache.h" +#include "fpu.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/sam_wdt.h" +#include "chip/sam_aximx.h" +#include "chip/sam_sfr.h" + +#include "sam_clockconfig.h" +#include "sam_memorymap.h" +#include "sam_lowputc.h" +#include "sam_serial.h" +#include "sam_lcd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Symbols defined via the linker script */ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_setupmappings + * + * Description + * Map all of the initial memory regions defined in g_section_mapping[] + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline void sam_setupmappings(void) +{ + int i; + + /* Set up each group of section mappings */ + + for (i = 0; i < g_num_mappings; i++) + { + mmu_l1_map_region(&g_section_mapping[i]); + } +} +#endif + +/**************************************************************************** + * Name: sam_remap + * + * Description + * Map all of the final memory regions defined in g_operational_mapping[] + * + ****************************************************************************/ + +#ifdef NEED_SDRAM_REMAPPING +static inline void sam_remap(void) +{ + int i; + + /* Re-map each group of section */ + + for (i = 0; i < g_num_opmappings; i++) + { + mmu_l1_map_region(&g_operational_mapping[i]); + } +} +#endif + +/**************************************************************************** + * Name: sam_vectorpermissions + * + * Description: + * Set permissions on the vector mapping. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \ + defined(CONFIG_PAGING) +static void sam_vectorpermissions(uint32_t mmuflags) +{ + /* The PTE for the beginning of ISRAM is at the base of the L2 page table */ + + uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0); + + /* Mask out the old MMU flags from the page table entry. + * + * The pte might be zero the first time this function is called. + */ + + if (pte == 0) + { + pte = PG_VECT_PBASE; + } + else + { + pte &= PG_L1_PADDRMASK; + } + + /* Update the page table entry with the MMU flags and save */ + + mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags); +} +#endif + +/**************************************************************************** + * Name: sam_vectorsize + * + * Description: + * Return the size of the vector data + * + ****************************************************************************/ + +static inline size_t sam_vectorsize(void) +{ + uintptr_t src; + uintptr_t end; + + src = (uintptr_t)&_vector_start; + end = (uintptr_t)&_vector_end; + + return (size_t)(end - src); +} + +/**************************************************************************** + * Name: sam_vectormapping + * + * Description: + * Setup a special mapping for the interrupt vectors when (1) the + * interrupt vectors are not positioned in ROM, and when (2) the interrupt + * vectors are located at the high address, 0xffff0000. When the + * interrupt vectors are located in ROM, we just have to assume that they + * were set up correctly; When vectors are located in low memory, + * 0x00000000, the mapping for the ROM memory region will be suppressed. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS) +static void sam_vectormapping(void) +{ + uint32_t vector_paddr = SAM_VECTOR_PADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_vaddr = SAM_VECTOR_VADDR & PTE_SMALL_PADDR_MASK; + uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start; + uint32_t end_paddr = SAM_VECTOR_PADDR + vector_size; + + /* REVISIT: Cannot really assert in this context */ + + DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE); + + /* We want to keep our interrupt vectors and interrupt-related logic in + * zero-wait state internal SRAM (ISRAM). The SAMA5 has 128Kb of ISRAM + * positioned at physical address 0x0300:0000; we need to map this to + * 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr, + MMU_L2_VECTORFLAGS); + vector_paddr += 4096; + vector_vaddr += 4096; + } + + /* Now set the level 1 descriptor to refer to the level 2 page table. */ + + mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, + SAM_VECTOR_VADDR & PMD_PTE_PADDR_MASK, + MMU_L1_VECTORFLAGS); +} +#else + /* No vector remap */ + +# define sam_vectormapping() +#endif + +/**************************************************************************** + * Name: sam_copyvectorblock + * + * Description: + * Copy the interrupt block to its final destination. Vectors are already + * positioned at the beginning of the text region and only need to be + * copied in the case where we are using high vectors or where the beginning + * of the text region cannot be remapped to address zero. + * + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_LOWVECTORS) +static void sam_copyvectorblock(void) +{ + uint32_t *src; + uint32_t *end; + uint32_t *dest; + +#ifdef CONFIG_PAGING + /* If we are using re-mapped vectors in an area that has been marked + * read only, then temporarily mark the mapping write-able (non-buffered). + */ + + sam_vectorpermissions(MMU_L2_VECTRWFLAGS); +#endif + + /* Copy the vectors into ISRAM at the address that will be mapped to the vector + * address: + * + * SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * SAM_VECTOR_VSRAM - Virtual address of vector table in SRAM + * SAM_VECTOR_VADDR - Virtual address of vector table (0x00000000 or + * 0xffff0000) + */ + + src = (uint32_t *)&_vector_start; + end = (uint32_t *)&_vector_end; + dest = (uint32_t *)SAM_VECTOR_VSRAM; + + while (src < end) + { + *dest++ = *src++; + } + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + /* Make the vectors read-only, cacheable again */ + + sam_vectorpermissions(MMU_L2_VECTORFLAGS); + +#else + /* Flush the DCache to assure that the vector data is in physical in ISRAM */ + + arch_clean_dcache((uintptr_t)SAM_VECTOR_VSRAM, + (uintptr_t)SAM_VECTOR_VSRAM + sam_vectorsize()); +#endif +} + +#else +/* Don't copy the vectors */ + +# define sam_copyvectorblock() +#endif + +/**************************************************************************** + * Name: sam_wdtdisable + * + * Description: + * Disable the watchdog timer. The SAMA5 always boots with the watchdog + * timer enabled at its maximum timeout (16 seconds). The watchdog timer + * can disabled by writing to the Watchdog Mode Register (WDT_MR). The + * WDT_MR, however, can be written only one time after the CPU has been + * reset. + * + * So if no watchdog timer driver has been configured, the watchdog timer + * must be disabled as part of the start up logic. But, on the other + * hand, we must not write to the WDT_MR register if the watchdog timer + * driver is configured. In that case, some later application will + * configure the WDT and begin periodic pinging (within 16 seconds, + * hopefully). + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_WDT +static inline void sam_wdtdisable(void) +{ + putreg32(WDT_MR_WDDIS, SAM_WDT_MR); +} +#else +# define sam_wdtdisable() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * Boot Sequence + * + * This logic may be executing in ISRAM or in external memory: CS0, DDR, + * CS1, CS2, or CS3. It may be executing in CS0 or ISRAM through the + * action of the SAMA5 "first level bootloader;" it might be executing in + * CS1-3 through the action of some second level bootloader that provides + * configuration for those memories. + * + * The system always boots from the ROM memory at address 0x0000:0000, + * starting the internal first level bootloader. That bootloader can be + * configured to work in different ways using the BMS pin and the contents + * of the Boot Sequence Configuration Register (BSC_CR). + * + * If the BMS_BIT is read "1", then the first level bootloader will + * support execution of code in the memory connected to CS0 on the EBI + * interface (presumably NOR flash). The following sequence is performed + * by the first level bootloader if BMS_BIT is "1": + * + * - The main clock is the on-chip 12 MHz RC oscillator, + * - The Static Memory Controller is configured with timing allowing + * code execution in CS0 external memory at 12 MHz + * - AXI matrix is configured to remap EBI CS0 address at 0x0 + * - 0x0000:0000 is loaded in the Program Counter register + * + * The user software in the external memory must perform the next + * operation in order to complete the clocks and SMC timings configuration + * to run at a higher clock frequency: + * + * - Enable the 32768 Hz oscillator if best accuracy is needed + * - Reprogram the SMC setup, cycle, hold, mode timing registers for EBI + * CS0, to adapt them to the new clock. + * - Program the PMC (Main Oscillator Enable or Bypass mode) + * - Program and Start the PLL + * - Switch the system clock to the new value + * + * If the BMS_BIT is read "0", then the first level bootloader will + * perform: + * + * - Basic chip initialization: XTal or external clock frequency + * detection: + * + * a. Stack Setup for ARM supervisor mode + * b. Main Oscillator Detection: The bootloader attempts to use an + * external crystal. If this is not successful, then the 12 MHz + * Fast RC internal oscillator is used as the main osciallator. + * c. Main Clock Selection: The Master Clock source is switched from + * to the main oscillator without prescaler. PCK and MCK are now + * the Main Clock. + * d. PLLA Initialization: PLLA is configured to get a PCK at 96 MHz + * and an MCK at 48 MHz. If an external clock or crystal frequency + * running at 12 MHz is found, then the PLLA is configured to allow + * USB communication. + * + * - Attempt to retrieve a valid code from external non-volatile + * memories (NVM): SPI0 CS0 Flash Boot, SD Card Boot, NAND Flash Boot, + * SPI0 CS1 Flash Boot, or TWI EEPROM Boot. Different heuristics are + * used with each media type. If a valid image is found, it is copied + * to internal SRAM and started. + * + * - In case no valid application has been found on any NVM, the SAM-BA + * Monitor is started. + * + ****************************************************************************/ + +void up_boot(void) +{ +#ifdef CONFIG_ARCH_RAMFUNCS + const uint32_t *src; + uint32_t *dest; +#endif +#ifdef ATSAMA5D2 + uint32_t regval; +#endif + +#ifndef CONFIG_ARCH_ROMPGTABLE + /* __start provided the basic MMU mappings for SRAM. Now provide mappings + * for all IO regions (Including the vector region). + */ + + sam_setupmappings(); + + /* Provide a special mapping for the IRAM interrupt vector positioned in + * high memory. + */ + + sam_vectormapping(); + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +#ifdef ATSAMA5D2 + /* The SAMA5D2 features a second 128-Kbyte SRAM that can be allocated + * either to the L2 cache controller or used as an internal SRAM. After + * reset, this block is connected to the L2 cache controller. The + * SRAM_SEL bit, located in the SFR_L2CC_HRAMC register, is used to + * reassign this memory as system SRAM, making the two 128-Kbyte + * RAMs contiguous. + */ + + regval = getreg32(SAM_SFR_L2CCHRAMC); + +#ifdef CONFIG_ARCH_L2CACHE + regval |= SFR_L2CCHRAMC_SRAMSEL; /* 1=Selects L2CC */ +#else + regval &= ~SFR_L2CCHRAMC_SRAMSEL; /* 0=Selects SRAM */ +#endif + + putreg32(regval, SAM_SFR_L2CCHRAMC); +#endif + +#ifdef CONFIG_ARCH_RAMFUNCS + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs + */ + + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } + + /* Flush the copied RAM functions into physical RAM so that will + * be available when fetched into the I-Cache. + */ + + arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs) +#endif + + /* Setup up vector block. _vector_start and _vector_end are exported from + * arm_vector.S + */ + + sam_copyvectorblock(); + + /* Disable the watchdog timer */ + + sam_wdtdisable(); + + /* Initialize clocking to settings provided by board-specific logic */ + + sam_clockconfig(); + +#ifdef CONFIG_ARCH_FPU + /* Initialize the FPU */ + + arm_fpuconfig(); +#endif + + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (PIOs, LEDs, etc). + * + * NOTE: We must use caution prior to this point to make sure that + * the logic does not access any global variables that might lie + * in SDRAM. + */ + + sam_boardinitialize(); + +#ifdef NEED_SDRAM_REMAPPING + /* SDRAM was configured in a temporary state to support low-level + * initialization. Now that the SDRAM has been fully initialized, + * we can reconfigure the SDRAM in its final, fully cache-able state. + */ + + sam_remap(); +#endif + +#ifdef CONFIG_BOOT_SDRAM_DATA + /* If .data and .bss reside in SDRAM, then initialize the data sections + * now after SDRAM has been initialized. + */ + + arm_data_initialize(); +#endif + + /* Perform common, low-level chip initialization (might do nothing) */ + + sam_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization if we are going to use the serial + * driver. + */ + + sam_earlyserialinit(); +#endif +} diff --git a/arch/arm/src/sama5/sam_can.c b/arch/arm/src/sama5/sam_can.c new file mode 100644 index 0000000000000000000000000000000000000000..ac9e93cc08a6e2474498c12ed062702e89892e1c --- /dev/null +++ b/arch/arm/src/sama5/sam_can.c @@ -0,0 +1,2030 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_can.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code (for bit timing configuration). + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + + +#include "chip/sam_pinmap.h" +#include "sam_periphclks.h" +#include "sam_pio.h" +#include "sam_can.h" + +#if defined(CONFIG_CAN) && (defined(CONFIG_SAMA5_CAN0) || defined(CONFIG_SAMA5_CAN1)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Common definitions *******************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a < b) ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) ((a > b) ? a : b) +#endif + +/* Mailboxes ****************************************************************/ + +#define SAMA5_CAN_NRECVMB MAX(CONFIG_SAMA5_CAN0_NRECVMB, CONFIG_SAMA5_CAN1_NRECVMB) + +/* The set of all mailboxes */ + +#if SAM_CAN_NMAILBOXES == 8 +# define CAN_ALL_MAILBOXES 0xff /* 8 mailboxes */ +#else +# error Unsupport/undefined number of mailboxes +#endif + +/* Interrupts ***************************************************************/ +/* If debug is enabled, then print some diagnostic info if any of these + * events occur: + * + * CAN_INT_ERRA YES Bit 16: Error Active Mode + * CAN_INT_WARN YES Bit 17: Warning Limit + * CAN_INT_ERRP NO Bit 18: Error Passive Mode + * CAN_INT_BOFF NO Bit 19: Bus Off Mode + * + * CAN_INT_SLEEP NO Bit 20: CAN Controller in Low-power Mode + * CAN_INT_WAKEUP NO Bit 21: Wake-up Interrupt + * CAN_INT_TOVF NO Bit 22: Timer Overflow + * CAN_INT_TSTP NO Bit 23: Timestamp + * + * CAN_INT_CERR YES Bit 24: Mailbox CRC Error + * CAN_INT_SERR YES Bit 25: Mailbox Stuffing Error + * CAN_INT_AERR NO Bit 26: Acknowledgment Error (uusally means no CAN bus) + * CAN_INT_FERR YES Bit 27: Form Error + * + * CAN_INT_BERR YES Bit 28: Bit Error + */ + +#define CAN_DEBUG_INTS (CAN_INT_ERRA | CAN_INT_WARN | CAN_INT_CERR | \ + CAN_INT_SERR | CAN_INT_FERR | CAN_INT_BERR) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing CAN */ + +#ifdef CONFIG_DEBUG_CAN +# define candbg dbg +# define canvdbg vdbg +# define canlldbg lldbg +# define canllvdbg llvdbg +#else +# define candbg(x...) +# define canvdbg(x...) +# define canlldbg(x...) +# define canllvdbg(x...) +#endif + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_CAN) +# undef CONFIG_SAMA5_CAN_REGDEBUG +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes receive mailbox filtering */ + +struct sam_filter_s +{ +#ifdef CONFIG_CAN_EXTID + uint32_t addr; /* 29-bit address to match */ + uint32_t mask; /* 29-bit address mask */ +#else + uint16_t addr; /* 11-bit address to match */ + uint16_t mask; /* 11-bit address mask */ +#endif +}; + +/* This structure provides the constant configuration of a CAN peripheral */ + +struct sam_config_s +{ + uint8_t port; /* CAN port number (1 or 2) */ + uint8_t pid; /* CAN periperal ID/IRQ number */ + uint8_t nrecvmb; /* Number of receive mailboxes */ + xcpt_t handler; /* CAN interrupt handler */ + uintptr_t base; /* Base address of the CAN control registers */ + uint32_t baud; /* Configured baud */ + pio_pinset_t rxpinset; /* RX pin configuration */ + pio_pinset_t txpinset; /* TX pin configuration */ + + /* Mailbox filters */ + + struct sam_filter_s filter[SAMA5_CAN_NRECVMB]; +}; + +/* This structure provides the current state of a CAN peripheral */ + +struct sam_can_s +{ + const struct sam_config_s *config; /* The constant configuration */ + bool initialized; /* TRUE: Device has been initialized */ + uint8_t freemb; /* Rhe set of unalloated mailboxes */ + uint8_t rxmbset; /* The set of mailboxes configured for receive */ + volatile uint8_t txmbset; /* The set of mailboxes actively transmitting */ + bool txdisabled; /* TRUE: Keep TX interrupts disabled */ + sem_t exclsem; /* Enforces mutually exclusive access */ + uint32_t frequency; /* CAN clock frequency */ + +#ifdef CONFIG_SAMA5_CAN_REGDEBUG + uintptr_t regaddr; /* Last register address read */ + uint32_t regval; /* Last value read from the register */ + unsigned int count; /* Number of times that the value was read */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* CAN Register access */ + +static uint32_t can_getreg(FAR struct sam_can_s *priv, int offset); +static void can_putreg(FAR struct sam_can_s *priv, int offset, uint32_t regval); +#ifdef CONFIG_SAMA5_CAN_REGDEBUG +static void can_dumpctrlregs(FAR struct sam_can_s *priv, FAR const char *msg); +static void can_dumpmbregs(FAR struct sam_can_s *priv, FAR const char *msg); +#else +# define can_dumpctrlregs(priv,msg) +# define can_dumpmbregs(priv,msg) +#endif + +/* Semaphore helpers */ + +static void can_semtake(FAR struct sam_can_s *priv); +#define can_semgive(priv) sem_post(&priv->exclsem) + +/* Mailboxes */ + +static int can_recvsetup(FAR struct sam_can_s *priv); + +/* CAN driver methods */ + +static void can_reset(FAR struct can_dev_s *dev); +static int can_setup(FAR struct can_dev_s *dev); +static void can_shutdown(FAR struct can_dev_s *dev); +static void can_rxint(FAR struct can_dev_s *dev, bool enable); +static void can_txint(FAR struct can_dev_s *dev, bool enable); +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg); +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id); +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg); +static bool can_txready(FAR struct can_dev_s *dev); +static bool can_txempty(FAR struct can_dev_s *dev); + +/* CAN interrupt handling */ + +static inline void can_rxinterrupt(FAR struct can_dev_s *dev, int mbndx, + uint32_t msr); +static inline void can_txinterrupt(FAR struct can_dev_s *dev, int mbndx); +static inline void can_mbinterrupt(FAR struct can_dev_s *dev, int mbndx); +static void can_interrupt(FAR struct can_dev_s *dev); +#ifdef CONFIG_SAMA5_CAN0 +static int can0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_CAN1 +static int can1_interrupt(int irq, void *context); +#endif + +/* Hardware initialization */ + +static int can_bittiming(FAR struct sam_can_s *priv); +#ifdef CONFIG_SAMA5_CAN_AUTOBAUD +static int can_autobaud(FAR struct sam_can_s *priv); +#endif +static int can_hwinitialize(FAR struct sam_can_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct can_ops_s g_canops = +{ + .co_reset = can_reset, + .co_setup = can_setup, + .co_shutdown = can_shutdown, + .co_rxint = can_rxint, + .co_txint = can_txint, + .co_ioctl = can_ioctl, + .co_remoterequest = can_remoterequest, + .co_send = can_send, + .co_txready = can_txready, + .co_txempty = can_txempty, +}; + +#ifdef CONFIG_SAMA5_CAN0 +static const struct sam_config_s g_can0const = +{ + .port = 0, + .pid = SAM_PID_CAN0, + .nrecvmb = CONFIG_SAMA5_CAN0_NRECVMB, + .handler = can0_interrupt, + .base = SAM_CAN0_VBASE, + .baud = CONFIG_SAMA5_CAN0_BAUD, + .rxpinset = PIO_CAN0_RX, + .txpinset = PIO_CAN0_TX, + .filter = + { + { + .addr = CONFIG_SAMA5_CAN0_ADDR0, + .mask = CONFIG_SAMA5_CAN0_MASK0, + }, +#if CONFIG_SAMA5_CAN0_NRECVMB > 1 + { + .addr = CONFIG_SAMA5_CAN0_ADDR1, + .mask = CONFIG_SAMA5_CAN0_MASK1, + }, +#if CONFIG_SAMA5_CAN0_NRECVMB > 1 + { + .addr = CONFIG_SAMA5_CAN0_ADDR2, + .mask = CONFIG_SAMA5_CAN0_MASK2, + }, +#endif +#endif + }, +}; + +static struct sam_can_s g_can0priv; +static struct can_dev_s g_can0dev; +#endif + +#ifdef CONFIG_SAMA5_CAN1 +static const struct sam_config_s g_can1const = +{ + .port = 1, + .pid = SAM_PID_CAN1, + .nrecvmb = CONFIG_SAMA5_CAN1_NRECVMB, + .handler = can1_interrupt, + .base = SAM_CAN1_VBASE, + .baud = CONFIG_SAMA5_CAN1_BAUD, + .rxpinset = PIO_CAN1_RX, + .txpinset = PIO_CAN1_TX, + .filter = + { + { + .addr = CONFIG_SAMA5_CAN1_ADDR0, + .mask = CONFIG_SAMA5_CAN1_MASK0, + }, +#if CONFIG_SAMA5_CAN1_NRECVMB > 1 + { + .addr = CONFIG_SAMA5_CAN1_ADDR1, + .mask = CONFIG_SAMA5_CAN1_MASK1, + }, +#if CONFIG_SAMA5_CAN1_NRECVMB > 1 + { + .addr = CONFIG_SAMA5_CAN1_ADDR2, + .mask = CONFIG_SAMA5_CAN1_MASK2, + }, +#endif +#endif + }, +}; + +static struct sam_can_s g_can1priv; +static struct can_dev_s g_can1dev; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: can_getreg + * + * Description: + * Read the value of a CAN register. + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN_REGDEBUG +static uint32_t can_getreg(FAR struct sam_can_s *priv, int offset) +{ + FAR const struct sam_config_s *config = priv->config; + uintptr_t regaddr; + uint32_t regval; + + /* Read the value from the register */ + + regaddr = config->base + offset; + regval = getreg32(regaddr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (regaddr == priv->regaddr && regval == priv->regval) + { + if (priv->count == 0xffffffff || ++priv->count > 3) + { + if (priv->count == 4) + { + lldbg("...\n"); + } + + return regval; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (priv->count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", priv->count - 3); + } + + /* Save the new address, value, and count */ + + priv->regaddr = regaddr; + priv->regval = regval; + priv->count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", regaddr, regval); + return regval; +} + +#else +static uint32_t can_getreg(FAR struct sam_can_s *priv, int offset) +{ + FAR const struct sam_config_s *config = priv->config; + return getreg32(config->base + offset); +} + +#endif + +/**************************************************************************** + * Name: can_putreg + * + * Description: + * Set the value of a CAN register. + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * offset - The offset to the register to write + * regval - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN_REGDEBUG +static void can_putreg(FAR struct sam_can_s *priv, int offset, uint32_t regval) +{ + FAR const struct sam_config_s *config = priv->config; + uintptr_t regaddr = config->base + offset; + + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", regaddr, regval); + + /* Write the value */ + + putreg32(regval, regaddr); +} + +#else +static void can_putreg(FAR struct sam_can_s *priv, int offset, uint32_t regval) +{ + FAR const struct sam_config_s *config = priv->config; + putreg32(regval, config->base + offset); +} + +#endif + +/**************************************************************************** + * Name: can_dumpctrlregs + * + * Description: + * Dump the contents of all CAN control registers + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN_REGDEBUG +static void can_dumpctrlregs(FAR struct sam_can_s *priv, FAR const char *msg) +{ + FAR const struct sam_config_s *config = priv->config; + + if (msg) + { + canlldbg("Control Registers: %s\n", msg); + } + else + { + canlldbg("Control Registers:\n"); + } + + /* CAN control and status registers */ + + lldbg(" MR: %08x IMR: %08x SR: %08x\n", + getreg32(config->base + SAM_CAN_MR_OFFSET), + getreg32(config->base + SAM_CAN_IMR_OFFSET), + getreg32(config->base + SAM_CAN_SR_OFFSET)); + + lldbg(" BR: %08x TIM: %08x TIMESTP: %08x\n", + getreg32(config->base + SAM_CAN_BR_OFFSET), + getreg32(config->base + SAM_CAN_TIM_OFFSET), + getreg32(config->base + SAM_CAN_TIMESTP_OFFSET)); + + lldbg(" ECR: %08x WPMR: %08x WPSR: %08x\n", + getreg32(config->base + SAM_CAN_ECR_OFFSET), + getreg32(config->base + SAM_CAN_TCR_OFFSET), + getreg32(config->base + SAM_CAN_ACR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: can_dumpmbregs + * + * Description: + * Dump the contents of all CAN mailbox registers + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN_REGDEBUG +static void can_dumpmbregs(FAR struct sam_can_s *priv, FAR const char *msg) +{ + FAR const struct sam_config_s *config = priv->config; + uintptr_t mbbase; + int i; + + if (msg) + { + canlldbg("Mailbox Registers: %s\n", msg); + } + else + { + canlldbg("Mailbox Registers:\n"); + } + + for (i = 0; i < SAM_CAN_NMAILBOXES; i++) + { + mbbase = config->base + SAM_CAN_MBn_OFFSET(i); + lldbg(" MB%d:\n", i); + + /* CAN mailbox registers */ + + lldbg(" MMR: %08x MAM: %08x MID: %08x MFID: %08x\n", + getreg32(mbbase + SAM_CAN_MMR_OFFSET), + getreg32(mbbase + SAM_CAN_MAM_OFFSET), + getreg32(mbbase + SAM_CAN_MID_OFFSET), + getreg32(mbbase + SAM_CAN_MFID_OFFSET)); + + lldbg(" MSR: %08x MDL: %08x MDH: %08x\n", + getreg32(mbbase + SAM_CAN_MSR_OFFSET), + getreg32(mbbase + SAM_CAN_MDL_OFFSET), + getreg32(mbbase + SAM_CAN_MDH_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: can_semtake + * + * Description: + * Take a semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_semtake(FAR struct sam_can_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->exclsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: can_mballoc + * + * Description: + * Allocate one mailbox + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN peripheral + * + * Returned Value: + * A non-negative mailbox index; a negated errno value on failure. + * + * Assumptions: + * The caller has exclusive access to the can data structures + * + ****************************************************************************/ + +static int can_mballoc(FAR struct sam_can_s *priv) +{ + int i; + + /* There any mailboxes free? */ + + if (priv->freemb) + { + /* Yes.. There are free mailboxes... pick one */ + + for (i = 0; i < SAM_CAN_NMAILBOXES; i++) + { + /* Is mailbox i availalbe? */ + + uint8_t bit = (1 << i); + if ((priv->freemb & bit) != 0) + { + /* No any more. Mark it allocated and return its index */ + + priv->freemb &= ~bit; + return i; + } + } + } + + /* No available mailboxes */ + + return -ENOMEM; +} + +/**************************************************************************** + * Name: can_mbfree + * + * Description: + * Free one mailbox + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN peripheral + * mbndx - Index of the mailbox to be freed + * + * Returned Value: + * None + * + * Assumptions: + * The caller has exclusive access to the can data structures + * + ****************************************************************************/ + +static void can_mbfree(FAR struct sam_can_s *priv, int mbndx) +{ + uint8_t bit; + + DEBUGASSERT(priv && (unsigned)mbndx < SAM_CAN_NMAILBOXES); + + /* Disable mailbox interrupts */ + + can_putreg(priv, SAM_CAN_IDR_OFFSET, CAN_INT_MB(mbndx)); + + /* Disable the mailbox */ + + can_putreg(priv, SAM_CAN_MnMR_OFFSET(mbndx), 0); + + /* Free the mailbox by clearing the corresponding bit in the freemb and + * txmbset (only TX mailboxes are freed in this way. + */ + + bit = (1 << mbndx); + DEBUGASSERT((priv->freemb & bit) != 0); + DEBUGASSERT((priv->txmbset & bit) != 0); + + priv->freemb &= ~bit; + priv->txmbset &= ~bit; +} + +/**************************************************************************** + * Name: can_recvsetup + * + * Description: + * Configure and enable mailbox(es) for reception + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN peripheral + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + * Assumptions: + * Caller has exclusive access to the CAN data structures + * CAN interrupts are disabled at the AIC + * + ****************************************************************************/ + +static int can_recvsetup(FAR struct sam_can_s *priv) +{ + FAR const struct sam_config_s *config = priv->config; + int mbndx; + int mbno; + + /* Setup the configured number of receive mailboxes */ + + priv->rxmbset = 0; + for (mbno = 0; mbno < config->nrecvmb; mbno++) + { + /* Allocate a(nother) receive mailbox */ + + mbndx = can_mballoc(priv); + if (mbndx < 0) + { + candbg("ERROR: Failed to allocate mailbox %d: %d\n", mbno, mbndx); + return mbndx; + } + + /* Add the allocated mailbox to the set of receive mailboxes */ + + priv->rxmbset |= (1 << mbndx); + + canvdbg("CAN%d Mailbox %d: Index=%d rxmbset=%02x\n", + config->port, mbno, mbndx, priv->rxmbset); + + /* Set up the message ID and filter mask + * REVISIT: This logic should be capable of setting up standard + * filters when CONFIG_CAN_EXTID is selected. + */ + +#ifdef CONFIG_CAN_EXTID + can_putreg(priv, SAM_CAN_MnID_OFFSET(mbndx), + CAN_MID_EXTID(config->filter[mbno].addr)); + can_putreg(priv, SAM_CAN_MnAM_OFFSET(mbndx), + CAN_MAM_EXTID(config->filter[mbno].mask)); +#else + can_putreg(priv, SAM_CAN_MnID_OFFSET(mbndx), + CAN_MID_STDID(config->filter[mbno].addr)); + can_putreg(priv, SAM_CAN_MnAM_OFFSET(mbndx), + CAN_MAM_STDID(config->filter[mbno].mask)); +#endif + + /* Note: Chaining is not supported. All receive mailboxes are + * configured in normal receive mode. + * + * REVISIT: Chaining would be needed if you want to support + * multipart messages. + */ + + can_putreg(priv, SAM_CAN_MnMR_OFFSET(mbndx), CAN_MMR_MOT_RX); + + /* Clear pending interrupts and start reception of the next message */ + + can_putreg(priv, SAM_CAN_MnCR_OFFSET(mbndx), CAN_MCR_MTCR); + + /* Enable interrupts from this mailbox */ + + can_putreg(priv, SAM_CAN_IER_OFFSET, CAN_INT_MB(mbndx)); + } + + return OK; +} + +/**************************************************************************** + * Name: can_reset + * + * Description: + * Reset the CAN device. Called early to initialize the hardware. This + * function is called, before can_setup() and on error conditions. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_reset(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv; + FAR const struct sam_config_s *config; + int i; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("CAN%d\n", config->port); + UNUSED(config); + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* Disable all interrupts */ + + can_putreg(priv, SAM_CAN_IDR_OFFSET, CAN_INT_ALL); + + /* Disable all mailboxes */ + + for (i = 0; i < SAM_CAN_NMAILBOXES; i++) + { + can_putreg(priv, SAM_CAN_MnMR_OFFSET(i), 0); + } + + /* All mailboxes are again available */ + + priv->freemb = CAN_ALL_MAILBOXES; + + /* Disable the CAN controller */ + + can_putreg(priv, SAM_CAN_MR_OFFSET, 0); + can_semgive(priv); +} + +/**************************************************************************** + * Name: can_setup + * + * Description: + * Configure the CAN. This method is called the first time that the CAN + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching CAN interrupts. + * All CAN interrupts are disabled upon return. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_setup(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv; + FAR const struct sam_config_s *config; + int ret; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("CAN%d pid: %d\n", config->port, config->pid); + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* CAN hardware initialization */ + + ret = can_hwinitialize(priv); + if (ret < 0) + { + canlldbg("CAN%d H/W initialization failed: %d\n", config->port, ret); + return ret; + } + + can_dumpctrlregs(priv, "After hardware initialization"); + can_dumpmbregs(priv, NULL); + + /* Attach the CAN interrupt handler */ + + ret = irq_attach(config->pid, config->handler); + if (ret < 0) + { + canlldbg("Failed to attach CAN%d IRQ (%d)", config->port, config->pid); + return ret; + } + + /* Setup receive mailbox(es) (enabling receive interrupts) */ + + ret = can_recvsetup(priv); + if (ret < 0) + { + canlldbg("CAN%d H/W initialization failed: %d\n", config->port, ret); + return ret; + } + + /* Enable all error interrupts */ + +#ifdef CONFIG_DEBUG + can_putreg(priv, SAM_CAN_IER_OFFSET, CAN_DEBUG_INTS); +#endif + + can_dumpctrlregs(priv, "After receive setup"); + can_dumpmbregs(priv, NULL); + + /* Enable the interrupts at the AIC. */ + + up_enable_irq(config->pid); + can_semgive(priv); + return OK; +} + +/**************************************************************************** + * Name: can_shutdown + * + * Description: + * Disable the CAN. This method is called when the CAN device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_shutdown(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv; + FAR const struct sam_config_s *config; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("CAN%d\n", config->port); + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* Disable the CAN interrupts */ + + up_disable_irq(config->pid); + + /* Detach the CAN interrupt handler */ + + irq_detach(config->pid); + + /* And reset the hardware */ + + can_reset(dev); + can_semgive(priv); +} + +/**************************************************************************** + * Name: can_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_rxint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + DEBUGASSERT(priv && priv->config); + + canllvdbg("CAN%d enable: %d\n", priv->config->port, enable); + + /* Enable/disable the mailbox interrupts from all receive mailboxes */ + + if (enable) + { + can_putreg(priv, SAM_CAN_IER_OFFSET, priv->rxmbset); + } + else + { + can_putreg(priv, SAM_CAN_IDR_OFFSET, priv->rxmbset); + } +} + +/**************************************************************************** + * Name: can_txint + * + * Description: + * Call to enable or disable TX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_txint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + DEBUGASSERT(priv && priv->config); + + canllvdbg("CAN%d enable: %d\n", priv->config->port, enable); + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* Support disabling interrupts on any mailboxes that are actively + * transmitting (txmbset); also suppress enabling new TX mailbox until + * txdisabled is reset by this function. + */ + + if (enable) + { + can_putreg(priv, SAM_CAN_IER_OFFSET, priv->txmbset); + priv->txdisabled = false; + } + else + { + can_putreg(priv, SAM_CAN_IDR_OFFSET, priv->txmbset); + priv->txdisabled = true; + } + + can_semgive(priv); +} + +/**************************************************************************** + * Name: can_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) +{ + /* No CAN ioctls are supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Name: can_remoterequest + * + * Description: + * Send a remote request + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id) +{ + /* REVISIT: Remote request not implemented */ + + return -ENOSYS; +} + +/**************************************************************************** + * Name: can_send + * + * Description: + * Send one can message. + * + * One CAN-message consists of a maximum of 10 bytes. A message is + * composed of at least the first 2 bytes (when there are no data bytes). + * + * Byte 0: Bits 0-7: Bits 3-10 of the 11-bit CAN identifier + * Byte 1: Bits 5-7: Bits 0-2 of the 11-bit CAN identifier + * Bit 4: Remote Tranmission Request (RTR) + * Bits 0-3: Data Length Code (DLC) + * Bytes 2-10: CAN data + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) +{ + FAR struct sam_can_s *priv; + FAR uint8_t *ptr; + uint32_t regval; + int mbndx; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv && priv->config); + + canllvdbg("CAN%d\n", priv->config->port); + canllvdbg("CAN%d ID: %d DLC: %d\n", + priv->config->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc); + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* Allocate a mailbox */ + + mbndx = can_mballoc(priv); + if (mbndx < 0) + { + candbg("ERROR: CAN%d failed to allocate a mailbox: %d\n", + priv->config->port, mbndx); + return mbndx; + } + + priv->txmbset |= (1 << mbndx); + + canvdbg("Mailbox Index=%d txmbset=%02x\n", mbndx, priv->txmbset); + + /* Set up the ID and mask, standard 11-bit or extended 29-bit. + * REVISIT: This logic should be capable of sending standard messages + * when CONFIG_CAN_EXTID is selected. + */ + +#ifdef CONFIG_CAN_EXTID + DEBUGASSERT(msg->cm_hdr.ch_extid); + DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 29)); + can_putreg(priv, SAM_CAN_MnID_OFFSET(mbndx), CAN_MID_EXTID(msg->cm_hdr.ch_id)); +#else + DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 11)); + can_putreg(priv, SAM_CAN_MnID_OFFSET(mbndx), CAN_MID_STDID(msg->cm_hdr.ch_id)); +#endif + + /* Enable transmit mode */ + + can_putreg(priv, SAM_CAN_MnMR_OFFSET(mbndx), CAN_MMR_MOT_TX); + + /* After Transmit Mode is enabled, the MRDY flag in the CAN_MSR register + * is automatically set until the first command is sent. When the MRDY + * flag is set, the software application can prepare a message to be sent + * by writing to the CAN_MDx registers. The message is sent once the + * software asks for a transfer command setting the MTCR bit and the + * message data length in the CAN_MCRx register. + */ + + DEBUGASSERT((can_getreg(priv, SAM_CAN_MnSR_OFFSET(mbndx)) & CAN_MSR_MRDY) != 0); + + /* Bytes are received/sent on the bus in the following order: + * + * 1. CAN_MDL[7:0] + * 2. CAN_MDL[15:8] + * 3. CAN_MDL[23:16] + * 4. CAN_MDL[31:24] + * 5. CAN_MDH[7:0] + * 6. CAN_MDH[15:8] + * 7. CAN_MDH[23:16] + * 8. CAN_MDH[31:24] + */ + +#ifdef CONFIG_ENDIAN_BIG +# warning REVISIT +#endif + + /* The message buffer is probably not properaly aligned for 32-bit accesses */ + + ptr = msg->cm_data; + regval = CAN_MDL0(ptr[0]) | CAN_MDL1(ptr[1]) | CAN_MDL2(ptr[2]) | CAN_MDL3(ptr[3]); + can_putreg(priv, SAM_CAN_MnDL_OFFSET(mbndx), regval); + + regval = CAN_MDH4(ptr[4]) | CAN_MDH5(ptr[5]) | CAN_MDH6(ptr[6]) | CAN_MDH7(ptr[7]); + can_putreg(priv, SAM_CAN_MnDH_OFFSET(mbndx), regval); + + /* Set the DLC value in the CAN_MCRx register. Set the MTCR register + * clearing MRDY, and indicating that the message is ready to be sent. + */ + + regval = CAN_MCR_MDLC(msg->cm_hdr.ch_dlc) | CAN_MCR_MTCR; + can_putreg(priv, SAM_CAN_MnCR_OFFSET(mbndx), regval); + + /* If we have not been asked to suppress TX interrupts, then enable + * interrupts from this mailbox now. + */ + + if (!priv->txdisabled) + { + can_putreg(priv, SAM_CAN_IER_OFFSET, CAN_INT_MB(mbndx)); + } + + can_dumpmbregs(priv, "After send"); + can_semgive(priv); + return OK; +} + +/**************************************************************************** + * Name: can_txready + * + * Description: + * Return true if the CAN hardware can accept another TX message. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if the CAN hardware is ready to accept another TX message. + * + ****************************************************************************/ + +static bool can_txready(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + bool txready; + + /* Get exclusive access to the CAN peripheral */ + + can_semtake(priv); + + /* Return true not all mailboxes are in-use */ + + txready = ((priv->rxmbset | priv->txmbset) != CAN_ALL_MAILBOXES); + + can_semgive(priv); + return txready; +} + +/**************************************************************************** + * Name: can_txempty + * + * Description: + * Return true if all message have been sent. If for example, the CAN + * hardware implements FIFOs, then this would mean the transmit FIFO is + * empty. This method is called when the driver needs to make sure that + * all characters are "drained" from the TX hardware before calling + * co_shutdown(). + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if there are no pending TX transfers in the CAN hardware. + * + ****************************************************************************/ + +static bool can_txempty(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + return (priv->txmbset == 0); +} + +/**************************************************************************** + * Name: can_rxinterrupt + * + * Description: + * CAN RX mailbox interrupt handler + * + * Input Parameters: + * priv - CAN-specific private data + * mbndx - The index of the mailbox that generated the interrupt + * msr - Applicable value from the mailbox status register + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void can_rxinterrupt(FAR struct can_dev_s *dev, int mbndx, + uint32_t msr) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + struct can_hdr_s hdr; + uint32_t md[2]; + uint32_t mid; + int ret; + + /* REVISIT: Check the MMI bit in CAN_MSRx to determine messages have been + * lost. + */ + + /* Read the mailbox data. Bytes are received/sent on the bus in the + * following order: + * + * 1. CAN_MDL[7:0] + * 2. CAN_MDL[15:8] + * 3. CAN_MDL[23:16] + * 4. CAN_MDL[31:24] + * 5. CAN_MDH[7:0] + * 6. CAN_MDH[15:8] + * 7. CAN_MDH[23:16] + * 8. CAN_MDH[31:24] + */ + +#ifdef CONFIG_ENDIAN_BIG +# warning REVISIT +#endif + + md[0] = can_getreg(priv, SAM_CAN_MnDH_OFFSET(mbndx)); + md[1] = can_getreg(priv, SAM_CAN_MnDL_OFFSET(mbndx)); + + /* Get the ID associated with the newly received message: )nce a new message + * is received, its ID is masked with the CAN_MAMx value and compared + * with the CAN_MIDx value. If accepted, the message ID is copied to the + * CAN_MIDx register. + */ + + mid = can_getreg(priv, SAM_CAN_MnID_OFFSET(mbndx)); + + /* Format the CAN header. + * REVISIT: This logic should be capable of receiving standard messages + * when CONFIG_CAN_EXTID is selected. + */ + +#ifdef CONFIG_CAN_EXTID + /* Save the extended ID of the newly received message */ + + hdr.ch_id = (mid & CAN_MAM_EXTID_MASK) >> CAN_MAM_EXTID_SHIFT; + hdr.ch_extid = true; +#else + /* Save the standard ID of the newly received message */ + + hdr.ch_id = (mid & CAN_MAM_STDID_MASK) >> CAN_MAM_STDID_SHIFT; +#endif + + hdr.ch_dlc = (msr & CAN_MSR_MDLC_MASK) >> CAN_MSR_MDLC_SHIFT; + hdr.ch_rtr = 0; +#ifdef CONFIG_CAN_ERRORS + hdr.ch_error = 0; /* Error reporting not supported */ +#endif + hdr.ch_unused = 0; + + /* And provide the CAN message to the upper half logic */ + + ret = can_receive(dev, &hdr, (FAR uint8_t *)md); + if (ret < 0) + { + canlldbg("ERROR: can_receive failed: %d\n", ret); + } + + /* Set the MTCR flag in the CAN_MCRx register. This clears the + * MRDY bit, notifices the hardware that processing has ended, and + * requests a new RX transfer. + */ + + can_putreg(priv, SAM_CAN_MnCR_OFFSET(mbndx), CAN_MCR_MTCR); +} + +/**************************************************************************** + * Name: can_txinterrupt + * + * Description: + * CAN TX mailbox interrupt handler + * + * Input Parameters: + * priv - CAN-specific private data + * mbndx - The index of the mailbox that generated the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void can_txinterrupt(FAR struct can_dev_s *dev, int mbndx) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + + /* REVISIT: Check the MABT bit in CAN_MSRx to determine if the transfer + * was aborted. + */ + + /* Disable and free the mailbox */ + + can_mbfree(priv, mbndx); + + /* Report that the TX transfer is complete to the upper half logic */ + + can_txdone(dev); +} + +/**************************************************************************** + * Name: can_mbinterrupt + * + * Description: + * CAN mailbox interrupt handler + * + * Input Parameters: + * priv - CAN-specific private data + * mbndx - The index of the mailbox that generated the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void can_mbinterrupt(FAR struct can_dev_s *dev, int mbndx) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + uint32_t msr; + uint32_t mmr; + + /* There are two causes of mailbox interrupts: + * + * - Data registers in the mailbox object are available to the + * application. In Receive Mode, a new message was received. In Transmit + * Mode, a message was transmitted successfully. + * - A sent transmission was aborted. + * + * Both conditions are are reported by the MRDY bit in the CAN_MSR + * register. + */ + + msr = can_getreg(priv, SAM_CAN_MnSR_OFFSET(mbndx)); + if ((msr & (CAN_MSR_MRDY | CAN_MSR_MABT)) != 0) + { + /* Handle the result based on how the mailbox was configured */ + + mmr = can_getreg(priv, SAM_CAN_MnMR_OFFSET(mbndx)); + switch (mmr & CAN_MMR_MOT_MASK) + { + case CAN_MMR_MOT_RX: /* Reception Mailbox */ + can_rxinterrupt(dev, mbndx, msr); + break; + + case CAN_MMR_MOT_TX: /* Transmit mailbox */ + can_txinterrupt(dev, mbndx); + break; + + case CAN_MMR_MOT_RXOVRWR: /* Reception mailbox with overwrite */ + case CAN_MMR_MOT_CONSUMER: /* Consumer Mailbox */ + case CAN_MMR_MOT_PRODUCER: /* Producer Mailbox */ + case CAN_MMR_MOT_DISABLED: /* Mailbox is disabled */ + canlldbg("ERROR: CAN%d MB%d: Unsupported or invalid mailbox type\n", + priv->config->port, mbndx); + canlldbg(" MSR: %08x MMR: %08x\n", msr, mmr); + break; + } + } +} + +/**************************************************************************** + * Name: can_interrupt + * + * Description: + * Common CAN interrupt handler + * + * Input Parameters: + * priv - CAN-specific private data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_interrupt(FAR struct can_dev_s *dev) +{ + FAR struct sam_can_s *priv = dev->cd_priv; + uint32_t sr; + uint32_t imr; + uint32_t pending; + + DEBUGASSERT(priv && priv->config); + + /* Get the set of pending interrupts. + * + * All interrupts are cleared by clearing the interrupt source except for + * the internal timer counter overflow interrupt and the timestamp interrupt. + * These interrupts are cleared by reading the CAN_SR register. + */ + + sr = can_getreg(priv, SAM_CAN_SR_OFFSET); + imr = can_getreg(priv, SAM_CAN_IMR_OFFSET); + pending = sr & imr; + + /* There are two different types of interrupts. One type of interrupt is a + * message-object related interrupt, the other is a system interrupt that + * handles errors or system-related interrupt sources. + */ + + /* Check for message related interrupts + * + * - Data registers in the mailbox object are available to the + * application. In Receive Mode, a new message was received. In Transmit + * Mode, a message was transmitted successfully. + * - A sent transmission was aborted. + */ + + if ((pending & CAN_INT_MBALL) != 0) + { + int mbndx; + + /* Check for pending interrupts from each mailbox */ + + for (mbndx = 0; mbndx < SAM_CAN_NMAILBOXES; mbndx++) + { + /* Check for a pending interrupt for this mailbox */ + + if ((pending & CAN_INT_MB(mbndx)) != 0) + { + can_mbinterrupt(dev, mbndx); + } + } + } + + /* Check for system interrupts + * + * - Bus off interrupt: The CAN module enters the bus off state. + * - Error passive interrupt: The CAN module enters Error Passive Mode. + * - Error Active Mode: The CAN module is neither in Error Passive Mode + * nor in Bus Off mode. + * - Warn Limit interrupt: The CAN module is in Error-active Mode, but at + * least one of its error counter value exceeds 96. + * - Wake-up interrupt: This interrupt is generated after a wake-up and a + * bus synchronization. + * - Sleep interrupt: This interrupt is generated after a Low-power Mode + * enable once all pending messages in transmission have been sent. + * - Internal timer counter overflow interrupt: This interrupt is + * generated when the internal timer rolls over. + * - Timestamp interrupt: This interrupt is generated after the reception + * or the transmission of a start of frame or an end of frame. The value + * of the internal counter is copied in the CAN_TIMESTP register. + */ + + if ((pending & ~CAN_INT_MBALL) != 0) + { + canlldbg("ERROR: CAN%d system interrupt, SR=%08x IMR=%08x\n", + priv->config->port, sr, imr); + } +} + +/**************************************************************************** + * Name: can0_interrupt + * + * Description: + * CAN0 interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN0 +static int can0_interrupt(int irq, void *context) +{ + can_interrupt(&g_can0dev); + return OK; +} +#endif + +/**************************************************************************** + * Name: can0_interrupt + * + * Description: + * CAN0 interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN1 +static int can1_interrupt(int irq, void *context) +{ + can_interrupt(&g_can1dev); + return OK; +} +#endif + +/**************************************************************************** + * Name: can_bittiming + * + * Description: + * Set the CAN baudrate register (BR) based on the configured BAUD. + * + * Definitions: + * + * TIME QUANTUM. The TIME QUANTUM (Tq) is a fixed unit of time derived + * from the MCK period. The total number of TIME QUANTA in a bit time is + * programmable from 8 to 25. + * + * INFORMATION PROCESSING TIME. The Information Processing Time (IPT) + * is the time required for the logic to determine the bit level of a + * sampled bit. The IPT begins at the sample point, is measured in Tq + * and is fixed at 2 Tq for the Atmel CAN. + * + * SAMPLE POINT. The SAMPLE POINT is the point in time at which the + * bus level is read and interpreted as the value of that respective + * bit. Its location is at the end of PHASE_SEG1. + * + * The CAN protocol specification partitions the nominal bit time into + * four different segments: + * + * 1. Synchronization segment (SYNC_SEG): a bit change is expected to occur + * within this time segment. It has a fixed length of one time quantum + * (1 x tCAN). + * 2. Propogation segment (PROP_SEG): This part of the bit time is used + * to compensate for the physical delay times within the network. It is + * twice the sum of the signal’s propagation time on the bus line, the + * input comparator delay, and the output driver delay. It is + * programmable to be 1 to 8 Tq long. This parameter is defined in the + * PROPAG field of the CAN Baudrate Register. + * 3. Phase segment 1 (PHASE_SEG1): defines the location of the sample + * point. Phase Segment 1 is programmable to be 1-8 Tq long. + * 4. Phase segement 2 (PHASE_SEG2): defines the location of the transmit + * point.Phase Segment 2 length has to be at least as long as the + * Information Processing Time (IPT) and may not be more than the + * length of Phase Segment 1 (since Phase Segment 2 also begins at the + * sample point and is the last segment in the bit time). + * + * The Phase-Buffer-Segments are used to compensate for edge phase errors. + * These segments can be lengthened (PHASE SEG1) or shortened (PHASE SEG2) + * by resynchronization: + * + * SJW: ReSynchronization Jump Width. The ReSynchronization Jump Width + * defines the limit to the amount of lengthening or shortening of the + * Phase Segments. SJW is programmable to be the minimum of PHASE SEG1 + * and 4 Tq. + * + * In the CAN controller, the length of a bit on the CAN bus is determined + * by the parameters (BRP, PROPAG, PHASE1 and PHASE2). + * + * Tbit = Tcsc + Tprs + Tphs1 + Tphs2 + * + * Pictorially: + * + * |<----------------------- NOMINAL BIT TIME ------------------------>| + * |<- SYNC_SEG ->|<- PROP_SEG ->|<-- PHASE_SEG1 -->|<-- PHASE_SEG2 -->| + * |<--- Tcsc --->|<--- Tprs --->|<---- Tphs1 ----->|<---- Tphs2 ----->| + * |<--- 1 Tq --->|<-- 1-8 Tq -->|<---- 1-8 Tq ---->|<--- <= Tphs1 --->| + * + * Where + * Tcsc is the duration of the SYNC_SEG segment + * Tprs is the duration of the PROP_SEG segment + * Tphs1 is the duration of the PHASE_SEG1 segment + * Tphs2 is the duration of the PHASE_SEG2 segment + * Tq is the "Time Quantum" + * + * Relationships: + * + * baud = 1 / Tbit + * Tbit = Tq + Tprs + Tphs1 + Tphs2 + * Tq = (BRP + 1) / MCK + * Tprs = Tq * (PROPAG + 1) + * Tphs1 = Tq * (PHASE1 + 1) + * Tphs2 = Tq * (PHASE2 + 1) + * + * Input Parameter: + * config - A reference to the CAN constant configuration + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_bittiming(struct sam_can_s *priv) +{ + FAR const struct sam_config_s *config = priv->config; + uint32_t regval; + uint32_t brp; + uint32_t propag; + uint32_t phase1; + uint32_t phase2; + uint32_t sjw; + uint32_t t1t2; + uint8_t tq; + + /* Select the time quantum + * + * REVISIT: We could probably do a better job than this. + */ + + if (config->baud >= 1000) + { + tq = 8; + } + else + { + tq = 16; + } + + /* Calculate the baudrate prescaler (BRP). This depends only on the + * selected Tq value, the desired BAUD and the CAN peripheral clock + * frequency. + * + * Tq = (BRP + 1) / CAN_FRQUENCY + * Tbit = Nquanta * (BRP + 1) / Fcan + * baud = Fcan / (Nquanta * (brp + 1)) + * brp = Fcan / (baud * nquanta) - 1 + */ + + brp = (priv->frequency / (config->baud * 1000 * tq)) - 1; + if (brp == 0) + { + /* The BRP field must be within the range 1 - 0x7f */ + + candbg("CAN%d: baud %d too high\n", config->port, config->baud); + return -EINVAL; + } + + /* Propagation delay: + * + * Delay Bus Driver - 50ns + * Delay Receiver - 30ns + * Delay Bus Line (20m) - 110ns + */ + + propag = tq * config->baud * 2 * (50 + 30 + 110) / 1000000; + if (propag >= 1) + { + propag--; + } + else + { + propag = 0; + } + + /* This the time of the first two segments */ + + t1t2 = tq - 1 - (propag + 1); + + /* Calcuate phase1 and phase2 */ + + phase1 = (t1t2 >> 1) - 1; + phase2 = phase1; + + if ((t1t2 & 1) != 0) + { + phase2++; + } + + /* Calculate SJW */ + + if (1 > (4 / (phase1 + 1))) + { + sjw = 3; + } + else + { + sjw = phase1; + } + + if ((propag + phase1 + phase2) != (uint32_t)(tq - 4)) + { + candbg("CAN%d: Could not realize baud %d\n", config->port, config->baud); + return -EINVAL; + } + + regval = CAN_BR_PHASE2(phase2) | CAN_BR_PHASE1(phase1) | + CAN_BR_PROPAG(propag) | CAN_BR_SJW(sjw) | CAN_BR_BRP(brp) | + CAN_BR_ONCE; + can_putreg(priv, SAM_CAN_BR_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Name: can_autobaud + * + * Description: + * Use the SAMA5 auto-baud feature to correct the initial timing + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN block + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_CAN_AUTOBAUD +static int can_autobaud(struct sam_can_s *priv) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + canllvdbg("CAN%d\n", config->port); + + /* The CAN controller can start listening to the network in Autobaud Mode. + * In this case, the error counters are locked and a mailbox may be + * configured in Receive Mode. By scanning error flags, the CAN_BR + * register values synchronized with the network. + */ + + /* Configure a Mailbox in Reception Mode */ +#warning Missing Logic + + /* Loop, adjusting bit rate parameters until no errors are reported in + * either CAR_SR or the CAN_MSRx registers. + */ + + do + { + /* Adjust baud rate setting */ +#warning Missing Logic + + /* Autobaud Mode. The autobaud feature is enabled by setting the ABM + * field in the CAN_MR register. In this mode, the CAN controller is only + * listening to the line without acknowledging the received messages. It + * can not send any message. The errors flags are updated. The bit timing + * can be adjusted until no error occurs (good configuration found). In + * this mode, the error counters are frozen. + */ + + regval = can_getreg(priv, SAM_CAN_MR_OFFSET); + regval |= (CAN_MR_CANEN | CAN_MR_ABM); + can_putreg(priv, SAM_CAN_MR_OFFSET, regval); + +#warning Missing logic + } + while (no errors reported); + + /* Once no error has been detected, the application disables the Autobaud + * Mode, clearing the ABM field in the CAN_MR register. To go back to the + * standard mode, the ABM bit must be cleared in the CAN_MR register. + */ + + regval = can_getreg(priv, SAM_CAN_MR_OFFSET); + regval &= ~(CAN_MR_CANEN | CAN_MR_ABM); + can_putreg(priv, SAM_CAN_MR_OFFSET, regval); + + return OK; +} +#endif + +/**************************************************************************** + * Name: can_hwinitialize + * + * Description: + * CAN cell initialization + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN peripheral + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int can_hwinitialize(struct sam_can_s *priv) +{ + FAR const struct sam_config_s *config = priv->config; + uint32_t regval; + uint32_t mck; + int ret; + + canllvdbg("CAN%d\n", config->port); + + /* Configure CAN pins */ + + sam_configpio(config->rxpinset); + sam_configpio(config->txpinset); + + /* Determine the maximum CAN peripheral clock frequency */ + + mck = BOARD_MCK_FREQUENCY; + if (mck <= SAM_CAN_MAXPERCLK) + { + priv->frequency = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= SAM_CAN_MAXPERCLK) + { + priv->frequency = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= SAM_CAN_MAXPERCLK) + { + priv->frequency = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else if ((mck >> 3) <= SAM_CAN_MAXPERCLK) + { + priv->frequency = (mck >> 3); + regval = PMC_PCR_DIV8; + } + else + { + candbg("ERROR: Cannot realize CAN input frequency\n"); + return -EINVAL; + } + + /* Set the maximum CAN peripheral clock frequency */ + + regval |= PMC_PCR_PID(config->pid) | PMC_PCR_CMD | PMC_PCR_EN; + can_putreg(priv, SAM_PMC_PCR, regval); + + /* Enable peripheral clocking */ + + sam_enableperiph1(config->pid); + + /* Disable all CAN interrupts */ + + can_putreg(priv, SAM_CAN_IDR_OFFSET, CAN_INT_ALL); + + /* Configure bit timing. */ + + ret = can_bittiming(priv); + if (ret < 0) + { + candbg("ERROR: Failed to set bit timing: %d\n", ret); + return ret; + } + +#ifdef CONFIG_SAMA5_CAN_AUTOBAUD + /* Optimize/correct bit timing */ + + ret = can_autobaud(priv); + if (ret < 0) + { + candbg("ERROR: can_autobaud failed: %d\n", ret); + return ret; + } +#endif + + /* The CAN controller is enabled by setting the CANEN flag in the CAN_MR + * register. At this stage, the internal CAN controller state machine is + * reset, error counters are reset to 0, error flags are reset to 0. + */ + + regval = can_getreg(priv, SAM_CAN_MR_OFFSET); + regval |= CAN_MR_CANEN; + can_putreg(priv, SAM_CAN_MR_OFFSET, regval); + + /* Once the CAN controller is enabled, bus synchronization is done + * automatically by scanning eleven recessive bits. The WAKEUP bit in + * the CAN_SR register is automatically set to 1 when the CAN controller + * is synchronized (WAKEUP and SLEEP are stuck at 0 after a reset). + */ + + while ((can_getreg(priv, SAM_CAN_SR_OFFSET) & CAN_INT_WAKEUP) == 0); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_caninitialize + * + * Description: + * Initialize the selected CAN port + * + * Input Parameter: + * Port number (for hardware that has mutiple CAN interfaces) + * + * Returned Value: + * Valid CAN device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct can_dev_s *sam_caninitialize(int port) +{ + FAR struct can_dev_s *dev; + FAR struct sam_can_s *priv; + FAR const struct sam_config_s *config; + + canvdbg("CAN%d\n", port); + + /* NOTE: Peripherical clocking for CAN0 and/or CAN1 was already provided + * by sam_clockconfig() early in the reset sequence. + */ + +#ifdef CONFIG_SAMA5_CAN0 + if (port == 0) + { + /* Select the CAN0 device structure */ + + dev = &g_can0dev; + priv = &g_can0priv; + config = &g_can0const; + } + else +#endif +#ifdef CONFIG_SAMA5_CAN1 + if (port == 1) + { + /* Select the CAN1 device structure */ + + dev = &g_can1dev; + priv = &g_can1priv; + config = &g_can1const; + } + else +#endif + { + candbg("ERROR: Unsupported port %d\n", port); + return NULL; + } + + /* Is this the first time that we have handed out this device? */ + + if (!priv->initialized) + { + /* Yes, then perform one time data initialization */ + + memset(priv, 0, sizeof(struct sam_can_s)); + priv->config = config; + priv->freemb = CAN_ALL_MAILBOXES; + priv->initialized = true; + + sem_init(&priv->exclsem, 0, 1); + + dev->cd_ops = &g_canops; + dev->cd_priv = (FAR void *)priv; + + /* And put the hardware in the intial state */ + + can_reset(dev); + } + + return dev; +} + +#endif /* CONFIG_CAN && (CONFIG_SAMA5_CAN0 || CONFIG_SAMA5_CAN1) */ diff --git a/arch/arm/src/sama5/sam_can.h b/arch/arm/src/sama5/sam_can.h new file mode 100644 index 0000000000000000000000000000000000000000..c18361533f28bfeb54112d83bcc786395f8c00b2 --- /dev/null +++ b/arch/arm/src/sama5/sam_can.h @@ -0,0 +1,146 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_can.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_CAN_H +#define __ARCH_ARM_SRC_SAMA5_SAM_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_can.h" + +#include + +#if defined(CONFIG_CAN) && (defined(CONFIG_SAMA5_CAN0) || defined(CONFIG_SAMA5_CAN1)) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +/* CAN BAUD */ + +#if defined(CONFIG_SAMA5_CAN0) && !defined(CONFIG_SAMA5_CAN0_BAUD) +# error "CONFIG_SAMA5_CAN0_BAUD is not defined" +#endif + +#if defined(CONFIG_SAMA5_CAN1) && !defined(CONFIG_SAMA5_CAN1_BAUD) +# error "CONFIG_SAMA5_CAN1_BAUD is not defined" +#endif + +/* There must be at least one but not more than three receive mailboxes */ + +#ifdef CONFIG_SAMA5_CAN0 +# if !defined(CONFIG_SAMA5_CAN0_NRECVMB) || CONFIG_SAMA5_CAN0_NRECVMB < 1 +# undef CONFIG_SAMA5_CAN0_NRECVMB +# define CONFIG_SAMA5_CAN0_NRECVMB 1 +# endif +# if CONFIG_SAMA5_CAN0_NRECVMB > 3 +# warning Current implementation only supports up to three receive mailboxes +# undef CONFIG_SAMA5_CAN0_NRECVMB +# define CONFIG_SAMA5_CAN0_NRECVMB 3 +# endif +#else +# undef CONFIG_SAMA5_CAN0_NRECVMB +# define CONFIG_SAMA5_CAN0_NRECVMB 0 +#endif + +#ifdef CONFIG_SAMA5_CAN1 +# if !defined(CONFIG_SAMA5_CAN1_NRECVMB) || CONFIG_SAMA5_CAN1_NRECVMB < 1 +# undef CONFIG_SAMA5_CAN1_NRECVMB +# define CONFIG_SAMA5_CAN1_NRECVMB 1 +# endif +# if CONFIG_SAMA5_CAN1_NRECVMB > 3 +# warning Current implementation only supports up to three receive mailboxes +# undef CONFIG_SAMA5_CAN1_NRECVMB +# define CONFIG_SAMA5_CAN1_NRECVMB 3 +# endif +#else +# undef CONFIG_SAMA5_CAN1_NRECVMB +# define CONFIG_SAMA5_CAN1_NRECVMB 0 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: sama5_caninitialize + * + * Description: + * Initialize the selected CAN port + * + * Input Parameter: + * Port number: 0=CAN0, 1=CAN1 + * + * Returned Value: + * Valid CAN device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct can_dev_s; +FAR struct can_dev_s *sam_caninitialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_CAN && (CONFIG_SAMA5_CAN0 || CONFIG_SAMA5_CAN1) */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_CAN_H */ diff --git a/arch/arm/src/sama5/sam_clockconfig.c b/arch/arm/src/sama5/sam_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..f743c7ae9a2d1afb27dd25b179db920adf022d72 --- /dev/null +++ b/arch/arm/src/sama5/sam_clockconfig.c @@ -0,0 +1,714 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_clockconfig.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_periphclks.h" +#include "sam_clockconfig.h" +#include "chip/sam_pmc.h" +#include "chip/sam_sfr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Do we need to setup the POLL? Yes if we are booting from ISRAM or NOR + * FLASH on CS0. + */ + +#undef NEED_PLLSETUP +#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) +# define NEED_PLLSETUP 1 +#endif + +/* Do we need to configure the UPLL */ + +#if !defined(CONFIG_SAMA5_EHCI) && !defined(CONFIG_SAMA5_OHCI) && \ + !defined(CONFIG_SAMA5_UDPHS) + + /* No... ignore the board setup */ + +# undef BOARD_USE_UPLL +#endif + +/* Problems have been seen when reconfiguring the PLL while executing out + * of NOR FLASH on CS0. In that case, we required RAM function support. The + * critical functions will be copied from NOR into ISRAM for execution. This + * prevents any strange behavior from the NOR while we reconfigure the PLL. + */ + +#if defined(CONFIG_SAMA5_BOOT_CS0FLASH) && !defined(CONFIG_ARCH_RAMFUNCS) +# error "CONFIG_ARCH_RAMFUNCS must be defined for this logic" +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pmcwait + * + * Description: + * Wait for the specide PMC status bit to become "1" + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) || defined(BOARD_USE_UPLL) +static void __ramfunc__ sam_pmcwait(uint32_t bit) +{ + /* There is no timeout on this wait. Why not? Because the symptoms there + * is no fallback if the wait times out and if the wait does time out, it + * can be very difficult to determine what happened. Much better to just + * hang here. + */ + + while ((getreg32(SAM_PMC_SR) & bit) == 0); +} +#endif + +/**************************************************************************** + * Name: sam_enablemosc + * + * Description: + * Enable the main oscillator + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_enablemosc(void) +{ + uint32_t regval; + + /* Switch from the internal 12MHz RC to the main external oscillator */ + + if ((getreg32(SAM_PMC_CKGR_MOR) & PMC_CKGR_MOR_MOSCSEL) == 0) + { + /* Enable main external oscillator */ + + regval = getreg32(SAM_PMC_CKGR_MOR); + regval |= PMC_CKGR_MOR_MOSCXTEN | PMC_CKGR_MOR_KEY; + putreg32(regval, SAM_PMC_CKGR_MOR); + + /* Wait for the main clock to become ready */ + + while ((getreg32(SAM_PMC_CKGR_MCFR) & PMC_CKGR_MCFR_MAINFRDY) == 0); + + /* Disable external OSC 12 MHz bypass */ + + regval = getreg32(SAM_PMC_CKGR_MOR); + regval &= ~PMC_CKGR_MOR_MOSCXTBY; + regval |= PMC_CKGR_MOR_KEY; + putreg32(regval, SAM_PMC_CKGR_MOR); + + /* Switch main clock source to the external oscillator */ + + regval = getreg32(SAM_PMC_CKGR_MOR); + regval |= (PMC_CKGR_MOR_MOSCSEL | PMC_CKGR_MOR_KEY); + putreg32(regval, SAM_PMC_CKGR_MOR); + + /* Wait for the main clock status change for the external oscillator + * selection. + */ + + sam_pmcwait(PMC_INT_MOSCSELS); + + /* And handle the case where MCK is running on main CLK */ + + sam_pmcwait(PMC_INT_MCKRDY); + } +} +#endif + +/**************************************************************************** + * Name: sam_selectmosc + * + * Description: + * Select the main oscillator as the input clock for processor clock (PCK) + * and the main clock (MCK). The PCK and MCK differ only by the MDIV + * divisor that permits the MCK to run at a lower rate. + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_selectmosc(void) +{ + uint32_t regval; + + /* Select the main oscillator as the input clock for PCK and MCK */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_CSS_MASK; + regval |= PMC_MCKR_CSS_MAIN; + putreg32(regval, SAM_PMC_MCKR); + + /* Wait for main clock to be ready */ + + sam_pmcwait(PMC_INT_MCKRDY); +} +#endif + +/**************************************************************************** + * Name: sam_pllasetup + * + * Description: + * Select the main oscillator as the input clock for processor clock (PCK) + * and the main clock (MCK). The PCK and MCK differ only by the MDIV + * divisor that permits the MCK to run at a lower rate. + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_pllasetup(void) +{ + uint32_t regval; + + /* Configure PLLA */ + +#ifdef SAMA5_HAVE_PLLAR_DIV + regval = (BOARD_CKGR_PLLAR_DIV | BOARD_CKGR_PLLAR_COUNT | + BOARD_CKGR_PLLAR_OUT | BOARD_CKGR_PLLAR_MUL | + PMC_CKGR_PLLAR_ONE); +#else + regval = (PMC_CKGR_PLLAR_DIV_BYPASS | BOARD_CKGR_PLLAR_COUNT | + BOARD_CKGR_PLLAR_OUT | BOARD_CKGR_PLLAR_MUL | + PMC_CKGR_PLLAR_ONE); +#endif + + putreg32(regval, SAM_PMC_CKGR_PLLAR); + + /* Set the PLL Charge Pump Current Register to zero */ + + putreg32(0, SAM_PMC_PLLICPR); + + /* And wait for the PLL to lock on */ + + sam_pmcwait(PMC_INT_LOCKA); +} +#endif + +/**************************************************************************** + * Name: sam_plladivider + * + * Description: + * Configure MCK PLLA divider + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_plladivider(void) +{ + uint32_t regval; + + /* Is the PLLA divider currently set? */ + + regval = getreg32(SAM_PMC_MCKR); + if ((regval & PMC_MCKR_PLLADIV2) != 0) + { +#if BOARD_PMC_MCKR_PLLADIV == 0 + /* The divider is set and we are configured to clear it */ + + regval &= ~PMC_MCKR_PLLADIV2; +#else + /* The divider is already set */ + + return; +#endif + } + else + { +#if BOARD_PMC_MCKR_PLLADIV == 0 + /* The divider is already cleared */ + + return; +#else + /* The divider is clear and we are configured to set it */ + + regval |= PMC_MCKR_PLLADIV2; +#endif + } + + /* Set/clear the divider */ + + putreg32(regval, SAM_PMC_MCKR); + + /* We changed the PLLA divider. Wait for the main clock to be ready again */ + + sam_pmcwait(PMC_INT_MCKRDY); +} +#endif + +/**************************************************************************** + * Name: sam_mckprescaler + * + * Description: + * Configure main clock (MCK) Prescaler + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_mckprescaler(void) +{ + uint32_t regval; + + /* Set the main clock prescaler */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_PRES_MASK; + regval |= BOARD_PMC_MCKR_PRES; + putreg32(regval, SAM_PMC_MCKR); + + /* Wait for the main clock to be ready again */ + + sam_pmcwait(PMC_INT_MCKRDY); +} +#endif + +/**************************************************************************** + * Name: sam_mckdivider + * + * Description: + * Configure main clock (MCK) divider (MDIV). This divider allows the MCK + * to run at a lower rate then PCK. + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_mckdivider(void) +{ + uint32_t regval; + + /* Set the main clock divider */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_MDIV_MASK; + regval |= BOARD_PMC_MCKR_MDIV; + putreg32(regval, SAM_PMC_MCKR); + + /* Wait for the main clock to be ready again */ + + sam_pmcwait(PMC_INT_MCKRDY); +} +#endif + +/**************************************************************************** + * Name: sam_h32mxdivider + * + * Description: + * Set the H32MX divider. + * + * 0: The AHB 32-bit Matrix frequency is equal to the AHB 64-bit Matrix + * frequency. It is possible only if the AHB 64-bit Matrix frequency + * does not exceed 90 MHz. + * 1: H32MXDIV2 The AHB 32-bit Matrix frequency is equal to the AHB 64-bit + * Matrix frequency divided by 2. + * + ****************************************************************************/ + +#if defined(PMC_MCKR_H32MXDIV) && defined(NEED_PLLSETUP) +static void __ramfunc__ sam_h32mxdivider(void) +{ + uint32_t regval; + + regval = getreg32(SAM_PMC_MCKR); + + /* Check the 64-bit Matrix frequency (MCK, right?) */ + + if (BOARD_MCK_FREQUENCY <= 90000000) + { + regval &= ~PMC_MCKR_H32MXDIV; + } + else + { + regval |= PMC_MCKR_H32MXDIV; + } + + putreg32(regval, SAM_PMC_MCKR); +} +#else +# define sam_h32mxdivider() +#endif + +/**************************************************************************** + * Name: sam_selectplla + * + * Description: + * Select the PLLA output as the input clock for PCK and MCK. + * + ****************************************************************************/ + +#if defined(NEED_PLLSETUP) +static void __ramfunc__ sam_selectplla(void) +{ + uint32_t regval; + + /* Select the PLLA output as the main clock input */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_CSS_MASK; + regval |= BOARD_PMC_MCKR_CSS; + putreg32(regval, SAM_PMC_MCKR); + + /* Wait for the main clock to be ready again */ + + sam_pmcwait(PMC_INT_MCKRDY); +} +#endif + +/**************************************************************************** + * Name: sam_usbclockconfig + * + * Description: + * Configure clocking for USB. + * + ****************************************************************************/ + +static inline void sam_usbclockconfig(void) +{ +#if defined(CONFIG_SAMA5_EHCI) || defined(CONFIG_SAMA5_OHCI) || \ + defined(CONFIG_SAMA5_UDPHS) + + /* We can either get the clock from the UPLL or from PLLA. In this latter + * case, however, the PLLACK frequency must be a multiple of 48MHz. + */ + +#if defined(BOARD_USE_UPLL) + uint32_t regval; + + /* The USB Host High Speed requires a 480 MHz clock (UPLLCK) for the + * embedded High-speed transceivers. UPLLCK is the output of the 480 MHz + * UTMI PLL (UPLL). The source clock of the UTMI PLL is the Main OSC output: + * Either the 12MHz internal oscillator on a 12MHz crystal. The Main OSC + * must be 12MHz because the UPLL has a built-in 40x multiplier. + * + * For High-speed operations, the user has to perform the following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in + * PMC_PCER register. + * 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. + * 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. + * 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register + * 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. + * 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is + * selected. + * 8) Enable OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 2 through 7 performed here. 1 and 8 are performed in the EHCI + * driver is initialized. + */ + + /* 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. */ + + regval = PMC_CKGR_UCKR_UPLLCOUNT(BOARD_CKGR_UCKR_UPLLCOUNT); + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. */ + + regval |= PMC_CKGR_UCKR_UPLLEN; + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register */ + + sam_pmcwait(PMC_INT_LOCKU); + + /* 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. */ + + regval |= PMC_CKGR_UCKR_BIASCOUNT(BOARD_CKGR_UCKR_BIASCOUNT); + putreg32(regval, SAM_PMC_CKGR_UCKR); + + regval |= PMC_CKGR_UCKR_BIASEN; + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + */ + + regval = PMC_USB_USBS_UPLL; + putreg32(regval, SAM_PMC_USB); + + /* 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is + * selected. + * + * REVISIT: The divisor of 10 produces a rate that is too high with + * SAMA5D3. A divisor of 5, however, seems to work just fine for the + * SAMA5D3. The SAMA5D4, on the other hand, needs the divisor of 10. + * No idea why? Let the board.h file decide which to use. + */ + + regval |= PMC_USB_USBDIV(BOARD_UPLL_OHCI_DIV-1); + putreg32(regval, SAM_PMC_USB); + +#else /* BOARD_USE_UPLL */ + /* For OHCI Full-speed operations only, the user has to perform the + * following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in PMC_PCER + * register. + * 2) Select PLLACK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 3) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV value is calculated regarding the PLLACK + * value and USB Full-speed accuracy. + * 4) Enable the OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 2 and 3 are done here. 1 and 2 are performed with the OHCI + * driver is initialized. + */ + + putreg32(BOARD_OHCI_INPUT | BOARD_OHCI_DIVIDER << PMC_USB_USBDIV_SHIFT, + SAM_PMC_USB); + +#endif /* BOARD_USE_UPLL */ +#endif /* CONFIG_SAMA5_EHCI ||CONFIG_SAMA5_OHCI) || CONFIG_SAMA5_UDPHS */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. (After power-on reset, the SAMA5 + * is initially running on a 12MHz internal RC clock). This function also + * performs other low-level chip initialization of the chip including master + * clock, IRQ & watchdog configuration. + * + * Boot Sequence + * + * This logic may be executing in ISRAM or in external mmemory: CS0, DDR, + * CS1, CS2, or CS3. It may be executing in CS0 or ISRAM through the + * action of the SAMA5 "first level bootloader;" it might be executing in + * CS1-3 through the action of some second level bootloader that provides + * configuration for those memories. + * + * The system always boots from the ROM memory at address 0x0000:0000, + * starting the internal first level bootloader. That bootloader can be + * configured to work in different ways using the BMS pin and the contents + * of the Boot Sequence Configuration Register (BSC_CR). + * + * If the BMS_BIT is read "0", then the first level bootloader will + * support execution of code in the memory connected to CS0 on the EBI + * interface (presumably NOR flash). The following sequence is performed + * by the first level bootloader if BMS_BIT is "0": + * + * - The main clock is the on-chip 12 MHz RC oscillator, + * - The Static Memory Controller is configured with timing allowing + * code execution in CS0 external memory at 12 MHz + * - AXI matrix is configured to remap EBI CS0 address at 0x0 + * - 0x0000:0000 is loaded in the Program Counter register + * + * The user software in the external memory must perform the next + * operation in order to complete the clocks and SMC timings configuration + * to run at a higher clock frequency: + * + * - Enable the 32768 Hz oscillator if best accuracy is needed + * - Reprogram the SMC setup, cycle, hold, mode timing registers for EBI + * CS0, to adapt them to the new clock. + * - Program the PMC (Main Oscillator Enable or Bypass mode) + * - Program and Start the PLL + * - Switch the system clock to the new value + * + * If the BMS_BIT is read "1", then the first level bootloader will + * perform: + * + * - Basic chip initialization: XTal or external clock frequency + * detection: + * + * a. Stack Setup for ARM supervisor mode + * b. Main Oscillator Detection: The bootloader attempts to use an + * external crystal. If this is not successful, then the 12 MHz + * Fast RC internal oscillator is used as the main osciallator. + * c. Main Clock Selection: The Master Clock source is switched from + * to the main oscillator without prescaler. PCK and MCK are now + * the Main Clock. + * d. PLLA Initialization: PLLA is configured to get a PCK at 96 MHz + * and an MCK at 48 MHz. If an external clock or crystal frequency + * running at 12 MHz is found, then the PLLA is configured to allow + * USB communication. + * + * - Attempt to retrieve a valid code from external non-volatile + * memories (NVM): SPI0 CS0 Flash Boot, SD Card Boot, NAND Flash Boot, + * SPI0 CS1 Flash Boot, or TWI EEPROM Boot. Different heuristics are + * used with each media type. If a valid image is found, it is copied + * to internal SRAM and started. + * + * - In case no valid application has been found on any NVM, the SAM-BA + * Monitor is started. + * + ****************************************************************************/ + +void __ramfunc__ sam_clockconfig(void) +{ +#ifdef CONFIG_SAMA5_BOOT_CS0FLASH + bool config = false; +#endif + + /* Initialize clocking. + * + * Check first: Are we running in CS0? + */ + +#ifdef CONFIG_SAMA5_BOOT_CS0FLASH + /* Yes... did we get here via the first level bootloader? */ + + if ((getreg32(SAM_SFR_EBICFG) & SFR_EBICFG_BMS) == 0) + { + /* Yes.. Perform the following operations in order to complete the + * clocks and SMC timings configuration to run at a higher clock + * frequency: + * + * - Enable the 32768 Hz oscillator if best accuracy is needed + * - Reprogram the SMC setup, cycle, hold, mode timing registers for EBI + * CS0, to adapt them to the new clock. + * + * Then below: + * + * - Program the PMC (Main Oscillator Enable or Bypass mode) + * - Program and Start the PLL + * - Switch the system clock to the new value + */ + + /* Enable the 32768 Hz oscillator */ + /* REVISIT! */ + + /* Reprogram the SMC setup, cycle, hold, mode timing registers for EBI + * CS0, to adapt them to the new clock. + */ + + board_norflash_config(); + config = true; + } +#endif + + /* If we are running from DDRAM or CS1-3, then we will not modify the + * clock configuration. In these cases, we have to assume that some + * secondary bootloader started us here and that the bootloader has + * configured clocking appropriately. + * + * If we are running in CS0, then we may have been started by either + * the first or second level bootloader. In either case, we need to + * update the PLLA settings in order to get a higher performance + * clock. + */ + +#if defined(NEED_PLLSETUP) +#ifdef CONFIG_SAMA5_BOOT_CS0FLASH + if (config) +#endif /* CONFIG_SAMA5_BOOT_CS0FLASH */ + { + /* Enable main oscillator (if it has not already been selected) */ + + sam_enablemosc(); + + /* Select the main oscillator as the input clock for processor clock + * (PCK) and the main clock (MCK). The PCK and MCK differ only by the + * MDIV divisor that permits the MCK to run at a lower rate. + */ + + sam_selectmosc(); + + /* Setup PLLA */ + + sam_pllasetup(); + + /* Configure the MCK PLLA divider. */ + + sam_plladivider(); + + /* Configure the MCK Prescaler */ + + sam_mckprescaler(); + + /* Configure MCK Divider */ + + sam_mckdivider(); + + /* Configure the H32MX Divider */ + + sam_h32mxdivider(); + + /* Finally, elect the PLLA output as the input clock for PCK and MCK. */ + + sam_selectplla(); + } +#endif /* NEED_PLLSETUP */ + +#ifdef ATSAMA5D2 + /* Enable clocking to the PIO module */ + + sam_pio_enableclk(); +#endif + + /* Setup USB clocking */ + + sam_usbclockconfig(); +} diff --git a/arch/arm/src/sama5/sam_clockconfig.h b/arch/arm/src/sama5/sam_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..6c88fdae182e8328f65e66e6f4e3255f6c7a3e97 --- /dev/null +++ b/arch/arm/src/sama5/sam_clockconfig.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_clockconfig.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void __ramfunc__ sam_clockconfig(void); + +/**************************************************************************** + * Name: board_norflash_config + * + * Description: + * If CONFIG_SAMA5_BOOT_CS0FLASH, then the system is boot directly off + * CS0 NOR FLASH. In this case, we assume that we get here from the + * primary boot loader under these conditions: + * + * "If BMS signal is tied to 0, BMS_BIT is read at 1. The ROM Code + * allows execution of the code contained into the memory connected to + * Chip Select 0 of the External Bus Interface. + * + * "To achieve that, the following sequence is preformed by the ROM + * Code: + * + * - The main clock is the on-chip 12 MHz RC oscillator, + * - The Static Memory Controller is configured with timing allowing + * code execution inCS0 external memory at 12 MHz + * - AXI matrix is configured to remap EBI CS0 address at 0x0 + * - 0x0 is loaded in the Program Counter register + * + * "The user software in the external memory must perform the next + * operation in order to complete the clocks and SMC timings + * configuration to run at a higher clock frequency: + * + * - Enable the 32768 Hz oscillator if best accuracy is needed + * - Reprogram the SMC setup, cycle, hold, mode timing registers + * for EBI CS0, to adapt them to the new clock + * - Program the PMC (Main Oscillator Enable or Bypass mode) + * - Program and Start the PLL + * - Switch the system clock to the new value" + * + * This function provides the board-specific implementation of the logic + * to reprogram the SMC. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_BOOT_CS0FLASH +void board_norflash_config(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H */ diff --git a/arch/arm/src/sama5/sam_config.h b/arch/arm/src/sama5/sam_config.h new file mode 100644 index 0000000000000000000000000000000000000000..650d6c150322c3b1f60c7638c50c4b05ca40433d --- /dev/null +++ b/arch/arm/src/sama5/sam_config.h @@ -0,0 +1,384 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_CONFIG_H +#define __ARCH_ARM_SRC_SAMA5_SAM_CONFIG_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* If the USART is not being used as a UART, then it really isn't enabled + * for our purposes. + */ + +#ifndef CONFIG_USART0_ISUART +# undef CONFIG_SAMA5_USART0 +# undef CONFIG_SAMA5_FLEXCOM0_USART +# undef CONFIG_USART0_SERIAL_CONSOLE +#endif +#ifndef CONFIG_USART1_ISUART +# undef CONFIG_SAMA5_USART1 +# undef CONFIG_SAMA5_FLEXCOM1_USART +# undef CONFIG_USART1_SERIAL_CONSOLE +#endif +#ifndef CONFIG_USART2_ISUART +# undef CONFIG_SAMA5_USART2 +# undef CONFIG_SAMA5_FLEXCOM2_USART +# undef CONFIG_USART2_SERIAL_CONSOLE +#endif +#ifndef CONFIG_USART3_ISUART +# undef CONFIG_SAMA5_USART3 +# undef CONFIG_SAMA5_FLEXCOM3_USART +# undef CONFIG_USART3_SERIAL_CONSOLE +#endif +#ifndef CONFIG_USART4_ISUART +# undef CONFIG_SAMA5_USART4 +# undef CONFIG_SAMA5_FLEXCOM4_USART +# undef CONFIG_USART4_SERIAL_CONSOLE +#endif + +/* Is there a USART/USART enabled? */ + +#if defined(CONFIG_SAMA5_UART0) || defined(CONFIG_SAMA5_UART1) || \ + defined(CONFIG_SAMA5_UART2) || defined(CONFIG_SAMA5_UART3) || \ + defined(CONFIG_SAMA5_UART4) +# define SAMA5_HAVE_UART +#endif + +#if defined(CONFIG_SAMA5_USART0) || defined(CONFIG_SAMA5_USART1) || \ + defined(CONFIG_SAMA5_USART2) || defined(CONFIG_SAMA5_USART3) || \ + defined(CONFIG_SAMA5_USART4) +# define SAMA5_HAVE_USART +#endif + +/* Same is true for Flexcom USARTs */ + +#ifndef CONFIG_SAMA5_FLEXCOM +# undef CONFIG_SAMA5_FLEXCOM_USART +#endif + +#ifndef CONFIG_SAMA5_FLEXCOM_USART +# undef CONFIG_SAMA5_FLEXCOM0_USART +# undef CONFIG_SAMA5_FLEXCOM1_USART +# undef CONFIG_SAMA5_FLEXCOM2_USART +# undef CONFIG_SAMA5_FLEXCOM3_USART +# undef CONFIG_SAMA5_FLEXCOM4_USART +#endif + +#if defined(CONFIG_SAMA5_FLEXCOM0_USART) || defined(CONFIG_SAMA5_FLEXCOM1_USART) || \ + defined(CONFIG_SAMA5_FLEXCOM2_USART) || defined(CONFIG_SAMA5_FLEXCOM3_USART) || \ + defined(CONFIG_SAMA5_FLEXCOM4_USART) +# define SAMA5_HAVE_FLEXCOM_USART +#endif + +#if defined(SAMA5_HAVE_FLEXCOM_USART) && defined(SAMA5_HAVE_USART) +# error "Cannot have both USART and Flexcom USART" +#endif + +#undef SUPPRESS_CONSOLE_CONFIG +#ifdef CONFIG_SUPPRESS_UART_CONFIG +# define SUPPRESS_CONSOLE_CONFIG 1 +#endif + +/* Is there a serial console? It could be on UART0-4 or USART0-3 */ + +#if defined(CONFIG_SAMA5_DBGU_CONSOLE) && defined(CONFIG_SAMA5_DBGU) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# define SAMA5_HAVE_DBGU_CONSOLE 1 +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_UART0) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# define SAMA5_HAVE_UART_CONSOLE 1 +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_UART1) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# define SAMA5_HAVE_UART_CONSOLE 1 +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_UART2) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# define SAMA5_HAVE_UART_CONSOLE 1 +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_UART3) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# define SAMA5_HAVE_UART_CONSOLE 1 +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_UART4) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# define SAMA5_HAVE_UART_CONSOLE 1 +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_USART0_ISUART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# define SAMA5_HAVE_USART_CONSOLE 1 +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_ISUART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# define SAMA5_HAVE_USART_CONSOLE 1 +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_ISUART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# define SAMA5_HAVE_USART_CONSOLE 1 +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_ISUART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# define SAMA5_HAVE_USART_CONSOLE 1 +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) && defined(CONFIG_USART4_ISUART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# define SAMA5_HAVE_USART_CONSOLE 1 +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_FLEXCOM0_USART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# define SAMA5_HAVE_FLEXCOM_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_FLEXCOM1_USART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# define SAMA5_HAVE_FLEXCOM_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_FLEXCOM2_USART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# define SAMA5_HAVE_FLEXCOM_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_FLEXCOM3_USART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# define SAMA5_HAVE_FLEXCOM_CONSOLE 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) && defined(CONFIG_SAMA5_FLEXCOM4_USART) +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# define SAMA5_HAVE_FLEXCOM_CONSOLE 1 +#else +# warning "No valid CONFIG_UARTn/USARTn_SERIAL_CONSOLE Setting" +# undef CONFIG_SAMA5_DBGU_CONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef SAMA5_HAVE_DBGU_CONSOLE +# undef SAMA5_HAVE_UART_CONSOLE +# undef SAMA5_HAVE_USART_CONSOLE +# undef SAMA5_HAVE_FLEXCOM_CONSOLE +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_CONFIG_H */ diff --git a/arch/arm/src/sama5/sam_dbgu.c b/arch/arm/src/sama5/sam_dbgu.c new file mode 100644 index 0000000000000000000000000000000000000000..877e1db82dce5213477c9586ff01442147245b35 --- /dev/null +++ b/arch/arm/src/sama5/sam_dbgu.c @@ -0,0 +1,644 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_dbgu.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/sam_dbgu.h" +#include "chip/sam_pinmap.h" +#include "sam_pio.h" +#include "sam_dbgu.h" + +#ifdef CONFIG_SAMA5_DBGU + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER +struct dbgu_dev_s +{ + uint32_t sr; /* Saved status bits */ +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int dbgu_setup(struct uart_dev_s *dev); + +#ifdef USE_SERIALDRIVER +static void dbgu_shutdown(struct uart_dev_s *dev); +static int dbgu_attach(struct uart_dev_s *dev); +static void dbgu_detach(struct uart_dev_s *dev); +static int dbgu_interrupt(int irq, void *context); +static int dbgu_ioctl(struct file *filep, int cmd, unsigned long arg); +static int dbgu_receive(struct uart_dev_s *dev, uint32_t *status); +static void dbgu_rxint(struct uart_dev_s *dev, bool enable); +static bool dbgu_rxavailable(struct uart_dev_s *dev); +static void dbgu_send(struct uart_dev_s *dev, int ch); +static void dbgu_txint(struct uart_dev_s *dev, bool enable); +static bool dbgu_txready(struct uart_dev_s *dev); +static bool dbgu_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = dbgu_setup, + .shutdown = dbgu_shutdown, + .attach = dbgu_attach, + .detach = dbgu_detach, + .ioctl = dbgu_ioctl, + .receive = dbgu_receive, + .rxint = dbgu_rxint, + .rxavailable = dbgu_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = dbgu_send, + .txint = dbgu_txint, + .txready = dbgu_txready, + .txempty = dbgu_txempty, +}; + +/* DBGU I/O buffers */ + +static char g_dbgu_rxbuffer[CONFIG_SAMA5_DBGU_RXBUFSIZE]; +static char g_dbgu_txbuffer[CONFIG_SAMA5_DBGU_TXBUFSIZE]; + +/* This describes the private state of the DBGU port */ + +static struct dbgu_dev_s g_dbgu_priv; + +/* This describes the state of the DBGU port as is visible from the upper + * half serial driver. + */ + +static uart_dev_t g_dbgu_port = +{ + .recv = + { + .size = CONFIG_SAMA5_DBGU_RXBUFSIZE, + .buffer = g_dbgu_rxbuffer, + }, + .xmit = + { + .size = CONFIG_SAMA5_DBGU_TXBUFSIZE, + .buffer = g_dbgu_txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_dbgu_priv, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dbgu_configure + * + * Description: + * Configure the DBGU baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#if !defined(CONFIG_SUPPRESS_UART_CONFIG) && !defined(CONFIG_SAMA5_DBGU_NOCONFIG) +static void dbgu_configure(void) +{ + uint32_t regval; + + /* Set up the mode register. Start with normal DBGU mode and the MCK + * as the timing source + */ + + regval = DBGU_MR_CHMODE_NORMAL; + + /* OR in settings for the selected parity */ + +#if CONFIG_SAMA5_DBGU_PARITY == 1 + regval |= DBGU_MR_PAR_ODD; +#elif CONFIG_SAMA5_DBGU_PARITY == 2 + regval |= DBGU_MR_PAR_EVEN; +#else + regval |= DBGU_MR_PAR_NONE; +#endif + + /* And save the new mode register value */ + + putreg32(regval, SAM_DBGU_MR); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower DBGU clocks. + */ + + regval = (BOARD_MCK_FREQUENCY + (CONFIG_SAMA5_DBGU_BAUD << 3)) / + (CONFIG_SAMA5_DBGU_BAUD << 4); + putreg32(regval, SAM_DBGU_BRGR); + + /* Enable receiver & transmitter */ + + putreg32((DBGU_CR_RXEN | DBGU_CR_TXEN), SAM_DBGU_CR); +} + +#else +# define dbgu_configure() +#endif /* !CONFIG_SUPPRESS_UART_CONFIG && !CONFIG_SAMA5_DBGU_NOCONFIG */ + +/**************************************************************************** + * Name: dbgu_setup + * + * Description: + * Configure the DBGU baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int dbgu_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + /* The shutdown method will put the DBGU in a known, disabled state */ + + dbgu_shutdown(dev); + + /* Then configure the DBGU */ + + dbgu_configure(); +#endif + return OK; +} + +/**************************************************************************** + * Name: dbgu_shutdown + * + * Description: + * Disable the DBGU. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void dbgu_shutdown(struct uart_dev_s *dev) +{ +#if !defined(CONFIG_SUPPRESS_UART_CONFIG) && !defined(CONFIG_SAMA5_DBGU_NOCONFIG) + /* Disable all interrupts */ + + putreg32(DBGU_INT_ALLINTS, SAM_DBGU_IDR); + +#else + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + + /* Reset and disable receiver and transmitter */ + + putreg32((DBGU_CR_RSTRX | DBGU_CR_RSTTX | DBGU_CR_RXDIS | DBGU_CR_TXDIS), + SAM_DBGU_CR); + + /* Disable all interrupts */ + + putreg32(DBGU_INT_ALLINTS, SAM_DBGU_IDR); + leave_critical_section(flags); +#endif +} + +/**************************************************************************** + * Name: dbgu_attach + * + * Description: + * Configure the DBGU to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int dbgu_attach(struct uart_dev_s *dev) +{ + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(SAM_IRQ_DBGU, dbgu_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the DBGU + */ + + up_enable_irq(SAM_IRQ_DBGU); + } + + return ret; +} + +/**************************************************************************** + * Name: dbgu_detach + * + * Description: + * Detach DBGU interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void dbgu_detach(struct uart_dev_s *dev) +{ + up_disable_irq(SAM_IRQ_DBGU); + irq_detach(SAM_IRQ_DBGU); +} + +/**************************************************************************** + * Name: dbgu_interrupt + * + * Description: + * This is the DBGU interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int dbgu_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = &g_dbgu_port; + struct dbgu_dev_s *priv = (struct dbgu_dev_s *)dev->priv; + uint32_t pending; + uint32_t imr; + int passes; + bool handled; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the DBGU/DBGU status (we are only interested in the unmasked interrupts). */ + + priv->sr = getreg32(SAM_DBGU_SR); /* Save for error reporting */ + imr = getreg32(SAM_DBGU_IMR); /* Interrupt mask */ + pending = priv->sr & imr; /* Mask out disabled interrupt sources */ + + /* Handle an incoming, receive byte. RXRDY: At least one complete character + * has been received and US_RHR has not yet been read. + */ + + if ((pending & DBGU_INT_RXRDY) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes. XRDY: There is no character in the + * US_THR. + */ + + if ((pending & DBGU_INT_TXRDY) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: dbgu_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int dbgu_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct dbgu_dev_s *user = (struct dbgu_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct dbgu_dev_s)); + } + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: dbgu_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the DBGU. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int dbgu_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct dbgu_dev_s *priv = (struct dbgu_dev_s *)dev->priv; + + /* Return the error information in the saved status */ + + *status = priv->sr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return (int)(getreg32(SAM_DBGU_RHR) & 0xff); +} + +/**************************************************************************** + * Name: dbgu_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void dbgu_rxint(struct uart_dev_s *dev, bool enable) +{ + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + putreg32(DBGU_INT_RXRDY, SAM_DBGU_IER); +#endif + } + else + { + putreg32(DBGU_INT_RXRDY, SAM_DBGU_IDR); + } +} + +/**************************************************************************** + * Name: dbgu_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool dbgu_rxavailable(struct uart_dev_s *dev) +{ + return ((getreg32(SAM_DBGU_SR) & DBGU_INT_RXRDY) != 0); +} + +/**************************************************************************** + * Name: dbgu_send + * + * Description: + * This method will send one byte on the DBGU/DBGU + * + ****************************************************************************/ + +static void dbgu_send(struct uart_dev_s *dev, int ch) +{ + putreg32((uint32_t)ch, SAM_DBGU_THR); +} + +/**************************************************************************** + * Name: dbgu_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void dbgu_txint(struct uart_dev_s *dev, bool enable) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + putreg32(DBGU_INT_TXRDY, SAM_DBGU_IER); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + putreg32(DBGU_INT_TXRDY, SAM_DBGU_IDR); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: dbgu_txready + * + * Description: + * Return true if the transmit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool dbgu_txready(struct uart_dev_s *dev) +{ + return ((getreg32(SAM_DBGU_SR) & DBGU_INT_TXRDY) != 0); +} + +/**************************************************************************** + * Name: dbgu_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool dbgu_txempty(struct uart_dev_s *dev) +{ + return ((getreg32(SAM_DBGU_SR) & DBGU_INT_TXEMPTY) != 0); +} + +/**************************************************************************** + * Name: sam_dbgu_devinitialize + * + * Description: + * Performs the low level DBGU initialization early in debug so that the + * DBGU console will be available during bootup. This must be called + * before getreg32it. + * + ****************************************************************************/ + +void sam_dbgu_devinitialize(void) +{ + /* Disable all DBGU interrupts */ + + putreg32(DBGU_INT_ALLINTS, SAM_DBGU_IDR); + +#ifdef CONFIG_SAMA5_DBGU_CONSOLE + /* Configuration the DBGU as the the console */ + + g_dbgu_port.isconsole = true; + dbgu_configure(); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dbgu_register + * + * Description: + * Register DBBU console and serial port. This assumes that + * sam_dbgu_initialize() was called previously. + * + ****************************************************************************/ + +void sam_dbgu_register(void) +{ + /* Register the console */ + +#ifdef CONFIG_SAMA5_DBGU_CONSOLE + (void)uart_register("/dev/console", &g_dbgu_port); +#endif + + /* Register the DBGU serial device */ + + (void)uart_register("/dev/ttyDBGU", &g_dbgu_port); +} + +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: sam_dbgu_initialize + * + * Description: + * Performs the low level DBGU initialization early in debug so that the + * DBGU console will be available during bootup. This must be called + * before getreg32it. + * + ****************************************************************************/ + +void sam_dbgu_initialize(void) +{ + /* Initialize DBGU pins */ + + (void)sam_configpio(PIO_DBGU_DRXD); + (void)sam_configpio(PIO_DBGU_DTXD); + +#if defined(USE_SERIALDRIVER) + /* Initialize the DBGU device driver */ + + sam_dbgu_devinitialize(); +#elif defined(CONFIG_SAMA5_DBGU_CONSOLE) + sam_dbgu_configure(); +#endif +} + +#endif /* CONFIG_SAMA5_DBGU */ diff --git a/arch/arm/src/sama5/sam_dbgu.h b/arch/arm/src/sama5/sam_dbgu.h new file mode 100644 index 0000000000000000000000000000000000000000..f85ecbe55d8de636bc01504039327e5e4b79a1a2 --- /dev/null +++ b/arch/arm/src/sama5/sam_dbgu.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_dbgu.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_DBGU_H +#define __ARCH_ARM_SRC_SAMA5_SAM_DBGU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +#ifdef CONFIG_SAMA5_DBGU + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dbgu_initialize + * + * Description: + * Performs the low level DBGU initialization early in debug so that the + * DBGU console will be available during bootup. + * + ****************************************************************************/ + +void sam_dbgu_initialize(void); + +/**************************************************************************** + * Name: sam_dbgu_register + * + * Description: + * Register DBBU console and serial port. This assumes that + * sam_dbgu_initialize() was called previously. + * + ****************************************************************************/ + +void sam_dbgu_register(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMA5_DBGU */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_DBGU_H */ diff --git a/arch/arm/src/sama5/sam_dmac.c b/arch/arm/src/sama5/sam_dmac.c new file mode 100644 index 0000000000000000000000000000000000000000..990e05df5456bee63e4c2470192036e78e89ede4 --- /dev/null +++ b/arch/arm/src/sama5/sam_dmac.c @@ -0,0 +1,2440 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam3u_dmac.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "cache.h" +#include "up_internal.h" +#include "sched/sched.h" + +#include "chip.h" +#include "sam_dmac.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "chip/sam_pmc.h" +#include "chip/sam_dmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* All of the currently supported SAMA5 chips support two DMA controllers + * of 8 DMA Channels each. + */ + +#if SAM_NDMAC < 1 +# undef CONFIG_SAMA5_DMAC1 +# undef CONFIG_SAMA5_DMAC0 +#elif SAM_NDMAC < 2 +# undef CONFIG_SAMA5_DMAC1 +#endif + +/* Condition out the whole file unless DMA is selected in the configuration */ + +#if defined(CONFIG_SAMA5_DMAC0) || defined(CONFIG_SAMA5_DMAC1) + +/* If SAMA5 DMA support is enabled, then OS DMA support should also be + * enabled + */ + +#ifndef CONFIG_ARCH_DMA +# warning "SAMA5 DMA enabled but CONFIG_ARCH_DMA disabled" +#endif + +/* Check the number of link list descriptors to allocate */ + +#ifndef CONFIG_SAMA5_NLLDESC +# define CONFIG_SAMA5_NLLDESC SAM_NDMACHAN +#endif + +#if CONFIG_SAMA5_NLLDESC < SAM_NDMACHAN +# warning "At least SAM_NDMACHAN descriptors must be allocated" + +# undef CONFIG_SAMA5_NLLDESC +# define CONFIG_SAMA5_NLLDESC SAM_NDMACHAN +#endif + +/* Register values **********************************************************/ + +#define DMAC_CH_CTRLB_BOTHDSCR \ + (DMAC_CH_CTRLB_SRCDSCR | DMAC_CH_CTRLB_DSTDSCR) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure maps a peripheral ID to an DMA channel */ + +struct sam_pidmap_s +{ + uint8_t pid; /* Peripheral identifier */ + uint8_t pchan; /* DMA channel */ +}; + +/* This structure descibes one DMA channel */ + +struct sam_dmach_s +{ +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + uint8_t dmac; /* DMA controller number (0-1) */ +#endif + uint8_t chan; /* DMA channel number (0-6) */ + bool inuse; /* TRUE: The DMA channel is in use */ + bool rx; /* TRUE: Peripheral to memory transfer */ + uint32_t flags; /* DMA channel flags */ + uint32_t base; /* DMA register channel base address */ + uint32_t cfg; /* Pre-calculated CFG register for transfer */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ + uint32_t rxaddr; /* RX memory address */ + size_t rxsize; /* Size of RX memory region */ + struct dma_linklist_s *llhead; /* DMA link list head */ + struct dma_linklist_s *lltail; /* DMA link list head */ +}; + +/* This structure describes the stae of one DMA controller */ + +struct sam_dmac_s +{ + /* These semaphores protect the DMA channel and descriptor tables */ + + sem_t chsem; /* Protects channel table */ + sem_t dsem; /* Protects descriptior table */ + uint32_t base; /* DMA register channel base address */ + + /* This array describes the available link list descriptors */ + + struct dma_linklist_s *desc; + + /* This array describes each DMA channel */ + + struct sam_dmach_s *dmach; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* CTRLA field lookups */ + +static const uint32_t g_srcwidth[4] = +{ + DMAC_CH_CTRLA_SRCWIDTH_BYTE, + DMAC_CH_CTRLA_SRCWIDTH_HWORD, + DMAC_CH_CTRLA_SRCWIDTH_WORD, + DMAC_CH_CTRLA_SRCWIDTH_DWORD +}; + +static const uint32_t g_destwidth[4] = +{ + DMAC_CH_CTRLA_DSTWIDTH_BYTE, + DMAC_CH_CTRLA_DSTWIDTH_HWORD, + DMAC_CH_CTRLA_DSTWIDTH_WORD, + DMAC_CH_CTRLA_DSTWIDTH_DWORD +}; + +static const uint32_t g_fifocfg[3] = +{ + DMAC_CH_CFG_FIFOCFG_ALAP, + DMAC_CH_CFG_FIFOCFG_HALF, + DMAC_CH_CFG_FIFOCFG_ASAP +}; + +/* These tables map peripheral IDs to channels. A lookup is performed + * before each DMA transfer in order to map the peripheral IDs to the + * correct channel. This must be done because the channel can change with + * the direction of the transfer. + */ + +#ifdef CONFIG_SAMA5_DMAC0 +/* DMA controller 0, RX DMA: */ + +static const struct sam_pidmap_s g_dmac0_rxchan[] = +{ + { SAM_PID_HSMCI0, DMAC0_CH_HSMCI0 }, /* HSMCI0 Receive/transmit */ + { SAM_PID_SPI0, DMAC0_CH_SPI0_RX }, /* SPI0 Receive */ + { SAM_PID_USART0, DMAC0_CH_USART0_RX }, /* USART0 Receive */ + { SAM_PID_USART1, DMAC0_CH_USART1_RX }, /* USART1 Receive */ + { SAM_PID_TWI0, DMAC0_CH_TWI0_RX }, /* TWI0 Receive */ + { SAM_PID_TWI1, DMAC0_CH_TWI1_RX }, /* TWI1 Receive */ + { SAM_PID_UART0, DMAC0_CH_UART0_RX }, /* UART0 Receive */ + { SAM_PID_SSC0, DMAC0_CH_SSC0_RX }, /* SSC0 Receive */ + { SAM_PID_SMD, DMAC0_CH_SMD_RX }, /* SMD Receive */ +}; +#define NDMAC0_RXCHANNELS (sizeof(g_dmac0_rxchan) / sizeof(struct sam_pidmap_s)) + +/* DMA controller 0, TX DMA: */ + +static const struct sam_pidmap_s g_dmac0_txchan[] = +{ + { SAM_PID_HSMCI0, DMAC0_CH_HSMCI0 }, /* HSMCI0 Receive/transmit */ + { SAM_PID_SPI0, DMAC0_CH_SPI0_TX }, /* SPI0 Transmit */ + { SAM_PID_USART0, DMAC0_CH_USART0_TX }, /* USART0 Transmit */ + { SAM_PID_USART1, DMAC0_CH_USART1_TX }, /* USART1 Transmit */ + { SAM_PID_TWI0, DMAC0_CH_TWI0_TX }, /* TWI0 Transmit */ + { SAM_PID_TWI1, DMAC0_CH_TWI1_TX }, /* TWI1 Transmit */ + { SAM_PID_UART0, DMAC0_CH_UART0_TX }, /* UART0 Transmit */ + { SAM_PID_SSC0, DMAC0_CH_SSC0_TX }, /* SSC0 Transmit */ + { SAM_PID_SMD, DMAC0_CH_SMD_TX }, /* SMD Transmit */ +}; +#define NDMAC0_TXCHANNELS (sizeof(g_dmac0_txchan) / sizeof(struct sam_pidmap_s)) +#endif + +#ifdef CONFIG_SAMA5_DMAC1 +/* DMA controller 1, RX DMA: */ + +static const struct sam_pidmap_s g_dmac1_rxchan[] = +{ + { SAM_PID_HSMCI1, DMAC1_CH_HSMCI1 }, /* HSMCI1 Receive/transmit */ + { SAM_PID_HSMCI2, DMAC1_CH_HSMCI2 }, /* HSMCI2 Receive/transmit */ + { SAM_PID_ADC, DMAC1_CH_ADC_RX }, /* ADC Receive */ + { SAM_PID_SSC1, DMAC1_CH_SSC1_RX }, /* SSC1 Receive */ + { SAM_PID_UART1, DMAC1_CH_UART1_RX }, /* UART1 Receive */ + { SAM_PID_USART2, DMAC1_CH_USART2_RX }, /* USART2 Receive */ + { SAM_PID_USART3, DMAC1_CH_USART3_RX }, /* USART3 Receive */ + { SAM_PID_TWI2, DMAC1_CH_TWI2_RX }, /* TWI2 Receive */ + { SAM_PID_DBGU, DMAC1_CH_DBGU_RX }, /* DBGU Receive */ + { SAM_PID_SPI1, DMAC1_CH_SPI1_RX }, /* SPI1 Receive */ + { SAM_PID_AES, DMAC1_CH_AES_RX }, /* AES Receive */ + { SAM_PID_TDES, DMAC1_CH_TDES_RX }, /* TDES Receive */ +}; +#define NDMAC1_RXCHANNELS (sizeof(g_dmac1_rxchan) / sizeof(struct sam_pidmap_s)) + +/* DMA controller 1, TX DMA: */ + +static const struct sam_pidmap_s g_dmac1_txchan[] = +{ + { SAM_PID_HSMCI1, DMAC1_CH_HSMCI1 }, /* HSMCI1 Receive/transmit */ + { SAM_PID_HSMCI2, DMAC1_CH_HSMCI2 }, /* HSMCI2 Receive/transmit */ + { SAM_PID_SSC1, DMAC1_CH_SSC1_TX }, /* SSC1 Transmit */ + { SAM_PID_UART1, DMAC1_CH_UART1_TX }, /* UART1 Transmit */ + { SAM_PID_USART2, DMAC1_CH_USART2_TX }, /* USART2 Transmit */ + { SAM_PID_USART3, DMAC1_CH_USART3_TX }, /* USART3 Transmit */ + { SAM_PID_TWI2, DMAC1_CH_TWI2_TX }, /* TWI2 Transmit */ + { SAM_PID_DBGU, DMAC1_CH_DBGU_TX }, /* DBGU Transmit */ + { SAM_PID_SPI1, DMAC1_CH_SPI1_TX }, /* SPI1 Transmit */ + { SAM_PID_SHA, DMAC1_CH_SHA_TX }, /* SHA Transmit */ + { SAM_PID_AES, DMAC1_CH_AES_TX }, /* AES Transmit */ + { SAM_PID_TDES, DMAC1_CH_TDES_TX }, /* TDES Transmit */ +}; +#define NDMAC1_TXCHANNELS (sizeof(g_dmac1_txchan) / sizeof(struct sam_pidmap_s)) +#endif + +#ifdef CONFIG_SAMA5_DMAC0 + +/* This array describes the available link list descriptors */ + +struct dma_linklist_s g_desc0[CONFIG_SAMA5_NLLDESC]; + +/* This array describes the state of each DMAC0 channel 0 */ + +static struct sam_dmach_s g_dmach0[SAM_NDMACHAN] = +{ +#if SAM_NDMACHAN > 0 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 0, + .base = SAM_DMAC0_CH0_BASE, + }, +#endif +#if SAM_NDMACHAN > 1 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 1, + .base = SAM_DMAC0_CH1_BASE, + }, +#endif +#if SAM_NDMACHAN > 2 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 2, + .base = SAM_DMAC0_CH2_BASE, + }, +#endif +#if SAM_NDMACHAN > 3 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 3, + .base = SAM_DMAC0_CH3_BASE, + }, +#endif +#if SAM_NDMACHAN > 4 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 4, + .base = SAM_DMAC0_CH4_BASE, + }, +#endif +#if SAM_NDMACHAN > 5 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 5, + .base = SAM_DMAC0_CH5_BASE, + }, +#endif +#if SAM_NDMACHAN > 6 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 6, + .base = SAM_DMAC0_CH6_BASE, + }, +#endif +#if SAM_NDMACHAN > 7 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 0, +#endif + .chan = 7, + .base = SAM_DMAC0_CH7_BASE, + } +#endif +}; + +/* This describes the overall state of DMA controller 0 */ + +static struct sam_dmac_s g_dmac0 = +{ + /* DMAC 0 base address */ + + .base = SAM_DMAC0_VBASE, + + /* This array describes the available link list descriptors */ + + .desc = g_desc0, + + /* This array describes each DMA channel */ + + .dmach = g_dmach0, +}; + +#endif /* CONFIG_SAMA5_DMAC0 */ + +/* This array describes the state of DMA controller 1 */ + +#ifdef CONFIG_SAMA5_DMAC1 +/* This array describes the available link list descriptors */ + +struct dma_linklist_s g_desc1[CONFIG_SAMA5_NLLDESC]; + +static struct sam_dmach_s g_dmach1[SAM_NDMACHAN] = +{ +#if SAM_NDMACHAN > 0 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 0, + .base = SAM_DMAC1_CH0_BASE, + }, +#endif +#if SAM_NDMACHAN > 1 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 1, + .base = SAM_DMAC1_CH1_BASE, + }, +#endif +#if SAM_NDMACHAN > 2 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 2, + .base = SAM_DMAC1_CH2_BASE, + }, +#endif +#if SAM_NDMACHAN > 3 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 3, + .base = SAM_DMAC1_CH3_BASE, + }, +#endif +#if SAM_NDMACHAN > 4 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 4, + .base = SAM_DMAC1_CH4_BASE, + }, +#endif +#if SAM_NDMACHAN > 5 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 5, + .base = SAM_DMAC1_CH5_BASE, + }, +#endif +#if SAM_NDMACHAN > 6 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 6, + .base = SAM_DMAC1_CH6_BASE, + }, +#endif +#if SAM_NDMACHAN > 7 + { +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + .dmac = 1, +#endif + .chan = 7, + .base = SAM_DMAC1_CH7_BASE, + } +#endif +}; + +/* This describes the overall state of DMA controller 1 */ + +static struct sam_dmac_s g_dmac1 = +{ + /* DMAC 0 base address */ + + .base = SAM_DMAC1_VBASE, + + /* This array describes the available link list descriptors */ + + .desc = g_desc1, + + /* This array describes each DMA channel */ + + .dmach = g_dmach1, +}; + +#endif /* CONFIG_SAMA5_DMAC1 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_takechsem() and sam_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table + * + ****************************************************************************/ + +static void sam_takechsem(struct sam_dmac_s *dmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmac->chsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givechsem(struct sam_dmac_s *dmac) +{ + (void)sem_post(&dmac->chsem); +} + +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +static void sam_takedsem(struct sam_dmac_s *dmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmac->dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(struct sam_dmac_s *dmac) +{ + (void)sem_post(&dmac->dsem); +} + +/**************************************************************************** + * Name: sam_getdmac + * + * Description: + * Read a global DMAC register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmac(struct sam_dmac_s *dmac, + unsigned int offset) +{ + return getreg32(dmac->base + offset); +} + +/**************************************************************************** + * Name: sam_putdmac + * + * Description: + * Write a value to a global DMAC register + * + ****************************************************************************/ + +static inline void sam_putdmac(struct sam_dmac_s *dmac, uint32_t value, + unsigned int offset) +{ + putreg32(value, dmac->base + offset); +} + +/**************************************************************************** + * Name: sam_getdmach + * + * Description: + * Read a DMAC channel register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmach(struct sam_dmach_s *dmach, + unsigned int offset) +{ + return getreg32(dmach->base + offset); +} + +/**************************************************************************** + * Name: sam_putdmach + * + * Description: + * Write a value to a DMAC channel register + * + ****************************************************************************/ + +static inline void sam_putdmach(struct sam_dmach_s *dmach, uint32_t value, + unsigned int offset) +{ + putreg32(value, dmach->base + offset); +} + +/**************************************************************************** + * Name: sam_controller + * + * Description: + * Given a DMA channel instance, return a pointer to the parent DMA + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_dmac_s *sam_controller(struct sam_dmach_s *dmach) +{ +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + return dmach->dmac ? &g_dmac1 : &g_dmac0; +#elif defined(CONFIG_SAMA5_DMAC0) + return &g_dmac0; +#else + return &g_dmac1; +#endif +} + +/**************************************************************************** + * Name: sam_fifocfg + * + * Description: + * Decode the FIFO config from the flags + * + ****************************************************************************/ + +static inline uint32_t sam_fifocfg(struct sam_dmach_s *dmach) +{ + unsigned int ndx; + + ndx = (dmach->flags & DMACH_FLAG_FIFOCFG_MASK) >> DMACH_FLAG_FIFOCFG_SHIFT; + DEBUGASSERT(ndx < 3); + return g_fifocfg[ndx]; +} + + +/**************************************************************************** + * Name: sam_channel, sam_source_channel, and sam_sink_channel + * + * Description: + * Return the RX or TX channel associated with a PID. As a clarification: + * + * The source channel refers to the source of data for the DMA. This is, + * either (1) memory for a TX DMA or (2) a peripheral register for an RX + * DMA. + * + * The sink channel is the recipient of the DMA data. This is either + * (1) memory for an RX DMA, or (2) a peripheral register for a TX DMA. + * + ****************************************************************************/ + +static uint8_t sam_channel(uint8_t pid, const struct sam_pidmap_s *table, + unsigned int nentries) +{ + int i; + + /* Search until either the entry with the matching PID is found or until + * all of the table entries have been examined without finding the PID. + */ + + for (i = 0; i < nentries; i++, table++) + { + if (table->pid == pid) + { + return table->pchan; + } + } + + dmadbg("No channel found for pid %d\n", pid); + DEBUGPANIC(); + return 0x3f; +} + +static uint32_t sam_source_channel(struct sam_dmach_s *dmach, uint8_t pid, + bool isperiph) +{ + const struct sam_pidmap_s *table; + unsigned int nentries; + + if (!isperiph) + { + /* The source is memory, not a peripheral. */ + + return 0x3f; + } + else + +#ifdef CONFIG_SAMA5_DMAC0 +#ifdef CONFIG_SAMA5_DMAC1 + if (dmach->dmac == 0) +#endif + { + /* Use the DMAC0 lookup table */ + + table = g_dmac0_rxchan; + nentries = NDMAC0_RXCHANNELS; + } +#endif + +#ifdef CONFIG_SAMA5_DMAC1 +#ifdef CONFIG_SAMA5_DMAC0 + else +#endif + { + /* Use the DMAC1 lookup table */ + + table = g_dmac1_rxchan; + nentries = NDMAC1_RXCHANNELS; + } +#endif + + return (uint32_t)sam_channel(pid, table, nentries); +} + +static uint32_t sam_sink_channel(struct sam_dmach_s *dmach, uint8_t pid, + bool isperiph) +{ + const struct sam_pidmap_s *table; + unsigned int nentries; + + if (!isperiph) + { + /* The source is memory, not a peripheral. */ + + return 0x3f; + } + else + +#ifdef CONFIG_SAMA5_DMAC0 +#ifdef CONFIG_SAMA5_DMAC1 + if (dmach->dmac == 0) +#endif + { + /* Use the DMAC0 lookup table */ + + table = g_dmac0_txchan; + nentries = NDMAC0_TXCHANNELS; + } +#endif + +#ifdef CONFIG_SAMA5_DMAC1 +#ifdef CONFIG_SAMA5_DMAC0 + else +#endif + { + /* Use the DMAC1 lookup table */ + + table = g_dmac1_txchan; + nentries = NDMAC1_TXCHANNELS; + } +#endif + + return (uint32_t)sam_channel(pid, table, nentries); +} + +/**************************************************************************** + * Name: sam_txcfg + * + * Description: + * Decode the flags to get the correct CFG register bit settings for + * a transmit (memory to peripheral) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_txcfg(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int pid; + unsigned int pchan; + bool isperiph; + + /* Set transfer (memory to peripheral) DMA channel configuration register */ + + regval = DMAC_CH_CFG_SOD; + + pid = (dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT; + isperiph = ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0); + pchan = sam_source_channel(dmach, pid, isperiph); + + regval |= ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT); + regval |= ((pchan & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4)); + regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0; + + pid = (dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT; + isperiph = ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0); + pchan = sam_sink_channel(dmach, pid, isperiph); + + regval |= ((pchan & 0x0f) << DMAC_CH_CFG_DSTPER_SHIFT); + regval |= ((pchan & 0x30) << (DMAC_CH_CFG_DSTPERMSB_SHIFT-4)); + regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0; + + regval |= sam_fifocfg(dmach); + return regval; +} + +/**************************************************************************** + * Name: sam_rxcfg + * + * Description: + * Decode the flags to get the correct CFG register bit settings for + * a receive (peripheral to memory) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_rxcfg(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int pid; + unsigned int pchan; + bool isperiph; + + /* Set received (peripheral to memory) DMA channel config */ + + regval = DMAC_CH_CFG_SOD; + + pid = (dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT; + isperiph = ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0); + pchan = sam_source_channel(dmach, pid, isperiph); + + regval |= ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT); + regval |= ((pchan & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4)); + regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0; + + pid = (dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT; + isperiph = ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0); + pchan = sam_sink_channel(dmach, pid, isperiph); + + regval |= ((pchan & 0x0f) << DMAC_CH_CFG_DSTPER_SHIFT); + regval |= ((pchan & 0x30) << (DMAC_CH_CFG_DSTPERMSB_SHIFT-4)); + regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0; + + regval |= sam_fifocfg(dmach); + return regval; +} + +/**************************************************************************** + * Name: sam_txctrlabits + * + * Description: + * Decode the flags to get the correct CTRLA register bit settings for + * a transmit (memory to peripheral) transfer. These are only the "fixed" + * CTRLA values and need to be updated with the actual transfer size before + * being written to CTRLA sam_txctrla). + * + ****************************************************************************/ + +static inline uint32_t sam_txctrlabits(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int ndx; + unsigned int chunksize; + + DEBUGASSERT(dmach); + + /* Since this is a transmit, the source is described by the memory selections. + * Set the source width (memory width). + */ + + ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT; + DEBUGASSERT(ndx < 4); + regval = g_srcwidth[ndx]; + + /* Set the source chunk size (memory chunk size) */ + + chunksize = (dmach->flags & DMACH_FLAG_MEMCHUNKSIZE_MASK) + >> DMACH_FLAG_MEMCHUNKSIZE_SHIFT; + regval |= chunksize << DMAC_CH_CTRLA_SCSIZE_SHIFT; + + /* Since this is a transmit, the destination is described by the peripheral selections. + * Set the destination width (peripheral width). + */ + + ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + DEBUGASSERT(ndx < 4); + regval |= g_destwidth[ndx]; + + /* Set the destination chunk size (peripheral chunk size) */ + + chunksize = (dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) + >> DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= chunksize << DMAC_CH_CTRLA_DCSIZE_SHIFT; + + return regval; +} + +/**************************************************************************** + * Name: sam_maxtxtransfer + * + * Description: + * Maximum number of bytes that can be sent in on transfer + * + ****************************************************************************/ + +static size_t sam_maxtxtransfer(struct sam_dmach_s *dmach) +{ + unsigned int srcwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes. BTSIZE is "the number of + * transfers to be performed, that is, for writes it refers to the number + * of source width transfers to perform when DMAC is flow controller. For + * Reads, BTSIZE refers to the number of transfers completed on the Source + * Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) + >> DMACH_FLAG_MEMWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 2: /* 32 bits 4 bytes */ + maxtransfer = 4 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 3: /* 64 bits, 8 bytes */ + maxtransfer = 8 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_ntxtransfers + * + * Description: + * Number of TX transfers via DMA + * + ****************************************************************************/ + +static uint32_t sam_ntxtransfers(struct sam_dmach_s *dmach, uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Adjust the source transfer size for the source chunk size (memory + * chunk size). BTSIZE is "the number of transfers to be performed, that + * is, for writes it refers to the number of source width transfers + * to perform when DMAC is flow controller. For Reads, BTSIZE refers to + * the number of transfers completed on the Source Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) + >> DMACH_FLAG_MEMWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + + case 3: /* 64 bits, 8 bytes */ + dmasize = (dmasize + 7) >> 3; + break; + } + + return dmasize; +} + +/**************************************************************************** + * Name: sam_txctrla + * + * Description: + * 'OR' in the variable CTRLA bits + * + ****************************************************************************/ + +static inline uint32_t sam_txctrla(struct sam_dmach_s *dmach, + uint32_t ctrla, uint32_t dmasize) +{ + uint32_t ntransfers; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + ntransfers = sam_ntxtransfers(dmach, dmasize); + + DEBUGASSERT(ntransfers <= DMAC_CH_CTRLA_BTSIZE_MAX); + return (ctrla & ~DMAC_CH_CTRLA_BTSIZE_MASK) | + (ntransfers << DMAC_CH_CTRLA_BTSIZE_SHIFT); +} + +/**************************************************************************** + * Name: sam_rxctrlabits + * + * Description: + * Decode the flags to get the correct CTRLA register bit settings for + * a read (peripheral to memory) transfer. These are only the "fixed" CTRLA + * values and need to be updated with the actual transfer size before being + * written to CTRLA sam_rxctrla). + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrlabits(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int ndx; + unsigned int chunksize; + + DEBUGASSERT(dmach); + + /* Since this is a receive, the source is described by the peripheral + * selections. Set the source width (peripheral width). + */ + + ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) + >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + + DEBUGASSERT(ndx < 4); + regval = g_srcwidth[ndx]; + + /* Set the source chunk size (peripheral chunk size) */ + + chunksize = (dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) + >> DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= chunksize << DMAC_CH_CTRLA_SCSIZE_SHIFT; + + /* Since this is a receive, the destination is described by the memory + * selections. Set the destination width (memory width). + */ + + ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) + >> DMACH_FLAG_MEMWIDTH_SHIFT; + + DEBUGASSERT(ndx < 4); + regval |= g_destwidth[ndx]; + + /* Set the destination chunk size (memory chunk size) */ + + chunksize = (dmach->flags & DMACH_FLAG_MEMCHUNKSIZE_MASK) + >> DMACH_FLAG_MEMCHUNKSIZE_SHIFT; + regval |= chunksize << DMAC_CH_CTRLA_DCSIZE_SHIFT; + + return regval; +} + +/**************************************************************************** + * Name: sam_maxrxtransfer + * + * Description: + * Maximum number of bytes that can be sent in on transfer + * + ****************************************************************************/ + +static size_t sam_maxrxtransfer(struct sam_dmach_s *dmach) +{ + unsigned int srcwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes. BTSIZE is "the number of + * transfers to be performed, that is, for writes it refers to the number + * of source width transfers to perform when DMAC is flow controller. For + * Reads, BTSIZE refers to the number of transfers completed on the Source + * Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) + >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 2: /* 32 bits, 4 bytes */ + maxtransfer = 4 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + + case 3: /* 64 bits, 8 bytes */ + maxtransfer = 8 * DMAC_CH_CTRLA_BTSIZE_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_nrxtransfers + * + * Description: + * Number of RX transfers via DMA + * + ****************************************************************************/ + +static uint32_t sam_nrxtransfers(struct sam_dmach_s *dmach, uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Adjust the source transfer size for the source chunk size (peripheral + * chunk size). BTSIZE is "the number of transfers to be performed, that + * is, for writes it refers to the number of source width transfers + * to perform when DMAC is flow controller. For Reads, BTSIZE refers to + * the number of transfers completed on the Source Interface. ..." + */ + + srcwidth = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) + >> DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + + case 3: /* 64 bits, 8 bytes */ + dmasize = (dmasize + 7) >> 3; + break; + } + + return dmasize; +} + +/**************************************************************************** + * Name: sam_rxctrla + * + * Description: + * 'OR' in the variable CTRLA bits + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrla(struct sam_dmach_s *dmach, + uint32_t ctrla, uint32_t dmasize) +{ + uint32_t ntransfers; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + ntransfers = sam_nrxtransfers(dmach, dmasize); + + DEBUGASSERT(ntransfers <= DMAC_CH_CTRLA_BTSIZE_MAX); + return (ctrla & ~DMAC_CH_CTRLA_BTSIZE_MASK) | + (ntransfers << DMAC_CH_CTRLA_BTSIZE_SHIFT); +} + +/**************************************************************************** + * Name: sam_txctrlb + * + * Description: + * Decode the flags to get the correct CTRLB register bit settings for + * a transmit (memory to peripheral) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_txctrlb(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int ahbif; + + /* Assume that we will not be using the link list and disable the source + * and destination descriptors. The default will be single transfer mode. + */ + + regval = DMAC_CH_CTRLB_BOTHDSCR | DMAC_CH_CTRLB_IEN; + + /* Select flow control (even if the channel doesn't support it). The + * naming convention from TX is memory to peripheral, but that is really + * be determined by bits in the DMA flags. + */ + + /* Is the memory source really a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. is the peripheral destination also a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral-to-peripheral flow control */ + + regval |= DMAC_CH_CTRLB_FC_P2P; + } + else + { + /* No.. Use peripheral-to-memory flow control */ + + regval |= DMAC_CH_CTRLB_FC_P2M; + } + } + else + { + /* No, the source is memory. Is the peripheral destination a + * peripheral + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use memory-to-peripheral flow control */ + + regval |= DMAC_CH_CTRLB_FC_M2P; + } + else + { + /* No.. Use memory-to-memory flow control */ + + regval |= DMAC_CH_CTRLB_FC_M2M; + } + } + + /* Source ABH layer */ + + ahbif = (dmach->flags & DMACH_FLAG_MEMAHB_MASK) >> DMACH_FLAG_MEMAHB_SHIFT; + regval |= (ahbif << DMAC_CH_CTRLB_SIF_SHIFT); + + /* Select source address incrementing */ + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) == 0) + { + regval |= DMAC_CH_CTRLB_SRCINCR_FIXED; + } + + /* Destination ABH layer */ + + ahbif = (dmach->flags & DMACH_FLAG_PERIPHAHB_MASK) >> DMACH_FLAG_PERIPHAHB_SHIFT; + regval |= (ahbif << DMAC_CH_CTRLB_DIF_SHIFT); + + /* Select destination address incrementing */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) == 0) + { + regval |= DMAC_CH_CTRLB_DSTINCR_FIXED; + } + + return regval; +} + +/**************************************************************************** + * Name: sam_rxctrlb + * + * Description: + * Decode the flags to get the correct CTRLB register bit settings for + * a receive (peripheral to memory) transfer. + * + ****************************************************************************/ + +static inline uint32_t sam_rxctrlb(struct sam_dmach_s *dmach) +{ + uint32_t regval; + unsigned int ahbif; + + /* Assume that we will not be using the link list and disable the source + * and destination descriptors. The default will be single transfer mode. + */ + + regval = DMAC_CH_CTRLB_BOTHDSCR | DMAC_CH_CTRLB_IEN; + + /* Select flow control (even if the channel doesn't support it). The + * naming convention from RX is peripheral to memory, but that is really + * be determined by bits in the DMA flags. + */ + + /* Is the peripheral source really a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. is the memory destination also a peripheral? */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. Use peripheral-to-peripheral flow control */ + + regval |= DMAC_CH_CTRLB_FC_P2P; + } + else + { + /* No.. Use peripheral-to-memory flow control */ + + regval |= DMAC_CH_CTRLB_FC_P2M; + } + } + else + { + /* No, the peripheral source is memory. Is the memory destination + * a peripheral + */ + + if ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0) + { + /* Yes.. Use memory-to-peripheral flow control */ + + regval |= DMAC_CH_CTRLB_FC_M2P; + } + else + { + /* No.. Use memory-to-memory flow control */ + + regval |= DMAC_CH_CTRLB_FC_M2M; + } + } + + /* Source ABH layer */ + + ahbif = (dmach->flags & DMACH_FLAG_PERIPHAHB_MASK) >> DMACH_FLAG_PERIPHAHB_SHIFT; + regval |= (ahbif << DMAC_CH_CTRLB_SIF_SHIFT); + + /* Select source address incrementing */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) == 0) + { + regval |= DMAC_CH_CTRLB_SRCINCR_FIXED; + } + + /* Destination ABH layer */ + + ahbif = (dmach->flags & DMACH_FLAG_MEMAHB_MASK) >> DMACH_FLAG_MEMAHB_SHIFT; + regval |= (ahbif << DMAC_CH_CTRLB_DIF_SHIFT); + + /* Select address incrementing */ + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) == 0) + { + regval |= DMAC_CH_CTRLB_DSTINCR_FIXED; + } + + return regval; +} + +/**************************************************************************** + * Name: sam_allocdesc + * + * Description: + * Allocate and add one descriptor to the DMA channel's link list. + * + * NOTE: link list entries are freed by the DMA interrupt handler. + * However, since the setting/clearing of the 'in use' indication is + * atomic, no special actions need be performed. It would be a good thing + * to add logic to handle the case where all of the entries are exhausted + * and we could wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct dma_linklist_s * +sam_allocdesc(struct sam_dmach_s *dmach, struct dma_linklist_s *prev, + uint32_t saddr, uint32_t daddr, uint32_t ctrla, uint32_t ctrlb) +{ + struct sam_dmac_s *dmac = sam_controller(dmach); + struct dma_linklist_s *desc = NULL; + int i; + + /* Sanity check -- saddr == 0 is the indication that the link is unused. + * Obviously setting it to zero would break that usage. + */ + +#ifdef CONFIG_DEBUG + if (saddr != 0) +#endif + { + /* Table a descriptor table semaphore count. When we get one, then there + * is at least one free descriptor in the table and it is ours. + */ + + sam_takedsem(dmac); + + /* Examine each link list entry to find an available one -- i.e., one + * with saddr == 0. That saddr field is set to zero by the DMA transfer + * complete interrupt handler. The following should be safe because + * that is an atomic operation. + */ + + sam_takechsem(dmac); + for (i = 0; i < CONFIG_SAMA5_NLLDESC; i++) + { + if (dmac->desc[i].saddr == 0) + { + /* We have it. Initialize the new link list entry */ + + desc = &dmac->desc[i]; + desc->saddr = saddr; /* Source address */ + desc->daddr = daddr; /* Destination address */ + desc->ctrla = ctrla; /* Control A value */ + desc->ctrlb = ctrlb; /* Control B value */ + desc->dscr = 0; /* Next descriptor address */ + + /* And then hook it at the tail of the link list */ + + if (!prev) + { + /* There is no previous link. This is the new head of + * the list + */ + + DEBUGASSERT(dmach->llhead == NULL && dmach->lltail == NULL); + dmach->llhead = desc; + } + else + { + DEBUGASSERT(dmach->llhead != NULL && dmach->lltail == prev); + + /* When the second link is added to the list, that is the + * cue that we are going to do the link list transfer. + * + * Enable the source and destination descriptor in the link + * list entry just before this one. We assume that both + * source and destination buffers are non-continuous, but + * this should work even if that is not the case. + */ + + prev->ctrlb &= ~DMAC_CH_CTRLB_BOTHDSCR; + + /* Link the previous tail to the new tail. + * REVISIT: This assumes that the next description is fetched + * via AHB IF0. + */ + + prev->dscr = (uint32_t)sam_physramaddr((uintptr_t)desc); + } + + /* In any event, this is the new tail of the list. The source + * and destination descriptors must be disabled for the last entry + * in the link list. */ + + desc->ctrlb |= DMAC_CH_CTRLB_BOTHDSCR; + dmach->lltail = desc; + + /* Assume that we will be doing multple buffer transfers and that + * that hardware will be accessing the descriptor via DMA. + */ + + arch_clean_dcache((uintptr_t)desc, + (uintptr_t)desc + sizeof(struct dma_linklist_s)); + break; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + sam_givechsem(dmac); + DEBUGASSERT(desc != NULL); + } + + return desc; +} + +/**************************************************************************** + * Name: sam_freelinklist + * + * Description: + * Free all descriptors in the DMA channel's link list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_freelinklist(struct sam_dmach_s *dmach) +{ + struct sam_dmac_s *dmac = sam_controller(dmach); + struct dma_linklist_s *desc; + uintptr_t paddr; + + /* Get the head of the link list and detach the link list from the DMA + * channel + */ + + desc = dmach->llhead; + dmach->llhead = NULL; + dmach->lltail = NULL; + + while (desc != NULL) + { + /* Valid, in-use descriptors never have saddr == 0 */ + + DEBUGASSERT(desc->saddr != 0); + + /* Get the physical address of the next descriptor in the list */ + + paddr = desc->dscr; + + /* Free the descriptor by simply nullifying it and bumping up the + * semaphore count. + */ + + memset(desc, 0, sizeof(struct dma_linklist_s)); + sam_givedsem(dmac); + + /* Get the virtual address of the next descriptor in the list */ + + desc = (struct dma_linklist_s *)sam_virtramaddr(paddr); + } +} + +/**************************************************************************** + * Name: sam_txbuffer + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t regval; + uint32_t ctrla; + uint32_t ctrlb; + + /* If we are appending a buffer to a linklist, then re-use the CTRLA/B + * values. Otherwise, create them from the properties of the transfer. + */ + + if (dmach->llhead) + { + regval = dmach->llhead->ctrla; + ctrlb = dmach->llhead->ctrlb; + } + else + { + regval = sam_txctrlabits(dmach); + ctrlb = sam_txctrlb(dmach); + } + + ctrla = sam_txctrla(dmach, regval, nbytes); + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, maddr, paddr, ctrla, ctrlb)) + { + return -ENOMEM; + } + + /* Pre-calculate the transmit CFG register setting (it won't be used until + * the DMA is started). + */ + + dmach->cfg = sam_txcfg(dmach); + return OK; +} + +/**************************************************************************** + * Name: sam_rxbuffer + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t regval; + uint32_t ctrla; + uint32_t ctrlb; + + /* If we are appending a buffer to a linklist, then re-use the CTRLA/B + * values. Otherwise, create them from the properties of the transfer. + */ + + if (dmach->llhead) + { + regval = dmach->llhead->ctrla; + ctrlb = dmach->llhead->ctrlb; + } + else + { + regval = sam_rxctrlabits(dmach); + ctrlb = sam_rxctrlb(dmach); + } + + ctrla = sam_rxctrla(dmach, regval, nbytes); + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, paddr, maddr, ctrla, ctrlb)) + { + return -ENOMEM; + } + + /* Pre-calculate the receive CFG register setting (it won't be used until + * the DMA is started). + */ + + dmach->cfg = sam_rxcfg(dmach); + return OK; +} + +/**************************************************************************** + * Name: sam_single + * + * Description: + * Start a single buffer DMA. + * + ****************************************************************************/ + +static inline int sam_single(struct sam_dmach_s *dmach) +{ + struct sam_dmac_s *dmac = sam_controller(dmach); + struct dma_linklist_s *llhead = dmach->llhead; + + /* Clear any pending interrupts from any previous DMAC transfer by reading + * the interrupt status register. + */ + + (void)sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET); + + /* Write the starting source address in the SADDR register */ + + DEBUGASSERT(llhead != NULL && llhead->saddr != 0); + sam_putdmach(dmach, llhead->saddr, SAM_DMAC_CH_SADDR_OFFSET); + + /* Write the starting destination address in the DADDR register */ + + sam_putdmach(dmach, llhead->daddr, SAM_DMAC_CH_DADDR_OFFSET); + + /* Clear the next descriptor address */ + + sam_putdmach(dmach, 0, SAM_DMAC_CH_DSCR_OFFSET); + + /* Set up the CTRLA register */ + + sam_putdmach(dmach, llhead->ctrla, SAM_DMAC_CH_CTRLA_OFFSET); + + /* Set up the CTRLB register */ + + sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLB_OFFSET); + + /* Both the DST and SRC DSCR bits should be '1' in CTRLB */ + + DEBUGASSERT((llhead->ctrlb & DMAC_CH_CTRLB_BOTHDSCR) == + DMAC_CH_CTRLB_BOTHDSCR); + + /* Set up the CFG register */ + + sam_putdmach(dmach, dmach->cfg, SAM_DMAC_CH_CFG_OFFSET); + + /* Enable the channel by writing a ‘1’ to the CHER enable bit */ + + sam_putdmac(dmac, DMAC_CHER_ENA(dmach->chan), SAM_DMAC_CHER_OFFSET); + + /* The DMA has been started. Once the transfer completes, hardware sets + * the interrupts and disables the channel. We will receive buffer + * complete and transfer complete interrupts. + * + * Enable error, buffer complete and transfer complete interrupts. + * (Since there is only a single buffer, we don't need the buffer + * complete interrupt). + */ + + sam_putdmac(dmac, DMAC_EBC_CBTCINTS(dmach->chan), SAM_DMAC_EBCIER_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_multiple + * + * Description: + * Start a multiple buffer DMA. + * + ****************************************************************************/ + +static inline int sam_multiple(struct sam_dmach_s *dmach) +{ + struct sam_dmac_s *dmac = sam_controller(dmach); + struct dma_linklist_s *llhead = dmach->llhead; + + DEBUGASSERT(llhead != NULL && llhead->saddr != 0); + + /* Check the first and last CTRLB values */ + + DEBUGASSERT((llhead->ctrlb & DMAC_CH_CTRLB_BOTHDSCR) == 0); + DEBUGASSERT((dmach->lltail->ctrlb & DMAC_CH_CTRLB_BOTHDSCR) == + DMAC_CH_CTRLB_BOTHDSCR); + + /* Clear any pending interrupts from any previous DMAC transfer by reading + * the status register + */ + + (void)sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET); + + /* Set up the initial CTRLA register */ + + sam_putdmach(dmach, llhead->ctrla, SAM_DMAC_CH_CTRLA_OFFSET); + + /* Set up the CTRLB register (will enable descriptors) */ + + sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLB_OFFSET); + + /* Write the channel configuration information into the CFG register */ + + sam_putdmach(dmach, dmach->cfg, SAM_DMAC_CH_CFG_OFFSET); + + /* Program the DSCR register with the pointer to the firstlink list entry. */ + + sam_putdmach(dmach, (uint32_t)llhead, SAM_DMAC_CH_DSCR_OFFSET); + + /* Finally, enable the channel by writing a ‘1’ to the CHER enable */ + + sam_putdmac(dmac, DMAC_CHER_ENA(dmach->chan), SAM_DMAC_CHER_OFFSET); + + /* As each buffer of data is transferred, the CTRLA register is written + * back into the link list entry. The CTRLA contains updated BTSIZE and + * DONE bits. Additionally, the CTRLA DONE bit is asserted when the + * buffer transfer has completed. + * + * The DMAC transfer continues until the CTRLB register disables the + * descriptor (DSCR bits) registers at the final buffer transfer. + * + * Enable error, buffer complete and transfer complete interrupts. We + * don't really need the buffer complete interrupts, but we will take them + * just to handle stall conditions. + */ + + sam_putdmac(dmac, DMAC_EBC_CHANINTS(dmach->chan), SAM_DMAC_EBCIER_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void sam_dmaterminate(struct sam_dmach_s *dmach, int result) +{ + struct sam_dmac_s *dmac = sam_controller(dmach); + + /* Disable all channel interrupts */ + + sam_putdmac(dmac, DMAC_EBC_CHANINTS(dmach->chan), SAM_DMAC_EBCIDR_OFFSET); + + /* Disable the channel by writing one to the write-only channel disable + * register. + */ + + sam_putdmac(dmac, DMAC_CHDR_DIS(dmach->chan), SAM_DMAC_CHDR_OFFSET); + + /* Free the linklist */ + + sam_freelinklist(dmach); + + /* If this was an RX DMA (peripheral-to-memory), then invalidate the cache + * to force reloads from memory. + */ + + if (dmach->rx) + { + arch_invalidate_dcache(dmach->rxaddr, dmach->rxaddr + dmach->rxsize); + } + + /* Perform the DMA complete callback */ + + if (dmach->callback) + { + dmach->callback((DMA_HANDLE)dmach, dmach->arg, result); + } + + dmach->callback = NULL; + dmach->arg = NULL; +} + +/**************************************************************************** + * Name: sam_dmac_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int sam_dmac_interrupt(struct sam_dmac_s *dmac) +{ + struct sam_dmach_s *dmach; + unsigned int chndx; + uint32_t regval; + + /* Get the DMAC status register value. Ignore all masked interrupt + * status bits. + */ + + regval = sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET) & + sam_getdmac(dmac, SAM_DMAC_EBCIMR_OFFSET); + + /* Check if the any transfer has completed or any errors have ocurred. */ + + if (regval & DMAC_EBC_ALLCHANINTS) + { + /* Yes.. Check each bit to see which channel has interrupted */ + + for (chndx = 0; chndx < SAM_NDMACHAN; chndx++) + { + /* Are any interrupts pending for this channel? */ + + if ((regval & DMAC_EBC_CHANINTS(chndx)) != 0) + { + dmach = &dmac->dmach[chndx]; + + /* Yes.. Did an error occur? */ + + if ((regval & DMAC_EBC_ERR(chndx)) != 0) + { + /* Yes... Terminate the transfer with an error? */ + + dmalldbg("ERROR: DMA failed: %08x\n", regval); + sam_dmaterminate(dmach, -EIO); + } + + /* Is the transfer complete? */ + + else if ((regval & DMAC_EBC_CBTC(chndx)) != 0) + { + /* Yes.. Terminate the transfer with success */ + + sam_dmaterminate(dmach, OK); + } + + /* Otherwise, this must be a Bufffer Transfer Complete (BTC) + * interrupt as part of a multiple buffer transfer. + */ + + else /* if ((regval & DMAC_EBC_BTC(chndx)) != 0) */ + { + /* Write the KEEPON field to clear the STALL states */ + + sam_putdmac(dmac, DMAC_CHER_KEEP(dmach->chan), + SAM_DMAC_CHER_OFFSET); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_dmac0_interrupt and sam_dmac1_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_DMAC0 +static int sam_dmac0_interrupt(int irq, void *context) +{ + return sam_dmac_interrupt(&g_dmac0); +} +#endif + +#ifdef CONFIG_SAMA5_DMAC1 +static int sam_dmac1_interrupt(int irq, void *context) +{ + return sam_dmac_interrupt(&g_dmac1); +} +#endif + +/**************************************************************************** + * Name: sam_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmainitialize(struct sam_dmac_s *dmac) +{ + /* Disable all DMA interrupts */ + + sam_putdmac(dmac, DMAC_EBC_ALLINTS, SAM_DMAC_EBCIDR_OFFSET); + + /* Disable all DMA channels */ + + sam_putdmac(dmac, DMAC_CHDR_DIS_ALL, SAM_DMAC_CHDR_OFFSET); + + /* Enable the DMA controller */ + + sam_putdmac(dmac, DMAC_EN_ENABLE, SAM_DMAC_EN_OFFSET); + + /* Initialize semaphores */ + + sem_init(&dmac->chsem, 0, 1); + sem_init(&dmac->dsem, 0, SAM_NDMACHAN); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ +#ifdef CONFIG_SAMA5_DMAC0 + dmallvdbg("Initialize DMAC0\n"); + + /* Enable peripheral clock */ + + sam_dmac0_enableclk(); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_DMAC0, sam_dmac0_interrupt); + + /* Initialize the controller */ + + sam_dmainitialize(&g_dmac0); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_DMAC0); +#endif + +#ifdef CONFIG_SAMA5_DMAC1 + dmallvdbg("Initialize DMAC1\n"); + + /* Enable peripheral clock */ + + sam_dmac1_enableclk(); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_DMAC1, sam_dmac1_interrupt); + + /* Initialize the controller */ + + sam_dmainitialize(&g_dmac1); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_DMAC1); +#endif +} + +/**************************************************************************** + * Name: sam_dmachannel + * + * Allocate a DMA channel. This function sets aside a DMA channel then + * gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. Howerver, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* + * DMA channel handle. NULL is returned on any failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags) +{ + struct sam_dmac_s *dmac; + struct sam_dmach_s *dmach; + unsigned int chndx; + + /* Pick the DMA controller */ + +#ifdef CONFIG_SAMA5_DMAC0 + if (dmacno == 0) + { + dmac = &g_dmac0; + } + else +#endif + +#ifdef CONFIG_SAMA5_DMAC1 + if (dmacno == 1) + { + dmac = &g_dmac1; + } + else +#endif + + { + dmadbg("ERROR: Bad DMAC number: %d\n", dmacno); + DEBUGPANIC(); + return (DMA_HANDLE)NULL; + } + + /* Search for an available DMA channel with at least the requested FIFO + * size. + */ + + dmach = NULL; + sam_takechsem(dmac); + for (chndx = 0; chndx < SAM_NDMACHAN; chndx++) + { + struct sam_dmach_s *candidate = &dmac->dmach[chndx]; + if (!candidate->inuse) + { + dmach = candidate; + dmach->inuse = true; + + /* Read the status register to clear any pending interrupts on the + * channel + */ + + (void)sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET); + + /* Disable the channel by writing one to the write-only channel + * disable register + */ + + sam_putdmac(dmac, DMAC_CHDR_DIS(chndx), SAM_DMAC_CHDR_OFFSET); + + /* Set the DMA channel flags. */ + + dmach->flags = chflags; + break; + } + } + + sam_givechsem(dmac); + + /* Show the result of the allocation */ + + if (dmach) + { + dmavdbg("DMAC%d CH%d: chflags: %08x returning dmach: %p\n", + (int)dmacno, dmach->chan, (int)chflags, dmach); + } + else + { + dmadbg("ERROR: Failed allocate DMAC%d channel\n", (int)dmacno); + } + + return (DMA_HANDLE)dmach; +} + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + + /* Set the new DMA channel flags. */ + + dmach->flags = chflags; + +#if defined(CONFIG_SAMA5_DMAC0) && defined(CONFIG_SAMA5_DMAC1) + dmavdbg("DMAC%d CH%d: chflags: %08x\n", + dmach->dmac, dmach->chan, (int)chflags); +#elif defined(CONFIG_SAMA5_DMAC0) + dmavdbg("DMAC0 CH%d: chflags: %08x\n", + dmach->chan, (int)chflags); +#else + dmavdbg("DMAC1 CH%d: chflags: %08x\n", + dmach->chan, (int)chflags); +#endif +} + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT((dmach != NULL) && (dmach->inuse)); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + dmach->flags = 0; + dmach->inuse = false; /* No longer in use */ +} + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtxtransfer(dmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_txbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_txbuffer(dmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was not an RX transfer. + */ + + dmach->rx = false; + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + dmavdbg("llhead: %p lltail: %p\n", dmach->llhead, dmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxrxtransfer(dmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_rxbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((dmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_rxbuffer(dmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was an RX transfer and will invalidate the cache. + */ + + dmach->rx = true; + dmach->rxaddr = maddr; + dmach->rxsize = (dmach->flags & DMACH_FLAG_MEMINCREMENT) != 0 ? nbytes : sizeof(uint32_t); + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + int ret = -EINVAL; + + dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg); + DEBUGASSERT(dmach != NULL); + + /* Verify that the DMA has been setup (i.e., at least one entry in the + * link list). + */ + + if (dmach->llhead) + { + /* Save the callback info. This will be invoked whent the DMA commpletes */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Is this a single block transfer? Or a multiple block transfer? */ + + if (dmach->llhead == dmach->lltail) + { + ret = sam_single(dmach); + } + else + { + ret = sam_multiple(dmach); + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + irqstate_t flags; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT(dmach != NULL); + + flags = enter_critical_section(); + sam_dmaterminate(dmach, -EINTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + struct sam_dmac_s *dmac = sam_controller(dmach); + irqstate_t flags; + + /* Sample global registers. NOTE: reading EBCISR clears interrupts, but + * that should be okay IF interrupts are enabled when this function is + * called. But there is a race condition where this instrumentation could + * cause lost interrupts. + */ + + flags = enter_critical_section(); + regs->gcfg = sam_getdmac(dmac, SAM_DMAC_GCFG_OFFSET); + regs->en = sam_getdmac(dmac, SAM_DMAC_EN_OFFSET); + regs->sreq = sam_getdmac(dmac, SAM_DMAC_SREQ_OFFSET); + regs->creq = sam_getdmac(dmac, SAM_DMAC_CREQ_OFFSET); + regs->last = sam_getdmac(dmac, SAM_DMAC_LAST_OFFSET); + regs->ebcimr = sam_getdmac(dmac, SAM_DMAC_EBCIMR_OFFSET); + regs->ebcisr = sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET); + regs->chsr = sam_getdmac(dmac, SAM_DMAC_CHSR_OFFSET); + regs->wpmr = sam_getdmac(dmac, SAM_DMAC_WPMR_OFFSET); + regs->wpsr = sam_getdmac(dmac, SAM_DMAC_WPSR_OFFSET); + + /* Sample channel registers */ + + regs->saddr = sam_getdmach(dmach, SAM_DMAC_CH_SADDR_OFFSET); + regs->daddr = sam_getdmach(dmach, SAM_DMAC_CH_DADDR_OFFSET); + regs->dscr = sam_getdmach(dmach, SAM_DMAC_CH_DSCR_OFFSET); + regs->ctrla = sam_getdmach(dmach, SAM_DMAC_CH_CTRLA_OFFSET); + regs->ctrlb = sam_getdmach(dmach, SAM_DMAC_CH_CTRLB_OFFSET); + regs->cfg = sam_getdmach(dmach, SAM_DMAC_CH_CFG_OFFSET); + regs->spip = sam_getdmach(dmach, SAM_DMAC_CH_SPIP_OFFSET); + regs->dpip = sam_getdmach(dmach, SAM_DMAC_CH_DPIP_OFFSET); + leave_critical_section(flags); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + struct sam_dmac_s *dmac = sam_controller(dmach); + + dmadbg("%s\n", msg); + dmadbg(" DMA Global Registers:\n"); + dmadbg(" GCFG[%08x]: %08x\n", dmac->base + SAM_DMAC_GCFG_OFFSET, regs->gcfg); + dmadbg(" EN[%08x]: %08x\n", dmac->base + SAM_DMAC_EN_OFFSET, regs->en); + dmadbg(" SREQ[%08x]: %08x\n", dmac->base + SAM_DMAC_SREQ_OFFSET, regs->sreq); + dmadbg(" CREQ[%08x]: %08x\n", dmac->base + SAM_DMAC_CREQ_OFFSET, regs->creq); + dmadbg(" LAST[%08x]: %08x\n", dmac->base + SAM_DMAC_LAST_OFFSET, regs->last); + dmadbg(" EBCIMR[%08x]: %08x\n", dmac->base + SAM_DMAC_EBCIMR_OFFSET, regs->ebcimr); + dmadbg(" EBCISR[%08x]: %08x\n", dmac->base + SAM_DMAC_EBCISR_OFFSET, regs->ebcisr); + dmadbg(" CHSR[%08x]: %08x\n", dmac->base + SAM_DMAC_CHSR_OFFSET, regs->chsr); + dmadbg(" WPMR[%08x]: %08x\n", dmac->base + SAM_DMAC_WPMR_OFFSET, regs->wpmr); + dmadbg(" WPSR[%08x]: %08x\n", dmac->base + SAM_DMAC_WPSR_OFFSET, regs->wpsr); + dmadbg(" DMA Channel Registers:\n"); + dmadbg(" SADDR[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_SADDR_OFFSET, regs->saddr); + dmadbg(" DADDR[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_DADDR_OFFSET, regs->daddr); + dmadbg(" DSCR[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_DSCR_OFFSET, regs->dscr); + dmadbg(" CTRLA[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_CTRLA_OFFSET, regs->ctrla); + dmadbg(" CTRLB[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_CTRLB_OFFSET, regs->ctrlb); + dmadbg(" CFG[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_CFG_OFFSET, regs->cfg); + dmadbg(" SPIP[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_SPIP_OFFSET, regs->spip); + dmadbg(" DPIP[%08x]: %08x\n", dmach->base + SAM_DMAC_CH_DPIP_OFFSET, regs->dpip); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_SAMA5_DMAC0 || CONFIG_SAMA5_DMAC1 */ diff --git a/arch/arm/src/sama5/sam_dmac.h b/arch/arm/src/sama5/sam_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..c9fc885369db4f1e689ebc442b2b638cf47c2a0c --- /dev/null +++ b/arch/arm/src/sama5/sam_dmac.h @@ -0,0 +1,499 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_dmac.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_DMAC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_DMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +#endif + +/* DMA ******************************************************************************/ + +/* Flags used to characterize the DMA channel. The naming convention is that one + * side is the peripheral and the other is memory (however, the interface could still + * be used if, for example, both sides were memory although the naming would be + * awkward) + */ + +#if defined(ATSAMA5D3) +/* MMMM MMMM MMMM MMMP PPPP PPPP PPPP PPFF + * .... .... .... .... .... .... .... ..FF Configurable properties of the channel + * .... .... .... ...P PPPP PPPP PPPP PP.. Peripheral endpoint characteristics + * MMMM MMMM MMMM MMM. .... .... .... .... Memory endpoint characteristics + */ + +/* Bits 0-1: Configurable properties of the channel + * + * .... .... .... .... .... .... .... ..FF Configurable properties of the channel + */ + +# define DMACH_FLAG_BURST_LARGEST 0 /* Largest length AHB burst */ +# define DMACH_FLAG_BURST_HALF 1 /* Half FIFO size */ +# define DMACH_FLAG_BURST_SINGLE 2 /* Single AHB access */ + +# define DMACH_FLAG_FIFOCFG_SHIFT (0) /* Bits 0-1: FIFO configuration */ +# define DMACH_FLAG_FIFOCFG_MASK (3 << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_LARGEST (DMACH_FLAG_BURST_LARGEST << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_HALF (DMACH_FLAG_BURST_HALF << DMACH_FLAG_FIFOCFG_SHIFT) +# define DMACH_FLAG_FIFOCFG_SINGLE (DMACH_FLAG_BURST_SINGLE << DMACH_FLAG_FIFOCFG_SHIFT) + +/* Bits 2-16: Peripheral endpoint characteristics + * + * .... .... .... ...P PPPP PPPP PPPP PP.. Peripheral endpoint characteristics + * .... .... .... .... .... .... IIII II.. Peripheral ID, range 0-49 + * .... .... .... .... .... ...H .... .... HW Handshaking + * .... .... .... .... .... ..P. .... .... 0=memory; 1=peripheral + * .... .... .... .... .... NN.. .... .... Peripheral ABH layer number + * .... .... .... .... ..WW .... .... .... Peripheral width + * .... .... .... .... .A.. .... .... .... Auto-increment peripheral address + * .... .... .... ...S S... .... .... .... Peripheral chunk size + */ + +# define DMACH_FLAG_PERIPHPID_SHIFT (2) /* Bits 1-7: Peripheral PID */ +# define DMACH_FLAG_PERIPHPID_MASK (0x3f << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID(n) ((uint32_t)(n) << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID_MAX DMACH_FLAG_PERIPHPID_MASK +# define DMACH_FLAG_PERIPHH2SEL (1 << 8) /* Bits 8: HW handshaking */ +# define DMACH_FLAG_PERIPHISPERIPH (1 << 9) /* Bits 9: 0=memory; 1=peripheral */ +# define DMACH_FLAG_PERIPHAHB_SHIFT (10) /* Bits 10-11: Peripheral ABH layer number */ +# define DMACH_FLAG_PERIPHAHB_MASK (3 << DMACH_FLAG_PERIPHAHB_SHIFT) +# define DMACH_FLAG_PERIPHAHB_AHB_IF0 (0 << DMACH_FLAG_PERIPHAHB_SHIFT) /* AHB-Lite Interface 0 */ +# define DMACH_FLAG_PERIPHAHB_AHB_IF1 (1 << DMACH_FLAG_PERIPHAHB_SHIFT) /* AHB-Lite Interface 1 */ +# define DMACH_FLAG_PERIPHAHB_AHB_IF2 (2 << DMACH_FLAG_PERIPHAHB_SHIFT) /* AHB-Lite Interface 2 */ +# define DMACH_FLAG_PERIPHWIDTH_SHIFT (12) /* Bits 12-13: Peripheral width */ +# define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) +# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */ +# define DMACH_FLAG_PERIPHWIDTH_64BITS (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 64 bits */ +# define DMACH_FLAG_PERIPHINCREMENT (1 << 14) /* Bit 14: Auto-increment peripheral address */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT (15) /* Bits 15-16: Peripheral chunk size */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_MASK (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) +# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 1 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_2 (0 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* No chunksize = 2 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_4 (1 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 4 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_8 (2 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 8 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_16 (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 16 */ + +/* Bits 17-31: Memory endpoint characteristics + * + * MMMM MMMM MMMM MMM. .... .... .... .... Memory endpoint characteristics + * .... .... .III III. .... .... .... .... Memory/peripheral ID, range 0-49 + * .... .... H... .... .... .... .... .... HW Handshaking + * .... ...P .... .... .... .... .... .... 0=memory; 1=peripheral + * .... .NN. .... .... .... .... .... .... Peripheral ABH layer number + * ...W W... .... .... .... .... .... .... Peripheral width + * ..A. .... .... .... .... .... .... .... Auto-increment peripheral address + * SS.. .... .... .... .... .... .... .... Peripheral chunk size + */ + +# define DMACH_FLAG_MEMPID_SHIFT (17) /* Bits 17-22: Memory PID */ +# define DMACH_FLAG_MEMPID_MASK (0x3f << DMACH_FLAG_MEMPID_SHIFT) +# define DMACH_FLAG_MEMPID(n) ((uint32_t)(n) << DMACH_FLAG_MEMPID_SHIFT) +# define DMACH_FLAG_MEMPID_MAX DMACH_FLAG_MEMPID_MASK +# define DMACH_FLAG_MEMH2SEL (1 << 23) /* Bits 23: HW handshaking */ +# define DMACH_FLAG_MEMISPERIPH (1 << 24) /* Bits 24: 0=memory; 1=peripheral */ +# define DMACH_FLAG_MEMAHB_SHIFT (25) /* Bits 25-26: Peripheral ABH layer number */ +# define DMACH_FLAG_MEMAHB_MASK (3 << DMACH_FLAG_MEMAHB_SHIFT) +# define DMACH_FLAG_MEMAHB_AHB_IF0 (0 << DMACH_FLAG_MEMAHB_SHIFT) /* AHB-Lite Interface 0 */ +# define DMACH_FLAG_MEMAHB_AHB_IF1 (1 << DMACH_FLAG_MEMAHB_SHIFT) /* AHB-Lite Interface 1 */ +# define DMACH_FLAG_MEMAHB_AHB_IF2 (2 << DMACH_FLAG_MEMAHB_SHIFT) /* AHB-Lite Interface 2 */ +# define DMACH_FLAG_MEMWIDTH_SHIFT (27) /* Bits 27-28: Memory width */ +# define DMACH_FLAG_MEMWIDTH_MASK (3 << DMACH_FLAG_MEMWIDTH_SHIFT) +# define DMACH_FLAG_MEMWIDTH_8BITS (0 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */ +# define DMACH_FLAG_MEMWIDTH_64BITS (3 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 64 bits */ +# define DMACH_FLAG_MEMINCREMENT (1 << 29) /* Bit 29: Auto-increment memory address */ +# define DMACH_FLAG_MEMCHUNKSIZE_SHIFT (30) /* Bit 30-31: Memory chunk size */ +# define DMACH_FLAG_MEMCHUNKSIZE_MASK (3 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) +# define DMACH_FLAG_MEMCHUNKSIZE_1 (0 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 1 */ +# define DMACH_FLAG_MEMCHUNKSIZE_2 (0 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* No chunksize = 2 */ +# define DMACH_FLAG_MEMCHUNKSIZE_4 (1 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 4 */ +# define DMACH_FLAG_MEMCHUNKSIZE_8 (2 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 8 */ +# define DMACH_FLAG_MEMCHUNKSIZE_16 (3 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 16 */ + +# define DMACH_FLAG_MEMBURST_1 (0) /* No memory burst size */ +# define DMACH_FLAG_MEMBURST_4 (0) +# define DMACH_FLAG_MEMBURST_8 (0) +# define DMACH_FLAG_MEMBURST_16 (0) + +#elif defined(ATSAMA5D4) +/* .... .... .... MMMM .PPP PPPP PPPP PPPP + * .... .... .... .... .... .... .... .... Configurable properties of the channel + * .... .... .... .... .PPP PPPP PPPP PPPP Peripheral endpoint characteristics + * .... .... .... MMMM .... .... .... .... Memory endpoint characteristics + */ + +/* Bits 0-1: Configurable properties of the channel + * + * .... .... .... .... .... .... .... .... Configurable properties of the channel + * + * NOTE: Many "peripheral" attributes are really "channel" attributes for + * the SAMA5D4's XDMAC since it does not support peripheral-to-peripheral + * DMA. + */ + +# define DMACH_FLAG_FIFOCFG_LARGEST (0) /* No FIFO controls */ +# define DMACH_FLAG_FIFOCFG_HALF (0) +# define DMACH_FLAG_FIFOCFG_SINGLE (0) + +/* Bits 0-15: Peripheral endpoint characteristics + * + * .... .... .... .... .PPP PPPP PPPP PPPP Peripheral endpoint characteristics + * .... .... .... .... .... .... .III IIII Peripheral ID, range 0-67 + * .... .... .... .... .... .... .... .... No HW Handshaking + * .... .... .... .... .... .... P... .... 0=memory; 1=peripheral + * .... .... .... .... .... ...N .... .... Peripheral ABH layer number + * .... .... .... .... .... .WW. .... .... Peripheral width + * .... .... .... .... .... A... .... .... Auto-increment peripheral address + * .... .... .... .... .SSS .... .... .... Peripheral chunk size + */ + +# define DMACH_FLAG_PERIPHPID_SHIFT (0) /* Bits 0-7: Peripheral PID */ +# define DMACH_FLAG_PERIPHPID_MASK (0x7f << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID(n) ((uint32_t)(n) << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID_MAX DMACH_FLAG_PERIPHPID_MASK +# define DMACH_FLAG_PERIPHH2SEL (0) /* No HW handshaking */ +# define DMACH_FLAG_PERIPHISPERIPH (1 << 7) /* Bit 7: 0=memory; 1=peripheral */ +# define DMACH_FLAG_PERIPHAHB_MASK (1 << 8) /* Bit 8: Peripheral ABH layer 1 */ +# define DMACH_FLAG_PERIPHAHB_AHB_IF0 (0) +# define DMACH_FLAG_PERIPHAHB_AHB_IF1 DMACH_FLAG_PERIPHAHB_MASK +# define DMACH_FLAG_PERIPHWIDTH_SHIFT (9) /* Bits 9-10: Peripheral width */ +# define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) +# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */ +# define DMACH_FLAG_PERIPHWIDTH_64BITS (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 64 bits */ +# define DMACH_FLAG_PERIPHINCREMENT (1 << 11) /* Bit 11: Auto-increment peripheral address */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT (12) /* Bits 12-14: Peripheral chunk size */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_MASK (7 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) +# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=1 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_2 (1 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* No chunksize=2 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_4 (2 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=4 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_8 (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=8 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_16 (4 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=16 */ + +/* Bits 16-19: Memory endpoint characteristics + * + * .... .... .... MMMM .... .... .... .... Memory endpoint characteristics + * .... .... .... .... .... .... .... .... No memory peripheral ID, range 0-49 + * .... .... .... .... .... .... .... .... No HW Handshaking + * .... .... .... .... .... .... .... .... No peripheral-to-peripheral + * .... .... .... ...N .... .... .... .... Memory ABH layer number + * .... .... .... .... .... .... .... .... No memory width + * .... .... .... ..A. .... .... .... .... Auto-increment memory address + * .... .... .... .... .... .... .... .... No memory chunk size + * .... .... .... BB.. .... .... .... .... Memory burst size + */ + +# define DMACH_FLAG_MEMPID(n) (0) /* No memory peripheral identifier */ +# define DMACH_FLAG_MEMPID_MAX (0) +# define DMACH_FLAG_MEMH2SEL (0) /* No HW handshaking */ +# define DMACH_FLAG_MEMISPERIPH (0) /* No peripheral-to-peripheral */ +# define DMACH_FLAG_MEMAHB_MASK (1 << 16) /* Bit 16: Memory ABH layer 1 */ +# define DMACH_FLAG_MEMAHB_AHB_IF0 (0) +# define DMACH_FLAG_MEMAHB_AHB_IF1 DMACH_FLAG_MEMAHB_MASK + +# define DMACH_FLAG_MEMWIDTH_8BITS (0) /* Only peripheral data width */ +# define DMACH_FLAG_MEMWIDTH_16BITS (0) +# define DMACH_FLAG_MEMWIDTH_32BITS (0) +# define DMACH_FLAG_MEMWIDTH_64BITS (0) + +# define DMACH_FLAG_MEMINCREMENT (1 << 17) /* Bit 17: Auto-increment memory address */ + +# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Only peripheral chunk size */ +# define DMACH_FLAG_MEMCHUNKSIZE_2 (0) +# define DMACH_FLAG_MEMCHUNKSIZE_4 (0) +# define DMACH_FLAG_MEMCHUNKSIZE_8 (0) +# define DMACH_FLAG_MEMCHUNKSIZE_16 (0) + +# define DMACH_FLAG_MEMBURST_SHIFT (18) /* Bits 18-19: Memory burst size */ +# define DMACH_FLAG_MEMBURST_MASK (3 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_1 (0 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_4 (1 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_8 (2 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_16 (3 << DMACH_FLAG_MEMBURST_SHIFT) + +#endif /* ATSAMA5D4 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +#if defined(CONFIG_SAMA5_DMAC0) || defined(CONFIG_SAMA5_DMAC1) + +struct sam_dmaregs_s +{ + /* Global Registers */ + + uint32_t gcfg; /* DMAC Global Configuration Register */ + uint32_t en; /* DMAC Enable Register */ + uint32_t sreq; /* DMAC Software Single Request Register */ + uint32_t creq; /* DMAC Software Chunk Transfer Request Register */ + uint32_t last; /* DMAC Software Last Transfer Flag Register */ + uint32_t ebcimr; /* DMAC Error Mask */ + uint32_t ebcisr; /* DMAC Error Status */ + uint32_t chsr; /* DMAC Channel Handler Status Register */ + uint32_t wpmr; /* DMAC Write Protect Mode Register */ + uint32_t wpsr; /* DMAC Write Protect Status Register */ + + /* Channel Registers */ + + uint32_t saddr; /* DMAC Channel Source Address Register */ + uint32_t daddr; /* DMAC Channel Destination Address Register */ + uint32_t dscr; /* DMAC Channel Descriptor Address Register */ + uint32_t ctrla; /* DMAC Channel Control A Register */ + uint32_t ctrlb; /* DMAC Channel Control B Register */ + uint32_t cfg; /* DMAC Channel Configuration Register */ + uint32_t spip; /* DMAC Channel Source PinP Configuration Register */ + uint32_t dpip; /* DMAC Channel Destination PinP Configuration Register */ +}; + +#elif defined(CONFIG_SAMA5_XDMAC0) || defined(CONFIG_SAMA5_XDMAC1) + +struct sam_dmaregs_s +{ + /* Global Registers */ + + uint32_t gtype; /* Global Type Register */ + uint32_t gcfg; /* Global Configuration Register */ + uint32_t gwac; /* Global Weighted Arbiter Configuration Register */ + uint32_t gim; /* Global Interrupt Mask Register */ + uint32_t gis; /* Global Interrupt Status Register */ + uint32_t gs; /* Global Channel Status Register */ + uint32_t grs; /* Global Channel Read Suspend Register */ + uint32_t gws; /* Global Channel Write Suspend Register */ + uint32_t gsws; /* Global Channel Software Request Status Register */ + + /* Channel Registers */ + + uint32_t cim; /* Channel Interrupt Mask Register */ + uint32_t cis; /* Channel Interrupt Status Register */ + uint32_t csa; /* Channel Source Address Register */ + uint32_t cda; /* Channel Destination Address Register */ + uint32_t cnda; /* Channel Next Descriptor Address Register */ + uint32_t cndc; /* Channel Next Descriptor Control Register */ + uint32_t cubc; /* Channel Microblock Control Register */ + uint32_t cbc; /* Channel Block Control Register */ + uint32_t cc; /* Channel Configuration Register */ + uint32_t cdsmsp; /* Channel Data Stride Memory Set Pattern */ + uint32_t csus; /* Channel Source Microblock Stride */ + uint32_t cdus; /* Channel Destination Microblock Stride */ +}; + +#endif /* CONFIG_SAMA5_XDMAC0 || CONFIG_SAMA5_XDMAC1 */ +#endif /* CONFIG_DEBUG_DMA */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel then gives the + * caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is the + * 'peripheral' and the other is 'memory'. Howerver, the interface could still + * be used if, for example, both sides were memory although the naming would be + * awkward. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* DMA + * channel handle. NULL is returned on any failure. + * + ************************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be + * used again until sam_dmachannel() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This function + * may be called multiple times to handle large and/or discontinuous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes); + +/************************************************************************************ + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This function + * may be called multiple times to handle large and/or discontinuous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes); + +/************************************************************************************ + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ************************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/************************************************************************************ + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is reset and + * sam_dmarx/txsetup() must be called before sam_dmastart() can be called again + * + ************************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs); +#else +# define sam_dmasample(handle,regs) +#endif + +/************************************************************************************ + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, const char *msg); +#else +# define sam_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_DMAC_H */ diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c new file mode 100644 index 0000000000000000000000000000000000000000..a6cb3d0d7aacbf46ccdd5113dbde8a7e349a461c --- /dev/null +++ b/arch/arm/src/sama5/sam_ehci.c @@ -0,0 +1,5150 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_ehci.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_usbhost.h" +#include "chip/sam_sfr.h" +#include "chip/sam_ehci.h" + +#ifdef CONFIG_SAMA5_EHCI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* Pre-requisites */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#elif !defined(CONFIG_SCHED_HPWORK) +# error Hi-priority work queue support is required (CONFIG_SCHED_HPWORK) +#endif + +/* Configurable number of Queue Head (QH) structures. The default is one per + * Root hub port plus one for EP0. + */ + +#ifndef CONFIG_SAMA5_EHCI_NQHS +# define CONFIG_SAMA5_EHCI_NQHS (SAM_EHCI_NRHPORT + 1) +#endif + +/* Configurable number of Queue Element Transfer Descriptor (qTDs). The default + * is one per root hub plus three from EP0. + */ + +#ifndef CONFIG_SAMA5_EHCI_NQTDS +# define CONFIG_SAMA5_EHCI_NQTDS (SAM_EHCI_NRHPORT + 3) +#endif + +/* Buffers must be aligned to the cache line size */ + +#define DCACHE_LINEMASK (ARMV7A_DCACHE_LINESIZE -1) + +/* Configurable size of a request/descriptor buffers */ + +#ifndef CONFIG_SAMA5_EHCI_BUFSIZE +# define CONFIG_SAMA5_EHCI_BUFSIZE 128 +#endif + +#define SAMA5_EHCI_BUFSIZE \ + ((CONFIG_SAMA5_EHCI_BUFSIZE + DCACHE_LINEMASK) & ~DCACHE_LINEMASK) + +/* Debug options */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_EHCI_REGDEBUG +#endif + +/* Isochronous transfers are not currently supported */ + +#undef CONFIG_USBHOST_ISOC_DISABLE +#define CONFIG_USBHOST_ISOC_DISABLE 1 + +/* If UDPHS is enabled, then don't use port A */ + +#ifdef CONFIG_SAMA5_UDPHS +# undef CONFIG_SAMA5_UHPHS_RHPORT1 +#endif + +/* Simplify DEBUG checks */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_USB +#endif + +/* For now, suppress use of PORTA in any event. I use that for SAM-BA and + * would prefer that the board not try to drive VBUS on that port! + */ + +#undef CONFIG_SAMA5_UHPHS_RHPORT1 + +/* Driver-private Definitions **************************************************/ + +/* This is the set of interrupts handled by this driver */ + +#define EHCI_HANDLED_INTS (EHCI_INT_USBINT | EHCI_INT_USBERRINT | \ + EHCI_INT_PORTSC | EHCI_INT_SYSERROR | \ + EHCI_INT_AAINT) + +/* The periodic frame list is a 4K-page aligned array of Frame List Link + * pointers. The length of the frame list may be programmable. The programmability + * of the periodic frame list is exported to system software via the HCCPARAMS + * register. If non-programmable, the length is 1024 elements. If programmable, + * the length can be selected by system software as one of 256, 512, or 1024 + * elements. + */ + +#define FRAME_LIST_SIZE 1024 + +/* Port numbers */ + +#define RHPNDX(rh) ((rh)->hport.hport.port) +#define RHPORT(rh) (RHPNDX(rh)+1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Internal representation of the EHCI Queue Head (QH) */ + +struct sam_epinfo_s; +struct sam_qh_s +{ + /* Fields visible to hardware */ + + struct ehci_qh_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ + + struct sam_epinfo_s *epinfo; /* Endpoint used for the transfer */ + uint32_t fqp; /* First qTD in the list (physical address) */ + uint8_t pad[8]; /* Padding to assure 32-byte alignment */ +}; + +/* Internal representation of the EHCI Queue Element Transfer Descriptor (qTD) */ + +struct sam_qtd_s +{ + /* Fields visible to hardware */ + + struct ehci_qtd_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ +}; + +/* The following is used to manage lists of free QHs and qTDs */ + +struct sam_list_s +{ + struct sam_list_s *flink; /* Link to next entry in the list */ + /* Variable length entry data follows */ +}; + +/* List traversal callout functions */ + +typedef int (*foreach_qh_t)(struct sam_qh_s *qh, uint32_t **bp, void *arg); +typedef int (*foreach_qtd_t)(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); + +/* This structure describes one endpoint. */ + +struct sam_epinfo_s +{ + uint8_t epno:7; /* Endpoint number */ + uint8_t dirin:1; /* 1:IN endpoint 0:OUT endpoint */ + uint8_t devaddr:7; /* Device address */ + uint8_t toggle:1; /* Next data toggle */ +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t interval; /* Polling interval */ +#endif + uint8_t status; /* Retained token status bits (for debug purposes) */ + volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */ + uint16_t maxpacket:11; /* Maximum packet size */ + uint16_t xfrtype:2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */ + uint16_t speed:2; /* See USB_*_SPEED definitions in ehci.h */ + int result; /* The result of the transfer */ + uint32_t xfrd; /* On completion, will hold the number of bytes transferred */ + sem_t iocsem; /* Semaphore used to wait for transfer completion */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* This structure retains the state of one root hub port */ + +struct sam_rhport_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct sam_rhport_s. + */ + + struct usbhost_driver_s drvr; + + /* Root hub port status */ + + volatile bool connected; /* Connected to device */ + struct sam_epinfo_s ep0; /* EP0 endpoint info */ + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s hport; +}; + +/* This structure retains the overall state of the USB host controller */ + +struct sam_ehci_s +{ + volatile bool pscwait; /* TRUE: Thread is waiting for port status change event */ + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for port status change events */ + + struct sam_epinfo_s ep0; /* Endpoint 0 */ + struct sam_list_s *qhfree; /* List of free Queue Head (QH) structures */ + struct sam_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */ + struct work_s work; /* Supports interrupt bottom half */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* Root hub ports */ + + struct sam_rhport_s rhport[SAM_EHCI_NRHPORT]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +static uint16_t sam_read16(const uint8_t *addr); +static uint32_t sam_read32(const uint8_t *addr); +#if 0 /* Not used */ +static void sam_write16(uint16_t memval, uint8_t *addr); +static void sam_write32(uint32_t memval, uint8_t *addr); +#endif + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t sam_swap16(uint16_t value); +static uint32_t sam_swap32(uint32_t value); +#else +# define sam_swap16(value) (value) +# define sam_swap32(value) (value) +#endif + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static void sam_checkreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static uint32_t sam_getreg(volatile uint32_t *regaddr); +static void sam_putreg(uint32_t regval, volatile uint32_t *regaddr); +#else +static inline uint32_t sam_getreg(volatile uint32_t *regaddr); +static inline void sam_putreg(uint32_t regval, volatile uint32_t *regaddr); +#endif +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay); + +/* Semaphores ******************************************************************/ + +static void sam_takesem(sem_t *sem); +#define sam_givesem(s) sem_post(s); + +/* Allocators ******************************************************************/ + +static struct sam_qh_s *sam_qh_alloc(void); +static void sam_qh_free(struct sam_qh_s *qh); +static struct sam_qtd_s *sam_qtd_alloc(void); +static void sam_qtd_free(struct sam_qtd_s *qtd); + +/* List Management *************************************************************/ + +static int sam_qh_foreach(struct sam_qh_s *qh, uint32_t **bp, + foreach_qh_t handler, void *arg); +static int sam_qtd_foreach(struct sam_qh_s *qh, foreach_qtd_t handler, + void *arg); +static int sam_qtd_discard(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_discard(struct sam_qh_s *qh); + +/* Cache Operations ************************************************************/ + +#if 0 /* Not used */ +static int sam_qtd_invalidate(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_invalidate(struct sam_qh_s *qh); +#endif +static int sam_qtd_flush(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_flush(struct sam_qh_s *qh); + +/* Endpoint Transfer Handling **************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_qtd_print(struct sam_qtd_s *qtd); +static void sam_qh_print(struct sam_qh_s *qh); +static int sam_qtd_dump(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_dump(struct sam_qh_s *qh, uint32_t **bp, void *arg); +#else +# define sam_qtd_print(qtd) +# define sam_qh_print(qh) +# define sam_qtd_dump(qtd, bp, arg) OK +# define sam_qh_dump(qh, bp, arg) OK +#endif + +static inline uint8_t sam_ehci_speed(uint8_t usbspeed); +static int sam_ioc_setup(struct sam_rhport_s *rhport, struct sam_epinfo_s *epinfo); +static int sam_ioc_wait(struct sam_epinfo_s *epinfo); +static void sam_qh_enqueue(struct sam_qh_s *qhead, struct sam_qh_s *qh); +static struct sam_qh_s *sam_qh_create(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo); +static int sam_qtd_addbpl(struct sam_qtd_s *qtd, const void *buffer, size_t buflen); +static struct sam_qtd_s *sam_qtd_setupphase(struct sam_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req); +static struct sam_qtd_s *sam_qtd_dataphase(struct sam_epinfo_s *epinfo, + void *buffer, int buflen, uint32_t tokenbits); +static struct sam_qtd_s *sam_qtd_statusphase(uint32_t tokenbits); +static int sam_async_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen); +#ifndef CONFIG_USBHOST_INT_DISABLE +static int sam_intr_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, uint8_t *buffer, size_t buflen); +#endif +static ssize_t sam_transfer_wait(struct sam_epinfo_s *epinfo); +#ifdef CONFIG_USBHOST_ASYNCH +static inline int sam_ioc_async_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, usbhost_asynch_t callback, + FAR void *arg); +static void sam_asynch_completion(struct sam_epinfo_s *epinfo); +#endif + +/* Interrupt Handling **********************************************************/ + +static int sam_qtd_ioccheck(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_ioccheck(struct sam_qh_s *qh, uint32_t **bp, void *arg); +static int sam_qtd_cancel(struct sam_qtd_s *qtd, uint32_t **bp, void *arg); +static int sam_qh_cancel(struct sam_qh_s *qh, uint32_t **bp, void *arg); +static inline void sam_ioc_bottomhalf(void); +static inline void sam_portsc_bottomhalf(void); +static inline void sam_syserr_bottomhalf(void); +static inline void sam_async_advance_bottomhalf(void); +static void sam_ehci_bottomhalf(FAR void *arg); +static int sam_ehci_tophalf(int irq, FAR void *context); + +/* USB Host Controller Operations **********************************************/ + +static int sam_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int sam_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int sam_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); +static int sam_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int sam_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int sam_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int sam_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int sam_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int sam_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer); +static int sam_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer); +static ssize_t sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int sam_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback, + FAR void *arg); +#endif +static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int sam_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, bool connected); +#endif +static void sam_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static int sam_reset(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct sam_ehci_s g_ehci; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_ehciconn; + +/* Maps USB chapter 9 speed to EHCI speed */ + +static const uint8_t g_ehci_speed[4] = +{ + 0, EHCI_LOW_SPEED, EHCI_FULL_SPEED, EHCI_HIGH_SPEED +}; + +/* The head of the asynchronous queue */ + +static struct sam_qh_s g_asynchead __attribute__ ((aligned(32))); + +#ifndef CONFIG_USBHOST_INT_DISABLE +/* The head of the periodic queue */ + +static struct sam_qh_s g_intrhead __attribute__ ((aligned(32))); + +/* The frame list */ + +#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE +static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__ ((aligned(4096))); +#else +static uint32_t *g_framelist; +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE +/* Pools of pre-allocated data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct sam_qh_s g_qhpool[CONFIG_SAMA5_EHCI_NQHS] + __attribute__ ((aligned(32))); + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct sam_qtd_s g_qtdpool[CONFIG_SAMA5_EHCI_NQTDS] + __attribute__ ((aligned(32))); + +#else +/* Pools of dynamically data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct sam_qh_s *g_qhpool; + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct sam_qtd_s *g_qtdpool; + +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_read16 + * + * Description: + * Read 16-bit little endian data + * + ****************************************************************************/ + +static uint16_t sam_read16(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint16_t)addr[0] << 8 | (uint16_t)addr[1]; +#else + return (uint16_t)addr[1] << 8 | (uint16_t)addr[0]; +#endif +} + +/**************************************************************************** + * Name: sam_read32 + * + * Description: + * Read 32-bit little endian data + * + ****************************************************************************/ + +static inline uint32_t sam_read32(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint32_t)sam_read16(&addr[0]) << 16 | + (uint32_t)sam_read16(&addr[2]); +#else + return (uint32_t)sam_read16(&addr[2]) << 16 | + (uint32_t)sam_read16(&addr[0]); +#endif +} + +/**************************************************************************** + * Name: sam_write16 + * + * Description: + * Write 16-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void sam_write16(uint16_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + addr[0] = memval & 0xff; + addr[1] = memval >> 8; +#else + addr[0] = memval >> 8; + addr[1] = memval & 0xff; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_write32 + * + * Description: + * Write 32-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void sam_write32(uint32_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + sam_write16(memval >> 16, &addr[0]); + sam_write16(memval & 0xffff, &addr[2]); +#else + sam_write16(memval & 0xffff, &addr[0]); + sam_write16(memval >> 16, &addr[2]); +#endif +} +#endif + +/**************************************************************************** + * Name: sam_swap16 + * + * Description: + * Swap bytes on a 16-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t sam_swap16(uint16_t value) +{ + return ((value >> 8) & 0xff) | ((value & 0xff) << 8); +} +#endif + +/**************************************************************************** + * Name: sam_swap32 + * + * Description: + * Swap bytes on a 32-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint32_t sam_swap32(uint32_t value) +{ + return (uint32_t)sam_swap16((uint16_t)((value >> 16) & 0xffff)) | + (uint32_t)sam_swap16((uint16_t)(value & 0xffff)) << 16; +} +#endif + +/**************************************************************************** + * Name: sam_printreg + * + * Description: + * Print the contents of a SAMA5 EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite) +{ + lldbg("%08x%s%08x\n", (uintptr_t)regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a SAMA5 + * EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_checkreg(volatile uint32_t *regaddr, uint32_t regval, bool iswrite) +{ + static uint32_t *prevaddr = NULL; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + sam_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = (uint32_t *)regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + sam_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMA5 register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static uint32_t sam_getreg(volatile uint32_t *regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = *regaddr; + + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t sam_getreg(volatile uint32_t *regaddr) +{ + return *regaddr; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMA5 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, true); + + /* Write the value */ + + *regaddr = regval; +} +#else +static inline void sam_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + *regaddr = regval; +} +#endif + +/**************************************************************************** + * Name: ehci_wait_usbsts + * + * Description: + * Wait for either (1) a field in the USBSTS register to take a specific + * value, (2) for a timeout to occur, or (3) a error to occur. Return + * a value to indicate which terminated the wait. + * + ****************************************************************************/ + +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay) +{ + uint32_t regval; + unsigned int timeout; + + timeout = 0; + do + { + /* Wait 5usec before trying again */ + + up_udelay(5); + timeout += 5; + + /* Read the USBSTS register and check for a system error */ + + regval = sam_getreg(&HCOR->usbsts); + if ((regval & EHCI_INT_SYSERROR) != 0) + { + usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval); + return -EIO; + } + + /* Mask out the bits of interest */ + + regval &= maskbits; + + /* Loop until the masked bits take the specified value or until a + * timeout occurs. + */ + } + while (regval != donebits && timeout < delay); + + /* We got here because either the waited for condition or a timeout + * occurred. Return a value to indicate which. + */ + + return (regval == donebits) ? OK : -ETIMEDOUT; +} + +/**************************************************************************** + * Semaphores + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void sam_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Allocators + ****************************************************************************/ +/**************************************************************************** + * Name: sam_qh_alloc + * + * Description: + * Allocate a Queue Head (QH) structure by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct sam_qh_s *sam_qh_alloc(void) +{ + struct sam_qh_s *qh; + + /* Remove the QH structure from the freelist */ + + qh = (struct sam_qh_s *)g_ehci.qhfree; + if (qh) + { + g_ehci.qhfree = ((struct sam_list_s *)qh)->flink; + memset(qh, 0, sizeof(struct sam_qh_s)); + } + + return qh; +} + +/**************************************************************************** + * Name: sam_qh_free + * + * Description: + * Free a Queue Head (QH) structure by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void sam_qh_free(struct sam_qh_s *qh) +{ + struct sam_list_s *entry = (struct sam_list_s *)qh; + + /* Put the QH structure back into the free list */ + + entry->flink = g_ehci.qhfree; + g_ehci.qhfree = entry; +} + +/**************************************************************************** + * Name: sam_qtd_alloc + * + * Description: + * Allocate a Queue Element Transfer Descriptor (qTD) by removing it from the + * free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct sam_qtd_s *sam_qtd_alloc(void) +{ + struct sam_qtd_s *qtd; + + /* Remove the qTD from the freelist */ + + qtd = (struct sam_qtd_s *)g_ehci.qtdfree; + if (qtd) + { + g_ehci.qtdfree = ((struct sam_list_s *)qtd)->flink; + memset(qtd, 0, sizeof(struct sam_qtd_s)); + } + + return qtd; +} + +/**************************************************************************** + * Name: sam_qtd_free + * + * Description: + * Free a Queue Element Transfer Descriptor (qTD) by returning it to the free + * list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void sam_qtd_free(struct sam_qtd_s *qtd) +{ + struct sam_list_s *entry = (struct sam_list_s *)qtd; + + /* Put the qTD back into the free list */ + + entry->flink = g_ehci.qtdfree; + g_ehci.qtdfree = entry; +} + +/**************************************************************************** + * List Management + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qh_foreach + * + * Description: + * Give the first entry in a list of Queue Head (QH) structures, call the + * handler for each QH structure in the list (including the one at the head + * of the list). + * + ****************************************************************************/ + +static int sam_qh_foreach(struct sam_qh_s *qh, uint32_t **bp, foreach_qh_t handler, + void *arg) +{ + struct sam_qh_s *next; + uintptr_t physaddr; + int ret; + + DEBUGASSERT(qh && handler); + while (qh) + { + /* Is this the end of the list? Check the horizontal link pointer (HLP) + * terminate (T) bit. If T==1, then the HLP address is not valid. + */ + + physaddr = sam_swap32(qh->hw.hlp); + if ((physaddr & QH_HLP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + + /* Is the next QH the asynchronous list head which will always be at + * the end of the asynchronous queue? + */ + + else if (sam_virtramaddr(physaddr & QH_HLP_MASK) == (uintptr_t)&g_asynchead) + { + /* That will also terminate the loop */ + + next = NULL; + } + + /* Otherwise, there is a QH structure after this one that describes + * another transaction. + */ + + else + { + physaddr = sam_swap32(qh->hw.hlp) & QH_HLP_MASK; + next = (struct sam_qh_s *)sam_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next QH pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qh, bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qh = next; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_qtd_foreach + * + * Description: + * Give a Queue Head (QH) instance, call the handler for each qTD structure + * in the queue. + * + ****************************************************************************/ + +static int sam_qtd_foreach(struct sam_qh_s *qh, foreach_qtd_t handler, void *arg) +{ + struct sam_qtd_s *qtd; + struct sam_qtd_s *next; + uintptr_t physaddr; + uint32_t *bp; + int ret; + + DEBUGASSERT(qh && handler); + + /* Handle the special case where the queue is empty */ + + bp = &qh->fqp; /* Start of qTDs in original list */ + physaddr = sam_swap32(*bp); /* Physical address of first qTD in CPU order */ + + if ((physaddr & QTD_NQP_T) != 0) + { + return 0; + } + + /* Start with the first qTD in the list */ + + qtd = (struct sam_qtd_s *)sam_virtramaddr(physaddr); + next = NULL; + + /* And loop until we encounter the end of the qTD list */ + + while (qtd) + { + /* Is this the end of the list? Check the next qTD pointer (NQP) + * terminate (T) bit. If T==1, then the NQP address is not valid. + */ + + if ((sam_swap32(qtd->hw.nqp) & QTD_NQP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + else + { + physaddr = sam_swap32(qtd->hw.nqp) & QTD_NQP_NTEP_MASK; + next = (struct sam_qtd_s *)sam_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next qTD pointer. + * + * Notice that we do not manage the back pointer (bp). If the callout + * uses it, it must update it as necessary. + */ + + ret = handler(qtd, &bp, arg); + + /* If the handler returns any non-zero value, then terminate the traversal + * early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qtd = next; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_qtd_discard + * + * Description: + * This is a sam_qtd_foreach callback. It simply unlinks the QTD, updates + * the back pointer, and frees the QTD structure. + * + ****************************************************************************/ + +static int sam_qtd_discard(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd && bp && *bp); + + /* Remove the qTD from the list by updating the forward pointer to skip + * around this qTD. We do not change that pointer because are repeatedly + * removing the aTD at the head of the QH list. + */ + + **bp = qtd->hw.nqp; + + /* Then free the qTD */ + + sam_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: sam_qh_discard + * + * Description: + * Free the Queue Head (QH) and all qTD's attached to the QH. + * + * Assumptions: + * The QH structure itself has already been unlinked from whatever list it + * may have been in. + * + ****************************************************************************/ + +static int sam_qh_discard(struct sam_qh_s *qh) +{ + int ret; + + DEBUGASSERT(qh); + + /* Free all of the qTD's attached to the QH */ + + ret = sam_qtd_foreach(qh, sam_qtd_discard, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then free the QH itself */ + + sam_qh_free(qh); + return ret; +} + +/**************************************************************************** + * Cache Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qtd_invalidate + * + * Description: + * This is a callback from sam_qtd_foreach. It simply invalidates D-cache for + * address range of the qTD entry. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int sam_qtd_invalidate(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Invalidate the D-Cache, i.e., force reloading of the D-Cache from memory + * memory over the specified address range. + */ + + arch_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_qh_invalidate + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int sam_qh_invalidate(struct sam_qh_s *qh) +{ + /* Invalidate the QH first so that we reload the qTD list head */ + + arch_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + + /* Then invalidate all of the qTD entries in the queue */ + + return sam_qtd_foreach(qh, sam_qtd_invalidate, NULL); +} +#endif + +/**************************************************************************** + * Name: sam_qtd_flush + * + * Description: + * This is a callback from sam_qtd_foreach. It simply flushes D-cache for + * address range of the qTD entry. + * + ****************************************************************************/ + +static int sam_qtd_flush(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Flush the D-Cache, i.e., make the contents of the memory match the contents + * of the D-Cache in the specified address range and invalidate the D-Cache + * to force re-loading of the data from memory when next accessed. + */ + +#if 0 /* Didn't behave as expected */ + arch_flush_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); +#else + arch_clean_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + arch_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_qh_flush + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +static int sam_qh_flush(struct sam_qh_s *qh) +{ + /* Flush the QH first. This will write the contents of the D-cache to RAM and + * invalidate the contents of the D-cache so that the next access will be + * reloaded from D-Cache. + */ + +#if 0 /* Didn't behave as expected */ + arch_flush_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); +#else + arch_clean_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + arch_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); +#endif + + /* Then flush all of the qTD entries in the queue */ + + return sam_qtd_foreach(qh, sam_qtd_flush, NULL); +} + +/**************************************************************************** + * Endpoint Transfer Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qtd_print + * + * Description: + * Print the context of one qTD + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_qtd_print(struct sam_qtd_s *qtd) +{ + udbg(" QTD[%p]:\n", qtd); + udbg(" hw:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + qtd->hw.nqp, qtd->hw.alt, qtd->hw.token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + qtd->hw.bpl[0], qtd->hw.bpl[1], qtd->hw.bpl[2], + qtd->hw.bpl[3], qtd->hw.bpl[4]); +} +#endif + +/**************************************************************************** + * Name: sam_qh_print + * + * Description: + * Print the context of one QH + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static void sam_qh_print(struct sam_qh_s *qh) +{ + struct sam_epinfo_s *epinfo; + struct ehci_overlay_s *overlay; + + udbg("QH[%p]:\n", qh); + udbg(" hw:\n"); + udbg(" hlp: %08x epchar: %08x epcaps: %08x cqp: %08x\n", + qh->hw.hlp, qh->hw.epchar, qh->hw.epcaps, qh->hw.cqp); + + overlay = &qh->hw.overlay; + udbg(" overlay:\n"); + udbg(" nqp: %08x alt: %08x token: %08x\n", + overlay->nqp, overlay->alt, overlay->token); + udbg(" bpl: %08x %08x %08x %08x %08x\n", + overlay->bpl[0], overlay->bpl[1], overlay->bpl[2], + overlay->bpl[3], overlay->bpl[4]); + + udbg(" fqp:\n", qh->fqp); + + epinfo = qh->epinfo; + udbg(" epinfo[%p]:\n", epinfo); + if (epinfo) + { + udbg(" EP%d DIR=%s FA=%08x TYPE=%d MaxPacket=%d\n", + epinfo->epno, epinfo->dirin ? "IN" : "OUT", epinfo->devaddr, + epinfo->xfrtype, epinfo->maxpacket); + udbg(" Toggle=%d iocwait=%d speed=%d result=%d\n", + epinfo->toggle, epinfo->iocwait, epinfo->speed, epinfo->result); + } +} +#endif + +/**************************************************************************** + * Name: sam_qtd_dump + * + * Description: + * This is a sam_qtd_foreach callout function. It dumps the context of one + * qTD + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static int sam_qtd_dump(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + sam_qtd_print(qtd); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_qh_dump + * + * Description: + * This is a sam_qh_foreach callout function. It dumps a QH structure and + * all of the qTD structures linked to the QH. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI_REGDEBUG +static int sam_qh_dump(struct sam_qh_s *qh, uint32_t **bp, void *arg) +{ + sam_qh_print(qh); + return sam_qtd_foreach(qh, sam_qtd_dump, NULL); +} +#endif + +/**************************************************************************** + * Name: sam_ehci_speed + * + * Description: + * Map a speed enumeration value per Chapter 9 of the USB specification to the + * speed enumeration required in the EHCI queue head. + * + ****************************************************************************/ + +static inline uint8_t sam_ehci_speed(uint8_t usbspeed) +{ + DEBUGASSERT(usbspeed >= USB_SPEED_LOW && usbspeed <= USB_SPEED_HIGH); + return g_ehci_speed[usbspeed]; +} + +/**************************************************************************** + * Name: sam_ioc_setup + * + * Description: + * Set the request for the IOC event well BEFORE enabling the transfer (as + * soon as we are absolutely committed to the to avoid transfer). We do this + * to minimize race conditions. This logic would have to be expanded if we + * want to have more than one packet in flight at a time! + * + * Assumption: The caller holds tex EHCI exclsem + * + ****************************************************************************/ + +static int sam_ioc_setup(struct sam_rhport_s *rhport, struct sam_epinfo_s *epinfo) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait); +#ifdef CONFIG_USBHOST_ASYNCH + DEBUGASSERT(epinfo->callback == NULL); +#endif + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then set iocwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + epinfo->iocwait = true; /* We want to be awakened by IOC interrupt */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; /* No asynchronous callback */ + epinfo->arg = NULL; +#endif + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_ioc_wait + * + * Description: + * Wait for the IOC event. + * + * Assumption: The caller does *NOT* hold the EHCI exclsem. That would cause + * a deadlock when the bottom-half, worker thread needs to take the semaphore. + * + ****************************************************************************/ + +static int sam_ioc_wait(struct sam_epinfo_s *epinfo) +{ + /* Wait for the IOC event. Loop to handle any false alarm semaphore counts. */ + + while (epinfo->iocwait) + { + sam_takesem(&epinfo->iocsem); + } + + return epinfo->result; +} + +/**************************************************************************** + * Name: sam_qh_enqueue + * + * Description: + * Add a new, ready-to-go QH w/attached qTDs to the asynchonous queue. + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static void sam_qh_enqueue(struct sam_qh_s *qhead, struct sam_qh_s *qh) +{ + uintptr_t physaddr; + + /* Set the internal fqp field. When we transverse the QH list later, + * we need to know the correct place to start because the overlay may no + * longer point to the first qTD entry. + */ + + qh->fqp = qh->hw.overlay.nqp; + (void)sam_qh_dump(qh, NULL, NULL); + + /* Add the new QH to the head of the asynchronous queue list. + * + * First, attach the old head as the new QH HLP and flush the new QH and its + * attached qTDs to RAM. + */ + + qh->hw.hlp = qhead->hw.hlp; + sam_qh_flush(qh); + + /* Then set the new QH as the first QH in the asychronous queue and flush the + * modified head to RAM. + */ + + physaddr = (uintptr_t)sam_physramaddr((uintptr_t)qh); + qhead->hw.hlp = sam_swap32(physaddr | QH_HLP_TYP_QH); + arch_clean_dcache((uintptr_t)&qhead->hw, + (uintptr_t)&qhead->hw + sizeof(struct ehci_qh_s)); +} + +/**************************************************************************** + * Name: sam_qh_create + * + * Description: + * Create a new Queue Head (QH) + * + ****************************************************************************/ + +static struct sam_qh_s *sam_qh_create(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo) +{ + struct sam_qh_s *qh; + uint32_t rhpndx; + uint32_t regval; + uint8_t hubaddr; + uint8_t hubport; + + /* Allocate a new queue head structure */ + + qh = sam_qh_alloc(); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0); + return NULL; + } + + /* Save the endpoint information with the QH itself */ + + qh->epinfo = epinfo; + + /* Write QH endpoint characteristics: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * DEVADDR Device address Endpoint structure + * I Inactivate on Next Transaction 0 + * ENDPT Endpoint number Endpoint structure + * EPS Endpoint speed Endpoint structure + * DTC Data toggle control 1 + * MAXPKT Max packet size Endpoint structure + * C Control endpoint Calculated + * RL NAK count reloaded 8 + */ + + regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) | + ((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) | + ((uint32_t)sam_ehci_speed(epinfo->speed) << QH_EPCHAR_EPS_SHIFT) | + QH_EPCHAR_DTC | + ((uint32_t)epinfo->maxpacket << QH_EPCHAR_MAXPKT_SHIFT) | + ((uint32_t)8 << QH_EPCHAR_RL_SHIFT); + + /* Paragraph 3.6.3: "Control Endpoint Flag (C). If the QH.EPS field + * indicates the endpoint is not a high-speed device, and the endpoint + * is an control endpoint, then software must set this bit to a one. + * Otherwise it should always set this bit to a zero." + */ + + if (epinfo->speed != USB_SPEED_HIGH && + epinfo->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + regval |= QH_EPCHAR_C; + } + + /* Save the endpoint characteristics word with the correct byte order */ + + qh->hw.epchar = sam_swap32(regval); + + /* Write QH endpoint capabilities + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * SSMASK Interrupt Schedule Mask Depends on epinfo->xfrtype + * SCMASK Split Completion Mask 0 + * HUBADDR Hub Address Always 0 for now + * PORT Port number RH port index + 1 + * MULT High band width multiplier 1 + */ + + rhpndx = RHPNDX(rhport); + +#ifdef CONFIG_USBHOST_HUB + /* REVISIT: Future HUB support will require the HUB port number + * and HUB device address to be included here: + * + * - The HUB device address is the USB device address of the USB 2.0 Hub + * below which a full- or low-speed device is attached. + * - The HUB port number is the port number on the above USB 2.0 Hub + * + * These fields are used in the split-transaction protocol. The kludge + * below should work for hubs connected directly to a root hub port, + * but would not work for devices connected to downstream hubs. + */ + +#warning Missing logic + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#else + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#endif + + regval = ((uint32_t)hubaddr << QH_EPCAPS_HUBADDR_SHIFT) | + ((uint32_t)hubport << QH_EPCAPS_PORT_SHIFT) | + ((uint32_t)1 << QH_EPCAPS_MULT_SHIFT); + +#ifndef CONFIG_USBHOST_INT_DISABLE + if (epinfo->xfrtype == USB_EP_ATTR_XFER_INT) + { + /* Here, the S-Mask field in the queue head is set to 1, indicating + * that the transaction for the endpoint should be executed on the bus + * during micro-frame 0 of the frame. + * + * REVISIT: The polling interval should be controlled by the which + * entry is the framelist holds the QH pointer for a given micro-frame + * and the QH pointer should be replicated for different polling rates. + * This implementation currently just sets all frame_list entry to + * all the same interrupt queue. That should work but will not give + * any control over polling rates. + */ +#warning REVISIT + + regval |= ((uint32_t)1 << QH_EPCAPS_SSMASK_SHIFT); + } +#endif + + qh->hw.epcaps = sam_swap32(regval); + + /* Mark this as the end of this list. This will be overwritten if/when the + * next qTD is added to the queue. + */ + + qh->hw.hlp = sam_swap32(QH_HLP_T); + qh->hw.overlay.nqp = sam_swap32(QH_NQP_T); + qh->hw.overlay.alt = sam_swap32(QH_AQP_T); + return qh; +} + +/**************************************************************************** + * Name: sam_qtd_addbpl + * + * Description: + * Add a buffer pointer list to a qTD. + * + ****************************************************************************/ + +static int sam_qtd_addbpl(struct sam_qtd_s *qtd, const void *buffer, size_t buflen) +{ + uint32_t physaddr; + uint32_t nbytes; + uint32_t next; + int ndx; + + /* Flush the contents of the data buffer to RAM so that the correct contents + * will be accessed for an OUT DMA. + */ + +#if 0 /* Didn't behave as expected */ + arch_flush_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); +#else + arch_clean_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + arch_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); +#endif + + /* Loop, adding the aligned physical addresses of the buffer to the buffer page + * list. Only the first entry need not be aligned (because only the first + * entry has the offset field). The subsequent entries must begin on 4KB + * address boundaries. + */ + + physaddr = (uint32_t)sam_physramaddr((uintptr_t)buffer); + + for (ndx = 0; ndx < 5; ndx++) + { + /* Write the physical address of the buffer into the qTD buffer pointer + * list. + */ + + qtd->hw.bpl[ndx] = sam_swap32(physaddr); + + /* Get the next buffer pointer (in the case where we will have to transfer + * more then one chunk). This buffer must be aligned to a 4KB address + * boundary. + */ + + next = (physaddr + 4096) & ~4095; + + /* How many bytes were included in the last buffer? Was it the whole + * thing? + */ + + nbytes = next - physaddr; + if (nbytes >= buflen) + { + /* Yes... it was the whole thing. Break out of the loop early. */ + + break; + } + + /* Adjust the buffer length and physical address for the next time + * through the loop. + */ + + buflen -= nbytes; + physaddr = next; + } + + /* Handle the case of a huge buffer > 4*4KB = 16KB */ + + if (ndx >= 5) + { + usbhost_trace1(EHCI_TRACE1_BUFTOOBIG, buflen); + return -EFBIG; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_qtd_setupphase + * + * Description: + * Create a SETUP phase request qTD. + * + ****************************************************************************/ + +static struct sam_qtd_s *sam_qtd_setupphase(struct sam_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req) +{ + struct sam_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = sam_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = sam_swap32(QTD_NQP_T); + qtd->hw.alt = sam_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code QTD_TOKEN_PID_SETUP + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete 0 + * NBYTES Total Bytes to Transfer USB_SIZEOF_CTRLREQ + * TOGGLE Data Toggle 0 + */ + + regval = QTD_TOKEN_ACTIVE | QTD_TOKEN_PID_SETUP | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)USB_SIZEOF_CTRLREQ << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = sam_swap32(regval); + + /* Add the buffer data */ + + ret = sam_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + sam_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += USB_SIZEOF_CTRLREQ; + + return qtd; +} + +/**************************************************************************** + * Name: sam_qtd_dataphase + * + * Description: + * Create a data transfer or SET data phase qTD. + * + ****************************************************************************/ + +static struct sam_qtd_s *sam_qtd_dataphase(struct sam_epinfo_s *epinfo, + void *buffer, int buflen, + uint32_t tokenbits) +{ + struct sam_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = sam_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = sam_swap32(QTD_NQP_T); + qtd->hw.alt = sam_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete Contained in tokenbits + * NBYTES Total Bytes to Transfer buflen + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)buflen << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = sam_swap32(regval); + + /* Add the buffer information to the buffer pointer list */ + + ret = sam_qtd_addbpl(qtd, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + sam_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += buflen; + + return qtd; +} + +/**************************************************************************** + * Name: sam_qtd_statusphase + * + * Description: + * Create a STATUS phase request qTD. + * + ****************************************************************************/ + +static struct sam_qtd_s *sam_qtd_statusphase(uint32_t tokenbits) +{ + struct sam_qtd_s *qtd; + uint32_t regval; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = sam_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = sam_swap32(QTD_NQP_T); + qtd->hw.alt = sam_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete QTD_TOKEN_IOC + * NBYTES Total Bytes to Transfer 0 + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | QTD_TOKEN_IOC | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT); + + qtd->hw.token = sam_swap32(regval); + return qtd; +} + +/**************************************************************************** + * Name: sam_async_setup + * + * Description: + * Process a IN or OUT request on any asynchronous endpoint (bulk or control). + * This function will enqueue the request and wait for it to complete. Bulk + * data transfers differ in that req == NULL and there are not SETUP or STATUS + * phases. + * + * This is a blocking function; it will not return until the control transfer + * has completed. + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +static int sam_async_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen) +{ + struct sam_qh_s *qh; + struct sam_qtd_s *qtd; + uintptr_t physaddr; + uint32_t *flink; + uint32_t *alt; + uint32_t toggle; + bool dirin = false; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_ASYNCXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d, req=%p\n", + RHPORT(rhport), epinfo->epno, buffer, buflen, req); +#endif + + DEBUGASSERT(rhport && epinfo); + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + DEBUGASSERT(req || (buffer && buflen > 0)); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = sam_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the QH link and get the next data toggle (not used for SETUP + * transfers) + */ + + flink = &qh->hw.overlay.nqp; + toggle = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + ret = -EIO; + + /* Is the an EP0 SETUP request? If so, req will be non-NULL and we will + * queue two or three qTDs: + * + * 1) One for the SETUP phase, + * 2) One for the DATA phase (if there is data), and + * 3) One for the STATUS phase. + * + * If this is not an EP0 SETUP request, then only a data transfer will be + * enqueued. + */ + + if (req != NULL) + { + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the SETUP + * phase of the request sequence. + */ + + qtd = sam_qtd_setupphase(epinfo, req); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to the QH head. */ + + physaddr = sam_physramaddr((uintptr_t)qtd); + *flink = sam_swap32(physaddr); + + /* Get the new forward link pointer and data toggle */ + + flink = &qtd->hw.nqp; + toggle = QTD_TOKEN_TOGGLE; + } + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer will + * always be present for normal endpoint data transfers. + */ + + alt = NULL; + if (buffer != NULL && buflen > 0) + { + uint32_t tokenbits; + + /* Extra TOKEN bits include the data toggle, the data PID, and if + * there is no request, an indication to interrupt at the end of this + * transfer. + */ + + tokenbits = toggle; + + /* Get the data token direction. + * + * If this is a SETUP request, use the direction contained in the + * request. The IOC bit is not set. + */ + + if (req) + { + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_IN; + dirin = true; + } + else + { + tokenbits |= QTD_TOKEN_PID_OUT; + dirin = false; + } + } + + /* Otherwise, the endpoint is uni-directional. Get the direction from + * the epinfo structure. Since this is not an EP0 SETUP request, + * nothing follows the data and we want the IOC interrupt when the + * data transfer completes. + */ + + else if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + dirin = true; + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + dirin = false; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = sam_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either QH head of the SETUP qTD. */ + + physaddr = sam_physramaddr((uintptr_t)qtd); + *flink = sam_swap32(physaddr); + + /* Set the forward link pointer to this new qTD */ + + flink = &qtd->hw.nqp; + + /* If this was an IN transfer, then setup a pointer alternate link. + * The EHCI hardware will use this link if a short packet is received. + */ + + if (dirin) + { + alt = &qtd->hw.alt; + } + } + + /* If this is an EP0 SETUP request, then enqueue one more qTD for the + * STATUS phase transfer. + */ + + if (req != NULL) + { + /* Extra TOKEN bits include the data toggle and the correct data PID. */ + + uint32_t tokenbits = toggle; + + /* The status phase direction is the opposite of the data phase. If + * this is an IN request, then we received the buffer and we will send + * the zero length packet handshake. + */ + + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_OUT; + } + + /* Otherwise, this in an OUT request. We send the buffer and we expect + * to receive the NULL packet handshake. + */ + + else + { + tokenbits |= QTD_TOKEN_PID_IN; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the status */ + + qtd = sam_qtd_statusphase(tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either the SETUP or data qTD. */ + + physaddr = sam_physramaddr((uintptr_t)qtd); + *flink = sam_swap32(physaddr); + + /* In an IN data qTD was also enqueued, then linke the data qTD's + * alternate pointer to this STATUS phase qTD in order to handle short + * transfers. + */ + + if (alt) + { + *alt = sam_swap32(physaddr); + } + } + + /* Add the new QH to the head of the asynchronous queue list */ + + sam_qh_enqueue(&g_asynchead, qh); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + sam_qh_discard(qh); + return ret; +} + +/**************************************************************************** + * Name: sam_intr_setup + * + * Description: + * Process a IN or OUT request on any interrupt endpoint by inserting a qTD + * into the periodic frame list. + * + * Paragraph 4.10.7 "Adding Interrupt Queue Heads to the Periodic Schedule" + * "The link path(s) from the periodic frame list to a queue head establishes + * in which frames a transaction can be executed for the queue head. Queue + * heads are linked into the periodic schedule so they are polled at + * the appropriate rate. System software sets a bit in a queue head's + * S-Mask to indicate which micro-frame with-in a 1 millisecond period a + * transaction should be executed for the queue head. Software must ensure + * that all queue heads in the periodic schedule have S-Mask set to a non- + * zero value. An S-mask with a zero value in the context of the periodic + * schedule yields undefined results. + * + * "If the desired poll rate is greater than one frame, system software can + * use a combination of queue head linking and S-Mask values to spread + * interrupts of equal poll rates through the schedule so that the + * periodic bandwidth is allocated and managed in the most efficient + * manner possible." + * + * Paragraph 4.6 "Periodic Schedule" + * + * "The periodic schedule is used to manage all isochronous and interrupt + * transfer streams. The base of the periodic schedule is the periodic + * frame list. Software links schedule data structures to the periodic + * frame list to produce a graph of scheduled data structures. The graph + * represents an appropriate sequence of transactions on the USB. ... + * isochronous transfers (using iTDs and siTDs) with a period of one are + * linked directly to the periodic frame list. Interrupt transfers (are + * managed with queue heads) and isochronous streams with periods other + * than one are linked following the period-one iTD/siTDs. Interrupt + * queue heads are linked into the frame list ordered by poll rate. + * Longer poll rates are linked first (e.g. closest to the periodic + * frame list), followed by shorter poll rates, with queue heads with a + * poll rate of one, on the very end." + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +#ifndef CONFIG_USBHOST_INT_DISABLE +static int sam_intr_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, + uint8_t *buffer, size_t buflen) +{ + struct sam_qh_s *qh; + struct sam_qtd_s *qtd; + uintptr_t physaddr; + uint32_t tokenbits; + uint32_t regval; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_INTRXFR, epinfo->epno, buflen); +#else + uvdbg("RHport%d EP%d: buffer=%p, buflen=%d\n", + RHPORT(rhport), epinfo->epno, buffer, buflen); +#endif + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = sam_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Extra TOKEN bits include the data toggle, the data PID, and an + * indication to interrupt at the end of this transfer. + */ + + tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + + /* Get the data token direction. */ + + if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = sam_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + ret = -ENOMEM; + goto errout_with_qh; + } + + /* Link the new qTD to the QH. */ + + physaddr = sam_physramaddr((uintptr_t)qtd); + qh->hw.overlay.nqp = sam_swap32(physaddr); + + /* Disable the periodic schedule */ + + regval = sam_getreg(&HCOR->usbcmd); + regval &= ~EHCI_USBCMD_PSEN; + sam_putreg(regval, &HCOR->usbcmd); + + /* Add the new QH to the head of the interrupt transfer list */ + + sam_qh_enqueue(&g_intrhead, qh); + + /* Re-enable the periodic schedule */ + + regval |= EHCI_USBCMD_PSEN; + sam_putreg(regval, &HCOR->usbcmd); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + sam_qh_discard(qh); + return ret; +} +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +/**************************************************************************** + * Name: sam_transfer_wait + * + * Description: + * Wait for an IN or OUT transfer to complete. + * + * Assumption: The caller holds the EHCI exclsem. The caller must be aware + * that the EHCI exclsem will released while waiting for the transfer to + * complete, but will be re-acquired when before returning. The state of + * EHCI resources could be very different upon return. + * + * Returned value: + * On success, this function returns the number of bytes actually transferred. + * For control transfers, this size includes the size of the control request + * plus the size of the data (which could be short); For bulk transfers, this + * will be the number of data bytes transfers (which could be short). + * + ****************************************************************************/ + +static ssize_t sam_transfer_wait(struct sam_epinfo_s *epinfo) +{ + int ret; + + /* Release the EHCI semaphore while we wait. Other threads need the + * opportunity to access the EHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not EHCI common) until + * the transfer is complete. But we can't use the common EHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ +#warning REVISIT + sam_givesem(&g_ehci.exclsem); + + /* Wait for the IOC completion event */ + + ret = sam_ioc_wait(epinfo); + + /* Re-acquire the EHCI semaphore. The caller expects to be holding + * this upon return. + */ + + sam_takesem(&g_ehci.exclsem); + +#if 0 /* Does not seem to be needed */ + /* Was there a data buffer? Was this an OUT transfer? */ + + if (buffer != NULL && buflen > 0 && !dirin) + { + /* We have received data from the host -- unless there was an error. + * in any event, we will invalidate the data buffer so that we will + * reload any new data freshly DMAed into the user buffer. + * + * NOTE: This might be un-necessary. We cleaned and invalidated the + * D-Cache prior to starting the DMA so the D-Cache should still be + * invalid in this memory region. + */ + + arch_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + } +#endif + + /* Did sam_ioc_wait() report an error? */ + + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_TRANSFER_FAILED, -ret); + epinfo->iocwait = false; + return (ssize_t)ret; + } + + /* Transfer completed successfully. Return the number of bytes + * transferred. + */ + + return epinfo->xfrd; +} + +/**************************************************************************** + * Name: sam_ioc_async_setup + * + * Description: + * Setup to receive an asynchronous notification when a transfer completes. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer will be performed. + * callback - The function to be called when the completes + * arg - An arbitrary argument that will be provided with the callback. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static inline int sam_ioc_async_setup(struct sam_rhport_s *rhport, + struct sam_epinfo_s *epinfo, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait && + epinfo->callback == NULL); + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then save callback information to used when either (1) the + * device is disconnected, or (2) the transfer completes. + */ + + epinfo->iocwait = false; /* No synchronous wakeup */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ + epinfo->callback = callback; /* Asynchronous callback */ + epinfo->arg = arg; /* Argument that accompanies the callback */ + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: sam_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer was performed. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void sam_asynch_completion(struct sam_epinfo_s *epinfo) +{ + usbhost_asynch_t callback; + ssize_t nbytes; + void *arg; + int result; + + DEBUGASSERT(epinfo != NULL && epinfo->iocwait == false && + epinfo->callback != NULL); + + /* Extract and reset the callback info */ + + callback = epinfo->callback; + arg = epinfo->arg; + result = epinfo->result; + nbytes = epinfo->xfrd; + + epinfo->callback = NULL; + epinfo->arg = NULL; + epinfo->result = OK; + epinfo->iocwait = false; + + /* Then perform the callback. Provide the number of bytes successfully + * transferred or the negated errno value in the event of a failure. + */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * EHCI Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qtd_ioccheck + * + * Description: + * This function is a sam_qtd_foreach() callback function. It services one + * qTD in the asynchronous queue. It removes all of the qTD structures that + * are no longer active. + * + ****************************************************************************/ + +static int sam_qtd_ioccheck(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)arg; + DEBUGASSERT(qtd && epinfo); + + /* Make sure we reload the QH from memory */ + + arch_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + sam_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + */ + + **bp = qtd->hw.nqp; + + /* Subtract the number of bytes left untransferred. The epinfo->xfrd + * field is initialized to the total number of bytes to be transferred + * (all qTDs in the list). We subtract out the number of untransferred + * bytes on each transfer and the final result will be the number of bytes + * actually transferred. + */ + + epinfo->xfrd -= (sam_swap32(qtd->hw.token) & QTD_TOKEN_NBYTES_MASK) >> + QTD_TOKEN_NBYTES_SHIFT; + + /* Release this QH by returning it to the free list */ + + sam_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: sam_qh_ioccheck + * + * Description: + * This function is a sam_qh_foreach() callback function. It services one + * QH in the asynchronous queue. It check all attached qTD structures and + * remove all of the structures that are no longer active. if all of the + * qTD structures are removed, then QH itself will also be removed. + * + ****************************************************************************/ + +static int sam_qh_ioccheck(struct sam_qh_s *qh, uint32_t **bp, void *arg) +{ + struct sam_epinfo_s *epinfo; + uint32_t token; + int ret; + + DEBUGASSERT(qh && bp); + + /* Make sure we reload the QH from memory */ + + arch_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + sam_qh_print(qh); + + /* Get the endpoint info pointer from the extended QH data. Only the + * g_asynchead QH can have a NULL epinfo field. + */ + + epinfo = qh->epinfo; + DEBUGASSERT(epinfo); + + /* Paragraph 3.6.3: "The nine DWords in [the Transfer Overlay] area represent + * a transaction working space for the host controller. The general + * operational model is that the host controller can detect whether the + * overlay area contains a description of an active transfer. If it does + * not contain an active transfer, then it follows the Queue Head Horizontal + * Link Pointer to the next queue head. The host controller will never follow + * the Next Transfer Queue Element or Alternate Queue Element pointers unless + * it is actively attempting to advance the queue ..." + */ + + /* Is the qTD still active? */ + + token = sam_swap32(qh->hw.overlay.token); + usbhost_vtrace2(EHCI_VTRACE2_IOCCHECK, epinfo->epno, token); + + if ((token & QH_TOKEN_ACTIVE) != 0) + { + /* Yes... we cannot process the QH while it is still active. Return + * zero to visit the next QH in the list. + */ + *bp = &qh->hw.hlp; + return OK; + } + + /* Remove all active, attached qTD structures from the inactive QH */ + + ret = sam_qtd_foreach(qh, sam_qtd_ioccheck, (void *)qh->epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* If there is no longer anything attached to the QH, then remove it from + * the asynchronous queue. + */ + + if ((sam_swap32(qh->fqp) & QTD_NQP_T) != 0) + { + /* Set the forward link of the previous QH to point to the next + * QH in the list. + */ + + **bp = qh->hw.hlp; + arch_clean_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Check for errors, update the data toggle */ + + if ((token & QH_TOKEN_ERRORS) == 0) + { + /* No errors.. Save the last data toggle value */ + + epinfo->toggle = (token >> QTD_TOKEN_TOGGLE_SHIFT) & 1; + + /* Report success */ + + epinfo->status = 0; + epinfo->result = OK; + } + else + { + /* An error occurred */ + + epinfo->status = (token & QH_TOKEN_STATUS_MASK) >> QH_TOKEN_STATUS_SHIFT; + + /* The HALT condition is set on a variety of conditions: babble, error + * counter countdown to zero, or a STALL. If we can rule out babble + * (babble bit not set) and if the error counter is non-zero, then we can + * assume a STALL. In this case, we return -PERM to inform the class + * driver of the stall condition. + */ + + if ((token & (QH_TOKEN_BABBLE | QH_TOKEN_HALTED)) == QH_TOKEN_HALTED && + (token & QH_TOKEN_CERR_MASK) != 0) + { + /* It is a stall, Note the that the data toggle is reset + * after the stall. + */ + + usbhost_trace2(EHCI_TRACE2_EPSTALLED, epinfo->epno, token); + epinfo->result = -EPERM; + epinfo->toggle = 0; + } + else + { + /* Otherwise, it is some kind of data transfer error */ + + usbhost_trace2(EHCI_TRACE2_EPIOERROR, epinfo->epno, token); + epinfo->result = -EIO; + } + } + + /* Is there a thread waiting for this transfer to complete? */ + + if (epinfo->iocwait) + { + /* Yes... wake it up */ + + sam_givesem(&epinfo->iocsem); + epinfo->iocwait = 0; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. Is there a pending asynchronous transfer? */ + + else if (epinfo->callback != NULL) + { + /* Yes.. perform the callback */ + + sam_asynch_completion(epinfo); + } +#endif + + /* Then release this QH by returning it to the free list */ + + sam_qh_free(qh); + } + else + { + /* Otherwise, the horizontal link pointer of this QH will become the next back pointer. + */ + + *bp = &qh->hw.hlp; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_qtd_cancel + * + * Description: + * This function is a sam_qtd_foreach() callback function. It removes each + * qTD attached to a QH. + * + ****************************************************************************/ + +static int sam_qtd_cancel(struct sam_qtd_s *qtd, uint32_t **bp, void *arg) +{ + DEBUGASSERT(qtd != NULL && bp != NULL); + + /* Make sure we reload the QH from memory */ + + arch_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + sam_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qtd->hw.nqp; + + /* Release this QH by returning it to the free list */ + + sam_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: sam_qh_cancel + * + * Description: + * This function is a sam_qh_foreach() callback function. It cancels one + * QH in the asynchronous queue. It will remove all attached qTD structures + * and remove all of the structures that are no longer active. Then QH + * itself will also be removed. + * + ****************************************************************************/ + +static int sam_qh_cancel(struct sam_qh_s *qh, uint32_t **bp, void *arg) +{ + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)arg; + uint32_t regval; + int ret; + + DEBUGASSERT(qh != NULL && bp != NULL && epinfo != NULL); + + /* Make sure we reload the QH from memory */ + + arch_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + sam_qh_print(qh); + + /* Check if this is the QH that we are looking for */ + + if (qh->epinfo == epinfo) + { + /* No... keep looking */ + + return OK; + } + + /* Disable both the asynchronous and period schedules */ + + regval = sam_getreg(&HCOR->usbcmd); + sam_putreg(regval & ~(EHCI_USBCMD_ASEN | EHCI_USBCMD_PSEN), + &HCOR->usbcmd); + + /* Remove the QH from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qh->hw.hlp; + cp15_flush_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Re-enable the schedules (if they were enabled before. */ + + sam_putreg(regval, &HCOR->usbcmd); + + /* Remove all active, attached qTD structures from the removed QH */ + + ret = sam_qtd_foreach(qh, sam_qtd_cancel, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then release this QH by returning it to the free list. Return 1 + * to stop the traverse without an error. + */ + + sam_qh_free(qh); + return 1; +} + +/**************************************************************************** + * Name: sam_ioc_bottomhalf + * + * Description: + * EHCI USB Interrupt (USBINT) "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor that + * had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is detected + * (actual number of bytes received was less than the expected number of + * bytes)." + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static inline void sam_ioc_bottomhalf(void) +{ + struct sam_qh_s *qh; + uint32_t *bp; + int ret; + + /* Check the Asynchronous Queue */ + /* Make sure that the head of the asynchronous queue is invalidated */ + + arch_invalidate_dcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward QH pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct sam_qh_s *)sam_virtramaddr(sam_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in the + * asynchronous queue head will point back to the the queue head. + */ + + if (qh && qh != &g_asynchead) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue + */ + + ret = sam_qh_foreach(qh, &bp, sam_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Check the Interrupt Queue */ + /* Make sure that the head of the interrupt queue is invalidated */ + + arch_invalidate_dcache((uintptr_t)&g_intrhead.hw, + (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward qTD pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct sam_qh_s *)sam_virtramaddr(sam_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue. + */ + + ret = sam_qh_foreach(qh, &bp, sam_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } +#endif +} + +/**************************************************************************** + * Name: sam_portsc_bottomhalf + * + * Description: + * EHCI Port Change Detect "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to a one when any port for which the Port + * Owner bit is set to zero ... has a change bit transition from a zero to a + * one or a Force Port Resume bit transition from a zero to a one as a result + * of a J-K transition detected on a suspended port. This bit will also be set + * as a result of the Connect Status Change being set to a one after system + * software has relinquished ownership of a connected port by writing a one + * to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition of the + * EHCI HC device, this bit is loaded with the OR of all of the PORTSC change + * bits (including: Force port resume, over-current change, enable/disable + * change and connect status change)." + * + ****************************************************************************/ + +static inline void sam_portsc_bottomhalf(void) +{ + struct sam_rhport_s *rhport; + struct usbhost_hubport_s *hport; + uint32_t portsc; + int rhpndx; + + /* Handle root hub status change on each root port */ + + for (rhpndx = 0; rhpndx < SAM_EHCI_NRHPORT; rhpndx++) + { + rhport = &g_ehci.rhport[rhpndx]; + portsc = sam_getreg(&HCOR->portsc[rhpndx]); + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc); + + /* Handle port connection status change (CSC) events */ + + if ((portsc & EHCI_PORTSC_CSC) != 0) + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CSC, portsc); + + /* Check current connect status */ + + if ((portsc & EHCI_PORTSC_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!rhport->connected) + { + /* Yes.. connected. */ + + rhport->connected = true; + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_CONNECTED, + rhpndx + 1, g_ehci.pscwait); + + /* Notify any waiters */ + + if (g_ehci.pscwait) + { + sam_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CONNALREADY, portsc); + } + } + else + { + /* Disconnected... Did we just become disconnected? */ + + if (rhport->connected) + { + /* Yes.. disconnect the device */ + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_DISCONND, + rhpndx+1, g_ehci.pscwait); + + rhport->connected = false; + + /* Are we bound to a class instance? */ + + hport = &rhport->hport.hport; + if (hport->devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(hport->devclass); + hport->devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change + * event. + */ + + if (g_ehci.pscwait) + { + sam_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_DISCALREADY, portsc); + } + } + } + + /* Clear all pending port interrupt sources by writing a '1' to the + * corresponding bit in the PORTSC register. In addition, we need + * to preserve the values of all R/W bits (RO bits don't matter) + */ + + sam_putreg(portsc, &HCOR->portsc[rhpndx]); + } +} + +/**************************************************************************** + * Name: sam_syserr_bottomhalf + * + * Description: + * EHCI Host System Error "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 when a serious error occurs during a + * host system access involving the Host Controller module. ... When this + * error occurs, the Host Controller clears the Run/Stop bit in the Command + * register to prevent further execution of the scheduled TDs." + * + ****************************************************************************/ + +static inline void sam_syserr_bottomhalf(void) +{ + usbhost_trace1(EHCI_TRACE1_SYSERR_INTR, 0); + PANIC(); +} + +/**************************************************************************** + * Name: sam_async_advance_bottomhalf + * + * Description: + * EHCI Async Advance "Bottom Half" interrupt handler + * + * "System software can force the host controller to issue an interrupt the + * next time the host controller advances the asynchronous schedule by writing + * a one to the Interrupt on Async Advance Doorbell bit in the USBCMD + * register. This status bit indicates the assertion of that interrupt + * source." + * + ****************************************************************************/ + +static inline void sam_async_advance_bottomhalf(void) +{ + usbhost_vtrace1(EHCI_VTRACE1_AAINTR, 0); + + /* REVISIT: Could remove all tagged QH entries here */ +} + +/**************************************************************************** + * Name: sam_ehci_bottomhalf + * + * Description: + * EHCI "Bottom Half" interrupt handler + * + ****************************************************************************/ + +static void sam_ehci_bottomhalf(FAR void *arg) +{ + uint32_t pending = (uint32_t)arg; + + /* We need to have exclusive access to the EHCI data structures. Waiting here + * is not a good thing to do on the worker thread, but there is no real option + * (other than to reschedule and delay). + */ + + sam_takesem(&g_ehci.exclsem); + + /* Handle all unmasked interrupt sources */ + /* USB Interrupt (USBINT) + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * USB Error Interrupt (USBERRINT) + * + * "The Host Controller sets this bit to 1 when completion of a USB + * transaction results in an error condition (e.g., error counter + * underflow). If the TD on which the error interrupt occurred also + * had its IOC bit set, both this bit and USBINT bit are set. ..." + * + * We do the same thing in either case: Traverse the asynchonous queue + * and remove all of the transfers that are no longer active. + */ + + if ((pending & (EHCI_INT_USBINT | EHCI_INT_USBERRINT)) != 0) + { + if ((pending & EHCI_INT_USBERRINT) != 0) + { + usbhost_trace1(EHCI_TRACE1_USBERR_INTR, pending); + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending); + } + + sam_ioc_bottomhalf(); + } + + /* Port Change Detect + * + * "The Host Controller sets this bit to a one when any port for which + * the Port Owner bit is set to zero ... has a change bit transition + * from a zero to a one or a Force Port Resume bit transition from a zero + * to a one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership + * of a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition + * of the EHCI HC device, this bit is loaded with the OR of all of the + * PORTSC change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + */ + + if ((pending & EHCI_INT_PORTSC) != 0) + { + sam_portsc_bottomhalf(); + } + + /* Frame List Rollover + * + * "The Host Controller sets this bit to a one when the Frame List Index ... + * rolls over from its maximum value to zero. The exact value at which + * the rollover occurs depends on the frame list size. For example, if + * the frame list size (as programmed in the Frame List Size field of the + * USBCMD register) is 1024, the Frame Index Register rolls over every + * time FRINDEX[13] toggles. Similarly, if the size is 512, the Host + * Controller sets this bit to a one every time FRINDEX[12] toggles." + */ + +#if 0 /* Not used */ + if ((pending & EHCI_INT_FLROLL) != 0) + { + sam_flroll_bottomhalf(); + } +#endif + + /* Host System Error + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit + * in the Command register to prevent further execution of the scheduled + * TDs." + */ + + if ((pending & EHCI_INT_SYSERROR) != 0) + { + sam_syserr_bottomhalf(); + } + + /* Interrupt on Async Advance + * + * "System software can force the host controller to issue an interrupt + * the next time the host controller advances the asynchronous schedule + * by writing a one to the Interrupt on Async Advance Doorbell bit in + * the USBCMD register. This status bit indicates the assertion of that + * interrupt source." + */ + + if ((pending & EHCI_INT_AAINT) != 0) + { + sam_async_advance_bottomhalf(); + } + + /* We are done with the EHCI structures */ + + sam_givesem(&g_ehci.exclsem); + + /* Re-enable relevant EHCI interrupts. Interrupts should still be enabled + * at the level of the AIC. + */ + + sam_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); +} + +/**************************************************************************** + * Name: sam_ehci_tophalf + * + * Description: + * EHCI "Top Half" interrupt handler + * + ****************************************************************************/ + +static int sam_ehci_tophalf(int irq, FAR void *context) +{ + uint32_t usbsts; + uint32_t pending; + uint32_t regval; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + usbsts = sam_getreg(&HCOR->usbsts); + regval = sam_getreg(&HCOR->usbintr); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(EHCI_VTRACE1_TOPHALF, usbsts & regval); +#else + ullvdbg("USBSTS: %08x USBINTR: %08x\n", usbsts, regval); +#endif + + /* Handle all unmasked interrupt sources */ + + pending = usbsts & regval; + if (pending != 0) + { + /* Schedule interrupt handling work for the high priority worker thread + * so that we are not pressed for time and so that we can interrupt with + * other USB threads gracefully. + * + * The worker should be available now because we implement a handshake + * by controlling the EHCI interrupts. + */ + + DEBUGASSERT(work_available(&g_ehci.work)); + DEBUGVERIFY(work_queue(HPWORK, &g_ehci.work, sam_ehci_bottomhalf, + (FAR void *)pending, 0)); + + /* Disable further EHCI interrupts so that we do not overrun the work + * queue. + */ + + sam_putreg(0, &HCOR->usbintr); + + /* Clear all pending status bits by writing the value of the pending + * interrupt bits back to the status register. + */ + + sam_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR->usbsts); + } + + return OK; +} + +/**************************************************************************** + * Name: sam_uhphs_interrupt + * + * Description: + * Common UHPHS interrupt handler. When both OHCI and EHCI are enabled, EHCI + * owns the interrupt and provides the interrupting event to both the OHCI and + * EHCI controllers. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI +static int sam_uhphs_interrupt(int irq, FAR void *context) +{ + int ohci; + int ehci; + + /* Provide the interrupting event to both the EHCI and OHCI top half */ + + ohci = sam_ohci_tophalf(irq, context); + ehci = sam_ehci_tophalf(irq, context); + + /* Return OK only if both handlers returned OK */ + + return ohci == OK ? ehci : ohci; +} +#endif + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + irqstate_t flags; + int rhpndx; + + /* Loop until a change in the connection state changes on one of the root hub + * ports or until an error occurs. + */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < SAM_EHCI_NRHPORT; rhpndx++) + { + struct sam_rhport_s *rhport; + struct usbhost_hubport_s *connport; + + /* Has the connection state changed on the RH port? */ + + rhport = &g_ehci.rhport[rhpndx]; + connport = &rhport->hport.hport; + if (rhport->connected != connport->connected) + { + /* Yes.. Return the RH port to inform the caller which + * port has the connection change. + */ + + connport->connected = rhport->connected; + *hport = connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + rhpndx + 1, rhport->connected); + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (g_ehci.hport) + { + volatile struct usbhost_hubport_s *connport; + + /* Yes.. return the external hub port */ + + connport = g_ehci.hport; + g_ehci.hport = NULL; + + *hport = (struct usbhost_hubport_s *)connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + connport->port + 1, connport->connected); + return OK; + } +#endif + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + + g_ehci.pscwait = true; + sam_takesem(&g_ehci.pscsem); + } +} + +/**************************************************************************** + * Name: sam_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + struct sam_rhport_s *rhport; + volatile uint32_t *regaddr; + uint32_t regval; + int rhpndx; + + DEBUGASSERT(conn != NULL && hport != NULL); + rhpndx = hport->port; + + DEBUGASSERT(rhpndx >= 0 && rhpndx < SAM_EHCI_NRHPORT); + rhport = &g_ehci.rhport[rhpndx]; + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!rhport->connected) + { + /* No, return an error */ + + usbhost_vtrace1(EHCI_VTRACE1_ENUM_DISCONN, 0); + return -ENODEV; + } + + /* USB 2.0 spec says at least 50ms delay before port reset. + * REVISIT: I think this is wrong. It needs to hold the port in + * reset for 50Msec, not wait 50Msec before resetting. + */ + + usleep(100*1000); + + /* Paragraph 2.3.9: + * + * "Line Status ... These bits reflect the current logical levels of the + * D+ (bit 11) and D- (bit 10) signal lines. These bits are used for + * detection of low-speed USB devices prior to the port reset and enable + * sequence. This field is valid only when the port enable bit is zero + * and the current connect status bit is set to a one." + * + * Bits[11:10] USB State Interpretation + * ----------- --------- -------------- + * 00b SE0 Not Low-speed device, perform EHCI reset + * 10b J-state Not Low-speed device, perform EHCI reset + * 01b K-state Low-speed device, release ownership of port + */ + + regval = sam_getreg(&HCOR->portsc[rhpndx]); + if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE) + { + /* Paragraph 2.3.9: + * + * "Port Owner ... This bit unconditionally goes to a 0b when the + * Configured bit in the CONFIGFLAG register makes a 0b to 1b + * transition. This bit unconditionally goes to 1b whenever the + * Configured bit is zero. + * + * "System software uses this field to release ownership of the + * port to a selected host controller (in the event that the + * attached device is not a high-speed device). Software writes + * a one to this bit when the attached device is not a high-speed + * device. A one in this bit means that a companion host + * controller owns and controls the port. .... + * + * Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + hport->speed = USB_SPEED_LOW; + regval |= EHCI_PORTSC_OWNER; + sam_putreg(regval, &HCOR->portsc[rhpndx]); + +#if 0 /* #ifdef CONFIG_SAMA5_OHCI */ + /* Give the port to the OHCI controller. Zero is the reset value for + * all ports; one makes the corresponding port available to OHCI. + */ + + regval = getreg32(SAM_SFR_OHCIICR); + regval |= SFR_OHCIICR_RES(rhpndx); + putreg32(regval, SAM_SFR_OHCIICR); +#endif + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; + } + else + { + /* Assume full-speed for now */ + + hport->speed = USB_SPEED_FULL; + } + + /* Put the root hub port in reset. + * + * Paragraph 2.3.9: + * + * "The HCHalted bit in the USBSTS register should be a zero before + * software attempts to use [the Port Reset] bit. The host controller + * may hold Port Reset asserted to a one when the HCHalted bit is a one. + */ + + DEBUGASSERT((sam_getreg(&HCOR->usbsts) & EHCI_USBSTS_HALTED) == 0); + + /* paragraph 2.3.9: + * + * "When software writes a one to [the Port Reset] bit (from a zero), the + * bus reset sequence as defined in the USB Specification Revision 2.0 is + * started. Software writes a zero to this bit to terminate the bus reset + * sequence. Software must keep this bit at a one long enough to ensure + * the reset sequence, as specified in the USB Specification Revision 2.0, + * completes. Note: when software writes this bit to a one, it must also + * write a zero to the Port Enable bit." + */ + + regaddr = &HCOR->portsc[RHPNDX(rhport)]; + regval = sam_getreg(regaddr); + regval &= ~EHCI_PORTSC_PE; + regval |= EHCI_PORTSC_RESET; + sam_putreg(regval, regaddr); + + /* USB 2.0 "Root hubs must provide an aggregate reset period of at least + * 50 ms." + */ + + usleep(50*1000); + + regval = sam_getreg(regaddr); + regval &= ~EHCI_PORTSC_RESET; + sam_putreg(regval, regaddr); + + /* Wait for the port reset to complete + * + * Paragraph 2.3.9: + * + * "Note that when software writes a zero to this bit there may be a + * delay before the bit status changes to a zero. The bit status will + * not read as a zero until after the reset has completed. If the port + * is in high-speed mode after reset is complete, the host controller + * will automatically enable this port (e.g. set the Port Enable bit + * to a one). A host controller must terminate the reset and stabilize + * the state of the port within 2 milliseconds of software transitioning + * this bit from a one to a zero ..." + */ + + while ((sam_getreg(regaddr) & EHCI_PORTSC_RESET) != 0); + usleep(200*1000); + + /* Paragraph 4.2.2: + * + * "... The reset process is actually complete when software reads a zero + * in the PortReset bit. The EHCI Driver checks the PortEnable bit in the + * PORTSC register. If set to a one, the connected device is a high-speed + * device and EHCI Driver (root hub emulator) issues a change report to the + * hub driver and the hub driver continues to enumerate the attached device." + * + * "At the time the EHCI Driver receives the port reset and enable request + * the LineStatus bits might indicate a low-speed device. Additionally, + * when the port reset process is complete, the PortEnable field may + * indicate that a full-speed device is attached. In either case the EHCI + * driver sets the PortOwner bit in the PORTSC register to a one to + * release port ownership to a companion host controller." + */ + + regval = sam_getreg(&HCOR->portsc[rhpndx]); + if ((regval & EHCI_PORTSC_PE) != 0) + { + /* High speed device */ + + hport->speed = USB_SPEED_HIGH; + } + else + { + /* Low- or Full- speed device. Set the port ownership bit. + * + * Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + regval |= EHCI_PORTSC_OWNER; + sam_putreg(regval, &HCOR->portsc[rhpndx]); + +#if 0 /* #ifdef CONFIG_SAMA5_OHCI */ + /* Give the port to the OHCI controller. Zero is the reset value for + * all ports; one makes the corresponding port available to OHCI. + */ + + regval = getreg32(SAM_SFR_OHCIICR); + regval |= SFR_OHCIICR_RES(rhpndx); + putreg32(regval, SAM_SFR_OHCIICR); +#endif + + /* And return a failure */ + + rhport->connected = false; + return -EPERM; + } + + return OK; +} + +static int sam_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + int ret; + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + + DEBUGASSERT(hport); +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = sam_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + usbhost_vtrace1(EHCI_VTRACE1_CLASSENUM, hport->port); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + /* Failed to enumerate */ + + usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, hport->port + 1, -ret); + + /* If this is a root hub port, then marking the hub port not connected will + * cause sam_wait() to return and we will try the connection again. + */ + + hport->connected = false; + } + + return ret; +} + +/************************************************************************************ + * Name: sam_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls. A funcaddr of zero will be received if no address is yet assigned + * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) +{ + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep0; + + usbhost_vtrace2(EHCI_VTRACE2_EP0CONFIG, speed, funcaddr); + DEBUGASSERT(drvr != NULL && epinfo != NULL && maxpacketsize < 2048); + + /* We must have exclusive access to the EHCI data structures. */ + + sam_takesem(&g_ehci.exclsem); + + /* Remember the new device address and max packet size */ + + epinfo->devaddr = funcaddr; + epinfo->speed = speed; + epinfo->maxpacket = maxpacketsize; + + sam_givesem(&g_ehci.exclsem); + return OK; +} + +/************************************************************************************ + * Name: sam_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep) +{ + struct sam_epinfo_s *epinfo; + struct usbhost_hubport_s *hport; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && epdesc->hport != NULL && ep != NULL); + hport = epdesc->hport; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_EPALLOC, epdesc->addr, epdesc->xfrtype); +#else + uvdbg("EP%d DIR=%s FA=%08x TYPE=%d Interval=%d MaxPacket=%d\n", + epdesc->addr, epdesc->in ? "IN" : "OUT", hport->funcaddr, + epdesc->xfrtype, epdesc->interval, epdesc->mxpacketsize); +#endif + + /* Allocate a endpoint information structure */ + + epinfo = (struct sam_epinfo_s *)kmm_zalloc(sizeof(struct sam_epinfo_s)); + if (!epinfo) + { + usbhost_trace1(EHCI_TRACE1_EPALLOC_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the endpoint container (which is really just another form of + * 'struct usbhost_epdesc_s', packed differently and with additional + * information. A cleaner design might just embed struct usbhost_epdesc_s + * inside of struct sam_epinfo_s and just memcpy here. + */ + + epinfo->epno = epdesc->addr; + epinfo->dirin = epdesc->in; + epinfo->devaddr = hport->funcaddr; +#ifndef CONFIG_USBHOST_INT_DISABLE + epinfo->interval = epdesc->interval; +#endif + epinfo->maxpacket = epdesc->mxpacketsize; + epinfo->xfrtype = epdesc->xfrtype; + epinfo->speed = hport->speed; + sem_init(&epinfo->iocsem, 0, 0); + + /* Success.. return an opaque reference to the endpoint information structure + * instance + */ + + *ep = (usbhost_ep_t)epinfo; + return OK; +} + +/************************************************************************************ + * Name: sam_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep; + + /* There should not be any pending, transfers */ + + DEBUGASSERT(drvr && epinfo && epinfo->iocwait == 0); + + /* Free the container */ + + kmm_free(epinfo); + return OK; +} + +/**************************************************************************** + * Name: sam_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * allocate the request/descriptor memory. If the underlying hardware does + * not support such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was + * assumed that the driver maintains a pool of small, pre-allocated buffers + * for descriptor traffic. NOTE that size is not an input, but an output: + * The size of the pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of a memory location provided by the caller in which + * to return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which + * to return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + int ret = -ENOMEM; + DEBUGASSERT(drvr && buffer && maxlen); + + /* The only special requirements for transfer/descriptor buffers are that (1) + * they be aligned to a cache line boundary and (2) they are a multiple of the + * cache line size in length. + */ + + *buffer = (FAR uint8_t *)kmm_memalign(ARMV7A_DCACHE_LINESIZE, SAMA5_EHCI_BUFSIZE); + if (*buffer) + { + *maxlen = SAMA5_EHCI_BUFSIZE; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * free that request/descriptor memory. If the underlying hardware does not + * support such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the transfer/descriptor buffer memory */ + + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: sam_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kumm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_ioalloc(FAR struct usbhost_driver_s *drvr, FAR uint8_t **buffer, + size_t buflen) +{ + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* The only special requirements for I/O buffers are that (1) they be aligned to a + * cache line boundary, (2) they are a multiple of the cache line size in length, + * and (3) they might need to be user accessible (depending on how the class driver + * implements its buffering). + */ + + buflen = (buflen + DCACHE_LINEMASK) & ~DCACHE_LINEMASK; + *buffer = (FAR uint8_t *)kumm_memalign(ARMV7A_DCACHE_LINESIZE, buflen); + return *buffer ? OK : -ENOMEM; +} + +/************************************************************************************ + * Name: sam_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kumm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the I/O buffer memory */ + + kumm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: sam_ctrlin and sam_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_epinfo_s *ep0info = (struct sam_epinfo_s *)ep0; + uint16_t len; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport != NULL && ep0info != NULL && req != NULL); + + len = sam_read16(req->len); + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, RHPORT(rhport), req->req); +#else + uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %04x\n", + RHPORT(rhport), req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], len); +#endif + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + sam_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = sam_ioc_setup(rhport, ep0info); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Now initiate the transfer */ + + ret = sam_async_setup(rhport, ep0info, req, buffer, len); + if (ret < 0) + { + udbg("ERROR: sam_async_setup failed: %d\n", ret); + goto errout_with_iocwait; + } + + /* And wait for the transfer to complete */ + + nbytes = sam_transfer_wait(ep0info); + sam_givesem(&g_ehci.exclsem); + return nbytes >= 0 ? OK : (int)nbytes; + +errout_with_iocwait: + ep0info->iocwait = false; +errout_with_sem: + sam_givesem(&g_ehci.exclsem); + return ret; +} + +static int sam_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + /* sam_ctrlin can handle both directions. We just need to work around the + * differences in the function signatures. + */ + + return sam_ctrlin(drvr, ep0, req, (uint8_t *)buffer); +} + +/**************************************************************************** + * Name: sam_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + sam_takesem(&g_ehci.exclsem); + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = sam_ioc_setup(rhport, epinfo); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = sam_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = sam_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + udbg("ERROR: Transfer setup failed: %d\n", ret); + goto errout_with_iocwait; + } + + /* Then wait for the transfer to complete */ + + nbytes = sam_transfer_wait(epinfo); + sam_givesem(&g_ehci.exclsem); + return nbytes; + +errout_with_iocwait: + epinfo->iocwait = false; +errout_with_sem: + sam_givesem(&g_ehci.exclsem); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: sam_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int sam_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data structures. */ + + sam_takesem(&g_ehci.exclsem); + + /* Set the request for the callback well BEFORE initiating the transfer. */ + + ret = sam_ioc_async_setup(rhport, epinfo, callback, arg); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = sam_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = sam_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_callback; + } + + /* The transfer is in progress */ + + sam_givesem(&g_ehci.exclsem); + return OK; + +errout_with_callback: + epinfo->callback = NULL; + epinfo->arg = NULL; +errout_with_sem: + sam_givesem(&g_ehci.exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: sam_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep; + struct sam_qh_s *qh; +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; + void *arg; +#endif + uint32_t *bp; + irqstate_t flags; + bool iocwait; + int ret; + + DEBUGASSERT(epinfo); + + /* We must have exclusive access to the EHCI hardware and data structures. This + * will prevent servicing any transfer completion events while we perform the + * the cancellation, but will not prevent DMA-related race conditions. + * + * REVISIT: This won't work. This function must be callable from the interrupt + * level. + */ + + sam_takesem(&g_ehci.exclsem); + + /* Sample and reset all transfer termination information. This will prevent any + * callbacks from occurring while are performing the cancellation. The transfer + * may still be in progress, however, so this does not eliminate other DMA- + * related race conditions. + */ + + flags = enter_critical_section(); +#ifdef CONFIG_USBHOST_ASYNCH + callback = epinfo->callback; + arg = epinfo->arg; +#endif + iocwait = epinfo->iocwait; + +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; + epinfo->arg = NULL; +#endif + epinfo->iocwait = false; + leave_critical_section(flags); + + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + + /* Handle the cancellation according to the type of the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + case USB_EP_ATTR_XFER_BULK: + { + /* Get the horizontal pointer from the head of the asynchronous + * queue. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct sam_qh_s *)sam_virtramaddr(sam_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in + * the asynchronous queue head will point back to the the queue + * head. + */ + + if (qh && qh != &g_asynchead) + { + /* Claim that we successfully cancelled the transfer */ + + ret = OK; + goto exit_terminate; + } + } + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + { + /* Get the horizontal pointer from the head of the interrupt + * queue. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct sam_qh_s *)sam_virtramaddr(sam_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* if the queue is empty, then just claim that we successfully + * cancelled the transfer. + */ + + ret = OK; + goto exit_terminate; + } + } + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + goto errout_with_sem; + } + + /* Find and remove the QH. There are four possibilities: + * + * 1) The transfer has already completed and the QH is no longer in the list. In + * this case, sam_hq_foreach will return zero + * 2a) The transfer is not active and still pending. It was removed from the list + * and sam_hq_foreach will return one. + * 2b) The is active but not yet complete. This is currently handled the same as + * 2a). REVISIT: This needs to be fixed. + * 3) Some bad happened and sam_hq_foreach returned an error code < 0. + */ + + ret = sam_qh_foreach(qh, &bp, sam_qh_cancel, epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Was there a pending synchronous transfer? */ + +exit_terminate: + epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH + if (iocwait) + { + /* Yes... wake it up */ + + DEBUGASSERT(callback == NULL); + sam_givesem(&epinfo->iocsem); + } + + /* No.. Is there a pending asynchronous transfer? */ + + else /* if (callback != NULL) */ + { + /* Yes.. perform the callback */ + + callback(arg, -ESHUTDOWN); + } + +#else + /* Wake up the waiting thread */ + + sam_givesem(&epinfo->iocsem); +#endif + +errout_with_sem: + sam_givesem(&g_ehci.exclsem); + return ret; +} + +/************************************************************************************ + * Name: sam_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int sam_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */ + + g_ehci.hport = hport; + if (g_ehci.pscwait) + { + g_ehci.pscwait = false; + sam_givesem(&g_ehci.pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void sam_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: sam_reset + * + * Description: + * Set the HCRESET bit in the USBCMD register to reset the EHCI hardware. + * + * Table 2-9. USBCMD - USB Command Register Bit Definitions + * + * "Host Controller Reset (HCRESET) ... This control bit is used by software + * to reset the host controller. The effects of this on Root Hub registers + * are similar to a Chip Hardware Reset. + * + * "When software writes a one to this bit, the Host Controller resets its + * internal pipelines, timers, counters, state machines, etc. to their + * initial value. Any transaction currently in progress on USB is + * immediately terminated. A USB reset is not driven on downstream + * ports. + * + * "PCI Configuration registers are not affected by this reset. All + * operational registers, including port registers and port state machines + * are set to their initial values. Port ownership reverts to the companion + * host controller(s)... Software must reinitialize the host controller ... + * in order to return the host controller to an operational state. + * + * "This bit is set to zero by the Host Controller when the reset process is + * complete. Software cannot terminate the reset process early by writing a + * zero to this register. Software should not set this bit to a one when + * the HCHalted bit in the USBSTS register is a zero. Attempting to reset + * an actively running host controller will result in undefined behavior." + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + * Assumptions: + * - Called during the initialization of the EHCI. + * + ****************************************************************************/ + +static int sam_reset(void) +{ + uint32_t regval; + unsigned int timeout; + + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to 0, + * the Host Controller completes the current transaction on the USB and then + * halts. The HC Halted bit in the status register indicates when the Hos + * Controller has finished the transaction and has entered the stopped state..." + */ + + sam_putreg(0, &HCOR->usbcmd); + + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in + * the USBSTS register is a zero. Attempting to reset an actively running + * host controller will result in undefined behavior." + */ + + timeout = 0; + do + { + /* Wait one microsecond and update the timeout counter */ + + up_udelay(1); + timeout++; + + /* Get the current value of the USBSTS register. This loop will terminate + * when either the timeout exceeds one millisecond or when the HCHalted + * bit is no longer set in the USBSTS register. + */ + + regval = sam_getreg(&HCOR->usbsts); + } + while (((regval & EHCI_USBSTS_HALTED) == 0) && (timeout < 1000)); + + /* Is the EHCI still running? Did we timeout? */ + + if ((regval & EHCI_USBSTS_HALTED) == 0) + { + usbhost_trace1(EHCI_TRACE1_HCHALTED_TIMEOUT, regval); + return -ETIMEDOUT; + } + + /* Now we can set the HCReset bit in the USBCMD register to initiate the reset */ + + regval = sam_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_HCRESET; + sam_putreg(regval, &HCOR->usbcmd); + + /* Wait for the HCReset bit to become clear */ + + do + { + /* Wait five microsecondw and update the timeout counter */ + + up_udelay(5); + timeout += 5; + + /* Get the current value of the USBCMD register. This loop will terminate + * when either the timeout exceeds one second or when the HCReset + * bit is no longer set in the USBSTS register. + */ + + regval = sam_getreg(&HCOR->usbcmd); + } + while (((regval & EHCI_USBCMD_HCRESET) != 0) && (timeout < 1000000)); + + /* Return either success or a timeout */ + + return (regval & EHCI_USBCMD_HCRESET) != 0 ? -ETIMEDOUT : OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *sam_ehci_initialize(int controller) +{ + FAR struct usbhost_hubport_s *hport; + irqstate_t flags; + uint32_t regval; +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + uint16_t regval16; + unsigned int nports; +#endif + uintptr_t physaddr; + int ret; + int i; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(((uintptr_t)&g_asynchead & 0x1f) == 0); + DEBUGASSERT((sizeof(struct sam_qh_s) & 0x1f) == 0); + DEBUGASSERT((sizeof(struct sam_qtd_s) & 0x1f) == 0); + +#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0); + DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0); +#endif + +#ifndef CONFIG_USBHOST_INT_DISABLE + DEBUGASSERT(((uintptr_t)&g_intrhead & 0x1f) == 0); +#ifdef CONFIG_SAMA5_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t)g_framelist & 0xfff) == 0); +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + + /* SAMA5 Configuration *******************************************************/ + /* For High-speed operations, the user has to perform the following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in + * PMC_PCER register. + * 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. + * 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. + * 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register + * 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. + * 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is + * selected. + * 8) Enable OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 1 and 8 are performed here. Steps 2 through 7 were are performed + * by sam_clockconfig() earlier in the boot sequence. + */ + + /* Enable UHP peripheral clocking */ + + flags = enter_critical_section(); + sam_uhphs_enableclk(); + + /* Enable OHCI clocks */ + + regval = sam_getreg((volatile uint32_t *)SAM_PMC_SCER); + regval |= PMC_UHP; + sam_putreg(regval, (volatile uint32_t *)SAM_PMC_SCER); + + /* "One transceiver is shared with the USB High Speed Device (port A). The + * selection between Host Port A and USB Device is controlled by the UDPHS + * enable bit (EN_UDPHS) located in the UDPHS_CTRL control register." + * + * Make all three ports usable for EHCI unless the high speed device is + * enabled; then let the device manage port zero. Zero is the reset + * value for all ports; one makes the corresponding port available to OHCI. + */ + + regval = getreg32(SAM_SFR_OHCIICR); +#ifdef CONFIG_SAMA5_UHPHS_RHPORT1 + regval &= ~SFR_OHCIICR_RES0; +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT2 + regval &= ~SFR_OHCIICR_RES1; +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT3 + regval &= ~SFR_OHCIICR_RES2; +#endif + putreg32(regval, SAM_SFR_OHCIICR); + leave_critical_section(flags); + + /* Note that no pin configuration is required. All USB HS pins have + * dedicated function + */ + + /* Software Configuration ****************************************************/ + + usbhost_vtrace1(EHCI_VTRACE1_INITIALIZING, 0); + + /* Initialize the EHCI state data structure */ + + sem_init(&g_ehci.exclsem, 0, 1); + sem_init(&g_ehci.pscsem, 0, 0); + + /* Initialize EP0 */ + + sem_init(&g_ehci.ep0.iocsem, 0, 1); + + /* Initialize the root hub port structures */ + + for (i = 0; i < SAM_EHCI_NRHPORT; i++) + { + struct sam_rhport_s *rhport = &g_ehci.rhport[i]; + + /* Initialize the device operations */ + + rhport->drvr.ep0configure = sam_ep0configure; + rhport->drvr.epalloc = sam_epalloc; + rhport->drvr.epfree = sam_epfree; + rhport->drvr.alloc = sam_alloc; + rhport->drvr.free = sam_free; + rhport->drvr.ioalloc = sam_ioalloc; + rhport->drvr.iofree = sam_iofree; + rhport->drvr.ctrlin = sam_ctrlin; + rhport->drvr.ctrlout = sam_ctrlout; + rhport->drvr.transfer = sam_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + rhport->drvr.asynch = sam_asynch; +#endif + rhport->drvr.cancel = sam_cancel; +#ifdef CONFIG_USBHOST_HUB + rhport->drvr.connect = sam_connect; +#endif + rhport->drvr.disconnect = sam_disconnect; + + /* Initialize EP0 */ + + rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; + rhport->ep0.speed = USB_SPEED_FULL; + rhport->ep0.maxpacket = 8; + sem_init(&rhport->ep0.iocsem, 0, 0); + + /* Initialize the public port representation */ + + hport = &rhport->hport.hport; + hport->drvr = &rhport->drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = &rhport->ep0; + hport->port = i; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&rhport->hport); + } + +#ifndef CONFIG_SAMA5_EHCI_PREALLOCATE + /* Allocate a pool of free Queue Head (QH) structures */ + + g_qhpool = (struct sam_qh_s *) + kmm_memalign(32, CONFIG_SAMA5_EHCI_NQHS * sizeof(struct sam_qh_s)); + if (!g_qhpool) + { + usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0); + return NULL; + } +#endif + + /* Initialize the list of free Queue Head (QH) structures */ + + for (i = 0; i < CONFIG_SAMA5_EHCI_NQHS; i++) + { + /* Put the QH structure in a free list */ + + sam_qh_free(&g_qhpool[i]); + } + +#ifndef CONFIG_SAMA5_EHCI_PREALLOCATE + /* Allocate a pool of free Transfer Descriptor (qTD) structures */ + + g_qtdpool = (struct sam_qtd_s *) + kmm_memalign(32, CONFIG_SAMA5_EHCI_NQTDS * sizeof(struct sam_qtd_s)); + if (!g_qtdpool) + { + usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0); + kmm_free(g_qhpool); + return NULL; + } +#endif + +#if !defined(CONFIG_SAMA5_EHCI_PREALLOCATE) && !defined(CONFIG_USBHOST_INT_DISABLE) + /* Allocate the periodic framelist */ + + g_framelist = (uint32_t *) + kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t)); + if (!g_framelist) + { + usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0); + kmm_free(g_qhpool); + kmm_free(g_qtdpool); + return NULL; + } +#endif + + /* Initialize the list of free Transfer Descriptor (qTD) structures */ + + for (i = 0; i < CONFIG_SAMA5_EHCI_NQTDS; i++) + { + /* Put the TD in a free list */ + + sam_qtd_free(&g_qtdpool[i]); + } + + /* EHCI Hardware Configuration ***********************************************/ + /* Host Controller Initialization. Paragraph 4.1 */ + /* Reset the EHCI hardware */ + + ret = sam_reset(); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); + return NULL; + } + + /* "In order to initialize the host controller, software should perform the + * following steps: + * + * • "Program the CTRLDSSEGMENT register with 4-Gigabyte segment where all + * of the interface data structures are allocated. [64-bit mode] + * • "Write the appropriate value to the USBINTR register to enable the + * appropriate interrupts. + * • "Write the base address of the Periodic Frame List to the PERIODICLIST + * BASE register. If there are no work items in the periodic schedule, + * all elements of the Periodic Frame List should have their T-Bits set + * to a one. + * • "Write the USBCMD register to set the desired interrupt threshold, + * frame list size (if applicable) and turn the host controller ON via + * setting the Run/Stop bit. + * • Write a 1 to CONFIGFLAG register to route all ports to the EHCI controller + * ... + * + * "At this point, the host controller is up and running and the port registers + * will begin reporting device connects, etc. System software can enumerate a + * port through the reset process (where the port is in the enabled state). At + * this point, the port is active with SOFs occurring down the enabled por + * enabled Highspeed ports, but the schedules have not yet been enabled. The + * EHCI Host controller will not transmit SOFs to enabled Full- or Low-speed + * ports. + */ + + /* Disable all interrupts */ + + sam_putreg(0, &HCOR->usbintr); + + /* Clear pending interrupts. Bits in the USBSTS register are cleared by + * writing a '1' to the corresponding bit. + */ + + sam_putreg(EHCI_INT_ALLINTS, &HCOR->usbsts); + +#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE) + /* Show the EHCI version */ + + regval16 = sam_swap16(HCCR->hciversion); + usbhost_vtrace2(EHCI_VTRACE2_HCIVERSION, regval16 >> 8, regval16 & 0xff); + + /* Verify that the correct number of ports is reported */ + + regval = sam_getreg(&HCCR->hcsparams); + nports = (regval & EHCI_HCSPARAMS_NPORTS_MASK) >> EHCI_HCSPARAMS_NPORTS_SHIFT; + + usbhost_vtrace2(EHCI_VTRACE2_HCSPARAMS, nports, regval); + DEBUGASSERT(nports == SAM_EHCI_NRHPORT); + + /* Show the HCCPARAMS register */ + + regval = sam_getreg(&HCCR->hccparams); + usbhost_vtrace1(EHCI_VTRACE1_HCCPARAMS, regval); +#endif + + /* Initialize the head of the asynchronous queue/reclamation list. + * + * "In order to communicate with devices via the asynchronous schedule, + * system software must write the ASYNDLISTADDR register with the address + * of a control or bulk queue head. Software must then enable the + * asynchronous schedule by writing a one to the Asynchronous Schedule + * Enable bit in the USBCMD register. In order to communicate with devices + * via the periodic schedule, system software must enable the periodic + * schedule by writing a one to the Periodic Schedule Enable bit in the + * USBCMD register. Note that the schedules can be turned on before the + * first port is reset (and enabled)." + */ + + memset(&g_asynchead, 0, sizeof(struct sam_qh_s)); + physaddr = sam_physramaddr((uintptr_t)&g_asynchead); + g_asynchead.hw.hlp = sam_swap32(physaddr | QH_HLP_TYP_QH); + g_asynchead.hw.epchar = sam_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL); + g_asynchead.hw.overlay.nqp = sam_swap32(QH_NQP_T); + g_asynchead.hw.overlay.alt = sam_swap32(QH_NQP_T); + g_asynchead.hw.overlay.token = sam_swap32(QH_TOKEN_HALTED); + g_asynchead.fqp = sam_swap32(QTD_NQP_T); + + arch_clean_dcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s)); + + /* Set the Current Asynchronous List Address. */ + + sam_putreg(sam_swap32(physaddr), &HCOR->asynclistaddr); + +#ifndef CONFIG_USBHOST_INT_DISABLE + /* Initialize the head of the periodic list. Since Isochronous + * endpoints are not not yet supported, each element of the + * frame list is initialized to point to the Interrupt Queue + * Head (g_intrhead). + */ + + memset(&g_intrhead, 0, sizeof(struct sam_qh_s)); + g_intrhead.hw.hlp = sam_swap32(QH_HLP_T); + g_intrhead.hw.overlay.nqp = sam_swap32(QH_NQP_T); + g_intrhead.hw.overlay.alt = sam_swap32(QH_NQP_T); + g_intrhead.hw.overlay.token = sam_swap32(QH_TOKEN_HALTED); + g_intrhead.hw.epcaps = sam_swap32(QH_EPCAPS_SSMASK(1)); + + /* Attach the periodic QH to Period Frame List */ + + physaddr = sam_physramaddr((uintptr_t)&g_intrhead); + for (i = 0; i < FRAME_LIST_SIZE; i++) + { + g_framelist[i] = sam_swap32(physaddr) | PFL_TYP_QH; + } + + /* Set the Periodic Frame List Base Address. */ + + arch_clean_dcache((uintptr_t)&g_intrhead.hw, + (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s)); + arch_clean_dcache((uintptr_t)g_framelist, + (uintptr_t)g_framelist + FRAME_LIST_SIZE * sizeof(uint32_t)); + + physaddr = sam_physramaddr((uintptr_t)g_framelist); + sam_putreg(sam_swap32(physaddr), &HCOR->periodiclistbase); +#endif + + /* Enable the asynchronous schedule and, possibly enable the periodic + * schedule and set the frame list size. + */ + + regval = sam_getreg(&HCOR->usbcmd); + regval &= ~(EHCI_USBCMD_HCRESET | EHCI_USBCMD_FLSIZE_MASK | + EHCI_USBCMD_FLSIZE_MASK | EHCI_USBCMD_PSEN | + EHCI_USBCMD_IAADB | EHCI_USBCMD_LRESET); + regval |= EHCI_USBCMD_ASEN; + +#ifndef CONFIG_USBHOST_INT_DISABLE + regval |= EHCI_USBCMD_PSEN; +# if FRAME_LIST_SIZE == 1024 + regval |= EHCI_USBCMD_FLSIZE_1024; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_512; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_256; +# else +# error Unsupported frame size list size +# endif +#endif + + sam_putreg(regval, &HCOR->usbcmd); + + /* Start the host controller by setting the RUN bit in the USBCMD regsiter. */ + + regval = sam_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_RUN; + sam_putreg(regval, &HCOR->usbcmd); + + /* Route all ports to this host controller by setting the CONFIG flag. */ + + regval = sam_getreg(&HCOR->configflag); + regval |= EHCI_CONFIGFLAG; + sam_putreg(regval, &HCOR->configflag); + + /* Wait for the EHCI to run (i.e., no longer report halted) */ + + ret = ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100*1000); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RUN_FAILED, sam_getreg(&HCOR->usbsts)); + return NULL; + } + + /* Interrupt Configuration ***************************************************/ + /* Attach USB host controller interrupt handler. If OHCI is also enabled, + * then we have to use a common UHPHS interrupt handler. + */ + +#ifdef CONFIG_SAMA5_OHCI + ret = irq_attach(SAM_IRQ_UHPHS, sam_uhphs_interrupt); +#else + ret = irq_attach(SAM_IRQ_UHPHS, sam_ehci_tophalf); +#endif + if (ret != 0) + { + usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, SAM_IRQ_UHPHS); + return NULL; + } + + /* Enable EHCI interrupts. Interrupts are still disabled at the level of + * the AIC. + */ + + sam_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); + + /* Drive Vbus +5V (the smoke test) + * + * REVISIT: + * - Should be done elsewhere in OTG mode. + * - Can we postpone enabling VBUS to save power? I think it can be + * done in sam_enumerate() and can probably be disabled when the + * port is disconnected. + * - Some EHCI implementations require setting the power bit in the + * PORTSC register to enable power. + */ + +#ifdef CONFIG_SAMA5_UHPHS_RHPORT1 + sam_usbhost_vbusdrive(SAM_RHPORT1, true); +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT2 + sam_usbhost_vbusdrive(SAM_RHPORT2, true); +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT3 + sam_usbhost_vbusdrive(SAM_RHPORT3, true); +#endif + up_mdelay(50); + + /* If there is a USB device in the slot at power up, then we will not + * get the status change interrupt to signal us that the device is + * connected. We need to set the initial connected state accordingly. + */ + + for (i = 0; i < SAM_EHCI_NRHPORT; i++) + { + g_ehci.rhport[i].connected = + ((sam_getreg(&HCOR->portsc[i]) & EHCI_PORTSC_CCS) != 0); + } + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(SAM_IRQ_UHPHS); /* enable USB interrupt */ + usbhost_vtrace1(EHCI_VTRACE1_INIITIALIZED, 0); + + /* Initialize and return the connection interface */ + + g_ehciconn.wait = sam_wait; + g_ehciconn.enumerate = sam_enumerate; + return &g_ehciconn; +} + +#endif /* CONFIG_SAMA5_EHCI */ diff --git a/arch/arm/src/sama5/sam_emaca.c b/arch/arm/src/sama5/sam_emaca.c new file mode 100644 index 0000000000000000000000000000000000000000..5d3ad03e60beb7ae8b113390ae3ba87dbae656ad --- /dev/null +++ b/arch/arm/src/sama5/sam_emaca.c @@ -0,0 +1,3574 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_emaca.c + * + * 10/100 Base-T Ethernet driver for the SAMA5D3. Denoted as 'A' to + * distinguish it from the SAMA5D4 EMAC driver. + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "chip.h" +#include "chip/sam_pinmap.h" +#include "sam_pio.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_ethernet.h" + +#include + +#if defined(CONFIG_NET) && defined(CONFIG_SAMA5_EMACA) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Number of buffers for RX */ + +#ifndef CONFIG_SAMA5_EMAC_NRXBUFFERS +# define CONFIG_SAMA5_EMAC_NRXBUFFERS 16 +#endif + +/* Number of buffers for TX */ + +#ifndef CONFIG_SAMA5_EMAC_NTXBUFFERS +# define CONFIG_SAMA5_EMAC_NTXBUFFERS 8 +#endif + +#undef CONFIG_SAMA5_EMACA_NBC + +#ifndef CONFIG_SAMA5_EMAC_PHYADDR +# error "CONFIG_SAMA5_EMAC_PHYADDR must be defined in the NuttX configuration" +#endif + +#if !defined(CONFIG_SAMA5_EMAC_MII) && !defined(CONFIG_SAMA5_EMAC_RMII) +# warning "Neither CONFIG_SAMA5_EMAC_MII nor CONFIG_SAMA5_EMAC_RMII defined" +#endif + +#if defined(CONFIG_SAMA5_EMAC_MII) && defined(CONFIG_SAMA5_EMAC_RMII) +# error "Both CONFIG_SAMA5_EMAC_MII and CONFIG_SAMA5_EMAC_RMII defined" +#endif + +#ifdef CONFIG_SAMA5_EMAC_AUTONEG +# ifndef CONFIG_SAMA5_EMAC_PHYSR +# error "CONFIG_SAMA5_EMAC_PHYSR must be defined in the NuttX configuration" +# endif +# ifdef CONFIG_SAMA5_EMAC_PHYSR_ALTCONFIG +# ifndef CONFIG_SAMA5_EMAC_PHYSR_ALTMODE +# error "CONFIG_SAMA5_EMAC_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_10HD +# error "CONFIG_SAMA5_EMAC_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_100HD +# error "CONFIG_SAMA5_EMAC_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_10FD +# error "CONFIG_SAMA5_EMAC_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_100FD +# error "CONFIG_SAMA5_EMAC_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAMA5_EMAC_PHYSR_SPEED +# error "CONFIG_SAMA5_EMAC_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_100MBPS +# error "CONFIG_SAMA5_EMAC_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_MODE +# error "CONFIG_SAMA5_EMAC_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC_PHYSR_FULLDUPLEX +# error "CONFIG_SAMA5_EMAC_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +#endif + +/* PHY definitions */ + +#if defined(SAMA5_EMAC_PHY_DM9161) +# define MII_OUI_MSB 0x0181 +# define MII_OUI_LSB 0x2e +#elif defined(SAMA5_EMAC_PHY_LAN8700) +# define MII_OUI_MSB 0x0007 +# define MII_OUI_LSB 0x30 +#elif defined(SAMA5_EMAC_PHY_KSZ8051) +# define MII_OUI_MSB 0x0022 +# define MII_OUI_LSB 0x05 +#elif defined(SAMA5_EMAC_PHY_KSZ8081) +# define MII_OUI_MSB 0x0022 +# define MII_OUI_LSB 0x05 +#else +# error EMAC PHY unrecognized +#endif + +#ifdef CONFIG_SAMA5_EMAC_PHYSR_ALTCONFIG + +# define PHYSR_MODE(sr) ((sr) & CONFIG_SAMA5_EMAC_PHYSR_ALTMODE) +# define PHYSR_ISMODE(sr,m) (PHYSR_MODE(sr) == (m)) + +# define PHYSR_IS10HDX(sr) PHYSR_ISMODE(sr,CONFIG_SAMA5_EMAC_PHYSR_10HD) +# define PHYSR_IS100HDX(sr) PHYSR_ISMODE(sr,CONFIG_SAMA5_EMAC_PHYSR_100HD) +# define PHYSR_IS10FDX(sr) PHYSR_ISMODE(sr,CONFIG_SAMA5_EMAC_PHYSR_10FD) +# define PHYSR_IS100FDX(sr) PHYSR_ISMODE(sr,CONFIG_SAMA5_EMAC_PHYSR_100FD) + +#else + +# define PHYSR_MODESPEED (CONFIG_PHYSR_MODE | CONFIG_PHYSR_SPEED) +# define PHYSR_10HDX (0) +# define PHYSR_100HDX (CONFIG_PHYSR_100MBPS) +# define PHYSR_10FDX (CONFIG_PHYSR_FULLDUPLEX) +# define PHYSR_100FDX (CONFIG_PHYSR_FULLDUPLEX | CONFIG_PHYSR_100MBPS) + +# define PHYSR_IS10HDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_10HDX) +# define PHYSR_IS100HDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_100HDX) +# define PHYSR_IS10FDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_10FDX) +# define PHYSR_IS100FDX(sr) (((sr) & PHYSR_MODESPEED) == PHYSR_100FDX) + +#endif + +/* EMAC buffer sizes, number of buffers, and number of descriptors. + * + * REVISIT: The CONFIG_NET_MULTIBUFFER might be useful. It might be possible + * to use this option to send and receive messages directly into the DMA + * buffers, saving a copy. There might be complications on the receiving + * side, however, where buffers may wrap and where the size of the received + * frame will typically be smaller than a full packet. + */ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER must not be set +#endif + +#define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ +#define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ + +/* We need at least one more free buffer than transmit buffers */ + +#define SAM_EMAC_NFREEBUFFERS (CONFIG_SAMA5_EMAC_NTXBUFFERS+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_EMACA_REGDEBUG +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define sam_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define SAM_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SAM_TXTIMEOUT (60*CLK_TCK) + +/* PHY read/write delays in loop counts */ + +#define PHY_RETRY_MAX 1000000 + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the EMAC + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The sam_emac_s encapsulates all state information for the EMAC peripheral */ + +struct sam_emac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */ + uint16_t txhead; /* Circular buffer head index */ + uint16_t txtail; /* Circular buffer tail index */ + uint16_t rxndx; /* RX index for current processing RX descriptor */ + + uint8_t *rxbuffer; /* Allocated RX buffers */ + uint8_t *txbuffer; /* Allocated TX buffers */ + struct emac_rxdesc_s *rxdesc; /* Allocated RX descriptors */ + struct emac_txdesc_s *txdesc; /* Allocated TX descriptors */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_EMACA_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The driver state singleton */ + +static struct sam_emac_s g_emac; + +#ifdef CONFIG_SAMA5_EMACA_PREALLOCATE +/* Preallocated data */ +/* TX descriptors list */ + +static struct emac_txdesc_s g_txdesc[CONFIG_SAMA5_EMAC_NTXBUFFERS] + __attribute__((aligned(8))); + +/* RX descriptors list */ + +static struct emac_rxdesc_s g_rxdesc[CONFIG_SAMA5_EMAC_NRXBUFFERS] + __attribute__((aligned(8))); + +/* Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_txbuffer[CONFIG_SAMA5_EMAC_NTXBUFFERS * EMAC_TX_UNITSIZE]; + __attribute__((aligned(8))) + +/* Receive Buffers */ + +static uint8_t g_rxbuffer[CONFIG_SAMA5_EMAC_NRXBUFFERS * EMAC_RX_UNITSIZE] + __attribute__((aligned(8))); + +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_EMACA_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, + uint32_t regval, uintptr_t address); +static uint32_t sam_getreg(struct sam_emac_s *priv, uintptr_t addr); +static void sam_putreg(struct sam_emac_s *priv, uintptr_t addr, uint32_t val); +#else +# define sam_getreg(priv,addr) getreg32(addr) +# define sam_putreg(priv,addr,val) putreg32(val,addr) +#endif + +/* Buffer management */ + +static uint16_t sam_txinuse(struct sam_emac_s *priv); +static uint16_t sam_txfree(struct sam_emac_s *priv); +static int sam_buffer_initialize(struct sam_emac_s *priv); +static void sam_buffer_free(struct sam_emac_s *priv); + +/* Common TX logic */ + +static int sam_transmit(struct sam_emac_s *priv); +static int sam_txpoll(struct net_driver_s *dev); +static void sam_dopoll(struct sam_emac_s *priv); + +/* Interrupt handling */ + +static int sam_recvframe(struct sam_emac_s *priv); +static void sam_receive(struct sam_emac_s *priv); +static void sam_txdone(struct sam_emac_s *priv); +static int sam_emac_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void sam_polltimer(int argc, uint32_t arg, ...); +static void sam_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int sam_ifup(struct net_driver_s *dev); +static int sam_ifdown(struct net_driver_s *dev); +static int sam_txavail(struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac); +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY Initialization */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv); +#else +# define sam_phydump(priv) +#endif + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv); +#endif +static int sam_phywait(struct sam_emac_s *priv); +static int sam_phyreset(struct sam_emac_s *priv); +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr); +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval); +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval); +static int sam_autonegotiate(struct sam_emac_s *priv); +static bool sam_linkup(struct sam_emac_s *priv); +static int sam_phyinit(struct sam_emac_s *priv); + +/* EMAC Initialization */ + +static void sam_txreset(struct sam_emac_s *priv); +static void sam_rxreset(struct sam_emac_s *priv); +static void sam_emac_reset(struct sam_emac_s *priv); +static void sam_macaddress(struct sam_emac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv); +#endif +static int sam_emac_configure(struct sam_emac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMACA_REGDEBUG +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, uint32_t regval, + uintptr_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMACA_REGDEBUG +static uint32_t sam_getreg(struct sam_emac_s *priv, uintptr_t address) +{ + uint32_t regval = getreg32(address); + + if (sam_checkreg(priv, false, regval, address)) + { + lldbg("%08x->%08x\n", address, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMACA_REGDEBUG +static void sam_putreg(struct sam_emac_s *priv, uintptr_t address, + uint32_t regval) +{ + if (sam_checkreg(priv, true, regval, address)) + { + lldbg("%08x<-%08x\n", address, regval); + } + + putreg32(regval, address); +} +#endif + +/**************************************************************************** + * Function: sam_txinuse + * + * Description: + * Return the number of TX buffers in-use + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers in-use + * + ****************************************************************************/ + +static uint16_t sam_txinuse(struct sam_emac_s *priv) +{ + uint32_t txhead32 = (uint32_t)priv->txhead; + if ((uint32_t)priv->txtail > txhead32) + { + txhead32 += CONFIG_SAMA5_EMAC_NTXBUFFERS; + } + + return (uint16_t)(txhead32 - (uint32_t)priv->txtail); +} + +/**************************************************************************** + * Function: sam_txfree + * + * Description: + * Return the number of TX buffers available + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers available + * + ****************************************************************************/ + +static uint16_t sam_txfree(struct sam_emac_s *priv) +{ + /* The number available is equal to the total number of buffers, minus the + * number of buffers in use. Notice that that actual number of buffers is + * the configured size minus 1. + */ + + return (CONFIG_SAMA5_EMAC_NTXBUFFERS-1) - sam_txinuse(priv); +} + +/**************************************************************************** + * Function: sam_buffer_initialize + * + * Description: + * Allocate aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function degenerates to a few assignements. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +static int sam_buffer_initialize(struct sam_emac_s *priv) +{ +#ifdef CONFIG_SAMA5_EMACA_PREALLOCATE + /* Use pre-allocated buffers */ + + priv->txdesc = g_txdesc; + priv->rxdesc = g_rxdesc; + priv->txbuffer = g_txbuffer; + priv->rxbuffer = g_rxbuffer; + +#else + size_t allocsize; + + /* Allocate buffers */ + + allocsize = CONFIG_SAMA5_EMAC_NTXBUFFERS * sizeof(struct emac_txdesc_s); + priv->txdesc = (struct emac_txdesc_s *)kmm_memalign(8, allocsize); + if (!priv->txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->txdesc, 0, allocsize); + + allocsize = CONFIG_SAMA5_EMAC_NRXBUFFERS * sizeof(struct emac_rxdesc_s); + priv->rxdesc = (struct emac_rxdesc_s *)kmm_memalign(8, allocsize); + if (!priv->rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->rxdesc, 0, allocsize); + + allocsize = CONFIG_SAMA5_EMAC_NTXBUFFERS * EMAC_TX_UNITSIZE; + priv->txbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + allocsize = CONFIG_SAMA5_EMAC_NRXBUFFERS * EMAC_RX_UNITSIZE; + priv->rxbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + +#endif + + DEBUGASSERT(((uintptr_t)priv->rxdesc & 7) == 0 && + ((uintptr_t)priv->rxbuffer & 7) == 0 && + ((uintptr_t)priv->txdesc & 7) == 0 && + ((uintptr_t)priv->txbuffer & 7) == 0); + return OK; +} + +/**************************************************************************** + * Function: sam_buffer_free + * + * Description: + * Free aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function does nothing. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_buffer_free(struct sam_emac_s *priv) +{ +#ifndef CONFIG_SAMA5_EMACA_PREALLOCATE + /* Free allocated buffers */ + + if (priv->txdesc) + { + kmm_free(priv->txdesc); + priv->txdesc = NULL; + } + + if (priv->rxdesc) + { + kmm_free(priv->rxdesc); + priv->rxdesc = NULL; + } + + if (priv->txbuffer) + { + kmm_free(priv->txbuffer); + priv->txbuffer = NULL; + } + + if (priv->rxbuffer) + { + kmm_free(priv->rxbuffer); + priv->rxbuffer = NULL; + } +#endif +} + +/**************************************************************************** + * Function: sam_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_transmit(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + volatile struct emac_txdesc_s *txdesc; + uintptr_t virtaddr; + uint32_t regval; + uint32_t status; + + nllvdbg("d_len: %d txhead: %d\n", dev->d_len, priv->txhead); + sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len); + + /* Check parameter */ + + if (dev->d_len > EMAC_TX_UNITSIZE) + { + nlldbg("ERROR: Packet too big: %d\n", dev->d_len); + return -EINVAL; + } + + /* Pointer to the current TX descriptor */ + + txdesc = &priv->txdesc[priv->txhead]; + + /* If no free TX descriptor, buffer can't be sent */ + + if (sam_txfree(priv) < 1) + { + nlldbg("ERROR: No free TX descriptors\n"); + return -EBUSY; + } + + /* Setup/Copy data to transmission buffer */ + + if (dev->d_len > 0) + { + /* Driver managed the ring buffer */ + + virtaddr = sam_virtramaddr(txdesc->addr); + memcpy((void *)virtaddr, dev->d_buf, dev->d_len); + arch_clean_dcache((uint32_t)virtaddr, (uint32_t)virtaddr + dev->d_len); + } + + /* Update TX descriptor status. */ + + status = dev->d_len | EMACTXD_STA_LAST; + if (priv->txhead == CONFIG_SAMA5_EMAC_NTXBUFFERS-1) + { + status |= EMACTXD_STA_WRAP; + } + + /* Update the descriptor status and flush the updated value to RAM */ + + txdesc->status = status; + arch_clean_dcache((uint32_t)txdesc, + (uint32_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Increment the head index */ + + if (++priv->txhead >= CONFIG_SAMA5_EMAC_NTXBUFFERS) + { + priv->txhead = 0; + } + + /* Now start transmission (if it is not already done) */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_TSTART; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SAM_TXTIMEOUT, sam_txtimeout, 1, + (uint32_t)priv); + + /* Set d_len to zero meaning that the d_buf[] packet buffer is again + * available. + */ + + dev->d_len = 0; + + /* If we have no more available TX descriptors, then we must disable the + * RCOMP interrupt to stop further RX processing. Why? Because EACH RX + * packet that is dispatched is also an opportunity to reply with a TX + * packet. So, if we cannot handle an RX packet reply, then we disable + * all RX packet processing. + */ + + if (sam_txfree(priv) < 1) + { + nllvdbg("Disabling RX interrupts\n"); + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_RCOMP); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_txpoll(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + sam_transmit(priv); + + /* Check if the there are any free TX descriptors. We cannot perform + * the TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) == 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: sam_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail), and + * 3. After a TX timeout to restart the sending process (sam_txtimeout). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_dopoll(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. */ + + (void)devif_poll(dev, sam_txpoll); + } +} + +/**************************************************************************** + * Function: sam_recvframe + * + * Description: + * The function is called when a frame is received. It scans the RX + * descriptors of the received frame and assembles the full packet/ + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * - Global interrupts are disabled by interrupt handling logic. + * - The RX descriptor D-cache list has been invalided to force fetching + * from RAM. + * + ****************************************************************************/ + +static int sam_recvframe(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc; + struct net_driver_s *dev; + const uint8_t *src; + uint8_t *dest; + uintptr_t physaddr; + uint32_t rxndx; + uint32_t pktlen; + uint16_t copylen; + bool isframe; + + /* Process received RX descriptor. The ownership bit is set by the EMAC + * once it has successfully written a frame to memory. + */ + + dev = &priv->dev; + dev->d_len = 0; + + dest = dev->d_buf; + pktlen = 0; + + rxndx = priv->rxndx; + rxdesc = &priv->rxdesc[rxndx]; + isframe = false; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + + nllvdbg("rxndx: %d\n", rxndx); + + while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0) + { + /* The start of frame bit indicates the beginning of a frame. Discard + * any previous fragments. + */ + + if ((rxdesc->status & EMACRXD_STA_SOF) != 0) + { + /* Skip previous fragments */ + + while (rxndx != priv->rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Reset the packet data pointer and packet length */ + + dest = dev->d_buf; + pktlen = 0; + + /* Start to gather buffers into the packet buffer */ + + isframe = true; + } + + /* Increment the working index */ + + if (++rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS) + { + rxndx = 0; + } + + /* Copy data into the packet buffer */ + + if (isframe) + { + if (rxndx == priv->rxndx) + { + nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n"); + do + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + while (rxndx != priv->rxndx); + return -EIO; + } + + /* Get the number of bytes to copy from the buffer */ + + copylen = EMAC_RX_UNITSIZE; + if ((pktlen + copylen) > CONFIG_NET_ETH_MTU) + { + copylen = CONFIG_NET_ETH_MTU - pktlen; + } + + /* Get the data source. Invalidate the source memory region to + * force reload from RAM. + */ + + physaddr = (uintptr_t)(rxdesc->addr & EMACRXD_ADDR_MASK); + src = (const uint8_t *)sam_virtramaddr(physaddr); + + arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); + + /* And do the copy */ + + memcpy(dest, src, copylen); + dest += copylen; + pktlen += copylen; + + /* If the end of frame has been received, return the data */ + + if ((rxdesc->status & EMACRXD_STA_EOF) != 0) + { + /* Frame size from the EMAC */ + + dev->d_len = (rxdesc->status & EMACRXD_STA_FRLEN_MASK); + nllvdbg("packet %d-%d (%d)\n", priv->rxndx, rxndx, dev->d_len); + + /* All data have been copied in the application frame buffer, + * release the RX descriptor + */ + + while (priv->rxndx != rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Check if the device packet buffer was large enough to accept + * all of the data. + */ + + nllvdbg("rxndx: %d d_len: %d\n", priv->rxndx, dev->d_len); + + if (pktlen < dev->d_len) + { + nlldbg("ERROR: Buffer size %d; frame size %d\n", dev->d_len, pktlen); + return -E2BIG; + } + + return OK; + } + } + + /* We have not encountered the SOF yet... discard this fragment and + * keep looking + */ + + else + { + /* Give ownership back to the EMAC */ + + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + priv->rxndx = rxndx; + } + + /* Process the next buffer */ + + rxdesc = &priv->rxdesc[rxndx]; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + } + + /* No packet was found */ + + priv->rxndx = rxndx; + nllvdbg("rxndx: %d\n", priv->rxndx); + return -EAGAIN; +} + +/**************************************************************************** + * Function: sam_receive + * + * Description: + * An interrupt was received indicating the availability of one or more + * new RX packets in FIFO memory. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_receive(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while sam_recvframe() successfully retrieves valid + * EMAC frames. + */ + + while (sam_recvframe(priv) == OK) + { + sam_dumppacket("Received packet", dev->d_buf, dev->d_len); + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + sam_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + } +} + +/**************************************************************************** + * Function: sam_txdone + * + * Description: + * An interrupt was received indicating that one or more frames have + * completed transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txdone(struct sam_emac_s *priv) +{ + struct emac_txdesc_s *txdesc; + + /* Are there any outstanding transmissions? Loop until either (1) all of + * the TX descriptors have been examined, or (2) until we encounter the + * first descriptor that is still in use by the hardware. + */ + + while (priv->txhead != priv->txtail) + { + /* Yes.. check the next buffer at the tail of the list */ + + txdesc = &priv->txdesc[priv->txtail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Is this TX descriptor still in use? */ + + if ((txdesc->status & EMACTXD_STA_USED) == 0) + { + /* Yes.. the descriptor is still in use. However, I have seen a + * case (only repeatable on start-up) where the USED bit is never + * set. Yikes! If we have encountered the first still busy + * descriptor, then we should also have TQBD equal to the descriptor + * address. If it is not, then treat is as used anyway. + */ + +#if 0 /* The issue does not exist in the current configuration, but may return */ +#warning REVISIT + if (priv->txtail == 0 && + sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv, SAM_EMAC_TBQP)) + { + txdesc->status = (uint32_t)EMACTXD_STA_USED; + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + } + else +#endif + { + /* Otherwise, the descriptor is truly in use. Break out of the + * loop now. + */ + + break; + } + } + + /* Increment the tail index */ + + if (++priv->txtail >= CONFIG_SAMA5_EMAC_NTXBUFFERS) + { + /* Wrap to the beginning of the TX descriptor list */ + + priv->txtail = 0; + } + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_EMAC_IER, EMAC_INT_RCOMP); + } + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_emac_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_interrupt(int irq, void *context) +{ + struct sam_emac_s *priv = &g_emac; + uint32_t isr; + uint32_t rsr; + uint32_t tsr; + uint32_t imr; + uint32_t regval; + uint32_t pending; + uint32_t clrbits; + + isr = sam_getreg(priv, SAM_EMAC_ISR); + rsr = sam_getreg(priv, SAM_EMAC_RSR); + tsr = sam_getreg(priv, SAM_EMAC_TSR); + imr = sam_getreg(priv, SAM_EMAC_IMR); + + pending = isr & ~(imr | EMAC_INT_UNUSED); + nllvdbg("isr: %08x pending: %08x\n", isr, pending); + + /* Check for the completion of a transmission. This should be done before + * checking for received data (because receiving can cause another transmission + * before we had a chance to handle the last one). + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read. + * TSR:COMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + if ((pending & EMAC_INT_TCOMP) != 0 || (tsr & EMAC_TSR_COMP) != 0) + { + /* A frame has been transmitted */ + + clrbits = EMAC_TSR_COMP; + + /* Check for Retry Limit Exceeded (RLE) */ + + if ((tsr & EMAC_TSR_RLES) != 0) + { + /* Status RLE & Number of discarded buffers */ + + clrbits = EMAC_TSR_RLES | sam_txinuse(priv); + sam_txreset(priv); + + nlldbg("ERROR: Retry Limit Exceeded TSR: %08x\n", tsr); + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_TE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + + /* Check Collision Occurred (COL) */ + + if ((tsr & EMAC_TSR_COL) != 0) + { + nlldbg("ERROR: Collision occurred TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_COL; + } + + /* Check Buffers exhausted mid frame (BEX) */ + + if ((tsr & EMAC_TSR_BEX) != 0) + { + nlldbg("ERROR: Buffers exhausted mid-frame TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_BEX; + } + + /* Check for Transmit Underrun (UND) + * + * ISR:UND is set transmit DMA was not able to read data from memory, + * either because the bus was not granted in time, because a not + * OK hresp(bus error) was returned or because a used bit was read + * midway through frame transmission. If this occurs, the + * transmitter forces bad CRC. Cleared by writing a one to this bit. + */ + + if ((tsr & EMAC_TSR_UND) != 0) + { + nlldbg("ERROR: Transmit Underrun TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_UND; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_TSR, clrbits); + + /* And handle the TX done event */ + + sam_txdone(priv); + } + + /* Check for the receipt of an RX packet. + * + * RXCOMP indicates that a packet has been received and stored in memory. + * The RXCOMP bit is cleared whent he interrupt status register was read. + * RSR:REC indicates that one or more frames have been received and placed + * in memory. This indication is cleared by writing a one to this bit. + */ + + if ((pending & EMAC_INT_RCOMP) != 0 || (rsr & EMAC_RSR_REC) != 0) + { + clrbits = EMAC_RSR_REC; + + /* Check for Receive Overrun. + * + * RSR:RXOVR will be set if the RX FIFO is not able to store the + * receive frame due to a FIFO overflow, or if the receive status + * was not taken at the end of the frame. This bit is also set in + * DMA packet buffer mode if the packet buffer overflows. For DMA + * operation, the buffer will be recovered if an overrun occurs. This + * bit is cleared when set to 1. + */ + + if ((rsr & EMAC_RSR_OVR) != 0) + { + nlldbg("ERROR: Receiver overrun RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_OVR; + } + + /* Check for buffer not available (BNA) + * + * RSR:BNA means that an attempt was made to get a new buffer and the + * pointer indicated that it was owned by the processor. The DMA will + * reread the pointer each time an end of frame is received until a + * valid pointer is found. This bit is set following each descriptor + * read attempt that fails, even if consecutive pointers are + * unsuccessful and software has in the mean time cleared the status + * flag. Cleared by writing a one to this bit. + */ + + if ((rsr & EMAC_RSR_BNA) != 0) + { + nlldbg("ERROR: Buffer not available RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_BNA; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_RSR, clrbits); + + /* Handle the received packet */ + + sam_receive(priv); + } + +#ifdef CONFIG_DEBUG_NET + /* Check for PAUSE Frame recieved (PFRE). + * + * ISR:PFRE indicates that a pause frame has been received. Cleared on a read. + */ + + if ((pending & EMAC_INT_PFR) != 0) + { + nlldbg("Pause frame received\n"); + } + + /* Check for Pause Time Zero (PTZ) + * + * ISR:PTZ is set Pause Time Zero + */ + + if ((pending & EMAC_INT_PTZ) != 0) + { + nlldbg("Pause TO!\n"); + } +#endif + + return OK; +} + +/**************************************************************************** + * Function: sam_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txtimeout(int argc, uint32_t arg, ...) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)arg; + + nlldbg("Timeout!\n"); + + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + sam_ifdown(&priv->dev); + sam_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_polltimer(int argc, uint32_t arg, ...) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)arg; + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* Update TCP timing states and poll uIP for new XMIT data. */ + + (void)devif_timer(dev, sam_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: sam_ifup + * + * Description: + * NuttX Callback: Bring up the EMAC interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifup(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + nlldbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Configure the EMAC interface for normal operation. */ + + nllvdbg("Initialize the EMAC\n"); + sam_emac_configure(priv); + + /* Set the MAC address (should have been configured while we were down) */ + + sam_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + sam_ipv6multicast(priv); +#endif + + /* Initialize for PHY access */ + + ret = sam_phyinit(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phyinit failed: %d\n", ret); + return ret; + } + + /* Auto Negotiate, working in RMII mode */ + + ret = sam_autonegotiate(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_autonegotiate failed: %d\n", ret); + return ret; + } + + while (sam_linkup(priv) == 0); + nllvdbg("Link detected \n"); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_polltimer, 1, (uint32_t)priv); + + /* Enable the EMAC interrupt */ + + priv->ifup = true; + up_enable_irq(SAM_IRQ_EMAC); + return OK; +} + +/**************************************************************************** + * Function: sam_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifdown(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + irqstate_t flags; + + nlldbg("Taking the network down\n"); + + /* Disable the EMAC interrupt */ + + flags = enter_critical_section(); + up_disable_irq(SAM_IRQ_EMAC); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the sam_ifup() always + * successfully brings the interface back up. + */ + + sam_emac_reset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: sam_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int sam_txavail(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + irqstate_t flags; + + nllvdbg("ifup: %d\n", priv->ifup); + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + sam_dopoll(priv); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_hashindx + * + * Description: + * Cacuclate the hash address register index. The hash address register + * is 64 bits long and takes up two locations in the memory map. The + * destination address is reduced to a 6-bit index into the 64-bit Hash + * Register using the following hash function: The hash function is an XOR + * of every sixth bit of the destination address. + * + * ndx:05 = da:05 ^ da:11 ^ da:17 ^ da:23 ^ da:29 ^ da:35 ^ da:41 ^ da:47 + * ndx:04 = da:04 ^ da:10 ^ da:16 ^ da:22 ^ da:28 ^ da:34 ^ da:40 ^ da:46 + * ndx:03 = da:03 ^ da:09 ^ da:15 ^ da:21 ^ da:27 ^ da:33 ^ da:39 ^ da:45 + * ndx:02 = da:02 ^ da:08 ^ da:14 ^ da:20 ^ da:26 ^ da:32 ^ da:38 ^ da:44 + * ndx:01 = da:01 ^ da:07 ^ da:13 ^ da:19 ^ da:25 ^ da:31 ^ da:37 ^ da:43 + * ndx:00 = da:00 ^ da:06 ^ da:12 ^ da:18 ^ da:24 ^ da:30 ^ da:36 ^ da:42 + * + * Where da:00 represents the least significant bit of the first byte + * received and da:47 represents the most significant bit of the last byte + * received. + * + * Input Parameters: + * mac - The multicast address to be hashed + * + * Returned Value: + * The 6-bit hash table index + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac) +{ + unsigned int ndx; + + /* Isolate: mac[0] + * ... 05 04 03 02 01 00] */ + + ndx = mac[0]; + + /* Isolate: mac[1] mac[0] + * ...11 10 09 08] [07 06 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + */ + + ndx ^= (mac[1] << 2) | (mac[0] >> 6); + + /* Isolate: mac[2] mac[1] + * ... 17 16] [15 14 13 12 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + */ + + ndx ^= (mac[2] << 4) | (mac[1] >> 4); + + /* Isolate: mac[2] + * [23 22 21 20 19 18 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + */ + + ndx ^= (mac[2] >> 2); + + /* Isolate: mac[3] + * ... 29 28 27 26 25 24] + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + */ + + ndx ^= mac[3]; + + /* Isolate: mac[4] mac[3] + * ... 35 34 33 32] [31 30 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + */ + + ndx ^= (mac[4] << 2) | (mac[3] >> 6); + + /* Isolate: mac[5] mac[4] + * ... 41 40] [39 38 37 36 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + */ + + ndx ^= (mac[5] << 4) | (mac[4] >> 4); + + /* Isolate: mac[5] + * [47 46 45 44 43 42 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + * XOR: 47 46 45 44 43 42 + */ + + ndx ^= (mac[5] >> 2); + + /* Mask out the garbage bits and return the 6-bit index */ + + return ndx & 0x3f; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uintptr_t regaddr; + uint32_t regval; + unsigned int ndx; + unsigned int bit; + UNUSED(priv); + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Add the multicast address to the hardware multicast hash table */ + + if (ndx >= 32) + { + regaddr = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr); + regval |= bit; + sam_putreg(priv, regaddr, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~EMAC_NCFGR_UNIHEN; /* Disable unicast matching */ + regval |= EMAC_NCFGR_MTIHEN; /* Enable multicast matching */ + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + return OK; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regaddr1; + unsigned int regaddr2; + unsigned int ndx; + unsigned int bit; + UNUSED(priv); + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Remove the multicast address to the hardware multicast hast table */ + + if (ndx >= 32) + { + regaddr1 = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + regaddr2 = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr1 = SAM_EMAC_HRB; /* Hash Register Bottom [31:0] Register */ + regaddr2 = SAM_EMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr1); + regval &= ~bit; + sam_putreg(priv, regaddr1, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + /* Are all multicast address matches disabled? */ + + if (regval == 0 && sam_getreg(priv, regaddr2) == 0) + { + /* Yes.. disable all address matching */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_UNIHEN | EMAC_NCFGR_MTIHEN); + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_ioctl + * + * Description: + * Handles driver ioctl calls: + * + * SIOCMIINOTIFY - Set up to received notifications from PHY interrupting + * events. + * + * SIOCGMIIPHY, SIOCGMIIREG, and SIOCSMIIREG: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = sam_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = priv->phyaddr; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Read from the requested register */ + + ret = sam_phyread(priv, req->phy_id, req->reg_num, &req->val_out); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Write to the requested register */ + + ret = sam_phywrite(priv, req->phy_id, req->reg_num, req->val_in); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: sam_phydump + * + * Description: + * Dump the contents of PHY registers + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + +#ifdef CONFIG_SAMA5_EMAC_RMII + nllvdbg("RMII Registers (Address %02x)\n", priv->phyaddr); +#else /* defined(CONFIG_SAMA5_EMAC_MII) */ + nllvdbg("MII Registers (Address %02x)\n", priv->phyaddr); +#endif + + sam_phyread(priv, priv->phyaddr, MII_MCR, &phyval); + nllvdbg(" MCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_MSR, &phyval); + nllvdbg(" MSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_ADVERTISE, &phyval); + nllvdbg(" ADVERTISE: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_LPA, &phyval); + nllvdbg(" LPR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, CONFIG_SAMA5_EMAC_PHYSR, &phyval); + nllvdbg(" PHYSR: %04x\n", phyval); + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); +} +#endif + +/**************************************************************************** + * Function: sam_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv) +{ +#if defined(SAMA5_EMAC_PHY_KSZ8051) || defined(SAMA5_EMAC_PHY_KSZ8081) + uint32_t regval; + uint16_t phyval; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); + + /* Read the interrupt status register in order to clear any pending + * interrupts + */ + + ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval); + if (ret == OK) + { + /* Enable link up/down interrupts */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, + (MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); + } + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; + +#else +# warning Missing logic + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Function: sam_phywait + * + * Description: + * Wait for the PHY to become IDLE + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +static int sam_phywait(struct sam_emac_s *priv) +{ + volatile unsigned int retries; + + /* Loop for the configured number of attempts */ + + for (retries = 0; retries < PHY_RETRY_MAX; retries++) + { + /* Is the PHY IDLE */ + + if ((sam_getreg(priv, SAM_EMAC_NSR) & EMAC_NSR_IDLE) != 0) + { + return OK; + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: sam_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyreset(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t mcr; + int timeout; + int ret; + + nllvdbg(" sam_phyreset\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Reset the PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + nlldbg("ERROR: sam_phywrite failed: %d\n", ret); + } + + /* Wait for the PHY reset to complete */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < 10; timeout++) + { + mcr = MII_MCR_RESET; + int result = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (result < 0) + { + nlldbg("ERROR: Failed to read the MCR register: %d\n", ret); + ret = result; + } + else if ((mcr & MII_MCR_RESET) == 0) + { + ret = OK; + break; + } + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyfind + * + * Description: + * Verify the PHY address and, if it is bad, try to one that works. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr) +{ + uint32_t regval; + uint16_t phyval; + uint8_t candidate; + unsigned int offset; + int ret = -ESRCH; + + nllvdbg("Find a valid PHY address\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + candidate = *phyaddr; + + /* Check current candidate address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == MII_OUI_MSB) + { + *phyaddr = candidate; + ret = OK; + } + + /* The current address does not work... try another */ + + else + { + nlldbg("ERROR: sam_phyread failed for PHY address %02x: %d\n", + candidate, ret); + + for (offset = 0; offset < 32; offset++) + { + /* Get the next candidate PHY address */ + + candidate = (candidate + 1) & 0x1f; + + /* Try reading the PHY ID from the candidate PHY address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == MII_OUI_MSB) + { + ret = OK; + break; + } + } + } + + if (ret == OK) + { + nllvdbg(" PHYID1: %04x PHY addr: %d\n", phyval, candidate); + *phyaddr = candidate; + sam_phyread(priv, candidate, CONFIG_SAMA5_EMAC_PHYSR, &phyval); + nllvdbg(" PHYSR: %04x PHY addr: %d\n", phyval, candidate); + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(0) | EMAC_MAN_CODE | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_READ | EMAC_MAN_SOF; + sam_putreg(priv, SAM_EMAC_MAN, regval); + + /* Wait until the PHY is again idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Return data */ + + *phyval = (uint16_t)(sam_getreg(priv, SAM_EMAC_MAN) & EMAC_MAN_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: sam_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The 16-bit value to write to the PHY register. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(phyval) | EMAC_MAN_CODE | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_WRITE | EMAC_MAN_SOF; + sam_putreg(priv, SAM_EMAC_MAN, regval); + + /* Wait until the PHY is again IDLE */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Function: sam_autonegotiate + * + * Description: + * Autonegotiate speed and duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_autonegotiate(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyid1; + uint16_t phyid2; + uint16_t mcr; + uint16_t msr; + uint16_t advertise; + uint16_t lpa; + int timeout; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Verify tht we can read the PHYID register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID1, &phyid1); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID1\n"); + goto errout; + } + + nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr); + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID2, &phyid2); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID2\n"); + goto errout; + } + + nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr); + + if (phyid1 == MII_OUI_MSB && + ((phyid2 & MII_PHYID2_OUI_MASK) >> MII_PHYID2_OUI_SHIFT) == MII_OUI_LSB) + { + nllvdbg(" Vendor Model Number: %04x\n", + (phyid2 & MII_PHYID2_MODEL_MASK) >> MII_PHYID2_MODEL_SHIFT); + nllvdbg(" Model Revision Number: %04x\n", + (phyid2 & MII_PHYID2_REV_MASK) >> MII_PHYID2_REV_SHIFT); + } + else + { + nlldbg("ERROR: PHY not recognized\n"); + } + + /* Setup control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr &= ~MII_MCR_ANENABLE; /* Remove autonegotiation enable */ + mcr &= ~(MII_MCR_LOOPBACK | MII_MCR_PDOWN); + mcr |= MII_MCR_ISOLATE; /* Electrically isolate PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Set the Auto_negotiation Advertisement Register MII advertising for + * Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 + */ + + advertise = MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_8023; + + ret = sam_phywrite(priv, priv->phyaddr, MII_ADVERTISE, advertise); + if (ret < 0) + { + nlldbg("ERROR: Failed to write ANAR\n"); + goto errout; + } + + /* Read and modify control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr |= (MII_MCR_SPEED100 | MII_MCR_ANENABLE | MII_MCR_FULLDPLX); + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Restart Auto_negotiation */ + + mcr |= MII_MCR_ANRESTART; + mcr &= ~MII_MCR_ISOLATE; + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + nllvdbg(" MCR: %04x\n", mcr); + + /* Check AutoNegotiate complete */ + + timeout = 0; + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR\n"); + goto errout; + } + + /* Completed successfully? */ + + if ((msr & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. break out of the loop */ + + nllvdbg("AutoNegotiate complete\n"); + break; + } + + /* No.. check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Get the AutoNeg Link partner base page */ + + ret = sam_phyread(priv, priv->phyaddr, MII_LPA, &lpa); + if (ret < 0) + { + nlldbg("ERROR: Failed to read ANLPAR\n"); + goto errout; + } + + /* Setup the EMAC link speed */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if (((advertise & lpa) & MII_ADVERTISE_100BASETXFULL) != 0) + { + /* Set MII for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXFULL) != 0) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + else if (((advertise & lpa) & MII_ADVERTISE_100BASETXHALF) != 0) + { + /* Set MII for 100BaseTX and half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } +#if 0 + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXHALF) != 0) + { + /* set MII for 10BaseT and half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Select RMII/MII */ + + regval = sam_getreg(priv, SAM_EMAC_USRIO); +#ifdef CONFIG_SAMA5_EMAC_RMII + regval |= EMAC_USRIO_RMII; +#else /* defined(CONFIG_SAMA5_EMAC_MII) */ + regval &= ~EMAC_USRIO_RMII; +#endif + + /* Enable the transceiver clock */ + + regval |= EMAC_USRIO_CLKEN; + sam_putreg(priv, SAM_EMAC_USRIO, regval); + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_linkup + * + * Description: + * Check if the link is up + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * true: The link is up + * + ****************************************************************************/ + +static bool sam_linkup(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t msr; + uint16_t physr; + bool linkup = false; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR: %d\n", ret); + goto errout; + } + + if ((msr & MII_MSR_LINKSTATUS) == 0) + { + nlldbg("ERROR: MSR LinkStatus: %04x\n", msr); + goto errout; + } + + /* Re-configure Link speed */ + + ret = sam_phyread(priv, priv->phyaddr, CONFIG_SAMA5_EMAC_PHYSR, &physr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYSR: %d\n", ret); + goto errout; + } + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if ((msr & MII_MSR_100BASETXFULL) != 0 && PHYSR_IS100FDX(physr)) + { + /* Set EMAC for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if ((msr & MII_MSR_10BASETXFULL) != 0 && PHYSR_IS10FDX(physr)) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + + else if ((msr & MII_MSR_100BASETXHALF) != 0 && PHYSR_IS100HDX(physr)) + { + /* Set MII for 100BaseTX and Half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } + +#if 0 + else if ((msr & MII_MSR_10BASETXHALF) != 0 && PHYSR_IS10HDX(physr)) + { + /* Set MII for 10BaseT and Half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Start the EMAC transfers */ + + nllvdbg("Link is up\n"); + linkup = true; + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + return linkup; +} + +/**************************************************************************** + * Function: sam_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_phyinit(struct sam_emac_s *priv) +{ + uint32_t regval; + uint32_t mck; + int ret; + + /* Configure PHY clocking */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval &= ~EMAC_NCFGR_CLK_MASK; + + mck = BOARD_MCK_FREQUENCY; + if (mck > (160*1000*1000)) + { + ndbg("ERROR: Cannot realize PHY clock\n"); + return -EINVAL; + } + else if (mck > (80*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */ + } + else if (mck > (40*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */ + } + else if (mck > (20*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */ + } + else + { + regval |= EMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */ + } + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Check the PHY Address */ + + priv->phyaddr = CONFIG_SAMA5_EMAC_PHYADDR; + ret = sam_phyfind(priv, &priv->phyaddr); + if (ret < 0) + { + nlldbg("ERROR: sam_phyfind failed: %d\n", ret); + return ret; + } + + if (priv->phyaddr != CONFIG_SAMA5_EMAC_PHYADDR) + { + sam_phyreset(priv); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_ethgpioconfig + * + * Description: + * Configure PIOs for the EMAC interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_ethgpioconfig(struct sam_emac_s *priv) +{ + /* Configure PIO pins to support EMAC */ + /* Configure EMAC PIO pins common to both MII and RMII */ + + sam_configpio(PIO_EMAC_TX0); + sam_configpio(PIO_EMAC_TX1); + sam_configpio(PIO_EMAC_RX0); + sam_configpio(PIO_EMAC_RX1); + sam_configpio(PIO_EMAC_TXEN); + sam_configpio(PIO_EMAC_CRSDV); + sam_configpio(PIO_EMAC_RXER); + sam_configpio(PIO_EMAC_REFCK); + sam_configpio(PIO_EMAC_MDC); + sam_configpio(PIO_EMAC_MDIO); +} + +/**************************************************************************** + * Function: sam_txreset + * + * Description: + * Reset the transmit logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_txreset(struct sam_emac_s *priv) +{ + uint8_t *txbuffer = priv->txbuffer; + struct emac_txdesc_s *txdesc = priv->txdesc; + uintptr_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable TX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_TE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Configure the TX descriptors. */ + + priv->txhead = 0; + priv->txtail = 0; + + for (ndx = 0; ndx < CONFIG_SAMA5_EMAC_NTXBUFFERS; ndx++) + { + bufaddr = (uint32_t)(&(txbuffer[ndx * EMAC_TX_UNITSIZE])); + + /* Set the buffer address and mark the descriptor as in used by firmware */ + + physaddr = sam_physramaddr(bufaddr); + txdesc[ndx].addr = physaddr; + txdesc[ndx].status = EMACTXD_STA_USED; + } + + /* Mark the final descriptor in the list */ + + txdesc[CONFIG_SAMA5_EMAC_NTXBUFFERS - 1].status = + EMACTXD_STA_USED | EMACTXD_STA_WRAP; + + /* Flush the entire TX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + + CONFIG_SAMA5_EMAC_NTXBUFFERS * sizeof(struct emac_txdesc_s)); + + /* Set the Transmit Buffer Queue Pointer Register */ + + physaddr = sam_physramaddr((uintptr_t)txdesc); + sam_putreg(priv, SAM_EMAC_TBQP, physaddr); +} + +/**************************************************************************** + * Function: sam_rxreset + * + * Description: + * Reset the receive logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_rxreset(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc = priv->rxdesc; + uint8_t *rxbuffer = priv->rxbuffer; + uint32_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable RX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~EMAC_NCR_RE; + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Configure the RX descriptors. */ + + priv->rxndx = 0; + for (ndx = 0; ndx < CONFIG_SAMA5_EMAC_NRXBUFFERS; ndx++) + { + bufaddr = (uintptr_t)(&(rxbuffer[ndx * EMAC_RX_UNITSIZE])); + DEBUGASSERT((bufaddr & ~EMACRXD_ADDR_MASK) == 0); + + /* Set the buffer address and remove EMACRXD_ADDR_OWNER and + * EMACRXD_ADDR_WRAP. + */ + + physaddr = sam_physramaddr(bufaddr); + rxdesc[ndx].addr = physaddr; + rxdesc[ndx].status = 0; + } + + /* Mark the final descriptor in the list */ + + rxdesc[CONFIG_SAMA5_EMAC_NRXBUFFERS - 1].addr |= EMACRXD_ADDR_WRAP; + + /* Flush the entire RX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + CONFIG_SAMA5_EMAC_NRXBUFFERS * sizeof(struct emac_rxdesc_s)); + + /* Set the Receive Buffer Queue Pointer Register */ + + physaddr = sam_physramaddr((uintptr_t)rxdesc); + sam_putreg(priv, SAM_EMAC_RBQP, physaddr); +} + +/**************************************************************************** + * Function: sam_emac_reset + * + * Description: + * Reset the EMAC block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_reset(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NETDEV_PHY_IOCTL + /* We are supporting PHY IOCTLs, then do not reset the MAC. If we do, + * then we cannot communicate with the PHY. So, instead, just disable + * interrupts, cancel timers, and disable TX and RX. + */ + + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Disable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval &= ~(EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR, regval); + +#else + /* Disable all EMAC interrupts */ + + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Make sure that RX and TX are disabled; clear statistics registers */ + + sam_putreg(priv, SAM_EMAC_NCR, EMAC_NCR_CLRSTAT); + + /* Disable clocking to the EMAC peripheral */ + + sam_emac_disableclk(); + +#endif +} + +/**************************************************************************** + * Function: sam_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_macaddress(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address */ + + regval = (uint32_t)dev->d_mac.ether_addr_octet[0] | + (uint32_t)dev->d_mac.ether_addr_octet[1] << 8 | + (uint32_t)dev->d_mac.ether_addr_octet[2] << 16 | + (uint32_t)dev->d_mac.ether_addr_octet[3] << 24; + sam_putreg(priv, SAM_EMAC_SA1B, regval); + + regval = (uint32_t)dev->d_mac.ether_addr_octet[4] | + (uint32_t)dev->d_mac.ether_addr_octet[5] << 8; + sam_putreg(priv, SAM_EMAC_SA1T, regval); +} + +/**************************************************************************** + * Function: sam_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)sam_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_emac_configure + * + * Description: + * Configure the EMAC interface for normal operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_configure(struct sam_emac_s *priv) +{ + uint32_t regval; + + nllvdbg("Entry\n"); + + /* Enable clocking to the EMAC peripheral */ + + sam_emac_enableclk(); + + /* Disable TX, RX, clear statistics. Disable all interrupts. */ + + sam_putreg(priv, SAM_EMAC_NCR, EMAC_NCR_CLRSTAT); + sam_putreg(priv, SAM_EMAC_IDR, EMAC_INT_ALL); + + /* Clear all status bits in the receive status register. */ + + regval = (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA); + sam_putreg(priv, SAM_EMAC_RSR, regval); + + /* Clear all status bits in the transmit status register */ + + regval = (EMAC_TSR_UBR | EMAC_TSR_COL | EMAC_TSR_RLES | EMAC_TSR_BEX | + EMAC_TSR_COMP | EMAC_TSR_UND); + sam_putreg(priv, SAM_EMAC_TSR, regval); + + /* Clear any pending interrupts */ + + (void)sam_getreg(priv, SAM_EMAC_ISR); + + /* Enable/disable the copy of data into the buffers, ignore broadcasts. + * Don't copy FCS. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR); + regval |= (EMAC_NCFGR_DRFCS | EMAC_NCFGR_PAE); + +#ifdef CONFIG_NET_PROMISCUOUS + regval |= EMAC_NCFGR_CAF; +#else + regval &= ~EMAC_NCFGR_CAF; +#endif + +#ifdef CONFIG_SAMA5_EMACA_NBC + regval |= EMAC_NCFGR_NBC; +#else + regval &= ~EMAC_NCFGR_NBC; +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR, regval); + + /* Reset TX and RX */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Enable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR); + regval |= (EMAC_NCR_RE | EMAC_NCR_TE | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR, regval); + + /* Setup the interrupts for TX events, RX events, and error events */ + + regval = (EMAC_INT_RCOMP | EMAC_INT_RXUBR | EMAC_INT_TUND | EMAC_INT_RLE | + EMAC_INT_TXERR | EMAC_INT_TCOMP | EMAC_INT_ROVR | EMAC_INT_HRESP | + EMAC_INT_PFR | EMAC_INT_PTZ); + sam_putreg(priv, SAM_EMAC_IER, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_emac_initialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_emac_initialize(void) +{ + struct sam_emac_s *priv = &g_emac; + int ret; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct sam_emac_s)); + priv->dev.d_ifup = sam_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = sam_ifdown; /* I/F down callback */ + priv->dev.d_txavail = sam_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = sam_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = sam_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = sam_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)&g_emac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); + if (!priv->txpoll) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout; + } + + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + if (!priv->txtimeout) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout_with_txpoll; + } + + /* Configure PIO pins to support EMAC */ + + sam_ethgpioconfig(priv); + + /* Allocate buffers */ + + ret = sam_buffer_initialize(priv); + if (ret < 0) + { + ndbg("ERROR: sam_buffer_initialize failed: %d\n", ret); + goto errout_with_txtimeout; + } + + /* Attach the IRQ to the driver. It will not be enabled at the AIC until + * the interface is in the 'up' state. + */ + + ret = irq_attach(SAM_IRQ_EMAC, sam_emac_interrupt); + if (ret < 0) + { + ndbg("ERROR: Failed to attach the handler to the IRQ%d\n", SAM_IRQ_EMAC); + goto errout_with_buffers; + } + + /* Enable clocking to the EMAC peripheral (just for sam_ifdown()) */ + + sam_emac_enableclk(); + + /* Put the interface in the down state (disabling clocking again). */ + + ret = sam_ifdown(&priv->dev); + if (ret < 0) + { + ndbg("ERROR: Failed to put the interface in the down state: %d\n", ret); + goto errout_with_buffers; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + ret = netdev_register(&priv->dev, NET_LL_ETHERNET); + if (ret >= 0) + { + return ret; + } + + ndbg("ERROR: netdev_register() failed: %d\n", ret); + +errout_with_buffers: + sam_buffer_free(priv); +errout_with_txtimeout: + wd_delete(priv->txtimeout); +errout_with_txpoll: + wd_delete(priv->txpoll); +errout: + return ret; +} + +#endif /* CONFIG_NET && CONFIG_SAMA5_EMACA */ diff --git a/arch/arm/src/sama5/sam_emacb.c b/arch/arm/src/sama5/sam_emacb.c new file mode 100644 index 0000000000000000000000000000000000000000..fccc2d51f035b440985fd94dd491cf5aa38095b2 --- /dev/null +++ b/arch/arm/src/sama5/sam_emacb.c @@ -0,0 +1,4647 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_emacb.c + * 10/100 Base-T Ethernet driver for the SAMA5D4. + * + * The SAMA5D3 and SAMA5D4 EMAC implementations differ in register naming + * and in register layout but are functionally equivalent. Here they are + * distinguished as 'A' and 'B'. For now, the 'A' and 'B' drivers are kept + * separate (mostly because the 'B' driver needs to support two EMAC blocks. + * But the 'B' driver should replace the 'A' driver someday. + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This logic derives from the SAM4E Ethernet driver which, in turn, derived + * from the SAMA5D3 Ethernet Type A driver. + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Which used Atmel NoOS sample code for reference (only). That Atmel + * sample code has a BSD compatible license that requires this copyright + * notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_DEBUG) && defined(CONFIG_SAMA5_EMACB_DEBUG) + /* Force debug output (from this file only) */ + +# undef CONFIG_DEBUG_NET +# define CONFIG_DEBUG_NET 1 +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "chip.h" +#include "chip/sam_pinmap.h" +#include "sam_pio.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_ethernet.h" + +#include + +#if defined(CONFIG_NET) && defined(CONFIG_SAMA5_EMACB) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +/* EMAC0 Configuration ******************************************************/ + +#ifdef CONFIG_SAMA5_EMAC0 + /* Number of buffers for RX */ + +# ifndef CONFIG_SAMA5_EMAC0_NRXBUFFERS +# define CONFIG_SAMA5_EMAC0_NRXBUFFERS 16 +# endif + + /* Number of buffers for TX */ + +# ifndef CONFIG_SAMA5_EMAC0_NTXBUFFERS +# define CONFIG_SAMA5_EMAC0_NTXBUFFERS 8 +# endif + +# ifndef CONFIG_SAMA5_EMAC0_PHYADDR +# error "CONFIG_SAMA5_EMAC0_PHYADDR must be defined in the NuttX configuration" +# endif + +# if !defined(CONFIG_SAMA5_EMAC0_MII) && !defined(CONFIG_SAMA5_EMAC0_RMII) +# warning "Neither CONFIG_SAMA5_EMAC0_MII nor CONFIG_SAMA5_EMAC0_RMII defined" +# endif + +# if defined(CONFIG_SAMA5_EMAC0_MII) && defined(CONFIG_SAMA5_EMAC0_RMII) +# error "Both CONFIG_SAMA5_EMAC0_MII and CONFIG_SAMA5_EMAC0_RMII defined" +# endif + +# ifndef CONFIG_SAMA5_EMAC0_PHYSR +# error "CONFIG_SAMA5_EMAC0_PHYSR must be defined in the NuttX configuration" +# endif + +# ifdef CONFIG_SAMA5_EMAC0_AUTONEG +# ifdef CONFIG_SAMA5_EMAC0_PHYSR_ALTCONFIG +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_ALTMODE +# error "CONFIG_SAMA5_EMAC0_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_10HD +# error "CONFIG_SAMA5_EMAC0_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_100HD +# error "CONFIG_SAMA5_EMAC0_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_10FD +# error "CONFIG_SAMA5_EMAC0_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_100FD +# error "CONFIG_SAMA5_EMAC0_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_SPEED +# error "CONFIG_SAMA5_EMAC0_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_100MBPS +# error "CONFIG_SAMA5_EMAC0_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_MODE +# error "CONFIG_SAMA5_EMAC0_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC0_PHYSR_FULLDUPLEX +# error "CONFIG_SAMA5_EMAC0_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +# endif + + /* PHY definitions */ + +# if defined(SAMA5_EMAC0_PHY_DM9161) +# define EMAC0_MII_OUI_MSB 0x0181 +# define EMAC0_MII_OUI_LSB 0x2e +# elif defined(SAMA5_EMAC0_PHY_LAN8700) +# define EMAC0_MII_OUI_MSB 0x0007 +# define EMAC0_MII_OUI_LSB 0x30 +# elif defined(SAMA5_EMAC0_PHY_KSZ8051) +# define EMAC0_MII_OUI_MSB 0x0022 +# define EMAC0_MII_OUI_LSB 0x05 +# elif defined(SAMA5_EMAC0_PHY_KSZ8081) +# define EMAC0_MII_OUI_MSB 0x0022 +# define EMAC0_MII_OUI_LSB 0x05 +# else +# error EMAC PHY unrecognized +# endif +#endif /* CONFIG_SAMA5_EMAC0 */ + +/* EMAC1 Configuration ******************************************************/ + +#ifdef CONFIG_SAMA5_EMAC1 + /* Number of buffers for RX */ + +# ifndef CONFIG_SAMA5_EMAC1_NRXBUFFERS +# define CONFIG_SAMA5_EMAC1_NRXBUFFERS 16 +# endif + + /* Number of buffers for TX */ + +# ifndef CONFIG_SAMA5_EMAC1_NTXBUFFERS +# define CONFIG_SAMA5_EMAC1_NTXBUFFERS 8 +# endif + +# ifndef CONFIG_SAMA5_EMAC1_PHYADDR +# error "CONFIG_SAMA5_EMAC1_PHYADDR must be defined in the NuttX configuration" +# endif + +# if !defined(CONFIG_SAMA5_EMAC1_MII) && !defined(CONFIG_SAMA5_EMAC1_RMII) +# warning "Neither CONFIG_SAMA5_EMAC1_MII nor CONFIG_SAMA5_EMAC1_RMII defined" +# endif + +# if defined(CONFIG_SAMA5_EMAC1_MII) && defined(CONFIG_SAMA5_EMAC1_RMII) +# error "Both CONFIG_SAMA5_EMAC1_MII and CONFIG_SAMA5_EMAC1_RMII defined" +# endif + +# ifndef CONFIG_SAMA5_EMAC1_PHYSR +# error "CONFIG_SAMA5_EMAC1_PHYSR must be defined in the NuttX configuration" +# endif + +# ifdef CONFIG_SAMA5_EMAC1_AUTONEG +# ifdef CONFIG_SAMA5_EMAC1_PHYSR_ALTCONFIG +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_ALTMODE +# error "CONFIG_SAMA5_EMAC1_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_10HD +# error "CONFIG_SAMA5_EMAC1_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_100HD +# error "CONFIG_SAMA5_EMAC1_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_10FD +# error "CONFIG_SAMA5_EMAC1_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_100FD +# error "CONFIG_SAMA5_EMAC1_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_SPEED +# error "CONFIG_SAMA5_EMAC1_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_100MBPS +# error "CONFIG_SAMA5_EMAC1_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_MODE +# error "CONFIG_SAMA5_EMAC1_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMA5_EMAC1_PHYSR_FULLDUPLEX +# error "CONFIG_SAMA5_EMAC1_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +# endif + + /* PHY definitions */ + +# if defined(SAMA5_EMAC1_PHY_DM9161) +# define EMAC1_MII_OUI_MSB 0x0181 +# define EMAC1_MII_OUI_LSB 0x2e +# elif defined(SAMA5_EMAC1_PHY_LAN8700) +# define EMAC1_MII_OUI_MSB 0x0007 +# define EMAC1_MII_OUI_LSB 0x30 +# elif defined(SAMA5_EMAC1_PHY_KSZ8051) +# define EMAC1_MII_OUI_MSB 0x0022 +# define EMAC1_MII_OUI_LSB 0x05 +# elif defined(SAMA5_EMAC1_PHY_KSZ8081) +# define EMAC1_MII_OUI_MSB 0x0022 +# define EMAC1_MII_OUI_LSB 0x05 +# else +# error EMAC PHY unrecognized +# endif +#endif /* CONFIG_SAMA5_EMAC1 */ + +/* Common Configuration *****************************************************/ + +#undef CONFIG_SAMA5_EMACB_NBC + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_EMACB_REGDEBUG +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define sam_dumppacket(m,a,n) +#endif + +/* EMAC buffer sizes, number of buffers, and number of descriptors ********** + * + * REVISIT: The CONFIG_NET_MULTIBUFFER might be useful. It might be possible + * to use this option to send and receive messages directly into the DMA + * buffers, saving a copy. There might be complications on the receiving + * side, however, where buffers may wrap and where the size of the received + * frame will typically be smaller than a full packet. + */ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER must not be set +#endif + +#define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ +#define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define SAM_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SAM_TXTIMEOUT (60*CLK_TCK) + +/* PHY read/write delays in loop counts */ + +#define PHY_RETRY_MAX 1000000 + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the EMAC + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure defines the constant an configured attributes of an EMAC */ + +struct sam_emacattr_s +{ + /* Basic hardware information */ + + uint32_t base; /* EMAC Register base address */ + xcpt_t handler; /* EMAC interrupt handler */ + uint8_t emac; /* EMACn, n=0 or 1 */ + uint8_t irq; /* EMAC interrupt number */ + + /* PHY Configuration */ + + uint8_t phyaddr; /* PHY address */ + uint8_t physr; /* PHY status register address */ + uint16_t msoui; /* MS 16 bits of the 18-bit OUI */ + uint8_t lsoui; /* LS 2 bits of the 18-bit OUI */ + bool rmii; /* True: RMII vs. False: MII */ + bool clause45; /* True: Clause 45 behavior */ +//bool autoneg; /* True: Autonegotiate rate and *plex */ + bool sralt; /* True: Alternate PHYSR bit access */ + + union + { + /* "Standard" form: Individual bits determine speed and half/full + * duplex. + */ + + struct + { + uint16_t stdmask; /* Mask for speed and *plex mode bits */ + uint16_t speed100; /* 100Base_t bit */ + uint16_t fduplex; /* Full duplex bit */ + } std; + + /* Alternative form: Speed and duplex are encoded in a single, + * multi-bit field. + */ + + struct + { + uint16_t altmask; /* Mask speed for mode bits */ + uint16_t hdx10; /* 10Base_T Half Duplex bit pattern */ + uint16_t hdx100; /* 100Base_T Half Duplex bit pattern */ + uint16_t fdx10; /* 10Base_T Half Duplex bit pattern */ + uint16_t fdx100; /* 100Base_T Half Duplex bit pattern */ + } alt; + } u; + + /* Buffer and descriptor configuration */ + + uint8_t ntxbuffers; /* Number of TX buffers */ + uint8_t nrxbuffers; /* Number of RX buffers */ + +#ifdef CONFIG_SAMA5_EMACB_PREALLOCATE + /* Attributes and addresses of preallocated buffers */ + + struct emac_txdesc_s *txdesc; /* Preallocated TX descriptor list */ + struct emac_rxdesc_s *rxdesc; /* Preallocated RX descriptor list */ + uint8_t *txbuffer; /* Preallocated TX buffers */ + uint8_t *rxbuffer; /* Preallocated RX buffers */ +#endif +}; + +/* The sam_emac_s encapsulates all state information for the EMAC peripheral */ + +struct sam_emac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Constant and configured attributes of the EMAC */ + + const struct sam_emacattr_s *attr; + + /* Used to track transmit and receive descriptors */ + + uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */ +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + uint8_t phytype; /* See SAMA5_EMAC0/1_PHY_TYPE definitions */ +#endif + uint16_t txhead; /* Circular buffer head index */ + uint16_t txtail; /* Circular buffer tail index */ + uint16_t rxndx; /* RX index for current processing RX descriptor */ + + uint8_t *rxbuffer; /* Allocated RX buffers */ + uint8_t *txbuffer; /* Allocated TX buffers */ + struct emac_rxdesc_s *rxdesc; /* Allocated RX descriptors */ + struct emac_txdesc_s *txdesc; /* Allocated TX descriptors */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_EMACB_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_EMACB_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, + uint32_t regval, uintptr_t address); +#endif + +static uint32_t sam_getreg(struct sam_emac_s *priv, uint16_t offset); +static void sam_putreg(struct sam_emac_s *priv, uint16_t offset, uint32_t val); + +/* Buffer management */ + +static uint16_t sam_txinuse(struct sam_emac_s *priv); +static uint16_t sam_txfree(struct sam_emac_s *priv); +static int sam_buffer_initialize(struct sam_emac_s *priv); +static void sam_buffer_free(struct sam_emac_s *priv); + +/* Common TX logic */ + +static int sam_transmit(struct sam_emac_s *priv); +static int sam_txpoll(struct net_driver_s *dev); +static void sam_dopoll(struct sam_emac_s *priv); + +/* Interrupt handling */ + +static int sam_recvframe(struct sam_emac_s *priv); +static void sam_receive(struct sam_emac_s *priv); +static void sam_txdone(struct sam_emac_s *priv); +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg); +#endif +static int sam_emac_interrupt(struct sam_emac_s *priv); +#ifdef CONFIG_SAMA5_EMAC0 +static int sam_emac0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_EMAC1 +static int sam_emac1_interrupt(int irq, void *context); +#endif + +/* Watchdog timer expirations */ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg); +#endif +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void sam_poll_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg); +#endif +static void sam_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int sam_ifup(struct net_driver_s *dev); +static int sam_ifdown(struct net_driver_s *dev); + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg); +#endif +static int sam_txavail(struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac); +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY Initialization */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv); +#else +# define sam_phydump(priv) +#endif + +#if 0 /* Not used */ +static bool sam_is10hdx(struct sam_emac_s *priv, uint16_t physr); +#endif +static bool sam_is100hdx(struct sam_emac_s *priv, uint16_t physr); +static bool sam_is10fdx(struct sam_emac_s *priv, uint16_t physr); +static bool sam_is100fdx(struct sam_emac_s *priv, uint16_t physr); + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv); +#endif +static int sam_phywait(struct sam_emac_s *priv); +static int sam_phyreset(struct sam_emac_s *priv); +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr); +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval); +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval); +static int sam_autonegotiate(struct sam_emac_s *priv); +static bool sam_linkup(struct sam_emac_s *priv); +static int sam_phyinit(struct sam_emac_s *priv); + +/* EMAC Initialization */ + +static void sam_txreset(struct sam_emac_s *priv); +static void sam_rxreset(struct sam_emac_s *priv); +static void sam_emac_enableclk(struct sam_emac_s *priv); +#ifndef CONFIG_NETDEV_PHY_IOCTL +static void sam_emac_disableclk(struct sam_emac_s *priv); +#endif +static void sam_emac_reset(struct sam_emac_s *priv); +static void sam_macaddress(struct sam_emac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv); +#endif +static int sam_emac_configure(struct sam_emac_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMACB_PREALLOCATE +/* Preallocated data */ + +#ifdef CONFIG_SAMA5_EMAC0 +/* EMAC0 TX descriptors list */ + +static struct emac_txdesc_s g_emac0_txdesc[CONFIG_SAMA5_EMAC0_NTXBUFFERS] + __attribute__((aligned(8))); + +/* EMAC0 RX descriptors list */ + +static struct emac_rxdesc_s g_emac0_rxdesc[CONFIG_SAMA5_EMAC0_NRXBUFFERS] + __attribute__((aligned(8))); + +/* EMAC0 Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_emac0_txbuffer[CONFIG_SAMA5_EMAC0_NTXBUFFERS * EMAC_TX_UNITSIZE]; + __attribute__((aligned(8))) + +/* EMAC0 Receive Buffers */ + +static uint8_t g_emac0_rxbuffer[CONFIG_SAMA5_EMAC0_NRXBUFFERS * EMAC_RX_UNITSIZE] + __attribute__((aligned(8))); + +#endif + +#ifdef CONFIG_SAMA5_EMAC1 +/* EMAC1 TX descriptors list */ + +static struct emac_txdesc_s g_emac1_txdesc[CONFIG_SAMA5_EMAC1_NTXBUFFERS] + __attribute__((aligned(8))); + +/* EMAC1 RX descriptors list */ + +static struct emac_rxdesc_s g_emac1_rxdesc[CONFIG_SAMA5_EMAC1_NRXBUFFERS] + __attribute__((aligned(8))); + +/* EMAC1 Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_emac1_txbuffer[CONFIG_SAMA5_EMAC1_NTXBUFFERS * EMAC_TX_UNITSIZE]; + __attribute__((aligned(8))) + +/* EMAC1 Receive Buffers */ + +static uint8_t g_emac1_rxbuffer[CONFIG_SAMA5_EMAC1_NRXBUFFERS * EMAC_RX_UNITSIZE] + __attribute__((aligned(8))); + +#endif +#endif + +/* The driver state singletons */ + +#ifdef CONFIG_SAMA5_EMAC0 +static const struct sam_emacattr_s g_emac0_attr = +{ + /* Basic hardware information */ + + .base = SAM_EMAC0_VBASE, + .handler = sam_emac0_interrupt, + .emac = EMAC0_INTF, + .irq = SAM_IRQ_EMAC0, + + /* PHY Configuration */ + + .phyaddr = CONFIG_SAMA5_EMAC0_PHYADDR, + .physr = CONFIG_SAMA5_EMAC0_PHYSR, + .msoui = EMAC0_MII_OUI_MSB, + .lsoui = EMAC0_MII_OUI_LSB, +#ifdef CONFIG_SAMA5_EMAC0_RMII + .rmii = true, +#endif +#ifdef CONFIG_SAMA5_EMAC0_CLAUSE45 + .clause45 = true, +#endif +#ifdef CONFIG_SAMA5_EMAC0_AUTONEG +//.autoneg = true, +#endif +#ifdef CONFIG_SAMA5_EMAC0_PHYSR_ALTCONFIG + .sralt = true, +#endif + + .u = + { +#ifdef CONFIG_SAMA5_EMAC0_PHYSR_ALTCONFIG + .alt = + { + .altmask = CONFIG_SAMA5_EMAC0_PHYSR_ALTMODE, + .hdx10 = CONFIG_SAMA5_EMAC0_PHYSR_10HD, + .hdx100 = CONFIG_SAMA5_EMAC0_PHYSR_100HD, + .fdx10 = CONFIG_SAMA5_EMAC0_PHYSR_10FD, + .fdx100 = CONFIG_SAMA5_EMAC0_PHYSR_100FD, + }, +#else + .std = + { + .stdmask = (CONFIG_SAMA5_EMAC0_PHYSR_SPEED | CONFIG_SAMA5_EMAC0_PHYSR_MODE), + .speed100 = CONFIG_SAMA5_EMAC0_PHYSR_100MBPS, + .fduplex = CONFIG_SAMA5_EMAC0_PHYSR_FULLDUPLEX, + }, +#endif + }, + + /* Buffer and descriptor configuration */ + + .ntxbuffers = CONFIG_SAMA5_EMAC0_NTXBUFFERS, + .nrxbuffers = CONFIG_SAMA5_EMAC0_NRXBUFFERS, + +#ifdef CONFIG_SAMA5_EMACB_PREALLOCATE + /* Addresses of preallocated buffers */ + + .txdesc = g_emac0_txdesc, + .rxdesc = g_emac0_rxdesc, + .txbuffer = g_emac0_txbuffer, + .rxbuffer = g_emac0_rxbuffer, +#endif +}; + +static struct sam_emac_s g_emac0; +#endif + +#ifdef CONFIG_SAMA5_EMAC1 +static const struct sam_emacattr_s g_emac1_attr = +{ + /* Basic hardware information */ + + .base = SAM_EMAC1_VBASE, + .handler = sam_emac1_interrupt, + .emac = EMAC1_INTF, + .irq = SAM_IRQ_EMAC1, + + /* PHY Configuration */ + + .phyaddr = CONFIG_SAMA5_EMAC1_PHYADDR, + .physr = CONFIG_SAMA5_EMAC1_PHYSR, + .msoui = EMAC1_MII_OUI_MSB, + .lsoui = EMAC1_MII_OUI_LSB, +#ifdef CONFIG_SAMA5_EMAC1_RMII + .rmii = true, +#endif +#ifdef CONFIG_SAMA5_EMAC1_CLAUSE45 + .clause45 = true, +#endif +#ifdef CONFIG_SAMA5_EMAC1_AUTONEG +//.autoneg = true, +#endif +#ifdef CONFIG_SAMA5_EMAC1_PHYSR_ALTCONFIG + .sralt = true, +#endif + + .u = + { +#ifdef CONFIG_SAMA5_EMAC1_PHYSR_ALTCONFIG + .alt = + { + .altmask = CONFIG_SAMA5_EMAC1_PHYSR_ALTMODE, + .hdx10 = CONFIG_SAMA5_EMAC1_PHYSR_10HD, + .hdx100 = CONFIG_SAMA5_EMAC1_PHYSR_100HD, + .fdx10 = CONFIG_SAMA5_EMAC1_PHYSR_10FD, + .fdx100 = CONFIG_SAMA5_EMAC1_PHYSR_100FD, + }, +#else + .std = + { + .stdmask = (CONFIG_SAMA5_EMAC1_PHYSR_SPEED | CONFIG_SAMA5_EMAC1_PHYSR_MODE), + .speed100 = CONFIG_SAMA5_EMAC1_PHYSR_100MBPS, + .fduplex = CONFIG_SAMA5_EMAC1_PHYSR_FULLDUPLEX, + }, +#endif + }, + + /* Buffer and descriptor configuration */ + + .ntxbuffers = CONFIG_SAMA5_EMAC1_NTXBUFFERS, + .nrxbuffers = CONFIG_SAMA5_EMAC1_NRXBUFFERS, + +#ifdef CONFIG_SAMA5_EMACB_PREALLOCATE + /* Attributes and addresses of preallocated buffers */ + + .txdesc = g_emac1_txdesc, + .rxdesc = g_emac1_rxdesc, + .txbuffer = g_emac1_txbuffer, + .rxbuffer = g_emac1_rxbuffer, +#endif +}; + +static struct sam_emac_s g_emac1; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMACB_REGDEBUG +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, uint32_t regval, + uintptr_t regaddr) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + regaddr == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read a 32-bit EMAC register using an offset from the EMAC base address + * + ****************************************************************************/ + +static uint32_t sam_getreg(struct sam_emac_s *priv, uint16_t offset) +{ + uintptr_t regaddr = priv->attr->base + (uintptr_t)offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_EMACB_REGDEBUG + if (sam_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to a 32-bit EMAC register using an offset from the EMAC base + * address + * + ****************************************************************************/ + +static void sam_putreg(struct sam_emac_s *priv, uint16_t offset, + uint32_t regval) +{ + uintptr_t regaddr = priv->attr->base + (uintptr_t)offset; + +#ifdef CONFIG_SAMA5_EMACB_REGDEBUG + if (sam_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Function: sam_txinuse + * + * Description: + * Return the number of TX buffers in-use + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers in-use + * + ****************************************************************************/ + +static uint16_t sam_txinuse(struct sam_emac_s *priv) +{ + uint32_t txhead32 = (uint32_t)priv->txhead; + if ((uint32_t)priv->txtail > txhead32) + { + txhead32 += priv->attr->ntxbuffers; + } + + return (uint16_t)(txhead32 - (uint32_t)priv->txtail); +} + +/**************************************************************************** + * Function: sam_txfree + * + * Description: + * Return the number of TX buffers available + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * The number of TX buffers available + * + ****************************************************************************/ + +static uint16_t sam_txfree(struct sam_emac_s *priv) +{ + /* The number available is equal to the total number of buffers, minus the + * number of buffers in use. Notice that that actual number of buffers is + * the configured size minus 1. + */ + + return (priv->attr->ntxbuffers-1) - sam_txinuse(priv); +} + +/**************************************************************************** + * Function: sam_buffer_initialize + * + * Description: + * Allocate aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function degenerates to a few assignements. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +static int sam_buffer_initialize(struct sam_emac_s *priv) +{ +#ifdef CONFIG_SAMA5_EMACB_PREALLOCATE + /* Use pre-allocated buffers */ + + priv->txdesc = priv->attr->txdesc; + priv->rxdesc = priv->attr->rxdesc; + priv->txbuffer = priv->attr->txbuffer; + priv->rxbuffer = priv->attr->rxbuffer; + +#else + size_t allocsize; + + /* Allocate buffers */ + + allocsize = priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s); + priv->txdesc = (struct emac_txdesc_s *)kmm_memalign(8, allocsize); + if (!priv->txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->txdesc, 0, allocsize); + + allocsize = priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s); + priv->rxdesc = (struct emac_rxdesc_s *)kmm_memalign(8, allocsize); + if (!priv->rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->rxdesc, 0, allocsize); + + allocsize = priv->attr->ntxbuffers * EMAC_TX_UNITSIZE; + priv->txbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + allocsize = priv->attr->nrxbuffers * EMAC_RX_UNITSIZE; + priv->rxbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + +#endif + + DEBUGASSERT(((uintptr_t)priv->rxdesc & 7) == 0 && + ((uintptr_t)priv->rxbuffer & 7) == 0 && + ((uintptr_t)priv->txdesc & 7) == 0 && + ((uintptr_t)priv->txbuffer & 7) == 0); + return OK; +} + +/**************************************************************************** + * Function: sam_buffer_free + * + * Description: + * Free aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function does nothing. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_buffer_free(struct sam_emac_s *priv) +{ +#ifndef CONFIG_SAMA5_EMACB_PREALLOCATE + /* Free allocated buffers */ + + if (priv->txdesc) + { + kmm_free(priv->txdesc); + priv->txdesc = NULL; + } + + if (priv->rxdesc) + { + kmm_free(priv->rxdesc); + priv->rxdesc = NULL; + } + + if (priv->txbuffer) + { + kmm_free(priv->txbuffer); + priv->txbuffer = NULL; + } + + if (priv->rxbuffer) + { + kmm_free(priv->rxbuffer); + priv->rxbuffer = NULL; + } +#endif +} + +/**************************************************************************** + * Function: sam_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_transmit(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + volatile struct emac_txdesc_s *txdesc; + uintptr_t virtaddr; + uint32_t regval; + uint32_t status; + + nllvdbg("d_len: %d txhead: %d\n", dev->d_len, priv->txhead); + sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len); + + /* Check parameter */ + + if (dev->d_len > EMAC_TX_UNITSIZE) + { + nlldbg("ERROR: Packet too big: %d\n", dev->d_len); + return -EINVAL; + } + + /* Pointer to the current TX descriptor */ + + txdesc = &priv->txdesc[priv->txhead]; + + /* If no free TX descriptor, buffer can't be sent */ + + if (sam_txfree(priv) < 1) + { + nlldbg("ERROR: No free TX descriptors\n"); + return -EBUSY; + } + + /* Setup/Copy data to transmission buffer */ + + if (dev->d_len > 0) + { + /* Driver managed the ring buffer */ + + virtaddr = sam_virtramaddr(txdesc->addr); + memcpy((void *)virtaddr, dev->d_buf, dev->d_len); + arch_clean_dcache((uint32_t)virtaddr, (uint32_t)virtaddr + dev->d_len); + } + + /* Update TX descriptor status. */ + + status = dev->d_len | EMACTXD_STA_LAST; + if (priv->txhead == priv->attr->ntxbuffers-1) + { + status |= EMACTXD_STA_WRAP; + } + + /* Update the descriptor status and flush the updated value to RAM */ + + txdesc->status = status; + arch_clean_dcache((uint32_t)txdesc, + (uint32_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Increment the head index */ + + if (++priv->txhead >= priv->attr->ntxbuffers) + { + priv->txhead = 0; + } + + /* Now start transmission (if it is not already done) */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_TSTART; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SAM_TXTIMEOUT, sam_txtimeout_expiry, 1, + (uint32_t)priv); + + /* Set d_len to zero meaning that the d_buf[] packet buffer is again + * available. + */ + + dev->d_len = 0; + + /* If we have no more available TX descriptors, then we must disable the + * RCOMP interrupt to stop further RX processing. Why? Because EACH RX + * packet that is dispatched is also an opportunity to replay with a TX + * packet. So, if we cannot handle an RX packet reply, then we disable + * all RX packet processing. + */ + + if (sam_txfree(priv) < 1) + { + nllvdbg("Disabling RX interrupts\n"); + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_RCOMP); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_txpoll(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + sam_transmit(priv); + + /* Check if the there are any free TX descriptors. We cannot perform + * the TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) == 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: sam_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (sam_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_dopoll(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. */ + + (void)devif_poll(dev, sam_txpoll); + } +} + +/**************************************************************************** + * Function: sam_recvframe + * + * Description: + * The function is called when a frame is received. It scans the RX + * descriptors of the received frame and assembles the full packet/ + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * - Global interrupts are disabled by interrupt handling logic. + * - The RX descriptor D-cache list has been invalided to force fetching + * from RAM. + * + ****************************************************************************/ + +static int sam_recvframe(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc; + struct net_driver_s *dev; + const uint8_t *src; + uint8_t *dest; + uintptr_t physaddr; + uint32_t rxndx; + uint32_t pktlen; + uint16_t copylen; + bool isframe; + + /* Process received RX descriptor. The ownership bit is set by the EMAC + * once it has successfully written a frame to memory. + */ + + dev = &priv->dev; + dev->d_len = 0; + + dest = dev->d_buf; + pktlen = 0; + + rxndx = priv->rxndx; + rxdesc = &priv->rxdesc[rxndx]; + isframe = false; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + nllvdbg("rxndx: %d\n", rxndx); + + while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0) + { + /* The start of frame bit indicates the beginning of a frame. Discard + * any previous fragments. + */ + + if ((rxdesc->status & EMACRXD_STA_SOF) != 0) + { + /* Skip previous fragments */ + + while (rxndx != priv->rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= priv->attr->nrxbuffers) + { + priv->rxndx = 0; + } + } + + /* Reset the packet data pointer and packet length */ + + dest = dev->d_buf; + pktlen = 0; + + /* Start to gather buffers into the packet buffer */ + + isframe = true; + } + + /* Increment the working index */ + + if (++rxndx >= priv->attr->nrxbuffers) + { + rxndx = 0; + } + + /* Copy data into the packet buffer */ + + if (isframe) + { + if (rxndx == priv->rxndx) + { + nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n"); + do + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= priv->attr->nrxbuffers) + { + priv->rxndx = 0; + } + } + while (rxndx != priv->rxndx); + return -EIO; + } + + /* Get the number of bytes to copy from the buffer */ + + copylen = EMAC_RX_UNITSIZE; + if ((pktlen + copylen) > CONFIG_NET_ETH_MTU) + { + copylen = CONFIG_NET_ETH_MTU - pktlen; + } + + /* Get the data source. Invalidate the source memory region to + * force reload from RAM. + */ + + physaddr = (uintptr_t)(rxdesc->addr & EMACRXD_ADDR_MASK); + src = (const uint8_t *)sam_virtramaddr(physaddr); + + arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); + + /* And do the copy */ + + memcpy(dest, src, copylen); + dest += copylen; + pktlen += copylen; + + /* If the end of frame has been received, return the data */ + + if ((rxdesc->status & EMACRXD_STA_EOF) != 0) + { + /* Frame size from the EMAC */ + + dev->d_len = (rxdesc->status & EMACRXD_STA_FRLEN_MASK); + nllvdbg("packet %d-%d (%d)\n", priv->rxndx, rxndx, dev->d_len); + + /* All data have been copied in the application frame buffer, + * release the RX descriptor + */ + + while (priv->rxndx != rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= priv->attr->nrxbuffers) + { + priv->rxndx = 0; + } + } + + /* Check if the device packet buffer was large enough to accept + * all of the data. + */ + + nllvdbg("rxndx: %d d_len: %d\n", priv->rxndx, dev->d_len); + if (pktlen < dev->d_len) + { + nlldbg("ERROR: Buffer size %d; frame size %d\n", + dev->d_len, pktlen); + return -E2BIG; + } + + return OK; + } + } + + /* We have not encountered the SOF yet... discard this fragment and + * keep looking + */ + + else + { + /* Give ownership back to the EMAC */ + + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + priv->rxndx = rxndx; + } + + /* Process the next buffer */ + + rxdesc = &priv->rxdesc[rxndx]; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + } + + /* No packet was found */ + + priv->rxndx = rxndx; + nllvdbg("rxndx: %d\n", priv->rxndx); + return -EAGAIN; +} + +/**************************************************************************** + * Function: sam_receive + * + * Description: + * An interrupt was received indicating the availability of one or more + * new RX packets in FIFO memory. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_receive(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while sam_recvframe() successfully retrieves valid + * EMAC frames. + */ + + while (sam_recvframe(priv) == OK) + { + sam_dumppacket("Received packet", dev->d_buf, dev->d_len); + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + sam_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + } +} + +/**************************************************************************** + * Function: sam_txdone + * + * Description: + * An interrupt was received indicating that one or more frames have + * completed transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txdone(struct sam_emac_s *priv) +{ + struct emac_txdesc_s *txdesc; +#ifndef __NO_KLUDGES__ + int ntxdone = 0; +#endif + + /* Are there any outstanding transmissions? Loop until either (1) all of + * the TX descriptors have been examined, or (2) until we encounter the + * first descriptor that is still in use by the hardware. + */ + + while (priv->txhead != priv->txtail) + { + /* Yes.. check the next buffer at the tail of the list */ + + txdesc = &priv->txdesc[priv->txtail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Is this TX descriptor still in use? */ + +#ifndef __NO_KLUDGES__ +# warning REVISIT + /* I have seen cases where we receive interrupts, but the USED + * bit is never set in the TX descriptor. This logic assumes + * that if we got the interrupt, then there most be at least + * one packet that completed. This is not necessarily a safe + * assumption. + */ + + ntxdone++; + if ((txdesc->status & EMACTXD_STA_USED) == 0 && ntxdone > 1) +#else + if ((txdesc->status & EMACTXD_STA_USED) == 0) +#endif + { + /* Yes.. the descriptor is still in use. However, I have seen a + * case (only repeatable on start-up) where the USED bit is never + * set. Yikes! If we have encountered the first still busy + * descriptor, then we should also have TQBD equal to the descriptor + * address. If it is not, then treat is as used anyway. + */ + +#if 0 /* The issue does not exist in the current configuration, but may return */ +#warning REVISIT + if (priv->txtail == 0 && + sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv, SAM_EMAC_TBQB_OFFSET)) + { + txdesc->status = (uint32_t)EMACTXD_STA_USED; + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + } + else +#endif + { + /* Otherwise, the descriptor is truly in use. Break out of the + * loop now. + */ + + break; + } + } + +#ifndef __NO_KLUDGES__ + /* Make sure that the USED bit is set */ + + txdesc->status = (uint32_t)EMACTXD_STA_USED; + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); +#endif + + /* Increment the tail index */ + + if (++priv->txtail >= priv->attr->ntxbuffers) + { + /* Wrap to the beginning of the TX descriptor list */ + + priv->txtail = 0; + } + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_EMAC_IER_OFFSET, EMAC_INT_RCOMP); + } + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv) +{ + uint32_t isr; + uint32_t rsr; + uint32_t tsr; + uint32_t imr; + uint32_t regval; + uint32_t pending; + uint32_t clrbits; + + isr = sam_getreg(priv, SAM_EMAC_ISR_OFFSET); + rsr = sam_getreg(priv, SAM_EMAC_RSR_OFFSET); + tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET); + imr = sam_getreg(priv, SAM_EMAC_IMR_OFFSET); + + pending = isr & ~(imr | EMAC_INT_UNUSED); + nllvdbg("isr: %08x pending: %08x\n", isr, pending); + + /* Check for the completion of a transmission. This should be done before + * checking for received data (because receiving can cause another transmission + * before we had a chance to handle the last one). + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read. + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + if ((pending & EMAC_INT_TCOMP) != 0 || (tsr & EMAC_TSR_TXCOMP) != 0) + { + /* A frame has been transmitted */ + + clrbits = EMAC_TSR_TXCOMP; + + /* Check for Retry Limit Exceeded (RLE) */ + + if ((tsr & EMAC_TSR_RLE) != 0) + { + /* Status RLE & Number of discarded buffers */ + + clrbits = EMAC_TSR_RLE | sam_txinuse(priv); + sam_txreset(priv); + + nlldbg("ERROR: Retry Limit Exceeded TSR: %08x\n", tsr); + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + + /* Check Collision Occurred (COL) */ + + if ((tsr & EMAC_TSR_COL) != 0) + { + nlldbg("ERROR: Collision occurred TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_COL; + } + + /* Check Transmit Frame Corruption due to AHB error (TFC) */ + + if ((tsr & EMAC_TSR_TFC) != 0) + { + nlldbg("ERROR: Transmit Frame Corruption due to AHB error: %08x\n", tsr); + clrbits |= EMAC_TSR_TFC; + } + + /* Check for Transmit Underrun (UND) + * + * ISR:UND is set transmit DMA was not able to read data from memory, + * either because the bus was not granted in time, because a not + * OK hresp(bus error) was returned or because a used bit was read + * midway through frame transmission. If this occurs, the + * transmitter forces bad CRC. Cleared by writing a one to this bit. + */ + + if ((tsr & EMAC_TSR_UND) != 0) + { + nlldbg("ERROR: Transmit Underrun TSR: %08x\n", tsr); + clrbits |= EMAC_TSR_UND; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_TSR_OFFSET, clrbits); + + /* And handle the TX done event */ + + sam_txdone(priv); + } + + /* Check for the receipt of an RX packet. + * + * RXCOMP indicates that a packet has been received and stored in memory. + * The RXCOMP bit is cleared when the interrupt status register was read. + * RSR:REC indicates that one or more frames have been received and placed + * in memory. This indication is cleared by writing a one to this bit. + */ + + if ((pending & EMAC_INT_RCOMP) != 0 || (rsr & EMAC_RSR_REC) != 0) + { + clrbits = EMAC_RSR_REC; + + /* Check for Receive Overrun. + * + * RSR:RXOVR will be set if the RX FIFO is not able to store the + * receive frame due to a FIFO overflow, or if the receive status + * was not taken at the end of the frame. This bit is also set in + * DMA packet buffer mode if the packet buffer overflows. For DMA + * operation, the buffer will be recovered if an overrun occurs. This + * bit is cleared when set to 1. + */ + + if ((rsr & EMAC_RSR_RXOVR) != 0) + { + nlldbg("ERROR: Receiver overrun RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_RXOVR; + } + + /* Check for buffer not available (BNA) + * + * RSR:BNA means that an attempt was made to get a new buffer and the + * pointer indicated that it was owned by the processor. The DMA will + * reread the pointer each time an end of frame is received until a + * valid pointer is found. This bit is set following each descriptor + * read attempt that fails, even if consecutive pointers are + * unsuccessful and software has in the mean time cleared the status + * flag. Cleared by writing a one to this bit. + */ + + if ((rsr & EMAC_RSR_BNA) != 0) + { + nlldbg("ERROR: Buffer not available RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_BNA; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_RSR_OFFSET, clrbits); + + /* Handle the received packet */ + + sam_receive(priv); + } + +#ifdef CONFIG_DEBUG_NET + /* Check for PAUSE Frame received (PFRE). + * + * ISR:PFRE indicates that a pause frame has been received with non-zero + * pause quantum. Cleared on a read. + */ + + if ((pending & EMAC_INT_PFNZ) != 0) + { + nlldbg("Pause frame received\n"); + } + + /* Check for Pause Time Zero (PTZ) + * + * ISR:PTZ is set Pause Time Zero + */ + + if ((pending & EMAC_INT_PTZ) != 0) + { + nlldbg("Pause TO!\n"); + } +#endif +} + +/**************************************************************************** + * Function: sam_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts */ + + up_enable_irq(priv->attr->irq); +} +#endif + +/**************************************************************************** + * Function: sam_emac_interrupt + * + * Description: + * Common hardware interrupt handler + * + * Parameters: + * priv - Reference to the EMAC private state structure + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_interrupt(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NET_NOINTS + uint32_t tsr; + + /* Disable further Ethernet interrupts. Because Ethernet interrupts are + * also disabled if the TX timeout event occurs, there can be no race + * condition here. + */ + + up_disable_irq(priv->attr->irq); + + /* Check for the completion of a transmission. Careful: + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read (so + * we cannot read it here). + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET); + if ((tsr & EMAC_TSR_TXCOMP) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be do race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_interrupt_work, priv, 0); + +#else + /* Process the interrupt now */ + + sam_interrupt_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: sam_emac0/1_interrupt + * + * Description: + * EMAC hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_EMAC0 +static int sam_emac0_interrupt(int irq, void *context) +{ + return sam_emac_interrupt(&g_emac0); +} +#endif + +#ifdef CONFIG_SAMA5_EMAC1 +static int sam_emac1_interrupt(int irq, void *context) +{ + return sam_emac_interrupt(&g_emac1); +} +#endif + +/**************************************************************************** + * Function: sam_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv) +{ + nlldbg("Timeout!\n"); + + /* Reset the hardware. Just take the interface down, then back up again. */ + + sam_ifdown(&priv->dev); + sam_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + */ + + up_disable_irq(priv->attr->irq); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txtimeout_work, priv, 0); +#else + /* Process the timeout now */ + + sam_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_poll_process(FAR struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* Update TCP timing states and poll uIP for new XMIT data. */ + + (void)devif_timer(dev, sam_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: sam_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg); + } + +#else + /* Process the interrupt now */ + + sam_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_ifup + * + * Description: + * NuttX Callback: Bring up the EMAC interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifup(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the EMAC interface for normal operation. */ + + nllvdbg("Initialize the EMAC\n"); + sam_emac_configure(priv); + + /* Set the MAC address (should have been configured while we were down) */ + + sam_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + sam_ipv6multicast(priv); +#endif + + /* Initialize for PHY access */ + + ret = sam_phyinit(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phyinit failed: %d\n", ret); + return ret; + } + + /* Auto Negotiate, working in RMII mode */ + + ret = sam_autonegotiate(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_autonegotiate failed: %d\n", ret); + return ret; + } + + while (sam_linkup(priv) == 0); + nllvdbg("Link detected \n"); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, (uint32_t)priv); + + /* Enable the EMAC interrupt */ + + priv->ifup = true; + up_enable_irq(priv->attr->irq); + return OK; +} + +/**************************************************************************** + * Function: sam_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifdown(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + irqstate_t flags; + + nlldbg("Taking the network down\n"); + + /* Disable the EMAC interrupt */ + + flags = enter_critical_section(); + up_disable_irq(priv->attr->irq); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the sam_ifup() always + * successfully brings the interface back up. + */ + + sam_emac_reset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: sam_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv) +{ + nllvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + sam_dopoll(priv); + } +} + +/**************************************************************************** + * Function: sam_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int sam_txavail(struct net_driver_s *dev) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + sam_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_hashindx + * + * Description: + * Cacuclate the hash address register index. The hash address register + * is 64 bits long and takes up two locations in the memory map. The + * destination address is reduced to a 6-bit index into the 64-bit Hash + * Register using the following hash function: The hash function is an XOR + * of every sixth bit of the destination address. + * + * ndx:05 = da:05 ^ da:11 ^ da:17 ^ da:23 ^ da:29 ^ da:35 ^ da:41 ^ da:47 + * ndx:04 = da:04 ^ da:10 ^ da:16 ^ da:22 ^ da:28 ^ da:34 ^ da:40 ^ da:46 + * ndx:03 = da:03 ^ da:09 ^ da:15 ^ da:21 ^ da:27 ^ da:33 ^ da:39 ^ da:45 + * ndx:02 = da:02 ^ da:08 ^ da:14 ^ da:20 ^ da:26 ^ da:32 ^ da:38 ^ da:44 + * ndx:01 = da:01 ^ da:07 ^ da:13 ^ da:19 ^ da:25 ^ da:31 ^ da:37 ^ da:43 + * ndx:00 = da:00 ^ da:06 ^ da:12 ^ da:18 ^ da:24 ^ da:30 ^ da:36 ^ da:42 + * + * Where da:00 represents the least significant bit of the first byte + * received and da:47 represents the most significant bit of the last byte + * received. + * + * Input Parameters: + * mac - The multicast address to be hashed + * + * Returned Value: + * The 6-bit hash table index + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac) +{ + unsigned int ndx; + + /* Isolate: mac[0] + * ... 05 04 03 02 01 00] */ + + ndx = mac[0]; + + /* Isolate: mac[1] mac[0] + * ...11 10 09 08] [07 06 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + */ + + ndx ^= (mac[1] << 2) | (mac[0] >> 6); + + /* Isolate: mac[2] mac[1] + * ... 17 16] [15 14 13 12 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + */ + + ndx ^= (mac[2] << 4) | (mac[1] >> 4); + + /* Isolate: mac[2] + * [23 22 21 20 19 18 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + */ + + ndx ^= (mac[2] >> 2); + + /* Isolate: mac[3] + * ... 29 28 27 26 25 24] + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + */ + + ndx ^= mac[3]; + + /* Isolate: mac[4] mac[3] + * ... 35 34 33 32] [31 30 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + */ + + ndx ^= (mac[4] << 2) | (mac[3] >> 6); + + /* Isolate: mac[5] mac[4] + * ... 41 40] [39 38 37 36 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + */ + + ndx ^= (mac[5] << 4) | (mac[4] >> 4); + + /* Isolate: mac[5] + * [47 46 45 44 43 42 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + * XOR: 47 46 45 44 43 42 + */ + + ndx ^= (mac[5] >> 2); + + /* Mask out the garbage bits and return the 6-bit index */ + + return ndx & 0x3f; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regoffset; + unsigned int ndx; + unsigned int bit; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Add the multicast address to the hardware multicast hash table */ + + if (ndx >= 32) + { + regoffset = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regoffset = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regoffset); + regval |= bit; + sam_putreg(priv, regoffset, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~EMAC_NCFGR_UNIHEN; /* Disable unicast matching */ + regval |= EMAC_NCFGR_MTIHEN; /* Enable multicast matching */ + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regoffset1; + unsigned int regoffset2; + unsigned int ndx; + unsigned int bit; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Remove the multicast address to the hardware multicast hast table */ + + if (ndx >= 32) + { + regoffset1 = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + regoffset2 = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regoffset1 = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + regoffset2 = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regoffset1); + regval &= ~bit; + sam_putreg(priv, regoffset1, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + /* Are all multicast address matches disabled? */ + + if (regval == 0 && sam_getreg(priv, regoffset2) == 0) + { + /* Yes.. disable all address matching */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_UNIHEN | EMAC_NCFGR_MTIHEN); + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_ioctl + * + * Description: + * Handles driver ioctl calls: + * + * SIOCMIINOTIFY - Set up to received notifications from PHY interrupting + * events. + * + * SIOCGMIIPHY, SIOCGMIIREG, and SIOCSMIIREG: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = sam_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = priv->phyaddr; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Read from the requested register */ + + ret = sam_phyread(priv, req->phy_id, req->reg_num, &req->val_out); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Write to the requested register */ + + ret = sam_phywrite(priv, req->phy_id, req->reg_num, req->val_in); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: sam_phydump + * + * Description: + * Dump the contents of PHY registers + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + nllvdbg("%s Registers (Address %02x)\n", + priv->attr->rmii ? "RMII" : "MII", priv->phyaddr); + + sam_phyread(priv, priv->phyaddr, MII_MCR, &phyval); + nllvdbg(" MCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_MSR, &phyval); + nllvdbg(" MSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_ADVERTISE, &phyval); + nllvdbg(" ADVERTISE: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_LPA, &phyval); + nllvdbg(" LPR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, priv->attr->physr, &phyval); + nllvdbg(" PHYSR: %04x\n", phyval); + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); +} +#endif + +/**************************************************************************** + * Function: sam_is* + * + * Description: + * Helpers to simplify decoding PHY status register bits + * + * Parameters: + * physr - The value of the PHY status register + * + * Returned Value: + * True: The PHY configuration is selected; False; some other PHY + * configuration is selected. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static bool sam_is10hdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.hdx10; + } + else + { + mask = priv->attr->u.std.stdmask; + match = 0; + } + + return (physr & mask) == match; +} +#endif + +static bool sam_is100hdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.hdx100; + } + else + { + mask = priv->attr->u.std.stdmask; + match = priv->attr->u.std.speed100; + } + + return (physr & mask) == match; +} + +static bool sam_is10fdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.fdx10; + } + else + { + mask = priv->attr->u.std.stdmask; + match = priv->attr->u.std.fduplex; + } + + return (physr & mask) == match; +} + +static bool sam_is100fdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.fdx100; + } + else + { + mask = priv->attr->u.std.stdmask; + match = (priv->attr->u.std.fduplex | priv->attr->u.std.speed100); + } + + return (physr & mask) == match; +} + +/**************************************************************************** + * Function: sam_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv) +{ +#if defined(SAMA5_EMAC0_PHY_KSZ8051) || defined(SAMA5_EMAC0_PHY_KSZ8081) || \ + defined(SAMA5_EMAC1_PHY_KSZ8051) || defined(SAMA5_EMAC1_PHY_KSZ8081) + uint32_t regval; + uint16_t phyval; + int ret; + + /* Does this MAC support a KSZ80x1 PHY? */ + + if (priv->phytype == SAMA5_PHY_KSZ8051 || priv->phytype == SAMA5_PHY_KSZ8081) + { + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Read the interrupt status register in order to clear any pending + * interrupts + */ + + ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval); + if (ret == OK) + { + /* Enable link up/down interrupts */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, + (MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); + } + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + else +#endif + { + ndbg("ERROR: Unsupported PHY type: %d\n", priv->phytype); + ret = -ENOSYS; + } + + return ret; +} +#endif + +/**************************************************************************** + * Function: sam_phywait + * + * Description: + * Wait for the PHY to become IDLE + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +static int sam_phywait(struct sam_emac_s *priv) +{ + volatile unsigned int retries; + + /* Loop for the configured number of attempts */ + + for (retries = 0; retries < PHY_RETRY_MAX; retries++) + { + /* Is the PHY IDLE */ + + if ((sam_getreg(priv, SAM_EMAC_NSR_OFFSET) & EMAC_NSR_IDLE) != 0) + { + return OK; + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: sam_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyreset(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t mcr; + int timeout; + int ret; + + nllvdbg(" sam_phyreset\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Reset the PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + nlldbg("ERROR: sam_phywrite failed: %d\n", ret); + } + + /* Wait for the PHY reset to complete */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < 10; timeout++) + { + mcr = MII_MCR_RESET; + int result = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (result < 0) + { + nlldbg("ERROR: Failed to read the MCR register: %d\n", ret); + ret = result; + } + else if ((mcr & MII_MCR_RESET) == 0) + { + ret = OK; + break; + } + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyfind + * + * Description: + * Verify the PHY address and, if it is bad, try to one that works. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr) +{ + uint32_t regval; + uint16_t phyval; + uint8_t candidate; + unsigned int offset; + int ret = -ESRCH; + + nllvdbg("Find a valid PHY address\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + candidate = *phyaddr; + + /* Check current candidate address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == priv->attr->msoui) + { + *phyaddr = candidate; + ret = OK; + } + + /* The current address does not work... try another */ + + else + { + nlldbg("ERROR: sam_phyread failed for PHY address %02x: %d\n", + candidate, ret); + + for (offset = 0; offset < 32; offset++) + { + /* Get the next candidate PHY address */ + + candidate = (candidate + 1) & 0x1f; + + /* Try reading the PHY ID from the candidate PHY address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == priv->attr->msoui) + { + ret = OK; + break; + } + } + } + + if (ret == OK) + { + nllvdbg(" PHYID1: %04x PHY addr: %d\n", phyval, candidate); + *phyaddr = candidate; + sam_phyread(priv, candidate, priv->attr->physr, &phyval); + nllvdbg(" PHYSR: %04x PHY addr: %d\n", phyval, candidate); + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(0) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_READ | EMAC_MAN_WZO; + + if (!priv->attr->clause45) + { + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, + * bit 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; + } + + sam_putreg(priv, SAM_EMAC_MAN_OFFSET, regval); + + /* Wait until the PHY is again idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Return data */ + + *phyval = (uint16_t)(sam_getreg(priv, SAM_EMAC_MAN_OFFSET) & EMAC_MAN_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: sam_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The 16-bit value to write to the PHY register. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(phyval) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_WRITE | EMAC_MAN_WZO; + + if (!priv->attr->clause45) + { + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, + * bit 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; + } + + sam_putreg(priv, SAM_EMAC_MAN_OFFSET, regval); + + /* Wait until the PHY is again IDLE */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Function: sam_autonegotiate + * + * Description: + * Autonegotiate speed and duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_autonegotiate(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyid1; + uint16_t phyid2; + uint16_t mcr; + uint16_t msr; + uint16_t advertise; + uint16_t lpa; + int timeout; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Verify tht we can read the PHYID register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID1, &phyid1); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID1\n"); + goto errout; + } + + nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr); + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID2, &phyid2); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID2\n"); + goto errout; + } + + nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr); + + if (phyid1 == priv->attr->msoui && + ((phyid2 & MII_PHYID2_OUI_MASK) >> MII_PHYID2_OUI_SHIFT) == + (uint16_t)priv->attr->lsoui) + { + nllvdbg(" Vendor Model Number: %04x\n", + (phyid2 & MII_PHYID2_MODEL_MASK) >> MII_PHYID2_MODEL_SHIFT); + nllvdbg(" Model Revision Number: %04x\n", + (phyid2 & MII_PHYID2_REV_MASK) >> MII_PHYID2_REV_SHIFT); + } + else + { + nlldbg("ERROR: PHY not recognized\n"); + } + + /* Setup control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr &= ~MII_MCR_ANENABLE; /* Remove autonegotiation enable */ + mcr &= ~(MII_MCR_LOOPBACK | MII_MCR_PDOWN); + mcr |= MII_MCR_ISOLATE; /* Electrically isolate PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Set the Auto_negotiation Advertisement Register MII advertising for + * Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 + */ + + advertise = MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_8023; + + ret = sam_phywrite(priv, priv->phyaddr, MII_ADVERTISE, advertise); + if (ret < 0) + { + nlldbg("ERROR: Failed to write ANAR\n"); + goto errout; + } + + /* Read and modify control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr |= (MII_MCR_SPEED100 | MII_MCR_ANENABLE | MII_MCR_FULLDPLX); + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Restart Auto_negotiation */ + + mcr |= MII_MCR_ANRESTART; + mcr &= ~MII_MCR_ISOLATE; + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + nllvdbg(" MCR: %04x\n", mcr); + + /* Check AutoNegotiate complete */ + + timeout = 0; + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR\n"); + goto errout; + } + + /* Completed successfully? */ + + if ((msr & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. break out of the loop */ + + nllvdbg("AutoNegotiate complete\n"); + break; + } + + /* No.. check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Get the AutoNeg Link partner base page */ + + ret = sam_phyread(priv, priv->phyaddr, MII_LPA, &lpa); + if (ret < 0) + { + nlldbg("ERROR: Failed to read ANLPAR\n"); + goto errout; + } + + /* Setup the EMAC link speed */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if (((advertise & lpa) & MII_ADVERTISE_100BASETXFULL) != 0) + { + /* Set MII for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXFULL) != 0) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + else if (((advertise & lpa) & MII_ADVERTISE_100BASETXHALF) != 0) + { + /* Set MII for 100BaseTX and half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } +#if 0 + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXHALF) != 0) + { + /* set MII for 10BaseT and half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Select RMII/MII */ + + regval = sam_getreg(priv, SAM_EMAC_UR_OFFSET); + regval &= ~EMAC_UR_RMII; /* Assume MII */ + + if (priv->attr->rmii) + { + /* Not MII, select RMII */ + + regval |= EMAC_UR_RMII; + } + + sam_putreg(priv, SAM_EMAC_UR_OFFSET, regval); + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_linkup + * + * Description: + * Check if the link is up + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * true: The link is up + * + ****************************************************************************/ + +static bool sam_linkup(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t msr; + uint16_t physr; + bool linkup = false; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR: %d\n", ret); + goto errout; + } + + if ((msr & MII_MSR_LINKSTATUS) == 0) + { + nlldbg("ERROR: MSR LinkStatus: %04x\n", msr); + goto errout; + } + + /* Re-configure Link speed */ + + ret = sam_phyread(priv, priv->phyaddr, priv->attr->physr, &physr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYSR: %d\n", ret); + goto errout; + } + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if ((msr & MII_MSR_100BASETXFULL) != 0 && sam_is100fdx(priv, physr)) + { + /* Set EMAC for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if ((msr & MII_MSR_10BASETXFULL) != 0 && sam_is10fdx(priv, physr)) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + + else if ((msr & MII_MSR_100BASETXHALF) != 0 && sam_is100hdx(priv, physr)) + { + /* Set MII for 100BaseTX and Half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } + +#if 0 + else if ((msr & MII_MSR_10BASETXHALF) != 0 && sam_is10hdx(priv, physr)) + { + /* Set MII for 10BaseT and Half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Start the EMAC transfers */ + + nllvdbg("Link is up\n"); + linkup = true; + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + return linkup; +} + +/**************************************************************************** + * Function: sam_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_phyinit(struct sam_emac_s *priv) +{ + uint32_t regval; + uint32_t mck; + int ret; + + /* Configure PHY clocking */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~EMAC_NCFGR_CLK_MASK; + + mck = BOARD_MCK_FREQUENCY; + if (mck > (160*1000*1000)) + { + ndbg("ERROR: Cannot realize PHY clock\n"); + return -EINVAL; + } + else if (mck > (80*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */ + } + else if (mck > (40*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */ + } + else if (mck > (20*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */ + } + else + { + regval |= EMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */ + } + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Check the PHY Address */ + + priv->phyaddr = priv->attr->phyaddr; + ret = sam_phyfind(priv, &priv->phyaddr); + if (ret < 0) + { + nlldbg("ERROR: sam_phyfind failed: %d\n", ret); + return ret; + } + + if (priv->phyaddr != priv->attr->phyaddr) + { + sam_phyreset(priv); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_ethgpioconfig + * + * Description: + * Configure PIOs for the EMAC0/1 RMII/MII interface. + * + * Signal Name Function MII RMII + * -------- --------------------------------- -------- ----------- + * TXCK Transmit Clock or Reference Clock TXCK REFCK + * TXEN Transmit Enable TXEN TXEN + * TX[3..0] Transmit Data TXD[3:0] TXD[1:0] + * TXER Transmit Coding Error TXER Not Used + * RXCK Receive Clock RXCK Not Used + * RXDV Receive Data Valid RXDV CRSDV + * RX[3..0] Receive Data RXD[3:0] RXD[1:0] + * RXER Receive Error RXER RXER + * CRS Carrier Sense and Data Valid CRS Not Used + * COL Collision Detect COL Not Used + * MDC Management Data Clock MDC MDC + * MDIO Management Data Input/Output MDIO MDIO + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_ethgpioconfig(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMA5_EMAC0) + /* Configure EMAC0 PIO pins */ + + if (priv->attr->emac == EMAC0_INTF) + { + /* Configure PIO pins common to RMII and MII mode */ + + sam_configpio(PIO_EMAC0_TXCK); /* Transmit Clock (or Reference Clock) */ + sam_configpio(PIO_EMAC0_TXEN); /* Transmit Enable */ + sam_configpio(PIO_EMAC0_TX0); /* Transmit data TXD0 */ + sam_configpio(PIO_EMAC0_TX1); /* Transmit data TXD1 */ + sam_configpio(PIO_EMAC0_RXDV); /* Receive Data Valid */ + sam_configpio(PIO_EMAC0_RX0); /* Receive data RXD0 */ + sam_configpio(PIO_EMAC0_RX1); /* Receive data RXD0 */ + sam_configpio(PIO_EMAC0_RXER); /* Receive Error */ + sam_configpio(PIO_EMAC0_MDC); /* Management Data Clock */ + sam_configpio(PIO_EMAC0_MDIO); /* Management Data Input/Output */ + + /* Configure additional PIO pins to support EMAC in MII mode */ + + if (!priv->attr->rmii) + { + sam_configpio(PIO_EMAC0_TX2); /* Transmit data TXD2 */ + sam_configpio(PIO_EMAC0_TX3); /* Transmit data TXD3 */ + sam_configpio(PIO_EMAC0_TXER); /* Transmit Coding Error */ + sam_configpio(PIO_EMAC0_RXCK); /* Receive Clock */ + sam_configpio(PIO_EMAC0_RX2); /* Receive data RXD2 */ + sam_configpio(PIO_EMAC0_RX3); /* Receive data RXD3 */ + sam_configpio(PIO_EMAC0_CRS); /* Carrier Sense and Data Valid */ + sam_configpio(PIO_EMAC0_COL); /* Collision Detect */ + } + } + else +#endif + +#if defined(CONFIG_SAMA5_EMAC1) + /* Configure EMAC0 PIO pins */ + + if (priv->attr->emac == EMAC1_INTF) + { + /* Configure PIO pins common to RMII and MII mode */ + + sam_configpio(PIO_EMAC1_TXCK); /* Transmit Clock (or Reference Clock) */ + sam_configpio(PIO_EMAC1_TXEN); /* Transmit Enable */ + sam_configpio(PIO_EMAC1_TX0); /* Transmit data TXD0 */ + sam_configpio(PIO_EMAC1_TX1); /* Transmit data TXD1 */ + sam_configpio(PIO_EMAC1_RXDV); /* Receive Data Valid */ + sam_configpio(PIO_EMAC1_RX0); /* Receive data RXD0 */ + sam_configpio(PIO_EMAC1_RX1); /* Receive data RXD0 */ + sam_configpio(PIO_EMAC1_RXER); /* Receive Error */ + sam_configpio(PIO_EMAC1_MDC); /* Management Data Clock */ + sam_configpio(PIO_EMAC1_MDIO); /* Management Data Input/Output */ + + /* Configure additional PIO pins to support EMAC in MII mode */ + + if (!priv->attr->rmii) + { + sam_configpio(PIO_EMAC1_TX2); /* Transmit data TXD2 */ + sam_configpio(PIO_EMAC1_TX3); /* Transmit data TXD3 */ + sam_configpio(PIO_EMAC1_TXER); /* Transmit Coding Error */ + sam_configpio(PIO_EMAC1_RXCK); /* Receive Clock */ + sam_configpio(PIO_EMAC1_RX2); /* Receive data RXD2 */ + sam_configpio(PIO_EMAC1_RX3); /* Receive data RXD3 */ + sam_configpio(PIO_EMAC1_CRS); /* Carrier Sense and Data Valid */ + sam_configpio(PIO_EMAC1_COL); /* Collision Detect */ + } + } + else +#endif + { + nvdbg("ERROR: emac=%d\n", priv->attr->emac); + } +} + +/**************************************************************************** + * Function: sam_txreset + * + * Description: + * Reset the transmit logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_txreset(struct sam_emac_s *priv) +{ + uint8_t *txbuffer = priv->txbuffer; + struct emac_txdesc_s *txdesc = priv->txdesc; + uintptr_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable TX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Configure the TX descriptors. */ + + priv->txhead = 0; + priv->txtail = 0; + + for (ndx = 0; ndx < priv->attr->ntxbuffers; ndx++) + { + bufaddr = (uint32_t)(&(txbuffer[ndx * EMAC_TX_UNITSIZE])); + + /* Set the buffer address and mark the descriptor as in used by firmware */ + + physaddr = sam_physramaddr(bufaddr); + txdesc[ndx].addr = physaddr; + txdesc[ndx].status = EMACTXD_STA_USED; + } + + /* Mark the final descriptor in the list */ + + txdesc[priv->attr->ntxbuffers - 1].status = + EMACTXD_STA_USED | EMACTXD_STA_WRAP; + + /* Flush the entire TX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + + priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s)); + + /* Set the Transmit Buffer Queue Pointer Register */ + + physaddr = sam_physramaddr((uintptr_t)txdesc); + sam_putreg(priv, SAM_EMAC_TBQB_OFFSET, physaddr); +} + +/**************************************************************************** + * Function: sam_rxreset + * + * Description: + * Reset the receive logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_rxreset(struct sam_emac_s *priv) +{ + struct emac_rxdesc_s *rxdesc = priv->rxdesc; + uint8_t *rxbuffer = priv->rxbuffer; + uint32_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable RX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_RXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Configure the RX descriptors. */ + + priv->rxndx = 0; + for (ndx = 0; ndx < priv->attr->nrxbuffers; ndx++) + { + bufaddr = (uintptr_t)(&(rxbuffer[ndx * EMAC_RX_UNITSIZE])); + DEBUGASSERT((bufaddr & ~EMACRXD_ADDR_MASK) == 0); + + /* Set the buffer address and remove EMACRXD_ADDR_OWNER and + * EMACRXD_ADDR_WRAP. + */ + + physaddr = sam_physramaddr(bufaddr); + rxdesc[ndx].addr = physaddr; + rxdesc[ndx].status = 0; + } + + /* Mark the final descriptor in the list */ + + rxdesc[priv->attr->nrxbuffers - 1].addr |= EMACRXD_ADDR_WRAP; + + /* Flush the entire RX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s)); + + /* Set the Receive Buffer Queue Pointer Register */ + + physaddr = sam_physramaddr((uintptr_t)rxdesc); + sam_putreg(priv, SAM_EMAC_RBQB_OFFSET, physaddr); +} + +/**************************************************************************** + * Function: sam_emac_enableclk + * + * Description: + * Enable clocking to the EMAC block + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_enableclk(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMA5_EMAC0) && defined(CONFIG_SAMA5_EMAC1) + /* Both EMAC blocks are selected, which are we enabling? */ + + if (priv->attr->emac == EMAC0_INTF) + { + sam_emac0_enableclk(); + } + else + { + sam_emac1_enableclk(); + } + +#elif defined(CONFIG_SAMA5_EMAC0) + /* Only EMAC0 is selected */ + + sam_emac0_enableclk(); + +#else + /* Only EMAC1 is selected */ + + sam_emac1_enableclk(); +#endif +} + +/**************************************************************************** + * Function: sam_emac_disableclk + * + * Description: + * Disable clocking to the EMAC block + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +#ifndef CONFIG_NETDEV_PHY_IOCTL +static void sam_emac_disableclk(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMA5_EMAC0) && defined(CONFIG_SAMA5_EMAC1) + /* Both EMAC blocks are selected, which are we disabling? */ + + if (priv->attr->emac == EMAC0_INTF) + { + sam_emac0_disableclk(); + } + else + { + sam_emac1_disableclk(); + } + +#elif defined(CONFIG_SAMA5_EMAC0) + /* Only EMAC0 is selected */ + + sam_emac0_disableclk(); + +#else + /* Only EMAC1 is selected */ + + sam_emac1_disableclk(); +#endif +} +#endif + +/**************************************************************************** + * Function: sam_emac_reset + * + * Description: + * Reset the EMAC block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_reset(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NETDEV_PHY_IOCTL + uint32_t regval; + + /* We are supporting PHY IOCTLs, then do not reset the MAC. If we do, + * then we cannot communicate with the PHY. So, instead, just disable + * interrupts, cancel timers, and disable TX and RX. + */ + + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Disable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~(EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + +#else + /* Disable all EMAC interrupts */ + + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Make sure that RX and TX are disabled; clear statistics registers */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT); + + /* Disable clocking to the EMAC peripheral */ + + sam_emac_disableclk(priv); + +#endif +} + +/**************************************************************************** + * Function: sam_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_macaddress(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address */ + + regval = (uint32_t)dev->d_mac.ether_addr_octet[0] | + (uint32_t)dev->d_mac.ether_addr_octet[1] << 8 | + (uint32_t)dev->d_mac.ether_addr_octet[2] << 16 | + (uint32_t)dev->d_mac.ether_addr_octet[3] << 24; + sam_putreg(priv, SAM_EMAC_SAB1_OFFSET, regval); + + regval = (uint32_t)dev->d_mac.ether_addr_octet[4] | + (uint32_t)dev->d_mac.ether_addr_octet[5] << 8; + sam_putreg(priv, SAM_EMAC_SAT1_OFFSET, regval); +} + +/**************************************************************************** + * Function: sam_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)sam_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_emac_configure + * + * Description: + * Configure the EMAC interface for normal operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_configure(struct sam_emac_s *priv) +{ + uint32_t regval; + + nllvdbg("Entry\n"); + + /* Enable clocking to the EMAC peripheral */ + + sam_emac_enableclk(priv); + + /* Disable TX, RX, clear statistics. Disable all interrupts. */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT); + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + + /* Clear all status bits in the receive status register. */ + + regval = (EMAC_RSR_RXOVR | EMAC_RSR_REC | EMAC_RSR_BNA); + sam_putreg(priv, SAM_EMAC_RSR_OFFSET, regval); + + /* Clear all status bits in the transmit status register */ + + regval = (EMAC_TSR_UBR | EMAC_TSR_COL | EMAC_TSR_RLE | EMAC_TSR_TFC | + EMAC_TSR_TXCOMP | EMAC_TSR_UND); + sam_putreg(priv, SAM_EMAC_TSR_OFFSET, regval); + + /* Clear any pending interrupts */ + + (void)sam_getreg(priv, SAM_EMAC_ISR_OFFSET); + + /* Enable/disable the copy of data into the buffers, ignore broadcasts. + * Don't copy FCS. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval |= (EMAC_NCFGR_RFCS | EMAC_NCFGR_PEN); + +#ifdef CONFIG_NET_PROMISCUOUS + regval |= EMAC_NCFGR_CAF; +#else + regval &= ~EMAC_NCFGR_CAF; +#endif + +#ifdef CONFIG_SAMA5_EMACB_NBC + regval |= EMAC_NCFGR_NBC; +#else + regval &= ~EMAC_NCFGR_NBC; +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Reset TX and RX */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Enable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= (EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Setup the interrupts for TX events, RX events, and error events */ + + regval = (EMAC_INT_RCOMP | EMAC_INT_RXUBR | EMAC_INT_TUR | EMAC_INT_RLEX | + EMAC_INT_TFC | EMAC_INT_TCOMP | EMAC_INT_ROVR | EMAC_INT_HRESP | + EMAC_INT_PFNZ | EMAC_INT_PTZ); + sam_putreg(priv, SAM_EMAC_IER_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_emac_initialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_emac_initialize(int intf) +{ + struct sam_emac_s *priv; + const struct sam_emacattr_s *attr; +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + uint8_t phytype; +#endif + int ret; + +#if defined(CONFIG_SAMA5_EMAC0) + if (intf == EMAC0_INTF) + { + priv = &g_emac0; + attr = &g_emac0_attr; + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + phytype = SAMA5_EMAC0_PHY_TYPE; +#endif + } + else +#endif +#if defined(CONFIG_SAMA5_EMAC1) + if (intf == EMAC1_INTF) + { + priv = &g_emac1; + attr = &g_emac1_attr; + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + phytype = SAMA5_EMAC1_PHY_TYPE; +#endif + } + else +#endif + { + ndbg("ERROR: Interface %d not supported\n", intf); + return -EINVAL; + } + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct sam_emac_s)); + priv->attr = attr; /* Save the constant attributes */ + priv->dev.d_ifup = sam_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = sam_ifdown; /* I/F down callback */ + priv->dev.d_txavail = sam_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = sam_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = sam_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = sam_ioctl; /* Support PHY ioctl() calls */ +#ifdef CONFIG_ARCH_PHY_INTERRUPT + priv->phytype = phytype; /* Type of PHY on port */ +#endif +#endif + + priv->dev.d_private = priv; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); + if (!priv->txpoll) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout; + } + + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + if (!priv->txtimeout) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout_with_txpoll; + } + + /* Configure PIO pins to support EMAC */ + + sam_ethgpioconfig(priv); + + /* Allocate buffers */ + + ret = sam_buffer_initialize(priv); + if (ret < 0) + { + ndbg("ERROR: sam_buffer_initialize failed: %d\n", ret); + goto errout_with_txtimeout; + } + + /* Attach the IRQ to the driver. It will not be enabled at the AIC until + * the interface is in the 'up' state. + */ + + ret = irq_attach(priv->attr->irq, priv->attr->handler); + if (ret < 0) + { + ndbg("ERROR: Failed to attach the handler to the IRQ%d\n", priv->attr->irq); + goto errout_with_buffers; + } + + /* Enable clocking to the EMAC peripheral (just for sam_ifdown()) */ + + sam_emac_enableclk(priv); + + /* Put the interface in the down state (disabling clocking again). */ + + ret = sam_ifdown(&priv->dev); + if (ret < 0) + { + ndbg("ERROR: Failed to put the interface in the down state: %d\n", ret); + goto errout_with_buffers; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + ret = netdev_register(&priv->dev, NET_LL_ETHERNET); + if (ret >= 0) + { + return ret; + } + + ndbg("ERROR: netdev_register() failed: %d\n", ret); + +errout_with_buffers: + sam_buffer_free(priv); +errout_with_txtimeout: + wd_delete(priv->txtimeout); +errout_with_txpoll: + wd_delete(priv->txpoll); +errout: + return ret; +} + +#endif /* CONFIG_NET && CONFIG_SAMA5_EMACB */ diff --git a/arch/arm/src/sama5/sam_ethernet.c b/arch/arm/src/sama5/sam_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..409db45535d2c4867b6fbea900d5e82f64ea1d1c --- /dev/null +++ b/arch/arm/src/sama5/sam_ethernet.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_ethernet.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "sam_ethernet.h" + +#ifdef CONFIG_NET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_gmac_initialize + * + * Description: + * Initialize the GMAC driver + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC +static inline void up_gmac_initialize(void) +{ + int ret; + + /* Initialize the GMAC driver */ + + ret = sam_gmac_initialize(); + if (ret < 0) + { + nlldbg("ERROR: sam_gmac_initialize failed: %d\n", ret); + } +} +#else +# define up_gmac_initialize() +#endif + +/**************************************************************************** + * Function: up_emac_initialize + * + * Description: + * Initialize the EMAC driver + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EMACA) +static inline void up_emac_initialize(void) +{ + int ret; + + /* Initialize the EMAC driver */ + + ret = sam_emac_initialize(); + if (ret < 0) + { + nlldbg("ERROR: up_emac_initialize failed: %d\n", ret); + } +} +#elif defined(CONFIG_SAMA5_EMACB) +static inline void up_emac_initialize(void) +{ + int ret; + +#if defined(CONFIG_SAMA5_EMAC0) + /* Initialize the EMAC0 driver */ + + ret = sam_emac_initialize(EMAC0_INTF); + if (ret < 0) + { + nlldbg("ERROR: up_emac_initialize(EMAC0) failed: %d\n", ret); + } +#endif + +#if defined(CONFIG_SAMA5_EMAC1) + /* Initialize the EMAC1 driver */ + + ret = sam_emac_initialize(EMAC1_INTF); + if (ret < 0) + { + nlldbg("ERROR: up_emac_initialize(EMAC1) failed: %d\n", ret); + } +#endif +} +#else +# define up_emac_initialize() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. If both the EMAC + * and GMAC are enabled, then this single entry point must initialize + * both. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +void up_netinitialize(void) +{ + /* The first device registered with be ETH0 and the second ETH1 */ + +#ifdef CONFIG_SAMA5_GMAC_ISETH0 + up_gmac_initialize(); + up_emac_initialize(); +#else + up_emac_initialize(); + up_gmac_initialize(); +#endif +} + +#endif /* CONFIG_NET */ diff --git a/arch/arm/src/sama5/sam_ethernet.h b/arch/arm/src/sama5/sam_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..23bfa713a1af7d5ca323011240f51629310a71a9 --- /dev/null +++ b/arch/arm/src/sama5/sam_ethernet.h @@ -0,0 +1,343 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_ethernet.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_ETHERNET_H +#define __ARCH_ARM_SRC_SAMA5_SAM_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_emac.h" +#include "chip/sam_gmac.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Understood PHY types */ + +#define SAMA5_PHY_DM9161 0 +#define SAMA5_PHY_LAN8700 1 +#define SAMA5_PHY_KSZ8051 2 +#define SAMA5_PHY_KSZ8081 3 +#define SAMA5_PHY_KSZ90x1 4 + +/* Definitions for use with sam_phy_boardinitialize */ + +#if defined(CONFIG_SAMA5_HAVE_EMACA) +# define GMAC_INTF 0 +# define EMAC_INTF 1 +#elif defined(CONFIG_SAMA5_HAVE_EMACB) +# define EMAC0_INTF 0 +# define EMAC1_INTF 1 +#endif + +/* Which is ETH0 and which is ETH1? */ + +#ifndef CONFIG_SAMA5_GMAC +# undef CONFIG_SAMA5_GMAC_ISETH0 +#endif + +#ifndef CONFIG_SAMA5_EMACA +# undef CONFIG_SAMA5_EMAC_ISETH0 +#endif + +#ifndef CONFIG_SAMA5_EMACB +# undef CONFIG_SAMA5_EMAC0_ISETH0 +# undef CONFIG_SAMA5_EMAC1_ISETH0 +#endif + +#if defined(CONFIG_SAMA5_GMAC_ISETH0) && defined(CONFIG_SAMA5_EMAC_ISETH0) +# error GMAC and EMAC cannot both be ETH0 +#endif + +#if defined(CONFIG_SAMA5_EMAC0_ISETH0) && defined(CONFIG_SAMA5_EMAC1_ISETH0) +# error EMAC0 and EMAC2 cannot both be ETH0 +#endif + +#if defined(CONFIG_SAMA5_GMAC_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMA5_GMAC_PHY_DM9161 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMA5_GMAC_PHY_LAN8700 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMA5_GMAC_PHY_KSZ8051 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_GMAC_PHY_KSZ8081 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMA5_GMAC_PHY_KSZ90x1 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMA5_GMAC) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMA5_GMAC_PHY_DM9161 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMA5_GMAC_PHY_LAN8700 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMA5_GMAC_PHY_KSZ8051 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH1_PHY_KSZ8081) +# define SAMA5_GMAC_PHY_KSZ8081 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMA5_GMAC_PHY_KSZ90x1 1 +# define SAMA5_GMAC_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +#if defined(CONFIG_SAMA5_EMAC_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMA5_EMAC_PHY_DM9161 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMA5_EMAC_PHY_LAN8700 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMA5_EMAC_PHY_KSZ8051 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_EMAC_PHY_KSZ8081 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMA5_EMAC_PHY_KSZ90x1 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMA5_EMACA) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMA5_EMAC_PHY_DM9161 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMA5_EMAC_PHY_LAN8700 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMA5_EMAC_PHY_KSZ8051 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH1_PHY_KSZ8081) +# define SAMA5_EMAC_PHY_KSZ8081 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMA5_EMAC_PHY_KSZ90x1 1 +# define SAMA5_EMAC_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +#if defined(CONFIG_SAMA5_EMAC0_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMA5_EMAC0_PHY_DM9161 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMA5_EMAC0_PHY_LAN8700 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMA5_EMAC0_PHY_KSZ8051 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_EMAC0_PHY_KSZ8081 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMA5_EMAC0_PHY_KSZ90x1 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMA5_EMAC0) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMA5_EMAC0_PHY_DM9161 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMA5_EMAC0_PHY_LAN8700 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMA5_EMAC0_PHY_KSZ8051 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_EMAC0_PHY_KSZ8081 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMA5_EMAC0_PHY_KSZ90x1 1 +# define SAMA5_EMAC0_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +#if defined(CONFIG_SAMA5_EMAC1_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMA5_EMAC1_PHY_DM9161 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMA5_EMAC1_PHY_LAN8700 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMA5_EMAC1_PHY_KSZ8051 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_EMAC1_PHY_KSZ8081 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMA5_EMAC1_PHY_KSZ90x1 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMA5_EMAC1) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMA5_EMAC1_PHY_DM9161 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMA5_EMAC1_PHY_LAN8700 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMA5_EMAC1_PHY_KSZ8051 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMA5_EMAC1_PHY_KSZ8081 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMA5_EMAC1_PHY_KSZ90x1 1 +# define SAMA5_EMAC1_PHY_TYPE SAMA5_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: sam_gmac_initialize + * + * Description: + * Initialize the GMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC +int sam_gmac_initialize(void); +#endif + +/**************************************************************************** + * Function: sam_emac_initialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EMACA) +int sam_emac_initialize(void); +#elif defined(CONFIG_SAMA5_EMACB) +int sam_emac_initialize(int intf); +#endif + +/************************************************************************************ + * Function: sam_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_SAMA5_PHYINIT is defined in the configuration then the board specific + * logic must provide sam_phyinitialize(); The SAMA5 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_PHYINIT +int sam_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ETHERNET_H */ + diff --git a/arch/arm/src/sama5/sam_flexcom_serial.c b/arch/arm/src/sama5/sam_flexcom_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..c65c1aab474ea8e74cd185f27ec19d38c420c87c --- /dev/null +++ b/arch/arm/src/sama5/sam_flexcom_serial.c @@ -0,0 +1,1299 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_flexcom_serial.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/sam_flexcom.h" +#include "sam_config.h" +#include "sam_dbgu.h" +#include "sam_serial.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +#undef TTYFC0_DEV +#undef TTYFC1_DEV +#undef TTYFC2_DEV +#undef TTYFC3_DEV +#undef TTYFC4_DEV + +#undef USART0_ASSIGNED +#undef USART1_ASSIGNED +#undef USART2_ASSIGNED +#undef USART3_ASSIGNED +#undef USART4_ASSIGNED + +#ifdef SAMA5_HAVE_FLEXCOM_USART + +/* Which Flexcom with be ttyFC0/console and which ttyFC1? ttyFC2? ttyFC3? + * ttyFC4? ttyFC5? + */ + +/* First pick the console and ttyFC0. This could be any of FLEXUS0-4 */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_flexus0port /* FLEXUS0 is console */ +# define TTYFC0_DEV g_flexus0port /* FLEXUS0 is ttyFC0 */ +# define FLEXUS0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_flexus1port /* FLEXUS1 is console */ +# define TTYFC0_DEV g_flexus1port /* FLEXUS1 is ttyFC0 */ +# define FLEXUS1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_flexus2port /* FLEXUS2 is console */ +# define TTYFC0_DEV g_flexus2port /* FLEXUS2 is ttyFC0 */ +# define FLEXUS2_ASSIGNED 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_flexus3port /* FLEXUS3 is console */ +# define TTYFC0_DEV g_flexus3port /* FLEXUS3 is ttyFC0 */ +# define FLEXUS3_ASSIGNED 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_flexus4port /* FLEXUS4 is console */ +# define TTYFC0_DEV g_flexus4port /* FLEXUS4 is ttyFC0 */ +# define FLEXUS4_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_USART0_ISUART) +# define TTYFC0_DEV g_flexus0port /* FLEXUS0 is ttyFC0 */ +# define FLEXUS0_ASSIGNED 1 +# elif defined(CONFIG_USART1_ISUART) +# define TTYFC0_DEV g_flexus1port /* FLEXUS1 is ttyFC0 */ +# define FLEXUS1_ASSIGNED 1 +# elif defined(CONFIG_USART2_ISUART) +# define TTYFC0_DEV g_flexus2port /* FLEXUS2 is ttyFC0 */ +# define FLEXUS2_ASSIGNED 1 +# elif defined(CONFIG_USART3_ISUART) +# define TTYFC0_DEV g_flexus3port /* FLEXUS3 is ttyFC0 */ +# define FLEXUS3_ASSIGNED 1 +# elif defined(CONFIG_USART4_ISUART) +# define TTYFC0_DEV g_flexus4port /* FLEXUS4 is ttyFC0 */ +# define FLEXUS4_ASSIGNED 4 +# endif +#endif + +/* Pick ttyFC1. This could be any of USART0-4 excluding the console UART. */ + +#if defined(CONFIG_USART0_ISUART) && !defined(FLEXUS0_ASSIGNED) +# define TTYFC1_DEV g_flexus0port /* FLEXUS0 is ttyFC1 */ +# define FLEXUS0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(FLEXUS1_ASSIGNED) +# define TTYFC1_DEV g_flexus1port /* FLEXUS1 is ttyFC1 */ +# define FLEXUS1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(FLEXUS2_ASSIGNED) +# define TTYFC1_DEV g_flexus2port /* FLEXUS2 is ttyFC1 */ +# define FLEXUS2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(FLEXUS3_ASSIGNED) +# define TTYFC1_DEV g_flexus3port /* FLEXUS3 is ttyFC1 */ +# define FLEXUS3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(FLEXUS4_ASSIGNED) +# define TTYFC1_DEV g_flexus4port /* FLEXUS4 is ttyFC1 */ +# define FLEXUS4_ASSIGNED 1 +#endif + +/* Pick ttyFC2. This could be one of FLEXUS1-4. It can't be FLEXUS0 + * because that was either assigned as ttyFC0 or ttyFC1. One of these + * could also be the console. + */ + +#if defined(CONFIG_USART1_ISUART) && !defined(FLEXUS1_ASSIGNED) +# define TTYFC2_DEV g_flexus1port /* FLEXUS1 is ttyFC2 */ +# define FLEXUS1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(FLEXUS2_ASSIGNED) +# define TTYFC2_DEV g_flexus2port /* FLEXUS2 is ttyFC2 */ +# define FLEXUS2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(FLEXUS3_ASSIGNED) +# define TTYFC2_DEV g_flexus3port /* FLEXUS3 is ttyFC2 */ +# define FLEXUS3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYFC2_DEV g_flexus4port /* FLEXUS4 is ttyFC2 */ +# define FLEXUS4_ASSIGNED 1 +#endif + +/* Pick ttyFC3. This could be one of FLEXUS2-4. It can't be FLEXUS0-1 + * UART0-1; those have already been assigned to ttyFC0, 1, or 2. One of + * FLEXUS2-4 could also be the console. + */ + +#if defined(CONFIG_USART2_ISUART) && !defined(FLEXUS2_ASSIGNED) +# define TTYFC3_DEV g_flexus2port /* FLEXUS2 is ttyFC3 */ +# define FLEXUS2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(FLEXUS3_ASSIGNED) +# define TTYFC3_DEV g_flexus3port /* FLEXUS3 is ttyFC3 */ +# define FLEXUS3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(FLEXUS4_ASSIGNED) +# define TTYFC3_DEV g_flexus4port /* FLEXUS4 is ttyFC3 */ +# define FLEXUS4_ASSIGNED 1 +#endif + +/* Pick ttyFC4. This could be one of USART3-4. It can't be one of + * USART0-2; those have already been assigned to ttyFC0-3. One of + * USART3-4 could also be the console. + */ + +#if defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYFC4_DEV g_flexus3port /* USART3 is ttyFC4 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYFC4_DEV g_flexus4port /* USART4 is ttyFC4 */ +# define USART4_ASSIGNED 1 +#endif + +/* The Flexcom modules are driven by the peripheral clock (MCK or MCK2). */ + +#define SAM_USART_CLOCK BOARD_FLEXCOM_FREQUENCY /* Frequency of the FLEXCOM clock */ +#define SAM_MR_USCLKS FLEXUS_MR_USCLKS_MCK /* Source = Main clock */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct flexus_dev_s +{ + xcpt_t handler; /* Interrupt handler */ + uint32_t usartbase; /* Base address of USART registers */ + uint32_t baud; /* Configured baud */ + uint32_t sr; /* Saved status bits */ + uint8_t irq; /* IRQ associated with this USART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; /* input flow control (RTS) enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int flexus_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_USART0_ISUART +static int flexus0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART1_ISUART +static int flexus1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART2_ISUART +static int flexus2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART3_ISUART +static int flexus3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART4_ISUART +static int flexus4_interrupt(int irq, void *context); +#endif + +static int flexus_setup(struct uart_dev_s *dev); +static void flexus_shutdown(struct uart_dev_s *dev); +static int flexus_attach(struct uart_dev_s *dev); +static void flexus_detach(struct uart_dev_s *dev); +static int flexus_ioctl(struct file *filep, int cmd, unsigned long arg); +static int flexus_receive(struct uart_dev_s *dev, uint32_t *status); +static void flexus_rxint(struct uart_dev_s *dev, bool enable); +static bool flexus_rxavailable(struct uart_dev_s *dev); +static void flexus_send(struct uart_dev_s *dev, int ch); +static void flexus_txint(struct uart_dev_s *dev, bool enable); +static bool flexus_txready(struct uart_dev_s *dev); +static bool flexus_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_flexus_ops = +{ + .setup = flexus_setup, + .shutdown = flexus_shutdown, + .attach = flexus_attach, + .detach = flexus_detach, + .ioctl = flexus_ioctl, + .receive = flexus_receive, + .rxint = flexus_rxint, + .rxavailable = flexus_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = flexus_send, + .txint = flexus_txint, + .txready = flexus_txready, + .txempty = flexus_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_USART0_ISUART +static char g_flexus0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_flexus0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART1_ISUART +static char g_flexus1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_flexus1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART2_ISUART +static char g_flexus2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_flexus2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART3_ISUART +static char g_flexus3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_flexus3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART4_ISUART +static char g_flexus4rxbuffer[CONFIG_USART4_RXBUFSIZE]; +static char g_flexus4txbuffer[CONFIG_USART4_TXBUFSIZE]; +#endif + +/* This describes the state of the USART0 port. */ + +#ifdef CONFIG_USART0_ISUART +static struct flexus_dev_s g_flexus0priv = +{ + .handler = flexus0_interrupt, + .usartbase = SAM_FLEXCOM0_VBASE, + .baud = CONFIG_USART0_BAUD, + .irq = SAM_IRQ_FLEXCOM0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +#if defined(CONFIG_USART0_OFLOWCONTROL) || defined(CONFIG_USART0_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_flexus0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_flexus0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_flexus0txbuffer, + }, + .ops = &g_flexus_ops, + .priv = &g_flexus0priv, +}; +#endif + +/* This describes the state of the USART1 port. */ + +#ifdef CONFIG_USART1_ISUART +static struct flexus_dev_s g_flexus1priv = +{ + .handler = flexus1_interrupt, + .usartbase = SAM_FLEXCOM1_VBASE, + .baud = CONFIG_USART1_BAUD, + .irq = SAM_IRQ_FLEXCOM1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, +#if defined(CONFIG_USART1_OFLOWCONTROL) || defined(CONFIG_USART1_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_flexus1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_flexus1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_flexus1txbuffer, + }, + .ops = &g_flexus_ops, + .priv = &g_flexus1priv, +}; +#endif + +/* This describes the state of the USART2 port. */ + +#ifdef CONFIG_USART2_ISUART +static struct flexus_dev_s g_flexus2priv = +{ + .handler = flexus2_interrupt, + .usartbase = SAM_FLEXCOM2_VBASE, + .baud = CONFIG_USART2_BAUD, + .irq = SAM_IRQ_FLEXCOM2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +#if defined(CONFIG_USART2_OFLOWCONTROL) || defined(CONFIG_USART2_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_flexus2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_flexus2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_flexus2txbuffer, + }, + .ops = &g_flexus_ops, + .priv = &g_flexus2priv, +}; +#endif + +/* This describes the state of the USART3 port. */ + +#ifdef CONFIG_USART3_ISUART +static struct flexus_dev_s g_flexus3priv = +{ + .handler = flexus3_interrupt, + .usartbase = SAM_FLEXCOM3_VBASE, + .baud = CONFIG_USART3_BAUD, + .irq = SAM_IRQ_FLEXCOM3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, +#if defined(CONFIG_USART3_OFLOWCONTROL) || defined(CONFIG_USART3_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_flexus3port = +{ + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_flexus3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_flexus3txbuffer, + }, + .ops = &g_flexus_ops, + .priv = &g_flexus3priv, +}; +#endif + +/* This describes the state of the USART4 port. */ + +#ifdef CONFIG_USART4_ISUART +static struct flexus_dev_s g_flexus4priv = +{ + .handler = flexus4_interrupt, + .usartbase = SAM_FLEXCOM4_VBASE, + .baud = CONFIG_USART4_BAUD, + .irq = SAM_IRQ_FLEXCOM4, + .parity = CONFIG_USART4_PARITY, + .bits = CONFIG_USART4_BITS, + .stopbits2 = CONFIG_USART4_2STOP, +#if defined(CONFIG_USART4_OFLOWCONTROL) || defined(CONFIG_USART4_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_flexus4port = +{ + .recv = + { + .size = CONFIG_USART4_RXBUFSIZE, + .buffer = g_flexus4rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART4_TXBUFSIZE, + .buffer = g_flexus4txbuffer, + }, + .ops = &g_flexus_ops, + .priv = &g_flexus4priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: flexus_serialin + ****************************************************************************/ + +static inline uint32_t flexus_serialin(struct flexus_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: flexus_serialout + ****************************************************************************/ + +static inline void flexus_serialout(struct flexus_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: flexus_restoreusartint + ****************************************************************************/ + +static inline void flexus_restoreusartint(struct flexus_dev_s *priv, + uint32_t imr) +{ + /* Restore the previous interrupt state (assuming all interrupts disabled) */ + + flexus_serialout(priv, SAM_FLEXUS_IER_OFFSET, imr); +} + +/**************************************************************************** + * Name: flexus_disableallints + ****************************************************************************/ + +static void flexus_disableallints(struct flexus_dev_s *priv, uint32_t *imr) +{ + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + + /* Return the current interrupt state */ + + if (imr) + { + *imr = flexus_serialin(priv, SAM_FLEXUS_IMR_OFFSET); + } + + /* Disable all interrupts */ + + flexus_serialout(priv, SAM_FLEXUS_IDR_OFFSET, FLEXUS_INT_ALLINTS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: flexus_interrupt + * + * Description: + * This is the common USART interrupt handler. It should call + * uart_transmitchars or uart_receivechar to perform the appropriate + * data transfers. + * + ****************************************************************************/ + +static int flexus_interrupt(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv; + uint32_t pending; + uint32_t imr; + int passes; + bool handled; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct flexus_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the UART/USART status (we are only interested in the unmasked interrupts). */ + + priv->sr = flexus_serialin(priv, SAM_FLEXUS_CSR_OFFSET); /* Save for error reporting */ + imr = flexus_serialin(priv, SAM_FLEXUS_IMR_OFFSET); /* Interrupt mask */ + pending = priv->sr & imr; /* Mask out disabled interrupt sources */ + + /* Handle an incoming, receive byte. RXRDY: At least one complete character + * has been received and US_RHR has not yet been read. + */ + + if ((pending & FLEXUS_INT_RXRDY) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes. XRDY: There is no character in the + * US_THR. + */ + + if ((pending & FLEXUS_INT_TXRDY) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: flexus*_interrupt + * + * Description: + * This is the specific UART/USART interrupt handler. These simply map + * the interrupt to the device-specific data and passes control to the + * common interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USART0_ISUART +static int flexus0_interrupt(int irq, void *context) +{ + return flexus_interrupt(&g_flexus0port); +} +#endif +#ifdef CONFIG_USART1_ISUART +static int flexus1_interrupt(int irq, void *context) +{ + return flexus_interrupt(&g_flexus1port); +} +#endif +#ifdef CONFIG_USART2_ISUART +static int flexus2_interrupt(int irq, void *context) +{ + return flexus_interrupt(&g_flexus2port); +} +#endif +#ifdef CONFIG_USART3_ISUART +static int flexus3_interrupt(int irq, void *context) +{ + return flexus_interrupt(&g_flexus3port); +} +#endif +#ifdef CONFIG_USART4_ISUART +static int flexus4_interrupt(int irq, void *context) +{ + return flexus_interrupt(&g_flexus4port); +} +#endif + +/**************************************************************************** + * Name: flexus_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int flexus_setup(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled and the pins were configured in sam_lowsetup(). + */ + + /* The shutdown method will put the UART in a known, disabled state */ + + flexus_shutdown(dev); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + /* "Setting the USART to operate with hardware handshaking is performed by + * writing the USART_MODE field in the Mode Register (US_MR) to the value + * 0x2. ... Using this mode requires using the PDC or DMAC channel for + * reception. The transmitter can handle hardware handshaking in any case." + */ + + if (priv->flowc) + { + /* Enable hardware flow control and MCK as the timing source */ + + regval = (FLEXUS_MR_MODE_HWHS | SAM_MR_USCLKS | FLEXUS_MR_CHMODE_NORMAL); + } + else +#endif + { + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source + */ + + regval = (FLEXUS_MR_MODE_NORMAL | SAM_MR_USCLKS | FLEXUS_MR_CHMODE_NORMAL); + } + + /* OR in settings for the selected number of bits */ + + if (priv->bits == 5) + { + regval |= FLEXUS_MR_CHRL_5BITS; /* 5 bits */ + } + else if (priv->bits == 6) + { + regval |= FLEXUS_MR_CHRL_6BITS; /* 6 bits */ + } + else if (priv->bits == 7) + { + regval |= FLEXUS_MR_CHRL_7BITS; /* 7 bits */ + } + else if (priv->bits == 9) + { + regval |= FLEXUS_MR_MODE9; /* 9 bits */ + } + else /* if (priv->bits == 8) */ + { + regval |= FLEXUS_MR_CHRL_8BITS; /* 8 bits (default) */ + } + + /* OR in settings for the selected parity */ + + if (priv->parity == 1) + { + regval |= FLEXUS_MR_PAR_ODD; + } + else if (priv->parity == 2) + { + regval |= FLEXUS_MR_PAR_EVEN; + } + else + { + regval |= FLEXUS_MR_PAR_NONE; + } + + /* OR in settings for the number of stop bits */ + + if (priv->stopbits2) + { + regval |= FLEXUS_MR_NBSTOP_2; + } + else + { + regval |= FLEXUS_MR_NBSTOP_1; + } + + /* And save the new mode register value */ + + flexus_serialout(priv, SAM_FLEXUS_MR_OFFSET, regval); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower USART clocks. + */ + + regval = (SAM_USART_CLOCK + (priv->baud << 3)) / (priv->baud << 4); + flexus_serialout(priv, SAM_FLEXUS_BRGR_OFFSET, regval); + + /* Enable receiver & transmitter */ + + flexus_serialout(priv, SAM_FLEXUS_CR_OFFSET, (FLEXUS_CR_RXEN | FLEXUS_CR_TXEN)); +#endif + return OK; +} + +/**************************************************************************** + * Name: flexus_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void flexus_shutdown(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + + /* Reset and disable receiver and transmitter */ + + flexus_serialout(priv, SAM_FLEXUS_CR_OFFSET, + (FLEXUS_CR_RSTRX | FLEXUS_CR_RSTTX | FLEXUS_CR_RXDIS | + FLEXUS_CR_TXDIS)); + + /* Disable all interrupts */ + + flexus_disableallints(priv, NULL); +} + +/**************************************************************************** + * Name: flexus_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int flexus_attach(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: flexus_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void flexus_detach(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: flexus_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int flexus_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct flexus_dev_s *user = (struct flexus_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct flexus_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Return baud */ + + cfsetispeed(termiosp, priv->baud); + + /* Return parity */ + + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; + + /* Return flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= (priv->flowc) ? (CCTS_OFLOW | CRTS_IFLOW): 0; +#endif + /* Return number of bits */ + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + default: + case 8: + termiosp->c_cflag |= CS8; + break; + + case 9: + termiosp->c_cflag |= CS8 /* CS9 */; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + uint32_t baud; + uint32_t imr; + uint8_t parity; + uint8_t nbits; + bool stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; +#endif + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Decode baud. */ + + ret = OK; + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + nbits = 5; + break; + + case CS6: + nbits = 6; + break; + + case CS7: + nbits = 7; + break; + + case CS8: + nbits = 8; + break; +#if 0 + case CS9: + nbits = 9; + break; +#endif + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) != 0; + + /* Decode flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + flowc = (termiosp->c_cflag & (CCTS_OFLOW | CRTS_IFLOW)) != 0; +#endif + /* Verify that all settings are valid before committing */ + + if (ret == OK) + { + /* Commit */ + + priv->baud = baud; + priv->parity = parity; + priv->bits = nbits; + priv->stopbits2 = stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flowc = flowc; +#endif + /* Effect the changes immediately - note that we do not + * implement TCSADRAIN / TCSAFLUSH + */ + + flexus_disableallints(priv, &imr); + ret = flexus_setup(dev); + + /* Restore the interrupt state */ + + flexus_restoreusartint(priv, imr); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: flexus_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int flexus_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + + /* Return the error information in the saved status */ + + *status = priv->sr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return (int)(flexus_serialin(priv, SAM_FLEXUS_RHR_OFFSET) & 0xff); +} + +/**************************************************************************** + * Name: flexus_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void flexus_rxint(struct uart_dev_s *dev, bool enable) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + flexus_serialout(priv, SAM_FLEXUS_IER_OFFSET, FLEXUS_INT_RXRDY); +#endif + } + else + { + flexus_serialout(priv, SAM_FLEXUS_IDR_OFFSET, FLEXUS_INT_RXRDY); + } +} + +/**************************************************************************** + * Name: flexus_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool flexus_rxavailable(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + return ((flexus_serialin(priv, SAM_FLEXUS_CSR_OFFSET) & FLEXUS_INT_RXRDY) != 0); +} + +/**************************************************************************** + * Name: flexus_send + * + * Description: + * This method will send one byte on the UART/USART + * + ****************************************************************************/ + +static void flexus_send(struct uart_dev_s *dev, int ch) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + flexus_serialout(priv, SAM_FLEXUS_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: flexus_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void flexus_txint(struct uart_dev_s *dev, bool enable) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + flexus_serialout(priv, SAM_FLEXUS_IER_OFFSET, FLEXUS_INT_TXRDY); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + +#endif + } + else + { + /* Disable the TX interrupt */ + + flexus_serialout(priv, SAM_FLEXUS_IDR_OFFSET, FLEXUS_INT_TXRDY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: flexus_txready + * + * Description: + * Return true if the transmit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool flexus_txready(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + return ((flexus_serialin(priv, SAM_FLEXUS_CSR_OFFSET) & FLEXUS_INT_TXRDY) != 0); +} + +/**************************************************************************** + * Name: flexus_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool flexus_txempty(struct uart_dev_s *dev) +{ + struct flexus_dev_s *priv = (struct flexus_dev_s *)dev->priv; + return ((flexus_serialin(priv, SAM_FLEXUS_CSR_OFFSET) & FLEXUS_INT_TXEMPTY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: flexus_earlyserialinit + * + * Description: + * Performs the low level Flexcom USART initialization early so that the + * Flexcom serial console will be available during bootup. This must be + * called before flexus_serialinit. + * + ****************************************************************************/ + +void flexus_earlyserialinit(void) +{ + /* NOTE: All PIO configuration for the USARTs was performed in + * sam_lowsetup + */ + + /* Disable the USART */ + +#ifdef TTYFC0_DEV + /* Select USART mode for the Flexcom */ + + flexus_serialout(TTYFC0_DEV.priv, SAM_FLEX_MR_OFFSET, FLEX_MR_OPMODE_USART); + + /* Disable the USART */ + + flexus_disableallints(TTYFC0_DEV.priv, NULL); +#endif +#ifdef TTYFC1_DEV + /* Select USART mode for the Flexcom */ + + flexus_serialout(TTYFC1_DEV.priv, SAM_FLEX_MR_OFFSET, FLEX_MR_OPMODE_USART); + + /* Disable the USART */ + + flexus_disableallints(TTYFC1_DEV.priv, NULL); +#endif +#ifdef TTYFC2_DEV + /* Select USART mode for the Flexcom */ + + flexus_serialout(TTYFC2_DEV.priv, SAM_FLEX_MR_OFFSET, FLEX_MR_OPMODE_USART); + + /* Disable the USART */ + + flexus_disableallints(TTYFC2_DEV.priv, NULL); +#endif +#ifdef TTYFC3_DEV + /* Select USART mode for the Flexcom */ + + flexus_serialout(TTYFC3_DEV.priv, SAM_FLEX_MR_OFFSET, FLEX_MR_OPMODE_USART); + + /* Disable the USART */ + + flexus_disableallints(TTYFC3_DEV.priv, NULL); +#endif +#ifdef TTYFC4_DEV + /* Select USART mode for the Flexcom */ + + flexus_serialout(TTYFC4_DEV.priv, SAM_FLEX_MR_OFFSET, FLEX_MR_OPMODE_USART); + + /* Disable the USART */ + + flexus_disableallints(TTYFC4_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef SAMA5_HAVE_FLEXCOM_CONSOLE + CONSOLE_DEV.isconsole = true; + flexus_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: flexus_serialinit + * + * Description: + * Register Flexcom serial console and serial ports. This assumes that + * flexus_earlyserialinit was called previously. + * + ****************************************************************************/ + +void flexus_serialinit(void) +{ + /* Register the console */ + +#ifdef SAMA5_HAVE_FLEXCOM_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs/USARTs */ + +#ifdef TTYFC0_DEV + (void)uart_register("/dev/ttyFC0", &TTYFC0_DEV); +#endif +#ifdef TTYFC1_DEV + (void)uart_register("/dev/ttyFC1", &TTYFC1_DEV); +#endif +#ifdef TTYFC2_DEV + (void)uart_register("/dev/ttyFC2", &TTYFC2_DEV); +#endif +#ifdef TTYFC3_DEV + (void)uart_register("/dev/ttyFC3", &TTYFC3_DEV); +#endif +#ifdef TTYFC4_DEV + (void)uart_register("/dev/ttyFC4", &TTYFC4_DEV); +#endif +} + +#endif /* USE_SERIALDRIVER */ +#endif /* SAMA5_HAVE_FLEXCOM_USART */ diff --git a/arch/arm/src/sama5/sam_freerun.c b/arch/arm/src/sama5/sam_freerun.c new file mode 100644 index 0000000000000000000000000000000000000000..18d2556bbf5d07e8c27833ac9f6af1c4fa1064da --- /dev/null +++ b/arch/arm/src/sama5/sam_freerun.c @@ -0,0 +1,336 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_freerun.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam_freerun.h" + +#ifdef CONFIG_SAMA5_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_freerun_handler + * + * Description: + * Timer interrupt callback. When the freerun timer counter overflows, + * this interrupt will occur. We will just increment an overflow count. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_freerun_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_freerun_s *freerun = (struct sam_freerun_s *)arg; + DEBUGASSERT(freerun && freerun->overflow < UINT16_MAX); + freerun->overflow++; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t divisor; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(freerun && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_divisor(frequency, &divisor, &cmr); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_divisor failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, divisor=%u, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)divisor, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * CMR_TCCLKS - Returned by sam_tc_divisor + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=0 - Don't stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UP - TC_CV is incremented from 0 to 0xffffffff + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NONE | TC_CMR_EEVTEDG_NONE | TC_CMR_EEVT_TIOB | + TC_CMR_WAVSEL_UP | TC_CMR_WAVE | TC_CMR_ACPA_NONE | + TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | TC_CMR_ASWTRG_NONE | + TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | TC_CMR_BEEVT_NONE | + TC_CMR_BSWTRG_NONE); + + freerun->tch = sam_tc_allocate(chan, cmr); + if (!freerun->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + freerun->chan = chan; + freerun->running = false; + freerun->overflow = 0; + + /* Set up to receive the callback when the counter overflow occurs */ + + (void)sam_tc_attach(freerun->tch, sam_freerun_handler, freerun, + TC_INT_COVFS); + + /* Start the counter */ + + sam_tc_start(freerun->tch); + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time from the free-running + * timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts) +{ + uint64_t usec; + uint32_t counter; + uint32_t verify; + uint32_t sr; + uint32_t overflow; + uint32_t sec; + irqstate_t flags; + + DEBUGASSERT(freerun && freerun->tch && ts); + + /* Temporarily disable the overflow counter. NOTE that we have to be careful + * here because sam_tc_getpending() will reset the pending interrupt status. + * If we do not handle the overflow here then, it will be lost. + */ + + flags = enter_critical_section(); + overflow = freerun->overflow; + counter = sam_tc_getcounter(freerun->tch); + sr = sam_tc_getpending(freerun->tch); + verify = sam_tc_getcounter(freerun->tch); + + /* If an interrupt was pending before we re-enabled interrupts, + * then the overflow needs to be incremented. + */ + + if ((sr & TC_INT_COVFS) != 0) + { + /* Increment the overflow count and use the value of the + * guaranteed to be AFTER the overflow occurred. + */ + + overflow++; + counter = verify; + + /* Update freerun overflow counter. */ + + freerun->overflow = overflow; + } + + leave_critical_section(flags); + + tcvdbg("counter=%lu (%lu) overflow=%lu, sr=%08lx\n", + (unsigned long)counter, (unsigned long)verify, + (unsigned long)overflow, (unsigned long)sr); + + /* Convert the whole thing to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) / + sam_tc_divfreq(freerun->tch); + + /* And return the value of the timer */ + + sec = (uint32_t)(usec / USEC_PER_SEC); + ts->tv_sec = sec; + ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + tcvdbg("usec=%llu ts=(%lu, %lu)\n", + usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun) +{ + DEBUGASSERT(freerun && freerun->tch); + + /* Now we can disable the timer interrupt and disable the timer. */ + + sam_tc_attach(freerun->tch, NULL, NULL, 0); + sam_tc_stop(freerun->tch); + + /* Free the timer */ + + sam_tc_free(freerun->tch); + freerun->tch = NULL; + return OK; +} + +#endif /* CONFIG_SAMA5_ONESHOT */ diff --git a/arch/arm/src/sama5/sam_freerun.h b/arch/arm/src/sama5/sam_freerun.h new file mode 100644 index 0000000000000000000000000000000000000000..22ef8194a895bb081d9304945f12e842afd2b52d --- /dev/null +++ b/arch/arm/src/sama5/sam_freerun.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_freerun.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_FREERUN_H +#define __ARCH_ARM_SRC_SAMA5_SAM_FREERUN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_tc.h" + +#ifdef CONFIG_SAMA5_FREERUN + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FREERUN_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The freerun client must allocate an instance of this structure and called + * sam_freerun_initialize() before using the freerun facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_freerun_s +{ + uint8_t chan; /* The timer/counter in use */ + bool running; /* True: the timer is running */ + uint16_t overflow; /* Timer counter overflow */ + TC_HANDLE tch; /* Handle returned by sam_tc_initialize() */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution); + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts); + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_FREERUN */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_FREERUN_H */ diff --git a/arch/arm/src/sama5/sam_gf1024.c b/arch/arm/src/sama5/sam_gf1024.c new file mode 100644 index 0000000000000000000000000000000000000000..574bcf7545e6436ae857873863e74e42a1b19c9e --- /dev/null +++ b/arch/arm/src/sama5/sam_gf1024.c @@ -0,0 +1,2119 @@ +/********************************************************************************************************************************** + * arch/arm/src/sama5/sam_gf512.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Taken from Atmel NoOS sample code. The Atmel sample code has a BSD compatible license that requires this copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************************************************/ + +/********************************************************************************************************************************** + * Included Files + **********************************************************************************************************************************/ + +#include +#include + +#include + +#include "sam_pmecc.h" + +#if defined(CONFIG_SAMA5_HAVE_PMECC) && !defined(CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES) + +/********************************************************************************************************************************** + * Public Data + **********************************************************************************************************************************/ + +/* Gallois Field tables for 1024 bytes sectors. First raw is "index_of" and second one is "alpha_to" */ + +const uint16_t pmecc_gf_1024[2][PMECC_GF_SIZEOF_1024] = +{ + /* "index_of" table */ + { + 0xffff, 0x0000, 0x0001, 0x0572, 0x0002, 0x0ae4, 0x0573, 0x015b, 0x0003, 0x06cd, 0x0ae5, 0x1ad9, 0x0574, 0x012e, 0x015c, 0x1056, + 0x0004, 0x15c8, 0x06ce, 0x288d, 0x0ae6, 0x02b6, 0x1ada, 0x06a0, 0x0575, 0x2ed2, 0x012f, 0x0c3f, 0x015d, 0x204b, 0x1057, 0x3812, + 0x0005, 0x3d84, 0x15c9, 0x0289, 0x06cf, 0x347d, 0x288e, 0x25bd, 0x0ae7, 0x10d1, 0x02b7, 0x3444, 0x1adb, 0x11b1, 0x06a1, 0x109c, + 0x0576, 0x1c34, 0x2ed3, 0x1b3a, 0x0130, 0x2dff, 0x0c40, 0x2238, 0x015e, 0x0c12, 0x204c, 0x3d67, 0x1058, 0x3f47, 0x3813, 0x0828, + 0x0006, 0x0d9a, 0x3d85, 0x15d2, 0x15ca, 0x35b2, 0x028a, 0x04ba, 0x06d0, 0x1f3c, 0x347e, 0x1184, 0x288f, 0x02da, 0x25be, 0x302d, + 0x0ae8, 0x025c, 0x10d2, 0x21a6, 0x02b8, 0x20ac, 0x3445, 0x034f, 0x1adc, 0x27aa, 0x11b2, 0x2bb3, 0x06a2, 0x396d, 0x109d, 0x3371, + 0x0577, 0x3bd2, 0x1c35, 0x02f7, 0x2ed4, 0x07fb, 0x1b3b, 0x1a8e, 0x0131, 0x2b2f, 0x2e00, 0x0411, 0x0c41, 0x0beb, 0x2239, 0x39ef, + 0x015f, 0x160e, 0x0c13, 0x0012, 0x204d, 0x363b, 0x3d68, 0x1723, 0x1059, 0x29e8, 0x3f48, 0x1643, 0x3814, 0x39b6, 0x0829, 0x1c07, + 0x0007, 0x2179, 0x0d9b, 0x2142, 0x3d86, 0x2393, 0x15d3, 0x3f28, 0x15cb, 0x1305, 0x35b3, 0x2f5a, 0x028b, 0x1bb5, 0x04bb, 0x2310, + 0x06d1, 0x270d, 0x1f3d, 0x1b80, 0x347f, 0x0584, 0x1185, 0x1d8f, 0x2890, 0x1c95, 0x02db, 0x3940, 0x25bf, 0x27e8, 0x302e, 0x3bad, + 0x0ae9, 0x3ec2, 0x025d, 0x0145, 0x10d3, 0x0869, 0x21a7, 0x3a22, 0x02b9, 0x2000, 0x20ad, 0x22b9, 0x3446, 0x0367, 0x0350, 0x0d6d, + 0x1add, 0x3f61, 0x27ab, 0x00a3, 0x11b3, 0x3000, 0x2bb4, 0x115d, 0x06a3, 0x10bd, 0x396e, 0x30a1, 0x109e, 0x0983, 0x3372, 0x37ad, + 0x0578, 0x3048, 0x3bd3, 0x130c, 0x1c36, 0x1b44, 0x02f8, 0x29bb, 0x2ed5, 0x0a2c, 0x07fc, 0x3744, 0x1b3c, 0x11f7, 0x1a8f, 0x3b24, + 0x0132, 0x359f, 0x2b30, 0x0488, 0x2e01, 0x3cf5, 0x0412, 0x084c, 0x0c42, 0x12ec, 0x0bec, 0x24ae, 0x223a, 0x16f6, 0x39f0, 0x122c, + 0x0160, 0x38e3, 0x160f, 0x09ac, 0x0c14, 0x03a2, 0x0013, 0x3edf, 0x204e, 0x03e4, 0x363c, 0x2d1c, 0x3d69, 0x3125, 0x1724, 0x14c0, + 0x105a, 0x1bca, 0x29e9, 0x07ce, 0x3f49, 0x2718, 0x1644, 0x193c, 0x3815, 0x08c1, 0x39b7, 0x35d8, 0x082a, 0x2d6b, 0x1c08, 0x261e, + 0x0008, 0x2b90, 0x217a, 0x0d46, 0x0d9c, 0x111b, 0x2143, 0x32dd, 0x3d87, 0x2b75, 0x2394, 0x0e33, 0x15d4, 0x3b4a, 0x3f29, 0x3e95, + 0x15cc, 0x056c, 0x1306, 0x213c, 0x35b4, 0x0d40, 0x2f5b, 0x26e5, 0x028c, 0x1eae, 0x1bb6, 0x327a, 0x04bc, 0x30fc, 0x2311, 0x2c8a, + 0x06d2, 0x0076, 0x270e, 0x3e55, 0x1f3e, 0x0f1e, 0x1b81, 0x3d2d, 0x3480, 0x0452, 0x0585, 0x1ab7, 0x1186, 0x3dd4, 0x1d90, 0x0914, + 0x2891, 0x1a32, 0x1c96, 0x2baa, 0x02dc, 0x1be9, 0x3941, 0x3697, 0x25c0, 0x2e82, 0x27e9, 0x0956, 0x302f, 0x328e, 0x3bae, 0x1665, + 0x0aea, 0x1da5, 0x3ec3, 0x35ba, 0x025e, 0x187e, 0x0146, 0x0f57, 0x10d4, 0x2f2d, 0x086a, 0x3796, 0x21a8, 0x1e5b, 0x3a23, 0x20b6, + 0x02ba, 0x0097, 0x2001, 0x2366, 0x20ae, 0x3025, 0x22ba, 0x1769, 0x3447, 0x016d, 0x0368, 0x0f9e, 0x0351, 0x3cb6, 0x0d6e, 0x13d5, + 0x1ade, 0x179e, 0x3f62, 0x072b, 0x27ac, 0x3b66, 0x00a4, 0x1c68, 0x11b4, 0x19c3, 0x3001, 0x185e, 0x2bb5, 0x2a20, 0x115e, 0x2b43, + 0x06a4, 0x0d33, 0x10be, 0x3b11, 0x396f, 0x09fa, 0x30a2, 0x16ed, 0x109f, 0x0dbe, 0x0984, 0x0242, 0x3373, 0x1d62, 0x37ae, 0x0268, + 0x0579, 0x2d0e, 0x3049, 0x26eb, 0x3bd4, 0x26b4, 0x130d, 0x0a5e, 0x1c37, 0x049b, 0x1b45, 0x2102, 0x02f9, 0x2c47, 0x29bc, 0x2905, + 0x2ed6, 0x2882, 0x0a2d, 0x3ac8, 0x07fd, 0x1841, 0x3745, 0x2127, 0x1b3d, 0x35ab, 0x11f8, 0x1877, 0x1a90, 0x34cc, 0x3b25, 0x08a8, + 0x0133, 0x0120, 0x35a0, 0x0c2e, 0x2b31, 0x04aa, 0x0489, 0x2d5a, 0x2e02, 0x2b20, 0x3cf6, 0x2207, 0x0413, 0x3eb2, 0x084d, 0x1a21, + 0x0c43, 0x081b, 0x12ed, 0x2c7f, 0x0bed, 0x20f2, 0x24af, 0x03b7, 0x223b, 0x2301, 0x16f7, 0x1760, 0x39f1, 0x2a10, 0x122d, 0x0af6, + 0x0161, 0x3d1f, 0x38e4, 0x2f61, 0x1610, 0x11ff, 0x09ad, 0x0ef5, 0x0c15, 0x172d, 0x03a3, 0x162f, 0x0014, 0x3613, 0x3ee0, 0x0b0e, + 0x204f, 0x20a0, 0x03e5, 0x04d4, 0x363d, 0x0615, 0x2d1d, 0x2218, 0x3d6a, 0x16cf, 0x3126, 0x370d, 0x1725, 0x0a24, 0x14c1, 0x3572, + 0x105b, 0x3d11, 0x1bcb, 0x0435, 0x29ea, 0x06b7, 0x07cf, 0x01b4, 0x3f4a, 0x3f94, 0x2719, 0x11ca, 0x1645, 0x3188, 0x193d, 0x0ddb, + 0x3816, 0x12df, 0x08c2, 0x1a3f, 0x39b8, 0x284e, 0x35d9, 0x08d9, 0x082b, 0x00ae, 0x2d6c, 0x2572, 0x1c09, 0x282b, 0x261f, 0x2097, + 0x0009, 0x2609, 0x2b91, 0x1eb4, 0x217b, 0x2e1a, 0x0d47, 0x2d9d, 0x0d9d, 0x3769, 0x111c, 0x0620, 0x2144, 0x2ae4, 0x32de, 0x1447, + 0x3d88, 0x085f, 0x2b76, 0x1851, 0x2395, 0x1fb1, 0x0e34, 0x0052, 0x15d5, 0x0e4b, 0x3b4b, 0x3ca0, 0x3f2a, 0x1387, 0x3e96, 0x2dc0, + 0x15cd, 0x02f2, 0x056d, 0x0284, 0x1307, 0x09a7, 0x213d, 0x0140, 0x35b5, 0x0726, 0x0d41, 0x3e50, 0x2f5c, 0x0430, 0x26e6, 0x0c29, + 0x028d, 0x134d, 0x1eaf, 0x027f, 0x1bb7, 0x068d, 0x327b, 0x36fa, 0x04bd, 0x05e3, 0x30fd, 0x0507, 0x2312, 0x173c, 0x2c8b, 0x1d0b, + 0x06d3, 0x1e28, 0x0077, 0x0292, 0x270f, 0x34d3, 0x3e56, 0x31a3, 0x1f3f, 0x1467, 0x0f1f, 0x3406, 0x1b82, 0x1a4b, 0x3d2e, 0x1771, + 0x3481, 0x1080, 0x0453, 0x2c3a, 0x0586, 0x2b16, 0x1ab8, 0x3b85, 0x1187, 0x17ac, 0x3dd5, 0x1c9f, 0x1d91, 0x1ba1, 0x0915, 0x1256, + 0x2892, 0x3ae4, 0x1a33, 0x1352, 0x1c97, 0x101e, 0x2bab, 0x0f96, 0x02dd, 0x22ec, 0x1bea, 0x1c41, 0x3942, 0x3c7f, 0x3698, 0x3143, + 0x25c1, 0x389f, 0x2e83, 0x2612, 0x27ea, 0x0a46, 0x0957, 0x090a, 0x3030, 0x278a, 0x328f, 0x1d35, 0x3baf, 0x3982, 0x1666, 0x0b87, + 0x0aeb, 0x3929, 0x1da6, 0x3280, 0x3ec4, 0x2c5d, 0x35bb, 0x2e59, 0x025f, 0x0fd0, 0x187f, 0x375a, 0x0147, 0x161b, 0x0f58, 0x2c26, + 0x10d5, 0x2e77, 0x2f2e, 0x3a15, 0x086b, 0x291f, 0x3797, 0x31b9, 0x21a9, 0x0bc5, 0x1e5c, 0x0a0d, 0x3a24, 0x2674, 0x20b7, 0x053f, + 0x02bb, 0x0e1a, 0x0098, 0x36ff, 0x2002, 0x1ec2, 0x2367, 0x3a3e, 0x20af, 0x0b07, 0x3026, 0x3b1d, 0x22bb, 0x1de9, 0x176a, 0x23fd, + 0x3448, 0x0d19, 0x016e, 0x2df4, 0x0369, 0x003b, 0x0f9f, 0x078f, 0x0352, 0x2699, 0x3cb7, 0x04fd, 0x0d6f, 0x0bcf, 0x13d6, 0x1db3, + 0x1adf, 0x1068, 0x179f, 0x1bbc, 0x3f63, 0x1a97, 0x072c, 0x2f82, 0x27ad, 0x357a, 0x3b67, 0x2873, 0x00a5, 0x1cd2, 0x1c69, 0x2404, + 0x11b5, 0x25fd, 0x19c4, 0x0d8d, 0x3002, 0x31f1, 0x185f, 0x1d25, 0x2bb6, 0x0929, 0x2a21, 0x16de, 0x115f, 0x30ab, 0x2b44, 0x2664, + 0x06a5, 0x3733, 0x0d34, 0x0692, 0x10bf, 0x11a0, 0x3b12, 0x108c, 0x3970, 0x32cc, 0x09fb, 0x395e, 0x30a3, 0x3d00, 0x16ee, 0x0a1c, + 0x10a0, 0x1f93, 0x0dbf, 0x2ec6, 0x0985, 0x34dc, 0x0243, 0x0425, 0x3374, 0x052e, 0x1d63, 0x3092, 0x37af, 0x2779, 0x0269, 0x110b, + 0x057a, 0x0baf, 0x2d0f, 0x3102, 0x304a, 0x12b8, 0x26ec, 0x08e4, 0x3bd5, 0x384f, 0x26b5, 0x315b, 0x130e, 0x1aeb, 0x0a5f, 0x168d, + 0x1c38, 0x0408, 0x049c, 0x2eb9, 0x1b46, 0x126a, 0x2103, 0x00bd, 0x02fa, 0x01fe, 0x2c48, 0x30e7, 0x29bd, 0x13a5, 0x2906, 0x0ccd, + 0x2ed7, 0x31fc, 0x2883, 0x050c, 0x0a2e, 0x206a, 0x3ac9, 0x366e, 0x07fe, 0x0ac6, 0x1842, 0x2420, 0x3746, 0x37ec, 0x2128, 0x1218, + 0x1b3e, 0x238d, 0x35ac, 0x0ade, 0x11f9, 0x26ae, 0x1878, 0x1115, 0x1a91, 0x2c57, 0x34cd, 0x2e14, 0x3b26, 0x3908, 0x08a9, 0x12b2, + 0x0134, 0x1bd7, 0x0121, 0x04c2, 0x35a1, 0x08af, 0x0c2f, 0x3800, 0x2b32, 0x1dd7, 0x04ab, 0x33f4, 0x048a, 0x0ec8, 0x2d5b, 0x22c2, + 0x2e03, 0x2414, 0x2b21, 0x1fa4, 0x3cf7, 0x311c, 0x2208, 0x1700, 0x0414, 0x3c09, 0x3eb3, 0x1026, 0x084e, 0x2350, 0x1a22, 0x215b, + 0x0c44, 0x0eda, 0x081c, 0x05e8, 0x12ee, 0x03c8, 0x2c80, 0x001e, 0x0bee, 0x02a0, 0x20f3, 0x333a, 0x24b0, 0x18dd, 0x03b8, 0x1490, + 0x223c, 0x0e86, 0x2302, 0x2b9e, 0x16f8, 0x3b7d, 0x1761, 0x0347, 0x39f2, 0x36e0, 0x2a11, 0x09c4, 0x122e, 0x2029, 0x0af7, 0x0fd9, + 0x0162, 0x07da, 0x3d20, 0x2c90, 0x38e5, 0x390e, 0x2f62, 0x22d4, 0x1611, 0x229d, 0x1200, 0x1330, 0x09ae, 0x07b4, 0x0ef6, 0x1360, + 0x0c16, 0x3567, 0x172e, 0x12a5, 0x03a4, 0x0084, 0x1630, 0x27d5, 0x0015, 0x1c5f, 0x3614, 0x24ee, 0x3ee1, 0x038a, 0x0b0f, 0x0f6c, + 0x2050, 0x28ad, 0x20a1, 0x1d10, 0x03e6, 0x0c9d, 0x04d5, 0x3f6e, 0x363e, 0x21da, 0x0616, 0x16ac, 0x2d1e, 0x246b, 0x2219, 0x00d9, + 0x3d6b, 0x30b5, 0x16d0, 0x047d, 0x3127, 0x34ed, 0x370e, 0x2f92, 0x1726, 0x2f26, 0x0a25, 0x1f35, 0x14c2, 0x1dd0, 0x3573, 0x1460, + 0x105c, 0x3a9b, 0x3d12, 0x2317, 0x1bcc, 0x3b2c, 0x0436, 0x3f11, 0x29eb, 0x14c9, 0x06b8, 0x3552, 0x07d0, 0x2634, 0x01b5, 0x1df0, + 0x3f4b, 0x2628, 0x3f95, 0x2943, 0x271a, 0x3f06, 0x11cb, 0x23cd, 0x1646, 0x2950, 0x3189, 0x349f, 0x193e, 0x3d08, 0x0ddc, 0x26c4, + 0x3817, 0x1947, 0x12e0, 0x1741, 0x08c3, 0x1eea, 0x1a40, 0x0229, 0x39b9, 0x0eb1, 0x284f, 0x06df, 0x35da, 0x1510, 0x08da, 0x2ce1, + 0x082c, 0x3fa3, 0x00af, 0x0609, 0x2d6d, 0x28d8, 0x2573, 0x2868, 0x1c0a, 0x1cdb, 0x282c, 0x14f4, 0x2620, 0x25f5, 0x2098, 0x3597, + 0x000a, 0x3b09, 0x260a, 0x2b96, 0x2b92, 0x0512, 0x1eb5, 0x2b67, 0x217c, 0x3623, 0x2e1b, 0x224d, 0x0d48, 0x1a66, 0x2d9e, 0x3ad5, + 0x0d9e, 0x28fb, 0x376a, 0x0516, 0x111d, 0x0b7b, 0x0621, 0x0976, 0x2145, 0x2dda, 0x2ae5, 0x2982, 0x32df, 0x13f4, 0x1448, 0x2e4a, + 0x3d89, 0x18bb, 0x0860, 0x1eb9, 0x2b77, 0x1cb3, 0x1852, 0x0dcd, 0x2396, 0x079b, 0x1fb2, 0x15ee, 0x0e35, 0x3e0d, 0x0053, 0x245c, + 0x15d6, 0x3253, 0x0e4c, 0x2b6b, 0x3b4c, 0x2501, 0x3ca1, 0x1a82, 0x3f2b, 0x1287, 0x1388, 0x1423, 0x3e97, 0x0c51, 0x2dc1, 0x33e5, + 0x15ce, 0x21a2, 0x02f3, 0x000e, 0x056e, 0x2889, 0x0285, 0x1b36, 0x1308, 0x0484, 0x09a8, 0x07ca, 0x213e, 0x1b7c, 0x0141, 0x009f, + 0x35b6, 0x2362, 0x0727, 0x3b0d, 0x0d42, 0x2138, 0x3e51, 0x2ba6, 0x2f5d, 0x04d0, 0x0431, 0x1a3b, 0x26e7, 0x3ac4, 0x0c2a, 0x2c7b, + 0x028e, 0x2c36, 0x134e, 0x260e, 0x1eb0, 0x184d, 0x0280, 0x027b, 0x1bb8, 0x0d89, 0x068e, 0x2ec2, 0x327c, 0x3a11, 0x36fb, 0x2df0, + 0x04be, 0x1fa0, 0x05e4, 0x2b9a, 0x30fe, 0x2eb5, 0x0508, 0x0ada, 0x2313, 0x293f, 0x173d, 0x0605, 0x2c8c, 0x12a1, 0x1d0c, 0x0479, + 0x06d4, 0x37c1, 0x1e29, 0x0d4c, 0x0078, 0x3202, 0x0293, 0x2e69, 0x2710, 0x2846, 0x34d4, 0x28d0, 0x3e57, 0x250e, 0x31a4, 0x3e80, + 0x1f40, 0x18d2, 0x1468, 0x1a6a, 0x0f20, 0x0bb9, 0x3407, 0x0d26, 0x1b83, 0x27cb, 0x1a4c, 0x280f, 0x3d2f, 0x18a2, 0x1772, 0x1e40, + 0x3482, 0x14de, 0x1081, 0x2da2, 0x0454, 0x3d92, 0x2c3b, 0x08fc, 0x0587, 0x1f70, 0x2b17, 0x21d1, 0x1ab9, 0x2a60, 0x3b86, 0x1893, + 0x1188, 0x225d, 0x17ad, 0x3ad9, 0x3dd6, 0x1817, 0x1ca0, 0x216d, 0x1d92, 0x2d47, 0x1ba2, 0x03fe, 0x0916, 0x1cf8, 0x1257, 0x05f6, + 0x2893, 0x19d2, 0x3ae5, 0x2180, 0x1a34, 0x2edd, 0x1353, 0x2342, 0x1c98, 0x16d7, 0x101f, 0x3498, 0x2bac, 0x24a7, 0x0f97, 0x3706, + 0x02de, 0x14fc, 0x22ed, 0x3627, 0x1beb, 0x09ef, 0x1c42, 0x211a, 0x3943, 0x3504, 0x3c80, 0x2ee4, 0x3699, 0x0a03, 0x3144, 0x3a5f, + 0x25c2, 0x2e99, 0x38a0, 0x2e1f, 0x2e84, 0x2282, 0x2613, 0x1f27, 0x27eb, 0x04e1, 0x0a47, 0x199c, 0x0958, 0x1709, 0x090b, 0x120f, + 0x3031, 0x064b, 0x278b, 0x2251, 0x3290, 0x3e5f, 0x1d36, 0x29dd, 0x3bb0, 0x3c23, 0x3983, 0x274c, 0x1667, 0x1c1e, 0x0b88, 0x137d, + 0x0aec, 0x3868, 0x392a, 0x1121, 0x1da7, 0x3674, 0x3281, 0x05b6, 0x3ec5, 0x0e56, 0x2c5e, 0x0746, 0x35bc, 0x2f3c, 0x2e5a, 0x182a, + 0x0260, 0x1bff, 0x0fd1, 0x0b7f, 0x1880, 0x0471, 0x375b, 0x205d, 0x0148, 0x38d0, 0x161c, 0x3dc1, 0x0f59, 0x36cd, 0x2c27, 0x0028, + 0x10d6, 0x123f, 0x2e78, 0x0625, 0x2f2f, 0x2373, 0x3a16, 0x1917, 0x086c, 0x3e23, 0x2920, 0x0770, 0x3798, 0x3659, 0x31ba, 0x0961, + 0x21aa, 0x1cef, 0x0bc6, 0x097a, 0x1e5d, 0x342b, 0x0a0e, 0x21fb, 0x3a25, 0x062f, 0x2675, 0x01e7, 0x20b8, 0x3537, 0x0540, 0x17dc, + 0x02bc, 0x1824, 0x0e1b, 0x0da2, 0x0099, 0x3acf, 0x3700, 0x3e7a, 0x2003, 0x30bc, 0x1ec3, 0x31c9, 0x2368, 0x3386, 0x3a3f, 0x02c2, + 0x20b0, 0x3e8f, 0x0b08, 0x28ff, 0x3027, 0x1050, 0x3b1e, 0x230a, 0x22bc, 0x1687, 0x1dea, 0x135a, 0x176b, 0x1441, 0x23fe, 0x2c20, + 0x3449, 0x0ce9, 0x0d1a, 0x376e, 0x016f, 0x0a7e, 0x2df5, 0x24f7, 0x036a, 0x3be0, 0x003c, 0x1901, 0x0fa0, 0x0c69, 0x0790, 0x25dc, + 0x0353, 0x178a, 0x269a, 0x051a, 0x3cb8, 0x141a, 0x04fe, 0x3d5e, 0x0d70, 0x2aa5, 0x0bd0, 0x1038, 0x13d7, 0x2992, 0x1db4, 0x1888, + 0x1ae0, 0x154b, 0x1069, 0x32e3, 0x17a0, 0x2070, 0x1bbd, 0x259b, 0x3f64, 0x2bdc, 0x1a98, 0x3c52, 0x072d, 0x0f36, 0x2f83, 0x0da8, + 0x27ae, 0x1325, 0x357b, 0x13f8, 0x3b68, 0x3110, 0x2874, 0x32bf, 0x00a6, 0x08b9, 0x1cd3, 0x0526, 0x1c6a, 0x3c1b, 0x2405, 0x00f0, + 0x11b6, 0x25a9, 0x25fe, 0x144c, 0x19c5, 0x0b5a, 0x0d8e, 0x3e6c, 0x3003, 0x0590, 0x31f2, 0x1d75, 0x1860, 0x054f, 0x1d26, 0x093a, + 0x2bb7, 0x1a02, 0x092a, 0x2e4e, 0x2a22, 0x030f, 0x16df, 0x1e4f, 0x1160, 0x19f9, 0x30ac, 0x0812, 0x2b45, 0x38ac, 0x2665, 0x3872, + 0x06a6, 0x2f14, 0x3734, 0x2149, 0x0d35, 0x0a34, 0x0693, 0x3a03, 0x10c0, 0x3d72, 0x11a1, 0x29a9, 0x3b13, 0x3176, 0x108d, 0x0e21, + 0x3971, 0x2834, 0x32cd, 0x2dde, 0x09fc, 0x3abd, 0x395f, 0x143a, 0x30a4, 0x1b9a, 0x3d01, 0x2349, 0x16ef, 0x3966, 0x0a1d, 0x3caf, + 0x10a1, 0x26cd, 0x1f94, 0x2ae9, 0x0dc0, 0x2f9e, 0x2ec7, 0x28c2, 0x0986, 0x3de9, 0x34dd, 0x017c, 0x0244, 0x1598, 0x0426, 0x0209, + 0x3375, 0x3824, 0x052f, 0x2986, 0x1d64, 0x2516, 0x3093, 0x3ba2, 0x37b0, 0x1c72, 0x277a, 0x24d6, 0x026a, 0x21f2, 0x110c, 0x368e, + 0x057b, 0x2916, 0x0bb0, 0x2b7b, 0x2d10, 0x2426, 0x3103, 0x1e7b, 0x304b, 0x330f, 0x12b9, 0x16b6, 0x26ed, 0x2c9e, 0x08e5, 0x338c, + 0x3bd6, 0x19b9, 0x3850, 0x1cb7, 0x26b6, 0x01a8, 0x315c, 0x3056, 0x130f, 0x0e04, 0x1aec, 0x3cdb, 0x0a60, 0x0b92, 0x168e, 0x1b1e, + 0x1c39, 0x3332, 0x0409, 0x1856, 0x049d, 0x0e93, 0x2eba, 0x18f9, 0x1b47, 0x0886, 0x126b, 0x13bd, 0x2104, 0x0213, 0x00be, 0x3a6e, + 0x02fb, 0x292b, 0x01ff, 0x0dd1, 0x2c49, 0x1dc3, 0x30e8, 0x358b, 0x29be, 0x05c4, 0x13a6, 0x3cc1, 0x2907, 0x2485, 0x0cce, 0x2523, + 0x2ed8, 0x227d, 0x31fd, 0x3d8d, 0x2884, 0x1848, 0x050d, 0x1cae, 0x0a2f, 0x2f99, 0x206b, 0x0b55, 0x3aca, 0x0a79, 0x366f, 0x236e, + 0x07ff, 0x142e, 0x0ac7, 0x18bf, 0x1843, 0x07f1, 0x2421, 0x0e8e, 0x3747, 0x3c6c, 0x37ed, 0x289a, 0x2129, 0x283b, 0x1219, 0x0bff, + 0x1b3f, 0x039d, 0x238e, 0x0864, 0x35ad, 0x07f6, 0x0adf, 0x3478, 0x11fa, 0x06b2, 0x26af, 0x04a5, 0x1879, 0x3b61, 0x1116, 0x0f19, + 0x1a92, 0x119b, 0x2c58, 0x1ebd, 0x34ce, 0x1019, 0x2e15, 0x09a2, 0x3b27, 0x1ee5, 0x3909, 0x0c98, 0x08aa, 0x03c3, 0x12b3, 0x2065, + 0x0135, 0x10f9, 0x1bd8, 0x0e39, 0x0122, 0x0acc, 0x04c3, 0x3ef4, 0x35a2, 0x1c56, 0x08b0, 0x2cfc, 0x0c30, 0x22a7, 0x3801, 0x02c8, + 0x2b33, 0x0e0f, 0x1dd8, 0x3e11, 0x04ac, 0x2b84, 0x33f5, 0x2270, 0x048b, 0x0e7c, 0x0ec9, 0x36a3, 0x2d5c, 0x1530, 0x22c3, 0x0fb8, + 0x2e04, 0x3415, 0x2415, 0x0057, 0x2b22, 0x18c4, 0x1fa5, 0x1fca, 0x3cf8, 0x1508, 0x311d, 0x3180, 0x2209, 0x1f59, 0x1701, 0x1590, + 0x0415, 0x36b5, 0x3c0a, 0x2460, 0x3eb4, 0x3892, 0x1027, 0x01f2, 0x084f, 0x24c1, 0x2351, 0x285e, 0x1a23, 0x21b3, 0x215c, 0x1000, + 0x0c45, 0x2ac3, 0x0edb, 0x239a, 0x081d, 0x0804, 0x05e9, 0x1f00, 0x12ef, 0x3715, 0x03c9, 0x243e, 0x2c81, 0x0cc4, 0x001f, 0x3a45, + 0x0bef, 0x1ce3, 0x02a1, 0x079f, 0x20f4, 0x10b2, 0x333b, 0x1fbd, 0x24b1, 0x031c, 0x18de, 0x19d9, 0x03b9, 0x3978, 0x1491, 0x1925, + 0x223d, 0x17c8, 0x0e87, 0x1fb6, 0x2303, 0x1433, 0x2b9f, 0x2113, 0x16f9, 0x23c6, 0x3b7e, 0x1d1e, 0x1762, 0x2211, 0x0348, 0x0845, + 0x39f3, 0x38f1, 0x36e1, 0x15f2, 0x2a12, 0x31ac, 0x09c5, 0x20e7, 0x122f, 0x00f8, 0x202a, 0x0fe4, 0x0af8, 0x3072, 0x0fda, 0x3088, + 0x0163, 0x167d, 0x07db, 0x3b50, 0x3d21, 0x121e, 0x2c91, 0x2ceb, 0x38e6, 0x0ea1, 0x390f, 0x0aa0, 0x2f63, 0x3604, 0x22d5, 0x30c2, + 0x1612, 0x1bac, 0x229e, 0x2505, 0x1201, 0x3438, 0x1331, 0x0b6e, 0x09af, 0x0997, 0x07b5, 0x1276, 0x0ef7, 0x1aa8, 0x1361, 0x3a4e, + 0x0c17, 0x1d7f, 0x3568, 0x3ca5, 0x172f, 0x0c04, 0x12a6, 0x174f, 0x03a5, 0x15fe, 0x0085, 0x26fc, 0x1631, 0x3ff0, 0x27d6, 0x1712, + 0x0016, 0x0f8e, 0x1c60, 0x1a86, 0x3615, 0x3470, 0x24ef, 0x0273, 0x3ee2, 0x2a00, 0x038b, 0x383e, 0x0b10, 0x3ed0, 0x0f6d, 0x2cd0, + 0x2051, 0x33d5, 0x28ae, 0x15da, 0x20a2, 0x212e, 0x1d11, 0x30d3, 0x03e7, 0x34f4, 0x0c9e, 0x0b22, 0x04d6, 0x2b07, 0x3f6f, 0x2009, + 0x363f, 0x2976, 0x21db, 0x3257, 0x0617, 0x1ad0, 0x16ad, 0x2244, 0x2d1f, 0x0461, 0x246c, 0x3aec, 0x221a, 0x2de5, 0x00da, 0x23e7, + 0x3d6c, 0x2bd6, 0x30b6, 0x0e50, 0x16d1, 0x2840, 0x047e, 0x361d, 0x3128, 0x33c5, 0x34ee, 0x0e9b, 0x370f, 0x1c50, 0x2f93, 0x3309, + 0x1727, 0x0495, 0x2f27, 0x2b6f, 0x0a26, 0x12ff, 0x1f36, 0x06c7, 0x14c3, 0x2297, 0x1dd1, 0x3849, 0x3574, 0x0fca, 0x1461, 0x3763, + 0x105d, 0x263e, 0x3a9c, 0x3e9b, 0x3d13, 0x37f2, 0x2318, 0x1564, 0x1bcd, 0x33cb, 0x3b2d, 0x1d44, 0x0437, 0x3063, 0x3f12, 0x31cf, + 0x29ec, 0x3198, 0x14ca, 0x0c55, 0x06b9, 0x11eb, 0x3553, 0x1b8d, 0x07d1, 0x2d05, 0x2635, 0x1542, 0x01b6, 0x3ccc, 0x1df1, 0x3221, + 0x3f4c, 0x0ab1, 0x2629, 0x2dc5, 0x3f96, 0x289f, 0x2944, 0x2be6, 0x271b, 0x1f79, 0x3f07, 0x1137, 0x11cc, 0x0f7f, 0x23ce, 0x2fdd, + 0x1647, 0x1169, 0x2951, 0x33e9, 0x318a, 0x3f87, 0x34a0, 0x31e5, 0x193f, 0x372b, 0x3d09, 0x38db, 0x0ddd, 0x17c0, 0x26c5, 0x2e91, + 0x3818, 0x2325, 0x1948, 0x3f2f, 0x12e1, 0x374c, 0x1742, 0x1141, 0x08c4, 0x312e, 0x1eeb, 0x2c0b, 0x1a41, 0x0a6f, 0x022a, 0x1ec9, + 0x39ba, 0x1c12, 0x0eb2, 0x128b, 0x2850, 0x3366, 0x06e0, 0x17cf, 0x35db, 0x0d01, 0x1511, 0x2187, 0x08db, 0x32d4, 0x2ce2, 0x05ad, + 0x082d, 0x0de5, 0x3fa4, 0x138c, 0x00b0, 0x3c71, 0x060a, 0x01d1, 0x2d6e, 0x3fb0, 0x28d9, 0x1800, 0x2574, 0x1f61, 0x2869, 0x2434, + 0x1c0b, 0x296f, 0x1cdc, 0x1427, 0x282d, 0x3e88, 0x14f5, 0x235b, 0x2621, 0x240d, 0x25f6, 0x1079, 0x2099, 0x0090, 0x3598, 0x0255, + 0x000b, 0x07c7, 0x3b0a, 0x1a38, 0x260b, 0x2ebf, 0x2b97, 0x0602, 0x2b93, 0x224a, 0x0513, 0x297f, 0x1eb6, 0x15eb, 0x2b68, 0x1420, + 0x217d, 0x3495, 0x3624, 0x2ee1, 0x2e1c, 0x1999, 0x224e, 0x2749, 0x0d49, 0x28cd, 0x1a67, 0x280c, 0x2d9f, 0x21ce, 0x3ad6, 0x03fb, + 0x0d9f, 0x31c6, 0x28fc, 0x1357, 0x376b, 0x18fe, 0x0517, 0x1035, 0x111e, 0x0743, 0x0b7c, 0x3dbe, 0x0622, 0x076d, 0x0977, 0x01e4, + 0x2146, 0x29a6, 0x2ddb, 0x2346, 0x2ae6, 0x0179, 0x2983, 0x24d3, 0x32e0, 0x3c4f, 0x13f5, 0x0523, 0x1449, 0x1d72, 0x2e4b, 0x080f, + 0x3d8a, 0x0b52, 0x18bc, 0x2897, 0x0861, 0x04a2, 0x1eba, 0x0c95, 0x2b78, 0x16b3, 0x1cb4, 0x3cd8, 0x1853, 0x13ba, 0x0dce, 0x3cbe, + 0x2397, 0x243b, 0x079c, 0x19d6, 0x1fb3, 0x1d1b, 0x15ef, 0x0fe1, 0x0e36, 0x2cf9, 0x3e0e, 0x36a0, 0x0054, 0x317d, 0x245d, 0x285b, + 0x15d7, 0x0b1f, 0x3254, 0x3ae9, 0x0e4d, 0x0e98, 0x2b6c, 0x3846, 0x3b4d, 0x0a9d, 0x2502, 0x1273, 0x3ca2, 0x26f9, 0x1a83, 0x383b, + 0x3f2c, 0x2c08, 0x1288, 0x2184, 0x1389, 0x17fd, 0x1424, 0x1076, 0x3e98, 0x1d41, 0x0c52, 0x153f, 0x2dc2, 0x1134, 0x33e6, 0x38d8, + 0x15cf, 0x1181, 0x21a3, 0x2bb0, 0x02f4, 0x040e, 0x000f, 0x1640, 0x056f, 0x1ad6, 0x288a, 0x0c3c, 0x0286, 0x3441, 0x1b37, 0x3d64, + 0x1309, 0x3741, 0x0485, 0x24ab, 0x09a9, 0x2d19, 0x07cb, 0x35d5, 0x213f, 0x2f57, 0x1b7d, 0x393d, 0x0142, 0x22b6, 0x00a0, 0x309e, + 0x35b7, 0x3793, 0x2363, 0x0f9b, 0x0728, 0x185b, 0x3b0e, 0x023f, 0x0d43, 0x0e30, 0x2139, 0x3277, 0x3e52, 0x1ab4, 0x2ba7, 0x0953, + 0x2f5e, 0x162c, 0x04d1, 0x370a, 0x0432, 0x11c7, 0x1a3c, 0x256f, 0x26e8, 0x20ff, 0x3ac5, 0x1874, 0x0c2b, 0x2204, 0x2c7c, 0x175d, + 0x028f, 0x3403, 0x2c37, 0x1c9c, 0x134f, 0x1c3e, 0x260f, 0x1d32, 0x1eb1, 0x061d, 0x184e, 0x3c9d, 0x0281, 0x3e4d, 0x027c, 0x0504, + 0x1bb9, 0x2870, 0x0d8a, 0x16db, 0x068f, 0x395b, 0x2ec3, 0x308f, 0x327d, 0x3757, 0x3a12, 0x0a0a, 0x36fc, 0x3b1a, 0x2df1, 0x04fa, + 0x04bf, 0x33f1, 0x1fa1, 0x1023, 0x05e5, 0x3337, 0x2b9b, 0x09c1, 0x30ff, 0x3158, 0x2eb6, 0x30e4, 0x0509, 0x241d, 0x0adb, 0x2e11, + 0x2314, 0x354f, 0x2940, 0x349c, 0x173e, 0x06dc, 0x0606, 0x14f1, 0x2c8d, 0x132d, 0x12a2, 0x24eb, 0x1d0d, 0x16a9, 0x047a, 0x1f32, + 0x06d5, 0x17f6, 0x37c2, 0x1bef, 0x1e2a, 0x00c3, 0x0d4d, 0x0d0a, 0x0079, 0x325d, 0x3203, 0x3b92, 0x0294, 0x3349, 0x2e6a, 0x1790, + 0x2711, 0x3634, 0x2847, 0x09f3, 0x34d5, 0x0a3f, 0x28d1, 0x3b76, 0x3e58, 0x2eae, 0x250f, 0x1413, 0x31a5, 0x1012, 0x3e81, 0x12f8, + 0x1f41, 0x3fc0, 0x18d3, 0x1c46, 0x1469, 0x3a73, 0x1a6b, 0x201a, 0x0f21, 0x0193, 0x0bba, 0x0f09, 0x3408, 0x17e8, 0x0d27, 0x0a50, + 0x1b84, 0x32b6, 0x27cc, 0x211e, 0x1a4d, 0x2a77, 0x2810, 0x24df, 0x3d30, 0x10e0, 0x18a3, 0x2db5, 0x1773, 0x2d3a, 0x1e41, 0x39aa, + 0x3483, 0x3242, 0x14df, 0x02e2, 0x1082, 0x2109, 0x2da3, 0x0443, 0x0455, 0x21e1, 0x3d93, 0x2f72, 0x2c3c, 0x3db0, 0x08fd, 0x0359, + 0x0588, 0x1f68, 0x1f71, 0x1500, 0x2b18, 0x1ff8, 0x21d2, 0x0aff, 0x1aba, 0x07e5, 0x2a61, 0x314b, 0x3b87, 0x0e28, 0x1894, 0x39e2, + 0x1189, 0x0b9e, 0x225e, 0x22f1, 0x17ae, 0x0218, 0x3ada, 0x0393, 0x3dd7, 0x1cc1, 0x1818, 0x13c5, 0x1ca1, 0x3e3f, 0x216e, 0x1176, + 0x1d93, 0x1c84, 0x2d48, 0x362b, 0x1ba3, 0x1bf6, 0x03ff, 0x0563, 0x0917, 0x3014, 0x1cf9, 0x1b70, 0x1258, 0x2c6e, 0x05f7, 0x0150, + 0x2894, 0x3cd5, 0x19d3, 0x369d, 0x3ae6, 0x1270, 0x2181, 0x153c, 0x1a35, 0x297c, 0x2ede, 0x2809, 0x1354, 0x3dbb, 0x2343, 0x0520, + 0x1c99, 0x3c9a, 0x16d8, 0x0a07, 0x1020, 0x30e1, 0x3499, 0x24e8, 0x2bad, 0x0c39, 0x24a8, 0x393a, 0x0f98, 0x3274, 0x3707, 0x1871, + 0x02df, 0x2f6f, 0x14fd, 0x3148, 0x22ee, 0x13c2, 0x3628, 0x1b6d, 0x1bec, 0x3b8f, 0x09f0, 0x1410, 0x1c43, 0x0f06, 0x211b, 0x2db2, + 0x3944, 0x387b, 0x3505, 0x3a63, 0x3c81, 0x09d0, 0x2ee5, 0x21c2, 0x369a, 0x2806, 0x0a04, 0x3937, 0x3145, 0x140d, 0x3a60, 0x3934, + 0x25c3, 0x0b33, 0x2e9a, 0x3947, 0x38a1, 0x1b4c, 0x2e20, 0x0df5, 0x2e85, 0x3645, 0x2283, 0x387e, 0x2614, 0x1373, 0x1f28, 0x26a0, + 0x27ec, 0x257b, 0x04e2, 0x3508, 0x0a48, 0x01dc, 0x199d, 0x3079, 0x0959, 0x2454, 0x170a, 0x3a66, 0x090c, 0x1094, 0x1210, 0x0c21, + 0x3032, 0x2959, 0x064c, 0x3c84, 0x278c, 0x088b, 0x2252, 0x3357, 0x3291, 0x0667, 0x3e60, 0x09d3, 0x1d37, 0x005f, 0x29de, 0x2935, + 0x3bb1, 0x2a30, 0x3c24, 0x2ee8, 0x3984, 0x37c9, 0x274d, 0x1a77, 0x1668, 0x27b6, 0x1c1f, 0x21c5, 0x0b89, 0x13eb, 0x137e, 0x2042, + 0x0aed, 0x1457, 0x3869, 0x2e88, 0x392b, 0x30ed, 0x1122, 0x2b56, 0x1da8, 0x23ed, 0x3675, 0x3648, 0x3282, 0x114f, 0x05b7, 0x2998, + 0x3ec6, 0x38fe, 0x0e57, 0x2286, 0x2c5f, 0x2563, 0x0747, 0x3210, 0x35bd, 0x05d8, 0x2f3d, 0x3881, 0x2e5b, 0x1c28, 0x182b, 0x18ae, + 0x0261, 0x2090, 0x1c00, 0x2617, 0x0fd2, 0x3590, 0x0b80, 0x1104, 0x1881, 0x3687, 0x0472, 0x1376, 0x375c, 0x024e, 0x205e, 0x3081, + 0x0149, 0x203b, 0x38d1, 0x1f2b, 0x161d, 0x2229, 0x3dc2, 0x0d5c, 0x0f5a, 0x35c8, 0x36ce, 0x26a3, 0x2c28, 0x15bb, 0x0029, 0x071a, + 0x10d7, 0x2a95, 0x1240, 0x25c6, 0x2e79, 0x2c4e, 0x0626, 0x29f7, 0x2f30, 0x00e0, 0x2374, 0x0b36, 0x3a17, 0x0234, 0x1918, 0x13dd, + 0x086d, 0x1807, 0x3e24, 0x2e9d, 0x2921, 0x1343, 0x0771, 0x2031, 0x3799, 0x3afd, 0x365a, 0x394a, 0x31bb, 0x3d79, 0x0962, 0x2335, + 0x21ab, 0x17b8, 0x1cf0, 0x38a4, 0x0bc7, 0x1dc8, 0x097b, 0x2a08, 0x1e5e, 0x1e6b, 0x342c, 0x1b4f, 0x0a0f, 0x34be, 0x21fc, 0x1405, + 0x3a26, 0x3fe0, 0x0630, 0x2e23, 0x2676, 0x00ca, 0x01e8, 0x0785, 0x20b9, 0x2bfb, 0x3538, 0x0df8, 0x0541, 0x192f, 0x17dd, 0x3dc9, + 0x02bd, 0x25d7, 0x1825, 0x095c, 0x0e1c, 0x0204, 0x0da3, 0x0935, 0x009a, 0x2deb, 0x3ad0, 0x2457, 0x3701, 0x120a, 0x3e7b, 0x188e, + 0x2004, 0x3304, 0x30bd, 0x170d, 0x1ec4, 0x242f, 0x31ca, 0x2fd8, 0x2369, 0x0f14, 0x3387, 0x3a69, 0x3a40, 0x0840, 0x02c3, 0x158b, + 0x20b1, 0x2b3e, 0x3e90, 0x090f, 0x0b09, 0x0dd6, 0x2900, 0x1a1c, 0x3028, 0x39ea, 0x1051, 0x1097, 0x3b1f, 0x14bb, 0x230b, 0x0d68, + 0x22bd, 0x148b, 0x1688, 0x1213, 0x1deb, 0x2cdc, 0x135b, 0x00d4, 0x176c, 0x313e, 0x1442, 0x0c24, 0x23ff, 0x0a17, 0x2c21, 0x23f8, + 0x344a, 0x2649, 0x0cea, 0x27ef, 0x0d1b, 0x0300, 0x376f, 0x33a3, 0x0170, 0x2220, 0x0a7f, 0x257e, 0x2df6, 0x0684, 0x24f8, 0x1dba, + 0x036b, 0x28e0, 0x3be1, 0x04e5, 0x003d, 0x28f0, 0x1902, 0x0feb, 0x0fa1, 0x1f1b, 0x0c6a, 0x350b, 0x0791, 0x10c7, 0x25dd, 0x0739, + 0x0354, 0x1171, 0x178b, 0x0a4b, 0x269b, 0x2930, 0x051b, 0x2dad, 0x3cb9, 0x3836, 0x141b, 0x01df, 0x04ff, 0x2e0c, 0x3d5f, 0x094e, + 0x0d71, 0x3da0, 0x2aa6, 0x19a0, 0x0bd1, 0x1e31, 0x1039, 0x36c2, 0x13d8, 0x1400, 0x2993, 0x307c, 0x1db5, 0x0949, 0x1889, 0x0d63, + 0x1ae1, 0x35fa, 0x154c, 0x3294, 0x106a, 0x0cd3, 0x32e4, 0x35e4, 0x17a1, 0x3af2, 0x2071, 0x066a, 0x1bbe, 0x1556, 0x259c, 0x2aab, + 0x3f65, 0x2d51, 0x2bdd, 0x3e63, 0x1a99, 0x1b64, 0x3c53, 0x1e0b, 0x072e, 0x2659, 0x0f37, 0x09d6, 0x2f84, 0x281f, 0x0da9, 0x371e, + 0x27af, 0x300d, 0x1326, 0x1d3a, 0x357c, 0x2528, 0x13f9, 0x2bf4, 0x3b69, 0x2685, 0x3111, 0x0062, 0x2875, 0x2bc8, 0x32c0, 0x19a5, + 0x00a7, 0x0db7, 0x08ba, 0x29e1, 0x1cd4, 0x36d9, 0x0527, 0x2783, 0x1c6b, 0x2a9e, 0x3c1c, 0x2938, 0x2406, 0x2290, 0x00f1, 0x1ede, + 0x11b7, 0x3b37, 0x25aa, 0x3035, 0x25ff, 0x290c, 0x144d, 0x3bf6, 0x19c6, 0x2472, 0x0b5b, 0x295c, 0x0d8f, 0x0b47, 0x3e6d, 0x0d76, + 0x3004, 0x3fb7, 0x0591, 0x064f, 0x31f3, 0x006d, 0x1d76, 0x1236, 0x1861, 0x316a, 0x0550, 0x3c87, 0x1d27, 0x29b0, 0x093b, 0x23da, + 0x2bb8, 0x1e97, 0x1a03, 0x278f, 0x092b, 0x248a, 0x2e4f, 0x3eea, 0x2a23, 0x196f, 0x0310, 0x088e, 0x16e0, 0x1f4b, 0x1e50, 0x3da5, + 0x1161, 0x36ad, 0x19fa, 0x2255, 0x30ad, 0x0d11, 0x0813, 0x3f59, 0x2b46, 0x252f, 0x38ad, 0x335a, 0x2666, 0x1483, 0x3873, 0x1624, + 0x06a7, 0x01bf, 0x2f15, 0x166b, 0x3735, 0x13ab, 0x214a, 0x0cb2, 0x0d36, 0x0467, 0x0a35, 0x27b9, 0x0694, 0x2e3c, 0x3a04, 0x103e, + 0x10c1, 0x083a, 0x3d73, 0x1c22, 0x11a2, 0x3268, 0x29aa, 0x2819, 0x3b14, 0x22b0, 0x3177, 0x21c8, 0x108e, 0x326e, 0x0e22, 0x100c, + 0x3972, 0x152a, 0x2835, 0x0b8c, 0x32ce, 0x3cc6, 0x2ddf, 0x1aa2, 0x09fd, 0x189c, 0x3abe, 0x13ee, 0x3960, 0x3c15, 0x143b, 0x36c7, + 0x30a5, 0x266e, 0x1b9b, 0x1381, 0x3d02, 0x0384, 0x234a, 0x139f, 0x16f0, 0x27e2, 0x3967, 0x2045, 0x0a1e, 0x34c6, 0x3cb0, 0x30f6, + 0x10a2, 0x1572, 0x26ce, 0x3bb4, 0x1f95, 0x29c3, 0x2aea, 0x2725, 0x0dc1, 0x2d25, 0x2f9f, 0x2a33, 0x2ec8, 0x2dd0, 0x28c3, 0x0bd6, + 0x0987, 0x2d75, 0x3dea, 0x3c27, 0x34de, 0x29d2, 0x017d, 0x00ff, 0x0245, 0x0764, 0x1599, 0x2eeb, 0x0427, 0x11a8, 0x020a, 0x3e04, + 0x3376, 0x164f, 0x3825, 0x3987, 0x0530, 0x05c9, 0x2987, 0x0702, 0x1d65, 0x253c, 0x2517, 0x37cc, 0x3094, 0x341d, 0x3ba3, 0x1e36, + 0x37b1, 0x1b02, 0x1c73, 0x2750, 0x277b, 0x0d54, 0x24d7, 0x24cb, 0x026b, 0x3583, 0x21f3, 0x1a7a, 0x110d, 0x36f2, 0x368f, 0x2230, + 0x057c, 0x1839, 0x2917, 0x007c, 0x0bb1, 0x3108, 0x2b7c, 0x11e3, 0x2d11, 0x30d9, 0x2427, 0x3260, 0x3104, 0x2fac, 0x1e7c, 0x0a84, + 0x304c, 0x0048, 0x3310, 0x3206, 0x12ba, 0x2fb0, 0x16b7, 0x1fd8, 0x26ee, 0x0be0, 0x2c9f, 0x3b95, 0x08e6, 0x27bf, 0x338d, 0x2fbc, + 0x3bd7, 0x33bc, 0x19ba, 0x0297, 0x3851, 0x1e80, 0x1cb8, 0x1966, 0x26b7, 0x25e7, 0x01a9, 0x334c, 0x315d, 0x2ef4, 0x3057, 0x2583, + 0x1310, 0x32fa, 0x0e05, 0x2e6d, 0x1aed, 0x0a88, 0x3cdc, 0x2758, 0x0a61, 0x0ee8, 0x0b93, 0x1793, 0x168f, 0x3235, 0x1b1f, 0x10ed, + 0x1c3a, 0x3957, 0x3333, 0x06d8, 0x040a, 0x2d15, 0x1857, 0x11c3, 0x049e, 0x1d17, 0x0e94, 0x17f9, 0x2ebb, 0x1995, 0x18fa, 0x0175, + 0x1b48, 0x01d8, 0x0887, 0x37c5, 0x126c, 0x30dd, 0x13be, 0x09cc, 0x2105, 0x1ff4, 0x0214, 0x1bf2, 0x00bf, 0x0a3b, 0x3a6f, 0x2a73, + 0x02fc, 0x28ec, 0x292c, 0x1e2d, 0x0200, 0x242b, 0x0dd2, 0x2cd8, 0x2c4a, 0x133f, 0x1dc4, 0x00c6, 0x30e9, 0x255f, 0x358c, 0x2225, + 0x29bf, 0x29ce, 0x05c5, 0x0d50, 0x13a7, 0x3264, 0x3cc2, 0x0380, 0x2908, 0x0069, 0x2486, 0x0d0d, 0x0ccf, 0x1b60, 0x2524, 0x36d5, + 0x2ed9, 0x09eb, 0x227e, 0x3e5b, 0x31fe, 0x0bb5, 0x3d8e, 0x1813, 0x2885, 0x2134, 0x1849, 0x2eb1, 0x050e, 0x0b77, 0x1caf, 0x24fd, + 0x0a30, 0x3ab9, 0x2f9a, 0x2512, 0x206c, 0x310c, 0x0b56, 0x030b, 0x3acb, 0x104c, 0x0a7a, 0x1416, 0x3670, 0x046d, 0x236f, 0x3427, + 0x0800, 0x10ae, 0x142f, 0x31a8, 0x0ac8, 0x2b80, 0x18c0, 0x388e, 0x1844, 0x07ed, 0x07f2, 0x1015, 0x2422, 0x01a4, 0x0e8f, 0x1dbf, + 0x3748, 0x3362, 0x3c6d, 0x3e84, 0x37ee, 0x11e7, 0x289b, 0x3f83, 0x212a, 0x1acc, 0x283c, 0x12fb, 0x121a, 0x3434, 0x0c00, 0x346c, + 0x1b40, 0x3cf1, 0x039e, 0x2714, 0x238f, 0x0580, 0x0865, 0x2ffc, 0x35ae, 0x20a8, 0x07f7, 0x3637, 0x0ae0, 0x02b2, 0x3479, 0x2dfb, + 0x11fb, 0x0611, 0x06b3, 0x284a, 0x26b0, 0x183d, 0x04a6, 0x20ee, 0x187a, 0x3021, 0x3b62, 0x09f6, 0x1117, 0x0d3c, 0x0f1a, 0x1be5, + 0x1a93, 0x31ed, 0x119c, 0x34d8, 0x2c59, 0x291b, 0x1ebe, 0x0037, 0x34cf, 0x2b12, 0x101a, 0x0a42, 0x2e16, 0x1fad, 0x09a3, 0x0689, + 0x3b28, 0x3f02, 0x1ee6, 0x28d4, 0x390a, 0x0080, 0x0c99, 0x34e9, 0x08ab, 0x3118, 0x03c4, 0x3b79, 0x12b4, 0x1266, 0x2066, 0x26aa, + 0x0136, 0x18ef, 0x10fa, 0x0f24, 0x1bd9, 0x08ea, 0x0e3a, 0x2190, 0x0123, 0x15e0, 0x0acd, 0x0196, 0x04c4, 0x2cbe, 0x3ef5, 0x0cef, + 0x35a3, 0x1c8d, 0x1c57, 0x0bbd, 0x08b1, 0x27c3, 0x2cfd, 0x0e74, 0x0c31, 0x2f4f, 0x22a8, 0x0f0c, 0x3802, 0x1044, 0x02c9, 0x03d2, + 0x2b34, 0x0658, 0x0e10, 0x340b, 0x1dd9, 0x3391, 0x3e12, 0x207e, 0x04ad, 0x2499, 0x2b85, 0x17eb, 0x33f6, 0x39d0, 0x2271, 0x27f4, + 0x048c, 0x1781, 0x0e7d, 0x0d2a, 0x0eca, 0x2fc0, 0x36a4, 0x1c7b, 0x2d5d, 0x1249, 0x1531, 0x0a53, 0x22c4, 0x1f0e, 0x0fb9, 0x2afb, + 0x2e05, 0x34b7, 0x3416, 0x1f44, 0x2416, 0x26f2, 0x0058, 0x3e38, 0x2b23, 0x28b4, 0x18c5, 0x3fc3, 0x1fa6, 0x2558, 0x1fcb, 0x344f, + 0x3cf9, 0x3c78, 0x1509, 0x18d6, 0x311e, 0x0be4, 0x3181, 0x2a19, 0x220a, 0x3b5a, 0x1f5a, 0x1c49, 0x1702, 0x3a0a, 0x1591, 0x0c62, + 0x0416, 0x3fd1, 0x36b6, 0x146c, 0x3c0b, 0x2ca3, 0x2461, 0x0f75, 0x3eb5, 0x385a, 0x3893, 0x3a76, 0x1028, 0x3456, 0x01f3, 0x264e, + 0x0850, 0x2fc9, 0x24c2, 0x1a6e, 0x2352, 0x3b99, 0x285f, 0x08d0, 0x1a24, 0x268c, 0x21b4, 0x201d, 0x215d, 0x070d, 0x1001, 0x0f61, + 0x0c46, 0x322a, 0x2ac4, 0x3d33, 0x0edc, 0x12be, 0x239b, 0x3a84, 0x081e, 0x33db, 0x0805, 0x10e3, 0x05ea, 0x3518, 0x1f01, 0x3774, + 0x12f0, 0x03f3, 0x3716, 0x18a6, 0x03ca, 0x2fb4, 0x243f, 0x2a80, 0x2c82, 0x380a, 0x0cc5, 0x2db8, 0x0020, 0x2e42, 0x3a46, 0x1b16, + 0x0bf0, 0x23b2, 0x1ce4, 0x1776, 0x02a2, 0x16bb, 0x07a0, 0x1e14, 0x20f5, 0x1ac2, 0x10b3, 0x2d3d, 0x333c, 0x2d81, 0x1fbe, 0x33a8, + 0x24b2, 0x38b5, 0x031d, 0x1e44, 0x18df, 0x1fdc, 0x19da, 0x0328, 0x03ba, 0x1298, 0x3979, 0x39ad, 0x1492, 0x1b57, 0x1926, 0x112b, + 0x223e, 0x0b68, 0x17c9, 0x1b87, 0x0e88, 0x3050, 0x1fb7, 0x226a, 0x2304, 0x2057, 0x1434, 0x32b9, 0x2ba0, 0x0970, 0x2114, 0x0d20, + 0x16fa, 0x00b7, 0x23c7, 0x27cf, 0x3b7f, 0x004c, 0x1d1f, 0x31b3, 0x1763, 0x26df, 0x2212, 0x2121, 0x0349, 0x069a, 0x0846, 0x1d89, + 0x39f4, 0x34a8, 0x38f2, 0x1a50, 0x36e2, 0x3314, 0x15f3, 0x14a2, 0x2a13, 0x0e6e, 0x31ad, 0x2a7a, 0x09c6, 0x1fd2, 0x20e8, 0x0305, + 0x1230, 0x1e05, 0x00f9, 0x2813, 0x202b, 0x320a, 0x0fe5, 0x2fd2, 0x0af9, 0x3b70, 0x3073, 0x24e2, 0x0fdb, 0x2743, 0x3089, 0x35cf, + 0x0164, 0x3c00, 0x167e, 0x0458, 0x07dc, 0x3161, 0x3b51, 0x2764, 0x3d22, 0x200f, 0x121f, 0x21e4, 0x2c92, 0x2a48, 0x2cec, 0x0c6f, + 0x38e7, 0x1f89, 0x0ea2, 0x3d96, 0x3910, 0x2ef8, 0x0aa1, 0x331a, 0x2f64, 0x0115, 0x3605, 0x2f75, 0x22d6, 0x1671, 0x30c3, 0x2a88, + 0x1613, 0x07ac, 0x1bad, 0x2c3f, 0x229f, 0x305b, 0x2506, 0x0f2e, 0x1202, 0x2e34, 0x3439, 0x3db3, 0x1332, 0x15a2, 0x0b6f, 0x3510, + 0x09b0, 0x077b, 0x0998, 0x0900, 0x07b6, 0x2587, 0x1277, 0x1b0a, 0x0ef8, 0x20da, 0x1aa9, 0x035c, 0x1362, 0x06ee, 0x3a4f, 0x38c4, + 0x0c18, 0x3dfb, 0x1d80, 0x3486, 0x3569, 0x26bb, 0x3ca6, 0x05a4, 0x1730, 0x3f75, 0x0c05, 0x3245, 0x12a7, 0x1ed3, 0x1750, 0x0fa6, + 0x03a6, 0x1393, 0x15ff, 0x14e2, 0x0086, 0x25eb, 0x26fd, 0x36e8, 0x1632, 0x2381, 0x3ff1, 0x02e5, 0x27d7, 0x2f1b, 0x1713, 0x1a0f, + 0x0017, 0x0222, 0x0f8f, 0x1085, 0x1c61, 0x01ad, 0x1a87, 0x3ed8, 0x3616, 0x01ca, 0x3471, 0x210c, 0x24f0, 0x28bb, 0x0274, 0x1f20, + 0x3ee3, 0x06fb, 0x2a01, 0x2da6, 0x038c, 0x3350, 0x383f, 0x09ba, 0x0b11, 0x19ac, 0x3ed1, 0x0446, 0x0f6e, 0x149b, 0x2cd1, 0x0030, + 0x2052, 0x0e69, 0x33d6, 0x1abd, 0x28af, 0x3855, 0x15db, 0x2494, 0x20a3, 0x2b0d, 0x212f, 0x07e8, 0x1d12, 0x133a, 0x30d4, 0x25e2, + 0x03e8, 0x131a, 0x34f5, 0x2a64, 0x0c9f, 0x1e84, 0x0b23, 0x14a8, 0x04d7, 0x03da, 0x2b08, 0x314e, 0x3f70, 0x01c5, 0x200a, 0x2e2f, + 0x3640, 0x0662, 0x2977, 0x3b8a, 0x21dc, 0x1cbc, 0x3258, 0x018e, 0x0618, 0x3153, 0x1ad1, 0x0e2b, 0x16ae, 0x0a98, 0x2245, 0x073e, + 0x2d20, 0x2537, 0x0462, 0x1897, 0x246d, 0x196a, 0x3aed, 0x2680, 0x221b, 0x3831, 0x2de6, 0x39e5, 0x00db, 0x1e66, 0x23e8, 0x3682, + 0x3d6d, 0x3de4, 0x2bd7, 0x058b, 0x30b7, 0x3bdb, 0x0e51, 0x3e1e, 0x16d2, 0x04dc, 0x2841, 0x1f6b, 0x047f, 0x0d84, 0x361e, 0x0796, + 0x3129, 0x3fab, 0x33c6, 0x1f74, 0x34ef, 0x33c0, 0x0e9c, 0x15f9, 0x3710, 0x23c1, 0x1c51, 0x1503, 0x2f94, 0x06ad, 0x330a, 0x0881, + 0x1728, 0x3f8f, 0x0496, 0x2b1b, 0x2f28, 0x19be, 0x2b70, 0x044d, 0x0a27, 0x03df, 0x1300, 0x1ffb, 0x1f37, 0x2b2a, 0x06c8, 0x10cc, + 0x14c4, 0x0eac, 0x2298, 0x21d5, 0x1dd2, 0x029b, 0x384a, 0x0ac1, 0x3575, 0x32c7, 0x0fcb, 0x0b02, 0x1462, 0x22e7, 0x3764, 0x0721, + 0x105e, 0x2ab9, 0x263f, 0x3dda, 0x3a9d, 0x1693, 0x3e9c, 0x151a, 0x3d14, 0x0b28, 0x37f3, 0x1cc4, 0x2319, 0x329e, 0x1565, 0x3be6, + 0x1bce, 0x1d9c, 0x33cc, 0x181b, 0x3b2e, 0x3239, 0x1d45, 0x34ae, 0x0438, 0x0f4c, 0x3064, 0x13c8, 0x3f13, 0x0cb8, 0x31d0, 0x2447, + 0x29ed, 0x059a, 0x3199, 0x1ca4, 0x14cb, 0x1b23, 0x0c56, 0x3c3f, 0x06ba, 0x14ad, 0x11ec, 0x3e42, 0x3554, 0x0334, 0x1b8e, 0x04ea, + 0x07d2, 0x3921, 0x2d06, 0x2171, 0x2636, 0x10f1, 0x1543, 0x37b9, 0x01b7, 0x25cf, 0x3ccd, 0x1179, 0x1df2, 0x0e61, 0x3222, 0x09e3, + 0x3f4d, 0x1d4e, 0x0ab2, 0x118c, 0x262a, 0x0a65, 0x2dc6, 0x3aa9, 0x3f97, 0x0ca4, 0x28a0, 0x0ba1, 0x2945, 0x0759, 0x2be7, 0x0370, + 0x271c, 0x0dec, 0x1f7a, 0x2261, 0x3f08, 0x0eec, 0x1138, 0x39fa, 0x11cd, 0x276d, 0x0f80, 0x22f4, 0x23cf, 0x2150, 0x2fde, 0x399d, + 0x1648, 0x1e90, 0x116a, 0x17b1, 0x2952, 0x0b97, 0x33ea, 0x0b18, 0x318b, 0x1e89, 0x3f88, 0x021b, 0x34a1, 0x3fca, 0x31e6, 0x28e5, + 0x1940, 0x0ed3, 0x372c, 0x3add, 0x3d0a, 0x1797, 0x38dc, 0x3bcb, 0x0dde, 0x2bcf, 0x17c1, 0x0396, 0x26c6, 0x0ce2, 0x2e92, 0x2c2f, + 0x3819, 0x1dfa, 0x2326, 0x091a, 0x1949, 0x1af1, 0x3f30, 0x2f04, 0x12e2, 0x34fa, 0x374d, 0x3017, 0x1743, 0x15aa, 0x1142, 0x1907, + 0x08c5, 0x3d53, 0x312f, 0x1cfc, 0x1eec, 0x0a8c, 0x2c0c, 0x1a56, 0x1a42, 0x02d1, 0x0a70, 0x1b73, 0x022b, 0x13b1, 0x1eca, 0x198c, + 0x39bb, 0x1955, 0x1c13, 0x125b, 0x0eb3, 0x3ce0, 0x128c, 0x3c5c, 0x2851, 0x2a69, 0x3367, 0x2c71, 0x06e1, 0x2cad, 0x17d0, 0x0ff0, + 0x35dc, 0x2b4e, 0x0d02, 0x05fa, 0x1512, 0x275c, 0x2188, 0x11db, 0x08dc, 0x2d95, 0x32d5, 0x0153, 0x2ce3, 0x1e73, 0x05ae, 0x2b5f, + 0x082e, 0x3d4d, 0x0de6, 0x1d96, 0x3fa5, 0x1314, 0x138d, 0x1f83, 0x00b1, 0x03ed, 0x3c72, 0x1c87, 0x060b, 0x3ab3, 0x01d2, 0x0042, + 0x2d6f, 0x0834, 0x3fb1, 0x2d4b, 0x28da, 0x32fe, 0x1801, 0x38f8, 0x2575, 0x3c94, 0x1f62, 0x362e, 0x286a, 0x373b, 0x2435, 0x348f, + 0x1c0c, 0x3192, 0x2970, 0x1ba6, 0x1cdd, 0x0e09, 0x1428, 0x19b3, 0x282e, 0x131f, 0x3e89, 0x1bf9, 0x14f6, 0x18cc, 0x235c, 0x28f5, + 0x2622, 0x3561, 0x240e, 0x0402, 0x25f7, 0x2e71, 0x107a, 0x0859, 0x209a, 0x287c, 0x0091, 0x0566, 0x3599, 0x2707, 0x0256, 0x15c2, + 0x000c, 0x1b34, 0x07c8, 0x009d, 0x3b0b, 0x2ba4, 0x1a39, 0x2c79, 0x260c, 0x0279, 0x2ec0, 0x2dee, 0x2b98, 0x0ad8, 0x0603, 0x0477, + 0x2b94, 0x2b65, 0x224b, 0x3ad3, 0x0514, 0x0974, 0x2980, 0x2e48, 0x1eb7, 0x0dcb, 0x15ec, 0x245a, 0x2b69, 0x1a80, 0x1421, 0x33e3, + 0x217e, 0x2340, 0x3496, 0x3704, 0x3625, 0x2118, 0x2ee2, 0x3a5d, 0x2e1d, 0x1f25, 0x199a, 0x120d, 0x224f, 0x29db, 0x274a, 0x137b, + 0x0d4a, 0x2e67, 0x28ce, 0x3e7e, 0x1a68, 0x0d24, 0x280d, 0x1e3e, 0x2da0, 0x08fa, 0x21cf, 0x1891, 0x3ad7, 0x216b, 0x03fc, 0x05f4, + 0x0da0, 0x3e78, 0x31c7, 0x02c0, 0x28fd, 0x2308, 0x1358, 0x2c1e, 0x376c, 0x24f5, 0x18ff, 0x25da, 0x0518, 0x3d5c, 0x1036, 0x1886, + 0x111f, 0x05b4, 0x0744, 0x1828, 0x0b7d, 0x205b, 0x3dbf, 0x0026, 0x0623, 0x1915, 0x076e, 0x095f, 0x0978, 0x21f9, 0x01e5, 0x17da, + 0x2147, 0x3a01, 0x29a7, 0x0e1f, 0x2ddc, 0x1438, 0x2347, 0x3cad, 0x2ae7, 0x28c0, 0x017a, 0x0207, 0x2984, 0x3ba0, 0x24d4, 0x368c, + 0x32e1, 0x2599, 0x3c50, 0x0da6, 0x13f6, 0x32bd, 0x0524, 0x00ee, 0x144a, 0x3e6a, 0x1d73, 0x0938, 0x2e4c, 0x1e4d, 0x0810, 0x3870, + 0x3d8b, 0x1cac, 0x0b53, 0x236c, 0x18bd, 0x0e8c, 0x2898, 0x0bfd, 0x0862, 0x3476, 0x04a3, 0x0f17, 0x1ebb, 0x09a0, 0x0c96, 0x2063, + 0x2b79, 0x1e79, 0x16b4, 0x338a, 0x1cb5, 0x3054, 0x3cd9, 0x1b1c, 0x1854, 0x18f7, 0x13bb, 0x3a6c, 0x0dcf, 0x3589, 0x3cbf, 0x2521, + 0x2398, 0x1efe, 0x243c, 0x3a43, 0x079d, 0x1fbb, 0x19d7, 0x1923, 0x1fb4, 0x2111, 0x1d1c, 0x0843, 0x15f0, 0x20e5, 0x0fe2, 0x3086, + 0x0e37, 0x3ef2, 0x2cfa, 0x02c6, 0x3e0f, 0x226e, 0x36a1, 0x0fb6, 0x0055, 0x1fc8, 0x317e, 0x158e, 0x245e, 0x01f0, 0x285c, 0x0ffe, + 0x15d8, 0x30d1, 0x0b20, 0x2007, 0x3255, 0x2242, 0x3aea, 0x23e5, 0x0e4e, 0x361b, 0x0e99, 0x3307, 0x2b6d, 0x06c5, 0x3847, 0x3761, + 0x3b4e, 0x2ce9, 0x0a9e, 0x30c0, 0x2503, 0x0b6c, 0x1274, 0x3a4c, 0x3ca3, 0x174d, 0x26fa, 0x1710, 0x1a84, 0x0271, 0x383c, 0x2cce, + 0x3f2d, 0x113f, 0x2c09, 0x1ec7, 0x1289, 0x17cd, 0x2185, 0x05ab, 0x138a, 0x01cf, 0x17fe, 0x2432, 0x1425, 0x2359, 0x1077, 0x0253, + 0x3e99, 0x1562, 0x1d42, 0x31cd, 0x0c53, 0x1b8b, 0x1540, 0x321f, 0x2dc3, 0x2be4, 0x1135, 0x2fdb, 0x33e7, 0x31e3, 0x38d9, 0x2e8f, + 0x15d0, 0x04b8, 0x1182, 0x302b, 0x21a4, 0x034d, 0x2bb1, 0x336f, 0x02f5, 0x1a8c, 0x040f, 0x39ed, 0x0010, 0x1721, 0x1641, 0x1c05, + 0x0570, 0x0159, 0x1ad7, 0x1054, 0x288b, 0x069e, 0x0c3d, 0x3810, 0x0287, 0x25bb, 0x3442, 0x109a, 0x1b38, 0x2236, 0x3d65, 0x0826, + 0x130a, 0x29b9, 0x3742, 0x3b22, 0x0486, 0x084a, 0x24ac, 0x122a, 0x09aa, 0x3edd, 0x2d1a, 0x14be, 0x07cc, 0x193a, 0x35d6, 0x261c, + 0x2140, 0x3f26, 0x2f58, 0x230e, 0x1b7e, 0x1d8d, 0x393e, 0x3bab, 0x0143, 0x3a20, 0x22b7, 0x0d6b, 0x00a1, 0x115b, 0x309f, 0x37ab, + 0x35b8, 0x0f55, 0x3794, 0x20b4, 0x2364, 0x1767, 0x0f9c, 0x13d3, 0x0729, 0x1c66, 0x185c, 0x2b41, 0x3b0f, 0x16eb, 0x0240, 0x0266, + 0x0d44, 0x32db, 0x0e31, 0x3e93, 0x213a, 0x26e3, 0x3278, 0x2c88, 0x3e53, 0x3d2b, 0x1ab5, 0x0912, 0x2ba8, 0x3695, 0x0954, 0x1663, + 0x2f5f, 0x0ef3, 0x162d, 0x0b0c, 0x04d2, 0x2216, 0x370b, 0x3570, 0x0433, 0x01b2, 0x11c8, 0x0dd9, 0x1a3d, 0x08d7, 0x2570, 0x2095, + 0x26e9, 0x0a5c, 0x2100, 0x2903, 0x3ac6, 0x2125, 0x1875, 0x08a6, 0x0c2c, 0x2d58, 0x2205, 0x1a1f, 0x2c7d, 0x03b5, 0x175e, 0x0af4, + 0x0290, 0x31a1, 0x3404, 0x176f, 0x2c38, 0x3b83, 0x1c9d, 0x1254, 0x1350, 0x0f94, 0x1c3f, 0x3141, 0x2610, 0x0908, 0x1d33, 0x0b85, + 0x1eb2, 0x2d9b, 0x061e, 0x1445, 0x184f, 0x0050, 0x3c9e, 0x2dbe, 0x0282, 0x013e, 0x3e4e, 0x0c27, 0x027d, 0x36f8, 0x0505, 0x1d09, + 0x1bba, 0x2f80, 0x2871, 0x2402, 0x0d8b, 0x1d23, 0x16dc, 0x2662, 0x0690, 0x108a, 0x395c, 0x0a1a, 0x2ec4, 0x0423, 0x3090, 0x1109, + 0x327e, 0x2e57, 0x3758, 0x2c24, 0x3a13, 0x31b7, 0x0a0b, 0x053d, 0x36fd, 0x3a3c, 0x3b1b, 0x23fb, 0x2df2, 0x078d, 0x04fb, 0x1db1, + 0x04c0, 0x37fe, 0x33f2, 0x22c0, 0x1fa2, 0x16fe, 0x1024, 0x2159, 0x05e6, 0x001c, 0x3338, 0x148e, 0x2b9c, 0x0345, 0x09c2, 0x0fd7, + 0x3100, 0x08e2, 0x3159, 0x168b, 0x2eb7, 0x00bb, 0x30e5, 0x0ccb, 0x050a, 0x366c, 0x241e, 0x1216, 0x0adc, 0x1113, 0x2e12, 0x12b0, + 0x2315, 0x3f0f, 0x3550, 0x1dee, 0x2941, 0x23cb, 0x349d, 0x26c2, 0x173f, 0x0227, 0x06dd, 0x2cdf, 0x0607, 0x2866, 0x14f2, 0x3595, + 0x2c8e, 0x22d2, 0x132e, 0x135e, 0x12a3, 0x27d3, 0x24ec, 0x0f6a, 0x1d0e, 0x3f6c, 0x16aa, 0x00d7, 0x047b, 0x2f90, 0x1f33, 0x145e, + 0x06d6, 0x11c1, 0x17f7, 0x0173, 0x37c3, 0x09ca, 0x1bf0, 0x2a71, 0x1e2b, 0x2cd6, 0x00c4, 0x2223, 0x0d4e, 0x037e, 0x0d0b, 0x36d3, + 0x007a, 0x11e1, 0x325e, 0x0a82, 0x3204, 0x1fd6, 0x3b93, 0x2fba, 0x0295, 0x1964, 0x334a, 0x2581, 0x2e6b, 0x2756, 0x1791, 0x10eb, + 0x2712, 0x2ffa, 0x3635, 0x2df9, 0x2848, 0x20ec, 0x09f4, 0x1be3, 0x34d6, 0x0035, 0x0a40, 0x0687, 0x28d2, 0x34e7, 0x3b77, 0x26a8, + 0x3e59, 0x1811, 0x2eaf, 0x24fb, 0x2510, 0x0309, 0x1414, 0x3425, 0x31a6, 0x388c, 0x1013, 0x1dbd, 0x3e82, 0x3f81, 0x12f9, 0x346a, + 0x1f42, 0x3e36, 0x3fc1, 0x344d, 0x18d4, 0x2a17, 0x1c47, 0x0c60, 0x146a, 0x0f73, 0x3a74, 0x264c, 0x1a6c, 0x08ce, 0x201b, 0x0f5f, + 0x0f22, 0x218e, 0x0194, 0x0ced, 0x0bbb, 0x0e72, 0x0f0a, 0x03d0, 0x3409, 0x207c, 0x17e9, 0x27f2, 0x0d28, 0x1c79, 0x0a51, 0x2af9, + 0x1b85, 0x2268, 0x32b7, 0x0d1e, 0x27cd, 0x31b1, 0x211f, 0x1d87, 0x1a4e, 0x14a0, 0x2a78, 0x0303, 0x2811, 0x2fd0, 0x24e0, 0x35cd, + 0x3d31, 0x3a82, 0x10e1, 0x3772, 0x18a4, 0x2a7e, 0x2db6, 0x1b14, 0x1774, 0x1e12, 0x2d3b, 0x33a6, 0x1e42, 0x0326, 0x39ab, 0x1129, + 0x3484, 0x05a2, 0x3243, 0x0fa4, 0x14e0, 0x36e6, 0x02e3, 0x1a0d, 0x1083, 0x3ed6, 0x210a, 0x1f1e, 0x2da4, 0x09b8, 0x0444, 0x002e, + 0x0456, 0x2762, 0x21e2, 0x0c6d, 0x3d94, 0x3318, 0x2f73, 0x2a86, 0x2c3d, 0x0f2c, 0x3db1, 0x350e, 0x08fe, 0x1b08, 0x035a, 0x38c2, + 0x0589, 0x3e1c, 0x1f69, 0x0794, 0x1f72, 0x15f7, 0x1501, 0x087f, 0x2b19, 0x044b, 0x1ff9, 0x10ca, 0x21d3, 0x0abf, 0x0b00, 0x071f, + 0x1abb, 0x2492, 0x07e6, 0x25e0, 0x2a62, 0x14a6, 0x314c, 0x2e2d, 0x3b88, 0x018c, 0x0e29, 0x073c, 0x1895, 0x267e, 0x39e3, 0x3680, + 0x118a, 0x3aa7, 0x0b9f, 0x036e, 0x225f, 0x39f8, 0x22f2, 0x399b, 0x17af, 0x0b16, 0x0219, 0x28e3, 0x3adb, 0x3bc9, 0x0394, 0x2c2d, + 0x3dd8, 0x1518, 0x1cc2, 0x3be4, 0x1819, 0x34ac, 0x13c6, 0x2445, 0x1ca2, 0x3c3d, 0x3e40, 0x04e8, 0x216f, 0x37b7, 0x1177, 0x09e1, + 0x1d94, 0x1f81, 0x1c85, 0x0040, 0x2d49, 0x38f6, 0x362c, 0x348d, 0x1ba4, 0x19b1, 0x1bf7, 0x28f3, 0x0400, 0x0857, 0x0564, 0x15c0, + 0x0918, 0x2f02, 0x3015, 0x1905, 0x1cfa, 0x1a54, 0x1b71, 0x198a, 0x1259, 0x3c5a, 0x2c6f, 0x0fee, 0x05f8, 0x11d9, 0x0151, 0x2b5d, + 0x2895, 0x0c93, 0x3cd6, 0x3cbc, 0x19d4, 0x0fdf, 0x369e, 0x2859, 0x3ae7, 0x3844, 0x1271, 0x3839, 0x2182, 0x1074, 0x153d, 0x38d6, + 0x1a36, 0x0600, 0x297d, 0x141e, 0x2edf, 0x2747, 0x280a, 0x03f9, 0x1355, 0x1033, 0x3dbc, 0x01e2, 0x2344, 0x24d1, 0x0521, 0x080d, + 0x1c9a, 0x1d30, 0x3c9b, 0x0502, 0x16d9, 0x308d, 0x0a08, 0x04f8, 0x1021, 0x09bf, 0x30e2, 0x2e0f, 0x349a, 0x14ef, 0x24e9, 0x1f30, + 0x2bae, 0x163e, 0x0c3a, 0x3d62, 0x24a9, 0x35d3, 0x393b, 0x309c, 0x0f99, 0x023d, 0x3275, 0x0951, 0x3708, 0x256d, 0x1872, 0x175b, + 0x02e0, 0x0441, 0x2f70, 0x0357, 0x14fe, 0x0afd, 0x3149, 0x39e0, 0x22ef, 0x0391, 0x13c3, 0x1174, 0x3629, 0x0561, 0x1b6e, 0x014e, + 0x1bed, 0x0d08, 0x3b90, 0x178e, 0x09f1, 0x3b74, 0x1411, 0x12f6, 0x1c44, 0x2018, 0x0f07, 0x0a4e, 0x211c, 0x24dd, 0x2db3, 0x39a8, + 0x3945, 0x0df3, 0x387c, 0x269e, 0x3506, 0x3077, 0x3a64, 0x0c1f, 0x3c82, 0x3355, 0x09d1, 0x2933, 0x2ee6, 0x1a75, 0x21c3, 0x2040, + 0x369b, 0x153a, 0x2807, 0x051e, 0x0a05, 0x24e6, 0x3938, 0x186f, 0x3146, 0x1b6b, 0x140e, 0x2db0, 0x3a61, 0x21c0, 0x3935, 0x3932, + 0x25c4, 0x29f5, 0x0b34, 0x13db, 0x2e9b, 0x202f, 0x3948, 0x2333, 0x38a2, 0x2a06, 0x1b4d, 0x1403, 0x2e21, 0x0783, 0x0df6, 0x3dc7, + 0x2e86, 0x2b54, 0x3646, 0x2996, 0x2284, 0x320e, 0x387f, 0x18ac, 0x2615, 0x1102, 0x1374, 0x307f, 0x1f29, 0x0d5a, 0x26a1, 0x0718, + 0x27ed, 0x33a1, 0x257c, 0x1db8, 0x04e3, 0x0fe9, 0x3509, 0x0737, 0x0a49, 0x2dab, 0x01dd, 0x094c, 0x199e, 0x36c0, 0x307a, 0x0d61, + 0x095a, 0x0933, 0x2455, 0x188c, 0x170b, 0x2fd6, 0x3a67, 0x1589, 0x090d, 0x1a1a, 0x1095, 0x0d66, 0x1211, 0x00d2, 0x0c22, 0x23f6, + 0x3033, 0x3bf4, 0x295a, 0x0d74, 0x064d, 0x1234, 0x3c85, 0x23d8, 0x278d, 0x3ee8, 0x088c, 0x3da3, 0x2253, 0x3f57, 0x3358, 0x1622, + 0x3292, 0x35e2, 0x0668, 0x2aa9, 0x3e61, 0x1e09, 0x09d4, 0x371c, 0x1d38, 0x2bf2, 0x0060, 0x19a3, 0x29df, 0x2781, 0x2936, 0x1edc, + 0x3bb2, 0x2723, 0x2a31, 0x0bd4, 0x3c25, 0x00fd, 0x2ee9, 0x3e02, 0x3985, 0x0700, 0x37ca, 0x1e34, 0x274e, 0x24c9, 0x1a78, 0x222e, + 0x1669, 0x0cb0, 0x27b7, 0x103c, 0x1c20, 0x2817, 0x21c6, 0x100a, 0x0b8a, 0x1aa0, 0x13ec, 0x36c5, 0x137f, 0x139d, 0x2043, 0x30f4, + 0x0aee, 0x37a5, 0x1458, 0x1dab, 0x386a, 0x05ee, 0x2e89, 0x0ff8, 0x392c, 0x1755, 0x30ee, 0x23f0, 0x1123, 0x3464, 0x2b57, 0x367a, + 0x1da9, 0x0ff6, 0x23ee, 0x3678, 0x3676, 0x351c, 0x3649, 0x351e, 0x3283, 0x2d2f, 0x1150, 0x364b, 0x05b8, 0x37d2, 0x2999, 0x3520, + 0x3ec7, 0x352e, 0x38ff, 0x3285, 0x0e58, 0x1f05, 0x2287, 0x2d31, 0x2c60, 0x0fab, 0x2564, 0x1152, 0x0748, 0x0108, 0x3211, 0x364d, + 0x35be, 0x20d0, 0x05d9, 0x05ba, 0x2f3e, 0x3778, 0x3882, 0x37d4, 0x2e5c, 0x254a, 0x1c29, 0x299b, 0x182c, 0x2acf, 0x18af, 0x3522, + 0x0262, 0x165f, 0x2091, 0x0af0, 0x1c01, 0x0822, 0x2618, 0x37a7, 0x0fd3, 0x12ac, 0x3591, 0x145a, 0x0b81, 0x1d05, 0x1105, 0x1dad, + 0x1882, 0x17d6, 0x3688, 0x386c, 0x0473, 0x33df, 0x1377, 0x05f0, 0x375d, 0x2cca, 0x024f, 0x2e8b, 0x205f, 0x251d, 0x3082, 0x0ffa, + 0x014a, 0x39a4, 0x203c, 0x392e, 0x38d2, 0x0809, 0x1f2c, 0x1757, 0x161e, 0x1ed8, 0x222a, 0x30f0, 0x3dc3, 0x0714, 0x0d5d, 0x23f2, + 0x0f5b, 0x2af5, 0x35c9, 0x1125, 0x36cf, 0x10e7, 0x26a4, 0x3466, 0x2c29, 0x09dd, 0x15bc, 0x2b59, 0x002a, 0x38be, 0x071b, 0x367c, + 0x10d8, 0x3c47, 0x2a96, 0x35c0, 0x1241, 0x0ee0, 0x25c7, 0x20d2, 0x2e7a, 0x0c0a, 0x2c4f, 0x05db, 0x0627, 0x127f, 0x29f8, 0x05bc, + 0x2f31, 0x2cb3, 0x00e1, 0x2f40, 0x2375, 0x12c2, 0x0b37, 0x377a, 0x3a18, 0x08f2, 0x0235, 0x3884, 0x1919, 0x2542, 0x13de, 0x37d6, + 0x086e, 0x20c7, 0x1808, 0x2e5e, 0x3e25, 0x239f, 0x2e9e, 0x254c, 0x2922, 0x324a, 0x1344, 0x1c2b, 0x0772, 0x32f1, 0x2032, 0x299d, + 0x379a, 0x2797, 0x3afe, 0x182e, 0x365b, 0x3a88, 0x394b, 0x2ad1, 0x31bc, 0x33b2, 0x3d7a, 0x18b1, 0x0963, 0x0638, 0x2336, 0x3524, + 0x21ac, 0x247e, 0x17b9, 0x3ec9, 0x1cf1, 0x0c4a, 0x38a5, 0x3530, 0x0bc8, 0x1735, 0x1dc9, 0x3901, 0x097c, 0x3f40, 0x2a09, 0x3287, + 0x1e5f, 0x06e7, 0x1e6c, 0x0e5a, 0x342d, 0x322e, 0x1b50, 0x1f07, 0x0a10, 0x15b4, 0x34bf, 0x2289, 0x21fd, 0x1d6b, 0x1406, 0x2d33, + 0x3a27, 0x2fe5, 0x3fe1, 0x2c62, 0x0631, 0x2ac8, 0x2e24, 0x0fad, 0x2677, 0x3f7a, 0x00cb, 0x2566, 0x01e9, 0x2164, 0x0786, 0x1154, + 0x20ba, 0x0c7d, 0x2bfc, 0x074a, 0x3539, 0x3d37, 0x0df9, 0x010a, 0x0542, 0x0f3e, 0x1930, 0x3213, 0x17de, 0x39c6, 0x3dca, 0x364f, + 0x02be, 0x2c1c, 0x25d8, 0x1884, 0x1826, 0x0024, 0x095d, 0x17d8, 0x0e1d, 0x3cab, 0x0205, 0x368a, 0x0da4, 0x00ec, 0x0936, 0x386e, + 0x009b, 0x2c77, 0x2dec, 0x0475, 0x3ad1, 0x2e46, 0x2458, 0x33e1, 0x3702, 0x3a5b, 0x120b, 0x1379, 0x3e7c, 0x1e3c, 0x188f, 0x05f2, + 0x2005, 0x23e3, 0x3305, 0x375f, 0x30be, 0x3a4a, 0x170e, 0x2ccc, 0x1ec5, 0x05a9, 0x2430, 0x0251, 0x31cb, 0x321d, 0x2fd9, 0x2e8d, + 0x236a, 0x0bfb, 0x0f15, 0x2061, 0x3388, 0x1b1a, 0x3a6a, 0x251f, 0x3a41, 0x1921, 0x0841, 0x3084, 0x02c4, 0x0fb4, 0x158c, 0x0ffc, + 0x20b2, 0x13d1, 0x2b3f, 0x0264, 0x3e91, 0x2c86, 0x0910, 0x1661, 0x0b0a, 0x356e, 0x0dd7, 0x2093, 0x2901, 0x08a4, 0x1a1d, 0x0af2, + 0x3029, 0x336d, 0x39eb, 0x1c03, 0x1052, 0x380e, 0x1098, 0x0824, 0x3b20, 0x1228, 0x14bc, 0x261a, 0x230c, 0x3ba9, 0x0d69, 0x37a9, + 0x22be, 0x2157, 0x148c, 0x0fd5, 0x1689, 0x0cc9, 0x1214, 0x12ae, 0x1dec, 0x26c0, 0x2cdd, 0x3593, 0x135c, 0x0f68, 0x00d5, 0x145c, + 0x176d, 0x1252, 0x313f, 0x0b83, 0x1443, 0x2dbc, 0x0c25, 0x1d07, 0x2400, 0x2660, 0x0a18, 0x1107, 0x2c22, 0x053b, 0x23f9, 0x1daf, + 0x344b, 0x0c5e, 0x264a, 0x0f5d, 0x0ceb, 0x03ce, 0x27f0, 0x2af7, 0x0d1c, 0x1d85, 0x0301, 0x35cb, 0x3770, 0x1b12, 0x33a4, 0x1127, + 0x0171, 0x2a6f, 0x2221, 0x36d1, 0x0a80, 0x2fb8, 0x257f, 0x10e9, 0x2df7, 0x1be1, 0x0685, 0x26a6, 0x24f9, 0x3423, 0x1dbb, 0x3468, + 0x036c, 0x3999, 0x28e1, 0x2c2b, 0x3be2, 0x2443, 0x04e6, 0x09df, 0x003e, 0x348b, 0x28f1, 0x15be, 0x1903, 0x1988, 0x0fec, 0x2b5b, + 0x0fa2, 0x1a0b, 0x1f1c, 0x002c, 0x0c6b, 0x2a84, 0x350c, 0x38c0, 0x0792, 0x087d, 0x10c8, 0x071d, 0x25de, 0x2e2b, 0x073a, 0x367e, + 0x0355, 0x39de, 0x1172, 0x014c, 0x178c, 0x12f4, 0x0a4c, 0x39a6, 0x269c, 0x0c1d, 0x2931, 0x203e, 0x051c, 0x186d, 0x2dae, 0x3930, + 0x3cba, 0x2857, 0x3837, 0x38d4, 0x141c, 0x03f7, 0x01e0, 0x080b, 0x0500, 0x04f6, 0x2e0d, 0x1f2e, 0x3d60, 0x309a, 0x094f, 0x1759, + 0x0d72, 0x23d6, 0x3da1, 0x1620, 0x2aa7, 0x371a, 0x19a1, 0x1eda, 0x0bd2, 0x3e00, 0x1e32, 0x222c, 0x103a, 0x1008, 0x36c3, 0x30f2, + 0x13d9, 0x2331, 0x1401, 0x3dc5, 0x2994, 0x18aa, 0x307d, 0x0716, 0x1db6, 0x0735, 0x094a, 0x0d5f, 0x188a, 0x1587, 0x0d64, 0x23f4, + 0x1ae2, 0x3b41, 0x35fb, 0x2f33, 0x154d, 0x3340, 0x3295, 0x2cb5, 0x106b, 0x1718, 0x0cd4, 0x00e3, 0x32e5, 0x2a54, 0x35e5, 0x2f42, + 0x17a2, 0x3c62, 0x3af3, 0x2377, 0x2072, 0x2d85, 0x066b, 0x12c4, 0x1bbf, 0x3544, 0x1557, 0x0b39, 0x259d, 0x398d, 0x2aac, 0x377c, + 0x3f66, 0x3a36, 0x2d52, 0x3a1a, 0x2bde, 0x1fc2, 0x3e64, 0x08f4, 0x1a9a, 0x1a14, 0x1b65, 0x0237, 0x3c54, 0x0186, 0x1e0c, 0x3886, + 0x072f, 0x0877, 0x265a, 0x191b, 0x0f38, 0x33ac, 0x09d7, 0x2544, 0x2f85, 0x37de, 0x2820, 0x13e0, 0x0daa, 0x2fec, 0x371f, 0x37d8, + 0x27b0, 0x2800, 0x300e, 0x10da, 0x1327, 0x20f9, 0x1d3b, 0x3c49, 0x357d, 0x27dc, 0x2529, 0x2a98, 0x13fa, 0x3138, 0x2bf5, 0x35c2, + 0x3b6a, 0x1292, 0x2686, 0x1243, 0x3112, 0x1ac6, 0x0063, 0x0ee2, 0x2876, 0x2d8f, 0x2bc9, 0x25c9, 0x32c1, 0x382b, 0x19a6, 0x20d4, + 0x00a8, 0x22fb, 0x0db8, 0x2e7c, 0x08bb, 0x10b7, 0x29e2, 0x0c0c, 0x1cd5, 0x2f20, 0x36da, 0x2c51, 0x0528, 0x2693, 0x2784, 0x05dd, + 0x1c6c, 0x19f3, 0x2a9f, 0x0629, 0x3c1d, 0x2d41, 0x2939, 0x1281, 0x2407, 0x3725, 0x2291, 0x29fa, 0x00f2, 0x24bb, 0x1edf, 0x05be, + 0x11b8, 0x1b2b, 0x3b38, 0x379c, 0x25ab, 0x02a6, 0x3036, 0x2799, 0x2600, 0x3ff6, 0x290d, 0x3b00, 0x144e, 0x07be, 0x3bf7, 0x1830, + 0x19c7, 0x3ce6, 0x2473, 0x365d, 0x0b5c, 0x16bf, 0x295d, 0x3a8a, 0x0d90, 0x2198, 0x0b48, 0x394d, 0x3e6e, 0x1655, 0x0d77, 0x2ad3, + 0x3005, 0x2088, 0x3fb8, 0x31be, 0x0592, 0x07a4, 0x0650, 0x33b4, 0x31f4, 0x02ea, 0x006e, 0x3d7c, 0x1d77, 0x332a, 0x1237, 0x18b3, + 0x1862, 0x1e9f, 0x316b, 0x0965, 0x0551, 0x1e18, 0x3c88, 0x063a, 0x1d28, 0x2ff2, 0x29b1, 0x2338, 0x093c, 0x3a2e, 0x23db, 0x3526, + 0x2bb9, 0x169d, 0x1e98, 0x0870, 0x1a04, 0x0bf4, 0x2790, 0x20c9, 0x092c, 0x1637, 0x248b, 0x180a, 0x2e50, 0x3f1f, 0x3eeb, 0x2e60, + 0x2a24, 0x0eb9, 0x1970, 0x3e27, 0x0311, 0x23b6, 0x088f, 0x23a1, 0x16e1, 0x089a, 0x1f4c, 0x2ea0, 0x1e51, 0x337c, 0x3da6, 0x254e, + 0x1162, 0x0f87, 0x36ae, 0x2924, 0x19fb, 0x1ce8, 0x2256, 0x324c, 0x30ae, 0x2386, 0x0d12, 0x1346, 0x0814, 0x1a2b, 0x3f5a, 0x1c2d, + 0x2b47, 0x391a, 0x2530, 0x0774, 0x38ae, 0x177a, 0x335b, 0x32f3, 0x2667, 0x0db0, 0x1484, 0x2034, 0x3874, 0x32af, 0x1625, 0x299f, + 0x06a8, 0x22e2, 0x01c0, 0x1e61, 0x2f16, 0x1496, 0x166c, 0x06e9, 0x3736, 0x2702, 0x13ac, 0x1e6e, 0x214b, 0x0cdd, 0x0cb3, 0x0e5c, + 0x0d37, 0x1261, 0x0468, 0x342f, 0x0a36, 0x1b5b, 0x27ba, 0x3230, 0x0695, 0x273e, 0x2e3d, 0x1b52, 0x3a05, 0x0708, 0x103f, 0x1f09, + 0x10c2, 0x0944, 0x083b, 0x0a12, 0x3d74, 0x192a, 0x1c23, 0x15b6, 0x11a3, 0x36ed, 0x3269, 0x34c1, 0x29ab, 0x147e, 0x281a, 0x228b, + 0x3b15, 0x16a4, 0x22b1, 0x21ff, 0x3178, 0x112f, 0x21c9, 0x1d6d, 0x108f, 0x13e6, 0x326f, 0x1408, 0x0e23, 0x2c69, 0x100d, 0x2d35, + 0x3973, 0x306d, 0x152b, 0x21ae, 0x2836, 0x03be, 0x0b8d, 0x2480, 0x32cf, 0x008b, 0x3cc7, 0x17bb, 0x2de0, 0x0fc5, 0x1aa3, 0x3ecb, + 0x09fe, 0x1c19, 0x189d, 0x1cf3, 0x3abf, 0x129c, 0x13ef, 0x0c4c, 0x3961, 0x21ed, 0x3c16, 0x38a7, 0x143c, 0x298d, 0x36c8, 0x3532, + 0x30a6, 0x2774, 0x266f, 0x0bca, 0x1b9c, 0x397d, 0x1382, 0x1737, 0x3d03, 0x25f0, 0x0385, 0x1dcb, 0x234b, 0x2024, 0x13a0, 0x3903, + 0x16f1, 0x2d66, 0x27e3, 0x097e, 0x3968, 0x39b1, 0x2046, 0x3f42, 0x0a1f, 0x2826, 0x34c7, 0x2a0b, 0x3cb1, 0x1d5d, 0x30f7, 0x3289, + 0x10a3, 0x14d3, 0x1573, 0x20bc, 0x26cf, 0x18e3, 0x3bb5, 0x0c7f, 0x1f96, 0x1604, 0x29c4, 0x2bfe, 0x2aeb, 0x258f, 0x2726, 0x074c, + 0x0dc2, 0x195b, 0x2d26, 0x353b, 0x2fa0, 0x1fe0, 0x2a34, 0x3d39, 0x2ec9, 0x0e42, 0x2dd1, 0x0dfb, 0x28c4, 0x05cf, 0x0bd7, 0x010c, + 0x0988, 0x197d, 0x2d76, 0x0544, 0x3deb, 0x19de, 0x3c28, 0x0f40, 0x34df, 0x14e7, 0x29d3, 0x1932, 0x017e, 0x1476, 0x0100, 0x3215, + 0x0246, 0x2bc0, 0x0765, 0x17e0, 0x159a, 0x032c, 0x2eec, 0x39c8, 0x0428, 0x37e4, 0x11a9, 0x3dcc, 0x020b, 0x3fe8, 0x3e05, 0x3651, + 0x3377, 0x32aa, 0x1650, 0x3a29, 0x3826, 0x24b6, 0x3988, 0x2fe7, 0x0531, 0x03ab, 0x05ca, 0x3fe3, 0x2988, 0x1d58, 0x0703, 0x2c64, + 0x1d66, 0x39c1, 0x253d, 0x0633, 0x2518, 0x38b9, 0x37cd, 0x2aca, 0x3095, 0x1582, 0x341e, 0x2e26, 0x3ba4, 0x0536, 0x1e37, 0x0faf, + 0x37b2, 0x11d4, 0x1b03, 0x2679, 0x1c74, 0x0321, 0x2751, 0x3f7c, 0x277c, 0x1398, 0x0d55, 0x00cd, 0x24d8, 0x21bb, 0x24cc, 0x2568, + 0x026c, 0x31de, 0x3584, 0x01eb, 0x21f4, 0x1e48, 0x1a7b, 0x2166, 0x110e, 0x2f8b, 0x36f3, 0x0788, 0x3690, 0x03b0, 0x2231, 0x1156, + 0x057d, 0x02af, 0x183a, 0x0d39, 0x2918, 0x1faa, 0x007d, 0x1263, 0x0bb2, 0x0b74, 0x3109, 0x046a, 0x2b7d, 0x01a1, 0x11e4, 0x3431, + 0x2d12, 0x1992, 0x30da, 0x0a38, 0x2428, 0x255c, 0x3261, 0x1b5d, 0x3105, 0x2fa9, 0x2fad, 0x27bc, 0x1e7d, 0x2ef1, 0x0a85, 0x3232, + 0x304d, 0x096d, 0x0049, 0x0697, 0x3311, 0x1fcf, 0x3207, 0x2740, 0x12bb, 0x3515, 0x2fb1, 0x2e3f, 0x16b8, 0x2d7e, 0x1fd9, 0x1b54, + 0x26ef, 0x2555, 0x0be1, 0x3a07, 0x2ca0, 0x3453, 0x3b96, 0x070a, 0x08e7, 0x2cbb, 0x27c0, 0x1041, 0x338e, 0x39cd, 0x2fbd, 0x1f0b, + 0x3bd8, 0x0d81, 0x33bd, 0x06aa, 0x19bb, 0x2b27, 0x0298, 0x22e4, 0x3852, 0x1337, 0x1e81, 0x01c2, 0x1cb9, 0x0a95, 0x1967, 0x1e63, + 0x26b8, 0x1ed0, 0x25e8, 0x2f18, 0x01aa, 0x28b8, 0x334d, 0x1498, 0x315e, 0x2a45, 0x2ef5, 0x166e, 0x3058, 0x159f, 0x2584, 0x06eb, + 0x1311, 0x3ab0, 0x32fb, 0x3738, 0x0e06, 0x18c9, 0x2e6e, 0x2704, 0x1aee, 0x15a7, 0x0a89, 0x13ae, 0x3cdd, 0x2caa, 0x2759, 0x1e70, + 0x0a62, 0x0756, 0x0ee9, 0x214d, 0x0b94, 0x3fc7, 0x1794, 0x0cdf, 0x1690, 0x329b, 0x3236, 0x0cb5, 0x1b20, 0x0331, 0x10ee, 0x0e5e, + 0x1c3b, 0x3e4a, 0x3958, 0x3b17, 0x3334, 0x241a, 0x06d9, 0x16a6, 0x040b, 0x343e, 0x2d16, 0x22b3, 0x1858, 0x1ab1, 0x11c4, 0x2201, + 0x049f, 0x13b7, 0x1d18, 0x317a, 0x0e95, 0x26f6, 0x17fa, 0x1131, 0x2ebc, 0x15e8, 0x1996, 0x21cb, 0x18fb, 0x076a, 0x0176, 0x1d6f, + 0x1b49, 0x1370, 0x01d9, 0x1091, 0x0888, 0x005c, 0x37c6, 0x13e8, 0x126d, 0x3db8, 0x30de, 0x3271, 0x13bf, 0x0f03, 0x09cd, 0x140a, + 0x2106, 0x3dad, 0x1ff5, 0x0e25, 0x0215, 0x3e3c, 0x1bf3, 0x2c6b, 0x00c0, 0x3346, 0x0a3c, 0x100f, 0x3a70, 0x17e5, 0x2a74, 0x2d37, + 0x02fd, 0x0681, 0x28ed, 0x10c4, 0x292d, 0x2e09, 0x1e2e, 0x0946, 0x0201, 0x1207, 0x242c, 0x083d, 0x0dd3, 0x14b8, 0x2cd9, 0x0a14, + 0x2c4b, 0x0231, 0x1340, 0x3d76, 0x1dc5, 0x34bb, 0x00c7, 0x192c, 0x30ea, 0x114c, 0x2560, 0x1c25, 0x358d, 0x024b, 0x2226, 0x15b8, + 0x29c0, 0x2dcd, 0x29cf, 0x11a5, 0x05c6, 0x341a, 0x0d51, 0x36ef, 0x13a8, 0x2e39, 0x3265, 0x326b, 0x3cc3, 0x3c12, 0x0381, 0x34c3, + 0x2909, 0x0b44, 0x006a, 0x29ad, 0x2487, 0x1f48, 0x0d0e, 0x1480, 0x0cd0, 0x1553, 0x1b61, 0x281c, 0x2525, 0x2bc5, 0x36d6, 0x228d, + 0x2eda, 0x24a4, 0x09ec, 0x0a00, 0x227f, 0x1706, 0x3e5c, 0x1c1b, 0x31ff, 0x250b, 0x0bb6, 0x189f, 0x3d8f, 0x2a5d, 0x1814, 0x1cf5, + 0x2886, 0x1b79, 0x2135, 0x3ac1, 0x184a, 0x3a0e, 0x2eb2, 0x129e, 0x050f, 0x1a63, 0x0b78, 0x13f1, 0x1cb0, 0x3e0a, 0x24fe, 0x0c4e, + 0x0a31, 0x3173, 0x3aba, 0x3963, 0x2f9b, 0x1595, 0x2513, 0x21ef, 0x206d, 0x0f33, 0x310d, 0x3c18, 0x0b57, 0x054c, 0x030c, 0x38a9, + 0x3acc, 0x3383, 0x104d, 0x143e, 0x0a7b, 0x0c66, 0x1417, 0x298f, 0x3671, 0x2f39, 0x046e, 0x36ca, 0x2370, 0x3656, 0x3428, 0x3534, + 0x0801, 0x0cc1, 0x10af, 0x3975, 0x1430, 0x220e, 0x31a9, 0x306f, 0x0ac9, 0x22a4, 0x2b81, 0x152d, 0x18c1, 0x1f56, 0x388f, 0x21b0, + 0x1845, 0x0a76, 0x07ee, 0x2838, 0x07f3, 0x3b5e, 0x1016, 0x03c0, 0x2423, 0x2c9b, 0x01a5, 0x0b8f, 0x0e90, 0x0210, 0x1dc0, 0x2482, + 0x3749, 0x0a6c, 0x3363, 0x32d1, 0x3c6e, 0x1f5e, 0x3e85, 0x008d, 0x37ef, 0x3060, 0x11e8, 0x3cc9, 0x289c, 0x0f7c, 0x3f84, 0x17bd, + 0x212b, 0x2b04, 0x1acd, 0x2de2, 0x283d, 0x1c4d, 0x12fc, 0x0fc7, 0x121b, 0x3601, 0x3435, 0x1aa5, 0x0c01, 0x3fed, 0x346d, 0x3ecd, + 0x1b41, 0x11f4, 0x3cf2, 0x16f3, 0x039f, 0x3122, 0x2715, 0x2d68, 0x2390, 0x1bb2, 0x0581, 0x27e5, 0x0866, 0x0364, 0x2ffd, 0x0980, + 0x35af, 0x02d7, 0x20a9, 0x396a, 0x07f8, 0x0be8, 0x3638, 0x39b3, 0x0ae1, 0x012b, 0x02b3, 0x2048, 0x347a, 0x11ae, 0x2dfc, 0x3f44, + 0x11fc, 0x3610, 0x0612, 0x0a21, 0x06b4, 0x3185, 0x284b, 0x2828, 0x26b1, 0x2c44, 0x183e, 0x34c9, 0x04a7, 0x3eaf, 0x20ef, 0x2a0d, + 0x187b, 0x1e58, 0x3022, 0x3cb3, 0x3b63, 0x2a1d, 0x09f7, 0x1d5f, 0x1118, 0x3b47, 0x0d3d, 0x30f9, 0x0f1b, 0x3dd1, 0x1be6, 0x328b, + 0x1a94, 0x1ccf, 0x31ee, 0x30a8, 0x119d, 0x3cfd, 0x34d9, 0x2776, 0x2c5a, 0x1618, 0x291c, 0x2671, 0x1ebf, 0x1de6, 0x0038, 0x0bcc, + 0x34d0, 0x1a48, 0x2b13, 0x1b9e, 0x101b, 0x3c7c, 0x0a43, 0x397f, 0x2e17, 0x2ae1, 0x1fae, 0x1384, 0x09a4, 0x042d, 0x068a, 0x1739, + 0x3b29, 0x2631, 0x3f03, 0x3d05, 0x1ee7, 0x150d, 0x28d5, 0x25f2, 0x390b, 0x07b1, 0x0081, 0x0387, 0x0c9a, 0x2468, 0x34ea, 0x1dcd, + 0x08ac, 0x0ec5, 0x3119, 0x234d, 0x03c5, 0x18da, 0x3b7a, 0x2026, 0x12b5, 0x1ae8, 0x1267, 0x13a2, 0x2067, 0x37e9, 0x26ab, 0x3905, + 0x0137, 0x25b4, 0x18f0, 0x0dc4, 0x10fb, 0x102c, 0x0f25, 0x195d, 0x1bda, 0x3a54, 0x08eb, 0x2d28, 0x0e3b, 0x2737, 0x2191, 0x353d, + 0x0124, 0x1a5c, 0x15e1, 0x2fa2, 0x0ace, 0x345a, 0x0197, 0x1fe2, 0x04c5, 0x1fe9, 0x2cbf, 0x2a36, 0x3ef6, 0x3c2d, 0x0cf0, 0x3d3b, + 0x35a4, 0x1ea7, 0x1c8e, 0x2ecb, 0x1c58, 0x01f7, 0x0bbe, 0x0e44, 0x08b2, 0x38c9, 0x27c4, 0x2dd3, 0x2cfe, 0x0990, 0x0e75, 0x0dfd, + 0x0c32, 0x2ea7, 0x2f50, 0x28c6, 0x22a9, 0x2652, 0x0f0d, 0x05d1, 0x3803, 0x2f48, 0x1045, 0x0bd9, 0x02ca, 0x0f45, 0x03d3, 0x010e, + 0x2b35, 0x378a, 0x0659, 0x10a5, 0x0e11, 0x3eb9, 0x340c, 0x14d5, 0x1dda, 0x1367, 0x3392, 0x1575, 0x3e13, 0x1ef5, 0x207f, 0x20be, + 0x04ae, 0x2c12, 0x249a, 0x26d1, 0x2b86, 0x385e, 0x17ec, 0x18e5, 0x33f7, 0x0675, 0x39d1, 0x3bb7, 0x2272, 0x3df0, 0x27f5, 0x0c81, + 0x048d, 0x1193, 0x1782, 0x1f98, 0x0e7e, 0x3897, 0x0d2b, 0x1606, 0x0ecb, 0x06f3, 0x2fc1, 0x29c6, 0x36a5, 0x3fd8, 0x1c7c, 0x2c00, + 0x2d5e, 0x19eb, 0x124a, 0x2aed, 0x1532, 0x3a7a, 0x0a54, 0x2591, 0x22c5, 0x35eb, 0x1f0f, 0x2728, 0x0fba, 0x19e3, 0x2afc, 0x074e, + 0x2e06, 0x14b5, 0x34b8, 0x0248, 0x3417, 0x3c0f, 0x1f45, 0x2bc2, 0x2417, 0x1aae, 0x26f3, 0x0767, 0x0059, 0x0f00, 0x3e39, 0x17e2, + 0x2b24, 0x0a92, 0x28b5, 0x159c, 0x18c6, 0x2ca7, 0x3fc4, 0x032e, 0x1fa7, 0x019e, 0x2559, 0x2eee, 0x1fcc, 0x2d7b, 0x3450, 0x39ca, + 0x3cfa, 0x1de3, 0x3c79, 0x042a, 0x150a, 0x2465, 0x18d7, 0x37e6, 0x311f, 0x0361, 0x0be5, 0x11ab, 0x3182, 0x3eac, 0x2a1a, 0x3dce, + 0x220b, 0x1f53, 0x3b5b, 0x020d, 0x1f5b, 0x0f79, 0x1c4a, 0x3fea, 0x1703, 0x2a5a, 0x3a0b, 0x3e07, 0x1592, 0x0549, 0x0c63, 0x3653, + 0x0417, 0x3ea6, 0x3fd2, 0x098a, 0x36b7, 0x041a, 0x146d, 0x197f, 0x3c0c, 0x0efd, 0x2ca4, 0x2d78, 0x2462, 0x3ea9, 0x0f76, 0x0546, + 0x3eb6, 0x1ef2, 0x385b, 0x3ded, 0x3894, 0x3fd5, 0x3a77, 0x19e0, 0x1029, 0x2734, 0x3457, 0x3c2a, 0x01f4, 0x098d, 0x264f, 0x0f42, + 0x0851, 0x0ab9, 0x2fca, 0x34e1, 0x24c3, 0x36ba, 0x1a6f, 0x14e9, 0x2353, 0x20df, 0x3b9a, 0x29d5, 0x2860, 0x041d, 0x08d1, 0x1934, + 0x1a25, 0x3324, 0x268d, 0x0180, 0x21b5, 0x1470, 0x201e, 0x1478, 0x215e, 0x32eb, 0x070e, 0x0102, 0x1002, 0x1982, 0x0f62, 0x3217, + 0x0c47, 0x3f3d, 0x322b, 0x1d68, 0x2ac5, 0x2161, 0x3d34, 0x39c3, 0x0edd, 0x127c, 0x12bf, 0x253f, 0x239c, 0x32ee, 0x3a85, 0x0635, + 0x081f, 0x1d02, 0x33dc, 0x251a, 0x0806, 0x0711, 0x10e4, 0x38bb, 0x05eb, 0x3461, 0x3519, 0x37cf, 0x1f02, 0x0105, 0x3775, 0x2acc, + 0x12f1, 0x186a, 0x03f4, 0x3097, 0x3717, 0x1005, 0x18a7, 0x1584, 0x03cb, 0x1b0f, 0x2fb5, 0x3420, 0x2440, 0x1985, 0x2a81, 0x2e28, + 0x2c83, 0x08a1, 0x380b, 0x3ba6, 0x0cc6, 0x0f65, 0x2db9, 0x0538, 0x0021, 0x00e9, 0x2e43, 0x1e39, 0x3a47, 0x321a, 0x1b17, 0x0fb1, + 0x0bf1, 0x3f1c, 0x23b3, 0x3379, 0x1ce5, 0x1a28, 0x1777, 0x32ac, 0x02a3, 0x07bb, 0x16bc, 0x1652, 0x07a1, 0x3327, 0x1e15, 0x3a2b, + 0x20f6, 0x3135, 0x1ac3, 0x3828, 0x10b4, 0x2690, 0x2d3e, 0x24b8, 0x333d, 0x2a51, 0x2d82, 0x398a, 0x1fbf, 0x0183, 0x33a9, 0x2fe9, + 0x24b3, 0x1d55, 0x38b6, 0x0533, 0x031e, 0x21b8, 0x1e45, 0x03ad, 0x18e0, 0x258c, 0x1fdd, 0x05cc, 0x19db, 0x1473, 0x0329, 0x3fe5, + 0x03bb, 0x0fc2, 0x1299, 0x298a, 0x397a, 0x2021, 0x39ae, 0x1d5a, 0x1493, 0x0cda, 0x1b58, 0x0705, 0x1927, 0x147b, 0x112c, 0x2c66, + 0x223f, 0x06c2, 0x0b69, 0x026e, 0x17ca, 0x2356, 0x1b88, 0x31e0, 0x0e89, 0x099d, 0x3051, 0x3586, 0x1fb8, 0x20e2, 0x226b, 0x01ed, + 0x2305, 0x3d59, 0x2058, 0x21f6, 0x1435, 0x3b9d, 0x32ba, 0x1e4a, 0x2ba1, 0x0ad5, 0x0971, 0x1a7d, 0x2115, 0x29d8, 0x0d21, 0x2168, + 0x16fb, 0x0342, 0x00b8, 0x1110, 0x23c8, 0x2863, 0x27d0, 0x2f8d, 0x3b80, 0x0905, 0x004d, 0x36f5, 0x1d20, 0x0420, 0x31b4, 0x078a, + 0x1764, 0x16e8, 0x26e0, 0x3692, 0x2213, 0x08d4, 0x2122, 0x03b2, 0x034a, 0x171e, 0x069b, 0x2233, 0x0847, 0x1937, 0x1d8a, 0x1158, + 0x39f5, 0x3bc6, 0x34a9, 0x37b4, 0x38f3, 0x0854, 0x1a51, 0x11d6, 0x36e3, 0x09b5, 0x3315, 0x1b05, 0x15f4, 0x0abc, 0x14a3, 0x267b, + 0x2a14, 0x08cb, 0x0e6f, 0x1c76, 0x31ae, 0x2fcd, 0x2a7b, 0x0323, 0x09c7, 0x037b, 0x1fd3, 0x2753, 0x20e9, 0x34e4, 0x0306, 0x3f7e, + 0x1231, 0x3f54, 0x1e06, 0x277e, 0x00fa, 0x24c6, 0x2814, 0x139a, 0x202c, 0x0780, 0x320b, 0x0d57, 0x0fe6, 0x36bd, 0x2fd3, 0x00cf, + 0x0afa, 0x055e, 0x3b71, 0x24da, 0x3074, 0x1a72, 0x24e3, 0x21bd, 0x0fdc, 0x1071, 0x2744, 0x24ce, 0x308a, 0x14ec, 0x35d0, 0x256a, + 0x0165, 0x27a2, 0x3c01, 0x17a4, 0x167f, 0x04c8, 0x0459, 0x3c64, 0x07dd, 0x2cf1, 0x3162, 0x3af5, 0x3b52, 0x1fec, 0x2765, 0x2379, + 0x3d23, 0x190d, 0x2010, 0x2074, 0x1220, 0x2cc2, 0x21e5, 0x2d87, 0x2c93, 0x2a3d, 0x2a49, 0x066d, 0x2ced, 0x2a39, 0x0c70, 0x12c6, + 0x38e8, 0x0642, 0x1f8a, 0x1bc1, 0x0ea3, 0x3ef9, 0x3d97, 0x3546, 0x3911, 0x0c74, 0x2ef9, 0x1559, 0x0aa2, 0x3c30, 0x331b, 0x0b3b, + 0x2f65, 0x23a8, 0x0116, 0x259f, 0x3606, 0x0cf3, 0x2f76, 0x398f, 0x22d7, 0x12ca, 0x1672, 0x2aae, 0x30c4, 0x3d3e, 0x2a89, 0x377e, + 0x1614, 0x2add, 0x07ad, 0x1ae4, 0x1bae, 0x0127, 0x2c40, 0x3b43, 0x22a0, 0x2c97, 0x305c, 0x35fd, 0x2507, 0x1a5f, 0x0f2f, 0x2f35, + 0x1203, 0x1148, 0x2e35, 0x154f, 0x343a, 0x15e4, 0x3db4, 0x3342, 0x1333, 0x2a41, 0x15a3, 0x3297, 0x0b70, 0x2fa5, 0x3511, 0x2cb7, + 0x09b1, 0x0377, 0x077c, 0x106d, 0x0999, 0x0ad1, 0x0901, 0x171a, 0x07b7, 0x2a4d, 0x2588, 0x0cd6, 0x1278, 0x345d, 0x1b0b, 0x00e5, + 0x0ef9, 0x2730, 0x20db, 0x32e7, 0x1aaa, 0x019a, 0x035d, 0x2a56, 0x1363, 0x0671, 0x06ef, 0x35e7, 0x3a50, 0x1fe5, 0x38c5, 0x2f44, + 0x0c19, 0x04f2, 0x3dfc, 0x0731, 0x1d81, 0x1bdd, 0x3487, 0x0879, 0x356a, 0x1224, 0x26bc, 0x265c, 0x3ca7, 0x3a57, 0x05a5, 0x191d, + 0x1731, 0x15b0, 0x3f76, 0x0f3a, 0x0c06, 0x08ee, 0x3246, 0x33ae, 0x12a8, 0x2cc6, 0x1ed4, 0x09d9, 0x1751, 0x2d2b, 0x0fa7, 0x2546, + 0x03a7, 0x157e, 0x1394, 0x2f87, 0x1600, 0x0e3e, 0x14e3, 0x37e0, 0x0087, 0x21e9, 0x25ec, 0x2822, 0x26fe, 0x273a, 0x36e9, 0x13e2, + 0x1633, 0x0896, 0x2382, 0x0dac, 0x3ff2, 0x2194, 0x02e6, 0x2fee, 0x27d8, 0x2d8b, 0x2f1c, 0x3721, 0x1714, 0x3540, 0x1a10, 0x37da, + 0x0018, 0x3668, 0x0223, 0x3f68, 0x0f90, 0x013a, 0x1086, 0x3a38, 0x1c62, 0x3d27, 0x01ae, 0x2d54, 0x1a88, 0x25b7, 0x3ed9, 0x3a1c, + 0x3617, 0x1749, 0x01cb, 0x2be0, 0x3472, 0x18f3, 0x210d, 0x1fc4, 0x24f1, 0x1911, 0x28bc, 0x3e66, 0x0275, 0x0dc7, 0x1f21, 0x08f6, + 0x3ee4, 0x2bee, 0x06fc, 0x1a9c, 0x2a02, 0x10fe, 0x2da7, 0x1a16, 0x038d, 0x2014, 0x3351, 0x1b67, 0x3840, 0x102f, 0x09bb, 0x0239, + 0x0b12, 0x3c39, 0x19ad, 0x3c56, 0x3ed2, 0x0f28, 0x0447, 0x0188, 0x0f6f, 0x2078, 0x149c, 0x1e0e, 0x2cd2, 0x1960, 0x0031, 0x3888, + 0x2053, 0x26db, 0x0e6a, 0x3b6c, 0x33d7, 0x3806, 0x1abe, 0x1294, 0x28b0, 0x3b56, 0x3856, 0x2688, 0x15dc, 0x2f4b, 0x2495, 0x1245, + 0x20a4, 0x301d, 0x2b0e, 0x3114, 0x2130, 0x1048, 0x07e9, 0x1ac8, 0x1d13, 0x1ff0, 0x133b, 0x0065, 0x30d5, 0x0bdc, 0x25e3, 0x0ee4, + 0x03e9, 0x3c90, 0x131b, 0x2878, 0x34f6, 0x02cd, 0x2a65, 0x2d91, 0x0ca0, 0x2769, 0x1e85, 0x2bcb, 0x0b24, 0x0f48, 0x14a9, 0x25cb, + 0x04d8, 0x23bd, 0x03db, 0x32c3, 0x2b09, 0x03d6, 0x314f, 0x382d, 0x3f71, 0x237d, 0x01c6, 0x19a8, 0x200b, 0x0111, 0x2e30, 0x20d6, + 0x3641, 0x2450, 0x0663, 0x27b2, 0x2978, 0x0c35, 0x3b8b, 0x2802, 0x21dd, 0x07e1, 0x1cbd, 0x3010, 0x3259, 0x2eaa, 0x018f, 0x10dc, + 0x0619, 0x3753, 0x3154, 0x1329, 0x1ad2, 0x2f53, 0x0e2c, 0x20fb, 0x16af, 0x2cf5, 0x0a99, 0x1d3d, 0x2246, 0x28c9, 0x073f, 0x3c4b, + 0x2d21, 0x0760, 0x2538, 0x357f, 0x0463, 0x22ac, 0x1898, 0x27de, 0x246e, 0x3166, 0x196b, 0x252b, 0x3aee, 0x2655, 0x2681, 0x2a9a, + 0x221c, 0x1f17, 0x3832, 0x13fc, 0x2de7, 0x0f10, 0x39e6, 0x313a, 0x00dc, 0x3af9, 0x1e67, 0x2bf7, 0x23e9, 0x05d4, 0x3683, 0x35c4, + 0x3d6e, 0x1b96, 0x3de5, 0x1c6e, 0x2bd8, 0x08b5, 0x058c, 0x19f5, 0x30b8, 0x1683, 0x3bdc, 0x2aa1, 0x0e52, 0x38cc, 0x3e1f, 0x062b, + 0x16d3, 0x3500, 0x04dd, 0x3c1f, 0x2842, 0x27c7, 0x1f6c, 0x2d43, 0x0480, 0x04cc, 0x0d85, 0x293b, 0x361f, 0x2dd6, 0x0797, 0x1283, + 0x312a, 0x0cfd, 0x3fac, 0x2409, 0x33c7, 0x2d01, 0x1f75, 0x3727, 0x34f0, 0x045d, 0x33c1, 0x2293, 0x0e9d, 0x0993, 0x15fa, 0x29fc, + 0x3711, 0x0318, 0x23c2, 0x00f4, 0x1c52, 0x0e78, 0x1504, 0x24bd, 0x2f95, 0x3c68, 0x06ae, 0x1ee1, 0x330b, 0x0e00, 0x0882, 0x05c0, + 0x1729, 0x16cb, 0x3f90, 0x00aa, 0x0497, 0x35a7, 0x2b1c, 0x22fd, 0x2f29, 0x0169, 0x19bf, 0x0dba, 0x2b71, 0x1eaa, 0x044e, 0x2e7e, + 0x0a28, 0x12e8, 0x03e0, 0x08bd, 0x1301, 0x1c91, 0x1ffc, 0x10b9, 0x1f38, 0x27a6, 0x2b2b, 0x29e4, 0x06c9, 0x2ece, 0x10cd, 0x0c0e, + 0x14c5, 0x294c, 0x0ead, 0x1cd7, 0x2299, 0x1c5b, 0x21d6, 0x2f22, 0x1dd3, 0x3c05, 0x029c, 0x36dc, 0x384b, 0x01fa, 0x0ac2, 0x2c53, + 0x3576, 0x0925, 0x32c8, 0x052a, 0x0fcc, 0x0bc1, 0x0b03, 0x2695, 0x1463, 0x17a8, 0x22e8, 0x2786, 0x3765, 0x0e47, 0x0722, 0x05df, + 0x105f, 0x303f, 0x2aba, 0x19c9, 0x2640, 0x33fa, 0x3ddb, 0x3ce8, 0x3a9e, 0x30c8, 0x1694, 0x2475, 0x3e9d, 0x0678, 0x151b, 0x365f, + 0x3d15, 0x2f0a, 0x0b29, 0x0b5e, 0x37f4, 0x39d4, 0x1cc5, 0x16c1, 0x231a, 0x3d42, 0x329f, 0x295f, 0x1566, 0x3bba, 0x3be7, 0x3a8c, + 0x1bcf, 0x1e20, 0x1d9d, 0x0d92, 0x33cd, 0x2275, 0x181c, 0x219a, 0x3b2f, 0x2a8d, 0x323a, 0x0b4a, 0x1d46, 0x3df3, 0x34af, 0x394f, + 0x0439, 0x3e2e, 0x0f4d, 0x3e70, 0x3065, 0x27f8, 0x13c9, 0x1657, 0x3f14, 0x3782, 0x0cb9, 0x0d79, 0x31d1, 0x0c84, 0x2448, 0x2ad5, + 0x29ee, 0x0c8c, 0x059b, 0x11ba, 0x319a, 0x04b1, 0x1ca5, 0x1b2d, 0x14cc, 0x22db, 0x1b24, 0x3b3a, 0x0c57, 0x2c15, 0x3c40, 0x379e, + 0x06bb, 0x3f36, 0x14ae, 0x25ad, 0x11ed, 0x249d, 0x3e43, 0x02a8, 0x3555, 0x12ce, 0x0335, 0x3038, 0x1b8f, 0x26d4, 0x04eb, 0x279b, + 0x07d3, 0x0ba8, 0x3922, 0x2602, 0x2d07, 0x2b89, 0x2172, 0x3ff8, 0x2637, 0x1676, 0x10f2, 0x290f, 0x1544, 0x3861, 0x37ba, 0x3b02, + 0x01b8, 0x35f3, 0x25d0, 0x1450, 0x3cce, 0x17ef, 0x117a, 0x07c0, 0x1df3, 0x2ab2, 0x0e62, 0x3bf9, 0x3223, 0x18e8, 0x09e4, 0x1832, + 0x3f4e, 0x033c, 0x1d4f, 0x1864, 0x0ab3, 0x1ddd, 0x118d, 0x1ea1, 0x262b, 0x360a, 0x0a66, 0x316d, 0x2dc7, 0x136a, 0x3aaa, 0x0967, + 0x3f98, 0x1af7, 0x0ca5, 0x0553, 0x28a1, 0x3395, 0x0ba2, 0x1e1a, 0x2946, 0x0cf7, 0x075a, 0x3c8a, 0x2be8, 0x1578, 0x0371, 0x063c, + 0x271d, 0x339b, 0x0ded, 0x1d2a, 0x1f7b, 0x3e16, 0x2262, 0x2ff4, 0x3f09, 0x2f7a, 0x0eed, 0x29b3, 0x1139, 0x1ef8, 0x39fb, 0x233a, + 0x11ce, 0x1977, 0x276e, 0x093e, 0x0f81, 0x2082, 0x22f5, 0x3a30, 0x23d0, 0x3993, 0x2151, 0x23dd, 0x2fdf, 0x20c1, 0x399e, 0x3528, + 0x1649, 0x1524, 0x1e91, 0x3007, 0x116b, 0x2b38, 0x17b2, 0x208a, 0x2953, 0x2f69, 0x0b98, 0x3fba, 0x33eb, 0x378d, 0x0b19, 0x31c0, + 0x318c, 0x194f, 0x1e8a, 0x0594, 0x3f89, 0x065c, 0x021c, 0x07a6, 0x34a2, 0x23ac, 0x3fcb, 0x0652, 0x31e7, 0x10a8, 0x28e6, 0x33b6, + 0x1941, 0x28a7, 0x0ed4, 0x31f6, 0x372d, 0x0e14, 0x3ade, 0x02ec, 0x3d0b, 0x011a, 0x1798, 0x0070, 0x38dd, 0x3ebc, 0x3bcc, 0x3d7e, + 0x0ddf, 0x0aab, 0x2bd0, 0x1d79, 0x17c2, 0x340f, 0x0397, 0x332c, 0x26c7, 0x25a3, 0x0ce3, 0x1239, 0x2e93, 0x14d8, 0x2c30, 0x18b5, + 0x381a, 0x12d5, 0x1dfb, 0x2a26, 0x2327, 0x22c8, 0x091b, 0x0ebb, 0x194a, 0x0aa6, 0x1af2, 0x1972, 0x3f31, 0x35ee, 0x2f05, 0x3e29, + 0x12e3, 0x0920, 0x34fb, 0x0313, 0x374e, 0x1f12, 0x3018, 0x23b8, 0x1744, 0x3c34, 0x15ab, 0x0891, 0x1143, 0x272b, 0x1908, 0x23a3, + 0x08c6, 0x0559, 0x3d54, 0x16e3, 0x3130, 0x0fbd, 0x1cfd, 0x089c, 0x1eed, 0x331f, 0x0a8d, 0x1f4e, 0x2c0d, 0x19e6, 0x1a57, 0x2ea2, + 0x1a43, 0x0ec0, 0x02d2, 0x1e53, 0x0a71, 0x2aff, 0x1b74, 0x337e, 0x022c, 0x0b3f, 0x13b2, 0x3da8, 0x1ecb, 0x0751, 0x198d, 0x2550, + 0x39bc, 0x31d9, 0x1956, 0x2bbb, 0x1c14, 0x2d61, 0x125c, 0x169f, 0x0eb4, 0x3915, 0x3ce1, 0x1e9a, 0x128d, 0x19ee, 0x3c5d, 0x0872, + 0x2852, 0x232c, 0x2a6a, 0x1a06, 0x3368, 0x124d, 0x2c72, 0x0bf6, 0x06e2, 0x0c78, 0x2cae, 0x2792, 0x17d1, 0x2af0, 0x0ff1, 0x20cb, + 0x35dd, 0x0cab, 0x2b4f, 0x092e, 0x0d03, 0x1535, 0x05fb, 0x1639, 0x1513, 0x2efd, 0x275d, 0x248d, 0x2189, 0x3a7d, 0x11dc, 0x180c, + 0x08dd, 0x22cd, 0x2d96, 0x2e52, 0x32d6, 0x0a57, 0x0154, 0x3f21, 0x2ce4, 0x155d, 0x1e74, 0x3eed, 0x05af, 0x2594, 0x2b60, 0x2e62, + 0x082f, 0x355c, 0x3d4e, 0x2b49, 0x0de7, 0x0ece, 0x1d97, 0x391c, 0x3fa6, 0x0ea7, 0x1315, 0x2532, 0x138e, 0x06f6, 0x1f84, 0x0776, + 0x00b2, 0x1e00, 0x03ee, 0x38b0, 0x3c73, 0x2fc4, 0x1c88, 0x177c, 0x060c, 0x3efd, 0x3ab4, 0x335d, 0x01d3, 0x29c9, 0x0043, 0x32f5, + 0x2d70, 0x1afd, 0x0835, 0x2669, 0x3fb2, 0x36a8, 0x2d4c, 0x0db2, 0x28db, 0x3d9b, 0x32ff, 0x1486, 0x1802, 0x3fdb, 0x38f9, 0x2036, + 0x2576, 0x2a2b, 0x3c95, 0x3876, 0x1f63, 0x1c7f, 0x362f, 0x32b1, 0x286b, 0x354a, 0x373c, 0x1627, 0x2436, 0x2c03, 0x3490, 0x29a1, + 0x1c0d, 0x296a, 0x3193, 0x1164, 0x2971, 0x0490, 0x1ba7, 0x0f89, 0x1cde, 0x38ec, 0x0e0a, 0x36b0, 0x1429, 0x1196, 0x19b4, 0x2926, + 0x282f, 0x381f, 0x1320, 0x19fd, 0x3e8a, 0x1785, 0x1bfa, 0x1cea, 0x14f7, 0x0646, 0x18cd, 0x2258, 0x235d, 0x1f9b, 0x28f6, 0x324e, + 0x2623, 0x3f9e, 0x3562, 0x30b0, 0x240f, 0x0e81, 0x0403, 0x2388, 0x25f8, 0x1f8e, 0x2e72, 0x0d14, 0x107b, 0x389a, 0x085a, 0x1348, + 0x209b, 0x12da, 0x287d, 0x0816, 0x0092, 0x0d2e, 0x0567, 0x1a2d, 0x359a, 0x1bc5, 0x2708, 0x3f5c, 0x0257, 0x1609, 0x15c3, 0x1c2f, + 0x000d, 0x21a1, 0x1b35, 0x2888, 0x07c9, 0x0483, 0x009e, 0x1b7b, 0x3b0c, 0x2361, 0x2ba5, 0x2137, 0x1a3a, 0x04cf, 0x2c7a, 0x3ac3, + 0x260d, 0x2c35, 0x027a, 0x184c, 0x2ec1, 0x0d88, 0x2def, 0x3a10, 0x2b99, 0x1f9f, 0x0ad9, 0x2eb4, 0x0604, 0x293e, 0x0478, 0x12a0, + 0x2b95, 0x3b08, 0x2b66, 0x0511, 0x224c, 0x3622, 0x3ad4, 0x1a65, 0x0515, 0x28fa, 0x0975, 0x0b7a, 0x2981, 0x2dd9, 0x2e49, 0x13f3, + 0x1eb8, 0x18ba, 0x0dcc, 0x1cb2, 0x15ed, 0x079a, 0x245b, 0x3e0c, 0x2b6a, 0x3252, 0x1a81, 0x2500, 0x1422, 0x1286, 0x33e4, 0x0c50, + 0x217f, 0x19d1, 0x2341, 0x2edc, 0x3497, 0x16d6, 0x3705, 0x24a6, 0x3626, 0x14fb, 0x2119, 0x09ee, 0x2ee3, 0x3503, 0x3a5e, 0x0a02, + 0x2e1e, 0x2e98, 0x1f26, 0x2281, 0x199b, 0x04e0, 0x120e, 0x1708, 0x2250, 0x064a, 0x29dc, 0x3e5e, 0x274b, 0x3c22, 0x137c, 0x1c1d, + 0x0d4b, 0x37c0, 0x2e68, 0x3201, 0x28cf, 0x2845, 0x3e7f, 0x250d, 0x1a69, 0x18d1, 0x0d25, 0x0bb8, 0x280e, 0x27ca, 0x1e3f, 0x18a1, + 0x2da1, 0x14dd, 0x08fb, 0x3d91, 0x21d0, 0x1f6f, 0x1892, 0x2a5f, 0x3ad8, 0x225c, 0x216c, 0x1816, 0x03fd, 0x2d46, 0x05f5, 0x1cf7, + 0x0da1, 0x1823, 0x3e79, 0x3ace, 0x31c8, 0x30bb, 0x02c1, 0x3385, 0x28fe, 0x3e8e, 0x2309, 0x104f, 0x1359, 0x1686, 0x2c1f, 0x1440, + 0x376d, 0x0ce8, 0x24f6, 0x0a7d, 0x1900, 0x3bdf, 0x25db, 0x0c68, 0x0519, 0x1789, 0x3d5d, 0x1419, 0x1037, 0x2aa4, 0x1887, 0x2991, + 0x1120, 0x3867, 0x05b5, 0x3673, 0x0745, 0x0e55, 0x1829, 0x2f3b, 0x0b7e, 0x1bfe, 0x205c, 0x0470, 0x3dc0, 0x38cf, 0x0027, 0x36cc, + 0x0624, 0x123e, 0x1916, 0x2372, 0x076f, 0x3e22, 0x0960, 0x3658, 0x0979, 0x1cee, 0x21fa, 0x342a, 0x01e6, 0x062e, 0x17db, 0x3536, + 0x2148, 0x2f13, 0x3a02, 0x0a33, 0x29a8, 0x3d71, 0x0e20, 0x3175, 0x2ddd, 0x2833, 0x1439, 0x3abc, 0x2348, 0x1b99, 0x3cae, 0x3965, + 0x2ae8, 0x26cc, 0x28c1, 0x2f9d, 0x017b, 0x3de8, 0x0208, 0x1597, 0x2985, 0x3823, 0x3ba1, 0x2515, 0x24d5, 0x1c71, 0x368d, 0x21f1, + 0x32e2, 0x154a, 0x259a, 0x206f, 0x3c51, 0x2bdb, 0x0da7, 0x0f35, 0x13f7, 0x1324, 0x32be, 0x310f, 0x0525, 0x08b8, 0x00ef, 0x3c1a, + 0x144b, 0x25a8, 0x3e6b, 0x0b59, 0x1d74, 0x058f, 0x0939, 0x054e, 0x2e4d, 0x1a01, 0x1e4e, 0x030e, 0x0811, 0x19f8, 0x3871, 0x38ab, + 0x3d8c, 0x227c, 0x1cad, 0x1847, 0x0b54, 0x2f98, 0x236d, 0x0a78, 0x18be, 0x142d, 0x0e8d, 0x07f0, 0x2899, 0x3c6b, 0x0bfe, 0x283a, + 0x0863, 0x039c, 0x3477, 0x07f5, 0x04a4, 0x06b1, 0x0f18, 0x3b60, 0x1ebc, 0x119a, 0x09a1, 0x1018, 0x0c97, 0x1ee4, 0x2064, 0x03c2, + 0x2b7a, 0x2915, 0x1e7a, 0x2425, 0x16b5, 0x330e, 0x338b, 0x2c9d, 0x1cb6, 0x19b8, 0x3055, 0x01a7, 0x3cda, 0x0e03, 0x1b1d, 0x0b91, + 0x1855, 0x3331, 0x18f8, 0x0e92, 0x13bc, 0x0885, 0x3a6d, 0x0212, 0x0dd0, 0x292a, 0x358a, 0x1dc2, 0x3cc0, 0x05c3, 0x2522, 0x2484, + 0x2399, 0x2ac2, 0x1eff, 0x0803, 0x243d, 0x3714, 0x3a44, 0x0cc3, 0x079e, 0x1ce2, 0x1fbc, 0x10b1, 0x19d8, 0x031b, 0x1924, 0x3977, + 0x1fb5, 0x17c7, 0x2112, 0x1432, 0x1d1d, 0x23c5, 0x0844, 0x2210, 0x15f1, 0x38f0, 0x20e6, 0x31ab, 0x0fe3, 0x00f7, 0x3087, 0x3071, + 0x0e38, 0x10f8, 0x3ef3, 0x0acb, 0x2cfb, 0x1c55, 0x02c7, 0x22a6, 0x3e10, 0x0e0e, 0x226f, 0x2b83, 0x36a2, 0x0e7b, 0x0fb7, 0x152f, + 0x0056, 0x3414, 0x1fc9, 0x18c3, 0x317f, 0x1507, 0x158f, 0x1f58, 0x245f, 0x36b4, 0x01f1, 0x3891, 0x285d, 0x24c0, 0x0fff, 0x21b2, + 0x15d9, 0x33d4, 0x30d2, 0x212d, 0x0b21, 0x34f3, 0x2008, 0x2b06, 0x3256, 0x2975, 0x2243, 0x1acf, 0x3aeb, 0x0460, 0x23e6, 0x2de4, + 0x0e4f, 0x2bd5, 0x361c, 0x283f, 0x0e9a, 0x33c4, 0x3308, 0x1c4f, 0x2b6e, 0x0494, 0x06c6, 0x12fe, 0x3848, 0x2296, 0x3762, 0x0fc9, + 0x3b4f, 0x167c, 0x2cea, 0x121d, 0x0a9f, 0x0ea0, 0x30c1, 0x3603, 0x2504, 0x1bab, 0x0b6d, 0x3437, 0x1275, 0x0996, 0x3a4d, 0x1aa7, + 0x3ca4, 0x1d7e, 0x174e, 0x0c03, 0x26fb, 0x15fd, 0x1711, 0x3fef, 0x1a85, 0x0f8d, 0x0272, 0x346f, 0x383d, 0x29ff, 0x2ccf, 0x3ecf, + 0x3f2e, 0x2324, 0x1140, 0x374b, 0x2c0a, 0x312d, 0x1ec8, 0x0a6e, 0x128a, 0x1c11, 0x17ce, 0x3365, 0x2186, 0x0d00, 0x05ac, 0x32d3, + 0x138b, 0x0de4, 0x01d0, 0x3c70, 0x17ff, 0x3faf, 0x2433, 0x1f60, 0x1426, 0x296e, 0x235a, 0x3e87, 0x1078, 0x240c, 0x0254, 0x008f, + 0x3e9a, 0x263d, 0x1563, 0x37f1, 0x1d43, 0x33ca, 0x31ce, 0x3062, 0x0c54, 0x3197, 0x1b8c, 0x11ea, 0x1541, 0x2d04, 0x3220, 0x3ccb, + 0x2dc4, 0x0ab0, 0x2be5, 0x289e, 0x1136, 0x1f78, 0x2fdc, 0x0f7e, 0x33e8, 0x1168, 0x31e4, 0x3f86, 0x38da, 0x372a, 0x2e90, 0x17bf, + 0x15d1, 0x0d99, 0x04b9, 0x35b1, 0x1183, 0x1f3b, 0x302c, 0x02d9, 0x21a5, 0x025b, 0x034e, 0x20ab, 0x2bb2, 0x27a9, 0x3370, 0x396c, + 0x02f6, 0x3bd1, 0x1a8d, 0x07fa, 0x0410, 0x2b2e, 0x39ee, 0x0bea, 0x0011, 0x160d, 0x1722, 0x363a, 0x1642, 0x29e7, 0x1c06, 0x39b5, + 0x0571, 0x3ffe, 0x015a, 0x0ae3, 0x1ad8, 0x06cc, 0x1055, 0x012d, 0x288c, 0x15c7, 0x069f, 0x02b5, 0x0c3e, 0x2ed1, 0x3811, 0x204a, + 0x0288, 0x3d83, 0x25bc, 0x347c, 0x3443, 0x10d0, 0x109b, 0x11b0, 0x1b39, 0x1c33, 0x2237, 0x2dfe, 0x3d66, 0x0c11, 0x0827, 0x3f46, + 0x130b, 0x3047, 0x29ba, 0x1b43, 0x3743, 0x0a2b, 0x3b23, 0x11f6, 0x0487, 0x359e, 0x084b, 0x3cf4, 0x24ad, 0x12eb, 0x122b, 0x16f5, + 0x09ab, 0x38e2, 0x3ede, 0x03a1, 0x2d1b, 0x03e3, 0x14bf, 0x3124, 0x07cd, 0x1bc9, 0x193b, 0x2717, 0x35d7, 0x08c0, 0x261d, 0x2d6a, + 0x2141, 0x2178, 0x3f27, 0x2392, 0x2f59, 0x1304, 0x230f, 0x1bb4, 0x1b7f, 0x270c, 0x1d8e, 0x0583, 0x393f, 0x1c94, 0x3bac, 0x27e7, + 0x0144, 0x3ec1, 0x3a21, 0x0868, 0x22b8, 0x1fff, 0x0d6c, 0x0366, 0x00a2, 0x3f60, 0x115c, 0x2fff, 0x30a0, 0x10bc, 0x37ac, 0x0982, + 0x35b9, 0x1da4, 0x0f56, 0x187d, 0x3795, 0x2f2c, 0x20b5, 0x1e5a, 0x2365, 0x0096, 0x1768, 0x3024, 0x0f9d, 0x016c, 0x13d4, 0x3cb5, + 0x072a, 0x179d, 0x1c67, 0x3b65, 0x185d, 0x19c2, 0x2b42, 0x2a1f, 0x3b10, 0x0d32, 0x16ec, 0x09f9, 0x0241, 0x0dbd, 0x0267, 0x1d61, + 0x0d45, 0x2b8f, 0x32dc, 0x111a, 0x0e32, 0x2b74, 0x3e94, 0x3b49, 0x213b, 0x056b, 0x26e4, 0x0d3f, 0x3279, 0x1ead, 0x2c89, 0x30fb, + 0x3e54, 0x0075, 0x3d2c, 0x0f1d, 0x1ab6, 0x0451, 0x0913, 0x3dd3, 0x2ba9, 0x1a31, 0x3696, 0x1be8, 0x0955, 0x2e81, 0x1664, 0x328d, + 0x2f60, 0x3d1e, 0x0ef4, 0x11fe, 0x162e, 0x172c, 0x0b0d, 0x3612, 0x04d3, 0x209f, 0x2217, 0x0614, 0x370c, 0x16ce, 0x3571, 0x0a23, + 0x0434, 0x3d10, 0x01b3, 0x06b6, 0x11c9, 0x3f93, 0x0dda, 0x3187, 0x1a3e, 0x12de, 0x08d8, 0x284d, 0x2571, 0x00ad, 0x2096, 0x282a, + 0x26ea, 0x2d0d, 0x0a5d, 0x26b3, 0x2101, 0x049a, 0x2904, 0x2c46, 0x3ac7, 0x2881, 0x2126, 0x1840, 0x1876, 0x35aa, 0x08a7, 0x34cb, + 0x0c2d, 0x011f, 0x2d59, 0x04a9, 0x2206, 0x2b1f, 0x1a20, 0x3eb1, 0x2c7e, 0x081a, 0x03b6, 0x20f1, 0x175f, 0x2300, 0x0af5, 0x2a0f, + 0x0291, 0x1e27, 0x31a2, 0x34d2, 0x3405, 0x1466, 0x1770, 0x1a4a, 0x2c39, 0x107f, 0x3b84, 0x2b15, 0x1c9e, 0x17ab, 0x1255, 0x1ba0, + 0x1351, 0x3ae3, 0x0f95, 0x101d, 0x1c40, 0x22eb, 0x3142, 0x3c7e, 0x2611, 0x389e, 0x0909, 0x0a45, 0x1d34, 0x2789, 0x0b86, 0x3981, + 0x1eb3, 0x2608, 0x2d9c, 0x2e19, 0x061f, 0x3768, 0x1446, 0x2ae3, 0x1850, 0x085e, 0x0051, 0x1fb0, 0x3c9f, 0x0e4a, 0x2dbf, 0x1386, + 0x0283, 0x02f1, 0x013f, 0x09a6, 0x3e4f, 0x0725, 0x0c28, 0x042f, 0x027e, 0x134c, 0x36f9, 0x068c, 0x0506, 0x05e2, 0x1d0a, 0x173b, + 0x1bbb, 0x1067, 0x2f81, 0x1a96, 0x2872, 0x3579, 0x2403, 0x1cd1, 0x0d8c, 0x25fc, 0x1d24, 0x31f0, 0x16dd, 0x0928, 0x2663, 0x30aa, + 0x0691, 0x3732, 0x108b, 0x119f, 0x395d, 0x32cb, 0x0a1b, 0x3cff, 0x2ec5, 0x1f92, 0x0424, 0x34db, 0x3091, 0x052d, 0x110a, 0x2778, + 0x327f, 0x3928, 0x2e58, 0x2c5c, 0x3759, 0x0fcf, 0x2c25, 0x161a, 0x3a14, 0x2e76, 0x31b8, 0x291e, 0x0a0c, 0x0bc4, 0x053e, 0x2673, + 0x36fe, 0x0e19, 0x3a3d, 0x1ec1, 0x3b1c, 0x0b06, 0x23fc, 0x1de8, 0x2df3, 0x0d18, 0x078e, 0x003a, 0x04fc, 0x2698, 0x1db2, 0x0bce, + 0x04c1, 0x1bd6, 0x37ff, 0x08ae, 0x33f3, 0x1dd6, 0x22c1, 0x0ec7, 0x1fa3, 0x2413, 0x16ff, 0x311b, 0x1025, 0x3c08, 0x215a, 0x234f, + 0x05e7, 0x0ed9, 0x001d, 0x03c7, 0x3339, 0x029f, 0x148f, 0x18dc, 0x2b9d, 0x0e85, 0x0346, 0x3b7c, 0x09c3, 0x36df, 0x0fd8, 0x2028, + 0x3101, 0x0bae, 0x08e3, 0x12b7, 0x315a, 0x384e, 0x168c, 0x1aea, 0x2eb8, 0x0407, 0x00bc, 0x1269, 0x30e6, 0x01fd, 0x0ccc, 0x13a4, + 0x050b, 0x31fb, 0x366d, 0x2069, 0x241f, 0x0ac5, 0x1217, 0x37eb, 0x0add, 0x238c, 0x1114, 0x26ad, 0x2e13, 0x2c56, 0x12b1, 0x3907, + 0x2316, 0x3a9a, 0x3f10, 0x3b2b, 0x3551, 0x14c8, 0x1def, 0x2633, 0x2942, 0x2627, 0x23cc, 0x3f05, 0x349e, 0x294f, 0x26c3, 0x3d07, + 0x1740, 0x1946, 0x0228, 0x1ee9, 0x06de, 0x0eb0, 0x2ce0, 0x150f, 0x0608, 0x3fa2, 0x2867, 0x28d7, 0x14f3, 0x1cda, 0x3596, 0x25f4, + 0x2c8f, 0x07d9, 0x22d3, 0x390d, 0x132f, 0x229c, 0x135f, 0x07b3, 0x12a4, 0x3566, 0x27d4, 0x0083, 0x24ed, 0x1c5e, 0x0f6b, 0x0389, + 0x1d0f, 0x28ac, 0x3f6d, 0x0c9c, 0x16ab, 0x21d9, 0x00d8, 0x246a, 0x047c, 0x30b4, 0x2f91, 0x34ec, 0x1f34, 0x2f25, 0x145f, 0x1dcf, + 0x06d7, 0x3956, 0x11c2, 0x2d14, 0x17f8, 0x1d16, 0x0174, 0x1994, 0x37c4, 0x01d7, 0x09cb, 0x30dc, 0x1bf1, 0x1ff3, 0x2a72, 0x0a3a, + 0x1e2c, 0x28eb, 0x2cd7, 0x242a, 0x00c5, 0x133e, 0x2224, 0x255e, 0x0d4f, 0x29cd, 0x037f, 0x3263, 0x0d0c, 0x0068, 0x36d4, 0x1b5f, + 0x007b, 0x1838, 0x11e2, 0x3107, 0x325f, 0x30d8, 0x0a83, 0x2fab, 0x3205, 0x0047, 0x1fd7, 0x2faf, 0x3b94, 0x0bdf, 0x2fbb, 0x27be, + 0x0296, 0x33bb, 0x1965, 0x1e7f, 0x334b, 0x25e6, 0x2582, 0x2ef3, 0x2e6c, 0x32f9, 0x2757, 0x0a87, 0x1792, 0x0ee7, 0x10ec, 0x3234, + 0x2713, 0x3cf0, 0x2ffb, 0x057f, 0x3636, 0x20a7, 0x2dfa, 0x02b1, 0x2849, 0x0610, 0x20ed, 0x183c, 0x09f5, 0x3020, 0x1be4, 0x0d3b, + 0x34d7, 0x31ec, 0x0036, 0x291a, 0x0a41, 0x2b11, 0x0688, 0x1fac, 0x28d3, 0x3f01, 0x34e8, 0x007f, 0x3b78, 0x3117, 0x26a9, 0x1265, + 0x3e5a, 0x09ea, 0x1812, 0x0bb4, 0x2eb0, 0x2133, 0x24fc, 0x0b76, 0x2511, 0x3ab8, 0x030a, 0x310b, 0x1415, 0x104b, 0x3426, 0x046c, + 0x31a7, 0x10ad, 0x388d, 0x2b7f, 0x1014, 0x07ec, 0x1dbe, 0x01a3, 0x3e83, 0x3361, 0x3f82, 0x11e6, 0x12fa, 0x1acb, 0x346b, 0x3433, + 0x1f43, 0x34b6, 0x3e37, 0x26f1, 0x3fc2, 0x28b3, 0x344e, 0x2557, 0x18d5, 0x3c77, 0x2a18, 0x0be3, 0x1c48, 0x3b59, 0x0c61, 0x3a09, + 0x146b, 0x3fd0, 0x0f74, 0x2ca2, 0x3a75, 0x3859, 0x264d, 0x3455, 0x1a6d, 0x2fc8, 0x08cf, 0x3b98, 0x201c, 0x268b, 0x0f60, 0x070c, + 0x0f23, 0x18ee, 0x218f, 0x08e9, 0x0195, 0x15df, 0x0cee, 0x2cbd, 0x0bbc, 0x1c8c, 0x0e73, 0x27c2, 0x0f0b, 0x2f4e, 0x03d1, 0x1043, + 0x340a, 0x0657, 0x207d, 0x3390, 0x17ea, 0x2498, 0x27f3, 0x39cf, 0x0d29, 0x1780, 0x1c7a, 0x2fbf, 0x0a52, 0x1248, 0x2afa, 0x1f0d, + 0x1b86, 0x0b67, 0x2269, 0x304f, 0x32b8, 0x2056, 0x0d1f, 0x096f, 0x27ce, 0x00b6, 0x31b2, 0x004b, 0x2120, 0x26de, 0x1d88, 0x0699, + 0x1a4f, 0x34a7, 0x14a1, 0x3313, 0x2a79, 0x0e6d, 0x0304, 0x1fd1, 0x2812, 0x1e04, 0x2fd1, 0x3209, 0x24e1, 0x3b6f, 0x35ce, 0x2742, + 0x3d32, 0x3229, 0x3a83, 0x12bd, 0x10e2, 0x33da, 0x3773, 0x3517, 0x18a5, 0x03f2, 0x2a7f, 0x2fb3, 0x2db7, 0x3809, 0x1b15, 0x2e41, + 0x1775, 0x23b1, 0x1e13, 0x16ba, 0x2d3c, 0x1ac1, 0x33a7, 0x2d80, 0x1e43, 0x38b4, 0x0327, 0x1fdb, 0x39ac, 0x1297, 0x112a, 0x1b56, + 0x3485, 0x3dfa, 0x05a3, 0x26ba, 0x3244, 0x3f74, 0x0fa5, 0x1ed2, 0x14e1, 0x1392, 0x36e7, 0x25ea, 0x02e4, 0x2380, 0x1a0e, 0x2f1a, + 0x1084, 0x0221, 0x3ed7, 0x01ac, 0x210b, 0x01c9, 0x1f1f, 0x28ba, 0x2da5, 0x06fa, 0x09b9, 0x334f, 0x0445, 0x19ab, 0x002f, 0x149a, + 0x0457, 0x3bff, 0x2763, 0x3160, 0x21e3, 0x200e, 0x0c6e, 0x2a47, 0x3d95, 0x1f88, 0x3319, 0x2ef7, 0x2f74, 0x0114, 0x2a87, 0x1670, + 0x2c3e, 0x07ab, 0x0f2d, 0x305a, 0x3db2, 0x2e33, 0x350f, 0x15a1, 0x08ff, 0x077a, 0x1b09, 0x2586, 0x035b, 0x20d9, 0x38c3, 0x06ed, + 0x058a, 0x3de3, 0x3e1d, 0x3bda, 0x1f6a, 0x04db, 0x0795, 0x0d83, 0x1f73, 0x3faa, 0x15f8, 0x33bf, 0x1502, 0x23c0, 0x0880, 0x06ac, + 0x2b1a, 0x3f8e, 0x044c, 0x19bd, 0x1ffa, 0x03de, 0x10cb, 0x2b29, 0x21d4, 0x0eab, 0x0ac0, 0x029a, 0x0b01, 0x32c6, 0x0720, 0x22e6, + 0x1abc, 0x0e68, 0x2493, 0x3854, 0x07e7, 0x2b0c, 0x25e1, 0x1339, 0x2a63, 0x1319, 0x14a7, 0x1e83, 0x314d, 0x03d9, 0x2e2e, 0x01c4, + 0x3b89, 0x0661, 0x018d, 0x1cbb, 0x0e2a, 0x3152, 0x073d, 0x0a97, 0x1896, 0x2536, 0x267f, 0x1969, 0x39e4, 0x3830, 0x3681, 0x1e65, + 0x118b, 0x1d4d, 0x3aa8, 0x0a64, 0x0ba0, 0x0ca3, 0x036f, 0x0758, 0x2260, 0x0deb, 0x39f9, 0x0eeb, 0x22f3, 0x276c, 0x399c, 0x214f, + 0x17b0, 0x1e8f, 0x0b17, 0x0b96, 0x021a, 0x1e88, 0x28e4, 0x3fc9, 0x3adc, 0x0ed2, 0x3bca, 0x1796, 0x0395, 0x2bce, 0x2c2e, 0x0ce1, + 0x3dd9, 0x2ab8, 0x1519, 0x1692, 0x1cc3, 0x0b27, 0x3be5, 0x329d, 0x181a, 0x1d9b, 0x34ad, 0x3238, 0x13c7, 0x0f4b, 0x2446, 0x0cb7, + 0x1ca3, 0x0599, 0x3c3e, 0x1b22, 0x3e41, 0x14ac, 0x04e9, 0x0333, 0x2170, 0x3920, 0x37b8, 0x10f0, 0x1178, 0x25ce, 0x09e2, 0x0e60, + 0x1d95, 0x3d4c, 0x1f82, 0x1313, 0x1c86, 0x03ec, 0x0041, 0x3ab2, 0x2d4a, 0x0833, 0x38f7, 0x32fd, 0x362d, 0x3c93, 0x348e, 0x373a, + 0x1ba5, 0x3191, 0x19b2, 0x0e08, 0x1bf8, 0x131e, 0x28f4, 0x18cb, 0x0401, 0x3560, 0x0858, 0x2e70, 0x0565, 0x287b, 0x15c1, 0x2706, + 0x0919, 0x1df9, 0x2f03, 0x1af0, 0x3016, 0x34f9, 0x1906, 0x15a9, 0x1cfb, 0x3d52, 0x1a55, 0x0a8b, 0x1b72, 0x02d0, 0x198b, 0x13b0, + 0x125a, 0x1954, 0x3c5b, 0x3cdf, 0x2c70, 0x2a68, 0x0fef, 0x2cac, 0x05f9, 0x2b4d, 0x11da, 0x275b, 0x0152, 0x2d94, 0x2b5e, 0x1e72, + 0x2896, 0x0b51, 0x0c94, 0x04a1, 0x3cd7, 0x16b2, 0x3cbd, 0x13b9, 0x19d5, 0x243a, 0x0fe0, 0x1d1a, 0x369f, 0x2cf8, 0x285a, 0x317c, + 0x3ae8, 0x0b1e, 0x3845, 0x0e97, 0x1272, 0x0a9c, 0x383a, 0x26f8, 0x2183, 0x2c07, 0x1075, 0x17fc, 0x153e, 0x1d40, 0x38d7, 0x1133, + 0x1a37, 0x07c6, 0x0601, 0x2ebe, 0x297e, 0x2249, 0x141f, 0x15ea, 0x2ee0, 0x3494, 0x2748, 0x1998, 0x280b, 0x28cc, 0x03fa, 0x21cd, + 0x1356, 0x31c5, 0x1034, 0x18fd, 0x3dbd, 0x0742, 0x01e3, 0x076c, 0x2345, 0x29a5, 0x24d2, 0x0178, 0x0522, 0x3c4e, 0x080e, 0x1d71, + 0x1c9b, 0x3402, 0x1d31, 0x1c3d, 0x3c9c, 0x061c, 0x0503, 0x3e4c, 0x16da, 0x286f, 0x308e, 0x395a, 0x0a09, 0x3756, 0x04f9, 0x3b19, + 0x1022, 0x33f0, 0x09c0, 0x3336, 0x30e3, 0x3157, 0x2e10, 0x241c, 0x349b, 0x354e, 0x14f0, 0x06db, 0x24ea, 0x132c, 0x1f31, 0x16a8, + 0x2baf, 0x1180, 0x163f, 0x040d, 0x0c3b, 0x1ad5, 0x3d63, 0x3440, 0x24aa, 0x3740, 0x35d4, 0x2d18, 0x393c, 0x2f56, 0x309d, 0x22b5, + 0x0f9a, 0x3792, 0x023e, 0x185a, 0x3276, 0x0e2f, 0x0952, 0x1ab3, 0x3709, 0x162b, 0x256e, 0x11c6, 0x1873, 0x20fe, 0x175c, 0x2203, + 0x02e1, 0x3241, 0x0442, 0x2108, 0x2f71, 0x21e0, 0x0358, 0x3daf, 0x14ff, 0x1f67, 0x0afe, 0x1ff7, 0x314a, 0x07e4, 0x39e1, 0x0e27, + 0x22f0, 0x0b9d, 0x0392, 0x0217, 0x13c4, 0x1cc0, 0x1175, 0x3e3e, 0x362a, 0x1c83, 0x0562, 0x1bf5, 0x1b6f, 0x3013, 0x014f, 0x2c6d, + 0x1bee, 0x17f5, 0x0d09, 0x00c2, 0x3b91, 0x325c, 0x178f, 0x3348, 0x09f2, 0x3633, 0x3b75, 0x0a3e, 0x1412, 0x2ead, 0x12f7, 0x1011, + 0x1c45, 0x3fbf, 0x2019, 0x3a72, 0x0f08, 0x0192, 0x0a4f, 0x17e7, 0x211d, 0x32b5, 0x24de, 0x2a76, 0x2db4, 0x10df, 0x39a9, 0x2d39, + 0x3946, 0x0b32, 0x0df4, 0x1b4b, 0x387d, 0x3644, 0x269f, 0x1372, 0x3507, 0x257a, 0x3078, 0x01db, 0x3a65, 0x2453, 0x0c20, 0x1093, + 0x3c83, 0x2958, 0x3356, 0x088a, 0x09d2, 0x0666, 0x2934, 0x005e, 0x2ee7, 0x2a2f, 0x1a76, 0x37c8, 0x21c4, 0x27b5, 0x2041, 0x13ea, + 0x369c, 0x3cd4, 0x153b, 0x126f, 0x2808, 0x297b, 0x051f, 0x3dba, 0x0a06, 0x3c99, 0x24e7, 0x30e0, 0x3939, 0x0c38, 0x1870, 0x3273, + 0x3147, 0x2f6e, 0x1b6c, 0x13c1, 0x140f, 0x3b8e, 0x2db1, 0x0f05, 0x3a62, 0x387a, 0x21c1, 0x09cf, 0x3936, 0x2805, 0x3933, 0x140c, + 0x25c5, 0x2a94, 0x29f6, 0x2c4d, 0x0b35, 0x00df, 0x13dc, 0x0233, 0x2e9c, 0x1806, 0x2030, 0x1342, 0x3949, 0x3afc, 0x2334, 0x3d78, + 0x38a3, 0x17b7, 0x2a07, 0x1dc7, 0x1b4e, 0x1e6a, 0x1404, 0x34bd, 0x2e22, 0x3fdf, 0x0784, 0x00c9, 0x0df7, 0x2bfa, 0x3dc8, 0x192e, + 0x2e87, 0x1456, 0x2b55, 0x30ec, 0x3647, 0x23ec, 0x2997, 0x114e, 0x2285, 0x38fd, 0x320f, 0x2562, 0x3880, 0x05d7, 0x18ad, 0x1c27, + 0x2616, 0x208f, 0x1103, 0x358f, 0x1375, 0x3686, 0x3080, 0x024d, 0x1f2a, 0x203a, 0x0d5b, 0x2228, 0x26a2, 0x35c7, 0x0719, 0x15ba, + 0x27ee, 0x2648, 0x33a2, 0x02ff, 0x257d, 0x221f, 0x1db9, 0x0683, 0x04e4, 0x28df, 0x0fea, 0x28ef, 0x350a, 0x1f1a, 0x0738, 0x10c6, + 0x0a4a, 0x1170, 0x2dac, 0x292f, 0x01de, 0x3835, 0x094d, 0x2e0b, 0x199f, 0x3d9f, 0x36c1, 0x1e30, 0x307b, 0x13ff, 0x0d62, 0x0948, + 0x095b, 0x25d6, 0x0934, 0x0203, 0x2456, 0x2dea, 0x188d, 0x1209, 0x170c, 0x3303, 0x2fd7, 0x242e, 0x3a68, 0x0f13, 0x158a, 0x083f, + 0x090e, 0x2b3d, 0x1a1b, 0x0dd5, 0x1096, 0x39e9, 0x0d67, 0x14ba, 0x1212, 0x148a, 0x00d3, 0x2cdb, 0x0c23, 0x313d, 0x23f7, 0x0a16, + 0x3034, 0x3b36, 0x3bf5, 0x290b, 0x295b, 0x2471, 0x0d75, 0x0b46, 0x064e, 0x3fb6, 0x1235, 0x006c, 0x3c86, 0x3169, 0x23d9, 0x29af, + 0x278e, 0x1e96, 0x3ee9, 0x2489, 0x088d, 0x196e, 0x3da4, 0x1f4a, 0x2254, 0x36ac, 0x3f58, 0x0d10, 0x3359, 0x252e, 0x1623, 0x1482, + 0x3293, 0x35f9, 0x35e3, 0x0cd2, 0x0669, 0x3af1, 0x2aaa, 0x1555, 0x3e62, 0x2d50, 0x1e0a, 0x1b63, 0x09d5, 0x2658, 0x371d, 0x281e, + 0x1d39, 0x300c, 0x2bf3, 0x2527, 0x0061, 0x2684, 0x19a4, 0x2bc7, 0x29e0, 0x0db6, 0x2782, 0x36d8, 0x2937, 0x2a9d, 0x1edd, 0x228f, + 0x3bb3, 0x1571, 0x2724, 0x29c2, 0x2a32, 0x2d24, 0x0bd5, 0x2dcf, 0x3c26, 0x2d74, 0x00fe, 0x29d1, 0x2eea, 0x0763, 0x3e03, 0x11a7, + 0x3986, 0x164e, 0x0701, 0x05c8, 0x37cb, 0x253b, 0x1e35, 0x341c, 0x274f, 0x1b01, 0x24ca, 0x0d53, 0x1a79, 0x3582, 0x222f, 0x36f1, + 0x166a, 0x01be, 0x0cb1, 0x13aa, 0x27b8, 0x0466, 0x103d, 0x2e3b, 0x1c21, 0x0839, 0x2818, 0x3267, 0x21c7, 0x22af, 0x100b, 0x326d, + 0x0b8b, 0x1529, 0x1aa1, 0x3cc5, 0x13ed, 0x189b, 0x36c6, 0x3c14, 0x1380, 0x266d, 0x139e, 0x0383, 0x2044, 0x27e1, 0x30f5, 0x34c5, + 0x0aef, 0x165e, 0x37a6, 0x0821, 0x1459, 0x12ab, 0x1dac, 0x1d04, 0x386b, 0x17d5, 0x05ef, 0x33de, 0x2e8a, 0x2cc9, 0x0ff9, 0x251c, + 0x392d, 0x39a3, 0x1756, 0x0808, 0x30ef, 0x1ed7, 0x23f1, 0x0713, 0x1124, 0x2af4, 0x3465, 0x10e6, 0x2b58, 0x09dc, 0x367b, 0x38bd, + 0x1daa, 0x37a4, 0x0ff7, 0x05ed, 0x23ef, 0x1754, 0x3679, 0x3463, 0x3677, 0x0ff5, 0x351d, 0x351b, 0x364a, 0x2d2e, 0x351f, 0x37d1, + 0x3284, 0x352d, 0x2d30, 0x1f04, 0x1151, 0x0faa, 0x364c, 0x0107, 0x05b9, 0x20cf, 0x37d3, 0x3777, 0x299a, 0x2549, 0x3521, 0x2ace, + 0x3ec8, 0x247d, 0x352f, 0x0c49, 0x3900, 0x1734, 0x3286, 0x3f3f, 0x0e59, 0x06e6, 0x1f06, 0x322d, 0x2288, 0x15b3, 0x2d32, 0x1d6a, + 0x2c61, 0x2fe4, 0x0fac, 0x2ac7, 0x2565, 0x3f79, 0x1153, 0x2163, 0x0749, 0x0c7c, 0x0109, 0x3d36, 0x3212, 0x0f3d, 0x364e, 0x39c5, + 0x35bf, 0x3c46, 0x20d1, 0x0edf, 0x05da, 0x0c09, 0x05bb, 0x127e, 0x2f3f, 0x2cb2, 0x3779, 0x12c1, 0x3883, 0x08f1, 0x37d5, 0x2541, + 0x2e5d, 0x20c6, 0x254b, 0x239e, 0x1c2a, 0x3249, 0x299c, 0x32f0, 0x182d, 0x2796, 0x2ad0, 0x3a87, 0x18b0, 0x33b1, 0x3523, 0x0637, + 0x0263, 0x13d0, 0x1660, 0x2c85, 0x2092, 0x356d, 0x0af1, 0x08a3, 0x1c02, 0x336c, 0x0823, 0x380d, 0x2619, 0x1227, 0x37a8, 0x3ba8, + 0x0fd4, 0x2156, 0x12ad, 0x0cc8, 0x3592, 0x26bf, 0x145b, 0x0f67, 0x0b82, 0x1251, 0x1d06, 0x2dbb, 0x1106, 0x265f, 0x1dae, 0x053a, + 0x1883, 0x2c1b, 0x17d7, 0x0023, 0x3689, 0x3caa, 0x386d, 0x00eb, 0x0474, 0x2c76, 0x33e0, 0x2e45, 0x1378, 0x3a5a, 0x05f1, 0x1e3b, + 0x375e, 0x23e2, 0x2ccb, 0x3a49, 0x0250, 0x05a8, 0x2e8c, 0x321c, 0x2060, 0x0bfa, 0x251e, 0x1b19, 0x3083, 0x1920, 0x0ffb, 0x0fb3, + 0x014b, 0x39dd, 0x39a5, 0x12f3, 0x203d, 0x0c1c, 0x392f, 0x186c, 0x38d3, 0x2856, 0x080a, 0x03f6, 0x1f2d, 0x04f5, 0x1758, 0x3099, + 0x161f, 0x23d5, 0x1ed9, 0x3719, 0x222b, 0x3dff, 0x30f1, 0x1007, 0x3dc4, 0x2330, 0x0715, 0x18a9, 0x0d5e, 0x0734, 0x23f3, 0x1586, + 0x0f5c, 0x0c5d, 0x2af6, 0x03cd, 0x35ca, 0x1d84, 0x1126, 0x1b11, 0x36d0, 0x2a6e, 0x10e8, 0x2fb7, 0x26a5, 0x1be0, 0x3467, 0x3422, + 0x2c2a, 0x3998, 0x09de, 0x2442, 0x15bd, 0x348a, 0x2b5a, 0x1987, 0x002b, 0x1a0a, 0x38bf, 0x2a83, 0x071c, 0x087c, 0x367d, 0x2e2a, + 0x10d9, 0x27ff, 0x3c48, 0x20f8, 0x2a97, 0x27db, 0x35c1, 0x3137, 0x1242, 0x1291, 0x0ee1, 0x1ac5, 0x25c8, 0x2d8e, 0x20d3, 0x382a, + 0x2e7b, 0x22fa, 0x0c0b, 0x10b6, 0x2c50, 0x2f1f, 0x05dc, 0x2692, 0x0628, 0x19f2, 0x1280, 0x2d40, 0x29f9, 0x3724, 0x05bd, 0x24ba, + 0x2f32, 0x3b40, 0x2cb4, 0x333f, 0x00e2, 0x1717, 0x2f41, 0x2a53, 0x2376, 0x3c61, 0x12c3, 0x2d84, 0x0b38, 0x3543, 0x377b, 0x398c, + 0x3a19, 0x3a35, 0x08f3, 0x1fc1, 0x0236, 0x1a13, 0x3885, 0x0185, 0x191a, 0x0876, 0x2543, 0x33ab, 0x13df, 0x37dd, 0x37d7, 0x2feb, + 0x086f, 0x169c, 0x20c8, 0x0bf3, 0x1809, 0x1636, 0x2e5f, 0x3f1e, 0x3e26, 0x0eb8, 0x23a0, 0x23b5, 0x2e9f, 0x0899, 0x254d, 0x337b, + 0x2923, 0x0f86, 0x324b, 0x1ce7, 0x1345, 0x2385, 0x1c2c, 0x1a2a, 0x0773, 0x3919, 0x32f2, 0x1779, 0x2033, 0x0daf, 0x299e, 0x32ae, + 0x379b, 0x1b2a, 0x2798, 0x02a5, 0x3aff, 0x3ff5, 0x182f, 0x07bd, 0x365c, 0x3ce5, 0x3a89, 0x16be, 0x394c, 0x2197, 0x2ad2, 0x1654, + 0x31bd, 0x2087, 0x33b3, 0x07a3, 0x3d7b, 0x02e9, 0x18b2, 0x3329, 0x0964, 0x1e9e, 0x0639, 0x1e17, 0x2337, 0x2ff1, 0x3525, 0x3a2d, + 0x21ad, 0x306c, 0x247f, 0x03bd, 0x17ba, 0x008a, 0x3eca, 0x0fc4, 0x1cf2, 0x1c18, 0x0c4b, 0x129b, 0x38a6, 0x21ec, 0x3531, 0x298c, + 0x0bc9, 0x2773, 0x1736, 0x397c, 0x1dca, 0x25ef, 0x3902, 0x2023, 0x097d, 0x2d65, 0x3f41, 0x39b0, 0x2a0a, 0x2825, 0x3288, 0x1d5c, + 0x1e60, 0x22e1, 0x06e8, 0x1495, 0x1e6d, 0x2701, 0x0e5b, 0x0cdc, 0x342e, 0x1260, 0x322f, 0x1b5a, 0x1b51, 0x273d, 0x1f08, 0x0707, + 0x0a11, 0x0943, 0x15b5, 0x1929, 0x34c0, 0x36ec, 0x228a, 0x147d, 0x21fe, 0x16a3, 0x1d6c, 0x112e, 0x1407, 0x13e5, 0x2d34, 0x2c68, + 0x3a28, 0x32a9, 0x2fe6, 0x24b5, 0x3fe2, 0x03aa, 0x2c63, 0x1d57, 0x0632, 0x39c0, 0x2ac9, 0x38b8, 0x2e25, 0x1581, 0x0fae, 0x0535, + 0x2678, 0x11d3, 0x3f7b, 0x0320, 0x00cc, 0x1397, 0x2567, 0x21ba, 0x01ea, 0x31dd, 0x2165, 0x1e47, 0x0787, 0x2f8a, 0x1155, 0x03af, + 0x20bb, 0x14d2, 0x0c7e, 0x18e2, 0x2bfd, 0x1603, 0x074b, 0x258e, 0x353a, 0x195a, 0x3d38, 0x1fdf, 0x0dfa, 0x0e41, 0x010b, 0x05ce, + 0x0543, 0x197c, 0x0f3f, 0x19dd, 0x1931, 0x14e6, 0x3214, 0x1475, 0x17df, 0x2bbf, 0x39c7, 0x032b, 0x3dcb, 0x37e3, 0x3650, 0x3fe7, + 0x02bf, 0x3e77, 0x2c1d, 0x2307, 0x25d9, 0x24f4, 0x1885, 0x3d5b, 0x1827, 0x05b3, 0x0025, 0x205a, 0x095e, 0x1914, 0x17d9, 0x21f8, + 0x0e1e, 0x3a00, 0x3cac, 0x1437, 0x0206, 0x28bf, 0x368b, 0x3b9f, 0x0da5, 0x2598, 0x00ed, 0x32bc, 0x0937, 0x3e69, 0x386f, 0x1e4c, + 0x009c, 0x1b33, 0x2c78, 0x2ba3, 0x2ded, 0x0278, 0x0476, 0x0ad7, 0x3ad2, 0x2b64, 0x2e47, 0x0973, 0x2459, 0x0dca, 0x33e2, 0x1a7f, + 0x3703, 0x233f, 0x3a5c, 0x2117, 0x120c, 0x1f24, 0x137a, 0x29da, 0x3e7d, 0x2e66, 0x1e3d, 0x0d23, 0x1890, 0x08f9, 0x05f3, 0x216a, + 0x2006, 0x30d0, 0x23e4, 0x2241, 0x3306, 0x361a, 0x3760, 0x06c4, 0x30bf, 0x2ce8, 0x3a4b, 0x0b6b, 0x170f, 0x174c, 0x2ccd, 0x0270, + 0x1ec6, 0x113e, 0x05aa, 0x17cc, 0x2431, 0x01ce, 0x0252, 0x2358, 0x31cc, 0x1561, 0x321e, 0x1b8a, 0x2fda, 0x2be3, 0x2e8e, 0x31e2, + 0x236b, 0x1cab, 0x0bfc, 0x0e8b, 0x0f16, 0x3475, 0x2062, 0x099f, 0x3389, 0x1e78, 0x1b1b, 0x3053, 0x3a6b, 0x18f6, 0x2520, 0x3588, + 0x3a42, 0x1efd, 0x1922, 0x1fba, 0x0842, 0x2110, 0x3085, 0x20e4, 0x02c5, 0x3ef1, 0x0fb5, 0x226d, 0x158d, 0x1fc7, 0x0ffd, 0x01ef, + 0x20b3, 0x0f54, 0x13d2, 0x1766, 0x2b40, 0x1c65, 0x0265, 0x16ea, 0x3e92, 0x32da, 0x2c87, 0x26e2, 0x0911, 0x3d2a, 0x1662, 0x3694, + 0x0b0b, 0x0ef2, 0x356f, 0x2215, 0x0dd8, 0x01b1, 0x2094, 0x08d6, 0x2902, 0x0a5b, 0x08a5, 0x2124, 0x1a1e, 0x2d57, 0x0af3, 0x03b4, + 0x302a, 0x04b7, 0x336e, 0x034c, 0x39ec, 0x1a8b, 0x1c04, 0x1720, 0x1053, 0x0158, 0x380f, 0x069d, 0x1099, 0x25ba, 0x0825, 0x2235, + 0x3b21, 0x29b8, 0x1229, 0x0849, 0x14bd, 0x3edc, 0x261b, 0x1939, 0x230d, 0x3f25, 0x3baa, 0x1d8c, 0x0d6a, 0x3a1f, 0x37aa, 0x115a, + 0x22bf, 0x37fd, 0x2158, 0x16fd, 0x148d, 0x001b, 0x0fd6, 0x0344, 0x168a, 0x08e1, 0x0cca, 0x00ba, 0x1215, 0x366b, 0x12af, 0x1112, + 0x1ded, 0x3f0e, 0x26c1, 0x23ca, 0x2cde, 0x0226, 0x3594, 0x2865, 0x135d, 0x22d1, 0x0f69, 0x27d2, 0x00d6, 0x3f6b, 0x145d, 0x2f8f, + 0x176e, 0x31a0, 0x1253, 0x3b82, 0x3140, 0x0f93, 0x0b84, 0x0907, 0x1444, 0x2d9a, 0x2dbd, 0x004f, 0x0c26, 0x013d, 0x1d08, 0x36f7, + 0x2401, 0x2f7f, 0x2661, 0x1d22, 0x0a19, 0x1089, 0x1108, 0x0422, 0x2c23, 0x2e56, 0x053c, 0x31b6, 0x23fa, 0x3a3b, 0x1db0, 0x078c, + 0x344c, 0x3e35, 0x0c5f, 0x2a16, 0x264b, 0x0f72, 0x0f5e, 0x08cd, 0x0cec, 0x218d, 0x03cf, 0x0e71, 0x27f1, 0x207b, 0x2af8, 0x1c78, + 0x0d1d, 0x2267, 0x1d86, 0x31b0, 0x0302, 0x149f, 0x35cc, 0x2fcf, 0x3771, 0x3a81, 0x1b13, 0x2a7d, 0x33a5, 0x1e11, 0x1128, 0x0325, + 0x0172, 0x11c0, 0x2a70, 0x09c9, 0x2222, 0x2cd5, 0x36d2, 0x037d, 0x0a81, 0x11e0, 0x2fb9, 0x1fd5, 0x2580, 0x1963, 0x10ea, 0x2755, + 0x2df8, 0x2ff9, 0x1be2, 0x20eb, 0x0686, 0x0034, 0x26a7, 0x34e6, 0x24fa, 0x1810, 0x3424, 0x0308, 0x1dbc, 0x388b, 0x3469, 0x3f80, + 0x036d, 0x3aa6, 0x399a, 0x39f7, 0x28e2, 0x0b15, 0x2c2c, 0x3bc8, 0x3be3, 0x1517, 0x2444, 0x34ab, 0x04e7, 0x3c3c, 0x09e0, 0x37b6, + 0x003f, 0x1f80, 0x348c, 0x38f5, 0x28f2, 0x19b0, 0x15bf, 0x0856, 0x1904, 0x2f01, 0x1989, 0x1a53, 0x0fed, 0x3c59, 0x2b5c, 0x11d8, + 0x0fa3, 0x05a1, 0x1a0c, 0x36e5, 0x1f1d, 0x3ed5, 0x002d, 0x09b7, 0x0c6c, 0x2761, 0x2a85, 0x3317, 0x350d, 0x0f2b, 0x38c1, 0x1b07, + 0x0793, 0x3e1b, 0x087e, 0x15f6, 0x10c9, 0x044a, 0x071e, 0x0abe, 0x25df, 0x2491, 0x2e2c, 0x14a5, 0x073b, 0x018b, 0x367f, 0x267d, + 0x0356, 0x0440, 0x39df, 0x0afc, 0x1173, 0x0390, 0x014d, 0x0560, 0x178d, 0x0d07, 0x12f5, 0x3b73, 0x0a4d, 0x2017, 0x39a7, 0x24dc, + 0x269d, 0x0df2, 0x0c1e, 0x3076, 0x2932, 0x3354, 0x203f, 0x1a74, 0x051d, 0x1539, 0x186e, 0x24e5, 0x2daf, 0x1b6a, 0x3931, 0x21bf, + 0x3cbb, 0x0c92, 0x2858, 0x0fde, 0x3838, 0x3843, 0x38d5, 0x1073, 0x141d, 0x05ff, 0x03f8, 0x2746, 0x01e1, 0x1032, 0x080c, 0x24d0, + 0x0501, 0x1d2f, 0x04f7, 0x308c, 0x2e0e, 0x09be, 0x1f2f, 0x14ee, 0x3d61, 0x163d, 0x309b, 0x35d2, 0x0950, 0x023c, 0x175a, 0x256c, + 0x0d73, 0x3bf3, 0x23d7, 0x1233, 0x3da2, 0x3ee7, 0x1621, 0x3f56, 0x2aa8, 0x35e1, 0x371b, 0x1e08, 0x19a2, 0x2bf1, 0x1edb, 0x2780, + 0x0bd3, 0x2722, 0x3e01, 0x00fc, 0x1e33, 0x06ff, 0x222d, 0x24c8, 0x103b, 0x0caf, 0x1009, 0x2816, 0x36c4, 0x1a9f, 0x30f3, 0x139c, + 0x13da, 0x29f4, 0x2332, 0x202e, 0x1402, 0x2a05, 0x3dc6, 0x0782, 0x2995, 0x2b53, 0x18ab, 0x320d, 0x307e, 0x1101, 0x0717, 0x0d59, + 0x1db7, 0x33a0, 0x0736, 0x0fe8, 0x094b, 0x2daa, 0x0d60, 0x36bf, 0x188b, 0x0932, 0x1588, 0x2fd5, 0x0d65, 0x1a19, 0x23f5, 0x00d1, + 0x1ae3, 0x2adc, 0x3b42, 0x0126, 0x35fc, 0x2c96, 0x2f34, 0x1a5e, 0x154e, 0x1147, 0x3341, 0x15e3, 0x3296, 0x2a40, 0x2cb6, 0x2fa4, + 0x106c, 0x0376, 0x1719, 0x0ad0, 0x0cd5, 0x2a4c, 0x00e4, 0x345c, 0x32e6, 0x272f, 0x2a55, 0x0199, 0x35e6, 0x0670, 0x2f43, 0x1fe4, + 0x17a3, 0x27a1, 0x3c63, 0x04c7, 0x3af4, 0x2cf0, 0x2378, 0x1feb, 0x2073, 0x190c, 0x2d86, 0x2cc1, 0x066c, 0x2a3c, 0x12c5, 0x2a38, + 0x1bc0, 0x0641, 0x3545, 0x3ef8, 0x1558, 0x0c73, 0x0b3a, 0x3c2f, 0x259e, 0x23a7, 0x398e, 0x0cf2, 0x2aad, 0x12c9, 0x377d, 0x3d3d, + 0x3f67, 0x3667, 0x3a37, 0x0139, 0x2d53, 0x3d26, 0x3a1b, 0x25b6, 0x2bdf, 0x1748, 0x1fc3, 0x18f2, 0x3e65, 0x1910, 0x08f5, 0x0dc6, + 0x1a9b, 0x2bed, 0x1a15, 0x10fd, 0x1b66, 0x2013, 0x0238, 0x102e, 0x3c55, 0x3c38, 0x0187, 0x0f27, 0x1e0d, 0x2077, 0x3887, 0x195f, + 0x0730, 0x04f1, 0x0878, 0x1bdc, 0x265b, 0x1223, 0x191c, 0x3a56, 0x0f39, 0x15af, 0x33ad, 0x08ed, 0x09d8, 0x2cc5, 0x2545, 0x2d2a, + 0x2f86, 0x157d, 0x37df, 0x0e3d, 0x2821, 0x21e8, 0x13e1, 0x2739, 0x0dab, 0x0895, 0x2fed, 0x2193, 0x3720, 0x2d8a, 0x37d9, 0x353f, + 0x27b1, 0x244f, 0x2801, 0x0c34, 0x300f, 0x07e0, 0x10db, 0x2ea9, 0x1328, 0x3752, 0x20fa, 0x2f52, 0x1d3c, 0x2cf4, 0x3c4a, 0x28c8, + 0x357e, 0x075f, 0x27dd, 0x22ab, 0x252a, 0x3165, 0x2a99, 0x2654, 0x13fb, 0x1f16, 0x3139, 0x0f0f, 0x2bf6, 0x3af8, 0x35c3, 0x05d3, + 0x3b6b, 0x26da, 0x1293, 0x3805, 0x2687, 0x3b55, 0x1244, 0x2f4a, 0x3113, 0x301c, 0x1ac7, 0x1047, 0x0064, 0x1fef, 0x0ee3, 0x0bdb, + 0x2877, 0x3c8f, 0x2d90, 0x02cc, 0x2bca, 0x2768, 0x25ca, 0x0f47, 0x32c2, 0x23bc, 0x382c, 0x03d5, 0x19a7, 0x237c, 0x20d5, 0x0110, + 0x00a9, 0x16ca, 0x22fc, 0x35a6, 0x0db9, 0x0168, 0x2e7d, 0x1ea9, 0x08bc, 0x12e7, 0x10b8, 0x1c90, 0x29e3, 0x27a5, 0x0c0d, 0x2ecd, + 0x1cd6, 0x294b, 0x2f21, 0x1c5a, 0x36db, 0x3c04, 0x2c52, 0x01f9, 0x0529, 0x0924, 0x2694, 0x0bc0, 0x2785, 0x17a7, 0x05de, 0x0e46, + 0x1c6d, 0x1b95, 0x19f4, 0x08b4, 0x2aa0, 0x1682, 0x062a, 0x38cb, 0x3c1e, 0x34ff, 0x2d42, 0x27c6, 0x293a, 0x04cb, 0x1282, 0x2dd5, + 0x2408, 0x0cfc, 0x3726, 0x2d00, 0x2292, 0x045c, 0x29fb, 0x0992, 0x00f3, 0x0317, 0x24bc, 0x0e77, 0x1ee0, 0x3c67, 0x05bf, 0x0dff, + 0x11b9, 0x0c8b, 0x1b2c, 0x04b0, 0x3b39, 0x22da, 0x379d, 0x2c14, 0x25ac, 0x3f35, 0x02a7, 0x249c, 0x3037, 0x12cd, 0x279a, 0x26d3, + 0x2601, 0x0ba7, 0x3ff7, 0x2b88, 0x290e, 0x1675, 0x3b01, 0x3860, 0x144f, 0x35f2, 0x07bf, 0x17ee, 0x3bf8, 0x2ab1, 0x1831, 0x18e7, + 0x19c8, 0x303e, 0x3ce7, 0x33f9, 0x2474, 0x30c7, 0x365e, 0x0677, 0x0b5d, 0x2f09, 0x16c0, 0x39d3, 0x295e, 0x3d41, 0x3a8b, 0x3bb9, + 0x0d91, 0x1e1f, 0x2199, 0x2274, 0x0b49, 0x2a8c, 0x394e, 0x3df2, 0x3e6f, 0x3e2d, 0x1656, 0x27f7, 0x0d78, 0x3781, 0x2ad4, 0x0c83, + 0x3006, 0x1523, 0x2089, 0x2b37, 0x3fb9, 0x2f68, 0x31bf, 0x378c, 0x0593, 0x194e, 0x07a5, 0x065b, 0x0651, 0x23ab, 0x33b5, 0x10a7, + 0x31f5, 0x28a6, 0x02eb, 0x0e13, 0x006f, 0x0119, 0x3d7d, 0x3ebb, 0x1d78, 0x0aaa, 0x332b, 0x340e, 0x1238, 0x25a2, 0x18b4, 0x14d7, + 0x1863, 0x033b, 0x1ea0, 0x1ddc, 0x316c, 0x3609, 0x0966, 0x1369, 0x0552, 0x1af6, 0x1e19, 0x3394, 0x3c89, 0x0cf6, 0x063b, 0x1577, + 0x1d29, 0x339a, 0x2ff3, 0x3e15, 0x29b2, 0x2f79, 0x2339, 0x1ef7, 0x093d, 0x1976, 0x3a2f, 0x2081, 0x23dc, 0x3992, 0x3527, 0x20c0, + 0x2bba, 0x31d8, 0x169e, 0x2d60, 0x1e99, 0x3914, 0x0871, 0x19ed, 0x1a05, 0x232b, 0x0bf5, 0x124c, 0x2791, 0x0c77, 0x20ca, 0x2aef, + 0x092d, 0x0caa, 0x1638, 0x1534, 0x248c, 0x2efc, 0x180b, 0x3a7c, 0x2e51, 0x22cc, 0x3f20, 0x0a56, 0x3eec, 0x155c, 0x2e61, 0x2593, + 0x2a25, 0x12d4, 0x0eba, 0x22c7, 0x1971, 0x0aa5, 0x3e28, 0x35ed, 0x0312, 0x091f, 0x23b7, 0x1f11, 0x0890, 0x3c33, 0x23a2, 0x272a, + 0x16e2, 0x0558, 0x089b, 0x0fbc, 0x1f4d, 0x331e, 0x2ea1, 0x19e5, 0x1e52, 0x0ebf, 0x337d, 0x2afe, 0x3da7, 0x0b3e, 0x254f, 0x0750, + 0x1163, 0x2969, 0x0f88, 0x048f, 0x36af, 0x38eb, 0x2925, 0x1195, 0x19fc, 0x381e, 0x1ce9, 0x1784, 0x2257, 0x0645, 0x324d, 0x1f9a, + 0x30af, 0x3f9d, 0x2387, 0x0e80, 0x0d13, 0x1f8d, 0x1347, 0x3899, 0x0815, 0x12d9, 0x1a2c, 0x0d2d, 0x3f5b, 0x1bc4, 0x1c2e, 0x1608, + 0x2b48, 0x355b, 0x391b, 0x0ecd, 0x2531, 0x0ea6, 0x0775, 0x06f5, 0x38af, 0x1dff, 0x177b, 0x2fc3, 0x335c, 0x3efc, 0x32f4, 0x29c8, + 0x2668, 0x1afc, 0x0db1, 0x36a7, 0x1485, 0x3d9a, 0x2035, 0x3fda, 0x3875, 0x2a2a, 0x32b0, 0x1c7e, 0x1626, 0x3549, 0x29a0, 0x2c02, + 0x06a9, 0x0d80, 0x22e3, 0x2b26, 0x01c1, 0x1336, 0x1e62, 0x0a94, 0x2f17, 0x1ecf, 0x1497, 0x28b7, 0x166d, 0x2a44, 0x06ea, 0x159e, + 0x3737, 0x3aaf, 0x2703, 0x18c8, 0x13ad, 0x15a6, 0x1e6f, 0x2ca9, 0x214c, 0x0755, 0x0cde, 0x3fc6, 0x0cb4, 0x329a, 0x0e5d, 0x0330, + 0x0d38, 0x02ae, 0x1262, 0x1fa9, 0x0469, 0x0b73, 0x3430, 0x01a0, 0x0a37, 0x1991, 0x1b5c, 0x255b, 0x27bb, 0x2fa8, 0x3231, 0x2ef0, + 0x0696, 0x096c, 0x273f, 0x1fce, 0x2e3e, 0x3514, 0x1b53, 0x2d7d, 0x3a06, 0x2554, 0x0709, 0x3452, 0x1040, 0x2cba, 0x1f0a, 0x39cc, + 0x10c3, 0x0680, 0x0945, 0x2e08, 0x083c, 0x1206, 0x0a13, 0x14b7, 0x3d75, 0x0230, 0x192b, 0x34ba, 0x1c24, 0x114b, 0x15b7, 0x024a, + 0x11a4, 0x2dcc, 0x36ee, 0x3419, 0x326a, 0x2e38, 0x34c2, 0x3c11, 0x29ac, 0x0b43, 0x147f, 0x1f47, 0x281b, 0x1552, 0x228c, 0x2bc4, + 0x3b16, 0x3e49, 0x16a5, 0x2419, 0x22b2, 0x343d, 0x2200, 0x1ab0, 0x3179, 0x13b6, 0x1130, 0x26f5, 0x21ca, 0x15e7, 0x1d6e, 0x0769, + 0x1090, 0x136f, 0x13e7, 0x005b, 0x3270, 0x3db7, 0x1409, 0x0f02, 0x0e24, 0x3dac, 0x2c6a, 0x3e3b, 0x100e, 0x3345, 0x2d36, 0x17e4, + 0x3974, 0x0cc0, 0x306e, 0x220d, 0x152c, 0x22a3, 0x21af, 0x1f55, 0x2837, 0x0a75, 0x03bf, 0x3b5d, 0x0b8e, 0x2c9a, 0x2481, 0x020f, + 0x32d0, 0x0a6b, 0x008c, 0x1f5d, 0x3cc8, 0x305f, 0x17bc, 0x0f7b, 0x2de1, 0x2b03, 0x0fc6, 0x1c4c, 0x1aa4, 0x3600, 0x3ecc, 0x3fec, + 0x09ff, 0x24a3, 0x1c1a, 0x1705, 0x189e, 0x250a, 0x1cf4, 0x2a5c, 0x3ac0, 0x1b78, 0x129d, 0x3a0d, 0x13f0, 0x1a62, 0x0c4d, 0x3e09, + 0x3962, 0x3172, 0x21ee, 0x1594, 0x3c17, 0x0f32, 0x38a8, 0x054b, 0x143d, 0x3382, 0x298e, 0x0c65, 0x36c9, 0x2f38, 0x3533, 0x3655, + 0x30a7, 0x1cce, 0x2775, 0x3cfc, 0x2670, 0x1617, 0x0bcb, 0x1de5, 0x1b9d, 0x1a47, 0x397e, 0x3c7b, 0x1383, 0x2ae0, 0x1738, 0x042c, + 0x3d04, 0x2630, 0x25f1, 0x150c, 0x0386, 0x07b0, 0x1dcc, 0x2467, 0x234c, 0x0ec4, 0x2025, 0x18d9, 0x13a1, 0x1ae7, 0x3904, 0x37e8, + 0x16f2, 0x11f3, 0x2d67, 0x3121, 0x27e4, 0x1bb1, 0x097f, 0x0363, 0x3969, 0x02d6, 0x39b2, 0x0be7, 0x2047, 0x012a, 0x3f43, 0x11ad, + 0x0a20, 0x360f, 0x2827, 0x3184, 0x34c8, 0x2c43, 0x2a0c, 0x3eae, 0x3cb2, 0x1e57, 0x1d5e, 0x2a1c, 0x30f8, 0x3b46, 0x328a, 0x3dd0, + 0x10a4, 0x3789, 0x14d4, 0x3eb8, 0x1574, 0x1366, 0x20bd, 0x1ef4, 0x26d0, 0x2c11, 0x18e4, 0x385d, 0x3bb6, 0x0674, 0x0c80, 0x3def, + 0x1f97, 0x1192, 0x1605, 0x3896, 0x29c5, 0x06f2, 0x2bff, 0x3fd7, 0x2aec, 0x19ea, 0x2590, 0x3a79, 0x2727, 0x35ea, 0x074d, 0x19e2, + 0x0dc3, 0x25b3, 0x195c, 0x102b, 0x2d27, 0x3a53, 0x353c, 0x2736, 0x2fa1, 0x1a5b, 0x1fe1, 0x3459, 0x2a35, 0x1fe8, 0x3d3a, 0x3c2c, + 0x2eca, 0x1ea6, 0x0e43, 0x01f6, 0x2dd2, 0x38c8, 0x0dfc, 0x098f, 0x28c5, 0x2ea6, 0x05d0, 0x2651, 0x0bd8, 0x2f47, 0x010d, 0x0f44, + 0x0989, 0x3ea5, 0x197e, 0x0419, 0x2d77, 0x0efc, 0x0545, 0x3ea8, 0x3dec, 0x1ef1, 0x19df, 0x3fd4, 0x3c29, 0x2733, 0x0f41, 0x098c, + 0x34e0, 0x0ab8, 0x14e8, 0x36b9, 0x29d4, 0x20de, 0x1933, 0x041c, 0x017f, 0x3323, 0x1477, 0x146f, 0x0101, 0x32ea, 0x3216, 0x1981, + 0x0247, 0x14b4, 0x2bc1, 0x3c0e, 0x0766, 0x1aad, 0x17e1, 0x0eff, 0x159b, 0x0a91, 0x032d, 0x2ca6, 0x2eed, 0x019d, 0x39c9, 0x2d7a, + 0x0429, 0x1de2, 0x37e5, 0x2464, 0x11aa, 0x0360, 0x3dcd, 0x3eab, 0x020c, 0x1f52, 0x3fe9, 0x0f78, 0x3e06, 0x2a59, 0x3652, 0x0548, + 0x3378, 0x3f1b, 0x32ab, 0x1a27, 0x1651, 0x07ba, 0x3a2a, 0x3326, 0x3827, 0x3134, 0x24b7, 0x268f, 0x3989, 0x2a50, 0x2fe8, 0x0182, + 0x0532, 0x1d54, 0x03ac, 0x21b7, 0x05cb, 0x258b, 0x3fe4, 0x1472, 0x2989, 0x0fc1, 0x1d59, 0x2020, 0x0704, 0x0cd9, 0x2c65, 0x147a, + 0x1d67, 0x3f3c, 0x39c2, 0x2160, 0x253e, 0x127b, 0x0634, 0x32ed, 0x2519, 0x1d01, 0x38ba, 0x0710, 0x37ce, 0x3460, 0x2acb, 0x0104, + 0x3096, 0x1869, 0x1583, 0x1004, 0x341f, 0x1b0e, 0x2e27, 0x1984, 0x3ba5, 0x08a0, 0x0537, 0x0f64, 0x1e38, 0x00e8, 0x0fb0, 0x3219, + 0x37b3, 0x3bc5, 0x11d5, 0x0853, 0x1b04, 0x09b4, 0x267a, 0x0abb, 0x1c75, 0x08ca, 0x0322, 0x2fcc, 0x2752, 0x037a, 0x3f7d, 0x34e3, + 0x277d, 0x3f53, 0x1399, 0x24c5, 0x0d56, 0x077f, 0x00ce, 0x36bc, 0x24d9, 0x055d, 0x21bc, 0x1a71, 0x24cd, 0x1070, 0x2569, 0x14eb, + 0x026d, 0x06c1, 0x31df, 0x2355, 0x3585, 0x099c, 0x01ec, 0x20e1, 0x21f5, 0x3d58, 0x1e49, 0x3b9c, 0x1a7c, 0x0ad4, 0x2167, 0x29d7, + 0x110f, 0x0341, 0x2f8c, 0x2862, 0x36f4, 0x0904, 0x0789, 0x041f, 0x3691, 0x16e7, 0x03b1, 0x08d3, 0x2232, 0x171d, 0x1157, 0x1936, + 0x057e, 0x3cef, 0x02b0, 0x20a6, 0x183b, 0x060f, 0x0d3a, 0x301f, 0x2919, 0x31eb, 0x1fab, 0x2b10, 0x007e, 0x3f00, 0x1264, 0x3116, + 0x0bb3, 0x09e9, 0x0b75, 0x2132, 0x310a, 0x3ab7, 0x046b, 0x104a, 0x2b7e, 0x10ac, 0x01a2, 0x07eb, 0x11e5, 0x3360, 0x3432, 0x1aca, + 0x2d13, 0x3955, 0x1993, 0x1d15, 0x30db, 0x01d6, 0x0a39, 0x1ff2, 0x2429, 0x28ea, 0x255d, 0x133d, 0x3262, 0x29cc, 0x1b5e, 0x0067, + 0x3106, 0x1837, 0x2faa, 0x30d7, 0x2fae, 0x0046, 0x27bd, 0x0bde, 0x1e7e, 0x33ba, 0x2ef2, 0x25e5, 0x0a86, 0x32f8, 0x3233, 0x0ee6, + 0x304e, 0x0b66, 0x096e, 0x2055, 0x004a, 0x00b5, 0x0698, 0x26dd, 0x3312, 0x34a6, 0x1fd0, 0x0e6c, 0x3208, 0x1e03, 0x2741, 0x3b6e, + 0x12bc, 0x3228, 0x3516, 0x33d9, 0x2fb2, 0x03f1, 0x2e40, 0x3808, 0x16b9, 0x23b0, 0x2d7f, 0x1ac0, 0x1fda, 0x38b3, 0x1b55, 0x1296, + 0x26f0, 0x34b5, 0x2556, 0x28b2, 0x0be2, 0x3c76, 0x3a08, 0x3b58, 0x2ca1, 0x3fcf, 0x3454, 0x3858, 0x3b97, 0x2fc7, 0x070b, 0x268a, + 0x08e8, 0x18ed, 0x2cbc, 0x15de, 0x27c1, 0x1c8b, 0x1042, 0x2f4d, 0x338f, 0x0656, 0x39ce, 0x2497, 0x2fbe, 0x177f, 0x1f0c, 0x1247, + 0x3bd9, 0x3de2, 0x0d82, 0x04da, 0x33be, 0x3fa9, 0x06ab, 0x23bf, 0x19bc, 0x3f8d, 0x2b28, 0x03dd, 0x0299, 0x0eaa, 0x22e5, 0x32c5, + 0x3853, 0x0e67, 0x1338, 0x2b0b, 0x1e82, 0x1318, 0x01c3, 0x03d8, 0x1cba, 0x0660, 0x0a96, 0x3151, 0x1968, 0x2535, 0x1e64, 0x382f, + 0x26b9, 0x3df9, 0x1ed1, 0x3f73, 0x25e9, 0x1391, 0x2f19, 0x237f, 0x01ab, 0x0220, 0x28b9, 0x01c8, 0x334e, 0x06f9, 0x1499, 0x19aa, + 0x315f, 0x3bfe, 0x2a46, 0x200d, 0x2ef6, 0x1f87, 0x166f, 0x0113, 0x3059, 0x07aa, 0x15a0, 0x2e32, 0x2585, 0x0779, 0x06ec, 0x20d8, + 0x1312, 0x3d4b, 0x3ab1, 0x03eb, 0x32fc, 0x0832, 0x3739, 0x3c92, 0x0e07, 0x3190, 0x18ca, 0x131d, 0x2e6f, 0x355f, 0x2705, 0x287a, + 0x1aef, 0x1df8, 0x15a8, 0x34f8, 0x0a8a, 0x3d51, 0x13af, 0x02cf, 0x3cde, 0x1953, 0x2cab, 0x2a67, 0x275a, 0x2b4c, 0x1e71, 0x2d93, + 0x0a63, 0x1d4c, 0x0757, 0x0ca2, 0x0eea, 0x0dea, 0x214e, 0x276b, 0x0b95, 0x1e8e, 0x3fc8, 0x1e87, 0x1795, 0x0ed1, 0x0ce0, 0x2bcd, + 0x1691, 0x2ab7, 0x329c, 0x0b26, 0x3237, 0x1d9a, 0x0cb6, 0x0f4a, 0x1b21, 0x0598, 0x0332, 0x14ab, 0x10ef, 0x391f, 0x0e5f, 0x25cd, + 0x1c3c, 0x3401, 0x3e4b, 0x061b, 0x3959, 0x286e, 0x3b18, 0x3755, 0x3335, 0x33ef, 0x241b, 0x3156, 0x06da, 0x354d, 0x16a7, 0x132b, + 0x040c, 0x117f, 0x343f, 0x1ad4, 0x2d17, 0x373f, 0x22b4, 0x2f55, 0x1859, 0x3791, 0x1ab2, 0x0e2e, 0x11c5, 0x162a, 0x2202, 0x20fd, + 0x04a0, 0x0b50, 0x13b8, 0x16b1, 0x1d19, 0x2439, 0x317b, 0x2cf7, 0x0e96, 0x0b1d, 0x26f7, 0x0a9b, 0x17fb, 0x2c06, 0x1132, 0x1d3f, + 0x2ebd, 0x07c5, 0x15e9, 0x2248, 0x1997, 0x3493, 0x21cc, 0x28cb, 0x18fc, 0x31c4, 0x076b, 0x0741, 0x0177, 0x29a4, 0x1d70, 0x3c4d, + 0x1b4a, 0x0b31, 0x1371, 0x3643, 0x01da, 0x2579, 0x1092, 0x2452, 0x0889, 0x2957, 0x005d, 0x0665, 0x37c7, 0x2a2e, 0x13e9, 0x27b4, + 0x126e, 0x3cd3, 0x3db9, 0x297a, 0x30df, 0x3c98, 0x3272, 0x0c37, 0x13c0, 0x2f6d, 0x0f04, 0x3b8d, 0x09ce, 0x3879, 0x140b, 0x2804, + 0x2107, 0x3240, 0x3dae, 0x21df, 0x1ff6, 0x1f66, 0x0e26, 0x07e3, 0x0216, 0x0b9c, 0x3e3d, 0x1cbf, 0x1bf4, 0x1c82, 0x2c6c, 0x3012, + 0x00c1, 0x17f4, 0x3347, 0x325b, 0x0a3d, 0x3632, 0x1010, 0x2eac, 0x3a71, 0x3fbe, 0x17e6, 0x0191, 0x2a75, 0x32b4, 0x2d38, 0x10de, + 0x02fe, 0x2647, 0x0682, 0x221e, 0x28ee, 0x28de, 0x10c5, 0x1f19, 0x292e, 0x116f, 0x2e0a, 0x3834, 0x1e2f, 0x3d9e, 0x0947, 0x13fe, + 0x0202, 0x25d5, 0x1208, 0x2de9, 0x242d, 0x3302, 0x083e, 0x0f12, 0x0dd4, 0x2b3c, 0x14b9, 0x39e8, 0x2cda, 0x1489, 0x0a15, 0x313c, + 0x2c4c, 0x2a93, 0x0232, 0x00de, 0x1341, 0x1805, 0x3d77, 0x3afb, 0x1dc6, 0x17b6, 0x34bc, 0x1e69, 0x00c8, 0x3fde, 0x192d, 0x2bf9, + 0x30eb, 0x1455, 0x114d, 0x23eb, 0x2561, 0x38fc, 0x1c26, 0x05d6, 0x358e, 0x208e, 0x024c, 0x3685, 0x2227, 0x2039, 0x15b9, 0x35c6, + 0x29c1, 0x1570, 0x2dce, 0x2d23, 0x29d0, 0x2d73, 0x11a6, 0x0762, 0x05c7, 0x164d, 0x341b, 0x253a, 0x0d52, 0x1b00, 0x36f0, 0x3581, + 0x13a9, 0x01bd, 0x2e3a, 0x0465, 0x3266, 0x0838, 0x326c, 0x22ae, 0x3cc4, 0x1528, 0x3c13, 0x189a, 0x0382, 0x266c, 0x34c4, 0x27e0, + 0x290a, 0x3b35, 0x0b45, 0x2470, 0x006b, 0x3fb5, 0x29ae, 0x3168, 0x2488, 0x1e95, 0x1f49, 0x196d, 0x0d0f, 0x36ab, 0x1481, 0x252d, + 0x0cd1, 0x35f8, 0x1554, 0x3af0, 0x1b62, 0x2d4f, 0x281d, 0x2657, 0x2526, 0x300b, 0x2bc6, 0x2683, 0x36d7, 0x0db5, 0x228e, 0x2a9c, + 0x2edb, 0x19d0, 0x24a5, 0x16d5, 0x09ed, 0x14fa, 0x0a01, 0x3502, 0x2280, 0x2e97, 0x1707, 0x04df, 0x3e5d, 0x0649, 0x1c1c, 0x3c21, + 0x3200, 0x37bf, 0x250c, 0x2844, 0x0bb7, 0x18d0, 0x18a0, 0x27c9, 0x3d90, 0x14dc, 0x2a5e, 0x1f6e, 0x1815, 0x225b, 0x1cf6, 0x2d45, + 0x2887, 0x21a0, 0x1b7a, 0x0482, 0x2136, 0x2360, 0x3ac2, 0x04ce, 0x184b, 0x2c34, 0x3a0f, 0x0d87, 0x2eb3, 0x1f9e, 0x129f, 0x293d, + 0x0510, 0x3b07, 0x1a64, 0x3621, 0x0b79, 0x28f9, 0x13f2, 0x2dd8, 0x1cb1, 0x18b9, 0x3e0b, 0x0799, 0x24ff, 0x3251, 0x0c4f, 0x1285, + 0x0a32, 0x2f12, 0x3174, 0x3d70, 0x3abb, 0x2832, 0x3964, 0x1b98, 0x2f9c, 0x26cb, 0x1596, 0x3de7, 0x2514, 0x3822, 0x21f0, 0x1c70, + 0x206e, 0x1549, 0x0f34, 0x2bda, 0x310e, 0x1323, 0x3c19, 0x08b7, 0x0b58, 0x25a7, 0x054d, 0x058e, 0x030d, 0x1a00, 0x38aa, 0x19f7, + 0x3acd, 0x1822, 0x3384, 0x30ba, 0x104e, 0x3e8d, 0x143f, 0x1685, 0x0a7c, 0x0ce7, 0x0c67, 0x3bde, 0x1418, 0x1788, 0x2990, 0x2aa3, + 0x3672, 0x3866, 0x2f3a, 0x0e54, 0x046f, 0x1bfd, 0x36cb, 0x38ce, 0x2371, 0x123d, 0x3657, 0x3e21, 0x3429, 0x1ced, 0x3535, 0x062d, + 0x0802, 0x2ac1, 0x0cc2, 0x3713, 0x10b0, 0x1ce1, 0x3976, 0x031a, 0x1431, 0x17c6, 0x220f, 0x23c4, 0x31aa, 0x38ef, 0x3070, 0x00f6, + 0x0aca, 0x10f7, 0x22a5, 0x1c54, 0x2b82, 0x0e0d, 0x152e, 0x0e7a, 0x18c2, 0x3413, 0x1f57, 0x1506, 0x3890, 0x36b3, 0x21b1, 0x24bf, + 0x1846, 0x227b, 0x0a77, 0x2f97, 0x07ef, 0x142c, 0x2839, 0x3c6a, 0x07f4, 0x039b, 0x3b5f, 0x06b0, 0x1017, 0x1199, 0x03c1, 0x1ee3, + 0x2424, 0x2914, 0x2c9c, 0x330d, 0x01a6, 0x19b7, 0x0b90, 0x0e02, 0x0e91, 0x3330, 0x0211, 0x0884, 0x1dc1, 0x2929, 0x2483, 0x05c2, + 0x374a, 0x2323, 0x0a6d, 0x312c, 0x3364, 0x1c10, 0x32d2, 0x0cff, 0x3c6f, 0x0de3, 0x1f5f, 0x3fae, 0x3e86, 0x296d, 0x008e, 0x240b, + 0x37f0, 0x263c, 0x3061, 0x33c9, 0x11e9, 0x3196, 0x3cca, 0x2d03, 0x289d, 0x0aaf, 0x0f7d, 0x1f77, 0x3f85, 0x1167, 0x17be, 0x3729, + 0x212c, 0x33d3, 0x2b05, 0x34f2, 0x1ace, 0x2974, 0x2de3, 0x045f, 0x283e, 0x2bd4, 0x1c4e, 0x33c3, 0x12fd, 0x0493, 0x0fc8, 0x2295, + 0x121c, 0x167b, 0x3602, 0x0e9f, 0x3436, 0x1baa, 0x1aa6, 0x0995, 0x0c02, 0x1d7d, 0x3fee, 0x15fc, 0x346e, 0x0f8c, 0x3ece, 0x29fe, + 0x1b42, 0x3046, 0x11f5, 0x0a2a, 0x3cf3, 0x359d, 0x16f4, 0x12ea, 0x03a0, 0x38e1, 0x3123, 0x03e2, 0x2716, 0x1bc8, 0x2d69, 0x08bf, + 0x2391, 0x2177, 0x1bb3, 0x1303, 0x0582, 0x270b, 0x27e6, 0x1c93, 0x0867, 0x3ec0, 0x0365, 0x1ffe, 0x2ffe, 0x3f5f, 0x0981, 0x10bb, + 0x35b0, 0x0d98, 0x02d8, 0x1f3a, 0x20aa, 0x025a, 0x396b, 0x27a8, 0x07f9, 0x3bd0, 0x0be9, 0x2b2d, 0x3639, 0x160c, 0x39b4, 0x29e6, + 0x0ae2, 0x3ffd, 0x012c, 0x06cb, 0x02b4, 0x15c6, 0x2049, 0x2ed0, 0x347b, 0x3d82, 0x11af, 0x10cf, 0x2dfd, 0x1c32, 0x3f45, 0x0c10, + 0x11fd, 0x3d1d, 0x3611, 0x172b, 0x0613, 0x209e, 0x0a22, 0x16cd, 0x06b5, 0x3d0f, 0x3186, 0x3f92, 0x284c, 0x12dd, 0x2829, 0x00ac, + 0x26b2, 0x2d0c, 0x2c45, 0x0499, 0x183f, 0x2880, 0x34ca, 0x35a9, 0x04a8, 0x011e, 0x3eb0, 0x2b1e, 0x20f0, 0x0819, 0x2a0e, 0x22ff, + 0x187c, 0x1da3, 0x1e59, 0x2f2b, 0x3023, 0x0095, 0x3cb4, 0x016b, 0x3b64, 0x179c, 0x2a1e, 0x19c1, 0x09f8, 0x0d31, 0x1d60, 0x0dbc, + 0x1119, 0x2b8e, 0x3b48, 0x2b73, 0x0d3e, 0x056a, 0x30fa, 0x1eac, 0x0f1c, 0x0074, 0x3dd2, 0x0450, 0x1be7, 0x1a30, 0x328c, 0x2e80, + 0x1a95, 0x1066, 0x1cd0, 0x3578, 0x31ef, 0x25fb, 0x30a9, 0x0927, 0x119e, 0x3731, 0x3cfe, 0x32ca, 0x34da, 0x1f91, 0x2777, 0x052c, + 0x2c5b, 0x3927, 0x1619, 0x0fce, 0x291d, 0x2e75, 0x2672, 0x0bc3, 0x1ec0, 0x0e18, 0x1de7, 0x0b05, 0x0039, 0x0d17, 0x0bcd, 0x2697, + 0x34d1, 0x1e26, 0x1a49, 0x1465, 0x2b14, 0x107e, 0x1b9f, 0x17aa, 0x101c, 0x3ae2, 0x3c7d, 0x22ea, 0x0a44, 0x389d, 0x3980, 0x2788, + 0x2e18, 0x2607, 0x2ae2, 0x3767, 0x1faf, 0x085d, 0x1385, 0x0e49, 0x09a5, 0x02f0, 0x042e, 0x0724, 0x068b, 0x134b, 0x173a, 0x05e1, + 0x3b2a, 0x3a99, 0x2632, 0x14c7, 0x3f04, 0x2626, 0x3d06, 0x294e, 0x1ee8, 0x1945, 0x150e, 0x0eaf, 0x28d6, 0x3fa1, 0x25f3, 0x1cd9, + 0x390c, 0x07d8, 0x07b2, 0x229b, 0x0082, 0x3565, 0x0388, 0x1c5d, 0x0c9b, 0x28ab, 0x2469, 0x21d8, 0x34eb, 0x30b3, 0x1dce, 0x2f24, + 0x08ad, 0x1bd5, 0x0ec6, 0x1dd5, 0x311a, 0x2412, 0x234e, 0x3c07, 0x03c6, 0x0ed8, 0x18db, 0x029e, 0x3b7b, 0x0e84, 0x2027, 0x36de, + 0x12b6, 0x0bad, 0x1ae9, 0x384d, 0x1268, 0x0406, 0x13a3, 0x01fc, 0x2068, 0x31fa, 0x37ea, 0x0ac4, 0x26ac, 0x238b, 0x3906, 0x2c55, + 0x0138, 0x3666, 0x25b5, 0x3d25, 0x18f1, 0x1747, 0x0dc5, 0x190f, 0x10fc, 0x2bec, 0x102d, 0x2012, 0x0f26, 0x3c37, 0x195e, 0x2076, + 0x1bdb, 0x04f0, 0x3a55, 0x1222, 0x08ec, 0x15ae, 0x2d29, 0x2cc4, 0x0e3c, 0x157c, 0x2738, 0x21e7, 0x2192, 0x0894, 0x353e, 0x2d89, + 0x0125, 0x2adb, 0x1a5d, 0x2c95, 0x15e2, 0x1146, 0x2fa3, 0x2a3f, 0x0acf, 0x0375, 0x345b, 0x2a4b, 0x0198, 0x272e, 0x1fe3, 0x066f, + 0x04c6, 0x27a0, 0x1fea, 0x2cef, 0x2cc0, 0x190b, 0x2a37, 0x2a3b, 0x3ef7, 0x0640, 0x3c2e, 0x0c72, 0x0cf1, 0x23a6, 0x3d3c, 0x12c8, + 0x35a5, 0x16c9, 0x1ea8, 0x0167, 0x1c8f, 0x12e6, 0x2ecc, 0x27a4, 0x1c59, 0x294a, 0x01f8, 0x3c03, 0x0bbf, 0x0923, 0x0e45, 0x17a6, + 0x08b3, 0x1b94, 0x38ca, 0x1681, 0x27c5, 0x34fe, 0x2dd4, 0x04ca, 0x2cff, 0x0cfb, 0x0991, 0x045b, 0x0e76, 0x0316, 0x0dfe, 0x3c66, + 0x0c33, 0x244e, 0x2ea8, 0x07df, 0x2f51, 0x3751, 0x28c7, 0x2cf3, 0x22aa, 0x075e, 0x2653, 0x3164, 0x0f0e, 0x1f15, 0x05d2, 0x3af7, + 0x3804, 0x26d9, 0x2f49, 0x3b54, 0x1046, 0x301b, 0x0bda, 0x1fee, 0x02cb, 0x3c8e, 0x0f46, 0x2767, 0x03d4, 0x23bb, 0x010f, 0x237b, + 0x2b36, 0x1522, 0x378b, 0x2f67, 0x065a, 0x194d, 0x10a6, 0x23aa, 0x0e12, 0x28a5, 0x3eba, 0x0118, 0x340d, 0x0aa9, 0x14d6, 0x25a1, + 0x1ddb, 0x033a, 0x1368, 0x3608, 0x3393, 0x1af5, 0x1576, 0x0cf5, 0x3e14, 0x3399, 0x1ef6, 0x2f78, 0x2080, 0x1975, 0x20bf, 0x3991, + 0x04af, 0x0c8a, 0x2c13, 0x22d9, 0x249b, 0x3f34, 0x26d2, 0x12cc, 0x2b87, 0x0ba6, 0x385f, 0x1674, 0x17ed, 0x35f1, 0x18e6, 0x2ab0, + 0x33f8, 0x303d, 0x0676, 0x30c6, 0x39d2, 0x2f08, 0x3bb8, 0x3d40, 0x2273, 0x1e1e, 0x3df1, 0x2a8b, 0x27f6, 0x3e2c, 0x0c82, 0x3780, + 0x048e, 0x2968, 0x1194, 0x38ea, 0x1783, 0x381d, 0x1f99, 0x0644, 0x0e7f, 0x3f9c, 0x3898, 0x1f8c, 0x0d2c, 0x12d8, 0x1607, 0x1bc3, + 0x0ecc, 0x355a, 0x06f4, 0x0ea5, 0x2fc2, 0x1dfe, 0x29c7, 0x3efb, 0x36a6, 0x1afb, 0x3fd9, 0x3d99, 0x1c7d, 0x2a29, 0x2c01, 0x3548, + 0x2d5f, 0x31d7, 0x19ec, 0x3913, 0x124b, 0x232a, 0x2aee, 0x0c76, 0x1533, 0x0ca9, 0x3a7b, 0x2efb, 0x0a55, 0x22cb, 0x2592, 0x155b, + 0x22c6, 0x12d3, 0x35ec, 0x0aa4, 0x1f10, 0x091e, 0x2729, 0x3c32, 0x0fbb, 0x0557, 0x19e4, 0x331d, 0x2afd, 0x0ebe, 0x074f, 0x0b3d, + 0x2e07, 0x067f, 0x14b6, 0x1205, 0x34b9, 0x022f, 0x0249, 0x114a, 0x3418, 0x2dcb, 0x3c10, 0x2e37, 0x1f46, 0x0b42, 0x2bc3, 0x1551, + 0x2418, 0x3e48, 0x1aaf, 0x343c, 0x26f4, 0x13b5, 0x0768, 0x15e6, 0x005a, 0x136e, 0x0f01, 0x3db6, 0x3e3a, 0x3dab, 0x17e3, 0x3344, + 0x2b25, 0x0d7f, 0x0a93, 0x1335, 0x28b6, 0x1ece, 0x159d, 0x2a43, 0x18c7, 0x3aae, 0x2ca8, 0x15a5, 0x3fc5, 0x0754, 0x032f, 0x3299, + 0x1fa8, 0x02ad, 0x019f, 0x0b72, 0x255a, 0x1990, 0x2eef, 0x2fa7, 0x1fcd, 0x096b, 0x2d7c, 0x3513, 0x3451, 0x2553, 0x39cb, 0x2cb9, + 0x3cfb, 0x1ccd, 0x1de4, 0x1616, 0x3c7a, 0x1a46, 0x042b, 0x2adf, 0x150b, 0x262f, 0x2466, 0x07af, 0x18d8, 0x0ec3, 0x37e7, 0x1ae6, + 0x3120, 0x11f2, 0x0362, 0x1bb0, 0x0be6, 0x02d5, 0x11ac, 0x0129, 0x3183, 0x360e, 0x3ead, 0x2c42, 0x2a1b, 0x1e56, 0x3dcf, 0x3b45, + 0x220c, 0x0cbf, 0x1f54, 0x22a2, 0x3b5c, 0x0a74, 0x020e, 0x2c99, 0x1f5c, 0x0a6a, 0x0f7a, 0x305e, 0x1c4b, 0x2b02, 0x3feb, 0x35ff, + 0x1704, 0x24a2, 0x2a5b, 0x2509, 0x3a0c, 0x1b77, 0x3e08, 0x1a61, 0x1593, 0x3171, 0x054a, 0x0f31, 0x0c64, 0x3381, 0x3654, 0x2f37, + 0x0418, 0x3ea4, 0x3ea7, 0x0efb, 0x3fd3, 0x1ef0, 0x098b, 0x2732, 0x36b8, 0x0ab7, 0x041b, 0x20dd, 0x146e, 0x3322, 0x1980, 0x32e9, + 0x3c0d, 0x14b3, 0x0efe, 0x1aac, 0x2ca5, 0x0a90, 0x2d79, 0x019c, 0x2463, 0x1de1, 0x3eaa, 0x035f, 0x0f77, 0x1f51, 0x0547, 0x2a58, + 0x3eb7, 0x3788, 0x1ef3, 0x1365, 0x385c, 0x2c10, 0x3dee, 0x0673, 0x3895, 0x1191, 0x3fd6, 0x06f1, 0x3a78, 0x19e9, 0x19e1, 0x35e9, + 0x102a, 0x25b2, 0x2735, 0x3a52, 0x3458, 0x1a5a, 0x3c2b, 0x1fe7, 0x01f5, 0x1ea5, 0x098e, 0x38c7, 0x2650, 0x2ea5, 0x0f43, 0x2f46, + 0x0852, 0x3bc4, 0x0aba, 0x09b3, 0x2fcb, 0x08c9, 0x34e2, 0x0379, 0x24c4, 0x3f52, 0x36bb, 0x077e, 0x1a70, 0x055c, 0x14ea, 0x106f, + 0x2354, 0x06c0, 0x20e0, 0x099b, 0x3b9b, 0x3d57, 0x29d6, 0x0ad3, 0x2861, 0x0340, 0x041e, 0x0903, 0x08d2, 0x16e6, 0x1935, 0x171c, + 0x1a26, 0x3f1a, 0x3325, 0x07b9, 0x268e, 0x3133, 0x0181, 0x2a4f, 0x21b6, 0x1d53, 0x1471, 0x258a, 0x201f, 0x0fc0, 0x1479, 0x0cd8, + 0x215f, 0x3f3b, 0x32ec, 0x127a, 0x070f, 0x1d00, 0x0103, 0x345f, 0x1003, 0x1868, 0x1983, 0x1b0d, 0x0f63, 0x089f, 0x3218, 0x00e7, + 0x0c48, 0x247c, 0x3f3e, 0x1733, 0x322c, 0x06e5, 0x1d69, 0x15b2, 0x2ac6, 0x2fe3, 0x2162, 0x3f78, 0x3d35, 0x0c7b, 0x39c4, 0x0f3c, + 0x0ede, 0x3c45, 0x127d, 0x0c08, 0x12c0, 0x2cb1, 0x2540, 0x08f0, 0x239d, 0x20c5, 0x32ef, 0x3248, 0x3a86, 0x2795, 0x0636, 0x33b0, + 0x0820, 0x165d, 0x1d03, 0x12aa, 0x33dd, 0x17d4, 0x251b, 0x2cc8, 0x0807, 0x39a2, 0x0712, 0x1ed6, 0x10e5, 0x2af3, 0x38bc, 0x09db, + 0x05ec, 0x37a3, 0x3462, 0x1753, 0x351a, 0x0ff4, 0x37d0, 0x2d2d, 0x1f03, 0x352c, 0x0106, 0x0fa9, 0x3776, 0x20ce, 0x2acd, 0x2548, + 0x12f2, 0x39dc, 0x186b, 0x0c1b, 0x03f5, 0x2855, 0x3098, 0x04f4, 0x3718, 0x23d4, 0x1006, 0x3dfe, 0x18a8, 0x232f, 0x1585, 0x0733, + 0x03cc, 0x0c5c, 0x1b10, 0x1d83, 0x2fb6, 0x2a6d, 0x3421, 0x1bdf, 0x2441, 0x3997, 0x1986, 0x3489, 0x2a82, 0x1a09, 0x2e29, 0x087b, + 0x2c84, 0x13cf, 0x08a2, 0x356c, 0x380c, 0x336b, 0x3ba7, 0x1226, 0x0cc7, 0x2155, 0x0f66, 0x26be, 0x2dba, 0x1250, 0x0539, 0x265e, + 0x0022, 0x2c1a, 0x00ea, 0x3ca9, 0x2e44, 0x2c75, 0x1e3a, 0x3a59, 0x3a48, 0x23e1, 0x321b, 0x05a7, 0x1b18, 0x0bf9, 0x0fb2, 0x191f, + 0x0bf2, 0x169b, 0x3f1d, 0x1635, 0x23b4, 0x0eb7, 0x337a, 0x0898, 0x1ce6, 0x0f85, 0x1a29, 0x2384, 0x1778, 0x3918, 0x32ad, 0x0dae, + 0x02a4, 0x1b29, 0x07bc, 0x3ff4, 0x16bd, 0x3ce4, 0x1653, 0x2196, 0x07a2, 0x2086, 0x3328, 0x02e8, 0x1e16, 0x1e9d, 0x3a2c, 0x2ff0, + 0x20f7, 0x27fe, 0x3136, 0x27da, 0x1ac4, 0x1290, 0x3829, 0x2d8d, 0x10b5, 0x22f9, 0x2691, 0x2f1e, 0x2d3f, 0x19f1, 0x24b9, 0x3723, + 0x333e, 0x3b3f, 0x2a52, 0x1716, 0x2d83, 0x3c60, 0x398b, 0x3542, 0x1fc0, 0x3a34, 0x0184, 0x1a12, 0x33aa, 0x0875, 0x2fea, 0x37dc, + 0x24b4, 0x32a8, 0x1d56, 0x03a9, 0x38b7, 0x39bf, 0x0534, 0x1580, 0x031f, 0x11d2, 0x21b9, 0x1396, 0x1e46, 0x31dc, 0x03ae, 0x2f89, + 0x18e1, 0x14d1, 0x258d, 0x1602, 0x1fde, 0x1959, 0x05cd, 0x0e40, 0x19dc, 0x197b, 0x1474, 0x14e5, 0x032a, 0x2bbe, 0x3fe6, 0x37e2, + 0x03bc, 0x306b, 0x0fc3, 0x0089, 0x129a, 0x1c17, 0x298b, 0x21eb, 0x397b, 0x2772, 0x2022, 0x25ee, 0x39af, 0x2d64, 0x1d5b, 0x2824, + 0x1494, 0x22e0, 0x0cdb, 0x2700, 0x1b59, 0x125f, 0x0706, 0x273c, 0x1928, 0x0942, 0x147c, 0x36eb, 0x112d, 0x16a2, 0x2c67, 0x13e4, + 0x2240, 0x30cf, 0x06c3, 0x3619, 0x0b6a, 0x2ce7, 0x026f, 0x174b, 0x17cb, 0x113d, 0x2357, 0x01cd, 0x1b89, 0x1560, 0x31e1, 0x2be2, + 0x0e8a, 0x1caa, 0x099e, 0x3474, 0x3052, 0x1e77, 0x3587, 0x18f5, 0x1fb9, 0x1efc, 0x20e3, 0x210f, 0x226c, 0x3ef0, 0x01ee, 0x1fc6, + 0x2306, 0x3e76, 0x3d5a, 0x24f3, 0x2059, 0x05b2, 0x21f7, 0x1913, 0x1436, 0x39ff, 0x3b9e, 0x28be, 0x32bb, 0x2597, 0x1e4b, 0x3e68, + 0x2ba2, 0x1b32, 0x0ad6, 0x0277, 0x0972, 0x2b63, 0x1a7e, 0x0dc9, 0x2116, 0x233e, 0x29d9, 0x1f23, 0x0d22, 0x2e65, 0x2169, 0x08f8, + 0x16fc, 0x37fc, 0x0343, 0x001a, 0x00b9, 0x08e0, 0x1111, 0x366a, 0x23c9, 0x3f0d, 0x2864, 0x0225, 0x27d1, 0x22d0, 0x2f8e, 0x3f6a, + 0x3b81, 0x319f, 0x0906, 0x0f92, 0x004e, 0x2d99, 0x36f6, 0x013c, 0x1d21, 0x2f7e, 0x0421, 0x1088, 0x31b5, 0x2e55, 0x078b, 0x3a3a, + 0x1765, 0x0f53, 0x16e9, 0x1c64, 0x26e1, 0x32d9, 0x3693, 0x3d29, 0x2214, 0x0ef1, 0x08d5, 0x01b0, 0x2123, 0x0a5a, 0x03b3, 0x2d56, + 0x034b, 0x04b6, 0x171f, 0x1a8a, 0x069c, 0x0157, 0x2234, 0x25b9, 0x0848, 0x29b7, 0x1938, 0x3edb, 0x1d8b, 0x3f24, 0x1159, 0x3a1e, + 0x39f6, 0x3aa5, 0x3bc7, 0x0b14, 0x34aa, 0x1516, 0x37b5, 0x3c3b, 0x38f4, 0x1f7f, 0x0855, 0x19af, 0x1a52, 0x2f00, 0x11d7, 0x3c58, + 0x36e4, 0x05a0, 0x09b6, 0x3ed4, 0x3316, 0x2760, 0x1b06, 0x0f2a, 0x15f5, 0x3e1a, 0x0abd, 0x0449, 0x14a4, 0x2490, 0x267c, 0x018a, + 0x2a15, 0x3e34, 0x08cc, 0x0f71, 0x0e70, 0x218c, 0x1c77, 0x207a, 0x31af, 0x2266, 0x2fce, 0x149e, 0x2a7c, 0x3a80, 0x0324, 0x1e10, + 0x09c8, 0x11bf, 0x037c, 0x2cd4, 0x1fd4, 0x11df, 0x2754, 0x1962, 0x20ea, 0x2ff8, 0x34e5, 0x0033, 0x0307, 0x180f, 0x3f7f, 0x388a, + 0x1232, 0x3bf2, 0x3f55, 0x3ee6, 0x1e07, 0x35e0, 0x277f, 0x2bf0, 0x00fb, 0x2721, 0x24c7, 0x06fe, 0x2815, 0x0cae, 0x139b, 0x1a9e, + 0x202d, 0x29f3, 0x0781, 0x2a04, 0x320c, 0x2b52, 0x0d58, 0x1100, 0x0fe7, 0x339f, 0x36be, 0x2da9, 0x2fd4, 0x0931, 0x00d0, 0x1a18, + 0x0afb, 0x043f, 0x055f, 0x038f, 0x3b72, 0x0d06, 0x24db, 0x2016, 0x3075, 0x0df1, 0x1a73, 0x3353, 0x24e4, 0x1538, 0x21be, 0x1b69, + 0x0fdd, 0x0c91, 0x1072, 0x3842, 0x2745, 0x05fe, 0x24cf, 0x1031, 0x308b, 0x1d2e, 0x14ed, 0x09bd, 0x35d1, 0x163c, 0x256b, 0x023b, + 0x0166, 0x16c8, 0x27a3, 0x12e5, 0x3c02, 0x2949, 0x17a5, 0x0922, 0x1680, 0x1b93, 0x04c9, 0x34fd, 0x045a, 0x0cfa, 0x3c65, 0x0315, + 0x07de, 0x244d, 0x2cf2, 0x3750, 0x3163, 0x075d, 0x3af6, 0x1f14, 0x3b53, 0x26d8, 0x1fed, 0x301a, 0x2766, 0x3c8d, 0x237a, 0x23ba, + 0x3d24, 0x3665, 0x190e, 0x1746, 0x2011, 0x2beb, 0x2075, 0x3c36, 0x1221, 0x04ef, 0x2cc3, 0x15ad, 0x21e6, 0x157b, 0x2d88, 0x0893, + 0x2c94, 0x2ada, 0x2a3e, 0x1145, 0x2a4a, 0x0374, 0x066e, 0x272d, 0x2cee, 0x279f, 0x2a3a, 0x190a, 0x0c71, 0x063f, 0x12c7, 0x23a5, + 0x38e9, 0x2967, 0x0643, 0x381c, 0x1f8b, 0x3f9b, 0x1bc2, 0x12d7, 0x0ea4, 0x3559, 0x3efa, 0x1dfd, 0x3d98, 0x1afa, 0x3547, 0x2a28, + 0x3912, 0x31d6, 0x0c75, 0x2329, 0x2efa, 0x0ca8, 0x155a, 0x22ca, 0x0aa3, 0x12d2, 0x3c31, 0x091d, 0x331c, 0x0556, 0x0b3c, 0x0ebd, + 0x2f66, 0x1521, 0x23a9, 0x194c, 0x0117, 0x28a4, 0x25a0, 0x0aa8, 0x3607, 0x0339, 0x0cf4, 0x1af4, 0x2f77, 0x3398, 0x3990, 0x1974, + 0x22d8, 0x0c89, 0x12cb, 0x3f33, 0x1673, 0x0ba5, 0x2aaf, 0x35f0, 0x30c5, 0x303c, 0x3d3f, 0x2f07, 0x2a8a, 0x1e1d, 0x377f, 0x3e2b, + 0x1615, 0x1ccc, 0x2ade, 0x1a45, 0x07ae, 0x262e, 0x1ae5, 0x0ec2, 0x1baf, 0x11f1, 0x0128, 0x02d4, 0x2c41, 0x360d, 0x3b44, 0x1e55, + 0x22a1, 0x0cbe, 0x2c98, 0x0a73, 0x305d, 0x0a69, 0x35fe, 0x2b01, 0x2508, 0x24a1, 0x1a60, 0x1b76, 0x0f30, 0x3170, 0x2f36, 0x3380, + 0x1204, 0x067e, 0x1149, 0x022e, 0x2e36, 0x2dca, 0x1550, 0x0b41, 0x343b, 0x3e47, 0x15e5, 0x13b4, 0x3db5, 0x136d, 0x3343, 0x3daa, + 0x1334, 0x0d7e, 0x2a42, 0x1ecd, 0x15a4, 0x3aad, 0x3298, 0x0753, 0x0b71, 0x02ac, 0x2fa6, 0x198f, 0x3512, 0x096a, 0x2cb8, 0x2552, + 0x09b2, 0x3bc3, 0x0378, 0x08c8, 0x077d, 0x3f51, 0x106e, 0x055b, 0x099a, 0x06bf, 0x0ad2, 0x3d56, 0x0902, 0x033f, 0x171b, 0x16e5, + 0x07b8, 0x3f19, 0x2a4e, 0x3132, 0x2589, 0x1d52, 0x0cd7, 0x0fbf, 0x1279, 0x3f3a, 0x345e, 0x1cff, 0x1b0c, 0x1867, 0x00e6, 0x089e, + 0x0efa, 0x3ea3, 0x2731, 0x1eef, 0x20dc, 0x0ab6, 0x32e8, 0x3321, 0x1aab, 0x14b2, 0x019b, 0x0a8f, 0x035e, 0x1de0, 0x2a57, 0x1f50, + 0x1364, 0x3787, 0x0672, 0x2c0f, 0x06f0, 0x1190, 0x35e8, 0x19e8, 0x3a51, 0x25b1, 0x1fe6, 0x1a59, 0x38c6, 0x1ea4, 0x2f45, 0x2ea4, + 0x0c1a, 0x39db, 0x04f3, 0x2854, 0x3dfd, 0x23d3, 0x0732, 0x232e, 0x1d82, 0x0c5b, 0x1bde, 0x2a6c, 0x3488, 0x3996, 0x087a, 0x1a08, + 0x356b, 0x13ce, 0x1225, 0x336a, 0x26bd, 0x2154, 0x265d, 0x124f, 0x3ca8, 0x2c19, 0x3a58, 0x2c74, 0x05a6, 0x23e0, 0x191e, 0x0bf8, + 0x1732, 0x247b, 0x15b1, 0x06e4, 0x3f77, 0x2fe2, 0x0f3b, 0x0c7a, 0x0c07, 0x3c44, 0x08ef, 0x2cb0, 0x3247, 0x20c4, 0x33af, 0x2794, + 0x12a9, 0x165c, 0x2cc7, 0x17d3, 0x1ed5, 0x39a1, 0x09da, 0x2af2, 0x1752, 0x37a2, 0x2d2c, 0x0ff3, 0x0fa8, 0x352b, 0x2547, 0x20cd, + 0x03a8, 0x32a7, 0x157f, 0x39be, 0x1395, 0x11d1, 0x2f88, 0x31db, 0x1601, 0x14d0, 0x0e3f, 0x1958, 0x14e4, 0x197a, 0x37e1, 0x2bbd, + 0x0088, 0x306a, 0x21ea, 0x1c16, 0x25ed, 0x2771, 0x2823, 0x2d63, 0x26ff, 0x22df, 0x273b, 0x125e, 0x36ea, 0x0941, 0x13e3, 0x16a1, + 0x1634, 0x169a, 0x0897, 0x0eb6, 0x2383, 0x0f84, 0x0dad, 0x3917, 0x3ff3, 0x1b28, 0x2195, 0x3ce3, 0x02e7, 0x2085, 0x2fef, 0x1e9c, + 0x27d9, 0x27fd, 0x2d8c, 0x128f, 0x2f1d, 0x22f8, 0x3722, 0x19f0, 0x1715, 0x3b3e, 0x3541, 0x3c5f, 0x1a11, 0x3a33, 0x37db, 0x0874, + 0x0019, 0x37fb, 0x3669, 0x08df, 0x0224, 0x3f0c, 0x3f69, 0x22cf, 0x0f91, 0x319e, 0x013b, 0x2d98, 0x1087, 0x2f7d, 0x3a39, 0x2e54, + 0x1c63, 0x0f52, 0x3d28, 0x32d8, 0x01af, 0x0ef0, 0x2d55, 0x0a59, 0x1a89, 0x04b5, 0x25b8, 0x0156, 0x3eda, 0x29b6, 0x3a1d, 0x3f23, + 0x3618, 0x30ce, 0x174a, 0x2ce6, 0x01cc, 0x113c, 0x2be1, 0x155f, 0x3473, 0x1ca9, 0x18f4, 0x1e76, 0x210e, 0x1efb, 0x1fc5, 0x3eef, + 0x24f2, 0x3e75, 0x1912, 0x05b1, 0x28bd, 0x39fe, 0x3e67, 0x2596, 0x0276, 0x1b31, 0x0dc8, 0x2b62, 0x1f22, 0x233d, 0x08f7, 0x2e64, + 0x3ee5, 0x3bf1, 0x2bef, 0x35df, 0x06fd, 0x2720, 0x1a9d, 0x0cad, 0x2a03, 0x29f2, 0x10ff, 0x2b51, 0x2da8, 0x339e, 0x1a17, 0x0930, + 0x038e, 0x043e, 0x2015, 0x0d05, 0x3352, 0x0df0, 0x1b68, 0x1537, 0x3841, 0x0c90, 0x1030, 0x05fd, 0x09bc, 0x1d2d, 0x023a, 0x163b, + 0x0b13, 0x3aa4, 0x3c3a, 0x1515, 0x19ae, 0x1f7e, 0x3c57, 0x2eff, 0x3ed3, 0x059f, 0x0f29, 0x275f, 0x0448, 0x3e19, 0x0189, 0x248f, + 0x0f70, 0x3e33, 0x2079, 0x218b, 0x149d, 0x2265, 0x1e0f, 0x3a7f, 0x2cd3, 0x11be, 0x1961, 0x11de, 0x0032, 0x2ff7, 0x3889, 0x180e, + 0x2054, 0x0b65, 0x26dc, 0x00b4, 0x0e6b, 0x34a5, 0x3b6d, 0x1e02, 0x33d8, 0x3227, 0x3807, 0x03f0, 0x1abf, 0x23af, 0x1295, 0x38b2, + 0x28b1, 0x34b4, 0x3b57, 0x3c75, 0x3857, 0x3fce, 0x2689, 0x2fc6, 0x15dd, 0x18ec, 0x2f4c, 0x1c8a, 0x2496, 0x0655, 0x1246, 0x177e, + 0x20a5, 0x3cee, 0x301e, 0x060e, 0x2b0f, 0x31ea, 0x3115, 0x3eff, 0x2131, 0x09e8, 0x1049, 0x3ab6, 0x07ea, 0x10ab, 0x1ac9, 0x335f, + 0x1d14, 0x3954, 0x1ff1, 0x01d5, 0x133c, 0x28e9, 0x0066, 0x29cb, 0x30d6, 0x1836, 0x0bdd, 0x0045, 0x25e4, 0x33b9, 0x0ee5, 0x32f7, + 0x03ea, 0x3d4a, 0x3c91, 0x0831, 0x131c, 0x318f, 0x2879, 0x355e, 0x34f7, 0x1df7, 0x02ce, 0x3d50, 0x2a66, 0x1952, 0x2d92, 0x2b4b, + 0x0ca1, 0x1d4b, 0x276a, 0x0de9, 0x1e86, 0x1e8d, 0x2bcc, 0x0ed0, 0x0b25, 0x2ab6, 0x0f49, 0x1d99, 0x14aa, 0x0597, 0x25cc, 0x391e, + 0x04d9, 0x3de1, 0x23be, 0x3fa8, 0x03dc, 0x3f8c, 0x32c4, 0x0ea9, 0x2b0a, 0x0e66, 0x03d7, 0x1317, 0x3150, 0x065f, 0x382e, 0x2534, + 0x3f72, 0x3df8, 0x237e, 0x1390, 0x01c7, 0x021f, 0x19a9, 0x06f8, 0x200c, 0x3bfd, 0x0112, 0x1f86, 0x2e31, 0x07a9, 0x20d7, 0x0778, + 0x3642, 0x0b30, 0x2451, 0x2578, 0x0664, 0x2956, 0x27b3, 0x2a2d, 0x2979, 0x3cd2, 0x0c36, 0x3c97, 0x3b8c, 0x2f6c, 0x2803, 0x3878, + 0x21de, 0x323f, 0x07e2, 0x1f65, 0x1cbe, 0x0b9b, 0x3011, 0x1c81, 0x325a, 0x17f3, 0x2eab, 0x3631, 0x0190, 0x3fbd, 0x10dd, 0x32b3, + 0x061a, 0x3400, 0x3754, 0x286d, 0x3155, 0x33ee, 0x132a, 0x354c, 0x1ad3, 0x117e, 0x2f54, 0x373e, 0x0e2d, 0x3790, 0x20fc, 0x1629, + 0x16b0, 0x0b4f, 0x2cf6, 0x2438, 0x0a9a, 0x0b1c, 0x1d3e, 0x2c05, 0x2247, 0x07c4, 0x28ca, 0x3492, 0x0740, 0x31c3, 0x3c4c, 0x29a3, + 0x2d22, 0x156f, 0x0761, 0x2d72, 0x2539, 0x164c, 0x3580, 0x1aff, 0x0464, 0x01bc, 0x22ad, 0x0837, 0x1899, 0x1527, 0x27df, 0x266b, + 0x246f, 0x3b34, 0x3167, 0x3fb4, 0x196c, 0x1e94, 0x252c, 0x36aa, 0x3aef, 0x35f7, 0x2656, 0x2d4e, 0x2682, 0x300a, 0x2a9b, 0x0db4, + 0x221d, 0x2646, 0x1f18, 0x28dd, 0x3833, 0x116e, 0x13fd, 0x3d9d, 0x2de8, 0x25d4, 0x0f11, 0x3301, 0x39e7, 0x2b3b, 0x313b, 0x1488, + 0x00dd, 0x2a92, 0x3afa, 0x1804, 0x1e68, 0x17b5, 0x2bf8, 0x3fdd, 0x23ea, 0x1454, 0x05d5, 0x38fb, 0x3684, 0x208d, 0x35c5, 0x2038, + 0x3d6f, 0x2f11, 0x1b97, 0x2831, 0x3de6, 0x26ca, 0x1c6f, 0x3821, 0x2bd9, 0x1548, 0x08b6, 0x1322, 0x058d, 0x25a6, 0x19f6, 0x19ff, + 0x30b9, 0x1821, 0x1684, 0x3e8c, 0x3bdd, 0x0ce6, 0x2aa2, 0x1787, 0x0e53, 0x3865, 0x38cd, 0x1bfc, 0x3e20, 0x123c, 0x062c, 0x1cec, + 0x16d4, 0x19cf, 0x3501, 0x14f9, 0x04de, 0x2e96, 0x3c20, 0x0648, 0x2843, 0x37be, 0x27c8, 0x18cf, 0x1f6d, 0x14db, 0x2d44, 0x225a, + 0x0481, 0x219f, 0x04cd, 0x235f, 0x0d86, 0x2c33, 0x293c, 0x1f9d, 0x3620, 0x3b06, 0x2dd7, 0x28f8, 0x0798, 0x18b8, 0x1284, 0x3250, + 0x312b, 0x2322, 0x0cfe, 0x1c0f, 0x3fad, 0x0de2, 0x240a, 0x296c, 0x33c8, 0x263b, 0x2d02, 0x3195, 0x1f76, 0x0aae, 0x3728, 0x1166, + 0x34f1, 0x33d2, 0x045e, 0x2973, 0x33c2, 0x2bd3, 0x2294, 0x0492, 0x0e9e, 0x167a, 0x0994, 0x1ba9, 0x15fb, 0x1d7c, 0x29fd, 0x0f8b, + 0x3712, 0x2ac0, 0x0319, 0x1ce0, 0x23c3, 0x17c5, 0x00f5, 0x38ee, 0x1c53, 0x10f6, 0x0e79, 0x0e0c, 0x1505, 0x3412, 0x24be, 0x36b2, + 0x2f96, 0x227a, 0x3c69, 0x142b, 0x06af, 0x039a, 0x1ee2, 0x1198, 0x330c, 0x2913, 0x0e01, 0x19b6, 0x0883, 0x332f, 0x05c1, 0x2928, + 0x172a, 0x3d1c, 0x16cc, 0x209d, 0x3f91, 0x3d0e, 0x00ab, 0x12dc, 0x0498, 0x2d0b, 0x35a8, 0x287f, 0x2b1d, 0x011d, 0x22fe, 0x0818, + 0x2f2a, 0x1da2, 0x016a, 0x0094, 0x19c0, 0x179b, 0x0dbb, 0x0d30, 0x2b72, 0x2b8d, 0x1eab, 0x0569, 0x044f, 0x0073, 0x2e7f, 0x1a2f, + 0x0a29, 0x3045, 0x12e9, 0x359c, 0x03e1, 0x38e0, 0x08be, 0x1bc7, 0x1302, 0x2176, 0x1c92, 0x270a, 0x1ffd, 0x3ebf, 0x10ba, 0x3f5e, + 0x1f39, 0x0d97, 0x27a7, 0x0259, 0x2b2c, 0x3bcf, 0x29e5, 0x160b, 0x06ca, 0x3ffc, 0x2ecf, 0x15c5, 0x10ce, 0x3d81, 0x0c0f, 0x1c31, + 0x14c6, 0x3a98, 0x294d, 0x2625, 0x0eae, 0x1944, 0x1cd8, 0x3fa0, 0x229a, 0x07d7, 0x1c5c, 0x3564, 0x21d7, 0x28aa, 0x2f23, 0x30b2, + 0x1dd4, 0x1bd4, 0x3c06, 0x2411, 0x029d, 0x0ed7, 0x36dd, 0x0e83, 0x384c, 0x0bac, 0x01fb, 0x0405, 0x0ac3, 0x31f9, 0x2c54, 0x238a, + 0x3577, 0x1065, 0x0926, 0x25fa, 0x32c9, 0x3730, 0x052b, 0x1f90, 0x0fcd, 0x3926, 0x0bc2, 0x2e74, 0x0b04, 0x0e17, 0x2696, 0x0d16, + 0x1464, 0x1e25, 0x17a9, 0x107d, 0x22e9, 0x3ae1, 0x2787, 0x389c, 0x3766, 0x2606, 0x0e48, 0x085c, 0x0723, 0x02ef, 0x05e0, 0x134a, + 0x1060, 0x3a93, 0x3040, 0x3d17, 0x2abb, 0x231d, 0x19ca, 0x2f0c, 0x2641, 0x156a, 0x33fb, 0x0b2b, 0x3ddc, 0x3d45, 0x3ce9, 0x0b60, + 0x3a9f, 0x3bec, 0x30c9, 0x37f6, 0x1695, 0x32a2, 0x2476, 0x39d6, 0x3e9e, 0x3bbe, 0x0679, 0x1cc7, 0x151c, 0x2962, 0x3660, 0x16c3, + 0x3d16, 0x3a92, 0x2f0b, 0x231c, 0x0b2a, 0x1569, 0x0b5f, 0x3d44, 0x37f5, 0x3beb, 0x39d5, 0x32a1, 0x1cc6, 0x3bbd, 0x16c2, 0x2961, + 0x231b, 0x3a91, 0x3d43, 0x1568, 0x32a0, 0x3bea, 0x2960, 0x3bbc, 0x1567, 0x3a90, 0x3bbb, 0x3be9, 0x3be8, 0x3a8f, 0x3a8d, 0x3a8e, + 0x1bd0, 0x3a94, 0x1e21, 0x1061, 0x1d9e, 0x3d18, 0x0d93, 0x3041, 0x33ce, 0x231e, 0x2276, 0x2abc, 0x181d, 0x2f0d, 0x219b, 0x19cb, + 0x3b30, 0x156b, 0x2a8e, 0x2642, 0x323b, 0x0b2c, 0x0b4b, 0x33fc, 0x1d47, 0x3d46, 0x3df4, 0x3ddd, 0x34b0, 0x0b61, 0x3950, 0x3cea, + 0x043a, 0x3bed, 0x3e2f, 0x3aa0, 0x0f4e, 0x37f7, 0x3e71, 0x30ca, 0x3066, 0x32a3, 0x27f9, 0x1696, 0x13ca, 0x39d7, 0x1658, 0x2477, + 0x3f15, 0x3bbf, 0x3783, 0x3e9f, 0x0cba, 0x1cc8, 0x0d7a, 0x067a, 0x31d2, 0x2963, 0x0c85, 0x151d, 0x2449, 0x16c4, 0x2ad6, 0x3661, + 0x29ef, 0x3bee, 0x0c8d, 0x043b, 0x059c, 0x3aa1, 0x11bb, 0x3e30, 0x319b, 0x37f8, 0x04b2, 0x0f4f, 0x1ca6, 0x30cb, 0x1b2e, 0x3e72, + 0x14cd, 0x32a4, 0x22dc, 0x3067, 0x1b25, 0x1697, 0x3b3b, 0x27fa, 0x0c58, 0x39d8, 0x2c16, 0x13cb, 0x3c41, 0x2478, 0x379f, 0x1659, + 0x06bc, 0x3bc0, 0x3f37, 0x3f16, 0x14af, 0x3ea0, 0x25ae, 0x3784, 0x11ee, 0x1cc9, 0x249e, 0x0cbb, 0x3e44, 0x067b, 0x02a9, 0x0d7b, + 0x3556, 0x2964, 0x12cf, 0x31d3, 0x0336, 0x151e, 0x3039, 0x0c86, 0x1b90, 0x16c5, 0x26d5, 0x244a, 0x04ec, 0x3662, 0x279c, 0x2ad7, + 0x07d4, 0x3a95, 0x0ba9, 0x1bd1, 0x3923, 0x1062, 0x2603, 0x1e22, 0x2d08, 0x3d19, 0x2b8a, 0x1d9f, 0x2173, 0x3042, 0x3ff9, 0x0d94, + 0x2638, 0x231f, 0x1677, 0x33cf, 0x10f3, 0x2abd, 0x2910, 0x2277, 0x1545, 0x2f0e, 0x3862, 0x181e, 0x37bb, 0x19cc, 0x3b03, 0x219c, + 0x01b9, 0x156c, 0x35f4, 0x3b31, 0x25d1, 0x2643, 0x1451, 0x2a8f, 0x3ccf, 0x0b2d, 0x17f0, 0x323c, 0x117b, 0x33fd, 0x07c1, 0x0b4c, + 0x1df4, 0x3d47, 0x2ab3, 0x1d48, 0x0e63, 0x3dde, 0x3bfa, 0x3df5, 0x3224, 0x0b62, 0x18e9, 0x34b1, 0x09e5, 0x3ceb, 0x1833, 0x3951, + 0x3f4f, 0x3bc1, 0x033d, 0x06bd, 0x1d50, 0x3f17, 0x1865, 0x3f38, 0x0ab4, 0x3ea1, 0x1dde, 0x14b0, 0x118e, 0x3785, 0x1ea2, 0x25af, + 0x262c, 0x1cca, 0x360b, 0x11ef, 0x0a67, 0x0cbc, 0x316e, 0x249f, 0x2dc8, 0x067c, 0x136b, 0x3e45, 0x3aab, 0x0d7c, 0x0968, 0x02aa, + 0x3f99, 0x2965, 0x1af8, 0x3557, 0x0ca6, 0x31d4, 0x0554, 0x12d0, 0x28a2, 0x151f, 0x3396, 0x0337, 0x0ba3, 0x0c87, 0x1e1b, 0x303a, + 0x2947, 0x16c6, 0x0cf8, 0x1b91, 0x075b, 0x244b, 0x3c8b, 0x26d6, 0x2be9, 0x3663, 0x1579, 0x04ed, 0x0372, 0x2ad8, 0x063d, 0x279d, + 0x271e, 0x3bef, 0x339c, 0x29f0, 0x0dee, 0x043c, 0x1d2b, 0x0c8e, 0x1f7c, 0x3aa2, 0x3e17, 0x059d, 0x2263, 0x3e31, 0x2ff5, 0x11bc, + 0x3f0a, 0x37f9, 0x2f7b, 0x319c, 0x0eee, 0x0f50, 0x29b4, 0x04b3, 0x113a, 0x30cc, 0x1ef9, 0x1ca7, 0x39fc, 0x3e73, 0x233b, 0x1b2f, + 0x11cf, 0x32a5, 0x1978, 0x14ce, 0x276f, 0x3068, 0x093f, 0x22dd, 0x0f82, 0x1698, 0x2083, 0x1b26, 0x22f6, 0x27fb, 0x3a31, 0x3b3c, + 0x23d1, 0x39d9, 0x3994, 0x0c59, 0x2152, 0x13cc, 0x23de, 0x2c17, 0x2fe0, 0x2479, 0x20c2, 0x3c42, 0x399f, 0x165a, 0x3529, 0x37a0, + 0x164a, 0x156d, 0x1525, 0x01ba, 0x1e92, 0x3b32, 0x3008, 0x35f5, 0x116c, 0x2644, 0x2b39, 0x25d2, 0x17b3, 0x2a90, 0x208b, 0x1452, + 0x2954, 0x0b2e, 0x2f6a, 0x3cd0, 0x0b99, 0x323d, 0x3fbb, 0x17f1, 0x33ec, 0x33fe, 0x378e, 0x117c, 0x0b1a, 0x0b4d, 0x31c1, 0x07c2, + 0x318d, 0x3d48, 0x1950, 0x1df5, 0x1e8b, 0x1d49, 0x0595, 0x2ab4, 0x3f8a, 0x3ddf, 0x065d, 0x0e64, 0x021d, 0x3df6, 0x07a7, 0x3bfb, + 0x34a3, 0x0b63, 0x23ad, 0x3225, 0x3fcc, 0x34b2, 0x0653, 0x18ea, 0x31e8, 0x3cec, 0x10a9, 0x09e6, 0x28e7, 0x3952, 0x33b7, 0x1834, + 0x1942, 0x3a96, 0x28a8, 0x07d5, 0x0ed5, 0x1bd2, 0x31f7, 0x0baa, 0x372e, 0x1063, 0x0e15, 0x3924, 0x3adf, 0x1e23, 0x02ed, 0x2604, + 0x3d0c, 0x3d1a, 0x011b, 0x2d09, 0x1799, 0x1da0, 0x0071, 0x2b8b, 0x38de, 0x3043, 0x3ebd, 0x2174, 0x3bcd, 0x0d95, 0x3d7f, 0x3ffa, + 0x0de0, 0x2320, 0x0aac, 0x2639, 0x2bd1, 0x33d0, 0x1d7a, 0x1678, 0x17c3, 0x2abe, 0x3410, 0x10f4, 0x0398, 0x2278, 0x332d, 0x2911, + 0x26c8, 0x2f0f, 0x25a4, 0x1546, 0x0ce4, 0x181f, 0x123a, 0x3863, 0x2e94, 0x19cd, 0x14d9, 0x37bc, 0x2c31, 0x219d, 0x18b6, 0x3b04, + 0x381b, 0x2966, 0x12d6, 0x3f9a, 0x1dfc, 0x3558, 0x2a27, 0x1af9, 0x2328, 0x31d5, 0x22c9, 0x0ca7, 0x091c, 0x12d1, 0x0ebc, 0x0555, + 0x194b, 0x1520, 0x0aa7, 0x28a3, 0x1af3, 0x0338, 0x1973, 0x3397, 0x3f32, 0x0c88, 0x35ef, 0x0ba4, 0x2f06, 0x303b, 0x3e2a, 0x1e1c, + 0x12e4, 0x16c7, 0x0921, 0x2948, 0x34fc, 0x1b92, 0x0314, 0x0cf9, 0x374f, 0x244c, 0x1f13, 0x075c, 0x3019, 0x26d7, 0x23b9, 0x3c8c, + 0x1745, 0x3664, 0x3c35, 0x2bea, 0x15ac, 0x04ee, 0x0892, 0x157a, 0x1144, 0x2ad9, 0x272c, 0x0373, 0x1909, 0x279e, 0x23a4, 0x063e, + 0x08c7, 0x3bc2, 0x055a, 0x3f50, 0x3d55, 0x06be, 0x16e4, 0x033e, 0x3131, 0x3f18, 0x0fbe, 0x1d51, 0x1cfe, 0x3f39, 0x089d, 0x1866, + 0x1eee, 0x3ea2, 0x3320, 0x0ab5, 0x0a8e, 0x14b1, 0x1f4f, 0x1ddf, 0x2c0e, 0x3786, 0x19e7, 0x118f, 0x1a58, 0x25b0, 0x2ea3, 0x1ea3, + 0x1a44, 0x1ccb, 0x0ec1, 0x262d, 0x02d3, 0x11f0, 0x1e54, 0x360c, 0x0a72, 0x0cbd, 0x2b00, 0x0a68, 0x1b75, 0x24a0, 0x337f, 0x316f, + 0x022d, 0x067d, 0x0b40, 0x2dc9, 0x13b3, 0x3e46, 0x3da9, 0x136c, 0x1ecc, 0x0d7d, 0x0752, 0x3aac, 0x198e, 0x02ab, 0x2551, 0x0969, + 0x39bd, 0x32a6, 0x31da, 0x11d0, 0x1957, 0x14cf, 0x2bbc, 0x1979, 0x1c15, 0x3069, 0x2d62, 0x2770, 0x125d, 0x22de, 0x16a0, 0x0940, + 0x0eb5, 0x1699, 0x3916, 0x0f83, 0x3ce2, 0x1b27, 0x1e9b, 0x2084, 0x128e, 0x27fc, 0x19ef, 0x22f7, 0x3c5e, 0x3b3d, 0x0873, 0x3a32, + 0x2853, 0x39da, 0x232d, 0x23d2, 0x2a6b, 0x0c5a, 0x1a07, 0x3995, 0x3369, 0x13cd, 0x124e, 0x2153, 0x2c73, 0x2c18, 0x0bf7, 0x23df, + 0x06e3, 0x247a, 0x0c79, 0x2fe1, 0x2caf, 0x3c43, 0x2793, 0x20c3, 0x17d2, 0x165b, 0x2af1, 0x39a0, 0x0ff2, 0x37a1, 0x20cc, 0x352a, + 0x35de, 0x3bf0, 0x0cac, 0x271f, 0x2b50, 0x29f1, 0x092f, 0x339d, 0x0d04, 0x043d, 0x1536, 0x0def, 0x05fc, 0x0c8f, 0x163a, 0x1d2c, + 0x1514, 0x3aa3, 0x2efe, 0x1f7d, 0x275e, 0x059e, 0x248e, 0x3e18, 0x218a, 0x3e32, 0x3a7e, 0x2264, 0x11dd, 0x11bd, 0x180d, 0x2ff6, + 0x08de, 0x37fa, 0x22ce, 0x3f0b, 0x2d97, 0x319d, 0x2e53, 0x2f7c, 0x32d7, 0x0f51, 0x0a58, 0x0eef, 0x0155, 0x04b4, 0x3f22, 0x29b5, + 0x2ce5, 0x30cd, 0x155e, 0x113b, 0x1e75, 0x1ca8, 0x3eee, 0x1efa, 0x05b0, 0x3e74, 0x2595, 0x39fd, 0x2b61, 0x1b30, 0x2e63, 0x233c, + 0x0830, 0x3d49, 0x355d, 0x318e, 0x3d4f, 0x1df6, 0x2b4a, 0x1951, 0x0de8, 0x1d4a, 0x0ecf, 0x1e8c, 0x1d98, 0x2ab5, 0x391d, 0x0596, + 0x3fa7, 0x3de0, 0x0ea8, 0x3f8b, 0x1316, 0x0e65, 0x2533, 0x065e, 0x138f, 0x3df7, 0x06f7, 0x021e, 0x1f85, 0x3bfc, 0x0777, 0x07a8, + 0x00b3, 0x0b64, 0x1e01, 0x34a4, 0x03ef, 0x3226, 0x38b1, 0x23ae, 0x3c74, 0x34b3, 0x2fc5, 0x3fcd, 0x1c89, 0x18eb, 0x177d, 0x0654, + 0x060d, 0x3ced, 0x3efe, 0x31e9, 0x3ab5, 0x09e7, 0x335e, 0x10aa, 0x01d4, 0x3953, 0x29ca, 0x28e8, 0x0044, 0x1835, 0x32f6, 0x33b8, + 0x2d71, 0x156e, 0x1afe, 0x164b, 0x0836, 0x01bb, 0x266a, 0x1526, 0x3fb3, 0x3b33, 0x36a9, 0x1e93, 0x2d4d, 0x35f6, 0x0db3, 0x3009, + 0x28dc, 0x2645, 0x3d9c, 0x116d, 0x3300, 0x25d3, 0x1487, 0x2b3a, 0x1803, 0x2a91, 0x3fdc, 0x17b4, 0x38fa, 0x1453, 0x2037, 0x208c, + 0x2577, 0x0b2f, 0x2a2c, 0x2955, 0x3c96, 0x3cd1, 0x3877, 0x2f6b, 0x1f64, 0x323e, 0x1c80, 0x0b9a, 0x3630, 0x17f2, 0x32b2, 0x3fbc, + 0x286c, 0x33ff, 0x354b, 0x33ed, 0x373d, 0x117d, 0x1628, 0x378f, 0x2437, 0x0b4e, 0x2c04, 0x0b1b, 0x3491, 0x07c3, 0x29a2, 0x31c2, + 0x1c0e, 0x2321, 0x296b, 0x0de1, 0x3194, 0x263a, 0x1165, 0x0aad, 0x2972, 0x33d1, 0x0491, 0x2bd2, 0x1ba8, 0x1679, 0x0f8a, 0x1d7b, + 0x1cdf, 0x2abf, 0x38ed, 0x17c4, 0x0e0b, 0x10f5, 0x36b1, 0x3411, 0x142a, 0x2279, 0x1197, 0x0399, 0x19b5, 0x2912, 0x2927, 0x332e, + 0x2830, 0x2f10, 0x3820, 0x26c9, 0x1321, 0x1547, 0x19fe, 0x25a5, 0x3e8b, 0x1820, 0x1786, 0x0ce5, 0x1bfb, 0x3864, 0x1ceb, 0x123b, + 0x14f8, 0x19ce, 0x0647, 0x2e95, 0x18ce, 0x37bd, 0x2259, 0x14da, 0x235e, 0x219e, 0x1f9c, 0x2c32, 0x28f7, 0x3b05, 0x324f, 0x18b7, + 0x2624, 0x3a97, 0x3f9f, 0x1943, 0x3563, 0x07d6, 0x30b1, 0x28a9, 0x2410, 0x1bd3, 0x0e82, 0x0ed6, 0x0404, 0x0bab, 0x2389, 0x31f8, + 0x25f9, 0x1064, 0x1f8f, 0x372f, 0x2e73, 0x3925, 0x0d15, 0x0e16, 0x107c, 0x1e24, 0x389b, 0x3ae0, 0x085b, 0x2605, 0x1349, 0x02ee, + 0x209c, 0x3d1b, 0x12db, 0x3d0d, 0x287e, 0x2d0a, 0x0817, 0x011c, 0x0093, 0x1da1, 0x0d2f, 0x179a, 0x0568, 0x2b8c, 0x1a2e, 0x0072, + 0x359b, 0x3044, 0x1bc6, 0x38df, 0x2709, 0x2175, 0x3f5d, 0x3ebe, 0x0258, 0x0d96, 0x160a, 0x3bce, 0x15c4, 0x3ffb, 0x1c30, 0x3d80 + }, + + /* "alpha_to" table */ + + { + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x0443, 0x0886, + 0x110c, 0x2218, 0x0073, 0x00e6, 0x01cc, 0x0398, 0x0730, 0x0e60, 0x1cc0, 0x3980, 0x3743, 0x2ac5, 0x11c9, 0x2392, 0x0367, 0x06ce, + 0x0d9c, 0x1b38, 0x3670, 0x28a3, 0x1505, 0x2a0a, 0x1057, 0x20ae, 0x051f, 0x0a3e, 0x147c, 0x28f8, 0x15b3, 0x2b66, 0x128f, 0x251e, + 0x0e7f, 0x1cfe, 0x39fc, 0x37bb, 0x2b35, 0x1229, 0x2452, 0x0ce7, 0x19ce, 0x339c, 0x237b, 0x02b5, 0x056a, 0x0ad4, 0x15a8, 0x2b50, + 0x12e3, 0x25c6, 0x0fcf, 0x1f9e, 0x3f3c, 0x3a3b, 0x3035, 0x2429, 0x0c11, 0x1822, 0x3044, 0x24cb, 0x0dd5, 0x1baa, 0x3754, 0x2aeb, + 0x1195, 0x232a, 0x0217, 0x042e, 0x085c, 0x10b8, 0x2170, 0x06a3, 0x0d46, 0x1a8c, 0x3518, 0x2e73, 0x18a5, 0x314a, 0x26d7, 0x09ed, + 0x13da, 0x27b4, 0x0b2b, 0x1656, 0x2cac, 0x1d1b, 0x3a36, 0x302f, 0x241d, 0x0c79, 0x18f2, 0x31e4, 0x278b, 0x0b55, 0x16aa, 0x2d54, + 0x1eeb, 0x3dd6, 0x3fef, 0x3b9d, 0x3379, 0x22b1, 0x0121, 0x0242, 0x0484, 0x0908, 0x1210, 0x2420, 0x0c03, 0x1806, 0x300c, 0x245b, + 0x0cf5, 0x19ea, 0x33d4, 0x23eb, 0x0395, 0x072a, 0x0e54, 0x1ca8, 0x3950, 0x36e3, 0x2985, 0x1749, 0x2e92, 0x1967, 0x32ce, 0x21df, + 0x07fd, 0x0ffa, 0x1ff4, 0x3fe8, 0x3b93, 0x3365, 0x2289, 0x0151, 0x02a2, 0x0544, 0x0a88, 0x1510, 0x2a20, 0x1003, 0x2006, 0x044f, + 0x089e, 0x113c, 0x2278, 0x00b3, 0x0166, 0x02cc, 0x0598, 0x0b30, 0x1660, 0x2cc0, 0x1dc3, 0x3b86, 0x334f, 0x22dd, 0x01f9, 0x03f2, + 0x07e4, 0x0fc8, 0x1f90, 0x3f20, 0x3a03, 0x3045, 0x24c9, 0x0dd1, 0x1ba2, 0x3744, 0x2acb, 0x11d5, 0x23aa, 0x0317, 0x062e, 0x0c5c, + 0x18b8, 0x3170, 0x26a3, 0x0905, 0x120a, 0x2414, 0x0c6b, 0x18d6, 0x31ac, 0x271b, 0x0a75, 0x14ea, 0x29d4, 0x17eb, 0x2fd6, 0x1bef, + 0x37de, 0x2bff, 0x13bd, 0x277a, 0x0ab7, 0x156e, 0x2adc, 0x11fb, 0x23f6, 0x03af, 0x075e, 0x0ebc, 0x1d78, 0x3af0, 0x31a3, 0x2705, + 0x0a49, 0x1492, 0x2924, 0x160b, 0x2c16, 0x1c6f, 0x38de, 0x35ff, 0x2fbd, 0x1b39, 0x3672, 0x28a7, 0x150d, 0x2a1a, 0x1077, 0x20ee, + 0x059f, 0x0b3e, 0x167c, 0x2cf8, 0x1db3, 0x3b66, 0x328f, 0x215d, 0x06f9, 0x0df2, 0x1be4, 0x37c8, 0x2bd3, 0x13e5, 0x27ca, 0x0bd7, + 0x17ae, 0x2f5c, 0x1afb, 0x35f6, 0x2faf, 0x1b1d, 0x363a, 0x2837, 0x142d, 0x285a, 0x14f7, 0x29ee, 0x179f, 0x2f3e, 0x1a3f, 0x347e, + 0x2cbf, 0x1d3d, 0x3a7a, 0x30b7, 0x252d, 0x0e19, 0x1c32, 0x3864, 0x348b, 0x2d55, 0x1ee9, 0x3dd2, 0x3fe7, 0x3b8d, 0x3359, 0x22f1, + 0x01a1, 0x0342, 0x0684, 0x0d08, 0x1a10, 0x3420, 0x2c03, 0x1c45, 0x388a, 0x3557, 0x2eed, 0x1999, 0x3332, 0x2227, 0x000d, 0x001a, + 0x0034, 0x0068, 0x00d0, 0x01a0, 0x0340, 0x0680, 0x0d00, 0x1a00, 0x3400, 0x2c43, 0x1cc5, 0x398a, 0x3757, 0x2aed, 0x1199, 0x2332, + 0x0227, 0x044e, 0x089c, 0x1138, 0x2270, 0x00a3, 0x0146, 0x028c, 0x0518, 0x0a30, 0x1460, 0x28c0, 0x15c3, 0x2b86, 0x134f, 0x269e, + 0x097f, 0x12fe, 0x25fc, 0x0fbb, 0x1f76, 0x3eec, 0x399b, 0x3775, 0x2aa9, 0x1111, 0x2222, 0x0007, 0x000e, 0x001c, 0x0038, 0x0070, + 0x00e0, 0x01c0, 0x0380, 0x0700, 0x0e00, 0x1c00, 0x3800, 0x3443, 0x2cc5, 0x1dc9, 0x3b92, 0x3367, 0x228d, 0x0159, 0x02b2, 0x0564, + 0x0ac8, 0x1590, 0x2b20, 0x1203, 0x2406, 0x0c4f, 0x189e, 0x313c, 0x263b, 0x0835, 0x106a, 0x20d4, 0x05eb, 0x0bd6, 0x17ac, 0x2f58, + 0x1af3, 0x35e6, 0x2f8f, 0x1b5d, 0x36ba, 0x2937, 0x162d, 0x2c5a, 0x1cf7, 0x39ee, 0x379f, 0x2b7d, 0x12b9, 0x2572, 0x0ea7, 0x1d4e, + 0x3a9c, 0x317b, 0x26b5, 0x0929, 0x1252, 0x24a4, 0x0d0b, 0x1a16, 0x342c, 0x2c1b, 0x1c75, 0x38ea, 0x3597, 0x2f6d, 0x1a99, 0x3532, + 0x2e27, 0x180d, 0x301a, 0x2477, 0x0cad, 0x195a, 0x32b4, 0x212b, 0x0615, 0x0c2a, 0x1854, 0x30a8, 0x2513, 0x0e65, 0x1cca, 0x3994, + 0x376b, 0x2a95, 0x1169, 0x22d2, 0x01e7, 0x03ce, 0x079c, 0x0f38, 0x1e70, 0x3ce0, 0x3d83, 0x3f45, 0x3ac9, 0x31d1, 0x27e1, 0x0b81, + 0x1702, 0x2e04, 0x184b, 0x3096, 0x256f, 0x0e9d, 0x1d3a, 0x3a74, 0x30ab, 0x2515, 0x0e69, 0x1cd2, 0x39a4, 0x370b, 0x2a55, 0x10e9, + 0x21d2, 0x07e7, 0x0fce, 0x1f9c, 0x3f38, 0x3a33, 0x3025, 0x2409, 0x0c51, 0x18a2, 0x3144, 0x26cb, 0x09d5, 0x13aa, 0x2754, 0x0aeb, + 0x15d6, 0x2bac, 0x131b, 0x2636, 0x082f, 0x105e, 0x20bc, 0x053b, 0x0a76, 0x14ec, 0x29d8, 0x17f3, 0x2fe6, 0x1b8f, 0x371e, 0x2a7f, + 0x10bd, 0x217a, 0x06b7, 0x0d6e, 0x1adc, 0x35b8, 0x2f33, 0x1a25, 0x344a, 0x2cd7, 0x1ded, 0x3bda, 0x33f7, 0x23ad, 0x0319, 0x0632, + 0x0c64, 0x18c8, 0x3190, 0x2763, 0x0a85, 0x150a, 0x2a14, 0x106b, 0x20d6, 0x05ef, 0x0bde, 0x17bc, 0x2f78, 0x1ab3, 0x3566, 0x2e8f, + 0x195d, 0x32ba, 0x2137, 0x062d, 0x0c5a, 0x18b4, 0x3168, 0x2693, 0x0965, 0x12ca, 0x2594, 0x0f6b, 0x1ed6, 0x3dac, 0x3f1b, 0x3a75, + 0x30a9, 0x2511, 0x0e61, 0x1cc2, 0x3984, 0x374b, 0x2ad5, 0x11e9, 0x23d2, 0x03e7, 0x07ce, 0x0f9c, 0x1f38, 0x3e70, 0x38a3, 0x3505, + 0x2e49, 0x18d1, 0x31a2, 0x2707, 0x0a4d, 0x149a, 0x2934, 0x162b, 0x2c56, 0x1cef, 0x39de, 0x37ff, 0x2bbd, 0x1339, 0x2672, 0x08a7, + 0x114e, 0x229c, 0x017b, 0x02f6, 0x05ec, 0x0bd8, 0x17b0, 0x2f60, 0x1a83, 0x3506, 0x2e4f, 0x18dd, 0x31ba, 0x2737, 0x0a2d, 0x145a, + 0x28b4, 0x152b, 0x2a56, 0x10ef, 0x21de, 0x07ff, 0x0ffe, 0x1ffc, 0x3ff8, 0x3bb3, 0x3325, 0x2209, 0x0051, 0x00a2, 0x0144, 0x0288, + 0x0510, 0x0a20, 0x1440, 0x2880, 0x1543, 0x2a86, 0x114f, 0x229e, 0x017f, 0x02fe, 0x05fc, 0x0bf8, 0x17f0, 0x2fe0, 0x1b83, 0x3706, + 0x2a4f, 0x10dd, 0x21ba, 0x0737, 0x0e6e, 0x1cdc, 0x39b8, 0x3733, 0x2a25, 0x1009, 0x2012, 0x0467, 0x08ce, 0x119c, 0x2338, 0x0233, + 0x0466, 0x08cc, 0x1198, 0x2330, 0x0223, 0x0446, 0x088c, 0x1118, 0x2230, 0x0023, 0x0046, 0x008c, 0x0118, 0x0230, 0x0460, 0x08c0, + 0x1180, 0x2300, 0x0243, 0x0486, 0x090c, 0x1218, 0x2430, 0x0c23, 0x1846, 0x308c, 0x255b, 0x0ef5, 0x1dea, 0x3bd4, 0x33eb, 0x2395, + 0x0369, 0x06d2, 0x0da4, 0x1b48, 0x3690, 0x2963, 0x1685, 0x2d0a, 0x1e57, 0x3cae, 0x3d1f, 0x3e7d, 0x38b9, 0x3531, 0x2e21, 0x1801, + 0x3002, 0x2447, 0x0ccd, 0x199a, 0x3334, 0x222b, 0x0015, 0x002a, 0x0054, 0x00a8, 0x0150, 0x02a0, 0x0540, 0x0a80, 0x1500, 0x2a00, + 0x1043, 0x2086, 0x054f, 0x0a9e, 0x153c, 0x2a78, 0x10b3, 0x2166, 0x068f, 0x0d1e, 0x1a3c, 0x3478, 0x2cb3, 0x1d25, 0x3a4a, 0x30d7, + 0x25ed, 0x0f99, 0x1f32, 0x3e64, 0x388b, 0x3555, 0x2ee9, 0x1991, 0x3322, 0x2207, 0x004d, 0x009a, 0x0134, 0x0268, 0x04d0, 0x09a0, + 0x1340, 0x2680, 0x0943, 0x1286, 0x250c, 0x0e5b, 0x1cb6, 0x396c, 0x369b, 0x2975, 0x16a9, 0x2d52, 0x1ee7, 0x3dce, 0x3fdf, 0x3bfd, + 0x33b9, 0x2331, 0x0221, 0x0442, 0x0884, 0x1108, 0x2210, 0x0063, 0x00c6, 0x018c, 0x0318, 0x0630, 0x0c60, 0x18c0, 0x3180, 0x2743, + 0x0ac5, 0x158a, 0x2b14, 0x126b, 0x24d6, 0x0def, 0x1bde, 0x37bc, 0x2b3b, 0x1235, 0x246a, 0x0c97, 0x192e, 0x325c, 0x20fb, 0x05b5, + 0x0b6a, 0x16d4, 0x2da8, 0x1f13, 0x3e26, 0x380f, 0x345d, 0x2cf9, 0x1db1, 0x3b62, 0x3287, 0x214d, 0x06d9, 0x0db2, 0x1b64, 0x36c8, + 0x29d3, 0x17e5, 0x2fca, 0x1bd7, 0x37ae, 0x2b1f, 0x127d, 0x24fa, 0x0db7, 0x1b6e, 0x36dc, 0x29fb, 0x17b5, 0x2f6a, 0x1a97, 0x352e, + 0x2e1f, 0x187d, 0x30fa, 0x25b7, 0x0f2d, 0x1e5a, 0x3cb4, 0x3d2b, 0x3e15, 0x3869, 0x3491, 0x2d61, 0x1e81, 0x3d02, 0x3e47, 0x38cd, + 0x35d9, 0x2ff1, 0x1ba1, 0x3742, 0x2ac7, 0x11cd, 0x239a, 0x0377, 0x06ee, 0x0ddc, 0x1bb8, 0x3770, 0x2aa3, 0x1105, 0x220a, 0x0057, + 0x00ae, 0x015c, 0x02b8, 0x0570, 0x0ae0, 0x15c0, 0x2b80, 0x1343, 0x2686, 0x094f, 0x129e, 0x253c, 0x0e3b, 0x1c76, 0x38ec, 0x359b, + 0x2f75, 0x1aa9, 0x3552, 0x2ee7, 0x198d, 0x331a, 0x2277, 0x00ad, 0x015a, 0x02b4, 0x0568, 0x0ad0, 0x15a0, 0x2b40, 0x12c3, 0x2586, + 0x0f4f, 0x1e9e, 0x3d3c, 0x3e3b, 0x3835, 0x3429, 0x2c11, 0x1c61, 0x38c2, 0x35c7, 0x2fcd, 0x1bd9, 0x37b2, 0x2b27, 0x120d, 0x241a, + 0x0c77, 0x18ee, 0x31dc, 0x27fb, 0x0bb5, 0x176a, 0x2ed4, 0x19eb, 0x33d6, 0x23ef, 0x039d, 0x073a, 0x0e74, 0x1ce8, 0x39d0, 0x37e3, + 0x2b85, 0x1349, 0x2692, 0x0967, 0x12ce, 0x259c, 0x0f7b, 0x1ef6, 0x3dec, 0x3f9b, 0x3b75, 0x32a9, 0x2111, 0x0661, 0x0cc2, 0x1984, + 0x3308, 0x2253, 0x00e5, 0x01ca, 0x0394, 0x0728, 0x0e50, 0x1ca0, 0x3940, 0x36c3, 0x29c5, 0x17c9, 0x2f92, 0x1b67, 0x36ce, 0x29df, + 0x17fd, 0x2ffa, 0x1bb7, 0x376e, 0x2a9f, 0x117d, 0x22fa, 0x01b7, 0x036e, 0x06dc, 0x0db8, 0x1b70, 0x36e0, 0x2983, 0x1745, 0x2e8a, + 0x1957, 0x32ae, 0x211f, 0x067d, 0x0cfa, 0x19f4, 0x33e8, 0x2393, 0x0365, 0x06ca, 0x0d94, 0x1b28, 0x3650, 0x28e3, 0x1585, 0x2b0a, + 0x1257, 0x24ae, 0x0d1f, 0x1a3e, 0x347c, 0x2cbb, 0x1d35, 0x3a6a, 0x3097, 0x256d, 0x0e99, 0x1d32, 0x3a64, 0x308b, 0x2555, 0x0ee9, + 0x1dd2, 0x3ba4, 0x330b, 0x2255, 0x00e9, 0x01d2, 0x03a4, 0x0748, 0x0e90, 0x1d20, 0x3a40, 0x30c3, 0x25c5, 0x0fc9, 0x1f92, 0x3f24, + 0x3a0b, 0x3055, 0x24e9, 0x0d91, 0x1b22, 0x3644, 0x28cb, 0x15d5, 0x2baa, 0x1317, 0x262e, 0x081f, 0x103e, 0x207c, 0x04bb, 0x0976, + 0x12ec, 0x25d8, 0x0ff3, 0x1fe6, 0x3fcc, 0x3bdb, 0x33f5, 0x23a9, 0x0311, 0x0622, 0x0c44, 0x1888, 0x3110, 0x2663, 0x0885, 0x110a, + 0x2214, 0x006b, 0x00d6, 0x01ac, 0x0358, 0x06b0, 0x0d60, 0x1ac0, 0x3580, 0x2f43, 0x1ac5, 0x358a, 0x2f57, 0x1aed, 0x35da, 0x2ff7, + 0x1bad, 0x375a, 0x2af7, 0x11ad, 0x235a, 0x02f7, 0x05ee, 0x0bdc, 0x17b8, 0x2f70, 0x1aa3, 0x3546, 0x2ecf, 0x19dd, 0x33ba, 0x2337, + 0x022d, 0x045a, 0x08b4, 0x1168, 0x22d0, 0x01e3, 0x03c6, 0x078c, 0x0f18, 0x1e30, 0x3c60, 0x3c83, 0x3d45, 0x3ec9, 0x39d1, 0x37e1, + 0x2b81, 0x1341, 0x2682, 0x0947, 0x128e, 0x251c, 0x0e7b, 0x1cf6, 0x39ec, 0x379b, 0x2b75, 0x12a9, 0x2552, 0x0ee7, 0x1dce, 0x3b9c, + 0x337b, 0x22b5, 0x0129, 0x0252, 0x04a4, 0x0948, 0x1290, 0x2520, 0x0e03, 0x1c06, 0x380c, 0x345b, 0x2cf5, 0x1da9, 0x3b52, 0x32e7, + 0x218d, 0x0759, 0x0eb2, 0x1d64, 0x3ac8, 0x31d3, 0x27e5, 0x0b89, 0x1712, 0x2e24, 0x180b, 0x3016, 0x246f, 0x0c9d, 0x193a, 0x3274, + 0x20ab, 0x0515, 0x0a2a, 0x1454, 0x28a8, 0x1513, 0x2a26, 0x100f, 0x201e, 0x047f, 0x08fe, 0x11fc, 0x23f8, 0x03b3, 0x0766, 0x0ecc, + 0x1d98, 0x3b30, 0x3223, 0x2005, 0x0449, 0x0892, 0x1124, 0x2248, 0x00d3, 0x01a6, 0x034c, 0x0698, 0x0d30, 0x1a60, 0x34c0, 0x2dc3, + 0x1fc5, 0x3f8a, 0x3b57, 0x32ed, 0x2199, 0x0771, 0x0ee2, 0x1dc4, 0x3b88, 0x3353, 0x22e5, 0x0189, 0x0312, 0x0624, 0x0c48, 0x1890, + 0x3120, 0x2603, 0x0845, 0x108a, 0x2114, 0x066b, 0x0cd6, 0x19ac, 0x3358, 0x22f3, 0x01a5, 0x034a, 0x0694, 0x0d28, 0x1a50, 0x34a0, + 0x2d03, 0x1e45, 0x3c8a, 0x3d57, 0x3eed, 0x3999, 0x3771, 0x2aa1, 0x1101, 0x2202, 0x0047, 0x008e, 0x011c, 0x0238, 0x0470, 0x08e0, + 0x11c0, 0x2380, 0x0343, 0x0686, 0x0d0c, 0x1a18, 0x3430, 0x2c23, 0x1c05, 0x380a, 0x3457, 0x2ced, 0x1d99, 0x3b32, 0x3227, 0x200d, + 0x0459, 0x08b2, 0x1164, 0x22c8, 0x01d3, 0x03a6, 0x074c, 0x0e98, 0x1d30, 0x3a60, 0x3083, 0x2545, 0x0ec9, 0x1d92, 0x3b24, 0x320b, + 0x2055, 0x04e9, 0x09d2, 0x13a4, 0x2748, 0x0ad3, 0x15a6, 0x2b4c, 0x12db, 0x25b6, 0x0f2f, 0x1e5e, 0x3cbc, 0x3d3b, 0x3e35, 0x3829, + 0x3411, 0x2c61, 0x1c81, 0x3902, 0x3647, 0x28cd, 0x15d9, 0x2bb2, 0x1327, 0x264e, 0x08df, 0x11be, 0x237c, 0x02bb, 0x0576, 0x0aec, + 0x15d8, 0x2bb0, 0x1323, 0x2646, 0x08cf, 0x119e, 0x233c, 0x023b, 0x0476, 0x08ec, 0x11d8, 0x23b0, 0x0323, 0x0646, 0x0c8c, 0x1918, + 0x3230, 0x2023, 0x0405, 0x080a, 0x1014, 0x2028, 0x0413, 0x0826, 0x104c, 0x2098, 0x0573, 0x0ae6, 0x15cc, 0x2b98, 0x1373, 0x26e6, + 0x098f, 0x131e, 0x263c, 0x083b, 0x1076, 0x20ec, 0x059b, 0x0b36, 0x166c, 0x2cd8, 0x1df3, 0x3be6, 0x338f, 0x235d, 0x02f9, 0x05f2, + 0x0be4, 0x17c8, 0x2f90, 0x1b63, 0x36c6, 0x29cf, 0x17dd, 0x2fba, 0x1b37, 0x366e, 0x289f, 0x157d, 0x2afa, 0x11b7, 0x236e, 0x029f, + 0x053e, 0x0a7c, 0x14f8, 0x29f0, 0x17a3, 0x2f46, 0x1acf, 0x359e, 0x2f7f, 0x1abd, 0x357a, 0x2eb7, 0x192d, 0x325a, 0x20f7, 0x05ad, + 0x0b5a, 0x16b4, 0x2d68, 0x1e93, 0x3d26, 0x3e0f, 0x385d, 0x34f9, 0x2db1, 0x1f21, 0x3e42, 0x38c7, 0x35cd, 0x2fd9, 0x1bf1, 0x37e2, + 0x2b87, 0x134d, 0x269a, 0x0977, 0x12ee, 0x25dc, 0x0ffb, 0x1ff6, 0x3fec, 0x3b9b, 0x3375, 0x22a9, 0x0111, 0x0222, 0x0444, 0x0888, + 0x1110, 0x2220, 0x0003, 0x0006, 0x000c, 0x0018, 0x0030, 0x0060, 0x00c0, 0x0180, 0x0300, 0x0600, 0x0c00, 0x1800, 0x3000, 0x2443, + 0x0cc5, 0x198a, 0x3314, 0x226b, 0x0095, 0x012a, 0x0254, 0x04a8, 0x0950, 0x12a0, 0x2540, 0x0ec3, 0x1d86, 0x3b0c, 0x325b, 0x20f5, + 0x05a9, 0x0b52, 0x16a4, 0x2d48, 0x1ed3, 0x3da6, 0x3f0f, 0x3a5d, 0x30f9, 0x25b1, 0x0f21, 0x1e42, 0x3c84, 0x3d4b, 0x3ed5, 0x39e9, + 0x3791, 0x2b61, 0x1281, 0x2502, 0x0e47, 0x1c8e, 0x391c, 0x367b, 0x28b5, 0x1529, 0x2a52, 0x10e7, 0x21ce, 0x07df, 0x0fbe, 0x1f7c, + 0x3ef8, 0x39b3, 0x3725, 0x2a09, 0x1051, 0x20a2, 0x0507, 0x0a0e, 0x141c, 0x2838, 0x1433, 0x2866, 0x148f, 0x291e, 0x167f, 0x2cfe, + 0x1dbf, 0x3b7e, 0x32bf, 0x213d, 0x0639, 0x0c72, 0x18e4, 0x31c8, 0x27d3, 0x0be5, 0x17ca, 0x2f94, 0x1b6b, 0x36d6, 0x29ef, 0x179d, + 0x2f3a, 0x1a37, 0x346e, 0x2c9f, 0x1d7d, 0x3afa, 0x31b7, 0x272d, 0x0a19, 0x1432, 0x2864, 0x148b, 0x2916, 0x166f, 0x2cde, 0x1dff, + 0x3bfe, 0x33bf, 0x233d, 0x0239, 0x0472, 0x08e4, 0x11c8, 0x2390, 0x0363, 0x06c6, 0x0d8c, 0x1b18, 0x3630, 0x2823, 0x1405, 0x280a, + 0x1457, 0x28ae, 0x151f, 0x2a3e, 0x103f, 0x207e, 0x04bf, 0x097e, 0x12fc, 0x25f8, 0x0fb3, 0x1f66, 0x3ecc, 0x39db, 0x37f5, 0x2ba9, + 0x1311, 0x2622, 0x0807, 0x100e, 0x201c, 0x047b, 0x08f6, 0x11ec, 0x23d8, 0x03f3, 0x07e6, 0x0fcc, 0x1f98, 0x3f30, 0x3a23, 0x3005, + 0x2449, 0x0cd1, 0x19a2, 0x3344, 0x22cb, 0x01d5, 0x03aa, 0x0754, 0x0ea8, 0x1d50, 0x3aa0, 0x3103, 0x2645, 0x08c9, 0x1192, 0x2324, + 0x020b, 0x0416, 0x082c, 0x1058, 0x20b0, 0x0523, 0x0a46, 0x148c, 0x2918, 0x1673, 0x2ce6, 0x1d8f, 0x3b1e, 0x327f, 0x20bd, 0x0539, + 0x0a72, 0x14e4, 0x29c8, 0x17d3, 0x2fa6, 0x1b0f, 0x361e, 0x287f, 0x14bd, 0x297a, 0x16b7, 0x2d6e, 0x1e9f, 0x3d3e, 0x3e3f, 0x383d, + 0x3439, 0x2c31, 0x1c21, 0x3842, 0x34c7, 0x2dcd, 0x1fd9, 0x3fb2, 0x3b27, 0x320d, 0x2059, 0x04f1, 0x09e2, 0x13c4, 0x2788, 0x0b53, + 0x16a6, 0x2d4c, 0x1edb, 0x3db6, 0x3f2f, 0x3a1d, 0x3079, 0x24b1, 0x0d21, 0x1a42, 0x3484, 0x2d4b, 0x1ed5, 0x3daa, 0x3f17, 0x3a6d, + 0x3099, 0x2571, 0x0ea1, 0x1d42, 0x3a84, 0x314b, 0x26d5, 0x09e9, 0x13d2, 0x27a4, 0x0b0b, 0x1616, 0x2c2c, 0x1c1b, 0x3836, 0x342f, + 0x2c1d, 0x1c79, 0x38f2, 0x35a7, 0x2f0d, 0x1a59, 0x34b2, 0x2d27, 0x1e0d, 0x3c1a, 0x3c77, 0x3cad, 0x3d19, 0x3e71, 0x38a1, 0x3501, + 0x2e41, 0x18c1, 0x3182, 0x2747, 0x0acd, 0x159a, 0x2b34, 0x122b, 0x2456, 0x0cef, 0x19de, 0x33bc, 0x233b, 0x0235, 0x046a, 0x08d4, + 0x11a8, 0x2350, 0x02e3, 0x05c6, 0x0b8c, 0x1718, 0x2e30, 0x1823, 0x3046, 0x24cf, 0x0ddd, 0x1bba, 0x3774, 0x2aab, 0x1115, 0x222a, + 0x0017, 0x002e, 0x005c, 0x00b8, 0x0170, 0x02e0, 0x05c0, 0x0b80, 0x1700, 0x2e00, 0x1843, 0x3086, 0x254f, 0x0edd, 0x1dba, 0x3b74, + 0x32ab, 0x2115, 0x0669, 0x0cd2, 0x19a4, 0x3348, 0x22d3, 0x01e5, 0x03ca, 0x0794, 0x0f28, 0x1e50, 0x3ca0, 0x3d03, 0x3e45, 0x38c9, + 0x35d1, 0x2fe1, 0x1b81, 0x3702, 0x2a47, 0x10cd, 0x219a, 0x0777, 0x0eee, 0x1ddc, 0x3bb8, 0x3333, 0x2225, 0x0009, 0x0012, 0x0024, + 0x0048, 0x0090, 0x0120, 0x0240, 0x0480, 0x0900, 0x1200, 0x2400, 0x0c43, 0x1886, 0x310c, 0x265b, 0x08f5, 0x11ea, 0x23d4, 0x03eb, + 0x07d6, 0x0fac, 0x1f58, 0x3eb0, 0x3923, 0x3605, 0x2849, 0x14d1, 0x29a2, 0x1707, 0x2e0e, 0x185f, 0x30be, 0x253f, 0x0e3d, 0x1c7a, + 0x38f4, 0x35ab, 0x2f15, 0x1a69, 0x34d2, 0x2de7, 0x1f8d, 0x3f1a, 0x3a77, 0x30ad, 0x2519, 0x0e71, 0x1ce2, 0x39c4, 0x37cb, 0x2bd5, + 0x13e9, 0x27d2, 0x0be7, 0x17ce, 0x2f9c, 0x1b7b, 0x36f6, 0x29af, 0x171d, 0x2e3a, 0x1837, 0x306e, 0x249f, 0x0d7d, 0x1afa, 0x35f4, + 0x2fab, 0x1b15, 0x362a, 0x2817, 0x146d, 0x28da, 0x15f7, 0x2bee, 0x139f, 0x273e, 0x0a3f, 0x147e, 0x28fc, 0x15bb, 0x2b76, 0x12af, + 0x255e, 0x0eff, 0x1dfe, 0x3bfc, 0x33bb, 0x2335, 0x0229, 0x0452, 0x08a4, 0x1148, 0x2290, 0x0163, 0x02c6, 0x058c, 0x0b18, 0x1630, + 0x2c60, 0x1c83, 0x3906, 0x364f, 0x28dd, 0x15f9, 0x2bf2, 0x13a7, 0x274e, 0x0adf, 0x15be, 0x2b7c, 0x12bb, 0x2576, 0x0eaf, 0x1d5e, + 0x3abc, 0x313b, 0x2635, 0x0829, 0x1052, 0x20a4, 0x050b, 0x0a16, 0x142c, 0x2858, 0x14f3, 0x29e6, 0x178f, 0x2f1e, 0x1a7f, 0x34fe, + 0x2dbf, 0x1f3d, 0x3e7a, 0x38b7, 0x352d, 0x2e19, 0x1871, 0x30e2, 0x2587, 0x0f4d, 0x1e9a, 0x3d34, 0x3e2b, 0x3815, 0x3469, 0x2c91, + 0x1d61, 0x3ac2, 0x31c7, 0x27cd, 0x0bd9, 0x17b2, 0x2f64, 0x1a8b, 0x3516, 0x2e6f, 0x189d, 0x313a, 0x2637, 0x082d, 0x105a, 0x20b4, + 0x052b, 0x0a56, 0x14ac, 0x2958, 0x16f3, 0x2de6, 0x1f8f, 0x3f1e, 0x3a7f, 0x30bd, 0x2539, 0x0e31, 0x1c62, 0x38c4, 0x35cb, 0x2fd5, + 0x1be9, 0x37d2, 0x2be7, 0x138d, 0x271a, 0x0a77, 0x14ee, 0x29dc, 0x17fb, 0x2ff6, 0x1baf, 0x375e, 0x2aff, 0x11bd, 0x237a, 0x02b7, + 0x056e, 0x0adc, 0x15b8, 0x2b70, 0x12a3, 0x2546, 0x0ecf, 0x1d9e, 0x3b3c, 0x323b, 0x2035, 0x0429, 0x0852, 0x10a4, 0x2148, 0x06d3, + 0x0da6, 0x1b4c, 0x3698, 0x2973, 0x16a5, 0x2d4a, 0x1ed7, 0x3dae, 0x3f1f, 0x3a7d, 0x30b9, 0x2531, 0x0e21, 0x1c42, 0x3884, 0x354b, + 0x2ed5, 0x19e9, 0x33d2, 0x23e7, 0x038d, 0x071a, 0x0e34, 0x1c68, 0x38d0, 0x35e3, 0x2f85, 0x1b49, 0x3692, 0x2967, 0x168d, 0x2d1a, + 0x1e77, 0x3cee, 0x3d9f, 0x3f7d, 0x3ab9, 0x3131, 0x2621, 0x0801, 0x1002, 0x2004, 0x044b, 0x0896, 0x112c, 0x2258, 0x00f3, 0x01e6, + 0x03cc, 0x0798, 0x0f30, 0x1e60, 0x3cc0, 0x3dc3, 0x3fc5, 0x3bc9, 0x33d1, 0x23e1, 0x0381, 0x0702, 0x0e04, 0x1c08, 0x3810, 0x3463, + 0x2c85, 0x1d49, 0x3a92, 0x3167, 0x268d, 0x0959, 0x12b2, 0x2564, 0x0e8b, 0x1d16, 0x3a2c, 0x301b, 0x2475, 0x0ca9, 0x1952, 0x32a4, + 0x210b, 0x0655, 0x0caa, 0x1954, 0x32a8, 0x2113, 0x0665, 0x0cca, 0x1994, 0x3328, 0x2213, 0x0065, 0x00ca, 0x0194, 0x0328, 0x0650, + 0x0ca0, 0x1940, 0x3280, 0x2143, 0x06c5, 0x0d8a, 0x1b14, 0x3628, 0x2813, 0x1465, 0x28ca, 0x15d7, 0x2bae, 0x131f, 0x263e, 0x083f, + 0x107e, 0x20fc, 0x05bb, 0x0b76, 0x16ec, 0x2dd8, 0x1ff3, 0x3fe6, 0x3b8f, 0x335d, 0x22f9, 0x01b1, 0x0362, 0x06c4, 0x0d88, 0x1b10, + 0x3620, 0x2803, 0x1445, 0x288a, 0x1557, 0x2aae, 0x111f, 0x223e, 0x003f, 0x007e, 0x00fc, 0x01f8, 0x03f0, 0x07e0, 0x0fc0, 0x1f80, + 0x3f00, 0x3a43, 0x30c5, 0x25c9, 0x0fd1, 0x1fa2, 0x3f44, 0x3acb, 0x31d5, 0x27e9, 0x0b91, 0x1722, 0x2e44, 0x18cb, 0x3196, 0x276f, + 0x0a9d, 0x153a, 0x2a74, 0x10ab, 0x2156, 0x06ef, 0x0dde, 0x1bbc, 0x3778, 0x2ab3, 0x1125, 0x224a, 0x00d7, 0x01ae, 0x035c, 0x06b8, + 0x0d70, 0x1ae0, 0x35c0, 0x2fc3, 0x1bc5, 0x378a, 0x2b57, 0x12ed, 0x25da, 0x0ff7, 0x1fee, 0x3fdc, 0x3bfb, 0x33b5, 0x2329, 0x0211, + 0x0422, 0x0844, 0x1088, 0x2110, 0x0663, 0x0cc6, 0x198c, 0x3318, 0x2273, 0x00a5, 0x014a, 0x0294, 0x0528, 0x0a50, 0x14a0, 0x2940, + 0x16c3, 0x2d86, 0x1f4f, 0x3e9e, 0x397f, 0x36bd, 0x2939, 0x1631, 0x2c62, 0x1c87, 0x390e, 0x365f, 0x28fd, 0x15b9, 0x2b72, 0x12a7, + 0x254e, 0x0edf, 0x1dbe, 0x3b7c, 0x32bb, 0x2135, 0x0629, 0x0c52, 0x18a4, 0x3148, 0x26d3, 0x09e5, 0x13ca, 0x2794, 0x0b6b, 0x16d6, + 0x2dac, 0x1f1b, 0x3e36, 0x382f, 0x341d, 0x2c79, 0x1cb1, 0x3962, 0x3687, 0x294d, 0x16d9, 0x2db2, 0x1f27, 0x3e4e, 0x38df, 0x35fd, + 0x2fb9, 0x1b31, 0x3662, 0x2887, 0x154d, 0x2a9a, 0x1177, 0x22ee, 0x019f, 0x033e, 0x067c, 0x0cf8, 0x19f0, 0x33e0, 0x2383, 0x0345, + 0x068a, 0x0d14, 0x1a28, 0x3450, 0x2ce3, 0x1d85, 0x3b0a, 0x3257, 0x20ed, 0x0599, 0x0b32, 0x1664, 0x2cc8, 0x1dd3, 0x3ba6, 0x330f, + 0x225d, 0x00f9, 0x01f2, 0x03e4, 0x07c8, 0x0f90, 0x1f20, 0x3e40, 0x38c3, 0x35c5, 0x2fc9, 0x1bd1, 0x37a2, 0x2b07, 0x124d, 0x249a, + 0x0d77, 0x1aee, 0x35dc, 0x2ffb, 0x1bb5, 0x376a, 0x2a97, 0x116d, 0x22da, 0x01f7, 0x03ee, 0x07dc, 0x0fb8, 0x1f70, 0x3ee0, 0x3983, + 0x3745, 0x2ac9, 0x11d1, 0x23a2, 0x0307, 0x060e, 0x0c1c, 0x1838, 0x3070, 0x24a3, 0x0d05, 0x1a0a, 0x3414, 0x2c6b, 0x1c95, 0x392a, + 0x3617, 0x286d, 0x1499, 0x2932, 0x1627, 0x2c4e, 0x1cdf, 0x39be, 0x373f, 0x2a3d, 0x1039, 0x2072, 0x04a7, 0x094e, 0x129c, 0x2538, + 0x0e33, 0x1c66, 0x38cc, 0x35db, 0x2ff5, 0x1ba9, 0x3752, 0x2ae7, 0x118d, 0x231a, 0x0277, 0x04ee, 0x09dc, 0x13b8, 0x2770, 0x0aa3, + 0x1546, 0x2a8c, 0x115b, 0x22b6, 0x012f, 0x025e, 0x04bc, 0x0978, 0x12f0, 0x25e0, 0x0f83, 0x1f06, 0x3e0c, 0x385b, 0x34f5, 0x2da9, + 0x1f11, 0x3e22, 0x3807, 0x344d, 0x2cd9, 0x1df1, 0x3be2, 0x3387, 0x234d, 0x02d9, 0x05b2, 0x0b64, 0x16c8, 0x2d90, 0x1f63, 0x3ec6, + 0x39cf, 0x37dd, 0x2bf9, 0x13b1, 0x2762, 0x0a87, 0x150e, 0x2a1c, 0x107b, 0x20f6, 0x05af, 0x0b5e, 0x16bc, 0x2d78, 0x1eb3, 0x3d66, + 0x3e8f, 0x395d, 0x36f9, 0x29b1, 0x1721, 0x2e42, 0x18c7, 0x318e, 0x275f, 0x0afd, 0x15fa, 0x2bf4, 0x13ab, 0x2756, 0x0aef, 0x15de, + 0x2bbc, 0x133b, 0x2676, 0x08af, 0x115e, 0x22bc, 0x013b, 0x0276, 0x04ec, 0x09d8, 0x13b0, 0x2760, 0x0a83, 0x1506, 0x2a0c, 0x105b, + 0x20b6, 0x052f, 0x0a5e, 0x14bc, 0x2978, 0x16b3, 0x2d66, 0x1e8f, 0x3d1e, 0x3e7f, 0x38bd, 0x3539, 0x2e31, 0x1821, 0x3042, 0x24c7, + 0x0dcd, 0x1b9a, 0x3734, 0x2a2b, 0x1015, 0x202a, 0x0417, 0x082e, 0x105c, 0x20b8, 0x0533, 0x0a66, 0x14cc, 0x2998, 0x1773, 0x2ee6, + 0x198f, 0x331e, 0x227f, 0x00bd, 0x017a, 0x02f4, 0x05e8, 0x0bd0, 0x17a0, 0x2f40, 0x1ac3, 0x3586, 0x2f4f, 0x1add, 0x35ba, 0x2f37, + 0x1a2d, 0x345a, 0x2cf7, 0x1dad, 0x3b5a, 0x32f7, 0x21ad, 0x0719, 0x0e32, 0x1c64, 0x38c8, 0x35d3, 0x2fe5, 0x1b89, 0x3712, 0x2a67, + 0x108d, 0x211a, 0x0677, 0x0cee, 0x19dc, 0x33b8, 0x2333, 0x0225, 0x044a, 0x0894, 0x1128, 0x2250, 0x00e3, 0x01c6, 0x038c, 0x0718, + 0x0e30, 0x1c60, 0x38c0, 0x35c3, 0x2fc5, 0x1bc9, 0x3792, 0x2b67, 0x128d, 0x251a, 0x0e77, 0x1cee, 0x39dc, 0x37fb, 0x2bb5, 0x1329, + 0x2652, 0x08e7, 0x11ce, 0x239c, 0x037b, 0x06f6, 0x0dec, 0x1bd8, 0x37b0, 0x2b23, 0x1205, 0x240a, 0x0c57, 0x18ae, 0x315c, 0x26fb, + 0x09b5, 0x136a, 0x26d4, 0x09eb, 0x13d6, 0x27ac, 0x0b1b, 0x1636, 0x2c6c, 0x1c9b, 0x3936, 0x362f, 0x281d, 0x1479, 0x28f2, 0x15a7, + 0x2b4e, 0x12df, 0x25be, 0x0f3f, 0x1e7e, 0x3cfc, 0x3dbb, 0x3f35, 0x3a29, 0x3011, 0x2461, 0x0c81, 0x1902, 0x3204, 0x204b, 0x04d5, + 0x09aa, 0x1354, 0x26a8, 0x0913, 0x1226, 0x244c, 0x0cdb, 0x19b6, 0x336c, 0x229b, 0x0175, 0x02ea, 0x05d4, 0x0ba8, 0x1750, 0x2ea0, + 0x1903, 0x3206, 0x204f, 0x04dd, 0x09ba, 0x1374, 0x26e8, 0x0993, 0x1326, 0x264c, 0x08db, 0x11b6, 0x236c, 0x029b, 0x0536, 0x0a6c, + 0x14d8, 0x29b0, 0x1723, 0x2e46, 0x18cf, 0x319e, 0x277f, 0x0abd, 0x157a, 0x2af4, 0x11ab, 0x2356, 0x02ef, 0x05de, 0x0bbc, 0x1778, + 0x2ef0, 0x19a3, 0x3346, 0x22cf, 0x01dd, 0x03ba, 0x0774, 0x0ee8, 0x1dd0, 0x3ba0, 0x3303, 0x2245, 0x00c9, 0x0192, 0x0324, 0x0648, + 0x0c90, 0x1920, 0x3240, 0x20c3, 0x05c5, 0x0b8a, 0x1714, 0x2e28, 0x1813, 0x3026, 0x240f, 0x0c5d, 0x18ba, 0x3174, 0x26ab, 0x0915, + 0x122a, 0x2454, 0x0ceb, 0x19d6, 0x33ac, 0x231b, 0x0275, 0x04ea, 0x09d4, 0x13a8, 0x2750, 0x0ae3, 0x15c6, 0x2b8c, 0x135b, 0x26b6, + 0x092f, 0x125e, 0x24bc, 0x0d3b, 0x1a76, 0x34ec, 0x2d9b, 0x1f75, 0x3eea, 0x3997, 0x376d, 0x2a99, 0x1171, 0x22e2, 0x0187, 0x030e, + 0x061c, 0x0c38, 0x1870, 0x30e0, 0x2583, 0x0f45, 0x1e8a, 0x3d14, 0x3e6b, 0x3895, 0x3569, 0x2e91, 0x1961, 0x32c2, 0x21c7, 0x07cd, + 0x0f9a, 0x1f34, 0x3e68, 0x3893, 0x3565, 0x2e89, 0x1951, 0x32a2, 0x2107, 0x064d, 0x0c9a, 0x1934, 0x3268, 0x2093, 0x0565, 0x0aca, + 0x1594, 0x2b28, 0x1213, 0x2426, 0x0c0f, 0x181e, 0x303c, 0x243b, 0x0c35, 0x186a, 0x30d4, 0x25eb, 0x0f95, 0x1f2a, 0x3e54, 0x38eb, + 0x3595, 0x2f69, 0x1a91, 0x3522, 0x2e07, 0x184d, 0x309a, 0x2577, 0x0ead, 0x1d5a, 0x3ab4, 0x312b, 0x2615, 0x0869, 0x10d2, 0x21a4, + 0x070b, 0x0e16, 0x1c2c, 0x3858, 0x34f3, 0x2da5, 0x1f09, 0x3e12, 0x3867, 0x348d, 0x2d59, 0x1ef1, 0x3de2, 0x3f87, 0x3b4d, 0x32d9, + 0x21f1, 0x07a1, 0x0f42, 0x1e84, 0x3d08, 0x3e53, 0x38e5, 0x3589, 0x2f51, 0x1ae1, 0x35c2, 0x2fc7, 0x1bcd, 0x379a, 0x2b77, 0x12ad, + 0x255a, 0x0ef7, 0x1dee, 0x3bdc, 0x33fb, 0x23b5, 0x0329, 0x0652, 0x0ca4, 0x1948, 0x3290, 0x2163, 0x0685, 0x0d0a, 0x1a14, 0x3428, + 0x2c13, 0x1c65, 0x38ca, 0x35d7, 0x2fed, 0x1b99, 0x3732, 0x2a27, 0x100d, 0x201a, 0x0477, 0x08ee, 0x11dc, 0x23b8, 0x0333, 0x0666, + 0x0ccc, 0x1998, 0x3330, 0x2223, 0x0005, 0x000a, 0x0014, 0x0028, 0x0050, 0x00a0, 0x0140, 0x0280, 0x0500, 0x0a00, 0x1400, 0x2800, + 0x1443, 0x2886, 0x154f, 0x2a9e, 0x117f, 0x22fe, 0x01bf, 0x037e, 0x06fc, 0x0df8, 0x1bf0, 0x37e0, 0x2b83, 0x1345, 0x268a, 0x0957, + 0x12ae, 0x255c, 0x0efb, 0x1df6, 0x3bec, 0x339b, 0x2375, 0x02a9, 0x0552, 0x0aa4, 0x1548, 0x2a90, 0x1163, 0x22c6, 0x01cf, 0x039e, + 0x073c, 0x0e78, 0x1cf0, 0x39e0, 0x3783, 0x2b45, 0x12c9, 0x2592, 0x0f67, 0x1ece, 0x3d9c, 0x3f7b, 0x3ab5, 0x3129, 0x2611, 0x0861, + 0x10c2, 0x2184, 0x074b, 0x0e96, 0x1d2c, 0x3a58, 0x30f3, 0x25a5, 0x0f09, 0x1e12, 0x3c24, 0x3c0b, 0x3c55, 0x3ce9, 0x3d91, 0x3f61, + 0x3a81, 0x3141, 0x26c1, 0x09c1, 0x1382, 0x2704, 0x0a4b, 0x1496, 0x292c, 0x161b, 0x2c36, 0x1c2f, 0x385e, 0x34ff, 0x2dbd, 0x1f39, + 0x3e72, 0x38a7, 0x350d, 0x2e59, 0x18f1, 0x31e2, 0x2787, 0x0b4d, 0x169a, 0x2d34, 0x1e2b, 0x3c56, 0x3cef, 0x3d9d, 0x3f79, 0x3ab1, + 0x3121, 0x2601, 0x0841, 0x1082, 0x2104, 0x064b, 0x0c96, 0x192c, 0x3258, 0x20f3, 0x05a5, 0x0b4a, 0x1694, 0x2d28, 0x1e13, 0x3c26, + 0x3c0f, 0x3c5d, 0x3cf9, 0x3db1, 0x3f21, 0x3a01, 0x3041, 0x24c1, 0x0dc1, 0x1b82, 0x3704, 0x2a4b, 0x10d5, 0x21aa, 0x0717, 0x0e2e, + 0x1c5c, 0x38b8, 0x3533, 0x2e25, 0x1809, 0x3012, 0x2467, 0x0c8d, 0x191a, 0x3234, 0x202b, 0x0415, 0x082a, 0x1054, 0x20a8, 0x0513, + 0x0a26, 0x144c, 0x2898, 0x1573, 0x2ae6, 0x118f, 0x231e, 0x027f, 0x04fe, 0x09fc, 0x13f8, 0x27f0, 0x0ba3, 0x1746, 0x2e8c, 0x195b, + 0x32b6, 0x212f, 0x061d, 0x0c3a, 0x1874, 0x30e8, 0x2593, 0x0f65, 0x1eca, 0x3d94, 0x3f6b, 0x3a95, 0x3169, 0x2691, 0x0961, 0x12c2, + 0x2584, 0x0f4b, 0x1e96, 0x3d2c, 0x3e1b, 0x3875, 0x34a9, 0x2d11, 0x1e61, 0x3cc2, 0x3dc7, 0x3fcd, 0x3bd9, 0x33f1, 0x23a1, 0x0301, + 0x0602, 0x0c04, 0x1808, 0x3010, 0x2463, 0x0c85, 0x190a, 0x3214, 0x206b, 0x0495, 0x092a, 0x1254, 0x24a8, 0x0d13, 0x1a26, 0x344c, + 0x2cdb, 0x1df5, 0x3bea, 0x3397, 0x236d, 0x0299, 0x0532, 0x0a64, 0x14c8, 0x2990, 0x1763, 0x2ec6, 0x19cf, 0x339e, 0x237f, 0x02bd, + 0x057a, 0x0af4, 0x15e8, 0x2bd0, 0x13e3, 0x27c6, 0x0bcf, 0x179e, 0x2f3c, 0x1a3b, 0x3476, 0x2caf, 0x1d1d, 0x3a3a, 0x3037, 0x242d, + 0x0c19, 0x1832, 0x3064, 0x248b, 0x0d55, 0x1aaa, 0x3554, 0x2eeb, 0x1995, 0x332a, 0x2217, 0x006d, 0x00da, 0x01b4, 0x0368, 0x06d0, + 0x0da0, 0x1b40, 0x3680, 0x2943, 0x16c5, 0x2d8a, 0x1f57, 0x3eae, 0x391f, 0x367d, 0x28b9, 0x1531, 0x2a62, 0x1087, 0x210e, 0x065f, + 0x0cbe, 0x197c, 0x32f8, 0x21b3, 0x0725, 0x0e4a, 0x1c94, 0x3928, 0x3613, 0x2865, 0x1489, 0x2912, 0x1667, 0x2cce, 0x1ddf, 0x3bbe, + 0x333f, 0x223d, 0x0039, 0x0072, 0x00e4, 0x01c8, 0x0390, 0x0720, 0x0e40, 0x1c80, 0x3900, 0x3643, 0x28c5, 0x15c9, 0x2b92, 0x1367, + 0x26ce, 0x09df, 0x13be, 0x277c, 0x0abb, 0x1576, 0x2aec, 0x119b, 0x2336, 0x022f, 0x045e, 0x08bc, 0x1178, 0x22f0, 0x01a3, 0x0346, + 0x068c, 0x0d18, 0x1a30, 0x3460, 0x2c83, 0x1d45, 0x3a8a, 0x3157, 0x26ed, 0x0999, 0x1332, 0x2664, 0x088b, 0x1116, 0x222c, 0x001b, + 0x0036, 0x006c, 0x00d8, 0x01b0, 0x0360, 0x06c0, 0x0d80, 0x1b00, 0x3600, 0x2843, 0x14c5, 0x298a, 0x1757, 0x2eae, 0x191f, 0x323e, + 0x203f, 0x043d, 0x087a, 0x10f4, 0x21e8, 0x0793, 0x0f26, 0x1e4c, 0x3c98, 0x3d73, 0x3ea5, 0x3909, 0x3651, 0x28e1, 0x1581, 0x2b02, + 0x1247, 0x248e, 0x0d5f, 0x1abe, 0x357c, 0x2ebb, 0x1935, 0x326a, 0x2097, 0x056d, 0x0ada, 0x15b4, 0x2b68, 0x1293, 0x2526, 0x0e0f, + 0x1c1e, 0x383c, 0x343b, 0x2c35, 0x1c29, 0x3852, 0x34e7, 0x2d8d, 0x1f59, 0x3eb2, 0x3927, 0x360d, 0x2859, 0x14f1, 0x29e2, 0x1787, + 0x2f0e, 0x1a5f, 0x34be, 0x2d3f, 0x1e3d, 0x3c7a, 0x3cb7, 0x3d2d, 0x3e19, 0x3871, 0x34a1, 0x2d01, 0x1e41, 0x3c82, 0x3d47, 0x3ecd, + 0x39d9, 0x37f1, 0x2ba1, 0x1301, 0x2602, 0x0847, 0x108e, 0x211c, 0x067b, 0x0cf6, 0x19ec, 0x33d8, 0x23f3, 0x03a5, 0x074a, 0x0e94, + 0x1d28, 0x3a50, 0x30e3, 0x2585, 0x0f49, 0x1e92, 0x3d24, 0x3e0b, 0x3855, 0x34e9, 0x2d91, 0x1f61, 0x3ec2, 0x39c7, 0x37cd, 0x2bd9, + 0x13f1, 0x27e2, 0x0b87, 0x170e, 0x2e1c, 0x187b, 0x30f6, 0x25af, 0x0f1d, 0x1e3a, 0x3c74, 0x3cab, 0x3d15, 0x3e69, 0x3891, 0x3561, + 0x2e81, 0x1941, 0x3282, 0x2147, 0x06cd, 0x0d9a, 0x1b34, 0x3668, 0x2893, 0x1565, 0x2aca, 0x11d7, 0x23ae, 0x031f, 0x063e, 0x0c7c, + 0x18f8, 0x31f0, 0x27a3, 0x0b05, 0x160a, 0x2c14, 0x1c6b, 0x38d6, 0x35ef, 0x2f9d, 0x1b79, 0x36f2, 0x29a7, 0x170d, 0x2e1a, 0x1877, + 0x30ee, 0x259f, 0x0f7d, 0x1efa, 0x3df4, 0x3fab, 0x3b15, 0x3269, 0x2091, 0x0561, 0x0ac2, 0x1584, 0x2b08, 0x1253, 0x24a6, 0x0d0f, + 0x1a1e, 0x343c, 0x2c3b, 0x1c35, 0x386a, 0x3497, 0x2d6d, 0x1e99, 0x3d32, 0x3e27, 0x380d, 0x3459, 0x2cf1, 0x1da1, 0x3b42, 0x32c7, + 0x21cd, 0x07d9, 0x0fb2, 0x1f64, 0x3ec8, 0x39d3, 0x37e5, 0x2b89, 0x1351, 0x26a2, 0x0907, 0x120e, 0x241c, 0x0c7b, 0x18f6, 0x31ec, + 0x279b, 0x0b75, 0x16ea, 0x2dd4, 0x1feb, 0x3fd6, 0x3bef, 0x339d, 0x2379, 0x02b1, 0x0562, 0x0ac4, 0x1588, 0x2b10, 0x1263, 0x24c6, + 0x0dcf, 0x1b9e, 0x373c, 0x2a3b, 0x1035, 0x206a, 0x0497, 0x092e, 0x125c, 0x24b8, 0x0d33, 0x1a66, 0x34cc, 0x2ddb, 0x1ff5, 0x3fea, + 0x3b97, 0x336d, 0x2299, 0x0171, 0x02e2, 0x05c4, 0x0b88, 0x1710, 0x2e20, 0x1803, 0x3006, 0x244f, 0x0cdd, 0x19ba, 0x3374, 0x22ab, + 0x0115, 0x022a, 0x0454, 0x08a8, 0x1150, 0x22a0, 0x0103, 0x0206, 0x040c, 0x0818, 0x1030, 0x2060, 0x0483, 0x0906, 0x120c, 0x2418, + 0x0c73, 0x18e6, 0x31cc, 0x27db, 0x0bf5, 0x17ea, 0x2fd4, 0x1beb, 0x37d6, 0x2bef, 0x139d, 0x273a, 0x0a37, 0x146e, 0x28dc, 0x15fb, + 0x2bf6, 0x13af, 0x275e, 0x0aff, 0x15fe, 0x2bfc, 0x13bb, 0x2776, 0x0aaf, 0x155e, 0x2abc, 0x113b, 0x2276, 0x00af, 0x015e, 0x02bc, + 0x0578, 0x0af0, 0x15e0, 0x2bc0, 0x13c3, 0x2786, 0x0b4f, 0x169e, 0x2d3c, 0x1e3b, 0x3c76, 0x3caf, 0x3d1d, 0x3e79, 0x38b1, 0x3521, + 0x2e01, 0x1841, 0x3082, 0x2547, 0x0ecd, 0x1d9a, 0x3b34, 0x322b, 0x2015, 0x0469, 0x08d2, 0x11a4, 0x2348, 0x02d3, 0x05a6, 0x0b4c, + 0x1698, 0x2d30, 0x1e23, 0x3c46, 0x3ccf, 0x3ddd, 0x3ff9, 0x3bb1, 0x3321, 0x2201, 0x0041, 0x0082, 0x0104, 0x0208, 0x0410, 0x0820, + 0x1040, 0x2080, 0x0543, 0x0a86, 0x150c, 0x2a18, 0x1073, 0x20e6, 0x058f, 0x0b1e, 0x163c, 0x2c78, 0x1cb3, 0x3966, 0x368f, 0x295d, + 0x16f9, 0x2df2, 0x1fa7, 0x3f4e, 0x3adf, 0x31fd, 0x27b9, 0x0b31, 0x1662, 0x2cc4, 0x1dcb, 0x3b96, 0x336f, 0x229d, 0x0179, 0x02f2, + 0x05e4, 0x0bc8, 0x1790, 0x2f20, 0x1a03, 0x3406, 0x2c4f, 0x1cdd, 0x39ba, 0x3737, 0x2a2d, 0x1019, 0x2032, 0x0427, 0x084e, 0x109c, + 0x2138, 0x0633, 0x0c66, 0x18cc, 0x3198, 0x2773, 0x0aa5, 0x154a, 0x2a94, 0x116b, 0x22d6, 0x01ef, 0x03de, 0x07bc, 0x0f78, 0x1ef0, + 0x3de0, 0x3f83, 0x3b45, 0x32c9, 0x21d1, 0x07e1, 0x0fc2, 0x1f84, 0x3f08, 0x3a53, 0x30e5, 0x2589, 0x0f51, 0x1ea2, 0x3d44, 0x3ecb, + 0x39d5, 0x37e9, 0x2b91, 0x1361, 0x26c2, 0x09c7, 0x138e, 0x271c, 0x0a7b, 0x14f6, 0x29ec, 0x179b, 0x2f36, 0x1a2f, 0x345e, 0x2cff, + 0x1dbd, 0x3b7a, 0x32b7, 0x212d, 0x0619, 0x0c32, 0x1864, 0x30c8, 0x25d3, 0x0fe5, 0x1fca, 0x3f94, 0x3b6b, 0x3295, 0x2169, 0x0691, + 0x0d22, 0x1a44, 0x3488, 0x2d53, 0x1ee5, 0x3dca, 0x3fd7, 0x3bed, 0x3399, 0x2371, 0x02a1, 0x0542, 0x0a84, 0x1508, 0x2a10, 0x1063, + 0x20c6, 0x05cf, 0x0b9e, 0x173c, 0x2e78, 0x18b3, 0x3166, 0x268f, 0x095d, 0x12ba, 0x2574, 0x0eab, 0x1d56, 0x3aac, 0x311b, 0x2675, + 0x08a9, 0x1152, 0x22a4, 0x010b, 0x0216, 0x042c, 0x0858, 0x10b0, 0x2160, 0x0683, 0x0d06, 0x1a0c, 0x3418, 0x2c73, 0x1ca5, 0x394a, + 0x36d7, 0x29ed, 0x1799, 0x2f32, 0x1a27, 0x344e, 0x2cdf, 0x1dfd, 0x3bfa, 0x33b7, 0x232d, 0x0219, 0x0432, 0x0864, 0x10c8, 0x2190, + 0x0763, 0x0ec6, 0x1d8c, 0x3b18, 0x3273, 0x20a5, 0x0509, 0x0a12, 0x1424, 0x2848, 0x14d3, 0x29a6, 0x170f, 0x2e1e, 0x187f, 0x30fe, + 0x25bf, 0x0f3d, 0x1e7a, 0x3cf4, 0x3dab, 0x3f15, 0x3a69, 0x3091, 0x2561, 0x0e81, 0x1d02, 0x3a04, 0x304b, 0x24d5, 0x0de9, 0x1bd2, + 0x37a4, 0x2b0b, 0x1255, 0x24aa, 0x0d17, 0x1a2e, 0x345c, 0x2cfb, 0x1db5, 0x3b6a, 0x3297, 0x216d, 0x0699, 0x0d32, 0x1a64, 0x34c8, + 0x2dd3, 0x1fe5, 0x3fca, 0x3bd7, 0x33ed, 0x2399, 0x0371, 0x06e2, 0x0dc4, 0x1b88, 0x3710, 0x2a63, 0x1085, 0x210a, 0x0657, 0x0cae, + 0x195c, 0x32b8, 0x2133, 0x0625, 0x0c4a, 0x1894, 0x3128, 0x2613, 0x0865, 0x10ca, 0x2194, 0x076b, 0x0ed6, 0x1dac, 0x3b58, 0x32f3, + 0x21a5, 0x0709, 0x0e12, 0x1c24, 0x3848, 0x34d3, 0x2de5, 0x1f89, 0x3f12, 0x3a67, 0x308d, 0x2559, 0x0ef1, 0x1de2, 0x3bc4, 0x33cb, + 0x23d5, 0x03e9, 0x07d2, 0x0fa4, 0x1f48, 0x3e90, 0x3963, 0x3685, 0x2949, 0x16d1, 0x2da2, 0x1f07, 0x3e0e, 0x385f, 0x34fd, 0x2db9, + 0x1f31, 0x3e62, 0x3887, 0x354d, 0x2ed9, 0x19f1, 0x33e2, 0x2387, 0x034d, 0x069a, 0x0d34, 0x1a68, 0x34d0, 0x2de3, 0x1f85, 0x3f0a, + 0x3a57, 0x30ed, 0x2599, 0x0f71, 0x1ee2, 0x3dc4, 0x3fcb, 0x3bd5, 0x33e9, 0x2391, 0x0361, 0x06c2, 0x0d84, 0x1b08, 0x3610, 0x2863, + 0x1485, 0x290a, 0x1657, 0x2cae, 0x1d1f, 0x3a3e, 0x303f, 0x243d, 0x0c39, 0x1872, 0x30e4, 0x258b, 0x0f55, 0x1eaa, 0x3d54, 0x3eeb, + 0x3995, 0x3769, 0x2a91, 0x1161, 0x22c2, 0x01c7, 0x038e, 0x071c, 0x0e38, 0x1c70, 0x38e0, 0x3583, 0x2f45, 0x1ac9, 0x3592, 0x2f67, + 0x1a8d, 0x351a, 0x2e77, 0x18ad, 0x315a, 0x26f7, 0x09ad, 0x135a, 0x26b4, 0x092b, 0x1256, 0x24ac, 0x0d1b, 0x1a36, 0x346c, 0x2c9b, + 0x1d75, 0x3aea, 0x3197, 0x276d, 0x0a99, 0x1532, 0x2a64, 0x108b, 0x2116, 0x066f, 0x0cde, 0x19bc, 0x3378, 0x22b3, 0x0125, 0x024a, + 0x0494, 0x0928, 0x1250, 0x24a0, 0x0d03, 0x1a06, 0x340c, 0x2c5b, 0x1cf5, 0x39ea, 0x3797, 0x2b6d, 0x1299, 0x2532, 0x0e27, 0x1c4e, + 0x389c, 0x357b, 0x2eb5, 0x1929, 0x3252, 0x20e7, 0x058d, 0x0b1a, 0x1634, 0x2c68, 0x1c93, 0x3926, 0x360f, 0x285d, 0x14f9, 0x29f2, + 0x17a7, 0x2f4e, 0x1adf, 0x35be, 0x2f3f, 0x1a3d, 0x347a, 0x2cb7, 0x1d2d, 0x3a5a, 0x30f7, 0x25ad, 0x0f19, 0x1e32, 0x3c64, 0x3c8b, + 0x3d55, 0x3ee9, 0x3991, 0x3761, 0x2a81, 0x1141, 0x2282, 0x0147, 0x028e, 0x051c, 0x0a38, 0x1470, 0x28e0, 0x1583, 0x2b06, 0x124f, + 0x249e, 0x0d7f, 0x1afe, 0x35fc, 0x2fbb, 0x1b35, 0x366a, 0x2897, 0x156d, 0x2ada, 0x11f7, 0x23ee, 0x039f, 0x073e, 0x0e7c, 0x1cf8, + 0x39f0, 0x37a3, 0x2b05, 0x1249, 0x2492, 0x0d67, 0x1ace, 0x359c, 0x2f7b, 0x1ab5, 0x356a, 0x2e97, 0x196d, 0x32da, 0x21f7, 0x07ad, + 0x0f5a, 0x1eb4, 0x3d68, 0x3e93, 0x3965, 0x3689, 0x2951, 0x16e1, 0x2dc2, 0x1fc7, 0x3f8e, 0x3b5f, 0x32fd, 0x21b9, 0x0731, 0x0e62, + 0x1cc4, 0x3988, 0x3753, 0x2ae5, 0x1189, 0x2312, 0x0267, 0x04ce, 0x099c, 0x1338, 0x2670, 0x08a3, 0x1146, 0x228c, 0x015b, 0x02b6, + 0x056c, 0x0ad8, 0x15b0, 0x2b60, 0x1283, 0x2506, 0x0e4f, 0x1c9e, 0x393c, 0x363b, 0x2835, 0x1429, 0x2852, 0x14e7, 0x29ce, 0x17df, + 0x2fbe, 0x1b3f, 0x367e, 0x28bf, 0x153d, 0x2a7a, 0x10b7, 0x216e, 0x069f, 0x0d3e, 0x1a7c, 0x34f8, 0x2db3, 0x1f25, 0x3e4a, 0x38d7, + 0x35ed, 0x2f99, 0x1b71, 0x36e2, 0x2987, 0x174d, 0x2e9a, 0x1977, 0x32ee, 0x219f, 0x077d, 0x0efa, 0x1df4, 0x3be8, 0x3393, 0x2365, + 0x0289, 0x0512, 0x0a24, 0x1448, 0x2890, 0x1563, 0x2ac6, 0x11cf, 0x239e, 0x037f, 0x06fe, 0x0dfc, 0x1bf8, 0x37f0, 0x2ba3, 0x1305, + 0x260a, 0x0857, 0x10ae, 0x215c, 0x06fb, 0x0df6, 0x1bec, 0x37d8, 0x2bf3, 0x13a5, 0x274a, 0x0ad7, 0x15ae, 0x2b5c, 0x12fb, 0x25f6, + 0x0faf, 0x1f5e, 0x3ebc, 0x393b, 0x3635, 0x2829, 0x1411, 0x2822, 0x1407, 0x280e, 0x145f, 0x28be, 0x153f, 0x2a7e, 0x10bf, 0x217e, + 0x06bf, 0x0d7e, 0x1afc, 0x35f8, 0x2fb3, 0x1b25, 0x364a, 0x28d7, 0x15ed, 0x2bda, 0x13f7, 0x27ee, 0x0b9f, 0x173e, 0x2e7c, 0x18bb, + 0x3176, 0x26af, 0x091d, 0x123a, 0x2474, 0x0cab, 0x1956, 0x32ac, 0x211b, 0x0675, 0x0cea, 0x19d4, 0x33a8, 0x2313, 0x0265, 0x04ca, + 0x0994, 0x1328, 0x2650, 0x08e3, 0x11c6, 0x238c, 0x035b, 0x06b6, 0x0d6c, 0x1ad8, 0x35b0, 0x2f23, 0x1a05, 0x340a, 0x2c57, 0x1ced, + 0x39da, 0x37f7, 0x2bad, 0x1319, 0x2632, 0x0827, 0x104e, 0x209c, 0x057b, 0x0af6, 0x15ec, 0x2bd8, 0x13f3, 0x27e6, 0x0b8f, 0x171e, + 0x2e3c, 0x183b, 0x3076, 0x24af, 0x0d1d, 0x1a3a, 0x3474, 0x2cab, 0x1d15, 0x3a2a, 0x3017, 0x246d, 0x0c99, 0x1932, 0x3264, 0x208b, + 0x0555, 0x0aaa, 0x1554, 0x2aa8, 0x1113, 0x2226, 0x000f, 0x001e, 0x003c, 0x0078, 0x00f0, 0x01e0, 0x03c0, 0x0780, 0x0f00, 0x1e00, + 0x3c00, 0x3c43, 0x3cc5, 0x3dc9, 0x3fd1, 0x3be1, 0x3381, 0x2341, 0x02c1, 0x0582, 0x0b04, 0x1608, 0x2c10, 0x1c63, 0x38c6, 0x35cf, + 0x2fdd, 0x1bf9, 0x37f2, 0x2ba7, 0x130d, 0x261a, 0x0877, 0x10ee, 0x21dc, 0x07fb, 0x0ff6, 0x1fec, 0x3fd8, 0x3bf3, 0x33a5, 0x2309, + 0x0251, 0x04a2, 0x0944, 0x1288, 0x2510, 0x0e63, 0x1cc6, 0x398c, 0x375b, 0x2af5, 0x11a9, 0x2352, 0x02e7, 0x05ce, 0x0b9c, 0x1738, + 0x2e70, 0x18a3, 0x3146, 0x26cf, 0x09dd, 0x13ba, 0x2774, 0x0aab, 0x1556, 0x2aac, 0x111b, 0x2236, 0x002f, 0x005e, 0x00bc, 0x0178, + 0x02f0, 0x05e0, 0x0bc0, 0x1780, 0x2f00, 0x1a43, 0x3486, 0x2d4f, 0x1edd, 0x3dba, 0x3f37, 0x3a2d, 0x3019, 0x2471, 0x0ca1, 0x1942, + 0x3284, 0x214b, 0x06d5, 0x0daa, 0x1b54, 0x36a8, 0x2913, 0x1665, 0x2cca, 0x1dd7, 0x3bae, 0x331f, 0x227d, 0x00b9, 0x0172, 0x02e4, + 0x05c8, 0x0b90, 0x1720, 0x2e40, 0x18c3, 0x3186, 0x274f, 0x0add, 0x15ba, 0x2b74, 0x12ab, 0x2556, 0x0eef, 0x1dde, 0x3bbc, 0x333b, + 0x2235, 0x0029, 0x0052, 0x00a4, 0x0148, 0x0290, 0x0520, 0x0a40, 0x1480, 0x2900, 0x1643, 0x2c86, 0x1d4f, 0x3a9e, 0x317f, 0x26bd, + 0x0939, 0x1272, 0x24e4, 0x0d8b, 0x1b16, 0x362c, 0x281b, 0x1475, 0x28ea, 0x1597, 0x2b2e, 0x121f, 0x243e, 0x0c3f, 0x187e, 0x30fc, + 0x25bb, 0x0f35, 0x1e6a, 0x3cd4, 0x3deb, 0x3f95, 0x3b69, 0x3291, 0x2161, 0x0681, 0x0d02, 0x1a04, 0x3408, 0x2c53, 0x1ce5, 0x39ca, + 0x37d7, 0x2bed, 0x1399, 0x2732, 0x0a27, 0x144e, 0x289c, 0x157b, 0x2af6, 0x11af, 0x235e, 0x02ff, 0x05fe, 0x0bfc, 0x17f8, 0x2ff0, + 0x1ba3, 0x3746, 0x2acf, 0x11dd, 0x23ba, 0x0337, 0x066e, 0x0cdc, 0x19b8, 0x3370, 0x22a3, 0x0105, 0x020a, 0x0414, 0x0828, 0x1050, + 0x20a0, 0x0503, 0x0a06, 0x140c, 0x2818, 0x1473, 0x28e6, 0x158f, 0x2b1e, 0x127f, 0x24fe, 0x0dbf, 0x1b7e, 0x36fc, 0x29bb, 0x1735, + 0x2e6a, 0x1897, 0x312e, 0x261f, 0x087d, 0x10fa, 0x21f4, 0x07ab, 0x0f56, 0x1eac, 0x3d58, 0x3ef3, 0x39a5, 0x3709, 0x2a51, 0x10e1, + 0x21c2, 0x07c7, 0x0f8e, 0x1f1c, 0x3e38, 0x3833, 0x3425, 0x2c09, 0x1c51, 0x38a2, 0x3507, 0x2e4d, 0x18d9, 0x31b2, 0x2727, 0x0a0d, + 0x141a, 0x2834, 0x142b, 0x2856, 0x14ef, 0x29de, 0x17ff, 0x2ffe, 0x1bbf, 0x377e, 0x2abf, 0x113d, 0x227a, 0x00b7, 0x016e, 0x02dc, + 0x05b8, 0x0b70, 0x16e0, 0x2dc0, 0x1fc3, 0x3f86, 0x3b4f, 0x32dd, 0x21f9, 0x07b1, 0x0f62, 0x1ec4, 0x3d88, 0x3f53, 0x3ae5, 0x3189, + 0x2751, 0x0ae1, 0x15c2, 0x2b84, 0x134b, 0x2696, 0x096f, 0x12de, 0x25bc, 0x0f3b, 0x1e76, 0x3cec, 0x3d9b, 0x3f75, 0x3aa9, 0x3111, + 0x2661, 0x0881, 0x1102, 0x2204, 0x004b, 0x0096, 0x012c, 0x0258, 0x04b0, 0x0960, 0x12c0, 0x2580, 0x0f43, 0x1e86, 0x3d0c, 0x3e5b, + 0x38f5, 0x35a9, 0x2f11, 0x1a61, 0x34c2, 0x2dc7, 0x1fcd, 0x3f9a, 0x3b77, 0x32ad, 0x2119, 0x0671, 0x0ce2, 0x19c4, 0x3388, 0x2353, + 0x02e5, 0x05ca, 0x0b94, 0x1728, 0x2e50, 0x18e3, 0x31c6, 0x27cf, 0x0bdd, 0x17ba, 0x2f74, 0x1aab, 0x3556, 0x2eef, 0x199d, 0x333a, + 0x2237, 0x002d, 0x005a, 0x00b4, 0x0168, 0x02d0, 0x05a0, 0x0b40, 0x1680, 0x2d00, 0x1e43, 0x3c86, 0x3d4f, 0x3edd, 0x39f9, 0x37b1, + 0x2b21, 0x1201, 0x2402, 0x0c47, 0x188e, 0x311c, 0x267b, 0x08b5, 0x116a, 0x22d4, 0x01eb, 0x03d6, 0x07ac, 0x0f58, 0x1eb0, 0x3d60, + 0x3e83, 0x3945, 0x36c9, 0x29d1, 0x17e1, 0x2fc2, 0x1bc7, 0x378e, 0x2b5f, 0x12fd, 0x25fa, 0x0fb7, 0x1f6e, 0x3edc, 0x39fb, 0x37b5, + 0x2b29, 0x1211, 0x2422, 0x0c07, 0x180e, 0x301c, 0x247b, 0x0cb5, 0x196a, 0x32d4, 0x21eb, 0x0795, 0x0f2a, 0x1e54, 0x3ca8, 0x3d13, + 0x3e65, 0x3889, 0x3551, 0x2ee1, 0x1981, 0x3302, 0x2247, 0x00cd, 0x019a, 0x0334, 0x0668, 0x0cd0, 0x19a0, 0x3340, 0x22c3, 0x01c5, + 0x038a, 0x0714, 0x0e28, 0x1c50, 0x38a0, 0x3503, 0x2e45, 0x18c9, 0x3192, 0x2767, 0x0a8d, 0x151a, 0x2a34, 0x102b, 0x2056, 0x04ef, + 0x09de, 0x13bc, 0x2778, 0x0ab3, 0x1566, 0x2acc, 0x11db, 0x23b6, 0x032f, 0x065e, 0x0cbc, 0x1978, 0x32f0, 0x21a3, 0x0705, 0x0e0a, + 0x1c14, 0x3828, 0x3413, 0x2c65, 0x1c89, 0x3912, 0x3667, 0x288d, 0x1559, 0x2ab2, 0x1127, 0x224e, 0x00df, 0x01be, 0x037c, 0x06f8, + 0x0df0, 0x1be0, 0x37c0, 0x2bc3, 0x13c5, 0x278a, 0x0b57, 0x16ae, 0x2d5c, 0x1efb, 0x3df6, 0x3faf, 0x3b1d, 0x3279, 0x20b1, 0x0521, + 0x0a42, 0x1484, 0x2908, 0x1653, 0x2ca6, 0x1d0f, 0x3a1e, 0x307f, 0x24bd, 0x0d39, 0x1a72, 0x34e4, 0x2d8b, 0x1f55, 0x3eaa, 0x3917, + 0x366d, 0x2899, 0x1571, 0x2ae2, 0x1187, 0x230e, 0x025f, 0x04be, 0x097c, 0x12f8, 0x25f0, 0x0fa3, 0x1f46, 0x3e8c, 0x395b, 0x36f5, + 0x29a9, 0x1711, 0x2e22, 0x1807, 0x300e, 0x245f, 0x0cfd, 0x19fa, 0x33f4, 0x23ab, 0x0315, 0x062a, 0x0c54, 0x18a8, 0x3150, 0x26e3, + 0x0985, 0x130a, 0x2614, 0x086b, 0x10d6, 0x21ac, 0x071b, 0x0e36, 0x1c6c, 0x38d8, 0x35f3, 0x2fa5, 0x1b09, 0x3612, 0x2867, 0x148d, + 0x291a, 0x1677, 0x2cee, 0x1d9f, 0x3b3e, 0x323f, 0x203d, 0x0439, 0x0872, 0x10e4, 0x21c8, 0x07d3, 0x0fa6, 0x1f4c, 0x3e98, 0x3973, + 0x36a5, 0x2909, 0x1651, 0x2ca2, 0x1d07, 0x3a0e, 0x305f, 0x24fd, 0x0db9, 0x1b72, 0x36e4, 0x298b, 0x1755, 0x2eaa, 0x1917, 0x322e, + 0x201f, 0x047d, 0x08fa, 0x11f4, 0x23e8, 0x0393, 0x0726, 0x0e4c, 0x1c98, 0x3930, 0x3623, 0x2805, 0x1449, 0x2892, 0x1567, 0x2ace, + 0x11df, 0x23be, 0x033f, 0x067e, 0x0cfc, 0x19f8, 0x33f0, 0x23a3, 0x0305, 0x060a, 0x0c14, 0x1828, 0x3050, 0x24e3, 0x0d85, 0x1b0a, + 0x3614, 0x286b, 0x1495, 0x292a, 0x1617, 0x2c2e, 0x1c1f, 0x383e, 0x343f, 0x2c3d, 0x1c39, 0x3872, 0x34a7, 0x2d0d, 0x1e59, 0x3cb2, + 0x3d27, 0x3e0d, 0x3859, 0x34f1, 0x2da1, 0x1f01, 0x3e02, 0x3847, 0x34cd, 0x2dd9, 0x1ff1, 0x3fe2, 0x3b87, 0x334d, 0x22d9, 0x01f1, + 0x03e2, 0x07c4, 0x0f88, 0x1f10, 0x3e20, 0x3803, 0x3445, 0x2cc9, 0x1dd1, 0x3ba2, 0x3307, 0x224d, 0x00d9, 0x01b2, 0x0364, 0x06c8, + 0x0d90, 0x1b20, 0x3640, 0x28c3, 0x15c5, 0x2b8a, 0x1357, 0x26ae, 0x091f, 0x123e, 0x247c, 0x0cbb, 0x1976, 0x32ec, 0x219b, 0x0775, + 0x0eea, 0x1dd4, 0x3ba8, 0x3313, 0x2265, 0x0089, 0x0112, 0x0224, 0x0448, 0x0890, 0x1120, 0x2240, 0x00c3, 0x0186, 0x030c, 0x0618, + 0x0c30, 0x1860, 0x30c0, 0x25c3, 0x0fc5, 0x1f8a, 0x3f14, 0x3a6b, 0x3095, 0x2569, 0x0e91, 0x1d22, 0x3a44, 0x30cb, 0x25d5, 0x0fe9, + 0x1fd2, 0x3fa4, 0x3b0b, 0x3255, 0x20e9, 0x0591, 0x0b22, 0x1644, 0x2c88, 0x1d53, 0x3aa6, 0x310f, 0x265d, 0x08f9, 0x11f2, 0x23e4, + 0x038b, 0x0716, 0x0e2c, 0x1c58, 0x38b0, 0x3523, 0x2e05, 0x1849, 0x3092, 0x2567, 0x0e8d, 0x1d1a, 0x3a34, 0x302b, 0x2415, 0x0c69, + 0x18d2, 0x31a4, 0x270b, 0x0a55, 0x14aa, 0x2954, 0x16eb, 0x2dd6, 0x1fef, 0x3fde, 0x3bff, 0x33bd, 0x2339, 0x0231, 0x0462, 0x08c4, + 0x1188, 0x2310, 0x0263, 0x04c6, 0x098c, 0x1318, 0x2630, 0x0823, 0x1046, 0x208c, 0x055b, 0x0ab6, 0x156c, 0x2ad8, 0x11f3, 0x23e6, + 0x038f, 0x071e, 0x0e3c, 0x1c78, 0x38f0, 0x35a3, 0x2f05, 0x1a49, 0x3492, 0x2d67, 0x1e8d, 0x3d1a, 0x3e77, 0x38ad, 0x3519, 0x2e71, + 0x18a1, 0x3142, 0x26c7, 0x09cd, 0x139a, 0x2734, 0x0a2b, 0x1456, 0x28ac, 0x151b, 0x2a36, 0x102f, 0x205e, 0x04ff, 0x09fe, 0x13fc, + 0x27f8, 0x0bb3, 0x1766, 0x2ecc, 0x19db, 0x33b6, 0x232f, 0x021d, 0x043a, 0x0874, 0x10e8, 0x21d0, 0x07e3, 0x0fc6, 0x1f8c, 0x3f18, + 0x3a73, 0x30a5, 0x2509, 0x0e51, 0x1ca2, 0x3944, 0x36cb, 0x29d5, 0x17e9, 0x2fd2, 0x1be7, 0x37ce, 0x2bdf, 0x13fd, 0x27fa, 0x0bb7, + 0x176e, 0x2edc, 0x19fb, 0x33f6, 0x23af, 0x031d, 0x063a, 0x0c74, 0x18e8, 0x31d0, 0x27e3, 0x0b85, 0x170a, 0x2e14, 0x186b, 0x30d6, + 0x25ef, 0x0f9d, 0x1f3a, 0x3e74, 0x38ab, 0x3515, 0x2e69, 0x1891, 0x3122, 0x2607, 0x084d, 0x109a, 0x2134, 0x062b, 0x0c56, 0x18ac, + 0x3158, 0x26f3, 0x09a5, 0x134a, 0x2694, 0x096b, 0x12d6, 0x25ac, 0x0f1b, 0x1e36, 0x3c6c, 0x3c9b, 0x3d75, 0x3ea9, 0x3911, 0x3661, + 0x2881, 0x1541, 0x2a82, 0x1147, 0x228e, 0x015f, 0x02be, 0x057c, 0x0af8, 0x15f0, 0x2be0, 0x1383, 0x2706, 0x0a4f, 0x149e, 0x293c, + 0x163b, 0x2c76, 0x1caf, 0x395e, 0x36ff, 0x29bd, 0x1739, 0x2e72, 0x18a7, 0x314e, 0x26df, 0x09fd, 0x13fa, 0x27f4, 0x0bab, 0x1756, + 0x2eac, 0x191b, 0x3236, 0x202f, 0x041d, 0x083a, 0x1074, 0x20e8, 0x0593, 0x0b26, 0x164c, 0x2c98, 0x1d73, 0x3ae6, 0x318f, 0x275d, + 0x0af9, 0x15f2, 0x2be4, 0x138b, 0x2716, 0x0a6f, 0x14de, 0x29bc, 0x173b, 0x2e76, 0x18af, 0x315e, 0x26ff, 0x09bd, 0x137a, 0x26f4, + 0x09ab, 0x1356, 0x26ac, 0x091b, 0x1236, 0x246c, 0x0c9b, 0x1936, 0x326c, 0x209b, 0x0575, 0x0aea, 0x15d4, 0x2ba8, 0x1313, 0x2626, + 0x080f, 0x101e, 0x203c, 0x043b, 0x0876, 0x10ec, 0x21d8, 0x07f3, 0x0fe6, 0x1fcc, 0x3f98, 0x3b73, 0x32a5, 0x2109, 0x0651, 0x0ca2, + 0x1944, 0x3288, 0x2153, 0x06e5, 0x0dca, 0x1b94, 0x3728, 0x2a13, 0x1065, 0x20ca, 0x05d7, 0x0bae, 0x175c, 0x2eb8, 0x1933, 0x3266, + 0x208f, 0x055d, 0x0aba, 0x1574, 0x2ae8, 0x1193, 0x2326, 0x020f, 0x041e, 0x083c, 0x1078, 0x20f0, 0x05a3, 0x0b46, 0x168c, 0x2d18, + 0x1e73, 0x3ce6, 0x3d8f, 0x3f5d, 0x3af9, 0x31b1, 0x2721, 0x0a01, 0x1402, 0x2804, 0x144b, 0x2896, 0x156f, 0x2ade, 0x11ff, 0x23fe, + 0x03bf, 0x077e, 0x0efc, 0x1df8, 0x3bf0, 0x33a3, 0x2305, 0x0249, 0x0492, 0x0924, 0x1248, 0x2490, 0x0d63, 0x1ac6, 0x358c, 0x2f5b, + 0x1af5, 0x35ea, 0x2f97, 0x1b6d, 0x36da, 0x29f7, 0x17ad, 0x2f5a, 0x1af7, 0x35ee, 0x2f9f, 0x1b7d, 0x36fa, 0x29b7, 0x172d, 0x2e5a, + 0x18f7, 0x31ee, 0x279f, 0x0b7d, 0x16fa, 0x2df4, 0x1fab, 0x3f56, 0x3aef, 0x319d, 0x2779, 0x0ab1, 0x1562, 0x2ac4, 0x11cb, 0x2396, + 0x036f, 0x06de, 0x0dbc, 0x1b78, 0x36f0, 0x29a3, 0x1705, 0x2e0a, 0x1857, 0x30ae, 0x251f, 0x0e7d, 0x1cfa, 0x39f4, 0x37ab, 0x2b15, + 0x1269, 0x24d2, 0x0de7, 0x1bce, 0x379c, 0x2b7b, 0x12b5, 0x256a, 0x0e97, 0x1d2e, 0x3a5c, 0x30fb, 0x25b5, 0x0f29, 0x1e52, 0x3ca4, + 0x3d0b, 0x3e55, 0x38e9, 0x3591, 0x2f61, 0x1a81, 0x3502, 0x2e47, 0x18cd, 0x319a, 0x2777, 0x0aad, 0x155a, 0x2ab4, 0x112b, 0x2256, + 0x00ef, 0x01de, 0x03bc, 0x0778, 0x0ef0, 0x1de0, 0x3bc0, 0x33c3, 0x23c5, 0x03c9, 0x0792, 0x0f24, 0x1e48, 0x3c90, 0x3d63, 0x3e85, + 0x3949, 0x36d1, 0x29e1, 0x1781, 0x2f02, 0x1a47, 0x348e, 0x2d5f, 0x1efd, 0x3dfa, 0x3fb7, 0x3b2d, 0x3219, 0x2071, 0x04a1, 0x0942, + 0x1284, 0x2508, 0x0e53, 0x1ca6, 0x394c, 0x36db, 0x29f5, 0x17a9, 0x2f52, 0x1ae7, 0x35ce, 0x2fdf, 0x1bfd, 0x37fa, 0x2bb7, 0x132d, + 0x265a, 0x08f7, 0x11ee, 0x23dc, 0x03fb, 0x07f6, 0x0fec, 0x1fd8, 0x3fb0, 0x3b23, 0x3205, 0x2049, 0x04d1, 0x09a2, 0x1344, 0x2688, + 0x0953, 0x12a6, 0x254c, 0x0edb, 0x1db6, 0x3b6c, 0x329b, 0x2175, 0x06a9, 0x0d52, 0x1aa4, 0x3548, 0x2ed3, 0x19e5, 0x33ca, 0x23d7, + 0x03ed, 0x07da, 0x0fb4, 0x1f68, 0x3ed0, 0x39e3, 0x3785, 0x2b49, 0x12d1, 0x25a2, 0x0f07, 0x1e0e, 0x3c1c, 0x3c7b, 0x3cb5, 0x3d29, + 0x3e11, 0x3861, 0x3481, 0x2d41, 0x1ec1, 0x3d82, 0x3f47, 0x3acd, 0x31d9, 0x27f1, 0x0ba1, 0x1742, 0x2e84, 0x194b, 0x3296, 0x216f, + 0x069d, 0x0d3a, 0x1a74, 0x34e8, 0x2d93, 0x1f65, 0x3eca, 0x39d7, 0x37ed, 0x2b99, 0x1371, 0x26e2, 0x0987, 0x130e, 0x261c, 0x087b, + 0x10f6, 0x21ec, 0x079b, 0x0f36, 0x1e6c, 0x3cd8, 0x3df3, 0x3fa5, 0x3b09, 0x3251, 0x20e1, 0x0581, 0x0b02, 0x1604, 0x2c08, 0x1c53, + 0x38a6, 0x350f, 0x2e5d, 0x18f9, 0x31f2, 0x27a7, 0x0b0d, 0x161a, 0x2c34, 0x1c2b, 0x3856, 0x34ef, 0x2d9d, 0x1f79, 0x3ef2, 0x39a7, + 0x370d, 0x2a59, 0x10f1, 0x21e2, 0x0787, 0x0f0e, 0x1e1c, 0x3c38, 0x3c33, 0x3c25, 0x3c09, 0x3c51, 0x3ce1, 0x3d81, 0x3f41, 0x3ac1, + 0x31c1, 0x27c1, 0x0bc1, 0x1782, 0x2f04, 0x1a4b, 0x3496, 0x2d6f, 0x1e9d, 0x3d3a, 0x3e37, 0x382d, 0x3419, 0x2c71, 0x1ca1, 0x3942, + 0x36c7, 0x29cd, 0x17d9, 0x2fb2, 0x1b27, 0x364e, 0x28df, 0x15fd, 0x2bfa, 0x13b7, 0x276e, 0x0a9f, 0x153e, 0x2a7c, 0x10bb, 0x2176, + 0x06af, 0x0d5e, 0x1abc, 0x3578, 0x2eb3, 0x1925, 0x324a, 0x20d7, 0x05ed, 0x0bda, 0x17b4, 0x2f68, 0x1a93, 0x3526, 0x2e0f, 0x185d, + 0x30ba, 0x2537, 0x0e2d, 0x1c5a, 0x38b4, 0x352b, 0x2e15, 0x1869, 0x30d2, 0x25e7, 0x0f8d, 0x1f1a, 0x3e34, 0x382b, 0x3415, 0x2c69, + 0x1c91, 0x3922, 0x3607, 0x284d, 0x14d9, 0x29b2, 0x1727, 0x2e4e, 0x18df, 0x31be, 0x273f, 0x0a3d, 0x147a, 0x28f4, 0x15ab, 0x2b56, + 0x12ef, 0x25de, 0x0fff, 0x1ffe, 0x3ffc, 0x3bbb, 0x3335, 0x2229, 0x0011, 0x0022, 0x0044, 0x0088, 0x0110, 0x0220, 0x0440, 0x0880, + 0x1100, 0x2200, 0x0043, 0x0086, 0x010c, 0x0218, 0x0430, 0x0860, 0x10c0, 0x2180, 0x0743, 0x0e86, 0x1d0c, 0x3a18, 0x3073, 0x24a5, + 0x0d09, 0x1a12, 0x3424, 0x2c0b, 0x1c55, 0x38aa, 0x3517, 0x2e6d, 0x1899, 0x3132, 0x2627, 0x080d, 0x101a, 0x2034, 0x042b, 0x0856, + 0x10ac, 0x2158, 0x06f3, 0x0de6, 0x1bcc, 0x3798, 0x2b73, 0x12a5, 0x254a, 0x0ed7, 0x1dae, 0x3b5c, 0x32fb, 0x21b5, 0x0729, 0x0e52, + 0x1ca4, 0x3948, 0x36d3, 0x29e5, 0x1789, 0x2f12, 0x1a67, 0x34ce, 0x2ddf, 0x1ffd, 0x3ffa, 0x3bb7, 0x332d, 0x2219, 0x0071, 0x00e2, + 0x01c4, 0x0388, 0x0710, 0x0e20, 0x1c40, 0x3880, 0x3543, 0x2ec5, 0x19c9, 0x3392, 0x2367, 0x028d, 0x051a, 0x0a34, 0x1468, 0x28d0, + 0x15e3, 0x2bc6, 0x13cf, 0x279e, 0x0b7f, 0x16fe, 0x2dfc, 0x1fbb, 0x3f76, 0x3aaf, 0x311d, 0x2679, 0x08b1, 0x1162, 0x22c4, 0x01cb, + 0x0396, 0x072c, 0x0e58, 0x1cb0, 0x3960, 0x3683, 0x2945, 0x16c9, 0x2d92, 0x1f67, 0x3ece, 0x39df, 0x37fd, 0x2bb9, 0x1331, 0x2662, + 0x0887, 0x110e, 0x221c, 0x007b, 0x00f6, 0x01ec, 0x03d8, 0x07b0, 0x0f60, 0x1ec0, 0x3d80, 0x3f43, 0x3ac5, 0x31c9, 0x27d1, 0x0be1, + 0x17c2, 0x2f84, 0x1b4b, 0x3696, 0x296f, 0x169d, 0x2d3a, 0x1e37, 0x3c6e, 0x3c9f, 0x3d7d, 0x3eb9, 0x3931, 0x3621, 0x2801, 0x1441, + 0x2882, 0x1547, 0x2a8e, 0x115f, 0x22be, 0x013f, 0x027e, 0x04fc, 0x09f8, 0x13f0, 0x27e0, 0x0b83, 0x1706, 0x2e0c, 0x185b, 0x30b6, + 0x252f, 0x0e1d, 0x1c3a, 0x3874, 0x34ab, 0x2d15, 0x1e69, 0x3cd2, 0x3de7, 0x3f8d, 0x3b59, 0x32f1, 0x21a1, 0x0701, 0x0e02, 0x1c04, + 0x3808, 0x3453, 0x2ce5, 0x1d89, 0x3b12, 0x3267, 0x208d, 0x0559, 0x0ab2, 0x1564, 0x2ac8, 0x11d3, 0x23a6, 0x030f, 0x061e, 0x0c3c, + 0x1878, 0x30f0, 0x25a3, 0x0f05, 0x1e0a, 0x3c14, 0x3c6b, 0x3c95, 0x3d69, 0x3e91, 0x3961, 0x3681, 0x2941, 0x16c1, 0x2d82, 0x1f47, + 0x3e8e, 0x395f, 0x36fd, 0x29b9, 0x1731, 0x2e62, 0x1887, 0x310e, 0x265f, 0x08fd, 0x11fa, 0x23f4, 0x03ab, 0x0756, 0x0eac, 0x1d58, + 0x3ab0, 0x3123, 0x2605, 0x0849, 0x1092, 0x2124, 0x060b, 0x0c16, 0x182c, 0x3058, 0x24f3, 0x0da5, 0x1b4a, 0x3694, 0x296b, 0x1695, + 0x2d2a, 0x1e17, 0x3c2e, 0x3c1f, 0x3c7d, 0x3cb9, 0x3d31, 0x3e21, 0x3801, 0x3441, 0x2cc1, 0x1dc1, 0x3b82, 0x3347, 0x22cd, 0x01d9, + 0x03b2, 0x0764, 0x0ec8, 0x1d90, 0x3b20, 0x3203, 0x2045, 0x04c9, 0x0992, 0x1324, 0x2648, 0x08d3, 0x11a6, 0x234c, 0x02db, 0x05b6, + 0x0b6c, 0x16d8, 0x2db0, 0x1f23, 0x3e46, 0x38cf, 0x35dd, 0x2ff9, 0x1bb1, 0x3762, 0x2a87, 0x114d, 0x229a, 0x0177, 0x02ee, 0x05dc, + 0x0bb8, 0x1770, 0x2ee0, 0x1983, 0x3306, 0x224f, 0x00dd, 0x01ba, 0x0374, 0x06e8, 0x0dd0, 0x1ba0, 0x3740, 0x2ac3, 0x11c5, 0x238a, + 0x0357, 0x06ae, 0x0d5c, 0x1ab8, 0x3570, 0x2ea3, 0x1905, 0x320a, 0x2057, 0x04ed, 0x09da, 0x13b4, 0x2768, 0x0a93, 0x1526, 0x2a4c, + 0x10db, 0x21b6, 0x072f, 0x0e5e, 0x1cbc, 0x3978, 0x36b3, 0x2925, 0x1609, 0x2c12, 0x1c67, 0x38ce, 0x35df, 0x2ffd, 0x1bb9, 0x3772, + 0x2aa7, 0x110d, 0x221a, 0x0077, 0x00ee, 0x01dc, 0x03b8, 0x0770, 0x0ee0, 0x1dc0, 0x3b80, 0x3343, 0x22c5, 0x01c9, 0x0392, 0x0724, + 0x0e48, 0x1c90, 0x3920, 0x3603, 0x2845, 0x14c9, 0x2992, 0x1767, 0x2ece, 0x19df, 0x33be, 0x233f, 0x023d, 0x047a, 0x08f4, 0x11e8, + 0x23d0, 0x03e3, 0x07c6, 0x0f8c, 0x1f18, 0x3e30, 0x3823, 0x3405, 0x2c49, 0x1cd1, 0x39a2, 0x3707, 0x2a4d, 0x10d9, 0x21b2, 0x0727, + 0x0e4e, 0x1c9c, 0x3938, 0x3633, 0x2825, 0x1409, 0x2812, 0x1467, 0x28ce, 0x15df, 0x2bbe, 0x133f, 0x267e, 0x08bf, 0x117e, 0x22fc, + 0x01bb, 0x0376, 0x06ec, 0x0dd8, 0x1bb0, 0x3760, 0x2a83, 0x1145, 0x228a, 0x0157, 0x02ae, 0x055c, 0x0ab8, 0x1570, 0x2ae0, 0x1183, + 0x2306, 0x024f, 0x049e, 0x093c, 0x1278, 0x24f0, 0x0da3, 0x1b46, 0x368c, 0x295b, 0x16f5, 0x2dea, 0x1f97, 0x3f2e, 0x3a1f, 0x307d, + 0x24b9, 0x0d31, 0x1a62, 0x34c4, 0x2dcb, 0x1fd5, 0x3faa, 0x3b17, 0x326d, 0x2099, 0x0571, 0x0ae2, 0x15c4, 0x2b88, 0x1353, 0x26a6, + 0x090f, 0x121e, 0x243c, 0x0c3b, 0x1876, 0x30ec, 0x259b, 0x0f75, 0x1eea, 0x3dd4, 0x3feb, 0x3b95, 0x3369, 0x2291, 0x0161, 0x02c2, + 0x0584, 0x0b08, 0x1610, 0x2c20, 0x1c03, 0x3806, 0x344f, 0x2cdd, 0x1df9, 0x3bf2, 0x33a7, 0x230d, 0x0259, 0x04b2, 0x0964, 0x12c8, + 0x2590, 0x0f63, 0x1ec6, 0x3d8c, 0x3f5b, 0x3af5, 0x31a9, 0x2711, 0x0a61, 0x14c2, 0x2984, 0x174b, 0x2e96, 0x196f, 0x32de, 0x21ff, + 0x07bd, 0x0f7a, 0x1ef4, 0x3de8, 0x3f93, 0x3b65, 0x3289, 0x2151, 0x06e1, 0x0dc2, 0x1b84, 0x3708, 0x2a53, 0x10e5, 0x21ca, 0x07d7, + 0x0fae, 0x1f5c, 0x3eb8, 0x3933, 0x3625, 0x2809, 0x1451, 0x28a2, 0x1507, 0x2a0e, 0x105f, 0x20be, 0x053f, 0x0a7e, 0x14fc, 0x29f8, + 0x17b3, 0x2f66, 0x1a8f, 0x351e, 0x2e7f, 0x18bd, 0x317a, 0x26b7, 0x092d, 0x125a, 0x24b4, 0x0d2b, 0x1a56, 0x34ac, 0x2d1b, 0x1e75, + 0x3cea, 0x3d97, 0x3f6d, 0x3a99, 0x3171, 0x26a1, 0x0901, 0x1202, 0x2404, 0x0c4b, 0x1896, 0x312c, 0x261b, 0x0875, 0x10ea, 0x21d4, + 0x07eb, 0x0fd6, 0x1fac, 0x3f58, 0x3af3, 0x31a5, 0x2709, 0x0a51, 0x14a2, 0x2944, 0x16cb, 0x2d96, 0x1f6f, 0x3ede, 0x39ff, 0x37bd, + 0x2b39, 0x1231, 0x2462, 0x0c87, 0x190e, 0x321c, 0x207b, 0x04b5, 0x096a, 0x12d4, 0x25a8, 0x0f13, 0x1e26, 0x3c4c, 0x3cdb, 0x3df5, + 0x3fa9, 0x3b11, 0x3261, 0x2081, 0x0541, 0x0a82, 0x1504, 0x2a08, 0x1053, 0x20a6, 0x050f, 0x0a1e, 0x143c, 0x2878, 0x14b3, 0x2966, + 0x168f, 0x2d1e, 0x1e7f, 0x3cfe, 0x3dbf, 0x3f3d, 0x3a39, 0x3031, 0x2421, 0x0c01, 0x1802, 0x3004, 0x244b, 0x0cd5, 0x19aa, 0x3354, + 0x22eb, 0x0195, 0x032a, 0x0654, 0x0ca8, 0x1950, 0x32a0, 0x2103, 0x0645, 0x0c8a, 0x1914, 0x3228, 0x2013, 0x0465, 0x08ca, 0x1194, + 0x2328, 0x0213, 0x0426, 0x084c, 0x1098, 0x2130, 0x0623, 0x0c46, 0x188c, 0x3118, 0x2673, 0x08a5, 0x114a, 0x2294, 0x016b, 0x02d6, + 0x05ac, 0x0b58, 0x16b0, 0x2d60, 0x1e83, 0x3d06, 0x3e4f, 0x38dd, 0x35f9, 0x2fb1, 0x1b21, 0x3642, 0x28c7, 0x15cd, 0x2b9a, 0x1377, + 0x26ee, 0x099f, 0x133e, 0x267c, 0x08bb, 0x1176, 0x22ec, 0x019b, 0x0336, 0x066c, 0x0cd8, 0x19b0, 0x3360, 0x2283, 0x0145, 0x028a, + 0x0514, 0x0a28, 0x1450, 0x28a0, 0x1503, 0x2a06, 0x104f, 0x209e, 0x057f, 0x0afe, 0x15fc, 0x2bf8, 0x13b3, 0x2766, 0x0a8f, 0x151e, + 0x2a3c, 0x103b, 0x2076, 0x04af, 0x095e, 0x12bc, 0x2578, 0x0eb3, 0x1d66, 0x3acc, 0x31db, 0x27f5, 0x0ba9, 0x1752, 0x2ea4, 0x190b, + 0x3216, 0x206f, 0x049d, 0x093a, 0x1274, 0x24e8, 0x0d93, 0x1b26, 0x364c, 0x28db, 0x15f5, 0x2bea, 0x1397, 0x272e, 0x0a1f, 0x143e, + 0x287c, 0x14bb, 0x2976, 0x16af, 0x2d5e, 0x1eff, 0x3dfe, 0x3fbf, 0x3b3d, 0x3239, 0x2031, 0x0421, 0x0842, 0x1084, 0x2108, 0x0653, + 0x0ca6, 0x194c, 0x3298, 0x2173, 0x06a5, 0x0d4a, 0x1a94, 0x3528, 0x2e13, 0x1865, 0x30ca, 0x25d7, 0x0fed, 0x1fda, 0x3fb4, 0x3b2b, + 0x3215, 0x2069, 0x0491, 0x0922, 0x1244, 0x2488, 0x0d53, 0x1aa6, 0x354c, 0x2edb, 0x19f5, 0x33ea, 0x2397, 0x036d, 0x06da, 0x0db4, + 0x1b68, 0x36d0, 0x29e3, 0x1785, 0x2f0a, 0x1a57, 0x34ae, 0x2d1f, 0x1e7d, 0x3cfa, 0x3db7, 0x3f2d, 0x3a19, 0x3071, 0x24a1, 0x0d01, + 0x1a02, 0x3404, 0x2c4b, 0x1cd5, 0x39aa, 0x3717, 0x2a6d, 0x1099, 0x2132, 0x0627, 0x0c4e, 0x189c, 0x3138, 0x2633, 0x0825, 0x104a, + 0x2094, 0x056b, 0x0ad6, 0x15ac, 0x2b58, 0x12f3, 0x25e6, 0x0f8f, 0x1f1e, 0x3e3c, 0x383b, 0x3435, 0x2c29, 0x1c11, 0x3822, 0x3407, + 0x2c4d, 0x1cd9, 0x39b2, 0x3727, 0x2a0d, 0x1059, 0x20b2, 0x0527, 0x0a4e, 0x149c, 0x2938, 0x1633, 0x2c66, 0x1c8f, 0x391e, 0x367f, + 0x28bd, 0x1539, 0x2a72, 0x10a7, 0x214e, 0x06df, 0x0dbe, 0x1b7c, 0x36f8, 0x29b3, 0x1725, 0x2e4a, 0x18d7, 0x31ae, 0x271f, 0x0a7d, + 0x14fa, 0x29f4, 0x17ab, 0x2f56, 0x1aef, 0x35de, 0x2fff, 0x1bbd, 0x377a, 0x2ab7, 0x112d, 0x225a, 0x00f7, 0x01ee, 0x03dc, 0x07b8, + 0x0f70, 0x1ee0, 0x3dc0, 0x3fc3, 0x3bc5, 0x33c9, 0x23d1, 0x03e1, 0x07c2, 0x0f84, 0x1f08, 0x3e10, 0x3863, 0x3485, 0x2d49, 0x1ed1, + 0x3da2, 0x3f07, 0x3a4d, 0x30d9, 0x25f1, 0x0fa1, 0x1f42, 0x3e84, 0x394b, 0x36d5, 0x29e9, 0x1791, 0x2f22, 0x1a07, 0x340e, 0x2c5f, + 0x1cfd, 0x39fa, 0x37b7, 0x2b2d, 0x1219, 0x2432, 0x0c27, 0x184e, 0x309c, 0x257b, 0x0eb5, 0x1d6a, 0x3ad4, 0x31eb, 0x2795, 0x0b69, + 0x16d2, 0x2da4, 0x1f0b, 0x3e16, 0x386f, 0x349d, 0x2d79, 0x1eb1, 0x3d62, 0x3e87, 0x394d, 0x36d9, 0x29f1, 0x17a1, 0x2f42, 0x1ac7, + 0x358e, 0x2f5f, 0x1afd, 0x35fa, 0x2fb7, 0x1b2d, 0x365a, 0x28f7, 0x15ad, 0x2b5a, 0x12f7, 0x25ee, 0x0f9f, 0x1f3e, 0x3e7c, 0x38bb, + 0x3535, 0x2e29, 0x1811, 0x3022, 0x2407, 0x0c4d, 0x189a, 0x3134, 0x262b, 0x0815, 0x102a, 0x2054, 0x04eb, 0x09d6, 0x13ac, 0x2758, + 0x0af3, 0x15e6, 0x2bcc, 0x13db, 0x27b6, 0x0b2f, 0x165e, 0x2cbc, 0x1d3b, 0x3a76, 0x30af, 0x251d, 0x0e79, 0x1cf2, 0x39e4, 0x378b, + 0x2b55, 0x12e9, 0x25d2, 0x0fe7, 0x1fce, 0x3f9c, 0x3b7b, 0x32b5, 0x2129, 0x0611, 0x0c22, 0x1844, 0x3088, 0x2553, 0x0ee5, 0x1dca, + 0x3b94, 0x336b, 0x2295, 0x0169, 0x02d2, 0x05a4, 0x0b48, 0x1690, 0x2d20, 0x1e03, 0x3c06, 0x3c4f, 0x3cdd, 0x3df9, 0x3fb1, 0x3b21, + 0x3201, 0x2041, 0x04c1, 0x0982, 0x1304, 0x2608, 0x0853, 0x10a6, 0x214c, 0x06db, 0x0db6, 0x1b6c, 0x36d8, 0x29f3, 0x17a5, 0x2f4a, + 0x1ad7, 0x35ae, 0x2f1f, 0x1a7d, 0x34fa, 0x2db7, 0x1f2d, 0x3e5a, 0x38f7, 0x35ad, 0x2f19, 0x1a71, 0x34e2, 0x2d87, 0x1f4d, 0x3e9a, + 0x3977, 0x36ad, 0x2919, 0x1671, 0x2ce2, 0x1d87, 0x3b0e, 0x325f, 0x20fd, 0x05b9, 0x0b72, 0x16e4, 0x2dc8, 0x1fd3, 0x3fa6, 0x3b0f, + 0x325d, 0x20f9, 0x05b1, 0x0b62, 0x16c4, 0x2d88, 0x1f53, 0x3ea6, 0x390f, 0x365d, 0x28f9, 0x15b1, 0x2b62, 0x1287, 0x250e, 0x0e5f, + 0x1cbe, 0x397c, 0x36bb, 0x2935, 0x1629, 0x2c52, 0x1ce7, 0x39ce, 0x37df, 0x2bfd, 0x13b9, 0x2772, 0x0aa7, 0x154e, 0x2a9c, 0x117b, + 0x22f6, 0x01af, 0x035e, 0x06bc, 0x0d78, 0x1af0, 0x35e0, 0x2f83, 0x1b45, 0x368a, 0x2957, 0x16ed, 0x2dda, 0x1ff7, 0x3fee, 0x3b9f, + 0x337d, 0x22b9, 0x0131, 0x0262, 0x04c4, 0x0988, 0x1310, 0x2620, 0x0803, 0x1006, 0x200c, 0x045b, 0x08b6, 0x116c, 0x22d8, 0x01f3, + 0x03e6, 0x07cc, 0x0f98, 0x1f30, 0x3e60, 0x3883, 0x3545, 0x2ec9, 0x19d1, 0x33a2, 0x2307, 0x024d, 0x049a, 0x0934, 0x1268, 0x24d0, + 0x0de3, 0x1bc6, 0x378c, 0x2b5b, 0x12f5, 0x25ea, 0x0f97, 0x1f2e, 0x3e5c, 0x38fb, 0x35b5, 0x2f29, 0x1a11, 0x3422, 0x2c07, 0x1c4d, + 0x389a, 0x3577, 0x2ead, 0x1919, 0x3232, 0x2027, 0x040d, 0x081a, 0x1034, 0x2068, 0x0493, 0x0926, 0x124c, 0x2498, 0x0d73, 0x1ae6, + 0x35cc, 0x2fdb, 0x1bf5, 0x37ea, 0x2b97, 0x136d, 0x26da, 0x09f7, 0x13ee, 0x27dc, 0x0bfb, 0x17f6, 0x2fec, 0x1b9b, 0x3736, 0x2a2f, + 0x101d, 0x203a, 0x0437, 0x086e, 0x10dc, 0x21b8, 0x0733, 0x0e66, 0x1ccc, 0x3998, 0x3773, 0x2aa5, 0x1109, 0x2212, 0x0067, 0x00ce, + 0x019c, 0x0338, 0x0670, 0x0ce0, 0x19c0, 0x3380, 0x2343, 0x02c5, 0x058a, 0x0b14, 0x1628, 0x2c50, 0x1ce3, 0x39c6, 0x37cf, 0x2bdd, + 0x13f9, 0x27f2, 0x0ba7, 0x174e, 0x2e9c, 0x197b, 0x32f6, 0x21af, 0x071d, 0x0e3a, 0x1c74, 0x38e8, 0x3593, 0x2f65, 0x1a89, 0x3512, + 0x2e67, 0x188d, 0x311a, 0x2677, 0x08ad, 0x115a, 0x22b4, 0x012b, 0x0256, 0x04ac, 0x0958, 0x12b0, 0x2560, 0x0e83, 0x1d06, 0x3a0c, + 0x305b, 0x24f5, 0x0da9, 0x1b52, 0x36a4, 0x290b, 0x1655, 0x2caa, 0x1d17, 0x3a2e, 0x301f, 0x247d, 0x0cb9, 0x1972, 0x32e4, 0x218b, + 0x0755, 0x0eaa, 0x1d54, 0x3aa8, 0x3113, 0x2665, 0x0889, 0x1112, 0x2224, 0x000b, 0x0016, 0x002c, 0x0058, 0x00b0, 0x0160, 0x02c0, + 0x0580, 0x0b00, 0x1600, 0x2c00, 0x1c43, 0x3886, 0x354f, 0x2edd, 0x19f9, 0x33f2, 0x23a7, 0x030d, 0x061a, 0x0c34, 0x1868, 0x30d0, + 0x25e3, 0x0f85, 0x1f0a, 0x3e14, 0x386b, 0x3495, 0x2d69, 0x1e91, 0x3d22, 0x3e07, 0x384d, 0x34d9, 0x2df1, 0x1fa1, 0x3f42, 0x3ac7, + 0x31cd, 0x27d9, 0x0bf1, 0x17e2, 0x2fc4, 0x1bcb, 0x3796, 0x2b6f, 0x129d, 0x253a, 0x0e37, 0x1c6e, 0x38dc, 0x35fb, 0x2fb5, 0x1b29, + 0x3652, 0x28e7, 0x158d, 0x2b1a, 0x1277, 0x24ee, 0x0d9f, 0x1b3e, 0x367c, 0x28bb, 0x1535, 0x2a6a, 0x1097, 0x212e, 0x061f, 0x0c3e, + 0x187c, 0x30f8, 0x25b3, 0x0f25, 0x1e4a, 0x3c94, 0x3d6b, 0x3e95, 0x3969, 0x3691, 0x2961, 0x1681, 0x2d02, 0x1e47, 0x3c8e, 0x3d5f, + 0x3efd, 0x39b9, 0x3731, 0x2a21, 0x1001, 0x2002, 0x0447, 0x088e, 0x111c, 0x2238, 0x0033, 0x0066, 0x00cc, 0x0198, 0x0330, 0x0660, + 0x0cc0, 0x1980, 0x3300, 0x2243, 0x00c5, 0x018a, 0x0314, 0x0628, 0x0c50, 0x18a0, 0x3140, 0x26c3, 0x09c5, 0x138a, 0x2714, 0x0a6b, + 0x14d6, 0x29ac, 0x171b, 0x2e36, 0x182f, 0x305e, 0x24ff, 0x0dbd, 0x1b7a, 0x36f4, 0x29ab, 0x1715, 0x2e2a, 0x1817, 0x302e, 0x241f, + 0x0c7d, 0x18fa, 0x31f4, 0x27ab, 0x0b15, 0x162a, 0x2c54, 0x1ceb, 0x39d6, 0x37ef, 0x2b9d, 0x1379, 0x26f2, 0x09a7, 0x134e, 0x269c, + 0x097b, 0x12f6, 0x25ec, 0x0f9b, 0x1f36, 0x3e6c, 0x389b, 0x3575, 0x2ea9, 0x1911, 0x3222, 0x2007, 0x044d, 0x089a, 0x1134, 0x2268, + 0x0093, 0x0126, 0x024c, 0x0498, 0x0930, 0x1260, 0x24c0, 0x0dc3, 0x1b86, 0x370c, 0x2a5b, 0x10f5, 0x21ea, 0x0797, 0x0f2e, 0x1e5c, + 0x3cb8, 0x3d33, 0x3e25, 0x3809, 0x3451, 0x2ce1, 0x1d81, 0x3b02, 0x3247, 0x20cd, 0x05d9, 0x0bb2, 0x1764, 0x2ec8, 0x19d3, 0x33a6, + 0x230f, 0x025d, 0x04ba, 0x0974, 0x12e8, 0x25d0, 0x0fe3, 0x1fc6, 0x3f8c, 0x3b5b, 0x32f5, 0x21a9, 0x0711, 0x0e22, 0x1c44, 0x3888, + 0x3553, 0x2ee5, 0x1989, 0x3312, 0x2267, 0x008d, 0x011a, 0x0234, 0x0468, 0x08d0, 0x11a0, 0x2340, 0x02c3, 0x0586, 0x0b0c, 0x1618, + 0x2c30, 0x1c23, 0x3846, 0x34cf, 0x2ddd, 0x1ff9, 0x3ff2, 0x3ba7, 0x330d, 0x2259, 0x00f1, 0x01e2, 0x03c4, 0x0788, 0x0f10, 0x1e20, + 0x3c40, 0x3cc3, 0x3dc5, 0x3fc9, 0x3bd1, 0x33e1, 0x2381, 0x0341, 0x0682, 0x0d04, 0x1a08, 0x3410, 0x2c63, 0x1c85, 0x390a, 0x3657, + 0x28ed, 0x1599, 0x2b32, 0x1227, 0x244e, 0x0cdf, 0x19be, 0x337c, 0x22bb, 0x0135, 0x026a, 0x04d4, 0x09a8, 0x1350, 0x26a0, 0x0903, + 0x1206, 0x240c, 0x0c5b, 0x18b6, 0x316c, 0x269b, 0x0975, 0x12ea, 0x25d4, 0x0feb, 0x1fd6, 0x3fac, 0x3b1b, 0x3275, 0x20a9, 0x0511, + 0x0a22, 0x1444, 0x2888, 0x1553, 0x2aa6, 0x110f, 0x221e, 0x007f, 0x00fe, 0x01fc, 0x03f8, 0x07f0, 0x0fe0, 0x1fc0, 0x3f80, 0x3b43, + 0x32c5, 0x21c9, 0x07d1, 0x0fa2, 0x1f44, 0x3e88, 0x3953, 0x36e5, 0x2989, 0x1751, 0x2ea2, 0x1907, 0x320e, 0x205f, 0x04fd, 0x09fa, + 0x13f4, 0x27e8, 0x0b93, 0x1726, 0x2e4c, 0x18db, 0x31b6, 0x272f, 0x0a1d, 0x143a, 0x2874, 0x14ab, 0x2956, 0x16ef, 0x2dde, 0x1fff, + 0x3ffe, 0x3bbf, 0x333d, 0x2239, 0x0031, 0x0062, 0x00c4, 0x0188, 0x0310, 0x0620, 0x0c40, 0x1880, 0x3100, 0x2643, 0x08c5, 0x118a, + 0x2314, 0x026b, 0x04d6, 0x09ac, 0x1358, 0x26b0, 0x0923, 0x1246, 0x248c, 0x0d5b, 0x1ab6, 0x356c, 0x2e9b, 0x1975, 0x32ea, 0x2197, + 0x076d, 0x0eda, 0x1db4, 0x3b68, 0x3293, 0x2165, 0x0689, 0x0d12, 0x1a24, 0x3448, 0x2cd3, 0x1de5, 0x3bca, 0x33d7, 0x23ed, 0x0399, + 0x0732, 0x0e64, 0x1cc8, 0x3990, 0x3763, 0x2a85, 0x1149, 0x2292, 0x0167, 0x02ce, 0x059c, 0x0b38, 0x1670, 0x2ce0, 0x1d83, 0x3b06, + 0x324f, 0x20dd, 0x05f9, 0x0bf2, 0x17e4, 0x2fc8, 0x1bd3, 0x37a6, 0x2b0f, 0x125d, 0x24ba, 0x0d37, 0x1a6e, 0x34dc, 0x2dfb, 0x1fb5, + 0x3f6a, 0x3a97, 0x316d, 0x2699, 0x0971, 0x12e2, 0x25c4, 0x0fcb, 0x1f96, 0x3f2c, 0x3a1b, 0x3075, 0x24a9, 0x0d11, 0x1a22, 0x3444, + 0x2ccb, 0x1dd5, 0x3baa, 0x3317, 0x226d, 0x0099, 0x0132, 0x0264, 0x04c8, 0x0990, 0x1320, 0x2640, 0x08c3, 0x1186, 0x230c, 0x025b, + 0x04b6, 0x096c, 0x12d8, 0x25b0, 0x0f23, 0x1e46, 0x3c8c, 0x3d5b, 0x3ef5, 0x39a9, 0x3711, 0x2a61, 0x1081, 0x2102, 0x0647, 0x0c8e, + 0x191c, 0x3238, 0x2033, 0x0425, 0x084a, 0x1094, 0x2128, 0x0613, 0x0c26, 0x184c, 0x3098, 0x2573, 0x0ea5, 0x1d4a, 0x3a94, 0x316b, + 0x2695, 0x0969, 0x12d2, 0x25a4, 0x0f0b, 0x1e16, 0x3c2c, 0x3c1b, 0x3c75, 0x3ca9, 0x3d11, 0x3e61, 0x3881, 0x3541, 0x2ec1, 0x19c1, + 0x3382, 0x2347, 0x02cd, 0x059a, 0x0b34, 0x1668, 0x2cd0, 0x1de3, 0x3bc6, 0x33cf, 0x23dd, 0x03f9, 0x07f2, 0x0fe4, 0x1fc8, 0x3f90, + 0x3b63, 0x3285, 0x2149, 0x06d1, 0x0da2, 0x1b44, 0x3688, 0x2953, 0x16e5, 0x2dca, 0x1fd7, 0x3fae, 0x3b1f, 0x327d, 0x20b9, 0x0531, + 0x0a62, 0x14c4, 0x2988, 0x1753, 0x2ea6, 0x190f, 0x321e, 0x207f, 0x04bd, 0x097a, 0x12f4, 0x25e8, 0x0f93, 0x1f26, 0x3e4c, 0x38db, + 0x35f5, 0x2fa9, 0x1b11, 0x3622, 0x2807, 0x144d, 0x289a, 0x1577, 0x2aee, 0x119f, 0x233e, 0x023f, 0x047e, 0x08fc, 0x11f8, 0x23f0, + 0x03a3, 0x0746, 0x0e8c, 0x1d18, 0x3a30, 0x3023, 0x2405, 0x0c49, 0x1892, 0x3124, 0x260b, 0x0855, 0x10aa, 0x2154, 0x06eb, 0x0dd6, + 0x1bac, 0x3758, 0x2af3, 0x11a5, 0x234a, 0x02d7, 0x05ae, 0x0b5c, 0x16b8, 0x2d70, 0x1ea3, 0x3d46, 0x3ecf, 0x39dd, 0x37f9, 0x2bb1, + 0x1321, 0x2642, 0x08c7, 0x118e, 0x231c, 0x027b, 0x04f6, 0x09ec, 0x13d8, 0x27b0, 0x0b23, 0x1646, 0x2c8c, 0x1d5b, 0x3ab6, 0x312f, + 0x261d, 0x0879, 0x10f2, 0x21e4, 0x078b, 0x0f16, 0x1e2c, 0x3c58, 0x3cf3, 0x3da5, 0x3f09, 0x3a51, 0x30e1, 0x2581, 0x0f41, 0x1e82, + 0x3d04, 0x3e4b, 0x38d5, 0x35e9, 0x2f91, 0x1b61, 0x36c2, 0x29c7, 0x17cd, 0x2f9a, 0x1b77, 0x36ee, 0x299f, 0x177d, 0x2efa, 0x19b7, + 0x336e, 0x229f, 0x017d, 0x02fa, 0x05f4, 0x0be8, 0x17d0, 0x2fa0, 0x1b03, 0x3606, 0x284f, 0x14dd, 0x29ba, 0x1737, 0x2e6e, 0x189f, + 0x313e, 0x263f, 0x083d, 0x107a, 0x20f4, 0x05ab, 0x0b56, 0x16ac, 0x2d58, 0x1ef3, 0x3de6, 0x3f8f, 0x3b5d, 0x32f9, 0x21b1, 0x0721, + 0x0e42, 0x1c84, 0x3908, 0x3653, 0x28e5, 0x1589, 0x2b12, 0x1267, 0x24ce, 0x0ddf, 0x1bbe, 0x377c, 0x2abb, 0x1135, 0x226a, 0x0097, + 0x012e, 0x025c, 0x04b8, 0x0970, 0x12e0, 0x25c0, 0x0fc3, 0x1f86, 0x3f0c, 0x3a5b, 0x30f5, 0x25a9, 0x0f11, 0x1e22, 0x3c44, 0x3ccb, + 0x3dd5, 0x3fe9, 0x3b91, 0x3361, 0x2281, 0x0141, 0x0282, 0x0504, 0x0a08, 0x1410, 0x2820, 0x1403, 0x2806, 0x144f, 0x289e, 0x157f, + 0x2afe, 0x11bf, 0x237e, 0x02bf, 0x057e, 0x0afc, 0x15f8, 0x2bf0, 0x13a3, 0x2746, 0x0acf, 0x159e, 0x2b3c, 0x123b, 0x2476, 0x0caf, + 0x195e, 0x32bc, 0x213b, 0x0635, 0x0c6a, 0x18d4, 0x31a8, 0x2713, 0x0a65, 0x14ca, 0x2994, 0x176b, 0x2ed6, 0x19ef, 0x33de, 0x23ff, + 0x03bd, 0x077a, 0x0ef4, 0x1de8, 0x3bd0, 0x33e3, 0x2385, 0x0349, 0x0692, 0x0d24, 0x1a48, 0x3490, 0x2d63, 0x1e85, 0x3d0a, 0x3e57, + 0x38ed, 0x3599, 0x2f71, 0x1aa1, 0x3542, 0x2ec7, 0x19cd, 0x339a, 0x2377, 0x02ad, 0x055a, 0x0ab4, 0x1568, 0x2ad0, 0x11e3, 0x23c6, + 0x03cf, 0x079e, 0x0f3c, 0x1e78, 0x3cf0, 0x3da3, 0x3f05, 0x3a49, 0x30d1, 0x25e1, 0x0f81, 0x1f02, 0x3e04, 0x384b, 0x34d5, 0x2de9, + 0x1f91, 0x3f22, 0x3a07, 0x304d, 0x24d9, 0x0df1, 0x1be2, 0x37c4, 0x2bcb, 0x13d5, 0x27aa, 0x0b17, 0x162e, 0x2c5c, 0x1cfb, 0x39f6, + 0x37af, 0x2b1d, 0x1279, 0x24f2, 0x0da7, 0x1b4e, 0x369c, 0x297b, 0x16b5, 0x2d6a, 0x1e97, 0x3d2e, 0x3e1f, 0x387d, 0x34b9, 0x2d31, + 0x1e21, 0x3c42, 0x3cc7, 0x3dcd, 0x3fd9, 0x3bf1, 0x33a1, 0x2301, 0x0241, 0x0482, 0x0904, 0x1208, 0x2410, 0x0c63, 0x18c6, 0x318c, + 0x275b, 0x0af5, 0x15ea, 0x2bd4, 0x13eb, 0x27d6, 0x0bef, 0x17de, 0x2fbc, 0x1b3b, 0x3676, 0x28af, 0x151d, 0x2a3a, 0x1037, 0x206e, + 0x049f, 0x093e, 0x127c, 0x24f8, 0x0db3, 0x1b66, 0x36cc, 0x29db, 0x17f5, 0x2fea, 0x1b97, 0x372e, 0x2a1f, 0x107d, 0x20fa, 0x05b7, + 0x0b6e, 0x16dc, 0x2db8, 0x1f33, 0x3e66, 0x388f, 0x355d, 0x2ef9, 0x19b1, 0x3362, 0x2287, 0x014d, 0x029a, 0x0534, 0x0a68, 0x14d0, + 0x29a0, 0x1703, 0x2e06, 0x184f, 0x309e, 0x257f, 0x0ebd, 0x1d7a, 0x3af4, 0x31ab, 0x2715, 0x0a69, 0x14d2, 0x29a4, 0x170b, 0x2e16, + 0x186f, 0x30de, 0x25ff, 0x0fbd, 0x1f7a, 0x3ef4, 0x39ab, 0x3715, 0x2a69, 0x1091, 0x2122, 0x0607, 0x0c0e, 0x181c, 0x3038, 0x2433, + 0x0c25, 0x184a, 0x3094, 0x256b, 0x0e95, 0x1d2a, 0x3a54, 0x30eb, 0x2595, 0x0f69, 0x1ed2, 0x3da4, 0x3f0b, 0x3a55, 0x30e9, 0x2591, + 0x0f61, 0x1ec2, 0x3d84, 0x3f4b, 0x3ad5, 0x31e9, 0x2791, 0x0b61, 0x16c2, 0x2d84, 0x1f4b, 0x3e96, 0x396f, 0x369d, 0x2979, 0x16b1, + 0x2d62, 0x1e87, 0x3d0e, 0x3e5f, 0x38fd, 0x35b9, 0x2f31, 0x1a21, 0x3442, 0x2cc7, 0x1dcd, 0x3b9a, 0x3377, 0x22ad, 0x0119, 0x0232, + 0x0464, 0x08c8, 0x1190, 0x2320, 0x0203, 0x0406, 0x080c, 0x1018, 0x2030, 0x0423, 0x0846, 0x108c, 0x2118, 0x0673, 0x0ce6, 0x19cc, + 0x3398, 0x2373, 0x02a5, 0x054a, 0x0a94, 0x1528, 0x2a50, 0x10e3, 0x21c6, 0x07cf, 0x0f9e, 0x1f3c, 0x3e78, 0x38b3, 0x3525, 0x2e09, + 0x1851, 0x30a2, 0x2507, 0x0e4d, 0x1c9a, 0x3934, 0x362b, 0x2815, 0x1469, 0x28d2, 0x15e7, 0x2bce, 0x13df, 0x27be, 0x0b3f, 0x167e, + 0x2cfc, 0x1dbb, 0x3b76, 0x32af, 0x211d, 0x0679, 0x0cf2, 0x19e4, 0x33c8, 0x23d3, 0x03e5, 0x07ca, 0x0f94, 0x1f28, 0x3e50, 0x38e3, + 0x3585, 0x2f49, 0x1ad1, 0x35a2, 0x2f07, 0x1a4d, 0x349a, 0x2d77, 0x1ead, 0x3d5a, 0x3ef7, 0x39ad, 0x3719, 0x2a71, 0x10a1, 0x2142, + 0x06c7, 0x0d8e, 0x1b1c, 0x3638, 0x2833, 0x1425, 0x284a, 0x14d7, 0x29ae, 0x171f, 0x2e3e, 0x183f, 0x307e, 0x24bf, 0x0d3d, 0x1a7a, + 0x34f4, 0x2dab, 0x1f15, 0x3e2a, 0x3817, 0x346d, 0x2c99, 0x1d71, 0x3ae2, 0x3187, 0x274d, 0x0ad9, 0x15b2, 0x2b64, 0x128b, 0x2516, + 0x0e6f, 0x1cde, 0x39bc, 0x373b, 0x2a35, 0x1029, 0x2052, 0x04e7, 0x09ce, 0x139c, 0x2738, 0x0a33, 0x1466, 0x28cc, 0x15db, 0x2bb6, + 0x132f, 0x265e, 0x08ff, 0x11fe, 0x23fc, 0x03bb, 0x0776, 0x0eec, 0x1dd8, 0x3bb0, 0x3323, 0x2205, 0x0049, 0x0092, 0x0124, 0x0248, + 0x0490, 0x0920, 0x1240, 0x2480, 0x0d43, 0x1a86, 0x350c, 0x2e5b, 0x18f5, 0x31ea, 0x2797, 0x0b6d, 0x16da, 0x2db4, 0x1f2b, 0x3e56, + 0x38ef, 0x359d, 0x2f79, 0x1ab1, 0x3562, 0x2e87, 0x194d, 0x329a, 0x2177, 0x06ad, 0x0d5a, 0x1ab4, 0x3568, 0x2e93, 0x1965, 0x32ca, + 0x21d7, 0x07ed, 0x0fda, 0x1fb4, 0x3f68, 0x3a93, 0x3165, 0x2689, 0x0951, 0x12a2, 0x2544, 0x0ecb, 0x1d96, 0x3b2c, 0x321b, 0x2075, + 0x04a9, 0x0952, 0x12a4, 0x2548, 0x0ed3, 0x1da6, 0x3b4c, 0x32db, 0x21f5, 0x07a9, 0x0f52, 0x1ea4, 0x3d48, 0x3ed3, 0x39e5, 0x3789, + 0x2b51, 0x12e1, 0x25c2, 0x0fc7, 0x1f8e, 0x3f1c, 0x3a7b, 0x30b5, 0x2529, 0x0e11, 0x1c22, 0x3844, 0x34cb, 0x2dd5, 0x1fe9, 0x3fd2, + 0x3be7, 0x338d, 0x2359, 0x02f1, 0x05e2, 0x0bc4, 0x1788, 0x2f10, 0x1a63, 0x34c6, 0x2dcf, 0x1fdd, 0x3fba, 0x3b37, 0x322d, 0x2019, + 0x0471, 0x08e2, 0x11c4, 0x2388, 0x0353, 0x06a6, 0x0d4c, 0x1a98, 0x3530, 0x2e23, 0x1805, 0x300a, 0x2457, 0x0ced, 0x19da, 0x33b4, + 0x232b, 0x0215, 0x042a, 0x0854, 0x10a8, 0x2150, 0x06e3, 0x0dc6, 0x1b8c, 0x3718, 0x2a73, 0x10a5, 0x214a, 0x06d7, 0x0dae, 0x1b5c, + 0x36b8, 0x2933, 0x1625, 0x2c4a, 0x1cd7, 0x39ae, 0x371f, 0x2a7d, 0x10b9, 0x2172, 0x06a7, 0x0d4e, 0x1a9c, 0x3538, 0x2e33, 0x1825, + 0x304a, 0x24d7, 0x0ded, 0x1bda, 0x37b4, 0x2b2b, 0x1215, 0x242a, 0x0c17, 0x182e, 0x305c, 0x24fb, 0x0db5, 0x1b6a, 0x36d4, 0x29eb, + 0x1795, 0x2f2a, 0x1a17, 0x342e, 0x2c1f, 0x1c7d, 0x38fa, 0x35b7, 0x2f2d, 0x1a19, 0x3432, 0x2c27, 0x1c0d, 0x381a, 0x3477, 0x2cad, + 0x1d19, 0x3a32, 0x3027, 0x240d, 0x0c59, 0x18b2, 0x3164, 0x268b, 0x0955, 0x12aa, 0x2554, 0x0eeb, 0x1dd6, 0x3bac, 0x331b, 0x2275, + 0x00a9, 0x0152, 0x02a4, 0x0548, 0x0a90, 0x1520, 0x2a40, 0x10c3, 0x2186, 0x074f, 0x0e9e, 0x1d3c, 0x3a78, 0x30b3, 0x2525, 0x0e09, + 0x1c12, 0x3824, 0x340b, 0x2c55, 0x1ce9, 0x39d2, 0x37e7, 0x2b8d, 0x1359, 0x26b2, 0x0927, 0x124e, 0x249c, 0x0d7b, 0x1af6, 0x35ec, + 0x2f9b, 0x1b75, 0x36ea, 0x2997, 0x176d, 0x2eda, 0x19f7, 0x33ee, 0x239f, 0x037d, 0x06fa, 0x0df4, 0x1be8, 0x37d0, 0x2be3, 0x1385, + 0x270a, 0x0a57, 0x14ae, 0x295c, 0x16fb, 0x2df6, 0x1faf, 0x3f5e, 0x3aff, 0x31bd, 0x2739, 0x0a31, 0x1462, 0x28c4, 0x15cb, 0x2b96, + 0x136f, 0x26de, 0x09ff, 0x13fe, 0x27fc, 0x0bbb, 0x1776, 0x2eec, 0x199b, 0x3336, 0x222f, 0x001d, 0x003a, 0x0074, 0x00e8, 0x01d0, + 0x03a0, 0x0740, 0x0e80, 0x1d00, 0x3a00, 0x3043, 0x24c5, 0x0dc9, 0x1b92, 0x3724, 0x2a0b, 0x1055, 0x20aa, 0x0517, 0x0a2e, 0x145c, + 0x28b8, 0x1533, 0x2a66, 0x108f, 0x211e, 0x067f, 0x0cfe, 0x19fc, 0x33f8, 0x23b3, 0x0325, 0x064a, 0x0c94, 0x1928, 0x3250, 0x20e3, + 0x0585, 0x0b0a, 0x1614, 0x2c28, 0x1c13, 0x3826, 0x340f, 0x2c5d, 0x1cf9, 0x39f2, 0x37a7, 0x2b0d, 0x1259, 0x24b2, 0x0d27, 0x1a4e, + 0x349c, 0x2d7b, 0x1eb5, 0x3d6a, 0x3e97, 0x396d, 0x3699, 0x2971, 0x16a1, 0x2d42, 0x1ec7, 0x3d8e, 0x3f5f, 0x3afd, 0x31b9, 0x2731, + 0x0a21, 0x1442, 0x2884, 0x154b, 0x2a96, 0x116f, 0x22de, 0x01ff, 0x03fe, 0x07fc, 0x0ff8, 0x1ff0, 0x3fe0, 0x3b83, 0x3345, 0x22c9, + 0x01d1, 0x03a2, 0x0744, 0x0e88, 0x1d10, 0x3a20, 0x3003, 0x2445, 0x0cc9, 0x1992, 0x3324, 0x220b, 0x0055, 0x00aa, 0x0154, 0x02a8, + 0x0550, 0x0aa0, 0x1540, 0x2a80, 0x1143, 0x2286, 0x014f, 0x029e, 0x053c, 0x0a78, 0x14f0, 0x29e0, 0x1783, 0x2f06, 0x1a4f, 0x349e, + 0x2d7f, 0x1ebd, 0x3d7a, 0x3eb7, 0x392d, 0x3619, 0x2871, 0x14a1, 0x2942, 0x16c7, 0x2d8e, 0x1f5f, 0x3ebe, 0x393f, 0x363d, 0x2839, + 0x1431, 0x2862, 0x1487, 0x290e, 0x165f, 0x2cbe, 0x1d3f, 0x3a7e, 0x30bf, 0x253d, 0x0e39, 0x1c72, 0x38e4, 0x358b, 0x2f55, 0x1ae9, + 0x35d2, 0x2fe7, 0x1b8d, 0x371a, 0x2a77, 0x10ad, 0x215a, 0x06f7, 0x0dee, 0x1bdc, 0x37b8, 0x2b33, 0x1225, 0x244a, 0x0cd7, 0x19ae, + 0x335c, 0x22fb, 0x01b5, 0x036a, 0x06d4, 0x0da8, 0x1b50, 0x36a0, 0x2903, 0x1645, 0x2c8a, 0x1d57, 0x3aae, 0x311f, 0x267d, 0x08b9, + 0x1172, 0x22e4, 0x018b, 0x0316, 0x062c, 0x0c58, 0x18b0, 0x3160, 0x2683, 0x0945, 0x128a, 0x2514, 0x0e6b, 0x1cd6, 0x39ac, 0x371b, + 0x2a75, 0x10a9, 0x2152, 0x06e7, 0x0dce, 0x1b9c, 0x3738, 0x2a33, 0x1025, 0x204a, 0x04d7, 0x09ae, 0x135c, 0x26b8, 0x0933, 0x1266, + 0x24cc, 0x0ddb, 0x1bb6, 0x376c, 0x2a9b, 0x1175, 0x22ea, 0x0197, 0x032e, 0x065c, 0x0cb8, 0x1970, 0x32e0, 0x2183, 0x0745, 0x0e8a, + 0x1d14, 0x3a28, 0x3013, 0x2465, 0x0c89, 0x1912, 0x3224, 0x200b, 0x0455, 0x08aa, 0x1154, 0x22a8, 0x0113, 0x0226, 0x044c, 0x0898, + 0x1130, 0x2260, 0x0083, 0x0106, 0x020c, 0x0418, 0x0830, 0x1060, 0x20c0, 0x05c3, 0x0b86, 0x170c, 0x2e18, 0x1873, 0x30e6, 0x258f, + 0x0f5d, 0x1eba, 0x3d74, 0x3eab, 0x3915, 0x3669, 0x2891, 0x1561, 0x2ac2, 0x11c7, 0x238e, 0x035f, 0x06be, 0x0d7c, 0x1af8, 0x35f0, + 0x2fa3, 0x1b05, 0x360a, 0x2857, 0x14ed, 0x29da, 0x17f7, 0x2fee, 0x1b9f, 0x373e, 0x2a3f, 0x103d, 0x207a, 0x04b7, 0x096e, 0x12dc, + 0x25b8, 0x0f33, 0x1e66, 0x3ccc, 0x3ddb, 0x3ff5, 0x3ba9, 0x3311, 0x2261, 0x0081, 0x0102, 0x0204, 0x0408, 0x0810, 0x1020, 0x2040, + 0x04c3, 0x0986, 0x130c, 0x2618, 0x0873, 0x10e6, 0x21cc, 0x07db, 0x0fb6, 0x1f6c, 0x3ed8, 0x39f3, 0x37a5, 0x2b09, 0x1251, 0x24a2, + 0x0d07, 0x1a0e, 0x341c, 0x2c7b, 0x1cb5, 0x396a, 0x3697, 0x296d, 0x1699, 0x2d32, 0x1e27, 0x3c4e, 0x3cdf, 0x3dfd, 0x3fb9, 0x3b31, + 0x3221, 0x2001, 0x0441, 0x0882, 0x1104, 0x2208, 0x0053, 0x00a6, 0x014c, 0x0298, 0x0530, 0x0a60, 0x14c0, 0x2980, 0x1743, 0x2e86, + 0x194f, 0x329e, 0x217f, 0x06bd, 0x0d7a, 0x1af4, 0x35e8, 0x2f93, 0x1b65, 0x36ca, 0x29d7, 0x17ed, 0x2fda, 0x1bf7, 0x37ee, 0x2b9f, + 0x137d, 0x26fa, 0x09b7, 0x136e, 0x26dc, 0x09fb, 0x13f6, 0x27ec, 0x0b9b, 0x1736, 0x2e6c, 0x189b, 0x3136, 0x262f, 0x081d, 0x103a, + 0x2074, 0x04ab, 0x0956, 0x12ac, 0x2558, 0x0ef3, 0x1de6, 0x3bcc, 0x33db, 0x23f5, 0x03a9, 0x0752, 0x0ea4, 0x1d48, 0x3a90, 0x3163, + 0x2685, 0x0949, 0x1292, 0x2524, 0x0e0b, 0x1c16, 0x382c, 0x341b, 0x2c75, 0x1ca9, 0x3952, 0x36e7, 0x298d, 0x1759, 0x2eb2, 0x1927, + 0x324e, 0x20df, 0x05fd, 0x0bfa, 0x17f4, 0x2fe8, 0x1b93, 0x3726, 0x2a0f, 0x105d, 0x20ba, 0x0537, 0x0a6e, 0x14dc, 0x29b8, 0x1733, + 0x2e66, 0x188f, 0x311e, 0x267f, 0x08bd, 0x117a, 0x22f4, 0x01ab, 0x0356, 0x06ac, 0x0d58, 0x1ab0, 0x3560, 0x2e83, 0x1945, 0x328a, + 0x2157, 0x06ed, 0x0dda, 0x1bb4, 0x3768, 0x2a93, 0x1165, 0x22ca, 0x01d7, 0x03ae, 0x075c, 0x0eb8, 0x1d70, 0x3ae0, 0x3183, 0x2745, + 0x0ac9, 0x1592, 0x2b24, 0x120b, 0x2416, 0x0c6f, 0x18de, 0x31bc, 0x273b, 0x0a35, 0x146a, 0x28d4, 0x15eb, 0x2bd6, 0x13ef, 0x27de, + 0x0bff, 0x17fe, 0x2ffc, 0x1bbb, 0x3776, 0x2aaf, 0x111d, 0x223a, 0x0037, 0x006e, 0x00dc, 0x01b8, 0x0370, 0x06e0, 0x0dc0, 0x1b80, + 0x3700, 0x2a43, 0x10c5, 0x218a, 0x0757, 0x0eae, 0x1d5c, 0x3ab8, 0x3133, 0x2625, 0x0809, 0x1012, 0x2024, 0x040b, 0x0816, 0x102c, + 0x2058, 0x04f3, 0x09e6, 0x13cc, 0x2798, 0x0b73, 0x16e6, 0x2dcc, 0x1fdb, 0x3fb6, 0x3b2f, 0x321d, 0x2079, 0x04b1, 0x0962, 0x12c4, + 0x2588, 0x0f53, 0x1ea6, 0x3d4c, 0x3edb, 0x39f5, 0x37a9, 0x2b11, 0x1261, 0x24c2, 0x0dc7, 0x1b8e, 0x371c, 0x2a7b, 0x10b5, 0x216a, + 0x0697, 0x0d2e, 0x1a5c, 0x34b8, 0x2d33, 0x1e25, 0x3c4a, 0x3cd7, 0x3ded, 0x3f99, 0x3b71, 0x32a1, 0x2101, 0x0641, 0x0c82, 0x1904, + 0x3208, 0x2053, 0x04e5, 0x09ca, 0x1394, 0x2728, 0x0a13, 0x1426, 0x284c, 0x14db, 0x29b6, 0x172f, 0x2e5e, 0x18ff, 0x31fe, 0x27bf, + 0x0b3d, 0x167a, 0x2cf4, 0x1dab, 0x3b56, 0x32ef, 0x219d, 0x0779, 0x0ef2, 0x1de4, 0x3bc8, 0x33d3, 0x23e5, 0x0389, 0x0712, 0x0e24, + 0x1c48, 0x3890, 0x3563, 0x2e85, 0x1949, 0x3292, 0x2167, 0x068d, 0x0d1a, 0x1a34, 0x3468, 0x2c93, 0x1d65, 0x3aca, 0x31d7, 0x27ed, + 0x0b99, 0x1732, 0x2e64, 0x188b, 0x3116, 0x266f, 0x089d, 0x113a, 0x2274, 0x00ab, 0x0156, 0x02ac, 0x0558, 0x0ab0, 0x1560, 0x2ac0, + 0x11c3, 0x2386, 0x034f, 0x069e, 0x0d3c, 0x1a78, 0x34f0, 0x2da3, 0x1f05, 0x3e0a, 0x3857, 0x34ed, 0x2d99, 0x1f71, 0x3ee2, 0x3987, + 0x374d, 0x2ad9, 0x11f1, 0x23e2, 0x0387, 0x070e, 0x0e1c, 0x1c38, 0x3870, 0x34a3, 0x2d05, 0x1e49, 0x3c92, 0x3d67, 0x3e8d, 0x3959, + 0x36f1, 0x29a1, 0x1701, 0x2e02, 0x1847, 0x308e, 0x255f, 0x0efd, 0x1dfa, 0x3bf4, 0x33ab, 0x2315, 0x0269, 0x04d2, 0x09a4, 0x1348, + 0x2690, 0x0963, 0x12c6, 0x258c, 0x0f5b, 0x1eb6, 0x3d6c, 0x3e9b, 0x3975, 0x36a9, 0x2911, 0x1661, 0x2cc2, 0x1dc7, 0x3b8e, 0x335f, + 0x22fd, 0x01b9, 0x0372, 0x06e4, 0x0dc8, 0x1b90, 0x3720, 0x2a03, 0x1045, 0x208a, 0x0557, 0x0aae, 0x155c, 0x2ab8, 0x1133, 0x2266, + 0x008f, 0x011e, 0x023c, 0x0478, 0x08f0, 0x11e0, 0x23c0, 0x03c3, 0x0786, 0x0f0c, 0x1e18, 0x3c30, 0x3c23, 0x3c05, 0x3c49, 0x3cd1, + 0x3de1, 0x3f81, 0x3b41, 0x32c1, 0x21c1, 0x07c1, 0x0f82, 0x1f04, 0x3e08, 0x3853, 0x34e5, 0x2d89, 0x1f51, 0x3ea2, 0x3907, 0x364d, + 0x28d9, 0x15f1, 0x2be2, 0x1387, 0x270e, 0x0a5f, 0x14be, 0x297c, 0x16bb, 0x2d76, 0x1eaf, 0x3d5e, 0x3eff, 0x39bd, 0x3739, 0x2a31, + 0x1021, 0x2042, 0x04c7, 0x098e, 0x131c, 0x2638, 0x0833, 0x1066, 0x20cc, 0x05db, 0x0bb6, 0x176c, 0x2ed8, 0x19f3, 0x33e6, 0x238f, + 0x035d, 0x06ba, 0x0d74, 0x1ae8, 0x35d0, 0x2fe3, 0x1b85, 0x370a, 0x2a57, 0x10ed, 0x21da, 0x07f7, 0x0fee, 0x1fdc, 0x3fb8, 0x3b33, + 0x3225, 0x2009, 0x0451, 0x08a2, 0x1144, 0x2288, 0x0153, 0x02a6, 0x054c, 0x0a98, 0x1530, 0x2a60, 0x1083, 0x2106, 0x064f, 0x0c9e, + 0x193c, 0x3278, 0x20b3, 0x0525, 0x0a4a, 0x1494, 0x2928, 0x1613, 0x2c26, 0x1c0f, 0x381e, 0x347f, 0x2cbd, 0x1d39, 0x3a72, 0x30a7, + 0x250d, 0x0e59, 0x1cb2, 0x3964, 0x368b, 0x2955, 0x16e9, 0x2dd2, 0x1fe7, 0x3fce, 0x3bdf, 0x33fd, 0x23b9, 0x0331, 0x0662, 0x0cc4, + 0x1988, 0x3310, 0x2263, 0x0085, 0x010a, 0x0214, 0x0428, 0x0850, 0x10a0, 0x2140, 0x06c3, 0x0d86, 0x1b0c, 0x3618, 0x2873, 0x14a5, + 0x294a, 0x16d7, 0x2dae, 0x1f1f, 0x3e3e, 0x383f, 0x343d, 0x2c39, 0x1c31, 0x3862, 0x3487, 0x2d4d, 0x1ed9, 0x3db2, 0x3f27, 0x3a0d, + 0x3059, 0x24f1, 0x0da1, 0x1b42, 0x3684, 0x294b, 0x16d5, 0x2daa, 0x1f17, 0x3e2e, 0x381f, 0x347d, 0x2cb9, 0x1d31, 0x3a62, 0x3087, + 0x254d, 0x0ed9, 0x1db2, 0x3b64, 0x328b, 0x2155, 0x06e9, 0x0dd2, 0x1ba4, 0x3748, 0x2ad3, 0x11e5, 0x23ca, 0x03d7, 0x07ae, 0x0f5c, + 0x1eb8, 0x3d70, 0x3ea3, 0x3905, 0x3649, 0x28d1, 0x15e1, 0x2bc2, 0x13c7, 0x278e, 0x0b5f, 0x16be, 0x2d7c, 0x1ebb, 0x3d76, 0x3eaf, + 0x391d, 0x3679, 0x28b1, 0x1521, 0x2a42, 0x10c7, 0x218e, 0x075f, 0x0ebe, 0x1d7c, 0x3af8, 0x31b3, 0x2725, 0x0a09, 0x1412, 0x2824, + 0x140b, 0x2816, 0x146f, 0x28de, 0x15ff, 0x2bfe, 0x13bf, 0x277e, 0x0abf, 0x157e, 0x2afc, 0x11bb, 0x2376, 0x02af, 0x055e, 0x0abc, + 0x1578, 0x2af0, 0x11a3, 0x2346, 0x02cf, 0x059e, 0x0b3c, 0x1678, 0x2cf0, 0x1da3, 0x3b46, 0x32cf, 0x21dd, 0x07f9, 0x0ff2, 0x1fe4, + 0x3fc8, 0x3bd3, 0x33e5, 0x2389, 0x0351, 0x06a2, 0x0d44, 0x1a88, 0x3510, 0x2e63, 0x1885, 0x310a, 0x2657, 0x08ed, 0x11da, 0x23b4, + 0x032b, 0x0656, 0x0cac, 0x1958, 0x32b0, 0x2123, 0x0605, 0x0c0a, 0x1814, 0x3028, 0x2413, 0x0c65, 0x18ca, 0x3194, 0x276b, 0x0a95, + 0x152a, 0x2a54, 0x10eb, 0x21d6, 0x07ef, 0x0fde, 0x1fbc, 0x3f78, 0x3ab3, 0x3125, 0x2609, 0x0851, 0x10a2, 0x2144, 0x06cb, 0x0d96, + 0x1b2c, 0x3658, 0x28f3, 0x15a5, 0x2b4a, 0x12d7, 0x25ae, 0x0f1f, 0x1e3e, 0x3c7c, 0x3cbb, 0x3d35, 0x3e29, 0x3811, 0x3461, 0x2c81, + 0x1d41, 0x3a82, 0x3147, 0x26cd, 0x09d9, 0x13b2, 0x2764, 0x0a8b, 0x1516, 0x2a2c, 0x101b, 0x2036, 0x042f, 0x085e, 0x10bc, 0x2178, + 0x06b3, 0x0d66, 0x1acc, 0x3598, 0x2f73, 0x1aa5, 0x354a, 0x2ed7, 0x19ed, 0x33da, 0x23f7, 0x03ad, 0x075a, 0x0eb4, 0x1d68, 0x3ad0, + 0x31e3, 0x2785, 0x0b49, 0x1692, 0x2d24, 0x1e0b, 0x3c16, 0x3c6f, 0x3c9d, 0x3d79, 0x3eb1, 0x3921, 0x3601, 0x2841, 0x14c1, 0x2982, + 0x1747, 0x2e8e, 0x195f, 0x32be, 0x213f, 0x063d, 0x0c7a, 0x18f4, 0x31e8, 0x2793, 0x0b65, 0x16ca, 0x2d94, 0x1f6b, 0x3ed6, 0x39ef, + 0x379d, 0x2b79, 0x12b1, 0x2562, 0x0e87, 0x1d0e, 0x3a1c, 0x307b, 0x24b5, 0x0d29, 0x1a52, 0x34a4, 0x2d0b, 0x1e55, 0x3caa, 0x3d17, + 0x3e6d, 0x3899, 0x3571, 0x2ea1, 0x1901, 0x3202, 0x2047, 0x04cd, 0x099a, 0x1334, 0x2668, 0x0893, 0x1126, 0x224c, 0x00db, 0x01b6, + 0x036c, 0x06d8, 0x0db0, 0x1b60, 0x36c0, 0x29c3, 0x17c5, 0x2f8a, 0x1b57, 0x36ae, 0x291f, 0x167d, 0x2cfa, 0x1db7, 0x3b6e, 0x329f, + 0x217d, 0x06b9, 0x0d72, 0x1ae4, 0x35c8, 0x2fd3, 0x1be5, 0x37ca, 0x2bd7, 0x13ed, 0x27da, 0x0bf7, 0x17ee, 0x2fdc, 0x1bfb, 0x37f6, + 0x2baf, 0x131d, 0x263a, 0x0837, 0x106e, 0x20dc, 0x05fb, 0x0bf6, 0x17ec, 0x2fd8, 0x1bf3, 0x37e6, 0x2b8f, 0x135d, 0x26ba, 0x0937, + 0x126e, 0x24dc, 0x0dfb, 0x1bf6, 0x37ec, 0x2b9b, 0x1375, 0x26ea, 0x0997, 0x132e, 0x265c, 0x08fb, 0x11f6, 0x23ec, 0x039b, 0x0736, + 0x0e6c, 0x1cd8, 0x39b0, 0x3723, 0x2a05, 0x1049, 0x2092, 0x0567, 0x0ace, 0x159c, 0x2b38, 0x1233, 0x2466, 0x0c8f, 0x191e, 0x323c, + 0x203b, 0x0435, 0x086a, 0x10d4, 0x21a8, 0x0713, 0x0e26, 0x1c4c, 0x3898, 0x3573, 0x2ea5, 0x1909, 0x3212, 0x2067, 0x048d, 0x091a, + 0x1234, 0x2468, 0x0c93, 0x1926, 0x324c, 0x20db, 0x05f5, 0x0bea, 0x17d4, 0x2fa8, 0x1b13, 0x3626, 0x280f, 0x145d, 0x28ba, 0x1537, + 0x2a6e, 0x109f, 0x213e, 0x063f, 0x0c7e, 0x18fc, 0x31f8, 0x27b3, 0x0b25, 0x164a, 0x2c94, 0x1d6b, 0x3ad6, 0x31ef, 0x279d, 0x0b79, + 0x16f2, 0x2de4, 0x1f8b, 0x3f16, 0x3a6f, 0x309d, 0x2579, 0x0eb1, 0x1d62, 0x3ac4, 0x31cb, 0x27d5, 0x0be9, 0x17d2, 0x2fa4, 0x1b0b, + 0x3616, 0x286f, 0x149d, 0x293a, 0x1637, 0x2c6e, 0x1c9f, 0x393e, 0x363f, 0x283d, 0x1439, 0x2872, 0x14a7, 0x294e, 0x16df, 0x2dbe, + 0x1f3f, 0x3e7e, 0x38bf, 0x353d, 0x2e39, 0x1831, 0x3062, 0x2487, 0x0d4d, 0x1a9a, 0x3534, 0x2e2b, 0x1815, 0x302a, 0x2417, 0x0c6d, + 0x18da, 0x31b4, 0x272b, 0x0a15, 0x142a, 0x2854, 0x14eb, 0x29d6, 0x17ef, 0x2fde, 0x1bff, 0x37fe, 0x2bbf, 0x133d, 0x267a, 0x08b7, + 0x116e, 0x22dc, 0x01fb, 0x03f6, 0x07ec, 0x0fd8, 0x1fb0, 0x3f60, 0x3a83, 0x3145, 0x26c9, 0x09d1, 0x13a2, 0x2744, 0x0acb, 0x1596, + 0x2b2c, 0x121b, 0x2436, 0x0c2f, 0x185e, 0x30bc, 0x253b, 0x0e35, 0x1c6a, 0x38d4, 0x35eb, 0x2f95, 0x1b69, 0x36d2, 0x29e7, 0x178d, + 0x2f1a, 0x1a77, 0x34ee, 0x2d9f, 0x1f7d, 0x3efa, 0x39b7, 0x372d, 0x2a19, 0x1071, 0x20e2, 0x0587, 0x0b0e, 0x161c, 0x2c38, 0x1c33, + 0x3866, 0x348f, 0x2d5d, 0x1ef9, 0x3df2, 0x3fa7, 0x3b0d, 0x3259, 0x20f1, 0x05a1, 0x0b42, 0x1684, 0x2d08, 0x1e53, 0x3ca6, 0x3d0f, + 0x3e5d, 0x38f9, 0x35b1, 0x2f21, 0x1a01, 0x3402, 0x2c47, 0x1ccd, 0x399a, 0x3777, 0x2aad, 0x1119, 0x2232, 0x0027, 0x004e, 0x009c, + 0x0138, 0x0270, 0x04e0, 0x09c0, 0x1380, 0x2700, 0x0a43, 0x1486, 0x290c, 0x165b, 0x2cb6, 0x1d2f, 0x3a5e, 0x30ff, 0x25bd, 0x0f39, + 0x1e72, 0x3ce4, 0x3d8b, 0x3f55, 0x3ae9, 0x3191, 0x2761, 0x0a81, 0x1502, 0x2a04, 0x104b, 0x2096, 0x056f, 0x0ade, 0x15bc, 0x2b78, + 0x12b3, 0x2566, 0x0e8f, 0x1d1e, 0x3a3c, 0x303b, 0x2435, 0x0c29, 0x1852, 0x30a4, 0x250b, 0x0e55, 0x1caa, 0x3954, 0x36eb, 0x2995, + 0x1769, 0x2ed2, 0x19e7, 0x33ce, 0x23df, 0x03fd, 0x07fa, 0x0ff4, 0x1fe8, 0x3fd0, 0x3be3, 0x3385, 0x2349, 0x02d1, 0x05a2, 0x0b44, + 0x1688, 0x2d10, 0x1e63, 0x3cc6, 0x3dcf, 0x3fdd, 0x3bf9, 0x33b1, 0x2321, 0x0201, 0x0402, 0x0804, 0x1008, 0x2010, 0x0463, 0x08c6, + 0x118c, 0x2318, 0x0273, 0x04e6, 0x09cc, 0x1398, 0x2730, 0x0a23, 0x1446, 0x288c, 0x155b, 0x2ab6, 0x112f, 0x225e, 0x00ff, 0x01fe, + 0x03fc, 0x07f8, 0x0ff0, 0x1fe0, 0x3fc0, 0x3bc3, 0x33c5, 0x23c9, 0x03d1, 0x07a2, 0x0f44, 0x1e88, 0x3d10, 0x3e63, 0x3885, 0x3549, + 0x2ed1, 0x19e1, 0x33c2, 0x23c7, 0x03cd, 0x079a, 0x0f34, 0x1e68, 0x3cd0, 0x3de3, 0x3f85, 0x3b49, 0x32d1, 0x21e1, 0x0781, 0x0f02, + 0x1e04, 0x3c08, 0x3c53, 0x3ce5, 0x3d89, 0x3f51, 0x3ae1, 0x3181, 0x2741, 0x0ac1, 0x1582, 0x2b04, 0x124b, 0x2496, 0x0d6f, 0x1ade, + 0x35bc, 0x2f3b, 0x1a35, 0x346a, 0x2c97, 0x1d6d, 0x3ada, 0x31f7, 0x27ad, 0x0b19, 0x1632, 0x2c64, 0x1c8b, 0x3916, 0x366f, 0x289d, + 0x1579, 0x2af2, 0x11a7, 0x234e, 0x02df, 0x05be, 0x0b7c, 0x16f8, 0x2df0, 0x1fa3, 0x3f46, 0x3acf, 0x31dd, 0x27f9, 0x0bb1, 0x1762, + 0x2ec4, 0x19cb, 0x3396, 0x236f, 0x029d, 0x053a, 0x0a74, 0x14e8, 0x29d0, 0x17e3, 0x2fc6, 0x1bcf, 0x379e, 0x2b7f, 0x12bd, 0x257a, + 0x0eb7, 0x1d6e, 0x3adc, 0x31fb, 0x27b5, 0x0b29, 0x1652, 0x2ca4, 0x1d0b, 0x3a16, 0x306f, 0x249d, 0x0d79, 0x1af2, 0x35e4, 0x2f8b, + 0x1b55, 0x36aa, 0x2917, 0x166d, 0x2cda, 0x1df7, 0x3bee, 0x339f, 0x237d, 0x02b9, 0x0572, 0x0ae4, 0x15c8, 0x2b90, 0x1363, 0x26c6, + 0x09cf, 0x139e, 0x273c, 0x0a3b, 0x1476, 0x28ec, 0x159b, 0x2b36, 0x122f, 0x245e, 0x0cff, 0x19fe, 0x33fc, 0x23bb, 0x0335, 0x066a, + 0x0cd4, 0x19a8, 0x3350, 0x22e3, 0x0185, 0x030a, 0x0614, 0x0c28, 0x1850, 0x30a0, 0x2503, 0x0e45, 0x1c8a, 0x3914, 0x366b, 0x2895, + 0x1569, 0x2ad2, 0x11e7, 0x23ce, 0x03df, 0x07be, 0x0f7c, 0x1ef8, 0x3df0, 0x3fa3, 0x3b05, 0x3249, 0x20d1, 0x05e1, 0x0bc2, 0x1784, + 0x2f08, 0x1a53, 0x34a6, 0x2d0f, 0x1e5d, 0x3cba, 0x3d37, 0x3e2d, 0x3819, 0x3471, 0x2ca1, 0x1d01, 0x3a02, 0x3047, 0x24cd, 0x0dd9, + 0x1bb2, 0x3764, 0x2a8b, 0x1155, 0x22aa, 0x0117, 0x022e, 0x045c, 0x08b8, 0x1170, 0x22e0, 0x0183, 0x0306, 0x060c, 0x0c18, 0x1830, + 0x3060, 0x2483, 0x0d45, 0x1a8a, 0x3514, 0x2e6b, 0x1895, 0x312a, 0x2617, 0x086d, 0x10da, 0x21b4, 0x072b, 0x0e56, 0x1cac, 0x3958, + 0x36f3, 0x29a5, 0x1709, 0x2e12, 0x1867, 0x30ce, 0x25df, 0x0ffd, 0x1ffa, 0x3ff4, 0x3bab, 0x3315, 0x2269, 0x0091, 0x0122, 0x0244, + 0x0488, 0x0910, 0x1220, 0x2440, 0x0cc3, 0x1986, 0x330c, 0x225b, 0x00f5, 0x01ea, 0x03d4, 0x07a8, 0x0f50, 0x1ea0, 0x3d40, 0x3ec3, + 0x39c5, 0x37c9, 0x2bd1, 0x13e1, 0x27c2, 0x0bc7, 0x178e, 0x2f1c, 0x1a7b, 0x34f6, 0x2daf, 0x1f1d, 0x3e3a, 0x3837, 0x342d, 0x2c19, + 0x1c71, 0x38e2, 0x3587, 0x2f4d, 0x1ad9, 0x35b2, 0x2f27, 0x1a0d, 0x341a, 0x2c77, 0x1cad, 0x395a, 0x36f7, 0x29ad, 0x1719, 0x2e32, + 0x1827, 0x304e, 0x24df, 0x0dfd, 0x1bfa, 0x37f4, 0x2bab, 0x1315, 0x262a, 0x0817, 0x102e, 0x205c, 0x04fb, 0x09f6, 0x13ec, 0x27d8, + 0x0bf3, 0x17e6, 0x2fcc, 0x1bdb, 0x37b6, 0x2b2f, 0x121d, 0x243a, 0x0c37, 0x186e, 0x30dc, 0x25fb, 0x0fb5, 0x1f6a, 0x3ed4, 0x39eb, + 0x3795, 0x2b69, 0x1291, 0x2522, 0x0e07, 0x1c0e, 0x381c, 0x347b, 0x2cb5, 0x1d29, 0x3a52, 0x30e7, 0x258d, 0x0f59, 0x1eb2, 0x3d64, + 0x3e8b, 0x3955, 0x36e9, 0x2991, 0x1761, 0x2ec2, 0x19c7, 0x338e, 0x235f, 0x02fd, 0x05fa, 0x0bf4, 0x17e8, 0x2fd0, 0x1be3, 0x37c6, + 0x2bcf, 0x13dd, 0x27ba, 0x0b37, 0x166e, 0x2cdc, 0x1dfb, 0x3bf6, 0x33af, 0x231d, 0x0279, 0x04f2, 0x09e4, 0x13c8, 0x2790, 0x0b63, + 0x16c6, 0x2d8c, 0x1f5b, 0x3eb6, 0x392f, 0x361d, 0x2879, 0x14b1, 0x2962, 0x1687, 0x2d0e, 0x1e5f, 0x3cbe, 0x3d3f, 0x3e3d, 0x3839, + 0x3431, 0x2c21, 0x1c01, 0x3802, 0x3447, 0x2ccd, 0x1dd9, 0x3bb2, 0x3327, 0x220d, 0x0059, 0x00b2, 0x0164, 0x02c8, 0x0590, 0x0b20, + 0x1640, 0x2c80, 0x1d43, 0x3a86, 0x314f, 0x26dd, 0x09f9, 0x13f2, 0x27e4, 0x0b8b, 0x1716, 0x2e2c, 0x181b, 0x3036, 0x242f, 0x0c1d, + 0x183a, 0x3074, 0x24ab, 0x0d15, 0x1a2a, 0x3454, 0x2ceb, 0x1d95, 0x3b2a, 0x3217, 0x206d, 0x0499, 0x0932, 0x1264, 0x24c8, 0x0dd3, + 0x1ba6, 0x374c, 0x2adb, 0x11f5, 0x23ea, 0x0397, 0x072e, 0x0e5c, 0x1cb8, 0x3970, 0x36a3, 0x2905, 0x1649, 0x2c92, 0x1d67, 0x3ace, + 0x31df, 0x27fd, 0x0bb9, 0x1772, 0x2ee4, 0x198b, 0x3316, 0x226f, 0x009d, 0x013a, 0x0274, 0x04e8, 0x09d0, 0x13a0, 0x2740, 0x0ac3, + 0x1586, 0x2b0c, 0x125b, 0x24b6, 0x0d2f, 0x1a5e, 0x34bc, 0x2d3b, 0x1e35, 0x3c6a, 0x3c97, 0x3d6d, 0x3e99, 0x3971, 0x36a1, 0x2901, + 0x1641, 0x2c82, 0x1d47, 0x3a8e, 0x315f, 0x26fd, 0x09b9, 0x1372, 0x26e4, 0x098b, 0x1316, 0x262c, 0x081b, 0x1036, 0x206c, 0x049b, + 0x0936, 0x126c, 0x24d8, 0x0df3, 0x1be6, 0x37cc, 0x2bdb, 0x13f5, 0x27ea, 0x0b97, 0x172e, 0x2e5c, 0x18fb, 0x31f6, 0x27af, 0x0b1d, + 0x163a, 0x2c74, 0x1cab, 0x3956, 0x36ef, 0x299d, 0x1779, 0x2ef2, 0x19a7, 0x334e, 0x22df, 0x01fd, 0x03fa, 0x07f4, 0x0fe8, 0x1fd0, + 0x3fa0, 0x3b03, 0x3245, 0x20c9, 0x05d1, 0x0ba2, 0x1744, 0x2e88, 0x1953, 0x32a6, 0x210f, 0x065d, 0x0cba, 0x1974, 0x32e8, 0x2193, + 0x0765, 0x0eca, 0x1d94, 0x3b28, 0x3213, 0x2065, 0x0489, 0x0912, 0x1224, 0x2448, 0x0cd3, 0x19a6, 0x334c, 0x22db, 0x01f5, 0x03ea, + 0x07d4, 0x0fa8, 0x1f50, 0x3ea0, 0x3903, 0x3645, 0x28c9, 0x15d1, 0x2ba2, 0x1307, 0x260e, 0x085f, 0x10be, 0x217c, 0x06bb, 0x0d76, + 0x1aec, 0x35d8, 0x2ff3, 0x1ba5, 0x374a, 0x2ad7, 0x11ed, 0x23da, 0x03f7, 0x07ee, 0x0fdc, 0x1fb8, 0x3f70, 0x3aa3, 0x3105, 0x2649, + 0x08d1, 0x11a2, 0x2344, 0x02cb, 0x0596, 0x0b2c, 0x1658, 0x2cb0, 0x1d23, 0x3a46, 0x30cf, 0x25dd, 0x0ff9, 0x1ff2, 0x3fe4, 0x3b8b, + 0x3355, 0x22e9, 0x0191, 0x0322, 0x0644, 0x0c88, 0x1910, 0x3220, 0x2003, 0x0445, 0x088a, 0x1114, 0x2228, 0x0013, 0x0026, 0x004c, + 0x0098, 0x0130, 0x0260, 0x04c0, 0x0980, 0x1300, 0x2600, 0x0843, 0x1086, 0x210c, 0x065b, 0x0cb6, 0x196c, 0x32d8, 0x21f3, 0x07a5, + 0x0f4a, 0x1e94, 0x3d28, 0x3e13, 0x3865, 0x3489, 0x2d51, 0x1ee1, 0x3dc2, 0x3fc7, 0x3bcd, 0x33d9, 0x23f1, 0x03a1, 0x0742, 0x0e84, + 0x1d08, 0x3a10, 0x3063, 0x2485, 0x0d49, 0x1a92, 0x3524, 0x2e0b, 0x1855, 0x30aa, 0x2517, 0x0e6d, 0x1cda, 0x39b4, 0x372b, 0x2a15, + 0x1069, 0x20d2, 0x05e7, 0x0bce, 0x179c, 0x2f38, 0x1a33, 0x3466, 0x2c8f, 0x1d5d, 0x3aba, 0x3137, 0x262d, 0x0819, 0x1032, 0x2064, + 0x048b, 0x0916, 0x122c, 0x2458, 0x0cf3, 0x19e6, 0x33cc, 0x23db, 0x03f5, 0x07ea, 0x0fd4, 0x1fa8, 0x3f50, 0x3ae3, 0x3185, 0x2749, + 0x0ad1, 0x15a2, 0x2b44, 0x12cb, 0x2596, 0x0f6f, 0x1ede, 0x3dbc, 0x3f3b, 0x3a35, 0x3029, 0x2411, 0x0c61, 0x18c2, 0x3184, 0x274b, + 0x0ad5, 0x15aa, 0x2b54, 0x12eb, 0x25d6, 0x0fef, 0x1fde, 0x3fbc, 0x3b3b, 0x3235, 0x2029, 0x0411, 0x0822, 0x1044, 0x2088, 0x0553, + 0x0aa6, 0x154c, 0x2a98, 0x1173, 0x22e6, 0x018f, 0x031e, 0x063c, 0x0c78, 0x18f0, 0x31e0, 0x2783, 0x0b45, 0x168a, 0x2d14, 0x1e6b, + 0x3cd6, 0x3def, 0x3f9d, 0x3b79, 0x32b1, 0x2121, 0x0601, 0x0c02, 0x1804, 0x3008, 0x2453, 0x0ce5, 0x19ca, 0x3394, 0x236b, 0x0295, + 0x052a, 0x0a54, 0x14a8, 0x2950, 0x16e3, 0x2dc6, 0x1fcf, 0x3f9e, 0x3b7f, 0x32bd, 0x2139, 0x0631, 0x0c62, 0x18c4, 0x3188, 0x2753, + 0x0ae5, 0x15ca, 0x2b94, 0x136b, 0x26d6, 0x09ef, 0x13de, 0x27bc, 0x0b3b, 0x1676, 0x2cec, 0x1d9b, 0x3b36, 0x322f, 0x201d, 0x0479, + 0x08f2, 0x11e4, 0x23c8, 0x03d3, 0x07a6, 0x0f4c, 0x1e98, 0x3d30, 0x3e23, 0x3805, 0x3449, 0x2cd1, 0x1de1, 0x3bc2, 0x33c7, 0x23cd, + 0x03d9, 0x07b2, 0x0f64, 0x1ec8, 0x3d90, 0x3f63, 0x3a85, 0x3149, 0x26d1, 0x09e1, 0x13c2, 0x2784, 0x0b4b, 0x1696, 0x2d2c, 0x1e1b, + 0x3c36, 0x3c2f, 0x3c1d, 0x3c79, 0x3cb1, 0x3d21, 0x3e01, 0x3841, 0x34c1, 0x2dc1, 0x1fc1, 0x3f82, 0x3b47, 0x32cd, 0x21d9, 0x07f1, + 0x0fe2, 0x1fc4, 0x3f88, 0x3b53, 0x32e5, 0x2189, 0x0751, 0x0ea2, 0x1d44, 0x3a88, 0x3153, 0x26e5, 0x0989, 0x1312, 0x2624, 0x080b, + 0x1016, 0x202c, 0x041b, 0x0836, 0x106c, 0x20d8, 0x05f3, 0x0be6, 0x17cc, 0x2f98, 0x1b73, 0x36e6, 0x298f, 0x175d, 0x2eba, 0x1937, + 0x326e, 0x209f, 0x057d, 0x0afa, 0x15f4, 0x2be8, 0x1393, 0x2726, 0x0a0f, 0x141e, 0x283c, 0x143b, 0x2876, 0x14af, 0x295e, 0x16ff, + 0x2dfe, 0x1fbf, 0x3f7e, 0x3abf, 0x313d, 0x2639, 0x0831, 0x1062, 0x20c4, 0x05cb, 0x0b96, 0x172c, 0x2e58, 0x18f3, 0x31e6, 0x278f, + 0x0b5d, 0x16ba, 0x2d74, 0x1eab, 0x3d56, 0x3eef, 0x399d, 0x3779, 0x2ab1, 0x1121, 0x2242, 0x00c7, 0x018e, 0x031c, 0x0638, 0x0c70, + 0x18e0, 0x31c0, 0x27c3, 0x0bc5, 0x178a, 0x2f14, 0x1a6b, 0x34d6, 0x2def, 0x1f9d, 0x3f3a, 0x3a37, 0x302d, 0x2419, 0x0c71, 0x18e2, + 0x31c4, 0x27cb, 0x0bd5, 0x17aa, 0x2f54, 0x1aeb, 0x35d6, 0x2fef, 0x1b9d, 0x373a, 0x2a37, 0x102d, 0x205a, 0x04f7, 0x09ee, 0x13dc, + 0x27b8, 0x0b33, 0x1666, 0x2ccc, 0x1ddb, 0x3bb6, 0x332f, 0x221d, 0x0079, 0x00f2, 0x01e4, 0x03c8, 0x0790, 0x0f20, 0x1e40, 0x3c80, + 0x3d43, 0x3ec5, 0x39c9, 0x37d1, 0x2be1, 0x1381, 0x2702, 0x0a47, 0x148e, 0x291c, 0x167b, 0x2cf6, 0x1daf, 0x3b5e, 0x32ff, 0x21bd, + 0x0739, 0x0e72, 0x1ce4, 0x39c8, 0x37d3, 0x2be5, 0x1389, 0x2712, 0x0a67, 0x14ce, 0x299c, 0x177b, 0x2ef6, 0x19af, 0x335e, 0x22ff, + 0x01bd, 0x037a, 0x06f4, 0x0de8, 0x1bd0, 0x37a0, 0x2b03, 0x1245, 0x248a, 0x0d57, 0x1aae, 0x355c, 0x2efb, 0x19b5, 0x336a, 0x2297, + 0x016d, 0x02da, 0x05b4, 0x0b68, 0x16d0, 0x2da0, 0x1f03, 0x3e06, 0x384f, 0x34dd, 0x2df9, 0x1fb1, 0x3f62, 0x3a87, 0x314d, 0x26d9, + 0x09f1, 0x13e2, 0x27c4, 0x0bcb, 0x1796, 0x2f2c, 0x1a1b, 0x3436, 0x2c2f, 0x1c1d, 0x383a, 0x3437, 0x2c2d, 0x1c19, 0x3832, 0x3427, + 0x2c0d, 0x1c59, 0x38b2, 0x3527, 0x2e0d, 0x1859, 0x30b2, 0x2527, 0x0e0d, 0x1c1a, 0x3834, 0x342b, 0x2c15, 0x1c69, 0x38d2, 0x35e7, + 0x2f8d, 0x1b59, 0x36b2, 0x2927, 0x160d, 0x2c1a, 0x1c77, 0x38ee, 0x359f, 0x2f7d, 0x1ab9, 0x3572, 0x2ea7, 0x190d, 0x321a, 0x2077, + 0x04ad, 0x095a, 0x12b4, 0x2568, 0x0e93, 0x1d26, 0x3a4c, 0x30db, 0x25f5, 0x0fa9, 0x1f52, 0x3ea4, 0x390b, 0x3655, 0x28e9, 0x1591, + 0x2b22, 0x1207, 0x240e, 0x0c5f, 0x18be, 0x317c, 0x26bb, 0x0935, 0x126a, 0x24d4, 0x0deb, 0x1bd6, 0x37ac, 0x2b1b, 0x1275, 0x24ea, + 0x0d97, 0x1b2e, 0x365c, 0x28fb, 0x15b5, 0x2b6a, 0x1297, 0x252e, 0x0e1f, 0x1c3e, 0x387c, 0x34bb, 0x2d35, 0x1e29, 0x3c52, 0x3ce7, + 0x3d8d, 0x3f59, 0x3af1, 0x31a1, 0x2701, 0x0a41, 0x1482, 0x2904, 0x164b, 0x2c96, 0x1d6f, 0x3ade, 0x31ff, 0x27bd, 0x0b39, 0x1672, + 0x2ce4, 0x1d8b, 0x3b16, 0x326f, 0x209d, 0x0579, 0x0af2, 0x15e4, 0x2bc8, 0x13d3, 0x27a6, 0x0b0f, 0x161e, 0x2c3c, 0x1c3b, 0x3876, + 0x34af, 0x2d1d, 0x1e79, 0x3cf2, 0x3da7, 0x3f0d, 0x3a59, 0x30f1, 0x25a1, 0x0f01, 0x1e02, 0x3c04, 0x3c4b, 0x3cd5, 0x3de9, 0x3f91, + 0x3b61, 0x3281, 0x2141, 0x06c1, 0x0d82, 0x1b04, 0x3608, 0x2853, 0x14e5, 0x29ca, 0x17d7, 0x2fae, 0x1b1f, 0x363e, 0x283f, 0x143d, + 0x287a, 0x14b7, 0x296e, 0x169f, 0x2d3e, 0x1e3f, 0x3c7e, 0x3cbf, 0x3d3d, 0x3e39, 0x3831, 0x3421, 0x2c01, 0x1c41, 0x3882, 0x3547, + 0x2ecd, 0x19d9, 0x33b2, 0x2327, 0x020d, 0x041a, 0x0834, 0x1068, 0x20d0, 0x05e3, 0x0bc6, 0x178c, 0x2f18, 0x1a73, 0x34e6, 0x2d8f, + 0x1f5d, 0x3eba, 0x3937, 0x362d, 0x2819, 0x1471, 0x28e2, 0x1587, 0x2b0e, 0x125f, 0x24be, 0x0d3f, 0x1a7e, 0x34fc, 0x2dbb, 0x1f35, + 0x3e6a, 0x3897, 0x356d, 0x2e99, 0x1971, 0x32e2, 0x2187, 0x074d, 0x0e9a, 0x1d34, 0x3a68, 0x3093, 0x2565, 0x0e89, 0x1d12, 0x3a24, + 0x300b, 0x2455, 0x0ce9, 0x19d2, 0x33a4, 0x230b, 0x0255, 0x04aa, 0x0954, 0x12a8, 0x2550, 0x0ee3, 0x1dc6, 0x3b8c, 0x335b, 0x22f5, + 0x01a9, 0x0352, 0x06a4, 0x0d48, 0x1a90, 0x3520, 0x2e03, 0x1845, 0x308a, 0x2557, 0x0eed, 0x1dda, 0x3bb4, 0x332b, 0x2215, 0x0069, + 0x00d2, 0x01a4, 0x0348, 0x0690, 0x0d20, 0x1a40, 0x3480, 0x2d43, 0x1ec5, 0x3d8a, 0x3f57, 0x3aed, 0x3199, 0x2771, 0x0aa1, 0x1542, + 0x2a84, 0x114b, 0x2296, 0x016f, 0x02de, 0x05bc, 0x0b78, 0x16f0, 0x2de0, 0x1f83, 0x3f06, 0x3a4f, 0x30dd, 0x25f9, 0x0fb1, 0x1f62, + 0x3ec4, 0x39cb, 0x37d5, 0x2be9, 0x1391, 0x2722, 0x0a07, 0x140e, 0x281c, 0x147b, 0x28f6, 0x15af, 0x2b5e, 0x12ff, 0x25fe, 0x0fbf, + 0x1f7e, 0x3efc, 0x39bb, 0x3735, 0x2a29, 0x1011, 0x2022, 0x0407, 0x080e, 0x101c, 0x2038, 0x0433, 0x0866, 0x10cc, 0x2198, 0x0773, + 0x0ee6, 0x1dcc, 0x3b98, 0x3373, 0x22a5, 0x0109, 0x0212, 0x0424, 0x0848, 0x1090, 0x2120, 0x0603, 0x0c06, 0x180c, 0x3018, 0x2473, + 0x0ca5, 0x194a, 0x3294, 0x216b, 0x0695, 0x0d2a, 0x1a54, 0x34a8, 0x2d13, 0x1e65, 0x3cca, 0x3dd7, 0x3fed, 0x3b99, 0x3371, 0x22a1, + 0x0101, 0x0202, 0x0404, 0x0808, 0x1010, 0x2020, 0x0403, 0x0806, 0x100c, 0x2018, 0x0473, 0x08e6, 0x11cc, 0x2398, 0x0373, 0x06e6, + 0x0dcc, 0x1b98, 0x3730, 0x2a23, 0x1005, 0x200a, 0x0457, 0x08ae, 0x115c, 0x22b8, 0x0133, 0x0266, 0x04cc, 0x0998, 0x1330, 0x2660, + 0x0883, 0x1106, 0x220c, 0x005b, 0x00b6, 0x016c, 0x02d8, 0x05b0, 0x0b60, 0x16c0, 0x2d80, 0x1f43, 0x3e86, 0x394f, 0x36dd, 0x29f9, + 0x17b1, 0x2f62, 0x1a87, 0x350e, 0x2e5f, 0x18fd, 0x31fa, 0x27b7, 0x0b2d, 0x165a, 0x2cb4, 0x1d2b, 0x3a56, 0x30ef, 0x259d, 0x0f79, + 0x1ef2, 0x3de4, 0x3f8b, 0x3b55, 0x32e9, 0x2191, 0x0761, 0x0ec2, 0x1d84, 0x3b08, 0x3253, 0x20e5, 0x0589, 0x0b12, 0x1624, 0x2c48, + 0x1cd3, 0x39a6, 0x370f, 0x2a5d, 0x10f9, 0x21f2, 0x07a7, 0x0f4e, 0x1e9c, 0x3d38, 0x3e33, 0x3825, 0x3409, 0x2c51, 0x1ce1, 0x39c2, + 0x37c7, 0x2bcd, 0x13d9, 0x27b2, 0x0b27, 0x164e, 0x2c9c, 0x1d7b, 0x3af6, 0x31af, 0x271d, 0x0a79, 0x14f2, 0x29e4, 0x178b, 0x2f16, + 0x1a6f, 0x34de, 0x2dff, 0x1fbd, 0x3f7a, 0x3ab7, 0x312d, 0x2619, 0x0871, 0x10e2, 0x21c4, 0x07cb, 0x0f96, 0x1f2c, 0x3e58, 0x38f3, + 0x35a5, 0x2f09, 0x1a51, 0x34a2, 0x2d07, 0x1e4d, 0x3c9a, 0x3d77, 0x3ead, 0x3919, 0x3671, 0x28a1, 0x1501, 0x2a02, 0x1047, 0x208e, + 0x055f, 0x0abe, 0x157c, 0x2af8, 0x11b3, 0x2366, 0x028f, 0x051e, 0x0a3c, 0x1478, 0x28f0, 0x15a3, 0x2b46, 0x12cf, 0x259e, 0x0f7f, + 0x1efe, 0x3dfc, 0x3fbb, 0x3b35, 0x3229, 0x2011, 0x0461, 0x08c2, 0x1184, 0x2308, 0x0253, 0x04a6, 0x094c, 0x1298, 0x2530, 0x0e23, + 0x1c46, 0x388c, 0x355b, 0x2ef5, 0x19a9, 0x3352, 0x22e7, 0x018d, 0x031a, 0x0634, 0x0c68, 0x18d0, 0x31a0, 0x2703, 0x0a45, 0x148a, + 0x2914, 0x166b, 0x2cd6, 0x1def, 0x3bde, 0x33ff, 0x23bd, 0x0339, 0x0672, 0x0ce4, 0x19c8, 0x3390, 0x2363, 0x0285, 0x050a, 0x0a14, + 0x1428, 0x2850, 0x14e3, 0x29c6, 0x17cf, 0x2f9e, 0x1b7f, 0x36fe, 0x29bf, 0x173d, 0x2e7a, 0x18b7, 0x316e, 0x269f, 0x097d, 0x12fa, + 0x25f4, 0x0fab, 0x1f56, 0x3eac, 0x391b, 0x3675, 0x28a9, 0x1511, 0x2a22, 0x1007, 0x200e, 0x045f, 0x08be, 0x117c, 0x22f8, 0x01b3, + 0x0366, 0x06cc, 0x0d98, 0x1b30, 0x3660, 0x2883, 0x1545, 0x2a8a, 0x1157, 0x22ae, 0x011f, 0x023e, 0x047c, 0x08f8, 0x11f0, 0x23e0, + 0x0383, 0x0706, 0x0e0c, 0x1c18, 0x3830, 0x3423, 0x2c05, 0x1c49, 0x3892, 0x3567, 0x2e8d, 0x1959, 0x32b2, 0x2127, 0x060d, 0x0c1a, + 0x1834, 0x3068, 0x2493, 0x0d65, 0x1aca, 0x3594, 0x2f6b, 0x1a95, 0x352a, 0x2e17, 0x186d, 0x30da, 0x25f7, 0x0fad, 0x1f5a, 0x3eb4, + 0x392b, 0x3615, 0x2869, 0x1491, 0x2922, 0x1607, 0x2c0e, 0x1c5f, 0x38be, 0x353f, 0x2e3d, 0x1839, 0x3072, 0x24a7, 0x0d0d, 0x1a1a, + 0x3434, 0x2c2b, 0x1c15, 0x382a, 0x3417, 0x2c6d, 0x1c99, 0x3932, 0x3627, 0x280d, 0x1459, 0x28b2, 0x1527, 0x2a4e, 0x10df, 0x21be, + 0x073f, 0x0e7e, 0x1cfc, 0x39f8, 0x37b3, 0x2b25, 0x1209, 0x2412, 0x0c67, 0x18ce, 0x319c, 0x277b, 0x0ab5, 0x156a, 0x2ad4, 0x11eb, + 0x23d6, 0x03ef, 0x07de, 0x0fbc, 0x1f78, 0x3ef0, 0x39a3, 0x3705, 0x2a49, 0x10d1, 0x21a2, 0x0707, 0x0e0e, 0x1c1c, 0x3838, 0x3433, + 0x2c25, 0x1c09, 0x3812, 0x3467, 0x2c8d, 0x1d59, 0x3ab2, 0x3127, 0x260d, 0x0859, 0x10b2, 0x2164, 0x068b, 0x0d16, 0x1a2c, 0x3458, + 0x2cf3, 0x1da5, 0x3b4a, 0x32d7, 0x21ed, 0x0799, 0x0f32, 0x1e64, 0x3cc8, 0x3dd3, 0x3fe5, 0x3b89, 0x3351, 0x22e1, 0x0181, 0x0302, + 0x0604, 0x0c08, 0x1810, 0x3020, 0x2403, 0x0c45, 0x188a, 0x3114, 0x266b, 0x0895, 0x112a, 0x2254, 0x00eb, 0x01d6, 0x03ac, 0x0758, + 0x0eb0, 0x1d60, 0x3ac0, 0x31c3, 0x27c5, 0x0bc9, 0x1792, 0x2f24, 0x1a0b, 0x3416, 0x2c6f, 0x1c9d, 0x393a, 0x3637, 0x282d, 0x1419, + 0x2832, 0x1427, 0x284e, 0x14df, 0x29be, 0x173f, 0x2e7e, 0x18bf, 0x317e, 0x26bf, 0x093d, 0x127a, 0x24f4, 0x0dab, 0x1b56, 0x36ac, + 0x291b, 0x1675, 0x2cea, 0x1d97, 0x3b2e, 0x321f, 0x207d, 0x04b9, 0x0972, 0x12e4, 0x25c8, 0x0fd3, 0x1fa6, 0x3f4c, 0x3adb, 0x31f5, + 0x27a9, 0x0b11, 0x1622, 0x2c44, 0x1ccb, 0x3996, 0x376f, 0x2a9d, 0x1179, 0x22f2, 0x01a7, 0x034e, 0x069c, 0x0d38, 0x1a70, 0x34e0, + 0x2d83, 0x1f45, 0x3e8a, 0x3957, 0x36ed, 0x2999, 0x1771, 0x2ee2, 0x1987, 0x330e, 0x225f, 0x00fd, 0x01fa, 0x03f4, 0x07e8, 0x0fd0, + 0x1fa0, 0x3f40, 0x3ac3, 0x31c5, 0x27c9, 0x0bd1, 0x17a2, 0x2f44, 0x1acb, 0x3596, 0x2f6f, 0x1a9d, 0x353a, 0x2e37, 0x182d, 0x305a, + 0x24f7, 0x0dad, 0x1b5a, 0x36b4, 0x292b, 0x1615, 0x2c2a, 0x1c17, 0x382e, 0x341f, 0x2c7d, 0x1cb9, 0x3972, 0x36a7, 0x290d, 0x1659, + 0x2cb2, 0x1d27, 0x3a4e, 0x30df, 0x25fd, 0x0fb9, 0x1f72, 0x3ee4, 0x398b, 0x3755, 0x2ae9, 0x1191, 0x2322, 0x0207, 0x040e, 0x081c, + 0x1038, 0x2070, 0x04a3, 0x0946, 0x128c, 0x2518, 0x0e73, 0x1ce6, 0x39cc, 0x37db, 0x2bf5, 0x13a9, 0x2752, 0x0ae7, 0x15ce, 0x2b9c, + 0x137b, 0x26f6, 0x09af, 0x135e, 0x26bc, 0x093b, 0x1276, 0x24ec, 0x0d9b, 0x1b36, 0x366c, 0x289b, 0x1575, 0x2aea, 0x1197, 0x232e, + 0x021f, 0x043e, 0x087c, 0x10f8, 0x21f0, 0x07a3, 0x0f46, 0x1e8c, 0x3d18, 0x3e73, 0x38a5, 0x3509, 0x2e51, 0x18e1, 0x31c2, 0x27c7, + 0x0bcd, 0x179a, 0x2f34, 0x1a2b, 0x3456, 0x2cef, 0x1d9d, 0x3b3a, 0x3237, 0x202d, 0x0419, 0x0832, 0x1064, 0x20c8, 0x05d3, 0x0ba6, + 0x174c, 0x2e98, 0x1973, 0x32e6, 0x218f, 0x075d, 0x0eba, 0x1d74, 0x3ae8, 0x3193, 0x2765, 0x0a89, 0x1512, 0x2a24, 0x100b, 0x2016, + 0x046f, 0x08de, 0x11bc, 0x2378, 0x02b3, 0x0566, 0x0acc, 0x1598, 0x2b30, 0x1223, 0x2446, 0x0ccf, 0x199e, 0x333c, 0x223b, 0x0035, + 0x006a, 0x00d4, 0x01a8, 0x0350, 0x06a0, 0x0d40, 0x1a80, 0x3500, 0x2e43, 0x18c5, 0x318a, 0x2757, 0x0aed, 0x15da, 0x2bb4, 0x132b, + 0x2656, 0x08ef, 0x11de, 0x23bc, 0x033b, 0x0676, 0x0cec, 0x19d8, 0x33b0, 0x2323, 0x0205, 0x040a, 0x0814, 0x1028, 0x2050, 0x04e3, + 0x09c6, 0x138c, 0x2718, 0x0a73, 0x14e6, 0x29cc, 0x17db, 0x2fb6, 0x1b2f, 0x365e, 0x28ff, 0x15bd, 0x2b7a, 0x12b7, 0x256e, 0x0e9f, + 0x1d3e, 0x3a7c, 0x30bb, 0x2535, 0x0e29, 0x1c52, 0x38a4, 0x350b, 0x2e55, 0x18e9, 0x31d2, 0x27e7, 0x0b8d, 0x171a, 0x2e34, 0x182b, + 0x3056, 0x24ef, 0x0d9d, 0x1b3a, 0x3674, 0x28ab, 0x1515, 0x2a2a, 0x1017, 0x202e, 0x041f, 0x083e, 0x107c, 0x20f8, 0x05b3, 0x0b66, + 0x16cc, 0x2d98, 0x1f73, 0x3ee6, 0x398f, 0x375d, 0x2af9, 0x11b1, 0x2362, 0x0287, 0x050e, 0x0a1c, 0x1438, 0x2870, 0x14a3, 0x2946, + 0x16cf, 0x2d9e, 0x1f7f, 0x3efe, 0x39bf, 0x373d, 0x2a39, 0x1031, 0x2062, 0x0487, 0x090e, 0x121c, 0x2438, 0x0c33, 0x1866, 0x30cc, + 0x25db, 0x0ff5, 0x1fea, 0x3fd4, 0x3beb, 0x3395, 0x2369, 0x0291, 0x0522, 0x0a44, 0x1488, 0x2910, 0x1663, 0x2cc6, 0x1dcf, 0x3b9e, + 0x337f, 0x22bd, 0x0139, 0x0272, 0x04e4, 0x09c8, 0x1390, 0x2720, 0x0a03, 0x1406, 0x280c, 0x145b, 0x28b6, 0x152f, 0x2a5e, 0x10ff, + 0x21fe, 0x07bf, 0x0f7e, 0x1efc, 0x3df8, 0x3fb3, 0x3b25, 0x3209, 0x2051, 0x04e1, 0x09c2, 0x1384, 0x2708, 0x0a53, 0x14a6, 0x294c, + 0x16db, 0x2db6, 0x1f2f, 0x3e5e, 0x38ff, 0x35bd, 0x2f39, 0x1a31, 0x3462, 0x2c87, 0x1d4d, 0x3a9a, 0x3177, 0x26ad, 0x0919, 0x1232, + 0x2464, 0x0c8b, 0x1916, 0x322c, 0x201b, 0x0475, 0x08ea, 0x11d4, 0x23a8, 0x0313, 0x0626, 0x0c4c, 0x1898, 0x3130, 0x2623, 0x0805, + 0x100a, 0x2014, 0x046b, 0x08d6, 0x11ac, 0x2358, 0x02f3, 0x05e6, 0x0bcc, 0x1798, 0x2f30, 0x1a23, 0x3446, 0x2ccf, 0x1ddd, 0x3bba, + 0x3337, 0x222d, 0x0019, 0x0032, 0x0064, 0x00c8, 0x0190, 0x0320, 0x0640, 0x0c80, 0x1900, 0x3200, 0x2043, 0x04c5, 0x098a, 0x1314, + 0x2628, 0x0813, 0x1026, 0x204c, 0x04db, 0x09b6, 0x136c, 0x26d8, 0x09f3, 0x13e6, 0x27cc, 0x0bdb, 0x17b6, 0x2f6c, 0x1a9b, 0x3536, + 0x2e2f, 0x181d, 0x303a, 0x2437, 0x0c2d, 0x185a, 0x30b4, 0x252b, 0x0e15, 0x1c2a, 0x3854, 0x34eb, 0x2d95, 0x1f69, 0x3ed2, 0x39e7, + 0x378d, 0x2b59, 0x12f1, 0x25e2, 0x0f87, 0x1f0e, 0x3e1c, 0x387b, 0x34b5, 0x2d29, 0x1e11, 0x3c22, 0x3c07, 0x3c4d, 0x3cd9, 0x3df1, + 0x3fa1, 0x3b01, 0x3241, 0x20c1, 0x05c1, 0x0b82, 0x1704, 0x2e08, 0x1853, 0x30a6, 0x250f, 0x0e5d, 0x1cba, 0x3974, 0x36ab, 0x2915, + 0x1669, 0x2cd2, 0x1de7, 0x3bce, 0x33df, 0x23fd, 0x03b9, 0x0772, 0x0ee4, 0x1dc8, 0x3b90, 0x3363, 0x2285, 0x0149, 0x0292, 0x0524, + 0x0a48, 0x1490, 0x2920, 0x1603, 0x2c06, 0x1c4f, 0x389e, 0x357f, 0x2ebd, 0x1939, 0x3272, 0x20a7, 0x050d, 0x0a1a, 0x1434, 0x2868, + 0x1493, 0x2926, 0x160f, 0x2c1e, 0x1c7f, 0x38fe, 0x35bf, 0x2f3d, 0x1a39, 0x3472, 0x2ca7, 0x1d0d, 0x3a1a, 0x3077, 0x24ad, 0x0d19, + 0x1a32, 0x3464, 0x2c8b, 0x1d55, 0x3aaa, 0x3117, 0x266d, 0x0899, 0x1132, 0x2264, 0x008b, 0x0116, 0x022c, 0x0458, 0x08b0, 0x1160, + 0x22c0, 0x01c3, 0x0386, 0x070c, 0x0e18, 0x1c30, 0x3860, 0x3483, 0x2d45, 0x1ec9, 0x3d92, 0x3f67, 0x3a8d, 0x3159, 0x26f1, 0x09a1, + 0x1342, 0x2684, 0x094b, 0x1296, 0x252c, 0x0e1b, 0x1c36, 0x386c, 0x349b, 0x2d75, 0x1ea9, 0x3d52, 0x3ee7, 0x398d, 0x3759, 0x2af1, + 0x11a1, 0x2342, 0x02c7, 0x058e, 0x0b1c, 0x1638, 0x2c70, 0x1ca3, 0x3946, 0x36cf, 0x29dd, 0x17f9, 0x2ff2, 0x1ba7, 0x374e, 0x2adf, + 0x11fd, 0x23fa, 0x03b7, 0x076e, 0x0edc, 0x1db8, 0x3b70, 0x32a3, 0x2105, 0x0649, 0x0c92, 0x1924, 0x3248, 0x20d3, 0x05e5, 0x0bca, + 0x1794, 0x2f28, 0x1a13, 0x3426, 0x2c0f, 0x1c5d, 0x38ba, 0x3537, 0x2e2d, 0x1819, 0x3032, 0x2427, 0x0c0d, 0x181a, 0x3034, 0x242b, + 0x0c15, 0x182a, 0x3054, 0x24eb, 0x0d95, 0x1b2a, 0x3654, 0x28eb, 0x1595, 0x2b2a, 0x1217, 0x242e, 0x0c1f, 0x183e, 0x307c, 0x24bb, + 0x0d35, 0x1a6a, 0x34d4, 0x2deb, 0x1f95, 0x3f2a, 0x3a17, 0x306d, 0x2499, 0x0d71, 0x1ae2, 0x35c4, 0x2fcb, 0x1bd5, 0x37aa, 0x2b17, + 0x126d, 0x24da, 0x0df7, 0x1bee, 0x37dc, 0x2bfb, 0x13b5, 0x276a, 0x0a97, 0x152e, 0x2a5c, 0x10fb, 0x21f6, 0x07af, 0x0f5e, 0x1ebc, + 0x3d78, 0x3eb3, 0x3925, 0x3609, 0x2851, 0x14e1, 0x29c2, 0x17c7, 0x2f8e, 0x1b5f, 0x36be, 0x293f, 0x163d, 0x2c7a, 0x1cb7, 0x396e, + 0x369f, 0x297d, 0x16b9, 0x2d72, 0x1ea7, 0x3d4e, 0x3edf, 0x39fd, 0x37b9, 0x2b31, 0x1221, 0x2442, 0x0cc7, 0x198e, 0x331c, 0x227b, + 0x00b5, 0x016a, 0x02d4, 0x05a8, 0x0b50, 0x16a0, 0x2d40, 0x1ec3, 0x3d86, 0x3f4f, 0x3add, 0x31f9, 0x27b1, 0x0b21, 0x1642, 0x2c84, + 0x1d4b, 0x3a96, 0x316f, 0x269d, 0x0979, 0x12f2, 0x25e4, 0x0f8b, 0x1f16, 0x3e2c, 0x381b, 0x3475, 0x2ca9, 0x1d11, 0x3a22, 0x3007, + 0x244d, 0x0cd9, 0x19b2, 0x3364, 0x228b, 0x0155, 0x02aa, 0x0554, 0x0aa8, 0x1550, 0x2aa0, 0x1103, 0x2206, 0x004f, 0x009e, 0x013c, + 0x0278, 0x04f0, 0x09e0, 0x13c0, 0x2780, 0x0b43, 0x1686, 0x2d0c, 0x1e5b, 0x3cb6, 0x3d2f, 0x3e1d, 0x3879, 0x34b1, 0x2d21, 0x1e01, + 0x3c02, 0x3c47, 0x3ccd, 0x3dd9, 0x3ff1, 0x3ba1, 0x3301, 0x2241, 0x00c1, 0x0182, 0x0304, 0x0608, 0x0c10, 0x1820, 0x3040, 0x24c3, + 0x0dc5, 0x1b8a, 0x3714, 0x2a6b, 0x1095, 0x212a, 0x0617, 0x0c2e, 0x185c, 0x30b8, 0x2533, 0x0e25, 0x1c4a, 0x3894, 0x356b, 0x2e95, + 0x1969, 0x32d2, 0x21e7, 0x078d, 0x0f1a, 0x1e34, 0x3c68, 0x3c93, 0x3d65, 0x3e89, 0x3951, 0x36e1, 0x2981, 0x1741, 0x2e82, 0x1947, + 0x328e, 0x215f, 0x06fd, 0x0dfa, 0x1bf4, 0x37e8, 0x2b93, 0x1365, 0x26ca, 0x09d7, 0x13ae, 0x275c, 0x0afb, 0x15f6, 0x2bec, 0x139b, + 0x2736, 0x0a2f, 0x145e, 0x28bc, 0x153b, 0x2a76, 0x10af, 0x215e, 0x06ff, 0x0dfe, 0x1bfc, 0x37f8, 0x2bb3, 0x1325, 0x264a, 0x08d7, + 0x11ae, 0x235c, 0x02fb, 0x05f6, 0x0bec, 0x17d8, 0x2fb0, 0x1b23, 0x3646, 0x28cf, 0x15dd, 0x2bba, 0x1337, 0x266e, 0x089f, 0x113e, + 0x227c, 0x00bb, 0x0176, 0x02ec, 0x05d8, 0x0bb0, 0x1760, 0x2ec0, 0x19c3, 0x3386, 0x234f, 0x02dd, 0x05ba, 0x0b74, 0x16e8, 0x2dd0, + 0x1fe3, 0x3fc6, 0x3bcf, 0x33dd, 0x23f9, 0x03b1, 0x0762, 0x0ec4, 0x1d88, 0x3b10, 0x3263, 0x2085, 0x0549, 0x0a92, 0x1524, 0x2a48, + 0x10d3, 0x21a6, 0x070f, 0x0e1e, 0x1c3c, 0x3878, 0x34b3, 0x2d25, 0x1e09, 0x3c12, 0x3c67, 0x3c8d, 0x3d59, 0x3ef1, 0x39a1, 0x3701, + 0x2a41, 0x10c1, 0x2182, 0x0747, 0x0e8e, 0x1d1c, 0x3a38, 0x3033, 0x2425, 0x0c09, 0x1812, 0x3024, 0x240b, 0x0c55, 0x18aa, 0x3154, + 0x26eb, 0x0995, 0x132a, 0x2654, 0x08eb, 0x11d6, 0x23ac, 0x031b, 0x0636, 0x0c6c, 0x18d8, 0x31b0, 0x2723, 0x0a05, 0x140a, 0x2814, + 0x146b, 0x28d6, 0x15ef, 0x2bde, 0x13ff, 0x27fe, 0x0bbf, 0x177e, 0x2efc, 0x19bb, 0x3376, 0x22af, 0x011d, 0x023a, 0x0474, 0x08e8, + 0x11d0, 0x23a0, 0x0303, 0x0606, 0x0c0c, 0x1818, 0x3030, 0x2423, 0x0c05, 0x180a, 0x3014, 0x246b, 0x0c95, 0x192a, 0x3254, 0x20eb, + 0x0595, 0x0b2a, 0x1654, 0x2ca8, 0x1d13, 0x3a26, 0x300f, 0x245d, 0x0cf9, 0x19f2, 0x33e4, 0x238b, 0x0355, 0x06aa, 0x0d54, 0x1aa8, + 0x3550, 0x2ee3, 0x1985, 0x330a, 0x2257, 0x00ed, 0x01da, 0x03b4, 0x0768, 0x0ed0, 0x1da0, 0x3b40, 0x32c3, 0x21c5, 0x07c9, 0x0f92, + 0x1f24, 0x3e48, 0x38d3, 0x35e5, 0x2f89, 0x1b51, 0x36a2, 0x2907, 0x164d, 0x2c9a, 0x1d77, 0x3aee, 0x319f, 0x277d, 0x0ab9, 0x1572, + 0x2ae4, 0x118b, 0x2316, 0x026f, 0x04de, 0x09bc, 0x1378, 0x26f0, 0x09a3, 0x1346, 0x268c, 0x095b, 0x12b6, 0x256c, 0x0e9b, 0x1d36, + 0x3a6c, 0x309b, 0x2575, 0x0ea9, 0x1d52, 0x3aa4, 0x310b, 0x2655, 0x08e9, 0x11d2, 0x23a4, 0x030b, 0x0616, 0x0c2c, 0x1858, 0x30b0, + 0x2523, 0x0e05, 0x1c0a, 0x3814, 0x346b, 0x2c95, 0x1d69, 0x3ad2, 0x31e7, 0x278d, 0x0b59, 0x16b2, 0x2d64, 0x1e8b, 0x3d16, 0x3e6f, + 0x389d, 0x3579, 0x2eb1, 0x1921, 0x3242, 0x20c7, 0x05cd, 0x0b9a, 0x1734, 0x2e68, 0x1893, 0x3126, 0x260f, 0x085d, 0x10ba, 0x2174, + 0x06ab, 0x0d56, 0x1aac, 0x3558, 0x2ef3, 0x19a5, 0x334a, 0x22d7, 0x01ed, 0x03da, 0x07b4, 0x0f68, 0x1ed0, 0x3da0, 0x3f03, 0x3a45, + 0x30c9, 0x25d1, 0x0fe1, 0x1fc2, 0x3f84, 0x3b4b, 0x32d5, 0x21e9, 0x0791, 0x0f22, 0x1e44, 0x3c88, 0x3d53, 0x3ee5, 0x3989, 0x3751, + 0x2ae1, 0x1181, 0x2302, 0x0247, 0x048e, 0x091c, 0x1238, 0x2470, 0x0ca3, 0x1946, 0x328c, 0x215b, 0x06f5, 0x0dea, 0x1bd4, 0x37a8, + 0x2b13, 0x1265, 0x24ca, 0x0dd7, 0x1bae, 0x375c, 0x2afb, 0x11b5, 0x236a, 0x0297, 0x052e, 0x0a5c, 0x14b8, 0x2970, 0x16a3, 0x2d46, + 0x1ecf, 0x3d9e, 0x3f7f, 0x3abd, 0x3139, 0x2631, 0x0821, 0x1042, 0x2084, 0x054b, 0x0a96, 0x152c, 0x2a58, 0x10f3, 0x21e6, 0x078f, + 0x0f1e, 0x1e3c, 0x3c78, 0x3cb3, 0x3d25, 0x3e09, 0x3851, 0x34e1, 0x2d81, 0x1f41, 0x3e82, 0x3947, 0x36cd, 0x29d9, 0x17f1, 0x2fe2, + 0x1b87, 0x370e, 0x2a5f, 0x10fd, 0x21fa, 0x07b7, 0x0f6e, 0x1edc, 0x3db8, 0x3f33, 0x3a25, 0x3009, 0x2451, 0x0ce1, 0x19c2, 0x3384, + 0x234b, 0x02d5, 0x05aa, 0x0b54, 0x16a8, 0x2d50, 0x1ee3, 0x3dc6, 0x3fcf, 0x3bdd, 0x33f9, 0x23b1, 0x0321, 0x0642, 0x0c84, 0x1908, + 0x3210, 0x2063, 0x0485, 0x090a, 0x1214, 0x2428, 0x0c13, 0x1826, 0x304c, 0x24db, 0x0df5, 0x1bea, 0x37d4, 0x2beb, 0x1395, 0x272a, + 0x0a17, 0x142e, 0x285c, 0x14fb, 0x29f6, 0x17af, 0x2f5e, 0x1aff, 0x35fe, 0x2fbf, 0x1b3d, 0x367a, 0x28b7, 0x152d, 0x2a5a, 0x10f7, + 0x21ee, 0x079f, 0x0f3e, 0x1e7c, 0x3cf8, 0x3db3, 0x3f25, 0x3a09, 0x3051, 0x24e1, 0x0d81, 0x1b02, 0x3604, 0x284b, 0x14d5, 0x29aa, + 0x1717, 0x2e2e, 0x181f, 0x303e, 0x243f, 0x0c3d, 0x187a, 0x30f4, 0x25ab, 0x0f15, 0x1e2a, 0x3c54, 0x3ceb, 0x3d95, 0x3f69, 0x3a91, + 0x3161, 0x2681, 0x0941, 0x1282, 0x2504, 0x0e4b, 0x1c96, 0x392c, 0x361b, 0x2875, 0x14a9, 0x2952, 0x16e7, 0x2dce, 0x1fdf, 0x3fbe, + 0x3b3f, 0x323d, 0x2039, 0x0431, 0x0862, 0x10c4, 0x2188, 0x0753, 0x0ea6, 0x1d4c, 0x3a98, 0x3173, 0x26a5, 0x0909, 0x1212, 0x2424, + 0x0c0b, 0x1816, 0x302c, 0x241b, 0x0c75, 0x18ea, 0x31d4, 0x27eb, 0x0b95, 0x172a, 0x2e54, 0x18eb, 0x31d6, 0x27ef, 0x0b9d, 0x173a, + 0x2e74, 0x18ab, 0x3156, 0x26ef, 0x099d, 0x133a, 0x2674, 0x08ab, 0x1156, 0x22ac, 0x011b, 0x0236, 0x046c, 0x08d8, 0x11b0, 0x2360, + 0x0283, 0x0506, 0x0a0c, 0x1418, 0x2830, 0x1423, 0x2846, 0x14cf, 0x299e, 0x177f, 0x2efe, 0x19bf, 0x337e, 0x22bf, 0x013d, 0x027a, + 0x04f4, 0x09e8, 0x13d0, 0x27a0, 0x0b03, 0x1606, 0x2c0c, 0x1c5b, 0x38b6, 0x352f, 0x2e1d, 0x1879, 0x30f2, 0x25a7, 0x0f0d, 0x1e1a, + 0x3c34, 0x3c2b, 0x3c15, 0x3c69, 0x3c91, 0x3d61, 0x3e81, 0x3941, 0x36c1, 0x29c1, 0x17c1, 0x2f82, 0x1b47, 0x368e, 0x295f, 0x16fd, + 0x2dfa, 0x1fb7, 0x3f6e, 0x3a9f, 0x317d, 0x26b9, 0x0931, 0x1262, 0x24c4, 0x0dcb, 0x1b96, 0x372c, 0x2a1b, 0x1075, 0x20ea, 0x0597, + 0x0b2e, 0x165c, 0x2cb8, 0x1d33, 0x3a66, 0x308f, 0x255d, 0x0ef9, 0x1df2, 0x3be4, 0x338b, 0x2355, 0x02e9, 0x05d2, 0x0ba4, 0x1748, + 0x2e90, 0x1963, 0x32c6, 0x21cf, 0x07dd, 0x0fba, 0x1f74, 0x3ee8, 0x3993, 0x3765, 0x2a89, 0x1151, 0x22a2, 0x0107, 0x020e, 0x041c, + 0x0838, 0x1070, 0x20e0, 0x0583, 0x0b06, 0x160c, 0x2c18, 0x1c73, 0x38e6, 0x358f, 0x2f5d, 0x1af9, 0x35f2, 0x2fa7, 0x1b0d, 0x361a, + 0x2877, 0x14ad, 0x295a, 0x16f7, 0x2dee, 0x1f9f, 0x3f3e, 0x3a3f, 0x303d, 0x2439, 0x0c31, 0x1862, 0x30c4, 0x25cb, 0x0fd5, 0x1faa, + 0x3f54, 0x3aeb, 0x3195, 0x2769, 0x0a91, 0x1522, 0x2a44, 0x10cb, 0x2196, 0x076f, 0x0ede, 0x1dbc, 0x3b78, 0x32b3, 0x2125, 0x0609, + 0x0c12, 0x1824, 0x3048, 0x24d3, 0x0de5, 0x1bca, 0x3794, 0x2b6b, 0x1295, 0x252a, 0x0e17, 0x1c2e, 0x385c, 0x34fb, 0x2db5, 0x1f29, + 0x3e52, 0x38e7, 0x358d, 0x2f59, 0x1af1, 0x35e2, 0x2f87, 0x1b4d, 0x369a, 0x2977, 0x16ad, 0x2d5a, 0x1ef7, 0x3dee, 0x3f9f, 0x3b7d, + 0x32b9, 0x2131, 0x0621, 0x0c42, 0x1884, 0x3108, 0x2653, 0x08e5, 0x11ca, 0x2394, 0x036b, 0x06d6, 0x0dac, 0x1b58, 0x36b0, 0x2923, + 0x1605, 0x2c0a, 0x1c57, 0x38ae, 0x351f, 0x2e7d, 0x18b9, 0x3172, 0x26a7, 0x090d, 0x121a, 0x2434, 0x0c2b, 0x1856, 0x30ac, 0x251b, + 0x0e75, 0x1cea, 0x39d4, 0x37eb, 0x2b95, 0x1369, 0x26d2, 0x09e7, 0x13ce, 0x279c, 0x0b7b, 0x16f6, 0x2dec, 0x1f9b, 0x3f36, 0x3a2f, + 0x301d, 0x2479, 0x0cb1, 0x1962, 0x32c4, 0x21cb, 0x07d5, 0x0faa, 0x1f54, 0x3ea8, 0x3913, 0x3665, 0x2889, 0x1551, 0x2aa2, 0x1107, + 0x220e, 0x005f, 0x00be, 0x017c, 0x02f8, 0x05f0, 0x0be0, 0x17c0, 0x2f80, 0x1b43, 0x3686, 0x294f, 0x16dd, 0x2dba, 0x1f37, 0x3e6e, + 0x389f, 0x357d, 0x2eb9, 0x1931, 0x3262, 0x2087, 0x054d, 0x0a9a, 0x1534, 0x2a68, 0x1093, 0x2126, 0x060f, 0x0c1e, 0x183c, 0x3078, + 0x24b3, 0x0d25, 0x1a4a, 0x3494, 0x2d6b, 0x1e95, 0x3d2a, 0x3e17, 0x386d, 0x3499, 0x2d71, 0x1ea1, 0x3d42, 0x3ec7, 0x39cd, 0x37d9, + 0x2bf1, 0x13a1, 0x2742, 0x0ac7, 0x158e, 0x2b1c, 0x127b, 0x24f6, 0x0daf, 0x1b5e, 0x36bc, 0x293b, 0x1635, 0x2c6a, 0x1c97, 0x392e, + 0x361f, 0x287d, 0x14b9, 0x2972, 0x16a7, 0x2d4e, 0x1edf, 0x3dbe, 0x3f3f, 0x3a3d, 0x3039, 0x2431, 0x0c21, 0x1842, 0x3084, 0x254b, + 0x0ed5, 0x1daa, 0x3b54, 0x32eb, 0x2195, 0x0769, 0x0ed2, 0x1da4, 0x3b48, 0x32d3, 0x21e5, 0x0789, 0x0f12, 0x1e24, 0x3c48, 0x3cd3, + 0x3de5, 0x3f89, 0x3b51, 0x32e1, 0x2181, 0x0741, 0x0e82, 0x1d04, 0x3a08, 0x3053, 0x24e5, 0x0d89, 0x1b12, 0x3624, 0x280b, 0x1455, + 0x28aa, 0x1517, 0x2a2e, 0x101f, 0x203e, 0x043f, 0x087e, 0x10fc, 0x21f8, 0x07b3, 0x0f66, 0x1ecc, 0x3d98, 0x3f73, 0x3aa5, 0x3109, + 0x2651, 0x08e1, 0x11c2, 0x2384, 0x034b, 0x0696, 0x0d2c, 0x1a58, 0x34b0, 0x2d23, 0x1e05, 0x3c0a, 0x3c57, 0x3ced, 0x3d99, 0x3f71, + 0x3aa1, 0x3101, 0x2641, 0x08c1, 0x1182, 0x2304, 0x024b, 0x0496, 0x092c, 0x1258, 0x24b0, 0x0d23, 0x1a46, 0x348c, 0x2d5b, 0x1ef5, + 0x3dea, 0x3f97, 0x3b6d, 0x3299, 0x2171, 0x06a1, 0x0d42, 0x1a84, 0x3508, 0x2e53, 0x18e5, 0x31ca, 0x27d7, 0x0bed, 0x17da, 0x2fb4, + 0x1b2b, 0x3656, 0x28ef, 0x159d, 0x2b3a, 0x1237, 0x246e, 0x0c9f, 0x193e, 0x327c, 0x20bb, 0x0535, 0x0a6a, 0x14d4, 0x29a8, 0x1713, + 0x2e26, 0x180f, 0x301e, 0x247f, 0x0cbd, 0x197a, 0x32f4, 0x21ab, 0x0715, 0x0e2a, 0x1c54, 0x38a8, 0x3513, 0x2e65, 0x1889, 0x3112, + 0x2667, 0x088d, 0x111a, 0x2234, 0x002b, 0x0056, 0x00ac, 0x0158, 0x02b0, 0x0560, 0x0ac0, 0x1580, 0x2b00, 0x1243, 0x2486, 0x0d4f, + 0x1a9e, 0x353c, 0x2e3b, 0x1835, 0x306a, 0x2497, 0x0d6d, 0x1ada, 0x35b4, 0x2f2b, 0x1a15, 0x342a, 0x2c17, 0x1c6d, 0x38da, 0x35f7, + 0x2fad, 0x1b19, 0x3632, 0x2827, 0x140d, 0x281a, 0x1477, 0x28ee, 0x159f, 0x2b3e, 0x123f, 0x247e, 0x0cbf, 0x197e, 0x32fc, 0x21bb, + 0x0735, 0x0e6a, 0x1cd4, 0x39a8, 0x3713, 0x2a65, 0x1089, 0x2112, 0x0667, 0x0cce, 0x199c, 0x3338, 0x2233, 0x0025, 0x004a, 0x0094, + 0x0128, 0x0250, 0x04a0, 0x0940, 0x1280, 0x2500, 0x0e43, 0x1c86, 0x390c, 0x365b, 0x28f5, 0x15a9, 0x2b52, 0x12e7, 0x25ce, 0x0fdf, + 0x1fbe, 0x3f7c, 0x3abb, 0x3135, 0x2629, 0x0811, 0x1022, 0x2044, 0x04cb, 0x0996, 0x132c, 0x2658, 0x08f3, 0x11e6, 0x23cc, 0x03db, + 0x07b6, 0x0f6c, 0x1ed8, 0x3db0, 0x3f23, 0x3a05, 0x3049, 0x24d1, 0x0de1, 0x1bc2, 0x3784, 0x2b4b, 0x12d5, 0x25aa, 0x0f17, 0x1e2e, + 0x3c5c, 0x3cfb, 0x3db5, 0x3f29, 0x3a11, 0x3061, 0x2481, 0x0d41, 0x1a82, 0x3504, 0x2e4b, 0x18d5, 0x31aa, 0x2717, 0x0a6d, 0x14da, + 0x29b4, 0x172b, 0x2e56, 0x18ef, 0x31de, 0x27ff, 0x0bbd, 0x177a, 0x2ef4, 0x19ab, 0x3356, 0x22ef, 0x019d, 0x033a, 0x0674, 0x0ce8, + 0x19d0, 0x33a0, 0x2303, 0x0245, 0x048a, 0x0914, 0x1228, 0x2450, 0x0ce3, 0x19c6, 0x338c, 0x235b, 0x02f5, 0x05ea, 0x0bd4, 0x17a8, + 0x2f50, 0x1ae3, 0x35c6, 0x2fcf, 0x1bdd, 0x37ba, 0x2b37, 0x122d, 0x245a, 0x0cf7, 0x19ee, 0x33dc, 0x23fb, 0x03b5, 0x076a, 0x0ed4, + 0x1da8, 0x3b50, 0x32e3, 0x2185, 0x0749, 0x0e92, 0x1d24, 0x3a48, 0x30d3, 0x25e5, 0x0f89, 0x1f12, 0x3e24, 0x380b, 0x3455, 0x2ce9, + 0x1d91, 0x3b22, 0x3207, 0x204d, 0x04d9, 0x09b2, 0x1364, 0x26c8, 0x09d3, 0x13a6, 0x274c, 0x0adb, 0x15b6, 0x2b6c, 0x129b, 0x2536, + 0x0e2f, 0x1c5e, 0x38bc, 0x353b, 0x2e35, 0x1829, 0x3052, 0x24e7, 0x0d8d, 0x1b1a, 0x3634, 0x282b, 0x1415, 0x282a, 0x1417, 0x282e, + 0x141f, 0x283e, 0x143f, 0x287e, 0x14bf, 0x297e, 0x16bf, 0x2d7e, 0x1ebf, 0x3d7e, 0x3ebf, 0x393d, 0x3639, 0x2831, 0x1421, 0x2842, + 0x14c7, 0x298e, 0x175f, 0x2ebe, 0x193f, 0x327e, 0x20bf, 0x053d, 0x0a7a, 0x14f4, 0x29e8, 0x1793, 0x2f26, 0x1a0f, 0x341e, 0x2c7f, + 0x1cbd, 0x397a, 0x36b7, 0x292d, 0x1619, 0x2c32, 0x1c27, 0x384e, 0x34df, 0x2dfd, 0x1fb9, 0x3f72, 0x3aa7, 0x310d, 0x2659, 0x08f1, + 0x11e2, 0x23c4, 0x03cb, 0x0796, 0x0f2c, 0x1e58, 0x3cb0, 0x3d23, 0x3e05, 0x3849, 0x34d1, 0x2de1, 0x1f81, 0x3f02, 0x3a47, 0x30cd, + 0x25d9, 0x0ff1, 0x1fe2, 0x3fc4, 0x3bcb, 0x33d5, 0x23e9, 0x0391, 0x0722, 0x0e44, 0x1c88, 0x3910, 0x3663, 0x2885, 0x1549, 0x2a92, + 0x1167, 0x22ce, 0x01df, 0x03be, 0x077c, 0x0ef8, 0x1df0, 0x3be0, 0x3383, 0x2345, 0x02c9, 0x0592, 0x0b24, 0x1648, 0x2c90, 0x1d63, + 0x3ac6, 0x31cf, 0x27dd, 0x0bf9, 0x17f2, 0x2fe4, 0x1b8b, 0x3716, 0x2a6f, 0x109d, 0x213a, 0x0637, 0x0c6e, 0x18dc, 0x31b8, 0x2733, + 0x0a25, 0x144a, 0x2894, 0x156b, 0x2ad6, 0x11ef, 0x23de, 0x03ff, 0x07fe, 0x0ffc, 0x1ff8, 0x3ff0, 0x3ba3, 0x3305, 0x2249, 0x00d1, + 0x01a2, 0x0344, 0x0688, 0x0d10, 0x1a20, 0x3440, 0x2cc3, 0x1dc5, 0x3b8a, 0x3357, 0x22ed, 0x0199, 0x0332, 0x0664, 0x0cc8, 0x1990, + 0x3320, 0x2203, 0x0045, 0x008a, 0x0114, 0x0228, 0x0450, 0x08a0, 0x1140, 0x2280, 0x0143, 0x0286, 0x050c, 0x0a18, 0x1430, 0x2860, + 0x1483, 0x2906, 0x164f, 0x2c9e, 0x1d7f, 0x3afe, 0x31bf, 0x273d, 0x0a39, 0x1472, 0x28e4, 0x158b, 0x2b16, 0x126f, 0x24de, 0x0dff, + 0x1bfe, 0x37fc, 0x2bbb, 0x1335, 0x266a, 0x0897, 0x112e, 0x225c, 0x00fb, 0x01f6, 0x03ec, 0x07d8, 0x0fb0, 0x1f60, 0x3ec0, 0x39c3, + 0x37c5, 0x2bc9, 0x13d1, 0x27a2, 0x0b07, 0x160e, 0x2c1c, 0x1c7b, 0x38f6, 0x35af, 0x2f1d, 0x1a79, 0x34f2, 0x2da7, 0x1f0d, 0x3e1a, + 0x3877, 0x34ad, 0x2d19, 0x1e71, 0x3ce2, 0x3d87, 0x3f4d, 0x3ad9, 0x31f1, 0x27a1, 0x0b01, 0x1602, 0x2c04, 0x1c4b, 0x3896, 0x356f, + 0x2e9d, 0x1979, 0x32f2, 0x21a7, 0x070d, 0x0e1a, 0x1c34, 0x3868, 0x3493, 0x2d65, 0x1e89, 0x3d12, 0x3e67, 0x388d, 0x3559, 0x2ef1, + 0x19a1, 0x3342, 0x22c7, 0x01cd, 0x039a, 0x0734, 0x0e68, 0x1cd0, 0x39a0, 0x3703, 0x2a45, 0x10c9, 0x2192, 0x0767, 0x0ece, 0x1d9c, + 0x3b38, 0x3233, 0x2025, 0x0409, 0x0812, 0x1024, 0x2048, 0x04d3, 0x09a6, 0x134c, 0x2698, 0x0973, 0x12e6, 0x25cc, 0x0fdb, 0x1fb6, + 0x3f6c, 0x3a9b, 0x3175, 0x26a9, 0x0911, 0x1222, 0x2444, 0x0ccb, 0x1996, 0x332c, 0x221b, 0x0075, 0x00ea, 0x01d4, 0x03a8, 0x0750, + 0x0ea0, 0x1d40, 0x3a80, 0x3143, 0x26c5, 0x09c9, 0x1392, 0x2724, 0x0a0b, 0x1416, 0x282c, 0x141b, 0x2836, 0x142f, 0x285e, 0x14ff, + 0x29fe, 0x17bf, 0x2f7e, 0x1abf, 0x357e, 0x2ebf, 0x193d, 0x327a, 0x20b7, 0x052d, 0x0a5a, 0x14b4, 0x2968, 0x1693, 0x2d26, 0x1e0f, + 0x3c1e, 0x3c7f, 0x3cbd, 0x3d39, 0x3e31, 0x3821, 0x3401, 0x2c41, 0x1cc1, 0x3982, 0x3747, 0x2acd, 0x11d9, 0x23b2, 0x0327, 0x064e, + 0x0c9c, 0x1938, 0x3270, 0x20a3, 0x0505, 0x0a0a, 0x1414, 0x2828, 0x1413, 0x2826, 0x140f, 0x281e, 0x147f, 0x28fe, 0x15bf, 0x2b7e, + 0x12bf, 0x257e, 0x0ebf, 0x1d7e, 0x3afc, 0x31bb, 0x2735, 0x0a29, 0x1452, 0x28a4, 0x150b, 0x2a16, 0x106f, 0x20de, 0x05ff, 0x0bfe, + 0x17fc, 0x2ff8, 0x1bb3, 0x3766, 0x2a8f, 0x115d, 0x22ba, 0x0137, 0x026e, 0x04dc, 0x09b8, 0x1370, 0x26e0, 0x0983, 0x1306, 0x260c, + 0x085b, 0x10b6, 0x216c, 0x069b, 0x0d36, 0x1a6c, 0x34d8, 0x2df3, 0x1fa5, 0x3f4a, 0x3ad7, 0x31ed, 0x2799, 0x0b71, 0x16e2, 0x2dc4, + 0x1fcb, 0x3f96, 0x3b6f, 0x329d, 0x2179, 0x06b1, 0x0d62, 0x1ac4, 0x3588, 0x2f53, 0x1ae5, 0x35ca, 0x2fd7, 0x1bed, 0x37da, 0x2bf7, + 0x13ad, 0x275a, 0x0af7, 0x15ee, 0x2bdc, 0x13fb, 0x27f6, 0x0baf, 0x175e, 0x2ebc, 0x193b, 0x3276, 0x20af, 0x051d, 0x0a3a, 0x1474, + 0x28e8, 0x1593, 0x2b26, 0x120f, 0x241e, 0x0c7f, 0x18fe, 0x31fc, 0x27bb, 0x0b35, 0x166a, 0x2cd4, 0x1deb, 0x3bd6, 0x33ef, 0x239d, + 0x0379, 0x06f2, 0x0de4, 0x1bc8, 0x3790, 0x2b63, 0x1285, 0x250a, 0x0e57, 0x1cae, 0x395c, 0x36fb, 0x29b5, 0x1729, 0x2e52, 0x18e7, + 0x31ce, 0x27df, 0x0bfd, 0x17fa, 0x2ff4, 0x1bab, 0x3756, 0x2aef, 0x119d, 0x233a, 0x0237, 0x046e, 0x08dc, 0x11b8, 0x2370, 0x02a3, + 0x0546, 0x0a8c, 0x1518, 0x2a30, 0x1023, 0x2046, 0x04cf, 0x099e, 0x133c, 0x2678, 0x08b3, 0x1166, 0x22cc, 0x01db, 0x03b6, 0x076c, + 0x0ed8, 0x1db0, 0x3b60, 0x3283, 0x2145, 0x06c9, 0x0d92, 0x1b24, 0x3648, 0x28d3, 0x15e5, 0x2bca, 0x13d7, 0x27ae, 0x0b1f, 0x163e, + 0x2c7c, 0x1cbb, 0x3976, 0x36af, 0x291d, 0x1679, 0x2cf2, 0x1da7, 0x3b4e, 0x32df, 0x21fd, 0x07b9, 0x0f72, 0x1ee4, 0x3dc8, 0x3fd3, + 0x3be5, 0x3389, 0x2351, 0x02e1, 0x05c2, 0x0b84, 0x1708, 0x2e10, 0x1863, 0x30c6, 0x25cf, 0x0fdd, 0x1fba, 0x3f74, 0x3aab, 0x3115, + 0x2669, 0x0891, 0x1122, 0x2244, 0x00cb, 0x0196, 0x032c, 0x0658, 0x0cb0, 0x1960, 0x32c0, 0x21c3, 0x07c5, 0x0f8a, 0x1f14, 0x3e28, + 0x3813, 0x3465, 0x2c89, 0x1d51, 0x3aa2, 0x3107, 0x264d, 0x08d9, 0x11b2, 0x2364, 0x028b, 0x0516, 0x0a2c, 0x1458, 0x28b0, 0x1523, + 0x2a46, 0x10cf, 0x219e, 0x077f, 0x0efe, 0x1dfc, 0x3bf8, 0x33b3, 0x2325, 0x0209, 0x0412, 0x0824, 0x1048, 0x2090, 0x0563, 0x0ac6, + 0x158c, 0x2b18, 0x1273, 0x24e6, 0x0d8f, 0x1b1e, 0x363c, 0x283b, 0x1435, 0x286a, 0x1497, 0x292e, 0x161f, 0x2c3e, 0x1c3f, 0x387e, + 0x34bf, 0x2d3d, 0x1e39, 0x3c72, 0x3ca7, 0x3d0d, 0x3e59, 0x38f1, 0x35a1, 0x2f01, 0x1a41, 0x3482, 0x2d47, 0x1ecd, 0x3d9a, 0x3f77, + 0x3aad, 0x3119, 0x2671, 0x08a1, 0x1142, 0x2284, 0x014b, 0x0296, 0x052c, 0x0a58, 0x14b0, 0x2960, 0x1683, 0x2d06, 0x1e4f, 0x3c9e, + 0x3d7f, 0x3ebd, 0x3939, 0x3631, 0x2821, 0x1401, 0x2802, 0x1447, 0x288e, 0x155f, 0x2abe, 0x113f, 0x227e, 0x00bf, 0x017e, 0x02fc, + 0x05f8, 0x0bf0, 0x17e0, 0x2fc0, 0x1bc3, 0x3786, 0x2b4f, 0x12dd, 0x25ba, 0x0f37, 0x1e6e, 0x3cdc, 0x3dfb, 0x3fb5, 0x3b29, 0x3211, + 0x2061, 0x0481, 0x0902, 0x1204, 0x2408, 0x0c53, 0x18a6, 0x314c, 0x26db, 0x09f5, 0x13ea, 0x27d4, 0x0beb, 0x17d6, 0x2fac, 0x1b1b, + 0x3636, 0x282f, 0x141d, 0x283a, 0x1437, 0x286e, 0x149f, 0x293e, 0x163f, 0x2c7e, 0x1cbf, 0x397e, 0x36bf, 0x293d, 0x1639, 0x2c72, + 0x1ca7, 0x394e, 0x36df, 0x29fd, 0x17b9, 0x2f72, 0x1aa7, 0x354e, 0x2edf, 0x19fd, 0x33fa, 0x23b7, 0x032d, 0x065a, 0x0cb4, 0x1968, + 0x32d0, 0x21e3, 0x0785, 0x0f0a, 0x1e14, 0x3c28, 0x3c13, 0x3c65, 0x3c89, 0x3d51, 0x3ee1, 0x3981, 0x3741, 0x2ac1, 0x11c1, 0x2382, + 0x0347, 0x068e, 0x0d1c, 0x1a38, 0x3470, 0x2ca3, 0x1d05, 0x3a0a, 0x3057, 0x24ed, 0x0d99, 0x1b32, 0x3664, 0x288b, 0x1555, 0x2aaa, + 0x1117, 0x222e, 0x001f, 0x003e, 0x007c, 0x00f8, 0x01f0, 0x03e0, 0x07c0, 0x0f80, 0x1f00, 0x3e00, 0x3843, 0x34c5, 0x2dc9, 0x1fd1, + 0x3fa2, 0x3b07, 0x324d, 0x20d9, 0x05f1, 0x0be2, 0x17c4, 0x2f88, 0x1b53, 0x36a6, 0x290f, 0x165d, 0x2cba, 0x1d37, 0x3a6e, 0x309f, + 0x257d, 0x0eb9, 0x1d72, 0x3ae4, 0x318b, 0x2755, 0x0ae9, 0x15d2, 0x2ba4, 0x130b, 0x2616, 0x086f, 0x10de, 0x21bc, 0x073b, 0x0e76, + 0x1cec, 0x39d8, 0x37f3, 0x2ba5, 0x1309, 0x2612, 0x0867, 0x10ce, 0x219c, 0x077b, 0x0ef6, 0x1dec, 0x3bd8, 0x33f3, 0x23a5, 0x0309, + 0x0612, 0x0c24, 0x1848, 0x3090, 0x2563, 0x0e85, 0x1d0a, 0x3a14, 0x306b, 0x2495, 0x0d69, 0x1ad2, 0x35a4, 0x2f0b, 0x1a55, 0x34aa, + 0x2d17, 0x1e6d, 0x3cda, 0x3df7, 0x3fad, 0x3b19, 0x3271, 0x20a1, 0x0501, 0x0a02, 0x1404, 0x2808, 0x1453, 0x28a6, 0x150f, 0x2a1e, + 0x107f, 0x20fe, 0x05bf, 0x0b7e, 0x16fc, 0x2df8, 0x1fb3, 0x3f66, 0x3a8f, 0x315d, 0x26f9, 0x09b1, 0x1362, 0x26c4, 0x09cb, 0x1396, + 0x272c, 0x0a1b, 0x1436, 0x286c, 0x149b, 0x2936, 0x162f, 0x2c5e, 0x1cff, 0x39fe, 0x37bf, 0x2b3d, 0x1239, 0x2472, 0x0ca7, 0x194e, + 0x329c, 0x217b, 0x06b5, 0x0d6a, 0x1ad4, 0x35a8, 0x2f13, 0x1a65, 0x34ca, 0x2dd7, 0x1fed, 0x3fda, 0x3bf7, 0x33ad, 0x2319, 0x0271, + 0x04e2, 0x09c4, 0x1388, 0x2710, 0x0a63, 0x14c6, 0x298c, 0x175b, 0x2eb6, 0x192f, 0x325e, 0x20ff, 0x05bd, 0x0b7a, 0x16f4, 0x2de8, + 0x1f93, 0x3f26, 0x3a0f, 0x305d, 0x24f9, 0x0db1, 0x1b62, 0x36c4, 0x29cb, 0x17d5, 0x2faa, 0x1b17, 0x362e, 0x281f, 0x147d, 0x28fa, + 0x15b7, 0x2b6e, 0x129f, 0x253e, 0x0e3f, 0x1c7e, 0x38fc, 0x35bb, 0x2f35, 0x1a29, 0x3452, 0x2ce7, 0x1d8d, 0x3b1a, 0x3277, 0x20ad, + 0x0519, 0x0a32, 0x1464, 0x28c8, 0x15d3, 0x2ba6, 0x130f, 0x261e, 0x087f, 0x10fe, 0x21fc, 0x07bb, 0x0f76, 0x1eec, 0x3dd8, 0x3ff3, + 0x3ba5, 0x3309, 0x2251, 0x00e1, 0x01c2, 0x0384, 0x0708, 0x0e10, 0x1c20, 0x3840, 0x34c3, 0x2dc5, 0x1fc9, 0x3f92, 0x3b67, 0x328d, + 0x2159, 0x06f1, 0x0de2, 0x1bc4, 0x3788, 0x2b53, 0x12e5, 0x25ca, 0x0fd7, 0x1fae, 0x3f5c, 0x3afb, 0x31b5, 0x2729, 0x0a11, 0x1422, + 0x2844, 0x14cb, 0x2996, 0x176f, 0x2ede, 0x19ff, 0x33fe, 0x23bf, 0x033d, 0x067a, 0x0cf4, 0x19e8, 0x33d0, 0x23e3, 0x0385, 0x070a, + 0x0e14, 0x1c28, 0x3850, 0x34e3, 0x2d85, 0x1f49, 0x3e92, 0x3967, 0x368d, 0x2959, 0x16f1, 0x2de2, 0x1f87, 0x3f0e, 0x3a5f, 0x30fd, + 0x25b9, 0x0f31, 0x1e62, 0x3cc4, 0x3dcb, 0x3fd5, 0x3be9, 0x3391, 0x2361, 0x0281, 0x0502, 0x0a04, 0x1408, 0x2810, 0x1463, 0x28c6, + 0x15cf, 0x2b9e, 0x137f, 0x26fe, 0x09bf, 0x137e, 0x26fc, 0x09bb, 0x1376, 0x26ec, 0x099b, 0x1336, 0x266c, 0x089b, 0x1136, 0x226c, + 0x009b, 0x0136, 0x026c, 0x04d8, 0x09b0, 0x1360, 0x26c0, 0x09c3, 0x1386, 0x270c, 0x0a5b, 0x14b6, 0x296c, 0x169b, 0x2d36, 0x1e2f, + 0x3c5e, 0x3cff, 0x3dbd, 0x3f39, 0x3a31, 0x3021, 0x2401, 0x0c41, 0x1882, 0x3104, 0x264b, 0x08d5, 0x11aa, 0x2354, 0x02eb, 0x05d6, + 0x0bac, 0x1758, 0x2eb0, 0x1923, 0x3246, 0x20cf, 0x05dd, 0x0bba, 0x1774, 0x2ee8, 0x1993, 0x3326, 0x220f, 0x005d, 0x00ba, 0x0174, + 0x02e8, 0x05d0, 0x0ba0, 0x1740, 0x2e80, 0x1943, 0x3286, 0x214f, 0x06dd, 0x0dba, 0x1b74, 0x36e8, 0x2993, 0x1765, 0x2eca, 0x19d7, + 0x33ae, 0x231f, 0x027d, 0x04fa, 0x09f4, 0x13e8, 0x27d0, 0x0be3, 0x17c6, 0x2f8c, 0x1b5b, 0x36b6, 0x292f, 0x161d, 0x2c3a, 0x1c37, + 0x386e, 0x349f, 0x2d7d, 0x1eb9, 0x3d72, 0x3ea7, 0x390d, 0x3659, 0x28f1, 0x15a1, 0x2b42, 0x12c7, 0x258e, 0x0f5f, 0x1ebe, 0x3d7c, + 0x3ebb, 0x3935, 0x3629, 0x2811, 0x1461, 0x28c2, 0x15c7, 0x2b8e, 0x135f, 0x26be, 0x093f, 0x127e, 0x24fc, 0x0dbb, 0x1b76, 0x36ec, + 0x299b, 0x1775, 0x2eea, 0x1997, 0x332e, 0x221f, 0x007d, 0x00fa, 0x01f4, 0x03e8, 0x07d0, 0x0fa0, 0x1f40, 0x3e80, 0x3943, 0x36c5, + 0x29c9, 0x17d1, 0x2fa2, 0x1b07, 0x360e, 0x285f, 0x14fd, 0x29fa, 0x17b7, 0x2f6e, 0x1a9f, 0x353e, 0x2e3f, 0x183d, 0x307a, 0x24b7, + 0x0d2d, 0x1a5a, 0x34b4, 0x2d2b, 0x1e15, 0x3c2a, 0x3c17, 0x3c6d, 0x3c99, 0x3d71, 0x3ea1, 0x3901, 0x3641, 0x28c1, 0x15c1, 0x2b82, + 0x1347, 0x268e, 0x095f, 0x12be, 0x257c, 0x0ebb, 0x1d76, 0x3aec, 0x319b, 0x2775, 0x0aa9, 0x1552, 0x2aa4, 0x110b, 0x2216, 0x006f, + 0x00de, 0x01bc, 0x0378, 0x06f0, 0x0de0, 0x1bc0, 0x3780, 0x2b43, 0x12c5, 0x258a, 0x0f57, 0x1eae, 0x3d5c, 0x3efb, 0x39b5, 0x3729, + 0x2a11, 0x1061, 0x20c2, 0x05c7, 0x0b8e, 0x171c, 0x2e38, 0x1833, 0x3066, 0x248f, 0x0d5d, 0x1aba, 0x3574, 0x2eab, 0x1915, 0x322a, + 0x2017, 0x046d, 0x08da, 0x11b4, 0x2368, 0x0293, 0x0526, 0x0a4c, 0x1498, 0x2930, 0x1623, 0x2c46, 0x1ccf, 0x399e, 0x377f, 0x2abd, + 0x1139, 0x2272, 0x00a7, 0x014e, 0x029c, 0x0538, 0x0a70, 0x14e0, 0x29c0, 0x17c3, 0x2f86, 0x1b4f, 0x369e, 0x297f, 0x16bd, 0x2d7a, + 0x1eb7, 0x3d6e, 0x3e9f, 0x397d, 0x36b9, 0x2931, 0x1621, 0x2c42, 0x1cc7, 0x398e, 0x375f, 0x2afd, 0x11b9, 0x2372, 0x02a7, 0x054e, + 0x0a9c, 0x1538, 0x2a70, 0x10a3, 0x2146, 0x06cf, 0x0d9e, 0x1b3c, 0x3678, 0x28b3, 0x1525, 0x2a4a, 0x10d7, 0x21ae, 0x071f, 0x0e3e, + 0x1c7c, 0x38f8, 0x35b3, 0x2f25, 0x1a09, 0x3412, 0x2c67, 0x1c8d, 0x391a, 0x3677, 0x28ad, 0x1519, 0x2a32, 0x1027, 0x204e, 0x04df, + 0x09be, 0x137c, 0x26f8, 0x09b3, 0x1366, 0x26cc, 0x09db, 0x13b6, 0x276c, 0x0a9b, 0x1536, 0x2a6c, 0x109b, 0x2136, 0x062f, 0x0c5e, + 0x18bc, 0x3178, 0x26b3, 0x0925, 0x124a, 0x2494, 0x0d6b, 0x1ad6, 0x35ac, 0x2f1b, 0x1a75, 0x34ea, 0x2d97, 0x1f6d, 0x3eda, 0x39f7, + 0x37ad, 0x2b19, 0x1271, 0x24e2, 0x0d87, 0x1b0e, 0x361c, 0x287b, 0x14b5, 0x296a, 0x1697, 0x2d2e, 0x1e1f, 0x3c3e, 0x3c3f, 0x3c3d, + 0x3c39, 0x3c31, 0x3c21, 0x3c01, 0x3c41, 0x3cc1, 0x3dc1, 0x3fc1, 0x3bc1, 0x33c1, 0x23c1, 0x03c1, 0x0782, 0x0f04, 0x1e08, 0x3c10, + 0x3c63, 0x3c85, 0x3d49, 0x3ed1, 0x39e1, 0x3781, 0x2b41, 0x12c1, 0x2582, 0x0f47, 0x1e8e, 0x3d1c, 0x3e7b, 0x38b5, 0x3529, 0x2e11, + 0x1861, 0x30c2, 0x25c7, 0x0fcd, 0x1f9a, 0x3f34, 0x3a2b, 0x3015, 0x2469, 0x0c91, 0x1922, 0x3244, 0x20cb, 0x05d5, 0x0baa, 0x1754, + 0x2ea8, 0x1913, 0x3226, 0x200f, 0x045d, 0x08ba, 0x1174, 0x22e8, 0x0193, 0x0326, 0x064c, 0x0c98, 0x1930, 0x3260, 0x2083, 0x0545, + 0x0a8a, 0x1514, 0x2a28, 0x1013, 0x2026, 0x040f, 0x081e, 0x103c, 0x2078, 0x04b3, 0x0966, 0x12cc, 0x2598, 0x0f73, 0x1ee6, 0x3dcc, + 0x3fdb, 0x3bf5, 0x33a9, 0x2311, 0x0261, 0x04c2, 0x0984, 0x1308, 0x2610, 0x0863, 0x10c6, 0x218c, 0x075b, 0x0eb6, 0x1d6c, 0x3ad8, + 0x31f3, 0x27a5, 0x0b09, 0x1612, 0x2c24, 0x1c0b, 0x3816, 0x346f, 0x2c9d, 0x1d79, 0x3af2, 0x31a7, 0x270d, 0x0a59, 0x14b2, 0x2964, + 0x168b, 0x2d16, 0x1e6f, 0x3cde, 0x3dff, 0x3fbd, 0x3b39, 0x3231, 0x2021, 0x0401, 0x0802, 0x1004, 0x2008, 0x0453, 0x08a6, 0x114c, + 0x2298, 0x0173, 0x02e6, 0x05cc, 0x0b98, 0x1730, 0x2e60, 0x1883, 0x3106, 0x264f, 0x08dd, 0x11ba, 0x2374, 0x02ab, 0x0556, 0x0aac, + 0x1558, 0x2ab0, 0x1123, 0x2246, 0x00cf, 0x019e, 0x033c, 0x0678, 0x0cf0, 0x19e0, 0x33c0, 0x23c3, 0x03c5, 0x078a, 0x0f14, 0x1e28, + 0x3c50, 0x3ce3, 0x3d85, 0x3f49, 0x3ad1, 0x31e1, 0x2781, 0x0b41, 0x1682, 0x2d04, 0x1e4b, 0x3c96, 0x3d6f, 0x3e9d, 0x3979, 0x36b1, + 0x2921, 0x1601, 0x2c02, 0x1c47, 0x388e, 0x355f, 0x2efd, 0x19b9, 0x3372, 0x22a7, 0x010d, 0x021a, 0x0434, 0x0868, 0x10d0, 0x21a0, + 0x0703, 0x0e06, 0x1c0c, 0x3818, 0x3473, 0x2ca5, 0x1d09, 0x3a12, 0x3067, 0x248d, 0x0d59, 0x1ab2, 0x3564, 0x2e8b, 0x1955, 0x32aa, + 0x2117, 0x066d, 0x0cda, 0x19b4, 0x3368, 0x2293, 0x0165, 0x02ca, 0x0594, 0x0b28, 0x1650, 0x2ca0, 0x1d03, 0x3a06, 0x304f, 0x24dd, + 0x0df9, 0x1bf2, 0x37e4, 0x2b8b, 0x1355, 0x26aa, 0x0917, 0x122e, 0x245c, 0x0cfb, 0x19f6, 0x33ec, 0x239b, 0x0375, 0x06ea, 0x0dd4, + 0x1ba8, 0x3750, 0x2ae3, 0x1185, 0x230a, 0x0257, 0x04ae, 0x095c, 0x12b8, 0x2570, 0x0ea3, 0x1d46, 0x3a8c, 0x315b, 0x26f5, 0x09a9, + 0x1352, 0x26a4, 0x090b, 0x1216, 0x242c, 0x0c1b, 0x1836, 0x306c, 0x249b, 0x0d75, 0x1aea, 0x35d4, 0x2feb, 0x1b95, 0x372a, 0x2a17, + 0x106d, 0x20da, 0x05f7, 0x0bee, 0x17dc, 0x2fb8, 0x1b33, 0x3666, 0x288f, 0x155d, 0x2aba, 0x1137, 0x226e, 0x009f, 0x013e, 0x027c, + 0x04f8, 0x09f0, 0x13e0, 0x27c0, 0x0bc3, 0x1786, 0x2f0c, 0x1a5b, 0x34b6, 0x2d2f, 0x1e1d, 0x3c3a, 0x3c37, 0x3c2d, 0x3c19, 0x3c71, + 0x3ca1, 0x3d01, 0x3e41, 0x38c1, 0x35c1, 0x2fc1, 0x1bc1, 0x3782, 0x2b47, 0x12cd, 0x259a, 0x0f77, 0x1eee, 0x3ddc, 0x3ffb, 0x3bb5, + 0x3329, 0x2211, 0x0061, 0x00c2, 0x0184, 0x0308, 0x0610, 0x0c20, 0x1840, 0x3080, 0x2543, 0x0ec5, 0x1d8a, 0x3b14, 0x326b, 0x2095, + 0x0569, 0x0ad2, 0x15a4, 0x2b48, 0x12d3, 0x25a6, 0x0f0f, 0x1e1e, 0x3c3c, 0x3c3b, 0x3c35, 0x3c29, 0x3c11, 0x3c61, 0x3c81, 0x3d41, + 0x3ec1, 0x39c1, 0x37c1, 0x2bc1, 0x13c1, 0x2782, 0x0b47, 0x168e, 0x2d1c, 0x1e7b, 0x3cf6, 0x3daf, 0x3f1d, 0x3a79, 0x30b1, 0x2521, + 0x0e01, 0x1c02, 0x3804, 0x344b, 0x2cd5, 0x1de9, 0x3bd2, 0x33e7, 0x238d, 0x0359, 0x06b2, 0x0d64, 0x1ac8, 0x3590, 0x2f63, 0x1a85, + 0x350a, 0x2e57, 0x18ed, 0x31da, 0x27f7, 0x0bad, 0x175a, 0x2eb4, 0x192b, 0x3256, 0x20ef, 0x059d, 0x0b3a, 0x1674, 0x2ce8, 0x1d93, + 0x3b26, 0x320f, 0x205d, 0x04f9, 0x09f2, 0x13e4, 0x27c8, 0x0bd3, 0x17a6, 0x2f4c, 0x1adb, 0x35b6, 0x2f2f, 0x1a1d, 0x343a, 0x2c37, + 0x1c2d, 0x385a, 0x34f7, 0x2dad, 0x1f19, 0x3e32, 0x3827, 0x340d, 0x2c59, 0x1cf1, 0x39e2, 0x3787, 0x2b4d, 0x12d9, 0x25b2, 0x0f27, + 0x1e4e, 0x3c9c, 0x3d7b, 0x3eb5, 0x3929, 0x3611, 0x2861, 0x1481, 0x2902, 0x1647, 0x2c8e, 0x1d5f, 0x3abe, 0x313f, 0x263d, 0x0839, + 0x1072, 0x20e4, 0x058b, 0x0b16, 0x162c, 0x2c58, 0x1cf3, 0x39e6, 0x378f, 0x2b5d, 0x12f9, 0x25f2, 0x0fa7, 0x1f4e, 0x3e9c, 0x397b, + 0x36b5, 0x2929, 0x1611, 0x2c22, 0x1c07, 0x380e, 0x345f, 0x2cfd, 0x1db9, 0x3b72, 0x32a7, 0x210d, 0x0659, 0x0cb2, 0x1964, 0x32c8, + 0x21d3, 0x07e5, 0x0fca, 0x1f94, 0x3f28, 0x3a13, 0x3065, 0x2489, 0x0d51, 0x1aa2, 0x3544, 0x2ecb, 0x19d5, 0x33aa, 0x2317, 0x026d, + 0x04da, 0x09b4, 0x1368, 0x26d0, 0x09e3, 0x13c6, 0x278c, 0x0b5b, 0x16b6, 0x2d6c, 0x1e9b, 0x3d36, 0x3e2f, 0x381d, 0x3479, 0x2cb1, + 0x1d21, 0x3a42, 0x30c7, 0x25cd, 0x0fd9, 0x1fb2, 0x3f64, 0x3a8b, 0x3155, 0x26e9, 0x0991, 0x1322, 0x2644, 0x08cb, 0x1196, 0x232c, + 0x021b, 0x0436, 0x086c, 0x10d8, 0x21b0, 0x0723, 0x0e46, 0x1c8c, 0x3918, 0x3673, 0x28a5, 0x1509, 0x2a12, 0x1067, 0x20ce, 0x05df, + 0x0bbe, 0x177c, 0x2ef8, 0x19b3, 0x3366, 0x228f, 0x015d, 0x02ba, 0x0574, 0x0ae8, 0x15d0, 0x2ba0, 0x1303, 0x2606, 0x084f, 0x109e, + 0x213c, 0x063b, 0x0c76, 0x18ec, 0x31d8, 0x27f3, 0x0ba5, 0x174a, 0x2e94, 0x196b, 0x32d6, 0x21ef, 0x079d, 0x0f3a, 0x1e74, 0x3ce8, + 0x3d93, 0x3f65, 0x3a89, 0x3151, 0x26e1, 0x0981, 0x1302, 0x2604, 0x084b, 0x1096, 0x212c, 0x061b, 0x0c36, 0x186c, 0x30d8, 0x25f3, + 0x0fa5, 0x1f4a, 0x3e94, 0x396b, 0x3695, 0x2969, 0x1691, 0x2d22, 0x1e07, 0x3c0e, 0x3c5f, 0x3cfd, 0x3db9, 0x3f31, 0x3a21, 0x3001, + 0x2441, 0x0cc1, 0x1982, 0x3304, 0x224b, 0x00d5, 0x01aa, 0x0354, 0x06a8, 0x0d50, 0x1aa0, 0x3540, 0x2ec3, 0x19c5, 0x338a, 0x2357, + 0x02ed, 0x05da, 0x0bb4, 0x1768, 0x2ed0, 0x19e3, 0x33c6, 0x23cf, 0x03dd, 0x07ba, 0x0f74, 0x1ee8, 0x3dd0, 0x3fe3, 0x3b85, 0x3349, + 0x22d1, 0x01e1, 0x03c2, 0x0784, 0x0f08, 0x1e10, 0x3c20, 0x3c03, 0x3c45, 0x3cc9, 0x3dd1, 0x3fe1, 0x3b81, 0x3341, 0x22c1, 0x01c1, + 0x0382, 0x0704, 0x0e08, 0x1c10, 0x3820, 0x3403, 0x2c45, 0x1cc9, 0x3992, 0x3767, 0x2a8d, 0x1159, 0x22b2, 0x0127, 0x024e, 0x049c, + 0x0938, 0x1270, 0x24e0, 0x0d83, 0x1b06, 0x360c, 0x285b, 0x14f5, 0x29ea, 0x1797, 0x2f2e, 0x1a1f, 0x343e, 0x2c3f, 0x1c3d, 0x387a, + 0x34b7, 0x2d2d, 0x1e19, 0x3c32, 0x3c27, 0x3c0d, 0x3c59, 0x3cf1, 0x3da1, 0x3f01, 0x3a41, 0x30c1, 0x25c1, 0x0fc1, 0x1f82, 0x3f04, + 0x3a4b, 0x30d5, 0x25e9, 0x0f91, 0x1f22, 0x3e44, 0x38cb, 0x35d5, 0x2fe9, 0x1b91, 0x3722, 0x2a07, 0x104d, 0x209a, 0x0577, 0x0aee, + 0x15dc, 0x2bb8, 0x1333, 0x2666, 0x088f, 0x111e, 0x223c, 0x003b, 0x0076, 0x00ec, 0x01d8, 0x03b0, 0x0760, 0x0ec0, 0x1d80, 0x3b00, + 0x3243, 0x20c5, 0x05c9, 0x0b92, 0x1724, 0x2e48, 0x18d3, 0x31a6, 0x270f, 0x0a5d, 0x14ba, 0x2974, 0x16ab, 0x2d56, 0x1eef, 0x3dde, + 0x3fff, 0x3bbd, 0x3339, 0x2231, 0x0021, 0x0042, 0x0084, 0x0108, 0x0210, 0x0420, 0x0840, 0x1080, 0x2100, 0x0643, 0x0c86, 0x190c, + 0x3218, 0x2073, 0x04a5, 0x094a, 0x1294, 0x2528, 0x0e13, 0x1c26, 0x384c, 0x34db, 0x2df5, 0x1fa9, 0x3f52, 0x3ae7, 0x318d, 0x2759, + 0x0af1, 0x15e2, 0x2bc4, 0x13cb, 0x2796, 0x0b6f, 0x16de, 0x2dbc, 0x1f3b, 0x3e76, 0x38af, 0x351d, 0x2e79, 0x18b1, 0x3162, 0x2687, + 0x094d, 0x129a, 0x2534, 0x0e2b, 0x1c56, 0x38ac, 0x351b, 0x2e75, 0x18a9, 0x3152, 0x26e7, 0x098d, 0x131a, 0x2634, 0x082b, 0x1056, + 0x20ac, 0x051b, 0x0a36, 0x146c, 0x28d8, 0x15f3, 0x2be6, 0x138f, 0x271e, 0x0a7f, 0x14fe, 0x29fc, 0x17bb, 0x2f76, 0x1aaf, 0x355e, + 0x2eff, 0x19bd, 0x337a, 0x22b7, 0x012d, 0x025a, 0x04b4, 0x0968, 0x12d0, 0x25a0, 0x0f03, 0x1e06, 0x3c0c, 0x3c5b, 0x3cf5, 0x3da9, + 0x3f11, 0x3a61, 0x3081, 0x2541, 0x0ec1, 0x1d82, 0x3b04, 0x324b, 0x20d5, 0x05e9, 0x0bd2, 0x17a4, 0x2f48, 0x1ad3, 0x35a6, 0x2f0f, + 0x1a5d, 0x34ba, 0x2d37, 0x1e2d, 0x3c5a, 0x3cf7, 0x3dad, 0x3f19, 0x3a71, 0x30a1, 0x2501, 0x0e41, 0x1c82, 0x3904, 0x364b, 0x28d5, + 0x15e9, 0x2bd2, 0x13e7, 0x27ce, 0x0bdf, 0x17be, 0x2f7c, 0x1abb, 0x3576, 0x2eaf, 0x191d, 0x323a, 0x2037, 0x042d, 0x085a, 0x10b4, + 0x2168, 0x0693, 0x0d26, 0x1a4c, 0x3498, 0x2d73, 0x1ea5, 0x3d4a, 0x3ed7, 0x39ed, 0x3799, 0x2b71, 0x12a1, 0x2542, 0x0ec7, 0x1d8e, + 0x3b1c, 0x327b, 0x20b5, 0x0529, 0x0a52, 0x14a4, 0x2948, 0x16d3, 0x2da6, 0x1f0f, 0x3e1e, 0x387f, 0x34bd, 0x2d39, 0x1e31, 0x3c62, + 0x3c87, 0x3d4d, 0x3ed9, 0x39f1, 0x37a1, 0x2b01, 0x1241, 0x2482, 0x0d47, 0x1a8e, 0x351c, 0x2e7b, 0x18b5, 0x316a, 0x2697, 0x096d, + 0x12da, 0x25b4, 0x0f2b, 0x1e56, 0x3cac, 0x3d1b, 0x3e75, 0x38a9, 0x3511, 0x2e61, 0x1881, 0x3102, 0x2647, 0x08cd, 0x119a, 0x2334, + 0x022b, 0x0456, 0x08ac, 0x1158, 0x22b0, 0x0123, 0x0246, 0x048c, 0x0918, 0x1230, 0x2460, 0x0c83, 0x1906, 0x320c, 0x205b, 0x04f5, + 0x09ea, 0x13d4, 0x27a8, 0x0b13, 0x1626, 0x2c4c, 0x1cdb, 0x39b6, 0x372f, 0x2a1d, 0x1079, 0x20f2, 0x05a7, 0x0b4e, 0x169c, 0x2d38, + 0x1e33, 0x3c66, 0x3c8f, 0x3d5d, 0x3ef9, 0x39b1, 0x3721, 0x2a01, 0x1041, 0x2082, 0x0547, 0x0a8e, 0x151c, 0x2a38, 0x1033, 0x2066, + 0x048f, 0x091e, 0x123c, 0x2478, 0x0cb3, 0x1966, 0x32cc, 0x21db, 0x07f5, 0x0fea, 0x1fd4, 0x3fa8, 0x3b13, 0x3265, 0x2089, 0x0551, + 0x0aa2, 0x1544, 0x2a88, 0x1153, 0x22a6, 0x010f, 0x021e, 0x043c, 0x0878, 0x10f0, 0x21e0, 0x0783, 0x0f06, 0x1e0c, 0x3c18, 0x3c73, + 0x3ca5, 0x3d09, 0x3e51, 0x38e1, 0x3581, 0x2f41, 0x1ac1, 0x3582, 0x2f47, 0x1acd, 0x359a, 0x2f77, 0x1aad, 0x355a, 0x2ef7, 0x19ad, + 0x335a, 0x22f7, 0x01ad, 0x035a, 0x06b4, 0x0d68, 0x1ad0, 0x35a0, 0x2f03, 0x1a45, 0x348a, 0x2d57, 0x1eed, 0x3dda, 0x3ff7, 0x3bad, + 0x3319, 0x2271, 0x00a1, 0x0142, 0x0284, 0x0508, 0x0a10, 0x1420, 0x2840, 0x14c3, 0x2986, 0x174f, 0x2e9e, 0x197f, 0x32fe, 0x21bf, + 0x073d, 0x0e7a, 0x1cf4, 0x39e8, 0x3793, 0x2b65, 0x1289, 0x2512, 0x0e67, 0x1cce, 0x399c, 0x377b, 0x2ab5, 0x1129, 0x2252, 0x00e7, + 0x01ce, 0x039c, 0x0738, 0x0e70, 0x1ce0, 0x39c0, 0x37c3, 0x2bc5, 0x13c9, 0x2792, 0x0b67, 0x16ce, 0x2d9c, 0x1f7b, 0x3ef6, 0x39af, + 0x371d, 0x2a79, 0x10b1, 0x2162, 0x0687, 0x0d0e, 0x1a1c, 0x3438, 0x2c33, 0x1c25, 0x384a, 0x34d7, 0x2ded, 0x1f99, 0x3f32, 0x3a27, + 0x300d, 0x2459, 0x0cf1, 0x19e2, 0x33c4, 0x23cb, 0x03d5, 0x07aa, 0x0f54, 0x1ea8, 0x3d50, 0x3ee3, 0x3985, 0x3749, 0x2ad1, 0x11e1, + 0x23c2, 0x03c7, 0x078e, 0x0f1c, 0x1e38, 0x3c70, 0x3ca3, 0x3d05, 0x3e49, 0x38d1, 0x35e1, 0x2f81, 0x1b41, 0x3682, 0x2947, 0x16cd, + 0x2d9a, 0x1f77, 0x3eee, 0x399f, 0x377d, 0x2ab9, 0x1131, 0x2262, 0x0087, 0x010e, 0x021c, 0x0438, 0x0870, 0x10e0, 0x21c0, 0x07c3, + 0x0f86, 0x1f0c, 0x3e18, 0x3873, 0x34a5, 0x2d09, 0x1e51, 0x3ca2, 0x3d07, 0x3e4d, 0x38d9, 0x35f1, 0x2fa1, 0x1b01, 0x3602, 0x2847, + 0x14cd, 0x299a, 0x1777, 0x2eee, 0x199f, 0x333e, 0x223f, 0x003d, 0x007a, 0x00f4, 0x01e8, 0x03d0, 0x07a0, 0x0f40, 0x1e80, 0x3d00, + 0x3e43, 0x38c5, 0x35c9, 0x2fd1, 0x1be1, 0x37c2, 0x2bc7, 0x13cd, 0x279a, 0x0b77, 0x16ee, 0x2ddc, 0x1ffb, 0x3ff6, 0x3baf, 0x331d, + 0x2279, 0x00b1, 0x0162, 0x02c4, 0x0588, 0x0b10, 0x1620, 0x2c40, 0x1cc3, 0x3986, 0x374f, 0x2add, 0x11f9, 0x23f2, 0x03a7, 0x074e, + 0x0e9c, 0x1d38, 0x3a70, 0x30a3, 0x2505, 0x0e49, 0x1c92, 0x3924, 0x360b, 0x2855, 0x14e9, 0x29d2, 0x17e7, 0x2fce, 0x1bdf, 0x37be, + 0x2b3f, 0x123d, 0x247a, 0x0cb7, 0x196e, 0x32dc, 0x21fb, 0x07b5, 0x0f6a, 0x1ed4, 0x3da8, 0x3f13, 0x3a65, 0x3089, 0x2551, 0x0ee1, + 0x1dc2, 0x3b84, 0x334b, 0x22d5, 0x01e9, 0x03d2, 0x07a4, 0x0f48, 0x1e90, 0x3d20, 0x3e03, 0x3845, 0x34c9, 0x2dd1, 0x1fe1, 0x3fc2, + 0x3bc7, 0x33cd, 0x23d9, 0x03f1, 0x07e2, 0x0fc4, 0x1f88, 0x3f10, 0x3a63, 0x3085, 0x2549, 0x0ed1, 0x1da2, 0x3b44, 0x32cb, 0x21d5, + 0x07e9, 0x0fd2, 0x1fa4, 0x3f48, 0x3ad3, 0x31e5, 0x2789, 0x0b51, 0x16a2, 0x2d44, 0x1ecb, 0x3d96, 0x3f6f, 0x3a9d, 0x3179, 0x26b1, + 0x0921, 0x1242, 0x2484, 0x0d4b, 0x1a96, 0x352c, 0x2e1b, 0x1875, 0x30ea, 0x2597, 0x0f6d, 0x1eda, 0x3db4, 0x3f2b, 0x3a15, 0x3069, + 0x2491, 0x0d61, 0x1ac2, 0x3584, 0x2f4b, 0x1ad5, 0x35aa, 0x2f17, 0x1a6d, 0x34da, 0x2df7, 0x1fad, 0x3f5a, 0x3af7, 0x31ad, 0x2719, + 0x0a71, 0x14e2, 0x29c4, 0x17cb, 0x2f96, 0x1b6f, 0x36de, 0x29ff, 0x17bd, 0x2f7a, 0x1ab7, 0x356e, 0x2e9f, 0x197d, 0x32fa, 0x21b7, + 0x072d, 0x0e5a, 0x1cb4, 0x3968, 0x3693, 0x2965, 0x1689, 0x2d12, 0x1e67, 0x3cce, 0x3ddf, 0x3ffd, 0x3bb9, 0x3331, 0x2221, 0x0001 + } +}; + +#endif /* CONFIG_SAMA5_HAVE_PMECC && !CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */ diff --git a/arch/arm/src/sama5/sam_gf512.c b/arch/arm/src/sama5/sam_gf512.c new file mode 100644 index 0000000000000000000000000000000000000000..bdbbc678022cfff77ffdf6cf24d22ca5cada50e7 --- /dev/null +++ b/arch/arm/src/sama5/sam_gf512.c @@ -0,0 +1,1095 @@ +/********************************************************************************************************************************** + * arch/arm/src/sama5/sam_gf512.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Taken from Atmel NoOS sample code. The Atmel sample code has a BSD compatible license that requires this copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************************************************/ + +/********************************************************************************************************************************** + * Included Files + **********************************************************************************************************************************/ + +#include +#include + +#include + +#include "sam_pmecc.h" + +#if defined(CONFIG_SAMA5_HAVE_PMECC) && !defined(CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES) + +/********************************************************************************************************************************** + * Public Data + **********************************************************************************************************************************/ + +/* Gallois Field tables for 512 bytes sectors. First raw is "index_of" and second one is "alpha_to" */ + +const uint16_t pmecc_gf512[2][PMECC_GF_SIZEOF_512] = +{ + /* "index_of" table */ + { + 0xffff, 0x0000, 0x0001, 0x03a6, 0x0002, 0x074c, 0x03a7, 0x18c0, 0x0003, 0x1c66, 0x074d, 0x01ea, 0x03a8, 0x005d, 0x18c1, 0x0af2, + 0x0004, 0x0e98, 0x1c67, 0x183e, 0x074e, 0x1181, 0x01eb, 0x0403, 0x03a9, 0x119c, 0x005e, 0x000d, 0x18c2, 0x0590, 0x0af3, 0x1877, + 0x0005, 0x1c1d, 0x0e99, 0x191d, 0x1c68, 0x0d6f, 0x183f, 0x0936, 0x074f, 0x13d9, 0x1182, 0x1542, 0x01ec, 0x03b3, 0x0404, 0x1395, + 0x03aa, 0x1aaa, 0x119d, 0x123e, 0x005f, 0x1be4, 0x000e, 0x0bda, 0x18c3, 0x07a9, 0x0591, 0x1d35, 0x0af4, 0x19ae, 0x1878, 0x1527, + 0x0006, 0x18cd, 0x1c1e, 0x174b, 0x0e9a, 0x03d4, 0x191e, 0x1d54, 0x1c69, 0x057f, 0x0d70, 0x0b4f, 0x1840, 0x00dc, 0x0937, 0x0a5d, + 0x0750, 0x00ba, 0x13da, 0x1e50, 0x1183, 0x15e4, 0x1543, 0x155a, 0x01ed, 0x0f80, 0x03b4, 0x05f3, 0x0405, 0x1138, 0x1396, 0x1f8a, + 0x03ab, 0x0122, 0x1aab, 0x1fc3, 0x119e, 0x1cc3, 0x123f, 0x164b, 0x0060, 0x0cdc, 0x1be5, 0x0a42, 0x000f, 0x1eb9, 0x0bdb, 0x1115, + 0x18c4, 0x173b, 0x07aa, 0x094b, 0x0592, 0x1444, 0x1d36, 0x0759, 0x0af5, 0x10ff, 0x19af, 0x177f, 0x1879, 0x18e8, 0x1528, 0x0247, + 0x0007, 0x05ed, 0x18ce, 0x091f, 0x1c1f, 0x049b, 0x174c, 0x1c8e, 0x0e9b, 0x13ac, 0x03d5, 0x14a5, 0x191f, 0x1b25, 0x1d55, 0x1fe1, + 0x1c6a, 0x169f, 0x0580, 0x1ae1, 0x0d71, 0x0cf1, 0x0b50, 0x136b, 0x1841, 0x0aff, 0x00dd, 0x18d4, 0x0938, 0x194d, 0x0a5e, 0x17ea, + 0x0751, 0x15f6, 0x00bb, 0x04c8, 0x13db, 0x036a, 0x1e51, 0x1bbb, 0x1184, 0x19f1, 0x15e5, 0x02f2, 0x1544, 0x1a28, 0x155b, 0x006a, + 0x01ee, 0x14bb, 0x0f81, 0x126f, 0x03b5, 0x11f9, 0x05f4, 0x0260, 0x0406, 0x01b9, 0x1139, 0x1082, 0x1397, 0x0de8, 0x1f8b, 0x1674, + 0x03ac, 0x1a21, 0x0123, 0x1c73, 0x1aac, 0x1af1, 0x1fc4, 0x189b, 0x119f, 0x00fb, 0x1cc4, 0x0142, 0x1240, 0x0c56, 0x164c, 0x077a, + 0x0061, 0x0e03, 0x0cdd, 0x1309, 0x1be6, 0x18ad, 0x0a43, 0x0482, 0x0010, 0x1a61, 0x1eba, 0x0925, 0x0bdc, 0x0ef5, 0x1116, 0x0c9a, + 0x18c5, 0x0331, 0x173c, 0x1386, 0x07ab, 0x0f4a, 0x094c, 0x14de, 0x0593, 0x11de, 0x1445, 0x1326, 0x1d37, 0x0999, 0x075a, 0x1d67, + 0x0af6, 0x1ef8, 0x1100, 0x0460, 0x19b0, 0x01f7, 0x1780, 0x0340, 0x187a, 0x1900, 0x18e9, 0x0630, 0x1529, 0x0285, 0x0248, 0x198a, + 0x0008, 0x1d30, 0x05ee, 0x177a, 0x18cf, 0x107d, 0x0920, 0x062b, 0x1c20, 0x157f, 0x049c, 0x1ca6, 0x174d, 0x09d6, 0x1c8f, 0x1d92, + 0x0e9c, 0x0303, 0x13ad, 0x029f, 0x03d6, 0x0806, 0x14a6, 0x0a14, 0x1920, 0x06e6, 0x1b26, 0x1c25, 0x1d56, 0x101a, 0x1fe2, 0x059d, + 0x1c6b, 0x1a0b, 0x16a0, 0x06d7, 0x0581, 0x172c, 0x1ae2, 0x19e2, 0x0d72, 0x1884, 0x0cf2, 0x07ba, 0x0b51, 0x012a, 0x136c, 0x12f0, + 0x1842, 0x010e, 0x0b00, 0x15c3, 0x00de, 0x0f0c, 0x18d5, 0x0d3f, 0x0939, 0x043b, 0x194e, 0x1584, 0x0a5f, 0x16cc, 0x17eb, 0x0fe8, + 0x0752, 0x0339, 0x15f7, 0x1dc7, 0x00bc, 0x001a, 0x04c9, 0x0f59, 0x13dc, 0x1c41, 0x036b, 0x0d05, 0x1e52, 0x0abf, 0x1bbc, 0x1e97, + 0x1185, 0x0b20, 0x19f2, 0x0c37, 0x15e6, 0x10ef, 0x02f3, 0x0ffc, 0x1545, 0x020c, 0x1a29, 0x04a1, 0x155c, 0x04e8, 0x006b, 0x102b, + 0x01ef, 0x1040, 0x14bc, 0x0fd5, 0x0f82, 0x0852, 0x1270, 0x129b, 0x03b6, 0x0c79, 0x11fa, 0x1e07, 0x05f5, 0x0ccb, 0x0261, 0x09c0, + 0x0407, 0x056d, 0x01ba, 0x11a9, 0x113a, 0x16af, 0x1083, 0x15fe, 0x1398, 0x0828, 0x0de9, 0x1cab, 0x1f8c, 0x1b07, 0x1675, 0x1c53, + 0x03ad, 0x1eb3, 0x1a22, 0x0993, 0x0124, 0x0cc5, 0x1c74, 0x0318, 0x1aad, 0x0035, 0x1af2, 0x0179, 0x1fc5, 0x0b3a, 0x189c, 0x0841, + 0x11a0, 0x0388, 0x00fc, 0x09f9, 0x1cc5, 0x1f1f, 0x0143, 0x1ecb, 0x1241, 0x0dcc, 0x0c57, 0x1752, 0x164d, 0x184b, 0x077b, 0x14ed, + 0x0062, 0x1b90, 0x0e04, 0x0bf0, 0x0cde, 0x0e1b, 0x130a, 0x1cf3, 0x1be7, 0x0673, 0x18ae, 0x0ea5, 0x0a44, 0x1c7a, 0x0483, 0x1b98, + 0x0011, 0x0c04, 0x1a62, 0x1a45, 0x1ebb, 0x1e87, 0x0926, 0x197a, 0x0bdd, 0x1711, 0x0ef6, 0x09db, 0x1117, 0x10cf, 0x0c9b, 0x1097, + 0x18c6, 0x1a1a, 0x0332, 0x1a13, 0x173d, 0x1436, 0x1387, 0x118e, 0x07ac, 0x100c, 0x0f4b, 0x055f, 0x094d, 0x1428, 0x14df, 0x0665, + 0x0594, 0x10b6, 0x11df, 0x1861, 0x1446, 0x1615, 0x1327, 0x0423, 0x1d38, 0x0606, 0x099a, 0x1c94, 0x075b, 0x053e, 0x1d68, 0x159f, + 0x0af7, 0x0dc4, 0x1ef9, 0x199c, 0x1101, 0x086e, 0x0461, 0x0e7c, 0x19b1, 0x1f61, 0x01f8, 0x13f2, 0x1781, 0x031e, 0x0341, 0x0710, + 0x187b, 0x0410, 0x1901, 0x095b, 0x18ea, 0x1048, 0x0631, 0x1dce, 0x152a, 0x1f47, 0x0286, 0x1d97, 0x0249, 0x0698, 0x198b, 0x1e3f, + 0x0009, 0x01e6, 0x1d31, 0x153e, 0x05ef, 0x0b4b, 0x177b, 0x0a3e, 0x18d0, 0x14a1, 0x107e, 0x02ee, 0x0921, 0x013e, 0x062c, 0x1322, + 0x1c21, 0x1ca2, 0x1580, 0x07b6, 0x049d, 0x0d01, 0x1ca7, 0x1e03, 0x174e, 0x0175, 0x09d7, 0x0ea1, 0x1c90, 0x055b, 0x1d93, 0x13ee, + 0x0e9d, 0x02ea, 0x0304, 0x116a, 0x13ae, 0x1d42, 0x02a0, 0x09a8, 0x03d7, 0x1222, 0x0807, 0x116e, 0x14a7, 0x1ab3, 0x0a15, 0x0c14, + 0x1921, 0x0ab6, 0x06e7, 0x0a88, 0x1b27, 0x07dd, 0x1c26, 0x06c4, 0x1d57, 0x0bca, 0x101b, 0x0308, 0x1fe3, 0x1798, 0x059e, 0x05ae, + 0x1c6c, 0x1744, 0x1a0c, 0x1dc0, 0x16a1, 0x1db9, 0x06d8, 0x12e2, 0x0582, 0x1534, 0x172d, 0x1d46, 0x1ae3, 0x0452, 0x19e3, 0x17dc, + 0x0d73, 0x0a0b, 0x1885, 0x0ed2, 0x0cf3, 0x115c, 0x07bb, 0x17ce, 0x0b52, 0x07d3, 0x012b, 0x13b2, 0x136d, 0x0905, 0x12f1, 0x1487, + 0x1843, 0x1945, 0x010f, 0x0517, 0x0b01, 0x0f6c, 0x15c4, 0x08e4, 0x00df, 0x0b6b, 0x0f0d, 0x09ac, 0x18d6, 0x003b, 0x0d40, 0x0b75, + 0x093a, 0x1a02, 0x043c, 0x145c, 0x194f, 0x1c07, 0x1585, 0x00c3, 0x0a60, 0x07c9, 0x16cd, 0x02a4, 0x17ec, 0x0614, 0x0fe9, 0x19bb, + 0x0753, 0x0bd4, 0x033a, 0x025a, 0x15f8, 0x0d39, 0x1dc8, 0x1974, 0x00bd, 0x06be, 0x001b, 0x1226, 0x04ca, 0x1628, 0x0f5a, 0x106b, + 0x13dd, 0x0be7, 0x1c42, 0x0769, 0x036c, 0x0971, 0x0d06, 0x0ee0, 0x1e53, 0x1f01, 0x0ac0, 0x03db, 0x1bbd, 0x051f, 0x1e98, 0x0a9f, + 0x1186, 0x1893, 0x0b21, 0x146d, 0x19f3, 0x054c, 0x0c38, 0x1bf1, 0x15e7, 0x0c47, 0x10f0, 0x1172, 0x02f4, 0x1af8, 0x0ffd, 0x0e0c, + 0x1546, 0x1f16, 0x020d, 0x072e, 0x1a2a, 0x0d9f, 0x04a2, 0x122c, 0x155d, 0x0272, 0x04e9, 0x080b, 0x006c, 0x089a, 0x102c, 0x02c6, + 0x01f0, 0x143d, 0x1041, 0x16a8, 0x14bd, 0x1c00, 0x0fd6, 0x1475, 0x0f83, 0x15ad, 0x0853, 0x1ab7, 0x1271, 0x0d81, 0x129c, 0x1349, + 0x03b7, 0x065c, 0x0c7a, 0x0faa, 0x11fb, 0x1deb, 0x1e08, 0x17b9, 0x05f6, 0x1d20, 0x0ccc, 0x14ab, 0x0262, 0x1935, 0x09c1, 0x022e, + 0x0408, 0x1ef0, 0x056e, 0x1f36, 0x01bb, 0x0f96, 0x11aa, 0x05be, 0x113b, 0x009a, 0x16b0, 0x0c18, 0x1084, 0x017f, 0x15ff, 0x11c1, + 0x1399, 0x1f3e, 0x0829, 0x1b45, 0x0dea, 0x14c4, 0x1cac, 0x0021, 0x1f8d, 0x1660, 0x1b08, 0x0a19, 0x1676, 0x124b, 0x1c54, 0x1d76, + 0x03ae, 0x0058, 0x1eb4, 0x00d7, 0x1a23, 0x1b20, 0x0994, 0x0c51, 0x0125, 0x09d1, 0x0cc6, 0x0aba, 0x1c75, 0x0b35, 0x0319, 0x1423, + 0x1aae, 0x0139, 0x0036, 0x044d, 0x1af3, 0x1623, 0x017a, 0x0d7c, 0x1fc6, 0x0b30, 0x0b3b, 0x1925, 0x189d, 0x004d, 0x0842, 0x10bf, + 0x11a1, 0x0943, 0x0389, 0x1454, 0x00fd, 0x05dc, 0x09fa, 0x13c0, 0x1cc6, 0x0419, 0x1f20, 0x0a8c, 0x0144, 0x1fcb, 0x1ecc, 0x1a79, + 0x1242, 0x027c, 0x0dcd, 0x06a9, 0x0c58, 0x0645, 0x1753, 0x162e, 0x164e, 0x0dba, 0x184c, 0x06eb, 0x077c, 0x0f35, 0x14ee, 0x0bac, + 0x0063, 0x138e, 0x1b91, 0x12e9, 0x0e05, 0x0c0d, 0x0bf1, 0x1a72, 0x0cdf, 0x0fcb, 0x0e1c, 0x07e1, 0x130b, 0x192a, 0x1cf4, 0x1335, + 0x1be8, 0x1bb2, 0x0674, 0x04b4, 0x18af, 0x1969, 0x0ea6, 0x17a8, 0x0a45, 0x10e5, 0x1c7b, 0x1b2b, 0x0484, 0x1f0b, 0x1b99, 0x12b2, + 0x0012, 0x03cc, 0x0c05, 0x1db1, 0x1a63, 0x0a7d, 0x1a46, 0x0eb7, 0x1ebc, 0x1d88, 0x1e88, 0x06c8, 0x0927, 0x0b40, 0x197b, 0x1ad2, + 0x0bde, 0x1696, 0x1712, 0x0391, 0x0ef7, 0x147c, 0x09dc, 0x04d0, 0x1118, 0x0431, 0x10d0, 0x1c2a, 0x0c9c, 0x0b60, 0x1098, 0x0e4d, + 0x18c7, 0x1ff9, 0x1a1b, 0x05e7, 0x0333, 0x1d2a, 0x1a14, 0x1ead, 0x173e, 0x01e0, 0x1437, 0x0bce, 0x1388, 0x0052, 0x118f, 0x1ff3, + 0x07ad, 0x1835, 0x100d, 0x0913, 0x0f4c, 0x154f, 0x0560, 0x11ed, 0x094e, 0x19a4, 0x1429, 0x1d5b, 0x14e0, 0x0117, 0x0666, 0x1a55, + 0x0595, 0x186f, 0x10b7, 0x13e6, 0x11e0, 0x137b, 0x1862, 0x0532, 0x1447, 0x1641, 0x1616, 0x030c, 0x1328, 0x18a2, 0x0424, 0x0bf8, + 0x1d39, 0x0d66, 0x0607, 0x15b7, 0x099b, 0x1fd6, 0x1c95, 0x1071, 0x075c, 0x00b0, 0x053f, 0x101f, 0x1d69, 0x01ae, 0x15a0, 0x0c6d, + 0x0af8, 0x1195, 0x0dc5, 0x06df, 0x1efa, 0x016e, 0x199d, 0x0b29, 0x1102, 0x12ff, 0x086f, 0x179c, 0x0462, 0x10c4, 0x0e7d, 0x03c0, + 0x19b2, 0x023e, 0x1f62, 0x120e, 0x01f9, 0x0e71, 0x13f3, 0x0e65, 0x1782, 0x0f40, 0x031f, 0x1fe7, 0x0342, 0x10ab, 0x0711, 0x00a4, + 0x187c, 0x13d1, 0x0411, 0x121a, 0x1902, 0x0c2c, 0x095c, 0x088e, 0x18eb, 0x166a, 0x1049, 0x05b2, 0x0632, 0x0847, 0x1dcf, 0x0650, + 0x152b, 0x0576, 0x1f48, 0x0ec6, 0x0287, 0x0fdd, 0x1d98, 0x0f60, 0x024a, 0x13a2, 0x0699, 0x05a2, 0x198c, 0x1574, 0x1e40, 0x1495, + 0x000a, 0x183b, 0x01e7, 0x03a3, 0x1d32, 0x123b, 0x153f, 0x191a, 0x05f0, 0x1e4d, 0x0b4c, 0x1748, 0x177c, 0x0948, 0x0a3f, 0x1fc0, + 0x18d1, 0x1ade, 0x14a2, 0x091c, 0x107f, 0x126c, 0x02ef, 0x04c5, 0x0922, 0x1306, 0x013f, 0x1c70, 0x062d, 0x045d, 0x1323, 0x1383, + 0x1c22, 0x029c, 0x1ca3, 0x1777, 0x1581, 0x15c0, 0x07b7, 0x06d4, 0x049e, 0x0c34, 0x0d02, 0x1dc4, 0x1ca8, 0x11a6, 0x1e04, 0x0fd2, + 0x174f, 0x09f6, 0x0176, 0x0990, 0x09d8, 0x1a42, 0x0ea2, 0x0bed, 0x1c91, 0x185e, 0x055c, 0x1a10, 0x1d94, 0x0958, 0x13ef, 0x1999, + 0x0e9e, 0x07b3, 0x02eb, 0x153b, 0x0305, 0x0a85, 0x116b, 0x1167, 0x13af, 0x0ecf, 0x1d43, 0x1dbd, 0x02a1, 0x1459, 0x09a9, 0x0514, + 0x03d8, 0x0766, 0x1223, 0x0257, 0x0808, 0x072b, 0x116f, 0x146a, 0x14a8, 0x0fa7, 0x1ab4, 0x16a5, 0x0a16, 0x1b42, 0x0c15, 0x1f33, + 0x1922, 0x044a, 0x0ab7, 0x00d4, 0x06e8, 0x06a6, 0x0a89, 0x1451, 0x1b28, 0x04b1, 0x07de, 0x12e6, 0x1c27, 0x038e, 0x06c5, 0x1dae, + 0x1d58, 0x0910, 0x0bcb, 0x05e4, 0x101c, 0x15b4, 0x0309, 0x13e3, 0x1fe4, 0x120b, 0x1799, 0x06dc, 0x059f, 0x0ec3, 0x05af, 0x1217, + 0x1c6d, 0x0919, 0x1745, 0x03a0, 0x1a0d, 0x098d, 0x1dc1, 0x1774, 0x16a2, 0x0254, 0x1dba, 0x1538, 0x06d9, 0x05e1, 0x12e3, 0x00d1, + 0x0583, 0x039a, 0x1535, 0x039d, 0x172e, 0x1bd8, 0x1d47, 0x03f8, 0x1ae4, 0x1109, 0x0453, 0x0586, 0x19e4, 0x0f74, 0x17dd, 0x1c12, + 0x0d74, 0x1dfb, 0x0a0c, 0x03fb, 0x1886, 0x04dc, 0x0ed3, 0x04bd, 0x0cf4, 0x061f, 0x115d, 0x1d4a, 0x07bc, 0x0102, 0x17cf, 0x0ce6, + 0x0b53, 0x1a39, 0x07d4, 0x1bdb, 0x012c, 0x0cb9, 0x13b3, 0x076f, 0x136e, 0x1593, 0x0906, 0x1731, 0x12f2, 0x1f55, 0x1488, 0x18f5, + 0x1844, 0x1013, 0x1946, 0x0589, 0x0110, 0x0046, 0x0518, 0x0554, 0x0b02, 0x0e59, 0x0f6d, 0x0456, 0x15c5, 0x13c5, 0x08e5, 0x068d, + 0x00e0, 0x1da5, 0x0b6c, 0x110c, 0x0f0e, 0x195d, 0x09ad, 0x1ce8, 0x18d7, 0x1417, 0x003c, 0x1ae7, 0x0d41, 0x0dae, 0x0b76, 0x037d, + 0x093b, 0x02e2, 0x1a03, 0x1c15, 0x043d, 0x178c, 0x145d, 0x0294, 0x1950, 0x08d8, 0x1c08, 0x17e0, 0x1586, 0x09ff, 0x00c4, 0x1721, + 0x0a61, 0x0f9e, 0x07ca, 0x0f77, 0x16ce, 0x0f8a, 0x02a5, 0x1c48, 0x17ed, 0x02ba, 0x0615, 0x19e7, 0x0fea, 0x06b2, 0x19bc, 0x1c36, + 0x0754, 0x1555, 0x0bd5, 0x03fe, 0x033b, 0x047d, 0x025b, 0x1366, 0x15f9, 0x0ff7, 0x0d3a, 0x0a0f, 0x1dc9, 0x041e, 0x1975, 0x1ec6, + 0x00be, 0x17c9, 0x06bf, 0x1dfe, 0x001c, 0x17b4, 0x1227, 0x0edb, 0x04cb, 0x17a3, 0x1629, 0x0d77, 0x0f5b, 0x0e60, 0x106c, 0x11e8, + 0x13de, 0x1465, 0x0be8, 0x04c0, 0x1c43, 0x1ce3, 0x076a, 0x03f3, 0x036d, 0x190a, 0x0972, 0x0ed6, 0x0d07, 0x1ccb, 0x0ee1, 0x07e8, + 0x1e54, 0x1e28, 0x1f02, 0x04df, 0x0ac1, 0x07f3, 0x03dc, 0x0977, 0x1bbe, 0x1122, 0x0520, 0x1889, 0x1e99, 0x1a92, 0x0aa0, 0x19c9, + 0x1187, 0x0f52, 0x1894, 0x1d4d, 0x0b22, 0x1a6b, 0x146e, 0x12db, 0x19f4, 0x12d4, 0x054d, 0x1160, 0x0c39, 0x0a91, 0x1bf2, 0x1b37, + 0x15e8, 0x135d, 0x0c48, 0x0622, 0x10f1, 0x0a4f, 0x1173, 0x190f, 0x02f5, 0x19d4, 0x1af9, 0x0cf7, 0x0ffe, 0x1e31, 0x0e0d, 0x09eb, + 0x1547, 0x0969, 0x1f17, 0x0ce9, 0x020e, 0x17fa, 0x072f, 0x1bd0, 0x1a2b, 0x1766, 0x0da0, 0x17d2, 0x04a3, 0x1f25, 0x122d, 0x0982, + 0x155e, 0x1e1f, 0x0273, 0x0105, 0x04ea, 0x1abe, 0x080c, 0x0372, 0x006d, 0x12be, 0x089b, 0x07bf, 0x102d, 0x0e32, 0x02c7, 0x08cd, + 0x01f1, 0x11f3, 0x143e, 0x1bde, 0x1042, 0x1e81, 0x16a9, 0x0f06, 0x14be, 0x0d99, 0x1c01, 0x07d7, 0x0fd7, 0x1fd0, 0x1476, 0x063f, + 0x0f84, 0x0cb3, 0x15ae, 0x1a3c, 0x0854, 0x0737, 0x1ab8, 0x07ed, 0x1272, 0x0876, 0x0d82, 0x0b56, 0x129d, 0x0b09, 0x134a, 0x1822, + 0x03b8, 0x1341, 0x065d, 0x0772, 0x0c7b, 0x0158, 0x0fab, 0x0685, 0x11fc, 0x125d, 0x1dec, 0x13b6, 0x1e09, 0x0149, 0x17ba, 0x0e23, + 0x05f7, 0x1e78, 0x1d21, 0x0cbc, 0x0ccd, 0x073d, 0x14ac, 0x0ee6, 0x0263, 0x1ddc, 0x1936, 0x012f, 0x09c2, 0x0a6e, 0x022f, 0x019f, + 0x0409, 0x0566, 0x1ef1, 0x1734, 0x056f, 0x168f, 0x1f37, 0x19fb, 0x01bc, 0x1e18, 0x0f97, 0x0909, 0x11ab, 0x1a7e, 0x05bf, 0x0fb3, + 0x113c, 0x16db, 0x009b, 0x1596, 0x16b1, 0x1056, 0x0c19, 0x1cd0, 0x1085, 0x021c, 0x0180, 0x1371, 0x1600, 0x0b87, 0x11c2, 0x16e4, + 0x139a, 0x1658, 0x1f3f, 0x18f8, 0x082a, 0x1b6c, 0x1b46, 0x02b2, 0x0deb, 0x01cc, 0x14c5, 0x148b, 0x1cad, 0x1ed1, 0x0022, 0x1808, + 0x1f8e, 0x01c3, 0x1661, 0x1f58, 0x1b09, 0x085a, 0x0a1a, 0x0d0c, 0x1677, 0x1b4e, 0x124c, 0x12f5, 0x1c55, 0x1700, 0x1d77, 0x1d0f, + 0x03af, 0x19aa, 0x0059, 0x058c, 0x1eb5, 0x18e4, 0x00d8, 0x1134, 0x1a24, 0x0de4, 0x1b21, 0x1949, 0x0995, 0x0281, 0x0c52, 0x0ef1, + 0x0126, 0x16c8, 0x09d2, 0x1016, 0x0cc7, 0x1b03, 0x0abb, 0x04e4, 0x1c76, 0x10cb, 0x0b36, 0x1847, 0x031a, 0x0694, 0x1424, 0x053a, + 0x1aaf, 0x1794, 0x013a, 0x0557, 0x0037, 0x0610, 0x044e, 0x0901, 0x1af4, 0x0896, 0x1624, 0x051b, 0x017b, 0x1247, 0x0d7d, 0x1931, + 0x1fc7, 0x0f31, 0x0b31, 0x0049, 0x0b3c, 0x0b5c, 0x1926, 0x1f07, 0x189e, 0x01aa, 0x004e, 0x0113, 0x0843, 0x1570, 0x10c0, 0x10a7, + 0x11a2, 0x0954, 0x0944, 0x0459, 0x038a, 0x0ebf, 0x1455, 0x1b3e, 0x00fe, 0x1f51, 0x05dd, 0x0f70, 0x09fb, 0x06ae, 0x13c1, 0x0daa, + 0x1cc7, 0x1a8e, 0x041a, 0x0e5c, 0x1f21, 0x0e2e, 0x0a8d, 0x1e2d, 0x0145, 0x0a6a, 0x1fcc, 0x0b05, 0x1ecd, 0x16fc, 0x1a7a, 0x0b83, + 0x1243, 0x156c, 0x027d, 0x0690, 0x0dce, 0x1510, 0x06aa, 0x16f8, 0x0c59, 0x0d4e, 0x0646, 0x08e8, 0x1754, 0x0dd2, 0x162f, 0x00e9, + 0x164f, 0x0fba, 0x0dbb, 0x13c8, 0x184d, 0x0d88, 0x06ec, 0x1e59, 0x077d, 0x08a5, 0x0f36, 0x15c8, 0x14ef, 0x1514, 0x0bad, 0x1f6b, + 0x0064, 0x1d61, 0x138f, 0x110f, 0x1b92, 0x070a, 0x12ea, 0x09ba, 0x0e06, 0x11bb, 0x0c0e, 0x0b6f, 0x0bf2, 0x064a, 0x1a73, 0x1acc, + 0x0ce0, 0x171b, 0x0fcc, 0x1da8, 0x0e1d, 0x1802, 0x07e2, 0x097c, 0x130c, 0x0469, 0x192b, 0x00e3, 0x1cf5, 0x08ec, 0x1336, 0x1fad, + 0x1be9, 0x052a, 0x1bb3, 0x1ceb, 0x0675, 0x08bd, 0x04b5, 0x067d, 0x18b0, 0x0c8a, 0x196a, 0x09b0, 0x0ea7, 0x0c5d, 0x17a9, 0x1312, + 0x0a46, 0x0f1b, 0x10e6, 0x1960, 0x1c7c, 0x087c, 0x1b2c, 0x03e1, 0x0485, 0x04f8, 0x1f0c, 0x0f11, 0x1b9a, 0x0d52, 0x12b3, 0x0084, + 0x0013, 0x142f, 0x03cd, 0x1aea, 0x0c06, 0x0167, 0x1db2, 0x1bf9, 0x1a64, 0x1688, 0x0a7e, 0x003f, 0x1a47, 0x1633, 0x0eb8, 0x0160, + 0x1ebd, 0x1b82, 0x1d89, 0x141a, 0x1e89, 0x081a, 0x06c9, 0x07f8, 0x0928, 0x0e8a, 0x0b41, 0x18da, 0x197c, 0x00ed, 0x1ad3, 0x035c, + 0x0bdf, 0x182d, 0x1697, 0x0380, 0x1713, 0x1409, 0x0392, 0x0cab, 0x0ef8, 0x1e6a, 0x147d, 0x0b79, 0x09dd, 0x1758, 0x04d1, 0x046f, + 0x1119, 0x05c6, 0x0432, 0x0db1, 0x10d1, 0x1278, 0x1c2b, 0x0ac6, 0x0c9d, 0x1b74, 0x0b61, 0x0d44, 0x1099, 0x0dd6, 0x0e4e, 0x1502, + 0x18c8, 0x011d, 0x1ffa, 0x1c18, 0x1a1c, 0x032c, 0x05e8, 0x15f1, 0x0334, 0x103b, 0x1d2b, 0x1a06, 0x1a15, 0x0dbf, 0x1eae, 0x1b8b, + 0x173f, 0x1940, 0x01e1, 0x02e5, 0x1438, 0x1eeb, 0x0bcf, 0x188e, 0x1389, 0x03c7, 0x0053, 0x093e, 0x1190, 0x13cc, 0x1ff4, 0x186a, + 0x07ae, 0x0445, 0x1836, 0x0297, 0x100e, 0x02dd, 0x0914, 0x1df6, 0x0f4d, 0x0964, 0x1550, 0x1460, 0x0561, 0x1653, 0x11ee, 0x133c, + 0x094f, 0x1567, 0x19a5, 0x178f, 0x142a, 0x1828, 0x1d5c, 0x0525, 0x14e1, 0x05cf, 0x0118, 0x0440, 0x0667, 0x0fbe, 0x1a56, 0x0e40, + 0x0596, 0x14e6, 0x1870, 0x17e3, 0x10b8, 0x1a4e, 0x13e7, 0x0a98, 0x11e1, 0x181b, 0x137c, 0x1c0b, 0x1863, 0x06f0, 0x0533, 0x1fa6, + 0x1448, 0x16ef, 0x1642, 0x08db, 0x1617, 0x0f24, 0x030d, 0x1127, 0x1329, 0x06fd, 0x18a3, 0x1953, 0x0425, 0x1e5d, 0x0bf9, 0x034f, + 0x1d3a, 0x05d4, 0x0d67, 0x1724, 0x0608, 0x02d5, 0x15b8, 0x1cdb, 0x099c, 0x071e, 0x1fd7, 0x00c7, 0x1c96, 0x1851, 0x1072, 0x1fb3, + 0x075d, 0x1a85, 0x00b1, 0x0a02, 0x0540, 0x1350, 0x1020, 0x1bc3, 0x1d6a, 0x1b5f, 0x01af, 0x1589, 0x15a1, 0x0d8c, 0x0c6e, 0x0192, + 0x0af9, 0x1a5b, 0x1196, 0x0f7a, 0x0dc6, 0x0600, 0x06e0, 0x0206, 0x1efb, 0x1d1a, 0x016f, 0x07cd, 0x199e, 0x0f3a, 0x0b2a, 0x10df, + 0x1103, 0x1411, 0x1300, 0x0fa1, 0x0870, 0x0216, 0x179d, 0x19ce, 0x0463, 0x0e84, 0x10c5, 0x0a64, 0x0e7e, 0x15cc, 0x03c1, 0x06f7, + 0x19b3, 0x0e45, 0x023f, 0x1c4b, 0x1f63, 0x018a, 0x120f, 0x08c5, 0x01fa, 0x0bb8, 0x0e72, 0x02a8, 0x13f4, 0x0781, 0x0e66, 0x1cfb, + 0x1783, 0x1400, 0x0f41, 0x0f8d, 0x0320, 0x0b0f, 0x1fe8, 0x0aa5, 0x0343, 0x1286, 0x10ac, 0x16d1, 0x0712, 0x08a9, 0x00a5, 0x0d17, + 0x187d, 0x066c, 0x13d2, 0x19ea, 0x0412, 0x163a, 0x121b, 0x0c40, 0x1903, 0x1256, 0x0c2d, 0x0618, 0x095d, 0x0bb1, 0x088f, 0x0c83, + 0x18ec, 0x007b, 0x166b, 0x02bd, 0x104a, 0x0ad4, 0x05b3, 0x1a97, 0x0633, 0x15d2, 0x0848, 0x17f0, 0x1dd0, 0x1f6f, 0x0651, 0x1145, + 0x152c, 0x0fc3, 0x0577, 0x1c39, 0x1f49, 0x1813, 0x0ec7, 0x12cc, 0x0288, 0x1f97, 0x0fde, 0x19bf, 0x1d99, 0x14f3, 0x0f61, 0x08f2, + 0x024b, 0x11b2, 0x13a3, 0x06b5, 0x069a, 0x12a3, 0x05a3, 0x1e9e, 0x198d, 0x0832, 0x1575, 0x0fed, 0x1e41, 0x1518, 0x1496, 0x14cf, + 0x000b, 0x1875, 0x183c, 0x0401, 0x01e8, 0x0af0, 0x03a4, 0x18be, 0x1d33, 0x1525, 0x123c, 0x0bd8, 0x1540, 0x1393, 0x191b, 0x0934, + 0x05f1, 0x1f88, 0x1e4e, 0x1558, 0x0b4d, 0x0a5b, 0x1749, 0x1d52, 0x177d, 0x0245, 0x0949, 0x0757, 0x0a40, 0x1113, 0x1fc1, 0x1649, + 0x18d2, 0x17e8, 0x1adf, 0x1369, 0x14a3, 0x1fdf, 0x091d, 0x1c8c, 0x1080, 0x1672, 0x126d, 0x025e, 0x02f0, 0x0068, 0x04c6, 0x1bb9, + 0x0923, 0x0c98, 0x1307, 0x0480, 0x0140, 0x0778, 0x1c71, 0x1899, 0x062e, 0x1988, 0x045e, 0x033e, 0x1324, 0x1d65, 0x1384, 0x14dc, + 0x1c23, 0x059b, 0x029d, 0x0a12, 0x1ca4, 0x1d90, 0x1778, 0x0629, 0x1582, 0x0fe6, 0x15c1, 0x0d3d, 0x07b8, 0x12ee, 0x06d5, 0x19e0, + 0x049f, 0x1029, 0x0c35, 0x0ffa, 0x0d03, 0x1e95, 0x1dc5, 0x0f57, 0x1ca9, 0x1c51, 0x11a7, 0x15fc, 0x1e05, 0x09be, 0x0fd3, 0x1299, + 0x1750, 0x14eb, 0x09f7, 0x1ec9, 0x0177, 0x083f, 0x0991, 0x0316, 0x09d9, 0x1095, 0x1a43, 0x1978, 0x0ea3, 0x1b96, 0x0bee, 0x1cf1, + 0x1c92, 0x159d, 0x185f, 0x0421, 0x055d, 0x0663, 0x1a11, 0x118c, 0x1d95, 0x1e3d, 0x0959, 0x1dcc, 0x13f0, 0x070e, 0x199a, 0x0e7a, + 0x0e9f, 0x13ec, 0x07b4, 0x1e01, 0x02ec, 0x1320, 0x153c, 0x0a3c, 0x0306, 0x05ac, 0x0a86, 0x06c2, 0x116c, 0x0c12, 0x1168, 0x09a6, + 0x13b0, 0x1485, 0x0ed0, 0x17cc, 0x1d44, 0x17da, 0x1dbe, 0x12e0, 0x02a2, 0x19b9, 0x145a, 0x00c1, 0x09aa, 0x0b73, 0x0515, 0x08e2, + 0x03d9, 0x0a9d, 0x0767, 0x0ede, 0x1224, 0x1069, 0x0258, 0x1972, 0x0809, 0x02c4, 0x072c, 0x122a, 0x1170, 0x0e0a, 0x146b, 0x1bef, + 0x14a9, 0x022c, 0x0fa8, 0x17b7, 0x1ab5, 0x1347, 0x16a6, 0x1473, 0x0a17, 0x1d74, 0x1b43, 0x001f, 0x0c16, 0x11bf, 0x1f34, 0x05bc, + 0x1923, 0x10bd, 0x044b, 0x0d7a, 0x0ab8, 0x1421, 0x00d5, 0x0c4f, 0x06e9, 0x0baa, 0x06a7, 0x162c, 0x0a8a, 0x1a77, 0x1452, 0x13be, + 0x1b29, 0x12b0, 0x04b2, 0x17a6, 0x07df, 0x1333, 0x12e7, 0x1a70, 0x1c28, 0x0e4b, 0x038f, 0x04ce, 0x06c6, 0x1ad0, 0x1daf, 0x0eb5, + 0x1d59, 0x1a53, 0x0911, 0x11eb, 0x0bcc, 0x1ff1, 0x05e5, 0x1eab, 0x101d, 0x0c6b, 0x15b5, 0x106f, 0x030a, 0x0bf6, 0x13e4, 0x0530, + 0x1fe5, 0x00a2, 0x120c, 0x0e63, 0x179a, 0x03be, 0x06dd, 0x0b27, 0x05a0, 0x1493, 0x0ec4, 0x0f5e, 0x05b0, 0x064e, 0x1218, 0x088c, + 0x1c6e, 0x1381, 0x091a, 0x04c3, 0x1746, 0x1fbe, 0x03a1, 0x1918, 0x1a0e, 0x1997, 0x098e, 0x0beb, 0x1dc2, 0x0fd0, 0x1775, 0x06d2, + 0x16a3, 0x1f31, 0x0255, 0x1468, 0x1dbb, 0x0512, 0x1539, 0x1165, 0x06da, 0x1215, 0x05e2, 0x13e1, 0x12e4, 0x1dac, 0x00d2, 0x144f, + 0x0584, 0x1c10, 0x039b, 0x03f6, 0x1536, 0x00cf, 0x039e, 0x1772, 0x172f, 0x18f3, 0x1bd9, 0x076d, 0x1d48, 0x0ce4, 0x03f9, 0x04bb, + 0x1ae5, 0x037b, 0x110a, 0x1ce6, 0x0454, 0x068b, 0x0587, 0x0552, 0x19e5, 0x1c34, 0x0f75, 0x1c46, 0x17de, 0x171f, 0x1c13, 0x0292, + 0x0d75, 0x11e6, 0x1dfc, 0x0ed9, 0x0a0d, 0x1ec4, 0x03fc, 0x1364, 0x1887, 0x19c7, 0x04dd, 0x0975, 0x0ed4, 0x07e6, 0x04be, 0x03f1, + 0x0cf5, 0x09e9, 0x0620, 0x190d, 0x115e, 0x1b35, 0x1d4b, 0x12d9, 0x07bd, 0x08cb, 0x0103, 0x0370, 0x17d0, 0x0980, 0x0ce7, 0x1bce, + 0x0b54, 0x1820, 0x1a3a, 0x07eb, 0x07d5, 0x063d, 0x1bdc, 0x0f04, 0x012d, 0x019d, 0x0cba, 0x0ee4, 0x13b4, 0x0e21, 0x0770, 0x0683, + 0x136f, 0x16e2, 0x1594, 0x1cce, 0x0907, 0x0fb1, 0x1732, 0x19f9, 0x12f3, 0x1d0d, 0x1f56, 0x0d0a, 0x1489, 0x1806, 0x18f6, 0x02b0, + 0x1845, 0x0538, 0x1014, 0x04e2, 0x1947, 0x0eef, 0x058a, 0x1132, 0x0111, 0x10a5, 0x0047, 0x1f05, 0x0519, 0x192f, 0x0555, 0x08ff, + 0x0b03, 0x0b81, 0x0e5a, 0x1e2b, 0x0f6e, 0x0da8, 0x0457, 0x1b3c, 0x15c6, 0x1f69, 0x13c6, 0x1e57, 0x08e6, 0x00e7, 0x068e, 0x16f6, + 0x00e1, 0x1fab, 0x1da6, 0x097a, 0x0b6d, 0x1aca, 0x110d, 0x09b8, 0x0f0f, 0x0082, 0x195e, 0x03df, 0x09ae, 0x1310, 0x1ce9, 0x067b, + 0x18d8, 0x035a, 0x1418, 0x07f6, 0x003d, 0x015e, 0x1ae8, 0x1bf7, 0x0d42, 0x1500, 0x0daf, 0x0ac4, 0x0b77, 0x046d, 0x037e, 0x0ca9, + 0x093c, 0x1868, 0x02e3, 0x188c, 0x1a04, 0x1b89, 0x1c16, 0x15ef, 0x043e, 0x0e3e, 0x178d, 0x0523, 0x145e, 0x133a, 0x0295, 0x1df4, + 0x1951, 0x034d, 0x08d9, 0x1125, 0x1c09, 0x1fa4, 0x17e1, 0x0a96, 0x1587, 0x0190, 0x0a00, 0x1bc1, 0x00c5, 0x1fb1, 0x1722, 0x1cd9, + 0x0a62, 0x06f5, 0x0f9f, 0x19cc, 0x07cb, 0x10dd, 0x0f78, 0x0204, 0x16cf, 0x0d15, 0x0f8b, 0x0aa3, 0x02a6, 0x1cf9, 0x1c49, 0x08c3, + 0x17ee, 0x1143, 0x02bb, 0x1a95, 0x0616, 0x0c81, 0x19e8, 0x0c3e, 0x0feb, 0x14cd, 0x06b3, 0x1e9c, 0x19bd, 0x08f0, 0x1c37, 0x12ca, + 0x0755, 0x1647, 0x1556, 0x1d50, 0x0bd6, 0x0932, 0x03ff, 0x18bc, 0x033c, 0x14da, 0x047e, 0x1897, 0x025c, 0x1bb7, 0x1367, 0x1c8a, + 0x15fa, 0x1297, 0x0ff8, 0x0f55, 0x0d3b, 0x19de, 0x0a10, 0x0627, 0x1dca, 0x0e78, 0x041f, 0x118a, 0x1976, 0x1cef, 0x1ec7, 0x0314, + 0x00bf, 0x08e0, 0x17ca, 0x12de, 0x06c0, 0x09a4, 0x1dff, 0x0a3a, 0x001d, 0x05ba, 0x17b5, 0x1471, 0x1228, 0x1bed, 0x0edc, 0x1970, + 0x04cc, 0x0eb3, 0x17a4, 0x1a6e, 0x162a, 0x13bc, 0x0d78, 0x0c4d, 0x0f5c, 0x088a, 0x0e61, 0x0b25, 0x106d, 0x052e, 0x11e9, 0x1ea9, + 0x13df, 0x144d, 0x1466, 0x1163, 0x0be9, 0x06d0, 0x04c1, 0x1916, 0x1c44, 0x0290, 0x1ce4, 0x0550, 0x076b, 0x04b9, 0x03f4, 0x1770, + 0x036e, 0x1bcc, 0x190b, 0x12d7, 0x0973, 0x03ef, 0x0ed7, 0x1362, 0x0d08, 0x02ae, 0x1ccc, 0x19f7, 0x0ee2, 0x0681, 0x07e9, 0x0f02, + 0x1e55, 0x16f4, 0x1e29, 0x1b3a, 0x1f03, 0x08fd, 0x04e0, 0x1130, 0x0ac2, 0x0ca7, 0x07f4, 0x1bf5, 0x03dd, 0x0679, 0x0978, 0x09b6, + 0x1bbf, 0x1cd7, 0x1123, 0x0a94, 0x0521, 0x1df2, 0x188a, 0x15ed, 0x1e9a, 0x12c8, 0x1a93, 0x0c3c, 0x0aa1, 0x08c1, 0x19ca, 0x0202, + 0x1188, 0x0312, 0x0f53, 0x0625, 0x1895, 0x1c88, 0x1d4e, 0x18ba, 0x0b23, 0x1ea7, 0x1a6c, 0x0c4b, 0x146f, 0x196e, 0x12dc, 0x0a38, + 0x19f5, 0x0f00, 0x12d5, 0x1360, 0x054e, 0x176e, 0x1161, 0x1914, 0x0c3a, 0x0200, 0x0a92, 0x15eb, 0x1bf3, 0x09b4, 0x1b38, 0x112e, + 0x15e9, 0x112c, 0x135e, 0x1912, 0x0c49, 0x0a36, 0x0623, 0x18b8, 0x10f2, 0x1a9e, 0x0a50, 0x1176, 0x1174, 0x18b4, 0x1910, 0x18b6, + 0x02f6, 0x048f, 0x19d5, 0x0a52, 0x1afa, 0x1263, 0x0cf8, 0x1178, 0x0fff, 0x11d2, 0x1e32, 0x10f4, 0x0e0e, 0x0c8e, 0x09ec, 0x1aa0, + 0x1548, 0x161c, 0x096a, 0x0cfa, 0x1f18, 0x07ff, 0x0cea, 0x117a, 0x020f, 0x1ee4, 0x17fb, 0x1afc, 0x0730, 0x17ad, 0x1bd1, 0x1265, + 0x1a2c, 0x1150, 0x1767, 0x19d7, 0x0da1, 0x050b, 0x17d3, 0x0a54, 0x04a4, 0x0bbe, 0x1f26, 0x02f8, 0x122e, 0x1316, 0x0983, 0x0491, + 0x155f, 0x0f29, 0x1e20, 0x09ee, 0x0274, 0x0aae, 0x0106, 0x1aa2, 0x04eb, 0x1ba6, 0x1abf, 0x0e10, 0x080d, 0x0eab, 0x0373, 0x0c90, + 0x006e, 0x0c20, 0x12bf, 0x1e34, 0x089c, 0x1202, 0x07c0, 0x10f6, 0x102e, 0x01d4, 0x0e33, 0x1001, 0x02c8, 0x0c61, 0x08ce, 0x11d4, + 0x01f2, 0x18a8, 0x11f4, 0x0cec, 0x143f, 0x15df, 0x1bdf, 0x117c, 0x1043, 0x1610, 0x1e82, 0x1f1a, 0x16aa, 0x10ea, 0x0f07, 0x0801, + 0x14bf, 0x1de6, 0x0d9a, 0x096c, 0x1c02, 0x1157, 0x07d8, 0x0cfc, 0x0fd8, 0x0e6c, 0x1fd1, 0x154a, 0x1477, 0x1964, 0x0640, 0x161e, + 0x0f85, 0x1958, 0x0cb4, 0x1bd3, 0x15af, 0x0726, 0x1a3d, 0x1267, 0x0855, 0x1051, 0x0738, 0x0732, 0x1ab9, 0x0a4a, 0x07ee, 0x17af, + 0x1273, 0x0815, 0x0877, 0x17fd, 0x0d83, 0x0e29, 0x0b57, 0x1afe, 0x129e, 0x0acf, 0x0b0a, 0x0211, 0x134b, 0x0f1f, 0x1823, 0x1ee6, + 0x03b9, 0x132e, 0x1342, 0x17d5, 0x065e, 0x1e90, 0x0773, 0x0a56, 0x0c7c, 0x1f9f, 0x0159, 0x0da3, 0x0fac, 0x1b30, 0x0686, 0x050d, + 0x11fd, 0x0506, 0x125e, 0x1769, 0x1ded, 0x03ea, 0x13b7, 0x19d9, 0x1e0a, 0x1d01, 0x014a, 0x1a2e, 0x17bb, 0x03e5, 0x0e24, 0x1152, + 0x05f8, 0x0702, 0x1e79, 0x0985, 0x1d22, 0x0d31, 0x0cbd, 0x0493, 0x0cce, 0x1f7c, 0x073e, 0x1230, 0x14ad, 0x1c80, 0x0ee7, 0x1318, + 0x0264, 0x105d, 0x1ddd, 0x1f28, 0x1937, 0x17c0, 0x0130, 0x02fa, 0x09c3, 0x0b9e, 0x0a6f, 0x04a6, 0x0230, 0x0880, 0x01a0, 0x0bc0, + 0x040a, 0x0bfe, 0x0567, 0x0108, 0x1ef2, 0x14b5, 0x1735, 0x1aa4, 0x0570, 0x0d60, 0x1690, 0x0276, 0x1f38, 0x1f10, 0x19fc, 0x0ab0, + 0x01bd, 0x1e72, 0x1e19, 0x1e22, 0x0f98, 0x1a33, 0x090a, 0x09f0, 0x11ac, 0x13fa, 0x1a7f, 0x1561, 0x05c0, 0x0f15, 0x0fb4, 0x0f2b, + 0x113d, 0x0354, 0x16dc, 0x0375, 0x009c, 0x0226, 0x1597, 0x0c92, 0x16b2, 0x0adb, 0x1057, 0x080f, 0x0c1a, 0x0489, 0x1cd1, 0x0ead, + 0x1086, 0x0ae1, 0x021d, 0x1ac1, 0x0181, 0x014f, 0x1372, 0x0e12, 0x1601, 0x0d22, 0x0b88, 0x04ed, 0x11c3, 0x04fc, 0x16e5, 0x1ba8, + 0x139b, 0x042a, 0x1659, 0x07c2, 0x1f40, 0x0821, 0x18f9, 0x10f8, 0x082b, 0x1b58, 0x1b6d, 0x089e, 0x1b47, 0x12b7, 0x02b3, 0x1204, + 0x0dec, 0x0b97, 0x01cd, 0x12c1, 0x14c6, 0x1d06, 0x148c, 0x1e36, 0x1cae, 0x0787, 0x1ed2, 0x0070, 0x0023, 0x0088, 0x1809, 0x0c22, + 0x1f8f, 0x1e62, 0x01c4, 0x08d0, 0x1662, 0x0092, 0x1f59, 0x11d6, 0x1b0a, 0x0a23, 0x085b, 0x02ca, 0x0a1b, 0x1b9e, 0x0d0d, 0x0c63, + 0x1678, 0x16b8, 0x1b4f, 0x0e35, 0x124d, 0x1e0f, 0x12f6, 0x1003, 0x1c56, 0x0df3, 0x1701, 0x1030, 0x1d78, 0x0d56, 0x1d10, 0x01d6, + 0x03b0, 0x0d6c, 0x19ab, 0x1be1, 0x005a, 0x0749, 0x058d, 0x117e, 0x1eb6, 0x1cc0, 0x18e5, 0x1441, 0x00d9, 0x03d1, 0x1135, 0x15e1, + 0x1a25, 0x0367, 0x0de5, 0x11f6, 0x1b22, 0x0498, 0x194a, 0x0cee, 0x0996, 0x0f47, 0x0282, 0x01f4, 0x0c53, 0x1aee, 0x0ef2, 0x18aa, + 0x0127, 0x1729, 0x16c9, 0x0f09, 0x09d3, 0x107a, 0x1017, 0x0803, 0x0cc8, 0x084f, 0x1b04, 0x16ac, 0x0abc, 0x0017, 0x04e5, 0x10ec, + 0x1c77, 0x0e18, 0x10cc, 0x1e84, 0x0b37, 0x0cc2, 0x1848, 0x1f1c, 0x031b, 0x086b, 0x0695, 0x1045, 0x1425, 0x1433, 0x053b, 0x1612, + 0x1ab0, 0x1d3f, 0x1795, 0x07da, 0x013b, 0x0b48, 0x0558, 0x0cfe, 0x0038, 0x0f69, 0x0611, 0x1c04, 0x044f, 0x1db6, 0x0902, 0x1159, + 0x1af5, 0x0549, 0x0897, 0x0d9c, 0x1625, 0x0d36, 0x051c, 0x096e, 0x017c, 0x0f93, 0x1248, 0x14c1, 0x0d7e, 0x1bfd, 0x1932, 0x1de8, + 0x1fc8, 0x05d9, 0x0f32, 0x0642, 0x0b32, 0x1b1d, 0x004a, 0x1620, 0x0b3d, 0x0a7a, 0x0b5d, 0x1479, 0x1927, 0x0c0a, 0x1f08, 0x1966, + 0x189f, 0x1378, 0x01ab, 0x1fd3, 0x004f, 0x1d27, 0x0114, 0x154c, 0x0844, 0x0c29, 0x1571, 0x0fda, 0x10c1, 0x016b, 0x10a8, 0x0e6e, + 0x11a3, 0x15bd, 0x0955, 0x1a3f, 0x0945, 0x1238, 0x045a, 0x1269, 0x038b, 0x06a3, 0x0ec0, 0x15b1, 0x1456, 0x0a82, 0x1b3f, 0x0728, + 0x00ff, 0x04d9, 0x1f52, 0x0cb6, 0x05de, 0x098a, 0x0f71, 0x1bd5, 0x09fc, 0x1789, 0x06af, 0x0f87, 0x13c2, 0x0043, 0x0dab, 0x195a, + 0x1cc8, 0x1ce0, 0x1a8f, 0x07f0, 0x041b, 0x047a, 0x0e5d, 0x17b1, 0x1f22, 0x17f7, 0x0e2f, 0x1abb, 0x0a8e, 0x1a68, 0x1e2e, 0x0a4c, + 0x0146, 0x0155, 0x0a6b, 0x073a, 0x1fcd, 0x1e7e, 0x0b06, 0x0734, 0x1ece, 0x1b69, 0x16fd, 0x0857, 0x1a7b, 0x168c, 0x0b84, 0x1053, + 0x1244, 0x060d, 0x156d, 0x0b59, 0x027e, 0x18e1, 0x0691, 0x1b00, 0x0dcf, 0x150d, 0x1511, 0x0d85, 0x06ab, 0x0ebc, 0x16f9, 0x0e2b, + 0x0c5a, 0x08ba, 0x0d4f, 0x0879, 0x0647, 0x0707, 0x08e9, 0x17ff, 0x1755, 0x1406, 0x0dd3, 0x1275, 0x1630, 0x0164, 0x00ea, 0x0817, + 0x1650, 0x02da, 0x0fbb, 0x1825, 0x0dbc, 0x0329, 0x13c9, 0x1ee8, 0x184e, 0x02d2, 0x0d89, 0x134d, 0x06ed, 0x1a4b, 0x1e5a, 0x0f21, + 0x077e, 0x0187, 0x08a6, 0x0b0c, 0x0f37, 0x05fd, 0x15c9, 0x0213, 0x14f0, 0x1810, 0x1515, 0x12a0, 0x0bae, 0x1637, 0x1f6c, 0x0ad1, + 0x0065, 0x1fdc, 0x1d62, 0x0775, 0x1390, 0x0aed, 0x1110, 0x0a58, 0x1b93, 0x083c, 0x070b, 0x0660, 0x12eb, 0x1d8d, 0x09bb, 0x1e92, + 0x0e07, 0x1066, 0x11bc, 0x1344, 0x0c0f, 0x131d, 0x0b70, 0x17d7, 0x0bf3, 0x1fee, 0x064b, 0x03bb, 0x1a74, 0x141e, 0x1acd, 0x1330, + 0x0ce1, 0x00cc, 0x171c, 0x0688, 0x0fcd, 0x1fbb, 0x1da9, 0x050f, 0x0e1e, 0x063a, 0x1803, 0x0fae, 0x07e3, 0x1ec1, 0x097d, 0x1b32, + 0x130d, 0x1ac7, 0x046a, 0x015b, 0x192c, 0x0eec, 0x00e4, 0x0da5, 0x1cf6, 0x10da, 0x08ed, 0x0c7e, 0x1337, 0x1b86, 0x1fae, 0x1fa1, + 0x1bea, 0x09a1, 0x052b, 0x13b9, 0x1bb4, 0x092f, 0x1cec, 0x19db, 0x0676, 0x08fa, 0x08be, 0x1def, 0x04b6, 0x06cd, 0x067e, 0x03ec, + 0x18b1, 0x0a33, 0x0c8b, 0x1260, 0x196b, 0x1c85, 0x09b1, 0x176b, 0x0ea8, 0x0aab, 0x0c5e, 0x11ff, 0x17aa, 0x07fc, 0x1313, 0x0508, + 0x0a47, 0x0723, 0x0f1c, 0x0e26, 0x10e7, 0x15dc, 0x1961, 0x1154, 0x1c7d, 0x0d2e, 0x087d, 0x17bd, 0x1b2d, 0x1e8d, 0x03e2, 0x03e7, + 0x0486, 0x0223, 0x04f9, 0x014c, 0x1f0d, 0x14b2, 0x0f12, 0x1a30, 0x1b9b, 0x008f, 0x0d53, 0x1e0c, 0x12b4, 0x081e, 0x0085, 0x1d03, + 0x0014, 0x1077, 0x1430, 0x0cbf, 0x03ce, 0x0746, 0x1aeb, 0x0495, 0x0c07, 0x1b1a, 0x0168, 0x1d24, 0x1db3, 0x0b45, 0x1bfa, 0x0d33, + 0x1a65, 0x0477, 0x1689, 0x1e7b, 0x0a7f, 0x1235, 0x0040, 0x0987, 0x1a48, 0x0326, 0x1634, 0x05fa, 0x0eb9, 0x18de, 0x0161, 0x0704, + 0x1ebe, 0x1fb8, 0x1b83, 0x0ee9, 0x1d8a, 0x0aea, 0x141b, 0x131a, 0x1e8a, 0x15d9, 0x081b, 0x14af, 0x06ca, 0x092c, 0x07f9, 0x1c82, + 0x0929, 0x0ae7, 0x0e8b, 0x0740, 0x0b42, 0x0743, 0x18db, 0x1232, 0x197d, 0x079e, 0x00ee, 0x0cd0, 0x1ad4, 0x0e8e, 0x035d, 0x1f7e, + 0x0be0, 0x1c9b, 0x182e, 0x0132, 0x1698, 0x0e91, 0x0381, 0x02fc, 0x1714, 0x16c1, 0x140a, 0x1939, 0x0393, 0x1ad7, 0x0cac, 0x17c2, + 0x0ef9, 0x1290, 0x1e6b, 0x1ddf, 0x147e, 0x1f81, 0x0b7a, 0x1f2a, 0x09de, 0x0b15, 0x1759, 0x0266, 0x04d2, 0x0360, 0x0470, 0x105f, + 0x111a, 0x1856, 0x05c7, 0x01a2, 0x0433, 0x07a1, 0x0db2, 0x0bc2, 0x10d2, 0x0863, 0x1279, 0x0232, 0x1c2c, 0x1980, 0x0ac7, 0x0882, + 0x0c9e, 0x108c, 0x1b75, 0x0a71, 0x0b62, 0x0cd3, 0x0d45, 0x04a8, 0x109a, 0x002a, 0x0dd7, 0x09c5, 0x0e4f, 0x00f1, 0x1503, 0x0ba0, + 0x18c9, 0x00b6, 0x011e, 0x1737, 0x1ffb, 0x0e94, 0x1c19, 0x1aa6, 0x1a1d, 0x0dff, 0x032d, 0x1ef4, 0x05e9, 0x169b, 0x15f2, 0x14b7, + 0x0335, 0x0b1c, 0x103c, 0x0569, 0x1d2c, 0x02ff, 0x1a07, 0x010a, 0x1a16, 0x10b2, 0x0dc0, 0x040c, 0x1eaf, 0x0384, 0x1b8c, 0x0c00, + 0x1740, 0x0a07, 0x1941, 0x19fe, 0x01e2, 0x1c9e, 0x02e6, 0x0ab2, 0x1439, 0x0658, 0x1eec, 0x1f3a, 0x0bd0, 0x0be3, 0x188f, 0x1f12, + 0x138a, 0x1bae, 0x03c8, 0x1692, 0x0054, 0x0135, 0x093f, 0x0278, 0x1191, 0x023a, 0x13cd, 0x0572, 0x1ff5, 0x1831, 0x186b, 0x0d62, + 0x07af, 0x0762, 0x0446, 0x090c, 0x1837, 0x1ada, 0x0298, 0x09f2, 0x100f, 0x1da1, 0x02de, 0x0f9a, 0x0915, 0x0396, 0x1df7, 0x1a35, + 0x0f4e, 0x1359, 0x0965, 0x1e1b, 0x1551, 0x17c5, 0x1461, 0x1e24, 0x0562, 0x16d7, 0x1654, 0x01bf, 0x11ef, 0x0caf, 0x133d, 0x1e74, + 0x0950, 0x1a8a, 0x1568, 0x0fb6, 0x19a6, 0x16c4, 0x1790, 0x0f2d, 0x142b, 0x1b7e, 0x1829, 0x05c2, 0x1d5d, 0x1717, 0x0526, 0x0f17, + 0x14e2, 0x16eb, 0x05d0, 0x1a81, 0x0119, 0x193c, 0x0441, 0x1563, 0x0668, 0x0077, 0x0fbf, 0x11ae, 0x1a57, 0x140d, 0x0e41, 0x13fc, + 0x0597, 0x1025, 0x14e7, 0x1599, 0x1871, 0x1f84, 0x17e4, 0x0c94, 0x10b9, 0x12ac, 0x1a4f, 0x009e, 0x13e8, 0x1481, 0x0a99, 0x0228, + 0x11e2, 0x09e5, 0x181c, 0x16de, 0x137d, 0x1f2d, 0x1c0c, 0x0377, 0x1864, 0x0349, 0x06f1, 0x113f, 0x0534, 0x0b7d, 0x1fa7, 0x0356, + 0x1449, 0x1bc8, 0x16f0, 0x1cd3, 0x1643, 0x1293, 0x08dc, 0x0eaf, 0x1618, 0x114c, 0x0f25, 0x0c1c, 0x030e, 0x0efc, 0x1128, 0x048b, + 0x132a, 0x0502, 0x06fe, 0x1059, 0x18a4, 0x1de2, 0x1954, 0x0811, 0x0426, 0x0b93, 0x1e5e, 0x16b4, 0x0bfa, 0x1e6e, 0x0350, 0x0add, + 0x1d3b, 0x0545, 0x05d5, 0x1374, 0x0d68, 0x0363, 0x1725, 0x0e14, 0x0609, 0x08b6, 0x02d6, 0x0183, 0x15b9, 0x04d5, 0x1cdc, 0x0151, + 0x099d, 0x0a2f, 0x071f, 0x021f, 0x1fd8, 0x1062, 0x00c8, 0x1ac3, 0x1c97, 0x128c, 0x1852, 0x1088, 0x1073, 0x0473, 0x1fb4, 0x0ae3, + 0x075e, 0x1355, 0x1a86, 0x16e7, 0x00b2, 0x0b18, 0x0a03, 0x1baa, 0x0541, 0x0a2b, 0x1351, 0x11c5, 0x1021, 0x09e1, 0x1bc4, 0x04fe, + 0x1d6b, 0x11c9, 0x1b60, 0x0b8a, 0x01b0, 0x0269, 0x158a, 0x04ef, 0x15a2, 0x1ed9, 0x0d8d, 0x1603, 0x0c6f, 0x175c, 0x0193, 0x0d24, + 0x0afa, 0x01b4, 0x1a5c, 0x18fb, 0x1197, 0x07a4, 0x0f7b, 0x10fa, 0x0dc7, 0x170c, 0x0601, 0x1f42, 0x06e1, 0x0436, 0x0207, 0x0823, + 0x1efc, 0x026d, 0x1d1b, 0x165b, 0x0170, 0x0bc5, 0x07ce, 0x07c4, 0x199f, 0x00ab, 0x0f3b, 0x139d, 0x0b2b, 0x0db5, 0x10e0, 0x042c, + 0x1104, 0x158e, 0x1412, 0x02b5, 0x1301, 0x1859, 0x0fa2, 0x1206, 0x0871, 0x1dd7, 0x0217, 0x1b49, 0x179e, 0x111d, 0x19cf, 0x12b9, + 0x0464, 0x04f3, 0x0e85, 0x1b6f, 0x10c6, 0x01a5, 0x0a65, 0x08a0, 0x0e7f, 0x1281, 0x15cd, 0x082d, 0x03c2, 0x05ca, 0x06f8, 0x1b5a, + 0x19b4, 0x1d6f, 0x0e46, 0x148e, 0x0240, 0x1983, 0x1c4c, 0x1e38, 0x1f64, 0x14fb, 0x018b, 0x14c8, 0x1210, 0x1c2f, 0x08c6, 0x1d08, + 0x01fb, 0x11cd, 0x0bb9, 0x01cf, 0x0e73, 0x0885, 0x02a9, 0x12c3, 0x13f5, 0x0d1d, 0x0782, 0x0dee, 0x0e67, 0x0aca, 0x1cfc, 0x0b99, + 0x1784, 0x1b64, 0x1401, 0x180b, 0x0f42, 0x0866, 0x0f8e, 0x0c24, 0x0321, 0x0799, 0x0b10, 0x0025, 0x1fe9, 0x10d5, 0x0aa6, 0x008a, + 0x0344, 0x0b8e, 0x1287, 0x1ed4, 0x10ad, 0x0235, 0x16d2, 0x0072, 0x0713, 0x078e, 0x08aa, 0x1cb0, 0x00a6, 0x127c, 0x0d18, 0x0789, + 0x187e, 0x0c73, 0x066d, 0x1f5b, 0x13d3, 0x0cd6, 0x19eb, 0x11d8, 0x0413, 0x1d82, 0x163b, 0x1664, 0x121c, 0x0b65, 0x0c41, 0x0094, + 0x1904, 0x1760, 0x1257, 0x01c6, 0x0c2e, 0x04ab, 0x0619, 0x08d2, 0x095e, 0x0718, 0x0bb2, 0x1f91, 0x0890, 0x0d48, 0x0c84, 0x1e64, + 0x18ed, 0x0197, 0x007c, 0x0d0f, 0x166c, 0x108f, 0x02be, 0x0c65, 0x104b, 0x1f76, 0x0ad5, 0x0a1d, 0x05b4, 0x0ca1, 0x1a98, 0x1ba0, + 0x0634, 0x0d28, 0x15d3, 0x085d, 0x0849, 0x0a74, 0x17f1, 0x02cc, 0x1dd1, 0x0793, 0x1f70, 0x1b0c, 0x0652, 0x1b78, 0x1146, 0x0a25, + 0x152d, 0x15a6, 0x0fc4, 0x12f8, 0x0578, 0x00f4, 0x1c3a, 0x1005, 0x1f4a, 0x1681, 0x1814, 0x124f, 0x0ec8, 0x0e52, 0x12cd, 0x1e11, + 0x0289, 0x1edd, 0x1f98, 0x1b51, 0x0fdf, 0x0ba3, 0x19c0, 0x0e37, 0x1d9a, 0x08af, 0x14f4, 0x167a, 0x0f62, 0x1506, 0x08f3, 0x16ba, + 0x024c, 0x0d91, 0x11b3, 0x1d12, 0x13a4, 0x002d, 0x06b6, 0x01d8, 0x069b, 0x1b12, 0x12a4, 0x1d7a, 0x05a4, 0x109d, 0x1e9f, 0x0d58, + 0x198e, 0x1607, 0x0833, 0x1703, 0x1576, 0x09c8, 0x0fee, 0x1032, 0x1e42, 0x1cb5, 0x1519, 0x1c58, 0x1497, 0x0dda, 0x14d0, 0x0df5, + 0x000c, 0x119b, 0x1876, 0x058f, 0x183d, 0x0e97, 0x0402, 0x1180, 0x01e9, 0x1c65, 0x0af1, 0x005c, 0x03a5, 0x1ffe, 0x18bf, 0x074b, + 0x1d34, 0x07a8, 0x1526, 0x19ad, 0x123d, 0x1aa9, 0x0bd9, 0x1be3, 0x1541, 0x13d8, 0x1394, 0x03b2, 0x191c, 0x1c1c, 0x0935, 0x0d6e, + 0x05f2, 0x0f7f, 0x1f89, 0x1137, 0x1e4f, 0x00b9, 0x1559, 0x15e3, 0x0b4e, 0x057e, 0x0a5c, 0x00db, 0x174a, 0x18cc, 0x1d53, 0x03d3, + 0x177e, 0x10fe, 0x0246, 0x18e7, 0x094a, 0x173a, 0x0758, 0x1443, 0x0a41, 0x0cdb, 0x1114, 0x1eb8, 0x1fc2, 0x0121, 0x164a, 0x1cc2, + 0x18d3, 0x0afe, 0x17e9, 0x194c, 0x1ae0, 0x169e, 0x136a, 0x0cf0, 0x14a4, 0x13ab, 0x1fe0, 0x1b24, 0x091e, 0x05ec, 0x1c8d, 0x049a, + 0x1081, 0x01b8, 0x1673, 0x0de7, 0x126e, 0x14ba, 0x025f, 0x11f8, 0x02f1, 0x19f0, 0x0069, 0x1a27, 0x04c7, 0x15f5, 0x1bba, 0x0369, + 0x0924, 0x1a60, 0x0c99, 0x0ef4, 0x1308, 0x0e02, 0x0481, 0x18ac, 0x0141, 0x00fa, 0x0779, 0x0c55, 0x1c72, 0x1a20, 0x189a, 0x1af0, + 0x062f, 0x18ff, 0x1989, 0x0284, 0x045f, 0x1ef7, 0x033f, 0x01f6, 0x1325, 0x11dd, 0x1d66, 0x0998, 0x1385, 0x0330, 0x14dd, 0x0f49, + 0x1c24, 0x06e5, 0x059c, 0x1019, 0x029e, 0x0302, 0x0a13, 0x0805, 0x1ca5, 0x157e, 0x1d91, 0x09d5, 0x1779, 0x1d2f, 0x062a, 0x107c, + 0x1583, 0x043a, 0x0fe7, 0x16cb, 0x15c2, 0x010d, 0x0d3e, 0x0f0b, 0x07b9, 0x1883, 0x12ef, 0x0129, 0x06d6, 0x1a0a, 0x19e1, 0x172b, + 0x04a0, 0x020b, 0x102a, 0x04e7, 0x0c36, 0x0b1f, 0x0ffb, 0x10ee, 0x0d04, 0x1c40, 0x1e96, 0x0abe, 0x1dc6, 0x0338, 0x0f58, 0x0019, + 0x1caa, 0x0827, 0x1c52, 0x1b06, 0x11a8, 0x056c, 0x15fd, 0x16ae, 0x1e06, 0x0c78, 0x09bf, 0x0cca, 0x0fd4, 0x103f, 0x129a, 0x0851, + 0x1751, 0x0dcb, 0x14ec, 0x184a, 0x09f8, 0x0387, 0x1eca, 0x1f1e, 0x0178, 0x0034, 0x0840, 0x0b39, 0x0992, 0x1eb2, 0x0317, 0x0cc4, + 0x09da, 0x1710, 0x1096, 0x10ce, 0x1a44, 0x0c03, 0x1979, 0x1e86, 0x0ea4, 0x0672, 0x1b97, 0x1c79, 0x0bef, 0x1b8f, 0x1cf2, 0x0e1a, + 0x1c93, 0x0605, 0x159e, 0x053d, 0x1860, 0x10b5, 0x0422, 0x1614, 0x055e, 0x100b, 0x0664, 0x1427, 0x1a12, 0x1a19, 0x118d, 0x1435, + 0x1d96, 0x1f46, 0x1e3e, 0x0697, 0x095a, 0x040f, 0x1dcd, 0x1047, 0x13f1, 0x1f60, 0x070f, 0x031d, 0x199b, 0x0dc3, 0x0e7b, 0x086d, + 0x0ea0, 0x0174, 0x13ed, 0x055a, 0x07b5, 0x1ca1, 0x1e02, 0x0d00, 0x02ed, 0x14a0, 0x1321, 0x013d, 0x153d, 0x01e5, 0x0a3d, 0x0b4a, + 0x0307, 0x0bc9, 0x05ad, 0x1797, 0x0a87, 0x0ab5, 0x06c3, 0x07dc, 0x116d, 0x1221, 0x0c13, 0x1ab2, 0x1169, 0x02e9, 0x09a7, 0x1d41, + 0x13b1, 0x07d2, 0x1486, 0x0904, 0x0ed1, 0x0a0a, 0x17cd, 0x115b, 0x1d45, 0x1533, 0x17db, 0x0451, 0x1dbf, 0x1743, 0x12e1, 0x1db8, + 0x02a3, 0x07c8, 0x19ba, 0x0613, 0x145b, 0x1a01, 0x00c2, 0x1c06, 0x09ab, 0x0b6a, 0x0b74, 0x003a, 0x0516, 0x1944, 0x08e3, 0x0f6b, + 0x03da, 0x1f00, 0x0a9e, 0x051e, 0x0768, 0x0be6, 0x0edf, 0x0970, 0x1225, 0x06bd, 0x106a, 0x1627, 0x0259, 0x0bd3, 0x1973, 0x0d38, + 0x080a, 0x0271, 0x02c5, 0x0899, 0x072d, 0x1f15, 0x122b, 0x0d9e, 0x1171, 0x0c46, 0x0e0b, 0x1af7, 0x146c, 0x1892, 0x1bf0, 0x054b, + 0x14aa, 0x1d1f, 0x022d, 0x1934, 0x0fa9, 0x065b, 0x17b8, 0x1dea, 0x1ab6, 0x15ac, 0x1348, 0x0d80, 0x16a7, 0x143c, 0x1474, 0x1bff, + 0x0a18, 0x165f, 0x1d75, 0x124a, 0x1b44, 0x1f3d, 0x0020, 0x14c3, 0x0c17, 0x0099, 0x11c0, 0x017e, 0x1f35, 0x1eef, 0x05bd, 0x0f95, + 0x1924, 0x0b2f, 0x10be, 0x004c, 0x044c, 0x0138, 0x0d7b, 0x1622, 0x0ab9, 0x09d0, 0x1422, 0x0b34, 0x00d6, 0x0057, 0x0c50, 0x1b1f, + 0x06ea, 0x0db9, 0x0bab, 0x0f34, 0x06a8, 0x027b, 0x162d, 0x0644, 0x0a8b, 0x0418, 0x1a78, 0x1fca, 0x1453, 0x0942, 0x13bf, 0x05db, + 0x1b2a, 0x10e4, 0x12b1, 0x1f0a, 0x04b3, 0x1bb1, 0x17a7, 0x1968, 0x07e0, 0x0fca, 0x1334, 0x1929, 0x12e8, 0x138d, 0x1a71, 0x0c0c, + 0x1c29, 0x0430, 0x0e4c, 0x0b5f, 0x0390, 0x1695, 0x04cf, 0x147b, 0x06c7, 0x1d87, 0x1ad1, 0x0b3f, 0x1db0, 0x03cb, 0x0eb6, 0x0a7c, + 0x1d5a, 0x19a3, 0x1a54, 0x0116, 0x0912, 0x1834, 0x11ec, 0x154e, 0x0bcd, 0x01df, 0x1ff2, 0x0051, 0x05e6, 0x1ff8, 0x1eac, 0x1d29, + 0x101e, 0x00af, 0x0c6c, 0x01ad, 0x15b6, 0x0d65, 0x1070, 0x1fd5, 0x030b, 0x1640, 0x0bf7, 0x18a1, 0x13e5, 0x186e, 0x0531, 0x137a, + 0x1fe6, 0x0f3f, 0x00a3, 0x10aa, 0x120d, 0x023d, 0x0e64, 0x0e70, 0x179b, 0x12fe, 0x03bf, 0x10c3, 0x06de, 0x1194, 0x0b28, 0x016d, + 0x05a1, 0x13a1, 0x1494, 0x1573, 0x0ec5, 0x0575, 0x0f5f, 0x0fdc, 0x05b1, 0x1669, 0x064f, 0x0846, 0x1219, 0x13d0, 0x088d, 0x0c2b, + 0x1c6f, 0x1305, 0x1382, 0x045c, 0x091b, 0x1add, 0x04c4, 0x126b, 0x1747, 0x1e4c, 0x1fbf, 0x0947, 0x03a2, 0x183a, 0x1919, 0x123a, + 0x1a0f, 0x185d, 0x1998, 0x0957, 0x098f, 0x09f5, 0x0bec, 0x1a41, 0x1dc3, 0x0c33, 0x0fd1, 0x11a5, 0x1776, 0x029b, 0x06d3, 0x15bf, + 0x16a4, 0x0fa6, 0x1f32, 0x1b41, 0x0256, 0x0765, 0x1469, 0x072a, 0x1dbc, 0x0ece, 0x0513, 0x1458, 0x153a, 0x07b2, 0x1166, 0x0a84, + 0x06db, 0x120a, 0x1216, 0x0ec2, 0x05e3, 0x090f, 0x13e2, 0x15b3, 0x12e5, 0x04b0, 0x1dad, 0x038d, 0x00d3, 0x0449, 0x1450, 0x06a5, + 0x0585, 0x1108, 0x1c11, 0x0f73, 0x039c, 0x0399, 0x03f7, 0x1bd7, 0x1537, 0x0253, 0x00d0, 0x05e0, 0x039f, 0x0918, 0x1773, 0x098c, + 0x1730, 0x1592, 0x18f4, 0x1f54, 0x1bda, 0x1a38, 0x076e, 0x0cb8, 0x1d49, 0x061e, 0x0ce5, 0x0101, 0x03fa, 0x1dfa, 0x04bc, 0x04db, + 0x1ae6, 0x1416, 0x037c, 0x0dad, 0x110b, 0x1da4, 0x1ce7, 0x195c, 0x0455, 0x0e58, 0x068c, 0x13c4, 0x0588, 0x1012, 0x0553, 0x0045, + 0x19e6, 0x02b9, 0x1c35, 0x06b1, 0x0f76, 0x0f9d, 0x1c47, 0x0f89, 0x17df, 0x08d7, 0x1720, 0x09fe, 0x1c14, 0x02e1, 0x0293, 0x178b, + 0x0d76, 0x17a2, 0x11e7, 0x0e5f, 0x1dfd, 0x17c8, 0x0eda, 0x17b3, 0x0a0e, 0x0ff6, 0x1ec5, 0x041d, 0x03fd, 0x1554, 0x1365, 0x047c, + 0x1888, 0x1121, 0x19c8, 0x1a91, 0x04de, 0x1e27, 0x0976, 0x07f2, 0x0ed5, 0x1909, 0x07e7, 0x1cca, 0x04bf, 0x1464, 0x03f2, 0x1ce2, + 0x0cf6, 0x19d3, 0x09ea, 0x1e30, 0x0621, 0x135c, 0x190e, 0x0a4e, 0x115f, 0x12d3, 0x1b36, 0x0a90, 0x1d4c, 0x0f51, 0x12da, 0x1a6a, + 0x07be, 0x12bd, 0x08cc, 0x0e31, 0x0104, 0x1e1e, 0x0371, 0x1abd, 0x17d1, 0x1765, 0x0981, 0x1f24, 0x0ce8, 0x0968, 0x1bcf, 0x17f9, + 0x0b55, 0x0875, 0x1821, 0x0b08, 0x1a3b, 0x0cb2, 0x07ec, 0x0736, 0x07d6, 0x0d98, 0x063e, 0x1fcf, 0x1bdd, 0x11f2, 0x0f05, 0x1e80, + 0x012e, 0x1ddb, 0x019e, 0x0a6d, 0x0cbb, 0x1e77, 0x0ee5, 0x073c, 0x13b5, 0x125c, 0x0e22, 0x0148, 0x0771, 0x1340, 0x0684, 0x0157, + 0x1370, 0x021b, 0x16e3, 0x0b86, 0x1595, 0x16da, 0x1ccf, 0x1055, 0x0908, 0x1e17, 0x0fb2, 0x1a7d, 0x1733, 0x0565, 0x19fa, 0x168e, + 0x12f4, 0x1b4d, 0x1d0e, 0x16ff, 0x1f57, 0x01c2, 0x0d0b, 0x0859, 0x148a, 0x01cb, 0x1807, 0x1ed0, 0x18f7, 0x1657, 0x02b1, 0x1b6b, + 0x1846, 0x10ca, 0x0539, 0x0693, 0x1015, 0x16c7, 0x04e3, 0x1b02, 0x1948, 0x0de3, 0x0ef0, 0x0280, 0x058b, 0x19a9, 0x1133, 0x18e3, + 0x0112, 0x01a9, 0x10a6, 0x156f, 0x0048, 0x0f30, 0x1f06, 0x0b5b, 0x051a, 0x0895, 0x1930, 0x1246, 0x0556, 0x1793, 0x0900, 0x060f, + 0x0b04, 0x0a69, 0x0b82, 0x16fb, 0x0e5b, 0x1a8d, 0x1e2c, 0x0e2d, 0x0f6f, 0x1f50, 0x0da9, 0x06ad, 0x0458, 0x0953, 0x1b3d, 0x0ebe, + 0x15c7, 0x08a4, 0x1f6a, 0x1513, 0x13c7, 0x0fb9, 0x1e58, 0x0d87, 0x08e7, 0x0d4d, 0x00e8, 0x0dd1, 0x068f, 0x156b, 0x16f7, 0x150f, + 0x00e2, 0x0468, 0x1fac, 0x08eb, 0x1da7, 0x171a, 0x097b, 0x1801, 0x0b6e, 0x11ba, 0x1acb, 0x0649, 0x110e, 0x1d60, 0x09b9, 0x0709, + 0x0f10, 0x04f7, 0x0083, 0x0d51, 0x195f, 0x0f1a, 0x03e0, 0x087b, 0x09af, 0x0c89, 0x1311, 0x0c5c, 0x1cea, 0x0529, 0x067c, 0x08bc, + 0x18d9, 0x0e89, 0x035b, 0x00ec, 0x1419, 0x1b81, 0x07f7, 0x0819, 0x003e, 0x1687, 0x015f, 0x1632, 0x1ae9, 0x142e, 0x1bf8, 0x0166, + 0x0d43, 0x1b73, 0x1501, 0x0dd5, 0x0db0, 0x05c5, 0x0ac5, 0x1277, 0x0b78, 0x1e69, 0x046e, 0x1757, 0x037f, 0x182c, 0x0caa, 0x1408, + 0x093d, 0x03c6, 0x1869, 0x13cb, 0x02e4, 0x193f, 0x188d, 0x1eea, 0x1a05, 0x103a, 0x1b8a, 0x0dbe, 0x1c17, 0x011c, 0x15f0, 0x032b, + 0x043f, 0x05ce, 0x0e3f, 0x0fbd, 0x178e, 0x1566, 0x0524, 0x1827, 0x145f, 0x0963, 0x133b, 0x1652, 0x0296, 0x0444, 0x1df5, 0x02dc, + 0x1952, 0x06fc, 0x034e, 0x1e5c, 0x08da, 0x16ee, 0x1126, 0x0f23, 0x1c0a, 0x181a, 0x1fa5, 0x06ef, 0x17e2, 0x14e5, 0x0a97, 0x1a4d, + 0x1588, 0x1b5e, 0x0191, 0x0d8b, 0x0a01, 0x1a84, 0x1bc2, 0x134f, 0x00c6, 0x071d, 0x1fb2, 0x1850, 0x1723, 0x05d3, 0x1cda, 0x02d4, + 0x0a63, 0x0e83, 0x06f6, 0x15cb, 0x0fa0, 0x1410, 0x19cd, 0x0215, 0x07cc, 0x1d19, 0x10de, 0x0f39, 0x0f79, 0x1a5a, 0x0205, 0x05ff, + 0x16d0, 0x1285, 0x0d16, 0x08a8, 0x0f8c, 0x13ff, 0x0aa4, 0x0b0e, 0x02a7, 0x0bb7, 0x1cfa, 0x0780, 0x1c4a, 0x0e44, 0x08c4, 0x0189, + 0x17ef, 0x15d1, 0x1144, 0x1f6e, 0x02bc, 0x007a, 0x1a96, 0x0ad3, 0x0617, 0x1255, 0x0c82, 0x0bb0, 0x19e9, 0x066b, 0x0c3f, 0x1639, + 0x0fec, 0x0831, 0x14ce, 0x1517, 0x06b4, 0x11b1, 0x1e9d, 0x12a2, 0x19be, 0x1f96, 0x08f1, 0x14f2, 0x1c38, 0x0fc2, 0x12cb, 0x1812, + 0x0756, 0x0244, 0x1648, 0x1112, 0x1557, 0x1f87, 0x1d51, 0x0a5a, 0x0bd7, 0x1524, 0x0933, 0x1392, 0x0400, 0x1874, 0x18bd, 0x0aef, + 0x033d, 0x1987, 0x14db, 0x1d64, 0x047f, 0x0c97, 0x1898, 0x0777, 0x025d, 0x1671, 0x1bb8, 0x0067, 0x1368, 0x17e7, 0x1c8b, 0x1fde, + 0x15fb, 0x1c50, 0x1298, 0x09bd, 0x0ff9, 0x1028, 0x0f56, 0x1e94, 0x0d3c, 0x0fe5, 0x19df, 0x12ed, 0x0a11, 0x059a, 0x0628, 0x1d8f, + 0x1dcb, 0x1e3c, 0x0e79, 0x070d, 0x0420, 0x159c, 0x118b, 0x0662, 0x1977, 0x1094, 0x1cf0, 0x1b95, 0x1ec8, 0x14ea, 0x0315, 0x083e, + 0x00c0, 0x19b8, 0x08e1, 0x0b72, 0x17cb, 0x1484, 0x12df, 0x17d9, 0x06c1, 0x05ab, 0x09a5, 0x0c11, 0x1e00, 0x13eb, 0x0a3b, 0x131f, + 0x001e, 0x1d73, 0x05bb, 0x11be, 0x17b6, 0x022b, 0x1472, 0x1346, 0x1229, 0x02c3, 0x1bee, 0x0e09, 0x0edd, 0x0a9c, 0x1971, 0x1068, + 0x04cd, 0x0e4a, 0x0eb4, 0x1acf, 0x17a5, 0x12af, 0x1a6f, 0x1332, 0x162b, 0x0ba9, 0x13bd, 0x1a76, 0x0d79, 0x10bc, 0x0c4e, 0x1420, + 0x0f5d, 0x1492, 0x088b, 0x064d, 0x0e62, 0x00a1, 0x0b26, 0x03bd, 0x106e, 0x0c6a, 0x052f, 0x0bf5, 0x11ea, 0x1a52, 0x1eaa, 0x1ff0, + 0x13e0, 0x1214, 0x144e, 0x1dab, 0x1467, 0x1f30, 0x1164, 0x0511, 0x0bea, 0x1996, 0x06d1, 0x0fcf, 0x04c2, 0x1380, 0x1917, 0x1fbd, + 0x1c45, 0x1c33, 0x0291, 0x171e, 0x1ce5, 0x037a, 0x0551, 0x068a, 0x076c, 0x18f2, 0x04ba, 0x0ce3, 0x03f5, 0x1c0f, 0x1771, 0x00ce, + 0x036f, 0x08ca, 0x1bcd, 0x097f, 0x190c, 0x09e8, 0x12d8, 0x1b34, 0x0974, 0x19c6, 0x03f0, 0x07e5, 0x0ed8, 0x11e5, 0x1363, 0x1ec3, + 0x0d09, 0x1d0c, 0x02af, 0x1805, 0x1ccd, 0x16e1, 0x19f8, 0x0fb0, 0x0ee3, 0x019c, 0x0682, 0x0e20, 0x07ea, 0x181f, 0x0f03, 0x063c, + 0x1e56, 0x1f68, 0x16f5, 0x00e6, 0x1e2a, 0x0b80, 0x1b3b, 0x0da7, 0x1f04, 0x10a4, 0x08fe, 0x192e, 0x04e1, 0x0537, 0x1131, 0x0eee, + 0x0ac3, 0x14ff, 0x0ca8, 0x046c, 0x07f5, 0x0359, 0x1bf6, 0x015d, 0x03de, 0x0081, 0x067a, 0x130f, 0x0979, 0x1faa, 0x09b7, 0x1ac9, + 0x1bc0, 0x018f, 0x1cd8, 0x1fb0, 0x1124, 0x034c, 0x0a95, 0x1fa3, 0x0522, 0x0e3d, 0x1df3, 0x1339, 0x188b, 0x1867, 0x15ee, 0x1b88, + 0x1e9b, 0x14cc, 0x12c9, 0x08ef, 0x1a94, 0x1142, 0x0c3d, 0x0c80, 0x0aa2, 0x0d14, 0x08c2, 0x1cf8, 0x19cb, 0x06f4, 0x0203, 0x10dc, + 0x1189, 0x0e77, 0x0313, 0x1cee, 0x0f54, 0x1296, 0x0626, 0x19dd, 0x1896, 0x14d9, 0x1c89, 0x1bb6, 0x1d4f, 0x1646, 0x18bb, 0x0931, + 0x0b24, 0x0889, 0x1ea8, 0x052d, 0x1a6d, 0x0eb2, 0x0c4c, 0x13bb, 0x1470, 0x05b9, 0x196f, 0x1bec, 0x12dd, 0x08df, 0x0a39, 0x09a3, + 0x19f6, 0x02ad, 0x0f01, 0x0680, 0x12d6, 0x1bcb, 0x1361, 0x03ee, 0x054f, 0x028f, 0x176f, 0x04b8, 0x1162, 0x144c, 0x1915, 0x06cf, + 0x0c3b, 0x12c7, 0x0201, 0x08c0, 0x0a93, 0x1cd6, 0x15ec, 0x1df1, 0x1bf4, 0x0ca6, 0x09b5, 0x0678, 0x1b39, 0x16f3, 0x112f, 0x08fc, + 0x15ea, 0x01ff, 0x112d, 0x09b3, 0x135f, 0x0eff, 0x1913, 0x176d, 0x0c4a, 0x1ea6, 0x0a37, 0x196d, 0x0624, 0x0311, 0x18b9, 0x1c87, + 0x10f3, 0x11d1, 0x1a9f, 0x0c8d, 0x0a51, 0x048e, 0x1177, 0x1262, 0x1175, 0x1a9d, 0x18b5, 0x18b3, 0x1911, 0x112b, 0x18b7, 0x0a35, + 0x02f7, 0x0bbd, 0x0490, 0x1315, 0x19d6, 0x114f, 0x0a53, 0x050a, 0x1afb, 0x1ee3, 0x1264, 0x17ac, 0x0cf9, 0x161b, 0x1179, 0x07fe, + 0x1000, 0x01d3, 0x11d3, 0x0c60, 0x1e33, 0x0c1f, 0x10f5, 0x1201, 0x0e0f, 0x1ba5, 0x0c8f, 0x0eaa, 0x09ed, 0x0f28, 0x1aa1, 0x0aad, + 0x1549, 0x0e6b, 0x161d, 0x1963, 0x096b, 0x1de5, 0x0cfb, 0x1156, 0x1f19, 0x160f, 0x0800, 0x10e9, 0x0ceb, 0x18a7, 0x117b, 0x15de, + 0x0210, 0x0ace, 0x1ee5, 0x0f1e, 0x17fc, 0x0814, 0x1afd, 0x0e28, 0x0731, 0x1050, 0x17ae, 0x0a49, 0x1bd2, 0x1957, 0x1266, 0x0725, + 0x1a2d, 0x1d00, 0x1151, 0x03e4, 0x1768, 0x0505, 0x19d8, 0x03e9, 0x0da2, 0x1f9e, 0x050c, 0x1b2f, 0x17d4, 0x132d, 0x0a55, 0x1e8f, + 0x04a5, 0x0b9d, 0x0bbf, 0x087f, 0x1f27, 0x105c, 0x02f9, 0x17bf, 0x122f, 0x1f7b, 0x1317, 0x1c7f, 0x0984, 0x0701, 0x0492, 0x0d30, + 0x1560, 0x13f9, 0x0f2a, 0x0f14, 0x1e21, 0x1e71, 0x09ef, 0x1a32, 0x0275, 0x0d5f, 0x0aaf, 0x1f0f, 0x0107, 0x0bfd, 0x1aa3, 0x14b4, + 0x04ec, 0x0d21, 0x1ba7, 0x04fb, 0x1ac0, 0x0ae0, 0x0e11, 0x014e, 0x080e, 0x0ada, 0x0eac, 0x0488, 0x0374, 0x0353, 0x0c91, 0x0225, + 0x006f, 0x0786, 0x0c21, 0x0087, 0x12c0, 0x0b96, 0x1e35, 0x1d05, 0x089d, 0x1b57, 0x1203, 0x12b6, 0x07c1, 0x0429, 0x10f7, 0x0820, + 0x102f, 0x0df2, 0x01d5, 0x0d55, 0x0e34, 0x16b7, 0x1002, 0x1e0e, 0x02c9, 0x0a22, 0x0c62, 0x1b9d, 0x08cf, 0x1e61, 0x11d5, 0x0091, + 0x01f3, 0x0f46, 0x18a9, 0x1aed, 0x11f5, 0x0366, 0x0ced, 0x0497, 0x1440, 0x1cbf, 0x15e0, 0x03d0, 0x1be0, 0x0d6b, 0x117d, 0x0748, + 0x1044, 0x086a, 0x1611, 0x1432, 0x1e83, 0x0e17, 0x1f1b, 0x0cc1, 0x16ab, 0x084e, 0x10eb, 0x0016, 0x0f08, 0x1728, 0x0802, 0x1079, + 0x14c0, 0x0f92, 0x1de7, 0x1bfc, 0x0d9b, 0x0548, 0x096d, 0x0d35, 0x1c03, 0x0f68, 0x1158, 0x1db5, 0x07d9, 0x1d3e, 0x0cfd, 0x0b47, + 0x0fd9, 0x0c28, 0x0e6d, 0x016a, 0x1fd2, 0x1377, 0x154b, 0x1d26, 0x1478, 0x0a79, 0x1965, 0x0c09, 0x0641, 0x05d8, 0x161f, 0x1b1c, + 0x0f86, 0x1788, 0x1959, 0x0042, 0x0cb5, 0x04d8, 0x1bd4, 0x0989, 0x15b0, 0x06a2, 0x0727, 0x0a81, 0x1a3e, 0x15bc, 0x1268, 0x1237, + 0x0856, 0x1b68, 0x1052, 0x168b, 0x0739, 0x0154, 0x0733, 0x1e7d, 0x1aba, 0x17f6, 0x0a4b, 0x1a67, 0x07ef, 0x1cdf, 0x17b0, 0x0479, + 0x1274, 0x1405, 0x0816, 0x0163, 0x0878, 0x08b9, 0x17fe, 0x0706, 0x0d84, 0x150c, 0x0e2a, 0x0ebb, 0x0b58, 0x060c, 0x1aff, 0x18e0, + 0x129f, 0x180f, 0x0ad0, 0x1636, 0x0b0b, 0x0186, 0x0212, 0x05fc, 0x134c, 0x02d1, 0x0f20, 0x1a4a, 0x1824, 0x02d9, 0x1ee7, 0x0328, + 0x03ba, 0x1fed, 0x132f, 0x141d, 0x1343, 0x1065, 0x17d6, 0x131c, 0x065f, 0x083b, 0x1e91, 0x1d8c, 0x0774, 0x1fdb, 0x0a57, 0x0aec, + 0x0c7d, 0x10d9, 0x1fa0, 0x1b85, 0x015a, 0x1ac6, 0x0da4, 0x0eeb, 0x0fad, 0x0639, 0x1b31, 0x1ec0, 0x0687, 0x00cb, 0x050e, 0x1fba, + 0x11fe, 0x0aaa, 0x0507, 0x07fb, 0x125f, 0x0a32, 0x176a, 0x1c84, 0x1dee, 0x08f9, 0x03eb, 0x06cc, 0x13b8, 0x09a0, 0x19da, 0x092e, + 0x1e0b, 0x008e, 0x1d02, 0x081d, 0x014b, 0x0222, 0x1a2f, 0x14b1, 0x17bc, 0x0d2d, 0x03e6, 0x1e8c, 0x0e25, 0x0722, 0x1153, 0x15db, + 0x05f9, 0x0325, 0x0703, 0x18dd, 0x1e7a, 0x0476, 0x0986, 0x1234, 0x1d23, 0x1b19, 0x0d32, 0x0b44, 0x0cbe, 0x1076, 0x0494, 0x0745, + 0x0ccf, 0x079d, 0x1f7d, 0x0e8d, 0x073f, 0x0ae6, 0x1231, 0x0742, 0x14ae, 0x15d8, 0x1c81, 0x092b, 0x0ee8, 0x1fb7, 0x1319, 0x0ae9, + 0x0265, 0x0b14, 0x105e, 0x035f, 0x1dde, 0x128f, 0x1f29, 0x1f80, 0x1938, 0x16c0, 0x17c1, 0x1ad6, 0x0131, 0x1c9a, 0x02fb, 0x0e90, + 0x09c4, 0x0029, 0x0b9f, 0x00f0, 0x0a70, 0x108b, 0x04a7, 0x0cd2, 0x0231, 0x0862, 0x0881, 0x197f, 0x01a1, 0x1855, 0x0bc1, 0x07a0, + 0x040b, 0x10b1, 0x0bff, 0x0383, 0x0568, 0x0b1b, 0x0109, 0x02fe, 0x1ef3, 0x0dfe, 0x14b6, 0x169a, 0x1736, 0x00b5, 0x1aa5, 0x0e93, + 0x0571, 0x0239, 0x0d61, 0x1830, 0x1691, 0x1bad, 0x0277, 0x0134, 0x1f39, 0x0657, 0x1f11, 0x0be2, 0x19fd, 0x0a06, 0x0ab1, 0x1c9d, + 0x01be, 0x16d6, 0x1e73, 0x0cae, 0x1e1a, 0x1358, 0x1e23, 0x17c4, 0x0f99, 0x1da0, 0x1a34, 0x0395, 0x090b, 0x0761, 0x09f1, 0x1ad9, + 0x11ad, 0x0076, 0x13fb, 0x140c, 0x1a80, 0x16ea, 0x1562, 0x193b, 0x05c1, 0x1b7d, 0x0f16, 0x1716, 0x0fb5, 0x1a89, 0x0f2c, 0x16c3, + 0x113e, 0x0348, 0x0355, 0x0b7c, 0x16dd, 0x09e4, 0x0376, 0x1f2c, 0x009d, 0x12ab, 0x0227, 0x1480, 0x1598, 0x1024, 0x0c93, 0x1f83, + 0x16b3, 0x0b92, 0x0adc, 0x1e6d, 0x1058, 0x0501, 0x0810, 0x1de1, 0x0c1b, 0x114b, 0x048a, 0x0efb, 0x1cd2, 0x1bc7, 0x0eae, 0x1292, + 0x1087, 0x128b, 0x0ae2, 0x0472, 0x021e, 0x0a2e, 0x1ac2, 0x1061, 0x0182, 0x08b5, 0x0150, 0x04d4, 0x1373, 0x0544, 0x0e13, 0x0362, + 0x1602, 0x1ed8, 0x0d23, 0x175b, 0x0b89, 0x11c8, 0x04ee, 0x0268, 0x11c4, 0x0a2a, 0x04fd, 0x09e0, 0x16e6, 0x1354, 0x1ba9, 0x0b17, + 0x139c, 0x00aa, 0x042b, 0x0db4, 0x165a, 0x026c, 0x07c3, 0x0bc4, 0x1f41, 0x170b, 0x0822, 0x0435, 0x18fa, 0x01b3, 0x10f9, 0x07a3, + 0x082c, 0x1280, 0x1b59, 0x05c9, 0x1b6e, 0x04f2, 0x089f, 0x01a4, 0x1b48, 0x1dd6, 0x12b8, 0x111c, 0x02b4, 0x158d, 0x1205, 0x1858, + 0x0ded, 0x0d1c, 0x0b98, 0x0ac9, 0x01ce, 0x11cc, 0x12c2, 0x0884, 0x14c7, 0x14fa, 0x1d07, 0x1c2e, 0x148d, 0x1d6e, 0x1e37, 0x1982, + 0x1caf, 0x078d, 0x0788, 0x127b, 0x1ed3, 0x0b8d, 0x0071, 0x0234, 0x0024, 0x0798, 0x0089, 0x10d4, 0x180a, 0x1b63, 0x0c23, 0x0865, + 0x1f90, 0x0717, 0x1e63, 0x0d47, 0x01c5, 0x175f, 0x08d1, 0x04aa, 0x1663, 0x1d81, 0x0093, 0x0b64, 0x1f5a, 0x0c72, 0x11d7, 0x0cd5, + 0x1b0b, 0x0792, 0x0a24, 0x1b77, 0x085c, 0x0d27, 0x02cb, 0x0a73, 0x0a1c, 0x1f75, 0x1b9f, 0x0ca0, 0x0d0e, 0x0196, 0x0c64, 0x108e, + 0x1679, 0x08ae, 0x16b9, 0x1505, 0x1b50, 0x1edc, 0x0e36, 0x0ba2, 0x124e, 0x1680, 0x1e10, 0x0e51, 0x12f7, 0x15a5, 0x1004, 0x00f3, + 0x1c57, 0x1cb4, 0x0df4, 0x0dd9, 0x1702, 0x1606, 0x1031, 0x09c7, 0x1d79, 0x1b11, 0x0d57, 0x109c, 0x1d11, 0x0d90, 0x01d7, 0x002c, + 0x03b1, 0x13d7, 0x0d6d, 0x1c1b, 0x19ac, 0x07a7, 0x1be2, 0x1aa8, 0x005b, 0x1c64, 0x074a, 0x1ffd, 0x058e, 0x119a, 0x117f, 0x0e96, + 0x1eb7, 0x0cda, 0x1cc1, 0x0120, 0x18e6, 0x10fd, 0x1442, 0x1739, 0x00da, 0x057d, 0x03d2, 0x18cb, 0x1136, 0x0f7e, 0x15e2, 0x00b8, + 0x1a26, 0x19ef, 0x0368, 0x15f4, 0x0de6, 0x01b7, 0x11f7, 0x14b9, 0x1b23, 0x13aa, 0x0499, 0x05eb, 0x194b, 0x0afd, 0x0cef, 0x169d, + 0x0997, 0x11dc, 0x0f48, 0x032f, 0x0283, 0x18fe, 0x01f5, 0x1ef6, 0x0c54, 0x00f9, 0x1aef, 0x1a1f, 0x0ef3, 0x1a5f, 0x18ab, 0x0e01, + 0x0128, 0x1882, 0x172a, 0x1a09, 0x16ca, 0x0439, 0x0f0a, 0x010c, 0x09d4, 0x157d, 0x107b, 0x1d2e, 0x1018, 0x06e4, 0x0804, 0x0301, + 0x0cc9, 0x0c77, 0x0850, 0x103e, 0x1b05, 0x0826, 0x16ad, 0x056b, 0x0abd, 0x1c3f, 0x0018, 0x0337, 0x04e6, 0x020a, 0x10ed, 0x0b1e, + 0x1c78, 0x0671, 0x0e19, 0x1b8e, 0x10cd, 0x170f, 0x1e85, 0x0c02, 0x0b38, 0x0033, 0x0cc3, 0x1eb1, 0x1849, 0x0dca, 0x1f1d, 0x0386, + 0x031c, 0x1f5f, 0x086c, 0x0dc2, 0x0696, 0x1f45, 0x1046, 0x040e, 0x1426, 0x100a, 0x1434, 0x1a18, 0x053c, 0x0604, 0x1613, 0x10b4, + 0x1ab1, 0x1220, 0x1d40, 0x02e8, 0x1796, 0x0bc8, 0x07db, 0x0ab4, 0x013c, 0x149f, 0x0b49, 0x01e4, 0x0559, 0x0173, 0x0cff, 0x1ca0, + 0x0039, 0x0b69, 0x0f6a, 0x1943, 0x0612, 0x07c7, 0x1c05, 0x1a00, 0x0450, 0x1532, 0x1db7, 0x1742, 0x0903, 0x07d1, 0x115a, 0x0a09, + 0x1af6, 0x0c45, 0x054a, 0x1891, 0x0898, 0x0270, 0x0d9d, 0x1f14, 0x1626, 0x06bc, 0x0d37, 0x0bd2, 0x051d, 0x1eff, 0x096f, 0x0be5, + 0x017d, 0x0098, 0x0f94, 0x1eee, 0x1249, 0x165e, 0x14c2, 0x1f3c, 0x0d7f, 0x15ab, 0x1bfe, 0x143b, 0x1933, 0x1d1e, 0x1de9, 0x065a, + 0x1fc9, 0x0417, 0x05da, 0x0941, 0x0f33, 0x0db8, 0x0643, 0x027a, 0x0b33, 0x09cf, 0x1b1e, 0x0056, 0x004b, 0x0b2e, 0x1621, 0x0137, + 0x0b3e, 0x1d86, 0x0a7b, 0x03ca, 0x0b5e, 0x042f, 0x147a, 0x1694, 0x1928, 0x0fc9, 0x0c0b, 0x138c, 0x1f09, 0x10e3, 0x1967, 0x1bb0, + 0x18a0, 0x163f, 0x1379, 0x186d, 0x01ac, 0x00ae, 0x1fd4, 0x0d64, 0x0050, 0x01de, 0x1d28, 0x1ff7, 0x0115, 0x19a2, 0x154d, 0x1833, + 0x0845, 0x1668, 0x0c2a, 0x13cf, 0x1572, 0x13a0, 0x0fdb, 0x0574, 0x10c2, 0x12fd, 0x016c, 0x1193, 0x10a9, 0x0f3e, 0x0e6f, 0x023c, + 0x11a4, 0x0c32, 0x15be, 0x029a, 0x0956, 0x185c, 0x1a40, 0x09f4, 0x0946, 0x1e4b, 0x1239, 0x1839, 0x045b, 0x1304, 0x126a, 0x1adc, + 0x038c, 0x04af, 0x06a4, 0x0448, 0x0ec1, 0x1209, 0x15b2, 0x090e, 0x1457, 0x0ecd, 0x0a83, 0x07b1, 0x1b40, 0x0fa5, 0x0729, 0x0764, + 0x0100, 0x061d, 0x04da, 0x1df9, 0x1f53, 0x1591, 0x0cb7, 0x1a37, 0x05df, 0x0252, 0x098b, 0x0917, 0x0f72, 0x1107, 0x1bd6, 0x0398, + 0x09fd, 0x08d6, 0x178a, 0x02e0, 0x06b0, 0x02b8, 0x0f88, 0x0f9c, 0x13c3, 0x0e57, 0x0044, 0x1011, 0x0dac, 0x1415, 0x195b, 0x1da3, + 0x1cc9, 0x1908, 0x1ce1, 0x1463, 0x1a90, 0x1120, 0x07f1, 0x1e26, 0x041c, 0x0ff5, 0x047b, 0x1553, 0x0e5e, 0x17a1, 0x17b2, 0x17c7, + 0x1f23, 0x1764, 0x17f8, 0x0967, 0x0e30, 0x12bc, 0x1abc, 0x1e1d, 0x0a8f, 0x12d2, 0x1a69, 0x0f50, 0x1e2f, 0x19d2, 0x0a4d, 0x135b, + 0x0147, 0x125b, 0x0156, 0x133f, 0x0a6c, 0x1dda, 0x073b, 0x1e76, 0x1fce, 0x0d97, 0x1e7f, 0x11f1, 0x0b07, 0x0874, 0x0735, 0x0cb1, + 0x1ecf, 0x01ca, 0x1b6a, 0x1656, 0x16fe, 0x1b4c, 0x0858, 0x01c1, 0x1a7c, 0x1e16, 0x168d, 0x0564, 0x0b85, 0x021a, 0x1054, 0x16d9, + 0x1245, 0x0894, 0x060e, 0x1792, 0x156e, 0x01a8, 0x0b5a, 0x0f2f, 0x027f, 0x0de2, 0x18e2, 0x19a8, 0x0692, 0x10c9, 0x1b01, 0x16c6, + 0x0dd0, 0x0d4c, 0x150e, 0x156a, 0x1512, 0x08a3, 0x0d86, 0x0fb8, 0x06ac, 0x1f4f, 0x0ebd, 0x0952, 0x16fa, 0x0a68, 0x0e2c, 0x1a8c, + 0x0c5b, 0x0c88, 0x08bb, 0x0528, 0x0d50, 0x04f6, 0x087a, 0x0f19, 0x0648, 0x11b9, 0x0708, 0x1d5f, 0x08ea, 0x0467, 0x1800, 0x1719, + 0x1756, 0x1e68, 0x1407, 0x182b, 0x0dd4, 0x1b72, 0x1276, 0x05c4, 0x1631, 0x1686, 0x0165, 0x142d, 0x00eb, 0x0e88, 0x0818, 0x1b80, + 0x1651, 0x0962, 0x02db, 0x0443, 0x0fbc, 0x05cd, 0x1826, 0x1565, 0x0dbd, 0x1039, 0x032a, 0x011b, 0x13ca, 0x03c5, 0x1ee9, 0x193e, + 0x184f, 0x071c, 0x02d3, 0x05d2, 0x0d8a, 0x1b5d, 0x134e, 0x1a83, 0x06ee, 0x1819, 0x1a4c, 0x14e4, 0x1e5b, 0x06fb, 0x0f22, 0x16ed, + 0x077f, 0x0bb6, 0x0188, 0x0e43, 0x08a7, 0x1284, 0x0b0d, 0x13fe, 0x0f38, 0x1d18, 0x05fe, 0x1a59, 0x15ca, 0x0e82, 0x0214, 0x140f, + 0x14f1, 0x1f95, 0x1811, 0x0fc1, 0x1516, 0x0830, 0x12a1, 0x11b0, 0x0baf, 0x1254, 0x1638, 0x066a, 0x1f6d, 0x15d0, 0x0ad2, 0x0079, + 0x0066, 0x1670, 0x1fdd, 0x17e6, 0x1d63, 0x1986, 0x0776, 0x0c96, 0x1391, 0x1523, 0x0aee, 0x1873, 0x1111, 0x0243, 0x0a59, 0x1f86, + 0x1b94, 0x1093, 0x083d, 0x14e9, 0x070c, 0x1e3b, 0x0661, 0x159b, 0x12ec, 0x0fe4, 0x1d8e, 0x0599, 0x09bc, 0x1c4f, 0x1e93, 0x1027, + 0x0e08, 0x02c2, 0x1067, 0x0a9b, 0x11bd, 0x1d72, 0x1345, 0x022a, 0x0c10, 0x05aa, 0x131e, 0x13ea, 0x0b71, 0x19b7, 0x17d8, 0x1483, + 0x0bf4, 0x0c69, 0x1fef, 0x1a51, 0x064c, 0x1491, 0x03bc, 0x00a0, 0x1a75, 0x0ba8, 0x141f, 0x10bb, 0x1ace, 0x0e49, 0x1331, 0x12ae, + 0x0ce2, 0x18f1, 0x00cd, 0x1c0e, 0x171d, 0x1c32, 0x0689, 0x0379, 0x0fce, 0x1995, 0x1fbc, 0x137f, 0x1daa, 0x1213, 0x0510, 0x1f2f, + 0x0e1f, 0x019b, 0x063b, 0x181e, 0x1804, 0x1d0b, 0x0faf, 0x16e0, 0x07e4, 0x19c5, 0x1ec2, 0x11e4, 0x097e, 0x08c9, 0x1b33, 0x09e7, + 0x130e, 0x0080, 0x1ac8, 0x1fa9, 0x046b, 0x14fe, 0x015c, 0x0358, 0x192d, 0x10a3, 0x0eed, 0x0536, 0x00e5, 0x1f67, 0x0da6, 0x0b7f, + 0x1cf7, 0x0d13, 0x10db, 0x06f3, 0x08ee, 0x14cb, 0x0c7f, 0x1141, 0x1338, 0x0e3c, 0x1b87, 0x1866, 0x1faf, 0x018e, 0x1fa2, 0x034b, + 0x1beb, 0x05b8, 0x09a2, 0x08de, 0x052c, 0x0888, 0x13ba, 0x0eb1, 0x1bb5, 0x14d8, 0x0930, 0x1645, 0x1ced, 0x0e76, 0x19dc, 0x1295, + 0x0677, 0x0ca5, 0x08fb, 0x16f2, 0x08bf, 0x12c6, 0x1df0, 0x1cd5, 0x04b7, 0x028e, 0x06ce, 0x144b, 0x067f, 0x02ac, 0x03ed, 0x1bca, + 0x18b2, 0x1a9c, 0x0a34, 0x112a, 0x0c8c, 0x11d0, 0x1261, 0x048d, 0x196c, 0x1ea5, 0x1c86, 0x0310, 0x09b2, 0x01fe, 0x176c, 0x0efe, + 0x0ea9, 0x1ba4, 0x0aac, 0x0f27, 0x0c5f, 0x01d2, 0x1200, 0x0c1e, 0x17ab, 0x1ee2, 0x07fd, 0x161a, 0x1314, 0x0bbc, 0x0509, 0x114e, + 0x0a48, 0x104f, 0x0724, 0x1956, 0x0f1d, 0x0acd, 0x0e27, 0x0813, 0x10e8, 0x160e, 0x15dd, 0x18a6, 0x1962, 0x0e6a, 0x1155, 0x1de4, + 0x1c7e, 0x1f7a, 0x0d2f, 0x0700, 0x087e, 0x0b9c, 0x17be, 0x105b, 0x1b2e, 0x1f9d, 0x1e8e, 0x132c, 0x03e3, 0x1cff, 0x03e8, 0x0504, + 0x0487, 0x0ad9, 0x0224, 0x0352, 0x04fa, 0x0d20, 0x014d, 0x0adf, 0x1f0e, 0x0d5e, 0x14b3, 0x0bfc, 0x0f13, 0x13f8, 0x1a31, 0x1e70, + 0x1b9c, 0x0a21, 0x0090, 0x1e60, 0x0d54, 0x0df1, 0x1e0d, 0x16b6, 0x12b5, 0x1b56, 0x081f, 0x0428, 0x0086, 0x0785, 0x1d04, 0x0b95, + 0x0015, 0x084d, 0x1078, 0x1727, 0x1431, 0x0869, 0x0cc0, 0x0e16, 0x03cf, 0x1cbe, 0x0747, 0x0d6a, 0x1aec, 0x0f45, 0x0496, 0x0365, + 0x0c08, 0x0a78, 0x1b1b, 0x05d7, 0x0169, 0x0c27, 0x1d25, 0x1376, 0x1db4, 0x0f67, 0x0b46, 0x1d3d, 0x1bfb, 0x0f91, 0x0d34, 0x0547, + 0x1a66, 0x17f5, 0x0478, 0x1cde, 0x168a, 0x1b67, 0x1e7c, 0x0153, 0x0a80, 0x06a1, 0x1236, 0x15bb, 0x0041, 0x1787, 0x0988, 0x04d7, + 0x1a49, 0x02d0, 0x0327, 0x02d8, 0x1635, 0x180e, 0x05fb, 0x0185, 0x0eba, 0x150b, 0x18df, 0x060b, 0x0162, 0x1404, 0x0705, 0x08b8, + 0x1ebf, 0x0638, 0x1fb9, 0x00ca, 0x1b84, 0x10d8, 0x0eea, 0x1ac5, 0x1d8b, 0x083a, 0x0aeb, 0x1fda, 0x141c, 0x1fec, 0x131b, 0x1064, + 0x1e8b, 0x0d2c, 0x15da, 0x0721, 0x081c, 0x008d, 0x14b0, 0x0221, 0x06cb, 0x08f8, 0x092d, 0x099f, 0x07fa, 0x0aa9, 0x1c83, 0x0a31, + 0x092a, 0x15d7, 0x0ae8, 0x1fb6, 0x0e8c, 0x079c, 0x0741, 0x0ae5, 0x0b43, 0x1b18, 0x0744, 0x1075, 0x18dc, 0x0324, 0x1233, 0x0475, + 0x197e, 0x0861, 0x079f, 0x1854, 0x00ef, 0x0028, 0x0cd1, 0x108a, 0x1ad5, 0x16bf, 0x0e8f, 0x1c99, 0x035e, 0x0b13, 0x1f7f, 0x128e, + 0x0be1, 0x0656, 0x1c9c, 0x0a05, 0x182f, 0x0238, 0x0133, 0x1bac, 0x1699, 0x0dfd, 0x0e92, 0x00b4, 0x0382, 0x10b0, 0x02fd, 0x0b1a, + 0x1715, 0x1b7c, 0x16c2, 0x1a88, 0x140b, 0x0075, 0x193a, 0x16e9, 0x0394, 0x1d9f, 0x1ad8, 0x0760, 0x0cad, 0x16d5, 0x17c3, 0x1357, + 0x0efa, 0x114a, 0x1291, 0x1bc6, 0x1e6c, 0x0b91, 0x1de0, 0x0500, 0x147f, 0x12aa, 0x1f82, 0x1023, 0x0b7b, 0x0347, 0x1f2b, 0x09e3, + 0x09df, 0x0a29, 0x0b16, 0x1353, 0x175a, 0x1ed7, 0x0267, 0x11c7, 0x04d3, 0x08b4, 0x0361, 0x0543, 0x0471, 0x128a, 0x1060, 0x0a2d, + 0x111b, 0x1dd5, 0x1857, 0x158c, 0x05c8, 0x127f, 0x01a3, 0x04f1, 0x0434, 0x170a, 0x07a2, 0x01b2, 0x0db3, 0x00a9, 0x0bc3, 0x026b, + 0x10d3, 0x0797, 0x0864, 0x1b62, 0x127a, 0x078c, 0x0233, 0x0b8c, 0x1c2d, 0x14f9, 0x1981, 0x1d6d, 0x0ac8, 0x0d1b, 0x0883, 0x11cb, + 0x0c9f, 0x1f74, 0x108d, 0x0195, 0x1b76, 0x0791, 0x0a72, 0x0d26, 0x0b63, 0x1d80, 0x0cd4, 0x0c71, 0x0d46, 0x0716, 0x04a9, 0x175e, + 0x109b, 0x1b10, 0x002b, 0x0d8f, 0x0dd8, 0x1cb3, 0x09c6, 0x1605, 0x0e50, 0x167f, 0x00f2, 0x15a4, 0x1504, 0x08ad, 0x0ba1, 0x1edb, + 0x18ca, 0x057c, 0x00b7, 0x0f7d, 0x011f, 0x0cd9, 0x1738, 0x10fc, 0x1ffc, 0x1c63, 0x0e95, 0x1199, 0x1c1a, 0x13d6, 0x1aa7, 0x07a6, + 0x1a1e, 0x00f8, 0x0e00, 0x1a5e, 0x032e, 0x11db, 0x1ef5, 0x18fd, 0x05ea, 0x13a9, 0x169c, 0x0afc, 0x15f3, 0x19ee, 0x14b8, 0x01b6, + 0x0336, 0x1c3e, 0x0b1d, 0x0209, 0x103d, 0x0c76, 0x056a, 0x0825, 0x1d2d, 0x157c, 0x0300, 0x06e3, 0x1a08, 0x1881, 0x010b, 0x0438, + 0x1a17, 0x1009, 0x10b3, 0x0603, 0x0dc1, 0x1f5e, 0x040d, 0x1f44, 0x1eb0, 0x0032, 0x0385, 0x0dc9, 0x1b8d, 0x0670, 0x0c01, 0x170e, + 0x1741, 0x1531, 0x0a08, 0x07d0, 0x1942, 0x0b68, 0x19ff, 0x07c6, 0x01e3, 0x149e, 0x1c9f, 0x0172, 0x02e7, 0x121f, 0x0ab3, 0x0bc7, + 0x143a, 0x15aa, 0x0659, 0x1d1d, 0x1eed, 0x0097, 0x1f3b, 0x165d, 0x0bd1, 0x06bb, 0x0be4, 0x1efe, 0x1890, 0x0c44, 0x1f13, 0x026f, + 0x138b, 0x0fc8, 0x1baf, 0x10e2, 0x03c9, 0x1d85, 0x1693, 0x042e, 0x0055, 0x09ce, 0x0136, 0x0b2d, 0x0940, 0x0416, 0x0279, 0x0db7, + 0x1192, 0x12fc, 0x023b, 0x0f3d, 0x13ce, 0x1667, 0x0573, 0x139f, 0x1ff6, 0x01dd, 0x1832, 0x19a1, 0x186c, 0x163e, 0x0d63, 0x00ad, + 0x07b0, 0x0ecc, 0x0763, 0x0fa4, 0x0447, 0x04ae, 0x090d, 0x1208, 0x1838, 0x1e4a, 0x1adb, 0x1303, 0x0299, 0x0c31, 0x09f3, 0x185b, + 0x1010, 0x0e56, 0x1da2, 0x1414, 0x02df, 0x08d5, 0x0f9b, 0x02b7, 0x0916, 0x0251, 0x0397, 0x1106, 0x1df8, 0x061c, 0x1a36, 0x1590, + 0x0f4f, 0x12d1, 0x135a, 0x19d1, 0x0966, 0x1763, 0x1e1c, 0x12bb, 0x1552, 0x0ff4, 0x17c6, 0x17a0, 0x1462, 0x1907, 0x1e25, 0x111f, + 0x0563, 0x1e15, 0x16d8, 0x0219, 0x1655, 0x01c9, 0x01c0, 0x1b4b, 0x11f0, 0x0d96, 0x0cb0, 0x0873, 0x133e, 0x125a, 0x1e75, 0x1dd9, + 0x0951, 0x1f4e, 0x1a8b, 0x0a67, 0x1569, 0x0d4b, 0x0fb7, 0x08a2, 0x19a7, 0x0de1, 0x16c5, 0x10c8, 0x1791, 0x0893, 0x0f2e, 0x01a7, + 0x142c, 0x1685, 0x1b7f, 0x0e87, 0x182a, 0x1e67, 0x05c3, 0x1b71, 0x1d5e, 0x11b8, 0x1718, 0x0466, 0x0527, 0x0c87, 0x0f18, 0x04f5, + 0x14e3, 0x1818, 0x16ec, 0x06fa, 0x05d1, 0x071b, 0x1a82, 0x1b5c, 0x011a, 0x1038, 0x193d, 0x03c4, 0x0442, 0x0961, 0x1564, 0x05cc, + 0x0669, 0x1253, 0x0078, 0x15cf, 0x0fc0, 0x1f94, 0x11af, 0x082f, 0x1a58, 0x1d17, 0x140e, 0x0e81, 0x0e42, 0x0bb5, 0x13fd, 0x1283, + 0x0598, 0x0fe3, 0x1026, 0x1c4e, 0x14e8, 0x1092, 0x159a, 0x1e3a, 0x1872, 0x1522, 0x1f85, 0x0242, 0x17e5, 0x166f, 0x0c95, 0x1985, + 0x10ba, 0x0ba7, 0x12ad, 0x0e48, 0x1a50, 0x0c68, 0x009f, 0x1490, 0x13e9, 0x05a9, 0x1482, 0x19b6, 0x0a9a, 0x02c1, 0x0229, 0x1d71, + 0x11e3, 0x19c4, 0x09e6, 0x08c8, 0x181d, 0x019a, 0x16df, 0x1d0a, 0x137e, 0x1994, 0x1f2e, 0x1212, 0x1c0d, 0x18f0, 0x0378, 0x1c31, + 0x1865, 0x0e3b, 0x034a, 0x018d, 0x06f2, 0x0d12, 0x1140, 0x14ca, 0x0535, 0x10a2, 0x0b7e, 0x1f66, 0x1fa8, 0x007f, 0x0357, 0x14fd, + 0x144a, 0x028d, 0x1bc9, 0x02ab, 0x16f1, 0x0ca4, 0x1cd4, 0x12c5, 0x1644, 0x14d7, 0x1294, 0x0e75, 0x08dd, 0x05b7, 0x0eb0, 0x0887, + 0x1619, 0x1ee1, 0x114d, 0x0bbb, 0x0f26, 0x1ba3, 0x0c1d, 0x01d1, 0x030f, 0x1ea4, 0x0efd, 0x01fd, 0x1129, 0x1a9b, 0x048c, 0x11cf, + 0x132b, 0x1f9c, 0x0503, 0x1cfe, 0x06ff, 0x1f79, 0x105a, 0x0b9b, 0x18a5, 0x160d, 0x1de3, 0x0e69, 0x1955, 0x104e, 0x0812, 0x0acc, + 0x0427, 0x1b55, 0x0b94, 0x0784, 0x1e5f, 0x0a20, 0x16b5, 0x0df0, 0x0bfb, 0x0d5d, 0x1e6f, 0x13f7, 0x0351, 0x0ad8, 0x0ade, 0x0d1f, + 0x1d3c, 0x0f66, 0x0546, 0x0f90, 0x05d6, 0x0a77, 0x1375, 0x0c26, 0x0d69, 0x1cbd, 0x0364, 0x0f44, 0x1726, 0x084c, 0x0e15, 0x0868, + 0x060a, 0x150a, 0x08b7, 0x1403, 0x02d7, 0x02cf, 0x0184, 0x180d, 0x15ba, 0x06a0, 0x04d6, 0x1786, 0x1cdd, 0x17f4, 0x0152, 0x1b66, + 0x099e, 0x08f7, 0x0a30, 0x0aa8, 0x0720, 0x0d2b, 0x0220, 0x008c, 0x1fd9, 0x0839, 0x1063, 0x1feb, 0x00c9, 0x0637, 0x1ac4, 0x10d7, + 0x1c98, 0x16be, 0x128d, 0x0b12, 0x1853, 0x0860, 0x1089, 0x0027, 0x1074, 0x1b17, 0x0474, 0x0323, 0x1fb5, 0x15d6, 0x0ae4, 0x079b, + 0x075f, 0x1d9e, 0x1356, 0x16d4, 0x1a87, 0x1b7b, 0x16e8, 0x0074, 0x00b3, 0x0dfc, 0x0b19, 0x10af, 0x0a04, 0x0655, 0x1bab, 0x0237, + 0x0542, 0x08b3, 0x0a2c, 0x1289, 0x1352, 0x0a28, 0x11c6, 0x1ed6, 0x1022, 0x12a9, 0x09e2, 0x0346, 0x1bc5, 0x1149, 0x04ff, 0x0b90, + 0x1d6c, 0x14f8, 0x11ca, 0x0d1a, 0x1b61, 0x0796, 0x0b8b, 0x078b, 0x01b1, 0x1709, 0x026a, 0x00a8, 0x158b, 0x1dd4, 0x04f0, 0x127e, + 0x15a3, 0x167e, 0x1eda, 0x08ac, 0x0d8e, 0x1b0f, 0x1604, 0x1cb2, 0x0c70, 0x1d7f, 0x175d, 0x0715, 0x0194, 0x1f73, 0x0d25, 0x0790, + 0x0afb, 0x13a8, 0x01b5, 0x19ed, 0x1a5d, 0x00f7, 0x18fc, 0x11da, 0x1198, 0x1c62, 0x07a5, 0x13d5, 0x0f7c, 0x057b, 0x10fb, 0x0cd8, + 0x0dc8, 0x0031, 0x170d, 0x066f, 0x0602, 0x1008, 0x1f43, 0x1f5d, 0x06e2, 0x157b, 0x0437, 0x1880, 0x0208, 0x1c3d, 0x0824, 0x0c75, + 0x1efd, 0x06ba, 0x026e, 0x0c43, 0x1d1c, 0x15a9, 0x165c, 0x0096, 0x0171, 0x149d, 0x0bc6, 0x121e, 0x07cf, 0x1530, 0x07c5, 0x0b67, + 0x19a0, 0x01dc, 0x00ac, 0x163d, 0x0f3c, 0x12fb, 0x139e, 0x1666, 0x0b2c, 0x09cd, 0x0db6, 0x0415, 0x10e1, 0x0fc7, 0x042d, 0x1d84, + 0x1105, 0x0250, 0x158f, 0x061b, 0x1413, 0x0e55, 0x02b6, 0x08d4, 0x1302, 0x1e49, 0x185a, 0x0c30, 0x0fa3, 0x0ecb, 0x1207, 0x04ad, + 0x0872, 0x0d95, 0x1dd8, 0x1259, 0x0218, 0x1e14, 0x1b4a, 0x01c8, 0x179f, 0x0ff3, 0x111e, 0x1906, 0x19d0, 0x12d0, 0x12ba, 0x1762, + 0x0465, 0x11b7, 0x04f4, 0x0c86, 0x0e86, 0x1684, 0x1b70, 0x1e66, 0x10c7, 0x0de0, 0x01a6, 0x0892, 0x0a66, 0x1f4d, 0x08a1, 0x0d4a, + 0x0e80, 0x1d16, 0x1282, 0x0bb4, 0x15ce, 0x1252, 0x082e, 0x1f93, 0x03c3, 0x1037, 0x05cb, 0x0960, 0x06f9, 0x1817, 0x1b5b, 0x071a, + 0x19b5, 0x05a8, 0x1d70, 0x02c0, 0x0e47, 0x0ba6, 0x148f, 0x0c67, 0x0241, 0x1521, 0x1984, 0x166e, 0x1c4d, 0x0fe2, 0x1e39, 0x1091, + 0x1f65, 0x10a1, 0x14fc, 0x007e, 0x018c, 0x0e3a, 0x14c9, 0x0d11, 0x1211, 0x1993, 0x1c30, 0x18ef, 0x08c7, 0x19c3, 0x1d09, 0x0199, + 0x01fc, 0x1ea3, 0x11ce, 0x1a9a, 0x0bba, 0x1ee0, 0x01d0, 0x1ba2, 0x0e74, 0x14d6, 0x0886, 0x05b6, 0x02aa, 0x028c, 0x12c4, 0x0ca3, + 0x13f6, 0x0d5c, 0x0d1e, 0x0ad7, 0x0783, 0x1b54, 0x0def, 0x0a1f, 0x0e68, 0x160c, 0x0acb, 0x104d, 0x1cfd, 0x1f9b, 0x0b9a, 0x1f78, + 0x1785, 0x069f, 0x1b65, 0x17f3, 0x1402, 0x1509, 0x180c, 0x02ce, 0x0f43, 0x1cbc, 0x0867, 0x084b, 0x0f8f, 0x0f65, 0x0c25, 0x0a76, + 0x0322, 0x1b16, 0x079a, 0x15d5, 0x0b11, 0x16bd, 0x0026, 0x085f, 0x1fea, 0x0838, 0x10d6, 0x0636, 0x0aa7, 0x08f6, 0x008b, 0x0d2a, + 0x0345, 0x12a8, 0x0b8f, 0x1148, 0x1288, 0x08b2, 0x1ed5, 0x0a27, 0x10ae, 0x0dfb, 0x0236, 0x0654, 0x16d3, 0x1d9d, 0x0073, 0x1b7a, + 0x0714, 0x1d7e, 0x078f, 0x1f72, 0x08ab, 0x167d, 0x1cb1, 0x1b0e, 0x00a7, 0x1708, 0x127d, 0x1dd3, 0x0d19, 0x14f7, 0x078a, 0x0795, + 0x187f, 0x157a, 0x0c74, 0x1c3c, 0x066e, 0x0030, 0x1f5c, 0x1007, 0x13d4, 0x1c61, 0x0cd7, 0x057a, 0x19ec, 0x13a7, 0x11d9, 0x00f6, + 0x0414, 0x09cc, 0x1d83, 0x0fc6, 0x163c, 0x01db, 0x1665, 0x12fa, 0x121d, 0x149c, 0x0b66, 0x152f, 0x0c42, 0x06b9, 0x0095, 0x15a8, + 0x1905, 0x0ff2, 0x1761, 0x12cf, 0x1258, 0x0d94, 0x01c7, 0x1e13, 0x0c2f, 0x1e48, 0x04ac, 0x0eca, 0x061a, 0x024f, 0x08d3, 0x0e54, + 0x095f, 0x1036, 0x0719, 0x1816, 0x0bb3, 0x1d15, 0x1f92, 0x1251, 0x0891, 0x0ddf, 0x0d49, 0x1f4c, 0x0c85, 0x11b6, 0x1e65, 0x1683, + 0x18ee, 0x1992, 0x0198, 0x19c2, 0x007d, 0x10a0, 0x0d10, 0x0e39, 0x166d, 0x1520, 0x1090, 0x0fe1, 0x02bf, 0x05a7, 0x0c66, 0x0ba5, + 0x104c, 0x160b, 0x1f77, 0x1f9a, 0x0ad6, 0x0d5b, 0x0a1e, 0x1b53, 0x05b5, 0x14d5, 0x0ca2, 0x028b, 0x1a99, 0x1ea2, 0x1ba1, 0x1edf, + 0x0635, 0x0837, 0x0d29, 0x08f5, 0x15d4, 0x1b15, 0x085e, 0x16bc, 0x084a, 0x1cbb, 0x0a75, 0x0f64, 0x17f2, 0x069e, 0x02cd, 0x1508, + 0x1dd2, 0x1707, 0x0794, 0x14f6, 0x1f71, 0x1d7d, 0x1b0d, 0x167c, 0x0653, 0x0dfa, 0x1b79, 0x1d9c, 0x1147, 0x12a7, 0x0a26, 0x08b1, + 0x152e, 0x149b, 0x15a7, 0x06b8, 0x0fc5, 0x09cb, 0x12f9, 0x01da, 0x0579, 0x1c60, 0x00f5, 0x13a6, 0x1c3b, 0x1579, 0x1006, 0x002f, + 0x1f4b, 0x0dde, 0x1682, 0x11b5, 0x1815, 0x1035, 0x1250, 0x1d14, 0x0ec9, 0x1e47, 0x0e53, 0x024e, 0x12ce, 0x0ff1, 0x1e12, 0x0d93, + 0x028a, 0x14d4, 0x1ede, 0x1ea1, 0x1f99, 0x160a, 0x1b52, 0x0d5a, 0x0fe0, 0x151f, 0x0ba4, 0x05a6, 0x19c1, 0x1991, 0x0e38, 0x109f, + 0x1d9b, 0x0df9, 0x08b0, 0x12a6, 0x14f5, 0x1706, 0x167b, 0x1d7c, 0x0f63, 0x1cba, 0x1507, 0x069d, 0x08f4, 0x0836, 0x16bb, 0x1b14, + 0x024d, 0x1e46, 0x0d92, 0x0ff0, 0x11b4, 0x0ddd, 0x1d13, 0x1034, 0x13a5, 0x1c5f, 0x002e, 0x1578, 0x06b7, 0x149a, 0x01d9, 0x09ca, + 0x069c, 0x1cb9, 0x1b13, 0x0835, 0x12a5, 0x0df8, 0x1d7b, 0x1705, 0x05a5, 0x151e, 0x109e, 0x1990, 0x1ea0, 0x14d3, 0x0d59, 0x1609, + 0x198f, 0x151d, 0x1608, 0x14d2, 0x0834, 0x1cb8, 0x1704, 0x0df7, 0x1577, 0x1c5e, 0x09c9, 0x1499, 0x0fef, 0x1e45, 0x1033, 0x0ddc, + 0x1e43, 0x1c5c, 0x1cb6, 0x151b, 0x151a, 0x1c5b, 0x1c59, 0x1c5a, 0x1498, 0x1c5d, 0x0ddb, 0x1e44, 0x14d1, 0x151c, 0x0df6, 0x1cb7 + }, + + /* "alpha_to" table */ + + { + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x001b, 0x0036, 0x006c, + 0x00d8, 0x01b0, 0x0360, 0x06c0, 0x0d80, 0x1b00, 0x161b, 0x0c2d, 0x185a, 0x10af, 0x0145, 0x028a, 0x0514, 0x0a28, 0x1450, 0x08bb, + 0x1176, 0x02f7, 0x05ee, 0x0bdc, 0x17b8, 0x0f6b, 0x1ed6, 0x1db7, 0x1b75, 0x16f1, 0x0df9, 0x1bf2, 0x17ff, 0x0fe5, 0x1fca, 0x1f8f, + 0x1f05, 0x1e11, 0x1c39, 0x1869, 0x10c9, 0x0189, 0x0312, 0x0624, 0x0c48, 0x1890, 0x113b, 0x026d, 0x04da, 0x09b4, 0x1368, 0x06cb, + 0x0d96, 0x1b2c, 0x1643, 0x0c9d, 0x193a, 0x126f, 0x04c5, 0x098a, 0x1314, 0x0633, 0x0c66, 0x18cc, 0x1183, 0x031d, 0x063a, 0x0c74, + 0x18e8, 0x11cb, 0x038d, 0x071a, 0x0e34, 0x1c68, 0x18cb, 0x118d, 0x0301, 0x0602, 0x0c04, 0x1808, 0x100b, 0x000d, 0x001a, 0x0034, + 0x0068, 0x00d0, 0x01a0, 0x0340, 0x0680, 0x0d00, 0x1a00, 0x141b, 0x082d, 0x105a, 0x00af, 0x015e, 0x02bc, 0x0578, 0x0af0, 0x15e0, + 0x0bdb, 0x17b6, 0x0f77, 0x1eee, 0x1dc7, 0x1b95, 0x1731, 0x0e79, 0x1cf2, 0x19ff, 0x13e5, 0x07d1, 0x0fa2, 0x1f44, 0x1e93, 0x1d3d, + 0x1a61, 0x14d9, 0x09a9, 0x1352, 0x06bf, 0x0d7e, 0x1afc, 0x15e3, 0x0bdd, 0x17ba, 0x0f6f, 0x1ede, 0x1da7, 0x1b55, 0x16b1, 0x0d79, + 0x1af2, 0x15ff, 0x0be5, 0x17ca, 0x0f8f, 0x1f1e, 0x1e27, 0x1c55, 0x18b1, 0x1179, 0x02e9, 0x05d2, 0x0ba4, 0x1748, 0x0e8b, 0x1d16, + 0x1a37, 0x1475, 0x08f1, 0x11e2, 0x03df, 0x07be, 0x0f7c, 0x1ef8, 0x1deb, 0x1bcd, 0x1781, 0x0f19, 0x1e32, 0x1c7f, 0x18e5, 0x11d1, + 0x03b9, 0x0772, 0x0ee4, 0x1dc8, 0x1b8b, 0x170d, 0x0e01, 0x1c02, 0x181f, 0x1025, 0x0051, 0x00a2, 0x0144, 0x0288, 0x0510, 0x0a20, + 0x1440, 0x089b, 0x1136, 0x0277, 0x04ee, 0x09dc, 0x13b8, 0x076b, 0x0ed6, 0x1dac, 0x1b43, 0x169d, 0x0d21, 0x1a42, 0x149f, 0x0925, + 0x124a, 0x048f, 0x091e, 0x123c, 0x0463, 0x08c6, 0x118c, 0x0303, 0x0606, 0x0c0c, 0x1818, 0x102b, 0x004d, 0x009a, 0x0134, 0x0268, + 0x04d0, 0x09a0, 0x1340, 0x069b, 0x0d36, 0x1a6c, 0x14c3, 0x099d, 0x133a, 0x066f, 0x0cde, 0x19bc, 0x1363, 0x06dd, 0x0dba, 0x1b74, + 0x16f3, 0x0dfd, 0x1bfa, 0x17ef, 0x0fc5, 0x1f8a, 0x1f0f, 0x1e05, 0x1c11, 0x1839, 0x1069, 0x00c9, 0x0192, 0x0324, 0x0648, 0x0c90, + 0x1920, 0x125b, 0x04ad, 0x095a, 0x12b4, 0x0573, 0x0ae6, 0x15cc, 0x0b83, 0x1706, 0x0e17, 0x1c2e, 0x1847, 0x1095, 0x0131, 0x0262, + 0x04c4, 0x0988, 0x1310, 0x063b, 0x0c76, 0x18ec, 0x11c3, 0x039d, 0x073a, 0x0e74, 0x1ce8, 0x19cb, 0x138d, 0x0701, 0x0e02, 0x1c04, + 0x1813, 0x103d, 0x0061, 0x00c2, 0x0184, 0x0308, 0x0610, 0x0c20, 0x1840, 0x109b, 0x012d, 0x025a, 0x04b4, 0x0968, 0x12d0, 0x05bb, + 0x0b76, 0x16ec, 0x0dc3, 0x1b86, 0x1717, 0x0e35, 0x1c6a, 0x18cf, 0x1185, 0x0311, 0x0622, 0x0c44, 0x1888, 0x110b, 0x020d, 0x041a, + 0x0834, 0x1068, 0x00cb, 0x0196, 0x032c, 0x0658, 0x0cb0, 0x1960, 0x12db, 0x05ad, 0x0b5a, 0x16b4, 0x0d73, 0x1ae6, 0x15d7, 0x0bb5, + 0x176a, 0x0ecf, 0x1d9e, 0x1b27, 0x1655, 0x0cb1, 0x1962, 0x12df, 0x05a5, 0x0b4a, 0x1694, 0x0d33, 0x1a66, 0x14d7, 0x09b5, 0x136a, + 0x06cf, 0x0d9e, 0x1b3c, 0x1663, 0x0cdd, 0x19ba, 0x136f, 0x06c5, 0x0d8a, 0x1b14, 0x1633, 0x0c7d, 0x18fa, 0x11ef, 0x03c5, 0x078a, + 0x0f14, 0x1e28, 0x1c4b, 0x188d, 0x1101, 0x0219, 0x0432, 0x0864, 0x10c8, 0x018b, 0x0316, 0x062c, 0x0c58, 0x18b0, 0x117b, 0x02ed, + 0x05da, 0x0bb4, 0x1768, 0x0ecb, 0x1d96, 0x1b37, 0x1675, 0x0cf1, 0x19e2, 0x13df, 0x07a5, 0x0f4a, 0x1e94, 0x1d33, 0x1a7d, 0x14e1, + 0x09d9, 0x13b2, 0x077f, 0x0efe, 0x1dfc, 0x1be3, 0x17dd, 0x0fa1, 0x1f42, 0x1e9f, 0x1d25, 0x1a51, 0x14b9, 0x0969, 0x12d2, 0x05bf, + 0x0b7e, 0x16fc, 0x0de3, 0x1bc6, 0x1797, 0x0f35, 0x1e6a, 0x1ccf, 0x1985, 0x1311, 0x0639, 0x0c72, 0x18e4, 0x11d3, 0x03bd, 0x077a, + 0x0ef4, 0x1de8, 0x1bcb, 0x178d, 0x0f01, 0x1e02, 0x1c1f, 0x1825, 0x1051, 0x00b9, 0x0172, 0x02e4, 0x05c8, 0x0b90, 0x1720, 0x0e5b, + 0x1cb6, 0x1977, 0x12f5, 0x05f1, 0x0be2, 0x17c4, 0x0f93, 0x1f26, 0x1e57, 0x1cb5, 0x1971, 0x12f9, 0x05e9, 0x0bd2, 0x17a4, 0x0f53, + 0x1ea6, 0x1d57, 0x1ab5, 0x1571, 0x0af9, 0x15f2, 0x0bff, 0x17fe, 0x0fe7, 0x1fce, 0x1f87, 0x1f15, 0x1e31, 0x1c79, 0x18e9, 0x11c9, + 0x0389, 0x0712, 0x0e24, 0x1c48, 0x188b, 0x110d, 0x0201, 0x0402, 0x0804, 0x1008, 0x000b, 0x0016, 0x002c, 0x0058, 0x00b0, 0x0160, + 0x02c0, 0x0580, 0x0b00, 0x1600, 0x0c1b, 0x1836, 0x1077, 0x00f5, 0x01ea, 0x03d4, 0x07a8, 0x0f50, 0x1ea0, 0x1d5b, 0x1aad, 0x1541, + 0x0a99, 0x1532, 0x0a7f, 0x14fe, 0x09e7, 0x13ce, 0x0787, 0x0f0e, 0x1e1c, 0x1c23, 0x185d, 0x10a1, 0x0159, 0x02b2, 0x0564, 0x0ac8, + 0x1590, 0x0b3b, 0x1676, 0x0cf7, 0x19ee, 0x13c7, 0x0795, 0x0f2a, 0x1e54, 0x1cb3, 0x197d, 0x12e1, 0x05d9, 0x0bb2, 0x1764, 0x0ed3, + 0x1da6, 0x1b57, 0x16b5, 0x0d71, 0x1ae2, 0x15df, 0x0ba5, 0x174a, 0x0e8f, 0x1d1e, 0x1a27, 0x1455, 0x08b1, 0x1162, 0x02df, 0x05be, + 0x0b7c, 0x16f8, 0x0deb, 0x1bd6, 0x17b7, 0x0f75, 0x1eea, 0x1dcf, 0x1b85, 0x1711, 0x0e39, 0x1c72, 0x18ff, 0x11e5, 0x03d1, 0x07a2, + 0x0f44, 0x1e88, 0x1d0b, 0x1a0d, 0x1401, 0x0819, 0x1032, 0x007f, 0x00fe, 0x01fc, 0x03f8, 0x07f0, 0x0fe0, 0x1fc0, 0x1f9b, 0x1f2d, + 0x1e41, 0x1c99, 0x1929, 0x1249, 0x0489, 0x0912, 0x1224, 0x0453, 0x08a6, 0x114c, 0x0283, 0x0506, 0x0a0c, 0x1418, 0x082b, 0x1056, + 0x00b7, 0x016e, 0x02dc, 0x05b8, 0x0b70, 0x16e0, 0x0ddb, 0x1bb6, 0x1777, 0x0ef5, 0x1dea, 0x1bcf, 0x1785, 0x0f11, 0x1e22, 0x1c5f, + 0x18a5, 0x1151, 0x02b9, 0x0572, 0x0ae4, 0x15c8, 0x0b8b, 0x1716, 0x0e37, 0x1c6e, 0x18c7, 0x1195, 0x0331, 0x0662, 0x0cc4, 0x1988, + 0x130b, 0x060d, 0x0c1a, 0x1834, 0x1073, 0x00fd, 0x01fa, 0x03f4, 0x07e8, 0x0fd0, 0x1fa0, 0x1f5b, 0x1ead, 0x1d41, 0x1a99, 0x1529, + 0x0a49, 0x1492, 0x093f, 0x127e, 0x04e7, 0x09ce, 0x139c, 0x0723, 0x0e46, 0x1c8c, 0x1903, 0x121d, 0x0421, 0x0842, 0x1084, 0x0113, + 0x0226, 0x044c, 0x0898, 0x1130, 0x027b, 0x04f6, 0x09ec, 0x13d8, 0x07ab, 0x0f56, 0x1eac, 0x1d43, 0x1a9d, 0x1521, 0x0a59, 0x14b2, + 0x097f, 0x12fe, 0x05e7, 0x0bce, 0x179c, 0x0f23, 0x1e46, 0x1c97, 0x1935, 0x1271, 0x04f9, 0x09f2, 0x13e4, 0x07d3, 0x0fa6, 0x1f4c, + 0x1e83, 0x1d1d, 0x1a21, 0x1459, 0x08a9, 0x1152, 0x02bf, 0x057e, 0x0afc, 0x15f8, 0x0beb, 0x17d6, 0x0fb7, 0x1f6e, 0x1ec7, 0x1d95, + 0x1b31, 0x1679, 0x0ce9, 0x19d2, 0x13bf, 0x0765, 0x0eca, 0x1d94, 0x1b33, 0x167d, 0x0ce1, 0x19c2, 0x139f, 0x0725, 0x0e4a, 0x1c94, + 0x1933, 0x127d, 0x04e1, 0x09c2, 0x1384, 0x0713, 0x0e26, 0x1c4c, 0x1883, 0x111d, 0x0221, 0x0442, 0x0884, 0x1108, 0x020b, 0x0416, + 0x082c, 0x1058, 0x00ab, 0x0156, 0x02ac, 0x0558, 0x0ab0, 0x1560, 0x0adb, 0x15b6, 0x0b77, 0x16ee, 0x0dc7, 0x1b8e, 0x1707, 0x0e15, + 0x1c2a, 0x184f, 0x1085, 0x0111, 0x0222, 0x0444, 0x0888, 0x1110, 0x023b, 0x0476, 0x08ec, 0x11d8, 0x03ab, 0x0756, 0x0eac, 0x1d58, + 0x1aab, 0x154d, 0x0a81, 0x1502, 0x0a1f, 0x143e, 0x0867, 0x10ce, 0x0187, 0x030e, 0x061c, 0x0c38, 0x1870, 0x10fb, 0x01ed, 0x03da, + 0x07b4, 0x0f68, 0x1ed0, 0x1dbb, 0x1b6d, 0x16c1, 0x0d99, 0x1b32, 0x167f, 0x0ce5, 0x19ca, 0x138f, 0x0705, 0x0e0a, 0x1c14, 0x1833, + 0x107d, 0x00e1, 0x01c2, 0x0384, 0x0708, 0x0e10, 0x1c20, 0x185b, 0x10ad, 0x0141, 0x0282, 0x0504, 0x0a08, 0x1410, 0x083b, 0x1076, + 0x00f7, 0x01ee, 0x03dc, 0x07b8, 0x0f70, 0x1ee0, 0x1ddb, 0x1bad, 0x1741, 0x0e99, 0x1d32, 0x1a7f, 0x14e5, 0x09d1, 0x13a2, 0x075f, + 0x0ebe, 0x1d7c, 0x1ae3, 0x15dd, 0x0ba1, 0x1742, 0x0e9f, 0x1d3e, 0x1a67, 0x14d5, 0x09b1, 0x1362, 0x06df, 0x0dbe, 0x1b7c, 0x16e3, + 0x0ddd, 0x1bba, 0x176f, 0x0ec5, 0x1d8a, 0x1b0f, 0x1605, 0x0c11, 0x1822, 0x105f, 0x00a5, 0x014a, 0x0294, 0x0528, 0x0a50, 0x14a0, + 0x095b, 0x12b6, 0x0577, 0x0aee, 0x15dc, 0x0ba3, 0x1746, 0x0e97, 0x1d2e, 0x1a47, 0x1495, 0x0931, 0x1262, 0x04df, 0x09be, 0x137c, + 0x06e3, 0x0dc6, 0x1b8c, 0x1703, 0x0e1d, 0x1c3a, 0x186f, 0x10c5, 0x0191, 0x0322, 0x0644, 0x0c88, 0x1910, 0x123b, 0x046d, 0x08da, + 0x11b4, 0x0373, 0x06e6, 0x0dcc, 0x1b98, 0x172b, 0x0e4d, 0x1c9a, 0x192f, 0x1245, 0x0491, 0x0922, 0x1244, 0x0493, 0x0926, 0x124c, + 0x0483, 0x0906, 0x120c, 0x0403, 0x0806, 0x100c, 0x0003, 0x0006, 0x000c, 0x0018, 0x0030, 0x0060, 0x00c0, 0x0180, 0x0300, 0x0600, + 0x0c00, 0x1800, 0x101b, 0x002d, 0x005a, 0x00b4, 0x0168, 0x02d0, 0x05a0, 0x0b40, 0x1680, 0x0d1b, 0x1a36, 0x1477, 0x08f5, 0x11ea, + 0x03cf, 0x079e, 0x0f3c, 0x1e78, 0x1ceb, 0x19cd, 0x1381, 0x0719, 0x0e32, 0x1c64, 0x18d3, 0x11bd, 0x0361, 0x06c2, 0x0d84, 0x1b08, + 0x160b, 0x0c0d, 0x181a, 0x102f, 0x0045, 0x008a, 0x0114, 0x0228, 0x0450, 0x08a0, 0x1140, 0x029b, 0x0536, 0x0a6c, 0x14d8, 0x09ab, + 0x1356, 0x06b7, 0x0d6e, 0x1adc, 0x15a3, 0x0b5d, 0x16ba, 0x0d6f, 0x1ade, 0x15a7, 0x0b55, 0x16aa, 0x0d4f, 0x1a9e, 0x1527, 0x0a55, + 0x14aa, 0x094f, 0x129e, 0x0527, 0x0a4e, 0x149c, 0x0923, 0x1246, 0x0497, 0x092e, 0x125c, 0x04a3, 0x0946, 0x128c, 0x0503, 0x0a06, + 0x140c, 0x0803, 0x1006, 0x0017, 0x002e, 0x005c, 0x00b8, 0x0170, 0x02e0, 0x05c0, 0x0b80, 0x1700, 0x0e1b, 0x1c36, 0x1877, 0x10f5, + 0x01f1, 0x03e2, 0x07c4, 0x0f88, 0x1f10, 0x1e3b, 0x1c6d, 0x18c1, 0x1199, 0x0329, 0x0652, 0x0ca4, 0x1948, 0x128b, 0x050d, 0x0a1a, + 0x1434, 0x0873, 0x10e6, 0x01d7, 0x03ae, 0x075c, 0x0eb8, 0x1d70, 0x1afb, 0x15ed, 0x0bc1, 0x1782, 0x0f1f, 0x1e3e, 0x1c67, 0x18d5, + 0x11b1, 0x0379, 0x06f2, 0x0de4, 0x1bc8, 0x178b, 0x0f0d, 0x1e1a, 0x1c2f, 0x1845, 0x1091, 0x0139, 0x0272, 0x04e4, 0x09c8, 0x1390, + 0x073b, 0x0e76, 0x1cec, 0x19c3, 0x139d, 0x0721, 0x0e42, 0x1c84, 0x1913, 0x123d, 0x0461, 0x08c2, 0x1184, 0x0313, 0x0626, 0x0c4c, + 0x1898, 0x112b, 0x024d, 0x049a, 0x0934, 0x1268, 0x04cb, 0x0996, 0x132c, 0x0643, 0x0c86, 0x190c, 0x1203, 0x041d, 0x083a, 0x1074, + 0x00f3, 0x01e6, 0x03cc, 0x0798, 0x0f30, 0x1e60, 0x1cdb, 0x19ad, 0x1341, 0x0699, 0x0d32, 0x1a64, 0x14d3, 0x09bd, 0x137a, 0x06ef, + 0x0dde, 0x1bbc, 0x1763, 0x0edd, 0x1dba, 0x1b6f, 0x16c5, 0x0d91, 0x1b22, 0x165f, 0x0ca5, 0x194a, 0x128f, 0x0505, 0x0a0a, 0x1414, + 0x0833, 0x1066, 0x00d7, 0x01ae, 0x035c, 0x06b8, 0x0d70, 0x1ae0, 0x15db, 0x0bad, 0x175a, 0x0eaf, 0x1d5e, 0x1aa7, 0x1555, 0x0ab1, + 0x1562, 0x0adf, 0x15be, 0x0b67, 0x16ce, 0x0d87, 0x1b0e, 0x1607, 0x0c15, 0x182a, 0x104f, 0x0085, 0x010a, 0x0214, 0x0428, 0x0850, + 0x10a0, 0x015b, 0x02b6, 0x056c, 0x0ad8, 0x15b0, 0x0b7b, 0x16f6, 0x0df7, 0x1bee, 0x17c7, 0x0f95, 0x1f2a, 0x1e4f, 0x1c85, 0x1911, + 0x1239, 0x0469, 0x08d2, 0x11a4, 0x0353, 0x06a6, 0x0d4c, 0x1a98, 0x152b, 0x0a4d, 0x149a, 0x092f, 0x125e, 0x04a7, 0x094e, 0x129c, + 0x0523, 0x0a46, 0x148c, 0x0903, 0x1206, 0x0417, 0x082e, 0x105c, 0x00a3, 0x0146, 0x028c, 0x0518, 0x0a30, 0x1460, 0x08db, 0x11b6, + 0x0377, 0x06ee, 0x0ddc, 0x1bb8, 0x176b, 0x0ecd, 0x1d9a, 0x1b2f, 0x1645, 0x0c91, 0x1922, 0x125f, 0x04a5, 0x094a, 0x1294, 0x0533, + 0x0a66, 0x14cc, 0x0983, 0x1306, 0x0617, 0x0c2e, 0x185c, 0x10a3, 0x015d, 0x02ba, 0x0574, 0x0ae8, 0x15d0, 0x0bbb, 0x1776, 0x0ef7, + 0x1dee, 0x1bc7, 0x1795, 0x0f31, 0x1e62, 0x1cdf, 0x19a5, 0x1351, 0x06b9, 0x0d72, 0x1ae4, 0x15d3, 0x0bbd, 0x177a, 0x0eef, 0x1dde, + 0x1ba7, 0x1755, 0x0eb1, 0x1d62, 0x1adf, 0x15a5, 0x0b51, 0x16a2, 0x0d5f, 0x1abe, 0x1567, 0x0ad5, 0x15aa, 0x0b4f, 0x169e, 0x0d27, + 0x1a4e, 0x1487, 0x0915, 0x122a, 0x044f, 0x089e, 0x113c, 0x0263, 0x04c6, 0x098c, 0x1318, 0x062b, 0x0c56, 0x18ac, 0x1143, 0x029d, + 0x053a, 0x0a74, 0x14e8, 0x09cb, 0x1396, 0x0737, 0x0e6e, 0x1cdc, 0x19a3, 0x135d, 0x06a1, 0x0d42, 0x1a84, 0x1513, 0x0a3d, 0x147a, + 0x08ef, 0x11de, 0x03a7, 0x074e, 0x0e9c, 0x1d38, 0x1a6b, 0x14cd, 0x0981, 0x1302, 0x061f, 0x0c3e, 0x187c, 0x10e3, 0x01dd, 0x03ba, + 0x0774, 0x0ee8, 0x1dd0, 0x1bbb, 0x176d, 0x0ec1, 0x1d82, 0x1b1f, 0x1625, 0x0c51, 0x18a2, 0x115f, 0x02a5, 0x054a, 0x0a94, 0x1528, + 0x0a4b, 0x1496, 0x0937, 0x126e, 0x04c7, 0x098e, 0x131c, 0x0623, 0x0c46, 0x188c, 0x1103, 0x021d, 0x043a, 0x0874, 0x10e8, 0x01cb, + 0x0396, 0x072c, 0x0e58, 0x1cb0, 0x197b, 0x12ed, 0x05c1, 0x0b82, 0x1704, 0x0e13, 0x1c26, 0x1857, 0x10b5, 0x0171, 0x02e2, 0x05c4, + 0x0b88, 0x1710, 0x0e3b, 0x1c76, 0x18f7, 0x11f5, 0x03f1, 0x07e2, 0x0fc4, 0x1f88, 0x1f0b, 0x1e0d, 0x1c01, 0x1819, 0x1029, 0x0049, + 0x0092, 0x0124, 0x0248, 0x0490, 0x0920, 0x1240, 0x049b, 0x0936, 0x126c, 0x04c3, 0x0986, 0x130c, 0x0603, 0x0c06, 0x180c, 0x1003, + 0x001d, 0x003a, 0x0074, 0x00e8, 0x01d0, 0x03a0, 0x0740, 0x0e80, 0x1d00, 0x1a1b, 0x142d, 0x0841, 0x1082, 0x011f, 0x023e, 0x047c, + 0x08f8, 0x11f0, 0x03fb, 0x07f6, 0x0fec, 0x1fd8, 0x1fab, 0x1f4d, 0x1e81, 0x1d19, 0x1a29, 0x1449, 0x0889, 0x1112, 0x023f, 0x047e, + 0x08fc, 0x11f8, 0x03eb, 0x07d6, 0x0fac, 0x1f58, 0x1eab, 0x1d4d, 0x1a81, 0x1519, 0x0a29, 0x1452, 0x08bf, 0x117e, 0x02e7, 0x05ce, + 0x0b9c, 0x1738, 0x0e6b, 0x1cd6, 0x19b7, 0x1375, 0x06f1, 0x0de2, 0x1bc4, 0x1793, 0x0f3d, 0x1e7a, 0x1cef, 0x19c5, 0x1391, 0x0739, + 0x0e72, 0x1ce4, 0x19d3, 0x13bd, 0x0761, 0x0ec2, 0x1d84, 0x1b13, 0x163d, 0x0c61, 0x18c2, 0x119f, 0x0325, 0x064a, 0x0c94, 0x1928, + 0x124b, 0x048d, 0x091a, 0x1234, 0x0473, 0x08e6, 0x11cc, 0x0383, 0x0706, 0x0e0c, 0x1c18, 0x182b, 0x104d, 0x0081, 0x0102, 0x0204, + 0x0408, 0x0810, 0x1020, 0x005b, 0x00b6, 0x016c, 0x02d8, 0x05b0, 0x0b60, 0x16c0, 0x0d9b, 0x1b36, 0x1677, 0x0cf5, 0x19ea, 0x13cf, + 0x0785, 0x0f0a, 0x1e14, 0x1c33, 0x187d, 0x10e1, 0x01d9, 0x03b2, 0x0764, 0x0ec8, 0x1d90, 0x1b3b, 0x166d, 0x0cc1, 0x1982, 0x131f, + 0x0625, 0x0c4a, 0x1894, 0x1133, 0x027d, 0x04fa, 0x09f4, 0x13e8, 0x07cb, 0x0f96, 0x1f2c, 0x1e43, 0x1c9d, 0x1921, 0x1259, 0x04a9, + 0x0952, 0x12a4, 0x0553, 0x0aa6, 0x154c, 0x0a83, 0x1506, 0x0a17, 0x142e, 0x0847, 0x108e, 0x0107, 0x020e, 0x041c, 0x0838, 0x1070, + 0x00fb, 0x01f6, 0x03ec, 0x07d8, 0x0fb0, 0x1f60, 0x1edb, 0x1dad, 0x1b41, 0x1699, 0x0d29, 0x1a52, 0x14bf, 0x0965, 0x12ca, 0x058f, + 0x0b1e, 0x163c, 0x0c63, 0x18c6, 0x1197, 0x0335, 0x066a, 0x0cd4, 0x19a8, 0x134b, 0x068d, 0x0d1a, 0x1a34, 0x1473, 0x08fd, 0x11fa, + 0x03ef, 0x07de, 0x0fbc, 0x1f78, 0x1eeb, 0x1dcd, 0x1b81, 0x1719, 0x0e29, 0x1c52, 0x18bf, 0x1165, 0x02d1, 0x05a2, 0x0b44, 0x1688, + 0x0d0b, 0x1a16, 0x1437, 0x0875, 0x10ea, 0x01cf, 0x039e, 0x073c, 0x0e78, 0x1cf0, 0x19fb, 0x13ed, 0x07c1, 0x0f82, 0x1f04, 0x1e13, + 0x1c3d, 0x1861, 0x10d9, 0x01a9, 0x0352, 0x06a4, 0x0d48, 0x1a90, 0x153b, 0x0a6d, 0x14da, 0x09af, 0x135e, 0x06a7, 0x0d4e, 0x1a9c, + 0x1523, 0x0a5d, 0x14ba, 0x096f, 0x12de, 0x05a7, 0x0b4e, 0x169c, 0x0d23, 0x1a46, 0x1497, 0x0935, 0x126a, 0x04cf, 0x099e, 0x133c, + 0x0663, 0x0cc6, 0x198c, 0x1303, 0x061d, 0x0c3a, 0x1874, 0x10f3, 0x01fd, 0x03fa, 0x07f4, 0x0fe8, 0x1fd0, 0x1fbb, 0x1f6d, 0x1ec1, + 0x1d99, 0x1b29, 0x1649, 0x0c89, 0x1912, 0x123f, 0x0465, 0x08ca, 0x1194, 0x0333, 0x0666, 0x0ccc, 0x1998, 0x132b, 0x064d, 0x0c9a, + 0x1934, 0x1273, 0x04fd, 0x09fa, 0x13f4, 0x07f3, 0x0fe6, 0x1fcc, 0x1f83, 0x1f1d, 0x1e21, 0x1c59, 0x18a9, 0x1149, 0x0289, 0x0512, + 0x0a24, 0x1448, 0x088b, 0x1116, 0x0237, 0x046e, 0x08dc, 0x11b8, 0x036b, 0x06d6, 0x0dac, 0x1b58, 0x16ab, 0x0d4d, 0x1a9a, 0x152f, + 0x0a45, 0x148a, 0x090f, 0x121e, 0x0427, 0x084e, 0x109c, 0x0123, 0x0246, 0x048c, 0x0918, 0x1230, 0x047b, 0x08f6, 0x11ec, 0x03c3, + 0x0786, 0x0f0c, 0x1e18, 0x1c2b, 0x184d, 0x1081, 0x0119, 0x0232, 0x0464, 0x08c8, 0x1190, 0x033b, 0x0676, 0x0cec, 0x19d8, 0x13ab, + 0x074d, 0x0e9a, 0x1d34, 0x1a73, 0x14fd, 0x09e1, 0x13c2, 0x079f, 0x0f3e, 0x1e7c, 0x1ce3, 0x19dd, 0x13a1, 0x0759, 0x0eb2, 0x1d64, + 0x1ad3, 0x15bd, 0x0b61, 0x16c2, 0x0d9f, 0x1b3e, 0x1667, 0x0cd5, 0x19aa, 0x134f, 0x0685, 0x0d0a, 0x1a14, 0x1433, 0x087d, 0x10fa, + 0x01ef, 0x03de, 0x07bc, 0x0f78, 0x1ef0, 0x1dfb, 0x1bed, 0x17c1, 0x0f99, 0x1f32, 0x1e7f, 0x1ce5, 0x19d1, 0x13b9, 0x0769, 0x0ed2, + 0x1da4, 0x1b53, 0x16bd, 0x0d61, 0x1ac2, 0x159f, 0x0b25, 0x164a, 0x0c8f, 0x191e, 0x1227, 0x0455, 0x08aa, 0x1154, 0x02b3, 0x0566, + 0x0acc, 0x1598, 0x0b2b, 0x1656, 0x0cb7, 0x196e, 0x12c7, 0x0595, 0x0b2a, 0x1654, 0x0cb3, 0x1966, 0x12d7, 0x05b5, 0x0b6a, 0x16d4, + 0x0db3, 0x1b66, 0x16d7, 0x0db5, 0x1b6a, 0x16cf, 0x0d85, 0x1b0a, 0x160f, 0x0c05, 0x180a, 0x100f, 0x0005, 0x000a, 0x0014, 0x0028, + 0x0050, 0x00a0, 0x0140, 0x0280, 0x0500, 0x0a00, 0x1400, 0x081b, 0x1036, 0x0077, 0x00ee, 0x01dc, 0x03b8, 0x0770, 0x0ee0, 0x1dc0, + 0x1b9b, 0x172d, 0x0e41, 0x1c82, 0x191f, 0x1225, 0x0451, 0x08a2, 0x1144, 0x0293, 0x0526, 0x0a4c, 0x1498, 0x092b, 0x1256, 0x04b7, + 0x096e, 0x12dc, 0x05a3, 0x0b46, 0x168c, 0x0d03, 0x1a06, 0x1417, 0x0835, 0x106a, 0x00cf, 0x019e, 0x033c, 0x0678, 0x0cf0, 0x19e0, + 0x13db, 0x07ad, 0x0f5a, 0x1eb4, 0x1d73, 0x1afd, 0x15e1, 0x0bd9, 0x17b2, 0x0f7f, 0x1efe, 0x1de7, 0x1bd5, 0x17b1, 0x0f79, 0x1ef2, + 0x1dff, 0x1be5, 0x17d1, 0x0fb9, 0x1f72, 0x1eff, 0x1de5, 0x1bd1, 0x17b9, 0x0f69, 0x1ed2, 0x1dbf, 0x1b65, 0x16d1, 0x0db9, 0x1b72, + 0x16ff, 0x0de5, 0x1bca, 0x178f, 0x0f05, 0x1e0a, 0x1c0f, 0x1805, 0x1011, 0x0039, 0x0072, 0x00e4, 0x01c8, 0x0390, 0x0720, 0x0e40, + 0x1c80, 0x191b, 0x122d, 0x0441, 0x0882, 0x1104, 0x0213, 0x0426, 0x084c, 0x1098, 0x012b, 0x0256, 0x04ac, 0x0958, 0x12b0, 0x057b, + 0x0af6, 0x15ec, 0x0bc3, 0x1786, 0x0f17, 0x1e2e, 0x1c47, 0x1895, 0x1131, 0x0279, 0x04f2, 0x09e4, 0x13c8, 0x078b, 0x0f16, 0x1e2c, + 0x1c43, 0x189d, 0x1121, 0x0259, 0x04b2, 0x0964, 0x12c8, 0x058b, 0x0b16, 0x162c, 0x0c43, 0x1886, 0x1117, 0x0235, 0x046a, 0x08d4, + 0x11a8, 0x034b, 0x0696, 0x0d2c, 0x1a58, 0x14ab, 0x094d, 0x129a, 0x052f, 0x0a5e, 0x14bc, 0x0963, 0x12c6, 0x0597, 0x0b2e, 0x165c, + 0x0ca3, 0x1946, 0x1297, 0x0535, 0x0a6a, 0x14d4, 0x09b3, 0x1366, 0x06d7, 0x0dae, 0x1b5c, 0x16a3, 0x0d5d, 0x1aba, 0x156f, 0x0ac5, + 0x158a, 0x0b0f, 0x161e, 0x0c27, 0x184e, 0x1087, 0x0115, 0x022a, 0x0454, 0x08a8, 0x1150, 0x02bb, 0x0576, 0x0aec, 0x15d8, 0x0bab, + 0x1756, 0x0eb7, 0x1d6e, 0x1ac7, 0x1595, 0x0b31, 0x1662, 0x0cdf, 0x19be, 0x1367, 0x06d5, 0x0daa, 0x1b54, 0x16b3, 0x0d7d, 0x1afa, + 0x15ef, 0x0bc5, 0x178a, 0x0f0f, 0x1e1e, 0x1c27, 0x1855, 0x10b1, 0x0179, 0x02f2, 0x05e4, 0x0bc8, 0x1790, 0x0f3b, 0x1e76, 0x1cf7, + 0x19f5, 0x13f1, 0x07f9, 0x0ff2, 0x1fe4, 0x1fd3, 0x1fbd, 0x1f61, 0x1ed9, 0x1da9, 0x1b49, 0x1689, 0x0d09, 0x1a12, 0x143f, 0x0865, + 0x10ca, 0x018f, 0x031e, 0x063c, 0x0c78, 0x18f0, 0x11fb, 0x03ed, 0x07da, 0x0fb4, 0x1f68, 0x1ecb, 0x1d8d, 0x1b01, 0x1619, 0x0c29, + 0x1852, 0x10bf, 0x0165, 0x02ca, 0x0594, 0x0b28, 0x1650, 0x0cbb, 0x1976, 0x12f7, 0x05f5, 0x0bea, 0x17d4, 0x0fb3, 0x1f66, 0x1ed7, + 0x1db5, 0x1b71, 0x16f9, 0x0de9, 0x1bd2, 0x17bf, 0x0f65, 0x1eca, 0x1d8f, 0x1b05, 0x1611, 0x0c39, 0x1872, 0x10ff, 0x01e5, 0x03ca, + 0x0794, 0x0f28, 0x1e50, 0x1cbb, 0x196d, 0x12c1, 0x0599, 0x0b32, 0x1664, 0x0cd3, 0x19a6, 0x1357, 0x06b5, 0x0d6a, 0x1ad4, 0x15b3, + 0x0b7d, 0x16fa, 0x0def, 0x1bde, 0x17a7, 0x0f55, 0x1eaa, 0x1d4f, 0x1a85, 0x1511, 0x0a39, 0x1472, 0x08ff, 0x11fe, 0x03e7, 0x07ce, + 0x0f9c, 0x1f38, 0x1e6b, 0x1ccd, 0x1981, 0x1319, 0x0629, 0x0c52, 0x18a4, 0x1153, 0x02bd, 0x057a, 0x0af4, 0x15e8, 0x0bcb, 0x1796, + 0x0f37, 0x1e6e, 0x1cc7, 0x1995, 0x1331, 0x0679, 0x0cf2, 0x19e4, 0x13d3, 0x07bd, 0x0f7a, 0x1ef4, 0x1df3, 0x1bfd, 0x17e1, 0x0fd9, + 0x1fb2, 0x1f7f, 0x1ee5, 0x1dd1, 0x1bb9, 0x1769, 0x0ec9, 0x1d92, 0x1b3f, 0x1665, 0x0cd1, 0x19a2, 0x135f, 0x06a5, 0x0d4a, 0x1a94, + 0x1533, 0x0a7d, 0x14fa, 0x09ef, 0x13de, 0x07a7, 0x0f4e, 0x1e9c, 0x1d23, 0x1a5d, 0x14a1, 0x0959, 0x12b2, 0x057f, 0x0afe, 0x15fc, + 0x0be3, 0x17c6, 0x0f97, 0x1f2e, 0x1e47, 0x1c95, 0x1931, 0x1279, 0x04e9, 0x09d2, 0x13a4, 0x0753, 0x0ea6, 0x1d4c, 0x1a83, 0x151d, + 0x0a21, 0x1442, 0x089f, 0x113e, 0x0267, 0x04ce, 0x099c, 0x1338, 0x066b, 0x0cd6, 0x19ac, 0x1343, 0x069d, 0x0d3a, 0x1a74, 0x14f3, + 0x09fd, 0x13fa, 0x07ef, 0x0fde, 0x1fbc, 0x1f63, 0x1edd, 0x1da1, 0x1b59, 0x16a9, 0x0d49, 0x1a92, 0x153f, 0x0a65, 0x14ca, 0x098f, + 0x131e, 0x0627, 0x0c4e, 0x189c, 0x1123, 0x025d, 0x04ba, 0x0974, 0x12e8, 0x05cb, 0x0b96, 0x172c, 0x0e43, 0x1c86, 0x1917, 0x1235, + 0x0471, 0x08e2, 0x11c4, 0x0393, 0x0726, 0x0e4c, 0x1c98, 0x192b, 0x124d, 0x0481, 0x0902, 0x1204, 0x0413, 0x0826, 0x104c, 0x0083, + 0x0106, 0x020c, 0x0418, 0x0830, 0x1060, 0x00db, 0x01b6, 0x036c, 0x06d8, 0x0db0, 0x1b60, 0x16db, 0x0dad, 0x1b5a, 0x16af, 0x0d45, + 0x1a8a, 0x150f, 0x0a05, 0x140a, 0x080f, 0x101e, 0x0027, 0x004e, 0x009c, 0x0138, 0x0270, 0x04e0, 0x09c0, 0x1380, 0x071b, 0x0e36, + 0x1c6c, 0x18c3, 0x119d, 0x0321, 0x0642, 0x0c84, 0x1908, 0x120b, 0x040d, 0x081a, 0x1034, 0x0073, 0x00e6, 0x01cc, 0x0398, 0x0730, + 0x0e60, 0x1cc0, 0x199b, 0x132d, 0x0641, 0x0c82, 0x1904, 0x1213, 0x043d, 0x087a, 0x10f4, 0x01f3, 0x03e6, 0x07cc, 0x0f98, 0x1f30, + 0x1e7b, 0x1ced, 0x19c1, 0x1399, 0x0729, 0x0e52, 0x1ca4, 0x1953, 0x12bd, 0x0561, 0x0ac2, 0x1584, 0x0b13, 0x1626, 0x0c57, 0x18ae, + 0x1147, 0x0295, 0x052a, 0x0a54, 0x14a8, 0x094b, 0x1296, 0x0537, 0x0a6e, 0x14dc, 0x09a3, 0x1346, 0x0697, 0x0d2e, 0x1a5c, 0x14a3, + 0x095d, 0x12ba, 0x056f, 0x0ade, 0x15bc, 0x0b63, 0x16c6, 0x0d97, 0x1b2e, 0x1647, 0x0c95, 0x192a, 0x124f, 0x0485, 0x090a, 0x1214, + 0x0433, 0x0866, 0x10cc, 0x0183, 0x0306, 0x060c, 0x0c18, 0x1830, 0x107b, 0x00ed, 0x01da, 0x03b4, 0x0768, 0x0ed0, 0x1da0, 0x1b5b, + 0x16ad, 0x0d41, 0x1a82, 0x151f, 0x0a25, 0x144a, 0x088f, 0x111e, 0x0227, 0x044e, 0x089c, 0x1138, 0x026b, 0x04d6, 0x09ac, 0x1358, + 0x06ab, 0x0d56, 0x1aac, 0x1543, 0x0a9d, 0x153a, 0x0a6f, 0x14de, 0x09a7, 0x134e, 0x0687, 0x0d0e, 0x1a1c, 0x1423, 0x085d, 0x10ba, + 0x016f, 0x02de, 0x05bc, 0x0b78, 0x16f0, 0x0dfb, 0x1bf6, 0x17f7, 0x0ff5, 0x1fea, 0x1fcf, 0x1f85, 0x1f11, 0x1e39, 0x1c69, 0x18c9, + 0x1189, 0x0309, 0x0612, 0x0c24, 0x1848, 0x108b, 0x010d, 0x021a, 0x0434, 0x0868, 0x10d0, 0x01bb, 0x0376, 0x06ec, 0x0dd8, 0x1bb0, + 0x177b, 0x0eed, 0x1dda, 0x1baf, 0x1745, 0x0e91, 0x1d22, 0x1a5f, 0x14a5, 0x0951, 0x12a2, 0x055f, 0x0abe, 0x157c, 0x0ae3, 0x15c6, + 0x0b97, 0x172e, 0x0e47, 0x1c8e, 0x1907, 0x1215, 0x0431, 0x0862, 0x10c4, 0x0193, 0x0326, 0x064c, 0x0c98, 0x1930, 0x127b, 0x04ed, + 0x09da, 0x13b4, 0x0773, 0x0ee6, 0x1dcc, 0x1b83, 0x171d, 0x0e21, 0x1c42, 0x189f, 0x1125, 0x0251, 0x04a2, 0x0944, 0x1288, 0x050b, + 0x0a16, 0x142c, 0x0843, 0x1086, 0x0117, 0x022e, 0x045c, 0x08b8, 0x1170, 0x02fb, 0x05f6, 0x0bec, 0x17d8, 0x0fab, 0x1f56, 0x1eb7, + 0x1d75, 0x1af1, 0x15f9, 0x0be9, 0x17d2, 0x0fbf, 0x1f7e, 0x1ee7, 0x1dd5, 0x1bb1, 0x1779, 0x0ee9, 0x1dd2, 0x1bbf, 0x1765, 0x0ed1, + 0x1da2, 0x1b5f, 0x16a5, 0x0d51, 0x1aa2, 0x155f, 0x0aa5, 0x154a, 0x0a8f, 0x151e, 0x0a27, 0x144e, 0x0887, 0x110e, 0x0207, 0x040e, + 0x081c, 0x1038, 0x006b, 0x00d6, 0x01ac, 0x0358, 0x06b0, 0x0d60, 0x1ac0, 0x159b, 0x0b2d, 0x165a, 0x0caf, 0x195e, 0x12a7, 0x0555, + 0x0aaa, 0x1554, 0x0ab3, 0x1566, 0x0ad7, 0x15ae, 0x0b47, 0x168e, 0x0d07, 0x1a0e, 0x1407, 0x0815, 0x102a, 0x004f, 0x009e, 0x013c, + 0x0278, 0x04f0, 0x09e0, 0x13c0, 0x079b, 0x0f36, 0x1e6c, 0x1cc3, 0x199d, 0x1321, 0x0659, 0x0cb2, 0x1964, 0x12d3, 0x05bd, 0x0b7a, + 0x16f4, 0x0df3, 0x1be6, 0x17d7, 0x0fb5, 0x1f6a, 0x1ecf, 0x1d85, 0x1b11, 0x1639, 0x0c69, 0x18d2, 0x11bf, 0x0365, 0x06ca, 0x0d94, + 0x1b28, 0x164b, 0x0c8d, 0x191a, 0x122f, 0x0445, 0x088a, 0x1114, 0x0233, 0x0466, 0x08cc, 0x1198, 0x032b, 0x0656, 0x0cac, 0x1958, + 0x12ab, 0x054d, 0x0a9a, 0x1534, 0x0a73, 0x14e6, 0x09d7, 0x13ae, 0x0747, 0x0e8e, 0x1d1c, 0x1a23, 0x145d, 0x08a1, 0x1142, 0x029f, + 0x053e, 0x0a7c, 0x14f8, 0x09eb, 0x13d6, 0x07b7, 0x0f6e, 0x1edc, 0x1da3, 0x1b5d, 0x16a1, 0x0d59, 0x1ab2, 0x157f, 0x0ae5, 0x15ca, + 0x0b8f, 0x171e, 0x0e27, 0x1c4e, 0x1887, 0x1115, 0x0231, 0x0462, 0x08c4, 0x1188, 0x030b, 0x0616, 0x0c2c, 0x1858, 0x10ab, 0x014d, + 0x029a, 0x0534, 0x0a68, 0x14d0, 0x09bb, 0x1376, 0x06f7, 0x0dee, 0x1bdc, 0x17a3, 0x0f5d, 0x1eba, 0x1d6f, 0x1ac5, 0x1591, 0x0b39, + 0x1672, 0x0cff, 0x19fe, 0x13e7, 0x07d5, 0x0faa, 0x1f54, 0x1eb3, 0x1d7d, 0x1ae1, 0x15d9, 0x0ba9, 0x1752, 0x0ebf, 0x1d7e, 0x1ae7, + 0x15d5, 0x0bb1, 0x1762, 0x0edf, 0x1dbe, 0x1b67, 0x16d5, 0x0db1, 0x1b62, 0x16df, 0x0da5, 0x1b4a, 0x168f, 0x0d05, 0x1a0a, 0x140f, + 0x0805, 0x100a, 0x000f, 0x001e, 0x003c, 0x0078, 0x00f0, 0x01e0, 0x03c0, 0x0780, 0x0f00, 0x1e00, 0x1c1b, 0x182d, 0x1041, 0x0099, + 0x0132, 0x0264, 0x04c8, 0x0990, 0x1320, 0x065b, 0x0cb6, 0x196c, 0x12c3, 0x059d, 0x0b3a, 0x1674, 0x0cf3, 0x19e6, 0x13d7, 0x07b5, + 0x0f6a, 0x1ed4, 0x1db3, 0x1b7d, 0x16e1, 0x0dd9, 0x1bb2, 0x177f, 0x0ee5, 0x1dca, 0x1b8f, 0x1705, 0x0e11, 0x1c22, 0x185f, 0x10a5, + 0x0151, 0x02a2, 0x0544, 0x0a88, 0x1510, 0x0a3b, 0x1476, 0x08f7, 0x11ee, 0x03c7, 0x078e, 0x0f1c, 0x1e38, 0x1c6b, 0x18cd, 0x1181, + 0x0319, 0x0632, 0x0c64, 0x18c8, 0x118b, 0x030d, 0x061a, 0x0c34, 0x1868, 0x10cb, 0x018d, 0x031a, 0x0634, 0x0c68, 0x18d0, 0x11bb, + 0x036d, 0x06da, 0x0db4, 0x1b68, 0x16cb, 0x0d8d, 0x1b1a, 0x162f, 0x0c45, 0x188a, 0x110f, 0x0205, 0x040a, 0x0814, 0x1028, 0x004b, + 0x0096, 0x012c, 0x0258, 0x04b0, 0x0960, 0x12c0, 0x059b, 0x0b36, 0x166c, 0x0cc3, 0x1986, 0x1317, 0x0635, 0x0c6a, 0x18d4, 0x11b3, + 0x037d, 0x06fa, 0x0df4, 0x1be8, 0x17cb, 0x0f8d, 0x1f1a, 0x1e2f, 0x1c45, 0x1891, 0x1139, 0x0269, 0x04d2, 0x09a4, 0x1348, 0x068b, + 0x0d16, 0x1a2c, 0x1443, 0x089d, 0x113a, 0x026f, 0x04de, 0x09bc, 0x1378, 0x06eb, 0x0dd6, 0x1bac, 0x1743, 0x0e9d, 0x1d3a, 0x1a6f, + 0x14c5, 0x0991, 0x1322, 0x065f, 0x0cbe, 0x197c, 0x12e3, 0x05dd, 0x0bba, 0x1774, 0x0ef3, 0x1de6, 0x1bd7, 0x17b5, 0x0f71, 0x1ee2, + 0x1ddf, 0x1ba5, 0x1751, 0x0eb9, 0x1d72, 0x1aff, 0x15e5, 0x0bd1, 0x17a2, 0x0f5f, 0x1ebe, 0x1d67, 0x1ad5, 0x15b1, 0x0b79, 0x16f2, + 0x0dff, 0x1bfe, 0x17e7, 0x0fd5, 0x1faa, 0x1f4f, 0x1e85, 0x1d11, 0x1a39, 0x1469, 0x08c9, 0x1192, 0x033f, 0x067e, 0x0cfc, 0x19f8, + 0x13eb, 0x07cd, 0x0f9a, 0x1f34, 0x1e73, 0x1cfd, 0x19e1, 0x13d9, 0x07a9, 0x0f52, 0x1ea4, 0x1d53, 0x1abd, 0x1561, 0x0ad9, 0x15b2, + 0x0b7f, 0x16fe, 0x0de7, 0x1bce, 0x1787, 0x0f15, 0x1e2a, 0x1c4f, 0x1885, 0x1111, 0x0239, 0x0472, 0x08e4, 0x11c8, 0x038b, 0x0716, + 0x0e2c, 0x1c58, 0x18ab, 0x114d, 0x0281, 0x0502, 0x0a04, 0x1408, 0x080b, 0x1016, 0x0037, 0x006e, 0x00dc, 0x01b8, 0x0370, 0x06e0, + 0x0dc0, 0x1b80, 0x171b, 0x0e2d, 0x1c5a, 0x18af, 0x1145, 0x0291, 0x0522, 0x0a44, 0x1488, 0x090b, 0x1216, 0x0437, 0x086e, 0x10dc, + 0x01a3, 0x0346, 0x068c, 0x0d18, 0x1a30, 0x147b, 0x08ed, 0x11da, 0x03af, 0x075e, 0x0ebc, 0x1d78, 0x1aeb, 0x15cd, 0x0b81, 0x1702, + 0x0e1f, 0x1c3e, 0x1867, 0x10d5, 0x01b1, 0x0362, 0x06c4, 0x0d88, 0x1b10, 0x163b, 0x0c6d, 0x18da, 0x11af, 0x0345, 0x068a, 0x0d14, + 0x1a28, 0x144b, 0x088d, 0x111a, 0x022f, 0x045e, 0x08bc, 0x1178, 0x02eb, 0x05d6, 0x0bac, 0x1758, 0x0eab, 0x1d56, 0x1ab7, 0x1575, + 0x0af1, 0x15e2, 0x0bdf, 0x17be, 0x0f67, 0x1ece, 0x1d87, 0x1b15, 0x1631, 0x0c79, 0x18f2, 0x11ff, 0x03e5, 0x07ca, 0x0f94, 0x1f28, + 0x1e4b, 0x1c8d, 0x1901, 0x1219, 0x0429, 0x0852, 0x10a4, 0x0153, 0x02a6, 0x054c, 0x0a98, 0x1530, 0x0a7b, 0x14f6, 0x09f7, 0x13ee, + 0x07c7, 0x0f8e, 0x1f1c, 0x1e23, 0x1c5d, 0x18a1, 0x1159, 0x02a9, 0x0552, 0x0aa4, 0x1548, 0x0a8b, 0x1516, 0x0a37, 0x146e, 0x08c7, + 0x118e, 0x0307, 0x060e, 0x0c1c, 0x1838, 0x106b, 0x00cd, 0x019a, 0x0334, 0x0668, 0x0cd0, 0x19a0, 0x135b, 0x06ad, 0x0d5a, 0x1ab4, + 0x1573, 0x0afd, 0x15fa, 0x0bef, 0x17de, 0x0fa7, 0x1f4e, 0x1e87, 0x1d15, 0x1a31, 0x1479, 0x08e9, 0x11d2, 0x03bf, 0x077e, 0x0efc, + 0x1df8, 0x1beb, 0x17cd, 0x0f81, 0x1f02, 0x1e1f, 0x1c25, 0x1851, 0x10b9, 0x0169, 0x02d2, 0x05a4, 0x0b48, 0x1690, 0x0d3b, 0x1a76, + 0x14f7, 0x09f5, 0x13ea, 0x07cf, 0x0f9e, 0x1f3c, 0x1e63, 0x1cdd, 0x19a1, 0x1359, 0x06a9, 0x0d52, 0x1aa4, 0x1553, 0x0abd, 0x157a, + 0x0aef, 0x15de, 0x0ba7, 0x174e, 0x0e87, 0x1d0e, 0x1a07, 0x1415, 0x0831, 0x1062, 0x00df, 0x01be, 0x037c, 0x06f8, 0x0df0, 0x1be0, + 0x17db, 0x0fad, 0x1f5a, 0x1eaf, 0x1d45, 0x1a91, 0x1539, 0x0a69, 0x14d2, 0x09bf, 0x137e, 0x06e7, 0x0dce, 0x1b9c, 0x1723, 0x0e5d, + 0x1cba, 0x196f, 0x12c5, 0x0591, 0x0b22, 0x1644, 0x0c93, 0x1926, 0x1257, 0x04b5, 0x096a, 0x12d4, 0x05b3, 0x0b66, 0x16cc, 0x0d83, + 0x1b06, 0x1617, 0x0c35, 0x186a, 0x10cf, 0x0185, 0x030a, 0x0614, 0x0c28, 0x1850, 0x10bb, 0x016d, 0x02da, 0x05b4, 0x0b68, 0x16d0, + 0x0dbb, 0x1b76, 0x16f7, 0x0df5, 0x1bea, 0x17cf, 0x0f85, 0x1f0a, 0x1e0f, 0x1c05, 0x1811, 0x1039, 0x0069, 0x00d2, 0x01a4, 0x0348, + 0x0690, 0x0d20, 0x1a40, 0x149b, 0x092d, 0x125a, 0x04af, 0x095e, 0x12bc, 0x0563, 0x0ac6, 0x158c, 0x0b03, 0x1606, 0x0c17, 0x182e, + 0x1047, 0x0095, 0x012a, 0x0254, 0x04a8, 0x0950, 0x12a0, 0x055b, 0x0ab6, 0x156c, 0x0ac3, 0x1586, 0x0b17, 0x162e, 0x0c47, 0x188e, + 0x1107, 0x0215, 0x042a, 0x0854, 0x10a8, 0x014b, 0x0296, 0x052c, 0x0a58, 0x14b0, 0x097b, 0x12f6, 0x05f7, 0x0bee, 0x17dc, 0x0fa3, + 0x1f46, 0x1e97, 0x1d35, 0x1a71, 0x14f9, 0x09e9, 0x13d2, 0x07bf, 0x0f7e, 0x1efc, 0x1de3, 0x1bdd, 0x17a1, 0x0f59, 0x1eb2, 0x1d7f, + 0x1ae5, 0x15d1, 0x0bb9, 0x1772, 0x0eff, 0x1dfe, 0x1be7, 0x17d5, 0x0fb1, 0x1f62, 0x1edf, 0x1da5, 0x1b51, 0x16b9, 0x0d69, 0x1ad2, + 0x15bf, 0x0b65, 0x16ca, 0x0d8f, 0x1b1e, 0x1627, 0x0c55, 0x18aa, 0x114f, 0x0285, 0x050a, 0x0a14, 0x1428, 0x084b, 0x1096, 0x0137, + 0x026e, 0x04dc, 0x09b8, 0x1370, 0x06fb, 0x0df6, 0x1bec, 0x17c3, 0x0f9d, 0x1f3a, 0x1e6f, 0x1cc5, 0x1991, 0x1339, 0x0669, 0x0cd2, + 0x19a4, 0x1353, 0x06bd, 0x0d7a, 0x1af4, 0x15f3, 0x0bfd, 0x17fa, 0x0fef, 0x1fde, 0x1fa7, 0x1f55, 0x1eb1, 0x1d79, 0x1ae9, 0x15c9, + 0x0b89, 0x1712, 0x0e3f, 0x1c7e, 0x18e7, 0x11d5, 0x03b1, 0x0762, 0x0ec4, 0x1d88, 0x1b0b, 0x160d, 0x0c01, 0x1802, 0x101f, 0x0025, + 0x004a, 0x0094, 0x0128, 0x0250, 0x04a0, 0x0940, 0x1280, 0x051b, 0x0a36, 0x146c, 0x08c3, 0x1186, 0x0317, 0x062e, 0x0c5c, 0x18b8, + 0x116b, 0x02cd, 0x059a, 0x0b34, 0x1668, 0x0ccb, 0x1996, 0x1337, 0x0675, 0x0cea, 0x19d4, 0x13b3, 0x077d, 0x0efa, 0x1df4, 0x1bf3, + 0x17fd, 0x0fe1, 0x1fc2, 0x1f9f, 0x1f25, 0x1e51, 0x1cb9, 0x1969, 0x12c9, 0x0589, 0x0b12, 0x1624, 0x0c53, 0x18a6, 0x1157, 0x02b5, + 0x056a, 0x0ad4, 0x15a8, 0x0b4b, 0x1696, 0x0d37, 0x1a6e, 0x14c7, 0x0995, 0x132a, 0x064f, 0x0c9e, 0x193c, 0x1263, 0x04dd, 0x09ba, + 0x1374, 0x06f3, 0x0de6, 0x1bcc, 0x1783, 0x0f1d, 0x1e3a, 0x1c6f, 0x18c5, 0x1191, 0x0339, 0x0672, 0x0ce4, 0x19c8, 0x138b, 0x070d, + 0x0e1a, 0x1c34, 0x1873, 0x10fd, 0x01e1, 0x03c2, 0x0784, 0x0f08, 0x1e10, 0x1c3b, 0x186d, 0x10c1, 0x0199, 0x0332, 0x0664, 0x0cc8, + 0x1990, 0x133b, 0x066d, 0x0cda, 0x19b4, 0x1373, 0x06fd, 0x0dfa, 0x1bf4, 0x17f3, 0x0ffd, 0x1ffa, 0x1fef, 0x1fc5, 0x1f91, 0x1f39, + 0x1e69, 0x1cc9, 0x1989, 0x1309, 0x0609, 0x0c12, 0x1824, 0x1053, 0x00bd, 0x017a, 0x02f4, 0x05e8, 0x0bd0, 0x17a0, 0x0f5b, 0x1eb6, + 0x1d77, 0x1af5, 0x15f1, 0x0bf9, 0x17f2, 0x0fff, 0x1ffe, 0x1fe7, 0x1fd5, 0x1fb1, 0x1f79, 0x1ee9, 0x1dc9, 0x1b89, 0x1709, 0x0e09, + 0x1c12, 0x183f, 0x1065, 0x00d1, 0x01a2, 0x0344, 0x0688, 0x0d10, 0x1a20, 0x145b, 0x08ad, 0x115a, 0x02af, 0x055e, 0x0abc, 0x1578, + 0x0aeb, 0x15d6, 0x0bb7, 0x176e, 0x0ec7, 0x1d8e, 0x1b07, 0x1615, 0x0c31, 0x1862, 0x10df, 0x01a5, 0x034a, 0x0694, 0x0d28, 0x1a50, + 0x14bb, 0x096d, 0x12da, 0x05af, 0x0b5e, 0x16bc, 0x0d63, 0x1ac6, 0x1597, 0x0b35, 0x166a, 0x0ccf, 0x199e, 0x1327, 0x0655, 0x0caa, + 0x1954, 0x12b3, 0x057d, 0x0afa, 0x15f4, 0x0bf3, 0x17e6, 0x0fd7, 0x1fae, 0x1f47, 0x1e95, 0x1d31, 0x1a79, 0x14e9, 0x09c9, 0x1392, + 0x073f, 0x0e7e, 0x1cfc, 0x19e3, 0x13dd, 0x07a1, 0x0f42, 0x1e84, 0x1d13, 0x1a3d, 0x1461, 0x08d9, 0x11b2, 0x037f, 0x06fe, 0x0dfc, + 0x1bf8, 0x17eb, 0x0fcd, 0x1f9a, 0x1f2f, 0x1e45, 0x1c91, 0x1939, 0x1269, 0x04c9, 0x0992, 0x1324, 0x0653, 0x0ca6, 0x194c, 0x1283, + 0x051d, 0x0a3a, 0x1474, 0x08f3, 0x11e6, 0x03d7, 0x07ae, 0x0f5c, 0x1eb8, 0x1d6b, 0x1acd, 0x1581, 0x0b19, 0x1632, 0x0c7f, 0x18fe, + 0x11e7, 0x03d5, 0x07aa, 0x0f54, 0x1ea8, 0x1d4b, 0x1a8d, 0x1501, 0x0a19, 0x1432, 0x087f, 0x10fe, 0x01e7, 0x03ce, 0x079c, 0x0f38, + 0x1e70, 0x1cfb, 0x19ed, 0x13c1, 0x0799, 0x0f32, 0x1e64, 0x1cd3, 0x19bd, 0x1361, 0x06d9, 0x0db2, 0x1b64, 0x16d3, 0x0dbd, 0x1b7a, + 0x16ef, 0x0dc5, 0x1b8a, 0x170f, 0x0e05, 0x1c0a, 0x180f, 0x1005, 0x0011, 0x0022, 0x0044, 0x0088, 0x0110, 0x0220, 0x0440, 0x0880, + 0x1100, 0x021b, 0x0436, 0x086c, 0x10d8, 0x01ab, 0x0356, 0x06ac, 0x0d58, 0x1ab0, 0x157b, 0x0aed, 0x15da, 0x0baf, 0x175e, 0x0ea7, + 0x1d4e, 0x1a87, 0x1515, 0x0a31, 0x1462, 0x08df, 0x11be, 0x0367, 0x06ce, 0x0d9c, 0x1b38, 0x166b, 0x0ccd, 0x199a, 0x132f, 0x0645, + 0x0c8a, 0x1914, 0x1233, 0x047d, 0x08fa, 0x11f4, 0x03f3, 0x07e6, 0x0fcc, 0x1f98, 0x1f2b, 0x1e4d, 0x1c81, 0x1919, 0x1229, 0x0449, + 0x0892, 0x1124, 0x0253, 0x04a6, 0x094c, 0x1298, 0x052b, 0x0a56, 0x14ac, 0x0943, 0x1286, 0x0517, 0x0a2e, 0x145c, 0x08a3, 0x1146, + 0x0297, 0x052e, 0x0a5c, 0x14b8, 0x096b, 0x12d6, 0x05b7, 0x0b6e, 0x16dc, 0x0da3, 0x1b46, 0x1697, 0x0d35, 0x1a6a, 0x14cf, 0x0985, + 0x130a, 0x060f, 0x0c1e, 0x183c, 0x1063, 0x00dd, 0x01ba, 0x0374, 0x06e8, 0x0dd0, 0x1ba0, 0x175b, 0x0ead, 0x1d5a, 0x1aaf, 0x1545, + 0x0a91, 0x1522, 0x0a5f, 0x14be, 0x0967, 0x12ce, 0x0587, 0x0b0e, 0x161c, 0x0c23, 0x1846, 0x1097, 0x0135, 0x026a, 0x04d4, 0x09a8, + 0x1350, 0x06bb, 0x0d76, 0x1aec, 0x15c3, 0x0b9d, 0x173a, 0x0e6f, 0x1cde, 0x19a7, 0x1355, 0x06b1, 0x0d62, 0x1ac4, 0x1593, 0x0b3d, + 0x167a, 0x0cef, 0x19de, 0x13a7, 0x0755, 0x0eaa, 0x1d54, 0x1ab3, 0x157d, 0x0ae1, 0x15c2, 0x0b9f, 0x173e, 0x0e67, 0x1cce, 0x1987, + 0x1315, 0x0631, 0x0c62, 0x18c4, 0x1193, 0x033d, 0x067a, 0x0cf4, 0x19e8, 0x13cb, 0x078d, 0x0f1a, 0x1e34, 0x1c73, 0x18fd, 0x11e1, + 0x03d9, 0x07b2, 0x0f64, 0x1ec8, 0x1d8b, 0x1b0d, 0x1601, 0x0c19, 0x1832, 0x107f, 0x00e5, 0x01ca, 0x0394, 0x0728, 0x0e50, 0x1ca0, + 0x195b, 0x12ad, 0x0541, 0x0a82, 0x1504, 0x0a13, 0x1426, 0x0857, 0x10ae, 0x0147, 0x028e, 0x051c, 0x0a38, 0x1470, 0x08fb, 0x11f6, + 0x03f7, 0x07ee, 0x0fdc, 0x1fb8, 0x1f6b, 0x1ecd, 0x1d81, 0x1b19, 0x1629, 0x0c49, 0x1892, 0x113f, 0x0265, 0x04ca, 0x0994, 0x1328, + 0x064b, 0x0c96, 0x192c, 0x1243, 0x049d, 0x093a, 0x1274, 0x04f3, 0x09e6, 0x13cc, 0x0783, 0x0f06, 0x1e0c, 0x1c03, 0x181d, 0x1021, + 0x0059, 0x00b2, 0x0164, 0x02c8, 0x0590, 0x0b20, 0x1640, 0x0c9b, 0x1936, 0x1277, 0x04f5, 0x09ea, 0x13d4, 0x07b3, 0x0f66, 0x1ecc, + 0x1d83, 0x1b1d, 0x1621, 0x0c59, 0x18b2, 0x117f, 0x02e5, 0x05ca, 0x0b94, 0x1728, 0x0e4b, 0x1c96, 0x1937, 0x1275, 0x04f1, 0x09e2, + 0x13c4, 0x0793, 0x0f26, 0x1e4c, 0x1c83, 0x191d, 0x1221, 0x0459, 0x08b2, 0x1164, 0x02d3, 0x05a6, 0x0b4c, 0x1698, 0x0d2b, 0x1a56, + 0x14b7, 0x0975, 0x12ea, 0x05cf, 0x0b9e, 0x173c, 0x0e63, 0x1cc6, 0x1997, 0x1335, 0x0671, 0x0ce2, 0x19c4, 0x1393, 0x073d, 0x0e7a, + 0x1cf4, 0x19f3, 0x13fd, 0x07e1, 0x0fc2, 0x1f84, 0x1f13, 0x1e3d, 0x1c61, 0x18d9, 0x11a9, 0x0349, 0x0692, 0x0d24, 0x1a48, 0x148b, + 0x090d, 0x121a, 0x042f, 0x085e, 0x10bc, 0x0163, 0x02c6, 0x058c, 0x0b18, 0x1630, 0x0c7b, 0x18f6, 0x11f7, 0x03f5, 0x07ea, 0x0fd4, + 0x1fa8, 0x1f4b, 0x1e8d, 0x1d01, 0x1a19, 0x1429, 0x0849, 0x1092, 0x013f, 0x027e, 0x04fc, 0x09f8, 0x13f0, 0x07fb, 0x0ff6, 0x1fec, + 0x1fc3, 0x1f9d, 0x1f21, 0x1e59, 0x1ca9, 0x1949, 0x1289, 0x0509, 0x0a12, 0x1424, 0x0853, 0x10a6, 0x0157, 0x02ae, 0x055c, 0x0ab8, + 0x1570, 0x0afb, 0x15f6, 0x0bf7, 0x17ee, 0x0fc7, 0x1f8e, 0x1f07, 0x1e15, 0x1c31, 0x1879, 0x10e9, 0x01c9, 0x0392, 0x0724, 0x0e48, + 0x1c90, 0x193b, 0x126d, 0x04c1, 0x0982, 0x1304, 0x0613, 0x0c26, 0x184c, 0x1083, 0x011d, 0x023a, 0x0474, 0x08e8, 0x11d0, 0x03bb, + 0x0776, 0x0eec, 0x1dd8, 0x1bab, 0x174d, 0x0e81, 0x1d02, 0x1a1f, 0x1425, 0x0851, 0x10a2, 0x015f, 0x02be, 0x057c, 0x0af8, 0x15f0, + 0x0bfb, 0x17f6, 0x0ff7, 0x1fee, 0x1fc7, 0x1f95, 0x1f31, 0x1e79, 0x1ce9, 0x19c9, 0x1389, 0x0709, 0x0e12, 0x1c24, 0x1853, 0x10bd, + 0x0161, 0x02c2, 0x0584, 0x0b08, 0x1610, 0x0c3b, 0x1876, 0x10f7, 0x01f5, 0x03ea, 0x07d4, 0x0fa8, 0x1f50, 0x1ebb, 0x1d6d, 0x1ac1, + 0x1599, 0x0b29, 0x1652, 0x0cbf, 0x197e, 0x12e7, 0x05d5, 0x0baa, 0x1754, 0x0eb3, 0x1d66, 0x1ad7, 0x15b5, 0x0b71, 0x16e2, 0x0ddf, + 0x1bbe, 0x1767, 0x0ed5, 0x1daa, 0x1b4f, 0x1685, 0x0d11, 0x1a22, 0x145f, 0x08a5, 0x114a, 0x028f, 0x051e, 0x0a3c, 0x1478, 0x08eb, + 0x11d6, 0x03b7, 0x076e, 0x0edc, 0x1db8, 0x1b6b, 0x16cd, 0x0d81, 0x1b02, 0x161f, 0x0c25, 0x184a, 0x108f, 0x0105, 0x020a, 0x0414, + 0x0828, 0x1050, 0x00bb, 0x0176, 0x02ec, 0x05d8, 0x0bb0, 0x1760, 0x0edb, 0x1db6, 0x1b77, 0x16f5, 0x0df1, 0x1be2, 0x17df, 0x0fa5, + 0x1f4a, 0x1e8f, 0x1d05, 0x1a11, 0x1439, 0x0869, 0x10d2, 0x01bf, 0x037e, 0x06fc, 0x0df8, 0x1bf0, 0x17fb, 0x0fed, 0x1fda, 0x1faf, + 0x1f45, 0x1e91, 0x1d39, 0x1a69, 0x14c9, 0x0989, 0x1312, 0x063f, 0x0c7e, 0x18fc, 0x11e3, 0x03dd, 0x07ba, 0x0f74, 0x1ee8, 0x1dcb, + 0x1b8d, 0x1701, 0x0e19, 0x1c32, 0x187f, 0x10e5, 0x01d1, 0x03a2, 0x0744, 0x0e88, 0x1d10, 0x1a3b, 0x146d, 0x08c1, 0x1182, 0x031f, + 0x063e, 0x0c7c, 0x18f8, 0x11eb, 0x03cd, 0x079a, 0x0f34, 0x1e68, 0x1ccb, 0x198d, 0x1301, 0x0619, 0x0c32, 0x1864, 0x10d3, 0x01bd, + 0x037a, 0x06f4, 0x0de8, 0x1bd0, 0x17bb, 0x0f6d, 0x1eda, 0x1daf, 0x1b45, 0x1691, 0x0d39, 0x1a72, 0x14ff, 0x09e5, 0x13ca, 0x078f, + 0x0f1e, 0x1e3c, 0x1c63, 0x18dd, 0x11a1, 0x0359, 0x06b2, 0x0d64, 0x1ac8, 0x158b, 0x0b0d, 0x161a, 0x0c2f, 0x185e, 0x10a7, 0x0155, + 0x02aa, 0x0554, 0x0aa8, 0x1550, 0x0abb, 0x1576, 0x0af7, 0x15ee, 0x0bc7, 0x178e, 0x0f07, 0x1e0e, 0x1c07, 0x1815, 0x1031, 0x0079, + 0x00f2, 0x01e4, 0x03c8, 0x0790, 0x0f20, 0x1e40, 0x1c9b, 0x192d, 0x1241, 0x0499, 0x0932, 0x1264, 0x04d3, 0x09a6, 0x134c, 0x0683, + 0x0d06, 0x1a0c, 0x1403, 0x081d, 0x103a, 0x006f, 0x00de, 0x01bc, 0x0378, 0x06f0, 0x0de0, 0x1bc0, 0x179b, 0x0f2d, 0x1e5a, 0x1caf, + 0x1945, 0x1291, 0x0539, 0x0a72, 0x14e4, 0x09d3, 0x13a6, 0x0757, 0x0eae, 0x1d5c, 0x1aa3, 0x155d, 0x0aa1, 0x1542, 0x0a9f, 0x153e, + 0x0a67, 0x14ce, 0x0987, 0x130e, 0x0607, 0x0c0e, 0x181c, 0x1023, 0x005d, 0x00ba, 0x0174, 0x02e8, 0x05d0, 0x0ba0, 0x1740, 0x0e9b, + 0x1d36, 0x1a77, 0x14f5, 0x09f1, 0x13e2, 0x07df, 0x0fbe, 0x1f7c, 0x1ee3, 0x1ddd, 0x1ba1, 0x1759, 0x0ea9, 0x1d52, 0x1abf, 0x1565, + 0x0ad1, 0x15a2, 0x0b5f, 0x16be, 0x0d67, 0x1ace, 0x1587, 0x0b15, 0x162a, 0x0c4f, 0x189e, 0x1127, 0x0255, 0x04aa, 0x0954, 0x12a8, + 0x054b, 0x0a96, 0x152c, 0x0a43, 0x1486, 0x0917, 0x122e, 0x0447, 0x088e, 0x111c, 0x0223, 0x0446, 0x088c, 0x1118, 0x022b, 0x0456, + 0x08ac, 0x1158, 0x02ab, 0x0556, 0x0aac, 0x1558, 0x0aab, 0x1556, 0x0ab7, 0x156e, 0x0ac7, 0x158e, 0x0b07, 0x160e, 0x0c07, 0x180e, + 0x1007, 0x0015, 0x002a, 0x0054, 0x00a8, 0x0150, 0x02a0, 0x0540, 0x0a80, 0x1500, 0x0a1b, 0x1436, 0x0877, 0x10ee, 0x01c7, 0x038e, + 0x071c, 0x0e38, 0x1c70, 0x18fb, 0x11ed, 0x03c1, 0x0782, 0x0f04, 0x1e08, 0x1c0b, 0x180d, 0x1001, 0x0019, 0x0032, 0x0064, 0x00c8, + 0x0190, 0x0320, 0x0640, 0x0c80, 0x1900, 0x121b, 0x042d, 0x085a, 0x10b4, 0x0173, 0x02e6, 0x05cc, 0x0b98, 0x1730, 0x0e7b, 0x1cf6, + 0x19f7, 0x13f5, 0x07f1, 0x0fe2, 0x1fc4, 0x1f93, 0x1f3d, 0x1e61, 0x1cd9, 0x19a9, 0x1349, 0x0689, 0x0d12, 0x1a24, 0x1453, 0x08bd, + 0x117a, 0x02ef, 0x05de, 0x0bbc, 0x1778, 0x0eeb, 0x1dd6, 0x1bb7, 0x1775, 0x0ef1, 0x1de2, 0x1bdf, 0x17a5, 0x0f51, 0x1ea2, 0x1d5f, + 0x1aa5, 0x1551, 0x0ab9, 0x1572, 0x0aff, 0x15fe, 0x0be7, 0x17ce, 0x0f87, 0x1f0e, 0x1e07, 0x1c15, 0x1831, 0x1079, 0x00e9, 0x01d2, + 0x03a4, 0x0748, 0x0e90, 0x1d20, 0x1a5b, 0x14ad, 0x0941, 0x1282, 0x051f, 0x0a3e, 0x147c, 0x08e3, 0x11c6, 0x0397, 0x072e, 0x0e5c, + 0x1cb8, 0x196b, 0x12cd, 0x0581, 0x0b02, 0x1604, 0x0c13, 0x1826, 0x1057, 0x00b5, 0x016a, 0x02d4, 0x05a8, 0x0b50, 0x16a0, 0x0d5b, + 0x1ab6, 0x1577, 0x0af5, 0x15ea, 0x0bcf, 0x179e, 0x0f27, 0x1e4e, 0x1c87, 0x1915, 0x1231, 0x0479, 0x08f2, 0x11e4, 0x03d3, 0x07a6, + 0x0f4c, 0x1e98, 0x1d2b, 0x1a4d, 0x1481, 0x0919, 0x1232, 0x047f, 0x08fe, 0x11fc, 0x03e3, 0x07c6, 0x0f8c, 0x1f18, 0x1e2b, 0x1c4d, + 0x1881, 0x1119, 0x0229, 0x0452, 0x08a4, 0x1148, 0x028b, 0x0516, 0x0a2c, 0x1458, 0x08ab, 0x1156, 0x02b7, 0x056e, 0x0adc, 0x15b8, + 0x0b6b, 0x16d6, 0x0db7, 0x1b6e, 0x16c7, 0x0d95, 0x1b2a, 0x164f, 0x0c85, 0x190a, 0x120f, 0x0405, 0x080a, 0x1014, 0x0033, 0x0066, + 0x00cc, 0x0198, 0x0330, 0x0660, 0x0cc0, 0x1980, 0x131b, 0x062d, 0x0c5a, 0x18b4, 0x1173, 0x02fd, 0x05fa, 0x0bf4, 0x17e8, 0x0fcb, + 0x1f96, 0x1f37, 0x1e75, 0x1cf1, 0x19f9, 0x13e9, 0x07c9, 0x0f92, 0x1f24, 0x1e53, 0x1cbd, 0x1961, 0x12d9, 0x05a9, 0x0b52, 0x16a4, + 0x0d53, 0x1aa6, 0x1557, 0x0ab5, 0x156a, 0x0acf, 0x159e, 0x0b27, 0x164e, 0x0c87, 0x190e, 0x1207, 0x0415, 0x082a, 0x1054, 0x00b3, + 0x0166, 0x02cc, 0x0598, 0x0b30, 0x1660, 0x0cdb, 0x19b6, 0x1377, 0x06f5, 0x0dea, 0x1bd4, 0x17b3, 0x0f7d, 0x1efa, 0x1def, 0x1bc5, + 0x1791, 0x0f39, 0x1e72, 0x1cff, 0x19e5, 0x13d1, 0x07b9, 0x0f72, 0x1ee4, 0x1dd3, 0x1bbd, 0x1761, 0x0ed9, 0x1db2, 0x1b7f, 0x16e5, + 0x0dd1, 0x1ba2, 0x175f, 0x0ea5, 0x1d4a, 0x1a8f, 0x1505, 0x0a11, 0x1422, 0x085f, 0x10be, 0x0167, 0x02ce, 0x059c, 0x0b38, 0x1670, + 0x0cfb, 0x19f6, 0x13f7, 0x07f5, 0x0fea, 0x1fd4, 0x1fb3, 0x1f7d, 0x1ee1, 0x1dd9, 0x1ba9, 0x1749, 0x0e89, 0x1d12, 0x1a3f, 0x1465, + 0x08d1, 0x11a2, 0x035f, 0x06be, 0x0d7c, 0x1af8, 0x15eb, 0x0bcd, 0x179a, 0x0f2f, 0x1e5e, 0x1ca7, 0x1955, 0x12b1, 0x0579, 0x0af2, + 0x15e4, 0x0bd3, 0x17a6, 0x0f57, 0x1eae, 0x1d47, 0x1a95, 0x1531, 0x0a79, 0x14f2, 0x09ff, 0x13fe, 0x07e7, 0x0fce, 0x1f9c, 0x1f23, + 0x1e5d, 0x1ca1, 0x1959, 0x12a9, 0x0549, 0x0a92, 0x1524, 0x0a53, 0x14a6, 0x0957, 0x12ae, 0x0547, 0x0a8e, 0x151c, 0x0a23, 0x1446, + 0x0897, 0x112e, 0x0247, 0x048e, 0x091c, 0x1238, 0x046b, 0x08d6, 0x11ac, 0x0343, 0x0686, 0x0d0c, 0x1a18, 0x142b, 0x084d, 0x109a, + 0x012f, 0x025e, 0x04bc, 0x0978, 0x12f0, 0x05fb, 0x0bf6, 0x17ec, 0x0fc3, 0x1f86, 0x1f17, 0x1e35, 0x1c71, 0x18f9, 0x11e9, 0x03c9, + 0x0792, 0x0f24, 0x1e48, 0x1c8b, 0x190d, 0x1201, 0x0419, 0x0832, 0x1064, 0x00d3, 0x01a6, 0x034c, 0x0698, 0x0d30, 0x1a60, 0x14db, + 0x09ad, 0x135a, 0x06af, 0x0d5e, 0x1abc, 0x1563, 0x0add, 0x15ba, 0x0b6f, 0x16de, 0x0da7, 0x1b4e, 0x1687, 0x0d15, 0x1a2a, 0x144f, + 0x0885, 0x110a, 0x020f, 0x041e, 0x083c, 0x1078, 0x00eb, 0x01d6, 0x03ac, 0x0758, 0x0eb0, 0x1d60, 0x1adb, 0x15ad, 0x0b41, 0x1682, + 0x0d1f, 0x1a3e, 0x1467, 0x08d5, 0x11aa, 0x034f, 0x069e, 0x0d3c, 0x1a78, 0x14eb, 0x09cd, 0x139a, 0x072f, 0x0e5e, 0x1cbc, 0x1963, + 0x12dd, 0x05a1, 0x0b42, 0x1684, 0x0d13, 0x1a26, 0x1457, 0x08b5, 0x116a, 0x02cf, 0x059e, 0x0b3c, 0x1678, 0x0ceb, 0x19d6, 0x13b7, + 0x0775, 0x0eea, 0x1dd4, 0x1bb3, 0x177d, 0x0ee1, 0x1dc2, 0x1b9f, 0x1725, 0x0e51, 0x1ca2, 0x195f, 0x12a5, 0x0551, 0x0aa2, 0x1544, + 0x0a93, 0x1526, 0x0a57, 0x14ae, 0x0947, 0x128e, 0x0507, 0x0a0e, 0x141c, 0x0823, 0x1046, 0x0097, 0x012e, 0x025c, 0x04b8, 0x0970, + 0x12e0, 0x05db, 0x0bb6, 0x176c, 0x0ec3, 0x1d86, 0x1b17, 0x1635, 0x0c71, 0x18e2, 0x11df, 0x03a5, 0x074a, 0x0e94, 0x1d28, 0x1a4b, + 0x148d, 0x0901, 0x1202, 0x041f, 0x083e, 0x107c, 0x00e3, 0x01c6, 0x038c, 0x0718, 0x0e30, 0x1c60, 0x18db, 0x11ad, 0x0341, 0x0682, + 0x0d04, 0x1a08, 0x140b, 0x080d, 0x101a, 0x002f, 0x005e, 0x00bc, 0x0178, 0x02f0, 0x05e0, 0x0bc0, 0x1780, 0x0f1b, 0x1e36, 0x1c77, + 0x18f5, 0x11f1, 0x03f9, 0x07f2, 0x0fe4, 0x1fc8, 0x1f8b, 0x1f0d, 0x1e01, 0x1c19, 0x1829, 0x1049, 0x0089, 0x0112, 0x0224, 0x0448, + 0x0890, 0x1120, 0x025b, 0x04b6, 0x096c, 0x12d8, 0x05ab, 0x0b56, 0x16ac, 0x0d43, 0x1a86, 0x1517, 0x0a35, 0x146a, 0x08cf, 0x119e, + 0x0327, 0x064e, 0x0c9c, 0x1938, 0x126b, 0x04cd, 0x099a, 0x1334, 0x0673, 0x0ce6, 0x19cc, 0x1383, 0x071d, 0x0e3a, 0x1c74, 0x18f3, + 0x11fd, 0x03e1, 0x07c2, 0x0f84, 0x1f08, 0x1e0b, 0x1c0d, 0x1801, 0x1019, 0x0029, 0x0052, 0x00a4, 0x0148, 0x0290, 0x0520, 0x0a40, + 0x1480, 0x091b, 0x1236, 0x0477, 0x08ee, 0x11dc, 0x03a3, 0x0746, 0x0e8c, 0x1d18, 0x1a2b, 0x144d, 0x0881, 0x1102, 0x021f, 0x043e, + 0x087c, 0x10f8, 0x01eb, 0x03d6, 0x07ac, 0x0f58, 0x1eb0, 0x1d7b, 0x1aed, 0x15c1, 0x0b99, 0x1732, 0x0e7f, 0x1cfe, 0x19e7, 0x13d5, + 0x07b1, 0x0f62, 0x1ec4, 0x1d93, 0x1b3d, 0x1661, 0x0cd9, 0x19b2, 0x137f, 0x06e5, 0x0dca, 0x1b94, 0x1733, 0x0e7d, 0x1cfa, 0x19ef, + 0x13c5, 0x0791, 0x0f22, 0x1e44, 0x1c93, 0x193d, 0x1261, 0x04d9, 0x09b2, 0x1364, 0x06d3, 0x0da6, 0x1b4c, 0x1683, 0x0d1d, 0x1a3a, + 0x146f, 0x08c5, 0x118a, 0x030f, 0x061e, 0x0c3c, 0x1878, 0x10eb, 0x01cd, 0x039a, 0x0734, 0x0e68, 0x1cd0, 0x19bb, 0x136d, 0x06c1, + 0x0d82, 0x1b04, 0x1613, 0x0c3d, 0x187a, 0x10ef, 0x01c5, 0x038a, 0x0714, 0x0e28, 0x1c50, 0x18bb, 0x116d, 0x02c1, 0x0582, 0x0b04, + 0x1608, 0x0c0b, 0x1816, 0x1037, 0x0075, 0x00ea, 0x01d4, 0x03a8, 0x0750, 0x0ea0, 0x1d40, 0x1a9b, 0x152d, 0x0a41, 0x1482, 0x091f, + 0x123e, 0x0467, 0x08ce, 0x119c, 0x0323, 0x0646, 0x0c8c, 0x1918, 0x122b, 0x044d, 0x089a, 0x1134, 0x0273, 0x04e6, 0x09cc, 0x1398, + 0x072b, 0x0e56, 0x1cac, 0x1943, 0x129d, 0x0521, 0x0a42, 0x1484, 0x0913, 0x1226, 0x0457, 0x08ae, 0x115c, 0x02a3, 0x0546, 0x0a8c, + 0x1518, 0x0a2b, 0x1456, 0x08b7, 0x116e, 0x02c7, 0x058e, 0x0b1c, 0x1638, 0x0c6b, 0x18d6, 0x11b7, 0x0375, 0x06ea, 0x0dd4, 0x1ba8, + 0x174b, 0x0e8d, 0x1d1a, 0x1a2f, 0x1445, 0x0891, 0x1122, 0x025f, 0x04be, 0x097c, 0x12f8, 0x05eb, 0x0bd6, 0x17ac, 0x0f43, 0x1e86, + 0x1d17, 0x1a35, 0x1471, 0x08f9, 0x11f2, 0x03ff, 0x07fe, 0x0ffc, 0x1ff8, 0x1feb, 0x1fcd, 0x1f81, 0x1f19, 0x1e29, 0x1c49, 0x1889, + 0x1109, 0x0209, 0x0412, 0x0824, 0x1048, 0x008b, 0x0116, 0x022c, 0x0458, 0x08b0, 0x1160, 0x02db, 0x05b6, 0x0b6c, 0x16d8, 0x0dab, + 0x1b56, 0x16b7, 0x0d75, 0x1aea, 0x15cf, 0x0b85, 0x170a, 0x0e0f, 0x1c1e, 0x1827, 0x1055, 0x00b1, 0x0162, 0x02c4, 0x0588, 0x0b10, + 0x1620, 0x0c5b, 0x18b6, 0x1177, 0x02f5, 0x05ea, 0x0bd4, 0x17a8, 0x0f4b, 0x1e96, 0x1d37, 0x1a75, 0x14f1, 0x09f9, 0x13f2, 0x07ff, + 0x0ffe, 0x1ffc, 0x1fe3, 0x1fdd, 0x1fa1, 0x1f59, 0x1ea9, 0x1d49, 0x1a89, 0x1509, 0x0a09, 0x1412, 0x083f, 0x107e, 0x00e7, 0x01ce, + 0x039c, 0x0738, 0x0e70, 0x1ce0, 0x19db, 0x13ad, 0x0741, 0x0e82, 0x1d04, 0x1a13, 0x143d, 0x0861, 0x10c2, 0x019f, 0x033e, 0x067c, + 0x0cf8, 0x19f0, 0x13fb, 0x07ed, 0x0fda, 0x1fb4, 0x1f73, 0x1efd, 0x1de1, 0x1bd9, 0x17a9, 0x0f49, 0x1e92, 0x1d3f, 0x1a65, 0x14d1, + 0x09b9, 0x1372, 0x06ff, 0x0dfe, 0x1bfc, 0x17e3, 0x0fdd, 0x1fba, 0x1f6f, 0x1ec5, 0x1d91, 0x1b39, 0x1669, 0x0cc9, 0x1992, 0x133f, + 0x0665, 0x0cca, 0x1994, 0x1333, 0x067d, 0x0cfa, 0x19f4, 0x13f3, 0x07fd, 0x0ffa, 0x1ff4, 0x1ff3, 0x1ffd, 0x1fe1, 0x1fd9, 0x1fa9, + 0x1f49, 0x1e89, 0x1d09, 0x1a09, 0x1409, 0x0809, 0x1012, 0x003f, 0x007e, 0x00fc, 0x01f8, 0x03f0, 0x07e0, 0x0fc0, 0x1f80, 0x1f1b, + 0x1e2d, 0x1c41, 0x1899, 0x1129, 0x0249, 0x0492, 0x0924, 0x1248, 0x048b, 0x0916, 0x122c, 0x0443, 0x0886, 0x110c, 0x0203, 0x0406, + 0x080c, 0x1018, 0x002b, 0x0056, 0x00ac, 0x0158, 0x02b0, 0x0560, 0x0ac0, 0x1580, 0x0b1b, 0x1636, 0x0c77, 0x18ee, 0x11c7, 0x0395, + 0x072a, 0x0e54, 0x1ca8, 0x194b, 0x128d, 0x0501, 0x0a02, 0x1404, 0x0813, 0x1026, 0x0057, 0x00ae, 0x015c, 0x02b8, 0x0570, 0x0ae0, + 0x15c0, 0x0b9b, 0x1736, 0x0e77, 0x1cee, 0x19c7, 0x1395, 0x0731, 0x0e62, 0x1cc4, 0x1993, 0x133d, 0x0661, 0x0cc2, 0x1984, 0x1313, + 0x063d, 0x0c7a, 0x18f4, 0x11f3, 0x03fd, 0x07fa, 0x0ff4, 0x1fe8, 0x1fcb, 0x1f8d, 0x1f01, 0x1e19, 0x1c29, 0x1849, 0x1089, 0x0109, + 0x0212, 0x0424, 0x0848, 0x1090, 0x013b, 0x0276, 0x04ec, 0x09d8, 0x13b0, 0x077b, 0x0ef6, 0x1dec, 0x1bc3, 0x179d, 0x0f21, 0x1e42, + 0x1c9f, 0x1925, 0x1251, 0x04b9, 0x0972, 0x12e4, 0x05d3, 0x0ba6, 0x174c, 0x0e83, 0x1d06, 0x1a17, 0x1435, 0x0871, 0x10e2, 0x01df, + 0x03be, 0x077c, 0x0ef8, 0x1df0, 0x1bfb, 0x17ed, 0x0fc1, 0x1f82, 0x1f1f, 0x1e25, 0x1c51, 0x18b9, 0x1169, 0x02c9, 0x0592, 0x0b24, + 0x1648, 0x0c8b, 0x1916, 0x1237, 0x0475, 0x08ea, 0x11d4, 0x03b3, 0x0766, 0x0ecc, 0x1d98, 0x1b2b, 0x164d, 0x0c81, 0x1902, 0x121f, + 0x0425, 0x084a, 0x1094, 0x0133, 0x0266, 0x04cc, 0x0998, 0x1330, 0x067b, 0x0cf6, 0x19ec, 0x13c3, 0x079d, 0x0f3a, 0x1e74, 0x1cf3, + 0x19fd, 0x13e1, 0x07d9, 0x0fb2, 0x1f64, 0x1ed3, 0x1dbd, 0x1b61, 0x16d9, 0x0da9, 0x1b52, 0x16bf, 0x0d65, 0x1aca, 0x158f, 0x0b05, + 0x160a, 0x0c0f, 0x181e, 0x1027, 0x0055, 0x00aa, 0x0154, 0x02a8, 0x0550, 0x0aa0, 0x1540, 0x0a9b, 0x1536, 0x0a77, 0x14ee, 0x09c7, + 0x138e, 0x0707, 0x0e0e, 0x1c1c, 0x1823, 0x105d, 0x00a1, 0x0142, 0x0284, 0x0508, 0x0a10, 0x1420, 0x085b, 0x10b6, 0x0177, 0x02ee, + 0x05dc, 0x0bb8, 0x1770, 0x0efb, 0x1df6, 0x1bf7, 0x17f5, 0x0ff1, 0x1fe2, 0x1fdf, 0x1fa5, 0x1f51, 0x1eb9, 0x1d69, 0x1ac9, 0x1589, + 0x0b09, 0x1612, 0x0c3f, 0x187e, 0x10e7, 0x01d5, 0x03aa, 0x0754, 0x0ea8, 0x1d50, 0x1abb, 0x156d, 0x0ac1, 0x1582, 0x0b1f, 0x163e, + 0x0c67, 0x18ce, 0x1187, 0x0315, 0x062a, 0x0c54, 0x18a8, 0x114b, 0x028d, 0x051a, 0x0a34, 0x1468, 0x08cb, 0x1196, 0x0337, 0x066e, + 0x0cdc, 0x19b8, 0x136b, 0x06cd, 0x0d9a, 0x1b34, 0x1673, 0x0cfd, 0x19fa, 0x13ef, 0x07c5, 0x0f8a, 0x1f14, 0x1e33, 0x1c7d, 0x18e1, + 0x11d9, 0x03a9, 0x0752, 0x0ea4, 0x1d48, 0x1a8b, 0x150d, 0x0a01, 0x1402, 0x081f, 0x103e, 0x0067, 0x00ce, 0x019c, 0x0338, 0x0670, + 0x0ce0, 0x19c0, 0x139b, 0x072d, 0x0e5a, 0x1cb4, 0x1973, 0x12fd, 0x05e1, 0x0bc2, 0x1784, 0x0f13, 0x1e26, 0x1c57, 0x18b5, 0x1171, + 0x02f9, 0x05f2, 0x0be4, 0x17c8, 0x0f8b, 0x1f16, 0x1e37, 0x1c75, 0x18f1, 0x11f9, 0x03e9, 0x07d2, 0x0fa4, 0x1f48, 0x1e8b, 0x1d0d, + 0x1a01, 0x1419, 0x0829, 0x1052, 0x00bf, 0x017e, 0x02fc, 0x05f8, 0x0bf0, 0x17e0, 0x0fdb, 0x1fb6, 0x1f77, 0x1ef5, 0x1df1, 0x1bf9, + 0x17e9, 0x0fc9, 0x1f92, 0x1f3f, 0x1e65, 0x1cd1, 0x19b9, 0x1369, 0x06c9, 0x0d92, 0x1b24, 0x1653, 0x0cbd, 0x197a, 0x12ef, 0x05c5, + 0x0b8a, 0x1714, 0x0e33, 0x1c66, 0x18d7, 0x11b5, 0x0371, 0x06e2, 0x0dc4, 0x1b88, 0x170b, 0x0e0d, 0x1c1a, 0x182f, 0x1045, 0x0091, + 0x0122, 0x0244, 0x0488, 0x0910, 0x1220, 0x045b, 0x08b6, 0x116c, 0x02c3, 0x0586, 0x0b0c, 0x1618, 0x0c2b, 0x1856, 0x10b7, 0x0175, + 0x02ea, 0x05d4, 0x0ba8, 0x1750, 0x0ebb, 0x1d76, 0x1af7, 0x15f5, 0x0bf1, 0x17e2, 0x0fdf, 0x1fbe, 0x1f67, 0x1ed5, 0x1db1, 0x1b79, + 0x16e9, 0x0dc9, 0x1b92, 0x173f, 0x0e65, 0x1cca, 0x198f, 0x1305, 0x0611, 0x0c22, 0x1844, 0x1093, 0x013d, 0x027a, 0x04f4, 0x09e8, + 0x13d0, 0x07bb, 0x0f76, 0x1eec, 0x1dc3, 0x1b9d, 0x1721, 0x0e59, 0x1cb2, 0x197f, 0x12e5, 0x05d1, 0x0ba2, 0x1744, 0x0e93, 0x1d26, + 0x1a57, 0x14b5, 0x0971, 0x12e2, 0x05df, 0x0bbe, 0x177c, 0x0ee3, 0x1dc6, 0x1b97, 0x1735, 0x0e71, 0x1ce2, 0x19df, 0x13a5, 0x0751, + 0x0ea2, 0x1d44, 0x1a93, 0x153d, 0x0a61, 0x14c2, 0x099f, 0x133e, 0x0667, 0x0cce, 0x199c, 0x1323, 0x065d, 0x0cba, 0x1974, 0x12f3, + 0x05fd, 0x0bfa, 0x17f4, 0x0ff3, 0x1fe6, 0x1fd7, 0x1fb5, 0x1f71, 0x1ef9, 0x1de9, 0x1bc9, 0x1789, 0x0f09, 0x1e12, 0x1c3f, 0x1865, + 0x10d1, 0x01b9, 0x0372, 0x06e4, 0x0dc8, 0x1b90, 0x173b, 0x0e6d, 0x1cda, 0x19af, 0x1345, 0x0691, 0x0d22, 0x1a44, 0x1493, 0x093d, + 0x127a, 0x04ef, 0x09de, 0x13bc, 0x0763, 0x0ec6, 0x1d8c, 0x1b03, 0x161d, 0x0c21, 0x1842, 0x109f, 0x0125, 0x024a, 0x0494, 0x0928, + 0x1250, 0x04bb, 0x0976, 0x12ec, 0x05c3, 0x0b86, 0x170c, 0x0e03, 0x1c06, 0x1817, 0x1035, 0x0071, 0x00e2, 0x01c4, 0x0388, 0x0710, + 0x0e20, 0x1c40, 0x189b, 0x112d, 0x0241, 0x0482, 0x0904, 0x1208, 0x040b, 0x0816, 0x102c, 0x0043, 0x0086, 0x010c, 0x0218, 0x0430, + 0x0860, 0x10c0, 0x019b, 0x0336, 0x066c, 0x0cd8, 0x19b0, 0x137b, 0x06ed, 0x0dda, 0x1bb4, 0x1773, 0x0efd, 0x1dfa, 0x1bef, 0x17c5, + 0x0f91, 0x1f22, 0x1e5f, 0x1ca5, 0x1951, 0x12b9, 0x0569, 0x0ad2, 0x15a4, 0x0b53, 0x16a6, 0x0d57, 0x1aae, 0x1547, 0x0a95, 0x152a, + 0x0a4f, 0x149e, 0x0927, 0x124e, 0x0487, 0x090e, 0x121c, 0x0423, 0x0846, 0x108c, 0x0103, 0x0206, 0x040c, 0x0818, 0x1030, 0x007b, + 0x00f6, 0x01ec, 0x03d8, 0x07b0, 0x0f60, 0x1ec0, 0x1d9b, 0x1b2d, 0x1641, 0x0c99, 0x1932, 0x127f, 0x04e5, 0x09ca, 0x1394, 0x0733, + 0x0e66, 0x1ccc, 0x1983, 0x131d, 0x0621, 0x0c42, 0x1884, 0x1113, 0x023d, 0x047a, 0x08f4, 0x11e8, 0x03cb, 0x0796, 0x0f2c, 0x1e58, + 0x1cab, 0x194d, 0x1281, 0x0519, 0x0a32, 0x1464, 0x08d3, 0x11a6, 0x0357, 0x06ae, 0x0d5c, 0x1ab8, 0x156b, 0x0acd, 0x159a, 0x0b2f, + 0x165e, 0x0ca7, 0x194e, 0x1287, 0x0515, 0x0a2a, 0x1454, 0x08b3, 0x1166, 0x02d7, 0x05ae, 0x0b5c, 0x16b8, 0x0d6b, 0x1ad6, 0x15b7, + 0x0b75, 0x16ea, 0x0dcf, 0x1b9e, 0x1727, 0x0e55, 0x1caa, 0x194f, 0x1285, 0x0511, 0x0a22, 0x1444, 0x0893, 0x1126, 0x0257, 0x04ae, + 0x095c, 0x12b8, 0x056b, 0x0ad6, 0x15ac, 0x0b43, 0x1686, 0x0d17, 0x1a2e, 0x1447, 0x0895, 0x112a, 0x024f, 0x049e, 0x093c, 0x1278, + 0x04eb, 0x09d6, 0x13ac, 0x0743, 0x0e86, 0x1d0c, 0x1a03, 0x141d, 0x0821, 0x1042, 0x009f, 0x013e, 0x027c, 0x04f8, 0x09f0, 0x13e0, + 0x07db, 0x0fb6, 0x1f6c, 0x1ec3, 0x1d9d, 0x1b21, 0x1659, 0x0ca9, 0x1952, 0x12bf, 0x0565, 0x0aca, 0x1594, 0x0b33, 0x1666, 0x0cd7, + 0x19ae, 0x1347, 0x0695, 0x0d2a, 0x1a54, 0x14b3, 0x097d, 0x12fa, 0x05ef, 0x0bde, 0x17bc, 0x0f63, 0x1ec6, 0x1d97, 0x1b35, 0x1671, + 0x0cf9, 0x19f2, 0x13ff, 0x07e5, 0x0fca, 0x1f94, 0x1f33, 0x1e7d, 0x1ce1, 0x19d9, 0x13a9, 0x0749, 0x0e92, 0x1d24, 0x1a53, 0x14bd, + 0x0961, 0x12c2, 0x059f, 0x0b3e, 0x167c, 0x0ce3, 0x19c6, 0x1397, 0x0735, 0x0e6a, 0x1cd4, 0x19b3, 0x137d, 0x06e1, 0x0dc2, 0x1b84, + 0x1713, 0x0e3d, 0x1c7a, 0x18ef, 0x11c5, 0x0391, 0x0722, 0x0e44, 0x1c88, 0x190b, 0x120d, 0x0401, 0x0802, 0x1004, 0x0013, 0x0026, + 0x004c, 0x0098, 0x0130, 0x0260, 0x04c0, 0x0980, 0x1300, 0x061b, 0x0c36, 0x186c, 0x10c3, 0x019d, 0x033a, 0x0674, 0x0ce8, 0x19d0, + 0x13bb, 0x076d, 0x0eda, 0x1db4, 0x1b73, 0x16fd, 0x0de1, 0x1bc2, 0x179f, 0x0f25, 0x1e4a, 0x1c8f, 0x1905, 0x1211, 0x0439, 0x0872, + 0x10e4, 0x01d3, 0x03a6, 0x074c, 0x0e98, 0x1d30, 0x1a7b, 0x14ed, 0x09c1, 0x1382, 0x071f, 0x0e3e, 0x1c7c, 0x18e3, 0x11dd, 0x03a1, + 0x0742, 0x0e84, 0x1d08, 0x1a0b, 0x140d, 0x0801, 0x1002, 0x001f, 0x003e, 0x007c, 0x00f8, 0x01f0, 0x03e0, 0x07c0, 0x0f80, 0x1f00, + 0x1e1b, 0x1c2d, 0x1841, 0x1099, 0x0129, 0x0252, 0x04a4, 0x0948, 0x1290, 0x053b, 0x0a76, 0x14ec, 0x09c3, 0x1386, 0x0717, 0x0e2e, + 0x1c5c, 0x18a3, 0x115d, 0x02a1, 0x0542, 0x0a84, 0x1508, 0x0a0b, 0x1416, 0x0837, 0x106e, 0x00c7, 0x018e, 0x031c, 0x0638, 0x0c70, + 0x18e0, 0x11db, 0x03ad, 0x075a, 0x0eb4, 0x1d68, 0x1acb, 0x158d, 0x0b01, 0x1602, 0x0c1f, 0x183e, 0x1067, 0x00d5, 0x01aa, 0x0354, + 0x06a8, 0x0d50, 0x1aa0, 0x155b, 0x0aad, 0x155a, 0x0aaf, 0x155e, 0x0aa7, 0x154e, 0x0a87, 0x150e, 0x0a07, 0x140e, 0x0807, 0x100e, + 0x0007, 0x000e, 0x001c, 0x0038, 0x0070, 0x00e0, 0x01c0, 0x0380, 0x0700, 0x0e00, 0x1c00, 0x181b, 0x102d, 0x0041, 0x0082, 0x0104, + 0x0208, 0x0410, 0x0820, 0x1040, 0x009b, 0x0136, 0x026c, 0x04d8, 0x09b0, 0x1360, 0x06db, 0x0db6, 0x1b6c, 0x16c3, 0x0d9d, 0x1b3a, + 0x166f, 0x0cc5, 0x198a, 0x130f, 0x0605, 0x0c0a, 0x1814, 0x1033, 0x007d, 0x00fa, 0x01f4, 0x03e8, 0x07d0, 0x0fa0, 0x1f40, 0x1e9b, + 0x1d2d, 0x1a41, 0x1499, 0x0929, 0x1252, 0x04bf, 0x097e, 0x12fc, 0x05e3, 0x0bc6, 0x178c, 0x0f03, 0x1e06, 0x1c17, 0x1835, 0x1071, + 0x00f9, 0x01f2, 0x03e4, 0x07c8, 0x0f90, 0x1f20, 0x1e5b, 0x1cad, 0x1941, 0x1299, 0x0529, 0x0a52, 0x14a4, 0x0953, 0x12a6, 0x0557, + 0x0aae, 0x155c, 0x0aa3, 0x1546, 0x0a97, 0x152e, 0x0a47, 0x148e, 0x0907, 0x120e, 0x0407, 0x080e, 0x101c, 0x0023, 0x0046, 0x008c, + 0x0118, 0x0230, 0x0460, 0x08c0, 0x1180, 0x031b, 0x0636, 0x0c6c, 0x18d8, 0x11ab, 0x034d, 0x069a, 0x0d34, 0x1a68, 0x14cb, 0x098d, + 0x131a, 0x062f, 0x0c5e, 0x18bc, 0x1163, 0x02dd, 0x05ba, 0x0b74, 0x16e8, 0x0dcb, 0x1b96, 0x1737, 0x0e75, 0x1cea, 0x19cf, 0x1385, + 0x0711, 0x0e22, 0x1c44, 0x1893, 0x113d, 0x0261, 0x04c2, 0x0984, 0x1308, 0x060b, 0x0c16, 0x182c, 0x1043, 0x009d, 0x013a, 0x0274, + 0x04e8, 0x09d0, 0x13a0, 0x075b, 0x0eb6, 0x1d6c, 0x1ac3, 0x159d, 0x0b21, 0x1642, 0x0c9f, 0x193e, 0x1267, 0x04d5, 0x09aa, 0x1354, + 0x06b3, 0x0d66, 0x1acc, 0x1583, 0x0b1d, 0x163a, 0x0c6f, 0x18de, 0x11a7, 0x0355, 0x06aa, 0x0d54, 0x1aa8, 0x154b, 0x0a8d, 0x151a, + 0x0a2f, 0x145e, 0x08a7, 0x114e, 0x0287, 0x050e, 0x0a1c, 0x1438, 0x086b, 0x10d6, 0x01b7, 0x036e, 0x06dc, 0x0db8, 0x1b70, 0x16fb, + 0x0ded, 0x1bda, 0x17af, 0x0f45, 0x1e8a, 0x1d0f, 0x1a05, 0x1411, 0x0839, 0x1072, 0x00ff, 0x01fe, 0x03fc, 0x07f8, 0x0ff0, 0x1fe0, + 0x1fdb, 0x1fad, 0x1f41, 0x1e99, 0x1d29, 0x1a49, 0x1489, 0x0909, 0x1212, 0x043f, 0x087e, 0x10fc, 0x01e3, 0x03c6, 0x078c, 0x0f18, + 0x1e30, 0x1c7b, 0x18ed, 0x11c1, 0x0399, 0x0732, 0x0e64, 0x1cc8, 0x198b, 0x130d, 0x0601, 0x0c02, 0x1804, 0x1013, 0x003d, 0x007a, + 0x00f4, 0x01e8, 0x03d0, 0x07a0, 0x0f40, 0x1e80, 0x1d1b, 0x1a2d, 0x1441, 0x0899, 0x1132, 0x027f, 0x04fe, 0x09fc, 0x13f8, 0x07eb, + 0x0fd6, 0x1fac, 0x1f43, 0x1e9d, 0x1d21, 0x1a59, 0x14a9, 0x0949, 0x1292, 0x053f, 0x0a7e, 0x14fc, 0x09e3, 0x13c6, 0x0797, 0x0f2e, + 0x1e5c, 0x1ca3, 0x195d, 0x12a1, 0x0559, 0x0ab2, 0x1564, 0x0ad3, 0x15a6, 0x0b57, 0x16ae, 0x0d47, 0x1a8e, 0x1507, 0x0a15, 0x142a, + 0x084f, 0x109e, 0x0127, 0x024e, 0x049c, 0x0938, 0x1270, 0x04fb, 0x09f6, 0x13ec, 0x07c3, 0x0f86, 0x1f0c, 0x1e03, 0x1c1d, 0x1821, + 0x1059, 0x00a9, 0x0152, 0x02a4, 0x0548, 0x0a90, 0x1520, 0x0a5b, 0x14b6, 0x0977, 0x12ee, 0x05c7, 0x0b8e, 0x171c, 0x0e23, 0x1c46, + 0x1897, 0x1135, 0x0271, 0x04e2, 0x09c4, 0x1388, 0x070b, 0x0e16, 0x1c2c, 0x1843, 0x109d, 0x0121, 0x0242, 0x0484, 0x0908, 0x1210, + 0x043b, 0x0876, 0x10ec, 0x01c3, 0x0386, 0x070c, 0x0e18, 0x1c30, 0x187b, 0x10ed, 0x01c1, 0x0382, 0x0704, 0x0e08, 0x1c10, 0x183b, + 0x106d, 0x00c1, 0x0182, 0x0304, 0x0608, 0x0c10, 0x1820, 0x105b, 0x00ad, 0x015a, 0x02b4, 0x0568, 0x0ad0, 0x15a0, 0x0b5b, 0x16b6, + 0x0d77, 0x1aee, 0x15c7, 0x0b95, 0x172a, 0x0e4f, 0x1c9e, 0x1927, 0x1255, 0x04b1, 0x0962, 0x12c4, 0x0593, 0x0b26, 0x164c, 0x0c83, + 0x1906, 0x1217, 0x0435, 0x086a, 0x10d4, 0x01b3, 0x0366, 0x06cc, 0x0d98, 0x1b30, 0x167b, 0x0ced, 0x19da, 0x13af, 0x0745, 0x0e8a, + 0x1d14, 0x1a33, 0x147d, 0x08e1, 0x11c2, 0x039f, 0x073e, 0x0e7c, 0x1cf8, 0x19eb, 0x13cd, 0x0781, 0x0f02, 0x1e04, 0x1c13, 0x183d, + 0x1061, 0x00d9, 0x01b2, 0x0364, 0x06c8, 0x0d90, 0x1b20, 0x165b, 0x0cad, 0x195a, 0x12af, 0x0545, 0x0a8a, 0x1514, 0x0a33, 0x1466, + 0x08d7, 0x11ae, 0x0347, 0x068e, 0x0d1c, 0x1a38, 0x146b, 0x08cd, 0x119a, 0x032f, 0x065e, 0x0cbc, 0x1978, 0x12eb, 0x05cd, 0x0b9a, + 0x1734, 0x0e73, 0x1ce6, 0x19d7, 0x13b5, 0x0771, 0x0ee2, 0x1dc4, 0x1b93, 0x173d, 0x0e61, 0x1cc2, 0x199f, 0x1325, 0x0651, 0x0ca2, + 0x1944, 0x1293, 0x053d, 0x0a7a, 0x14f4, 0x09f3, 0x13e6, 0x07d7, 0x0fae, 0x1f5c, 0x1ea3, 0x1d5d, 0x1aa1, 0x1559, 0x0aa9, 0x1552, + 0x0abf, 0x157e, 0x0ae7, 0x15ce, 0x0b87, 0x170e, 0x0e07, 0x1c0e, 0x1807, 0x1015, 0x0031, 0x0062, 0x00c4, 0x0188, 0x0310, 0x0620, + 0x0c40, 0x1880, 0x111b, 0x022d, 0x045a, 0x08b4, 0x1168, 0x02cb, 0x0596, 0x0b2c, 0x1658, 0x0cab, 0x1956, 0x12b7, 0x0575, 0x0aea, + 0x15d4, 0x0bb3, 0x1766, 0x0ed7, 0x1dae, 0x1b47, 0x1695, 0x0d31, 0x1a62, 0x14df, 0x09a5, 0x134a, 0x068f, 0x0d1e, 0x1a3c, 0x1463, + 0x08dd, 0x11ba, 0x036f, 0x06de, 0x0dbc, 0x1b78, 0x16eb, 0x0dcd, 0x1b9a, 0x172f, 0x0e45, 0x1c8a, 0x190f, 0x1205, 0x0411, 0x0822, + 0x1044, 0x0093, 0x0126, 0x024c, 0x0498, 0x0930, 0x1260, 0x04db, 0x09b6, 0x136c, 0x06c3, 0x0d86, 0x1b0c, 0x1603, 0x0c1d, 0x183a, + 0x106f, 0x00c5, 0x018a, 0x0314, 0x0628, 0x0c50, 0x18a0, 0x115b, 0x02ad, 0x055a, 0x0ab4, 0x1568, 0x0acb, 0x1596, 0x0b37, 0x166e, + 0x0cc7, 0x198e, 0x1307, 0x0615, 0x0c2a, 0x1854, 0x10b3, 0x017d, 0x02fa, 0x05f4, 0x0be8, 0x17d0, 0x0fbb, 0x1f76, 0x1ef7, 0x1df5, + 0x1bf1, 0x17f9, 0x0fe9, 0x1fd2, 0x1fbf, 0x1f65, 0x1ed1, 0x1db9, 0x1b69, 0x16c9, 0x0d89, 0x1b12, 0x163f, 0x0c65, 0x18ca, 0x118f, + 0x0305, 0x060a, 0x0c14, 0x1828, 0x104b, 0x008d, 0x011a, 0x0234, 0x0468, 0x08d0, 0x11a0, 0x035b, 0x06b6, 0x0d6c, 0x1ad8, 0x15ab, + 0x0b4d, 0x169a, 0x0d2f, 0x1a5e, 0x14a7, 0x0955, 0x12aa, 0x054f, 0x0a9e, 0x153c, 0x0a63, 0x14c6, 0x0997, 0x132e, 0x0647, 0x0c8e, + 0x191c, 0x1223, 0x045d, 0x08ba, 0x1174, 0x02f3, 0x05e6, 0x0bcc, 0x1798, 0x0f2b, 0x1e56, 0x1cb7, 0x1975, 0x12f1, 0x05f9, 0x0bf2, + 0x17e4, 0x0fd3, 0x1fa6, 0x1f57, 0x1eb5, 0x1d71, 0x1af9, 0x15e9, 0x0bc9, 0x1792, 0x0f3f, 0x1e7e, 0x1ce7, 0x19d5, 0x13b1, 0x0779, + 0x0ef2, 0x1de4, 0x1bd3, 0x17bd, 0x0f61, 0x1ec2, 0x1d9f, 0x1b25, 0x1651, 0x0cb9, 0x1972, 0x12ff, 0x05e5, 0x0bca, 0x1794, 0x0f33, + 0x1e66, 0x1cd7, 0x19b5, 0x1371, 0x06f9, 0x0df2, 0x1be4, 0x17d3, 0x0fbd, 0x1f7a, 0x1eef, 0x1dc5, 0x1b91, 0x1739, 0x0e69, 0x1cd2, + 0x19bf, 0x1365, 0x06d1, 0x0da2, 0x1b44, 0x1693, 0x0d3d, 0x1a7a, 0x14ef, 0x09c5, 0x138a, 0x070f, 0x0e1e, 0x1c3c, 0x1863, 0x10dd, + 0x01a1, 0x0342, 0x0684, 0x0d08, 0x1a10, 0x143b, 0x086d, 0x10da, 0x01af, 0x035e, 0x06bc, 0x0d78, 0x1af0, 0x15fb, 0x0bed, 0x17da, + 0x0faf, 0x1f5e, 0x1ea7, 0x1d55, 0x1ab1, 0x1579, 0x0ae9, 0x15d2, 0x0bbf, 0x177e, 0x0ee7, 0x1dce, 0x1b87, 0x1715, 0x0e31, 0x1c62, + 0x18df, 0x11a5, 0x0351, 0x06a2, 0x0d44, 0x1a88, 0x150b, 0x0a0d, 0x141a, 0x082f, 0x105e, 0x00a7, 0x014e, 0x029c, 0x0538, 0x0a70, + 0x14e0, 0x09db, 0x13b6, 0x0777, 0x0eee, 0x1ddc, 0x1ba3, 0x175d, 0x0ea1, 0x1d42, 0x1a9f, 0x1525, 0x0a51, 0x14a2, 0x095f, 0x12be, + 0x0567, 0x0ace, 0x159c, 0x0b23, 0x1646, 0x0c97, 0x192e, 0x1247, 0x0495, 0x092a, 0x1254, 0x04b3, 0x0966, 0x12cc, 0x0583, 0x0b06, + 0x160c, 0x0c03, 0x1806, 0x1017, 0x0035, 0x006a, 0x00d4, 0x01a8, 0x0350, 0x06a0, 0x0d40, 0x1a80, 0x151b, 0x0a2d, 0x145a, 0x08af, + 0x115e, 0x02a7, 0x054e, 0x0a9c, 0x1538, 0x0a6b, 0x14d6, 0x09b7, 0x136e, 0x06c7, 0x0d8e, 0x1b1c, 0x1623, 0x0c5d, 0x18ba, 0x116f, + 0x02c5, 0x058a, 0x0b14, 0x1628, 0x0c4b, 0x1896, 0x1137, 0x0275, 0x04ea, 0x09d4, 0x13a8, 0x074b, 0x0e96, 0x1d2c, 0x1a43, 0x149d, + 0x0921, 0x1242, 0x049f, 0x093e, 0x127c, 0x04e3, 0x09c6, 0x138c, 0x0703, 0x0e06, 0x1c0c, 0x1803, 0x101d, 0x0021, 0x0042, 0x0084, + 0x0108, 0x0210, 0x0420, 0x0840, 0x1080, 0x011b, 0x0236, 0x046c, 0x08d8, 0x11b0, 0x037b, 0x06f6, 0x0dec, 0x1bd8, 0x17ab, 0x0f4d, + 0x1e9a, 0x1d2f, 0x1a45, 0x1491, 0x0939, 0x1272, 0x04ff, 0x09fe, 0x13fc, 0x07e3, 0x0fc6, 0x1f8c, 0x1f03, 0x1e1d, 0x1c21, 0x1859, + 0x10a9, 0x0149, 0x0292, 0x0524, 0x0a48, 0x1490, 0x093b, 0x1276, 0x04f7, 0x09ee, 0x13dc, 0x07a3, 0x0f46, 0x1e8c, 0x1d03, 0x1a1d, + 0x1421, 0x0859, 0x10b2, 0x017f, 0x02fe, 0x05fc, 0x0bf8, 0x17f0, 0x0ffb, 0x1ff6, 0x1ff7, 0x1ff5, 0x1ff1, 0x1ff9, 0x1fe9, 0x1fc9, + 0x1f89, 0x1f09, 0x1e09, 0x1c09, 0x1809, 0x1009, 0x0009, 0x0012, 0x0024, 0x0048, 0x0090, 0x0120, 0x0240, 0x0480, 0x0900, 0x1200, + 0x041b, 0x0836, 0x106c, 0x00c3, 0x0186, 0x030c, 0x0618, 0x0c30, 0x1860, 0x10db, 0x01ad, 0x035a, 0x06b4, 0x0d68, 0x1ad0, 0x15bb, + 0x0b6d, 0x16da, 0x0daf, 0x1b5e, 0x16a7, 0x0d55, 0x1aaa, 0x154f, 0x0a85, 0x150a, 0x0a0f, 0x141e, 0x0827, 0x104e, 0x0087, 0x010e, + 0x021c, 0x0438, 0x0870, 0x10e0, 0x01db, 0x03b6, 0x076c, 0x0ed8, 0x1db0, 0x1b7b, 0x16ed, 0x0dc1, 0x1b82, 0x171f, 0x0e25, 0x1c4a, + 0x188f, 0x1105, 0x0211, 0x0422, 0x0844, 0x1088, 0x010b, 0x0216, 0x042c, 0x0858, 0x10b0, 0x017b, 0x02f6, 0x05ec, 0x0bd8, 0x17b0, + 0x0f7b, 0x1ef6, 0x1df7, 0x1bf5, 0x17f1, 0x0ff9, 0x1ff2, 0x1fff, 0x1fe5, 0x1fd1, 0x1fb9, 0x1f69, 0x1ec9, 0x1d89, 0x1b09, 0x1609, + 0x0c09, 0x1812, 0x103f, 0x0065, 0x00ca, 0x0194, 0x0328, 0x0650, 0x0ca0, 0x1940, 0x129b, 0x052d, 0x0a5a, 0x14b4, 0x0973, 0x12e6, + 0x05d7, 0x0bae, 0x175c, 0x0ea3, 0x1d46, 0x1a97, 0x1535, 0x0a71, 0x14e2, 0x09df, 0x13be, 0x0767, 0x0ece, 0x1d9c, 0x1b23, 0x165d, + 0x0ca1, 0x1942, 0x129f, 0x0525, 0x0a4a, 0x1494, 0x0933, 0x1266, 0x04d7, 0x09ae, 0x135c, 0x06a3, 0x0d46, 0x1a8c, 0x1503, 0x0a1d, + 0x143a, 0x086f, 0x10de, 0x01a7, 0x034e, 0x069c, 0x0d38, 0x1a70, 0x14fb, 0x09ed, 0x13da, 0x07af, 0x0f5e, 0x1ebc, 0x1d63, 0x1add, + 0x15a1, 0x0b59, 0x16b2, 0x0d7f, 0x1afe, 0x15e7, 0x0bd5, 0x17aa, 0x0f4f, 0x1e9e, 0x1d27, 0x1a55, 0x14b1, 0x0979, 0x12f2, 0x05ff, + 0x0bfe, 0x17fc, 0x0fe3, 0x1fc6, 0x1f97, 0x1f35, 0x1e71, 0x1cf9, 0x19e9, 0x13c9, 0x0789, 0x0f12, 0x1e24, 0x1c53, 0x18bd, 0x1161, + 0x02d9, 0x05b2, 0x0b64, 0x16c8, 0x0d8b, 0x1b16, 0x1637, 0x0c75, 0x18ea, 0x11cf, 0x0385, 0x070a, 0x0e14, 0x1c28, 0x184b, 0x108d, + 0x0101, 0x0202, 0x0404, 0x0808, 0x1010, 0x003b, 0x0076, 0x00ec, 0x01d8, 0x03b0, 0x0760, 0x0ec0, 0x1d80, 0x1b1b, 0x162d, 0x0c41, + 0x1882, 0x111f, 0x0225, 0x044a, 0x0894, 0x1128, 0x024b, 0x0496, 0x092c, 0x1258, 0x04ab, 0x0956, 0x12ac, 0x0543, 0x0a86, 0x150c, + 0x0a03, 0x1406, 0x0817, 0x102e, 0x0047, 0x008e, 0x011c, 0x0238, 0x0470, 0x08e0, 0x11c0, 0x039b, 0x0736, 0x0e6c, 0x1cd8, 0x19ab, + 0x134d, 0x0681, 0x0d02, 0x1a04, 0x1413, 0x083d, 0x107a, 0x00ef, 0x01de, 0x03bc, 0x0778, 0x0ef0, 0x1de0, 0x1bdb, 0x17ad, 0x0f41, + 0x1e82, 0x1d1f, 0x1a25, 0x1451, 0x08b9, 0x1172, 0x02ff, 0x05fe, 0x0bfc, 0x17f8, 0x0feb, 0x1fd6, 0x1fb7, 0x1f75, 0x1ef1, 0x1df9, + 0x1be9, 0x17c9, 0x0f89, 0x1f12, 0x1e3f, 0x1c65, 0x18d1, 0x11b9, 0x0369, 0x06d2, 0x0da4, 0x1b48, 0x168b, 0x0d0d, 0x1a1a, 0x142f, + 0x0845, 0x108a, 0x010f, 0x021e, 0x043c, 0x0878, 0x10f0, 0x01fb, 0x03f6, 0x07ec, 0x0fd8, 0x1fb0, 0x1f7b, 0x1eed, 0x1dc1, 0x1b99, + 0x1729, 0x0e49, 0x1c92, 0x193f, 0x1265, 0x04d1, 0x09a2, 0x1344, 0x0693, 0x0d26, 0x1a4c, 0x1483, 0x091d, 0x123a, 0x046f, 0x08de, + 0x11bc, 0x0363, 0x06c6, 0x0d8c, 0x1b18, 0x162b, 0x0c4d, 0x189a, 0x112f, 0x0245, 0x048a, 0x0914, 0x1228, 0x044b, 0x0896, 0x112c, + 0x0243, 0x0486, 0x090c, 0x1218, 0x042b, 0x0856, 0x10ac, 0x0143, 0x0286, 0x050c, 0x0a18, 0x1430, 0x087b, 0x10f6, 0x01f7, 0x03ee, + 0x07dc, 0x0fb8, 0x1f70, 0x1efb, 0x1ded, 0x1bc1, 0x1799, 0x0f29, 0x1e52, 0x1cbf, 0x1965, 0x12d1, 0x05b9, 0x0b72, 0x16e4, 0x0dd3, + 0x1ba6, 0x1757, 0x0eb5, 0x1d6a, 0x1acf, 0x1585, 0x0b11, 0x1622, 0x0c5f, 0x18be, 0x1167, 0x02d5, 0x05aa, 0x0b54, 0x16a8, 0x0d4b, + 0x1a96, 0x1537, 0x0a75, 0x14ea, 0x09cf, 0x139e, 0x0727, 0x0e4e, 0x1c9c, 0x1923, 0x125d, 0x04a1, 0x0942, 0x1284, 0x0513, 0x0a26, + 0x144c, 0x0883, 0x1106, 0x0217, 0x042e, 0x085c, 0x10b8, 0x016b, 0x02d6, 0x05ac, 0x0b58, 0x16b0, 0x0d7b, 0x1af6, 0x15f7, 0x0bf5, + 0x17ea, 0x0fcf, 0x1f9e, 0x1f27, 0x1e55, 0x1cb1, 0x1979, 0x12e9, 0x05c9, 0x0b92, 0x1724, 0x0e53, 0x1ca6, 0x1957, 0x12b5, 0x0571, + 0x0ae2, 0x15c4, 0x0b93, 0x1726, 0x0e57, 0x1cae, 0x1947, 0x1295, 0x0531, 0x0a62, 0x14c4, 0x0993, 0x1326, 0x0657, 0x0cae, 0x195c, + 0x12a3, 0x055d, 0x0aba, 0x1574, 0x0af3, 0x15e6, 0x0bd7, 0x17ae, 0x0f47, 0x1e8e, 0x1d07, 0x1a15, 0x1431, 0x0879, 0x10f2, 0x01ff, + 0x03fe, 0x07fc, 0x0ff8, 0x1ff0, 0x1ffb, 0x1fed, 0x1fc1, 0x1f99, 0x1f29, 0x1e49, 0x1c89, 0x1909, 0x1209, 0x0409, 0x0812, 0x1024, + 0x0053, 0x00a6, 0x014c, 0x0298, 0x0530, 0x0a60, 0x14c0, 0x099b, 0x1336, 0x0677, 0x0cee, 0x19dc, 0x13a3, 0x075d, 0x0eba, 0x1d74, + 0x1af3, 0x15fd, 0x0be1, 0x17c2, 0x0f9f, 0x1f3e, 0x1e67, 0x1cd5, 0x19b1, 0x1379, 0x06e9, 0x0dd2, 0x1ba4, 0x1753, 0x0ebd, 0x1d7a, + 0x1aef, 0x15c5, 0x0b91, 0x1722, 0x0e5f, 0x1cbe, 0x1967, 0x12d5, 0x05b1, 0x0b62, 0x16c4, 0x0d93, 0x1b26, 0x1657, 0x0cb5, 0x196a, + 0x12cf, 0x0585, 0x0b0a, 0x1614, 0x0c33, 0x1866, 0x10d7, 0x01b5, 0x036a, 0x06d4, 0x0da8, 0x1b50, 0x16bb, 0x0d6d, 0x1ada, 0x15af, + 0x0b45, 0x168a, 0x0d0f, 0x1a1e, 0x1427, 0x0855, 0x10aa, 0x014f, 0x029e, 0x053c, 0x0a78, 0x14f0, 0x09fb, 0x13f6, 0x07f7, 0x0fee, + 0x1fdc, 0x1fa3, 0x1f5d, 0x1ea1, 0x1d59, 0x1aa9, 0x1549, 0x0a89, 0x1512, 0x0a3f, 0x147e, 0x08e7, 0x11ce, 0x0387, 0x070e, 0x0e1c, + 0x1c38, 0x186b, 0x10cd, 0x0181, 0x0302, 0x0604, 0x0c08, 0x1810, 0x103b, 0x006d, 0x00da, 0x01b4, 0x0368, 0x06d0, 0x0da0, 0x1b40, + 0x169b, 0x0d2d, 0x1a5a, 0x14af, 0x0945, 0x128a, 0x050f, 0x0a1e, 0x143c, 0x0863, 0x10c6, 0x0197, 0x032e, 0x065c, 0x0cb8, 0x1970, + 0x12fb, 0x05ed, 0x0bda, 0x17b4, 0x0f73, 0x1ee6, 0x1dd7, 0x1bb5, 0x1771, 0x0ef9, 0x1df2, 0x1bff, 0x17e5, 0x0fd1, 0x1fa2, 0x1f5f, + 0x1ea5, 0x1d51, 0x1ab9, 0x1569, 0x0ac9, 0x1592, 0x0b3f, 0x167e, 0x0ce7, 0x19ce, 0x1387, 0x0715, 0x0e2a, 0x1c54, 0x18b3, 0x117d, + 0x02e1, 0x05c2, 0x0b84, 0x1708, 0x0e0b, 0x1c16, 0x1837, 0x1075, 0x00f1, 0x01e2, 0x03c4, 0x0788, 0x0f10, 0x1e20, 0x1c5b, 0x18ad, + 0x1141, 0x0299, 0x0532, 0x0a64, 0x14c8, 0x098b, 0x1316, 0x0637, 0x0c6e, 0x18dc, 0x11a3, 0x035d, 0x06ba, 0x0d74, 0x1ae8, 0x15cb, + 0x0b8d, 0x171a, 0x0e2f, 0x1c5e, 0x18a7, 0x1155, 0x02b1, 0x0562, 0x0ac4, 0x1588, 0x0b0b, 0x1616, 0x0c37, 0x186e, 0x10c7, 0x0195, + 0x032a, 0x0654, 0x0ca8, 0x1950, 0x12bb, 0x056d, 0x0ada, 0x15b4, 0x0b73, 0x16e6, 0x0dd7, 0x1bae, 0x1747, 0x0e95, 0x1d2a, 0x1a4f, + 0x1485, 0x0911, 0x1222, 0x045f, 0x08be, 0x117c, 0x02e3, 0x05c6, 0x0b8c, 0x1718, 0x0e2b, 0x1c56, 0x18b7, 0x1175, 0x02f1, 0x05e2, + 0x0bc4, 0x1788, 0x0f0b, 0x1e16, 0x1c37, 0x1875, 0x10f1, 0x01f9, 0x03f2, 0x07e4, 0x0fc8, 0x1f90, 0x1f3b, 0x1e6d, 0x1cc1, 0x1999, + 0x1329, 0x0649, 0x0c92, 0x1924, 0x1253, 0x04bd, 0x097a, 0x12f4, 0x05f3, 0x0be6, 0x17cc, 0x0f83, 0x1f06, 0x1e17, 0x1c35, 0x1871, + 0x10f9, 0x01e9, 0x03d2, 0x07a4, 0x0f48, 0x1e90, 0x1d3b, 0x1a6d, 0x14c1, 0x0999, 0x1332, 0x067f, 0x0cfe, 0x19fc, 0x13e3, 0x07dd, + 0x0fba, 0x1f74, 0x1ef3, 0x1dfd, 0x1be1, 0x17d9, 0x0fa9, 0x1f52, 0x1ebf, 0x1d65, 0x1ad1, 0x15b9, 0x0b69, 0x16d2, 0x0dbf, 0x1b7e, + 0x16e7, 0x0dd5, 0x1baa, 0x174f, 0x0e85, 0x1d0a, 0x1a0f, 0x1405, 0x0811, 0x1022, 0x005f, 0x00be, 0x017c, 0x02f8, 0x05f0, 0x0be0, + 0x17c0, 0x0f9b, 0x1f36, 0x1e77, 0x1cf5, 0x19f1, 0x13f9, 0x07e9, 0x0fd2, 0x1fa4, 0x1f53, 0x1ebd, 0x1d61, 0x1ad9, 0x15a9, 0x0b49, + 0x1692, 0x0d3f, 0x1a7e, 0x14e7, 0x09d5, 0x13aa, 0x074f, 0x0e9e, 0x1d3c, 0x1a63, 0x14dd, 0x09a1, 0x1342, 0x069f, 0x0d3e, 0x1a7c, + 0x14e3, 0x09dd, 0x13ba, 0x076f, 0x0ede, 0x1dbc, 0x1b63, 0x16dd, 0x0da1, 0x1b42, 0x169f, 0x0d25, 0x1a4a, 0x148f, 0x0905, 0x120a, + 0x040f, 0x081e, 0x103c, 0x0063, 0x00c6, 0x018c, 0x0318, 0x0630, 0x0c60, 0x18c0, 0x119b, 0x032d, 0x065a, 0x0cb4, 0x1968, 0x12cb, + 0x058d, 0x0b1a, 0x1634, 0x0c73, 0x18e6, 0x11d7, 0x03b5, 0x076a, 0x0ed4, 0x1da8, 0x1b4b, 0x168d, 0x0d01, 0x1a02, 0x141f, 0x0825, + 0x104a, 0x008f, 0x011e, 0x023c, 0x0478, 0x08f0, 0x11e0, 0x03db, 0x07b6, 0x0f6c, 0x1ed8, 0x1dab, 0x1b4d, 0x1681, 0x0d19, 0x1a32, + 0x147f, 0x08e5, 0x11ca, 0x038f, 0x071e, 0x0e3c, 0x1c78, 0x18eb, 0x11cd, 0x0381, 0x0702, 0x0e04, 0x1c08, 0x180b, 0x100d, 0x0001 + } +}; + +#endif /* CONFIG_SAMA5_HAVE_PMECC && !CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */ diff --git a/arch/arm/src/sama5/sam_gmac.c b/arch/arm/src/sama5/sam_gmac.c new file mode 100644 index 0000000000000000000000000000000000000000..8426e7dcb3b36929fd8d5e45f285c6e556f8add7 --- /dev/null +++ b/arch/arm/src/sama5/sam_gmac.c @@ -0,0 +1,3646 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_gmac.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "chip.h" +#include "chip/sam_pinmap.h" +#include "sam_pio.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_ethernet.h" + +#include + +#if defined(CONFIG_NET) && defined(CONFIG_SAMA5_GMAC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Number of buffer for RX */ + +#ifndef CONFIG_SAMA5_GMAC_NRXBUFFERS +# define CONFIG_SAMA5_GMAC_NRXBUFFERS 16 +#endif + +/* Number of buffer for TX */ + +#ifndef CONFIG_SAMA5_GMAC_NTXBUFFERS +# define CONFIG_SAMA5_GMAC_NTXBUFFERS 8 +#endif + +#undef CONFIG_SAMA5_GMAC_NBC + +#ifndef CONFIG_SAMA5_GMAC_PHYADDR +# error "CONFIG_SAMA5_GMAC_PHYADDR must be defined in the NuttX configuration" +#endif + +/* PHY definitions */ + +#ifdef SAMA5_GMAC_PHY_KSZ90x1 +# define GMII_OUI_MSB 0x0022 +# define GMII_OUI_LSB GMII_PHYID2_OUI(5) +#else +# error Unknown PHY +#endif + +/* GMAC buffer sizes, number of buffers, and number of descriptors. + * + * REVISIT: The CONFIG_NET_MULTIBUFFER might be useful. It might be possible + * to use this option to send and receive messages directly into the DMA + * buffers, saving a copy. There might be complications on the receiving + * side, however, where buffers may wrap and where the size of the received + * frame will typically be smaller than a full packet. + */ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER must not be set +#endif + +#define GMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ +#define GMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ + +/* The MAC can support frame lengths up to 1536 bytes */ + +#define GMAC_MAX_FRAMELEN 1536 +#if CONFIG_NET_ETH_MTU >GMAC_MAX_FRAMELEN +# error CONFIG_NET_ETH_MTU is too large +#endif + +/* We need at least one more free buffer than transmit buffers */ + +#define SAM_GMAC_NFREEBUFFERS (CONFIG_SAMA5_GMAC_NTXBUFFERS+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_GMAC_REGDEBUG +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define sam_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define SAM_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SAM_TXTIMEOUT (60*CLK_TCK) + +/* PHY read/write delays in loop counts */ + +#define PHY_RETRY_MAX 300000 + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the GMAC + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The sam_gmac_s encapsulates all state information for the GMAC peripheral */ + +struct sam_gmac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */ + uint16_t txhead; /* Circular buffer head index */ + uint16_t txtail; /* Circualr buffer tail index */ + uint16_t rxndx; /* RX index for current processing RX descriptor */ + + uint8_t *rxbuffer; /* Allocated RX buffers */ + uint8_t *txbuffer; /* Allocated TX buffers */ + struct gmac_rxdesc_s *rxdesc; /* Allocated RX descriptors */ + struct gmac_txdesc_s *txdesc; /* Allocated TX descriptors */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_GMAC_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The driver state singleton */ + +static struct sam_gmac_s g_gmac; + +#ifdef CONFIG_SAMA5_GMAC_PREALLOCATE +/* Preallocated data */ +/* TX descriptors list */ + +static struct gmac_txdesc_s g_txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS] + __attribute__((aligned(8))); + +/* RX descriptors list */ + +static struct gmac_rxdesc_s g_rxdesc[CONFIG_SAMA5_GMAC_NRXBUFFERS] + __attribute__((aligned(8))); + +/* Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_txbuffer[CONFIG_SAMA5_GMAC_NTXBUFFERS * GMAC_TX_UNITSIZE] + __attribute__((aligned(8))); + +/* Receive Buffers */ + +static uint8_t g_rxbuffer[CONFIG_SAMA5_GMAC_NRXBUFFERS * GMAC_RX_UNITSIZE] + __attribute__((aligned(8))); +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_GMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(struct sam_gmac_s *priv, bool wr, + uint32_t regval, uintptr_t address); +static uint32_t sam_getreg(struct sam_gmac_s *priv, uintptr_t addr); +static void sam_putreg(struct sam_gmac_s *priv, uintptr_t addr, uint32_t val); +#else +# define sam_getreg(priv,addr) getreg32(addr) +# define sam_putreg(priv,addr,val) putreg32(val,addr) +#endif + +/* Buffer management */ + +static uint16_t sam_txinuse(struct sam_gmac_s *priv); +static uint16_t sam_txfree(struct sam_gmac_s *priv); +static int sam_buffer_initialize(struct sam_gmac_s *priv); +static void sam_buffer_free(struct sam_gmac_s *priv); + +/* Common TX logic */ + +static int sam_transmit(struct sam_gmac_s *priv); +static int sam_txpoll(struct net_driver_s *dev); +static void sam_dopoll(struct sam_gmac_s *priv); + +/* Interrupt handling */ + +static int sam_recvframe(struct sam_gmac_s *priv); +static void sam_receive(struct sam_gmac_s *priv); +static void sam_txdone(struct sam_gmac_s *priv); +static int sam_gmac_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void sam_polltimer(int argc, uint32_t arg, ...); +static void sam_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int sam_ifup(struct net_driver_s *dev); +static int sam_ifdown(struct net_driver_s *dev); +static int sam_txavail(struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac); +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY Initialization */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_gmac_s *priv); +#else +# define sam_phydump(priv) +#endif + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_gmac_s *priv); +#endif +static void sam_enablemdio(struct sam_gmac_s *priv); +static void sam_disablemdio(struct sam_gmac_s *priv); +static int sam_phywait(struct sam_gmac_s *priv); +static int sam_phyreset(struct sam_gmac_s *priv); +static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr); +static int sam_phyread(struct sam_gmac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval); +static int sam_phywrite(struct sam_gmac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval); +#ifdef CONFIG_SAMA5_GMAC_AUTONEG +static int sam_autonegotiate(struct sam_gmac_s *priv); +#else +static void sam_linkspeed(struct sam_gmac_s *priv); +#endif +static void sam_mdcclock(struct sam_gmac_s *priv); +static int sam_phyinit(struct sam_gmac_s *priv); + +/* GMAC Initialization */ + +static void sam_txreset(struct sam_gmac_s *priv); +static void sam_rxreset(struct sam_gmac_s *priv); +static void sam_gmac_reset(struct sam_gmac_s *priv); +static void sam_macaddress(struct sam_gmac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_gmac_s *priv); +#endif +static int sam_gmac_configure(struct sam_gmac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC_REGDEBUG +static bool sam_checkreg(struct sam_gmac_s *priv, bool wr, uint32_t regval, + uintptr_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC_REGDEBUG +static uint32_t sam_getreg(struct sam_gmac_s *priv, uintptr_t address) +{ + uint32_t regval = getreg32(address); + + if (sam_checkreg(priv, false, regval, address)) + { + lldbg("%08x->%08x\n", address, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC_REGDEBUG +static void sam_putreg(struct sam_gmac_s *priv, uintptr_t address, + uint32_t regval) +{ + if (sam_checkreg(priv, true, regval, address)) + { + lldbg("%08x<-%08x\n", address, regval); + } + + putreg32(regval, address); +} +#endif + +/**************************************************************************** + * Function: sam_txinuse + * + * Description: + * Return the number of TX buffers in-use + * + * Input Parameters: + * priv - The GMAC driver state + * + * Returned Value: + * The number of TX buffers in-use + * + ****************************************************************************/ + +static uint16_t sam_txinuse(struct sam_gmac_s *priv) +{ + uint32_t txhead32 = (uint32_t)priv->txhead; + if ((uint32_t)priv->txtail > txhead32) + { + txhead32 += CONFIG_SAMA5_GMAC_NTXBUFFERS; + } + + return (uint16_t)(txhead32 - (uint32_t)priv->txtail); +} + +/**************************************************************************** + * Function: sam_txfree + * + * Description: + * Return the number of TX buffers available + * + * Input Parameters: + * priv - The GMAC driver state + * + * Returned Value: + * The number of TX buffers available + * + ****************************************************************************/ + +static uint16_t sam_txfree(struct sam_gmac_s *priv) +{ + /* The number available is equal to the total number of buffers, minus the + * number of buffers in use. Notice that that actual number of buffers is + * the configured size minus 1. + */ + + return (CONFIG_SAMA5_GMAC_NTXBUFFERS-1) - sam_txinuse(priv); +} + +/**************************************************************************** + * Function: sam_buffer_initialize + * + * Description: + * Allocate aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function degenerates to a few assignements. + * + * Input Parameters: + * priv - The GMAC driver state + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +static int sam_buffer_initialize(struct sam_gmac_s *priv) +{ +#ifdef CONFIG_SAMA5_GMAC_PREALLOCATE + /* Use pre-allocated buffers */ + + priv->txdesc = g_txdesc; + priv->rxdesc = g_rxdesc; + priv->txbuffer = g_txbuffer; + priv->rxbuffer = g_rxbuffer; + +#else + size_t allocsize; + + /* Allocate buffers */ + + allocsize = CONFIG_SAMA5_GMAC_NTXBUFFERS * sizeof(struct gmac_txdesc_s); + priv->txdesc = (struct gmac_txdesc_s *)kmm_memalign(8, allocsize); + if (!priv->txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->txdesc, 0, allocsize); + + allocsize = CONFIG_SAMA5_GMAC_NRXBUFFERS * sizeof(struct gmac_rxdesc_s); + priv->rxdesc = (struct gmac_rxdesc_s *)kmm_memalign(8, allocsize); + if (!priv->rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->rxdesc, 0, allocsize); + + allocsize = CONFIG_SAMA5_GMAC_NTXBUFFERS * GMAC_TX_UNITSIZE; + priv->txbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + allocsize = CONFIG_SAMA5_GMAC_NRXBUFFERS * GMAC_RX_UNITSIZE; + priv->rxbuffer = (uint8_t *)kmm_memalign(8, allocsize); + if (!priv->rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + +#endif + + DEBUGASSERT(((uintptr_t)priv->rxdesc & 7) == 0 && + ((uintptr_t)priv->rxbuffer & 7) == 0 && + ((uintptr_t)priv->txdesc & 7) == 0 && + ((uintptr_t)priv->txbuffer & 7) == 0); + return OK; +} + +/**************************************************************************** + * Function: sam_buffer_free + * + * Description: + * Free aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function does nothing. + * + * Input Parameters: + * priv - The GMAC driver state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_buffer_free(struct sam_gmac_s *priv) +{ +#ifndef CONFIG_SAMA5_GMAC_PREALLOCATE + /* Free allocated buffers */ + + if (priv->txdesc) + { + kmm_free(priv->txdesc); + priv->txdesc = NULL; + } + + if (priv->rxdesc) + { + kmm_free(priv->rxdesc); + priv->rxdesc = NULL; + } + + if (priv->txbuffer) + { + kmm_free(priv->txbuffer); + priv->txbuffer = NULL; + } + + if (priv->rxbuffer) + { + kmm_free(priv->rxbuffer); + priv->rxbuffer = NULL; + } +#endif +} + +/**************************************************************************** + * Function: sam_transmit + * + * Description: + * Start hardware transmission. Called either from the TX done interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_transmit(struct sam_gmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + volatile struct gmac_txdesc_s *txdesc; + uintptr_t virtaddr; + uint32_t regval; + uint32_t status; + + nllvdbg("d_len: %d txhead: %d txtail: %d\n", + dev->d_len, priv->txhead, priv->txtail); + sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len); + + /* Check parameter */ + + if (dev->d_len > GMAC_TX_UNITSIZE) + { + nlldbg("ERROR: Packet too big: %d\n", dev->d_len); + return -EINVAL; + } + + /* Pointer to the current TX descriptor */ + + txdesc = &priv->txdesc[priv->txhead]; + + /* If no free TX descriptor, buffer can't be sent */ + + if (sam_txfree(priv) < 1) + { + nlldbg("ERROR: No free TX descriptors\n"); + return -EBUSY; + } + + /* Setup/Copy data to transmition buffer */ + + if (dev->d_len > 0) + { + /* Driver managed the ring buffer */ + + virtaddr = sam_virtramaddr(txdesc->addr); + memcpy((void *)virtaddr, dev->d_buf, dev->d_len); + arch_clean_dcache((uint32_t)virtaddr, (uint32_t)virtaddr + dev->d_len); + } + + /* Update TX descriptor status. */ + + status = dev->d_len | GMACTXD_STA_LAST; + if (priv->txhead == CONFIG_SAMA5_GMAC_NTXBUFFERS-1) + { + status |= GMACTXD_STA_WRAP; + } + + /* Update the descriptor status and flush the updated value to RAM */ + + txdesc->status = status; + arch_clean_dcache((uint32_t)txdesc, + (uint32_t)txdesc + sizeof(struct gmac_txdesc_s)); + + /* Increment the head index */ + + if (++priv->txhead >= CONFIG_SAMA5_GMAC_NTXBUFFERS) + { + priv->txhead = 0; + } + + /* Now start transmission (if it is not already done) */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval |= GMAC_NCR_TSTART; + sam_putreg(priv, SAM_GMAC_NCR, regval); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SAM_TXTIMEOUT, sam_txtimeout, 1, + (uint32_t)priv); + + /* Set d_len to zero meaning that the d_buf[] packet buffer is again + * available. + */ + + dev->d_len = 0; + + /* If we have no more available TX descriptors, then we must disable the + * RCOMP interrupt to stop further RX processing. Why? Because EACH RX + * packet that is dispatched is also an opportunity to reply with a TX + * packet. So, if we cannot handle an RX packet reply, then we disable + * all RX packet processing. + */ + + if (sam_txfree(priv) < 1) + { + nllvdbg("Disabling RX interrupts\n"); + sam_putreg(priv, SAM_GMAC_IDR, GMAC_INT_RCOMP); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_txpoll(struct net_driver_s *dev) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + sam_transmit(priv); + + /* Check if the there are any free TX descriptors. We cannot perform + * the TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) == 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: sam_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail), and + * 3. After a TX timeout to restart the sending process (sam_txtimeout). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_dopoll(struct sam_gmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. */ + + (void)devif_poll(dev, sam_txpoll); + } +} + +/**************************************************************************** + * Function: sam_recvframe + * + * Description: + * The function is called when a frame is received. It scans the RX + * descriptors of the received frame and assembles the full packet/ + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * - Global interrupts are disabled by interrupt handling logic. + * - The RX descriptor D-cache list has been invalided to force fetching + * from RAM. + * + ****************************************************************************/ + +static int sam_recvframe(struct sam_gmac_s *priv) +{ + volatile struct gmac_rxdesc_s *rxdesc; + struct net_driver_s *dev; + const uint8_t *src; + uint8_t *dest; + uintptr_t physaddr; + uint32_t rxndx; + uint32_t pktlen; + uint16_t copylen; + bool isframe; + + /* Process received RX descriptor. The ownership bit is set by the GMAC + * once it has successfully written a frame to memory. + */ + + dev = &priv->dev; + dev->d_len = 0; + + dest = dev->d_buf; + pktlen = 0; + + rxndx = priv->rxndx; + rxdesc = &priv->rxdesc[rxndx]; + isframe = false; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct gmac_rxdesc_s)); + + nllvdbg("rxndx: %d\n", rxndx); + + while ((rxdesc->addr & GMACRXD_ADDR_OWNER) != 0) + { + /* The start of frame bit indicates the beginning of a frame. Discard + * any previous fragments. + */ + + if ((rxdesc->status & GMACRXD_STA_SOF) != 0) + { + /* Skip previous fragments */ + + while (rxndx != priv->rxndx) + { + /* Give ownership back to the GMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(GMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct gmac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_GMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Reset the packet data pointer and packet length */ + + dest = dev->d_buf; + pktlen = 0; + + /* Start to gather buffers into the packet buffer */ + + isframe = true; + } + + /* Increment the working index */ + + if (++rxndx >= CONFIG_SAMA5_GMAC_NRXBUFFERS) + { + rxndx = 0; + } + + /* Copy data into the packet buffer */ + + if (isframe) + { + if (rxndx == priv->rxndx) + { + nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n"); + do + { + /* Give ownership back to the GMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(GMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct gmac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_GMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + while (rxndx != priv->rxndx); + return -EIO; + } + + /* Get the number of bytes to copy from the buffer */ + + copylen = GMAC_RX_UNITSIZE; + if ((pktlen + copylen) > CONFIG_NET_ETH_MTU) + { + copylen = CONFIG_NET_ETH_MTU - pktlen; + } + + /* Get the data source. Invalidate the source memory region to + * force reload from RAM. + */ + + physaddr = (uintptr_t)(rxdesc->addr & GMACRXD_ADDR_MASK); + src = (const uint8_t *)sam_virtramaddr(physaddr); + + arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); + + /* And do the copy */ + + memcpy(dest, src, copylen); + dest += copylen; + pktlen += copylen; + + /* If the end of frame has been received, return the data */ + + if ((rxdesc->status & GMACRXD_STA_EOF) != 0) + { + /* Frame size from the GMAC */ + + dev->d_len = (rxdesc->status & GMACRXD_STA_FRLEN_MASK); + nllvdbg("packet %d-%d (%d)\n", priv->rxndx, rxndx, dev->d_len); + + /* All data have been copied in the application frame buffer, + * release the RX descriptor + */ + + while (priv->rxndx != rxndx) + { + /* Give ownership back to the GMAC */ + + rxdesc = &priv->rxdesc[priv->rxndx]; + rxdesc->addr &= ~(GMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct gmac_rxdesc_s)); + + /* Increment the RX index */ + + if (++priv->rxndx >= CONFIG_SAMA5_GMAC_NRXBUFFERS) + { + priv->rxndx = 0; + } + } + + /* Check if the device packet buffer was large enough to accept + * all of the data. + */ + + nllvdbg("rxndx: %d d_len: %d\n", priv->rxndx, dev->d_len); + + if (pktlen < dev->d_len) + { + nlldbg("ERROR: Buffer size %d; frame size %d\n", dev->d_len, pktlen); + return -E2BIG; + } + + return OK; + } + } + + /* We have not encount the SOF yet... discard this fragment and keep looking */ + + else + { + /* Give ownership back to the GMAC */ + + rxdesc->addr &= ~(GMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct gmac_rxdesc_s)); + + priv->rxndx = rxndx; + } + + /* Process the next buffer */ + + rxdesc = &priv->rxdesc[rxndx]; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct gmac_rxdesc_s)); + } + + /* No packet was found */ + + priv->rxndx = rxndx; + nllvdbg("rxndx: %d\n", priv->rxndx); + return -EAGAIN; +} + +/**************************************************************************** + * Function: sam_receive + * + * Description: + * An interrupt was received indicating the availability of onr or more + * new RX packets in FIFO memory. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_receive(struct sam_gmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while sam_recvframe() successfully retrieves valid + * GMAC frames. + */ + + while (sam_recvframe(priv) == OK) + { + sam_dumppacket("Received packet", dev->d_buf, dev->d_len); + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + sam_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + } +} + +/**************************************************************************** + * Function: sam_txdone + * + * Description: + * An interrupt was received indicating that one or more frames have + * completed transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txdone(struct sam_gmac_s *priv) +{ + struct gmac_txdesc_s *txdesc; + + /* Are there any outstanding transmissions? Loop until either (1) all of + * the TX descriptors have been examined, or (2) until we encounter the + * first descriptor that is still in use by the hardware. + */ + + while (priv->txhead != priv->txtail) + { + /* Yes.. check the next buffer at the tail of the list */ + + txdesc = &priv->txdesc[priv->txtail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct gmac_txdesc_s)); + + /* Is this TX descriptor still in use? */ + + if ((txdesc->status & GMACTXD_STA_USED) == 0) + { + /* Yes.. the descriptor is still in use. However, I have seen a + * case (only repeatable on start-up) where the USED bit is never + * set. Yikes! If we have encountered the first still busy + * descriptor, then we should also have TQBD equal to the descriptor + * address. If it is not, then treat is as used anyway. + */ + +#warning REVISIT + if (priv->txtail == 0 && + sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv, SAM_GMAC_TBQB)) + { + txdesc->status = (uint32_t)GMACTXD_STA_USED; + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct gmac_txdesc_s)); + } + else + { + /* Otherwise, the descriptor is truly in use. Break out of the + * loop now. + */ + + break; + } + } + + /* Increment the tail index */ + + if (++priv->txtail >= CONFIG_SAMA5_GMAC_NTXBUFFERS) + { + /* Wrap to the beginning of the TX descriptor list */ + + priv->txtail = 0; + } + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_GMAC_IER, GMAC_INT_RCOMP); + } + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_gmac_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_gmac_interrupt(int irq, void *context) +{ + struct sam_gmac_s *priv = &g_gmac; + uint32_t isr; + uint32_t rsr; + uint32_t tsr; + uint32_t imr; + uint32_t regval; + uint32_t pending; + uint32_t clrbits; + + isr = sam_getreg(priv, SAM_GMAC_ISR); + rsr = sam_getreg(priv, SAM_GMAC_RSR); + tsr = sam_getreg(priv, SAM_GMAC_TSR); + imr = sam_getreg(priv, SAM_GMAC_IMR); + + pending = isr & ~(imr | GMAC_INT_UNUSED); + nllvdbg("isr: %08x pending: %08x\n", isr, pending); + + /* Check for the completion of a transmission. This should be done before + * checking for received data (because receiving can cause another transmission + * before we had a chance to handle the last one). + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read. + * TSR:COMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + if ((pending & GMAC_INT_TCOMP) != 0 || (tsr & GMAC_TSR_TXCOMP) != 0) + { + /* A frame has been transmitted */ + + clrbits = GMAC_TSR_TXCOMP; + + /* Check for Retry Limit Exceeded (RLE) */ + + if ((tsr & GMAC_TSR_RLE) != 0) + { + /* Status RLE & Number of discarded buffers */ + + clrbits = GMAC_TSR_RLE | sam_txinuse(priv); + sam_txreset(priv); + + nlldbg("ERROR: Retry Limit Exceeded TSR: %08x\n", tsr); + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval |= GMAC_NCR_TXEN; + sam_putreg(priv, SAM_GMAC_NCR, regval); + } + + /* Check Collision Occurred (COL) */ + + if ((tsr & GMAC_TSR_COL) != 0) + { + nlldbg("ERROR: Collision occurred TSR: %08x\n", tsr); + clrbits |= GMAC_TSR_COL; + } + + /* Check for Transmit Frame Corruption due to AHB error (TFC) */ + + if ((tsr & GMAC_TSR_TFC) != 0) + { + nlldbg("ERROR: Buffers exhausted mid-frame TSR: %08x\n", tsr); + clrbits |= GMAC_TSR_TFC; + } + + /* Check for Transmit Underrun (UND) + * + * ISR:UND is set transmit DMA was not able to read data from memory, + * either because the bus was not granted in time, because a not + * OK hresp(bus error) was returned or because a used bit was read + * midway through frame transmission. If this occurs, the + * transmitter forces bad CRC. Cleared by writing a one to this bit. + */ + + if ((tsr & GMAC_TSR_UND) != 0) + { + nlldbg("ERROR: Transmit Underrun TSR: %08x\n", tsr); + clrbits |= GMAC_TSR_UND; + } + + /* Check for HRESP not OK */ + + if ((tsr & GMAC_TSR_HRESP) != 0) + { + nlldbg("ERROR: HRESP not OK: %08x\n", tsr); + clrbits |= GMAC_TSR_HRESP; + } + + /* Check for Late Collitions (LCO) */ + + if ((tsr & GMAC_TSR_LCO) != 0) + { + nlldbg("ERROR: Late collision: %08x\n", tsr); + clrbits |= GMAC_TSR_LCO; + } + + /* Clear status */ + + sam_putreg(priv, SAM_GMAC_TSR, clrbits); + + /* And handle the TX done event */ + + sam_txdone(priv); + } + + /* Check for the receipt of an RX packet. + * + * RXCOMP indicates that a packet has been received and stored in memory. + * The RXCOMP bit is cleared whent he interrupt status register was read. + * RSR:REC indicates that one or more frames have been received and placed + * in memory. This indication is cleared by writing a one to this bit. + */ + + if ((pending & GMAC_INT_RCOMP) != 0 || (rsr & GMAC_RSR_REC) != 0) + { + clrbits = GMAC_RSR_REC; + + /* Check for Receive Overrun. + * + * RSR:RXOVR will be set if the RX FIFO is not able to store the + * receive frame due to a FIFO overflow, or if the receive status + * was not taken at the end of the frame. This bit is also set in + * DMA packet buffer mode if the packet buffer overflows. For DMA + * operation, the buffer will be recovered if an overrun occurs. This + * bit is cleared when set to 1. + */ + + if ((rsr & GMAC_RSR_RXOVR) != 0) + { + nlldbg("ERROR: Receiver overrun RSR: %08x\n", rsr); + clrbits |= GMAC_RSR_RXOVR; + } + + /* Check for buffer not available (BNA) + * + * RSR:BNA means that an attempt was made to get a new buffer and the + * pointer indicated that it was owned by the processor. The DMA will + * reread the pointer each time an end of frame is received until a + * valid pointer is found. This bit is set following each descriptor + * read attempt that fails, even if consecutive pointers are + * unsuccessful and software has in the mean time cleared the status + * flag. Cleared by writing a one to this bit. + */ + + if ((rsr & GMAC_RSR_BNA) != 0) + { + nlldbg("ERROR: Buffer not available RSR: %08x\n", rsr); + clrbits |= GMAC_RSR_BNA; + } + + /* Check for HRESP not OK (HNO) */ + + if ((rsr & GMAC_RSR_HNO) != 0) + { + nlldbg("ERROR: HRESP not OK: %08x\n", rsr); + clrbits |= GMAC_RSR_HNO; + } + + /* Clear status */ + + sam_putreg(priv, SAM_GMAC_RSR, clrbits); + + /* Handle the received packet */ + + sam_receive(priv); + } + +#ifdef CONFIG_DEBUG_NET + /* Check for PAUSE Frame recieved (PFRE). + * + * ISR:PFRE indicates that a pause frame has been received. Cleared on a read. + */ + + if ((pending & GMAC_INT_PFNZ) != 0) + { + nlldbg("Pause frame received\n"); + } + + /* Check for Pause Time Zero (PTZ) + * + * ISR:PTZ is set Pause Time Zero + */ + + if ((pending & GMAC_INT_PTZ) != 0) + { + nlldbg("Pause TO!\n"); + } +#endif + + return OK; +} + +/**************************************************************************** + * Function: sam_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txtimeout(int argc, uint32_t arg, ...) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)arg; + + nlldbg("Timeout!\n"); + + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + sam_ifdown(&priv->dev); + sam_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + sam_dopoll(priv); +} + +/**************************************************************************** + * Function: sam_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_polltimer(int argc, uint32_t arg, ...) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)arg; + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv) > 0) + { + /* Update TCP timing states and poll uIP for new XMIT data. */ + + (void)devif_timer(dev, sam_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: sam_ifup + * + * Description: + * NuttX Callback: Bring up the GMAC interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifup(struct net_driver_s *dev) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + int ret; + + nlldbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Configure the GMAC interface for normal operation. */ + + nllvdbg("Initialize the GMAC\n"); + sam_gmac_configure(priv); + + /* Set the MAC address (should have been configured while we were down) */ + + sam_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + sam_ipv6multicast(priv); +#endif + + /* Initialize for PHY access */ + + ret = sam_phyinit(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phyinit failed: %d\n", ret); + return ret; + } + +#ifdef CONFIG_SAMA5_GMAC_AUTONEG + /* Auto Negotiate, working in RMII mode */ + + ret = sam_autonegotiate(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_autonegotiate failed: %d\n", ret); + return ret; + } +#else + /* Just force the configured link speed */ + + sam_linkspeed(priv); +#endif + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_polltimer, 1, (uint32_t)priv); + + /* Enable the GMAC interrupt */ + + priv->ifup = true; + up_enable_irq(SAM_IRQ_GMAC); + return OK; +} + +/**************************************************************************** + * Function: sam_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifdown(struct net_driver_s *dev) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + irqstate_t flags; + + nlldbg("Taking the network down\n"); + + /* Disable the GMAC interrupt */ + + flags = enter_critical_section(); + up_disable_irq(SAM_IRQ_GMAC); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the GMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the sam_ifup() always + * successfully brings the interface back up. + */ + + sam_gmac_reset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: sam_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int sam_txavail(struct net_driver_s *dev) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + irqstate_t flags; + + nllvdbg("ifup: %d\n", priv->ifup); + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + sam_dopoll(priv); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_hashindx + * + * Description: + * Cacuclate the hash address register index. The hash address register + * is 64 bits long and takes up two locations in the memory map. The + * destination address is reduced to a 6-bit index into the 64-bit Hash + * Register using the following hash function: The hash function is an XOR + * of every sixth bit of the destination address. + * + * ndx:05 = da:05 ^ da:11 ^ da:17 ^ da:23 ^ da:29 ^ da:35 ^ da:41 ^ da:47 + * ndx:04 = da:04 ^ da:10 ^ da:16 ^ da:22 ^ da:28 ^ da:34 ^ da:40 ^ da:46 + * ndx:03 = da:03 ^ da:09 ^ da:15 ^ da:21 ^ da:27 ^ da:33 ^ da:39 ^ da:45 + * ndx:02 = da:02 ^ da:08 ^ da:14 ^ da:20 ^ da:26 ^ da:32 ^ da:38 ^ da:44 + * ndx:01 = da:01 ^ da:07 ^ da:13 ^ da:19 ^ da:25 ^ da:31 ^ da:37 ^ da:43 + * ndx:00 = da:00 ^ da:06 ^ da:12 ^ da:18 ^ da:24 ^ da:30 ^ da:36 ^ da:42 + * + * Where da:00 represents the least significant bit of the first byte + * received and da:47 represents the most significant bit of the last byte + * received. + * + * Input Parameters: + * mac - The multicast address to be hashed + * + * Returned Value: + * The 6-bit hash table index + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac) +{ + unsigned int ndx; + + /* Isolate: mac[0] + * ... 05 04 03 02 01 00] */ + + ndx = mac[0]; + + /* Isolate: mac[1] mac[0] + * ...11 10 09 08] [07 06 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + */ + + ndx ^= (mac[1] << 2) | (mac[0] >> 6); + + /* Isolate: mac[2] mac[1] + * ... 17 16] [15 14 13 12 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + */ + + ndx ^= (mac[2] << 4) | (mac[1] >> 4); + + /* Isolate: mac[2] + * [23 22 21 20 19 18 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + */ + + ndx ^= (mac[2] >> 2); + + /* Isolate: mac[3] + * ... 29 28 27 26 25 24] + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + */ + + ndx ^= mac[3]; + + /* Isolate: mac[4] mac[3] + * ... 35 34 33 32] [31 30 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + */ + + ndx ^= (mac[4] << 2) | (mac[3] >> 6); + + /* Isolate: mac[5] mac[4] + * ... 41 40] [39 38 37 36 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + */ + + ndx ^= (mac[5] << 4) | (mac[4] >> 4); + + /* Isolate: mac[5] + * [47 46 45 44 43 42 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + * XOR: 47 46 45 44 43 42 + */ + + ndx ^= (mac[5] >> 2); + + /* Mask out the garbage bits and return the 6-bit index */ + + return ndx & 0x3f; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + uintptr_t regaddr; + uint32_t regval; + unsigned int ndx; + unsigned int bit; + UNUSED(priv); + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Add the multicast address to the hardware multicast hash table */ + + if (ndx >= 32) + { + regaddr = SAM_GMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr = SAM_GMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr); + regval |= bit; + sam_putreg(priv, regaddr, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + regval = sam_getreg(priv, SAM_GMAC_NCFGR); + regval &= ~GMAC_NCFGR_UNIHEN; /* Disable unicast matching */ + regval |= GMAC_NCFGR_MTIHEN; /* Enable multicast matching */ + sam_putreg(priv, SAM_GMAC_NCFGR, regval); + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + uint32_t regval; + unsigned int regaddr1; + unsigned int regaddr2; + unsigned int ndx; + unsigned int bit; + UNUSED(priv); + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Remove the multicast address to the hardware multicast hast table */ + + if (ndx >= 32) + { + regaddr1 = SAM_GMAC_HRT; /* Hash Register Top [63:32] Register */ + regaddr2 = SAM_GMAC_HRB; /* Hash Register Bottom [31:0] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regaddr1 = SAM_GMAC_HRB; /* Hash Register Bottom [31:0] Register */ + regaddr2 = SAM_GMAC_HRT; /* Hash Register Top [63:32] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regaddr1); + regval &= ~bit; + sam_putreg(priv, regaddr1, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + /* Are all multicast address matches disabled? */ + + if (regval == 0 && sam_getreg(priv, regaddr2) == 0) + { + /* Yes.. disable all address matching */ + + regval = sam_getreg(priv, SAM_GMAC_NCFGR); + regval &= ~(GMAC_NCFGR_UNIHEN | GMAC_NCFGR_MTIHEN); + sam_putreg(priv, SAM_GMAC_NCFGR, regval); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_ioctl + * + * Description: + * Handles driver ioctl calls: + * + * SIOCMIINOTIFY - Set up to received notifications from PHY interrupting + * events. + * + * SIOCGMIIPHY, SIOCGMIIREG, and SIOCSMIIREG: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + struct sam_gmac_s *priv = (struct sam_gmac_s *)dev->d_private; + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = sam_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = priv->phyaddr; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + + /* Enable the management port */ + + sam_enablemdio(priv); + + /* Read from the requested register */ + + ret = sam_phyread(priv, req->phy_id, req->reg_num, &req->val_out); + + /* Disable the management port */ + + sam_disablemdio(priv); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + + /* Enable the management port */ + + sam_enablemdio(priv); + + /* Write to the requested register */ + + ret = sam_phywrite(priv, req->phy_id, req->reg_num, req->val_in); + + /* Disable the management port */ + + sam_disablemdio(priv); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: sam_phydump + * + * Description: + * Dump the contents of PHY registers + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_gmac_s *priv) +{ + uint16_t phyval; + + /* Enable management port */ + + sam_enablemdio(priv); + + nllvdbg("GMII Registers (Address %02x)\n", priv->phyaddr); + sam_phyread(priv, priv->phyaddr, GMII_MCR, &phyval); + nllvdbg(" MCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_MSR, &phyval); + nllvdbg(" MSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_ADVERTISE, &phyval); + nllvdbg(" ADVERTISE: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_LPA, &phyval); + nllvdbg(" LPR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_1000BTCR, &phyval); + nllvdbg(" 1000BTCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_1000BTSR, &phyval); + nllvdbg(" 1000BTSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, GMII_ESTATUS, &phyval); + nllvdbg(" ESTATUS: %04x\n", phyval); + + /* Disable management port */ + + sam_disablemdio(priv); +} +#endif + +/**************************************************************************** + * Function: sam_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_gmac_s *priv) +{ +#if defined(SAMA5_GMAC_PHY_KSZ90x1) + uint16_t phyval; + int ret; + + /* Enable the management port */ + + sam_enablemdio(priv); + + /* Read the interrupt status register in order to clear any pending + * interrupts + */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_KSZ90x1_ICS, &phyval); + if (ret == OK) + { + /* Enable link up/down interrupts */ + + ret = sam_phywrite(priv, priv->phyaddr, GMII_KSZ90x1_ICS, + (GMII_KSZ90x1_INT_LDEN | GMII_KSZ90x1_INT_LUEN)); + } + + /* Disable the management port */ + + sam_disablemdio(priv); + return ret; + +#else +# warning Missing logic + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Function: sam_enablemdio + * + * Description: + * Enable the management port + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_enablemdio(struct sam_gmac_s *priv) +{ + uint32_t regval; + uint32_t enables; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + enables = regval & (GMAC_NCR_RXEN | GMAC_NCR_TXEN); + + regval &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN); + regval |= GMAC_NCR_MPE; + sam_putreg(priv, SAM_GMAC_NCR, regval); + + regval |= enables; + sam_putreg(priv, SAM_GMAC_NCR, regval); +} + +/**************************************************************************** + * Function: sam_disablemdio + * + * Description: + * Disable the management port + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablemdio(struct sam_gmac_s *priv) +{ + uint32_t regval; + uint32_t enables; + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + enables = regval & (GMAC_NCR_RXEN | GMAC_NCR_TXEN); + + regval &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN); + sam_putreg(priv, SAM_GMAC_NCR, regval); + + regval &= ~GMAC_NCR_MPE; + sam_putreg(priv, SAM_GMAC_NCR, regval); + + regval |= enables; + sam_putreg(priv, SAM_GMAC_NCR, regval); +} + +/**************************************************************************** + * Function: sam_phywait + * + * Description: + * Wait for the PHY to become IDLE + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +static int sam_phywait(struct sam_gmac_s *priv) +{ + volatile unsigned int retries; + + /* Loop for the configured number of attempts */ + + for (retries = 0; retries < PHY_RETRY_MAX; retries++) + { + /* Is the PHY IDLE */ + + if ((sam_getreg(priv, SAM_GMAC_NSR) & GMAC_NSR_IDLE) != 0) + { + return OK; + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: sam_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyreset(struct sam_gmac_s *priv) +{ + uint16_t mcr; + int timeout; + int ret; + + nllvdbg(" sam_phyreset\n"); + + /* Enable management port */ + + sam_enablemdio(priv); + + /* Reset the PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, GMII_MCR_RESET); + if (ret < 0) + { + nlldbg("ERROR: sam_phywrite failed: %d\n", ret); + } + + /* Wait for the PHY reset to complete */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < 10; timeout++) + { + mcr = GMII_MCR_RESET; + int result = sam_phyread(priv, priv->phyaddr, GMII_MCR, &mcr); + if (result < 0) + { + nlldbg("ERROR: Failed to read the MCR register: %d\n", ret); + ret = result; + } + else if ((mcr & GMII_MCR_RESET) == 0) + { + ret = OK; + break; + } + } + + /* Disable management port */ + + sam_disablemdio(priv); + return ret; +} + +/**************************************************************************** + * Function: sam_phyfind + * + * Description: + * Verify the PHY address and, if it is bad, try to one that works. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr) +{ + uint16_t phyval; + uint8_t candidate; + unsigned int offset; + int ret = -ESRCH; + + nllvdbg("Find a valid PHY address\n"); + + /* Enable management port */ + + sam_enablemdio(priv); + + /* Check initial candidate address */ + + candidate = *phyaddr; + + ret = sam_phyread(priv, candidate, GMII_PHYID1, &phyval); + if (ret == OK && phyval == GMII_OUI_MSB) + { + *phyaddr = candidate; + ret = OK; + } + + /* The current address does not work... try another */ + + else + { + nlldbg("ERROR: sam_phyread failed for PHY address %02x: %d\n", + candidate, ret); + + for (offset = 0; offset < 32; offset++) + { + /* Get the next candidate PHY address */ + + candidate = (candidate + 1) & 0x1f; + + /* Try reading the PHY ID from the candidate PHY address */ + + ret = sam_phyread(priv, candidate, GMII_PHYID1, &phyval); + if (ret == OK && phyval == GMII_OUI_MSB) + { + ret = OK; + break; + } + } + } + + if (ret == OK) + { + nllvdbg(" PHYID1: %04x PHY addr: %d\n", phyval, candidate); + *phyaddr = candidate; + } + + /* Disable management port */ + + sam_disablemdio(priv); + return ret; +} + +/**************************************************************************** + * Function: sam_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyread(struct sam_gmac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = GMAC_MAN_DATA(0) | GMAC_MAN_WTN | GMAC_MAN_REGA(regaddr) | + GMAC_MAN_PHYA(phyaddr) | GMAC_MAN_READ | GMAC_MAN_CLTTO; + sam_putreg(priv, SAM_GMAC_MAN, regval); + + /* Wait until the PHY is again idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Return the PHY data */ + + *phyval = (uint16_t)(sam_getreg(priv, SAM_GMAC_MAN) & GMAC_MAN_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: sam_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The 16-bit value to write to the PHY register. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phywrite(struct sam_gmac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = GMAC_MAN_DATA(phyval) | GMAC_MAN_WTN | GMAC_MAN_REGA(regaddr) | + GMAC_MAN_PHYA(phyaddr) | GMAC_MAN_WRITE | GMAC_MAN_CLTTO; + sam_putreg(priv, SAM_GMAC_MAN, regval); + + /* Wait until the PHY is again IDLE */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Function: sam_autonegotiate + * + * Description: + * Autonegotiate speed and duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_GMAC_AUTONEG +static int sam_autonegotiate(struct sam_gmac_s *priv) +{ + uint32_t regval; + uint32_t ncr; + uint32_t linkmode; + uint16_t phyval; + uint16_t phyid1; + uint16_t phyid2; + uint16_t advertise; + uint16_t lpa; + uint16_t btcr; + uint16_t btsr; + int timeout; + int ret; + + /* Enable management port */ + + sam_enablemdio(priv); + + /* Read the MS bits of the OUI from Pthe PHYID1 register */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_PHYID1, &phyid1); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID1 register\n"); + goto errout; + } + + nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr); + + /* Read the LS bits of the OUI from Pthe PHYID2 register */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_PHYID2, &phyid2); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID2 register\n"); + goto errout; + } + + nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr); + + if (phyid1 == GMII_OUI_MSB && + (phyid2 & GMII_PHYID2_OUI_MASK) == GMII_OUI_LSB) + { + nllvdbg(" Vendor Model Number: %04x\n", + (phyid2 & GMII_PHYID2_MODEL_MASK) >> GMII_PHYID2_MODEL_SHIFT); + nllvdbg(" Model Revision Number: %04x\n", + (phyid2 & GMII_PHYID2_REV_MASK) >> GMII_PHYID2_REV_SHIFT); + } + else + { + nlldbg("ERROR: PHY not recognized: PHYID1=%04x PHYID2=%04x\n", + phyid1, phyid2); + } + +#ifdef SAMA5_GMAC_PHY_KSZ90x1 + /* Set up the KSZ9020/31 PHY */ + + phyval = GMII_KSZ90x1_RCCPSR | GMII_ERCR_WRITE; + sam_phywrite(priv, priv->phyaddr, GMII_ERCR, phyval); + sam_phywrite(priv, priv->phyaddr, GMII_ERDWR, 0xf2f4); + + phyval = GMII_KSZ90x1_RRDPSR | GMII_ERCR_WRITE; + sam_phywrite(priv, priv->phyaddr, GMII_ERCR, phyval); + sam_phywrite(priv, priv->phyaddr, GMII_ERDWR, 0x2222); + + ret = sam_phywrite(priv, priv->phyaddr, GMII_KSZ90x1_ICS, 0xff00); +#endif + + /* Set the Auto_negotiation Advertisement Register, MII advertising for + * Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 + */ + + advertise = GMII_ADVERTISE_100BASETXFULL | GMII_ADVERTISE_100BASETXHALF | + GMII_ADVERTISE_10BASETXFULL | GMII_ADVERTISE_10BASETXHALF | + GMII_ADVERTISE_8023; + + ret = sam_phywrite(priv, priv->phyaddr, GMII_ADVERTISE, advertise); + if (ret < 0) + { + nlldbg("ERROR: Failed to write ADVERTISE register\n"); + goto errout; + } + + /* Modify the 1000Base-T control register to advertise 1000Base-T full + * and half duplex support. + */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_1000BTCR, &btcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read 1000BTCR register: %d\n", ret); + goto errout; + } + + btcr |= GMII_1000BTCR_1000BASETFULL | GMII_1000BTCR_1000BASETHALF; + + ret = sam_phywrite(priv, priv->phyaddr, GMII_1000BTCR, btcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write 1000BTCR register: %d\n", ret); + goto errout; + } + + /* Restart Auto_negotiation */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_MCR, &phyval); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR register: %d\n", ret); + goto errout; + } + + phyval |= GMII_MCR_ANRESTART; + + ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, phyval); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR register: %d\n", ret); + goto errout; + } + + nllvdbg(" MCR: 0x%X\n", phyval); + + /* Wait for autonegotion to complete */ + + timeout = 0; + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, GMII_MSR, &phyval); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR register: %d\n", ret); + goto errout; + } + + /* Check for completion of autonegotiation */ + + if ((phyval & GMII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. break out of the loop */ + + nllvdbg("AutoNegotiate complete\n"); + break; + } + + /* No.. check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Setup the GMAC local link speed */ + + linkmode = 0; /* 10Base-T Half-Duplex */ + timeout = 0; + + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, GMII_1000BTSR, &btsr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read 1000BTSR register: %d\n", ret); + goto errout; + } + + /* Setup the GMAC link speed */ + + if ((btsr & GMII_1000BTSR_LP1000BASETFULL) != 0 && + (btcr & GMII_1000BTCR_1000BASETHALF) != 0) + { + /* Set RGMII for 1000BaseTX and Full Duplex */ + + linkmode = (GMAC_NCFGR_FD | GMAC_NCFGR_GBE); + break; + } + else if ((btsr & GMII_1000BTSR_LP1000BASETHALF) != 0 && + (btcr & GMII_1000BTCR_1000BASETFULL) != 0) + { + /* Set RGMII for 1000BaseT and Half Duplex */ + + linkmode = GMAC_NCFGR_GBE; + break; + } + + /* Get the Autonegotiation Link partner base page */ + + ret = sam_phyread(priv, priv->phyaddr, GMII_LPA, &lpa); + if (ret < 0) + { + nlldbg("ERROR: Failed to read LPA register: %d\n", ret); + goto errout; + } + + /* Setup the GMAC link speed */ + + if ((advertise & GMII_ADVERTISE_100BASETXFULL) != 0 && + (lpa & GMII_LPA_100BASETXFULL) != 0) + { + /* Set RGMII for 100BaseTX and Full Duplex */ + + linkmode = (GMAC_NCFGR_SPD | GMAC_NCFGR_FD); + break; + } + else if ((advertise & GMII_ADVERTISE_10BASETXFULL) != 0 && + (lpa & GMII_LPA_10BASETXFULL) != 0) + { + /* Set RGMII for 10BaseT and Full Duplex */ + + linkmode = GMAC_NCFGR_FD; + break; + } + else if ((advertise & GMII_ADVERTISE_100BASETXHALF) != 0 && + (lpa & GMII_LPA_100BASETXHALF) != 0) + { + /* Set RGMII for 100BaseTX and half Duplex */ + + linkmode = GMAC_NCFGR_SPD; + break; + } + else if ((advertise & GMII_ADVERTISE_10BASETXHALF) != 0 && + (lpa & GMII_LPA_10BASETXHALF) != 0) + { + /* Set RGMII for 10BaseT and half Duplex */ + + break; + } + + /* Check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Disable RX and TX momentarily */ + + ncr = sam_getreg(priv, SAM_GMAC_NCR); + sam_putreg(priv, SAM_GMAC_NCR, ncr & ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN)); + + /* Modify the NCFGR register based on the negotiated speed and duplex */ + + regval = sam_getreg(priv, SAM_GMAC_NCFGR); + regval &= ~(GMAC_NCFGR_SPD | GMAC_NCFGR_FD | GMAC_NCFGR_GBE); + regval |= linkmode; + sam_putreg(priv, SAM_GMAC_NCFGR, regval); + sam_putreg(priv, SAM_GMAC_NCR, ncr); + + /* Enable RGMII enable */ + + regval = sam_getreg(priv, SAM_GMAC_UR); + regval |= GMAC_UR_RGMII; + sam_putreg(priv, SAM_GMAC_UR, regval); + +errout: + /* Disable the management port */ + + sam_disablemdio(priv); + return ret; +} +#endif + +/**************************************************************************** + * Function: sam_linkspeed + * + * Description: + * If autonegotiation is not configured, then just force the configuration + * mode + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_GMAC_AUTONEG +statoc void sam_linkspeed(struct sam_gmac_s *priv) +{ + uint32_t regval; + uint32_t ncr; + + /* Disable RX and TX momentarily */ + + ncr = sam_getreg(priv, SAM_GMAC_NCR); + sam_putreg(priv, SAM_GMAC_NCR, ncr & ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN)); + + /* Modify the NCFGR register based on the configured speed and duplex */ + + regval = sam_getreg(priv, SAM_GMAC_NCFGR); + regval &= ~(GMAC_NCFGR_SPD | GMAC_NCFGR_FD | GMAC_NCFGR_GBE); + +#ifdef SAMA5_GMAC_ETHFD + regval |= GMAC_NCFGR_FD; +#endif + +#if defined(SAMA5_GMAC_ETH100MBPS) + regval |= GMAC_NCFGR_SPD; +#elif defined(SAMA5_GMAC_ETH1000MBPS) */ + regval |= GMAC_NCFGR_GBE; +#endif + + sam_puttreg(priv, SAM_GMAC_NCFGR, regval); + sam_putreg(priv, SAM_GMAC_NCR, ncr); +} +#endif + +/**************************************************************************** + * Function: sam_mdcclock + * + * Description: + * Configure the MDC clocking + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_mdcclock(struct sam_gmac_s *priv) +{ + uint32_t ncfgr; + uint32_t ncr; + uint32_t mck; + + /* Disable RX and TX momentarily */ + + ncr = sam_getreg(priv, SAM_GMAC_NCR); + sam_putreg(priv, SAM_GMAC_NCR, ncr & ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN)); + + /* Modify the NCFGR register based on the configured board MCK frequency */ + + ncfgr = sam_getreg(priv, SAM_GMAC_NCFGR); + ncfgr &= ~GMAC_NCFGR_CLK_MASK; + + mck = BOARD_MCK_FREQUENCY; + DEBUGASSERT(mck <= 240000000); + + if (mck <= 20000000) + { + ncfgr |= GMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */ + } + else if (mck <= 40000000) + { + ncfgr |= GMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */ + } + else if (mck <= 80000000) + { + ncfgr |= GMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */ + } + else if (mck <= 120000000) + { + ncfgr |= GMAC_NCFGR_CLK_DIV48; /* MCK divided by 48 (MCK up to 120 MHz) */ + } + else if (mck <= 160000000) + { + ncfgr |= GMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */ + } + else /* if (mck <= 240000000) */ + { + ncfgr |= GMAC_NCFGR_CLK_DIV96; /* MCK divided by 64 (MCK up to 240 MHz) */ + } + + sam_putreg(priv, SAM_GMAC_NCFGR, ncfgr); + + /* Restore RX and TX enable settings */ + + sam_putreg(priv, SAM_GMAC_NCR, ncr); +} + +/**************************************************************************** + * Function: sam_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_phyinit(struct sam_gmac_s *priv) +{ + int ret; + + /* Configure PHY clocking */ + + sam_mdcclock(priv); + + /* Check the PHY Address */ + + priv->phyaddr = CONFIG_SAMA5_GMAC_PHYADDR; + ret = sam_phyfind(priv, &priv->phyaddr); + if (ret < 0) + { + nlldbg("ERROR: sam_phyfind failed: %d\n", ret); + return ret; + } + + /* We have a PHY address. Reset the PHY */ + + sam_phyreset(priv); + return OK; +} + +/**************************************************************************** + * Function: sam_ethgpioconfig + * + * Description: + * Configure GPIOs for the GMAC interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_ethgpioconfig(struct sam_gmac_s *priv) +{ + /* Configure PIO pins to support GMAC in RGMII mode */ + + sam_configpio(PIO_GMAC_TX0); + sam_configpio(PIO_GMAC_TX1); + sam_configpio(PIO_GMAC_TX2); + sam_configpio(PIO_GMAC_TX3); + + sam_configpio(PIO_GMAC_RX0); + sam_configpio(PIO_GMAC_RX1); + sam_configpio(PIO_GMAC_RX2); + sam_configpio(PIO_GMAC_RX3); + + sam_configpio(PIO_GMAC_TXCK); + sam_configpio(PIO_GMAC_TXEN); + sam_configpio(PIO_GMAC_RXCK); + sam_configpio(PIO_GMAC_RXDV); + sam_configpio(PIO_GMAC_RXER); + + sam_configpio(PIO_GMAC_MDC); + sam_configpio(PIO_GMAC_MDIO); + sam_configpio(PIO_GMAC_125CK); +} + +/**************************************************************************** + * Function: sam_txreset + * + * Description: + * Reset the transmit logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_txreset(struct sam_gmac_s *priv) +{ + uint8_t *txbuffer = priv->txbuffer; + struct gmac_txdesc_s *txdesc = priv->txdesc; + uintptr_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable TX */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval &= ~GMAC_NCR_TXEN; + sam_putreg(priv, SAM_GMAC_NCR, regval); + + /* Configure the TX descriptors. */ + + priv->txhead = 0; + priv->txtail = 0; + + for (ndx = 0; ndx < CONFIG_SAMA5_GMAC_NTXBUFFERS; ndx++) + { + bufaddr = (uintptr_t)(&(txbuffer[ndx * GMAC_TX_UNITSIZE])); + + /* Set the buffer address and mark the descriptor as in used by + * firmware. + */ + + physaddr = sam_physramaddr(bufaddr); + txdesc[ndx].addr = physaddr; + txdesc[ndx].status = (uint32_t)GMACTXD_STA_USED; + } + + /* Mark the final descriptor in the list */ + + txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS - 1].status = GMACTXD_STA_USED | GMACTXD_STA_WRAP; + + /* Flush the entire TX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + + CONFIG_SAMA5_GMAC_NTXBUFFERS * sizeof(struct gmac_txdesc_s)); + + /* Set the Transmit Buffer Queue Base Register */ + + physaddr = sam_physramaddr((uintptr_t)txdesc); + sam_putreg(priv, SAM_GMAC_TBQB, physaddr); +} + +/**************************************************************************** + * Function: sam_rxreset + * + * Description: + * Reset the receive logic + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_rxreset(struct sam_gmac_s *priv) +{ + struct gmac_rxdesc_s *rxdesc = priv->rxdesc; + uint8_t *rxbuffer = priv->rxbuffer; + uintptr_t bufaddr; + uint32_t physaddr; + uint32_t regval; + int ndx; + + /* Disable RX */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval &= ~GMAC_NCR_RXEN; + sam_putreg(priv, SAM_GMAC_NCR, regval); + + /* Configure the RX descriptors. */ + + priv->rxndx = 0; + for (ndx = 0; ndx < CONFIG_SAMA5_GMAC_NRXBUFFERS; ndx++) + { + bufaddr = (uintptr_t)(&(rxbuffer[ndx * GMAC_RX_UNITSIZE])); + DEBUGASSERT((bufaddr & ~GMACRXD_ADDR_MASK) == 0); + + /* Set the buffer address and remove GMACRXD_ADDR_OWNER and + * GMACRXD_ADDR_WRAP. + */ + + physaddr = sam_physramaddr(bufaddr); + rxdesc[ndx].addr = physaddr; + rxdesc[ndx].status = 0; + } + + /* Mark the final descriptor in the list */ + + rxdesc[CONFIG_SAMA5_GMAC_NRXBUFFERS - 1].addr |= GMACRXD_ADDR_WRAP; + + /* Flush the entire RX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + CONFIG_SAMA5_GMAC_NRXBUFFERS * sizeof(struct gmac_rxdesc_s)); + + /* Set the Receive Buffer Queue Base Register */ + + physaddr = sam_physramaddr((uintptr_t)rxdesc); + sam_putreg(priv, SAM_GMAC_RBQB, physaddr); +} + +/**************************************************************************** + * Function: sam_gmac_reset + * + * Description: + * Reset the GMAC block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_gmac_reset(struct sam_gmac_s *priv) +{ +#ifdef CONFIG_NETDEV_PHY_IOCTL + /* We are supporting PHY IOCTLs, then do not reset the MAC. If we do, + * then we cannot communicate with the PHY. So, instead, just disable + * interrupts, cancel timers, and disable TX and RX. + */ + + sam_putreg(priv, SAM_GMAC_IDR, GMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Disable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN | GMAC_NCR_WESTAT); + sam_putreg(priv, SAM_GMAC_NCR, regval); + +#else + /* Disable all GMAC interrupts */ + + sam_putreg(priv, SAM_GMAC_IDR, GMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Make sure that RX and TX are disabled; clear statistics registers */ + + sam_putreg(priv, SAM_GMAC_NCR, GMAC_NCR_CLRSTAT); + + /* Disable clocking to the GMAC peripheral */ + + sam_gmac_disableclk(); + +#endif +} + +/**************************************************************************** + * Function: sam_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_macaddress(struct sam_gmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address */ + + regval = (uint32_t)dev->d_mac.ether_addr_octet[0] | + (uint32_t)dev->d_mac.ether_addr_octet[1] << 8 | + (uint32_t)dev->d_mac.ether_addr_octet[2] << 16 | + (uint32_t)dev->d_mac.ether_addr_octet[3] << 24; + sam_putreg(priv, SAM_GMAC_SAB1, regval); + + regval = (uint32_t)dev->d_mac.ether_addr_octet[4] | + (uint32_t)dev->d_mac.ether_addr_octet[5] << 8; + sam_putreg(priv, SAM_GMAC_SAT1, regval); +} + +/**************************************************************************** + * Function: sam_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_gmac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)sam_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_gmac_configure + * + * Description: + * Configure the GMAC interface for normal operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_gmac_configure(struct sam_gmac_s *priv) +{ + uint32_t regval; + + nllvdbg("Entry\n"); + + /* Enable clocking to the GMAC peripheral */ + + sam_gmac_enableclk(); + + /* Disable TX, RX, clear statistics. Disable all interrupts. */ + + sam_putreg(priv, SAM_GMAC_NCR, GMAC_NCR_CLRSTAT); + sam_putreg(priv, SAM_GMAC_IDR, GMAC_INT_ALL); + + /* Clear all status bits in the receive status register. */ + + regval = (GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA | GMAC_RSR_HNO); + sam_putreg(priv, SAM_GMAC_RSR, regval); + + /* Clear all status bits in the transmit status register */ + + regval = GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE | GMAC_TSR_TXGO | + GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND | GMAC_TSR_HRESP | + GMAC_TSR_LCO; + sam_putreg(priv, SAM_GMAC_TSR, regval); + + /* Clear any pending interrupts */ + + (void)sam_getreg(priv, SAM_GMAC_ISR); + + /* Initial configuration: + * + * SPD = 0 : Assuming 1000Base-T full duplex + * FD = 1 : Assuming 1000Base-T full duplex + * DNVLAN = 0 : Don't discard non-VLAN frames + * JFRAME = 0 : Disable jumbo frames + * CAF : Depends on CONFIG_NET_PROMISCUOUS + * NBC : Depends on CONFIG_SAMA5_GMAC_NBC + * MTIHEN = 0 : Multicast hash disabled + * UNIHEN = 0 : Unicast hash disabled + * MAXFS = 0 : Disable receive 1536 byte frames + * GBE = 1 : Assuming 1000Base-T full duplex + * RTY = 0 : Disable retry test + * PEN = 1 : Pause frames disabled + * RXBUFO = 0 : No receive buffer offset + * LFERD = 0 : No length field error discard + * RFCS = 1 : Remove FCS + * CLK = 4 : Assuming MCK <= 160MHz + * DBW = 1 : 64-bit data bus with + * DCPF = 0 : Copy of pause frames not disabled + * RXCOEN = 0 : RX checksum offload disabled + * EFRHD = 0 : Disable frames received in half duple + * IRXFCS = 0 : Disable ignore RX FCX + * IPGSEN = 0 : IP stretch disabled + * RXBP = 0 : Receive bad pre-ambled disabled + * IRXER = 0 : Disable ignore IPG GXER + */ + + regval = GMAC_NCFGR_FD | GMAC_NCFGR_GBE | GMAC_NCFGR_PEN | + GMAC_NCFGR_RFCS | GMAC_NCFGR_CLK_DIV64 | GMAC_NCFGR_DBW_64; + +#ifdef CONFIG_NET_PROMISCUOUS + regval |= GMAC_NCFGR_CAF; +#endif + +#ifdef CONFIG_SAMA5_GMAC_NBC + regval |= GMAC_NCFGR_NBC; +#endif + + sam_putreg(priv, SAM_GMAC_NCFGR, regval); + + /* Reset TX and RX */ + + sam_rxreset(priv); + sam_txreset(priv); + + /* Enable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_GMAC_NCR); + regval |= (GMAC_NCR_RXEN | GMAC_NCR_TXEN | GMAC_NCR_WESTAT); + sam_putreg(priv, SAM_GMAC_NCR, regval); + + /* Setup the interrupts for TX events, RX events, and error events */ + + regval = GMAC_INT_MFS | GMAC_INT_RCOMP | GMAC_INT_RXUBR | GMAC_INT_TXUBR | + GMAC_INT_TUR | GMAC_INT_RLEX | GMAC_INT_TFC | GMAC_INT_TCOMP | + GMAC_INT_ROVR | GMAC_INT_HRESP | GMAC_INT_PFNZ | GMAC_INT_PTZ | + GMAC_INT_PFTR | GMAC_INT_EXINT | GMAC_INT_DRQFR | GMAC_INT_SFR | + GMAC_INT_DRQFT | GMAC_INT_SFT | GMAC_INT_PDRQFR | GMAC_INT_PDRSFR | + GMAC_INT_PDRQFT | GMAC_INT_PDRSFT; + sam_putreg(priv, SAM_GMAC_IER, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_gmac_initialize + * + * Description: + * Initialize the GMAC driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_gmac_initialize(void) +{ + struct sam_gmac_s *priv = &g_gmac; + int ret; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct sam_gmac_s)); + priv->dev.d_ifup = sam_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = sam_ifdown; /* I/F down callback */ + priv->dev.d_txavail = sam_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = sam_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = sam_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = sam_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)&g_gmac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); + if (!priv->txpoll) + { + nlldbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout; + } + + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + if (!priv->txtimeout) + { + nlldbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout_with_txpoll; + } + + /* Configure PIO pins to support GMAC */ + + sam_ethgpioconfig(priv); + + /* Allocate buffers */ + + ret = sam_buffer_initialize(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_buffer_initialize failed: %d\n", ret); + goto errout_with_txtimeout; + } + + /* Attach the IRQ to the driver. It will not be enabled at the AIC until + * the interface is in the 'up' state. + */ + + ret = irq_attach(SAM_IRQ_GMAC, sam_gmac_interrupt); + if (ret < 0) + { + nlldbg("ERROR: Failed to attach the handler to the IRQ%d\n", SAM_IRQ_GMAC); + goto errout_with_buffers; + } + + /* Enable clocking to the GMAC peripheral (just for sam_ifdown()) */ + + sam_gmac_enableclk(); + + /* Put the interface in the down state (disabling clocking again). */ + + ret = sam_ifdown(&priv->dev); + if (ret < 0) + { + nlldbg("ERROR: Failed to put the interface in the down state: %d\n", ret); + goto errout_with_buffers; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + ret = netdev_register(&priv->dev, NET_LL_ETHERNET); + if (ret >= 0) + { + return ret; + } + + nlldbg("ERROR: netdev_register() failed: %d\n", ret); + +errout_with_buffers: + sam_buffer_free(priv); +errout_with_txtimeout: + wd_delete(priv->txtimeout); +errout_with_txpoll: + wd_delete(priv->txpoll); +errout: + return ret; +} + +#endif /* CONFIG_NET && CONFIG_SAMA5_GMAC */ diff --git a/arch/arm/src/sama5/sam_hsmci.c b/arch/arm/src/sama5/sam_hsmci.c new file mode 100644 index 0000000000000000000000000000000000000000..54a7e34d9a5cc1ea69bf190ad6d3f65f6dae6431 --- /dev/null +++ b/arch/arm/src/sama5/sam_hsmci.c @@ -0,0 +1,3445 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_hsmci.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "sam_pio.h" +#include "sam_dmac.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_hsmci.h" +#include "chip/sam_dmac.h" +#include "chip/sam_pmc.h" +#include "chip/sam_hsmci.h" +#include "chip/sam_pinmap.h" + +#if defined(CONFIG_SAMA5_HSMCI0) || defined(CONFIG_SAMA5_HSMCI1) || \ + defined(CONFIG_SAMA5_HSMCI2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#if defined(ATSAMA5D3) + /* The SAMA5D3 has three HSMCI blocks: HSMCI0-2. HSMCI0 requires DMAC0 + * support, HSMCI1-2 require DMAC1 support. + */ + +# define HSMCI0_DMAC 0 +# define HSMCI1_DMAC 1 +# define HSMCI2_DMAC 1 + +# if defined(CONFIG_SAMA5_HSMCI0) && !defined(CONFIG_SAMA5_DMAC0) +# error "HSMCI0 support requires CONFIG_SAMA5_DMAC0" +# endif + +# if defined(CONFIG_SAMA5_HSMCI1) && !defined(CONFIG_SAMA5_DMAC1) +# error "HSMCI1 support requires CONFIG_SAMA5_DMAC1" +# endif + +# if defined(CONFIG_SAMA5_HSMCI2) && !defined(CONFIG_SAMA5_DMAC1) +# error "HSMCI2 support requires CONFIG_SAMA5_DMAC1" +# endif + + /* System Bus Interfaces */ + +# define HSMCI_SYSBUS_IF DMACH_FLAG_PERIPHAHB_AHB_IF2 +# define MEMORY_SYSBUS_IF DMACH_FLAG_MEMAHB_AHB_IF0 + +#elif defined(ATSAMA5D4) + /* The SAMA5D3 has two HSMCI blocks: HSMCI0-1. They can be driven + * either by XDMAC0 (secure) or XDMAC1 (unsecure). + */ + +# if !defined(CONFIG_SAMA5_XDMAC0) && !defined(CONFIG_SAMA5_XDMAC1) +# error HSMCI0/1 require CONFIG_SAMA5_XDMAC0 and/or CONFIG_SAMA5_XDMAC1 +# endif + + /* If both XDMAC blocks are enabled, then we have to select which + * used by each HSMCI block. + */ + +# if defined(CONFIG_SAMA5_HSMCI0) +# if defined(CONFIG_SAMA5_HSMCI0_XDMAC0) && defined(CONFIG_SAMA5_XDMAC0) +# define HSMCI0_DMAC 0 +# elif defined(CONFIG_SAMA5_HSMCI0_XDMAC1) && defined(CONFIG_SAMA5_XDMAC1) +# define HSMCI0_DMAC 1 +# else +# error No valid DMA configuration for HSMCI0 +# endif +# endif + +# if defined(CONFIG_SAMA5_HSMCI1) +# if defined(CONFIG_SAMA5_HSMCI1_XDMAC0) && defined(CONFIG_SAMA5_XDMAC0) +# define HSMCI1_DMAC 0 +# elif defined(CONFIG_SAMA5_HSMCI0_XDMAC1) && defined(CONFIG_SAMA5_XDMAC1) +# define HSMCI1_DMAC 1 +# else +# error No valid DMA configuration for HSMCI1 +# endif +# endif + + /* System Bus Interfaces + * + * HSMCI0 is on H32MX, APB1; HSMCI1 is on H32MX, APB0. Both are + * accessible on MATRIX IF1. + * + * Memory is available on either port 5 (IF0 for both XDMAC0 and 1) or + * port 6 (IF1 for both XDMAC0 and 1). + */ + +# define HSMCI_SYSBUS_IF DMACH_FLAG_PERIPHAHB_AHB_IF1 +# define MEMORY_SYSBUS_IF DMACH_FLAG_MEMAHB_AHB_IF0 + +#else +# error Unrecognized SAMA5 architecture +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_SDIO_BLOCKSETUP +# error "This driver requires CONFIG_SDIO_BLOCKSETUP" +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE) +# undef CONFIG_SAMA5_HSMCI_CMDDEBUG +# undef CONFIG_SAMA5_HSMCI_XFRDEBUG +#endif + +#ifdef CONFIG_SAMA5_HSMCI_RDPROOF +# ifdef CONFIG_SAMA5_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS (HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF) +# else +# define HSMCU_PROOF_BITS HSMCI_MR_RDPROOF +# endif +#else +# ifdef CONFIG_SAMA5_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS HSMCI_MR_WRPROOF +# else +# define HSMCU_PROOF_BITS (0) +# endif +#endif + +/* There is some unresolved issue with the SAMA5D3 DMA. TX DMA is currently + * disabled. + */ + +#undef HSCMI_NORXDMA /* Define to disable RX DMA */ +#undef HSCMI_NOTXDMA /* Define to disable TX DMA */ + +#ifdef ATSAMA5D3 +# define HSCMI_NOTXDMA 1 /* Disabled */ +#endif + +/* Timing */ + +#define HSMCI_CMDTIMEOUT (100000) +#define HSMCI_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define HSMCI_DTIMER_DATATIMEOUT (0x000fffff) + +/* DMA configuration flags */ + +#define HSMCI_DMA_CHKSIZE HSMCI_DMA_CHKSIZE_1 + +#define DMA_FLAGS(pid) \ + (DMACH_FLAG_PERIPHPID(pid) | HSMCI_SYSBUS_IF | \ + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \ + DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | MEMORY_SYSBUS_IF | \ + DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_4 | DMACH_FLAG_MEMBURST_1) + +/* Status errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_STATUS_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | \ + HSMCI_INT_RCRCE | HSMCI_INT_RDIRE | HSMCI_INT_RINDE) + +/* Response errors: + * + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_RESPONSE_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RCRCE | \ + HSMCI_INT_RDIRE | HSMCI_INT_RINDE) +#define HSMCI_RESPONSE_NOCRC_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RDIRE | \ + HSMCI_INT_RINDE) +#define HSMCI_RESPONSE_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE) + +/* Data transfer errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + */ + +#define HSMCI_DATA_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE) + +#define HSMCI_DATA_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_DTOE) + +#define HSMCI_DATA_RECV_ERRORS \ + (HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \ + HSMCI_INT_DCRCE) + +#define HSMCI_DATA_DMASEND_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | HSMCI_INT_DCRCE) + +/* Data transfer status and interrupt mask bits. + * + * The XFRDONE flag in the HSMCI_SR indicates exactly when the read or + * write sequence is finished. + * + * 0: A transfer is in progress. + * 1: Command register is ready to operate and the data bus is in the idle state. + * + * DMADONE: DMA Transfer done + * + * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 1: DMA buffer transfer has completed. + */ + +#define HSMCI_RECV_INTS \ + (HSMCI_DATA_RECV_ERRORS | HSMCI_INT_RXRDY) +#define HSMCI_DMARECV_INTS \ + (HSMCI_DATA_RECV_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) +#define HSMCI_DMASEND_INTS \ + (HSMCI_DATA_DMASEND_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) + +/* Event waiting interrupt mask bits. + * + * CMDRDY (Command Ready): + * + * 0: A command is in progress + * 1: The last command has been sent. The CMDRDY flag is released 8 bits + * after the end of the card response. Cleared when writing in the HSMCI_CMDR + */ + +#define HSMCI_CMDRESP_INTS \ + (HSMCI_RESPONSE_ERRORS | HSMCI_INT_CMDRDY) +#define HSMCI_CMDRESP_NOCRC_INTS \ + (HSMCI_RESPONSE_NOCRC_ERRORS | HSMCI_INT_CMDRDY) + +/* Register logging support */ + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +# ifdef CONFIG_DEBUG_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define SAMPLENDX_TIMEOUT 5 +# define DEBUG_NDMASAMPLES 6 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define SAMPLENDX_TIMEOUT 3 +# define DEBUG_NDMASAMPLES 4 +# endif +#endif + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG +# define SAMPLENDX_AFTER_CMDR 0 +# define SAMPLENDX_AT_WAKEUP 1 +# define DEBUG_NCMDSAMPLES 2 +#endif + +/* Some semi-standard definitions */ + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Register logging support */ + +#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) +struct sam_hsmciregs_s +{ + uint32_t mr; /* Mode Register */ + uint32_t dtor; /* Data Timeout Register */ + uint32_t sdcr; /* SD/SDIO Card Register */ + uint32_t argr; /* Argument Register */ + uint32_t blkr; /* Block Register */ + uint32_t cstor; /* Completion Signal Timeout Register */ + uint32_t rsp0; /* Response Register 0 */ + uint32_t rsp1; /* Response Register 1 */ + uint32_t rsp2; /* Response Register 2 */ + uint32_t rsp3; /* Response Register 3 */ + uint32_t sr; /* Status Register */ + uint32_t imr; /* Interrupt Mask Register */ + uint32_t dma; /* DMA Configuration Register */ + uint32_t cfg; /* Configuration Register */ + uint32_t wpmr; /* Write Protection Mode Register */ + uint32_t wpsr; /* Write Protection Status Register */ +}; +#endif + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +struct sam_xfrregs_s +{ + struct sam_hsmciregs_s hsmci; +#ifdef CONFIG_DEBUG_DMA + struct sam_dmaregs_s dma; +#endif +}; +#endif + +/* This structure defines the state of the SAMA5 HSMCI interface */ + +struct sam_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* SAMA5-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t base; /* HSMCI register base address */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + uint8_t hsmci; /* HSMCI (0, 1, or 2) */ + volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ + volatile bool xfrbusy; /* TRUE: Transfer is in progress */ + volatile bool txbusy; /* TRUE: TX transfer is in progress (for delay calculation) */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + ssize_t remaining; /* Number of bytes remaining in the transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ + DMA_HANDLE dma; /* Handle for DMA channel */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_HSMCI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif + + /* Register logging support */ + +#if defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) && defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) + bool xfrinitialized; + bool cmdinitialized; +#endif +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG + uint8_t smplset; + struct sam_xfrregs_s xfrsamples[DEBUG_NDMASAMPLES]; +#endif +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG + struct sam_hsmciregs_s cmdsamples[DEBUG_NCMDSAMPLES]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_dev_s *priv); +#define sam_givesem(priv) (sem_post(&priv->waitsem)) + +#ifdef CONFIG_SAMA5_HSMCI_REGDEBUG +static bool sam_checkreg(struct sam_dev_s *priv, bool wr, + uint32_t value, uint32_t address); +#else +# define sam_checkreg(priv,wr,value,address) (false) +#endif + +static inline uint32_t sam_getreg(struct sam_dev_s *priv, + unsigned int offset); +static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, + unsigned int offset); + +static inline void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents); +static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static void sam_disablexfrints(struct sam_dev_s *priv); +static inline void sam_enableints(struct sam_dev_s *priv); + +static inline void sam_disable(struct sam_dev_s *priv); +static inline void sam_enable(struct sam_dev_s *priv); + +/* Register Sampling ********************************************************/ + +#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs); +static void sam_hsmcidump(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs, const char *msg); +#endif + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(struct sam_dev_s *priv); +static void sam_xfrsample(struct sam_dev_s *priv, int index); +static void sam_xfrdumpone(struct sam_dev_s *priv, int index, + const char *msg); +static void sam_xfrdump(struct sam_dev_s *priv); +#else +# define sam_xfrsampleinit(priv) +# define sam_xfrsample(priv,index) +# define sam_xfrdump(priv) +#endif + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(struct sam_dev_s *priv); +static inline void sam_cmdsample1(struct sam_dev_s *priv, int index3); +static inline void sam_cmdsample2(struct sam_dev_s *priv, int index, + uint32_t sr); +static void sam_cmddump(struct sam_dev_s *priv); +#else +# define sam_cmdsampleinit(priv) +# define sam_cmdsample1(priv,index) +# define sam_cmdsample2(priv,index,sr) +# define sam_cmddump(priv) +#endif + +/* DMA Helpers **************************************************************/ + +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv, + unsigned int offset); + +/* Data Transfer Helpers ****************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg); +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_notransfer(struct sam_dev_s *priv); + +/* Interrupt Handling *******************************************************/ + +static int sam_hsmci_interrupt(struct sam_dev_s *priv); +#ifdef CONFIG_SAMA5_HSMCI0 +static int sam_hsmci0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_HSMCI1 +static int sam_hsmci1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_HSMCI2 +static int sam_hsmci2_interrupt(int irq, void *context); +#endif + +/* SDIO interface methods ***************************************************/ + +/* Initialization/setup */ + +static void sam_reset(FAR struct sdio_dev_s *dev); +static uint8_t sam_status(FAR struct sdio_dev_s *dev); +static void sam_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void sam_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int sam_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks); +static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes); +static int sam_cancel(FAR struct sdio_dev_s *dev); +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev); +#endif +#ifndef HSCMI_NORXDMA +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +#endif +#ifndef HSCMI_NOTXDMA +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void sam_callback(void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Callbacks */ + +static const struct sdio_dev_s g_callbacks = +{ + .reset = sam_reset, + .status = sam_status, + .widebus = sam_widebus, + .clock = sam_clock, + .attach = sam_attach, + .sendcmd = sam_sendcmd, + .blocksetup = sam_blocksetup, + .recvsetup = sam_recvsetup, + .sendsetup = sam_sendsetup, + .cancel = sam_cancel, + .waitresponse = sam_waitresponse, + .recvR1 = sam_recvshort, + .recvR2 = sam_recvlong, + .recvR3 = sam_recvshort, + .recvR4 = sam_recvnotimpl, + .recvR5 = sam_recvnotimpl, + .recvR6 = sam_recvshort, + .recvR7 = sam_recvshort, + .waitenable = sam_waitenable, + .eventwait = sam_eventwait, + .callbackenable = sam_callbackenable, + .registercallback = sam_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = sam_dmasupported, +#ifndef HSCMI_NORXDMA + .dmarecvsetup = sam_dmarecvsetup, +#else + .dmarecvsetup = sam_recvsetup, +#endif +#ifndef HSCMI_NOTXDMA + .dmasendsetup = sam_dmasendsetup, +#else + .dmasendsetup = sam_sendsetup, +#endif +#endif +}; + +/* Pre-allocate memory for each HSMCI device */ + +#ifdef CONFIG_SAMA5_HSMCI0 +static struct sam_dev_s g_hsmci0; +#endif +#ifdef CONFIG_SAMA5_HSMCI1 +static struct sam_dev_s g_hsmci1; +#endif +#ifdef CONFIG_SAMA5_HSMCI2 +static struct sam_dev_s g_hsmci2; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_REGDEBUG +static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = value; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read an HSMCI register + * + ****************************************************************************/ + +static inline uint32_t sam_getreg(struct sam_dev_s *priv, unsigned int offset) +{ + uint32_t address = priv->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMA5_HSMCI_REGDEBUG + if (sam_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write a value to an HSMCI register + * + ****************************************************************************/ + +static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, + unsigned int offset) +{ + uint32_t address = priv->base + offset; + +#ifdef CONFIG_SAMA5_HSMCI_REGDEBUG + if (sam_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: sam_configwaitints + * + * Description: + * Configure HSMCI interrupts needed to support the wait function. Wait + * interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * waitmask - The set of bits in the HSMCI MASK register to set + * waitevents - Waited for events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_configwaitints(struct sam_dev_s *priv, + uint32_t waitmask, + sdio_eventset_t waitevents) +{ + irqstate_t flags; + + /* Save all of the data in one, atomic operation. */ + + flags = enter_critical_section(); + priv->waitevents = waitevents; + priv->wkupevent = 0; + priv->waitmask = waitmask; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_disablewaitints + * + * Description: + * Disable HSMCI interrupts and save wakeup event. Called + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * wkupevent - Wake-up event(s) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + + flags = enter_critical_section(); + priv->waitevents = 0; + priv->wkupevent = wkupevent; + priv->waitmask = 0; + sam_putreg(priv, ~priv->xfrmask, SAM_HSMCI_IDR_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_configxfrints + * + * Description: + * Configure HSMCI interrupts needed to support the data transfer. Data + * transfer interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +{ + priv->xfrmask = xfrmask; +} + +/**************************************************************************** + * Name: sam_disablexfrints + * + * Description: + * Disable HSMCI interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablexfrints(struct sam_dev_s *priv) +{ + irqstate_t flags = enter_critical_section(); + priv->xfrmask = 0; + sam_putreg(priv, ~priv->waitmask, SAM_HSMCI_IDR_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_enableints + * + * Description: + * Enable the previously configured HSMCI interrupts needed to suport the + * wait and transfer functions. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_enableints(struct sam_dev_s *priv) +{ + /* Enable all interrupts associated with the waited-for event */ + + sam_putreg(priv, priv->xfrmask | priv->waitmask, SAM_HSMCI_IER_OFFSET); +} + +/**************************************************************************** + * Name: sam_disable + * + * Description: + * Disable the HSMCI + * + ****************************************************************************/ + +static inline void sam_disable(struct sam_dev_s *priv) +{ + /* Disable the MCI */ + + sam_putreg(priv, HSMCI_CR_MCIDIS, SAM_HSMCI_CR_OFFSET); + + /* Disable all the interrupts */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); +} + +/**************************************************************************** + * Name: sam_enable + * + * Description: + * Enable the HSMCI + * + ****************************************************************************/ + +static inline void sam_enable(struct sam_dev_s *priv) +{ + /* Enable the MCI and the Power Saving */ + + sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); +} + +/**************************************************************************** + * Register Sampling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmcisample + * + * Description: + * Sample HSMCI registers + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs) +{ + regs->mr = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regs->dtor = sam_getreg(priv, SAM_HSMCI_DTOR_OFFSET); + regs->sdcr = sam_getreg(priv, SAM_HSMCI_SDCR_OFFSET); + regs->argr = sam_getreg(priv, SAM_HSMCI_ARGR_OFFSET); + regs->blkr = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + regs->cstor = sam_getreg(priv, SAM_HSMCI_CSTOR_OFFSET); + regs->rsp0 = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + regs->rsp1 = sam_getreg(priv, SAM_HSMCI_RSPR1_OFFSET); + regs->rsp2 = sam_getreg(priv, SAM_HSMCI_RSPR2_OFFSET); + regs->rsp3 = sam_getreg(priv, SAM_HSMCI_RSPR3_OFFSET); + regs->sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + regs->imr = sam_getreg(priv, SAM_HSMCI_IMR_OFFSET); + regs->dma = sam_getreg(priv, SAM_HSMCI_DMA_OFFSET); + regs->cfg = sam_getreg(priv, SAM_HSMCI_CFG_OFFSET); + regs->wpmr = sam_getreg(priv, SAM_HSMCI_WPMR_OFFSET); + regs->wpsr = sam_getreg(priv, SAM_HSMCI_WPSR_OFFSET); +} +#endif + +/**************************************************************************** + * Name: sam_hsmcidump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) +static void sam_hsmcidump(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs, const char *msg) +{ + fdbg("HSMCI Registers: %s\n", msg); + fdbg(" MR[%08x]: %08x\n", priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); + fdbg(" DTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); + fdbg(" SDCR[%08x]: %08x\n", priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); + fdbg(" ARGR[%08x]: %08x\n", priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); + fdbg(" BLKR[%08x]: %08x\n", priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); + fdbg(" CSTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); + fdbg(" RSPR0[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); + fdbg(" RSPR1[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); + fdbg(" RSPR2[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); + fdbg(" RSPR3[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); + fdbg(" SR[%08x]: %08x\n", priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); + fdbg(" IMR[%08x]: %08x\n", priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); + fdbg(" DMA[%08x]: %08x\n", priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); + fdbg(" CFG[%08x]: %08x\n", priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); + fdbg(" WPMR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); + fdbg(" WPSR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); +} +#endif + +/**************************************************************************** + * Name: sam_xfrsample + * + * Description: + * Sample HSMCI/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +static void sam_xfrsample(struct sam_dev_s *priv, int index) +{ + /* On a multiple block transfer, only sample on the first block */ + + if ((priv->smplset & (1 << index)) == 0) + { + struct sam_xfrregs_s *regs = &priv->xfrsamples[index]; + +#ifdef CONFIG_DEBUG_DMA + sam_dmasample(priv->dma, ®s->dma); +#endif + sam_hsmcisample(priv, ®s->hsmci); + priv->smplset |= (1 << index); + } +} +#endif + +/**************************************************************************** + * Name: sam_xfrsampleinit + * + * Description: + * Setup prior to collecting transfer samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(struct sam_dev_s *priv) +{ + priv->smplset = 0; + memset(priv->xfrsamples, 0xff, + DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s)); + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG + priv->xfrinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_xfrdumpone + * + * Description: + * Dump one transfer register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +static void sam_xfrdumpone(struct sam_dev_s *priv, int index, + const char *msg) +{ + if ((priv->smplset & (1 << index)) != 0) + { + struct sam_xfrregs_s *regs = &priv->xfrsamples[index]; + +#ifdef CONFIG_DEBUG_DMA + sam_dmadump(priv->dma, ®s->dma, msg); +#endif + sam_hsmcidump(priv, ®s->hsmci, msg); + } + else + { + fdbg("%s: Not collected\n", msg); + } +} +#endif + +/**************************************************************************** + * Name: sam_xfrdump + * + * Description: + * Dump all transfer-related, sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG +static void sam_xfrdump(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG + if (priv->xfrinitialized) +#endif + { + sam_xfrdumpone(priv, SAMPLENDX_BEFORE_SETUP, "Before setup"); +#ifdef CONFIG_DEBUG_DMA + sam_xfrdumpone(priv, SAMPLENDX_BEFORE_ENABLE, "Before DMA enable"); +#endif + sam_xfrdumpone(priv, SAMPLENDX_AFTER_SETUP, "After setup"); + sam_xfrdumpone(priv, SAMPLENDX_END_TRANSFER, "End of transfer"); +#ifdef CONFIG_DEBUG_DMA + sam_xfrdumpone(priv, SAMPLENDX_DMA_CALLBACK, "DMA Callback"); +#endif + sam_xfrdumpone(priv, SAMPLENDX_TIMEOUT, "Timeout"); + + priv->smplset = 0; +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG + priv->xfrinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * Name: sam_cmdsampleinit + * + * Description: + * Setup prior to collecting command/response samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(struct sam_dev_s *priv) +{ + memset(priv->cmdsamples, 0xff, + DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s)); + +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG + priv->cmdinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_cmdsample1 & 2 + * + * Description: + * Sample command/response registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG +static inline void sam_cmdsample1(struct sam_dev_s *priv, int index) +{ + sam_hsmcisample(priv, &priv->cmdsamples[index]); +} + +static inline void sam_cmdsample2(struct sam_dev_s *priv, int index, + uint32_t sr) +{ + sam_hsmcisample(priv, &priv->cmdsamples[index]); + priv->cmdsamples[index].sr = sr; +} +#endif + +/**************************************************************************** + * Name: sam_cmddump + * + * Description: + * Dump all comand/response register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG +static void sam_cmddump(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG + if (priv->cmdinitialized) +#endif + { + sam_hsmcidump(priv, &priv->cmdsamples[SAMPLENDX_AFTER_CMDR], + "After command setup"); + sam_hsmcidump(priv, &priv->cmdsamples[SAMPLENDX_AT_WAKEUP], + "After wakeup"); +#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG + priv->cmdinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dmacallback + * + * Description: + * Called when HSMCI DMA completes + * + ****************************************************************************/ + +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + sdio_eventset_t wkupevent; + + /* Is DMA still active? We can get this callback when sam_dmastop() is + * called too. + */ + + if (priv->dmabusy) + { + /* Mark the DMA not busy and sample DMA registers */ + + priv->dmabusy = false; + sam_xfrsample((struct sam_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Terminate the transfer with an I/O error in the event of a DMA failure */ + + if (result < 0) + { + wkupevent = (result == -ETIMEDOUT ? SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); + flldbg("ERROR: DMA failed: result=%d wkupevent=%04x\n", result, wkupevent); + + /* sam_endtransfer will terminate the transfer and wait up the waiting + * client in this case. + */ + + sam_endtransfer(priv, wkupevent); + } + + /* The DMA completed without error. Wake-up the waiting client if (1) both the + * HSMCI and DMA completion events, and (2) There is a client waiting for + * this event. + * + * If the HSMCI transfer event has already completed, it must have completed + * successfully (because the DMA was not cancelled). sam_endtransfer() should + * have already received the SDIOWAIT_TRANSFERDONE event, but this event would + * not yet have been recorded. We need to post the SDIOWAIT_TRANSFERDONE + * again in this case here. + * + * The timeout will remain active until sam_endwait() is eventually called + * so we should not have any concern about hangs if the HSMCI transfer never + * completed. + */ + + else if (!priv->xfrbusy && (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) + { + /* Okay.. wake up any waiting threads */ + + sam_endwait(priv, SDIOWAIT_TRANSFERDONE); + } + } +} + +/**************************************************************************** + * Name: hsmci_physregaddr + * + * Description: + * Return the physical address of an HSMCI register + * + ****************************************************************************/ + +static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv, + unsigned int offset) +{ + return sam_physregaddr(priv->base + offset); +} + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + + DEBUGASSERT(argc == 1 && priv != NULL); + sam_xfrsample((struct sam_dev_s *)arg, SAMPLENDX_TIMEOUT); + + /* Make sure that any hung DMA is stopped. dmabusy == false is the cue + * so the DMA callback is ignored. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Make sure that any hung HSMCI transfer is stopped */ + + sam_disablexfrints(priv); + sam_notransfer(priv); + + /* Is a data timeout complete event expected? (should always be the case) */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + sam_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("ERROR: Timeout\n"); + } +} + +/**************************************************************************** + * Name: sam_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts and save wakeup event */ + + sam_disablewaitints(priv, wkupevent); + + /* Wake up the waiting thread */ + + sam_givesem(priv); +} + +/**************************************************************************** + * Name: sam_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the HSMCI interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + sam_disablexfrints(priv); + + /* No data transfer */ + + sam_notransfer(priv); + + /* DMA debug instrumentation */ + + sam_xfrsample(priv, SAMPLENDX_END_TRANSFER); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0) + { + /* dmabusy == false gives the DMA callback handler a clue about what + * is going on. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + } + + /* The transfer is complete. Wake-up the waiting client if (1) both the + * HSMCI and DMA completion events, and (2) There is a client waiting for + * this event. + * + * The timeout will remain active until sam_endwait() is eventually called + * so we should not have any concern about hangs if the DMA never completes. + */ + + if (!priv->dmabusy && (priv->waitevents & wkupevent) != 0) + { + /* Okay.. wake up any waiting threads */ + + sam_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Name: sam_notransfer + * + * Description: + * Setup for no transfer. This is called both before beginning a new + * transfer and when a transfer completes. In the first case, this is the + * default setup that is overridden by sam_dmarecvsetup or sam_dmasendsetup + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_notransfer(struct sam_dev_s *priv) +{ + uint32_t regval; + + /* Make read/write proof (or not). This is a legacy behavior: This really + * just needs be be done once at initialization time. + */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + + /* Clear the block size and count */ + + sam_putreg(priv, 0, SAM_HSMCI_BLKR_OFFSET); + + /* Clear transfer flags (DMA could still be active in a corner case) */ + + priv->xfrbusy = false; + priv->txbusy = false; +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmci_interrupt + * + * Description: + * HSMCI interrupt handler + * + * Input Parameters: + * irq - IRQ number of the interrupts + * context - Saved machine context at the time of the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_hsmci_interrupt(struct sam_dev_s *priv) +{ + uint32_t sr; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. */ + + for (; ; ) + { + /* Check the HSMCI status register. Mask out all bits that don't + * correspond to enabled interrupts. (This depends on the fact that + * bits are ordered the same in both the SR and IMR registers). If + * there are non-zero bits remaining, then we have work to do here. + */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + enabled = sr & sam_getreg(priv, SAM_HSMCI_IMR_OFFSET); + + if (enabled == 0) + { + break; + } + + /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal a data transfer event? */ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { + /* Yes.. Did the transfer complete with an error? */ + + if ((pending & HSMCI_DATA_ERRORS) != 0) + { + /* Yes.. Was it some kind of timeout error? */ + + flldbg("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) + { + /* Yes.. Terminate with a timeout. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + else + { + /* No.. Terminate with an I/O error. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + + /* No, If RXRDY is enabled, then we are doing a non-DMA receive. + * We need to transfer word(s) from the RDR register to the user + * buffer. + */ + + else if ((pending & HSMCI_INT_RXRDY) != 0) + { + /* Interrupt mode data transfer support */ + + DEBUGASSERT(!priv->dmabusy && priv->xfrbusy && !priv->txbusy); + DEBUGASSERT(priv->buffer && priv->remaining > 0); + + *priv->buffer++ = sam_getreg(priv, SAM_HSMCI_RDR_OFFSET); + priv->remaining -= sizeof(uint32_t); + + /* Are we finished? */ + + if (priv->remaining <= 0) + { + /* Yes.. End the transfer */ + + priv->buffer = NULL; + priv->remaining = 0; + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Otherwise it must be a DMA transfer that completed successfully */ + + else + { + /* End the transfer */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + sdio_eventset_t wkupevent = 0; + + /* Is this a Command-Response sequence completion event? */ + + if ((pending & priv->cmdrmask) != 0) + { + sam_cmdsample2(priv, SAMPLENDX_AT_WAKEUP, sr); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fllvdbg("ERROR: events: %08x SR: %08x\n", + priv->cmdrmask, enabled); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. signal a timeout error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + } + else + { + /* No.. signal some generic I/O error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + } + + /* Yes.. Is there a thread waiting for this event set? */ + + wkupevent &= priv->waitevents; + if (wkupevent != 0) + { + /* Yes.. wake the thread up */ + + sam_endwait(priv, wkupevent); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_hsmci0_interrupt, sam_hsmci1_interrupt, and sam_hsmci2_interrupt + * + * Description: + * HSMCI interrupt handler + * + * Input Parameters: + * irq - IRQ number of the interrupts + * context - Saved machine context at the time of the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HSMCI0 +static int sam_hsmci0_interrupt(int irq, void *context) +{ + return sam_hsmci_interrupt(&g_hsmci0); +} +#endif + +#ifdef CONFIG_SAMA5_HSMCI1 +static int sam_hsmci1_interrupt(int irq, void *context) +{ + return sam_hsmci_interrupt(&g_hsmci1); +} +#endif + +#ifdef CONFIG_SAMA5_HSMCI2 +static int sam_hsmci2_interrupt(int irq, void *context) +{ + return sam_hsmci_interrupt(&g_hsmci2); +} +#endif + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ +/**************************************************************************** + * Name: sam_reset + * + * Description: + * Reset the HSMCI controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)dev; + irqstate_t flags; + + /* Reset the MCI */ + + flags = enter_critical_section(); + sam_putreg(priv, HSMCI_CR_SWRST, SAM_HSMCI_CR_OFFSET); + + /* Disable the MCI */ + + sam_putreg(priv, HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS, SAM_HSMCI_CR_OFFSET); + + /* Disable all the interrupts */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); + + /* Set the Data Timeout Register */ + + sam_putreg(priv, HSMCI_DTOR_DTOCYC_MAX | HSMCI_DTOR_DTOMUL_MAX, + SAM_HSMCI_DTOR_OFFSET); + + /* Set the Mode Register for ID mode frequency (probably 400KHz) */ + + sam_clock(dev, CLOCK_IDMODE); + + /* Set the SDCard Register */ + + sam_putreg(priv, HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_4BIT, + SAM_HSMCI_SDCR_OFFSET); + + /* Enable the MCI controller */ + + sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); + + /* Disable the DMA interface */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Configure MCI */ + + sam_putreg(priv, HSMCI_CFG_FIFOMODE, SAM_HSMCI_CFG_OFFSET); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ + priv->dmabusy = false; /* No DMA in progress */ + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; /* Required for DMA support */ + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see sam_status_* defines) + * + ****************************************************************************/ + +static uint8_t sam_status(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: sam_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + + /* Set 1-bit or 4-bit bus by configuring the SDCBUS field of the SDCR register */ + + regval = sam_getreg(priv, SAM_HSMCI_SDCR_OFFSET); + regval &= ~HSMCI_SDCR_SDCBUS_MASK; + regval |= wide ? HSMCI_SDCR_SDCBUS_4BIT : HSMCI_SDCR_SDCBUS_1BIT; + sam_putreg(priv, regval, SAM_HSMCI_SDCR_OFFSET); + + /* Remember the setting */ + + priv->widebus = wide; +} + +/**************************************************************************** + * Name: sam_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + bool enable = true; + + /* Fetch the current mode register and mask out the clkdiv+clockodd (and pwsdiv) */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_CLKDIV_MASK | HSMCI_MR_PWSDIV_MASK | HSMCI_MR_CLKODD); + + /* These clock devisor values that must be defined in the board-specific + * board.h header file: HSMCI_INIT_CLKDIV, HSMCI_MMCXFR_CLKDIV, + * HSMCI_SDXFR_CLKDIV, and HSMCI_SDWIDEXFR_CLKDIV. + */ + + switch (rate) + { + default: + case CLOCK_SDIO_DISABLED: /* Clock is disabled */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + enable = false; + return; + + case CLOCK_IDMODE: /* Initial ID mode clocking (<400KHz) */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_MMC_TRANSFER: /* MMC normal operation clocking */ + regval |= HSMCI_MMCXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_1BIT: /* SD normal operation clocking (narrow 1-bit mode) */ + regval |= HSMCI_SDXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_4BIT: /* SD normal operation clocking (wide 4-bit mode) */ + regval |= HSMCI_SDWIDEXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + }; + + /* Set the new clock diver and make sure that the clock is enabled or + * disabled, whichever the case. + */ + + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + if (enable) + { + sam_enable(priv); + } + else + { + sam_disable(priv); + } +} + +/**************************************************************************** + * Name: sam_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int sam_attach(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + xcpt_t handler; + int irq; + int ret; + + /* Select the handler and IRQ */ + +#ifdef CONFIG_SAMA5_HSMCI0 + if (priv->hsmci == 0) + { + handler = sam_hsmci0_interrupt; + irq = SAM_IRQ_HSMCI0; + } + else +#endif +#ifdef CONFIG_SAMA5_HSMCI1 + if (priv->hsmci == 1) + { + handler = sam_hsmci1_interrupt; + irq = SAM_IRQ_HSMCI1; + } + else +#endif +#ifdef CONFIG_SAMA5_HSMCI2 + if (priv->hsmci == 2) + { + handler = sam_hsmci2_interrupt; + irq = SAM_IRQ_HSMCI2; + } + else +#endif + { + DEBUGPANIC(); + return -EINVAL; /* Shouldn't happen */ + } + + /* Attach the HSMCI interrupt handler */ + + ret = irq_attach(irq, handler); + if (ret == OK) + { + + /* Disable all interrupts at the HSMCI controller and clear (most) static + * interrupt flags by reading the status register. + */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Enable HSMCI interrupts at the NVIC. They can now be enabled at + * the HSMCI controller as needed. + */ + + up_enable_irq(irq); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + uint32_t cmdidx; + + sam_cmdsampleinit(priv); + + /* Set the HSMCI Argument value */ + + sam_putreg(priv, arg, SAM_HSMCI_ARGR_OFFSET); + + /* Construct the command valid, starting with the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval = cmdidx << HSMCI_CMDR_CMDNB_SHIFT; + + /* 'OR' in response related bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + /* No response */ + + case MMCSD_NO_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= HSMCI_CMDR_RSPTYP_NONE; + + break; + + /* 48-bit response with CRC */ + + case MMCSD_R1_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + case MMCSD_R1B_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + break; + + /* 48-bit response without CRC */ + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + /* 136-bit response with CRC */ + + case MMCSD_R2_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + break; + } + + /* 'OR' in data transfer related bits */ + + switch (cmd & MMCSD_DATAXFR_MASK) + { +#if 0 /* No MMC support */ + case MMCSD_RDSTREAM: /* MMC Read stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + break; + + case MMCSD_WRSTREAM: /* MMC Write stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + break; +#endif + + case MMCSD_RDDATAXFR: /* Read block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_WRDATAXFR: /* Write block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_NODATAXFR: + default: + if ((cmd & MMCSD_STOPXFR) != 0) + { + regval |= HSMCI_CMDR_TRCMD_STOP; + } + break; + } + + /* 'OR' in Open Drain option */ + +#if 0 /* No MMC support */ + if ((cmd & MMCSD_OPENDRAIN) != 0) + { + regval |= HSMCI_CMDR_OPDCMD; + } +#endif + + /* Write the fully decorated command to CMDR */ + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + sam_putreg(priv, regval, SAM_HSMCI_CMDR_OFFSET); + sam_cmdsample1(priv, SAMPLENDX_AFTER_CMDR); + return OK; +} + +/**************************************************************************** + * Name: sam_blocksetup + * + * Description: + * Some hardward needs to be informed of the selected blocksize. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * blocklen - The selected block size. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + + DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535); + DEBUGASSERT(blocklen < 65535 && (blocklen & 3) == 0); + + /* Make read/write proof (or not). This is a legacy behavior: This really + * just needs be be done once at initialization time. + */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); + regval |= HSMCU_PROOF_BITS; + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + + /* Set the block size and count */ + + regval = (blocklen << HSMCI_BLKR_BLKLEN_SHIFT) | + (nblocks << HSMCI_BLKR_BCNT_SHIFT); + sam_putreg(priv, regval, SAM_HSMCI_BLKR_OFFSET); +} + +/**************************************************************************** + * Name: sam_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer in which to receive the data + * buflen - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Initialize register sampling */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Disable DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Setup of the transfer configuration */ + + priv->dmabusy = false; + priv->xfrbusy = true; + priv->txbusy = false; + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + + /* And enable interrupts */ + + sam_configxfrints(priv, HSMCI_RECV_INTS); + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: sam_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer containing the data to send + * buflen - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + unsigned int nwords; + const uint32_t *ptr; + uint32_t sr; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Disable DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + sam_configxfrints(priv, HSMCI_DMASEND_INTS); + + priv->dmabusy = false; + priv->xfrbusy = true; + priv->txbusy = true; + + /* Nullify register sampling */ + + sam_xfrsampleinit(priv); + + /* Copy each word to the TX FIFO + * + * REVISIT: If TX data underruns occur, then it may be necessary to + * disable pre-emption around this loop. + */ + + nwords = (buflen + 3) >> 2; + ptr = (const uint32_t *)buffer; + + while (nwords > 0) + { + /* Check the HSMCI status */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + if ((sr & HSMCI_DATA_DMASEND_ERRORS) != 0) + { + /* Some fatal error has occurred */ + + fdbg("ERROR: sr %08x\n", sr); + return -EIO; + } + else if ((sr & HSMCI_INT_TXRDY) != 0) + { + /* TXRDY -- transfer another word */ + + sam_putreg(priv, *ptr++, SAM_HSMCI_TDR_OFFSET); + nwords--; + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_cancel(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + sam_disablexfrints(priv); + sam_disablewaitints(priv, 0); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Clearing (most) pending interrupt status by reading the status register */ + + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + * + * dmabusy == false let's the DMA callback know what is happening. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + return OK; +} + +/**************************************************************************** + * Name: sam_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t sr; + uint32_t pending; + int32_t timeout; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + timeout = HSMCI_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_NO_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + timeout = HSMCI_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + for (; ; ) + { + /* Did a Command-Response sequence termination evernt occur? */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + pending = sr & priv->cmdrmask; + + if (pending != 0) + { + sam_cmdsample2(priv, SAMPLENDX_AT_WAKEUP, sr); + sam_cmddump(priv); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fdbg("ERROR: cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. return a timeout error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + else + { + /* No.. return some generic I/O error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + return -EIO; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + return OK; + } + } + else if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + priv->wkupevent = SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + } +} + +/**************************************************************************** + * Name: sam_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a failure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intact and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int sam_recvshort(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rshort) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* These responses could have CRC errors: + * + * R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * But there is no parity on the R3 response and parity errors should + * be ignored. + * + * R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + ret = -EIO; + } + + /* Return the R1/R6 response */ + + else if (rshort) + { + *rshort = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + } + + priv->wkupevent = 0; + return ret; +} + +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + ret = -EIO; + } + + /* Return the long response */ + + else if (rlong) + { + rlong[0] = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + rlong[1] = sam_getreg(priv, SAM_HSMCI_RSPR1_OFFSET); + rlong[2] = sam_getreg(priv, SAM_HSMCI_RSPR2_OFFSET); + rlong[3] = sam_getreg(priv, SAM_HSMCI_RSPR3_OFFSET); + } + + priv->wkupevent = 0; + return ret; +} + +/* MMC responses not supported */ + +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rnotimpl) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + priv->wkupevent = 0; + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling either calling SDIO_DMARECVSETUP, + * SDIO_DMASENDSETUP, or or SDIO_WAITEVENT. This is the recommended + * ordering: + * + * SDIO_WAITENABLE: Discard any pending interrupts, enable event(s) + * of interest + * SDIO_DMARECVSETUP/ + * SDIO_DMASENDSETUP: Setup the logic that will trigger the event the + * event(s) of interest + * SDIO_WAITEVENT: Wait for the event of interest (which might + * already have occurred) + * + * This sequency should eliminate race conditions between the command/trasnfer + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + sam_disablewaitints(priv, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + + waitmask = 0; + if ((eventset & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0) + { + waitmask |= priv->cmdrmask; + } + + /* Clear (most) pending interrupts by reading the status register. + * No interrupts should be lost (assuming that interrupts were enabled + * before sam_waitenable() was called). Any interrupts that become + * pending after this point must be valid event indications. + */ + + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Wait interrupts are configured here, but not enabled until + * sam_eventwait() is called. Why? Because the XFRDONE interrupt is + * always pending until start the data transfer. + */ + + sam_configwaitints(priv, waitmask, eventset); +} + +/**************************************************************************** + * Name: sam_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when sam_eventwait + * returns. SDIO_WAITEVENTS must be called again before sam_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + int ret; + + /* Since interrupts not been enabled to this point, any relevant events + * are pending and should not yet have occurred. + */ + + DEBUGASSERT(priv->waitevents != 0 && priv->wkupevent == 0); + + /* Now enable event-related interrupts. If the events are pending, they + * may happen immediately here before entering the loop. + */ + + sam_enableints(priv); + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevent will + * be non-zero (and, hopefully, the semaphore count will also be non-zero). + */ + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + return SDIOWAIT_TIMEOUT; + } + + /* Start the watchdog timer. I am not sure why this is, but I am + * currently seeing some additional delays when DMA is used. + */ + + if (priv->txbusy) + { + /* TX transfers can be VERY long in the worst case */ + + timeout = MAX(5000, timeout); + } + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)sam_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling sam_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + sam_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + * When wkupevent becomes non-zero, further interrupts will have already + * been disabled. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + sam_cmddump(priv); + sam_xfrdump(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: sam_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in sam_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methods. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + sam_callback(priv); +} + +/**************************************************************************** + * Name: sam_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE. + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: sam_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: sam_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef HSCMI_NORXDMA +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t paddr; + uint32_t maddr; + uint32_t regval; + unsigned int blocksize; + unsigned int nblocks; + unsigned int offset; + unsigned int i; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* How many blocks? That should have been saved by the sam_blocksetup() + * method earlier. + */ + + regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + + DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); + + /* Physical address of the HSCMI source register, either the TDR (for + * single transfers) or the first FIFO register, and the physical address + * of the buffer in RAM. + */ + + offset = (nblocks == 1 ? SAM_HSMCI_RDR_OFFSET : SAM_HSMCI_FIFO_OFFSET); + paddr = hsmci_physregaddr(priv, offset); + maddr = sam_physramaddr((uintptr_t)buffer); + + /* Setup register sampling (only works for the case of nblocks == 1) */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Set DMA for each block */ + + for (i = 0; i < nblocks; i++) + { + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->dma, paddr, maddr, buflen); + + /* Update addresses for the next block */ + + paddr += sizeof(uint32_t); + maddr += blocksize; + } + + /* Enable DMA handshaking */ + + sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + priv->xfrbusy = true; + priv->txbusy = false; + sam_dmastart(priv->dma, sam_dmacallback, priv); + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is started with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMARECV_INTS); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef HSCMI_NOTXDMA +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t paddr; + uint32_t maddr; + uint32_t regval; + unsigned int blocksize; + unsigned int nblocks; + unsigned int offset; + unsigned int i; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* How many blocks? That should have been saved by the sam_blocksetup() + * method earlier. + */ + + regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + + DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); + + /* Physical address of the HSCMI source register, either the TDR (for + * single transfers) or the first FIFO register, and the physical address + * of the buffer in RAM. + */ + + offset = (nblocks == 1 ? SAM_HSMCI_TDR_OFFSET : SAM_HSMCI_FIFO_OFFSET); + paddr = hsmci_physregaddr(priv, offset); + maddr = sam_physramaddr((uintptr_t)buffer); + + /* Setup register sampling (only works for the case of nblocks == 1) */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Set DMA for each block */ + + for (i = 0; i < nblocks; i++) + { + /* Configure the TX DMA */ + + sam_dmatxsetup(priv->dma, paddr, maddr, buflen); + + /* Update addresses for the next block */ + + paddr += sizeof(uint32_t); + maddr += blocksize; + } + + /* Enable DMA handshaking */ + + sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + priv->xfrbusy = true; + priv->txbusy = true; + sam_dmastart(priv->dma, sam_dmacallback, priv); + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is stard with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMASEND_INTS); + return OK; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: sam_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void sam_callback(void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + irqstate_t flags; + int ret; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + flags = enter_critical_section(); + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* This function is called either from (1) the context of the calling + * thread or from the the context of (2) card detection logic. The + * caller may or may not have interrupts disabled (we have them + * disabled here!). + * + * So to minimize the possibility of recursive behavior and to assure + * that callback is always performed outside of the interrupt handling + * context and with interrupts enabled, the callback is always performed + * on the lower priority work thread. + */ + + /* First cancel any existing work */ + + ret = work_cancel(LPWORK, &priv->cbwork); + if (ret < 0) + { + /* NOTE: Currently, work_cancel only returns success */ + + fdbg("ERROR: Failed to cancel work: %d\n", ret); + } + + fllvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + ret = work_queue(LPWORK, &priv->cbwork, (worker_t)priv->callback, + priv->cbarg, 0); + if (ret < 0) + { + /* NOTE: Currently, work_queue only returns success */ + + fdbg("ERROR: Failed to schedule work: %d\n", ret); + } + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SD for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + struct sam_dev_s *priv; + uint32_t pid; + uint8_t dmac; + + /* Select the slot and perform slot-specific initialization. The + * semantics here are bad. There are three HSMCI peripherals that we + * will treat as "slots." In principle they could each peripheral could + * support 4 slots, A-D. However, selection of slots B, C, and D is + * listed as "reserved" in the HSMCI register definitions. So, at least + * for now, an* HSMCI peripheral does correspond to a slot. + */ + + fdbg("slotno: %d\n", slotno); + +#ifdef CONFIG_SAMA5_HSMCI0 + if (slotno == 0) + { + /* Select HSMCI0 */ + + priv = &g_hsmci0; + + /* HSMCI0 Initialization */ + + priv->base = SAM_HSMCI0_VBASE; + priv->hsmci = 0; + + /* Configure PIOs for 4-bit, wide-bus operation. NOTE: (1) the chip + * is capable of 8-bit wide bus operation but D4-D7 are not configured, + * (2) any card detection PIOs must be set up in board-specific logic. + * + * REVISIT: What about Slot B? + */ + + sam_configpio(PIO_MCI0_DA0); /* Data 0 of Slot A */ + sam_configpio(PIO_MCI0_DA1); /* Data 1 of Slot A */ + sam_configpio(PIO_MCI0_DA2); /* Data 2 of Slot A */ + sam_configpio(PIO_MCI0_DA3); /* Data 3 of Slot A */ + sam_configpio(PIO_MCI0_CK); /* Common SD clock */ + sam_configpio(PIO_MCI0_CDA); /* Command/Response of Slot A */ + + /* Enable the HSMCI0 peripheral clock. This really should be done in + * sam_enable (as well as disabling peripheral clocks in sam_disable(). + */ + + sam_hsmci0_enableclk(); + + /* For DMA channel selection */ + + dmac = HSMCI0_DMAC; + pid = SAM_PID_HSMCI0; + } + else +#endif +#ifdef CONFIG_SAMA5_HSMCI1 + if (slotno == 1) + { + /* Select HSMCI1 */ + + priv = &g_hsmci1; + + /* HSMCI1 Initialization */ + + priv->base = SAM_HSMCI1_VBASE; + priv->hsmci = 1; + + /* Configure PIOs for 4-bit, wide-bus operation. NOTE: (1) the chip + * is capable of 8-bit wide bus operation but D4-D7 are not configured, + * (2) any card detection PIOs must be set up in board-specific logic. + * + * REVISIT: What about Slot B? + */ + + sam_configpio(PIO_MCI1_DA0); /* Data 0 of Slot A */ + sam_configpio(PIO_MCI1_DA1); /* Data 1 of Slot A */ + sam_configpio(PIO_MCI1_DA2); /* Data 2 of Slot A */ + sam_configpio(PIO_MCI1_DA3); /* Data 3 of Slot A */ + sam_configpio(PIO_MCI1_CK); /* Common SD clock */ + sam_configpio(PIO_MCI1_CDA); /* Command/Response of Slot A */ + + /* Enable the HSMCI1 peripheral clock This really should be done in + * sam_enable (as well as disabling peripheral clocks in sam_disable(). + */ + + sam_hsmci1_enableclk(); + + /* For DMA channel selection */ + + dmac = HSMCI1_DMAC; + pid = SAM_PID_HSMCI1; + } + else +#endif +#ifdef CONFIG_SAMA5_HSMCI2 + if (slotno == 2) + { + /* Select HSMCI2 */ + + priv = &g_hsmci2; + + /* HSMCI2 Initialization */ + + priv->base = SAM_HSMCI2_VBASE; + priv->hsmci = 2; + + /* Configure PIOs for 4-bit, wide-bus operation. NOTE: (1) the chip + * is capable of 8-bit wide bus operation but D4-D7 are not configured, + * (2) any card detection PIOs must be set up in board-specific logic. + * + * REVISIT: What about Slot B? + */ + + sam_configpio(PIO_MCI2_DA0); /* Data 0 of Slot A */ + sam_configpio(PIO_MCI2_DA1); /* Data 1 of Slot A */ + sam_configpio(PIO_MCI2_DA2); /* Data 2 of Slot A */ + sam_configpio(PIO_MCI1_DA3); /* Data 3 of Slot A */ + sam_configpio(PIO_MCI2_CK); /* Common SD clock */ + sam_configpio(PIO_MCI2_CDA); /* Command/Response of Slot A */ + + /* Enable the HSMCI2 peripheral clock This really should be done in + * sam_enable (as well as disabling peripheral clocks in sam_disable(). + */ + + sam_hsmci1_enableclk(); + + /* For DMA channel selection */ + + dmac = HSMCI2_DMAC; + pid = SAM_PID_HSMCI2; + } + else +#endif + { + DEBUGPANIC(); + return NULL; + } + + fvdbg("priv: %p base: %08x hsmci: %d dmac: %d pid: %d\n", + priv, priv->base, priv->hsmci, dmac, pid); + + /* Initialize the HSMCI slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + + /* Initialize the callbacks */ + + memcpy(&priv->dev, &g_callbacks, sizeof(struct sdio_dev_s)); + + /* Allocate a DMA channel */ + + priv->dma = sam_dmachannel(dmac, DMA_FLAGS(pid)); + DEBUGASSERT(priv->dma); + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + sam_reset(&priv->dev); + return &priv->dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- possibly from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status. Interrupts are disabled here because if we are + * not called from an interrupt handler, then the following steps must + * still be atomic. + */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + fllvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + sam_callback(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is write protected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} + +#endif /* CONFIG_SAMA5_HSMCI0 || CONFIG_SAMA5_HSMCI1 || CONFIG_SAMA5_HSMCI2 */ diff --git a/arch/arm/src/sama5/sam_hsmci.h b/arch/arm/src/sama5/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..c28bf89594f6c3894099cb752c7f25ee3946dde1 --- /dev/null +++ b/arch/arm/src/sama5/sam_hsmci.h @@ -0,0 +1,177 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_hsmci.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAMA5_SAM_HSMCI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * NOTE: The primary use of this function is for cases where the clock + * frequencies are not known a priori and so HSMCI clock dividers must + * be determined dynamically. This is the case, for example, when we + * execute out of SDRAM. In that case, the clocking was set up by the + * bootloader that brought us into SDRAM and it is that bootloader that + * has configured the clocking. + * + * Input parameters: + * target - The target SD frequency + * + * Returned Value: + * A bitset containing the CLKDIV and CLKODD bits as needed to configure + * the HSMCI clock output. + * + ****************************************************************************/ + +uint32_t sam_hsmci_clkdiv(uint32_t target); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- possibly from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_HSMCI_H */ diff --git a/arch/arm/src/sama5/sam_hsmci_clkdiv.c b/arch/arm/src/sama5/sam_hsmci_clkdiv.c new file mode 100644 index 0000000000000000000000000000000000000000..4ddba13e82b8da3b4514869a8336dddfea447c21 --- /dev/null +++ b/arch/arm/src/sama5/sam_hsmci_clkdiv.c @@ -0,0 +1,141 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pmc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "chip.h" +#include "chip/sam_hsmci.h" +#include "sam_hsmci.h" + +#if defined(CONFIG_SAMA5_HSMCI0) || defined(CONFIG_SAMA5_HSMCI1) || \ + defined(CONFIG_SAMA5_HSMCI2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * NOTE: The primary use of this function is for cases where the clock + * frequencies are not known a priori and so HSMCI clock dividers must + * be determined dynamically. This is the case, for example, when we + * execute out of SDRAM. In that case, the clocking was set up by the + * bootloader that brought us into SDRAM and it is that bootloader that + * has configured the clocking. + * + * Input parameters: + * target - The target SD frequency + * + * Returned Value: + * A bitset containing the CLKDIV and CLKODD bits as needed to configure + * the HSMCI clock output. + * + ****************************************************************************/ + +uint32_t sam_hsmci_clkdiv(uint32_t target) +{ + uint32_t clkfulldiv; + uint32_t ret; + + /* Get the largest divisor does not exceed the target value */ + + clkfulldiv = (BOARD_MCK_FREQUENCY + target - 1) / target; + + if (clkfulldiv > 2) + { + clkfulldiv -= 2; + } + else + { + clkfulldiv = 0; + } + + if (clkfulldiv > 511) + { + clkfulldiv = 511; + } + + ret = (clkfulldiv >> 1) << HSMCI_MR_CLKDIV_SHIFT; + if ((clkfulldiv & 1) != 0) + { + ret |= HSMCI_MR_CLKODD; + } + + return ret; +} + +#endif /* CONFIG_SAMA5_HSMCI0 || CONFIG_SAMA5_HSMCI1 || CONFIG_SAMA5_HSMCI2 */ diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..21ce68ff236dbe29458a80cc8d4ba9fde796d940 --- /dev/null +++ b/arch/arm/src/sama5/sam_irq.c @@ -0,0 +1,912 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_irq.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#ifdef CONFIG_SAMA5_PIO_IRQ +# include "sam_pio.h" +#endif + +#include "chip.h" +#include "mmu.h" +#include "cache.h" +#include "sctlr.h" +#include "chip/sam_aic.h" +#include "chip/sam_matrix.h" +#include "chip/sam_aximx.h" +#include "chip/sam_sfr.h" + +#include "sam_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private types + ****************************************************************************/ + +typedef uint32_t *(*doirq_t)(int irq, uint32_t *regs); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* Symbols defined via the linker script */ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_srctype[SCRTYPE_NTYPES] = +{ + 0, 0, 1, 1, 2, 3 +}; + +/* This is an arry of bit maps that can be used to quickly determine is the + * peripheral identified by its PID is served by H64MX or H32MX. Then the + * appropriate MATRIX SPSELR register can be consulted to determine if the + * peripheral interrupts are secured or not. + */ + +#if defined(CONFIG_SAMA5_SAIC) +static const uint32_t g_h64mxpids[3] = +{ + H64MX_SPSELR0_PIDS, H64MX_SPSELR1_PIDS, H64MX_SPSELR2_PIDS +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dumpaic + * + * Description: + * Dump some interesting AIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void sam_dumpaic(const char *msg, uintptr_t base, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("AIC (%s, base=%08x irq=%d):\n", msg, base, irq); + + /* Select the register set associated with this irq */ + + putreg32(irq, base + SAM_AIC_SSR_OFFSET); + + /* Then dump all of the (readable) register contents */ + + lldbg(" SSR: %08x SMR: %08x SVR: %08x IVR: %08x\n", + getreg32(base + SAM_AIC_SSR_OFFSET), + getreg32(base + SAM_AIC_SMR_OFFSET), + getreg32(base + SAM_AIC_SVR_OFFSET), + getreg32(base + SAM_AIC_IVR_OFFSET)); + lldbg(" FVR: %08x ISR: %08x\n", + getreg32(base + SAM_AIC_FVR_OFFSET), + getreg32(base + SAM_AIC_ISR_OFFSET)); + lldbg(" IPR: %08x %08x %08x %08x\n", + getreg32(base + SAM_AIC_IPR0_OFFSET), + getreg32(base + SAM_AIC_IPR1_OFFSET), + getreg32(base + SAM_AIC_IPR2_OFFSET), + getreg32(base + SAM_AIC_IPR3_OFFSET)); + + /* SAMA5D4 does not have the FFSR register */ + +#if defined(SAM_AIC_FFSR) + lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n", + getreg32(base + SAM_AIC_IMR_OFFSET), + getreg32(base + SAM_AIC_CISR_OFFSET), + getreg32(base + SAM_AIC_SPU_OFFSET), + getreg32(base + SAM_AIC_FFSR_OFFSET)); +#else + lldbg(" IMR: %08x CISR: %08x SPU: %08x\n", + getreg32(base + SAM_AIC_IMR_OFFSET), + getreg32(base + SAM_AIC_CISR_OFFSET), + getreg32(base + SAM_AIC_SPU_OFFSET)); +#endif + + lldbg(" DCR: %08x WPMR: %08x WPSR: %08x\n", + getreg32(base + SAM_AIC_DCR_OFFSET), + getreg32(base + SAM_AIC_WPMR_OFFSET), + getreg32(base + SAM_AIC_WPSR_OFFSET)); + + leave_critical_section(flags); +} +#else +# define sam_dumpaic(msg, base, irq) +#endif + +/**************************************************************************** + * Name: sam_vectorsize + * + * Description: + * Return the size of the vector data + * + ****************************************************************************/ + +static inline size_t sam_vectorsize(void) +{ + uintptr_t src; + uintptr_t end; + + src = (uintptr_t)&_vector_start; + end = (uintptr_t)&_vector_end; + + return (size_t)(end - src); +} + +/**************************************************************************** + * Name: sam_spurious + * + * Description: + * Spurious interrupt handler. + * + * Paragraph 17.8.6, Spurious Interrupt: "The Advanced Interrupt Controller + * features protection against spurious interrupts. A spurious interrupt is + * defined as being the assertion of an interrupt source long enough for the + * AIC to assert the nIRQ, but no longer present when AIC_IVR is read. This + * is most prone to occur when: + * + * o An external interrupt source is programmed in level-sensitive mode + * and an active level occurs for only a short time. + * o An internal interrupt source is programmed in level sensitive and + * the output signal of the corresponding embedded peripheral is + * activated for a short time. (As in the case for the Watchdog.) + * o An interrupt occurs just a few cycles before the software begins to + * mask it, thus resulting in a pulse on the interrupt source. + * + * "The AIC detects a spurious interrupt at the time the AIC_IVR is read + * while no enabled interrupt source is pending. When this happens, the AIC + * returns the value stored by the programmer in AIC_SPU (Spurious Vector + * Register). The programmer must store the address of a spurious interrupt + * handler in AIC_SPU as part of the application, to enable an as fast as + * possible return to the normal execution flow. This handler writes in + * AIC_EOICR and performs a return from interrupt." + * + ****************************************************************************/ + +static uint32_t *sam_spurious(int irq, uint32_t *regs) +{ + /* This is probably irrelevant since true vectored interrupts are not used + * in this implementation. The value of AIC_IVR is ignored. + */ + +#if defined(CONFIG_DEBUG_IRQ) + lldbg("Spurious interrupt: IRQ %d\n", irq); +#endif + return regs; +} + +/**************************************************************************** + * Name: sam_fiqhandler + * + * Description: + * Default FIQ interrupt handler. + * + ****************************************************************************/ + +static uint32_t *sam_fiqhandler(int irq, uint32_t *regs) +{ + /* Dispatch the FIQ */ + + return arm_doirq(SAM_IRQ_FIQ, regs); +} + +/**************************************************************************** + * Name: sam_aic_issecure + * + * Description: + * Return true if the peripheral secure. + * + * Input Parameter: + * PID = IRQ number + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SAIC) +static bool sam_aic_issecure(uint32_t irq) +{ + uintptr_t regaddr; + uint32_t bit; + unsigned int regndx; + + /* Get the register index and bit mask */ + + regndx = (irq >> 5); + bit = ((uint32_t)1 << (irq & 0x1f)); + + /* Get the SPSELR register address */ + + DEBUGASSERT(regndx < 3); + if ((g_h64mxpids[regndx] & bit) != 0) + { + /* H64MX. Use Matrix 0 */ + + regaddr = SAM_MATRIX0_SPSELR(regndx); + } + else + { + /* H32MX. Use Matrix 1 */ + + regaddr = SAM_MATRIX1_SPSELR(regndx); + } + + /* Return true if the bit corresponding to this IRQ is zero */ + + return (getreg32(regaddr) & bit) == 0; +} +#endif + +/**************************************************************************** + * Name: sam_aic_redirection + * + * Description: + * Redirect all interrupts to the AIC. This function is only compiled if + * (1) the architecture supports an SAIC (CONFIG_SAMA5_HAVE_SAIC), but (2) + * Use of the SAIC has not been selected (!CONFIG_SAMA5_SAIC). + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_HAVE_SAIC) && !defined(CONFIG_SAMA5_SAIC) +static void sam_aic_redirection(void) +{ + unsigned int regval; + + /* Check if interrupts are already redirected to the AIC */ + + regval = getreg32(SAM_SFR_AICREDIR); + if ((regval & SFR_AICREDIR_ENABLE) == 0) + { + /* Enable redirection of all interrupts to the AIC */ + + regval = getreg32(SAM_SFR_SN1); + regval ^= SFR_AICREDIR_KEY; + regval |= SFR_AICREDIR_ENABLE; + putreg32(regval, SAM_SFR_AICREDIR); + +#if defined(CONFIG_DEBUG_IRQ) + /* Check if redirection was successfully enabled */ + + regval = getreg32(SAM_SFR_AICREDIR); + lldbg("Interrupts %s redirected to the AIC\n", + (regval & SFR_AICREDIR_ENABLE) != 0 ? "ARE" : "NOT"); +#endif + } +} +#else +# define sam_aic_redirection() +#endif + +/**************************************************************************** + * Name: sam_aic_initialize + * + * Description: + * Initialize the AIC or the SAIC. + * + ****************************************************************************/ + +static void sam_aic_initialize(uintptr_t base) +{ + int i; + + /* Unprotect SMR, SVR, SPU and DCR register */ + + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); + + /* Configure the FIQ and the IRQs. */ + + for (i = 0; i < SAM_IRQ_NINT; i++) + { + /* Select the interrupt registers */ + + putreg32(i, base + SAM_AIC_SSR_OFFSET); + + /* Disable the interrupt */ + + putreg32(AIC_IDCR_INTD, base + SAM_AIC_IDCR_OFFSET); + + /* Set the (unused) FIQ/IRQ handler */ + + if (i == SAM_PID_FIQ) + { + putreg32((uint32_t)sam_fiqhandler, base + SAM_AIC_SVR_OFFSET); + } + else + { + putreg32((uint32_t)arm_doirq, base + SAM_AIC_SVR_OFFSET); + } + + /* Set the default interrupt priority */ + + putreg32(SAM_DEFAULT_PRIOR, base + SAM_AIC_SMR_OFFSET); + + /* Clear any pending interrupt */ + + putreg32(AIC_ICCR_INTCLR, base + SAM_AIC_ICCR_OFFSET); + } + + /* Set the (unused) spurious interrupt handler */ + + putreg32((uint32_t)sam_spurious, base + SAM_AIC_SPU_OFFSET); + + /* Perform 8 interrupt acknowledgements by writing any value to the + * EOICR register. + */ + + for (i = 0; i < 8; i++) + { + putreg32(AIC_EOICR_ENDIT, base + SAM_AIC_EOICR_OFFSET); + } + + /* Restore protection and the interrupt state */ + + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * This function is called by up_initialize() during the bring-up of the + * system. It is the responsibility of this function to but the interrupt + * subsystem into the working and ready state. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ +#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) + size_t vectorsize; +#endif + + /* The following operations need to be atomic, but since this function is + * called early in the initialization sequence, we expect to have exclusive + * access to the AIC. + */ + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Redirect all interrupts to the AIC if so configured */ + + sam_aic_redirection(); + + /* Initialize the Advanced Interrupt Controller (AIC) */ + + sam_aic_initialize(SAM_AIC_VBASE); + +#if defined(CONFIG_SAMA5_SAIC) + /* Initialize the Secure Advanced Interrupt Controller (SAIC) */ + + sam_aic_initialize(SAM_SAIC_VBASE); + +#endif + +#if defined(CONFIG_ARCH_LOWVECTORS) + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are three ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. A second way is to map the use the AXI MATRIX remap register to + * map physical address zero to the beginning of the text region, + * either internal SRAM or EBI CS 0. Then we can set an identity + * mapping to map the boot region at 0x0000:0000 to virtual address + * 0x0000:00000. VBAR == 0x0000:0000. + * + * This method is used when booting from ISRAM or NOR FLASH. In + * that case, vectors must lie at the beginning of NOFR FLASH. + * + * 3. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * This is the method used when booting from SDRAM. + * + * - When executing from NOR FLASH, the first level bootloader is supposed + * to provide the AXI MATRIX mapping for us at boot time base on the state + * of the BMS pin. However, I have found that in the test environments + * that I use, I cannot always be assured of that physical address mapping. + * + * - If we are executing out of ISRAM, then the SAMA5 primary bootloader + * probably copied us into ISRAM and set the AXI REMAP bit for us. + * + * - If we are executing from external SDRAM, then a secondary bootloader + * must have loaded us into SDRAM. In this case, simply set the VBAR + * register to the address of the vector table (not necessary at the + * beginning or SDRAM). + */ + +#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) + /* Set the vector base address register to 0x0000:0000 */ + + cp15_wrvbar(0); + +#if 0 /* Disabled on reset */ + /* Disable MATRIX write protection */ + + putreg32(MATRIX_WPMR_WPKEY, SAM_MATRIX_WPMR); +#endif + + /* Set remap state 0 if we are running from internal SRAM or from SDRAM. + * If we booted into NOR FLASH, then the first level bootloader should + * have already provided this mapping for us. + * + * This is done late in the boot sequence. Any exceptions taken before + * this point in time will be handled by the ROM code, not by the NuttX + * interrupt since which was, up to this point, uninitialized. + * + * Boot state: ROM is seen at address 0x00000000 + * Remap State 0: SRAM is seen at address 0x00000000 (through AHB slave + * interface) instead of ROM. + * Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave + * interface) instead of ROM for external boot. + * + * Here we are assuming that vectors reside in the lower end of ISRAM. + * Hmmm... this probably does not matter since we will map a page to + * address 0x0000:0000 in that case anyway. + */ + +#ifdef ATSAMA5D3 + putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable Cortex-A5 remap */ +#endif + +#if defined(CONFIG_SAMA5_BOOT_ISRAM) + putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */ +#elif defined(ATSAMA5D3) /* && defined(CONFIG_SAMA5_BOOT_CS0FLASH) */ + putreg32(AXIMX_REMAP_REMAP1, SAM_AXIMX_REMAP); /* Remap NOR FLASH on CS0 */ +#endif + + /* Make sure that there is no trace of any previous mapping (here we + * that the L2 cache has not yet been enabled. + */ + + vectorsize = sam_vectorsize(); + cp15_invalidate_icache(); + cp15_invalidate_dcache(0, vectorsize); + mmu_invalidate_region(0, vectorsize); + +#if 0 /* Disabled on reset */ + /* Restore MATRIX write protection */ + + putreg32(MATRIX_WPMR_WPKEY | MATRIX_WPMR_WPEN, SAM_MATRIX_WPMR); +#endif + +#elif defined(CONFIG_SAMA5_BOOT_SDRAM) + /* Set the VBAR register to the address of the vector table in SDRAM */ + + DEBUGASSERT((((uintptr_t)&_vector_start) & ~VBAR_MASK) == 0); + cp15_wrvbar((uint32_t)&_vector_start); + +#endif /* CONFIG_SAMA5_BOOT_ISRAM || CONFIG_SAMA5_BOOT_CS0FLASH */ +#endif /* CONFIG_ARCH_LOWVECTORS */ + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * PIO pins. + */ + +#ifdef CONFIG_SAMA5_PIO_IRQ + sam_pioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + (void)up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: arm_decodeirq, arm_decodefiq (and sam_decodeirq helper). + * + * Description: + * This function is called from the IRQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +static uint32_t *sam_decodeirq(uintptr_t base, uint32_t *regs) +{ + uint32_t irqid; + uint32_t ivr; + + /* Paragraph 17.8.5 Protect Mode: "The Protect Mode permits reading the + * Interrupt Vector Register without performing the associated automatic + * operations. ... Writing PROT in AIC_DCR (Debug Control Register) at 0x1 + * enables the Protect Mode. + * + * "When the Protect Mode is enabled, the AIC performs interrupt stacking + * only when a write access is performed on the AIC_IVR. Therefore, the + * Interrupt Service Routines must write (arbitrary data) to the AIC_IVR + * just after reading it. The new context of the AIC, including the value + * of the Interrupt Status Register (AIC_ISR), is updated with the current + * interrupt only when AIC_IVR is written. ..." + * + * "To summarize, in normal operating mode, the read of AIC_IVR performs the + * following operations within the AIC: + * + * 1. Calculates active interrupt (higher than current or spurious). + * 2. Determines and returns the vector of the active interrupt. + * 3. Memorizes the interrupt. + * 4. Pushes the current priority level onto the internal stack. + * 5. Acknowledges the interrupt. + * + * "However, while the Protect Mode is activated, only operations 1 to 3 are + * performed when AIC_IVR is read. Operations 4 and 5 are only performed by + * the AIC when AIC_IVR is written. + * + * "Software that has been written and debugged using the Protect Mode runs + * correctly in Normal Mode without modification. However, in Normal Mode the + * AIC_IVR write has no effect and can be removed to optimize the code. + */ + + /* Write in the IVR to support Protect Mode */ + + ivr = getreg32(base + SAM_AIC_IVR_OFFSET); + putreg32(ivr, base + SAM_AIC_IVR_OFFSET); + + /* Get the IRQ number from the interrupt status register. NOTE that the + * IRQ number is the same is the peripheral ID (PID). + */ + + irqid = getreg32(base + SAM_AIC_ISR_OFFSET) & AIC_ISR_MASK; + + /* Dispatch the interrupt */ + + regs = ((doirq_t)ivr)((int)irqid, regs); + + /* Acknowledge interrupt */ + + putreg32(AIC_EOICR_ENDIT, base + SAM_AIC_EOICR_OFFSET); + return regs; +} + +/* This is the entry point from the ARM IRQ vector handler */ + +uint32_t *arm_decodeirq(uint32_t *regs) +{ + return sam_decodeirq(SAM_AIC_VBASE, regs); +} + +#if defined(CONFIG_SAMA5_SAIC) +/* This is the entry point from the ARM FIQ vector handler */ + +uint32_t *arm_decodefiq(FAR uint32_t *regs) +{ + uint32_t *ret; + + /* In order to distinguish a FIQ from a true secure interrupt we need to + * check the state of the FIQ line in the SAIC_CISR register. + */ + + if ((getreg32(SAM_SAIC_CISR) & AIC_CISR_NFIQ) != 0) + { + /* Handle the FIQ */ + + ret = arm_doirq(SAM_IRQ_FIQ, regs); + + /* Acknowledge interrupt */ + + putreg32(AIC_EOICR_ENDIT, SAM_SAIC_EOICR); + } + else + { + /* Handle the IRQ */ + + ret = sam_decodeirq(SAM_SAIC_VBASE, regs); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: up_disable_irq (and sam_disable_irq helper) + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +static void sam_disable_irq(uintptr_t base, int irq) +{ + irqstate_t flags; + + if (irq < SAM_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Select the register set associated with this irq */ + + putreg32(irq, base + SAM_AIC_SSR_OFFSET); + + /* Disable the interrupt */ + + putreg32(AIC_IDCR_INTD, base + SAM_AIC_IDCR_OFFSET); + sam_dumpaic("disable", base, irq); + leave_critical_section(flags); + } +#ifdef CONFIG_SAMA5_PIO_IRQ + else + { + /* Maybe it is a (derived) PIO IRQ */ + + sam_pioirqdisable(irq); + } +#endif +} + +void up_disable_irq(int irq) +{ +#if defined(CONFIG_SAMA5_SAIC) + if (sam_aic_issecure(irq)) + { + sam_disable_irq(SAM_SAIC_VBASE, irq); + } + else +#endif + { + sam_disable_irq(SAM_AIC_VBASE, irq); + } +} + +/**************************************************************************** + * Name: up_enable_irq (and sam_enable_irq helper) + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +static void sam_enable_irq(uintptr_t base, int irq) +{ + irqstate_t flags; + + if (irq < SAM_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Select the register set associated with this irq */ + + putreg32(irq, base + SAM_AIC_SSR_OFFSET); + + /* Enable the interrupt */ + + putreg32(AIC_IECR_INTEN, base + SAM_AIC_IECR_OFFSET); + sam_dumpaic("enable", base, irq); + leave_critical_section(flags); + } +#ifdef CONFIG_SAMA5_PIO_IRQ + else + { + /* Maybe it is a (derived) PIO IRQ */ + + sam_pioirqenable(irq); + } +#endif +} + +void up_enable_irq(int irq) +{ +#if defined(CONFIG_SAMA5_SAIC) + if (sam_aic_issecure(irq)) + { + sam_enable_irq(SAM_SAIC_VBASE, irq); + } + else +#endif + { + sam_enable_irq(SAM_AIC_VBASE, irq); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq (and sam_prioritize_irq helper) + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +static int sam_prioritize_irq(uint32_t base, int irq, int priority) +{ + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(irq < SAM_IRQ_NINT && (unsigned)priority <= AIC_SMR_PRIOR_MASK); + if (irq < SAM_IRQ_NINT) + { + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Select the register set associated with this irq */ + + putreg32(irq, base + SAM_AIC_SSR_OFFSET); + + /* Unprotect and write the SMR register */ + + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); + + /* Set the new priority, preserving the current srctype */ + + regval = getreg32(base + SAM_AIC_SMR_OFFSET); + regval &= ~AIC_SMR_PRIOR_MASK; + regval |= (uint32_t)priority << AIC_SMR_PRIOR_SHIFT; + putreg32(regval, base + SAM_AIC_SMR_OFFSET); + + /* Restore protection and the interrupt state */ + + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); + sam_dumpaic("prioritize", base, irq); + leave_critical_section(flags); + } + + return OK; +} + +int up_prioritize_irq(int irq, int priority) +{ +#if defined(CONFIG_SAMA5_SAIC) + if (sam_aic_issecure(irq)) + { + sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority); + } + else +#endif + { + sam_prioritize_irq(SAM_AIC_VBASE, irq, priority); + } +} +#endif + +/**************************************************************************** + * Name: sam_irq_srctype (and _sam_irq_srctype helper) + * + * Description: + * irq - Identifies the IRQ source to be configured + * srctype - IRQ source configuration + * + ****************************************************************************/ + +static void _sam_irq_srctype(uintptr_t base, int irq, + enum sam_srctype_e srctype) +{ + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(irq < SAM_IRQ_NINT && (unsigned)srctype < SCRTYPE_NTYPES); + + /* These operations must be atomic */ + + flags = enter_critical_section(); + + /* Select the register set associated with this irq */ + + putreg32(irq, base + SAM_AIC_SSR_OFFSET); + + /* Unprotect and write the SMR register */ + + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); + + /* Set the new srctype, preserving the current priority */ + + regval = getreg32(base + SAM_AIC_SMR_OFFSET); + regval &= ~AIC_SMR_SRCTYPE_MASK; + regval |= (uint32_t)g_srctype[srctype] << AIC_SMR_SRCTYPE_SHIFT; + putreg32(regval, base + SAM_AIC_SMR_OFFSET); + + /* Restore protection and the interrupt state */ + + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); + sam_dumpaic("srctype", base, irq); + leave_critical_section(flags); +} + +void sam_irq_srctype(int irq, enum sam_srctype_e srctype) +{ +#if defined(CONFIG_SAMA5_SAIC) + if (sam_aic_issecure(irq)) + { + _sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype); + } + else +#endif + { + _sam_irq_srctype(SAM_AIC_VBASE, irq, srctype); + } +} diff --git a/arch/arm/src/sama5/sam_irq.h b/arch/arm/src/sama5/sam_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..5f462862d0061f201a2ca6c9513ee6d67be176e5 --- /dev/null +++ b/arch/arm/src/sama5/sam_irq.h @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_irq.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_IRQ_H +#define __ARCH_ARM_SRC_SAMA5_SAM_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/sam_aic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCRTYPE_NTYPES 6 +#define SAM_DEFAULT_PRIOR ((AIC_SMR_PRIOR_MAX+1) >> 1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum sam_srctype_e +{ + SRCTYPE_IHIGH = 0, /* Internal high level */ + SRCTYPE_XLOW = 1, /* External low level */ + SRCTYPE_IRISING = 2, /* Internal positive edge */ + SRCTYPE_XFALLING = 3, /* External negative edge */ + SRCTYPE_XHIGH = 4, /* External high level */ + SRCTYPE_XRISING = 5 /* External rising edge */ +}; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_irq_srctype + * + * Description: + * irq - Identifies the IRQ source to be configured + * srctype - IRQ source configuration + * + ****************************************************************************/ + +void sam_irq_srctype(int irq, enum sam_srctype_e srctype); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_IRQ_H */ diff --git a/arch/arm/src/sama5/sam_isi.c b/arch/arm/src/sama5/sam_isi.c new file mode 100644 index 0000000000000000000000000000000000000000..124734a416cc389bcd6b6871659a14512b41d5b2 --- /dev/null +++ b/arch/arm/src/sama5/sam_isi.c @@ -0,0 +1,183 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_isi.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "sam_memories.h" +#include "sam_pio.h" +#include "sam_pck.h" +#include "sam_isi.h" + +#ifdef CONFIG_SAMA5_ISI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The sensor master clock (ISI_MCK) is generated by the Advanced Power + * Management Controller (APMC) through a Programmable Clock output. + */ + +#ifndef CONFIG_ISI_MCKFREQ +# error "CONFIG_ISI_MCKFREQ must be defined" +#endif + +#if defined(CONFIG_ISI_PCK0) +# define ISI_PCKID PCK0 +#elif defined(CONFIG_ISI_PCK1) +# define ISI_PCKID PCK1 +#elif defined(CONFIG_ISI_PCK2) +# define ISI_PCKID PCK2 +#else +# error "No valid PCK selection" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure defines the overall state of the ISI interface */ + +struct sam_isi_s +{ + uint32_t actual; /* Acutal ISI_MCK frequency */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ISI interface state */ + +static struct sam_isi_s g_isi; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_isi_initialize + * + * Description: + * Initialize the ISI driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_isi_initialize(void) +{ + int ret; + + /* Configure PIO pins for the ISI (outputs) */ + /* Data pins */ + + (void)sam_configpio(PIO_ISI_D0); + (void)sam_configpio(PIO_ISI_D1); + (void)sam_configpio(PIO_ISI_D2); + (void)sam_configpio(PIO_ISI_D3); + (void)sam_configpio(PIO_ISI_D4); + (void)sam_configpio(PIO_ISI_D5); + (void)sam_configpio(PIO_ISI_D6); + (void)sam_configpio(PIO_ISI_D7); + (void)sam_configpio(PIO_ISI_D8); + (void)sam_configpio(PIO_ISI_D9); + (void)sam_configpio(PIO_ISI_D10); + (void)sam_configpio(PIO_ISI_D11); + + /* Horizontal and vertical sync pins (inputs) */ + + (void)sam_configpio(PIO_ISI_HSYNC); + (void)sam_configpio(PIO_ISI_VSYNC); + + /* Pixel clock input (ISI_PCK, not to be confused with the processor clock + * (PCK) or the programmable clock (PCK). + * + * NOTE: "Several parts of the ISI controller use the pixel clock provided + * by the image sensor (ISI_PCK). Thus the user must first program the + * image sensor to provide this clock (ISI_PCK) before programming the + * Image Sensor Controller." + */ + + (void)sam_configpio(PIO_ISI_PCK); + + /* Configure ISI_MCK programmable clock output. + * + * REVISIT: Might this not be needed before the image sensor is + * initialized? + */ + + g_isi.actual = sam_pck_configure(ISI_PCKID, PCKSRC_MCK, CONFIG_ISI_MCKFREQ); + gvdbg("PCK%d frequency=%d actual=%d\n", + ISI_PCKID, CONFIG_ISI_MCKFREQ, g_isi.actual); + + /* Enable the MCK (output) */ + + sam_pck_enable(ISI_PCKID, true); + + /* Configure the pixel clock */ +#warning Missing logic + + /* Configure color */ +#warning Missing logic + + /* Configure decimation */ +#warning Missing logic + + /* Configure DMA */ +#warning Missing logic +} + +#endif /* CONFIG_SAMA5_ISI */ diff --git a/arch/arm/src/sama5/sam_isi.h b/arch/arm/src/sama5/sam_isi.h new file mode 100644 index 0000000000000000000000000000000000000000..5b3bc7482fc950c1cb7d4a9b98bd4f19d91c338d --- /dev/null +++ b/arch/arm/src/sama5/sam_isi.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_isi.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_ISI_H +#define __ARCH_ARM_SRC_SAMA5_SAM_ISI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_isi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: sam_isi_initialize + * + * Description: + * Initialize the ISI driver. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_ISI +int sam_isi_initialize(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ISI_H */ diff --git a/arch/arm/src/sama5/sam_lcd.c b/arch/arm/src/sama5/sam_lcd.c new file mode 100644 index 0000000000000000000000000000000000000000..c41d880d546a7111afdb2cd3809046c64046657c --- /dev/null +++ b/arch/arm/src/sama5/sam_lcd.c @@ -0,0 +1,3086 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_lcd.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "chip/sam_lcdc.h" +#include "chip/sam_pinmap.h" +#include "sam_pio.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_lcd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAMA5_LCDC_DEFBACKLIGHT +# define CONFIG_SAMA5_LCDC_DEFBACKLIGHT 0xf0 +#endif +#define SAMA5_LCDC_BACKLIGHT_OFF 0x00 + +#if defined(CONFIG_FB_HWCURSOR) && !defined(CONFIG_SAMA5_LCDC_HCR) +# error CONFIG_FB_HWCURSOR=y but CONFIG_SAMA5_LCDC_HCR=n +#elif !defined(CONFIG_FB_HWCURSOR) && defined(CONFIG_SAMA5_LCDC_HCR) +# error CONFIG_FB_HWCURSOR=n but CONFIG_SAMA5_LCDC_HCR=y +#endif + +/* Color/video formats */ + +#if defined(CONFIG_SAMA5_LCDC_BASE_RGB444) +# define SAMA5_LCDC_BASE_BPP 16 /* 12BPP but must be 16-bit aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT FB_FMT_RGB12_444 +#elif defined(CONFIG_SAMA5_LCDC_BASE_ARGB4444) +# define SAMA5_LCDC_BASE_BPP 16 +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGBA4444) +# define SAMA5_LCDC_BASE_BPP 16 +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGB565) +# define SAMA5_LCDC_BASE_BPP 16 +# define SAMA5_LCDC_BASE_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_SAMA5_LCDC_BASE_TRGB1555) +# define SAMA5_LCDC_BASE_BPP 16 +# define SAMA5_LCDC_BASE_COLOR_FMT FB_FMT_RGBT16 +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGB666) +# define SAMA5_LCDC_BASE_BPP 32 /* 18BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT RGB666 +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGB666P) +# define SAMA5_LCDC_BASE_BPP 24 /* 18BPP but must be byte aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_TRGB1666) +# define SAMA5_LCDC_BASE_BPP 32 /* 19BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_TRGBP) +# define SAMA5_LCDC_BASE_BPP 24 /* 19BPP but must be byte aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGB888P) +# define SAMA5_LCDC_BASE_BPP 24 +# define SAMA5_LCDC_BASE_COLOR_FMT FB_FMT_RGB24 +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGB888) +# define SAMA5_LCDC_BASE_BPP 32 +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_TRGB1888) +# define SAMA5_LCDC_BASE_BPP 32 /* 25BPP but must be byte aligned */ +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_ARGB8888) +# define SAMA5_LCDC_BASE_BPP 32 +# define SAMA5_LCDC_BASE_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_BASE_RGBA8888) +# define SAMA5_LCDC_BASE_BPP 32 +# define SAMA5_LCDC_BASE_COLOR_FMT FB_FMT_RGBA32 +#else +# error Undefined or unrecognized base color format +#endif + +#if defined(CONFIG_SAMA5_LCDC_OVR1_RGB444) +# define SAMA5_LCDC_OVR1_BPP 16 /* 12BPP but must be 16-bit aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT FB_FMT_RGB12_444 +#elif defined(CONFIG_SAMA5_LCDC_OVR1_ARGB4444) +# define SAMA5_LCDC_OVR1_BPP 16 +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGBA4444) +# define SAMA5_LCDC_OVR1_BPP 16 +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB565) +# define SAMA5_LCDC_OVR1_BPP 16 +# define SAMA5_LCDC_OVR1_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_SAMA5_LCDC_OVR1_TRGB1555) +# define SAMA5_LCDC_OVR1_BPP 16 +# define SAMA5_LCDC_OVR1_COLOR_FMT FB_FMT_RGBT16 +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB666) +# define SAMA5_LCDC_OVR1_BPP 32 /* 18BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT RGB666 +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB666P) +# define SAMA5_LCDC_OVR1_BPP 24 /* 18BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_TRGB1666) +# define SAMA5_LCDC_OVR1_BPP 32 /* 19BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_TRGBP) +# define SAMA5_LCDC_OVR1_BPP 24 /* 19BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB888P) +# define SAMA5_LCDC_OVR1_BPP 24 +# define SAMA5_LCDC_OVR1_COLOR_FMT FB_FMT_RGB24 +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB888) +# define SAMA5_LCDC_OVR1_BPP 32 +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_TRGB1888) +# define SAMA5_LCDC_OVR1_BPP 32 /* 25BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_ARGB8888) +# define SAMA5_LCDC_OVR1_BPP 32 +# define SAMA5_LCDC_OVR1_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR1_RGBA8888) +# define SAMA5_LCDC_OVR1_BPP 32 +# define SAMA5_LCDC_OVR1_COLOR_FMT FB_FMT_RGBA32 +#elif defined(CONFIG_SAMA5_LCDC_OVR1) +# error Undefined or unrecognized overlay 1 color format +#endif + +#if defined(CONFIG_SAMA5_LCDC_OVR2_RGB444) +# define SAMA5_LCDC_OVR2_BPP 16 /* 12BPP but must be 16-bit aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT FB_FMT_RGB12_444 +#elif defined(CONFIG_SAMA5_LCDC_OVR2_ARGB4444) +# define SAMA5_LCDC_OVR2_BPP 16 +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGBA4444) +# define SAMA5_LCDC_OVR2_BPP 16 +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB565) +# define SAMA5_LCDC_OVR2_BPP 16 +# define SAMA5_LCDC_OVR2_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_SAMA5_LCDC_OVR2_TRGB1555) +# define SAMA5_LCDC_OVR2_BPP 16 +# define SAMA5_LCDC_OVR2_COLOR_FMT FB_FMT_RGBT16 +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB666) +# define SAMA5_LCDC_OVR2_BPP 32 /* 18BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT RGB666 +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB666P) +# define SAMA5_LCDC_OVR2_BPP 24 /* 18BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_TRGB1666) +# define SAMA5_LCDC_OVR2_BPP 32 /* 19BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_TRGBP) +# define SAMA5_LCDC_OVR2_BPP 24 /* 19BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB888P) +# define SAMA5_LCDC_OVR2_BPP 24 +# define SAMA5_LCDC_OVR2_COLOR_FMT FB_FMT_RGB24 +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB888) +# define SAMA5_LCDC_OVR2_BPP 32 +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_TRGB1888) +# define SAMA5_LCDC_OVR2_BPP 32 /* 25BPP but must be byte aligned */ +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_ARGB8888) +# define SAMA5_LCDC_OVR2_BPP 32 +# define SAMA5_LCDC_OVR2_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_OVR2_RGBA8888) +# define SAMA5_LCDC_OVR2_BPP 32 +# define SAMA5_LCDC_OVR2_COLOR_FMT FB_FMT_RGBA32 +#elif defined(CONFIG_SAMA5_LCDC_OVR2) +# error Undefined or unrecognized overlay 2 color format +#endif + +#if defined(CONFIG_SAMA5_LCDC_HEO_RGB444) +# define SAMA5_LCDC_HEO_BPP 16 /* 12BPP but must be 16-bit aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT FB_FMT_RGB12_444 +#elif defined(CONFIG_SAMA5_LCDC_HEO_ARGB4444) +# define SAMA5_LCDC_HEO_BPP 16 +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGBA4444) +# define SAMA5_LCDC_HEO_BPP 16 +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGB565) +# define SAMA5_LCDC_HEO_BPP 16 +# define SAMA5_LCDC_HEO_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_SAMA5_LCDC_HEO_TRGB1555) +# define SAMA5_LCDC_HEO_BPP 16 +# define SAMA5_LCDC_HEO_COLOR_FMT FB_FMT_RGBT16 +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGB666) +# define SAMA5_LCDC_HEO_BPP 32 /* 18BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT RGB666 +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGB666P) +# define SAMA5_LCDC_HEO_BPP 24 /* 18BPP but must be byte aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_TRGB1666) +# define SAMA5_LCDC_HEO_BPP 32 /* 19BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_TRGBP) +# define SAMA5_LCDC_HEO_BPP 24 /* 19BPP but must be byte aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGB888P) +# define SAMA5_LCDC_HEO_BPP 24 +# define SAMA5_LCDC_HEO_COLOR_FMT FB_FMT_RGB24 +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGB888) +# define SAMA5_LCDC_HEO_BPP 32 +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_TRGB1888) +# define SAMA5_LCDC_HEO_BPP 32 /* 25BPP but must be byte aligned */ +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_ARGB8888) +# define SAMA5_LCDC_HEO_BPP 32 +# define SAMA5_LCDC_HEO_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HEO_RGBA8888) +# define SAMA5_LCDC_HEO_BPP 32 +# define SAMA5_LCDC_HEO_COLOR_FMT FB_FMT_RGBA32 +#elif defined(CONFIG_SAMA5_LCDC_HEO) +# error Undefined or unrecognized HEO color format +#endif + +#if defined(CONFIG_SAMA5_LCDC_HCR_RGB444) +# define SAMA5_LCDC_HCR_BPP 16 /* 12BPP but must be 16-bit aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT FB_FMT_RGB12_444 +#elif defined(CONFIG_SAMA5_LCDC_HCR_ARGB4444) +# define SAMA5_LCDC_HCR_BPP 16 +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGBA4444) +# define SAMA5_LCDC_HCR_BPP 16 +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGB565) +# define SAMA5_LCDC_HCR_BPP 16 +# define SAMA5_LCDC_HCR_COLOR_FMT FB_FMT_RGB16_565 +#elif defined(CONFIG_SAMA5_LCDC_HCR_TRGB1555) +# define SAMA5_LCDC_HCR_BPP 16 +# define SAMA5_LCDC_HCR_COLOR_FMT FB_FMT_RGBT16 +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGB666) +# define SAMA5_LCDC_HCR_BPP 32 /* 18BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT RGB666 +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGB666P) +# define SAMA5_LCDC_HCR_BPP 24 /* 18BPP but must be byte aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_TRGB1666) +# define SAMA5_LCDC_HCR_BPP 32 /* 19BPP but must be 32-bit aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_TRGBP) +# define SAMA5_LCDC_HCR_BPP 24 /* 19BPP but must be byte aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGB888P) +# define SAMA5_LCDC_HCR_BPP 24 +# define SAMA5_LCDC_HCR_COLOR_FMT FB_FMT_RGB24 +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGB888) +# define SAMA5_LCDC_HCR_BPP 32 +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_TRGB1888) +# define SAMA5_LCDC_HCR_BPP 32 /* 25BPP but must be byte aligned */ +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_ARGB8888) +# define SAMA5_LCDC_HCR_BPP 32 +# define SAMA5_LCDC_HCR_COLOR_FMT ??? /* No color format definition */ +#elif defined(CONFIG_SAMA5_LCDC_HCR_RGBA8888) +# define SAMA5_LCDC_HCR_BPP 32 +# define SAMA5_LCDC_HCR_COLOR_FMT FB_FMT_RGBA32 +#elif defined(CONFIG_SAMA5_LCDC_HCR) +# error Undefined or unrecognized cursor color format +#endif + +/* Framebuffer sizes in bytes */ + +#ifndef BOARD_LCDC_WIDTH +# error BOARD_LCDC_WIDTH must be defined in the board.h header file +#endif + +#ifndef BOARD_LCDC_HEIGHT +# error BOARD_LCDC_HEIGHT must be defined in the board.h header file +#endif + +#if SAMA5_LCDC_BASE_BPP == 16 +# define SAMA5_BASE_STRIDE ((BOARD_LCDC_WIDTH * 16 + 7) / 8) +#elif SAMA5_LCDC_BASE_BPP == 24 +# define SAMA5_BASE_STRIDE ((BOARD_LCDC_WIDTH * 24 + 7) / 8) +#elif SAMA5_LCDC_BASE_BPP == 32 +# define SAMA5_BASE_STRIDE ((BOARD_LCDC_WIDTH * 32 + 7) / 8) +#else +# error Undefined or unrecognized base resolution +#endif + +#define SAMA5_BASE_FBSIZE (SAMA5_BASE_STRIDE * BOARD_LCDC_HEIGHT) + +#ifdef CONFIG_SAMA5_LCDC_OVR1 +# ifndef CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH +# define CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH BOARD_LCDC_WIDTH +# endif + +# if CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH > BOARD_LCDC_WIDTH +# error Width of overlay 1 exceeds the width of the display +# endif + +# ifndef CONFIG_SAMA5_LCDC_OVR1_MAXHEIGHT +# define CONFIG_SAMA5_LCDC_OVR1_MAXHEIGHT BOARD_LCDC_HEIGHT +# endif + +# if CONFIG_SAMA5_LCDC_OVR1_MAXHEIGHT > BOARD_LCDC_HEIGHT +# error Height of overlay 1 exceeds the height of the display +# endif + +# if SAMA5_LCDC_OVR1_BPP == 16 +# define SAMA5_OVR1_STRIDE ((CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH * 16 + 7) / 8) +# elif SAMA5_LCDC_OVR1_BPP == 24 +# define SAMA5_OVR1_STRIDE ((CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH * 24 + 7) / 8) +# elif SAMA5_LCDC_OVR1_BPP == 32 +# define SAMA5_OVR1_STRIDE ((CONFIG_SAMA5_LCDC_OVR1_MAXWIDTH * 32 + 7) / 8) +# elif defined(CONFIG_SAMA5_LCDC_OVR1) +# error Undefined or unrecognized overlay 1 color resolution +# endif + +# define SAMA5_OVR1_FBSIZE (SAMA5_OVR1_STRIDE * CONFIG_SAMA5_LCDC_OVR1_MAXHEIGHT) + +#else +# define SAMA5_OVR1_FBSIZE (0) +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR2 +# ifndef CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH +# define CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH BOARD_LCDC_WIDTH +# endif + +# if CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH > BOARD_LCDC_WIDTH +# error Width of overlay 2 exceeds the width of the display +# endif + +# ifndef CONFIG_SAMA5_LCDC_OVR2_MAXHEIGHT +# define CONFIG_SAMA5_LCDC_OVR2_MAXHEIGHT BOARD_LCDC_HEIGHT +# endif + +# if CONFIG_SAMA5_LCDC_OVR2_MAXHEIGHT > BOARD_LCDC_HEIGHT +# error Height of overlay 2 exceeds the height of the display +# endif + +# if SAMA5_LCDC_OVR2_BPP == 16 +# define SAMA5_OVR2_STRIDE ((CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH * 16 + 7) / 8) +# elif SAMA5_LCDC_OVR2_BPP == 24 +# define SAMA5_OVR2_STRIDE ((CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH * 24 + 7) / 8) +# elif SAMA5_LCDC_OVR2_BPP == 32 +# define SAMA5_OVR2_STRIDE ((CONFIG_SAMA5_LCDC_OVR2_MAXWIDTH * 32 + 7) / 8) +# elif defined(CONFIG_SAMA5_LCDC_OVR2) +# error Undefined or unrecognized overlay 2 color resolution +# endif + +# define SAMA5_OVR2_FBSIZE (SAMA5_OVR2_STRIDE * CONFIG_SAMA5_LCDC_OVR2_MAXHEIGHT) + +#else +# define SAMA5_OVR2_FBSIZE (0) +#endif + +#ifdef CONFIG_SAMA5_LCDC_HEO +# ifndef CONFIG_SAMA5_LCDC_HEO_MAXWIDTH +# define CONFIG_SAMA5_LCDC_HEO_MAXWIDTH BOARD_LCDC_WIDTH +# endif + +# if CONFIG_SAMA5_LCDC_HEO_MAXWIDTH > BOARD_LCDC_WIDTH +# error Width of HEO exceeds the width of the display +# endif + +# ifndef CONFIG_SAMA5_LCDC_HEO_MAXHEIGHT +# define CONFIG_SAMA5_LCDC_HEO_MAXHEIGHT BOARD_LCDC_HEIGHT +# endif + +# if CONFIG_SAMA5_LCDC_HEO_MAXHEIGHT > BOARD_LCDC_HEIGHT +# error Height of HEO exceeds the height of the display +# endif + +# if SAMA5_LCDC_HEO_BPP == 16 +# define SAMA5_HEO_STRIDE ((CONFIG_SAMA5_LCDC_HEO_MAXWIDTH * 16 + 7) / 8) +# elif SAMA5_LCDC_HEO_BPP == 24 +# define SAMA5_HEO_STRIDE ((CONFIG_SAMA5_LCDC_HEO_MAXWIDTH * 24 + 7) / 8) +# elif SAMA5_LCDC_HEO_BPP == 32 +# define SAMA5_HEO_STRIDE ((CONFIG_SAMA5_LCDC_HEO_MAXWIDTH * 32 + 7) / 8) +# elif defined(CONFIG_SAMA5_LCDC_HEO) +# error Undefined or unrecognized HEO color resolution +# endif + +# define SAMA5_HEO_FBSIZE (SAMA5_HEO_STRIDE * CONFIG_SAMA5_LCDC_HEO_MAXHEIGHT) + +#else +# define SAMA5_HEO_FBSIZE (0) +#endif + +#ifdef CONFIG_SAMA5_LCDC_HCR +# ifndef CONFIG_SAMA5_LCDC_HCR_MAXWIDTH +# define CONFIG_SAMA5_LCDC_HCR_MAXWIDTH BOARD_LCDC_WIDTH +# endif + +# if CONFIG_SAMA5_LCDC_HCR_MAXWIDTH > BOARD_LCDC_WIDTH +# error Width of the hardware cursor exceeds the width of the display +# endif + +# ifndef CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT +# define CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT BOARD_LCDC_HEIGHT +# endif + +# if CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT > BOARD_LCDC_HEIGHT +# error Height of the hardware cursor exceeds the height of the display +# endif + +# if SAMA5_LCDC_HCR_BPP == 16 +# define SAMA5_HCR_STRIDE ((CONFIG_SAMA5_LCDC_HCR_MAXWIDTH * 16 + 7) / 8) +# elif SAMA5_LCDC_HCR_BPP == 24 +# define SAMA5_HCR_STRIDE ((CONFIG_SAMA5_LCDC_HCR_MAXWIDTH * 24 + 7) / 8) +# elif SAMA5_LCDC_HCR_BPP == 32 +# define SAMA5_HCR_STRIDE ((CONFIG_SAMA5_LCDC_HCR_MAXWIDTH * 32 + 7) / 8) +# elif defined(CONFIG_SAMA5_LCDC_HCR) +# error Undefined or unrecognized cursor color resolution +# endif + +# define SAMA5_HCR_FBSIZE (SAMA5_HCR_STRIDE * CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT) + +#else +# define SAMA5_HCR_FBSIZE (0) +#endif + +/* Total memory used for framebuffers */ + +#define SAMA5_TOTAL_FBSIZE (SAMA5_BASE_FBSIZE + SAMA5_OVR1_FBSIZE + \ + SAMA5_OVR2_FBSIZE + SAMA5_HEO_FBSIZE + \ + SAMA5_HCR_FBSIZE) + +/* Are size, position, and pixel stride support needed? */ + +#undef SAMA5_HAVE_POSITION /* The base layer has none of these */ +#undef SAMA5_HAVE_SIZE +#undef SAMA5_HAVE_PSTRIDE + +#if defined(CONFIG_SAMA5_LCDC_OVR1) || defined(CONFIG_SAMA5_LCDC_OVR2) || \ + defined(CONFIG_SAMA5_LCDC_HEO) +# define SAMA5_HAVE_POSITION 1 +# define SAMA5_HAVE_SIZE 1 +# define SAMA5_HAVE_PSTRIDE 1 +#elif defined(CONFIG_SAMA5_LCDC_HCR) +# define SAMA5_HAVE_POSITION 1 +# define SAMA5_HAVE_SIZE 1 +#endif + +/* Debug */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_LCDC_REGDEBUG +#endif + +/* LCDC flags */ + +#define LCDC_FLAG_BOTTOMUP (1 << 0) /* Rend bottom-up */ +#define LCDC_FLAG_RIGHTLEFT (1 << 1) /* Rend right-to-left */ + +/* Preallocated LCDC DMA structures and framebuffers */ +/* Base layer */ + +#define SAMA5_LCDC_BASE_DSCR (CONFIG_SAMA5_LCDC_FB_VBASE+0) + +/* Overlay 1/2 Layers */ + +#define SAMA5_LCDC_OVR2_DSCR (CONFIG_SAMA5_LCDC_FB_VBASE+SIZEOF_SAM_DSCR_S) +#define SAMA5_LCDC_OVR1_DSCR (CONFIG_SAMA5_LCDC_FB_VBASE+2*SIZEOF_SAM_DSCR_S) + +/* High End Overlay (HEO) Layer */ + +#define SAMA5_LCDC_HEO_DSCR (CONFIG_SAMA5_LCDC_FB_VBASE+3*SIZEOF_SAM_DSCR_S) + +/* Hardware cursor (HRC) Layer */ + +#define SAMA5_LCDC_HCR_DSCR (CONFIG_SAMA5_LCDC_FB_VBASE+6*SIZEOF_SAM_DSCR_S) + +#define SAMA5_LCDC_DSCR_SIZE (7*SIZEOF_SAM_DSCR_S) +#define SAMA5_LCDC_DSCR_END (CONFIG_SAMA5_LCDC_FB_VBASE+SAMA5_LCDC_DSCR_SIZE) + +/* Position the framebuffer memory in the center of the memory set aside. We + * will use any skirts before or after the framebuffer memory as a guard against + * wild framebuffer writes. + */ + +#define SAMA5_LCDC_BUFFER_SIZE (CONFIG_SAMA5_LCDC_FB_SIZE-SAMA5_LCDC_DSCR_SIZE) +#define SAMA5_LCDC_BUFFER_FREE (SAMA5_LCDC_BUFFER_SIZE-SAMA5_TOTAL_FBSIZE) +#define SAMA5_LCDC_BUFFER_START (SAMA5_LCDC_DSCR_END + SAMA5_LCDC_BUFFER_FREE/2) + +#if SAMA5_LCDC_BUFFER_FREE < 0 +# error "SAMA5_LCDC_BUFFER_SIZE not large enough for frame buffers" +#endif + +/* Base layer frame buffer */ + +#define SAMA5_LCDC_BUFFER_BASE SAMA5_LCDC_BUFFER_START +#define SAMA5_LCDC_ENDBUF_BASE (SAMA5_LCDC_BUFFER_BASE + SAMA5_BASE_FBSIZE) + +#ifdef CONFIG_SAMA5_LCDC_OVR1 +# define SAMA5_LCDC_BUFFER_OVR1 SAMA5_LCDC_ENDBUF_BASE +# define SAMA5_LCDC_ENDBUF_OVR1 (SAMA5_LCDC_BUFFER_OVR1 + SAMA5_OVR1_FBSIZE) +#else +# define SAMA5_LCDC_ENDBUF_OVR1 SAMA5_LCDC_ENDBUF_BASE +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR2 +# define SAMA5_LCDC_BUFFER_OVR2 SAMA5_LCDC_ENDBUF_OVR1 +# define SAMA5_LCDC_ENDBUF_OVR2 (SAMA5_LCDC_BUFFER_OVR2 + SAMA5_OVR2_FBSIZE) +#else +# define SAMA5_LCDC_ENDBUF_OVR2 SAMA5_LCDC_ENDBUF_OVR1 +#endif + +#ifdef CONFIG_SAMA5_LCDC_HEO +# define SAMA5_LCDC_BUFFER_HEO SAMA5_LCDC_ENDBUF_OVR2 +# define SAMA5_LCDC_ENDBUF_HEO (SAMA5_LCDC_BUFFER_HEO + SAMA5_HEO_FBSIZE) +#else +# define SAMA5_LCDC_ENDBUF_HEO SAMA5_LCDC_ENDBUF_OVR2 +#endif + +#ifdef CONFIG_SAMA5_LCDC_HCR +# define SAMA5_LCDC_BUFFER_HCR SAMA5_LCDC_ENDBUF_HEO +# define SAMA5_LCDC_ENDBUF_HCR (SAMA5_LCDC_BUFFER_HCR + SAMA5_HCR_FBSIZE) +#else +# define SAMA5_LCDC_ENDBUF_HCR SAMA5_LCDC_ENDBUF_HEO +#endif + +/* Layer helpers */ + +#ifdef SAMA5_HAVE_LCDC_HCRCH +# define LCDC_NLAYERS 5 +#else +# define LCDC_NLAYERS 4 +#endif + +#define LAYER(i) g_lcdc.layer[i] +#define LAYER_BASE g_lcdc.layer[LCDC_LAYER_BASE] +#define LAYER_OVR1 g_lcdc.layer[LCDC_LAYER_OVR1] +#define LAYER_OVR2 g_lcdc.layer[LCDC_LAYER_OVR2] +#define LAYER_HEO g_lcdc.layer[LCDC_LAYER_HEO] + +#ifdef SAMA5_HAVE_LCDC_HCRCH +# define LAYER_HCR g_lcdc.layer[LCDC_LAYER_HCR] +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This enumeration names each layer supported by the hardware */ + +enum sam_layer_e +{ + LCDC_LAYER_BASE = 0, /* LCD base layer, display fixed size image */ + LCDC_LAYER_OVR1, /* LCD Overlay 1 */ + LCDC_LAYER_OVR2, /* LCD Overlay 2 */ + LCDC_LAYER_HEO /* LCD HighEndOverlay, support resize */ +#ifdef SAMA5_HAVE_LCDC_HCRCH + , LCDC_LAYER_HCR /* LCD Cursor, max size 128x128 */ +#endif +}; + +/* Possible rotations supported by all layers */ + +enum sam_rotation_e +{ + LCDC_ROT_0 = 0, /* LCD base layer, display fixed size image */ + LCDC_ROT_90, /* LCD Overlay 1 */ + LCDC_ROT_180, /* LCD Overlay 2 */ + LCDC_ROT_270 /* LCD HighEndOverlay, support resize */ +}; + +/* LCDC General Layer information */ + +struct sam_layer_s +{ + /* Descriptors and buffering */ + + struct sam_dscr_s *dscr; /* DMA descriptor(s) */ + uint8_t *framebuffer; /* DMA framebuffer memory */ + uint8_t lid; /* Layer ID (see enum sam_layer_e) */ + + /* Orientation information */ + + uint8_t rotation; /* See enum_rotation_e */ + uint8_t flags; /* See LDCD_FLAG_* definitions */ + + /* Color information */ + + uint8_t bpp; /* Bits per pixel */ +#ifdef CONFIG_FB_CMAP + uint8_t offset; /* Offset to first value entry in CLUT */ + uint8_t nclut; /* Number of colors in the CLUT */ +#endif +}; + +/* This structure provides the overall state of the LCDC */ + +struct sam_lcdc_s +{ + /* Layer information */ + + struct sam_layer_s layer[LCDC_NLAYERS]; + +#ifdef CONFIG_FB_HWCURSOR + struct fb_cursorpos_s cpos; /* Current cursor position */ +#ifdef CONFIG_FB_HWCURSORSIZE + struct fb_cursorsize_s csize; /* Current cursor size */ +#endif +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_LCDC_REGDEBUG + bool wrlast; /* True: Last access was a write */ + uintptr_t addrlast; /* Last address accessed */ + uint32_t vallast; /* Last value read or written */ + int ntimes; /* Number of consecutive accesses */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_LCDC_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(bool wr, uint32_t regval, uintptr_t address); +static uint32_t sam_getreg(uintptr_t addr); +static void sam_putreg(uintptr_t addr, uint32_t val); +#else +# define sam_getreg(addr) getreg32(addr) +# define sam_putreg(addr,val) putreg32(val,addr) +#endif +static void sam_wait_lcdstatus(uint32_t mask, uint32_t value); + +/* Frame buffer interface ***************************************************/ +/* Get information about the video controller configuration and the + * configuration of each color plane. + */ + +static int sam_base_getvideoinfo(struct fb_vtable_s *vtable, + struct fb_videoinfo_s *vinfo); +static int sam_base_getplaneinfo(struct fb_vtable_s *vtable, + int planeno, struct fb_planeinfo_s *pinfo); + +/* The following is provided only if the video hardware supports RGB color + * mapping + */ + +#ifdef CONFIG_FB_CMAP +static int sam_base_getcmap(struct fb_vtable_s *vtable, + struct fb_cmap_s *cmap); +static int sam_base_putcmap(struct fb_vtable_s *vtable, + const struct fb_cmap_s *cmap); +#endif + +/* The following is provided only if the video hardware supports a hardware + * cursor + */ + +#ifdef CONFIG_FB_HWCURSOR +static int sam_hcr_getcursor(struct fb_vtable_s *vtable, + struct fb_cursorattrib_s *attrib); +static int sam_hcr_setcursor(struct fb_vtable_s *vtable, + struct fb_setcursor_s *setttings); +#endif + +/* Initialization ***********************************************************/ + +static void sam_dmasetup(int lid, struct sam_dscr_s *dscr, uint8_t *buffer); +#if 0 /* #if defined(SAMA5_HAVE_POSITION) && defined(SAMA5_HAVE_SIZE) -- not used */ +static void sam_setposition(int lid, uint32_t x, uint32_t y) +#endif +#ifdef CONFIG_FB_CMAP +static int sam_setclut(struct sam_layer_s *layer, + const struct fb_cmap_s *cmap); +static int sam_getclut(struct sam_layer_s *layer, + struct fb_cmap_s *cmap); +#endif + +static void sam_pio_config(void); +static void sam_backlight(uint32_t level); +static void sam_base_disable(void); +static void sam_ovr1_disable(void); +static void sam_ovr2_disable(void); +static void sam_heo_disable(void); +#ifdef SAMA5_HAVE_LCDC_HCRCH +static void sam_hcr_disable(void); +#endif +static void sam_lcd_disable(void); +static void sam_layer_orientation(void); +static void sam_layer_color(void); +static void sam_lcd_enable(void); +static void sam_layer_configure(void); +#ifdef CONFIG_SAMA5_LCDC_HEO +static uint32_t sam_scalefactor(uint32_t wnew, uint32_t oldw); +#endif +static void sam_show_layer(struct sam_layer_s *layer, + uint32_t dispx, uint32_t dispy, uint32_t dispw, uint32_t disph, + uint32_t imgw, uint32_t imgh); +static void sam_show_base(void); +#ifdef CONFIG_SAMA5_LCDC_HCR +static void sam_show_hcr(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This structure describes the simulated video controller */ + +static const struct fb_videoinfo_s g_base_videoinfo = +{ + .fmt = SAMA5_LCDC_BASE_COLOR_FMT, + .xres = BOARD_LCDC_WIDTH, + .yres = BOARD_LCDC_HEIGHT, + .nplanes = 1, +}; + +/* This structure provides the overall state of the LCDC */ + +static struct sam_lcdc_s g_lcdc; + +/* This structure provides the base layer interface */ + +static const struct fb_vtable_s g_base_vtable = +{ + .getvideoinfo = sam_base_getvideoinfo, + .getplaneinfo = sam_base_getplaneinfo, +#ifdef CONFIG_FB_CMAP + .getcmap = sam_base_getcmap, + .putcmap = sam_base_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + .getcursor = sam_hcr_getcursor, + .setcursor = sam_hcr_setcursor, +#endif +}; + +/* PIO pin configurations */ + +static pio_pinset_t g_lcdcpins[] = +{ + PIO_LCD_DAT0, PIO_LCD_DAT2, PIO_LCD_DAT1, PIO_LCD_DAT3, + PIO_LCD_DAT4, PIO_LCD_DAT5, PIO_LCD_DAT6, PIO_LCD_DAT7, + PIO_LCD_DAT8, PIO_LCD_DAT9, PIO_LCD_DAT10, PIO_LCD_DAT11, + +#if BOARD_LCDC_OUTPUT_BPP > 12 + PIO_LCD_DAT12, PIO_LCD_DAT13, PIO_LCD_DAT14, PIO_LCD_DAT15, + +#if BOARD_LCDC_OUTPUT_BPP > 16 + PIO_LCD_DAT16, PIO_LCD_DAT17, +#if BOARD_LCDC_OUTPUT_BPP > 18 + PIO_LCD_DAT18, PIO_LCD_DAT19, + PIO_LCD_DAT20, PIO_LCD_DAT21, PIO_LCD_DAT22, PIO_LCD_DAT23, +#endif +#endif +#endif + + PIO_LCD_PWM, PIO_LCD_DISP, PIO_LCD_VSYNC, PIO_LCD_HSYNC, + PIO_LCD_PCK, PIO_LCD_DEN +}; +#define SAMA5_LCDC_NPINCONFIGS (sizeof(g_lcdcpins) / sizeof(pio_pinset_t)) + +/* Register lookup tables permit common logic to deal with different + * layers. + */ + +static const uintptr_t g_layerenable[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECHER, + SAM_LCDC_OVR1CHER, + SAM_LCDC_OVR2CHER, + SAM_LCDC_HEOCHER +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCHER +#endif +}; + +static const uintptr_t g_layerdisable[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECHDR, + SAM_LCDC_OVR1CHDR, + SAM_LCDC_OVR2CHDR, + SAM_LCDC_HEOCHDR +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCHDR +#endif +}; + +static const uintptr_t g_layerstatus[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECHSR, + SAM_LCDC_OVR1CHSR, + SAM_LCDC_OVR2CHSR, + SAM_LCDC_HEOCHSR +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCHSR +#endif +}; + +static const uintptr_t g_layerblend[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECFG4, + SAM_LCDC_OVR1CFG9, + SAM_LCDC_OVR2CFG9, + SAM_LCDC_HEOCFG12 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG9 +#endif +}; + +static const uintptr_t g_layerhead[LCDC_NLAYERS] = +{ + SAM_LCDC_BASEHEAD, + SAM_LCDC_OVR1HEAD, + SAM_LCDC_OVR2HEAD, + SAM_LCDC_HEOHEAD +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRHEAD +#endif +}; + +static const uintptr_t g_layeraddr[LCDC_NLAYERS] = +{ + SAM_LCDC_BASEADDR, + SAM_LCDC_OVR1ADDR, + SAM_LCDC_OVR2ADDR, + SAM_LCDC_HEOADDR +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRADDR +#endif +}; + +static const uintptr_t g_layerctrl[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECTRL, + SAM_LCDC_OVR1CTRL, + SAM_LCDC_OVR2CTRL, + SAM_LCDC_HEOCTRL +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCTRL +#endif +}; + +static const uintptr_t g_layernext[LCDC_NLAYERS] = +{ + SAM_LCDC_BASENEXT, + SAM_LCDC_OVR1NEXT, + SAM_LCDC_OVR2NEXT, + SAM_LCDC_HEONEXT +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRNEXT +#endif +}; + +static const uintptr_t g_layercfg[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECFG0, + SAM_LCDC_OVR1CFG0, + SAM_LCDC_OVR2CFG0, + SAM_LCDC_HEOCFG0 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG0 +#endif +}; + +static const uintptr_t g_layercolor[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECFG1, + SAM_LCDC_OVR1CFG1, + SAM_LCDC_OVR2CFG1, + SAM_LCDC_HEOCFG1 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG1 +#endif +}; + +#ifdef SAMA5_HAVE_POSITION +static const uintptr_t g_layerpos[LCDC_NLAYERS] = +{ + 0, + SAM_LCDC_OVR1CFG2, + SAM_LCDC_OVR2CFG2, + SAM_LCDC_HEOCFG2 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG2 +#endif +}; +#endif + +#ifdef SAMA5_HAVE_SIZE +static const uintptr_t g_layersize[LCDC_NLAYERS] = +{ + 0, + SAM_LCDC_OVR1CFG3, + SAM_LCDC_OVR2CFG3, + SAM_LCDC_HEOCFG3 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG3 +#endif +}; +#endif + +static const uintptr_t g_layerstride[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECFG2, + SAM_LCDC_OVR1CFG4, + SAM_LCDC_OVR2CFG4, + SAM_LCDC_HEOCFG5 +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCFG4 +#endif +}; + +#ifdef SAMA5_HAVE_PSTRIDE +static const uintptr_t g_layerpstride[LCDC_NLAYERS] = +{ + 0, SAM_LCDC_OVR1CFG5, SAM_LCDC_OVR2CFG5, SAM_LCDC_HEOCFG6, + 0 +}; +#endif + +#ifdef CONFIG_FB_CMAP +static const uintptr_t g_layerclut[LCDC_NLAYERS] = +{ + SAM_LCDC_BASECLUT, + SAM_LCDC_OVR1CLUT, + SAM_LCDC_OVR2CLUT, + SAM_LCDC_HEOCLUT +#ifdef SAMA5_HAVE_LCDC_HCRCH + , SAM_LCDC_HCRCLUT +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_LCDC_REGDEBUG +static bool sam_checkreg(bool wr, uint32_t regval, uintptr_t address) +{ + if (wr == g_lcdc.wrlast && /* Same kind of access? */ + regval == g_lcdc.vallast && /* Same value? */ + address == g_lcdc.addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + g_lcdc.ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (g_lcdc.ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", g_lcdc.ntimes); + } + + /* Save information about the new access */ + + g_lcdc.wrlast = wr; + g_lcdc.vallast = regval; + g_lcdc.addrlast = address; + g_lcdc.ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_LCDC_REGDEBUG +static uint32_t sam_getreg(uintptr_t address) +{ + uint32_t regval = getreg32(address); + + if (sam_checkreg(false, regval, address)) + { + lldbg("%08x->%08x\n", address, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_LCDC_REGDEBUG +static void sam_putreg(uintptr_t address, uint32_t regval) +{ + if (sam_checkreg(true, regval, address)) + { + lldbg("%08x<-%08x\n", address, regval); + } + + putreg32(regval, address); +} +#endif + +/**************************************************************************** + * Name: sam_wait_lcdstatus + * + * Description: + * Wait for the masked set of bits in the LCDC status register to take a + * specific value. + * + ****************************************************************************/ + +static void sam_wait_lcdstatus(uint32_t mask, uint32_t value) +{ + while ((sam_getreg(SAM_LCDC_LCDSR) & mask) != value); +} + +/**************************************************************************** + * Name: sam_base_getvideoinfo + ****************************************************************************/ + +static int sam_base_getvideoinfo(struct fb_vtable_s *vtable, + struct fb_videoinfo_s *vinfo) +{ + gvdbg("vtable=%p vinfo=%p\n", vtable, vinfo); + if (vtable && vinfo) + { + memcpy(vinfo, &g_base_videoinfo, sizeof(struct fb_videoinfo_s)); + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: sam_base_getplaneinfo + ****************************************************************************/ + +static int sam_base_getplaneinfo(struct fb_vtable_s *vtable, int planeno, + struct fb_planeinfo_s *pinfo) +{ + gvdbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo); + if (vtable && planeno == 0 && pinfo) + { + pinfo->fbmem = (void *)LAYER_BASE.framebuffer; + pinfo->fblen = SAMA5_BASE_FBSIZE; + pinfo->stride = SAMA5_BASE_STRIDE, + pinfo->bpp = LAYER_BASE.bpp; + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: sam_base_getcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int sam_base_getcmap(struct fb_vtable_s *vtable, + struct fb_cmap_s *cmap) +{ + return sam_getclut(&LAYER_BASE, cmap); +} +#endif + +/**************************************************************************** + * Name: sam_base_putcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int sam_base_putcmap(struct fb_vtable_s *vtable, + const struct fb_cmap_s *cmap) +{ + return sam_setclut(&LAYER_BASE, cmap); +} +#endif + +/**************************************************************************** + * Name: sam_hcr_getcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int sam_hcr_getcursor(struct fb_vtable_s *vtable, + struct fb_cursorattrib_s *attrib) +{ + gvdbg("vtable=%p attrib=%p\n", vtable, attrib); + if (vtable && attrib) + { +#ifdef CONFIG_FB_HWCURSORIMAGE + attrib->fmt = SAMA5_HCR_COLOR_FMT; +#endif + + gvdbg("pos: (x=%d, y=%d)\n", g_lcdc.cpos.x, g_lcdc.cpos.y); + attrib->pos = g_lcdc.cpos; + +#ifdef CONFIG_FB_HWCURSORSIZE + attrib->mxsize.h = CONFIG_SAMA5_LCDC_HCR_HEIGHT; + attrib->mxsize.w = CONFIG_SAMA5_LCDC_HCR_WIDTH; + + gvdbg("size: (h=%d, w=%d)\n", g_lcdc.csize.h, g_lcdc.csize.w); + attrib->size = g_lcdc.csize; +#endif + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: sam_hcr_setcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int sam_hcr_setcursor(struct fb_vtable_s *vtable, + struct fb_setcursor_s *setttings) +{ + gvdbg("vtable=%p setttings=%p\n", vtable, setttings); + if (vtable && setttings) + { + gvdbg("flags: %02x\n", settings->flags); + if ((flags & FB_CUR_SETPOSITION) != 0) + { + g_lcdc.cpos = settings->pos; + gvdbg("pos: (h:%d, w:%d)\n", g_lcdc.cpos.x, g_lcdc.cpos.y); + } +#ifdef CONFIG_FB_HWCURSORSIZE + if ((flags & FB_CUR_SETSIZE) != 0) + { + g_lcdc.csize = settings->size; + gvdbg("size: (h:%d, w:%d)\n", g_lcdc.csize.h, g_lcdc.csize.w); + } +#endif +#ifdef CONFIG_FB_HWCURSORIMAGE + if ((flags & FB_CUR_SETIMAGE) != 0) + { + gvdbg("image: (h:%d, w:%d) @ %p\n", + settings->img.height, settings->img.width, + settings->img.image); + } +#endif + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: sam_dmasetup + * + * Description: + * Configure the channel DMA + * + ****************************************************************************/ + +static void sam_dmasetup(int lid, struct sam_dscr_s *dscr, uint8_t *buffer) +{ + uintptr_t physbuffer; + uintptr_t physdscr; + + /* Get the physical address of the DMA descriptor and the DMA buffer */ + + physbuffer = sam_physramaddr((uintptr_t)buffer); + physdscr = sam_physramaddr((uintptr_t)dscr); + + /* 31.6.2.2 Programming a DMA Channel: + * + * 2. Write the channel descriptor (DSCR) structure in the system memory by + * writing DSCR.CHXADDR Frame base address, DSCR.CHXCTRL channel control + * and DSCR.CHXNEXT next descriptor location. + * 3. If more than one descriptor is expected, the DFETCH field of + * DSCR.CHXCTRL is set to one to enable the descriptor fetch operation. + */ + + dscr->addr = (uint32_t)physbuffer; + dscr->ctrl = LCDC_BASECTRL_DFETCH; + dscr->next = (uint32_t)physdscr; + + /* Check if the DMA is already active */ + + if ((sam_getreg(g_layerblend[lid]) & LCDC_BASECFG4_DMA) != 0) + { + /* Yes.. add the new descriptor to the buffer list + * 31.6.2.4 DMA Dynamic Linking of a New Transfer Descriptor: + * + * 2. Write the address of the new structure in the CHXHEAD register. + * 3. Add the new structure to the queue of descriptors by writing one + * to the A2QEN field of the CHXCHER register. + */ + + sam_putreg(g_layerhead[lid], physdscr); + sam_putreg(g_layerenable[lid], LCDC_BASECHER_A2Q); + } + else + { + /* 31.6.2.2 Programming a DMA Channel: + * + * 4. Write the DSCR.CHXNEXT register with the address location + * of the descriptor structure and set DFETCH field of the + * DSCR.CHXCTRL register to one. + */ + + sam_putreg(g_layeraddr[lid], physbuffer); + sam_putreg(g_layerctrl[lid], LCDC_BASECTRL_DFETCH); + sam_putreg(g_layernext[lid], physdscr); + } + +#if defined(CONFIG_DEBUG_GRAPHICS) && defined(CONFIG_DEBUG_VERBOSE) + /* Dump the DMA setup */ + + gvdbg("DMA descriptor: addr=%08x ctrl=%08x next=%08x\n", + dscr->addr, dscr->ctrl, dscr->next); + gvdbg("DMA registers[%d]: head=%08x addr=%08x ctrl=%08x next=%08x\n", + lid, sam_getreg(g_layerhead[lid]), sam_getreg(g_layeraddr[lid]), + sam_getreg(g_layerctrl[lid]), sam_getreg(g_layernext[lid])); +#endif +} + +/**************************************************************************** + * Name: sam_setposition + * + * Description: + * Set the new position of a move-able layer (any layer except the base + * layer). + * + ****************************************************************************/ + +#if 0 /* #if defined(SAMA5_HAVE_POSITION) && defined(SAMA5_HAVE_SIZE) -- not used */ +static void sam_setposition(int lid, uint32_t x, uint32_t y) +{ + uintptr_t regaddr; + uintptr_t regval; + uint32_t h; + uint32_t w; + + regaddr = g_layersize[lid]; + if (regaddr) + { + /* Get the layer size */ + + regval = sam_getreg(regaddr); + w = (regval & LCDC_OVR1CFG3_XSIZE_MASK) >> LCDC_OVR1CFG3_XSIZE_SHIFT; + h = (regval & LCDC_OVR1CFG3_YSIZE_MASK) >> LCDC_OVR1CFG3_YSIZE_SHIFT; + + /* Clip the position so that the window lies on the physical display */ + + if (x + w >= BOARD_LCDC_WIDTH) + { + x = BOARD_LCDC_WIDTH - w; + } + + if (y + h >= BOARD_LCDC_HEIGHT) + { + y = BOARD_LCDC_HEIGHT - h; + } + + /* Set the new position of the layer */ + + regaddr = g_layerpos[lid]; + if (regaddr) + { + sam_putreg(regaddr, LCDC_OVR1CFG2_XPOS(x) | LCDC_OVR1CFG2_YPOS(y)); + + /* If the channel is enabled, then update the layer */ + + regaddr = g_layerstatus[lid]; + if ((sam_getreg(regaddr) & LCDC_OVR1CHSR_CH) != 0) + { + regaddr = g_layerenable[lid]; + sam_putreg(regaddr, LCDC_OVR1CHER_UPDATE); + } + } + } +} +#endif + +/**************************************************************************** + * Name: sam_setclut + * + * Description: + * Set a range of CLUT values for any layer + * + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int sam_setclut(struct sam_layer_s *layer, + const struct fb_cmap_s *cmap) +{ + uintptr_t regaddr; + uint32_t offset; + uint32_t rgb; + unsigned int len; + unsigned int end; + int i; + + gvdbg("layer=%d cmap=%p first=%d len=%d\n", + layer->lid, cmap, cmap->first, cmap->len); + + DEBUGASSERT(layer && cmap); + + /* Get and verify the range of CLUT entries to modify */ + + offset = (uint32_t)cmap->first; + len = (unsigned int)cmap->len; + + if (offset >= SAM_LCDC_NCLUT) + { + gdbg("ERROR: CLUT offset is out of range: %d\n", offset); + return -EINVAL; + } + + if (offset + len > SAM_LCDC_NCLUT) + { + len = SAM_LCDC_NCLUT - offset; + } + + /* Update the valid range of CLUT entries */ + + if (offset < layer->offset) + { + layer->offset = offset; + } + + end = offset + len; + if (end > (layer->offset + layer->nclut)) + { + layer->nclut = end - layer->offset; + } + + /* Get the offset address to the first CLUT entry to modify */ + + regaddr = g_layerclut[layer->lid] + offset << 2; + + /* Then set the number of CLUT entries beginning at this offset */ + + for (i = 0; i < len; i++) + { + /* Pack the RGB (+transparency?) values as required */ + + rgb = (uint32_t)cmap->red[i] << LCDC_BASECLUT_RCLUT_SHIFT | + (uint32_t)cmap->green[i] << LCDC_BASECLUT_GCLUT_SHIFT | + (uint32_t)cmap->blue[i] << LCDC_BASECLUT_BCLUT_SHIFT; + +#ifdef CONFIG_FB_TRANSPARENCY + if (camp->transp) + { + rgb |= (uint32_t)cmap->transp[i] << LCDC_OVR1CLUT_ACLUT_SHIFT; + } +#endif + + /* And write to the CLUT register */ + + sam_putreg(regaddr, clut[i]); + regaddr += sizeof(uint32_t); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_getclut + * + * Description: + * Get a range of CLUT values for any layer + * + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int sam_getclut(struct sam_layer_s *layer, + struct fb_cmap_s *cmap) +{ + uintptr_t regaddr; + uintptr_t regval; + int i; + + gvdbg("layer=%d cmap=%p first=%d len=%d\n", + layer->lid, cmap, layer->offset, layer->nclut); + + DEBUGASSERT(layer && cmap); + + /* Return the range of CLUT entries to modify */ + + cmap->first = layer->offset; + cmap->len = layer->nclut; + + /* Get the offset address to the first CLUT entry to modify */ + + regaddr = g_layerclut[layer->lid] + (uint32_t)cmap->first << 2; + + /* Then set the number of CLUT entries beginning at this offset */ + + for (i = 0; i < (int)cmap->len; i++) + { + /* Read the CLUT entry */ + + regval = getreg(regaddr); + regaddr += sizeof(uint32_t); + + /* Unpack and return the RGB (+transparency?) values as required */ + + cmap->red[i] = (uint8_t) + (regval & LCDC_BASECLUT_RCLUT_MASK) << LCDC_BASECLUT_RCLUT_SHIFT; + cmap->green[i] = (uint8_t) + (regval & LCDC_BASECLUT_GCLUT_MASK) << LCDC_BASECLUT_GCLUT_SHIFT; + cmap->blue[i] = (uint8_t) + (regval & LCDC_BASECLUT_GCLUT_MASK) << LCDC_BASECLUT_BCLUT_SHIFT; + +#ifdef CONFIG_FB_TRANSPARENCY + cmap->transp[i] = (uint8_t) + (regval & LCDC_OVR1CLUT_ACLUT_MASK) << LCDC_OVR1CLUT_ACLUT_SHIFT; +#endif + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_pio_config + * + * Description: + * Configure PIO pins for use with the LCDC + * + ****************************************************************************/ + +static void sam_pio_config(void) +{ + int i; + + gvdbg("Configuring pins\n"); + + /* Configure each pin */ + + for (i = 0; i < SAMA5_LCDC_NPINCONFIGS; i++) + { + sam_configpio(g_lcdcpins[i]); + } +} + +/**************************************************************************** + * Name: sam_backlight + * + * Description: + * Set the backlight level + * + ****************************************************************************/ + +static void sam_backlight(uint32_t level) +{ + uint32_t regval; + + /* Are we turning the backlight off? */ + + if (level == SAMA5_LCDC_BACKLIGHT_OFF) + { + /* Disable the backlight */ + + sam_putreg(SAM_LCDC_LCDDIS, LCDC_LCDDIS_PWM); + + /* And wait for the PWM to be disabled */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_PWM, 0); + } +#ifdef CONFIG_SAMA5_LCDC_BACKLIGHT + else + { + /* Set the backight level */ + + regval = sam_getreg(SAM_LCDC_LCDCFG6); + regval &= ~LCDC_LCDCFG6_PWMCVAL_MASK; + regval |= LCDC_LCDCFG6_PWMCVAL(level); + sam_putreg(SAM_LCDC_LCDCFG6, regval); + + /* Enable the backlight */ + + sam_putreg(SAM_LCDC_LCDEN, LCDC_LCDEN_PWM); + } +#endif +} + +/**************************************************************************** + * Name: sam_base_disable + * + * Description: + * Disable the base layer + * + ****************************************************************************/ + +static void sam_base_disable(void) +{ + struct sam_dscr_s *dscr; + uintptr_t physaddr; + uint32_t regval; + + dscr = LAYER_BASE.dscr; + DEBUGASSERT(dscr); + + /* 1. Clear the DFETCH bit in the DSCR.CHXCTRL field of the DSCR structure + * will disable the channel at the end of the frame. + */ + + regval = sam_getreg(SAM_LCDC_BASECTRL); + regval &= ~LCDC_BASECTRL_DFETCH; + sam_putreg(SAM_LCDC_BASECTRL, regval); + + /* 2. Set the DSCR.CHXNEXT field of the DSCR structure will disable the + * channel at the end of the frame. + */ + + physaddr = sam_physramaddr((uintptr_t)dscr); + dscr->next = physaddr; + + sam_putreg(SAM_LCDC_BASENEXT, physaddr); + + /* 3. Writing one to the CHDIS field of the CHXCHDR register will disable + * the channel at the end of the frame. + */ + + sam_putreg(SAM_LCDC_BASECHDR, LCDC_BASECHDR_CH); + + /* 4. Writing one to the CHRST field of the CHXCHDR register will disable + * the channel immediately. This may occur in the middle of the image. + */ + + /* 5. Poll CHSR field in the CHXCHSR register until the channel is + * successfully disabled. + */ + + while ((sam_getreg(SAM_LCDC_BASECHSR) & LCDC_BASECHSR_CH) != 0); +} + +/**************************************************************************** + * Name: sam_ovr1_disable + * + * Description: + * Disable the overlay 1 layer + * + ****************************************************************************/ + +static void sam_ovr1_disable(void) +{ + struct sam_dscr_s *dscr; + uintptr_t physaddr; + uint32_t regval; + + dscr = LAYER_OVR1.dscr; + DEBUGASSERT(dscr); + + /* 1. Clear the DFETCH bit in the DSCR.CHXCTRL field of the DSCR structure + * will disable the channel at the end of the frame. + */ + + dscr->ctrl &= ~LCDC_OVR1CTRL_DFETCH; + + regval = sam_getreg(SAM_LCDC_OVR1CTRL); + regval &= ~LCDC_OVR1CTRL_DFETCH; + sam_putreg(SAM_LCDC_OVR1CTRL, regval); + + /* 2. Set the DSCR.CHXNEXT field of the DSCR structure will disable the + * channel at the end of the frame. + */ + + physaddr = sam_physramaddr((uintptr_t)dscr); + dscr->next = physaddr; + + sam_putreg(SAM_LCDC_OVR1NEXT, physaddr); + + /* 3. Writing one to the CHDIS field of the CHXCHDR register will disable + * the channel at the end of the frame. + */ + + sam_putreg(SAM_LCDC_OVR1CHDR, LCDC_OVR1CHDR_CH); + + /* 4. Writing one to the CHRST field of the CHXCHDR register will disable + * the channel immediately. This may occur in the middle of the image. + */ + + /* 5. Poll CHSR field in the CHXCHSR register until the channel is + * successfully disabled. + */ + + while ((sam_getreg(SAM_LCDC_OVR1CHSR) & LCDC_OVR1CHSR_CH) != 0); +} + +/**************************************************************************** + * Name: sam_ovr2_disable + * + * Description: + * Disable the overlay 2 layer + * + ****************************************************************************/ + +static void sam_ovr2_disable(void) +{ + struct sam_dscr_s *dscr; + uintptr_t physaddr; + uint32_t regval; + + dscr = LAYER_OVR2.dscr; + DEBUGASSERT(dscr); + + /* 1. Clear the DFETCH bit in the DSCR.CHXCTRL field of the DSCR structure + * will disable the channel at the end of the frame. + */ + + dscr->ctrl &= ~LCDC_OVR2CTRL_DFETCH; + + regval = sam_getreg(SAM_LCDC_OVR2CTRL); + regval &= ~LCDC_OVR2CTRL_DFETCH; + sam_putreg(SAM_LCDC_OVR2CTRL, regval); + + /* 2. Set the DSCR.CHXNEXT field of the DSCR structure will disable the + * channel at the end of the frame. + */ + + physaddr = sam_physramaddr((uintptr_t)dscr); + dscr->next = physaddr; + + sam_putreg(SAM_LCDC_OVR2NEXT, physaddr); + + /* 3. Writing one to the CHDIS field of the CHXCHDR register will disable + * the channel at the end of the frame. + */ + + sam_putreg(SAM_LCDC_OVR2CHDR, LCDC_OVR2CHDR_CH); + + /* 4. Writing one to the CHRST field of the CHXCHDR register will disable + * the channel immediately. This may occur in the middle of the image. + */ + + /* 5. Poll CHSR field in the CHXCHSR register until the channel is + * successfully disabled. + */ + + while ((sam_getreg(SAM_LCDC_OVR2CHSR) & LCDC_OVR2CHSR_CH) != 0); +} + +/**************************************************************************** + * Name: sam_heo_disable + * + * Description: + * Disable the High End Overlay (HEO) layer + * + ****************************************************************************/ + +static void sam_heo_disable(void) +{ + struct sam_dscr_s *dscr; + uintptr_t physaddr; + uint32_t regval; + + dscr = LAYER_HEO.dscr; + DEBUGASSERT(dscr); + + /* 1. Clear the DFETCH bit in the DSCR.CHXCTRL field of the DSCR structure + * will disable the channel at the end of the frame. + */ + + dscr[0].ctrl &= ~LCDC_HEOCTRL_DFETCH; + dscr[1].ctrl &= ~LCDC_HEOUCTRL_DFETCH; + dscr[2].ctrl &= ~LCDC_HEOVCTRL_DFETCH; + + regval = sam_getreg(SAM_LCDC_HEOCTRL); + regval &= ~LCDC_HEOCTRL_DFETCH; + sam_putreg(SAM_LCDC_HEOCTRL, regval); + + regval = sam_getreg(SAM_LCDC_HEOUCTRL); + regval &= ~LCDC_HEOUCTRL_DFETCH; + sam_putreg(SAM_LCDC_HEOUCTRL, regval); + + regval = sam_getreg(SAM_LCDC_HEOVCTRL); + regval &= ~LCDC_HEOVCTRL_DFETCH; + sam_putreg(SAM_LCDC_HEOVCTRL, regval); + + /* 2. Set the DSCR.CHXNEXT field of the DSCR structure will disable the + * channel at the end of the frame. + */ + + physaddr = sam_physramaddr((uintptr_t)&dscr[0]); + dscr[0].next = physaddr; + sam_putreg(SAM_LCDC_HEONEXT, physaddr); + + physaddr = sam_physramaddr((uintptr_t)&dscr[1]); + dscr[1].next = physaddr; + sam_putreg(SAM_LCDC_HEOUNEXT, physaddr); + + physaddr = sam_physramaddr((uintptr_t)&dscr[2]); + dscr[2].next = physaddr; + sam_putreg(SAM_LCDC_HEOVNEXT, physaddr); + + /* 3. Writing one to the CHDIS field of the CHXCHDR register will disable + * the channel at the end of the frame. + */ + + sam_putreg(SAM_LCDC_HEOCHDR, LCDC_HEOCHDR_CH); + + /* 4. Writing one to the CHRST field of the CHXCHDR register will disable + * the channel immediately. This may occur in the middle of the image. + */ + + /* 5. Poll CHSR field in the CHXCHSR register until the channel is + * successfully disabled. + */ + + while ((sam_getreg(SAM_LCDC_HEOCHSR) & LCDC_HEOCHSR_CH) != 0); +} + +/**************************************************************************** + * Name: sam_hcr_disable + * + * Description: + * Disable the Hardware Cursor Channel (HCR) layer + * + ****************************************************************************/ + +#ifdef SAMA5_HAVE_LCDC_HCRCH +static void sam_hcr_disable(void) +{ + struct sam_dscr_s *dscr; + uintptr_t physaddr; + uint32_t regval; + + dscr = LAYER_HCR.dscr; + DEBUGASSERT(dscr); + + /* 1. Clear the DFETCH bit in the DSCR.CHXCTRL field of the DSCR structure + * will disable the channel at the end of the frame. + */ + + dscr->ctrl &= ~LCDC_HCRCTRL_DFETCH; + + regval = sam_getreg(SAM_LCDC_HCRCTRL); + regval &= ~LCDC_HCRCTRL_DFETCH; + sam_putreg(SAM_LCDC_HCRCTRL, regval); + + /* 2. Set the DSCR.CHXNEXT field of the DSCR structure will disable the + * channel at the end of the frame. + */ + + physaddr = sam_physramaddr((uintptr_t)dscr); + dscr->next = physaddr; + + sam_putreg(SAM_LCDC_HCRNEXT, physaddr); + + /* 3. Writing one to the CHDIS field of the CHXCHDR register will disable + * the channel at the end of the frame. + */ + + sam_putreg(SAM_LCDC_HCRCHDR, LCDC_HCRCHDR_CH); + + /* 4. Writing one to the CHRST field of the CHXCHDR register will disable + * the channel immediately. This may occur in the middle of the image. + */ + + /* 5. Poll CHSR field in the CHXCHSR register until the channel is + * successfully disabled. + */ + + while ((sam_getreg(SAM_LCDC_HCRCHSR) & LCDC_HCRCHSR_CH) != 0); +} +#endif + +/**************************************************************************** + * Name: sam_lcd_disable + * + * Description: + * Disable the LCD peripheral + * + ****************************************************************************/ + +static void sam_lcd_disable(void) +{ + /* Disable layers */ + + sam_base_disable(); + sam_ovr1_disable(); + sam_ovr2_disable(); + sam_heo_disable(); +#ifdef SAMA5_HAVE_LCDC_HCRCH + sam_hcr_disable(); +#endif + + /* Disable DMA path */ + + sam_putreg(SAM_LCDC_BASECFG4, 0); + + /* Turn off the back light */ + + sam_backlight(SAMA5_LCDC_BACKLIGHT_OFF); + + /* Timing Engine Power Down Software Operation */ + + /* 1. Disable the DISP signal writing DISPDIS field of the LCDC_LCDDIS + * register. + */ + + sam_putreg(SAM_LCDC_LCDDIS, LCDC_LCDDIS_DISP); + + /* 2. Poll DISPSTS field of the LCDC_LCDSR register to verify that the DISP + * is no longer activated. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_DISP, 0); + + /* 3. Disable the hsync and vsync signals by writing one to SYNCDIS field of + * the LCDC_LCDDIS register. + */ + + sam_putreg(SAM_LCDC_LCDDIS, LCDC_LCDDIS_SYNC); + + /* 4. Poll LCDSTS field of the LCDC_LCDSR register to check that the + * synchronization is off. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_LCD, 0); + + /* 5. Disable the Pixel clock by writing one in the CLKDIS field of the + * LCDC_LCDDIS register. + */ + + sam_putreg(SAM_LCDC_LCDDIS, LCDC_LCDDIS_CLK); + + /* 6. Poll CLKSTS field of the LCDC_CLKSR register to check that Pixel Clock + * is disabled. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_CLK, 0); + + /* Disable peripheral clock */ + + sam_lcdc_disableclk(); + + /* Disable the LCD clock */ + + sam_putreg(SAM_PMC_SCDR, PMC_LCDCK); +} + +/**************************************************************************** + * Name: sam_layer_orientation + * + * Description: + * Configure LCDC layer orientation + * + ****************************************************************************/ + +static void sam_layer_orientation(void) +{ + /* Base channel orientation */ + + LAYER_BASE.flags = 0; + +#if defined(CONFIG_SAMA5_LCDC_BASE_ROT90) + LAYER_BASE.rotation = LCDC_ROT_90; +#elif defined(CONFIG_SAMA5_LCDC_BASE_ROT180) + LAYER_BASE.rotation = LCDC_ROT_180; +#elif defined(CONFIG_SAMA5_LCDC_BASE_ROT270) + LAYER_BASE.rotation = LCDC_ROT_270; +#else + LAYER_BASE.rotation = LCDC_ROT_0; +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR1 + /* Overlay 1 orientation */ + + LAYER_OVR1.flags = 0; +#ifdef CONFIG_SAMA5_LCDC_OVR1_BOTTOMUP + LAYER_OVR1.flags |= LCDC_FLAG_BOTTOMUP; +#endif +#ifdef CONFIG_SAMA5_LCDC_OVR1_RIGHTLEFT + LAYER_OVR1.flags |= LCDC_FLAG_RIGHTLEFT; +#endif + +#if defined(CONFIG_SAMA5_LCDC_OVR1_ROT90) + LAYER_OVR1.rotation = LCDC_ROT_90; +#elif defined(CONFIG_SAMA5_LCDC_OVR1_ROT180) + LAYER_OVR1.rotation = LCDC_ROT_180; +#elif defined(CONFIG_SAMA5_LCDC_OVR1_ROT270) + LAYER_OVR1.rotation = LCDC_ROT_270; +#else + LAYER_OVR1.rotation = LCDC_ROT_0; +#endif +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR2 + /* Overlay 2 orientation */ + + LAYER_OVR2.flags = 0; +#ifdef CONFIG_SAMA5_LCDC_OVR2_BOTTOMUP + LAYER_OVR2.flags |= LCDC_FLAG_BOTTOMUP; +#endif +#ifdef CONFIG_SAMA5_LCDC_OVR2_RIGHTLEFT + LAYER_OVR2.flags |= LCDC_FLAG_RIGHTLEFT; +#endif + +#if defined(CONFIG_SAMA5_LCDC_OVR2_ROT90) + LAYER_OVR2.rotation = LCDC_ROT_90; +#elif defined(CONFIG_SAMA5_LCDC_OVR2_ROT180) + LAYER_OVR2.rotation = LCDC_ROT_180; +#elif defined(CONFIG_SAMA5_LCDC_OVR2_ROT270) + LAYER_OVR2.rotation = LCDC_ROT_270; +#else + LAYER_OVR2.rotation = LCDC_ROT_0; +#endif +#endif + +#ifdef CONFIG_SAMA5_LCDC_HEO + /* High End Overlay orientation */ + + LAYER_HEO.flags = 0; +#ifdef CONFIG_SAMA5_LCDC_HEO_BOTTOMUP + LAYER_HEO.flags |= LCDC_FLAG_BOTTOMUP; +#endif +#ifdef CONFIG_SAMA5_LCDC_HEO_RIGHTLEFT + LAYER_HEO.flags |= LCDC_FLAG_RIGHTLEFT; +#endif + +#if defined(CONFIG_SAMA5_LCDC_HEO_ROT90) + LAYER_HEO.rotation = LCDC_ROT_90; +#elif defined(CONFIG_SAMA5_LCDC_HEO_ROT180) + LAYER_HEO.rotation = LCDC_ROT_180; +#elif defined(CONFIG_SAMA5_LCDC_HEO_ROT270) + LAYER_HEO.rotation = LCDC_ROT_270; +#else + LAYER_HEO.rotation = LCDC_ROT_0; +#endif +#endif + +#ifdef CONFIG_SAMA5_LCDC_HCR + /* Hardware Cursor orientation */ + + LAYER_HCR.flags = 0; + +#if defined(CONFIG_SAMA5_LCDC_HCR_ROT90) + LAYER_HCR.rotation = LCDC_ROT_90; +#elif defined(CONFIG_SAMA5_LCDC_HCR_ROT180) + LAYER_HCR.rotation = LCDC_ROT_180; +#elif defined(CONFIG_SAMA5_LCDC_HCR_ROT270) + LAYER_HCR.rotation = LCDC_ROT_270; +#else + LAYER_HCR.rotation = LCDC_ROT_0; +#endif +#endif +} + +/**************************************************************************** + * Name: sam_layer_color + * + * Description: + * Configure LCDC layer color mode + * + ****************************************************************************/ + +static void sam_layer_color(void) +{ + /* Mark the CLUTs as empty */ + +#ifdef CONFIG_FB_CMAP + LAYER_BASE.offset = SAM_LCDC_NCLUT - 1; + LAYER_OVR1.offset = SAM_LCDC_NCLUT - 1; + LAYER_OVR2.offset = SAM_LCDC_NCLUT - 1; + LAYER_HEO.offset = SAM_LCDC_NCLUT - 1; + LAYER_HCR.offset = SAM_LCDC_NCLUT - 1; +#endif + + /* Base channel color configuration */ + +#if defined(CONFIG_SAMA5_LCDC_BASE_RGB888P) + LAYER_BASE.bpp = 24; + + sam_putreg(SAM_LCDC_BASECFG0, + LCDC_BASECFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16); + sam_putreg(SAM_LCDC_BASECFG1, + LCDC_BASECFG1_24BPP_RGB888P); + +# elif defined(CONFIG_SAMA5_LCDC_BASE_RGB565) + LAYER_BASE.bpp = 16; + + sam_putreg(SAM_LCDC_BASECFG0, + LCDC_BASECFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16); + sam_putreg(SAM_LCDC_BASECFG1, + LCDC_BASECFG1_16BPP_RGB565); + +#else +# error Support for this resolution is not yet implemented +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR1 + /* Overlay 1 color configuration, GA 0xff */ + +# if defined(CONFIG_SAMA5_LCDC_OVR1_RGB888P) + LAYER_OVR1.bpp = 24; + + sam_putreg(SAM_LCDC_OVR1CFG0, + LCDC_OVR1CFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16 | + LCDC_OVR1CFG0_ROTDIS); + sam_putreg(SAM_LCDC_OVR1CFG1, + LCDC_OVR1CFG1_24BPP_RGB888P); + sam_putreg(SAM_LCDC_OVR1CFG9, + LCDC_OVR1CFG9_GA(0xff) | LCDC_OVR1CFG9_GAEN); + +# elif defined(CONFIG_SAMA5_LCDC_OVR1_RGB565) + LAYER_OVR1.bpp = 16; + + sam_putreg(SAM_LCDC_OVR1CFG0, + LCDC_OVR1CFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16 | + LCDC_OVR1CFG0_ROTDIS); + sam_putreg(SAM_LCDC_OVR1CFG1, + LCDC_OVR1CFG1_16BPP_RGB565); + sam_putreg(SAM_LCDC_OVR1CFG9, + LCDC_OVR1CFG9_GA(0xff) | LCDC_OVR1CFG9_GAEN); + +# else +# error Support for this resolution is not yet implemented +# endif +#endif + +#ifdef CONFIG_SAMA5_LCDC_OVR2 + /* Overlay 2 color configuration, GA 0xff */ + +# if defined(CONFIG_SAMA5_LCDC_OVR2_RGB888P) + LAYER_OVR2.bpp = 24; + + sam_putreg(SAM_LCDC_OVR2CFG0, + LCDC_OVR2CFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16 | + LCDC_OVR2CFG0_ROTDIS; + sam_putreg(SAM_LCDC_OVR2CFG1, + LCDC_OVR2CFG1_24BPP_RGB888P); + sam_putreg(SAM_LCDC_OVR2CFG9, + LCDC_OVR2CFG9_GA(0xff) | LCDC_OVR2CFG9_GAEN; + +# elif defined(CONFIG_SAMA5_LCDC_OVR2_RGB565) + LAYER_OVR2.bpp = 16; + + sam_putreg(SAM_LCDC_OVR2CFG0, + LCDC_OVR2CFG0_DLBO | LCDC_BASECFG0_BLEN_INCR16 | + LCDC_OVR2CFG0_ROTDIS); + sam_putreg(SAM_LCDC_OVR2CFG1, + LCDC_OVR2CFG1_16BPP_RGB565); + sam_putreg(SAM_LCDC_OVR2CFG9, + LCDC_OVR2CFG9_GA(0xff) | LCDC_OVR2CFG9_GAEN); + +# else +# error Support for this resolution is not yet implemented +# endif +#endif + +#ifdef CONFIG_SAMA5_LCDC_HEO + /* High End Overlay color configuration, GA 0xff */ + +# if defined(CONFIG_SAMA5_LCDC_HEO_RGB888P) + LAYER_HEO.bpp = 24; + + sam_putreg(SAM_LCDC_HEOCFG0, + LCDC_HEOCFG0_DLBO | LCDC_HEOCFG0_BLEN_INCR16 | + LCDC_HEOCFG0_ROTDIS); + sam_putreg(SAM_LCDC_HEOCFG1, + LCDC_HEOCFG1_24BPP_RGB888P); + sam_putreg(SAM_LCDC_HEOCFG12, + LCDC_HEOCFG12_GA(0xff) | LCDC_HEOCFG12_GAEN); + +# elif defined(CONFIG_SAMA5_LCDC_HEO_RGB565) + LAYER_HEO.bpp = 16; + + sam_putreg(SAM_LCDC_HEOCFG0, + LCDC_HEOCFG0_DLBO | LCDC_HEOCFG0_BLEN_INCR16 | + LCDC_HEOCFG0_ROTDIS); + sam_putreg(SAM_LCDC_HEOCFG1, + LCDC_HEOCFG1_16BPP_RGB565); + sam_putreg(SAM_LCDC_HEOCFG9, + LCDC_HEOCFG9_GA(0xff) | LCDC_HEOCFG9_GAEN); + +# else +# error Support for this resolution is not yet implemented +# endif +#endif + +#ifdef SAMA5_HAVE_LCDC_HCRCH +#ifdef CONFIG_SAMA5_LCDC_HCR + /* Hardware Cursor color configuration, GA 0xff, Key #000000 */ + +# if defined(CONFIG_SAMA5_LCDC_HCR_RGB888P) + LAYER_HCR.bpp = 24; + + sam_putreg(SAM_LCDC_HCRCFG0, + LCDC_HCRCFG0_DLBO | LCDC_HCRCFG0_BLEN_INCR16); + sam_putreg(SAM_LCDC_HCRCFG1, + LCDC_HCRCFG1_24BPP_RGB888P; + sam_putreg(SAM_LCDC_HCRCFG7, + 0x000000); + sam_putreg(SAM_LCDC_HCRCFG8, + 0xffffff); + sam_putreg(SAM_LCDC_HCRCFG9, + LCDC_HCRCFG9_GAEN(0xff) | LCDC_HCRCFG9_GAEN); + +# elif defined(CONFIG_SAMA5_LCDC_HCR_RGB565) + LAYER_HCR.bpp = 16; + + sam_putreg(SAM_LCDC_HCRCFG0, + LCDC_HCRCFG0_DLBO | LCDC_HCRCFG0_BLEN_INCR16 | + LCDC_HCRCFG0_ROTDIS); + sam_putreg(SAM_LCDC_HCRCFG1, + LCDC_HCRCFG1_16BPP_RGB565); + sam_putreg(SAM_LCDC_HCRCFG9, + LCDC_HCRCFG9_GA(0xff) | LCDC_HCRCFG9_GAEN); + +# else +# error Support for this resolution is not yet implemented +# endif +#endif +#endif +} + +/**************************************************************************** + * Name: sam_lcd_enable + * + * Description: + * Enable the LCD for normal use + * + ****************************************************************************/ + +static void sam_lcd_enable(void) +{ + uint32_t regval; + uint32_t div; + + /* Enable the LCD peripheral clock */ + + sam_lcdc_enableclk(); + + /* Enable the LCD clock */ + + sam_putreg(SAM_PMC_SCER, PMC_LCDCK); + + /* 1. Configure LCD timing parameters, signal polarity and clock period. */ + +#ifdef BOARD_LCDC_MCK_MUL2 + div = (2*BOARD_MCK_FREQUENCY + (BOARD_LCDC_PIXELCLOCK-1)) / BOARD_LCDC_PIXELCLOCK; +#else + div = (BOARD_MCK_FREQUENCY + (BOARD_LCDC_PIXELCLOCK-1)) / BOARD_LCDC_PIXELCLOCK; +#endif + DEBUGASSERT(div > 1); + + regval = LCDC_LCDCFG0_CGDISBASE | LCDC_LCDCFG0_CLKDIV(div - 2); + +#ifdef BOARD_LCDC_PIXCLK_INV + regval |= LCDC_LCDCFG0_CLKPOL; +#endif +#ifdef BOARD_LCDC_MCK_MUL2 + regval |= LCDC_LCDCFG0_CLKSEL; +#endif +#ifdef CONFIG_SAMA5_LCDC_OVR1 + regval |= LCDC_LCDCFG0_CGDISOVR1; +#endif +#ifdef CONFIG_SAMA5_LCDC_OVR2 + regval |= LCDC_LCDCFG0_CGDISOVR2; +#endif +#ifdef CONFIG_SAMA5_LCDC_HEO + regval |= LCDC_LCDCFG0_CGDISHEO; +#endif +#ifdef CONFIG_SAMA5_LCDC_HCR + regval |= LCDC_LCDCFG0_CGDISHCR; +#endif + sam_putreg(SAM_LCDC_LCDCFG0, regval); + + regval = LCDC_LCDCFG1_HSPW(BOARD_LCDC_HSPW - 1) | + LCDC_LCDCFG1_VSPW(BOARD_LCDC_VSPW - 1); + sam_putreg(SAM_LCDC_LCDCFG1, regval); + + regval = LCDC_LCDCFG2_VFPW(BOARD_LCDC_VFPW - 1) | + LCDC_LCDCFG2_VBPW(BOARD_LCDC_VBPW); + sam_putreg(SAM_LCDC_LCDCFG2, regval); + + regval = LCDC_LCDCFG3_HFPW(BOARD_LCDC_HFPW - 1) | + LCDC_LCDCFG3_HBPW(BOARD_LCDC_HBPW - 1); + sam_putreg(SAM_LCDC_LCDCFG3, regval); + + regval = LCDC_LCDCFG4_PPL(BOARD_LCDC_WIDTH - 1) | + LCDC_LCDCFG4_RPF(BOARD_LCDC_HEIGHT - 1); + sam_putreg(SAM_LCDC_LCDCFG4, regval); + + regval = LCDC_LCDCFG5_HSPOL | LCDC_LCDCFG5_VSPOL | + LCDC_LCDCFG5_VSPDLYS | LCDC_LCDCFG5_DISPDLY | + LCDC_LCDCFG5_GUARDTIME(BOARD_LCDC_GUARDTIME); + +#if BOARD_LCDC_OUTPUT_BPP == 16 + regval |= LCDC_LCDCFG5_MODE_12BPP; +#elif BOARD_LCDC_OUTPUT_BPP == 16 + regval |= LCDC_LCDCFG5_MODE_16BPP; +#elif BOARD_LCDC_OUTPUT_BPP == 18 + regval |= LCDC_LCDCFG5_MODE_18BPP; +#elif BOARD_LCDC_OUTPUT_BPP == 24 + regval |= LCDC_LCDCFG5_MODE_24BPP; +#else +# error Unknown or undefined output resolution +#endif + + sam_putreg(SAM_LCDC_LCDCFG5, regval); + + regval = BOARD_LCDC_PWMPS | BOARD_LCDC_PWMPOL | + LCDC_LCDCFG6_PWMCVAL(CONFIG_SAMA5_LCDC_DEFBACKLIGHT); + sam_putreg(SAM_LCDC_LCDCFG6, regval); + + /* 2. Enable the Pixel Clock by writing one to the CLKEN field of the + * LCDC_LCDEN register. + */ + + sam_putreg(SAM_LCDC_LCDEN, LCDC_LCDEN_CLK); + + /* 3. Poll CLKSTS field of the LCDC_LCDSR register to check that the clock + * is running. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_CLK, LCDC_LCDSR_CLK); + + /* 4. Enable Horizontal and Vertical Synchronization by writing one to the + * SYNCEN field of the LCDC_LCDEN register. + */ + + sam_putreg(SAM_LCDC_LCDEN, LCDC_LCDEN_SYNC); + + /* 5. Poll LCDSTS field of the LCDC_LCDSR register to check that the + * synchronization is up. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_LCD, LCDC_LCDSR_LCD); + + /* 6. Enable the display power signal writing one to the DISPEN field of the + * LCDC_LCDEN register. + */ + + sam_putreg(SAM_LCDC_LCDEN, LCDC_LCDEN_DISP); + + /* 7. Poll DISPSTS field of the LCDC_LCDSR register to check that the power + * signal is activated. + */ + + sam_wait_lcdstatus(LCDC_LCDSR_SIP | LCDC_LCDSR_DISP, LCDC_LCDSR_DISP); +} + +/**************************************************************************** + * Name: sam_layer_configure + * + * Description: + * Configure layer layer structures, DMA descriptor memory, and + * framebuffers + * + ****************************************************************************/ + +static void sam_layer_configure(void) +{ + /* Common layer initialization */ + + memset(&LAYER_BASE, 0, sizeof(struct sam_layer_s)); + LAYER_BASE.dscr = (struct sam_dscr_s *)SAMA5_LCDC_BASE_DSCR; + LAYER_BASE.lid = LCDC_LAYER_BASE; + LAYER_BASE.framebuffer = (uint8_t *)SAMA5_LCDC_BUFFER_BASE; + + memset(&LAYER_OVR1, 0, sizeof(struct sam_layer_s)); + LAYER_OVR1.dscr = (struct sam_dscr_s *)SAMA5_LCDC_OVR1_DSCR; + LAYER_OVR1.lid = LCDC_LAYER_OVR1; +#ifdef CONFIG_SAMA5_LCDC_OVR1 + LAYER_OVR1.framebuffer = (uint8_t *)SAMA5_LCDC_BUFFER_OVR1; +#endif + + memset(&LAYER_OVR2, 0, sizeof(struct sam_layer_s)); + LAYER_OVR2.dscr = (struct sam_dscr_s *)SAMA5_LCDC_OVR2_DSCR; + LAYER_OVR2.lid = LCDC_LAYER_OVR2; +#ifdef CONFIG_SAMA5_LCDC_OVR2 + LAYER_OVR2.framebuffer = (uint8_t *)SAMA5_LCDC_BUFFER_OVR2; +#endif + + memset(&LAYER_HEO, 0, sizeof(struct sam_layer_s)); + LAYER_HEO.dscr = (struct sam_dscr_s *)SAMA5_LCDC_HEO_DSCR; + LAYER_HEO.lid = LCDC_LAYER_HEO; +#ifdef CONFIG_SAMA5_LCDC_HEO + LAYER_HEO.framebuffer = (uint8_t *)SAMA5_LCDC_BUFFER_HEO; +#endif + +#ifdef SAMA5_HAVE_LCDC_HCRCH + memset(&LAYER_HCR, 0, sizeof(struct sam_layer_s)); + LAYER_HCR.dscr = (struct sam_dscr_s *)SAMA5_LCDC_HCR_DSCR; + LAYER_HCR.lid = LCDC_LAYER_HCR; +#ifdef CONFIG_SAMA5_LCDC_HCR + LAYER_HCR.framebuffer = (uint8_t *)SAMA5_LCDC_BUFFER_HCR; +#endif +#endif /* SAMA5_HAVE_LCDC_HCRCH */ +} + +/**************************************************************************** + * Name: sam_scalefactor + * + * Description: + * Calculate HEO scale factor + * + * Input Parameters: + * oldw - the old image width + * neww - The new image width + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_LCDC_HEO +static uint32_t sam_scalefactor(uint32_t oldw, uint32_t neww) +{ + return 2048 * (neww + 1) / (oldw + 1); +} +#endif + +/**************************************************************************** + * Name: sam_show_layer + * + * Description: + * Show the give layer with the specified orientation and (perhaps) scaling. + * + ****************************************************************************/ + +static void sam_show_layer(struct sam_layer_s *layer, + uint32_t dispx, uint32_t dispy, + uint32_t dispw, uint32_t disph, + uint32_t imgw, uint32_t imgh) +{ + struct sam_dscr_s *dscr; + uint8_t *buffer; + uintptr_t cfgaddr; + uintptr_t regaddr; + uint32_t padding = 0; + uint32_t regval; + uint32_t bytesprow; + uint32_t bytespp; + uint32_t bprow; + bool bottomup; + bool rightleft; + int lid; + + DEBUGASSERT(layer && layer->dscr); + + /* Windows position & size check */ + + if (dispx + dispw > BOARD_LCDC_WIDTH) + { + dispw = BOARD_LCDC_WIDTH - dispx; + } + + if (dispy + disph > BOARD_LCDC_HEIGHT) + { + disph = BOARD_LCDC_HEIGHT - dispy; + } + + if (dispw <= 0) + { + dispw = 1; + } + + if (disph <= 0) + { + disph = 1; + } + + if (imgw <= 0) + { + imgw = 1; + } + + if (imgh <= 0) + { + imgh = 1; + } + + /* Set display buffer and mode setup */ + + bytespp = (uint32_t)layer->bpp >> 3; + bprow = imgw * (uint32_t)layer->bpp; + bytesprow = bprow >> 3; + + if ((bprow & 7) != 0) + { + bytesprow ++; + } + + padding = 0; + if ((bytesprow & 3) != 0) + { + padding = 4 - (bytesprow & 0x3); + } + + /* Bottom-up and Right-to-left mode setup */ + + bottomup = (layer->flags & LCDC_FLAG_BOTTOMUP) != 0; + rightleft = (layer->flags & LCDC_FLAG_RIGHTLEFT) != 0; + + /* No X mirror supported layer, no Right->Left scan */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + rightleft = false; + } +#endif + + dscr = layer->dscr; + lid = layer->lid; + buffer = layer->framebuffer; + + cfgaddr = g_layercfg[lid]; + + /* Normal direction: Left,Top -> Right,Down */ + + if ((!rightleft && !bottomup && layer->rotation == LCDC_ROT_0 ) || + ( rightleft && bottomup && layer->rotation == LCDC_ROT_180)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* X0 ++ */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0); + } +#endif + + /* Y0 ++ */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, padding); + + /* Pointer to Left,Top (x0,y0) */ + } + + /* X mirror: Right,Top -> Left,Down */ + + else if (( rightleft && !bottomup && layer->rotation == LCDC_ROT_0 ) || + (!rightleft && bottomup && layer->rotation == LCDC_ROT_180)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* X1 -- */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0 - 2*bytespp); + } +#endif + + /* Y0 ++ */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 2*bytesprow + padding - 2*bytespp); + + /* Pointer to Right,Top (x1,y0) */ + + buffer = (uint8_t *) + ((uint32_t)layer->framebuffer + bytespp * (imgw - 1)); + } + + /* Y mirror: Left,Down -> Right,Top */ + + else if ((!rightleft && bottomup && layer->rotation == LCDC_ROT_0 ) || + ( rightleft && !bottomup && layer->rotation == LCDC_ROT_180)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* X0 ++ */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0); + } +#endif + + /* Y1 -- */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 0 - (2*bytesprow + padding)); + + /* Pointer to Left,Down (x0,y1) */ + + buffer = (uint8_t *) + ((uintptr_t)layer->framebuffer + (bytesprow + padding) * (imgh - 1)); + } + + /* X,Y mirror: Right,Top -> Left,Down */ + + else if (( rightleft && bottomup && layer->rotation == LCDC_ROT_0 ) || + (!rightleft && !bottomup && layer->rotation == LCDC_ROT_180)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* X1 -- */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0 - 2*bytespp; + } +#endif + + /* Y1 -- */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 0 - (2*bytespp + padding)); + + /* Pointer to Left,Down (x1,y1) */ + + buffer = (uint8_t *) + ((uint32_t)layer->framebuffer + + (bytesprow + padding) * (imgh - 1) + + bytespp * (imgw - 1)); + } + + /* Rotate 90: Down,Left -> Top,Right (with w,h swap) */ + + else if ((!rightleft && !bottomup && layer->rotation == LCDC_ROT_90 ) || + ( rightleft && bottomup && layer->rotation == LCDC_ROT_270)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* Y -- as pixels in row */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0 - (bytespp + bytesprow + padding)); + } +#endif + + /* X ++ as rows */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, (bytesprow + padding) * (imgh - 1)); + + /* Pointer to Bottom,Left */ + + buffer = (uint8_t *) + ((uint32_t)layer->framebuffer + + (bytesprow + padding) * (imgh - 1)); + } + + /* Rotate 270: Top,Right -> Down,Left (with w,h swap) */ + + else if ((!rightleft && !bottomup && layer->rotation == LCDC_ROT_270) || + ( rightleft && bottomup && layer->rotation == LCDC_ROT_90 )) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* Y ++ as pixels in row */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, bytesprow + padding - bytespp); + } +#endif + + /* X -- as rows */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 0 - 2*bytespp - (bytesprow + padding) * (imgh - 1)); + + /* Pointer to top right */ + + buffer = (uint8_t *) + ((uintptr_t)layer->framebuffer + bytespp * (imgw - 1)); + } + + /* Mirror X then Rotate 90: Down,Right -> Top,Left */ + + else if (( rightleft && !bottomup && layer->rotation == LCDC_ROT_90 ) || + (!rightleft && bottomup && layer->rotation == LCDC_ROT_270)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* Y -- as pixels in row */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, 0 - (bytespp + bytesprow + padding)); + } +#endif + + /* X -- as rows */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 0 - 2 * bytespp + (bytesprow + padding) * (imgh - 1)); + + /* Pointer to down right (x1,y1) */ + + buffer = (uint8_t *) + ((uintptr_t)layer->framebuffer + + (bytesprow + padding) * (imgh - 1) + + (bytespp) * (imgw - 1)); + } + + /* Mirror Y then Rotate 90: Top,Left -> Down,Right */ + + else if ((!rightleft && bottomup && layer->rotation == 90) || + ( rightleft && !bottomup && layer->rotation == LCDC_ROT_270)) + { + /* No rotation optimization */ + + regval = sam_getreg(cfgaddr); + regval |= LCDC_HEOCFG0_ROTDIS; + sam_putreg(cfgaddr, regval); + + /* Y ++ as pixels in row */ + +#ifdef SAMA5_HAVE_PSTRIDE + regaddr = g_layerpstride[lid]; + if (regaddr) + { + sam_putreg(regaddr, bytesprow + padding - bytespp); + } +#endif + + /* X ++ as rows */ + + regaddr = g_layerstride[lid]; + sam_putreg(regaddr, 0 - (bytesprow + padding) * (imgh - 1)); + + /* Pointer to top left (x0,y0) */ + } + + /* Configure DMA */ + /* DMA is running, just add new descriptor to queue */ + + sam_dmasetup(lid, dscr, buffer); + + /* Set layer position and size */ + +#ifdef SAMA5_HAVE_POSITION + regaddr = g_layerpos[lid]; + if (regaddr) + { + sam_putreg(regaddr, + LCDC_HEOCFG2_XPOS(dispx) | LCDC_HEOCFG2_YPOS(dispy)); + } +#endif + +#ifdef SAMA5_HAVE_SIZE + regaddr = g_layersize[lid]; + if (regaddr) + { + sam_putreg(regaddr, + LCDC_HEOCFG3_XSIZE(dispw - 1) | LCDC_HEOCFG3_YSIZE(disph - 1); + } +#endif + +#ifdef CONFIG_SAMA5_LCDC_HEO + /* Scaling setup */ + + if (lid == LCDC_HEO) + { + uint32_t srcw; + uint32_t srch; + + /* Image size only used in scaling */ + /* Scaling target */ + + if (layer->rotation == LCDC_ROT_90 || layer->rotation == LCDC_ROT_270) + { + srcw = imgh; + srch = imgw; + } + else + { + srcw = imgw; + srch = imgh; + } + + sam_putreg(SAM_LCDC_HEOCFG4, + LCDC_HEOCFG4_XMEM_SIZE(srcw - 1) | + LCDC_HEOCFG4_YMEM_SIZE(srch - 1)); + + /* Scaled */ + + if (dispw != srcw || disph != srch) + { + uint16_t xfactor; + uint16_t yfactor; + + xfactor = sam_scalefactor(dispw, srcw); + yfactor = sam_scalefactor(disph, srch); + + sam_putreg(LCDC_HEOCFG13, + LCDC_HEOCFG13_YFACTOR(yfactor) | + LCDC_HEOCFG13_XFACTOR(xfactor) | + LCDC_HEOCFG13_SCALEN; + } + + /* Disable scaling */ + + else + { + sam_putreg(LCDC_HEOCFG13, 0); + } + } +#endif + + /* Enable DMA */ + + if (buffer) + { + regaddr = g_layerblend[lid]; + regval = sam_getreg(regaddr); + regval |= LCDC_HEOCFG12_DMA | LCDC_HEOCFG12_OVR; + sam_putreg(regaddr, regval); + } + + /* 5. Enable the relevant channel by writing one to the CHEN field of the + * CHXCHER register. + */ + + regaddr = g_layerenable[lid]; + sam_putreg(regaddr, LCDC_HEOCHER_UPDATE | LCDC_HEOCHER_CH); + + /* 6. An interrupt may be raised if unmasked when the descriptor has been + * loaded. + */ +} + +/**************************************************************************** + * Name: sam_show_base + * + * Description: + * Show the base layer + * + ****************************************************************************/ + +static void sam_show_base(void) +{ + sam_show_layer(&LAYER_BASE, 0, 0, + BOARD_LCDC_WIDTH, BOARD_LCDC_HEIGHT, BOARD_LCDC_WIDTH, BOARD_LCDC_HEIGHT); +} + +/**************************************************************************** + * Name: sam_show_hcr + * + * Description: + * Show the hardware cursor layer + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_LCDC_HCR +static void sam_show_hcr(void) +{ + uint32_t regval; + + /* Enable default transparent keying */ + + sam_putreg(SAM_LCDC_HCRCFG7, 0x00000000); + sam_putreg(SAM_LCDC_HCRCFG8, 0xffffffff); + + regval = sam_getreg(SAM_LCDC_HCRCFG9); + regval |= LCDC_HCRCFG9_CRKEY; + sam_putreg(SAM_LCDC_HCRCFG9, regval); + + /* And show the hardware cursor layer */ + + sam_show_layer(&LAYER_HCR, + (BOARD_LCDC_WIDTH - CONFIG_SAMA5_LCDC_HCR_MAXWIDTH) / 2, + (BOARD_LCDC_HEIGHT - CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT) / 2, + CONFIG_SAMA5_LCDC_HCR_MAXWIDTH, CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT, + CONFIG_SAMA5_LCDC_HCR_MAXWIDTH, CONFIG_SAMA5_LCDC_HCR_MAXHEIGHT); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_fbinitialize + * + * Description: + * Initialize the framebuffer video hardware + * + ****************************************************************************/ + +int up_fbinitialize(void) +{ +#if defined(CONFIG_SAMA5_LCDC_OVR1) && defined(CONFIG_SAMA5_LCDC_HEO) + uint32_t regval; +#endif + + gvdbg("Entry\n"); + + /* Configure layer layer structures, DMA descriptor memory, and + * framebuffers + */ + + sam_layer_configure(); + + /* Disable the LCD */ + + sam_lcd_disable(); + + /* Configure PIO pins */ + + sam_pio_config(); + + gvdbg("Configuring the LCD controller\n"); + + /* Enable the LCD peripheral clock */ + + sam_lcdc_enableclk(); + + /* Enable the LCD clock */ + + sam_putreg(SAM_PMC_SCER, PMC_LCDCK); + + /* Disable LCD interrupts */ + + sam_putreg(SAM_LCDC_LCDIDR, LCDC_LCDINT_ALL); + + /* Configure layer orientation */ + + sam_layer_orientation(); + + /* Configure layer colors */ + + sam_layer_color(); + + /* Clear the display memory */ + + sam_lcdclear(CONFIG_SAMA5_LCDC_BACKCOLOR); + + /* And turn the LCD on */ + + gvdbg("Enabling the display\n"); + sam_lcd_enable(); + + /* Display base layer */ + + sam_show_base(); + +#if defined(CONFIG_SAMA5_LCDC_OVR1) && defined(CONFIG_SAMA5_LCDC_HEO) + /* Overlay 1 is above the HEO layer */ + + regval = sam_getreg(SAM_LCDC_HEOCFG12); + regval |= LCDC_HEOCFG12_VIDPRI; + sam_putreg(SAM_LCDC_HEOCFG12, regval); + + sam_putreg(SAM_LCDC_HEOCHER, LCDC_HEOCHER_UPDATE); +#endif + +#ifdef CONFIG_SAMA5_LCDC_HCR + /* Show cursor layer */ + + sam_show_hcr(); +#endif + + /* Enable the backlight. + * + * REVISIT: Backlight level could be dynamically adjustable + */ + + sam_backlight(CONFIG_SAMA5_LCDC_DEFBACKLIGHT); + + return OK; +} + +/**************************************************************************** + * Name: sam_fbgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video + * plane. + * + * Input parameters: + * None + * + * Returned value: + * Reference to the framebuffer object (NULL on failure) + * + ****************************************************************************/ + +struct fb_vtable_s *up_fbgetvplane(int vplane) +{ + gvdbg("vplane: %d\n", vplane); + if (vplane == 0) + { + return (struct fb_vtable_s *)&g_base_vtable; + } + else + { + return NULL; + } +} + +/**************************************************************************** + * Name: fb_uninitialize + * + * Description: + * Uninitialize the framebuffer driver. Bad things will happen if you + * call this without first calling fb_initialize()! + * + ****************************************************************************/ + +void fb_uninitialize(void) +{ + /* Disable the LCD controller */ + + sam_lcd_disable(); +} + +/************************************************************************************ + * Name: sam_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the SAMA5. Clearing the display + * in the normal way by writing a sequences of runs that covers the entire display + * can be slow. Here the display is cleared by simply setting all video memory to + * the specified color. + * + ************************************************************************************/ + +void sam_lcdclear(nxgl_mxpixel_t color) +{ +#if SAMA5_LCDC_BASE_BPP == 16 + uint16_t *dest = (uint16_t *)LAYER_BASE.framebuffer; + int i; + + gvdbg("Clearing display: BPP=16 color=%04x framebuffer=%08x size=%d\n", + color, LAYER_BASE.framebuffer, SAMA5_BASE_FBSIZE); + + for (i = 0; i < SAMA5_BASE_FBSIZE; i += sizeof(uint16_t)) + { + *dest++ = (uint16_t)color; + } +#elif SAMA5_LCDC_BASE_BPP == 24 + uint8_t *dest = (uint8_t *)LAYER_BASE.framebuffer; + uint8_t r; + uint8_t g; + uint8_t b; + int i; + + gvdbg("Clearing display: BPP=24 color=%06x framebuffer=%08x size=%d\n", + color, LAYER_BASE.framebuffer, SAMA5_BASE_FBSIZE); + + b = color & 0xff; + g = (color >> 8) & 0xff; + r = (color >> 16) & 0xff; + + for (i = 0; i < SAMA5_BASE_FBSIZE; i += 3*sizeof(uint8_t)) + { + *dest++ = b; + *dest++ = g; + *dest++ = r; + } +#elif SAMA5_LCDC_BASE_BPP == 32 + uint32_t *dest = (uint32_t *)LAYER_BASE.framebuffer; + int i; + + gvdbg("Clearing display: BPP=32 color=%08x framebuffer=%08x size=%d\n", + color, LAYER_BASE.framebuffer, SAMA5_BASE_FBSIZE); + + for (i = 0; i < SAMA5_BASE_FBSIZE; i += sizeof(uint32_t)) + { + *dest++ = (uint32_t)color; + } +#endif +} diff --git a/arch/arm/src/sama5/sam_lcd.h b/arch/arm/src/sama5/sam_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..d16a2ec6f8324054b7b47e34bda34cf9477f7eaa --- /dev/null +++ b/arch/arm/src/sama5/sam_lcd.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_lcd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_LCDC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_LCDC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include + +#include "chip/sam_lcdc.h" + +#ifdef CONFIG_SAMA5_LCDC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* These definitions provide the LCDC framebuffer memory description needed to + * remap that region to be non-cacheable and non-bufferable + */ + +#if (CONFIG_SAMA5_LCDC_FB_VBASE & 0x000fffff) != 0 +# error CONFIG_SAMA5_LCDC_FB_VBASE not aligned to 1MB boundary +#endif + +#if (CONFIG_SAMA5_LCDC_FB_PBASE & 0x000fffff) != 0 +# error CONFIG_SAMA5_LCDC_FB_PBASE not aligned to 1MB boundary +#endif + +#define SAMA5_LCDC_FBNSECTIONS \ + ((CONFIG_SAMA5_LCDC_FB_SIZE + 0x000fffff) >> 20) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/* The SAMA5 LCD driver uses the common framebuffer interfaces declared in + * include/nuttx/video/fb.h. + */ + +/************************************************************************************ + * Name: sam_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the SAMA5. Clearing the display + * in the normal way by writing a sequences of runs that covers the entire display + * can be slow. Here the dispaly is cleared by simply setting all VRAM memory to + * the specified color. + * + ************************************************************************************/ + +void sam_lcdclear(nxgl_mxpixel_t color); + +/************************************************************************************ + * Name: sam_backlight + * + * Description: + * If CONFIG_SAM_LCD_BACKLIGHT is defined, then the board-specific logic must + * provide this interface to turn the backlight on and off. + * + ************************************************************************************/ + +#ifdef CONFIG_SAM_LCD_BACKLIGHT +void sam_backlight(bool blon); +#endif + +#endif /* CONFIG_SAMA5_LCDC */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_LCDC_H */ diff --git a/arch/arm/src/sama5/sam_lowputc.c b/arch/arm/src/sama5/sam_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..84e7a37d213b7ed9be8d09f5bd5a2e344d250edf --- /dev/null +++ b/arch/arm/src/sama5/sam_lowputc.c @@ -0,0 +1,624 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_lowputc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_pio.h" +#include "sam_periphclks.h" +#include "sam_config.h" +#include "sam_dbgu.h" +#include "sam_lowputc.h" + +#include "chip/sam_uart.h" +#include "chip/sam_flexcom.h" +#include "chip/sam_dbgu.h" +#include "chip/sam_pinmap.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The UART/USART modules are driven by the peripheral clock (MCK or MCK2). */ + +#ifdef SAMA5_HAVE_FLEXCOM_CONSOLE +# define SAM_USART_CLOCK BOARD_FLEXCOM_FREQUENCY /* Frequency of the FLEXCOM clock */ +# define SAM_MR_USCLKS FLEXUS_MR_USCLKS_MCK /* Source = Main clock */ +#else +# define SAM_USART_CLOCK BOARD_USART_FREQUENCY /* Frequency of the USART clock */ +# define SAM_MR_USCLKS UART_MR_USCLKS_MCK /* Source = Main clock */ +#endif + +/* Select USART parameters for the selected console */ + +#if defined(CONFIG_SAMA5_DBGU_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_DBGU_VBASE +# define SAM_CONSOLE_BITS 8 +# define SAM_CONSOLE_2STOP 0 +# ifdef CONFIG_SAMA5_DBGU_NOCONFIG +# undef SUPPRESS_CONSOLE_CONFIG +# define SUPPRESS_CONSOLE_CONFIG 1 +# define SAM_CONSOLE_BAUD 115200 +# define SAM_CONSOLE_PARITY 0 +# else +# define SAM_CONSOLE_BAUD CONFIG_SAMA5_DBGU_BAUD +# define SAM_CONSOLE_PARITY CONFIG_SAMA5_DBGU_PARITY +# endif +#elif defined(CONFIG_UART0_SERIAL_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_UART0_VBASE +# define SAM_CONSOLE_BAUD CONFIG_UART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_UART1_VBASE +# define SAM_CONSOLE_BAUD CONFIG_UART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_UART2_VBASE +# define SAM_CONSOLE_BAUD CONFIG_UART2_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART2_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART2_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_UART3_VBASE +# define SAM_CONSOLE_BAUD CONFIG_UART3_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART3_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART3_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART3_2STOP +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define SAM_CONSOLE_VBASE SAM_UART4_VBASE +# define SAM_CONSOLE_BAUD CONFIG_UART4_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART4_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART4_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART4_2STOP +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# ifdef CONFIG_SAMA5_FLEXCOM0_USART +# define SAM_CONSOLE_VBASE SAM_FLEXCOM0_VBASE +# else +# define SAM_CONSOLE_VBASE SAM_USART0_VBASE +# endif +# define SAM_CONSOLE_BAUD CONFIG_USART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART0_2STOP +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# ifdef CONFIG_SAMA5_FLEXCOM1_USART +# define SAM_CONSOLE_VBASE SAM_FLEXCOM1_VBASE +# else +# define SAM_CONSOLE_VBASE SAM_USART1_VBASE +# endif +# define SAM_CONSOLE_BAUD CONFIG_USART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART1_2STOP +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# ifdef CONFIG_SAMA5_FLEXCOM2_USART +# define SAM_CONSOLE_VBASE SAM_FLEXCOM2_VBASE +# else +# define SAM_CONSOLE_VBASE SAM_USART2_VBASE +# endif +# define SAM_CONSOLE_BAUD CONFIG_USART2_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART2_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART2_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART2_2STOP +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# ifdef CONFIG_SAMA5_FLEXCOM3_USART +# define SAM_CONSOLE_VBASE SAM_FLEXCOM3_VBASE +# else +# define SAM_CONSOLE_VBASE SAM_USART3_VBASE +# endif +# define SAM_CONSOLE_BAUD CONFIG_USART3_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART3_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART3_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART3_2STOP +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# ifdef CONFIG_SAMA5_FLEXCOM4_USART +# define SAM_CONSOLE_VBASE SAM_FLEXCOM4_VBASE +# else +# define SAM_CONSOLE_VBASE SAM_USART4_VBASE +# endif +# define SAM_CONSOLE_BAUD CONFIG_USART4_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART4_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART4_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART4_2STOP +#else +# error "No CONFIG_U[S]ARTn_SERIAL_CONSOLE Setting" +#endif + +/* Select the settings for the mode register */ + +#if defined(SAMA5_HAVE_UART_CONSOLE) +# if SAM_CONSOLE_BITS == 8 && SAM_CONSOLE_PARITY == 0 +# elif SAM_CONSOLE_BITS == 7 && SAM_CONSOLE_PARITY != 0 +# else +# error "Unsupported combination of bits and parity in UART console" +# endif + +# if SAM_CONSOLE_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART console" +# endif +#endif + +#if SAM_CONSOLE_BITS == 5 +# define MR_CHRL_VALUE UART_MR_CHRL_5BITS /* 5 bits */ +#elif SAM_CONSOLE_BITS == 6 +# define MR_CHRL_VALUE UART_MR_CHRL_6BITS /* 6 bits */ +#elif SAM_CONSOLE_BITS == 7 +# define MR_CHRL_VALUE UART_MR_CHRL_7BITS /* 7 bits */ +#elif SAM_CONSOLE_BITS == 8 +# define MR_CHRL_VALUE UART_MR_CHRL_8BITS /* 8 bits */ +#elif SAM_CONSOLE_BITS == 9 && !defined(CONFIG_UART0_SERIAL_CONSOLE) && \ + !defined(CONFIG_UART1_SERIAL_CONSOLE) +# define MR_CHRL_VALUE UART_MR_MODE9 +#else +# error "Invalid number of bits" +#endif + +#if SAM_CONSOLE_PARITY == 1 +# define MR_PAR_VALUE UART_MR_PAR_ODD +#elif SAM_CONSOLE_PARITY == 2 +# define MR_PAR_VALUE UART_MR_PAR_EVEN +#else +# define MR_PAR_VALUE UART_MR_PAR_NONE +#endif + +#if SAM_CONSOLE_2STOP != 0 +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_2 +#else +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_1 +#endif + +#if defined(ATSAMA5D2) +# define MR_VALUE (MR_PAR_VALUE | UART_MR_PERIPHCLK | \ + UART_MR_CHMODE_NORMAL) +#elif defined(ATSAMA5D3) ||defined(ATSAMA5D4) +# define MR_VALUE (UART_MR_MODE_NORMAL | SAM_MR_USCLKS | \ + MR_CHRL_VALUE | MR_PAR_VALUE | MR_NBSTOP_VALUE | \ + UART_MR_CHMODE_NORMAL) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined(SAMA5_HAVE_UART_CONSOLE) || defined(SAMA5_HAVE_USART_CONSOLE) + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(SAM_CONSOLE_VBASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(SAM_CONSOLE_VBASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, SAM_CONSOLE_VBASE + SAM_UART_THR_OFFSET); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } + +#elif defined(SAMA5_HAVE_FLEXCOM_CONSOLE) + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(SAM_CONSOLE_VBASE + SAM_FLEXUS_CSR_OFFSET) & + FLEXUS_INT_TXEMPTY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(SAM_CONSOLE_VBASE + SAM_FLEXUS_CSR_OFFSET) & + FLEXUS_INT_TXEMPTY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, SAM_CONSOLE_VBASE + SAM_FLEXUS_THR_OFFSET); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } + +#elif defined(CONFIG_SAMA5_DBGU_CONSOLE) + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(SAM_DBGU_SR) & DBGU_INT_TXEMPTY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(SAM_DBGU_SR) & DBGU_INT_TXEMPTY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, SAM_DBGU_THR); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if defined(SAMA5_HAVE_UART_CONSOLE) || defined(SAMA5_HAVE_USART_CONSOLE) || \ + defined(SAMA5_HAVE_FLEXCOM_CONSOLE) || defined(CONFIG_SAMA5_DBGU_CONSOLE) + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void sam_lowsetup(void) +{ + /* Enable clocking for all selected UART/USARTs (USARTs may not + * necessarily be configured as UARTs). + */ + +#ifdef CONFIG_SAMA5_UART0 + sam_uart0_enableclk(); +#endif +#ifdef CONFIG_SAMA5_UART1 + sam_uart1_enableclk(); +#endif +#ifdef CONFIG_SAMA5_UART2 + sam_uart2_enableclk(); +#endif +#ifdef CONFIG_SAMA5_UART3 + sam_uart3_enableclk(); +#endif +#ifdef CONFIG_SAMA5_UART4 + sam_uart4_enableclk(); +#endif +#ifdef CONFIG_USART0_ISUART + sam_usart0_enableclk(); +#endif +#ifdef CONFIG_SAMA5_USART1 + sam_usart1_enableclk(); +#endif +#ifdef CONFIG_SAMA5_USART2 + sam_usart2_enableclk(); +#endif +#ifdef CONFIG_SAMA5_USART3 + sam_usart3_enableclk(); +#endif +#ifdef CONFIG_SAMA5_FLEXCOM0 + sam_flexcom0_enableclk(); +#endif +#ifdef CONFIG_SAMA5_FLEXCOM1 + sam_flexcom1_enableclk(); +#endif +#ifdef CONFIG_SAMA5_FLEXCOM2 + sam_flexcom2_enableclk(); +#endif +#ifdef CONFIG_SAMA5_FLEXCOM3 + sam_flexcom3_enableclk(); +#endif +#ifdef CONFIG_SAMA5_FLEXCOM4 + sam_flexcom4_enableclk(); +#endif + + /* Configure UART pins for all selected UART/USARTs. USARTs pins are + * only configured if the USART is also configured as as a UART. + */ + +#ifdef CONFIG_SAMA5_UART0 + (void)sam_configpio(PIO_UART0_RXD); + (void)sam_configpio(PIO_UART0_TXD); +#endif + +#ifdef CONFIG_SAMA5_UART1 + (void)sam_configpio(PIO_UART1_RXD); + (void)sam_configpio(PIO_UART1_TXD); +#endif + +#ifdef CONFIG_SAMA5_UART2 + (void)sam_configpio(PIO_UART2_RXD); + (void)sam_configpio(PIO_UART2_TXD); +#endif + +#ifdef CONFIG_SAMA5_UART3 + (void)sam_configpio(PIO_UART3_RXD); + (void)sam_configpio(PIO_UART3_TXD); +#endif + +#ifdef CONFIG_SAMA5_UART4 + (void)sam_configpio(PIO_UART4_RXD); + (void)sam_configpio(PIO_UART4_TXD); +#endif + +#if defined(CONFIG_USART0_ISUART) && defined(CONFIG_SAMA5_USART0) + (void)sam_configpio(PIO_USART0_RXD); + (void)sam_configpio(PIO_USART0_TXD); +#ifdef CONFIG_USART0_OFLOWCONTROL + (void)sam_configpio(PIO_USART0_CTS); +#endif +#ifdef CONFIG_USART0_IFLOWCONTROL + (void)sam_configpio(PIO_USART0_RTS); +#endif +#endif + +#if defined(CONFIG_USART1_ISUART) && defined(CONFIG_SAMA5_USART1) + (void)sam_configpio(PIO_USART1_RXD); + (void)sam_configpio(PIO_USART1_TXD); +#ifdef CONFIG_USART1_OFLOWCONTROL + (void)sam_configpio(PIO_USART1_CTS); +#endif +#ifdef CONFIG_USART1_IFLOWCONTROL + (void)sam_configpio(PIO_USART1_RTS); +#endif +#endif + +#if defined(CONFIG_USART2_ISUART) && defined(CONFIG_SAMA5_USART2) + (void)sam_configpio(PIO_USART2_RXD); + (void)sam_configpio(PIO_USART2_TXD); +#ifdef CONFIG_USART2_OFLOWCONTROL + (void)sam_configpio(PIO_USART2_CTS); +#endif +#ifdef CONFIG_USART2_IFLOWCONTROL + (void)sam_configpio(PIO_USART2_RTS); +#endif +#endif + +#if defined(CONFIG_USART3_ISUART) && defined(CONFIG_SAMA5_USART3) + (void)sam_configpio(PIO_USART3_RXD); + (void)sam_configpio(PIO_USART3_TXD); +#ifdef CONFIG_USART3_OFLOWCONTROL + (void)sam_configpio(PIO_USART3_CTS); +#endif +#ifdef CONFIG_USART3_IFLOWCONTROL + (void)sam_configpio(PIO_USART3_RTS); +#endif +#endif + +#if defined(CONFIG_USART4_ISUART) && defined(CONFIG_SAMA5_USART4) + (void)sam_configpio(PIO_USART4_RXD); + (void)sam_configpio(PIO_USART4_TXD); +#ifdef CONFIG_USART4_OFLOWCONTROL + (void)sam_configpio(PIO_USART4_CTS); +#endif +#ifdef CONFIG_USART4_IFLOWCONTROL + (void)sam_configpio(PIO_USART4_RTS); +#endif +#endif + + /* For Flexcom USARTs: + * + * FLEXCOM_IO0 = TXD + * FLEXCOM_IO1 = RXD + * FLEXCOM_IO2 = SCK + * FLEXCOM_IO3 = CTS + * FLEXCOM_IO4 = RTS + */ + +#if defined(CONFIG_USART0_ISUART) && defined(CONFIG_SAMA5_FLEXCOM0_USART) + (void)sam_configpio(PIO_FLEXCOM0_IO0); + (void)sam_configpio(PIO_FLEXCOM0_IO1); +#ifdef CONFIG_USART0_OFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM0_IO3); +#endif +#ifdef CONFIG_USART0_IFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM0_IO4); +#endif +#endif + +#if defined(CONFIG_USART1_ISUART) && defined(CONFIG_SAMA5_FLEXCOM1_USART) + (void)sam_configpio(PIO_FLEXCOM1_IO0); + (void)sam_configpio(PIO_FLEXCOM1_IO1); +#ifdef CONFIG_USART1_OFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM1_IO3); +#endif +#ifdef CONFIG_USART1_IFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM1_IO4); +#endif +#endif + +#if defined(CONFIG_USART2_ISUART) && defined(CONFIG_SAMA5_FLEXCOM2_USART) + (void)sam_configpio(PIO_FLEXCOM2_IO0); + (void)sam_configpio(PIO_FLEXCOM2_IO1); +#ifdef CONFIG_USART2_OFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM2_IO3); +#endif +#ifdef CONFIG_USART2_IFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM2_IO4); +#endif +#endif + +#if defined(CONFIG_USART3_ISUART) && defined(CONFIG_SAMA5_FLEXCOM3_USART) + (void)sam_configpio(PIO_FLEXCOM3_IO0); + (void)sam_configpio(PIO_FLEXCOM3_IO1); +#ifdef CONFIG_USART3_OFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM3_IO3); +#endif +#ifdef CONFIG_USART3_IFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM3_IO4); +#endif +#endif + +#if defined(CONFIG_USART4_ISUART) && defined(CONFIG_SAMA5_FLEXCOM4_USART) + (void)sam_configpio(PIO_FLEXCOM4_IO0); + (void)sam_configpio(PIO_FLEXCOM4_IO1); +#ifdef CONFIG_USART4_OFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM4_IO3); +#endif +#ifdef CONFIG_USART4_IFLOWCONTROL + (void)sam_configpio(PIO_FLEXCOM4_IO4); +#endif +#endif + + /* Configure the console (only) */ + +#if (defined(SAMA5_HAVE_UART_CONSOLE) || defined(SAMA5_HAVE_USART_CONSOLE)) && \ + !defined(SUPPRESS_CONSOLE_CONFIG) + /* Reset and disable receiver and transmitter */ + + putreg32((UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS), + SAM_CONSOLE_VBASE + SAM_UART_CR_OFFSET); + + /* Disable all interrupts */ + + putreg32(0xffffffff, SAM_CONSOLE_VBASE + SAM_UART_IDR_OFFSET); + + /* Set up the mode register */ + + putreg32(MR_VALUE, SAM_CONSOLE_VBASE + SAM_UART_MR_OFFSET); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower USART clocks. + */ + + putreg32(((SAM_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) / (SAM_CONSOLE_BAUD << 4)), + SAM_CONSOLE_VBASE + SAM_UART_BRGR_OFFSET); + + /* Enable receiver & transmitter */ + + putreg32((UART_CR_RXEN | UART_CR_TXEN), + SAM_CONSOLE_VBASE + SAM_UART_CR_OFFSET); + +#elif defined(SAMA5_HAVE_FLEXCOM_CONSOLE) && !defined(SUPPRESS_CONSOLE_CONFIG) + /* Select USART mode for the Flexcom */ + + putreg32(FLEX_MR_OPMODE_USART, SAM_CONSOLE_VBASE + SAM_FLEX_MR_OFFSET); + + /* Reset and disable receiver and transmitter */ + + putreg32((FLEXUS_CR_RSTRX | FLEXUS_CR_RSTTX | FLEXUS_CR_RXDIS | FLEXUS_CR_TXDIS), + SAM_CONSOLE_VBASE + SAM_FLEXUS_CR_OFFSET); + + /* Disable all interrupts */ + + putreg32(0xffffffff, SAM_CONSOLE_VBASE + SAM_FLEXUS_IDR_OFFSET); + + /* Set up the mode register */ + + putreg32(MR_VALUE, SAM_CONSOLE_VBASE + SAM_FLEXUS_MR_OFFSET); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower USART clocks. + */ + + putreg32(((SAM_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) / (SAM_CONSOLE_BAUD << 4)), + SAM_CONSOLE_VBASE + SAM_FLEXUS_BRGR_OFFSET); + + /* Enable receiver & transmitter */ + + putreg32((FLEXUS_CR_RXEN | FLEXUS_CR_TXEN), + SAM_CONSOLE_VBASE + SAM_FLEXUS_CR_OFFSET); + +#endif + +#ifdef CONFIG_SAMA5_DBGU + /* Initialize the DBGU (might be the serial console) */ + + sam_dbgu_initialize(); +#endif +} diff --git a/arch/arm/src/sama5/sam_lowputc.h b/arch/arm/src/sama5/sam_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..a7e193062ebf4df931625d465c5a22eeb0647fef --- /dev/null +++ b/arch/arm/src/sama5/sam_lowputc.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void sam_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H */ diff --git a/arch/arm/src/sama5/sam_memories.c b/arch/arm/src/sama5/sam_memories.c new file mode 100644 index 0000000000000000000000000000000000000000..231545ed55928a05a83286315d8c69ebcb21805f --- /dev/null +++ b/arch/arm/src/sama5/sam_memories.c @@ -0,0 +1,1066 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_memories.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "sam_pgalloc.h" +#include "sam_memories.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: peripha_physregaddr + * + * Description: + * Given the virtual address of a peripheral A register, return the + * physical address of the register + * + ****************************************************************************/ + +static inline uintptr_t peripha_physregaddr(uintptr_t virtregaddr) +{ +#if SAM_PERIPHA_PSECTION != SAM_PERIPHA_VSECTION + /* Get the offset into the virtual memory region section containing the + * register + */ + + uintptr_t sectoffset = virtregaddr - SAM_PERIPHA_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_PERIPHA_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtregaddr; + +#endif +} + +/**************************************************************************** + * Name: periphb_physregaddr + * + * Description: + * Given the virtual address of a peripheral B register, return the + * physical address of the register + * + ****************************************************************************/ + +static inline uintptr_t periphb_physregaddr(uintptr_t virtregaddr) +{ +#if SAM_PERIPHB_PSECTION != SAM_PERIPHB_VSECTION + /* Get the offset into the virtual memory region section containing the + * register + */ + + uintptr_t sectoffset = virtregaddr - SAM_PERIPHB_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_PERIPHB_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtregaddr; + +#endif +} + +/**************************************************************************** + * Name: periphc_physregaddr + * + * Description: + * Given the virtual address of a peripheral C register, return the + * physical address of the register + * + ****************************************************************************/ + +#ifdef SAM_PERIPHC_VSECTION +static inline uintptr_t periphc_physregaddr(uintptr_t virtregaddr) +{ +#if SAM_PERIPHB_PSECTION != SAM_PERIPHB_VSECTION + /* Get the offset into the virtual memory region section containing the + * register + */ + + uintptr_t sectoffset = virtregaddr - SAM_PERIPHC_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_PERIPHC_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtregaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: sysc_physregaddr + * + * Description: + * Given the virtual address of a system controller register, return the + * physical address of the register + * + ****************************************************************************/ + +#ifdef SAM_SYSC_VSECTION +static inline uintptr_t sysc_physregaddr(uintptr_t virtregaddr) +{ +#if SAM_SYSC_PSECTION != SAM_SYSC_VSECTION + /* Get the offset into the virtual memory region section containing the + * register + */ + + uintptr_t sectoffset = virtregaddr - SAM_SYSC_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_SYSC_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtregaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: isram_physramaddr + * + * Description: + * Given the virtual address of an internal SRAM memory location, return the + * physical address of that location + * + ****************************************************************************/ + +static inline uintptr_t isram_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_ISRAM_PSECTION != SAM_ISRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_ISRAM_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_ISRAM_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} + +/**************************************************************************** + * Name: sdram_physramaddr + * + * Description: + * Given the virtual address of an external SDRAM memory location, return + * the physical address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_DDRCS) || defined(CONFIG_SAMA5_BOOT_SDRAM) || \ + defined(CONFIG_BOOT_SDRAM_DATA) +static inline uintptr_t sdram_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_DDRCS_PSECTION != SAM_DDRCS_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_DDRCS_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_DDRCS_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: nfcsram_physramaddr + * + * Description: + * Given the virtual address of an NFC SRAM memory location, return the + * physical address of that location. If NFC SRAM is not being used by + * the NAND logic, then it may be used a general purpose SRAM. + * + ****************************************************************************/ + +static inline uintptr_t nfcsram_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_NFCSRAM_PSECTION != SAM_NFCSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_NFCSRAM_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_NFCSRAM_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} + +/**************************************************************************** + * Name: udphsram_physramaddr + * + * Description: + * Given the virtual address of an UDPH SRAM memory location, return the + * physical address of that location + * + ****************************************************************************/ + +static inline uintptr_t udphsram_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_UDPHSRAM_PSECTION != SAM_UDPHSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_UDPHSRAM_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_UDPHSRAM_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} + +/**************************************************************************** + * Name: ebics0_physramaddr + * + * Description: + * Given the virtual address of an external CS0 SRAM memory location, + * return the physical address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) +static inline uintptr_t ebics0_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_EBICS0_PSECTION != SAM_EBICS0_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_EBICS0_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS0_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics1_physramaddr + * + * Description: + * Given the virtual address of an external CS1 SRAM memory location, + * return the physical address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) +static inline uintptr_t ebics1_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_EBICS1_PSECTION != SAM_EBICS1_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_EBICS1_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS1_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics2_physramaddr + * + * Description: + * Given the virtual address of an external CS2 SRAM memory location, + * return the physical address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) +static inline uintptr_t ebics2_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_EBICS2_PSECTION != SAM_EBICS2_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_EBICS2_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS2_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics3_physramaddr + * + * Description: + * Given the virtual address of an external CS3 SRAM memory location, + * return the physical address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) +static inline uintptr_t ebics3_physramaddr(uintptr_t virtramaddr) +{ +#if SAM_EBICS3_PSECTION != SAM_EBICS3_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = virtramaddr - SAM_EBICS3_VSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS3_PSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: isram_virtramaddr + * + * Description: + * Given the physical address of an internal SRAM memory location, return + * the virtual address of that location + * + ****************************************************************************/ + +static inline uintptr_t isram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_ISRAM_PSECTION != SAM_ISRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_ISRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_ISRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} + +/**************************************************************************** + * Name: sdram_virtramaddr + * + * Description: + * Given the physical address of an external SDRAM memory location, return + * the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_DDRCS) || defined(CONFIG_SAMA5_BOOT_SDRAM) || \ + defined(CONFIG_BOOT_SDRAM_DATA) +static inline uintptr_t sdram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_DDRCS_PSECTION != SAM_DDRCS_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_DDRCS_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_DDRCS_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: nfcsram_virtramaddr + * + * Description: + * Given the physical address of an NFC SRAM memory location, return the + * virtual address of that location. If NFC SRAM is not being used by + * the NAND logic, then it may be used a general purpose SRAM. + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_HAVE_NAND +static inline uintptr_t nfcsram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_NFCSRAM_PSECTION != SAM_NFCSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_NFCSRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_NFCSRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: udphsram_virtramaddr + * + * Description: + * Given the physical address of an UDPH SRAM memory location, return the + * virtual address of that location + * + ****************************************************************************/ + +static inline uintptr_t udphsram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_UDPHSRAM_PSECTION != SAM_UDPHSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_UDPHSRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_UDPHSRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} + +/**************************************************************************** + * Name: ebics0_virtramaddr + * + * Description: + * Given the physical address of an external CS0 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) +static inline uintptr_t ebics0_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS0_PSECTION != SAM_EBICS0_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS0_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS0_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics1_virtramaddr + * + * Description: + * Given the physical address of an external CS1 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) +static inline uintptr_t ebics1_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS1_PSECTION != SAM_EBICS1_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS1_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS1_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics2_virtramaddr + * + * Description: + * Given the physical address of an external CS2 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) +static inline uintptr_t ebics2_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS2_PSECTION != SAM_EBICS2_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS2_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS2_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics3_virtramaddr + * + * Description: + * Given the physical address of an external CS3 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) +static inline uintptr_t ebics3_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS3_PSECTION != SAM_EBICS3_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS3_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS3_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_physregaddr + * + * Description: + * Given the virtual address of a register, return the physical address of + * the register + * + ****************************************************************************/ + +uintptr_t sam_physregaddr(uintptr_t virtregaddr) +{ + /* Check for a peripheral A register */ + + if (virtregaddr >= SAM_PERIPHA_VSECTION && + virtregaddr < (SAM_PERIPHA_VSECTION + SAM_PERIPHA_SIZE)) + { + return peripha_physregaddr(virtregaddr); + } + + /* Check for a peripheral A register */ + + else if (virtregaddr >= SAM_PERIPHB_VSECTION && + virtregaddr < (SAM_PERIPHB_VSECTION + SAM_PERIPHB_SIZE)) + { + return periphb_physregaddr(virtregaddr); + } + + /* Check for a system controller/peripheral C register + * + * Naming of peripheral sections differs between the SAMA5D3 and SAMA5D4. + * There is nothing called SYSC in the SAMA5D4 memory map. The third + * peripheral section is un-named in the SAMA5D4 memory map, but I have + * chosen the name PERIPHC for this usage. + */ + +#ifdef SAM_PERIPHC_VSECTION + else if (virtregaddr >= SAM_PERIPHC_VSECTION && + virtregaddr < (SAM_PERIPHC_VSECTION + SAM_PERIPHC_SIZE)) + { + return periphc_physregaddr(virtregaddr); + } +#endif + +#ifdef SAM_SYSC_VSECTION + else if (virtregaddr >= SAM_SYSC_VSECTION && + virtregaddr < (SAM_SYSC_VSECTION + SAM_SYSC_SIZE)) + { + return sysc_physregaddr(virtregaddr); + } +#endif + + /* Check for NFCS SRAM. If NFC SRAM is being used by the NAND logic, + * then it will be treated as peripheral space. + */ + +#ifdef CONFIG_SAMA5_HAVE_NAND + if (virtregaddr >= SAM_NFCSRAM_VSECTION && + virtregaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE)) + { + return nfcsram_physramaddr(virtregaddr); + } +#endif + + /* We will not get here unless we are called with an invalid register + * address + */ + + dbg("Bad virtual address: %08lx\n", virtregaddr); + DEBUGPANIC(); + return virtregaddr; +} + +/**************************************************************************** + * Name: sam_physramaddr + * + * Description: + * Given the virtual address of a RAM memory location, return the physical + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_physramaddr(uintptr_t virtramaddr) +{ + /* Check for internal SRAM. We we assume that ISRAM0 and ISRAM1 are + * contiguous. + */ + + if (virtramaddr >= SAM_ISRAM_VSECTION && + virtramaddr < (SAM_ISRAM_VSECTION + SAM_ISRAM_SIZE)) + { + return isram_physramaddr(virtramaddr); + } + +#if defined(CONFIG_SAMA5_DDRCS) + /* Check for external SDRAM. We may have external DRAM if, as examples, + * we are running from NOR FLASH or ISRAM with data in DRAM + * (SAMA5_BOOT_ISRAM or SAMA5_BOOT_CS0FLASH with CONFIG_SAMA5_DDRCS). In + * this case, the DRAM configuration settings, SAM_DDRCS_VSECTION and + * SAMA5_DDRCS_SIZE give us the correct size of the installed DRAM. + * + * SAM_DDRCS_VSECTION -- Virtual start of the DRAM memory region + * SAMA5_DDRCS_SIZE -- The installed DRAM size. + * + * REVISIT: However, not all of it may be mapped? Only the "primary" + * RAM region will be mapped by default. See below. + */ + + else if (virtramaddr >= SAM_DDRCS_VSECTION && + virtramaddr < (SAM_DDRCS_VSECTION + SAMA5_DDRCS_SIZE)) + { + return sdram_physramaddr(virtramaddr); + } + +#elif defined(CONFIG_SAMA5_BOOT_SDRAM) || defined(CONFIG_BOOT_SDRAM_DATA) + /* The DDRCS values may be highly couple to the CONFIG_RAM_START, + * CONFIG_RAM_VSTART, and CONFIG_RAM_SIZE when CONFIG_SAMA5_BOOT_SDRAM or + * CONFIG_BOOT_SDRAM_DATA is selected. + * + * CONFIG_SAMA5_BOOT_SDRAM -- We were booted into DRAM by some bootloader. + * DRAM support is not enabled, SAMA5_DDRCS_SIZE is not valid. + * CONFIG_BOOT_SDRAM_DATA -- We are running from NOR or ISRAM, but our + * .bss, .data, and primary heap are in DRAM (In this case, I would + * expect CONFIG_SAMA5_DDRCS to also be set, however). + * + * In all cases, CONFIG_RAM_START, RAM_VSTART, and RAM_SIZE describe the + * "primary" RAM region that is mapped at boot time. This "primary" RAM + * region is the one that holds .bss, .data, and primary head. And this + * is the only DRAM memory region that is mapped at boot time. + * + * REVISIT: How does this work if we want to set aside a block of DRAM + * outside of .bss, .data, and .heap for, as an example, for a framebuffer. + * In that case, we will to revisit this. + */ + + else if (virtramaddr >= CONFIG_RAM_VSTART && + virtramaddr < (CONFIG_RAM_VSTART + CONFIG_RAM_SIZE)) + { + return sdram_physramaddr(virtramaddr); + } +#endif + + /* Check for NFCS SRAM. If NFC SRAM is not being used by the NAND logic, + * then it may be used a general purpose SRAM. + */ + +#ifndef CONFIG_SAMA5_HAVE_NAND + if (virtramaddr >= SAM_NFCSRAM_VSECTION && + virtramaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE)) + { + return nfcsram_physramaddr(virtramaddr); + } +#endif + + /* Check for UDPH SRAM. */ + + if (virtramaddr >= SAM_UDPHSRAM_VSECTION && + virtramaddr < (SAM_UDPHSRAM_VSECTION + SAM_UDPHSRAM_SIZE)) + { + return udphsram_physramaddr(virtramaddr); + } + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) + /* Check for external SRAM or PSRAM on CS0 */ + + else if (virtramaddr >= SAM_EBICS0_VSECTION && + virtramaddr < (SAM_EBICS0_VSECTION + SAMA5_EBICS0_SIZE)) + { + return ebics0_physramaddr(virtramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) + /* Check for external SRAM or PSRAM on CS1 */ + + else if (virtramaddr >= SAM_EBICS1_VSECTION && + virtramaddr < (SAM_EBICS1_VSECTION + SAMA5_EBICS1_SIZE)) + { + return ebics1_physramaddr(virtramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) + /* Check for external SRAM or PSRAM on CS2 */ + + else if (virtramaddr >= SAM_EBICS2_VSECTION && + virtramaddr < (SAM_EBICS2_VSECTION + SAMA5_EBICS2_SIZE)) + { + return ebics2_physramaddr(virtramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) + /* Check for external SRAM or PSRAM on CS3 */ + + else if (virtramaddr >= SAM_EBICS3_VSECTION && + virtramaddr < (SAM_EBICS3_VSECTION + SAMA5_EBICS3_SIZE)) + { + return ebics3_physramaddr(virtramaddr); + } +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Check if the virtual address lies in the user data area and, if so + * get the mapping to the physical address in the page pool. + */ + + else + { + uintptr_t paddr = sam_physpgaddr(virtramaddr); + if (paddr != 0) + { + return paddr; + } + } +#endif + + /* We will not get here unless we are called with an invalid or + * unsupported RAM address. Special case the NULL address. + */ + + if (virtramaddr != 0) + { + dbg("Bad virtual address: %08lx\n", virtramaddr); + DEBUGPANIC(); + } + + return virtramaddr; +} + +/**************************************************************************** + * Name: sam_virtramaddr + * + * Description: + * Give the physical address of a RAM memory location, return the virtual + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_virtramaddr(uintptr_t physramaddr) +{ + /* Check for internal SRAM. We we assume that ISRAM0 and ISRAM1 are + * contiguous. + */ + + if (physramaddr >= SAM_ISRAM_PSECTION && + physramaddr < (SAM_ISRAM_PSECTION + SAM_ISRAM_SIZE)) + { + return isram_virtramaddr(physramaddr); + } + +#ifdef CONFIG_SAMA5_DDRCS + /* Check for external SDRAM. NOTE: See comments in sam_physramaddr */ + + else if (physramaddr >= SAM_DDRCS_PSECTION && + physramaddr < (SAM_DDRCS_PSECTION + SAMA5_DDRCS_SIZE)) + { + return sdram_virtramaddr(physramaddr); + } + +#elif defined(CONFIG_SAMA5_BOOT_SDRAM) || defined(CONFIG_BOOT_SDRAM_DATA) + /* See comments in sam_physramaddr */ + + else if (physramaddr >= CONFIG_RAM_START && + physramaddr < (CONFIG_RAM_START + CONFIG_RAM_SIZE)) + { + return sdram_physramaddr(physramaddr); + } + +#endif + + /* Check for NFCS SRAM. If NFC SRAM is not being used by the NAND logic, + * then it may be used a general purpose SRAM. + */ + +#ifndef CONFIG_SAMA5_HAVE_NAND + if (physramaddr >= SAM_NFCSRAM_PSECTION && + physramaddr < (SAM_NFCSRAM_PSECTION + SAM_NFCSRAM_SIZE)) + { + return nfcsram_virtramaddr(physramaddr); + } +#endif + + /* Check for UDPH SRAM. */ + + if (physramaddr >= SAM_UDPHSRAM_PSECTION && + physramaddr < (SAM_UDPHSRAM_PSECTION + SAM_UDPHSRAM_SIZE)) + { + return udphsram_virtramaddr(physramaddr); + } + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) + /* Check for external SRAM or PSRAM on CS0 */ + + else if (physramaddr >= SAM_EBICS0_PSECTION && + physramaddr < (SAM_EBICS0_PSECTION + SAMA5_EBICS0_SIZE)) + { + return ebics0_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) + /* Check for external SRAM or PSRAM on CS1 */ + + else if (physramaddr >= SAM_EBICS1_PSECTION && + physramaddr < (SAM_EBICS1_PSECTION + SAMA5_EBICS1_SIZE)) + { + return ebics1_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) + /* Check for external SRAM or PSRAM on CS2 */ + + else if (physramaddr >= SAM_EBICS2_PSECTION && + physramaddr < (SAM_EBICS2_PSECTION + SAMA5_EBICS2_SIZE)) + { + return ebics2_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) + /* Check for external SRAM or PSRAM on CS3 */ + + else if (physramaddr >= SAM_EBICS3_PSECTION && + physramaddr < (SAM_EBICS3_PSECTION + SAMA5_EBICS3_SIZE)) + { + return ebics3_virtramaddr(physramaddr); + } +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Check if the physical address lies in the page pool and, if so + * get the mapping to the virtual address in the user data area. + */ + + else + { + uintptr_t vaddr = sam_virtpgaddr(physramaddr); + if (vaddr != 0) + { + return vaddr; + } + } +#endif + + /* We will not get here unless we are called with an invalid or + * unsupported RAM address. Special case the NULL address. + */ + + if (physramaddr != 0) + { + dbg("Bad physical address: %08lx\n|", physramaddr); + DEBUGPANIC(); + } + + return physramaddr; +} diff --git a/arch/arm/src/sama5/sam_memories.h b/arch/arm/src/sama5/sam_memories.h new file mode 100644 index 0000000000000000000000000000000000000000..249331cbf5b4a8c61d72f4f463eee46c52efd1b7 --- /dev/null +++ b/arch/arm/src/sama5/sam_memories.h @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_memories.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H +#define __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_physregaddr + * + * Description: + * Give the virtual address of a register, return the physical address of + * the register + * + ****************************************************************************/ + +uintptr_t sam_physregaddr(uintptr_t virtregaddr); + +/**************************************************************************** + * Name: sam_physramaddr + * + * Description: + * Give the virtual address of a RAM memory location, return the physical + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_physramaddr(uintptr_t vramaddr); + +/**************************************************************************** + * Name: sam_virtramaddr + * + * Description: + * Give the physical address of a RAM memory location, return the virtual + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_virtramaddr(uintptr_t physramaddr); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H */ diff --git a/arch/arm/src/sama5/sam_memorymap.c b/arch/arm/src/sama5/sam_memorymap.c new file mode 100644 index 0000000000000000000000000000000000000000..89ab0c2f9afecafb7661090c0719cada3fb18d6f --- /dev/null +++ b/arch/arm/src/sama5/sam_memorymap.c @@ -0,0 +1,55 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_memorymap.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* chip.h holds the characteristics of the configured chip */ + +#include +#include + +/* Include the correct logic for the configured chip */ + +#if defined(ATSAMA5D2) +# include "sama5d2x_memorymap.c" +#elif defined(ATSAMA5D3) +# include "sama5d3x_memorymap.c" +#elif defined(ATSAMA5D4) +# include "sama5d4x_memorymap.c" +#else +# error Unrecognized SAMA5 family +#endif diff --git a/arch/arm/src/sama5/sam_memorymap.h b/arch/arm/src/sama5/sam_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..673f4f9ef36f97b207358ac8318134b160a11d6f --- /dev/null +++ b/arch/arm/src/sama5/sam_memorymap.h @@ -0,0 +1,116 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMA5_SAM_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "mmu.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* The vectors are, by default, positioned at the beginning of the text + * section. Under what conditions do we have to remap the these vectors? + * + * 1) If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case, + * the vectors will lie at virtual address 0xffff:000 and we will need + * to a) copy the vectors to another location, and b) map the vectors + * to that address, and + * + * For the case of CONFIG_ARCH_LOWVECTORS=y, defined. The SAMA5 boot-up + * logic will map the beginning of the boot memory to address 0x0000:0000 + * using both the MMU and the AXI matrix REMAP register. No vector copy + * is required because the vectors are position at the beginning of the + * boot memory at link time and no additional MMU mapping required. + * + * 2) We are not using a ROM page table. We cannot set any custom mappings in + * the case and the build must conform to the ROM page table properties + */ + +#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE) +# error High vector remap cannot be performed if we are using a ROM page table +#endif + +/* If SDRAM needs to be configured, then it will be configured twice: It + * will first be configured to a temporary state to support low-level + * initialization. After the SDRAM has been fully initialized, SRAM be used + * to set the SDRM in its final, fully cache-able state. + */ + +#undef NEED_SDRAM_CONFIGURATION +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) +# define NEED_SDRAM_CONFIGURATION 1 +#endif + +#undef NEED_SDRAM_MAPPING +#undef NEED_SDRAM_REMAPPING +#if defined(NEED_SDRAM_CONFIGURATION) && !defined(CONFIG_ARCH_ROMPGTABLE) +# define NEED_SDRAM_MAPPING 1 +# define NEED_SDRAM_REMAPPING 1 +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + + /* This table describes how to map a set of 1Mb pages to space the physical + * address space of the SAMA5. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +extern const struct section_mapping_s g_section_mapping[]; +extern const size_t g_num_mappings; +#endif + +/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +extern const struct section_mapping_s g_operational_mapping[]; +extern const size_t g_num_opmappings; +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_MEMORYMAP_H */ diff --git a/arch/arm/src/sama5/sam_nand.c b/arch/arm/src/sama5/sam_nand.c new file mode 100644 index 0000000000000000000000000000000000000000..d5d235d21685c828b942afc4098d483a6a9dec6a --- /dev/null +++ b/arch/arm/src/sama5/sam_nand.c @@ -0,0 +1,3107 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_nand.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "cache.h" + +#include "sam_memories.h" +#include "sam_dmac.h" +#include "sam_pmecc.h" +#include "sam_nand.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_CE +# define ENABLE_CE(priv) board_nand_ce(priv->cs, true) +# define DISABLE_CE(priv) board_nand_ce(priv->cs, false) +#else +# define ENABLE_CE(priv) +# define DISABLE_CE(priv) +#endif + +/* Nand flash chip status codes */ + +#define STATUS_ERROR (1 << 0) +#define STATUS_READY (1 << 6) + +/* NFC ALE CLE command parameter */ + +#define HSMC_ALE_COL_EN (1 << 0) +#define HSMC_ALE_ROW_EN (1 << 1) +#define HSMC_CLE_WRITE_EN (1 << 2) +#define HSMC_CLE_DATA_EN (1 << 3) +#define HSMC_CLE_VCMD2_EN (1 << 4) + +/* Number of tries for erasing or writing block */ + +#define NAND_ERASE_NRETRIES 2 +#define NAND_WRITE_NRETRIES 2 + +/* DMA Configuration */ + +#define NFCSRAM_DMA_FLAGS \ + DMACH_FLAG_FIFOCFG_LARGEST | \ + (DMACH_FLAG_PERIPHPID_MAX | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \ + DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHINCREMENT | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | DMACH_FLAG_MEMAHB_AHB_IF0 | \ + DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4) + +#define NAND_DMA_FLAGS8 \ + DMACH_FLAG_FIFOCFG_LARGEST | \ + (DMACH_FLAG_PERIPHPID_MAX | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \ + DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | DMACH_FLAG_MEMAHB_AHB_IF0 | \ + DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4) + +#define NAND_DMA_FLAGS16 \ + DMACH_FLAG_FIFOCFG_LARGEST | \ + (DMACH_FLAG_PERIPHPID_MAX | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \ + DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | DMACH_FLAG_MEMAHB_AHB_IF0 | \ + DMACH_FLAG_MEMWIDTH_16BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Low-level HSMC Helpers */ + +#if NAND_NBANKS > 1 +void nand_lock(void); +void nand_unlock(void); +#else +# define nand_lock() +# define nand_unlock() +#endif + +#ifdef CONFIG_SAMA5_NAND_DUMP +# define nand_dump(m,b,s) lib_dumpbuffer(m,b,s) +#else +# define nand_dump(m,b,s) +#endif + +static void nand_wait_ready(struct sam_nandcs_s *priv); +static void nand_nfc_cmdsend(struct sam_nandcs_s *priv, uint32_t cmd, + uint32_t acycle, uint32_t cycle0); +static int nand_operation_complete(struct sam_nandcs_s *priv); +static int nand_translate_address(struct sam_nandcs_s *priv, + uint16_t coladdr, uint32_t rowaddr, uint32_t *acycle0, + uint32_t *acycle1234, bool rowonly); +static uint32_t nand_get_acycle(int ncycles); +static void nand_nfc_cleale(struct sam_nandcs_s *priv, + uint8_t mode, uint32_t cmd1, uint32_t cmd2, + uint32_t coladdr, uint32_t rowaddr); + +/* Interrupt Handling */ + +static void nand_wait_cmddone(struct sam_nandcs_s *priv); +static void nand_setup_cmddone(struct sam_nandcs_s *priv); +static void nand_wait_xfrdone(struct sam_nandcs_s *priv); +static void nand_setup_xfrdone(struct sam_nandcs_s *priv); +static void nand_wait_rbedge(struct sam_nandcs_s *priv); +static void nand_setup_rbedge(struct sam_nandcs_s *priv); +#if 0 /* Not used */ +static void nand_wait_nfcbusy(struct sam_nandcs_s *priv); +#endif +static uint32_t nand_nfc_poll(void); +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS +static int hsmc_interrupt(int irq, void *context); +#endif + +/* DMA Helpers */ + +#ifdef CONFIG_SAMA5_NAND_DMA +#ifdef CONFIG_SAMA5_NAND_DMADEBUG +static void nand_dma_sampleinit(struct sam_nandcs_s *priv); +# define nand_dma_sample(p,i) sam_dmasample((p)->dma, &(p)->dmaregs[i]) +static void nand_dma_sampledone(struct sam_nandcs_s *priv, int result); + +#else +# define nand_dma_sampleinit(p) +# define nand_dma_sample(p,i) +# define nand_dma_sampledone(p,r) + +#endif + +static int nand_wait_dma(struct sam_nandcs_s *priv); +static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result); +static int nand_dma_read(struct sam_nandcs_s *priv, + uintptr_t vsrc, uintptr_t vdest, size_t nbytes, + uint32_t dmaflags); +static int nand_dma_write(struct sam_nandcs_s *priv, + uintptr_t vsrc, uintptr_t vdest, size_t nbytes, + uint32_t dmaflags); +#endif + +/* Raw Data Transfer Helpers */ + +static int nand_nfcsram_read(struct sam_nandcs_s *priv, + uint8_t *buffer, uint16_t buflen, uint16_t offset); +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_read(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen); +#endif + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data); +#endif + +static int nand_nfcsram_write(struct sam_nandcs_s *priv, + uint8_t *buffer, uint16_t buflen, uint16_t offset); +static int nand_write(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen, uint16_t offset); + +/* NAND Access Helpers */ + +static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data, void *spare); + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data); +#endif + +static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, const void *data, const void *spare); + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, const void *data); +#endif + +/* MTD driver methods */ + +static int nand_eraseblock(struct nand_raw_s *raw, off_t block); +static int nand_rawread(struct nand_raw_s *raw, off_t block, + unsigned int page, void *data, void *spare); +static int nand_rawwrite(struct nand_raw_s *raw, off_t block, + unsigned int page, const void *data, const void *spare); + +#ifdef CONFIG_MTD_NAND_HWECC +static int nand_readpage(struct nand_raw_s *raw, off_t block, + unsigned int page, void *data, void *spare); +static int nand_writepage(struct nand_raw_s *raw, off_t block, + unsigned int page, const void *data, const void *spare); +#endif + +/* Initialization */ + +static void nand_reset(struct sam_nandcs_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* These pre-allocated structures hold the state of the MTD driver for NAND + * on CS0..3 as configured. + */ + +#ifdef CONFIG_SAMA5_EBICS0_NAND +static struct sam_nandcs_s g_cs0nand; +#endif +#ifdef CONFIG_SAMA5_EBICS1_NAND +static struct sam_nandcs_s g_cs1nand; +#endif +#ifdef CONFIG_SAMA5_EBICS2_NAND +static struct sam_nandcs_s g_cs2nand; +#endif +#ifdef CONFIG_SAMA5_EBICS3_NAND +static struct sam_nandcs_s g_cs3nand; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* NAND global state */ + +struct sam_nand_s g_nand; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nand_lock + * + * Description: + * Get exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NBANKS > 1 +void nand_lock(void) +{ + int ret; + + do + { + ret = sem_wait(&g_nand.exclsem); + DEBUGASSERT(ret == OK || errno == EINTR); + } + while (ret != OK); +} +#endif + +/**************************************************************************** + * Name: nand_unlock + * + * Description: + * Relinquish exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NBANKS > 1 +void nand_unlock(void) +{ + sem_post(&g_nand.exclsem); +} +#endif + +/**************************************************************************** + * Name: nand_wait_ready + * + * Description: + * Waiting for the completion of a page program, erase and random read + * completion. + * + * Input parameters: + * priv Pointer to a sam_nandcs_s instance. + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_wait_ready(struct sam_nandcs_s *priv) +{ +#ifdef SAMA5_NAND_READYBUSY + while (board_nand_busy(priv->cs)); +#endif + nand_nfc_cleale(priv, 0, COMMAND_STATUS, 0, 0, 0); + while ((READ_DATA8(&priv->raw) & STATUS_READY) == 0); +} + +/**************************************************************************** + * Name: nand_nfc_cmdsend + * + * Description: + * Use the HOST NAND FLASH controller to send a command to the NFC. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * cmd - command to send + * acycle - address cycle when command access id decoded + * cycle0 - address at first cycle + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_nfc_cmdsend(struct sam_nandcs_s *priv, uint32_t cmd, + uint32_t acycle, uint32_t cycle0) +{ + uintptr_t cmdaddr; + + /* Wait until host controller is not busy. */ + + while ((nand_getreg(NFCCMD_BASE + NFCADDR_CMD_NFCCMD) & 0x08000000) != 0); + nand_setup_cmddone(priv); + + /* Send the command plus the ADDR_CYCLE */ + + cmdaddr = NFCCMD_BASE + cmd; + nand_putreg(SAM_HSMC_ADDR, cycle0); + nand_putreg(cmdaddr, acycle); + + /* Wait for the command transfer to complete */ + + nand_wait_cmddone(priv); +} + +/**************************************************************************** + * Name: nand_operation_complete + * + * Description: + * Check if a program or erase operation completed successfully + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * + * Returned value. + * OK on success, a negated errnor value on failure + * + ****************************************************************************/ + +static int nand_operation_complete(struct sam_nandcs_s *priv) +{ + uint8_t status; + + nand_nfc_cleale(priv, 0, COMMAND_STATUS, 0, 0, 0); + status = READ_DATA8(&priv->raw); + + /* On successful completion, the NAND will be READY with no ERROR conditions */ + + if ((status & STATUS_ERROR) != 0) + { + return -EIO; + } + else if ((status & STATUS_READY) == 0) + { + return -EBUSY; + } + + return OK; +} + +/**************************************************************************** + * Name: nand_translate_address + * + * Description: + * Translates the given column and row address into first and other (1-4) + * address cycles. The resulting values are stored in the provided + * variables if they are not null. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * coladdr - Column address to translate. + * rowaddr - Row address to translate. + * acycle0 - First address cycle + * acycle1234 - Four address cycles. + * rowonly - True:Only ROW address is used. + * + * Returned value. + * Number of address cycles converted. + * + ****************************************************************************/ + +static int nand_translate_address(struct sam_nandcs_s *priv, + uint16_t coladdr, uint32_t rowaddr, + uint32_t *acycle0, uint32_t *acycle1234, + bool rowonly) +{ + uint16_t maxsize; + uint32_t maxpage; + uint32_t accum0; + uint32_t accum1234; + uint8_t bytes[8]; + int ncycles; + int ndx; + int pos; + + /* Setup */ + + maxsize = nandmodel_getpagesize(&priv->raw.model) + + nandmodel_getsparesize(&priv->raw.model) - 1; + maxpage = nandmodel_getdevpagesize(&priv->raw.model) - 1; + ncycles = 0; + accum0 = 0; + accum1234 = 0; + + /* Check the data bus width of the NAND FLASH */ + + if (nandmodel_getbuswidth(&priv->raw.model) == 16) + { + /* Use word vs. bytes addressing */ + + coladdr >>= 1; + } + + /* Convert column address */ + + if (!rowonly) + { + /* Send single column address byte for small block devices, or two + * column address bytes for large block devices + */ + + while (maxsize > 2) + { + bytes[ncycles++] = coladdr & 0xff; + maxsize >>= 8; + coladdr >>= 8; + } + } + + /* Convert row address */ + + while (maxpage > 0) + { + bytes[ncycles++] = rowaddr & 0xff; + maxpage >>= 8; + rowaddr >>= 8; + } + + /* Build acycle0 and acycle1234 */ + + ndx = 0; + + /* If more than 4 cycles, acycle0 is used */ + + if (ncycles > 4) + { + for (pos = 0; ndx < ncycles - 4; ndx++) + { + accum0 += bytes[ndx] << pos; + pos += 8; + } + } + + /* acycle1234 */ + + for (pos = 0; ndx < ncycles; ndx++) + { + accum1234 += bytes[ndx] << pos; + pos += 8; + } + + /* Store values */ + + if (acycle0) + { + *acycle0 = accum0; + } + + if (acycle1234) + { + *acycle1234 = accum1234; + } + + return ncycles; +} + +/**************************************************************************** + * Name: nand_get_acycle + * + * Description: + * Map the number of address cycles the bit setting for the NFC command + * + * Input parameters: + * ncycles - Number of address cycles + * + * Returned value. + * NFC command value + * + ****************************************************************************/ + +static uint32_t nand_get_acycle(int ncycles) +{ + switch (ncycles) + { + case 1: + return NFCADDR_CMD_ACYCLE_ONE; + + case 2: + return NFCADDR_CMD_ACYCLE_TWO; + + case 3: + return NFCADDR_CMD_ACYCLE_THREE; + + case 4: + return NFCADDR_CMD_ACYCLE_FOUR; + + case 5: + return NFCADDR_CMD_ACYCLE_FIVE; + } + + return 0; +} + +/**************************************************************************** + * Name: nand_nfc_cleale + * + * Description: + * Sends NAND CLE/ALE command. + * + * Input parameters: + * priv - Pointer to a sam_nandcs_s instance. + * mode - SMC ALE CLE mode parameter. + * cmd1 - First command to be sent. + * cmd2 - Second command to be sent. + * coladdr - Column address. + * rowaddr - Row address. + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_nfc_cleale(struct sam_nandcs_s *priv, uint8_t mode, + uint32_t cmd1, uint32_t cmd2, + uint32_t coladdr, uint32_t rowaddr) +{ + uint32_t cmd; + uint32_t regval; + uint32_t rw; + uint32_t acycle; + uint32_t acycle0 = 0; + uint32_t acycle1234 = 0; + int ncycles; + + if ((mode & HSMC_CLE_WRITE_EN) != 0) + { + rw = NFCADDR_CMD_NFCWR; + } + else + { + rw = NFCADDR_CMD_NFCRD; + } + + if ((mode & HSMC_CLE_DATA_EN) != 0) + { + regval = NFCADDR_CMD_DATAEN; + } + else + { + regval = NFCADDR_CMD_DATADIS; + } + + if (((mode & HSMC_ALE_COL_EN) != 0) || ((mode & HSMC_ALE_ROW_EN) != 0)) + { + bool rowonly = ((mode & HSMC_ALE_COL_EN) == 0); + ncycles = nand_translate_address(priv, coladdr, rowaddr, + &acycle0, &acycle1234, rowonly); + acycle = nand_get_acycle(ncycles); + } + else + { + acycle = NFCADDR_CMD_ACYCLE_NONE; + } + + cmd = (rw | regval | NFCADDR_CMD_CSID(priv->cs) | acycle | + (((mode & HSMC_CLE_VCMD2_EN) == HSMC_CLE_VCMD2_EN) ? NFCADDR_CMD_VCMD2 : 0) | + (cmd1 << NFCADDR_CMD_CMD1_SHIFT) | (cmd2 << NFCADDR_CMD_CMD2_SHIFT)); + + nand_nfc_cmdsend(priv, cmd, acycle1234, acycle0); +} + +/**************************************************************************** + * Name: nand_wait_cmddone + * + * Description: + * Wait for NFC command done + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_wait_cmddone(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + int ret; + + /* Wait for the CMDDONE interrupt to occur */ + + flags = enter_critical_section(); + do + { + ret = sem_wait(&g_nand.waitsem); + if (ret < 0) + { + DEBUGASSERT(errno == EINTR); + } + } + while (!g_nand.cmddone); + + /* CMDDONE received */ + + g_nand.cmddone = false; + leave_critical_section(flags); + +#else + /* Poll for the CMDDONE event (latching other events as necessary) */ + + do + { + (void)nand_nfc_poll(); + } + while (!g_nand.cmddone); +#endif +} + +/**************************************************************************** + * Name: nand_setup_cmddone + * + * Description: + * Setup to wait for CMDDONE event + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_setup_cmddone(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + + /* Clear all pending interrupts. This must be done with interrupts + * enabled or we could lose interrupts. + */ + + nand_getreg(SAM_HSMC_SR); + flags = enter_critical_section(); + + /* Mark CMDDONE not received */ + + g_nand.cmddone = false; + + /* Enable the CMDDONE interrupt */ + + nand_putreg(SAM_HSMC_IER, HSMC_NFCINT_CMDDONE); + leave_critical_section(flags); +#else + /* Just sample and clear any pending NFC status, then clear CMDDONE status */ + + (void)nand_nfc_poll(); + g_nand.cmddone = false; +#endif +} + +/**************************************************************************** + * Name: nand_wait_xfrdone + * + * Description: + * Wait for a transfer to complete + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_wait_xfrdone(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + int ret; + + /* Wait for the XFRDONE interrupt to occur */ + + flags = enter_critical_section(); + do + { + ret = sem_wait(&g_nand.waitsem); + if (ret < 0) + { + DEBUGASSERT(errno == EINTR); + } + } + while (!g_nand.xfrdone); + + /* XFRDONE received */ + + g_nand.xfrdone = false; + leave_critical_section(flags); + +#else + /* Poll for the XFRDONE event (latching other events as necessary) */ + + do + { + (void)nand_nfc_poll(); + } + while (!g_nand.xfrdone); +#endif +} + +/**************************************************************************** + * Name: nand_setup_xfrdone + * + * Description: + * Setup to wait for XFDONE event + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_setup_xfrdone(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + + /* Clear all pending interrupts. This must be done with interrupts + * enabled or we could lose interrupts. + */ + + nand_getreg(SAM_HSMC_SR); + flags = enter_critical_section(); + + /* Mark XFRDONE not received */ + + g_nand.xfrdone = false; + + /* Enable the XFRDONE interrupt */ + + nand_putreg(SAM_HSMC_IER, HSMC_NFCINT_XFRDONE); + leave_critical_section(flags); +#else + /* Just sample and clear any pending NFC status, then clear XFRDONE status */ + + (void)nand_nfc_poll(); + g_nand.xfrdone = false; +#endif +} + +/**************************************************************************** + * Name: nand_wait_rbedge + * + * Description: + * Wait for read/busy edge detection + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_wait_rbedge(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + int ret; + + /* Wait for the RBEDGE0 interrupt to occur */ + + flags = enter_critical_section(); + do + { + ret = sem_wait(&g_nand.waitsem); + if (ret < 0) + { + DEBUGASSERT(errno == EINTR); + } + } + while (!g_nand.rbedge); + + /* RBEDGE0 received */ + + g_nand.rbedge = false; + leave_critical_section(flags); + +#else + /* Poll for the RBEDGE0 event (latching other events as necessary) */ + + do + { + (void)nand_nfc_poll(); + } + while (!g_nand.rbedge); +#endif +} + +/**************************************************************************** + * Name: nand_setup_rbedge + * + * Description: + * Setup to wait for RBEDGE0 event + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_setup_rbedge(struct sam_nandcs_s *priv) +{ +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + + /* Clear all pending interrupts. This must be done with interrupts + * enabled or we could lose interrupts. + */ + + nand_getreg(SAM_HSMC_SR); + flags = enter_critical_section(); + + /* Mark RBEDGE0 not received */ + + g_nand.rbedge = false; + + /* Enable the RBEDGE0 interrupt */ + + nand_putreg(SAM_HSMC_IER, HSMC_NFCINT_RBEDGE0); + leave_critical_section(flags); +#else + /* Just sample and clear any pending NFC status, then clear RBEDGE0 status */ + + (void)nand_nfc_poll(); + g_nand.rbedge = false; +#endif +} + +/**************************************************************************** + * Name: nand_wait_nfcbusy + * + * Description: + * Wait for NFC not busy + * + * Input parameters: + * priv - CS state structure instance + * + * Returned value. + * None + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void nand_wait_nfcbusy(struct sam_nandcs_s *priv) +{ + uint32_t sr; + + /* Poll for the NFC not busy state (latching other events as necessary) */ + + do + { + sr = nand_nfc_poll(); + } + while ((sr & HSMC_SR_NFCBUSY) != 0); +} +#endif + +/**************************************************************************** + * Name: nand_nfc_poll + * + * Description: + * Sample, latch, and return NFC status. Some pending status is cleared. + * This latching capability function is needed to prevent loss of pending + * status when sampling the HSMC_SR register. + * + * Input parameters: + * None + * + * Returned value. + * Current HSMC_SR register value; + * + ****************************************************************************/ + +static uint32_t nand_nfc_poll(void) +{ + uint32_t sr; +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + irqstate_t flags; + + /* Disable interrupts while we sample NFS status as this may be done from + * the interrupt level as well. + */ + + flags = enter_critical_section(); +#endif + + /* Read the current HSMC status, clearing most pending conditions */ + + sr = nand_getreg(SAM_HSMC_SR); + +#ifndef CONFIG_SAMA5_NAND_REGDEBUG + // fllvdbg("sr=%08x\n", sr); +#endif + + /* When set to one, this XFRDONE indicates that the NFC has terminated + * the data transfer. This flag is reset after the status read. + */ + + if ((sr & HSMC_NFCINT_XFRDONE) != 0) + { + /* Set the latching XFRDONE status */ + + g_nand.xfrdone = true; + } + + /* When set to one, the CMDDONE flag indicates that the NFC has terminated + * the Command. This flag is reset after the status read. + */ + + if ((sr & HSMC_NFCINT_CMDDONE) != 0) + { + /* Set the latching CMDDONE status */ + + g_nand.cmddone = true; + } + + /* If set to one, the RBEDGE0 flag indicates that an edge has been detected + * on the Ready/Busy Line x. Depending on the EDGE CTRL field located in the + * SMC_CFG register, only rising or falling edge is detected. This flag is + * reset after the status read. + */ + + if ((sr & HSMC_NFCINT_RBEDGE0) != 0) + { + /* Set the latching RBEDGE0 status */ + + g_nand.rbedge = true; + } + +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + leave_critical_section(flags); +#endif + return sr; +} + +/**************************************************************************** + * Name: hsmc_interrupt + * + * Description: + * HSMC interrupt handler + * + * Input parameters: + * Standard interrupt arguments + * + * Returned value. + * Always returns OK + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS +static int hsmc_interrupt(int irq, void *context) +{ + uint32_t sr = nand_nfc_poll(); + uint32_t imr = nand_getreg(SAM_HSMC_IMR); + uint32_t pending = sr & imr; + +#ifndef CONFIG_SAMA5_NAND_REGDEBUG + fllvdbg("sr=%08x imr=%08x\n", sr, imr); +#endif + + /* When set to one, this XFRDONE indicates that the NFC has terminated + * the data transfer. This flag is reset after the status read. + */ + + if ((g_nand.xfrdone && (imr & HSMC_NFCINT_XFRDONE) != 0) + { + /* Post the XFRDONE event */ + + sem_post(&g_nand.waitsem); + + /* Disable further XFRDONE interrupts */ + + nand_putreg(SAM_HSMC_IDR, HSMC_NFCINT_XFRDONE); + } + + /* When set to one, the CMDDONE flag indicates that the NFC has terminated + * the Command. This flag is reset after the status read. + */ + + if (g_nand.xfrdone && (imr & HSMC_NFCINT_CMDDONE) != 0) + { + /* Post the CMDDONE event */ + + sem_post(&g_nand.waitsem); + + /* Disable further CMDDONE interrupts */ + + nand_putreg(SAM_HSMC_IDR, HSMC_NFCINT_CMDDONE); + } + + /* If set to one, the RBEDGE0 flag indicates that an edge has been detected + * on the Ready/Busy Line x. Depending on the EDGE CTRL field located in the + * SMC_CFG register, only rising or falling edge is detected. This flag is + * reset after the status read. + */ + + if (g_nand.rbedge && (imr & HSMC_NFCINT_RBEDGE0) != 0) + { + /* Post the RBEDGE0 event */ + + sem_post(&g_nand.waitsem); + + /* Disable further RBEDGE0 interrupts */ + + nand_putreg(SAM_HSMC_IDR, HSMC_NFCINT_RBEDGE0); + } + + return OK; +} +#endif /* CONFIG_SAMA5_NAND_HSMCINTERRUPTS */ + +/**************************************************************************** + * Name: nand_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMA5_NAND_DMADEBUG) + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMADEBUG +static void nand_dma_sampleinit(struct sam_nandcs_s *priv) +{ + /* Put contents of register samples into a known state */ + + memset(priv->dmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(priv->dma, &priv->dmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: nand_dma_sampledone + * + * Description: + * Dump sampled RX DMA registers + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMADEBUG +static void nand_dma_sampledone(struct sam_nandcs_s *priv, int result) +{ + lldbg("result: %d\n", result); + + /* Sample the final registers */ + + sam_dmasample(priv->dma, &priv->dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->dma, &priv->dmaregs[DMA_INITIAL], "Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->dma, &priv->dmaregs[DMA_AFTER_SETUP], "After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->dma, &priv->dmaregs[DMA_AFTER_START], "After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timedout, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + +#if 0 /* No timeout */ + if (result == -ETIMEDOUT || result == -EINTR) + { + sam_dmadump(priv->dma, &priv->dmaregs[DMA_TIMEOUT], "At DMA timeout"); + } + else +#endif + { + sam_dmadump(priv->dma, &priv->dmaregs[DMA_CALLBACK], "At DMA callback"); + } + + sam_dmadump(priv->dma, &priv->dmaregs[DMA_END_TRANSFER], "At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: nand_wait_dma + * + * Description: + * Wait for the completion of a DMA transfer + * + * Input parameters: + * Wait for read/busy edge detection + * + * Returned value. + * The result of the DMA. OK on success; a negated ernno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMA +static int nand_wait_dma(struct sam_nandcs_s *priv) +{ + int ret; + + while (!priv->dmadone) + { + ret = sem_wait(&priv->waitsem); + if (ret < 0) + { + DEBUGASSERT(errno == EINTR); + } + } + + fvdbg("Awakened: result=%d\n", priv->result); + priv->dmadone = false; + return priv->result; +} +#endif + +/**************************************************************************** + * Name: sam_adc_dmacallback + * + * Description: + * Called when one NAND DMA sequence completes. This function just wakes + * the the waiting NAND driver logic. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMA +static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)arg; + + DEBUGASSERT(priv); + nand_dma_sample(priv, DMA_CALLBACK); + + /* Wake up the thread that is waiting for the DMA result */ + + priv->result = result; + priv->dmadone = true; + sem_post(&priv->waitsem); +} +#endif + +/**************************************************************************** + * Name: nand_dma_read + * + * Description: + * Transfer data to NAND from the provided buffer via DMA. + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * vsrc - NAND data destination address. + * vdest - Buffer where data read from NAND will be returned. + * nbytes - The number of bytes to transfer + * dmaflags - Describes the DMA configuration + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMA +static int nand_dma_read(struct sam_nandcs_s *priv, + uintptr_t vsrc, uintptr_t vdest, size_t nbytes, + uint32_t dmaflags) +{ + uint32_t psrc; + uint32_t pdest; + int ret; + + DEBUGASSERT(priv->dma); + + fvdbg("vsrc=%08x vdest=%08x nbytes=%d\n", + (int)vsrc, (int)vdest, (int)nbytes); + + /* Initialize sampling */ + + nand_dma_sampleinit(priv); + + /* Invalidate the destination memory buffer before performing the DMA (so + * that nothing gets flushed later, corrupting the DMA transfer, and so + * that memory will be re-cached after the DMA completes). + */ + + arch_invalidate_dcache(vdest, vdest + nbytes); + + /* DMA will need physical addresses. */ + + psrc = sam_physregaddr(vsrc); /* Source is NAND */ + pdest = sam_physramaddr(vdest); /* Destination is normal memory */ + + /* Configure the DMA: 8- vs 16-bit, NFC SRAM or NAND */ + + sam_dmaconfig(priv->dma, dmaflags); + + /* Setup the Memory-to-Memory DMA. The semantics of the DMA module are + * awkward here. We will treat the NAND (src) as the peripheral source + * and memory as the destination. Internally, the DMA module will realize + * that this is a memory to memory transfer and should do the right thing. + */ + + ret = sam_dmarxsetup(priv->dma, psrc, pdest, nbytes); + if (ret < 0) + { + fdbg("ERROR: sam_dmarxsetup failed: %d\n", ret); + return ret; + } + + nand_dma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA */ + + priv->dmadone = false; + priv->result = -EBUSY; + + sam_dmastart(priv->dma, nand_dmacallback, priv); + nand_dma_sample(priv, DMA_AFTER_START); + + /* Wait for the DMA to complete */ + + ret = nand_wait_dma(priv); + if (ret < 0) + { + fdbg("ERROR: DMA failed: %d\n", ret); + } + + nand_dma_sample(priv, DMA_END_TRANSFER); + nand_dma_sampledone(priv, ret); + return ret; +} +#endif + +/**************************************************************************** + * Name: nand_dma_write + * + * Description: + * Transfer data to NAND from the provided buffer via DMA. + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * vsrc - Buffer that provides the data for the write + * vdest - NAND data destination address + * nbytes - The number of bytes to transfer + * dmaflags - Describes the DMA configuration + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_DMA +static int nand_dma_write(struct sam_nandcs_s *priv, + uintptr_t vsrc, uintptr_t vdest, size_t nbytes, + uint32_t dmaflags) +{ + uint32_t psrc; + uint32_t pdest; + int ret; + + DEBUGASSERT(priv->dma); + + /* Initialize sampling */ + + nand_dma_sampleinit(priv); + + /* Clean the D-Cache associated with the source data buffer so that all of + * the data to be transferred lies in physical memory + */ + + arch_clean_dcache(vsrc, vsrc + nbytes); + + /* DMA will need physical addresses. */ + + psrc = sam_physramaddr(vsrc); /* Source is normal memory */ + pdest = sam_physregaddr(vdest); /* Destination is NAND (or NAND host SRAM) */ + + /* Configure the DMA: 8- vs 16-bit, NFC SRAM or NAND */ + + sam_dmaconfig(priv->dma, dmaflags); + + /* Setup the Memory-to-Memory DMA. The semantics of the DMA module are + * awkward here. We will treat the NAND (dest) as the peripheral destination + * and memory as the source. Internally, the DMA module will realize taht + * this is a memory to memory transfer and should do the right thing. + */ + + ret = sam_dmatxsetup(priv->dma, pdest, psrc, nbytes); + if (ret < 0) + { + fdbg("ERROR: sam_dmatxsetup failed: %d\n", ret); + return ret; + } + + nand_dma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA */ + + priv->dmadone = false; + priv->result = -EBUSY; + + sam_dmastart(priv->dma, nand_dmacallback, priv); + nand_dma_sample(priv, DMA_AFTER_START); + + /* Wait for the DMA to complete */ + + ret = nand_wait_dma(priv); + if (ret < 0) + { + fdbg("ERROR: DMA failed: %d\n", ret); + } + + nand_dma_sample(priv, DMA_END_TRANSFER); + nand_dma_sampledone(priv, ret); + return ret; +} +#endif + +/**************************************************************************** + * Name: nand_nfcsram_read + * + * Description: + * Read data from NAND using the NFC SRAM + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * buffer - Buffer that provides the data for the write + * buflen - The amount of data to read into the buffer + * offset - If reading from NFC SRAM, this is the offset into + * the SRAM. + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen, uint16_t offset) +{ + uintptr_t src; + int remaining; + int ret; + + fvdbg("buffer=%p buflen=%d\n", buffer, buflen); + + /* Get the offset data source address */ + + src = NFCSRAM_BASE + (uintptr_t)offset; + +#ifdef CONFIG_SAMA5_NAND_DMA + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not performed + * because the DMA context switch can take more time that the DMA itself. + */ + + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) + { + DEBUGASSERT(((uintptr_t)buffer & 3) == 0 && ((uintptr_t)src & 3) == 0); + + /* Transfer using DMA */ + + ret = nand_dma_read(priv, src, (uintptr_t)buffer, buflen, NFCSRAM_DMA_FLAGS); + } + else +#endif + + /* Transfer without DMA */ + + { + uint8_t *src8 = (uint8_t *)src; + uint8_t *dest8 = buffer; + + for (remaining = buflen; remaining > 0; remaining--) + { + *dest8++ = *src8++; + } + + ret = OK; + } + + nand_dump("NFS SRAM Read", buffer, buflen); + return ret; +} + +/**************************************************************************** + * Name: nand_read + * + * Description: + * Read data directly from the NAND data address. Currently this only used + * by the PMECC logic which I could not get working if I read from NFC SRAM. + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * nfcsram - True: Use NFC Host SRAM + * buffer - Buffer that provides the data for the write + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_read(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen) +{ + int remaining; + int buswidth; + int ret; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Get the buswidth */ + + buswidth = nandmodel_getbuswidth(&priv->raw.model); + +#ifdef CONFIG_SAMA5_NAND_DMA + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not peformed + * because the DMA context switch can take more time that the DMA itself. + */ + + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) + { + /* Select NFC DATA DMA */ + + uint32_t dmaflags = + (buswidth == 16 ? NAND_DMA_FLAGS16 : NAND_DMA_FLAGS8); + + /* Transfer using DMA */ + + ret = nand_dma_read(priv, priv->raw.dataaddr, (uintptr_t)buffer, + buflen, dmaflags); + } + else +#endif + + /* Transfer without DMA */ + + { + /* Check the data bus width of the NAND FLASH */ + + remaining = buflen; + if (buswidth == 16) + { + volatile uint16_t *src16 = (volatile uint16_t *)priv->raw.dataaddr; + uint16_t *dest16 = (uint16_t *)buffer; + + DEBUGASSERT(((uintptr_t)buffer & 1) == 0); + + for (; remaining > 1; remaining -= sizeof(uint16_t)) + { + *dest16++ = *src16; + } + } + else + { + volatile uint8_t *src8 = (volatile uint8_t *)priv->raw.dataaddr; + uint8_t *dest8 = (uint8_t *)buffer; + + for (; remaining > 0; remaining--) + { + *dest8++ = *src8; + } + } + + ret = OK; + } + + nand_dump("NAND Read", buffer, buflen); + return ret; +} +#endif + +/**************************************************************************** + * Name: nand_read_pmecc + * + * Description: + * Reads the data area of a page of a NAND FLASH into the provided buffer. + * + * Input parameters: + * priv - Lower-half, raw NAND FLASH interface + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data) +{ + uint32_t rowaddr; + uint32_t regval; + uint16_t pagesize; + uint16_t sparesize; + int ret; + + fvdbg("block=%d page=%d data=%p\n", (int)block, page, data); + DEBUGASSERT(priv && data); + + /* Get page and spare sizes */ + + pagesize = nandmodel_getpagesize(&priv->raw.model); + sparesize = nandmodel_getsparesize(&priv->raw.model); + + /* Convert the page size to something understood by the hardware */ + + switch (pagesize) + { + case 512: + regval = HSMC_CFG_PAGESIZE_512; + break; + + case 1024: + regval = HSMC_CFG_PAGESIZE_1024; + break; + + case 2048: + regval = HSMC_CFG_PAGESIZE_2048; + break; + + case 4096: + regval = HSMC_CFG_PAGESIZE_4096; + break; + + case 8192: + regval = HSMC_CFG_PAGESIZE_8192; + break; + + default: + fdbg("ERROR: Unsupported page size: %d\n", pagesize); + return -EINVAL; + } + + /* Configure the SMC */ + + regval |= (HSMC_CFG_RSPARE | HSMC_CFG_RBEDGE | HSMC_CFG_DTOCYC(15) | + HSMC_CFG_DTOMUL_1048576 | + HSMC_CFG_NFCSPARESIZE((sparesize - 1) >> 2)); + nand_putreg(SAM_HSMC_CFG, regval); + + /* Calculate actual address of the page */ + + rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; + + /* Reset and enable the PMECC */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST); + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_ENABLE); + + regval = nand_getreg(SAM_HSMC_PMECCFG); + if ((regval & HSMC_PMECCFG_SPAREEN_MASK) == HSMC_PMECCFG_SPARE_DISABLE) + { + regval |= HSMC_PMECCFG_AUTO_ENABLE; + } + + nand_putreg(SAM_HSMC_PMECCFG, regval); + + /* Start the data phase and perform the transfer */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA); + +#if 0 /* Don't use NFC SRAM */ + nand_nfc_cleale(priv, + HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN | HSMC_CLE_DATA_EN, + COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); +#else + nand_setup_rbedge(priv); + nand_nfc_cleale(priv, + HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN, + COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); + nand_wait_rbedge(priv); +#endif + + /* Reset the PMECC module */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST); + + /* Start a Data Phase */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA); + + /* Read the data area into the caller provided buffer (pagesize bytes). + * NOTE: NFC SRAM is not used. In that case, the wait for PMECC not + * busy below would hang. + */ + +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); +#else + ret = nand_read(priv, (uint8_t *)data, pagesize); +#endif + if (ret < 0) + { + fdbg("ERROR: nand_read for data region failed: %d\n", ret); + return ret; + } + + /* Now read the spare area into priv->raw.spare (sparesize bytes). */ + +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, priv->raw.spare, sparesize, pagesize); +#else + ret = nand_read(priv, priv->raw.spare, sparesize); +#endif + if (ret < 0) + { + fdbg("ERROR: nand_read for spare region failed: %d\n", ret); + return ret; + } + + /* Wait until the kernel of the PMECC is not busy */ + + while ((nand_getreg(SAM_HSMC_PMECCSR) & HSMC_PMECCSR_BUSY) != 0); + return OK; +} +#endif + +/**************************************************************************** + * Name: nand_nfcsram_write + * + * Description: + * Write data to NAND using NAND NFC SRAM + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * buffer - Buffer that provides the data for the write + * offset - Data offset in bytes + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int nand_nfcsram_write(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen, uint16_t offset) +{ + uintptr_t dest; + int ret; + + fvdbg("buffer=%p buflen=%d offset=%d\n", buffer, buflen, offset); + nand_dump("NFC SRAM Write", buffer, buflen); + + /* Apply the offset to the destination address */ + + dest = NFCSRAM_BASE + offset; + +#ifdef CONFIG_SAMA5_NAND_DMA + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not peformed + * because the DMA context switch can take more time that the DMA itself. + */ + + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) + { + DEBUGASSERT(((uintptr_t)buffer & 3) == 0 && ((uintptr_t)dest & 3) == 0); + + /* Transfer using DMA */ + + ret = nand_dma_write(priv, (uintptr_t)buffer, dest, buflen, NFCSRAM_DMA_FLAGS); + } + else +#endif + + /* Transfer without DMA */ + + { + uint8_t *dest8 = (uint8_t *)dest; + + for (; buflen > 0; buflen--) + { + *dest8++ = *buffer++; + } + + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: nand_write + * + * Description: + * Write data to NAND using the NAND data address. + * + * Input Parameters: + * priv - Lower-half, private NAND FLASH device state + * buffer - Buffer that provides the data for the write + * offset - Data offset in bytes + * + * Returned Value + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int nand_write(struct sam_nandcs_s *priv, uint8_t *buffer, + uint16_t buflen, uint16_t offset) +{ + uintptr_t dest; + int buswidth; + int ret; + + fvdbg("buffer=%p buflen=%d offset=%d\n", buffer, buflen, offset); + nand_dump("NAND Write", buffer, buflen); + + /* Apply the offset to the destination address */ + + dest = priv->raw.dataaddr + offset; + + /* Get the buswidth */ + + buswidth = nandmodel_getbuswidth(&priv->raw.model); + +#ifdef CONFIG_SAMA5_NAND_DMA + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not peformed + * because the DMA context switch can take more time that the DMA itself. + */ + + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) + { + /* Select NFC DATA DMA */ + + uint32_t dmaflags = + (buswidth == 16 ? NAND_DMA_FLAGS16 : NAND_DMA_FLAGS8); + + /* Transfer using DMA */ + + ret = nand_dma_write(priv, (uintptr_t)buffer, dest, buflen, dmaflags); + } + else +#endif + + /* Transfer without DMA */ + + { + /* Check the data bus width of the NAND FLASH */ + + if (buswidth == 16) + { + volatile uint16_t *dest16 = (volatile uint16_t *)dest; + const uint16_t *src16 = (const uint16_t *)buffer; + + DEBUGASSERT(((uintptr_t)buffer & 1) == 0); + + for (; buflen > 1; buflen -= sizeof(uint16_t)) + { + *dest16 = *src16++; + } + } + else + { + volatile uint8_t *dest8 = (volatile uint8_t *)dest; + + for (; buflen > 0; buflen--) + { + *dest8 = *buffer++; + } + } + + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: nand_readpage_noecc + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. The raw NAND contents are returned with no ECC + * corrections. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data, void *spare) +{ + uint32_t regval; + uint16_t pagesize; + uint16_t sparesize; + off_t rowaddr; + off_t coladdr; + int ret; + + fvdbg("block=%d page=%d data=%p spare=%p\n", (int)block, page, data, spare); + DEBUGASSERT(priv && (data || spare)); + + /* Get page and spare sizes */ + + pagesize = nandmodel_getpagesize(&priv->raw.model); + sparesize = nandmodel_getsparesize(&priv->raw.model); + + /* Convert the page size to something understood by the hardware */ + + switch (pagesize) + { + case 512: + regval = HSMC_CFG_PAGESIZE_512; + break; + + case 1024: + regval = HSMC_CFG_PAGESIZE_1024; + break; + + case 2048: + regval = HSMC_CFG_PAGESIZE_2048; + break; + + case 4096: + regval = HSMC_CFG_PAGESIZE_4096; + break; + + case 8192: + regval = HSMC_CFG_PAGESIZE_8192; + break; + + default: + fdbg("ERROR: Unsupported page size: %d\n", pagesize); + return -EINVAL; + } + + /* Configure the SMC */ + + regval |= (HSMC_CFG_RBEDGE | HSMC_CFG_DTOCYC(15) | HSMC_CFG_DTOMUL_1048576 | + HSMC_CFG_NFCSPARESIZE((sparesize - 1) >> 2)); + nand_putreg(SAM_HSMC_CFG, regval); + + /* Calculate actual address of the page */ + + rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; + coladdr = data ? 0 : pagesize; + + /* Initialize the NFC */ + + nand_setup_xfrdone(priv); + nand_nfc_cleale(priv, + HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN | HSMC_CLE_DATA_EN, + COMMAND_READ_1, COMMAND_READ_2, coladdr, rowaddr); + nand_wait_xfrdone(priv); + + /* Read data area if so requested */ + + if (data) + { + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: nand_nfcsram_read for data region failed: %d\n", ret); + return ret; + } + } + + /* Read the spare area if so requested. If there is no data, then the + * spare data will appear at offset 0; If there is data, thenthe spare data + * will appear followign the data at offset pagesize. + */ + + if (spare) + { + uint16_t offset = data ? pagesize : 0; + ret = nand_nfcsram_read(priv, (uint8_t *)spare, sparesize, offset); + if (ret < 0) + { + fdbg("ERROR: nand_nfcsram_read for spare region failed: %d\n", ret); + return ret; + } + } + + return OK; +} + +/**************************************************************************** + * Name: nand_readpage_pmecc + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. PMECC is used + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, void *data) +{ + uint32_t regval; + uint16_t sparesize; + int ret; + int i; + + fvdbg("block=%d page=%d data=%p\n", (int)block, page, data); + DEBUGASSERT(priv && data); + + /* Make sure that we have exclusive access to the PMECC and that the PMECC + * is properly configured for this CS. + */ + + pmecc_lock(); + ret = pmecc_configure(priv, false); + if (ret < 0) + { + fdbg("ERROR: pmecc_configure failed: %d\n", ret); + goto errout; + } + + /* Read page data into the user data buffer and spared data + * into the priv->raw.spare buffer. + */ + + ret = nand_read_pmecc(priv, block, page, data); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d Failed to read page\n", + block, page, ret); + goto errout; + } + + /* Check if any sector is corrupted */ + + regval = nand_getreg(SAM_HSMC_PMECCISR); + if (regval) + { + /* Bad sectors. Check if this is because spare area has been erased */ + /* First, re-read the spare area. REVISIT: Is this necessary? */ + + ret = nand_readpage_noecc(priv, block, page, NULL, priv->raw.spare); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d Failed to re-read spare area: %d\n", + block, page, ret); + goto errout; + } + + /* Then check if all bytes are in the erased state */ + + sparesize = nandmodel_getsparesize(&priv->raw.model); + for (i = 0 ; i < sparesize; i++) + { + if (priv->raw.spare[i] != 0xff) + { + break; + } + } + + /* Has the spare area has been erased? */ + + if (i >= sparesize) + { + /* Yes.. clear sector errors */ + + fdbg("Block=%d page=%d has been erased: %08x\n", + block, page, regval); + regval = 0; + } + else + { + fdbg("ERROR: block=%d page=%d Corrupted sectors: %08x\n", + block, page, regval); + } + } + + /* Bit correction will be done directly in destination buffer. */ + + ret = pmecc_correction(regval, (uintptr_t)data); + if (ret < 0) + { + fdbg("ERROR: block=%d page=%d Unrecoverable data error: %d\n", + block, page, ret); + } + + /* Disable auto mode */ + +errout: + regval = nand_getreg(SAM_HSMC_PMECCFG); + regval &= ~HSMC_PMECCFG_AUTO_MASK; + nand_putreg(SAM_HSMC_PMECCFG, regval); + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE); + pmecc_unlock(); + return ret; +} +#endif /* CONFIG_SAMA5_HAVE_PMECC */ + +/**************************************************************************** + * Name: nand_writepage_noecc + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * No ECC calculations are performed. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer conatining the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, const void *data, const void *spare) +{ + uint32_t regval; + uint16_t pagesize; + uint16_t sparesize; + off_t rowaddr; + int ret = OK; + + fvdbg("block=%d page=%d data=%p spare=%p\n", (int)block, page, data, spare); + + /* Get page and spare sizes */ + + pagesize = nandmodel_getpagesize(&priv->raw.model); + sparesize = nandmodel_getsparesize(&priv->raw.model); + + /* Convert the page size to something understood by the hardware */ + + switch (pagesize) + { + case 512: + regval = HSMC_CFG_PAGESIZE_512; + break; + + case 1024: + regval = HSMC_CFG_PAGESIZE_1024; + break; + + case 2048: + regval = HSMC_CFG_PAGESIZE_2048; + break; + + case 4096: + regval = HSMC_CFG_PAGESIZE_4096; + break; + + case 8192: + regval = HSMC_CFG_PAGESIZE_8192; + break; + + default: + fdbg("ERROR: Unsupported page size: %d\n", pagesize); + return -EINVAL; + } + + /* Configure the SMC */ + + regval |= (HSMC_CFG_RBEDGE | HSMC_CFG_DTOCYC(15) | HSMC_CFG_DTOMUL_1048576 | + HSMC_CFG_NFCSPARESIZE((sparesize - 1) >> 2)); + + if (spare) + { + /* Write spare area */ + + regval |= HSMC_CFG_WSPARE; + } + + nand_putreg(SAM_HSMC_CFG, regval); + + /* Calculate physical address of the page */ + + rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; + + /* Write the data and, if present, the spare bytes. */ + + if (data) + { + ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: nand_nfcsram_write for data region failed: %d\n", ret); + return ret; + } + + if (spare) + { + ret = nand_nfcsram_write(priv, (uint8_t *)spare, sparesize, pagesize); + if (ret < 0) + { + fdbg("ERROR: nand_nfcsram_write for data region failed: %d\n", ret); + return ret; + } + } + } + + /* Write data area if needed */ + + if (data) + { + /* Start a Data Phase */ + + nand_setup_xfrdone(priv); + nand_nfc_cleale(priv, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | + HSMC_ALE_ROW_EN | HSMC_CLE_DATA_EN, + COMMAND_WRITE_1, 0, 0, rowaddr); + nand_wait_xfrdone(priv); + + nand_setup_rbedge(priv); + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN, COMMAND_WRITE_2, 0, 0, 0); + nand_wait_rbedge(priv); + + /* Check if the transfer completed successfully */ + + ret = nand_operation_complete(priv); + if (ret < 0) + { + fdbg("ERROR: Failed writing data area: %d\n", ret); + } + } + + /* Write spare area alone if needed */ + + else if (spare) + { + nand_nfc_cleale(priv, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN, + COMMAND_WRITE_1, 0, pagesize, rowaddr); + + ret = nand_write(priv, (uint8_t *)spare, sparesize, 0); + if (ret < 0) + { + fdbg("ERROR: nand_write for spare region failed: %d\n", ret); + ret = -EPERM; + } + + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN, COMMAND_WRITE_2, 0, 0, 0); + nand_wait_ready(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: nand_writepage_pmecc + * + * Description: + * Writes the data area of a NAND FLASH page, The PMECC module generates + * redundancy at encoding time. When a NAND write page operation is + * performed. The redundancy is appended to the page and written in the + * spare area. + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_HAVE_PMECC +static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, + unsigned int page, const void *data) +{ + uint32_t regval; + volatile uint8_t *pmecc; + uint8_t *ecc; + unsigned int pagesize; + unsigned int rowaddr; + unsigned int eccsaddr; + unsigned int eccpersector; + unsigned int sectersperpage; + unsigned int eccsize; + unsigned int sector; + unsigned int i; + int ret = 0; + + fvdbg("block=%d page=%d data=%p\n", (int)block, page, data); + DEBUGASSERT(priv && data); + + /* Make sure that we have exclusive access to the PMECC and that the PMECC + * is properly configured for this CS. + */ + + pmecc_lock(); + ret = pmecc_configure(priv, false); + if (ret < 0) + { + fdbg("ERROR: pmecc_configure failed: %d\n", ret); + goto errout; + } + + /* Calculate the start page address */ + + regval = nand_getreg(SAM_HSMC_PMECCSADDR); + pagesize = nandmodel_getpagesize(&priv->raw.model); + eccsaddr = pagesize + regval; + + /* Calculate physical address of the page */ + + rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; + fvdbg("pagesize=%d eccsaddr=%d rowaddr=%d\n", pagesize, eccsaddr, rowaddr); + +#if 1 /* Use NFC SRAM */ + /* Write the data area to NFC SRAM */ + + ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d nand_nfcsram_write for data region failed: %d\n", + block, page, ret); + goto errout; + } +#endif + + /* Get the encoded number of sectors per page */ + + switch (pmecc_get_pagesize()) + { + case HSMC_PMECCFG_PAGESIZE_1SEC: + sectersperpage = 1; + break; + + case HSMC_PMECCFG_PAGESIZE_2SEC: + sectersperpage = 2; + break; + + case HSMC_PMECCFG_PAGESIZE_4SEC: + sectersperpage = 4; + break; + + case HSMC_PMECCFG_PAGESIZE_8SEC: + sectersperpage = 8; + break; + + default: + sectersperpage = 1; + break; + } + + /* Reset and enable the PMECC */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST); + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_ENABLE); + + /* Start a data phase */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA); + + regval = nand_getreg(SAM_HSMC_PMECCFG); + regval |= HSMC_PMECCFG_NANDWR_WRITE; + nand_putreg(SAM_HSMC_PMECCFG, regval); + +#if 1 /* Use NFC SRAM */ + /* Setup the NFC and wait for the transfer to complete */ + + nand_setup_xfrdone(priv); + nand_nfc_cleale(priv, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | + HSMC_ALE_ROW_EN | HSMC_CLE_DATA_EN, + COMMAND_WRITE_1, 0, 0, rowaddr); + nand_wait_xfrdone(priv); +#else + /* Setup the for the data transfer */ + + nand_nfc_cleale(priv, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN, + COMMAND_WRITE_1, 0, 0, rowaddr); + + /* Transfer the data via the NAND */ + + ret = nand_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d nand_write for data region failed: %d\n", + block, page, ret); + goto errout; + } +#endif + + /* Set up for the ECC transfer */ + + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN, + COMMAND_RANDOM_IN, 0, eccsaddr, 0); + + /* Wait until the kernel of the PMECC is not busy */ + + while ((nand_getreg(SAM_HSMC_PMECCSR) & HSMC_PMECCSR_BUSY) != 0); + + /* Get the ECC values from the PMECC */ + + eccpersector = (pmecc_get_eccsize()) / sectersperpage; + eccsize = sectersperpage * eccpersector; + + fvdbg("sectersperpage=%d eccpersector=%d eccsize=%d\n", + sectersperpage, eccpersector, eccsize); + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE + if (nand_trrimffs(priv) && page >= nand_get_trimpage(priv)) + { + /* Comments in the Atmel sample say that this behavior was found to + * fix both UBI and JFFS2 images written to cleanly erased NAND + * partitions + */ + + memset(g_nand.ecctab, 0xff, eccsize); + } + else +#endif + { + /* Read ECC registers for each sector in the page */ + + ecc = g_nand.ecctab; + for (sector = 0; sector < sectersperpage; sector++) + { + pmecc = (volatile uint8_t *)SAM_HSMC_PMECC_BASE(sector); + + /* Read all EEC registers for this page */ + + for (i = 0; i < eccpersector; i++) + { + *ecc++ = *pmecc++; + } + } + } + + /* Write the ECC to NAND */ + + ret = nand_write(priv, (uint8_t *)g_nand.ecctab, eccsize, 0); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d nand_write for spare region failed: %d\n", + block, page, ret); + goto errout; + } + + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN, COMMAND_WRITE_2, 0, 0, 0); + nand_wait_ready(priv); + + /* Check for success */ + + ret = nand_operation_complete(priv); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d Failed writing data area: %d\n", + block, page, ret); + } + + /* Disable the PMECC */ + +errout: + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE); + pmecc_unlock(); + return ret; +} +#endif /* CONFIG_SAMA5_HAVE_PMECC */ + +/**************************************************************************** + * Name: nand_eraseblock + * + * Description: + * Erases the specified block of the device. + * + * Input parameters: + * raw - Lower-half, raw NAND FLASH interface + * block - Number of the physical block to erase. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static inline int nand_tryeraseblock(struct sam_nandcs_s *priv, off_t block) +{ + uint32_t rowaddr; + int ret; + + /* Calculate address used for erase */ + + rowaddr = block * nandmodel_pagesperblock(&priv->raw.model); + + /* Configure the NFC for the block erase */ + + nand_nfc_cleale(priv, HSMC_CLE_VCMD2_EN | HSMC_ALE_ROW_EN, + COMMAND_ERASE_1, COMMAND_ERASE_2, 0, rowaddr); + + /* Wait for the erase operation to complete */ + + nand_wait_ready(priv); + + ret = nand_operation_complete(priv); + if (ret < 0) + { + fdbg("ERROR: Block %d Could not erase: %d\n", block, ret); + } + + return ret; +} + +static int nand_eraseblock(struct nand_raw_s *raw, off_t block) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw; + int retries = NAND_ERASE_NRETRIES; + int ret = OK; + + DEBUGASSERT(priv); + + fvdbg("block=%d\n", (int)block); + + /* Get exclusvie access to the HSMC hardware. + * REVISIT: The scope of this exclusivity is just NAND. + */ + + nand_lock(); + + /* Try up to NAND_ERASE_NRETRIES times to erase the FLASH */ + + while (retries > 0) + { + ret = nand_tryeraseblock(priv, block); + if (ret == OK) + { + nand_unlock(); + return OK; + } + + retries--; + } + + fdbg("ERROR: Block %d Failed to erase after %d tries\n", + (int)block, NAND_ERASE_NRETRIES); + + nand_unlock(); + return -EAGAIN; +} + +/**************************************************************************** + * Name: nand_rawread + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. This is a raw read of the flash contents. + * + * Input parameters: + * raw - Lower-half, raw NAND FLASH interface + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_rawread(struct nand_raw_s *raw, off_t block, + unsigned int page, void *data, void *spare) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw; + int ret; + + DEBUGASSERT(raw); + + /* Get exclusvie access to the HSMC hardware. + * REVISIT: The scope of this exclusivity is just NAND. + */ + + nand_lock(); + ret = nand_readpage_noecc(priv, block, page, data, spare); + nand_unlock(); + return ret; +} + +/**************************************************************************** + * Name: nand_rawwrite + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * This is a raw write of the flash contents. + * + * Input parameters: + * raw - Lower-half, raw NAND FLASH interface + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer containing the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +static int nand_rawwrite(struct nand_raw_s *raw, off_t block, + unsigned int page, const void *data, + const void *spare) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw; + int ret; + + DEBUGASSERT(raw); + + /* Get exclusvie access to the HSMC hardware. + * REVISIT: The scope of this exclusivity is just NAND. + */ + + nand_lock(); + ret = nand_writepage_noecc(priv, block, page, data, spare); + nand_unlock(); + return ret; +} + +/**************************************************************************** + * Name: nand_readpage + * + * Description: + * Reads the data and/or the spare areas of a page of a NAND FLASH into the + * provided buffers. Hardware ECC checking will be performed if so + * configured. + * + * Input parameters: + * raw - Lower-half, raw NAND FLASH interface + * block - Number of the block where the page to read resides. + * page - Number of the page to read inside the given block. + * data - Buffer where the data area will be stored. + * spare - Buffer where the spare area will be stored. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_HWECC +static int nand_readpage(struct nand_raw_s *raw, off_t block, + unsigned int page, void *data, void *spare) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw; + int ret; + + DEBUGASSERT(raw); + + /* Get exclusvie access to the HSMC hardware. + * REVISIT: The scope of this exclusivity is just NAND. + */ + + nand_lock(); + + /* Read the page */ + + DEBUGASSERT(raw->ecctype != NANDECC_SWECC); + switch (raw->ecctype) + { + case NANDECC_NONE: + case NANDECC_CHIPECC: + ret = nand_readpage_noecc(priv, block, page, data, spare); + break; + +#ifdef CONFIG_SAMA5_HAVE_PMECC + case NANDECC_PMECC: + DEBUGASSERT(!spare); + ret = nand_readpage_pmecc(priv, block, page, data); + break; +#endif + + case NANDECC_SWECC: + default: + ret = -EINVAL; + break; + } + + nand_unlock(); + return ret; +} +#endif + +/**************************************************************************** + * Name: nand_writepage + * + * Description: + * Writes the data and/or the spare area of a page on a NAND FLASH chip. + * Hardware ECC checking will be performed if so configured. + * + * Input parameters: + * raw - Lower-half, raw NAND FLASH interface + * block - Number of the block where the page to write resides. + * page - Number of the page to write inside the given block. + * data - Buffer containing the data to be writting + * spare - Buffer conatining the spare data to be written. + * + * Returned value. + * OK is returned in succes; a negated errno value is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_NAND_HWECC +static int nand_writepage(struct nand_raw_s *raw, off_t block, + unsigned int page, const void *data, + const void *spare) +{ + struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw; + int ret; + + DEBUGASSERT(raw); + + /* Get exclusvie access to the HSMC hardware. + * REVISIT: The scope of this exclusivity is just NAND. + */ + + nand_lock(); + + /* Write the page */ + + DEBUGASSERT(raw->ecctype != NANDECC_SWECC); + switch (raw->ecctype) + { + case NANDECC_NONE: + case NANDECC_CHIPECC: + ret = nand_writepage_noecc(priv, block, page, data, spare); + break; + +#ifdef CONFIG_SAMA5_HAVE_PMECC + case NANDECC_PMECC: + DEBUGASSERT(!spare); + ret = nand_writepage_pmecc(priv, block, page, data); + break; +#endif + + case NANDECC_SWECC: + default: + ret = -EINVAL; + break; + } + + nand_unlock(); + return ret; +} +#endif + +/**************************************************************************** + * Name: nand_reset + * + * Description: + * Resets a NAND FLASH device + * + * Input parameters: + * priv - Lower-half, private NAND FLASH device state + * + * Returned value. + * None + * + ****************************************************************************/ + +static void nand_reset(struct sam_nandcs_s *priv) +{ + fvdbg("Resetting\n"); + nand_nfc_cleale(priv, 0, COMMAND_RESET, 0, 0, 0); + nand_wait_ready(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_nand_initialize + * + * Description: + * Create and initialize an raw NAND device instance. This driver + * implements the RAW NAND interface: No software ECC or sparing is + * performed here. Those necessary NAND features are provided by common, + * higher level NAND MTD layers found in drivers/mtd. + * + * Input parameters: + * cs - Chip select number (in the event that multiple NAND devices + * are connected on-board). + * + * Returned value. + * On success a non-NULL pointer to an MTD device structure is returned; + * NULL is returned on a failure. + * + ****************************************************************************/ + +struct mtd_dev_s *sam_nand_initialize(int cs) +{ + struct sam_nandcs_s *priv; + struct mtd_dev_s *mtd; + uintptr_t cmdaddr; + uintptr_t addraddr; + uintptr_t dataaddr; + uint8_t ecctype; + int ret; + + fvdbg("CS%d\n", cs); + + /* Select the device structure (In SAMA5D3, NAND is only supported on CS3). */ + +#ifdef CONFIG_SAMA5_EBICS0_NAND + if (cs == HSMC_CS0) + { + /* Refer to the pre-allocated NAND device structure */ + + priv = &g_cs0nand; + + /* Set up the NAND addresses. These must be provided in the board.h + * header file. + */ + + cmdaddr = BOARD_EBICS0_NAND_CMDADDR; + addraddr = BOARD_EBICS0_NAND_ADDRADDR; + dataaddr = BOARD_EBICS0_NAND_DATAADDR; + + /* Pass on the configured ECC type */ + + ecctype = SAMA5_EBICS0_ECCTYPE; + } + else +#endif +#ifdef CONFIG_SAMA5_EBICS1_NAND + if (cs == HSMC_CS1) + { + /* Refer to the pre-allocated NAND device structure */ + + priv = &g_cs1nand; + + /* Set up the NAND addresses. These must be provided in the board.h + * header file. + */ + + cmdaddr = BOARD_EBICS1_NAND_CMDADDR; + addraddr = BOARD_EBICS1_NAND_ADDRADDR; + dataaddr = BOARD_EBICS1_NAND_DATAADDR; + + /* Pass on the configured ECC type */ + + ecctype = SAMA5_EBICS1_ECCTYPE; + } + else +#endif +#ifdef CONFIG_SAMA5_EBICS2_NAND + if (cs == HSMC_CS2) + { + /* Refer to the pre-allocated NAND device structure */ + + priv = &g_cs2nand; + + /* Set up the NAND addresses. These must be provided in the board.h + * header file. + */ + + cmdaddr = BOARD_EBICS2_NAND_CMDADDR; + addraddr = BOARD_EBICS2_NAND_ADDRADDR; + dataaddr = BOARD_EBICS2_NAND_DATAADDR; + + /* Pass on the configured ECC type */ + + ecctype = SAMA5_EBICS2_ECCTYPE; + } + else +#endif +#ifdef CONFIG_SAMA5_EBICS3_NAND + if (cs == HSMC_CS3) + { + /* Refer to the pre-allocated NAND device structure */ + + priv = &g_cs3nand; + + /* Set up the NAND addresses. These must be provided in the board.h + * header file. + */ + + cmdaddr = BOARD_EBICS3_NAND_CMDADDR; + addraddr = BOARD_EBICS3_NAND_ADDRADDR; + dataaddr = BOARD_EBICS3_NAND_DATAADDR; + + /* Pass on the configured ECC type */ + + ecctype = SAMA5_EBICS3_ECCTYPE; + } + else +#endif + { + fdbg("ERROR: CS%d unsupported or invalid\n", cs); + return NULL; + } + + /* Initialize the device structure */ + + memset(priv, 0, sizeof(struct sam_nandcs_s)); + priv->raw.cmdaddr = cmdaddr; + priv->raw.addraddr = addraddr; + priv->raw.dataaddr = dataaddr; + priv->raw.ecctype = ecctype; + priv->raw.eraseblock = nand_eraseblock; + priv->raw.rawread = nand_rawread; + priv->raw.rawwrite = nand_rawwrite; +#ifdef CONFIG_MTD_NAND_HWECC + priv->raw.readpage = nand_readpage; + priv->raw.writepage = nand_writepage; +#endif + priv->cs = cs; + +#ifdef CONFIG_SAMA5_NAND_DMA + sem_init(&priv->waitsem, 0, 0); +#endif + + /* Perform one-time, global NFC/PMECC initialization */ + + if (!g_nand.initialized) + { + /* Initialize the global nand state structure */ + +#if NAND_NBANKS > 1 + sem_init(&g_nand.exclsem, 0, 1); +#endif +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + sem_init(&g_nand.waitsem, 0, 0); +#endif + + /* Enable the NAND FLASH Controller (The NFC is always used) */ + + nand_putreg(SAM_HSMC_CTRL, HSMC_CTRL_NFCEN); + +#ifdef CONFIG_SAMA5_HAVE_PMECC + /* Perform one-time initialization of the PMECC */ + + pmecc_initialize(); + +#else + /* Disable the PMECC if it is not being used */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST); + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE); + nand_putreg(SAM_HSMC_PMECCFG, 0); +#endif + +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + /* Attach the CAN interrupt handler */ + + ret = irq_attach(SAM_IRQ_HSMC, hsmc_interrupt); + if (ret < 0) + { + fdbg("Failed to attach HSMC IRQ (%d)", SAM_IRQ_HSMC); + return NULL; + } +#endif + /* Disable all interrupts at the HSMC */ + + nand_putreg(SAM_HSMC_IDR, HSMC_NFCINT_ALL); + +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + /* Enable the HSMC interrupts at the interrupt controller */ + + up_enable_irq(SAM_IRQ_HSMC); + g_nand.initialized = true; +#endif + } + + /* Initialize the NAND hardware for this CS */ + /* Perform board-specific SMC initialization for this CS. This should include: + * + * 1. Enabling of clocking to the HSMC + * 2. Configuration of timing for the HSMC NAND CS + * 3. Configuration of PIO pins + * + * Other than enabling the HSMC, these are all things that the board-cognizant + * logic is best prepared to handle. + */ + + ret = board_nandflash_config(cs); + if (ret < 0) + { + fdbg("ERROR: board_nandflash_config failed for CS%d: %d\n", + cs, ret); + return NULL; + } + + /* Reset the NAND FLASH part */ + + nand_reset(priv); + + /* Probe the NAND part. On success, an MTD interface that wraps + * our raw NAND interface is returned. + */ + + mtd = nand_initialize(&priv->raw); + if (!mtd) + { + fdbg("ERROR: CS%d nand_initialize failed %d\n", cs); + return NULL; + } + +#ifdef CONFIG_SAMA5_NAND_DMA + /* Allocate a DMA channel for NAND transfers. The channels will be + * configured as needed on-the-fly. NOTE that no failure is declared + * if we fail to allocate DMA channel; in that case, only non-DMA + * transfers will be performed. + */ + + priv->dma = sam_dmachannel(NAND_DMAC, 0); + if (!priv->dma) + { + fdbg("ERROR: Failed to allocate the DMA channel for CS%d\n", cs); + } +#endif + + /* Return the MTD wrapper interface as the MTD device */ + + return mtd; +} + +/**************************************************************************** + * Name: nand_checkreg + * + * Description: + * Check if the current HSMC register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_REGDEBUG +bool nand_checkreg(bool wr, uintptr_t regaddr, uint32_t regval) +{ + if (wr == g_nand.wr && /* Same kind of access? */ + regval == g_nand.regval && /* Same regval? */ + regaddr == g_nand.regadddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + g_nand.ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (g_nand.ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", g_nand.ntimes); + } + + /* Save information about the new access */ + + g_nand.wr = wr; + g_nand.regval = regval; + g_nand.regadddr = regaddr; + g_nand.ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + diff --git a/arch/arm/src/sama5/sam_nand.h b/arch/arm/src/sama5/sam_nand.h new file mode 100644 index 0000000000000000000000000000000000000000..f4229b8d6c0f4075e183cd8b038b632452bd4b9f --- /dev/null +++ b/arch/arm/src/sama5/sam_nand.h @@ -0,0 +1,645 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_nand.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_NAND_H +#define __ARCH_ARM_SRC_SAMA5_SAM_NAND_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/sam_hsmc.h" + +#include "sam_dmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* DMA. DMA support requires that DMAC0 be enabled. According to + * "Table 15-2. SAMA5 Master to Slave Access", DMAC1 does not have access + * to NFC SRAM. + */ + +#ifdef CONFIG_SAMA5_NAND_DMA +# ifdef CONFIG_SAMA5_DMAC0 +# define NAND_DMAC 0 +# else +# error "DMA controller 0 (DMAC0) must be enabled to perform DMA transfers" +# undef CONFIG_SAMA5_NAND_DMA +# endif +#endif + +/* If memory-to-memory DMAs are used, then two context switches will occur: + * (1) when the NAND logic waits for the DMA to complete, and (2) again when + * the DMA completes and the NAND logic is re-awakened. Each context switch + * will required saving and restoring a set of registers defining the task + * state. Those register include the PSR, 16 general purpose registers, and + * 32 floating point registers or about 196 bytes per task state. That is + * then 392*2 bytes per context and 784 bytes for both. Plus there is + * processing overhead. So certainly, there is no reason to use a memory-to- + * memory DMA transfer for much smaller blocks of data. + */ + +#ifdef CONFIG_SAMA5_NAND_DMA +# ifndef CONFIG_SAMA5_NAND_DMA_THRESHOLD +# define CONFIG_SAMA5_NAND_DMA_THRESHOLD 784 +# endif +#endif + + +/* Hardware ECC types. These are extensions to the NANDECC_HWECC value + * defined in include/nuttx/mtd/nand_raw.h. + * + * NANDECC_CHIPECC ECC is performed internal to chip + * NANDECC_PMECC Programmable Multibit Error Correcting Code (PMECC) + */ + +#define NANDECC_CHIPECC (NANDECC_HWECC + 0) +#define NANDECC_PMECC (NANDECC_HWECC + 1) + +/* Per NAND bank ECC selections */ +/* Only CS3 can support NAND. The rest is a fantasy */ + +# undef CONFIG_SAMA5_EBICS0_NAND +# undef CONFIG_SAMA5_EBICS1_NAND +# undef CONFIG_SAMA5_EBICS2_NAND + +#if defined(CONFIG_SAMA5_EBICS0_NAND) +# if defined(CONFIG_SAMA5_EBICS0_ECCNONE) +# define SAMA5_EBICS0_ECCTYPE NANDECC_NONE + +# elif defined(CONFIG_SAMA5_EBICS0_SWECC) +# ifndef CONFIG_MTD_NAND_SWECC +# error CONFIG_SAMA5_EBICS0_SWECC is an invalid selection +# endif +# define SAMA5_EBICS0_ECCTYPE NANDECC_SWECC + +# elif defined(CONFIG_SAMA5_EBICS0_PMECC) +# ifndef CONFIG_MTD_NAND_HWECC +# error CONFIG_SAMA5_EBICS0_PMECC is an invalid selection +# endif +# define SAMA5_EBICS0_ECCTYPE NANDECC_PMECC + +# elif defined(CONFIG_SAMA5_EBICS0_CHIPECC) +# ifndef CONFIG_MTD_NAND_EMBEDDEDECC +# error CONFIG_SAMA5_EBICS0_CHIPECC is an invalid selection +# endif +# define SAMA5_EBICS0_ECCTYPE NANDECC_CHIPECC + +# else +# error "No ECC type specified for CS0" +# endif +#endif /* CONFIG_SAMA5_EBICS0_NAND */ + +#if defined(CONFIG_SAMA5_EBICS1_NAND) +# if defined(CONFIG_SAMA5_EBICS1_ECCNONE) +# define SAMA5_EBICS1_ECCTYPE NANDECC_NONE + +# elif defined(CONFIG_SAMA5_EBICS1_SWECC) +# ifndef CONFIG_MTD_NAND_SWECC +# error CONFIG_SAMA5_EBICS1_SWECC is an invalid selection +# endif +# define SAMA5_EBICS1_ECCTYPE NANDECC_SWECC + +# elif defined(CONFIG_SAMA5_EBICS1_PMECC) +# ifndef CONFIG_MTD_NAND_HWECC +# error CONFIG_SAMA5_EBICS1_PMECC is an invalid selection +# endif +# define SAMA5_EBICS1_ECCTYPE NANDECC_PMECC + +# elif defined(CONFIG_SAMA5_EBICS1_CHIPECC) +# ifndef CONFIG_MTD_NAND_EMBEDDEDECC +# error CONFIG_SAMA5_EBICS1_CHIPECC is an invalid selection +# endif +# define SAMA5_EBICS1_ECCTYPE NANDECC_CHIPECC + +# else +# error "No ECC type specified for CS1" +# endif +#endif /* CONFIG_SAMA5_EBICS1_NAND */ + +#if defined(CONFIG_SAMA5_EBICS2_NAND) +# if defined(CONFIG_SAMA5_EBICS2_ECCNONE) +# define SAMA5_EBICS2_ECCTYPE NANDECC_NONE + +# elif defined(CONFIG_SAMA5_EBICS2_SWECC +# ifndef CONFIG_MTD_NAND_SWECC +# error CONFIG_SAMA5_EBICS2_SWECC is an invalid selection +# endif +# define SAMA5_EBICS2_ECCTYPE NANDECC_SWECC + +# elif defined(CONFIG_SAMA5_EBICS2_PMECC) +# ifndef CONFIG_MTD_NAND_HWECC +# error CONFIG_SAMA5_EBICS2_PMECC is an invalid selection +# endif +# define SAMA5_EBICS2_ECCTYPE NANDECC_PMECC + +# elif defined(CONFIG_SAMA5_EBICS2_CHIPECC) +# ifndef CONFIG_MTD_NAND_EMBEDDEDECC +# error CONFIG_SAMA5_EBICS2_CHIPECC is an invalid selection +# endif +# define SAMA5_EBICS2_ECCTYPE NANDECC_CHIPECC + +# else +# error "No ECC type specified for CS2" +# endif +#endif /* CONFIG_SAMA5_EBICS2_NAND */ + +#if defined(CONFIG_SAMA5_EBICS3_NAND) +# if defined(CONFIG_SAMA5_EBICS3_ECCNONE) +# define SAMA5_EBICS3_ECCTYPE NANDECC_NONE + +# elif defined(CONFIG_SAMA5_EBICS3_SWECC) +# ifndef CONFIG_MTD_NAND_SWECC +# error CONFIG_SAMA5_EBICS3_SWECC is an invalid selection +# endif +# define SAMA5_EBICS3_ECCTYPE NANDECC_SWECC + +# elif defined(CONFIG_SAMA5_EBICS3_PMECC) +# ifndef CONFIG_MTD_NAND_HWECC +# error CONFIG_SAMA5_EBICS3_PMECC is an invalid selection +# endif +# define SAMA5_EBICS3_ECCTYPE NANDECC_PMECC + +# elif defined(CONFIG_SAMA5_EBICS3_CHIPECC) +# ifndef CONFIG_MTD_NAND_EMBEDDEDECC +# error CONFIG_SAMA5_EBICS3_CHIPECC is an invalid selection +# endif +# define SAMA5_EBICS3_ECCTYPE NANDECC_CHIPECC + +# else +# error "No ECC type specified for CS3" +# endif +#endif /* CONFIG_SAMA5_EBICS3_NAND */ + +/* Count the number of banks that configured for NAND with PMECC support + * enabled. + */ + +#undef CONFIG_SAMA5_HAVE_NAND +#ifdef CONFIG_SAMA5_EBICS0_NAND +# define CONFIG_SAMA5_HAVE_NAND 1 +# define NAND_HAVE_EBICS0 1 +#else +# define NAND_HAVE_EBICS0 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS1_NAND +# define CONFIG_SAMA5_HAVE_NAND 1 +# define NAND_HAVE_EBICS1 1 +#else +# define NAND_HAVE_EBICS1 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS2_NAND +# define CONFIG_SAMA5_HAVE_NAND 1 +# define NAND_HAVE_EBICS2 1 +#else +# define NAND_HAVE_EBICS2 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS3_NAND +# define CONFIG_SAMA5_HAVE_NAND 1 +# define NAND_HAVE_EBICS3 1 +#else +# define NAND_HAVE_EBICS3 0 +#endif + +#ifdef CONFIG_SAMA5_HAVE_NAND + +/* Count the number of banks configured for NAND */ + +#define NAND_NBANKS \ + (NAND_HAVE_EBICS0 + NAND_HAVE_EBICS1 + NAND_HAVE_EBICS2 + NAND_HAVE_EBICS3) + +/* Debug */ + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_FS) +# undef CONFIG_DEBUG_FS +# undef CONFIG_SAMA5_NAND_DMADEBUG +# undef CONFIG_SAMA5_NAND_REGDEBUG +# undef CONFIG_SAMA5_NAND_DUMP +#endif + +#if !defined(CONFIG_SAMA5_NAND_DMA) || !defined(CONFIG_DEBUG_DMA) +# undef CONFIG_SAMA5_NAND_DMADEBUG +#endif + +/* An early version of this driver used SMC interrupts to determine when + * NAND commands completed, transfers completed, and RB edges occurred. It + * turns out that those interrupts occurred so quickly that some really + * nasty race conditions were created. Rather than resolve those, I simply + * disabled the interrupt logic with this setting. The setting is retained + * in case, for some reason, someone wants to restore the interrupt-driven + * logic. Polling should be better solution in this case. + */ + +#undef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + +/* DMA Debug */ + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 /* No timeout */ +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This type represents the state of a raw NAND MTD device on a single chip + * select. The struct nand_raw_s must appear at the beginning of the + * definition so that you can freely cast between pointers to struct + * nand_raw_s and struct sam_nandcs_s. + * + * NOTE: Currently, only SAMA5D3x CS3 can support NAND. The logic here would + * support NAND on any CS, but that capability is not needed. + */ + +struct sam_nandcs_s +{ + struct nand_raw_s raw; /* Externally visible part of the driver */ + + /* Static configuration */ + + uint8_t cs; /* Chip select number (0..3) */ +#ifdef CONFIG_SAMA5_NAND_DMA + volatile bool dmadone; /* True: DMA has completed */ +#endif + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE + bool dropjss; /* Enable page trimming */ + uint16_t trimpage; /* Trim page number boundary */ +#endif + +#ifdef CONFIG_SAMA5_NAND_DMA + sem_t waitsem; /* Used to wait for DMA done */ + DMA_HANDLE dma; /* DMA channel assigned to this CS */ + int result; /* The result of the DMA */ + +#ifdef CONFIG_SAMA5_NAND_DMADEBUG + struct sam_dmaregs_s dmaregs[DMA_NSAMPLES]; +#endif +#endif +}; + +struct sam_nand_s +{ + bool initialized; /* True: One time initialization is complete */ +#if NAND_NBANKS > 1 + sem_t exclsem; /* Enforce exclusive access to the SMC hardware */ +#endif + + /* Dynamic state */ + +#ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + volatile bool cmddone; /* True: NFC command has completed (latching) */ + volatile bool xfrdone; /* True: Transfer has completed (latching) */ + volatile bool rbedge; /* True: Ready/busy edge detected (latching) */ + sem_t waitsem; /* Used to wait for one of the above states */ + +#else + bool cmddone; /* True: NFC command has completed (latching) */ + bool xfrdone; /* True: Transfer has completed (latching) */ + bool rbedge; /* True: Ready/busy edge detected (latching) */ + +#endif + +#ifdef CONFIG_SAMA5_HAVE_PMECC + uint8_t ecctab[CONFIG_MTD_NAND_MAX_PMECCSIZE]; +#endif + +#ifdef CONFIG_SAMA5_NAND_REGDEBUG + /* Register debug state */ + + bool wr; /* Last was a write */ + uint32_t regadddr; /* Last address */ + uint32_t regval; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* NAND global state */ + +EXTERN struct sam_nand_s g_nand; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_nand_initialize + * + * Description: + * Create and initialize an raw NAND device instance. This driver + * implements the RAW NAND interface: No software ECC or sparing is + * performed here. Those necessary NAND features are provided by common, + * higher level NAND MTD layers found in drivers/mtd. + * + * Input parameters: + * cs - Chip select number (in the event that multiple NAND devices + * are connected on-board). + * + * Returned value. + * On success a non-NULL pointer to an MTD device structure is returned; + * NULL is returned on a failure. + * + ****************************************************************************/ + +struct mtd_dev_s; +struct mtd_dev_s *sam_nand_initialize(int cs); + +/**************************************************************************** + * Name: board_nandflash_config + * + * Description: + * If CONFIG_SAMA5_BOOT_CS3FLASH is defined, then NAND FLASH support is + * enabled. This function provides the board-specific implementation of + * the logic to reprogram the SMC to support NAND FLASH on the specified + * CS. As a minimum, this board-specific initialization should do the + * following: + * + * 1. Enable clocking to the HSMC + * 2. Configure timing for the HSMC CS + * 3. Configure NAND PIO pins + * + * Input Parameters: + * cs - Chip select number (in the event that multiple NAND devices + * are connected on-board). + * + * Returned Values: + * OK if the HSMC was successfully configured for this CS. A negated + * errno value is returned on a failure. This would fail with -ENODEV, + * for example, if the board does not support NAND FLASH on the requested + * CS. + * + ****************************************************************************/ + +int board_nandflash_config(int cs); + +/**************************************************************************** + * Name: board_nand_busy + * + * Description: + * Must be provided if the board logic supports and interface to detect + * NAND Busy/Ready signal. + * + * Input Parameters: + * cs - Chip select number (in the event that multiple NAND devices + * are connected on-board). + * + * Returned Values: + * True: NAND is busy, False: NAND is ready + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_READYBUSY +bool board_nand_busy(int cs); +#endif + +/**************************************************************************** + * Name: board_nand_ce + * + * Description: + * Must be provided if the board logic supports and interface to control + * the NAND Chip Enable signal. + * + * Input Parameters: + * cs - Chip select number (in the event that multiple NAND devices + * are connected on-board). + * enable - True: enable Chip Select, False: Disable Chip select + * + * Returned Values: + * OK if the HSMC was successfully configured for this CS. A negated + * errno value is returned on a failure. This would fail with -ENODEV, + * for example, if the board does not support NAND FLASH on the requested + * CS. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_CE +void board_nand_ce(int cs, bool enable); +#endif + +/**************************************************************************** + * Name: nand_checkreg + * + * Description: + * Check if the current HSMC register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_NAND_REGDEBUG +bool nand_checkreg(bool wr, uintptr_t regaddr, uint32_t regval); +#endif + +/**************************************************************************** + * Name: nand_getreg + * + * Description: + * Read an HSMC register + * + ****************************************************************************/ + +static inline uint32_t nand_getreg(uintptr_t regaddr) +{ + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_NAND_REGDEBUG + if (nand_checkreg(false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: nand_putreg + * + * Description: + * Write a value to an HSMC register + * + ****************************************************************************/ + +static inline void nand_putreg(uintptr_t regaddr, uint32_t regval) +{ +#ifdef CONFIG_SAMA5_NAND_REGDEBUG + if (nand_checkreg(true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: nand_trimffs_enable + * + * Description: + * Set current trimffs status. + * + * Input Parameters: + * + * Returned Value: + * + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE +static inline void nand_trimffs_enable(struct sam_nandcs_s *priv, bool enable) +{ + priv->dropjss = enable; +} +#else +# define nand_trimffs_enable(p,e) +#endif + +/**************************************************************************** + * Name: nand_trrimffs + * + * Description: + * Get current trimffs status. + * + * Input Parameters: + * + * Returned Value: + * + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE +static inline bool nand_trrimffs(struct sam_nandcs_s *priv) +{ + return priv->dropjss; +} +#else +# define nand_trrimffs(p) (false) +#endif + +/**************************************************************************** + * Name: nand_set_trimpage + * + * Description: + * Set current trimffs page. + * + * Input Parameters: + * page - Start trim page. + * + * Returned Value: + * + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE +static inline void nand_set_trimpage(struct sam_nandcs_s *priv, uint16_t page) +{ + priv->trimpage = page; +} +#else +# define nand_set_trimpage(p,t) +#endif + +/**************************************************************************** + * Name: nand_get_trimpage + * + * Description: + * Get current trimffs page. + * + * Input Parameters: + * None + * + * Returned Value: + * Start trim page. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE +uint16_t nand_get_trimpage(struct sam_nandcs_s *priv) +{ + return priv->trimpage; +} +#else +# define nand_get_trimpage(p) (0) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMA5_HAVE_NAND */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_NAND_H */ diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c new file mode 100644 index 0000000000000000000000000000000000000000..5dbad089e961cb9040a5e5cf9ec72db4a0a66404 --- /dev/null +++ b/arch/arm/src/sama5/sam_ohci.c @@ -0,0 +1,4225 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_ohci.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include /* May redefine PIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "cache.h" +#include "chip.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "sam_usbhost.h" +#include "chip/sam_pmc.h" +#include "chip/sam_sfr.h" +#include "chip/sam_ohci.h" + +#ifdef CONFIG_SAMA5_OHCI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* Pre-requisites */ + +#ifndef CONFIG_SCHED_WORKQUEUE +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#endif + +/* Configurable number of user endpoint descriptors (EDs). This number excludes + * the control endpoint that is always allocated. + */ + +#ifndef CONFIG_SAMA5_OHCI_NEDS +# define CONFIG_SAMA5_OHCI_NEDS 2 +#endif + +/* Configurable number of user transfer descriptors (TDs). */ + +#ifndef CONFIG_SAMA5_OHCI_NTDS +# define CONFIG_SAMA5_OHCI_NTDS 3 +#endif + +#if CONFIG_SAMA5_OHCI_NTDS < 2 +# error Insufficent number of transfer descriptors (CONFIG_SAMA5_OHCI_NTDS < 2) +#endif + +/* Minimum alignment for DMA access is 16 bytes, but it is safer to align to the + * cache line size. + */ + +#if ARMV7A_DCACHE_LINESIZE > 16 +# define SAMA5_DMA_ALIGN ARMV7A_DCACHE_LINESIZE +#else +# define SAMA5_DMA_ALIGN 16 +#endif + +/* Configurable number of request/descriptor buffers (TDBUFFER) */ + +#ifndef CONFIG_SAMA5_OHCI_TDBUFFERS +# define CONFIG_SAMA5_OHCI_TDBUFFERS 2 +#endif + +#if CONFIG_SAMA5_OHCI_TDBUFFERS < 2 +# error At least two TD buffers are required (CONFIG_SAMA5_OHCI_TDBUFFERS < 2) +#endif + +/* Configurable size of one TD buffer */ + +#if CONFIG_SAMA5_OHCI_TDBUFFERS > 0 && !defined(CONFIG_SAMA5_OHCI_TDBUFSIZE) +# define CONFIG_SAMA5_OHCI_TDBUFSIZE 128 +#endif + +#if (CONFIG_SAMA5_OHCI_TDBUFSIZE & 3) != 0 +# error "TD buffer size must be an even number of 32-bit words" +#endif + +/* Total buffer size */ + +#define SAM_BUFALLOC (CONFIG_SAMA5_OHCI_TDBUFFERS * CONFIG_SAMA5_OHCI_TDBUFSIZE) + +/* If UDPHS is enabled, then don't use port A */ + +#ifdef CONFIG_SAMA5_UDPHS +# undef CONFIG_SAMA5_UHPHS_RHPORT1 +#endif + +/* For now, suppress use of PORTA in any event. I use that for SAM-BA and + * would prefer that the board not try to drive VBUS on that port! + */ + +#undef CONFIG_SAMA5_UHPHS_RHPORT1 + +/* Debug */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_OHCI_REGDEBUG +#endif + +/* OHCI Setup ******************************************************************/ +/* Frame Interval / Periodic Start. + * + * At 12Mbps, there are 12000 bit time in each 1Msec frame. + */ + +#define BITS_PER_FRAME 12000 +#define FI (BITS_PER_FRAME-1) +#define FSMPS ((6 * (FI - 210)) / 7) +#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI) +#define DEFAULT_PERSTART (((9 * BITS_PER_FRAME) / 10) - 1) + +/* CLKCTRL enable bits */ + +#define SAM_CLKCTRL_ENABLES (USBOTG_CLK_HOSTCLK|USBOTG_CLK_PORTSELCLK|USBOTG_CLK_AHBCLK) + +/* Interrupt enable bits */ + +#ifdef CONFIG_DEBUG_USB +# define SAM_DEBUG_INTS (OHCI_INT_SO|OHCI_INT_RD|OHCI_INT_UE|OHCI_INT_OC) +#else +# define SAM_DEBUG_INTS 0 +#endif + +#define SAM_NORMAL_INTS (OHCI_INT_WDH|OHCI_INT_RHSC) +#define SAM_ALL_INTS (SAM_NORMAL_INTS|SAM_DEBUG_INTS) + +/* Periodic Intervals **********************************************************/ +/* Periodic intervals 2, 4, 8, 16,and 32 supported */ + +#define MIN_PERINTERVAL 2 +#define MAX_PERINTERVAL 32 + +/* Descriptors *****************************************************************/ +/* Actual number of allocated EDs and TDs will include one for the control ED + * and one for the tail ED for each RHPort: + */ + +#define SAMA5_OHCI_NEDS (CONFIG_SAMA5_OHCI_NEDS + SAM_OHCI_NRHPORT) +#define SAMA5_OHCI_NTDS (CONFIG_SAMA5_OHCI_NTDS + SAM_OHCI_NRHPORT) + +/* TD delay interrupt value */ + +#define TD_DELAY(n) (uint32_t)((n) << GTD_STATUS_DI_SHIFT) + +/* Port numbers */ + +#define HPNDX(hp) ((hp)->port) +#define HPORT(hp) (HPNDX(hp)+1) +#define RHPNDX(rh) ((rh)->hport.hport.port) +#define RHPORT(rh) (RHPNDX(rh)+1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure contains one endpoint list. The main reason for the existence + * of this structure is to contain the sem_t value associated with the ED. It + * doesn't work well within the ED itself because then the semaphore counter + * is subject to DMA cache operations (invalidate a modified semaphore count + * is fatal!). + */ + +struct sam_eplist_s +{ + volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */ + sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif + uint8_t *buffer; /* Buffer being transferred */ + uint16_t buflen; /* Length of the buffer */ + uint16_t xfrd; /* Number of bytes completed in the last transfer */ + struct sam_ed_s *ed; /* Endpoint descriptor (ED) */ + struct sam_gtd_s *tail; /* Tail transfer descriptor (TD) */ +}; + +/* This structure retains the state of one root hub port */ + +struct sam_rhport_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct sam_rhport_s. + */ + + struct usbhost_driver_s drvr; + + /* Root hub port status */ + + volatile bool connected; /* Connected to device */ + uint8_t rhpndx; /* Root hub port index */ + bool ep0init; /* True: EP0 initialized */ + + struct sam_eplist_s ep0; /* EP0 endpoint list */ + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s hport; +}; + +/* This structure retains the overall state of the USB host controller */ + +struct sam_ohci_s +{ + volatile bool pscwait; /* TRUE: Thread is waiting for Root Hub Status change */ + +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t ininterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ + uint8_t outinterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ +#endif + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait Writeback Done Head event */ + struct work_s work; /* Supports interrupt bottom half */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* Root hub ports */ + + struct sam_rhport_s rhport[SAM_OHCI_NRHPORT]; +}; + +/* The OCHI expects the size of an endpoint descriptor to be 16 bytes. + * However, the size allocated for an endpoint descriptor is 32 bytes. This + * is necessary first because the Cortex-A5 cache line size is 32 bytes and + * tht is the smallest amount of memory that we can perform cache operations + * on. The 16-bytes is also used by the OHCI host driver in order to maintain + * additional endpoint-specific data. + */ + +struct sam_ed_s +{ + /* Hardware specific fields */ + + struct ohci_ed_s hw; /* 0-15 */ + + /* Software specific fields */ + + struct sam_eplist_s *eplist; /* 16-19: List structure associated with the ED */ + uint8_t xfrtype; /* 20: Transfer type. See SB_EP_ATTR_XFER_* in usb.h */ + uint8_t interval; /* 21: Periodic EP polling interval: 2, 4, 6, 16, or 32 */ + volatile uint8_t tdstatus; /* 22: TD control status bits from last Writeback Done Head event */ + uint8_t pad[9]; /* 23-31: Pad to 32-bytes */ +}; + +#define SIZEOF_SAM_ED_S 32 + +/* The OCHI expects the size of an transfer descriptor to be 16 bytes. + * However, the size allocated for an endpoint descriptor is 32 bytes in + * RAM. This extra 16-bytes is used by the OHCI host driver in order to + * maintain additional endpoint-specific data. + */ + +struct sam_gtd_s +{ + /* Hardware specific fields */ + + struct ohci_gtd_s hw; /* 0-15 */ + + /* Software specific fields */ + + struct sam_ed_s *ed; /* 16-19: Pointer to parent ED */ + uint8_t pad[12]; /* 20-31: Pad to 32 bytes */ +}; + +#define SIZEOF_SAM_TD_S 32 + +/* The following is used to manage lists of free EDs, TDs, and TD buffers */ + +struct sam_list_s +{ + struct sam_list_s *flink; /* Link to next buffer in the list */ + /* Variable length buffer data follows */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_SAMA5_OHCI_REGDEBUG +static void sam_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void sam_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t sam_getreg(uint32_t addr); +static void sam_putreg(uint32_t val, uint32_t addr); +#else +# define sam_getreg(addr) getreg32(addr) +# define sam_putreg(val,addr) putreg32(val,addr) +#endif + +/* Semaphores ******************************************************************/ + +static void sam_takesem(sem_t *sem); +#define sam_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t sam_getle16(const uint8_t *val); +#if 0 /* Not used */ +static void sam_putle16(uint8_t *dest, uint16_t val); +#endif + +/* OHCI memory pool helper functions *******************************************/ + +static struct sam_ed_s *sam_edalloc(void); +static void sam_edfree(struct sam_ed_s *ed); +static struct sam_gtd_s *sam_tdalloc(void); +static void sam_tdfree(struct sam_gtd_s *buffer); +static uint8_t *sam_tballoc(void); +static void sam_tbfree(uint8_t *buffer); + +/* ED list helper functions ****************************************************/ + +static int sam_addctrled(struct sam_ed_s *ed); +static inline int sam_remctrled(struct sam_ed_s *ed); + +static inline int sam_addbulked(struct sam_ed_s *ed); +static inline int sam_rembulked(struct sam_ed_s *ed); + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static unsigned int sam_getinterval(uint8_t interval); +static void sam_setinttab(uint32_t value, unsigned int interval, unsigned int offset); +#endif + +static inline int sam_addinted(const struct usbhost_epdesc_s *epdesc, + struct sam_ed_s *ed); +static inline int sam_reminted(struct sam_ed_s *ed); + +static inline int sam_addisoced(const struct usbhost_epdesc_s *epdesc, + struct sam_ed_s *ed); +static inline int sam_remisoced(struct sam_ed_s *ed); + +/* Descriptor helper functions *************************************************/ + +static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplist, + struct sam_ed_s *ed, uint32_t dirpid, uint32_t toggle, + volatile uint8_t *buffer, size_t buflen); +static int sam_ep0enqueue(struct sam_rhport_s *rhport); +static void sam_ep0dequeue(struct sam_eplist_s *ep0); +static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + uint8_t *buffer, uint16_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int sam_wdhasynch(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + usbhost_asynch_t callback, void *arg, + uint8_t *buffer, uint16_t buflen); +#endif +static int sam_ctrltd(struct sam_rhport_s *rhport, struct sam_eplist_s *ep0, + uint32_t dirpid, uint8_t *buffer, size_t buflen); + +/* Interrupt handling **********************************************************/ + +static void sam_rhsc_bottomhalf(void); +static void sam_wdh_bottomhalf(void); +static void sam_ohci_bottomhalf(void *arg); + +/* USB host controller operations **********************************************/ + +static int sam_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport); +static int sam_rh_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); +static int sam_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); + +static int sam_ep0configure(struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int sam_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int sam_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int sam_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen); +static int sam_free(struct usbhost_driver_s *drvr, uint8_t *buffer); +static int sam_ioalloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t buflen); +static int sam_iofree(struct usbhost_driver_s *drvr, uint8_t *buffer); +static int sam_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer); +static int sam_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer); +static int sam_transfer_common(struct sam_rhport_s *rhport, + struct sam_eplist_s *eplist, + uint8_t *buffer, size_t buflen); +static ssize_t sam_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void sam_asynch_completion(struct sam_eplist_s *eplist); +static int sam_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg); +#endif +static int sam_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int sam_connect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport, + bool connected); +#endif +static void sam_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct sam_ohci_s g_ohci; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_ohciconn; + +/* This is a free list of EDs and TD buffers */ + +static struct sam_list_s *g_edfree; /* List of unused EDs */ +static struct sam_list_s *g_tdfree; /* List of unused TDs */ +static struct sam_list_s *g_tbfree; /* List of unused transfer buffers */ + +/* Allocated descriptor memory. These must all be properly aligned + * and must be positioned in a DMA-able memory region. + */ + +/* This must be aligned to a 256-byte boundary */ + +static struct ohci_hcca_s g_hcca + __attribute__ ((aligned (256))); + +/* Pools of free descriptors and buffers. These will all be linked + * into the free lists declared above. These must be aligned to 8-byte + * boundaries (we do 16-byte alignment). + */ + +static struct sam_ed_s g_edalloc[SAMA5_OHCI_NEDS] + __attribute__ ((aligned (SAMA5_DMA_ALIGN))); +static struct sam_gtd_s g_tdalloc[SAMA5_OHCI_NTDS] + __attribute__ ((aligned (SAMA5_DMA_ALIGN))); +static uint8_t g_bufalloc[SAM_BUFALLOC] + __attribute__ ((aligned (SAMA5_DMA_ALIGN))); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_printreg + * + * Description: + * Print the contents of an SAMA5 OHCI register operation + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI_REGDEBUG +static void sam_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Get the contents of an SAMA5 OHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI_REGDEBUG +static void sam_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + sam_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + sam_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMA5 register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI_REGDEBUG +static uint32_t sam_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + sam_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMA5 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI_REGDEBUG +static void sam_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + sam_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void sam_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t sam_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: sam_putle16 + * + * Description: + * Put a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void sam_putle16(uint8_t *dest, uint16_t val) +{ + dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */ + dest[1] = val >> 8; +} +#endif + +/**************************************************************************** + * Name: sam_edalloc + * + * Description: + * Allocate an endpoint descriptor by removing it from the free list + * + ****************************************************************************/ + +static struct sam_ed_s *sam_edalloc(void) +{ + struct sam_ed_s *ed; + + /* Remove the ED from the freelist */ + + ed = (struct sam_ed_s *)g_edfree; + if (ed) + { + g_edfree = ((struct sam_list_s *)ed)->flink; + } + + return ed; +} + +/**************************************************************************** + * Name: sam_edfree + * + * Description: + * Free an endpoint descriptor by returning to the free list + * + ****************************************************************************/ + +static inline void sam_edfree(struct sam_ed_s *ed) +{ + struct sam_list_s *entry = (struct sam_list_s *)ed; + + /* Put the ED back into the free list */ + + entry->flink = g_edfree; + g_edfree = entry; +} + +/**************************************************************************** + * Name: sam_tdalloc + * + * Description: + * Allocate an transfer descriptor from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protected from conconcurrent access to the TD pool by the interrupt + * handler + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +static struct sam_gtd_s *sam_tdalloc(void) +{ + struct sam_gtd_s *ret; + irqstate_t flags; + + /* Disable interrupts momentarily so that sam_tdfree is not called from the + * interrupt handler. + */ + + flags = enter_critical_section(); + ret = (struct sam_gtd_s *)g_tdfree; + if (ret) + { + g_tdfree = ((struct sam_list_s *)ret)->flink; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_tdfree + * + * Description: + * Free a transfer descriptor by returning it to the free list + * + * Assumptions: + * - Only called from the WDH interrupt handler (and during initialization). + * - Interrupts are disabled in any case. + * + ****************************************************************************/ + +static void sam_tdfree(struct sam_gtd_s *td) +{ + struct sam_list_s *tdfree = (struct sam_list_s *)td; + DEBUGASSERT(td); + + tdfree->flink = g_tdfree; + g_tdfree = tdfree; +} + +/**************************************************************************** + * Name: sam_tballoc + * + * Description: + * Allocate an request/descriptor transfer buffer from the free list + * + * Assumptions: + * - Never called from an interrupt handler. + * - Protection from re-entrance must be assured by the caller + * + ****************************************************************************/ + +static uint8_t *sam_tballoc(void) +{ + uint8_t *ret = (uint8_t *)g_tbfree; + if (ret) + { + g_tbfree = ((struct sam_list_s *)ret)->flink; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_tbfree + * + * Description: + * Return an request/descriptor transfer buffer to the free list + * + ****************************************************************************/ + +static void sam_tbfree(uint8_t *buffer) +{ + struct sam_list_s *tbfree = (struct sam_list_s *)buffer; + + if (tbfree) + { + tbfree->flink = g_tbfree; + g_tbfree = tbfree; + } +} + +/**************************************************************************** + * Name: sam_addctrled + * + * Description: + * Helper function to add an ED to the control list. + * + ****************************************************************************/ + +static int sam_addctrled(struct sam_ed_s *ed) +{ + irqstate_t flags; + uint32_t regval; + uintptr_t physed; + + /* Disable control list processing while we modify the list */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Add the new control ED to the head of the control list */ + + ed->hw.nexted = sam_getreg(SAM_USBHOST_CTRLHEADED); + arch_clean_dcache((uintptr_t)ed, (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + physed = sam_physramaddr((uintptr_t)ed); + sam_putreg((uint32_t)physed, SAM_USBHOST_CTRLHEADED); + + /* Re-enable control list processing. */ + + sam_putreg(0, SAM_USBHOST_CTRLED); + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_remctrled + * + * Description: + * Helper function remove an ED from the control list. + * + ****************************************************************************/ + +static inline int sam_remctrled(struct sam_ed_s *ed) +{ + struct sam_ed_s *curr; + struct sam_ed_s *prev; + irqstate_t flags; + uintptr_t physed; + uint32_t regval; + + /* Disable control list processing while we modify the list */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Find the ED in the control list. */ + + physed = sam_getreg(SAM_USBHOST_CTRLHEADED); + for (curr = (struct sam_ed_s *)sam_virtramaddr(physed), prev = NULL; + curr && curr != ed; + prev = curr, curr = (struct sam_ed_s *)curr->hw.nexted); + + /* Hmmm.. It would be a bug if we do not find the ED in the control list. */ + + DEBUGASSERT(curr != NULL); + + /* Remove the ED from the control list */ + + if (curr != NULL) + { + /* Is this ED the first on in the control list? */ + + if (prev == NULL) + { + /* Yes... set the head of the control list to skip over this ED */ + + sam_putreg(ed->hw.nexted, SAM_USBHOST_CTRLHEADED); + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + arch_clean_dcache((uintptr_t)prev, + (uintptr_t)prev + sizeof(struct sam_ed_s)); + } + } + + /* Re-enable control list processing if the control list is still non-empty + * after removing the ED node. + */ + + sam_putreg(0, SAM_USBHOST_CTRLED); + if (sam_getreg(SAM_USBHOST_CTRLHEADED) != 0) + { + /* If the control list is now empty, then disable it */ + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_addbulked + * + * Description: + * Helper function to add an ED to the bulk list. + * + ****************************************************************************/ + +static inline int sam_addbulked(struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_BULK_DISABLE + irqstate_t flags; + uint32_t regval; + uintptr_t physed; + + /* Disable bulk list processing while we modify the list */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_BLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Add the new bulk ED to the head of the bulk list */ + + ed->hw.nexted = sam_getreg(SAM_USBHOST_BULKHEADED); + arch_clean_dcache((uintptr_t)ed, (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + physed = sam_physramaddr((uintptr_t)ed); + sam_putreg((uint32_t)physed, SAM_USBHOST_BULKHEADED); + + /* Re-enable bulk list processing. */ + + sam_putreg(0, SAM_USBHOST_BULKED); + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_BLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: sam_rembulked + * + * Description: + * Helper function remove an ED from the bulk list. + * + ****************************************************************************/ + +static inline int sam_rembulked(struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_BULK_DISABLE + struct sam_ed_s *curr; + struct sam_ed_s *prev; + irqstate_t flags; + uintptr_t physed; + uint32_t regval; + + /* Disable bulk list processing while we modify the list */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_BLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Find the ED in the bulk list. */ + + physed = sam_getreg(SAM_USBHOST_BULKHEADED); + for (curr = (struct sam_ed_s *)sam_virtramaddr(physed), prev = NULL; + curr && curr != ed; + prev = curr, curr = (struct sam_ed_s *)curr->hw.nexted); + + /* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */ + + DEBUGASSERT(curr != NULL); + + /* Remove the ED from the bulk list */ + + if (curr != NULL) + { + /* Is this ED the first on in the bulk list? */ + + if (prev == NULL) + { + /* Yes... set the head of the bulk list to skip over this ED */ + + sam_putreg(ed->hw.nexted, SAM_USBHOST_BULKHEADED); + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + arch_clean_dcache((uintptr_t)prev, + (uintptr_t)prev + sizeof(struct sam_ed_s)); + } + } + + /* Re-enable bulk list processing if the bulk list is still non-empty + * after removing the ED node. + */ + + sam_putreg(0, SAM_USBHOST_BULKED); + if (sam_getreg(SAM_USBHOST_BULKHEADED) != 0) + { + /* If the bulk list is now empty, then disable it */ + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_BLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + } + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: sam_getinterval + * + * Description: + * Convert the endpoint polling interval into a HCCA table increment + * + ****************************************************************************/ + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static unsigned int sam_getinterval(uint8_t interval) +{ + /* The bInterval field of the endpoint descriptor contains the polling interval + * for interrupt and isochronous endpoints. For other types of endpoint, this + * value should be ignored. bInterval is provided in units of 1MS frames. + */ + + if (interval < 3) + { + return 2; + } + else if (interval < 7) + { + return 4; + } + else if (interval < 15) + { + return 8; + } + else if (interval < 31) + { + return 16; + } + else + { + return 32; + } +} +#endif + +/**************************************************************************** + * Name: sam_setinttab + * + * Description: + * Set the interrupt table to the selected value using the provided interval + * and offset. + * + ****************************************************************************/ + +#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE) +static void sam_setinttab(uint32_t value, unsigned int interval, unsigned int offset) +{ + uintptr_t inttbl; + unsigned int i; + + for (i = offset; i < HCCA_INTTBL_WSIZE; i += interval) + { + /* Modify the table value */ + + g_hcca.inttbl[i] = value; + } + + /* Make sure that the modified table value is flushed to RAM */ + + inttbl = (uintptr_t)g_hcca.inttbl; + arch_clean_dcache(inttbl, inttbl + sizeof(uint32_t)*HCCA_INTTBL_WSIZE); +} +#endif + +/**************************************************************************** + * Name: sam_addinted + * + * Description: + * Helper function to add an ED to the HCCA interrupt table. + * + * To avoid reshuffling the table so much and to keep life simple in general, + * the following rules are applied: + * + * 1. IN EDs get the even entries, OUT EDs get the odd entries. + * 2. Add IN/OUT EDs are scheduled together at the minimum interval of all + * IN/OUT EDs. + * + * This has the following consequences: + * + * 1. The minimum support polling rate is 2MS, and + * 2. Some devices may get polled at a much higher rate than they request. + * + ****************************************************************************/ + +static inline int sam_addinted(const struct usbhost_epdesc_s *epdesc, + struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_INT_DISABLE + irqstate_t flags; + unsigned int interval; + unsigned int offset; + uintptr_t physed; + uintptr_t physhead; + uint32_t regval; + + /* Disable periodic list processing. Does this take effect immediately? Or + * at the next SOF... need to check. + */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_PLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Get the quanitized interval value associated with this ED and save it + * in the ED. + */ + + interval = sam_getinterval(epdesc->interval); + ed->interval = interval; + usbhost_vtrace2(OHCI_VTRACE2_INTERVAL, epdesc->interval, interval); + + /* Get the offset associated with the ED direction. IN EDs get the even + * entries, OUT EDs get the odd entries. + * + * Get the new, minimum interval. Add IN/OUT EDs are scheduled together + * at the minimum interval of all IN/OUT EDs. + */ + + if (epdesc->in) + { + offset = 0; + if (g_ohci.ininterval > interval) + { + g_ohci.ininterval = interval; + } + else + { + interval = g_ohci.ininterval; + } + } + else + { + offset = 1; + if (g_ohci.outinterval > interval) + { + g_ohci.outinterval = interval; + } + else + { + interval = g_ohci.outinterval; + } + } + + usbhost_vtrace2(OHCI_VTRACE2_MININTERVAL, interval, offset); + + /* Get the (physical) head of the first of the duplicated entries. The + * first offset entry is always guaranteed to contain the common ED list + * head. + */ + + physhead = g_hcca.inttbl[offset]; + + /* Clear all current entries in the interrupt table for this direction */ + + sam_setinttab(0, 2, offset); + + /* Add the new ED before the old head of the periodic ED list and set the + * new ED as the head ED in all of the appropriate entries of the HCCA + * interrupt table. + */ + + ed->hw.nexted = physhead; + arch_clean_dcache((uintptr_t)ed, (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + physed = sam_physramaddr((uintptr_t)ed); + sam_setinttab((uint32_t)physed, interval, offset); + + usbhost_vtrace1(OHCI_VTRACE1_PHYSED, physed); + + /* Re-enable periodic list processing */ + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_PLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: sam_reminted + * + * Description: + * Helper function to remove an ED from the HCCA interrupt table. + * + * To avoid reshuffling the table so much and to keep life simple in general, + * the following rules are applied: + * + * 1. IN EDs get the even entries, OUT EDs get the odd entries. + * 2. Add IN/OUT EDs are scheduled together at the minimum interval of all + * IN/OUT EDs. + * + * This has the following consequences: + * + * 1. The minimum support polling rate is 2MS, and + * 2. Some devices may get polled at a much higher rate than they request. + * + ****************************************************************************/ + +static inline int sam_reminted(struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_INT_DISABLE + struct sam_ed_s *head; + struct sam_ed_s *curr; + struct sam_ed_s *prev; + irqstate_t flags; + uintptr_t physhead; + unsigned int interval; + unsigned int offset; + uint32_t regval; + + /* Disable periodic list processing. Does this take effect immediately? Or + * at the next SOF... need to check. + */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_PLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Get the offset associated with the ED direction. IN EDs get the even + * entries, OUT EDs get the odd entries. + */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + offset = 0; + } + else + { + offset = 1; + } + + /* Get the head of the first of the duplicated entries. The first offset + * entry is always guaranteed to contain the common ED list head. + */ + + physhead = g_hcca.inttbl[offset]; + head = (struct sam_ed_s *)sam_virtramaddr((uintptr_t)physhead); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(OHCI_VTRACE1_VIRTED, (uintptr_t)ed); +#else + uvdbg("ed: %08x head: %08x next: %08x offset: %d\n", + ed, physhead, head ? head->hw.nexted : 0, offset); +#endif + + /* Find the ED to be removed in the ED list */ + + for (curr = head, prev = NULL; + curr && curr != ed; + prev = curr, curr = (struct sam_ed_s *)curr->hw.nexted); + + /* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */ + + DEBUGASSERT(curr != NULL); + if (curr != NULL) + { + /* Clear all current entries in the interrupt table for this direction */ + + sam_setinttab(0, 2, offset); + + /* Remove the ED from the list.. Is this ED the first on in the list? */ + + if (prev == NULL) + { + /* Yes... set the head of the bulk list to skip over this ED */ + + physhead = ed->hw.nexted; + head = (struct sam_ed_s *)sam_virtramaddr((uintptr_t)physhead); + } + else + { + /* No.. set the forward link of the previous ED in the list + * skip over this ED. + */ + + prev->hw.nexted = ed->hw.nexted; + } + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(OHCI_VTRACE1_VIRTED, (uintptr_t)ed); +#else + uvdbg("ed: %08x head: %08x next: %08x\n", + ed, physhead, head ? head->hw.nexted : 0); +#endif + + /* Calculate the new minimum interval for this list */ + + interval = MAX_PERINTERVAL; + for (curr = head; curr; curr = (struct sam_ed_s *)curr->hw.nexted) + { + if (curr->interval < interval) + { + interval = curr->interval; + } + } + + usbhost_vtrace2(OHCI_VTRACE2_MININTERVAL, interval, offset); + + /* Save the new minimum interval */ + + if ((ed->hw.ctrl && ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + g_ohci.ininterval = interval; + } + else + { + g_ohci.outinterval = interval; + } + + /* Set the head ED in all of the appropriate entries of the HCCA interrupt + * table (head might be NULL). + */ + + sam_setinttab((uint32_t)physhead, interval, offset); + } + + /* Re-enabled periodic list processing */ + + if (head != NULL) + { + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_PLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + } + + leave_critical_section(flags); + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: sam_addisoced + * + * Description: + * Helper functions to add an ED to the periodic table. + * + ****************************************************************************/ + +static inline int sam_addisoced(const struct usbhost_epdesc_s *epdesc, + struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_ISOC_DISABLE +# warning "Isochronous endpoints not yet supported" +#endif + return -ENOSYS; + +} + +/**************************************************************************** + * Name: sam_remisoced + * + * Description: + * Helper functions to remove an ED from the periodic table. + * + ****************************************************************************/ + +static inline int sam_remisoced(struct sam_ed_s *ed) +{ +#ifndef CONFIG_USBHOST_ISOC_DISABLE +# warning "Isochronous endpoints not yet supported" +#endif + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_enqueuetd + * + * Description: + * Enqueue a transfer descriptor. Notice that this function only supports + * queue on TD per ED. + * + ****************************************************************************/ + +static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplist, + struct sam_ed_s *ed, uint32_t dirpid, uint32_t toggle, + volatile uint8_t *buffer, size_t buflen) +{ + struct sam_gtd_s *td; + struct sam_gtd_s *tdtail; + uintptr_t phytd; + uintptr_t phytail; + uintptr_t phybuf; + int ret = -ENOMEM; + + /* Allocate a TD from the free list */ + + td = sam_tdalloc(); + if (td != NULL) + { + /* Skip processing of this ED while we modify the TD list. */ + + ed->hw.ctrl |= ED_CONTROL_K; + arch_clean_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + /* Get the tail ED for this hub port */ + + tdtail = eplist->tail; + + /* Get physical addresses to support the DMA */ + + phytd = sam_physramaddr((uintptr_t)td); + phytail = sam_physramaddr((uintptr_t)tdtail); + phybuf = sam_physramaddr((uintptr_t)buffer); + + /* Initialize the allocated TD and link it before the common tail TD. */ + + td->hw.ctrl = (GTD_STATUS_R | dirpid | TD_DELAY(0) | + toggle | GTD_STATUS_CC_MASK); + tdtail->hw.ctrl = 0; + td->hw.cbp = (uint32_t)phybuf; + tdtail->hw.cbp = 0; + td->hw.nexttd = (uint32_t)phytail; + tdtail->hw.nexttd = 0; + td->hw.be = (uint32_t)(phybuf + (buflen - 1)); + tdtail->hw.be = 0; + + /* Configure driver-only fields in the extended TD structure */ + + td->ed = ed; + + /* Link the td to the head of the ED's TD list */ + + ed->hw.headp = (uint32_t)phytd | ((ed->hw.headp) & ED_HEADP_C); + ed->hw.tailp = (uint32_t)phytail; + + /* Flush the buffer (if there is one), the new TD, and the modified ED + * to RAM. + */ + + if (buffer && buflen > 0) + { + arch_clean_dcache((uintptr_t)buffer, + (uintptr_t)buffer + buflen); + } + + arch_clean_dcache((uintptr_t)tdtail, + (uintptr_t)tdtail + sizeof(struct ohci_gtd_s)); + arch_clean_dcache((uintptr_t)td, + (uintptr_t)td + sizeof(struct ohci_gtd_s)); + + /* Resume processing of this ED */ + + ed->hw.ctrl &= ~ED_CONTROL_K; + arch_clean_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_ep0enqueue + * + * Description: + * Initialize ED for a root hub EP0, add it to the control ED list, and + * enable control transfers. + * + * Input Parameters: + * rhpndx - Root hub port index. + * + * Returned Values: + * None + * + ****************************************************************************/ + +static int sam_ep0enqueue(struct sam_rhport_s *rhport) +{ + struct sam_ed_s *edctrl; + struct sam_gtd_s *tdtail; + irqstate_t flags; + uintptr_t physaddr; + int ret; + + DEBUGASSERT(rhport && !rhport->ep0init && rhport->ep0.ed == NULL && + rhport->ep0.tail == NULL); + + /* Allocate a control ED and a tail TD */ + + flags = enter_critical_section(); + edctrl = sam_edalloc(); + if (!edctrl) + { + leave_critical_section(flags); + return -ENOMEM; + } + + tdtail = sam_tdalloc(); + if (!tdtail) + { + sam_edfree(edctrl); + leave_critical_section(flags); + return -ENOMEM; + } + + rhport->ep0.ed = edctrl; + rhport->ep0.tail = tdtail; + + /* Initialize the common tail TD for this port */ + + memset(tdtail, 0, sizeof(struct sam_gtd_s)); + tdtail->ed = edctrl; + + /* Initialize the control endpoint for this port. + * Set up some default values (like max packetsize = 8). + * NOTE that the SKIP bit is set until the first readl TD is added. + */ + + memset(edctrl, 0, sizeof(struct sam_ed_s)); + (void)sam_ep0configure(&rhport->drvr, &rhport->ep0, 0, + rhport->hport.hport.speed, 8); + + edctrl->hw.ctrl |= ED_CONTROL_K; + edctrl->eplist = &rhport->ep0; + edctrl->xfrtype = USB_EP_ATTR_XFER_CONTROL; + + /* Link the common tail TD to the ED's TD list */ + + physaddr = sam_physramaddr((uintptr_t)tdtail); + edctrl->hw.headp = (uint32_t)physaddr; + edctrl->hw.tailp = (uint32_t)physaddr; + + /* Flush the affected control ED and tail TD to RAM */ + + arch_clean_dcache((uintptr_t)edctrl, + (uintptr_t)edctrl + sizeof(struct ohci_ed_s)); + arch_clean_dcache((uintptr_t)tdtail, + (uintptr_t)tdtail + sizeof(struct ohci_gtd_s)); + + /* Add the ED to the control list */ + + ret = sam_addctrled(edctrl); + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_ep0dequeue + * + * Description: + * Remove the ED for EP0 from the control ED list and possibly disable control + * list processing. + * + * Input Parameters: + * ep0 - The control endpoint to be released. May be the control endpoint for + * an attached hub. + * + * Returned Values: + * None + * + ****************************************************************************/ + +static void sam_ep0dequeue(struct sam_eplist_s *ep0) +{ + struct sam_ed_s *edctrl; + struct sam_ed_s *curred; + struct sam_ed_s *preved; + struct sam_gtd_s *tdtail; + struct sam_gtd_s *currtd; + irqstate_t flags; + uintptr_t physcurr; + uint32_t regval; + + DEBUGASSERT(ep0->ed != NULL && ep0->tail != NULL); + + /* ControlListEnable. This bit is cleared to disable the processing of the + * Control list. We should never modify the control list while CLE is set. + */ + + flags = enter_critical_section(); + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Search the control list to find the entry to be removed (and its + * precedessor). + */ + + edctrl = ep0->ed; + physcurr = sam_getreg(SAM_USBHOST_CTRLHEADED); + + for (curred = (struct sam_ed_s *)sam_virtramaddr(physcurr), + preved = NULL; + curred && curred != edctrl; + preved = curred, + curred = (struct sam_ed_s *)sam_virtramaddr(physcurr)) + { + physcurr = curred->hw.nexted; + } + + DEBUGASSERT(curred); + + /* Remove the ED from the control list */ + + if (preved) + { + /* Unlink the ED from the previous ED in the list */ + + preved->hw.nexted = edctrl->hw.nexted; + + /* Flush the modified ED to RAM */ + + arch_clean_dcache((uintptr_t)preved, + (uintptr_t)preved + sizeof(struct ohci_ed_s)); + } + else + { + /* Set the new control list head ED */ + + sam_putreg(edctrl->hw.nexted, SAM_USBHOST_CTRLHEADED); + + /* If the control list head is still non-NULL, then (re-)enable + * processing of the Control list. + */ + + if (edctrl->hw.nexted != 0) + { + regval = sam_getreg(SAM_USBHOST_CTRL); + regval |= OHCI_CTRL_CLE; + sam_putreg(regval, SAM_USBHOST_CTRL); + } + } + + leave_critical_section(flags); + + /* Release any TDs that may still be attached to the ED. */ + + tdtail = ep0->tail; + physcurr = edctrl->hw.headp; + + for (currtd = (struct sam_gtd_s *)sam_virtramaddr(physcurr); + currtd && currtd != tdtail; + currtd = (struct sam_gtd_s *)sam_virtramaddr(physcurr)) + { + physcurr = currtd->hw.nexttd; + sam_tdfree(currtd); + } + + /* Free the tail TD and the control ED allocated for this port */ + + sam_tdfree(tdtail); + sam_edfree(edctrl); + + ep0->ed = NULL; + ep0->tail = NULL; +} + +/**************************************************************************** + * Name: sam_wdhwait + * + * Description: + * Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to perform the transfer). + * We do this to minimize race conditions. This logic would have to be + * expanded if we want to have more than one packet in flight at a time! + * + ****************************************************************************/ + +static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + uint8_t *buffer, uint16_t buflen) +{ + struct sam_eplist_s *eplist; + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (rhport->connected) + { + /* Yes.. Get the endpoint list associated with the ED */ + + eplist = ed->eplist; + DEBUGASSERT(eplist); + + /* Then set wdhwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + eplist->wdhwait = true; +#ifdef CONFIG_USBHOST_ASYNCH + eplist->callback = NULL; + eplist->arg = NULL; +#endif + eplist->buffer = buffer; + eplist->buflen = buflen; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_wdhasynch + * + * Description: + * Set the request for the Writeback Done Head callback well BEFORE enabling + * the transfer (as soon as we are absolutely committed to perform the + * transfer). We do this to minimize race conditions. This logic would have + * to be expanded if we want to have more than one packet in flight at a time! + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int sam_wdhasynch(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + usbhost_asynch_t callback, void *arg, + uint8_t *buffer, uint16_t buflen) +{ + struct sam_eplist_s *eplist; + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (rhport->connected) + { + /* Yes.. Get the endpoint list associated with the ED */ + + eplist = ed->eplist; + DEBUGASSERT(eplist); + + /* Then set wdhwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + eplist->wdhwait = false; + eplist->callback = callback; + eplist->arg = arg; + eplist->buffer = buffer; + eplist->buflen = buflen; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: sam_ctrltd + * + * Description: + * Process a IN or OUT request on the control endpoint. This function + * will enqueue the request and wait for it to complete. Only one transfer + * may be queued; Neither these methods nor the transfer() method can be + * called again until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + ****************************************************************************/ + +static int sam_ctrltd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplist, + uint32_t dirpid, uint8_t *buffer, size_t buflen) +{ + struct sam_ed_s *edctrl; + uint32_t toggle; + uint32_t regval; + int ret; + + /* Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer. + */ + + edctrl = eplist->ed; + ret = sam_wdhwait(rhport, edctrl, buffer, buflen); + if (ret != OK) + { + usbhost_trace1(OHCI_TRACE1_DEVDISCONN, RHPORT(rhport)); + return ret; + } + + /* Configure the toggle field in the TD */ + + if (dirpid == GTD_STATUS_DP_SETUP) + { + toggle = GTD_STATUS_T_DATA0; + } + else + { + toggle = GTD_STATUS_T_DATA1; + } + + /* Then enqueue the transfer */ + + edctrl->tdstatus = TD_CC_NOERROR; + ret = sam_enqueuetd(rhport, eplist, edctrl, dirpid, toggle, buffer, buflen); + if (ret == OK) + { + /* Set ControlListFilled. This bit is used to indicate whether there are + * TDs on the Control list. + */ + + regval = sam_getreg(SAM_USBHOST_CMDST); + regval |= OHCI_CMDST_CLF; + sam_putreg(regval, SAM_USBHOST_CMDST); + + /* Release the OHCI semaphore while we wait. Other threads need the + * opportunity to access the OHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not OHCI common) until + * the transfer is complete. But we can't use the common OHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ +#warning REVISIT + sam_givesem(&g_ohci.exclsem); + + /* Wait for the Writeback Done Head interrupt Loop to handle any false + * alarm semaphore counts. + */ + + while (eplist->wdhwait) + { + sam_takesem(&eplist->wdhsem); + } + + /* Re-acquire the ECHI semaphore. The caller expects to be holding + * this upon return. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Check the TD completion status bits */ + + if (edctrl->tdstatus == TD_CC_NOERROR) + { + ret = OK; + } + else + { + usbhost_trace2(OHCI_TRACE2_BADTDSTATUS, RHPORT(rhport), + edctrl->tdstatus); + ret = edctrl->tdstatus == TD_CC_STALL ? -EPERM : -EIO; + } + } + + /* Make sure that there is no outstanding request on this endpoint */ + + eplist->wdhwait = false; + return ret; +} + +/**************************************************************************** + * Name: sam_rhsc_bottomhalf + * + * Description: + * OHCI root hub status change interrupt handler + * + ****************************************************************************/ + +static void sam_rhsc_bottomhalf(void) +{ + struct sam_rhport_s *rhport; + uint32_t regaddr; + uint32_t rhportst; + int rhpndx; + + /* Handle root hub status change on each root port */ + + for (rhpndx = 0; rhpndx < SAM_OHCI_NRHPORT; rhpndx++) + { + rhport = &g_ohci.rhport[rhpndx]; + + regaddr = SAM_USBHOST_RHPORTST(rhpndx+1); + rhportst = sam_getreg(regaddr); + + usbhost_vtrace2(OHCI_VTRACE2_RHPORTST, rhpndx + 1, (uint16_t)rhportst); + + if ((rhportst & OHCI_RHPORTST_CSC) != 0) + { + uint32_t rhstatus = sam_getreg(SAM_USBHOST_RHSTATUS); + usbhost_vtrace1(OHCI_VTRACE1_CSC, rhstatus); + + /* If DRWE is set, Connect Status Change indicates a remote + * wake-up event + */ + + if (rhstatus & OHCI_RHSTATUS_DRWE) + { + usbhost_vtrace1(OHCI_VTRACE1_DRWE, rhstatus); + } + + /* Otherwise... Not a remote wake-up event */ + + else + { + /* Check current connect status */ + + if ((rhportst & OHCI_RHPORTST_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!rhport->connected) + { + /* Yes.. connected. */ + + rhport->connected = true; + + usbhost_vtrace2(OHCI_VTRACE2_CONNECTED, + rhpndx + 1, g_ohci.pscwait); + + /* Notify any waiters */ + + if (g_ohci.pscwait) + { + sam_givesem(&g_ohci.pscsem); + g_ohci.pscwait = false; + } + } + else + { + usbhost_vtrace1(OHCI_VTRACE1_ALREADYCONN, rhportst); + } + + /* The LSDA (Low speed device attached) bit is valid + * when CCS == 1. + */ + + if ((rhportst & OHCI_RHPORTST_LSDA) != 0) + { + rhport->hport.hport.speed = USB_SPEED_LOW; + } + else + { + rhport->hport.hport.speed = USB_SPEED_FULL; + } + + usbhost_vtrace1(OHCI_VTRACE1_SPEED, rhport->hport.hport.speed); + } + + /* Check if we are now disconnected */ + + else if (rhport->connected) + { + /* Yes.. disconnect the device */ + + usbhost_vtrace2(OHCI_VTRACE2_DISCONNECTED, + rhpndx + 1, g_ohci.pscwait); + + rhport->connected = false; + + /* Set the port speed to the default (FULL). We cannot + * yet free the function address. That has to be done + * by the class when responds to the disconnection. + */ + + rhport->hport.hport.speed = USB_SPEED_FULL; + + /* Are we bound to a class instance? */ + + if (rhport->hport.hport.devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(rhport->hport.hport.devclass); + rhport->hport.hport.devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change + * event. + */ + + if (g_ohci.pscwait) + { + sam_givesem(&g_ohci.pscsem); + g_ohci.pscwait = false; + } + } + else + { + usbhost_vtrace1(OHCI_VTRACE1_ALREADYDISCONN, rhportst); + } + } + + /* Clear the status change interrupt */ + + sam_putreg(OHCI_RHPORTST_CSC, regaddr); + } + + /* Check for port reset status change */ + + if ((rhportst & OHCI_RHPORTST_PRSC) != 0) + { + /* Release the RH port from reset */ + + sam_putreg(OHCI_RHPORTST_PRSC, regaddr); + } + } +} + +/**************************************************************************** + * Name: sam_wdh_bottomhalf + * + * Description: + * OHCI write done head interrupt handler + * + ****************************************************************************/ + +static void sam_wdh_bottomhalf(void) +{ + struct sam_eplist_s *eplist; + struct sam_gtd_s *td; + struct sam_gtd_s *next; + struct sam_ed_s *ed; + uintptr_t paddr; + uintptr_t tmp; + + /* The host controller just wrote the finished TDs into the HCCA done head. + * This may include multiple packets that were transferred in the preceding + * frame. + * + * Remove the TD from the Writeback Done Head in the HCCA and return + * it to the free list. Note that this is safe because the hardware + * will not modify the writeback done head again until the WDH bit is + * cleared in the interrupt status register. + */ + + /* Invalidate D-cache to force re-reading of the Done Head */ + +#if 0 /* Apparently insufficient */ + arch_invalidate_dcache((uintptr_t)&g_hcca.donehead, + (uintptr_t)&g_hcca.donehead + sizeof(uint32_t)); +#else + arch_invalidate_dcache((uintptr_t)&g_hcca, + (uintptr_t)&g_hcca + sizeof(struct ohci_hcca_s)); +#endif + + /* Now read the done head. */ + + td = (struct sam_gtd_s *)sam_virtramaddr(g_hcca.donehead & HCCA_DONEHEAD_MASK); + g_hcca.donehead = 0; + + /* Process each TD in the write done list */ + + for (; td; td = next) + { + /* Invalidate the just-finished TD from D-cache to force it to be + * reloaded from memory. + */ + + arch_invalidate_dcache((uintptr_t)td, + (uintptr_t)td + sizeof(struct ohci_gtd_s)); + + /* Get the ED in which this TD was enqueued */ + + ed = td->ed; + DEBUGASSERT(ed != NULL); + + /* Get the endpoint list that contains the ED */ + + eplist = ed->eplist; + DEBUGASSERT(eplist != NULL); + + /* Do nothing if there is no transfer in progress. This situation may + * occur after cancellation of a transfer. + */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (eplist->wdhwait || eplist->callback) +#else + if (eplist->wdhwait) +#endif + { + /* Invalidate the control ED so that it two will be re-read from + * memory. + */ + + arch_invalidate_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + /* Save the condition code from the (single) TD status/control + * word. + */ + + ed->tdstatus = (td->hw.ctrl & GTD_STATUS_CC_MASK) >> GTD_STATUS_CC_SHIFT; + +#ifdef HAVE_USBHOST_TRACE + if (ed->tdstatus != TD_CC_NOERROR) + { + /* The transfer failed for some reason... dump some diagnostic info. */ + + usbhost_trace2(OHCI_TRACE2_WHDTDSTATUS, ed->tdstatus, ed->xfrtype); + } +#endif + + /* Determine the number of bytes actually transfer by* subtracting + * the buffer start address from the CBP. A value of zero means + * that all bytes were transferred. + */ + + tmp = (uintptr_t)td->hw.cbp; + if (tmp == 0) + { + /* Set the (fake) CBP to the end of the buffer + 1 */ + + tmp = eplist->buflen; + } + else + { + paddr = sam_physramaddr((uintptr_t)eplist->buffer); + DEBUGASSERT(tmp >= paddr); + + /* Determine the size of the transfer by subtracting the + * current buffer pointer (CBP) from the initial buffer + * pointer (on packet receipt only). + */ + + tmp -= paddr; + DEBUGASSERT(tmp < UINT16_MAX); + } + + eplist->xfrd = (uint16_t)tmp; + } + + /* Return the TD to the free list */ + + next = (struct sam_gtd_s *)sam_virtramaddr(td->hw.nexttd); + sam_tdfree(td); + + /* And wake up the thread waiting for the WDH event */ + + if (eplist->wdhwait) + { + sam_givesem(&eplist->wdhsem); + eplist->wdhwait = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No thread waiting. Is there a callback scheduled? */ + + else if (eplist->callback) + { + /* Yes.. perform the callback */ + + sam_asynch_completion(eplist); + } +#endif + } +} + +/**************************************************************************** + * Name: sam_ohci_bottomhalf + * + * Description: + * OHCI interrupt bottom half. This function runs on the high priority worker + * thread and was xcheduled when the last interrupt occurred. The set of + * pending interrupts is provided as the argument. OHCI interrupts were + * disabled when this function is scheduled so no further interrupts can + * occur until this work re-enables OHCI interrupts + * + ****************************************************************************/ + +static void sam_ohci_bottomhalf(void *arg) +{ + uint32_t pending = (uint32_t)arg; + + /* We need to have exclusive access to the OHCI data structures. Waiting here + * is not a good thing to do on the worker thread, but there is no real option + * (other than to reschedule and delay). + */ + + sam_takesem(&g_ohci.exclsem); + + /* Root hub status change interrupt */ + + if ((pending & OHCI_INT_RHSC) != 0) + { + /* Handle root hub status change on each root port */ + + usbhost_vtrace1(OHCI_VTRACE1_RHSC, pending); + sam_rhsc_bottomhalf(); + } + + /* Writeback Done Head interrupt */ + + if ((pending & OHCI_INT_WDH) != 0) + { + /* The host controller just wrote the list of finished TDs into the HCCA + * done head. This may include multiple packets that were transferred + * in the preceding frame. + */ + + usbhost_vtrace1(OHCI_VTRACE1_WDHINTR, pending); + sam_wdh_bottomhalf(); + } + +#ifdef CONFIG_DEBUG_USB + if ((pending & SAM_DEBUG_INTS) != 0) + { + if ((pending & OHCI_INT_UE) != 0) + { + /* An unrecoverable error occurred. Unrecoverable errors + * are usually the consequence of bad descriptor contents + * or DMA errors. + * + * Treat this like a normal write done head interrupt. We + * just want to see if there is any status information writen + * to the descriptors (and the normal write done head + * interrupt will not be occurring). + */ + + usbhost_trace1(OHCI_TRACE1_INTRUNRECOVERABLE, pending); + sam_wdh_bottomhalf(); + } + else + { + usbhost_trace1(OHCI_TRACE1_INTRUNHANDLED, pending); + } + } +#endif + + /* Now re-enable interrupts */ + + sam_putreg(OHCI_INT_MIE, SAM_USBHOST_INTEN); + sam_givesem(&g_ohci.exclsem); +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport) +{ + irqstate_t flags; + int rhpndx; + + /* Loop until a change in the connection state changes on one of the root hub + * ports or until an error occurs. + */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < SAM_OHCI_NRHPORT; rhpndx++) + { + struct sam_rhport_s *rhport = &g_ohci.rhport[rhpndx]; + struct usbhost_hubport_s *connport; + +#if 0 /* #ifdef CONFIG_SAMA5_EHCI */ + /* If a device is no longer connected, return the port to the EHCI + * controller. Zero is the reset value for all ports; one makes + * the corresponding port available to OHCI. + */ + + if (!rhport->connected) + { + uint32_t regval = getreg32(SAM_SFR_OHCIICR); + regval &= ~SFR_OHCIICR_RES(rhpndx); + putreg32(regval, SAM_SFR_OHCIICR); + } +#endif + + /* Has the connection state changed on the RH port? */ + + connport = &rhport->hport.hport; + if (rhport->connected != connport->connected) + { + /* Yes.. Return the RH port number to inform the caller which + * port has the connection change. + */ + + leave_critical_section(flags); + usbhost_vtrace2(OHCI_VTRACE2_WAKEUP, + rhpndx + 1, g_ohci.rhport[rhpndx].connected); + + connport->connected = rhport->connected; + *hport = connport; + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (g_ohci.hport) + { + struct usbhost_hubport_s *connport; + + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)g_ohci.hport; + g_ohci.hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + usbhost_vtrace2(OHCI_VTRACE2_HUBWAKEUP, + HPORT(connport), connport->connected); + return OK; + } +#endif + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + + g_ohci.pscwait = true; + sam_takesem(&g_ohci.pscsem); + } +} + +/**************************************************************************** + * Name: sam_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_rh_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport) +{ + struct sam_rhport_s *rhport; + uint32_t regaddr; + int rhpndx; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL); + rhpndx = hport->port; + + DEBUGASSERT(rhpndx >= 0 && rhpndx < SAM_OHCI_NRHPORT); + rhport = &g_ohci.rhport[rhpndx]; + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!rhport->connected) + { + /* No, return an error */ + + usbhost_vtrace1(OHCI_VTRACE1_ENUMDISCONN, RHPORT(rhport)); + return -ENODEV; + } + + /* Add root hub EP0 to the control list */ + + if (!rhport->ep0init) + { + ret = sam_ep0enqueue(rhport); + if (ret < 0) + { + usbhost_trace2(OHCI_TRACE2_EP0ENQUEUE_FAILED, RHPORT(rhport), + -ret); + return ret; + } + + /* Successfully initialized */ + + rhport->ep0init = true; + } + + /* USB 2.0 spec says at least 50ms delay before port reset */ + + up_mdelay(100); + + /* Put the root hub port in reset (the SAMA5 supports three downstream + * ports) + */ + + regaddr = SAM_USBHOST_RHPORTST(rhpndx+1); + sam_putreg(OHCI_RHPORTST_PRS, regaddr); + + /* Wait for the port reset to complete */ + + while ((sam_getreg(regaddr) & OHCI_RHPORTST_PRS) != 0); + + /* Release RH port 1 from reset and wait a bit */ + + sam_putreg(OHCI_RHPORTST_PRSC, regaddr); + up_mdelay(200); + return OK; +} + +static int sam_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport) +{ + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = sam_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + usbhost_vtrace1(OHCI_VTRACE1_CLASSENUM, HPORT(hport)); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + usbhost_trace2(OHCI_TRACE2_CLASSENUM_FAILED, HPORT(hport), -ret); + } + + return ret; +} + +/************************************************************************************ + * Name: sam_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls. A funcaddr of zero will be received if no address is yet assigned + * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_ep0configure(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *ep0list = (struct sam_eplist_s *)ep0; + struct sam_ed_s *edctrl; + uint32_t hwctrl; + + usbhost_vtrace2(OHCI_VTRACE2_EP0CONFIG, speed, funcaddr); + DEBUGASSERT(rhport && maxpacketsize < 2048); + + edctrl = ep0list->ed; + + /* We must have exclusive access to EP0 and the control list */ + + sam_takesem(&g_ohci.exclsem); + + /* Set the EP0 ED control word (preserving only speed) */ + + hwctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | + (uint32_t)ED_CONTROL_D_TD1 | + (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + + if (speed == USB_SPEED_LOW) + { + hwctrl |= ED_CONTROL_S; + } + + edctrl->hw.ctrl = hwctrl; + + /* Flush the modified control ED to RAM */ + + arch_clean_dcache((uintptr_t)edctrl, + (uintptr_t)edctrl + sizeof(struct ohci_ed_s)); + sam_givesem(&g_ohci.exclsem); + + usbhost_vtrace2(OHCI_VTRACE2_EP0CTRLED, RHPORT(rhport), (uint16_t)edctrl->hw.ctrl); + UNUSED(rhport); + return OK; +} + +/************************************************************************************ + * Name: sam_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *eplist; + struct usbhost_hubport_s *hport; + struct sam_ed_s *ed; + struct sam_gtd_s *td; + uintptr_t physaddr; + int ret = -ENOMEM; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(rhport != NULL && epdesc != NULL && epdesc->hport != NULL); + DEBUGASSERT(ep != NULL && rhport->connected); + UNUSED(rhport); + + hport = epdesc->hport; + + /* Allocate a container for the endpoint data */ + + eplist = (struct sam_eplist_s *)kmm_zalloc(sizeof(struct sam_eplist_s)); + if (!eplist) + { + usbhost_trace1(OHCI_TRACE1_EPLISTALLOC_FAILED, 0); + goto errout; + } + + /* Initialize the endpoint container */ + + sem_init(&eplist->wdhsem, 0, 0); + + /* We must have exclusive access to the ED pool, the bulk list, the periodic list + * and the interrupt table. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Allocate an ED and a tail TD for the new endpoint */ + + ed = sam_edalloc(); + if (!ed) + { + usbhost_trace1(OHCI_TRACE1_EDALLOC_FAILED, 0); + goto errout_with_semaphore; + } + + td = sam_tdalloc(); + if (!td) + { + usbhost_trace1(OHCI_TRACE1_TDALLOC_FAILED, 0); + goto errout_with_ed; + } + + /* Save the descriptors in the endpoint container */ + + eplist->ed = ed; + eplist->tail = td; + + /* Configure the endpoint descriptor. */ + + memset((void *)ed, 0, sizeof(struct sam_ed_s)); + + ed->hw.ctrl = (uint32_t)(hport->funcaddr) << ED_CONTROL_FA_SHIFT | + (uint32_t)(epdesc->addr) << ED_CONTROL_EN_SHIFT | + (uint32_t)(epdesc->mxpacketsize) << ED_CONTROL_MPS_SHIFT; + + /* Get the direction of the endpoint. For control endpoints, the + * direction is in the TD. + */ + + if (epdesc->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + ed->hw.ctrl |= ED_CONTROL_D_TD1; + } + else if (epdesc->in) + { + ed->hw.ctrl |= ED_CONTROL_D_IN; + } + else + { + ed->hw.ctrl |= ED_CONTROL_D_OUT; + } + + /* Check for a low-speed device */ + + if (hport->speed == USB_SPEED_LOW) + { + ed->hw.ctrl |= ED_CONTROL_S; + } + + /* Set the transfer type */ + + ed->xfrtype = epdesc->xfrtype; + + /* Special Case isochronous transfer types */ + +#if 0 /* Isochronous transfers not yet supported */ + if (ed->xfrtype == USB_EP_ATTR_XFER_ISOC) + { + ed->hw.ctrl |= ED_CONTROL_F; + } +#endif + + ed->eplist = eplist; + usbhost_vtrace2(OHCI_VTRACE2_EPALLOC, epdesc->addr, (uint16_t)ed->hw.ctrl); + + /* Configure the tail descriptor. */ + + memset(td, 0, sizeof(struct sam_gtd_s)); + td->ed = ed; + + /* Link the tail TD to the ED's TD list */ + + physaddr = (uintptr_t)sam_physramaddr((uintptr_t)td); + ed->hw.headp = physaddr; + ed->hw.tailp = physaddr; + + /* Make sure these settings are flushed to RAM */ + + arch_clean_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + arch_clean_dcache((uintptr_t)td, + (uintptr_t)td + sizeof(struct ohci_gtd_s)); + + /* Now add the endpoint descriptor to the appropriate list */ + + switch (ed->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + ret = sam_addctrled(ed); + break; + + case USB_EP_ATTR_XFER_BULK: + ret = sam_addbulked(ed); + break; + + case USB_EP_ATTR_XFER_INT: + ret = sam_addinted(epdesc, ed); + break; + + case USB_EP_ATTR_XFER_ISOC: + ret = sam_addisoced(epdesc, ed); + break; + + default: + ret = -EINVAL; + break; + } + + /* Was the ED successfully added? */ + + if (ret != OK) + { + /* No.. destroy it and report the error */ + + usbhost_trace2(OHCI_TRACE2_EDENQUEUE_FAILED, ed->xfrtype, -ret); + goto errout_with_td; + } + + /* Success.. return an opaque reference to the endpoint list container */ + + *ep = (usbhost_ep_t)eplist; + sam_givesem(&g_ohci.exclsem); + return OK; + +errout_with_td: + sam_tdfree(td); +errout_with_ed: + sam_edfree(ed); +errout_with_semaphore: + sam_givesem(&g_ohci.exclsem); + kmm_free(eplist); +errout: + return ret; +} + +/************************************************************************************ + * Name: sam_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpoint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ +#ifdef CONFIG_DEBUG + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; +#endif + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep; + struct sam_ed_s *ed; + int ret; + + DEBUGASSERT(rhport != NULL && eplist != NULL && + eplist->ed != NULL && eplist->tail != NULL); + + /* There should not be any pending, real TDs linked to this ED */ + + ed = eplist->ed; + DEBUGASSERT((ed->hw.headp & ED_HEADP_ADDR_MASK) == ed->hw.tailp); + + /* We must have exclusive access to the ED pool, the bulk list, the periodic list + * and the interrupt table. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Remove the ED to the correct list depending on the transfer type */ + + switch (ed->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + ret = sam_remctrled(eplist->ed); + break; + + case USB_EP_ATTR_XFER_BULK: + ret = sam_rembulked(eplist->ed); + break; + + case USB_EP_ATTR_XFER_INT: + ret = sam_reminted(eplist->ed); + break; + + case USB_EP_ATTR_XFER_ISOC: + ret = sam_remisoced(eplist->ed); + break; + + default: + ret = -EINVAL; + break; + } + + /* Put the ED and tail TDs back into the free list */ + + sam_edfree(eplist->ed); + sam_tdfree(eplist->tail); + + /* And free the container */ + + sem_destroy(&eplist->wdhsem); + kmm_free(eplist); + sam_givesem(&g_ohci.exclsem); + return ret; +} + +/**************************************************************************** + * Name: sam_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen) +{ + int ret = -ENOMEM; + DEBUGASSERT(drvr && buffer && maxlen); + + /* We must have exclusive access to the transfer buffer pool */ + + sam_takesem(&g_ohci.exclsem); + + *buffer = sam_tballoc(); + if (*buffer) + { + *maxlen = CONFIG_SAMA5_OHCI_TDBUFSIZE; + ret = OK; + } + + sam_givesem(&g_ohci.exclsem); + return ret; +} + +/**************************************************************************** + * Name: sam_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data + * can be accessed more efficiently. This method provides a mechanism to + * free that request/descriptor memory. If the underlying hardware does not + * support such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_free(struct usbhost_driver_s *drvr, uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* We must have exclusive access to the transfer buffer pool */ + + sam_takesem(&g_ohci.exclsem); + sam_tbfree(buffer); + sam_givesem(&g_ohci.exclsem); + return OK; +} + +/************************************************************************************ + * Name: sam_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kumm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_ioalloc(struct usbhost_driver_s *drvr, uint8_t **buffer, + size_t buflen) +{ + DEBUGASSERT(drvr && buffer); + + /* kumm_malloc() should return user accessible, DMA-able memory */ + + *buffer = kumm_malloc(buflen); + return *buffer ? OK : -ENOMEM; +} + +/************************************************************************************ + * Name: sam_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kumm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int sam_iofree(struct usbhost_driver_s *drvr, uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* kumm_free is all that is required */ + + kumm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: sam_ctrlin and sam_ctrlout + * + * Description: + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep0; + uint16_t len; + int ret; + + DEBUGASSERT(rhport != NULL && eplist != NULL && req != NULL); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(OHCI_VTRACE2_CTRLIN, RHPORT(rhport), req->req); +#else + uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %02x%02x\n", + RHPORT(rhport), req->type, req->req, req->value[1], + req->value[0], req->index[1], req->index[0], req->len[1], + req->len[0]); +#endif + + /* We must have exclusive access to EP0 and the control list */ + + sam_takesem(&g_ohci.exclsem); + + len = sam_getle16(req->len); + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_SETUP, (uint8_t *)req, + USB_SIZEOF_CTRLREQ); + if (ret == OK) + { + if (len) + { + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_IN, buffer, len); + } + + if (ret == OK) + { + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_OUT, NULL, 0); + } + } + + /* On an IN transaction, we need to invalidate the buffer contents to force + * it to be reloaded from RAM after the DMA. + */ + + sam_givesem(&g_ohci.exclsem); + arch_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + len); + return ret; +} + +static int sam_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep0; + uint16_t len; + int ret; + + DEBUGASSERT(rhport != NULL && eplist != NULL && req != NULL); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(OHCI_VTRACE2_CTRLOUT, RHPORT(rhport), req->req); +#else + uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %02x%02x\n", + RHPORT(rhport), req->type, req->req, req->value[1], + req->value[0], req->index[1], req->index[0], req->len[1], + req->len[0]); +#endif + + /* We must have exclusive access to EP0 and the control list */ + + sam_takesem(&g_ohci.exclsem); + + len = sam_getle16(req->len); + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_SETUP, (uint8_t *)req, + USB_SIZEOF_CTRLREQ); + if (ret == OK) + { + if (len) + { + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_OUT, + (uint8_t *)buffer, len); + } + + if (ret == OK) + { + ret = sam_ctrltd(rhport, eplist, GTD_STATUS_DP_IN, NULL, 0); + } + } + + sam_givesem(&g_ohci.exclsem); + return ret; +} + +/**************************************************************************** + * Name: sam_transfer_common + * + * Description: + * Initiate a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately + * + * Input Parameters: + * rhport - Internal driver root hub port state structure. + * eplist - The internal representation of the device endpoint on which + * to perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int sam_transfer_common(struct sam_rhport_s *rhport, + struct sam_eplist_s *eplist, + uint8_t *buffer, size_t buflen) +{ + struct sam_ed_s *ed; + uint32_t dirpid; + uint32_t regval; + bool in; + int ret; + + ed = eplist->ed; + in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN; + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(OHCI_VTRACE2_TRANSFER, + (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT, + (uint16_t)buflen); +#else + uvdbg("EP%d %s toggle: %d maxpacket: %d buflen: %d\n", + (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT, + in ? "IN" : "OUT", + (ed->hw.headp & ED_HEADP_C) != 0 ? 1 : 0, + (ed->hw.ctrl & ED_CONTROL_MPS_MASK) >> ED_CONTROL_MPS_SHIFT, + buflen); +#endif + + /* Get the direction of the endpoint */ + + if (in) + { + dirpid = GTD_STATUS_DP_IN; + } + else + { + dirpid = GTD_STATUS_DP_OUT; + } + + /* Then enqueue the transfer */ + + ed->tdstatus = TD_CC_NOERROR; + ret = sam_enqueuetd(rhport, eplist, ed, dirpid, GTD_STATUS_T_TOGGLE, + buffer, buflen); + if (ret == OK) + { + /* BulkListFilled. This bit is used to indicate whether there are any + * TDs on the Bulk list. + */ + + if (ed->xfrtype == USB_EP_ATTR_XFER_BULK) + { + regval = sam_getreg(SAM_USBHOST_CMDST); + regval |= OHCI_CMDST_BLF; + sam_putreg(regval, SAM_USBHOST_CMDST); + } + } + + return ret; +} +/**************************************************************************** + * Name: sam_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t sam_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep; + struct sam_ed_s *ed; + ssize_t nbytes; + bool in; + int ret; + + DEBUGASSERT(rhport && eplist && eplist->ed && eplist->tail && + buffer && buflen > 0); + + ed = eplist->ed; + in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN; + + /* We must have exclusive access to the endpoint, the TD pool, the I/O buffer + * pool, the bulk and interrupt lists, and the HCCA interrupt table. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Set the request for the Writeback Done Head event well BEFORE enabling the + * transfer. + */ + + ret = sam_wdhwait(rhport, ed, buffer, buflen); + if (ret != OK) + { + usbhost_trace1(OHCI_TRACE1_DEVDISCONN, RHPORT(rhport)); + goto errout; + } + + /* Set up the transfer */ + + ret = sam_transfer_common(rhport, eplist, buffer, buflen); + if (ret < 0) + { + udbg("ERROR: sam_transfer_common failed: %d\n", ret); + goto errout; + } + + /* Release the OHCI semaphore while we wait. Other threads need the + * opportunity to access the OHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not OHCI common) until + * the transfer is complete. But we can't use the common OHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ +#warning REVISIT + sam_givesem(&g_ohci.exclsem); + + /* Wait for the Writeback Done Head interrupt Loop to handle any false + * alarm semaphore counts. + */ + + while (eplist->wdhwait) + { + sam_takesem(&eplist->wdhsem); + } + + /* Re-acquire the OCHI semaphore. The caller expects to be holding + * this upon return. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Invalidate the D cache to force the ED to be reloaded from RAM */ + + arch_invalidate_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + /* Check the TD completion status bits */ + + if (ed->tdstatus == TD_CC_NOERROR) + { + /* On an IN transaction, we also need to invalidate the buffer + * contents to force it to be reloaded from RAM. + */ + + if (in) + { + arch_invalidate_dcache((uintptr_t)buffer, + (uintptr_t)buffer + buflen); + } + + nbytes = eplist->xfrd; + DEBUGASSERT(nbytes >= 0 && nbytes <= buflen); + + sam_givesem(&g_ohci.exclsem); + return nbytes; + } + + /* A transfer error occurred */ + + usbhost_trace2(OHCI_TRACE2_BADTDSTATUS, RHPORT(rhport), ed->tdstatus); + switch (ed->tdstatus) + { + case TD_CC_STALL: + ret = -EPERM; + break; + + case TD_CC_USER: + ret = -ESHUTDOWN; + break; + + default: + ret = -EIO; + break; + } + +errout: + /* Make sure that there is no outstanding request on this endpoint */ + + eplist->wdhwait = false; + sam_givesem(&g_ohci.exclsem); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: sam_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * rhport - Internal driver root hub port state structure. + * eplist - The internal representation of the device endpoint on which + * to perform the transfer. + * + * Returned Values: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void sam_asynch_completion(struct sam_eplist_s *eplist) +{ + struct sam_ed_s *ed; + usbhost_asynch_t callback; + void *arg; + ssize_t nbytes; + + DEBUGASSERT(eplist->ed && eplist->tail && eplist->callback != NULL && + eplist->buffer != NULL && eplist->buflen > 0); + ed = eplist->ed; + + /* Invalidate the D cache to force the ED to be reloaded from RAM */ + + arch_invalidate_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + /* Check the TD completion status bits */ + + if (ed->tdstatus == TD_CC_NOERROR) + { + /* On an IN transaction, we also need to invalidate the buffer + * contents to force it to be reloaded from RAM. + */ + + if ((ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN) + { + uintptr_t buffaddr = (uintptr_t)eplist->buffer; + arch_invalidate_dcache(buffaddr, buffaddr + eplist->buflen); + } + + nbytes = eplist->xfrd; + DEBUGASSERT(nbytes >= 0 && nbytes <= eplist->buflen); + } + else + { + /* Map the bad completion status to something that a class driver + * might understand. + */ + + usbhost_trace1(OHCI_TRACE1_BADTDSTATUS, ed->tdstatus); + + switch (ed->tdstatus) + { + case TD_CC_STALL: + nbytes = -EPERM; + break; + + case TD_CC_USER: + nbytes = -ESHUTDOWN; + break; + + default: + nbytes = -EIO; + break; + } + } + + /* Extract the callback information before freeing the buffer */ + + callback = eplist->callback; + arg = eplist->arg; + + /* Clear any pending transfer indicators */ + + eplist->wdhwait = false; + eplist->callback = NULL; + eplist->arg = NULL; + eplist->buffer = NULL; + eplist->buflen = 0; + + /* Then perform the callback */ + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: sam_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int sam_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep; + struct sam_ed_s *ed; + int ret; + + DEBUGASSERT(rhport && eplist && eplist->ed && eplist->tail && + buffer && buflen > 0 && buflen <= UINT16_MAX); + ed = eplist->ed; + + /* We must have exclusive access to the endpoint, the TD pool, the I/O buffer + * pool, the bulk and interrupt lists, and the HCCA interrupt table. + */ + + sam_takesem(&g_ohci.exclsem); + + /* Set the request for the Writeback Done Head callback well BEFORE + * enabling thetransfer. + */ + + ret = sam_wdhasynch(rhport, ed, callback, arg, buffer, buflen); + if (ret != OK) + { + usbhost_trace1(OHCI_TRACE1_DEVDISCONN, RHPORT(rhport)); + goto errout; + } + + /* Set up the transfer */ + + ret = sam_transfer_common(rhport, eplist, buffer, buflen); + if (ret < 0) + { + udbg("ERROR: sam_transfer_common failed: %d\n", ret); + goto errout; + } + + /* Then just return. The callback will be performed asynchronously + * when the transfer completes. + */ + + sam_givesem(&g_ohci.exclsem); + return OK; + +errout: + /* Make sure that there is no outstanding request on this endpoint */ + + eplist->callback = NULL; + eplist->arg = NULL; + sam_givesem(&g_ohci.exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: sam_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int sam_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct sam_eplist_s *eplist = (struct sam_eplist_s *)ep; + struct sam_ed_s *ed; + struct sam_gtd_s *td; + struct sam_gtd_s *next; + irqstate_t flags; + uintptr_t paddr; + uint32_t ctrl; + + DEBUGASSERT(eplist && eplist->ed && eplist->tail); + ed = eplist->ed; + + /* These first steps must be atomic as possible */ + + flags = enter_critical_section(); + + /* It might be possible for no transfer to be in progress (callback == NULL + * and wdhwait == false) + */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (eplist->callback || eplist->wdhwait) +#else + if (eplist->wdhwait) +#endif + { + /* Control endpoints should not come through this path and + * isochronous endpoints are not yet implemented. So we only have + * to distinguish bulk and interrupt endpoints. + */ + + if (ed->xfrtype == USB_EP_ATTR_XFER_BULK) + { + /* Disable bulk list processing while we modify the list */ + + ctrl = sam_getreg(SAM_USBHOST_CTRL); + sam_putreg(ctrl & ~OHCI_CTRL_BLE, SAM_USBHOST_CTRL); + + /* Remove the TDs attached to the ED, keeping the ED in the list */ + + paddr = ed->hw.headp & ED_HEADP_ADDR_MASK; + td = (struct sam_gtd_s *)sam_virtramaddr(paddr); + + paddr = sam_physramaddr((uintptr_t)eplist->tail); + ed->hw.headp = paddr; + + arch_clean_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + + /* Re-enable bulk list processing, if it was enabled before */ + + sam_putreg(0, SAM_USBHOST_BULKED); + sam_putreg(ctrl, SAM_USBHOST_CTRL); + } + else + { + /* Remove the TDs attached to the ED, keeping the Ed in the list */ + + paddr = ed->hw.headp & ED_HEADP_ADDR_MASK; + td = (struct sam_gtd_s *)sam_virtramaddr(paddr); + + paddr = sam_physramaddr((uintptr_t)eplist->tail); + ed->hw.headp = paddr; + + arch_clean_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct ohci_ed_s)); + } + + /* Free all transfer descriptors that were connected to the ED. In some + * race conditions with the hardware, this might be none. + */ + + while (td != (struct sam_gtd_s *)eplist->tail) + { + paddr = (uintptr_t)td->hw.nexttd; + next = (struct sam_gtd_s *)sam_virtramaddr(paddr); + sam_tdfree(td); + td = next; + } + + ed->tdstatus = TD_CC_USER; + + /* If there is a thread waiting for the transfer to complete, then + * wake up the thread. + */ + + if (eplist->wdhwait) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(eplist->callback == NULL); +#endif + + /* Wake up the waiting thread */ + + sam_givesem(&eplist->wdhsem); + eplist->wdhwait = false; + } +#ifdef CONFIG_USBHOST_ASYNCH + else + { + /* Otherwise, perform the callback */ + + sam_asynch_completion(eplist); + } +#endif + } + + /* Reset any pending activity indications */ + + eplist->wdhwait = false; +#ifdef CONFIG_USBHOST_ASYNCH + eplist->callback = NULL; + eplist->arg = NULL; +#endif + eplist->buffer = NULL; + eplist->buflen = 0; + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: sam_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int sam_connect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport, + bool connected) +{ + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + DEBUGASSERT(g_ohci.hport == NULL); /* REVISIT */ + + g_ohci.hport = hport; + if (g_ohci.pscwait) + { + g_ohci.pscwait = false; + sam_givesem(&g_ohci.pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void sam_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport) +{ + struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; + struct sam_eplist_s *ep0; + + DEBUGASSERT(rhport != NULL && hport != NULL && hport->ep0); + ep0 = (struct sam_eplist_s *)hport->ep0; + + /* Remove the disconnected port from the control list */ + + sam_ep0dequeue(ep0); + + /* Did we just dequeue EP0 from a hoot hub port? */ + + if (ROOTHUB(hport)) + { + rhport->ep0init = false; + } + + /* Unbind the class from the port */ + + hport->ep0 = NULL; + hport->devclass = NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ohci_initialize + * + * Description: + * Initialize USB OHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one OHCI interface, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +struct usbhost_connection_s *sam_ohci_initialize(int controller) +{ + struct usbhost_hubport_s *hport; + uintptr_t physaddr; + uint32_t regval; + uint8_t *buffer; + irqstate_t flags; + int i; + + /* One time sanity checks */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(sizeof(struct sam_ed_s) == SIZEOF_SAM_ED_S); + DEBUGASSERT(sizeof(struct sam_gtd_s) == SIZEOF_SAM_TD_S); + + /* Initialize the state data structure */ + + sem_init(&g_ohci.pscsem, 0, 0); + sem_init(&g_ohci.exclsem, 0, 1); + +#ifndef CONFIG_USBHOST_INT_DISABLE + g_ohci.ininterval = MAX_PERINTERVAL; + g_ohci.outinterval = MAX_PERINTERVAL; +#endif + + /* For OHCI Full-speed operations only, the user has to perform the + * following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in PMC_PCER + * register. + * 2) Select PLLACK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 3) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV value is calculated regarding the PLLACK + * value and USB Full-speed accuracy. + * 4) Enable the OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 1 and 4 are done here. 2 and 3 are already performed by + * sam_clockconfig(). + */ + + /* Enable UHP peripheral clocking */ + + flags = enter_critical_section(); + sam_uhphs_enableclk(); + + /* Enable OHCI clocks */ + + regval = getreg32(SAM_PMC_SCER); + regval |= PMC_UHP; + putreg32(regval, SAM_PMC_SCER); + + /* "One transceiver is shared with the USB High Speed Device (port A). The + * selection between Host Port A and USB Device is controlled by the UDPHS + * enable bit (EN_UDPHS) located in the UDPHS_CTRL control register." + */ + +#ifndef CONFIG_SAMA5_EHCI + /* Make all three ports usable for OHCI unless the high speed device is + * enabled; then let the device manage port zero. Zero is the reset + * value for all ports; one makes the corresponding port available to OHCI. + */ + + regval = getreg32(SAM_SFR_OHCIICR); +#ifdef CONFIG_SAMA5_UHPHS_RHPORT1 + regval |= SFR_OHCIICR_RES0; +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT2 + regval |= SFR_OHCIICR_RES1; +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT3 + regval |= SFR_OHCIICR_RES2; +#endif + putreg32(regval, SAM_SFR_OHCIICR); +#endif + + leave_critical_section(flags); + + /* Note that no pin configuration is required. All USB HS pins have + * dedicated function + */ + + usbhost_vtrace1(OHCI_VTRACE1_INITIALIZING, 0); + + /* Initialize all the HCCA to 0 */ + + memset((void *)&g_hcca, 0, sizeof(struct ohci_hcca_s)); + + arch_clean_dcache((uint32_t)&g_hcca, + (uint32_t)&g_hcca + sizeof(struct ohci_hcca_s)); + + /* Initialize user-configurable EDs */ + + for (i = 0; i < SAMA5_OHCI_NEDS; i++) + { + /* Put the ED in a free list */ + + sam_edfree(&g_edalloc[i]); + } + + /* Initialize user-configurable TDs */ + + for (i = 0; i < SAMA5_OHCI_NTDS; i++) + { + /* Put the TD in a free list */ + + sam_tdfree(&g_tdalloc[i]); + } + + /* Initialize user-configurable request/descriptor transfer buffers */ + + buffer = g_bufalloc; + for (i = 0; i < CONFIG_SAMA5_OHCI_TDBUFFERS; i++) + { + /* Put the TD buffer in a free list */ + + sam_tbfree(buffer); + buffer += CONFIG_SAMA5_OHCI_TDBUFSIZE; + } + + /* Initialize the root hub port structures */ + + for (i = 0; i < SAM_OHCI_NRHPORT; i++) + { + struct sam_rhport_s *rhport = &g_ohci.rhport[i]; + + /* Initialize the device operations */ + + rhport->drvr.ep0configure = sam_ep0configure; + rhport->drvr.epalloc = sam_epalloc; + rhport->drvr.epfree = sam_epfree; + rhport->drvr.alloc = sam_alloc; + rhport->drvr.free = sam_free; + rhport->drvr.ioalloc = sam_ioalloc; + rhport->drvr.iofree = sam_iofree; + rhport->drvr.ctrlin = sam_ctrlin; + rhport->drvr.ctrlout = sam_ctrlout; + rhport->drvr.transfer = sam_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + rhport->drvr.asynch = sam_asynch; +#endif + rhport->drvr.cancel = sam_cancel; +#ifdef CONFIG_USBHOST_HUB + rhport->drvr.connect = sam_connect; +#endif + rhport->drvr.disconnect = sam_disconnect; + + /* Initialize the public port representation */ + + hport = &rhport->hport.hport; + hport->drvr = &rhport->drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = &rhport->ep0; + hport->port = i; + hport->speed = USB_SPEED_FULL; + hport->funcaddr = 0; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&rhport->hport); + } + + /* Wait 50MS then perform hardware reset */ + + up_mdelay(50); + + sam_putreg(0, SAM_USBHOST_CTRL); /* Hardware reset */ + sam_putreg(0, SAM_USBHOST_CTRLHEADED); /* Initialize control list head to Zero */ + sam_putreg(0, SAM_USBHOST_BULKHEADED); /* Initialize bulk list head to Zero */ + + /* Software reset */ + + sam_putreg(OHCI_CMDST_HCR, SAM_USBHOST_CMDST); + + /* Write Fm interval (FI), largest data packet counter (FSMPS), and + * periodic start. + */ + + sam_putreg(DEFAULT_FMINTERVAL, SAM_USBHOST_FMINT); + sam_putreg(DEFAULT_PERSTART, SAM_USBHOST_PERSTART); + + /* Put HC in operational state */ + + regval = sam_getreg(SAM_USBHOST_CTRL); + regval &= ~OHCI_CTRL_HCFS_MASK; + regval |= OHCI_CTRL_HCFS_OPER; + sam_putreg(regval, SAM_USBHOST_CTRL); + + /* Set global power in HcRhStatus */ + + sam_putreg(OHCI_RHSTATUS_SGP, SAM_USBHOST_RHSTATUS); + + /* Set HCCA base address */ + + physaddr = sam_physramaddr((uintptr_t)&g_hcca); + sam_putreg(physaddr, SAM_USBHOST_HCCA); + + /* Clear pending interrupts */ + + regval = sam_getreg(SAM_USBHOST_INTST); + sam_putreg(regval, SAM_USBHOST_INTST); + + /* Enable OHCI interrupts */ + + sam_putreg((SAM_ALL_INTS | OHCI_INT_MIE), SAM_USBHOST_INTEN); + +#ifndef CONFIG_SAMA5_EHCI + /* Attach USB host controller interrupt handler. If ECHI is enabled, + * then it will manage the shared interrupt. + */ + + if (irq_attach(SAM_IRQ_UHPHS, sam_ohci_tophalf) != 0) + { + usbhost_trace1(OHCI_TRACE1_IRQATTACH, SAM_IRQ_UHPHS); + return NULL; + } + + /* Drive Vbus +5V (the smoke test). + * + * REVISIT: + * - Should be done elsewhere in OTG mode. + * - Can we postpone enabling VBUS to save power? I think it can be + * done in sam_enumerate() and can probably be disabled when the + * port is disconnected. + */ + +#ifdef CONFIG_SAMA5_UHPHS_RHPORT1 + sam_usbhost_vbusdrive(SAM_RHPORT1, true); +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT2 + sam_usbhost_vbusdrive(SAM_RHPORT2, true); +#endif +#ifdef CONFIG_SAMA5_UHPHS_RHPORT3 + sam_usbhost_vbusdrive(SAM_RHPORT3, true); +#endif + up_mdelay(50); + + /* If there is a USB device in the slot at power up, then we will not + * get the status change interrupt to signal us that the device is + * connected. We need to set the initial connected state accordingly. + */ + + for (i = 0; i < SAM_OHCI_NRHPORT; i++) + { + regval = sam_getreg(SAM_USBHOST_RHPORTST(i)); + g_ohci.rhport[i].connected = ((regval & OHCI_RHPORTST_CCS) != 0); + + usbhost_vtrace2(OHCI_VTRACE2_INITCONNECTED, + i+1, g_ohci.rhport[i].connected); + } + + /* Enable interrupts at the interrupt controller. If ECHI is enabled, + * then it will manage the shared interrupt. + */ + + up_enable_irq(SAM_IRQ_UHPHS); /* enable USB interrupt */ + +#endif /* CONFIG_SAMA5_EHCI */ + + usbhost_vtrace1(OHCI_VTRACE1_INITIALIZED, 0); + + /* Initialize and return the connection interface */ + + g_ohciconn.wait = sam_wait; + g_ohciconn.enumerate = sam_enumerate; + return &g_ohciconn; +} + +/**************************************************************************** + * Name: sam_ohci_tophalf + * + * Description: + * OHCI "Top Half" interrupt handler. If both EHCI and OHCI are enabled, then + * EHCI will manage the common UHPHS interrupt and will forward the interrupt + * event to this function. + * + ****************************************************************************/ + +int sam_ohci_tophalf(int irq, void *context) +{ + uint32_t intst; + uint32_t inten; + uint32_t pending; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + intst = sam_getreg(SAM_USBHOST_INTST); + inten = sam_getreg(SAM_USBHOST_INTEN); + usbhost_vtrace1(OHCI_VTRACE1_INTRPENDING, intst & inten); + +#ifdef CONFIG_SAMA5_EHCI + /* Check the Master Interrupt Enable bit (MIE). It this function is called + * from the common UHPHS interrupt handler, there might be pending interrupts + * but with the overall interstate disabled. This could never happen if only + * OHCI were enabled because we would never get here. + */ + + if ((inten & OHCI_INT_MIE) != 0) +#endif + { + /* Mask out the interrupts that are not enabled */ + pending = intst & inten; + if (pending != 0) + { + /* Schedule interrupt handling work for the high priority worker + * thread so that we are not pressed for time and so that we can + * interrupt with other USB threads gracefully. + * + * The worker should be available now because we implement a + * handshake by controlling the OHCI interrupts. + */ + + DEBUGASSERT(work_available(&g_ohci.work)); + DEBUGVERIFY(work_queue(HPWORK, &g_ohci.work, sam_ohci_bottomhalf, + (void *)pending, 0)); + + /* Disable further OHCI interrupts so that we do not overrun the + * work queue. + */ + + sam_putreg(OHCI_INT_MIE, SAM_USBHOST_INTDIS); + + /* Clear all pending status bits by writing the value of the + * pending interrupt bits back to the status register. + */ + + sam_putreg(intst, SAM_USBHOST_INTST); + } + } + + return OK; +} + +#endif /* CONFIG_SAMA5_OHCI */ diff --git a/arch/arm/src/sama5/sam_oneshot.c b/arch/arm/src/sama5/sam_oneshot.c new file mode 100644 index 0000000000000000000000000000000000000000..c86224155af4e2ae84d306b284e9db7425beb257 --- /dev/null +++ b/arch/arm/src/sama5/sam_oneshot.c @@ -0,0 +1,450 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_oneshot.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam_oneshot.h" + +#ifdef CONFIG_SAMA5_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Timer interrupt callback. When the oneshot timer interrupt expires, + * this function will be called. It will forward the call to the next + * level up. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_oneshot_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_oneshot_s *oneshot = (struct sam_oneshot_s *)arg; + oneshot_handler_t oneshot_handler; + void *oneshot_arg; + + tcllvdbg("Expired...\n"); + DEBUGASSERT(oneshot && oneshot->handler); + + /* The clock was stopped, but not disabled when the RC match occurred. + * Disable the TC now and disable any further interrupts. + */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + /* The timer is no longer running */ + + oneshot->running = false; + + /* Forward the event, clearing out any vestiges */ + + oneshot_handler = (oneshot_handler_t)oneshot->handler; + oneshot->handler = NULL; + oneshot_arg = (void *)oneshot->arg; + oneshot->arg = NULL; + + oneshot_handler(oneshot_arg); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t divisor; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(oneshot && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_divisor(frequency, &divisor, &cmr); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_divisor failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, divisor=%lu, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)divisor, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * CMR_TCCLKS - Returned by sam_tc_divisor + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=1 - Stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UPRC - TC_CV is incremented from 0 to the value of RC, + * then automatically reset on a RC Compare + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NONE | TC_CMR_CPCSTOP | TC_CMR_EEVTEDG_NONE | + TC_CMR_EEVT_TIOB | TC_CMR_WAVSEL_UPRC | TC_CMR_WAVE | + TC_CMR_ACPA_NONE | TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | + TC_CMR_ASWTRG_NONE | TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | + TC_CMR_BEEVT_NONE | TC_CMR_BSWTRG_NONE); + + oneshot->tch = sam_tc_allocate(chan, cmr); + if (!oneshot->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + oneshot->chan = chan; + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts) +{ + uint64_t usec; + uint64_t regval; + irqstate_t flags; + + tcvdbg("handler=%p arg=%p, ts=(%lu, %lu)\n", + handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + DEBUGASSERT(oneshot && handler && ts); + + /* Was the oneshot already running? */ + + flags = enter_critical_section(); + if (oneshot->running) + { + /* Yes.. then cancel it */ + + tcvdbg("Already running... cancelling\n"); + (void)sam_oneshot_cancel(oneshot, NULL); + } + + /* Save the new handler and its argument */ + + oneshot->handler = handler; + oneshot->arg = arg; + + /* Express the delay in microseconds */ + + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); + + /* Get the timer counter frequency and determine the number of counts need to achieve the requested delay. + * + * frequency = ticks / second + * ticks = seconds * frequency + * = (usecs * frequency) / USEC_PER_SEC; + */ + + regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / USEC_PER_SEC; + + tcvdbg("usec=%llu regval=%08llx\n", usec, regval); + DEBUGASSERT(regval <= UINT32_MAX); + + /* Set up to receive the callback when the interrupt occurs */ + + (void)sam_tc_attach(oneshot->tch, sam_oneshot_handler, oneshot, + TC_INT_CPCS); + + /* Set RC so that an event will be triggered when TC_CV register counts + * up to RC. + */ + + sam_tc_setregister(oneshot->tch, TC_REGC, (uint32_t)regval); + + /* Start the counter */ + + sam_tc_start(oneshot->tch); + + /* Enable interrupts. We should get the callback when the interrupt + * occurs. + */ + + oneshot->running = true; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. ts may be zero in which case the time remaining + * is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts) +{ + irqstate_t flags; + uint64_t usec; + uint64_t sec; + uint64_t nsec; + uint32_t count; + uint32_t rc; + + /* Was the timer running? */ + + flags = enter_critical_section(); + if (!oneshot->running) + { + /* No.. Just return zero timer remaining and successful cancellation. + * This function may execute at a high rate with no timer running + * (as when pre-emption is enabled and disabled). + */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + leave_critical_section(flags); + return OK; + } + + /* Yes.. Get the timer counter and rc registers and stop the counter. If + * the counter expires while we are doing this, the counter clock will be + * stopped, but the clock will not be disabled. + * + * The expected behavior is that the the counter register will freezes at + * a value equal to the RC register when the timer expires. The counter + * should have values between 0 and RC in all other cased. + * + * REVISIT: This does not appear to be the case. + */ + + tcvdbg("Cancelling...\n"); + + count = sam_tc_getcounter(oneshot->tch); + rc = sam_tc_getregister(oneshot->tch, TC_REGC); + + /* Now we can disable the interrupt and stop the timer. */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + leave_critical_section(flags); + + /* Did the caller provide us with a location to return the time + * remaining? + */ + + if (ts) + { + /* Yes.. then calculate and return the time remaining on the + * oneshot timer. + */ + + tcvdbg("rc=%lu count=%lu usec=%lu\n", + (unsigned long)rc, (unsigned long)count, (unsigned long)usec); + + /* REVISIT: I am not certain why the timer counter value sometimes + * exceeds RC. Might be a bug, or perhaps the counter does not stop + * in all cases. + */ + + if (count >= rc) + { + /* No time remaining (?) */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + else + { + /* The total time remaining is the difference. Convert the that + * to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = (((uint64_t)(rc - count)) * USEC_PER_SEC) / + sam_tc_divfreq(oneshot->tch); + + /* Return the time remaining in the correct form */ + + sec = usec / USEC_PER_SEC; + nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + ts->tv_sec = (time_t)sec; + ts->tv_nsec = (unsigned long)nsec; + } + + tcvdbg("remaining (%lu, %lu)\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + } + + return OK; +} + +#endif /* CONFIG_SAMA5_ONESHOT */ diff --git a/arch/arm/src/sama5/sam_oneshot.h b/arch/arm/src/sama5/sam_oneshot.h new file mode 100644 index 0000000000000000000000000000000000000000..4fefe9fe11ba3c55e9cd6086ddf9f88f958cf15e --- /dev/null +++ b/arch/arm/src/sama5/sam_oneshot.h @@ -0,0 +1,182 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_oneshot.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H +#define __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_tc.h" + +#ifdef CONFIG_SAMA5_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ONESHOT_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the callback function that will be invoked when the oneshot + * timer expires. The oneshot fires, the client will receive: + * + * arg - The opaque argument provided when the interrupt was registered + */ + +typedef void (*oneshot_handler_t)(void *arg); + +/* The oneshot client must allocate an instance of this structure and called + * sam_oneshot_initialize() before using the oneshot facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_oneshot_s +{ + uint8_t chan; /* The timer/counter in use */ + volatile bool running; /* True: the timer is running */ + TC_HANDLE tch; /* Handle returned by + * sam_tc_initialize() */ + volatile oneshot_handler_t handler; /* Oneshot expiration callback */ + volatile void *arg; /* The argument that will accompany + * the callback */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/sama5/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution); + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts); + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_ONESHOT */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ONESHOT_H */ diff --git a/arch/arm/src/sama5/sam_pck.c b/arch/arm/src/sama5/sam_pck.c new file mode 100644 index 0000000000000000000000000000000000000000..11202c5d5653709afcfd613443c222ea493b554a --- /dev/null +++ b/arch/arm/src/sama5/sam_pck.c @@ -0,0 +1,295 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pck.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip/sam_pinmap.h" + +#include "up_arch.h" +#include "sam_pio.h" +#include "sam_isi.h" + +#include "sam_pck.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_pck_configure + * + * Description: + * Configure a programmable clock output. The selected PCK is programmed + * to the selected frequency using either PLLA or the MCK as the source + * clock (depending on the value of the selected frequency). The clock + * is initially disabled. You must call sam_pck_enable() to enable the + * clock after it has been configured. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * clocksrc - MCK or SCK. If MCK is selected, the logic will automatically + * select the PLLACK clock if it seems like a better choice. + * frequency - Defines the desired frequency. The exact frequency may + * not be attainable. In this case, frequency is interpreted to be + * a not-to-exceed frequency. + * + * Returned Value: + * The actual frequency of the clock output. + * + ****************************************************************************/ + +uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc, + uint32_t frequency) +{ + uint32_t regval; + uint32_t clkin; + uint32_t actual; +#ifdef SAMA5_HAVE_PCK_INT_PRES + uint32_t pres; +#endif + + /* Pick a clock source. Several are possible but only MCK, PLLA, the + * MAINCK,or SCK are supported here. + */ + + switch (clksrc) + { + case PCKSRC_MCK: /* Source clock = MCK or PLLACK */ + { + /* Pick either the MCK or the PLLACK, whichever will best realize + * the target frequency. + */ + + DEBUGASSERT(BOARD_MCK_FREQUENCY < BOARD_PLLA_FREQUENCY); + + /* Pick the PLLACK if it seems like a better choice */ + + if (frequency <= BOARD_MCK_FREQUENCY || + frequency < BOARD_PLLA_FREQUENCY / 64) + { + regval = PMC_PCK_CSS_MCK; + clkin = BOARD_MCK_FREQUENCY; + } + else + { + regval = PMC_PCK_CSS_PLLA; + clkin = BOARD_PLLA_FREQUENCY; + } + } + break; + + case PCKSRC_MAINCK: /* Source clock = MAIN clock */ + regval = PMC_PCK_CSS_MAIN; + clkin = BOARD_MAINCK_FREQUENCY; + break; + + case PCKSRC_SCK: /* Source clock = SCK */ + regval = PMC_PCK_CSS_SLOW; + clkin = BOARD_SLOWCLK_FREQUENCY; + break; + + default: + dbg("ERROR: Unknown clock source\n"); + return 0; + } + +#ifdef SAMA5_HAVE_PCK_INT_PRES + /* Programmable Clock frequency is selected clock freqency divided by PRES + 1 */ + + pres = clkin / frequency; + if (pres < 1) + { + pres = 1; + } + else if (pres > 256) + { + pres = 256; + } + + regval |= PMC_PCK_PRES(pres - 1); + actual = clkin / pres; + +#else + /* The the larger smallest divisor that does not exceed the requested + * frequency. + */ + + if (frequency >= clkin) + { + regval |= PMC_PCK_PRES_DIV1; + actual = clkin; + } + else if (frequency >= (clkin >> 1)) + { + regval |= PMC_PCK_PRES_DIV2; + actual = clkin >> 1; + } + else if (frequency >= (clkin >> 2)) + { + regval |= PMC_PCK_PRES_DIV4; + actual = clkin >> 2; + } + else if (frequency >= (clkin >> 3)) + { + regval |= PMC_PCK_PRES_DIV8; + actual = clkin >> 3; + } + else if (frequency >= (clkin >> 4)) + { + regval |= PMC_PCK_PRES_DIV16; + actual = clkin >> 4; + } + else if (frequency >= (clkin >> 5)) + { + regval |= PMC_PCK_PRES_DIV32; + actual = clkin >> 5; + } + else if (frequency >= (clkin >> 6)) + { + regval |= PMC_PCK_PRES_DIV64; + actual = clkin >> 6; + } + else + { + sdbg("ERROR: frequency cannot be realized.\n"); + sdbg(" frequency=%lu clkin=%lu\n", + (unsigned long)frequency, (unsigned long)clkin); + return 0; + } +#endif + + /* Disable the programmable clock, configure the PCK output pin, then set + * the selected configuration. + */ + + switch (pckid) + { + case PCK0: + putreg32(PMC_PCK0, SAM_PMC_SCDR); +#ifdef PIO_PMC_PCK0 + (void)sam_configpio(PIO_PMC_PCK0); +#endif + putreg32(regval, SAM_PMC_PCK0); + break; + + case PCK1: + putreg32(PMC_PCK1, SAM_PMC_SCDR); +#ifdef PIO_PMC_PCK1 + (void)sam_configpio(PIO_PMC_PCK1); +#endif + putreg32(regval, SAM_PMC_PCK1); + break; + + case PCK2: + putreg32(PMC_PCK2, SAM_PMC_SCDR); +#ifdef PIO_PMC_PCK2 + (void)sam_configpio(PIO_PMC_PCK2); +#endif + putreg32(regval, SAM_PMC_PCK2); + break; + + default: + return -EINVAL; + } + + /* And return the actual frequency */ + + return actual; +} + +/**************************************************************************** + * Function: sam_pck_enable + * + * Description: + * Enable or disable a programmable clock output. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * enable - True: enable the clock output, False: disable the clock output + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_pck_enable(enum pckid_e pckid, bool enable) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Select the bit in the PMC_SDER or PMC_SCER corresponding to the + * programmable clock. + */ + + regval = PMC_PCKN(pckid); + + /* Select the SDER or SCER */ + + regaddr = enable ? SAM_PMC_SCER : SAM_PMC_SCDR; + + /* And do the deead */ + + putreg32(regval, regaddr); +} diff --git a/arch/arm/src/sama5/sam_pck.h b/arch/arm/src/sama5/sam_pck.h new file mode 100644 index 0000000000000000000000000000000000000000..0d8199e8ea86226e2249e31018a165fd5109b01c --- /dev/null +++ b/arch/arm/src/sama5/sam_pck.h @@ -0,0 +1,136 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_pck.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARPCKNG IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PCK_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PCK_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Identifies the programmable clock */ + +enum pckid_e +{ + PCK0 = 0, + PCK1, + PCK2 +}; + +enum pckid_clksrc_e +{ + PCKSRC_MCK = 0, /* Source clock is the master clock (MCK) or PLLA output (PLLACK) */ + PCKSRC_MAINCK, /* Source clock is the main clock (probably the XTAL) */ + PCKSRC_SCK /* Source clock is the slow clock (SCK) */ +}; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: sam_pck_configure + * + * Description: + * Configure a programmable clock output. The selected PCK is programmed + * to the selected frequency using either PLLA or the MCK as the source + * clock (depending on the value of the selected frequency). The clock + * is initially disabled. You must call sam_pck_enable() to enable the + * clock after it has been configured. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * clocksrc - MCK or SCK. If MCK is selected, the logic will automatically + * select the PLLACK clock if it seems like a better choice. + * frequency - Defines the desired frequency. The exact frequency may + * not be attainable. In this case, frequency is interpreted to be + * a not-to-exceed frequency. + * + * Returned Value: + * The actual frequency of the clock output. + * + ****************************************************************************/ + +uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc, + uint32_t frequency); + +/**************************************************************************** + * Function: sam_pck_enable + * + * Description: + * Enable or disable a programmable clock output. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * enable - True: enable the clock output, False: disable the clock output + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_pck_enable(enum pckid_e pckid, bool enable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PCK_H */ + diff --git a/arch/arm/src/sama5/sam_periphclks.h b/arch/arm/src/sama5/sam_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..ca46f432ee811d10f627d8c02b1607659957edc1 --- /dev/null +++ b/arch/arm/src/sama5/sam_periphclks.h @@ -0,0 +1,60 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_periphclks.h + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* chip.h holds the characteristics of the configured chip */ + +#include +#include + +/* Include the correct logic for the configured chip */ + +#if defined(ATSAMA5D2) +# include "sama5d2x_periphclks.h" +#elif defined(ATSAMA5D3) +# include "sama5d3x_periphclks.h" +#elif defined(ATSAMA5D4) +# include "sama5d4x_periphclks.h" +#else +# error Unrecognized SAMA5 family +#endif + +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PERIPHCLKS_H */ diff --git a/arch/arm/src/sama5/sam_pgalloc.c b/arch/arm/src/sama5/sam_pgalloc.c new file mode 100644 index 0000000000000000000000000000000000000000..5fbaac8a9598f9bb13ed97250f0aee15291a6495 --- /dev/null +++ b/arch/arm/src/sama5/sam_pgalloc.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pgalloc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "mmu.h" +#include "cache.h" + +#include "sam_pgalloc.h" + +#ifdef CONFIG_MM_PGALLOC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Currently, page cache memory must be allocated in DRAM. There are other + * possibilities, but the logic in this file will have to extended in order + * handle any other possibility. + */ + +#ifndef CONFIG_SAMA5_DDRCS_PGHEAP +# error CONFIG_SAMA5_DDRCS_PGHEAP must be selected +#endif + +#ifndef CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET +# error CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET must be specified +#endif + +#if (CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET & MM_PGMASK) != 0 +# warning CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET is not aligned to a page boundary +#endif + +#ifndef CONFIG_SAMA5_DDRCS_PGHEAP_SIZE +# error CONFIG_SAMA5_DDRCS_PGHEAP_SIZE must be specified +#endif + +#if (CONFIG_SAMA5_DDRCS_PGHEAP_SIZE & MM_PGMASK) != 0 +# warning CONFIG_SAMA5_DDRCS_PGHEAP_SIZE is not aligned to a page boundary +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_pgheap + * + * Description: + * If there is a page allocator in the configuration, then this function + * must be provided by the platform-specific code. The OS initialization + * logic will call this function early in the initialization sequence to + * get the page heap information needed to configure the page allocator. + * + ****************************************************************************/ + +void up_allocate_pgheap(FAR void **heap_start, size_t *heap_size) +{ + DEBUGASSERT(heap_start && heap_size); + + *heap_start = (FAR void *)((uintptr_t)SAM_DDRCS_PSECTION + + CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET); + *heap_size = CONFIG_SAMA5_DDRCS_PGHEAP_SIZE; +} + +/**************************************************************************** + * Name: sam_virtpgaddr + * + * Description: + * Check if the physical address lies in the page pool and, if so + * get the mapping to the virtual address in the user data area. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_PGPOOL_MAPPING +uintptr_t sam_virtpgaddr(uintptr_t paddr) +{ + uintptr_t poolstart; + uintptr_t poolend; + + /* REVISIT: Not implemented correctly. The reverse lookup from physical + * to virtual. This will return a kernel accessible virtual address, but + * not an address usable by the user code. + * + * The correct solutions is complex and, perhaps, will never be needed. + */ + + poolstart = ((uintptr_t)SAM_DDRCS_PSECTION + CONFIG_SAMA5_DDRCS_PGHEAP_OFFSET); + poolend = poolstart + CONFIG_SAMA5_DDRCS_PGHEAP_SIZE; + + if (paddr >= poolstart && paddr < poolend) + { + return paddr - SAM_DDRCS_PSECTION + SAM_DDRCS_VSECTION; + } + + return 0; +} +#endif /* !CONFIG_ARCH_PGPOOL_MAPPING */ + +#endif /* CONFIG_MM_PGALLOC */ diff --git a/arch/arm/src/sama5/sam_pgalloc.h b/arch/arm/src/sama5/sam_pgalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..75f4f90f1b39525cc8670a575fdd4148ceaa8a02 --- /dev/null +++ b/arch/arm/src/sama5/sam_pgalloc.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pgalloc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PGALLOC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PGALLOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "pgalloc.h" + +#ifdef CONFIG_MM_PGALLOC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_physpgaddr + * + * Description: + * Check if the virtual address lies in the user data area and, if so + * get the mapping to the physical address in the page pool. + * + ****************************************************************************/ + +#define sam_physpgaddr(vaddr) arm_physpgaddr(vaddr) + +/**************************************************************************** + * Name: sam_virtpgaddr + * + * Description: + * Check if the physical address lies in the page pool and, if so + * get the mapping to the virtual address in the user data area. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_PGPOOL_MAPPING +# define sam_virtpgaddr(vaddr) arm_virtpgaddr(vaddr) +#else +uintptr_t sam_virtpgaddr(uintptr_t paddr); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_MM_PGALLOC */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PGALLOC_H */ diff --git a/arch/arm/src/sama5/sam_pio.c b/arch/arm/src/sama5/sam_pio.c new file mode 100644 index 0000000000000000000000000000000000000000..8c4eab9d998d7fd144866bd922b342e08fe2fc18 --- /dev/null +++ b/arch/arm/src/sama5/sam_pio.c @@ -0,0 +1,53 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_pio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* chip.h holds the characteristics of the configured chip */ + +#include +#include + +/* Include the correct logic for the configured chip */ + +#if defined(ATSAMA5D2) +# include "sama5d2x_pio.c" +#elif defined(ATSAMA5D3) || defined(ATSAMA5D4) +# include "sama5d3x4x_pio.c" +#else +# error Unrecognized SAMA5 family +#endif diff --git a/arch/arm/src/sama5/sam_pio.h b/arch/arm/src/sama5/sam_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..2b867ea05a9748339b5b43e0e07a7947cc6b7b24 --- /dev/null +++ b/arch/arm/src/sama5/sam_pio.h @@ -0,0 +1,229 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_pio.h + * Parallel Input/Output (PIO) definitions for the SAMA5 + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PIO_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include + +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Definitions and types customized for each SAMA5Dx familiy */ + +#if defined(ATSAMA5D2) +# include "sama5d2x_pio.h" +#elif defined(ATSAMA5D3) || defined(ATSAMA5D4) +# include "sama5d3x4x_pio.h" +#else +# error Unrecognized SAMA5 architecture +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Lookup for non-secure PIOs */ + +extern const uintptr_t g_piobase[SAM_NPIO]; +#define sam_pion_vbase(n) (g_piobase[(n)]) + +#ifdef ATSAMA5D2 +/* Lookup for secrure PIOs */ + +extern const uintptr_t g_spiobase[SAM_NPIO]; +# define sam_spion_vbase(n) (g_spiobase[(n)]) +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_pioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for PIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_PIO_IRQ +void sam_pioirqinitialize(void); +#else +# define sam_pioirqinitialize() +#endif + +/************************************************************************************ + * Name: sam_configpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int sam_configpio(pio_pinset_t cfgset); + +/************************************************************************************ + * Name: sam_piowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ************************************************************************************/ + +void sam_piowrite(pio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: sam_pioread + * + * Description: + * Read one or zero from the selected PIO pin + * + ************************************************************************************/ + +bool sam_pioread(pio_pinset_t pinset); + +/************************************************************************************ + * Name: sam_pioirq + * + * Description: + * Configure an interrupt for the specified PIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_PIO_IRQ +void sam_pioirq(pio_pinset_t pinset); +#else +# define sam_pioirq(pinset) +#endif + +/************************************************************************************ + * Name: sam_pioirqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_PIO_IRQ +void sam_pioirqenable(int irq); +#else +# define sam_pioirqenable(irq) +#endif + +/************************************************************************************ + * Name: sam_pioirqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_PIO_IRQ +void sam_pioirqdisable(int irq); +#else +# define sam_pioirqdisable(irq) +#endif + +/************************************************************************************ + * Name: sam_pio_forceclk + * + * Description: + * Enable PIO clocking. This logic is overly conservative and does not enable PIO + * clocking unless necessary (PIO input selected, glitch/filtering enable, or PIO + * interrupts enabled). There are, however, certain conditions were we may want + * for force the PIO clock to be enabled. An example is reading the input value + * from an open drain output. + * + * The PIO automatic enable/disable logic is not smart enough enough to know about + * these cases. For those cases, sam_pio_forceclk() is provided. + * + ************************************************************************************/ + +void sam_pio_forceclk(pio_pinset_t pinset, bool enable); + +/************************************************************************************ + * Function: sam_dumppio + * + * Description: + * Dump all PIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumppio(uint32_t pinset, const char *msg); +#else +# define sam_dumppio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PIO_H */ diff --git a/arch/arm/src/sama5/sam_pioirq.c b/arch/arm/src/sama5/sam_pioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..2d9950168ed167b52abd7cb4f2f12a11fe47be46 --- /dev/null +++ b/arch/arm/src/sama5/sam_pioirq.c @@ -0,0 +1,511 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pioirq.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/sam_pio.h" +#include "chip/sam_pmc.h" + +#include "sam_pio.h" +#include "sam_periphclks.h" + +#ifdef CONFIG_SAMA5_PIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_piobase + * + * Description: + * Return the base address of the PIO register set + * + ****************************************************************************/ + +static inline uint32_t sam_piobase(pio_pinset_t pinset) +{ + int port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + return sam_pion_vbase(port >> PIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: sam_piopin + * + * Description: + * Return the base address of the PIO register set + * + ****************************************************************************/ + +static inline int sam_piopin(pio_pinset_t pinset) +{ + return 1 << ((pinset & PIO_PIN_MASK) >> PIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_irqbase + * + * Description: + * Return PIO information associated with this IRQ + * + ****************************************************************************/ + +static int sam_irqbase(int irq, uint32_t *base, int *pin) +{ + if (irq >= SAM_IRQ_NINT) + { +#ifdef CONFIG_SAMA5_PIOA_IRQ + if (irq <= SAM_IRQ_PA31) + { + *base = SAM_PIOA_VBASE; + *pin = irq - SAM_IRQ_PA0; + return OK; + } +#endif +#ifdef CONFIG_SAMA5_PIOB_IRQ + if (irq <= SAM_IRQ_PB31) + { + *base = SAM_PIOB_VBASE; + *pin = irq - SAM_IRQ_PB0; + return OK; + } +#endif +#ifdef CONFIG_SAMA5_PIOC_IRQ + if (irq <= SAM_IRQ_PC31) + { + *base = SAM_PIOC_VBASE; + *pin = irq - SAM_IRQ_PC0; + return OK; + } +#endif +#ifdef CONFIG_SAMA5_PIOD_IRQ + if (irq <= SAM_IRQ_PD31) + { + *base = SAM_PIOD_VBASE; + *pin = irq - SAM_IRQ_PD0; + return OK; + } +#endif +#ifdef CONFIG_SAMA5_PIOE_IRQ + if (irq <= SAM_IRQ_PE31) + { + *base = SAM_PIOE_VBASE; + *pin = irq - SAM_IRQ_PE0; + return OK; + } +#endif +#ifdef CONFIG_SAMA5_PIOF_IRQ + if (irq <= SAM_IRQ_PF31) + { + *base = SAM_PIOF_VBASE; + *pin = irq - SAM_IRQ_PF0; + return OK; + } +#endif + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: sam_pioa/b/c/d/e/finterrupt + * + * Description: + * Receive PIOA/B/C/D/E/F interrupts + * + ****************************************************************************/ + +static int sam_piointerrupt(uint32_t base, int irq0, void *context) +{ + uint32_t pending; + uint32_t bit; + int irq; + + pending = getreg32(base + SAM_PIO_ISR_OFFSET) & getreg32(base + SAM_PIO_IMR_OFFSET); + for (bit = 1, irq = irq0; pending != 0; bit <<= 1, irq++) + { + if ((pending & bit) != 0) + { + /* Re-deliver the IRQ (recurses! We got here from irq_dispatch!) */ + + irq_dispatch(irq, context); + + /* Remove this from the set of pending interrupts */ + + pending &= ~bit; + } + } + + return OK; +} + +#ifdef CONFIG_SAMA5_PIOA_IRQ +static int sam_pioainterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOA_VBASE, SAM_IRQ_PA0, context); +} +#endif + +#ifdef CONFIG_SAMA5_PIOB_IRQ +static int sam_piobinterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOB_VBASE, SAM_IRQ_PB0, context); +} +#endif + +#ifdef CONFIG_SAMA5_PIOC_IRQ +static int sam_piocinterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOC_VBASE, SAM_IRQ_PC0, context); +} +#endif + +#ifdef CONFIG_SAMA5_PIOD_IRQ +static int sam_piodinterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOD_VBASE, SAM_IRQ_PD0, context); +} +#endif + +#ifdef CONFIG_SAMA5_PIOE_IRQ +static int sam_pioeinterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOE_VBASE, SAM_IRQ_PE0, context); +} +#endif + +#ifdef CONFIG_SAMA5_PIOF_IRQ +static int sam_piofinterrupt(int irq, void *context) +{ + return sam_piointerrupt(SAM_PIOF_VBASE, SAM_IRQ_PF0, context); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * PIO pins. + * + ****************************************************************************/ + +void sam_pioirqinitialize(void) +{ + /* Configure PIOA interrupts */ + +#ifdef CONFIG_SAMA5_PIOA_IRQ + /* Enable PIOA clocking */ + + sam_pioa_enableclk(); + + /* Clear and disable all PIOA interrupts */ + + (void)getreg32(SAM_PIOA_ISR); + putreg32(0xffffffff, SAM_PIOA_IDR); + + /* Attach and enable the PIOA IRQ */ + + (void)irq_attach(SAM_IRQ_PIOA, sam_pioainterrupt); + up_enable_irq(SAM_IRQ_PIOA); +#endif + + /* Configure PIOB interrupts */ + +#ifdef CONFIG_SAMA5_PIOB_IRQ + /* Enable PIOB clocking */ + + sam_piob_enableclk(); + + /* Clear and disable all PIOB interrupts */ + + (void)getreg32(SAM_PIOB_ISR); + putreg32(0xffffffff, SAM_PIOB_IDR); + + /* Attach and enable the PIOB IRQ */ + + (void)irq_attach(SAM_IRQ_PIOB, sam_piobinterrupt); + up_enable_irq(SAM_IRQ_PIOB); +#endif + + /* Configure PIOC interrupts */ + +#ifdef CONFIG_SAMA5_PIOC_IRQ + /* Enable PIOC clocking */ + + sam_pioc_enableclk(); + + /* Clear and disable all PIOC interrupts */ + + (void)getreg32(SAM_PIOC_ISR); + putreg32(0xffffffff, SAM_PIOC_IDR); + + /* Attach and enable the PIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOC, sam_piocinterrupt); + up_enable_irq(SAM_IRQ_PIOC); +#endif + + /* Configure PIOD interrupts */ + +#ifdef CONFIG_SAMA5_PIOD_IRQ + /* Enable PIOD clocking */ + + sam_piod_enableclk(); + + /* Clear and disable all PIOD interrupts */ + + (void)getreg32(SAM_PIOD_ISR); + putreg32(0xffffffff, SAM_PIOD_IDR); + + /* Attach and enable the PIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOD, sam_piodinterrupt); + up_enable_irq(SAM_IRQ_PIOD); +#endif + + /* Configure PIOE interrupts */ + +#ifdef CONFIG_SAMA5_PIOE_IRQ + /* Enable PIOE clocking */ + + sam_pioe_enableclk(); + + /* Clear and disable all PIOE interrupts */ + + (void)getreg32(SAM_PIOE_ISR); + putreg32(0xffffffff, SAM_PIOE_IDR); + + /* Attach and enable the PIOE IRQ */ + + (void)irq_attach(SAM_IRQ_PIOE, sam_pioeinterrupt); + up_enable_irq(SAM_IRQ_PIOE); +#endif + + /* Configure PIOF interrupts */ + +#ifdef CONFIG_SAMA5_PIOF_IRQ + /* Enable PIOF clocking */ + + sam_piof_enableclk(); + + /* Clear and disable all PIOF interrupts */ + + (void)getreg32(SAM_PIOF_ISR); + putreg32(0xffffffff, SAM_PIOF_IDR); + + /* Attach and enable the PIOF IRQ */ + + (void)irq_attach(SAM_IRQ_PIOF, sam_piofinterrupt); + up_enable_irq(SAM_IRQ_PIOF); +#endif +} + +/************************************************************************************ + * Name: sam_pioirq + * + * Description: + * Configure an interrupt for the specified PIO pin. + * + ************************************************************************************/ + +void sam_pioirq(pio_pinset_t pinset) +{ +#if defined(SAM_PIO_ISLR_OFFSET) + uint32_t regval; +#endif + uint32_t base = sam_piobase(pinset); + int pin = sam_piopin(pinset); + +#if defined(SAM_PIO_ISLR_OFFSET) + /* Enable writing to PIO registers. The following registers are protected: + * + * - PIO Enable/Disable Registers (PER/PDR) + * - PIO Output Enable/Disable Registers (OER/ODR) + * - PIO Interrupt Security Level Register (ISLR) + * - PIO Input Filter Enable/Disable Registers (IFER/IFDR) + * - PIO Multi-driver Enable/Disable Registers (MDER/MDDR) + * - PIO Pull-Up Enable/Disable Registers (PUER/PUDR) + * - PIO Peripheral ABCD Select Register 1/2 (ABCDSR1/2) + * - PIO Output Write Enable/Disable Registers + * - PIO Pad Pull-Down Enable/Disable Registers (PPER/PPDR) + * + * I suspect that the default state is the WPMR is unprotected, so these + * operations could probably all be avoided. + */ + + putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + + /* Is the interrupt secure? */ + + regval = getreg32(base + SAM_PIO_ISLR_OFFSET); + if ((pinset & PIO_INT_SECURE) != 0) + { + /* Yes.. make sure that the corresponding bit in ISLR is cleared */ + + regval &= ~pin; + } + else + { + /* Yes.. make sure that the corresponding bit in ISLR is set */ + + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_ISLR_OFFSET); +#endif + + /* Are any additional interrupt modes selected? */ + + if ((pinset & _PIO_INT_AIM) != 0) + { + /* Yes.. Enable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMER_OFFSET); + + /* Level or edge detected interrupt? */ + + if ((pinset & _PIO_INT_LEVEL) != 0) + { + putreg32(pin, base + SAM_PIO_LSR_OFFSET); /* Level */ + } + else + { + putreg32(pin, base + SAM_PIO_ESR_OFFSET); /* Edge */ + } + + /* High level/rising edge or low level /falling edge? */ + + if ((pinset & _PIO_INT_RH) != 0) + { + putreg32(pin, base + SAM_PIO_REHLSR_OFFSET); /* High level/Rising edge */ + } + else + { + putreg32(pin, base + SAM_PIO_FELLSR_OFFSET); /* Low level/Falling edge */ + } + } + else + { + /* No.. Disable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMDR_OFFSET); + } + +#if defined(SAM_PIO_ISLR_OFFSET) + /* Disable writing to PIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); +#endif +} + +/************************************************************************************ + * Name: sam_pioirqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +void sam_pioirqenable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Clear (all) pending interrupts and enable this pin interrupt */ + + //(void)getreg32(base + SAM_PIO_ISR_OFFSET); + putreg32((1 << pin), base + SAM_PIO_IER_OFFSET); + } +} + +/************************************************************************************ + * Name: sam_pioirqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +void sam_pioirqdisable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Disable this pin interrupt */ + + putreg32((1 << pin), base + SAM_PIO_IDR_OFFSET); + } +} + +#endif /* CONFIG_SAMA5_PIO_IRQ */ diff --git a/arch/arm/src/sama5/sam_pmc.c b/arch/arm/src/sama5/sam_pmc.c new file mode 100644 index 0000000000000000000000000000000000000000..f6c6b555f6a562611f08dde5b31aec5fbd5eac3f --- /dev/null +++ b/arch/arm/src/sama5/sam_pmc.c @@ -0,0 +1,297 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pmc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" + +#include "chip.h" + +#ifdef CONFIG_ARCH_HAVE_SDIO +# include "chip/sam_hsmci.h" +#endif + +#include "chip/sam_pmc.h" +#include "sam_pmc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pllack_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled. If the PLL is is disabled, either at the input divider + * or the output multiplier, the value zero is returned. + * + ****************************************************************************/ + +uint32_t sam_pllack_frequency(uint32_t mainclk) +{ + uint32_t regval; +#ifdef SAMA5_HAVE_PLLAR_DIV + uint32_t diva; +#endif + uint32_t mula; + uint32_t pllack; + + /* Get the PLLA configuration. We will multiply (and possibly divide) + * the Main Clock to get the PLLA output clock (PLLACK). + */ + + regval = getreg32(SAM_PMC_CKGR_PLLAR); + pllack = mainclk; + +#ifdef SAMA5_HAVE_PLLAR_DIV + /* Get the PLLA divider (DIVA) + * + * DIVA = 0: Divider output is 0 + * DIVA = 1: Divider is bypassed + * DIVA = 2-255: Divider output is the selected clock divided by DIVA + */ + + diva = (regval & PMC_CKGR_PLLAR_DIV_MASK) >> PMC_CKGR_PLLAR_DIV_SHIFT; + if (diva > 1) + { + pllack /= diva; + } + else if (diva < 1) + { + return 0; + } +#endif + + /* Get the PLLA multiplier (MULA) + * + * MULA = 0: PLLA is deactivated + * MULA > 0: The PLLA Clock frequency is the PLLA input frequency + * multiplied by MULA + 1. + */ + + mula = (regval & PMC_CKGR_PLLAR_MUL_MASK) >> PMC_CKGR_PLLAR_MUL_SHIFT; + if (mula > 0) + { + pllack *= (mula + 1); + } + else + { + return 0; + } + + return pllack; +} + +/**************************************************************************** + * Name: sam_plladiv2_frequency + * + * Description: + * The PLLACK input to most clocking may or may not be divided by two. + * This function will return the possibly divided PLLACK clock input + * frequency. + * + * Assumptions: + * See sam_pllack_frequency. + * + ****************************************************************************/ + +uint32_t sam_plladiv2_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t pllack; + + /* Get the PLLA output clock */ + + pllack = sam_pllack_frequency(mainclk); + if (pllack == 0) + { + return 0; + } + + /* Check if the PLLACK output is divided by 2 */ + + regval = getreg32(SAM_PMC_MCKR); + if ((regval & PMC_MCKR_PLLADIV2) != 0) + { + pllack >>= 1; + } + + return pllack; +} + +/**************************************************************************** + * Name: sam_pck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the processor clock (PCK). + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_pck_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t pres; + uint32_t pck; + + /* Get the input source selection to the master/processor clock divider */ + + regval = getreg32(SAM_PMC_MCKR); + switch (regval & PMC_MCKR_CSS_MASK) + { + case PMC_MCKR_CSS_MAIN: /* Main Clock */ + /* Use the Main Clock frequency */ + + pck = mainclk; + break; + + case PMC_MCKR_CSS_PLLA: /* PLLA Clock */ + /* Use the PLLA output clock */ + + pck = sam_plladiv2_frequency(mainclk); + if (pck == 0) + { + return 0; + } + break; + + case PMC_MCKR_CSS_SLOW: /* Slow Clock */ + case PMC_MCKR_CSS_UPLL: /* UPLL Clock */ + default: + return 0; + } + + /* Get the PCK frequency which is given by the selected input clock + * divided by a power-of-two prescaler. + * + * PRES = 0: Selected clock + * PRES = n > 0: Selected clock divided by 2**n + */ + + pres = (regval & PMC_MCKR_PRES_MASK) >> PMC_MCKR_PRES_SHIFT; + return pck >> pres; +} + +/**************************************************************************** + * Name: sam_mck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_mck_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t mdiv; + uint32_t mck; + + /* The MCK frequency is equivalent to the PCK clock frequency with an + * additional divider. + */ + + mck = sam_pck_frequency(mainclk); + if (mck == 0) + { + return 0; + } + + /* MDIV = n: Master Clock is Prescaler Output Clock divided by encoded value */ + + regval = getreg32(SAM_PMC_MCKR); + switch (regval & PMC_MCKR_MDIV_MASK) + { + case PMC_MCKR_MDIV_PCKDIV1: + return mck; + + case PMC_MCKR_MDIV_PCKDIV2: + mdiv = 2; + break; + + case PMC_MCKR_MDIV_PCKDIV3: + mdiv = 3; + break; + + case PMC_MCKR_MDIV_PCKDIV4: + mdiv = 4; + break; + + default: + return 0; + } + + return mck / mdiv; +} diff --git a/arch/arm/src/sama5/sam_pmc.h b/arch/arm/src/sama5/sam_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..2ad35c3321ef39f4f3bff704164a945ae18b0d75 --- /dev/null +++ b/arch/arm/src/sama5/sam_pmc.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pmc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PMC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PMC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pllack_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled. If the PLL is is disabled, either at the input divider + * or the output multiplier, the value zero is returned. + * + ****************************************************************************/ + +uint32_t sam_pllack_frequency(uint32_t mainclk); + +/**************************************************************************** + * Name: sam_plladiv2_frequency + * + * Description: + * The PLLACK input to most clocking may or may not be divided by two. + * This function will return the possibly divided PLLACK clock input + * frequency. + * + * Assumptions: + * See sam_pllack_frequency. + * + ****************************************************************************/ + +uint32_t sam_plladiv2_frequency(uint32_t mainclk); + +/**************************************************************************** + * Name: sam_pck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the processor clock (PCK). + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_pck_frequency(uint32_t mainclk); + +/**************************************************************************** + * Name: sam_mck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_mck_frequency(uint32_t mainclk); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PMC_H */ diff --git a/arch/arm/src/sama5/sam_pmecc.c b/arch/arm/src/sama5/sam_pmecc.c new file mode 100644 index 0000000000000000000000000000000000000000..8dfee40e3a6286472294bc37162ac0b5ba84093d --- /dev/null +++ b/arch/arm/src/sama5/sam_pmecc.c @@ -0,0 +1,1493 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pmecc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * All of the detailed PMECC operations are taken directly from the Atmel + * NoOS sample code. The Atmel sample code has a BSD compatible license + * that requires this copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sam_pmecc.h" +#include "sam_nand.h" + +/* Compile this logic only if there is at least one CS configure for NAND + * and with PMECC support enabled. + */ + +#ifdef CONFIG_SAMA5_HAVE_PMECC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Number of bits of correction. These much match the (unshifted) values + * in the SMC_PMECCFG register BCH_ERR field. + */ + +#define BCH_ERR2 0 /* 2 bit errors */ +#define BCH_ERR4 1 /* 4 bit errors */ +#define BCH_ERR8 2 /* 8 bit errors */ +#define BCH_ERR12 3 /* 12 bit errors */ +#define BCH_ERR24 4 /* 24 bit errors */ + +/* Defines the maximum value of the error correcting capability */ + +#define PMECC_MAX_CORRECTABILITY 25 + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This is the form of the PMECC descriptor that is passed to the ECC + * detection correction algorithm in ROM. The binary for of this structure + * cannot be altered! + */ + +struct pmecc_desc_s +{ + uint32_t pagesize; /* 0-3: See HSMC_PMECCFG_PAGESIZE_* definitions */ + uint32_t sparesize; /* 4-7: The spare area size is equal to (SPARESIZE+1) bytes */ + uint32_t sectorsz; /* 8-11: See HSMC_PMECCFG_SECTORSZ_* definitions */ + uint32_t bcherr; /* 12-15: See HSMC_PMECCFG_BCHERR_* definitions */ + uint32_t eccsize; /* 16-19: Real size in bytes of ECC in spare */ + uint32_t eccstart; /* 20-23: The first byte address of the ECC area */ + uint32_t eccend; /* 24-27: The last byte address of the ECC area */ + uint32_t nandwr; /* 28-31: NAND Write Access */ + uint32_t sparena; /* 32-35: Spare Enable */ + uint32_t automode; /* 36-39: Automatic Mode */ + uint32_t clkctrl; /* 40-43: PMECC Module data path Setup Time is CLKCTRL+1. */ + uint32_t interrupt; /* 44-47: */ + int32_t tt; /* 48-51: Error correcting capability */ + int32_t mm; /* 52-55: Degree of the remainders, GF(2**mm) */ + int32_t nn; /* 56-59: Length of codeword = nn=2**mm -1 */ + int16_t *alphato; /* 60-63: Gallois field table */ + int16_t *indexof; /* 64-67: Index of Gallois field table */ + int16_t partsyn[100]; /* 68-267: */ + int16_t si[100]; /* 268-467: Current syndrome value */ + + /* 468-: Sigma table */ + + int16_t smu[PMECC_MAX_CORRECTABILITY + 2][2 * PMECC_MAX_CORRECTABILITY + 1]; + + /* Polynomial order */ + + int16_t lmu[PMECC_MAX_CORRECTABILITY + 1]; +}; + +/* PMECC state data */ + +struct sam_pmecc_s +{ + bool configured; /* True: Configured for some HSMC NAND bank */ +#if NAND_NPMECC_BANKS > 1 + sem_t exclem; /* For mutually exclusive access to the PMECC */ + uint8_t cs; /* Currently configured for this bank */ +#endif + bool sector1k; /* True: 1024B sector size; False: 512B sector size */ + uint8_t nsectors; /* Number of sectors per page */ + uint8_t correctability; /* Number of correctable bits per sector */ + struct pmecc_desc_s desc; /* Atmel PMECC descriptor */ +}; + +/* This is the type of the ROM detection/correction function + * + * REVISIT: Whare are the types Pmecc and Pmerrloc? + */ + +#ifdef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +typedef uint32_t (*pmecc_correctionalgo_t)(Pmecc *, Pmerrloc *, + struct pmecc_desc_s *desc, + uint32_t isr, uintptr_t data); +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +# define pmecc_correctionalgo \ + ((pmecc_correctionalgo_t)CONFIG_SAMA5_PMECC_EMBEDDEDALGO_ADDR) +#else +static uint32_t pmecc_correctionalgo(uint32_t isr, uintptr_t data); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* PMECC state data */ + +static struct sam_pmecc_s g_pmecc; + +/* Maps BCH_ERR correctability register value to number of errors per sector */ + +static const uint8_t g_correctability[5] = {2, 4, 8, 12, 24}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pmecc_gensyn + * + * Description: + * Build the pseudo syndromes table + * + * Input Parameters: + * sector - Targetted sector. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static void pmecc_gensyn(uint32_t sector) +{ + int16_t *remainder; + int i; + + remainder = (int16_t *)SAM_HSMC_REM_BASE(sector); + + for (i = 0; i < (uint32_t)g_pmecc.desc.tt; i++) + { + /* Fill odd syndromes */ + + g_pmecc.desc.partsyn[1 + (2 * i)] = remainder[i]; + } +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_substitute + * + * Description: + * The pmecc_substitute function evaluates the polynomial remainder, with + * different values of the field primitive elements. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (always) + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static uint32_t pmecc_substitute(void) +{ + int16_t *si = g_pmecc.desc.si; + int16_t *partsyn = g_pmecc.desc.partsyn; + int16_t *alphato = g_pmecc.desc.alphato; + int16_t *indexof = g_pmecc.desc.indexof; + int i; + int j; + + /* si[] is a table that holds the current syndrome value, an element of + * that table belongs to the field. + */ + + for (i = 1; i < 2 * PMECC_MAX_CORRECTABILITY; i++) + { + si[i] = 0; + } + + /* Computation 2t syndromes based on S(x) */ + /* Odd syndromes */ + + for (i = 1; i <= 2 * g_pmecc.desc.tt - 1; i = i + 2) + { + si[i] = 0; + for (j = 0; j < g_pmecc.desc.mm; j++) + { + if (partsyn[i] & ((uint16_t)0x1 << j)) + { + si[i] = alphato[(i * j)] ^ si[i]; + } + } + } + + /* Even syndrome = (Odd syndrome) ** 2 */ + + for (i = 2; i <= 2 * g_pmecc.desc.tt; i = i + 2) + { + j = i / 2; + if (si[j] == 0) + { + si[i] = 0; + } + else + { + si[i] = alphato[(2 * indexof[si[j]]) % g_pmecc.desc.nn]; + } + } + + return 0; +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_getsigma + * + * Description: + * The substitute function finding the value of the error location + * polynomial. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (always) + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static uint32_t pmecc_getsigma(void) +{ + uint32_t dmu0count; + int16_t *lmu = g_pmecc.desc.lmu; + int16_t *si = g_pmecc.desc.si; + int16_t tt = g_pmecc.desc.tt; + int32_t mu[PMECC_MAX_CORRECTABILITY+1]; /* Mu */ + int32_t dmu[PMECC_MAX_CORRECTABILITY+1]; /* Discrepancy */ + int32_t delta[PMECC_MAX_CORRECTABILITY+1]; /* Delta order */ + int32_t largest; + int32_t diff; + int ro; /* Index of largest delta */ + int i; + int j; + int k; + + dmu0count = 0; + + /* First Row */ + /* Mu */ + + mu[0] = -1; /* Actually -1/2 */ + + /* Sigma(x) set to 1 */ + + for (i = 0; i < (2 * PMECC_MAX_CORRECTABILITY + 1); i++) + { + g_pmecc.desc.smu[0][i] = 0; + } + + g_pmecc.desc.smu[0][0] = 1; + + /* Discrepancy set to 1 */ + + dmu[0] = 1; + + /* Polynom order set to 0 */ + + lmu[0] = 0; + + /* delta set to -1 */ + + delta[0] = (mu[0] * 2 - lmu[0]) >> 1; + + /* Second row */ + /* Mu */ + + mu[1] = 0; + + /* Sigma(x) set to 1 */ + + for (i = 0; i < (2 * PMECC_MAX_CORRECTABILITY + 1); i++) + { + g_pmecc.desc.smu[1][i] = 0; + } + + g_pmecc.desc.smu[1][0] = 1; + + /* Discrepancy set to S1 */ + + dmu[1] = si[1]; + + /* Polynom order set to 0 */ + + lmu[1] = 0; + + /* Delta set to 0 */ + + delta[1] = (mu[1] * 2 - lmu[1]) >> 1; + + /* Initialize the Sigma(x) last row */ + + for (i = 0; i < (2 * PMECC_MAX_CORRECTABILITY + 1); i++) + { + g_pmecc.desc.smu[tt + 1][i] = 0; + } + + for (i = 1; i <= tt; i++) + { + mu[i+1] = i << 1; + + /* Compute Sigma (Mu+1) and L(mu). */ + /* check if discrepancy is set to 0 */ + + if (dmu[i] == 0) + { + dmu0count++; + if ((tt - (lmu[i] >> 1) - 1) & 0x1) + { + if (dmu0count == (uint32_t)((tt - (lmu[i] >> 1) - 1) / 2) + 2) + { + for (j = 0; j <= (lmu[i] >> 1) + 1; j++) + { + g_pmecc.desc.smu[tt+1][j] = g_pmecc.desc.smu[i][j]; + } + lmu[tt + 1] = lmu[i]; + return 0; + } + } + else + { + if (dmu0count == (uint32_t)((tt - (lmu[i] >> 1) - 1) / 2) + 1) + { + for (j = 0; j <= (lmu[i] >> 1) + 1; j++) + { + g_pmecc.desc.smu[tt + 1][j] = g_pmecc.desc.smu[i][j]; + } + lmu[tt + 1] = lmu[i]; + return 0; + } + } + + /* Copy polynom */ + + for (j = 0; j <= lmu[i] >> 1; j++) + { + g_pmecc.desc.smu[i + 1][j] = g_pmecc.desc.smu[i][j]; + } + + /* Copy previous polynom order to the next */ + + lmu[i + 1] = lmu[i]; + } + else + { + ro = 0; + largest = -1; + + /* find largest delta with dmu != 0 */ + + for (j = 0; j < i; j++) + { + if (dmu[j]) + { + if (delta[j] > largest) + { + largest = delta[j]; + ro = j; + } + } + } + + /* Compute difference */ + + diff = (mu[i] - mu[ro]); + + /* Compute degree of the new smu polynomial */ + + if ((lmu[i] >> 1) > ((lmu[ro] >> 1) + diff)) + { + lmu[i + 1] = lmu[i]; + } + else + { + lmu[i + 1] = ((lmu[ro] >> 1) + diff) * 2; + } + + /* Init smu[i+1] with 0 */ + + for (k = 0; k < (2 * PMECC_MAX_CORRECTABILITY+1); k ++) + { + g_pmecc.desc.smu[i+1][k] = 0; + } + + /* Compute smu[i+1] */ + + for (k = 0; k <= lmu[ro] >> 1; k++) + { + if (g_pmecc.desc.smu[ro][k] && dmu[i]) + { + g_pmecc.desc.smu[i + 1][k + diff] = + g_pmecc.desc.alphato[(g_pmecc.desc.indexof[dmu[i]] + + (g_pmecc.desc.nn - g_pmecc.desc.indexof[dmu[ro]]) + + g_pmecc.desc.indexof[g_pmecc.desc.smu[ro][k]]) % g_pmecc.desc.nn]; + } + } + + for (k = 0; k <= lmu[i] >> 1; k++) + { + g_pmecc.desc.smu[i+1][k] ^= g_pmecc.desc.smu[i][k]; + } + } + + /* End Compute Sigma (Mu+1) and L(mu) */ + /* In either case compute delta */ + + delta[i + 1] = (mu[i + 1] * 2 - lmu[i + 1]) >> 1; + + /* Do not compute discrepancy for the last iteration */ + + if (i < tt) + { + for (k = 0 ; k <= (lmu[i + 1] >> 1); k++) + { + if (k == 0) + { + dmu[i + 1] = si[2 * (i - 1) + 3]; + } + + /* Check if one operand of the multiplier is null, its index is -1 */ + + else if (g_pmecc.desc.smu[i + 1][k] && si[2 * (i - 1) + 3 - k]) + { + dmu[i + 1] = + g_pmecc.desc.alphato[(g_pmecc.desc.indexof[g_pmecc.desc.smu[i + 1][k]] + + g_pmecc.desc.indexof[si[2 * (i - 1) + 3 - k]]) % g_pmecc.desc.nn] ^ dmu[i + 1]; + } + } + } + } + + return 0; +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_errorlocation + * + * Description: + * Initialize the PMECC Error Location peripheral and start the error + * location processing + * + * Input Parameters: + * bitsize - Size of the sector in bits. + * + * Returned Value: + * Number of errors (or -1 on an error) + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static int32_t pmecc_errorlocation(uint32_t bitsize) +{ + uint32_t *sigma; + uint32_t errornumber; + uint32_t nroots; + uint32_t regval; + uint32_t alphax; + + /* Disable PMECC Error Location IP */ + + nand_putreg(SAM_HSMC_ELDIS, 0xffffffff); + + errornumber = 0; + alphax = 0; + + sigma = (uint32_t *)SAM_HSMC_SIGMA0; + for (alphax = 0; + alphax <= (uint32_t)(g_pmecc.desc.lmu[g_pmecc.desc.tt + 1] >> 1); + alphax++) + { + *sigma++ = g_pmecc.desc.smu[g_pmecc.desc.tt + 1][alphax]; + errornumber++; + } + + regval = nand_getreg(SAM_HSMC_ELCFG); + regval |= HSMC_ELCFG_ERRNUM(errornumber - 1); + nand_putreg(SAM_HSMC_ELCFG, regval); + + /* Enable error location process */ + + nand_putreg(SAM_HSMC_ELEN, bitsize); + while ((nand_getreg(SAM_HSMC_ELISR) & HSMC_ELIINT_DONE) == 0); + + nroots = (nand_getreg(SAM_HSMC_ELISR) & HSMC_ELISR_ERRCNT_MASK) >> + HSMC_ELISR_ERRCNT_SHIFT; + + /* Number of roots == degree of smu hence <= tt */ + + if (nroots == (uint32_t)(g_pmecc.desc.lmu[g_pmecc.desc.tt + 1] >> 1)) + { + return (errornumber - 1); + } + + /* Number of roots not match the degree of smu ==> unable to correct + * error + */ + + return -1; +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_errorcorrection + * + * Description: + * Correct errors indicated in the PMECCEL error location registers. + * + * Input Parameters: + * sectorbase - Base address of the sector. + * extrabytes - Number of extra bytes of the sector (encoded spare area, + * only for the last sector) + * nerrors Number of error to correct + * + * Returned Value: + * Number of errors + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static uint32_t pmecc_errorcorrection(uintptr_t sectorbase, + uint32_t extrabytes, uint32_t nerrors) +{ + uint32_t *errpos; + uint32_t bytepos; + uint32_t bitpos; + uint32_t sectorsz; + uint32_t eccsize; + uint32_t eccend; + + errpos = (uint32_t *)SAM_HSMC_ERRLOC_BASE(0); + + if ((nand_getreg(SAM_HSMC_PMECCFG) & HSMC_PMECCFG_SECTORSZ_MASK) == + HSMC_PMECCFG_SECTORSZ_512) + { + sectorsz = 512; + } + else + { + sectorsz = 1024; + } + + /* Get number of ECC bytes */ + + eccend = nand_getreg(SAM_HSMC_PMECCEADDR); + eccsize = (eccend - nand_getreg(SAM_HSMC_PMECCSADDR)) + 1; + + while (nerrors) + { + bytepos = (*errpos - 1) / 8; + bitpos = (*errpos - 1) % 8; + + /* If error is located in the data area (not in ECC) */ + + if (bytepos < (sectorsz + extrabytes)) + { + /* If the error position is before ECC area */ + + if (bytepos < sectorsz + nand_getreg(SAM_HSMC_PMECCSADDR)) + { + fdbg("Correct error bit @[Byte %d, Bit %d]\n", + (int)bytepos, (int)bitpos); + + if (*(uint8_t *)(sectorbase + bytepos) & (1 << bitpos)) + { + *(uint8_t *)(sectorbase + bytepos) &= (0xff ^ (1 << bitpos)); + } + else + { + *(uint8_t *)(sectorbase + bytepos) |= (1 << bitpos); + } + } + else + { + if (*(uint8_t *)(sectorbase + bytepos + eccsize) & (1 << bitpos)) + { + *(uint8_t *)(sectorbase + bytepos + eccsize) &= (0xff ^ (1 << bitpos)); + } + else + { + *(uint8_t *)(sectorbase + bytepos + eccsize) |= (1 << bitpos); + } + } + } + + errpos++; + nerrors--; + } + + return 0; +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_correctionalgo + * + * Description: + * Launch error detection functions and correct corrupted bits. + * + * Input Parameters: + * isr - Value of the PMECC status register. + * data - Base address of the buffer containing the page to be corrected. + * + * Returned Value: + * 0 if all errors have been corrected, 1 if too many errors detected + * + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO +static uint32_t pmecc_correctionalgo(uint32_t isr, uintptr_t data) +{ + uintptr_t sectorbase; + uint32_t sector = 0; + uint32_t sectorsz; + int32_t nerrors; + unsigned int mm; + + /* Set the sector size (512 or 1024 bytes) */ + + if ((g_pmecc.desc.sectorsz & HSMC_PMECCFG_SECTORSZ_MASK) != 0) + { + sectorsz = 1024; + mm = 14; + nand_putreg(SAM_HSMC_ELCFG, HSMC_ELCFG_SECTORSZ_1024); + } + else + { + sectorsz = 512; + mm = 13; + nand_putreg(SAM_HSMC_ELCFG, HSMC_ELCFG_SECTORSZ_512); + } + +#define HSMC_PAGESIZE \ + (1 << ((nand_getreg(SAM_HSMC_PMECCFG) & HSMC_PMECCFG_PAGESIZE_MASK) >> \ + HSMC_PMECCFG_PAGESIZE_SHIFT)) + + while (sector < (uint32_t)HSMC_PAGESIZE && isr != 0) + { + nerrors = 0; + if ((isr & 1) != 0) + { + sectorbase = data + (sector * sectorsz); + + pmecc_gensyn(sector); + pmecc_substitute(); + pmecc_getsigma(); + + /* Number of bits of the sector + ecc */ + + nerrors = pmecc_errorlocation((sectorsz * 8) + (g_pmecc.desc.tt * mm)); + if (nerrors == -1) + { + return 1; + } + else + { + /* Extra byte is 0 */ + + pmecc_errorcorrection(sectorbase, 0, nerrors); + } + } + + sector++; + isr = isr >> 1; + } + + return 0; +} +#endif /* CONFIG_SAMA5_PMECC_EMBEDDEDALGO */ + +/**************************************************************************** + * Name: pmecc_bcherr512 + * + * Description: + * Get the correctabity that could be achieved using a 512 byte sector + * + ****************************************************************************/ + +static int pmecc_bcherr512(uint8_t nsectors, uint16_t eccsize) +{ + /* 39-bytes per 512 byte sector are required correctability of 24 errors */ + + if (eccsize >= 39 * ((unsigned int)nsectors)) + { + return BCH_ERR24; + } + + /* 20-bytes per 512 byte sector are required correctability of 12 errors */ + + else if (eccsize >= (20 * (unsigned int)nsectors)) + { + return BCH_ERR12; + } + + /* 13-bytes per 512 byte sector are required correctability of 8 errors */ + + else if (eccsize >= (13 * (unsigned int)nsectors)) + { + return BCH_ERR8; + } + + /* 7-bytes per 512 byte sector are required correctability of 4 errors */ + + else if (eccsize >= (7 * (unsigned int) nsectors)) + { + return BCH_ERR4; + } + + /* 4-bytes per 512 byte sector are required correctability of 2 errors */ + + else if (eccsize >= (4 * (unsigned int) nsectors)) + { + return BCH_ERR2; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pmecc_bcherr512 + * + * Description: + * Get the correctabity that could be achieved using a 512 byte sector + * + ****************************************************************************/ + +static int pmecc_bcherr1k(uint8_t nsectors, uint16_t eccsize) +{ + /* 42-bytes per 1024 byte sector are required correctability of 24 errors */ + + if (eccsize >= 42 * ((unsigned int)nsectors)) + { + return BCH_ERR24; + } + + /* 21-bytes per 1024 byte sector are required correctability of 12 errors */ + + else if (eccsize >= (21 * (unsigned int)nsectors)) + { + return BCH_ERR12; + } + + /* 14-bytes per 1024 byte sector are required correctability of 8 errors */ + + else if (eccsize >= (14 * (unsigned int)nsectors)) + { + return BCH_ERR8; + } + + /* 7-bytes per 1024 byte sector are required correctability of 4 errors */ + + else if (eccsize >= (7 * (unsigned int) nsectors)) + { + return BCH_ERR4; + } + + /* 4-bytes per 1024 byte sector are required correctability of 2 errors */ + + else if (eccsize >= (4 * (unsigned int) nsectors)) + { + return BCH_ERR2; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pmecc_pagelayout + * + * Description: + * Given the size of the data region and the size of the ECC region, + * determine the optimal sector size and correctability. + * + ****************************************************************************/ + +static int pmecc_pagelayout(uint16_t datasize, uint16_t eccsize) +{ + uint16_t correctability512; + uint16_t correctability1K; + uint8_t nsectors512; + uint8_t nsectors1k; + uint8_t bcherr; + int bcherr512; + int bcherr1k; + int selector; + + fvdbg("datasize=%d eccsize=%d\n", datasize, eccsize); + DEBUGASSERT(datasize > 0 && eccsize > 0); + + /* Try for 512 byte sectors */ + + DEBUGASSERT((datasize & 0x000001ff) == 0 && datasize >= 512); + + selector = 0; + nsectors512 = (datasize >> 9); + bcherr512 = pmecc_bcherr512(nsectors512, eccsize); + if (bcherr512 < 0) + { + fdbg("WARNING: Cannot realize 512B sectors\n"); + } + else + { + selector = 1; + } + + fvdbg("nsectors512=%d bcherr512=%d selector=%d\n", + nsectors512, bcherr512, selector); + + /* Try for 1024 byte sectors */ + + if ((datasize & 0x000003ff) == 0) + { + nsectors1k = (datasize >> 10); + bcherr1k = pmecc_bcherr1k(nsectors1k, eccsize); + } + else + { + nsectors1k = 0; + bcherr1k = -EINVAL; + } + + if (bcherr1k < 0) + { + fdbg("WARNING: Cannot realize 1KB sectors\n"); + } + else + { + selector |= 2; + } + + fvdbg("nsectors1k=%d bcherr1k=%d selector=%d\n", + nsectors1k, bcherr1k, selector); + + /* Now pick the best (most likely 1024) */ + + DEBUGASSERT(bcherr512 >= 0 || bcherr1k >= 0); + switch (selector) + { + case 1: /* 512B sectors possible; 1KB sectors not possible */ + { + g_pmecc.sector1k = false; + g_pmecc.nsectors = nsectors512; + bcherr = bcherr512; + DEBUGASSERT(bcherr512 >= 0); + } + break; + + case 3: /* Both 512B and 1KB sectors possible */ + { + correctability512 = nsectors512 * g_correctability[bcherr512]; + correctability1K = nsectors1k * g_correctability[bcherr1k]; + + /* Use 512B sectors unless we can do better with 1K sectors */ + + if (correctability512 >= correctability1K) + { + g_pmecc.sector1k = false; + g_pmecc.nsectors = nsectors512; + bcherr = bcherr512; + DEBUGASSERT(bcherr512 >= 0); + break; + } + } + + /* Otherwise, fall through for the 1KB sectors */ + + case 2: /* 512B sectors not possible; 1KB sectors possible */ + { + g_pmecc.sector1k = true; + g_pmecc.nsectors = nsectors1k; + bcherr = bcherr1k; + DEBUGASSERT(bcherr1k >= 0); + } + break; + + case 0: /* Either 512B and 1KB sectors possible */ + default: + return -ENOSYS; + } + + /* Save the correctability value */ + + g_pmecc.correctability = g_correctability[bcherr]; + + /* And the correctly shifted BCH_ERR register value */ + + g_pmecc.desc.bcherr = ((uint32_t)bcherr << HSMC_PMECCFG_BCHERR_SHIFT); + + fvdbg("sector1k=%d nsectors=%d bcherr=%d correctability=%d\n", + g_pmecc.sector1k, g_pmecc.nsectors, bcherr, g_pmecc.correctability); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pmecc_initialize + * + * Description: + * Perform one-time PMECC initialization. This must be called before any + * other PMECC interfaces are used. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_initialize(void) +{ + sem_init(&g_pmecc.exclsem, 0, 1); +} +#endif + +/**************************************************************************** + * Name: pmecc_configure + * + * Description: + * Configure and Initialize the PMECC peripheral for this CS. + * + * Input Parameters: + * priv - Pointer to a struct sam_nandcs_s instance. + * protected - True: The spare area is protected with the last sector of + * data. + * False: The spare area is skipped in read or write mode. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pmecc_configure(struct sam_nandcs_s *priv, bool protected) +{ + struct nand_model_s *model; + unsigned int sectorsperpage = 0; + uint16_t eccoffset; + uint16_t eccsize; + uint32_t regval; + int ret; + + fvdbg("protected=%d configured=%d\n", protected, g_pmecc.configured); + + /* Check if we need to re-configure */ + +#if NAND_NPMECC_BANKS > 1 + if (g_pmecc.configured && g_pmecc.cs == priv->cs) +#else + if (g_pmecc.configured) +#endif + { + /* No, we are already configured */ + + fvdbg("Already configured\n"); + return OK; + } + + /* Get a convenience pointer to the NAND model */ + + model = &priv->raw.model; + + /* Get the offset and size of the ECC information in the spare area from + * the NAND scheme. + */ + + DEBUGASSERT(model->scheme); + eccoffset = nandscheme_eccoffset(model->scheme); + eccsize = nandscheme_eccsize(model->scheme); + + /* Get the number of sectors and the error correction per sector. This + * function will set the following structure values in order to get the + * best overall correctability: + * + * g_pmecc.sector1k : True if we are using 1024B sectors + * g_pmecc.nsectors : The number of sectors per page + * g_pmecc.correctability : Number of correctable bits per sector + * g_pmecc.desc.bcherr : The BCH_ERR value for the PMECC CFG register + */ + + ret = pmecc_pagelayout(priv->raw.model.pagesize, eccsize); + if (ret < 0) + { + fdbg("ERROR: pmecc_pagelayout failed: %d\n", ret); + return ret; + } + + /* Number of Sectors in one Page */ + + if (g_pmecc.sector1k) + { + /* 1024 bytes per sector */ + + g_pmecc.desc.sectorsz = HSMC_PMECCFG_SECTORSZ_1024; + sectorsperpage = (priv->raw.model.pagesize >> 10); + g_pmecc.desc.mm = 14; +#if defined (CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR) && defined (CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES) + g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_SIZEOF_1024]); + g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[0]); +#else + g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_ALPHA_TO]); + g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[PMECC_GF_INDEX_OF]); +#endif + } + else + { + /* 512 bytes per sector */ + + g_pmecc.desc.sectorsz = HSMC_PMECCFG_SECTORSZ_512; + sectorsperpage = (priv->raw.model.pagesize >> 9); + g_pmecc.desc.mm = 13; +#if defined (CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR) && defined (CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES) + g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_SIZEOF_512]); + g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[0]); +#else + g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_ALPHA_TO]); + g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[PMECC_GF_INDEX_OF]); +#endif + } + + fvdbg("sectorsz=%08x sectorsperpage=%d mm=%d\n", + g_pmecc.desc.sectorsz, sectorsperpage, g_pmecc.desc.mm); + + switch (sectorsperpage) + { + case 1: + g_pmecc.desc.pagesize = HSMC_PMECCFG_PAGESIZE_1SEC; + break; + case 2: + g_pmecc.desc.pagesize = HSMC_PMECCFG_PAGESIZE_2SEC; + break; + case 4: + g_pmecc.desc.pagesize = HSMC_PMECCFG_PAGESIZE_4SEC; + break; + case 8: + g_pmecc.desc.pagesize = HSMC_PMECCFG_PAGESIZE_8SEC; + break; + default: + fdbg("ERROR: Unsupported sectors per page: %d\n", sectorsperpage); + return -EINVAL; + } + + g_pmecc.desc.nn = (1 << g_pmecc.desc.mm) - 1; + + fvdbg("pagesize=%08x nn=%d\n", g_pmecc.desc.pagesize, g_pmecc.desc.nn); + + /* Real value of ECC bit number correction (2, 4, 8, 12, 24) */ + + g_pmecc.desc.tt = g_pmecc.correctability; + if (((g_pmecc.desc.mm * g_pmecc.correctability) & 7) == 0) + { + g_pmecc.desc.eccsize = + ((g_pmecc.desc.mm * g_pmecc.correctability) >> 3) * sectorsperpage; + } + else + { + g_pmecc.desc.eccsize = + (((g_pmecc.desc.mm * g_pmecc.correctability) >> 3) + 1) * sectorsperpage; + } + + fvdbg("mm=%d correctability=%d eccsize=%d\n", + g_pmecc.desc.mm, g_pmecc.correctability, g_pmecc.desc.eccsize); + + g_pmecc.desc.eccstart = eccoffset; + g_pmecc.desc.eccend = eccoffset + g_pmecc.desc.eccsize; + + fvdbg("eccstart=%d eccend=%d sparesize=%d\n", + g_pmecc.desc.eccstart, g_pmecc.desc.eccend, + priv->raw.model.sparesize); + + if (g_pmecc.desc.eccend > priv->raw.model.sparesize) + { + fdbg("ERROR: No room for ECC in spare bytes %d > %d\n", + g_pmecc.desc.eccend, priv->raw.model.sparesize); + + return -ENOSPC; + } + + /* Save the size of the spare area. + * + * REVISIT: Could we save a bit by setting this to eccend since there is + * no need to read beyond that? + */ + + g_pmecc.desc.sparesize = priv->raw.model.sparesize; + + //g_pmecc.desc.nandwr = PMECC_CFG_NANDWR; /* NAND write access */ + g_pmecc.desc.nandwr = 0; /* NAND Read access */ + if (protected) + { + g_pmecc.desc.sparena = HSMC_PMECCFG_SPARE_ENABLE; + } + else + { + g_pmecc.desc.sparena = 0; + } + + /* PMECC_CFG_AUTO indicates that the spare is error protected. In this + * case, the ECC computation takes into account the whole spare area + * minus the ECC area in the ECC computation operation + * + * NOTE: At 133 Mhz, the clkctrl field must be programmed with 2, + * indicating that the setup time is 3 clock cycles. + */ + + g_pmecc.desc.automode = 0; + g_pmecc.desc.clkctrl = 2; + g_pmecc.desc.interrupt = 0; + + /* Disable ECC module */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE); + + /* Reset the ECC module */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST); + + regval = g_pmecc.desc.bcherr | g_pmecc.desc.sectorsz | + g_pmecc.desc.pagesize | g_pmecc.desc.nandwr | + g_pmecc.desc.sparena | g_pmecc.desc.automode; + nand_putreg(SAM_HSMC_PMECCFG, regval); + + nand_putreg(SAM_HSMC_PMECCSAREA, g_pmecc.desc.sparesize - 1); + nand_putreg(SAM_HSMC_PMECCSADDR, g_pmecc.desc.eccstart); + nand_putreg(SAM_HSMC_PMECCEADDR, g_pmecc.desc.eccend - 1); + + /* Disable all interrupts */ + + nand_putreg(SAM_HSMC_PMECCIDR, 0xff); + + /* Enable ECC module */ + + nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_ENABLE); + + /* Now we are configured */ + + g_pmecc.configured = true; +#if NAND_NPMECC_BANKS > 1 + g_pmecc.cs = priv->cs; +#endif + return OK; +} + +/**************************************************************************** + * Name: pmecc_lock + * + * Description: + * Get exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_lock(void) +{ + int ret; + + do + { + ret = sem_wait(&g_pmecc.exclsem); + DEBUGASSERT(ret == OK || errno == EINTR); + } + while (ret != OK); +} +#endif + +/**************************************************************************** + * Name: pmecc_unlock + * + * Description: + * Relinquish exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_unlock(void) +{ + sem_post(&g_pmecc.exclsem); +} +#endif + +/**************************************************************************** + * Name: pmecc_correction + * + * Description: + * Perform the PMECC correction algorithm + * + * Input Parameters: + * isr - Value of the PMECC ISR register + * data - Data to be corrected + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * PMECC has been initialized for the CS and the caller holds the PMECC + * lock. + * + ****************************************************************************/ + +int pmecc_correction(uint32_t isr, uintptr_t data) +{ +#ifdef CONFIG_SAMA5_PMECC_EMBEDDEDALGO + /* REVISIT: Whare are the types Pmecc and Pmerrloc? */ + /* REVISIT: Check returned value */ + + return pmecc_correctionalgo(??, ??, &g_pmecc, isr, data); +#else + /* REVISIT: Check returned value */ + + return pmecc_correctionalgo(isr, data); +#endif +} + +/**************************************************************************** + * Name: pmecc_get* + * + * Description: + * Various PMECC accessor functions + * + * pmecc_get_eccsize() - Returns the raw ECS size in bytes + * pmecc_get_pagesize() - Returns encoded HSMC_PMECCFG_PAGESIZE_* value + * + * Input Parameters: + * None + * + * Returned Value: + * The requested value + * + * Assumptions: + * PMECC has been initialized for the CS and the caller holds the PMECC + * lock. + * + ****************************************************************************/ + +uint32_t pmecc_get_eccsize(void) +{ + return g_pmecc.desc.eccsize; +} + +uint32_t pmecc_get_pagesize(void) +{ + return g_pmecc.desc.pagesize; +} + +/**************************************************************************** + * Name: pmecc_buildgf + * + * Description: + * This function is able to build Galois Field. + * + * Input Parameters: + * mm - Degree of the remainders. + * indexof - Pointer to a buffer for indexof table. + * alphato - Pointer to a buffer for alphato table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_GALOIS_CUSTOM +void pmecc_buildgf(uint32_t mm, int16_t *indexof, int16_t *alphato) +{ + uint32_t i; + uint32_t mask; + uint32_t nn; + uint32_t p[15]; + + nn = (1 << mm) - 1; + + /* Set default value */ + + for (i = 1; i < mm; i++) + { + p[i] = 0; + } + + /* 1 + X^mm */ + + p[0] = 1; + p[mm] = 1; + + /* others */ + + if (mm == 3) + { + p[1] = 1; + } + else if (mm == 4) + { + p[1] = 1; + } + else if (mm == 5) + { + p[2] = 1; + } + else if (mm == 6) + { + p[1] = 1; + } + else if (mm == 7) + { + p[3] = 1; + } + else if (mm == 8) + { + p[2] = p[3] = p[4] = 1; + } + else if (mm == 9) + { + p[4] = 1; + } + else if (mm == 10) + { + p[3] = 1; + } + else if (mm == 11) + { + p[2] = 1; + } + else if (mm == 12) + { + p[1] = p[4] = p[6] = 1; + } + else if (mm == 13) + { + p[1] = p[3] = p[4] = 1; + } + else if (mm == 14) + { + p[1] = p[6] = p[10] = 1; + } + else if (mm == 15) + { + p[1] = 1; + } + + /* First + * + * build alpha ^ mm it will help to generate the field (primitiv) + */ + + alphato[mm] = 0; + for (i = 0; i < mm; i++) + { + if (p[i]) + { + alphato[mm] |= 1 << i; + } + } + + /* Second + * + * Build elements from 0 to mm - 1. Very easy because degree is less than + * mm so it is just a logical shift ! (only the remainder) + */ + + mask = 1; + for (i = 0; i < mm; i++) + { + alphato[i] = mask; + indexof[alphato[i]] = i; + mask <<= 1; + } + + indexof[alphato[mm]] = mm ; + + /* Use a mask to select the MSB bit of the LFSR ! */ + + mask >>= 1; /* Previous value moust be decremented */ + + /* Then finish the building */ + + for (i = mm + 1; i <= nn; i++) + { + /* Check if the msb bit of the lfsr is set */ + + if (alphato[i-1] & mask) + { + /* Feedback loop is set */ + + alphato[i] = alphato[mm] ^ ((alphato[i-1] ^ mask) << 1); + } + else + { + /* Only shift is enabled */ + + alphato[i] = alphato[i-1] << 1; + } + + /* lookup table */ + + //indexof[alphato[i]] = i; + indexof[alphato[i]] = i % nn; + } + + /* Of course index of 0 is undefined in a multiplicative field */ + + indexof[0] = -1; +} +#endif /* CONFIG_SAMA5_PMECC_GALOIS_CUSTOM */ + +#endif /* CONFIG_SAMA5_HAVE_PMECC */ diff --git a/arch/arm/src/sama5/sam_pmecc.h b/arch/arm/src/sama5/sam_pmecc.h new file mode 100644 index 0000000000000000000000000000000000000000..c0d894415035769cc4aad156fd7110971c30190c --- /dev/null +++ b/arch/arm/src/sama5/sam_pmecc.h @@ -0,0 +1,421 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pmecc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This logic was based largely on Atmel sample code with modifications for + * better integration with NuttX. The Atmel sample code has a BSD + * compatible license that requires this copyright notice: + * + * Copyright (c) 2010, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_PMECC_H +#define __ARCH_ARM_SRC_SAMA5_PMECC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Block checking and H/W ECC support must be enabled for PMECC */ + +#ifndef CONFIG_MTD_NAND_HWECC +# undef CONFIG_SAMA5_EBICS0_PMECC +# undef CONFIG_SAMA5_EBICS1_PMECC +# undef CONFIG_SAMA5_EBICS2_PMECC +# undef CONFIG_SAMA5_EBICS3_PMECC +#endif + +/* Only CS3 can support NAND. The rest of what follows is a fantasy */ + +# undef CONFIG_SAMA5_EBICS0_NAND +# undef CONFIG_SAMA5_EBICS1_NAND +# undef CONFIG_SAMA5_EBICS2_NAND + +# undef CONFIG_SAMA5_EBICS0_PMECC +# undef CONFIG_SAMA5_EBICS1_PMECC +# undef CONFIG_SAMA5_EBICS2_PMECC + +/* Disable PMECC support for any banks not enabled or configured for NAND */ + +#if !defined(CONFIG_SAMA5_EBICS0) || !defined(CONFIG_SAMA5_EBICS0_NAND) +# undef CONFIG_SAMA5_EBICS0_PMECC +#endif + +#if !defined(CONFIG_SAMA5_EBICS1) || !defined(CONFIG_SAMA5_EBICS1_NAND) +# undef CONFIG_SAMA5_EBICS1_PMECC +#endif + +#if !defined(CONFIG_SAMA5_EBICS2) || !defined(CONFIG_SAMA5_EBICS2_NAND) +# undef CONFIG_SAMA5_EBICS2_PMECC +#endif + +#if !defined(CONFIG_SAMA5_EBICS3) || !defined(CONFIG_SAMA5_EBICS3_NAND) +# undef CONFIG_SAMA5_EBICS3_PMECC +#endif + +/* Count the number of banks that configured for NAND with PMECC support + * enabled. + */ + +#undef CONFIG_SAMA5_HAVE_PMECC +#ifdef CONFIG_SAMA5_EBICS0_PMECC +# define CONFIG_SAMA5_HAVE_PMECC 1 +# define NAND_HAVE_EBICS0_PMECC 1 +#else +# define NAND_HAVE_EBICS0_PMECC 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS1_PMECC +# define CONFIG_SAMA5_HAVE_PMECC 1 +# define NAND_HAVE_EBICS1_PMECC 1 +#else +# define NAND_HAVE_EBICS1_PMECC 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS2_PMECC +# define CONFIG_SAMA5_HAVE_PMECC 1 +# define NAND_HAVE_EBICS2_PMECC 1 +#else +# define NAND_HAVE_EBICS2_PMECC 0 +#endif + +#ifdef CONFIG_SAMA5_EBICS3_PMECC +# define CONFIG_SAMA5_HAVE_PMECC 1 +# define NAND_HAVE_EBICS3_PMECC 1 +#else +# define NAND_HAVE_EBICS3_PMECC 0 +#endif + +/* Count the number of banks using PMECC */ + +#define NAND_NPMECC_BANKS \ + (NAND_HAVE_EBICS0_PMECC + NAND_HAVE_EBICS1_PMECC + \ + NAND_HAVE_EBICS2_PMECC + NAND_HAVE_EBICS3_PMECC) + +/* Compile this logic only if there is at least one CS configure for NAND + * and with PMECC support enabled. + */ + +#ifdef CONFIG_SAMA5_HAVE_PMECC + +/* Maximum PMECC size */ + +#ifndef CONFIG_MTD_NAND_MAX_PMECCSIZE +# define CONFIG_MTD_NAND_MAX_PMECCSIZE 200 +#endif + +/* The ROM code embeds the software used in the process of ECC + * detection/correction + */ + +#ifdef CONFIG_SAMA5_PMECC_EMBEDDEDALGO_ADDR +# ifndef CONFIG_SAMA5_PMECC_EMBEDDEDALGO_ADDR +# define CONFIG_SAMA5_PMECC_EMBEDDEDALGO_ADDR 0x00104510 +# endif +#endif + +#ifdef CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES +# ifndef CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR +# define CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR 0x00110000 +# endif + +# ifndef CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR +# define CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR 0x00118000 +# endif +#endif + +/* Gallois Field Tables *****************************************************/ + +/* Indexes of tables in Gallois Field tables */ + +#define PMECC_GF_INDEX_OF 0 +#define PMECC_GF_ALPHA_TO 1 + +/* Gallois Field tables for 512 and 1024 bytes sectors + * First raw is "index_of" and second one is "alpha_to" + */ + +#define PMECC_GF_SIZEOF_512 0x2000 +#define PMECC_GF_SIZEOF_1024 0x4000 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Gallois Field tables for 512 bytes sectors. First raw is "index_of" and + * second one is "alpha_to" + */ + +#ifdef CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR +# ifndef CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR +# error CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR is not defined +# endif +# define pmecc_gf512 ((const int16_t *)CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR) + +# ifndef CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR +# error CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR is not defined +# endif +# define pmecc_gf1024 ((const int16_t *)CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR) + +#else + EXTERN const uint16_t pmecc_gf512[2][PMECC_GF_SIZEOF_512]; + EXTERN const uint16_t pmecc_gf1024[2][PMECC_GF_SIZEOF_1024]; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pmecc_lock + * + * Description: + * Get exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_lock(void); +#else +# define pmecc_lock() +#endif + +/**************************************************************************** + * Name: pmecc_unlock + * + * Description: + * Relinquish exclusive access to PMECC hardware + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_unlock(void); +#else +# define pmecc_unlock() +#endif + +/**************************************************************************** + * Name: pmecc_enable + * + * Description: + * Enable PMECC + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void pmecc_enable(void); + +/**************************************************************************** + * Name: pmecc_disable + * + * Description: + * Enable PMECC + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void pmecc_disable(void); + +/**************************************************************************** + * Name: pmecc_initialize + * + * Description: + * Perform one-time PMECC initialization. This must be called before any + * other PMECC interfaces are used. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if NAND_NPMECC_BANKS > 1 +void pmecc_initialize(void); +#else +# define pmecc_initialize() +#endif + +/**************************************************************************** + * Name: pmecc_configure + * + * Description: + * Configure and Initialize the PMECC peripheral for this CS. + * + * Input Parameters: + * priv - Pointer to a struct sam_nandcs_s instance. + * protected - True: The spare area is protected with the last sector of + * data. + * False: The spare area is skipped in read or write mode. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +struct sam_nandcs_s; +int pmecc_configure(struct sam_nandcs_s *priv, bool protected); + +/**************************************************************************** + * Name: pmecc_correction + * + * Description: + * Perform the PMECC correction algorithm + * + * Input Parameters: + * isr - Value of the PMECC ISR register + * data - Data to be corrected + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * PMECC has been initialized for the CS and the caller holds the PMECC + * lock. + * + ****************************************************************************/ + +int pmecc_correction(uint32_t isr, uintptr_t data); + +/**************************************************************************** + * Name: pmecc_get* + * + * Description: + * Various PMECC accessor functions + * + * pmecc_get_eccsize() - Returns the raw ECS size in bytes + * pmecc_get_pagesize() - Returns encoded HSMC_PMECCFG_PAGESIZE_* value + * + * Input Parameters: + * None + * + * Returned Value: + * The requested value + * + * Assumptions: + * PMECC has been initialized for the CS and the caller holds the PMECC + * lock. + * + ****************************************************************************/ + +uint32_t pmecc_get_eccsize(void); +uint32_t pmecc_get_pagesize(void); + +/**************************************************************************** + * Name: pmecc_buildgf + * + * Description: + * This function is able to build Galois Field. + * + * Input Parameters: + * mm - Degree of the remainders. + * indexof - Pointer to a buffer for indexof table. + * alphato - Pointer to a buffer for alphato table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PMECC_GALOIS_CUSTOM +void pmecc_buildgf(uint32_t mm, int16_t* indexof, int16_t* alphato); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#else /* CONFIG_SAMA5_HAVE_PMECC */ +/****************************************************************************/ +/* Stub definitions to minimize conditional compilation when PMECC is + * disabled + */ + +# define pmecc_lock() +# define pmecc_unlock() +# define pmecc_enable() +# define pmecc_disable() +# define pmecc_initialize() +# define pmecc_configure(a,b) (0) +# define pmecc_get_eccsize() (0) +# define pmecc_get_pagesize() (0) + +#endif /* CONFIG_SAMA5_HAVE_PMECC */ +#endif /* __ARCH_ARM_SRC_SAMA5_PMECC_H */ diff --git a/arch/arm/src/sama5/sam_pwm.c b/arch/arm/src/sama5/sam_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..c83764d50c5df86d708db534fa566bf2f9f853d1 --- /dev/null +++ b/arch/arm/src/sama5/sam_pwm.c @@ -0,0 +1,1401 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_pwm.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip/sam_pinmap.h" +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_periphclks.h" +#include "sam_pio.h" +#include "sam_pwm.h" + +#ifdef CONFIG_SAMA5_PWM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Currently, we support only a single PWM peripheral. However, the hooks + * are in place to support multiple PWM peripherals. + */ + +#define PWM_SINGLE 1 + +/* Pulse counting is not supported by this driver */ + +#ifdef CONFIG_PWM_PULSECOUNT +# warning CONFIG_PWM_PULSECOUNT no supported by this driver. +#endif + +/* Are we using CLKA? CLKB? If so, what frequency? Select the prescaler + * value that allows the largest, valid divider value. This may not be + * optimal in all cases, but in general should provide a reasonable frequency + * value. + * + * frequency = MCK / prescaler / div + * + * Pick smallest prescaler such that: + * + * prescaler = MCK / frequency / div < 256 + * + * Then: + * + * div = MCK / prescaler / frequency + * + * Calulcated Values + * + * CLKn_PRE = CLKn prescaler value + * PWM_CLK_PREn = CLKn prescaler register setting + * CLKn_DIV = CLKn divider value + * PWM_CLK_DIVn = CLKn divider register setting + * CLKn_FREQUENCY = Actual resulting CLKn frequency + */ + +#ifdef CONFIG_SAMA5_PWM_CLKA + +# if !defined(CONFIG_SAMA5_PWM_CLKA_FREQUENCY) +# error CONFIG_SAMA5_PWM_CLKA_FREQUENCY is not defined + +# elif (BOARD_MCK_FREQUENCY / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1 +# define CLKA_PRE 1 + +# elif (BOARD_MCK_FREQUENCY / 2 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV2 +# define CLKA_PRE 2 + +# elif (BOARD_MCK_FREQUENCY / 4 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV4 +# define CLKA_PRE 4 + +# elif (BOARD_MCK_FREQUENCY / 8 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV8 +# define CLKA_PRE 8 + +# elif (BOARD_MCK_FREQUENCY / 16 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV16 +# define CLKA_PRE 16 + +# elif (BOARD_MCK_FREQUENCY / 32 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV32 +# define CLKA_PRE 32 + +# elif (BOARD_MCK_FREQUENCY / 64 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV64 +# define CLKA_PRE 64 + +# elif (BOARD_MCK_FREQUENCY / 128 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV128 +# define CLKA_PRE 128 + +# elif (BOARD_MCK_FREQUENCY / 256 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV256 +# define CLKA_PRE 256 + +# elif (BOARD_MCK_FREQUENCY / 512 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV512 +# define CLKA_PRE 512 + +# elif (BOARD_MCK_FREQUENCY / 1024 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256 +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1024 +# define CLKA_PRE 1024 + +# else +# error Cannot realize CONFIG_SAMA5_PWM_CLKA_FREQUENCY +# endif + +# define CLKA_DIV (BOARD_MCK_FREQUENCY / CLKA_PRE / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) +# define CLKA_FREQUENCY (BOARD_MCK_FREQUENCY / CLKA_PRE / CLKA_DIV) +# define CLKA_DIV_BITS PWM_CLK_DIVA(CLKA_DIV) + +#else +# undef CONFIG_SAMA5_PWM_CLKA_FREQUENCY +# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1 +# define CLKA_DIV_BITS PWM_CLK_DIVA_OFF +#endif + +#ifdef CONFIG_SAMA5_PWM_CLKB + +# if !defined(CONFIG_SAMA5_PWM_CLKB_FREQUENCY) +# error CONFIG_SAMA5_PWM_CLKB_FREQUENCY is not defined + +# elif (BOARD_MCK_FREQUENCY / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1 +# define CLKB_PRE 1 + +# elif (BOARD_MCK_FREQUENCY / 2 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV2 +# define CLKB_PRE 2 + +# elif (BOARD_MCK_FREQUENCY / 4 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV4 +# define CLKB_PRE 4 + +# elif (BOARD_MCK_FREQUENCY / 8 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV8 +# define CLKB_PRE 8 + +# elif (BOARD_MCK_FREQUENCY / 16 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV16 +# define CLKB_PRE 16 + +# elif (BOARD_MCK_FREQUENCY / 32 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV32 +# define CLKB_PRE 32 + +# elif (BOARD_MCK_FREQUENCY / 64 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV64 +# define CLKB_PRE 64 + +# elif (BOARD_MCK_FREQUENCY / 128 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV128 +# define CLKB_PRE 128 + +# elif (BOARD_MCK_FREQUENCY / 256 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV256 +# define CLKB_PRE 256 + +# elif (BOARD_MCK_FREQUENCY / 512 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV512 +# define CLKB_PRE 512 + +# elif (BOARD_MCK_FREQUENCY / 1024 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256 +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1024 +# define CLKB_PRE 1024 + +# else +# error Cannot realize CONFIG_SAMA5_PWM_CLKB_FREQUENCY +# endif + +# define CLKB_DIV (BOARD_MCK_FREQUENCY / CLKB_PRE / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) +# define CLKB_FREQUENCY (BOARD_MCK_FREQUENCY / CLKB_PRE / CLKB_DIV) +# define CLKB_DIV_BITS PWM_CLK_DIVB(CLKB_DIV) + +#else +# undef CONFIG_SAMA5_PWM_CLKB_FREQUENCY +# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1 +# define CLKB_DIV_BITS PWM_CLK_DIVB_OFF +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN0 +# if defined(CONFIG_SAMA5_PWM_CHAN0_MCK) +# undef CONFIG_SAMA5_PWM_CHAN0_CLKA +# undef CONFIG_SAMA5_PWM_CHAN0_CLKB +# if CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 1 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 0 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 2 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 1 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 4 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 2 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 8 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 3 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 16 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 4 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 32 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 5 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 64 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 6 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 128 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 7 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 256 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 8 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 512 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 9 +# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 1024 +# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 10 +# else +# error Unsupported MCK divider value +# endif + +# elif defined(CONFIG_SAMA5_PWM_CHAN0_CLKA) +# undef CONFIG_SAMA5_PWM_CHAN0_CLKB + +# elif !defined(CONFIG_SAMA5_PWM_CHAN0_CLKB) +# error CHAN0 clock source not defined + +# endif +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN1 +# if defined(CONFIG_SAMA5_PWM_CHAN1_MCK) +# undef CONFIG_SAMA5_PWM_CHAN1_CLKA +# undef CONFIG_SAMA5_PWM_CHAN1_CLKB +# if CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 1 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 0 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 2 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 1 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 4 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 2 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 8 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 3 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 16 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 4 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 32 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 5 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 64 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 6 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 128 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 7 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 256 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 8 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 512 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 9 +# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 1024 +# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 10 +# else +# error Unsupported MCK divider value +# endif + +# elif defined(CONFIG_SAMA5_PWM_CHAN1_CLKA) +# undef CONFIG_SAMA5_PWM_CHAN1_CLKB + +# elif !defined(CONFIG_SAMA5_PWM_CHAN1_CLKB) +# error CHAN1 clock source not defined + +# endif +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN2 +# if defined(CONFIG_SAMA5_PWM_CHAN2_MCK) +# undef CONFIG_SAMA5_PWM_CHAN2_CLKA +# undef CONFIG_SAMA5_PWM_CHAN2_CLKB +# if CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 1 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 0 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 2 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 1 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 4 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 2 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 8 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 3 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 16 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 4 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 32 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 5 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 64 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 6 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 128 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 7 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 256 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 8 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 512 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 9 +# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 1024 +# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 10 +# else +# error Unsupported MCK divider value +# endif + +# elif defined(CONFIG_SAMA5_PWM_CHAN2_CLKA) +# undef CONFIG_SAMA5_PWM_CHAN2_CLKB + +# elif !defined(CONFIG_SAMA5_PWM_CHAN2_CLKB) +# error CHAN2 clock source not defined + +# endif +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN3 +# if defined(CONFIG_SAMA5_PWM_CHAN3_MCK) +# undef CONFIG_SAMA5_PWM_CHAN3_CLKA +# undef CONFIG_SAMA5_PWM_CHAN3_CLKB +# if CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 1 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 0 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 2 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 1 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 4 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 2 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 8 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 3 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 16 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 4 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 32 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 5 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 64 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 6 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 128 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 7 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 256 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 8 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 512 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 9 +# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 1024 +# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 10 +# else +# error Unsupported MCK divider value +# endif + +# elif defined(CONFIG_SAMA5_PWM_CHAN3_CLKA) +# undef CONFIG_SAMA5_PWM_CHAN3_CLKB + +# elif !defined(CONFIG_SAMA5_PWM_CHAN3_CLKB) +# error CHAN3 clock source not defined + +# endif +#endif + +/* The current design does not use any PWM interrupts */ + +#undef PWM_INTERRUPTS + +/* Pin configuration ********************************************************/ + +#define PWM_INPUTCFG (PIO_INPUT | PIO_CFG_DEFAULT | PIO_DRIVE_LOW) +#define PWM_PINMASK (PIO_PORT_MASK | PIO_PIN_MASK) +#define PWM_MKINPUT(cfg) (((cfg) & PWM_PINMASK) | PWM_INPUTCFG) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Channel clock sources */ + +enum pwm_clksrc_e +{ + PWM_CLKSRC_MCK = 1, /* Source = Divided MCK */ + PWM_CLKSRC_CLKA, /* Source = CLKA */ + PWM_CLKSRC_CLKB, /* Source = CLKB */ +}; + +/* This structure represents the state of one PWM channel */ + +struct sam_pwm_s; +struct sam_pwm_chan_s +{ + const struct pwm_ops_s *ops; /* PWM operations */ +#ifndef PWM_SINGLE + struct sam_pwm_s *pwm; /* Parent PWM peripheral */ +#endif + uintptr_t base; /* Base address of channel registers */ + uint8_t channel; /* PWM channel: {0,..3} */ + uint8_t clksrc; /* 0=MCK; 1=CLKA; 2=CLKB */ + uint8_t divlog2; /* Log2 MCK divisor: 0->1, 1->2, 2->4, ... 10->1024 */ + pio_pinset_t ohpincfg; /* Output high pin configuration */ + pio_pinset_t olpincfg; /* Output low pin configuration */ + pio_pinset_t fipincfg; /* Fault input pin configuration */ +}; + +/* This structure represents the overall state of the PWM peripheral */ + +struct sam_pwm_s +{ + bool initialized; /* True: one time initialization has been performed */ +#ifndef PWM_SINGLE + uintptr_t base; /* Base address of peripheral registers */ +#endif + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG + bool wr; /* Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int count; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG +static bool pwm_checkreg(FAR struct sam_pwm_s *chan, bool wr, uint32_t regval, + uintptr_t regaddr); +#else +# define pwm_checkreg(chan,wr,regval,regaddr) (false) +#endif + +static uint32_t pwm_getreg(FAR struct sam_pwm_chan_s *chan, int offset); +static void pwm_putreg(FAR struct sam_pwm_chan_s *chan, int offset, uint32_t regval); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(FAR struct sam_pwm_chan_s *chan, FAR const char *msg); +#else +# define pwm_dumpregs(chan,msg) +#endif + +/* PWM Interrupts */ + +#ifdef PWM_INTERRUPTS +static int pwm_interrupt(int irq, void *context); +#endif + +/* PWM driver methods */ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/* Initialization */ + +static void pwm_resetpins(FAR struct sam_pwm_chan_s *chan); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper + * half driver + */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +/* This is the overall state of the PWM peripheral */ + +static struct sam_pwm_s g_pwm = +{ + .initialized = false, +#ifndef PWM_SINGLE + .base = SAM_PWMC_VBASE, +#endif +}; + +#ifdef CONFIG_SAMA5_PWM_CHAN0 +/* This is the state of the PWM channel 0 */ + +static struct sam_pwm_chan_s g_pwm_chan0 = +{ + .ops = &g_pwmops, +#ifndef PWM_SINGLE + .pwm = &g_pwm, +#endif + .channel = 0, + .base = SAM_PWM_CHANA_BASE(0), + +#if defined(CONFIG_SAMA5_PWM_CHAN0_MCK) + .clksrc = PWM_CLKSRC_MCK, + .divlog2 = SAMA5_PWM_CHAN0_MCKDIV_LOG2, +#elif defined(CONFIG_SAMA5_PWM_CHAN0_CLKA) + .clksrc = PWM_CLKSRC_CLKA, +#elif defined(CONFIG_SAMA5_PWM_CHAN0_CLKB) + .clksrc = PWM_CLKSRC_CLKB, +#else +# error No clock source for channel 0 +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTH + .ohpincfg = PIO_PWM0_H, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTL + .olpincfg = PIO_PWM0_L, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN0_FAULTINPUT + .fipincfg = PIO_PWM0_FI, +#endif +}; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN1 +/* This is the state of the PWM channel 1 */ + +static struct sam_pwm_chan_s g_pwm_chan1 = +{ + .ops = &g_pwmops, +#ifndef PWM_SINGLE + .pwm = &g_pwm, +#endif + .channel = 1, + .base = SAM_PWM_CHANA_BASE(1), + +#if defined(CONFIG_SAMA5_PWM_CHAN1_MCK) + .clksrc = PWM_CLKSRC_MCK, + .divlog2 = SAMA5_PWM_CHAN1_MCKDIV_LOG2, +#elif defined(CONFIG_SAMA5_PWM_CHAN1_CLKA) + .clksrc = PWM_CLKSRC_CLKA, +#elif defined(CONFIG_SAMA5_PWM_CHAN1_CLKB) + .clksrc = PWM_CLKSRC_CLKB, +#else +# error No clock source for channel 0 +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN1_OUTPUTH + .ohpincfg = PIO_PWM1_H, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN1_OUTPUTL + .olpincfg = PIO_PWM1_L, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN1_FAULTINPUT + .fipincfg = PIO_PWM1_FI, +#endif +}; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN2 +/* This is the state of the PWM channel 2 */ + +static struct sam_pwm_chan_s g_pwm_chan2 = +{ + .ops = &g_pwmops, +#ifndef PWM_SINGLE + .pwm = &g_pwm, +#endif + .channel = 2, + .base = SAM_PWM_CHANA_BASE(2), + +#if defined(CONFIG_SAMA5_PWM_CHAN2_MCK) + .clksrc = PWM_CLKSRC_MCK, + .divlog2 = SAMA5_PWM_CHAN2_MCKDIV_LOG2, +#elif defined(CONFIG_SAMA5_PWM_CHAN2_CLKA) + .clksrc = PWM_CLKSRC_CLKA, +#elif defined(CONFIG_SAMA5_PWM_CHAN2_CLKB) + .clksrc = PWM_CLKSRC_CLKB, +#else +# error No clock source for channel 0 +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN2_OUTPUTH + .ohpincfg = PIO_PWM2_H, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN2_OUTPUTL + .olpincfg = PIO_PWM2_L, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN2_FAULTINPUT + .fipincfg = PIO_PWM2_FI, +#endif +}; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN3 +/* This is the state of the PWM channel 3 */ + +static struct sam_pwm_chan_s g_pwm_chan3 = +{ + .ops = &g_pwmops, +#ifndef PWM_SINGLE + .pwm = &g_pwm, +#endif + .channel = 3, + .base = SAM_PWM_CHANA_BASE(3), + +#if defined(CONFIG_SAMA5_PWM_CHAN3_MCK) + .clksrc = PWM_CLKSRC_MCK, + .divlog2 = SAMA5_PWM_CHAN3_MCKDIV_LOG2, +#elif defined(CONFIG_SAMA5_PWM_CHAN3_CLKA) + .clksrc = PWM_CLKSRC_CLKA, +#elif defined(CONFIG_SAMA5_PWM_CHAN3_CLKB) + .clksrc = PWM_CLKSRC_CLKB, +#else +# error No clock source for channel 0 +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN3_OUTPUTH + .ohpincfg = PIO_PWM3_H, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN3_OUTPUTL + .olpincfg = PIO_PWM3_L, +#endif +#ifdef CONFIG_SAMA5_PWM_CHAN3_FAULTINPUT + .fipincfg = PIO_PWM3_FI, +#endif +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG +static bool pwm_checkreg(FAR struct sam_pwm_s *pwm, bool wr, uint32_t regval, + uintptr_t regaddr) +{ + if (wr == pwm->wr && /* Same kind of access? */ + regval == pwm->regval && /* Same value? */ + regaddr == pwm->regaddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + pwm->count++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (pwm->count > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", pwm->count); + } + + /* Save information about the new access */ + + pwm->wr = wr; + pwm->regval = regval; + pwm->regaddr = regaddr; + pwm->count = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: pwm_getreg + * + * Description: + * Read the value of a PWM register. + * + * Input Parameters: + * chan - A reference to the PWM channel instance + * offset - The offset to the PWM register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t pwm_getreg(struct sam_pwm_chan_s *chan, int offset) +{ +#ifdef PWM_SINGLE + uintptr_t regaddr; + uint32_t regval; + + regaddr = SAM_PWMC_VBASE + offset; + regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG + if (pwm_checkreg(&g_pwm, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; + +#else + struct sam_pwm_chan_s *pwm = chan->pwm; + uintptr_t regaddr; + uint32_t regval; + + regaddr = pwm->base + offset; + regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG + if (pwm_checkreg(pwm, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; + +#endif +} + +/**************************************************************************** + * Name: pwm_chan_getreg + * + * Description: + * Read the value of a PWM channel register. + * + * Input Parameters: + * chan - A reference to the PWM channel instance + * offset - The offset to the channel register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t pwm_chan_getreg(struct sam_pwm_chan_s *chan, int offset) +{ + uintptr_t regaddr; + uint32_t regval; + + regaddr = chan->base + offset; + regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG +#ifdef PWM_SINGLE + if (pwm_checkreg(&g_pwm, false, regval, regaddr)) +#else + if (pwm_checkreg(chan->pwm, false, regval, regaddr)) +#endif + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: pwm_putreg + * + * Description: + * Write a value to a PWM register. + * + * Input Parameters: + * chan - A reference to the PWM channel instance + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_putreg(struct sam_pwm_chan_s *chan, int offset, + uint32_t regval) +{ +#ifdef PWM_SINGLE + uintptr_t regaddr = SAM_PWMC_VBASE + offset; + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG + if (pwm_checkreg(&g_pwm, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); + +#else + struct sam_pwm_chan_s *pwm = chan->pwm; + uintptr_t regaddr = pwm->base + offset; + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG + if (pwm_checkreg(pwm, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); + +#endif +} + +/**************************************************************************** + * Name: pwm_chan_putreg + * + * Description: + * Read the value of an PWM channel register. + * + * Input Parameters: + * chan - A reference to the PWM channel instance + * offset - The offset to the channel register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_chan_putreg(struct sam_pwm_chan_s *chan, int offset, + uint32_t regval) +{ + uintptr_t regaddr = chan->base + offset; + +#ifdef CONFIG_SAMA5_PWM_REGDEBUG +#ifdef PWM_SINGLE + if (pwm_checkreg(&g_pwm, true, regval, regaddr)) +#else + if (pwm_checkreg(chan->pwm, true, regval, regaddr)) +#endif + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: pwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * chan - A reference to the PWM channel instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct sam_pwm_chan_s *chan, FAR const char *msg) +{ + pwmvdbg("PWM: %s\n", msg); + pwmvdbg(" CLK: %08x SR: %08x IMR1: %08x ISR1: %08x\n", + pwm_getreg(chan, SAM_PWM_CLK_OFFSET), + pwm_getreg(chan, SAM_PWM_SR_OFFSET), + pwm_getreg(chan, SAM_PWM_IMR1_OFFSET), + pwm_getreg(chan, SAM_PWM_ISR1_OFFSET)); + pwmvdbg(" SCM: %08x SCUC: %08x SCUP: %08x IMR2: %08x\n", + pwm_getreg(chan, SAM_PWM_SCM_OFFSET), + pwm_getreg(chan, SAM_PWM_SCUC_OFFSET), + pwm_getreg(chan, SAM_PWM_SCUP_OFFSET), + pwm_getreg(chan, SAM_PWM_IMR2_OFFSET)); + pwmvdbg(" ISR2: %08x OOV: %08x OS: %08x FMR: %08x\n", + pwm_getreg(chan, SAM_PWM_ISR2_OFFSET), + pwm_getreg(chan, SAM_PWM_OOV_OFFSET), + pwm_getreg(chan, SAM_PWM_OS_OFFSET), + pwm_getreg(chan, SAM_PWM_FMR_OFFSET)); + pwmvdbg(" FSR: %08x FPV: %08x FPE: %08x ELMR0: %08x\n", + pwm_getreg(chan, SAM_PWM_FSR_OFFSET), + pwm_getreg(chan, SAM_PWM_FPV_OFFSET), + pwm_getreg(chan, SAM_PWM_FPE_OFFSET), + pwm_getreg(chan, SAM_PWM_ELMR0_OFFSET)); + pwmvdbg(" ELMR1: %08x SMMR: %08x WPSR: %08x\n", + pwm_getreg(chan, SAM_PWM_ELMR1_OFFSET), + pwm_getreg(chan, SAM_PWM_SMMR_OFFSET), + pwm_getreg(chan, SAM_PWM_WPSR_OFFSET)); + pwmvdbg(" CMPV0: %08x CMPM0: %08x CMPV1: %08x CMPM1: %08x\n", + pwm_getreg(chan, SAM_PWM_CMPV0_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM0_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPV1_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM1_OFFSET)); + pwmvdbg(" CMPV2: %08x CMPM2: %08x CMPV3: %08x CMPM3: %08x\n", + pwm_getreg(chan, SAM_PWM_CMPV2_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM2_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPV3_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM3_OFFSET)); + pwmvdbg(" CMPV4: %08x CMPM4: %08x CMPV5: %08x CMPM5: %08x\n", + pwm_getreg(chan, SAM_PWM_CMPV4_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM4_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPV5_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM5_OFFSET)); + pwmvdbg(" CMPV6: %08x CMPM6: %08x CMPV7: %08x CMPM7: %08x\n", + pwm_getreg(chan, SAM_PWM_CMPV6_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM6_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPV7_OFFSET), + pwm_getreg(chan, SAM_PWM_CMPM7_OFFSET)); + pwmvdbg("Channel %d: %s\n", chan->channel, msg); + pwmvdbg(" CMR: %08x CDTY: %08x CPRD: %08x CCNT: %08x\n", + pwm_chan_getreg(chan, SAM_PWM_CMR_OFFSET), + pwm_chan_getreg(chan, SAM_PWM_CDTY_OFFSET), + pwm_chan_getreg(chan, SAM_PWM_CPRD_OFFSET), + pwm_chan_getreg(chan, SAM_PWM_CCNT_OFFSET)); + pwmvdbg(" CT: %08x\n", + pwm_chan_getreg(chan, SAM_PWM_DT_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: pwm_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * Standard interrupt handler inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef PWM_INTERRUPTS +static int pwm_interrupt(int irq, void *context) +{ + /* No PWM interrupts are used in the current design */ + +#warning Missing logic + return OK; +} +#endif + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * will be configured and initialized the device so that it is ready for + * use. It will not, however, output pulses until the start method is + * called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev; + + pwmvdbg("Channel %d: H=%08x L=%08x FI=%08x\n", + chan->channel, chan->ohpincfg, chan->olpincfg, chan->fipincfg); + + /* Configure selected PWM pins */ + + if (chan->ohpincfg) + { + (void)sam_configpio(chan->ohpincfg); + } + + if (chan->olpincfg) + { + (void)sam_configpio(chan->olpincfg); + } + + if (chan->fipincfg) + { + (void)sam_configpio(chan->fipincfg); + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev; + + pwmvdbg("Channel %d\n", chan->channel); + + /* Make sure that the output has been stopped */ + + pwm_stop(dev); + + /* Then put the GPIO pins back to the default, input state */ + + pwm_resetpins(chan); + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev; + uint32_t regval; + uint32_t cprd; + uint32_t fsrc; + + /* Disable the channel (should already be disabled) */ + + pwm_putreg(chan, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel)); + + /* Determine the clock source */ + + switch (chan->clksrc) + { + case PWM_CLKSRC_MCK: + regval = PWM_CMR_CPRE_MCKDIV(chan->divlog2); + fsrc = BOARD_MCK_FREQUENCY >> chan->divlog2; + break; + +#ifdef CONFIG_SAMA5_PWM_CLKA + case PWM_CLKSRC_CLKA: + regval = PWM_CMR_CPRE_CLKA; + fsrc = CLKA_FREQUENCY; + break; +#endif + +#ifdef CONFIG_SAMA5_PWM_CLKB + case PWM_CLKSRC_CLKB: + regval = PWM_CMR_CPRE_CLKB; + fsrc = CLKB_FREQUENCY; + break; +#endif + + default: + pwmdbg("ERROR: Invalid or unsupported clock source value: %d\n", chan->clksrc); + return -EINVAL; + } + + /* Configure the channel */ + + pwm_chan_putreg(chan, SAM_PWM_CMR_OFFSET, PWM_CMR_CPRE_CLKA); + + /* Set the PWM period. + * + * If the waveform is left-aligned, then the output waveform period + * depends on the channel counter source clock and can be calculated + * as follows: + * + * Tchan = cprd / Fsrc + * cprd = Fsrc / Fchan + * + * If the waveform is center-aligned, then the output waveform period + * depends on the channel counter source clock and can be calculated: + * + * Tchan = 2 * cprd / Fsrc + * cprd = Fsrc / 2 / Fchan + * + * Since the PWM is disabled, we can write directly to the CPRD (vs. + * the CPRDUPD) register. + */ + + cprd = (fsrc + (info->frequency >> 1)) / info->frequency; + pwm_chan_putreg(chan, SAM_PWM_CPRD_OFFSET, cprd); + + /* Set the PWM duty. Since the PWM is disabled, we can write directly + * to the CTDY (vs. the CTDYUPD) register. + */ + + regval = b16toi(info->duty * cprd + b16HALF); + if (regval > cprd) + { + /* Rounding up could cause the duty value to exceed CPRD (?) */ + + regval = cprd; + } + + pwm_chan_putreg(chan, SAM_PWM_CDTY_OFFSET, regval); + pwmvdbg("Fsrc=%d cprd=%d cdty=%d\n", fsrc, cprd, regval); + + /* Enable the channel */ + + pwm_putreg(chan, SAM_PWM_ENA_OFFSET, PWM_CHID(chan->channel)); + pwm_dumpregs(chan, "After start"); + return OK; +} + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev; + + pwmvdbg("Channel %d\n", chan->channel); + + /* Disable further PWM interrupts from this channel */ + + pwm_putreg(chan, SAM_PWM_IDR1_OFFSET, + PWM_INT1_CHID(chan->channel) | PWM_INT1_FCHID(chan->channel)); + + /* Disable the channel */ + + pwm_putreg(chan, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel)); + pwm_dumpregs(chan, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("Channel %d\n", chan->channel); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static void pwm_resetpins(FAR struct sam_pwm_chan_s *chan) +{ + if (chan->ohpincfg) + { + (void)sam_configpio(PWM_MKINPUT(chan->ohpincfg)); + } + + if (chan->olpincfg) + { + (void)sam_configpio(PWM_MKINPUT(chan->olpincfg)); + } + + if (chan->fipincfg) + { + (void)sam_configpio(PWM_MKINPUT(chan->fipincfg)); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pwminitialize + * + * Description: + * Initialize one PWM channel for use with the upper_level PWM driver. + * + * Input Parameters: + * channel - A number identifying the PWM channel use. + * + * Returned Value: + * On success, a pointer to the SAMA5 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *sam_pwminitialize(int channel) +{ + FAR struct sam_pwm_chan_s *chan; + uint32_t regval; + + pwmvdbg("Channel %d\n", channel); + + switch (channel) + { +#ifdef CONFIG_SAMA5_PWM_CHAN0 + case 0: + /* Select the Channel 0 interface */ + + chan = &g_pwm_chan0; + break; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN1 + case 1: + /* Select the Channel 1 interface */ + + chan = &g_pwm_chan1; + break; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN2 + case 2: + /* Select the Channel 2 interface */ + + chan = &g_pwm_chan2; + break; +#endif + +#ifdef CONFIG_SAMA5_PWM_CHAN3 + case 3: + /* Select the Channel 3 interface */ + + chan = &g_pwm_chan3; + break; +#endif + + default: + pwmdbg("ERROR: Channel invalid or not configured: %d\n", channel); + return NULL; + } + + /* Have we already performed the one time initialization of the overall + * PWM peripheral? + */ + + if (!g_pwm.initialized) + { + /* Enable the PWM peripheral clock */ + + sam_pwm_enableclk(); + + /* Set clock A and clock B */ + + regval = (CLKA_PRE_BITS | CLKA_DIV_BITS | CLKB_PRE_BITS | CLKB_DIV_BITS); + pwm_putreg(chan, SAM_PWM_CLK_OFFSET, regval); + + /* Disable all PWM interrupts at the PWM peripheral */ + + pwm_putreg(chan, SAM_PWM_IDR1_OFFSET, PWM_INT1_ALL); + pwm_putreg(chan, SAM_PWM_IDR2_OFFSET, PWM_INT2_ALL); + + /* Attach the PWM interrupt handler */ + +#ifdef PWM_INTERRUPTS + ret = irq_attach(SAM_IRQ_PWM, pwm_interrupt); + if (ret < 0) + { + pwmdbg("ERROR: Failed to attach IRQ%d\n", channel); + return NULL; + + } +#endif + + /* Clear any pending PWM interrupts */ + + (void)pwm_getreg(chan, SAM_PWM_ISR1_OFFSET); + (void)pwm_getreg(chan, SAM_PWM_ISR2_OFFSET); + + /* Enable PWM interrupts at the AIC */ + +#ifdef PWM_INTERRUPTS + up_enable_irq(SAM_IRQ_PWM); +#endif + + /* Now were are initialized */ + + g_pwm.initialized = true; + pwm_dumpregs(chan, "After Initialization"); + } + + /* Configure all pins for this channel as inputs */ + + pwm_resetpins(chan); + + /* Return the lower-half driver instance for this channel */ + + return (FAR struct pwm_lowerhalf_s *)chan; +} + +#endif /* CONFIG_SAMA5_PWM */ diff --git a/arch/arm/src/sama5/sam_pwm.h b/arch/arm/src/sama5/sam_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..b9615d64da6bcf7a4960837f1f6dbf5d2eb7a89b --- /dev/null +++ b/arch/arm/src/sama5/sam_pwm.h @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_pwm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_PWM_H +#define __ARCH_ARM_SRC_SAMA5_SAM_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_pwm.h" + +#ifdef CONFIG_SAMA5_PWM + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +/* Do we have any PWM channels enabled? If not, then why is the PWM enabled? */ + +#if !defined(CONFIG_SAMA5_PWM_CHAN0) && !defined(CONFIG_SAMA5_PWM_CHAN1) && \ + !defined(CONFIG_SAMA5_PWM_CHAN2) && !defined(CONFIG_SAMA5_PWM_CHAN3) +# error "No PWM channels configured" +# undef CONFIG_SAMA5_PWM +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * channel - A number identifying the PWM channel use. + * + * Returned Value: + * On success, a pointer to the SAMA5 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *sam_pwminitialize(int channel); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMA5_PWM */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_PWM_H */ diff --git a/arch/arm/src/sama5/sam_rtc.c b/arch/arm/src/sama5/sam_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..94bca9114246b1a0f894c4de41712667bb7aab86 --- /dev/null +++ b/arch/arm/src/sama5/sam_rtc.c @@ -0,0 +1,686 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_rtc.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sam_rtc.h" + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error "CONFIG_RTC_DATETIME must be set to use this driver" +#endif + +#ifdef CONFIG_RTC_HIRES +# error "CONFIG_RTC_HIRES must NOT be set with this driver" +#endif + +#if defined(CONFIG_RTC_ALARM) && !defined(CONFIG_SCHED_WORKQUEUE) +# error CONFIG_RTC_ALARM requires CONFIG_SCHED_WORKQUEUE +#endif + +#define RTC_MAGIC 0xdeadbeef + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +/* Constants ************************************************************************/ + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +struct work_s g_alarmwork; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" CR: %08x\n", getreg32(SAM_RTC_CR)); + rtclldbg(" MR: %08x\n", getreg32(SAM_RTC_MR)); + rtclldbg(" TIMR: %08x\n", getreg32(SAM_RTC_TIMR)); + rtclldbg(" CALR: %08x\n", getreg32(SAM_RTC_CALR)); + rtclldbg(" TIMALR: %08x\n", getreg32(SAM_RTC_TIMALR)); + rtclldbg(" CALALR: %08x\n", getreg32(SAM_RTC_CALALR)); + rtclldbg(" SR: %08x\n", getreg32(SAM_RTC_SR)); + rtclldbg(" IMR: %08x\n", getreg32(SAM_RTC_IMR)); + rtclldbg(" VER: %08x\n", getreg32(SAM_RTC_VER)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint32_t rtc_bin2bcd(int value) +{ + uint32_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint32_t value) +{ + uint32_t tens = (value >> 4) * 10; + return (int)(tens + (value & 0x0f)); +} + +/************************************************************************************ + * Name: rtc_worker + * + * Description: + * Perform alarm callback + * + * Input Parameters: + * Standard work callbacks + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static void rtc_worker(FAR void *arg) +{ + /* Sample once (atomically) */ + + alarmcb_t alarmcb = g_alarmcb; + + /* Is there a subscriber to the alarm? */ + + if (alarmcb) + { + /* Yes.. perform the callback */ + + alarmcb(); + } +} +#endif + +/************************************************************************************ + * Name: rtc_interrupt + * + * Description: + * RTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_interrupt(int irq, void *context) +{ + int ret; + + /* Schedule the callback to occur on the low-priority worker thread */ + + DEBUGASSERT(work_available(&g_alarmwork)); + ret = work_queue(LPWORK, &g_alarmwork, rtc_worker, NULL, 0); + if (ret < 0) + { + rtclldbg("ERRPR: work_queue failed: %d\n", ret); + } + + /* Disable any further alarm interrupts */ + + putreg32(RTC_IDR_ALRDIS, SAM_RTC_IDR); + + /* Clear any pending alarm interrupts */ + + putreg32(RTC_SCCR_ALRCLR, SAM_RTC_SCCR); + return OK; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + uint32_t ver; + + rtc_dumpregs("On reset"); + + /* No clocking setup need be performed. The Real-time Clock is continuously clocked + * at 32768 Hz (SCLK). The Power Management Controller has no effect on RTC + * behavior. + */ + + /* Set the 24 hour format */ + + putreg32(0, SAM_RTC_MR); + + /* Has the RTC been initialized? */ + + ver = getreg32(SAM_RTC_VER); + g_rtc_enabled = ((ver & (RTC_VER_NVTIM | RTC_VER_NVCAL)) == 0); + +#ifdef CONFIG_RTC_ALARM + /* Then attach the ALARM interrupt handler */ + + irq_attach(SAM_PID_SYS, rtc_interrupt); + + /* Should RTC alarm interrupt be enabled at the peripheral? Let's assume so + * for now. Let's say yes if the time is valid and a valid alarm has been + * programmed. + */ + + if (g_rtc_enabled && (ver & (RTC_VER_NVTIMALR | RTC_VER_NVCALALR)) == 0) + { + /* Enable the alarm interrupt at the RTC */ + + putreg32(RTC_IER_ALREN, SAM_RTC_IER); + } + else + { + /* Disable the alarm interrupt at the RTC */ + + putreg32(RTC_IDR_ALRDIS, SAM_RTC_IDR); + } + + /* Enable SYSC interrupts at the AIC in any event */ + + up_enable_irq(SAM_PID_SYS); + +#endif + + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + uint32_t timr; + uint32_t calr; + uint32_t cent; + uint32_t year; + uint32_t tmp; + + /* Sample the data time registers. There is a race condition here... If we sample + * the time just before midnight on December 31, the date could be wrong because + * the day rolled over while were sampling. + */ + + do + { + calr = getreg32(SAM_RTC_CALR); + timr = getreg32(SAM_RTC_TIMR); + tmp = getreg32(SAM_RTC_CALR); + } + while (tmp != calr); + + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time register fields to struct tm format. + * + * struct tm TIMR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + tmp = (timr & RTC_TIMR_SEC_MASK) >> RTC_TIMR_SEC_SHIFT; + tp->tm_sec = rtc_bcd2bin(tmp); + + tmp = (timr & RTC_TIMR_MIN_MASK) >> RTC_TIMR_MIN_SHIFT; + tp->tm_min = rtc_bcd2bin(tmp); + + tmp = (timr & RTC_TIMR_HOUR_MASK) >> RTC_TIMR_HOUR_SHIFT; + tp->tm_hour = rtc_bcd2bin(tmp); + + /* Convert the RTC date register fields to struct tm format. + * + * struct tm TIMR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported + */ + + tmp = (calr & RTC_CALR_DATE_MASK) >> RTC_CALR_DATE_SHIFT; + tp->tm_mday = rtc_bcd2bin(tmp); + + tmp = (calr & RTC_CALR_MONTH_MASK) >> RTC_CALR_MONTH_SHIFT; + tp->tm_mon = rtc_bcd2bin(tmp) - 1; + + tmp = (calr & RTC_CALR_CENT_MASK) >> RTC_CALR_CENT_SHIFT; + cent = rtc_bcd2bin(tmp); + tmp = (calr & RTC_CALR_YEAR_MASK) >> RTC_CALR_YEAR_SHIFT; + year = rtc_bcd2bin(tmp); + tp->tm_year = cent * 100 + year - 1900; + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + uint32_t regval; + uint32_t timr; + uint32_t calr; + uint32_t cent; + uint32_t year; + + /* Break out the time values (note that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + rtc_dumptime(&newtime, "Setting time"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. + * + * struct tm TIMR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + timr = (rtc_bin2bcd(newtime.tm_sec) << RTC_TIMR_SEC_SHIFT) & RTC_TIMR_SEC_MASK; + timr |= (rtc_bin2bcd(newtime.tm_min) << RTC_TIMR_MIN_SHIFT) & RTC_TIMR_MIN_MASK; + timr |= (rtc_bin2bcd(newtime.tm_hour) << RTC_TIMR_HOUR_SHIFT) & RTC_TIMR_HOUR_MASK; + + /* Convert the struct tm format to RTC date register fields. + * + * struct tm CALR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported. Set to Monday. + */ + + calr = (rtc_bin2bcd(newtime.tm_mday) << RTC_CALR_DATE_SHIFT) & RTC_CALR_DATE_MASK; + calr |= (rtc_bin2bcd(1) << RTC_CALR_DAY_SHIFT) & RTC_CALR_DAY_MASK; + calr |= (rtc_bin2bcd(newtime.tm_mon+1) << RTC_CALR_MONTH_SHIFT) & RTC_CALR_MONTH_MASK; + + cent = newtime.tm_year / 100 + 19; + year = newtime.tm_year % 100; + + calr |= (rtc_bin2bcd(year) << RTC_CALR_YEAR_SHIFT) & RTC_CALR_YEAR_MASK; + calr |= (rtc_bin2bcd(cent) << RTC_CALR_CENT_SHIFT) & RTC_CALR_CENT_MASK; + + /* Stop RTC time and date counting */ + + regval = getreg32(SAM_RTC_CR); + regval |= (RTC_CR_UPDTIM | RTC_CR_UPDCAL); + putreg32(regval, SAM_RTC_CR); + + /* Wait until the RTC has stopped so that we can update the time */ + + while ((getreg32(SAM_RTC_SR) & RTC_SR_ACKUPD) != RTC_SR_ACKUPD); + + /* Clear the ACKUPD bit in the status register */ + + putreg32(RTC_SCCR_ACKCLR, SAM_RTC_SCCR); + + /* Set the new date */ + + putreg32(calr, SAM_RTC_CALR); + + /* Write the new time */ + + putreg32(timr, SAM_RTC_TIMR); + + /* Resume RTC date/time counting */ + + regval = getreg32(SAM_RTC_CR); + regval &= ~(RTC_CR_UPDTIM | RTC_CR_UPDCAL); + putreg32(regval, SAM_RTC_CR); + + /* Clear the SEC status in the SR */ + + regval = getreg32(SAM_RTC_SCCR); + regval = RTC_SCCR_SECCLR; + putreg32(regval, SAM_RTC_SCCR); + + /* The RTC should now be enabled */ + + g_rtc_enabled = ((getreg32(SAM_RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL)) == 0); + DEBUGASSERT(g_rtc_enabled); + + rtc_dumpregs("New time setting"); + return OK; +} + +/************************************************************************************ + * Name: sam_rtc_setalarm + * + * Description: + * Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B). + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int sam_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + FAR struct tm newalarm; + irqstate_t flags; + uint32_t timalr; + uint32_t calalr; + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + flags = enter_critical_section(); + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Clear any pending alarm interrupts */ + + putreg32(RTC_SCCR_ALRCLR, SAM_RTC_SCCR); + + /* Break out the time values (note that the time is set only to units + * of seconds) + */ + + (void)gmtime_r(&tp->tv_sec, &newalarm); + rtc_dumptime(&newalarm, "Setting alarm"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. + * + * struct tm TIMALR register + * tm_sec 0-61* SEC (0-59) + * tm_min 0-59 MIN (0-59) + * tm_hour 0-23 HOUR (0-23) + * + * *To allow for leap seconds. But these never actuall happen. + */ + + timalr = (rtc_bin2bcd(newalarm.tm_sec) << RTC_TIMALR_SEC_SHIFT) & RTC_TIMALR_SEC_MASK; + timalr |= (rtc_bin2bcd(newalarm.tm_min) << RTC_TIMALR_MIN_SHIFT) & RTC_TIMALR_MIN_MASK; + timalr |= (rtc_bin2bcd(newalarm.tm_hour) << RTC_TIMALR_HOUR_SHIFT) & RTC_TIMALR_HOUR_MASK; + timalr |= (RTC_TIMALR_SECEN | RTC_TIMALR_MINEN | RTC_TIMALR_HOUREN); + + /* Convert the struct tm format to RTC date register fields. + * + * struct tm CALALR register + * tm_mday 1-31 DATE (1-31) + * tm_wday 0-6 DAY (1-7) ** + * tm_mon 0-11 MONTH: (1-12) + * tm_year * YEAR (0-99) + * CENT (19-20) + * + * *Years since 1900 + * **Day of the week is not supported + */ + + calalr = (rtc_bin2bcd(newalarm.tm_mday) << RTC_CALALR_DATE_SHIFT) & RTC_CALALR_DATE_MASK; + calalr |= (rtc_bin2bcd(newalarm.tm_mon+1) << RTC_CALALR_MONTH_SHIFT) & RTC_CALALR_MONTH_MASK; + calalr |= (RTC_CALALR_MTHEN | RTC_CALALR_DATEEN); + + /* Set the new date */ + + putreg32(calalr, SAM_RTC_CALALR); + + /* Write the new time */ + + putreg32(timalr, SAM_RTC_TIMALR); + + DEBUGASSERT((getreg32(SAM_RTC_VER) & RTC_VER_NVTIMALR) == 0); + DEBUGASSERT((getreg32(SAM_RTC_VER) & RTC_VER_NVCALALR) == 0); + + rtc_dumpregs("New alarm setting"); + + /* Enable alarm interrupts */ + + putreg32(RTC_IER_ALREN, SAM_RTC_IER); + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +#endif /* CONFIG_RTC */ + diff --git a/arch/arm/src/sama5/sam_rtc.h b/arch/arm/src/sama5/sam_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..bb97c5ea566cb3e0adf66c67c44bebf5a533e377 --- /dev/null +++ b/arch/arm/src/sama5/sam_rtc.h @@ -0,0 +1,104 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_rtc.h + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_RTC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_RTC_H + +#include + +#include "chip.h" +#include "chip/sam_rtc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* The form of an alarm callback */ + +typedef void (*alarmcb_t)(void); + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct timespec; +int sam_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_RTC_H */ diff --git a/arch/arm/src/sama5/sam_sckc.c b/arch/arm/src/sama5/sam_sckc.c new file mode 100644 index 0000000000000000000000000000000000000000..e416aebd8db2e3070a7ee1ea1c81fbfb03e98be7 --- /dev/null +++ b/arch/arm/src/sama5/sam_sckc.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_sckc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "sam_sckc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_sckc_enable + * + * Description: + * Enable or disable the slow clock oscillator driver by an external + * crystal. + * + * Input Parameters: + * enable - True: enable the slow clock, False: disable the slow clock + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_sckc_enable(bool enable) +{ + uint32_t regval; + +#ifdef ATSAMA5D3 + /* REVISIT: Missing the logic that disables the external OSC32 */ + /* Enable external OSC 32 kHz */ + + regval = getreg32(SAM_SCKC_CR); + regval |= SCKC_CR_OSC32EN; + putreg32(regval, SAM_SCKC_CR); + + /* Wait for 32,768 XTAL start-up time */ + + up_udelay(5 * USEC_PER_SEC / BOARD_SLOWCLK_FREQUENCY); + + /* Disable OSC 32 kHz bypass */ + + regval &= ~SCKC_CR_OSC32BYP; + putreg32(regval, SAM_SCKC_CR); + + /* Switch slow clock source to external OSC 32 kHz */ + + regval |= SCKC_CR_OSCSEL; + putreg32(regval, SAM_SCKC_CR); + + /* Wait 5 slow clock cycles for internal resynchronization */ + + up_udelay(5 * USEC_PER_SEC / BOARD_SLOWCLK_FREQUENCY); + + /* Disable internal RC 32 kHz */ + + regval &= ~SCKC_CR_RCEN; + putreg32(regval, SAM_SCKC_CR); + +#else + /* Switch slow clock source to external OSC 32 kHz */ + + regval = enable ? SCKC_CR_OSCSEL : 0; + putreg32(regval, SAM_SCKC_CR); + + /* Wait 5 slow clock cycles for internal resynchronization */ + + up_udelay(5 * USEC_PER_SEC / BOARD_SLOWCLK_FREQUENCY); +#endif +} diff --git a/arch/arm/src/sama5/sam_sckc.h b/arch/arm/src/sama5/sam_sckc.h new file mode 100644 index 0000000000000000000000000000000000000000..0dc2a2ed4cea2b0dd8ee6df7760aca1961268232 --- /dev/null +++ b/arch/arm/src/sama5/sam_sckc.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_sckc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_SCKC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_SCKC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/sam_sckc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_sckc_enable + * + * Description: + * Enable or disable the slow clock oscillator driver by an external + * crystal. + * + * Input Parameters: + * enable - True: enable the slow clock, False: disable the slow clock + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_sckc_enable(bool enable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_SCKC_H */ diff --git a/arch/arm/src/sama5/sam_serial.c b/arch/arm/src/sama5/sam_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..0083606dba16f2a6abcb846333551ca264dc8855 --- /dev/null +++ b/arch/arm/src/sama5/sam_serial.c @@ -0,0 +1,1790 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_serial.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "chip/sam_uart.h" +#include "sam_config.h" +#include "sam_dbgu.h" +#include "sam_serial.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +#undef TTYS0_DEV +#undef TTYS1_DEV +#undef TTYS2_DEV +#undef TTYS3_DEV +#undef TTYS4_DEV +#undef TTYS5_DEV +#undef TTYS6_DEV +#undef TTYS7_DEV +#undef TTYS8_DEV +#undef TTYS9_DEV + +#undef UART0_ASSIGNED +#undef UART1_ASSIGNED +#undef UART2_ASSIGNED +#undef UART3_ASSIGNED +#undef UART4_ASSIGNED +#undef USART0_ASSIGNED +#undef USART1_ASSIGNED +#undef USART2_ASSIGNED +#undef USART3_ASSIGNED +#undef USART4_ASSIGNED + +#if defined(SAMA5_HAVE_UART) || defined(SAMA5_HAVE_USART) + +/* Which UART/USART with be ttyS0/console and which ttyS1? ttyS2? ttyS3? ... + * ttyS9? + */ + +/* First pick the console and ttyS0. This could be any of UART0-4, + * USART0-4. + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART2 is console */ +# define TTYS0_DEV g_uart1port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART3 is console */ +# define TTYS0_DEV g_uart1port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART4 is console */ +# define TTYS0_DEV g_uart1port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart3port /* USART3 is console */ +# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart4port /* USART4 is console */ +# define TTYS0_DEV g_usart4port /* USART4 is ttyS0 */ +# define USART4_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_SAMA5_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_SAMA5_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_SAMA5_UART2) +# define TTYS0_DEV g_uart1port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_SAMA5_UART3) +# define TTYS0_DEV g_uart1port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_SAMA5_UART4) +# define TTYS0_DEV g_uart1port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_USART0_ISUART) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +# elif defined(CONFIG_USART1_ISUART) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +# elif defined(CONFIG_USART2_ISUART) +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +# elif defined(CONFIG_USART3_ISUART) +# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */ +# define USART3_ASSIGNED 1 +# elif defined(CONFIG_USART4_ISUART) +# define TTYS0_DEV g_usart4port /* USART4 is ttyS0 */ +# define USART4_ASSIGNED 4 +# endif +#endif + +/* Pick ttyS1. This could be any of UART0-4, USART0-4 excluding the console UART. */ + +#if defined(CONFIG_SAMA5_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS1_DEV g_usart3port /* USART3 is ttyS1 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS1_DEV g_usart4port /* USART4 is ttyS1 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS2. This could be one of UART1-4 or USART0-4. It can't be UART0 + * because that was either assigned as ttyS0 or ttyS1. One of these + * could also be the console. + */ + +#if defined(CONFIG_SAMA5_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS2_DEV g_usart0port /* USART0 is ttyS2 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS2_DEV g_usart3port /* USART3 is ttyS2 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS2_DEV g_usart4port /* USART4 is ttyS2 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS3. This could be one of UART2-4 or USART0-4. It can't be + * UART0-1; those have already been assigned to ttyS0, 1, or 2. One of + * UART2-4 or USART0-4 could also be the console. + */ + +#if defined(CONFIG_SAMA5_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart1port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart1port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart1port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS3_DEV g_usart0port /* USART0 is ttyS3 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS3_DEV g_usart1port /* USART1 is ttyS3 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS3_DEV g_usart3port /* USART3 is ttyS3 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS3_DEV g_usart4port /* USART4 is ttyS3 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS4. This could be one of UART3-4 or USART0-4. It can't be + * UART0-2; those have already been assigned to ttyS0-3. One of + * UART3-4 or USART0-4 could also be the console. + */ + +#if defined(CONFIG_SAMA5_UART3) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart1port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMA5_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart1port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS4_DEV g_usart0port /* USART0 is ttyS4 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS4_DEV g_usart1port /* USART1 is ttyS4 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS4_DEV g_usart2port /* USART2 is ttyS4 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS4_DEV g_usart3port /* USART3 is ttyS4 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS4_DEV g_usart4port /* USART4 is ttyS4 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS5. This could be one of UART4 or USART0-4. It can't be + * UART0-3; those have already been assigned to ttyS0-4. One of + * UART4 or USART0-4 could also be the console. + */ + +#if defined(CONFIG_SAMA5_UART4) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS5_DEV g_usart0port /* USART0 is ttyS5 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS5_DEV g_usart1port /* USART1 is ttyS5 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS5_DEV g_usart2port /* USART2 is ttyS5 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS5_DEV g_usart3port /* USART3 is ttyS5 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS5_DEV g_usart4port /* USART4 is ttyS5 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS6. This could be one of USART0-4. It can't be UART0-4; + * those have already been assigned to ttyS0-5. One of USART0-4 + * could also be the console. + */ + +#if defined(CONFIG_USART0_ISUART) && !defined(USART0_ASSIGNED) +# define TTYS6_DEV g_usart0port /* USART0 is ttyS6 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS6_DEV g_usart1port /* USART1 is ttyS6 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS6_DEV g_usart2port /* USART2 is ttyS6 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS6_DEV g_usart3port /* USART3 is ttyS6 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS6_DEV g_usart4port /* USART4 is ttyS6 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS7. This could be one of USART1-4. It can't be UART0-4 + * or USART0; those have already been assigned to ttyS0-5. One of + * USART1-4 could also be the console. + */ + +#if defined(CONFIG_USART1_ISUART) && !defined(USART1_ASSIGNED) +# define TTYS7_DEV g_usart1port /* USART1 is ttyS7 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS7_DEV g_usart2port /* USART2 is ttyS7 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS7_DEV g_usart3port /* USART3 is ttyS7 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS7_DEV g_usart4port /* USART4 is ttyS7 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS8. This could be one of USART2-4. It can't be UART0-4 + * or USART0-1; those have already been assigned to ttyS0-5. One of + * USART2-4 could also be the console. + */ + +#if defined(CONFIG_USART2_ISUART) && !defined(USART2_ASSIGNED) +# define TTYS8_DEV g_usart2port /* USART2 is ttyS8 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS8_DEV g_usart3port /* USART3 is ttyS8 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS8_DEV g_usart4port /* USART4 is ttyS8 */ +# define USART4_ASSIGNED 1 +#endif + +/* Pick ttyS9. This could be one of USART3-4. It can't be UART0-4 + * or USART0-2; those have already been assigned to ttyS0-8. One of + * USART3-4 could also be the console. + */ + +#if defined(CONFIG_USART3_ISUART) && !defined(USART3_ASSIGNED) +# define TTYS9_DEV g_usart3port /* USART3 is ttyS9 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_ISUART) && !defined(USART4_ASSIGNED) +# define TTYS9_DEV g_usart4port /* USART4 is ttyS9 */ +# define USART4_ASSIGNED 1 +#endif + +/* The UART/USART modules are driven by the peripheral clock (MCK or MCK2). */ + +#define SAM_USART_CLOCK BOARD_USART_FREQUENCY /* Frequency of the USART clock */ +#define SAM_MR_USCLKS UART_MR_USCLKS_MCK /* Source = Main clock */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + xcpt_t handler; /* Interrupt handler */ + uint32_t usartbase; /* Base address of USART registers */ + uint32_t baud; /* Configured baud */ + uint32_t sr; /* Saved status bits */ + uint8_t irq; /* IRQ associated with this USART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; /* input flow control (RTS) enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_SAMA5_UART0 +static int up_uart0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_UART1 +static int up_uart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_UART2 +static int up_uart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_UART3 +static int up_uart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_UART4 +static int up_uart4_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART0_ISUART +static int up_usart0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART1_ISUART +static int up_usart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART2_ISUART +static int up_usart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART3_ISUART +static int up_usart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_USART4_ISUART +static int up_usart4_interrupt(int irq, void *context); +#endif + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_SAMA5_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMA5_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMA5_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMA5_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMA5_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART0_ISUART +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART1_ISUART +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART2_ISUART +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART3_ISUART +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_USART4_ISUART +static char g_usart4rxbuffer[CONFIG_USART4_RXBUFSIZE]; +static char g_usart4txbuffer[CONFIG_USART4_TXBUFSIZE]; +#endif + +/* This describes the state of the UART0 port. */ + +#ifdef CONFIG_SAMA5_UART0 +# if CONFIG_UART0_BITS == 8 && CONFIG_UART0_PARITY == 0 +# elif CONFIG_UART0_BITS == 7 && CONFIG_UART0_PARITY != 0 +# else +# error "Unsupported combination of bits and parity for UART0" +# endif + +# if CONFIG_UART0_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART0" +# endif + +static struct up_dev_s g_uart0priv = +{ + .handler = up_uart0_interrupt, + .usartbase = SAM_UART0_VBASE, + .baud = CONFIG_UART0_BAUD, + .irq = SAM_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the UART1 port. */ + +#ifdef CONFIG_SAMA5_UART1 +# if CONFIG_UART1_BITS == 8 && CONFIG_UART1_PARITY == 0 +# elif CONFIG_UART1_BITS == 7 && CONFIG_UART1_PARITY != 0 +# else +# error "Unsupported combination of bits and parity for UART1" +# endif + +# if CONFIG_UART1_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART1" +# endif + +static struct up_dev_s g_uart1priv = +{ + .handler = up_uart1_interrupt, + .usartbase = SAM_UART1_VBASE, + .baud = CONFIG_UART1_BAUD, + .irq = SAM_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the UART2 port. */ + +#ifdef CONFIG_SAMA5_UART2 +# if CONFIG_UART2_BITS == 8 && CONFIG_UART2_PARITY == 0 +# elif CONFIG_UART2_BITS == 7 && CONFIG_UART2_PARITY != 0 +# else +# error "Unsupported combination of bits and parity for UART2" +# endif + +# if CONFIG_UART2_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART2" +# endif + +static struct up_dev_s g_uart2priv = +{ + .handler = up_uart2_interrupt, + .usartbase = SAM_UART2_VBASE, + .baud = CONFIG_UART2_BAUD, + .irq = SAM_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the UART3 port. */ + +#ifdef CONFIG_SAMA5_UART3 +# if CONFIG_UART3_BITS == 8 && CONFIG_UART3_PARITY == 0 +# elif CONFIG_UART3_BITS == 7 && CONFIG_UART3_PARITY != 0 +# else +# error "Unsupported combination of bits and parity for UART3" +# endif + +# if CONFIG_UART3_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART3" +# endif + +static struct up_dev_s g_uart3priv = +{ + .handler = up_uart3_interrupt, + .usartbase = SAM_UART3_VBASE, + .baud = CONFIG_UART3_BAUD, + .irq = SAM_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the UART4 port. */ + +#ifdef CONFIG_SAMA5_UART4 +# if CONFIG_UART4_BITS == 8 && CONFIG_UART4_PARITY == 0 +# elif CONFIG_UART4_BITS == 7 && CONFIG_UART4_PARITY != 0 +# else +# error "Unsupported combination of bits and parity for UART4" +# endif + +# if CONFIG_UART4_2STOP != 0 +# error "Unsupported number of stop bits and parity for UART4" +# endif + +static struct up_dev_s g_uart4priv = +{ + .handler = up_uart4_interrupt, + .usartbase = SAM_UART4_VBASE, + .baud = CONFIG_UART4_BAUD, + .irq = SAM_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the USART0 port. */ + +#ifdef CONFIG_USART0_ISUART +static struct up_dev_s g_usart0priv = +{ + .handler = up_usart0_interrupt, + .usartbase = SAM_USART0_VBASE, + .baud = CONFIG_USART0_BAUD, + .irq = SAM_IRQ_USART0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +#if defined(CONFIG_USART0_OFLOWCONTROL) || defined(CONFIG_USART0_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the USART1 port. */ + +#ifdef CONFIG_USART1_ISUART +static struct up_dev_s g_usart1priv = +{ + .handler = up_usart1_interrupt, + .usartbase = SAM_USART1_VBASE, + .baud = CONFIG_USART1_BAUD, + .irq = SAM_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, +#if defined(CONFIG_USART1_OFLOWCONTROL) || defined(CONFIG_USART1_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the USART2 port. */ + +#ifdef CONFIG_USART2_ISUART +static struct up_dev_s g_usart2priv = +{ + .handler = up_usart2_interrupt, + .usartbase = SAM_USART2_VBASE, + .baud = CONFIG_USART2_BAUD, + .irq = SAM_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +#if defined(CONFIG_USART2_OFLOWCONTROL) || defined(CONFIG_USART2_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/* This describes the state of the USART3 port. */ + +#ifdef CONFIG_USART3_ISUART +static struct up_dev_s g_usart3priv = +{ + .handler = up_usart3_interrupt, + .usartbase = SAM_USART3_VBASE, + .baud = CONFIG_USART3_BAUD, + .irq = SAM_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, +#if defined(CONFIG_USART3_OFLOWCONTROL) || defined(CONFIG_USART3_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart3port = +{ + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart3priv, +}; +#endif + +/* This describes the state of the USART4 port. */ + +#ifdef CONFIG_USART4_ISUART +static struct up_dev_s g_usart4priv = +{ + .handler = up_usart4_interrupt, + .usartbase = SAM_USART4_VBASE, + .baud = CONFIG_USART4_BAUD, + .irq = SAM_IRQ_USART4, + .parity = CONFIG_USART4_PARITY, + .bits = CONFIG_USART4_BITS, + .stopbits2 = CONFIG_USART4_2STOP, +#if defined(CONFIG_USART4_OFLOWCONTROL) || defined(CONFIG_USART4_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart4port = +{ + .recv = + { + .size = CONFIG_USART4_RXBUFSIZE, + .buffer = g_usart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART4_TXBUFSIZE, + .buffer = g_usart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart4priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static inline void up_restoreusartint(struct up_dev_s *priv, uint32_t imr) +{ + /* Restore the previous interrupt state (assuming all interrupts disabled) */ + + up_serialout(priv, SAM_UART_IER_OFFSET, imr); +} + +/**************************************************************************** + * Name: up_disableallints + ****************************************************************************/ + +static void up_disableallints(struct up_dev_s *priv, uint32_t *imr) +{ + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + + /* Return the current interrupt state */ + + if (imr) + { + *imr = up_serialin(priv, SAM_UART_IMR_OFFSET); + } + + /* Disable all interrupts */ + + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_ALLINTS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the common USART interrupt handler. It should call + * uart_transmitchars or uart_receivechar to perform the appropriate + * data transfers. + * + ****************************************************************************/ + +static int up_interrupt(struct uart_dev_s *dev) +{ + struct up_dev_s *priv; + uint32_t pending; + uint32_t imr; + int passes; + bool handled; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the UART/USART status (we are only interested in the unmasked interrupts). */ + + priv->sr = up_serialin(priv, SAM_UART_SR_OFFSET); /* Save for error reporting */ + imr = up_serialin(priv, SAM_UART_IMR_OFFSET); /* Interrupt mask */ + pending = priv->sr & imr; /* Mask out disabled interrupt sources */ + + /* Handle an incoming, receive byte. RXRDY: At least one complete character + * has been received and US_RHR has not yet been read. + */ + + if ((pending & UART_INT_RXRDY) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes. XRDY: There is no character in the + * US_THR. + */ + + if ((pending & UART_INT_TXRDY) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +#ifdef CONFIG_SAMA5_UART0 +static int up_uart0_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart0port); +} +#endif +#ifdef CONFIG_SAMA5_UART1 +static int up_uart1_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart1port); +} +#endif +#ifdef CONFIG_SAMA5_UART2 +static int up_uart2_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart2port); +} +#endif +#ifdef CONFIG_SAMA5_UART3 +static int up_uart3_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart3port); +} +#endif +#ifdef CONFIG_SAMA5_UART4 +static int up_uart4_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart4port); +} +#endif +#ifdef CONFIG_USART0_ISUART +static int up_usart0_interrupt(int irq, void *context) +{ + return up_interrupt(&g_usart0port); +} +#endif +#ifdef CONFIG_USART1_ISUART +static int up_usart1_interrupt(int irq, void *context) +{ + return up_interrupt(&g_usart1port); +} +#endif +#ifdef CONFIG_USART2_ISUART +static int up_usart2_interrupt(int irq, void *context) +{ + return up_interrupt(&g_usart2port); +} +#endif +#ifdef CONFIG_USART3_ISUART +static int up_usart3_interrupt(int irq, void *context) +{ + return up_interrupt(&g_usart3port); +} +#endif +#ifdef CONFIG_USART4_ISUART +static int up_usart4_interrupt(int irq, void *context) +{ + return up_interrupt(&g_usart4port); +} +#endif + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled and the pins were configured in sam_lowsetup(). + */ + + /* The shutdown method will put the UART in a known, disabled state */ + + up_shutdown(dev); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + /* "Setting the USART to operate with hardware handshaking is performed by + * writing the USART_MODE field in the Mode Register (US_MR) to the value + * 0x2. ... Using this mode requires using the PDC or DMAC channel for + * reception. The transmitter can handle hardware handshaking in any case." + */ + + if (priv->flowc) + { + /* Enable hardware flow control and MCK as the timing source */ + + regval = (UART_MR_MODE_HWHS | SAM_MR_USCLKS | UART_MR_CHMODE_NORMAL); + } + else +#endif + { +#if defined(ATSAMA5D2) + /* Set up the mode register. Start with normal UART mode and the + * peripheral clock as the timing source + */ + + regval = (UART_MR_PERIPHCLK | UART_MR_CHMODE_NORMAL); + +#elif defined(ATSAMA5D3) || defined(ATSAMA5D4) + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source + */ + + regval = (UART_MR_MODE_NORMAL | SAM_MR_USCLKS | UART_MR_CHMODE_NORMAL); +#endif + } + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) + /* OR in settings for the selected number of bits */ + + if (priv->bits == 5) + { + regval |= UART_MR_CHRL_5BITS; /* 5 bits */ + } + else if (priv->bits == 6) + { + regval |= UART_MR_CHRL_6BITS; /* 6 bits */ + } + else if (priv->bits == 7) + { + regval |= UART_MR_CHRL_7BITS; /* 7 bits */ + } +#ifdef SAMA5_HAVE_USART + else if (priv->bits == 9 +#if defined(CONFIG_SAMA5_UART0) + && priv->usartbase != SAM_UART0_VBASE +#endif +#if defined(CONFIG_SAMA5_UART1) + && priv->usartbase != SAM_UART1_VBASE +#endif +#if defined(CONFIG_SAMA5_UART2) +# warning REVIST +#endif +#if defined(CONFIG_SAMA5_UART3) +# warning REVIST +#endif +#if defined(CONFIG_SAMA5_UART4) +# warning REVIST +#endif + ) + { + regval |= UART_MR_MODE9; /* 9 bits */ + } +#endif + else /* if (priv->bits == 8) */ + { + regval |= UART_MR_CHRL_8BITS; /* 8 bits (default) */ + } +#endif /* ATSAMA5D3 || ATSAMA5D4 */ + + /* OR in settings for the selected parity */ + + if (priv->parity == 1) + { + regval |= UART_MR_PAR_ODD; + } + else if (priv->parity == 2) + { + regval |= UART_MR_PAR_EVEN; + } + else + { + regval |= UART_MR_PAR_NONE; + } + +#if defined(ATSAMA5D3) || defined(ATSAMA5D4) + /* OR in settings for the number of stop bits */ + + if (priv->stopbits2) + { + regval |= UART_MR_NBSTOP_2; + } + else + { + regval |= UART_MR_NBSTOP_1; + } +#endif /* ATSAMA5D3 || ATSAMA5D4 */ + + /* And save the new mode register value */ + + up_serialout(priv, SAM_UART_MR_OFFSET, regval); + + /* Configure the console baud. NOTE: Oversampling by 8 is not supported. + * This may limit BAUD rates for lower USART clocks. + */ + + regval = (SAM_USART_CLOCK + (priv->baud << 3)) / (priv->baud << 4); + up_serialout(priv, SAM_UART_BRGR_OFFSET, regval); + + /* Enable receiver & transmitter */ + + up_serialout(priv, SAM_UART_CR_OFFSET, (UART_CR_RXEN | UART_CR_TXEN)); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Reset and disable receiver and transmitter */ + + up_serialout(priv, SAM_UART_CR_OFFSET, + (UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | + UART_CR_TXDIS)); + + /* Disable all interrupts */ + + up_disableallints(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Return baud */ + + cfsetispeed(termiosp, priv->baud); + + /* Return parity */ + + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; + + /* Return flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= (priv->flowc) ? (CCTS_OFLOW | CRTS_IFLOW): 0; +#endif + /* Return number of bits */ + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + default: + case 8: + termiosp->c_cflag |= CS8; + break; + + case 9: + termiosp->c_cflag |= CS8 /* CS9 */; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t baud; + uint32_t imr; + uint8_t parity; + uint8_t nbits; + bool stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; +#endif + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Decode baud. */ + + ret = OK; + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + nbits = 5; + break; + + case CS6: + nbits = 6; + break; + + case CS7: + nbits = 7; + break; + + case CS8: + nbits = 8; + break; +#if 0 + case CS9: + nbits = 9; + break; +#endif + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) != 0; + + /* Decode flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + flowc = (termiosp->c_cflag & (CCTS_OFLOW | CRTS_IFLOW)) != 0; +#endif + /* Verify that all settings are valid before committing */ + + if (ret == OK) + { + /* Commit */ + + priv->baud = baud; + priv->parity = parity; + priv->bits = nbits; + priv->stopbits2 = stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flowc = flowc; +#endif + /* Effect the changes immediately - note that we do not + * implement TCSADRAIN / TCSAFLUSH + */ + + up_disableallints(priv, &imr); + ret = up_setup(dev); + + /* Restore the interrupt state */ + + up_restoreusartint(priv, imr); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return the error information in the saved status */ + + *status = priv->sr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return (int)(up_serialin(priv, SAM_UART_RHR_OFFSET) & 0xff); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_RXRDY); +#endif + } + else + { + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_RXRDY); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_RXRDY) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART/USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, SAM_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_TXRDY); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + +#endif + } + else + { + /* Disable the TX interrupt */ + + up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_TXRDY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXRDY) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +void uart_earlyserialinit(void) +{ + /* NOTE: All PIO configuration for the USARTs was performed in + * sam_lowsetup + */ + + /* Disable all USARTS */ + +#ifdef TTYS0_DEV + up_disableallints(TTYS0_DEV.priv, NULL); +#endif +#ifdef TTYS1_DEV + up_disableallints(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + up_disableallints(TTYS2_DEV.priv, NULL); +#endif +#ifdef TTYS3_DEV + up_disableallints(TTYS3_DEV.priv, NULL); +#endif +#ifdef TTYS4_DEV + up_disableallints(TTYS4_DEV.priv, NULL); +#endif +#ifdef TTYS5_DEV + up_disableallints(TTYS5_DEV.priv, NULL); +#endif +#ifdef TTYS6_DEV + up_disableallints(TTYS6_DEV.priv, NULL); +#endif +#ifdef TTYS7_DEV + up_disableallints(TTYS7_DEV.priv, NULL); +#endif +#ifdef TTYS8_DEV + up_disableallints(TTYS8_DEV.priv, NULL); +#endif +#ifdef TTYS9_DEV + up_disableallints(TTYS9_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#if defined(SAMA5_HAVE_UART_CONSOLE) || defined(SAMA5_HAVE_USART_CONSOLE) + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: uart_serialinit + * + * Description: + * Register UART/USART serial console and serial ports. This assumes that + * uart_earlyserialinit was called previously. + * + ****************************************************************************/ + +void uart_serialinit(void) +{ + /* Register the console */ + +#if defined(SAMA5_HAVE_UART_CONSOLE) || defined(SAMA5_HAVE_USART_CONSOLE) + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs/USARTs */ + +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +#ifdef TTYS6_DEV + (void)uart_register("/dev/ttyS6", &TTYS6_DEV); +#endif +#ifdef TTYS7_DEV + (void)uart_register("/dev/ttyS7", &TTYS7_DEV); +#endif +#ifdef TTYS8_DEV + (void)uart_register("/dev/ttyS8", &TTYS8_DEV); +#endif +#ifdef TTYS9_DEV + (void)uart_register("/dev/ttyS9", &TTYS9_DEV); +#endif +} + +#endif /* SAMA5_HAVE_UART || SAMA5_HAVE_USART */ +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/sama5/sam_serial.h b/arch/arm/src/sama5/sam_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..63cb5ab792f99698d863aeb2b365e1c2e2d65c4f --- /dev/null +++ b/arch/arm/src/sama5/sam_serial.h @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_serial.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_SERIAL_H +#define __ARCH_ARM_SRC_SAMA5_SAM_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" +#include "sam_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void sam_earlyserialinit(void); +#endif + +/**************************************************************************** + * Name: uart_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#if defined(USE_EARLYSERIALINIT) && (defined(SAMA5_HAVE_UART) || defined(SAMA5_HAVE_USART)) +void uart_earlyserialinit(void); +#endif + +/**************************************************************************** + * Name: flexus_earlyserialinit + * + * Description: + * Performs the low level Flexcom USART initialization early so that the + * Flexcom serial console will be available during bootup. This must be + * called before flexus_serialinit. + * + ****************************************************************************/ + +#if defined(USE_EARLYSERIALINIT) && defined(SAMA5_HAVE_FLEXCOM_USART) +void flexus_earlyserialinit(void); +#endif + +/**************************************************************************** + * Name: uart_serialinit + * + * Description: + * Register UART/USART serial console and serial ports. This assumes that + * uart_earlyserialinit was called previously. + * + ****************************************************************************/ + +#if defined(SAMA5_HAVE_UART) || defined(SAMA5_HAVE_USART) +void uart_serialinit(void); +#endif + +/**************************************************************************** + * Name: flexus_serialinit + * + * Description: + * Register Flexcom serial console and serial ports. This assumes that + * flexus_earlyserialinit was called previously. + * + ****************************************************************************/ + +#if defined(USE_EARLYSERIALINIT) && defined(SAMA5_HAVE_FLEXCOM_USART) +void flexus_serialinit(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_SERIAL_H */ diff --git a/arch/arm/src/sama5/sam_serialinit.c b/arch/arm/src/sama5/sam_serialinit.c new file mode 100644 index 0000000000000000000000000000000000000000..59c25ed285f8da6ec5396f8835d0ee90a2de5785 --- /dev/null +++ b/arch/arm/src/sama5/sam_serialinit.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_serialinit.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" +#include "sam_dbgu.h" +#include "sam_serial.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_earlyserialinit + * + * Description: + * Performs the low level serial initialization early so that the serial + * console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +void sam_earlyserialinit(void) +{ + /* NOTE: All PIO configuration for the USARTs was performed in + * sam_lowsetup + */ + +#if defined(SAMA5_HAVE_UART) || defined(SAMA5_HAVE_USART) + /* Initialize UART/USART drivers */ + + uart_earlyserialinit(); +#endif + +#ifdef SAMA5_HAVE_FLEXCOM_USART + /* Initialize Flexcom USARTs */ + + flexus_earlyserialinit(); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register all serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#if defined(SAMA5_HAVE_UART) || defined(SAMA5_HAVE_USART) + /* Register UART/USART drivers */ + + uart_serialinit(); +#endif + +#ifdef SAMA5_HAVE_FLEXCOM_USART + /* Register Flexcom USART drivers */ + + flexus_serialinit(); +#endif + + /* Register the DBGU as well */ + +#ifdef CONFIG_SAMA5_DBGU + sam_dbgu_register(); +#endif +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/sama5/sam_spi.c b/arch/arm/src/sama5/sam_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..2d370fe7a94175451a6f61cf4d598c9e92d360ab --- /dev/null +++ b/arch/arm/src/sama5/sam_spi.c @@ -0,0 +1,1859 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_spi.c + * + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * This derives from SAM3/4 SPI driver: + * + * Authors: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_pio.h" +#include "sam_dmac.h" +#include "sam_memories.h" +#include "sam_periphclks.h" +#include "sam_spi.h" +#include "chip/sam_pmc.h" +#include "chip/sam_spi.h" +#include "chip/sam_pinmap.h" + +#if defined(CONFIG_SAMA5_SPI0) || defined(CONFIG_SAMA5_SPI1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* When SPI DMA is enabled, small DMA transfers will still be performed by + * polling logic. But we need a threshold value to determine what is small. + * That value is provided by CONFIG_SAMA5_SPI_DMATHRESHOLD. + */ + +#ifndef CONFIG_SAMA5_SPI_DMATHRESHOLD +# define CONFIG_SAMA5_SPI_DMATHRESHOLD 4 +#endif + +#ifdef CONFIG_SAMA5_SPI_DMA + +# if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_DMAC0) +# define SAMA5_SPI0_DMA true +# else +# define SAMA5_SPI0_DMA false +# endif + +# if defined(CONFIG_SAMA5_SPI1) && defined(CONFIG_SAMA5_DMAC1) +# define SAMA5_SPI1_DMA true +# else +# define SAMA5_SPI1_DMA false +# endif +#endif + +#ifndef CONFIG_SAMA5_SPI_DMA +# undef CONFIG_SAMA5_SPI_DMADEBUG +#endif + +/* Clocking *****************************************************************/ +/* Select MCU-specific settings + * + * SPI is driven by the main clock. + */ + +#define SAM_SPI_CLOCK BOARD_MCK_FREQUENCY + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* Debug *******************************************************************/ +/* Check if SPI debut is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_SAMA5_SPI_DMADEBUG +# undef CONFIG_SAMA5_SPI_REGDEBUG +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAMA5_SPI_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the one SPI chip select */ + +struct sam_spics_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ + +#if defined(CONFIG_SAMA5_SPI0) || defined(CONFIG_SAMA5_SPI1) + uint8_t spino; /* SPI controller number (0 or 1) */ +#endif + uint8_t cs; /* Chip select number */ + +#ifdef CONFIG_SAMA5_SPI_DMA + bool candma; /* DMA is supported */ + sem_t dmawait; /* Used to wait for DMA completion */ + WDOG_ID dmadog; /* Watchdog that handles DMA timeouts */ + int result; /* DMA result */ + DMA_HANDLE rxdma; /* SPI RX DMA handle */ + DMA_HANDLE txdma; /* SPI TX DMA handle */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_SPI_DMADEBUG + struct sam_dmaregs_s rxdmaregs[DMA_NSAMPLES]; + struct sam_dmaregs_s txdmaregs[DMA_NSAMPLES]; +#endif +}; + +/* Type of board-specific SPI status fuction */ + +typedef void (*select_t)(enum spi_dev_e devid, bool selected); + +/* Chip select register offsetrs */ + +/* The overall state of one SPI controller */ + +struct sam_spidev_s +{ + uint32_t base; /* SPI controller register base address */ + sem_t spisem; /* Assures mutually exclusive acess to SPI */ + select_t select; /* SPI select callout */ + bool initialized; /* TRUE: Controller has been initialized */ +#ifdef CONFIG_SAMA5_SPI_DMA + uint8_t pid; /* Peripheral ID */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_SPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addresslast; /* Last address */ + uint32_t valuelast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAMA5_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, + uint32_t value, uint32_t address); +#else +# define spi_checkreg(spi,wr,value,address) (false) +#endif + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset); +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset); +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg); +#else +# define spi_dumpregs(spi,msg) +#endif + +static inline void spi_flush(struct sam_spidev_s *spi); +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics); + +/* DMA support */ + +#ifdef CONFIG_SAMA5_SPI_DMA + +#ifdef CONFIG_SAMA5_SPI_DMADEBUG +# define spi_rxdma_sample(s,i) sam_dmasample((s)->rxdma, &(s)->rxdmaregs[i]) +# define spi_txdma_sample(s,i) sam_dmasample((s)->txdma, &(s)->txdmaregs[i]) +static void spi_dma_sampleinit(struct sam_spics_s *spics); +static void spi_dma_sampledone(struct sam_spics_s *spics); + +#else +# define spi_rxdma_sample(s,i) +# define spi_txdma_sample(s,i) +# define spi_dma_sampleinit(s) +# define spi_dma_sampledone(s) + +#endif + +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result); +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t spi_physregaddr(struct sam_spics_s *spics, + unsigned int offset); +#endif + +/* SPI methods */ + +static int spi_lock(struct spi_dev_s *dev, bool lock); +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch); +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, + const void *txbuffer, void *rxbuffer, size_t nwords); +#endif +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, + const void *buffer, size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps chip select numbers (0-3) to CSR register offsets */ + +static const uint8_t g_csroffset[4] = +{ + SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET, + SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET +}; + +#ifdef CONFIG_SAMA5_SPI0 +/* SPI0 driver operations */ + +static const struct spi_ops_s g_spi0ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = sam_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi0dev = +{ + .base = SAM_SPI0_VBASE, + .select = sam_spi0select, +#ifdef CONFIG_SAMA5_SPI_DMA + .pid = SAM_PID_SPI0, +#endif +}; +#endif + +#ifdef CONFIG_SAMA5_SPI1 +/* SPI1 driver operations */ + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi1dev = +{ + .base = SAM_SPI1_VBASE, + .select = sam_spi1select, +#ifdef CONFIG_SAMA5_SPI_DMA + .pid = SAM_PID_SPI1, +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == spi->wrlast && /* Same kind of access? */ + value == spi->valuelast && /* Same value? */ + address == spi->addresslast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + spi->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (spi->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", spi->ntimes); + } + + /* Save information about the new access */ + + spi->wrlast = wr; + spi->valuelast = value; + spi->addresslast = address; + spi->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMA5_SPI_REGDEBUG + if (spi_checkreg(spi, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + +#ifdef CONFIG_SAMA5_SPI_REGDEBUG + if (spi_checkreg(spi, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * spi - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" MR:%08x SR:%08x IMR:%08x\n", + getreg32(spi->base + SAM_SPI_MR_OFFSET), + getreg32(spi->base + SAM_SPI_SR_OFFSET), + getreg32(spi->base + SAM_SPI_IMR_OFFSET)); + spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n", + getreg32(spi->base + SAM_SPI_CSR0_OFFSET), + getreg32(spi->base + SAM_SPI_CSR1_OFFSET), + getreg32(spi->base + SAM_SPI_CSR2_OFFSET), + getreg32(spi->base + SAM_SPI_CSR3_OFFSET)); + spivdbg(" WPCR:%08x WPSR:%08x\n", + getreg32(spi->base + SAM_SPI_WPCR_OFFSET), + getreg32(spi->base + SAM_SPI_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_device + * + * Description: + * Given a chip select instance, return a pointer to the parent SPI + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics) +{ +#if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_SPI1) + return spics->spino ? &g_spi1dev : &g_spi0dev; +#elif defined(CONFIG_SAMA5_SPI0) + return &g_spi0dev; +#else + return &g_spi1dev; +#endif +} + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Make sure that there are now dangling SPI transfer in progress + * + * Input Parameters: + * spi - SPI controller state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_flush(struct sam_spidev_s *spi) +{ + /* Make sure the no TX activity is in progress... waiting if necessary */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TXEMPTY) == 0); + + /* Then make sure that there is no pending RX data .. reading as + * discarding as necessary. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) != 0) + { + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + } +} + +/**************************************************************************** + * Name: spi_cs2pcs + * + * Description: + * Map the chip select number to the bit-set PCS field used in the SPI + * registers. A chip select number is used for indexing and identifying + * chip selects. However, the chip select information is represented by + * a bit set in the SPI regsisters. This function maps those chip select + * numbers to the correct bit set: + * + * CS Returned Spec Effective + * No. PCS Value NPCS + * ---- -------- -------- -------- + * 0 0000 xxx0 1110 + * 1 0001 xx01 1101 + * 2 0011 x011 1011 + * 3 0111 0111 0111 + * + * Input Parameters: + * spics - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics) +{ + return ((uint32_t)1 << (spics->cs)) - 1; +} + +/**************************************************************************** + * Name: spi_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMA5_SPI_DMADEBUG) + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMADEBUG +static void spi_dma_sampleinit(struct sam_spics_s *spics) +{ + /* Put contents of register samples into a known state */ + + memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: spi_dma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMADEBUG +static void spi_dma_sampledone(struct sam_spics_s *spics) +{ + /* Sample the final registers */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL], + "TX: Initial Registers"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL], + "RX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_SETUP], + "TX: After DMA Setup"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_SETUP], + "RX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_START], + "TX: After DMA Start"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_START], + "RX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timedout, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_CALLBACK], + "TX: At DMA callback"); + + /* Register values at the end of the DMA */ + + if (spics->result == -ETIMEDOUT) + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_TIMEOUT], + "RX: At DMA timeout"); + } + else + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_CALLBACK], + "RX: At DMA callback"); + } + + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER], + "RX: At End-of-Transfer"); + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER], + "TX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: spi_dmatimeout + * + * Description: + * The watchdog timeout setup when a has expired without completion of a + * DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_dmatimeout(int argc, uint32_t arg) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Sample DMA registers at the time of the timeout */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report timeout result, perhaps overwriting any failure reports from + * the TX callback. + */ + + spics->result = -ETIMEDOUT; + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_rxcallback + * + * Description: + * This callback function is invoked at the completion of the SPI RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Sample DMA registers at the time of the callback */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report the result of the transfer only if the TX callback has not already + * reported an error. + */ + + if (spics->result == -EBUSY) + { + /* Save the result of the transfer if no error was previuosly reported */ + + spics->result = result; + } + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_txcallback + * + * Description: + * This callback function is invoked at the completion of the SPI TX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + spi_txdma_sample(spics, DMA_CALLBACK); + + /* Do nothing on the TX callback unless an error is reported. This + * callback is not really important because the SPI exchange is not + * complete until the RX callback is received. + */ + + if (result != OK && spics->result == -EBUSY) + { + /* Save the result of the transfer if an error is reported */ + + spics->result = result; + } +} +#endif + +/**************************************************************************** + * Name: spi_physregaddr + * + * Description: + * Return the physical address of an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMA +static inline uintptr_t spi_physregaddr(struct sam_spics_s *spics, + unsigned int offset) +{ + struct sam_spidev_s *spi = spi_device(spics); + return sam_physregaddr(spi->base + offset); +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(struct spi_dev_s *dev, bool lock) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&spi->spisem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&spi->spisem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_select + * + * Description: + * This function does not actually set the chip select line. Rather, it + * simply maps the device ID into a chip select number and retains that + * chip select number for later use. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + + /* Are we selecting or de-selecting the device? */ + + spivdbg("selected=%d\n", selected); + if (selected) + { + spivdbg("cs=%d\n", spics->cs); + + /* Before writing the TDR, the PCS field in the SPI_MR register must be set + * in order to select a slave. + */ + + regval = spi_getreg(spi, SAM_SPI_MR_OFFSET); + regval &= ~SPI_MR_PCS_MASK; + regval |= (spi_cs2pcs(spics) << SPI_MR_PCS_SHIFT); + spi_putreg(spi, regval, SAM_SPI_MR_OFFSET); + } + + /* Perform any board-specific chip select operations. PIO chip select + * pins may be programmed by the board specific logic in one of two + * different ways. First, the pins may be programmed as SPI peripherals. + * In that case, the pins are completely controlled by the SPI driver. + * The sam_spi[0|1]select methods still needs to be provided, but they + * may be only stubs. + * + * An alternative way to program the PIO chip select pins is as normal + * PIO outputs. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + */ + + spi->select(devid, selected); +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t actual; + uint32_t scbr; + uint32_t dlybs; + uint32_t dlybct; + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d frequency=%d\n", spics->cs, frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (spics->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return spics->actual; + } + + /* Configure SPI to a frequency as close as possible to the requested frequency. + * + * SPCK frequency = SPI_CLK / SCBR, or SCBR = SPI_CLK / frequency + */ + + scbr = SAM_SPI_CLOCK / frequency; + + if (scbr < 8) + { + scbr = 8; + } + else if (scbr > 254) + { + scbr = 254; + } + + scbr = (scbr + 1) & ~1; + + /* Save the new scbr value */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK); + regval |= scbr << SPI_CSR_SCBR_SHIFT; + + /* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the + * first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK + * transition is 1/2 the SPCK clock period. Otherwise, the following equations + * determine the delay: + * + * Delay Before SPCK = DLYBS / SPI_CLK + * + * For a 2uS delay + * + * DLYBS = SPI_CLK * 0.000002 = SPI_CLK / 500000 + */ + + dlybs = SAM_SPI_CLOCK / 500000; + regval |= dlybs << SPI_CSR_DLYBS_SHIFT; + + /* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay + * between two consecutive transfers with the same peripheral without removing + * the chip select. The delay is always inserted after each transfer and + * before removing the chip select if needed. + * + * Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK + * + * For a 5uS delay: + * + * DLYBCT = SPI_CLK * 0.000005 / 32 = SPI_CLK / 200000 / 32 + */ + + dlybct = SAM_SPI_CLOCK / 200000 / 32; + regval |= dlybct << SPI_CSR_DLYBCT_SHIFT; + spi_putreg(spi, regval, offset); + + /* Calculate the new actual frequency */ + + actual = SAM_SPI_CLOCK / scbr; + spivdbg("csr[offset=%02x]=%08x actual=%d\n", offset, regval, actual); + + /* Save the frequency setting */ + + spics->frequency = frequency; + spics->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d mode=%d\n", spics->cs, mode); + + /* Has the mode changed? */ + + if (mode != spics->mode) + { + /* Yes... Set the mode appropriately: + * + * SPI CPOL NCPHA + * MODE + * 0 0 1 + * 1 0 0 + * 2 1 1 + * 3 1 0 + */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; NCPHA=1 */ + regval |= SPI_CSR_NCPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; NCPHA=0 */ + break; + + case SPIDEV_MODE2: /* CPOL=1; NCPHA=1 */ + regval |= (SPI_CSR_CPOL | SPI_CSR_NCPHA); + break; + + case SPIDEV_MODE3: /* CPOL=1; NCPHA=0 */ + regval |= SPI_CSR_CPOL; + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(spi, regval, offset); + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + spics->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d nbits=%d\n", spics->cs, nbits); + DEBUGASSERT(spics && nbits > 7 && nbits < 17); + + /* NOTE: The logic in spi_send and in spi_exchange only handles 8-bit + * data at the present time. So the following extra assertion is a + * reminder that we have to fix that someday. + */ + + DEBUGASSERT(nbits == 8); /* Temporary -- FIX ME */ + + /* Has the number of bits changed? */ + + if (nbits != spics->nbits) + { + /* Yes... Set number of bits appropriately */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~SPI_CSR_BITS_MASK; + regval |= SPI_CSR_BITS(nbits); + spi_putreg(spi, regval, offset); + + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + spics->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd) +{ + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange can do this. Note: right now, this only deals with 8-bit + * words. If the SPI interface were configured for words of other sizes, + * this would fail. + */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange(dev, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; +} + +/**************************************************************************** + * Name: spi_exchange (and spi_exchange_nodma) + * + * Description: + * Exchange a block of data from SPI. There are two versions of this + * function: (1) One that is enabled only when CONFIG_SAMA5_SPI_DMA=y + * that performs DMA SPI transfers, but only when a larger block of + * data is being transferred. And (2) another version that does polled + * SPI transfers. When CONFIG_SAMA5_SPI_DMA=n the latter is the only + * version avaialable; when CONFIG_SAMA5_SPI_DMA=y, this version is only + * used for short SPI transfers and gets renamed as spi_exchange_nodma). + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#else +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#endif +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint8_t *rxptr = (uint8_t *)rxbuffer; + uint8_t *txptr = (uint8_t *)txbuffer; + uint32_t pcs; + uint32_t data; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Set up PCS bits */ + + pcs = spi_cs2pcs(spics) << SPI_TDR_PCS_SHIFT; + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Loop, sending each word in the user-provied data buffer. + * + * Note 1: Right now, this only deals with 8-bit words. If the SPI + * interface were configured for words of other sizes, this + * would fail. + * Note 2: Good SPI performance would require that we implement DMA + * transfers! + * Note 3: This loop might be made more efficient. Would logic + * like the following improve the throughput? Or would it + * just add the risk of overruns? + * + * Get word 1; + * Send word 1; Now word 1 is "in flight" + * nwords--; + * for (; nwords > 0; nwords--) + * { + * Get word N. + * Wait for TDRE meaning that word N-1 has moved to the shift + * register. + * Disable interrupts to keep the following atomic + * Send word N. Now both work N-1 and N are "in flight" + * Wait for RDRF meaning that word N-1 is available + * Read word N-1. + * Re-enable interrupts. + * Save word N-1. + * } + * Wait for RDRF meaning that the final word is available + * Read the final word. + * Save the final word. + */ + + for (; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source) */ + + if (txptr) + { + data = (uint32_t)*txptr++; + } + else + { + data = 0xffff; + } + + /* Set the PCS field in the value written to the TDR */ + + data |= pcs; + + /* Do we need to set the LASTXFER bit in the TDR value too? */ + +#ifdef CONFIG_SPI_VARSELECT + if (nwords == 1) + { + data |= SPI_TDR_LASTXFER; + } +#endif + + /* Wait for any previous data written to the TDR to be transferred + * to the serializer. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TDRE) == 0); + + /* Write the data to transmitted to the Transmit Data Register (TDR) */ + + spi_putreg(spi, data, SAM_SPI_TDR_OFFSET); + + /* Wait for the read data to be available in the RDR. + * TODO: Data transfer rates would be improved using the RX FIFO + * (and also DMA) + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) == 0); + + /* Read the received data from the SPI Data Register.. + * TODO: The following only works if nbits <= 8. + */ + + data = spi_getreg(spi, SAM_SPI_RDR_OFFSET); + if (rxptr) + { + *rxptr++ = (uint8_t)data; + } + } +} + +#ifdef CONFIG_SAMA5_SPI_DMA +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t rxflags; + uint32_t txflags; + uint32_t txdummy; + uint32_t rxdummy; + uint32_t paddr; + uint32_t maddr; + int ret; + + /* If we cannot do DMA -OR- if this is a small SPI transfer, then let + * spi_exchange_nodma() do the work. + */ + + if (!spics->candma || nwords <= CONFIG_SAMA5_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + spics = (struct sam_spics_s *)dev; + spi = spi_device(spics); + DEBUGASSERT(spics && spi); + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Sample initial DMA registers */ + + spi_dma_sampleinit(spics); + + /* Configure the DMA channels. There are four different cases: + * + * 1) A true exchange with the memory address incrementing on both + * RX and TX channels, + * 2) A read operation with the memory address incrementing only on + * the receive channel, + * 3) A write operation where the memory address increments only on + * the receive channel, and + * 4) A corner case where there the memory address does not increment + * on either channel. This case might be used in certain cases + * where you want to assure that certain number of clocks are + * provided on the SPI bus. + */ + + rxflags = DMACH_FLAG_FIFOCFG_LARGEST | DMACH_FLAG_PERIPHPID(spi->pid) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHAHB_AHB_IF2 | DMACH_FLAG_PERIPHWIDTH_8BITS | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | + DMACH_FLAG_MEMAHB_AHB_IF0 | DMACH_FLAG_MEMWIDTH_8BITS | + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4; + + if (!rxbuffer) + { + /* No sink data buffer. Point to our dummy buffer and leave + * the rxflags so that no address increment is performed. + */ + + rxbuffer = (void *)&rxdummy; + } + else + { + /* A receive buffer is available. Use normal TX memory incrementing. */ + + rxflags |= DMACH_FLAG_MEMINCREMENT; + } + + txflags = DMACH_FLAG_FIFOCFG_LARGEST | DMACH_FLAG_PERIPHPID(spi->pid) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHAHB_AHB_IF2 | DMACH_FLAG_PERIPHWIDTH_8BITS | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | + DMACH_FLAG_MEMAHB_AHB_IF0 | DMACH_FLAG_MEMWIDTH_8BITS | + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_4; + + if (!txbuffer) + { + /* No source data buffer. Point to our dummy buffer and configure + * the txflags so that no address increment is performed. + */ + + txdummy = 0xffffffff; + txbuffer = (const void *)&txdummy; + } + else + { + /* Source data is available. Use normal TX memory incrementing. */ + + txflags |= DMACH_FLAG_MEMINCREMENT; + } + + /* Then configure the DMA channels to make it so */ + + sam_dmaconfig(spics->rxdma, rxflags); + sam_dmaconfig(spics->txdma, txflags); + + /* Configure the exchange transfers */ + + paddr = spi_physregaddr(spics, SAM_SPI_RDR_OFFSET); + maddr = sam_physramaddr((uintptr_t)rxbuffer); + + ret = sam_dmarxsetup(spics->rxdma, paddr, maddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmarxsetup failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_SETUP); + + paddr = spi_physregaddr(spics, SAM_SPI_TDR_OFFSET); + maddr = sam_physramaddr((uintptr_t)txbuffer); + + ret = sam_dmatxsetup(spics->txdma, paddr, maddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmatxsetup failed: %d\n", ret); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_SETUP); + + /* Start the DMA transfer */ + + spics->result = -EBUSY; + ret = sam_dmastart(spics->rxdma, spi_rxcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_START); + + ret = sam_dmastart(spics->txdma, spi_txcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + sam_dmastop(spics->rxdma); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_START); + + /* Wait for DMA completion. This is done in a loop becaue there my be + * false alarm semaphore counts that cause sam_wait() not fail to wait + * or to wake-up prematurely (for example due to the receipt of a signal). + * We know that the DMA has completed when the result is anything other + * that -EBUSY. + */ + + do + { + /* Start (or re-start) the watchdog timeout */ + + ret = wd_start(spics->dmadog, DMA_TIMEOUT_TICKS, + (wdentry_t)spi_dmatimeout, 1, (uint32_t)spics); + if (ret != OK) + { + spidbg("ERROR: wd_start failed: %d\n", ret); + } + + /* Wait for the DMA complete */ + + ret = sem_wait(&spics->dmawait); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Check if we were awakened by an error of some kind */ + + if (ret < 0) + { + /* EINTR is not a failure. That simply means that the wait + * was awakened by a signel. + */ + + int errorcode = errno; + if (errorcode != EINTR) + { + DEBUGPANIC(); + return; + } + } + + /* Not that we might be awkened before the wait is over due to + * residual counts on the semaphore. So, to handle, that case, + * we loop until somthing changes the DMA result to any value other + * than -EBUSY. + */ + } + while (spics->result == -EBUSY); + + /* Dump the sampled DMA registers */ + + spi_dma_sampledone(spics); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + sam_dmastop(spics->rxdma); + sam_dmastop(spics->txdma); + + /* All we can do is complain if the DMA fails */ + + if (spics->result) + { + spidbg("ERROR: DMA failed with result: %d\n", spics->result); + } +} +#endif /* CONFIG_SAMA5_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port) +{ + struct sam_spidev_s *spi; + struct sam_spics_s *spics; + int csno = (port & __SPI_CS_MASK) >> __SPI_CS_SHIFT; + int spino = (port & __SPI_SPI_MASK) >> __SPI_SPI_SHIFT; + irqstate_t flags; + uint32_t regval; + unsigned int offset; + + /* The support SAM parts have only a single SPI port */ + + spivdbg("port: %d csno: %d spino: %d\n", port, csno, spino); + DEBUGASSERT(csno >= 0 && csno <= SAM_SPI_NCS); + +#if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_SPI1) + DEBUGASSERT(spino >= 0 && spino <= 1); +#elif defined(CONFIG_SAMA5_SPI0) + DEBUGASSERT(spino == 0); +#else + DEBUGASSERT(spino == 1); +#endif + + /* Allocate a new state structure for this chip select. NOTE that there + * is no protection if the same chip select is used in two different + * chip select structures. + */ + + spics = (struct sam_spics_s *)zalloc(sizeof(struct sam_spics_s)); + if (!spics) + { + spidbg("ERROR: Failed to allocate a chip select structure\n"); + return NULL; + } + + /* Set up the initial state for this chip select structure. Other fields + * were zeroed by zalloc(). + */ + +#ifdef CONFIG_SAMA5_SPI_DMA + /* Can we do DMA on this peripheral? */ + + spics->candma = spino ? SAMA5_SPI1_DMA : SAMA5_SPI0_DMA; + + /* Pre-allocate DMA channels. These allocations exploit that fact that + * SPI0 is managed by DMAC0 and SPI1 is managed by DMAC1. Hence, + * the SPI number (spino) is the same as the DMAC number. + */ + + if (spics->candma) + { + spics->rxdma = sam_dmachannel(spino, 0); + if (!spics->rxdma) + { + spidbg("ERROR: Failed to allocate the RX DMA channel\n"); + spics->candma = false; + } + } + + if (spics->candma) + { + spics->txdma = sam_dmachannel(spino, 0); + if (!spics->txdma) + { + spidbg("ERROR: Failed to allocate the TX DMA channel\n"); + sam_dmafree(spics->rxdma); + spics->rxdma = NULL; + spics->candma = false; + } + } +#endif + + /* Select the SPI operations */ + +#if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_SPI1) + spics->spidev.ops = spino ? &g_spi1ops : &g_spi0ops; +#elif defined(CONFIG_SAMA5_SPI0) + spics->spidev.ops = &g_spi0ops; +#else + spics->spidev.ops = &g_spi1ops; +#endif + + /* Save the chip select and SPI controller numbers */ + + spics->cs = csno; +#if defined(CONFIG_SAMA5_SPI0) || defined(CONFIG_SAMA5_SPI1) + spics->spino = spino; +#endif + + /* Get the SPI device structure associated with the chip select */ + + spi = spi_device(spics); + + /* Has the SPI hardware been initialized? */ + + if (!spi->initialized) + { + /* Enable clocking to the SPI block */ + + flags = enter_critical_section(); +#if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_SPI1) + if (spino == 0) +#endif +#if defined(CONFIG_SAMA5_SPI0) + { + sam_spi0_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configpio(PIO_SPI0_MISO); + sam_configpio(PIO_SPI0_MOSI); + sam_configpio(PIO_SPI0_SPCK); + } +#endif +#if defined(CONFIG_SAMA5_SPI0) && defined(CONFIG_SAMA5_SPI1) + else +#endif +#if defined(CONFIG_SAMA5_SPI1) + { + sam_spi1_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configpio(PIO_SPI1_MISO); + sam_configpio(PIO_SPI1_MOSI); + sam_configpio(PIO_SPI1_SPCK); + } +#endif + + /* Disable SPI clocking */ + + spi_putreg(spi, SPI_CR_SPIDIS, SAM_SPI_CR_OFFSET); + + /* Execute a software reset of the SPI (twice) */ + + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + leave_critical_section(flags); + + /* Configure the SPI mode register */ + + spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS, SAM_SPI_MR_OFFSET); + + /* And enable the SPI */ + + spi_putreg(spi, SPI_CR_SPIEN, SAM_SPI_CR_OFFSET); + up_mdelay(20); + + /* Flush any pending transfers */ + + (void)spi_getreg(spi, SAM_SPI_SR_OFFSET); + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + + /* Initialize the SPI semaphore that enforces mutually exclusive + * access to the SPI registers. + */ + + sem_init(&spi->spisem, 0, 1); + spi->initialized = true; + +#ifdef CONFIG_SAMA5_SPI_DMA + /* Initialize the SPI semaphore that is used to wake up the waiting + * thread when the DMA transfer completes. + */ + + sem_init(&spics->dmawait, 0, 0); + + /* Create a watchdog time to catch DMA timeouts */ + + spics->dmadog = wd_create(); + DEBUGASSERT(spics->dmadog); +#endif + + spi_dumpregs(spi, "After initialization"); + } + + /* Set to mode=0 and nbits=8 and impossible frequency. The SPI will only + * be reconfigured if there is a change. + */ + + offset = (unsigned int)g_csroffset[csno]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK); + regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8)); + spi_putreg(spi, regval, offset); + + spics->nbits = 8; + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + return &spics->spidev; +} +#endif /* CONFIG_SAMA5_SPI0 || CONFIG_SAMA5_SPI1 */ diff --git a/arch/arm/src/sama5/sam_spi.h b/arch/arm/src/sama5/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..cf988639372d338af75e3ed7d7bec2bbac8d7828 --- /dev/null +++ b/arch/arm/src/sama5/sam_spi.h @@ -0,0 +1,252 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_spi.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_SPI_H +#define __ARCH_ARM_SRC_SAMA5_SAM_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The SPI port number used as an input to sam_spibus_initialize encodes information + * about the SPI controller (0 or 1) and the SPI chip select (0-3) + */ + +#define __SPI_CS_SHIFT (0) /* Bits 0-1: SPI chip select number */ +#define __SPI_CS_MASK (3 << __SPI_CS_SHIFT) +# define __SPI_CS0 (0 << __SPI_CS_SHIFT) +# define __SPI_CS1 (1 << __SPI_CS_SHIFT) +# define __SPI_CS2 (2 << __SPI_CS_SHIFT) +# define __SPI_CS3 (3 << __SPI_CS_SHIFT) +#define __SPI_SPI_SHIFT (2) /* Bit 2: SPI controller number */ +#define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT) +# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */ +# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */ + +#define SPI0_CS0 (__SPI_SPI0 | __SPI_CS0) +#define SPI0_CS1 (__SPI_SPI0 | __SPI_CS1) +#define SPI0_CS2 (__SPI_SPI0 | __SPI_CS2) +#define SPI0_CS3 (__SPI_SPI0 | __SPI_CS3) + +#define SPI1_CS0 (__SPI_SPI1 | __SPI_CS0) +#define SPI1_CS1 (__SPI_SPI1 | __SPI_CS1) +#define SPI1_CS2 (__SPI_SPI1 | __SPI_CS2) +#define SPI1_CS3 (__SPI_SPI1 | __SPI_CS3) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port); + +/**************************************************************************** + * Name: sam_spi[0|1]select, sam_spi[0|1]status, and sam_spi[0|1]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They + * include: + * + * o sam_spi[0|1]select is a functions tomanage the board-specific chip selects + * o sam_spi[0|1]status and sam_spi[0|1]cmddata: Implementations of the status + * and cmddata methods of the SPI interface defined by struct spi_ops_ + * (see include/nuttx/spi/spi.h). All other methods including + * sam_spibus_initialize()) are provided by common SAM3/4 logic. + * + * To use this common SPI logic on your board: + * + * 1. Provide logic in sam_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in your board- + * specific logic. These functions will perform chip selection and + * status operations using PIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * sam_spi[0|1]cmddata() functions in your board-specific logic. This + * function will perform cmd/data selection operations using PIOs in + * the way your board is configured. + * 3. Add a call to sam_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by sam_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spi[0|1]select + * + * Description: + * PIO chip select pins may be programmed by the board specific logic in + * one of two different ways. First, the pins may be programmed as SPI + * peripherals. In that case, the pins are completely controlled by the + * SPI driver. This method still needs to be provided, but it may be only + * a stub. + * + * An alternative way to program the PIO chip select pins is as a normal + * PIO output. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * selected - TRUE:Select the device, FALSE:De-select the device + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI0 +void sam_spi0select(enum spi_dev_e devid, bool selected); +#endif +#ifdef CONFIG_SAMA5_SPI1 +void sam_spi1select(enum spi_dev_e devid, bool selected); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]status + * + * Description: + * Return status information associated with the SPI device. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Bit-encoded SPI status (see include/nuttx/spi/spi.h. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SPI0 +uint8_t sam_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif +#ifdef CONFIG_SAMA5_SPI1 +uint8_t sam_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]cmddata + * + * Description: + * Some SPI devices require an additional control to determine if the SPI + * data being sent is a command or is data. If CONFIG_SPI_CMDDATA then + * this function will be called to different be command and data transfers. + * + * This is often needed, for example, by LCD drivers. Some LCD hardware + * may be configured to use 9-bit data transfers with the 9th bit + * indicating command or data. That same hardware may be configurable, + * instead, to use 8-bit data but to require an additional, board- + * specific PIO control to distinguish command and data. This function + * would be needed in that latter case. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Zero on success; a negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_SAMA5_SPI0 +int sam_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#ifdef CONFIG_SAMA5_SPI1 +int sam_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_SPI_H */ diff --git a/arch/arm/src/sama5/sam_ssc.c b/arch/arm/src/sama5/sam_ssc.c new file mode 100644 index 0000000000000000000000000000000000000000..52aac74b17d7d96efb53a35814c04000b94527d8 --- /dev/null +++ b/arch/arm/src/sama5/sam_ssc.c @@ -0,0 +1,3532 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_ssc.c + * + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "chip.h" +#include "sam_pio.h" +#include "sam_dmac.h" +#include "sam_memories.h" +#include "sam_periphclks.h" +#include "sam_ssc.h" +#include "chip/sam_pmc.h" +#include "chip/sam_ssc.h" +#include "chip/sam_pinmap.h" + +#if defined(CONFIG_SAMA5_SSC0) || defined(CONFIG_SAMA5_SSC1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SCHED_WORKQUEUE +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#endif + +#ifndef CONFIG_AUDIO +# error CONFIG_AUDIO required by this driver +#endif + +#ifndef CONFIG_SAMA5_SSC_MAXINFLIGHT +# define CONFIG_SAMA5_SSC_MAXINFLIGHT 16 +#endif + +/* Assume no RX/TX support until we learn better */ + +#undef SSC_HAVE_RX +#undef SSC_HAVE_TX + +/* Check for SSC0 support */ + +#if defined(CONFIG_SAMA5_SSC0) + +# if defined(CONFIG_SAMA5_HAVE_XDMA) +# if !defined(CONFIG_SAMA5_XDMAC0) && !defined(CONFIG_SAMA5_XDMAC1) +# error CONFIG_SAMA5_XDMAC0 or XDMAC1 required by SSC0 +# endif +# else +# if !defined(CONFIG_SAMA5_DMAC0) +# error CONFIG_SAMA5_DMAC0 required by SSC0 +# endif +# endif + + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + +# ifndef CONFIG_SAMA5_SSC0_DATALEN +# define CONFIG_SAMA5_SSC0_DATALEN 16 +# endif + +# if CONFIG_SAMA5_SSC0_DATALEN == 8 +# define SAMA5_SSC0_DATAMASK 0 +# elif CONFIG_SAMA5_SSC0_DATALEN == 16 +# define SAMA5_SSC0_DATAMASK 1 +# elif CONFIG_SAMA5_SSC0_DATALEN == 32 +# define SAMA5_SSC0_DATAMASK 3 +# elif CONFIG_SAMA5_SSC0_DATALEN < 2 || CONFIG_SAMA5_SSC0_DATALEN > 32 +# error Invalid value for CONFIG_SAMA5_SSC0_DATALEN +# else +# error Valid but supported value for CONFIG_SAMA5_SSC0_DATALEN +# endif + +/* Check for SSC0 RX support */ + +# if defined(CONFIG_SAMA5_SSC0_RX) +# define SSC_HAVE_RX 1 + +# ifndef CONFIG_SSC0_RX_FSLEN +# define CONFIG_SSC0_RX_FSLEN 1 +# endif + +# if CONFIG_SSC0_RX_FSLEN < 1 || CONFIG_SSC0_RX_FSLEN > 255 +# error Invalid value for CONFIG_SSC0_RX_FSLEN +# endif + +# ifndef CONFIG_SSC0_RX_STTDLY +# define CONFIG_SSC0_RX_STTDLY CONFIG_SSC0_RX_FSLEN +# endif + +# if CONFIG_SSC0_RX_STTDLY < 0 || \ + CONFIG_SSC0_RX_STTDLY < CONFIG_SSC0_RX_FSLEN || \ + CONFIG_SSC0_RX_STTDLY > 255 +# error Invalid value for CONFIG_SSC0_RX_STTDLY +# endif +# endif + +/* Check for SSC0 TX support */ + +# if defined(CONFIG_SAMA5_SSC0_TX) +# define SSC_HAVE_TX 1 + +# ifndef CONFIG_SSC0_TX_FSLEN +# define CONFIG_SSC0_TX_FSLEN 0 +# endif + +# if CONFIG_SSC0_TX_FSLEN < 0 || CONFIG_SSC0_TX_FSLEN > 255 +# error Invalid value for CONFIG_SSC0_TX_FSLEN +# endif + +# ifndef CONFIG_SSC0_TX_STTDLY +# if CONFIG_SSC0_TX_FSLEN > 0 +# define CONFIG_SSC0_TX_STTDLY CONFIG_SSC0_TX_FSLEN +# else +# define CONFIG_SSC0_TX_STTDLY 0 +# endif +# endif + +# if CONFIG_SSC0_TX_STTDLY < 0 || \ + CONFIG_SSC0_TX_STTDLY < CONFIG_SSC0_TX_FSLEN || \ + CONFIG_SSC0_TX_STTDLY > 255 +# error Invalid value for CONFIG_SSC0_TX_STTDLY +# endif +# endif + +#endif + +/* Check for SSC1 support */ + +#if defined(CONFIG_SAMA5_SSC1) + +# if defined(CONFIG_SAMA5_HAVE_XDMA) +# if !defined(CONFIG_SAMA5_XDMAC0) && !defined(CONFIG_SAMA5_XDMAC1) +# error CONFIG_SAMA5_XDMAC1 (or XDMAC0) required by SSC1 +# endif +# else +# if !defined(CONFIG_SAMA5_DMAC1) +# error CONFIG_SAMA5_DMAC0 required by SSC1 +# endif +# endif + + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + +# ifndef CONFIG_SAMA5_SSC1_DATALEN +# define CONFIG_SAMA5_SSC1_DATALEN 16 +# endif + +# if CONFIG_SAMA5_SSC1_DATALEN == 8 +# define SAMA5_SSC1_DATAMASK 0 +# elif CONFIG_SAMA5_SSC1_DATALEN == 16 +# define SAMA5_SSC1_DATAMASK 1 +# elif CONFIG_SAMA5_SSC1_DATALEN == 32 +# define SAMA5_SSC1_DATAMASK 3 +# elif CONFIG_SAMA5_SSC1_DATALEN < 2 || CONFIG_SAMA5_SSC1_DATALEN > 32 +# error Invalid value for CONFIG_SAMA5_SSC1_DATALEN +# else +# error Valid but supported value for CONFIG_SAMA5_SSC1_DATALEN +# endif + +/* Check for SSC1 RX support */ + +# if defined(CONFIG_SAMA5_SSC1_RX) +# define SSC_HAVE_RX 1 + +# ifndef CONFIG_SSC1_RX_FSLEN +# define CONFIG_SSC1_RX_FSLEN 1 +# endif + +# if CONFIG_SSC1_RX_FSLEN < 1 || CONFIG_SSC1_RX_FSLEN > 255 +# error Invalid value for CONFIG_SSC1_RX_FSLEN +# endif + +# ifndef CONFIG_SSC1_RX_STTDLY +# define CONFIG_SSC1_RX_STTDLY CONFIG_SSC1_RX_FSLEN +# endif + +# if CONFIG_SSC1_RX_STTDLY < 0 || \ + CONFIG_SSC1_RX_STTDLY < CONFIG_SSC1_RX_FSLEN || \ + CONFIG_SSC1_RX_STTDLY > 255 +# error Invalid value for CONFIG_SSC1_RX_STTDLY +# endif + +# endif + +/* Check for SSC1 TX support */ + +# if defined(CONFIG_SAMA5_SSC1_TX) +# define SSC_HAVE_TX 1 + +# ifndef CONFIG_SSC1_TX_FSLEN +# define CONFIG_SSC1_TX_FSLEN 0 +# endif + +# if CONFIG_SSC1_TX_FSLEN < 0 || CONFIG_SSC1_TX_FSLEN > 255 +# error Invalid value for CONFIG_SSC1_TX_FSLEN +# endif + +# ifndef CONFIG_SSC1_TX_STTDLY +# if CONFIG_SSC1_TX_FSLEN > 0 +# define CONFIG_SSC1_TX_STTDLY CONFIG_SSC1_TX_FSLEN +# else +# define CONFIG_SSC1_TX_STTDLY 0 +# endif +# endif + +# if CONFIG_SSC1_TX_STTDLY < 0 || \ + CONFIG_SSC1_TX_STTDLY < CONFIG_SSC1_TX_FSLEN || \ + CONFIG_SSC1_TX_STTDLY > 255 +# error Invalid value for CONFIG_SSC1_TX_STTDLY +# endif +# endif + +#endif + +/* Check if we need to build RX and/or TX support */ + +#if defined(SSC_HAVE_RX) || defined(SSC_HAVE_TX) + +/* Check if we need the sample rate to set MCK/2 divider */ + +#undef SSC_HAVE_MCK2 +#undef SSC0_HAVE_MCK2 +#undef SSC1_HAVE_MCK2 + +#if (defined(CONFIG_SAMA5_SSC0_RX) && defined(CONFIG_SAMA5_SSC0_RX_MCKDIV)) || \ + (defined(CONFIG_SAMA5_SSC0_TX) && defined(CONFIG_SAMA5_SSC0_TX_MCKDIV)) +# define SSC0_HAVE_MCK2 1 +#endif + +#if (defined(CONFIG_SAMA5_SSC1_RX) && defined(CONFIG_SAMA5_SSC1_RX_MCKDIV)) || \ + (defined(CONFIG_SAMA5_SSC1_TX) && defined(CONFIG_SAMA5_SSC1_TX_MCKDIV)) +# define SSC1_HAVE_MCK2 1 +#endif + +#if defined(SSC0_HAVE_MCK2) || defined(SSC1_HAVE_MCK2) +# define SSC_HAVE_MCK2 1 +#endif + +/* Waveform: + * + * |<---------------- PERIOD --------------->| + * ----+ +-----------------------------------+ +--- + * | | | | + * +-----+ +----+ + * |FSLEN| + * |<-STTDLY->|<--DATALEN-->|<--DATALEN-->| | + * |<-----DATALEN * DATNB----->| + * + * TK/RK is assumed to be a negative pulse + * DATALEN is configurable: CONFIG_SAMA5_SSCx_DATALEN + * FSLEN is configuration: CONFIG_SAMA5_SSCx_RX/TX_FSLEN + * FSLEN and STTDLY are fixed at two clocks + * DATNB is fixed a one work + * + * REVISIT: These will probably need to be configurable + */ + +#define SSC_DATNB (1) /* Number words per per frame */ +#define SCC_PERIOD(s,d) ((s) + (d) * SSC_DATNB) + +/* Clocking *****************************************************************/ + +/* Clock source definitions */ + +#define SSC_CLKSRC_NONE 0 /* No clock */ +#define SSC_CLKSRC_MCKDIV 1 /* Clock source is MCK divided down */ +#define SSC_CLKSRC_RXOUT 2 /* Transmitter clock source is the receiver clock */ +#define SSC_CLKSRC_TXOUT 2 /* Receiver clock source is the transmitter clock */ +#define SSC_CLKSRC_TKIN 3 /* Transmitter clock source is TK */ +#define SSC_CLKSRC_RKIN 3 /* Receiver clock source is RK */ + +/* Clock output definitions */ + +#define SSC_CLKOUT_NONE 0 /* No output clock */ +#define SSC_CLKOUT_CONT 1 /* Continuous */ +#define SSC_CLKOUT_XFER 2 /* Only output clock during transfers */ + +/* Bus configuration differ with chip */ + +#if defined(ATSAMA5D3) + /* System bus interfaces */ + +# define DMACH_FLAG_PERIPH_IF DMACH_FLAG_PERIPHAHB_AHB_IF2 +# define DMACH_FLAG_MEM_IF DMACH_FLAG_MEMAHB_AHB_IF0 + +#elif defined(ATSAMA5D4) + /* System Bus Interfaces + * + * Both SSC0 and SSC1 are APB1. Both are accessible on MATRIX IF1. + * + * Memory is available on either port 5 (IF0 for both XDMAC0 and 1) or + * port 6 (IF1 for both XDMAC0 and 1). + */ + +# define DMACH_FLAG_PERIPH_IF DMACH_FLAG_PERIPHAHB_AHB_IF1 +# define DMACH_FLAG_MEM_IF DMACH_FLAG_MEMAHB_AHB_IF0 +#endif + +/* DMA configuration */ + +#define DMA8_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_8BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +#define DMA16_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_16BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +#define DMA32_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_32BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_32BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* Debug *******************************************************************/ +/* Check if SSC debut is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_I2S +#endif + +#ifndef CONFIG_DEBUG_I2S +# undef CONFIG_SAMA5_SSC_DMADEBUG +# undef CONFIG_SAMA5_SSC_REGDEBUG +# undef CONFIG_SAMA5_SSC_QDEBUG +# undef CONFIG_SAMA5_SSC_DUMPBUFFERS +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAMA5_SSC_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_I2S +# define i2sdbg dbg +# define i2slldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define i2svdbg dbg +# define i2sllvdbg lldbg +# else +# define i2svdbg(x...) +# endif +#else +# define i2sdbg(x...) +# define i2slldbg(x...) +# define i2svdbg(x...) +# define i2sllvdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* I2S buffer container */ + +struct sam_buffer_s +{ + struct sam_buffer_s *flink; /* Supports a singly linked list */ + i2s_callback_t callback; /* Function to call when the transfer completes */ + uint32_t timeout; /* The timeout value to use with DMA transfers */ + void *arg; /* The argument to be returned with the callback */ + struct ap_buffer_s *apb; /* The audio buffer */ + int result; /* The result of the transfer */ +}; + +/* This structure describes the state of one receiver or transmitter transport */ + +struct sam_transport_s +{ + DMA_HANDLE dma; /* SSC DMA handle */ + WDOG_ID dog; /* Watchdog that handles DMA timeouts */ + sq_queue_t pend; /* A queue of pending transfers */ + sq_queue_t act; /* A queue of active transfers */ + sq_queue_t done; /* A queue of completed transfers */ + struct work_s work; /* Supports worker thread operations */ + +#ifdef CONFIG_SAMA5_SSC_DMADEBUG + struct sam_dmaregs_s dmaregs[DMA_NSAMPLES]; +#endif +}; + +/* The state of the one SSC peripheral */ + +struct sam_ssc_s +{ + struct i2s_dev_s dev; /* Externally visible I2S interface */ + uintptr_t base; /* SSC controller register base address */ + sem_t exclsem; /* Assures mutually exclusive acess to SSC */ + uint8_t datalen; /* Data width (8, 16, or 32) */ +#ifdef CONFIG_DEBUG + uint8_t align; /* Log2 of data width (0, 1, or 3) */ +#endif + uint8_t pid; /* Peripheral ID */ + uint8_t rxfslen; /* RX frame sync length */ + uint8_t txfslen; /* TX frame sync length */ + uint8_t rxsttdly; /* RX start delay */ + uint8_t txsttdly; /* TX start delay */ + uint8_t rxenab:1; /* True: RX transfers enabled */ + uint8_t txenab:1; /* True: TX transfers enabled */ + uint8_t loopback:1; /* True: Loopback mode */ + uint8_t sscno:1; /* SSC controller number (0 or 1) */ + uint8_t rxclk:2; /* Receiver clock source. See SSC_CLKSRC_* definitions */ + uint8_t txclk:2; /* Transmitter clock source. See SSC_CLKSRC_* definitions */ + uint8_t rxout:2; /* Receiver clock output. See SSC_CLKOUT_* definitions */ + uint8_t txout:2; /* Transmitter clock output. See SSC_CLKOUT_* definitions */ + uint32_t frequency; /* SSC clock frequency */ +#ifdef SSC_HAVE_MCK2 + uint32_t samplerate; /* Data sample rate (determines only MCK/2 divider) */ +#endif + +#ifdef SSC_HAVE_RX + struct sam_transport_s rx; /* RX transport state */ +#endif +#ifdef SSC_HAVE_TX + struct sam_transport_s tx; /* TX transport state */ +#endif + + /* Pre-allocated pool of buffer containers */ + + sem_t bufsem; /* Buffer wait semaphore */ + struct sam_buffer_s *freelist; /* A list a free buffer containers */ + struct sam_buffer_s containers[CONFIG_SAMA5_SSC_MAXINFLIGHT]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_SSC_REGDEBUG + bool wr; /* Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int count; /* Number of times */ +#endif /* CONFIG_SAMA5_SSC_REGDEBUG */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register helpers */ + +#ifdef CONFIG_SAMA5_SSC_REGDEBUG +static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval, + uint32_t regaddr); +#else +# define ssc_checkreg(priv,wr,regval,regaddr) (false) +#endif + +static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, unsigned int offset); +static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset, + uint32_t regval); +static inline uintptr_t ssc_physregaddr(struct sam_ssc_s *priv, + unsigned int offset); + +#if defined(CONFIG_DEBUG_I2S) && defined(CONFIG_DEBUG_VERBOSE) +static void scc_dump_regs(struct sam_ssc_s *priv, const char *msg); +#else +# define scc_dump_regs(s,m) +#endif + +#ifdef CONFIG_SAMA5_SSC_QDEBUG +static void ssc_dump_queues(struct sam_transport_s *xpt, + const char *msg); +# define ssc_dump_rxqueues(s,m) ssc_dump_queues(&(s)->rx,m) +# define ssc_dump_txqueues(s,m) ssc_dump_queues(&(s)->tx,m) +#else +# define ssc_dump_rxqueues(s,m) +# define ssc_dump_txqueues(s,m) +#endif + +#ifdef CONFIG_SAMA5_SSC_DUMPBUFFERS +# define ssc_init_buffer(b,s) memset(b, 0x55, s); +# define ssc_dump_buffer(m,b,s) lib_dumpbuffer(m,b,s) +#else +# define ssc_init_buffer(b,s) +# define ssc_dump_buffer(m,b,s) +#endif + +/* Semaphore helpers */ + +static void ssc_exclsem_take(struct sam_ssc_s *priv); +#define ssc_exclsem_give(priv) sem_post(&priv->exclsem) + +static void ssc_bufsem_take(struct sam_ssc_s *priv); +#define ssc_bufsem_give(priv) sem_post(&priv->bufsem) + +/* Buffer container helpers */ + +static struct sam_buffer_s * + ssc_buf_allocate(struct sam_ssc_s *priv); +static void ssc_buf_free(struct sam_ssc_s *priv, + struct sam_buffer_s *bfcontainer); +static void ssc_buf_initialize(struct sam_ssc_s *priv); + +/* DMA support */ + +#ifdef CONFIG_SAMA5_SSC_DMADEBUG +static void ssc_dma_sampleinit(struct sam_ssc_s *priv, + struct sam_transport_s *xpt); +#endif + +#if defined(CONFIG_SAMA5_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +# define ssc_rxdma_sample(s,i) sam_dmasample((s)->rx.dma, &(s)->rx.dmaregs[i]) +# define ssc_rxdma_sampleinit(s) ssc_dma_sampleinit(s, &(s)->rx) +static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result); + +#else +# define ssc_rxdma_sample(s,i) +# define ssc_rxdma_sampleinit(s) +# define ssc_rxdma_sampledone(s,r) + +#endif + +#if defined(CONFIG_SAMA5_SSC_DMADEBUG) && defined(SSC_HAVE_TX) +# define ssc_txdma_sample(s,i) sam_dmasample((s)->tx.dma, &(s)->tx.dmaregs[i]) +# define ssc_txdma_sampleinit(s) ssc_dma_sampleinit(s, &(s)->tx) +static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result); + +#else +# define ssc_txdma_sample(s,i) +# define ssc_txdma_sampleinit(s) +# define ssc_txdma_sampledone(s,r) + +#endif + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_timeout(int argc, uint32_t arg); +static int ssc_rxdma_setup(struct sam_ssc_s *priv); +static void ssc_rx_worker(void *arg); +static void ssc_rx_schedule(struct sam_ssc_s *priv, int result); +static void ssc_rxdma_callback(DMA_HANDLE handle, void *arg, int result); +#endif +#ifdef SSC_HAVE_TX +static void ssc_txdma_timeout(int argc, uint32_t arg); +static int ssc_txdma_setup(struct sam_ssc_s *priv); +static void ssc_tx_worker(void *arg); +static void ssc_tx_schedule(struct sam_ssc_s *priv, int result); +static void ssc_txdma_callback(DMA_HANDLE handle, void *arg, int result); +#endif + +/* I2S methods (and close friends) */ + +static int ssc_checkwidth(struct sam_ssc_s *priv, int bits); + +static uint32_t ssc_rxsamplerate(struct i2s_dev_s *dev, uint32_t rate); +static uint32_t ssc_rxdatawidth(struct i2s_dev_s *dev, int bits); +static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout); +static uint32_t ssc_txsamplerate(struct i2s_dev_s *dev, uint32_t rate); +static uint32_t ssc_txdatawidth(struct i2s_dev_s *dev, int bits); +static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, + uint32_t timeout); + +/* Initialization */ + +#ifdef SSC_HAVE_RX +static int ssc_rx_configure(struct sam_ssc_s *priv); +#endif +#ifdef SSC_HAVE_TX +static int ssc_tx_configure(struct sam_ssc_s *priv); +#endif +static uint32_t ssc_mck2divider(struct sam_ssc_s *priv); +static void ssc_clocking(struct sam_ssc_s *priv); +static int ssc_dma_flags(struct sam_ssc_s *priv, uint32_t *dmaflags); +static int ssc_dma_allocate(struct sam_ssc_s *priv); +static void ssc_dma_free(struct sam_ssc_s *priv); +#ifdef CONFIG_SAMA5_SSC0 +static void ssc0_configure(struct sam_ssc_s *priv); +#endif +#ifdef CONFIG_SAMA5_SSC1 +static void ssc1_configure(struct sam_ssc_s *priv); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* I2S device operations */ + +static const struct i2s_ops_s g_sscops = +{ + /* Receiver methods */ + + .i2s_rxsamplerate = ssc_rxsamplerate, + .i2s_rxdatawidth = ssc_rxdatawidth, + .i2s_receive = ssc_receive, + + /* Transmitter methods */ + + .i2s_txsamplerate = ssc_txsamplerate, + .i2s_txdatawidth = ssc_txdatawidth, + .i2s_send = ssc_send, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssc_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SSC_REGDEBUG +static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval, + uint32_t regaddr) +{ + if (wr == priv->wr && /* Same kind of access? */ + regval == priv->regval && /* Same value? */ + regaddr == priv->regaddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->count++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->count > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->count); + } + + /* Save information about the new access */ + + priv->wr = wr; + priv->regval = regval; + priv->regaddr = regaddr; + priv->count = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: ssc_getreg + * + * Description: + * Read an SSC register + * + ****************************************************************************/ + +static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, + unsigned int offset) +{ + uint32_t regaddr = priv->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_SSC_REGDEBUG + if (ssc_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: ssc_putreg + * + * Description: + * Write a value to an SSC register + * + ****************************************************************************/ + +static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset, + uint32_t regval) +{ + uint32_t regaddr = priv->base + offset; + +#ifdef CONFIG_SAMA5_SSC_REGDEBUG + if (ssc_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: ssc_physregaddr + * + * Description: + * Return the physical address of an SSC register + * + ****************************************************************************/ + +static inline uintptr_t ssc_physregaddr(struct sam_ssc_s *priv, + unsigned int offset) +{ + return sam_physregaddr(priv->base + offset); +} + +/**************************************************************************** + * Name: scc_dump_regs + * + * Description: + * Dump the contents of all SSC registers + * + * Input Parameters: + * priv - The SSC controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_I2S) && defined(CONFIG_DEBUG_VERBOSE) +static void scc_dump_regs(struct sam_ssc_s *priv, const char *msg) +{ + i2svdbg("SSC%d: %s\n", priv->sscno, msg); + i2svdbg(" CMR:%08x RCMR:%08x RFMR:%08x TCMR:%08x\n", + getreg32(priv->base + SAM_SSC_CMR_OFFSET), + getreg32(priv->base + SAM_SSC_RCMR_OFFSET), + getreg32(priv->base + SAM_SSC_RFMR_OFFSET), + getreg32(priv->base + SAM_SSC_TCMR_OFFSET)); + i2svdbg(" TFMR:%08x RC0R:%08x RC1R:%08x SR:%08x\n", + getreg32(priv->base + SAM_SSC_TFMR_OFFSET), + getreg32(priv->base + SAM_SSC_RC0R_OFFSET), + getreg32(priv->base + SAM_SSC_RC1R_OFFSET), + getreg32(priv->base + SAM_SSC_SR_OFFSET)); + i2svdbg(" IMR:%08x WPMR:%08x WPSR:%08x\n", + getreg32(priv->base + SAM_SSC_IMR_OFFSET), + getreg32(priv->base + SAM_SSC_WPMR_OFFSET), + getreg32(priv->base + SAM_SSC_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: ssc_dump_queues + * + * Description: + * Dump the contents of transport queues + * + * Input Parameters: + * priv - The SSC controller to dump + * xpt - The transport to be dumped + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SSC_QDEBUG +static void ssc_dump_queue(sq_queue_t *queue) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + sq_entry_t *entry; + + for (entry = queue->head; entry; entry = entry->flink) + { + bfcontainer = (struct sam_buffer_s *)entry; + apb = bfcontainer->apb; + + if (!apb) + { + i2sllvdbg(" %p: No buffer\n", bfcontainer); + } + else + { + i2sllvdbg(" %p: buffer=%p nmaxbytes=%d nbytes=%d\n", + bfcontainer, apb, apb->nmaxbytes, apb->nbytes); + } + } +} + +static void ssc_dump_queues(struct sam_transport_s *xpt, const char *msg) +{ + irqstate_t flags; + + flags = enter_critical_section(); + i2sllvdbg("%s\n", msg); + i2sllvdbg(" Pending:\n"); + ssc_dump_queue(&xpt->pend); + i2sllvdbg(" Active:\n"); + ssc_dump_queue(&xpt->act); + i2sllvdbg(" Done:\n"); + ssc_dump_queue(&xpt->done); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: ssc_exclsem_take + * + * Description: + * Take the exclusive access semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the SSC peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_exclsem_take(struct sam_ssc_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->exclsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: ssc_bufsem_take + * + * Description: + * Take the buffer semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the SSC peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_bufsem_take(struct sam_ssc_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->bufsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: ssc_buf_allocate + * + * Description: + * Allocate a buffer container by removing the one at the head of the + * free list + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * A non-NULL pointer to the allocate buffer container on success; NULL if + * there are no available buffer containers. + * + * Assumptions: + * The caller does NOT have exclusive access to the SSC state structure. + * That would result in a deadlock! + * + ****************************************************************************/ + +static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + + /* Set aside a buffer container. By doing this, we guarantee that we will + * have at least one free buffer container. + */ + + ssc_bufsem_take(priv); + + /* Get the buffer from the head of the free list */ + + flags = enter_critical_section(); + bfcontainer = priv->freelist; + ASSERT(bfcontainer); + + /* Unlink the buffer from the freelist */ + + priv->freelist = bfcontainer->flink; + leave_critical_section(flags); + return bfcontainer; +} + +/**************************************************************************** + * Name: ssc_buf_free + * + * Description: + * Free buffer container by adding it to the head of the free list + * + * Input Parameters: + * priv - SSC state instance + * bfcontainer - The buffer container to be freed + * + * Returned Value: + * None + * + * Assumptions: + * The caller has exclusive access to the SSC state structure + * + ****************************************************************************/ + +static void ssc_buf_free(struct sam_ssc_s *priv, struct sam_buffer_s *bfcontainer) +{ + irqstate_t flags; + + /* Put the buffer container back on the free list */ + + flags = enter_critical_section(); + bfcontainer->flink = priv->freelist; + priv->freelist = bfcontainer; + leave_critical_section(flags); + + /* Wake up any threads waiting for a buffer container */ + + ssc_bufsem_give(priv); +} + +/**************************************************************************** + * Name: ssc_buf_initialize + * + * Description: + * Initialize the buffer container allocator by adding all of the + * pre-allocated buffer containers to the free list + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + * Assumptions: + * Called early in SSC initialization so that there are no issues with + * concurrency. + * + ****************************************************************************/ + +static void ssc_buf_initialize(struct sam_ssc_s *priv) +{ + int i; + + priv->freelist = NULL; + sem_init(&priv->bufsem, 0, CONFIG_SAMA5_SSC_MAXINFLIGHT); + + for (i = 0; i < CONFIG_SAMA5_SSC_MAXINFLIGHT; i++) + { + ssc_buf_free(priv, &priv->containers[i]); + } +} + +/**************************************************************************** + * Name: ssc_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMA5_SSC_DMADEBUG) + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +static void ssc_dma_sampleinit(struct sam_ssc_s *priv, + struct sam_transport_s *xpt) +{ + /* Put contents of register samples into a known state */ + + memset(xpt->dmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(xpt->dma, &xpt->dmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_sampledone + * + * Description: + * Dump sampled RX DMA registers + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result) +{ + lldbg("result: %d\n", result); + + /* Sample the final registers */ + + sam_dmasample(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_INITIAL], + "RX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_AFTER_SETUP], + "RX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_AFTER_START], + "RX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timedout, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + if (result == -ETIMEDOUT || result == -EINTR) + { + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_TIMEOUT], + "RX: At DMA timeout"); + } + else + { + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_CALLBACK], + "RX: At DMA callback"); + } + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER], + "RX: At End-of-Transfer"); + + scc_dump_regs(priv, "RX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SSC_DMADEBUG) && defined(SSC_HAVE_TX) +static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result) +{ + lldbg("result: %d\n", result); + + /* Sample the final registers */ + + sam_dmasample(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_INITIAL], + "TX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_AFTER_SETUP], + "TX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_AFTER_START], + "TX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + */ + + if (result == -ETIMEDOUT || result == -EINTR) + { + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_TIMEOUT], + "TX: At DMA timeout"); + } + else + { + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_CALLBACK], + "TX: At DMA callback"); + } + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER], + "TX: At End-of-Transfer"); + + scc_dump_regs(priv, "TX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_timeout + * + * Description: + * The RX watchdog timeout without completion of the RX DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_timeout(int argc, uint32_t arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Sample DMA registers at the time of the timeout */ + + ssc_rxdma_sample(priv, DMA_TIMEOUT); + + /* Cancel the DMA */ + + sam_dmastop(priv->rx.dma); + + /* Then schedule completion of the transfer to occur on the worker thread. + * NOTE: sam_dmastop() will call the DMA complete callback with an error + * of -EINTR. So the following is just insurance and should have no + * effect if the worker is already schedule. + */ + + ssc_rx_schedule(priv, -ETIMEDOUT); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_setup + * + * Description: + * Setup and initiate the next RX DMA transfer + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static int ssc_rxdma_setup(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + uintptr_t paddr; + uintptr_t maddr; + uint32_t timeout; + bool notimeout; + int ret; + + /* If there is already an active transmission in progress, then bail + * returning success. + */ + + if (!sq_empty(&priv->rx.act)) + { + return OK; + } + + /* If there are no pending transfer, then bail returning success */ + + if (sq_empty(&priv->rx.pend)) + { + return OK; + } + + /* Initialize DMA register sampling */ + + ssc_rxdma_sampleinit(priv); + + /* Loop, adding each pending DMA */ + + timeout = 0; + notimeout = false; + + do + { + /* Remove the pending RX transfer at the head of the RX pending queue. */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.pend); + DEBUGASSERT(bfcontainer && bfcontainer->apb); + + apb = bfcontainer->apb; + DEBUGASSERT(((uintptr_t)apb->samp % priv->align) == 0); + + /* No data received yet */ + + apb->nbytes = 0; + apb->curbyte = 0; + + /* Physical address of the SSC RHR register and of the buffer location + * in RAM. + */ + + paddr = ssc_physregaddr(priv, SAM_SSC_RHR_OFFSET); + maddr = sam_physramaddr((uintptr_t)apb->samp); + + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->rx.dma, paddr, maddr, apb->nmaxbytes); + + /* Increment the DMA timeout */ + + if (bfcontainer->timeout > 0) + { + timeout += bfcontainer->timeout; + } + else + { + notimeout = true; + } + + /* Add the container to the list of active DMAs */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.act); + + /* Invalidate the data cache so that nothing gets flush into the + * DMA buffer after starting the DMA transfer. + */ + + arch_invalidate_dcache((uintptr_t)apb->samp, + (uintptr_t)apb->samp + apb->nmaxbytes); + + } +#if 1 /* REVISIT: Chained RX transfers */ + while (0); +#else + while (!sq_empty(&priv->rx.pend)); +#endif + + /* Sample DMA registers */ + + ssc_rxdma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA, saving the container as the current active transfer */ + + sam_dmastart(priv->rx.dma, ssc_rxdma_callback, priv); + ssc_rxdma_sample(priv, DMA_AFTER_START); + + /* Enable the receiver */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXEN); + + /* Start a watchdog to catch DMA timeouts */ + + if (!notimeout) + { + ret = wd_start(priv->rx.dog, timeout, (wdentry_t)ssc_rxdma_timeout, + 1, (uint32_t)priv); + + /* Check if we have successfully started the watchdog timer. Note + * that we do nothing in the case of failure to start the timer. We + * are already committed to the DMA anyway. Let's just hope that the + * DMA does not hang. + */ + + if (ret < 0) + { + i2slldbg("ERROR: wd_start failed: %d\n", errno); + } + } + + ssc_dump_rxqueues(priv, "RX DMA started"); + return OK; +} +#endif + +/**************************************************************************** + * Name: ssc_rx_worker + * + * Description: + * RX transfer done worker + * + * Input Parameters: + * arg - the SSC device instance cast to void* + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rx_worker(void *arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + irqstate_t flags; + + DEBUGASSERT(priv); + + /* When the transfer was started, the active buffer containers were removed + * from the rx.pend queue and saved in the rx.act queue. We get here when the + * DMA is finished... either successfully, with a DMA error, or with a DMA + * timeout. + * + * In any case, the buffer containers in rx.act will be moved to the end + * of the rx.done queue and rx.act queue will be emptied before this worker + * is started. + * + * REVISIT: Normal DMA callback processing should restart the DMA + * immediately to avoid audio artifacts at the boundaries between DMA + * transfers. Unfortunately, the DMA callback occurs at the interrupt + * level and we cannot call dma_rxsetup() from the interrupt level. + * So we have to start the next DMA here. + */ + + i2svdbg("rx.act.head=%p rx.done.head=%p\n", + priv->rx.act.head, priv->rx.done.head); + ssc_dump_rxqueues(priv, "RX worker start"); + + /* Check if the DMA is IDLE */ + + if (sq_empty(&priv->rx.act)) + { +#ifdef CONFIG_SAMA5_SSC_DMADEBUG + bfcontainer = (struct sam_buffer_s *)sq_peek(&priv->rx.done); + if (bfcontainer) + { + /* Dump the DMA registers */ + + ssc_rxdma_sampledone(priv, bfcontainer->result); + } +#endif + + /* Then start the next DMA. This must be done with interrupts + * disabled. + */ + + flags = enter_critical_section(); + (void)ssc_rxdma_setup(priv); + leave_critical_section(flags); + } + + /* Process each buffer in the rx.done queue */ + + while (sq_peek(&priv->rx.done) != NULL) + { + /* Remove the buffer container from the rx.done queue. NOTE that + * interrupts must be enabled to do this because the rx.done queue is + * also modified from the interrupt level. + */ + + flags = enter_critical_section(); + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.done); + leave_critical_section(flags); + + DEBUGASSERT(bfcontainer && bfcontainer->apb && bfcontainer->callback); + apb = bfcontainer->apb; + + /* If the DMA was successful, then update the number of valid bytes in + * the audio buffer. + */ + + if (bfcontainer->result == OK) + { + apb->nbytes = apb->nmaxbytes; + } + + ssc_dump_buffer("Received", apb->samp, apb->nbytes); + + /* Perform the RX transfer done callback */ + + bfcontainer->callback(&priv->dev, apb, bfcontainer->arg, + bfcontainer->result); + + /* Release our reference on the audio buffer. This may very likely + * cause the audio buffer to be freed. + */ + + apb_free(apb); + + /* And release the buffer container */ + + ssc_buf_free(priv, bfcontainer); + } + + ssc_dump_rxqueues(priv, "RX worker done"); +} +#endif + +/**************************************************************************** + * Name: ssc_rx_schedule + * + * Description: + * An RX DMA completion or timeout has occurred. Schedule processing on + * the working thread. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rx_schedule(struct sam_ssc_s *priv, int result) +{ + struct sam_buffer_s *bfcontainer; + int ret; + + /* Upon entry, the transfer(s) that just completed are the ones in the + * priv->rx.act queue. NOTE: In certain conditions, this function may + * be called an additional time, hence, we can't assert this to be true. + * For example, in the case of a timeout, this function will be called by + * both indirectly via the sam_dmastop() logic and directly via the + * ssc_rxdma_timeout() logic. + */ + + ssc_dump_rxqueues(priv, "RX schedule"); + + /* Move all entries from the rx.act queue to the rx.done queue */ + + while (!sq_empty(&priv->rx.act)) + { + /* Remove the next buffer container from the rx.act list */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.act); + + /* Report the result of the transfer */ + + bfcontainer->result = result; + + /* Add the completed buffer container to the tail of the rx.done queue */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.done); + } + + /* If the worker has completed running, then reschedule the working thread. + * REVISIT: There may be a race condition here. So we do nothing is the + * worker is not available. + */ + + if (work_available(&priv->rx.work)) + { + /* Schedule the TX DMA done processing to occur on the worker thread. */ + + ret = work_queue(HPWORK, &priv->rx.work, ssc_rx_worker, priv, 0); + if (ret != 0) + { + i2slldbg("ERROR: Failed to queue RX work: %d\n", ret); + } + } +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_callback + * + * Description: + * This callback function is invoked at the completion of the SSC RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_callback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->rx.dog); + + /* Sample DMA registers at the time of the DMA completion */ + + ssc_rxdma_sample(priv, DMA_CALLBACK); + + /* REVISIT: We would like to the next DMA started here so that we do not + * get audio glitches at the boundaries between DMA transfers. + * Unfortunately, we cannot call sam_dmasetup() from an interrupt handler! + */ + + /* Then schedule completion of the transfer to occur on the worker thread */ + + ssc_rx_schedule(priv, result); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_timeout + * + * Description: + * The RX watchdog timeout without completion of the RX DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_txdma_timeout(int argc, uint32_t arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Sample DMA registers at the time of the timeout */ + + ssc_txdma_sample(priv, DMA_TIMEOUT); + + /* Cancel the DMA */ + + sam_dmastop(priv->tx.dma); + + /* Then schedule completion of the transfer to occur on the worker thread. + * NOTE: sam_dmastop() will call the DMA complete callback with an error + * of -EINTR. So the following is just insurance and should have no + * effect if the worker is already schedule. + */ + + ssc_tx_schedule(priv, -ETIMEDOUT); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_setup + * + * Description: + * Setup and initiate the next TX DMA transfer + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static int ssc_txdma_setup(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + uintptr_t samp; + uintptr_t paddr; + uintptr_t maddr; + uint32_t timeout; + apb_samp_t nbytes; + bool notimeout; + int ret; + + /* If there is already an active transmission in progress, then bail + * returning success. + */ + + if (!sq_empty(&priv->tx.act)) + { + return OK; + } + + /* If there are no pending transfer, then bail returning success */ + + if (sq_empty(&priv->tx.pend)) + { + return OK; + } + + /* Initialize DMA register sampling */ + + ssc_txdma_sampleinit(priv); + + /* Loop, adding each pending DMA */ + + timeout = 0; + notimeout = false; + + do + { + /* Remove the pending TX transfer at the head of the TX pending queue. */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.pend); + DEBUGASSERT(bfcontainer && bfcontainer->apb); + + apb = bfcontainer->apb; + + /* Get the transfer information, accounting for any data offset */ + + samp = (uintptr_t)&apb->samp[apb->curbyte]; + nbytes = apb->nbytes - apb->curbyte; + DEBUGASSERT((samp & priv->align) == 0 && (nbytes & priv->align) == 0); + + /* Physical address of the SSC THR register and of the buffer location + * in RAM. + */ + + paddr = ssc_physregaddr(priv, SAM_SSC_THR_OFFSET); + maddr = sam_physramaddr(samp); + + /* Configure the TX DMA */ + + sam_dmatxsetup(priv->tx.dma, paddr, maddr, nbytes); + + /* Increment the DMA timeout */ + + if (bfcontainer->timeout > 0) + { + timeout += bfcontainer->timeout; + } + else + { + notimeout = true; + } + + /* Add the container to the list of active DMAs */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.act); + + /* Flush the data cache so that everything is in the physical memory + * before starting the DMA. + */ + + arch_clean_dcache(samp, samp + nbytes); + } +#if 1 /* REVISIT: Chained TX transfers */ + while (0); +#else + while (!sq_empty(&priv->tx.pend)); +#endif + + /* Sample DMA registers */ + + ssc_txdma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA, saving the container as the current active transfer */ + + sam_dmastart(priv->tx.dma, ssc_txdma_callback, priv); + ssc_txdma_sample(priv, DMA_AFTER_START); + + /* Enable the transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_TXEN); + + /* Start a watchdog to catch DMA timeouts */ + + if (!notimeout) + { + ret = wd_start(priv->tx.dog, timeout, (wdentry_t)ssc_txdma_timeout, + 1, (uint32_t)priv); + + /* Check if we have successfully started the watchdog timer. Note + * that we do nothing in the case of failure to start the timer. We + * are already committed to the DMA anyway. Let's just hope that the + * DMA does not hang. + */ + + if (ret < 0) + { + i2slldbg("ERROR: wd_start failed: %d\n", errno); + } + } + + ssc_dump_txqueues(priv, "TX DMA started"); + return OK; +} +#endif + +/**************************************************************************** + * Name: ssc_tx_worker + * + * Description: + * TX transfer done worker + * + * Input Parameters: + * arg - the SSC device instance cast to void* + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_tx_worker(void *arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + + DEBUGASSERT(priv); + + /* When the transfer was started, the active buffer containers were removed + * from the tx.pend queue and saved in the tx.act queue. We get here when the + * DMA is finished... either successfully, with a DMA error, or with a DMA + * timeout. + * + * In any case, the buffer containers in tx.act will be moved to the end + * of the tx.done queue and tx.act will be emptied before this worker is + * started. + * + * REVISIT: Normal DMA callback processing should restart the DMA + * immediately to avoid audio artifacts at the boundaries between DMA + * transfers. Unfortunately, the DMA callback occurs at the interrupt + * level and we cannot call dma_txsetup() from the interrupt level. + * So we have to start the next DMA here. + */ + + i2svdbg("tx.act.head=%p tx.done.head=%p\n", + priv->tx.act.head, priv->tx.done.head); + ssc_dump_txqueues(priv, "TX worker start"); + + /* Check if the DMA is IDLE */ + + if (sq_empty(&priv->tx.act)) + { +#ifdef CONFIG_SAMA5_SSC_DMADEBUG + bfcontainer = (struct sam_buffer_s *)sq_peek(&priv->tx.done); + if (bfcontainer) + { + /* Dump the DMA registers */ + + ssc_txdma_sampledone(priv, bfcontainer->result); + } +#endif + + /* Then start the next DMA. This must be done with interrupts + * disabled. + */ + + flags = enter_critical_section(); + (void)ssc_txdma_setup(priv); + leave_critical_section(flags); + } + + /* Process each buffer in the tx.done queue */ + + while (sq_peek(&priv->tx.done) != NULL) + { + /* Remove the buffer container from the tx.done queue. NOTE that + * interrupts must be enabled to do this because the tx.done queue is + * also modified from the interrupt level. + */ + + flags = enter_critical_section(); + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.done); + leave_critical_section(flags); + + /* Perform the TX transfer done callback */ + + DEBUGASSERT(bfcontainer && bfcontainer->callback); + bfcontainer->callback(&priv->dev, bfcontainer->apb, + bfcontainer->arg, bfcontainer->result); + + /* Release our reference on the audio buffer. This may very likely + * cause the audio buffer to be freed. + */ + + apb_free(bfcontainer->apb); + + /* And release the buffer container */ + + ssc_buf_free(priv, bfcontainer); + } + + ssc_dump_txqueues(priv, "TX worker done"); +} +#endif + +/**************************************************************************** + * Name: ssc_tx_schedule + * + * Description: + * An TX DMA completion or timeout has occurred. Schedule processing on + * the working thread. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + * Assumptions: + * - Interrupts are disabled + * - The TX timeout has been canceled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_tx_schedule(struct sam_ssc_s *priv, int result) +{ + struct sam_buffer_s *bfcontainer; + int ret; + + /* Upon entry, the transfer(s) that just completed are the ones in the + * priv->tx.act queue. NOTE: In certain conditions, this function may + * be called an additional time, hence, we can't assert this to be true. + * For example, in the case of a timeout, this function will be called by + * both indirectly via the sam_dmastop() logic and directly via the + * ssc_txdma_timeout() logic. + */ + + ssc_dump_txqueues(priv, "TX schedule"); + + /* Move all entries from the tx.act queue to the tx.done queue */ + + while (!sq_empty(&priv->tx.act)) + { + /* Remove the next buffer container from the tx.act list */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.act); + + /* Report the result of the transfer */ + + bfcontainer->result = result; + + /* Add the completed buffer container to the tail of the tx.done queue */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.done); + } + + /* If the worker has completed running, then reschedule the working thread. + * REVISIT: There may be a race condition here. So we do nothing is the + * worker is not available. + */ + + if (work_available(&priv->tx.work)) + { + /* Schedule the TX DMA done processing to occur on the worker thread. */ + + ret = work_queue(HPWORK, &priv->tx.work, ssc_tx_worker, priv, 0); + if (ret != 0) + { + i2slldbg("ERROR: Failed to queue TX work: %d\n", ret); + } + } +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_callback + * + * Description: + * This callback function is invoked at the completion of the SSC TX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_txdma_callback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->tx.dog); + + /* Sample DMA registers at the time of the DMA completion */ + + ssc_txdma_sample(priv, DMA_CALLBACK); + + /* REVISIT: We would like to the next DMA started here so that we do not + * get audio glitches at the boundaries between DMA transfers. + * Unfortunately, we cannot call sam_dmasetup() from an interrupt handler! + */ + + /* Then schedule completion of the transfer to occur on the worker thread */ + + ssc_tx_schedule(priv, result); +} +#endif + +/**************************************************************************** + * Name: ssc_checkwidth + * + * Description: + * Check for a valid bit width. The SSC is capable of handling most any + * bit width from 2 to 32, but the DMA logic in this driver is constrained + * to 8-, 16-, and 32-bit data widths + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static int ssc_checkwidth(struct sam_ssc_s *priv, int bits) +{ + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + + switch (bits) + { + case 8: +#ifdef CONFIG_DEBUG + priv->align = 0; +#endif + break; + + case 16: +#ifdef CONFIG_DEBUG + priv->align = 1; +#endif + break; + + case 32: +#ifdef CONFIG_DEBUG + priv->align = 3; +#endif + break; + + default: + i2sdbg("ERROR: Unsupported or invalid data width: %d\n", bits); + return (bits < 2 || bits > 32) ? -EINVAL : -ENOSYS; + } + + /* Save the new data width */ + + priv->datalen = bits; + return OK; +} + +/**************************************************************************** + * Name: ssc_rxsamplerate + * + * Description: + * Set the I2S RX sample rate. NOTE: This will have no effect if (1) the + * driver does not support an I2C receiver or if (2) the sample rate is + * driven by the I2C frame clock. This may also have unexpected side- + * effects of the RX sample is coupled with the TX sample rate. + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_rxsamplerate(struct i2s_dev_s *dev, uint32_t rate) +{ +#if defined(SSC_HAVE_RX) && defined(SSC_HAVE_MCK2) + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + DEBUGASSERT(priv && priv->samplerate > 0 && rate > 0); + + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->rxclk == SSC_CLKSRC_MCKDIV) + { + /* Save the new sample rate and update the MCK/2 divider */ + + priv->samplerate = rate; + return ssc_mck2divider(priv); + } +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_rxdatawidth + * + * Description: + * Set the I2S RX data width. The RX bitrate is determined by + * sample_rate * data_width. + * + * Input Parameters: + * dev - Device-specific state data + * width - The I2S data with in bits. + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_rxdatawidth(struct i2s_dev_s *dev, int bits) +{ +#ifdef SSC_HAVE_RX + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + uint32_t dmaflags; + int ret; + + DEBUGASSERT(priv && bits > 1); + + /* Check if this is a bit width that we are configured to handle */ + + ret = ssc_checkwidth(priv, bits); + if (ret < 0) + { + i2sdbg("ERROR: ssc_checkwidth failed: %d\n", ret); + return 0; + } + + /* Update the DMA flags */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return 0; + } + + /* Reconfigure the RX DMA (and TX DMA if applicable) */ + + sam_dmaconfig(priv->rx.dma, dmaflags); +#ifdef SSC_HAVE_RX + if (priv->txenab) + { + sam_dmaconfig(priv->tx.dma, dmaflags); + } +#endif + +#ifdef SSC_HAVE_MCK2 + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->rxclk == SSC_CLKSRC_MCKDIV) + { + /* Update the MCK/2 divider. bitrate is samplerate * datawidth. */ + + return ssc_mck2divider(priv); + } +#endif +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_receive + * + * Description: + * Receive a block of data from I2S. + * + * Input Parameters: + * dev - Device-specific state data + * apb - A pointer to the audio buffer in which to recieve data + * callback - A user provided callback function that will be called at + * the completion of the transfer. The callback will be + * performed in the context of the worker thread. + * arg - An opaque argument that will be provided to the callback + * when the transfer complete + * timeout - The timeout value to use. The transfer will be canceled + * and an ETIMEDOUT error will be reported if this timeout + * elapsed without completion of the DMA transfer. Units + * are system clock ticks. Zero means no timeout. + * + * Returned Value: + * OK on success; a negated errno value on failure. NOTE: This function + * only enqueues the transfer and returns immediately. Success here only + * means that the transfer was enqueued correctly. + * + * When the transfer is complete, a 'result' value will be provided as + * an argument to the callback function that will indicate if the transfer + * failed. + * + ****************************************************************************/ + +static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; +#ifdef SSC_HAVE_RX + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + int ret; +#endif + + DEBUGASSERT(priv && apb && ((uintptr_t)apb->samp & priv->align) == 0); + i2svdbg("apb=%p nmaxbytes=%d arg=%p timeout=%d\n", + apb, apb->nmaxbytes, arg, timeout); + + ssc_init_buffer(apb->samp, apb->nmaxbytes); + +#ifdef SSC_HAVE_RX + /* Allocate a buffer container in advance */ + + bfcontainer = ssc_buf_allocate(priv); + DEBUGASSERT(bfcontainer); + + /* Get exclusive access to the SSC driver data */ + + ssc_exclsem_take(priv); + + /* Has the RX channel been enabled? */ + + if (!priv->rxenab) + { + i2sdbg("ERROR: SSC%d has no receiver\n", priv->sscno); + ret = -EAGAIN; + goto errout_with_exclsem; + } + + /* Add a reference to the audio buffer */ + + apb_reference(apb); + + /* Initialize the buffer container structure */ + + bfcontainer->callback = (void *)callback; + bfcontainer->timeout = timeout; + bfcontainer->arg = arg; + bfcontainer->apb = apb; + bfcontainer->result = -EBUSY; + + /* Add the buffer container to the end of the RX pending queue */ + + flags = enter_critical_section(); + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend); + ssc_dump_rxqueues(priv, "Receving"); + + /* Then start the next transfer. If there is already a transfer in progess, + * then this will do nothing. + */ + + ret = ssc_rxdma_setup(priv); + DEBUGASSERT(ret == OK); + leave_critical_section(flags); + ssc_exclsem_give(priv); + return OK; + +errout_with_exclsem: + ssc_exclsem_give(priv); + ssc_buf_free(priv, bfcontainer); + return ret; + +#else + i2sdbg("ERROR: SSC%d has no receiver\n", priv->sscno); + UNUSED(priv); + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: ssc_txsamplerate + * + * Description: + * Set the I2S TX sample rate. NOTE: This will have no effect if (1) the + * driver does not support an I2C transmitter or if (2) the sample rate is + * driven by the I2C frame clock. This may also have unexpected side- + * effects of the TX sample is coupled with the RX sample rate. + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_txsamplerate(struct i2s_dev_s *dev, uint32_t rate) +{ +#if defined(SSC_HAVE_TX) && defined(SSC_HAVE_MCK2) + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + DEBUGASSERT(priv && priv->samplerate > 0 && rate > 0); + + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + /* Save the new sample rate and update the MCK/2 divider */ + + priv->samplerate = rate; + return ssc_mck2divider(priv); + } +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_txdatawidth + * + * Description: + * Set the I2S TX data width. The TX bitrate is determined by + * sample_rate * data_width. + * + * Input Parameters: + * dev - Device-specific state data + * width - The I2S data with in bits. + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_txdatawidth(struct i2s_dev_s *dev, int bits) +{ +#ifdef SSC_HAVE_TX + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + uint32_t dmaflags; + int ret; + + DEBUGASSERT(priv && bits > 1); + + /* Check if this is a bit width that we are configured to handle */ + + ret = ssc_checkwidth(priv, bits); + if (ret < 0) + { + i2sdbg("ERROR: ssc_checkwidth failed: %d\n", ret); + return 0; + } + + /* Upate the DMA flags */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return 0; + } + + /* Reconfigure the RX DMA (and RX DMA if applicable) */ + + sam_dmaconfig(priv->tx.dma, dmaflags); +#ifdef SSC_HAVE_RX + if (priv->rxenab) + { + sam_dmaconfig(priv->rx.dma, dmaflags); + } +#endif + +#ifdef SSC_HAVE_MCK2 + /* Check if the transmitter is driven by the MCK/2 */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + /* Update the MCK/2 divider. bitrate is samplerate * datawidth. */ + + return ssc_mck2divider(priv); + } +#endif +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_send + * + * Description: + * Send a block of data on I2S. + * + * Input Parameters: + * dev - Device-specific state data + * apb - A pointer to the audio buffer from which to send data + * callback - A user provided callback function that will be called at + * the completion of the transfer. The callback will be + * performed in the context of the worker thread. + * arg - An opaque argument that will be provided to the callback + * when the transfer complete + * timeout - The timeout value to use. The transfer will be canceled + * and an ETIMEDOUT error will be reported if this timeout + * elapsed without completion of the DMA transfer. Units + * are system clock ticks. Zero means no timeout. + * + * Returned Value: + * OK on success; a negated errno value on failure. NOTE: This function + * only enqueues the transfer and returns immediately. Success here only + * means that the transfer was enqueued correctly. + * + * When the transfer is complete, a 'result' value will be provided as + * an argument to the callback function that will indicate if the transfer + * failed. + * + ****************************************************************************/ + +static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; +#ifdef SSC_HAVE_TX + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + int ret; +#endif + + /* Make sure that we have valid pointers that that the data has uint32_t + * alignment. + */ + + DEBUGASSERT(priv && apb); + i2svdbg("apb=%p nbytes=%d arg=%p timeout=%d\n", + apb, apb->nbytes - apb->curbyte, arg, timeout); + + ssc_dump_buffer("Sending", &apb->samp[apb->curbyte], + apb->nbytes - apb->curbyte); + DEBUGASSERT(((uintptr_t)&apb->samp[apb->curbyte] & priv->align) == 0); + +#ifdef SSC_HAVE_TX + /* Allocate a buffer container in advance */ + + bfcontainer = ssc_buf_allocate(priv); + DEBUGASSERT(bfcontainer); + + /* Get exclusive access to the SSC driver data */ + + ssc_exclsem_take(priv); + + /* Has the TX channel been enabled? */ + + if (!priv->txenab) + { + i2sdbg("ERROR: SSC%d has no transmitter\n", priv->sscno); + ret = -EAGAIN; + goto errout_with_exclsem; + } + + /* Add a reference to the audio buffer */ + + apb_reference(apb); + + /* Initialize the buffer container structure */ + + bfcontainer->callback = (void *)callback; + bfcontainer->timeout = timeout; + bfcontainer->arg = arg; + bfcontainer->apb = apb; + bfcontainer->result = -EBUSY; + + /* Add the buffer container to the end of the TX pending queue */ + + flags = enter_critical_section(); + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend); + ssc_dump_txqueues(priv, "Transmitting"); + + /* Then start the next transfer. If there is already a transfer in progess, + * then this will do nothing. + */ + + ret = ssc_txdma_setup(priv); + DEBUGASSERT(ret == OK); + leave_critical_section(flags); + ssc_exclsem_give(priv); + return OK; + +errout_with_exclsem: + ssc_exclsem_give(priv); + ssc_buf_free(priv, bfcontainer); + return ret; + +#else + i2sdbg("ERROR: SSC%d has no transmitter\n", priv->sscno); + UNUSED(priv); + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: ssc_rx/tx_configure + * + * Description: + * Configure the SSC receiver and transmitter. + * + * Input Parameters: + * priv - Fully initialized SSC device structure. + * + * Returned Value: + * OK is returned on failure. A negated errno value is returned on failure. + * + ****************************************************************************/ + +static int ssc_rx_configure(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_RX + uint32_t regval; + uint32_t fslen; + + /* Get the RX sync time (in RX clocks) */ + + DEBUGASSERT(priv->rxfslen > 0); + fslen = priv->rxfslen - 1; + + /* RCMR settings */ + /* Configure the receiver input clock */ + + regval = 0; + switch (priv->rxclk) + { + case SSC_CLKSRC_RKIN: /* Receiver clock source is RK */ + regval = SSC_RCMR_CKS_RK; + break; + + case SSC_CLKSRC_TXOUT: /* Receiver clock source is the transmitter clock */ + regval = SSC_RCMR_CKS_TK; + break; + + case SSC_CLKSRC_MCKDIV: /* Clock source is MCK divided down */ +#ifdef SSC_HAVE_MCK2 + DEBUGASSERT(priv->samplerate > 0); + regval = SSC_RCMR_CKS_MCK; + break; +#endif + + case SSC_CLKSRC_NONE: /* No clock */ + default: + i2sdbg("ERROR: No receiver clock\n"); + return -EINVAL; + } + + /* Configure the receiver output clock */ + + switch (priv->rxout) + { + case SSC_CLKOUT_CONT: /* Continuous */ + regval |= SSC_RCMR_CKO_CONT; + break; + + case SSC_CLKOUT_XFER: /* Only output clock during transfers */ + regval |= SSC_RCMR_CKO_TRANSFER; + break; + + case SSC_CLKOUT_NONE: /* No output clock */ + regval |= SSC_RCMR_CKO_NONE; + break; + + default: + i2sdbg("ERROR: Invalid clock output selection\n"); + return -EINVAL; + } + + /* REVISIT: Some of these settings will need to be configurable as well. + * Currently hardcoded to: + * + * SSC_RCMR_CKI Receive clock inversion + * SSC_RCMR_CKG_CONT No receive clock gating + * SSC_RCMR_START_EDGE Detection of any edge on RF signal + * SSC_RCMR_STOP Not selected + * SSC_RCMR_STTDLY(1) Receive start delay = 1 (same as FSLEN) + * SSC_RCMR_PERIOD(0) Receive period divider = 0 + * + * REVISIT: This implementation assumes that on the transmitter + * can be the master (i.e, can generate the TK/RK clocking. + */ + + regval |= (SSC_RCMR_CKI | SSC_RCMR_CKG_CONT | SSC_RCMR_START_EDGE | + SSC_RCMR_STTDLY(priv->rxsttdly) | SSC_RCMR_PERIOD(0)); + ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, regval); + + /* RFMR settings. Some of these settings will need to be configurable as well. + * Currently hardcoded to: + * + * SSC_RFMR_DATLEN(n) 'n' deterimined by configuration + * SSC_RFMR_LOOP Determined by configuration + * SSC_RFMR_MSBF Most significant bit first + * SSC_RFMR_DATNB(n) Data number 'n' per frame (hard-coded) + * SSC_RFMR_FSLEN Set to LS 4 bits of (CONFIG_SSCx_RX_FSLEN-1) + * SSC_RFMR_FSLEN(1) Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 = 2 clocks + * SSC_RFMR_FSOS_NONE RF pin is always in input + * SSC_RFMR_FSEDGE_POS Positive frame sync edge detection + * SSC_RFMR_FSLENEXT I Set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + */ + + regval = (SSC_RFMR_DATLEN(CONFIG_SAMA5_SSC0_DATALEN - 1) | SSC_RFMR_MSBF | + SSC_RFMR_DATNB(SSC_DATNB - 1) | SSC_RFMR_FSOS_NONE); + + /* Set the RX frame synch */ + + regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) | SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f)); + + /* Loopback mode? */ + + if (priv->loopback) + { + regval |= SSC_RFMR_LOOP; + } + + ssc_putreg(priv, SAM_SSC_RFMR_OFFSET, regval); + +#else + ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, 0); + ssc_putreg(priv, SAM_SSC_RFMR_OFFSET, 0); + +#endif + + /* Disable the receiver */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS); + return OK; +} + +static int ssc_tx_configure(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_TX + uint32_t regval; + uint32_t fslen; + uint32_t period; + + /* Get the TX synch in (in TX clocks) */ + + fslen = priv->txfslen > 0 ? priv->txfslen - 1 : 0; + + /* From the start delay and the datalength , we can get the full + * period of the waveform. + */ + + period = SCC_PERIOD(priv->txsttdly, priv->datalen); + + /* TCMR settings */ + /* Configure the transmitter input clock */ + + regval = 0; + switch (priv->txclk) + { + case SSC_CLKSRC_TKIN: /* Transmitter clock source is TK */ + regval = SSC_TCMR_CKS_TK; + break; + + case SSC_CLKSRC_RXOUT: /* Transmitter clock source is the receiver clock */ + regval = SSC_TCMR_CKS_RK; + break; + + case SSC_CLKSRC_MCKDIV: /* Clock source is MCK divided down */ +#ifdef SSC_HAVE_MCK2 + DEBUGASSERT(priv->samplerate > 0); + regval = SSC_TCMR_CKS_MCK; + break; +#endif + + case SSC_CLKSRC_NONE: /* No clock */ + default: + i2sdbg("ERROR: No transmitter clock\n"); + return -EINVAL; + } + + /* Configure the receiver output clock */ + + switch (priv->txout) + { + case SSC_CLKOUT_CONT: /* Continuous */ + regval |= SSC_TCMR_CKO_CONT; + break; + + case SSC_CLKOUT_XFER: /* Only output clock during transfers */ + regval |= SSC_TCMR_CKO_TRANSFER; + break; + + case SSC_CLKOUT_NONE: /* No output clock */ + regval |= SSC_TCMR_CKO_NONE; + break; + + default: + i2sdbg("ERROR: Invalid clock output selection\n"); + return -EINVAL; + } + + /* REVISIT: Some of these settings will need to be configurable as well. + * Currently hard-coded to: + * + * SSC_RCMR_CKI No transmitter clock inversion + * SSC_RCMR_CKG_CONT No transmit clock gating + * SSC_TCMR_STTDLY(1) Receive start delay = 2 clocks (same as FSLEN) + * + * If master (i.e., provides clocking): + * SSC_TCMR_START_CONT When data written to THR + * SSC_TCMR_PERIOD(n) 'n' depends on the datawidth + * + * If slave (i.e., receives clocking): + * SSC_TCMR_START_EDGE Detection of any edge on TF signal + * SSC_TCMR_PERIOD(0) Receive period divider = 0 + * + * The period signal is generated at clocks = 2 x (PERIOD+1), or + * PERIOD = (clocks / 2) - 1. + */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_CONT | + SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(period / 2 - 1)); + } + else + { + regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_EDGE | + SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(0)); + } + + ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, regval); + + /* TFMR settings. Some of these settings will need to be configurable as well. + * Currently set to: + * + * SSC_TFMR_DATLEN(n) 'n' determined by configuration + * SSC_TFMR_DATDEF Data default = 0 + * SSC_TFMR_MSBF Most significant bit first + * SSC_TFMR_DATNB(n) Data number 'n' per frame (hard-coded) + * SSC_TFMR_FSDEN Enabled if CONFIG_SSCx_TX_FSLEN > 0 + * SSC_TFMR_FSLEN If enabled, set to LS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + * SSC_TFMR_FSLENEXT If enabled, set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + * + * If master (i.e., provides clocking): + * SSC_TFMR_FSOS_NEGATIVE Negative pulse TF output + * + * If slave (i.e, receives clocking): + * SSC_TFMR_FSOS_NONE TF is an output + */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + regval = (SSC_TFMR_DATLEN(priv->datalen - 1) | + SSC_TFMR_MSBF | SSC_TFMR_DATNB(SSC_DATNB - 1) | + SSC_TFMR_FSOS_NEGATIVE); + } + else + { + regval = (SSC_TFMR_DATLEN(priv->datalen - 1) | + SSC_TFMR_MSBF | SSC_TFMR_DATNB(SSC_DATNB - 1) | + SSC_TFMR_FSOS_NONE); + } + + /* Is the TX frame synch enabled? */ + + if (priv->txfslen > 0) + { + /* Yes.. Set the FSDEN bit and the FSLEN field */ + + regval |= (SSC_TFMR_FSDEN | SSC_TFMR_FSLEN(fslen & 0x0f) | + SSC_TFMR_FSLENEXT((fslen >> 4) & 0x0f)); + } + + ssc_putreg(priv, SAM_SSC_TFMR_OFFSET, regval); + +#else + ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, 0); + ssc_putreg(priv, SAM_SSC_TFMR_OFFSET, 0); + +#endif + + /* Disable the transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_TXDIS); + return OK; +} + +/**************************************************************************** + * Name: ssc_mck2divider + * + * Description: + * Setup the MCK/2 divider based on the currently selected data width and + * the sample rate + * + * Input Parameter: + * priv - I2C device structure (only the sample rate and data length is + * needed at this point). + * + * Returned Value: + * The current bitrate + * + ****************************************************************************/ + +static uint32_t ssc_mck2divider(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_MCK2 + uint32_t bitrate; + uint32_t regval; + DEBUGASSERT(priv && priv->samplerate > 0 && priv->datalen > 0); + + /* A zero sample rate means to disable the MCK/2 clock */ + + if (priv->samplerate == 0) + { + bitrate = 0; + regval = 0; + } + else + { + /* Calculate the new bitrate in Hz */ + + bitrate = priv->samplerate * priv->datalen; + + /* Calculate the new MCK/2 divider from the bitrate. The divided clock + * equals: + * + * bitrate = MCK / (2 * div) + * div = MCK / (2 * bitrate) + * + * The maximum bit rate is MCK/2. The minimum bit rate is + * MCK/2 x 4095 = MCK/8190. + */ + + regval = (BOARD_MCK_FREQUENCY + bitrate) / (bitrate << 1); + } + + /* Configure MCK/2 divider */ + + ssc_putreg(priv, SAM_SSC_CMR_OFFSET, regval); + return bitrate; +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: ssc_clocking + * + * Description: + * Enable and configure clocking to the SSC + * + * Input Parameter: + * priv - Partially initialized I2C device structure (only the PID is + * needed at this point). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_clocking(struct sam_ssc_s *priv) +{ + uint32_t regval; + uint32_t mck; + + /* Determine the maximum SSC peripheral clock frequency */ + + mck = BOARD_MCK_FREQUENCY; +#ifdef SAMA5_HAVE_PMC_PCR_DIV + DEBUGASSERT((mck >> 3) <= SAM_SSC_MAXPERCLK); + + if (mck <= SAM_SSC_MAXPERCLK) + { + priv->frequency = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= SAM_SSC_MAXPERCLK) + { + priv->frequency = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= SAM_SSC_MAXPERCLK) + { + priv->frequency = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else /* if ((mck >> 3) <= SAM_SSC_MAXPERCLK) */ + { + priv->frequency = (mck >> 3); + regval = PMC_PCR_DIV8; + } + +#else + /* No PCR_DIV field */ + + priv->frequency = mck; + regval = 0; +#endif + + /* Set the maximum SSC peripheral clock frequency */ + + regval |= PMC_PCR_PID(priv->pid) | PMC_PCR_CMD | PMC_PCR_EN; + putreg32(regval, SAM_PMC_PCR); + + /* Reset, disable receiver & transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST); + + /* Configure MCK/2 divider */ + + (void)ssc_mck2divider(priv); + + /* Enable peripheral clocking */ + + sam_enableperiph1(priv->pid); + + i2svdbg("PCSR1=%08x PCR=%08x CMR=%08x\n", + getreg32(SAM_PMC_PCSR1), regval, + ssc_getreg(priv, SAM_SSC_CMR_OFFSET)); +} + +/**************************************************************************** + * Name: ssc_dma_flags + * + * Description: + * Determine DMA FLAGS based on PID and data width + * + * Input Parameters: + * priv - Partially initialized I2C device structure. + * dmaflags - Location to return the DMA flags. + * + * Returned Value: + * OK on success; a negated errno value on failure + * + ****************************************************************************/ + +static int ssc_dma_flags(struct sam_ssc_s *priv, uint32_t *dmaflags) +{ + uint32_t flags; + + switch (priv->datalen) + { + case 8: + flags = DMA8_FLAGS; + break; + + case 16: + flags = DMA16_FLAGS; + break; + + case 32: + flags = DMA32_FLAGS; + break; + + default: + i2sdbg("ERROR: Unsupported data width: %d\n", priv->datalen); + return -ENOSYS; + } + + *dmaflags = (flags | DMACH_FLAG_PERIPHPID(priv->pid)); + return OK; +} + +/**************************************************************************** + * Name: ssc_dma_allocate + * + * Description: + * Allocate SCC DMA channels + * + * Input Parameters: + * priv - Partially initialized I2C device structure. This function + * will complete the DMA specific portions of the initialization + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +static int ssc_dma_allocate(struct sam_ssc_s *priv) +{ + uint32_t dmaflags; + int ret; + + /* Get the DMA flags for this channel */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return ret; + } + + /* Allocate DMA channels. These allocations exploit that fact that + * SSC0 is managed by DMAC0 and SSC1 is managed by DMAC1. Hence, + * the SSC number (sscno) is the same as the DMAC number. + */ + +#ifdef SSC_HAVE_RX + if (priv->rxenab) + { + /* Allocate an RX DMA channel */ + + priv->rx.dma = sam_dmachannel(priv->sscno, dmaflags); + if (!priv->rx.dma) + { + i2sdbg("ERROR: Failed to allocate the RX DMA channel\n"); + goto errout; + } + + /* Create a watchdog time to catch RX DMA timeouts */ + + priv->rx.dog = wd_create(); + if (!priv->rx.dog) + { + i2sdbg("ERROR: Failed to create the RX DMA watchdog\n"); + goto errout; + } + } +#endif + +#ifdef SSC_HAVE_TX + if (priv->txenab) + { + /* Allocate a TX DMA channel */ + + priv->tx.dma = sam_dmachannel(priv->sscno, dmaflags); + if (!priv->tx.dma) + { + i2sdbg("ERROR: Failed to allocate the TX DMA channel\n"); + goto errout; + } + + /* Create a watchdog time to catch TX DMA timeouts */ + + priv->tx.dog = wd_create(); + if (!priv->tx.dog) + { + i2sdbg("ERROR: Failed to create the TX DMA watchdog\n"); + goto errout; + } + } +#endif + + /* Success exit */ + + return OK; + + /* Error exit */ + +errout: + ssc_dma_free(priv); + return -ENOMEM; +} + +/**************************************************************************** + * Name: ssc_dma_free + * + * Description: + * Release DMA-related resources allocated by ssc_dma_allocate() + * + * Input Parameters: + * priv - Partially initialized I2C device structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_dma_free(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_TX + if (priv->tx.dog) + { + wd_delete(priv->tx.dog); + } + + if (priv->tx.dma) + { + sam_dmafree(priv->tx.dma); + } +#endif + +#ifdef SSC_HAVE_RX + if (priv->rx.dog) + { + wd_delete(priv->rx.dog); + } + + if (priv->rx.dma) + { + sam_dmafree(priv->rx.dma); + } +#endif +} + +/**************************************************************************** + * Name: ssc0/1_configure + * + * Description: + * Configure SSC0 and/or SSC1 + * + * Input Parameters: + * priv - Partially initialized I2C device structure. These functions + * will complete the SSC specific portions of the initialization + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_SSC0 +static void ssc0_configure(struct sam_ssc_s *priv) +{ + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + +#ifdef CONFIG_SAMA5_SSC0_RX + priv->rxenab = true; + + /* Configure the receiver data (RD) and receiver frame synchro (RF) pins */ + + sam_configpio(PIO_SSC0_RD); + sam_configpio(PIO_SSC0_RF); + +#if defined(CONFIG_SAMA5_SSC0_RX_RKINPUT) + /* Configure the RK pin only if we are using an external clock to drive + * the receiver clock. + * + * REVISIT: The SSC is also capable of generated the receiver clock + * output on the RK pin. + */ + + sam_configpio(PIO_SSC0_RK); /* External clock received on the RK I/O pad */ + priv->rxclk = SSC_CLKSRC_RKIN; + +#elif defined(CONFIG_SAMA5_SSC0_RX_TXCLK) + priv->rxclk = SSC_CLKSRC_TXOUT; + +#elif defined(CONFIG_SAMA5_SSC0_RX_MCKDIV) + priv->rxclk = SSC_CLKSRC_MCKDIV; + +#else + priv->rxclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember parameters of the configured waveform */ + + priv->rxfslen = CONFIG_SSC0_RX_FSLEN; + priv->rxsttdly = CONFIG_SSC0_RX_STTDLY; + + /* Remember the configured RX clock output */ + +#if defined(CONFIG_SAMA5_SSC0_RX_RKOUTPUT_CONT) + priv->rxout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMA5_SSC0_RX_RKOUTPUT_XFR) + priv->rxout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMA5_SSC0_RX_RKOUTPUT_NONE) */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->rxenab = false; + priv->rxclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMA5_SSC0_RX */ + +#ifdef CONFIG_SAMA5_SSC0_TX + priv->txenab = true; + + /* Configure the transmitter data (TD) and transmitter frame synchro (TF) + * pins + */ + + sam_configpio(PIO_SSC0_TD); + sam_configpio(PIO_SSC0_TF); + +#if defined(CONFIG_SAMA5_SSC0_TX_TKINPUT) + /* Configure the TK pin only if we are using an external clock to drive + * the transmitter clock. + * + * REVISIT: The SSC is also capable of generated the transmitter clock + * output on the TK pin. + */ + + sam_configpio(PIO_SSC0_TK); /* External clock received on the TK I/O pad */ + priv->txclk = SSC_CLKSRC_TKIN; + +#elif defined(CONFIG_SAMA5_SSC0_TX_RXCLK) + priv->txclk = SSC_CLKSRC_RXOUT; + +#elif defined(CONFIG_SAMA5_SSC0_TX_MCKDIV) + priv->txclk = SSC_CLKSRC_MCKDIV; + +#else + priv->txclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember the configured TX clock output */ + +#if defined(CONFIG_SAMA5_SSC0_TX_TKOUTPUT_CONT) + priv->txout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMA5_SSC0_TX_TKOUTPUT_XFR) + priv->txout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMA5_SSC0_TX_TKOUTPUT_NONE) */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->txenab = false; + priv->txclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMA5_SSC0_TX */ + + /* Remember parameters of the configured waveform */ + + priv->txfslen = CONFIG_SSC0_TX_FSLEN; + priv->txsttdly = CONFIG_SSC0_TX_STTDLY; + + /* Set/clear loopback mode */ + +#if defined(CONFIG_SAMA5_SSC0_RX) && defined(CONFIG_SAMA5_SSC0_TX) && \ + defined(CONFIG_SAMA5_SSC0_LOOPBACK) + priv->loopback = true; +#else + priv->loopback = false; +#endif + + /* Does the receiver or transmitter need to have the MCK divider set up? */ + +#if defined(SSC0_HAVE_MCK2) + priv->samplerate = CONFIG_SAMA5_SSC0_MCKDIV_SAMPLERATE; +#elif defined(SSC_HAVE_MCK2) + priv->samplerate = 0; +#endif + + /* Configure driver state specific to this SSC peripheral */ + + priv->base = SAM_SSC0_VBASE; + priv->datalen = CONFIG_SAMA5_SSC0_DATALEN; +#ifdef CONFIG_DEBUG + priv->align = SAMA5_SSC0_DATAMASK; +#endif + priv->pid = SAM_PID_SSC0; +} +#endif + +#ifdef CONFIG_SAMA5_SSC1 +static void ssc1_configure(struct sam_ssc_s *priv) +{ + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + +#ifdef CONFIG_SAMA5_SSC1_RX + priv->rxenab = true; + + /* Configure the receiver data (RD) and receiver frame synchro (RF) pins */ + + sam_configpio(PIO_SSC1_RD); + sam_configpio(PIO_SSC1_RF); + +#ifdef CONFIG_SAMA5_SSC1_RX_RKINPUT + /* Configure the RK pin only if we are using an external clock to drive + * the receiver clock. + * + * REVISIT: The SSC is also capable of generated the receiver clock + * output on the RK pin. + */ + + sam_configpio(PIO_SSC1_RK); /* External clock received on the RK I/O pad */ + priv->rxclk = SSC_CLKSRC_RKIN; + +#elif defined(CONFIG_SAMA5_SSC1_RX_TXCLK) + priv->rxclk = SSC_CLKSRC_TXOUT; + +#elif defined(CONFIG_SAMA5_SSC1_RX_MCKDIV) + priv->rxclk = SSC_CLKSRC_MCKDIV; + +#else + priv->rxclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember parameters of the configured waveform */ + + priv->rxfslen = CONFIG_SSC1_RX_FSLEN; + priv->rxsttdly = CONFIG_SSC1_RX_STTDLY; + + /* Remember the configured RX clock output */ + +#if defined(CONFIG_SAMA5_SSC1_RX_RKOUTPUT_CONT) + priv->rxout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMA5_SSC1_RX_RKOUTPUT_XFR) + priv->rxout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMA5_SSC1_RX_RKOUTPUT_NONE) */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->rxenab = false; + priv->rxclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMA5_SSC1_RX */ + +#ifdef CONFIG_SAMA5_SSC1_TX + priv->txenab = true; + + /* Configure the transmitter data (TD) and transmitter frame synchro (TF) + * pins + */ + + sam_configpio(PIO_SSC1_TD); + sam_configpio(PIO_SSC1_TF); + +#if defined(CONFIG_SAMA5_SSC1_TX_TKINPUT) + /* Configure the TK pin only if we are using an external clock to drive + * the transmitter clock. + * + * REVISIT: The SSC is also capable of generated the transmitter clock + * output on the TK pin. + */ + + sam_configpio(PIO_SSC1_TK); /* External clock received on the TK I/O pad */ + priv->txclk = SSC_CLKSRC_TKIN; + +#elif defined(CONFIG_SAMA5_SSC1_TX_RXCLK) + priv->txclk = SSC_CLKSRC_RXOUT; + +#elif defined(CONFIG_SAMA5_SSC1_TX_MCKDIV) + priv->txclk = SSC_CLKSRC_MCKDIV; + +#else + priv->txclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember the configured TX clock output */ + +#if defined(CONFIG_SAMA5_SSC1_TX_TKOUTPUT_CONT) + priv->txout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMA5_SSC1_TX_TKOUTPUT_XFR) + priv->txout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMA5_SSC1_TX_TKOUTPUT_NONE) */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->txenab = false; + priv->txclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMA5_SSC1_TX */ + + /* Remember parameters of the configured waveform */ + + priv->txfslen = CONFIG_SSC1_TX_FSLEN; + priv->txsttdly = CONFIG_SSC1_TX_STTDLY; + + /* Set/clear loopback mode */ + +#if defined(CONFIG_SAMA5_SSC1_RX) && defined(CONFIG_SAMA5_SSC1_TX) && \ + defined(CONFIG_SAMA5_SSC1_LOOPBACK) + priv->loopback = true; +#else + priv->loopback = false; +#endif + + /* Does the receiver or transmitter need to have the MCK divider set up? */ + +#if defined(SSC1_HAVE_MCK2) + priv->samplerate = CONFIG_SAMA5_SSC1_MCKDIV_SAMPLERATE; +#elif defined(SSC_HAVE_MCK2) + priv->samplerate = 0; +#endif + + /* Configure driver state specific to this SSC peripheral */ + + priv->base = SAM_SSC1_VBASE; + priv->datalen = CONFIG_SAMA5_SSC1_DATALEN; +#ifdef CONFIG_DEBUG + priv->align = SAMA5_SSC1_DATAMASK; +#endif + priv->pid = SAM_PID_SSC1; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ssc_initialize + * + * Description: + * Initialize the selected SSC port + * + * Input Parameter: + * port - I2S "port" number (identifying the "logical" SSC port) + * + * Returned Value: + * Valid SSC device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct i2s_dev_s *sam_ssc_initialize(int port) +{ + struct sam_ssc_s *priv; + irqstate_t flags; + int ret; + + /* The support SAM parts have only a single SSC port */ + + i2svdbg("port: %d\n", port); + + /* Allocate a new state structure for this chip select. NOTE that there + * is no protection if the same chip select is used in two different + * chip select structures. + */ + + priv = (struct sam_ssc_s *)zalloc(sizeof(struct sam_ssc_s)); + if (!priv) + { + i2sdbg("ERROR: Failed to allocate a chip select structure\n"); + return NULL; + } + + /* Set up the initial state for this chip select structure. Other fields + * were zeroed by zalloc(). + */ + + /* Initialize the common parts for the SSC device structure */ + + sem_init(&priv->exclsem, 0, 1); + priv->dev.ops = &g_sscops; + priv->sscno = port; + + /* Initialize buffering */ + + ssc_buf_initialize(priv); + + flags = enter_critical_section(); +#ifdef CONFIG_SAMA5_SSC0 + if (port == 0) + { + ssc0_configure(priv); + } + else +#endif /* CONFIG_SAMA5_SSC0 */ +#ifdef CONFIG_SAMA5_SSC1 + if (port == 1) + { + ssc1_configure(priv); + } + else +#endif /* CONFIG_SAMA5_SSC1 */ + { + i2sdbg("ERROR: Unsupported I2S port: %d\n", port); + goto errout_with_alloc; + } + + /* Allocate DMA channels */ + + ret = ssc_dma_allocate(priv); + if (ret < 0) + { + goto errout_with_alloc; + } + + /* Configure and enable clocking */ + + ssc_clocking(priv); + + /* Configure the receiver */ + + ret = ssc_rx_configure(priv); + if (ret < 0) + { + i2sdbg("ERROR: Failed to configure the receiver: %d\n", ret); + goto errout_with_clocking; + } + + /* Configure the transmitter */ + + ret = ssc_tx_configure(priv); + if (ret < 0) + { + i2sdbg("ERROR: Failed to configure the transmitter: %d\n", ret); + goto errout_with_clocking; + } + + leave_critical_section(flags); + scc_dump_regs(priv, "After initialization"); + + /* Success exit */ + + return &priv->dev; + + /* Failure exits */ + +errout_with_clocking: + sam_disableperiph1(priv->pid); + ssc_dma_free(priv); + +errout_with_alloc: + sem_destroy(&priv->exclsem); + kmm_free(priv); + return NULL; +} + +#endif /* SSC_HAVE_RX || SSC_HAVE_TX */ +#endif /* CONFIG_SAMA5_SSC0 || CONFIG_SAMA5_SSC1 */ diff --git a/arch/arm/src/sama5/sam_ssc.h b/arch/arm/src/sama5/sam_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..b7ecafe5a454591009f0523c484d68988a21bd2c --- /dev/null +++ b/arch/arm/src/sama5/sam_ssc.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_ssc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_SSC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_SSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/sam_ssc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_ssc_initialize + * + * Description: + * Initialize the selected I2S port. + * + * Input Parameter: + * Port number (for hardware that has mutiple I2S interfaces) + * + * Returned Value: + * Valid I2S device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2s_dev_s *sam_ssc_initialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_SSC_H */ diff --git a/arch/arm/src/sama5/sam_tc.c b/arch/arm/src/sama5/sam_tc.c new file mode 100644 index 0000000000000000000000000000000000000000..54cf71242c3205afb57c264d3779d9cf94fb3cfe --- /dev/null +++ b/arch/arm/src/sama5/sam_tc.c @@ -0,0 +1,1520 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_tc.c + * + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_periphclks.h" +#include "chip/sam_pinmap.h" +#include "chip/sam_pmc.h" +#include "sam_pio.h" +#include "sam_tc.h" + +#if defined(CONFIG_SAMA5_TC0) || defined(CONFIG_SAMA5_TC1) || \ + defined(CONFIG_SAMA5_TC2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes the static configuration of a TC channel */ + +struct sam_chconfig_s +{ + uintptr_t base; /* Channel register base address */ + pio_pinset_t clkset; /* CLK input PIO configuration */ + pio_pinset_t tioaset; /* Output A PIO configuration */ + pio_pinset_t tiobset; /* Output B PIO configuration */ +}; + +/* This structure describes the static configuration of a TC */ + +struct sam_tcconfig_s +{ + uintptr_t base; /* TC register base address */ + uint8_t pid; /* Peripheral ID */ + uint8_t chfirst; /* First channel number */ + uint8_t tc; /* Timer/counter number */ + + /* Channels */ + + struct sam_chconfig_s channel[3]; +}; + +/* This structure describes one timer counter channel */ + +struct sam_tc_s; +struct sam_chan_s +{ + struct sam_tc_s *tc; /* Parent timer/counter */ + uintptr_t base; /* Channel register base address */ + tc_handler_t handler; /* Attached interrupt handler */ + void *arg; /* Interrupt handler argument */ + uint8_t chan; /* Channel number (0, 1, or 2 OR 3, 4, or 5) */ + bool inuse; /* True: channel is in use */ +}; + +/* This structure describes one timer/counter */ + +struct sam_tc_s +{ + sem_t exclsem; /* Assures mutually exclusive access to TC */ + uintptr_t base; /* Register base address */ + uint8_t pid; /* Peripheral ID/irq number */ + uint8_t tc; /* Timer/channel number (0 or 1) */ + bool initialized; /* True: Timer data has been initialized */ + + /* Channels */ + + struct sam_chan_s channel[3]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_TC_REGDEBUG + bool wr; /* True:Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_tc_s *tc); +#define sam_givesem(tc) (sem_post(&tc->exclsem)) + +#ifdef CONFIG_SAMA5_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg); +static bool sam_checkreg(struct sam_tc_s *tc, bool wr, uint32_t regaddr, + uint32_t regval); +#else +# define sam_regdump(chan,msg) +# define sam_checkreg(tc,wr,regaddr,regval) (false) +#endif + +static inline uint32_t sam_tc_getreg(struct sam_chan_s *chan, + unsigned int offset); +static inline void sam_tc_putreg(struct sam_chan_s *chan, + unsigned int offset, uint32_t regval); + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset); +static inline void sam_chan_putreg(struct sam_chan_s *chan, + unsigned int offset, uint32_t regval); + +/* Interrupt Handling *******************************************************/ + +static int sam_tc_interrupt(struct sam_tc_s *tc); +#ifdef CONFIG_SAMA5_TC0 +static int sam_tc012_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_TC1 +static int sam_tc345_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMA5_TC2 +static int sam_tc678_interrupt(int irq, void *context); +#endif + +/* Initialization ***********************************************************/ + +#ifdef SAMA5_HAVE_PMC_PCR_DIV +static int sam_tc_mckdivider(uint32_t mck); +#endif +static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx); +static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx); +static inline struct sam_chan_s *sam_tc_initialize(int channel); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Static timer configuration */ + +#ifdef CONFIG_SAMA5_TC0 +static const struct sam_tcconfig_s g_tc012config = +{ + .base = SAM_TC012_VBASE, + .pid = SAM_PID_TC0, + .chfirst = 0, + .tc = 0, + .channel = + { + [0] = + { + .base = SAM_TC012_CHAN_BASE(0), +#ifdef CONFIG_SAMA5_TC0_CLK0 + .clkset = PIO_TC0_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOA0 + .tioaset = PIO_TC0_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOB0 + .tiobset = PIO_TC0_IOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC012_CHAN_BASE(1), +#ifdef CONFIG_SAMA5_TC0_CLK1 + .clkset = PIO_TC1_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOA1 + .tioaset = PIO_TC1_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOB1 + .tiobset = PIO_TC1_IOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC012_CHAN_BASE(2), +#ifdef CONFIG_SAMA5_TC0_CLK2 + .clkset = PIO_TC2_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOA2 + .tioaset = PIO_TC2_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC0_TIOB2 + .tiobset = PIO_TC2_IOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +#ifdef CONFIG_SAMA5_TC1 +static const struct sam_tcconfig_s g_tc345config = +{ + .base = SAM_TC345_VBASE, + .pid = SAM_PID_TC1, + .chfirst = 3, + .tc = 1, + .channel = + { + [0] = + { + .base = SAM_TC345_CHAN_BASE(3), +#ifdef CONFIG_SAMA5_TC1_CLK3 + .clkset = PIO_TC3_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOA3 + .tioaset = PIO_TC3_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOB3 + .tiobset = PIO_TC3_IOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC345_CHAN_BASE(4), +#ifdef CONFIG_SAMA5_TC1_CLK4 + .clkset = PIO_TC4_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOA4 + .tioaset = PIO_TC4_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOB4 + .tiobset = PIO_TC4_IOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC345_CHAN_BASE(5), +#ifdef CONFIG_SAMA5_TC1_CLK5 + .clkset = PIO_TC5_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOA5 + .tioaset = PIO_TC5_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC1_TIOB5 + .tiobset = PIO_TC5_IOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +#ifdef CONFIG_SAMA5_TC2 +static const struct sam_tcconfig_s g_tc678config = +{ + .base = SAM_TC678_VBASE, + .pid = SAM_PID_TC2, + .chfirst = 6, + .tc = 2, + .channel = + { + [0] = + { + .base = SAM_TC678_CHAN_BASE(6), +#ifdef CONFIG_SAMA5_TC2_CLK6 + .clkset = PIO_TC6_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOA6 + .tioaset = PIO_TC6_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOB6 + .tiobset = PIO_TC6_IOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC678_CHAN_BASE(7), +#ifdef CONFIG_SAMA5_TC2_CLK7 + .clkset = PIO_TC7_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOA7 + .tioaset = PIO_TC7_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOB7 + .tiobset = PIO_TC7_IOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC345_CHAN_BASE(8), +#ifdef CONFIG_SAMA5_TC2_CLK8 + .clkset = PIO_TC8_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOA8 + .tioaset = PIO_TC8_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMA5_TC2_TIOB8 + .tiobset = PIO_TC8_IOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +/* Timer/counter state */ + +#ifdef CONFIG_SAMA5_TC0 +static struct sam_tc_s g_tc012; +#endif + +#ifdef CONFIG_SAMA5_TC1 +static struct sam_tc_s g_tc345; +#endif + +#ifdef CONFIG_SAMA5_TC2 +static struct sam_tc_s g_tc678; +#endif + +/* TC frequency data. This table provides the frequency for each selection of TCCLK */ + +#define TC_NDIVIDERS 4 +#define TC_NDIVOPTIONS 5 + +/* This is the list of divider values: divider = (1 << value) */ + +static const uint8_t g_log2divider[TC_NDIVIDERS] = +{ + 1, /* TIMER_CLOCK1 -> div2 */ + 3, /* TIMER_CLOCK2 -> div8 */ + 5, /* TIMER_CLOCK3 -> div32 */ + 7 /* TIMER_CLOCK4 -> div128 */ +}; + +/* TC register lookup used by sam_tc_setregister */ + +#define TC_NREGISTERS 3 + +static const uint8_t g_regoffset[TC_NREGISTERS] = +{ + SAM_TC_RA_OFFSET, /* Register A */ + SAM_TC_RB_OFFSET, /* Register B */ + SAM_TC_RC_OFFSET /* Register C */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_tc_s *tc) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&tc->exclsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_regdump + * + * Description: + * Dump all timer/counter channel and global registers + * + * Input Parameters: + * chan - The timer/counter channel state + * msg - Message to print with the data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg) +{ + struct sam_tc_s *tc = chan->tc; + uintptr_t base; + + base = tc->base; + lldbg("TC%d [%08x]: %s\n", tc->tc, (int)base, msg); + lldbg(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n", + getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET), + getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET)); + + base = chan->base; + lldbg("TC%d Channel %d [%08x]: %s\n", tc->tc, chan->chan, (int)base, msg); + lldbg(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n", + getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET), + getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET)); + lldbg(" RA: %08x RB: %08x RC: %08x SR: %08x\n", + getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET), + getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_SR_OFFSET)); + lldbg(" IMR: %08x\n", + getreg32(base+SAM_TC_IMR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * tc - The timer/counter peripheral state + * wr - True:write access false:read access + * regval - The regiser value associated with the access + * regaddr - The address of the register being accessed + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TC_REGDEBUG +static bool sam_checkreg(struct sam_tc_s *tc, bool wr, uint32_t regaddr, + uint32_t regval) +{ + if (wr == tc->wr && /* Same kind of access? */ + regaddr == tc->regaddr && /* Same register address? */ + regval == tc->regval) /* Same register value? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + tc->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (tc->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", tc->ntimes); + } + + /* Save information about the new access */ + + tc->wr = wr; + tc->regval = regval; + tc->regaddr = regaddr; + tc->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_tc_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t sam_tc_getreg(struct sam_chan_s *chan, + unsigned int offset) +{ + struct sam_tc_s *tc = chan->tc; + uint32_t regaddr = tc->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_TC_REGDEBUG + if (sam_checkreg(tc, false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_tc_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void sam_tc_putreg(struct sam_chan_s *chan, uint32_t regval, + unsigned int offset) +{ + struct sam_tc_s *tc = chan->tc; + uint32_t regaddr = tc->base + offset; + +#ifdef CONFIG_SAMA5_TC_REGDEBUG + if (sam_checkreg(tc, true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: sam_chan_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset) +{ + uint32_t regaddr = chan->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMA5_TC_REGDEBUG + if (sam_checkreg(chan->tc, false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_chan_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset, + uint32_t regval) +{ + uint32_t regaddr = chan->base + offset; + +#ifdef CONFIG_SAMA5_TC_REGDEBUG + if (sam_checkreg(chan->tc, true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_interrupt + * + * Description: + * Common timer channel interrupt handling. + * + * Input Parameters: + * tc Timer status instance + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +static int sam_tc_interrupt(struct sam_tc_s *tc) +{ + struct sam_chan_s *chan; + uint32_t sr; + uint32_t imr; + uint32_t pending; + int i; + + /* Process interrupts on each channel */ + + for (i = 0; i < 3; i++) + { + /* Get the handy channel reference */ + + chan = &tc->channel[i]; + + /* Get the interrupt status for this channel */ + + sr = sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + imr = sam_chan_getreg(chan, SAM_TC_IMR_OFFSET); + pending = sr & imr; + + /* Are there any pending interrupts for this channel? */ + + if (pending) + { + /* Yes... if we have pending interrupts then interrupts must be + * enabled and we must have a handler attached. + */ + + DEBUGASSERT(chan->handler); + if (chan->handler) + { + /* Execute the callback */ + + chan->handler(chan, chan->arg, sr); + } + else + { + /* Should never happen */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_tcABC_interrupt + * + * Description: + * Timer block interrupt handlers + * + * Input Parameters: + * chan TC channel structure + * sr The status register value that generated the interrupt + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TC0 +static int sam_tc012_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc012); +} +#endif + +#ifdef CONFIG_SAMA5_TC1 +static int sam_tc345_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc345); +} +#endif + +#ifdef CONFIG_SAMA5_TC2 +static int sam_tc678_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc678); +} +#endif + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_mckdivider + * + * Description: + * Return the TC clock input divider value. One of n=0..3 corresponding + * to divider values of {1, 2, 4, 8}. + * + * NOTE: The SAMA5D4 has no clock input divider + * + * Input Parameters: + * mck - The MCK frequency to be divider. + * + * Returned Value: + * Log2 of the TC clock divider. + * + ****************************************************************************/ + +#ifdef SAMA5_HAVE_PMC_PCR_DIV +static int sam_tc_mckdivider(uint32_t mck) +{ + if (mck <= SAM_TC_MAXPERCLK) + { + return 0; + } + else if ((mck >> 1) <= SAM_TC_MAXPERCLK) + { + return 1; + } + else if ((mck >> 2) <= SAM_TC_MAXPERCLK) + { + return 2; + } + else /* if ((mck >> 3) <= SAM_TC_MAXPERCLK) */ + { + DEBUGASSERT((mck >> 3) <= SAM_TC_MAXPERCLK); + return 3; + } +} +#endif + +/**************************************************************************** + * Name: sam_tc_freqdiv_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the value of + * the Ftcin divider. + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The Ftcin input divider value + * + ****************************************************************************/ + +static int sam_tc_freqdiv_lookup(uint32_t ftcin, int ndx) +{ + /* The final option is to use the SLOW clock */ + + if (ndx >= TC_NDIVIDERS) + { + /* Not really a divider. In this case, the board is actually driven + * by the 32.768KHz slow clock. This returns a value that looks like + * correct divider if MCK were the input. + */ + + return ftcin / BOARD_SLOWCLK_FREQUENCY; + } + else + { + return 1 << g_log2divider[ndx]; + } +} + +/**************************************************************************** + * Name: sam_tc_divfreq_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the + * value of the divided frequency + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The divided frequency value + * + ****************************************************************************/ + +static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx) +{ + /* The final option is to use the SLOW clock */ + + if (ndx >= TC_NDIVIDERS) + { + return BOARD_SLOWCLK_FREQUENCY; + } + else + { + return ftcin >> g_log2divider[ndx]; + } +} + +/**************************************************************************** + * Name: sam_tc_initialize + * + * Description: + * There is no global, one-time initialization of timer/counter data + * structures. Rather, this function is called each time that a channel + * is allocated and, if the channel has not been initialized, it will be + * initialized then. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +static inline struct sam_chan_s *sam_tc_initialize(int channel) +{ + struct sam_tc_s *tc; + const struct sam_tcconfig_s *tcconfig; + struct sam_chan_s *chan; + const struct sam_chconfig_s *chconfig; + irqstate_t flags; + xcpt_t handler; + uint32_t regval; + uint8_t ch; + int i; + + /* Select the timer/counter and get the index associated with the + * channel. + */ + +#ifdef CONFIG_SAMA5_TC0 + if (channel >= 0 && channel < 3) + { + tc = &g_tc012; + tcconfig = &g_tc012config; + handler = sam_tc012_interrupt; + } + else +#endif +#ifdef CONFIG_SAMA5_TC1 + if (channel >= 3 && channel < 6) + { + tc = &g_tc345; + tcconfig = &g_tc345config; + handler = sam_tc345_interrupt; + } + else +#endif +#ifdef CONFIG_SAMA5_TC2 + if (channel >= 6 && channel < 9) + { + tc = &g_tc678; + tcconfig = &g_tc678config; + handler = sam_tc678_interrupt; + } + else +#endif + { + /* Timer/counter is not invalid or not enabled */ + + tcdbg("ERROR: Bad channel number: %d\n", channel); + return NULL; + } + + /* Has the timer counter been initialized. We have to be careful here + * because there is no semaphore protection. + */ + + flags = enter_critical_section(); + if (!tc->initialized) + { + /* Initialize the timer counter data structure. */ + + memset(tc, 0, sizeof(struct sam_tc_s)); + sem_init(&tc->exclsem, 0, 1); + tc->base = tcconfig->base; + tc->tc = channel < 3 ? 0 : 1; + tc->pid = tcconfig->pid; + + /* Initialize the channels */ + + for (i = 0, ch = tcconfig->chfirst; i < SAM_TC_NCHANNELS; i++) + { + tcdbg("Initializing TC%d channel %d\n", tcconfig->tc, ch); + + /* Initialize the channel data structure */ + + chan = &tc->channel[i]; + chconfig = &tcconfig->channel[i]; + + chan->tc = tc; + chan->base = chconfig->base; + chan->chan = ch++; + + /* Configure channel input/output pins */ + + if (chconfig->clkset) + { + /* Configure clock input pin */ + + sam_configpio(chconfig->clkset); + } + + if (chconfig->tioaset) + { + /* Configure output A pin */ + + sam_configpio(chconfig->tioaset); + } + + if (chconfig->tiobset) + { + /* Configure output B pin */ + + sam_configpio(chconfig->tiobset); + } + + /* Disable and clear all channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + } + + /* Set the maximum TC peripheral clock frequency */ + + regval = PMC_PCR_PID(tcconfig->pid) | PMC_PCR_CMD | PMC_PCR_EN; + +#ifdef SAMA5_HAVE_PMC_PCR_DIV + /* Set the MCK divider (if any) */ + + regval |= PMC_PCR_DIV(sam_tc_mckdivider(BOARD_MCK_FREQUENCY)); +#endif + + putreg32(regval, SAM_PMC_PCR); + + /* Enable clocking to the timer counter */ + + sam_enableperiph0(tcconfig->pid); + + /* Attach the timer interrupt handler and enable the timer interrupts */ + + (void)irq_attach(tc->pid, handler); + up_enable_irq(tc->pid); + + /* Now the channel is initialized */ + + tc->initialized = true; + } + + /* Get exclusive access to the timer/count data structure */ + + sam_takesem(tc); + leave_critical_section(flags); + + /* Get the requested channel structure */ + + chan = &tc->channel[channel - tcconfig->chfirst]; + + /* Is it available? */ + + if (chan->inuse) + { + /* No.. return a failure */ + + tcdbg("Channel %d is in-used\n", channel); + sam_givesem(tc); + return NULL; + } + + /* Mark the channel "inuse" */ + + chan->inuse = true; + + /* And return the channel with the semaphore locked */ + + sam_regdump(chan, "Initialized"); + return chan; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode) +{ + struct sam_chan_s *chan; + + /* Initialize the timer/counter data (if necessary) and get exclusive + * access to the requested channel. + */ + + tcvdbg("channel=%d mode=%08x\n", channel, mode); + + chan = sam_tc_initialize(channel); + if (chan) + { + /* Disable TC clock */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + + /* Disable channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + + /* Clear and pending status */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* And set the requested mode */ + + sam_chan_putreg(chan, SAM_TC_CMR_OFFSET, mode); + sam_regdump(chan, "Allocated"); + sam_givesem(chan->tc); + } + + /* Return an opaque reference to the channel */ + + tcvdbg("Returning %p\n", chan); + return (TC_HANDLE)chan; +} + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Freeing %p channel=%d inuse=%d\n", chan, chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Make sure that interrupts are detached and disabled and that the channel + * is stopped and disabled. + */ + + sam_tc_attach(handle, NULL, NULL, 0); + sam_tc_stop(handle); + + /* Mark the channel as available */ + + chan->inuse = false; +} + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Starting channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Read the SR to clear any pending interrupts on this channel */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* Then enable the timer (by setting the CLKEN bit). Setting SWTRIG + * will also reset the timer counter and starting the timer. + */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKEN | TC_CCR_SWTRG); + sam_regdump(chan, "Started"); +} + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Stopping channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + sam_regdump(chan, "Stopped"); +} + +/**************************************************************************** + * Name: sam_tc_attach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. + * + * Returned Value: + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + tc_handler_t oldhandler; + irqstate_t flags; + + DEBUGASSERT(chan); + + /* Remember the old interrupt handler and set the new handler */ + + flags = enter_critical_section(); + oldhandler = chan->handler; + chan->handler = handler; + + /* Don't enable interrupt if we are detaching no matter what the caller + * says. + */ + + if (!handler) + { + arg = NULL; + mask = 0; + } + + chan->arg = arg; + + /* Now enable interrupt as requested */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL & ~mask); + sam_chan_putreg(chan, SAM_TC_IER_OFFSET, TC_INT_ALL & mask); + leave_critical_section(flags); + + return oldhandler; +} + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrupt status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_SR_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + DEBUGASSERT(chan && regid < TC_NREGISTERS); + + tcvdbg("Channel %d: Set register RC%d to %08lx\n", + chan->chan, regid, (unsigned long)regval); + + sam_chan_putreg(chan, g_regoffset[regid], regval); + sam_regdump(chan, "Set register"); +} + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, g_regoffset[regid]); +} + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_CV_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_infreq + * + * Description: + * Return the timer input frequency (Ftcin), that is, the MCK frequency + * divided down so that the timer/counter is driven within its maximum + * frequency. + * + * Input Parameters: + * None + * + * Returned Value: + * The timer input frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_infreq(void) +{ +#ifdef SAMA5_HAVE_PMC_PCR_DIV + uint32_t mck = BOARD_MCK_FREQUENCY; + int shift = sam_tc_mckdivider(mck); + return mck >> shift; +#else + return BOARD_MCK_FREQUENCY; +#endif +} + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + uint32_t ftcin = sam_tc_infreq(); + uint32_t regval; + int tcclks; + + DEBUGASSERT(chan); + + /* Get the the TC_CMR register contents for this channel and extract the + * TCCLKS index. + */ + + regval = sam_chan_getreg(chan, SAM_TC_CMR_OFFSET); + tcclks = (regval & TC_CMR_TCCLKS_MASK) >> TC_CMR_TCCLKS_SHIFT; + + /* And use the TCCLKS index to calculate the timer counter frequency */ + + return sam_tc_divfreq_lookup(ftcin, tcclks); +} + +/**************************************************************************** + * Name: sam_tc_divisor + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / dev) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * div Divisor value. + * tcclks TCCLKS field value for divisor. + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks) +{ + uint32_t ftcin = sam_tc_infreq(); + int ndx = 0; + + tcvdbg("frequency=%d\n", frequency); + + /* Satisfy lower bound. That is, the value of the divider such that: + * + * frequency >= (tc_input_frequency * 65536) / divider. + */ + + while (frequency < (sam_tc_divfreq_lookup(ftcin, ndx) >> 16)) + { + if (++ndx > TC_NDIVOPTIONS) + { + /* If no divisor can be found, return -ERANGE */ + + tcdbg("Lower bound search failed\n"); + return -ERANGE; + } + } + + /* Try to maximize DIV while still satisfying upper bound. That the + * value of the divider such that: + * + * frequency < tc_input_frequency / divider. + */ + + for (; ndx < (TC_NDIVOPTIONS-1); ndx++) + { + if (frequency > sam_tc_divfreq_lookup(ftcin, ndx + 1)) + { + break; + } + } + + /* Return the divider value */ + + if (div) + { + uint32_t value = sam_tc_freqdiv_lookup(ftcin, ndx); + tcvdbg("return div=%lu\n", (unsigned long)value); + *div = value; + } + + /* Return the TCCLKS selection */ + + if (tcclks) + { + tcvdbg("return tcclks=%08lx\n", (unsigned long)TC_CMR_TCCLKS(ndx)); + *tcclks = TC_CMR_TCCLKS(ndx); + } + + return OK; +} + +#endif /* CONFIG_SAMA5_TC0 || CONFIG_SAMA5_TC1 || CONFIG_SAMA5_TC2 */ diff --git a/arch/arm/src/sama5/sam_tc.h b/arch/arm/src/sama5/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..311f6d329f2d459a15c7e69c4764bc758bbc3fbf --- /dev/null +++ b/arch/arm/src/sama5/sam_tc.h @@ -0,0 +1,366 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_tc.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_TC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_TC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "chip/sam_tc.h" + +#if defined(CONFIG_SAMA5_TC0) || defined(CONFIG_SAMA5_TC1) || defined(CONFIG_SAMA5_TC2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The timer/counter and channel arguments to sam_tc_allocate() */ + +#define TC_CHAN0 0 /* TC0 */ +#define TC_CHAN1 1 +#define TC_CHAN2 2 +#define TC_CHAN3 3 /* TC1 */ +#define TC_CHAN4 4 +#define TC_CHAN5 5 +#define TC_CHAN6 6 /* TC2 */ +#define TC_CHAN7 7 +#define TC_CHAN8 8 + +/* Register identifier used with sam_tc_setregister */ + +#define TC_REGA 0 +#define TC_REGB 1 +#define TC_REGC 2 + +/* Timer debug is enabled if any timer client is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_ANALOG +# undef CONFIG_SAMA5_TC_REGDEBUG +#endif + +#if !defined(CONFIG_SAMA5_TC_DEBUG) && defined(CONFIG_SAMA5_ADC) && defined(CONFIG_DEBUG_ANALOG) +# define CONFIG_SAMA5_TC_DEBUG 1 +#endif + +/* Timer/counter debug output */ + +#ifdef CONFIG_SAMA5_TC_DEBUG +# define tcdbg dbg +# define tcvdbg vdbg +# define tclldbg lldbg +# define tcllvdbg llvdbg +#else +# define tcdbg(x...) +# define tcvdbg(x...) +# define tclldbg(x...) +# define tcllvdbg(x...) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* An opaque handle used to represent a timer channel */ + +typedef void *TC_HANDLE; + +/* Timer interrupt callback. When a timer interrupt expires, the client will + * receive: + * + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + */ + +typedef void (*tc_handler_t)(TC_HANDLE tch, void *arg, uint32_t sr); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode); + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_attach/sam_tc_detach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. Ignored if handler is NULL. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. Ignored if handler is + * NULL. + * + * Returned Value: + * The address of the previous handler, if any. + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask); + +#define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0) + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrutp status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval); + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid); + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_infreq + * + * Description: + * Return the timer input frequency, that is, the MCK frequency divided + * down so that the timer/counter is driven within its maximum frequency. + * + * Input Parameters: + * None + * + * Returned Value: + * The timer input frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_infreq(void); + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_divisor + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / div) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * div Divisor value. + * tcclks TCCLKS field value for divisor. + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_TC0 || CONFIG_SAMA5_TC1 || CONFIG_SAMA5_TC2 */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TC_H */ + diff --git a/arch/arm/src/sama5/sam_tickless.c b/arch/arm/src/sama5/sam_tickless.c new file mode 100644 index 0000000000000000000000000000000000000000..a785266a5dd1b214911e01ffb41e5a84756ba02b --- /dev/null +++ b/arch/arm/src/sama5/sam_tickless.c @@ -0,0 +1,416 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_tickless.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Tickless OS Support. + * + * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts + * is suppressed and the platform specific code is expected to provide the + * following custom functions. + * + * void up_timer_initialize(void): Initializes the timer facilities. Called + * early in the initialization sequence (by up_intialize()). + * int up_timer_gettime(FAR struct timespec *ts): Returns the current + * time from the platform specific time source. + * int up_timer_cancel(void): Cancels the interval timer. + * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts) + * the interval timer. + * + * The RTOS will provide the following interfaces for use by the platform- + * specific interval timer implementation: + * + * void sched_timer_expiration(void): Called by the platform-specific + * logic when the interval timer expires. + * + ****************************************************************************/ +/**************************************************************************** + * SAMA5 Timer Usage + * + * This current implementation uses two timers: A one-shot timer to provide + * the timed events and a free running timer to provide the current time. + * Since timers are a limited resource, that could be an issue on some + * systems. + * + * We could do the job with a single timer if we were to keep the single + * timer in a free-running at all times. The SAMA5 timer/counters have + * 32-bit counters with the capability to generate a compare interrupt when + * the timer matches a compare value but also to continue counting without + * stopping (giving another, different interrupt when the timer rolls over + * from 0xffffffff to zero). So we could potentially just set the compare + * at the number of ticks you want PLUS the current value of timer. Then + * you could have both with a single timer: An interval timer and a free- + * running counter with the same timer! + * + * Patches are welcome! + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "sam_oneshot.h" +#include "sam_freerun.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SAMA5_HAVE_TC +# error Timer/counters must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMA5_ONESHOT +# error CONFIG_SAMA5_ONESHOT must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMA5_FREERUN +# error CONFIG_SAMA5_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMA5_TICKLESS_FREERUN +# error CONFIG_SAMA5_TICKLESS_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMA5_TICKLESS_ONESHOT +# error CONFIG_SAMA5_TICKLESS_ONESHOT must be selected for the Tickless OS option +#endif + +#if CONFIG_SAMA5_TICKLESS_ONESHOT == 0 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 0 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 1 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 1 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 2 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 2 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 3 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 3 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 4 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 4 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 5 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 5 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 6 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 6 && CONFIG_SAMA5_TC2 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 7 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 7 && CONFIG_SAMA5_TC2 not selected +#elif CONFIG_SAMA5_TICKLESS_ONESHOT == 8 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_ONESHOT == 8 && CONFIG_SAMA5_TC2 not selected +#endif + +#if CONFIG_SAMA5_TICKLESS_ONESHOT < 0 || CONFIG_SAMA5_TICKLESS_ONESHOT > 8 +# error CONFIG_SAMA5_TICKLESS_ONESHOT is not valid +#endif + +#if CONFIG_SAMA5_TICKLESS_FREERUN == 0 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 0 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 1 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 1 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 2 && !defined(CONFIG_SAMA5_TC0) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 2 && CONFIG_SAMA5_TC0 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 3 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 3 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 4 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 4 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 5 && !defined(CONFIG_SAMA5_TC1) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 5 && CONFIG_SAMA5_TC1 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 6 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 6 && CONFIG_SAMA5_TC2 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 7 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 7 && CONFIG_SAMA5_TC2 not selected +#elif CONFIG_SAMA5_TICKLESS_FREERUN == 8 && !defined(CONFIG_SAMA5_TC2) +# error CONFIG_SAMA5_TICKLESS_FREERUN == 8 && CONFIG_SAMA5_TC2 not selected +#endif + +#if CONFIG_SAMA5_TICKLESS_FREERUN < 0 || CONFIG_SAMA5_TICKLESS_FREERUN > 8 +# error CONFIG_SAMA5_TICKLESS_FREERUN is not valid +#endif + +#if CONFIG_SAMA5_TICKLESS_FREERUN == CONFIG_SAMA5_TICKLESS_ONESHOT +# error CONFIG_SAMA5_TICKLESS_FREERUN is the same as CONFIG_SAMA5_TICKLESS_ONESHOT +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sam_tickless_s +{ + struct sam_oneshot_s oneshot; + struct sam_freerun_s freerun; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct sam_tickless_s g_tickless; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Called when the one shot timer expires + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +static void sam_oneshot_handler(void *arg) +{ + tcllvdbg("Expired...\n"); + sched_timer_expiration(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Initializes all platform-specific timer facilities. This function is + * called early in the initialization sequence by up_intialize(). + * On return, the current up-time should be available from + * up_timer_gettime() and the interval timer is ready for use (but not + * actively timing. + * + * Provided by platform-specific code and called from the architecture- + * specific logic. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + uint64_t max_delay; +#endif + int ret; + + /* Initialize the one-shot timer */ + + ret = sam_oneshot_initialize(&g_tickless.oneshot, + CONFIG_SAMA5_TICKLESS_ONESHOT, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_oneshot_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(ONESHOT_INITIALIZED(&g_tickless.oneshot)); + +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + /* Get the maximum delay of the one-shot timer in microseconds */ + + ret = sam_oneshot_max_delay(&g_tickless.oneshot, &max_delay); + if (ret < 0) + { + tclldbg("ERROR: sam_oneshot_max_delay failed\n"); + PANIC(); + } + + /* Convert this to configured clock ticks for use by the OS timer logic */ + + max_delay /= CONFIG_USEC_PER_TICK; + if (max_delay > (uint64_t)UINT32_MAX) + { + g_oneshot_maxticks = UINT32_MAX; + } + else + { + g_oneshot_maxticks = (uint32_t)max_delay; + } +#endif + + /* Initialize the free-running timer */ + + ret = sam_freerun_initialize(&g_tickless.freerun, + CONFIG_SAMA5_TICKLESS_FREERUN, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_freerun_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(FREERUN_INITIALIZED(&g_tickless.freerun)); +} + +/**************************************************************************** + * Name: up_timer_gettime + * + * Description: + * Return the elapsed time since power-up (or, more correctly, since + * up_timer_initialize() was called). This function is functionally + * equivalent to: + * + * int clock_gettime(clockid_t clockid, FAR struct timespec *ts); + * + * when clockid is CLOCK_MONOTONIC. + * + * This function provides the basis for reporting the current time and + * also is used to eliminate error build-up from small errors in interval + * time calculations. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the location in which to return the up-time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * Called from the the normal tasking context. The implementation must + * provide whatever mutual exclusion is necessary for correct operation. + * This can include disabling interrupts in order to assure atomic register + * operations. + * + ****************************************************************************/ + +int up_timer_gettime(FAR struct timespec *ts) +{ + return FREERUN_INITIALIZED(&g_tickless.freerun) ? + sam_freerun_counter(&g_tickless.freerun, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_cancel + * + * Description: + * Cancel the interval timer and return the time remaining on the timer. + * These two steps need to be as nearly atomic as possible. + * sched_timer_expiration() will not be called unless the timer is + * restarted with up_timer_start(). + * + * If, as a race condition, the timer has already expired when this + * function is called, then that pending interrupt must be cleared so + * that up_timer_start() and the remaining time of zero should be + * returned. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Location to return the remaining time. Zero should be returned + * if the timer is not active. ts may be zero in which case the + * time remaining is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_cancel(FAR struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_cancel(&g_tickless.oneshot, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_start + * + * Description: + * Start the interval timer. sched_timer_expiration() will be + * called at the completion of the timeout (unless up_timer_cancel + * is called to stop the timing. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the time interval until sched_timer_expiration() is + * called. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_start(FAR const struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_start(&g_tickless.oneshot, sam_oneshot_handler, NULL, ts) : + -EAGAIN; +} +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/sama5/sam_timerisr.c b/arch/arm/src/sama5/sam_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..3861b1217a3c71999d567b466c7418e1673fa12f --- /dev/null +++ b/arch/arm/src/sama5/sam_timerisr.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_timerisr.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "up_arch.h" +#include "sam_periphclks.h" +#include "chip/sam_pit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The PIT counter runs at a rate of the main clock (MCK) divided by 16. + * + * On the SAMA5D4, the clocking to the PIC may be divided down from MCK. + * Perhaps because of H32MXDIV? We will let the board.h tell us the correct + * PIT include clock by defining BOARD_PIT_FREQUENCY. + */ + +#define PIT_CLOCK (BOARD_PIT_FREQUENCY >> 4) + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The PIT counts from zero and up until it reaches the overflow value set + * in the field PIV of the Mode Register (PIT MR). So an PIV value of n + * corresponds a duration of n * PIT_CLOCK + */ + +#define PIT_PIV ((PIT_CLOCK + (CLK_TCK >> 1)) / CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* "When CPIV and PICNT values are obtained by reading the Periodic + * Interval Value Register (PIT_PIVR), the overflow counter (PICNT) is + * reset and the PITS is cleared, thus acknowledging the interrupt. The + * value of PICNT gives the number of periodic intervals elapsed since the + * last read of PIT_PIVR." + */ + + uint32_t picnt = getreg32(SAM_PIT_PIVR) >> PIT_PICNT_SHIFT; + + /* Process timer interrupt (multiple times if we missed an interrupt) */ + + while (picnt-- > 0) + { + sched_process_timer(); + } + + return OK; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Enable the PIT peripheral */ + + sam_pit_enableclk(); + + /* Make sure that interrupts from the PIT are disabled */ + + up_disable_irq(SAM_IRQ_PIT); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(SAM_IRQ_PIT, (xcpt_t)up_timerisr); + + /* Set the PIT overflow value (PIV), enable the PIT, and enable + * interrupts from the PIT. + */ + + regval = PIT_PIV; + DEBUGASSERT(regval <= PIT_MR_PIV_MASK); + + regval |= (PIT_MR_PITEN | PIT_MR_PITIEN); + putreg32(regval, SAM_PIT_MR); + + /* And enable the timer interrupt */ + + up_enable_irq(SAM_IRQ_PIT); +} diff --git a/arch/arm/src/sama5/sam_trng.c b/arch/arm/src/sama5/sam_trng.c new file mode 100644 index 0000000000000000000000000000000000000000..1be5585bc4ba8f2eb22a1c90a58c59edb5e61f0e --- /dev/null +++ b/arch/arm/src/sama5/sam_trng.c @@ -0,0 +1,389 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_trng.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives, in part, from Max Holtzberg's STM32 RNG Nuttx driver: + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_periphclks.h" +#include "sam_trng.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Interrupts */ + +static int sam_interrupt(int irq, void *context); + +/* Character driver methods */ + +static ssize_t sam_read(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct trng_dev_s +{ + sem_t exclsem; /* Enforces exclusive access to the TRNG */ + sem_t waitsem; /* Wait for buffer full */ + uint32_t *samples; /* Current buffer being filled */ + size_t maxsamples; /* Size of the current buffer (in 32-bit words) */ + volatile size_t nsamples; /* Number of samples currently buffered */ + volatile bool first; /* The first random number must be handled differently */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct trng_dev_s g_trngdev; + +static const struct file_operations g_trngops = +{ + 0, /* open */ + 0, /* close */ + sam_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * The TRNG interrupt handler + * + * Input Parameters: + * + * Returned Value: + * + * + ****************************************************************************/ + +static int sam_interrupt(int irq, void *context) +{ + uint32_t odata; + + /* Loop where there are samples available to be read and/or until the user + * buffer is filled. Each sample requires only 84 clocks it is likely + * that we will loop here. + */ + + for (; ; ) + { + /* Read the random sample (before checking DATRDY -- but probably not + * necessary) + */ + + odata = getreg32(SAM_TRNG_ODATA); + + /* Verify that sample data is available (DATARDY is cleared when the + * interrupt status regiser is read) + */ + + if ((getreg32(SAM_TRNG_ISR) & TRNG_INT_DATRDY) == 0) + { + /* No? Then return and continue processing on the next interrupt. */ + + return OK; + } + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting + * the RNGEN bit should not be used, but saved for comparison with the + * next generated random number. Each subsequent generated random number + * has to be compared with the previously generated number. The test + * fails if any two compared numbers are equal (continuous random number + * generator test). + */ + + if (g_trngdev.nsamples == 0) + { + /* This is the first sample we have taken. Save it for subsequent + * comparison. + */ + + g_trngdev.samples[0] = odata; + g_trngdev.nsamples = 1; + continue; + } + + /* This is not the first sample. Check if the new sample differs from + * the preceding sample. + */ + + else if (odata == g_trngdev.samples[g_trngdev.nsamples - 1]) + { + /* Two samples with the same value. Discard this one and try again. */ + + continue; + } + + /* This sample differs from the previous value. Have we discarded the + * first sample yet? + */ + + if (g_trngdev.first) + { + /* No, discard it now by replacing it with the new sample */ + + g_trngdev.samples[0] = odata; + g_trngdev.nsamples = 1; + g_trngdev.first = false; + } + + /* Yes.. the first sample has been dicarded */ + + else + { + /* Add the new random number to the buffer */ + + g_trngdev.samples[g_trngdev.nsamples] = odata; + g_trngdev.nsamples++; + } + + /* Have all of the requested samples been saved? */ + + if (g_trngdev.nsamples == g_trngdev.maxsamples) + { + /* Yes.. disable any further interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* And wakeup the waiting read thread. */ + + sem_post(&g_trngdev.waitsem); + return OK; + } + } +} + +/**************************************************************************** + * Name: sam_read + * + * Description: + * This is the standard, NuttX character driver read method + * + * Input Parameters: + * filep - The VFS file instance + * buffer - Buffer in which to return the random samples + * buflen - The length of the buffer + * + * Returned Value: + * + ****************************************************************************/ + +static ssize_t sam_read(struct file *filep, char *buffer, size_t buflen) +{ + ssize_t retval; + int ret; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Get exclusive access to the TRNG harware */ + + if (sem_wait(&g_trngdev.exclsem) != OK) + { + /* This is probably -EINTR meaning that we were awakened by a signal */ + + return -errno; + } + + /* Save the buffer information. */ + + DEBUGASSERT(((uintptr_t)buffer & 3) == 0); + + g_trngdev.samples = (uint32_t *)buffer; + g_trngdev.maxsamples = buflen >> 2; + g_trngdev.nsamples = 0; + g_trngdev.first = true; + + /* Enable the TRNG */ + + putreg32(TRNG_CR_ENABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Clear any pending TRNG interrupts by reading the interrupt status + * register + */ + + (void)getreg32(SAM_TRNG_ISR); + + /* Enable TRNG interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IER); + + /* Wait until the buffer is filled */ + + while (g_trngdev.nsamples < g_trngdev.maxsamples) + { + ret = sem_wait(&g_trngdev.waitsem); + + fvdbg("Awakened: nsamples=%d maxsamples=%d ret=%d\n", + g_trngdev.nsamples, g_trngdev.maxsamples, ret); + + if (ret < 0) + { + /* We must have been awakened by a signal */ + + if (g_trngdev.nsamples > 0) + { + break; + } + else + { + retval = -errno; + goto errout; + } + } + } + + /* Success... calculate the number of bytes to return */ + + retval = g_trngdev.nsamples << 2; + +errout: + + /* Disable TRNG interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Release our lock on the TRNG hardware */ + + sem_post(&g_trngdev.exclsem); + + fvdbg("Return %d\n", (int)retval); + return retval; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_rnginitialize + * + * Description: + * Initialize the TRNG hardware and register the /dev/randome driver. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_rnginitialize(void) +{ + int ret; + + fvdbg("Initializing TRNG hardware\n"); + + /* Initialize the device structure */ + + memset(&g_trngdev, 0, sizeof(struct trng_dev_s)); + sem_init(&g_trngdev.exclsem, 0, 1); + sem_init(&g_trngdev.waitsem, 0, 0); + + /* Enable clocking to the TRNG */ + + sam_trng_enableclk(); + + /* Initialize the TRNG interrupt */ + + if (irq_attach(SAM_IRQ_TRNG, sam_interrupt)) + { + fdbg("ERROR: Failed to attach to IRQ%d\n", SAM_IRQ_TRNG); + return; + } + + /* Disable the interrupts at the TRNG */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Register the character driver */ + + ret = register_driver("/dev/random", &g_trngops, 0644, NULL); + if (ret < 0) + { + fdbg("ERROR: Failed to register /dev/random\n"); + return; + } + + /* Enable the TRNG interrupt at the AIC */ + + up_enable_irq(SAM_IRQ_TRNG); +} diff --git a/arch/arm/src/sama5/sam_trng.h b/arch/arm/src/sama5/sam_trng.h new file mode 100644 index 0000000000000000000000000000000000000000..d27186ac3cc94572ac7f7a599adbf527a0af27dd --- /dev/null +++ b/arch/arm/src/sama5/sam_trng.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_trng.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_TRNG_H +#define __ARCH_ARM_SRC_SAMA5_SAM_TRNG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_trng.h" + +#if defined(CONFIG_DEV_RANDOM) && defined(CONFIG_SAMA5_TRNG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_DEV_RANDOM && CONFIG_SAMA5_TRNG */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TRNG_H */ diff --git a/arch/arm/src/sama5/sam_tsd.c b/arch/arm/src/sama5/sam_tsd.c new file mode 100644 index 0000000000000000000000000000000000000000..3bed567508bc02d54d2d4394da586eb8c1988697 --- /dev/null +++ b/arch/arm/src/sama5/sam_tsd.c @@ -0,0 +1,1732 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_tsd.c + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip/sam_adc.h" +#include "sam_adc.h" +#include "sam_tsd.h" + +#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TSD) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Driver support ***********************************************************/ +/* This format is used to construct the /dev/input[n] device driver path. It + * defined here so that it will be used consistently in all places. + */ + +#define DEV_FORMAT "/dev/input%d" +#define DEV_NAMELEN 16 + +/* Poll the pen position while the pen is down at this rate (50MS): */ + +#define TSD_WDOG_DELAY MSEC2TICK(50) + +/* This is a value for the threshold that guantees a big difference on the + * first pendown (but can't overflow). + */ + +#define INVALID_THRESHOLD 0x1000 + +/* Data read bit definitions */ + +#ifdef CONFIG_SAMA5_TSD_4WIRE +# define TSD_ALLREADY (ADC_INT_XRDY | ADC_INT_YRDY | ADC_INT_PRDY) +#else +# define TSD_ALLREADY (ADC_INT_XRDY | ADC_INT_YRDY) +#endif + +/* Pen sample state bit sets */ + +#ifdef CONFIG_SAMA5_TSD_4WIRE +# define TSD_PENUP_VALID (TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID | \ + TOUCH_PRESSURE_VALID) +# define TSD_PENUP_INVALID (TOUCH_UP | TOUCH_ID_VALID) +# define TSD_PENDOWN (TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID | \ + TOUCH_PRESSURE_VALID) +# define TSD_PENMOVE (TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID | \ + TOUCH_PRESSURE_VALID) +#else +# define TSD_PENUP_VALID (TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID) +# define TSD_PENUP_INVALID (TOUCH_UP | TOUCH_ID_VALID) +# define TSD_PENDOWN (TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID) +# define TSD_PENMOVE (TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID) +#endif + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This describes the state of one contact */ + +enum sam_contact_e +{ + CONTACT_NONE = 0, /* No contact */ + CONTACT_DOWN, /* First contact */ + CONTACT_MOVE, /* Same contact, possibly different position */ + CONTACT_UP, /* Contact lost */ +}; + +/* This structure describes the results of one touchscreen sample */ + +struct sam_sample_s +{ + uint8_t id; /* Sampled touch point ID */ + uint8_t contact; /* Contact state (see enum sam_contact_e) */ + bool valid; /* True: x,y,p contain valid, sampled data */ + uint16_t x; /* Measured X position */ + uint16_t y; /* Measured Y position */ +#ifdef CONFIG_SAMA5_TSD_4WIRE + uint16_t p; /* Measured pressure */ +#endif +}; + +/* This structure describes the state of one touchscreen driver instance */ + +struct sam_tsd_s +{ + uint8_t nwaiters; /* Number of threads waiting for touchscreen data */ + uint8_t id; /* Current touch point ID */ + uint8_t valid; /* Data ready bit set */ + uint8_t crefs; /* The number of times the device has been opened */ + volatile bool penchange; /* An unreported event is buffered */ + uint32_t threshx; /* Thresholding X value */ + uint32_t threshy; /* Thresholding Y value */ + sem_t waitsem; /* Used to wait for the availability of data */ + + struct sam_adc_s *adc; /* ADC device handle */ + struct work_s work; /* Supports the interrupt handling "bottom half" */ + struct sam_sample_s sample; /* Last sampled touch point data */ + WDOG_ID wdog; /* Poll the position while the pen is down */ + + /* The following is a list if poll structures of threads waiting for + * driver events. The 'struct pollfd' reference for each open is also + * retained in the f_priv field of the 'struct file'. + */ + +#ifndef CONFIG_DISABLE_POLL + struct pollfd *fds[CONFIG_SAMA5_TSD_NPOLLWAITERS]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Interrupt bottom half logic and data sampling */ + +static void sam_tsd_notify(struct sam_tsd_s *priv); +static int sam_tsd_sample(struct sam_tsd_s *priv, struct sam_sample_s *sample); +static int sam_tsd_waitsample(struct sam_tsd_s *priv, + struct sam_sample_s *sample); +static void sam_tsd_bottomhalf(void *arg); +static int sam_tsd_schedule(struct sam_tsd_s *priv); +static void sam_tsd_expiry(int argc, uint32_t arg1, ...); + +/* Character driver methods */ + +static int sam_tsd_open(struct file *filep); +static int sam_tsd_close(struct file *filep); +static ssize_t sam_tsd_read(struct file *filep, char *buffer, size_t len); +static int sam_tsd_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifndef CONFIG_DISABLE_POLL +static int sam_tsd_poll(struct file *filep, struct pollfd *fds, bool setup); +#endif + +/* Initialization and configuration */ + +static void sam_tsd_startuptime(struct sam_tsd_s *priv, uint32_t time); +static void sam_tsd_tracking(struct sam_tsd_s *priv, uint32_t time); +static void sam_tsd_trigperiod(struct sam_tsd_s *priv, uint32_t period); +static void sam_tsd_debounce(struct sam_tsd_s *priv, uint32_t time); +static void sam_tsd_initialize(struct sam_tsd_s *priv); +static void sam_tsd_uninitialize(struct sam_tsd_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This the vtable that supports the character driver interface */ + +static const struct file_operations g_tsdops = +{ + sam_tsd_open, /* open */ + sam_tsd_close, /* close */ + sam_tsd_read, /* read */ + 0, /* write */ + 0, /* seek */ + sam_tsd_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , sam_tsd_poll /* poll */ +#endif +}; + +/* The driver state structure is pre-allocated. */ + +static struct sam_tsd_s g_tsd; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tsd_notify + ****************************************************************************/ + +static void sam_tsd_notify(struct sam_tsd_s *priv) +{ +#ifndef CONFIG_DISABLE_POLL + int i; +#endif + + /* If there are threads waiting for read data, then signal one of them + * that the read data is available. + */ + + if (priv->nwaiters > 0) + { + /* After posting this semaphore, we need to exit because the touchscreen + * is no longer available. + */ + + sem_post(&priv->waitsem); + } + + /* If there are threads waiting on poll() for touchscreen data to become available, + * then wake them up now. NOTE: we wake up all waiting threads because we + * do not know that they are going to do. If they all try to read the data, + * then some make end up blocking after all. + */ + +#ifndef CONFIG_DISABLE_POLL + for (i = 0; i < CONFIG_SAMA5_TSD_NPOLLWAITERS; i++) + { + struct pollfd *fds = priv->fds[i]; + if (fds) + { + fds->revents |= POLLIN; + ivdbg("Report events: %02x\n", fds->revents); + sem_post(fds->sem); + } + } +#endif +} + +/**************************************************************************** + * Name: sam_tsd_sample + ****************************************************************************/ + +static int sam_tsd_sample(struct sam_tsd_s *priv, struct sam_sample_s *sample) +{ + irqstate_t flags; + int ret = -EAGAIN; + + /* Interrupts me be disabled when this is called to (1) prevent posting + * of semaphores from interrupt handlers, and (2) to prevent sampled data + * from changing until it has been reported. + */ + + flags = enter_critical_section(); + + /* Is there new touchscreen sample data available? */ + + if (priv->penchange) + { + /* Yes.. the state has changed in some way. Return a copy of the + * sampled data. + */ + + memcpy(sample, &priv->sample, sizeof(struct sam_sample_s)); + + /* Now manage state transitions */ + + if (sample->contact == CONTACT_UP) + { + /* Next.. no contact. Increment the ID so that next contact ID + * will be unique. X/Y positions are no longer valid. + */ + + priv->sample.contact = CONTACT_NONE; + priv->sample.valid = false; + priv->id++; + } + else if (sample->contact == CONTACT_DOWN) + { + /* First report -- next report will be a movement */ + + priv->sample.contact = CONTACT_MOVE; + } + + priv->penchange = false; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_tsd_waitsample + ****************************************************************************/ + +static int sam_tsd_waitsample(struct sam_tsd_s *priv, struct sam_sample_s *sample) +{ + irqstate_t flags; + int ret; + + /* Interrupts me be disabled when this is called to (1) prevent posting + * of semaphores from interrupt handlers, and (2) to prevent sampled data + * from changing until it has been reported. + * + * In addition, we will also disable pre-emption to prevent other threads + * from getting control while we muck with the semaphores. + */ + + sched_lock(); + flags = enter_critical_section(); + + /* Now release the semaphore that manages mutually exclusive access to + * the device structure. This may cause other tasks to become ready to + * run, but they cannot run yet because pre-emption is disabled. + */ + + sam_adc_unlock(priv->adc); + + /* Try to get the a sample... if we cannot, then wait on the semaphore + * that is posted when new sample data is available. + */ + + while (sam_tsd_sample(priv, sample) < 0) + { + /* Wait for a sample data */ + + ivdbg("Waiting..\n"); + priv->nwaiters++; + ret = sem_wait(&priv->waitsem); + priv->nwaiters--; + + if (ret < 0) + { + /* If we are awakened by a signal, then we need to return + * the failure now. + */ + + idbg("ERROR: sem_wait: %d\n", errno); + DEBUGASSERT(errno == EINTR); + ret = -EINTR; + goto errout; + } + } + + ivdbg("Sampled\n"); + + /* Re-acquire the semaphore that manages mutually exclusive access to + * the device structure. We may have to wait here. But we have our sample. + * Interrupts and pre-emption will be re-enabled while we wait. + */ + + sam_adc_lock(priv->adc); + +errout: + /* Then re-enable interrupts. We might get interrupt here and there + * could be a new sample. But no new threads will run because we still + * have pre-emption disabled. + */ + + leave_critical_section(flags); + + /* Restore pre-emption. We might get suspended here but that is okay + * because we already have our sample. Note: this means that if there + * were two threads reading from the touchscreen ADC for some reason, the + * data might be read out of order. + */ + + sched_unlock(); + return ret; +} + +/**************************************************************************** + * Name: sam_tsd_setaverage + * + * Description: + * The ADC hardware can filter the touchscreen samples by averaging. The + * function selects (or de-selects) that filtering. + * + * Input Parameters + * priv - The touchscreen private data structure + * tsav - The new (shifted) value of the TSAV field of the ADC TSMR regsiter. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_setaverage(struct sam_tsd_s *priv, uint32_t tsav) +{ + uint32_t regval; + uint32_t minfreq; + uint32_t tsfreq; + + /* Get the current value of the TSMR register */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TSMR); + + /* Get the unshifted TSAVE value and compare it to the touchscreen + * frequency + * + * minfreq = 0: No filtering + * minfreq = 1: Averages 2 ADC conversions + * minfreq = 2: Averages 4 ADC conversions + * minfreq = 3: Averages 8 ADC conversions + */ + + minfreq = (tsav >> ADC_TSMR_TSAV_SHIFT); + if (minfreq) + { + /* TSFREQ: Defines the Touchscreen Frequency compared to the Trigger + * Frequency. --> TSFREQ must be greater or equal to TSAV. <-- + */ + + tsfreq = (regval & ADC_TSMR_TSFREQ_MASK) >> ADC_TSMR_TSFREQ_SHIFT; + if (minfreq > tsfreq) + { + /* Set TSFREQ = TSAV */ + + regval &= ~ADC_TSMR_TSFREQ_MASK; + regval |= ADC_TSMR_TSFREQ(minfreq); + } + } + + /* Save the new filter value */ + + regval &= ~ADC_TSMR_TSAV_MASK; + regval |= tsav; + sam_adc_putreg(priv->adc, SAM_ADC_TSMR, regval); +} + +/**************************************************************************** + * Name: sam_tsd_bottomhalf + * + * Description: + * This function executes on the worker thread. It is scheduled by + * sam_tsd_interrupt whenever any interesting, enabled TSD event occurs. + * All TSD interrupts are disabled when this function runs. sam_tsd_bottomhalf + * will re-enable TSD interrupts when it completes processing all pending + * TSD events. + * + * Input Parameters + * arg - The touchscreen private data structure cast to (void *) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_bottomhalf(void *arg) +{ + struct sam_tsd_s *priv = (struct sam_tsd_s *)arg; + uint32_t pending; + uint32_t ier; + uint32_t regval; + uint32_t xraw; + uint32_t xscale; + uint32_t x; + uint32_t xdiff; + uint32_t yraw; + uint32_t yscale; + uint32_t y; + uint32_t ydiff; + uint32_t z1; + uint32_t z2; + uint32_t pressr; + uint32_t p; + bool pendown; + + ASSERT(priv != NULL); + + /* Get the set of pending ADC interrupts and pen status */ + + pending = sam_adc_getreg(priv->adc, SAM_ADC_ISR); + + /* Get exclusive access to the driver data structure */ + + sam_adc_lock(priv->adc); + + /* Check the pen state */ + + pendown = ((pending & ADC_SR_PENS) != 0); + + /* Handle the change from pen down to pen up */ + + ivdbg("pending: %08x pendown: %d contact: %d\n", + pending, pendown, priv->sample.contact); + + if (!pendown) + { + /* The pen is up.. reset thresholding variables. */ + + priv->threshx = INVALID_THRESHOLD; + priv->threshy = INVALID_THRESHOLD; + + /* We will enable only the ADC_INT_PEN interrupt on exit. We don't + * want to hear anything from the touchscreen until the next touch. + */ + + ier = ADC_INT_PEN; + + /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up + * and already reported; CONTACT_UP == pen up, but not reported) + */ + + if (priv->sample.contact == CONTACT_NONE || + priv->sample.contact == CONTACT_UP) + + { + goto ignored; + } + + /* The pen is up. NOTE: We know from a previous test, that this is a + * loss of contact condition. This will be changed to CONTACT_NONE + * after the loss of contact is sampled. + */ + + priv->sample.contact = CONTACT_UP; + + /* Stop periodic trigger & enable pen */ + + sam_tsd_setaverage(priv, ADC_TSMR_TSAV_NOFILTER); + sam_tsd_debounce(priv, BOARD_TSD_DEBOUNCE); + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_PEN; + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); + } + + /* It is a pen down event. If the last loss-of-contact event has not been + * processed yet, then we have to ignore the pen down event (or else it will + * look like a drag event) + */ + + else if (priv->sample.contact == CONTACT_UP) + { + /* If we have not yet processed the last pen up event, then we + * cannot handle this pen down event. We will have to discard it. That + * should be okay because we will set the timer to to sample again + * a little later. NOTE that pen interrupts are not re-enabled in + * this case; we rely on the timer expiry to get us going again. + */ + + wd_start(priv->wdog, TSD_WDOG_DELAY, sam_tsd_expiry, 1, (uint32_t)priv); + ier = 0; + goto ignored; + } + else + { + /* The pen is down and the driver has accepted the last sample values. */ + + /* While the pen is down we want interrupts on all data ready and pen + * release events. + */ + + ier = ADC_TSD_RELEASEINTS; + + /* Check if all of the date that we need is available. If not, just + * re-enable interrupts and wait until it is. + */ + + if ((pending & TSD_ALLREADY) != TSD_ALLREADY) + { + /* But don't enable interrupts for the data that we already have */ + + ier &= ~(pending & TSD_ALLREADY); + goto ignored; + } + + /* Sample positional values. Get raw X and Y position data */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_XPOSR); + xraw = (regval & ADC_XPOSR_XPOS_MASK) >> ADC_XPOSR_XPOS_SHIFT; + xscale = (regval & ADC_XPOSR_XSCALE_MASK) >> ADC_XPOSR_XSCALE_SHIFT; + + regval = sam_adc_getreg(priv->adc, SAM_ADC_YPOSR); + yraw = (regval & ADC_YPOSR_YPOS_MASK) >> ADC_YPOSR_YPOS_SHIFT; + yscale = (regval & ADC_YPOSR_YSCALE_MASK) >> ADC_YPOSR_YSCALE_SHIFT; + +#ifdef CONFIG_SAMA5_TSD_4WIRE + /* Read the PRESSR register now, but don't do anything until we + * decide if we are going to use this measurement. + */ + + pressr = sam_adc_getreg(priv->adc, SAM_ADC_PRESSR); +#endif + /* Discard any bad readings. This check may not be necessary. */ + + if (xraw == 0 || xraw >= xscale || yraw == 0 || yraw > yscale) + { + idbg("Discarding: x %d:%d y %d:%d\n", xraw, xscale); + goto ignored; + } + + /* Scale the X/Y measurements. The scale value is the maximum + * value that the sample can attain. It should be close to 4095. + * Scaling: + * + * scaled = raw * 4095 / scale + * = ((raw << 12) - raw) / scale + */ + +#ifdef CONFIG_SAMA5_TSD_SWAPXY + x = ((yraw << 12) - yraw) / yscale; + y = ((xraw << 12) - xraw) / xscale; +#else + x = ((xraw << 12) - xraw) / xscale; + y = ((yraw << 12) - yraw) / yscale; +#endif + + /* Perform a thresholding operation so that the results will be + * more stable. If the difference from the last sample is small, + * then ignore the event. REVISIT: Should a large change in + * pressure also generate a event? + */ + + xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x); + ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y); + + /* Continue to sample the position while the pen is down */ + + wd_start(priv->wdog, TSD_WDOG_DELAY, sam_tsd_expiry, 1, (uint32_t)priv); + + /* Check the thresholds. Bail if (1) this is not the first + * measurement and (2) there is no significant difference from + * the last measurement. + */ + + if (priv->sample.contact == CONTACT_MOVE && + xdiff < CONFIG_SAMA5_TSD_THRESHX && + ydiff < CONFIG_SAMA5_TSD_THRESHY) + { + /* Little or no change in either direction ... don't report + * anything. + */ + + goto ignored; + } + + /* When we see a big difference, snap to the new x/y thresholds */ + + priv->threshx = x; + priv->threshy = y; + + /* Update the x/y position in the sample data */ + + priv->sample.x = MIN(x, UINT16_MAX); + priv->sample.y = MIN(y, UINT16_MAX); + +#ifdef CONFIG_SAMA5_TSD_4WIRE + /* Scale the pressure and update the pressure in the sample data. + * + * The method to measure the pressure (Rp) applied to the + * touchscreen is based on the known resistance of the X-Panel + * resistance (Rxp). Three conversions (Xpos, Z1, Z2) are + * necessary to determine the value of Rp (Zaxis resistance). + * + * Rp = Rxp * (Xraw / 1024) * [(Z2 / Z1) - 1] + */ + + z2 = (pressr & ADC_PRESSR_Z2_MASK) >> ADC_PRESSR_Z2_SHIFT; + z1 = (pressr & ADC_PRESSR_Z1_MASK) >> ADC_PRESSR_Z1_SHIFT; + p = CONFIG_SAMA_TSD_RXP * xraw * (z2 - z1) / z1; + + priv->sample.p = MIN(p, UINT16_MAX); +#endif + + /* The X/Y positional data is now valid */ + + priv->sample.valid = true; + + /* If this is the first (acknowledged) pen down report, then + * report this as the first contact. If contact == CONTACT_DOWN, + * it will be set to set to CONTACT_MOVE after the contact is + * first sampled. + */ + + if (priv->sample.contact != CONTACT_MOVE) + { + /* First contact. Handle transitions from pen UP to pen DOWN */ + + priv->sample.contact = CONTACT_DOWN; + + /* Configure for periodic trigger */ + + sam_tsd_setaverage(priv, ADC_TSMR_TSAV_8CONV); + sam_tsd_debounce(priv, 300); /* 300ns */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_PERIOD; + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); + } + } + + /* Indicate the availability of new sample data for this ID */ + + priv->sample.id = priv->id; + priv->penchange = true; + + /* Notify any waiters that new touchscreen data is available */ + + sam_tsd_notify(priv); + + /* Exit, re-enabling touchscreen interrupts */ + +ignored: + /* Re-enable touchscreen interrupts as appropriate. */ + + sam_adc_putreg(priv->adc, SAM_ADC_IER, ier); + + /* Release our lock on the state structure */ + + sam_adc_unlock(priv->adc); +} + +/**************************************************************************** + * Name: sam_tsd_schedule + ****************************************************************************/ + +static int sam_tsd_schedule(struct sam_tsd_s *priv) +{ + int ret; + + /* Disable the watchdog timer. It will be re-enabled in the worker thread + * while the pen remains down. + */ + + wd_cancel(priv->wdog); + + /* Disable further touchscreen interrupts. Touchscreen interrupts will be + * re-enabled after the worker thread executes. + */ + + sam_adc_putreg(priv->adc, SAM_ADC_IDR, ADC_TSD_ALLINTS); + + /* Transfer processing to the worker thread. Since touchscreen ADC interrupts are + * disabled while the work is pending, no special action should be required + * to protected the work queue. + */ + + DEBUGASSERT(priv->work.worker == NULL); + ret = work_queue(HPWORK, &priv->work, sam_tsd_bottomhalf, priv, 0); + if (ret != 0) + { + illdbg("Failed to queue work: %d\n", ret); + } + + return OK; +} + +/**************************************************************************** + * Name: sam_tsd_expiry + * + * Description: + * While the pen is pressed, pen position is periodically polled via a + * watchdog timer. This function handles that timer expiration. + * + ****************************************************************************/ + +static void sam_tsd_expiry(int argc, uint32_t arg1, ...) +{ + struct sam_tsd_s *priv = (struct sam_tsd_s *)((uintptr_t)arg1); + + /* Schedule touchscreen work */ + + (void)sam_tsd_schedule(priv); +} + +/**************************************************************************** + * Name: sam_tsd_open + ****************************************************************************/ + +static int sam_tsd_open(struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct sam_tsd_s *priv = inode->i_private; + uint8_t tmp; + int ret; + + ivdbg("crefs: %d\n", priv->crefs); + + /* Get exclusive access to the device structures */ + + sam_adc_lock(priv->adc); + + /* Increment the count of references to the device. If this the first + * time that the driver has been opened for this device, then initialize + * the device. + */ + + tmp = priv->crefs + 1; + if (tmp == 0) + { + /* More than 255 opens; uint8_t overflows to zero */ + + ret = -EAGAIN; + } + else + { + /* Save the new open count */ + + priv->crefs = tmp; + + /* Initialize the touchscreen when it is first opened */ + + if (tmp == 1) + { + sam_tsd_initialize(priv); + } + + /* Successfully opened */ + + ret = OK; + } + + sam_adc_unlock(priv->adc); + return ret; +} + +/**************************************************************************** + * Name: sam_tsd_close + ****************************************************************************/ + +static int sam_tsd_close(struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct sam_tsd_s *priv = inode->i_private; + + ivdbg("crefs: %d\n", priv->crefs); + + /* Get exclusive access to the ADC device */ + + sam_adc_lock(priv->adc); + + /* Decrement the references to the driver */ + + DEBUGASSERT(priv->crefs > 0); + priv->crefs--; + + /* If this was the last reference to the driver, then un-initialize the + * TSD now. + */ + + if (priv->crefs == 0) + { + sam_tsd_uninitialize(priv); + } + + sam_adc_unlock(priv->adc); + return OK; +} + +/**************************************************************************** + * Name: sam_tsd_read + ****************************************************************************/ + +static ssize_t sam_tsd_read(struct file *filep, char *buffer, size_t len) +{ + struct inode *inode; + struct sam_tsd_s *priv; + struct touch_sample_s *report; + struct sam_sample_s sample; + int ret; + + ivdbg("buffer:%p len:%d\n", buffer, len); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (struct sam_tsd_s *)inode->i_private; + + /* Verify that the caller has provided a buffer large enough to receive + * the touch data. + */ + + if (len < SIZEOF_TOUCH_SAMPLE_S(1)) + { + /* We could provide logic to break up a touch report into segments and + * handle smaller reads... but why? + */ + + idbg("ERROR: Unsupported read size: %d\n", len); + return -ENOSYS; + } + + /* Get exclusive access to the driver data structure */ + + sam_adc_lock(priv->adc); + + /* Try to read sample data. */ + + ret = sam_tsd_sample(priv, &sample); + if (ret < 0) + { + /* Sample data is not available now. We would ave to wait to get + * receive sample data. If the user has specified the O_NONBLOCK + * option, then just return an error. + */ + + ivdbg("Sample data is not available\n"); + if (filep->f_oflags & O_NONBLOCK) + { + ret = -EAGAIN; + goto errout; + } + + /* Wait for sample data */ + + ret = sam_tsd_waitsample(priv, &sample); + if (ret < 0) + { + /* We might have been awakened by a signal */ + + idbg("ERROR: sam_tsd_waitsample: %d\n", ret); + goto errout; + } + } + + /* In any event, we now have sampled touchscreen data that we can report + * to the caller. + */ + + report = (struct touch_sample_s *)buffer; + memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1)); + report->npoints = 1; + report->point[0].id = sample.id; + report->point[0].x = sample.x; + report->point[0].y = sample.y; +#ifdef CONFIG_SAMA5_TSD_4WIRE + report->point[0].pressure = sample.p; +#endif + + /* Report the appropriate flags */ + + if (sample.contact == CONTACT_UP) + { + /* Pen is now up. Is the positional data valid? This is important + * to know because the release will be sent to the window based on + * its last positional data. + */ + + if (sample.valid) + { + report->point[0].flags = TSD_PENUP_VALID; + } + else + { + report->point[0].flags = TSD_PENUP_INVALID; + } + } + else if (sample.contact == CONTACT_DOWN) + { + /* First contact */ + + report->point[0].flags = TSD_PENDOWN; + } + else /* if (sample->contact == CONTACT_MOVE) */ + { + /* Movement of the same contact */ + + report->point[0].flags = TSD_PENMOVE; + } + + ivdbg(" id: %d\n", report->point[0].id); + ivdbg(" flags: %02x\n", report->point[0].flags); + ivdbg(" x: %d\n", report->point[0].x); + ivdbg(" y: %d\n", report->point[0].y); + + ret = SIZEOF_TOUCH_SAMPLE_S(1); + +errout: + sam_adc_unlock(priv->adc); + ivdbg("Returning: %d\n", ret); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name:sam_tsd_ioctl + ****************************************************************************/ + +static int sam_tsd_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode; + struct sam_tsd_s *priv; + int ret; + + ivdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (struct sam_tsd_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + sam_adc_lock(priv->adc); + + /* Process the IOCTL by command */ + + switch (cmd) + { + default: + ret = -ENOTTY; + break; + } + + sam_adc_unlock(priv->adc); + return ret; +} + +/**************************************************************************** + * Name: sam_tsd_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int sam_tsd_poll(struct file *filep, struct pollfd *fds, bool setup) +{ + struct inode *inode; + struct sam_tsd_s *priv; + int ret = OK; + int i; + + ivdbg("setup: %d\n", (int)setup); + DEBUGASSERT(filep && fds); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (struct sam_tsd_s *)inode->i_private; + + /* Get exclusive access to the ADC hardware */ + + sam_adc_lock(priv->adc); + + /* Are we setting up the poll? Or tearing it down? */ + + if (setup) + { + /* Ignore waits that do not include POLLIN */ + + if ((fds->events & POLLIN) == 0) + { + ret = -EDEADLK; + goto errout; + } + + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference + */ + + for (i = 0; i < CONFIG_SAMA5_TSD_NPOLLWAITERS; i++) + { + /* Find an available slot */ + + if (!priv->fds[i]) + { + /* Bind the poll structure and this slot */ + + priv->fds[i] = fds; + fds->priv = &priv->fds[i]; + break; + } + } + + if (i >= CONFIG_SAMA5_TSD_NPOLLWAITERS) + { + fds->priv = NULL; + ret = -EBUSY; + goto errout; + } + + /* Should we immediately notify on any of the requested events? */ + + if (priv->penchange) + { + sam_tsd_notify(priv); + } + } + else if (fds->priv) + { + /* This is a request to tear down the poll. */ + + struct pollfd **slot = (struct pollfd **)fds->priv; + DEBUGASSERT(slot != NULL); + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->priv = NULL; + } + +errout: + sam_adc_unlock(priv->adc); + return ret; +} +#endif + +/**************************************************************************** + * Initialization and Configuration + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tsd_startuptime + * + * Description: + * Set the STARTUP field of the ADC MR register. + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * time - The new startup time in nanoseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_startuptime(struct sam_tsd_s *priv, uint32_t time) +{ + uint32_t startup; + uint32_t regval; + + /* Formula for STARTUP is: + * + * STARTUP = (time x ADCCLK) / (1000000) - 1 + * + * Division multiplied by 10 for higher precision. + */ + + startup = (time * BOARD_ADCCLK_FREQUENCY) / 100000; + + if (startup % 10) + { + /* Handle partial values by not decrementing startup. This is + * basically a 'ceil' operation. + */ + + startup /= 10; + } + else + { + /* The final value needs to be decrement by one */ + + startup /= 10; + if (startup) + { + startup --; + } + } + + /* Then set the STARTUP value in the ADC MR register. */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_MR); + regval &= ~ADC_MR_STARTUP_MASK; + + if (startup > 896) + { + regval = ADC_MR_STARTUP_960; + } + else if (startup > 832) + { + regval = ADC_MR_STARTUP_896; + } + else if (startup > 768) + { + regval = ADC_MR_STARTUP_832; + } + else if (startup > 704) + { + regval = ADC_MR_STARTUP_768; + } + else if (startup > 640) + { + regval = ADC_MR_STARTUP_704; + } + else if (startup > 576) + { + regval = ADC_MR_STARTUP_640; + } + else if (startup > 512) + { + regval = ADC_MR_STARTUP_576; + } + else if (startup > 112) + { + regval = ADC_MR_STARTUP_512; + } + else if (startup > 96) + { + regval = ADC_MR_STARTUP_112; + } + else if (startup > 80) + { + regval = ADC_MR_STARTUP_96; + } + else if (startup > 64) + { + regval = ADC_MR_STARTUP_80; + } + else if (startup > 24) + { + regval = ADC_MR_STARTUP_64; + } + else if (startup > 16) + { + regval = ADC_MR_STARTUP_24; + } + else if (startup > 8) + { + regval = ADC_MR_STARTUP_16; + } + else if (startup > 0) + { + regval = ADC_MR_STARTUP_8; + } + else + { + regval = ADC_MR_STARTUP_0; + } + + sam_adc_putreg(priv->adc, SAM_ADC_MR, regval); +} + +/**************************************************************************** + * Name: sam_tsd_tracking + * + * Description: + * Set the TRACKTIM field of the ADC MR register. + * + * TrackingTime = (TRACKTIM + 1) * ADCClock periods. + * TRACKTIM = (TrackingTime * ADCCLK) / (1000000000) - 1 + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * time - The new tracking time in nanoseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_tracking(struct sam_tsd_s *priv, uint32_t time) +{ + uint32_t tracktim; + uint32_t regval; + + /* Formula for SHTIM is: + * + * TRACKTIM = (TrackingTime * ADCCLK) / (1000000000) - 1 + * + * Since 1 billion is close to the maximum value for an integer, we first + * divide ADCCLK by 1000 to avoid an overflow + */ + + tracktim = (time * (BOARD_ADCCLK_FREQUENCY / 1000)) / 100000; + if (tracktim % 10) + { + /* Handle partial values by not decrementing tracktim. This is + * basically a 'ceil' operation. + */ + + tracktim /= 10; + } + else + { + /* The final value needs to be decrement by one */ + + tracktim /= 10; + if (tracktim) + { + tracktim --; + } + } + + /* Set the neew TRACKTIM field value int he ADC MR register */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_MR); + regval &= ~ADC_MR_TRACKTIM_MASK; + regval |= ADC_MR_TRACKTIM(tracktim); + sam_adc_putreg(priv->adc, SAM_ADC_MR, regval); +} + +/**************************************************************************** + * Name: sam_tsd_trigperiod + * + * Description: + * Set the TGPER field of the TRGR register in order to define a periodic + * trigger perioc. + * + * Trigger Period = (TRGPER+1) / ADCCLK + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * time - The new trigger period in nanoseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_trigperiod(struct sam_tsd_s *priv, uint32_t period) +{ + uint32_t trigper; + uint32_t regval; + uint32_t div; + + /* Divide trigger period avoid overflows. Division by ten is awkard, but + * appropriate here because times are specified in decimal with lots of + * zeroes. + */ + + div = 100000000; + while (period >= 10 && div >= 10) + { + period /= 10; + div /= 10; + } + + /* Calculate and adjust the scaled trigger period: + * + * Trigger Period = (TRGPER+1) / ADCCLK + */ + + trigper = (period * BOARD_ADCCLK_FREQUENCY) / div; + if ((trigper % 10) != 0) + { + /* Handle partial values by not decrementing trigper. This is + * basically a 'ceil' operation. + */ + + trigper /= 10; + } + else + { + /* The final value needs to be decrement by one */ + + trigper /= 10; + if (trigper > 0) + { + trigper--; + } + } + + /* Set the calculated trigger period in the TRGR register */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGPER_MASK; + regval |= ADC_TRGR_TRGPER(trigper); + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); +} + +/**************************************************************************** + * Name: sam_tsd_debounce + * + * Description: + * Set the Pen Detect Debouncing Period (PENBC) in the touchscreen mode + * register. + * + * Debouncing period = 2 ** PENDBC ADCClock periods. + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * time - The new debounce time in nanoseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_tsd_debounce(struct sam_tsd_s *priv, uint32_t time) +{ + uint32_t candidate; + uint32_t target; + uint32_t regval; + uint32_t pendbc; + uint32_t div; + uint32_t clk; + + /* Make sure that a valid debounce time was provided */ + + DEBUGASSERT(time > 0); + + /* Divide time and ADCCLK to avoid overflows. Division by ten is awkard, + * but appropriate here because times are specified in decimal with lots of + * zeroes. + */ + + div = 1000000000; + while (div > 1 && (time % 10) == 0) + { + time /= 10; + div /= 10; + } + + clk = BOARD_ADCCLK_FREQUENCY; + while (div > 1 && (clk % 10) == 0) + { + clk /= 10; + div /= 10; + } + + /* Compute PENDBC */ + + target = time * clk / div; + candidate = 1; + pendbc = 0; + + while (candidate < target) + { + pendbc++; + candidate *= 2; + } + + DEBUGASSERT(pendbc > 0); + + /* Update the TSMR with the new PENBC value */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TSMR); + regval &= ~ADC_TSMR_PENDBC_MASK; + regval |= ADC_TSMR_PENDBC(pendbc); + sam_adc_putreg(priv->adc, SAM_ADC_TSMR, regval); +} + +/**************************************************************************** + * Name: sam_tsd_initialize + * + * Description: + * Initialize the touchscreen for normal operation. This function is + * called from sam_tsd_open() the first time that the driver is opened. + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +static void sam_tsd_initialize(struct sam_tsd_s *priv) +{ + uint32_t regval; + + /* Disable touch trigger */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_NOTRIG; + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); + + /* Setup timing */ + + sam_tsd_startuptime(priv, BOARD_TSD_STARTUP); + sam_tsd_tracking(priv, BOARD_TSD_TRACKTIM); + sam_tsd_trigperiod(priv, 20000000); /* 20ms */ + + /* Setup the touchscreen mode */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TSMR); + regval &= ~ADC_TSMR_TSMODE_MASK; + +#if defined(CONFIG_SAMA5_TSD_5WIRE) + regval |= ADC_TSMR_TSMODE_5WIRE; +#elif defined(CONFIG_SAMA5_TSD_4WIRENPM) + regval |= ADC_TSMR_TSMODE_4WIRENPM; +#else /* if defined(CONFIG_SAMA5_TSD_4WIRE) */ + regval |= ADC_TSMR_TSMODE_4WIRE; +#endif + + sam_adc_putreg(priv->adc, SAM_ADC_TSMR, regval); + + /* Disable averaging */ + + sam_tsd_setaverage(priv, ADC_TSMR_TSAV_NOFILTER); + + /* Select 4-wire w/pressure, 4-wire w/o pressure, or 5 wire modes */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TSMR); + regval &= ~ADC_TSMR_TSMODE_MASK; + +#if defined(CONFIG_SAMA5_TSD_5WIRE) + regval |= ADC_TSMR_TSMODE_5WIRE; +#elif defined(CONFIG_SAMA5_TSD_4WIRENPM) + regval |= ADC_TSMR_TSMODE_4WIRENPM; +#else /* if defined(CONFIG_SAMA5_TSD_4WIRE) */ + regval |= ADC_TSMR_TSMODE_4WIRE; +#endif + + /* Disable all TSD-related interrupts */ + + sam_adc_putreg(priv->adc, SAM_ADC_IDR, ADC_TSD_ALLINTS); + + /* Clear any pending TSD interrupts */ + + sam_adc_getreg(priv->adc, SAM_ADC_ISR); + + /* Read and discard any samples */ + + sam_adc_getreg(priv->adc, SAM_ADC_XPOSR); + sam_adc_getreg(priv->adc, SAM_ADC_YPOSR); +#ifdef CONFIG_SAMA5_TSD_4WIRE + sam_adc_getreg(priv->adc, SAM_ADC_PRESSR); +#endif + + /* Enable pen contact detection */ + + regval |= ADC_TSMR_PENDET; + sam_adc_putreg(priv->adc, SAM_ADC_TSMR, regval); + + /* Set up pen debounce time */ + + sam_tsd_debounce(priv, BOARD_TSD_DEBOUNCE); + + /* Configure pen interrupt generation */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_PEN; + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); + + sam_adc_putreg(priv->adc, SAM_ADC_IER, ADC_INT_PEN); +} + +/**************************************************************************** + * Name: sam_tsd_uninitialize + * + * Description: + * Uninitialize the touchscreen. This function is called from + * sam_tsd_close() when the final driver instance is closed. + * + * Input Parameters: + * priv - A reference to the touchscreen device structure + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +static void sam_tsd_uninitialize(struct sam_tsd_s *priv) +{ + uint32_t regval; + + /* Disable the watchdog timer. It will be re-enabled in the worker thread + * while the pen remains down. + */ + + wd_cancel(priv->wdog); + + /* Disable further touchscreen interrupts. Touchscreen interrupts will be + * re-enabled after the worker thread executes. + */ + + sam_adc_putreg(priv->adc, SAM_ADC_IDR, ADC_TSD_ALLINTS); + + /* Disable touch trigger */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TRGR); + regval &= ~ADC_TRGR_TRGMOD_MASK; + regval |= ADC_TRGR_TRGMOD_NOTRIG; + sam_adc_putreg(priv->adc, SAM_ADC_TRGR, regval); + + /* Disable the touchscreen mode */ + + regval = sam_adc_getreg(priv->adc, SAM_ADC_TSMR); + regval &= ~ADC_TSMR_TSMODE_MASK; + regval |= ADC_TSMR_TSMODE_NONE; + sam_adc_putreg(priv->adc, SAM_ADC_TSMR, regval); + + /* No touch and no valid sample data */ + + priv->sample.contact = CONTACT_NONE; + priv->sample.valid = false; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tsd_register + * + * Description: + * Configure the SAMA5 touchscreen. This will register the driver as + * /dev/inputN where N is the minor device number + * + * Input Parameters: + * adc - An opaque reference to the ADC device structure + * minor - The input device minor number + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int sam_tsd_register(struct sam_adc_s *adc, int minor) +{ + struct sam_tsd_s *priv = &g_tsd; + char devname[DEV_NAMELEN]; + int ret; + + ivdbg("minor: %d\n", minor); + + /* Debug-only sanity checks */ + + DEBUGASSERT(adc && minor >= 0 && minor < 100); + + /* Initialize the touchscreen device driver instance */ + + memset(priv, 0, sizeof(struct sam_tsd_s)); + priv->adc = adc; /* Save the ADC device handle */ + priv->wdog = wd_create(); /* Create a watchdog timer */ + priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */ + priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */ + + sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + + /* Register the device as an input device */ + + (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); + ivdbg("Registering %s\n", devname); + + ret = register_driver(devname, &g_tsdops, 0666, priv); + if (ret < 0) + { + idbg("ERROR: register_driver() failed: %d\n", ret); + goto errout_with_priv; + } + + /* And return success. The hardware will be initialized as soon as the + * touchscreen driver is opened for the first time. + */ + + return OK; + +errout_with_priv: + sem_destroy(&priv->waitsem); + return ret; +} + +/**************************************************************************** + * Name: sam_tsd_interrupt + * + * Description: + * Handles ADC interrupts associated with touchscreen channels + * + * Input parmeters: + * pending - Current set of pending interrupts being handled + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tsd_interrupt(uint32_t pending) +{ + struct sam_tsd_s *priv = &g_tsd; + int ret; + + /* Are there pending TSD interrupts? */ + + if ((pending & ADC_TSD_ALLINTS) != 0) + { + /* Schedule sampling to occur by the interrupt bottom half on the + * worker thread. + */ + + ret = sam_tsd_schedule(priv); + if (ret < 0) + { + idbg("ERROR: sam_tsd_schedule failed: %d\n", ret); + } + } +} + +#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TSD */ diff --git a/arch/arm/src/sama5/sam_tsd.h b/arch/arm/src/sama5/sam_tsd.h new file mode 100644 index 0000000000000000000000000000000000000000..3ae36434b792a21f213144a98f13694b1981b551 --- /dev/null +++ b/arch/arm/src/sama5/sam_tsd.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_tsd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_TSD_H +#define __ARCH_ARM_SRC_SAMA5_SAM_TSD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/sam_adc.h" + +#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TSD) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_SAMA_TSD_RXP +# define CONFIG_SAMA_TSD_RXP 6 +#endif + +/* Touchscreen interrupt event sets + * + * ADC_INT_XRDY TSD Measure XPOS Ready Interrupt + * ADC_INT_YRDY TSD Measure YPOS Ready Interrupt + * ADC_INT_PRDY TSD Measure Pressure Ready Interrupt + * ADC_INT_PEN Pen Contact Interrupt + * ADC_INT_NOPEN No Pen Contact Interrupt + * ADC_SR_PENS Pen detect Status (Not an interrupt) + */ + +#define ADC_TSD_CMNINTS (ADC_INT_XRDY | ADC_INT_YRDY | ADC_INT_PRDY | ADC_INT_NOPEN) +#define ADC_TSD_ALLINTS (ADC_TSD_CMNINTS | ADC_INT_PEN) +#define ADC_TSD_ALLSTATUS (ADC_TSD_ALLINTS | ADC_SR_PENS) +#define ADC_TSD_RELEASEINTS ADC_TSD_CMNINTS + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tsd_register + * + * Description: + * Configure the SAMA5 touchscreen. This will register the driver as + * /dev/inputN where N is the minor device number + * + * Input Parameters: + * dev - The ADC device handle received from sam_adc_initialize() + * minor - The input device minor number + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +struct sam_adc_s; +int sam_tsd_register(FAR struct sam_adc_s *adc, int minor); + +/**************************************************************************** + * Interfaces exported from the touchscreen to the ADC driver + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tsd_interrupt + * + * Description: + * Handles ADC interrupts associated with touchscreen channels + * + * Input parmeters: + * pending - Current set of pending interrupts being handled + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tsd_interrupt(uint32_t pending); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TSD */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TSD_H */ diff --git a/arch/arm/src/sama5/sam_twi.c b/arch/arm/src/sama5/sam_twi.c new file mode 100644 index 0000000000000000000000000000000000000000..8944de9ed4b00c5affbdda204f6f54e8878cfd3d --- /dev/null +++ b/arch/arm/src/sama5/sam_twi.c @@ -0,0 +1,1371 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_twi.c + * + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/sam_pmc.h" +#include "chip/sam_pinmap.h" + +#include "sam_periphclks.h" +#include "sam_pio.h" +#include "sam_twi.h" + +#if defined(CONFIG_SAMA5_TWI0) || defined(CONFIG_SAMA5_TWI1) || \ + defined(CONFIG_SAMA5_TWI2) || defined(CONFIG_SAMA5_TWI3) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_SAMA5_TWI0_FREQUENCY +# define CONFIG_SAMA5_TWI0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAMA5_TWI1_FREQUENCY +# define CONFIG_SAMA5_TWI1_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAMA5_TWI2_FREQUENCY +# define CONFIG_SAMA5_TWI2_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAMA5_TWI3_FREQUENCY +# define CONFIG_SAMA5_TWI3_FREQUENCY 100000 +#endif + +/* Driver internal definitions *************************************************/ +/* If verbose I2C debug output is enable, then allow more time before we declare + * a timeout. The debug output from twi_interrupt will really slow things down! + * + * With a very slow clock (say 100,000 Hz), less than 100 usec would be required + * to transfer on byte. So these define a "long" timeout. + */ + +#if defined(CONFIG_DEBUG_I2C) && defined(CONFIG_DEBUG_VERBOSE) +# define TWI_TIMEOUT_MSPB (50) /* 50 msec/byte */ +#else +# define TWI_TIMEOUT_MSPB (5) /* 5 msec/byte */ +#endif + +/* Clocking to the TWI module(s) is provided by the main clock, divided down + * as necessary. + */ + +#define TWI_MAX_FREQUENCY 66000000 /* Maximum TWI frequency */ + +/* Macros to convert a I2C pin to a PIO open-drain output */ + +#define I2C_INPUT (PIO_INPUT | PIO_CFG_PULLUP) +#define I2C_OUTPUT (PIO_OUTPUT | PIO_CFG_OPENDRAIN | PIO_OUTPUT_SET) + +#define MKI2C_INPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_INPUT) +#define MKI2C_OUTPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ***********************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +# define i2clldbg lldbg +# define i2cllvdbg llvdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +# define i2clldbg(x...) +# define i2cllvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Invariant attributes of a TWI bus */ + +struct twi_attr_s +{ + uint8_t twi; /* TWI device number (for debug output) */ + uint8_t pid; /* TWI peripheral ID */ + uint16_t irq; /* IRQ number for this TWI bus */ + pio_pinset_t sclcfg; /* TWI CK pin configuration (SCL in I2C-ese) */ + pio_pinset_t sdacfg; /* TWI D pin configuration (SDA in I2C-ese) */ + uintptr_t base; /* Base address of TWI registers */ + xcpt_t handler; /* TWI interrupt handler */ +}; + +/* State of a TWI bus */ + +struct twi_dev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + const struct twi_attr_s *attr; /* Invariant attributes of TWI device */ + struct i2c_msg_s *msg; /* Message list */ + uint32_t twiclk; /* TWI input clock frequency */ + uint32_t frequency; /* TWI transfer clock frequency */ + uint8_t msgc; /* Number of message in the message list */ + + sem_t exclsem; /* Only one thread can access at a time */ + sem_t waitsem; /* Wait for TWI transfer completion */ + WDOG_ID timeout; /* Watchdog to recover from bus hangs */ + volatile int result; /* The result of the transfer */ + volatile int xfrd; /* Number of bytes transfers */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMA5_TWI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helper functions */ + +static void twi_takesem(sem_t *sem); +#define twi_givesem(sem) (sem_post(sem)) + +#ifdef CONFIG_SAMA5_TWI_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, + uint32_t value, uintptr_t address); +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address); +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value); +#else +# define twi_checkreg(priv,wr,value,address) (false) +# define twi_putabs(p,a,v) putreg32(v,a) +# define twi_getabs(p,a) getreg32(a) +#endif + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, + unsigned int offset); +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value); + +/* I2C transfer helper functions */ + +static int twi_wait(struct twi_dev_s *priv, unsigned int size); +static void twi_wakeup(struct twi_dev_s *priv, int result); +static int twi_interrupt(struct twi_dev_s *priv); +#ifdef CONFIG_SAMA5_TWI0 +static int twi0_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAMA5_TWI1 +static int twi1_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAMA5_TWI2 +static int twi2_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAMA5_TWI3 +static int twi3_interrupt(int irq, FAR void *context); +#endif +static void twi_timeout(int argc, uint32_t arg, ...); + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg); + +/* I2C device operations */ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s * dev); +#endif + +/* Initialization */ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency); +static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TWI0 +static const struct twi_attr_s g_twi0attr = +{ + .twi = 0, + .pid = SAM_PID_TWI0, + .irq = SAM_IRQ_TWI0, + .sclcfg = PIO_TWI0_CK, + .sdacfg = PIO_TWI0_D, + .base = SAM_TWI0_VBASE, + .handler = twi0_interrupt, +}; + +static struct twi_dev_s g_twi0; +#endif + +#ifdef CONFIG_SAMA5_TWI1 +static const struct twi_attr_s g_twi1attr = +{ + .twi = 1, + .pid = SAM_PID_TWI1, + .irq = SAM_IRQ_TWI1, + .sclcfg = PIO_TWI1_CK, + .sdacfg = PIO_TWI1_D, + .base = SAM_TWI1_VBASE, + .handler = twi1_interrupt, +}; + +static struct twi_dev_s g_twi1; +#endif + +#ifdef CONFIG_SAMA5_TWI2 +static const struct twi_attr_s g_twi2attr = +{ + .twi = 2, + .pid = SAM_PID_TWI2, + .irq = SAM_IRQ_TWI2, + .sclcfg = PIO_TWI2_CK, + .sdacfg = PIO_TWI2_D, + .base = SAM_TWI2_VBASE, + .handler = twi2_interrupt, +}; + +static struct twi_dev_s g_twi2; +#endif + +#ifdef CONFIG_SAMA5_TWI3 +static const struct twi_attr_s g_twi3attr = +{ + .twi = 3, + .pid = SAM_PID_TWI3, + .irq = SAM_IRQ_TWI3, + .sclcfg = PIO_TWI3_CK, + .sdacfg = PIO_TWI3_D, + .base = SAM_TWI3_VBASE, + .handler = twi3_interrupt, +}; + +static struct twi_dev_s g_twi3; +#endif + +static const struct i2c_ops_s g_twiops = +{ + .transfer = twi_transfer +#ifdef CONFIG_I2C_RESET + , .reset = twi_reset +#endif +}; + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: twi_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wake-ups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void twi_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: twi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * false: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TWI_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = value; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: twi_getabs + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TWI_REGDEBUG +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address) +{ + uint32_t value = getreg32(address); + + if (twi_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } + + return value; +} +#endif + +/**************************************************************************** + * Name: twi_putabs + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_TWI_REGDEBUG +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value) +{ + if (twi_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } + + putreg32(value, address); +} +#endif + +/**************************************************************************** + * Name: twi_getrel + * + * Description: + * Read a TWI register using an offset relative to the TWI base address + * + ****************************************************************************/ + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, unsigned int offset) +{ + return twi_getabs(priv, priv->attr->base + offset); +} + +/**************************************************************************** + * Name: twi_putrel + * + * Description: + * Write a value to a TWI register using an offset relative to the TWI base + * address. + * + ****************************************************************************/ + +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value) +{ + twi_putabs(priv, priv->attr->base + offset, value); +} + +/**************************************************************************** + * I2C transfer helper functions + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_wait + * + * Description: + * Perform a I2C transfer start + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +static int twi_wait(struct twi_dev_s *priv, unsigned int size) +{ + uint32_t timeout; + + /* Calculate a timeout value based on the size of the transfer + * + * ticks = msec-per-byte * bytes / msec-per-tick + * + * There is no concern about arithmetic overflow for reasonable transfer sizes. + */ + + timeout = MSEC2TICK(TWI_TIMEOUT_MSPB); + if (timeout < 1) + { + timeout = 1; + } + + /* Then start the timeout. This timeout is needed to avoid hangs if/when an + * TWI transfer stalls. + */ + + wd_start(priv->timeout, timeout, twi_timeout, 1, (uint32_t)priv); + + /* Wait for either the TWI transfer or the timeout to complete */ + + do + { + i2cvdbg("TWI%d Waiting...\n", priv->attr->twi); + twi_takesem(&priv->waitsem); + i2cvdbg("TWI%d Awakened with result: %d\n", + priv->attr->twi, priv->result); + } + while (priv->result == -EBUSY); + + /* We get here via twi_wakeup. The watchdog timer has been disabled and + * all further interrupts for the TWI have been disabled. + */ + + return priv->result; +} + +/**************************************************************************** + * Name: twi_wakeup + * + * Description: + * A terminal event has occurred. Wake-up the waiting thread + * + ****************************************************************************/ + +static void twi_wakeup(struct twi_dev_s *priv, int result) +{ + /* Cancel any pending timeout */ + + wd_cancel(priv->timeout); + + /* Disable any further TWI interrupts */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_ALL); + + /* Wake up the waiting thread with the result of the transfer */ + + priv->result = result; + twi_givesem(&priv->waitsem); +} + +/**************************************************************************** + * Name: twi_interrupt + * + * Description: + * The TWI Interrupt Handler + * + ****************************************************************************/ + +static int twi_interrupt(struct twi_dev_s *priv) +{ + struct i2c_msg_s *msg; + uint32_t sr; + uint32_t imr; + uint32_t pending; + uint32_t regval; + + /* Retrieve masked interrupt status */ + + sr = twi_getrel(priv, SAM_TWI_SR_OFFSET); + imr = twi_getrel(priv, SAM_TWI_IMR_OFFSET); + pending = sr & imr; + + i2cllvdbg("TWI%d pending: %08x\n", priv->attr->twi, pending); + + /* Byte received */ + + msg = priv->msg; + if ((pending & TWI_INT_RXRDY) != 0) + { + msg->buffer[priv->xfrd] = twi_getrel(priv, SAM_TWI_RHR_OFFSET); + priv->xfrd++; + + /* Check for transfer complete */ + + if (priv->xfrd >= msg->length) + { + /* The transfer is complete. Disable the RXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_RXRDY); + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP); + } + + /* Not yet complete, but will the next be the last byte? */ + + else if (priv->xfrd == (msg->length - 1)) + { + /* Yes, set the stop signal */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP); + } + } + + /* Byte sent */ + + else if ((pending & TWI_INT_TXRDY) != 0) + { + /* Transfer finished? */ + + if (priv->xfrd >= msg->length) + { + /* The transfer is complete. Disable the TXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXRDY); + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP); + + /* Send the STOP condition */ + + regval = twi_getrel(priv, SAM_TWI_CR_OFFSET); + regval |= TWI_CR_STOP; + twi_putrel(priv, SAM_TWI_CR_OFFSET, regval); + } + + /* No, there are more bytes remaining to be sent */ + + else + { + twi_putrel(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd]); + priv->xfrd++; + } + } + + /* Transfer complete */ + + else if ((pending & TWI_INT_TXCOMP) != 0) + { + twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP); + + /* Is there another message to send? */ + + if (priv->msgc > 1) + { + /* Yes... start the next message */ + + priv->msg++; + priv->msgc--; + twi_startmessage(priv, priv->msg); + } + else + { + /* No.. we made it to the end of the message list with no errors. + * Cancel any timeout and wake up the waiting thread with a + * success indication. + */ + + twi_wakeup(priv, OK); + } + } + + /* Check for errors */ + + else if ((pending & TWI_INT_ERRORS) != 0) + { + /* Wake up the thread with an I/O error indication */ + + i2clldbg("ERROR: TWI%d pending: %08x\n", priv->attr->twi, pending); + twi_wakeup(priv, -EIO); + } + + return OK; +} + +#ifdef CONFIG_SAMA5_TWI0 +static int twi0_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi0); +} +#endif + +#ifdef CONFIG_SAMA5_TWI1 +static int twi1_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi1); +} +#endif + +#ifdef CONFIG_SAMA5_TWI2 +static int twi2_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi2); +} +#endif + +#ifdef CONFIG_SAMA5_TWI3 +static int twi3_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi3); +} +#endif + +/**************************************************************************** + * Name: twi_timeout + * + * Description: + * Watchdog timer for timeout of TWI operation + * + * Assumptions: + * Called from the timer interrupt handler with interrupts disabled. + * + ****************************************************************************/ + +static void twi_timeout(int argc, uint32_t arg, ...) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)arg; + + i2clldbg("ERROR: TWI%d Timeout!\n", priv->attr->twi); + twi_wakeup(priv, -ETIMEDOUT); +} + +/**************************************************************************** + * Name: twi_startread + * + * Description: + * Start the next read message + * + ****************************************************************************/ + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set STOP signal if only one byte is sent */ + + if (msg->length == 1) + { + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP); + } + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWI_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_MREAD | + TWI_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWI_IADR_OFFSET, 0); + + /* Enable read interrupt and send the START condition */ + + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_RXRDY | TWI_INT_ERRORS); + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_START); +} + +/**************************************************************************** + * Name: twi_startwrite + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWI_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWI_IADR_OFFSET, 0); + + /* Write first byte to send. */ + + twi_putrel(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd++]); + + /* Enable write interrupt */ + + twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXRDY | TWI_INT_ERRORS); +} + +/**************************************************************************** + * Name: twi_startmessage + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + if ((msg->flags & I2C_M_READ) != 0) + { + twi_startread(priv, msg); + } + else + { + twi_startwrite(priv, msg); + } +} + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_transfer + * + * Description: + * Receive a block of data on I2C using the previously selected I2C + * frequency and slave address. + * + * Returned Value: + * Returns zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)dev; + irqstate_t flags; + unsigned int size; + int i; + int ret; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + i2cvdbg("TWI%d count: %d\n", priv->attr->twi, count); + + /* Calculate the total transfer size so that we can calculate a reasonable + * timeout value. + */ + + size = 0; + for (i = 0; i < count; i++) + { + size += msgs[i].length; + } + + DEBUGASSERT(size > 0); + + /* Get exclusive access to the device */ + + twi_takesem(&priv->exclsem); + + /* Setup the message transfer */ + + priv->msg = msgs; + priv->msgc = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + twi_setfrequency(priv, msgs->frequency); + + /* Initiate the transfer. The rest will be handled from interrupt + * logic. Interrupts must be disabled to prevent re-entrance from the + * interrupt level. + */ + + flags = enter_critical_section(); + twi_startmessage(priv, msgs); + + /* And wait for the transfers to complete. Interrupts will be re-enabled + * while we are waiting. + */ + + ret = twi_wait(priv, size); + if (ret < 0) + { + i2cdbg("ERROR: Transfer failed: %d\n", ret); + } + + leave_critical_section(flags); + twi_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: twi_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s *dev) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)dev; + unsigned int clockcnt; + unsigned int stretchcnt; + uint32_t sclpin; + uint32_t sdapin; + int ret; + + ASSERT(priv); + + /* Get exclusive access to the TWI device */ + + twi_takesem(&priv->exclsem); + + /* Disable TWI interrupts */ + + up_disable_irq(priv->attr->irq); + + /* Use PIO configuration to un-wedge the bus. + * + * Reconfigure both pins as open drain outputs with initial output value + * "high" (i.e., floating since these are open-drain outputs). + */ + + sclpin = MKI2C_OUTPUT(priv->attr->sclcfg); + sdapin = MKI2C_OUTPUT(priv->attr->sdacfg); + + sam_configpio(sclpin); + sam_configpio(sdapin); + + /* Peripheral clocking must be enabled in order to read valid data from + * the output pin (clocking is enabled automatically for pins configured + * as inputs). + */ + + sam_pio_forceclk(sclpin, true); + sam_pio_forceclk(sdapin, true); + + /* Clock the bus until any slaves currently driving it low let it float. + * Reading from the output will return the actual sensed level on the + * SDA pin (not the level that we wrote). + */ + + clockcnt = 0; + while (sam_pioread(sdapin) == false) + { + /* Give up if we have tried too hard */ + + if (clockcnt++ > 10) + { + ret = -ETIMEDOUT; + goto errout_with_lock; + } + + /* Sniff to make sure that clock stretching has finished. SCL should + * be floating high here unless something is driving it low. + * + * If the bus never relaxes, the reset has failed. + */ + + stretchcnt = 0; + while (sam_pioread(sclpin) == false) + { + /* Give up if we have tried too hard */ + + if (stretchcnt++ > 10) + { + ret = -EAGAIN; + goto errout_with_lock; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + sam_piowrite(sclpin, false); + up_udelay(10); + + /* Drive SCL high (floating) again */ + + sam_piowrite(sclpin, true); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + sam_piowrite(sdapin, false); + up_udelay(10); + sam_piowrite(sclpin, false); + up_udelay(10); + + sam_piowrite(sclpin, true); + up_udelay(10); + sam_piowrite(sdapin, true); + up_udelay(10); + + /* Clocking is no longer forced */ + + sam_pio_forceclk(sclpin, false); + sam_pio_forceclk(sdapin, false); + + /* Re-initialize the port hardware */ + + twi_hw_initialize(priv, priv->frequency); + ret = OK; + +errout_with_lock: + + /* Release our lock on the bus */ + + twi_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Initialization + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_enableclk + * + * Description: + * Enable clocking on the selected TWI + * + ****************************************************************************/ + +static void twi_enableclk(struct twi_dev_s *priv) +{ + int pid; + + /* Get the peripheral ID associated with the TWI device port and enable + * clocking to the TWI block. + */ + + pid = priv->attr->pid; + if (pid < 32) + { + sam_enableperiph0(pid); + } + else + { + sam_enableperiph1(pid); + } +} + +/**************************************************************************** + * Name: twi_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency) +{ + unsigned int ckdiv; + unsigned int cldiv; + uint32_t regval; + + if (frequency != priv->frequency) + { + /* Configure TWI output clocking, trying each value of CKDIV {0..7} */ + + for (ckdiv = 0; ckdiv < 8; ckdiv++) + { + /* Calculate the CLDIV value using the current CKDIV guess */ + + cldiv = ((priv->twiclk / (frequency << 1)) - 4) / (1 << ckdiv); + + /* Is CLDIV in range? */ + + if (cldiv <= 255) + { + /* Yes, break out and use it */ + + break; + } + } + + /* Then setup the TWI Clock Waveform Generator Register, using the same + * value for CLDIV and CHDIV (for 1:1 duty). + */ + + twi_putrel(priv, SAM_TWI_CWGR_OFFSET, 0); + + regval = ((uint32_t)ckdiv << TWI_CWGR_CKDIV_SHIFT) | + ((uint32_t)cldiv << TWI_CWGR_CHDIV_SHIFT) | + ((uint32_t)cldiv << TWI_CWGR_CLDIV_SHIFT); + twi_putrel(priv, SAM_TWI_CWGR_OFFSET, regval); + + /* Save the requested frequency */ + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: twi_hw_initialize + * + * Description: + * Initialize/Re-initialize the TWI peripheral. This logic performs only + * repeatable initialization after either (1) the one-time initialization, or + * (2) after each bus reset. + * + ****************************************************************************/ + +static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency) +{ + irqstate_t flags = enter_critical_section(); + uint32_t regval; + uint32_t mck; + + i2cvdbg("TWI%d Initializing\n", priv->attr->twi); + + /* Configure PIO pins */ + + sam_configpio(priv->attr->sclcfg); + sam_configpio(priv->attr->sdacfg); + + /* Enable peripheral clocking */ + + twi_enableclk(priv); + + /* SVEN: TWI Slave Mode Enabled */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SVEN); + + /* Reset the TWI */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SWRST); + (void)twi_getrel(priv, SAM_TWI_RHR_OFFSET); + + /* TWI Slave Mode Disabled, TWI Master Mode Disabled. */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_SVDIS); + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSDIS); + + /* Set master mode */ + + twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSEN); + + /* Determine the maximum valid frequency setting */ + + mck = BOARD_MCK_FREQUENCY; + +#ifdef SAMA5_HAVE_PMC_PCR_DIV + /* Select the optimal value for the PCR DIV field */ + + DEBUGASSERT((mck >> 3) <= TWI_MAX_FREQUENCY); + if (mck <= TWI_MAX_FREQUENCY) + { + priv->twiclk = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= TWI_MAX_FREQUENCY) + { + priv->twiclk = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= TWI_MAX_FREQUENCY) + { + priv->twiclk = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else /* if ((mck >> 3) <= TWI_MAX_FREQUENCY) */ + { + priv->twiclk = (mck >> 3); + regval = PMC_PCR_DIV8; + } + +#else + /* No DIV field in the PCR register */ + + priv->twiclk = mck; + regval = 0; + +#endif /* SAMA5_HAVE_PMC_PCR_DIV */ + + /* Set the TWI peripheral input clock to the maximum, valid frequency */ + + regval |= PMC_PCR_PID(priv->attr->pid) | PMC_PCR_CMD | PMC_PCR_EN; + twi_putabs(priv, SAM_PMC_PCR, regval); + + /* Set the initial TWI data transfer frequency */ + + twi_setfrequency(priv, frequency); + + /* Enable Interrupts */ + + up_enable_irq(priv->attr->irq); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize a TWI device for I2C operation + * + ****************************************************************************/ + +struct i2c_master_s *sam_i2cbus_initialize(int bus) +{ + struct twi_dev_s *priv; + uint32_t frequency; + irqstate_t flags; + int ret; + + i2cvdbg("Initializing TWI%d\n", bus); + +#ifdef CONFIG_SAMA5_TWI0 + if (bus == 0) + { + /* Select up TWI0 and setup invariant attributes */ + + priv = &g_twi0; + priv->attr = &g_twi0attr; + + /* Select the (initial) TWI frequency */ + + frequency = CONFIG_SAMA5_TWI0_FREQUENCY; + } + else +#endif +#ifdef CONFIG_SAMA5_TWI1 + if (bus == 1) + { + /* Select up TWI1 and setup invariant attributes */ + + priv = &g_twi1; + priv->attr = &g_twi1attr; + + /* Select the (initial) TWI frequency */ + + frequency = CONFIG_SAMA5_TWI1_FREQUENCY; + } + else +#endif +#ifdef CONFIG_SAMA5_TWI2 + if (bus == 2) + { + /* Select up TWI2 and setup invariant attributes */ + + priv = &g_twi2; + priv->attr = &g_twi2attr; + + /* Select the (initial) TWI frequency */ + + frequency = CONFIG_SAMA5_TWI2_FREQUENCY; + } + else +#endif +#ifdef CONFIG_SAMA5_TWI3 + if (bus == 3) + { + /* Select up TWI3 and setup invariant attributes */ + + priv = &g_twi3; + priv->attr = &g_twi3attr; + + /* Select the (initial) TWI frequency */ + + frequency = CONFIG_SAMA5_TWI3_FREQUENCY; + } + else +#endif + { + i2cdbg("ERROR: Unsupported bus: TWI%d\n", bus); + return NULL; + } + + /* Perform one-time TWI initialization */ + + flags = enter_critical_section(); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + if (priv->timeout == NULL) + { + idbg("ERROR: Failed to allocate a timer\n"); + goto errout_with_irq; + } + + /* Attach Interrupt Handler */ + + ret = irq_attach(priv->attr->irq, priv->attr->handler); + if (ret < 0) + { + idbg("ERROR: Failed to attach irq %d\n", priv->attr->irq); + goto errout_with_wdog; + } + + /* Initialize the TWI driver structure */ + + priv->dev.ops = &g_twiops; + + (void)sem_init(&priv->exclsem, 0, 1); + (void)sem_init(&priv->waitsem, 0, 0); + + /* Perform repeatable TWI hardware initialization */ + + twi_hw_initialize(priv, frequency); + leave_critical_section(flags); + return &priv->dev; + +errout_with_wdog: + wd_delete(priv->timeout); + priv->timeout = NULL; + +errout_with_irq: + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C device + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + struct twi_dev_s *priv = (struct twi_dev_s *) dev; + + i2cvdbg("TWI%d Un-initializing\n", priv->attr->twi); + + /* Disable TWI interrupts */ + + up_disable_irq(priv->attr->irq); + + /* Reset data structures */ + + sem_destroy(&priv->exclsem); + sem_destroy(&priv->waitsem); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Detach Interrupt Handler */ + + (void)irq_detach(priv->attr->irq); + return OK; +} + +#endif /* CONFIG_SAMA5_TWI0 || ... || CONFIG_SAMA5_TWI3 */ diff --git a/arch/arm/src/sama5/sam_twi.h b/arch/arm/src/sama5/sam_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..e8d75e133540ecfd66e90cda005cf6bff16832d9 --- /dev/null +++ b/arch/arm/src/sama5/sam_twi.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_twi.h + * + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_TWI_H +#define __ARCH_ARM_SRC_SAMA5_SAM_TWI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip/sam_twi.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *sam_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the sam_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TWI_H */ diff --git a/arch/arm/src/sama5/sam_udphs.c b/arch/arm/src/sama5/sam_udphs.c new file mode 100644 index 0000000000000000000000000000000000000000..06c2cf2fed41d8f79cf8df99275d26d87b62238e --- /dev/null +++ b/arch/arm/src/sama5/sam_udphs.c @@ -0,0 +1,4634 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_udphs.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2009, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "chip/sam_udphs.h" +#include "sam_udphs.h" + +#if defined(CONFIG_USBDEV) && defined(CONFIG_SAMA5_UDPHS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +/* Number of DMA transfer descriptors. Default: 8 */ + +#ifndef CONFIG_SAMA5_UDPHS_NDTDS +# define CONFIG_SAMA5_UDPHS_NDTDS 8 +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMA5_UDPHS_REGDEBUG +#endif + +/* Not yet supported */ + +#undef CONFIG_SAMA5_UDPHS_SCATTERGATHER + +/* Driver Definitions *******************************************************/ +/* Initial interrupt mask: Reset + Suspend + Correct Transfer */ + +#define SAM_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_CTRM) + +/* Endpoint definitions */ + +#define EP0 (0) +#define SAM_EPSET_ALL (0xffff) /* All endpoints */ +#define SAM_EPSET_NOTEP0 (0xfffe) /* All endpoints except EP0 */ +#define SAM_EPSET_DMA (0x00fe) /* All endpoints that support DMA transfers */ +#define SAM_EP_BIT(ep) (1 << (ep)) +#define SAM_EP0_MAXPACKET (64) /* EP0 Max. packet size */ + +/* DMA FIFO */ + +#define DMA_MAX_FIFO_SIZE (65536/1) /* Max size of the FMA FIFO */ +#define EPT_VIRTUAL_SIZE 16384 /* FIFO space size in units of 32-bit words */ + +/* USB-related masks */ + +#define REQRECIPIENT_MASK (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK) + +/* Endpoint register masks (handling toggle fields) */ + +#define EPR_NOTOG_MASK (USB_EPR_CTR_RX | USB_EPR_SETUP | USB_EPR_EPTYPE_MASK |\ + USB_EPR_EP_KIND | USB_EPR_CTR_TX | USB_EPR_EA_MASK) +#define EPR_TXDTOG_MASK (USB_EPR_STATTX_MASK | EPR_NOTOG_MASK) +#define EPR_RXDTOG_MASK (USB_EPR_STATRX_MASK | EPR_NOTOG_MASK) + +/* Request queue operations *************************************************/ + +#define sam_rqempty(q) ((q)->head == NULL) +#define sam_rqpeek(q) ((q)->head) + +/* USB trace ****************************************************************/ +/* Trace error codes */ + +#define SAM_TRACEERR_ALLOCFAIL 0x0001 +#define SAM_TRACEERR_BADCLEARFEATURE 0x0002 +#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003 +#define SAM_TRACEERR_BADEPGETSTATUS 0x0004 +#define SAM_TRACEERR_BADEOBSTATE 0x0005 +#define SAM_TRACEERR_BADEPNO 0x0006 +#define SAM_TRACEERR_BADEPTYPE 0x0007 +#define SAM_TRACEERR_BADGETCONFIG 0x0008 +#define SAM_TRACEERR_BADGETSETDESC 0x0009 +#define SAM_TRACEERR_BADGETSTATUS 0x000a +#define SAM_TRACEERR_BADSETADDRESS 0x000b +#define SAM_TRACEERR_BADSETCONFIG 0x000c +#define SAM_TRACEERR_BADSETFEATURE 0x000d +#define SAM_TRACEERR_BINDFAILED 0x000e +#define SAM_TRACEERR_DISPATCHSTALL 0x000f +#define SAM_TRACEERR_DMAERR 0x0010 +#define SAM_TRACEERR_DRIVER 0x0011 +#define SAM_TRACEERR_DRIVERREGISTERED 0x0012 +#define SAM_TRACEERR_ENDBUFST 0x0013 +#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0014 +#define SAM_TRACEERR_EP0SETUPSTALLED 0x0015 +#define SAM_TRACEERR_EPOUTNULLPACKET 0x0016 +#define SAM_TRACEERR_EPRESERVE 0x0017 +#define SAM_TRACEERR_EPTCFGMAPD 0x0018 +#define SAM_TRACEERR_INVALIDCTRLREQ 0x0019 +#define SAM_TRACEERR_INVALIDPARMS 0x001a +#define SAM_TRACEERR_IRQREGISTRATION 0x001b +#define SAM_TRACEERR_NOTCONFIGURED 0x001c +#define SAM_TRACEERR_REQABORTED 0x001d +#define SAM_TRACEERR_TXRDYERR 0x001e + +/* Trace interrupt codes */ + +#define SAM_TRACEINTID_ADDRESSED 0x0001 +#define SAM_TRACEINTID_CLEARFEATURE 0x0002 +#define SAM_TRACEINTID_DETSUSPD 0x0003 +#define SAM_TRACEINTID_DEVGETSTATUS 0x0004 +#define SAM_TRACEINTID_DISPATCH 0x0005 +#define SAM_TRACEINTID_DMA 0x0006 +#define SAM_TRACEINTID_DMAEOB 0x0007 +#define SAM_TRACEINTID_DMAEOC 0x0008 +#define SAM_TRACEINTID_ENDRESET 0x0009 +#define SAM_TRACEINTID_EP 0x0001 +#define SAM_TRACEINTID_EP0SETUPIN 0x000b +#define SAM_TRACEINTID_EP0SETUPOUT 0x000c +#define SAM_TRACEINTID_EP0SETUPSETADDRESS 0x000d +#define SAM_TRACEINTID_EPGETSTATUS 0x000e +#define SAM_TRACEINTID_EPINQEMPTY 0x000f +#define SAM_TRACEINTID_EPOUTQEMPTY 0x0010 +#define SAM_TRACEINTID_GETCONFIG 0x0011 +#define SAM_TRACEINTID_GETSETDESC 0x0012 +#define SAM_TRACEINTID_GETSETIF 0x0013 +#define SAM_TRACEINTID_GETSTATUS 0x0014 +#define SAM_TRACEINTID_IFGETSTATUS 0x0015 +#define SAM_TRACEINTID_INTERRUPT 0x0016 +#define SAM_TRACEINTID_INTSOF 0x0017 +#define SAM_TRACEINTID_NOSTDREQ 0x0018 +#define SAM_TRACEINTID_PENDING 0x0019 +#define SAM_TRACEINTID_RXRDY 0x001a +#define SAM_TRACEINTID_RXSETUP 0x001b +#define SAM_TRACEINTID_SETCONFIG 0x001c +#define SAM_TRACEINTID_SETFEATURE 0x001d +#define SAM_TRACEINTID_STALLSNT 0x001e +#define SAM_TRACEINTID_SYNCHFRAME 0x001f +#define SAM_TRACEINTID_TXRDY 0x0020 +#define SAM_TRACEINTID_UPSTRRES 0x0021 +#define SAM_TRACEINTID_WAKEUP 0x0022 + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/* Byte ordering in host-based values */ + +#ifdef CONFIG_ENDIAN_BIG +# define LSB 1 +# define MSB 0 +#else +# define LSB 0 +# define MSB 1 +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ +/* State of an endpoint */ + +enum sam_epstate_e +{ + /* --- All Endpoints --- */ + UDPHS_EPSTATE_DISABLED = 0, /* Endpoint is disabled */ + UDPHS_EPSTATE_STALLED, /* Endpoint is stalled */ + UDPHS_EPSTATE_IDLE, /* Endpoint is idle (i.e. ready for transmission) */ + UDPHS_EPSTATE_SENDING, /* Endpoint is sending data */ + UDPHS_EPSTATE_RECEIVING, /* Endpoint is receiving data */ + /* --- Endpoint 0 Only --- */ + UDPHS_EPSTATE_EP0DATAOUT, /* Endpoint 0 is receiving SETUP OUT data */ + UDPHS_EPSTATE_EP0STATUSIN, /* Endpoint 0 is sending SETUP status */ + UDPHS_EPSTATE_EP0ADDRESS /* Address change is pending completion of status */ +}; + +/* The overall state of the device */ + +enum sam_devstate_e +{ + UDPHS_DEVSTATE_SUSPENDED = 0, /* The device is currently suspended */ + UDPHS_DEVSTATE_POWERED, /* Host is providing +5V through the USB cable */ + UDPHS_DEVSTATE_DEFAULT, /* Device has been reset */ + UDPHS_DEVSTATE_ADDRESSED, /* The device has been given an address on the bus */ + UDPHS_DEVSTATE_CONFIGURED /* A valid configuration has been selected. */ +}; + +/* The result of EP0 SETUP processing */ + +enum sam_ep0setup_e +{ + UDPHS_EP0SETUP_SUCCESS = 0, /* The SETUP was handle without incident */ + UDPHS_EP0SETUP_DISPATCHED, /* The SETUP was forwarded to the class driver */ + UDPHS_EP0SETUP_ADDRESS, /* A new device address is pending */ + UDPHS_EP0SETUP_STALL /* An error occurred */ +}; + +/* DMA transfer descriptor */ + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +struct sam_dtd_s +{ + struct udphs_dtd_s hw; /* These are the fields as seen by the hardware */ + uint32_t pad; /* Pad to 16 bytes to support arrays of descriptors */ +}; +#define SIZEOF_SAM_DTD_S 16 +#endif + +/* The following is used to manage lists of free DMA transfer descriptors */ + +struct sam_list_s +{ + struct sam_list_s *flink; /* Link to next entry in the list */ + /* Variable length entry data follows */ +}; + +union wb_u +{ + uint16_t w; + uint8_t b[2]; +}; + +/* A container for a request so that the request make be retained in a list */ + +struct sam_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct sam_req_s *flink; /* Supports a singly linked list */ + uint16_t inflight; /* Number of TX bytes written to FIFO */ +}; + +/* The head of a queue of requests */ + +struct sam_rqhead_s +{ + struct sam_req_s *head; /* Requests are added to the head of the list */ + struct sam_req_s *tail; /* Requests are removed from the tail of the list */ +}; + +/* This is the internal representation of an endpoint */ + +struct sam_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct sam_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* SAMA5-specific fields */ + + struct sam_usbdev_s *dev; /* Reference to private driver data */ + struct sam_rqhead_s reqq; /* Read/write request queue */ +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER + struct sam_dtd_s *dtdll; /* Head of the DMA transfer descriptor list */ +#endif + volatile uint8_t epstate; /* State of the endpoint (see enum sam_epstate_e) */ + volatile uint8_t bank; /* Current reception bank (0 or 1) */ + uint8_t stalled:1; /* true: Endpoint is stalled */ + uint8_t halted:1; /* true: Endpoint feature halted */ + uint8_t zlpneeded:1; /* Zero length packet needed at end of transfer */ + uint8_t zlpsent:1; /* Zero length packet has been sent */ +}; + +struct sam_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structsam_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* UDPHS-specific fields */ + + struct usb_ctrlreq_s ctrl; /* Last EP0 request */ + uint8_t devstate; /* State of the device (see enum sam_devstate_e) */ + uint8_t prevstate; /* Previous state of the device before SUSPEND */ + uint8_t devaddr; /* Assigned device address */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint16_t epavail; /* Bitset of available endpoints */ + + /* DMA Transfer descriptors */ + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER + struct sam_dtd_s *tdfree; /* A list of free transfer descriptors */ +#ifndef CONFIG_SAMA5_UDPHS_PREALLOCATE + struct sam_dtd_s *tdpool; /* Pool of allocated DMA transfer descriptors */ +#endif +#endif + + /* The endpoint list */ + + struct sam_ep_s eplist[SAM_UDPHS_NENDPOINTS]; + + /* EP0 data buffer. For data that is included in an EP0 SETUP OUT + * transaction. In this case, no request is in place from the class + * driver and the incoming data is caught in this buffer. The size + * of valid dat in the buffer is given by ctrlreg.len[]. For the + * case of EP0 SETUP IN transaction, the normal request mechanism is + * used and the class driver provides the buffering. + */ + + uint8_t ep0out[SAM_EP0_MAXPACKET]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +static void sam_dumpep(struct sam_usbdev_s *priv, int epno); +#else +static inline uint32_t sam_getreg(uintptr_t regaddr); +static inline void sam_putreg(uint32_t regval, uintptr_t regaddr); +# define sam_dumpep(priv,epno) +#endif + +/* Suspend/Resume Helpers ***************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv); +static void sam_resume(struct sam_usbdev_s *priv); + +/* DMA Transfer Helpers *****************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +static struct sam_dtd_s *sam_dtd_alloc(struct sam_usbdev_s *priv); +static void sam_dtd_free(struct sam_usbdev_s *priv, struct sam_dtd_s *dtd); +#endif +static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq, + uint32_t dmacontrol); +static void sam_dma_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); +static void sam_dma_rdsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); + +/* Request Helpers **********************************************************/ + +static struct sam_req_s * + sam_req_dequeue(struct sam_rqhead_s *queue); +static void sam_req_enqueue(struct sam_rqhead_s *queue, + struct sam_req_s *req); +static inline void + sam_req_abort(struct sam_ep_s *privep, + struct sam_req_s *privreq, int16_t result); +static void sam_req_complete(struct sam_ep_s *privep, int16_t result); +static void sam_ep_txrdy(unsigned int epno); +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); +static int sam_req_write(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static void sam_req_rddone(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq, + uint16_t recvsize); +static void sam_req_rdenable(uint8_t epno); +static void sam_req_rddisable(uint8_t epno); +static int sam_req_read(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, uint16_t recvsize); +static void sam_req_cancel(struct sam_ep_s *privep, int16_t status); + +/* Interrupt level processing ***********************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen); +static void sam_ep0_wrstatus(const uint8_t *buffer, size_t buflen); +static void sam_ep0_dispatch(struct sam_usbdev_s *priv); +static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t value); +static void sam_ep0_setup(struct sam_usbdev_s *priv); +static void sam_dma_interrupt(struct sam_usbdev_s *priv, int chan); +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno); +static int sam_udphs_interrupt(int irq, void *context); + +/* Endpoint helpers *********************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno); +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset); +static inline struct sam_ep_s * + sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset); +static inline void + sam_ep_unreserve(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static inline bool + sam_ep_reserved(struct sam_usbdev_s *priv, int epno); +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc); + +/* Endpoint operations ******************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int sam_ep_disable(struct usbdev_ep_s *ep); +static struct usbdev_req_s * + sam_ep_allocreq(struct usbdev_ep_s *ep); +static void sam_ep_freereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes); +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf); +#endif +static int sam_ep_submit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_cancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations *****************************************/ + +static struct usbdev_ep_s * + sam_allocep(struct usbdev_s *dev, uint8_t epno, bool in, + uint8_t eptype); +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep); +static int sam_getframe(struct usbdev_s *dev); +static int sam_wakeup(struct usbdev_s *dev); +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int sam_pullup(FAR struct usbdev_s *dev, bool enable); + +/* Initialization/Reset *****************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv); +static void sam_hw_setup(struct sam_usbdev_s *priv); +static void sam_sw_setup(struct sam_usbdev_s *priv); +static void sam_hw_shutdown(struct sam_usbdev_s *priv); +static void sam_sw_shutdown(struct sam_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct sam_usbdev_s g_udphs; + +static const struct usbdev_epops_s g_epops = +{ + .configure = sam_ep_configure, + .disable = sam_ep_disable, + .allocreq = sam_ep_allocreq, + .freereq = sam_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = sam_ep_allocbuffer, + .freebuffer = sam_ep_freebuffer, +#endif + .submit = sam_ep_submit, + .cancel = sam_ep_cancel, + .stall = sam_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = sam_allocep, + .freeep = sam_freeep, + .getframe = sam_getframe, + .wakeup = sam_wakeup, + .selfpowered = sam_selfpowered, + .pullup = sam_pullup, +}; + +/* This describes endpoint 0 */ + +static const struct usb_epdesc_s g_ep0desc = +{ + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = EP0, + .attr = USB_EP_ATTR_XFER_CONTROL, + .mxpacketsize = {64, 0}, + .interval = 0 +}; + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +#ifdef CONFIG_SAMA5_UDPHS_PREALLOCATE +/* This is a properly aligned pool of preallocated DMA transfer descriptors */ + +static struct sam_dtd_s g_dtdpool[CONFIG_SAMA5_UDPHS_NDTDS] + __attribute__ ((aligned(16))); +#endif +#endif + + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(SAM_TRACEERR_ALLOCFAIL), + TRACE_STR(SAM_TRACEERR_BADCLEARFEATURE), + TRACE_STR(SAM_TRACEERR_BADDEVGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEOBSTATE), + TRACE_STR(SAM_TRACEERR_BADEPNO), + TRACE_STR(SAM_TRACEERR_BADEPTYPE), + TRACE_STR(SAM_TRACEERR_BADGETCONFIG), + TRACE_STR(SAM_TRACEERR_BADGETSETDESC), + TRACE_STR(SAM_TRACEERR_BADGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADSETADDRESS), + TRACE_STR(SAM_TRACEERR_BADSETCONFIG), + TRACE_STR(SAM_TRACEERR_BADSETFEATURE), + TRACE_STR(SAM_TRACEERR_BINDFAILED), + TRACE_STR(SAM_TRACEERR_DISPATCHSTALL), + TRACE_STR(SAM_TRACEERR_DMAERR), + TRACE_STR(SAM_TRACEERR_DRIVER), + TRACE_STR(SAM_TRACEERR_DRIVERREGISTERED), + TRACE_STR(SAM_TRACEERR_ENDBUFST), + TRACE_STR(SAM_TRACEERR_EP0SETUPOUTSIZE), + TRACE_STR(SAM_TRACEERR_EP0SETUPSTALLED), + TRACE_STR(SAM_TRACEERR_EPOUTNULLPACKET), + TRACE_STR(SAM_TRACEERR_EPRESERVE), + TRACE_STR(SAM_TRACEERR_EPTCFGMAPD), + TRACE_STR(SAM_TRACEERR_INVALIDCTRLREQ), + TRACE_STR(SAM_TRACEERR_INVALIDPARMS), + TRACE_STR(SAM_TRACEERR_IRQREGISTRATION), + TRACE_STR(SAM_TRACEERR_NOTCONFIGURED), + TRACE_STR(SAM_TRACEERR_REQABORTED), + TRACE_STR(SAM_TRACEERR_TXRDYERR), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(SAM_TRACEINTID_ADDRESSED), + TRACE_STR(SAM_TRACEINTID_CLEARFEATURE), + TRACE_STR(SAM_TRACEINTID_DETSUSPD), + TRACE_STR(SAM_TRACEINTID_DEVGETSTATUS), + TRACE_STR(SAM_TRACEINTID_DISPATCH), + TRACE_STR(SAM_TRACEINTID_DMA), + TRACE_STR(SAM_TRACEINTID_DMAEOB), + TRACE_STR(SAM_TRACEINTID_DMAEOC), + TRACE_STR(SAM_TRACEINTID_ENDRESET), + TRACE_STR(SAM_TRACEINTID_EP), + TRACE_STR(SAM_TRACEINTID_EP0SETUPIN), + TRACE_STR(SAM_TRACEINTID_EP0SETUPOUT), + TRACE_STR(SAM_TRACEINTID_EP0SETUPSETADDRESS), + TRACE_STR(SAM_TRACEINTID_EPGETSTATUS), + TRACE_STR(SAM_TRACEINTID_EPINQEMPTY), + TRACE_STR(SAM_TRACEINTID_EPOUTQEMPTY), + TRACE_STR(SAM_TRACEINTID_GETCONFIG), + TRACE_STR(SAM_TRACEINTID_GETSETDESC), + TRACE_STR(SAM_TRACEINTID_GETSETIF), + TRACE_STR(SAM_TRACEINTID_GETSTATUS), + TRACE_STR(SAM_TRACEINTID_IFGETSTATUS), + TRACE_STR(SAM_TRACEINTID_INTERRUPT), + TRACE_STR(SAM_TRACEINTID_INTSOF), + TRACE_STR(SAM_TRACEINTID_NOSTDREQ), + TRACE_STR(SAM_TRACEINTID_PENDING), + TRACE_STR(SAM_TRACEINTID_RXRDY), + TRACE_STR(SAM_TRACEINTID_RXSETUP), + TRACE_STR(SAM_TRACEINTID_SETCONFIG), + TRACE_STR(SAM_TRACEINTID_SETFEATURE), + TRACE_STR(SAM_TRACEINTID_STALLSNT), + TRACE_STR(SAM_TRACEINTID_SYNCHFRAME), + TRACE_STR(SAM_TRACEINTID_TXRDY), + TRACE_STR(SAM_TRACEINTID_UPSTRRES), + TRACE_STR(SAM_TRACEINTID_WAKEUP), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_printreg + * + * Description: + * Print the contents of a SAMA5 UDPHS register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + lldbg("%p%s%08x\n", regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a SAMA5 + * UDPHS register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + static uintptr_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + sam_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + sam_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMA5 register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG +static uint32_t sam_getreg(uintptr_t regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t sam_getreg(uintptr_t regaddr) +{ + return getreg32(regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMA5 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, true); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#else +static inline void sam_putreg(uint32_t regval, uint32_t regaddr) +{ + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_dumpep + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_UDPHS_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_dumpep(struct sam_usbdev_s *priv, int epno) +{ + /* Global Registers */ + + lldbg("Global Register:\n"); + lldbg(" CTRL: %04x\n", sam_getreg(SAM_UDPHS_CTRL)); + lldbg(" FNUM: %04x\n", sam_getreg(SAM_UDPHS_FNUM)); + lldbg(" IEN: %04x\n", sam_getreg(SAM_UDPHS_IEN)); + lldbg(" INSTA: %04x\n", sam_getreg(SAM_UDPHS_INTSTA)); + lldbg(" TST: %04x\n", sam_getreg(SAM_UDPHS_TST)); + + /* Endpoint registers */ + + lldbg("Endpoint %d Register:\n", epno); + lldbg(" CFG: %04x\n", sam_getreg(SAM_UDPHS_EPTCFG(epno))); + lldbg(" CTL: %04x\n", sam_getreg(SAM_UDPHS_EPTCTL(epno))); + lldbg(" STA: %04x\n", sam_getreg(SAM_UDPHS_EPTSTA(epno))); + + lldbg("DMA %d Register:\n", epno); + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + lldbg(" NXTDSC: %04x\n", sam_getreg(SAM_UDPHS_DMANXTDSC(epno))); + lldbg(" ADDRESS: %04x\n", sam_getreg(SAM_UDPHS_DMAADDRESS(epno))); + lldbg(" CONTROL: %04x\n", sam_getreg(SAM_UDPHS_DMACONTROL(epno))); + lldbg(" STATUS: %04x\n", sam_getreg(SAM_UDPHS_DMASTATUS(epno))); + } + else + { + lldbg(" None\n"); + } +} +#endif + +/**************************************************************************** + * DMA + ****************************************************************************/ +/**************************************************************************** + * Name: sam_dtd_alloc + * + * Description: + * Allocate a DMA transfer descriptor by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +static struct sam_dtd_s *sam_dtd_alloc(struct sam_usbdev_s *priv) +{ + struct sam_dtd_s *dtd; + + /* Remove the DMA transfer descriptor from the freelist */ + + dtd = (struct sam_dtd_s *)g_udphs.dtdfree; + if (dtd) + { + g_udphs.dtdfree = ((struct sam_list_s *)dtd)->flink; + memset(dtd, 0, sizeof(struct sam_dtd_s)); + } + + return dtd; +} +#endif + +/**************************************************************************** + * Name: sam_dtd_free + * + * Description: + * Free a DMA transfer descriptor by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +static void sam_dtd_free(struct sam_usbdev_s *priv, struct sam_dtd_s *dtd) +{ + struct sam_list_s *entry = (struct sam_list_s *)dtd; + + /* Put the dtd structure back into the free list */ + + entry->flink = g_udphs.dtdfree; + g_udphs.dtdfree = entry; +} +#endif + +/**************************************************************************** + * Name: sam_dma_single + * + * Description: + * Setup a start a single buffer DMA. + * + * Assumption: Called as part of UDPHS interrupt handling + * + ****************************************************************************/ + +static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq, + uint32_t dmacontrol) +{ + uintptr_t buffer; + uintptr_t physaddr; + uint32_t regval; + + /* Not all endpoints support DMA */ + + DEBUGASSERT((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0); + + /* Flush the contents of the DMA buffer to RAM */ + + buffer = (uintptr_t)&privreq->req.buf[privreq->req.xfrd]; + arch_clean_dcache(buffer, buffer + privreq->inflight); + + /* Set up the DMA */ + + physaddr = sam_physramaddr(buffer); + sam_putreg(physaddr, SAM_UDPHS_DMAADDRESS(epno)); + + /* Clear any pending interrupts then enable the DMA interrupt */ + + (void)sam_getreg(SAM_UDPHS_DMASTATUS(epno)); + regval = sam_getreg(SAM_UDPHS_IEN); + regval |= UDPHS_INT_DMA(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + + /* Setup and enable the DMA */ + + sam_putreg(0, SAM_UDPHS_DMACONTROL(epno)); + + dmacontrol |= UDPHS_DMACONTROL_BUFLEN(privreq->inflight); + sam_putreg(dmacontrol, SAM_UDPHS_DMACONTROL(epno)); +} + +/**************************************************************************** + * Name: sam_dma_wrsetup + * + * Description: + * Process the next queued write request for an endpoint that supports DMA. + * + ****************************************************************************/ + +static void sam_dma_wrsetup(struct sam_usbdev_s *priv, struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + uint32_t regval; + int remaining; + int epno; + + /* Switch to the sending state */ + + privep->epstate = UDPHS_EPSTATE_SENDING; + privreq->inflight = 0; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* How many bytes remain to be transferred in the request? */ + + remaining = (int)privreq->req.len - (int)privreq->req.xfrd; + DEBUGASSERT(remaining >= 0 && remaining <= (int)privreq->req.len); + + /* If there are no bytes to send, then send a zero length packet */ + + if (remaining > 0) + { + /* Clip the transfer to the size of the DMA FIFO */ + +#if USBDEV_MAXREQUEUST > DMA_MAX_FIFO_SIZE + if (remaining > DMA_MAX_FIFO_SIZE) + { + privreq->inflight = DMA_MAX_FIFO_SIZE; + privep->zlpneeded = false; + } + else +#endif + { + privreq->inflight = remaining; + + /* If the size is an exact multple of full packets, then note if + * we need to send a zero length packet next. + */ + + privep->zlpneeded = + ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0 && + (remaining % privep->ep.maxpacket) == 0); + } + + /* And perform the single DMA transfer. + * + * 32.6.10.6 Bulk IN or Interrupt IN: Sending a Buffer Using DMA + * - END_B_EN: The endpoint can validate the packet (according to the + * values programmed in the AUTO_VALID and SHRT_PCKT fields of + * UDPHS_EPTCTLx.) ... + * - END_BUFFIT: generate an interrupt when the BUFF_COUNT in + * UDPHS_DMASTATUSx reaches 0. + * - CHANN_ENB: Run and stop at end of buffer + */ + + sam_dma_single(epno, privreq, + UDPHS_DMACONTROL_ENDBEN | UDPHS_DMACONTROL_ENDBUFFIT | + UDPHS_DMACONTROL_CHANNENB); + } + + /* Enable the endpoint interrupt */ + + regval = sam_getreg(SAM_UDPHS_IEN); + regval |= UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); +} + +/**************************************************************************** + * Name: sam_dma_rdsetup + * + * Description: + * Process the next queued read request for an endpoint that supports DMA. + * + ****************************************************************************/ + +static void sam_dma_rdsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + uint32_t regval; + int remaining; + int epno; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* How many more bytes can we append to the request buffer? */ + + remaining = (int)privreq->req.len - (int)privreq->req.xfrd; + DEBUGASSERT(remaining > 0 && remaining <= (int)privreq->req.len && + privep->epstate == UDPHS_EPSTATE_RECEIVING); + + /* Clip the DMA transfer size to the size available in the user buffer */ + +#if USBDEV_MAXREQUEUST > DMA_MAX_FIFO_SIZE + if (remaining > DMA_MAX_FIFO_SIZE) + { + privreq->inflight = DMA_MAX_FIFO_SIZE; + } + else +#endif + { + privreq->inflight = remaining; + } + + /* And perform the single DMA transfer. + * + * 32.6.10.12 Bulk OUT or Interrupt OUT: Sending a Buffer Using DMA + * - END_B_EN: Can be used for OUT packet truncation (discarding of + * unbuffered packet data) at the end of DMA buffer. + * - END_BUFFIT: Generate an interrupt when BUFF_COUNT in the + * UDPHS_DMASTATUSx register reaches 0. + * - END_TR_EN: End of transfer enable, the UDPHS device can put an + * end to the current DMA transfer, in case of a short packet. + * - END_TR_IT: End of transfer interrupt enable, an interrupt is sent + * after the last USB packet has been transferred by the DMA, if the + * USB transfer ended with a short packet. (Beneficial when the + * receive size is unknown.) + * - CHANN_ENB: Run and stop at end of buffer. + */ + + regval = UDPHS_DMACONTROL_ENDBEN | UDPHS_DMACONTROL_ENDBUFFIT | + UDPHS_DMACONTROL_ENDTREN | UDPHS_DMACONTROL_ENDTRIT | + UDPHS_DMACONTROL_CHANNENB; + + sam_dma_single(epno, privreq, regval); +} + +/**************************************************************************** + * Request Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_req_dequeue + ****************************************************************************/ + +static struct sam_req_s *sam_req_dequeue(struct sam_rqhead_s *queue) +{ + struct sam_req_s *ret = queue->head; + + if (ret) + { + queue->head = ret->flink; + if (!queue->head) + { + queue->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_req_enqueue + ****************************************************************************/ + +static void sam_req_enqueue(struct sam_rqhead_s *queue, struct sam_req_s *req) +{ + req->flink = NULL; + if (!queue->head) + { + queue->head = req; + queue->tail = req; + } + else + { + queue->tail->flink = req; + queue->tail = req; + } +} + +/**************************************************************************** + * Name: sam_req_abort + ****************************************************************************/ + +static inline void +sam_req_abort(struct sam_ep_s *privep, struct sam_req_s *privreq, int16_t result) +{ + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_REQABORTED), + (uint16_t)USB_EPNO(privep->ep.eplog)); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: sam_req_complete + ****************************************************************************/ + +static void sam_req_complete(struct sam_ep_s *privep, int16_t result) +{ + struct sam_req_s *privreq; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = sam_req_dequeue(&privep->reqq); + leave_critical_section(flags); + + if (privreq) + { + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Reset the endpoint state and restore the stalled indication */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + privep->zlpneeded = false; + privep->zlpsent = false; + } +} + +/**************************************************************************** + * Name: sam_ep_txrdy + * + * Description: + * IN data has been loaded in the endpoint FIFO. Manage the endpoint to + * (1) initiate sending of the data and (2) receive the TXRDY interrupt + * when the transfer completes. + * + ****************************************************************************/ + +static void sam_ep_txrdy(unsigned int epno) +{ + /* Set TXRDY to indicate that the packet is ready to send (this works even + * for zero length packets). We will get an TXCOMP interrupt with TXRDY + * cleared. Then we are able to send the next packet. + */ + + sam_putreg(UDPHS_EPTSETSTA_TXRDY, SAM_UDPHS_EPTSETSTA(epno)); + + /* Clear the NAK IN bit to stop NAKing IN tokens from the host. We now + * have data ready to go. + */ + + sam_putreg(UDPHS_EPTSTA_NAKIN, SAM_UDPHS_EPTCLRSTA(epno)); + + /* Enable the TXRDY interrupt on the endpoint */ + + sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLENB(epno)); +} + +/**************************************************************************** + * Name: sam_req_wrsetup + * + * Description: + * Process the next queued write request for an endpoint that does not + * support DMA. + * + ****************************************************************************/ + +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + const uint8_t *buf; + uint8_t *fifo; + uint8_t epno; + int nbytes; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Write access to the FIFO is not possible if TXDRY is set */ + + DEBUGASSERT((sam_getreg(SAM_UDPHS_EPTSTA(epno)) & UDPHS_EPTSTA_TXRDY) == 0); + + /* Get the number of bytes remaining to be sent. */ + + DEBUGASSERT(privreq->req.xfrd < privreq->req.len); + nbytes = privreq->req.len - privreq->req.xfrd; + + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + privep->zlpneeded = false; + if (nbytes > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + else if (nbytes == privep->ep.maxpacket) + { + /* If the size is exactly a full packet, then note if we need to + * send a zero length packet next. + */ + + privep->zlpneeded = + ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + } + + /* This is the new number of bytes "in-flight" */ + + privreq->inflight = nbytes; + usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes); + + /* The new buffer pointer is the started of the buffer plus the number + * of bytes successfully transfered plus the number of bytes previously + * "in-flight". + */ + + buf = privreq->req.buf + privreq->req.xfrd; + + /* Write packet in the FIFO buffer */ + + fifo = (uint8_t *) + ((uint32_t *)SAM_UDPHSRAM_VSECTION + (EPT_VIRTUAL_SIZE * epno)); + + for (; nbytes; nbytes--) + { + *fifo++ = *buf++; + } + + /* Indicate that there is data in the TX packet memory. This will + * be cleared when the next data out interrupt is received. + */ + + privep->epstate = UDPHS_EPSTATE_SENDING; + + /* Initiate the transfer and configure to receive the transfer complete + * interrupt. + */ + + sam_ep_txrdy(epno); +} + +/**************************************************************************** + * Name: sam_req_write + * + * Description: + * Process the next queued write request. This function is called in one + * of three contexts: (1) When the endpoint is IDLE and a new write request + * is submitted (with interrupts disabled), (2) from interrupt handling + * when the current transfer completes (either DMA or FIFO), or (3) when + * resuming a stalled IN or control endpoint. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is the number of bytes + * to transfer and 'xfrd' and 'inflight' must be zero. + * + * When this function starts a transfer it will update the request + * 'inflight' field to indicate the size of the transfer. + * + * When the transfer completes, the the 'inflight' field must hold the + * number of bytes that have completed the transfer. This function will + * update 'xfrd' with the new size of the transfer. + * + ****************************************************************************/ + +static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + struct sam_req_s *privreq; + uint32_t regval; + uint32_t eptype; + uint8_t epno; + int bytesleft; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* We get here when an IN endpoint interrupt occurs. So now we know that + * there is no TX transfer in progress. + */ + + while (privep->epstate == UDPHS_EPSTATE_IDLE) + { + /* Check the request from the head of the endpoint request queue */ + + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* There is no TX transfer in progress and no new pending TX + * requests to send. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPINQEMPTY), 0); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_UDPHS_EPTCFG(epno)); + eptype = regval & UDPHS_EPTCFG_TYPE_MASK; + + /* Disable interrupts on non-control endpoints */ + + if (eptype != UDPHS_EPTCFG_TYPE_CTRL8) + { + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + } + + /* Disable the TXRDY interrupt */ + + sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLDIS(epno)); + return -ENOENT; + } + + ullvdbg("epno=%d req=%p: len=%d xfrd=%d inflight=%d zlpneeded=%d\n", + epno, privreq, privreq->req.len, privreq->req.xfrd, + privreq->inflight, privep->zlpneeded); + + /* Handle any bytes in flight. */ + + privreq->req.xfrd += privreq->inflight; + privreq->inflight = 0; + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + if (bytesleft > 0) + { + /* The way that we handle the transfer is going to depend on + * whether or not this endpoint supports DMA. In either case + * the endpoint state will transition to SENDING. + */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + sam_dma_wrsetup(priv, privep, privreq); + } + else + { + sam_req_wrsetup(priv, privep, privreq); + } + } + + /* No data to send... This can happen on one of two ways: + * (1) The last packet sent was the final packet of a transfer. + * If it was also exactly maxpacketsize and the protocol expects + * a zero length packet to follow then privep->zlpneeded will be + * set. Or (2) we called with a request packet that has + * len == 0 (privep->zlpneeded will not be set). Either case + * means that it is time to send a zero length packet and complete + * this transfer. + */ + + else if ((privreq->req.len == 0 || privep->zlpneeded) && !privep->zlpsent) + { + /* If we get here, then we sent the last of the data on the + * previous pass and we need to send the zero length packet now. + * + * A Zero Length Packet can be sent by setting just the TXRDY flag + * in the UDPHS_EPTSETSTAx register + */ + + privep->epstate = UDPHS_EPSTATE_SENDING; + privep->zlpneeded = false; + privep->zlpsent = true; + privreq->inflight = 0; + + /* Initiate the zero length transfer and configure to receive the + * transfer complete interrupt. + */ + + sam_ep_txrdy(epno); + } + + /* If all of the bytes were sent (including any final zero length + * packet) then we are finished with the request buffer and we can + * return the request buffer to the class driver. The state will + * remain IDLE only if nothing else was put in flight. + * + * Note that we will then loop to check to check the next queued + * write request. + */ + + if (privep->epstate == UDPHS_EPSTATE_IDLE) + { + /* Return the write request to the class driver */ + + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + privreq->req.xfrd); + + DEBUGASSERT(privreq->req.len == privreq->req.xfrd); + sam_req_complete(privep, OK); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_req_rddone + * + * Description: + * The last non-DMA OUT transfer has completed. Read 'recvsize' byts from + * the FIFO into the read request buffer. + * + ****************************************************************************/ + +static void sam_req_rddone(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq, uint16_t recvsize) +{ + const uint8_t *fifo; + uint8_t *dest; + int remaining; + int readlen; + int epno; + + /* Get the number of bytes that can be received. This is the size of the + * user-provided request buffer, minus the number of bytes already + * transferred to the user-buffer. + */ + + remaining = privreq->req.len - privreq->req.xfrd; + + /* Read the smaller of the number of bytes available in FIFO and the + * size remaining in the request buffer provided by the caller. + */ + + readlen = MIN(remaining, recvsize); + privreq->req.xfrd += readlen; + + /* Get the source and destination transfer addresses */ + + epno = USB_EPNO(privep->ep.eplog); + fifo = (const uint8_t *) + ((uint32_t *)SAM_UDPHSRAM_VSECTION + (EPT_VIRTUAL_SIZE * epno)); + dest = privreq->req.buf + privreq->req.xfrd; + + /* Retrieve packet from the FIFO */ + + for (; readlen > 0; readlen--) + { + *dest++ = *fifo++; + } +} + +/**************************************************************************** + * Name: sam_req_rdenable + * + * Description: + * Make sure that the endpoint RXRDY_TXTK interrupt is enabled in order + * to receive the next incoming packet + * + ****************************************************************************/ + +static void sam_req_rdenable(uint8_t epno) +{ + uint32_t regval; + + regval = sam_getreg(SAM_UDPHS_IEN); + regval |= UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + + sam_putreg(UDPHS_EPTCTL_RXRDYTXKL, SAM_UDPHS_EPTCTLENB(epno)); +} + +/**************************************************************************** + * Name: sam_req_rddisable + * + * Description: + * Disable endpoint interrupts + * + ****************************************************************************/ + +static void sam_req_rddisable(uint8_t epno) +{ + uint32_t regval; + + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + + sam_putreg(UDPHS_EPTCTL_RXRDYTXKL, SAM_UDPHS_EPTCTLDIS(epno)); +} + +/**************************************************************************** + * Name: sam_req_read + * + * Description: + * Complete the last read request, return the read request to the class + * implementation, and try to started the next queued read request. + * + * This function is called in one of three contexts: (1) When the endpoint + * is IDLE and a new read request is submitted (with interrupts disabled), + * (2) from interrupt handling when the current transfer completes (either + * DMA or FIFO), or (3) when resuming a stalled OUT or control endpoint. + * + * There is a fundamental difference between receiving packets via DMA and + * via the FIFO: + * + * - When receiving data via DMA, then data has already been transferred + * and this function is called on the terminating event. The transfer + * is complete and we just need to check for end of request events and + * if we need to setup the transfer for the next request. + * - When receiving via the FIFO, the transfer is not complete. The + * data is in the FIFO and must be transferred from the FIFO to the + * request buffer. No setup is needed for the next transfer other than + * assuring that the endpoint RXRDY_TXTK interrupt is enabled. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is size of the request + * buffer. Any OUT request can be received that will fit in this + * buffer. 'xfrd' and 'inflight' in the request must be zero + * If sam_req_read() is called to start a new transfer, the recvsize + * parameter must be zero. + * + * When this function starts a DMA transfer it will update the request + * 'inflight' field to hold the maximum size of the transfer; but + * 'inflight' is not used with FIFO transfers. + * + * When the transfer completes, the 'recvsize' parameter must be the + * size of the transfer that just completed. For the case of DMA, + * that is the size of the DMA transfer that has just been written to + * memory; for the FIFO transfer, recvsize is the number of bytes + * waiting in the FIFO to be read. + * + ****************************************************************************/ + +static int sam_req_read(struct sam_usbdev_s *priv, struct sam_ep_s *privep, + uint16_t recvsize) +{ + struct sam_req_s *privreq; + uint32_t regval; + uint32_t eptype; + uint8_t epno; + + DEBUGASSERT(priv && privep && privep->epstate == UDPHS_EPSTATE_IDLE); + + /* Loop in case we need to handle multiple read requests */ + + while (privep->epstate == UDPHS_EPSTATE_IDLE) + { + /* Check the request from the head of the endpoint request queue */ + + epno = USB_EPNO(privep->ep.eplog); + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* No packet to receive data */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPOUTQEMPTY), epno); + return -ENOENT; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + epno, privreq->req.len, privreq->req.xfrd); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPOUTNULLPACKET), 0); + sam_req_complete(privep, OK); + recvsize = 0; + continue; + } + + usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), recvsize); + + /* Update the number of bytes transferred with the received size */ + + privreq->req.xfrd += recvsize; + privreq->inflight = 0; + + /* If this was not a DMA transfer, read the incoming data from the FIFO */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) == 0) + { + sam_req_rddone(priv, privep, privreq, recvsize); + } + + /* In case we go through the loop again */ + + recvsize = 0; + + /* If nothing has yet be transferred into the read request, then + * indicate that we are in the RECEIVING state and, if the endpoint + * supports DMA, setup the receive DMA. + */ + + if (privreq->req.xfrd == 0) + { + /* Set the RECEIVING state */ + + privep->epstate = UDPHS_EPSTATE_RECEIVING; + + /* If the endpoint supports DMA, set up the DMA now */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + /* Set up the next DMA */ + + sam_dma_rdsetup(priv, privep, privreq); + } + else + { + /* Enable endpoint RXRDY_TXTK interrupts */ + + sam_req_rdenable(epno); + } + } + + /* We will not try to accumulate packet data here. If anything + * has been received, we will complete the transfer immediately and + * give the data to the class driver. The idea is that we will let the + * receiving be in-charge if incoming buffer. + */ + + else + { + /* Return the read request to the class driver. */ + + usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd); + sam_putreg(UDPHS_EPTCTL_RXRDYTXKL, SAM_UDPHS_EPTCTLDIS(epno)); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_UDPHS_EPTCFG(epno)); + eptype = regval & UDPHS_EPTCFG_TYPE_MASK; + + /* Disable endpoint interrupts if not the control endpoint */ + + if (eptype != UDPHS_EPTCFG_TYPE_CTRL8) + { + sam_req_rddisable(epno); + } + + /* And complete the request */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + sam_req_complete(privep, OK); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_req_cancel + ****************************************************************************/ + +static void sam_req_cancel(struct sam_ep_s *privep, int16_t result) +{ + uint32_t regval; + uint8_t epno; + + /* Disable endpoint interrupts if not endpoint 0 */ + + epno = USB_EPNO(privep->ep.eplog); + if (epno != 0) + { + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_DMA(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + } + + /* Then complete every queued request with the specified status */ + + while (!sam_rqempty(&privep->reqq)) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + (sam_rqpeek(&privep->reqq))->req.xfrd); + sam_req_complete(privep, result); + } +} + +/**************************************************************************** + * Interrupt Level Processing + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep0_read + * + * Description: + * Read a general USB request from the UDPHS FIFO + * + ****************************************************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen) +{ + volatile const uint8_t *fifo; + + /* Retrieve packet from the FIFO */ + + fifo = (volatile const uint8_t *)SAM_UDPHSRAM_VSECTION; + for (; buflen > 0; buflen--) + { + *buffer++ = *fifo++; + } +} + +/**************************************************************************** + * Name: sam_ep0_wrstatus + * + * Description: + * Process the next queued write request for an endpoint that does not + * support DMA. + * + ****************************************************************************/ + +static void sam_ep0_wrstatus(const uint8_t *buffer, size_t buflen) +{ + volatile uint8_t *fifo; + + /* Write packet in the FIFO buffer */ + + fifo = (volatile uint8_t *)SAM_UDPHSRAM_VSECTION; + for (; buflen > 0; buflen--) + { + *fifo++ = *buffer++; + } + + /* Initiate the transfer and configure to receive the transfer complete + * interrupt. + */ + + sam_ep_txrdy(EP0); +} + +/**************************************************************************** + * Name: sam_ep0_dispatch + ****************************************************************************/ + +static void sam_ep0_dispatch(struct sam_usbdev_s *priv) +{ + uint8_t *dataout; + size_t outlen; + int ret; + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Assume IN SETUP (or OUT SETUP with no data) */ + + dataout = NULL; + outlen = 0; + + /* Was this an OUT SETUP command? */ + + if (USB_REQ_ISOUT(priv->ctrl.type)) + { + uint16_t tmplen = GETUINT16(priv->ctrl.len); + if (tmplen > 0) + { + dataout = priv->ep0out; + outlen = tmplen; + } + } + + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, + dataout, outlen); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DISPATCHSTALL), 0); + (void)sam_ep_stall(&priv->eplist[EP0].ep, false); + } + } +} + +/**************************************************************************** + * Name: sam_setdevaddr + ****************************************************************************/ + +static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t address) +{ + uint32_t regval; + + if (address) + { + /* Enable the address */ + + regval = sam_getreg(SAM_UDPHS_CTRL); + regval &= ~UDPHS_CTRL_DEVADDR_MASK; + regval |= UDPHS_CTRL_DEVADDR(address) | UDPHS_CTRL_FADDREN; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* Go to the addressed state */ + + priv->devstate = UDPHS_DEVSTATE_ADDRESSED; + } + else + { + /* Disable address */ + + regval = sam_getreg(SAM_UDPHS_CTRL); + regval &= ~UDPHS_CTRL_FADDREN; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* Revert to the un-addressed, default state */ + + priv->devstate = UDPHS_DEVSTATE_DEFAULT; + } +} + +/**************************************************************************** + * Name: sam_ep0_setup + ****************************************************************************/ + +static void sam_ep0_setup(struct sam_usbdev_s *priv) +{ + struct sam_ep_s *ep0 = &priv->eplist[EP0]; + struct sam_ep_s *privep; + union wb_u value; + union wb_u index; + union wb_u len; + union wb_u response; + enum sam_ep0setup_e ep0result; + uint8_t epno; + int nbytes = 0; /* Assume zero-length packet */ + int ret; + + /* Terminate any pending requests */ + + sam_req_cancel(ep0, -EPROTO); + + /* Assume NOT stalled; no TX in progress */ + + ep0->stalled = 0; + ep0->epstate = UDPHS_EPSTATE_IDLE; + + /* And extract the little-endian 16-bit values to host order */ + + value.w = GETUINT16(priv->ctrl.value); + index.w = GETUINT16(priv->ctrl.index); + len.w = GETUINT16(priv->ctrl.len); + + ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + + /* Dispatch any non-standard requests */ + + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standar requests */ + + sam_ep0_dispatch(priv); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + ep0result = UDPHS_EP0SETUP_SUCCESS; + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPGETSTATUS), epno); + if (epno >= SAM_UDPHS_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), epno); + ep0result = UDPHS_EP0SETUP_STALL; + } + else + { + privep = &priv->eplist[epno]; + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ + + if (privep->stalled) + { + /* Endpoint stalled */ + + response.b[LSB] = 1; /* Stalled */ + } + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADDEVGETSTATUS), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSTATUS), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* Let the class implementation handle all recipients (except for the + * endpoint recipient) + */ + + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + else + { + /* Endpoint recipient */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_UDPHS_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 0; + + ret = sam_ep_stall(&privep->ep, true); + if (ret < 0) + { + ep0result = UDPHS_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADCLEARFEATURE), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETFEATURE), priv->ctrl.type); + if (((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + ullvdbg("test mode: %d\n", index.w); + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* The class driver handles all recipients except recipient=endpoint */ + + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + else + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_UDPHS_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 1; + + ret = sam_ep_stall(&privep->ep, false); + if (ret < 0) + { + ep0result = UDPHS_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETFEATURE), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETADDRESS), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + else + { + /* Note that setting of the device address will be deferred. A + * zero-length packet will be sent and the device address will + * be set when the zero-length packet transfer completes. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPSETADDRESS), value.w); + priv->devaddr = value.w; + ep0result = UDPHS_EP0SETUP_ADDRESS; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSETDESC), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETCONFIG), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index.w == 0 && len.w == 0) + { + /* The request seems valid... let the class implementation handle it. + * If the class implementation accespts it new configuration, it will + * call sam_ep_configure() to configure the endpoints. + */ + + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETCONFIG), 0); + ep0result = UDPHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETIF), priv->ctrl.type); + sam_ep0_dispatch(priv); + ep0result = UDPHS_EP0SETUP_DISPATCHED; + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); + ep0result = UDPHS_EP0SETUP_STALL; + } + break; + } + + /* Restrict the data length to the length requested in the setup packet */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* At this point, the request has been handled and there are three + * (or four) possible outcomes: + * + * 1a. ep0result == UDPHS_EP0SETUP_SUCCESS + * + * The setup request was successfully handled above and a response + * packet must be sent (may be a zero length packet). + * + * 1b. ep0result == UDPHS_EP0SETUP_ADDRESS + * + * A special case is the case where epstate=UDPHS_EPSTATE_EP0ADDRESS. + * This means that the above processing generated an additional state + * where we need to wait until we complete the status phase before + * applying the new device address. + * + * 2. ep0result == UDPHS_EP0SETUP_DISPATCHED; + * + * The request was forwarded to the class implementation. In case, + * EP0 IN data may have already been sent and the EP0 IN response + * has already been queued? Or perhaps the endpoint has already + * been stalled? This is all under the control of the class driver. + * + * NOTE that for the case of non-standard SETUP requested, those + * requests were forwarded to the class driver and we don't even get + * to this logic. + * + * 3. ep0result == UDPHS_EP0SETUP_STALL; + * + * An error was detected in either the above logic or by the class + * implementation logic. + */ + + switch (ep0result) + { + case UDPHS_EP0SETUP_SUCCESS: + { + /* Send the response (might be a zero-length packet) */ + + ep0->epstate = UDPHS_EPSTATE_EP0STATUSIN; + sam_ep0_wrstatus(response.b, nbytes); + } + break; + + case UDPHS_EP0SETUP_ADDRESS: + { + /* Send the response (might be a zero-length packet) */ + + ep0->epstate = UDPHS_EPSTATE_EP0ADDRESS; + sam_ep0_wrstatus(response.b, nbytes); + } + break; + + case UDPHS_EP0SETUP_STALL: + { + /* Stall EP0 */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPSTALLED), + priv->ctrl.req); + + (void)sam_ep_stall(&priv->eplist[EP0].ep, false); + } + break; + + case UDPHS_EP0SETUP_DISPATCHED: + default: + break; + } +} + +/**************************************************************************** + * Name: sam_dma_interrupt + * + * Description: + * Handle the UDPHS DMA interrupt + * + ****************************************************************************/ + +static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno) +{ + struct sam_ep_s *privep; + struct sam_req_s *privreq; + uintptr_t regaddr; + uint32_t regval; + uint32_t dmastatus; + uint8_t *buf; + int bufcnt; + int xfrsize; + + /* Not all endpoints support DMA */ + + DEBUGASSERT((unsigned)epno < SAM_UDPHS_NENDPOINTS && + (SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0); + + /* Get the endpoint structure */ + + privep = &priv->eplist[epno]; + + /* Get the request from the head of the endpoint request queue */ + + privreq = sam_rqpeek(&privep->reqq); + DEBUGASSERT(privreq); + + /* Get the result of the DMA operation */ + + dmastatus = sam_getreg(SAM_UDPHS_DMASTATUS(epno)); + uvdbg("DMA%d DMASTATUS: %08x\n", epno, dmastatus); + + /* Disable DMA interrupt to avoid receiving 2 (B_EN and TR_EN) */ + + regaddr = SAM_UDPHS_DMACONTROL(epno); + regval = sam_getreg(regaddr); + regval &= ~(UDPHS_DMACONTROL_ENDTREN | UDPHS_DMACONTROL_ENDBEN); + sam_putreg(regval, regaddr); + + /* Check for end of the buffer. Set by hardware when the BUFF_COUNT + * downcount reaches zero. This could be either an IN or OUT transfer. + */ + + if ((dmastatus & UDPHS_DMASTATUS_ENDBFST) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOB), (uint16_t)dmastatus); + + /* BUFF_COUNT holds the number of untransmitted bytes. BUFF_COUNT is + * equal to zero in case of good transfer. BUFF_COUNT was set to + * the 'inflight' count when the DMA started and the BUFF_COUNT has + * now decremented to zero + */ + + /* This is just debug logic that only does any if USB debug or tracing + * are enabled. This just verifies taht BUFF_COUNT is zero. + */ + + bufcnt = (dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK) + >> UDPHS_DMASTATUS_BUFCNT_SHIFT; + + if (bufcnt != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_ENDBUFST), bufcnt); + } + + /* Were we sending? Or receiving? */ + + if (privep->epstate == UDPHS_EPSTATE_SENDING) + { + /* This is an IN endpoint. Continuing processing the write + * request. We must call sam_req_write in the IDLE state + * with the number of bytes transferred in 'inflight' + * + * REVISIT: On the SAMV7, I found that you really need to + * wait for the TX completion interrupt before calling + * sam_req_write(). For the SAMV7, the logic here just + * enables that TX completion interrupt if BYCT > 0. The + * symptom of the problem was occasional missing zero-length + * packets because sam_req_write() was called too soon. + */ + + DEBUGASSERT(USB_ISEPIN(privep->ep.eplog)); + privep->epstate = UDPHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + else if (privep->epstate == UDPHS_EPSTATE_RECEIVING) + { + /* privreg->inflight holds the total transfer size */ + + xfrsize = privreq->inflight; + privreq->inflight = 0; + + /* This is an OUT endpoint. Invalidate the data cache for + * region that just completed DMA. This will force the + * buffer data to be reloaded from RAM when it is accessed. + */ + + DEBUGASSERT(USB_ISEPOUT(privep->ep.eplog)); + buf = &privreq->req.buf[privreq->req.xfrd]; + arch_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize); + + /* Complete this transfer, return the request to the class + * implementation, and try to start the next, queue read request. + * We must call sam_req_read in the IDLE state, 'inflight' is + * ignored (should be zero) and the transfer size is passed as + * an argument to sam_req_read(). + */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + (void)sam_req_read(priv, privep, xfrsize); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEOBSTATE), bufcnt); + } + } + + /* Check for end of channel transfer. END_TR_ST is set by hardware when + * the last packet transfer is complete iff END_TR_EN is set in the + * DMACONTROL rgister. The request is complete. + * + * "Used for OUT transfers only. + * + * "0 = USB end of transfer is ignored. + * "1 = UDPHS device can put an end to the current buffer transfer. + * + * "When set, a BULK or INTERRUPT short packet or the last packet of + * an ISOCHRONOUS (micro) frame (DATAX) will close the current buffer + * and the UDPHS_DMASTATUSx register END_TR_ST flag will be raised." + */ + + else if ((dmastatus & UDPHS_DMASTATUS_ENDTRST) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOC), (uint16_t)dmastatus); + DEBUGASSERT(privep->epstate == UDPHS_EPSTATE_RECEIVING && + USB_ISEPOUT(privep->ep.eplog)); + + /* Get the number of bytes transferred from the DMA status. + * + * BUFF_COUNT holds the number of untransmitted bytes. In this case, + * BUFF_COUNT should not be zero. BUFF_COUNT was set to the + * 'inflight' count when the DMA started so the difference will + * give us the actual size of the transfer. + */ + + bufcnt = ((dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK) + >> UDPHS_DMASTATUS_BUFCNT_SHIFT); + xfrsize = privreq->inflight - bufcnt; + privreq->inflight = 0; + + /* Invalidate the data cache for region that just completed DMA. + * This will force the buffer data to be reloaded from RAM. + */ + + buf = &privreq->req.buf[privreq->req.xfrd]; + arch_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize); + + /* Complete this transfer, return the request to the class + * implementation, and try to start the next, queue read request. + */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + (void)sam_req_read(priv, privep, xfrsize); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DMAERR), (uint16_t)dmastatus); + + /* Return the request buffer to the class implementation with the I/O + * error indication. + */ + + sam_req_complete(privep, -EIO); + } +} + +/**************************************************************************** + * Name: sam_ep_interrupt + * + * Description: + * Handle the UDPHS endpoint interrupt + * + ****************************************************************************/ + +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno) +{ + struct sam_ep_s *privep; + uint32_t eptsta; + uint32_t eptype; + uint32_t regval; + uint16_t pktsize; + + DEBUGASSERT((unsigned)epno < SAM_UDPHS_NENDPOINTS); + + /* Get the endpoint structure */ + + privep = &priv->eplist[epno]; + + /* Get the endpoint status */ + + eptsta = sam_getreg(SAM_UDPHS_EPTSTA(epno)); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_UDPHS_EPTCFG(epno)); + eptype = regval & UDPHS_EPTCFG_TYPE_MASK; + + /* IN packet sent */ + + if ((sam_getreg(SAM_UDPHS_EPTCTL(epno)) & UDPHS_EPTCTL_TXRDY) != 0 && + (eptsta & UDPHS_EPTSTA_TXRDY) == 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_TXRDY), (uint16_t)eptsta); + + /* Sending state. This is the completion of a "normal" write request + * transfer. In this case, we need to resume request processing in + * order to send the next outgoing packet. + */ + + if (privep->epstate == UDPHS_EPSTATE_SENDING || + privep->epstate == UDPHS_EPSTATE_EP0STATUSIN) + { + /* Continue/resume processing the write requests. TXRDY will + * be disabled when the last transfer completes. + */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + + /* Setting of the device address is a special case. The address was + * obtained when a preceding SETADDRESS SETUP command was processed. + * But the address is not set until the final SETUP status phase + * completes. This interrupt indicates the completion of that status + * phase and now we set the address. + */ + + else if (privep->epstate == UDPHS_EPSTATE_EP0ADDRESS) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ADDRESSED), priv->devaddr); + DEBUGASSERT(epno == EP0); + + /* Set the device address */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + sam_setdevaddr(priv, priv->devaddr); + + /* Disable the further TXRDY interrupts on EP0. */ + + sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLDIS(epno)); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_TXRDYERR), privep->epstate); + sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLDIS(epno)); + } + } + + /* OUT packet received */ + + if ((eptsta & UDPHS_EPTSTA_RXRDYTXKL) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXRDY), (uint16_t)eptsta); + + /* Are we receiving data for a read request? */ + + if (privep->epstate == UDPHS_EPSTATE_RECEIVING) + { + /* Yes, get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((eptsta & UDPHS_EPTSTA_BYTECNT_MASK) >> + UDPHS_EPTSTA_BYTECNT_SHIFT); + + /* And continue processing the read request, clearing RXRDYTXKL in + * order to receive more data. + */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + sam_req_read(priv, privep, pktsize); + sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno)); + } + + /* Did we just receive the data associated with an OUT SETUP command? */ + + else if (privep->epstate == UDPHS_EPSTATE_EP0DATAOUT) + { + uint16_t len; + + /* Yes.. back to the IDLE state */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + + /* Get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((eptsta & UDPHS_EPTSTA_BYTECNT_MASK) >> + UDPHS_EPTSTA_BYTECNT_SHIFT); + + /* Get the size that we expected to receive */ + + len = GETUINT16(priv->ctrl.len); + if (len == pktsize) + { + /* Copy the OUT data from the EP0 FIFO into a special EP0 buffer + * and clear RXRDYTXKL in order to receive more data. + */ + + sam_ep0_read(priv->ep0out, len); + sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno)); + + /* And handle the EP0 SETUP now. */ + + sam_ep0_setup(priv); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPOUTSIZE), pktsize); + + /* STALL and discard received data. */ + + (void)sam_ep_stall(&privep->ep, false); + sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno)); + } + } + else + { + /* Check if ACK received on a Control EP */ + + if (eptype == UDPHS_EPTCFG_TYPE_CTRL8 && + (eptsta & UDPHS_EPTSTA_BYTECNT_MASK) == 0) + { + } + + /* Data has been STALLed */ + + else if ((eptsta & UDPHS_EPTSTA_FRCESTALL) != 0) + { + } + + /* NAK the data */ + + else + { + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + } + + /* Discard any received data and clear UDPHS_EPTSTA_RXRDYTXKL so that we + * may receive more data. + */ + + sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno)); + } + } + + /* STALL sent */ + + if ((eptsta & UDPHS_EPTSTA_STALLSNT) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_STALLSNT), (uint16_t)eptsta); + + /* Acknowledge */ + + sam_putreg(UDPHS_EPTSTA_STALLSNT, SAM_UDPHS_EPTCLRSTA(epno)); + + /* ISO error */ + + if (eptype == UDPHS_EPTCFG_TYPE_ISO) + { + privep->epstate = UDPHS_EPSTATE_IDLE; + sam_req_complete(privep, -EIO); + } + + /* If EP is not halted, clear STALL */ + + else if (privep->epstate != UDPHS_EPSTATE_STALLED) + { + sam_putreg(UDPHS_EPTSTA_FRCESTALL, SAM_UDPHS_EPTCLRSTA(epno)); + } + } + + /* SETUP packet received */ + + if ((eptsta & UDPHS_EPTSTA_RXSETUP) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXSETUP), (uint16_t)eptsta); + + /* If a request transfer was pending, complete it. Handle the case + * where during the status phase of a control write transfer, the host + * receives the device ZLP and ack it, but the ack is not received by the + * device + */ + + if (privep->epstate == UDPHS_EPSTATE_RECEIVING || + privep->epstate == UDPHS_EPSTATE_SENDING) + { + sam_req_complete(privep, -EPROTO); + } + + /* ISO Err Flow */ + + if (eptype == UDPHS_EPTCFG_TYPE_ISO) + { + /* Acknowledge setup packet */ + + sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(epno)); + } + else + { + uint16_t len; + + /* Copy setup data from the EP0 FIFO into the driver structure. */ + + sam_ep0_read((uint8_t *)&priv->ctrl, USB_SIZEOF_CTRLREQ); + + /* Acknowledge setup packet */ + + sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(epno)); + + /* Check for a SETUP IN transaction */ + + len = GETUINT16(priv->ctrl.len); + if (USB_REQ_ISOUT(priv->ctrl.type) && len > 0) + { + /* Yes.. then we have to wait for the OUT data phase to + * complete before processing the SETUP command. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPOUT), priv->ctrl.req); + privep->epstate = UDPHS_EPSTATE_EP0DATAOUT; + } + else + { + /* This is an SETUP IN command (or a SETUP IN with no data). + * Handle the EP0 SETUP now. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPIN), len); + privep->epstate = UDPHS_EPSTATE_IDLE; + sam_ep0_setup(priv); + } + } + } +} + +/**************************************************************************** + * Name: sam_udphs_interrupt + * + * Description: + * Handle the UDPHS interrupt + * + ****************************************************************************/ + +static int sam_udphs_interrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple UDPHS controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udphs; + uint32_t intsta; + uint32_t pending; + uint32_t regval; + int i; + + /* Get the set of pending interrupts */ + + intsta = sam_getreg(SAM_UDPHS_INTSTA); + usbtrace(TRACE_INTENTRY(SAM_TRACEINTID_INTERRUPT), intsta); + + regval = sam_getreg(SAM_UDPHS_IEN); + pending = intsta & regval; + + /* Handle all pending UDPHS interrupts (and new interrupts that become + * pending) + */ + + while (pending) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_PENDING), (uint16_t)pending); + + /* Suspend, treated last */ + + if ((pending == UDPHS_INT_DETSUSPD) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DETSUSPD), (uint16_t)pending); + + /* Enable wakeup interrupts */ + + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_DETSUSPD; + regval |= (UDPHS_INT_WAKEUP | UDPHS_INT_ENDOFRSM); + sam_putreg(regval, SAM_UDPHS_IEN); + + /* Acknowledge interrupt */ + + sam_putreg(UDPHS_INT_DETSUSPD | UDPHS_INT_WAKEUP, SAM_UDPHS_CLRINT); + sam_suspend(priv); + } + + /* SOF interrupt */ + + else if ((pending & UDPHS_INT_INTSOF) != 0) + { + /* Acknowledge interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_INTSOF), (uint16_t)pending); + sam_putreg(UDPHS_INT_INTSOF, SAM_UDPHS_CLRINT); + } + + /* Resume */ + + else if ((pending & UDPHS_INT_WAKEUP) != 0 || + (pending & UDPHS_INT_ENDOFRSM) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_WAKEUP), (uint16_t)pending); + sam_resume(priv); + + /* Acknowledge interrupt */ + + sam_putreg(UDPHS_INT_WAKEUP | UDPHS_INT_ENDOFRSM | UDPHS_INT_DETSUSPD, + SAM_UDPHS_CLRINT); + + /* Enable suspend interrupts */ + + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_WAKEUP; + regval |= (UDPHS_INT_ENDOFRSM | UDPHS_INT_DETSUSPD); + sam_putreg(regval, SAM_UDPHS_IEN); + } + + /* End of Reset. Set by hardware when an End Of Reset has been + * detected by the UDPHS controller. Automatically enabled after USB + * reset. + * + * Paragraph 32.6.11, Speed Identification + * + * "The high speed reset is managed by the hardware. + * + * "At the connection, the host makes a reset which could be a + * classic reset (full speed) or a high speed reset. + * + * "At the end of the reset process (full or high), the ENDRESET + * interrupt is generated. + * + * "Then the CPU should read the SPEED bit in UDPHS_INTSTAx to + * ascertain the speed mode of the device." + * + * Paragraph 32.6.14.4 From Powered State to Default State (reset) + * "After its connection to a USB host, the USB device waits for an + * end-of-bus reset. The unmasked flag ENDRESET is set in the + * UDPHS_IEN register and an interrupt is triggered. + * + * "Once the ENDRESET interrupt has been triggered, the device + * enters Default State. In this state, the UDPHS software must: + * + * - Enable the default endpoint, setting the EPT_ENABL flag in + * the UDPHS_EPTCTLENB[0] register and, optionally, enabling + * the interrupt for endpoint 0 by writing 1 in EPT_0 of the + * UDPHS_IEN register. The enumeration then begins by a control + * transfer. + * - Configure the Interrupt Mask Register which has been reset + * by the USB reset detection + * - Enable the transceiver. + * + * "In this state, the EN_UDPHS bit in UDPHS_CTRL register must be + * enabled." + */ + + if ((pending & UDPHS_INT_ENDRESET) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ENDRESET), (uint16_t)pending); + + /* Handle the reset */ + + sam_reset(priv); + + /* Get the device speed */ + + if ((sam_getreg(SAM_UDPHS_INTSTA) & UDPHS_INTSTA_SPEED) > 0) + { + priv->usbdev.speed = USB_SPEED_HIGH; + } + else + { + priv->usbdev.speed = USB_SPEED_FULL; + } + } + + /* Upstream resume */ + + else if ((pending & UDPHS_INT_UPSTRRES) != 0) + { + /* Acknowledge interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_UPSTRRES), (uint16_t)pending); + sam_putreg(UDPHS_INT_UPSTRRES, SAM_UDPHS_CLRINT); + } + + /* DMA interrupts */ + + else if ((pending & UDPHS_INT_DMA_MASK) != 0) + { + for (i = 1; i <= SAM_UDPHS_NDMACHANNELS; i++) + { + if ((pending & UDPHS_INT_DMA(i)) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMA), (uint16_t)i); + sam_dma_interrupt(priv, i); + } + } + } + + /* Endpoint Interrupts */ + + else if ((pending & UDPHS_INT_EPT_MASK) != 0) + { + for (i = 0; i < SAM_UDPHS_NENDPOINTS; i++) + { + if ((pending & UDPHS_INT_EPT(i)) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP), (uint16_t)i); + sam_ep_interrupt(priv, i); + } + } + } + + /* Re-sample the set of pending interrupts */ + + intsta = sam_getreg(SAM_UDPHS_INTSTA); + regval = sam_getreg(SAM_UDPHS_IEN); + pending = intsta & regval; + } + + usbtrace(TRACE_INTEXIT(SAM_TRACEINTID_INTERRUPT), intsta); + return OK; +} + +/**************************************************************************** + * Suspend/Resume Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_suspend + ****************************************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv) +{ + /* Don't do anything if the device is already suspended */ + + if (priv->devstate != UDPHS_DEVSTATE_SUSPENDED) + { + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* Switch to the Suspended state */ + + priv->prevstate = priv->devstate; + priv->devstate = UDPHS_DEVSTATE_SUSPENDED; + + /* Disable clocking to the UDPHS peripheral + * + * NOTE: The Atmel sample code disables USB clocking here (via the PMC + * CKGR_UCKR). However, we cannot really do that here because that + * clocking is also needed by the UHPHS host. + */ + + sam_udphs_disableclk(); + + /* Let the board-specific logic know that we have entered the + * suspend state. This may trigger additional reduced power + * consumuption measures. + */ + + sam_usbsuspend((struct usbdev_s *)priv, false); + } +} + +/**************************************************************************** + * Name: sam_resume + ****************************************************************************/ + +static void sam_resume(struct sam_usbdev_s *priv) +{ + /* This function is called when either (1) a WKUP interrupt is received from + * the host PC, or (2) the class device implementation calls the wakeup() + * method. + */ + + /* Don't do anything if the device was not suspended */ + + if (priv->devstate == UDPHS_DEVSTATE_SUSPENDED) + { + /* Enable clocking to the UDPHS peripheral. + * + * NOTE: In the Atmel example code, they also enable USB clocking + * at this point (via the BIAS in the CKGR_UCKR register). In this + * implementation, that should not be necessary here because we + * never disable BIAS to begin with. + */ + + sam_udphs_enableclk(); + + /* Revert to the previous state */ + + priv->devstate = priv->prevstate; + + /* Restore full power -- whatever that means for this particular board */ + + sam_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + } +} + +/**************************************************************************** + * Endpoint Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ep_reset + * + * Description + * Reset and disable a set of endpoints. + * + ****************************************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno) +{ + struct sam_ep_s *privep = &priv->eplist[epno]; + uint32_t regval; + + /* Disable endpoint interrupt */ + + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + + /* Cancel any queued requests. Since they are canceled with status + * -ESHUTDOWN, then will not be requeued until the configuration is reset. + * NOTE: This should not be necessary... the CLASS_DISCONNECT above + * should result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint */ + + sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST); + + /* Reset endpoint status */ + + privep->epstate = UDPHS_EPSTATE_DISABLED; + privep->stalled = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + privep->bank = 0; +} + +/**************************************************************************** + * Name: sam_epset_reset + * + * Description + * Reset and disable a set of endpoints. + * + ****************************************************************************/ + +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset) +{ + uint32_t bit; + int epno; + + /* Reset each endpoint in the set */ + + for (epno = 0, bit = 1, epset &= SAM_EPSET_ALL; + epno < SAM_UDPHS_NENDPOINTS && epset != 0; + epno++, bit <<= 1) + { + /* Is this endpoint in the set? */ + + if ((epset & bit) != 0) + { + /* Yes.. reset it */ + + sam_ep_reset(priv, epno); + epset &= ~bit; + } + } +} + +/**************************************************************************** + * Name: sam_ep_reserve + * + * Description: + * Find and un-reserved endpoint number and reserve it for the caller. + * + ****************************************************************************/ + +static inline struct sam_ep_s * +sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset) +{ + struct sam_ep_s *privep = NULL; + irqstate_t flags; + int epndx = 0; + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints + * (skipping EP0) + */ + + for (epndx = 1; epndx < SAM_UDPHS_NENDPOINTS; epndx++) + { + uint8_t bit = SAM_EP_BIT(epndx); + if ((epset & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail &= ~bit; + + /* And return the pointer to the standard endpoint structure */ + + privep = &priv->eplist[epndx]; + break; + } + } + } + + leave_critical_section(flags); + return privep; +} + +/**************************************************************************** + * Name: sam_ep_unreserve + * + * Description: + * The endpoint is no long in-used. It will be un-reserved and can be + * re-used if needed. + * + ****************************************************************************/ + +static inline void +sam_ep_unreserve(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= SAM_EP_BIT(USB_EPNO(privep->ep.eplog)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_ep_reserved + * + * Description: + * Check if the endpoint has already been allocated. + * + ****************************************************************************/ + +static inline bool +sam_ep_reserved(struct sam_usbdev_s *priv, int epno) +{ + return ((priv->epavail & SAM_EP_BIT(epno)) == 0); +} + +/**************************************************************************** + * Name: sam_ep_configure_internal + * + * Description: + * This is the internal implementation of the endpoint configuration logic + * and implements the endpoint configuration method of the usbdev_ep_s + * interface. As an internal interface, it will be used to configure + * endpoint 0 which is not available to the class implementation. + * + ****************************************************************************/ + +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc) +{ + struct sam_usbdev_s *priv; + uintptr_t regaddr; + uint32_t regval; + uint16_t maxpacket; + uint8_t epno; + uint8_t eptype; + uint8_t nbtrans; + bool dirin; + + uvdbg("len: %02x type: %02x addr: %02x attr: %02x " + "maxpacketsize: %02x %02x interval: %02x\n", + desc->len, desc->type, desc->addr, desc->attr, + desc->mxpacketsize[0], desc->mxpacketsize[1], + desc->interval); + + /* Decode the endpoint descriptor */ + + epno = USB_EPNO(desc->addr); + dirin = (desc->addr & USB_DIR_MASK) == USB_REQ_DIR_IN; + eptype = (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) >> USB_EP_ATTR_XFERTYPE_SHIFT; + maxpacket = GETUINT16(desc->mxpacketsize); + nbtrans = 1; + + /* Special case maxpacket handling for high-speed endpoints */ + + priv = privep->dev; + if (priv->usbdev.speed == USB_SPEED_HIGH) + { + /* HS Interval, 125us */ + /* MPS: Bits 12:11 specify NB_TRANS, as USB 2.0 Spec. */ + + nbtrans = ((maxpacket >> 11) & 3); + if (nbtrans == 3) + { + nbtrans = 1; + } + else + { + nbtrans++; + } + + /* Mask, bit 10..0 is the max packet size */ + + maxpacket &= 0x7ff; + } + + /* Initialize the endpoint structure */ + + privep->ep.eplog = desc->addr; /* Includes direction */ + privep->ep.maxpacket = maxpacket; + privep->epstate = UDPHS_EPSTATE_IDLE; + privep->bank = SAM_UDPHS_NBANKS(epno); + + /* Initialize the endpoint hardware */ + /* Disable the endpoint */ + + sam_putreg(UDPHS_EPTCTL_SHRTPCKT | UDPHS_EPTCTL_BUSYBANK | + UDPHS_EPTCTL_NAKOUT | UDPHS_EPTCTL_NAKIN | + UDPHS_EPTCTL_STALLSNT | UDPHS_EPTCTL_STALLSNT | + UDPHS_EPTCTL_TXRDY | UDPHS_EPTCTL_RXRDYTXKL | + UDPHS_EPTCTL_ERROVFLW | UDPHS_EPTCTL_MDATARX | + UDPHS_EPTCTL_DATAXRX | UDPHS_EPTCTL_NYETDIS | + UDPHS_EPTCTL_INTDISDMA | UDPHS_EPTCTL_AUTOVALID | + UDPHS_EPTCTL_EPTENABL, + SAM_UDPHS_EPTCTLDIS(epno)); + + /* Reset Endpoint Fifos */ + + sam_putreg(UDPHS_EPTSTA_TOGGLESQ_MASK | UDPHS_EPTSTA_FRCESTALL, + SAM_UDPHS_EPTCLRSTA(epno)); + sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST); + + /* If this is EP0, disable interrupts now */ + + if (eptype == USB_EP_ATTR_XFER_CONTROL) + { + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~UDPHS_INT_EPT(epno); + sam_putreg(regval, SAM_UDPHS_IEN); + } + + /* Configure the endpoint */ + + regaddr = SAM_UDPHS_EPTCFG(epno); + regval = sam_getreg(regaddr) & UDPHS_EPTCFG_MAPD; + + if (maxpacket <= 8) + { + regval |= UDPHS_EPTCFG_SIZE_8; + } + else if (maxpacket <= 16) + { + regval |= UDPHS_EPTCFG_SIZE_16; + } + else if (maxpacket <= 32) + { + regval |= UDPHS_EPTCFG_SIZE_32; + } + else if (maxpacket <= 64) + { + regval |= UDPHS_EPTCFG_SIZE_64; + } + else if (maxpacket <= 128) + { + regval |= UDPHS_EPTCFG_SIZE_128; + } + else if (maxpacket <= 256) + { + regval |= UDPHS_EPTCFG_SIZE_256; + } + else if (maxpacket <= 512) + { + regval |= UDPHS_EPTCFG_SIZE_512; + } + else if (maxpacket <= 1024) + { + regval |= UDPHS_EPTCFG_SIZE_1024; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPTYPE), eptype); + DEBUGPANIC(); + regval |= UDPHS_EPTCFG_SIZE_8; + } + + regval |= ((uint32_t)dirin << 3) | ((uint32_t)eptype << 4) | + ((uint32_t)(privep->bank) << 6) | ((uint32_t)nbtrans << 8); + sam_putreg(regval, regaddr); + + /* Verify that the EPT_MAPD flag is set. This flag is set if the + * endpoint size and the number of banks are correct compared to + * the FIFO maximum capacity and the maximum number of allowed banks. + */ + + if ((sam_getreg(regaddr) & UDPHS_EPTCFG_MAPD) == 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPTCFGMAPD), epno); + return -EINVAL; + } + + /* Enable the endpoint. The way that the endpoint is enabled depends of + * if the endpoint supports DMA transfers or not. + */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + /* Select AUTO_VALID so that the hardware will manage RXRDY_TXKL + * and TXRDY. + */ + + regval = UDPHS_EPTCTL_AUTOVALID | UDPHS_EPTCTL_EPTENABL; + } + else + { + /* No DMA... Software will manage RXRDY_TXKL and TXRDY. */ + + regval = UDPHS_EPTCTL_RXRDYTXKL | UDPHS_EPTCTL_RXSETUP | + UDPHS_EPTCTL_EPTENABL; + } + + sam_putreg(regval, SAM_UDPHS_EPTCTLENB(epno)); + sam_dumpep(priv, epno); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep_configure + * + * Description: + * This is the endpoint configuration method of the usbdev_ep_s interface. + * + ****************************************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + int ret; + + /* Verify parameters. Endpoint 0 is not available at this interface */ + +#if defined(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE) + uint8_t epno = USB_EPNO(desc->addr); + usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno); + + DEBUGASSERT(ep && desc && epno > 0 && epno < SAM_UDPHS_NENDPOINTS); + DEBUGASSERT(epno == USB_EPNO(ep->eplog)); +#endif + + /* This logic is implemented in sam_ep_configure_internal */ + + ret = sam_ep_configure_internal(privep, desc); + if (ret == OK && last) + { + /* If this was the last endpoint, then the class driver is fully + * configured. + */ + + priv = privep->dev; + priv->devstate = UDPHS_DEVSTATE_CONFIGURED; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_ep_disable + * + * Description: + * This is the disable() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_disable(struct usbdev_ep_s *ep) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p\n", ep); + return -EINVAL; + } +#endif + + epno = USB_EPNO(ep->eplog); + usbtrace(TRACE_EPDISABLE, epno); + + /* Reset the endpoint and cancel any ongoing activity */ + + flags = enter_critical_section(); + priv = privep->dev; + sam_ep_reset(priv, epno); + + /* Revert to the addressed-but-not-configured state */ + + priv->devstate = UDPHS_DEVSTATE_ADDRESSED; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_allocreq + * + * Description: + * This is the allocreq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static struct usbdev_req_s *sam_ep_allocreq(struct usbdev_ep_s *ep) +{ + struct sam_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, USB_EPNO(ep->eplog)); + + privreq = (struct sam_req_s *)kmm_malloc(sizeof(struct sam_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct sam_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: sam_ep_freereq + * + * Description: + * This is the freereq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static void sam_ep_freereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, USB_EPNO(ep->eplog)); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: sam_ep_allocbuffer + * + * Description: + * This is the allocbuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes) +{ + /* There is not special buffer allocation requirement */ + + return kumm_malloc(nbytes); +} +#endif + +/**************************************************************************** + * Name: sam_ep_freebuffer + * + * Description: + * This is the freebuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf) +{ + /* There is not special buffer allocation requirement */ + + kumm_free(buf); +} +#endif + +/**************************************************************************** + * Name: sam_ep_submit + * + * Description: + * This is the submit() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + ulldbg("ERROR: driver=%p\n", priv->driver); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + epno = USB_EPNO(ep->eplog); + req->result = -EINPROGRESS; + req->xfrd = 0; + privreq->inflight = 0; + flags = enter_critical_section(); + + /* Handle IN (device-to-host) requests. NOTE: If the class device is + * using the bi-directional EP0, then we assume that they intend the EP0 + * IN functionality (EP0 SETUP OUT data receipt does not use requests). + */ + + if (USB_ISEPIN(ep->eplog) || epno == EP0) + { + /* If the endpoint is stalled, then fail any attempts to write + * through the endpoint. + */ + + if (privep->stalled) + { + sam_req_abort(privep, privreq, -EBUSY); + ulldbg("ERROR: stalled\n"); + ret = -EPERM; + } + else + { + /* Add the new request to the request queue for the IN endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_INREQQUEUED(epno), req->len); + + /* If the IN endpoint is IDLE, then transfer the data now */ + + if (privep->epstate == UDPHS_EPSTATE_IDLE) + { + ret = sam_req_write(priv, privep); + } + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_OUTREQQUEUED(epno), req->len); + + /* If the OUT endpoint IDLE, then setup the read */ + + if (privep->epstate == UDPHS_EPSTATE_IDLE) + { + ret = sam_req_read(priv, privep, 0); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_ep_cancel + ****************************************************************************/ + +static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); + + flags = enter_critical_section(); + sam_req_cancel(privep, -EAGAIN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_stall + ****************************************************************************/ + +static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume) +{ + struct sam_ep_s *privep; + struct sam_usbdev_s *priv; + uint8_t epno = USB_EPNO(ep->eplog); + uint32_t regval; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Check that endpoint is in Idle state */ + + privep = (struct sam_ep_s *)ep; + DEBUGASSERT(/* privep->epstate == UDPHS_EPSTATE_IDLE && */ privep->dev); + + priv = (struct sam_usbdev_s *)privep->dev; + epno = USB_EPNO(ep->eplog); + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, USB_EPNO(ep->eplog)); + + /* Handle the resume condition */ + + if (resume) + { + /* Check if the endpoint is halted */ + + if (privep->epstate == UDPHS_EPSTATE_STALLED) + { + usbtrace(TRACE_EPRESUME, epno); + privep->stalled = false; + + /* Return endpoint to Idle state */ + + privep->epstate = UDPHS_EPSTATE_IDLE; + + /* Clear FORCESTALL request + * REVISIT: Data sheet says to reset toggle to DATA0 only on OUT + * endpoints. + */ + + sam_putreg(UDPHS_EPTCLRSTA_TOGGLESQ | UDPHS_EPTCLRSTA_FRCESTALL, + SAM_UDPHS_EPTCLRSTA(epno)); + + /* Reset endpoint FIFOs */ + + sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST); + + /* Resuming any blocked data transfers on the endpoint */ + + if (epno == 0 || USB_ISEPIN(ep->eplog)) + { + /* IN endpoint (or EP0). Restart any queued write requests */ + + (void)sam_req_write(priv, privep); + } + else + { + /* OUT endpoint. Restart any queued read requests. */ + + (void)sam_req_read(priv, privep, 0); + } + } + } + + /* Handle the stall condition */ + + else + { + /* Check that endpoint is enabled and not already in Halt state */ + + if ((privep->epstate != UDPHS_EPSTATE_DISABLED) && + (privep->epstate != UDPHS_EPSTATE_STALLED)) + { + usbtrace(TRACE_EPSTALL, epno); + + /* If this is an IN endpoint (or endpoint 0), then cancel all + * of the pending write requests. + */ + + if (epno == 0 || USB_ISEPIN(ep->eplog)) + { + sam_req_cancel(privep, -EPERM); + } + + /* Otherwise, it is an OUT endpoint. Complete any read request + * currently in progress (it will get requeued immediately). + */ + + else if (privep->epstate == UDPHS_EPSTATE_RECEIVING) + { + sam_req_complete(privep, -EPERM); + } + + /* Put endpoint into stalled state */ + + privep->epstate = UDPHS_EPSTATE_STALLED; + privep->stalled = true; + + sam_putreg(UDPHS_EPTSETSTA_FRCESTALL, SAM_UDPHS_EPTSETSTA(epno)); + + /* Disable endpoint/DMA interrupts. The not be re-enabled until + * the stall is cleared and the next transfer is started. It + * would, of course, be a bad idea to do this on EP0 since it is + * a SETUP request that is going to clear the STALL. + */ + + if (epno != 0) + { + regval = sam_getreg(SAM_UDPHS_IEN); + regval &= ~(UDPHS_INT_DMA(epno) | UDPHS_INT_EPT(epno)); + sam_putreg(regval, SAM_UDPHS_IEN); + } + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_allocep + * + * Description: + * This is the allocep() method of the USB device driver interface + * + ****************************************************************************/ + +static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno, + bool in, uint8_t eptype) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + struct sam_ep_s *privep = NULL; + uint16_t epset = SAM_EPSET_NOTEP0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epno >= SAM_UDPHS_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset = SAM_EP_BIT(epno); + } + + /* Check if the selected endpoint number is available */ + + privep = sam_ep_reserve(priv, epset); + if (!privep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPRESERVE), (uint16_t)epset); + return NULL; + } + + return &privep->ep; +} + +/**************************************************************************** + * Name: sam_freeep + * + * Description: + * This is the freeep() method of the USB device driver interface + * + ****************************************************************************/ + +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) +{ + struct sam_usbdev_s *priv; + struct sam_ep_s *privep; + +#ifdef CONFIG_DEBUG + if (!dev || !ep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + priv = (struct sam_usbdev_s *)dev; + privep = (struct sam_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)USB_EPNO(ep->eplog)); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + sam_ep_unreserve(priv, privep); + } +} + +/**************************************************************************** + * Name: sam_getframe + * + * Description: + * This is the getframe() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + uint16_t frameno; + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Return the last frame number detected by the hardware */ + + regval = sam_getreg(SAM_UDPHS_FNUM); + frameno = (regval & UDPHS_FNUM_FRAMENUM_MASK) >> UDPHS_FNUM_FRAMENUM_SHIFT; + + usbtrace(TRACE_DEVGETFRAME, frameno); + return frameno; +} + +/**************************************************************************** + * Name: sam_wakeup + * + * Description: + * This is the wakeup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_wakeup(struct usbdev_s *dev) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + irqstate_t flags; + uint32_t regval; + + usbtrace(TRACE_DEVWAKEUP, 0); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Resume normal operation */ + + flags = enter_critical_section(); + sam_resume(priv); + + /* Activate a remote wakeup. Setting this bit forces an external interrupt + * on the UDPHS controller for Remote Wake UP purposes. An Upstream Resume + * is sent only after the UDPHS bus has been in SUSPEND state for at least 5 + * ms. + */ + + regval = sam_getreg(SAM_UDPHS_CTRL); + regval |= UDPHS_CTRL_REWAKEUP; + sam_putreg(regval, SAM_UDPHS_CTRL); + leave_critical_section(flags); + + /* This bit is automatically cleared by hardware at the end of the Upstream + * Resume + */ + + while ((sam_getreg(SAM_UDPHS_CTRL) & UDPHS_CTRL_REWAKEUP) != 0); + return OK; +} + +/**************************************************************************** + * Name: sam_selfpowered + * + * Description: + * This is the selfpowered() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: sam_pullup + * + * Description: + * This is the pullup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_pullup(FAR struct usbdev_s *dev, bool enable) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + /* DETACH PULLD_DIS DP DM Condition + * + * 0 1 Pull High VBUS present + * Up Impedance + * 1 0 Pull Pull No VBUS + * Down Down + * 1 1 High High VBUS present + + * Impedance Imedpance Disconnect + */ + + regval = sam_getreg(SAM_UDPHS_CTRL); + if (enable) + { + /* PULLD_DIS=1: No pull-Down on DP and DM */ + + regval |= UDPHS_CTRL_PULLDDIS; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* DETACH=0: UDPHS is attached. Pulls up the DP line */ + + regval &= ~UDPHS_CTRL_DETACH; + sam_putreg(regval, SAM_UDPHS_CTRL); + } + else + { + /* DETACH=1: UDPHS is detached, UTMI transceiver is suspended. */ + + regval |= UDPHS_CTRL_DETACH; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* PULLD_DIS=0: Pull-Down on DP & DM */ + + regval &= ~UDPHS_CTRL_PULLDDIS; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* Device returns to the Powered state */ + + if (priv->devstate > UDPHS_DEVSTATE_POWERED) + { + priv->devstate = UDPHS_DEVSTATE_POWERED; + } + } + + return OK; +} + +/**************************************************************************** + * Initialization/Reset + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_reset + ****************************************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv) +{ + uint32_t regval; + uint8_t epno; + + /* Make sure that clocking is enabled to the UDPHS peripheral. + * + * NOTE: In the Atmel example code, they also enable USB clocking + * at this point (via the BIAS in the CKGR_UCKR register). In this + * implementation, that should not be necessary here because we + * never disable BIAS to begin with. + */ + + sam_udphs_enableclk(); + + /* Tell the class driver that we are disconnected. The class driver + * should then accept any new configurations. + */ + + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + + /* The device enters the Default state */ + + priv->devaddr = 0; + sam_setdevaddr(priv, 0); + + priv->devstate = UDPHS_DEVSTATE_DEFAULT; + + /* Reset and disable all endpoints other. Then re-configure EP0 */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + sam_ep_configure_internal(&priv->eplist[EP0], &g_ep0desc); + + /* Reset endpoint data structures */ + + for (epno = 0; epno < SAM_UDPHS_NENDPOINTS; epno++) + { + struct sam_ep_s *privep = &priv->eplist[epno]; + + /* Cancel any queued requests. Since they are canceled + * with status -ESHUTDOWN, then will not be requeued + * until the configuration is reset. NOTE: This should + * not be necessary... the CLASS_DISCONNECT above should + * result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + } + + /* Re-configure the USB controller in its initial, unconnected state */ + + priv->usbdev.speed = USB_SPEED_FULL; + + /* Clear all pending interrupt status */ + + regval = UDPHS_INT_UPSTRRES | UDPHS_INT_ENDOFRSM | UDPHS_INT_WAKEUP | + UDPHS_INT_ENDRESET | UDPHS_INT_INTSOF | UDPHS_INT_MICROSOF | + UDPHS_INT_DETSUSPD; + sam_putreg(regval, SAM_UDPHS_CLRINT); + + /* Enable normal operational interrupts (including endpoint 0) */ + + regval = UDPHS_INT_ENDOFRSM | UDPHS_INT_WAKEUP | UDPHS_INT_DETSUSPD | + UDPHS_INT_EPT0; + sam_putreg(regval, SAM_UDPHS_IEN); + + sam_dumpep(priv, EP0); +} + +/**************************************************************************** + * Name: sam_hw_setup + ****************************************************************************/ + +static void sam_hw_setup(struct sam_usbdev_s *priv) +{ + uint32_t regval; + int i; + + /* Paragraph 32.5.1, "Power Management". The UDPHS is not continuously + * clocked. For using the UDPHS, the programmer must first enable the + * UDPHS Clock in the Power Management Controller (PMC_PCER register). + * Then enable the PLL (PMC_UCKR register). Finally, enable BIAS in + * PMC_UCKR register. However, if the application does not require UDPHS + * operations, the UDPHS clock can be stopped when not needed and + * restarted later. + * + * Here, we set only the PCER. PLL configuration was performed in + * sam_clockconfig() earlier in the boot sequence. + */ + + sam_udphs_enableclk(); + + /* Reset and disable endpoints */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + + /* Configure the pull-up on D+ and disconnect it */ + + regval = sam_getreg(SAM_UDPHS_CTRL); + regval |= UDPHS_CTRL_DETACH; + sam_putreg(regval, SAM_UDPHS_CTRL); + + regval &= ~UDPHS_CTRL_PULLDDIS; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* Reset the UDPHS block + * + * Paragraph 33.5.1. "One transceiver is shared with the USB High Speed + * Device (port A). The selection between Host Port A and USB Device is + * controlled by the UDPHS enable bit (EN_UDPHS) located in the UDPHS_CTRL + * control register. + * + * "In the case the port A is driven by the USB High Speed Device, the ... + * transceiver is automatically selected for Device operation once the + * USB High Speed Device is enabled." + */ + + regval &= ~UDPHS_CTRL_ENUDPHS; + sam_putreg(regval, SAM_UDPHS_CTRL); + + regval |= UDPHS_CTRL_ENUDPHS; + sam_putreg(regval, SAM_UDPHS_CTRL); + + /* REVISIT: Per recommendations and sample code, USB clocking (as + * configured in the PMC CKGR_UCKR) is set up after resetting the UDHPS. + * However, that initialization has already been done in sam_clockconfig(). + * Also, that clocking is shared with the UHPHS USB host logic; the + * device logic cannot autonomously control USB clocking. + */ + + /* Initialize DMA channels */ + + for (i = 1; i <= SAM_UDPHS_NDMACHANNELS; i++) + { + /* Stop any DMA transfer */ + + sam_putreg(0, SAM_UDPHS_DMACONTROL(i)); + + /* Reset DMA channel (Buffer count and Control field) */ + + sam_putreg(UDPHS_DMACONTROL_LDNXTDSC, SAM_UDPHS_DMACONTROL(i)); + + /* Reset DMA channel */ + + sam_putreg(0, SAM_UDPHS_DMACONTROL(i)); + + /* Clear DMA channel status (read to clear) */ + + regval = sam_getreg(SAM_UDPHS_DMASTATUS(i)); + sam_putreg(regval, SAM_UDPHS_DMACONTROL(i)); + } + + /* Initialize Endpoints */ + + for (i = 0; i < SAM_UDPHS_NENDPOINTS; i++) + { + /* Disable endpoint */ + + regval = UDPHS_EPTCTL_SHRTPCKT | UDPHS_EPTCTL_BUSYBANK | + UDPHS_EPTCTL_NAKOUT | UDPHS_EPTCTL_NAKIN | + UDPHS_EPTCTL_STALLSNT | UDPHS_EPTCTL_STALLSNT | + UDPHS_EPTCTL_TXRDY | UDPHS_EPTCTL_TXCOMPLT | + UDPHS_EPTCTL_RXRDYTXKL | UDPHS_EPTCTL_ERROVFLW | + UDPHS_EPTCTL_MDATARX | UDPHS_EPTCTL_DATAXRX | + UDPHS_EPTCTL_NYETDIS | UDPHS_EPTCTL_INTDISDMA | + UDPHS_EPTCTL_AUTOVALID | UDPHS_EPTCTL_EPTENABL; + sam_putreg(regval, SAM_UDPHS_EPTCTLDIS(i)); + + /* Clear endpoint status */ + + regval = UDPHS_EPTSTA_TOGGLESQ_MASK | UDPHS_EPTSTA_FRCESTALL | + UDPHS_EPTSTA_RXRDYTXKL | UDPHS_EPTSTA_TXCOMPLT | + UDPHS_EPTSTA_RXSETUP | UDPHS_EPTSTA_STALLSNT | + UDPHS_EPTSTA_NAKIN | UDPHS_EPTSTA_NAKOUT; + sam_putreg(regval, SAM_UDPHS_EPTCLRSTA(i)); + + /* Reset endpoint configuration */ + + sam_putreg(0, SAM_UDPHS_EPTCTLENB(i)); + } + + /* Normal mode (full speed not forced) */ + + sam_putreg(0, SAM_UDPHS_TST); + + /* Disable all interrupts */ + + sam_putreg(0, SAM_UDPHS_IEN); + + /* The Atmel sample code disables USB clocking here (via the PMC + * CKGR_UCKR). However, we cannot really do that here because that + * clocking is also needed by the UHPHS host. + */ +} + +/**************************************************************************** + * Name: sam_sw_setup + ****************************************************************************/ + +static void sam_sw_setup(struct sam_usbdev_s *priv) +{ + int epno; + +#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER +#ifndef CONFIG_SAMA5_UDPHS_PREALLOCATE + int i; + + /* Allocate a pool of free DMA transfer descriptors */ + + priv->dtdpool = (struct sam_dtd_s *) + kmm_memalign(16, CONFIG_SAMA5_UDPHS_NDTDS * sizeof(struct sam_dtd_s)); + if (!priv->dtdpool) + { + udbg("ERROR: Failed to allocate the DMA transfer descriptor pool\n"); + return NULL; + } + + /* Initialize the list of free DMA transfer descriptors */ + + for (i = 0; i < CONFIG_SAMA5_UDPHS_NDTDS; i++) + { + /* Put the transfer descriptor in a free list */ + + sam_td_free(&priv->dtdpool[i]); + } + +#else + /* Initialize the list of free DMA transfer descriptors */ + + DEBUGASSERT(((uintptr_t)&g_dtdpool & 15) == 0); + for (i = 0; i < CONFIG_SAMA5_UDPHS_NDTDS; i++) + { + /* Put the transfer descriptor in a free list */ + + sam_td_free(&g_dtdpool[i]); + } + +#endif /* CONFIG_SAMA5_UDPHS_PREALLOCATE */ +#endif /* CONFIG_SAMA5_UDPHS_SCATTERGATHER */ + + /* Initialize the device state structure. NOTE: many fields + * have the initial value of zero and, hence, are not explicitly + * initialized here. + */ + + memset(priv, 0, sizeof(struct sam_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[EP0].ep; + priv->epavail = SAM_EPSET_ALL & ~SAM_EP_BIT(EP0); + priv->devstate = UDPHS_DEVSTATE_SUSPENDED; + priv->prevstate = UDPHS_DEVSTATE_POWERED; + + /* Initialize the endpoint list */ + + for (epno = 0; epno < SAM_UDPHS_NENDPOINTS; epno++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the (physical) endpoint number which is just the index to the + * endpoint. + */ + + priv->eplist[epno].ep.ops = &g_epops; + priv->eplist[epno].dev = priv; + priv->eplist[epno].ep.eplog = epno; + + /* We will use a maxpacket size for supported for each endpoint */ + + priv->eplist[epno].ep.maxpacket = SAM_UDPHS_MAXPACKETSIZE(epno); + } +} + +/**************************************************************************** + * Name: sam_hw_shutdown + ****************************************************************************/ + +static void sam_hw_shutdown(struct sam_usbdev_s *priv) +{ + uint32_t regval; + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable all interrupts */ + + sam_putreg(0, SAM_UDPHS_IEN); + + /* Clear all pending interrupt status */ + + regval = UDPHS_INT_UPSTRRES | UDPHS_INT_ENDOFRSM | UDPHS_INT_WAKEUP | + UDPHS_INT_ENDRESET | UDPHS_INT_INTSOF | UDPHS_INT_MICROSOF | + UDPHS_INT_DETSUSPD; + sam_putreg(regval, SAM_UDPHS_CLRINT); + + /* Disconnect the device / disable the pull-up */ + + sam_pullup(&priv->usbdev, false); + + /* Disable clocking to the UDPHS peripheral */ + + sam_udphs_disableclk(); +} + +/**************************************************************************** + * Name: sam_sw_shutdown + ****************************************************************************/ + +static void sam_sw_shutdown(struct sam_usbdev_s *priv) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_usbinitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udphs; + + usbtrace(TRACE_DEVINIT, 0); + + /* Software initialization */ + + sam_sw_setup(priv); + + /* Power up and initialize USB controller. Interrupts from the UDPHS + * controller are initialized here, but will not be enabled at the AIC + * until the class driver is installed. + */ + + sam_hw_setup(priv); + + /* Attach USB controller interrupt handlers. The hardware will not be + * initialized and interrupts will not be enabled until the class device + * driver is bound. Getting the IRQs here only makes sure that we have + * them when we need them later. + */ + + if (irq_attach(SAM_IRQ_UDPHS, sam_udphs_interrupt) != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_IRQREGISTRATION), + (uint16_t)SAM_IRQ_UDPHS); + goto errout; + } + + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udphs; + irqstate_t flags; + + flags = enter_critical_section(); + usbtrace(TRACE_DEVUNINIT, 0); + + /* Disable and detach the UDPHS IRQ */ + + up_disable_irq(SAM_IRQ_UDPHS); + irq_detach(SAM_IRQ_UDPHS); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Put the hardware in an inactive state */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udphs; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts at the AIC. + * + * NOTE that interrupts and clocking are left disabled in the UDPHS + * peripheral. The ENDRESET interrupt will automatically be enabled + * when the bus reset occurs. The normal operating configuration will + * be established at that time. + */ + + up_enable_irq(SAM_IRQ_UDPHS); + + /* Enable pull-up to connect the device. The host should enumerate us + * some time after this. The next thing we expect the the ENDRESET + * interrupt. + */ + + sam_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver. If the USB device is connected to a + * USB host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_udphs; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts (but keep them attached) */ + + up_disable_irq(SAM_IRQ_UDPHS); + + /* Put the hardware in an inactive state. Then bring the hardware back up + * in the initial state. This is essentially the same state as we were + * in when up_usbinitialize() was first called. + */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + + sam_sw_setup(priv); + sam_hw_setup(priv); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_SAMA5_UDPHS */ diff --git a/arch/arm/src/sama5/sam_udphs.h b/arch/arm/src/sama5/sam_udphs.h new file mode 100644 index 0000000000000000000000000000000000000000..1f8ec79dec924076a5f7c10c74be02ce24adc049 --- /dev/null +++ b/arch/arm/src/sama5/sam_udphs.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_udphs.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H +#define __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/sam_udphs.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: sam_usbsuspend + * + * Description: + * Board logic must provide the sam_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +void sam_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H */ + diff --git a/arch/arm/src/sama5/sam_usbhost.c b/arch/arm/src/sama5/sam_usbhost.c new file mode 100644 index 0000000000000000000000000000000000000000..7d8e46d55bf9612c29e06715744398a91847b5d3 --- /dev/null +++ b/arch/arm/src/sama5/sam_usbhost.c @@ -0,0 +1,258 @@ +/******************************************************************************************** + * arch/arm/src/sama5/sam_usbhost.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "sam_usbhost.h" + +#ifdef HAVE_USBHOST_TRACE + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +#define TR_OHCI false +#define TR_EHCI true + +#define TR_FMT1 false +#define TR_FMT2 true + +#define TRENTRY(id,ehci,fmt1,string) {string} + +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + +/******************************************************************************************** + * Private Types + ********************************************************************************************/ + +struct sam_usbhost_trace_s +{ +#if 0 + uint16_t id; + bool ehci; + bool fmt2; +#endif + FAR const char *string; +}; + +/******************************************************************************************** + * Private Data + ********************************************************************************************/ + +static const struct sam_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] = +{ +#ifdef CONFIG_SAMA5_OHCI + TRENTRY(OHCI_TRACE1_DEVDISCONN, TR_OHCI, TR_FMT1, "OHCI ERROR: RHport%d Device disconnected\n"), + TRENTRY(OHCI_TRACE1_INTRUNRECOVERABLE, TR_OHCI, TR_FMT1, "OHCI ERROR: Unrecoverable error. pending: %06x\n"), + TRENTRY(OHCI_TRACE1_INTRUNHANDLED, TR_OHCI, TR_FMT1, "OHCI ERROR: Unhandled interrupts pending: %06x\n"), + TRENTRY(OHCI_TRACE1_EPLISTALLOC_FAILED, TR_OHCI, TR_FMT1, "OHCI ERROR: Failed to allocate EP list\n"), + TRENTRY(OHCI_TRACE1_EDALLOC_FAILED, TR_OHCI, TR_FMT1, "OHCI ERROR: Failed to allocate ED\n"), + TRENTRY(OHCI_TRACE1_TDALLOC_FAILED, TR_OHCI, TR_FMT1, "OHCI ERROR: Failed to allocate TD\n"), + TRENTRY(OHCI_TRACE1_IRQATTACH, TR_OHCI, TR_FMT1, "OHCI ERROR: Failed to attach IRQ%d\n"), +#ifdef CONFIG_USBHOST_ASYNCH + TRENTRY(OHCI_TRACE1_BADTDSTATUS, TR_OHCI, TR_FMT1, "OHCI ERROR: Bad asynch TD completion status: %d\n"), +#endif + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(OHCI_VTRACE1_PHYSED, TR_OHCI, TR_FMT1, "OHCI physed: %06x\n"), + TRENTRY(OHCI_VTRACE1_VIRTED, TR_OHCI, TR_FMT1, "OHCI ed: %06x\n"), + TRENTRY(OHCI_VTRACE1_CSC, TR_OHCI, TR_FMT1, "OHCI Connect Status Change, RHSTATUS: %06x\n"), + TRENTRY(OHCI_VTRACE1_DRWE, TR_OHCI, TR_FMT1, "OHCI DRWE: Remote wake-up, RHSTATUS: %06x\n"), + TRENTRY(OHCI_VTRACE1_ALREADYCONN, TR_OHCI, TR_FMT1, "OHCI Already connected, RHPORTST: %06x\n"), + TRENTRY(OHCI_VTRACE1_SPEED, TR_OHCI, TR_FMT1, "OHCI Port speed: %d\n"), + TRENTRY(OHCI_VTRACE1_ALREADYDISCONN, TR_OHCI, TR_FMT1, "OHCI Already disconnected, RHPORTST: %06x\n"), + TRENTRY(OHCI_VTRACE1_RHSC, TR_OHCI, TR_FMT1, "OHCI Root Hub Status Change. Pending: %06x\n"), + TRENTRY(OHCI_VTRACE1_WDHINTR, TR_OHCI, TR_FMT1, "OHCI Writeback Done Head interrupt. Pending: %06x\n"), + TRENTRY(OHCI_VTRACE1_CLASSENUM, TR_OHCI, TR_FMT1, "OHCI Hub port %d: Enumerate device\n"), + TRENTRY(OHCI_VTRACE1_ENUMDISCONN, TR_OHCI, TR_FMT1, "OHCI RHport%dNot connected\n"), + TRENTRY(OHCI_VTRACE1_INITIALIZING, TR_OHCI, TR_FMT1, "OHCI Initializing Stack\n"), + TRENTRY(OHCI_VTRACE1_INITIALIZED, TR_OHCI, TR_FMT1, "OHCI Initialized\n"), + TRENTRY(OHCI_VTRACE1_INTRPENDING, TR_OHCI, TR_FMT1, "OHCI Interrupts pending: %06x\n"), +#endif +#endif + +#ifdef CONFIG_SAMA5_EHCI + TRENTRY(EHCI_TRACE1_SYSTEMERROR, TR_EHCI, TR_FMT1, "EHCI ERROR: System error: %06x\n"), + TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qtd_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_QHALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate a QH\n"), + TRENTRY(EHCI_TRACE1_BUFTOOBIG, TR_EHCI, TR_FMT1, "EHCI ERROR: Buffer too big. Remaining %d\n"), + TRENTRY(EHCI_TRACE1_REQQTDALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate request qTD"), + TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qtd_addbpl failed: %d\n"), + TRENTRY(EHCI_TRACE1_DATAQTDALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate data buffer qTD, 0"), + TRENTRY(EHCI_TRACE1_DEVDISCONNECTED, TR_EHCI, TR_FMT1, "EHCI ERROR: Device disconnected %d\n"), + TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qh_create failed\n"), + TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qtd_setupphase failed\n"), + TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qtd_dataphase failed\n"), + TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qtd_statusphase failed\n"), + TRENTRY(EHCI_TRACE1_TRANSFER_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Transfer failed %d\n"), + TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_qh_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_SYSERR_INTR, TR_EHCI, TR_FMT1, "EHCI: Host System Error Interrupt\n"), + TRENTRY(EHCI_TRACE1_USBERR_INTR, TR_EHCI, TR_FMT1, "EHCI: USB Error Interrupt (USBERRINT) Interrupt: %06x\n"), + TRENTRY(EHCI_TRACE1_EPALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate EP info structure\n"), + TRENTRY(EHCI_TRACE1_BADXFRTYPE, TR_EHCI, TR_FMT1, "EHCI ERROR: Support for transfer type %d not implemented\n"), + TRENTRY(EHCI_TRACE1_HCHALTED_TIMEOUT, TR_EHCI, TR_FMT1, "EHCI ERROR: Timed out waiting for HCHalted. USBSTS: %06x\n"), + TRENTRY(EHCI_TRACE1_QHPOOLALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate the QH pool\n"), + TRENTRY(EHCI_TRACE1_QTDPOOLALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate the qTD pool\n"), + TRENTRY(EHCI_TRACE1_PERFLALLOC_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to allocate the periodic frame list\n"), + TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: sam_reset failed: %d\n"), + TRENTRY(EHCI_TRACE1_RUN_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: EHCI Failed to run: USBSTS=%06x\n"), + TRENTRY(EHCI_TRACE1_IRQATTACH_FAILED, TR_EHCI, TR_FMT1, "EHCI ERROR: Failed to attach IRQ%d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE1_PORTSC_CSC, TR_EHCI, TR_FMT1, "EHCI Connect Status Change: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_CONNALREADY, TR_EHCI, TR_FMT1, "EHCI Already connected: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_DISCALREADY, TR_EHCI, TR_FMT1, "EHCI Already disconnected: %06x\n"), + TRENTRY(EHCI_VTRACE1_TOPHALF, TR_EHCI, TR_FMT1, "EHCI Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_AAINTR, TR_EHCI, TR_FMT1, "EHCI Async Advance Interrupt\n"), + TRENTRY(EHCI_VTRACE1_USBINTR, TR_EHCI, TR_FMT1, "EHCI USB Interrupt (USBINT) Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_CLASSENUM, TR_EHCI, TR_FMT1, "EHCI Hub port %d: Enumerate device\n"), + TRENTRY(EHCI_VTRACE1_ENUM_DISCONN, TR_EHCI, TR_FMT1, "EHCI Enumeration not connected\n"), + TRENTRY(EHCI_VTRACE1_INITIALIZING, TR_EHCI, TR_FMT1, "EHCI Initializing EHCI Stack\n"), + TRENTRY(EHCI_VTRACE1_HCCPARAMS, TR_EHCI, TR_FMT1, "EHCI HCCPARAMS=%06x\n"), + TRENTRY(EHCI_VTRACE1_INIITIALIZED, TR_EHCI, TR_FMT1, "EHCI USB EHCI Initialized\n"), +#endif +#endif +}; + +static const struct sam_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] = +{ +#ifdef CONFIG_SAMA5_OHCI + TRENTRY(OHCI_TRACE2_BADTDSTATUS, TR_OHCI, TR_FMT2, "OHCI ERROR: RHport%d Bad TD completion status: %d\n"), + TRENTRY(OHCI_TRACE2_WHDTDSTATUS, TR_OHCI, TR_FMT2, "OHCI ERROR: WHD Bad TD completion status: %d xfrtype: %d\n"), + TRENTRY(OHCI_TRACE2_EP0ENQUEUE_FAILED, TR_OHCI, TR_FMT2, "OHCI ERROR: RHport%d Failed to enqueue EP0: %d\n"), + TRENTRY(OHCI_TRACE2_EDENQUEUE_FAILED, TR_OHCI, TR_FMT2, "OHCI ERROR: Failed to queue ED for transfer type %d: %d\n"), + TRENTRY(OHCI_TRACE2_CLASSENUM_FAILED, TR_OHCI, TR_FMT2, "OHCI Hub port %d usbhost_enumerate() failed: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(OHCI_VTRACE2_EP0CONFIG, TR_OHCI, TR_FMT2, "OHCI EP0 configure speed=%d funcaddr=%d\n"), + TRENTRY(OHCI_VTRACE2_INTERVAL, TR_OHCI, TR_FMT2, "OHCI interval: %d->%d\n"), + TRENTRY(OHCI_VTRACE2_MININTERVAL, TR_OHCI, TR_FMT2, "OHCI MIN interval: %d offset: %d\n"), + TRENTRY(OHCI_VTRACE2_RHPORTST, TR_OHCI, TR_FMT2, "OHCI RHPORTST%d: %04x\n"), + TRENTRY(OHCI_VTRACE2_CONNECTED, TR_OHCI, TR_FMT2, "OHCI RHPort%d connected, rhswait: %d\n"), + TRENTRY(OHCI_VTRACE2_DISCONNECTED, TR_OHCI, TR_FMT2, "OHCI RHPort%d disconnected, rhswait: %d\n"), + TRENTRY(OHCI_VTRACE2_WAKEUP, TR_OHCI, TR_FMT2, "OHCI RHPort%d connected: %d\n"), + TRENTRY(OHCI_VTRACE2_EP0CTRLED, TR_OHCI, TR_FMT2, "OHCI RHPort%d EP0 CTRL: %04x\n"), + TRENTRY(OHCI_VTRACE2_EPALLOC, TR_OHCI, TR_FMT2, "OHCI EP%d CTRL: %04x\n"), + TRENTRY(OHCI_VTRACE2_CTRLIN, TR_OHCI, TR_FMT2, "OHCI CTRLIN RHPort%d req: %02x\n"), + TRENTRY(OHCI_VTRACE2_CTRLOUT, TR_OHCI, TR_FMT2, "OHCI CTRLOUT RHPort%d req: %02x\n"), + TRENTRY(OHCI_VTRACE2_TRANSFER, TR_OHCI, TR_FMT2, "OHCI EP%d buflen: %d\n"), + TRENTRY(OHCI_VTRACE2_INITCONNECTED, TR_OHCI, TR_FMT2, "OHCI RHPort%d Device connected: %d\n"), +#ifdef CONFIG_USBHOST_HUB + TRENTRY(OHCI_VTRACE2_HUBWAKEUP, TR_OHCI, TR_FMT2, "OHCI Hub Port%d connected: %d\n"), +#endif +#endif +#endif + +#ifdef CONFIG_SAMA5_EHCI + TRENTRY(EHCI_TRACE2_EPSTALLED, TR_EHCI, TR_FMT2, "EHCI EP%d Stalled: TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_EPIOERROR, TR_EHCI, TR_FMT2, "EHCI ERROR: EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_CLASSENUM_FAILED, TR_EHCI, TR_FMT2, "EHCI Hub port %d usbhost_enumerate() failed: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE2_EP0CONFIG, TR_EHCI, TR_FMT2, "EHCI EP0 configure speed=%d funcaddr=%d\n"), + TRENTRY(EHCI_VTRACE2_ASYNCXFR, TR_EHCI, TR_FMT2, "EHCI Async transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_INTRXFR, TR_EHCI, TR_FMT2, "EHCI Intr Transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_IOCCHECK, TR_EHCI, TR_FMT2, "EHCI IOC EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC, TR_EHCI, TR_FMT2, "EHCI PORTSC%d: %04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_CONNECTED, TR_EHCI, TR_FMT2, "EHCI RHPort%d connected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_DISCONND, TR_EHCI, TR_FMT2, "EHCI RHport%d disconnected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_MONWAKEUP, TR_EHCI, TR_FMT2, "EHCI Hub port%d connected: %d\n"), + TRENTRY(EHCI_VTRACE2_EPALLOC, TR_EHCI, TR_FMT2, "EHCI EPALLOC: EP%d TYPE=%d\n"), + TRENTRY(EHCI_VTRACE2_CTRLINOUT, TR_EHCI, TR_FMT2, "EHCI CTRLIN/OUT: RHPort%d req: %02x\n"), + TRENTRY(EHCI_VTRACE2_HCIVERSION, TR_EHCI, TR_FMT2, "EHCI HCIVERSION %x.%02x\n"), + TRENTRY(EHCI_VTRACE2_HCSPARAMS, TR_EHCI, TR_FMT2, "EHCI nports=%d, HCSPARAMS=%04x\n"), +#endif +#endif +}; + +/******************************************************************************************** + * Private Function Prototypes + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ********************************************************************************************/ + +FAR const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +FAR const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} + +#endif /* HAVE_USBHOST_TRACE */ + diff --git a/arch/arm/src/sama5/sam_usbhost.h b/arch/arm/src/sama5/sam_usbhost.h new file mode 100644 index 0000000000000000000000000000000000000000..a67a0a42ddc71c6292ec9cefd279a6df6f9aeb74 --- /dev/null +++ b/arch/arm/src/sama5/sam_usbhost.h @@ -0,0 +1,333 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_usbhost.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H +#define __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#ifdef CONFIG_USBHOST + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* This is the interface argument for call outs to board-specific functions which + * need to know which USB host interface is being used. + */ + +#define SAM_EHCI_IFACE 0 +#define SAM_OHCI_IFACE 1 + +/* This is the interface argument for call outs to board-specific functions which + * need to know which root hub port is being used. + */ + +#define SAM_RHPORT1 0 +#define SAM_RHPORT2 1 +#define SAM_RHPORT3 2 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + +#ifdef CONFIG_SAMA5_OHCI + OHCI_TRACE1_DEVDISCONN, /* OHCI ERROR: RHport Device disconnected */ + OHCI_TRACE1_INTRUNRECOVERABLE, /* OHCI ERROR: Unrecoverable error */ + OHCI_TRACE1_INTRUNHANDLED, /* OHCI ERROR: Unhandled interrupts */ + OHCI_TRACE1_EPLISTALLOC_FAILED, /* OHCI ERROR: Failed to allocate EP list */ + OHCI_TRACE1_EDALLOC_FAILED, /* OHCI ERROR: Failed to allocate ED */ + OHCI_TRACE1_TDALLOC_FAILED, /* OHCI ERROR: Failed to allocate TD */ + OHCI_TRACE1_IRQATTACH, /* OHCI ERROR: Failed to attach IRQ */ +#ifdef CONFIG_USBHOST_ASYNCH + OHCI_TRACE1_BADTDSTATUS, /* OHCI ERROR: Bad asynch TD completion status */ +#endif + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + OHCI_VTRACE1_PHYSED, /* OHCI physed */ + OHCI_VTRACE1_VIRTED, /* OHCI ed */ + OHCI_VTRACE1_CSC, /* OHCI Connect Status Change */ + OHCI_VTRACE1_DRWE, /* OHCI DRWE: Remote wake-up */ + OHCI_VTRACE1_ALREADYCONN, /* OHCI Already connected */ + OHCI_VTRACE1_SPEED, /* OHCI Low speed */ + OHCI_VTRACE1_ALREADYDISCONN, /* OHCI Already disconnected */ + OHCI_VTRACE1_RHSC, /* OHCI Root Hub Status Change */ + OHCI_VTRACE1_WDHINTR, /* OHCI Writeback Done Head interrupt */ + OHCI_VTRACE1_CLASSENUM, /* OHCI Enumerate the device */ + OHCI_VTRACE1_ENUMDISCONN, /* OHCI RHport Not connected */ + OHCI_VTRACE1_INITIALIZING, /* OHCI Initializing Stack */ + OHCI_VTRACE1_INITIALIZED, /* OHCI Initialized */ + OHCI_VTRACE1_INTRPENDING, /* OHCI Interrupts pending */ +#endif +#endif + +#ifdef CONFIG_SAMA5_EHCI + EHCI_TRACE1_SYSTEMERROR, /* EHCI ERROR: System error */ + EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: sam_qtd_foreach failed */ + EHCI_TRACE1_QHALLOC_FAILED, /* EHCI ERROR: Failed to allocate a QH */ + EHCI_TRACE1_BUFTOOBIG, /* EHCI ERROR: Buffer too big */ + EHCI_TRACE1_REQQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate request qTD */ + EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: sam_qtd_addbpl failed */ + EHCI_TRACE1_DATAQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate data buffer qTD */ + EHCI_TRACE1_DEVDISCONNECTED, /* EHCI ERROR: Device disconnected */ + EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: sam_qh_create failed */ + EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: sam_qtd_setupphase failed */ + EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: sam_qtd_dataphase failed */ + EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: sam_qtd_statusphase failed */ + EHCI_TRACE1_TRANSFER_FAILED, /* EHCI ERROR: Transfer failed */ + EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: sam_qh_foreach failed: */ + EHCI_TRACE1_SYSERR_INTR, /* EHCI: Host System Error Interrup */ + EHCI_TRACE1_USBERR_INTR, /* EHCI: USB Error Interrupt (USBERRINT) Interrupt */ + EHCI_TRACE1_EPALLOC_FAILED, /* EHCI ERROR: Failed to allocate EP info structure */ + EHCI_TRACE1_BADXFRTYPE, /* EHCI ERROR: Support for transfer type not implemented */ + EHCI_TRACE1_HCHALTED_TIMEOUT, /* EHCI ERROR: Timed out waiting for HCHalted */ + EHCI_TRACE1_QHPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the QH pool */ + EHCI_TRACE1_QTDPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the qTD pool */ + EHCI_TRACE1_PERFLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the periodic frame list */ + EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: sam_reset failed */ + EHCI_TRACE1_RUN_FAILED, /* EHCI ERROR: EHCI Failed to run */ + EHCI_TRACE1_IRQATTACH_FAILED, /* EHCI ERROR: Failed to attach IRQ */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE1_PORTSC_CSC, /* EHCI Connect Status Change */ + EHCI_VTRACE1_PORTSC_CONNALREADY, /* EHCI Already connected */ + EHCI_VTRACE1_PORTSC_DISCALREADY, /* EHCI Already disconnected */ + EHCI_VTRACE1_TOPHALF, /* EHCI Interrupt top half */ + EHCI_VTRACE1_AAINTR, /* EHCI Async Advance Interrupt */ + EHCI_VTRACE1_USBINTR, /* EHCI USB Interrupt (USBINT) Interrupt */ + EHCI_VTRACE1_CLASSENUM, /* EHCI Enumerate the device */ + EHCI_VTRACE1_ENUM_DISCONN, /* EHCI Enumeration not connected */ + EHCI_VTRACE1_INITIALIZING, /* EHCI Initializing EHCI Stack */ + EHCI_VTRACE1_HCCPARAMS, /* EHCI HCCPARAMS */ + EHCI_VTRACE1_INIITIALIZED, /* EHCI USB EHCI Initialized */ +#endif +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + +#ifdef CONFIG_SAMA5_OHCI + OHCI_TRACE2_BADTDSTATUS, /* OHCI ERROR: RHport Bad TD completion status */ + OHCI_TRACE2_WHDTDSTATUS, /* OHCI ERROR: WDH Bad TD completion status */ + OHCI_TRACE2_EP0ENQUEUE_FAILED, /* OHCI ERROR: RHport Failed to enqueue EP0 */ + OHCI_TRACE2_EDENQUEUE_FAILED, /* OHCI ERROR: Failed to queue ED for transfer type */ + OHCI_TRACE2_CLASSENUM_FAILED, /* OHCI usbhost_enumerate() failed */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + OHCI_VTRACE2_EP0CONFIG, /* OHCI EP0 configuration */ + OHCI_VTRACE2_INTERVAL, /* OHCI interval */ + OHCI_VTRACE2_MININTERVAL, /* OHCI MIN interval/offset */ + OHCI_VTRACE2_RHPORTST, /* OHCI RHPORTST */ + OHCI_VTRACE2_CONNECTED, /* OHCI RHPort connected */ + OHCI_VTRACE2_DISCONNECTED, /* OHCI RHPort disconnected */ + OHCI_VTRACE2_WAKEUP, /* OHCI RHPort connected wakeup */ + OHCI_VTRACE2_EP0CTRLED, /* OHCI RHPort EP0 CTRL */ + OHCI_VTRACE2_EPALLOC, /* OHCI EP CTRL */ + OHCI_VTRACE2_CTRLIN, /* OHCI CTRLIN */ + OHCI_VTRACE2_CTRLOUT, /* OHCI CTRLOUT */ + OHCI_VTRACE2_TRANSFER, /* OHCI EP buflen */ + OHCI_VTRACE2_INITCONNECTED, /* OHCI RHPort Device connected */ +#ifdef CONFIG_USBHOST_HUB + OHCI_VTRACE2_HUBWAKEUP, /* EHCI Hub Port connected wakeup */ +#endif +#endif +#endif + +#ifdef CONFIG_SAMA5_EHCI + EHCI_TRACE2_EPSTALLED, /* EHCI EP Stalled */ + EHCI_TRACE2_EPIOERROR, /* EHCI ERROR: EP TOKEN */ + EHCI_TRACE2_CLASSENUM_FAILED, /* EHCI usbhost_enumerate() failed */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE2_EP0CONFIG, /* EHCI EP0 configuration */ + EHCI_VTRACE2_ASYNCXFR, /* EHCI Async transfer */ + EHCI_VTRACE2_INTRXFR, /* EHCI Interrupt Transfer */ + EHCI_VTRACE2_IOCCHECK, /* EHCI IOC */ + EHCI_VTRACE2_PORTSC, /* EHCI PORTSC */ + EHCI_VTRACE2_PORTSC_CONNECTED, /* EHCI RHPort connected */ + EHCI_VTRACE2_PORTSC_DISCONND, /* EHCI RHport disconnected */ + EHCI_VTRACE2_MONWAKEUP, /* EHCI RHPort connected wakeup */ + EHCI_VTRACE2_EPALLOC, /* EHCI EPALLOC */ + EHCI_VTRACE2_CTRLINOUT, /* EHCI CTRLIN/OUT */ + EHCI_VTRACE2_HCIVERSION, /* EHCI HCIVERSION */ + EHCI_VTRACE2_HCSPARAMS, /* EHCI HCSPARAMS */ +#endif +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) + +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_ohci_initialize + * + * Description: + * Initialize USB OHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one USB OHCI interface, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI +struct usbhost_connection_s; +FAR struct usbhost_connection_s *sam_ohci_initialize(int controller); +#endif + +/************************************************************************************ + * Name: sam_ohci_tophalf + * + * Description: + * OHCI "Top Half" interrupt handler. If both EHCI and OHCI are enabled, then + * EHCI will manage the common UHPHS interrupt and will forward the interrupt + * event to this function. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_OHCI +int sam_ohci_tophalf(int irq, FAR void *context); +#endif + +/************************************************************************************ + * Name: sam_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMA5_EHCI +struct usbhost_connection_s; +FAR struct usbhost_connection_s *sam_ehci_initialize(int controller); +#endif + +/*********************************************************************************** + * Name: sam_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be provided by + * each platform that implements the OHCI or EHCI host interface + * + * Input Parameters: + * rhport - Selects root hub port to be powered host interface. See SAM_RHPORT_* + * definitions above. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ***********************************************************************************/ + +void sam_usbhost_vbusdrive(int rhport, bool enable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_USBHOST */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H */ diff --git a/arch/arm/src/sama5/sam_wdt.c b/arch/arm/src/sama5/sam_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..6868b573c603459051888e54a96b3d1b55fa77eb --- /dev/null +++ b/arch/arm/src/sama5/sam_wdt.c @@ -0,0 +1,706 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_wwdg.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_wdt.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SAMA5_WDT) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The Watchdog Timer uses the Slow Clock divided by 128 to establish the + * maximum Watchdog period to be 16 seconds (with a typical Slow Clock of + * 32768 kHz). + */ + +#ifndef BOARD_SCLK_FREQUENCY +# define BOARD_SCLK_FREQUENCY 32768 +#endif + +#define WDT_FREQUENCY (BOARD_SCLK_FREQUENCY / 128) + +/* At 32768Hz, the maximum timeout value will be: + * + * 4096 / WDT_FREQUENCY = 256 seconds or 16,000 milliseconds + * + * And the minimum (non-zero) timeout would be: + * + * 1 / WDT_FREQUENCY = 3.9 milliseconds + */ + +#define WDT_MINTIMEOUT ((1000 + WDT_FREQUENCY - 1) / WDT_FREQUENCY) +#define WDT_MAXTIMEOUT ((4096 * 1000) / WDT_FREQUENCY) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct sam_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ +#ifdef CONFIG_SAMA5_WDT_INTERRUPT + xcpt_t handler; /* Current WDT interrupt handler */ +#endif + uint32_t timeout; /* The actual timeout value (milliseconds) */ + uint16_t reload; /* The 12-bit watchdog reload value */ + bool started; /* The timer has been started */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +#else +# define sam_getreg(regaddr) getreg32(regaddr) +# define sam_putreg(regval,regaddr) putreg32(regval,regaddr) +#endif + +/* Interrupt hanlding *******************************************************/ + +#ifdef CONFIG_SAMA5_WDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context); +#endif + +/* "Lower half" driver methods **********************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower); +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower); +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler); +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = sam_start, + .stop = sam_stop, + .keepalive = sam_keepalive, + .getstatus = sam_getstatus, + .settimeout = sam_settimeout, + .capture = sam_capture, + .ioctl = sam_ioctl, +}; + +/* "Lower half" driver state */ + +static struct sam_lowerhalf_s g_wdtdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMA5 register + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (regaddr == prevaddr && regval == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return regval; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = regaddr; + preval = regval; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%048\n", regaddr, regval); + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMA5 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", regaddr, regval); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * WDT early warning interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_WDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + /* Is there a registered handler? */ + + if (priv->handler) + { + /* Yes... NOTE: This interrupt service routine (ISR) must reload + * the WDT counter to prevent the reset. Otherwise, we will reset + * upon return. + */ + + priv->handler(irq, context); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return priv->started ? OK : -ENOSYS; +} + +/**************************************************************************** + * Name: sam_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the atchdog timer or "petting the dog". + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + wdvdbg("Entry\n"); + + /* Write WDT_CR_WDRSTT to the WDT CR regiser (along with the KEY value) + * will restart the watchdog timer. + */ + + sam_putreg(WDT_CR_WDRSTT | WDT_CR_KEY, SAM_WDT_CR); + return OK; +} + +/**************************************************************************** + * Name: sam_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * stawtus - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + +#ifdef CONFIG_SAMA5_WDT_INTERRUPT + if (priv->handler) + { + status->flags |= WDFLAGS_CAPTURE; + } +#endif + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the watchdog expires (in milliseconds) + * + * REVISIT: I think this that this information is available. + */ + + status->timeleft = 0; + + wdvdbg("Status :\n"); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in millisecnds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + uint32_t reload; + uint32_t regval; + + DEBUGASSERT(priv); + wdvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < WDT_MINTIMEOUT || timeout >= WDT_MAXTIMEOUT) + { + wddbg("Cannot represent timeout: %d < %d > %d\n", + WDT_MINTIMEOUT, timeout, WDT_MAXTIMEOUT); + return -ERANGE; + } + + /* Calculate the reload value to achiee this (appoximate) timeout. + * + * Examples with WDT_FREQUENCY = 32768 / 128 = 256: + * timeout = 4 -> reload = 1 + * timeout = 16000 -> reload = 4096 + */ + + reload = (timeout * WDT_FREQUENCY + 500) / 1000; + if (reload < 1) + { + reload = 1; + } + else if (reload > 4095) + { + reload = 4095; + } + + /* Calculate and save the actual timeout value in milliseconds: + * + * timeout = 1000 * (reload + 1) / Fwwdg + */ + + priv->timeout = (1000 * reload + WDT_FREQUENCY/2) / WDT_FREQUENCY; + + /* Remember the selected values */ + + priv->reload = reload; + + wdvdbg("reload=%d timout: %d->%d\n", + reload, timeout, priv->timeout); + + /* Set the WDT_MR according to calculated value + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + regval = WDT_MR_WDV(reload) | WDT_MR_WDD(reload); + +#ifdef CONFIG_SAMA5_WDT_INTERRUPT + /* Generate an interrupt whent he watchdog timer expires */ + + regval |= WDT_MR_WDFIEN; +#else + /* Reset (everything) if the watchdog timer expires. + * + * REVISIT: Set WDT_MR_WDRPROC so that only the processor is reset? + */ + + regval |= WDT_MR_WDRSTEN; +#endif + +#ifdef CONFIG_SAMA5_WDT_DEBUGHALT + /* Halt the watchdog in the debug state */ + + regval |= WDT_MR_WDDBGHLT; +#endif + +#ifdef CONFIG_SAMA5_WDT_IDLEHALT + /* Halt the watchdog in the IDLE mode */ + + regval |= WDT_MR_WDIDLEHLT; +#endif + + sam_putreg(regval, SAM_WDT_MR); + + /* NOTE: We had to start the watchdog here (because we cannot re-write the + * MR register). So sam_start will not be able to do anything. + */ + + priv->started = true; + + wdvdbg("Setup: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_WDT_CR), sam_getreg(SAM_WDT_MR), + sam_getreg(SAM_WDT_SR)); + + return OK; +} + +/**************************************************************************** + * Name: sam_capture + * + * Description: + * Don't reset on watchdog timer timeout; instead, call this user provider + * timeout handler. NOTE: Providing handler==NULL will restore the reset + * behavior. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new watchdog expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous watchdog expiration function pointer or NULL is there was + * no previous function pointer, i.e., if the previous behavior was + * reset-on-expiration (NULL is also returned if an error occurs). + * + ****************************************************************************/ + +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler) +{ +#ifndef CONFIG_SAMA5_WDT_INTERRUPT + wddbg("ERROR: Not configured for this mode\n"); + return NULL; +#else + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + irqstate_t flags; + xcpt_t oldhandler; + + DEBUGASSERT(priv); + wdvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + flags = enter_critical_section(); + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + /* Are we attaching or detaching the handler? */ + + if (handler) + { + /* Attaching... Enable the WDT interrupt */ + + up_enable_irq(SAM_IRQ_WDT); + } + else + { + /* Detaching... Disable the WDT interrupt */ + + up_disable_irq(SAM_IRQ_WDT); + } + + leave_critical_section(flags); + return oldhandler; +#endif +} + +/**************************************************************************** + * Name: sam_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctol command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + wdvdbg("cmd=%d arg=%ld\n", cmd, arg); + + /* No ioctls are supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdginitialize + * + * Description: + * Initialize the WDT watchdog time. The watchdog timer is initialized and + * registered as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * None + * + * Returned Values: + * None + * + ****************************************************************************/ + +int up_wdginitialize(void) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + wdvdbg("Entry: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_WDT_CR), sam_getreg(SAM_WDT_MR), + sam_getreg(SAM_WDT_SR)); + + /* Check if some previous logic was disabled the watchdog timer. Since the + * MR can be written only one time, we are out of business if that is the + * case. + */ + + DEBUGASSERT((sam_getreg(SAM_WDT_MR) & WDT_MR_WDDIS) == 0); + + /* No clock setup is required. The Watchdog Timer uses the Slow Clock + * divided by 128 to establish the maximum Watchdog period to be 16 seconds + * (with a typical Slow Clock of 32768 kHz). + */ + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_wdgops; + +#ifdef CONFIG_SAMA5_WDT_INTERRUPT + /* Attach our WDT interrupt handler (But don't enable it yet) */ + + (void)irq_attach(SAM_IRQ_WDT, sam_interrupt); +#endif + + /* Register the watchdog driver as /dev/watchdog0 */ + + (void)watchdog_register("/dev/watchdog0", + (FAR struct watchdog_lowerhalf_s *)priv); + return OK; +} + +#endif /* CONFIG_WATCHDOG && CONFIG_SAMA5_WDT */ diff --git a/arch/arm/src/sama5/sam_wdt.h b/arch/arm/src/sama5/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..6f99082e1634f9256715f5ff09261ea14d9cbf26 --- /dev/null +++ b/arch/arm/src/sama5/sam_wdt.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_wdt.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_WDT_H +#define __ARCH_ARM_SRC_SAMA5_SAM_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_wdt.h" + +#ifdef CONFIG_WATCHDOG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_WATCHDOG */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_WDT_H */ diff --git a/arch/arm/src/sama5/sam_xdmac.c b/arch/arm/src/sama5/sam_xdmac.c new file mode 100644 index 0000000000000000000000000000000000000000..651624d63a03a3f5ef08d930b0fc34b724e3120a --- /dev/null +++ b/arch/arm/src/sama5/sam_xdmac.c @@ -0,0 +1,2494 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_xdmac.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "cache.h" +#include "up_internal.h" +#include "sched/sched.h" + +#include "chip.h" +#include "sam_dmac.h" +#include "sam_periphclks.h" +#include "sam_memories.h" +#include "chip/sam_pmc.h" +#include "chip/sam_xdmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* All of the currently supported SAMA5 chips support two DMA controllers + * of 8 DMA Channels each. + */ + +#if SAM_NDMAC < 1 +# undef CONFIG_SAMA5_XDMAC1 +# undef CONFIG_SAMA5_XDMAC0 +#elif SAM_NDMAC < 2 +# undef CONFIG_SAMA5_XDMAC1 +#endif + +/* Condition out the whole file unless DMA is selected in the configuration */ + +#if defined(CONFIG_SAMA5_XDMAC0) || defined(CONFIG_SAMA5_XDMAC1) + +/* If SAMA5 DMA support is enabled, then OS DMA support should also be + * enabled + */ + +#ifndef CONFIG_ARCH_DMA +# warning "SAMA5 DMA enabled but CONFIG_ARCH_DMA disabled" +#endif + +/* Check the number of link list descriptors to allocate */ + +#ifndef CONFIG_SAMA5_NLLDESC +# define CONFIG_SAMA5_NLLDESC SAM_NDMACHAN +#endif + +#if CONFIG_SAMA5_NLLDESC < SAM_NDMACHAN +# warning "At least SAM_NDMACHAN descriptors must be allocated" + +# undef CONFIG_SAMA5_NLLDESC +# define CONFIG_SAMA5_NLLDESC SAM_NDMACHAN +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure maps a peripheral ID to an DMA channel */ + +struct sam_pidmap_s +{ + uint8_t pid; /* Peripheral identifier */ + uint8_t pchan; /* DMA channel */ +}; + +/* This structure describes one DMA channel */ + +struct sam_xdmach_s +{ +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + uint8_t xdmac; /* DMA controller number (0-1) */ +#endif + uint8_t chan; /* DMA channel number (0-15) */ + bool inuse; /* TRUE: The DMA channel is in use */ + bool rx; /* TRUE: Peripheral to memory transfer */ + uint32_t flags; /* DMA channel flags */ + uint32_t base; /* DMA register channel base address */ + uint32_t cc; /* Pre-calculated CC register for transfer */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ + uint32_t rxaddr; /* RX memory address to be invalidated */ + size_t rxsize; /* Size of RX memory region */ + struct chnext_view1_s *llhead; /* DMA link list head */ + struct chnext_view1_s *lltail; /* DMA link list head */ +}; + +/* This structure describes the state of one DMA controller */ + +struct sam_xdmac_s +{ + /* These semaphores protect the DMA channel and descriptor tables */ + + sem_t chsem; /* Protects channel table */ + sem_t dsem; /* Protects descriptor table */ + uint32_t base; /* DMA register channel base address */ + + /* This array describes the available link list descriptors */ + + struct chnext_view1_s *descr; + + /* This array describes each DMA channel */ + + struct sam_xdmach_s *xdmach; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Channel Control (CC) Register field lookups */ + +static const uint32_t g_chanwidth[4] = +{ + XDMACH_CC_DWIDTH_BYTE, + XDMACH_CC_DWIDTH_HWORD, + XDMACH_CC_DWIDTH_WORD, + XDMACH_CC_DWIDTH_DWORD +}; + +/* These tables map peripheral IDs to channels. A lookup is performed + * before each DMA transfer in order to map the peripheral IDs to the + * correct channel. This must be done because the channel can change with + * the direction of the transfer. + */ + +#ifdef CONFIG_SAMA5_XDMAC0 +/* DMA controller 0, RX DMA: */ + +static const struct sam_pidmap_s g_xdmac0_rxchan[] = +{ + { SAM_PID_HSMCI0, XDMAC0_CH_HSMCI0 }, /* HSMCI0 Receive/Transmit */ + { SAM_PID_HSMCI1, XDMAC0_CH_HSMCI1 }, /* HSMCI1 Receive/Transmit */ + { SAM_PID_TWI0, XDMAC0_CH_TWI0_RX }, /* TWI0 Receive */ + { SAM_PID_TWI1, XDMAC0_CH_TWI1_RX }, /* TWI1 Receive */ + { SAM_PID_TWI2, XDMAC0_CH_TWI2_RX }, /* TWI2 Receive */ + { SAM_PID_TWI3, XDMAC0_CH_TWI3_RX }, /* TWI3 Receive */ + { SAM_PID_SPI0, XDMAC0_CH_SPI0_RX }, /* SPI0 Receive */ + { SAM_PID_SPI1, XDMAC0_CH_SPI1_RX }, /* SPI1 Receive */ + { SAM_PID_SPI2, XDMAC0_CH_SPI2_RX }, /* SPI2 Receive */ + { SAM_PID_USART2, XDMAC0_CH_USART2_RX }, /* USART2 Receive */ + { SAM_PID_USART3, XDMAC0_CH_USART3_RX }, /* USART3 Receive */ + { SAM_PID_USART4, XDMAC0_CH_USART4_RX }, /* USART4 Receive */ + { SAM_PID_UART0, XDMAC0_CH_UART0_RX }, /* UART0 Receive */ + { SAM_PID_UART1, XDMAC0_CH_UART1_RX }, /* UART1 Receive */ + { SAM_PID_SSC0, XDMAC0_CH_SSC0_RX }, /* SSC0 Receive */ + { SAM_PID_SSC1, XDMAC0_CH_SSC1_RX }, /* SSC1 Receive */ + { SAM_PID_DBGU, XDMAC0_CH_DBGU_RX }, /* DBGU Receive */ + { SAM_PID_ADC, XDMAC0_CH_ADC_RX }, /* ADC Receive */ + { SAM_PID_SMD, XDMAC0_CH_SMD_RX }, /* SMD Receive */ + { SAM_PID_USART0, XDMAC0_CH_USART0_RX }, /* USART0 Receive */ + { SAM_PID_USART1, XDMAC0_CH_USART1_RX }, /* USART1 Receive */ + { SAM_PID_AES, XDMAC0_CH_AES_RX }, /* AES Receive */ + { SAM_PID_TDES, XDMAC0_CH_TDES_RX }, /* TDES Receive */ + { SAM_PID_CATB, XDMAC0_CH_CATB_RX }, /* CATB Receive */ +}; +#define NXDMAC0_RXCHANNELS (sizeof(g_xdmac0_rxchan) / sizeof(struct sam_pidmap_s)) + +/* DMA controller 0, TX DMA: */ + +static const struct sam_pidmap_s g_xdmac0_txchan[] = +{ + { SAM_PID_HSMCI0, XDMAC0_CH_HSMCI0 }, /* HSMCI0 Receive/Transmit */ + { SAM_PID_HSMCI1, XDMAC0_CH_HSMCI1 }, /* HSMCI1 Receive/Transmit */ + { SAM_PID_TWI0, XDMAC0_CH_TWI0_TX }, /* TWI0 Transmit */ + { SAM_PID_TWI1, XDMAC0_CH_TWI1_TX }, /* TWI1 Transmit */ + { SAM_PID_TWI2, XDMAC0_CH_TWI2_TX }, /* TWI2 Transmit */ + { SAM_PID_TWI3, XDMAC0_CH_TWI3_TX }, /* TWI3 Transmit */ + { SAM_PID_SPI0, XDMAC0_CH_SPI0_TX }, /* SPI0 Transmit */ + { SAM_PID_SPI1, XDMAC0_CH_SPI1_TX }, /* SPI1 Transmit */ + { SAM_PID_SPI2, XDMAC0_CH_SPI2_TX }, /* SPI2 Transmit */ + { SAM_PID_USART2, XDMAC0_CH_USART2_TX }, /* USART2 Transmit */ + { SAM_PID_USART3, XDMAC0_CH_USART3_TX }, /* USART3 Transmit */ + { SAM_PID_USART4, XDMAC0_CH_USART4_TX }, /* USART4 Transmit */ + { SAM_PID_UART0, XDMAC0_CH_UART0_TX }, /* UART0 Transmit */ + { SAM_PID_UART1, XDMAC0_CH_UART1_TX }, /* UART1 Transmit */ + { SAM_PID_SSC0, XDMAC0_CH_SSC0_TX }, /* SSC0 Transmit */ + { SAM_PID_SSC1, XDMAC0_CH_SSC1_TX }, /* SSC1 Transmit */ + { SAM_PID_DBGU, XDMAC0_CH_DBGU_TX }, /* DBGU Transmit */ + { SAM_PID_SMD, XDMAC0_CH_SMD_TX }, /* SMD Transmit */ + { SAM_PID_USART0, XDMAC0_CH_USART0_TX }, /* USART0 Transmit */ + { SAM_PID_USART1, XDMAC0_CH_USART1_TX }, /* USART1 Transmit */ + { SAM_PID_AES, XDMAC0_CH_AES_TX }, /* AES Transmit */ + { SAM_PID_TDES, XDMAC0_CH_TDES_TX }, /* TDES Transmit */ + { SAM_PID_SHA, XDMAC0_CH_SHA_TX }, /* SHA Transmit */ + { SAM_PID_CATB, XDMAC0_CH_CATB_TX }, /* CATB Transmit */ +}; +#define NXDMAC0_TXCHANNELS (sizeof(g_xdmac0_txchan) / sizeof(struct sam_pidmap_s)) +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 +/* DMA controller 1, RX DMA: */ + +static const struct sam_pidmap_s g_xdmac1_rxchan[] = +{ + { SAM_PID_HSMCI0, XDMAC1_CH_HSMCI0 }, /* HSMCI0 Receive/Transmit */ + { SAM_PID_HSMCI1, XDMAC1_CH_HSMCI1 }, /* HSMCI1 Receive/Transmit */ + { SAM_PID_TWI0, XDMAC1_CH_TWI0_RX }, /* TWI0 Receive */ + { SAM_PID_TWI1, XDMAC1_CH_TWI1_RX }, /* TWI1 Receive */ + { SAM_PID_TWI2, XDMAC1_CH_TWI2_RX }, /* TWI2 Receive */ + { SAM_PID_TWI3, XDMAC1_CH_TWI3_RX }, /* TWI3 Receive */ + { SAM_PID_SPI0, XDMAC1_CH_SPI0_RX }, /* SPI0 Receive */ + { SAM_PID_SPI1, XDMAC1_CH_SPI1_RX }, /* SPI1 Receive */ + { SAM_PID_SPI2, XDMAC1_CH_SPI2_RX }, /* SPI2 Receive */ + { SAM_PID_USART2, XDMAC1_CH_USART2_RX }, /* USART2 Receive */ + { SAM_PID_USART3, XDMAC1_CH_USART3_RX }, /* USART3 Receive */ + { SAM_PID_USART4, XDMAC1_CH_USART4_RX }, /* USART4 Receive */ + { SAM_PID_UART0, XDMAC1_CH_UART0_RX }, /* UART0 Receive */ + { SAM_PID_UART1, XDMAC1_CH_UART1_RX }, /* UART1 Receive */ + { SAM_PID_SSC0, XDMAC1_CH_SSC0_RX }, /* SSC0 Receive */ + { SAM_PID_SSC1, XDMAC1_CH_SSC1_RX }, /* SSC1 Receive */ + { SAM_PID_DBGU, XDMAC1_CH_DBGU_RX }, /* DBGU Receive */ + { SAM_PID_ADC, XDMAC1_CH_ADC_RX }, /* ADC Receive */ + { SAM_PID_SMD, XDMAC1_CH_SMD_RX }, /* SMD Receive */ + +}; +#define NXDMAC1_RXCHANNELS (sizeof(g_xdmac1_rxchan) / sizeof(struct sam_pidmap_s)) + +/* DMA controller 1, TX DMA: */ + +static const struct sam_pidmap_s g_xdmac1_txchan[] = +{ + { SAM_PID_HSMCI0, XDMAC1_CH_HSMCI0 }, /* HSMCI0 Receive/Transmit */ + { SAM_PID_HSMCI1, XDMAC1_CH_HSMCI1 }, /* HSMCI1 Receive/Transmit */ + { SAM_PID_TWI0, XDMAC1_CH_TWI0_TX }, /* TWI0 Transmit */ + { SAM_PID_TWI1, XDMAC1_CH_TWI1_TX }, /* TWI1 Transmit */ + { SAM_PID_TWI2, XDMAC1_CH_TWI2_TX }, /* TWI2 Transmit */ + { SAM_PID_TWI3, XDMAC1_CH_TWI3_TX }, /* TWI3 Transmit */ + { SAM_PID_SPI0, XDMAC1_CH_SPI0_TX }, /* SPI0 Transmit */ + { SAM_PID_SPI1, XDMAC1_CH_SPI1_TX }, /* SPI1 Transmit */ + { SAM_PID_SPI2, XDMAC1_CH_SPI2_TX }, /* SPI2 Transmit */ + { SAM_PID_USART2, XDMAC1_CH_USART2_TX }, /* USART2 Transmit */ + { SAM_PID_USART3, XDMAC1_CH_USART3_TX }, /* USART3 Transmit */ + { SAM_PID_USART4, XDMAC1_CH_USART4_TX }, /* USART4 Transmit */ + { SAM_PID_UART0, XDMAC1_CH_UART0_TX }, /* UART0 Transmit */ + { SAM_PID_UART1, XDMAC1_CH_UART1_TX }, /* UART1 Transmit */ + { SAM_PID_SSC0, XDMAC1_CH_SSC0_TX }, /* SSC0 Transmit */ + { SAM_PID_SSC1, XDMAC1_CH_SSC1_TX }, /* SSC1 Transmit */ + { SAM_PID_DBGU, XDMAC1_CH_DBGU_TX }, /* DBGU Transmit */ + { SAM_PID_SMD, XDMAC1_CH_SMD_TX }, /* SMD Transmit */ +}; +#define NXDMAC1_TXCHANNELS (sizeof(g_xdmac1_txchan) / sizeof(struct sam_pidmap_s)) +#endif + +#ifdef CONFIG_SAMA5_XDMAC0 + +/* This array describes the available link list descriptors */ + +struct chnext_view1_s g_desc0[CONFIG_SAMA5_NLLDESC]; + +/* This array describes the state of each XDMAC0 channel 0 */ + +static struct sam_xdmach_s g_xdmach0[SAM_NDMACHAN] = +{ +#if SAM_NDMACHAN > 0 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 0, + .base = SAM_XDMAC0_CH0_BASE, + }, +#endif +#if SAM_NDMACHAN > 1 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 1, + .base = SAM_XDMAC0_CH1_BASE, + }, +#endif +#if SAM_NDMACHAN > 2 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 2, + .base = SAM_XDMAC0_CH2_BASE, + }, +#endif +#if SAM_NDMACHAN > 3 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 3, + .base = SAM_XDMAC0_CH3_BASE, + }, +#endif +#if SAM_NDMACHAN > 4 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 4, + .base = SAM_XDMAC0_CH4_BASE, + }, +#endif +#if SAM_NDMACHAN > 5 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 5, + .base = SAM_XDMAC0_CH5_BASE, + }, +#endif +#if SAM_NDMACHAN > 6 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 6, + .base = SAM_XDMAC0_CH6_BASE, + }, +#endif +#if SAM_NDMACHAN > 7 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 7, + .base = SAM_XDMAC0_CH7_BASE, + }, +#endif +#if SAM_NDMACHAN > 8 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 8, + .base = SAM_XDMAC0_CH8_BASE, + }, +#endif +#if SAM_NDMACHAN > 9 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 9, + .base = SAM_XDMAC0_CH9_BASE, + }, +#endif +#if SAM_NDMACHAN > 10 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 10, + .base = SAM_XDMAC0_CH10_BASE, + }, +#endif +#if SAM_NDMACHAN > 11 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 11, + .base = SAM_XDMAC0_CH11_BASE, + }, +#endif +#if SAM_NDMACHAN > 12 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 12, + .base = SAM_XDMAC0_CH12_BASE, + }, +#endif +#if SAM_NDMACHAN > 13 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 13, + .base = SAM_XDMAC0_CH13_BASE, + }, +#endif +#if SAM_NDMACHAN > 14 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 14, + .base = SAM_XDMAC0_CH14_BASE, + }, +#endif +#if SAM_NDMACHAN > 15 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 0, +#endif + .chan = 15, + .base = SAM_XDMAC0_CH15_BASE, + } +#endif +}; + +/* This describes the overall state of DMA controller 0 */ + +static struct sam_xdmac_s g_xdmac0 = +{ + /* XDMAC 0 base address */ + + .base = SAM_XDMAC0_VBASE, + + /* This array describes the available link list descriptors */ + + .descr = g_desc0, + + /* This array describes each DMA channel */ + + .xdmach = g_xdmach0, +}; + +#endif /* CONFIG_SAMA5_XDMAC0 */ + +/* This array describes the state of DMA controller 1 */ + +#ifdef CONFIG_SAMA5_XDMAC1 +/* This array describes the available link list descriptors */ + +struct chnext_view1_s g_desc1[CONFIG_SAMA5_NLLDESC]; + +static struct sam_xdmach_s g_xdmach1[SAM_NDMACHAN] = +{ +#if SAM_NDMACHAN > 0 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 0, + .base = SAM_XDMAC1_CH0_BASE, + }, +#endif +#if SAM_NDMACHAN > 1 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 1, + .base = SAM_XDMAC1_CH1_BASE, + }, +#endif +#if SAM_NDMACHAN > 2 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 2, + .base = SAM_XDMAC1_CH2_BASE, + }, +#endif +#if SAM_NDMACHAN > 3 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 3, + .base = SAM_XDMAC1_CH3_BASE, + }, +#endif +#if SAM_NDMACHAN > 4 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 4, + .base = SAM_XDMAC1_CH4_BASE, + }, +#endif +#if SAM_NDMACHAN > 5 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 5, + .base = SAM_XDMAC1_CH5_BASE, + }, +#endif +#if SAM_NDMACHAN > 6 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 6, + .base = SAM_XDMAC1_CH6_BASE, + }, +#endif +#if SAM_NDMACHAN > 7 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 7, + .base = SAM_XDMAC1_CH7_BASE, + }, +#endif +#if SAM_NDMACHAN > 8 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 8, + .base = SAM_XDMAC1_CH8_BASE, + }, +#endif +#if SAM_NDMACHAN > 9 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 9, + .base = SAM_XDMAC1_CH9_BASE, + }, +#endif +#if SAM_NDMACHAN > 10 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 10, + .base = SAM_XDMAC1_CH10_BASE, + }, +#endif +#if SAM_NDMACHAN > 11 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 11, + .base = SAM_XDMAC1_CH11_BASE, + }, +#endif +#if SAM_NDMACHAN > 12 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 12, + .base = SAM_XDMAC1_CH12_BASE, + }, +#endif +#if SAM_NDMACHAN > 13 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 13, + .base = SAM_XDMAC1_CH13_BASE, + }, +#endif +#if SAM_NDMACHAN > 14 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 14, + .base = SAM_XDMAC1_CH14_BASE, + }, +#endif +#if SAM_NDMACHAN > 15 + { +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + .xdmac = 1, +#endif + .chan = 15, + .base = SAM_XDMAC1_CH15_BASE, + } +#endif +}; + +/* This describes the overall state of DMA controller 1 */ + +static struct sam_xdmac_s g_xdmac1 = +{ + /* XDMAC 0 base address */ + + .base = SAM_XDMAC1_VBASE, + + /* This array describes the available link list descriptors */ + + .descr = g_desc1, + + /* This array describes each DMA channel */ + + .xdmach = g_xdmach1, +}; + +#endif /* CONFIG_SAMA5_XDMAC1 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_takechsem() and sam_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table + * + ****************************************************************************/ + +static void sam_takechsem(struct sam_xdmac_s *xdmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&xdmac->chsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givechsem(struct sam_xdmac_s *xdmac) +{ + (void)sem_post(&xdmac->chsem); +} + +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +static void sam_takedsem(struct sam_xdmac_s *xdmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&xdmac->dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(struct sam_xdmac_s *xdmac) +{ + (void)sem_post(&xdmac->dsem); +} + +/**************************************************************************** + * Name: sam_getdmac + * + * Description: + * Read a global XDMAC register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmac(struct sam_xdmac_s *xdmac, + unsigned int offset) +{ + return getreg32(xdmac->base + offset); +} + +/**************************************************************************** + * Name: sam_putdmac + * + * Description: + * Write a value to a global XDMAC register + * + ****************************************************************************/ + +static inline void sam_putdmac(struct sam_xdmac_s *xdmac, uint32_t value, + unsigned int offset) +{ + putreg32(value, xdmac->base + offset); +} + +/**************************************************************************** + * Name: sam_getdmach + * + * Description: + * Read a XDMAC channel register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmach(struct sam_xdmach_s *xdmach, + unsigned int offset) +{ + return getreg32(xdmach->base + offset); +} + +/**************************************************************************** + * Name: sam_putdmach + * + * Description: + * Write a value to a XDMAC channel register + * + ****************************************************************************/ + +static inline void sam_putdmach(struct sam_xdmach_s *xdmach, uint32_t value, + unsigned int offset) +{ + putreg32(value, xdmach->base + offset); +} + +/**************************************************************************** + * Name: sam_controller + * + * Description: + * Given a DMA channel instance, return a pointer to the parent DMA + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_xdmac_s *sam_controller(struct sam_xdmach_s *xdmach) +{ +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + return xdmach->xdmac ? &g_xdmac1 : &g_xdmac0; +#elif defined(CONFIG_SAMA5_XDMAC0) + return &g_xdmac0; +#else + return &g_xdmac1; +#endif +} + +/**************************************************************************** + * Name: sam_channel, sam_source_channel, and sam_sink_channel + * + * Description: + * Return the RX or TX channel associated with a PID. As a clarification: + * + * The source channel refers to the source of data for the DMA. This is, + * either (1) memory for a TX DMA or (2) a peripheral register for an RX + * DMA. + * + * The sink channel is the recipient of the DMA data. This is either + * (1) memory for an RX DMA, or (2) a peripheral register for a TX DMA. + * + ****************************************************************************/ + +static uint8_t sam_channel(uint8_t pid, const struct sam_pidmap_s *table, + unsigned int nentries) +{ + int i; + + /* Search until either the entry with the matching PID is found or until + * all of the table entries have been examined without finding the PID. + */ + + for (i = 0; i < nentries; i++, table++) + { + if (table->pid == pid) + { + return table->pchan; + } + } + + dmadbg("No channel found for pid %d\n", pid); + DEBUGPANIC(); + return 0x3f; +} + +static uint32_t sam_source_channel(struct sam_xdmach_s *xdmach, uint8_t pid) +{ + const struct sam_pidmap_s *table; + unsigned int nentries; + +#ifdef CONFIG_SAMA5_XDMAC0 +#ifdef CONFIG_SAMA5_XDMAC1 + if (xdmach->xdmac == 0) +#endif + { + /* Use the XDMAC0 lookup table */ + + table = g_xdmac0_rxchan; + nentries = NXDMAC0_RXCHANNELS; + } +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 +#ifdef CONFIG_SAMA5_XDMAC0 + else +#endif + { + /* Use the XDMAC1 lookup table */ + + table = g_xdmac1_rxchan; + nentries = NXDMAC1_RXCHANNELS; + } +#endif + + return (uint32_t)sam_channel(pid, table, nentries); +} + +static uint32_t sam_sink_channel(struct sam_xdmach_s *xdmach, uint8_t pid) +{ + const struct sam_pidmap_s *table; + unsigned int nentries; + +#ifdef CONFIG_SAMA5_XDMAC0 +#ifdef CONFIG_SAMA5_XDMAC1 + if (xdmach->xdmac == 0) +#endif + { + /* Use the XDMAC0 lookup table */ + + table = g_xdmac0_txchan; + nentries = NXDMAC0_TXCHANNELS; + } +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 +#ifdef CONFIG_SAMA5_XDMAC0 + else +#endif + { + /* Use the XDMAC1 lookup table */ + + table = g_xdmac1_txchan; + nentries = NXDMAC1_TXCHANNELS; + } +#endif + + return (uint32_t)sam_channel(pid, table, nentries); +} + +/**************************************************************************** + * Name: sam_maxtransfer + * + * Description: + * Maximum number of bytes that can be sent in one transfer + * + ****************************************************************************/ + +static size_t sam_maxtransfer(struct sam_xdmach_s *xdmach) +{ + unsigned int xfrwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes */ + + xfrwidth = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (xfrwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = XDMACH_CUBC_UBLEN_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * XDMACH_CUBC_UBLEN_MAX; + break; + + case 2: /* 32 bits 4 bytes */ + maxtransfer = 4 * XDMACH_CUBC_UBLEN_MAX; + break; + + case 3: /* 64 bits, 8 bytes */ + maxtransfer = 8 * XDMACH_CUBC_UBLEN_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_ntxtransfers + * + * Description: + * Number of TX transfers via DMA + * + ****************************************************************************/ + +static uint32_t sam_ntxtransfers(struct sam_xdmach_s *xdmach, + uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Adjust the source transfer size for the source chunk size (memory + * chunk size). BTSIZE is "the number of transfers to be performed, that + * is, for writes it refers to the number of source width transfers + * to perform when XDMAC is flow controller. For Reads, BTSIZE refers to + * the number of transfers completed on the Source Interface. ..." + */ + + srcwidth = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + + case 3: /* 64 bits, 8 bytes */ + dmasize = (dmasize + 7) >> 3; + break; + } + + return dmasize; +} + +/**************************************************************************** + * Name: sam_cubc + * + * Description: + * Calculate the CUBC transfer size + * + ****************************************************************************/ + +static inline uint32_t sam_cubc(struct sam_xdmach_s *xdmach, + uint32_t dmasize) +{ + uint32_t ntransfers; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + ntransfers = sam_ntxtransfers(xdmach, dmasize); + + DEBUGASSERT(ntransfers <= XDMACH_CUBC_UBLEN_MAX); + return (ntransfers << XDMACH_CUBC_UBLEN_SHIFT); +} + +/**************************************************************************** + * Name: sam_txcc + * + * Description: + * Decode the flags to get the correct Channel Control (CC) Register bit + * settings for a transmit (memory to peripheral) transfer. + * + * Single Block: + * 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * 2. Program MBSIZE to the memory burst size used. + * 3. Program SAM/DAM to the memory addressing scheme. + * 4. Program SYNC to select the peripheral transfer direction. + * 5. Set PROT to activate a secure channel. + * 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + * 7. Program DWIDTH to configure the transfer data width. + * 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + * 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + * + ****************************************************************************/ + +static inline uint32_t sam_txcc(struct sam_xdmach_s *xdmach) +{ + uint32_t regval = 0; + uint32_t field; + + /* 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * + * By convention, TX refers to a memory to peripheral transfer. So the + * source is memory. Is the "peripheral" destination a peripheral? or + * it is really memory? + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral synchronized mode */ + + regval |= XDMACH_CC_TYPE; + } + + /* 2. Program MBSIZE to the memory burst size used. + * + * NOTE: This assumes the same encoding in the DMACH flags as in the CC + * register MBSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_MEMBURST_MASK) >> + DMACH_FLAG_MEMBURST_SHIFT; + regval |= (field << XDMACH_CC_MBSIZE_SHIFT); + + /* 3. Program SAM/DAM to the memory addressing scheme. + * + * NOTE: This assumes that 0 means non-incrementing. + * TX -> Source is memory. + */ + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + regval |= XDMACH_CC_SAM_INCR; + } + + /* TX -> Destination is peripheral. */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + regval |= XDMACH_CC_DAM_INCR; + } + + /* 4. Program DSYNC to select the peripheral transfer direction. + * + * TX -> Memory to peripheral + */ + + regval |= XDMACH_CC_DSYNC; + +#if 0 /* REVISIT */ + /* 5. Set PROT to activate a secure channel (REVISIT). */ + + regval |= XDMACH_CC_PROT; /* Channel is unsecured */ +#endif + + /* 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Peripheral synchronized mode -- set chunk size. + * NOTE that we assume that encoding in the XDMACH flags is the same + * as in the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) >> + DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + } + + /* 7. Program DWIDTH to configure the transfer data width. + * + * NOTE that we assume that encoding in the XDMACH flags is the same as in + * the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + regval |= (field << XDMACH_CC_DWIDTH_SHIFT); + + /* 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * + * TX -> Source is memory + */ + + if ((xdmach->flags & DMACH_FLAG_MEMAHB_MASK) == DMACH_FLAG_MEMAHB_AHB_IF1) + { + regval |= XDMACH_CC_SIF; + } + + /* TX -> Destination is peripheral */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHAHB_MASK) == DMACH_FLAG_PERIPHAHB_AHB_IF1) + { + regval |= XDMACH_CC_DIF; + } + + /* 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + int pid; + + /* Get the PID from the DMACH flags */ + + pid = (xdmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> + DMACH_FLAG_PERIPHPID_SHIFT; + + /* Look up the DMA channel code for TX: Peripheral is the sink. */ + + field = sam_sink_channel(xdmach, pid); + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + +#if 0 /* Not supported */ + /* 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + */ + + regval |= XDMACH_CC_SWREQ; +#endif + } + + return regval; +} + +/**************************************************************************** + * Name: sam_rxcc + * + * Description: + * Decode the flags to get the correct Channel Control (CC) Register bit + * settings for a receive (peripheral to memory) transfer. + * + * 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * 2. Program MBSIZE to the memory burst size used. + * 3. Program SAM/DAM to the memory addressing scheme. + * 4. Program SYNC to select the peripheral transfer direction. + * 5. Set PROT to activate a secure channel. + * 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + * 7. Program DWIDTH to configure the transfer data width. + * 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + * 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + * + ****************************************************************************/ + +static inline uint32_t sam_rxcc(struct sam_xdmach_s *xdmach) +{ + uint32_t regval = 0; + uint32_t field; + + /* 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * + * By convention, RX refers to a peripheral to memory transfer. So the + * source is peripheral. Is the "peripheral" source a peripheral? or + * is it also memory? + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral synchronized mode */ + + regval |= XDMACH_CC_TYPE; + } + + /* 2. Program MBSIZE to the memory burst size used. + * + * NOTE: This assumes the same encoding in the DMACH flags as in the CC + * register MBSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_MEMBURST_MASK) >> + DMACH_FLAG_MEMBURST_SHIFT; + regval |= (field << XDMACH_CC_MBSIZE_SHIFT); + + /* 3. Program SAM/DAM to the memory addressing scheme. + * + * NOTE: This assumes that 0 means non-incrementing. + * RX -> Source is peripheral. + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + regval |= XDMACH_CC_SAM_INCR; + } + + /* RX -> Destination is memory. */ + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + regval |= XDMACH_CC_DAM_INCR; + } + + /* 4. Program DSYNC to select the peripheral transfer direction. + * + * RX -> Peripheral to memory (DSYNC == 0) + */ + +#if 0 /* REVISIT */ + /* 5. Set PROT to activate a secure channel (REVISIT) */ + + regval |= XDMACH_CC_PROT; /* Channel is unsecured */ +#endif + + /* 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Peripheral synchronized mode -- set chunk size. + * NOTE that we assume that encoding in the XDMACH flags is the same + * as in the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) >> + DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + } + + /* 7. Program DWIDTH to configure the transfer data width. + * + * NOTE that we assume that encoding in the XDMACH flags is the same as in + * the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + regval |= (field << XDMACH_CC_DWIDTH_SHIFT); + + /* 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * + * RX -> Source is peripheral + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHAHB_MASK) == DMACH_FLAG_PERIPHAHB_AHB_IF1) + { + regval |= XDMACH_CC_SIF; + } + + /* RX -> Destination is memory */ + + if ((xdmach->flags & DMACH_FLAG_MEMAHB_MASK) == DMACH_FLAG_MEMAHB_AHB_IF1) + { + regval |= XDMACH_CC_DIF; + } + + /* 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + int pid; + + /* Get the PID from the DMACH flags */ + + pid = (xdmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> + DMACH_FLAG_PERIPHPID_SHIFT; + + /* Look up the DMA channel code for RX: Peripheral is the source. */ + + field = sam_source_channel(xdmach, pid); + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + +#if 0 /* Not supported */ + /* 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + */ + + regval |= XDMACH_CC_SWREQ; +#endif + } + + return regval; +} + +/**************************************************************************** + * Name: sam_allocdesc + * + * Description: + * Allocate and add one descriptor to the DMA channel's link list. + * + * NOTE: link list entries are freed by the DMA interrupt handler. + * However, since the setting/clearing of the 'in use' indication is + * atomic, no special actions need be performed. It would be a good thing + * to add logic to handle the case where all of the entries are exhausted + * and we could wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct chnext_view1_s * +sam_allocdesc(struct sam_xdmach_s *xdmach, struct chnext_view1_s *prev, + uint32_t csa, uint32_t cda, uint32_t cubc) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *descr = NULL; + int i; + + /* Sanity check -- csa == 0 is the indication that the link is unused. + * Obviously setting it to zero would break that usage. + */ + +#ifdef CONFIG_DEBUG + if (csa != 0) +#endif + { + /* Table a descriptor table semaphore count. When we get one, then there + * is at least one free descriptor in the table and it is ours. + */ + + sam_takedsem(xdmac); + + /* Examine each link list entry to find an available one -- i.e., one + * with csa == 0. That csa field is set to zero by the DMA transfer + * complete interrupt handler. The following should be safe because + * that is an atomic operation. + */ + + sam_takechsem(xdmac); + for (i = 0; i < CONFIG_SAMA5_NLLDESC; i++) + { + if (xdmac->descr[i].csa == 0) + { + /* We have it. Initialize the new link list entry */ + + descr = &xdmac->descr[i]; + descr->cnda = 0; /* Next Descriptor Address */ + descr->cubc = cubc; /* Channel Microblock Control Register */ + descr->csa = csa; /* Source address */ + descr->cda = cda; /* Destination address */ + + /* And then hook it at the tail of the link list */ + + if (!prev) + { + /* There is no previous link. This is the new head of + * the list + */ + + DEBUGASSERT(xdmach->llhead == NULL && xdmach->lltail == NULL); + xdmach->llhead = descr; + } + else + { + DEBUGASSERT(xdmach->llhead != NULL && xdmach->lltail == prev); + + /* When the second link is added to the list, that is the + * cue that we are going to do the link list transfer. + * + * Set the NDE field in the previous descriptor; Clear the + * NDE field in the final descriptor. + */ + + prev->cubc |= CHNEXT_UBC_NDE; + + /* Link the previous tail to the new tail. + * REVISIT: This assumes that the next description is fetched + * via AHB IF0. + */ + + prev->cnda = (uint32_t)sam_physramaddr((uintptr_t)descr); + } + + /* In any event, this is the new tail of the list */ + + xdmach->lltail = descr; + + /* Assume that we will be doing multiple buffer transfers and that + * that hardware will be accessing the descriptor via DMA. + */ + + arch_clean_dcache((uintptr_t)descr, + (uintptr_t)descr + sizeof(struct chnext_view1_s)); + break; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + sam_givechsem(xdmac); + DEBUGASSERT(descr != NULL); + } + + return descr; +} + +/**************************************************************************** + * Name: sam_freelinklist + * + * Description: + * Free all descriptors in the DMA channel's link list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_freelinklist(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *descr; + uintptr_t paddr; + + /* Get the head of the link list and detach the link list from the DMA + * channel + */ + + descr = xdmach->llhead; + xdmach->llhead = NULL; + xdmach->lltail = NULL; + + while (descr != NULL) + { + /* Valid, in-use descriptors never have csa == 0 */ + + DEBUGASSERT(descr->csa != 0); + + /* Get the physical address of the next descriptor in the list */ + + paddr = descr->cnda; + + /* Free the descriptor by simply nullifying it and bumping up the + * semaphore count. + */ + + memset(descr, 0, sizeof(struct chnext_view1_s)); + sam_givedsem(xdmac); + + /* Get the virtual address of the next descriptor in the list */ + + descr = (struct chnext_view1_s *)sam_virtramaddr(paddr); + } +} + +/**************************************************************************** + * Name: sam_txbuffer + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_txbuffer(struct sam_xdmach_s *xdmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t cubc; + + /* If we are appending a buffer to a linklist, then re-use the previously + * calculated CC register value. Otherwise, create the CC register value + * from the properties of the transfer. + */ + + if (!xdmach->llhead) + { + xdmach->cc = sam_txcc(xdmach); + } + + /* Calculate the number of transfers for CUBC */ + + cubc = sam_cubc(xdmach, nbytes); + cubc |= (CHNEXT_UBC_NVIEW_1 | CHNEXT_UBC_NSEN); + + /* Add the new link list entry */ + + if (!sam_allocdesc(xdmach, xdmach->lltail, maddr, paddr, cubc)) + { + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_rxbuffer + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_rxbuffer(struct sam_xdmach_s *xdmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t cubc; + + /* If we are appending a buffer to a linklist, then re-use the previously + * calculated CC register value. Otherwise, create the CC register value + * from the properties of the transfer. + */ + + if (!xdmach->llhead) + { + xdmach->cc = sam_rxcc(xdmach); + } + + /* Calculate the number of transfers for CUBC */ + + cubc = sam_cubc(xdmach, nbytes); + cubc |= (CHNEXT_UBC_NVIEW_1 | CHNEXT_UBC_NSEN); + + /* Add the new link list entry */ + + if (!sam_allocdesc(xdmach, xdmach->lltail, paddr, maddr, cubc)) + { + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_single + * + * Description: + * Start a single buffer DMA. + * + ****************************************************************************/ + +static inline int sam_single(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *llhead = xdmach->llhead; + + /* 1. Read the XDMAC Global Channel Status Register (XDMAC_GS) to choose a + * free channel. + * + * In this implementation, the free channel is assigned in a different + * manner. + */ + + /* 2. Clear any pending interrupts from any previous XDMAC transfer by + * reading the XDMAC Channel Interrupt Status Register (CIS). + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* 3. Write the starting source address in the Channel Source Address (CSA) + * Register. + */ + + DEBUGASSERT(llhead != NULL && llhead->csa != 0); + sam_putdmach(xdmach, llhead->csa, SAM_XDMACH_CSA_OFFSET); + + /* 4. Write the starting destination address in the Channel Destination + * Address Register (CDA). + */ + + sam_putdmach(xdmach, llhead->cda, SAM_XDMACH_CDA_OFFSET); + + /* 5. Program field UBLEN in the XDMAC Channel Microblock Control (CUBC) + * Register with the number of data. + */ + + sam_putdmach(xdmach, llhead->cubc, SAM_XDMACH_CUBC_OFFSET); + + /* 6. Program the Channel Control (CC) Register */ + + sam_putdmach(xdmach, xdmach->cc, SAM_XDMACH_CC_OFFSET); + + /* 7. Clear the following five registers: + * + * XDMAC Channel Next Descriptor Control (CNDC) Register + * XDMAC Channel Block Control (CBC) Register + * XDMAC Channel Data Stride Memory Set Pattern (CDSMSP) Register + * XDMAC Channel Source Microblock Stride (CSUS) Register + * XDMAC Channel Destination Microblock Stride (CDUS)Register + * + * This respectively indicates that the linked list is disabled, there is + * only one block and striding is disabled + */ + + sam_putdmach(xdmach, 0, SAM_XDMACH_CNDC_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CBC_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CDSMSP_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CSUS_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CDUS_OFFSET); + + /* 8. Enable the Microblock interrupt by setting the "End of Block" + * interrupt bit in the XDMAC Channel Interrupt Enable (CIE) Register. + */ + + sam_putdmach(xdmach, XDMAC_CHINT_BI | XDMAC_CHINT_ERRORS, + SAM_XDMACH_CIE_OFFSET); + + /* Enable the Channel Interrupt Enable bit by setting the corresponding + * bit in the XDMAC Global Interrupt Enable (GIE) Register. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GIE_OFFSET); + + /* 9. Enable the channel by setting the corresponding bit in the + * XDMAC Global Channel Enable (GE) Register. The channel bit will + * be set in the GS register by hardware. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GE_OFFSET); + + /* 10. The DMA has been started. Once completed, the DMA channel sets the + * corresponding "End of Block Interrupt" Status bit in the channel + * CIS register and generates an global interrupt for the channel. + * The channel bit will be cleared in the GS register by hardware. + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_multiple + * + * Description: + * Start a multiple buffer DMA. + * + ****************************************************************************/ + +static inline int sam_multiple(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); +#ifdef CONFIG_DEBUG + struct chnext_view1_s *llhead = xdmach->llhead; +#endif + uintptr_t paddr; + uint32_t regval; + + DEBUGASSERT(llhead != NULL && llhead->csa != 0); + + /* 1. Read the XDMAC Global Channel Status Register (XDMAC_GS) to choose a + * free channel. + * + * In this implementation, the free channel is assigned in a different + * manner. + */ + + /* 2. Clear any pending interrupts from any previous XDMAC transfer by + * reading the XDMAC Channel Interrupt Status Register (CIS). + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* 3. Build a linked list of transfer descriptors in memory. The + * descriptor view is programmable on a per descriptor basis. The + * linked list items structure must be word aligned. CUBC NDE + * must be configured to 0 in the last descriptor to terminate the + * list. + * + * This was done during the RX/TX setup phases of the DMA transfer. + */ + + /* Since we are using view1, I imagine that we need to set the Channel + * Control (CC) Register. + */ + + sam_putdmach(xdmach, xdmach->cc, SAM_XDMACH_CC_OFFSET); + + /* 4. Program field NDA in the XDMAC Channel Next Descriptor Address + * (CNDA) Register with the first descriptor address and bit NDAIF + * with the master interface identifier. + * + * REVIST: Using NDAIF=0. Is that correct? + */ + + paddr = sam_physramaddr((uintptr_t)xdmach->llhead); + sam_putdmach(xdmach, (uint32_t)paddr, SAM_XDMACH_CNDA_OFFSET); + + /* 5. Program the CNDC register: + * + * a. Set NDE to enable the descriptor fetch. + * b. Set NDSUP to update the source address at the descriptor fetch + * time, otherwise clear this bit. + * c. Set NDDUP to update the destination address at the descriptor + * fetch time, otherwise clear this bit. + * d. Program the NDVIEW field to define the length of the first + * descriptor. + */ + + regval = (XDMACH_CNDC_NDE | XDMACH_CNDC_NDVIEW_NDV2); + + /* Update the source address if this is a memory-to-* transfer. + * + * TYPE = 0 -> memory-to-memory + * TYPE = 1 && DSYNC = 1 -> memory-to-peripheral + */ + + if ((xdmach->cc & XDMACH_CC_TYPE) == 0 || + (xdmach->cc & XDMACH_CC_DSYNC) != 0) + { + regval |= XDMACH_CNDC_NDSUP; + } + + /* Update the destination address if this is a *-to-memory transfer. + * + * TYPE = 0 -> memory-to-memory + * TYPE = 1 && DSYNC = 0 -> peripheral-to-memory + */ + + if ((xdmach->cc & XDMACH_CC_TYPE) == 0 || + (xdmach->cc & XDMACH_CC_TYPE) == 0) + { + regval |= XDMACH_CNDC_NDDUP; + } + + sam_putdmach(xdmach, regval, SAM_XDMACH_CNDC_OFFSET); + + /* 6. Enable the End of Linked List interrupt by setting the LI bit in the + * CIE register. + */ + + sam_putdmach(xdmach, XDMAC_CHINT_LI | XDMAC_CHINT_ERRORS, + SAM_XDMACH_CIE_OFFSET); + + /* Enable the Channel Interrupt Enable bit by setting the corresponding + * bit in the XDMAC Global Interrupt Enable (GIE) Register. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GIE_OFFSET); + + /* 7. Enable the channel by setting the corresponding bit in the + * XDMAC Global Channel Enable (GE) Register. The channel bit will + * be set in the GS register by hardware. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GE_OFFSET); + + /* 8. The DMA has been started. Once completed, the DMA channel sets the + * corresponding "End of Block Interrupt" Status bit in the channel + * CIS register and generates an global interrupt for the channel. + * The channel bit will be cleared in the GS register by hardware. + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void sam_dmaterminate(struct sam_xdmach_s *xdmach, int result) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + uint32_t chanbit = XDMAC_CHAN(xdmach->chan); + + /* Disable all channel interrupts */ + + sam_putdmac(xdmac, chanbit, SAM_XDMAC_GID_OFFSET); + sam_putdmach(xdmach, XDMAC_CHINT_ALL, SAM_XDMACH_CID_OFFSET); + + /* Under normal operation, the software enables a channel by setting the + * associated bit in the Global Channel Enable (GE) Register. The hardware + * then disables a channel on transfer completion by clearing channel bit + * in the GS register. To disable a channel, setting the channel bit in the + * GD register and poll the channel bit in GS register to determine when + * the channel has been disabled. + */ + + sam_putdmac(xdmac, chanbit, SAM_XDMAC_GD_OFFSET); + while ((sam_getdmac(xdmac, SAM_XDMAC_GS_OFFSET) & chanbit) != 0); + + /* Free the linklist */ + + sam_freelinklist(xdmach); + + /* If this was an RX DMA (peripheral-to-memory), then invalidate the cache + * to force reloads from memory. + */ + + if (xdmach->rx) + { + arch_invalidate_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize); + } + + /* Perform the DMA complete callback */ + + if (xdmach->callback) + { + xdmach->callback((DMA_HANDLE)xdmach, xdmach->arg, result); + } + + xdmach->callback = NULL; + xdmach->arg = NULL; +} + +/**************************************************************************** + * Name: sam_xdmac_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int sam_xdmac_interrupt(struct sam_xdmac_s *xdmac) +{ + struct sam_xdmach_s *xdmach; + unsigned int chndx; + uint32_t gpending; + uint32_t chpending; + uint32_t bit; + + /* Get the set of pending, unmasked global XDMAC interrupts */ + + gpending = sam_getdmac(xdmac, SAM_XDMAC_GIS_OFFSET) & + sam_getdmac(xdmac, SAM_XDMAC_GIM_OFFSET); + + /* Yes.. Check each bit to see which channel(s) have interrupted */ + + for (chndx = 0; chndx < SAM_NDMACHAN && gpending != 0; chndx++) + { + /* Are any interrupts pending for this channel? */ + + bit = XDMAC_CHAN(chndx); + if ((gpending & bit) != 0) + { + xdmach = &xdmac->xdmach[chndx]; + + /* Get the set of interrupts pending for this channel */ + + chpending = sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET) & + sam_getdmach(xdmach, SAM_XDMACH_CIM_OFFSET); + + /* Yes.. Did an error occur? */ + + if ((chpending & XDMAC_CHINT_ERRORS) != 0) + { + /* Yes... Terminate the transfer with an error? */ + + dmalldbg("ERROR: DMA failed: %08x\n", chpending); + sam_dmaterminate(xdmach, -EIO); + } + + /* Is the transfer complete? */ + + else if ((chpending & (XDMAC_CHINT_BI | XDMAC_CHINT_LI)) != 0) + { + /* Yes.. Terminate the transfer with success */ + + sam_dmaterminate(xdmach, OK); + } + + /* Else what? */ + + else + { + dmalldbg("ERROR: Unexpected interrupt: %08x\n", chpending); + DEBUGPANIC(); + } + + /* Clear the bit in the sampled set of pending global interrupts */ + + gpending &= !bit; + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_xdmac0_interrupt and sam_xdmac1_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_XDMAC0 +static int sam_xdmac0_interrupt(int irq, void *context) +{ + return sam_xdmac_interrupt(&g_xdmac0); +} +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 +static int sam_xdmac1_interrupt(int irq, void *context) +{ + return sam_xdmac_interrupt(&g_xdmac1); +} +#endif + +/**************************************************************************** + * Name: sam_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmainitialize(struct sam_xdmac_s *xdmac) +{ + /* Disable all DMA interrupts */ + + sam_putdmac(xdmac, XDMAC_CHAN_ALL, SAM_XDMAC_GID_OFFSET); + + /* Disable all DMA channels */ + + sam_putdmac(xdmac, XDMAC_CHAN_ALL, SAM_XDMAC_GD_OFFSET); + + /* Initialize semaphores */ + + sem_init(&xdmac->chsem, 0, 1); + sem_init(&xdmac->dsem, 0, SAM_NDMACHAN); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ +#ifdef CONFIG_SAMA5_XDMAC0 + dmallvdbg("Initialize XDMAC0\n"); + + /* Enable peripheral clock */ + + sam_xdmac0_enableclk(); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_XDMAC0, sam_xdmac0_interrupt); + + /* Initialize the controller */ + + sam_dmainitialize(&g_xdmac0); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_XDMAC0); +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 + dmallvdbg("Initialize XDMAC1\n"); + + /* Enable peripheral clock */ + + sam_xdmac1_enableclk(); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_XDMAC1, sam_xdmac1_interrupt); + + /* Initialize the controller */ + + sam_dmainitialize(&g_xdmac1); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_XDMAC1); +#endif +} + +/**************************************************************************** + * Name: sam_dmachannel + * + * Allocate a DMA channel. This function sets aside a DMA channel then + * gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. Howerver, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* + * DMA channel handle. NULL is returned on any failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags) +{ + struct sam_xdmac_s *xdmac; + struct sam_xdmach_s *xdmach; + unsigned int chndx; + + /* Pick the DMA controller */ + +#ifdef CONFIG_SAMA5_XDMAC0 + if (dmacno == 0) + { + xdmac = &g_xdmac0; + } + else +#endif + +#ifdef CONFIG_SAMA5_XDMAC1 + if (dmacno == 1) + { + xdmac = &g_xdmac1; + } + else +#endif + + { + dmadbg("ERROR: Bad XDMAC number: %d\n", dmacno); + DEBUGPANIC(); + return (DMA_HANDLE)NULL; + } + + /* Search for an available DMA channel with at least the requested FIFO + * size. + */ + + xdmach = NULL; + sam_takechsem(xdmac); + for (chndx = 0; chndx < SAM_NDMACHAN; chndx++) + { + struct sam_xdmach_s *candidate = &xdmac->xdmach[chndx]; + if (!candidate->inuse) + { + xdmach = candidate; + xdmach->inuse = true; + + /* Clear the pending Interrupt Status bits by reading the XDMAC + * Channel Interrupt Status (CIS) Register + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* Disable the channel by writing one to the write-only Global + * Channel Disable (GD) Register + */ + + sam_putdmac(xdmac, XDMAC_CHAN(chndx), SAM_XDMAC_GD_OFFSET); + + /* Set the DMA channel flags. */ + + xdmach->flags = chflags; + break; + } + } + + sam_givechsem(xdmac); + + /* Show the result of the allocation */ + + if (xdmach) + { + dmavdbg("XDMAC%d CH%d: chflags: %08x returning xdmach: %p\n", + (int)dmacno, xdmach->chan, (int)chflags, xdmach); + } + else + { + dmadbg("ERROR: Failed allocate XDMAC%d channel\n", (int)dmacno); + } + + return (DMA_HANDLE)xdmach; +} + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + + /* Set the new DMA channel flags. */ + + xdmach->flags = chflags; + +#if defined(CONFIG_SAMA5_XDMAC0) && defined(CONFIG_SAMA5_XDMAC1) + dmavdbg("XDMAC%d CH%d: chflags: %08x\n", + xdmach->xdmac, xdmach->chan, (int)chflags); +#elif defined(CONFIG_SAMA5_XDMAC0) + dmavdbg("XDMAC0 CH%d: chflags: %08x\n", + xdmach->chan, (int)chflags); +#else + dmavdbg("XDMAC1 CH%d: chflags: %08x\n", + xdmach->chan, (int)chflags); +#endif +} + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + struct sam_xdmac_s *xdmac; + + dmavdbg("xdmach: %p\n", xdmach); + DEBUGASSERT((xdmach != NULL) && (xdmach->inuse)); + + xdmac = sam_controller(xdmach); + + /* Make sure that the channel is disabled by writing one to the write-only + * Global Channel Disable (GD) Register + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GD_OFFSET); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + xdmach->flags = 0; + xdmach->inuse = false; /* No longer in use */ +} + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("xdmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + xdmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(xdmach); + dmavdbg("llhead: %p lltail: %p\n", xdmach->llhead, xdmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(xdmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_txbuffer(xdmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_txbuffer(xdmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was not an RX transfer. + */ + + xdmach->rx = false; + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("xdmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + xdmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(xdmach); + dmavdbg("llhead: %p lltail: %p\n", xdmach->llhead, xdmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(xdmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_rxbuffer(xdmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_rxbuffer(xdmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was an RX transfer and will invalidate the cache. + */ + + xdmach->rx = true; + xdmach->rxaddr = maddr; + xdmach->rxsize = (xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0 ? nbytes : sizeof(uint32_t); + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + int ret = -EINVAL; + + dmavdbg("xdmach: %p callback: %p arg: %p\n", xdmach, callback, arg); + DEBUGASSERT(xdmach != NULL); + + /* Verify that the DMA has been setup (i.e., at least one entry in the + * link list). + */ + + if (xdmach->llhead) + { + /* Save the callback info. This will be invoked whent the DMA commpletes */ + + xdmach->callback = callback; + xdmach->arg = arg; + + /* Is this a single block transfer? Or a multiple block transfer? */ + + if (xdmach->llhead == xdmach->lltail) + { + ret = sam_single(xdmach); + } + else + { + ret = sam_multiple(xdmach); + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + irqstate_t flags; + + dmavdbg("xdmach: %p\n", xdmach); + DEBUGASSERT(xdmach != NULL); + + flags = enter_critical_section(); + sam_dmaterminate(xdmach, -EINTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + irqstate_t flags; + + /* Sample global registers. NOTE: reading GIS clears interrupts, but + * that should be okay IF interrupts are enabled when this function is + * called. But there is a race condition where this instrumentation could + * cause lost interrupts. + */ + + flags = enter_critical_section(); + + regs->gtype = sam_getdmac(xdmac, SAM_XDMAC_GTYPE_OFFSET); + regs->gcfg = sam_getdmac(xdmac, SAM_XDMAC_GCFG_OFFSET); + regs->gwac = sam_getdmac(xdmac, SAM_XDMAC_GWAC_OFFSET); + regs->gim = sam_getdmac(xdmac, SAM_XDMAC_GIM_OFFSET); + regs->gis = sam_getdmac(xdmac, SAM_XDMAC_GIS_OFFSET); + regs->gs = sam_getdmac(xdmac, SAM_XDMAC_GS_OFFSET); + regs->grs = sam_getdmac(xdmac, SAM_XDMAC_GRS_OFFSET); + regs->gws = sam_getdmac(xdmac, SAM_XDMAC_GWS_OFFSET); + regs->gsws = sam_getdmac(xdmac, SAM_XDMAC_GSWS_OFFSET); + + /* Sample channel registers */ + + regs->cim = sam_getdmach(xdmach, SAM_XDMACH_CIM_OFFSET); + regs->cis = sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + regs->csa = sam_getdmach(xdmach, SAM_XDMACH_CSA_OFFSET); + regs->cda = sam_getdmach(xdmach, SAM_XDMACH_CDA_OFFSET); + regs->cnda = sam_getdmach(xdmach, SAM_XDMACH_CNDA_OFFSET); + regs->cndc = sam_getdmach(xdmach, SAM_XDMACH_CNDC_OFFSET); + regs->cubc = sam_getdmach(xdmach, SAM_XDMACH_CUBC_OFFSET); + regs->cbc = sam_getdmach(xdmach, SAM_XDMACH_CBC_OFFSET); + regs->cc = sam_getdmach(xdmach, SAM_XDMACH_CC_OFFSET); + regs->cdsmsp = sam_getdmach(xdmach, SAM_XDMACH_CDSMSP_OFFSET); + regs->csus = sam_getdmach(xdmach, SAM_XDMACH_CSUS_OFFSET); + regs->cdus = sam_getdmach(xdmach, SAM_XDMACH_CDUS_OFFSET); + + leave_critical_section(flags); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + + dmadbg("%s\n", msg); + dmadbg(" DMA Global Registers:\n"); + dmadbg(" GTYPE[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GTYPE_OFFSET, regs->gtype); + dmadbg(" GCFG[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GCFG_OFFSET, regs->gcfg); + dmadbg(" GWAC[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GWAC_OFFSET, regs->gwac); + dmadbg(" GIM[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GIM_OFFSET, regs->gim); + dmadbg(" GIS[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GIS_OFFSET, regs->gis); + dmadbg(" GS[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GS_OFFSET, regs->gs); + dmadbg(" GRS[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GRS_OFFSET, regs->grs); + dmadbg(" GWS[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GWS_OFFSET, regs->gws); + dmadbg(" GSWS[%08x]: %08x\n", xdmac->base + SAM_XDMAC_GSWS_OFFSET, regs->gsws); + dmadbg(" DMA Channel Registers:\n"); + dmadbg(" CIM[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CIM_OFFSET, regs->cim); + dmadbg(" CIS[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CIS_OFFSET, regs->cis); + dmadbg(" CSA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CSA_OFFSET, regs->csa); + dmadbg(" CDA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDA_OFFSET, regs->cda); + dmadbg(" CNDA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CNDA_OFFSET, regs->cnda); + dmadbg(" CNDC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CNDC_OFFSET, regs->cndc); + dmadbg(" CUBC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CUBC_OFFSET, regs->cubc); + dmadbg(" CBC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CBC_OFFSET, regs->cbc); + dmadbg(" CC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CC_OFFSET, regs->cc); + dmadbg(" CDSMSP[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDSMSP_OFFSET, regs->cdsmsp); + dmadbg(" CSUS[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CSUS_OFFSET, regs->csus); + dmadbg(" CDUS[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDUS_OFFSET, regs->cdus); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_SAMA5_XDMAC0 || CONFIG_SAMA5_XDMAC1 */ diff --git a/arch/arm/src/sama5/sama5d2x_memorymap.c b/arch/arm/src/sama5/sama5d2x_memorymap.c new file mode 100644 index 0000000000000000000000000000000000000000..e73281cabd2f1f609febb8a00b00f0bd789b075e --- /dev/null +++ b/arch/arm/src/sama5/sama5d2x_memorymap.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * arch/arm/src/sama5/sama5d2x_memorymap.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "mmu.h" + +#include "chip/sam_memorymap.h" +#include "sam_lcd.h" +#include "sam_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical + * address space of the SAMA5. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +const struct section_mapping_s g_section_mapping[] = +{ + /* SAMA5 Internal Memories */ + + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are three ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. A second way is to map the use the AXI MATRIX remap register to + * map physical address zero to the beginning of the text region, + * either internal SRAM or EBI CS 0. Then we can set an identity + * mapping to map the boot region at 0x0000:0000 to virtual address + * 0x0000:00000. VBAR == 0x0000:0000. + * + * This method is used when booting from ISRAM or NOR FLASH. In + * that case, vectors must lie at the beginning of NOFR FLASH. + * + * 3. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * This is the method used when booting from SDRAM. + * + * The system always boots from the ROM memory at address 0x0. After + * reset, and until the Remap command is performed, the SRAM is accessible + * at address 0x0020 0000. When the AXI Bus Matrix is remapped, the SRAM is + * also available at address 0x0. + * + * If we are executing out of ISRAM, then the SAMA5 primary bootloader + * probably copied us into ISRAM and set the AXI REMAP0 bit for us. + * + * If we are executing from external SDRAM, then a secondary bootloader must + * have loaded us into SDRAM. In this case, simply set the VBAR register + * to the address of the vector table (not necessary at the beginning + * or SDRAM). + */ + +#ifdef CONFIG_ARCH_LOWVECTORS + { SAM_SRAMREMAP_PSECTION, SAM_SRAMREMAP_VSECTION, + SAM_SRAMREMAP_MMUFLAGS, SAM_SRAMREMAP_NSECTIONS + }, +#endif + + { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION, + SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS + }, + +#ifndef CONFIG_PAGING /* Internal SRAM is already fully mapped */ + { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION, + SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS + }, +#endif + + { SAM_UDPHSRAM_PSECTION, SAM_UDPHSRAM_VSECTION, + SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS + }, + { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION, + SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS + }, + { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION, + SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS + }, + { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION, + SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS + }, + { SAM_DAP_PSECTION, SAM_DAP_VSECTION, + SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS + }, + +#if defined(CONFIG_ARCH_CHIP_SAMA5D2) && defined(CONFIG_ARCH_L2CACHE) + /* The SAMA5D2 features a second 128-Kbyte SRAM that can be allocated + * either to the L2 cache controller or used as an internal SRAM. After + * reset, this block is connected to the L2 cache controller. The + * SRAM_SEL bit, located in the SFR_L2CC_HRAMC register, is used to + * reassign this memory as system SRAM, making the two 128-Kbyte + * RAMs contiguous. + */ + + { SAM_L2CC_PSECTION, SAM_L2CC_VSECTION, + SAM_L2CC_MMUFLAGS, SAM_L2CC_NSECTIONS + }, +#endif + + /* SAMA5 CS0 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS0 + { SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION, + SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS + }, +#endif + + /* SAMA5 External SDRAM Memory. The SDRAM is not usable until it has been + * initialized. If we are running out of SDRAM now, we can assume that some + * second level boot loader has properly configured SRAM for us. In that + * case, we set the MMU flags for the final, fully cache-able state. + * + * Also, in this case, the mapping for the SDRAM was done in arm_head.S and + * need not be repeated here. + * + * If we are running from ISRAM or NOR flash, then we will need to configure + * the SDRAM ourselves. In this case, we set the MMU flags to the strongly + * ordered, non-cacheable state. We need this direct access to SDRAM in + * order to configure it. Once SDRAM has been initialized, it will be re- + * configured in its final state. + */ + +#ifdef NEED_SDRAM_MAPPING + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + MMU_STRONGLY_ORDERED, SAM_DDRCS_NSECTIONS + }, + { SAM_DDRAESCS_PSECTION, SAM_DDRAESCS_VSECTION, + MMU_STRONGLY_ORDERED, SAM_DDRAESCS_NSECTIONS + }, +#endif + + /* SAMA5 CS1-3 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS1 + { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, + SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS2 + { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, + SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS3 + { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION, + SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_QSPI0AES + { SAM_QSPI0AES_PSECTION, SAM_QSPI0AES_VSECTION, + SAM_QSPI0AES_MMUFLAGS, SAM_QSPI0AES_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_QSPI1AES + { SAM_QSPI1AES_PSECTION, SAM_QSPI1AES_VSECTION, + SAM_QSPI1AES_MMUFLAGS, SAM_QSPI1AES_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_SDMMC0 + { SAM_SDMMC0_PSECTION, SAM_SDMMC0_VSECTION, + SAM_SDMMC0_MMUFLAGS, SAM_SDMMC0_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_SDMMC1 + { SAM_SDMMC1_PSECTION, SAM_SDMMC1_VSECTION, + SAM_SDMMC1_MMUFLAGS, SAM_SDMMC1_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_HAVE_NAND + { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION, + SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_QSPI0 + { SAM_QSPI0_PSECTION, SAM_QSPI0_VSECTION, + SAM_QSPI0_MMUFLAGS, SAM_QSPI0_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_QSPI1 + { SAM_QSPI1_PSECTION, SAM_QSPI1_VSECTION, + SAM_QSPI1_MMUFLAGS, SAM_QSPI1_NSECTIONS + }, +#endif + + /* SAMA5 Internal Peripherals + * + * Naming of peripheral sections differs between the SAMA5D3 and SAMA5D4. + * There is nothing called SYSC in the SAMA5D4 memory map. The third + * peripheral section is un-named in the SAMA5D4 memory map, but I have + * chosen the name PERIPHC for this usage. + */ + + { SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION, + SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS + }, + { SAM_PERIPHB_PSECTION, SAM_PERIPHB_VSECTION, + SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS + }, + { SAM_PERIPHC_PSECTION, SAM_PERIPHC_VSECTION, + SAM_PERIPHC_MMUFLAGS, SAM_PERIPHC_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + * + * If SDRAM will be reconfigured, then we will defer setup of the framebuffer + * until after the SDRAM remapping (since the framebuffer problem resides) in + * SDRAM. + */ + +#if defined(CONFIG_SAMA5_LCDC) && !defined(NEED_SDRAM_REMAPPING) + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the mapping table */ + +#define NMAPPINGS \ + (sizeof(g_section_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_mappings = NMAPPINGS; + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +const struct section_mapping_s g_operational_mapping[] = +{ + /* This entry reprograms the SDRAM entry, making it cacheable and + * bufferable. + */ + + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS + }, + { SAM_DDRAESCS_PSECTION, SAM_DDRAESCS_VSECTION, + SAM_DDRAESCS_MMUFLAGS, SAM_DDRAESCS_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + */ + +#ifdef CONFIG_SAMA5_LCDC + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the operational mapping table */ + +#define NREMAPPINGS \ + (sizeof(g_operational_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_opmappings = NREMAPPINGS; + +#endif /* NEED_SDRAM_REMAPPING */ diff --git a/arch/arm/src/sama5/sama5d2x_periphclks.h b/arch/arm/src/sama5/sama5d2x_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..181169634ea7a3f4078d1ce1a3d45af458cefc4c --- /dev/null +++ b/arch/arm/src/sama5/sama5d2x_periphclks.h @@ -0,0 +1,303 @@ +/************************************************************************************ + * arch/arm/src/sama5/sama5d2x_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAMAD52X_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMA5_SAMAD52X_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) +#define sam_isenabled0(s) (getreg32(SAM_PMC_PCER0) & (1 << (s)) != 0) +#define sam_isenabled1(s) (getreg32(SAM_PMC_PCER1) & (1 << ((s) - 32)) != 0) + +#define sam_fiq_enableclk() /* No peripheral clock */ +#define sam_arm_enableclk() /* No peripheral clock */ +#define sam_pit_enableclk() sam_enableperiph0(SAM_PID_PIT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_emac0_enableclk() sam_enableperiph0(SAM_PID_EMAC0) +#define sam_xdmac0_enableclk() sam_enableperiph0(SAM_PID_XDMAC0) +#define sam_xdmac1_enableclk() sam_enableperiph0(SAM_PID_XDMAC1) +#define sam_icm_enableclk() sam_enableperiph0(SAM_PID_ICM) +#define sam_aes_enableclk() sam_enableperiph0(SAM_PID_AES) +#define sam_aesb_enableclk() sam_enableperiph0(SAM_PID_AESB) +#define sam_tdes_enableclk() sam_enableperiph0(SAM_PID_TDES) +#define sam_sha_enableclk() sam_enableperiph0(SAM_PID_SHA) +#define sam_mpddrc_enableclk() sam_enableperiph0(SAM_PID_MPDDRC) +#define sam_matrix1_enableclk() sam_enableperiph0(SAM_PID_MATRIX1) +#define sam_matrix0_enableclk() sam_enableperiph0(SAM_PID_MATRIX0) +#define sam_secumod_enableclk() sam_enableperiph0(SAM_PID_SECUMOD) +#define sam_hsmc_enableclk() sam_enableperiph0(SAM_PID_HSMC) +#define sam_pio_enableclk() sam_enableperiph0(SAM_PID_PIO) +#define sam_flexcom0_enableclk() sam_enableperiph0(SAM_PID_FLEXCOM0) +#define sam_flexcom1_enableclk() sam_enableperiph0(SAM_PID_FLEXCOM1) +#define sam_flexcom2_enableclk() sam_enableperiph0(SAM_PID_FLEXCOM2) +#define sam_flexcom3_enableclk() sam_enableperiph0(SAM_PID_FLEXCOM3) +#define sam_flexcom4_enableclk() sam_enableperiph0(SAM_PID_FLEXCOM4) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_uart2_enableclk() sam_enableperiph0(SAM_PID_UART2) +#define sam_uart3_enableclk() sam_enableperiph0(SAM_PID_UART3) +#define sam_uart4_enableclk() sam_enableperiph0(SAM_PID_UART4) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_sdmmc0_enableclk() sam_enableperiph0(SAM_PID_SDMMC0) + +#define sam_sdmmc1_enableclk() sam_enableperiph1(SAM_PID_SDMMC1) +#define sam_spi0_enableclk() sam_enableperiph1(SAM_PID_SPI0) +#define sam_spi1_enableclk() sam_enableperiph1(SAM_PID_SPI1) +#define sam_tc0_enableclk() sam_enableperiph1(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph1(SAM_PID_TC1) +#define sam_pwm_enableclk() sam_enableperiph1(SAM_PID_PWM) +#define sam_adc_enableclk() sam_enableperiph1(SAM_PID_ADC) +#define sam_uhphs_enableclk() sam_enableperiph1(SAM_PID_UHPHS) +#define sam_udphs_enableclk() sam_enableperiph1(SAM_PID_UDPHS) +#define sam_ssc0_enableclk() sam_enableperiph1(SAM_PID_SSC0) +#define sam_ssc1_enableclk() sam_enableperiph1(SAM_PID_SSC1) +#define sam_lcdc_enableclk() sam_enableperiph1(SAM_PID_LCDC) +#define sam_isc_enableclk() sam_enableperiph1(SAM_PID_ISC) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_pdmic_enableclk() sam_enableperiph1(SAM_PID_PDMIC) +#define sam_irqid_enableclk() sam_enableperiph1(SAM_PID_IRQID) +#define sam_sfc_enableclk() sam_enableperiph1(SAM_PID_SFC) +#define sam_securam_enableclk() sam_enableperiph1(SAM_PID_SECURAM) +#define sam_qspi0_enableclk() sam_enableperiph1(SAM_PID_QSPI0) +#define sam_qspi1_enableclk() sam_enableperiph1(SAM_PID_QSPI1) +#define sam_i2sc0_enableclk() sam_enableperiph1(SAM_PID_I2SC0) +#define sam_i2sc1_enableclk() sam_enableperiph1(SAM_PID_I2SC1) +#define sam_mcan0_enableclk() sam_enableperiph1(SAM_PID_MCAN00) +#define sam_mcan1_enableclk() sam_enableperiph1(SAM_PID_MCAN10) +#define sam_classd_enableclk() sam_enableperiph1(SAM_PID_CLASSD) +#define sam_sfr_enableclk() sam_enableperiph1(SAM_PID_SFR) +#define sam_saic_enableclk() sam_enableperiph1(SAM_PID_SAIC) +#define sam_aic_enableclk() sam_enableperiph1(SAM_PID_AIC) + +#define sam_piob_enableclk() /* No peripheral clock */ +#define sam_pioc_enableclk() /* No peripheral clock */ +#define sam_piod_enableclk() /* No peripheral clock */ +#define sam_sys_enableclk() /* No peripheral clock */ +#define sam_acc_enableclk() /* No peripheral clock */ +#define sam_rxlp_enableclk() /* No peripheral clock */ +#define sam_sfrbu_enableclk() /* No peripheral clock */ +#define sam_chipid_enableclk() /* No peripheral clock */ + +#define sam_fiq_disableclk() /* No peripheral clock */ +#define sam_arm_disableclk() /* No peripheral clock */ +#define sam_pit_disableclk() sam_disableperiph0(SAM_PID_PIT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_emac0_disableclk() sam_disableperiph0(SAM_PID_EMAC0) +#define sam_xdmac0_disableclk() sam_disableperiph0(SAM_PID_XDMAC0) +#define sam_xdmac1_disableclk() sam_disableperiph0(SAM_PID_XDMAC1) +#define sam_icm_disableclk() sam_disableperiph0(SAM_PID_ICM) +#define sam_aes_disableclk() sam_disableperiph0(SAM_PID_AES) +#define sam_aesb_disableclk() sam_disableperiph0(SAM_PID_AESB) +#define sam_tdes_disableclk() sam_disableperiph0(SAM_PID_TDES) +#define sam_sha_disableclk() sam_disableperiph0(SAM_PID_SHA) +#define sam_mpddrc_disableclk() sam_disableperiph0(SAM_PID_MPDDRC) +#define sam_matrix1_disableclk() sam_disableperiph0(SAM_PID_MATRIX1) +#define sam_matrix0_disableclk() sam_disableperiph0(SAM_PID_MATRIX0) +#define sam_secumod_disableclk() sam_disableperiph0(SAM_PID_SECUMOD) +#define sam_hsmc_disableclk() sam_disableperiph0(SAM_PID_HSMC) +#define sam_pio_disableclk() sam_disableperiph0(SAM_PID_PIO) +#define sam_flexcom0_disableclk() sam_disableperiph0(SAM_PID_FLEXCOM0) +#define sam_flexcom1_disableclk() sam_disableperiph0(SAM_PID_FLEXCOM1) +#define sam_flexcom2_disableclk() sam_disableperiph0(SAM_PID_FLEXCOM2) +#define sam_flexcom3_disableclk() sam_disableperiph0(SAM_PID_FLEXCOM3) +#define sam_flexcom4_disableclk() sam_disableperiph0(SAM_PID_FLEXCOM4) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_uart2_disableclk() sam_disableperiph0(SAM_PID_UART2) +#define sam_uart3_disableclk() sam_disableperiph0(SAM_PID_UART3) +#define sam_uart4_disableclk() sam_disableperiph0(SAM_PID_UART4) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_sdmmc0_disableclk() sam_disableperiph0(SAM_PID_SDMMC0) + +#define sam_sdmmc1_disableclk() sam_disableperiph1(SAM_PID_SDMMC1) +#define sam_spi0_disableclk() sam_disableperiph1(SAM_PID_SPI0) +#define sam_spi1_disableclk() sam_disableperiph1(SAM_PID_SPI1) +#define sam_tc0_disableclk() sam_disableperiph1(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph1(SAM_PID_TC1) +#define sam_pwm_disableclk() sam_disableperiph1(SAM_PID_PWM) +#define sam_adc_disableclk() sam_disableperiph1(SAM_PID_ADC) +#define sam_uhphs_disableclk() sam_disableperiph1(SAM_PID_UHPHS) +#define sam_udphs_disableclk() sam_disableperiph1(SAM_PID_UDPHS) +#define sam_ssc0_disableclk() sam_disableperiph1(SAM_PID_SSC0) +#define sam_ssc1_disableclk() sam_disableperiph1(SAM_PID_SSC1) +#define sam_lcdc_disableclk() sam_disableperiph1(SAM_PID_LCDC) +#define sam_isc_disableclk() sam_disableperiph1(SAM_PID_ISC) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_pdmic_disableclk() sam_disableperiph1(SAM_PID_PDMIC) +#define sam_irqid_disableclk() sam_disableperiph1(SAM_PID_IRQID) +#define sam_sfc_disableclk() sam_disableperiph1(SAM_PID_SFC) +#define sam_securam_disableclk() sam_disableperiph1(SAM_PID_SECURAM) +#define sam_qspi0_disableclk() sam_disableperiph1(SAM_PID_QSPI0) +#define sam_qspi1_disableclk() sam_disableperiph1(SAM_PID_QSPI1) +#define sam_i2sc0_disableclk() sam_disableperiph1(SAM_PID_I2SC0) +#define sam_i2sc1_disableclk() sam_disableperiph1(SAM_PID_I2SC1) +#define sam_mcan0_disableclk() sam_disableperiph1(SAM_PID_MCAN00) +#define sam_mcan1_disableclk() sam_disableperiph1(SAM_PID_MCAN10) +#define sam_classd_disableclk() sam_disableperiph1(SAM_PID_CLASSD) +#define sam_sfr_disableclk() sam_disableperiph1(SAM_PID_SFR) +#define sam_saic_disableclk() sam_disableperiph1(SAM_PID_SAIC) +#define sam_aic_disableclk() sam_disableperiph1(SAM_PID_AIC) + +#define sam_piob_disableclk() /* No peripheral clock */ +#define sam_pioc_disableclk() /* No peripheral clock */ +#define sam_piod_disableclk() /* No peripheral clock */ +#define sam_sys_disableclk() /* No peripheral clock */ +#define sam_acc_disableclk() /* No peripheral clock */ +#define sam_rxlp_disableclk() /* No peripheral clock */ +#define sam_sfrbu_disableclk() /* No peripheral clock */ +#define sam_chipid_disableclk() /* No peripheral clock */ + +#define sam_fiq_isenabled() (false) /* No peripheral clock */ +#define sam_arm_isenabled() (false) /* No peripheral clock */ +#define sam_pit_isenabled() sam_isenabled0(SAM_PID_PIT) +#define sam_wdt_isenabled() sam_isenabled0(SAM_PID_WDT) +#define sam_emac0_isenabled() sam_isenabled0(SAM_PID_EMAC0) +#define sam_xdmac0_isenabled() sam_isenabled0(SAM_PID_XDMAC0) +#define sam_xdmac1_isenabled() sam_isenabled0(SAM_PID_XDMAC1) +#define sam_icm_isenabled() sam_isenabled0(SAM_PID_ICM) +#define sam_aes_isenabled() sam_isenabled0(SAM_PID_AES) +#define sam_aesb_isenabled() sam_isenabled0(SAM_PID_AESB) +#define sam_tdes_isenabled() sam_isenabled0(SAM_PID_TDES) +#define sam_sha_isenabled() sam_isenabled0(SAM_PID_SHA) +#define sam_mpddrc_isenabled() sam_isenabled0(SAM_PID_MPDDRC) +#define sam_matrix1_isenabled() sam_isenabled0(SAM_PID_MATRIX1) +#define sam_matrix0_isenabled() sam_isenabled0(SAM_PID_MATRIX0) +#define sam_secumod_isenabled() sam_isenabled0(SAM_PID_SECUMOD) +#define sam_hsmc_isenabled() sam_isenabled0(SAM_PID_HSMC) +#define sam_pio_isenabled() sam_isenabled0(SAM_PID_PIO) +#define sam_flexcom0_isenabled() sam_isenabled0(SAM_PID_FLEXCOM0) +#define sam_flexcom1_isenabled() sam_isenabled0(SAM_PID_FLEXCOM1) +#define sam_flexcom2_isenabled() sam_isenabled0(SAM_PID_FLEXCOM2) +#define sam_flexcom3_isenabled() sam_isenabled0(SAM_PID_FLEXCOM3) +#define sam_flexcom4_isenabled() sam_isenabled0(SAM_PID_FLEXCOM4) +#define sam_uart0_isenabled() sam_isenabled0(SAM_PID_UART0) +#define sam_uart1_isenabled() sam_isenabled0(SAM_PID_UART1) +#define sam_uart2_isenabled() sam_isenabled0(SAM_PID_UART2) +#define sam_uart3_isenabled() sam_isenabled0(SAM_PID_UART3) +#define sam_uart4_isenabled() sam_isenabled0(SAM_PID_UART4) +#define sam_twi0_isenabled() sam_isenabled0(SAM_PID_TWI0) +#define sam_twi1_isenabled() sam_isenabled0(SAM_PID_TWI1) +#define sam_sdmmc0_isenabled() sam_isenabled0(SAM_PID_SDMMC0) + +#define sam_sdmmc1_isenabled() sam_isenabled1(SAM_PID_SDMMC1) +#define sam_spi0_isenabled() sam_isenabled1(SAM_PID_SPI0) +#define sam_spi1_isenabled() sam_isenabled1(SAM_PID_SPI1) +#define sam_tc0_isenabled() sam_isenabled1(SAM_PID_TC0) +#define sam_tc1_isenabled() sam_isenabled1(SAM_PID_TC1) +#define sam_pwm_isenabled() sam_isenabled1(SAM_PID_PWM) +#define sam_adc_isenabled() sam_isenabled1(SAM_PID_ADC) +#define sam_uhphs_isenabled() sam_isenabled1(SAM_PID_UHPHS) +#define sam_udphs_isenabled() sam_isenabled1(SAM_PID_UDPHS) +#define sam_ssc0_isenabled() sam_isenabled1(SAM_PID_SSC0) +#define sam_ssc1_isenabled() sam_isenabled1(SAM_PID_SSC1) +#define sam_lcdc_isenabled() sam_isenabled1(SAM_PID_LCDC) +#define sam_isc_isenabled() sam_isenabled1(SAM_PID_ISC) +#define sam_trng_isenabled() sam_isenabled1(SAM_PID_TRNG) +#define sam_pdmic_isenabled() sam_isenabled1(SAM_PID_PDMIC) +#define sam_irqid_isenabled() sam_isenabled1(SAM_PID_IRQID) +#define sam_sfc_isenabled() sam_isenabled1(SAM_PID_SFC) +#define sam_securam_isenabled() sam_isenabled1(SAM_PID_SECURAM) +#define sam_qspi0_isenabled() sam_isenabled1(SAM_PID_QSPI0) +#define sam_qspi1_isenabled() sam_isenabled1(SAM_PID_QSPI1) +#define sam_i2sc0_isenabled() sam_isenabled1(SAM_PID_I2SC0) +#define sam_i2sc1_isenabled() sam_isenabled1(SAM_PID_I2SC1) +#define sam_mcan0_isenabled() sam_isenabled1(SAM_PID_MCAN00) +#define sam_mcan1_isenabled() sam_isenabled1(SAM_PID_MCAN10) +#define sam_classd_isenabled() sam_isenabled1(SAM_PID_CLASSD) +#define sam_sfr_isenabled() sam_isenabled1(SAM_PID_SFR) +#define sam_saic_isenabled() sam_isenabled1(SAM_PID_SAIC) +#define sam_aic_isenabled() sam_isenabled1(SAM_PID_AIC) + +#define sam_piob_isenabled() (false) /* No peripheral clock */ +#define sam_pioc_isenabled() (false) /* No peripheral clock */ +#define sam_piod_isenabled() (false) /* No peripheral clock */ +#define sam_sys_isenabled() (false) /* No peripheral clock */ +#define sam_acc_isenabled() (false) /* No peripheral clock */ +#define sam_rxlp_isenabled() (false) /* No peripheral clock */ +#define sam_sfrbu_isenabled() (false) /* No peripheral clock */ +#define sam_chipid_isenabled() (false) /* No peripheral clock */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAMAD52X_PERIPHCLKS_H */ diff --git a/arch/arm/src/sama5/sama5d2x_pio.c b/arch/arm/src/sama5/sama5d2x_pio.c new file mode 100644 index 0000000000000000000000000000000000000000..d6daf15a82003fb57987c21d863e362e8988481d --- /dev/null +++ b/arch/arm/src/sama5/sama5d2x_pio.c @@ -0,0 +1,664 @@ +/**************************************************************************** + * arch/arm/src/sama5/sama5d2x_pio.c + * General Purpose Input/Output (PIO) logic for the SAMA5D2x + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/_sama5d2x_pio.h" + +#include "chip.h" +#include "sam_periphclks.h" +#include "sam_pio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Macros to convert a pin to a vanilla input */ + +#define PIO_INPUT_BITS (PIO_INPUT | PIO_CFG_DEFAULT) +#define MK_INPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | PIO_INPUT_BITS) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Lookup for non-secure PIOs */ + +const uintptr_t g_piobase[SAM_NPIO] = +{ + SAM_PIO_IOGROUPA_VBASE +#if SAM_NPIO > 1 + , SAM_PIO_IOGROUPB_VBASE +#endif +#if SAM_NPIO > 2 + , SAM_PIO_IOGROUPC_VBASE +#endif +#if SAM_NPIO > 3 + , SAM_PIO_IOGROUPD_VBASE +#endif +#if SAM_NPIO > 4 + , SAM_PIO_IOGROUPE_VBASE +#endif +}; + +/* Lookup for non-secure PIOs */ + +const uintptr_t g_spiobase[SAM_NPIO] = +{ + SAM_SPIO_IOGROUPA_VBASE +#if SAM_NPIO > 1 + , SAM_SPIO_IOGROUPB_VBASE +#endif +#if SAM_NPIO > 2 + , SAM_SPIO_IOGROUPC_VBASE +#endif +#if SAM_NPIO > 3 + , SAM_SPIO_IOGROUPD_VBASE +#endif +#if SAM_NPIO > 4 + , SAM_SPIO_IOGROUPE_VBASE +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Maps a port number to the standard port character */ + +#if defined(CONFIG_DEBUG_GPIO) && SAM_NPIO > 0 +static const char g_portchar[SAM_NPIO] = +{ + 'A' +#if SAM_NPIO > 1 + , 'B' +#endif +#if SAM_NPIO > 2 + , 'C' +#endif +#if SAM_NPIO > 3 + , 'D' +#endif +#if SAM_NPIO > 4 + , 'E' +#endif +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sam_issecure + * + * Description: + * Return true if the configuration selects a secure port. + * + ****************************************************************************/ + +static inline bool sam_issecure(pio_pinset_t cfgset) +{ + return ((cfgset & PIO_INT_SECURE) != 0); +} + +/**************************************************************************** + * Name: sam_piobase + * + * Description: + * Return the base address of the PIO register set + * + ****************************************************************************/ + +static uintptr_t sam_piobase(pio_pinset_t cfgset) +{ + int port = (cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + + /* Verify that the port number is within range */ + + if (port < SAM_NPIO) + { + /* Is this a secure or an un-secured PIO? */ + + if (sam_issecure(cfgset)) + { + /* Return the base address of the secure PIO registers */ + + return sam_spion_vbase(port); + } + else + { + /* Return the base address of the un-secured PIO registers */ + + return sam_pion_vbase(port); + } + } + + return 0; +} + +/**************************************************************************** + * Name: sam_piopin + * + * Description: + * Return a bitmask corresponding to the bit position in a PIO register + * + ****************************************************************************/ + +static inline uint32_t sam_piopin(pio_pinset_t cfgset) +{ + return 1 << ((cfgset & PIO_PIN_MASK) >> PIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_configcommon + * + * Description: + * Configure common PIO pin settings based on bit-encoded description of + * the pin. + * + ****************************************************************************/ + +static uint32_t sam_configcommon(pio_pinset_t cfgset) +{ + uint32_t regval = 0; + + /* Enable/disable the pull-up as requested + * NOTE: Control of the pull-up resistor is possible regardless of the + * configuration of the I/O line (Input, Output, Open-drain). + */ + + if ((cfgset & PIO_CFG_PULLUP) != 0) + { + regval |= PIO_CFGR_PUEN; + } + + /* Enable/disable the pull-down as requested */ + + if ((cfgset & PIO_CFG_PULLDOWN) != 0) + { + regval |= PIO_CFGR_PDEN; + } + + /* Check if filtering should be enabled. + * NOTE: Input filtering and Schmitt triggering apply only to inputs. + */ + + if ((cfgset & PIO_CFG_DEGLITCH) != 0) + { + if ((cfgset & PIO_CFG_DEGLITCH) != 0) + { + regval |= (PIO_CFGR_IFEN | PIO_CFGR_IFSCEN); + } + else + { + regval |= PIO_CFGR_IFEN; + } + } + + /* Enable/disable the Schmitt trigger inputs. + * NOTE: Input filtering and Schmitt triggering apply only to inputs. + */ + + if ((cfgset & PIO_CFG_SCHMITT) != 0) + { + regval |= PIO_CFGR_SCHMITT; + } + + /* Enable the open drain driver if requested. + * NOTE: The open drain apply option applies only to output and + * peripheral pins. + */ + + if ((cfgset & PIO_CFG_OPENDRAIN) != 0) + { + regval |= PIO_CFGR_OPD; + } + + /* Select I/O drive. + * REVISIT: Does't rive strength apply only to output and peripheral + * pins as well? + */ + + switch (cfgset & PIO_DRIVE_MASK) + { + default: + case PIO_DRIVE_LOW: + regval |= PIO_CFGR_DRVSTR_LOW; + break; + + case PIO_DRIVE_MEDIUM: + regval |= PIO_CFGR_DRVSTR_MED; + break; + + case PIO_DRIVE_HIGH: + regval |= PIO_CFGR_DRVSTR_HIGH; + break; + } + + return regval; +} + +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a PIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configinput(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ + uint32_t regval; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Select GPIO input */ + + regval = sam_configcommon(cfgset); + regval = (PIO_CFGR_FUNC_GPIO | PIO_CFGR_DIR_INPUT); + + /* Clear some output only bits. Mostly this just simplifies debug. */ + + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + + /* Configure the pin as an input and enable the PIO function */ + + putreg32(regval, base + SAM_PIO_CFGR_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a PIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configoutput(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ + uint32_t regval; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Select GPIO output */ + + regval = sam_configcommon(cfgset); + regval = (PIO_CFGR_FUNC_GPIO | PIO_CFGR_DIR_OUTPUT); + + /* Set default value. This is to be done before the pin is configured as + * an output in order to avoid any glitches at the time of the + * configuration. + */ + + if ((cfgset & PIO_OUTPUT_SET) != 0) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + + /* Configure the pin as an output and enable the PIO function */ + + putreg32(regval, base + SAM_PIO_CFGR_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a PIO pin driven by a peripheral A or B signal based on + * bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configperiph(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ + uint32_t regval; + unsigned int periph; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Select the peripheral function. The Direction bit does not apply to + * peripherals. + */ + + regval = sam_configcommon(cfgset); + periph = ((cfgset & PIO_CFGR_FUNC_MASK) - PIO_CFGR_FUNC_PERIPHA) >> PIO_CFGR_FUNC_SHIFT; + regval |= PIO_CFGR_FUNC_PERIPH(periph); + + /* Clear some output only bits. Mostly this just simplifies debug. */ + + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + + /* Configure the pin as a peripheral */ + + putreg32(regval, base + SAM_PIO_CFGR_OFFSET); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configpio(pio_pinset_t cfgset) +{ + uintptr_t base; + uint32_t pin; + irqstate_t flags; + int ret; + + /* Get the base address and pin mask associated with this pin configuration */ + + base = sam_piobase(cfgset); + if (base == 0) + { + return -EINVAL; + } + + pin = sam_piopin(cfgset); + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Enable writing to PIO registers. + * + * The following registers are write-protected when WPEN is set in + * PIO_WPMR: + * - PIO Mask Register + * - PIO Configuration Register + * The following registers are write-protected when WPEN is set in + * S_PIO_WPMR: + * - Secure PIO Mask Register + * - Secure PIO Configuration Register + * - Secure PIO Slow Clock Divider Debouncing Register + * The following registers are write-protected when WPITEN is set in + * PIO_WPMR: + * - PIO Interrupt Enable Register + * - PIO Interrupt Disable Register + * The following registers are write-protected when WPITEN is set in + * S_PIO_WPMR: + * - Secure PIO Interrupt Enable Register + * - Secure PIO Interrupt Disable Register + * + * I suspect that the default state is the WPMR is unprotected, so these + * operations could probably all be avoided. + */ + + putreg32(PIO_WPMR_WPKEY, SAM_PIO_WPMR); + putreg32(PIO_WPMR_WPKEY, SAM_SPIO_WPMR); + + /* Select the secure or un-secured PIO operation */ + + if (sam_issecure(cfgset)) + { + putreg32(pin, base + SAM_SPIO_SIOSR_OFFSET); + } + else + { + putreg32(pin, base + SAM_SPIO_SIONR_OFFSET); + } + + /* Set the mask register to modify only the specific pin being configured. */ + + putreg32(pin, base + SAM_PIO_MSKR_OFFSET); + + /* Put the pin in an initial state -- a vanilla input pin */ + + (void)sam_configinput(base, pin, MK_INPUT(cfgset)); + + /* Then handle the real pin configuration according to pin type */ + + switch (cfgset & PIO_MODE_MASK) + { + case PIO_INPUT: + ret = sam_configinput(base, pin, cfgset); + break; + + case PIO_OUTPUT: + ret = sam_configoutput(base, pin, cfgset); + break; + + case PIO_ANALOG: + /* REVISIT */ + ret = OK; + break; + + case PIO_PERIPHA: + case PIO_PERIPHB: + case PIO_PERIPHC: + case PIO_PERIPHD: + case PIO_PERIPHE: + case PIO_PERIPHF: + case PIO_PERIPHG: + ret = sam_configperiph(base, pin, cfgset); + break; + + default: + ret = -EINVAL; + break; + } + + /* Disable writing to PIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPITEN | PIO_WPMR_WPKEY, SAM_PIO_WPMR); + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPITEN | PIO_WPMR_WPKEY, SAM_SPIO_WPMR); + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: sam_piowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ****************************************************************************/ + +void sam_piowrite(pio_pinset_t pinset, bool value) +{ + uintptr_t base = sam_piobase(pinset); + uint32_t pin = sam_piopin(pinset); + + if (base != 0) + { + /* Set or clear the output as requested. NOTE: that there is no + * check if the pin is actually configured as an output so this could, + * potentially, do nothing. + */ + + if (value) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: sam_pioread + * + * Description: + * Read one or zero from the selected PIO pin + * + ****************************************************************************/ + +bool sam_pioread(pio_pinset_t pinset) +{ + uintptr_t base = sam_piobase(pinset); + uint32_t pin; + uint32_t regval; + + if (base != 0) + { + pin = sam_piopin(pinset); + + /* For output PIOs, the ODSR register provides the output value to + * drive the pin. The PDSR register, on the the other hand, provides + * the current sensed value on a pin, whether the pin is configured + * as an input, an output or as a peripheral. + * + * There is small delay between the setting in ODSR and PDSR but + * otherwise the they should be the same unless something external + * is driving the pin. + * + * Let's assume that PDSR is what the caller wants. + */ + + regval = getreg32(base + SAM_PIO_PDSR_OFFSET); + return (regval & pin) != 0; + } + + return 0; +} + +/************************************************************************************ + * Name: sam_pio_forceclk + * + * Description: + * Enable PIO clocking. Needed only for SAMA5D3/D4 compatibility. For the SAMA5D2, + * there is a common clock for all PIO ports and that clock is always enabled. + * + ************************************************************************************/ + +void sam_pio_forceclk(pio_pinset_t pinset, bool enable) +{ +} + +/************************************************************************************ + * Function: sam_dumppio + * + * Description: + * Dump all PIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumppio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int port; + bool secure; + + /* Get the base address associated with the PIO port */ + + port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + base = sam_piobase(pinset); + secure = sam_issecure(pinset); + + /* The following requires exclusive access to the PIO registers */ + + flags = enter_critical_section(); + + if (secure) + { + lldbg("SPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + } + else + { + lldbg("PIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + } + + lldbg(" MSKR: %08x CFGR: %08x PDSR: %08x LOCKSR: %08x\n", + getreg32(base + SAM_PIO_MSKR_OFFSET), getreg32(base + SAM_PIO_CFGR_OFFSET), + getreg32(base + SAM_PIO_PDSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET)); + lldbg(" ODSR: %08x IMR: %08x ISR: %08x\n", + getreg32(base + SAM_PIO_ODSR_OFFSET), getreg32(base + SAM_PIO_IMR_OFFSET), + getreg32(base + SAM_PIO_ISR_OFFSET)); + + if (secure) + { + lldbg(" SCDR: %08x WPMR: %08x WPSR: %08x IOSSR: %08x\n", + getreg32(SAM_SPIO_SCDR), getreg32(SAM_SPIO_WPMR), + getreg32(SAM_SPIO_WPSR), getreg32(base + SAM_SPIO_IOSSR_OFFSET)); + } + else + { + lldbg(" WPMR: %08x WPSR: %08x\n", + getreg32(SAM_PIO_WPMR), getreg32(SAM_PIO_WPSR)); + } + + leave_critical_section(flags); + return OK; +} +#endif diff --git a/arch/arm/src/sama5/sama5d2x_pio.h b/arch/arm/src/sama5/sama5d2x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..4b37166d4b3f0a65870dfe31a7eaea17835f8cd7 --- /dev/null +++ b/arch/arm/src/sama5/sama5d2x_pio.h @@ -0,0 +1,214 @@ +/************************************************************************************ + * arch/arm/src/sama5/sama5d2x_pio.h + * Parallel Input/Output (PIO) definitions for the SAMA5D2 family + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAMA5D2X_PIO_H +#define __ARCH_ARM_SRC_SAMA5_SAMA5D2X_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if !defined(CONFIG_SAMA5_PIOA_IRQ) && !defined(CONFIG_SAMA5_PIOB_IRQ) && \ + !defined(CONFIG_SAMA5_PIOC_IRQ) && !defined(CONFIG_SAMA5_PIOD_IRQ) +# undef CONFIG_SAMA5_PIO_IRQ +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#define PIO_HAVE_PULLDOWN 1 +#define PIO_HAVE_PERIPHCD 1 +#define PIO_HAVE_SCHMITT 1 +#define PIO_HAVE_DRIVE 1 + +#define SAM_NPIO 4 /* (4) PIOA-D */ + +/* Bit-encoded input to sam_configpio() ********************************************/ + +/* 32-bit Encoding: + * + * .... .MMM MM.C CCCC CDDI IISV .PPB BBBB + */ + +/* Input/Output mode: + * + * .... .MMM MM.. .... .... .... .... .... + */ + +#define PIO_MODE_SHIFT (22) /* Bits 22-26: PIO mode */ +#define PIO_MODE_MASK (15 << PIO_MODE_SHIFT) +# define PIO_INPUT (0 << PIO_MODE_SHIFT) /* Input */ +# define PIO_OUTPUT (1 << PIO_MODE_SHIFT) /* Output */ +# define PIO_ANALOG (2 << PIO_MODE_SHIFT) /* Analog */ +# define PIO_PERIPHA (3 << PIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define PIO_PERIPHB (4 << PIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define PIO_PERIPHC (5 << PIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define PIO_PERIPHD (6 << PIO_MODE_SHIFT) /* Controlled by periph D signal */ +# define PIO_PERIPHE (7 << PIO_MODE_SHIFT) /* Controlled by periph E signal */ +# define PIO_PERIPHF (8 << PIO_MODE_SHIFT) /* Controlled by periph F signal */ +# define PIO_PERIPHG (9 << PIO_MODE_SHIFT) /* Controlled by periph G signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * .... .... ...C CCCC C... .... .... .... + */ + +#define PIO_CFG_SHIFT (15) /* Bits 15-20: PIO configuration bits */ +#define PIO_CFG_MASK (0x3f << PIO_CFG_SHIFT) +# define PIO_CFG_DEFAULT (0x00 << PIO_CFG_SHIFT) /* Default, no attribute */ +# define PIO_CFG_PULLUP (0x01 << PIO_CFG_SHIFT) /* Bit 15: Internal pull-up */ +# define PIO_CFG_PULLDOWN (0x02 << PIO_CFG_SHIFT) /* Bit 16: Internal pull-down */ +# define PIO_CFG_DEGLITCH (0x04 << PIO_CFG_SHIFT) /* Bit 17: Internal input filter (Tmck/2)*/ +# define PIO_CFG_SLOWCLK (0x0c << PIO_CFG_SHIFT) /* Bits 17+18: Internal input filter (Tslwclk/2)*/ +# define PIO_CFG_OPENDRAIN (0x10 << PIO_CFG_SHIFT) /* Bit 19: Open drain */ +# define PIO_CFG_SCHMITT (0x20 << PIO_CFG_SHIFT) /* Bit 20: Schmitt trigger */ + +/* Drive Strength: + * + * .... .... .... .... .DD. .... .... .... + */ + +#define PIO_DRIVE_SHIFT (13) /* Bits 13-14: Drive strength */ +#define PIO_DRIVE_MASK (7 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_LOW (0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDIUM (2 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_HIGH (3 << PIO_DRIVE_SHIFT) + +/* Additional interrupt modes: + * + * .... .... .... .... ...I II.. .... .... + */ + +#define PIO_INT_SHIFT (10) /* Bits 9-12: PIO interrupt bits */ +#define PIO_INT_MASK (7 << PIO_INT_SHIFT) +# define PIO_INT_NONE (0 << PIO_INT_SHIFT) +# define PIO_INT_FALLING (1 << PIO_INT_SHIFT) +# define PIO_INT_RISING (2 << PIO_INT_SHIFT) +# define PIO_INT_BOTHEDGES (3 << PIO_INT_SHIFT) +# define PIO_INT_LOWLEVEL (4 << PIO_INT_SHIFT) +# define PIO_INT_HIGHLEVEL (5 << PIO_INT_SHIFT) + +/* If the pin is an interrupt, then this determines if the pin is a secure: + * + * .... .... .... .... .... ..S. .... .... + */ + +#define PIO_INT_SECURE (1 << 9) /* Bit 9: Secure PIO */ +#define PIO_INT_UNSECURE (0) + +/* If the pin is an PIO output, then this identifies the initial output value: + * + * .... .... .... .... .... ...V .... .... + */ + +#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */ +#define PIO_OUTPUT_CLEAR (0) + +/* This identifies the PIO port: + * + * .... .... .... .... .... .... .PP. .... + */ + +#define PIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ +#define PIO_PORT_MASK (3 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOA (0 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOB (1 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOC (2 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOD (3 << PIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... .... .... .... ...B BBBB + */ + +#define PIO_PIN_SHIFT (0) /* Bits 0-4: PIO number: 0-31 */ +#define PIO_PIN_MASK (31 << PIO_PIN_SHIFT) +#define PIO_PIN0 (0 << PIO_PIN_SHIFT) +#define PIO_PIN1 (1 << PIO_PIN_SHIFT) +#define PIO_PIN2 (2 << PIO_PIN_SHIFT) +#define PIO_PIN3 (3 << PIO_PIN_SHIFT) +#define PIO_PIN4 (4 << PIO_PIN_SHIFT) +#define PIO_PIN5 (5 << PIO_PIN_SHIFT) +#define PIO_PIN6 (6 << PIO_PIN_SHIFT) +#define PIO_PIN7 (7 << PIO_PIN_SHIFT) +#define PIO_PIN8 (8 << PIO_PIN_SHIFT) +#define PIO_PIN9 (9 << PIO_PIN_SHIFT) +#define PIO_PIN10 (10 << PIO_PIN_SHIFT) +#define PIO_PIN11 (11 << PIO_PIN_SHIFT) +#define PIO_PIN12 (12 << PIO_PIN_SHIFT) +#define PIO_PIN13 (13 << PIO_PIN_SHIFT) +#define PIO_PIN14 (14 << PIO_PIN_SHIFT) +#define PIO_PIN15 (15 << PIO_PIN_SHIFT) +#define PIO_PIN16 (16 << PIO_PIN_SHIFT) +#define PIO_PIN17 (17 << PIO_PIN_SHIFT) +#define PIO_PIN18 (18 << PIO_PIN_SHIFT) +#define PIO_PIN19 (19 << PIO_PIN_SHIFT) +#define PIO_PIN20 (20 << PIO_PIN_SHIFT) +#define PIO_PIN21 (21 << PIO_PIN_SHIFT) +#define PIO_PIN22 (22 << PIO_PIN_SHIFT) +#define PIO_PIN23 (23 << PIO_PIN_SHIFT) +#define PIO_PIN24 (24 << PIO_PIN_SHIFT) +#define PIO_PIN25 (25 << PIO_PIN_SHIFT) +#define PIO_PIN26 (26 << PIO_PIN_SHIFT) +#define PIO_PIN27 (27 << PIO_PIN_SHIFT) +#define PIO_PIN28 (28 << PIO_PIN_SHIFT) +#define PIO_PIN29 (29 << PIO_PIN_SHIFT) +#define PIO_PIN30 (30 << PIO_PIN_SHIFT) +#define PIO_PIN31 (31 << PIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t pio_pinset_t; + +#endif /* __ARCH_ARM_SRC_SAMA5_SAMA5D2X_PIO_H */ diff --git a/arch/arm/src/sama5/sama5d3x4x_pio.c b/arch/arm/src/sama5/sama5d3x4x_pio.c new file mode 100644 index 0000000000000000000000000000000000000000..b9379ad868c734f96e427f7711c0ae5c11d69e7b --- /dev/null +++ b/arch/arm/src/sama5/sama5d3x4x_pio.c @@ -0,0 +1,911 @@ +/**************************************************************************** + * arch/arm/src/sama5/sama5d3x4x_pio.c + * General Purpose Input/Output (PIO) logic for the SAMA5D3x and SAMA5D4x + * + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/_sama5d3x4x_pio.h" + +#include "chip.h" +#include "sam_periphclks.h" +#include "sam_pio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Macros to convert a pin to a vanilla input */ + +#define PIO_INPUT_BITS (PIO_INPUT | PIO_CFG_DEFAULT) +#define MK_INPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | PIO_INPUT_BITS) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Lookup for (non-secure) PIOs */ + +const uintptr_t g_piobase[SAM_NPIO] = +{ + SAM_PIOA_VBASE +#if SAM_NPIO > 1 + , SAM_PIOB_VBASE +#endif +#if SAM_NPIO > 2 + , SAM_PIOC_VBASE +#endif +#if SAM_NPIO > 3 + , SAM_PIOD_VBASE +#endif +#if SAM_NPIO > 4 + , SAM_PIOE_VBASE +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Maps a port number to the standard port character */ + +#if defined(CONFIG_DEBUG_GPIO) && SAM_NPIO > 0 +static const char g_portchar[SAM_NPIO] = +{ + 'A' +#if SAM_NPIO > 1 + , 'B' +#endif +#if SAM_NPIO > 2 + , 'C' +#endif +#if SAM_NPIO > 3 + , 'D' +#endif +#if SAM_NPIO > 4 + , 'E' +#endif +}; +#endif + +/* Map a PIO number to the PIO peripheral identifier (PID) */ + +#if SAM_NPIO > 0 +static const uint8_t g_piopid[SAM_NPIO] = +{ + SAM_PID_PIOA +#if SAM_NPIO > 1 + , SAM_PID_PIOB +#endif +#if SAM_NPIO > 2 + , SAM_PID_PIOC +#endif +#if SAM_NPIO > 3 + , SAM_PID_PIOD +#endif +#if SAM_NPIO > 4 + , SAM_PID_PIOE +#endif +}; +#endif + +/* Used to determine if a PIO port is configured to support interrupts */ + +#if SAM_NPIO > 0 +static const bool g_piointerrupt[SAM_NPIO] = +{ +#ifdef CONFIG_SAMA5_PIOA_IRQ + true +#else + false +#endif + +#if SAM_NPIO > 1 +#ifdef CONFIG_SAMA5_PIOB_IRQ + , true +#else + , false +#endif +#endif + +#if SAM_NPIO > 2 +#ifdef CONFIG_SAMA5_PIOC_IRQ + , true +#else + , false +#endif +#endif + +#if SAM_NPIO > 3 +#ifdef CONFIG_SAMA5_PIOD_IRQ + , true +#else + , false +#endif +#endif + +#if SAM_NPIO > 4 +#ifdef CONFIG_SAMA5_PIOE_IRQ + , true +#else + , false +#endif +#endif +}; +#endif + +/* This is an array of ports that PIO enable forced on */ + +static uint32_t g_forced[SAM_NPIO]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sam_piobase + * + * Description: + * Return the base address of the PIO register set + * + ****************************************************************************/ + +static inline uintptr_t sam_piobase(pio_pinset_t cfgset) +{ + int port = (cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + + if (port < SAM_NPIO) + { + return sam_pion_vbase(port); + } + else + { + return 0; + } +} + +/**************************************************************************** + * Name: sam_piopin + * + * Description: + * Return a bitmask corresponding to the bit position in a PIO register + * + ****************************************************************************/ + +static inline uint32_t sam_piopin(pio_pinset_t cfgset) +{ + return 1 << ((cfgset & PIO_PIN_MASK) >> PIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_pio_enableclk + * + * Description: + * Enable clocking on the selected PIO + * + ****************************************************************************/ + +static void sam_pio_enableclk(pio_pinset_t cfgset) +{ + int port = (cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + int pid; + + if (port < SAM_NPIO) + { + /* Get the peripheral ID associated with the PIO port and enable + * clocking to the PIO block. + */ + + pid = g_piopid[port]; + if (pid < 32) + { + sam_enableperiph0(pid); + } + else + { + sam_enableperiph1(pid); + } + } +} + +/**************************************************************************** + * Name: sam_pio_disableclk + * + * Description: + * Disable clocking on the selected PIO if we can. We can that if: + * + * 1) No pins are configured as PIO inputs (peripheral inputs don't need + * clocking, and + * 2) Glitch and debounce filtering are not enabled. Currently, this can + * only happen if the the pin is a PIO input, but we may need to + * implement glitch filtering on peripheral inputs as well in the + * future??? + * 3) The port is not configured for PIO interrupts. At present, the logic + * always keeps clocking on to ports that are configured for interrupts, + * but that could be dynamically controlled as well be keeping track + * of which PIOs have interrupts enabled. + * + * My! Wouldn't is be much easier to just keep all of the PIO clocks + * enabled? Is there a power management downside? + * + ****************************************************************************/ + +static void sam_pio_disableclk(pio_pinset_t cfgset) +{ + int port = (cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + uintptr_t base; + int pid; + + /* Leave clocking enabled for configured interrupt ports or for ports that + * have forced enabling of PIO clocking. + */ + + if (port < SAM_NPIO && !g_piointerrupt[port] && g_forced[port] == 0) + { + /* Get the base address of the PIO port */ + + base = sam_pion_vbase(port); + + /* Are any pins configured as PIO inputs? + * + * PSR - A bit set to "1" means that the corresponding pin is a PIO + * OSR - A bit set to "1" means that the corresponding pin is an output + */ + + if ((getreg32(base + SAM_PIO_PSR_OFFSET) & + ~getreg32(base + SAM_PIO_PSR_OFFSET)) == 0) + { + /* Any remaining configured pins are either not PIOs or all not + * PIO inputs. Disable clocking to this PIO block. + * + * Get the peripheral ID associated with the PIO port and disable + * clocking to the PIO block. + */ + + pid = g_piopid[port]; + if (pid < 32) + { + sam_disableperiph0(pid); + } + else + { + sam_disableperiph1(pid); + } + } + } +} + +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a PIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configinput(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ +#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE) + uint32_t regval; +#endif +#if defined(PIO_HAVE_DRIVE) + uint32_t offset; + uint32_t mask; + uint32_t drive; + int shift; +#endif + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & PIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef PIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & PIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Check if filtering should be enabled */ + + if ((cfgset & PIO_CFG_DEGLITCH) != 0) + { + putreg32(pin, base + SAM_PIO_IFER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_IFDR_OFFSET); + } + +#ifdef PIO_HAVE_SCHMITT + /* Enable/disable the Schmitt trigger: Zero enables. Schmitt triggered + * inputs are enabled by default. + */ + + regval = getreg32(base + SAM_PIO_SCHMITT_OFFSET); + if ((cfgset & PIO_CFG_SCHMITT) != 0) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET); +#endif + +#ifdef PIO_HAVE_DRIVE + /* Configure drive strength */ + + drive = (cfgset & PIO_DRIVE_MASK) >> PIO_DRIVE_SHIFT; + if (pin < 32) + { + offset = SAM_PIO_DRIVER1_OFFSET; + mask = PIO_DRIVER1_LINE_MASK(pin); + shift = PIO_DRIVER1_LINE_SHIFT(pin); + } + else + { + offset = SAM_PIO_DRIVER2_OFFSET; + mask = PIO_DRIVER2_LINE_MASK(pin); + shift = PIO_DRIVER2_LINE_SHIFT(pin); + } + + regval = getreg32(base + offset); + regval &= ~mask; + regval |= drive << shift; + putreg32(regval, base + offset); +#endif + + /* Clear some output only bits. Mostly this just simplifies debug. */ + + putreg32(pin, base + SAM_PIO_MDDR_OFFSET); + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + + /* Configure the pin as an input and enable the PIO function */ + + putreg32(pin, base + SAM_PIO_ODR_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + + /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and + * IFDGSR registers. This would probably best be done with + * another, new API... perhaps sam_configfilter() + */ + + /* "Reading the I/O line levels requires the clock of the PIO Controller + * to be enabled, otherwise PIO_PDSR reads the levels present on the I/O + * line at the time the clock was disabled." + */ + + sam_pio_enableclk(cfgset); + return OK; +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a PIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configoutput(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & PIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef PIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & PIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Disable glitch filtering */ + + putreg32(pin, base + SAM_PIO_IFDR_OFFSET); + + /* Enable the open drain driver if requested */ + + if ((cfgset & PIO_CFG_OPENDRAIN) != 0) + { + putreg32(pin, base + SAM_PIO_MDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_MDDR_OFFSET); + } + + /* Set default value. This is to be done before the pin is configured as + * an output in order to avoid any glitches at the time of the + * configuration. + */ + + if ((cfgset & PIO_OUTPUT_SET) != 0) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + + /* Configure the pin as an output and enable the PIO function */ + + putreg32(pin, base + SAM_PIO_OER_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + + /* Clocking to the PIO block may no longer be necessary. */ + + sam_pio_disableclk(cfgset); + return OK; +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a PIO pin driven by a peripheral A or B signal based on + * bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configperiph(uintptr_t base, uint32_t pin, + pio_pinset_t cfgset) +{ + uint32_t regval; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & PIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef PIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & PIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Disable glitch filtering */ + + putreg32(pin, base + SAM_PIO_IFDR_OFFSET); + +#ifdef PIO_HAVE_PERIPHCD + /* Configure pin, depending upon the peripheral A, B, C or D + * + * PERIPHA: ABCDSR1[n] = 0 ABCDSR2[n] = 0 + * PERIPHB: ABCDSR1[n] = 1 ABCDSR2[n] = 0 + * PERIPHC: ABCDSR1[n] = 0 ABCDSR2[n] = 1 + * PERIPHD: ABCDSR1[n] = 1 ABCDSR2[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABCDSR1_OFFSET); + if ((cfgset & PIO_MODE_MASK) == PIO_PERIPHA || + (cfgset & PIO_MODE_MASK) == PIO_PERIPHC) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_ABCDSR1_OFFSET); + + regval = getreg32(base + SAM_PIO_ABCDSR2_OFFSET); + if ((cfgset & PIO_MODE_MASK) == PIO_PERIPHA || + (cfgset & PIO_MODE_MASK) == PIO_PERIPHB) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_ABCDSR2_OFFSET); + +#else + /* Configure pin, depending upon the peripheral A or B: + * + * PERIPHA: ABSR[n] = 0 + * PERIPHB: ABSR[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABSR_OFFSET); + if ((cfgset & PIO_MODE_MASK) == PIO_PERIPHA) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_ABSR_OFFSET); +#endif + + /* Disable PIO functionality */ + + putreg32(pin, base + SAM_PIO_PDR_OFFSET); + + /* Clocking to the PIO block may no longer be necessary. */ + + sam_pio_disableclk(cfgset); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configpio(pio_pinset_t cfgset) +{ + uintptr_t base; + uint32_t pin; + irqstate_t flags; + int ret; + + /* Sanity check */ + + base = sam_piobase(cfgset); + if (base == 0) + { + return -EINVAL; + } + + pin = sam_piopin(cfgset); + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Enable writing to PIO registers. The following registers are protected: + * + * - PIO Enable/Disable Registers (PER/PDR) + * - PIO Output Enable/Disable Registers (OER/ODR) + * - PIO Interrupt Security Level Register (ISLR) + * - PIO Input Filter Enable/Disable Registers (IFER/IFDR) + * - PIO Multi-driver Enable/Disable Registers (MDER/MDDR) + * - PIO Pull-Up Enable/Disable Registers (PUER/PUDR) + * - PIO Peripheral ABCD Select Register 1/2 (ABCDSR1/2) + * - PIO Output Write Enable/Disable Registers + * - PIO Pad Pull-Down Enable/Disable Registers (PPER/PPDR) + * + * I suspect that the default state is the WPMR is unprotected, so these + * operations could probably all be avoided. + */ + + putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + + /* Put the pin in an initial state -- a vanilla input pin */ + + (void)sam_configinput(base, pin, MK_INPUT(cfgset)); + + /* Then handle the real pin configuration according to pin type */ + + switch (cfgset & PIO_MODE_MASK) + { + case PIO_INPUT: + ret = sam_configinput(base, pin, cfgset); + break; + + case PIO_OUTPUT: + ret = sam_configoutput(base, pin, cfgset); + break; + + case PIO_PERIPHA: + case PIO_PERIPHB: +#ifdef PIO_HAVE_PERIPHCD + case PIO_PERIPHC: + case PIO_PERIPHD: +#endif + ret = sam_configperiph(base, pin, cfgset); + break; + + default: + ret = -EINVAL; + break; + } + + /* Disable writing to PIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: sam_piowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ****************************************************************************/ + +void sam_piowrite(pio_pinset_t pinset, bool value) +{ + uintptr_t base = sam_piobase(pinset); + uint32_t pin = sam_piopin(pinset); + + if (base != 0) + { + /* Set or clear the output as requested. NOTE: that there is no + * check if the pin is actually configured as an output so this could, + * potentially, do nothing. + */ + + if (value) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: sam_pioread + * + * Description: + * Read one or zero from the selected PIO pin + * + ****************************************************************************/ + +bool sam_pioread(pio_pinset_t pinset) +{ + uintptr_t base = sam_piobase(pinset); + uint32_t pin; + uint32_t regval; + + if (base != 0) + { + pin = sam_piopin(pinset); + + /* For output PIOs, the ODSR register provides the output value to + * drive the pin. The PDSR register, on the the other hand, provides + * the current sensed value on a pin, whether the pin is configured + * as an input, an output or as a peripheral. + * + * There is small delay between the setting in ODSR and PDSR but + * otherwise the they should be the same unless something external + * is driving the pin. + * + * Let's assume that PDSR is what the caller wants. + */ + + regval = getreg32(base + SAM_PIO_PDSR_OFFSET); + return (regval & pin) != 0; + } + + return 0; +} + +/************************************************************************************ + * Name: sam_pio_forceclk + * + * Description: + * Enable PIO clocking. This logic is overly conservative and does not enable PIO + * clocking unless necessary (PIO input selected, glitch/filtering enable, or PIO + * interrupts enabled). There are, however, certain conditions were we may want + * for force the PIO clock to be enabled. An example is reading the input value + * from an open drain output. + * + * The PIO automatic enable/disable logic is not smart enough enough to know about + * these cases. For those cases, sam_pio_forceclk() is provided. + * + ************************************************************************************/ + +void sam_pio_forceclk(pio_pinset_t pinset, bool enable) +{ + unsigned int port; + uint32_t pin; + irqstate_t flags; + + /* Extract the port number */ + + port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + pin = sam_piopin(pinset); + + /* The remainder of this operation must be atomic */ + + flags = enter_critical_section(); + + /* Are we enabling or disabling clocking */ + + if (enable) + { + /* Indicate that clocking is forced and enable the clock */ + + g_forced[port] |= pin; + sam_pio_enableclk(pinset); + } + else + { + /* Clocking is no longer forced for this pin */ + + g_forced[port] &= ~pin; + sam_pio_disableclk(pinset); + } + + leave_critical_section(flags); +} + +/************************************************************************************ + * Function: sam_dumppio + * + * Description: + * Dump all PIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumppio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int port; + + /* Get the base address associated with the PIO port */ + + port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT; + base = sam_pion_vbase(port); + + /* The following requires exclusive access to the PIO registers */ + + flags = enter_critical_section(); + lldbg("PIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + +#ifdef SAM_PIO_ISLR_OFFSET + lldbg(" PSR: %08x ISLR: %08x OSR: %08x IFSR: %08x\n", + getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_ISLR_OFFSET), + getreg32(base + SAM_PIO_OSR_OFFSET), getreg32(base + SAM_PIO_IFSR_OFFSET)); +#else + lldbg(" PSR: %08x OSR: %08x IFSR: %08x\n", + getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_OSR_OFFSET), + getreg32(base + SAM_PIO_IFSR_OFFSET)); +#endif + lldbg(" ODSR: %08x PDSR: %08x IMR: %08x ISR: %08x\n", + getreg32(base + SAM_PIO_ODSR_OFFSET), getreg32(base + SAM_PIO_PDSR_OFFSET), + getreg32(base + SAM_PIO_IMR_OFFSET), getreg32(base + SAM_PIO_ISR_OFFSET)); + lldbg(" MDSR: %08x PUSR: %08x ABDCSR: %08x %08x\n", + getreg32(base + SAM_PIO_MDSR_OFFSET), getreg32(base + SAM_PIO_PUSR_OFFSET), + getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET)); + lldbg(" IFSCSR: %08x SCDR: %08x PPDSR: %08x OWSR: %08x\n", + getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET), + getreg32(base + SAM_PIO_PPDSR_OFFSET), getreg32(base + SAM_PIO_OWSR_OFFSET)); +#ifdef SAM_PIO_LOCKSR_OFFSET + lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x LOCKSR: %08x\n", + getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET), + getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET)); +#else + lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x\n", + getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET), + getreg32(base + SAM_PIO_FRLHSR_OFFSET)); +#endif + lldbg("SCHMITT: %08x DRIVER: %08x %08x\n", + getreg32(base + SAM_PIO_SCHMITT_OFFSET), getreg32(base + SAM_PIO_DRIVER1_OFFSET), + getreg32(base + SAM_PIO_DRIVER2_OFFSET)); + lldbg(" WPMR: %08x WPSR: %08x\n", + getreg32(base + SAM_PIO_WPMR_OFFSET), getreg32(base + SAM_PIO_WPSR_OFFSET)); + + leave_critical_section(flags); + return OK; +} +#endif diff --git a/arch/arm/src/sama5/sama5d3x4x_pio.h b/arch/arm/src/sama5/sama5d3x4x_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..63b6615b556955465ba7f093342c3fb3e7fa4b13 --- /dev/null +++ b/arch/arm/src/sama5/sama5d3x4x_pio.h @@ -0,0 +1,213 @@ +/************************************************************************************ + * arch/arm/src/sama5/sama5d3x4x_pio.h + * Parallel Input/Output (PIO) definitions for the SAMA5D23 and SAMA5D4 families + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAMA5D3X4X_PIO_H +#define __ARCH_ARM_SRC_SAMA5_SAMA5D3X4X_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if !defined(CONFIG_SAMA5_PIOA_IRQ) && !defined(CONFIG_SAMA5_PIOB_IRQ) && \ + !defined(CONFIG_SAMA5_PIOC_IRQ) && !defined(CONFIG_SAMA5_PIOD_IRQ) && \ + !defined(CONFIG_SAMA5_PIOE_IRQ) && !defined(CONFIG_SAMA5_PIOF_IRQ) +# undef CONFIG_SAMA5_PIO_IRQ +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#define PIO_HAVE_PULLDOWN 1 +#define PIO_HAVE_PERIPHCD 1 +#define PIO_HAVE_SCHMITT 1 +#define PIO_HAVE_DRIVE 1 + +#define SAM_NPIO 5 /* (5) PIOA-E */ + +/* Bit-encoded input to sam_configpio() ********************************************/ + +/* 32-bit Encoding: + * + * .... .... .MMM CCCC CDDI IISV PPPB BBBB + */ + +/* Input/Output mode: + * + * .... .... .MMM .... .... .... .... .... + */ + +#define PIO_MODE_SHIFT (20) /* Bits 20-22: PIO mode */ +#define PIO_MODE_MASK (7 << PIO_MODE_SHIFT) +# define PIO_INPUT (0 << PIO_MODE_SHIFT) /* Input */ +# define PIO_OUTPUT (1 << PIO_MODE_SHIFT) /* Output */ +# define PIO_PERIPHA (2 << PIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define PIO_PERIPHB (3 << PIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define PIO_PERIPHC (4 << PIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define PIO_PERIPHD (5 << PIO_MODE_SHIFT) /* Controlled by periph D signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * .... .... .... CCCC C... .... .... .... + */ + +#define PIO_CFG_SHIFT (15) /* Bits 15-19: PIO configuration bits */ +#define PIO_CFG_MASK (31 << PIO_CFG_SHIFT) +# define PIO_CFG_DEFAULT (0 << PIO_CFG_SHIFT) /* Default, no attribute */ +# define PIO_CFG_PULLUP (1 << PIO_CFG_SHIFT) /* Bit 15: Internal pull-up */ +# define PIO_CFG_PULLDOWN (2 << PIO_CFG_SHIFT) /* Bit 16: Internal pull-down */ +# define PIO_CFG_DEGLITCH (4 << PIO_CFG_SHIFT) /* Bit 17: Internal glitch filter */ +# define PIO_CFG_OPENDRAIN (8 << PIO_CFG_SHIFT) /* Bit 18: Open drain */ +# define PIO_CFG_SCHMITT (16 << PIO_CFG_SHIFT) /* Bit 19: Schmitt trigger */ + +/* Drive Strength: + * + * .... .... .... .... .DD. .... .... .... + */ + +#define PIO_DRIVE_SHIFT (13) /* Bits 13-14: Drive strength */ +#define PIO_DRIVE_MASK (7 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_LOW (0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDIUM (2 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_HIGH (3 << PIO_DRIVE_SHIFT) + +/* Additional interrupt modes: + * + * .... .... .... .... ...I II.. .... .... + */ + +#define PIO_INT_SHIFT (10) /* Bits 9-12: PIO interrupt bits */ +#define PIO_INT_MASK (7 << PIO_INT_SHIFT) +# define _PIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */ +# define _PIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */ +# define _PIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _PIO_INT_RH (1 << 8) /* Bit 9: Rising edge/High level detection interrupt */ +# define _PIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define PIO_INT_HIGHLEVEL (_PIO_INT_AIM | _PIO_INT_LEVEL | _PIO_INT_RH) +# define PIO_INT_LOWLEVEL (_PIO_INT_AIM | _PIO_INT_LEVEL | _PIO_INT_FL) +# define PIO_INT_RISING (_PIO_INT_AIM | _PIO_INT_EDGE | _PIO_INT_RH) +# define PIO_INT_FALLING (_PIO_INT_AIM | _PIO_INT_EDGE | _PIO_INT_FL) +# define PIO_INT_BOTHEDGES (0) + +/* If the pin is an interrupt, then this determines if the pin is a secure interrupt: + * + * .... .... .... .... .... ..S. .... .... + */ + +#ifdef SAMA5_SAIC +# define PIO_INT_SECURE (1 << 9) /* Bit 9: Secure interrupt */ +#else +# define PIO_INT_SECURE (0) +#endif +#define PIO_INT_UNSECURE (0) + +/* If the pin is an PIO output, then this identifies the initial output value: + * + * .... .... .... .... .... ...V .... .... + */ + +#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */ +#define PIO_OUTPUT_CLEAR (0) + +/* This identifies the PIO port: + * + * .... .... .... .... .... .... PPP. .... + */ + +#define PIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define PIO_PORT_MASK (7 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOA (0 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOB (1 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOC (2 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOD (3 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOE (4 << PIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... .... .... .... ...B BBBB + */ + +#define PIO_PIN_SHIFT (0) /* Bits 0-4: PIO number: 0-31 */ +#define PIO_PIN_MASK (31 << PIO_PIN_SHIFT) +#define PIO_PIN0 (0 << PIO_PIN_SHIFT) +#define PIO_PIN1 (1 << PIO_PIN_SHIFT) +#define PIO_PIN2 (2 << PIO_PIN_SHIFT) +#define PIO_PIN3 (3 << PIO_PIN_SHIFT) +#define PIO_PIN4 (4 << PIO_PIN_SHIFT) +#define PIO_PIN5 (5 << PIO_PIN_SHIFT) +#define PIO_PIN6 (6 << PIO_PIN_SHIFT) +#define PIO_PIN7 (7 << PIO_PIN_SHIFT) +#define PIO_PIN8 (8 << PIO_PIN_SHIFT) +#define PIO_PIN9 (9 << PIO_PIN_SHIFT) +#define PIO_PIN10 (10 << PIO_PIN_SHIFT) +#define PIO_PIN11 (11 << PIO_PIN_SHIFT) +#define PIO_PIN12 (12 << PIO_PIN_SHIFT) +#define PIO_PIN13 (13 << PIO_PIN_SHIFT) +#define PIO_PIN14 (14 << PIO_PIN_SHIFT) +#define PIO_PIN15 (15 << PIO_PIN_SHIFT) +#define PIO_PIN16 (16 << PIO_PIN_SHIFT) +#define PIO_PIN17 (17 << PIO_PIN_SHIFT) +#define PIO_PIN18 (18 << PIO_PIN_SHIFT) +#define PIO_PIN19 (19 << PIO_PIN_SHIFT) +#define PIO_PIN20 (20 << PIO_PIN_SHIFT) +#define PIO_PIN21 (21 << PIO_PIN_SHIFT) +#define PIO_PIN22 (22 << PIO_PIN_SHIFT) +#define PIO_PIN23 (23 << PIO_PIN_SHIFT) +#define PIO_PIN24 (24 << PIO_PIN_SHIFT) +#define PIO_PIN25 (25 << PIO_PIN_SHIFT) +#define PIO_PIN26 (26 << PIO_PIN_SHIFT) +#define PIO_PIN27 (27 << PIO_PIN_SHIFT) +#define PIO_PIN28 (28 << PIO_PIN_SHIFT) +#define PIO_PIN29 (29 << PIO_PIN_SHIFT) +#define PIO_PIN30 (30 << PIO_PIN_SHIFT) +#define PIO_PIN31 (31 << PIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t pio_pinset_t; + +#endif /* __ARCH_ARM_SRC_SAMA5_SAMA5D3X4X_PIO_H */ diff --git a/arch/arm/src/sama5/sama5d3x_memorymap.c b/arch/arm/src/sama5/sama5d3x_memorymap.c new file mode 100644 index 0000000000000000000000000000000000000000..229d2e813272e9a0e655387a9d8c36544f7f9ae0 --- /dev/null +++ b/arch/arm/src/sama5/sama5d3x_memorymap.c @@ -0,0 +1,282 @@ +/**************************************************************************** + * arch/arm/src/sama5/sama5d3x_memorymap.c + * + * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "mmu.h" + +#include "chip/sam_memorymap.h" +#include "sam_lcd.h" +#include "sam_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical + * address space of the SAMA5. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +const struct section_mapping_s g_section_mapping[] = +{ + /* SAMA5 Internal Memories */ + + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are three ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. A second way is to map the use the AXI MATRIX remap register to + * map physical address zero to the beginning of the text region, + * either internal SRAM or EBI CS 0. Then we can set an identity + * mapping to map the boot region at 0x0000:0000 to virtual address + * 0x0000:00000. VBAR == 0x0000:0000. + * + * This method is used when booting from ISRAM or NOR FLASH. In + * that case, vectors must lie at the beginning of NOFR FLASH. + * + * 3. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * This is the method used when booting from SDRAM. + * + * - When executing from NOR FLASH, the first level bootloader is supposed + * to provide the AXI MATRIX mapping for us at boot time base on the state + * of the BMS pin. However, I have found that in the test environments + * that I use, I cannot always be assured of that physical address mapping. + * + * So we do both here. If we are executing from NOR FLASH, then we provide + * the MMU to map the physical address of FLASH to address 0x0000:0000; + * + * - If we are executing out of ISRAM, then the SAMA5 primary bootloader + * probably copied us into ISRAM and set the AXI REMAP bit for us. + * + * - If we are executing from external SDRAM, then a secondary bootloader must + * have loaded us into SDRAM. In this case, simply set the VBAR register + * to the address of the vector table (not necessary at the beginning + * or SDRAM). + */ + +#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM) && \ + !defined(CONFIG_SAMA5_BOOT_SDRAM) + { CONFIG_FLASH_START, 0x00000000, + MMU_ROMFLAGS, 1 + }, +#else + { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION, + SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS + }, +#endif + + { SAM_ROM_PSECTION, SAM_ROM_VSECTION, + SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS + }, + { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION, + SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS + }, + +#ifndef CONFIG_PAGING /* Internal SRAM is already fully mapped */ + { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION, + SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS + }, +#endif + + { SAM_SMD_PSECTION, SAM_SMD_VSECTION, + SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS + }, + { SAM_UDPHSRAM_PSECTION, SAM_UDPHSRAM_VSECTION, + SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS + }, + { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION, + SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS + }, + { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION, + SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS + }, + { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION, + SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS + }, + { SAM_DAP_PSECTION, SAM_DAP_VSECTION, + SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS + }, + + /* SAMA5 CS0 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS0 + { SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION, + SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS + }, +#endif + + /* SAMA5 External SDRAM Memory. The SDRAM is not usable until it has been + * initialized. If we are running out of SDRAM now, we can assume that some + * second level boot loader has properly configured SRAM for us. In that + * case, we set the MMU flags for the final, fully cache-able state. + * + * Also, in this case, the mapping for the SDRAM was done in arm_head.S and + * need not be repeated here. + * + * If we are running from ISRAM or NOR flash, then we will need to configure + * the SDRAM ourselves. In this case, we set the MMU flags to the strongly + * ordered, non-cacheable state. We need this direct access to SDRAM in + * order to configure it. Once SDRAM has been initialized, it will be re- + * configured in its final state. + */ + +#ifdef NEED_SDRAM_MAPPING + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + MMU_STRONGLY_ORDERED, SAM_DDRCS_NSECTIONS + }, +#endif + + /* SAMA5 CS1-3 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS1 + { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, + SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS2 + { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, + SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS3 + { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION, + SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_HAVE_NAND + { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION, + SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS + }, +#endif + + /* SAMA5 Internal Peripherals + * + * Naming of peripheral sections differs between the SAMA5D3 and SAMA5D4. + * There is nothing called SYSC in the SAMA5D4 memory map. The third + * peripheral section is un-named in the SAMA5D4 memory map, but I have + * chosen the name PERIPHC for this usage. + */ + + { SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION, + SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS + }, + + { SAM_PERIPHB_PSECTION, SAM_PERIPHB_VSECTION, + SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS + }, + + { SAM_SYSC_PSECTION, SAM_SYSC_VSECTION, + SAM_SYSC_MMUFLAGS, SAM_SYSC_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + * + * If SDRAM will be reconfigured, then we will defer setup of the framebuffer + * until after the SDRAM remapping (since the framebuffer problem resides) in + * SDRAM. + */ + +#if defined(CONFIG_SAMA5_LCDC) && !defined(NEED_SDRAM_REMAPPING) + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the mapping table */ + +#define NMAPPINGS \ + (sizeof(g_section_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_mappings = NMAPPINGS; + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +const struct section_mapping_s g_operational_mapping[] = +{ + /* This entry reprograms the SDRAM entry, making it cacheable and + * bufferable. + */ + + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + */ + +#ifdef CONFIG_SAMA5_LCDC + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the operational mapping table */ + +#define NREMAPPINGS \ + (sizeof(g_operational_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_opmappings = NREMAPPINGS; + +#endif /* NEED_SDRAM_REMAPPING */ diff --git a/arch/arm/src/sama5/sama5d3x_periphclks.h b/arch/arm/src/sama5/sama5d3x_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..2d2fe7c3e9db3b2cd879e96ecdf54a719b1d996a --- /dev/null +++ b/arch/arm/src/sama5/sama5d3x_periphclks.h @@ -0,0 +1,243 @@ +/************************************************************************************ + * arch/arm/src/sama5/sama5d3x_periphclks.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAMAD53X_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMA5_SAMAD53X_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) +#define sam_isenabled0(s) (getreg32(SAM_PMC_PCER0) & (1 << (s)) != 0) +#define sam_isenabled1(s) (getreg32(SAM_PMC_PCER1) & (1 << ((s) - 32)) != 0) + +#define sam_dbgu_enableclk() sam_enableperiph0(SAM_PID_DBGU) +#define sam_pit_enableclk() sam_enableperiph0(SAM_PID_PIT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_hsmc_enableclk() sam_enableperiph0(SAM_PID_HSMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_smd_enableclk() sam_enableperiph0(SAM_PID_SMD) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_usart3_enableclk() sam_enableperiph0(SAM_PID_USART3) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_twi0_enableclk() sam_enableperiph0(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph0(SAM_PID_TWI1) +#define sam_twi2_enableclk() sam_enableperiph0(SAM_PID_TWI2) +#define sam_hsmci0_enableclk() sam_enableperiph0(SAM_PID_HSMCI0) +#define sam_hsmci1_enableclk() sam_enableperiph0(SAM_PID_HSMCI1) +#define sam_hsmci2_enableclk() sam_enableperiph0(SAM_PID_HSMCI2) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_spi1_enableclk() sam_enableperiph0(SAM_PID_SPI1) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_pwm_enableclk() sam_enableperiph0(SAM_PID_PWM) +#define sam_adc_enableclk() sam_enableperiph0(SAM_PID_ADC) +#define sam_dmac0_enableclk() sam_enableperiph0(SAM_PID_DMAC0) +#define sam_dmac1_enableclk() sam_enableperiph0(SAM_PID_DMAC1) + +#define sam_uhphs_enableclk() sam_enableperiph1(SAM_PID_UHPHS) +#define sam_udphs_enableclk() sam_enableperiph1(SAM_PID_UDPHS) +#define sam_gmac_enableclk() sam_enableperiph1(SAM_PID_GMAC) +#define sam_emac_enableclk() sam_enableperiph1(SAM_PID_EMAC) +#define sam_lcdc_enableclk() sam_enableperiph1(SAM_PID_LCDC) +#define sam_isi_enableclk() sam_enableperiph1(SAM_PID_ISI) +#define sam_ssc0_enableclk() sam_enableperiph1(SAM_PID_SSC0) +#define sam_ssc1_enableclk() sam_enableperiph1(SAM_PID_SSC1) +#define sam_can0_enableclk() sam_enableperiph1(SAM_PID_CAN0) +#define sam_can1_enableclk() sam_enableperiph1(SAM_PID_CAN1) +#define sam_sha_enableclk() sam_enableperiph1(SAM_PID_SHA) +#define sam_aes_enableclk() sam_enableperiph1(SAM_PID_AES) +#define sam_tdes_enableclk() sam_enableperiph1(SAM_PID_TDES) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_arm_enableclk() sam_enableperiph1(SAM_PID_ARM) +#define sam_aic_enableclk() sam_enableperiph1(SAM_PID_AIC) +#define sam_fuse_enableclk() sam_enableperiph1(SAM_PID_FUSE) +#define sam_mpddrc_enableclk() sam_enableperiph1(SAM_PID_MPDDRC) + +#define sam_dbgu_disableclk() sam_disableperiph0(SAM_PID_DBGU) +#define sam_pit_disableclk() sam_disableperiph0(SAM_PID_PIT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_hsmc_disableclk() sam_disableperiph0(SAM_PID_HSMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_smd_disableclk() sam_disableperiph0(SAM_PID_SMD) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_usart3_disableclk() sam_disableperiph0(SAM_PID_USART3) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_twi0_disableclk() sam_disableperiph0(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph0(SAM_PID_TWI1) +#define sam_twi2_disableclk() sam_disableperiph0(SAM_PID_TWI2) +#define sam_hsmci0_disableclk() sam_disableperiph0(SAM_PID_HSMCI0) +#define sam_hsmci1_disableclk() sam_disableperiph0(SAM_PID_HSMCI1) +#define sam_hsmci2_disableclk() sam_disableperiph0(SAM_PID_HSMCI2) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_spi1_disableclk() sam_disableperiph0(SAM_PID_SPI1) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_pwm_disableclk() sam_disableperiph0(SAM_PID_PWM) +#define sam_adc_disableclk() sam_disableperiph0(SAM_PID_ADC) +#define sam_dmac0_disableclk() sam_disableperiph0(SAM_PID_DMAC0) +#define sam_dmac1_disableclk() sam_disableperiph0(SAM_PID_DMAC1) + +#define sam_uhphs_disableclk() sam_disableperiph1(SAM_PID_UHPHS) +#define sam_udphs_disableclk() sam_disableperiph1(SAM_PID_UDPHS) +#define sam_gmac_disableclk() sam_disableperiph1(SAM_PID_GMAC) +#define sam_emac_disableclk() sam_disableperiph1(SAM_PID_EMAC) +#define sam_lcdc_disableclk() sam_disableperiph1(SAM_PID_LCDC) +#define sam_isi_disableclk() sam_disableperiph1(SAM_PID_ISI) +#define sam_ssc0_disableclk() sam_disableperiph1(SAM_PID_SSC0) +#define sam_ssc1_disableclk() sam_disableperiph1(SAM_PID_SSC1) +#define sam_can0_disableclk() sam_disableperiph1(SAM_PID_CAN0) +#define sam_can1_disableclk() sam_disableperiph1(SAM_PID_CAN1) +#define sam_sha_disableclk() sam_disableperiph1(SAM_PID_SHA) +#define sam_aes_disableclk() sam_disableperiph1(SAM_PID_AES) +#define sam_tdes_disableclk() sam_disableperiph1(SAM_PID_TDES) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_arm_disableclk() sam_disableperiph1(SAM_PID_ARM) +#define sam_aic_disableclk() sam_disableperiph1(SAM_PID_AIC) +#define sam_fuse_disableclk() sam_disableperiph1(SAM_PID_FUSE) +#define sam_mpddrc_disableclk() sam_disableperiph1(SAM_PID_MPDDRC) + +#define sam_dbgu_isenabled() sam_isenabled0(SAM_PID_DBGU) +#define sam_pit_isenabled() sam_isenabled0(SAM_PID_PIT) +#define sam_wdt_isenabled() sam_isenabled0(SAM_PID_WDT) +#define sam_hsmc_isenabled() sam_isenabled0(SAM_PID_HSMC) +#define sam_pioa_isenabled() sam_isenabled0(SAM_PID_PIOA) +#define sam_piob_isenabled() sam_isenabled0(SAM_PID_PIOB) +#define sam_pioc_isenabled() sam_isenabled0(SAM_PID_PIOC) +#define sam_piod_isenabled() sam_isenabled0(SAM_PID_PIOD) +#define sam_pioe_isenabled() sam_isenabled0(SAM_PID_PIOE) +#define sam_smd_isenabled() sam_isenabled0(SAM_PID_SMD) +#define sam_usart0_isenabled() sam_isenabled0(SAM_PID_USART0) +#define sam_usart1_isenabled() sam_isenabled0(SAM_PID_USART1) +#define sam_usart2_isenabled() sam_isenabled0(SAM_PID_USART2) +#define sam_usart3_isenabled() sam_isenabled0(SAM_PID_USART3) +#define sam_uart0_isenabled() sam_isenabled0(SAM_PID_UART0) +#define sam_uart1_isenabled() sam_isenabled0(SAM_PID_UART1) +#define sam_twi0_isenabled() sam_isenabled0(SAM_PID_TWI0) +#define sam_twi1_isenabled() sam_isenabled0(SAM_PID_TWI1) +#define sam_twi2_isenabled() sam_isenabled0(SAM_PID_TWI2) +#define sam_hsmci0_isenabled() sam_isenabled0(SAM_PID_HSMCI0) +#define sam_hsmci1_isenabled() sam_isenabled0(SAM_PID_HSMCI1) +#define sam_hsmci2_isenabled() sam_isenabled0(SAM_PID_HSMCI2) +#define sam_spi0_isenabled() sam_isenabled0(SAM_PID_SPI0) +#define sam_spi1_isenabled() sam_isenabled0(SAM_PID_SPI1) +#define sam_tc0_isenabled() sam_isenabled0(SAM_PID_TC0) +#define sam_tc1_isenabled() sam_isenabled0(SAM_PID_TC1) +#define sam_pwm_isenabled() sam_isenabled0(SAM_PID_PWM) +#define sam_adc_isenabled() sam_isenabled0(SAM_PID_ADC) +#define sam_dmac0_isenabled() sam_isenabled0(SAM_PID_DMAC0) +#define sam_dmac1_isenabled() sam_isenabled0(SAM_PID_DMAC1) + +#define sam_uhphs_isenabled() sam_isenabled1(SAM_PID_UHPHS) +#define sam_udphs_isenabled() sam_isenabled1(SAM_PID_UDPHS) +#define sam_gmac_isenabled() sam_isenabled1(SAM_PID_GMAC) +#define sam_emac_isenabled() sam_isenabled1(SAM_PID_EMAC) +#define sam_lcdc_isenabled() sam_isenabled1(SAM_PID_LCDC) +#define sam_isi_isenabled() sam_isenabled1(SAM_PID_ISI) +#define sam_ssc0_isenabled() sam_isenabled1(SAM_PID_SSC0) +#define sam_ssc1_isenabled() sam_isenabled1(SAM_PID_SSC1) +#define sam_can0_isenabled() sam_isenabled1(SAM_PID_CAN0) +#define sam_can1_isenabled() sam_isenabled1(SAM_PID_CAN1) +#define sam_sha_isenabled() sam_isenabled1(SAM_PID_SHA) +#define sam_aes_isenabled() sam_isenabled1(SAM_PID_AES) +#define sam_tdes_isenabled() sam_isenabled1(SAM_PID_TDES) +#define sam_trng_isenabled() sam_isenabled1(SAM_PID_TRNG) +#define sam_arm_isenabled() sam_isenabled1(SAM_PID_ARM) +#define sam_aic_isenabled() sam_isenabled1(SAM_PID_AIC) +#define sam_fuse_isenabled() sam_isenabled1(SAM_PID_FUSE) +#define sam_mpddrc_isenabled() sam_isenabled1(SAM_PID_MPDDRC) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAMAD53X_PERIPHCLKS_H */ diff --git a/arch/arm/src/sama5/sama5d4x_memorymap.c b/arch/arm/src/sama5/sama5d4x_memorymap.c new file mode 100644 index 0000000000000000000000000000000000000000..8d63ea70d532744809341fb17a0c9a9a59b960bb --- /dev/null +++ b/arch/arm/src/sama5/sama5d4x_memorymap.c @@ -0,0 +1,286 @@ +/**************************************************************************** + * arch/arm/src/sama5/sama5d4x_memorymap.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "mmu.h" + +#include "chip/sam_memorymap.h" +#include "sam_lcd.h" +#include "sam_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical + * address space of the SAMA5. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +const struct section_mapping_s g_section_mapping[] = +{ + /* SAMA5 Internal Memories */ + + /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the + * beginning of the .text region must appear at address at the address + * specified in the VBAR. There are three ways to accomplish this: + * + * 1. By explicitly mapping the beginning of .text region with a page + * table entry so that the virtual address zero maps to the beginning + * of the .text region. VBAR == 0x0000:0000. + * + * 2. A second way is to map the use the AXI MATRIX remap register to + * map physical address zero to the beginning of the text region, + * either internal SRAM or EBI CS 0. Then we can set an identity + * mapping to map the boot region at 0x0000:0000 to virtual address + * 0x0000:00000. VBAR == 0x0000:0000. + * + * This method is used when booting from ISRAM or NOR FLASH. In + * that case, vectors must lie at the beginning of NOFR FLASH. + * + * 3. Set the Cortex-A5 VBAR register so that the vector table address + * is moved to a location other than 0x0000:0000. + * + * This is the method used when booting from SDRAM. + * + * - When executing from NOR FLASH, the first level bootloader is supposed + * to provide the AXI MATRIX mapping for us at boot time base on the state + * of the BMS pin. However, I have found that in the test environments + * that I use, I cannot always be assured of that physical address mapping. + * + * So we do both here. If we are executing from NOR FLASH, then we provide + * the MMU to map the physical address of FLASH to address 0x0000:0000; + * + * - If we are executing out of ISRAM, then the SAMA5 primary bootloader + * probably copied us into ISRAM and set the AXI REMAP bit for us. + * + * - If we are executing from external SDRAM, then a secondary bootloader must + * have loaded us into SDRAM. In this case, simply set the VBAR register + * to the address of the vector table (not necessary at the beginning + * or SDRAM). + */ + +#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM) && \ + !defined(CONFIG_SAMA5_BOOT_SDRAM) + { CONFIG_FLASH_START, 0x00000000, + MMU_ROMFLAGS, 1 + }, +#else + { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION, + SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS + }, +#endif + + { SAM_ROM_PSECTION, SAM_ROM_VSECTION, + SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS + }, + { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION, + SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS + }, + +#ifndef CONFIG_PAGING /* Internal SRAM is already fully mapped */ + { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION, + SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS + }, +#endif + + { SAM_VDEC_PSECTION, SAM_VDEC_VSECTION, + SAM_VDEC_MMUFLAGS, SAM_VDEC_NSECTIONS + }, + { SAM_SMD_PSECTION, SAM_SMD_VSECTION, + SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS + }, + { SAM_UDPHSRAM_PSECTION, SAM_UDPHSRAM_VSECTION, + SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS + }, + { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION, + SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS + }, + { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION, + SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS + }, + { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION, + SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS + }, + { SAM_DAP_PSECTION, SAM_DAP_VSECTION, + SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS + }, + { SAM_L2CC_PSECTION, SAM_L2CC_VSECTION, + SAM_L2CC_MMUFLAGS, SAM_L2CC_NSECTIONS + }, + + /* SAMA5 CS0 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS0 + { SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION, + SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS + }, +#endif + + /* SAMA5 External SDRAM Memory. The SDRAM is not usable until it has been + * initialized. If we are running out of SDRAM now, we can assume that some + * second level boot loader has properly configured SRAM for us. In that + * case, we set the MMU flags for the final, fully cache-able state. + * + * Also, in this case, the mapping for the SDRAM was done in arm_head.S and + * need not be repeated here. + * + * If we are running from ISRAM or NOR flash, then we will need to configure + * the SDRAM ourselves. In this case, we set the MMU flags to the strongly + * ordered, non-cacheable state. We need this direct access to SDRAM in + * order to configure it. Once SDRAM has been initialized, it will be re- + * configured in its final state. + */ + +#ifdef NEED_SDRAM_MAPPING + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + MMU_STRONGLY_ORDERED, SAM_DDRCS_NSECTIONS + }, +#endif + + /* SAMA5 CS1-3 External Memories */ + +#ifdef CONFIG_SAMA5_EBICS1 + { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, + SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS2 + { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, + SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_EBICS3 + { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION, + SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS + }, +#endif +#ifdef CONFIG_SAMA5_HAVE_NAND + { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION, + SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS + }, +#endif + + /* SAMA5 Internal Peripherals + * + * Naming of peripheral sections differs between the SAMA5D3 and SAMA5D4. + * There is nothing called SYSC in the SAMA5D4 memory map. The third + * peripheral section is un-named in the SAMA5D4 memory map, but I have + * chosen the name PERIPHC for this usage. + */ + + { SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION, + SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS + }, + { SAM_PERIPHB_PSECTION, SAM_PERIPHB_VSECTION, + SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS + }, + { SAM_PERIPHC_PSECTION, SAM_PERIPHC_VSECTION, + SAM_PERIPHC_MMUFLAGS, SAM_PERIPHC_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + * + * If SDRAM will be reconfigured, then we will defer setup of the framebuffer + * until after the SDRAM remapping (since the framebuffer problem resides) in + * SDRAM. + */ + +#if defined(CONFIG_SAMA5_LCDC) && !defined(NEED_SDRAM_REMAPPING) + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the mapping table */ + +#define NMAPPINGS \ + (sizeof(g_section_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_mappings = NMAPPINGS; + +#endif /* CONFIG_ARCH_ROMPGTABLE */ + +/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING +const struct section_mapping_s g_operational_mapping[] = +{ + /* This entry reprograms the SDRAM entry, making it cacheable and + * bufferable. + */ + + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS + }, + + /* LCDC Framebuffer. This entry reprograms a part of one of the above + * regions, making it non-cacheable and non-buffereable. + */ + +#ifdef CONFIG_SAMA5_LCDC + { CONFIG_SAMA5_LCDC_FB_PBASE, CONFIG_SAMA5_LCDC_FB_VBASE, + MMU_IOFLAGS, SAMA5_LCDC_FBNSECTIONS + }, +#endif +}; + +/* The number of entries in the operational mapping table */ + +#define NREMAPPINGS \ + (sizeof(g_operational_mapping) / sizeof(struct section_mapping_s)) + +const size_t g_num_opmappings = NREMAPPINGS; + +#endif /* NEED_SDRAM_REMAPPING */ diff --git a/arch/arm/src/sama5/sama5d4x_periphclks.h b/arch/arm/src/sama5/sama5d4x_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..c4e14eda63c7fbf58672dca32faead2e4f487438 --- /dev/null +++ b/arch/arm/src/sama5/sama5d4x_periphclks.h @@ -0,0 +1,318 @@ +/************************************************************************************ + * arch/arm/src/sama5/sama5d4x_periphclks.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAMAD54X_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMA5_SAMAD54X_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) +#define sam_isenabled0(s) (getreg32(SAM_PMC_PCER0) & (1 << (s)) != 0) +#define sam_isenabled1(s) (getreg32(SAM_PMC_PCER1) & (1 << ((s) - 32)) != 0) + +/* Enable peripheral clocking */ + +#define sam_arm_enableclk() sam_enableperiph0(SAM_PID_ARM) +#define sam_pit_enableclk() sam_enableperiph0(SAM_PID_PIT) +#define sam_wdt_enableclk() sam_enableperiph0(SAM_PID_WDT) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_xdmac0_enableclk() sam_enableperiph0(SAM_PID_XDMAC0) +#define sam_icm_enableclk() sam_enableperiph0(SAM_PID_ICM) +#define sam_cpkcc_enableclk() sam_enableperiph0(SAM_PID_CPKCC) +#define sam_aes_enableclk() sam_enableperiph0(SAM_PID_AES) +#define sam_aesb_enableclk() sam_enableperiph0(SAM_PID_AESB) +#define sam_tdes_enableclk() sam_enableperiph0(SAM_PID_TDES) +#define sam_sha_enableclk() sam_enableperiph0(SAM_PID_SHA) +#define sam_mpddrc_enableclk() sam_enableperiph0(SAM_PID_MPDDRC) +#define sam_matrix1_enableclk() sam_enableperiph0(SAM_PID_MATRIX1) +#define sam_matrix0_enableclk() sam_enableperiph0(SAM_PID_MATRIX0) +#define sam_vdec_enableclk() sam_enableperiph0(SAM_PID_VDEC) +#define sam_sbm_enableclk() sam_enableperiph0(SAM_PID_SBM) +#define sam_hsmc_enableclk() sam_enableperiph0(SAM_PID_HSMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_usart3_enableclk() sam_enableperiph0(SAM_PID_USART3) +#define sam_usart4_enableclk() sam_enableperiph0(SAM_PID_USART4) + +#define sam_twi0_enableclk() sam_enableperiph1(SAM_PID_TWI0) +#define sam_twi1_enableclk() sam_enableperiph1(SAM_PID_TWI1) +#define sam_twi2_enableclk() sam_enableperiph1(SAM_PID_TWI2) +#define sam_hsmci0_enableclk() sam_enableperiph1(SAM_PID_HSMCI0) +#define sam_hsmci1_enableclk() sam_enableperiph1(SAM_PID_HSMCI1) +#define sam_spi0_enableclk() sam_enableperiph1(SAM_PID_SPI0) +#define sam_spi1_enableclk() sam_enableperiph1(SAM_PID_SPI1) +#define sam_spi2_enableclk() sam_enableperiph1(SAM_PID_SPI2) +#define sam_tc0_enableclk() sam_enableperiph1(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph1(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph1(SAM_PID_TC2) +#define sam_pwm_enableclk() sam_enableperiph1(SAM_PID_PWM) +#define sam_adc_enableclk() sam_enableperiph1(SAM_PID_ADC) +#define sam_dbgu_enableclk() sam_enableperiph1(SAM_PID_DBGU) +#define sam_uhphs_enableclk() sam_enableperiph1(SAM_PID_UHPHS) +#define sam_udphs_enableclk() sam_enableperiph1(SAM_PID_UDPHS) +#define sam_ssc0_enableclk() sam_enableperiph1(SAM_PID_SSC0) +#define sam_ssc1_enableclk() sam_enableperiph1(SAM_PID_SSC1) +#define sam_xdmac1_enableclk() sam_enableperiph1(SAM_PID_XDMAC1) +#define sam_lcdc_enableclk() sam_enableperiph1(SAM_PID_LCDC) +#define sam_isi_enableclk() sam_enableperiph1(SAM_PID_ISI) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_emac0_enableclk() sam_enableperiph1(SAM_PID_EMAC0) +#define sam_emac1_enableclk() sam_enableperiph1(SAM_PID_EMAC1) +#define sam_aicid_enableclk() sam_enableperiph1(SAM_PID_AICID) +#define sam_sfc_enableclk() sam_enableperiph1(SAM_PID_SFC) +#define sam_secureram_enableclk() sam_enableperiph1(SAM_PID_SECURAM) +#define sam_smd_enableclk() sam_enableperiph1(SAM_PID_SMD) +#define sam_twi3_enableclk() sam_enableperiph1(SAM_PID_TWI3) +#define sam_catb_enableclk() sam_enableperiph1(SAM_PID_CATB) + +/* The Advanced Interrupt Controller and L2CC cache controllers are + * continuously clocked. The Power Management Controller has no effect on + * their behavior. + * + * (I presume that this is true of the SFR as well since it has no PMC + * bits to control its clocking). + */ + +#define sam_sfr_enableclk() +#define sam_aic_enableclk() +#define sam_saic_enableclk() +#define sam_l2cc_enableclk() + +/* Disable peripheral clocking */ + +#define sam_arm_disableclk() sam_disableperiph0(SAM_PID_ARM) +#define sam_pit_disableclk() sam_disableperiph0(SAM_PID_PIT) +#define sam_wdt_disableclk() sam_disableperiph0(SAM_PID_WDT) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_xdmac0_disableclk() sam_disableperiph0(SAM_PID_XDMAC0) +#define sam_icm_disableclk() sam_disableperiph0(SAM_PID_ICM) +#define sam_cpkcc_disableclk() sam_disableperiph0(SAM_PID_CPKCC) +#define sam_aes_disableclk() sam_disableperiph0(SAM_PID_AES) +#define sam_aesb_disableclk() sam_disableperiph0(SAM_PID_AESB) +#define sam_tdes_disableclk() sam_disableperiph0(SAM_PID_TDES) +#define sam_sha_disableclk() sam_disableperiph0(SAM_PID_SHA) +#define sam_mpddrc_disableclk() sam_disableperiph0(SAM_PID_MPDDRC) +#define sam_matrix1_disableclk() sam_disableperiph0(SAM_PID_MATRIX1) +#define sam_matrix0_disableclk() sam_disableperiph0(SAM_PID_MATRIX0) +#define sam_vdec_disableclk() sam_disableperiph0(SAM_PID_VDEC) +#define sam_sbm_disableclk() sam_disableperiph0(SAM_PID_SBM) +#define sam_hsmc_disableclk() sam_disableperiph0(SAM_PID_HSMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_usart3_disableclk() sam_disableperiph0(SAM_PID_USART3) +#define sam_usart4_disableclk() sam_disableperiph0(SAM_PID_USART4) + +#define sam_twi0_disableclk() sam_disableperiph1(SAM_PID_TWI0) +#define sam_twi1_disableclk() sam_disableperiph1(SAM_PID_TWI1) +#define sam_twi2_disableclk() sam_disableperiph1(SAM_PID_TWI2) +#define sam_hsmci0_disableclk() sam_disableperiph1(SAM_PID_HSMCI0) +#define sam_hsmci1_disableclk() sam_disableperiph1(SAM_PID_HSMCI1) +#define sam_spi0_disableclk() sam_disableperiph1(SAM_PID_SPI0) +#define sam_spi1_disableclk() sam_disableperiph1(SAM_PID_SPI1) +#define sam_spi2_disableclk() sam_disableperiph1(SAM_PID_SPI2) +#define sam_tc0_disableclk() sam_disableperiph1(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph1(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph1(SAM_PID_TC2) +#define sam_pwm_disableclk() sam_disableperiph1(SAM_PID_PWM) +#define sam_adc_disableclk() sam_disableperiph1(SAM_PID_ADC) +#define sam_dbgu_disableclk() sam_disableperiph1(SAM_PID_DBGU) +#define sam_uhphs_disableclk() sam_disableperiph1(SAM_PID_UHPHS) +#define sam_udphs_disableclk() sam_disableperiph1(SAM_PID_UDPHS) +#define sam_ssc0_disableclk() sam_disableperiph1(SAM_PID_SSC0) +#define sam_ssc1_disableclk() sam_disableperiph1(SAM_PID_SSC1) +#define sam_xdmac1_disableclk() sam_disableperiph1(SAM_PID_XDMAC1) +#define sam_lcdc_disableclk() sam_disableperiph1(SAM_PID_LCDC) +#define sam_isi_disableclk() sam_disableperiph1(SAM_PID_ISI) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_emac0_disableclk() sam_disableperiph1(SAM_PID_EMAC0) +#define sam_emac1_disableclk() sam_disableperiph1(SAM_PID_EMAC1) +#define sam_aicid_disableclk() sam_disableperiph1(SAM_PID_AICID) +#define sam_sfc_disableclk() sam_disableperiph1(SAM_PID_SFC) +#define sam_secureram_disableclk() sam_disableperiph1(SAM_PID_SECURAM) +#define sam_smd_disableclk() sam_disableperiph1(SAM_PID_SMD) +#define sam_twi3_disableclk() sam_disableperiph1(SAM_PID_TWI3) +#define sam_catb_disableclk() sam_disableperiph1(SAM_PID_CATB) + +/* The Advanced Interrupt Controller and L2CC cache controllers are + * continuously clocked. The Power Management Controller has no effect on + * their behavior. + * + * (I presume that this is true of the SFR as well since it has no PMC + * bits to control its clocking). + */ + +#define sam_sfr_disableclk() +#define sam_aic_disableclk() +#define sam_saic_disableclk() +#define sam_l2cc_disableclk() + +/* Test if peripheral clocking is enabled */ + +#define sam_arm_isenabled() sam_isenabled0(SAM_PID_ARM) +#define sam_pit_isenabled() sam_isenabled0(SAM_PID_PIT) +#define sam_wdt_isenabled() sam_isenabled0(SAM_PID_WDT) +#define sam_piod_isenabled() sam_isenabled0(SAM_PID_PIOD) +#define sam_usart0_isenabled() sam_isenabled0(SAM_PID_USART0) +#define sam_usart1_isenabled() sam_isenabled0(SAM_PID_USART1) +#define sam_xdmac0_isenabled() sam_isenabled0(SAM_PID_XDMAC0) +#define sam_icm_isenabled() sam_isenabled0(SAM_PID_ICM) +#define sam_cpkcc_isenabled() sam_isenabled0(SAM_PID_CPKCC) +#define sam_aes_isenabled() sam_isenabled0(SAM_PID_AES) +#define sam_aesb_isenabled() sam_isenabled0(SAM_PID_AESB) +#define sam_tdes_isenabled() sam_isenabled0(SAM_PID_TDES) +#define sam_sha_isenabled() sam_isenabled0(SAM_PID_SHA) +#define sam_mpddrc_isenabled() sam_isenabled0(SAM_PID_MPDDRC) +#define sam_matrix1_isenabled() sam_isenabled0(SAM_PID_MATRIX1) +#define sam_matrix0_isenabled() sam_isenabled0(SAM_PID_MATRIX0) +#define sam_vdec_isenabled() sam_isenabled0(SAM_PID_VDEC) +#define sam_sbm_isenabled() sam_isenabled0(SAM_PID_SBM) +#define sam_hsmc_isenabled() sam_isenabled0(SAM_PID_HSMC) +#define sam_pioa_isenabled() sam_isenabled0(SAM_PID_PIOA) +#define sam_piob_isenabled() sam_isenabled0(SAM_PID_PIOB) +#define sam_pioc_isenabled() sam_isenabled0(SAM_PID_PIOC) +#define sam_pioe_isenabled() sam_isenabled0(SAM_PID_PIOE) +#define sam_uart0_isenabled() sam_isenabled0(SAM_PID_UART0) +#define sam_uart1_isenabled() sam_isenabled0(SAM_PID_UART1) +#define sam_usart2_isenabled() sam_isenabled0(SAM_PID_USART2) +#define sam_usart3_isenabled() sam_isenabled0(SAM_PID_USART3) +#define sam_usart4_isenabled() sam_isenabled0(SAM_PID_USART4) + +#define sam_twi0_isenabled() sam_isenabled1(SAM_PID_TWI0) +#define sam_twi1_isenabled() sam_isenabled1(SAM_PID_TWI1) +#define sam_twi2_isenabled() sam_isenabled1(SAM_PID_TWI2) +#define sam_hsmci0_isenabled() sam_isenabled1(SAM_PID_HSMCI0) +#define sam_hsmci1_isenabled() sam_isenabled1(SAM_PID_HSMCI1) +#define sam_spi0_isenabled() sam_isenabled1(SAM_PID_SPI0) +#define sam_spi1_isenabled() sam_isenabled1(SAM_PID_SPI1) +#define sam_spi2_isenabled() sam_isenabled1(SAM_PID_SPI2) +#define sam_tc0_isenabled() sam_isenabled1(SAM_PID_TC0) +#define sam_tc1_isenabled() sam_isenabled1(SAM_PID_TC1) +#define sam_tc2_isenabled() sam_isenabled1(SAM_PID_TC2) +#define sam_pwm_isenabled() sam_isenabled1(SAM_PID_PWM) +#define sam_adc_isenabled() sam_isenabled1(SAM_PID_ADC) +#define sam_dbgu_isenabled() sam_isenabled1(SAM_PID_DBGU) +#define sam_uhphs_isenabled() sam_isenabled1(SAM_PID_UHPHS) +#define sam_udphs_isenabled() sam_isenabled1(SAM_PID_UDPHS) +#define sam_ssc0_isenabled() sam_isenabled1(SAM_PID_SSC0) +#define sam_ssc1_isenabled() sam_isenabled1(SAM_PID_SSC1) +#define sam_xdmac1_isenabled() sam_isenabled1(SAM_PID_XDMAC1) +#define sam_lcdc_isenabled() sam_isenabled1(SAM_PID_LCDC) +#define sam_isi_isenabled() sam_isenabled1(SAM_PID_ISI) +#define sam_trng_isenabled() sam_isenabled1(SAM_PID_TRNG) +#define sam_emac0_isenabled() sam_isenabled1(SAM_PID_EMAC0) +#define sam_emac1_isenabled() sam_isenabled1(SAM_PID_EMAC1) +#define sam_aicid_isenabled() sam_isenabled1(SAM_PID_AICID) +#define sam_sfc_isenabled() sam_isenabled1(SAM_PID_SFC) +#define sam_secureram_isenabled() sam_isenabled1(SAM_PID_SECURAM) +#define sam_smd_isenabled() sam_isenabled1(SAM_PID_SMD) +#define sam_twi3_isenabled() sam_isenabled1(SAM_PID_TWI3) +#define sam_catb_isenabled() sam_isenabled1(SAM_PID_CATB) + +/* The Advanced Interrupt Controller and L2CC cache controllers are + * continuously clocked. The Power Management Controller has no effect on + * their behavior. + * + * (I presume that this is true of the SFR as well since it has no PMC + * bits to control its clocking). + */ + +#define sam_sfr_isenabled() (true) +#define sam_aic_isenabled() (true) +#define sam_saic_isenabled() (true) +#define sam_l2cc_isenabled() (true) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAMAD54X_PERIPHCLKS_H */ diff --git a/arch/arm/src/samdl/Kconfig b/arch/arm/src/samdl/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..68ea979f909ee22a4421333d87e545be05d9d0e9 --- /dev/null +++ b/arch/arm/src/samdl/Kconfig @@ -0,0 +1,724 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Atmel SAMD/L Configuration Options" + +choice + prompt "Atmel SAMD/L Chip Selection" + default ARCH_CHIP_SAMD20J18 if ARCH_CHIP_SAMD + default ARCH_CHIP_SAMD21J18 if ARCH_CHIP_SAML + depends on ARCH_CHIP_SAMD || ARCH_CHIP_SAML + +config ARCH_CHIP_SAMD20E14 + bool "SAMD20E14" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20E + ---help--- + Flash 16KB SRAM 2KB + +config ARCH_CHIP_SAMD20E15 + bool "SAMD20E15" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20E + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD20E16 + bool "SAMD20E16" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20E + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD20E17 + bool "SAMD20E17" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20E + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD20E18 + bool "SAMD20E18" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20E + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAMD20G14 + bool "SAMD20G14" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20G + ---help--- + Flash 16KB SRAM 2KB + +config ARCH_CHIP_SAMD20G15 + bool "SAMD20G15" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20G + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD20G16 + bool "SAMD20G16" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20G + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD20G17 + bool "SAMD20G17" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20G + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD20G18 + bool "SAMD20G18" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20G + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAMD20J14 + bool "SAMD20J14" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20J + ---help--- + Flash 16KB SRAM 2KB + +config ARCH_CHIP_SAMD20J15 + bool "SAMD20J15" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20J + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD20J16 + bool "SAMD20J16" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20J + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD20J17 + bool "SAMD20J17" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20J + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD20J18 + bool "SAMD20J18" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD20 + select ARCH_FAMILY_SAMD20J + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAMD21E15A + bool "SAMD21E15A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD21E15B + bool "SAMD21E15B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 32KB SRAM 4KB RWW FLASH 1KB + +config ARCH_CHIP_SAMD21E16A + bool "SAMD21E16A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD21E16B + bool "SAMD21E16B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 64KB SRAM 8KB RWW FLASH 2KB + +config ARCH_CHIP_SAMD21E17A + bool "SAMD21E17A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD21E18A + bool "SAMD21E18A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAMD21G15A + bool "SAMD21G15A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21G + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD21G15B + bool "SAMD21G15B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21G + ---help--- + Flash 32KB SRAM 4KB RWW FLASH 1KB + +config ARCH_CHIP_SAMD21G16A + bool "SAMD21G16A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21G + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD21G16B + bool "SAMD21G16B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 64KB SRAM 8KB RWW FLASH 2KB + +config ARCH_CHIP_SAMD21G17A + bool "SAMD21G17A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21G + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD21G18A + bool "SAMD21G18A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21G + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAMD21J15A + bool "SAMD21J15A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21J + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAMD21J15B + bool "SAMD21J15B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21J + ---help--- + Flash 32KB SRAM 4KB RWW FLASH 1KB + +config ARCH_CHIP_SAMD21J16A + bool "SAMD21J16A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21J + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAMD21J16B + bool "SAMD21J16B" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21J + ---help--- + Flash 64KB SRAM 8KB RWW FLASH 2KB + +config ARCH_CHIP_SAMD21J17A + bool "SAMD21J17A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21E + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAMD21J18A + bool "SAMD21J18A" + depends on ARCH_CHIP_SAMD + select ARCH_FAMILY_SAMD21 + select ARCH_FAMILY_SAMD21J + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAML21E15 + bool "SAML21E15" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21E + ---help--- + Flash 32KB SRAM 4KB + +config ARCH_CHIP_SAML21E16 + bool "SAML21E16" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21E + ---help--- + Flash 64KB SRAM 8KB + +config ARCH_CHIP_SAML21E17 + bool "SAML21E17" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21E + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAML21E18 + bool "SAML21E18" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21E + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAML21G16 + bool "SAML21G16" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21G + ---help--- + Flash 64KB SRAM 4KB + +config ARCH_CHIP_SAML21G17 + bool "SAML21G17" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21G + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAML21G18 + bool "SAML21G18" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21G + ---help--- + Flash 256KB SRAM 32KB + +config ARCH_CHIP_SAML21J16 + bool "SAML21J16" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21J + ---help--- + Flash 64KB SRAM 4KB + +config ARCH_CHIP_SAML21J17 + bool "SAML21J17" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21J + ---help--- + Flash 128KB SRAM 16KB + +config ARCH_CHIP_SAML21J18 + bool "SAML21J18" + depends on ARCH_CHIP_SAML + select ARCH_FAMILY_SAML21 + select ARCH_FAMILY_SAML21J + ---help--- + Flash 256KB SRAM 32KB + +endchoice + +config ARCH_FAMILY_SAMD20 + bool + default n + select SAMDL_HAVE_TC2 + select SAMDL_HAVE_TC3 + select SAMDL_HAVE_TC5 + +config ARCH_FAMILY_SAMD20E + bool + default n + +config ARCH_FAMILY_SAMD20G + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + +config ARCH_FAMILY_SAMD20J + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + select SAMDL_HAVE_TC6 + select SAMDL_HAVE_TC7 + +config ARCH_FAMILY_SAMD21 + bool + default n + select SAMDL_HAVE_DMAC + select SAMDL_HAVE_USB + +config ARCH_FAMILY_SAMD21E + bool + default n + +config ARCH_FAMILY_SAMD21G + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + +config ARCH_FAMILY_SAMD21J + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + select SAMDL_HAVE_TC2 + select SAMDL_HAVE_TC3 + select SAMDL_HAVE_TC5 + +config ARCH_FAMILY_SAML21 + bool + default n + select SAMDL_HAVE_DMAC + select SAMDL_HAVE_USB + +config ARCH_FAMILY_SAML21E + bool + default n + +config ARCH_FAMILY_SAML21G + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + +config ARCH_FAMILY_SAML21J + bool + default n + select SAMDL_HAVE_SERCOM4 + select SAMDL_HAVE_SERCOM5 + select SAMDL_HAVE_TC2 + select SAMDL_HAVE_TC3 + select SAMDL_HAVE_TC5 + +menu "SAMD/L Peripheral Support" + +config SAMDL_HAVE_DMAC + bool + default n + +config SAMDL_HAVE_SERCOM4 + bool + default n + +config SAMDL_HAVE_SERCOM5 + bool + default n + +config SAMDL_HAVE_TC5 + bool + default n + +config SAMDL_HAVE_TC2 + bool + default n + +config SAMDL_HAVE_TC3 + bool + default n + +config SAMDL_HAVE_TC6 + bool + default n + +config SAMDL_HAVE_TC7 + bool + default n + +config SAMDL_AC + bool "Analog Comparator" + default n + +config SAMDL_ADC + bool "Analog-to-Digital Converter" + default n + +config SAMDL_DAC + bool "Digital-to-Analog Converter" + default n + +config SAMDL_DMAC + bool "DMA Controller" + default n + select ARCH_DMA + depends on SAMDL_HAVE_DMAC && EXPERIMENTAL + +config SAMDL_EVSYS + bool "Event System" + default n + +config SAMDL_NVMCTRL + bool "Non-Volatile Memory Controller" + default n + +config SAMDL_PTC + bool "Peripheral Touch Controller" + default n + +config SAMDL_RTC + bool "Real Time Counter" + default n + +config SAMDL_SERCOM0 + bool "Serial Communication Interface 0" + default n + +config SAMDL_SERCOM1 + bool "Serial Communication Interface 1" + default n + +config SAMDL_SERCOM2 + bool "Serial Communication Interface 2" + default n + +config SAMDL_SERCOM3 + bool "Serial Communication Interface 3" + default n + +config SAMDL_SERCOM4 + bool "Serial Communication Interface 4" + default n + depends on SAMDL_HAVE_SERCOM4 + +config SAMDL_SERCOM5 + bool "Serial Communication Interface 5" + default n + depends on SAMDL_HAVE_SERCOM5 + +config SAMDL_TC0 + bool "Timer/Counter 0" + default n + +config SAMDL_TC1 + bool "Timer/Counter 1" + default n + +config SAMDL_TC2 + bool "Timer/Counter 2" + default n + depends on SAMDL_HAVE_TC2 + +config SAMDL_TC3 + bool "Timer/Counter 3" + default n + depends on SAMDL_HAVE_TC3 + +config SAMDL_TC4 + bool "Timer/Counter 4" + default n + +config SAMDL_TC5 + bool "Timer/Counter 5" + default n + depends on SAMDL_HAVE_TC5 + +config SAMDL_TC6 + bool "Timer/Counter 6" + default n + depends on SAMDL_HAVE_TC6 + +config SAMDL_TC7 + bool "Timer/Counter 7" + default n + depends on SAMDL_HAVE_TC7 + +config SAMDL_USB + bool "USB" + default n + depends on SAMDL_HAVE_USB + +config SAMDL_WDT + bool "Watchdog Timer" + default n + +endmenu + +choice + prompt "SERCOM0 mode" + default SAMDL_SERCOM0_ISUSART + depends on SAMDL_SERCOM0 + +config SAMDL_SERCOM0_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM0_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM0_ISUSART + bool "USART" + select ARCH_HAVE_USART0 + select USART0_ISUART + +endchoice + +config SAMDL_DMAC_NDESC + int "Number of additional DMA Descriptors" + default 0 + depends on SAMDL_DMAC + ---help--- + This provides the number of additional DMA descriptors that can be + use to support multi-linked DMA transfers. A minimum of 16 + descriptors will always be allocated (16 for the base descriptor which + overlap the writeback descriptors). If this value is set to zero, + then only single block DMA transfers can be supported. + + Each additional DMA descriptor will require 16-bytes for LPRAM + memory. + +choice + prompt "SERCOM1 mode" + default SAMDL_SERCOM1_ISUSART + depends on SAMDL_SERCOM1 + +config SAMDL_SERCOM1_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM1_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM1_ISUSART + bool "USART" + select ARCH_HAVE_USART1 + select USART1_ISUART + +endchoice + +choice + prompt "SERCOM2 mode" + default SAMDL_SERCOM2_ISUSART + depends on SAMDL_SERCOM2 + +config SAMDL_SERCOM2_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM2_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM2_ISUSART + bool "USART" + select ARCH_HAVE_USART2 + select USART2_ISUART + +endchoice + +choice + prompt "SERCOM3 mode" + default SAMDL_SERCOM3_ISUSART + depends on SAMDL_SERCOM3 + +config SAMDL_SERCOM3_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM3_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM3_ISUSART + bool "USART" + select ARCH_HAVE_USART3 + select USART3_ISUART + +endchoice + +choice + prompt "SERCOM4 mode" + default SAMDL_SERCOM4_ISUSART + depends on SAMDL_SERCOM4 + +config SAMDL_SERCOM4_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM4_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM4_ISUSART + bool "USART" + select ARCH_HAVE_USART4 + select USART4_ISUART + +endchoice + +choice + prompt "SERCOM5 mode" + default SAMDL_SERCOM5_ISUSART + depends on SAMDL_SERCOM5 + +config SAMDL_SERCOM5_ISI2C + bool "I2C" + select I2C + +config SAMDL_SERCOM5_ISSPI + bool "SPI" + select SAMDL_HAVE_SPI + +config SAMDL_SERCOM5_ISUSART + bool "USART" + select ARCH_HAVE_USART5 + select USART5_ISUART + +endchoice + +config SAMDL_HAVE_SPI + bool + select SPI + +if SAMDL_HAVE_SPI + +config SAMDL_SPI_REGDEBUG + bool "SPI register-Level Debug" + default n + depends on DEBUG_SPI + ---help--- + Enable very low-level register access debug. Depends on DEBUG_SPI. + +endif # SAMDL_HAVE_SPI diff --git a/arch/arm/src/samdl/Make.defs b/arch/arm/src/samdl/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..d9a82f959e592953e0732a5e8c066feda4e9fc7c --- /dev/null +++ b/arch/arm/src/samdl/Make.defs @@ -0,0 +1,102 @@ +############################################################################ +# arch/arm/src/samdl/Make.defs +# +# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +CMN_ASRCS = up_exception.S up_saveusercontext.S up_fullcontextrestore.S +CMN_ASRCS += up_switchcontext.S vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vectors.c up_vfork.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CMN_CSRCS += up_dumpnvic.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = sam_idle.c sam_irq.c sam_lowputc.c sam_port.c sam_sercom.c +CHIP_CSRCS += sam_serial.c sam_start.c sam_usart.c + +ifeq ($(CONFIG_ARCH_FAMILY_SAMD20),y) +CHIP_CSRCS += samd_clockconfig.c samd_gclk.c +else ifeq ($(CONFIG_ARCH_FAMILY_SAMD21),y) +CHIP_CSRCS += samd_clockconfig.c samd_gclk.c +else ifeq ($(CONFIG_ARCH_FAMILY_SAML21),y) +CHIP_CSRCS += saml_clockconfig.c saml_gclk.c +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += sam_userspace.c +endif + +ifeq ($(CONFIG_ARCH_IRQPRIO),y) +CHIP_CSRCS += sam_irqprio.c +endif + +ifeq ($(CONFIG_SAMDL_DMAC),y) +CHIP_CSRCS += sam_dmac.c +endif + +ifeq ($(CONFIG_SAMDL_HAVE_SPI),y) +CHIP_CSRCS += sam_spi.c +endif diff --git a/arch/arm/src/samdl/chip.h b/arch/arm/src/samdl/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..99d922e589e9957f55e86cd5d8618056bd9c7e42 --- /dev/null +++ b/arch/arm/src/samdl/chip.h @@ -0,0 +1,83 @@ +/************************************************************************************ + * arch/arm/src/samdl/chip.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* Define the number of interrupt vectors that need to be supported for this chip */ + +#define ARMV6M_PERIPHERAL_INTERRUPTS 25 + +/* Include the memory map file. Other chip hardware files should then include + * this file for the proper setup. + */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# include "chip/samd20_memorymap.h" +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd21_memorymap.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml21_memorymap.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_H */ diff --git a/arch/arm/src/samdl/chip/samd20_memorymap.h b/arch/arm/src/samdl/chip/samd20_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..99f8271ad5028f13b655c483d5e61bff78ae01df --- /dev/null +++ b/arch/arm/src/samdl/chip/samd20_memorymap.h @@ -0,0 +1,125 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd20_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_MEMORYMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* System Memory Map */ + +#define SAM_FLASH_BASE 0x00000000 /* Embedded FLASH memory space (<= 256KB) */ +#define SAM_CALIB_BASE 0x00800000 /* Calibration and auxiliary space */ +#define SAM_SRAM_BASE 0x20000000 /* Embedded SRAM memory space (<= 64KB) */ +#define SAM_AHBA_BASE 0x40000000 /* AHB-APB Bridge A (64KB) */ +#define SAM_AHBB_BASE 0x41000000 /* AHB-APB Bridge B (64KB) */ +#define SAM_AHBC_BASE 0x42000000 /* AHB-APB Bridge C (64KB) */ + +/* Calibration and Auxiliary Space */ + +#define SAM_LOCKBIT_BASE 0x00802000 /* LOCKBIT Base Address */ +#define SAM_AUX0_BASE 0x00804000 /* AUX0 offset address */ +#define SAM_AUX1_BASE 0x00806000 /* AUX1 offset address */ +# define SAM_AUX1_AREA1 0x00806000 /* Area 1 offset address (reserved, 64 bits) */ +# define SAM_AUX1_AREA2 0x00806008 /* Area 2 Device configuration area (64 bits) */ +# define SAM_AUX1_AREA3 0x00806010 /* Area 3 offset address (reserved, 128 bits) */ +# define SAM_AUX1_AREA4 0x00806020 /* Area 4 Software calibration area (256 bits) */ + +/* AHB-APB Bridge A */ + +#define SAM_PAC0_BASE 0x40000000 /* Peripheral Access Controller 0 */ +#define SAM_PM_BASE 0x40000400 /* Power Manager */ +#define SAM_SYSCTRL_BASE 0x40000800 /* System Controller */ +#define SAM_GCLK_BASE 0x40000c00 /* Generic Clock Controller */ +#define SAM_WDT_BASE 0x40001000 /* Watchdog Timer */ +#define SAM_RTC_BASE 0x40001400 /* Real-Time Counter */ +#define SAM_EIC_BASE 0x40001800 /* External Interrupt Controller */ + +/* AHB-APB Bridge B */ + +#define SAM_PAC1_BASE 0x41000000 /* Peripheral Access Controller 1 */ +#define SAM_DSU_BASE 0x41002000 /* Device Service Unit */ +#define SAM_NVMCTRL_BASE 0x41004000 /* Non-Volatile Memory Controller */ +#define SAM_PORT_BASE 0x41004400 /* Ports */ + +/* AHB-APB Bridge C */ + +#define SAM_PAC2_BASE 0x42000000 /* Peripheral Access Controller 2 */ +#define SAM_EVSYS_BASE 0x42000400 /* Event System */ +#define SAM_SERCOM0_BASE 0x42000800 /* Serial Communication Interface 0 */ +#define SAM_SERCOM1_BASE 0x42000c00 /* Serial Communication Interface 1 */ +#define SAM_SERCOM2_BASE 0x42001000 /* Serial Communication Interface 2 */ +#define SAM_SERCOM3_BASE 0x42001400 /* Serial Communication Interface 3 */ +#define SAM_SERCOM4_BASE 0x42001800 /* Serial Communication Interface 4 */ +#define SAM_SERCOM5_BASE 0x42001c00 /* Serial Communication Interface 5 */ +#define SAM_TC0_BASE 0x42002000 /* Timer/Counter 0 */ +#define SAM_TC1_BASE 0x42002400 /* Timer/Counter 1 */ +#define SAM_TC2_BASE 0x42002800 /* Timer/Counter 2 */ +#define SAM_TC3_BASE 0x42002c00 /* Timer/Counter 3 */ +#define SAM_TC4_BASE 0x42003000 /* Timer/Counter 4 */ +#define SAM_TC5_BASE 0x42003400 /* Timer/Counter 5 */ +#define SAM_TC6_BASE 0x42003800 /* Timer/Counter 6 */ +#define SAM_TC7_BASE 0x42003c00 /* Timer/Counter 7 */ +#define SAM_ADC_BASE 0x42004000 /* Analog-to-Digital Converter */ +#define SAM_AC_BASE 0x42004400 /* Analog Comparator*/ +#define SAM_DAC_BASE 0x42004800 /* Digital-to-Analog Converter */ +#define SAM_PTC_BASE 0x42004c00 /* Peripheral Touch Controller */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_MEMORYMAP_H */ diff --git a/arch/arm/src/samdl/chip/samd20_pinmap.h b/arch/arm/src/samdl/chip/samd20_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..655170aef57861d5bef67c05c8f9e77c86e290e6 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd20_pinmap.h @@ -0,0 +1,365 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd20_pinmap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_PINMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_PINMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* GPIO pin definitions *********************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the SERCOM0 PAD0 on PA8, then the following definition should appear in + * the board.h header file for that board: + * + * #define PORT_SERCOM0_PAD0 PORT_SERCOM0_PAD0_1 + * + * The driver will then automatically configure PA8 as the SERCOM0 PAD0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog comparator */ + +#define PORT_AC_CMP0_1 (PORT_FUNCH | PORTA | PORT_PIN12) +#define PORT_AC_CMP0_2 (PORT_FUNCH | PORTA | PORT_PIN18) +#define PORT_AC_CMP1_1 (PORT_FUNCH | PORTA | PORT_PIN13) +#define PORT_AC_CMP1_2 (PORT_FUNCH | PORTA | PORT_PIN19) + +/* ADC voltage references */ + +#define PORT_ADC_VREFA (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_ADC_VREFB (PORT_FUNCB | PORTA | PORT_PIN4) + +#define PORT_AIN0_1 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_AIN0_2 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN1_1 (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_AIN1_2 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN2_1 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN2_2 (PORT_FUNCB | PORTB | PORT_PIN8) +#define PORT_AIN3_1 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN3_2 (PORT_FUNCB | PORTB | PORT_PIN9) +#define PORT_AIN4 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN5 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN6 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN7 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN8 (PORT_FUNCB | PORTB | PORT_PIN0) +#define PORT_AIN9 (PORT_FUNCB | PORTB | PORT_PIN1) +#define PORT_AIN10 (PORT_FUNCB | PORTB | PORT_PIN2) +#define PORT_AIN11 (PORT_FUNCB | PORTB | PORT_PIN3) +#define PORT_AIN12 (PORT_FUNCB | PORTB | PORT_PIN4) +#define PORT_AIN13 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_AIN14 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_AIN15 (PORT_FUNCB | PORTB | PORT_PIN7) +#define PORT_AIN16 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_AIN17 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_AIN18 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_AIN19 (PORT_FUNCB | PORTA | PORT_PIN11) + +/* DAC */ + +#define PORT_DAC_VREFA (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_DAC_VOUT (PORT_FUNCB | PORTA | PORT_PIN2) + +/* External interrupts */ + +#define PORT_EXTINT0_1 (PORT_FUNCA | PORTA | PORT_PIN0) +#define PORT_EXTINT0_2 (PORT_FUNCA | PORTA | PORT_PIN16) +#define PORT_EXTINT0_3 (PORT_FUNCA | PORTB | PORT_PIN0) +#define PORT_EXTINT0_4 (PORT_FUNCA | PORTB | PORT_PIN16) +#define PORT_EXTINT1_1 (PORT_FUNCA | PORTA | PORT_PIN1) +#define PORT_EXTINT1_2 (PORT_FUNCA | PORTA | PORT_PIN17) +#define PORT_EXTINT1_3 (PORT_FUNCA | PORTB | PORT_PIN1) +#define PORT_EXTINT1_4 (PORT_FUNCA | PORTB | PORT_PIN17) +#define PORT_EXTINT2_1 (PORT_FUNCA | PORTA | PORT_PIN18) +#define PORT_EXTINT2_2 (PORT_FUNCA | PORTA | PORT_PIN2) +#define PORT_EXTINT2_3 (PORT_FUNCA | PORTB | PORT_PIN2) +#define PORT_EXTINT3_1 (PORT_FUNCA | PORTA | PORT_PIN19) +#define PORT_EXTINT3_2 (PORT_FUNCA | PORTA | PORT_PIN3) +#define PORT_EXTINT3_3 (PORT_FUNCA | PORTB | PORT_PIN3) +#define PORT_EXTINT4_1 (PORT_FUNCA | PORTA | PORT_PIN20) +#define PORT_EXTINT4_2 (PORT_FUNCA | PORTA | PORT_PIN4) +#define PORT_EXTINT4_3 (PORT_FUNCA | PORTB | PORT_PIN4) +#define PORT_EXTINT5_1 (PORT_FUNCA | PORTA | PORT_PIN21) +#define PORT_EXTINT5_2 (PORT_FUNCA | PORTA | PORT_PIN5) +#define PORT_EXTINT5_3 (PORT_FUNCA | PORTB | PORT_PIN5) +#define PORT_EXTINT6_1 (PORT_FUNCA | PORTA | PORT_PIN22) +#define PORT_EXTINT6_2 (PORT_FUNCA | PORTA | PORT_PIN6) +#define PORT_EXTINT6_3 (PORT_FUNCA | PORTB | PORT_PIN22) +#define PORT_EXTINT6_4 (PORT_FUNCA | PORTB | PORT_PIN6) +#define PORT_EXTINT7_1 (PORT_FUNCA | PORTA | PORT_PIN23) +#define PORT_EXTINT7_2 (PORT_FUNCA | PORTA | PORT_PIN7) +#define PORT_EXTINT7_3 (PORT_FUNCA | PORTB | PORT_PIN23) +#define PORT_EXTINT7_4 (PORT_FUNCA | PORTB | PORT_PIN7) +#define PORT_EXTINT8_1 (PORT_FUNCA | PORTA | PORT_PIN28) +#define PORT_EXTINT8_2 (PORT_FUNCA | PORTB | PORT_PIN8) +#define PORT_EXTINT9_1 (PORT_FUNCA | PORTA | PORT_PIN9) +#define PORT_EXTINT9_2 (PORT_FUNCA | PORTB | PORT_PIN9) +#define PORT_EXTINT10_1 (PORT_FUNCA | PORTA | PORT_PIN10) +#define PORT_EXTINT10_2 (PORT_FUNCA | PORTA | PORT_PIN30) +#define PORT_EXTINT10_3 (PORT_FUNCA | PORTB | PORT_PIN10) +#define PORT_EXTINT11_1 (PORT_FUNCA | PORTA | PORT_PIN11) +#define PORT_EXTINT11_2 (PORT_FUNCA | PORTA | PORT_PIN31) +#define PORT_EXTINT11_3 (PORT_FUNCA | PORTB | PORT_PIN11) +#define PORT_EXTINT12_1 (PORT_FUNCA | PORTA | PORT_PIN12) +#define PORT_EXTINT12_2 (PORT_FUNCA | PORTA | PORT_PIN24) +#define PORT_EXTINT12_3 (PORT_FUNCA | PORTB | PORT_PIN12) +#define PORT_EXTINT13_1 (PORT_FUNCA | PORTA | PORT_PIN13) +#define PORT_EXTINT13_2 (PORT_FUNCA | PORTA | PORT_PIN25) +#define PORT_EXTINT13_3 (PORT_FUNCA | PORTB | PORT_PIN13) +#define PORT_EXTINT14_1 (PORT_FUNCA | PORTA | PORT_PIN14) +#define PORT_EXTINT14_2 (PORT_FUNCA | PORTB | PORT_PIN14) +#define PORT_EXTINT14_3 (PORT_FUNCA | PORTB | PORT_PIN30) +#define PORT_EXTINT15_1 (PORT_FUNCA | PORTA | PORT_PIN15) +#define PORT_EXTINT15_2 (PORT_FUNCA | PORTA | PORT_PIN27) +#define PORT_EXTINT15_3 (PORT_FUNCA | PORTB | PORT_PIN15) +#define PORT_EXTINT15_4 (PORT_FUNCA | PORTB | PORT_PIN31) + +/* Generic clock controller I/O */ + +#define PORT_GCLK_IO0_1 (PORT_FUNCH | PORTA | PORT_PIN14) +#define PORT_GCLK_IO0_2 (PORT_FUNCH | PORTA | PORT_PIN27) +#define PORT_GCLK_IO0_3 (PORT_FUNCH | PORTA | PORT_PIN28) +#define PORT_GCLK_IO0_4 (PORT_FUNCH | PORTA | PORT_PIN30) +#define PORT_GCLK_IO0_5 (PORT_FUNCH | PORTB | PORT_PIN14) +#define PORT_GCLK_IO0_6 (PORT_FUNCH | PORTB | PORT_PIN22) +#define PORT_GCLK_IO1_1 (PORT_FUNCH | PORTA | PORT_PIN15) +#define PORT_GCLK_IO1_2 (PORT_FUNCH | PORTB | PORT_PIN15) +#define PORT_GCLK_IO1_3 (PORT_FUNCH | PORTB | PORT_PIN23) +#define PORT_GCLK_IO2_1 (PORT_FUNCH | PORTA | PORT_PIN16) +#define PORT_GCLK_IO2_2 (PORT_FUNCH | PORTB | PORT_PIN16) +#define PORT_GCLK_IO3_1 (PORT_FUNCH | PORTA | PORT_PIN17) +#define PORT_GCLK_IO3_2 (PORT_FUNCH | PORTB | PORT_PIN17) +#define PORT_GCLK_IO4_1 (PORT_FUNCH | PORTA | PORT_PIN10) +#define PORT_GCLK_IO4_2 (PORT_FUNCH | PORTA | PORT_PIN20) +#define PORT_GCLK_IO4_3 (PORT_FUNCH | PORTB | PORT_PIN10) +#define PORT_GCLK_IO5_1 (PORT_FUNCH | PORTA | PORT_PIN11) +#define PORT_GCLK_IO5_2 (PORT_FUNCH | PORTA | PORT_PIN21) +#define PORT_GCLK_IO5_3 (PORT_FUNCH | PORTB | PORT_PIN11) +#define PORT_GCLK_IO6_1 (PORT_FUNCH | PORTA | PORT_PIN22) +#define PORT_GCLK_IO6_2 (PORT_FUNCH | PORTB | PORT_PIN12) +#define PORT_GCLK_IO7_1 (PORT_FUNCH | PORTA | PORT_PIN23) +#define PORT_GCLK_IO7_2 (PORT_FUNCH | PORTB | PORT_PIN13) + +/* Non maskable interrupt */ + +#define PORT_NMI (PORT_FUNCA | PORTA | PORT_PIN8) + +/* Serial communication interface (SERCOM) */ + +#define PORT_SERCOM0_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN8) +#define PORT_SERCOM0_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN4) +#define PORT_SERCOM0_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN9) +#define PORT_SERCOM0_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN5) +#define PORT_SERCOM0_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN10) +#define PORT_SERCOM0_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN6) +#define PORT_SERCOM0_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN11) +#define PORT_SERCOM0_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN7) +#define PORT_SERCOM1_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN16) +#define PORT_SERCOM1_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN0) +#define PORT_SERCOM1_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN17) +#define PORT_SERCOM1_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN1) +#define PORT_SERCOM1_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN18) +#define PORT_SERCOM1_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN30) +#define PORT_SERCOM1_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN19) +#define PORT_SERCOM1_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN31) +#define PORT_SERCOM2_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN12) +#define PORT_SERCOM2_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN8) +#define PORT_SERCOM2_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN13) +#define PORT_SERCOM2_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN9) +#define PORT_SERCOM2_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN14) +#define PORT_SERCOM2_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN10) +#define PORT_SERCOM2_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN15) +#define PORT_SERCOM2_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN11) +#define PORT_SERCOM3_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN22) +#define PORT_SERCOM3_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN16) +#define PORT_SERCOM3_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN23) +#define PORT_SERCOM3_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN17) +#define PORT_SERCOM3_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN24) +#define PORT_SERCOM3_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN18) +#define PORT_SERCOM3_PAD2_3 (PORT_FUNCD | PORTA | PORT_PIN20) +#define PORT_SERCOM3_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN25) +#define PORT_SERCOM3_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN19) +#define PORT_SERCOM3_PAD3_3 (PORT_FUNCD | PORTA | PORT_PIN21) +#define PORT_SERCOM4_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN12) +#define PORT_SERCOM4_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN12) +#define PORT_SERCOM4_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN8) +#define PORT_SERCOM4_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN13) +#define PORT_SERCOM4_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN13) +#define PORT_SERCOM4_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN9) +#define PORT_SERCOM4_PAD2_1 (PORT_FUNCC | PORTB | PORT_PIN14) +#define PORT_SERCOM4_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN14) +#define PORT_SERCOM4_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN10) +#define PORT_SERCOM4_PAD3_1 (PORT_FUNCC | PORTB | PORT_PIN15) +#define PORT_SERCOM4_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN15) +#define PORT_SERCOM4_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN11) +#define PORT_SERCOM5_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN16) +#define PORT_SERCOM5_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN22) +#define PORT_SERCOM5_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN2) +#define PORT_SERCOM5_PAD0_4 (PORT_FUNCD | PORTB | PORT_PIN30) +#define PORT_SERCOM5_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN17) +#define PORT_SERCOM5_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN23) +#define PORT_SERCOM5_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN3) +#define PORT_SERCOM5_PAD1_4 (PORT_FUNCD | PORTB | PORT_PIN31) +#define PORT_SERCOM5_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN20) +#define PORT_SERCOM5_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN24) +#define PORT_SERCOM5_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN0) +#define PORT_SERCOM5_PAD2_4 (PORT_FUNCD | PORTB | PORT_PIN22) +#define PORT_SERCOM5_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN21) +#define PORT_SERCOM5_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN25) +#define PORT_SERCOM5_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN1) +#define PORT_SERCOM5_PAD3_4 (PORT_FUNCD | PORTB | PORT_PIN23) + +/* JTAG/SWI */ + +#define PORT_SWCLK (PORT_FUNCG | PORTA | PORT_PIN30) +#define PORT_SWDIO (PORT_FUNCG | PORTA | PORT_PIN31) + +/* Timer/Counters */ + +#define PORT_TC0_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN8) +#define PORT_TC0_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN4) +#define PORT_TC0_WO0_3 (PORT_FUNCF | PORTB | PORT_PIN30) +#define PORT_TC0_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN9) +#define PORT_TC0_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN5) +#define PORT_TC0_WO1_3 (PORT_FUNCF | PORTB | PORT_PIN31) +#define PORT_TC1_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN10) +#define PORT_TC1_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN30) +#define PORT_TC1_WO0_3 (PORT_FUNCF | PORTA | PORT_PIN6) +#define PORT_TC1_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN11) +#define PORT_TC1_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN31) +#define PORT_TC1_WO1_3 (PORT_FUNCF | PORTA | PORT_PIN7) +#define PORT_TC2_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN12) +#define PORT_TC2_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN0) +#define PORT_TC2_WO0_3 (PORT_FUNCF | PORTA | PORT_PIN16) +#define PORT_TC2_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN13) +#define PORT_TC2_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN1) +#define PORT_TC2_WO1_3 (PORT_FUNCF | PORTA | PORT_PIN17) +#define PORT_TC3_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN14) +#define PORT_TC3_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN18) +#define PORT_TC3_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN15) +#define PORT_TC3_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN19) +#define PORT_TC4_WO0_1 (PORT_FUNCE | PORTB | PORT_PIN12) +#define PORT_TC4_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN22) +#define PORT_TC4_WO0_3 (PORT_FUNCF | PORTB | PORT_PIN8) +#define PORT_TC4_WO1_1 (PORT_FUNCE | PORTB | PORT_PIN13) +#define PORT_TC4_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN23) +#define PORT_TC4_WO1_3 (PORT_FUNCF | PORTB | PORT_PIN9) +#define PORT_TC5_WO0_1 (PORT_FUNCE | PORTB | PORT_PIN14) +#define PORT_TC5_WO0_2 (PORT_FUNCF | PORTA | PORT_PIN24) +#define PORT_TC5_WO0_3 (PORT_FUNCF | PORTB | PORT_PIN10) +#define PORT_TC5_WO1_1 (PORT_FUNCE | PORTB | PORT_PIN15) +#define PORT_TC5_WO1_2 (PORT_FUNCF | PORTA | PORT_PIN25) +#define PORT_TC5_WO1_3 (PORT_FUNCF | PORTB | PORT_PIN11) +#define PORT_TC6_WO0_1 (PORT_FUNCE | PORTB | PORT_PIN16) +#define PORT_TC6_WO0_2 (PORT_FUNCF | PORTB | PORT_PIN2) +#define PORT_TC6_WO1_1 (PORT_FUNCE | PORTB | PORT_PIN17) +#define PORT_TC6_WO1_2 (PORT_FUNCF | PORTB | PORT_PIN3) +#define PORT_TC7_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN20) +#define PORT_TC7_WO0_2 (PORT_FUNCF | PORTB | PORT_PIN0) +#define PORT_TC7_WO0_3 (PORT_FUNCF | PORTB | PORT_PIN22) +#define PORT_TC7_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN21) +#define PORT_TC7_WO1_2 (PORT_FUNCF | PORTB | PORT_PIN1) +#define PORT_TC7_WO1_3 (PORT_FUNCF | PORTB | PORT_PIN23) + +/* Peripheral touch controller */ + +#define PORT_PTC_X0 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_PTC_X1 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_PTC_X2 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_PTC_X3 (PORT_FUNCB | PORTA | PORT_PIN11) +#define PORT_PTC_X4 (PORT_FUNCB | PORTA | PORT_PIN16) +#define PORT_PTC_X5 (PORT_FUNCB | PORTA | PORT_PIN17) +#define PORT_PTC_X6 (PORT_FUNCB | PORTA | PORT_PIN18) +#define PORT_PTC_X7 (PORT_FUNCB | PORTA | PORT_PIN19) +#define PORT_PTC_X8 (PORT_FUNCB | PORTA | PORT_PIN20) +#define PORT_PTC_X9 (PORT_FUNCB | PORTA | PORT_PIN21) +#define PORT_PTC_X10 (PORT_FUNCB | PORTA | PORT_PIN22) +#define PORT_PTC_X11 (PORT_FUNCB | PORTA | PORT_PIN23) +#define PORT_PTC_X12 (PORT_FUNCB | PORTB | PORT_PIN12) +#define PORT_PTC_X13 (PORT_FUNCB | PORTB | PORT_PIN13) +#define PORT_PTC_X14 (PORT_FUNCB | PORTB | PORT_PIN14) +#define PORT_PTC_X15 (PORT_FUNCB | PORTB | PORT_PIN15) + +#define PORT_PTC_Y0 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_PTC_Y1 (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_PTC_Y2 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_PTC_Y3 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_PTC_Y4 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_PTC_Y5 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_PTC_Y6 (PORT_FUNCB | PORTB | PORT_PIN0) +#define PORT_PTC_Y7 (PORT_FUNCB | PORTB | PORT_PIN1) +#define PORT_PTC_Y8 (PORT_FUNCB | PORTB | PORT_PIN2) +#define PORT_PTC_Y9 (PORT_FUNCB | PORTB | PORT_PIN3) +#define PORT_PTC_Y10 (PORT_FUNCB | PORTB | PORT_PIN4) +#define PORT_PTC_Y11 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_PTC_Y12 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_PTC_Y13 (PORT_FUNCB | PORTB | PORT_PIN7) +#define PORT_PTC_Y14 (PORT_FUNCB | PORTB | PORT_PIN8) +#define PORT_PTC_Y15 (PORT_FUNCB | PORTB | PORT_PIN9) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD20_PINMAP_H */ diff --git a/arch/arm/src/samdl/chip/samd21_memorymap.h b/arch/arm/src/samdl/chip/samd21_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..f9cfe70ebaa185c3df9920965ff52c1dd4fd8923 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd21_memorymap.h @@ -0,0 +1,130 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd21_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_MEMORYMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* System Memory Map */ + +#define SAM_FLASH_BASE 0x00000000 /* Embedded FLASH memory space (<= 256KB) */ +#define SAM_FLASHRWW_BASE 0x00100000 /* Embedded FLASH RWW memory space (<= 2KB) */ +#define SAM_CALIB_BASE 0x00800000 /* Calibration and auxiliary space */ +#define SAM_SRAM_BASE 0x20000000 /* Embedded SRAM memory space (<= 64KB) */ +#define SAM_AHBA_BASE 0x40000000 /* AHB-APB Bridge A (64KB) */ +#define SAM_AHBB_BASE 0x41000000 /* AHB-APB Bridge B (64KB) */ +#define SAM_AHBC_BASE 0x42000000 /* AHB-APB Bridge C (64KB) */ + +/* Calibration and Auxiliary Space */ + +#define SAM_AUTOCAL_BASE 0x00800000 /* Automatic Calibration row */ +#define SAM_AUX0_BASE 0x00804000 /* AUX0 offset address */ +#define SAM_AUX1_BASE 0x00806000 /* AUX1 offset address */ +# define SAM_AUX1_AREA1 0x00806000 /* Area 1 offset address (reserved, 64 bits) */ +# define SAM_AUX1_AREA2 0x00806008 /* Area 2 Device configuration area (64 bits) */ +# define SAM_AUX1_AREA3 0x00806010 /* Area 3 offset address (reserved, 128 bits) */ +# define SAM_AUX1_AREA4 0x00806020 /* Area 4 Software calibration area (256 bits) */ + +/* AHB-APB Bridge A */ + +#define SAM_PAC0_BASE 0x40000000 /* Peripheral Access Controller 0 */ +#define SAM_PM_BASE 0x40000400 /* Power Manager */ +#define SAM_SYSCTRL_BASE 0x40000800 /* System Controller */ +#define SAM_GCLK_BASE 0x40000c00 /* Generic Clock Controller */ +#define SAM_WDT_BASE 0x40001000 /* Watchdog Timer */ +#define SAM_RTC_BASE 0x40001400 /* Real-Time Counter */ +#define SAM_EIC_BASE 0x40001800 /* External Interrupt Controller */ + +/* AHB-APB Bridge B */ + +#define SAM_PAC1_BASE 0x41000000 /* Peripheral Access Controller 1 */ +#define SAM_DSU_BASE 0x41002000 /* Device Service Unit */ +#define SAM_NVMCTRL_BASE 0x41004000 /* Non-Volatile Memory Controller */ +#define SAM_PORT_BASE 0x41004400 /* Ports */ +#define SAM_DMAC_BASE 0x41004800 /* DMA Controller */ +#define SAM_USB_BASE 0x41005000 /* USB */ +#define SAM_MTB_BASE 0x41006000 /* Micro Trace Buffer (MTB) */ + +/* AHB-APB Bridge C */ + +#define SAM_PAC2_BASE 0x42000000 /* Peripheral Access Controller 2 */ +#define SAM_EVSYS_BASE 0x42000400 /* Event System */ +#define SAM_SERCOM0_BASE 0x42000800 /* Serial Communication Interface 0 */ +#define SAM_SERCOM1_BASE 0x42000c00 /* Serial Communication Interface 1 */ +#define SAM_SERCOM2_BASE 0x42001000 /* Serial Communication Interface 2 */ +#define SAM_SERCOM3_BASE 0x42001400 /* Serial Communication Interface 3 */ +#define SAM_SERCOM4_BASE 0x42001800 /* Serial Communication Interface 4 */ +#define SAM_SERCOM5_BASE 0x42001c00 /* Serial Communication Interface 5 */ +#define SAM_TCC0_BASE 0x42002000 /* Timer/Counter Control 0 */ +#define SAM_TCC1_BASE 0x42002400 /* Timer/Counter Control 1 */ +#define SAM_TCC2_BASE 0x42002800 /* Timer/Counter Control 2 */ +#define SAM_TC3_BASE 0x42002c00 /* Timer/Counter 3 */ +#define SAM_TC4_BASE 0x42003000 /* Timer/Counter 4 */ +#define SAM_TC5_BASE 0x42003400 /* Timer/Counter 5 */ +#define SAM_TC6_BASE 0x42003800 /* Timer/Counter 6 */ +#define SAM_TC7_BASE 0x42003c00 /* Timer/Counter 7 */ +#define SAM_ADC_BASE 0x42004000 /* Analog-to-Digital Converter */ +#define SAM_AC_BASE 0x42004400 /* Analog Comparator*/ +#define SAM_DAC_BASE 0x42004800 /* Digital-to-Analog Converter */ +#define SAM_PTC_BASE 0x42004c00 /* Peripheral Touch Controller */ +#define SAM_I2S_BASE 0x42005000 /* Inter IC Sound */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_MEMORYMAP_H */ diff --git a/arch/arm/src/samdl/chip/samd21_pinmap.h b/arch/arm/src/samdl/chip/samd21_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..7fd0888acf51cd8f2c15108281374b41a4bae858 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd21_pinmap.h @@ -0,0 +1,416 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd21_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_PINMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_PINMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* GPIO pin definitions *********************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the SERCOM0 PAD0 on PA8, then the following definition should appear in + * the board.h header file for that board: + * + * #define PORT_SERCOM0_PAD0 PORT_SERCOM0_PAD0_1 + * + * The driver will then automatically configure PA8 as the SERCOM0 PAD0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog comparator */ + +#define PORT_AC_CMP0_1 (PORT_FUNCH | PORTA | PORT_PIN12) +#define PORT_AC_CMP0_2 (PORT_FUNCH | PORTA | PORT_PIN18) +#define PORT_AC_CMP1_1 (PORT_FUNCH | PORTA | PORT_PIN13) +#define PORT_AC_CMP1_2 (PORT_FUNCH | PORTA | PORT_PIN19) + +/* ADC voltage references */ + +#define PORT_ADC_VREFA (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_ADC_VREFB (PORT_FUNCB | PORTA | PORT_PIN4) + +#define PORT_AIN0_1 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_AIN0_2 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN1_1 (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_AIN1_2 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN2_1 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN2_2 (PORT_FUNCB | PORTB | PORT_PIN8) +#define PORT_AIN3_1 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN3_2 (PORT_FUNCB | PORTB | PORT_PIN9) +#define PORT_AIN4 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN5 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN6 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN7 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN8 (PORT_FUNCB | PORTB | PORT_PIN0) +#define PORT_AIN9 (PORT_FUNCB | PORTB | PORT_PIN1) +#define PORT_AIN10 (PORT_FUNCB | PORTB | PORT_PIN2) +#define PORT_AIN11 (PORT_FUNCB | PORTB | PORT_PIN3) +#define PORT_AIN12 (PORT_FUNCB | PORTB | PORT_PIN4) +#define PORT_AIN13 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_AIN14 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_AIN15 (PORT_FUNCB | PORTB | PORT_PIN7) +#define PORT_AIN16 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_AIN17 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_AIN18 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_AIN19 (PORT_FUNCB | PORTA | PORT_PIN11) + +/* DAC */ + +#define PORT_DAC_VREFA (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_DAC_VOUT (PORT_FUNCB | PORTA | PORT_PIN2) + +/* External interrupts */ + +#define PORT_EXTINT0_1 (PORT_FUNCA | PORTA | PORT_PIN0) +#define PORT_EXTINT0_2 (PORT_FUNCA | PORTA | PORT_PIN16) +#define PORT_EXTINT0_3 (PORT_FUNCA | PORTB | PORT_PIN0) +#define PORT_EXTINT0_4 (PORT_FUNCA | PORTB | PORT_PIN16) +#define PORT_EXTINT1_1 (PORT_FUNCA | PORTA | PORT_PIN1) +#define PORT_EXTINT1_2 (PORT_FUNCA | PORTA | PORT_PIN17) +#define PORT_EXTINT1_3 (PORT_FUNCA | PORTB | PORT_PIN1) +#define PORT_EXTINT1_4 (PORT_FUNCA | PORTB | PORT_PIN17) +#define PORT_EXTINT2_1 (PORT_FUNCA | PORTA | PORT_PIN18) +#define PORT_EXTINT2_2 (PORT_FUNCA | PORTA | PORT_PIN2) +#define PORT_EXTINT2_3 (PORT_FUNCA | PORTB | PORT_PIN2) +#define PORT_EXTINT3_1 (PORT_FUNCA | PORTA | PORT_PIN19) +#define PORT_EXTINT3_2 (PORT_FUNCA | PORTA | PORT_PIN3) +#define PORT_EXTINT3_3 (PORT_FUNCA | PORTB | PORT_PIN3) +#define PORT_EXTINT4_1 (PORT_FUNCA | PORTA | PORT_PIN20) +#define PORT_EXTINT4_2 (PORT_FUNCA | PORTA | PORT_PIN4) +#define PORT_EXTINT4_3 (PORT_FUNCA | PORTB | PORT_PIN4) +#define PORT_EXTINT5_1 (PORT_FUNCA | PORTA | PORT_PIN21) +#define PORT_EXTINT5_2 (PORT_FUNCA | PORTA | PORT_PIN5) +#define PORT_EXTINT5_3 (PORT_FUNCA | PORTB | PORT_PIN5) +#define PORT_EXTINT6_1 (PORT_FUNCA | PORTA | PORT_PIN22) +#define PORT_EXTINT6_2 (PORT_FUNCA | PORTA | PORT_PIN6) +#define PORT_EXTINT6_3 (PORT_FUNCA | PORTB | PORT_PIN22) +#define PORT_EXTINT6_4 (PORT_FUNCA | PORTB | PORT_PIN6) +#define PORT_EXTINT7_1 (PORT_FUNCA | PORTA | PORT_PIN23) +#define PORT_EXTINT7_2 (PORT_FUNCA | PORTA | PORT_PIN7) +#define PORT_EXTINT7_3 (PORT_FUNCA | PORTB | PORT_PIN23) +#define PORT_EXTINT7_4 (PORT_FUNCA | PORTB | PORT_PIN7) +#define PORT_EXTINT8_1 (PORT_FUNCA | PORTA | PORT_PIN28) +#define PORT_EXTINT8_2 (PORT_FUNCA | PORTB | PORT_PIN8) +#define PORT_EXTINT9_1 (PORT_FUNCA | PORTA | PORT_PIN9) +#define PORT_EXTINT9_2 (PORT_FUNCA | PORTB | PORT_PIN9) +#define PORT_EXTINT10_1 (PORT_FUNCA | PORTA | PORT_PIN10) +#define PORT_EXTINT10_2 (PORT_FUNCA | PORTA | PORT_PIN30) +#define PORT_EXTINT10_3 (PORT_FUNCA | PORTB | PORT_PIN10) +#define PORT_EXTINT11_1 (PORT_FUNCA | PORTA | PORT_PIN11) +#define PORT_EXTINT11_2 (PORT_FUNCA | PORTA | PORT_PIN31) +#define PORT_EXTINT11_3 (PORT_FUNCA | PORTB | PORT_PIN11) +#define PORT_EXTINT12_1 (PORT_FUNCA | PORTA | PORT_PIN12) +#define PORT_EXTINT12_2 (PORT_FUNCA | PORTA | PORT_PIN24) +#define PORT_EXTINT12_3 (PORT_FUNCA | PORTB | PORT_PIN12) +#define PORT_EXTINT13_1 (PORT_FUNCA | PORTA | PORT_PIN13) +#define PORT_EXTINT13_2 (PORT_FUNCA | PORTA | PORT_PIN25) +#define PORT_EXTINT13_3 (PORT_FUNCA | PORTB | PORT_PIN13) +#define PORT_EXTINT14_1 (PORT_FUNCA | PORTA | PORT_PIN14) +#define PORT_EXTINT14_2 (PORT_FUNCA | PORTB | PORT_PIN14) +#define PORT_EXTINT14_3 (PORT_FUNCA | PORTB | PORT_PIN30) +#define PORT_EXTINT15_1 (PORT_FUNCA | PORTA | PORT_PIN15) +#define PORT_EXTINT15_2 (PORT_FUNCA | PORTA | PORT_PIN27) +#define PORT_EXTINT15_3 (PORT_FUNCA | PORTB | PORT_PIN15) +#define PORT_EXTINT15_4 (PORT_FUNCA | PORTB | PORT_PIN31) + +/* Generic clock controller I/O */ + +#define PORT_GCLK_IO0_1 (PORT_FUNCH | PORTA | PORT_PIN14) +#define PORT_GCLK_IO0_2 (PORT_FUNCH | PORTA | PORT_PIN27) +#define PORT_GCLK_IO0_3 (PORT_FUNCH | PORTA | PORT_PIN28) +#define PORT_GCLK_IO0_4 (PORT_FUNCH | PORTA | PORT_PIN30) +#define PORT_GCLK_IO0_5 (PORT_FUNCH | PORTB | PORT_PIN14) +#define PORT_GCLK_IO0_6 (PORT_FUNCH | PORTB | PORT_PIN22) +#define PORT_GCLK_IO1_1 (PORT_FUNCH | PORTA | PORT_PIN15) +#define PORT_GCLK_IO1_2 (PORT_FUNCH | PORTB | PORT_PIN15) +#define PORT_GCLK_IO1_3 (PORT_FUNCH | PORTB | PORT_PIN23) +#define PORT_GCLK_IO2_1 (PORT_FUNCH | PORTA | PORT_PIN16) +#define PORT_GCLK_IO2_2 (PORT_FUNCH | PORTB | PORT_PIN16) +#define PORT_GCLK_IO3_1 (PORT_FUNCH | PORTA | PORT_PIN17) +#define PORT_GCLK_IO3_2 (PORT_FUNCH | PORTB | PORT_PIN17) +#define PORT_GCLK_IO4_1 (PORT_FUNCH | PORTA | PORT_PIN10) +#define PORT_GCLK_IO4_2 (PORT_FUNCH | PORTA | PORT_PIN20) +#define PORT_GCLK_IO4_3 (PORT_FUNCH | PORTB | PORT_PIN10) +#define PORT_GCLK_IO5_1 (PORT_FUNCH | PORTA | PORT_PIN11) +#define PORT_GCLK_IO5_2 (PORT_FUNCH | PORTA | PORT_PIN21) +#define PORT_GCLK_IO5_3 (PORT_FUNCH | PORTB | PORT_PIN11) +#define PORT_GCLK_IO6_1 (PORT_FUNCH | PORTA | PORT_PIN22) +#define PORT_GCLK_IO6_2 (PORT_FUNCH | PORTB | PORT_PIN12) +#define PORT_GCLK_IO7_1 (PORT_FUNCH | PORTA | PORT_PIN23) +#define PORT_GCLK_IO7_2 (PORT_FUNCH | PORTB | PORT_PIN13) + +/* Inter IC Sound (I2S) */ + +#define PORT_I2S_FS0_1 (PORT_FUNCG | PORTA | PORT_PIN11) +#define PORT_I2S_FS0_2 (PORT_FUNCG | PORTA | PORT_PIN21) +#define PORT_I2S_FS1 (PORT_FUNCG | PORTB | PORT_PIN12) +#define PORT_I2S_MCK0_1 (PORT_FUNCG | PORTA | PORT_PIN9) +#define PORT_I2S_MCK0_2 (PORT_FUNCG | PORTB | PORT_PIN17) +#define PORT_I2S_MCK1 (PORT_FUNCG | PORTB | PORT_PIN10) +#define PORT_I2S_SCK0_1 (PORT_FUNCG | PORTA | PORT_PIN10) +#define PORT_I2S_SCK0_2 (PORT_FUNCG | PORTA | PORT_PIN20) +#define PORT_I2S_SCK1 (PORT_FUNCG | PORTB | PORT_PIN11) +#define PORT_I2S_SD0_1 (PORT_FUNCG | PORTA | PORT_PIN19) +#define PORT_I2S_SD0_2 (PORT_FUNCG | PORTA | PORT_PIN7) +#define PORT_I2S_SD1_1 (PORT_FUNCG | PORTA | PORT_PIN8) +#define PORT_I2S_SD1_2 (PORT_FUNCG | PORTB | PORT_PIN16) + +/* Non maskable interrupt */ + +#define PORT_NMI (PORT_FUNCA | PORTA | PORT_PIN8) + +/* Serial communication interface (SERCOM) */ + +#define PORT_SERCOM0_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN8) +#define PORT_SERCOM0_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN4) +#define PORT_SERCOM0_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN9) +#define PORT_SERCOM0_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN5) +#define PORT_SERCOM0_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN10) +#define PORT_SERCOM0_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN6) +#define PORT_SERCOM0_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN11) +#define PORT_SERCOM0_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN7) +#define PORT_SERCOM1_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN16) +#define PORT_SERCOM1_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN0) +#define PORT_SERCOM1_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN17) +#define PORT_SERCOM1_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN1) +#define PORT_SERCOM1_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN18) +#define PORT_SERCOM1_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN30) +#define PORT_SERCOM1_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN19) +#define PORT_SERCOM1_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN31) +#define PORT_SERCOM2_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN12) +#define PORT_SERCOM2_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN8) +#define PORT_SERCOM2_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN13) +#define PORT_SERCOM2_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN9) +#define PORT_SERCOM2_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN14) +#define PORT_SERCOM2_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN10) +#define PORT_SERCOM2_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN15) +#define PORT_SERCOM2_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN11) +#define PORT_SERCOM3_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN22) +#define PORT_SERCOM3_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN16) +#define PORT_SERCOM3_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN23) +#define PORT_SERCOM3_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN17) +#define PORT_SERCOM3_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN24) +#define PORT_SERCOM3_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN18) +#define PORT_SERCOM3_PAD2_3 (PORT_FUNCD | PORTA | PORT_PIN20) +#define PORT_SERCOM3_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN25) +#define PORT_SERCOM3_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN19) +#define PORT_SERCOM3_PAD3_3 (PORT_FUNCD | PORTA | PORT_PIN21) +#define PORT_SERCOM4_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN12) +#define PORT_SERCOM4_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN12) +#define PORT_SERCOM4_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN8) +#define PORT_SERCOM4_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN13) +#define PORT_SERCOM4_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN13) +#define PORT_SERCOM4_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN9) +#define PORT_SERCOM4_PAD2_1 (PORT_FUNCC | PORTB | PORT_PIN14) +#define PORT_SERCOM4_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN14) +#define PORT_SERCOM4_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN10) +#define PORT_SERCOM4_PAD3_1 (PORT_FUNCC | PORTB | PORT_PIN15) +#define PORT_SERCOM4_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN15) +#define PORT_SERCOM4_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN11) +#define PORT_SERCOM5_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN16) +#define PORT_SERCOM5_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN22) +#define PORT_SERCOM5_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN2) +#define PORT_SERCOM5_PAD0_4 (PORT_FUNCD | PORTB | PORT_PIN30) +#define PORT_SERCOM5_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN17) +#define PORT_SERCOM5_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN23) +#define PORT_SERCOM5_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN3) +#define PORT_SERCOM5_PAD1_4 (PORT_FUNCD | PORTB | PORT_PIN31) +#define PORT_SERCOM5_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN20) +#define PORT_SERCOM5_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN24) +#define PORT_SERCOM5_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN0) +#define PORT_SERCOM5_PAD2_4 (PORT_FUNCD | PORTB | PORT_PIN22) +#define PORT_SERCOM5_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN21) +#define PORT_SERCOM5_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN25) +#define PORT_SERCOM5_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN1) +#define PORT_SERCOM5_PAD3_4 (PORT_FUNCD | PORTB | PORT_PIN23) + +/* JTAG/SWI */ + +#define PORT_SWCLK (PORT_FUNCG | PORTA | PORT_PIN30) +#define PORT_SWDIO (PORT_FUNCG | PORTA | PORT_PIN31) + +/* Timer/Counters */ + +#define PORT_TC3_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN14) +#define PORT_TC3_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN18) +#define PORT_TC3_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN15) +#define PORT_TC3_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN19) +#define PORT_TC4_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN22) +#define PORT_TC4_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN12) +#define PORT_TC4_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN8) +#define PORT_TC4_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN23) +#define PORT_TC4_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN13) +#define PORT_TC4_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN9) +#define PORT_TC5_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN24) +#define PORT_TC5_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN10) +#define PORT_TC5_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN14) +#define PORT_TC5_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN25) +#define PORT_TC5_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN11) +#define PORT_TC5_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN15) +#define PORT_TC6_WO0_1 (PORT_FUNCE | PORTB | PORT_PIN16) +#define PORT_TC6_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN2) +#define PORT_TC6_WO1_1 (PORT_FUNCE | PORTB | PORT_PIN17) +#define PORT_TC6_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN3) +#define PORT_TC7_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN20) +#define PORT_TC7_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN0) +#define PORT_TC7_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN22) +#define PORT_TC7_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN21) +#define PORT_TC7_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN1) +#define PORT_TC7_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN23) + +/* Timer/Counters for Control */ + +#define PORT_TCC0_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN4) +#define PORT_TCC0_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN8) +#define PORT_TCC0_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN30) +#define PORT_TCC0_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN5) +#define PORT_TCC0_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN9) +#define PORT_TCC0_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN31) +#define PORT_TCC0_WO2_1 (PORT_FUNCF | PORTA | PORT_PIN18) +#define PORT_TCC0_WO2_2 (PORT_FUNCE | PORTA | PORT_PIN10) +#define PORT_TCC0_WO3_1 (PORT_FUNCF | PORTA | PORT_PIN11) +#define PORT_TCC0_WO3_2 (PORT_FUNCF | PORTA | PORT_PIN19) +#define PORT_TCC0_WO4_1 (PORT_FUNCF | PORTA | PORT_PIN14) +#define PORT_TCC0_WO4_2 (PORT_FUNCF | PORTA | PORT_PIN22) +#define PORT_TCC0_WO4_3 (PORT_FUNCF | PORTB | PORT_PIN10) +#define PORT_TCC0_WO4_4 (PORT_FUNCF | PORTB | PORT_PIN16) +#define PORT_TCC0_WO5_1 (PORT_FUNCF | PORTA | PORT_PIN15) +#define PORT_TCC0_WO5_2 (PORT_FUNCF | PORTA | PORT_PIN23) +#define PORT_TCC0_WO5_3 (PORT_FUNCF | PORTB | PORT_PIN11) +#define PORT_TCC0_WO5_4 (PORT_FUNCF | PORTB | PORT_PIN17) +#define PORT_TCC0_WO6_1 (PORT_FUNCF | PORTA | PORT_PIN12) +#define PORT_TCC0_WO6_2 (PORT_FUNCF | PORTA | PORT_PIN16) +#define PORT_TCC0_WO6_3 (PORT_FUNCF | PORTA | PORT_PIN20) +#define PORT_TCC0_WO6_4 (PORT_FUNCF | PORTB | PORT_PIN12) +#define PORT_TCC0_WO7_1 (PORT_FUNCF | PORTA | PORT_PIN13) +#define PORT_TCC0_WO7_2 (PORT_FUNCF | PORTA | PORT_PIN17) +#define PORT_TCC0_WO7_3 (PORT_FUNCF | PORTA | PORT_PIN21) +#define PORT_TCC0_WO7_4 (PORT_FUNCF | PORTB | PORT_PIN13) +#define PORT_TCC1_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN10) +#define PORT_TCC1_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN30) +#define PORT_TCC1_WO0_3 (PORT_FUNCE | PORTA | PORT_PIN6) +#define PORT_TCC1_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN11) +#define PORT_TCC1_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN31) +#define PORT_TCC1_WO1_3 (PORT_FUNCE | PORTA | PORT_PIN7) +#define PORT_TCC1_WO2_1 (PORT_FUNCF | PORTA | PORT_PIN24) +#define PORT_TCC1_WO2_2 (PORT_FUNCF | PORTA | PORT_PIN8) +#define PORT_TCC1_WO2_3 (PORT_FUNCF | PORTB | PORT_PIN30) +#define PORT_TCC1_WO3_1 (PORT_FUNCF | PORTA | PORT_PIN25) +#define PORT_TCC1_WO3_2 (PORT_FUNCF | PORTA | PORT_PIN9) +#define PORT_TCC1_WO3_3 (PORT_FUNCF | PORTB | PORT_PIN31) +#define PORT_TCC2_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN0) +#define PORT_TCC2_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN12) +#define PORT_TCC2_WO0_3 (PORT_FUNCE | PORTA | PORT_PIN16) +#define PORT_TCC2_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN1) +#define PORT_TCC2_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN13) +#define PORT_TCC2_WO1_3 (PORT_FUNCE | PORTA | PORT_PIN17) + +/* USB */ + +#define PORT_USB_DM (PORT_FUNCG | PORTA | PORT_PIN24) +#define PORT_USB_DP (PORT_FUNCG | PORTA | PORT_PIN25) +#define PORT_USB_SOF (PORT_FUNCG | PORTA | PORT_PIN23) + +/* Peripheral touch controller */ + +#define PORT_PTC_X0 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN8) +#define PORT_PTC_X1 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN9) +#define PORT_PTC_X2 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN10) +#define PORT_PTC_X3 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN11) +#define PORT_PTC_X4 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN16) +#define PORT_PTC_X5 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN17) +#define PORT_PTC_X6 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN18) +#define PORT_PTC_X7 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN19) +#define PORT_PTC_X8 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN20) +#define PORT_PTC_X9 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN21) +#define PORT_PTC_X10 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN22) +#define PORT_PTC_X11 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN23) +#define PORT_PTC_X12 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN12) +#define PORT_PTC_X13 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN13) +#define PORT_PTC_X14 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN14) +#define PORT_PTC_X15 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN15) + +#define PORT_PTC_Y0 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN2) +#define PORT_PTC_Y1 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN3) +#define PORT_PTC_Y2 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN4) +#define PORT_PTC_Y3 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN5) +#define PORT_PTC_Y4 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN6) +#define PORT_PTC_Y5 (PORT_PTC_FUNCB | PORTA | PORT_PTC_PIN7) +#define PORT_PTC_Y6 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN0) +#define PORT_PTC_Y7 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN1) +#define PORT_PTC_Y8 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN2) +#define PORT_PTC_Y9 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN3) +#define PORT_PTC_Y10 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN4) +#define PORT_PTC_Y11 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN5) +#define PORT_PTC_Y12 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN6) +#define PORT_PTC_Y13 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN7) +#define PORT_PTC_Y14 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN8) +#define PORT_PTC_Y15 (PORT_PTC_FUNCB | PORTB | PORT_PTC_PIN9) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD21_PINMAP_H */ diff --git a/arch/arm/src/samdl/chip/samd_evsys.h b/arch/arm/src/samdl/chip/samd_evsys.h new file mode 100644 index 0000000000000000000000000000000000000000..e1489a2622b62554fcc9f5b13ba6c446c0702f3e --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_evsys.h @@ -0,0 +1,352 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_evsys.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EVSYS_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EVSYS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* EVSYS register offsets *******************************************************************/ + +#define SAM_EVSYS_CTRL_OFFSET 0x0000 /* Control register */ +#define SAM_EVSYS_CHANNEL_OFFSET 0x0004 /* Channel register */ +#define SAM_EVSYS_USER_OFFSET 0x0008 /* User multiplexer register */ +#define SAM_EVSYS_CHSTATUS_OFFSET 0x000c /* Channel status register */ +#define SAM_EVSYS_INTENCLR_OFFSET 0x0010 /* Interrupt enable clear register */ +#define SAM_EVSYS_INTENSET_OFFSET 0x0014 /* Interrupt enable set register */ +#define SAM_EVSYS_INTFLAG_OFFSET 0x0018 /* Interrupt flag status and clear register */ + +/* EVSYS register addresses *****************************************************************/ + +#define SAM_EVSYS_CTRL (SAM_EVSYS_BASE+SAM_EVSYS_CTRL_OFFSET) +#define SAM_EVSYS_CHANNEL (SAM_EVSYS_BASE+SAM_EVSYS_CHANNEL_OFFSET) +#define SAM_EVSYS_USER (SAM_EVSYS_BASE+SAM_EVSYS_USER_OFFSET) +#define SAM_EVSYS_CHSTATUS (SAM_EVSYS_BASE+SAM_EVSYS_CHSTATUS_OFFSET +#define SAM_EVSYS_INTENCLR (SAM_EVSYS_BASE+SAM_EVSYS_INTENCLR_OFFSET +#define SAM_EVSYS_INTENSET (SAM_EVSYS_BASE+SAM_EVSYS_INTENSET_OFFSET +#define SAM_EVSYS_INTFLAG (SAM_EVSYS_BASE+SAM_EVSYS_INTFLAG_OFFSET) + +/* EVSYS register bit definitions ***********************************************************/ + +/* Control register */ + +#define EVSYS_CTRL_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define EVSYS_CTRL_GCLKREQ (1 << 4) /* Bit 4: Generic Clock Requests */ + +/* Channel register */ + +#define EVSYS_CHANNEL_SHIFT (0) /* Bits 0-3: Channel Selection */ +#define EVSYS_CHANNEL_MASK (0xff << EVSYS_CHANNEL_SHIFT) +# define EVSYS_CHANNEL(n) ((uint32_t)(n) << EVSYS_CHANNEL_SHIFT) +#define EVSYS_CHANNEL_SWEVT (1 << 8) /* Bit 8: Software Event */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define EVSYS_CHANNEL_EVGEN_SHIFT (16) /* Bits 16-23: Event Generator */ +# define EVSYS_CHANNEL_EVGEN_MASK (0xff << EVSYS_CHANNEL_EVGEN_SHIFT) +# define EVSYS_CHANNEL_EVGEN_NONE (0 << EVSYS_CHANNEL_EVGEN_SHIFT) /* No event generator selected */ +# define EVSYS_CHANNEL_EVGEN_RTCCMP0 (1 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Compare 0 or Alarm 0 */ +# define EVSYS_CHANNEL_EVGEN_RTCCMP1 (2 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Compare 1 */ +# define EVSYS_CHANNEL_EVGEN_RTCOVF (3 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Overflow */ +# define EVSYS_CHANNEL_EVGEN_RTCPER0 (4 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 0 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER1 (5 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 1 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER2 (6 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 2 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER3 (7 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 3 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER4 (8 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 4 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER5 (9 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 5 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER6 (10 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 6 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER7 (11 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 7 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT0 (12 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 0 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT1 (13 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 1 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT2 (14 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 2 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT3 (15 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 3 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT4 (16 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 4 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT5 (17 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 5 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT6 (18 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 6 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT7 (19 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 7 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT8 (20 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 8 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT9 (21 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 9 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT10 (22 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 10 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT11 (23 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 11 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT12 (24 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 12 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT13 (25 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 13 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT14 (26 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 14 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT15 (27 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 15 */ +# define EVSYS_CHANNEL_EVGEN_TC0OVF (28 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC0 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC0MC0 (29 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC0 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC0MC1 (30 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC0 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC1OVF (31 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC1MC0 (32 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC1MC1 (33 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC2OVF (34 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC2MC0 (35 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC2MC1 (36 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC3OVF (37 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC3MC0 (38 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC3MC1 (39 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC4OVF (40 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC4MC0 (41 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC4MC1 (42 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC5OVF (43 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC5MC0 (44 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC5MC1 (45 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC6OVF (46 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC6MC0 (47 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC6MC1 (48 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC7OVF (49 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC7MC0 (50 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC7MC1 (51 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_ADCRESRDY (52 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC Result Ready */ +# define EVSYS_CHANNEL_EVGEN_ADCWINMON (53 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC Window Monitor */ +# define EVSYS_CHANNEL_EVGEN_ACCOMP0 (54 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Comparator 0 */ +# define EVSYS_CHANNEL_EVGEN_ACCOMP1 (55 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Comparator 1 */ +# define EVSYS_CHANNEL_EVGEN_ACWIN (56 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Window 0 */ +# define EVSYS_CHANNEL_EVGEN_DACEMPTY (57 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DAC Data Buffer Empty */ +# define EVSYS_CHANNEL_EVGEN_PTCEOC (58 << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC End of Conversion */ +# define EVSYS_CHANNEL_EVGEN_PTCWCOMP (59 << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC Window Comparator */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define EVSYS_CHANNEL_EVGEN_SHIFT (16) /* Bits 16-22: Event Generator */ +# define EVSYS_CHANNEL_EVGEN_MASK (0x7f << EVSYS_CHANNEL_EVGEN_SHIFT) +# define EVSYS_CHANNEL_EVGEN_NONE (0 << EVSYS_CHANNEL_EVGEN_SHIFT) /* No event generator selected */ +# define EVSYS_CHANNEL_EVGEN_RTCCMP0 (1 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Compare 0 or Alarm 0 */ +# define EVSYS_CHANNEL_EVGEN_RTCCMP1 (2 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Compare 1 */ +# define EVSYS_CHANNEL_EVGEN_RTCOVF (3 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Overflow */ +# define EVSYS_CHANNEL_EVGEN_RTCPER0 (4 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 0 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER1 (5 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 1 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER2 (6 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 2 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER3 (7 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 3 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER4 (8 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 4 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER5 (9 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 5 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER6 (10 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 6 */ +# define EVSYS_CHANNEL_EVGEN_RTCPER7 (11 << EVSYS_CHANNEL_EVGEN_SHIFT) /* RTC Period 7 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT0 (12 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 0 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT1 (13 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 1 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT2 (14 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 2 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT3 (15 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 3 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT4 (16 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 4 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT5 (17 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 5 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT6 (18 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 6 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT7 (19 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 7 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT8 (20 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 8 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT9 (21 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 9 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT10 (22 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 10 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT11 (23 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 11 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT12 (24 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 12 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT13 (25 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 13 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT14 (26 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 14 */ +# define EVSYS_CHANNEL_EVGEN_EXTINT15 (27 << EVSYS_CHANNEL_EVGEN_SHIFT) /* EIC External Interrupt 15 */ +# define EVSYS_CHANNEL_EVGEN_DMACH0 (30 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMAC CH0 Channel 0 */ +# define EVSYS_CHANNEL_EVGEN_DMACH1 (31 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMAC CH1 Channel 1 */ +# define EVSYS_CHANNEL_EVGEN_DMACH2 (32 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMAC CH2 Channel 2 */ +# define EVSYS_CHANNEL_EVGEN_DMACH3 (33 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMAC CH3 Channel 3 */ +# define EVSYS_CHANNEL_EVGEN_TCC0OVF (34 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TCC0TRG (35 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Trig */ +# define EVSYS_CHANNEL_EVGEN_TCC0CNT (36 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Counter */ +# define EVSYS_CHANNEL_EVGEN_TCC0MCX0 (37 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCC0MCX1 (38 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TCC0MCX2 (39 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Match/Capture 2 */ +# define EVSYS_CHANNEL_EVGEN_TCC0MCX3 (40 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 Match/Capture 3 */ +# define EVSYS_CHANNEL_EVGEN_TCC1OVF (41 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TCC1TRG (42 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 Trig */ +# define EVSYS_CHANNEL_EVGEN_TCC1CNT (43 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 Counter */ +# define EVSYS_CHANNEL_EVGEN_TCC1MCX0 (44 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCC1MCX1 (45 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TCC2OVF (46 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TCC2TRG (47 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 Trig */ +# define EVSYS_CHANNEL_EVGEN_TCC2CNT (48 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 Counter */ +# define EVSYS_CHANNEL_EVGEN_TCC2MCX0 (49 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCC2MCX1 (50 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC3OVF (51 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC3MC0 (52 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC3MC1 (53 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC4OVF (54 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC4MC0 (55 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC4MC1 (56 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC5OVF (57 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC5MC0 (58 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC5MC1 (59 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC5 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC6OVF (60 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC6MC0 (61 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC6MC1 (62 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC6 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC7OVF (63 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Overflow/Underflow */ +# define EVSYS_CHANNEL_EVGEN_TC7MC0 (64 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Match/Capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC7MC1 (65 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC7 Match/Capture 1 */ +# define EVSYS_CHANNEL_EVGEN_ADCRESRDY (66 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC Result Ready */ +# define EVSYS_CHANNEL_EVGEN_ADCWINMON (67 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC Window Monitor */ +# define EVSYS_CHANNEL_EVGEN_ACCOMP0 (68 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Comparator 0 */ +# define EVSYS_CHANNEL_EVGEN_ACCOMP1 (69 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Comparator 1 */ +# define EVSYS_CHANNEL_EVGEN_ACWIN (70 << EVSYS_CHANNEL_EVGEN_SHIFT) /* AC Window 0 */ +# define EVSYS_CHANNEL_EVGEN_DACEMPTY (71 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DAC Data Buffer Empty */ +# define EVSYS_CHANNEL_EVGEN_PTCEOC (72 << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC End of Conversion */ +# define EVSYS_CHANNEL_EVGEN_PTCWCOMP (73 << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC Window Comparator */ +#endif + +#define EVSYS_CHANNEL_PATH_SHIFT (24) /* Bits 24-25: Path Selection */ +#define EVSYS_CHANNEL_PATH_MASK (3 << EVSYS_CHANNEL_PATH_SHIFT) +# define EVSYS_CHANNEL_PATH_SYNCH (0 << EVSYS_CHANNEL_PATH_SHIFT) /* Synchronous path */ +# define EVSYS_CHANNEL_PATH_RESYNCH (1 << EVSYS_CHANNEL_PATH_SHIFT) /* Resynchronized path */ +# define EVSYS_CHANNEL_PATH_ASYNCH (2 << EVSYS_CHANNEL_PATH_SHIFT) /* Asynchronous path */ +#define EVSYS_CHANNEL_EDGSEL_SHIFT (26) /* Bits 26-27: Edge Detection Selection */ +#define EVSYS_CHANNEL_EDGSEL_MASK (3 << EVSYS_CHANNEL_EDGSEL_SHIFT) +# define EVSYS_CHANNEL_EDGSEL_NOEVT (0 << EVSYS_CHANNEL_EDGSEL_SHIFT) /* No event output */ +# define EVSYS_CHANNEL_EDGSEL_RISING (1 << EVSYS_CHANNEL_EDGSEL_SHIFT) /* Event detection on rising edge */ +# define EVSYS_CHANNEL_EDGSEL_FALLING (2 << EVSYS_CHANNEL_EDGSEL_SHIFT) /* Event detection on falling edge */ +# define EVSYS_CHANNEL_EDGSEL_BOTH (3 << EVSYS_CHANNEL_EDGSEL_SHIFT) /* Event detection on both edges */ + +/* User multiplexer register */ + +#define EVSYS_USER_SHIFT (0) /* Bits 0-4: User Multiplexer Selection */ +#define EVSYS_USER_MASK (0x1f << EVSYS_USER_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define EVSYS_USER_TC0 (0 << EVSYS_USER_SHIFT) /* TC0 paths */ +# define EVSYS_USER_TC1 (1 << EVSYS_USER_SHIFT) /* TC1 paths */ +# define EVSYS_USER_TC2 (2 << EVSYS_USER_SHIFT) /* TC2 paths */ +# define EVSYS_USER_TC3 (3 << EVSYS_USER_SHIFT) /* TC3 paths */ +# define EVSYS_USER_TC4 (4 << EVSYS_USER_SHIFT) /* TC4 paths */ +# define EVSYS_USER_TC5 (5 << EVSYS_USER_SHIFT) /* TC5 paths */ +# define EVSYS_USER_TC6 (6 << EVSYS_USER_SHIFT) /* TC6 paths */ +# define EVSYS_USER_TC7 (7 << EVSYS_USER_SHIFT) /* TC7 paths */ +# define EVSYS_USER_ADCSTART (8 << EVSYS_USER_SHIFT) /* ADC start conversion asynch path */ +# define EVSYS_USER_ADCSYNC (9 << EVSYS_USER_SHIFT) /* Flush ADC asynch path */ +# define EVSYS_USER_ACCOMP0 (10 << EVSYS_USER_SHIFT) /* Start comparator 0 asynch path */ +# define EVSYS_USER_ACCOMP1 (11 << EVSYS_USER_SHIFT) /* Start comparator 1 asynch path */ +# define EVSYS_USER_DACSTART (12 << EVSYS_USER_SHIFT) /* DAC start conversion asynch path */ +# define EVSYS_USER_PTCSTCONV (13 << EVSYS_USER_SHIFT) /* PTC start conversion asynch path */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define EVSYS_USER_DMACH0 (0 << EVSYS_USER_SHIFT) /* DMAC Channel 0 resync path */ +# define EVSYS_USER_DMACH1 (1 << EVSYS_USER_SHIFT) /* DMAC Channel 1 resync path only */ +# define EVSYS_USER_DMACH2 (2 << EVSYS_USER_SHIFT) /* DMAC Channel 2 resync path only */ +# define EVSYS_USER_DMACH3 (3 << EVSYS_USER_SHIFT) /* DMAC Channel 3 resync path only */ +# define EVSYS_USER_TCC0EV0 (4 << EVSYS_USER_SHIFT) /* TCC0 EV0 async, sync and resync paths */ +# define EVSYS_USER_TCC0EV1 (5 << EVSYS_USER_SHIFT) /* TCC0 EV1 async, sync and resync paths */ +# define EVSYS_USER_TCC0MC0 (6 << EVSYS_USER_SHIFT) /* TCC0 Match/Capture 0 async, sync and resync paths */ +# define EVSYS_USER_TCC0MC1 (7 << EVSYS_USER_SHIFT) /* TCC0 Match/Capture 1 async, sync and resync paths */ +# define EVSYS_USER_TCC0MC2 (8 << EVSYS_USER_SHIFT) /* TCC0 Match/Capture 2 async, sync and resync paths */ +# define EVSYS_USER_TCCMC3 (9 << EVSYS_USER_SHIFT) /* TCC0 Match/Capture 3 async, sync and resync paths */ +# define EVSYS_USER_TCC1EV0 (10 << EVSYS_USER_SHIFT) /* TCC1 EV0 async, sync and resync paths */ +# define EVSYS_USER_TCC1EV1 (11 << EVSYS_USER_SHIFT) /* TCC1 EV1 async, sync and resync paths */ +# define EVSYS_USER_TCC1MC0 (12 << EVSYS_USER_SHIFT) /* TCC1 Match/Capture 0 async, sync and resync paths */ +# define EVSYS_USER_TCC1MC1 (13 << EVSYS_USER_SHIFT) /* TCC1 Match/Capture 1 async, sync and resync paths */ +# define EVSYS_USER_TCC2EV0 (14 << EVSYS_USER_SHIFT) /* TCC2 EV0 async, sync and resync paths */ +# define EVSYS_USER_TCC2EV1 (15 << EVSYS_USER_SHIFT) /* TCC2 EV1 async, sync and resync paths */ +# define EVSYS_USER_TCC2MC0 (16 << EVSYS_USER_SHIFT) /* TCC2 Match/Capture 0 async, sync and resync paths */ +# define EVSYS_USER_TCC2MC1 (17 << EVSYS_USER_SHIFT) /* TCC2 Match/Capture 1 async, sync and resync paths */ +# define EVSYS_USER_TC3 (18 << EVSYS_USER_SHIFT) /* TC3 async, sync and resync paths */ +# define EVSYS_USER_TC4 (19 << EVSYS_USER_SHIFT) /* TC4 async, sync and resync paths */ +# define EVSYS_USER_TC5 (10 << EVSYS_USER_SHIFT) /* TC5 async, sync and resync paths */ +# define EVSYS_USER_TC6 (21 << EVSYS_USER_SHIFT) /* TC6 async, TC and resync paths */ +# define EVSYS_USER_TC7 (22 << EVSYS_USER_SHIFT) /* TC7 async, sync and resync paths */ +# define EVSYS_USER_ADCSTART (23 << EVSYS_USER_SHIFT) /* ADC start conversion asynch path */ +# define EVSYS_USER_ADCSYNC (24 << EVSYS_USER_SHIFT) /* Flush ADC asynch path */ +# define EVSYS_USER_ACCOMP0 (25 << EVSYS_USER_SHIFT) /* Start comparator 0 asynch path */ +# define EVSYS_USER_ACCOMP1 (26 << EVSYS_USER_SHIFT) /* Start comparator 1 asynch path */ +# define EVSYS_USER_DACSTART (27 << EVSYS_USER_SHIFT) /* DAC start conversion asynch path */ +# define EVSYS_USER_PTCSTCONV (28 << EVSYS_USER_SHIFT) /* PTC start conversion asynch path */ +#endif + +#define EVSYS_USER_CHANNEL_SHIFT (8) /* Bits 8-12: Channel Event Selection */ +#define EVSYS_USER_CHANNEL_MASK (0x1f << EVSYS_USER_CHANNEL_SHIFT) +# define EVSYS_USER_CHANNEL_NONE (0 << EVSYS_USER_CHANNEL_SHIFT) /* No channel output selected */ +# define EVSYS_USER_CHANNEL(n) ((uint16_t)((n)+1) << EVSYS_USER_CHANNEL_SHIFT) + +/* Channel status register */ + +#define EVSYS_CHSTATUS_USRRDY_SHIFT (0) /* Bits 0-7: User Ready for Channel n, n=0-7 */ +#define EVSYS_CHSTATUS_USRRDY_MASK (0xff << EVSYS_CHSTATUS_USRRDY_SHIFT) +# define EVSYS_CHSTATUS_USRRDY(n) (1 << (n)) +#define EVSYS_CHSTATUS_CHBUSY_SHIFT (8) /* Bits 8-15: Channel Busy n, n=0-7 */ +#define EVSYS_CHSTATUS_CHBUSY_MASK (0xff << EVSYS_CHSTATUS_CHBUSY_SHIFT) +# define EVSYS_CHSTATUS_CHBUSY(n) (1 << ((n) + 8)) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define EVSYS_CHSTATUS_USRRDYH_SHIFT (16) /* Bits 16-19: User Ready for Channel n, n=8-11 */ +# define EVSYS_CHSTATUS_USRRDYH_MASK (15 << EVSYS_CHSTATUS_USRRDYH_SHIFT) +# define EVSYS_CHSTATUS_USRRDYH(n) (1 << ((n) + 8)) +# define EVSYS_CHSTATUS_CHBUSYH_SHIFT (24) /* Bits 24-27: Channel Busy n, n=8-11 */ +# define EVSYS_CHSTATUS_CHBUSYH_MASK (15 << EVSYS_CHSTATUS_CHBUSYH_SHIFT) +# define EVSYS_CHSTATUS_CHBUSYH(n) (1 << ((n) + 16)) +#endif + +/* Interrupt enable clear, interrupt enable set, and interrupt flag status and clear registers */ + +#define EVSYS_INT_OVR_SHIFT (0) /* Bits 0-7: Overrun channel n interrupt, n=0-7 */ +#define EVSYS_INT_OVR_MASK (0xff << EVSYS_INT_OVR_SHIFT) +# define EVSYS_INT_OVR(n) (1 << (n)) +#define EVSYS_INT_EVD_SHIFT (8) /* Bits 8-15: Event detected channel n interrupt, n=0-7 */ +#define EVSYS_INT_EVD_MASK (0xff << EVSYS_INT_EVD_SHIFT) +# define EVSYS_INT_EVD(n) (1 << ((n) + 8)) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define EVSYS_INT_OVR_SHIFT (16) /* Bits 16-19: Overrun channel n interrupt, n=8-11 */ +# define EVSYS_INT_OVR_MASK (15 << EVSYS_INT_OVR_SHIFT) +# define EVSYS_INT_OVR(n) (1 << ((n) + 8)) +# define EVSYS_INT_EVD_SHIFT (24) /* Bits 24-27: Event detected channel n interrupt, n=8-11 */ +# define EVSYS_INT_EVD_MASK (15 << EVSYS_INT_EVD_SHIFT) +# define EVSYS_INT_EVD(n) (1 << ((n) + 16)) +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EVSYS_H */ diff --git a/arch/arm/src/samdl/chip/samd_fuses.h b/arch/arm/src/samdl/chip/samd_fuses.h new file mode 100644 index 0000000000000000000000000000000000000000..afd53e8acf4c3c5e2e18bf0921e6080d891bbab3 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_fuses.h @@ -0,0 +1,298 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_fuses.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Some fuse-related definitions derive from Atmel sample code: + * + * Copyright (c) 2013 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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 __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_FUSES_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_FUSES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Fuse definitions *************************************************************************/ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define NVMCTRL_FUSES_LOCKFIELD_ADDR (SAM_LOCKBIT_BASE + 0) +# define NVMCTRL_FUSES_LOCKFIELD_SHIFT (0) /* LOCK Region */ +# define NVMCTRL_FUSES_LOCKFIELD_MASK (0xff << NVMCTRL_FUSES_LOCKFIELD_SHIFT) +# define NVMCTRL_FUSES_LOCKFIELD(n) ((n) << NVMCTRL_FUSES_LOCKFIELD_SHIFT) +#endif + +#define NVMCTRL_FUSES_BOOTPROT_ADDR (SAM_AUX0_BASE + 0) +#define NVMCTRL_FUSES_BOOTPROT_SHIFT (0) /* Bits 0-2: Bootloader Size */ +#define NVMCTRL_FUSES_BOOTPROT_MASK (7 << NVMCTRL_FUSES_BOOTPROT_SHIFT) +# define NVMCTRL_FUSES_BOOTPROT(n) ((n) << NVMCTRL_FUSES_BOOTPROT_SHIFT) + +#define NVMCTRL_FUSES_EEPROM_SIZE_ADDR (SAM_AUX0_BASE + 0) +#define NVMCTRL_FUSES_EEPROM_SIZE_SHIFT (4) /* Bits 4-6: EEPROM Size */ +#define NVMCTRL_FUSES_EEPROM_SIZE_MASK (7 << NVMCTRL_FUSES_EEPROM_SIZE_SHIFT) +# define NVMCTRL_FUSES_EEPROM_SIZE(n) ((n) << NVMCTRL_FUSES_EEPROM_SIZE_SHIFT) + +#define SYSCTRL_FUSES_BOD33USERLEVEL_ADDR (SAM_AUX0_BASE + 8) +#define SYSCTRL_FUSES_BOD33USERLEVEL_SHIFT (8) /* Bits 8-13: BOD33 User Level */ +#define SYSCTRL_FUSES_BOD33USERLEVEL_MASK (0x3f << SYSCTRL_FUSES_BOD33USERLEVEL_SHIFT) +# define SYSCTRL_FUSES_BOD33USERLEVEL(n) ((n) << SYSCTRL_FUSES_BOD33USERLEVEL_SHIFT) + +#define SYSCTRL_FUSES_BOD33_EN_ADDR (SAM_AUX0_BASE + 0) +#define SYSCTRL_FUSES_BOD33_EN_SHIFT (14) /* Bit 14: BOD33 Enable */ +#define SYSCTRL_FUSES_BOD33_EN_MASK (1 << SYSCTRL_FUSES_BOD33_EN_SHIFT) + +#define SYSCTRL_FUSES_BOD33_ACTION_ADDR (SAM_AUX0_BASE + 0) +#define SYSCTRL_FUSES_BOD33_ACTION_SHIFT (15) /* Bits 15-16: BOD33 Action */ +#define SYSCTRL_FUSES_BOD33_ACTION_MASK (3 << SYSCTRL_FUSES_BOD33_ACTION_SHIFT) +# define SYSCTRL_FUSES_BOD33_ACTION(n) ((n) << SYSCTRL_FUSES_BOD33_ACTION_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SYSCTRL_FUSES_BOD12USERLEVEL_ADDR (SAM_AUX0_BASE + 0) +# define SYSCTRL_FUSES_BOD12USERLEVEL_SHIFT (17) /* Bit 17: BOD12 User Level */ +# define SYSCTRL_FUSES_BOD12USERLEVEL_MASK (0x1f << SYSCTRL_FUSES_BOD12USERLEVEL_SHIFT) +# define SYSCTRL_FUSES_BOD12USERLEVEL(n) ((n) << SYSCTRL_FUSES_BOD12USERLEVEL_SHIFT) +# define SYSCTRL_FUSES_BOD12_ACTION_ADDR (SAM_AUX0_BASE + 0) +# define SYSCTRL_FUSES_BOD12_EN_ADDR (SAM_AUX0_BASE + 0) +# define SYSCTRL_FUSES_BOD12_EN_SHIFT (22) /* Bit 22: BOD12 Enable */ +# define SYSCTRL_FUSES_BOD12_EN_MASK (1 << SYSCTRL_FUSES_BOD12_EN_SHIFT) +# define SYSCTRL_FUSES_BOD12_ACTION_SHIFT (23) /* Bits 23-24: BOD12 Action */ +# define SYSCTRL_FUSES_BOD12_ACTION_MASK (3 << SYSCTRL_FUSES_BOD12_ACTION_SHIFT) +# define SYSCTRL_FUSES_BOD12_ACTION(n) ((n) << SYSCTRL_FUSES_BOD12_ACTION_SHIFT) +#endif + +#define WDT_FUSES_ENABLE_ADDR (SAM_AUX0_BASE + 0) +#define WDT_FUSES_ENABLE_SHIFT (25) /* Bit 25: WDT Enable */ +#define WDT_FUSES_ENABLE_MASK (1 << WDT_FUSES_ENABLE_SHIFT) + +#define WDT_FUSES_ALWAYSON_ADDR (SAM_AUX0_BASE + 0) +#define WDT_FUSES_ALWAYSON_SHIFT (26) /* Bit 26: WDT Always On */ +#define WDT_FUSES_ALWAYSON_MASK (1 << WDT_FUSES_ALWAYSON_SHIFT) + +#define WDT_FUSES_PER_ADDR (SAM_AUX0_BASE + 0) +#define WDT_FUSES_PER_SHIFT (27) /* Bits 27-30: WDT Period */ +#define WDT_FUSES_PER_MASK (15 << WDT_FUSES_PER_SHIFT) +# define WDT_FUSES_PER(n) ((n) << WDT_FUSES_PER_SHIFT) + +#define WDT_FUSES_WINDOW_0_ADDR (SAM_AUX0_BASE + 0) +#define WDT_FUSES_WINDOW_0_SHIFT (31) /* Bit 31: WDT Window bit 0 */ +#define WDT_FUSES_WINDOW_0_MASK (1 << WDT_FUSES_WINDOW_0_SHIFT) + +#define WDT_FUSES_WINDOW_1_ADDR (SAM_AUX0_BASE + 4) +#define WDT_FUSES_WINDOW_1_SHIFT (0) /* Bits 32-34: WDT Window bits 3:1 */ +#define WDT_FUSES_WINDOW_1_MASK (7 << WDT_FUSES_WINDOW_1_SHIFT) +# define WDT_FUSES_WINDOW_1(n) ((n) << WDT_FUSES_WINDOW_1_SHIFT) + +#define WDT_FUSES_EWOFFSET_ADDR (SAM_AUX0_BASE + 4) +#define WDT_FUSES_EWOFFSET_SHIFT (3) /* Bits 35-38: WDT Early Warning Offset */ +#define WDT_FUSES_EWOFFSET_MASK (15 << WDT_FUSES_EWOFFSET_SHIFT) +# define WDT_FUSES_EWOFFSET(n) ((n) << WDT_FUSES_EWOFFSET_SHIFT) + +#define WDT_FUSES_WEN_ADDR (SAM_AUX0_BASE + 4) +#define WDT_FUSES_WEN_SHIFT (7) /* Bit 39: WDT Window Mode Enable */ +#define WDT_FUSES_WEN_MASK (1 << WDT_FUSES_WEN_SHIFT) + +#define NVMCTRL_FUSES_REGION_LOCKS_ADDR (SAM_AUX0_BASE + 4) +#define NVMCTRL_FUSES_REGION_LOCKS_SHIFT (16) /* Bits 48-63: NVM Region Locks */ +#define NVMCTRL_FUSES_REGION_LOCKS_MASK (0xffff << NVMCTRL_FUSES_REGION_LOCKS_SHIFT) +# define NVMCTRL_FUSES_REGION_LOCKS(n) ((n) << NVMCTRL_FUSES_REGION_LOCKS_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define NVMCTRL_FUSES_NVM_LOCK_ADDR (SAM_AUX1_AREA1 + 0) +# define NVMCTRL_FUSES_NVM_LOCK_SHIFT (0) /* Bits 0-7: NVM Lock */ +# define NVMCTRL_FUSES_NVM_LOCK_MASK (0xff << NVMCTRL_FUSES_NVM_LOCK_SHIFT) +# define NVMCTRL_FUSES_NVM_LOCK(n) ((n) << NVMCTRL_FUSES_NVM_LOCK_SHIFT) + +# define NVMCTRL_FUSES_PSZ_ADDR (SAM_AUX1_AREA1 + 0) +# define NVMCTRL_FUSES_PSZ_SHIFT (8) /* Bits 8-11: NVM Page Size */ +# define NVMCTRL_FUSES_PSZ_MASK (15 << NVMCTRL_FUSES_PSZ_SHIFT) +# define NVMCTRL_FUSES_PSZ(n) ((n) << NVMCTRL_FUSES_PSZ_SHIFT) + +# define NVMCTRL_FUSES_NVMP_ADDR (SAM_AUX1_AREA1 + 0) +# define NVMCTRL_FUSES_NVMP_SHIFT (16) /* Bits 16-31: Number of NVM Pages */ +# define NVMCTRL_FUSES_NVMP_MASK (0xffff << NVMCTRL_FUSES_NVMP_SHIFT) +# define NVMCTRL_FUSES_NVMP(n) ((n) << NVMCTRL_FUSES_NVMP_SHIFT) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define DSU_FUSES_DCFG0_ADDR (SAM_AUX1_AREA2 + 0) +# define DSU_FUSES_DCFG0_SHIFT (0) /* Bits 0-31: Device Configuration 0 */ +# define DSU_FUSES_DCFG0_MASK (0xffffffff << DSU_FUSES_DCFG0_SHIFT) +# define DSU_FUSES_DCFG0(n) ((n) << DSU_FUSES_DCFG0_SHIFT) + +# define DSU_FUSES_DID_DEVSEL_ADDR (SAM_AUX1_AREA2 + 0) +# define DSU_FUSES_DID_DEVSEL_SHIFT (0) /* Bits 0-4: Device Number */ +# define DSU_FUSES_DID_DEVSEL_MASK (0x1f << DSU_FUSES_DID_DEVSEL_SHIFT) +# define DSU_FUSES_DID_DEVSEL(n) ((n) << DSU_FUSES_DID_DEVSEL_SHIFT) + +# define DSU_FUSES_DEV_FAMILY_CFG_0_ADDR (SAM_AUX1_AREA2 + 0) +# define DSU_FUSES_DEV_FAMILY_CFG_0_SHIFT (5) /* Bits 5-31: Device Family Configuration bits 26:0 */ +# define DSU_FUSES_DEV_FAMILY_CFG_0_MASK (0x7ffffff << DSU_FUSES_DEV_FAMILY_CFG_0_SHIFT) +# define DSU_FUSES_DEV_FAMILY_CFG_0(n) ((n) << DSU_FUSES_DEV_FAMILY_CFG_0_SHIFT) + +# define DSU_FUSES_DCFG1_ADDR (SAM_AUX1_AREA2 + 4) +# define DSU_FUSES_DCFG1_SHIFT (0) /* Bits 0-31: Device Configuration 1 */ +# define DSU_FUSES_DCFG1_MASK (0xffffffff << DSU_FUSES_DCFG1_SHIFT) +# define DSU_FUSES_DCFG1(n) ((n) << DSU_FUSES_DCFG1_SHIFT) + +# define DSU_FUSES_DEV_FAMILY_CFG_1_ADDR (SAM_AUX1_AREA2 + 4) +# define DSU_FUSES_DEV_FAMILY_CFG_1_SHIFT (0) /* Bits 0-15: Device Family Configuration bits 42:27 */ +# define DSU_FUSES_DEV_FAMILY_CFG_1_MASK (0xffff << DSU_FUSES_DEV_FAMILY_CFG_1_SHIFT) +# define DSU_FUSES_DEV_FAMILY_CFG_1(n) ((n) << DSU_FUSES_DEV_FAMILY_CFG_1_SHIFT) + +# define ADC_FUSES_DCFG_ADDR (SAM_AUX1_AREA2 + 4) +# define ADC_FUSES_DCFG_SHIFT (16) /* Bits 16-19: ADC Device Configuration */ +# define ADC_FUSES_DCFG_MASK (15 << ADC_FUSES_DCFG_SHIFT) +# define ADC_FUSES_DCFG(n) ((n) << ADC_FUSES_DCFG_SHIFT) + +# define ADC_FUSES_CMPDELAY_ADDR (SAM_AUX1_AREA2 + 4) +# define ADC_FUSES_CMPDELAY_SHIFT (16) /* Bit 16: ADC Comparator Delay */ +# define ADC_FUSES_CMPDELAY_MASK (1 << ADC_FUSES_CMPDELAY_SHIFT) + +# define ADC_FUSES_BOOSTEN_ADDR (SAM_AUX1_AREA2 + 4) +# define ADC_FUSES_BOOSTEN_SHIFT (17) /* Bit 17: ADC Boost Enable */ +# define ADC_FUSES_BOOSTEN_MASK (1 << ADC_FUSES_BOOSTEN_SHIFT) + +# define ADC_FUSES_VCMPULSE_ADDR (SAM_AUX1_AREA2 + 4) +# define ADC_FUSES_VCMPULSE_SHIFT (18) /* Bit 18: ADC VCM Pulse */ +# define ADC_FUSES_VCMPULSE_MASK (1 << ADC_FUSES_VCMPULSE_SHIFT) + +# define ADC_FUSES_BIAS_OPA_ADDR (SAM_AUX1_AREA2 + 4) +# define ADC_FUSES_BIAS_OPA_SHIFT (19) /* Bit 19: ADC OPA Bias */ +# define ADC_FUSES_BIAS_OPA_MASK (1 << ADC_FUSES_BIAS_OPA_SHIFT) + +# define DSU_FUSES_RAM_BIAS_ADDR (SAM_AUX1_AREA2 + 4) +# define DSU_FUSES_RAM_BIAS_SHIFT (20) /* Bits 20-21: RAM Bias */ +# define DSU_FUSES_RAM_BIAS_MASK (3 << DSU_FUSES_RAM_BIAS_SHIFT) +# define DSU_FUSES_RAM_BIAS(n) ((n) << DSU_FUSES_RAM_BIAS_SHIFT) + +# define DSU_FUSES_RAM_READ_MARGIN_ADDR (SAM_AUX1_AREA2 + 4) +# define DSU_FUSES_RAM_READ_MARGIN_SHIFT (22) /* Bits 22-25: RAM Read Margin */ +# define DSU_FUSES_RAM_READ_MARGIN_MASK (15 << DSU_FUSES_RAM_READ_MARGIN_SHIFT) +# define DSU_FUSES_RAM_READ_MARGIN(n) ((n) << DSU_FUSES_RAM_READ_MARGIN_SHIFT) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SYSCTRL_FUSES_ULPVREG_ADDR (SAM_AUX1_AREA4 + 0) +# define SYSCTRL_FUSES_ULPVREG_SHIFT (0) /* Bits 0-2: ULP Regulator Fallback Mode */ +# define SYSCTRL_FUSES_ULPVREG_MASK (7 << SYSCTRL_FUSES_ULPVREG_SHIFT) +# define SYSCTRL_FUSES_ULPVREG(n) ((n) << SYSCTRL_FUSES_ULPVREG_SHIFT) + +# define ADC_FUSES_GAINCORR_ADDR (SAM_AUX1_AREA4 + 0) +# define ADC_FUSES_GAINCORR_SHIFT (3) /* Bits 3-14: ADC Gain Correction */ +# define ADC_FUSES_GAINCORR_MASK (0xfff << ADC_FUSES_GAINCORR_SHIFT) +# define ADC_FUSES_GAINCORR(n) ((n) << ADC_FUSES_GAINCORR_SHIFT) + +# define ADC_FUSES_OFFSETCORR_ADDR (SAM_AUX1_AREA4 + 0) +# define ADC_FUSES_OFFSETCORR_SHIFT (15) /* Bits 15-26: ADC Offset Correction */ +# define ADC_FUSES_OFFSETCORR_MASK (0xfff << ADC_FUSES_OFFSETCORR_SHIFT) +# define ADC_FUSES_OFFSETCORR(n) ((n) << ADC_FUSES_OFFSETCORR_SHIFT) +#endif + +#define ADC_FUSES_LINEARITY_0_ADDR (SAM_AUX1_AREA4 + 0) +#define ADC_FUSES_LINEARITY_0_SHIFT (27) /* Bits 27-31: ADC Linearity bits 4:0 */ +#define ADC_FUSES_LINEARITY_0_MASK (0x1f << ADC_FUSES_LINEARITY_0_SHIFT) +# define ADC_FUSES_LINEARITY_0(n) ((n) << ADC_FUSES_LINEARITY_0_SHIFT) + +#define ADC_FUSES_LINEARITY_1_ADDR (SAM_AUX1_AREA4 + 4) +#define ADC_FUSES_LINEARITY_1_SHIFT (0) /* Bits 32-34: ADC Linearity bits 7:5 */ +#define ADC_FUSES_LINEARITY_1_MASK (7 << ADC_FUSES_LINEARITY_1_SHIFT) +# define ADC_FUSES_LINEARITY_1(n) ((n) << ADC_FUSES_LINEARITY_1_SHIFT) + +#define ADC_FUSES_BIASCAL_ADDR (SAM_AUX1_AREA4 + 4) +#define ADC_FUSES_BIASCAL_SHIFT (3) /* Bits 35-27: ADC Bias Calibration */ +#define ADC_FUSES_BIASCAL_MASK (7 << ADC_FUSES_BIASCAL_SHIFT) +# define ADC_FUSES_BIASCAL(n) ((n) << ADC_FUSES_BIASCAL_SHIFT) + +#define SYSCTRL_FUSES_OSC32KCAL_ADDR (SAM_AUX1_AREA4 + 4) +#define SYSCTRL_FUSES_OSC32KCAL_SHIFT (6) /* Bits 38-44: OSC32K Calibration */ +#define SYSCTRL_FUSES_OSC32KCAL_MASK (0x7f << SYSCTRL_FUSES_OSC32KCAL_SHIFT) +# define SYSCTRL_FUSES_OSC32KCAL(n) ((n) << SYSCTRL_FUSES_OSC32KCAL_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_FUSES_USBTRANSN_ADDR (SAM_AUX1_AREA4 + 4) +# define SYSCTRL_FUSES_USBTRANSN_SHIFT (13) /* Bits 45-49: USB TRANSN calibration value. */ +# define SYSCTRL_FUSES_USBTRANSN_MASK (0x1f << SYSCTRL_FUSES_USBTRANSN_SHIFT) +# define SYSCTRL_FUSES_USBTRANSN(n) ((n) << SYSCTRL_FUSES_USBTRANSN_SHIFT) + +# define SYSCTRL_FUSES_USBTRANSP_ADDR (SAM_AUX1_AREA4 + 4) +# define SYSCTRL_FUSES_USBTRANSP_SHIFT (18) /* Bits 50-54: USB TRANSP calibration value. */ +# define SYSCTRL_FUSES_USBTRANSP_MASK (0x1f << SYSCTRL_FUSES_USBTRANSP_SHIFT) +# define SYSCTRL_FUSES_USBTRANSP(n) ((n) << SYSCTRL_FUSES_USBTRANSP_SHIFT) + +# define SYSCTRL_FUSES_USBTRIM_ADDR (SAM_AUX1_AREA4 + 4) +# define SYSCTRL_FUSES_USBTRIM_SHIFT (23) /* Bits 55-57: USB TRIM calibration value. */ +# define SYSCTRL_FUSES_USBTRIM_MASK (7 << SYSCTRL_FUSES_USBTRIM_SHIFT) +# define SYSCTRL_FUSES_USBTRIM(n) ((n) << SYSCTRL_FUSES_USBTRIM_SHIFT) + +# define SYSCTRL_FUSES_DFLL48MCOARSE_ADDR (SAM_AUX1_AREA4 + 4) +# define SYSCTRL_FUSES_DFLL48MCOARSE_SHIFT (26) /* Bits 58-63: DFLL48M Coarse calibration value. */ +# define SYSCTRL_FUSES_DFLL48MCOARSE_MASK (0x3f << SYSCTRL_FUSES_DFLL48MCOARSE_SHIFT) +# define SYSCTRL_FUSES_DFLL48MCOARSE(n) ((n) << SYSCTRL_FUSES_DFLL48MCOARSE_SHIFT) + +# define SYSCTRL_FUSES_DFLL48MFINE_ADDR (SAM_AUX1_AREA4 + 8) +# define SYSCTRL_FUSES_DFLL48MFINE_SHIFT (0) /* Bits 64-74: DFLL48M Fine calibration value. */ +# define SYSCTRL_FUSES_DFLL48MFINE_MASK (0x7ff << SYSCTRL_FUSES_DFLL48MFINE_SHIFT) +# define SYSCTRL_FUSES_DFLL48MFINE(n) ((n) << SYSCTRL_FUSES_DFLL48MFINE_SHIFT) +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_FUSES_H */ diff --git a/arch/arm/src/samdl/chip/samd_gclk.h b/arch/arm/src/samdl/chip/samd_gclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6c337d8bd75e17a0a68c5a7ca862935595922dd2 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_gclk.h @@ -0,0 +1,258 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_gclk.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_GCLK_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_GCLK_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* GCLK register offsets ********************************************************************/ + +#define SAM_GCLK_CTRL_OFFSET 0x0000 /* Control register */ +#define SAM_GCLK_STATUS_OFFSET 0x0001 /* Status register */ +#define SAM_GCLK_CLKCTRL_OFFSET 0x0002 /* Generic clock control register */ +#define SAM_GCLK_GENCTRL_OFFSET 0x0004 /* Generic clock generator control register */ +#define SAM_GCLK_GENDIV_OFFSET 0x0008 /* Generic clock generator division register */ + +/* GCLK register addresses ******************************************************************/ + +#define SAM_GCLK_CTRL (SAM_GCLK_BASE+SAM_GCLK_CTRL_OFFSET) +#define SAM_GCLK_STATUS (SAM_GCLK_BASE+SAM_GCLK_STATUS_OFFSET) +#define SAM_GCLK_CLKCTRL (SAM_GCLK_BASE+SAM_GCLK_CLKCTRL_OFFSET) +#define SAM_GCLK_GENCTRL (SAM_GCLK_BASE+SAM_GCLK_GENCTRL_OFFSET) +#define SAM_GCLK_GENDIV (SAM_GCLK_BASE+SAM_GCLK_GENDIV_OFFSET) + +/* GCLK register bit definitions ************************************************************/ + +/* Control register */ + +#define GCLK_CTRL_SWRST (1 << 0) /* Bit 0: Software Reset */ + +/* Status register */ + +#define GCLK_STATUS_SYNCBUSY (1 << 7) /* Bit 7: Synchronization Busy Status */ + +/* Generic clock control register */ + +#define GCLK_CLKCTRL_ID_SHIFT (0) /* Bits 0-5: Generic Clock Selection ID */ +#define GCLK_CLKCTRL_ID_MASK (0x3f << GCLK_CLKCTRL_ID_SHIFT) +# define GCLK_CLKCTRL_ID(n) ((n) << GCLK_CLKCTRL_ID_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define GCLK_CLKCTRL_ID_DFLL48M (0 << GCLK_CLKCTRL_ID_SHIFT) /* DFLL48M Reference */ +# define GCLK_CLKCTRL_ID_WDT (1 << GCLK_CLKCTRL_ID_SHIFT) /* WDT */ +# define GCLK_CLKCTRL_ID_RTC (2 << GCLK_CLKCTRL_ID_SHIFT) /* RTC */ +# define GCLK_CLKCTRL_ID_EIC (3 << GCLK_CLKCTRL_ID_SHIFT) /* EIC */ +# define GCLK_CLKCTRL_ID_EVSYS(n) (((n)+4) << GCLK_CLKCTRL_ID_SHIFT) +# define GCLK_CLKCTRL_ID_EVSYS1 (5 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_1 */ +# define GCLK_CLKCTRL_ID_EVSYS1 (5 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_1 */ +# define GCLK_CLKCTRL_ID_EVSYS2 (6 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_2 */ +# define GCLK_CLKCTRL_ID_EVSYS3 (7 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_3 */ +# define GCLK_CLKCTRL_ID_EVSYS4 (8 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_4 */ +# define GCLK_CLKCTRL_ID_EVSYS5 (9 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_5 */ +# define GCLK_CLKCTRL_ID_EVSYS6 (10 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_6 */ +# define GCLK_CLKCTRL_ID_EVSYS7 (11 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_7 */ +# define GCLK_CLKCTRL_ID_SERCOMS (12 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOMx_SLOW */ +# define GCLK_CLKCTRL_ID_SERCOMC(n) (((n)+13) << GCLK_CLKCTRL_ID_SHIFT) +# define GCLK_CLKCTRL_ID_SERCOM0C (13 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM0_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM1C (14 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM1_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM2C (15 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM2_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM3C (16 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM3_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM4C (17 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM4_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM5C (18 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM5_CORE */ +# define GCLK_CLKCTRL_ID_TC01 (19 << GCLK_CLKCTRL_ID_SHIFT) /* TC0,TC1 */ +# define GCLK_CLKCTRL_ID_TC23 (20 << GCLK_CLKCTRL_ID_SHIFT) /* TC2,TC3 */ +# define GCLK_CLKCTRL_ID_TC45 (21 << GCLK_CLKCTRL_ID_SHIFT) /* TC4,TC5 */ +# define GCLK_CLKCTRL_ID_TC67 (22 << GCLK_CLKCTRL_ID_SHIFT) /* TC6,TC7 */ +# define GCLK_CLKCTRL_ID_ADC (23 << GCLK_CLKCTRL_ID_SHIFT) /* ADC */ +# define GCLK_CLKCTRL_ID_ACDIG (24 << GCLK_CLKCTRL_ID_SHIFT) /* AC_DIG */ +# define GCLK_CLKCTRL_ID_ACANA (25 << GCLK_CLKCTRL_ID_SHIFT) /* AC_ANA */ +# define GCLK_CLKCTRL_ID_DAC (26 << GCLK_CLKCTRL_ID_SHIFT) /* DAC */ +# define GCLK_CLKCTRL_ID_PTC (27 << GCLK_CLKCTRL_ID_SHIFT) /* PTC */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define GCLK_CLKCTRL_ID_DFLL48M (0 << GCLK_CLKCTRL_ID_SHIFT) /* DFLL48M Reference */ +# define GCLK_CLKCTRL_ID_DPLL (1 << GCLK_CLKCTRL_ID_SHIFT) /* FDPLL96M input clock source for reference */ +# define GCLK_CLKCTRL_ID_DPLL32K (2 << GCLK_CLKCTRL_ID_SHIFT) /* FDPLL96M 32kHz clock for FDPLL96M internal lock timer */ +# define GCLK_CLKCTRL_ID_WDT (3 << GCLK_CLKCTRL_ID_SHIFT) /* WDT */ +# define GCLK_CLKCTRL_ID_RTC (4 << GCLK_CLKCTRL_ID_SHIFT) /* RTC */ +# define GCLK_CLKCTRL_ID_EIC (5 << GCLK_CLKCTRL_ID_SHIFT) /* EIC */ +# define GCLK_CLKCTRL_ID_EVSYS(n) (((n)+7) << GCLK_CLKCTRL_ID_SHIFT) +# define GCLK_CLKCTRL_ID_EVSYS0 (7 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_0 */ +# define GCLK_CLKCTRL_ID_EVSYS1 (8 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_1 */ +# define GCLK_CLKCTRL_ID_EVSYS2 (9 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_2 */ +# define GCLK_CLKCTRL_ID_EVSYS3 (10 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_3 */ +# define GCLK_CLKCTRL_ID_EVSYS4 (11 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_4 */ +# define GCLK_CLKCTRL_ID_EVSYS5 (12 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_5 */ +# define GCLK_CLKCTRL_ID_EVSYS6 (13 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_6 */ +# define GCLK_CLKCTRL_ID_EVSYS7 (14 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_7 */ +# define GCLK_CLKCTRL_ID_EVSYS8 (15 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_8 */ +# define GCLK_CLKCTRL_ID_EVSYS9 (16 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_9 */ +# define GCLK_CLKCTRL_ID_EVSYS10 (17 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_10 */ +# define GCLK_CLKCTRL_ID_EVSYS11 (18 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_11 */ +# define GCLK_CLKCTRL_ID_SERCOMS (19 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOMx_SLOW */ +# define GCLK_CLKCTRL_ID_SERCOMC(n) (((n)+20) << GCLK_CLKCTRL_ID_SHIFT) +# define GCLK_CLKCTRL_ID_SERCOM0C (20 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM0_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM1C (21 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM1_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM2C (22 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM2_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM3C (23 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM3_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM4C (24 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM4_CORE */ +# define GCLK_CLKCTRL_ID_SERCOM5C (25 << GCLK_CLKCTRL_ID_SHIFT) /* SERCOM5_CORE */ +# define GCLK_CLKCTRL_ID_TCC01 (26 << GCLK_CLKCTRL_ID_SHIFT) /* TCC0,TCC1 */ +# define GCLK_CLKCTRL_ID_TCC23 (27 << GCLK_CLKCTRL_ID_SHIFT) /* TCC2,TC3 */ +# define GCLK_CLKCTRL_ID_TC45 (28 << GCLK_CLKCTRL_ID_SHIFT) /* TC4,TC5 */ +# define GCLK_CLKCTRL_ID_TC67 (29 << GCLK_CLKCTRL_ID_SHIFT) /* TC6,TC7 */ +# define GCLK_CLKCTRL_ID_ADC (30 << GCLK_CLKCTRL_ID_SHIFT) /* ADC */ +# define GCLK_CLKCTRL_ID_ACDIG (31 << GCLK_CLKCTRL_ID_SHIFT) /* AC_DIG */ +# define GCLK_CLKCTRL_ID_ACANA (32 << GCLK_CLKCTRL_ID_SHIFT) /* AC_ANA */ +# define GCLK_CLKCTRL_ID_DAC (33 << GCLK_CLKCTRL_ID_SHIFT) /* DAC */ +# define GCLK_CLKCTRL_ID_PTC (34 << GCLK_CLKCTRL_ID_SHIFT) /* PTC */ +# define GCLK_CLKCTRL_I2S0_PTC (35 << GCLK_CLKCTRL_ID_SHIFT) /* I2S0 */ +# define GCLK_CLKCTRL_I2S1_PTC (36 << GCLK_CLKCTRL_ID_SHIFT) /* I2S1 */ +#endif + +#define GCLK_CLKCTRL_GEN_SHIFT (8) /* Bits 8-11: Generic Clock Generator */ +#define GCLK_CLKCTRL_GEN_MASK (15 << GCLK_CLKCTRL_GEN_SHIFT) +# define GCLK_CLKCTRL_GEN(n) ((n) << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator n */ +# define GCLK_CLKCTRL_GEN0 (0 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 0 */ +# define GCLK_CLKCTRL_GEN1 (1 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 1 */ +# define GCLK_CLKCTRL_GEN2 (2 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 2 */ +# define GCLK_CLKCTRL_GEN3 (3 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 3 */ +# define GCLK_CLKCTRL_GEN4 (4 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 4 */ +# define GCLK_CLKCTRL_GEN5 (5 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 5 */ +# define GCLK_CLKCTRL_GEN6 (6 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 6 */ +# define GCLK_CLKCTRL_GEN7 (7 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 7 */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define GCLK_CLKCTRL_GEN8 (8 << GCLK_CLKCTRL_GEN_SHIFT) /* Generic clock generator 8 */ +#endif + +#define GCLK_CLKCTRL_CLKEN (1 << 14) /* Bit 14: Clock Enable */ +#define GCLK_CLKCTRL_WRTLOCK (1 << 15) /* Bit 15: Write Lock */ + +/* Generic clock generator control register */ + +#define GCLK_GENCTRL_ID_SHIFT (0) /* Bits 0-3: Generic Clock Generator Selection */ +#define GCLK_GENCTRL_ID_MASK (15 << GCLK_GENCTRL_ID_SHIFT) +# define GCLK_GENCTRL_ID(n) ((n) << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator n */ +# define GCLK_GENCTRL_ID0 (0 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 0 */ +# define GCLK_GENCTRL_ID1 (1 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 1 */ +# define GCLK_GENCTRL_ID2 (2 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 2 */ +# define GCLK_GENCTRL_ID3 (3 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 3 */ +# define GCLK_GENCTRL_ID4 (4 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 4 */ +# define GCLK_GENCTRL_ID5 (5 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 5 */ +# define GCLK_GENCTRL_ID6 (6 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 6 */ +# define GCLK_GENCTRL_ID7 (7 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 7 */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define GCLK_GENCTRL_ID8 (8 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 8 */ +#endif + +#define GCLK_GENCTRL_SRC_SHIFT (8) /* Bits 8-12: Source Select */ +#define GCLK_GENCTRL_SRC_MASK (31 << GCLK_GENCTRL_SRC_SHIFT) +# define GCLK_GENCTRL_SRC_XOSC (0 << GCLK_GENCTRL_SRC_SHIFT) /* XOSC oscillator output */ +# define GCLK_GENCTRL_SRC_GCLKIN (1 << GCLK_GENCTRL_SRC_SHIFT) /* Generator input pad */ +# define GCLK_GENCTRL_SRC_GCLKGEN1 (2 << GCLK_GENCTRL_SRC_SHIFT) /* Generic clock generator 1 output */ +# define GCLK_GENCTRL_SRC_OSCULP32K (3 << GCLK_GENCTRL_SRC_SHIFT) /* OSCULP32K oscillator output */ +# define GCLK_GENCTRL_SRC_OSC32K (4 << GCLK_GENCTRL_SRC_SHIFT) /* OSC32K oscillator output */ +# define GCLK_GENCTRL_SRC_XOSC32K (5 << GCLK_GENCTRL_SRC_SHIFT) /* XOSC32K oscillator output */ +# define GCLK_GENCTRL_SRC_OSC8M (6 << GCLK_GENCTRL_SRC_SHIFT) /* OSC8M oscillator output */ +# define GCLK_GENCTRL_SRC_DFLL48M (7 << GCLK_GENCTRL_SRC_SHIFT) /* DFLL48M output */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define GCLK_GENCTRL_SRC_FDPLL96M (8 << GCLK_GENCTRL_SRC_SHIFT) /* FDPLL96M output */ +#endif + +#define GCLK_GENCTRL_GENEN (1 << 16) /* Bit 16: Generic Clock Generator Enable */ +#define GCLK_GENCTRL_IDC (1 << 17) /* Bit 17: Improve Duty Cycle */ +#define GCLK_GENCTRL_OOV (1 << 18) /* Bit 18: Output Off Value */ +#define GCLK_GENCTRL_OE (1 << 19) /* Bit 19: Output Enable */ +#define GCLK_GENCTRL_DIVSEL (1 << 20) /* Bit 20: Divide Selection */ +#define GCLK_GENCTRL_RUNSTDBY (1 << 21) /* Bit 21: Run in Standby */ + +/* Generic clock generator division register */ + +#define GCLK_GENDIV_ID_SHIFT (0) /* Bits 0-3: Generic Clock Generator Selection */ +#define GCLK_GENDIV_ID_MASK (15 << GCLK_GENDIV_ID_SHIFT) +# define GCLK_GENDIV_ID(n) ((n) << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator n */ +# define GCLK_GENDIV_ID0 (0 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 0 */ +# define GCLK_GENDIV_ID1 (1 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 1 */ +# define GCLK_GENDIV_ID2 (2 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 2 */ +# define GCLK_GENDIV_ID3 (3 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 3 */ +# define GCLK_GENDIV_ID4 (4 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 4 */ +# define GCLK_GENDIV_ID5 (5 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 5 */ +# define GCLK_GENDIV_ID6 (6 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 6 */ +# define GCLK_GENDIV_ID7 (7 << GCLK_GENDIV_ID_SHIFT) /* Generic clock generator 7 */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define GCLK_GENDIV_ID8 (8 << GCLK_GENCTRL_ID_SHIFT) /* Generic clock generator 8 */ +#endif + +#define GCLK_GENDIV_DIV_SHIFT (8) /* Bits 8-23: Division Factor */ +#define GCLK_GENDIV_DIV_MASK (0xffff << GCLK_GENDIV_DIV_SHIFT) +# define GCLK_GENDIV_DIV(n) ((n) << GCLK_GENDIV_DIV_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_GCLK_H */ diff --git a/arch/arm/src/samdl/chip/samd_i2c_master.h b/arch/arm/src/samdl/chip/samd_i2c_master.h new file mode 100644 index 0000000000000000000000000000000000000000..5b674729f35268a3ca51287868c2c8ba91c3587a --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_i2c_master.h @@ -0,0 +1,341 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_i2c_master.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_MASTER_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_MASTER_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/samd_sercom.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* I2C register offsets *********************************************************************/ + +#define SAM_I2C_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_I2C_CTRLB_OFFSET 0x0004 /* Control B register */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define SAM_I2C_BAUD_OFFSET 0x000a /* Baud register */ +# define SAM_I2C_DBGCTRL_OFFSET 0x0008 /* Debug control register */ +# define SAM_I2C_INTENCLR_OFFSET 0x000c /* Interrupt enable clear register */ +# define SAM_I2C_INTENSET_OFFSET 0x000d /* Interrupt enable set register */ +# define SAM_I2C_INTFLAG_OFFSET 0x000e /* Interrupt flag and status clear register */ +# define SAM_I2C_STATUS_OFFSET 0x0010 /* Status register */ +# define SAM_I2C_ADDR_OFFSET 0x0014 /* Address register */ +# define SAM_I2C_DATA_OFFSET 0x0018 /* Data register */ +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define SAM_I2C_BAUD_OFFSET 0x000c /* Baud register */ +# define SAM_I2C_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +# define SAM_I2C_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +# define SAM_I2C_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +# define SAM_I2C_STATUS_OFFSET 0x001a /* Status register */ +# define SAM_I2C_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +# define SAM_I2C_ADDR_OFFSET 0x0024 /* Address register */ +# define SAM_I2C_DATA_OFFSET 0x0028 /* Data register */ +# define SAM_I2C_DBGCTRL_OFFSET 0x0030 /* Debug control register */ +#endif + +/* I2C register addresses *******************************************************************/ + +#define SAM_I2C0_CTRLA (SAM_SERCOM0_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C0_CTRLB (SAM_SERCOM0_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C0_BAUD (SAM_SERCOM0_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C0_INTENCLR (SAM_SERCOM0_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C0_INTENSET (SAM_SERCOM0_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C0_INTFLAG (SAM_SERCOM0_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C0_STATUS (SAM_SERCOM0_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C0_ADDR (SAM_SERCOM0_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C0_DATA (SAM_SERCOM0_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C0_DBGCTRL (SAM_SERCOM0_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C1_CTRLA (SAM_SERCOM1_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C1_CTRLB (SAM_SERCOM1_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C1_BAUD (SAM_SERCOM1_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C1_INTENCLR (SAM_SERCOM1_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C1_INTENSET (SAM_SERCOM1_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C1_INTFLAG (SAM_SERCOM1_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C1_STATUS (SAM_SERCOM1_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C1_ADDR (SAM_SERCOM1_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C1_DATA (SAM_SERCOM1_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C1_DBGCTRL (SAM_SERCOM1_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C2_CTRLA (SAM_SERCOM2_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C2_CTRLB (SAM_SERCOM2_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C2_BAUD (SAM_SERCOM2_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C2_INTENCLR (SAM_SERCOM2_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C2_INTENSET (SAM_SERCOM2_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C2_INTFLAG (SAM_SERCOM2_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C2_STATUS (SAM_SERCOM2_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C2_ADDR (SAM_SERCOM2_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C2_DATA (SAM_SERCOM2_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C2_DBGCTRL (SAM_SERCOM2_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C3_CTRLA (SAM_SERCOM3_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C3_CTRLB (SAM_SERCOM3_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C3_BAUD (SAM_SERCOM3_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C3_INTENCLR (SAM_SERCOM3_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C3_INTENSET (SAM_SERCOM3_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C3_INTFLAG (SAM_SERCOM3_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C3_STATUS (SAM_SERCOM3_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C3_ADDR (SAM_SERCOM3_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C3_DATA (SAM_SERCOM3_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C3_DBGCTRL (SAM_SERCOM3_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C4_CTRLA (SAM_SERCOM4_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C4_CTRLB (SAM_SERCOM4_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C4_BAUD (SAM_SERCOM4_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C4_INTENCLR (SAM_SERCOM4_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C4_INTENSET (SAM_SERCOM4_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C4_INTFLAG (SAM_SERCOM4_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C4_STATUS (SAM_SERCOM4_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C4_ADDR (SAM_SERCOM4_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C4_DATA (SAM_SERCOM4_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C4_DBGCTRL (SAM_SERCOM4_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C5_CTRLA (SAM_SERCOM5_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C5_CTRLB (SAM_SERCOM5_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C5_BAUD (SAM_SERCOM5_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C5_INTENCLR (SAM_SERCOM5_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C5_INTENSET (SAM_SERCOM5_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C5_INTFLAG (SAM_SERCOM5_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C5_STATUS (SAM_SERCOM5_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C5_ADDR (SAM_SERCOM5_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C5_DATA (SAM_SERCOM5_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C5_DBGCTRL (SAM_SERCOM5_BASE+SAM_I2C_DBGCTRL_OFFSET) + +/* I2C register bit definitions *************************************************************/ + +/* Control A register */ + +#define I2C_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define I2C_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define I2C_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define I2C_CTRLA_MODE_MASK (7 << I2C_CTRLA_MODE_SHIFT) +# define I2C_CTRLA_MODE_MASTER (5 << I2C_CTRLA_MODE_SHIFT) /* I2C master mode */ +#define I2C_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define I2C_CTRLA_PINOUT (1 << 16) /* Bit 16: Transmit data pinout */ +# define I2C_CTRLA_1WIRE (0) /* 4-wire operation disable */ +# define I2C_CTRLA_4WIRE I2C_CTRLA_PINOUT /* 4-wire operation enable */ +#define I2C_CTRLA_SDAHOLD_SHIFT (20) /* Bits 20-21: SDA Hold Time */ +#define I2C_CTRLA_SDAHOLD_MASK (3 << I2C_CTRLA_SDAHOLD_SHIFT) +# define I2C_CTRLA_SDAHOLD_DIS (0 << I2C_CTRLA_SDAHOLD_SHIFT) /* Disabled */ +# define I2C_CTRLA_SDAHOLD_75NS (1 << I2C_CTRLA_SDAHOLD_SHIFT) /* 50-100ns hold time */ +# define I2C_CTRLA_SDAHOLD_450NS (2 << I2C_CTRLA_SDAHOLD_SHIFT) /* 300-600ns hold time */ +# define I2C_CTRLA_SDAHOLD_600NS (3 << I2C_CTRLA_SDAHOLD_SHIFT) /* 400-800ns hold time */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_CTRLA_MEXTTOEN (1 << 22) /* Bit 22: Master SCL low extend time-out */ +# define I2C_CTRLA_SEXTTOEN (1 << 23) /* Bit 23: Slave SCL low extend time-out */ +# define I2C_CTRLA_SPEED_SHIFT (24) /* Bits 24-25: Transfer speed */ +# define I2C_CTRLA_SPEED_MASK (3 << I2C_CTRLA_SPEED_SHIFT) +# define I2C_CTRLA_SPEED_STANDARD (0 << I2C_CTRLA_SPEED_SHIFT) /* Standard-mode (<=100 kHz) and Fast-mode (<=400 kHz) */ +# define I2C_CTRLA_SPEED_FAST (1 << I2C_CTRLA_SPEED_SHIFT) /* Fast-mode Plus (<=1 MHz) */ +# define I2C_CTRLA_SPEED_HIGHSPEED (2 << I2C_CTRLA_SPEED_SHIFT) /* High-speed mode (<=3.4 MHz) */ +# define I2C_CTRLA_SCLSM (1 << 27) /* Bit 27: SCL clock stretch mode */ +#endif + +#define I2C_CTRLA_INACTOUT_SHIFT (28) /* Bits 28-29: Inactive Time-Out */ +#define I2C_CTRLA_INACTOUT_MASK (7 << I2C_CTRLA_INACTOUT_SHIFT) +# define I2C_CTRLA_INACTOUT_DIS (0 << I2C_CTRLA_INACTOUT_SHIFT) /* Disabled */ +# define I2C_CTRLA_INACTOUT_55US (1 << I2C_CTRLA_INACTOUT_SHIFT) /* 5-6 SCL cycle time-out (50-60µs) */ +# define I2C_CTRLA_INACTOUT_105US (2 << I2C_CTRLA_INACTOUT_SHIFT) /* 10-11 SCL cycle time-out (100-110µs) */ +# define I2C_CTRLA_INACTOUT_205US (3 << I2C_CTRLA_INACTOUT_SHIFT) /* 20-21 SCL cycle time-out (200-210µs) */ +#define I2C_CTRLA_LOWTOUT (1 << 30) /* Bit 30: SCL Low Time-Out */ + +/* Control B register */ + +#define I2C_CTRLB_SMEN (1 << 8) /* Bit 8: Smart Mode Enable */ +#define I2C_CTRLB_QCEN (1 << 9) /* Bit 9: Quick Command Enable */ +#define I2C_CTRLB_CMD_SHIFT (16) /* Bits 16-17: Command */ +#define I2C_CTRLB_CMD_MASK (3 << I2C_CTRLB_CMD_SHIFT) +# define I2C_CTRLB_CMD_NOACTION (0 << I2C_CTRLB_CMD_SHIFT) /* No action */ +# define I2C_CTRLB_CMD_ACKREP (1 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by repeated START */ +# define I2C_CTRLB_CMD_ACKREAD (2 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by read operation */ +# define I2C_CTRLB_CMD_ACKSTOP (3 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by STOP */ +#define I2C_CTRLB_ACKACT (1 << 18) /* Bit 18: Acknowledge Action */ +# define I2C_CTRLB_ACK (0) /* Send ACK */ +# define I2C_CTRLB_NACK I2C_CTRLB_ACKACT /* Send NACK */ + +/* Baud register (16-bit baud value) */ + +#define I2C_BAUD_SHIFT (0) /* Bits 0-7: Master baud rate */ +#define I2C_BAUD_MASK (0xff << I2C_BAUD_SHIFT) +# define I2C_BAUD(n) ((uint16)(n) << I2C_BAUD_SHIFT) +#define I2C_BAUDLOW_SHIFT (8) /* Bits 8-15: Master baud rate low */ +#define I2C_BAUDLOW_MASK (0xff << I2C_BAUDLOW_SHIFT) +# define I2C_BAUDLOW(n) (uint16)(n) << I2C_BAUDLOW_SHIFT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_HSBAUD_SHIFT (16) /* Bits 16-23: High speed master baud rate */ +# define I2C_HSBAUD_MASK (0xff << I2C_HSBAUD_SHIFT) +# define I2C_HSBAUD(n) ((uint16)(n) << I2C_HSBAUD_SHIFT) +# define I2C_HSBAUDLOW_SHIFT (24) /* Bits 24-31: High speed master baud rate low */ +# define I2C_HSBAUDLOW_MASK (0xff << I2C_HSBAUDLOW_SHIFT) +# define I2C_HSBAUDLOW(n) (uint16)(n) << I2C_HSBAUDLOW_SHIFT) +#endif + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define I2C_INT_MB (1 << 0) /* Bit 0: Master on bus interrupt */ +#define I2C_INT_SB (1 << 1) /* Bit 1: Slave on bus interrupt */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define I2C_INT_ALL (0x03) +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define I2C_INT_ERROR (1 << 7) /* Bit 7: Error interrupt */ +# define I2C_INT_ALL (0x03) +#endif + +/* Status register */ + +#define I2C_STATUS_BUSERR (1 << 0) /* Bit 0: Bus Error */ +#define I2C_STATUS_ARBLOST (1 << 1) /* Bit 1: Arbitration Lost */ +#define I2C_STATUS_RXNACK (1 << 2) /* Bit 2: Received Not Acknowledge */ +#define I2C_STATUS_BUSSTATE_SHIFT (4) /* Bits 4-5: Bus State */ +#define I2C_STATUS_BUSSTATE_MASK (3 << I2C_STATUS_BUSSTATE_SHIFT) +# define I2C_STATUS_BUSSTATE_UNKNOWN (0 << I2C_STATUS_BUSSTATE_SHIFT) /* Unknown to master */ +# define I2C_STATUS_BUSSTATE_IDLE (1 << I2C_STATUS_BUSSTATE_SHIFT) /* Waiting for transaction */ +# define I2C_STATUS_BUSSTATE_OWNER (2 << I2C_STATUS_BUSSTATE_SHIFT) /* Master of bus owner */ +# define I2C_STATUS_BUSSTATE_BUSY (3 << I2C_STATUS_BUSSTATE_SHIFT) /* Other master owns */ +#define I2C_STATUS_LOWTOUT (1 << 6) /* Bit 6: SCL Low Time-Out */ +#define I2C_STATUS_CLKHOLD (1 << 7) /* Bit 7: Clock Hold */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_STATUS_MEXTTOUT (1 << 8) /* Bit 8: Master SCL low extend time-out */ +# define I2C_STATUS_SEXTTOUT (1 << 9) /* Bit 9: Slave SCL low extend time-out */ +# define I2C_STATUS_LENERR (1 << 10) /* Bit 10: Transaction length error */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define I2C_STATUS_SYNCBUSY (1 << 15) /* Bit 15: Synchronization busy */ +#endif + +/* Synchronization busy register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +# define I2C_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +# define I2C_SYNCBUSY_SYSOP (1 << 2) /* Bit 2: System operation synchronization busy */ + +# define I2C_SYNCBUSY_ALL 0x0007 +#endif + +/* Address register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define I2C_ADDR_SHIFT (0) /* Bits 0-7: Address */ +# define I2C_ADDR_MASK (0xff << I2C_ADDR_SHIFT) +# define I2C_ADDR(n) ((uint16_t)(n) << I2C_ADDR_SHIFT) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_ADDR_SHIFT (0) /* Bits 0-10: Address */ +# define I2C_ADDR_MASK (0x7ff << I2C_ADDR_SHIFT) +# define I2C_ADDR(n) ((uint32_t)(n) << I2C_ADDR_SHIFT) +# define I2C_ADDR_LENEN (1 << 13) /* Bit 13: Transfer length enable */ +# define I2C_ADDR_HS (1 << 14) /* Bit 14: High speed */ +# define I2C_ADDR_TENBITEN (1 << 15) /* Bit 15: Ten Bit Addressing Enable */ +# define I2C_ADDR_LEN_SHIFT (16) /* Bits 16-23: Transaction Length */ +# define I2C_ADDR_LEN_MASK (0xff << I2C_ADDR_LEN_SHIFT) +# define I2C_ADDR_LEN(n) ((uint32_t)(n) << I2C_ADDR_LEN_SHIFT) +#endif + +/* Data register */ + +#define I2C_DATA_MASK (0x00ff) /* Bits 0-7: Data */ + +/* Debug control register */ + +#define I2C_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_MASTER_H */ diff --git a/arch/arm/src/samdl/chip/samd_i2c_slave.h b/arch/arm/src/samdl/chip/samd_i2c_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..61184432bb5625e28f9b4a7fd0ff5fa7c03746f1 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_i2c_slave.h @@ -0,0 +1,303 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_i2c_slave.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_SLAVE_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_SLAVE_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/samd_sercom.h" + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* I2C register offsets *********************************************************************/ + +#define SAM_I2C_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_I2C_CTRLB_OFFSET 0x0004 /* Control B register */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define SAM_I2C_INTENCLR_OFFSET 0x000c /* Interrupt enable clear register */ +# define SAM_I2C_INTENSET_OFFSET 0x000d /* Interrupt enable set register */ +# define SAM_I2C_INTFLAG_OFFSET 0x000e /* Interrupt flag and status clear register */ +# define SAM_I2C_STATUS_OFFSET 0x0010 /* Status register */ +# define SAM_I2C_ADDR_OFFSET 0x0014 /* Address register */ +# define SAM_I2C_DATA_OFFSET 0x0018 /* Data register */ +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define SAM_I2C_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +# define SAM_I2C_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +# define SAM_I2C_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +# define SAM_I2C_STATUS_OFFSET 0x001a /* Status register */ +# define SAM_I2C_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +# define SAM_I2C_ADDR_OFFSET 0x0024 /* Address register */ +# define SAM_I2C_DATA_OFFSET 0x0028 /* Data register */ +#endif + +/* I2C register addresses *******************************************************************/ + +#define SAM_I2C0_CTRLA (SAM_SERCOM0_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C0_CTRLB (SAM_SERCOM0_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C0_INTENCLR (SAM_SERCOM0_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C0_INTENSET (SAM_SERCOM0_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C0_INTFLAG (SAM_SERCOM0_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C0_STATUS (SAM_SERCOM0_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C0_ADDR (SAM_SERCOM0_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C0_DATA (SAM_SERCOM0_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C1_CTRLA (SAM_SERCOM1_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C1_CTRLB (SAM_SERCOM1_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C1_INTENCLR (SAM_SERCOM1_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C1_INTENSET (SAM_SERCOM1_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C1_INTFLAG (SAM_SERCOM1_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C1_STATUS (SAM_SERCOM1_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C1_ADDR (SAM_SERCOM1_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C1_DATA (SAM_SERCOM1_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C2_CTRLA (SAM_SERCOM2_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C2_CTRLB (SAM_SERCOM2_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C2_INTENCLR (SAM_SERCOM2_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C2_INTENSET (SAM_SERCOM2_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C2_INTFLAG (SAM_SERCOM2_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C2_STATUS (SAM_SERCOM2_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C2_ADDR (SAM_SERCOM2_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C2_DATA (SAM_SERCOM2_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C3_CTRLA (SAM_SERCOM3_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C3_CTRLB (SAM_SERCOM3_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C3_INTENCLR (SAM_SERCOM3_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C3_INTENSET (SAM_SERCOM3_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C3_INTFLAG (SAM_SERCOM3_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C3_STATUS (SAM_SERCOM3_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C3_ADDR (SAM_SERCOM3_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C3_DATA (SAM_SERCOM3_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C4_CTRLA (SAM_SERCOM4_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C4_CTRLB (SAM_SERCOM4_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C4_INTENCLR (SAM_SERCOM4_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C4_INTENSET (SAM_SERCOM4_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C4_INTFLAG (SAM_SERCOM4_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C4_STATUS (SAM_SERCOM4_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C4_ADDR (SAM_SERCOM4_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C4_DATA (SAM_SERCOM4_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C5_CTRLA (SAM_SERCOM5_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C5_CTRLB (SAM_SERCOM5_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C5_INTENCLR (SAM_SERCOM5_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C5_INTENSET (SAM_SERCOM5_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C5_INTFLAG (SAM_SERCOM5_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C5_STATUS (SAM_SERCOM5_BASE+SAM_I2C_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_I2C5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#endif + +#define SAM_I2C5_ADDR (SAM_SERCOM5_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C5_DATA (SAM_SERCOM5_BASE+SAM_I2C_DATA_OFFSET) + +/* I2C register bit definitions *************************************************************/ + +/* Control A register */ + +#define I2C_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define I2C_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define I2C_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define I2C_CTRLA_MODE_MASK (7 << I2C_CTRLA_MODE_SHIFT) +# define I2C_CTRLA_MODE_SLAVE (4 << I2C_CTRLA_MODE_SHIFT) /* I2C slave mode */ +#define I2C_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define I2C_CTRLA_PINOUT (1 << 16) /* Bit 16: Transmit data pinout */ +# define I2C_CTRLA_1WIRE (0) /* 4-wire operation disable */ +# define I2C_CTRLA_4WIRE I2C_CTRLA_PINOUT /* 4-wire operation enable */ +#define I2C_CTRLA_SDAHOLD_SHIFT (20) /* Bits 20-21: SDA Hold Time */ +#define I2C_CTRLA_SDAHOLD_MASK (3 << I2C_CTRLA_SDAHOLD_SHIFT) +# define I2C_CTRLA_SDAHOLD_DIS (0 << I2C_CTRLA_SDAHOLD_SHIFT) /* Disabled */ +# define I2C_CTRLA_SDAHOLD_75NS (1 << I2C_CTRLA_SDAHOLD_SHIFT) /* 50-100ns hold time */ +# define I2C_CTRLA_SDAHOLD_450NS (2 << I2C_CTRLA_SDAHOLD_SHIFT) /* 300-600ns hold time */ +# define I2C_CTRLA_SDAHOLD_600NS (3 << I2C_CTRLA_SDAHOLD_SHIFT) /* 400-800ns hold time */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_CTRLA_SEXTTOEN (1 << 23) /* Bit 23: Slave SCL low extend time-out */ +# define I2C_CTRLA_SPEED_SHIFT (24) /* Bits 24-25: Transfer speed */ +# define I2C_CTRLA_SPEED_MASK (3 << I2C_CTRLA_SPEED_SHIFT) +# define I2C_CTRLA_SPEED_STANDARD (0 << I2C_CTRLA_SPEED_SHIFT) /* Standard-mode (<=100 kHz) and Fast-mode (<=400 kHz) */ +# define I2C_CTRLA_SPEED_FAST (1 << I2C_CTRLA_SPEED_SHIFT) /* Fast-mode Plus (<=1 MHz) */ +# define I2C_CTRLA_SPEED_HIGHSPEED (2 << I2C_CTRLA_SPEED_SHIFT) /* High-speed mode (<=3.4 MHz) */ +# define I2C_CTRLA_SCLSM (1 << 27) /* Bit 27: SCL clock stretch mode */ +#endif + +#define I2C_CTRLA_LOWTOUT (1 << 30) /* Bit 30: SCL low time-out */ + +/* Control B register */ + +#define I2C_CTRLB_SMEN (1 << 8) /* Bit 8: Smart Mode Enable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_CTRLB_GCMD (1 << 9) /* Bit 8: PMBus group command */ +# define I2C_CTRLB_AACKEN (1 << 10) /* Bit 10: Automatic acknowledge enable */ +#endif + +#define I2C_CRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */ +#define I2C_CRLB_AMODE_MASK (3 << I2C_CRLB_AMODE_SHIFT) +# define I2C_CRLB_AMODE_MASK (0 << I2C_CRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */ +# define I2C_CRLB_AMODE_2ADDRS (1 << I2C_CRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */ +# define I2C_CRLB_AMODE_RANGE (2 << I2C_CRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */ +#define I2C_CTRLB_CMD_SHIFT (16) /* Bits 16-17: Command */ +#define I2C_CTRLB_CMD_MASK (3 << I2C_CTRLB_CMD_SHIFT) +# define I2C_CTRLB_CMD_NOACTION (0 << I2C_CTRLB_CMD_SHIFT) /* No action */ +# define I2C_CTRLB_CMD_WAITSTART (2 << I2C_CTRLB_CMD_SHIFT) /* ACK (write) wait for START */ +# define I2C_CTRLB_CMD_ACKREAD (3 << I2C_CTRLB_CMD_SHIFT) /* ACK with read (context dependent) */ +#define I2C_CTRLB_ACKACT (1 << 18) /* Bit 18: Acknowledge Action */ +# define I2C_CTRLB_ACK (0) /* Send ACK */ +# define I2C_CTRLB_NCK I2C_CTRLB_ACKACT /* Send NACK */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define I2C_INT_PREC (1 << 0) /* Bit 0: Stop received interrupt */ +#define I2C_INT_AMATCH (1 << 1) /* Bit 1: Address match interrupt */ +#define I2C_INT_DRDY (1 << 2) /* Bit 2: Data ready interrupt */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define I2C_INT_ALL (0x07) +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define I2C_INT_ERROR (1 << 7) /* Bit 7: Error interrupt */ +# define I2C_INT_ALL (0x87) +#endif + +/* Status register */ + +#define I2C_STATUS_BUSERR (1 << 0) /* Bit 0: Bus Error */ +#define I2C_STATUS_COLL (1 << 1) /* Bit 1: Transmit Collision */ +#define I2C_STATUS_RXNACK (1 << 2) /* Bit 2: Received Not Acknowledge */ +#define I2C_STATUS_DIR (1 << 3) /* Bit 3: Read / Write Direction */ +#define I2C_STATUS_SR (1 << 4) /* Bit 4: Repeated Start */ +#define I2C_STATUS_LOWTOUT (1 << 6) /* Bit 6: SCL Low Time-Out */ +#define I2C_STATUS_CLKHOLD (1 << 7) /* Bit 7: Clock Hold */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_STATUS_SEXTTOUT (1 << 9) /* Bit 9: Slave SCL low extend time-out */ +# define I2C_STATUS_HS (1 << 10) /* Bit 10: High speed */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define I2C_STATUS_SYNCBUSY (1 << 15) /* Bit 15: Synchronization busy */ +#endif + +/* Synchronization busy register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define I2C_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +# define I2C_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ + +# define I2C_SYNCBUSY_ALL 0x0003 +#endif + +/* Address register */ + +#define SPI_ADDR_GENCEN (1 << 0) /* Bit 0: General call address enable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SPI_ADDR_SHIFT (1) /* Bits 1-7: Address */ +# define SPI_ADDR_MASK (0x7f << SPI_ADDR_SHIFT) +# define SPI_ADDR(n) ((uint32_t)(n) << SPI_ADDR_SHIFT) +# define SPI_ADDRMASK_SHIFT (17) /* Bits 17-23: Address Mask */ +# define SPI_ADDRMASK_MASK (0x7f << SPI_ADDRMASK_SHIFT) +# define SPI_ADDRMASK(n) ((uint32_t)(n) << SPI_ADDRMASK_SHIFT) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SPI_ADDR_SHIFT (1) /* Bits 1-10: Address */ +# define SPI_ADDR_MASK (0x3ff << SPI_ADDR_SHIFT) +# define SPI_ADDR(n) ((uint32_t)(n) << SPI_ADDR_SHIFT) +# define SPI_ADDR_TENBITEN (1 << 15) /* Bit 15: Ten bit addressing enable */ +# define SPI_ADDRMASK_SHIFT (17) /* Bits 17-26: Address Mask */ +# define SPI_ADDRMASK_MASK (0x3ff << SPI_ADDRMASK_SHIFT) +# define SPI_ADDRMASK(n) ((uint32_t)(n) << SPI_ADDRMASK_SHIFT) +#endif + +/* Data register */ + +#define I2C_DATA_MASK (0xooff) /* Bits 0-7: Data */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_I2C_SLAVE_H */ diff --git a/arch/arm/src/samdl/chip/samd_nvmctrl.h b/arch/arm/src/samdl/chip/samd_nvmctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..bc19e57622fd284a51fade09ffe762e847699a4d --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_nvmctrl.h @@ -0,0 +1,187 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_nvmctrl.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_NVMCTRL_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_NVMCTRL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* NVMCTRL register offsets *****************************************************************/ + +#define SAM_NVMCTRL_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_NVMCTRL_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_NVMCTRL_PARAM_OFFSET 0x0008 /* NVM parameter register */ +#define SAM_NVMCTRL_INTENCLR_OFFSET 0x000c /* Interrupt clear register */ +#define SAM_NVMCTRL_INTENSET_OFFSET 0x0010 /* Interrupt set register */ +#define SAM_NVMCTRL_INTFLAG_OFFSET 0x0014 /* Interface flags status and clear register */ +#define SAM_NVMCTRL_STATUS_OFFSET 0x0018 /* Status register */ +#define SAM_NVMCTRL_ADDR_OFFSET 0x001c /* Address register */ +#define SAM_NVMCTRL_LOCK_OFFSET 0x0020 /* Lock section register */ + +/* NVMCTRL register addresses ***************************************************************/ + +#define SAM_NVMCTRL_CTRLA (SAM_NVMCTRL_BASE+SAM_NVMCTRL_CTRLA_OFFSET) +#define SAM_NVMCTRL_CTRLB (SAM_NVMCTRL_BASE+SAM_NVMCTRL_CTRLB_OFFSET) +#define SAM_NVMCTRL_PARAM (SAM_NVMCTRL_BASE+SAM_NVMCTRL_PARAM_OFFSET) +#define SAM_NVMCTRL_INTENCLR (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTENCLR_OFFSET) +#define SAM_NVMCTRL_INTENSET (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTENSET_OFFSET) +#define SAM_NVMCTRL_INTFLAG (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTFLAG_OFFSET) +#define SAM_NVMCTRL_STATUS (SAM_NVMCTRL_BASE+SAM_NVMCTRL_STATUS_OFFSET) +#define SAM_NVMCTRL_ADDR (SAM_NVMCTRL_BASE+SAM_NVMCTRL_ADDR_OFFSET) +#define SAM_NVMCTRL_LOCK (SAM_NVMCTRL_BASE+SAM_NVMCTRL_LOCK_OFFSET) + +/* NVMCTRL register bit definitions *********************************************************/ + +/* Control A register */ + +#define NVMCTRL_CTRLA_CMD_SHIFT (0) /* Bits 0-6: Command */ +#define NVMCTRL_CTRLA_CMD_MASK (0x7f << NVMCTRL_CTRLA_CMD_SHIFT) +# define NVMCTRL_CTRLA_CMD_ER (0x02 << NVMCTRL_CTRLA_CMD_SHIFT) /* Erase Row */ +# define NVMCTRL_CTRLA_CMD_WP (0x04 << NVMCTRL_CTRLA_CMD_SHIFT) /* Write Page */ +# define NVMCTRL_CTRLA_CMD_EAR (0x05 << NVMCTRL_CTRLA_CMD_SHIFT) /* Erase Auxiliary Row */ +# define NVMCTRL_CTRLA_CMD_WAP (0x06 << NVMCTRL_CTRLA_CMD_SHIFT) /* Write Auxiliary Page */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define NVMCTRL_CTRLA_CMD_SF (0x0a << NVMCTRL_CTRLA_CMD_SHIFT) /* Security Flow Command */ +# define NVMCTRL_CTRLA_CMD_WL (0x0f << NVMCTRL_CTRLA_CMD_SHIFT) /* Write lockbits */ +# define NVMCTRL_CTRLA_CMD_RWWEEER (0x1a << NVMCTRL_CTRLA_CMD_SHIFT) /* RWWEE Erase Row */ +# define NVMCTRL_CTRLA_CMD_RWWEEEP (0x1c << NVMCTRL_CTRLA_CMD_SHIFT) /* RWWEE Write Page */ +#endif + +# define NVMCTRL_CTRLA_CMD_LR (0x40 << NVMCTRL_CTRLA_CMD_SHIFT) /* Lock Region */ +# define NVMCTRL_CTRLA_CMD_UR (0x41 << NVMCTRL_CTRLA_CMD_SHIFT) /* Unlock Region */ +# define NVMCTRL_CTRLA_CMD_SPRM (0x42 << NVMCTRL_CTRLA_CMD_SHIFT) /* Set power reduction mode */ +# define NVMCTRL_CTRLA_CMD_CPRM (0x43 << NVMCTRL_CTRLA_CMD_SHIFT) /* Clear power reduction mode */ +# define NVMCTRL_CTRLA_CMD_PBC (0x44 << NVMCTRL_CTRLA_CMD_SHIFT) /* Page Buffer Clear */ +# define NVMCTRL_CTRLA_CMD_SSB (0x45 << NVMCTRL_CTRLA_CMD_SHIFT) /* Set Security Bit */ +# define NVMCTRL_CTRLA_CMD_INVALL (0x46 << NVMCTRL_CTRLA_CMD_SHIFT) /* Invalidate all cache lines */ +#define NVMCTRL_CTRLA_CMDEX_SHIFT (8) /* Bits 8-15: Command Execution */ +#define NVMCTRL_CTRLA_CMDEX_MASK (0xff << NVMCTRL_CTRLA_CMDEX_SHIFT) +# define NVMCTRL_CTRLA_CMDEX (0xa5 << NVMCTRL_CTRLA_CMDEX_SHIFT) + +/* Control B register */ + +#define NVMCTRL_CTRLB_RWS_SHIFT (1) /* Bits 1-4: NVM Read Wait States */ +#define NVMCTRL_CTRLB_RWS_MASK (15 << NVMCTRL_CTRLB_RWS_SHIFT) +# define NVMCTRL_CTRLB_RWS(n) ((n) << NVMCTRL_CTRLB_RWS_SHIFT) +#define NVMCTRL_CTRLB_MANW (1 << 7) /* Bit 7: Manual Write */ +#define NVMCTRL_CTRLB_SLEEPPRM_SHIFT (8) /* Bits 8-9: Power Reduction Mode during Sleep */ +#define NVMCTRL_CTRLB_SLEEPPRM_MASK (3 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) +# define NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS (0 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Exit low power on first access */ +# define NVMCTRL_CTRLB_SLEEPPRM_WAKEUPINSTANT (1 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Exit low power when exit sleep */ +# define NVMCTRL_CTRLB_SLEEPPRM_DISABLED (3 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Auto power reduction disabled */ +#define NVMCTRL_CTRLB_READMODE_SHIFT (16) /* Bits 16-17: NVMCTRL Read Mode */ +#define NVMCTRL_CTRLB_READMODE_MASK (3 << NVMCTRL_CTRLB_READMODE_SHIFT) +# define NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY (0 << NVMCTRL_CTRLB_READMODE_SHIFT) /* No extra wait states on miss */ +# define NVMCTRL_CTRLB_READMODE_LOW_POWER (1 << NVMCTRL_CTRLB_READMODE_SHIFT) /* Insert wait/reduce power */ +# define NVMCTRL_CTRLB_READMODE_DETERMINISTIC (2 << NVMCTRL_CTRLB_READMODE_SHIFT) /* Same wait on all access */ +#define NVMCTRL_CTRLB_CACHEDIS (1 << 18) /* Bit 18: Cache Disable */ + +/* NVM parameter register */ + +#define NVMCTRL_PARAM_NVMP_SHIFT (0) /* Bits 0-15: NVM Pages */ +#define NVMCTRL_PARAM_NVMP_MASK (0xffff << NVMCTRL_PARAM_NVMP_SHIFT) +# define NVMCTRL_PARAM_NVMP(n) ((n) << NVMCTRL_PARAM_NVMP_SHIFT) +#define NVMCTRL_PARAM_PSZ_SHIFT (16) /* Bits 16-18: Page Size */ +#define NVMCTRL_PARAM_PSZ_MASK (7 << NVMCTRL_PARAM_PSZ_SHIFT) +# define NVMCTRL_PARAM_PSZ_8B (0 << NVMCTRL_PARAM_PSZ_SHIFT) /* 8 bytes */ +# define NVMCTRL_PARAM_PSZ_16B (1 << NVMCTRL_PARAM_PSZ_SHIFT) /* 16 bytes */ +# define NVMCTRL_PARAM_PSZ_32B (2 << NVMCTRL_PARAM_PSZ_SHIFT) /* 32 bytes */ +# define NVMCTRL_PARAM_PSZ_64B (3 << NVMCTRL_PARAM_PSZ_SHIFT) /* 64 bytes */ +# define NVMCTRL_PARAM_PSZ_128B (4 << NVMCTRL_PARAM_PSZ_SHIFT) /* 128 bytes */ +# define NVMCTRL_PARAM_PSZ_256B (5 << NVMCTRL_PARAM_PSZ_SHIFT) /* 256 bytes */ +# define NVMCTRL_PARAM_PSZ_512B (6 << NVMCTRL_PARAM_PSZ_SHIFT) /* 512 bytes */ +# define NVMCTRL_PARAM_PSZ_1KB (7 << NVMCTRL_PARAM_PSZ_SHIFT) /* 1024 bytes */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define NVMCTRL_PARAM_RWWEEP_SHIFT (20) /* Bits 20-31: Read whle write EEPROM emulation area pages */ +# define NVMCTRL_PARAM_RWWEEP_MASK (0xfff << NVMCTRL_PARAM_RWWEEP_SHIFT) +#endif + +/* Interrupt clear register */ +/* Interrupt set register */ +/* Interface flags status and clear register */ + +#define NVMCTRL_INT_READY (1 << 0) /* Bit 0: NVM Ready Interrupt */ +#define NVMCTRL_INT_ERROR (1 << 1) /* Bit 1: Error Interrupt */ + +/* Status register */ + +#define NVMCTRL_STATUS_PRM (1 << 0) /* Bit 0: Power Reduction Mode */ +#define NVMCTRL_STATUS_LOAD (1 << 1) /* Bit 1: NVM Page Buffer Active Loading */ +#define NVMCTRL_STATUS_PROGE (1 << 2) /* Bit 2: Programming Error Status */ +#define NVMCTRL_STATUS_LOCKE (1 << 3) /* Bit 3: Lock Error Status */ +#define NVMCTRL_STATUS_NVME (1 << 4) /* Bit 4: NVM Error */ +#define NVMCTRL_STATUS_SB (1 << 8) /* Bit 8: Security Bit Status */ + +/* Address register */ + +#define NVMCTRL_ADDR_MASK (0x003fffff) /* Bits 0-21: NVM Address */ + +/* Lock section register */ + +#define NVMCTRL_LOCK_REGION(n) (1 << (n)) /* Region n is locked */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_NVMCTRL_H */ diff --git a/arch/arm/src/samdl/chip/samd_pm.h b/arch/arm/src/samdl/chip/samd_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..7c3e7f08724ef7fbf8e6ac956e052ecbd7704308 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_pm.h @@ -0,0 +1,264 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_pm.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PM_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PM_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* PM register offsets ********************************************************************/ + +#define SAM_PM_CTRL_OFFSET 0x0000 /* Control register */ +#define SAM_PM_SLEEP_OFFSET 0x0001 /* Sleep mode register */ +#define SAM_PM_CPUSEL_OFFSET 0x0008 /* CPU clock select register */ +#define SAM_PM_APBASEL_OFFSET 0x0009 /* APBA clock select register */ +#define SAM_PM_APBBSEL_OFFSET 0x000a /* APBB clock select register */ +#define SAM_PM_APBCSEL_OFFSET 0x000b /* APBC clock select register */ +#define SAM_PM_AHBMASK_OFFSET 0x0014 /* AHB mask register */ +#define SAM_PM_APBAMASK_OFFSET 0x0018 /* APBA mask register */ +#define SAM_PM_APBBMASK_OFFSET 0x001c /* APBB mask register */ +#define SAM_PM_APBCMASK_OFFSET 0x0020 /* APBC mask register */ +#define SAM_PM_INTENCLR_OFFSET 0x0034 /* Interrupt enable clear register */ +#define SAM_PM_INTENSET_OFFSET 0x0035 /* Interrupt enable set register */ +#define SAM_PM_INTFLAG_OFFSET 0x0036 /* Interrupt flag status and clear register */ +#define SAM_PM_RCAUSE_OFFSET 0x0038 /* Reset cause register */ + +/* PM register addresses ******************************************************************/ + +#define SAM_PM_CTRL (SAM_PM_BASE+SAM_PM_CTRL_OFFSET) +#define SAM_PM_SLEEP (SAM_PM_BASE+SAM_PM_SLEEP_OFFSET) +#define SAM_PM_CPUSEL (SAM_PM_BASE+SAM_PM_CPUSEL_OFFSET) +#define SAM_PM_APBASEL (SAM_PM_BASE+SAM_PM_APBASEL_OFFSET) +#define SAM_PM_APBBSEL (SAM_PM_BASE+SAM_PM_APBBSEL_OFFSET) +#define SAM_PM_APBCSEL (SAM_PM_BASE+SAM_PM_APBCSEL_OFFSET) +#define SAM_PM_AHBMASK (SAM_PM_BASE+SAM_PM_AHBMASK_OFFSET) +#define SAM_PM_APBAMASK (SAM_PM_BASE+SAM_PM_APBAMASK_OFFSET) +#define SAM_PM_APBBMASK (SAM_PM_BASE+SAM_PM_APBBMASK_OFFSET) +#define SAM_PM_APBCMASK (SAM_PM_BASE+SAM_PM_APBCMASK_OFFSET) +#define SAM_PM_INTENCLR (SAM_PM_BASE+SAM_PM_INTENCLR_OFFSET) +#define SAM_PM_INTENSET (SAM_PM_BASE+SAM_PM_INTENSET_OFFSET) +#define SAM_PM_INTFLAG (SAM_PM_BASE+SAM_PM_INTFLAG_OFFSET) +#define SAM_PM_RCAUSE (SAM_PM_BASE+SAM_PM_RCAUSE_OFFSET) + +/* PM register bit definitions ************************************************************/ + +/* Control register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define PM_CTRL_CFDEN (1 << 2) /* Bit 2: Clock Failure Detector Enable */ +# define PM_CTRL_BKUPCLK (1 << 4) /* Bit 4: Backup Clock Select */ +#endif + +/* Sleep mode register */ + +#define PM_SLEEP_IDLE_SHIFT (0) /* Bits 0-1: Idle Mode Configuration */ +#define PM_SLEEP_IDLE_MASK (3 << PM_SLEEP_IDLE_SHIFT) +# define PM_SLEEP_IDLE_CPU (0 << PM_SLEEP_IDLE_SHIFT) /* CPU clock domain stopped */ +# define PM_SLEEP_IDLE_CPUAHB (1 << PM_SLEEP_IDLE_SHIFT) /* CPU and AHB clock domains stopped */ +# define PM_SLEEP_IDLE_CPUAHBAPB (2 << PM_SLEEP_IDLE_SHIFT) /* CPU, AHB, and APB clock domains stopped */ + +/* CPU clock select register */ + +#define PM_CPUSEL_CPUDIV_SHIFT (0) /* Bits 0-2: CPU Prescaler Selection */ +#define PM_CPUSEL_CPUDIV_MASK (7 << PM_CPUSEL_CPUDIV_SHIFT) +# define PM_CPUSEL_CPUDIV_1 (0 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 1 */ +# define PM_CPUSEL_CPUDIV_2 (1 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 2 */ +# define PM_CPUSEL_CPUDIV_4 (2 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 4 */ +# define PM_CPUSEL_CPUDIV_8 (3 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 8 */ +# define PM_CPUSEL_CPUDIV_16 (4 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 16 */ +# define PM_CPUSEL_CPUDIV_32 (5 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 32 */ +# define PM_CPUSEL_CPUDIV_64 (6 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 64 */ +# define PM_CPUSEL_CPUDIV_128 (7 << PM_CPUSEL_CPUDIV_SHIFT) /* Divide by 128 */ + +/* APBA clock select register */ + +#define PM_APBASEL_APBADIV_SHIFT (0) /* Bits 0-2: APBA Prescaler Selection */ +#define PM_APBASEL_APBADIV_MASK (7 << PM_APBASEL_APBADIV_SHIFT) +# define PM_APBASEL_APBADIV_1 (0 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 1 */ +# define PM_APBASEL_APBADIV_2 (1 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 2 */ +# define PM_APBASEL_APBADIV_4 (2 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 4 */ +# define PM_APBASEL_APBADIV_8 (3 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 8 */ +# define PM_APBASEL_APBADIV_16 (4 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 16 */ +# define PM_APBASEL_APBADIV_32 (5 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 32 */ +# define PM_APBASEL_APBADIV_64 (6 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 64 */ +# define PM_APBASEL_APBADIV_128 (7 << PM_APBASEL_APBADIV_SHIFT) /* Divide by 128 */ + +/* APBB clock select register */ + +#define PM_APBBSEL_APBBDIV_SHIFT (0) /* Bits 0-2: APBB Prescaler Selection */ +#define PM_APBBSEL_APBBDIV_MASK (7 << PM_APBBSEL_APBBDIV_SHIFT) +# define PM_APBBSEL_APBBDIV_1 (0 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 1 */ +# define PM_APBBSEL_APBBDIV_2 (1 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 2 */ +# define PM_APBBSEL_APBBDIV_4 (2 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 4 */ +# define PM_APBBSEL_APBBDIV_8 (3 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 8 */ +# define PM_APBBSEL_APBBDIV_16 (4 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 16 */ +# define PM_APBBSEL_APBBDIV_32 (5 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 32 */ +# define PM_APBBSEL_APBBDIV_64 (6 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 64 */ +# define PM_APBBSEL_APBBDIV_128 (7 << PM_APBBSEL_APBBDIV_SHIFT) /* Divide by 128 */ + +/* APBC clock select register */ + +#define PM_APBCSEL_APBCDIV_SHIFT (0) /* Bits 0-2: APBC Prescaler Selection */ +#define PM_APBCSEL_APBCDIV_MASK (7 << PM_APBCSEL_APBCDIV_SHIFT) +# define PM_APBCSEL_APBCDIV_1 (0 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 1 */ +# define PM_APBCSEL_APBCDIV_2 (1 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 2 */ +# define PM_APBCSEL_APBCDIV_4 (2 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 4 */ +# define PM_APBCSEL_APBCDIV_8 (3 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 8 */ +# define PM_APBCSEL_APBCDIV_16 (4 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 16 */ +# define PM_APBCSEL_APBCDIV_32 (5 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 32 */ +# define PM_APBCSEL_APBCDIV_64 (6 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 64 */ +# define PM_APBCSEL_APBCDIV_128 (7 << PM_APBCSEL_APBCDIV_SHIFT) /* Divide by 128 */ + +/* AHB mask register */ + +#define PM_AHBMASK_HPB0 (1 << 0) /* Bit 0: HPB0 */ +#define PM_AHBMASK_HPB1 (1 << 1) /* Bit 1: HPB1 */ +#define PM_AHBMASK_HPB2 (1 << 2) /* Bit 2: HPB2 */ +#define PM_AHBMASK_DSU (1 << 3) /* Bit 3: DSU */ +#define PM_AHBMASK_NVMCTRL (1 << 4) /* Bit 4: NVMCTRL */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define PM_AHBMASK_DMAC (1 << 5) /* Bit 4: DMA controller */ +# define PM_AHBMASK_USB (1 << 6) /* Bit 4: USB */ +#endif + +/* APBA mask register */ + +#define PM_APBAMASK_PAC0 (1 << 0) /* Bit 0: PAC0 */ +#define PM_APBAMASK_PM (1 << 1) /* Bit 1: PM */ +#define PM_APBAMASK_SYSCTRL (1 << 2) /* Bit 2: SYSCTRL */ +#define PM_APBAMASK_GCLK (1 << 3) /* Bit 3: GCLK */ +#define PM_APBAMASK_WDT (1 << 4) /* Bit 4: WDT */ +#define PM_APBAMASK_RTC (1 << 5) /* Bit 5: RTC */ +#define PM_APBAMASK_EIC (1 << 6) /* Bit 6: EIC */ + +/* APBB mask register */ + +#define PM_APBBMASK_PAC1 (1 << 0) /* Bit 0: PAC1 */ +#define PM_APBBMASK_DSU (1 << 1) /* Bit 1: DSU */ +#define PM_APBBMASK_NVMCTRL (1 << 2) /* Bit 2: NVMCTRL */ +#define PM_APBBMASK_PORT (1 << 3) /* Bit 3: PORT */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define PM_APBBMASK_DMAC (1 << 4) /* Bit 4: DMA controller */ +# define PM_APBBMASK_USB (1 << 5) /* Bit 5: USB */ +#endif + +/* APBC mask register */ + +#define PM_APBCMASK_PAC2 (1 << 0) /* Bit 0: PAC2 */ +#define PM_APBCMASK_EVSYS (1 << 1) /* Bit 1: EVSYS */ +#define PM_APBCMASK_SERCOM(n) (1 << ((n)+2)) +# define PM_APBCMASK_SERCOM0 (1 << 2) /* Bit 2: SERCOM0 */ +# define PM_APBCMASK_SERCOM1 (1 << 3) /* Bit 3: SERCOM1 */ +# define PM_APBCMASK_SERCOM2 (1 << 4) /* Bit 4: SERCOM2 */ +# define PM_APBCMASK_SERCOM3 (1 << 5) /* Bit 5: SERCOM3 */ +# define PM_APBCMASK_SERCOM4 (1 << 6) /* Bit 6: SERCOM4 */ +# define PM_APBCMASK_SERCOM5 (1 << 7) /* Bit 7: SERCOM5 */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define PM_APBCMASK_TC0 (1 << 8) /* Bit 8: TC0 */ +# define PM_APBCMASK_TC1 (1 << 9) /* Bit 9: TC1 */ +# define PM_APBCMASK_TC2 (1 << 10) /* Bit 10: TC2 */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define PM_APBCMASK_TCC0 (1 << 8) /* Bit 8: TCC0 */ +# define PM_APBCMASK_TCC1 (1 << 9) /* Bit 9: TCC1 */ +# define PM_APBCMASK_TCC2 (1 << 10) /* Bit 10: TCC2 */ +#endif + +#define PM_APBCMASK_TC3 (1 << 11) /* Bit 11: TC3 */ +#define PM_APBCMASK_TC4 (1 << 12) /* Bit 12: TC4 */ +#define PM_APBCMASK_TC5 (1 << 13) /* Bit 13: TC5 */ +#define PM_APBCMASK_TC6 (1 << 14) /* Bit 14: TC6 */ +#define PM_APBCMASK_TC7 (1 << 15) /* Bit 15: TC7 */ +#define PM_APBCMASK_ADC (1 << 16) /* Bit 16: ADC */ +#define PM_APBCMASK_AC (1 << 17) /* Bit 17: AC */ +#define PM_APBCMASK_DAC (1 << 18) /* Bit 18: DAC */ +#define PM_APBCMASK_PTC (1 << 19) /* Bit 19: PTC */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define PM_APBBMASK_I2S (1 << 20) /* Bit 20: Inter IC Sound */ +#endif + +/* Interrupt enable clear, Interrupt enable set, and Interrupt flag status and clear registers */ + +#define PM_INT_CKRDY (1 << 0) /* Bit 0: Clock Ready Interrupt */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define PM_INT_CFD (1 << 1) /* Bit 1: Clock Failure Detector Interrupt */ +#endif + +/* Reset cause register */ + +#define PM_RCAUSE_POR (1 << 0) /* Bit 0: Power-On Reset */ +#define PM_RCAUSE_BOD12 (1 << 1) /* Bit 1: Brown Out 12 Detector Reset */ +#define PM_RCAUSE_BOD33 (1 << 2) /* Bit 2: Brown Out 33 Detector Reset */ +#define PM_RCAUSE_EXT (1 << 4) /* Bit 4: External Reset */ +#define PM_RCAUSE_WDT (1 << 5) /* Bit 5: Watchdog Reset */ +#define PM_RCAUSE_SYST (1 << 6) /* Bit 6: System Reset Request */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PM_H */ diff --git a/arch/arm/src/samdl/chip/samd_port.h b/arch/arm/src/samdl/chip/samd_port.h new file mode 100644 index 0000000000000000000000000000000000000000..1cdd769363c8ab156efcb182c19d535fc5e47029 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_port.h @@ -0,0 +1,334 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_port.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PORT_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PORT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* PORT register offsets ********************************************************************/ + +#define SAM_PORTA (0) +#define SAM_PORTB (1) + +#define SAM_PORTN_OFFSET(n) (0x0000 + ((n) << 7)) +#define SAM_PORTA_OFFSET 0x0000 /* Port A register offset */ +#define SAM_PORTB_OFFSET 0x0080 /* Port B register offset */ + +#define SAM_PORT_DIR_OFFSET 0x0000 /* Data direction register */ +#define SAM_PORT_DIRCLR_OFFSET 0x0004 /* Data direction clear register */ +#define SAM_PORT_DIRSET_OFFSET 0x0008 /* Data direction set register */ +#define SAM_PORT_DIRTGL_OFFSET 0x000c /* Data direction toggle register */ +#define SAM_PORT_OUT_OFFSET 0x0010 /* Data output value register */ +#define SAM_PORT_OUTCLR_OFFSET 0x0014 /* Data output value clear register */ +#define SAM_PORT_OUTSET_OFFSET 0x0018 /* Data output value set register */ +#define SAM_PORT_OUTTGL_OFFSET 0x001c /* Data output value toggle register */ +#define SAM_PORT_IN_OFFSET 0x0020 /* Data input value register */ +#define SAM_PORT_CTRL_OFFSET 0x0024 /* Control register */ +#define SAM_PORT_WRCONFIG_OFFSET 0x0028 /* Write configuration registers */ + +#define SAM_PORT_PMUX_OFFSET(n) (0x0030+((n)>>1)) +#define SAM_PORT_PMUX0_OFFSET 0x0030 /* Peripheral multiplexing register 0 */ +#define SAM_PORT_PMUX1_OFFSET 0x0031 /* Peripheral multiplexing register 1 */ +#define SAM_PORT_PMUX2_OFFSET 0x0032 /* Peripheral multiplexing register 2 */ +#define SAM_PORT_PMUX3_OFFSET 0x0033 /* Peripheral multiplexing register 3 */ +#define SAM_PORT_PMUX4_OFFSET 0x0034 /* Peripheral multiplexing register 4 */ +#define SAM_PORT_PMUX5_OFFSET 0x0035 /* Peripheral multiplexing register 5 */ +#define SAM_PORT_PMUX6_OFFSET 0x0036 /* Peripheral multiplexing register 6 */ +#define SAM_PORT_PMUX7_OFFSET 0x0037 /* Peripheral multiplexing register 7 */ +#define SAM_PORT_PMUX8_OFFSET 0x0038 /* Peripheral multiplexing register 8 */ +#define SAM_PORT_PMUX9_OFFSET 0x0039 /* Peripheral multiplexing register 9 */ +#define SAM_PORT_PMUX10_OFFSET 0x003a /* Peripheral multiplexing register 10 */ +#define SAM_PORT_PMUX11_OFFSET 0x003b /* Peripheral multiplexing register 11 */ +#define SAM_PORT_PMUX12_OFFSET 0x003c /* Peripheral multiplexing register 12 */ +#define SAM_PORT_PMUX13_OFFSET 0x003d /* Peripheral multiplexing register 13 */ +#define SAM_PORT_PMUX14_OFFSET 0x003e /* Peripheral multiplexing register 14 */ +#define SAM_PORT_PMUX15_OFFSET 0x003f /* Peripheral multiplexing register 15 */ + +#define SAM_PORT_PINCFG_OFFSET(n) (0x0040+(n)) +#define SAM_PORT_PINCFG0_OFFSET 0x0040 /* Pin configuration register 0 */ +#define SAM_PORT_PINCFG1_OFFSET 0x0041 /* Pin configuration register 1 */ +#define SAM_PORT_PINCFG2_OFFSET 0x0042 /* Pin configuration register 2 */ +#define SAM_PORT_PINCFG3_OFFSET 0x0043 /* Pin configuration register 3 */ +#define SAM_PORT_PINCFG4_OFFSET 0x0044 /* Pin configuration register 4 */ +#define SAM_PORT_PINCFG5_OFFSET 0x0045 /* Pin configuration register 5 */ +#define SAM_PORT_PINCFG6_OFFSET 0x0046 /* Pin configuration register 6 */ +#define SAM_PORT_PINCFG7_OFFSET 0x0047 /* Pin configuration register 7 */ +#define SAM_PORT_PINCFG8_OFFSET 0x0048 /* Pin configuration register 8 */ +#define SAM_PORT_PINCFG9_OFFSET 0x0049 /* Pin configuration register 9 */ +#define SAM_PORT_PINCFG10_OFFSET 0x004a /* Pin configuration register 10 */ +#define SAM_PORT_PINCFG11_OFFSET 0x004b /* Pin configuration register 11 */ +#define SAM_PORT_PINCFG12_OFFSET 0x004c /* Pin configuration register 12 */ +#define SAM_PORT_PINCFG13_OFFSET 0x004d /* Pin configuration register 13 */ +#define SAM_PORT_PINCFG14_OFFSET 0x004e /* Pin configuration register 14 */ +#define SAM_PORT_PINCFG15_OFFSET 0x004f /* Pin configuration register 15 */ +#define SAM_PORT_PINCFG16_OFFSET 0x0050 /* Pin configuration register 16 */ +#define SAM_PORT_PINCFG17_OFFSET 0x0051 /* Pin configuration register 17 */ +#define SAM_PORT_PINCFG18_OFFSET 0x0052 /* Pin configuration register 18 */ +#define SAM_PORT_PINCFG19_OFFSET 0x0053 /* Pin configuration register 19 */ +#define SAM_PORT_PINCFG20_OFFSET 0x0054 /* Pin configuration register 20 */ +#define SAM_PORT_PINCFG21_OFFSET 0x0055 /* Pin configuration register 21 */ +#define SAM_PORT_PINCFG22_OFFSET 0x0056 /* Pin configuration register 22 */ +#define SAM_PORT_PINCFG23_OFFSET 0x0057 /* Pin configuration register 23 */ +#define SAM_PORT_PINCFG24_OFFSET 0x0058 /* Pin configuration register 24 */ +#define SAM_PORT_PINCFG25_OFFSET 0x0059 /* Pin configuration register 25 */ +#define SAM_PORT_PINCFG26_OFFSET 0x005a /* Pin configuration register 26 */ +#define SAM_PORT_PINCFG27_OFFSET 0x005b /* Pin configuration register 27 */ +#define SAM_PORT_PINCFG28_OFFSET 0x005c /* Pin configuration register 28 */ +#define SAM_PORT_PINCFG29_OFFSET 0x005d /* Pin configuration register 29 */ +#define SAM_PORT_PINCFG30_OFFSET 0x005e /* Pin configuration register 30 */ +#define SAM_PORT_PINCFG31_OFFSET 0x005f /* Pin configuration register 31 */ + +/* PORT register addresses ******************************************************************/ + +#define SAM_PORTN_BASE(n) (SAM_PORT_BASE+SAM_PORTN_OFFSET(n)) +#define SAM_PORTA_BASE (SAM_PORT_BASE+SAM_PORTA_OFFSET) +#define SAM_PORTB_BASE (SAM_PORT_BASE+SAM_PORTB_OFFSET) + +#define SAM_PORTA_DIR (SAM_PORTA_BASE+SAM_PORT_DIR_OFFSET) +#define SAM_PORTA_DIRCLR (SAM_PORTA_BASE+SAM_PORT_DIRCLR_OFFSET) +#define SAM_PORTA_DIRSET (SAM_PORTA_BASE+SAM_PORT_DIRSET_OFFSET) +#define SAM_PORTA_DIRTGL (SAM_PORTA_BASE+SAM_PORT_DIRTGL_OFFSET) +#define SAM_PORTA_OUT (SAM_PORTA_BASE+SAM_PORT_OUT_OFFSET) +#define SAM_PORTA_OUTCLR (SAM_PORTA_BASE+SAM_PORT_OUTCLR_OFFSET) +#define SAM_PORTA_OUTSET (SAM_PORTA_BASE+SAM_PORT_OUTSET_OFFSET) +#define SAM_PORTA_OUTTGL (SAM_PORTA_BASE+SAM_PORT_OUTTGL_OFFSET) +#define SAM_PORTA_IN (SAM_PORTA_BASE+SAM_PORT_IN_OFFSET) +#define SAM_PORTA_CTRL (SAM_PORTA_BASE+SAM_PORT_CTRL_OFFSET) +#define SAM_PORTA_WRCONFIG (SAM_PORTA_BASE+SAM_PORT_WRCONFIG_OFFSET) + +#define SAM_PORTA_PMUX(n) (SAM_PORTA_BASE+SAM_PORT_PMUX_OFFSET(n)) +#define SAM_PORTA_PMUX0 (SAM_PORTA_BASE+SAM_PORT_PMUX0_OFFSET) +#define SAM_PORTA_PMUX1 (SAM_PORTA_BASE+SAM_PORT_PMUX1_OFFSET) +#define SAM_PORTA_PMUX2 (SAM_PORTA_BASE+SAM_PORT_PMUX2_OFFSET) +#define SAM_PORTA_PMUX3 (SAM_PORTA_BASE+SAM_PORT_PMUX3_OFFSET) +#define SAM_PORTA_PMUX4 (SAM_PORTA_BASE+SAM_PORT_PMUX4_OFFSET) +#define SAM_PORTA_PMUX5 (SAM_PORTA_BASE+SAM_PORT_PMUX5_OFFSET) +#define SAM_PORTA_PMUX6 (SAM_PORTA_BASE+SAM_PORT_PMUX6_OFFSET) +#define SAM_PORTA_PMUX7 (SAM_PORTA_BASE+SAM_PORT_PMUX7_OFFSET) +#define SAM_PORTA_PMUX8 (SAM_PORTA_BASE+SAM_PORT_PMUX8_OFFSET) +#define SAM_PORTA_PMUX9 (SAM_PORTA_BASE+SAM_PORT_PMUX9_OFFSET) +#define SAM_PORTA_PMUX10 (SAM_PORTA_BASE+SAM_PORT_PMUX10_OFFSET) +#define SAM_PORTA_PMUX11 (SAM_PORTA_BASE+SAM_PORT_PMUX11_OFFSET) +#define SAM_PORTA_PMUX12 (SAM_PORTA_BASE+SAM_PORT_PMUX12_OFFSET) +#define SAM_PORTA_PMUX13 (SAM_PORTA_BASE+SAM_PORT_PMUX13_OFFSET) +#define SAM_PORTA_PMUX14 (SAM_PORTA_BASE+SAM_PORT_PMUX14_OFFSET) +#define SAM_PORTA_PMUX15 (SAM_PORTA_BASE+SAM_PORT_PMUX15_OFFSET) + +#define SAM_PORTA_PINCFG(n) (SAM_PORTA_BASE+SAM_PORT_PINCFG_OFFSET(n)) +#define SAM_PORTA_PINCFG0 (SAM_PORTA_BASE+SAM_PORT_PINCFG0_OFFSET) +#define SAM_PORTA_PINCFG1 (SAM_PORTA_BASE+SAM_PORT_PINCFG1_OFFSET) +#define SAM_PORTA_PINCFG2 (SAM_PORTA_BASE+SAM_PORT_PINCFG2_OFFSET) +#define SAM_PORTA_PINCFG3 (SAM_PORTA_BASE+SAM_PORT_PINCFG3_OFFSET) +#define SAM_PORTA_PINCFG4 (SAM_PORTA_BASE+SAM_PORT_PINCFG4_OFFSET) +#define SAM_PORTA_PINCFG5 (SAM_PORTA_BASE+SAM_PORT_PINCFG5_OFFSET) +#define SAM_PORTA_PINCFG6 (SAM_PORTA_BASE+SAM_PORT_PINCFG6_OFFSET) +#define SAM_PORTA_PINCFG7 (SAM_PORTA_BASE+SAM_PORT_PINCFG7_OFFSET) +#define SAM_PORTA_PINCFG8 (SAM_PORTA_BASE+SAM_PORT_PINCFG8_OFFSET) +#define SAM_PORTA_PINCFG9 (SAM_PORTA_BASE+SAM_PORT_PINCFG9_OFFSET) +#define SAM_PORTA_PINCFG10 (SAM_PORTA_BASE+SAM_PORT_PINCFG10_OFFSET) +#define SAM_PORTA_PINCFG11 (SAM_PORTA_BASE+SAM_PORT_PINCFG11_OFFSET) +#define SAM_PORTA_PINCFG12 (SAM_PORTA_BASE+SAM_PORT_PINCFG12_OFFSET) +#define SAM_PORTA_PINCFG13 (SAM_PORTA_BASE+SAM_PORT_PINCFG13_OFFSET) +#define SAM_PORTA_PINCFG14 (SAM_PORTA_BASE+SAM_PORT_PINCFG14_OFFSET) +#define SAM_PORTA_PINCFG15 (SAM_PORTA_BASE+SAM_PORT_PINCFG15_OFFSET) +#define SAM_PORTA_PINCFG16 (SAM_PORTA_BASE+SAM_PORT_PINCFG16_OFFSET) +#define SAM_PORTA_PINCFG17 (SAM_PORTA_BASE+SAM_PORT_PINCFG17_OFFSET) +#define SAM_PORTA_PINCFG18 (SAM_PORTA_BASE+SAM_PORT_PINCFG18_OFFSET) +#define SAM_PORTA_PINCFG19 (SAM_PORTA_BASE+SAM_PORT_PINCFG19_OFFSET) +#define SAM_PORTA_PINCFG20 (SAM_PORTA_BASE+SAM_PORT_PINCFG20_OFFSET) +#define SAM_PORTA_PINCFG21 (SAM_PORTA_BASE+SAM_PORT_PINCFG21_OFFSET) +#define SAM_PORTA_PINCFG22 (SAM_PORTA_BASE+SAM_PORT_PINCFG22_OFFSET) +#define SAM_PORTA_PINCFG23 (SAM_PORTA_BASE+SAM_PORT_PINCFG23_OFFSET) +#define SAM_PORTA_PINCFG24 (SAM_PORTA_BASE+SAM_PORT_PINCFG24_OFFSET) +#define SAM_PORTA_PINCFG25 (SAM_PORTA_BASE+SAM_PORT_PINCFG25_OFFSET) +#define SAM_PORTA_PINCFG26 (SAM_PORTA_BASE+SAM_PORT_PINCFG26_OFFSET) +#define SAM_PORTA_PINCFG27 (SAM_PORTA_BASE+SAM_PORT_PINCFG27_OFFSET) +#define SAM_PORTA_PINCFG28 (SAM_PORTA_BASE+SAM_PORT_PINCFG28_OFFSET) +#define SAM_PORTA_PINCFG29 (SAM_PORTA_BASE+SAM_PORT_PINCFG29_OFFSET) +#define SAM_PORTA_PINCFG30 (SAM_PORTA_BASE+SAM_PORT_PINCFG30_OFFSET) +#define SAM_PORTA_PINCFG31 (SAM_PORTA_BASE+SAM_PORT_PINCFG31_OFFSET) + +#define SAM_PORTB_DIR (SAM_PORTB_BASE+SAM_PORT_DIR_OFFSET) +#define SAM_PORTB_DIRCLR (SAM_PORTB_BASE+SAM_PORT_DIRCLR_OFFSET) +#define SAM_PORTB_DIRSET (SAM_PORTB_BASE+SAM_PORT_DIRSET_OFFSET) +#define SAM_PORTB_DIRTGL (SAM_PORTB_BASE+SAM_PORT_DIRTGL_OFFSET) +#define SAM_PORTB_OUT (SAM_PORTB_BASE+SAM_PORT_OUT_OFFSET) +#define SAM_PORTB_OUTCLR (SAM_PORTB_BASE+SAM_PORT_OUTCLR_OFFSET) +#define SAM_PORTB_OUTSET (SAM_PORTB_BASE+SAM_PORT_OUTSET_OFFSET) +#define SAM_PORTB_OUTTGL (SAM_PORTB_BASE+SAM_PORT_OUTTGL_OFFSET) +#define SAM_PORTB_IN (SAM_PORTB_BASE+SAM_PORT_IN_OFFSET) +#define SAM_PORTB_CTRL (SAM_PORTB_BASE+SAM_PORT_CTRL_OFFSET) +#define SAM_PORTB_WRCONFIG (SAM_PORTB_BASE+SAM_PORT_WRCONFIG_OFFSET) + +#define SAM_PORTB_PMUX(n) (SAM_PORTB_BASE+SAM_PORT_PMUX_OFFSET(n)) +#define SAM_PORTB_PMUX0 (SAM_PORTB_BASE+SAM_PORT_PMUX0_OFFSET) +#define SAM_PORTB_PMUX1 (SAM_PORTB_BASE+SAM_PORT_PMUX1_OFFSET) +#define SAM_PORTB_PMUX2 (SAM_PORTB_BASE+SAM_PORT_PMUX2_OFFSET) +#define SAM_PORTB_PMUX3 (SAM_PORTB_BASE+SAM_PORT_PMUX3_OFFSET) +#define SAM_PORTB_PMUX4 (SAM_PORTB_BASE+SAM_PORT_PMUX4_OFFSET) +#define SAM_PORTB_PMUX5 (SAM_PORTB_BASE+SAM_PORT_PMUX5_OFFSET) +#define SAM_PORTB_PMUX6 (SAM_PORTB_BASE+SAM_PORT_PMUX6_OFFSET) +#define SAM_PORTB_PMUX7 (SAM_PORTB_BASE+SAM_PORT_PMUX7_OFFSET) +#define SAM_PORTB_PMUX8 (SAM_PORTB_BASE+SAM_PORT_PMUX8_OFFSET) +#define SAM_PORTB_PMUX9 (SAM_PORTB_BASE+SAM_PORT_PMUX9_OFFSET) +#define SAM_PORTB_PMUX10 (SAM_PORTB_BASE+SAM_PORT_PMUX10_OFFSET) +#define SAM_PORTB_PMUX11 (SAM_PORTB_BASE+SAM_PORT_PMUX11_OFFSET) +#define SAM_PORTB_PMUX12 (SAM_PORTB_BASE+SAM_PORT_PMUX12_OFFSET) +#define SAM_PORTB_PMUX13 (SAM_PORTB_BASE+SAM_PORT_PMUX13_OFFSET) +#define SAM_PORTB_PMUX14 (SAM_PORTB_BASE+SAM_PORT_PMUX14_OFFSET) +#define SAM_PORTB_PMUX15 (SAM_PORTB_BASE+SAM_PORT_PMUX15_OFFSET) + +#define SAM_PORTB_PINCFG(n) (SAM_PORTB_BASE+SAM_PORT_PINCFG_OFFSET(n)) +#define SAM_PORTB_PINCFG0 (SAM_PORTB_BASE+SAM_PORT_PINCFG0_OFFSET) +#define SAM_PORTB_PINCFG1 (SAM_PORTB_BASE+SAM_PORT_PINCFG1_OFFSET) +#define SAM_PORTB_PINCFG2 (SAM_PORTB_BASE+SAM_PORT_PINCFG2_OFFSET) +#define SAM_PORTB_PINCFG3 (SAM_PORTB_BASE+SAM_PORT_PINCFG3_OFFSET) +#define SAM_PORTB_PINCFG4 (SAM_PORTB_BASE+SAM_PORT_PINCFG4_OFFSET) +#define SAM_PORTB_PINCFG5 (SAM_PORTB_BASE+SAM_PORT_PINCFG5_OFFSET) +#define SAM_PORTB_PINCFG6 (SAM_PORTB_BASE+SAM_PORT_PINCFG6_OFFSET) +#define SAM_PORTB_PINCFG7 (SAM_PORTB_BASE+SAM_PORT_PINCFG7_OFFSET) +#define SAM_PORTB_PINCFG8 (SAM_PORTB_BASE+SAM_PORT_PINCFG8_OFFSET) +#define SAM_PORTB_PINCFG9 (SAM_PORTB_BASE+SAM_PORT_PINCFG9_OFFSET) +#define SAM_PORTB_PINCFG10 (SAM_PORTB_BASE+SAM_PORT_PINCFG10_OFFSET) +#define SAM_PORTB_PINCFG11 (SAM_PORTB_BASE+SAM_PORT_PINCFG11_OFFSET) +#define SAM_PORTB_PINCFG12 (SAM_PORTB_BASE+SAM_PORT_PINCFG12_OFFSET) +#define SAM_PORTB_PINCFG13 (SAM_PORTB_BASE+SAM_PORT_PINCFG13_OFFSET) +#define SAM_PORTB_PINCFG14 (SAM_PORTB_BASE+SAM_PORT_PINCFG14_OFFSET) +#define SAM_PORTB_PINCFG15 (SAM_PORTB_BASE+SAM_PORT_PINCFG15_OFFSET) +#define SAM_PORTB_PINCFG16 (SAM_PORTB_BASE+SAM_PORT_PINCFG16_OFFSET) +#define SAM_PORTB_PINCFG17 (SAM_PORTB_BASE+SAM_PORT_PINCFG17_OFFSET) +#define SAM_PORTB_PINCFG18 (SAM_PORTB_BASE+SAM_PORT_PINCFG18_OFFSET) +#define SAM_PORTB_PINCFG19 (SAM_PORTB_BASE+SAM_PORT_PINCFG19_OFFSET) +#define SAM_PORTB_PINCFG20 (SAM_PORTB_BASE+SAM_PORT_PINCFG20_OFFSET) +#define SAM_PORTB_PINCFG21 (SAM_PORTB_BASE+SAM_PORT_PINCFG21_OFFSET) +#define SAM_PORTB_PINCFG22 (SAM_PORTB_BASE+SAM_PORT_PINCFG22_OFFSET) +#define SAM_PORTB_PINCFG23 (SAM_PORTB_BASE+SAM_PORT_PINCFG23_OFFSET) +#define SAM_PORTB_PINCFG24 (SAM_PORTB_BASE+SAM_PORT_PINCFG24_OFFSET) +#define SAM_PORTB_PINCFG25 (SAM_PORTB_BASE+SAM_PORT_PINCFG25_OFFSET) +#define SAM_PORTB_PINCFG26 (SAM_PORTB_BASE+SAM_PORT_PINCFG26_OFFSET) +#define SAM_PORTB_PINCFG27 (SAM_PORTB_BASE+SAM_PORT_PINCFG27_OFFSET) +#define SAM_PORTB_PINCFG28 (SAM_PORTB_BASE+SAM_PORT_PINCFG28_OFFSET) +#define SAM_PORTB_PINCFG29 (SAM_PORTB_BASE+SAM_PORT_PINCFG29_OFFSET) +#define SAM_PORTB_PINCFG30 (SAM_PORTB_BASE+SAM_PORT_PINCFG30_OFFSET) +#define SAM_PORTB_PINCFG31 (SAM_PORTB_BASE+SAM_PORT_PINCFG31_OFFSET) + +/* PORT register bit definitions ************************************************************/ + +/* Data direction, data direction clear, data direction set, and data direction toggle + * registers + */ + +#define PORT_DIR(n) (1 << n) /* Port data n, direction, n=0-31 */ + +/* Data output value, data output value clear, data output value set, and data output + * value toggle registers + */ + +#define PORT_OUT(n) (1 << n) /* Port data n output value, n=0-31 */ + +/* Data input value register */ + +#define PORT_IN(n) (1 << n) /* Port n data input value, n=0-31 */ + +/* Control register */ + +#define PORT_CTRL(n) (1 << n) /* Port n input sampling mode, n=0-31 */ + +/* Write configuration registers */ + +#define PORT_WRCONFIG_PINMASK_SHIFT (0) /* Bits 0-15: Pin Mask for Multiple Pin Configuration */ +#define PORT_WRCONFIG_PINMASK_MASK (0xffff << PORT_WRCONFIG_PINMASK_SHIFT) +# define PORT_WRCONFIG_PINMASK(n) (1 << (PORT_WRCONFIG_PINMASK_SHIFT+(n))) +#define PORT_WRCONFIG_PMUXEN (1 << 16) /* Bit 16: Peripheral Multiplexer Enable */ +#define PORT_WRCONFIG_INEN (1 << 17) /* Bit 17: Input Enable */ +#define PORT_WRCONFIG_PULLEN (1 << 18) /* Bit 18: Pull Enable */ +#define PORT_WRCONFIG_DRVSTR (1 << 22) /* Bit 22: Output Driver Strength Selection */ +#define PORT_WRCONFIG_PMUX_SHIFT (24) /* Bits 24-27: Peripheral Multiplexing */ +#define PORT_WRCONFIG_PMUX_MASK (15 << PORT_WRCONFIG_PMUX_SHIFT) +# define PORT_WRCONFIG_PMUX(n) ((uint32_t)(n) << PORT_WRCONFIG_PMUX_SHIFT) +#define PORT_WRCONFIG_WRPMUX (1 << 28) /* Bit 28: Write PMUX */ +#define PORT_WRCONFIG_WRPINCFG (1 << 30) /* Bit 30: Write PINCFG */ +#define PORT_WRCONFIG_HWSEL (1 << 31) /* Bit 31: Half-Word Select */ + +/* Peripheral multiplexing registers */ + +#define PORT_PMUX_PERIPHA 0x00 /* Peripheral function A */ +#define PORT_PMUX_PERIPHB 0x01 /* Peripheral function B */ +#define PORT_PMUX_PERIPHC 0x02 /* Peripheral function C */ +#define PORT_PMUX_PERIPHD 0x03 /* Peripheral function D */ +#define PORT_PMUX_PERIPHE 0x04 /* Peripheral function E */ +#define PORT_PMUX_PERIPHF 0x05 /* Peripheral function F */ +#define PORT_PMUX_PERIPHG 0x06 /* Peripheral function G */ +#define PORT_PMUX_PERIPHH 0x07 /* Peripheral function H */ + +/* Pin configuration registers */ + +#define PORT_PINCFG_PMUXEN (1 << 0) /* Bit 0: Peripheral Multiplexer Enable */ +#define PORT_PINCFG_INEN (1 << 1) /* Bit 1: Input Enable */ +#define PORT_PINCFG_PULLEN (1 << 2) /* Bit 2: Pull Enable */ +#define PORT_PINCFG_DRVSTR (1 << 6) /* Bit 6: Output Driver Strength Selection */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_PORT_H */ diff --git a/arch/arm/src/samdl/chip/samd_sercom.h b/arch/arm/src/samdl/chip/samd_sercom.h new file mode 100644 index 0000000000000000000000000000000000000000..9935dfa3b51f44d5cb240db2ca2fa4cdfc194722 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_sercom.h @@ -0,0 +1,99 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_sercom.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SERCOM_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SERCOM_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Two generic clocks are used by the SERCOM: GCLK_SERCOMx_CORE and GCLK_SERCOMx_SLOW. The + * core clock (GCLK_SERCOMx_CORE) is required to clock the SERCOM while operating as a + * master, while the slow clock (GCLK_SERCOM_SLOW) is only required for certain functions. + * SERCOM modules must share the same slow GCLK channel ID. + * + * The baud-rate generator runs off the GCLK_SERCOMx_CORE clock (or, optionally, external + * clock). + * + * These definitions must match the GCLK_CLKCTRL_ID_* values defined in samd_gclk.c. + */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SERCOM_GCLK_ID_SLOW 12 +# define SERCOM_GCLK_ID_CORE(n) (13+(n)) +# define SERCOM0_GCLK_ID_CORE 13 +# define SERCOM1_GCLK_ID_CORE 14 +# define SERCOM2_GCLK_ID_CORE 15 +# define SERCOM3_GCLK_ID_CORE 16 +# define SERCOM4_GCLK_ID_CORE 17 +# define SERCOM5_GCLK_ID_CORE 18 +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SERCOM_GCLK_ID_SLOW 19 +# define SERCOM_GCLK_ID_CORE(n) (20+(n)) +# define SERCOM0_GCLK_ID_CORE 20 +# define SERCOM1_GCLK_ID_CORE 21 +# define SERCOM2_GCLK_ID_CORE 22 +# define SERCOM3_GCLK_ID_CORE 23 +# define SERCOM4_GCLK_ID_CORE 24 +# define SERCOM5_GCLK_ID_CORE 25 +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SERCOM_H */ diff --git a/arch/arm/src/samdl/chip/samd_spi.h b/arch/arm/src/samdl/chip/samd_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..8bdcc9e21ee2400db743dea1733e997c8ea32c66 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_spi.h @@ -0,0 +1,306 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_spi.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SPI_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SPI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/samd_sercom.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* SPI register offsets *********************************************************************/ + +#define SAM_SPI_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_SPI_CTRLB_OFFSET 0x0004 /* Control B register */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define SAM_SPI_DBGCTRL_OFFSET 0x0008 /* Debug control register */ +# define SAM_SPI_BAUD_OFFSET 0x000a /* Baud register */ +# define SAM_SPI_INTENCLR_OFFSET 0x000c /* Interrupt enable clear register */ +# define SAM_SPI_INTENSET_OFFSET 0x000d /* Interrupt enable set register */ +# define SAM_SPI_INTFLAG_OFFSET 0x000e /* Interrupt flag and status clear register */ +# define SAM_SPI_STATUS_OFFSET 0x0010 /* Status register */ +# define SAM_SPI_ADDR_OFFSET 0x0014 /* Address register */ +# define SAM_SPI_DATA_OFFSET 0x0018 /* Data register */ +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define SAM_SPI_BAUD_OFFSET 0x000c /* Baud register */ +# define SAM_SPI_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +# define SAM_SPI_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +# define SAM_SPI_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +# define SAM_SPI_STATUS_OFFSET 0x001a /* Status register */ +# define SAM_SPI_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +# define SAM_SPI_ADDR_OFFSET 0x0024 /* Address register */ +# define SAM_SPI_DATA_OFFSET 0x0028 /* Data register */ +# define SAM_SPI_DBGCTRL_OFFSET 0x0030 /* Debug control register */ +#endif + +/* SPI register addresses *******************************************************************/ + +#define SAM_SPI0_CTRLA (SAM_SERCOM0_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI0_CTRLB (SAM_SERCOM0_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI0_BAUD (SAM_SERCOM0_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI0_INTENCLR (SAM_SERCOM0_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI0_INTENSET (SAM_SERCOM0_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI0_INTFLAG (SAM_SERCOM0_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI0_STATUS (SAM_SERCOM0_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI0_ADDR (SAM_SERCOM0_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI0_DATA (SAM_SERCOM0_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI0_DBGCTRL (SAM_SERCOM0_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI1_CTRLA (SAM_SERCOM1_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI1_CTRLB (SAM_SERCOM1_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI1_BAUD (SAM_SERCOM1_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI1_INTENCLR (SAM_SERCOM1_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI1_INTENSET (SAM_SERCOM1_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI1_INTFLAG (SAM_SERCOM1_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI1_STATUS (SAM_SERCOM1_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI1_ADDR (SAM_SERCOM1_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI1_DATA (SAM_SERCOM1_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI1_DBGCTRL (SAM_SERCOM1_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI2_CTRLA (SAM_SERCOM2_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI2_CTRLB (SAM_SERCOM2_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI2_BAUD (SAM_SERCOM2_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI2_INTENCLR (SAM_SERCOM2_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI2_INTENSET (SAM_SERCOM2_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI2_INTFLAG (SAM_SERCOM2_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI2_STATUS (SAM_SERCOM2_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI2_ADDR (SAM_SERCOM2_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI2_DATA (SAM_SERCOM2_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI2_DBGCTRL (SAM_SERCOM2_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI3_CTRLA (SAM_SERCOM3_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI3_CTRLB (SAM_SERCOM3_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI3_BAUD (SAM_SERCOM3_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI3_INTENCLR (SAM_SERCOM3_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI3_INTENSET (SAM_SERCOM3_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI3_INTFLAG (SAM_SERCOM3_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI3_STATUS (SAM_SERCOM3_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI3_ADDR (SAM_SERCOM3_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI3_DATA (SAM_SERCOM3_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI3_DBGCTRL (SAM_SERCOM3_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI4_CTRLA (SAM_SERCOM4_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI4_CTRLB (SAM_SERCOM4_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI4_BAUD (SAM_SERCOM4_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI4_INTENCLR (SAM_SERCOM4_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI4_INTENSET (SAM_SERCOM4_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI4_INTFLAG (SAM_SERCOM4_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI4_STATUS (SAM_SERCOM4_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI4_ADDR (SAM_SERCOM4_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI4_DATA (SAM_SERCOM4_BASE+SAM_SPI_DATA_OFFSET) + +#define SAM_SPI5_CTRLA (SAM_SERCOM5_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI5_CTRLB (SAM_SERCOM5_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI5_DBGCTRL (SAM_SERCOM5_BASE+SAM_SPI_DBGCTRL_OFFSET) +#define SAM_SPI5_BAUD (SAM_SERCOM5_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI5_INTENCLR (SAM_SERCOM5_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI5_INTENSET (SAM_SERCOM5_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI5_INTFLAG (SAM_SERCOM5_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI5_STATUS (SAM_SERCOM5_BASE+SAM_SPI_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SPI5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#endif + +#define SAM_SPI5_ADDR (SAM_SERCOM5_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI5_DATA (SAM_SERCOM5_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI4_DBGCTRL (SAM_SERCOM4_BASE+SAM_SPI_DBGCTRL_OFFSET) + +/* SPI register bit definitions *************************************************************/ + +/* Control A register */ + +#define SPI_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define SPI_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SPI_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define SPI_CTRLA_MODE_MASK (7 << SPI_CTRLA_MODE_SHIFT) +# define SPI_CTRLA_MODE_SLAVE (2 << SPI_CTRLA_MODE_SHIFT) /* SPI slave operation */ +# define SPI_CTRLA_MODE_MASTER (3 << SPI_CTRLA_MODE_SHIFT) /* SPI master operation */ +#define SPI_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define SPI_CTRLA_IBON (1 << 8) /* Bit 8: Immediate BUFOVF notification */ +#define SPI_CTRLA_DOPO_SHIFT (16) /* Bit 16-17: Data out pinout */ +#define SPI_CTRLA_DOPO_MASK (3 << SPI_CTRLA_DOPO_SHIFT) /* Bit 16-17: Data out pinout */ +# define SPI_CTRLA_DOPO_DOPAD012 (0 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD0 SCK=PAD1 SS=PAD2 */ +# define SPI_CTRLA_DOPO_DOPAD231 (1 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD2 SCK=PAD3 SS=PAD1 */ +# define SPI_CTRLA_DOPO_DOPAD312 (2 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD3 SCK=PAD1 SS=PAD2 */ +# define SPI_CTRLA_DOPO_DOPAD031 (3 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD0 SCK=PAD3 SS=PAD1 */ +#define SPI_CTRLA_DIPO_SHIFT (20) /* Bits 20-21: Data in pinout */ +#define SPI_CTRLA_DIPO_MASK (3 << SPI_CTRLA_DIPO_SHIFT) +# define SPI_CTRLA_DIPAD0 (0 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD0 for DI */ +# define SPI_CTRLA_DIPAD1 (1 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD1 for DI */ +# define SPI_CTRLA_DIPAD2 (2 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD2 for DI */ +# define SPI_CTRLA_DIPAD3 (3 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD3 for DI */ +#define SPI_CTRLA_FORM_SHIFT (24) /* Bits 24-27: Frame format */ +#define SPI_CTRLA_FORM_MASK (7 << SPI_CTRLA_FORM_SHIFT) +# define SPI_CTRLA_FORM_SPI (0 << SPI_CTRLA_FORM_SHIFT) /* SPI frame (no address) */ +# define SPI_CTRLA_FORM_ADDR (2 << SPI_CTRLA_FORM_SHIFT) /* SPI frame (w/address) */ +#define SPI_CTRLA_CPHA (1 << 28) /* Bit 28: Clock phase */ +#define SPI_CTRLA_CPOL (1 << 29) /* Bit 29: Clock polarity */ +#define SPI_CTRLA_DORD (1 << 30) /* Bit 30: Data order */ +# define SPI_CTRLA_MSBFIRST (0) +# define SPI_CTRLA_LSBFIRST SPI_CTRLA_DORD + +/* Control B register */ + +#define SPI_CTRLB_CHSIZE_SHIFT (0) /* Bits 0-2: Character Size */ +#define SPI_CTRLB_CHSIZE_MASK (7 << SPI_CTRLB_CHSIZE_SHIFT) +# define SPI_CTRLB_CHSIZE_8BITS (0 << SPI_CTRLB_CHSIZE_SHIFT) /* 8 bits */ +# define SPI_CTRLB_CHSIZE_9BITS (1 << SPI_CTRLB_CHSIZE_SHIFT) /* 9 bits */ +#define SPI_CTRLB_PLOADEN (1 << 6) /* Bit 6: Slave Data Preload Enable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SPI_CTRLB_SSDE (1 << 9) /* Bit 9: Slave Select Low Detect Enable */ +# define SPI_CTRLB_MSSEN (1 << 13) /* Bit 13: Master Slave Select Enable */ +#endif + +#define SPI_CTRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */ +#define SPI_CTRLB_AMODE_MASK (3 << SPI_CTRLB_AMODE_SHIFT) +# define SPI_CTRLB_AMODE_ADDRMASK (0 << SPI_CTRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */ +# define SPI_CTRLB_AMODE_2ADDRS (1 << SPI_CTRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */ +# define SPI_CTRLB_AMODE_RANGE (2 << SPI_CTRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */ +#define SPI_CTRLB_RXEN (1 << 17) /* Bit 17: Receiver enable */ + +/* Baud register (8-bit baud value) */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define SPI_INT_DRE (1 << 0) /* Bit 0: Data register empty interrupt */ +#define SPI_INT_TXC (1 << 1) /* Bit 1: Transmit complete interrupt */ +#define SPI_INT_RXC (1 << 2) /* Bit 2: Receive complete interrupt */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SPI_INT_ALL (0x07) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SPI_INT_ SSL (1 << 3) /* Bit 3: Slave select low interrupt */ +# define SPI_INT_ ERROR (1 << 7) /* Bit 7: Error interrupt */ + +# define SPI_INT_ALL (0x8f) +#endif + +/* Status register */ + +#define SPI_STATUS_BUFOVF (1 << 2) /* Bit 2: Buffer overflow */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SPI_STATUS_SYNCBUSY (1 << 15) /* Bit 15: Synchronization busy */ +#endif + +#define SPI_STATUS_CLRALL SPI_STATUS_BUFOVF + +/* Synchronization busy register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SPI_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +# define SPI_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +# define SPI_SYNCBUSY_CTRLB (1 << 2) /* Bit 2: CTRLB synchronization busy */ + +# define SPI_SYNCBUSY_ALL 0x0007 +#endif + +/* Address register */ + +#define SPI_ADDR_SHIFT (0) /* Bits 0-7: Address */ +#define SPI_ADDR_MASK (0xff << SPI_ADDR_SHIFT) +# define SPI_ADDR(n) ((uint32_t)(n) << SPI_ADDR_SHIFT) +#define SPI_ADDRMASK_SHIFT (16) /* Bits 16-23: Address Mask */ +#define SPI_ADDRMASK_MASK (0xff << SPI_ADDRMASK_SHIFT) +# define SPI_ADDRMASK(n) ((uint32_t)(n) << SPI_ADDRMASK_SHIFT) + +/* Data register */ + +#define SPI_DATA_MASK (0x1ff) /* Bits 0-8: Data */ + +/* Debug control register */ + +#define SPI_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SPI_H */ diff --git a/arch/arm/src/samdl/chip/samd_sysctrl.h b/arch/arm/src/samdl/chip/samd_sysctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..a4c6cdd069b3a8026bd0a66d40f988240a090f85 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_sysctrl.h @@ -0,0 +1,435 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_sysctrl.h + * + * Copyright (C) 2014, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SYSCTRL_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SYSCTRL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* SYSCTRL register offsets *****************************************************************/ + +#define SAM_SYSCTRL_INTENCLR_OFFSET 0x0000 /* Interrupt enable clear */ +#define SAM_SYSCTRL_INTENSET_OFFSET 0x0004 /* Interrupt enable set */ +#define SAM_SYSCTRL_INTFLAG_OFFSET 0x0008 /* Interrupt flag status and clear */ +#define SAM_SYSCTRL_PCLKSR_OFFSET 0x000c /* Power and clocks status */ +#define SAM_SYSCTRL_XOSC_OFFSET 0x0010 /* External multi-purpose crystal oscillator control */ +#define SAM_SYSCTRL_XOSC32K_OFFSET 0x0014 /* 32kHz external crystal oscillator control */ +#define SAM_SYSCTRL_OSC32K_OFFSET 0x0018 /* 32kHz internal oscillator control */ +#define SAM_SYSCTRL_OSCULP32K_OFFSET 0x001c /* 32kHz ultra low power internal oscillator control */ +#define SAM_SYSCTRL_OSC8M_OFFSET 0x0020 /* 8MHz internal oscillator control */ +#define SAM_SYSCTRL_DFLLCTRL_OFFSET 0x0024 /* DFLL48M control */ +#define SAM_SYSCTRL_DFLLVAL_OFFSET 0x0028 /* DFLL48M value */ +#define SAM_SYSCTRL_DFLLMUL_OFFSET 0x002c /* DFLL48M multiplier */ +#define SAM_SYSCTRL_DFLLSYNC_OFFSET 0x0030 /* DFLL48M synchronization */ +#define SAM_SYSCTRL_BOD33_OFFSET 0x0034 /* 3.3V brown-out detector control */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SYSCTRL_VREG_OFFSET 0x003c /* Voltage regulator system control */ +#endif + +#define SAM_SYSCTRL_VREF_OFFSET 0x0040 /* Voltage references system control */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SYSCTRL_DPLLCTRLA_OFFSET 0x0044 /* DPLL Control A */ +# define SAM_SYSCTRL_DPLLRATIO_OFFSET 0x0048 /* DPLL ratio control */ +# define SAM_SYSCTRL_DPLLCTRLB_OFFSET 0x004c /* DPLL Control B */ +# define SAM_SYSCTRL_DPLLSTATUS_OFFSET 0x0050 /* DPLL status */ +#endif + +/* SYSCTRL register addresses ***************************************************************/ + +#define SAM_SYSCTRL_INTENCLR (SAM_SYSCTRL_BASE+SAM_SYSCTRL_INTENCLR_OFFSET) +#define SAM_SYSCTRL_INTENSET (SAM_SYSCTRL_BASE+SAM_SYSCTRL_INTENSET_OFFSET) +#define SAM_SYSCTRL_INTFLAG (SAM_SYSCTRL_BASE+SAM_SYSCTRL_INTFLAG_OFFSET) +#define SAM_SYSCTRL_PCLKSR (SAM_SYSCTRL_BASE+SAM_SYSCTRL_PCLKSR_OFFSET) +#define SAM_SYSCTRL_XOSC (SAM_SYSCTRL_BASE+SAM_SYSCTRL_XOSC_OFFSET) +#define SAM_SYSCTRL_XOSC32K (SAM_SYSCTRL_BASE+SAM_SYSCTRL_XOSC32K_OFFSET) +#define SAM_SYSCTRL_OSC32K (SAM_SYSCTRL_BASE+SAM_SYSCTRL_OSC32K_OFFSET) +#define SAM_SYSCTRL_OSCULP32K (SAM_SYSCTRL_BASE+SAM_SYSCTRL_OSCULP32K_OFFSET) +#define SAM_SYSCTRL_OSC8M (SAM_SYSCTRL_BASE+SAM_SYSCTRL_OSC8M_OFFSET) +#define SAM_SYSCTRL_DFLLCTRL (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DFLLCTRL_OFFSET) +#define SAM_SYSCTRL_DFLLVAL (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DFLLVAL_OFFSET) +#define SAM_SYSCTRL_DFLLMUL (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DFLLMUL_OFFSET) +#define SAM_SYSCTRL_DFLLSYNC (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DFLLSYNC_OFFSET) +#define SAM_SYSCTRL_BOD33 (SAM_SYSCTRL_BASE+SAM_SYSCTRL_BOD33_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SYSCTRL_VREG (SAM_SYSCTRL_BASE+SAM_SYSCTRL_VREG_OFFSET) +#endif + +#define SAM_SYSCTRL_VREF (SAM_SYSCTRL_BASE+SAM_SYSCTRL_VREF_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_SYSCTRL_DPLLCTRLA (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DPLLCTRLA_OFFSET) +# define SAM_SYSCTRL_DPLLRATIO (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DPLLRATIO_OFFSET) +# define SAM_SYSCTRL_DPLLCTRLB (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DPLLCTRLB_OFFSET) +# define SAM_SYSCTRL_DPLLSTATUS (SAM_SYSCTRL_BASE+SAM_SYSCTRL_DPLLSTATUS_OFFSET) +#endif + +/* SYSCTRL register bit definitions *********************************************************/ + +/* Interrupt enable clear, Interrupt enable set, Interrupt flag status and clear, and + * Power and clocks status registers. + */ + +#define SYSCTRL_INT_XOSCRDY (1 << 0) /* Bit 0: XOSC ready interrupt */ +#define SYSCTRL_INT_XOSC32KRDY (1 << 1) /* Bit 1: XOSC32K ready interrupt */ +#define SYSCTRL_INT_OSC32KRDY (1 << 2) /* Bit 2: OSC32K ready interrupt */ +#define SYSCTRL_INT_OSC8MRDY (1 << 3) /* Bit 3: OSC8M ready interrupt */ +#define SYSCTRL_INT_DFLLRDY (1 << 4) /* Bit 4: DFLL ready interrupt */ +#define SYSCTRL_INT_DFLLOOB (1 << 5) /* Bit 5: DFLL out of bounds interrupt */ +#define SYSCTRL_INT_DFLLLCKF (1 << 6) /* Bit 6: DFLL lock fine interrupt */ +#define SYSCTRL_INT_DFLLLCKC (1 << 7) /* Bit 7: DFLL lock coarse interrupt */ +#define SYSCTRL_INT_DFLLRCS (1 << 8) /* Bit 8: DFLL reference clock stopped interrupt */ +#define SYSCTRL_INT_BOD33RDY (1 << 9) /* Bit 9: BOD33 ready interrupt */ +#define SYSCTRL_INT_BOD33DET (1 << 10) /* Bit 10: BOD33 detection interrupt */ +#define SYSCTRL_INT_B33SRDY (1 << 11) /* Bit 11: BOD33 synchronization ready interrupt */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define SYSCTRL_INT_BOD12RDY (1 << 12) /* Bit 12: BOD12 ready interrupt */ +# define SYSCTRL_INT_BOD12DET (1 << 13) /* Bit 13: BOD12 detection interrupt */ +# define SYSCTRL_INT_B12SRDY (1 << 14) /* Bit 14: BOD12 synchronization ready interrupt */ + +# define SYSCTRL_INT_ALL (0x00007fff) +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define SYSCTRL_INT_DPLLLCKR (1 << 15) /* Bit 15: DPLL lock rise interrupt */ +# define SYSCTRL_INT_DPLLLCKF (1 << 16) /* Bit 16: DPLL lock fall interrupt */ +# define SYSCTRL_INT_DPLLLTO (1 << 17) /* Bit 17: DPLL lock timeout interrupt */ + +# define SYSCTRL_INT_ALL (0x00038fff) +#endif + +/* External multi-purpose crystal oscillator control register */ + +#define SYSCTRL_XOSC_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define SYSCTRL_XOSC_XTALEN (1 << 2) /* Bit 2: Crystal oscillator enable */ +#define SYSCTRL_XOSC_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SYSCTRL_XOSC_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SYSCTRL_XOSC_GAIN_SHIFT (8) /* Bits 8-10: Oscillator gain */ +#define SYSCTRL_XOSC_GAIN_MASK (7 << SYSCTRL_XOSC_GAIN_SHIFT) +# define SYSCTRL_XOSC_GAIN(n) ((n) << SYSCTRL_XOSC_GAIN_SHIFT) +# define SYSCTRL_XOSC_GAIN_2MHZ (0 << SYSCTRL_XOSC_GAIN_SHIFT) /* 2MHz */ +# define SYSCTRL_XOSC_GAIN_4MHZ (1 << SYSCTRL_XOSC_GAIN_SHIFT) /* 4MHz */ +# define SYSCTRL_XOSC_GAIN_8MHZ (2 << SYSCTRL_XOSC_GAIN_SHIFT) /* 8MHz */ +# define SYSCTRL_XOSC_GAIN_16MHZ (3 << SYSCTRL_XOSC_GAIN_SHIFT) /* 16MHz */ +# define SYSCTRL_XOSC_GAIN_30MHZ (4 << SYSCTRL_XOSC_GAIN_SHIFT) /* 30MHz */ +#define SYSCTRL_XOSC_AMPGC (1 << 11) /* Bit 11: Automatic amplitude gain control */ +#define SYSCTRL_XOSC_STARTUP_SHIFT (12) /* Bits 12-15: Start-up time */ +#define SYSCTRL_XOSC_STARTUP_MASK (15 << SYSCTRL_XOSC_STARTUP_SHIFT) +# define SYSCTRL_XOSC_STARTUP(n) ((n) << SYSCTRL_XOSC_STARTUP_SHIFT) +# define SYSCTRL_XOSC_STARTUP_31US (0 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 31µs */ +# define SYSCTRL_XOSC_STARTUP_61US (1 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 61µs */ +# define SYSCTRL_XOSC_STARTUP_122US (2 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 122µs */ +# define SYSCTRL_XOSC_STARTUP_244US (3 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 244µs */ +# define SYSCTRL_XOSC_STARTUP_488US (4 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 488µs */ +# define SYSCTRL_XOSC_STARTUP_977US (5 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 977µs */ +# define SYSCTRL_XOSC_STARTUP_2MS (6 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 1953µs */ +# define SYSCTRL_XOSC_STARTUP_4MS (7 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 3906µs */ +# define SYSCTRL_XOSC_STARTUP_8MS (8 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 7813µs */ +# define SYSCTRL_XOSC_STARTUP_16MS (9 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 15625µs */ +# define SYSCTRL_XOSC_STARTUP_31MS (10 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 31250µs */ +# define SYSCTRL_XOSC_STARTUP_63MS (11 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 62500µs */ +# define SYSCTRL_XOSC_STARTUP_125MS (12 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 125000µs */ +# define SYSCTRL_XOSC_STARTUP_250MS (13 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 250000µs */ +# define SYSCTRL_XOSC_STARTUP_500MS (14 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 500000µs */ +# define SYSCTRL_XOSC_STARTUP_1S (15 << SYSCTRL_XOSC_STARTUP_SHIFT) /* 1000000µs */ + +/* 32kHz external crystal oscillator control register */ + +#define SYSCTRL_XOSC32K_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define SYSCTRL_XOSC32K_XTALEN (1 << 2) /* Bit 2: Crystal oscillator enable */ +#define SYSCTRL_XOSC32K_EN32K (1 << 3) /* Bit 3: 32kHz Output enable */ +#define SYSCTRL_XOSC32K_EN1K (1 << 4) /* Bit 4: 1kHz Output enable */ +#define SYSCTRL_XOSC32K_AAMPEN (1 << 5) /* Bit 5: Automatic amplitude control enable */ +#define SYSCTRL_XOSC32K_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SYSCTRL_XOSC32K_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SYSCTRL_XOSC32K_STARTUP_SHIFT (8) /* Bits 8-10: Oscillator start-up time */ +#define SYSCTRL_XOSC32K_STARTUP_MASK (7 << SYSCTRL_XOSC32K_STARTUP_SHIFT) +# define SYSCTRL_XOSC32K_STARTUP(n) ((n) << SYSCTRL_XOSC32K_STARTUP_SHIFT) +# define SYSCTRL_XOSC32K_STARTUP_122US (0 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 122µs */ +# define SYSCTRL_XOSC32K_STARTUP_1MS (1 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 1068µs */ +# define SYSCTRL_XOSC32K_STARTUP_63MS (2 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 62592µs */ +# define SYSCTRL_XOSC32K_STARTUP_125MS (3 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 125092µs */ +# define SYSCTRL_XOSC32K_STARTUP_500MS (4 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 500092µs */ +# define SYSCTRL_XOSC32K_STARTUP_1S (5 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 1000092µs */ +# define SYSCTRL_XOSC32K_STARTUP_2S (6 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 2000092µs */ +# define SYSCTRL_XOSC32K_STARTUP_4S (7 << SYSCTRL_XOSC32K_STARTUP_SHIFT) /* 4000092µs */ +#define SYSCTRL_XOSC32K_WRTLOCK (1 << 12) /* Bit 12: Write lock */ + +/* 32kHz internal oscillator control register */ + +#define SYSCTRL_OSC32K_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define SYSCTRL_OSC32K_EN32K (1 << 2) /* Bit 2: 32kHz Output enable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define SYSCTRL_OSC32K_EN1K (1 << 3) /* Bit 3: 1kHz Output enable */ +#endif + +#define SYSCTRL_OSC32K_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SYSCTRL_OSC32K_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SYSCTRL_OSC32K_STARTUP_SHIFT (8) /* Bits 8-10: Oscillator start-up time */ +#define SYSCTRL_OSC32K_STARTUP_MASK (7 << SYSCTRL_OSC32K_STARTUP_SHIFT) +# define SYSCTRL_OSC32K_STARTUP(n) ((n) << SYSCTRL_OSC32K_STARTUP_SHIFT) +# define SYSCTRL_OSC32K_STARTUP_92US (0 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 92µs */ +# define SYSCTRL_OSC32K_STARTUP_122US (1 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 122µs */ +# define SYSCTRL_OSC32K_STARTUP_183US (2 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 183µs */ +# define SYSCTRL_OSC32K_STARTUP_305US (3 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 305µs */ +# define SYSCTRL_OSC32K_STARTUP_549US (4 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 549µs */ +# define SYSCTRL_OSC32K_STARTUP_1MS (5 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 1038µs */ +# define SYSCTRL_OSC32K_STARTUP_2MS (6 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 2014µs */ +# define SYSCTRL_OSC32K_STARTUP_4MS (7 << SYSCTRL_OSC32K_STARTUP_SHIFT) /* 3967µs */ +#define SYSCTRL_OSC32K_WRTLOCK (1 << 12) /* Bit 12: Write lock */ +#define SYSCTRL_OSC32K_CALIB_SHIFT (16) /* Bits 16-22: Oscillator calibration */ +#define SYSCTRL_OSC32K_CALIB_MASK (0x7f << SYSCTRL_OSC32K_CALIB_SHIFT) +# define SYSCTRL_OSC32K_CALIB(n) ((n) << SYSCTRL_OSC32K_CALIB_SHIFT) + +/* 32kHz ultra low power internal oscillator control register */ + +#define SYSCTRL_OSCULP32K_CALIB_SHIFT (0) /* Bits 0-4: Oscillator Calibration */ +#define SYSCTRL_OSCULP32K_CALIB_MASK (0x7f << SYSCTRL_OSCULP32K_CALIB_SHIFT) +# define SYSCTRL_OSCULP32K_CALIB(n) ((n) << SYSCTRL_OSCULP32K_CALIB_SHIFT) +#define SYSCTRL_OSCULP32K_WRTLOCK (1 << 7) /* Bit 7: Write Lock */ + +/* 8MHz internal oscillator control register */ + +#define SYSCTRL_OSC8M_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define SYSCTRL_OSC8M_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SYSCTRL_OSC8M_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SYSCTRL_OSC8M_PRESC_SHIFT (8) /* Bits 8-9: Oscillator prescaler */ +#define SYSCTRL_OSC8M_PRESC_MASK (3 << SYSCTRL_OSC8M_PRESC_SHIFT) +# define SYSCTRL_OSC8M_PRESC(n) ((n) << SYSCTRL_OSC8M_PRESC_SHIFT) +# define SYSCTRL_OSC8M_PRESC_DIV1 (0 << SYSCTRL_OSC8M_PRESC_SHIFT) /* 1 */ +# define SYSCTRL_OSC8M_PRESC_DIV2 (1 << SYSCTRL_OSC8M_PRESC_SHIFT) /* 2 */ +# define SYSCTRL_OSC8M_PRESC_DIV3 (2 << SYSCTRL_OSC8M_PRESC_SHIFT) /* 4 */ +# define SYSCTRL_OSC8M_PRESC_DIV8 (3 << SYSCTRL_OSC8M_PRESC_SHIFT) /* 8 */ +#define SYSCTRL_OSC8M_CALIB_SHIFT (16) /* Bits 16-27: Oscillator calibration */ +#define SYSCTRL_OSC8M_CALIB_MASK (0xfff << SYSCTRL_OSC8M_CALIB_SHIFT) +# define SYSCTRL_OSC8M_CALIB(n) ((n) << SYSCTRL_OSC8M_CALIB_SHIFT) +#define SYSCTRL_OSC8M_FRANGE_SHIFT (30) /* Bits 30-31: Oscillator frequency range */ +#define SYSCTRL_OSC8M_FRANGE_MASK (3 << SYSCTRL_OSC8M_FRANGE_SHIFT) +# define SYSCTRL_OSC8M_FRANGE(n) ((n) << SYSCTRL_OSC8M_FRANGE_SHIFT) +# define SYSCTRL_OSC8M_FRANGE_LOW (0 << SYSCTRL_OSC8M_FRANGE_SHIFT) /* 4 to 6MHz */ +# define SYSCTRL_OSC8M_FRANGE_MEDLOW (1 << SYSCTRL_OSC8M_FRANGE_SHIFT) /* 6 to 8MHz */ +# define SYSCTRL_OSC8M_FRANGE_MEDHI (2 << SYSCTRL_OSC8M_FRANGE_SHIFT) /* 8 to 11MHz */ +# define SYSCTRL_OSC8M_FRANGE_HI (3 << SYSCTRL_OSC8M_FRANGE_SHIFT) /* 11 to 15MHz */ + +/* DFLL48M control register */ + +#define SYSCTRL_DFLLCTRL_ENABLE (1 << 1) /* Bit 1: DFLL enable */ +#define SYSCTRL_DFLLCTRL_MODE (1 << 2) /* Bit 2: Operating mode selection */ +#define SYSCTRL_DFLLCTRL_STABLE (1 << 3) /* Bit 3: Stable DFLL frequency */ +#define SYSCTRL_DFLLCTRL_LLAW (1 << 4) /* Bit 4: Lose lock after wake */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DFLLCTRL_USBCRM (1 << 5) /* Bit 5: USB clock recovery mode */ +# define SYSCTRL_DFLLCTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#endif + +#define SYSCTRL_DFLLCTRL_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SYSCTRL_DFLLCTRL_CCDIS (1 << 8) /* Bit 8: Chill cycle disable */ +#define SYSCTRL_DFLLCTRL_QLDIS (1 << 9) /* Bit 9: Quick Lock Disable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DFLLCTRL_BPLCKC (1 << 10) /* Bit 10: Bypass coards lock */ +# define SYSCTRL_DFLLCTRL_WAITLOCK (1 << 11) /* Bit 11: Wait lock */ +#endif + +/* DFLL48M value register */ + +#define SYSCTRL_DFLLVAL_FINE_SHIFT (0) /* Bits 0-9: Fine value */ +#define SYSCTRL_DFLLVAL_FINE_MASK (0x3ff << SYSCTRL_DFLLVAL_FINE_SHIFT) +# define SYSCTRL_DFLLVAL_FINE(n) ((n) << SYSCTRL_DFLLVAL_FINE_SHIFT) +#define SYSCTRL_DFLLVAL_COARSE_SHIFT (10) /* Bits 10-15: Coarse value */ +#define SYSCTRL_DFLLVAL_COARSE_MASK (0x3f << SYSCTRL_DFLLVAL_COARSE_SHIFT) +# define SYSCTRL_DFLLVAL_COARSE(n) ((n) << SYSCTRL_DFLLVAL_COARSE_SHIFT) +#define SYSCTRL_DFLLVAL_DIFF_SHIFT (16) /* Bits 16-31: Multiplication ratio difference */ +#define SYSCTRL_DFLLVAL_DIFF_MASK (0xffff << SYSCTRL_DFLLVAL_DIFF_SHIFT) +# define SYSCTRL_DFLLVAL_DIFF(n) ((n) << SYSCTRL_DFLLVAL_DIFF_SHIFT) + +/* DFLL48M multiplier register */ + +#define SYSCTRL_DFLLMUL_MUL_SHIFT (0) /* Bits 0-15: DFLL multiply factor */ +#define SYSCTRL_DFLLMUL_MUL_MASK (0xffff << SYSCTRL_DFLLMUL_MUL_SHIFT) +# define SYSCTRL_DFLLMUL_MUL(n) ((n) << SYSCTRL_DFLLMUL_MUL_SHIFT) +#define SYSCTRL_DFLLMUL_FSTEP_SHIFT (16) /* Bits 16-25: Fine maximum step */ +#define SYSCTRL_DFLLMUL_FSTEP_MASK (0x3ff << SYSCTRL_DFLLMUL_FSTEP_SHIFT) +# define SYSCTRL_DFLLMUL_FSTEP(n) ((n) << SYSCTRL_DFLLMUL_FSTEP_SHIFT) +#define SYSCTRL_DFLLMUL_CSTEP_SHIFT (26) /* Bits 26-31: Coarse maximum step */ +#define SYSCTRL_DFLLMUL_CSTEP_MASK (0x3f << SYSCTRL_DFLLMUL_CSTEP_SHIFT) +# define SYSCTRL_DFLLMUL_CSTEP(n) ((n) << SYSCTRL_DFLLMUL_CSTEP_SHIFT) + +/* DFLL48M synchronization register */ + +#define SYSCTRL_DFLLSYNC_READREQ (1 << 7) /* Bit 7: Read request */ + +/* 3.3V brown-out detector control register */ + +#define SYSCTRL_BOD33_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SYSCTRL_BOD33_HYST (1 << 2) /* Bit 2: Hysteresis */ +#define SYSCTRL_BOD33_ACTION_SHIFT (3) /* Bits 3-4: BOD33 action */ +#define SYSCTRL_BOD33_ACTION_MASK (3 << SYSCTRL_BOD33_ACTION_SHIFT) +# define SYSCTRL_BOD33_ACTION(n) ((n) << SYSCTRL_BOD33_ACTION_SHIFT) +# define SYSCTRL_BOD33_ACTION_NONE (0 << SYSCTRL_BOD33_ACTION_SHIFT) /* No action */ +# define SYSCTRL_BOD33_ACTION_RESET (1 << SYSCTRL_BOD33_ACTION_SHIFT) /* BOD33 generates reset */ +# define SYSCTRL_BOD33_ACTION_INTR (2 << SYSCTRL_BOD33_ACTION_SHIFT) /* BOD33 generates interrupt */ +#define SYSCTRL_BOD33_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SYSCTRL_BOD33_MODE (1 << 8) /* Bit 8: Operation mode */ +#define SYSCTRL_BOD33_CEN (1 << 9) /* Bit 9: Clock enable */ +#define SYSCTRL_BOD33_PSEL_SHIFT (12) /* Bits 12-15: Prescaler select */ +#define SYSCTRL_BOD33_PSEL_MASK (15 << SYSCTRL_BOD33_PSEL_SHIFT) +# define SYSCTRL_BOD33_PSEL(n) ((n) << SYSCTRL_BOD33_PSEL_SHIFT) +# define SYSCTRL_BOD33_PSEL_DIV2 (0 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 2 */ +# define SYSCTRL_BOD33_PSEL_DIV4 (1 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 4 */ +# define SYSCTRL_BOD33_PSEL_DIV8 (2 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 8 */ +# define SYSCTRL_BOD33_PSEL_DIV16 (3 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 16 */ +# define SYSCTRL_BOD33_PSEL_DIV32 (4 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 32 */ +# define SYSCTRL_BOD33_PSEL_DIV64 (5 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 64 */ +# define SYSCTRL_BOD33_PSEL_DIV128 (6 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 128 */ +# define SYSCTRL_BOD33_PSEL_DIV256 (7 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 256 */ +# define SYSCTRL_BOD33_PSEL_DIV512 (8 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 512 */ +# define SYSCTRL_BOD33_PSEL_DIV1K (9 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 1024 */ +# define SYSCTRL_BOD33_PSEL_DIV2K (10 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 2048 */ +# define SYSCTRL_BOD33_PSEL_DIV4K (11 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 4096 */ +# define SYSCTRL_BOD33_PSEL_DIV8K (12 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 8192 */ +# define SYSCTRL_BOD33_PSEL_DIV16K (13 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 16384 */ +# define SYSCTRL_BOD33_PSEL_DIV32K (14 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 32768 */ +# define SYSCTRL_BOD33_PSEL_DIV64K (15 << SYSCTRL_BOD33_PSEL_SHIFT) /* Divide clock by 65536 */ +#define SYSCTRL_BOD33_LEVEL_SHIFT (16) /* Bits 16-21: BOD33 threshold level */ +#define SYSCTRL_BOD33_LEVEL_MASK (0x3f << SYSCTRL_BOD33_LEVEL_SHIFT) +# define SYSCTRL_BOD33_LEVEL(n) ((n) << SYSCTRL_BOD33_LEVEL_SHIFT) + +/* Voltage regulator system control register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_VREG_RUNSTDBY (1 << 6) /* Bit 6: Run in Standby */ +# define SYSCTRL_VREG_FORCELDO (1 << 13) /* Bit 13: Force LDO voltage regulator */ +#endif + +/* Voltage references system control register */ + +#define SYSCTRL_VREF_TSEN (1 << 1) /* Bit 1: Temperature sensor enable */ +#define SYSCTRL_VREF_BGOUTEN (1 << 2) /* Bit 2: Bandgap output enable */ +#define SYSCTRL_VREF_CALIB_SHIFT (16) /* Bits 16-26: Bandgap voltage generator calibration */ +#define SYSCTRL_VREF_CALIB_MASK (0x7ff << SYSCTRL_VREF_CALIB_SHIFT) +# define SYSCTRL_VREF_CALIB(n) ((n) << SYSCTRL_VREF_CALIB_SHIFT) + +/* DPLL Control A register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DPLLCTRLA_ENABLE (1 << 1) /* Bit 1: DPLL Enable */ +# define SYSCTRL_DPLLCTRLA_RUNSTDBY (1 << 6) /* Bit 6: Run in Standby */ +# define SYSCTRL_DPLLCTRLA_ONDEMAND (1 << 7) /* Bit 7: On Demand Clock Activation */ +#endif + +/* DPLL ratio control registers */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DPLLRATIO_LDR_SHIFT (0) /* Bits 0-11: Loop Divider Ratio */ +# define SYSCTRL_DPLLRATIO_LDR_MASK (0xfff << SYSCTRL_DPLLRATIO_LDR_SHIFT) +# define SYSCTRL_DPLLRATIO_LDR(n) ((uint32_t)(n) << SYSCTRL_DPLLRATIO_LDR_SHIFT) +# define SYSCTRL_DPLLRATIO_LDRFRAC_SHIFT (16) /* Bits 16-19: Loop Divider Ratio Fractional Part */ +# define SYSCTRL_DPLLRATIO_LDRFRAC_MASK (15 << SYSCTRL_DPLLRATIO_LDRFRAC_SHIFT) +# define SYSCTRL_DPLLRATIO_LDRFRAC(n) ((uint32_t)(n) << SYSCTRL_DPLLRATIO_LDRFRAC_SHIFT) +#endif + +/* DPLL Control B register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DPLLCTRLB_FILTER_SHIFT (0) /* Bits 0-1: Proportional Integral Filter Selection */ +# define SYSCTRL_DPLLCTRLB_FILTER_MASK (3 << SYSCTRL_DPLLCTRLB_FILTER_SHIFT) +# define SYSCTRL_DPLLCTRLB_FILTER_DEFAULT (0 << SYSCTRL_DPLLCTRLB_FILTER_SHIFT) /* Default filter mode */ +# define SYSCTRL_DPLLCTRLB_FILTER_LBFILT (1 << SYSCTRL_DPLLCTRLB_FILTER_SHIFT) /* Low bandwidth filter */ +# define SYSCTRL_DPLLCTRLB_FILTER_HBFILT (2 << SYSCTRL_DPLLCTRLB_FILTER_SHIFT) /* High bandwidth filter */ +# define SYSCTRL_DPLLCTRLB_FILTER_HDFILT (3 << SYSCTRL_DPLLCTRLB_FILTER_SHIFT) /* High damping filter */ +# define SYSCTRL_DPLLCTRLB_LPEN (1 << 2) /* Bit 2: Low-Power Enable */ +# define SYSCTRL_DPLLCTRLB_WUF (1 << 3) /* Bit 3: Wake Up Fast */ +# define SYSCTRL_DPLLCTRLB_REFCLK_SHIFT (4) /* Bits 4-5: Reference Clock Selection */ +# define SYSCTRL_DPLLCTRLB_REFCLK_MASK (3 << SYSCTRL_DPLLCTRLB_REFCLK_SHIFT) +# define SYSCTRL_DPLLCTRLB_REFCLK_XOSC32 (0 << SYSCTRL_DPLLCTRLB_REFCLK_SHIFT) /* XOSC32 clock reference */ +# define SYSCTRL_DPLLCTRLB_REFCLK_XOSC (1 << SYSCTRL_DPLLCTRLB_REFCLK_SHIFT) /* XOSC clock reference */ +# define SYSCTRL_DPLLCTRLB_REFCLK_GCLKDPLL (2 << SYSCTRL_DPLLCTRLB_REFCLK_SHIFT) /* GCLK_DPLL clock reference */ +# define SYSCTRL_DPLLCTRLB_LTIME_SHIFT (8) /* Bits 8-10: Lock Time */ +# define SYSCTRL_DPLLCTRLB_LTIME_MASK (7 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) +# define SYSCTRL_DPLLCTRLB_LTIME_DEFAULT (0 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) /* No time-out */ +# define SYSCTRL_DPLLCTRLB_LTIME_8MS (4 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no lock within 8 ms */ +# define SYSCTRL_DPLLCTRLB_LTIME_9MS (5 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no lock within 9 ms */ +# define SYSCTRL_DPLLCTRLB_LTIME_10MS (6 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no lock within 10 ms */ +# define SYSCTRL_DPLLCTRLB_LTIME_11MS (7 << SYSCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no lock within 11 ms */ +# define SYSCTRL_DPLLCTRLB_LBYPASS (1 << 12) /* Bit 12: Lock Bypass */ +# define SYSCTRL_DPLLCTRLB_DIV_SHIFT (16) /* Bits 16-26: */ +# define SYSCTRL_DPLLCTRLB_DIV_MASK (0x7ff << SYSCTRL_DPLLCTRLB_DIV_SHIFT) +# define SYSCTRL_DPLLCTRLB_DIV(n) ((uint32_t)(n) << SYSCTRL_DPLLCTRLB_DIV_SHIFT) +#endif + +/* DPLL status register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SYSCTRL_DPLLSTATUS_LOCK (1 << 0) /* Bit 0: DPLL Lock Status */ +# define SYSCTRL_DPLLSTATUS_CLKRDY (1 << 1) /* Bit 1: Output Clock Ready */ +# define SYSCTRL_DPLLSTATUS_ENABLE (1 << 2) /* Bit 2: DPLL Enable */ +# define SYSCTRL_DPLLSTATUS_DIV (1 << 3) /* Bit 3: Divider Enable */ +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_SYSCTRL_H */ diff --git a/arch/arm/src/samdl/chip/samd_usart.h b/arch/arm/src/samdl/chip/samd_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..0a5bfe85bbd3414fbeefb625be8d6277601515de --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_usart.h @@ -0,0 +1,394 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_usart.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_USART_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_USART_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/samd_sercom.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* USART register offsets *******************************************************************/ + +#define SAM_USART_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_USART_CTRLB_OFFSET 0x0004 /* Control B register */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define SAM_USART_DBGCTRL_OFFSET 0x0008 /* Debug control register */ +# define SAM_USART_BAUD_OFFSET 0x000a /* Baud register */ +# define SAM_USART_INTENCLR_OFFSET 0x000c /* Interrupt enable clear register */ +# define SAM_USART_INTENSET_OFFSET 0x000d /* Interrupt enable set register */ +# define SAM_USART_INTFLAG_OFFSET 0x000e /* Interrupt flag and status clear register */ +# define SAM_USART_STATUS_OFFSET 0x0010 /* Status register */ +# define SAM_USART_DATA_OFFSET 0x0018 /* Data register */ +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define SAM_USART_BAUD_OFFSET 0x000c /* Baud register */ +# define SAM_USART_RXPL_OFFSET 0x000e /* Receive pulse length register */ +# define SAM_USART_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +# define SAM_USART_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +# define SAM_USART_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +# define SAM_USART_STATUS_OFFSET 0x001a /* Status register */ +# define SAM_USART_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +# define SAM_USART_DATA_OFFSET 0x0028 /* Data register */ +# define SAM_USART_DBGCTRL_OFFSET 0x0030 /* Debug control register */ +#endif + + +/* USART register addresses *****************************************************************/ + +#define SAM_USART0_CTRLA (SAM_SERCOM0_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART0_CTRLB (SAM_SERCOM0_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART0_BAUD (SAM_SERCOM0_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART0_RXPL (SAM_SERCOM0_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART0_INTENCLR (SAM_SERCOM0_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART0_INTENSET (SAM_SERCOM0_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART0_INTFLAG (SAM_SERCOM0_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART0_STATUS (SAM_SERCOM0_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART0_DATA (SAM_SERCOM0_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART0_DBGCTRL (SAM_SERCOM0_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART1_CTRLA (SAM_SERCOM1_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART1_CTRLB (SAM_SERCOM1_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART1_BAUD (SAM_SERCOM1_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART1_RXPL (SAM_SERCOM1_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART1_INTENCLR (SAM_SERCOM1_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART1_INTENSET (SAM_SERCOM1_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART1_INTFLAG (SAM_SERCOM1_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART1_STATUS (SAM_SERCOM1_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART1_DATA (SAM_SERCOM1_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART1_DBGCTRL (SAM_SERCOM1_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART2_CTRLA (SAM_SERCOM2_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART2_CTRLB (SAM_SERCOM2_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART2_BAUD (SAM_SERCOM2_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART2_RXPL (SAM_SERCOM2_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART2_INTENCLR (SAM_SERCOM2_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART2_INTENSET (SAM_SERCOM2_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART2_INTFLAG (SAM_SERCOM2_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART2_STATUS (SAM_SERCOM2_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART2_DATA (SAM_SERCOM2_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART2_DBGCTRL (SAM_SERCOM2_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART3_CTRLA (SAM_SERCOM3_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART3_CTRLB (SAM_SERCOM3_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART3_BAUD (SAM_SERCOM3_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART3_RXPL (SAM_SERCOM3_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART3_INTENCLR (SAM_SERCOM3_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART3_INTENSET (SAM_SERCOM3_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART3_INTFLAG (SAM_SERCOM3_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART3_STATUS (SAM_SERCOM3_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART3_DATA (SAM_SERCOM3_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART3_DBGCTRL (SAM_SERCOM3_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART4_CTRLA (SAM_SERCOM4_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART4_CTRLB (SAM_SERCOM4_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART4_BAUD (SAM_SERCOM4_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART4_RXPL (SAM_SERCOM4_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART4_INTENCLR (SAM_SERCOM4_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART4_INTENSET (SAM_SERCOM4_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART4_INTFLAG (SAM_SERCOM4_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART4_STATUS (SAM_SERCOM4_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART4_DATA (SAM_SERCOM4_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART4_DBGCTRL (SAM_SERCOM4_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART5_CTRLA (SAM_SERCOM5_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART5_CTRLB (SAM_SERCOM5_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART5_BAUD (SAM_SERCOM5_BASE+SAM_USART_BAUD_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART5_RXPL (SAM_SERCOM5_BASE+SAM_USART_RXPL_OFFSET) +#endif + +#define SAM_USART5_INTENCLR (SAM_SERCOM5_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART5_INTENSET (SAM_SERCOM5_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART5_INTFLAG (SAM_SERCOM5_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART5_STATUS (SAM_SERCOM5_BASE+SAM_USART_STATUS_OFFSET) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define SAM_USART5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_USART_SYNCBUSY_OFFSET) +#endif + +#define SAM_USART5_DATA (SAM_SERCOM5_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART5_DBGCTRL (SAM_SERCOM5_BASE+SAM_USART_DBGCTRL_OFFSET) + +/* USART register bit definitions ***********************************************************/ + +/* Control A register */ + +#define USART_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define USART_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define USART_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define USART_CTRLA_MODE_MASK (7 << USART_CTRLA_MODE_SHIFT) +# define USART_CTRLA_MODE_EXTUSART (0 << USART_CTRLA_MODE_SHIFT) /* USART with external clock */ +# define USART_CTRLA_MODE_INTUSART (1 << USART_CTRLA_MODE_SHIFT) /* USART with internal clock */ + /* Bits 5-6: reserved */ +#define USART_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define USART_CTRLA_IBON (1 << 8) /* Bit 8: Immediate BUFOVF notification */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) + /* Bits 9-15: reserved */ +# define USART_CTRLA_TXPO (1 << 16) /* Bit 16: Transmit data pinout */ +# define USART_CTRLA_TXPAD0 (0) +# define USART_CTRLA_TXPAD2 USART_CTRLA_TXPO +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) + /* Bits 9-12: reserved */ +# define USART_CTRLA_SAMPR_SHIFT (13) /* Bits 13-15: Sample rate */ +# define USART_CTRLA_SAMPR_MASK (3 << USART_CTRLA_SAMPR_SHIFT) +# define USART_CTRLA_SAMPR_16XA (0 << USART_CTRLA_SAMPR_SHIFT) /* 16x oversampling; arithmetic baud */ +# define USART_CTRLA_SAMPR_16XF (1 << USART_CTRLA_SAMPR_SHIFT) /* 16x oversampling; fractional baud */ +# define USART_CTRLA_SAMPR_8XA (2 << USART_CTRLA_SAMPR_SHIFT) /* 8x oversampling; arithmetic baud */ +# define USART_CTRLA_SAMPR_8XF (3 << USART_CTRLA_SAMPR_SHIFT) /* 8x oversampling; fractional baud */ +# define USART_CTRLA_SAMPR_3XA (4 << USART_CTRLA_SAMPR_SHIFT) /* 3x oversampling; arithmetic baud */ +# define USART_CTRLA_TXPO_SHIFT (16) /* Bits 16-17: Transmit data pinout */ +# define USART_CTRLA_TXPO_MASK (3 << USART_CTRLA_TXPO_SHIFT) +# define USART_CTRLA_TXPAD0_1 (0 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[0]; XCK=PAD[1] */ +# define USART_CTRLA_TXPAD2 (1 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[2]; XCK=PAD[3] */ +# define USART_CTRLA_TXPAD0_2 (2 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[0]; RTS=PAD[2]; CTS=PAD[3] */ +#endif + +#define USART_CTRLA_RXPO_SHIFT (20) /* Bits 20-21: Receive data pinout */ +#define USART_CTRLA_RXPO_MASK (3 << USART_CTRLA_RXPO_SHIFT) +# define USART_CTRLA_RXPAD0 (0 << USART_CTRLA_RXPO_SHIFT) /* SERCOM PAD[0] for RxD */ +# define USART_CTRLA_RXPAD1 (1 << USART_CTRLA_RXPO_SHIFT) /* SERCOM PAD[1] for RxD */ +# define USART_CTRLA_RXPAD2 (2 << USART_CTRLA_RXPO_SHIFT) /* SERCOM PAD[2] for RxD */ +# define USART_CTRLA_RXPAD3 (3 << USART_CTRLA_RXPO_SHIFT) /* SERCOM PAD[3] for RxD */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_CTRLA_SAMPA_SHIFT (22) /* Bits 22-23: Sample adjustment */ +# define USART_CTRLA_SAMPA_MASK (3 << USART_CTRLA_SAMPA_SHIFT) +# define USART_CTRLA_SAMPA_789 (0 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 7-8-9 */ +# define USART_CTRLA_SAMPA_91011 (1 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 9-10-11 */ +# define USART_CTRLA_SAMPA_111213 (2 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 11-12-13 */ +# define USART_CTRLA_SAMPA_131415 (3 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 13-14-15 */ +#endif + +#define USART_CTRLA_FORM_SHIFT (24) /* Bits 24-27: Frame format */ +#define USART_CTRLA_FORM_MASK (7 << USART_CTRLA_FORM_SHIFT) +# define USART_CTRLA_FORM_NOPARITY (0 << USART_CTRLA_FORM_SHIFT) /* USART frame (no parity) */ +# define USART_CTRLA_FORM_PARITY (1 << USART_CTRLA_FORM_SHIFT) /* USART frame (w/parity) */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_CTRLA_FORM_AUTOBAUD (4 << USART_CTRLA_FORM_SHIFT) /* Auto-baud (no parity) */ +# define USART_CTRLA_FORM_AUTOBAUDP (5 << USART_CTRLA_FORM_SHIFT) /* Auto-baud (parity) */ +#endif + +#define USART_CTRLA_CMODE (1 << 28) /* Bit 28: Communication mode */ +# define USART_CTRLA_ASYNCH (0) +# define USART_CTRLA_SYNCH USART_CTRLA_CMODE +#define USART_CTRLA_CPOL (1 << 29) /* Bit 29: Clock polarity */ +# define USART_CTRLA_CPOL_NORMAL (0) /* Rising XCK edge Falling XCK edge */ +# define USART_CTRLA_CPOL_INVERTED USART_CTRLA_CPOL /* Falling XCK edge Rising XCK edge */ +#define USART_CTRLA_DORD (1 << 30) /* Bit 30: Data order */ +# define USART_CTRLA_MSBFIRST (0) +# define USART_CTRLA_LSBFIRST USART_CTRLA_DORD + +/* Control B register */ + +#define USART_CTRLB_CHSIZE_SHIFT (0) /* Bits 0-2: Character Size */ +#define USART_CTRLB_CHSIZE_MASK (7 << USART_CTRLB_CHSIZE_SHIFT) +# define USART_CTRLB_CHSIZE_8BITS (0 << USART_CTRLB_CHSIZE_SHIFT) /* 8 bits */ +# define USART_CTRLB_CHSIZE_9BITS (1 << USART_CTRLB_CHSIZE_SHIFT) /* 9 bits */ +# define USART_CTRLB_CHSIZE_5BITS (5 << USART_CTRLB_CHSIZE_SHIFT) /* 5 bits */ +# define USART_CTRLB_CHSIZE_6BITS (6 << USART_CTRLB_CHSIZE_SHIFT) /* 6 bits */ +# define USART_CTRLB_CHSIZE_7BITS (7 << USART_CTRLB_CHSIZE_SHIFT) /* 7 bits */ +#define USART_CTRLB_SBMODE (1 << 6) /* Bit 6: Stop bit mode */ +# define USART_CTRLB_SBMODE_1 (0) +# define USART_CTRLB_SBMODE_2 USART_CTRLB_SBMODE + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_CTRLB_COLDEN (1 << 8) /* Bit 8: Collision detection enable */ +#endif + +#define USART_CTRLB_SFDE (1 << 9) /* Bit 9: Start of frame detection enable */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_CTRLB_ENC (1 << 10) /* Bit 10: Encoding format */ +# define USART_CTRLB_UNENCODED (0) +# define USART_CTRLB_IRDA USART_CTRLB_ENC +#endif + +#define USART_CTRLB_PMODE (1 << 13) /* Bit 13: Parity mode */ +# define USART_CTRLB_PEVEN (0) +# define USART_CTRLB_PODD USART_CTRLB_PMODE +#define USART_CTRLB_TXEN (1 << 16) /* Bit 16: Transmitter enable */ +#define USART_CTRLB_RXEN (1 << 17) /* Bit 17: Receiver enable */ + +/* Baud register (For SAMD20, this is a 16-bit baud value) */ +/* For SAMD20 or for SAMD21 with SAMPR[0]=0 */ + +#define USART_BAUD_SHIFT (0) /* Bits 0-15: Baud Value */ +#define USART_BAUD_MASK (0xffff) +# define USART_BAUD(n) ((uint16_t)(n)) + +/* For SAMD20 or for SAMD21 with SAMPR[0]=0 */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_BAUD_IP_SHIFT (0) /* Bits 0-12: Baud Value (integer part) */ +# define USART_BAUD_IP_MASK (0x1fff) +# define USART_IP_BAUD(n) ((uint16_t)(n)) +# define USART_BAUD_FP_SHIFT (13) /* Bits 13-15: Fractional part */ +# define USART_BAUD_FP_MASK (7 << USART_BAUD_FP_SHIFT) +# define USART_BAUD_FP(n) ((uint16_t)(n) << USART_BAUD_FP_SHIFT) +#endif + +/* Receive pulse length register (8-bit value) */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define USART_INT_DRE (1 << 0) /* Bit 0: Data register empty interrupt */ +#define USART_INT_TXC (1 << 1) /* Bit 1: Transmit complete interrupt */ +#define USART_INT_RXC (1 << 2) /* Bit 2: Receive complete interrupt */ +#define USART_INT_RXS (1 << 3) /* Bit 3: Receive start interrupt */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# define USART_INT_CTSIC (1 << 4) /* Bit 4: Clear to send input change interrupt */ +# define USART_INT_RXBRK (1 << 5) /* Bit 5: Receive break interrupt */ +# define USART_INT_ERROR (1 << 7) /* Bit 6: Error interrupt */ +# define USART_INT_ALL (0xbf) +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# define USART_INT_ALL (0x0f) +#endif + +/* Status register */ + +#define USART_STATUS_PERR (1 << 0) /* Bit 0: Parity error */ +#define USART_STATUS_FERR (1 << 1) /* Bit 1: Frame error */ +#define USART_STATUS_BUFOVF (1 << 2) /* Bit 2: Buffer overflow */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_STATUS_CTS (1 << 3) /* Bit 3: Clear to send */ +# define USART_STATUS_ISF (1 << 4) /* Bit 4: Inconsistent sync field */ +# define USART_STATUS_COLL (1 << 5) /* Bit 5: Collision detected */ +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define USART_STATUS_SYNCBUSY (1 << 15) /* Bit 15: Synchronization busy */ +#endif + +/* Synchronization busy register */ + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define USART_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +# define USART_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +# define USART_SYNCBUSY_CTRLB (1 << 2) /* Bit 2: CTRLB synchronization busy */ + +# define USART_SYNCBUSY_ALL 0x0007 +#endif + +/* Data register */ + +#define USART_DATA_MASK (0x1ff) /* Bits 0-8: Data */ + +/* Debug control register */ + +#define USART_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_USART_H */ diff --git a/arch/arm/src/samdl/chip/samd_wdt.h b/arch/arm/src/samdl/chip/samd_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..0032ff70f0fe56b8724a7401191b98ba2e0181f5 --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_wdt.h @@ -0,0 +1,162 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_wdt.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAM_WDT_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAM_WDT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* WDT register offsets *********************************************************************/ + +#define SAM_WDT_CTRL_OFFSET 0x0000 /* Control register */ +#define SAM_WDT_CONFIG_OFFSET 0x0001 /* Configuration register */ +#define SAM_WDT_EWCTRL_OFFSET 0x0002 /* Early warning interrupt control register */ +#define SAM_WDT_INTENCLR_OFFSET 0x0004 /* Interrupt enable clear register */ +#define SAM_WDT_INTENSET_OFFSET 0x0005 /* Interrupt enable set register */ +#define SAM_WDT_INTFLAG_OFFSET 0x0006 /* Interrupt flag and status clear register */ +#define SAM_WDT_STATUS_OFFSET 0x0007 /* Status register */ +#define SAM_WDT_CLEAR_OFFSET 0x0008 /* Clear register */ + +/* WDT register addresses *******************************************************************/ + +#define SAM_WDT_CTRL (SAM_WDT_BASE+SAM_WDT_CTRL_OFFSET) +#define SAM_WDT_CONFIG (SAM_WDT_BASE+SAM_WDT_CONFIG_OFFSET) +#define SAM_WDT_EWCTRL (SAM_WDT_BASE+SAM_WDT_EWCTRL_OFFSET) +#define SAM_WDT_INTENCLR (SAM_WDT_BASE+SAM_WDT_INTENCLR_OFFSET) +#define SAM_WDT_INTENSET (SAM_WDT_BASE+SAM_WDT_INTENSET_OFFSET) +#define SAM_WDT_INTFLAG (SAM_WDT_BASE+SAM_WDT_INTFLAG_OFFSET) +#define SAM_WDT_STATUS (SAM_WDT_BASE+SAM_WDT_STATUS_OFFSET) +#define SAM_WDT_CLEAR (SAM_WDT_BASE+SAM_WDT_CLEAR_OFFSET) + +/* WDT register bit definitions *************************************************************/ + +/* Control register */ + +#define WDT_CTRL_ENABLE (1 << 1) /* Bit 1: Enable */ +#define WDT_CTRL_WEN (1 << 2) /* Bit 2: Watchdog Timer Window Mode Enable */ +#define WDT_CTRL_ALWAYSON (1 << 7) /* Bit 7: Always-On */ + +/* Configuration register */ + +#define WDT_CONFIG_PER_SHIFT (0) /* Bits 0–3: Time-Out Period */ +#define WDT_CONFIG_PER_MASK (15 << WDT_CONFIG_PER_SHIFT) +# define WDT_CONFIG_PER_8 (0 << WDT_CONFIG_PER_SHIFT) /* 8 clock cycles */ +# define WDT_CONFIG_PER_16 (1 << WDT_CONFIG_PER_SHIFT) /* 16 clock cycles */ +# define WDT_CONFIG_PER_32 (2 << WDT_CONFIG_PER_SHIFT) /* 32 clock cycles */ +# define WDT_CONFIG_PER_64 (3 << WDT_CONFIG_PER_SHIFT) /* 64 clock cycles */ +# define WDT_CONFIG_PER_128 (4 << WDT_CONFIG_PER_SHIFT) /* 128 clock cycles */ +# define WDT_CONFIG_PER_256 (5 << WDT_CONFIG_PER_SHIFT) /* 256 clocks cycles */ +# define WDT_CONFIG_PER_512 (6 << WDT_CONFIG_PER_SHIFT) /* 512 clocks cycles */ +# define WDT_CONFIG_PER_1K (7 << WDT_CONFIG_PER_SHIFT) /* 1024 clock cycles */ +# define WDT_CONFIG_PER_2K (8 << WDT_CONFIG_PER_SHIFT) /* 2048 clock cycles */ +# define WDT_CONFIG_PER_4K (9 << WDT_CONFIG_PER_SHIFT) /* 4096 clock cycles */ +# define WDT_CONFIG_PER_8k (10 << WDT_CONFIG_PER_SHIFT) /* 8192 clock cycles */ +# define WDT_CONFIG_PER_16K (11 << WDT_CONFIG_PER_SHIFT) /* 16384 clock cycles */ +#define WDT_CONFIG_WINDOW_SHIFT (4) /* Bits 4-7: Window Mode Time-Out Period */ +#define WDT_CONFIG_WINDOW_MASK (15 << WDT_CONFIG_WINDOW_SHIFT) +# define WDT_CONFIG_WINDOW_8 (0 << WDT_CONFIG_WINDOW_SHIFT) /* 8 clock cycles */ +# define WDT_CONFIG_WINDOW_16 (1 << WDT_CONFIG_WINDOW_SHIFT) /* 16 clock cycles */ +# define WDT_CONFIG_WINDOW_32 (2 << WDT_CONFIG_WINDOW_SHIFT) /* 32 clock cycles */ +# define WDT_CONFIG_WINDOW_64 (3 << WDT_CONFIG_WINDOW_SHIFT) /* 64 clock cycles */ +# define WDT_CONFIG_WINDOW_128 (4 << WDT_CONFIG_WINDOW_SHIFT) /* 128 clock cycles */ +# define WDT_CONFIG_WINDOW_256 (5 << WDT_CONFIG_WINDOW_SHIFT) /* 256 clocks cycles */ +# define WDT_CONFIG_WINDOW_512 (6 << WDT_CONFIG_WINDOW_SHIFT) /* 512 clocks cycles */ +# define WDT_CONFIG_WINDOW_1K (7 << WDT_CONFIG_WINDOW_SHIFT) /* 1024 clock cycles */ +# define WDT_CONFIG_WINDOW_2K (8 << WDT_CONFIG_WINDOW_SHIFT) /* 2048 clock cycles */ +# define WDT_CONFIG_WINDOW_4K (9 << WDT_CONFIG_WINDOW_SHIFT) /* 4096 clock cycles */ +# define WDT_CONFIG_WINDOW_8k (10 << WDT_CONFIG_WINDOW_SHIFT) /* 8192 clock cycles */ +# define WDT_CONFIG_WINDOW_16K (11 << WDT_CONFIG_WINDOW_SHIFT) /* 16384 clock cycles */ + +/* Early warning interrupt control register */ + +#define WDT_EWCTRL_EWOFFSET_SHIFT (0) /* Bits 0-3: Early warning interrupt time offset */ +#define WDT_EWCTRL_EWOFFSET_MASK (15 << WDT_EWCTRL_EWOFFSET_SHIFT) +# define WDT_EWCTRL_EWOFFSET_8 (0 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 8 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_16 (1 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 16 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_32 (2 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 32 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_64 (3 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 64 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_128 (4 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 128 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_256 (5 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 256 clocks cycles */ +# define WDT_EWCTRL_EWOFFSET_512 (6 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 512 clocks cycles */ +# define WDT_EWCTRL_EWOFFSET_1K (7 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 1024 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_2K (8 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 2048 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_4K (9 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 4096 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_8k (10 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 8192 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_16K (11 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 16384 clock cycles */ + +/* Interrupt enable clear, interrupt enable set register, interrupt flag status and clear registers */ + +#define WDT_INT_EW (1 << 0) /* Bit 0: Early warning interrupt */ +#define WDT_INT_All (0x01) + +/* Status register */ + +#define WDT_STATUS_SYNCBUSY (1 << 7) /* Bit 7: Synchronization Busy */ + +/* Clear register */ + +#define WDT_CLEAR_CLEAR_SHIFT (0) /* Bits 0-7: Watchdog clear */ +#define WDT_CLEAR_CLEAR_MASK (0xff << WDT_CLEAR_CLEAR_SHIFT) +# define WDT_CLEAR_CLEAR (0xa5 << WDT_CLEAR_CLEAR_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAM_WDT_H */ diff --git a/arch/arm/src/samdl/chip/saml21_memorymap.h b/arch/arm/src/samdl/chip/saml21_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..b02f6d15b4ff04053db90c72258766da349dabf4 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml21_memorymap.h @@ -0,0 +1,142 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml21_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_MEMORYMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* System Memory Map */ + +#define SAM_FLASH_BASE 0x00000000 /* Embedded FLASH memory space (<= 256KB) */ +#define SAM_FLASHRWW_BASE 0x00400000 /* Embedded FLASH RWW memory space (<= 8KB) */ +#define SAM_NVM_BASE 0x00800000 /* Readable NVM content */ +#define SAM_SRAM_BASE 0x20000000 /* Embedded SRAM memory space (<= 32KB) */ +#define SAM_LPSRAM_BASE 0x30000000 /* Embedded low-power SRAM memory space (<= 8KB) */ +#define SAM_AHBA_BASE 0x40000000 /* AHB-APB Bridge A (64KB) */ +#define SAM_AHBB_BASE 0x41000000 /* AHB-APB Bridge B (64KB) */ +#define SAM_AHBC_BASE 0x42000000 /* AHB-APB Bridge C (64KB) */ +#define SAM_AHBD_BASE 0x43000000 /* AHB-APB Bridge D (64KB) */ +#define SAM_AHBE_BASE 0x44000000 /* AHB-APB Bridge D (64KB) */ +#define SAM_IOBUS_BASE 0x60000000 /* IOBUS (O.5KB) */ +#define SAM_SYSTEM_BASE 0x60000200 /* System */ + +/* Non-volatile memory */ + +#define SAM_NVMUSER_ROW 0x00804000 /* NVM user row */ +#define SAM_NVMCALIB_AREA 0x00806020 /* NVM software calibration area */ +#define SAM_NVM_SERIALNO 0x0080a00c /* Serial number */ + +/* AHB-APB Bridge A */ + +#define SAM_PM_BASE 0x40000000 /* Power Management */ +#define SAM_MCLK_BASE 0x40000400 /* Main Clock */ +#define SAM_RSTC_BASE 0x40000800 /* Reset controller */ +#define SAM_OSCCTRL_BASE 0x40000c00 /* Oscillators Controller */ +#define SAM_OSC32KCTRL_BASE 0x40001000 /* 32KHz Oscillators Controller */ +#define SAM_SUPC_BASE 0x40001400 /* Supply Controller */ +#define SAM_GCLK_BASE 0x40001800 /* Generic Clock Controller */ +#define SAM_WDT_BASE 0x40001c00 /* Watchdog Timer */ +#define SAM_RTC_BASE 0x40002000 /* Real-Time Counter */ +#define SAM_EIC_BASE 0x40002400 /* External Interrupt Controller */ +#define SAM_PORT_BASE 0x40002800 /* Ports */ + +/* AHB-APB Bridge B */ + +#define SAM_USB_BASE 0x41000000 /* Universal Serial Bus */ +#define SAM_DSU_BASE 0x41002000 /* Device Service Unit */ +#define SAM_NVMCTRL_BASE 0x41004000 /* Non-Volatile Memory Controller */ +#define SAM_MTB_BASE 0x41006000 /* Micro trace buffer */ + +/* AHB-APB Bridge C */ + +#define SAM_SERCOM0_BASE 0x42000000 /* Serial Communication Interface 0 */ +#define SAM_SERCOM1_BASE 0x42000400 /* Serial Communication Interface 1 */ +#define SAM_SERCOM2_BASE 0x42000800 /* Serial Communication Interface 2 */ +#define SAM_SERCOM3_BASE 0x42000c00 /* Serial Communication Interface 3 */ +#define SAM_SERCOM4_BASE 0x42001000 /* Serial Communication Interface 4 */ +#define SAM_TCC0_BASE 0x42001400 /* Timer/Counter Control 0 */ +#define SAM_TCC1_BASE 0x42001800 /* Timer/Counter Control 1 */ +#define SAM_TCC2_BASE 0x42001c00 /* Timer/Counter Control 2 */ +#define SAM_TC0_BASE 0x42002000 /* Timer/Counter 0 */ +#define SAM_TC1_BASE 0x42002400 /* Timer/Counter 1 */ +#define SAM_TC2_BASE 0x42002800 /* Timer/Counter 2 */ +#define SAM_TC3_BASE 0x42002c00 /* Timer/Counter 3 */ +#define SAM_DAC_BASE 0x42003000 /* Digital-to-Analog Converter */ +#define SAM_AES_BASE 0x42003400 /* Advanced Encryption Standard */ +#define SAM_TRNG_BASE 0x42003800 /* True Random Number Generator */ + +/* AHB-APB Bridge D */ + +#define SAM_EVSYS_BASE 0x43000000 /* Event system */ +#define SAM_SERCOM5_BASE 0x43000400 /* Serial Communication Interface 5 */ +#define SAM_TC4_BASE 0x43000800 /* Timer/Counter 4 */ +#define SAM_ADC_BASE 0x43000c00 /* Analog-to-Digital Converter */ +#define SAM_AC_BASE 0x43001000 /* Analog Comparator */ +#define SAM_PTC_BASE 0x43001400 /* Peripheral Touch Controller */ +#define SAM_OPAMP_BASE 0x43001800 /* OpAmps */ +#define SAM_CCL_BASE 0x43001c00 /* Configurable Custom Logic */ + +/* AHB-APB Bridge E */ + +#define SAM_PAC_BASE 0x44000000 /* Peripheral Access Controller */ +#define SAM_DMAC_BASE 0x44000400 /* DMA Controller */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_MEMORYMAP_H */ diff --git a/arch/arm/src/samdl/chip/saml21_pinmap.h b/arch/arm/src/samdl/chip/saml21_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..40e50172eaf030fbf9886c9e96f08beca768e924 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml21_pinmap.h @@ -0,0 +1,468 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd20_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_PINMAP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_PINMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* GPIO pin definitions *********************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the SERCOM0 PAD0 on PA8, then the following definition should appear in + * the board.h header file for that board: + * + * #define PORT_SERCOM0_PAD0 PORT_SERCOM0_PAD0_1 + * + * The driver will then automatically configure PA8 as the SERCOM0 PAD0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog comparator */ + +#define PORT_AC_CMP0_1 (PORT_FUNCH | PORTA | PORT_PIN12) +#define PORT_AC_CMP0_2 (PORT_FUNCH | PORTA | PORT_PIN18) +#define PORT_AC_CMP1_1 (PORT_FUNCH | PORTA | PORT_PIN13) +#define PORT_AC_CMP1_2 (PORT_FUNCH | PORTA | PORT_PIN19) + +/* ADC voltage references */ + +#define PORT_ADC_VREFA (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_ADC_VREFB (PORT_FUNCB | PORTA | PORT_PIN4) + +#define PORT_AIN0_1 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_AIN0_2 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN1_1 (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_AIN1_2 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN2_1 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN2_2 (PORT_FUNCB | PORTB | PORT_PIN8) +#define PORT_AIN3_1 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN3_2 (PORT_FUNCB | PORTB | PORT_PIN9) +#define PORT_AIN4 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_AIN5 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_AIN6 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_AIN7 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_AIN8 (PORT_FUNCB | PORTB | PORT_PIN0) +#define PORT_AIN9 (PORT_FUNCB | PORTB | PORT_PIN1) +#define PORT_AIN10 (PORT_FUNCB | PORTB | PORT_PIN2) +#define PORT_AIN11 (PORT_FUNCB | PORTB | PORT_PIN3) +#define PORT_AIN12 (PORT_FUNCB | PORTB | PORT_PIN4) +#define PORT_AIN13 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_AIN14 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_AIN15 (PORT_FUNCB | PORTB | PORT_PIN7) +#define PORT_AIN16 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_AIN17 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_AIN18 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_AIN19 (PORT_FUNCB | PORTA | PORT_PIN11) + +/* Configurable Custom Logic */ + +#define PORT_CCL0_IN0_1 (PORT_FUNCE | PORTA | PORT_PIN4) +#define PORT_CCL0_IN0_2 (PORT_FUNCI | PORTA | PORT_PIN16) +#define PORT_CCL0_IN0_3 (PORT_FUNCI | PORTB | PORT_PIN22) +#define PORT_CCL0_IN1_1 (PORT_FUNCI | PORTA | PORT_PIN17) +#define PORT_CCL0_IN1_2 (PORT_FUNCI | PORTA | PORT_PIN5) +#define PORT_CCL0_IN1_3 (PORT_FUNCI | PORTB | PORT_PIN0) +#define PORT_CCL0_IN2_1 (PORT_FUNCI | PORTA | PORT_PIN18) +#define PORT_CCL0_IN2_2 (PORT_FUNCI | PORTA | PORT_PIN6) +#define PORT_CCL0_IN2_3 (PORT_FUNCI | PORTB | PORT_PIN1) +#define PORT_CCL0_OUT_1 (PORT_FUNCI | PORTA | PORT_PIN7) +#define PORT_CCL0_OUT_2 (PORT_FUNCI | PORTA | PORT_PIN19) +#define PORT_CCL0_OUT_3 (PORT_FUNCI | PORTB | PORT_PIN2) +#define PORT_CCL0_OUT_4 (PORT_FUNCI | PORTB | PORT_PIN23) +#define PORT_CCL1_IN0_1 (PORT_FUNCI | PORTA | PORT_PIN30) +#define PORT_CCL1_IN0_2 (PORT_FUNCI | PORTA | PORT_PIN8) +#define PORT_CCL1_IN0_3 (PORT_FUNCI | PORTB | PORT_PIN6) +#define PORT_CCL1_IN1 (PORT_FUNCI | PORTA | PORT_PIN9) +#define PORT_CCL1_IN2_1 (PORT_FUNCI | PORTA | PORT_PIN10) +#define PORT_CCL1_IN2_2 (PORT_FUNCI | PORTB | PORT_PIN10) +#define PORT_CCL1_OUT_1 (PORT_FUNCI | PORTA | PORT_PIN11) +#define PORT_CCL1_OUT_2 (PORT_FUNCI | PORTA | PORT_PIN31) +#define PORT_CCL1_OUT_3 (PORT_FUNCI | PORTB | PORT_PIN11) +#define PORT_CCL2_IN0 (PORT_FUNCI | PORTA | PORT_PIN22) +#define PORT_CCL2_IN1_1 (PORT_FUNCI | PORTA | PORT_PIN23) +#define PORT_CCL2_IN1_2 (PORT_FUNCI | PORTB | PORT_PIN7) +#define PORT_CCL2_IN1_3 (PORT_FUNCI | PORTB | PORT_PIN8) +#define PORT_CCL2_IN2 (PORT_FUNCI | PORTA | PORT_PIN24) +#define PORT_CCL2_OUT_1 (PORT_FUNCI | PORTA | PORT_PIN25) +#define PORT_CCL2_OUT_2 (PORT_FUNCI | PORTB | PORT_PIN9) +#define PORT_CCL3_IN0 (PORT_FUNCI | PORTB | PORT_PIN14) +#define PORT_CCL3_IN1 (PORT_FUNCI | PORTB | PORT_PIN15) +#define PORT_CCL3_IN2 (PORT_FUNCI | PORTB | PORT_PIN16) +#define PORT_CCL3_OUT (PORT_FUNCI | PORTB | PORT_PIN17) + +/* Cortex-M0 */ + +#define PORT_CORTEX_M0P (PORT_FUNCG | PORTA | PORT_PIN30) + +/* DAC */ + +#define PORT_DAC_VOUT0 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_DAC_VOUT1 (PORT_FUNCB | PORTA | PORT_PIN5) +#define PORT_DAC_VREFP (PORT_FUNCB | PORTA | PORT_PIN3) + +/* External interrupts */ + +#define PORT_EXTINT0_1 (PORT_FUNCA | PORTA | PORT_PIN0) +#define PORT_EXTINT0_2 (PORT_FUNCA | PORTA | PORT_PIN16) +#define PORT_EXTINT0_3 (PORT_FUNCA | PORTB | PORT_PIN0) +#define PORT_EXTINT0_4 (PORT_FUNCA | PORTB | PORT_PIN16) +#define PORT_EXTINT1_1 (PORT_FUNCA | PORTA | PORT_PIN1) +#define PORT_EXTINT1_2 (PORT_FUNCA | PORTA | PORT_PIN17) +#define PORT_EXTINT1_3 (PORT_FUNCA | PORTB | PORT_PIN1) +#define PORT_EXTINT1_4 (PORT_FUNCA | PORTB | PORT_PIN17) +#define PORT_EXTINT2_1 (PORT_FUNCA | PORTA | PORT_PIN2) +#define PORT_EXTINT2_2 (PORT_FUNCA | PORTB | PORT_PIN2) +#define PORT_EXTINT3_1 (PORT_FUNCA | PORTA | PORT_PIN3) +#define PORT_EXTINT3_2 (PORT_FUNCA | PORTB | PORT_PIN3) +#define PORT_EXTINT4_1 (PORT_FUNCA | PORTA | PORT_PIN20) +#define PORT_EXTINT4_2 (PORT_FUNCA | PORTA | PORT_PIN4) +#define PORT_EXTINT4_3 (PORT_FUNCA | PORTB | PORT_PIN4) +#define PORT_EXTINT5_1 (PORT_FUNCA | PORTA | PORT_PIN21) +#define PORT_EXTINT5_2 (PORT_FUNCA | PORTA | PORT_PIN5) +#define PORT_EXTINT5_3 (PORT_FUNCA | PORTB | PORT_PIN5) +#define PORT_EXTINT6_1 (PORT_FUNCA | PORTA | PORT_PIN22) +#define PORT_EXTINT6_2 (PORT_FUNCA | PORTA | PORT_PIN6) +#define PORT_EXTINT6_3 (PORT_FUNCA | PORTB | PORT_PIN22) +#define PORT_EXTINT6_4 (PORT_FUNCA | PORTB | PORT_PIN6) +#define PORT_EXTINT7_1 (PORT_FUNCA | PORTA | PORT_PIN7) +#define PORT_EXTINT7_2 (PORT_FUNCA | PORTA | PORT_PIN23) +#define PORT_EXTINT7_3 (PORT_FUNCA | PORTB | PORT_PIN23) +#define PORT_EXTINT7_4 (PORT_FUNCA | PORTB | PORT_PIN7) +#define PORT_EXTINT8 (PORT_FUNCA | PORTB | PORT_PIN8) +#define PORT_EXTINT9_1 (PORT_FUNCA | PORTA | PORT_PIN9) +#define PORT_EXTINT9_2 (PORT_FUNCA | PORTB | PORT_PIN9) +#define PORT_EXTINT10_1 (PORT_FUNCA | PORTA | PORT_PIN10) +#define PORT_EXTINT10_2 (PORT_FUNCA | PORTA | PORT_PIN30) +#define PORT_EXTINT10_3 (PORT_FUNCA | PORTB | PORT_PIN10) +#define PORT_EXTINT11_1 (PORT_FUNCA | PORTA | PORT_PIN11) +#define PORT_EXTINT11_2 (PORT_FUNCA | PORTA | PORT_PIN31) +#define PORT_EXTINT11_3 (PORT_FUNCA | PORTB | PORT_PIN11) +#define PORT_EXTINT12_1 (PORT_FUNCA | PORTA | PORT_PIN12) +#define PORT_EXTINT12_2 (PORT_FUNCA | PORTA | PORT_PIN18) +#define PORT_EXTINT12_3 (PORT_FUNCA | PORTA | PORT_PIN24) +#define PORT_EXTINT12_4 (PORT_FUNCA | PORTB | PORT_PIN12) +#define PORT_EXTINT13_1 (PORT_FUNCA | PORTA | PORT_PIN13) +#define PORT_EXTINT13_2 (PORT_FUNCA | PORTA | PORT_PIN19) +#define PORT_EXTINT13_3 (PORT_FUNCA | PORTA | PORT_PIN25) +#define PORT_EXTINT13_4 (PORT_FUNCA | PORTB | PORT_PIN13) +#define PORT_EXTINT14_1 (PORT_FUNCA | PORTA | PORT_PIN14) +#define PORT_EXTINT14_2 (PORT_FUNCA | PORTB | PORT_PIN14) +#define PORT_EXTINT14_3 (PORT_FUNCA | PORTB | PORT_PIN30) +#define PORT_EXTINT15_1 (PORT_FUNCA | PORTA | PORT_PIN15) +#define PORT_EXTINT15_2 (PORT_FUNCA | PORTA | PORT_PIN27) +#define PORT_EXTINT15_3 (PORT_FUNCA | PORTB | PORT_PIN15) +#define PORT_EXTINT15_4 (PORT_FUNCA | PORTB | PORT_PIN31) + +/* External wake-up for backup mode */ + +#define PORT_EXTWAKE0 (PORT_FUNCA | PORTA | PORT_PIN0) +#define PORT_EXTWAKE1 (PORT_FUNCA | PORTA | PORT_PIN1) +#define PORT_EXTWAKE2 (PORT_FUNCA | PORTA | PORT_PIN2) +#define PORT_EXTWAKE3 (PORT_FUNCA | PORTA | PORT_PIN3) +#define PORT_EXTWAKE4 (PORT_FUNCA | PORTA | PORT_PIN4) +#define PORT_EXTWAKE5 (PORT_FUNCA | PORTA | PORT_PIN5) +#define PORT_EXTWAKE6 (PORT_FUNCA | PORTA | PORT_PIN6) +#define PORT_EXTWAKE7 (PORT_FUNCA | PORTA | PORT_PIN7) + +/* Generic clock controller I/O */ + +#define PORT_GCLK_IO0_1 (PORT_FUNCH | PORTA | PORT_PIN14) +#define PORT_GCLK_IO0_2 (PORT_FUNCH | PORTA | PORT_PIN27) +#define PORT_GCLK_IO0_3 (PORT_FUNCH | PORTA | PORT_PIN30) +#define PORT_GCLK_IO0_4 (PORT_FUNCH | PORTB | PORT_PIN14) +#define PORT_GCLK_IO0_5 (PORT_FUNCH | PORTB | PORT_PIN22) +#define PORT_GCLK_IO1_1 (PORT_FUNCH | PORTA | PORT_PIN15) +#define PORT_GCLK_IO1_2 (PORT_FUNCH | PORTB | PORT_PIN15) +#define PORT_GCLK_IO1_3 (PORT_FUNCH | PORTB | PORT_PIN23) +#define PORT_GCLK_IO2_1 (PORT_FUNCH | PORTA | PORT_PIN16) +#define PORT_GCLK_IO2_2 (PORT_FUNCH | PORTB | PORT_PIN16) +#define PORT_GCLK_IO3_1 (PORT_FUNCH | PORTA | PORT_PIN17) +#define PORT_GLCK_IO3_2 (PORT_FUNCH | PORTB | PORT_PIN17) +#define PORT_GCLK_IO4_1 (PORT_FUNCH | PORTA | PORT_PIN10) +#define PORT_GCLK_IO4_2 (PORT_FUNCH | PORTA | PORT_PIN20) +#define PORT_GCLK_IO4_3 (PORT_FUNCH | PORTB | PORT_PIN10) +#define PORT_GCLK_IO5_1 (PORT_FUNCH | PORTA | PORT_PIN11) +#define PORT_GCLK_IO5_2 (PORT_FUNCH | PORTA | PORT_PIN21) +#define PORT_GCLK_IO5_3 (PORT_FUNCH | PORTB | PORT_PIN11) +#define PORT_GCLK_IO6_1 (PORT_FUNCH | PORTA | PORT_PIN22) +#define PORT_GCLK_IO6_2 (PORT_FUNCH | PORTB | PORT_PIN12) +#define PORT_GCLK_IO7_1 (PORT_FUNCH | PORTA | PORT_PIN23) +#define PORT_GCLK_IO7_2 (PORT_FUNCH | PORTB | PORT_PIN13) + +/* Non maskable interrupt */ + +#define PORT_NMI (PORT_FUNCA | PORTA | PORT_PIN8) + +/* OpAmps */ + +#define PORT_OA_NEG0 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_0A_NEG1 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_OA_NEG2 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_OA_OUT0 (PORT_FUNCB | PORTA | PORT_PIN7) +#define PORT_OA_OUT1 (PORT_FUNCB | PORTB | PORT_PIN8) +#define PORT_OA_OUT2 (PORT_FUNCB | PORTA | PORT_PIN4) +#define PORT_OA_POS0 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_OA_POS1 (PORT_FUNCB | PORTB | PORT_PIN9) +#define PORT_OA_POS2 (PORT_FUNCB | PORTA | PORT_PIN5) + +/* Serial communication interface (SERCOM) */ + +#define PORT_SERCOM0_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN8) +#define PORT_SERCOM0_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN4) +#define PORT_SERCOM0_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN9) +#define PORT_SERCOM0_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN5) +#define PORT_SERCOM0_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN10) +#define PORT_SERCOM0_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN6) +#define PORT_SERCOM0_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN11) +#define PORT_SERCOM0_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN7) +#define PORT_SERCOM1_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN16) +#define PORT_SERCOM1_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN0) +#define PORT_SERCOM1_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN17) +#define PORT_SERCOM1_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN1) +#define PORT_SERCOM1_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN18) +#define PORT_SERCOM1_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN30) +#define PORT_SERCOM1_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN19) +#define PORT_SERCOM1_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN31) +#define PORT_SERCOM2_PAD0 (PORT_FUNCC | PORTA | PORT_PIN12) +#define PORT_SERCOM2_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN13) +#define PORT_SERCOM2_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN8) +#define PORT_SERCOM2_PAD1_3 (PORT_FUNCD | PORTA | PORT_PIN9) +#define PORT_SERCOM2_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN14) +#define PORT_SERCOM2_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN10) +#define PORT_SERCOM2_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN15) +#define PORT_SERCOM2_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN11) +#define PORT_SERCOM3_PAD0_1 (PORT_FUNCC | PORTA | PORT_PIN22) +#define PORT_SERCOM3_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN16) +#define PORT_SERCOM3_PAD1_1 (PORT_FUNCC | PORTA | PORT_PIN23) +#define PORT_SERCOM3_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN17) +#define PORT_SERCOM3_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN24) +#define PORT_SERCOM3_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN18) +#define PORT_SERCOM3_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN25) +#define PORT_SERCOM3_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN19) +#define PORT_SERCOM3_PAD3_3 (PORT_FUNCD | PORTA | PORT_PIN20) +#define PORT_SERCOM3_PAD3_4 (PORT_FUNCD | PORTA | PORT_PIN21) +#define PORT_SERCOM4_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN12) +#define PORT_SERCOM4_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN12) +#define PORT_SERCOM4_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN9) +#define PORT_SERCOM4_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN13) +#define PORT_SERCOM4_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN13) +#define PORT_SERCOM4_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN8) +#define PORT_SERCOM4_PAD2_1 (PORT_FUNCC | PORTB | PORT_PIN14) +#define PORT_SERCOM4_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN14) +#define PORT_SERCOM4_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN10) +#define PORT_SERCOM4_PAD3_1 (PORT_FUNCC | PORTB | PORT_PIN15) +#define PORT_SERCOM4_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN15) +#define PORT_SERCOM4_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN11) +#define PORT_SERCOM5_PAD0_1 (PORT_FUNCC | PORTB | PORT_PIN16) +#define PORT_SERCOM5_PAD0_2 (PORT_FUNCD | PORTA | PORT_PIN22) +#define PORT_SERCOM5_PAD0_3 (PORT_FUNCD | PORTB | PORT_PIN2) +#define PORT_SERCOM5_PAD0_4 (PORT_FUNCD | PORTB | PORT_PIN30) +#define PORT_SERCOM5_PAD1_1 (PORT_FUNCC | PORTB | PORT_PIN17) +#define PORT_SERCOM5_PAD1_2 (PORT_FUNCD | PORTA | PORT_PIN23) +#define PORT_SERCOM5_PAD1_3 (PORT_FUNCD | PORTB | PORT_PIN3) +#define PORT_SERCOM5_PAD1_4 (PORT_FUNCD | PORTB | PORT_PIN31) +#define PORT_SERCOM5_PAD2_1 (PORT_FUNCC | PORTA | PORT_PIN20) +#define PORT_SERCOM5_PAD2_2 (PORT_FUNCD | PORTA | PORT_PIN24) +#define PORT_SERCOM5_PAD2_3 (PORT_FUNCD | PORTB | PORT_PIN0) +#define PORT_SERCOM5_PAD2_4 (PORT_FUNCD | PORTB | PORT_PIN22) +#define PORT_SERCOM5_PAD3_1 (PORT_FUNCC | PORTA | PORT_PIN21) +#define PORT_SERCOM5_PAD3_2 (PORT_FUNCD | PORTA | PORT_PIN25) +#define PORT_SERCOM5_PAD3_3 (PORT_FUNCD | PORTB | PORT_PIN1) +#define PORT_SERCOM5_PAD3_4 (PORT_FUNCD | PORTB | PORT_PIN23) + +/* Peripheral touch controller */ + +#define PORT_PTC_X0 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_PTC_X1 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_PTC_X2 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_PTC_X3 (PORT_FUNCB | PORTA | PORT_PIN11) +#define PORT_PTC_X4 (PORT_FUNCB | PORTA | PORT_PIN16) +#define PORT_PTC_X5 (PORT_FUNCB | PORTA | PORT_PIN17) +#define PORT_PTC_X6 (PORT_FUNCB | PORTA | PORT_PIN18) +#define PORT_PTC_X7 (PORT_FUNCB | PORTA | PORT_PIN19) +#define PORT_PTC_X8 (PORT_FUNCB | PORTA | PORT_PIN20) +#define PORT_PTC_X9 (PORT_FUNCB | PORTA | PORT_PIN21) +#define PORT_PTC_X10 (PORT_FUNCB | PORTA | PORT_PIN22) +#define PORT_PTC_X11 (PORT_FUNCB | PORTA | PORT_PIN23) +#define PORT_PTC_X12 (PORT_FUNCB | PORTB | PORT_PIN12) +#define PORT_PTC_X13 (PORT_FUNCB | PORTB | PORT_PIN13) +#define PORT_PTC_X14 (PORT_FUNCB | PORTB | PORT_PIN14) +#define PORT_PTC_X15 (PORT_FUNCB | PORTB | PORT_PIN15) +#define PORT_PTC_Y0 (PORT_FUNCB | PORTA | PORT_PIN2) +#define PORT_PTC_Y1 (PORT_FUNCB | PORTA | PORT_PIN3) +#define PORT_PTC_Y2 (PORT_FUNCB | PORTB | PORT_PIN10) +#define PORT_PTC_Y3 (PORT_FUNCB | PORTB | PORT_PIN11) +#define PORT_PTC_Y4 (PORT_FUNCB | PORTA | PORT_PIN6) +#define PORT_PTC_Y5 (PORT_FUNCB | PORTB | PORT_PIN12) +#define PORT_PTC_Y6 (PORT_FUNCB | PORTA | PORT_PIN8) +#define PORT_PTC_Y7 (PORT_FUNCB | PORTA | PORT_PIN9) +#define PORT_PTC_Y8 (PORT_FUNCB | PORTA | PORT_PIN10) +#define PORT_PTC_Y9 (PORT_FUNCB | PORTA | PORT_PIN11) +#define PORT_PTC_Y10 (PORT_FUNCB | PORTB | PORT_PIN4) +#define PORT_PTC_Y11 (PORT_FUNCB | PORTB | PORT_PIN5) +#define PORT_PTC_Y12 (PORT_FUNCB | PORTB | PORT_PIN6) +#define PORT_PTC_Y13 (PORT_FUNCB | PORTB | PORT_PIN7) +#define PORT_PTC_Y14 (PORT_FUNCB | PORTB | PORT_PIN13) +#define PORT_PTC_Y15 (PORT_FUNCB | PORTB | PORT_PIN9) + +/* Support Controller */ + +#define PORT_SUPC_OUT0 (PORT_FUNCH | PORTB | PORT_PIN1) +#define PORT_SUPC_OUT1 (PORT_FUNCH | PORTB | PORT_PIN2) +#define PORT_SUPC_PSOK (PORT_FUNCH | PORTB | PORT_PIN0) +#define PORT_SUPC_VBAT (PORT_FUNCH | PORTB | PORT_PIN3) + +/* JTAG/SWI */ + +#define PORT_SWCLK (PORT_FUNCG | PORTA | PORT_PIN30) +#define PORT_SWDIO (PORT_FUNCG | PORTA | PORT_PIN31) + +/* Timer/Counters */ + +#define PORT_TC0_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN22) +#define PORT_TC0_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN12) +#define PORT_TC0_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN8) +#define PORT_TC0_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN23) +#define PORT_TC0_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN13) +#define PORT_TC0_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN9) +#define PORT_TC1_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN24) +#define PORT_TC1_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN10) +#define PORT_TC1_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN14) +#define PORT_TC1_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN25) +#define PORT_TC1_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN11) +#define PORT_TC1_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN15) +#define PORT_TC2_WO0_1 (PORT_FUNCE | PORTB | PORT_PIN16) +#define PORT_TC2_WO0_2 (PORT_FUNCE | PORTB | PORT_PIN2) +#define PORT_TC2_WO1_1 (PORT_FUNCE | PORTB | PORT_PIN17) +#define PORT_TC2_WO1_2 (PORT_FUNCE | PORTB | PORT_PIN3) +#define PORT_TC3_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN14) +#define PORT_TC3_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN18) +#define PORT_TC3_WO0_3 (PORT_FUNCE | PORTA | PORT_PIN20) +#define PORT_TC3_WO0_4 (PORT_FUNCE | PORTB | PORT_PIN0) +#define PORT_TC3_WO0_5 (PORT_FUNCE | PORTB | PORT_PIN22) +#define PORT_TC3_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN15) +#define PORT_TC3_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN19) +#define PORT_TC3_WO1_3 (PORT_FUNCE | PORTA | PORT_PIN21) +#define PORT_TC3_WO1_4 (PORT_FUNCE | PORTB | PORT_PIN1) +#define PORT_TC3_WO1_5 (PORT_FUNCE | PORTB | PORT_PIN23) + +/* Timer/Counters Control */ + +#define PORT_TCC0_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN4) +#define PORT_TCC0_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN8) +#define PORT_TCCO_WO0_3 (PORT_FUNCE | PORTB | PORT_PIN30) +#define PORT_TCC0_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN5) +#define PORT_TCC0_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN9) +#define PORT_TCC0_WO1_3 (PORT_FUNCE | PORTB | PORT_PIN31) +#define PORT_TCC0_WO2_1 (PORT_FUNCF | PORTA | PORT_PIN10) +#define PORT_TCC0_WO2_2 (PORT_FUNCF | PORTA | PORT_PIN18) +#define PORT_TCC0_WO3_1 (PORT_FUNCF | PORTA | PORT_PIN11) +#define PORT_TCC0_WO3_2 (PORT_FUNCF | PORTA | PORT_PIN19) +#define PORT_TCC0_WO4_1 (PORT_FUNCF | PORTA | PORT_PIN14) +#define PORT_TCC0_WO4_2 (PORT_FUNCF | PORTA | PORT_PIN22) +#define PORT_TCC0_WO4_3 (PORT_FUNCF | PORTB | PORT_PIN10) +#define PORT_TCC0_WO4_4 (PORT_FUNCF | PORTB | PORT_PIN16) +#define PORT_TCC0_WO5_1 (PORT_FUNCF | PORTA | PORT_PIN15) +#define PORT_TCC0_WO5_2 (PORT_FUNCF | PORTA | PORT_PIN23) +#define PORT_TCC0_WO5_3 (PORT_FUNCF | PORTB | PORT_PIN11) +#define PORT_TCC0_WO5_4 (PORT_FUNCF | PORTB | PORT_PIN17) +#define PORT_TCC0_WO6_1 (PORT_FUNCF | PORTA | PORT_PIN12) +#define PORT_TCC0_WO6_2 (PORT_FUNCF | PORTA | PORT_PIN16) +#define PORT_TCC0_WO6_3 (PORT_FUNCF | PORTA | PORT_PIN20) +#define PORT_TCC0_WO6_4 (PORT_FUNCF | PORTB | PORT_PIN12) +#define PORT_TCC0_WO7_1 (PORT_FUNCF | PORTA | PORT_PIN13) +#define PORT_TCC0_WO7_2 (PORT_FUNCF | PORTA | PORT_PIN17) +#define PORT_TCC0_WO7_3 (PORT_FUNCF | PORTA | PORT_PIN21) +#define PORT_TCC0_WO7_4 (PORT_FUNCF | PORTB | PORT_PIN13) +#define PORT_TCC1_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN10) +#define PORT_TCC1_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN30) +#define PORT_TCC1_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN11) +#define PORT_TCC1_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN31) +#define PORT_TCC1_WO1_3 (PORT_FUNCE | PORTA | PORT_PIN6) +#define PORT_TCC1_WO1_4 (PORT_FUNCE | PORTA | PORT_PIN7) +#define PORT_TCC1_WO2_1 (PORT_FUNCF | PORTA | PORT_PIN24) +#define PORT_TCC1_WO2_2 (PORT_FUNCF | PORTA | PORT_PIN8) +#define PORT_TCC1_WO2_3 (PORT_FUNCF | PORTB | PORT_PIN30) +#define PORT_TCC1_WO3_1 (PORT_FUNCF | PORTA | PORT_PIN25) +#define PORT_TCC1_WO3_2 (PORT_FUNCF | PORTA | PORT_PIN9) +#define PORT_TCC1_WO3_3 (PORT_FUNCF | PORTB | PORT_PIN31) +#define PORT_TCC2_WO0_1 (PORT_FUNCE | PORTA | PORT_PIN0) +#define PORT_TCC2_WO0_2 (PORT_FUNCE | PORTA | PORT_PIN12) +#define PORT_TCC2_WO0_3 (PORT_FUNCE | PORTA | PORT_PIN16) +#define PORT_TCC2_WO1_1 (PORT_FUNCE | PORTA | PORT_PIN1) +#define PORT_TCC2_WO1_2 (PORT_FUNCE | PORTA | PORT_PIN13) +#define PORT_TCC2_WO1_3 (PORT_FUNCE | PORTA | PORT_PIN17) + +/* USB */ + +#define PORT_USB_DM (PORT_FUNCG | PORTA | PORT_PIN24) +#define PORT_USB_DP (PORT_FUNCG | PORTA | PORT_PIN25) +#define PORT_USB_SOF (PORT_FUNCG | PORTA | PORT_PIN23) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML21_PINMAP_H */ diff --git a/arch/arm/src/samdl/chip/saml_aes.h b/arch/arm/src/samdl/chip/saml_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..34e8150b00983583f6914640a107a7499d9d71d0 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_aes.h @@ -0,0 +1,211 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_aes.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_AES_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_AES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* AES register offsets ********************************************************************/ + +#define SAM_AES_CTRLA_OFFSET 0x0000 /* Control A Register */ +#define SAM_AES_CTRLB_OFFSET 0x0004 /* Control B Register */ +#define SAM_AES_INTENCLR_OFFSET 0x0005 /* Interrupt Enable Clear Register */ +#define SAM_AES_INTENSET_OFFSET 0x0006 /* Interrupt Enable Set Register */ +#define SAM_AES_INTENFLAG_OFFSET 0x0007 /* Interrupt Flag Status and Clear Register */ +#define SAM_AES_DATABUFPTR_OFFSET 0x0008 /* Data Buffer Pointer Register */ +#define SAM_AES_DBGCTRL_OFFSET 0x0009 /* Debug Register */ +#define SAM_AES_KEYWORD_OFFSET(n) (0x0010 + ((n) << 2)) +# define SAM_AES_KEWORD0_OFFSET 0x0010 /* Keyword 0 Register */ +# define SAM_AES_KEWORD1_OFFSET 0x0014 /* Keyword 1 Register */ +# define SAM_AES_KEWORD2_OFFSET 0x0018 /* Keyword 2 Register */ +# define SAM_AES_KEWORD3_OFFSET 0x001c /* Keyword 3 Register */ +# define SAM_AES_KEWORD4_OFFSET 0x0020 /* Keyword 4 Register */ +# define SAM_AES_KEWORD5_OFFSET 0x0024 /* Keyword 5 Register */ +# define SAM_AES_KEWORD6_OFFSET 0x0028 /* Keyword 6 Register */ +#define SAM_AES_DATA_OFFSET 0x0038 /* Data Register */ +#define SAM_AES_INTVECT_OFFSET(n) (0x003c + ((n) << 2)) +# define SAM_AES_INTVECT0_OFFSET 0x003c /* Initialization Vector 0 Register */ +# define SAM_AES_INTVECT1_OFFSET 0x0040 /* Initialization Vector 1 Register */ +# define SAM_AES_INTVECT2_OFFSET 0x0044 /* Initialization Vector 2 Register */ +# define SAM_AES_INTVECT3_OFFSET 0x0048 /* Initialization Vector 3 Register */ +#define SAM_AES_HASHKEY_OFFSET(n) (0x004c + ((n) << 2)) +# define SAM_AES_HASHKEY0_OFFSET 0x004c /* Hash Key 0 Register */ +# define SAM_AES_HASHKEY1_OFFSET 0x0050 /* Hash Key 1 Register */ +# define SAM_AES_HASHKEY2_OFFSET 0x0054 /* Hash Key 2 Register */ +# define SAM_AES_HASHKEY3_OFFSET 0x0058 /* Hash Key 3 Register */ +#define SAM_AES_GHASH_OFFSET(n) (0x005c + ((n) << 2)) +# define SAM_AES_GHASH0_OFFSET 0x005c /* Galois Hash 0 Register */ +# define SAM_AES_GHASH1_OFFSET 0x0060 /* Galois Hash 1 Register */ +# define SAM_AES_GHASH2_OFFSET 0x0064 /* Galois Hash 2 Register */ +# define SAM_AES_GHASH3_OFFSET 0x0068 /* Galois Hash 3 Register */ +#define SAM_AES_CIPLEN_OFFSET 0x0070 /* Cipher Length Register */ +#define SAM_AES_RANDSEED_OFFSET 0x0074 /* Random Seed Register */ + +/* AES register addresses ******************************************************************/ + +#define SAM_AES_CTRLA (SAM_AES_BASE+SAM_AES_CTRLA_OFFSET) +#define SAM_AES_CTRLB (SAM_AES_BASE+SAM_AES_CTRLB_OFFSET) +#define SAM_AES_INTENCLR (SAM_AES_BASE+SAM_AES_INTENCLR_OFFSET) +#define SAM_AES_INTENSET (SAM_AES_BASE+SAM_AES_INTENSET_OFFSET) +#define SAM_AES_INTENFLAG (SAM_AES_BASE+SAM_AES_INTENFLAG_OFFSET) +#define SAM_AES_DATABUFPTR (SAM_AES_BASE+SAM_AES_DATABUFPTR_OFFSET) +#define SAM_AES_DBGCTRL (SAM_AES_BASE+SAM_AES_DBGCTRL_OFFSET) +#define SAM_AES_KEYWORD(n) (SAM_AES_BASE+SAM_AES_KEYWORD_OFFSET(n)) +# define SAM_AES_KEWORD0 (SAM_AES_BASE+SAM_AES_KEWORD0_OFFSET) +# define SAM_AES_KEWORD1 (SAM_AES_BASE+SAM_AES_KEWORD1_OFFSET) +# define SAM_AES_KEWORD2 (SAM_AES_BASE+SAM_AES_KEWORD2_OFFSET) +# define SAM_AES_KEWORD3 (SAM_AES_BASE+SAM_AES_KEWORD3_OFFSET) +# define SAM_AES_KEWORD4 (SAM_AES_BASE+SAM_AES_KEWORD4_OFFSET) +# define SAM_AES_KEWORD5 (SAM_AES_BASE+SAM_AES_KEWORD5_OFFSET) +# define SAM_AES_KEWORD6 (SAM_AES_BASE+SAM_AES_KEWORD6_OFFSET) +#define SAM_AES_DATA (SAM_AES_BASE+SAM_AES_DATA_OFFSET) +#define SAM_AES_INTVECT(n) (SAM_AES_BASE+SAM_AES_INTVECT_OFFSET(n)) +# define SAM_AES_INTVECT0 (SAM_AES_BASE+SAM_AES_INTVECT0_OFFSET) +# define SAM_AES_INTVECT1 (SAM_AES_BASE+SAM_AES_INTVECT1_OFFSET) +# define SAM_AES_INTVECT2 (SAM_AES_BASE+SAM_AES_INTVECT2_OFFSET) +# define SAM_AES_INTVECT3 (SAM_AES_BASE+SAM_AES_INTVECT3_OFFSET) +#define SAM_AES_HASHKEY(n) (SAM_AES_BASE+SAM_AES_HASHKEY_OFFSET(n)) +# define SAM_AES_HASHKEY0 (SAM_AES_BASE+SAM_AES_HASHKEY0_OFFSET) +# define SAM_AES_HASHKEY1 (SAM_AES_BASE+SAM_AES_HASHKEY1_OFFSET) +# define SAM_AES_HASHKEY2 (SAM_AES_BASE+SAM_AES_HASHKEY2_OFFSET) +# define SAM_AES_HASHKEY3 (SAM_AES_BASE+SAM_AES_HASHKEY3_OFFSET) +#define SAM_AES_GHASH(n) (SAM_AES_BASE+SAM_AES_GHASH_OFFSET(n)) +# define SAM_AES_GHASH0 (SAM_AES_BASE+SAM_AES_GHASH0_OFFSET) +# define SAM_AES_GHASH1 (SAM_AES_BASE+SAM_AES_GHASH1_OFFSET) +# define SAM_AES_GHASH2 (SAM_AES_BASE+SAM_AES_GHASH2_OFFSET) +# define SAM_AES_GHASH3 (SAM_AES_BASE+SAM_AES_GHASH3_OFFSET) +#define SAM_AES_CIPLEN (SAM_AES_BASE+SAM_AES_CIPLEN_OFFSET) +#define SAM_AES_RANDSEED (SAM_AES_BASE+SAM_AES_RANDSEED_OFFSET) + +/* AES register bit definitions ************************************************************/ + +/* Control A Register */ + +#define AES_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define AES_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define AES_CTRLA_AESMODE_SHIFT (2) /* Bits 2-4: AES mode of operation */ +#define AES_CTRLA_AESMODE_MASK (7 << AES_CTRLA_AESMODE_SHIFT) +# define AES_CTRLA_AESMODE_ECB (0 << AES_CTRLA_AESMODE_SHIFT) /* Electronic code book mode */ +# define AES_CTRLA_AESMODE_CBC (1 << AES_CTRLA_AESMODE_SHIFT) /* Cipher block chaining mode */ +# define AES_CTRLA_AESMODE_OFB (2 << AES_CTRLA_AESMODE_SHIFT) /* Output feedback mode */ +# define AES_CTRLA_AESMODE_CFB (3 << AES_CTRLA_AESMODE_SHIFT) /* Cipher feedback mode */ +# define AES_CTRLA_AESMODE_CNTR (4 << AES_CTRLA_AESMODE_SHIFT) /* Counter mode */ +# define AES_CTRLA_AESMODE_CCM (5 << AES_CTRLA_AESMODE_SHIFT) /* CCM mode */ +# define AES_CTRLA_AESMODE_GCM (6 << AES_CTRLA_AESMODE_SHIFT) /* Galois counter mode */ +#define AES_CTRLA_CFBS_SHIFT (5) /* Bits 5-7: Cipher feedback block size */ +#define AES_CTRLA_CFBS_MASK (7 << AES_CTRLA_CFBS_SHIFT) +# define AES_CTRLA_CFBS_128 (0 << AES_CTRLA_CFBS_SHIFT) /* 128-bit data block */ +# define AES_CTRLA_CFBS_64 (1 << AES_CTRLA_CFBS_SHIFT) /* 64-bit data block */ +# define AES_CTRLA_CFBS_32 (2 << AES_CTRLA_CFBS_SHIFT) /* 32-bit data block */ +# define AES_CTRLA_CFBS_16 (3 << AES_CTRLA_CFBS_SHIFT) /* 16-bit data block */ +# define AES_CTRLA_CFBS_8 (4 << AES_CTRLA_CFBS_SHIFT) /* 8-bit data block */ +#define AES_CTRLA_KEYSIZE_SHIFT (8) /* Bits 8-9: Encryption key size */ +#define AES_CTRLA_KEYSIZE_MASK (3 << AES_CTRLA_KEYSIZE_SHIFT) +# define AES_CTRLA_KEYSIZE_128 (0 << AES_CTRLA_KEYSIZE_SHIFT) /* 128-bit key */ +# define AES_CTRLA_KEYSIZE_192 (1 << AES_CTRLA_KEYSIZE_SHIFT) /* 192-bit key */ +# define AES_CTRLA_KEYSIZE_256 (2 << AES_CTRLA_KEYSIZE_SHIFT) /* 256-bit key */ +#define AES_CTRLA_CIPHER (1 << 10) /* Bit 10: Cipher */ +#define AES_CTRLA_STARTMODE (1 << 11) /* Bit 11: Start mode select */ +#define AES_CTRLA_LOD (1 << 12) /* Bit 12: Last output data mode */ +#define AES_CTRLA_KEYGEN (1 << 13) /* Bit 13: Key generation */ +#define AES_CTRLA_XORKEY (1 << 14) /* Bit 14: XOR key */ +#define AES_CTRLA_CTYPE_SHIFT (16) /* Bits 16-19: Countermeasure type */ +#define AES_CTRLA_CTYPE_MASK (15 << AES_CTRLA_CTYPE_SHIFT) +# define AES_CTRLA_CTYPE_CTYPE1 (1 << AES_CTRLA_CTYPE_SHIFT) /* Countermeasure 1 enabled */ +# define AES_CTRLA_CTYPE_CTYPE2 (2 << AES_CTRLA_CTYPE_SHIFT) /* Countermeasure 2 enabled */ +# define AES_CTRLA_CTYPE_CTYPE3 (4 << AES_CTRLA_CTYPE_SHIFT) /* Countermeasure 3 enabled */ +# define AES_CTRLA_CTYPE_CTYPE4 (8 << AES_CTRLA_CTYPE_SHIFT) /* Countermeasure 4 enabled */ + +/* Control B Register */ + +#define AES_CTRLB_START (1 << 0) /* Bit 0: Start encryption/decryption */ +#define AES_CTRLB_NEWMSG (1 << 1) /* Bit 1: New message */ +#define AES_CTRLB_EOM (1 << 2) /* Bit 2: End of message */ +#define AES_CTRLB_GFMUL (1 << 3) /* Bit 3: GF multiplication */ + +/* Common Bit Definitions for the Interrupt Enable Clear Register, Interrupt Enable Set + * Register, and Interrupt Flag Status and Clear Register + */ + +#define AES_INT_ENCCMP (1 << 0) /* Bit 0: Encryption complete interrupt */ +#define AES_INT_GFMCMP (1 << 1) /* Bit 1: GF multiplication complete interrupt */ +#define AES_INT_ALL 0x03 + +/* Data Buffer Pointer Register */ + +#define AES_DATABUFPTR_MASK 0x03 /* Bits 0-1: Data pointer */ + +/* Debug Register */ + +#define AES_DBGCTRL_DBGRUN (1 << 0) /* Bit 0: Debug run */ + +/* Keyword n Register, n = 0-7 (32-value) */ +/* Data Register (32-bit value) */ +/* Initialization Vector n Register, n=0-3 (32-bit value) */ +/* Hash Key n Register, n=0-3 (32-bit value) */ +/* Galois Hash n Register, n=0-3 (32-bit value) */ +/* Cipher Length Register (32-bit vaoue) */ +/* Random Seed Register (32-bit value) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_AES_H */ diff --git a/arch/arm/src/samdl/chip/saml_dac.h b/arch/arm/src/samdl/chip/saml_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..bb4ca15020d221a5dc8edec496e52504e13585db --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_dac.h @@ -0,0 +1,179 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_dac.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DAC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DAC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* DAC register offsets ********************************************************************/ + +#define SAM_DAC_CTRLA_OFFSET 0x0000 /* Control A Register */ +#define SAM_DAC_CTRLB_OFFSET 0x0001 /* Control B Register */ +#define SAM_DAC_EVCTRL_OFFSET 0x0002 /* Event Control Register */ +#define SAM_DAC_INTENCLR_OFFSET 0x0004 /* Interrupt Enable Clear Register */ +#define SAM_DAC_INTENSET_OFFSET 0x0005 /* Interrupt Enable Set Register */ +#define SAM_DAC_INTFLAG_OFFSET 0x0006 /* Interrupt Flag Status and Clear Register */ +#define SAM_DAC_STATUS_OFFSET 0x0007 /* Status Register */ +#define SAM_DAC_SYNCBUSY_OFFSET 0x0008 /* Synchronization Busy Register */ +#define SAM_DAC_DACCTRL0_OFFSET 0x000c /* DAC0 Control Register */ +#define SAM_DAC_DACCTRL1_OFFSET 0x000e /* DAC1 Control Register */ +#define SAM_DAC_DATA0_OFFSET 0x0010 /* Data DAC0 Register */ +#define SAM_DAC_DATA1_OFFSET 0x0012 /* Data DAC1 Register */ +#define SAM_DAC_DATABUF0_OFFSET 0x0014 /* Data Buffer DAC0 Register */ +#define SAM_DAC_DATABUF1_OFFSET 0x0016 /* Data Buffer DAC1 Register */ +#define SAM_DAC_DBCTRL_OFFSET 0x0017 /* Debug Control Register */ + +/* DAC register addresses ******************************************************************/ + +#define SAM_DAC_CTRLA (SAM_DAC_BASE+SAM_DAC_CTRLA_OFFSET) +#define SAM_DAC_CTRLB (SAM_DAC_BASE+SAM_DAC_CTRLB_OFFSET) +#define SAM_DAC_EVCTRL (SAM_DAC_BASE+SAM_DAC_EVCTRL_OFFSET) +#define SAM_DAC_INTENCLR (SAM_DAC_BASE+SAM_DAC_INTENCLR_OFFSET) +#define SAM_DAC_INTENSET (SAM_DAC_BASE+SAM_DAC_INTENSET_OFFSET) +#define SAM_DAC_INTFLAG (SAM_DAC_BASE+SAM_DAC_INTFLAG_OFFSET) +#define SAM_DAC_STATUS (SAM_DAC_BASE+SAM_DAC_STATUS_OFFSET) +#define SAM_DAC_SYNCBUSY (SAM_DAC_BASE+SAM_DAC_SYNCBUSY_OFFSET) +#define SAM_DAC_DACCTRL0 (SAM_DAC_BASE+SAM_DAC_DACCTRL0_OFFSET) +#define SAM_DAC_DACCTRL1 (SAM_DAC_BASE+SAM_DAC_DACCTRL1_OFFSET) +#define SAM_DAC_DATA0 (SAM_DAC_BASE+SAM_DAC_DATA0_OFFSET) +#define SAM_DAC_DATA1 (SAM_DAC_BASE+SAM_DAC_DATA1_OFFSET) +#define SAM_DAC_DATABUF0 (SAM_DAC_BASE+SAM_DAC_DATABUF0_OFFSET) +#define SAM_DAC_DATABUF1 (SAM_DAC_BASE+SAM_DAC_DATABUF1_OFFSET) +#define SAM_DAC_DBCTRL (SAM_DAC_BASE+SAM_DAC_DBCTRL_OFFSET) + +/* DAC register bit definitions ************************************************************/ + +/* Control A Register */ + +#define DAC_CTRLA_SWRTS (1 << 0) /* Bit 0: Software reset */ +#define DAC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable DAC controller */ + +/* Control B Register */ + +#define DAC_CTRLB_DIFF (1 << 0) /* Bit 0: Differential mode enable */ +#define DAC_CTRLB_REFSEL_SHIFT (1) /* Bit 1-2: Reference selection */ +#define DAC_CTRLB_REFSEL_MASK (3 << DAC_CTRLB_REFSEL_SHIFT) +# define DAC_CTRLB_REFSEL_VREFAU (0 << DAC_CTRLB_REFSEL_SHIFT) /* Unbuffered external voltage reference */ +# define DAC_CTRLB_REFSEL_VDDANA (1 << DAC_CTRLB_REFSEL_SHIFT) /* Voltage supply */ +# define DAC_CTRLB_REFSEL_VREFAB (2 << DAC_CTRLB_REFSEL_SHIFT) /* Buffered external voltage reference */ +# define DAC_CTRLB_REFSEL_INTREF (3 << DAC_CTRLB_REFSEL_SHIFT) /* Internal bandgap reference */ + +/* Event Control Register */ + +#define DAC_EVCTRL_STARTEI0 (1 << 0) /* Bit 0: Start conversion event input DAC0 */ +#define DAC_EVCTRL_STARTEI1 (1 << 1) /* Bit 1: Start conversion event input DAC1 */ +#define DAC_EVCTRL_EMTPYEO0 (1 << 2) /* Bit 2: Data buffer empty event output DAC0 */ +#define DAC_EVCTRL_EMTPYEO1 (1 << 3) /* Bit 3: Data buffer empty event output DAC1 */ +#define DAC_EVCTRL_INVEI0 (1 << 4) /* Bit 4: Enable inversion of DAC0 input event */ +#define DAC_EVCTRL_INVEI1 (1 << 5) /* Bit 5: Enable inversion of DAC1 input event */ + +/* Common bit definitions for Interrupt Enable Clear Register, Interrupt Enable Set + * Register, and Interrupt Flag Status and Clear Register + */ + +#define DAC_INT_UNDERRUN0 (1 << 0) /* Bit 0: Underrun interrupt for DAC2 */ +#define DAC_INT_UNDERRUN1 (1 << 1) /* Bit 1: Underrun interrupt for DAC1 */ +#define DAC_INT_EMPTY0 (1 << 2) /* Bit 2: Data buffer 0 empty interrupt */ +#define DAC_INT_EMPTY1 (1 << 3) /* Bit 3: Data buffer 1 empty interrupt */ +#define DAC_INT_ALL 0x0f + +/* Status Register */ + +#define DAC_STATUS_READY0 (1 << 0) /* Bit 0: DAC0 startup ready */ +#define DAC_STATUS_READY1 (1 << 1) /* Bit 1: DAC1 startup ready */ +#define DAC_STATUS_EOC0 (1 << 2) /* Bit 2: DAC0 end of conversion */ +#define DAC_STATUS_EOC1 (1 << 3) /* Bit 3: DAC1 end of conversion */ + +/* Synchronization Busy Register */ + +#define DAC_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset */ +#define DAC_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: DAC enable status */ +#define DAC_SYNCBUSY_DATA0 (1 << 2) /* Bit 2: Data DAC0 */ +#define DAC_SYNCBUSY_DATA1 (1 << 3) /* Bit 3: Data DAC1 */ +#define DAC_SYNCBUSY_DATABUF0 (1 << 4) /* Bit 4: Data buffer DAC0 */ +#define DAC_SYNCBUSY_DATABUF1 (1 << 5) /* Bit 5: Data buffer DAC1 */ + +/* DAC0/1 Control Register */ + +#define DAC_DACCTRL_LEFTADJ (1 << 0) /* Bit 0: Left adjusted data */ +#define DAC_DACCTRL_ENABLE (1 << 1) /* Bit 1: Enable DAC */ +#define DAC_DACCTRL_CCTRL_SHIFT (2) /* Bit 2-3: Current control */ +#define DAC_DACCTRL_CCTRL_MASK (3 << DAC_DACCTRL_CCTRL_SHIFT) +# define DAC_DACCTRL_CCTRL_CC100K (0 << DAC_DACCTRL_CCTRL_SHIFT) /* GCLK_DAC <= 1.2MHz */ +# define DAC_DACCTRL_CCTRL_CC1M (1 << DAC_DACCTRL_CCTRL_SHIFT) /* 1.2MHz < GCLK_DAC <= 6MHz */ +# define DAC_DACCTRL_CCTRL_CC2M (2 << DAC_DACCTRL_CCTRL_SHIFT) /* 6MHz < GCLK_DAC <= 12MHz */ +#define DAC_DACCTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define DAC_DACCTRL_DITHER (1 << 7) /* Bit 7: Dithering mode */ +#define DAC_DACCTRL_REFRESH_SHIFT (8) /* Bit 8-11: Refresh period */ +#define DAC_DACCTRL_REFRESH_MASK (15 << DAC_DACCTRL_REFRESH_SHIFT) +# define DAC_DACCTRL_REFRESH(n) ((uin16_t)(n) << DAC_DACCTRL_REFRESH_SHIFT) + +/* Data DAC0/1 Register (16-bit data) */ +/* Data Buffer DAC0/1 Register (16-bit data) */ + +/* Debug Control Register */ + +#define DAC_DBCTRL_DBGRUN (1 << 0) /* Bit 0: Debug run */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DAC_H */ diff --git a/arch/arm/src/samdl/chip/saml_dmac.h b/arch/arm/src/samdl/chip/saml_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..191e888a7d4dddc571025d6406676c3881110f8c --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_dmac.h @@ -0,0 +1,389 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_dmac.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DMAC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DMAC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* DMAC register offsets ********************************************************************/ + +#define SAM_DMAC_CTRL_OFFSET 0x0000 /* Control Register */ +#define SAM_DMAC_CRCCTRL_OFFSET 0x0002 /* CRC Control Register */ +#define SAM_DMAC_CRCDATAIN_OFFSET 0x0004 /* CRC Data Input Register */ +#define SAM_DMAC_CRCCHKSUM_OFFSET 0x0008 /* CRC Checksum Register */ +#define SAM_DMAC_CRCSTATUS_OFFSET 0x000c /* CRC Status Register */ +#define SAM_DMAC_DBGCTRL_OFFSET 0x000d /* Debug Control Register */ +#define SAM_DMAC_QOSCTRL_OFFSET 0x000e /* Quality of Service Control Register */ +#define SAM_DMAC_SWTRIGCTRL_OFFSET 0x0010 /* Software Trigger Control Register */ +#define SAM_DMAC_PRICTRL0_OFFSET 0x0014 /* Priority Control 0 Register */ +#define SAM_DMAC_INTPEND_OFFSET 0x0020 /* Interrupt Pending Register */ +#define SAM_DMAC_INTSTATUS_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_DMAC_BUSYCH_OFFSET 0x0028 /* Busy Channels Register */ +#define SAM_DMAC_PENDCH_OFFSET 0x002c /* Pending Channels Register */ +#define SAM_DMAC_ACTIVE_OFFSET 0x0030 /* Active Channels and Levels Register */ +#define SAM_DMAC_BASEADDR_OFFSET 0x0034 /* Descriptor Memory Section Base Address Register */ +#define SAM_DMAC_WRBADDR_OFFSET 0x0038 /* Write-Back Memory Section Base Address Register */ +#define SAM_DMAC_CHID_OFFSET 0x003f /* Channel ID Register */ +#define SAM_DMAC_CHCTRLA_OFFSET 0x0040 /* Channel Control A Register */ +#define SAM_DMAC_CHCTRLB_OFFSET 0x0044 /* Channel Control B Register */ +#define SAM_DMAC_CHINTENCLR_OFFSET 0x004c /* Channel Interrupt Enable Clear Register */ +#define SAM_DMAC_CHINTENSET_OFFSET 0x004d /* Channel Interrupt Enable Set Register */ +#define SAM_DMAC_CHINTFLAG_OFFSET 0x004e /* Channel Interrupt Flag Status and Clear Register */ +#define SAM_DMAC_CHSTATUS_OFFSET 0x004f /* Channel Status Register */ + +/* LPSRAM Registers Relative to BASEADDR or WRBADDR */ + +#define SAM_LPSRAM_BTCTRL_OFFSET 0x0000 /* Block Transfer Control Register */ +#define SAM_LPSRAM_BTCNT_OFFSET 0x0002 /* Block Transfer Count Register */ +#define SAM_LPSRAM_SRCADDR_OFFSET 0x0004 /* Block Transfer Source Address Register */ +#define SAM_LPSRAM_DSTADDR_OFFSET 0x0008 /* Block Transfer Destination Address Register */ +#define SAM_LPSRAM_DESCADDR_OFFSET 0x000c /* Next Address Descriptor Register */ + +/* DMAC register addresses ******************************************************************/ + +#define SAM_DMAC_CTRL (SAM_DMAC_BASE+SAM_DMAC_CTRL_OFFSET) +#define SAM_DMAC_CRCCTRL (SAM_DMAC_BASE+SAM_DMAC_CRCCTRL_OFFSET) +#define SAM_DMAC_CRCDATAIN (SAM_DMAC_BASE+SAM_DMAC_CRCDATAIN_OFFSET) +#define SAM_DMAC_CRCCHKSUM (SAM_DMAC_BASE+SAM_DMAC_CRCCHKSUM_OFFSET) +#define SAM_DMAC_CRCSTATUS (SAM_DMAC_BASE+SAM_DMAC_CRCSTATUS_OFFSET) +#define SAM_DMAC_DBGCTRL (SAM_DMAC_BASE+SAM_DMAC_DBGCTRL_OFFSET) +#define SAM_DMAC_QOSCTRL (SAM_DMAC_BASE+SAM_DMAC_QOSCTRL_OFFSET) +#define SAM_DMAC_SWTRIGCTRL (SAM_DMAC_BASE+SAM_DMAC_SWTRIGCTRL_OFFSET) +#define SAM_DMAC_PRICTRL0 (SAM_DMAC_BASE+SAM_DMAC_PRICTRL0_OFFSET) +#define SAM_DMAC_INTPEND (SAM_DMAC_BASE+SAM_DMAC_INTPEND_OFFSET) +#define SAM_DMAC_INTSTATUS (SAM_DMAC_BASE+SAM_DMAC_INTSTATUS_OFFSET) +#define SAM_DMAC_BUSYCH (SAM_DMAC_BASE+SAM_DMAC_BUSYCH_OFFSET) +#define SAM_DMAC_PENDCH (SAM_DMAC_BASE+SAM_DMAC_PENDCH_OFFSET) +#define SAM_DMAC_ACTIVE (SAM_DMAC_BASE+SAM_DMAC_ACTIVE_OFFSET) +#define SAM_DMAC_BASEADDR (SAM_DMAC_BASE+SAM_DMAC_BASEADDR_OFFSET) +#define SAM_DMAC_WRBADDR (SAM_DMAC_BASE+SAM_DMAC_WRBADDR_OFFSET) +#define SAM_DMAC_CHID (SAM_DMAC_BASE+SAM_DMAC_CHID_OFFSET) +#define SAM_DMAC_CHCTRLA (SAM_DMAC_BASE+SAM_DMAC_CHCTRLA_OFFSET) +#define SAM_DMAC_CHCTRLB (SAM_DMAC_BASE+SAM_DMAC_CHCTRLB_OFFSET) +#define SAM_DMAC_CHINTENCLR (SAM_DMAC_BASE+SAM_DMAC_CHINTENCLR_OFFSET) +#define SAM_DMAC_CHINTENSET (SAM_DMAC_BASE+SAM_DMAC_CHINTENSET_OFFSET) +#define SAM_DMAC_CHINTFLAG (SAM_DMAC_BASE+SAM_DMAC_CHINTFLAG_OFFSET) +#define SAM_DMAC_CHSTATUS (SAM_DMAC_BASE+SAM_DMAC_CHSTATUS_OFFSET) + +/* DMAC register bit definitions ************************************************************/ + +/* Control Register */ + +#define DMAC_CTRL_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define DMAC_CTRL_DMAENABLE (1 << 1) /* Bit 1: DMA Enable */ +#define DMAC_CTRL_CRCENABLE (1 << 2) /* Bit 2: CRC Enable */ +#define DMAC_CTRL_LVLEN0 (1 << 8) /* Bit 8: Priority level 0 Enable */ +#define DMAC_CTRL_LVLEN1 (1 << 9) /* Bit 9: Priority level 1 Enable */ +#define DMAC_CTRL_LVLEN2 (1 << 10) /* Bit 10: Priority level 2 Enable */ + +/* CRC Control Register */ + +#define DMAC_CRCCTRL_CRCBEATSIZE_SHIFT (0) /* Bits 0-1: CRC beat size */ +#define DMAC_CRCCTRL_CRCBEATSIZE_MASK (3 < DMAC_CRCCTRL_CRCBEATSIZE_SHIFT) +# define DMAC_CRCCTRL_CRCBEATSIZE_BYTE (0 < DMAC_CRCCTRL_CRCBEATSIZE_SHIFT) /* 8-bit bus transfer */ +# define DMAC_CRCCTRL_CRCBEATSIZE_HWORD (1 < DMAC_CRCCTRL_CRCBEATSIZE_SHIFT) /* 16-bit bus transfer */ +# define DMAC_CRCCTRL_CRCBEATSIZE_WORD (2 < DMAC_CRCCTRL_CRCBEATSIZE_SHIFT) /* 32-bit bus transfer */ +#define DMAC_CRCCTRL_CRCPOLY_SHIFT (2) /* Bits 2-3: CRC polynomial type */ +#define DMAC_CRCCTRL_CRCPOLY_MASK (3 < DMAC_CRCCTRL_CRCPOLY_SHIFT) +# define DMAC_CRCCTRL_CRCPOLY_CRC16 (0 < DMAC_CRCCTRL_CRCPOLY_SHIFT) /* CRC-16 (CRC-CCITT) */ +# define DMAC_CRCCTRL_CRCPOLY_CRC32 (1 < DMAC_CRCCTRL_CRCPOLY_SHIFT) /* CRC32 (IEEE 802.3) */ +#define DMAC_CRCCTRL_CRCSRC_SHIFT (8) /* Bits 8-13: CRC Input Source */ +#define DMAC_CRCCTRL_CRCSRC_MASK (0x3f < DMAC_CRCCTRL_CRCSRC_SHIFT) +# define DMAC_CRCCTRL_CRCSRC_NOACTION (0 < DMAC_CRCCTRL_CRCSRC_SHIFT) /* No action */ +# define DMAC_CRCCTRL_CRCSRC_IO (1 < DMAC_CRCCTRL_CRCSRC_SHIFT) /* I/O interface */ +# define DMAC_CRCCTRL_CRCSRC_CHAN(n) (((uint32_t)(n) + 0x20) < DMAC_CRCCTRL_CRCSRC_SHIFT) + +/* CRC Data Input Register (32-bit value) */ +/* CRC Checksum Register (32-bit value) */ + +/* CRC Status Register */ + +#define DMAC_CRCSTATUS_CRCBUSY (1 << 0) /* Bit 0: CRC module busy */ +#define DMAC_CRCSTATUS_CRCZERO (1 << 1) /* Bit 1: CRC zero */ + +/* Debug Control Register */ + +#define DMAC_DBGCTRL_DBGRUN (1 << 0) /* Bit 0: Debug run */ + +/* Quality of Service Control Register */ + +#define DMAC_QOSCTRL_WRBQOS_SHIFT (0) /* Bits 0-1: Write back quality of service */ +#define DMAC_QOSCTRL_WRBQOS_MASK (3 << DMAC_QOSCTRL_WRBQOS_SHIFT) +# define DMAC_QOSCTRL_WRBQOS_DISABLE (0 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Background */ +# define DMAC_QOSCTRL_WRBQOS_LOW (1 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive bandwidth */ +# define DMAC_QOSCTRL_WRBQOS_MEDIUM (2 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive latency */ +# define DMAC_QOSCTRL_WRBQOS_HIGH (3 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Critical latency */ +#define DMAC_QOSCTRL_FQOS_SHIFT (2) /* Bits 2-3: Fetch quality of service */ +#define DMAC_QOSCTRL_FQOS_MASK (3 << DMAC_QOSCTRL_FQOS_SHIFT) +# define DMAC_QOSCTRL_FQOS_DISABLE (0 << DMAC_QOSCTRL_FQOS_SHIFT) /* Background */ +# define DMAC_QOSCTRL_FQOS_LOW (1 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive bandwidth */ +# define DMAC_QOSCTRL_FQOS_MEDIUM (2 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive latency */ +# define DMAC_QOSCTRL_FQOS_HIGH (3 << DMAC_QOSCTRL_FQOS_SHIFT) /* Critical latency */ +#define DMAC_QOSCTRL_DQOS_SHIFT (4) /* Bits 4-5: Data transfer quality of service */ +#define DMAC_QOSCTRL_DQOS_MASK (3 << DMAC_QOSCTRL_DQOS_SHIFT) +# define DMAC_QOSCTRL_DQOS_DISABLE (0 << DMAC_QOSCTRL_DQOS_SHIFT) /* Background */ +# define DMAC_QOSCTRL_DQOS_LOW (1 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive bandwidth */ +# define DMAC_QOSCTRL_DQOS_MEDIUM (2 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive latency */ +# define DMAC_QOSCTRL_DQOS_HIGH (3 << DMAC_QOSCTRL_DQOS_SHIFT) /* Critical latency */ + +/* Common bit definitions for: Software Trigger Control Register, Interrupt Status Register, + * Busy Channels Register, and Pending Channels Register + */ + +#define DMAC_CHAN(n) (1 << (n)) /* DMAC Channel n, n=0-15 */ + +/* Priority Control 0 Register */ + +#define DMAC_PRICTRL0_LVLPRI0_SHIFT (0) /* Bits 0-3: Level 0 channel priority number */ +#define DMAC_PRICTRL0_LVLPRI0_MASK (15 << DMAC_PRICTRL0_LVLPRI0_SHIFT) +# define DMAC_PRICTRL0_LVLPRI0(n) ((uint32_t)(n) << DMAC_PRICTRL0_LVLPRI0_SHIFT) +#define DMAC_PRICTRL0_RRLVLEN0 (1 << 7) /* Bit 7: Level 0 round-robin arbitrarion enable */ +#define DMAC_PRICTRL0_LVLPRI1_SHIFT (8) /* Bits 8-11: Level 1 channel priority number */ +#define DMAC_PRICTRL0_LVLPRI1_MASK (15 << DMAC_PRICTRL0_LVLPRI1_SHIFT) +# define DMAC_PRICTRL0_LVLPRI1(n) ((uint32_t)(n) << DMAC_PRICTRL0_LVLPRI1_SHIFT) +#define DMAC_PRICTRL0_RRLVLEN1 (1 << 15) /* Bit 15: Level 1 round-robin arbitrarion enable */ +#define DMAC_PRICTRL0_LVLPRI2_SHIFT (16) /* Bits 16-18: Level 2 channel priority number */ +#define DMAC_PRICTRL0_LVLPRI2_MASK (7 << DMAC_PRICTRL0_LVLPRI2_SHIFT) +# define DMAC_PRICTRL0_LVLPRI2(n) ((uint32_t)(n) << DMAC_PRICTRL0_LVLPRI2_SHIFT) +#define DMAC_PRICTRL0_RRLVLEN2 (1 << 23) /* Bit 23: Level 2 round-robin arbitrarion enable */ + +/* Interrupt Pending Register */ + +#define DMAC_INTPEND_ID_SHIFT (0) /* Bit 0-3: Channel ID */ +#define DMAC_INTPEND_ID_MASK (15 << DMAC_INTPEND_ID_SHIFT) +#define DMAC_INTPEND_TERR (1 << 8) /* Bit 8: Transfer error */ +#define DMAC_INTPEND_TCMPL (1 << 9) /* Bit 9: Transfer complete */ +#define DMAC_INTPEND_SUSP (1 << 10) /* Bit 10: Channel suspend */ +#define DMAC_INTPEND_FERR (1 << 13) /* Bit 13: Fetch error */ +#define DMAC_INTPEND_BUSY (1 << 14) /* Bit 14: Busy */ +#define DMAC_INTPEND_PEND (1 << 15) /* Bit 15: Pending */ + +/* Active Channels and Levels Register */ + +#define DMAC_ACTIVE_LVLEX0 (1 << 0) /* Bit 0: Level 0 channel trigger request executing */ +#define DMAC_ACTIVE_LVLEX1 (1 << 1) /* Bit 1: Level 1 channel trigger request executing */ +#define DMAC_ACTIVE_LVLEX2 (1 << 2) /* Bit 2: Level 2 channel trigger request executing */ +#define DMAC_ACTIVE_ID_SHIFT (8) /* Bits 8-11: Active channel ID */ +#define DMAC_ACTIVE_ID_MASK (15 << DMAC_ACTIVE_ID_SHIFT) +#define DMAC_ACTIVE_ABUSY (1 << 15) /* Bit 15: Active channel busy */ +#define DMAC_ACTIVE_BTCNT_SHIFT (16) /* Bit 16-31: Active channel block transfer count */ +#define DMAC_ACTIVE_BTCNT_MASK (0xffff << DMAC_ACTIVE_BTCNT_SHIFT) + +/* Descriptor Memory Section Base Address Register (32-bit address) */ +/* Write-Back Memory Section Base Address Register (31-bit address) */ + +/* Channel ID Register */ + +#define DMAC_CHID_MASK 0x0f /* Bits 0-3: Channel ID */ + +/* Channel Control A Register */ + +#define DMAC_CHCTRLA_SWRST (1 << 0) /* Bit 0: Channel software reset */ +#define DMAC_CHCTRLA_ENABLE (1 << 1) /* Bit 1: Channel enable */ +#define DMAC_CHCTRLA_RUNSTDBY (1 << 6) /* Bit 6: Channel run in standby */ + +/* Channel Control B Register */ + +#define DMAC_CHCTRLB_EVACT_SHIFT (0) /* Bits 0-2: Event input action */ +#define DMAC_CHCTRLB_EVACT_MASK (7 << DMAC_CHCTRLB_EVACT_SHIFT) +# define DMAC_CHCTRLB_EVACT_NOACT (0 << DMAC_CHCTRLB_EVACT_SHIFT) /* No action */ +# define DMAC_CHCTRLB_EVACT_TRIG (1 << DMAC_CHCTRLB_EVACT_SHIFT) /* Normal Transfer and Conditional Transfer on Strobe +trigger */ +# define DMAC_CHCTRLB_EVACT_CTRIG (2 << DMAC_CHCTRLB_EVACT_SHIFT) /* Conditional transfer trigger */ +# define DMAC_CHCTRLB_EVACT_CBLOCK (3 << DMAC_CHCTRLB_EVACT_SHIFT) /* Conditional block transfer */ +# define DMAC_CHCTRLB_EVACT_SUSPEND (4 << DMAC_CHCTRLB_EVACT_SHIFT) /* Channel suspend operation */ +# define DMAC_CHCTRLB_EVACT_RESUME (5 << DMAC_CHCTRLB_EVACT_SHIFT) /* Channel resume operation */ +# define DMAC_CHCTRLB_EVACT_SSKIP (6 << DMAC_CHCTRLB_EVACT_SHIFT) /* Skip next block suspend action */ +#define DMAC_CHCTRLB_EVIE (1 << 3) /* Bit 3: Channel event input enable */ +#define DMAC_CHCTRLB_EVOE (1 << 4) /* Bit 4: Channel event output enable */ +#define DMAC_CHCTRLB_LVL_SHIFT (5) /* Bits 5-6: Channel arbitration level */ +#define DMAC_CHCTRLB_LVL_MASK (3 << DMAC_CHCTRLB_LVL_SHIFT) +# define DMAC_CHCTRLB_LVL(n) ((uint32_t)(n) << DMAC_CHCTRLB_LVL_SHIFT) +# define DMAC_CHCTRLB_LVL_LVL0 (0 << DMAC_CHCTRLB_LVL_SHIFT) /* Channel priority level 0 */ +# define DMAC_CHCTRLB_LVL_LVL1 (1 << DMAC_CHCTRLB_LVL_SHIFT) /* Channel priority level 1 */ +# define DMAC_CHCTRLB_LVL_LVL2 (2 << DMAC_CHCTRLB_LVL_SHIFT) /* Channel priority level 2 */ +# define DMAC_CHCTRLB_LVL_LVL3 (3 << DMAC_CHCTRLB_LVL_SHIFT) /* Channel priority level 3 */ +#define DMAC_CHCTRLB_TRIGSRC_SHIFT (8) /* Bits 8-13: Trigger source */ +#define DMAC_CHCTRLB_TRIGSRC_MASK (0x3f << DMAC_CHCTRLB_TRIGSRC_SHIFT) + #define DMAC_CHCTRLB_TRIGSRC(n) ((uint32_t)(n) << DMAC_CHCTRLB_TRIGSRC_SHIFT) +#define DMAC_CHCTRLB_TRIGACT_SHIFT (22) /* Bits 22-23: Trigger action */ +#define DMAC_CHCTRLB_TRIGACT_MASK (3 << DMAC_CHCTRLB_TRIGACT_SHIFT) +# define DMAC_CHCTRLB_TRIGACT_BLOCK (0 << DMAC_CHCTRLB_TRIGACT_SHIFT) /* One trigger required for each action */ +# define DMAC_CHCTRLB_TRIGACT_BEAT (2 << DMAC_CHCTRLB_TRIGACT_SHIFT) /* One trigger required for beat transfer */ +# define DMAC_CHCTRLB_TRIGACT_TRANSACT (3 << DMAC_CHCTRLB_TRIGACT_SHIFT) /* One trigger required for each transaction */ +#define DMAC_CHCTRLB_CMD_SHIFT (24) /* Bits 24-25: Software command */ +#define DMAC_CHCTRLB_CMD_MASK (3 << DMAC_CHCTRLB_CMD_SHIFT) +# define DMAC_CHCTRLB_CMD_NOACTION (0 << DMAC_CHCTRLB_CMD_SHIFT) /* No action */ +# define DMAC_CHCTRLB_CMD_SUSPEND (1 << DMAC_CHCTRLB_CMD_SHIFT) /* Channel suspend operation */ +# define DMAC_CHCTRLB_CMD_RESUME (2 << DMAC_CHCTRLB_CMD_SHIFT) /* Channel resume operation */ + +/* Values for use with the DMAC_CHCTRLB_TRIGSRC(n) macro: */ + +#define DMAC_TRIGSRC_DISABLE (0) /* Only software/event triggers */ +#define DMAC_TRIGSRC_SERCOM0_RX (1) /* SERCOM0 RX Trigger */ +#define DMAC_TRIGSRC_SERCOM0_TX (2) /* SERCOM0 TX Trigger */ +#define DMAC_TRIGSRC_SERCOM1_RX (3) /* SERCOM1 RX Trigger */ +#define DMAC_TRIGSRC_SERCOM1_TX (4) /* SERCOM1 TX Trigger */ +#define DMAC_TRIGSRC_SERCOM2_RX (5) /* SERCOM2 RX Trigger */ +#define DMAC_TRIGSRC_SERCOM2_TX (6) /* SERCOM2 TX Trigger */ +#define DMAC_TRIGSRC_SERCOM3_RX (7) /* SERCOM3 RX Trigger */ +#define DMAC_TRIGSRC_SERCOM3_TX (8) /* SERCOM3 TX Trigger */ +#define DMAC_TRIGSRC_SERCOM4_RX (9) /* SERCOM4 RX Trigger */ +#define DMAC_TRIGSRC_SERCOM4_TX (10) /* SERCOM4 TX Trigger */ +#define DMAC_TRIGSRC_TCC0_OVF (11) /* TCC0 Overflow Trigger */ +#define DMAC_TRIGSRC_TCC0_MC0 (12) /* TCC0 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TCC0_MC1 (13) /* TCC0 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TCC0_MC2 (14) /* TCC0 Match/Compare 2 Trigger */ +#define DMAC_TRIGSRC_TCC0_MC3 (15) /* TCC0 Match/Compare 3 Trigger */ +#define DMAC_TRIGSRC_TCC1_OVF (16) /* TCC1 Overflow Trigger */ +#define DMAC_TRIGSRC_TCC1_MC0 (17) /* TCC1 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TCC1_MC1 (18) /* TCC1 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TCC2_OVF (19) /* TCC2 Overflow Trigger */ +#define DMAC_TRIGSRC_TCC2_MC0 (20) /* TCC2 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TCC2_MC1 (21) /* TCC2 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TC0_OVF (22) /* TC0 Overflow Trigger */ +#define DMAC_TRIGSRC_TC0_MC0 (23) /* TC0 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TC0 MC1 (24) /* TC0 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TC1_OVF (25) /* TC1 Overflow Trigger */ +#define DMAC_TRIGSRC_TC1_MC0 (26) /* TC1 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TC1_MC1 (27) /* TC1 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TC2_OVF (28) /* TC2 Overflow Trigger */ +#define DMAC_TRIGSRC_TC2_MC0 (29) /* TC2 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TC2_MC1 (30) /* TC2 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TC3_OVF (31) /* TC3 Overflow Trigger */ +#define DMAC_TRIGSRC_TC3_MC0 (32) /* TC3 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TC3_MC1 (33) /* TC3 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_TC4_OVF (34) /* TC4 Overflow Trigger */ +#define DMAC_TRIGSRC_TC4_MC0 (35) /* TC4 Match/Compare 0 Trigger */ +#define DMAC_TRIGSRC_TC4_MC1 (36) /* TC4 Match/Compare 1 Trigger */ +#define DMAC_TRIGSRC_ADC_RESRDY (37) /* ADC Result Ready Trigger */ +#define DMAC_TRIGSRC_DAC0_EMPTY (38) /* DAC0 Empty Trigger */ +#define DMAC_TRIGSRC_DAC1_EMPTY (39) /* DAC1 Empty Trigger */ +#define DMAC_TRIGSRC_AES_WR (44) /* AES Write Trigger */ +#define DMAC_TRIGSRC_AES_RD (45) /* AES Read Trigger */ + +/* Common register bit definitions: Channel Interrupt Enable Clear Register, Channel Interrupt + * Enable Set Register, and Channel Interrupt Flag Status and Clear Register + */ + +#define DMAC_INT_TERR (1 << 0) /* Bit 0: Transfer error interrupt */ +#define DMAC_INT_TCMPL (1 << 1) /* Bit 1: Channel transfer complete interrupt */ +#define DMAC_INT_SUSP (1 << 2) /* Bit 2: Channel suspend interrupt */ +#define DMAC_INT_ALL (0x07) + +/* Channel Status Register */ + +#define DMAC_CHSTATUS_PEND (1 << 0) /* Bit 0: Chennel pending */ +#define DMAC_CHSTATUS_BUSY (1 << 1) /* Bit 1: Channel busy */ +#define DMAC_CHSTATUS_FERR (1 << 2) /* Bit 2: Channel fetch error */ + +/* Block Transfer Control Register */ + +#define LPSRAM_BTCTRL_VALID (1 << 0) /* Bit 0: Descriptor valid */ +#define LPSRAM_BTCTRL_EVOSEL_SHIFT (1) /* Bits 1-2: Event output selection */ +#define LPSRAM_BTCTRL_EVOSEL_MASK (3 << LPSRAM_BTCTRL_EVOSEL_SHIFT) +# define LPSRAM_BTCTRL_EVOSEL_DISABLE (0 << LPSRAM_BTCTRL_EVOSEL_SHIFT) /* Event generation disabled */ +# define LPSRAM_BTCTRL_EVOSEL_BLOCK (1 << LPSRAM_BTCTRL_EVOSEL_SHIFT) /* Event strobe when block transfer complete */ +# define LPSRAM_BTCTRL_EVOSEL_BEAT (3 << LPSRAM_BTCTRL_EVOSEL_SHIFT) /* Event strobe when beat transfer complete */ +#define LPSRAM_BTCTRL_BLOCKACT_SHIFT (3) /* Bits 3-4: Block action */ +#define LPSRAM_BTCTRL_BLOCKACT_MASK (3 << LPSRAM_BTCTRL_BLOCKACT_SHIFT) +# define LPSRAM_BTCTRL_BLOCKACT_NOACT (0 << LPSRAM_BTCTRL_BLOCKACT_SHIFT) /* Channel disabled if last block transfer */ +# define LPSRAM_BTCTRL_BLOCKACT_INT (1 << LPSRAM_BTCTRL_BLOCKACT_SHIFT) /* Channel disabled if last block transfer + block int */ +# define LPSRAM_BTCTRL_BLOCKACT_SUSPEND (2 << LPSRAM_BTCTRL_BLOCKACT_SHIFT) /* Channel suspend operation is completed */ +# define LPSRAM_BTCTRL_BLOCKACT_BOTH (3 << LPSRAM_BTCTRL_BLOCKACT_SHIFT) /* Both channel suspend operation + block int */ +#define LPSRAM_BTCTRL_BEATSIZE_SHIFT (8) /* Bits 8-9: Beat size */ +#define LPSRAM_BTCTRL_BEATSIZE_MASK (3 << LPSRAM_BTCTRL_BEATSIZE_SHIFT) +# define LPSRAM_BTCTRL_BEATSIZE_BYTE (0 << LPSRAM_BTCTRL_BEATSIZE_SHIFT) /* 8-bit bus transfer */ +# define LPSRAM_BTCTRL_BEATSIZE_HWORD (1 << LPSRAM_BTCTRL_BEATSIZE_SHIFT) /* 16-bit bus transfer */ +# define LPSRAM_BTCTRL_BEATSIZE_WORD (2 << LPSRAM_BTCTRL_BEATSIZE_SHIFT) /* 32-bit bus transfer */ +#define LPSRAM_BTCTRL_SRCINC (1 << 10) /* Bit 10: Source address increment enable */ +#define LPSRAM_BTCTRL_DSTINC (1 << 11) /* Bit 11: Destination address increment enable */ +#define LPSRAM_BTCTRL_STEPSEL (1 << 12) /* Bit 12: Step selection */ +#define LPSRAM_BTCTRL_STEPSIZE_SHIFT (13) /* Bits 13-15: Address increment step */ +#define LPSRAM_BTCTRL_STEPSIZE_MASK (7 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) +# define LPSRAM_BTCTRL_STEPSIZE_X1 (0 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 1 */ +# define LPSRAM_BTCTRL_STEPSIZE_X2 (1 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 2 */ +# define LPSRAM_BTCTRL_STEPSIZE_X4 (2 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 4 */ +# define LPSRAM_BTCTRL_STEPSIZE_X8 (3 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 8 */ +# define LPSRAM_BTCTRL_STEPSIZE_X16 (4 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 16 */ +# define LPSRAM_BTCTRL_STEPSIZE_X32 (5 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 32 */ +# define LPSRAM_BTCTRL_STEPSIZE_X64 (6 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 64 */ +# define LPSRAM_BTCTRL_STEPSIZE_X128 (7 << LPSRAM_BTCTRL_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 128 */ + +/* Block Transfer Count Register (16-bit count) */ +/* Block Transfer Source Address Register (32-bit address) */ +/* Block Transfer Destination Address Register (32-bit address) */ +/* Next Address Descriptor Register (32-bit address) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ +/* DMA descriptor */ + +struct dma_desc_s +{ + uint16_t btctrl; /* Block Transfer Control Register */ + uint16_t btcnt; /* Block Transfer Count Register */ + uint32_t srcaddr; /* Block Transfer Source Address Register */ + uint32_t dstaddr; /* Block Transfer Destination Address Register */ + uint32_t descaddr; /* Next Address Descriptor Register */ +}; + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_DMAC_H */ diff --git a/arch/arm/src/samdl/chip/saml_eic.h b/arch/arm/src/samdl/chip/saml_eic.h new file mode 100644 index 0000000000000000000000000000000000000000..e6bb167e2ebd022381815e5a4d44edd597f57f4e --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_eic.h @@ -0,0 +1,207 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_eic.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EIC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EIC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* EIC register offsets *********************************************************************/ + +#define SAM_EIC_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_EIC_NVMICTRL_OFFSET 0x0001 /* Non-maskable interrupt control register */ +#define SAM_EIC_NMIFLAG_OFFSET 0x0002 /* Non-maskable interrupt flasg status and clear register */ +#define SAM_EIC_SYNCBUSY_OFFSET 0x0004 /* Synchronization busy register */ +#define SAM_EIC_EVCTRL_OFFSET 0x0008 /* Event control register */ +#define SAM_EIC_INTENCLR_OFFSET 0x000c /* Interrupt enable clear register */ +#define SAM_EIC_INTENSET_OFFSET 0x0010 /* Interrupt enable set register */ +#define SAM_EIC_INTFLAG_OFFSET 0x0014 /* Interrupt flag and status clear register */ +#define SAM_EIC_ASYNCH_OFFSET 0x0018 /* External interrupt asynchronous mode register */ +#define SAM_EIC_CONFIG0_OFFSET 0x001c /* Configuration 0 register */ +#define SAM_EIC_CONFIG1_OFFSET 0x0020 /* Configuration 1 register */ +#define SAM_EIC_CONFIG2_OFFSET 0x0024 /* Configuration 2 register */ +#define SAM_EIC_CONFIG3_OFFSET 0x0028 /* Configuration 3 register */ + +/* EIC register addresses *******************************************************************/ + +#define SAM_EIC_CTRLA (SAM_EIC_BASE+SAM_EIC_CTRLA_OFFSET) +#define SAM_EIC_NVMICTRL (SAM_EIC_BASE+SAM_EIC_NVMICTRL_OFFSET) +#define SAM_EIC_NMIFLAG (SAM_EIC_BASE+SAM_EIC_NMIFLAG_OFFSET) +#define SAM_EIC_SYNCBUSY (SAM_EIC_BASE+SAM_EIC_SYNCBUSY_OFFSET) +#define SAM_EIC_EVCTRL (SAM_EIC_BASE+SAM_EIC_EVCTRL_OFFSET) +#define SAM_EIC_INTENCLR (SAM_EIC_BASE+SAM_EIC_INTENCLR_OFFSET) +#define SAM_EIC_INTENSET (SAM_EIC_BASE+SAM_EIC_INTENSET_OFFSET) +#define SAM_EIC_INTFLAG (SAM_EIC_BASE+SAM_EIC_INTFLAG_OFFSET) +#define SAM_EIC_ASYNCH (SAM_EIC_BASE+SAM_EIC_ASYNCH_OFFSET) +#define SAM_EIC_CONFIG0 (SAM_EIC_BASE+SAM_EIC_CONFIG0_OFFSET) +#define SAM_EIC_CONFIG1 (SAM_EIC_BASE+SAM_EIC_CONFIG1_OFFSET) +#define SAM_EIC_CONFIG2 (SAM_EIC_BASE+SAM_EIC_CONFIG2_OFFSET) +#define SAM_EIC_CONFIG3 (SAM_EIC_BASE+SAM_EIC_CONFIG3_OFFSET) + +/* EIC register bit definitions *************************************************************/ + +/* Control A register */ + +#define EIC_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define EIC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define EIC_CTRLA_CKSEL (1 << 2) /* Bit 2: Clock selection */ +# define EIC_CTRLA_CKSEL_GCLK_EIC (0) /* 0=EIC clocked by GCLK_EIC */ +# define EIC_CTRLA_CKSEL_CLK_ULP32K EIC_CTRLA_CKSEL /* 1=EIC clocked by CLK_ULP32K */ + +/* Non-maskable interrupt control register */ + +#define EIC_NVMICTRL_NMISENSE_SHIFT (0) /* Bits 0-2: Non-maskable interrupt sense */ +#define EIC_NVMICTRL_NMISENSE_MASK (7 << EIC_NVMICTRL_NMISENSE_SHIFT) +# define EIC_NVMICTRL_NMISENSE_NONE (0 << EIC_NVMICTRL_NMISENSE_SHIFT) /* No detection */ +# define EIC_NVMICTRL_NMISENSE_RISE (1 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Rising edge detection */ +# define EIC_NVMICTRL_NMISENSE_FALL (2 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Falling edge detection */ +# define EIC_NVMICTRL_NMISENSE_BOTH (3 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Both edge detection */ +# define EIC_NVMICTRL_NMISENSE_HIGH (4 << EIC_NVMICTRL_NMISENSE_SHIFT) /* High level detection */ +# define EIC_NVMICTRL_NMISENSE_LOW (5 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Low level detection */ +#define EIC_NVMICTRL_NMIFLTEN (1 << 3) /* Bit 3: Non-maskable interrupt filter enable */ +#define EIC_NVMICTRL_ASYNC (1 << 4) /* Bit 4: Asynchronous edge detection mode */ + +/* Non-maskable interrupt flas status and clear register */ + +#define EIC_NMIFLAG_NMI (1 << 0) /* Non-maskable interrupt */ + +/* Synchronization busy register */ + +#define EIC_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset syncrhonization busy */ +#define EIC_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: Enable syncrhonization busy */ + +/* Event control, Interrupt enable clear, interrupt enable set register, interrupt flag + * status and clear, and External interrupt asynchronous mode registers. + */ + +#define EIC_EXTINT_SHIFT (0) /* Bits 0-15: External interrupt n */ +#define EIC_EXTINT_MASK (0xffff << EIC_EXTINT_SHIFT) +# define EIC_EXTINT(n) ((uint32_t)(n) << EIC_EXTINT_SHIFT) +# define EIC_EXTINT_0 (1 << 0) /* Bit 0: External interrupt 0 */ +# define EIC_EXTINT_1 (1 << 1) /* Bit 1: External interrupt 1 */ +# define EIC_EXTINT_2 (1 << 2) /* Bit 2: External interrupt 2 */ +# define EIC_EXTINT_3 (1 << 3) /* Bit 3: External interrupt 3 */ +# define EIC_EXTINT_4 (1 << 4) /* Bit 4: External interrupt 4 */ +# define EIC_EXTINT_5 (1 << 5) /* Bit 5: External interrupt 5 */ +# define EIC_EXTINT_6 (1 << 6) /* Bit 6: External interrupt 6 */ +# define EIC_EXTINT_7 (1 << 7) /* Bit 7: External interrupt 7 */ +# define EIC_EXTINT_8 (1 << 8) /* Bit 8: External interrupt 8 */ +# define EIC_EXTINT_9 (1 << 9) /* Bit 9: External interrupt 9 */ +# define EIC_EXTINT_10 (1 << 10) /* Bit 10: External interrupt 10 */ +# define EIC_EXTINT_11 (1 << 11) /* Bit 11: External interrupt 11 */ +# define EIC_EXTINT_12 (1 << 12) /* Bit 12: External interrupt 12 */ +# define EIC_EXTINT_13 (1 << 13) /* Bit 13: External interrupt 13 */ +# define EIC_EXTINT_14 (1 << 14) /* Bit 14: External interrupt 14 */ +# define EIC_EXTINT_15 (1 << 15) /* Bit 15: External interrupt 15 */ + +#define EIC_EXTINT_ALL EIC_EXTINT_MASK + +/* Configuration 0 register */ + +#define EIC_CONFIG0_FILTEN(n) (3 + ((n) << 2)) /* Filter n enable, n=0-7 */ +#define EIC_CONFIG0_SENSE_SHIFT(n) ((n) << 2) /* Filter n input sense, n=0-7 */ +#define EIC_CONFIG0_SENSE_MASK(n) (7 << EIC_CONFIG0_SENSE_SHIFT(n)) +# define EIC_CONFIG0_SENSE_NONE (0 << EIC_CONFIG0_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG0_SENSE_RISE (1 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG0_SENSE_FALL (2 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG0_SENSE_BOTH (3 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG0_SENSE_HIGH (4 << EIC_CONFIG0_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG0_SENSE_LOW (5 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Low level detection */ + +/* Configuration 1 register */ + +#define EIC_CONFIG1_FILTEN(n) (3 + (((n) - 8) << 2)) /* Filter n enable, n=8-15 */ +#define EIC_CONFIG1_SENSE_SHIFT(n) (((n) - 8) << 2) /* Filter n input sense, n=8-17 */ +#define EIC_CONFIG1_SENSE_MASK(n) (7 << EIC_CONFIG1_SENSE_SHIFT(n)) +# define EIC_CONFIG1_SENSE_NONE (0 << EIC_CONFIG1_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG1_SENSE_RISE (1 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG1_SENSE_FALL (2 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG1_SENSE_BOTH (3 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG1_SENSE_HIGH (4 << EIC_CONFIG1_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG1_SENSE_LOW (5 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Low level detection */ + +/* Configuration 2 register */ + +#define EIC_CONFIG2_FILTEN(n) (3 + (((n) - 16) << 2)) /* Filter n enable, n=16-23 */ +#define EIC_CONFIG2_SENSE_SHIFT(n) (((n) - 16) << 2) /* Filter n input sense, n=16-23 */ +#define EIC_CONFIG2_SENSE_MASK(n) (7 << EIC_CONFIG2_SENSE_SHIFT(n)) +# define EIC_CONFIG2_SENSE_NONE (0 << EIC_CONFIG2_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG2_SENSE_RISE (1 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG2_SENSE_FALL (2 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG2_SENSE_BOTH (3 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG2_SENSE_HIGH (4 << EIC_CONFIG2_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG2_SENSE_LOW (5 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Low level detection */ + +/* Configuration 3 register */ + +#define EIC_CONFIG3_FILTEN(n) (3 + (((n) - 24) << 2)) /* Filter n enable, n=24-31 */ +#define EIC_CONFIG3_SENSE_SHIFT(n) (((n) - 24) << 2) /* Filter n input sense, n=24-31 */ +#define EIC_CONFIG3_SENSE_MASK(n) (7 << EIC_CONFIG3_SENSE_SHIFT(n)) +# define EIC_CONFIG3_SENSE_NONE (0 << EIC_CONFIG3_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG3_SENSE_RISE (1 << EIC_CONFIG3_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG3_SENSE_FALL (2 << EIC_CONFIG3_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG3_SENSE_BOTH (3 << EIC_CONFIG3_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG3_SENSE_HIGH (4 << EIC_CONFIG3_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG3_SENSE_LOW (5 << EIC_CONFIG3_SENSE_SHIFT(n)) /* Low level detection */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EIC_H */ diff --git a/arch/arm/src/samdl/chip/saml_evsys.h b/arch/arm/src/samdl/chip/saml_evsys.h new file mode 100644 index 0000000000000000000000000000000000000000..06eb014ea92495a409bb8ebeffff038b398c92b6 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_evsys.h @@ -0,0 +1,262 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_evsys.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EVSYS_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EVSYS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* EVSYS register offsets *******************************************************************/ + +#define SAM_EVSYS_CTRLA_OFFSET 0x0000 /* Control register */ +#define SAM_EVSYS_CHSTATUS_OFFSET 0x000c /* Channel status register */ +#define SAM_EVSYS_INTENCLR_OFFSET 0x0010 /* Interrupt enable clear register */ +#define SAM_EVSYS_INTENSET_OFFSET 0x0014 /* Interrupt enable set register */ +#define SAM_EVSYS_INTFLAG_OFFSET 0x0018 /* Interrupt flag status and clear register */ +#define SAM_EVSYS_SWEVT_OFFSET 0x001c /* Event user */ +#define SAM_EVSYS_CHANNEL_OFFSET(n) (0x0020 + ((n) << 2)) /* Channel registers */ +#define SAM_EVSYS_USER_OFFSET(n) (0x0080 + ((m) << 2)) /* User registers */ + +/* EVSYS register addresses *****************************************************************/ + +#define SAM_EVSYS_CTRLA (SAM_EVSYS_BASE+SAM_EVSYS_CTRLA_OFFSET) +#define SAM_EVSYS_CHSTATUS (SAM_EVSYS_BASE+SAM_EVSYS_CHSTATUS_OFFSET +#define SAM_EVSYS_INTENCLR (SAM_EVSYS_BASE+SAM_EVSYS_INTENCLR_OFFSET +#define SAM_EVSYS_INTENSET (SAM_EVSYS_BASE+SAM_EVSYS_INTENSET_OFFSET +#define SAM_EVSYS_INTFLAG (SAM_EVSYS_BASE+SAM_EVSYS_INTFLAG_OFFSET) +#define SAM_EVSYS_SWEVT (SAM_EVSYS_BASE+SAM_EVSYS_SWEVT_OFFSET) +#define SAM_EVSYS_CHANNEL_OFFSET(n) (0x0020 + ((n) << 2)) /* Channel registers */ +#define SAM_EVSYS_CHANNEL_OFFSET(n) (0x0020 + ((n) << 2)) /* Channel registers */ +#define SAM_EVSYS_USER_OFFSET(n) (0x0080 + ((m) << 2)) /* User registers */ +#define SAM_EVSYS_USER_OFFSET(n) (0x0080 + ((m) << 2)) /* User registers */ + +/* EVSYS register bit definitions ***********************************************************/ + +/* Control register */ + +#define EVSYS_CTRLA_SWRST (1 << 0) /* Bit 0: Software Reset */ + +/* Channel status register */ + +#define EVSYS_CHSTATUS_USRRDY_SHIFT (0) /* Bits 0-7: User Ready for Channel n, n=0-11 */ +#define EVSYS_CHSTATUS_USRRDY_MASK (0xfff << EVSYS_CHSTATUS_USRRDY_SHIFT) +# define EVSYS_CHSTATUS_USRRDY(n) ((uint32_t)(n) << EVSYS_CHSTATUS_USRRDY_SHIFT) +#define EVSYS_CHSTATUS_CHBUSY_SHIFT (8) /* Bits 8-15: Channel Busy n, n=0-11 */ +#define EVSYS_CHSTATUS_CHBUSY_MASK (0xfff << EVSYS_CHSTATUS_CHBUSY_SHIFT) +# define EVSYS_CHSTATUS_CHBUSY(n) ((uint32_t)(n) << EVSYS_CHSTATUS_CHBUSY_SHIFT) + +/* Interrupt enable clear, interrupt enable set, and interrupt flag status and clear registers */ + +#define EVSYS_INT_OVR_SHIFT (0) /* Bits 0-7: Overrun channel n interrupt, n= 0-11 */ +#define EVSYS_INT_OVR_MASK (0xfff << EVSYS_INT_OVR_SHIFT) +# define EVSYS_INT_OVR(n) (1 << (n)) +#define EVSYS_INT_EVD_SHIFT (8) /* Bits 8-15: Event detected channel n interrupt */ +#define EVSYS_INT_EVD_MASK (0xff << EVSYS_INT_EVD_SHIFT) +# define EVSYS_INT_EVD(n) (1 << ((n)+8)) + +/* Event user register */ + +#define EVSYS_SWEVT_CHANNEL_SHIFT (0)) /* Bits 0-11: Channel n software selection, n=0-11 */ +#define EVSYS_SWEVT_CHANNEL_MASK (0xfff << EVSYS_SWEVT_CHANNEL_SHIFT) +# define EVSYS_SWEVT_CHANNEL(n) (1 << (n)) + +/* Channel registers */ + +#define EVSYS_CHANNEL_EVGEN_SHIFT (0) /* Bits 0-6: Event generator */ +#define EVSYS_CHANNEL_EVGEN_MASK (0x7f << EVSYS_CHANNEL_EVGEN_SHIFT) +# define EVSYS_CHANNEL_EVGEN_NONE (0x00 << EVSYS_CHANNEL_EVGEN_SHIFT) /* No event generator selected */ +# define EVSYS_CHANNEL_EVGEN_RTC_CMP0 (0x01 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Compare 0 or alarm 0 */ +# define EVSYS_CHANNEL_EVGEN_RTC_CMP1 (0x02 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Compare 1 */ +# define EVSYS_CHANNEL_EVGEN_RTC_OVF (0x03 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Overflow */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER0 (0x04 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 0 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER1 (0x05 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 1 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER2 (0x06 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 2 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER3 (0x07 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 3 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER4 (0x08 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 4 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER5 (0x09 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 5 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER6 (0x0a << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 6 */ +# define EVSYS_CHANNEL_EVGEN_RTC_PER7 (0x0b << EVSYS_CHANNEL_EVGEN_SHIFT) /* Period 7 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT0 (0x0c << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 0 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT1 (0x0d << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 1 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT2 (0x0e << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 2 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT3 (0x0f << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 3 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT4 (0x10 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 4 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT5 (0x11 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 5 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT6 (0x12 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 6 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT7 (0x13 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 7 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT8 (0x14 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 8 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT9 (0x15 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 9 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT10 (0x16 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 10 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT11 (0x17 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 11 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT12 (0x18 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 12 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT13 (0x19 << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 13 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT14 (0x1a << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 14 */ +# define EVSYS_CHANNEL_EVGEN_EIC_EXTINT15 (0x1b << EVSYS_CHANNEL_EVGEN_SHIFT) /* External interrupt 15 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH0 (0x1c << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 0 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH1 (0x1d << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 1 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH2 (0x1e << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 2 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH3 (0x1f << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 3 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH4 (0x20 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 4 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH5 (0x21 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 5 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH6 (0x22 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 6 */ +# define EVSYS_CHANNEL_EVGEN_DMAC_CH7 (0x23 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DMA channel 7 */ +# define EVSYS_CHANNEL_EVGEN_TCCO_OVF (0x24 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 overflow */ +# define EVSYS_CHANNEL_EVGEN_TCCO_TRG (0x25 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 trigger */ +# define EVSYS_CHANNEL_EVGEN_TCCO_CNT (0x26 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 counter */ +# define EVSYS_CHANNEL_EVGEN_TCCO_MCX0 (0x27 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCCO_MCX1 (0x28 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TCCO_MCX2 (0x29 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 match/capture 2 */ +# define EVSYS_CHANNEL_EVGEN_TCCO_MCX3 (0x2a << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC0 match/capture 2 */ +# define EVSYS_CHANNEL_EVGEN_TCC1_OVF (0x2b << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 overflow */ +# define EVSYS_CHANNEL_EVGEN_TCC1_TRG (0x2c << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 trigger */ +# define EVSYS_CHANNEL_EVGEN_TCC1_CNT (0x2d << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 counter */ +# define EVSYS_CHANNEL_EVGEN_TCC1_MCX0 (0x2e << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC01match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCC1_MCX1 (0x2f << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC1 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TCC2_OVF (0x30 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 overflow */ +# define EVSYS_CHANNEL_EVGEN_TCC2_TRG (0x31 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 trigger */ +# define EVSYS_CHANNEL_EVGEN_TCC2_CNT (0x32 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 counter */ +# define EVSYS_CHANNEL_EVGEN_TCC2_MCX0 (0x33 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TCC2_MCX1 (0x34 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCC2 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC0_OVF (0x35 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TCO Overflow */ +# define EVSYS_CHANNEL_EVGEN_TC0_MC0 (0x36 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC0 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC0_MC1 (0x37 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC0 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC1_OVF (0x38 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TC1_MC0 (0x39 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC1_MC1 (0x3a << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC1 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC2_OVF (0x3b << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TC2_MC0 (0x3c << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 match/captue 0 */ +# define EVSYS_CHANNEL_EVGEN_TC2_MC1 (0x3d << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC2 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC3_OVF (0x3e << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TC3_MC0 (0x3f << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC3_MC1 (0x40 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC3 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_TC4_OVF (0x41 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 Overflow */ +# define EVSYS_CHANNEL_EVGEN_TC4_MC0 (0x42 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 match/capture 0 */ +# define EVSYS_CHANNEL_EVGEN_TC4_MC1 (0x43 << EVSYS_CHANNEL_EVGEN_SHIFT) /* TC4 match/capture 1 */ +# define EVSYS_CHANNEL_EVGEN_ADC_RESRDY (0x44 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC result ready */ +# define EVSYS_CHANNEL_EVGEN_ADC_WINMON (0x45 << EVSYS_CHANNEL_EVGEN_SHIFT) /* ADC window monitor */ +# define EVSYS_CHANNEL_EVGEN_AC_COMP0 (0x46 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Analog comparator 0 */ +# define EVSYS_CHANNEL_EVGEN_AC_COMP1 (0x47 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Analog comparator 1 */ +# define EVSYS_CHANNEL_EVGEN_AC_WIN0 (0x48 << EVSYS_CHANNEL_EVGEN_SHIFT) /* Analog window comparator */ +# define EVSYS_CHANNEL_EVGEN_DAC_EMPTY0 (0x49 << EVSYS_CHANNEL_EVGEN_SHIFT) /* DAC data buffer 0 empty */ +# define EVSYS_CHANNEL_EVGEN_DAC_EMPTY1 (0x4a << EVSYS_CHANNEL_EVGEN_SHIFT) /* DAC data buffer 1 empty */ +# define EVSYS_CHANNEL_EVGEN_PTC_EOC (0x4b << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC end of conversion */ +# define EVSYS_CHANNEL_EVGEN_PTC_WCOMPT (0x4c << EVSYS_CHANNEL_EVGEN_SHIFT) /* PTC window comparator */ +# define EVSYS_CHANNEL_EVGEN_TRNG_READY (0x4d << EVSYS_CHANNEL_EVGEN_SHIFT) /* TRNG data ready */ +# define EVSYS_CHANNEL_EVGEN_CCL_LUTOUT0 (0x4e << EVSYS_CHANNEL_EVGEN_SHIFT) /* CCL output 0 */ +# define EVSYS_CHANNEL_EVGEN_CCL_LUTOUT1 (0x4f << EVSYS_CHANNEL_EVGEN_SHIFT) /* CCL output 1 */ +# define EVSYS_CHANNEL_EVGEN_CCL_LUTOUT2 (0x50 << EVSYS_CHANNEL_EVGEN_SHIFT) /* CCL output 2 */ +# define EVSYS_CHANNEL_EVGEN_CCL_LUTOUT3 (0x51 << EVSYS_CHANNEL_EVGEN_SHIFT) /* CCL output 3 */ +# define EVSYS_CHANNEL_EVGEN_PAC_ACCERR (0x52 << EVSYS_CHANNEL_EVGEN_SHIFT) /* PAC access error */ +#define EVSYS_CHANNEL_PATH_SHIFT (8) /* Bits 8-9: Path selection */ +#define EVSYS_CHANNEL_PATH_MASK (3 << EVSYS_CHANNEL_PATH_SHIFT) +# define EVSYS_CHANNEL_PATH_SYNCH (0 << EVSYS_CHANNEL_PATH_SHIFT) /* Synchronized path */ +# define EVSYS_CHANNEL_PATH_RESYNCH (1 << EVSYS_CHANNEL_PATH_SHIFT) /* Resynchronized path */ +# define EVSYS_CHANNEL_PATH_ASYNCH (2 << EVSYS_CHANNEL_PATH_SHIFT) /* Asynchronous path */ +#define EVSYS_CHANNEL_EDGESEL_SHIFT (10) /* Bits 10-11: Edge dection selection */ +#define EVSYS_CHANNEL_EDGESEL_MASK (3 << EVSYS_CHANNEL_EDGESEL_SHIFT) +# define EVSYS_CHANNEL_EDGESEL_NONE (0 << EVSYS_CHANNEL_EDGESEL_SHIFT) /* No event output */ +# define EVSYS_CHANNEL_EDGESEL_RISING (1 << EVSYS_CHANNEL_EDGESEL_SHIFT) /* Detect on rising edge */ +# define EVSYS_CHANNEL_EDGESEL_FALLING (2 << EVSYS_CHANNEL_EDGESEL_SHIFT) /* Detect on falling edge */ +# define EVSYS_CHANNEL_EDGESEL_BOTH (3 << EVSYS_CHANNEL_EDGESEL_SHIFT) /* Detect on both edges */ +#define EVSYS_CHANNEL_RUNSTDBY (1 << 14) /* Bit 14: Run in standby */ +#define EVSYS_CHANNEL_ONDEMAND (1 << 15) /* Bit 15: Generic clock on-demand */ + +/* User registers */ + +#define EVSYS_USER_CHANNEL_SHIFT (0) /* Bits 0-5: Channel number */ +#define EVSYS_USER_CHANNEL_MASK (63 << EVSYS_USER_CHANNEL_SHIFT) +# define EVSYS_USER_CHANNEL_NONE (0 << EVSYS_USER_CHANNEL_SHIFT) /* No channel output selected */ +# define EVSYS_USER_CHANNEL(n) ((uint32_t)((n)+1) << EVSYS_USER_CHANNEL_SHIFT) /* Channel n */ + +/* User multiplexer numbers ****************************************************************/ + +#define EVSYS_USER_PORT_EV0 0 /* Event 0 */ +#define EVSYS_USER_PORT_EV1 1 /* Event 1 */ +#define EVSYS_USER_PORT_EV2 2 /* Event 2 */ +#define EVSYS_USER_PORT_EV3 3 /* Event 3 */ +#define EVSYS_USER_DMAC_CH0 4 /* DMAC Channel 0 */ +#define EVSYS_USER_DMAC_CH1 5 /* DMAC Channel 1 */ +#define EVSYS_USER_DMAC_CH2 6 /* DMAC Channel 2 */ +#define EVSYS_USER_DMAC_CH3 7 /* DMAC Channel 3 */ +#define EVSYS_USER_DMAC_CH4 8 /* DMAC Channel 4 */ +#define EVSYS_USER_DMAC_CH5 9 /* DMAC Channel 5 */ +#define EVSYS_USER_DMAC_CH6 10 /* DMAC Channel 6 */ +#define EVSYS_USER_DMAC_CH7 11 /* DMAC Channel 7 */ +#define EVSYS_USER_TCC0_EV0 12 /* TCC0 Event 0 */ +#define EVSYS_USER_TCC0_EV1 13 /* TCC0 Event 1 */ +#define EVSYS_USER_TCC0_MC0 14 /* TCC0 Match/Capture 0 */ +#define EVSYS_USER_TCC0_MC1 15 /* TCC0 Match/Capture 1 */ +#define EVSYS_USER_TCC0_MC2 16 /* TCC0 Match/Capture 2 */ +#define EVSYS_USER_TCC0_MC3 17 /* TCC0 Match/Capture 3 */ +#define EVSYS_USER_TCC1_EV0 18 /* TCC1 Event 0 */ +#define EVSYS_USER_TCC1_EV1 19 /* TCC1 Event 1 */ +#define EVSYS_USER_TCC1_MC0 20 /* TCC1 Match/Capture 0 */ +#define EVSYS_USER_TCC1_MC1 21 /* TCC1 Match/Capture 1 */ +#define EVSYS_USER_TCC2_EV0 22 /* TCC2 Event 0 */ +#define EVSYS_USER_TCC2_EV1 23 /* TCC2 Event 1 */ +#define EVSYS_USER_TCC2_MC0 24 /* TCC2 Match/Capture 0 */ +#define EVSYS_USER_TCC2_MC1 25 /* TCC2 Match/Capture 1 */ +#define EVSYS_USER_TC0 26 /* TC0 */ +#define EVSYS_USER_TC1 27 /* TC1 */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_EVSYS_H */ diff --git a/arch/arm/src/samdl/chip/saml_fuses.h b/arch/arm/src/samdl/chip/saml_fuses.h new file mode 100644 index 0000000000000000000000000000000000000000..6b779540732b84f12f7903410489d1d889a58815 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_fuses.h @@ -0,0 +1,206 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/sam_fuses.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_FUSES_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_FUSES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* NVM Fuse addresses **********************************************************************/ + +/* NVM user row bits */ + +#define SAM_NVMUSER_ROW0 (SAM_NVMUSER_ROW + 0x0000) /* Bits 0-31 */ +#define SAM_NVMUSER_ROW1 (SAM_NVMUSER_ROW + 0x0004) /* Bits 32-63 */ + +/* NVM Software Calibration Area */ + +#define SAM_NVMCALIB_AREA0 (SAM_NVMCALIB_AREA + 0x0000) /* Bits 0-31 */ +#define SAM_NVMCALIB_AREA1 (SAM_NVMCALIB_AREA + 0x0000) /* Bits 32-63 */ +#define SAM_NVMCALIB_AREA2 (SAM_NVMCALIB_AREA + 0x0000) /* Bits 64-95 */ +#define SAM_NVMCALIB_AREA3 (SAM_NVMCALIB_AREA + 0x0000) /* Bits 96-127 */ + +/* Fuse bit-field definitions **************************************************************/ +/* NVM user row bits 0-31 */ + +#define SAM_FUSES_BOOTPROT_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOOTPROT_SHIFT (0) /* Bits 0-2: Bootloader Size */ +#define SAM_FUSES_BOOTPROT_MASK (7 << SAM_FUSES_BOOTPROT_SHIFT) +# define SAM_FUSES_BOOTPROT(n) ((uint32_t)(n) << SAM_FUSES_BOOTPROT_SHIFT) + +#define SAM_FUSES_EEPROM_SIZE_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_EEPROM_SIZE_SHIFT (4) /* Bits 4-6: EEPROM Size */ +#define SAM_FUSES_EEPROM_SIZE_MASK (7 << SAM_FUSES_EEPROM_SIZE_SHIFT) +# define SAM_FUSES_EEPROM_SIZE(n) ((uint32_t)(n) << SAM_FUSES_EEPROM_SIZE_SHIFT) + +#define SAM_FUSES_BOD33LEVEL_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD33LEVEL_SHIFT (8) /* Bits 8-13: BOD33 Level */ +#define SAM_FUSES_BOD33LEVEL_MASK (0x3f << SAM_FUSES_BOD33LEVEL_SHIFT) +# define SAM_FUSES_BOD33LEVEL(n) (((uint32_t)n) << SAM_FUSES_BOD33LEVEL_SHIFT) + +#define SAM_FUSES_BOD33_DIS_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD33_DIS_SHIFT (14) /* Bit 14: BOD33 Disable */ +#define SAM_FUSES_BOD33_DIS_MASK (1 << SAM_FUSES_BOD33_DIS_SHIFT) + +#define SAM_FUSES_BOD33_ACTION_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD33_ACTION_SHIFT (15) /* Bits 15-16: BOD33 Action */ +#define SAM_FUSES_BOD33_ACTION_MASK (3 << SAM_FUSES_BOD33_ACTION_SHIFT) +# define SAM_FUSES_BOD33_ACTION(n) (((uint32_t)n) << SAM_FUSES_BOD33_ACTION_SHIFT) + +#define SAM_FUSES_BOD12LEVEL_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD12LEVEL_SHIFT (17) /* Bits 17-22: BOD12 Level */ +#define SAM_FUSES_BOD12LEVEL_MASK (0x1f << SAM_FUSES_BOD12LEVEL_SHIFT) +# define SAM_FUSES_BOD12LEVEL(n) ((uint32_t)(n) << SAM_FUSES_BOD12LEVEL_SHIFT) + +#define SAM_FUSES_BOD12_DIS_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD12_DIS_SHIFT (23) /* Bit 23: BOD12 Disable */ +#define SAM_FUSES_BOD12_DIS_MASK (1 << SAM_FUSES_BOD12_DIS_SHIFT) + +#define SAM_FUSES_BOD12_ACTION_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_BOD12_ACTION_SHIFT (24) /* Bits 24-25: BOD12 Action */ +#define SAM_FUSES_BOD12_ACTION_MASK (3 << SAM_FUSES_BOD12_ACTION_SHIFT) +# define SAM_FUSES_BOD12_ACTION(n) ((uint32_t)(n) << SAM_FUSES_BOD12_ACTION_SHIFT) + +#define SAM_FUSES_WDT_ENA_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_WDT_ENA_SHIFT (26) /* Bit 26: WDT Enable */ +#define SAM_FUSES_WDT_ENA_MASK (1 << SAM_FUSES_WDT_ENA_SHIFT) + +#define SAM_FUSES_WDT_ALWAYSON_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_WDT_ALWAYSON_SHIFT (27) /* Bit 27: WDT Always On */ +#define SAM_FUSES_WDT_ALWAYSON_MASK (1 << SAM_FUSES_WDT_ALWAYSON_SHIFT) + +#define SAM_FUSES_WDT_PER_ADDR SAM_NVMUSER_ROW0 +#define SAM_FUSES_WDT_PER_SHIFT (28) /* Bits 28-31: WDT Period */ +#define SAM_FUSES_WDT_PER_MASK (15 << SAM_FUSES_WDT_PER_SHIFT) +# define SAM_FUSES_WDT_PER(n) ((uint32_t)(n) << SAM_FUSES_WDT_PER_SHIFT) + +/* NVM user row bits 32-64 */ + +#define SAM_FUSES_WDT_WINDOW_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_WDT_WINDOW_SHIFT (0) /* Bits 32-35: WDT Window */ +#define SAM_FUSES_WDT_WINDOW_MASK (15 << SAM_FUSES_WDT_WINDOW_SHIFT) + +#define SAM_FUSES_WDT_EWOFFSET_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_WDT_EWOFFSET_SHIFT (4) /* Bits 36-39: WDT Early Warning Offset */ +#define SAM_FUSES_WDT_EWOFFSET_MASK (15 << SAM_FUSES_WDT_EWOFFSET_SHIFT) +# define SAM_FUSES_WDT_EWOFFSET(n) ((uint32_t)(n) << SAM_FUSES_WDT_EWOFFSET_SHIFT) + +#define SAM_FUSES_WDT_WEN_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_WDT_WEN_SHIFT (8) /* Bit 40: WDT Window Mode Enable */ +#define SAM_FUSES_WDT_WEN_MASK (1 << SAM_FUSES_WDT_WEN_SHIFT) + +#define SAM_FUSES_BOD33_HYST_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_BOD33_HYST_SHIFT (9) /* Bit 41: BOD33 Hysteresis */ +#define SAM_FUSES_BOD33_HYST_MASK (1 << SAM_FUSES_BOD33_HYST_SHIFT) + +#define SAM_FUSES_BOD12_HYST_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_BOD12_HYST_SHIFT (10) /* Bit 42: BOD12 Hysteresis */ +#define SAM_FUSES_BOD12_HYST_MASK (1 << SAM_FUSES_BOD12_HYST_SHIFT) + +#define SAM_FUSES_LOCK_ADDR SAM_NVMUSER_ROW1 +#define SAM_FUSES_LOCK_SHIFT (16) /* Bits 48-63: NVM Region Lock bits */ +#define SAM_FUSES_LOCK_MASK (0xffff << SAM_FUSES_LOCK_SHIFT) +# define SAM_FUSES_LOCK(n) ((uint32_t)(n) << SAM_FUSES_LOCK_SHIFT) + +/* NVM Software Calibration Area bits 0-31 */ + +#define SAM_FUSES_ADC_LINEARITY_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_ADC_LINEARITY_SHIFT (0) /* Bits 0-2: ADC Linearity bits */ +#define SAM_FUSES_ADC_LINEARITY_MASK (7 << SAM_FUSES_ADC_LINEARITY_SHIFT) +# define SAM_FUSES_ADC_LINEARITY(n) ((uint32_t)(n) << SAM_FUSES_ADC_LINEARITY_SHIFT) + +#define SAM_FUSES_ADC_BIASCAL_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_ADC_BIASCAL_SHIFT (3) /* Bits 3-5: ADC Bias Calibration */ +#define SAM_FUSES_ADC_BIASCAL_MASK (7 << SAM_FUSES_ADC_BIASCAL_SHIFT) +# define SAM_FUSES_ADC_BIASCAL(n) ((uint32_t)(n) << SAM_FUSES_ADC_BIASCAL_SHIFT) + +#define SAM_FUSES_OSC32KCAL_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_OSC32KCAL_SHIFT (6) /* Bits 6-12: OSC32K Calibration */ +#define SAM_FUSES_OSC32KCAL_MASK (0x7f << SAM_FUSES_OSC32KCAL_SHIFT) +# define SAM_FUSES_OSC32KCAL(n) ((uint32_t)(n) << SAM_FUSES_OSC32KCAL_SHIFT) + +#define SAM_FUSES_USBTRANSN_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_USBTRANSN_SHIFT (13) /* Bits 13-17: USB TRNSN Calibration */ +#define SAM_FUSES_USBTRANSN_MASK (31 << SAM_FUSES_USBTRANSN_SHIFT) +# define SAM_FUSES_USBTRANSN(n) ((uint32_t)(n) << SAM_FUSES_USBTRANSN_SHIFT) + +#define SAM_FUSES_USBTRANSP_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_USBTRANSP_SHIFT (6) /* Bits 18-22: USB TRNSP Calibration */ +#define SAM_FUSES_USBTRANSP_MASK (31 << SAM_FUSES_USBTRANSP_SHIFT) +# define SAM_FUSES_USBTRANSP(n) ((uint32_t)(n) << SAM_FUSES_USBTRANSP_SHIFT) + +#define SAM_FUSES_USBTRIM_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_USBTRIM_SHIFT (23) /* Bits 23-25: USB TRIM Calibration */ +#define SAM_FUSES_USBTRIM_MASK (7 << SAM_FUSES_USBTRIM_SHIFT) +# define SAM_FUSES_USBTRIM(n) ((uint32_t)(n) << SAM_FUSES_USBTRIM_SHIFT) + +#define SAM_FUSES_DFLL48MCC_ADDR SAM_NVMCALIB_AREA0 +#define SAM_FUSES_DFLL48MCC_SHIFT (26) /* Bits 26-31: DFLL48M Coarse Calibration */ +#define SAM_FUSES_DFLL48MCC_MASK (0x3f << SAM_FUSES_DFLL48MCC_SHIFT) +# define SAM_FUSES_DFLL48MCC(n) ((uint32_t)(n) << SAM_FUSES_DFLL48MCC_SHIFT) + +/* NVM Software Calibration Area bits 32-63 - Reserved */ +/* NVM Software Calibration Area bits 64-95 - Reserved */ +/* NVM Software Calibration Area bits 96-127 - Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_FUSES_H */ diff --git a/arch/arm/src/samdl/chip/saml_gclk.h b/arch/arm/src/samdl/chip/saml_gclk.h new file mode 100644 index 0000000000000000000000000000000000000000..c172bb2020f37617e581f2cb6439b5e7a792d226 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_gclk.h @@ -0,0 +1,194 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_gclk.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_GCLK_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_GCLK_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* GCLK register offsets ********************************************************************/ + +#define SAM_GCLK_CTRLA_OFFSET 0x0000 /* Control register */ +#define SAM_GCLK_SYNCHBUSY_OFFSET 0x0004 /* Status register */ + +#define SAM_GCLK_GENCTRL_OFFSET(n) (0x0020 + ((n) << 2)) /* General clock generator n */ +#define SAM_GCLK_PCHCTRL_OFFSET(m) (0x0080 + ((m) << 2)) /* Peripheral channel control m */ + +/* GCLK register addresses ******************************************************************/ + +#define SAM_GCLK_CTRLA (SAM_GCLK_BASE+SAM_GCLK_CTRLA_OFFSET) +#define SAM_GCLK_SYNCHBUSY (SAM_GCLK_BASE+SAM_GCLK_SYNCHBUSY_OFFSET) + +#define SAM_GCLK_GENCTRL(n) (SAM_GCLK_BASE+SAM_GCLK_GENCTRL_OFFSET(n)) +#define SAM_GCLK_PCHCTRL(m) (SAM_GCLK_BASE+SAM_GCLK_PCHCTRL_OFFSET(m)) + +/* GCLK register bit definitions ************************************************************/ + +/* Control register */ + +#define GCLK_CTRLA_SWRST (1 << 0) /* Bit 0: Software Reset */ + +/* Status register */ + +#define GCLK_SYNCHBUSY_SWRST (1 << 0) /* Bit 0: SWRST synchronization busy */ +#define GCLK_SYNCHBUSY_GENCTRL(n) (1 << ((n) + 2)) /* Bit n+2: Generator control n busy */ +# define GCLK_SYNCHBUSY_GENCTRL0 (1 << 2) /* Bit 2: Generator control 0 busy */ +# define GCLK_SYNCHBUSY_GENCTRL1 (1 << 3) /* Bit 3: Generator control 1 busy */ +# define GCLK_SYNCHBUSY_GENCTRL2 (1 << 4) /* Bit 4: Generator control 2 busy */ +# define GCLK_SYNCHBUSY_GENCTRL3 (1 << 5) /* Bit 5: Generator control 3 busy */ +# define GCLK_SYNCHBUSY_GENCTRL4 (1 << 6) /* Bit 6: Generator control 4 busy */ +# define GCLK_SYNCHBUSY_GENCTRL5 (1 << 7) /* Bit 7: Generator control 5 busy */ +# define GCLK_SYNCHBUSY_GENCTRL6 (1 << 8) /* Bit 8: Generator control 6 busy */ +# define GCLK_SYNCHBUSY_GENCTRL7 (1 << 9) /* Bit 9: Generator control 7 busy */ +# define GCLK_SYNCHBUSY_GENCTRL8 (1 << 10) /* Bit 10: Generator control 8 busy */ + +/* General clock generator n */ + +#define GCLK_GENCTRL_SRC_SHIFT (0) /* Bits 0-4: Generator source selection */ +#define GCLK_GENCTRL_SRC_MASK (31 << GCLK_GENCTRL_SRC_SHIFT) +# define GCLK_GENCTRL_SRC_XOSC (0 << GCLK_GENCTRL_SRC_SHIFT) /* XOSC oscillator inpupt */ +# define GCLK_GENCTRL_SRC_GCLK_IN (1 << GCLK_GENCTRL_SRC_SHIFT) /* Generator input pad */ +# define GCLK_GENCTRL_SRC_GLCK_GEN1 (2 << GCLK_GENCTRL_SRC_SHIFT) /* Generic clock generater 1 output */ +# define GCLK_GENCTRL_SRC_OSCULP32K (3 << GCLK_GENCTRL_SRC_SHIFT) /* OSCULP32K oscillator output */ +# define GCLK_GENCTRL_SRC_OSC32K (4 << GCLK_GENCTRL_SRC_SHIFT) /* OSC32K osccillator output */ +# define GCLK_GENCTRL_SRC_XOSC32K (5 << GCLK_GENCTRL_SRC_SHIFT) /* XOSC32K oscillator output */ +# define GCLK_GENCTRL_SRC_OSC16M (6 << GCLK_GENCTRL_SRC_SHIFT) /* OSC16M oscillator output */ +# define GCLK_GENCTRL_SRC_DFLL48M (7 << GCLK_GENCTRL_SRC_SHIFT) /* DFLL48M output */ +# define GCLK_GENCTRL_SRC_DPLL96M (8 << GCLK_GENCTRL_SRC_SHIFT) /* DPLL96M output */ +#define GCLK_GENCTRL_GENEN (1 << 8) /* Bit 8: Generator enable */ +#define GCLK_GENCTRL_IDC (1 << 9) /* Bit 9: Improve duty cycle */ +#define GCLK_GENCTRL_OOV (1 << 10) /* Bit 10: Clock output selection */ +#define GCLK_GENCTRL_OE (1 << 11) /* Bit 11: Clock output enable */ +#define GCLK_GENCTRL_DIVSEL (1 << 12) /* Bit 12: Clock source divider */ +#define GCLK_GENCTRL_RUNSTDBY (1 << 13) /* Bit 13: Run in standby */ +#define GCLK_GENCTRL_DIV_SHIFT (16) /* Bits 16-31: Generator 0,2-8 Division factor */ +#define GCLK_GENCTRL_DIV_MASK (0xff << GCLK_GENCTRL_DIV_SHIFT) +# define GCLK_GENCTRL_DIV(n) ((uint32_t)(n) << GCLK_GENCTRL_DIV_SHIFT) +#define GCLK_GENCTRL1_DIV_SHIFT (16) /* Bits 16-23: Generator 1 Division factor **/ +#define GCLK_GENCTRL1_DIV_MASK (0xffff << GCLK_GENCTRL1_DIV_SHIFT) +# define GCLK_GENCTRL1_DIV(n) ((uint32_t)(n) << GCLK_GENCTRL1_DIV_SHIFT) + +/* Peripheral channel control m */ + +#define GCLK_PCHCTRL_GEN_SHIFT (0) /* Bits 0-3: Generator selection */ +#define GCLK_PCHCTRL_GEN_MASK (15 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN(n) ((uint32_t)(n) << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN0 (0 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN1 (1 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN2 (2 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN3 (3 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN4 (4 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN5 (5 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN6 (6 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN7 (7 << GCLK_PCHCTRL_GEN_SHIFT) +# define GCLK_PCHCTRL_GEN8 (8 << GCLK_PCHCTRL_GEN_SHIFT) +#define GCLK_PCHCTRL_CHEN (1 << 6) /* Bit 6: Channel enable */ +#define GCLK_PCHCTRL_WRTLOCK (1 << 7) /* Bit 7: Write lock */ + +/* PCHCTRL channel mapping ******************************************************************/ + +#define GCLK_CHAN_DFLL48M_REF 0 /* DFLL48M Reference */ +#define GCLK_CHAN_DPLL 1 /* FDPLL96M input clock source for reference */ +#define GCLK_CHAN_DPLL_32K 2 /* FDPLL96M 32kHz clock for FDPLL96M internal lock timer */ +#define GCLK_CHAN_EIC 3 /* EIC */ +#define GCLK_CHAN_USB 4 /* USB */ +#define GCLK_CHAN_EVSYS_CH0 5 /* EVSYS_CHANNEL_0 */ +#define GCLK_CHAN_EVSYS_CH1 6 /* EVSYS_CHANNEL_1 */ +#define GCLK_CHAN_EVSYS_CH2 7 /* EVSYS_CHANNEL_2 */ +#define GCLK_CHAN_EVSYS_CH3 8 /* EVSYS_CHANNEL_3 */ +#define GCLK_CHAN_EVSYS_CH4 9 /* EVSYS_CHANNEL_4 */ +#define GCLK_CHAN_EVSYS_CH5 10 /* EVSYS_CHANNEL_5 */ +#define GCLK_CHAN_EVSYS_CH6 11 /* EVSYS_CHANNEL_6 */ +#define GCLK_CHAN_EVSYS_CH7 12 /* EVSYS_CHANNEL_7 */ +#define GCLK_CHAN_EVSYS_CH8 13 /* EVSYS_CHANNEL_8 */ +#define GCLK_CHAN_EVSYS_CH9 14 /* EVSYS_CHANNEL_9 */ +#define GCLK_CHAN_EVSYS_CH10 15 /* EVSYS_CHANNEL_10 */ +#define GCLK_CHAN_EVSYS_CH11 16 /* EVSYS_CHANNEL_11 */ +#define GCLK_CHAN_SERCOM0_SLOW 17 /* SERCOM0_SLOW */ +#define GCLK_CHAN_SERCOM1_SLOW 17 /* SERCOM1_SLOW */ +#define GCLK_CHAN_SERCOM2_SLOW 17 /* SERCOM2_SLOW */ +#define GCLK_CHAN_SERCOM3_SLOW 17 /* SERCOM3_SLOW */ +#define GCLK_CHAN_SERCOM4_SLOW 17 /* SERCOM4_SLOW */ +#define GCLK_CHAN_SERCOM0_CORE 18 /* SERCOM0_CORE */ +#define GCLK_CHAN_SERCOM1_CORE 19 /* SERCOM1_CORE */ +#define GCLK_CHAN_SERCOM2_CORE 20 /* SERCOM2_CORE */ +#define GCLK_CHAN_SERCOM3_CORE 21 /* SERCOM3_CORE */ +#define GCLK_CHAN_SERCOM4_CORE 22 /* SERCOM4_CORE */ +#define GCLK_CHAN_SERCOM5_SLOW 23 /* SERCOM5_SLOW */ +#define GCLK_CHAN_SERCOM5_CORE 24 /* SERCOM5_CORE */ +#define GCLK_CHAN_TCC0 25 /* TCC0 */ +#define GCLK_CHAN_TCC1 25 /* TCC1 */ +#define GCLK_CHAN_TCC2 26 /* TCC2 */ +#define GCLK_CHAN_TC3_1 26 /* TC3 */ +#define GCLK_CHAN_TC0 27 /* TC0 */ +#define GCLK_CHAN_TC1 27 /* TC1 */ +#define GCLK_CHAN_TC2 28 /* TC2 */ +#define GCLK_CHAN_TC3_2 28 /* TC3 */ +#define GCLK_CHAN_TC4 29 /* TC4 */ +#define GCLK_CHAN_ADC 30 /* ADC */ +#define GCLK_CHAN_AC 31 /* AC */ +#define GCLK_CHAN_DAC 32 /* DAC */ +#define GCLK_CHAN_PTC 33 /* PTC */ +#define GCLK_CHAN_CCL 34 /* CCL */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_GCLK_H */ diff --git a/arch/arm/src/samdl/chip/saml_i2c_master.h b/arch/arm/src/samdl/chip/saml_i2c_master.h new file mode 100644 index 0000000000000000000000000000000000000000..a83a60bd2e3f470d16d0d1b069da7a5de8efdf96 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_i2c_master.h @@ -0,0 +1,274 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_i2c_master.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_MASTER_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_MASTER_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/saml_sercom.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* I2C register offsets *********************************************************************/ + +#define SAM_I2C_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_I2C_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_I2C_BAUD_OFFSET 0x000c /* Baud register */ +#define SAM_I2C_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +#define SAM_I2C_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +#define SAM_I2C_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +#define SAM_I2C_STATUS_OFFSET 0x001a /* Status register */ +#define SAM_I2C_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +#define SAM_I2C_ADDR_OFFSET 0x0024 /* Address register */ +#define SAM_I2C_DATA_OFFSET 0x0028 /* Data register */ +#define SAM_I2C_DBGCTRL_OFFSET 0x0030 /* Debug control register */ + +/* I2C register addresses *******************************************************************/ + +#define SAM_I2C0_CTRLA (SAM_SERCOM0_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C0_CTRLB (SAM_SERCOM0_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C0_BAUD (SAM_SERCOM0_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C0_INTENCLR (SAM_SERCOM0_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C0_INTENSET (SAM_SERCOM0_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C0_INTFLAG (SAM_SERCOM0_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C0_STATUS (SAM_SERCOM0_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C0_ADDR (SAM_SERCOM0_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C0_DATA (SAM_SERCOM0_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C0_DBGCTRL (SAM_SERCOM0_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C1_CTRLA (SAM_SERCOM1_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C1_CTRLB (SAM_SERCOM1_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C1_BAUD (SAM_SERCOM1_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C1_INTENCLR (SAM_SERCOM1_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C1_INTENSET (SAM_SERCOM1_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C1_INTFLAG (SAM_SERCOM1_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C1_STATUS (SAM_SERCOM1_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C1_ADDR (SAM_SERCOM1_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C1_DATA (SAM_SERCOM1_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C1_DBGCTRL (SAM_SERCOM1_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C2_CTRLA (SAM_SERCOM2_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C2_CTRLB (SAM_SERCOM2_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C2_BAUD (SAM_SERCOM2_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C2_INTENCLR (SAM_SERCOM2_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C2_INTENSET (SAM_SERCOM2_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C2_INTFLAG (SAM_SERCOM2_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C2_STATUS (SAM_SERCOM2_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C2_ADDR (SAM_SERCOM2_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C2_DATA (SAM_SERCOM2_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C2_DBGCTRL (SAM_SERCOM2_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C3_CTRLA (SAM_SERCOM3_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C3_CTRLB (SAM_SERCOM3_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C3_BAUD (SAM_SERCOM3_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C3_INTENCLR (SAM_SERCOM3_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C3_INTENSET (SAM_SERCOM3_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C3_INTFLAG (SAM_SERCOM3_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C3_STATUS (SAM_SERCOM3_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C3_ADDR (SAM_SERCOM3_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C3_DATA (SAM_SERCOM3_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C3_DBGCTRL (SAM_SERCOM3_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C4_CTRLA (SAM_SERCOM4_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C4_CTRLB (SAM_SERCOM4_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C4_BAUD (SAM_SERCOM4_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C4_INTENCLR (SAM_SERCOM4_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C4_INTENSET (SAM_SERCOM4_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C4_INTFLAG (SAM_SERCOM4_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C4_STATUS (SAM_SERCOM4_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C4_ADDR (SAM_SERCOM4_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C4_DATA (SAM_SERCOM4_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C4_DBGCTRL (SAM_SERCOM4_BASE+SAM_I2C_DBGCTRL_OFFSET) + +#define SAM_I2C5_CTRLA (SAM_SERCOM5_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C5_CTRLB (SAM_SERCOM5_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C5_BAUD (SAM_SERCOM5_BASE+SAM_I2C_BAUD_OFFSET) +#define SAM_I2C5_INTENCLR (SAM_SERCOM5_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C5_INTENSET (SAM_SERCOM5_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C5_INTFLAG (SAM_SERCOM5_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C5_STATUS (SAM_SERCOM5_BASE+SAM_I2C_STATUS_OFFSET) +#define SAM_I2C5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_I2C_SYNCBUSY_OFFSET) +#define SAM_I2C5_ADDR (SAM_SERCOM5_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C5_DATA (SAM_SERCOM5_BASE+SAM_I2C_DATA_OFFSET) +#define SAM_I2C5_DBGCTRL (SAM_SERCOM5_BASE+SAM_I2C_DBGCTRL_OFFSET) + +/* I2C register bit definitions *************************************************************/ + +/* Control A register */ + +#define I2C_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define I2C_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define I2C_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define I2C_CTRLA_MODE_MASK (7 << I2C_CTRLA_MODE_SHIFT) +# define I2C_CTRLA_MODE_MASTER (5 << I2C_CTRLA_MODE_SHIFT) /* I2C master mode */ +#define I2C_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define I2C_CTRLA_PINOUT (1 << 16) /* Bit 16: Transmit data pinout */ +# define I2C_CTRLA_2WIRE (0) /* 4-wire operation disable */ +# define I2C_CTRLA_4WIRE I2C_CTRLA_PINOUT /* 4-wire operation enable */ +#define I2C_CTRLA_SDAHOLD_SHIFT (20) /* Bits 20-21: SDA Hold Time */ +#define I2C_CTRLA_SDAHOLD_MASK (3 << I2C_CTRLA_SDAHOLD_SHIFT) +# define I2C_CTRLA_SDAHOLD_DIS (0 << I2C_CTRLA_SDAHOLD_SHIFT) /* Disabled */ +# define I2C_CTRLA_SDAHOLD_75NS (1 << I2C_CTRLA_SDAHOLD_SHIFT) /* 50-100ns hold time */ +# define I2C_CTRLA_SDAHOLD_450NS (2 << I2C_CTRLA_SDAHOLD_SHIFT) /* 300-600ns hold time */ +# define I2C_CTRLA_SDAHOLD_600NS (3 << I2C_CTRLA_SDAHOLD_SHIFT) /* 400-800ns hold time */ +#define I2C_CTRLA_MEXTTOEN (1 << 22) /* Bit 22: Master SCL low extend time-out */ +#define I2C_CTRLA_SEXTTOEN (1 << 23) /* Bit 23: Slave SCL low extend time-out */ +#define I2C_CTRLA_SPEED_SHIFT (24) /* Bits 24-25: Transfer speed */ +#define I2C_CTRLA_SPEED_MASK (3 << I2C_CTRLA_SPEED_SHIFT) +# define I2C_CTRLA_SPEED_STD (0 << I2C_CTRLA_SPEED_SHIFT) /* Standard (<=100KHz) and fast (<=400KHz) */ +# define I2C_CTRLA_SPEED_FAST (1 << I2C_CTRLA_SPEED_SHIFT) /* Fast-mode plus (<=1MHz) */ +# define I2C_CTRLA_SPEED_HIGH (2 << I2C_CTRLA_SPEED_SHIFT) /* High speed mode (<=3.4Mhz */ +#define I2C_CTRLA_SCLAM (1 << 27) /* Bit 27: CSL clock stretch mode */ +#define I2C_CTRLA_INACTOUT_SHIFT (28) /* Bits 28-29: Inactive Time-Out */ +#define I2C_CTRLA_INACTOUT_MASK (7 << I2C_CTRLA_INACTOUT_SHIFT) +# define I2C_CTRLA_INACTOUT_DIS (0 << I2C_CTRLA_INACTOUT_SHIFT) /* Disabled */ +# define I2C_CTRLA_INACTOUT_55US (1 << I2C_CTRLA_INACTOUT_SHIFT) /* 5-6 SCL cycle time-out (50-60µs) */ +# define I2C_CTRLA_INACTOUT_105US (2 << I2C_CTRLA_INACTOUT_SHIFT) /* 10-11 SCL cycle time-out (100-110µs) */ +# define I2C_CTRLA_INACTOUT_205US (3 << I2C_CTRLA_INACTOUT_SHIFT) /* 20-21 SCL cycle time-out (200-210µs) */ +#define I2C_CTRLA_LOWTOUT (1 << 30) /* Bit 30: SCL Low Time-Out */ + +/* Control B register */ + +#define I2C_CTRLB_SMEN (1 << 8) /* Bit 8: Smart Mode Enable */ +#define I2C_CTRLB_QCEN (1 << 9) /* Bit 9: Quick Command Enable */ +#define I2C_CTRLB_CMD_SHIFT (16) /* Bits 16-17: Command */ +#define I2C_CTRLB_CMD_MASK (3 << I2C_CTRLB_CMD_SHIFT) +# define I2C_CTRLB_CMD_NOACTION (0 << I2C_CTRLB_CMD_SHIFT) /* No action */ +# define I2C_CTRLB_CMD_ACKREP (1 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by repeated START */ +# define I2C_CTRLB_CMD_ACKREAD (2 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by read operation */ +# define I2C_CTRLB_CMD_ACKSTOP (3 << I2C_CTRLB_CMD_SHIFT) /* ACK followed by STOP */ +#define I2C_CTRLB_ACKACT (1 << 18) /* Bit 18: Acknowledge Action */ +# define I2C_CTRLB_ACK (0) /* Send ACK */ +# define I2C_CTRLB_NACK I2C_CTRLB_ACKACT /* Send NACK */ + +/* Baud register (16-bit baud value) */ + +#define I2C_BAUD_SHIFT (0) /* Bits 0-7: Master Baud Rate */ +#define I2C_BAUD_MASK (0xff << I2C_BAUD_SHIFT) +# define I2C_BAUD(n) ((uint16)(n) << I2C_BAUD_SHIFT) +#define I2C_BAUDLOW_SHIFT (8) /* Bits 8-15: Master Baud Rate Low */ +#define I2C_BAUDLOW_MASK (0xff << I2C_BAUDLOW_SHIFT) +# define I2C_BAUDLOW(n) (uint16)(n) << I2C_BAUDLOW_SHIFT) +#define I2C_HSBAUD_SHIFT (16) /* Bits 16-23: High speed master Baud Rate */ +#define I2C_HSBAUD_MASK (0xff << I2C_HSBAUD_SHIFT) +# define I2C_HSBAUD(n) ((uint16)(n) << I2C_HSBAUD_SHIFT) +#define I2C_HSBAUDLOW_SHIFT (24) /* Bits 24-31: High speed master Baud Rate Low */ +#define I2C_HSBAUDLOW_MASK (0xff << I2C_HSBAUDLOW_SHIFT) +# define I2C_HSBAUDLOW(n) (uint16)(n) << I2C_HSBAUDLOW_SHIFT) + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define I2C_INT_MB (1 << 0) /* Bit 0: Master on bus interrupt */ +#define I2C_INT_SB (1 << 1) /* Bit 1: Slave on bus interrupt */ + +#define I2C_INT_ALL (0x03) + +/* Status register */ + +#define I2C_STATUS_BUSERR (1 << 0) /* Bit 0: Bus Error */ +#define I2C_STATUS_ARBLOST (1 << 1) /* Bit 1: Arbitration Lost */ +#define I2C_STATUS_RXNACK (1 << 2) /* Bit 2: Received Not Acknowledge */ +#define I2C_STATUS_BUSSTATE_SHIFT (4) /* Bits 4-5: Bus State */ +#define I2C_STATUS_BUSSTATE_MASK (3 << I2C_STATUS_BUSSTATE_SHIFT) +# define I2C_STATUS_BUSSTATE_UNKNOWN (0 << I2C_STATUS_BUSSTATE_SHIFT) /* Unknown to master */ +# define I2C_STATUS_BUSSTATE_IDLE (1 << I2C_STATUS_BUSSTATE_SHIFT) /* Waiting for transaction */ +# define I2C_STATUS_BUSSTATE_OWNER (2 << I2C_STATUS_BUSSTATE_SHIFT) /* Master of bus owner */ +# define I2C_STATUS_BUSSTATE_BUSY (3 << I2C_STATUS_BUSSTATE_SHIFT) /* Other master owns */ +#define I2C_STATUS_LOWTOUT (1 << 6) /* Bit 6: SCL Low Time-Out */ +#define I2C_STATUS_CLKHOLD (1 << 7) /* Bit 7: Clock Hold */ +#define I2C_STATUS_MEXTTOUT (1 << 8) /* Bit 8: Master SCL low extend time-out */ +#define I2C_STATUS_SEXTTOUT (1 << 9) /* Bit 9: Slave SCL low extend time-out */ +#define I2C_STATUS_LENERR (1 << 10) /* Bit 10: Transaction length error */ + +/* Synchronization busy register */ + +#define I2C_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +#define I2C_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +#define I2C_SYNCBUSY_SYSOP (1 << 2) /* Bit 2: System operation synchronization busy */ + +/* Address register */ + +#define I2C_ADDR_SHIFT (8) /* Bits 8-10: Address */ +#define I2C_ADDR_MASK (7 << I2C_ADDR_SHIFT) +# define I2C_ADDR(n) ((uint32-_t(n) << I2C_ADDR_SHIFT) +#define I2C_ADDR_LENEN (1 << 13) /* Bit 13: Transfer length enable */ +#define I2C_ADDR_HS (1 << 14) /* Bit 14: High speed */ +#define I2C_ADDR_TENBITEN (1 << 15) /* Bit 15: Ten bit addressing enable */ +#define I2C_ADDR_LEN_SHIFT (16) /* Bits 16-23: Transaction length */ +#define I2C_ADDR_LEN_MASK (0xff << I2C_ADDR_LEN_SHIFT) +# define I2C_ADDR_LEN(n) ((uint32_t)(n) << I2C_ADDR_LEN_SHIFT) + +/* Data register */ + +#define I2C_DATA_MASK (0xff) /* Bits 0-7: Data */ + +/* Debug control register */ + +#define I2C_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_MASTER_H */ diff --git a/arch/arm/src/samdl/chip/saml_i2c_slave.h b/arch/arm/src/samdl/chip/saml_i2c_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..be4890a1d48a3a779f0dc55f66ecd853ea7814c1 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_i2c_slave.h @@ -0,0 +1,209 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_i2c_slave.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_SLAVE_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_SLAVE_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/saml_sercom.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* I2C register offsets *********************************************************************/ + +#define SAM_I2C_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_I2C_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_I2C_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +#define SAM_I2C_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +#define SAM_I2C_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +#define SAM_I2C_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +#define SAM_I2C_ADDR_OFFSET 0x0024 /* Address register */ +#define SAM_I2C_DATA_OFFSET 0x0028 /* Data register */ + +/* I2C register addresses *******************************************************************/ + +#define SAM_I2C0_CTRLA (SAM_SERCOM0_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C0_CTRLB (SAM_SERCOM0_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C0_INTENCLR (SAM_SERCOM0_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C0_INTENSET (SAM_SERCOM0_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C0_INTFLAG (SAM_SERCOM0_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C0_ADDR (SAM_SERCOM0_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C0_DATA (SAM_SERCOM0_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C1_CTRLA (SAM_SERCOM1_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C1_CTRLB (SAM_SERCOM1_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C1_INTENCLR (SAM_SERCOM1_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C1_INTENSET (SAM_SERCOM1_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C1_INTFLAG (SAM_SERCOM1_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C1_ADDR (SAM_SERCOM1_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C1_DATA (SAM_SERCOM1_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C2_CTRLA (SAM_SERCOM2_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C2_CTRLB (SAM_SERCOM2_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C2_INTENCLR (SAM_SERCOM2_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C2_INTENSET (SAM_SERCOM2_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C2_INTFLAG (SAM_SERCOM2_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C2_ADDR (SAM_SERCOM2_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C2_DATA (SAM_SERCOM2_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C3_CTRLA (SAM_SERCOM3_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C3_CTRLB (SAM_SERCOM3_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C3_INTENCLR (SAM_SERCOM3_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C3_INTENSET (SAM_SERCOM3_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C3_INTFLAG (SAM_SERCOM3_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C3_ADDR (SAM_SERCOM3_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C3_DATA (SAM_SERCOM3_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C4_CTRLA (SAM_SERCOM4_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C4_CTRLB (SAM_SERCOM4_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C4_INTENCLR (SAM_SERCOM4_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C4_INTENSET (SAM_SERCOM4_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C4_INTFLAG (SAM_SERCOM4_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C4_ADDR (SAM_SERCOM4_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C4_DATA (SAM_SERCOM4_BASE+SAM_I2C_DATA_OFFSET) + +#define SAM_I2C5_CTRLA (SAM_SERCOM5_BASE+SAM_I2C_CTRLA_OFFSET) +#define SAM_I2C5_CTRLB (SAM_SERCOM5_BASE+SAM_I2C_CTRLB_OFFSET) +#define SAM_I2C5_INTENCLR (SAM_SERCOM5_BASE+SAM_I2C_INTENCLR_OFFSET) +#define SAM_I2C5_INTENSET (SAM_SERCOM5_BASE+SAM_I2C_INTENSET_OFFSET) +#define SAM_I2C5_INTFLAG (SAM_SERCOM5_BASE+SAM_I2C_INTFLAG_OFFSET) +#define SAM_I2C5_ADDR (SAM_SERCOM5_BASE+SAM_I2C_ADDR_OFFSET) +#define SAM_I2C5_DATA (SAM_SERCOM5_BASE+SAM_I2C_DATA_OFFSET) + +/* I2C register bit definitions *************************************************************/ + +/* Control A register */ + +#define I2C_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define I2C_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define I2C_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define I2C_CTRLA_MODE_MASK (7 << I2C_CTRLA_MODE_SHIFT) +# define I2C_CTRLA_MODE_SLAVE (4 << I2C_CTRLA_MODE_SHIFT) /* I2C slave mode */ +#define I2C_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define I2C_CTRLA_PINOUT (1 << 16) /* Bit 16: Pin usage */ +# define I2C_CTRLA_1WIRE (0) /* 4-wire operation disabled */ +# define I2C_CTRLA_4WIRE I2C_CTRLA_PINOUT /* 4-wire operation enabled */ +#define I2C_CTRLA_SDAHOLD_SHIFT (20) /* Bits 20-21: SDA Hold Time */ +#define I2C_CTRLA_SDAHOLD_MASK (3 << I2C_CTRLA_SDAHOLD_SHIFT) +# define I2C_CTRLA_SDAHOLD_DIS (0 << I2C_CTRLA_SDAHOLD_SHIFT) /* Disabled */ +# define I2C_CTRLA_SDAHOLD_75NS (1 << I2C_CTRLA_SDAHOLD_SHIFT) /* 50-100ns hold time */ +# define I2C_CTRLA_SDAHOLD_450NS (2 << I2C_CTRLA_SDAHOLD_SHIFT) /* 300-600ns hold time */ +# define I2C_CTRLA_SDAHOLD_600NS (3 << I2C_CTRLA_SDAHOLD_SHIFT) /* 400-800ns hold time */ +#define I2C_CTRLA_SEXTTOEN (1 << 23) /* Bit 23: Slave SCL low extend time-out */ +#define I2C_CTRLA_SPEED_SHIFT (24) /* Bits 24-25: Trnasfer speed */ +#define I2C_CTRLA_SPEED_MASK (3 << I2C_CTRLA_SPEED_SHIFT) +# define I2C_CTRLA_SPEED_STD (0 << I2C_CTRLA_SPEED_SHIFT) /* Standard (<=100KHz) fast <=400KHz */ +# define I2C_CTRLA_SPEED_FAST (1 << I2C_CTRLA_SPEED_SHIFT) /* Fast-mode plase (<=1MHz) */ +# define I2C_CTRLA_SPEED_HIGH (2 << I2C_CTRLA_SPEED_SHIFT) /* High-speed mode (<=3.4Mhz */ +#define I2C_CTRLA_SCLSM (1 << 27) /* Bit 27: SCL clock stretch mode */ +#define I2C_CTRLA_LOWTOUT (1 << 30) /* Bit 30: SCL Low Time-Out */ + +/* Control B register */ + +#define I2C_CTRLB_SMEN (1 << 8) /* Bit 8: Smart Mode Enable */ +#define I2C_CTRLB_GCMD (1 << 9) /* Bit 9: PMBus group commend */ +#define I2C_CTRLB_AACKEN (1 << 10) /* Bit 10: Automatic acknowledge enable */ +#define I2C_CRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */ +#define I2C_CRLB_AMODE_MASK (3 << I2C_CRLB_AMODE_SHIFT) +# define I2C_CRLB_AMODE_MASK (0 << I2C_CRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */ +# define I2C_CRLB_AMODE_2ADDRS (1 << I2C_CRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */ +# define I2C_CRLB_AMODE_RANGE (2 << I2C_CRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */ +#define I2C_CTRLB_CMD_SHIFT (16) /* Bits 16-17: Command */ +#define I2C_CTRLB_CMD_MASK (3 << I2C_CTRLB_CMD_SHIFT) +# define I2C_CTRLB_CMD_NOACTION (0 << I2C_CTRLB_CMD_SHIFT) /* No action */ +# define I2C_CTRLB_CMD_WAITSTART (2 << I2C_CTRLB_CMD_SHIFT) /* ACK (write) wait for START */ +# define I2C_CTRLB_CMD_ACKREAD (3 << I2C_CTRLB_CMD_SHIFT) /* ACK with read (context dependent) */ +#define I2C_CTRLB_ACKACT (1 << 18) /* Bit 18: Acknowledge Action */ +# define I2C_CTRLB_ACK (0) /* Send ACK */ +# define I2C_CTRLB_NCK I2C_CTRLB_ACKACT /* Send NACK */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define I2C_INT_PREC (1 << 0) /* Bit 0: Stop received interrupt */ +#define I2C_INT_AMATCH (1 << 1) /* Bit 1: Address match interrupt */ +#define I2C_INT_DRDY (1 << 2) /* Bit 2: Data ready interrupt */ +#define I2C_INT_ERROR (1 << 7) /* Bit 7: Error interrupt */ + +#define I2C_INT_ALL (0x87) + +/* Synchronization busy register */ + +#define I2C_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +#define I2C_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ + +/* Address register */ + +#define SPI_ADDR_GENCEN (1 << 0) /* Bit 0: General Call Address Enable */ +#define SPI_ADDR_SHIFT (1) /* Bits 1-10: Address */ +#define SPI_ADDR_MASK (0x3ff << SPI_ADDR_SHIFT) +# define SPI_ADDR(n) ((uint32_t)(n) << SPI_ADDR_SHIFT) +#define SPI_ADDR_TENBITEN (1 << 15) /* Bit 15: */ +#define SPI_ADDRMASK_SHIFT (17) /* Bits 17-26: Address Mask */ +#define SPI_ADDRMASK_MASK (0x3ff << SPI_ADDRMASK_SHIFT) +# define SPI_ADDRMASK(n) ((uint32_t)(n) << SPI_ADDRMASK_SHIFT) + +/* Data register */ + +#define I2C_DATA_MASK (0xff) /* Bits 0-7: Data */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_I2C_SLAVE_H */ diff --git a/arch/arm/src/samdl/chip/saml_mclk.h b/arch/arm/src/samdl/chip/saml_mclk.h new file mode 100644 index 0000000000000000000000000000000000000000..731cccc30bc1b25f0786e7eea7ce103790fa96c6 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_mclk.h @@ -0,0 +1,216 @@ +/************************************************************************************ + * arch/arm/src/samdl/chip/saml_mclk.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_MCLK_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_MCLK_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* MCLK register offsets ************************************************************/ + +#define SAM_MCLK_CTRLA_OFFSET 0x0000 /* CTRLA register */ +#define SAM_MCLK_INTENCLR_OFFSET 0x0001 /* Interrupt enable clear */ +#define SAM_MCLK_INTENSET_OFFSET 0x0002 /* Interrupt enable set */ +#define SAM_MCLK_INTFLAG_OFFSET 0x0003 /* Interrupt flag status and clear */ +#define SAM_MCLK_CPUDIV_OFFSET 0x0004 /* CPU clock division */ +#define SAM_MCLK_LPDIV_OFFSET 0x0005 /* Low-power clock division */ +#define SAM_MCLK_BUPDIV_OFFSET 0x0006 /* Backup clock division */ + /* 0x0007-0x000f: Reserved */ +#define SAM_MCLK_AHBMASK_OFFSET 0x0010 /* AHB mask */ +#define SAM_MCLK_APBAMASK_OFFSET 0x0014 /* APBA mask */ +#define SAM_MCLK_APBBMASK_OFFSET 0x0018 /* APBB mask */ +#define SAM_MCLK_APBCMASK_OFFSET 0x001c /* APBC mask */ +#define SAM_MCLK_APBDMASK_OFFSET 0x0020 /* APBD mask */ +#define SAM_MCLK_APBEMASK_OFFSET 0x0024 /* APBE mask */ + +/* MCLK register addresses **********************************************************/ + +#define SAM_MCLK_CTRLA (SAM_MCLK_BASE+SAM_MCLK_CTRLA_OFFSET) +#define SAM_MCLK_INTENCLR (SAM_MCLK_BASE+SAM_MCLK_INTENCLR_OFFSET) +#define SAM_MCLK_INTENSET (SAM_MCLK_BASE+SAM_MCLK_INTENSET_OFFSET) +#define SAM_MCLK_INTFLAG (SAM_MCLK_BASE+SAM_MCLK_INTFLAG_OFFSET) +#define SAM_MCLK_CPUDIV (SAM_MCLK_BASE+SAM_MCLK_CPUDIV_OFFSET) +#define SAM_MCLK_LPDIV (SAM_MCLK_BASE+SAM_MCLK_LPDIV_OFFSET) +#define SAM_MCLK_BUPDIV (SAM_MCLK_BASE+SAM_MCLK_BUPDIV_OFFSET) + +#define SAM_MCLK_AHBMASK (SAM_MCLK_BASE+SAM_MCLK_AHBMASK_OFFSET) +#define SAM_MCLK_APBAMASK (SAM_MCLK_BASE+SAM_MCLK_APBAMASK_OFFSET) +#define SAM_MCLK_APBBMASK (SAM_MCLK_BASE+SAM_MCLK_APBBMASK_OFFSET) +#define SAM_MCLK_APBCMASK (SAM_MCLK_BASE+SAM_MCLK_APBCMASK_OFFSET) +#define SAM_MCLK_APBDMASK (SAM_MCLK_BASE+SAM_MCLK_APBDMASK_OFFSET) +#define SAM_MCLK_APBEMASK (SAM_MCLK_BASE+SAM_MCLK_APBEMASK_OFFSET) + +/* MCLK register bit definitions ****************************************************/ + +/* CTRLA register */ + +#define MCLK_CTRLA_CFDEN (1 << 2) /* Bit 2: Clock Failure Detector Enable */ +#define MCLK_CTRLA_EMCLK (1 << 4) /* Bit 4: Emergency Clock Select */ + +/* Interrupt enable clear, Interrupt enable set, and Interrupt flag status and + * clear. + */ + +#define MCLK_INT_CKRDY (1 << 0) /* Bit 0: Clock ready */ + +/* CPU clock division (8-bit divider) */ + +#define MCLK_CPUDIV_DIV1 0x01 +#define MCLK_CPUDIV_DIV2 0x02 +#define MCLK_CPUDIV_DIV4 0x04 +#define MCLK_CPUDIV_DIV8 0x08 +#define MCLK_CPUDIV_DIV16 0x10 +#define MCLK_CPUDIV_DIV32 0x20 +#define MCLK_CPUDIV_DIV64 0x40 +#define MCLK_CPUDIV_DIV128 0x80 + +/* Low-power clock division (8-bit divider) */ + +#define MCLK_LPDIV_DIV1 0x01 +#define MCLK_LPDIV_DIV2 0x02 +#define MCLK_LPDIV_DIV4 0x04 +#define MCLK_LPDIV_DIV8 0x08 +#define MCLK_LPDIV_DIV16 0x10 +#define MCLK_LPDIV_DIV32 0x20 +#define MCLK_LPDIV_DIV64 0x40 +#define MCLK_LPDIV_DIV128 0x80 + +/* Backup clock division (8-bit divider) */ + +#define MCLK_BUPDIV_DIV1 0x01 +#define MCLK_BUPDIV_DIV2 0x02 +#define MCLK_BUPDIV_DIV4 0x04 +#define MCLK_BUPDIV_DIV8 0x08 +#define MCLK_BUPDIV_DIV16 0x10 +#define MCLK_BUPDIV_DIV32 0x20 +#define MCLK_BUPDIV_DIV64 0x40 +#define MCLK_BUPDIV_DIV128 0x80 + +/* AHB mask */ + +#define MCLK_AHBMASK_APBA (1 << 0) /* Bit 0: APBA AHB clock enable */ +#define MCLK_AHBMASK_APBB (1 << 1) /* Bit 1: APBB AHB clock enable */ +#define MCLK_AHBMASK_APBC (1 << 2) /* Bit 2: APBC AHB clock enable */ +#define MCLK_AHBMASK_APBD (1 << 3) /* Bit 3: APBD AHB clock enable */ +#define MCLK_AHBMASK_APBE (1 << 4) /* Bit 4: APBE AHB clock enable */ +#define MCLK_AHBMASK_DSU (1 << 5) /* Bit 5: DSU AHB clock enable */ +#define MCLK_AHBMASK_NVMCTRL (1 << 8) /* Bit 8: NVMCTRL AHB clock enable */ +#define MCLK_AHBMASK_DMAC (1 << 11) /* Bit 11: DMAC AHB clock enable */ +#define MCLK_AHBMASK_USB (1 << 12) /* Bit 12: USB AHB clock enable */ +#define MCLK_AHBMASK_PAC (1 << 14) /* Bit 14: PAC AHB clock enable */ + +/* APBA mask */ + +#define MCLK_APBAMASK_PM (1 << 0) /* Bit 0: PM APBA clock enable */ +#define MCLK_APBAMASK_MCLK (1 << 1) /* Bit 1: MCLK APBA clock enable */ +#define MCLK_APBAMASK_RSTC (1 << 2) /* Bit 2: RSTC APBA clock enable */ +#define MCLK_APBAMASK_OSCCTRL (1 << 3) /* Bit 3: OSCCTRL APBA clock enable */ +#define MCLK_APBAMASK_OSC32KCTRL (1 << 4) /* Bit 4: OSC32KCTRL APBA clock enable */ +#define MCLK_APBAMASK_SUPC (1 << 5) /* Bit 5: SUPC APBA clock enable */ +#define MCLK_APBAMASK_GCLK (1 << 6) /* Bit 6: GCLK APBA clock enable */ +#define MCLK_APBAMASK_WDT (1 << 7) /* Bit 7: WDT APBA clock enable */ +#define MCLK_APBAMASK_RTC (1 << 8) /* Bit 8: RTC APBA clock enable */ +#define MCLK_APBAMASK_EIC (1 << 9) /* Bit 9: EIC APBA clock enable */ +#define MCLK_APBAMASK_PORT (1 << 10) /* Bit 10: PORT APBA clock enable */ + +/* APBB mask */ + +#define MCLK_APBBMASK_USB (1 << 0) /* Bit 0: USB APBB clock enable */ +#define MCLK_APBBMASK_DSU (1 << 1) /* Bit 1: DSU APBB clock enable */ +#define MCLK_APBBMASK_NVMCTRL (1 << 2) /* Bit 2: NVMCTRL APBB clock enable */ + +/* APBC mask */ + +#define MCLK_APBCMASK_SERCOM(n) (1 << (n)) /* Bit n: SERCOMn APBC clock enable, n=0-4 */ +# define MCLK_APBCMASK_SERCOM0 (1 << 0) /* Bit 0: SERCOM0 APBC clock enable */ +# define MCLK_APBCMASK_SERCOM1 (1 << 1) /* Bit 1: SERCOM1 APBC clock enable */ +# define MCLK_APBCMASK_SERCOM2 (1 << 2) /* Bit 2: SERCOM2 APBC clock enable */ +# define MCLK_APBCMASK_SERCOM3 (1 << 3) /* Bit 3: SERCOM3 APBC clock enable */ +# define MCLK_APBCMASK_SERCOM4 (1 << 4) /* Bit 4: SERCOM4 APBC clock enable */ +#define MCLK_APBCMASK_TCC0 (1 << 5) /* Bit 5: TCC0 APBC clock enable */ +#define MCLK_APBCMASK_TCC1 (1 << 6) /* Bit 6: TCC1 APBC clock enable */ +#define MCLK_APBCMASK_TCC2 (1 << 7) /* Bit 7: TCC2 APBC clock enable */ +#define MCLK_APBCMASK_TC0 (1 << 8) /* Bit 8: TC0 APBC clock enable */ +#define MCLK_APBCMASK_TC1 (1 << 9) /* Bit 9: TC1 APBC clock enable */ +#define MCLK_APBCMASK_TC2 (1 << 10) /* Bit 10: TC2 APBC clock enable */ +#define MCLK_APBCMASK_TC3 (1 << 11) /* Bit 11: TC3 APBC clock enable */ +#define MCLK_APBCMASK_DAC (1 << 12) /* Bit 12: DAC APBC clock enable */ +#define MCLK_APBCMASK_AES (1 << 13) /* Bit 13: AES APBC clock enable */ +#define MCLK_APBCMASK_TRNG (1 << 14) /* Bit 14: TRNG APBC clock enable */ + +/* APBD mask */ + +#define MCLK_APBDMASK_EVSYS (1 << 0) /* Bit 0: EVSYS APBD clock enable */ +#define MCLK_APBDMASK_SERCOM5 (1 << 1) /* Bit 1: SERCOM5 APBD clock enable */ +#define MCLK_APBDMASK_TC4 (1 << 2) /* Bit 2: TC4 APBD clock enable */ +#define MCLK_APBDMASK_ADC (1 << 3) /* Bit 3: ADC APBD clock enable */ +#define MCLK_APBDMASK_AC (1 << 4) /* Bit 4: AC APBD clock enable */ +#define MCLK_APBDMASK_PTC (1 << 5) /* Bit 5: PTC APBD clock enable */ +#define MCLK_APBDMASK_OPAMP (1 << 6) /* Bit 6: OpAmp APBD clock enable */ +#define MCLK_APBDMASK_CCL (1 << 7) /* Bit 7: CCL APBD clock enable */ + +/* APBE mask */ + +#define MCLK_APBEMASK_PAC (1 << 0) /* Bit 0: PAC APBE clock enable */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_MCLK_H */ diff --git a/arch/arm/src/samdl/chip/saml_nvmctrl.h b/arch/arm/src/samdl/chip/saml_nvmctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..4d6a2f3b792abce9ebb11c750b6ddd18afb5b559 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_nvmctrl.h @@ -0,0 +1,176 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_nvmctrl.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_NVMCTRL_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_NVMCTRL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* NVMCTRL register offsets *****************************************************************/ + +#define SAM_NVMCTRL_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_NVMCTRL_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_NVMCTRL_PARAM_OFFSET 0x0008 /* NVM parameter register */ +#define SAM_NVMCTRL_INTENCLR_OFFSET 0x000c /* Interrupt clear register */ +#define SAM_NVMCTRL_INTENSET_OFFSET 0x0010 /* Interrupt set register */ +#define SAM_NVMCTRL_INTFLAG_OFFSET 0x0014 /* Interface flags status and clear register */ +#define SAM_NVMCTRL_STATUS_OFFSET 0x0018 /* Status register */ +#define SAM_NVMCTRL_ADDR_OFFSET 0x001c /* Address register */ +#define SAM_NVMCTRL_LOCK_OFFSET 0x0020 /* Lock section register */ + +/* NVMCTRL register addresses ***************************************************************/ + +#define SAM_NVMCTRL_CTRLA (SAM_NVMCTRL_BASE+SAM_NVMCTRL_CTRLA_OFFSET) +#define SAM_NVMCTRL_CTRLB (SAM_NVMCTRL_BASE+SAM_NVMCTRL_CTRLB_OFFSET) +#define SAM_NVMCTRL_INTENCLR (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTENCLR_OFFSET) +#define SAM_NVMCTRL_INTENSET (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTENSET_OFFSET) +#define SAM_NVMCTRL_INTFLAG (SAM_NVMCTRL_BASE+SAM_NVMCTRL_INTFLAG_OFFSET) +#define SAM_NVMCTRL_STATUS (SAM_NVMCTRL_BASE+SAM_NVMCTRL_STATUS_OFFSET) +#define SAM_NVMCTRL_ADDR (SAM_NVMCTRL_BASE+SAM_NVMCTRL_ADDR_OFFSET) +#define SAM_NVMCTRL_LOCK (SAM_NVMCTRL_BASE+SAM_NVMCTRL_LOCK_OFFSET) + +/* NVMCTRL register bit definitions *********************************************************/ + +/* Control A register */ + +#define NVMCTRL_CTRLA_CMD_SHIFT (0) /* Bits 0-6: Command */ +#define NVMCTRL_CTRLA_CMD_MASK (0x7f << NVMCTRL_CTRLA_CMD_SHIFT) +# define NVMCTRL_CTRLA_CMD_ER (0x02 << NVMCTRL_CTRLA_CMD_SHIFT) /* Erase Row */ +# define NVMCTRL_CTRLA_CMD_WP (0x04 << NVMCTRL_CTRLA_CMD_SHIFT) /* Write Page */ +# define NVMCTRL_CTRLA_CMD_EAR (0x05 << NVMCTRL_CTRLA_CMD_SHIFT) /* Erase Auxiliary Row */ +# define NVMCTRL_CTRLA_CMD_WAP (0x06 << NVMCTRL_CTRLA_CMD_SHIFT) /* Write Auxiliary Page */ +# define NVMCTRL_CTRLA_CMD_RWWEEER (0x1a << NVMCTRL_CTRLA_CMD_SHIFT) /* RWWEE Erase Row */ +# define NVMCTRL_CTRLA_CMD_RWWEEWP (0x1a << NVMCTRL_CTRLA_CMD_SHIFT) /* RWWEE Write page */ +# define NVMCTRL_CTRLA_CMD_LR (0x40 << NVMCTRL_CTRLA_CMD_SHIFT) /* Lock Region */ +# define NVMCTRL_CTRLA_CMD_UR (0x41 << NVMCTRL_CTRLA_CMD_SHIFT) /* Unlock Region */ +# define NVMCTRL_CTRLA_CMD_SPRM (0x42 << NVMCTRL_CTRLA_CMD_SHIFT) /* Set power reduction mode */ +# define NVMCTRL_CTRLA_CMD_CPRM (0x43 << NVMCTRL_CTRLA_CMD_SHIFT) /* Clear power reduction mode */ +# define NVMCTRL_CTRLA_CMD_PBC (0x44 << NVMCTRL_CTRLA_CMD_SHIFT) /* Page Buffer Clear */ +# define NVMCTRL_CTRLA_CMD_SSB (0x45 << NVMCTRL_CTRLA_CMD_SHIFT) /* Set Security Bit */ +# define NVMCTRL_CTRLA_CMD_INVALL (0x46 << NVMCTRL_CTRLA_CMD_SHIFT) /* Invalidate all cache lines */ +#define NVMCTRL_CTRLA_CMDEX_SHIFT (8) /* Bits 8-15: Command Execution */ +#define NVMCTRL_CTRLA_CMDEX_MASK (0xff << NVMCTRL_CTRLA_CMDEX_SHIFT) +# define NVMCTRL_CTRLA_CMDEX (0xa5 << NVMCTRL_CTRLA_CMDEX_SHIFT) + +/* Control B register */ + +#define NVMCTRL_CTRLB_RWS_SHIFT (1) /* Bits 1-4: NVM Read Wait States */ +#define NVMCTRL_CTRLB_RWS_MASK (15 << NVMCTRL_CTRLB_RWS_SHIFT) +# define NVMCTRL_CTRLB_RWS(n) ((uint32_t)(n) << NVMCTRL_CTRLB_RWS_SHIFT) +#define NVMCTRL_CTRLB_MANW (1 << 7) /* Bit 7: Manual Write */ +#define NVMCTRL_CTRLB_SLEEPPRM_SHIFT (8) /* Bits 8-9: Power Reduction Mode during Sleep */ +#define NVMCTRL_CTRLB_SLEEPPRM_MASK (3 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) +# define NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS (0 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Exit low power on first access */ +# define NVMCTRL_CTRLB_SLEEPPRM_WAKEUPINSTANT (1 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Exit low power when exit sleep */ +# define NVMCTRL_CTRLB_SLEEPPRM_DISABLED (3 << NVMCTRL_CTRLB_SLEEPPRM_SHIFT) /* Auto power reduction disabled */ +#define NVMCTRL_CTRLB_READMODE_SHIFT (16) /* Bits 16-17: NVMCTRL Read Mode */ +#define NVMCTRL_CTRLB_READMODE_MASK (3 << NVMCTRL_CTRLB_READMODE_SHIFT) +# define NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY (0 << NVMCTRL_CTRLB_READMODE_SHIFT) /* No extra wait states on miss */ +# define NVMCTRL_CTRLB_READMODE_LOW_POWER (1 << NVMCTRL_CTRLB_READMODE_SHIFT) /* Insert wait/reduce power */ +# define NVMCTRL_CTRLB_READMODE_DETERMINISTIC (2 << NVMCTRL_CTRLB_READMODE_SHIFT) /* Same wait on all access */ +#define NVMCTRL_CTRLB_CACHEDIS (1 << 18) /* Bit 18: Cache Disable */ + +/* NVM parameter register */ + +#define NVMCTRL_PARAM_NVMP_SHIFT (0) /* Bits 0-15: NVM Pages */ +#define NVMCTRL_PARAM_NVMP_MASK (0xffff << NVMCTRL_PARAM_NVMP_SHIFT) +# define NVMCTRL_PARAM_NVMP(n) ((uint32_t)(n) << NVMCTRL_PARAM_NVMP_SHIFT) +#define NVMCTRL_PARAM_PSZ_SHIFT (16) /* Bits 16-18: Page Size */ +#define NVMCTRL_PARAM_PSZ_MASK (7 << NVMCTRL_PARAM_PSZ_SHIFT) +# define NVMCTRL_PARAM_PSZ_8B (0 << NVMCTRL_PARAM_PSZ_SHIFT) /* 8 bytes */ +# define NVMCTRL_PARAM_PSZ_16B (1 << NVMCTRL_PARAM_PSZ_SHIFT) /* 16 bytes */ +# define NVMCTRL_PARAM_PSZ_32B (2 << NVMCTRL_PARAM_PSZ_SHIFT) /* 32 bytes */ +# define NVMCTRL_PARAM_PSZ_64B (3 << NVMCTRL_PARAM_PSZ_SHIFT) /* 64 bytes */ +# define NVMCTRL_PARAM_PSZ_128B (4 << NVMCTRL_PARAM_PSZ_SHIFT) /* 128 bytes */ +# define NVMCTRL_PARAM_PSZ_256B (5 << NVMCTRL_PARAM_PSZ_SHIFT) /* 256 bytes */ +# define NVMCTRL_PARAM_PSZ_512B (6 << NVMCTRL_PARAM_PSZ_SHIFT) /* 512 bytes */ +# define NVMCTRL_PARAM_PSZ_1KB (7 << NVMCTRL_PARAM_PSZ_SHIFT) /* 1024 bytes */ +#define NVMCTRL_PARAM_RWWEEP_SHIFT (20) /* Bits 20-31: Read while write EEPROM emulation area pages */ +#define NVMCTRL_PARAM_RWWEEP_MASK (0xfff << NVMCTRL_PARAM_RWWEEP_SHIFT) +# define NVMCTRL_PARAM_RWWEEP(n) ((uint32_t)(n) << NVMCTRL_PARAM_RWWEEP_SHIFT) + +/* Interrupt clear register */ +/* Interrupt set register */ +/* Interface flags status and clear register */ + +#define NVMCTRL_INT_READY (1 << 0) /* Bit 0: NVM Ready Interrupt */ +#define NVMCTRL_INT_ERROR (1 << 1) /* Bit 1: Error Interrupt */ + +/* Status register */ + +#define NVMCTRL_STATUS_PRM (1 << 0) /* Bit 0: Power Reduction Mode */ +#define NVMCTRL_STATUS_LOAD (1 << 1) /* Bit 1: NVM Page Buffer Active Loading */ +#define NVMCTRL_STATUS_PROGE (1 << 2) /* Bit 2: Programming Error Status */ +#define NVMCTRL_STATUS_LOCKE (1 << 3) /* Bit 3: Lock Error Status */ +#define NVMCTRL_STATUS_NVME (1 << 4) /* Bit 4: NVM Error */ +#define NVMCTRL_STATUS_SB (1 << 8) /* Bit 8: Security Bit Status */ + +/* Address register */ + +#define NVMCTRL_ADDR_MASK (0x001fffff) /* Bits 0-20: NVM Address */ + +/* Lock section register */ + +#define NVMCTRL_LOCK_REGION(n) (1 << (n)) /* Region n is locked */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_NVMCTRL_H */ diff --git a/arch/arm/src/samdl/chip/saml_opamp.h b/arch/arm/src/samdl/chip/saml_opamp.h new file mode 100644 index 0000000000000000000000000000000000000000..661f235a4e524097531cfef49ac609e95cf5f8f0 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_opamp.h @@ -0,0 +1,153 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_opamp.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OPAMP_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OPAMP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* OPAMP register offsets ********************************************************************/ + +#define SAM_OPAMP_CTRLA_OFFSET 0x0000 /* Control A Register */ +#define SAM_OPAMP_STATUS_OFFSET 0x0002 /* Status Register */ +#define SAM_OPAMP_CTRL0_OFFSET 0x0004 /* OPAMP Control 0 Register */ +#define SAM_OPAMP_CTRL1_OFFSET 0x0008 /* OPAMP Control 1 Register */ +#define SAM_OPAMP_CTRL2_OFFSET 0x000c /* OPAMP Control 2 Register */ + +/* OPAMP register addresses ******************************************************************/ + +#define SAM_OPAMP_CTRLA (SAM_OPAMP_BASE+SAM_OPAMP_CTRLA_OFFSET) +#define SAM_OPAMP_STATUS (SAM_OPAMP_BASE+SAM_OPAMP_STATUS_OFFSET) +#define SAM_OPAMP_CTRL0 (SAM_OPAMP_BASE+SAM_OPAMP_CTRL0_OFFSET) +#define SAM_OPAMP_CTRL1 (SAM_OPAMP_BASE+SAM_OPAMP_CTRL1_OFFSET) +#define SAM_OPAMP_CTRL2 (SAM_OPAMP_BASE+SAM_OPAMP_CTRL2_OFFSET) + +/* OPAMP register bit definitions ************************************************************/ + +/* Control A Register */ + +#define OPAMP_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define OPAMP_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define OPAMP_CTRLA_LPMUX (1 << 7) /* Bit 7: Low-power mux */ + +/* Status Register */ + +#define OPAMP_STATUS_READY0 (1 << 0) /* Bit 0: OPAMP 0 ready */ +#define OPAMP_STATUS_READY1 (1 << 1) /* Bit 1: OPAMP 1 ready */ +#define OPAMP_STATUS_READY2 (1 << 2) /* Bit 2: OPAMP 2 ready */ + +/* OPAMP Control 0-2 Register */ + +#define OPAMP_CTRL_ENABLE (1 << 1) /* Bit 1: Operation amplifier enable */ +#define OPAMP_CTRL_ANAOUT (1 << 2) /* Bit 2: Analog output */ +#define OPAMP_CTRL_BIAS_SHIFT (3) /* Bits 3-5: Bias selection */ +#define OPAMP_CTRL_BIAS_MASK (7 << OPAMP_CTRL_BIAS_SHIFT) +# define OPAMP_CTRL_BIAS_MODE0 (0 << OPAMP_CTRL_BIAS_SHIFT) /* Minimum current, slowest mode */ +# define OPAMP_CTRL_BIAS_MODE1 (1 << OPAMP_CTRL_BIAS_SHIFT) /* Low current, slow */ +# define OPAMP_CTRL_BIAS_MODE2 (2 << OPAMP_CTRL_BIAS_SHIFT) /* High current, fast */ +# define OPAMP_CTRL_BIAS_MODE3 (3 << OPAMP_CTRL_BIAS_SHIFT) /* Maximum current, fastest mode */ +#define OPAMP_CTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OPAMP_CTRL_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OPAMP_CTRL_RES2OUT (1 << 8) /* Bit 8: Resistor ladder to output */ +#define OPAMP_CTRL_RES2VCC (1 << 9) /* Bit 9: Resistor ladder to VCC */ +#define OPAMP_CTRL_RES1EN (1 << 10) /* Bit 10: Resistor 1 enable */ +#define OPAMP_CTRL_RES1MUX_SHIFT (11) /* Bits 11-12: Resistor 1 mux */ +#define OPAMP_CTRL_RES1MUX_MASK (3 << OPAMP_CTRL_RES1MUX_MASK) +# define OPAMP_CTRL_RES1MUX_OAxPOS (0 << OPAMP_CTRL_RES1MUX_MASK) /* Positive input of OPAMPn, n=0,1,2 */ +# define OPAMP_CTRL_RES1MUX_OAxNEG (1 << OPAMP_CTRL_RES1MUX_MASK) /* Negative input of OPAMPn, n=0,1,2 */ +# define OPAMP_CTRL_RES1MUX_DAC_0 (2 << OPAMP_CTRL_RES1MUX_MASK) /* DAC output, OPAMP0 */ +# define OPAMP_CTRL_RES1MUX_OA0OUT_1 (2 << OPAMP_CTRL_RES1MUX_MASK) /* OPAMP0 output, OPAMP1 */ +# define OPAMP_CTRL_RES1MUX_OA1OUT_2 (2 << OPAMP_CTRL_RES1MUX_MASK) /* OPAMP1 output, OPAMP2 */ +# define OPAMP_CTRL_RES1MUX_GND (3 << OPAMP_CTRL_RES1MUX_MASK) /* Ground, OPAMPn, n=0,1,2 */ +#define OPAMP_CTRL_POTMUX_SHIFT (13) /* Bits 13-15: Potentiometer selection */ +#define OPAMP_CTRL_POTMUX_MASK (7 << OPAMP_CTRL_POTMUX_SHIFT) +# define OPAMP_CTRL_POTMUX_14R_2R (0 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 1/7 */ +# define OPAMP_CTRL_POTMUX_12R_4R (1 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 1/3 */ +# define OPAMP_CTRL_POTMUX_8R_8R (2 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 1 */ +# define OPAMP_CTRL_POTMUX_6R_10R (3 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 1+2/3 */ +# define OPAMP_CTRL_POTMUX_4R_12R (4 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 3 */ +# define OPAMP_CTRL_POTMUX_3R_13R (5 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 4+1/3 */ +# define OPAMP_CTRL_POTMUX_2R_14R (6 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 7 */ +# define OPAMP_CTRL_POTMUX_R_15R (7 << OPAMP_CTRL_POTMUX_SHIFT) /* Gain 15 */ +#define OPAMP_CTRL_MUXPOS_SHIFT (16) /* Bits 16-18: Positive input mux selection */ +#define OPAMP_CTRL_MUXPOS_MASK (7 << OPAMP_CTRL_MUXPOS_SHIFT) +# define OPAMP_CTRL_MUXPOS_OAxPOS (0 << OPAMP_CTRL_MUXPOS_SHIFT) /* Positive I/O pin, OPAMPn, n=0,1,2 */ +# define OPAMP_CTRL_MUXPOS_OAxTAP (1 << OPAMP_CTRL_MUXPOS_SHIFT) /* Resister ladder x taps, OPAMPn, n=0,1,2 */ +# define OPAMP_CTRL_MUXPOS_DAC_0 (2 << OPAMP_CTRL_MUXPOS_SHIFT) /* DAC ouput, OPAMP0 */ +# define OPAMP_CTRL_MUXPOS_OA0OUT_1 (2 << OPAMP_CTRL_MUXPOS_SHIFT) /* OPAMP0 output, OPAMP1 */ +# define OPAMP_CTRL_MUXPOS_OA1OUT_2 (2 << OPAMP_CTRL_MUXPOS_SHIFT) /* OPAMP1 output, OPAMP2 */ +# define OPAMP_CTRL_MUXPOS_GND (3 << OPAMP_CTRL_MUXPOS_SHIFT) /* Ground, OPAMPn, n=0,1,2 */ +# define OPAMP_CTRL_MUXPOS_OA0POS_2 (4 << OPAMP_CTRL_MUXPOS_SHIFT) /* Positive I/O pin OPA0, OPAMP2 */ +# define OPAMP_CTRL_MUXPOS_OA1POS_2 (5 << OPAMP_CTRL_MUXPOS_SHIFT) /* Positive I/O pin OPA1, OPAMP2 */ +# define OPAMP_CTRL_MUXPOS_OA0TAP_2 (6 << OPAMP_CTRL_MUXPOS_SHIFT) /* Resistor ladder 0 taps, OPAMP2 */ +#define OPAMP_CTRL_MUXNEG_SHIFT (20) /* Bits 20-22: Negative input mux selection */ +#define OPAMP_CTRL_MUXNEG_MASK (7 << OPAMP_CTRL_MUXNEG_SHIFT) +# define OPAMP_CTRL_MUXNEG_OAxNEG (0 << OPAMP_CTRL_MUXNEG_SHIFT) /* Negative I/O pin OPAMP n, n=0,1,2 */ +# define OPAMP_CTRL_MUXNEG_OAxTAP (1 << OPAMP_CTRL_MUXNEG_SHIFT) /* Resister laddr x tap OPAMP n, n=0,1,2 */ +# define OPAMP_CTRL_MUXNEG_OAxOUT (2 << OPAMP_CTRL_MUXNEG_SHIFT) /* OPAMPn output, n=0,1,2 */ +# define OPAMP_CTRL_MUXNEG_DAC_01 (3 << OPAMP_CTRL_MUXNEG_SHIFT) /* DAC output, OPAMP0,1 */ +# define OPAMP_CTRL_MUXNEG_OA0NEG_2 (3 << OPAMP_CTRL_MUXNEG_SHIFT) /* Negative I/O pin OPA0, OPAMP2 */ +# define OPAMP_CTRL_MUXNEG_OA1NEG_2 (4 << OPAMP_CTRL_MUXNEG_SHIFT) /* Negative I/O OPA1, OPAMP2 */ +# define OPAMP_CTRL_MUXNEG_DAC_2 (5 << OPAMP_CTRL_MUXNEG_SHIFT) /* DAC output, OPAMP2 */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OPAMP_H */ diff --git a/arch/arm/src/samdl/chip/saml_osc32kctrl.h b/arch/arm/src/samdl/chip/saml_osc32kctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..5f2023e1687097158ca2db59fe8d37ab8a29fe22 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_osc32kctrl.h @@ -0,0 +1,164 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_osc32kctrl.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSC32KCTRL_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSC32KCTRL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* OSC32KCTRL register offsets **************************************************************/ + +#define SAM_OSC32KCTRL_INTENCLR_OFFSET 0x0000 /* Interrupt enable clear */ +#define SAM_OSC32KCTRL_INTENSET_OFFSET 0x0004 /* Interrupt enable set */ +#define SAM_OSC32KCTRL_INTFLAG_OFFSET 0x0008 /* Interrupt flag status and clear */ +#define SAM_OSC32KCTRL_STATUS_OFFSET 0x000c /* Status */ +#define SAM_OSC32KCTRL_RTCCTRL_OFFSET 0x0010 /* RTC clock selection */ +#define SAM_OSC32KCTRL_XOSC32K_OFFSET 0x0014 /* 32kHz external crystal oscillator control */ +#define SAM_OSC32KCTRL_OSC32K_OFFSET 0x0018 /* 32kHz internal oscillator control */ +#define SAM_OSC32KCTRL_OSCULP32K_OFFSET 0x001c /* 32kHz ultra low power internal oscillator control */ + + +/* OSC32KCTRL register addresses ************************************************************/ + +#define SAM_OSC32KCTRL_INTENCLR (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_INTENCLR_OFFSET) +#define SAM_OSC32KCTRL_INTENSET (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_INTENSET_OFFSET) +#define SAM_OSC32KCTRL_INTFLAG (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_INTFLAG_OFFSET) +#define SAM_OSC32KCTRL_STATUS (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_STATUS_OFFSET) +#define SAM_OSC32KCTRL_RTCCTRL (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_RTCCTRL_OFFSET) +#define SAM_OSC32KCTRL_XOSC32K (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_XOSC32K_OFFSET) +#define SAM_OSC32KCTRL_OSC32K (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_OSC32K_OFFSET) +#define SAM_OSC32KCTRL_OSCULP32K (SAM_OSC32KCTRL_BASE+SAM_OSC32KCTRL_OSCULP32K_OFFSET) + +/* OSC32KCTRL register bit definitions ******************************************************/ + +/* Interrupt enable clear, Interrupt enable set, Interrupt flag status and clear, and + * status registers. + */ + +#define OSC32KCTRL_INT_XOSC32KRDY (1 << 0) /* Bit 0: XOSC32K ready interrupt */ +#define OSC32KCTRL_INT_OSC32KRDY (1 << 1) /* Bit 1: OSC32K ready interrupt */ + +#define OSC32KCTRL_INT_ALL (0x00000003) + +/* RTC clock selection */ + +#define OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT (0) /* Bits 0-2: RTC clock source selection */ +#define OSC32KCTRL_RTCCTRL_RTCSEL_MASK (7 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) +# define OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K (0 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 1.024KHz from 32HKz internal ULP oscillator */ +# define OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K (1 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 32.768KHz from 32KHz internal ULP oscillator */ +# define OSC32KCTRL_RTCCTRL_RTCSEL_OSC1K (2 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 1.024KHz for 32KHz internal oscillator */ +# define OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K (3 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 1.024KHz for 32KHz external oscillator */ +# define OSC32KCTRL_RTCCTRL_RTCSEL_OSC32K (4 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 32.768KHz from 32KHz external oscillator */ +# define OSC32KCTRL_RTCCTRL_RTCSEL_XOSC312K (5 << OSC32KCTRL_RTCCTRL_RTCSEL_SHIFT) /* 32.768KHz from 32KHz external crystal oscillator */ + +/* 32kHz external crystal oscillator control register */ + +#define OSC32KCTRL_XOSC32K_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define OSC32KCTRL_XOSC32K_XTALEN (1 << 2) /* Bit 2: Crystal oscillator enable */ +#define OSC32KCTRL_XOSC32K_EN32K (1 << 3) /* Bit 3: 32kHz Output enable */ +#define OSC32KCTRL_XOSC32K_EN1K (1 << 4) /* Bit 4: 1kHz Output enable */ +#define OSC32KCTRL_XOSC32K_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSC32KCTRL_XOSC32K_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OSC32KCTRL_XOSC32K_STARTUP_SHIFT (8) /* Bits 8-10: Oscillator start-up time */ +#define OSC32KCTRL_XOSC32K_STARTUP_MASK (7 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) +# define OSC32KCTRL_XOSC32K_STARTUP(n) ((n) << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) +# define OSC32KCTRL_XOSC32K_STARTUP_63MS (0 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 62.592 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_125MS (1 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 125.092 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_500MS (2 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 500.092 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_100MS (3 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 100.0092 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_200MS (4 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 200.0092 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_400MS (5 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 400.092 msec */ +# define OSC32KCTRL_XOSC32K_STARTUP_800MS (6 << OSC32KCTRL_XOSC32K_STARTUP_SHIFT) /* 800.0092 msec */ +#define OSC32KCTRL_XOSC32K_WRTLOCK (1 << 12) /* Bit 12: Write lock */ + +/* 32kHz internal oscillator control register */ + +#define OSC32KCTRL_OSC32K_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define OSC32KCTRL_OSC32K_EN32K (1 << 2) /* Bit 2: 32kHz Output enable */ +#define OSC32KCTRL_OSC32K_EN1K (1 << 3) /* Bit 3: 1kHz Output enable */ +#define OSC32KCTRL_OSC32K_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSC32KCTRL_OSC32K_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OSC32KCTRL_OSC32K_STARTUP_SHIFT (8) /* Bits 8-10: Oscillator start-up time */ +#define OSC32KCTRL_OSC32K_STARTUP_MASK (7 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) +# define OSC32KCTRL_OSC32K_STARTUP(n) ((n) << OSC32KCTRL_OSC32K_STARTUP_SHIFT) +# define OSC32KCTRL_OSC32K_STARTUP_92US (0 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 92µs */ +# define OSC32KCTRL_OSC32K_STARTUP_122US (1 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 122µs */ +# define OSC32KCTRL_OSC32K_STARTUP_183US (2 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 183µs */ +# define OSC32KCTRL_OSC32K_STARTUP_305US (3 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 305µs */ +# define OSC32KCTRL_OSC32K_STARTUP_549US (4 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 549µs */ +# define OSC32KCTRL_OSC32K_STARTUP_1MS (5 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 1038µs */ +# define OSC32KCTRL_OSC32K_STARTUP_2MS (6 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 2014µs */ +# define OSC32KCTRL_OSC32K_STARTUP_4MS (7 << OSC32KCTRL_OSC32K_STARTUP_SHIFT) /* 3967µs */ +#define OSC32KCTRL_OSC32K_WRTLOCK (1 << 12) /* Bit 12: Write lock */ +#define OSC32KCTRL_OSC32K_CALIB_SHIFT (16) /* Bits 16-22: Oscillator calibration */ +#define OSC32KCTRL_OSC32K_CALIB_MASK (0x7f << OSC32KCTRL_OSC32K_CALIB_SHIFT) +# define OSC32KCTRL_OSC32K_CALIB(n) ((n) << OSC32KCTRL_OSC32K_CALIB_SHIFT) + +/* 32kHz ultra low power internal oscillator control register */ + +#define OSC32KCTRL_OSCULP32K_CALIB_SHIFT (8) /* Bits 0-12: Oscillator Calibration */ +#define OSC32KCTRL_OSCULP32K_CALIB_MASK (31 << OSC32KCTRL_OSCULP32K_CALIB_SHIFT) +# define OSC32KCTRL_OSCULP32K_CALIB(n) ((n) << OSC32KCTRL_OSCULP32K_CALIB_SHIFT) +#define OSC32KCTRL_OSCULP32K_WRTLOCK (1 << 7) /* Bit 7: Write Lock */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSC32KCTRL_H */ diff --git a/arch/arm/src/samdl/chip/saml_oscctrl.h b/arch/arm/src/samdl/chip/saml_oscctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..9afa83f934a4c9727188c353bed037cf5e7be617 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_oscctrl.h @@ -0,0 +1,305 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_oscctrl.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSCCTRL_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSCCTRL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* OSCCTRL register offsets *****************************************************************/ + +#define SAM_OSCCTRL_INTENCLR_OFFSET 0x0000 /* Interrupt enable clear */ +#define SAM_OSCCTRL_INTENSET_OFFSET 0x0004 /* Interrupt enable set */ +#define SAM_OSCCTRL_INTFLAG_OFFSET 0x0008 /* Interrupt flag status and clear */ +#define SAM_OSCCTRL_STATUS_OFFSET 0x000c /* Status */ +#define SAM_OSCCTRL_XOSCCTRL_OFFSET 0x0010 /* External multi-purpose crystal oscillator control */ +#define SAM_OSCCTRL_OSC16MCTRL_OFFSET 0x0014 /* 16MHz internal oscillator control */ +#define SAM_OSCCTRL_DFLLCTRL_OFFSET 0x0018 /* DFLL48M control */ +#define SAM_OSCCTRL_DFLLVAL_OFFSET 0x001c /* DFLL48M value */ +#define SAM_OSCCTRL_DFLLMUL_OFFSET 0x0020 /* DFLL48M multiplier */ +#define SAM_OSCCTRL_DFLLSYNC_OFFSET 0x0024 /* DFLL48M synchronization */ +#define SAM_OSCCTRL_DPLLCTRLA_OFFSET 0x0028 /* DPLL control A */ +#define SAM_OSCCTRL_DPLLRATIO_OFFSET 0x002c /* DPLL ratio control */ +#define SAM_OSCCTRL_DPLLCTRLB_OFFSET 0x0030 /* DPLL control B */ +#define SAM_OSCCTRL_DPLLPRESC_OFFSET 0x0034 /* DPLL prescaler */ +#define SAM_OSCCTRL_DPLLSYNCBUSY_OFFSET 0x0038 /* DPLL synchronization busy */ +#define SAM_OSCCTRL_DPLLSTATUS_OFFSET 0x003c /* DPLL status */ + +/* OSCCTRL register addresses ***************************************************************/ + +#define SAM_OSCCTRL_INTENCLR (SAM_OSCCTRL_BASE+SAM_OSCCTRL_INTENCLR_OFFSET) +#define SAM_OSCCTRL_INTENSET (SAM_OSCCTRL_BASE+SAM_OSCCTRL_INTENSET_OFFSET) +#define SAM_OSCCTRL_INTFLAG (SAM_OSCCTRL_BASE+SAM_OSCCTRL_INTFLAG_OFFSET) +#define SAM_OSCCTRL_STATUS (SAM_OSCCTRL_BASE+SAM_OSCCTRL_STATUS_OFFSET) +#define SAM_OSCCTRL_XOSCCTRL (SAM_OSCCTRL_BASE+SAM_OSCCTRL_XOSCCTRL_OFFSET) +#define SAM_OSCCTRL_OSC16MCTRL (SAM_OSCCTRL_BASE+SAM_OSCCTRL_OSC16MCTRL_OFFSET) +#define SAM_OSCCTRL_DFLLCTRL (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DFLLCTRL_OFFSET) +#define SAM_OSCCTRL_DFLLVAL (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DFLLVAL_OFFSET) +#define SAM_OSCCTRL_DFLLMUL (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DFLLMUL_OFFSET) +#define SAM_OSCCTRL_DFLLSYNC (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DFLLSYNC_OFFSET) +#define SAM_OSCCTRL_DPLLCTRLA (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLCTRLA_OFFSET) +#define SAM_OSCCTRL_DPLLRATIO (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLRATIO_OFFSET) +#define SAM_OSCCTRL_DPLLCTRLB (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLCTRLB_OFFSET) +#define SAM_OSCCTRL_DPLLPRESC (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLPRESC_OFFSET) +#define SAM_OSCCTRL_DPLLSYNCBUSY (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLSYNCBUSY_OFFSET) +#define SAM_OSCCTRL_DPLLSTATUS (SAM_OSCCTRL_BASE+SAM_OSCCTRL_DPLLSTATUS_OFFSET) + +/* OSCCTRL register bit definitions *********************************************************/ + +/* Interrupt enable clear, Interrupt enable set, Interrupt flag status and clear, and + * Status registers. + */ + +#define OSCCTRL_INT_XOSCRDY (1 << 0) /* Bit 0: XOSC ready */ +#define OSCCTRL_INT_OSC16MRDY (1 << 4) /* Bit 4: OSC16M ready */ +#define OSCCTRL_INT_DFLLRDY (1 << 8) /* Bit 8: DFLL ready */ +#define OSCCTRL_INT_DFLLOOB (1 << 9) /* Bit 9: DFLL out of bounds */ +#define OSCCTRL_INT_DFLLLCKF (1 << 10) /* Bit 10: DFLL lock fine */ +#define OSCCTRL_INT_DFLLLCKC (1 << 11) /* Bit 11: DFLL lock coarse */ +#define OSCCTRL_INT_DFLLRCS (1 << 12) /* Bit 12: DFLL reference clock stopped */ +#define OSCCTRL_INT_DPLLLCKR (1 << 16) /* Bit 16: DPLL lock rise */ +#define OSCCTRL_INT_DPLLLCKF (1 << 17) /* Bit 17: DPLL lock fall */ +#define OSCCTRL_INT_DPLLLTP (1 << 18) /* Bit 18: DPLL lock timeout */ +#define OSCCTRL_INT_DPLLDRTO (1 << 19) /* Bit 19: DPLL loop divider ratio update complete */ + +#define OSCCTRL_INT_ALL (0x000f1f11) + +/* External multi-purpose crystal oscillator control register */ + +#define OSCCTRL_XOSCCTRL_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define OSCCTRL_XOSCCTRL_XTALEN (1 << 2) /* Bit 2: Crystal oscillator enable */ +#define OSCCTRL_XOSCCTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSCCTRL_XOSCCTRL_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OSCCTRL_XOSCCTRL_GAIN_SHIFT (8) /* Bits 8-10: Oscillator gain */ +#define OSCCTRL_XOSCCTRL_GAIN_MASK (7 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) +# define OSCCTRL_XOSCCTRL_GAIN(n) ((n) << OSCCTRL_XOSCCTRL_GAIN_SHIFT) +# define OSCCTRL_XOSCCTRL_GAIN_2MHZ (0 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) /* 2MHz */ +# define OSCCTRL_XOSCCTRL_GAIN_4MHZ (1 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) /* 4MHz */ +# define OSCCTRL_XOSCCTRL_GAIN_8MHZ (2 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) /* 8MHz */ +# define OSCCTRL_XOSCCTRL_GAIN_16MHZ (3 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) /* 16MHz */ +# define OSCCTRL_XOSCCTRL_GAIN_30MHZ (4 << OSCCTRL_XOSCCTRL_GAIN_SHIFT) /* 30MHz */ +#define OSCCTRL_XOSCCTRL_AMPGC (1 << 11) /* Bit 11: Automatic amplitude gain control */ +#define OSCCTRL_XOSCCTRL_STARTUP_SHIFT (12) /* Bits 12-15: Start-up time */ +#define OSCCTRL_XOSCCTRL_STARTUP_MASK (15 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) +# define OSCCTRL_XOSCCTRL_STARTUP(n) ((n) << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) +# define OSCCTRL_XOSCCTRL_STARTUP_31US (0 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 31µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_61US (1 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 61µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_122US (2 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 122µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_244US (3 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 244µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_488US (4 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 488µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_977US (5 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 977µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_2MS (6 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 1953µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_4MS (7 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 3906µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_8MS (8 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 7813µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_16MS (9 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 15625µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_31MS (10 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 31250µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_63MS (11 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 62500µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_125MS (12 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 125000µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_250MS (13 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 250000µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_500MS (14 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 500000µs */ +# define OSCCTRL_XOSCCTRL_STARTUP_1S (15 << OSCCTRL_XOSCCTRL_STARTUP_SHIFT) /* 1000000µs */ + +/* 16MHz internal oscillator control register */ + +#define OSCCTRL_OSC16MCTRL_ENABLE (1 << 1) /* Bit 1: Oscillator enable */ +#define OSCCTRL_OSC16MCTRL_FSEL_SHIFT (2) /* Bits 2-3: Oscillator frequency selection */ +#define OSCCTRL_OSC16MCTRL_FSEL_MASK (3 << OSCCTRL_OSC16MCTRL_FSEL_SHIFT) +# define OSCCTRL_OSC16MCTRL_FSEL_4MHZ (0 << OSCCTRL_OSC16MCTRL_FSEL_SHIFT) +# define OSCCTRL_OSC16MCTRL_FSEL_8MHZ (1 << OSCCTRL_OSC16MCTRL_FSEL_SHIFT) +# define OSCCTRL_OSC16MCTRL_FSEL_12MHZ (2 << OSCCTRL_OSC16MCTRL_FSEL_SHIFT) +# define OSCCTRL_OSC16MCTRL_FSEL_16MHZ (3 << OSCCTRL_OSC16MCTRL_FSEL_SHIFT) +#define OSCCTRL_OSC16MCTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSCCTRL_OSC16MCTRL_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OSCCTRL_OSC16MCTRL_GAIN_SHIFT (8) /* Bits 8-10: Oscillator gain */ +#define OSCCTRL_OSC16MCTRL_GAIN_MASK (7 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) +# define OSCCTRL_OSC16MCTRL_GAIN(n) ((n) << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) +# define OSCCTRL_OSC16MCTRL_GAIN_2MHZ (0 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) /* 2MHz */ +# define OSCCTRL_OSC16MCTRL_GAIN_4MHZ (1 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) /* 4MHz */ +# define OSCCTRL_OSC16MCTRL_GAIN_8MHZ (2 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) /* 8MHz */ +# define OSCCTRL_OSC16MCTRL_GAIN_16MHZ (3 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) /* 16MHz */ +# define OSCCTRL_OSC16MCTRL_GAIN_30MHZ (4 << OSCCTRL_OSC16MCTRL_GAIN_SHIFT) /* 30MHz */ +#define OSCCTRL_OSC16MCTRL_AMPGC (1 << 11) /* Bit 11: Automatic amplitude gain control */ +#define OSCCTRL_OSC16MCTRL_STARTUP_SHIFT (12) /* Bits 12-15: Start-up time */ +#define OSCCTRL_OSC16MCTRL_STARTUP_MASK (15 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) +# define OSCCTRL_OSC16MCTRL_STARTUP(n) ((n) << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) +# define OSCCTRL_OSC16MCTRL_STARTUP_31US (0 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 31µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_61US (1 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 61µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_122US (2 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 122µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_244US (3 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 244µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_488US (4 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 488µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_977US (5 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 977µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_2MS (6 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 1953µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_4MS (7 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 3906µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_8MS (8 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 7813µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_16MS (9 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 15625µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_31MS (10 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 31250µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_63MS (11 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 62500µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_125MS (12 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 125000µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_250MS (13 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 250000µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_500MS (14 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 500000µs */ +# define OSCCTRL_OSC16MCTRL_STARTUP_1S (15 << OSCCTRL_OSC16MCTRL_STARTUP_SHIFT) /* 1000000µs */ + +/* DFLL48M control register */ + +#define OSCCTRL_DFLLCTRL_ENABLE (1 << 1) /* Bit 1: DFLL enable */ +#define OSCCTRL_DFLLCTRL_MODE (1 << 2) /* Bit 2: Operating mode selection */ +#define OSCCTRL_DFLLCTRL_STABLE (1 << 3) /* Bit 3: Stable DFLL frequency */ +#define OSCCTRL_DFLLCTRL_LLAW (1 << 4) /* Bit 4: Lose lock after wake */ +#define OSCCTRL_DFLLCTRL_USBCRM (1 << 5) /* Bit 5: USB clock recovery mode */ +#define OSCCTRL_DFLLCTRL_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSCCTRL_DFLLCTRL_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define OSCCTRL_DFLLCTRL_CCDIS (1 << 8) /* Bit 8: Chill cycle disable */ +#define OSCCTRL_DFLLCTRL_QLDIS (1 << 9) /* Bit 9: Quick Lock Disable */ +#define OSCCTRL_DFLLCTRL_BPLCKC (1 << 10) /* Bit 10: Bypass coarse clock */ +#define OSCCTRL_DFLLCTRL_WAITLOCK (1 << 11) /* Bit 11: Wait lock */ + +/* DFLL48M value register */ + +#define OSCCTRL_DFLLVAL_FINE_SHIFT (0) /* Bits 0-9: Fine value */ +#define OSCCTRL_DFLLVAL_FINE_MASK (0x3ff << OSCCTRL_DFLLVAL_FINE_SHIFT) +# define OSCCTRL_DFLLVAL_FINE(n) ((n) << OSCCTRL_DFLLVAL_FINE_SHIFT) +#define OSCCTRL_DFLLVAL_COARSE_SHIFT (10) /* Bits 10-15: Coarse value */ +#define OSCCTRL_DFLLVAL_COARSE_MASK (0x3f << OSCCTRL_DFLLVAL_COARSE_SHIFT) +# define OSCCTRL_DFLLVAL_COARSE(n) ((n) << OSCCTRL_DFLLVAL_COARSE_SHIFT) +#define OSCCTRL_DFLLVAL_DIFF_SHIFT (16) /* Bits 16-31: Multiplication ratio difference */ +#define OSCCTRL_DFLLVAL_DIFF_MASK (0xffff << OSCCTRL_DFLLVAL_DIFF_SHIFT) +# define OSCCTRL_DFLLVAL_DIFF(n) ((n) << OSCCTRL_DFLLVAL_DIFF_SHIFT) + +/* DFLL48M multiplier register */ + +#define OSCCTRL_DFLLMUL_MUL_SHIFT (0) /* Bits 0-15: DFLL multiply factor */ +#define OSCCTRL_DFLLMUL_MUL_MASK (0xffff << OSCCTRL_DFLLMUL_MUL_SHIFT) +# define OSCCTRL_DFLLMUL_MUL(n) ((n) << OSCCTRL_DFLLMUL_MUL_SHIFT) +#define OSCCTRL_DFLLMUL_FSTEP_SHIFT (16) /* Bits 16-25: Fine maximum step */ +#define OSCCTRL_DFLLMUL_FSTEP_MASK (0x3ff << OSCCTRL_DFLLMUL_FSTEP_SHIFT) +# define OSCCTRL_DFLLMUL_FSTEP(n) ((n) << OSCCTRL_DFLLMUL_FSTEP_SHIFT) +#define OSCCTRL_DFLLMUL_CSTEP_SHIFT (26) /* Bits 26-31: Coarse maximum step */ +#define OSCCTRL_DFLLMUL_CSTEP_MASK (0x3f << OSCCTRL_DFLLMUL_CSTEP_SHIFT) +# define OSCCTRL_DFLLMUL_CSTEP(n) ((n) << OSCCTRL_DFLLMUL_CSTEP_SHIFT) + +/* DFLL48M synchronization register */ + +#define OSCCTRL_DFLLSYNC_READREQ (1 << 7) /* Bit 7: Read request */ + +/* DPLL control A */ + +#define OSCCTRL_DPLLCTRLA_ENABLE (1 << 1) /* Bit 1: DPLL enable */ +#define OSCCTRL_DPLLCTRLA_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define OSCCTRL_DPLLCTRLA_ONDEMAND (1 << 7) /* Bit 7: On demand clock activation */ + +/* DPLL ratio control */ + +#define OSCCTRL_DPLLRATIO_LDR_SHIFT (0) /* Bits 0-11: Loop divider ratio */ +#define OSCCTRL_DPLLRATIO_LDR_MASK (0xfff << OSCCTRL_DPLLRATIO_LDR_SHIFT) +# define OSCCTRL_DPLLRATIO_LDR(n) ((uint32_t)(n) << OSCCTRL_DPLLRATIO_LDR_SHIFT) +#define OSCCTRL_DPLLRATIO_LDRFRAC_SHIFT (16) /* Bits 16-19: Loop divider fractional part */ +#define OSCCTRL_DPLLRATIO_LDRFRAC_MASK (15 << OSCCTRL_DPLLRATIO_LDRFRAC_SHIFT) +# define OSCCTRL_DPLLRATIO_LDRFRAC(n) ((uint32_t)(n) << OSCCTRL_DPLLRATIO_LDRFRAC_SHIFT) + +/* DPLL control B */ + +#define OSCCTRL_DPLLCTRLB_FILTER_SHIFT (0) /* Bits 0-1: Proportional integer filter selection */ +#define OSCCTRL_DPLLCTRLB_FILTER_MASK (3 << OSCCTRL_DPLLCTRLB_FILTER_SHIFT) +# define OSCCTRL_DPLLCTRLB_FILTER_DEFAULT (0 << OSCCTRL_DPLLCTRLB_FILTER_SHIFT) /* Default filter mode */ +# define OSCCTRL_DPLLCTRLB_FILTER_LBFILT (1 << OSCCTRL_DPLLCTRLB_FILTER_SHIFT) /* Low bandwidth filter */ +# define OSCCTRL_DPLLCTRLB_FILTER_HBFILT (2 << OSCCTRL_DPLLCTRLB_FILTER_SHIFT) /* High bandwidth filter */ +# define OSCCTRL_DPLLCTRLB_FILTER_HDFILT (3 << OSCCTRL_DPLLCTRLB_FILTER_SHIFT) /* High damping filter */ +#define OSCCTRL_DPLLCTRLB_LPEN (1 << 2) /* Bit 2: Low-power enable */ +#define OSCCTRL_DPLLCTRLB_WUF (1 << 3) /* Bit 3: Wake up fast */ +#define OSCCTRL_DPLLCTRLB_REFLCK_SHIFT (4) /* Bits 4-5: Reference clock selection */ +#define OSCCTRL_DPLLCTRLB_REFLCK_MASK (3 << OSCCTRL_DPLLCTRLB_REFLCK_SHIFT) +# define OSCCTRL_DPLLCTRLB_REFLCK_XOSCK32K (0 << OSCCTRL_DPLLCTRLB_REFLCK_SHIFT) /* XOSC32K clock reference */ +# define OSCCTRL_DPLLCTRLB_REFLCK_XOSC (1 << OSCCTRL_DPLLCTRLB_REFLCK_SHIFT) /* XOSC clock reference */ +# define OSCCTRL_DPLLCTRLB_REFLCK_GLCK (1 << OSCCTRL_DPLLCTRLB_REFLCK_SHIFT) /* GCLK clock reference */ +#define OSCCTRL_DPLLCTRLB_LTIME_SHIFT (8) /* Bits 8-10: Lock time */ +#define OSCCTRL_DPLLCTRLB_LTIME_MASK (7 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) +# define OSCCTRL_DPLLCTRLB_LTIME_NONE (0 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) /* No time-out. Automatic lock */ +# define OSCCTRL_DPLLCTRLB_LTIME_8MS (4 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no locka within 8MS */ +# define OSCCTRL_DPLLCTRLB_LTIME_9MS (5 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no locka within 9MS */ +# define OSCCTRL_DPLLCTRLB_LTIME_10MS (6 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no locka within 10MS */ +# define OSCCTRL_DPLLCTRLB_LTIME_11MS (7 << OSCCTRL_DPLLCTRLB_LTIME_SHIFT) /* Time-out if no locka within 11MS */ +#define OSCCTRL_DPLLCTRLB_LBYPASS (1 << 12) /* Bit 12: Lock bypass */ +#define OSCCTRL_DPLLCTRLB_DIV_SHIFT (16) /* Bits 16-26: Clock divider */ +#define OSCCTRL_DPLLCTRLB_DIV_MASK (0x7ff << OSCCTRL_DPLLCTRLB_DIV_SHIFT) +# define OSCCTRL_DPLLCTRLB_DIV(n) ((uint32_t)(n) << OSCCTRL_DPLLCTRLB_DIV_SHIFT) + +/* DPLL prescaler */ + +#define OSCCTRL_DPLLPRESC_SHIFT (0) /* Bit 0-1: Output clock prescaler */ +#define OSCCTRL_DPLLPRESC_MASK (3 << OSCCTRL_DPLLPRESC_SHIFT) +# define OSCCTRL_DPLLPRESC_DIV1 (0 << OSCCTRL_DPLLPRESC_SHIFT) /* DPLL output is divided by 1 */ +# define OSCCTRL_DPLLPRESC_DIV2 (1 << OSCCTRL_DPLLPRESC_SHIFT) /* DPLL output is divided by 2 */ +# define OSCCTRL_DPLLPRESC_DIV4 (2 << OSCCTRL_DPLLPRESC_SHIFT) /* DPLL output is divided by 4 */ + +/* DPLL synchronization busy */ + +#define OSCCTRL_DPLLSYNCBUSY_ENABLE (1 << 1) /* Bit 1: DPLL Enable synchonization status */ +#define OSCCTRL_DPLLSYNCBUSY_DPLLRATIO (1 << 2) /* Bit 2: DPLL Loop divider ration status */ +#define OSCCTRL_DPLLSYNCBUSY_DPLLPRESC (1 << 3) /* Bit 3: DPLL prescaler synchronization status */ + +/* DPLL status */ + +#define OSCCTRL_DPLLSTATUS_LOCK (1 << 0) /* Bit 0: DPLL lock status */ +#define OSCCTRL_DPLLSTATUS_CLKRDY (1 << 1) /* Bit 1: Output clock ready */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_OSCCTRL_H */ diff --git a/arch/arm/src/samdl/chip/saml_pm.h b/arch/arm/src/samdl/chip/saml_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..170311c925aaa515a47515925c65d2b7d131a173 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_pm.h @@ -0,0 +1,150 @@ +/**************************************************************************************************** + * arch/arm/src/samdl/chip/saml_pm.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PM_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PM_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* PM register offsets ******************************************************************************/ + +#define SAM_PM_CTRLA_OFFSET 0x0000 /* Control A */ +#define SAM_PM_SLEEPCFG_OFFSET 0x0001 /* Sleep configuration */ +#define SAM_PM_PLCFG_OFFSET 0x0002 /* Performance level configuration */ +#define SAM_PM_INTENCLR_OFFSET 0x0004 /* Interrupt enable clear register */ +#define SAM_PM_INTENSET_OFFSET 0x0005 /* Interrupt enable set register */ +#define SAM_PM_INTFLAG_OFFSET 0x0006 /* Interrupt flag status and clear register */ +#define SAM_PM_STDBYCFG_OFFSET 0x0008 /* Standy configuration */ + +/* PM register addresses ****************************************************************************/ + +#define SAM_PM_CTRLA (SAM_PM_BASE+SAM_PM_CTRLA_OFFSET) +#define SAM_PM_SLEEPCFG (SAM_PM_BASE+SAM_PM_SLEEPCFG_OFFSET) +#define SAM_PM_PLCFG (SAM_PM_BASE+SAM_PM_PLCFG_OFFSET) +#define SAM_PM_INTENCLR (SAM_PM_BASE+SAM_PM_INTENCLR_OFFSET) +#define SAM_PM_INTENSET (SAM_PM_BASE+SAM_PM_INTENSET_OFFSET) +#define SAM_PM_INTFLAG (SAM_PM_BASE+SAM_PM_INTFLAG_OFFSET) +#define SAM_PM_STDBYCFG (SAM_PM_BASE+SAM_PM_STDBYCFG_OFFSET) + +/* PM register bit definitions **********************************************************************/ + +/* Control A register */ + +#define PM_CTRLA_IORET (1 << 2) /* Bit 2: I/O retention */ + +/* Sleep configuration register */ + +#define PM_SLEEPCFG_MODE_SHIFT (0) /* Bits 0-2: Idle Mode Configuration */ +#define PM_SLEEPCFG_MODE_MASK (7 << PM_SLEEPCFG_MODE_SHIFT) +# define PM_SLEEPCFG_MODE_IDLE (2 << PM_SLEEPCFG_MODE_SHIFT) /* CPU, AHBx, APBx clocks OFF */ +# define PM_SLEEPCFG_MODE_STANDBY (4 << PM_SLEEPCFG_MODE_SHIFT) /* All clocks OFF, except sleepwalking peripherals */ +# define PM_SLEEPCFG_MODE_BACKUP (5 << PM_SLEEPCFG_MODE_SHIFT) /* Only backup domain is powered ON */ +# define PM_SLEEPCFG_MODE_OFF (6 << PM_SLEEPCFG_MODE_SHIFT) /* All power domains are powered OFF */ + +/* Performance level configuration */ + +#define PM_PLCFG_PLSEL_SHIFT (0) /* Bits 0-1: Performance level select */ +#define PM_PLCFG_PLSEL_MASK (3 << PM_PLCFG_PLSEL_SHIFT) +# define PM_PLCFG_PLSEL_PL0 (0 << PM_PLCFG_PLSEL_SHIFT) /* Performance level 0 */ +# define PM_PLCFG_PLSEL_PL2 (2 << PM_PLCFG_PLSEL_SHIFT) /* Performance level 2 */ +#define PM_PLCFG_PLDIS (1 << 7) /* Bit 7: Performance level disable */ + +/* Interrupt enable clear, Interrupt enable set, and Interrupt flag status and clear registers */ + +#define PM_INT_PLRDY (1 << 0) /* Bit 0: Performanc level ready */ + +/* Standy configuration */ + +#define PM_STDBYCFG_PDCFG_SHIFT (0) /* Bits 0-1: Power domain configuration */ +#define PM_STDBYCFG_PDCFG_MASK (3 << PM_STDBYCFG_PDCFG_SHIFT) +# define PM_STDBYCFG_PDCFG_DEFAULT (0 << PM_STDBYCFG_PDCFG_SHIFT) /* All power domains handled by HW */ +# define PM_STDBYCFG_PDCFG_PD01 (1 << PM_STDBYCFG_PDCFG_SHIFT) /* PD0 ACTIVE; PD1/2 handled by HW */ +# define PM_STDBYCFG_PDCFG_PD12 (2 << PM_STDBYCFG_PDCFG_SHIFT) /* PD0/1 ACTIVE; PD2 handled by HW */ +# define PM_STDBYCFG_PDCFG_PD012 (3 << PM_STDBYCFG_PDCFG_SHIFT) /* All power domains ACTIVE */ +#define PM_STDBYCFG_DPGPD0 (1 << 4) /* Bit 4: Dynamic power gating for power domain 0 */ +#define PM_STDBYCFG_DPGPD1 (1 << 5) /* Bit 5: Dynamic power gating for power domain 1 */ +#define PM_STDBYCFG_VREGSMOD_SHIFT (6) /* Bits 6-7: Linked power domain */ +#define PM_STDBYCFG_VREGSMOD_MASK (3 << PM_STDBYCFG_VREGSMOD_SHIFT) +# define PM_STDBYCFG_VREGSMOD_AUTO (0 << PM_STDBYCFG_VREGSMOD_SHIFT) /* Automatic mode */ +# define PM_STDBYCFG_VREGSMOD_PERFORMANCE (1 << PM_STDBYCFG_VREGSMOD_SHIFT) /* Performance oriented */ +# define PM_STDBYCFG_VREGSMOD_LP (2 << PM_STDBYCFG_VREGSMOD_SHIFT) /* Low power consumption oriented */ +#define PM_STDBYCFG_LINKPD_SHIFT (8) /* Bits 8-9: */ +#define PM_STDBYCFG_LINKPD_MASK (3 << PM_STDBYCFG_LINKPD_SHIFT) +# define PM_STDBYCFG_LINKPD_DEFAULT (0 << PM_STDBYCFG_LINKPD_SHIFT) /* Power domains not linked */ +# define PM_STDBYCFG_LINKPD_PD01 (1 << PM_STDBYCFG_LINKPD_SHIFT) /* Power domains P0/1 linked */ +# define PM_STDBYCFG_LINKPD_PD12 (2 << PM_STDBYCFG_LINKPD_SHIFT) /* Power domains P1/P2 linked */ +# define PM_STDBYCFG_LINKPD_PD012 (3 << PM_STDBYCFG_LINKPD_SHIFT) /* All power domains linked */ +#define PM_STDBYCFG_BBIASHS_SHIFT (10) /* Bits 10-11: Back bias for HMCRAMCHS */ +#define PM_STDBYCFG_BBIASHS_MASK (3 << PM_STDBYCFG_BBIASHS_SHIFT) +# define PM_STDBYCFG_BBIASHS_RETBACK (0 << PM_STDBYCFG_BBIASHS_SHIFT) /* Retention back biasing mode */ +# define PM_STDBYCFG_BBIASHS_STDBYBACK (1 << PM_STDBYCFG_BBIASHS_SHIFT) /* Standby back biasing mode */ +# define PM_STDBYCFG_BBIASHS_STDBYOFF (2 << PM_STDBYCFG_BBIASHS_SHIFT) /* Standby OFF mode */ +# define PM_STDBYCFG_BBIASHS_OFF (3 << PM_STDBYCFG_BBIASHS_SHIFT) /* Always OFF mode */ +#define PM_STDBYCFG_BBIASLP_SHIFT (12) /* Bits 12-13: Back bias for HMCRAMCLP */ +#define PM_STDBYCFG_BBIASLP_MASK (3 << PM_STDBYCFG_BBIASLP_SHIFT) +# define PM_STDBYCFG_BBIASLP_RETBACK (0 << PM_STDBYCFG_BBIASLP_SHIFT) /* Retention back biasing mode */ +# define PM_STDBYCFG_BBIASLP_STDBYBACK (1 << PM_STDBYCFG_BBIASLP_SHIFT) /* Standby back biasing mode */ +# define PM_STDBYCFG_BBIASLP_STDBYOFF (2 << PM_STDBYCFG_BBIASLP_SHIFT) /* Standby OFF mode */ +# define PM_STDBYCFG_BBIASLP_OFF (3 << PM_STDBYCFG_BBIASLP_SHIFT) /* Always OFF mode */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PM_H */ diff --git a/arch/arm/src/samdl/chip/saml_port.h b/arch/arm/src/samdl/chip/saml_port.h new file mode 100644 index 0000000000000000000000000000000000000000..374afb38c0901236ae2306c887695d2497b072bc --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_port.h @@ -0,0 +1,454 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_port.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PORT_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PORT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* PORT register offsets ********************************************************************/ + +#define SAM_PORTA (0) +#define SAM_PORTB (1) +#define SAM_PORTC (2) + +#define SAM_PORTN_OFFSET(n) (0x0000 + ((n) << 7)) +# define SAM_PORTA_OFFSET 0x0000 /* Port A register offset */ +# define SAM_PORTB_OFFSET 0x0080 /* Port B register offset */ +# define SAM_PORTC_OFFSET 0x0100 /* Port B register offset */ + +#define SAM_PORT_DIR_OFFSET 0x0000 /* Data direction register */ +#define SAM_PORT_DIRCLR_OFFSET 0x0004 /* Data direction clear register */ +#define SAM_PORT_DIRSET_OFFSET 0x0008 /* Data direction set register */ +#define SAM_PORT_DIRTGL_OFFSET 0x000c /* Data direction toggle register */ +#define SAM_PORT_OUT_OFFSET 0x0010 /* Data output value register */ +#define SAM_PORT_OUTCLR_OFFSET 0x0014 /* Data output value clear register */ +#define SAM_PORT_OUTSET_OFFSET 0x0018 /* Data output value set register */ +#define SAM_PORT_OUTTGL_OFFSET 0x001c /* Data output value toggle register */ +#define SAM_PORT_IN_OFFSET 0x0020 /* Data input value register */ +#define SAM_PORT_CTRL_OFFSET 0x0024 /* Control register */ +#define SAM_PORT_WRCONFIG_OFFSET 0x0028 /* Write configuration register */ +#define SAM_PORT_EVCTRL_OFFSET 0x002c /* Event input control register */ + +#define SAM_PORT_PMUX_OFFSET(n) (0x0030+((n)>>1)) +# define SAM_PORT_PMUX0_OFFSET 0x0030 /* Peripheral multiplexing register 0 */ +# define SAM_PORT_PMUX1_OFFSET 0x0031 /* Peripheral multiplexing register 1 */ +# define SAM_PORT_PMUX2_OFFSET 0x0032 /* Peripheral multiplexing register 2 */ +# define SAM_PORT_PMUX3_OFFSET 0x0033 /* Peripheral multiplexing register 3 */ +# define SAM_PORT_PMUX4_OFFSET 0x0034 /* Peripheral multiplexing register 4 */ +# define SAM_PORT_PMUX5_OFFSET 0x0035 /* Peripheral multiplexing register 5 */ +# define SAM_PORT_PMUX6_OFFSET 0x0036 /* Peripheral multiplexing register 6 */ +# define SAM_PORT_PMUX7_OFFSET 0x0037 /* Peripheral multiplexing register 7 */ +# define SAM_PORT_PMUX8_OFFSET 0x0038 /* Peripheral multiplexing register 8 */ +# define SAM_PORT_PMUX9_OFFSET 0x0039 /* Peripheral multiplexing register 9 */ +# define SAM_PORT_PMUX10_OFFSET 0x003a /* Peripheral multiplexing register 10 */ +# define SAM_PORT_PMUX11_OFFSET 0x003b /* Peripheral multiplexing register 11 */ +# define SAM_PORT_PMUX12_OFFSET 0x003c /* Peripheral multiplexing register 12 */ +# define SAM_PORT_PMUX13_OFFSET 0x003d /* Peripheral multiplexing register 13 */ +# define SAM_PORT_PMUX14_OFFSET 0x003e /* Peripheral multiplexing register 14 */ +# define SAM_PORT_PMUX15_OFFSET 0x003f /* Peripheral multiplexing register 15 */ + +#define SAM_PORT_PINCFG_OFFSET(n) (0x0040+(n)) +# define SAM_PORT_PINCFG0_OFFSET 0x0040 /* Pin configuration register 0 */ +# define SAM_PORT_PINCFG1_OFFSET 0x0041 /* Pin configuration register 1 */ +# define SAM_PORT_PINCFG2_OFFSET 0x0042 /* Pin configuration register 2 */ +# define SAM_PORT_PINCFG3_OFFSET 0x0043 /* Pin configuration register 3 */ +# define SAM_PORT_PINCFG4_OFFSET 0x0044 /* Pin configuration register 4 */ +# define SAM_PORT_PINCFG5_OFFSET 0x0045 /* Pin configuration register 5 */ +# define SAM_PORT_PINCFG6_OFFSET 0x0046 /* Pin configuration register 6 */ +# define SAM_PORT_PINCFG7_OFFSET 0x0047 /* Pin configuration register 7 */ +# define SAM_PORT_PINCFG8_OFFSET 0x0048 /* Pin configuration register 8 */ +# define SAM_PORT_PINCFG9_OFFSET 0x0049 /* Pin configuration register 9 */ +# define SAM_PORT_PINCFG10_OFFSET 0x004a /* Pin configuration register 10 */ +# define SAM_PORT_PINCFG11_OFFSET 0x004b /* Pin configuration register 11 */ +# define SAM_PORT_PINCFG12_OFFSET 0x004c /* Pin configuration register 12 */ +# define SAM_PORT_PINCFG13_OFFSET 0x004d /* Pin configuration register 13 */ +# define SAM_PORT_PINCFG14_OFFSET 0x004e /* Pin configuration register 14 */ +# define SAM_PORT_PINCFG15_OFFSET 0x004f /* Pin configuration register 15 */ +# define SAM_PORT_PINCFG16_OFFSET 0x0050 /* Pin configuration register 16 */ +# define SAM_PORT_PINCFG17_OFFSET 0x0051 /* Pin configuration register 17 */ +# define SAM_PORT_PINCFG18_OFFSET 0x0052 /* Pin configuration register 18 */ +# define SAM_PORT_PINCFG19_OFFSET 0x0053 /* Pin configuration register 19 */ +# define SAM_PORT_PINCFG20_OFFSET 0x0054 /* Pin configuration register 20 */ +# define SAM_PORT_PINCFG21_OFFSET 0x0055 /* Pin configuration register 21 */ +# define SAM_PORT_PINCFG22_OFFSET 0x0056 /* Pin configuration register 22 */ +# define SAM_PORT_PINCFG23_OFFSET 0x0057 /* Pin configuration register 23 */ +# define SAM_PORT_PINCFG24_OFFSET 0x0058 /* Pin configuration register 24 */ +# define SAM_PORT_PINCFG25_OFFSET 0x0059 /* Pin configuration register 25 */ +# define SAM_PORT_PINCFG26_OFFSET 0x005a /* Pin configuration register 26 */ +# define SAM_PORT_PINCFG27_OFFSET 0x005b /* Pin configuration register 27 */ +# define SAM_PORT_PINCFG28_OFFSET 0x005c /* Pin configuration register 28 */ +# define SAM_PORT_PINCFG29_OFFSET 0x005d /* Pin configuration register 29 */ +# define SAM_PORT_PINCFG30_OFFSET 0x005e /* Pin configuration register 30 */ +# define SAM_PORT_PINCFG31_OFFSET 0x005f /* Pin configuration register 31 */ + +/* PORT register addresses ******************************************************************/ + +#define SAM_PORTN_BASE(n) (SAM_PORT_BASE+SAM_PORTN_OFFSET(n)) +# define SAM_PORTA_BASE (SAM_PORT_BASE+SAM_PORTA_OFFSET) +# define SAM_PORTB_BASE (SAM_PORT_BASE+SAM_PORTB_OFFSET) +# define SAM_PORTC_BASE (SAM_PORT_BASE+SAM_PORTC_OFFSET) + +#define SAM_PORTA_DIR (SAM_PORTA_BASE+SAM_PORT_DIR_OFFSET) +#define SAM_PORTA_DIRCLR (SAM_PORTA_BASE+SAM_PORT_DIRCLR_OFFSET) +#define SAM_PORTA_DIRSET (SAM_PORTA_BASE+SAM_PORT_DIRSET_OFFSET) +#define SAM_PORTA_DIRTGL (SAM_PORTA_BASE+SAM_PORT_DIRTGL_OFFSET) +#define SAM_PORTA_OUT (SAM_PORTA_BASE+SAM_PORT_OUT_OFFSET) +#define SAM_PORTA_OUTCLR (SAM_PORTA_BASE+SAM_PORT_OUTCLR_OFFSET) +#define SAM_PORTA_OUTSET (SAM_PORTA_BASE+SAM_PORT_OUTSET_OFFSET) +#define SAM_PORTA_OUTTGL (SAM_PORTA_BASE+SAM_PORT_OUTTGL_OFFSET) +#define SAM_PORTA_IN (SAM_PORTA_BASE+SAM_PORT_IN_OFFSET) +#define SAM_PORTA_CTRL (SAM_PORTA_BASE+SAM_PORT_CTRL_OFFSET) +#define SAM_PORTA_WRCONFIG (SAM_PORTA_BASE+SAM_PORT_WRCONFIG_OFFSET) +#define SAM_PORT_EVCTRL (SAM_PORTA_BASE+SAM_PORT_EVCTRL_OFFSET) + +#define SAM_PORTA_PMUX(n) (SAM_PORTA_BASE+SAM_PORT_PMUX_OFFSET(n)) +# define SAM_PORTA_PMUX0 (SAM_PORTA_BASE+SAM_PORT_PMUX0_OFFSET) +# define SAM_PORTA_PMUX1 (SAM_PORTA_BASE+SAM_PORT_PMUX1_OFFSET) +# define SAM_PORTA_PMUX2 (SAM_PORTA_BASE+SAM_PORT_PMUX2_OFFSET) +# define SAM_PORTA_PMUX3 (SAM_PORTA_BASE+SAM_PORT_PMUX3_OFFSET) +# define SAM_PORTA_PMUX4 (SAM_PORTA_BASE+SAM_PORT_PMUX4_OFFSET) +# define SAM_PORTA_PMUX5 (SAM_PORTA_BASE+SAM_PORT_PMUX5_OFFSET) +# define SAM_PORTA_PMUX6 (SAM_PORTA_BASE+SAM_PORT_PMUX6_OFFSET) +# define SAM_PORTA_PMUX7 (SAM_PORTA_BASE+SAM_PORT_PMUX7_OFFSET) +# define SAM_PORTA_PMUX8 (SAM_PORTA_BASE+SAM_PORT_PMUX8_OFFSET) +# define SAM_PORTA_PMUX9 (SAM_PORTA_BASE+SAM_PORT_PMUX9_OFFSET) +# define SAM_PORTA_PMUX10 (SAM_PORTA_BASE+SAM_PORT_PMUX10_OFFSET) +# define SAM_PORTA_PMUX11 (SAM_PORTA_BASE+SAM_PORT_PMUX11_OFFSET) +# define SAM_PORTA_PMUX12 (SAM_PORTA_BASE+SAM_PORT_PMUX12_OFFSET) +# define SAM_PORTA_PMUX13 (SAM_PORTA_BASE+SAM_PORT_PMUX13_OFFSET) +# define SAM_PORTA_PMUX14 (SAM_PORTA_BASE+SAM_PORT_PMUX14_OFFSET) +# define SAM_PORTA_PMUX15 (SAM_PORTA_BASE+SAM_PORT_PMUX15_OFFSET) + +#define SAM_PORTA_PINCFG(n) (SAM_PORTA_BASE+SAM_PORT_PINCFG_OFFSET(n)) +# define SAM_PORTA_PINCFG0 (SAM_PORTA_BASE+SAM_PORT_PINCFG0_OFFSET) +# define SAM_PORTA_PINCFG1 (SAM_PORTA_BASE+SAM_PORT_PINCFG1_OFFSET) +# define SAM_PORTA_PINCFG2 (SAM_PORTA_BASE+SAM_PORT_PINCFG2_OFFSET) +# define SAM_PORTA_PINCFG3 (SAM_PORTA_BASE+SAM_PORT_PINCFG3_OFFSET) +# define SAM_PORTA_PINCFG4 (SAM_PORTA_BASE+SAM_PORT_PINCFG4_OFFSET) +# define SAM_PORTA_PINCFG5 (SAM_PORTA_BASE+SAM_PORT_PINCFG5_OFFSET) +# define SAM_PORTA_PINCFG6 (SAM_PORTA_BASE+SAM_PORT_PINCFG6_OFFSET) +# define SAM_PORTA_PINCFG7 (SAM_PORTA_BASE+SAM_PORT_PINCFG7_OFFSET) +# define SAM_PORTA_PINCFG8 (SAM_PORTA_BASE+SAM_PORT_PINCFG8_OFFSET) +# define SAM_PORTA_PINCFG9 (SAM_PORTA_BASE+SAM_PORT_PINCFG9_OFFSET) +# define SAM_PORTA_PINCFG10 (SAM_PORTA_BASE+SAM_PORT_PINCFG10_OFFSET) +# define SAM_PORTA_PINCFG11 (SAM_PORTA_BASE+SAM_PORT_PINCFG11_OFFSET) +# define SAM_PORTA_PINCFG12 (SAM_PORTA_BASE+SAM_PORT_PINCFG12_OFFSET) +# define SAM_PORTA_PINCFG13 (SAM_PORTA_BASE+SAM_PORT_PINCFG13_OFFSET) +# define SAM_PORTA_PINCFG14 (SAM_PORTA_BASE+SAM_PORT_PINCFG14_OFFSET) +# define SAM_PORTA_PINCFG15 (SAM_PORTA_BASE+SAM_PORT_PINCFG15_OFFSET) +# define SAM_PORTA_PINCFG16 (SAM_PORTA_BASE+SAM_PORT_PINCFG16_OFFSET) +# define SAM_PORTA_PINCFG17 (SAM_PORTA_BASE+SAM_PORT_PINCFG17_OFFSET) +# define SAM_PORTA_PINCFG18 (SAM_PORTA_BASE+SAM_PORT_PINCFG18_OFFSET) +# define SAM_PORTA_PINCFG19 (SAM_PORTA_BASE+SAM_PORT_PINCFG19_OFFSET) +# define SAM_PORTA_PINCFG20 (SAM_PORTA_BASE+SAM_PORT_PINCFG20_OFFSET) +# define SAM_PORTA_PINCFG21 (SAM_PORTA_BASE+SAM_PORT_PINCFG21_OFFSET) +# define SAM_PORTA_PINCFG22 (SAM_PORTA_BASE+SAM_PORT_PINCFG22_OFFSET) +# define SAM_PORTA_PINCFG23 (SAM_PORTA_BASE+SAM_PORT_PINCFG23_OFFSET) +# define SAM_PORTA_PINCFG24 (SAM_PORTA_BASE+SAM_PORT_PINCFG24_OFFSET) +# define SAM_PORTA_PINCFG25 (SAM_PORTA_BASE+SAM_PORT_PINCFG25_OFFSET) +# define SAM_PORTA_PINCFG26 (SAM_PORTA_BASE+SAM_PORT_PINCFG26_OFFSET) +# define SAM_PORTA_PINCFG27 (SAM_PORTA_BASE+SAM_PORT_PINCFG27_OFFSET) +# define SAM_PORTA_PINCFG28 (SAM_PORTA_BASE+SAM_PORT_PINCFG28_OFFSET) +# define SAM_PORTA_PINCFG29 (SAM_PORTA_BASE+SAM_PORT_PINCFG29_OFFSET) +# define SAM_PORTA_PINCFG30 (SAM_PORTA_BASE+SAM_PORT_PINCFG30_OFFSET) +# define SAM_PORTA_PINCFG31 (SAM_PORTA_BASE+SAM_PORT_PINCFG31_OFFSET) + +#define SAM_PORTB_DIR (SAM_PORTB_BASE+SAM_PORT_DIR_OFFSET) +#define SAM_PORTB_DIRCLR (SAM_PORTB_BASE+SAM_PORT_DIRCLR_OFFSET) +#define SAM_PORTB_DIRSET (SAM_PORTB_BASE+SAM_PORT_DIRSET_OFFSET) +#define SAM_PORTB_DIRTGL (SAM_PORTB_BASE+SAM_PORT_DIRTGL_OFFSET) +#define SAM_PORTB_OUT (SAM_PORTB_BASE+SAM_PORT_OUT_OFFSET) +#define SAM_PORTB_OUTCLR (SAM_PORTB_BASE+SAM_PORT_OUTCLR_OFFSET) +#define SAM_PORTB_OUTSET (SAM_PORTB_BASE+SAM_PORT_OUTSET_OFFSET) +#define SAM_PORTB_OUTTGL (SAM_PORTB_BASE+SAM_PORT_OUTTGL_OFFSET) +#define SAM_PORTB_IN (SAM_PORTB_BASE+SAM_PORT_IN_OFFSET) +#define SAM_PORTB_CTRL (SAM_PORTB_BASE+SAM_PORT_CTRL_OFFSET) +#define SAM_PORTB_WRCONFIG (SAM_PORTB_BASE+SAM_PORT_WRCONFIG_OFFSET) + +#define SAM_PORTB_PMUX(n) (SAM_PORTB_BASE+SAM_PORT_PMUX_OFFSET(n)) +# define SAM_PORTB_PMUX0 (SAM_PORTB_BASE+SAM_PORT_PMUX0_OFFSET) +# define SAM_PORTB_PMUX1 (SAM_PORTB_BASE+SAM_PORT_PMUX1_OFFSET) +# define SAM_PORTB_PMUX2 (SAM_PORTB_BASE+SAM_PORT_PMUX2_OFFSET) +# define SAM_PORTB_PMUX3 (SAM_PORTB_BASE+SAM_PORT_PMUX3_OFFSET) +# define SAM_PORTB_PMUX4 (SAM_PORTB_BASE+SAM_PORT_PMUX4_OFFSET) +# define SAM_PORTB_PMUX5 (SAM_PORTB_BASE+SAM_PORT_PMUX5_OFFSET) +# define SAM_PORTB_PMUX6 (SAM_PORTB_BASE+SAM_PORT_PMUX6_OFFSET) +# define SAM_PORTB_PMUX7 (SAM_PORTB_BASE+SAM_PORT_PMUX7_OFFSET) +# define SAM_PORTB_PMUX8 (SAM_PORTB_BASE+SAM_PORT_PMUX8_OFFSET) +# define SAM_PORTB_PMUX9 (SAM_PORTB_BASE+SAM_PORT_PMUX9_OFFSET) +# define SAM_PORTB_PMUX10 (SAM_PORTB_BASE+SAM_PORT_PMUX10_OFFSET) +# define SAM_PORTB_PMUX11 (SAM_PORTB_BASE+SAM_PORT_PMUX11_OFFSET) +# define SAM_PORTB_PMUX12 (SAM_PORTB_BASE+SAM_PORT_PMUX12_OFFSET) +# define SAM_PORTB_PMUX13 (SAM_PORTB_BASE+SAM_PORT_PMUX13_OFFSET) +# define SAM_PORTB_PMUX14 (SAM_PORTB_BASE+SAM_PORT_PMUX14_OFFSET) +# define SAM_PORTB_PMUX15 (SAM_PORTB_BASE+SAM_PORT_PMUX15_OFFSET) + +#define SAM_PORTB_PINCFG(n) (SAM_PORTB_BASE+SAM_PORT_PINCFG_OFFSET(n)) +# define SAM_PORTB_PINCFG0 (SAM_PORTB_BASE+SAM_PORT_PINCFG0_OFFSET) +# define SAM_PORTB_PINCFG1 (SAM_PORTB_BASE+SAM_PORT_PINCFG1_OFFSET) +# define SAM_PORTB_PINCFG2 (SAM_PORTB_BASE+SAM_PORT_PINCFG2_OFFSET) +# define SAM_PORTB_PINCFG3 (SAM_PORTB_BASE+SAM_PORT_PINCFG3_OFFSET) +# define SAM_PORTB_PINCFG4 (SAM_PORTB_BASE+SAM_PORT_PINCFG4_OFFSET) +# define SAM_PORTB_PINCFG5 (SAM_PORTB_BASE+SAM_PORT_PINCFG5_OFFSET) +# define SAM_PORTB_PINCFG6 (SAM_PORTB_BASE+SAM_PORT_PINCFG6_OFFSET) +# define SAM_PORTB_PINCFG7 (SAM_PORTB_BASE+SAM_PORT_PINCFG7_OFFSET) +# define SAM_PORTB_PINCFG8 (SAM_PORTB_BASE+SAM_PORT_PINCFG8_OFFSET) +# define SAM_PORTB_PINCFG9 (SAM_PORTB_BASE+SAM_PORT_PINCFG9_OFFSET) +# define SAM_PORTB_PINCFG10 (SAM_PORTB_BASE+SAM_PORT_PINCFG10_OFFSET) +# define SAM_PORTB_PINCFG11 (SAM_PORTB_BASE+SAM_PORT_PINCFG11_OFFSET) +# define SAM_PORTB_PINCFG12 (SAM_PORTB_BASE+SAM_PORT_PINCFG12_OFFSET) +# define SAM_PORTB_PINCFG13 (SAM_PORTB_BASE+SAM_PORT_PINCFG13_OFFSET) +# define SAM_PORTB_PINCFG14 (SAM_PORTB_BASE+SAM_PORT_PINCFG14_OFFSET) +# define SAM_PORTB_PINCFG15 (SAM_PORTB_BASE+SAM_PORT_PINCFG15_OFFSET) +# define SAM_PORTB_PINCFG16 (SAM_PORTB_BASE+SAM_PORT_PINCFG16_OFFSET) +# define SAM_PORTB_PINCFG17 (SAM_PORTB_BASE+SAM_PORT_PINCFG17_OFFSET) +# define SAM_PORTB_PINCFG18 (SAM_PORTB_BASE+SAM_PORT_PINCFG18_OFFSET) +# define SAM_PORTB_PINCFG19 (SAM_PORTB_BASE+SAM_PORT_PINCFG19_OFFSET) +# define SAM_PORTB_PINCFG20 (SAM_PORTB_BASE+SAM_PORT_PINCFG20_OFFSET) +# define SAM_PORTB_PINCFG21 (SAM_PORTB_BASE+SAM_PORT_PINCFG21_OFFSET) +# define SAM_PORTB_PINCFG22 (SAM_PORTB_BASE+SAM_PORT_PINCFG22_OFFSET) +# define SAM_PORTB_PINCFG23 (SAM_PORTB_BASE+SAM_PORT_PINCFG23_OFFSET) +# define SAM_PORTB_PINCFG24 (SAM_PORTB_BASE+SAM_PORT_PINCFG24_OFFSET) +# define SAM_PORTB_PINCFG25 (SAM_PORTB_BASE+SAM_PORT_PINCFG25_OFFSET) +# define SAM_PORTB_PINCFG26 (SAM_PORTB_BASE+SAM_PORT_PINCFG26_OFFSET) +# define SAM_PORTB_PINCFG27 (SAM_PORTB_BASE+SAM_PORT_PINCFG27_OFFSET) +# define SAM_PORTB_PINCFG28 (SAM_PORTB_BASE+SAM_PORT_PINCFG28_OFFSET) +# define SAM_PORTB_PINCFG29 (SAM_PORTB_BASE+SAM_PORT_PINCFG29_OFFSET) +# define SAM_PORTB_PINCFG30 (SAM_PORTB_BASE+SAM_PORT_PINCFG30_OFFSET) +# define SAM_PORTB_PINCFG31 (SAM_PORTB_BASE+SAM_PORT_PINCFG31_OFFSET) + +#define SAM_PORTC_DIR (SAM_PORTC_BASE+SAM_PORT_DIR_OFFSET) +#define SAM_PORTC_DIRCLR (SAM_PORTC_BASE+SAM_PORT_DIRCLR_OFFSET) +#define SAM_PORTC_DIRSET (SAM_PORTC_BASE+SAM_PORT_DIRSET_OFFSET) +#define SAM_PORTC_DIRTGL (SAM_PORTC_BASE+SAM_PORT_DIRTGL_OFFSET) +#define SAM_PORTC_OUT (SAM_PORTC_BASE+SAM_PORT_OUT_OFFSET) +#define SAM_PORTC_OUTCLR (SAM_PORTC_BASE+SAM_PORT_OUTCLR_OFFSET) +#define SAM_PORTC_OUTSET (SAM_PORTC_BASE+SAM_PORT_OUTSET_OFFSET) +#define SAM_PORTC_OUTTGL (SAM_PORTC_BASE+SAM_PORT_OUTTGL_OFFSET) +#define SAM_PORTC_IN (SAM_PORTC_BASE+SAM_PORT_IN_OFFSET) +#define SAM_PORTC_CTRL (SAM_PORTC_BASE+SAM_PORT_CTRL_OFFSET) +#define SAM_PORTC_WRCONFIG (SAM_PORTC_BASE+SAM_PORT_WRCONFIG_OFFSET) + +#define SAM_PORTC_PMUX(n) (SAM_PORTC_BASE+SAM_PORT_PMUX_OFFSET(n)) +# define SAM_PORTC_PMUX0 (SAM_PORTC_BASE+SAM_PORT_PMUX0_OFFSET) +# define SAM_PORTC_PMUX1 (SAM_PORTC_BASE+SAM_PORT_PMUX1_OFFSET) +# define SAM_PORTC_PMUX2 (SAM_PORTC_BASE+SAM_PORT_PMUX2_OFFSET) +# define SAM_PORTC_PMUX3 (SAM_PORTC_BASE+SAM_PORT_PMUX3_OFFSET) +# define SAM_PORTC_PMUX4 (SAM_PORTC_BASE+SAM_PORT_PMUX4_OFFSET) +# define SAM_PORTC_PMUX5 (SAM_PORTC_BASE+SAM_PORT_PMUX5_OFFSET) +# define SAM_PORTC_PMUX6 (SAM_PORTC_BASE+SAM_PORT_PMUX6_OFFSET) +# define SAM_PORTC_PMUX7 (SAM_PORTC_BASE+SAM_PORT_PMUX7_OFFSET) +# define SAM_PORTC_PMUX8 (SAM_PORTC_BASE+SAM_PORT_PMUX8_OFFSET) +# define SAM_PORTC_PMUX9 (SAM_PORTC_BASE+SAM_PORT_PMUX9_OFFSET) +# define SAM_PORTC_PMUX10 (SAM_PORTC_BASE+SAM_PORT_PMUX10_OFFSET) +# define SAM_PORTC_PMUX11 (SAM_PORTC_BASE+SAM_PORT_PMUX11_OFFSET) +# define SAM_PORTC_PMUX12 (SAM_PORTC_BASE+SAM_PORT_PMUX12_OFFSET) +# define SAM_PORTC_PMUX13 (SAM_PORTC_BASE+SAM_PORT_PMUX13_OFFSET) +# define SAM_PORTC_PMUX14 (SAM_PORTC_BASE+SAM_PORT_PMUX14_OFFSET) +# define SAM_PORTC_PMUX15 (SAM_PORTC_BASE+SAM_PORT_PMUX15_OFFSET) + +#define SAM_PORTC_PINCFG(n) (SAM_PORTC_BASE+SAM_PORT_PINCFG_OFFSET(n)) +# define SAM_PORTC_PINCFG0 (SAM_PORTC_BASE+SAM_PORT_PINCFG0_OFFSET) +# define SAM_PORTC_PINCFG1 (SAM_PORTC_BASE+SAM_PORT_PINCFG1_OFFSET) +# define SAM_PORTC_PINCFG2 (SAM_PORTC_BASE+SAM_PORT_PINCFG2_OFFSET) +# define SAM_PORTC_PINCFG3 (SAM_PORTC_BASE+SAM_PORT_PINCFG3_OFFSET) +# define SAM_PORTC_PINCFG4 (SAM_PORTC_BASE+SAM_PORT_PINCFG4_OFFSET) +# define SAM_PORTC_PINCFG5 (SAM_PORTC_BASE+SAM_PORT_PINCFG5_OFFSET) +# define SAM_PORTC_PINCFG6 (SAM_PORTC_BASE+SAM_PORT_PINCFG6_OFFSET) +# define SAM_PORTC_PINCFG7 (SAM_PORTC_BASE+SAM_PORT_PINCFG7_OFFSET) +# define SAM_PORTC_PINCFG8 (SAM_PORTC_BASE+SAM_PORT_PINCFG8_OFFSET) +# define SAM_PORTC_PINCFG9 (SAM_PORTC_BASE+SAM_PORT_PINCFG9_OFFSET) +# define SAM_PORTC_PINCFG10 (SAM_PORTC_BASE+SAM_PORT_PINCFG10_OFFSET) +# define SAM_PORTC_PINCFG11 (SAM_PORTC_BASE+SAM_PORT_PINCFG11_OFFSET) +# define SAM_PORTC_PINCFG12 (SAM_PORTC_BASE+SAM_PORT_PINCFG12_OFFSET) +# define SAM_PORTC_PINCFG13 (SAM_PORTC_BASE+SAM_PORT_PINCFG13_OFFSET) +# define SAM_PORTC_PINCFG14 (SAM_PORTC_BASE+SAM_PORT_PINCFG14_OFFSET) +# define SAM_PORTC_PINCFG15 (SAM_PORTC_BASE+SAM_PORT_PINCFG15_OFFSET) +# define SAM_PORTC_PINCFG16 (SAM_PORTC_BASE+SAM_PORT_PINCFG16_OFFSET) +# define SAM_PORTC_PINCFG17 (SAM_PORTC_BASE+SAM_PORT_PINCFG17_OFFSET) +# define SAM_PORTC_PINCFG18 (SAM_PORTC_BASE+SAM_PORT_PINCFG18_OFFSET) +# define SAM_PORTC_PINCFG19 (SAM_PORTC_BASE+SAM_PORT_PINCFG19_OFFSET) +# define SAM_PORTC_PINCFG20 (SAM_PORTC_BASE+SAM_PORT_PINCFG20_OFFSET) +# define SAM_PORTC_PINCFG21 (SAM_PORTC_BASE+SAM_PORT_PINCFG21_OFFSET) +# define SAM_PORTC_PINCFG22 (SAM_PORTC_BASE+SAM_PORT_PINCFG22_OFFSET) +# define SAM_PORTC_PINCFG23 (SAM_PORTC_BASE+SAM_PORT_PINCFG23_OFFSET) +# define SAM_PORTC_PINCFG24 (SAM_PORTC_BASE+SAM_PORT_PINCFG24_OFFSET) +# define SAM_PORTC_PINCFG25 (SAM_PORTC_BASE+SAM_PORT_PINCFG25_OFFSET) +# define SAM_PORTC_PINCFG26 (SAM_PORTC_BASE+SAM_PORT_PINCFG26_OFFSET) +# define SAM_PORTC_PINCFG27 (SAM_PORTC_BASE+SAM_PORT_PINCFG27_OFFSET) +# define SAM_PORTC_PINCFG28 (SAM_PORTC_BASE+SAM_PORT_PINCFG28_OFFSET) +# define SAM_PORTC_PINCFG29 (SAM_PORTC_BASE+SAM_PORT_PINCFG29_OFFSET) +# define SAM_PORTC_PINCFG30 (SAM_PORTC_BASE+SAM_PORT_PINCFG30_OFFSET) +# define SAM_PORTC_PINCFG31 (SAM_PORTC_BASE+SAM_PORT_PINCFG31_OFFSET) + +/* PORT register bit definitions ************************************************************/ + +/* Data direction, data direction clear, data direction set, and data direction toggle + * registers + */ + +#define PORT_DIR(n) (1 << n) /* Port data n, direction, n=0-31 */ + +/* Data output value, data output value clear, data output value set, and data output + * value toggle registers + */ + +#define PORT_OUT(n) (1 << n) /* Port data n output value, n=0-31 */ + +/* Data input value register */ + +#define PORT_IN(n) (1 << n) /* Port n data input value, n=0-31 */ + +/* Control register */ + +#define PORT_CTRL(n) (1 << n) /* Port n input sampling mode, n=0-31 */ + +/* Write configuration registers */ + +#define PORT_WRCONFIG_PINMASK_SHIFT (0) /* Bits 0-15: Pin Mask for Multiple Pin Configuration */ +#define PORT_WRCONFIG_PINMASK_MASK (0xffff << PORT_WRCONFIG_PINMASK_SHIFT) +# define PORT_WRCONFIG_PINMASK(n) (1 << (PORT_WRCONFIG_PINMASK_SHIFT+(n))) +#define PORT_WRCONFIG_PMUXEN (1 << 16) /* Bit 16: Peripheral Multiplexer Enable */ +#define PORT_WRCONFIG_INEN (1 << 17) /* Bit 17: Input Enable */ +#define PORT_WRCONFIG_PULLEN (1 << 18) /* Bit 18: Pull Enable */ +#define PORT_WRCONFIG_DRVSTR (1 << 22) /* Bit 22: Output Driver Strength Selection */ +#define PORT_WRCONFIG_PMUX_SHIFT (24) /* Bits 24-27: Peripheral Multiplexing */ +#define PORT_WRCONFIG_PMUX_MASK (15 << PORT_WRCONFIG_PMUX_SHIFT) +# define PORT_WRCONFIG_PMUX(n) ((uint32_t)(n) << PORT_WRCONFIG_PMUX_SHIFT) +#define PORT_WRCONFIG_WRPMUX (1 << 28) /* Bit 28: Write PMUX */ +#define PORT_WRCONFIG_WRPINCFG (1 << 30) /* Bit 30: Write PINCFG */ +#define PORT_WRCONFIG_HWSEL (1 << 31) /* Bit 31: Half-Word Select */ + +/* Event input control register */ + +#define PORT_EVCTRL_PID_SHIFT(n) ((n) << 3) /* Port event pin identifier n, n=0..3 */ +#define PORT_EVCTRL_PID_MASK(n) (31 << PORT_EVCTRL_PID_SHIFT(n)) +# define PORT_EVCTRL_PID(n,v) ((unint32_t)(v) << PORT_EVCTRL_PID_SHIFT(n)) +#define PORT_EVCTRL_EVACT_SHIFT(n) (((n) << 3) + 5) /* Port event pin action n, n=0..3 */ +#define PORT_EVCTRL_EVACT_MASK(n) (3 << PORT_EVCTRL_EVACT_SHIFT(n)) +# define PORT_EVCTRL_EVACT(n,v) ((unint32_t)(v) << PORT_EVCTRL_EVACT_SHIFT(n)) +#define PORT_EVCTRL_PORTEI(n) (((n) << 3) + 7) /* Port event input enable n, n=0..3 */ + +#define PORT_EVCTRL_PID0_SHIFT (0) /* Bits 0-4: Port event pin identifier 0 */ +#define PORT_EVCTRL_PID0_MASK (31 << PORT_EVCTRL_PID0_SHIFT) +# define PORT_EVCTRL_PID0(v) ((unint32_t)(v) << PORT_EVCTRL_PID0_SHIFT) +#define PORT_EVCTRL_EVACT0_SHIFT (5) /* Bits 5-6: Port event pin action 0 */ +#define PORT_EVCTRL_EVACT0_MASK (3 << PORT_EVCTRL_EVACT0_SHIFT) +# define PORT_EVCTRL_EVACT0(v) ((unint32_t)(v) << PORT_EVCTRL_EVACT0_SHIFT) +#define PORT_EVCTRL_PORTEI0 (1 << 7) /* Bit 7: Port event input enable 0 */ +#define PORT_EVCTRL_PID1_SHIFT (8) /* Bits 8-12: Port event pin identifier 1 */ +#define PORT_EVCTRL_PID1_MASK (31 << PORT_EVCTRL_PID1_SHIFT) +# define PORT_EVCTRL_PID1(v) ((unint32_t)(v) << PORT_EVCTRL_PID1_SHIFT) +#define PORT_EVCTRL_EVACT1_SHIFT (13) /* Bits 13-14: Port event pin action 1 */ +#define PORT_EVCTRL_EVACT1_MASK (3 << PORT_EVCTRL_EVACT1_SHIFT) +# define PORT_EVCTRL_EVACT1(v) ((unint32_t)(v) << PORT_EVCTRL_EVACT1_SHIFT) +#define PORT_EVCTRL_PORTEI1 (1 << 15) /* Bit 15: Port event input enable 1 */ +#define PORT_EVCTRL_PID2_SHIFT (16) /* Bits 16-20: Port event pin identifier 2 */ +#define PORT_EVCTRL_PID2_MASK (31 << PORT_EVCTRL_PID2_SHIFT) +# define PORT_EVCTRL_PID2(v) ((unint32_t)(v) << PORT_EVCTRL_PID2_SHIFT) +#define PORT_EVCTRL_EVACT2_SHIFT (21) /* Bits 21-22: Port event pin action 2 */ +#define PORT_EVCTRL_EVACT2_MASK (3 << PORT_EVCTRL_EVACT2_SHIFT) +# define PORT_EVCTRL_EVACT2(v) ((unint32_t)(v) << PORT_EVCTRL_EVACT2_SHIFT) +#define PORT_EVCTRL_PORTEI2 (1 << 23) /* Bit 23: Port event input enable 2 */ +#define PORT_EVCTRL_PID3_SHIFT (24) /* Bits 24-28: Port event pin identifier 3 */ +#define PORT_EVCTRL_PID3_MASK (31 << PORT_EVCTRL_PID3_SHIFT) +# define PORT_EVCTRL_PID3(v) ((unint32_t)(v) << PORT_EVCTRL_PID3_SHIFT) +#define PORT_EVCTRL_EVACT3_SHIFT (29) /* Bits 29-30: Port event pin action 3 */ +#define PORT_EVCTRL_EVACT3_MASK (3 << PORT_EVCTRL_EVACT3_SHIFT) +# define PORT_EVCTRL_EVACT3(v) ((unint32_t)(v) << PORT_EVCTRL_EVACT3_SHIFT) +#define PORT_EVCTRL_PORTEI3 (1 << 31) /* Bit 31: Port event input enable 3 */ + +/* Peripheral multiplexing registers */ + +#define PORT_PMUXE_SHIFT (0) /* Bits 0-3: Peripheral multiplexing even */ +#define PORT_PMUXE_MASK (15 << PORT_PMUXE_SHIFT) +# define PORT_PMUXE_PERIPHA (0 << PORT_PMUXE_SHIFT) /* Peripheral function A */ +# define PORT_PMUXE_PERIPHB (1 << PORT_PMUXE_SHIFT) /* Peripheral function B */ +# define PORT_PMUXE_PERIPHC (2 << PORT_PMUXE_SHIFT) /* Peripheral function C */ +# define PORT_PMUXE_PERIPHD (3 << PORT_PMUXE_SHIFT) /* Peripheral function D */ +# define PORT_PMUXE_PERIPHE (4 << PORT_PMUXE_SHIFT) /* Peripheral function E */ +# define PORT_PMUXE_PERIPHF (5 << PORT_PMUXE_SHIFT) /* Peripheral function F */ +# define PORT_PMUXE_PERIPHG (6 << PORT_PMUXE_SHIFT) /* Peripheral function G */ +# define PORT_PMUXE_PERIPHH (7 << PORT_PMUXE_SHIFT) /* Peripheral function H */ +# define PORT_PMUXE_PERIPHI (8 << PORT_PMUXE_SHIFT) /* Peripheral function I */ +#define PORT_PMUXO_SHIFT (4) /* Bits 4-7: Peripheral multiplexing odd */ +#define PORT_PMUXO_MASK (15 << PORT_PMUXO_SHIFT) +# define PORT_PMUXO_PERIPHA (0 << PORT_PMUXO_SHIFT) /* Peripheral function A */ +# define PORT_PMUXO_PERIPHB (1 << PORT_PMUXO_SHIFT) /* Peripheral function B */ +# define PORT_PMUXO_PERIPHC (2 << PORT_PMUXO_SHIFT) /* Peripheral function C */ +# define PORT_PMUXO_PERIPHD (3 << PORT_PMUXO_SHIFT) /* Peripheral function D */ +# define PORT_PMUXO_PERIPHE (4 << PORT_PMUXO_SHIFT) /* Peripheral function E */ +# define PORT_PMUXO_PERIPHF (5 << PORT_PMUXO_SHIFT) /* Peripheral function F */ +# define PORT_PMUXO_PERIPHG (6 << PORT_PMUXO_SHIFT) /* Peripheral function G */ +# define PORT_PMUXO_PERIPHH (7 << PORT_PMUXO_SHIFT) /* Peripheral function H */ +# define PORT_PMUXO_PERIPHI (8 << PORT_PMUXO_SHIFT) /* Peripheral function I */ + +/* Pin configuration registers */ + +#define PORT_PINCFG_PMUXEN (1 << 0) /* Bit 0: Peripheral Multiplexer Enable */ +#define PORT_PINCFG_INEN (1 << 1) /* Bit 1: Input Enable */ +#define PORT_PINCFG_PULLEN (1 << 2) /* Bit 2: Pull Enable */ +#define PORT_PINCFG_DRVSTR (1 << 6) /* Bit 6: Output Driver Strength Selection */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_PORT_H */ diff --git a/arch/arm/src/samdl/chip/saml_rstc.h b/arch/arm/src/samdl/chip/saml_rstc.h new file mode 100644 index 0000000000000000000000000000000000000000..85547992fb4793ee9cf04ae8e4d73ce1d1861aac --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_rstc.h @@ -0,0 +1,145 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_rstc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_RSTC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_RSTC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* RSTC register offsets *********************************************************************/ + +#define SAM_RSTC_RCAUSE_OFFSET 0x0000 /* Reset cause */ +#define SAM_RSTC_BKUPEXIT_OFFSET 0x0002 /* Backup exit source */ +#define SAM_RSTC_WKDBCONF_OFFSET 0x0004 /* Wakeup debounce count */ +#define SAM_RSTC_WKPOL_OFFSET 0x0008 /* Wakeup polarity */ +#define SAM_RSTC_WKEN_OFFSET 0x000c /* Wakeup enable */ +#define SAM_RSTC_WKCAUSE_OFFSET 0x0010 /* Wakeup cause */ + +/* RSTC register addresses *******************************************************************/ + +#define SAM_RSTC_RCAUSE (SAM_RSTC_BASE+SAM_RSTC_RCAUSE_OFFSET) +#define SAM_RSTC_BKUPEXIT (SAM_RSTC_BASE+SAM_RSTC_BKUPEXIT_OFFSET) +#define SAM_RSTC_WKDBCONF (SAM_RSTC_BASE+SAM_RSTC_WKDBCONF_OFFSET) +#define SAM_RSTC_WKPOL (SAM_RSTC_BASE+SAM_RSTC_WKPOL_OFFSET) +#define SAM_RSTC_WKEN (SAM_RSTC_BASE+SAM_RSTC_WKEN_OFFSET) +#define SAM_RSTC_WKCAUSE (SAM_RSTC_BASE+SAM_RSTC_WKCAUSE_OFFSET) + +/* RSTC register bit definitions *************************************************************/ + +/* Reset cause */ + +#define RSTC_RCAUSE_POR (1 << 0) /* Bit 0: Power on reset */ +#define RSTC_RCAUSE_BOD12 (1 << 1) /* Bit 1: Brown out 12 detector reset */ +#define RSTC_RCAUSE_BOD33 (1 << 2) /* Bit 2: Brown out 33 detector reset */ +#define RSTC_RCAUSE_EXT (1 << 4) /* Bit 4: External reset */ +#define RSTC_RCAUSE_WDT (1 << 5) /* Bit 5: Watchdog reset */ +#define RSTC_RCAUSE_SYST (1 << 6) /* Bit 6: System reset request */ +#define RSTC_RCAUSE_BACKUP (1 << 7) /* Bit 7: Backup reset*/ + +/* Backup exit source */ + +#define RSTC_BKUPEXIT_EXTWAKE (1 << 0) /* Bit 0: External wakeup */ +#define RSTC_BKUPEXIT_RTC (1 << 1) /* Bit 1: Real time counter interrupt */ +#define RSTC_BKUPEXIT_BBPS (1 << 2) /* Bit 2: Battery backup power switch */ + +/* Wakeup debounce count */ + +#define RSTC_WKDBCONF_MASK (0x1f) + +/* Wakeup polarity */ + +#define RSTC_WKPOL_PIN(n) (1 << (n)) /* Bit n:Input pin n active high */ +# define RSTC_WKPOL_PIN0 (1 << 0) /* Bit 0: Input pin 0 active high */ +# define RSTC_WKPOL_PIN1 (1 << 1) /* Bit 1: Input pin 1 active high */ +# define RSTC_WKPOL_PIN2 (1 << 2) /* Bit 2: Input pin 2 active high */ +# define RSTC_WKPOL_PIN3 (1 << 3) /* Bit 3: Input pin 3 active high */ +# define RSTC_WKPOL_PIN4 (1 << 4) /* Bit 4: Input pin 4 active high */ +# define RSTC_WKPOL_PIN5 (1 << 5) /* Bit 5: Input pin 5 active high */ +# define RSTC_WKPOL_PIN6 (1 << 6) /* Bit 6: Input pin 6 active high */ +# define RSTC_WKPOL_PIN7 (1 << 7) /* Bit 7: Input pin 7 active high */ + +/* Wakeup enable */ + +#define RSTC_WKEN_PIN(n) (1 << (n)) /* Bit n: Wakeup input pin n enabled */ +# define RSTC_WKEN_PIN0 (1 << 0) /* Bit 0: Wakeup input pin 0 enabled */ +# define RSTC_WKEN_PIN1 (1 << 1) /* Bit 1: Wakeup input pin 1 enabled */ +# define RSTC_WKEN_PIN2 (1 << 2) /* Bit 2: Wakeup input pin 2 enabled */ +# define RSTC_WKEN_PIN3 (1 << 3) /* Bit 3: Wakeup input pin 3 enabled */ +# define RSTC_WKEN_PIN4 (1 << 4) /* Bit 4: Wakeup input pin 4 enabled */ +# define RSTC_WKEN_PIN5 (1 << 5) /* Bit 5: Wakeup input pin 5 enabled */ +# define RSTC_WKEN_PIN6 (1 << 6) /* Bit 6: Wakeup input pin 6 enabled */ +# define RSTC_WKEN_PIN7 (1 << 7) /* Bit 7: Wakeup input pin 7 enabled */ + +/* Wakeup cause */ + +#define RSTC_WKCAUSE_PIN(n) (1 << (n)) /* Bit n: WKCAUSE n active and enabled */ +# define RSTC_WKCAUSE_PIN0 (1 << 0) /* Bit 0: WKCAUSE 0 active and enabled */ +# define RSTC_WKCAUSE_PIN1 (1 << 1) /* Bit 1: WKCAUSE 1 active and enabled */ +# define RSTC_WKCAUSE_PIN2 (1 << 2) /* Bit 2: WKCAUSE 2 active and enabled */ +# define RSTC_WKCAUSE_PIN3 (1 << 3) /* Bit 3: WKCAUSE 3 active and enabled */ +# define RSTC_WKCAUSE_PIN4 (1 << 4) /* Bit 4: WKCAUSE 4 active and enabled */ +# define RSTC_WKCAUSE_PIN5 (1 << 5) /* Bit 5: WKCAUSE 5 active and enabled */ +# define RSTC_WKCAUSE_PIN6 (1 << 6) /* Bit 6: WKCAUSE 6 active and enabled */ +# define RSTC_WKCAUSE_PIN7 (1 << 7) /* Bit 7: WKCAUSE 7 active and enabled */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_RSTC_H */ diff --git a/arch/arm/src/samdl/chip/saml_sercom.h b/arch/arm/src/samdl/chip/saml_sercom.h new file mode 100644 index 0000000000000000000000000000000000000000..da7cea14549f91e9aa93ecf8c34cd9efd1d077ad --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_sercom.h @@ -0,0 +1,67 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_sercom.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SERCOM_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SERCOM_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SERCOM_H */ diff --git a/arch/arm/src/samdl/chip/saml_spi.h b/arch/arm/src/samdl/chip/saml_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..f69c14e6b932b1696ba5cf8a2342f2e6389397ac --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_spi.h @@ -0,0 +1,251 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_spi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SPI_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SPI_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/saml_sercom.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* SPI register offsets *********************************************************************/ + +#define SAM_SPI_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_SPI_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_SPI_BAUD_OFFSET 0x000c /* Baud register */ +#define SAM_SPI_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +#define SAM_SPI_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +#define SAM_SPI_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +#define SAM_SPI_STATUS_OFFSET 0x001a /* Status register */ +#define SAM_SPI_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +#define SAM_SPI_ADDR_OFFSET 0x0024 /* Address register */ +#define SAM_SPI_DATA_OFFSET 0x0028 /* Data register */ +#define SAM_SPI_DBGCTRL_OFFSET 0x0030 /* Debug control register */ + +/* SPI register addresses *******************************************************************/ + +#define SAM_SPI0_CTRLA (SAM_SERCOM0_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI0_CTRLB (SAM_SERCOM0_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI0_BAUD (SAM_SERCOM0_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI0_INTENCLR (SAM_SERCOM0_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI0_INTENSET (SAM_SERCOM0_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI0_INTFLAG (SAM_SERCOM0_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI0_STATUS (SAM_SERCOM0_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI0_ADDR (SAM_SERCOM0_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI0_DATA (SAM_SERCOM0_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI0_DBGCTRL (SAM_SERCOM0_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI1_CTRLA (SAM_SERCOM1_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI1_CTRLB (SAM_SERCOM1_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI1_BAUD (SAM_SERCOM1_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI1_INTENCLR (SAM_SERCOM1_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI1_INTENSET (SAM_SERCOM1_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI1_INTFLAG (SAM_SERCOM1_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI1_STATUS (SAM_SERCOM1_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI1_ADDR (SAM_SERCOM1_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI1_DATA (SAM_SERCOM1_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI1_DBGCTRL (SAM_SERCOM1_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI2_CTRLA (SAM_SERCOM2_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI2_CTRLB (SAM_SERCOM2_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI2_BAUD (SAM_SERCOM2_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI2_INTENCLR (SAM_SERCOM2_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI2_INTENSET (SAM_SERCOM2_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI2_INTFLAG (SAM_SERCOM2_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI2_STATUS (SAM_SERCOM2_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI2_ADDR (SAM_SERCOM2_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI2_DATA (SAM_SERCOM2_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI2_DBGCTRL (SAM_SERCOM2_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI3_CTRLA (SAM_SERCOM3_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI3_CTRLB (SAM_SERCOM3_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI3_BAUD (SAM_SERCOM3_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI3_INTENCLR (SAM_SERCOM3_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI3_INTENSET (SAM_SERCOM3_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI3_INTFLAG (SAM_SERCOM3_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI3_STATUS (SAM_SERCOM3_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI3_ADDR (SAM_SERCOM3_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI3_DATA (SAM_SERCOM3_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI3_DBGCTRL (SAM_SERCOM3_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI4_CTRLA (SAM_SERCOM4_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI4_CTRLB (SAM_SERCOM4_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI4_BAUD (SAM_SERCOM4_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI4_INTENCLR (SAM_SERCOM4_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI4_INTENSET (SAM_SERCOM4_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI4_INTFLAG (SAM_SERCOM4_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI4_STATUS (SAM_SERCOM4_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI4_ADDR (SAM_SERCOM4_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI4_DATA (SAM_SERCOM4_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI4_DBGCTRL (SAM_SERCOM4_BASE+SAM_SPI_DBGCTRL_OFFSET) + +#define SAM_SPI5_CTRLA (SAM_SERCOM5_BASE+SAM_SPI_CTRLA_OFFSET) +#define SAM_SPI5_CTRLB (SAM_SERCOM5_BASE+SAM_SPI_CTRLB_OFFSET) +#define SAM_SPI5_BAUD (SAM_SERCOM5_BASE+SAM_SPI_BAUD_OFFSET) +#define SAM_SPI5_INTENCLR (SAM_SERCOM5_BASE+SAM_SPI_INTENCLR_OFFSET) +#define SAM_SPI5_INTENSET (SAM_SERCOM5_BASE+SAM_SPI_INTENSET_OFFSET) +#define SAM_SPI5_INTFLAG (SAM_SERCOM5_BASE+SAM_SPI_INTFLAG_OFFSET) +#define SAM_SPI5_STATUS (SAM_SERCOM5_BASE+SAM_SPI_STATUS_OFFSET) +#define SAM_SPI5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_SPI_SYNCBUSY_OFFSET) +#define SAM_SPI5_ADDR (SAM_SERCOM5_BASE+SAM_SPI_ADDR_OFFSET) +#define SAM_SPI5_DATA (SAM_SERCOM5_BASE+SAM_SPI_DATA_OFFSET) +#define SAM_SPI5_DBGCTRL (SAM_SERCOM5_BASE+SAM_SPI_DBGCTRL_OFFSET) + +/* SPI register bit definitions *************************************************************/ + +/* Control A register */ + +#define SPI_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define SPI_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SPI_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define SPI_CTRLA_MODE_MASK (7 << SPI_CTRLA_MODE_SHIFT) +# define SPI_CTRLA_MODE_SLAVE (2 << SPI_CTRLA_MODE_SHIFT) /* SPI slave operation */ +# define SPI_CTRLA_MODE_MASTER (3 << SPI_CTRLA_MODE_SHIFT) /* SPI master operation */ +#define SPI_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define SPI_CTRLA_IBON (1 << 8) /* Bit 8: Immediate BUFOVF notification */ +#define SPI_CTRLA_DOPO_SHIFT (16) /* Bit 16-17: Data out pinout */ +#define SPI_CTRLA_DOPO_MASK (3 << SPI_CTRLA_DOPO_SHIFT) /* Bit 16-17: Data out pinout */ +# define SPI_CTRLA_DOPO_DOPAD012 (0 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD0 SCK=PAD1 SS=PAD2 */ +# define SPI_CTRLA_DOPO_DOPAD231 (1 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD2 SCK=PAD3 SS=PAD1 */ +# define SPI_CTRLA_DOPO_DOPAD312 (2 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD3 SCK=PAD1 SS=PAD2 */ +# define SPI_CTRLA_DOPO_DOPAD031 (3 << SPI_CTRLA_DOPO_SHIFT) /* D0=PAD0 SCK=PAD3 SS=PAD1 */ +#define SPI_CTRLA_DIPO_SHIFT (20) /* Bits 20-21: Data in pinout */ +#define SPI_CTRLA_DIPO_MASK (3 << SPI_CTRLA_DIPO_SHIFT) +# define SPI_CTRLA_DIPAD0 (0 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD0 for DI */ +# define SPI_CTRLA_DIPAD1 (1 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD1 for DI */ +# define SPI_CTRLA_DIPAD2 (2 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD2 for DI */ +# define SPI_CTRLA_DIPAD3 (3 << SPI_CTRLA_DIPO_SHIFT) /* SERCOM PAD3 for DI */ +#define SPI_CTRLA_FORM_SHIFT (24) /* Bits 24-27: Frame format */ +#define SPI_CTRLA_FORM_MASK (7 << SPI_CTRLA_FORM_SHIFT) +# define SPI_CTRLA_FORM_SPI (0 << SPI_CTRLA_FORM_SHIFT) /* SPI frame (no address) */ +# define SPI_CTRLA_FORM_ADDR (2 << SPI_CTRLA_FORM_SHIFT) /* SPI frame (w/address) */ +#define SPI_CTRLA_CPHA (1 << 28) /* Bit 28: Clock phase */ +#define SPI_CTRLA_CPOL (1 << 29) /* Bit 29: Clock polarity */ +#define SPI_CTRLA_DORD (1 << 30) /* Bit 30: Data order */ +# define SPI_CTRLA_MSBFIRST (0) +# define SPI_CTRLA_LSBFIRST SPI_CTRLA_DORD + +/* Control B register */ + +#define SPI_CTRLB_CHSIZE_SHIFT (0) /* Bits 0-2: Character Size */ +#define SPI_CTRLB_CHSIZE_MASK (7 << SPI_CTRLB_CHSIZE_SHIFT) +# define SPI_CTRLB_CHSIZE_8BITS (0 << SPI_CTRLB_CHSIZE_SHIFT) /* 8 bits */ +# define SPI_CTRLB_CHSIZE_9BITS (1 << SPI_CTRLB_CHSIZE_SHIFT) /* 9 bits */ +#define SPI_CTRLB_PLOADEN (1 << 6) /* Bit 6: Slave Data Preload Enable */ +#define SPI_CTRLB_SSDE (1 << 9) /* Bit 9: Slave select low detect enable */ +#define SPI_CTRLB_MSSEN (1 << 13) /* Bit 13: Master slave select enable */ +#define SPI_CTRLB_AMODE_SHIFT (14) /* Bits 14-15: Address Mode */ +#define SPI_CTRLB_AMODE_MASK (3 << SPI_CTRLB_AMODE_SHIFT) +# define SPI_CTRLB_AMODE_ADDRMASK (0 << SPI_CTRLB_AMODE_SHIFT) /* ADDRMASK used to mask ADDR */ +# define SPI_CTRLB_AMODE_2ADDRS (1 << SPI_CTRLB_AMODE_SHIFT) /* Slave 2 addresses: ADDR & ADDRMASK */ +# define SPI_CTRLB_AMODE_RANGE (2 << SPI_CTRLB_AMODE_SHIFT) /* Slave range of addresses: ADDRMASK-ADDR */ +#define SPI_CTRLB_RXEN (1 << 17) /* Bit 17: Receiver enable */ + +/* Baud register (8-bit baud value) */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define SPI_INT_DRE (1 << 0) /* Bit 0: Data register empty interrupt */ +#define SPI_INT_TXC (1 << 1) /* Bit 1: Transmit complete interrupt */ +#define SPI_INT_RXC (1 << 2) /* Bit 2: Receive complete interrupt */ +#define SPI_INT_SSL (1 << 3) /* Bit 3: Slave select low interrupt */ +#define SPI_INT_ERROR (1 << 7) /* Bit 7: Error interrupt */ + +#define SPI_INT_ALL (0x8f) + +/* Status register */ + +#define SPI_STATUS_BUFOVF (1 << 2) /* Bit 2: Buffer overflow */ + +#define SPI_STATUS_CLRALL SPI_STATUS_BUFOVF + +/* Synchronization busy register */ + +#define SPI_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +#define SPI_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +#define SPI_SYNCBUSY_CTRLB (1 << 2) /* Bit 2: CTRLB synchronization busy */ + +/* Address register */ + +#define SPI_ADDR_SHIFT (0) /* Bits 0-7: Address */ +#define SPI_ADDR_MASK (0xff << SPI_ADDR_SHIFT) +# define SPI_ADDR(n) ((uint32_t)(n) << SPI_ADDR_SHIFT) +#define SPI_ADDRMASK_SHIFT (16) /* Bits 16-23: Address Mask */ +#define SPI_ADDRMASK_MASK (0xff << SPI_ADDRMASK_SHIFT) +# define SPI_ADDRMASK(n) ((uint32_t)(n) << SPI_ADDRMASK_SHIFT) + +/* Data register */ + +#define SPI_DATA_MASK (0x1ff) /* Bits 0-8: Data */ + +/* Debug control register */ + +#define SPI_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SPI_H */ diff --git a/arch/arm/src/samdl/chip/saml_supc.h b/arch/arm/src/samdl/chip/saml_supc.h new file mode 100644 index 0000000000000000000000000000000000000000..3e9fad113f36ee460f0c475a513e2cf76e90fcd3 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_supc.h @@ -0,0 +1,263 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_supc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SUPC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SUPC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* SUPC register offsets *********************************************************************/ + +#define SAM_SUPC_INTENCLR_OFFSET 0x0000 /* Interrupt enable clear */ +#define SAM_SUPC_INTENSET_OFFSET 0x0004 /* Interrupt enable set */ +#define SAM_SUPC_INTFLAG_OFFSET 0x0008 /* Interrupt flag status and clear */ +#define SAM_SUPC_STATUS_OFFSET 0x000c /* Status */ +#define SAM_SUPC_BOD33_OFFSET 0x0010 /* 3.3V brown-out detector control */ + +#define SAM_SUPC_BOD12_OFFSET 0x0014 /* 1.2V brown-out detctor control */ +#define SAM_SUPC_VREG_OFFSET 0x0018 /* Voltage regulator system control */ + +#define SAM_SUPC_VREF_OFFSET 0x001c /* Voltage references system control */ + +#define SAM_SUPC_BBPS_OFFSET 0x0020 /* Battery backup power switch control */ +#define SAM_SUPC_BKOUT_OFFSET 0x0024 /* Backup output control */ +#define SAM_SUPC_BKIN_OFFSET 0x0028 /* Backup input value */ + +/* SUPC register addresses *******************************************************************/ + +#define SAM_SUPC_INTENCLR (SAM_SUPC_BASE+SAM_SUPC_INTENCLR_OFFSET) +#define SAM_SUPC_INTENSET (SAM_SUPC_BASE+SAM_SUPC_INTENSET_OFFSET) +#define SAM_SUPC_INTFLAG (SAM_SUPC_BASE+SAM_SUPC_INTFLAG_OFFSET) +#define SAM_SUPC_STATUS (SAM_SUPC_BASE+SAM_SUPC_STATUS_OFFSET) +#define SAM_SUPC_BOD33 (SAM_SUPC_BASE+SAM_SUPC_BOD33_OFFSET) +#define SAM_SUPC_BOD12 (SAM_SUPC_BASE+SAM_SUPC_BOD12_OFFSET) +#define SAM_SUPC_VREG (SAM_SUPC_BASE+SAM_SUPC_VREG_OFFSET) +#define SAM_SUPC_VREF (SAM_SUPC_BASE+SAM_SUPC_VREF_OFFSET) +#define SAM_SUPC_BBPS (SAM_SUPC_BASE+SAM_SUPC_BBPS_OFFSET) +#define SAM_SUPC_BKOUT (SAM_SUPC_BASE+SAM_SUPC_BKOUT_OFFSET) +#define SAM_SUPC_BKIN (SAM_SUPC_BASE+SAM_SUPC_BKIN_OFFSET) + +/* SUPC register bit definitions *************************************************************/ + +/* Interrupt enable clear, Interrupt enable set, Interrupt flag status and clear, and + * Status registers. + */ + +#define SUPC_INT_BOD33RDY (1 << 0) /* Bit 0: BOD33 ready interrupt */ +#define SUPC_INT_BOD33DET (1 << 1) /* Bit 1: BOD33 detection interrupt */ +#define SUPC_INT_B33SRDY (1 << 2) /* Bit 2: BOD33 synchronization ready interrupt */ +#define SUPC_INT_BOD12RDY (1 << 3) /* Bit 3: BOD12 ready interrupt */ +#define SUPC_INT_BOD12DET (1 << 4) /* Bit 4: BOD12 detection interrupt */ +#define SUPC_INT_B12SRDY (1 << 5) /* Bit 5: BOD12 synchronization ready interrupt */ +#define SUPC_INT_VREGRDY (1 << 8) /* Bit 8: Voltage regulator ready interrupt */ +#define SUPC_INT_APWSRDY (1 << 9) /* Bit 9: Automatic power switch ready interrupt */ +#define SUPC_INT_VCORERDY (1 << 10) /* Bit 10: VDDCORE voltage ready interrupt */ + +#define SUPC_INT_ALL (0x0000073f) + +/* 3.3V brown-out detector control register */ + +#define SUPC_BOD33_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SUPC_BOD33_HYST (1 << 2) /* Bit 2: Hysteresis */ +#define SUPC_BOD33_ACTION_SHIFT (3) /* Bits 3-4: BOD33 action */ +#define SUPC_BOD33_ACTION_MASK (3 << SUPC_BOD33_ACTION_SHIFT) +# define SUPC_BOD33_ACTION(n) ((n) << SUPC_BOD33_ACTION_SHIFT) +# define SUPC_BOD33_ACTION_NONE (0 << SUPC_BOD33_ACTION_SHIFT) /* No action */ +# define SUPC_BOD33_ACTION_RESET (1 << SUPC_BOD33_ACTION_SHIFT) /* BOD33 generates reset */ +# define SUPC_BOD33_ACTION_INTR (2 << SUPC_BOD33_ACTION_SHIFT) /* BOD33 generates interrupt */ +# define SUPC_BOD33_ACTION_BKUP (3 << SUPC_BOD33_ACTION_SHIFT) /* BOD33 backup sleep mode */ +#define SUPC_BOD33_STDBYCFG (1 << 5) /* Bit 5: BOD33 configuration in standby sleep mode */ +#define SUPC_BOD33_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SUPC_BOD33_RUNBKUP (1 << 7) /* Bit 7: BOD33 configuration in backup sleep */ +#define SUPC_BOD33_ACTCFG (1 << 8) /* Bit 8: BOD33 configuration in active sleep */ +#define SUPC_BOD33_VMON (1 << 10) /* Bit 10: Voltage monitored in active and standby */ +#define SUPC_BOD33_PSEL_SHIFT (12) /* Bits 12-15: Prescaler select */ +#define SUPC_BOD33_PSEL_MASK (15 << SUPC_BOD33_PSEL_SHIFT) +# define SUPC_BOD33_PSEL(n) ((uint32_t)(n) << SUPC_BOD33_PSEL_SHIFT) +# define SUPC_BOD33_PSEL_DIV2 (0 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 2 */ +# define SUPC_BOD33_PSEL_DIV4 (1 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 4 */ +# define SUPC_BOD33_PSEL_DIV8 (2 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 8 */ +# define SUPC_BOD33_PSEL_DIV16 (3 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 16 */ +# define SUPC_BOD33_PSEL_DIV32 (4 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 32 */ +# define SUPC_BOD33_PSEL_DIV64 (5 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 64 */ +# define SUPC_BOD33_PSEL_DIV128 (6 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 128 */ +# define SUPC_BOD33_PSEL_DIV256 (7 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 256 */ +# define SUPC_BOD33_PSEL_DIV512 (8 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 512 */ +# define SUPC_BOD33_PSEL_DIV1K (9 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 1024 */ +# define SUPC_BOD33_PSEL_DIV2K (10 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 2048 */ +# define SUPC_BOD33_PSEL_DIV4K (11 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 4096 */ +# define SUPC_BOD33_PSEL_DIV8K (12 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 8192 */ +# define SUPC_BOD33_PSEL_DIV16K (13 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 16384 */ +# define SUPC_BOD33_PSEL_DIV32K (14 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 32768 */ +# define SUPC_BOD33_PSEL_DIV64K (15 << SUPC_BOD33_PSEL_SHIFT) /* Divide clock by 65536 */ +#define SUPC_BOD33_LEVEL_SHIFT (16) /* Bits 16-21: BOD33 threshold level VDD */ +#define SUPC_BOD33_LEVEL_MASK (0x3f << SUPC_BOD33_LEVEL_SHIFT) +# define SUPC_BOD33_LEVEL(n) ((uint32_t)(n) << SUPC_BOD33_LEVEL_SHIFT) +#define SUPC_BOD33_BKUPLEVEL_SHIFT (24) /* Bits 24-29: BOD33 threshold VBAT/backup sleep level */ +#define SUPC_BOD33_BKUPLEVEL_MASK (0x3f << SUPC_BOD33_BKUPLEVEL_SHIFT) +# define SUPC_BOD33_BKUPLEVEL(n) ((uint32_t)(n) << SUPC_BOD33_BKUPLEVEL_SHIFT) + +/* 1.2V brown-out detctor control */ + +#define SUPC_BOD12_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SUPC_BOD12_HYST (1 << 2) /* Bit 2: Hysteresis */ +#define SUPC_BOD12_ACTION_SHIFT (3) /* Bits 3-4: BOD12 action */ +#define SUPC_BOD12_ACTION_MASK (3 << SUPC_BOD12_ACTION_SHIFT) +# define SUPC_BOD12_ACTION(n) ((n) << SUPC_BOD12_ACTION_SHIFT) +# define SUPC_BOD12_ACTION_NONE (0 << SUPC_BOD12_ACTION_SHIFT) /* No action */ +# define SUPC_BOD12_ACTION_RESET (1 << SUPC_BOD12_ACTION_SHIFT) /* BOD12 generates reset */ +# define SUPC_BOD12_ACTION_INTR (2 << SUPC_BOD12_ACTION_SHIFT) /* BOD12 generates interrupt */ +#define SUPC_BOD12_STDBYCFG (1 << 5) /* Bit 5: BOD12 configuration in standby sleep mode */ +#define SUPC_BOD12_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SUPC_BOD12_ACTCFG (1 << 8) /* Bit 8: BOD12 configuration in active sleep */ +#define SUPC_BOD12_PSEL_SHIFT (12) /* Bits 12-15: Prescaler select */ +#define SUPC_BOD12_PSEL_MASK (15 << SUPC_BOD12_PSEL_SHIFT) +# define SUPC_BOD12_PSEL(n) ((uint32_t)(n) << SUPC_BOD12_PSEL_SHIFT) +# define SUPC_BOD12_PSEL_DIV2 (0 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 2 */ +# define SUPC_BOD12_PSEL_DIV4 (1 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 4 */ +# define SUPC_BOD12_PSEL_DIV8 (2 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 8 */ +# define SUPC_BOD12_PSEL_DIV16 (3 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 16 */ +# define SUPC_BOD12_PSEL_DIV32 (4 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 32 */ +# define SUPC_BOD12_PSEL_DIV64 (5 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 64 */ +# define SUPC_BOD12_PSEL_DIV128 (6 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 128 */ +# define SUPC_BOD12_PSEL_DIV256 (7 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 256 */ +# define SUPC_BOD12_PSEL_DIV512 (8 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 512 */ +# define SUPC_BOD12_PSEL_DIV1K (9 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 1024 */ +# define SUPC_BOD12_PSEL_DIV2K (10 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 2048 */ +# define SUPC_BOD12_PSEL_DIV4K (11 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 4096 */ +# define SUPC_BOD12_PSEL_DIV8K (12 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 8192 */ +# define SUPC_BOD12_PSEL_DIV16K (13 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 16384 */ +# define SUPC_BOD12_PSEL_DIV32K (14 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 32768 */ +# define SUPC_BOD12_PSEL_DIV64K (15 << SUPC_BOD12_PSEL_SHIFT) /* Divide clock by 65536 */ +#define SUPC_BOD12_LEVEL_SHIFT (16) /* Bits 16-21: BOD12 threshold level */ +#define SUPC_BOD12_LEVEL_MASK (0x3f << SUPC_BOD12_LEVEL_SHIFT) +# define SUPC_BOD12_LEVEL(n) ((uint32_t)(n) << SUPC_BOD12_LEVEL_SHIFT) + +/* Voltage regulator system control */ + +#define SUPC_VREG_ENABLE (1 << 1) /* Bit 1: Enable */ +#define SUPC_VREG_SEL (1 << 2) /* Bit 2: Voltage regulator selection */ +#define SUPC_VREG_RUNDSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SUPC_VREG_LPEFF (1 << 8) /* Bit 8: Low power mode efficiency */ +#define SUPC_VREG_VSVSTEP_SHIFT (16) /* Bits 16-19: Voltage scaling step */ +#define SUPC_VREG_VSVSTEP_MASK (15 << SUPC_VREG_VSVSTEP_SHIFT) +# define SUPC_VREG_VSVSTEP(n) ((uint32_t)(n) << SUPC_VREG_VSVSTEP_SHIFT) +#define SUPC_VREG_VSPER_SHIFT (24) /* Bits 24-31: Voltage scaling period */ +#define SUPC_VREG_VSPER_MASK (0xff << SUPC_VREG_VSPER_SHIFT) +# define SUPC_VREG_VSPER(n) ((uint32_t)(n) << SUPC_VREG_VSPER_SHIFT) + +/* Voltage references system control register */ + +#define SUPC_VREF_TSEN (1 << 1) /* Bit 1: Temperature sensor enable */ +#define SUPC_VREF_VREFOE (1 << 2) /* Bit 2: Voltage reference output enable */ +#define SUPC_VREF_RUNSTDBY (1 << 6) /* Bit 6: Run in standby */ +#define SUPC_VREF_ONDEMAND (1 << 7) /* Bit 7: On demand control */ +#define SUPC_VREF_SEL_SHIFT (16) /* Bits 16-19: Voltage reference selection */ +#define SUPC_VREF_SEL_MASK (15 << SUPC_VREF_SEL_SHIFT) +# define SUPC_VREF_SEL_1V0 (0 << SUPC_VREF_SEL_SHIFT) /* 1.0V voltage reference typical value */ +# define SUPC_VREF_SEL_1V1 (1 << SUPC_VREF_SEL_SHIFT) /* 1.1V voltage reference typical value */ +# define SUPC_VREF_SEL_1V2 (2 << SUPC_VREF_SEL_SHIFT) /* 1.2V voltage reference typical value */ +# define SUPC_VREF_SEL_1V25 (3 << SUPC_VREF_SEL_SHIFT) /* 1.25V voltage reference typical value */ +# define SUPC_VREF_SEL_2V0 (4 << SUPC_VREF_SEL_SHIFT) /* 2.0V voltage reference typical value */ +# define SUPC_VREF_SEL_2V2 (5 << SUPC_VREF_SEL_SHIFT) /* 2.2V voltage reference typical value */ +# define SUPC_VREF_SEL_2V4 (6 << SUPC_VREF_SEL_SHIFT) /* 2.4V voltage reference typical value */ +# define SUPC_VREF_SEL_2V5 (7 << SUPC_VREF_SEL_SHIFT) /* 5.5V voltage reference typical value */ + + +/* Battery backup power switch control */ + +#define SUPC_BBPS_CONFIG_SHIFT (0) /* Bits 0-1: Battery backup power switch configuration */ +#define SUPC_BBPS_CONFIG_MASK (3 << SUPC_BBPS_CONFIG_SHIFT) +# define SUPC_BBPS_CONFIG_NONE (0 << SUPC_BBPS_CONFIG_SHIFT) /* Backup domain from main power */ +# define SUPC_BBPS_CONFIG_APWS (1 << SUPC_BBPS_CONFIG_SHIFT) /* Automatic power switch */ +# define SUPC_BBPS_CONFIG_FORCED (2 << SUPC_BBPS_CONFIG_SHIFT) /* Backup domain from batter backup power */ +# define SUPC_BBPS_CONFIG_BOD33 (3 << SUPC_BBPS_CONFIG_SHIFT) /* Power switch handled by BOD33 */ +#define SUPC_BBPS_WAKEEN (1 << 2) /* Bit 2: Wake enable */ +#define SUPC_BBPS_PSOKEN (1 << 3) /* Bit 3: Power supply OK enable */ + +/* Backup output control */ + +#define SUPC_BKOUT_EN_SHIFT (0) /* Bits 0-1: Output enable */ +#define SUPC_BKOUT_EN_MASK (3 << SUPC_BKOUT_EN_SHIFT) +# define SUPC_BKOUT_DISABLE (0 << SUPC_BKOUT_EN_SHIFT) +# define SUPC_BKOUT_ENABLE (1 << SUPC_BKOUT_EN_SHIFT) +#define SUPC_BKOUT_CLR_SHIFT (8) /* Bits 8-9: Clear output */ +#define SUPC_BKOUT_CLR_MASK (3 << SUPC_BKOUT_CLR_SHIFT) +# define SUPC_BKOUT_CLR (1 << SUPC_BKOUT_CLR_SHIFT) +#define SUPC_BKOUT_SET_SHIFT (16) /* Bits 16-17: Set output */ +#define SUPC_BKOUT_SET_MASK (3 << SUPC_BKOUT_SET_SHIFT) +# define SUPC_BKOUT_SET (1 << SUPC_BKOUT_SET_SHIFT) +#define SUPC_BKOUT_RTCTGL_SHIFT (24) /* Bits 24-25: RTC toggle output */ +#define SUPC_BKOUT_RTCTGL_MASK (3 << SUPC_BKOUT_RTCTGL_SHIFT) +# define SUPC_BKOUT_RTCTGL_NONE (0 << SUPC_BKOUT_EN_SHIFT) /* No toggle */ +# define SUPC_BKOUT_RTCTGL_TOGGLE (1 << SUPC_BKOUT_EN_SHIFT) /* Toggle */ + +/* Backup input value */ + +#define SUPC_BKIN_SHIFT (0) /* Bits 0-2: Backup I/O data input value */ +#define SUPC_BKIN_MASK (7 << SUPC_BKIN_SHIFT) +# define SUPC_BKIN_PSOK (1 << SUPC_BKIN_SHIFT) /* Input value of PSOCK pin */ +# define SUPC_BKIN_OUT0 (2 << SUPC_BKIN_SHIFT) /* Input value of OUT[0] pin */ +# define SUPC_BKIN_OUT1 (4 << SUPC_BKIN_SHIFT) /* Input value of OUT[1] pin */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_SUPC_H */ diff --git a/arch/arm/src/samdl/chip/saml_trng.h b/arch/arm/src/samdl/chip/saml_trng.h new file mode 100644 index 0000000000000000000000000000000000000000..4c1daeeb863c0124a018663111cff640313723c1 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_trng.h @@ -0,0 +1,102 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_trng.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_TRNG_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_TRNG_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* TRNG register offsets ********************************************************************/ + +#define SAM_TRNG_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_TRNG_EVCTRL_OFFSET 0x0004 /* Event control register */ +#define SAM_TRNG_INTENCLR_OFFSET 0x0008 /* Interrupt enable clear register */ +#define SAM_TRNG_INTENSET_OFFSET 0x0009 /* Interrupt enable set register */ +#define SAM_TRNG_INTFLAG_OFFSET 0x000a /* Interrupt flag and status clear register */ +#define SAM_TRNG_DATA_OFFSET 0x0020 /* Output data register */ + +/* TRNG register addresses ******************************************************************/ + +#define SAM_TRNG_CTRLA (SAM_TRNG_BASE+SAM_TRNG_CTRLA_OFFSET) +#define SAM_TRNG_EVCTRL (SAM_TRNG_BASE+SAM_TRNG_EVCTRL_OFFSET) +#define SAM_TRNG_INTENCLR (SAM_TRNG_BASE+SAM_TRNG_INTENCLR_OFFSET) +#define SAM_TRNG_INTENSET (SAM_TRNG_BASE+SAM_TRNG_INTENSET_OFFSET) +#define SAM_TRNG_INTFLAG (SAM_TRNG_BASE+SAM_TRNG_INTFLAG_OFFSET) +#define SAM_TRNG_DATA (SAM_TRNG_BASE+SAM_TRNG_DATA_OFFSET) + +/* TRNG register bit definitions ************************************************************/ + +/* Control register */ + +#define TRNG_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define TRNG_CTRLA_WEN (1 << 6) /* Bit 6: Run in standby */ + +/* Event control register, Interrupt enable clear, interrupt enable set register, interrupt + * flag status registers. + */ + +#define TRNG_EVCTRL_DATARDY (1 << 0) /* Bit 0: Data ready */ + +/* Data register (32-bit data) */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_TRNG_H */ diff --git a/arch/arm/src/samdl/chip/saml_usart.h b/arch/arm/src/samdl/chip/saml_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..2327120b28420cb3ca4ad0fdf5d24d8545241090 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_usart.h @@ -0,0 +1,279 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_usart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USART_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USART_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/saml_sercom.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* USART register offsets *******************************************************************/ + +#define SAM_USART_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_USART_CTRLB_OFFSET 0x0004 /* Control B register */ +#define SAM_USART_BAUD_OFFSET 0x000c /* Baud register */ +#define SAM_USART_RXPL_OFFSET 0x000e /* Receive pulse length register */ +#define SAM_USART_INTENCLR_OFFSET 0x0014 /* Interrupt enable clear register */ +#define SAM_USART_INTENSET_OFFSET 0x0016 /* Interrupt enable set register */ +#define SAM_USART_INTFLAG_OFFSET 0x0018 /* Interrupt flag and status clear register */ +#define SAM_USART_STATUS_OFFSET 0x001a /* Status register */ +#define SAM_USART_SYNCBUSY_OFFSET 0x001c /* Synchronization busy register */ +#define SAM_USART_DATA_OFFSET 0x0028 /* Data register */ +#define SAM_USART_DBGCTRL_OFFSET 0x0030 /* Debug control register */ + +/* USART register addresses *****************************************************************/ + +#define SAM_USART0_CTRLA (SAM_SERCOM0_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART0_CTRLB (SAM_SERCOM0_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART0_BAUD (SAM_SERCOM0_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART0_RXPL (SAM_SERCOM0_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART0_INTENCLR (SAM_SERCOM0_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART0_INTENSET (SAM_SERCOM0_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART0_INTFLAG (SAM_SERCOM0_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART0_STATUS (SAM_SERCOM0_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART0_SYNCBUSY (SAM_SERCOM0_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART0_DATA (SAM_SERCOM0_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART0_DBGCTRL (SAM_SERCOM0_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART1_CTRLA (SAM_SERCOM1_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART1_CTRLB (SAM_SERCOM1_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART1_BAUD (SAM_SERCOM1_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART1_RXPL (SAM_SERCOM1_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART1_INTENCLR (SAM_SERCOM1_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART1_INTENSET (SAM_SERCOM1_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART1_INTFLAG (SAM_SERCOM1_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART1_STATUS (SAM_SERCOM1_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART1_SYNCBUSY (SAM_SERCOM1_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART1_DATA (SAM_SERCOM1_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART1_DBGCTRL (SAM_SERCOM1_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART2_CTRLA (SAM_SERCOM2_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART2_CTRLB (SAM_SERCOM2_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART2_BAUD (SAM_SERCOM2_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART2_RXPL (SAM_SERCOM2_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART2_INTENCLR (SAM_SERCOM2_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART2_INTENSET (SAM_SERCOM2_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART2_INTFLAG (SAM_SERCOM2_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART2_STATUS (SAM_SERCOM2_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART2_SYNCBUSY (SAM_SERCOM2_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART2_DATA (SAM_SERCOM2_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART2_DBGCTRL (SAM_SERCOM2_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART3_CTRLA (SAM_SERCOM3_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART3_CTRLB (SAM_SERCOM3_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART3_BAUD (SAM_SERCOM3_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART3_RXPL (SAM_SERCOM3_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART3_INTENCLR (SAM_SERCOM3_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART3_INTENSET (SAM_SERCOM3_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART3_INTFLAG (SAM_SERCOM3_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART3_STATUS (SAM_SERCOM3_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART3_SYNCBUSY (SAM_SERCOM3_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART3_DATA (SAM_SERCOM3_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART3_DBGCTRL (SAM_SERCOM3_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART4_CTRLA (SAM_SERCOM4_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART4_CTRLB (SAM_SERCOM4_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART4_BAUD (SAM_SERCOM4_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART4_RXPL (SAM_SERCOM4_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART4_INTENCLR (SAM_SERCOM4_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART4_INTENSET (SAM_SERCOM4_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART4_INTFLAG (SAM_SERCOM4_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART4_STATUS (SAM_SERCOM4_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART4_SYNCBUSY (SAM_SERCOM4_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART4_DATA (SAM_SERCOM4_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART4_DBGCTRL (SAM_SERCOM4_BASE+SAM_USART_DBGCTRL_OFFSET) + +#define SAM_USART5_CTRLA (SAM_SERCOM5_BASE+SAM_USART_CTRLA_OFFSET) +#define SAM_USART5_CTRLB (SAM_SERCOM5_BASE+SAM_USART_CTRLB_OFFSET) +#define SAM_USART5_BAUD (SAM_SERCOM5_BASE+SAM_USART_BAUD_OFFSET) +#define SAM_USART5_RXPL (SAM_SERCOM0_BASE+SAM_USART_RXPL_OFFSET) +#define SAM_USART5_INTENCLR (SAM_SERCOM5_BASE+SAM_USART_INTENCLR_OFFSET) +#define SAM_USART5_INTENSET (SAM_SERCOM5_BASE+SAM_USART_INTENSET_OFFSET) +#define SAM_USART5_INTFLAG (SAM_SERCOM5_BASE+SAM_USART_INTFLAG_OFFSET) +#define SAM_USART5_STATUS (SAM_SERCOM5_BASE+SAM_USART_STATUS_OFFSET) +#define SAM_USART5_SYNCBUSY (SAM_SERCOM5_BASE+SAM_USART_SYNCBUSY_OFFSET) +#define SAM_USART5_DATA (SAM_SERCOM5_BASE+SAM_USART_DATA_OFFSET) +#define SAM_USART5_DBGCTRL (SAM_SERCOM5_BASE+SAM_USART_DBGCTRL_OFFSET) + +/* USART register bit definitions ***********************************************************/ + +/* Control A register */ + +#define USART_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define USART_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define USART_CTRLA_MODE_SHIFT (2) /* Bits 2-4: Operating Mode */ +#define USART_CTRLA_MODE_MASK (7 << USART_CTRLA_MODE_SHIFT) +# define USART_CTRLA_MODE_EXTUSART (0 << USART_CTRLA_MODE_SHIFT) /* USART with external clock */ +# define USART_CTRLA_MODE_INTUSART (1 << USART_CTRLA_MODE_SHIFT) /* USART with internal clock */ +#define USART_CTRLA_RUNSTDBY (1 << 7) /* Bit 7: Run in standby */ +#define USART_CTRLA_IBON (1 << 8) /* Bit 8: Immediate BUFOVF notification */ +#define USART_CTRLA_SAMPR_SHIFT (11) /* Bits 11-12: Sample rate */ +#define USART_CTRLA_SAMPR_MASK (3 << USART_CTRLA_SAMPR_SHIFT) +# define USART_CTRLA_SAMPR_16XA (0 << USART_CTRLA_SAMPR_SHIFT) /* 16x oversampling; arithmetic baud */ +# define USART_CTRLA_SAMPR_16XF (1 << USART_CTRLA_SAMPR_SHIFT) /* 16x oversampling; fractional baud */ +# define USART_CTRLA_SAMPR_8XA (2 << USART_CTRLA_SAMPR_SHIFT) /* 8x oversampling; arithmetic baud */ +# define USART_CTRLA_SAMPR_8XF (3 << USART_CTRLA_SAMPR_SHIFT) /* 8x oversampling; fractional baud */ +# define USART_CTRLA_SAMPR_3XA (4 << USART_CTRLA_SAMPR_SHIFT) /* 3x oversampling; arithmetic baud */ +#define USART_CTRLA_TXPO_SHIFT (16) /* Bits 16-17: Transmit data pinout */ +#define USART_CTRLA_TXPO_MASK (3 << USART_CTRLA_TXPO_SHIFT) +# define USART_CTRLA_TXPAD0_1 (0 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[0]; XCK=PAD[1] */ +# define USART_CTRLA_TXPAD2 (1 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[2]; XCK=PAD[3] */ +# define USART_CTRLA_TXPAD0_2 (2 << USART_CTRLA_TXPO_SHIFT) /* TxD=SERCOM PAD[0]; RTS=PAD[2]; CTS=PAD[3] */ +#define USART_CTRLA_RXPO_SHIFT (20) /* Bits 20-21: Receive data pinout */ +#define USART_CTRLA_RXPO_MASK (3 << USART_CTRLA_RXPO_SHIFT) +# define USART_CTRLA_RXPAD0 (0 << USART_CTRLA_RXPO_SHIFT) /* RxD=SERCOM PAD[0] */ +# define USART_CTRLA_RXPAD1 (1 << USART_CTRLA_RXPO_SHIFT) /* RxD=SERCOM PAD[1] */ +# define USART_CTRLA_RXPAD2 (2 << USART_CTRLA_RXPO_SHIFT) /* RxD=SERCOM PAD[2] */ +# define USART_CTRLA_RXPAD3 (3 << USART_CTRLA_RXPO_SHIFT) /* RxD=SERCOM PAD[3] */ +#define USART_CTRLA_SAMPA_SHIFT (22) /* Bits 22-23: Sample adjustment */ +#define USART_CTRLA_SAMPA_MASK (3 << USART_CTRLA_SAMPA_SHIFT) +# define USART_CTRLA_SAMPA_789 (0 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 7-8-9 */ +# define USART_CTRLA_SAMPA_91011 (1 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 9-10-11 */ +# define USART_CTRLA_SAMPA_111213 (2 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 11-12-13 */ +# define USART_CTRLA_SAMPA_131415 (3 << USART_CTRLA_SAMPA_SHIFT) /* 16x oversampling 13-14-15 */ +# define USART_CTRLA_SAMPA_345 (0 << USART_CTRLA_SAMPA_SHIFT) /* 8x oversampling 3-4-5 */ +# define USART_CTRLA_SAMPA_456 (1 << USART_CTRLA_SAMPA_SHIFT) /* 8x oversampling 4-5-6 */ +# define USART_CTRLA_SAMPA_567 (2 << USART_CTRLA_SAMPA_SHIFT) /* 8x oversampling 5-6-7 */ +# define USART_CTRLA_SAMPA_6768 (3 << USART_CTRLA_SAMPA_SHIFT) /* 8x oversampling 6-7-8 */ +#define USART_CTRLA_FORM_SHIFT (24) /* Bits 24-27: Frame format */ +#define USART_CTRLA_FORM_MASK (7 << USART_CTRLA_FORM_SHIFT) +# define USART_CTRLA_FORM_NOPARITY (0 << USART_CTRLA_FORM_SHIFT) /* USART frame (no parity) */ +# define USART_CTRLA_FORM_PARITY (1 << USART_CTRLA_FORM_SHIFT) /* USART frame (w/parity) */ +# define USART_CTRLA_FORM_AUTOBAUD (4 << USART_CTRLA_FORM_SHIFT) /* Auto-baud (no parity) */ +# define USART_CTRLA_FORM_AUTOBAUDP (5 << USART_CTRLA_FORM_SHIFT) /* Auto-baud (w/ parity) */ +#define USART_CTRLA_CMODE (1 << 28) /* Bit 28: Communication mode */ +# define USART_CTRLA_ASYNCH (0) +# define USART_CTRLA_SYNCH USART_CTRLA_CMODE +#define USART_CTRLA_CPOL (1 << 29) /* Bit 29: Clock polarity */ +# define USART_CTRLA_CPOL_NORMAL (0) /* Rising XCK edge Falling XCK edge */ +# define USART_CTRLA_CPOL_INVERTED USART_CTRLA_CPOL /* Falling XCK edge Rising XCK edge */ +#define USART_CTRLA_DORD (1 << 30) /* Bit 30: Data order */ +# define USART_CTRLA_MSBFIRST (0) +# define USART_CTRLA_LSBFIRST USART_CTRLA_DORD + +/* Control B register */ + +#define USART_CTRLB_CHSIZE_SHIFT (0) /* Bits 0-2: Character Size */ +#define USART_CTRLB_CHSIZE_MASK (7 << USART_CTRLB_CHSIZE_SHIFT) +# define USART_CTRLB_CHSIZE_8BITS (0 << USART_CTRLB_CHSIZE_SHIFT) /* 8 bits */ +# define USART_CTRLB_CHSIZE_9BITS (1 << USART_CTRLB_CHSIZE_SHIFT) /* 9 bits */ +# define USART_CTRLB_CHSIZE_5BITS (5 << USART_CTRLB_CHSIZE_SHIFT) /* 5 bits */ +# define USART_CTRLB_CHSIZE_6BITS (6 << USART_CTRLB_CHSIZE_SHIFT) /* 6 bits */ +# define USART_CTRLB_CHSIZE_7BITS (7 << USART_CTRLB_CHSIZE_SHIFT) /* 7 bits */ +#define USART_CTRLB_SBMODE (1 << 6) /* Bit 6: Stop bit mode */ +# define USART_CTRLB_SBMODE_1 (0) +# define USART_CTRLB_SBMODE_2 USART_CTRLB_SBMODE +#define USART_CTRLB_COLDEN (1 << 8) /* Bit 8: Collision detection enable */ +#define USART_CTRLB_SFDE (1 << 9) /* Bit 9: Start of frame detection enable */ +#define USART_CTRLB_ENC (1 << 10) /* Bit 10: Encoding format */ +# define USART_CTRLB_UNENCODED (0) +# define USART_CTRLB_IRDA USART_CTRLB_ENC +#define USART_CTRLB_PMODE (1 << 13) /* Bit 13: Parity mode */ +# define USART_CTRLB_PEVEN (0) +# define USART_CTRLB_PODD USART_CTRLB_PMODE +#define USART_CTRLB_TXEN (1 << 16) /* Bit 16: Transmitter enable */ +#define USART_CTRLB_RXEN (1 << 17) /* Bit 17: Receiver enable */ + +/* Baud register (16-bit baud value) */ +/* Receive pulse length register (8-bit value) */ + +/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and + * status clear registers. + */ + +#define USART_INT_DRE (1 << 0) /* Bit 0: Data register empty interrupt */ +#define USART_INT_TXC (1 << 1) /* Bit 1: Transmit complete interrupt */ +#define USART_INT_RXC (1 << 2) /* Bit 2: Receive complete interrupt */ +#define USART_INT_RXS (1 << 3) /* Bit 3: Receive start interrupt */ +#define USART_INT_CTSIC (1 << 4) /* Bit 4: Clear to send input change interrupt */ +#define USART_INT_RXBRK (1 << 5) /* Bit 5: Receive break interrupt */ +#define USART_INT_ERROR (1 << 6) /* Bit 7: Error interrupt */ + +#define USART_INT_ALL (0xbf) + +/* Status register */ + +#define USART_STATUS_PERR (1 << 0) /* Bit 0: Parity error */ +#define USART_STATUS_FERR (1 << 1) /* Bit 1: Frame error */ +#define USART_STATUS_BUFOVF (1 << 2) /* Bit 2: Buffer overflow */ +#define USART_STATUS_CTS (1 << 3) /* Bit 3: Clear to send */ +#define USART_STATUS_ISF (1 << 4) /* Bit 4: Inconsistent sync field */ +#define USART_STATUS_COLL (1 << 5) /* Bit 5: Collision detected */ + +/* Synchronization busy register */ + +#define USART_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset synchronization busy */ +#define USART_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: SERCOM enable synchronization busy */ +#define USART_SYNCBUSY_CTRLB (1 << 2) /* Bit 2: CTRLB synchronization busy */ + +#define USART_SYNCBUSY_ALL 0x0007 + +/* Data register */ + +#define USART_DATA_MASK (0x1ff) /* Bits 0-8: Data */ + +/* Debug control register */ + +#define USART_DBGCTRL_DBGSTOP (1 << 0) /* Bit 0: Debug stop mode */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USART_H */ diff --git a/arch/arm/src/samdl/chip/saml_usb.h b/arch/arm/src/samdl/chip/saml_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..190df37d9f853cdbfda54ef61ed349c0c4466b59 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_usb.h @@ -0,0 +1,612 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_usb.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USB_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USB_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* USB register offsets ********************************************************************/ + +/* Common USB Device/Host Register Offsets */ + +#define SAM_USB_CTRLA_OFFSET 0x0000 /* Control A Register */ +#define SAM_USB_SYNCBUSY_OFFSET 0x0002 /* Synchronization Busy Register */ +#define SAM_USB_QOSCTRL_OFFSET 0x0003 /* QOS Control Register */ +#define SAM_USB_FSMSTATUS_OFFSET 0x000d /* Finite State Machine Register */ +#define SAM_USB_DESCADD_OFFSET 0x0024 /* Descriptor Address Register */ +#define SAM_USB_PADCAL_OFFSET 0x0028 /* Pad Calibration Register */ + +/* USB Device Register Offsets */ + +#define SAM_USBDEV_CTRLB_OFFSET 0x0008 /* Control B Register */ +#define SAM_USBDEV_DADD_OFFSET 0x000a /* Device Address Register */ +#define SAM_USBDEV_STATUS_OFFSET 0x000c /* Status Register */ +#define SAM_USBDEV_FNUM_OFFSET 0x0010 /* Device Frame Number Register */ +#define SAM_USBDEV_INTENCLR_OFFSET 0x0014 /* Device Ineterrupt Enable Clear Register */ +#define SAM_USBDEV_INTENSET_OFFSET 0x0018 /* Device interrupt Enable Set Register */ +#define SAM_USBDEV_INTFLAG_OFFSET 0x001c /* Device Interrupt Flag Register */ +#define SAM_USBDEV_EPINTSMRY_OFFSET 0x0020 /* Endpoint Interrupt Summary Register */ + +/* Endpoint Register n offset */ + +#define SAM_USBDEV_EP_OFFSET(n) (0x0100 + ((n) << 5)) + +/* The following are then relative to the endpoint register n offset */ + +#define SAM_USBDEV_EPCFG_OFFSET 0x0000 /* Device Endpoint Configuration Register */ +#define SAM_USBDEV_EPSTATUSCLR_OFFSET 0x0004 /* Endpoint Status Clear Register */ +#define SAM_USBDEV_EPSTATUSSET_OFFSET 0x0005 /* Endpoint Status Set Register */ +#define SAM_USBDEV_EPSTATUS_OFFSET 0x0006 /* Endpoint Status Register */ +#define SAM_USBDEV_EPINTFLAG_OFFSET 0x0007 /* Device Endpoint Interrupt Flag Register */ +#define SAM_USBDEV_EPINTENCLR_OFFSET 0x0008 /* Device Endpoint Interrupt Enable Register */ +#define SAM_USBDEV_EPINTENSET_OFFSET 0x0009 /* Device Endpoint Interrupt Set Register */ + +#define SAM_USBDEV_EPnCFG_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPCFG_OFFSET) +#define SAM_USBDEV_EPnSTATUSCLR_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPSTATUSCLR_OFFSET) +#define SAM_USBDEV_EPnSTATUSSET_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPSTATUSSET_OFFSET) +#define SAM_USBDEV_EPnSTATUS_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPSTATUS_OFFSET) +#define SAM_USBDEV_EPnINTFLAG_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPINTFLAG_OFFSET) +#define SAM_USBDEV_EPnINTENCLR_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPINTENCLR_OFFSET) +#define SAM_USBDEV_EPnINTENSET_OFFSET(n) (SAM_USBDEV_EP_OFFSET(n)+SAM_USBDEV_EPINTENSET_OFFSET) + +/* Device Endpoint Descriptor */ + +#define SAM_USBDEV_ADDR_OFFSET 0x0000 /* Address of Data buffer (Both banks) */ +#define SAM_USBDEV_PKTSIZE_OFFSET 0x0004 /* Packet Size (Both banks) */ +#define SAM_USBDEV_EXTREG_OFFSET 0x0008 /* Extended Register (Bank 0 only) */ +#define SAM_USBDEV_STATUSBK_OFFSET 0x000a /* Device Status Bank (Both banks) */ + +/* USB Host Register Offsets */ + +#define SAM_USBHOST_CTRLB_OFFSET 0x0008 /* Control B Register */ +#define SAM_USBHOST_HSOFC_OFFSET 0x000a /* Host Start-of-Frame Control Register */ +#define SAM_USBHOST_STATUS_OFFSET 0x000c /* Status Register */ +#define SAM_USBHOST_FNUM_OFFSET 0x0010 /* Host Frame Number Register */ +#define SAM_USBHOST_FLENHIGH_OFFSET 0x0012 /* Host Frame Length Register */ +#define SAM_USBHOST_INTENCLR_OFFSET 0x0014 /* Host Interrupt Enable Clear Register */ +#define SAM_USBHOST_INTENSET_OFFSET 0x0018 /* Host Interrupt Enable Set Register */ +#define SAM_USBHOST_INTFLAG_OFFSET 0x001c /* Host Interrupt Flag Status and Clear Register */ +#define SAM_USBHOST_PINTSMRY_OFFSET 0x0020 /* Pipe Interrupt Summary Register */ + +/* Pipe Register n Register */ + +#define SAM_USBHOST_PIPE_OFFSET(n) (0x0100 + ((n) << 4)) + +/* The following are then relative to the pipe register n offset */ + +#define SAM_USBHOST_PCFG_OFFSET 0x0000 /* Host Pipe Configuration Register */ +#define SAM_USBHOST_BINTERVAL_OFFSET 0x0003 /* Interval for Bulk-OUT/Ping Transaction Register */ +#define SAM_USBHOST_PSTATUSCLR_OFFSET 0x0004 /* Pipe Status Clear Register */ +#define SAM_USBHOST_PSTATUSET_OFFSET 0x0005 /* Pipe Status Set Register */ +#define SAM_USBHOST_PSTATUS_OFFSET 0x0006 /* Pipe Status Register */ +#define SAM_USBHOST_PINTFLAG_OFFSET 0x0007 /* Host Pipe Interrupt Flag Register */ +#define SAM_USBHOST_PINTENCLR_OFFSET 0x0008 /* Host Pipe Interrupt Clear Register */ +#define SAM_USBHOST_PINTENSET_OFFSET 0x0009 /* Host Pipe Interrupt Set Register */ + +#define SAM_USBHOST_PnCFG_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PCFG_OFFSET) +#define SAM_USBHOST_BINTERVALn_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_BINTERVAL_OFFSET) +#define SAM_USBHOST_PnSTATUSCLR_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PSTATUSCLR_OFFSET) +#define SAM_USBHOST_PnSTATUSET_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PSTATUSET_OFFSET) +#define SAM_USBHOST_PnSTATUS_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PSTATUS_OFFSET) +#define SAM_USBHOST_PnINTFLAG_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PINTFLAG_OFFSET) +#define SAM_USBHOST_PnINTENCLR_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PINTENCLR_OFFSET) +#define SAM_USBHOST_PnINTENSET_OFFSET(n) (SAM_USBHOST_PIPE_OFFSET(n)+SAM_USBHOST_PINTENSET_OFFSET) + +/* Host Pipe Descriptor */ + +#define SAM_USBHOST_ADDR_OFFSET 0x0000 /* Data buffer address (Both banks) */ +#define SAM_USBHOST_PKTSIZE_OFFSET 0x0004 /* Packet size (Both banks) */ +#define SAM_USBHOST_EXTREG_OFFSET 0x0008 /* Extended register (Bank 0 only) */ +#define SAM_USBHOST_STATUSBK_OFFSET 0x000a /* host status bank (Both banks) */ +#define SAM_USBHOST_CTRLPIPE_OFFSET 0x000c /* Host control pipe (Bank 0 only) */ +#define SAM_USBHOST_STATUSPIPE_OFFSET 0x000e /* Host status pipe (Both banks) */ + +/* USB register addresses ******************************************************************/ + +/* Common USB Device/Host Register Addresses */ + +#define SAM_USB_CTRLA (SAM_USB_BASE+SAM_USB_CTRLA_OFFSET) +#define SAM_USB_SYNCBUSY (SAM_USB_BASE+SAM_USB_SYNCBUSY_OFFSET) +#define SAM_USB_QOSCTRL (SAM_USB_BASE+SAM_USB_QOSCTRL_OFFSET) +#define SAM_USB_FSMSTATUS (SAM_USB_BASE+SAM_USB_FSMSTATUS_OFFSET) +#define SAM_USB_DESCADD (SAM_USB_BASE+SAM_USB_DESCADD_OFFSET) +#define SAM_USB_PADCAL (SAM_USB_BASE+SAM_USB_PADCAL_OFFSET) + +/* USB Device Register Addresses */ + +#define SAM_USBDEV_CTRLB (SAM_USB_BASE+SAM_USBDEV_CTRLB_OFFSET) +#define SAM_USBDEV_DADD (SAM_USB_BASE+SAM_USBDEV_DADD_OFFSET) +#define SAM_USBDEV_STATUS (SAM_USB_BASE+SAM_USBDEV_STATUS_OFFSET) +#define SAM_USBDEV_FNUM (SAM_USB_BASE+SAM_USBDEV_FNUM_OFFSET) +#define SAM_USBDEV_INTENCLR (SAM_USB_BASE+SAM_USBDEV_INTENCLR_OFFSET) +#define SAM_USBDEV_INTENSET (SAM_USB_BASE+SAM_USBDEV_INTENSET_OFFSET) +#define SAM_USBDEV_INTFLAG (SAM_USB_BASE+SAM_USBDEV_INTFLAG_OFFSET) +#define SAM_USBDEV_EPINTSMRY (SAM_USB_BASE+SAM_USBDEV_EPINTSMRY_OFFSET) + +/* Endpoint Register n Base Address */ + +#define SAM_USBDEV_EP_BASE(n) (SAM_USB_BASE+SAM_USBDEV_EP_OFFSET(n)) + +/* Endpoint n Register Addresses */ + +#define SAM_USBDEV_EPCFG(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPCFG_OFFSET) +#define SAM_USBDEV_EPSTATUSCLR(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPSTATUSCLR_OFFSET) +#define SAM_USBDEV_EPSTATUSSET(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPSTATUSSET_OFFSET) +#define SAM_USBDEV_EPSTATUS(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPSTATUS_OFFSET) +#define SAM_USBDEV_EPINTFLAG(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPINTFLAG_OFFSET) +#define SAM_USBDEV_EPINTENCLR(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPINTENCLR_OFFSET) +#define SAM_USBDEV_EPINTENSET(n) (SAM_USBDEV_EP_BASE(n)+SAM_USBDEV_EPINTENSET_OFFSET) + +/* USB Host Register Addresses */ + +#define SAM_USBHOST_CTRLB (SAM_USB_BASE+SAM_USBHOST_CTRLB_OFFSET) +#define SAM_USBHOST_HSOFC (SAM_USB_BASE+SAM_USBHOST_HSOFC_OFFSET) +#define SAM_USBHOST_STATUS (SAM_USB_BASE+SAM_USBHOST_STATUS_OFFSET) +#define SAM_USBHOST_FNUM (SAM_USB_BASE+SAM_USBHOST_FNUM_OFFSET) +#define SAM_USBHOST_FLENHIGH (SAM_USB_BASE+SAM_USBHOST_FLENHIGH_OFFSET) +#define SAM_USBHOST_INTENCLR (SAM_USB_BASE+SAM_USBHOST_INTENCLR_OFFSET) +#define SAM_USBHOST_INTENSET (SAM_USB_BASE+SAM_USBHOST_INTENSET_OFFSET) +#define SAM_USBHOST_INTFLAG (SAM_USB_BASE+SAM_USBHOST_INTFLAG_OFFSET) +#define SAM_USBHOST_PINTSMRY (SAM_USB_BASE+SAM_USBHOST_PINTSMRY_OFFSET) + +/* Pipe Register n Base Address */ + +#define SAM_USBHOST_PIPE_BASE(n) (SAM_USB_BASE+SAM_USBHOST_PIPE_OFFSET(n)) + +/* Pipe n Register Addresses */ + +#define SAM_USBHOST_PCFG(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PCFG_OFFSET) +#define SAM_USBHOST_BINTERVAL(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_BINTERVAL_OFFSET) +#define SAM_USBHOST_PSTATUSCLR(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PSTATUSCLR_OFFSET) +#define SAM_USBHOST_PSTATUSET(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PSTATUSET_OFFSET) +#define SAM_USBHOST_PSTATUS(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PSTATUS_OFFSET) +#define SAM_USBHOST_PINTFLAG(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PINTFLAG_OFFSET) +#define SAM_USBHOST_PINTENCLR(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PINTENCLR_OFFSET) +#define SAM_USBHOST_PINTENSET(n) (SAM_USBHOST_PIPE_BASE(n)+SAM_USBHOST_PINTENSET_OFFSET) + +/* USB register bit definitions ************************************************************/ + +/* Common USB Device/Host Register Offsets */ + +/* Control A Register */ + +#define USB_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define USB_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define USB_CTRLA_RUNSTBY (1 << 2) /* Bit 2: Run in standby */ +#define USB_CTRLA_MODE (1 << 7) /* Bit 7: Operating mode */ +# define USB_CTRLA_MODE_DEVICE (0) /* 0 = USB device mode */ +# define USB_CTRLA_MODE_HOST (1 << 7) /* 1 = USB host mode */ + +/* Synchronization Busy Register */ + +#define USB_SYNCBUSY_SWRST (1 << 0) /* Bit 0: Software reset status */ +#define USB_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: Enable status */ + +/* QOS Control Register */ + +#define USB_QOSCTRL_CQOS_SHIFT (0) /* Bit 0-1: Data quality of service */ +#define USB_QOSCTRL_CQOS_MASK (3 << USB_QOSCTRL_CQOS_SHIFT) +# define USB_QOSCTRL_CQOS(n) ((uint8_t)(n) << USB_QOSCTRL_CQOS_SHIFT) +#define USB_QOSCTRL_DQOS_SHIFT (2) /* Bit 2-3: Configuration qualilty of service */ +#define USB_QOSCTRL_DQOS_MASK (3 << USB_QOSCTRL_DQOS_SHIFT) +# define USB_QOSCTRL_DQOS(n) ((uint8_t)(n) << USB_QOSCTRL_DQOS_SHIFT) + +/* Finite State Machine Register */ + +#define USB_FSMSTATUS_SHIFT (0) /* Bits 0-6: Finite state machine status */ +#define USB_FSMSTATUS_MASK (0x7f << USB_FSMSTATUS_SHIFT) +# define USB_FSMSTATUS_OFF (0x01 << USB_FSMSTATUS_SHIFT) /* Powered-off, disconnect, disabled state */ +# define USB_FSMSTATUS_ON (0x02 << USB_FSMSTATUS_SHIFT) /* Idle and Active states */ +# define USB_FSMSTATUS_SUSPEND (0x04 << USB_FSMSTATUS_SHIFT) +# define USB_FSMSTATUS_SLEEP (0x08 << USB_FSMSTATUS_SHIFT) +# define USB_FSMSTATUS_DNRESUME (0x10 << USB_FSMSTATUS_SHIFT) /* Down stream resume */ +# define USB_FSMSTATUS_UPRESUME (0x20 << USB_FSMSTATUS_SHIFT) /* Up stream resume */ +# define USB_FSMSTATUS_RESET (0x40 << USB_FSMSTATUS_SHIFT) /* USB lines reset */ + +/* Descriptor Address Register (32-bit address) */ + +/* Pad Calibration Register */ + +#define USB_PADCAL_TRANSP_SHIFT (0) /* Bit 0-4: Trimmable output driver impedance P */ +#define USB_PADCAL_TRANSP_MASK (31 << USB_PADCAL_TRANSP_SHIFT) +# define USB_PADCAL_TRANSP(n) ((uint16_t)(n) << USB_PADCAL_TRANSP_SHIFT) +#define USB_PADCAL_TRANSN_SHIFT (6) /* Bit 7-9: Trimmable output driver impedance N */ +#define USB_PADCAL_TRANSN_MASK (31 << USB_PADCAL_TRANSN_SHIFT) +# define USB_PADCAL_TRANSN(n) ((uint16_t)(n) << USB_PADCAL_TRANSN_SHIFT) +#define USB_PADCAL_TRIM_SHIFT (12) /* Bit 12-14: Trim bits for DP/DM */ +#define USB_PADCAL_TRIM_MASK (7 << USB_PADCAL_TRIM_SHIFT) +# define USB_PADCAL_TRIM(n) ((uint16_t)(n) << USB_PADCAL_TRIM_SHIFT) + +/* USB Device Register Offsets */ + +/* Control B Register */ + +#define USBDEV_CTRLB_DETACH (1 << 0) /* Bit 0: Detach */ +#define USBDEV_CTRLB_UPRSM (1 << 1) /* Bit 1: Upstream resume */ +#define USBDEV_CTRLB_SPDCONF_SHIFT (2) /* Bits 2-3: Speed configuration */ +#define USBDEV_CTRLB_SPDCONF_MASK (3 << USBDEV_CTRLB_SPDCONF_SHIFT) +# define USBDEV_CTRLB_SPDCONF_FULL (0 << USBDEV_CTRLB_SPDCONF_SHIFT) /* Full speed */ +# define USBDEV_CTRLB_SPDCONF_LOW (1 << USBDEV_CTRLB_SPDCONF_SHIFT) /* Low speed */ +# define USBDEV_CTRLB_SPDCONF_HIGH (2 << USBDEV_CTRLB_SPDCONF_SHIFT) /* High speed capable */ +# define USBDEV_CTRLB_SPDCONF_HIGH_TM (3 << USBDEV_CTRLB_SPDCONF_SHIFT) /* High speed Test Mode */ +#define USBDEV_CTRLB_NREPLY (1 << 4) /* Bit 4: No reply except SETUP token */ +#define USBDEV_CTRLB_GNAK (1 << 9) /* Bit 9: Global NAK */ +#define USBDEV_CTRLB_LPMHDSK_SHIFT (10) /* Bits 10-11: Link power management handshake */ +#define USBDEV_CTRLB_LPMHDSK_MASK (3 << USBDEV_CTRLB_LPMHDSK_SHIFT) +# define USBDEV_CTRLB_LPMHDSK_NONE (0 << USBDEV_CTRLB_LPMHDSK_SHIFT) /* No handshake, LPM not supported */ +# define USBDEV_CTRLB_LPMHDSK_ACK (1 << USBDEV_CTRLB_LPMHDSK_SHIFT) +# define USBDEV_CTRLB_LPMHDSK_NYET (2 << USBDEV_CTRLB_LPMHDSK_SHIFT) + +/* Device Address Register */ + +#define USBDEV_DADD_SHIFT (0) /* Bits 0-6: Device address */ +#define USBDEV_DADD_MASK (0x7f << USBDEV_DADD_SHIFT) +# define USBDEV_DADD(n) ((uint8_t)(n) << USBDEV_DADD_SHIFT) +#define USBDEV_DADD_ADDEN (1 << 7) /* Bit 7: Device address enable */ + +/* Status Register */ + +#define USBDEV_STATUS_SPEED_SHIFT (0) /* Bits 0-1: Speed status */ +#define USBDEV_STATUS_SPEED_MASK (3 << USBDEV_STATUS_SPEED_SHIFT) +# define USBDEV_STATUS_SPEED_LOW (0 << USBDEV_STATUS_SPEED_SHIFT) /* Low speed */ +# define USBDEV_STATUS_SPEED_FULL (1 << USBDEV_STATUS_SPEED_SHIFT) /* Full speed */ +#define USBDEV_STATUS_LNSTATE_SHIFT (6) /* Bits 6-7: USB line status */ +#define USBDEV_STATUS_LNSTATE_MASK (3 << USBDEV_STATUS_LNSTATE_SHIFT) +# define USBDEV_STATUS_LNSTATE_SE0 (0 << USBDEV_STATUS_LNSTATE_SHIFT) /* SE0/RESET */ +# define USBDEV_STATUS_LNSTATE_LJFK (1 << USBDEV_STATUS_LNSTATE_SHIFT) /* LS-J or FS-K */ +# define USBDEV_STATUS_LNSTATE_LKFJ (2 << USBDEV_STATUS_LNSTATE_SHIFT) /* LS-K or FS-L */ + +/* Device Frame Number Register */ + +#define USBDEV_MFNUM_SHIFT (0) /* Bits 0-2: Micro-frame number */ +#define USBDEV_MFNUM_MASK (7 << USBDEV_MFNUM_SHIFT) +#define USBDEV_FNUM_SHIFT (3) /* Bits 3-13: Frame number */ +#define USBDEV_FNUM_MASK (0x7ff << USBDEV_FNUM_SHIFT) +#define USBDEV_FNUM_FNCERR (1 << 15) /* Bit 15: Frame number CRC error */ + +/* Common definitions for Device Interrupt Enable Clear Register, Device interrupt + * Enable Set Register, and SAM_USBDEV_INTFLAG_OFFSET + */ + +#define USBDEV_INT_SUSPEND (1 << 0) /* Bit 0: Suspend interrupt */ +#define USBDEV_INT_SOF (1 << 2) /* Bit 2: Start of frame interrupt */ +#define USBDEV_INT_EORST (1 << 3) /* Bit 3: End of reset interrupt */ +#define USBDEV_INT_WAKEUP (1 << 4) /* Bit 4: Wake-up interrupt */ +#define USBDEV_INT_EORSM (1 << 5) /* Bit 5: End of resume interrupt */ +#define USBDEV_INT_UPRSM (1 << 6) /* Bit 6: Upstream resume interrupt */ +#define USBDEV_INT_RAMACER (1 << 7) /* Bit 7: RAM access interrupt */ +#define USBDEV_INT_LPMNYET (1 << 8) /* Bit 8: Link power NotYet interrupt */ +#define USBDEV_INT_LPMSUSP (1 << 9) /* Bit 9: Link power suspend interrupt */ + +/* Endpoint Interrupt Summary Register */ + +#define USBDEV_EPINTSMRY_EPINT(n) (1 << (n)) + +/* Device Endpoint Configuration Register */ + +#define USBDEV_EPCFG_EPTYPE0_SHIFT (0) /* Bits 0-2: Endpoint type for OUT direction */ +#define USBDEV_EPCFG_EPTYPE0_MASK (7 << USBDEV_EPCFG_EPTYPE0_SHIFT) +# define USBDEV_EPCCFG_EPTYPE0_DISABLED (0 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 disabled */ +# define USBDEV_EPCCFG_EPTYPE0_CTRLOUT (1 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 control SETUP/OUT */ +# define USBDEV_EPCCFG_EPTYPE0_ISOCOUT (2 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 isochronous OUT */ +# define USBDEV_EPCCFG_EPTYPE0_BULKOUT (3 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 bulk OUT */ +# define USBDEV_EPCCFG_EPTYPE0_INTOUT (4 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 interrupt OUT */ +# define USBDEV_EPCCFG_EPTYPE0_DBIN (5 << USBDEV_EPCFG_EPTYPE0_SHIFT) /* Bank 0 dual bank IN */ +#define USBDEV_EPCFG_EPTYPE1_SHIFT (4) /* Bits 4-6: Endpoint type for IN direction */ +#define USBDEV_EPCFG_EPTYPE1_MASK (7 << USBDEV_EPCFG_EPTYPE1_SHIFT) +# define USBDEV_EPCCFG_EPTYPE1_DISABLED (0 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 disabled */ +# define USBDEV_EPCCFG_EPTYPE1_CTRLIN (1 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 control IN */ +# define USBDEV_EPCCFG_EPTYPE1_ISOCIN (2 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 isochronous IN */ +# define USBDEV_EPCCFG_EPTYPE1_BULKIN (3 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 bulk IN */ +# define USBDEV_EPCCFG_EPTYPE1_INTIN (4 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 interrupt IN */ +# define USBDEV_EPCCFG_EPTYPE1_DBOUT (5 << USBDEV_EPCFG_EPTYPE1_SHIFT) /* Bank 1 dual bank OUT */ + +/* Common definitions for Endpoint Status Clear Register, Endpoint Status Set + * Register, and Endpoint Status Set Register + */ + +#define USBDEV_EPSTATUS_DTGLOUT (1 << 0) /* Bit 0: Data toggle OUT */ +#define USBDEV_EPSTATUS_DTGLIN (1 << 1) /* Bit 1: Data toggle IN */ +#define USBDEV_EPSTATUS_CURBK (1 << 2) /* Bit 2: Current bank */ +#define USBDEV_EPSTATUS_STALLRQ0 (1 << 4) /* Bit 4: Stall bank 0 request */ +#define USBDEV_EPSTATUS_STALLRQ1 (1 << 5) /* Bit 5: Stall bank 1 request */ +#define USBDEV_EPSTATUS_BK0RDY (1 << 6) /* Bit 6: Bank 0 ready */ +#define USBDEV_EPSTATUS_BK1RDY (1 << 7) /* Bit 7: Bank 1 ready */ + +/* Common definitions for Device Endpoint Interrupt Flag Register, Device Endpoint + * Interrupt Enable Register, and Device Endpoint Interrupt Set Register + */ + +#define USBDEV_EPINT_TRCPT0 (1 << 0) /* Bit 0: Transmit complete 0 interrupt */ +#define USBDEV_EPINT_TRCPT1 (1 << 1) /* Bit 1: Transmit complete 1 interrupt */ +#define USBDEV_EPINT_TRFAIL0 (1 << 2) /* Bit 2: Transmit fail 0 interrupt */ +#define USBDEV_EPINT_TRFAIL1 (1 << 3) /* Bit 3: Transmit fail 1 interrupt */ +#define USBDEV_EPINT_RXSTP (1 << 4) /* Bit 4: Received SETUP interrupt */ +#define USBDEV_EPINT_STALL0 (1 << 5) /* Bit 5: Transmit stall 0 interrupt */ +#define USBDEV_EPINT_STALL1 (1 << 6) /* Bit 5: Transmit stall 1 interrupt */ + +/* Device Endpoint Descriptor */ + +/* Address of Data buffer (Both banks, 32-bit address) */ + +/* Packet Size (Both banks) */ + +#define USBDEV_PKTSIZE_BCNT_SHIFT (0) /* Bits 0-13: Byte count */ +#define USBDEV_PKTSIZE_BCNT_MASK (0x3fff << USBDEV_PKTSIZE_BCNT_SHIFT) +# define USBDEV_PKTSIZE_BCNT(n) ((uint32_t)(n) << USBDEV_PKTSIZE_BCNT_SHIFT) +#define USBDEV_PKTSIZE_MPKTSIZE_SHIFT (14) /* Bits 14-27: Multi-packet size */ +#define USBDEV_PKTSIZE_MPKTSIZE_MASK (0x3fff << USBDEV_PKTSIZE_MPKTSIZE_SHIFT) +# define USBDEV_PKTSIZE_MPKTSIZE(n) ((uint32_t)(n) << USBDEV_PKTSIZE_MPKTSIZE_SHIFT) +#define USBDEV_PKTSIZE_SIZE_SHIFT (28) /* Bits 28-30: Endpoint size */ +#define USBDEV_PKTSIZE_SIZE_MASK (7 << USBDEV_PKTSIZE_SIZE_SHIFT) +# define USBDEV_PKTSIZE_SIZE_8B (0 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 8 bytes */ +# define USBDEV_PKTSIZE_SIZE_16B (1 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 16 bytes */ +# define USBDEV_PKTSIZE_SIZE_32B (2 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 32 bytes */ +# define USBDEV_PKTSIZE_SIZE_64B (3 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 64 bytes */ +# define USBDEV_PKTSIZE_SIZE_128B (4 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 128 bytes (isoc only) */ +# define USBDEV_PKTSIZE_SIZE_256B (5 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 256 bytes (isoc only) */ +# define USBDEV_PKTSIZE_SIZE_512B (6 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 512 bytes (isoc only) */ +# define USBDEV_PKTSIZE_SIZE_1023B (7 << USBDEV_PKTSIZE_SIZE_SHIFT) /* 1023 bytes (isoc only) */ +#define USBDEV_PKTSIZE_AUTOZLP (1 << 31) /* Bit 31: Automatic zero length packet */ + +/* Extended Register (Bank 0 only) */ + +#define USBDEV_EXTREG_SUBPID_SHIFT (0) /* Bits 0-3: Sub PID */ +#define USBDEV_EXTREG_SUBPID_MASK (15 << USBDEV_EXTREG_SUBPID_SHIFT) +# define USBDEV_EXTREG_SUBPID(n) ((uint16_t)(n) << USBDEV_EXTREG_SUBPID_SHIFT) +#define USBDEV_EXTREG_VARIABLE_SHIFT (4) /* Bits 4-14: Variable */ +#define USBDEV_EXTREG_VARIABLE_MASK (0x7ff << USBDEV_EXTREG_VARIABLE_SHIFT) +# define USBDEV_EXTREG_VARIABLE(n) ((uint16_t)(n) << USBDEV_EXTREG_VARIABLE_SHIFT) + +/* Device Status Bank (Both banks) */ + +#define USBDEV_STATUSBK_CRCERR (1 << 0) /* Bit 0: CRC error */ +#define USBDEV_STATUSBK_ERRORFLOW (1 << 1) /* Bit 1: Error flow status */ + +/* USB Host Register Offsets */ + +/* Control B Register */ + +#define USBHOST_CTRLB_RESUME (1 << 1) /* Bit 1: Send USB resume */ +#define USBHOST_CTRLB_SPDCONF_SHIFT (2) /* Bits 2-3: Host speed configuration */ +#define USBHOST_CTRLB_SPDCONF_MASK (3 << USBHOST_CTRLB_SPDCONF_SHIFT) +# define USBHOST_CTRLB_SPDCONF_LF (0 << USBHOST_CTRLB_SPDCONF_SHIFT) /* Low and full capable */ +#define USBHOST_CTRLB_TSTJ (1 << 5) /* Bit 5: TSTJ */ +#define USBHOST_CTRLB_TSTK (1 << 6) /* Bit 6: TSTK */ +#define USBHOST_CTRLB_SOFE (1 << 8) /* Bit 8: Start of frame generation enable */ +#define USBHOST_CTRLB_BUSRESET (1 << 9) /* Bit 9: Send USB reset */ +#define USBHOST_CTRLB_VBUSOK (1 << 10) /* Bit 10: VBUS is OK */ +#define USBHOST_CTRLB_L1RESUME (1 << 11) /* Bit 11: Send USB L1 resume */ + +/* Host Start-of-Frame Control Register */ + +#define USBHOST_HSOFC_FLENC_SHIFT (0) /* Bits 0-3: Frame length control */ +#define USBHOST_HSOFC_FLENC_MASK (15 << USBHOST_HSOFC_FLENC_SHIFT) +# define USBHOST_HSOFC_FLENC(n) ((uint8_t)(n) << USBHOST_HSOFC_FLENC_SHIFT) +#define USBHOST_HSOFC_FLENCE (1 << 7) /* Bit 7: Frame length control enable */ + +/* Status Register */ + +#define USBHOST_STATUS_SPEED_SHIFT (0) /* Bits 0-1: Speed status */ +#define USBHOST_STATUS_SPEED_MASK (3 << USBHOST_STATUS_SPEED_SHIFT) +# define USBHOST_STATUS_SPEED_LOW (0 << USBHOST_STATUS_SPEED_SHIFT) /* Full speed mode */ +# define USBHOST_STATUS_SPEED_FULL (2 << USBHOST_STATUS_SPEED_SHIFT) /* Low speed mode */ +#define USBHOST_STATUS_LNSTATE_SHIFT (6) /* Bits 6-7: USB line status */ +#define USBHOST_STATUS_LNSTATE_MASK (3 << USBHOST_STATUS_LNSTATE_SHIFT) +# define USBHOST_STATUS_LNSTATE_SE0 (0 << USBHOST_STATUS_LNSTATE_SHIFT) /* SE0/RESET */ +# define USBHOST_STATUS_LNSTATE_FJLK (1 << USBHOST_STATUS_LNSTATE_SHIFT) /* FS-J or LS-K */ +# define USBHOST_STATUS_LNSTATE_FKLJ (2 << USBHOST_STATUS_LNSTATE_SHIFT) /* FS-K or :S-L */ + +/* Host Frame Number Register */ + +#define USBHOST_FNUM_SHIFT (3) /* Bits 3-13: Frame number */ +#define USBHOST_FNUM_MASK (0x07ff << USBHOST_FNUM_SHIFT) + +/* Host Frame Length Register (8-bit data) */ + +/* Common definitions for Host Interrupt Enable Clear Register, Host Interrupt Enable + * Set Register, and Host Interrupt Flag Status and Clear Register + */ + +#define USBHOST_INT_HSOF (1 << 2) /* Bit 2: Host start of frame interrupt */ +#define USBHOST_INT_RST (1 << 3) /* Bit 3: Bus reset interrupt */ +#define USBHOST_INT_WAKEUP (1 << 4) /* Bit 4: Wake up interrupt */ +#define USBHOST_INT_DNRSM (1 << 5) /* Bit 5: Downstream resume interrupt */ +#define USBHOST_INT_UPRSM (1 << 6) /* Bit 6: Upstream resume from device interrupt */ +#define USBHOST_INT_RAMACER (1 << 7) /* Bit 7: FAM access interrupt */ +#define USBHOST_INT_DCONN (1 << 8) /* Bit 8: Device connection interrupt */ +#define USBHOST_INT_DDISC (1 << 9) /* Bit 9: Device disconnection interrupt */ + +/* Pipe Interrupt Summary Register */ + +#define USBHOST_PINTSMRY_PIPEINT(n) (1 << (n)) + +/* Host Pipe Configuration Register */ + +#define USBHOST_PCFG_PTOKEN_SHIFT (0) /* Bits 0-1: Pipe token */ +#define USBHOST_PCFG_PTOKEN_MASK (3 << USBHOST_PCFG_PTOKEN_SHIFT) +# define USBHOST_PCFG_PTOKEN_SETUP (0 << USBHOST_PCFG_PTOKEN_SHIFT) +# define USBHOST_PCFG_PTOKEN_IN (1 << USBHOST_PCFG_PTOKEN_SHIFT) +# define USBHOST_PCFG_PTOKEN_OUT (2 << USBHOST_PCFG_PTOKEN_SHIFT) +#define USBHOST_PCFG_BK (1 << 2) /* Bit 2: Pipe bank */ + #define USBHOST_PCFG_BK_SINGLE (0) /* 0=Single bank endpoint */ + #define USBHOST_PCFG_BK_DUAL (1 << 2) /* 1=Dual bank endpoint */ +#define USBHOST_PCFG_PTYPE_SHIFT (3) /* Bits 3-5: Type of pipe */ +#define USBHOST_PCFG_PTYPE_MASK (7 << USBHOST_PCFG_PTYPE_SHIFT) +# define USBHOST_PCFG_PTYPE_DISABLED (0 << USBHOST_PCFG_PTYPE_SHIFT) /* Disabled */ +# define USBHOST_PCFG_PTYPE_CTRL (1 << USBHOST_PCFG_PTYPE_SHIFT) /* Control pipe */ +# define USBHOST_PCFG_PTYPE_ISOC (2 << USBHOST_PCFG_PTYPE_SHIFT) /* Isochronous pipe */ +# define USBHOST_PCFG_PTYPE_BULK (3 << USBHOST_PCFG_PTYPE_SHIFT) /* Bulk pipe */ +# define USBHOST_PCFG_PTYPE_INT (4 << USBHOST_PCFG_PTYPE_SHIFT) /* Interrupt pipe */ +# define USBHOST_PCFG_PTYPE_EXTENDED (5 << USBHOST_PCFG_PTYPE_SHIFT) /* Extended pipe */ + +/* Interval for Bulk-OUT/Ping Transaction Register (8-bit data) */ + +/* Common definitions for Pipe Status Clear Register, Pipe Status Set Register, and + * Pipe Status Register + */ + +#define USBHOST_PSTATUS_DTGL (1 << 0) /* Bit 0: Data toggle sequence */ +#define USBHOST_PSTATUS_CURBK (1 << 2) /* Bit 2: Current bank */ +#define USBHOST_PSTATUS_PFREEZE (1 << 4) /* Bit 4: Pipe freeze */ +#define USBHOST_PSTATUS_BK0RDY (1 << 6) /* Bit 6: Bank 0 ready */ +#define USBHOST_PSTATUS_BK1RDY (1 << 7) /* Bit 7: Bank 1 ready */ + +/* Common definitions for Host Pipe Interrupt Flag Register, Host Pipe Interrupt Clear + * Register, and Host Pipe Interrupt Set Register + */ + +#define USBHOST_PINTFLAG_TRCPT0 (1 << 0) /* Bit 0: Transfer complete 0 interrupt */ +#define USBHOST_PINTFLAG_TRCPT1 (1 << 1) /* Bit 1: Transfer complete 1 interrupt */ +#define USBHOST_PINTFLAG_TRFAIL (1 << 2) /* Bit 2: Transfer fail interrupt */ +#define USBHOST_PINTFLAG_PERR (1 << 3) /* Bit 3: Pipe error interrupt */ +#define USBHOST_PINTFLAG_TXSTP (1 << 4) /* Bit 4: Transmitted SETUP interrupt */ +#define USBHOST_PINTFLAG_STALL (1 << 5) /* Bit 5: STALL received interrupt */ + +/* Host Pipe Descriptor */ + +/* Data buffer address (Both banks, 32-bit address) */ + +/* Packet size (Both banks) */ + +#define USBHOST_PKTSIZE_BCNT_SHIFT (8) /* Bits 8-13: Byte count */ +#define USBHOST_PKTSIZE_BCNT_MASK (0x3f << USBHOST_PKTSIZE_BCNT_SHIFT) +# define USBHOST_PKTSIZE_BCNT(n) ((uint32_t)(n) << USBHOST_PKTSIZE_BCNT_SHIFT) +#define USBHOST_PKTSIZE_MPKTSIZE_SHIFT (14) /* Bits 14-27: Multi-packet IN/OUT size */ +#define USBHOST_PKTSIZE_MPKTSIZE_MASK (0x3fff << USBHOST_PKTSIZE_MPKTSIZE_SHIFT) +# define USBHOST_PKTSIZE_MPKTSIZE(n) ((uint32_t)(n) << USBHOST_PKTSIZE_MPKTSIZE_SHIFT) +#define USBHOST_PKTSIZE_SIZE_SHIFT (28) /* Bits 28-30: Pipe size */ +#define USBHOST_PKTSIZE_SIZE_MASK (7 << USBHOST_PKTSIZE_SIZE_SHIFT) +# define USBHOST_PKTSIZE_SIZE_8B (0 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 8 bytes */ +# define USBHOST_PKTSIZE_SIZE_16B (1 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 16 bytes */ +# define USBHOST_PKTSIZE_SIZE_32B (2 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 32 bytes */ +# define USBHOST_PKTSIZE_SIZE_64B (3 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 64 bytes */ +# define USBHOST_PKTSIZE_SIZE_128B (4 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 128 bytes (isoc only) */ +# define USBHOST_PKTSIZE_SIZE_256B (5 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 256 bytes (isoc only) */ +# define USBHOST_PKTSIZE_SIZE_512B (6 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 512 bytes (isoc only) */ +# define USBHOST_PKTSIZE_SIZE_1023B (7 << USBHOST_PKTSIZE_SIZE_SHIFT) /* 1023 bytes (isoc only) */ +#define USBHOST_PKTSIZE_AUTOZLP (1 << 31) /* Bit 31: Automatic zero length packet */ + +/* Extended register (Bank 0 only) */ + +#define USBHOST_EXTREG_SUBPID_SHIFT (0) /* Bits 0-3: SUBPID */ +#define USBHOST_EXTREG_SUBPID_MASK (15 << USBHOST_EXTREG_SUBPID_SHIFT) +# define USBHOST_EXTREG_SUBPID(n) ((uint16_t)(n) << USBHOST_EXTREG_SUBPID_SHIFT) +#define USBHOST_EXTREG_VARIABLE_SHIFT (4) /* Bits 4-14: VARIABLE */ +#define USBHOST_EXTREG_VARIABLE_MASK (0x7ff << USBHOST_EXTREG_VARIABLE_SHIFT) +# define USBHOST_EXTREG_VARIABLE(n) ((uint16_t)(n) << USBHOST_EXTREG_VARIABLE_SHIFT) + +/* host status bank (Both banks) */ + +#define USBHOST_STATUSBK_CRCERR (1 << 0) /* Bit 0: CRC error */ +#define USBHOST_STATUSBK_ERRORFLOW (1 << 1) /* Bit 1: Error flow status */ + +/* Host control pipe (Bank 0 only) */ + +#define USBHOST_CTRLPIPE_PDADDR_SHIFT (0) /* Bits 0-6: Pipe device address */ +#define USBHOST_CTRLPIPE_PDADDR_MASK (0x7f << USBHOST_CTRLPIPE_PDADDR_SHIFT) +# define USBHOST_CTRLPIPE_PDADDR(n) ((uint16_t)(n) << USBHOST_CTRLPIPE_PDADDR_SHIFT) +#define USBHOST_CTRLPIPE_PEPNUM_SHIFT (8) /* Bits 8-11: Pipe endpoint number */ +#define USBHOST_CTRLPIPE_PEPNUM_MASK (15 << USBHOST_CTRLPIPE_PEPNUM_SHIFTxx) +# define USBHOST_CTRLPIPE_PEPNUM(n) ((uint16_t)(n) << USBHOST_CTRLPIPE_PEPNUM_SHIFTxx) +#define USBHOST_CTRLPIPE_PEPMAX_SHIFT (12) /* Bitx 12-15: Pipe error max number */ +#define USBHOST_CTRLPIPE_PEPMAX_MASK (15 << USBHOST_CTRLPIPE_PEPMAX_SHIFT) +# define USBHOST_CTRLPIPE_PEPMAX(n) ((uint16_t)(n) << USBHOST_CTRLPIPE_PEPMAX_SHIFT) + +/* Host status pipe (Both banks) */ + +#define USBHOST_STATUSPIPE_DTGLER (1 << 0) /* Bit 0: Data toggle error */ +#define USBHOST_STATUSPIPE_DAPIDER (1 << 1) /* Bit 1: Data PID error */ +#define USBHOST_STATUSPIPE_PIDER (1 << 2) /* Bit 2: PID error */ +#define USBHOST_STATUSPIPE_TOUTER (1 << 3) /* Bit 3: Timeout error */ +#define USBHOST_STATUSPIPE_CRC16ER (1 << 4) /* Bit 4: CRC16 error */ +#define USBHOST_STATUSPIPE_ERCNT_SHIFT (5) /* Bits 5-7: Pipe error counter */ +#define USBHOST_STATUSPIPE_ERCNT_MASK (7 << USBHOST_STATUSPIPE_ERCNT_SHIFT) +# define USBHOST_STATUSPIPE_ERCNT(n) ((uint16_t)(n) << USBHOST_STATUSPIPE_ERCNT_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/* Device Endpoint Descriptor. See USBDEV_* bit definitions above. */ + +struct usbdev_epdesc_s +{ + uint32_t addr; /* 0x0000-0x0003: Address of Data buffer (Both banks) */ + uint32_t pktsize; /* 0x0004-0x0007: Packet Size (Both banks) */ + uint16_t extreg; /* 0x0008-0x0009: Extended Register (Bank 0 only) */ + uint8_t stausbk; /* 0x000a-0x000a: Device Status Bank (Both banks) */ + uint8_t reserved[5]; /* 0x000b-0x000f: Both banks */ +}; + +/* Host Pipe Descriptor. See USBHOST_* bit definitions above */ + +struct usbhost_pipedesc_s +{ + uint32_t addr; /* 0x0000-0x0003: Address of Data buffer (Both banks) */ + uint32_t pktsize; /* 0x0004-0x0007: Packet Size (Both banks) */ + uint16_t extreg; /* 0x0008-0x0009: Extended Register (Bank 0 only) */ + uint8_t stausbk; /* 0x000a-0x000a: Device Status Bank (Both banks) */ + uint8_t reserved; /* 0x000b-0x000b: Both banks */ + uint16_t ctrlpipe; /* 0x000c-0x000d: Host control pipe (Bank 0 only) */ + uint16_t statuspipe; /* 0x000e-0x000f: Host status pipe (Both banks) */ +}; + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USB_H */ diff --git a/arch/arm/src/samdl/chip/saml_wdt.h b/arch/arm/src/samdl/chip/saml_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..1e236504f6c04a1b414104e78070ce6da0633720 --- /dev/null +++ b/arch/arm/src/samdl/chip/saml_wdt.h @@ -0,0 +1,165 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/saml_wdt.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_WDT_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_WDT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* WDT register offsets *********************************************************************/ + +#define SAM_WDT_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_WDT_CONFIG_OFFSET 0x0001 /* Configuration register */ +#define SAM_WDT_EWCTRL_OFFSET 0x0002 /* Early warning interrupt control register */ +#define SAM_WDT_INTENCLR_OFFSET 0x0004 /* Interrupt enable clear register */ +#define SAM_WDT_INTENSET_OFFSET 0x0005 /* Interrupt enable set register */ +#define SAM_WDT_INTFLAG_OFFSET 0x0006 /* Interrupt flag and status clear register */ +#define SAM_WDT_SYNCBUSY_OFFSET 0x0008 /* Synchronization busy register */ +#define SAM_WDT_CLEAR_OFFSET 0x000c /* Clear register */ + +/* WDT register addresses *******************************************************************/ + +#define SAM_WDT_CTRLA (SAM_WDT_BASE+SAM_WDT_CTRLA_OFFSET) +#define SAM_WDT_CONFIG (SAM_WDT_BASE+SAM_WDT_CONFIG_OFFSET) +#define SAM_WDT_EWCTRL (SAM_WDT_BASE+SAM_WDT_EWCTRL_OFFSET) +#define SAM_WDT_INTENCLR (SAM_WDT_BASE+SAM_WDT_INTENCLR_OFFSET) +#define SAM_WDT_INTENSET (SAM_WDT_BASE+SAM_WDT_INTENSET_OFFSET) +#define SAM_WDT_INTFLAG (SAM_WDT_BASE+SAM_WDT_INTFLAG_OFFSET) +#define SAM_WDT_SYNCBUSY (SAM_WDT_BASE+SAM_WDT_SYNCBUSY_OFFSET) +#define SAM_WDT_CLEAR (SAM_WDT_BASE+SAM_WDT_CLEAR_OFFSET) + +/* WDT register bit definitions *************************************************************/ + +/* Control register */ + +#define WDT_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ +#define WDT_CTRLA_WEN (1 << 2) /* Bit 2: Watchdog Timer Window Mode Enable */ +#define WDT_CTRLA_ALWAYSON (1 << 7) /* Bit 7: Always-On */ + +/* Configuration register */ + +#define WDT_CONFIG_PER_SHIFT (0) /* Bits 0–3: Time-Out Period */ +#define WDT_CONFIG_PER_MASK (15 << WDT_CONFIG_PER_SHIFT) +# define WDT_CONFIG_PER_8 (0 << WDT_CONFIG_PER_SHIFT) /* 8 clock cycles */ +# define WDT_CONFIG_PER_16 (1 << WDT_CONFIG_PER_SHIFT) /* 16 clock cycles */ +# define WDT_CONFIG_PER_32 (2 << WDT_CONFIG_PER_SHIFT) /* 32 clock cycles */ +# define WDT_CONFIG_PER_64 (3 << WDT_CONFIG_PER_SHIFT) /* 64 clock cycles */ +# define WDT_CONFIG_PER_128 (4 << WDT_CONFIG_PER_SHIFT) /* 128 clock cycles */ +# define WDT_CONFIG_PER_256 (5 << WDT_CONFIG_PER_SHIFT) /* 256 clocks cycles */ +# define WDT_CONFIG_PER_512 (6 << WDT_CONFIG_PER_SHIFT) /* 512 clocks cycles */ +# define WDT_CONFIG_PER_1K (7 << WDT_CONFIG_PER_SHIFT) /* 1024 clock cycles */ +# define WDT_CONFIG_PER_2K (8 << WDT_CONFIG_PER_SHIFT) /* 2048 clock cycles */ +# define WDT_CONFIG_PER_4K (9 << WDT_CONFIG_PER_SHIFT) /* 4096 clock cycles */ +# define WDT_CONFIG_PER_8k (10 << WDT_CONFIG_PER_SHIFT) /* 8192 clock cycles */ +# define WDT_CONFIG_PER_16K (11 << WDT_CONFIG_PER_SHIFT) /* 16384 clock cycles */ +#define WDT_CONFIG_WINDOW_SHIFT (4) /* Bits 4-7: Window Mode Time-Out Period */ +#define WDT_CONFIG_WINDOW_MASK (15 << WDT_CONFIG_WINDOW_SHIFT) +# define WDT_CONFIG_WINDOW_8 (0 << WDT_CONFIG_WINDOW_SHIFT) /* 8 clock cycles */ +# define WDT_CONFIG_WINDOW_16 (1 << WDT_CONFIG_WINDOW_SHIFT) /* 16 clock cycles */ +# define WDT_CONFIG_WINDOW_32 (2 << WDT_CONFIG_WINDOW_SHIFT) /* 32 clock cycles */ +# define WDT_CONFIG_WINDOW_64 (3 << WDT_CONFIG_WINDOW_SHIFT) /* 64 clock cycles */ +# define WDT_CONFIG_WINDOW_128 (4 << WDT_CONFIG_WINDOW_SHIFT) /* 128 clock cycles */ +# define WDT_CONFIG_WINDOW_256 (5 << WDT_CONFIG_WINDOW_SHIFT) /* 256 clocks cycles */ +# define WDT_CONFIG_WINDOW_512 (6 << WDT_CONFIG_WINDOW_SHIFT) /* 512 clocks cycles */ +# define WDT_CONFIG_WINDOW_1K (7 << WDT_CONFIG_WINDOW_SHIFT) /* 1024 clock cycles */ +# define WDT_CONFIG_WINDOW_2K (8 << WDT_CONFIG_WINDOW_SHIFT) /* 2048 clock cycles */ +# define WDT_CONFIG_WINDOW_4K (9 << WDT_CONFIG_WINDOW_SHIFT) /* 4096 clock cycles */ +# define WDT_CONFIG_WINDOW_8k (10 << WDT_CONFIG_WINDOW_SHIFT) /* 8192 clock cycles */ +# define WDT_CONFIG_WINDOW_16K (11 << WDT_CONFIG_WINDOW_SHIFT) /* 16384 clock cycles */ + +/* Early warning interrupt control register */ + +#define WDT_EWCTRL_EWOFFSET_SHIFT (0) /* Bits 0-3: Early warning interrupt time offset */ +#define WDT_EWCTRL_EWOFFSET_MASK (15 << WDT_EWCTRL_EWOFFSET_SHIFT) +# define WDT_EWCTRL_EWOFFSET_8 (0 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 8 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_16 (1 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 16 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_32 (2 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 32 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_64 (3 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 64 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_128 (4 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 128 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_256 (5 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 256 clocks cycles */ +# define WDT_EWCTRL_EWOFFSET_512 (6 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 512 clocks cycles */ +# define WDT_EWCTRL_EWOFFSET_1K (7 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 1024 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_2K (8 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 2048 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_4K (9 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 4096 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_8k (10 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 8192 clock cycles */ +# define WDT_EWCTRL_EWOFFSET_16K (11 << WDT_EWCTRL_EWOFFSET_SHIFT) /* 16384 clock cycles */ + +/* Interrupt enable clear, interrupt enable set register, interrupt flag status and clear registers */ + +#define WDT_INT_EW (1 << 0) /* Bit 0: Early warning interrupt */ +#define WDT_INT_All (0x01) + +/* Synchronization busy register */ + +#define WDT_SYNCBUSY_ENABLE (1 << 1) /* Bit 1: Enable syncrhonization busy */ +#define WDT_SYNCBUSY_WEN (1 << 2) /* Bit 2: Window enable synchronization busy */ +#define WDT_SYNCBUSY_ALWAYSON (1 << 3) /* Bit 3: Always-on synchronization busy */ +#define WDT_SYNCBUSY_CLEAR (1 << 4) /* Bit 4: Clear syncrhonization busy */ + +/* Clear register */ + +#define WDT_CLEAR_CLEAR_SHIFT (0) /* Bits 0-7: Watchdog clear */ +#define WDT_CLEAR_CLEAR_MASK (0xff << WDT_CLEAR_CLEAR_SHIFT) +# define WDT_CLEAR_CLEAR (0xa5 << WDT_CLEAR_CLEAR_SHIFT) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAML_WDT_H */ diff --git a/arch/arm/src/samdl/sam_clockconfig.h b/arch/arm/src/samdl/sam_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..00194320ef7dc98b873c3caa89861671724df71f --- /dev/null +++ b/arch/arm/src/samdl/sam_clockconfig.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_clockconfig.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_SAMDL_SAM_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_CLOCKCONFIG_H */ diff --git a/arch/arm/src/samdl/sam_config.h b/arch/arm/src/samdl/sam_config.h new file mode 100644 index 0000000000000000000000000000000000000000..846e3291d3164d697317096ed9fd8cdfd2d0e65b --- /dev/null +++ b/arch/arm/src/samdl/sam_config.h @@ -0,0 +1,291 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_config.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_CONFIG_H +#define __ARCH_ARM_SRC_SAMDL_SAM_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* How many SERCOM peripherals are configured as USART peripherals? */ + +#define SAMDL_HAVE_USART0 1 +#define SAMDL_HAVE_USART1 1 +#define SAMDL_HAVE_USART2 1 +#define SAMDL_HAVE_USART3 1 +#define SAMDL_HAVE_USART4 1 +#define SAMDL_HAVE_USART5 1 + +#if !defined(CONFIG_SAMDL_SERCOM0) || !defined(CONFIG_SAMDL_SERCOM0_ISUSART) || \ + !defined(CONFIG_USART0_ISUART) +# undef SAMDL_HAVE_USART0 +# undef CONFIG_SAMDL_SERCOM0_ISUSART +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART0_FLOWCONTROL +# undef CONFIG_USART0_IRDAMODE +# undef CONFIG_USART0_RS485MODE +#endif + +#if !defined(CONFIG_SAMDL_SERCOM1) || !defined(CONFIG_SAMDL_SERCOM1_ISUSART) || \ + !defined(CONFIG_USART1_ISUART) +# undef SAMDL_HAVE_USART1 +# undef CONFIG_SAMDL_SERCOM1_ISUSART +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART1_FLOWCONTROL +# undef CONFIG_USART1_IRDAMODE +# undef CONFIG_USART1_RS485MODE +#endif + +#if !defined(CONFIG_SAMDL_SERCOM2) || !defined(CONFIG_SAMDL_SERCOM2_ISUSART) || \ + !defined(CONFIG_USART2_ISUART) +# undef SAMDL_HAVE_USART2 +# undef CONFIG_SAMDL_SERCOM2_ISUSART +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART2_FLOWCONTROL +# undef CONFIG_USART2_IRDAMODE +# undef CONFIG_USART2_RS485MODE +#endif + +#if !defined(CONFIG_SAMDL_SERCOM3) || !defined(CONFIG_SAMDL_SERCOM3_ISUSART) || \ + !defined(CONFIG_USART3_ISUART) +# undef SAMDL_HAVE_USART3 +# undef CONFIG_SAMDL_SERCOM3_ISUSART +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART3_FLOWCONTROL +# undef CONFIG_USART3_IRDAMODE +# undef CONFIG_USART3_RS485MODE +#endif + +#if !defined(CONFIG_SAMDL_SERCOM4) || !defined(CONFIG_SAMDL_SERCOM4_ISUSART) || \ + !defined(CONFIG_USART4_ISUART) +# undef SAMDL_HAVE_USART4 +# undef CONFIG_SAMDL_SERCOM4_ISUSART +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART4_FLOWCONTROL +# undef CONFIG_USART4_IRDAMODE +# undef CONFIG_USART4_RS485MODE +#endif + +#if !defined(CONFIG_SAMDL_SERCOM5) || !defined(CONFIG_SAMDL_SERCOM5_ISUSART) || \ + !defined(CONFIG_USART5_ISUART) +# undef SAMDL_HAVE_USART5 +# undef CONFIG_SAMDL_SERCOM5_ISUSART +# undef CONFIG_USART5_SERIAL_CONSOLE +# undef CONFIG_USART5_FLOWCONTROL +# undef CONFIG_USART5_IRDAMODE +# undef CONFIG_USART5_RS485MODE +#endif + +/* Are any USARTs enabled? */ + +#undef SAMDL_HAVE_USART +#if defined(SAMDL_HAVE_USART0) || defined(SAMDL_HAVE_USART1) || \ + defined(SAMDL_HAVE_USART2) || defined(SAMDL_HAVE_USART3) || \ + defined(SAMDL_HAVE_USART4) || defined(SAMDL_HAVE_USART5) +# define SAMDL_HAVE_USART 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any USARTn, n=0-5 - OR - there might not be any serial console at all. + */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART5_SERIAL_CONSOLE) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_USART4_SERIAL_CONSOLE +# undef CONFIG_USART5_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Are any SERCOM peripherals are configured as SPI peripherals? */ + +#define SAMDL_HAVE_SPI0 1 +#define SAMDL_HAVE_SPI1 1 +#define SAMDL_HAVE_SPI2 1 +#define SAMDL_HAVE_SPI3 1 +#define SAMDL_HAVE_SPI4 1 +#define SAMDL_HAVE_SPI5 1 + +#if !defined(CONFIG_SAMDL_SERCOM0) || !defined(CONFIG_SAMDL_SERCOM0_ISSPI) +# undef SAMDL_HAVE_SPI0 +# undef CONFIG_SAMDL_SERCOM0_ISSPI +#endif + +#if !defined(CONFIG_SAMDL_SERCOM1) || !defined(CONFIG_SAMDL_SERCOM1_ISSPI) +# undef SAMDL_HAVE_SPI1 +# undef CONFIG_SAMDL_SERCOM1_ISSPI +#endif + +#if !defined(CONFIG_SAMDL_SERCOM2) || !defined(CONFIG_SAMDL_SERCOM2_ISSPI) +# undef SAMDL_HAVE_SPI2 +# undef CONFIG_SAMDL_SERCOM2_ISSPI +#endif + +#if !defined(CONFIG_SAMDL_SERCOM3) || !defined(CONFIG_SAMDL_SERCOM3_ISSPI) +# undef SAMDL_HAVE_SPI3 +# undef CONFIG_SAMDL_SERCOM3_ISSPI +#endif + +#if !defined(CONFIG_SAMDL_SERCOM4) || !defined(CONFIG_SAMDL_SERCOM4_ISSPI) +# undef SAMDL_HAVE_SPI4 +# undef CONFIG_SAMDL_SERCOM4_ISSPI +#endif + +#if !defined(CONFIG_SAMDL_SERCOM5) || !defined(CONFIG_SAMDL_SERCOM5_ISSPI) +# undef SAMDL_HAVE_SPI5 +# undef CONFIG_SAMDL_SERCOM5_ISSPI +#endif + +/* Are any SERCOMs configured for SPI? */ + +#undef SAMDL_HAVE_SPI +#if defined(SAMDL_HAVE_SPI0) || defined(SAMDL_HAVE_SPI1) || \ + defined(SAMDL_HAVE_SPI2) || defined(SAMDL_HAVE_SPI3) || \ + defined(SAMDL_HAVE_SPI4) || defined(SAMDL_HAVE_SPI5) +# define SAMDL_HAVE_SPI 1 +#endif + +/* Are any SERCOM peripherals are configured as I2C peripherals? */ + +#define SAMDL_HAVE_I2C0 1 +#define SAMDL_HAVE_I2C1 1 +#define SAMDL_HAVE_I2C2 1 +#define SAMDL_HAVE_I2C3 1 +#define SAMDL_HAVE_I2C4 1 +#define SAMDL_HAVE_I2C5 1 + +#if !defined(CONFIG_SAMDL_SERCOM0) || !defined(CONFIG_SAMDL_SERCOM0_ISI2C) +# undef SAMDL_HAVE_I2C0 +# undef CONFIG_SAMDL_SERCOM0_ISI2C +#endif + +#if !defined(CONFIG_SAMDL_SERCOM1) || !defined(CONFIG_SAMDL_SERCOM1_ISI2C) +# undef SAMDL_HAVE_I2C1 +# undef CONFIG_SAMDL_SERCOM1_ISI2C +#endif + +#if !defined(CONFIG_SAMDL_SERCOM2) || !defined(CONFIG_SAMDL_SERCOM2_ISI2C) +# undef SAMDL_HAVE_I2C2 +# undef CONFIG_SAMDL_SERCOM2_ISI2C +#endif + +#if !defined(CONFIG_SAMDL_SERCOM3) || !defined(CONFIG_SAMDL_SERCOM3_ISI2C) +# undef SAMDL_HAVE_I2C3 +# undef CONFIG_SAMDL_SERCOM3_ISI2C +#endif + +#if !defined(CONFIG_SAMDL_SERCOM4) || !defined(CONFIG_SAMDL_SERCOM4_ISI2C) +# undef SAMDL_HAVE_I2C4 +# undef CONFIG_SAMDL_SERCOM4_ISI2C +#endif + +#if !defined(CONFIG_SAMDL_SERCOM5) || !defined(CONFIG_SAMDL_SERCOM5_ISI2C) +# undef SAMDL_HAVE_I2C5 +# undef CONFIG_SAMDL_SERCOM5_ISI2C +#endif + +/* Are any SERCOMs configured for I2C? */ + +#undef SAMDL_HAVE_I2C +#if defined(SAMDL_HAVE_I2C0) || defined(SAMDL_HAVE_I2C1) || \ + defined(SAMDL_HAVE_I2C2) || defined(SAMDL_HAVE_I2C3) || \ + defined(SAMDL_HAVE_I2C4) || defined(SAMDL_HAVE_I2C5) +# define SAMDL_HAVE_I2C 1 +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_CONFIG_H */ diff --git a/arch/arm/src/samdl/sam_dmac.c b/arch/arm/src/samdl/sam_dmac.c new file mode 100644 index 0000000000000000000000000000000000000000..0d1cb43041d021882dc6b83ef0e6482f18f60626 --- /dev/null +++ b/arch/arm/src/samdl/sam_dmac.c @@ -0,0 +1,1329 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_dmac.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" + +#include "sam_dmac.h" +#include "sam_periphclks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Condition out the whole file unless DMA is selected in the configuration */ + +#ifdef CONFIG_SAMDL_DMAC + +/* If SAMD/L support is enabled, then OS DMA support should also be enabled */ + +#ifndef CONFIG_ARCH_DMA +# warning "SAMDL DMA enabled but CONFIG_ARCH_DMA disabled" +#endif + +/* Number of additional DMA descriptors in LPRAM */ + +#ifndef CONFIG_SAMDL_DMAC_NDESC +# define CONFIG_SAMDL_DMAC_NDESC 0 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* The direction of the transfer */ + +enum sam_dmadir_e +{ + DMADIR_UNKOWN = 0, /* We don't know the direction of the + * transfer yet */ + DMADIR_TX, /* Transmit: Memory to peripheral */ + DMADIR_RX /* Receive: Peripheral to memory */ +}; + +/* This structure describes one DMA channel */ + +struct sam_dmach_s +{ + bool dc_inuse; /* TRUE: The DMA channel is in use */ + uint8_t dc_chan; /* DMA channel number (0-15) */ + uint8_t dc_dir; /* See enum sam_dmadir_e */ + uint32_t dc_flags; /* DMA channel flags */ + dma_callback_t dc_callback; /* Callback invoked when the DMA completes */ + void *dc_arg; /* Argument passed to callback function */ +#if CONFIG_SAMDL_DMAC_NDESC > 0 + struct dma_desc_s *dc_head; /* First allocated DMA descriptor */ + struct dma_desc_s *dc_tail; /* DMA descriptor list tail */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void sam_takechsem(void); +static inline void sam_givechsem(void); +#if CONFIG_SAMDL_DMAC_NDESC > 0 +static void sam_takedsem(void); +static inline void sam_givedsem(void); +#endif +static void sam_dmaterminate(struct sam_dmach_s *dmach, int result); +static int sam_dmainterrupt(int irq, void *context); +static struct dma_desc_s *sam_alloc_desc(struct sam_dmach_s *dmach); +static struct dma_desc_s *sam_append_desc(struct sam_dmach_s *dmach, + uint16_t btctrl, uint16_t btcnt, + uint32_t srcaddr, uint32_t dstaddr); +static void sam_free_desc(struct sam_dmach_s *dmach); +static size_t sam_maxtransfer(struct sam_dmach_s *dmach); +static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes); +static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes); +static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These semaphores protect the DMA channel and descriptor tables */ + +static sem_t g_chsem; +#if CONFIG_SAMDL_DMAC_NDESC > 0 +static sem_t g_dsem; +#endif + +/* This array describes the state of each DMA channel */ + +static struct sam_dmach_s g_dmach[SAMDL_NDMACHAN]; + +/* DMA descriptor tables positioned in LPRAM. In this use case, it is + * acceptable for the writeback descriptors to overlap the base + * descriptors since the base descriptors are always initialized prior + * to starting each DMA transaction. + */ + +static struct dma_desc_s g_base_desc[SAMDL_NDMACHAN] + __attribute__ ((section(".lpram"), aligned(16))); +#define g_writeback_desc g_base_desc + +#if CONFIG_SAMDL_DMAC_NDESC > 0 +/* Additional DMA descriptors for (optional) multi-block transfer support. + * Also positioned in LPRAM. + */ + +static struct dma_desc_s g_dma_desc[CONFIG_SAMDL_DMAC_NDESC] + __attribute__ ((section(".lpram"), aligned(16))); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_takechsem() and sam_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table + * + ****************************************************************************/ + +static void sam_takechsem(void) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_chsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givechsem(void) +{ + (void)sem_post(&g_chsem); +} + +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +#if CONFIG_SAMDL_DMAC_NDESC > 0 +static void sam_takedsem(void) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(void) +{ + (void)sem_post(&g_dsem); +} +#endif + +/**************************************************************************** + * Name: sam_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void sam_dmaterminate(struct sam_dmach_s *dmach, int result) +{ + irqstate_t flags; + + /* Disable the DMA channel */ + + flags = enter_critical_section(); + putreg8(dmach->dc_chan, SAM_DMAC_CHID); + putreg8(0, SAM_DMAC_CHCTRLA); + + /* Reset the DMA channel */ + + putreg8(DMAC_CHCTRLA_SWRST, SAM_DMAC_CHCTRLA); + + /* Disable all channel interrupts */ + + putreg8(1 << dmach->dc_chan, SAM_DMAC_CHINTENCLR); + leave_critical_section(flags); + + /* Free the DMA descriptor list */ + + sam_free_desc(dmach); + + /* Perform the DMA complete callback */ + + if (dmach->dc_callback) + { + dmach->dc_callback((DMA_HANDLE)dmach, dmach->dc_arg, result); + } + + dmach->dc_callback = NULL; + dmach->dc_arg = NULL; + dmach->dc_dir = DMADIR_UNKOWN; +} + +/**************************************************************************** + * Name: sam_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int sam_dmainterrupt(int irq, void *context) +{ + struct sam_dmach_s *dmach; + unsigned int chndx; + uint16_t intpend; + + /* Process all pending channel interrupts */ + + while (((intpend = getreg16(SAM_DMAC_INTPEND)) & DMAC_INTPEND_PEND) != 0) + { + /* Get the channel that generated the interrupt */ + + chndx = (intpend & DMAC_INTPEND_ID_MASK) >> DMAC_INTPEND_ID_SHIFT; + dmach = &g_dmach[chndx]; + + /* Clear all pending channel interrupt */ + + putreg8(DMAC_INT_ALL, SAM_DMAC_CHINTFLAG); + + /* Check for transfer error interrupt */ + + if ((intpend & DMAC_INTPEND_TERR) != 0) + { + /* Yes... Terminate the transfer with an error? */ + + sam_dmaterminate(dmach, -EIO); + } + + /* Check for channel transfer complete interrupt */ + + else if ((intpend & DMAC_INTPEND_TCMPL) != 0) + { + /* Yes.. Terminate the transfer with success */ + + sam_dmaterminate(dmach, OK); + } + + /* Check for channel suspend interrupt */ + + else if ((intpend & DMAC_INTPEND_SUSP) != 0) + { + /* REVISIT: Do we want to do anything here? */ + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_addrincr + * + * Description: + * Peripheral address increment for each beat. + * + ****************************************************************************/ + +#if 0 // Not used +static size_t sam_addrincr(struct sam_dmach_s *dmach) +{ + size_t beatsize; + size_t stepsize; + int shift + + /* How bit is one beat? {1,2,4} */ + + shift = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> + DMACH_FLAG_BEATSIZE_SHIFT; + beatsize = (1 << shift); + + /* What is the address increment per beat? {1,4,6,...,128} */ + + shift = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> + DMACH_FLAG_STEPSIZE_SHIFT; + stepsize = (1 << shift); + + return (beatsize * stepsize); +} +#endif + +/**************************************************************************** + * Name: sam_alloc_desc + * + * Description: + * Allocate one DMA descriptor. If the base DMA descriptor list entry is + * unused, then that value structure will be returned. Otherwise, this + * function will search for a free descriptor in the g_desc[] list. + * + * NOTE: Descriptor list entries are freed by the DMA interrupt handler. + * However, since the setting/clearing of the 'in use' indication is atomic, + * no special actions need be performed. It would be a good thing to add + * logic to handle the case where all of the entries are exhausted and we + * could wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct dma_desc_s *sam_alloc_desc(struct sam_dmach_s *dmach) +{ + struct dma_desc_s *desc; + + /* First check if the base descriptor for the DMA channel is available */ + + desc = &g_base_desc[dmach->dc_chan]; + if (desc->srcaddr == 0) + { + /* Yes, return a pointer to the base descriptor */ + + desc->srcaddr = (uint32_t)-1; /* Any non-zero value */ + return desc; + } +#if CONFIG_SAMDL_DMAC_NDESC > 0 + else + { + int i; + + /* Wait if no descriptor is available. When we get a semaphore count, + * then there will be at least one free descriptor in the table and + * it is ours. + */ + + sam_takedsem(); + + /* Examine each list entry to find an available one -- i.e., one + * with srcaddr == 0. That srcaddr field is set to zero by the DMA + * transfer complete interrupt handler. The following should be safe + * because that is an atomic operation. + */ + + for (i = 0; i < CONFIG_SAMDL_DMAC_NDESC; i++) + { + desc = &g_dma_desc[i]; + if (desc->srcaddr == 0) + { + /* Set the srcaddr to any non-zero value to reserve + * the descriptor. + */ + + desc->srcaddr = (uint32_t)-1; /* Any non-zero value */ + + /* Save a pointer to the first allocated DMA descriptor + * (for sam_free_desc). We have to do this because we cannot + * use the link in the base descriptor; it will be overwritten + * by the writeback. + */ + + if (dmach->dc_head == NULL) + { + dmach->dc_head = desc; + } + + return desc; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + DEBUGPANIC(); + } +#endif + + return NULL; +} + +/**************************************************************************** + * Name: sam_append_desc + * + * Description: + * Allocate and add one descriptor to the DMA channel's descriptor list. + * + ****************************************************************************/ + +static struct dma_desc_s *sam_append_desc(struct sam_dmach_s *dmach, + uint16_t btctrl, uint16_t btcnt, + uint32_t srcaddr, uint32_t dstaddr) +{ + struct dma_desc_s *desc; + + /* Sanity check -- srcaddr == 0 is the indication that the descriptor is + * unused. Obviously setting it to zero would break that usage. + */ + + DEBUGASSERT(srcaddr != 0); + + /* Allocate a DMA descriptor */ + + desc = sam_alloc_desc(dmach); + if (desc == NULL) + { + /* We have it. Initialize the new descriptor list entry */ + + desc->btctrl = btctrl; /* Block Transfer Control Register */ + desc->btcnt = btcnt; /* Block Transfer Count Register */ + desc->srcaddr = srcaddr; /* Block Transfer Source Address Register */ + desc->dstaddr = dstaddr; /* Block Transfer Destination Address Register */ + desc->descaddr = 0; /* Next Address Descriptor Register */ + + /* And then hook it at the tail of the descriptor list */ + +#if CONFIG_SAMDL_DMAC_NDESC > 0 + if (dmach->dc_tail != NULL) + { + struct dma_desc_s *prev; + + DEBUGASSERT(desc != g_base_desc[dmach->dc_chan]); + + /* Link the previous tail to the new tail */ + + prev->descaddr = (uint32_t)desc; + } + else +#endif + { + /* There is no previous link. This is the new head of the list */ + + DEBUGASSERT(desc == g_base_desc[dmach->dc_chan]); + } + +#if CONFIG_SAMDL_DMAC_NDESC > 0 + /* In either case, this is the new tail of the list. */ + + dmach->dc_tail = desc; +#endif + } + + return desc; +} + +/**************************************************************************** + * Name: sam_free_desc + * + * Description: + * Free all descriptors in the DMA channel's descriptor list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_free_desc(struct sam_dmach_s *dmach) +{ + struct dma_desc_s *desc; +#if CONFIG_SAMDL_DMAC_NDESC > 0 + struct dma_desc_s *next; +#endif + + /* Get the base descriptor pointer */ + + desc = &g_base_desc[dmach->dc_chan]; +#if CONFIG_SAMDL_DMAC_NDESC > 0 + next = dmach->dc_head; + + dmach->dc_head = NULL; + dmach->dc_tail = NULL; +#endif + + /* Nullify the base descriptor */ + + memset(desc, 0, sizeof(struct dma_desc_s)); + +#if CONFIG_SAMDL_DMAC_NDESC > 0 + /* Reset each additional descriptor in the descriptor list (thereby + * freeing them) + */ + + while (next != NULL) + { + desc = next; + DEBUGASSERT(desc->srcaddr != 0); + + next = (struct dma_desc_s *)desc->descaddr; + memset(desc, 0, sizeof(struct dma_desc_s)); + sam_givedsem(); + } +#endif +} + +/**************************************************************************** + * Name: sam_maxtransfer + * + * Description: + * Maximum number of bytes that can be sent/received in one transfer + * + ****************************************************************************/ + +static size_t sam_maxtransfer(struct sam_dmach_s *dmach) +{ + int beatsize; + + /* The number of bytes per beat is 2**BEATSIZE */ + + beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> + LPSRAM_BTCTRL_STEPSIZE_SHIFT; + + /* Maximum beats is UINT16_MAX */ + + return (size_t)UINT16_MAX << beatsize; +} + +/**************************************************************************** + * Name: sam_bytes2beats + * + * Description: + * Convert a count of bytes into a count of beats + * + ****************************************************************************/ + +static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes) +{ + size_t mask; + int beatsize; + size_t nbeats; + + /* The number of bytes per beat is 2**BEATSIZE */ + + beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> + LPSRAM_BTCTRL_STEPSIZE_SHIFT; + + /* The number of beats is then the ceiling of the division */ + + mask = (1 < beatsize) - 1; + nbeats = (nbytes + mask) >> beatsize; + DEBUGASSERT(nbeats <= UINT16_MAX); + return (uint16_t)nbeats; +} + +/**************************************************************************** + * Name: sam_txbuffer + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint16_t btctrl; + uint16_t btcnt; + uint16_t tmp; + + DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_TX); + + /* Set up the Block Transfer Control Register configuration: + * + * This are fixed register selections: + * + * LPSRAM_BTCTRL_VALID - Descriptor is valid + * LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output + * LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt + * when the last block transfer completes. + * + * Other settings come from the channel configuration: + * + * LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE + * LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_MEM_INCREMENT + * LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_PERIPH_INCREMENT + * LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL + * LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE + */ + + btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE | + LPSRAM_BTCTRL_BLOCKACT_INT; + + tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT; + btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT; + + if ((dmach->dc_flags & DMACH_FLAG_MEM_INCREMENT) != 0) + { + btctrl |= LPSRAM_BTCTRL_SRCINC; + } + + if ((dmach->dc_flags & DMACH_FLAG_PERIPH_INCREMENT) != 0) + { + btctrl |= LPSRAM_BTCTRL_DSTINC; + } + + if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_PERIPH) + { + btctrl |= LPSRAM_BTCTRL_STEPSEL; + } + + tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT; + btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT; + + /* Set up the Block Transfer Count Register configuration */ + + btcnt = sam_bytes2beats(dmach, nbytes); + + /* Add the new descriptor list entry */ + + if (!sam_append_desc(dmach, btctrl, btcnt, maddr, paddr)) + { + return -ENOMEM; + } + + dmach->dc_dir = DMADIR_TX; + return OK; +} + +/**************************************************************************** + * Name: sam_rxbuffer + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint16_t btctrl; + uint16_t btcnt; + uint16_t tmp; + + DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_RX); + + /* Set up the Block Transfer Control Register configuration: + * + * This are fixed register selections: + * + * LPSRAM_BTCTRL_VALID - Descriptor is valid + * LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output + * LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt + * when the last block transfer completes. + * + * Other settings come from the channel configuration: + * + * LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE + * LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_PERIPH_INCREMENT + * LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_MEM_INCREMENT + * LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL + * LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE + */ + + btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE | + LPSRAM_BTCTRL_BLOCKACT_INT; + + tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT; + btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT; + + if ((dmach->dc_flags & DMACH_FLAG_PERIPH_INCREMENT) != 0) + { + btctrl |= LPSRAM_BTCTRL_SRCINC; + } + + if ((dmach->dc_flags & DMACH_FLAG_MEM_INCREMENT) != 0) + { + btctrl |= LPSRAM_BTCTRL_DSTINC; + } + + if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_MEM) + { + btctrl |= LPSRAM_BTCTRL_STEPSEL; + } + + tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT; + btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT; + + /* Set up the Block Transfer Count Register configuration */ + + btcnt = sam_bytes2beats(dmach, nbytes); + + /* Add the new descriptor list entry */ + + if (!sam_append_desc(dmach, btctrl, btcnt, paddr, maddr)) + { + return -ENOMEM; + } + + dmach->dc_dir = DMADIR_RX; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + dmallvdbg("Initialize DMAC\n"); + int i; + + /* Initialize global semaphores */ + + sem_init(&g_chsem, 0, 1); +#if CONFIG_SAMDL_DMAC_NDESC > 0 + sem_init(&g_dsem, 0, CONFIG_SAMDL_DMAC_NDESC); +#endif + + /* Initialized the DMA channel table */ + + for (i = 0; i < SAMDL_NDMACHAN; i++) + { + g_dmach[i].dc_chan = i; + } + + /* Clear descriptors (this will not be done automatically because they are + * not in .bss). + */ + + memset(g_base_desc, 0, sizeof(struct dma_desc_s)*SAMDL_NDMACHAN); + memset(g_writeback_desc, 0, sizeof(struct dma_desc_s)*SAMDL_NDMACHAN); +#if CONFIG_SAMDL_DMAC_NDESC > 0 + memset(g_dma_desc, 0, sizeof(struct dma_desc_s)*CONFIG_SAMDL_DMAC_NDESC); +#endif + + /* Enable peripheral clock */ + + sam_dmac_enableperiph(); + + /* Disable and reset the DMAC */ + + putreg16(0, SAM_DMAC_CTRL); + putreg16(DMAC_CTRL_SWRST, SAM_DMAC_CTRL); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_DMAC, sam_dmainterrupt); + + /* Set the LPRAM DMA descriptor table addresses. These can only be + * written when the DMAC is disabled. + */ + + putreg32((uint32_t)g_base_desc, SAM_DMAC_BASEADDR); + putreg32((uint32_t)g_writeback_desc, SAM_DMAC_WRBADDR); + + /* Enable the DMA controller and all priority levels */ + + putreg16(DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0 | DMAC_CTRL_LVLEN1 | + DMAC_CTRL_LVLEN2, SAM_DMAC_CTRL); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_DMAC); +} + +/**************************************************************************** + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. However, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel if the required FIFO size is available, this function + * returns a non-NULL, void* DMA channel handle. NULL is returned on any + * failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint32_t chflags) +{ + struct sam_dmach_s *dmach; + irqstate_t flags; + unsigned int chndx; + + /* Search for an available DMA channel */ + + dmach = NULL; + sam_takechsem(); + + for (chndx = 0; chndx < SAMDL_NDMACHAN; chndx++) + { + struct sam_dmach_s *candidate = &g_dmach[chndx]; + if (!candidate->dc_inuse) + { + dmach = candidate; + dmach->dc_inuse = true; + + /* Set the DMA channel flags */ + + dmach->dc_flags = chflags; + + /* Disable the DMA channel */ + + flags = enter_critical_section(); + putreg8(chndx, SAM_DMAC_CHID); + putreg8(0, SAM_DMAC_CHCTRLA); + + /* Reset the channel */ + + putreg8(DMAC_CHCTRLA_SWRST, SAM_DMAC_CHCTRLA); + + /* Disable all channel interrupts */ + + putreg8(1 << chndx, SAM_DMAC_CHINTENCLR); + leave_critical_section(flags); + break; + } + } + + sam_givechsem(); + + dmavdbg("chflags: %08x returning dmach: %p\n", (int)chflags, dmach); + return (DMA_HANDLE)dmach; +} + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and + * configured in one step. This is the typical case where a DMA channel performs + * a constant role. The alternative is (2) where the DMA channel is reconfigured + * on the fly. In this case, the chflags provided to sam_dmachannel are not used + * and sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + + /* Set the new DMA channel flags. */ + + dmavdbg("chflags: %08x\n", (int)chflags); + dmach->dc_flags = chflags; +} + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT((dmach != NULL) && (dmach->dc_inuse)); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + dmach->dc_flags = 0; + dmach->dc_inuse = false; +} + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + ssize_t remaining = (ssize_t)nbytes; + size_t maxtransfer; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + +#if CONFIG_SAMDL_DMAC_NDESC > 0 + dmavdbg("dc_head: %p dc_tail: %p\n", dmach->dc_head, dmach->dc_tail); +#endif + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(dmach); + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_txbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do do). + * + * REVISIT: What if stepsize is not 1? + */ + + if ((dmach->dc_flags & DMACH_FLAG_PERIPH_INCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->dc_flags & DMACH_FLAG_MEM_INCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_txbuffer(dmach, paddr, maddr, remaining); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + ssize_t remaining = (ssize_t)nbytes; + size_t maxtransfer; + int ret = OK; + + dmavdbg("dmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + dmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(dmach); + +#if CONFIG_SAMDL_DMAC_NDESC > 0 + dmavdbg("dc_head: %p dc_tail: %p\n", dmach->dc_head, dmach->dc_tail); +#endif + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(dmach); + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_rxbuffer(dmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate + * to do so). + * + * REVISIT: What if stepsize is not 1? + */ + + if ((dmach->dc_flags & DMACH_FLAG_PERIPH_INCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((dmach->dc_flags & DMACH_FLAG_MEM_INCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_rxbuffer(dmach, paddr, maddr, remaining); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + struct dma_desc_s *head; + irqstate_t flags; + uint8_t ctrla; + uint32_t chctrlb; + uint32_t tmp; + uint8_t qosctrl; + uint8_t periphqos; + uint8_t memqos; + int ret = -EINVAL; + + dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg); + DEBUGASSERT(dmach != NULL && dmach->dc_chan < SAMDL_NDMACHAN); + head = &g_base_desc[dmach->dc_chan]; + + /* Verify that the DMA has been setup (i.e., at least one entry in the + * descriptor list, the base entry). + */ + + if (head->srcaddr != 0) + { + /* Save the callback info. This will be invoked when the DMA + * completes. + */ + + dmach->dc_callback = callback; + dmach->dc_arg = arg; + + /* Clear any pending interrupts from any previous DMAC transfer. */ + + flags = enter_critical_section(); + putreg8(dmach->dc_chan, SAM_DMAC_CHID); + putreg8(0, SAM_DMAC_CHCTRLA); + + /* Setup the Channel Control B Register + * + * DMAC_CHCTRLB_EVACT_TRIG - Normal transfer and trigger + * DMAC_CHCTRLB_EVIE=0 - No channel input actions + * DMAC_CHCTRLB_EVOE=0 - Channel event output disabled + * DMAC_CHCTRLB_LVL - Determined by DMACH_FLAG_PRIORITY + * DMAC_CHCTRLB_TRIGSRC - Determined by DMACH_FLAG_PERIPH_*XTRIG + * DMAC_CHCTRLB_TRIGACT_BEAT - One trigger required for beat transfer + * DMAC_CHCTRLB_CMD_NOACTION - No action + */ + + chctrlb = DMAC_CHCTRLB_EVACT_TRIG | DMAC_CHCTRLB_TRIGACT_BEAT | + DMAC_CHCTRLB_CMD_NOACTION; + + tmp = (dmach->dc_flags & DMACH_FLAG_PRIORITY_MASK) >> + DMACH_FLAG_PRIORITY_SHIFT; + chctrlb |= tmp << DMAC_CHCTRLB_LVL_SHIFT; + + if (dmach->dc_dir == DMADIR_TX) + { + /* Memory to peripheral */ + + tmp = (dmach->dc_flags & DMACH_FLAG_PERIPH_TXTRIG_MASK) >> + DMACH_FLAG_PERIPH_TXTRIG_SHIFT; + } + else + { + /* Peripheral to memory */ + + DEBUGASSERT(dmach->dc_dir == DMADIR_RX); + tmp = (dmach->dc_flags & DMACH_FLAG_PERIPH_RXTRIG_MASK) >> + DMACH_FLAG_PERIPH_RXTRIG_SHIFT; + } + + chctrlb |= tmp << DMAC_CHCTRLB_TRIGSRC_SHIFT; + putreg8(chctrlb, SAM_DMAC_CHCTRLB); + + /* Setup the Quality of Service Control Register + * + * DMAC_QOSCTRL_WRBQOS_DISABLE - Background + * DMAC_QOSCTRL_FQOS, DMAC_QOSCTRL_DQOS - Depend on DMACH_FLAG_PERIPH_QOS + * and DMACH_FLAG_MEM_QOS + */ + + periphqos = (dmach->dc_flags & DMACH_FLAG_PERIPH_QOS_MASK) >> + DMACH_FLAG_PERIPH_QOS_SHIFT; + memqos = (dmach->dc_flags & DMACH_FLAG_MEM_QOS_MASK) >> + DMACH_FLAG_MEM_QOS_SHIFT; + + if (dmach->dc_dir == DMADIR_TX) + { + /* Memory to peripheral */ + + qosctrl = (memqos << DMAC_QOSCTRL_FQOS_SHIFT) | + (periphqos << DMAC_QOSCTRL_DQOS_SHIFT); + } + else + { + /* Peripheral to memory */ + + DEBUGASSERT(dmach->dc_dir == DMADIR_RX); + qosctrl = (periphqos << DMAC_QOSCTRL_FQOS_SHIFT) | + (memqos << DMAC_QOSCTRL_DQOS_SHIFT); + } + + putreg8(qosctrl | DMAC_QOSCTRL_WRBQOS_DISABLE, SAM_DMAC_QOSCTRL); + + /* Enable the channel */ + + ctrla = DMAC_CHCTRLA_ENABLE; + if (dmach->dc_flags & DMACH_FLAG_RUNINSTDBY) + { + ctrla |= DMAC_CHCTRLA_RUNSTDBY; + } + + putreg8(ctrla, SAM_DMAC_CHCTRLA); + + /* Enable DMA channel interrupts */ + + putreg8(DMAC_INT_TERR | DMAC_INT_TCMPL, SAM_DMAC_CHINTENSET); + leave_critical_section(flags); + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can + * be called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + irqstate_t flags; + + dmavdbg("dmach: %p\n", dmach); + DEBUGASSERT(dmach != NULL); + + flags = enter_critical_section(); + sam_dmaterminate(dmach, -EINTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + uintptr_t base; + irqstate_t flags; + + /* Sample DMAC registers. */ + + flags = enter_critical_section(); + regs->ctrl = getreg16(SAM_DMAC_CTRL); /* Control Register */ + regs->crcctrl = getreg16(SAM_DMAC_CRCCTRL); /* CRC Control Register */ + regs->crcdatain = getreg32(SAM_DMAC_CRCDATAIN); /* CRC Data Input Register */ + regs->crcchksum = getreg32(SAM_DMAC_CRCCHKSUM); /* CRC Checksum Register */ + regs->crcstatus = getreg8(SAM_DMAC_CRCSTATUS); /* CRC Status Register */ + regs->dbgctrl = getreg8(SAM_DMAC_DBGCTRL); /* Debug Control Register */ + regs->qosctrl = getreg8(SAM_DMAC_QOSCTRL); /* Quality of Service Control Register */ + regs->swtrigctrl = getreg32(SAM_DMAC_SWTRIGCTRL); /* Software Trigger Control Register */ + regs->prictrl0 = getreg32(SAM_DMAC_PRICTRL0); /* Priority Control 0 Register */ + regs->intpend = getreg16(SAM_DMAC_INTPEND); /* Interrupt Pending Register */ + regs->intstatus = getreg32(SAM_DMAC_INTSTATUS); /* Interrupt Status Register */ + regs->busych = getreg32(SAM_DMAC_BUSYCH); /* Busy Channels Register */ + regs->pendch = getreg32(SAM_DMAC_PENDCH); /* Pending Channels Register */ + regs->active = getreg32(SAM_DMAC_ACTIVE); /* Active Channels and Levels Register */ + regs->baseaddr = getreg32(SAM_DMAC_BASEADDR); /* Descriptor Memory Section Base Address Register */ + regs->wrbaddr = getreg32(SAM_DMAC_WRBADDR); /* Write-Back Memory Section Base Address Register */ + regs->chid = getreg8(SAM_DMAC_CHID); /* Channel ID Register */ + regs->chctrla = getreg8(SAM_DMAC_CHCTRLA); /* Channel Control A Register */ + regs->chctrlb = getreg32(SAM_DMAC_CHCTRLB); /* Channel Control B Register */ + regs->chintflag = getreg8(SAM_DMAC_CHINTFLAG); /* Channel Interrupt Flag Status and Clear Register */ + regs->chstatus = getreg8(SAM_DMAC_CHSTATUS); /* Channel Status Register */ +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg) +{ + struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle; + + dmadbg("%s\n", msg); + dmadbg(" DMAC Registers:\n"); + dmadbg(" CTRL: %04x CRCCTRL: %04x CRCDATAIN: %08x CRCCHKSUM: %08x\n", + regs->ctrl, regs->crcctrl, regs->crcdatain, regs->crcchksum); + dmadbg(" CRCSTATUS: %02x DBGCTRL: %02x QOSCTRL: %02x SWTRIGCTRL: %08x\n", + regs->crcstatus, regs->dbgctrl, regs->qosctrl, regs->swtrigctrl); + dmadbg(" PRICTRL0: %08x INTPEND: %04x INSTSTATUS: %08x BUSYCH: %08x\n", + regs->prictrl0, regs->intpend, regs->intstatus, regs->busych); + dmadbg(" PENDCH: %08x ACTIVE: %08x BASEADDR: %08x WRBADDR: %08x\n", + regs->pendch, regs->active, regs->baseaddr, regs->wrbaddr); + dmadbg(" CHID: %02x CHCRTRLA: %02x CHCRTRLB: %08x CHINFLAG: %02x\n", + regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag, + dmadbg(" CHSTATUS: %02x\n", + regs->chstatus); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_SAMDL_DMAC */ diff --git a/arch/arm/src/samdl/sam_dmac.h b/arch/arm/src/samdl/sam_dmac.h new file mode 100644 index 0000000000000000000000000000000000000000..cc1c60e7a0cd781d2d37aed06b533b53428ccd0b --- /dev/null +++ b/arch/arm/src/samdl/sam_dmac.h @@ -0,0 +1,352 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_dmac.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_DMAC_H +#define __ARCH_ARM_SRC_SAMDL_SAM_DMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +#include "chip/sam_dmac.h" + +#ifdef CONFIG_SAMDL_DMAC + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# error Missing support for the SAMD20 architecture +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_dmac.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +#endif + +/* DMA ******************************************************************************/ + +/* Flags used to characterize the desired DMA channel. The naming convention is that + * one side is the peripheral and the other is memory (however, the interface could still + * be used if, for example, both sides were memory although the naming would be awkward) + */ + +/* Common characteristics + * + * BEATSIZE - The size of one bus transfer or "beat". 8-, 16-, or 32-bits + * STEPSIZE - When the address is incremented, it is increments by how many "beats"? + * STEPSEL - The STEPSIZE may be applied only to the memory to the peripheral. + */ + +#define DMACH_FLAG_BEATSIZE_SHIFT (0) /* Bits 0-1: Beat size */ +#define DMACH_FLAG_BEATSIZE_MASK (3 << DMACH_FLAG_BEATSIZE_SHIFT) +# define DMACH_FLAG_BEATSIZE_BYTE (0 << DMACH_FLAG_BEATSIZE_SHIFT) /* 8-bit bus transfer */ +# define DMACH_FLAG_BEATSIZE_HWORD (1 << DMACH_FLAG_BEATSIZE_SHIFT) /* 16-bit bus transfer */ +# define DMACH_FLAG_BEATSIZE_WORD (2 << DMACH_FLAG_BEATSIZE_SHIFT) /* 32-bit bus transfer */ +#define DMACH_FLAG_STEPSEL (1 << 2) /* Bit 2: Step selection */ +# define DMACH_FLAG_STEPSEL_MEM (0) /* 0=Step size applies to memory */ +# define DMACH_FLAG_STEPSEL_PERIPH (1 << 2) /* 1=Step size applies to peripheral */ +#define DMACH_FLAG_STEPSIZE_SHIFT (3) /* Bits 3-5: Address increment step */ +#define DMACH_FLAG_STEPSIZE_MASK (7 << DMACH_FLAG_STEPSIZE_SHIFT) +# define DMACH_FLAG_STEPSIZE_X1 (0 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 1 */ +# define DMACH_FLAG_STEPSIZE_X2 (1 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 2 */ +# define DMACH_FLAG_STEPSIZE_X4 (2 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 4 */ +# define DMACH_FLAG_STEPSIZE_X8 (3 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 8 */ +# define DMACH_FLAG_STEPSIZE_X16 (4 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 16 */ +# define DMACH_FLAG_STEPSIZE_X32 (5 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 32 */ +# define DMACH_FLAG_STEPSIZE_X64 (6 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 64 */ +# define DMACH_FLAG_STEPSIZE_X128 (7 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 128 */ +#define DMACH_FLAG_PRIORITY_SHIFT (6) /* Bit 6-7: Arbitration priority */ +#define DMACH_FLAG_PRIORITY_MASK (3 << DMACH_FLAG_PRIORITY_SHIFT) +# define DMACH_FLAG_PRIORITY(n) ((uint32_t)(n) << DMACH_FLAG_PRIORITY_SHIFT) +#define DMACH_FLAG_RUNINSTDBY (1 << 8) /* Bit 8: Run in standby */ + +/* Peripheral endpoint characteristics. + * + * PERIPH_TXTRIG - The TX ID of the peripheral that provides the DMA trigger. This + * is one of the DMA_TRIGSRC_*[_TX] definitions. This trigger source + * is selected when sam_dmatxsetup() is called. + * PERIPH_RXTRIG - The RX ID of the peripheral that provides the DMA trigger. This + * is one of the DMA_TRIGSRC_*[_RX] definitions. This trigger source + * is selected when sam_dmarxsetup() is called. + * PERIPH_INCREMENT - Indicates the that peripheral address should be incremented on + * each "beat" + * PERIPH_QOS - Quality of service for peripheral accesses + */ + +#define DMACH_FLAG_PERIPH_TXTRIG_SHIFT (9) /* Bits 9-14: See DMAC_TRIGSRC_*[_TX] */ +#define DMACH_FLAG_PERIPH_TXTRIG_MASK (0x3f << DMACH_FLAG_PERIPH_TXTRIG_SHIFT) +# define DMACH_FLAG_PERIPH_TXTRIG(n) ((uint32_t)(n) << DMACH_FLAG_PERIPH_TXTRIG_SHIFT) +#define DMACH_FLAG_PERIPH_RXTRIG_SHIFT (15) /* Bits 15-20: See DMAC_TRIGSRC_*[_RX] */ +#define DMACH_FLAG_PERIPH_RXTRIG_MASK (0x3f << DMACH_FLAG_PERIPH_RXTRIG_SHIFT) +# define DMACH_FLAG_PERIPH_RXTRIG(n) ((uint32_t)(n) << DMACH_FLAG_PERIPH_RXTRIG_SHIFT) +#define DMACH_FLAG_PERIPH_INCREMENT (1 << 21) /* Bit 21: Autoincrement peripheral address */ +#define DMACH_FLAG_PERIPH_QOS_SHIFT (22) /* Bits 22-23: Peripheral quality of service */ +#define DMACH_FLAG_PERIPH_QOS_MASK (3 << DMACH_FLAG_PERIPH_QOS_SHIFT) +# define DMACH_FLAG_PERIPH_QOS_DISABLE (0 << DMACH_FLAG_PERIPH_QOS_SHIFT) /* Background */ +# define DMACH_FLAG_PERIPH_QOS_LOW (1 << DMACH_FLAG_PERIPH_QOS_SHIFT) /* Sensitve bandwidth */ +# define DMACH_FLAG_PERIPH_QOS_MEDIUM (2 << DMACH_FLAG_PERIPH_QOS_SHIFT) /* Sensitive latency */ +# define DMACH_FLAG_PERIPH_QOS_HIGH (3 << DMACH_FLAG_PERIPH_QOS_SHIFT) /* Critical latency */ + +/* Memory endpoint characteristics + * + * MEM_INCREMENT - Indicates the that memory address should be incremented on each + * "beat" + * MEM_QOS - Quality of service for memory accesses + */ + +#define DMACH_FLAG_MEM_INCREMENT (1 << 24) /* Bit 24: Autoincrement memory address */ +#define DMACH_FLAG_MEM_QOS_SHIFT (25) /* Bits 25-26: Memory quality of service */ +#define DMACH_FLAG_MEM_QOS_MASK (3 << DMACH_FLAG_MEM_QOS_SHIFT) +# define DMACH_FLAG_MEM_QOS_DISABLE (0 << DMACH_FLAG_MEM_QOS_SHIFT) /* Background */ +# define DMACH_FLAG_MEM_QOS_LOW (1 << DMACH_FLAG_MEM_QOS_SHIFT) /* Sensitve bandwidth */ +# define DMACH_FLAG_MEM_QOS_MEDIUM (2 << DMACH_FLAG_MEM_QOS_SHIFT) /* Sensitive latency */ +# define DMACH_FLAG_MEM_QOS_HIGH (3 << DMACH_FLAG_MEM_QOS_SHIFT) /* Critical latency */ + /* Bits 27-31: Not used */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct sam_dmaregs_s +{ + /* DMAC Registers */ + + uint8_t crcstatus; /* CRC Status Register */ + uint8_t dbgctrl; /* Debug Control Register */ + uint8_t qosctrl; /* Quality of Service Control Register */ + uint8_t chid; /* Channel ID Register */ + uint8_t chctrla; /* Channel Control A Register */ + uint8_t chintflag; /* Channel Interrupt Flag Status and Clear Register */ + uint8_t chstatus; /* Channel Status Register */ + + uint16_t ctrl; /* Control Register */ + uint16_t crcctrl; /* CRC Control Register */ + uint16_t intpend; /* Interrupt Pending Register */ + + uint32_t crcdatain; /* CRC Data Input Register */ + uint32_t crcchksum; /* CRC Checksum Register */ + uint32_t swtrigctrl; /* Software Trigger Control Register */ + uint32_t prictrl0; /* Priority Control 0 Register */ + uint32_t intstatus; /* Interrupt Status Register */ + uint32_t busych; /* Busy Channels Register */ + uint32_t pendch; /* Pending Channels Register */ + uint32_t active; /* Active Channels and Levels Register */ + uint32_t baseaddr; /* Descriptor Memory Section Base Address Register */ + uint32_t wrbaddr; /* Write-Back Memory Section Base Address Register */ + uint32_t chctrlb; /* Channel Control B Register */ +}; +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and gives the + * caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is the + * 'peripheral' and the other is 'memory'. However, the interface could still be + * used if, for example, both sides were memory although the naming would be + * awkward. + * + * Returned Value: + * If a DMA channel if the required FIFO size is available, this function returns + * a non-NULL, void* DMA channel handle. NULL is returned on any failure. + * + ************************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and + * configured in one step. This is the typical case where a DMA channel performs + * a constant role. The alternative is (2) where the DMA channel is reconfigured + * on the fly. In this case, the chflags provided to sam_dmachannel are not used + * and sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be + * used again until sam_dmachannel() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This function + * may be called multiple times to handle large and/or non-contiguous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes); + +/************************************************************************************ + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This function + * may be called multiple times to handle large and/or non-contiguous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes); + +/************************************************************************************ + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ************************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/************************************************************************************ + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ************************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs); +#else +# define sam_dmasample(handle,regs) +#endif + +/************************************************************************************ + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg); +#else +# define sam_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMDL_DMAC */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_DMAC_H */ diff --git a/arch/arm/src/samdl/sam_fuses.h b/arch/arm/src/samdl/sam_fuses.h new file mode 100644 index 0000000000000000000000000000000000000000..97b2971580b6979cba45c653bf618cb1c831ca11 --- /dev/null +++ b/arch/arm/src/samdl/sam_fuses.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_fuses.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_FUSES_H +#define __ARCH_ARM_SRC_SAMDL_SAM_FUSES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_fuses.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_fuses.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_FUSES_H */ diff --git a/arch/arm/src/samdl/sam_gclk.h b/arch/arm/src/samdl/sam_gclk.h new file mode 100644 index 0000000000000000000000000000000000000000..99fc453f13ce92198487a25798e3f079cc683c07 --- /dev/null +++ b/arch/arm/src/samdl/sam_gclk.h @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_gclk.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_GCLK_H +#define __ARCH_ARM_SRC_SAMDL_SAM_GCLK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_gclk.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_gclk.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure describes the configuration of one GCLK */ + +struct sam_gclkconfig_s +{ + uint8_t gclk; /* Clock generator */ + bool runstandby; /* Run clock in standby */ + bool output; /* Output enable */ + uint8_t clksrc; /* Encoded clock source */ + uint16_t prescaler; /* Prescaler value */ +}; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gclk_config + * + * Description: + * Configure a single GCLK(s) based on settings in the config structure. + * + * Input Parameters: + * config - An instance of struct sam_gclkconfig describing the GCLK + * configuration. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_gclk_config(FAR const struct sam_gclkconfig_s *config); + +/**************************************************************************** + * Name: sam_gclk_chan_enable + * + * Description: + * Configure and enable a GCLK peripheral channel. + * + * Input Parameters: + * channel - Index of the GCLK channel to be enabled + * srcgen - The GCLK source generator index + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FAMILY_SAML21 +void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen); +#endif + +/**************************************************************************** + * Name: sam_gclk_chan_disable + * + * Description: + * Disable a GCLK peripheral channel. + * + * Input Parameters: + * channel - Index of the GCLK channel to be disabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FAMILY_SAML21 +void sam_gclk_chan_disable(uint8_t channel); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_GCLK_H */ diff --git a/arch/arm/src/samdl/sam_i2c_master.h b/arch/arm/src/samdl/sam_i2c_master.h new file mode 100644 index 0000000000000000000000000000000000000000..b4bd90e830dfcf8c9e113b986b87763e693ea0da --- /dev/null +++ b/arch/arm/src/samdl/sam_i2c_master.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_i2c_master.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_I2C_MASTER_H +#define __ARCH_ARM_SRC_SAMDL_SAM_I2C_MASTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_i2c_master.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_i2c_master.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_I2C_MASTER_H */ diff --git a/arch/arm/src/samdl/sam_i2c_slave.h b/arch/arm/src/samdl/sam_i2c_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..ed94897fdfe2374841026e1396c78fe36250056d --- /dev/null +++ b/arch/arm/src/samdl/sam_i2c_slave.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_i2c_slave.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_I2C_SLAVE_H +#define __ARCH_ARM_SRC_SAMDL_SAM_I2C_SLAVE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_i2c_slave.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_i2c_slave.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_I2C_SLAVE_H */ diff --git a/arch/arm/src/samdl/sam_idle.c b/arch/arm/src/samdl/sam_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..be58de12be6351cf9b21f970441e583dcb33a8f0 --- /dev/null +++ b/arch/arm/src/samdl/sam_idle.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_idle.c + * + * Copyright (C) 2014, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + sam_pmstop(true); + break; + + case PM_SLEEP: + (void)sam_pmstandby(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/samdl/sam_irq.c b/arch/arm/src/samdl/sam_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..3f12b9943ac58f79823e36f3b285fd8f5b8c9834 --- /dev/null +++ b/arch/arm/src/samdl/sam_irq.c @@ -0,0 +1,337 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_irq.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | NVIC_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_nmi, sam_busfault, sam_usagefault, sam_pendsv, + * sam_dbgmonitor, sam_pendsv, sam_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int sam_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int sam_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int sam_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: sam_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. + * + ****************************************************************************/ + +static inline void sam_clrpend(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= SAM_IRQ_INTERRUPT && irq < SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - SAM_IRQ_INTERRUPT)), ARMV6M_NVIC_ICPR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int i; + + /* Disable all interrupts */ + + putreg32(0xffffffff, ARMV6M_NVIC_ICER); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR2); + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR3); + + /* Now set all of the interrupt lines to the default priority */ + + for (i = 0; i < 8; i++) + { + regaddr = ARMV6M_NVIC_IPR(i); + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(SAM_IRQ_SVCALL, up_svcall); + irq_attach(SAM_IRQ_HARDFAULT, up_hardfault); + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(SAM_IRQ_NMI, sam_nmi); + irq_attach(SAM_IRQ_PENDSV, sam_pendsv); + irq_attach(SAM_IRQ_RESERVED, sam_reserved); +#endif + + sam_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= SAM_IRQ_INTERRUPT && irq < SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS) + { + /* Set the appropriate bit in the ICER register to disable the + * interrupt + */ + + putreg32((1 << (irq - SAM_IRQ_INTERRUPT)), ARMV6M_NVIC_ICER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == SAM_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, SYSTICK_CSR_ENABLE, 0); + } + + sam_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= SAM_IRQ_INTERRUPT && irq < SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - SAM_IRQ_INTERRUPT)), ARMV6M_NVIC_ISER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == SAM_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, 0, SYSTICK_CSR_ENABLE); + } + + sam_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + sam_clrpend(irq); +} + +/**************************************************************************** + * Name: sam_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_IRQ +void sam_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" ISER: %08x ICER: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); + lldbg(" ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), + getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), + getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); + + lldbg("SYSCON:\n"); + lldbg(" CPUID: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID)); + lldbg(" ICSR: %08x AIRCR: %08x\n", + getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); + lldbg(" SCR: %08x CCR: %08x\n", + getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); + lldbg(" SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#else +# define sam_dumpnvic(msg, irq) +#endif + diff --git a/arch/arm/src/samdl/sam_irq.h b/arch/arm/src/samdl/sam_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ddc5a7ada5204f9a5a3bd116b68f513aaf567f3a --- /dev/null +++ b/arch/arm/src/samdl/sam_irq.h @@ -0,0 +1,79 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_IRQ_H +#define __ARCH_ARM_SRC_SAMDL_SAM_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_IRQ +void sam_dumpnvic(const char *msg, int irq); +#else +# define sam_dumpnvic(msg, irq) +#endif + +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_IRQ_H */ diff --git a/arch/arm/src/samdl/sam_irqprio.c b/arch/arm/src/samdl/sam_irqprio.c new file mode 100644 index 0000000000000000000000000000000000000000..e02325f632987115288c1c017317172d5c2ba0f5 --- /dev/null +++ b/arch/arm/src/samdl/sam_irqprio.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_irqprio.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "nvic.h" +#include "up_arch.h" + +#include "sam_irq.h" + +#ifdef CONFIG_ARCH_IRQPRIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq == SAM_IRQ_SVCALL || + irq == SAM_IRQ_PENDSV || + irq == SAM_IRQ_SYSTICK || + (irq >= SAM_IRQ_INTERRUPT && irq < NR_IRQS)); + DEBUGASSERT(priority >= NVIC_SYSH_PRIORITY_MAX && + priority <= NVIC_SYSH_PRIORITY_MIN); + + /* Check for external interrupt */ + + if (irq >= SAM_IRQ_INTERRUPT && irq < SAM_IRQ_INTERRUPT + SAM_IRQ_NINTS) + { + /* ARMV6M_NVIC_IPR() maps register IPR0-IPR7 with four settings per + * register. + */ + + regaddr = ARMV6M_NVIC_IPR(irq >> 2); + shift = (irq & 3) << 3; + } + + /* Handle processor exceptions. Only SVCall, PendSV, and SysTick can be + * reprioritized. And we will not permit modification of SVCall through + * this function. + */ + + else if (irq == SAM_IRQ_PENDSV) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_14_SHIFT; + } + else if (irq == SAM_IRQ_SYSTICK) + { + regaddr = ARMV6M_SYSCON_SHPR2; + shift = SYSCON_SHPR3_PRI_15_SHIFT; + } + else + { + return ERROR; + } + + /* Set the priority */ + + regval = getreg32(regaddr); + regval &= ~((uint32_t)0xff << shift); + regval |= ((uint32_t)priority << shift); + putreg32(regval, regaddr); + + sam_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/samdl/sam_lowputc.c b/arch/arm/src/samdl/sam_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..800c3c110d34b5131672f5c3a0e3bad7f3e8ac88 --- /dev/null +++ b/arch/arm/src/samdl/sam_lowputc.c @@ -0,0 +1,484 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_lowputc.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * 2. Atmel sample code. This code has an ASF license with is compatible + * with the NuttX BSD license, but includes the provision that this + * code not be used in non-Atmel products. That sample code was used + * only as a reference so I believe that only the NuttX BSD license + * applies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sam_config.h" +#include "sam_gclk.h" +#include "sam_pm.h" +#include "sam_sercom.h" +#include "sam_usart.h" +#include "sam_lowputc.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef OK +# define OK 0 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_wait_synchronization + * + * Description: + * Wait until the SERCOM USART reports that it is synchronized. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +static void +sam_wait_synchronization(const struct sam_usart_config_s * const config) +{ + while (usart_syncbusy(config)); +} +#endif + +/**************************************************************************** + * Name: sam_usart_configure + * + * Description: + * Configure the SERCOM USART operating mode (as a normal UART). + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +static inline int +sam_usart_configure(const struct sam_usart_config_s * const config) +{ + uint32_t ctrla; + uint32_t ctrlb; + uint16_t baud; + uint64_t tmp; + + /* Calculate BAUD divider from the source clock frequency and desired. + * baud. For asynchronous mode, the formula for the baud generation is + * + * Fbaud = (Frefclk / 16) * (1 - (BAUD / 65,536)) + * + * Or, + * + * BAUD = 65,536 * (1 - 16 * (Fbaud / Fref)) + * = 65,536 - 16 * 65,536 * Fbaud / Fref + * + * Example: Fref = 48MHz and Fbaud = 9600 + * + * BAUD = 65,326 + * Fbaud = 9600 + * + * Example: Fref = 48MHz and Fbaud = 115,200 + * + * BAUD = 63,019 + * Fbaud = 115,219 + * + * REVISIT: For the SAML21, only 16x sampling with arithmetic BAUD is + * supported. + */ + + tmp = (uint64_t)config->baud << 20; + tmp = (tmp + (config->frequency >> 1)) / config->frequency; + + /* Verify that the calculated result is within range */ + + if (tmp < 1 || tmp > UINT16_MAX) + { + return -ERANGE; + } + + baud = 65536 - (uint16_t)tmp; + + /* Disable all USART interrupts */ + + putreg8(USART_INT_ALL, config->base + SAM_USART_INTENCLR_OFFSET); + + /* Wait until synchronization is complete */ + + sam_wait_synchronization(config); + + /* Set baud divisor */ + + putreg16((uint16_t)baud, config->base + SAM_USART_BAUD_OFFSET); + + /* Configure the USART CTRLA and CTRLB registers */ + + ctrla = (USART_CTRLA_MODE_INTUSART | (uint32_t)config->muxconfig | + USART_CTRLA_ASYNCH | USART_CTRLA_CPOL_NORMAL | + USART_CTRLA_LSBFIRST); + ctrlb = (USART_CTRLB_TXEN | USART_CTRLB_RXEN); + + /* Set the number of stop bits */ + + if (config->stopbits2) + { + ctrlb |= USART_CTRLB_SBMODE; + } + + /* Set the USART word size */ + + switch (config->bits) + { + case 5: + ctrlb |= USART_CTRLB_CHSIZE_5BITS; + break; + + case 6: + ctrlb |= USART_CTRLB_CHSIZE_6BITS; + break; + + case 7: + ctrlb |= USART_CTRLB_CHSIZE_7BITS; + break; + + default: + case 8: + break; + + case 9: + ctrlb |= USART_CTRLB_CHSIZE_9BITS; + break; + } + + /* Set parity mode */ + + switch (config->parity) + { + default: + case 0: /* None */ + break; + + case 1: /* Odd */ + ctrlb |= USART_CTRLB_PODD; + /* Fall through */ + + case 2: /* Even */ + ctrla |= USART_CTRLA_FORM_PARITY; + break; + } + +#if 0 /* Not supported */ + /* Set run mode during device sleep */ + + if (config->runinstandby) + { + /* Enable in sleep mode */ + + ctrla |= USART_CTRLA_RUNSTDBY; + } +#endif + + /* Wait until synchronization is complete */ + + sam_wait_synchronization(config); + + /* Write configuration to CTRLB */ + + putreg32(ctrlb, config->base + SAM_USART_CTRLB_OFFSET); + + /* Wait until synchronization is complete */ + + sam_wait_synchronization(config); + + /* Write configuration to CTRLA */ + + putreg32(ctrla, config->base + SAM_USART_CTRLA_OFFSET); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_pad_configure + * + * Description: + * Configure the SERCOM USART pads. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +static inline void +sam_pad_configure(const struct sam_usart_config_s * const config) +{ + /* Configure SERCOM pads */ + + if (config->pad0 != 0) + { + sam_configport(config->pad0); + } + + if (config->pad1 != 0) + { + sam_configport(config->pad1); + } + + if (config->pad2 != 0) + { + sam_configport(config->pad2); + } + + if (config->pad3 != 0) + { + sam_configport(config->pad3); + } +} +#endif + +/**************************************************************************** + * Name: sam_usart_internal + * + * Description: + * Set the configuration of a SERCOM for provided USART configuration. + * This configures the SERCOM as a USART, but does not configure USART + * interrupts or enable the USART. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +int sam_usart_internal(const struct sam_usart_config_s * const config) +{ +#ifdef CONFIG_ARCH_FAMILY_SAML21 + int channel; +#endif + int ret; + + /* Enable clocking to the SERCOM module */ + + sercom_enable(config->sercom); + + /* Configure the GCLKs for the SERCOM module */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + sercom_coreclk_configure(config->sercom, config->gclkgen, false); + +#elif defined(CONFIG_ARCH_FAMILY_SAML21) + if (config->sercom == 5) + { + channel = GCLK_CHAN_SERCOM5_CORE; + } + else + { + channel = config->sercom + GCLK_CHAN_SERCOM0_CORE; + } + + sam_gclk_chan_enable(channel, config->gclkgen); +#endif + + sercom_slowclk_configure(config->sercom, config->slowgen); + + /* Set USART configuration according to the board configuration */ + + ret = sam_usart_configure(config); + if (ret == OK) + { + /* Configure USART pins */ + + sam_pad_configure(config); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: sam_usart_enable + * + * Description: + * Enable the SERCOM USART (without enabling interrupts). + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +static inline void +sam_usart_enable(const struct sam_usart_config_s * const config) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Wait until synchronization is complete */ + + sam_wait_synchronization(config); + + /* Enable USART module */ + + regaddr = config->base + SAM_USART_CTRLA_OFFSET; + regval = getreg32(regaddr); + regval |= USART_CTRLA_ENABLE; + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization. + * + ****************************************************************************/ + +void sam_lowsetup(void) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Configure and enable the console USART */ + + VERIFY(sam_usart_internal(&g_consoleconfig)); + sam_usart_enable(&g_consoleconfig); +#endif +} + +/**************************************************************************** + * Name: sam_usart_initialize + * + * Description: + * Set the configuration of a SERCOM for provided USART configuration. + * This configures the SERCOM as a USART, but does not configure USART + * interrupts or enable the USART. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +int sam_usart_initialize(const struct sam_usart_config_s * const config) +{ + irqstate_t flags; + int ret; + + /* Reset the SERCOM so that we know that it is in its initial state */ + + flags = enter_critical_section(); + sam_usart_reset(config); + + /* Just invoke the internal implementation, but with interrupts disabled + * so that the operation is atomic. + */ + + ret = sam_usart_internal(config); + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: sam_usart_reset + * + * Description: + * Reset the USART SERCOM. This restores all SERCOM register to the + * initial state and disables the SERCOM. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +void sam_usart_reset(const struct sam_usart_config_s * const config) +{ + uintptr_t regaddr = config->base + SAM_USART_CTRLA_OFFSET; + uint32_t regval; + + /* Reset the SERCOM by setting the SWRST bit in the CTRLA register. When + * the reset completes, the SERCOM will registers will be restored to there + * initial state and the SERCOM will be disabled. + */ + + regval = getreg32(regaddr); + regval |= USART_CTRLA_SWRST; + putreg32(regval, regaddr); + + /* Wait for the reset to complete */ + + while ((getreg32(regaddr) & USART_CTRLA_SWRST) != 0); +} +#endif + +/**************************************************************************** + * Name: sam_lowputc + * + * Description: + * Output one character to the USART using a simple polling method. + * + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void sam_lowputc(uint32_t ch) +{ + uintptr_t base = g_consoleconfig.base; + uintptr_t intflag = base + SAM_USART_INTFLAG_OFFSET; + + /* Wait for the USART to be ready for new TX data */ + + while ((getreg8(intflag) & USART_INT_DRE) == 0); + + /* Wait until synchronization is complete */ + + sam_wait_synchronization(&g_consoleconfig); + + /* Write data to USART module */ + + putreg16((uint16_t)ch, base + SAM_USART_DATA_OFFSET); + + /* Wait until data is sent */ + + while ((getreg8(intflag) & USART_INT_TXC) == 0); +} +#endif diff --git a/arch/arm/src/samdl/sam_lowputc.h b/arch/arm/src/samdl/sam_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..a553c89ac95a6f442bf59fb98ca2b37160335e28 --- /dev/null +++ b/arch/arm/src/samdl/sam_lowputc.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_lowputc.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_LOWPUTC_H +#define __ARCH_ARM_SRC_SAMDL_SAM_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "sam_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization. + * + ****************************************************************************/ + +void sam_lowsetup(void); + +/**************************************************************************** + * Name: sam_usart_initialize + * + * Description: + * Set the configuration of a SERCOM for provided USART configuration. + * This configures the SERCOM as a USART, but does not configure USART + * interrupts or enable the USART. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +struct sam_usart_config_s; +int sam_usart_initialize(const struct sam_usart_config_s * const config); +#endif + +/**************************************************************************** + * Name: sam_usart_reset + * + * Description: + * Reset the USART SERCOM. This restores all SERCOM register to the + * initial state and disables the SERCOM. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART +struct sam_usart_config_s; +void sam_usart_reset(const struct sam_usart_config_s * const config); +#endif + +/**************************************************************************** + * Name: sam_lowputc + * + * Description: + * Output one character to the USART using a simple polling method. + * + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void sam_lowputc(uint32_t ch); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_LOWPUTC_H */ diff --git a/arch/arm/src/samdl/sam_periphclks.h b/arch/arm/src/samdl/sam_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed6e84ac3c544a49460c94443423383a2ab345 --- /dev/null +++ b/arch/arm/src/samdl/sam_periphclks.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMDL_SAM_PERIPHCLKS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "samd_periphclks.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "saml_periphclks.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_PERIPHCLKS_H */ diff --git a/arch/arm/src/samdl/sam_pinmap.h b/arch/arm/src/samdl/sam_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..560d68ee9f96e62ab371cacef4cb9a72e53d715b --- /dev/null +++ b/arch/arm/src/samdl/sam_pinmap.h @@ -0,0 +1,55 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_pinmap.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_PINMAP_H +#define __ARCH_ARM_SRC_SAMDL_SAM_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) +# include "chip/samd20_pinmap.h" +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd21_pinmap.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml21_pinmap.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_PINMAP_H */ diff --git a/arch/arm/src/samdl/sam_pm.h b/arch/arm/src/samdl/sam_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..b7953b2ed18e5ca46ef62ec327f5d5448bdc25d2 --- /dev/null +++ b/arch/arm/src/samdl/sam_pm.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_pm.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_PM_H +#define __ARCH_ARM_SRC_SAMDL_SAM_PM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_pm.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_pm.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_PM_H */ diff --git a/arch/arm/src/samdl/sam_port.c b/arch/arm/src/samdl/sam_port.c new file mode 100644 index 0000000000000000000000000000000000000000..53c8664efdf97d96710f7312521b6c14b2cfb472 --- /dev/null +++ b/arch/arm/src/samdl/sam_port.c @@ -0,0 +1,560 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_port.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_port.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_PORT +static const char g_portchar[2] = { 'A', 'B' }; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sam_portbase + * + * Description: + * Return the base address of the PORT register set + * + ****************************************************************************/ + +static inline uintptr_t sam_portbase(port_pinset_t pinset) +{ + int port = (pinset & PORT_MASK) >> PORT_SHIFT; + return SAM_PORTN_BASE(port); +} + +/**************************************************************************** + * Name: sam_portpin + * + * Description: + * Return the bit associated with the pin + * + ****************************************************************************/ + +static inline int sam_portpin(port_pinset_t pinset) +{ + return 1 << ((pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a PORT input pin based on bit-encoded description of the pin. + * This function serves the dual role of putting all pins into a known, + * initial state. Hence, it is overkill for what really needs to be done. + * + * Assumption: + * sam_configreset has been called to put the pin into the default reset + * state. + * + ****************************************************************************/ + +static inline void sam_configinput(uintptr_t base, port_pinset_t pinset) +{ + uint32_t regval; + uint32_t bit; + int pin; + + /* Decode pin information */ + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + bit = (1 << pin); + + /* Direction bit is already zero (input) */ + /* Enable the I/O synchronizer? */ + + if ((pinset & PORT_SYNCHRONIZER_MASK) == PORT_SYNCHRONIZER_ON) + { + regval = getreg32(base + SAM_PORT_CTRL_OFFSET); + regval |= bit; + putreg32(regval, base + SAM_PORT_CTRL_OFFSET); + } + + /* Set the pin configuration */ + + regval = (PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_INEN); + if (pin > 16) + { + /* Select the upper half word and adjust the bit setting */ + + regval |= PORT_WRCONFIG_HWSEL; + pin -= 16; + } + + regval |= PORT_WRCONFIG_PINMASK(pin); + + /* Check for pull-up/down selection */ + + switch (pinset & PORT_PULL_MASK) + { + case PORT_PULL_UP: + { + /* Select pull-up by setting the corresponding bit in OUT + * register. + */ + + putreg32(bit, base + SAM_PORT_OUTSET_OFFSET); + } + /* Fall through */ + + case PORT_PULL_DOWN: + { + regval |= PORT_WRCONFIG_PULLEN; + } + break; + + default: + case PORT_PULL_NONE: + break; + } + + /* Configure the pin as an input */ + + putreg32(regval, base + SAM_PORT_WRCONFIG_OFFSET); +} + +/**************************************************************************** + * Name: sam_configinterrupt + * + * Description: + * Configure a PORT interrupt pin based on bit-encoded description of the + * pin. + * + * Assumption: + * sam_configreset has been called to put the pin into the default reset + * state: + * + ****************************************************************************/ + +static inline void sam_configinterrupt(uintptr_t base, port_pinset_t pinset) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a PORT output pin based on bit-encoded description of the pin. + * + * Assumption: + * sam_configreset has been called to put the pin into the default reset + * state. + * + ****************************************************************************/ + +static inline void sam_configoutput(uintptr_t base, port_pinset_t pinset) +{ + uint32_t regval; + uint32_t bit; + int pin; + + /* Decode pin information */ + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + bit = (1 << pin); + + /* Set the direction bit to configure the pin as an input */ + + putreg32(bit, base + SAM_PORT_DIRSET_OFFSET); + + /* Set the initial output value to high? */ + + if ((pinset & PORT_OUTVALUE_MASK) == PORT_OUTPUT_SET) + { + putreg32(bit, base + SAM_PORT_OUTSET_OFFSET); + } + + /* Set the pin configuration. This will be an output with the input + * buffer enabled. + */ + + regval = (PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_INEN); + if (pin > 16) + { + /* Select the upper half word and adjust the bit setting */ + + regval |= PORT_WRCONFIG_HWSEL; + pin -= 16; + } + + regval |= PORT_WRCONFIG_PINMASK(pin); + + /* Check for pull-up/down selection */ + + switch (pinset & PORT_PULL_MASK) + { + case PORT_PULL_UP: + { + /* Select pull-up by setting the corresponding bit in OUT + * register. + */ + + putreg32(bit, base + SAM_PORT_OUTSET_OFFSET); + } + /* Fall through */ + + case PORT_PULL_DOWN: + { + regval |= PORT_WRCONFIG_PULLEN; + } + break; + + default: + case PORT_PULL_NONE: + break; + } + + /* Select higher strength drive? */ + + if ((pinset & PORT_DRIVE_MASK) == PORT_DRIVE_HIGH) + { + regval |= PORT_WRCONFIG_DRVSTR; + } + + /* Configure the pin as an output */ + + putreg32(regval, base + SAM_PORT_WRCONFIG_OFFSET); +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a PORT pin driven by a peripheral based on bit-encoded + * description of the pin. + * + * Assumption: + * sam_configreset has been called to put the pin into the default reset + * state. + * + ****************************************************************************/ + +static inline void sam_configperiph(uintptr_t base, port_pinset_t pinset) +{ + uint32_t regval; + uint32_t bit; + uint32_t func; + int pin; + + /* Decode pin information */ + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + bit = (1 << pin); + + /* If pin is output with readback then set the pin as output */ + + if ((pinset & PORT_OUTREADBACK_MASK) == PORT_OUTREADBACK_ENABLE) + { + putreg32(bit, base + SAM_PORT_DIRSET_OFFSET); + } + + /* Set the pin configuration. This will be an peripheral with the + * selected function. + */ + + regval = (PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PMUXEN); + + /* If pin is output with readback then enable the input buffer */ + + if ((pinset & PORT_OUTREADBACK_MASK) == PORT_OUTREADBACK_ENABLE) + { + regval |= PORT_WRCONFIG_INEN; + } + + if (pin >= 16) + { + /* Select the upper half word and adjust the bit setting */ + + regval |= PORT_WRCONFIG_HWSEL; + pin -= 16; + } + + regval |= PORT_WRCONFIG_PINMASK(pin); + + /* Set the pin function */ + + func = (pinset & PORT_FUNC_MASK) >> PORT_FUNC_SHIFT; + regval |= (func << PORT_WRCONFIG_PMUX_SHIFT); + + /* Check for pull-up/down selection */ + + switch (pinset & PORT_PULL_MASK) + { + case PORT_PULL_UP: + { + /* Select pull-up by setting the corresponding bit in OUT + * register. + */ + + putreg32(bit, base + SAM_PORT_OUTSET_OFFSET); + } + /* Fall through */ + + case PORT_PULL_DOWN: + { + regval |= PORT_WRCONFIG_PULLEN; + } + break; + + default: + case PORT_PULL_NONE: + break; + } + + /* Configure the pin for the peripheral function */ + + putreg32(regval, base + SAM_PORT_WRCONFIG_OFFSET); +} + +/**************************************************************************** + * Name: sam_configreset + * + * Description: + * Configure a PORT pin in the default, reset state. + * + ****************************************************************************/ + +static inline void sam_configreset(uintptr_t base, port_pinset_t pinset) +{ + uint32_t regval; + uint32_t bit; + int pin; + + /* Decode pin information */ + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + bit = (1 << pin); + + /* Set the direction bit to zero (input) */ + + putreg32(bit, base + SAM_PORT_DIRCLR_OFFSET); + + /* Disable the I/O synchronizer */ + + regval = getreg32(base + SAM_PORT_CTRL_OFFSET); + regval &= ~bit; + putreg32(regval, base + SAM_PORT_CTRL_OFFSET); + + /* Assume input pull-down or output value low */ + + putreg32(bit, base + SAM_PORT_OUTCLR_OFFSET); + + /* Set the pin configuration */ + + regval = (PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX); + if (pin > 16) + { + /* Select the upper half word and adjust the bit setting */ + + regval |= PORT_WRCONFIG_HWSEL; + pin -= 16; + } + + regval |= PORT_WRCONFIG_PINMASK(pin); + + /* Disable the peripheral multiplexor, disable the input, disable + * pull-up/down, reset driver strength, etc. + */ + + putreg32(regval, base + SAM_PORT_WRCONFIG_OFFSET); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configport + * + * Description: + * Configure a PORT pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configport(port_pinset_t pinset) +{ + uintptr_t base = sam_portbase(pinset); + irqstate_t flags; + + /* Make sure that all operations on the port are atomic */ + + flags = enter_critical_section(); + + /* Put the PORT in the known, reset state. */ + + sam_configreset(base, pinset); + + /* Then put the PORT into the requested state */ + + switch (pinset & PORT_MODE_MASK) + { + case PORT_INPUT: + sam_configinput(base, pinset); + break; + + case PORT_OUTPUT: + sam_configoutput(base, pinset); + break; + + case PORT_PERIPHERAL: + sam_configperiph(base, pinset); + break; + + case PORT_INTERRUPT: + sam_configinterrupt(base, pinset); + break; + + default: + break; + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_portwrite + * + * Description: + * Write one or zero to the selected PORT pin + * + ****************************************************************************/ + +void sam_portwrite(port_pinset_t pinset, bool value) +{ + uintptr_t base = sam_portbase(pinset); + uint32_t pin = sam_portpin(pinset); + + if (value) + { + putreg32(pin, base + SAM_PORT_OUTSET_OFFSET); + } + else + { + putreg32(pin, base + SAM_PORT_OUTCLR_OFFSET); + } +} + +/**************************************************************************** + * Name: sam_portread + * + * Description: + * Read one or zero from the selected PORT pin + * + ****************************************************************************/ + +bool sam_portread(port_pinset_t pinset) +{ + uintptr_t base = sam_portbase(pinset); + uint32_t pin = sam_portpin(pinset); + + return (getreg32(base + SAM_PORT_IN_OFFSET) & pin) != 0; +} + +/************************************************************************************ + * Function: sam_dumpport + * + * Description: + * Dump all PORT registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_PORT +int sam_dumpport(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int pin; + unsigned int port; + + /* Get the base address associated with the PIO port */ + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + port = (pinset & PORT_MASK) >> PORT_SHIFT; + base = SAM_PORTN_BASE(port); + + /* The following requires exclusive access to the PORT registers */ + + flags = enter_critical_section(); + lldbg("PORT%c pin: %d pinset: %08x base: %08x -- %s\n", + g_portchar[port], pin, pinset, base, msg); + lldbg(" DIR: %08x OUT: %08x IN: %08x\n", + getreg32(base + SAM_PORT_DIR_OFFSET), + getreg32(base + SAM_PORT_OUT_OFFSET), + getreg32(base + SAM_PORT_IN_OFFSET)); + lldbg(" CTRL: %08x WRCONFIG: %08x\n", + getreg32(base + SAM_PORT_CTRL_OFFSET), + getreg32(base + SAM_PORT_WRCONFIG_OFFSET)); + lldbg(" PMUX[%08x]: %02x PINCFG[%08x]: %02x\n", + base + SAM_PORT_PMUX_OFFSET(pin), + getreg8(base + SAM_PORT_PMUX_OFFSET(pin)), + base + SAM_PORT_PINCFG_OFFSET(pin), + getreg8(base + SAM_PORT_PINCFG_OFFSET(pin))); + + leave_critical_section(flags); + return OK; +} +#endif + diff --git a/arch/arm/src/samdl/sam_port.h b/arch/arm/src/samdl/sam_port.h new file mode 100644 index 0000000000000000000000000000000000000000..26ba8bcb5d3562617a54ab2552d2cc20cba4a2f1 --- /dev/null +++ b/arch/arm/src/samdl/sam_port.h @@ -0,0 +1,394 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_port.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_PORT_H +#define __ARCH_ARM_SRC_SAMDL_SAM_PORT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_port.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_port.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +/* Bit-encoded input to sam_configport() */ + +/* 24-bit Encoding. This could be compacted into 16-bits by making the bit usage + * mode specific. However, by giving each bit field a unique position, we handle + * bad combinations of properties safely. + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: MMRR .... .S.. .... ..PB BBBB + * PORT Output: MM.. .... D..V .... ..PB BBBB + * Peripheral: MM.. FFFO .... II.. ..PB BBBB + * ------------ ----------------------------- + * MMRR FFFO DS.V II.. ..PB BBBB + */ + +/* Input/output/peripheral mode: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: MM.. .... .... .... .... .... + * PORT Output: MM.. .... .... .... .... .... + * Peripheral: MM.. .... .... .... .... .... + */ + +#define PORT_MODE_SHIFT (22) /* Bits 22-23: PORT mode */ +#define PORT_MODE_MASK (3 << PORT_MODE_SHIFT) +# define PORT_INPUT (0 << PORT_MODE_SHIFT) /* PORT Input */ +# define PORT_OUTPUT (1 << PORT_MODE_SHIFT) /* PORT Output */ +# define PORT_PERIPHERAL (2 << PORT_MODE_SHIFT) /* Controlled by peripheral */ +# define PORT_INTERRUPT (3 << PORT_MODE_SHIFT) /* Interrupting input */ + +/* Pull-up/down resistor control for inputs + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: ..RR .... .... .... .... .... + * PORT Output: ..RR .... .... .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define PORT_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */ +#define PORT_PULL_MASK (3 << PORT_PULL_SHIFT) +# define PORT_PULL_NONE (0 << PORT_PULL_SHIFT) +# define PORT_PULL_UP (1 << PORT_PULL_SHIFT) +# define PORT_PULL_DOWN (2 << PORT_PULL_SHIFT) + +/* Peripheral Function + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... .... .... .... .... + * Peripheral: .... FFF. .... .... .... .... + */ + +#define PORT_FUNC_SHIFT (17) /* Bits 17-19: Peripheral function */ +#define PORT_FUNC_MASK (7 << PORT_FUNC_SHIFT) +# define _PORT_FUNCA (0 << PORT_FUNC_SHIFT) /* Function A */ +# define _PORT_FUNCB (1 << PORT_FUNC_SHIFT) /* Function B */ +# define _PORT_FUNCC (2 << PORT_FUNC_SHIFT) /* Function C */ +# define _PORT_FUNCD (3 << PORT_FUNC_SHIFT) /* Function D */ +# define _PORT_FUNCE (4 << PORT_FUNC_SHIFT) /* Function E */ +# define _PORT_FUNCF (5 << PORT_FUNC_SHIFT) /* Function F */ +# define _PORT_FUNCG (6 << PORT_FUNC_SHIFT) /* Function G */ +# define _PORT_FUNCH (7 << PORT_FUNC_SHIFT) /* Function H */ + +/* Extended input/output/peripheral mode: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... .... .... .... .... + * Peripheral: MM.. FFF. .... .... .... .... + */ + +#define PORT_FUNCA (PORT_PERIPHERAL | _PORT_FUNCA) /* Function A */ +#define PORT_FUNCB (PORT_PERIPHERAL | _PORT_FUNCB) /* Function B */ +#define PORT_FUNCC (PORT_PERIPHERAL | _PORT_FUNCC) /* Function C */ +#define PORT_FUNCD (PORT_PERIPHERAL | _PORT_FUNCD) /* Function D */ +#define PORT_FUNCE (PORT_PERIPHERAL | _PORT_FUNCE) /* Function E */ +#define PORT_FUNCF (PORT_PERIPHERAL | _PORT_FUNCF) /* Function F */ +#define PORT_FUNCG (PORT_PERIPHERAL | _PORT_FUNCG) /* Function G */ +#define PORT_FUNCH (PORT_PERIPHERAL | _PORT_FUNCH) /* Function H */ + +/* Output and Input Buffer both enabled to let readback + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... .... .... .... .... + * Peripheral: .... ...O .... .... .... .... + */ + +#define PORT_OUTREADBACK_SHIFT (16) /* Bit 16: Pin output and input buffer enabled */ +#define PORT_OUTREADBACK_MASK (1 << PORT_OUTREADBACK_SHIFT) +# define PORT_OUTREADBACK_DISABLE (0 << PORT_OUTREADBACK_SHIFT) +# define PORT_OUTREADBACK_ENABLE (1 << PORT_OUTREADBACK_SHIFT) + +/* Output drive control + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... D... .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define PORT_DRIVE_SHIFT (15) /* Bit 15: Interrupting input control */ +#define PORT_DRIVE_MASK (1 << PORT_INT_SHIFT) +# define PORT_DRIVE_LOW (0 << PORT_INT_SHIFT) +# define PORT_DRIVE_HIGH (1 << PORT_INT_SHIFT) + +/* Input sampling + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .S.. .... .... .... + * PORT Output: .... .... .... .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define PORT_SYNCHRONIZER_SHIFT (14) /* Bit 14: Input synchronizer input control */ +#define PORT_SYNCHRONIZER_MASK (1 << PORT_SYNCHRONIZER_SHIFT) +# define PORT_SYNCHRONIZER_OFF (0 << PORT_SYNCHRONIZER_SHIFT) +# define PORT_SYNCHRONIZER_ON (1 << PORT_SYNCHRONIZER_SHIFT) + +/* If the pin is an PORT output, then this identifies the initial output value: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... ...V .... .... .... + * Peripheral: .... .... .... .... .... .... + */ + +#define PORT_OUTVALUE_SHIFT (12) /* Bit 12: Initial value of output */ +#define PORT_OUTVALUE_MASK (1 << PORT_SYNCHRONIZER_SHIFT) +# define PORT_OUTPUT_CLEAR (0 << PORT_SYNCHRONIZER_SHIFT) +# define PORT_OUTPUT_SET (1 << PORT_SYNCHRONIZER_SHIFT) + +/* Selections for external interrupts: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... .... .... + * PORT Output: .... .... .... .... .... .... + * Peripheral: .... .... .... II.. .... .... + */ + +#define PORT_INT_SHIFT (10) /* Bits 10-11: Interrupting input control */ +#define PORT_INT_MASK (3 << PORT_INT_SHIFT) +# define PORT_INT_CHANGE (0 << PORT_INT_SHIFT) /* Pin change */ +# define PORT_INT_RISING (1 << PORT_INT_SHIFT) /* Rising edge */ +# define PORT_INT_FALLING (2 << PORT_INT_SHIFT) /* Falling edge */ + +/* This identifies the PORT port: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... ..P. .... + * PORT Output: .... .... .... .... ..P. .... + * Peripheral: .... .... .... .... ..P. .... + */ + +#define PORT_SHIFT (5) /* Bit 5: Port number */ +#define PORT_MASK (1 << PORT_SHIFT) +# define PORTA (SAM_PORTA << PORT_SHIFT) +# define PORTB (SAM_PORTB << PORT_SHIFT) + +/* This identifies the bit in the port: + * + * MODE BITFIELDS + * ------------ ----------------------------- + * 2222 1111 1111 1100 0000 0000 + * 3210 9876 5432 1098 7654 3210 + * ------------ ----------------------------- + * PORT Input: .... .... .... .... ...B BBBB + * PORT Output: .... .... .... .... ...B BBBB + * Peripheral: .... .... .... .... ...B BBBB + */ + +#define PORT_PIN_SHIFT 0 /* Bits 0-4: PORT number: 0-31 */ +#define PORT_PIN_MASK (31 << PORT_PIN_SHIFT) +#define PORT_PIN0 (0 << PORT_PIN_SHIFT) +#define PORT_PIN1 (1 << PORT_PIN_SHIFT) +#define PORT_PIN2 (2 << PORT_PIN_SHIFT) +#define PORT_PIN3 (3 << PORT_PIN_SHIFT) +#define PORT_PIN4 (4 << PORT_PIN_SHIFT) +#define PORT_PIN5 (5 << PORT_PIN_SHIFT) +#define PORT_PIN6 (6 << PORT_PIN_SHIFT) +#define PORT_PIN7 (7 << PORT_PIN_SHIFT) +#define PORT_PIN8 (8 << PORT_PIN_SHIFT) +#define PORT_PIN9 (9 << PORT_PIN_SHIFT) +#define PORT_PIN10 (10 << PORT_PIN_SHIFT) +#define PORT_PIN11 (11 << PORT_PIN_SHIFT) +#define PORT_PIN12 (12 << PORT_PIN_SHIFT) +#define PORT_PIN13 (13 << PORT_PIN_SHIFT) +#define PORT_PIN14 (14 << PORT_PIN_SHIFT) +#define PORT_PIN15 (15 << PORT_PIN_SHIFT) +#define PORT_PIN16 (16 << PORT_PIN_SHIFT) +#define PORT_PIN17 (17 << PORT_PIN_SHIFT) +#define PORT_PIN18 (18 << PORT_PIN_SHIFT) +#define PORT_PIN19 (19 << PORT_PIN_SHIFT) +#define PORT_PIN20 (20 << PORT_PIN_SHIFT) +#define PORT_PIN21 (21 << PORT_PIN_SHIFT) +#define PORT_PIN22 (22 << PORT_PIN_SHIFT) +#define PORT_PIN23 (23 << PORT_PIN_SHIFT) +#define PORT_PIN24 (24 << PORT_PIN_SHIFT) +#define PORT_PIN25 (25 << PORT_PIN_SHIFT) +#define PORT_PIN26 (26 << PORT_PIN_SHIFT) +#define PORT_PIN27 (27 << PORT_PIN_SHIFT) +#define PORT_PIN28 (28 << PORT_PIN_SHIFT) +#define PORT_PIN29 (29 << PORT_PIN_SHIFT) +#define PORT_PIN30 (30 << PORT_PIN_SHIFT) +#define PORT_PIN31 (31 << PORT_PIN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef uint32_t port_pinset_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configport + * + * Description: + * Configure a PORT pin based on bit-encoded description of the pin. + * + * Returns: + * OK (always) + * + ****************************************************************************/ + +int sam_configport(port_pinset_t pinset); + +/**************************************************************************** + * Name: sam_portwrite + * + * Description: + * Write one or zero to the selected PORT pin + * + ****************************************************************************/ + +void sam_portwrite(port_pinset_t pinset, bool value); + +/**************************************************************************** + * Name: sam_portread + * + * Description: + * Read one or zero from the selected PORT pin + * + ****************************************************************************/ + +bool sam_portread(port_pinset_t pinset); + +/**************************************************************************** + * Function: sam_dumpport + * + * Description: + * Dump all PORT registers associated with the provided pin description + * along with a descriptive message. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +int sam_dumpport(port_pinset_t pinset, const char *msg); +#else +# define sam_dumpport(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_PORT_H */ diff --git a/arch/arm/src/samdl/sam_sercom.c b/arch/arm/src/samdl/sam_sercom.c new file mode 100644 index 0000000000000000000000000000000000000000..ae50ca39c1e3a779a2d481782f713a60517951ea --- /dev/null +++ b/arch/arm/src/samdl/sam_sercom.c @@ -0,0 +1,312 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_sercom.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "sam_config.h" + +#include "sam_pm.h" +#include "sam_gclk.h" +#include "sam_sercom.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef HAVE_SERCOM0_4 +#if defined(CONFIG_SAMDL_SERCOM0) || defined(CONFIG_SAMDL_SERCOM1) || \ + defined(CONFIG_SAMDL_SERCOM2) || defined(CONFIG_SAMDL_SERCOM3) || \ + defined(CONFIG_SAMDL_SERCOM4) +# define HAVE_SERCOM0_4 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sercom_coreclk_configure + * + * Description: + * Configure the SERCOM core source clock. + * + * Two generic clocks are used by the SERCOM: GCLK_SERCOMx_CORE and + * GCLK_SERCOM_SLOW. The core clock (GCLK_SERCOMx_CORE) is required to + * clock the SERCOM while operating as a master, while the slow clock + * (GCLK_SERCOM_SLOW) is only required for certain functions. SERCOM + * modules must share the same slow GCLK channel ID. + * + * The baud-rate generator runs off the GCLK_SERCOMx_CORE clock (or, + * optionally, external clock). + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock) +{ + uint16_t regval; + uint8_t gclkcore; + + /* Set up the SERCOMn_GCLK_ID_CORE clock */ + + gclkcore = (uint8_t)SERCOM_GCLK_ID_CORE(sercom); + regval = ((uint16_t)gclkcore << GCLK_CLKCTRL_ID_SHIFT); + + /* Select and disable the SERCOMn_GCLK_ID_CORE generic clock */ + + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Wait for clock to become disabled */ + + while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); + + /* Select the SERCOMn_GCLK_ID_CORE source clock generator */ + + regval |= (uint16_t)gclkgen << GCLK_CLKCTRL_GEN_SHIFT; + + /* Write the new configuration */ + + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Enable the SERCOMn_GCLK_ID_CORE generic clock, optionally locking + * further writes to this GCLK. + */ + + regval |= GCLK_CLKCTRL_CLKEN; + + if (wrlock) + { + regval |= GCLK_CLKCTRL_WRTLOCK; + } + + putreg16(regval, SAM_GCLK_CLKCTRL); +} +#endif + +/**************************************************************************** + * Name: sercom_slowclk_configure + * + * Description: + * Configure the SERCOM slow source clock. + * + * Two generic clocks are used by the SERCOM: GCLK_SERCOMx_CORE and + * GCLK_SERCOM_SLOW. The core clock (GCLK_SERCOMx_CORE) is required to + * clock the SERCOM while operating as a master, while the slow clock + * (GCLK_SERCOM_SLOW) is only required for certain functions. SERCOM + * modules must share the same slow GCLK channel ID. + * + ****************************************************************************/ + +void sercom_slowclk_configure(int sercom, int gclkgen) +{ +#if defined(CONFIG_ARCH_FAMILY_SAML21) +#ifdef HAVE_SERCOM0_4 + static bool configured = false; +#endif +#ifdef CONFIG_SAMDL_SERCOM5 + static bool configured5 = false; +#endif +#ifdef CONFIG_DEBUG +#ifdef HAVE_SERCOM0_4 + static uint8_t slowgen = 0xff; +#endif +#ifdef CONFIG_SAMDL_SERCOM5 + static uint8_t slowgen5 = 0xff; +#endif +#endif + + /* Setup the SERCOMn_GCLK channel. SERCOM0-4 use a common channel, but + * SERCOM5 uses a different channel. Configuration should be done only + * once. + */ + + switch (sercom) + { +#ifdef HAVE_SERCOM0_4 +#ifdef CONFIG_SAMDL_SERCOM0 + case 0: +#endif +#ifdef CONFIG_SAMDL_SERCOM1 + case 1: +#endif +#ifdef CONFIG_SAMDL_SERCOM2 + case 2: +#endif +#ifdef CONFIG_SAMDL_SERCOM3 + case 3: +#endif +#ifdef CONFIG_SAMDL_SERCOM4 + case 4: +#endif + if (!configured) + { + /* Configure the common slow clock channel */ + + sam_gclk_chan_enable(GCLK_CHAN_SERCOM0_SLOW, gclkgen); + + /* The slow clock is now configured and should not be configured + * again. + */ + + configured = true; +#ifdef CONFIG_DEBUG + slowgen = (uint8_t)gclkgen; +#endif + } + +#ifdef CONFIG_DEBUG + /* Already configured. This is okay provided that the same GCLK + * generator is being used. Otherwise, there is a problem. + */ + + else + { + DEBUGASSERT((int)slowgen == gclkgen); + } +#endif + break; +#endif /* HAVE_SERCOM0_4 */ + +#ifdef CONFIG_SAMDL_SERCOM5 + case 5: + if (!configured5) + { + /* Configure the common slow clock channel */ + + sam_gclk_chan_enable(GCLK_CHAN_SERCOM5_SLOW, gclkgen); + + /* The slow clock is now configured and should not be configured + * again. + */ + + configured5 = true; +#ifdef CONFIG_DEBUG + slowgen5 = (uint8_t)gclkgen; +#endif + } + +#ifdef CONFIG_DEBUG + /* Already configured. This is okay provided that the same GCLK + * generator is being used. Otherwise, there is a problem. + */ + + else + { + DEBUGASSERT((int)slowgen5 == gclkgen); + } +#endif + break; +#endif /* CONFIG_SAMDL_SERCOM5 */ + + /* Unsupported or invalid SERCOM number provided */ + + default: + DEBUGPANIC(); + break; + } + +#elif defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + static bool configured = false; + uint16_t regval; + + /* Since GCLK_SERCOM_SLOW is shared amongst all SERCOM modules, it should + * only be configured one time. + */ + + if (!configured) + { + /* Set up the SERCOM_GCLK_ID_SLOW clock */ + + regval = (SERCOM_GCLK_ID_SLOW << GCLK_CLKCTRL_ID_SHIFT); + + /* Select and disable the SERCOM_GCLK_ID_SLOW generic clock */ + + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Wait for clock to become disabled */ + + while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); + + /* Select the SERCOM_GCLK_ID_SLOW clock source generator */ + + regval |= (uint16_t)gclkgen << GCLK_CLKCTRL_GEN_SHIFT; + + /* Write the new configuration */ + + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Enable the GCLK_SERCOM_SLOW generic clock and lock further + * writes to this GCLK. When this bit is written, it will lock + * further writes to the generic clock pointed by the CLKCTRL.ID. The + * generic clock generator pointed by CLKCTRL.GEN and the GENDIV.DIV + * will also be locked. + * + * We lock the SERCOM slow clock because it is common to all SERCOM modules + * and, once set, should not be changed again. + */ + + regval |= (/* GCLK_CLKCTRL_WRTLOCK | */ GCLK_CLKCTRL_CLKEN); + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Now we are configured */ + + configured = true; + } +#endif +} diff --git a/arch/arm/src/samdl/sam_sercom.h b/arch/arm/src/samdl/sam_sercom.h new file mode 100644 index 0000000000000000000000000000000000000000..8d000726938cda2fba85712f899b9a42fab356b6 --- /dev/null +++ b/arch/arm/src/samdl/sam_sercom.h @@ -0,0 +1,158 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_sercom.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_SERCOM_H +#define __ARCH_ARM_SRC_SAMDL_SAM_SERCOM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "sam_config.h" +#include "sam_periphclks.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_sercom.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_sercom.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sercom_enable + * + * Description: + * Enable clocking to a SERCOM module + * + * Assumptions/Limitation: + * This operation is global and atomic. Interrupts will be masked. + * + ****************************************************************************/ + +static inline void sercom_enable(int sercom) +{ +#ifdef SAMDL_HAVE_SERCOM5 + /* SERCOM5 is a special case */ + + if (sercom == 5) + { + sam_sercom5_enableperiph(); + } + else +#endif + { + sam_sercom_enableperiph(sercom); + } +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sercom_coreclk_configure + * + * Description: + * Configure the SERCOM core source clock. + * + * Two generic clocks are used by the SERCOM: GCLK_SERCOMx_CORE and + * GCLK_SERCOMx_SLOW. The core clock (GCLK_SERCOMx_CORE) is required to + * clock the SERCOM while operating as a master, while the slow clock + * (GCLK_SERCOM_SLOW) is only required for certain functions. SERCOM + * modules must share the same slow GCLK channel ID. + * + * The baud-rate generator runs off the GCLK_SERCOMx_CORE clock (or, + * optionally, external clock). + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +void sercom_coreclk_configure(int sercom, int gclkgen, bool wrlock); +#endif + +/**************************************************************************** + * Name: sercom_slowclk_configure + * + * Description: + * Configure the SERCOM slow source clock. + * + * Two generic clocks are used by the SERCOM: GCLK_SERCOMx_CORE and + * GCLK_SERCOMx_SLOW. The core clock (GCLK_SERCOMx_CORE) is required to + * clock the SERCOM while operating as a master, while the slow clock + * (GCLK_SERCOM_SLOW) is only required for certain functions. SERCOM + * modules must share the same slow GCLK channel ID. + * + ****************************************************************************/ + +void sercom_slowclk_configure(int sercom, int gclkgen); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_SERCOM_H */ diff --git a/arch/arm/src/samdl/sam_serial.c b/arch/arm/src/samdl/sam_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..ac94f694acf05153a44f7be1e754f071983f453c --- /dev/null +++ b/arch/arm/src/samdl/sam_serial.c @@ -0,0 +1,1087 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_serial.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "sam_config.h" +#include "sam_usart.h" +#include "sam_lowputc.h" +#include "sam_serial.h" + +#ifdef SAMDL_HAVE_USART + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which USART with be tty0/console and which tty1? tty2? tty3? tty4? tty5? */ + +/* First pick the console and ttys0. This could be any of USART0-5 */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart3port /* USART3 is console */ +# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */ +# define USART3_ASSIGNED 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart4port /* USART4 is console */ +# define TTYS0_DEV g_usart4port /* USART4 is ttyS0 */ +# define USART4_ASSIGNED 1 +#elif defined(CONFIG_USART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart5port /* USART5 is console */ +# define TTYS5_DEV g_usart5port /* USART5 is ttyS0 */ +#else +# undef CONSOLE_DEV /* No console */ +# if defined(SAMDL_HAVE_USART0) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +# elif defined(SAMDL_HAVE_USART1) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +# elif defined(SAMDL_HAVE_USART2) +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +# elif defined(SAMDL_HAVE_USART3) +# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */ +# define USART3_ASSIGNED 1 +# elif defined(SAMDL_HAVE_USART4) +# define TTYS0_DEV g_usart4port /* USART4 is ttyS0 */ +# define USART4_ASSIGNED 1 +# elif defined(SAMDL_HAVE_USART5) +# define TTYS0_DEV g_usart5port /* USART5 is ttyS0 */ +# define USART5_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of USART0-5 excluding the console USART. */ + +#if defined(SAMDL_HAVE_USART0) && !defined(USART0_ASSIGNED) +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# define USART0_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART1) && !defined(USART1_ASSIGNED) +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# define USART1_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART2) && !defined(USART2_ASSIGNED) +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# define USART2_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART3) && !defined(USART3_ASSIGNED) +# define TTYS1_DEV g_usart3port /* USART3 is ttyS1 */ +# define USART3_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART4) && !defined(USART4_ASSIGNED) +# define TTYS1_DEV g_usart4port /* USART4 is ttyS1 */ +# define USART4_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART5) && !defined(USART5_ASSIGNED) +# define TTYS1_DEV g_usart5port /* USART5 is ttyS1 */ +# define USART5_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of USART1-5. It can't be USART0 + * because that was either assigned as ttyS0 or ttys1. One of these + * could also be the console. + */ + +#if defined(SAMDL_HAVE_USART1) && !defined(USART1_ASSIGNED) +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# define USART1_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART2) && !defined(USART2_ASSIGNED) +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# define USART2_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART3) && !defined(USART3_ASSIGNED) +# define TTYS2_DEV g_usart3port /* USART3 is ttyS2 */ +# define USART3_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART4) && !defined(USART4_ASSIGNED) +# define TTYS2_DEV g_usart4port /* USART4 is ttyS2 */ +# define USART4_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART5) && !defined(USART5_ASSIGNED) +# define TTYS2_DEV g_usart5port /* USART5 is ttyS2 */ +# define USART5_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of USART2-5. It can't be USART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * USART2-5 could also be the console. + */ + +#if defined(SAMDL_HAVE_USART2) && !defined(USART2_ASSIGNED) +# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */ +# define USART2_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART3) && !defined(USART3_ASSIGNED) +# define TTYS3_DEV g_usart3port /* USART3 is ttyS3 */ +# define USART3_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART4) && !defined(USART4_ASSIGNED) +# define TTYS3_DEV g_usart4port /* USART4 is ttyS3 */ +# define USART4_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART5) && !defined(USART5_ASSIGNED) +# define TTYS3_DEV g_usart5port /* USART5 is ttyS3 */ +# define USART5_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of USART3-5. It can't be USART0-2 + * because those have already been assigned to ttsyS0, 1, 2 or 3. One of + * USART3-5 could also be the console. + */ + +#if defined(SAMDL_HAVE_USART3) && !defined(USART3_ASSIGNED) +# define TTYS4_DEV g_usart3port /* USART3 is ttyS4 */ +# define USART3_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART4) && !defined(USART4_ASSIGNED) +# define TTYS4_DEV g_usart4port /* USART4 is ttyS4 */ +# define USART4_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART5) && !defined(USART5_ASSIGNED) +# define TTYS4_DEV g_usart5port /* USART5 is ttyS4 */ +# define USART5_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of USART4-5. It can't be USART0-3 + * because those have already been assigned to ttsyS0, 1, 2, 3 or 4. + * One of USART4-5 could also be the console. + */ + +#if defined(SAMDL_HAVE_USART4) && !defined(USART4_ASSIGNED) +# define TTYS5_DEV g_usart4port /* USART4 is ttyS5 */ +# define USART4_ASSIGNED 1 +#elif defined(SAMDL_HAVE_USART5) && !defined(USART5_ASSIGNED) +# define TTYS5_DEV g_usart5port /* USART5 is ttyS5 */ +# define USART5_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sam_dev_s +{ + /* Common USART configuration */ + + const struct sam_usart_config_s * const config; + + /* Information unique to the serial driver */ + + xcpt_t handler; /* Interrupt handler */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Support functions */ + +static inline uint8_t + sam_serialin8(struct sam_dev_s *priv, int offset); +static inline void + sam_serialout8(struct sam_dev_s *priv, int offset, + uint8_t regval); +static inline uint16_t + sam_serialin16(struct sam_dev_s *priv, int offset); +static inline void + sam_serialout16(struct sam_dev_s *priv, int offset, + uint16_t regval); +static void sam_disableallints(struct sam_dev_s *priv); +static int sam_interrupt(struct uart_dev_s *dev); + +#ifdef SAMDL_HAVE_USART0 +static int sam_usart0_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_USART1 +static int sam_usart1_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_USART2 +static int sam_usart2_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_USART3 +static int sam_usart3_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_USART4 +static int sam_usart4_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_USART5 +static int sam_usart5_interrupt(int irq, void *context); +#endif + +/* UART methods */ + +static int sam_setup(struct uart_dev_s *dev); +static void sam_shutdown(struct uart_dev_s *dev); +static int sam_attach(struct uart_dev_s *dev); +static void sam_detach(struct uart_dev_s *dev); +static int sam_ioctl(struct file *filep, int cmd, unsigned long arg); +static int sam_receive(struct uart_dev_s *dev, uint32_t *status); +static void sam_rxint(struct uart_dev_s *dev, bool enable); +static bool sam_rxavailable(struct uart_dev_s *dev); +static void sam_send(struct uart_dev_s *dev, int ch); +static void sam_txint(struct uart_dev_s *dev, bool enable); +static bool sam_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = sam_setup, + .shutdown = sam_shutdown, + .attach = sam_attach, + .detach = sam_detach, + .ioctl = sam_ioctl, + .receive = sam_receive, + .rxint = sam_rxint, + .rxavailable = sam_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = sam_send, + .txint = sam_txint, + .txready = sam_txempty, + .txempty = sam_txempty, +}; + +/* I/O buffers */ + +#ifdef SAMDL_HAVE_USART0 +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef SAMDL_HAVE_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef SAMDL_HAVE_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif +#ifdef SAMDL_HAVE_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif +#ifdef SAMDL_HAVE_USART4 +static char g_usart4rxbuffer[CONFIG_USART4_RXBUFSIZE]; +static char g_usart4txbuffer[CONFIG_USART4_TXBUFSIZE]; +#endif +#ifdef SAMDL_HAVE_USART5 +static char g_usart5rxbuffer[CONFIG_USART5_RXBUFSIZE]; +static char g_usart5txbuffer[CONFIG_USART5_TXBUFSIZE]; +#endif + +/* This describes the state of the USART0 port. */ + +#ifdef SAMDL_HAVE_USART0 +static struct sam_dev_s g_usart0priv = +{ + .config = &g_usart0config, + .handler = sam_usart0_interrupt, +}; + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the USART1 port. */ + +#ifdef SAMDL_HAVE_USART1 +static struct sam_dev_s g_usart1priv = +{ + .config = &g_usart1config, + .handler = sam_usart1_interrupt, +}; + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the USART2 port. */ + +#ifdef SAMDL_HAVE_USART2 +static struct sam_dev_s g_usart2priv = +{ + .config = &g_usart2config, + .handler = sam_usart2_interrupt, +}; + +static uart_dev_t g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/* This describes the state of the USART3 port. */ + +#ifdef SAMDL_HAVE_USART3 +static struct sam_dev_s g_usart3priv = +{ + .config = &g_usart3config, + .handler = sam_usart3_interrupt, +}; + +static uart_dev_t g_usart3port = +{ + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart3priv, +}; +#endif + +/* This describes the state of the USART4 port. */ + +#ifdef SAMDL_HAVE_USART4 +static struct sam_dev_s g_usart4priv = +{ + .config = &g_usart4config, + .handler = sam_usart4_interrupt, +}; + +static uart_dev_t g_usart4port = +{ + .recv = + { + .size = CONFIG_USART4_RXBUFSIZE, + .buffer = g_usart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART4_TXBUFSIZE, + .buffer = g_usart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart4priv, +}; +#endif + +/* This describes the state of the USART5 port. */ + +#ifdef SAMDL_HAVE_USART5 +static struct sam_dev_s g_usart5priv = +{ + .config = &g_usart5config, + .handler = sam_usart5_interrupt, +}; + +static uart_dev_t g_usart5port = +{ + .recv = + { + .size = CONFIG_USART5_RXBUFSIZE, + .buffer = g_usart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART5_TXBUFSIZE, + .buffer = g_usart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart5priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_serialin8 + ****************************************************************************/ + +static inline uint8_t sam_serialin8(struct sam_dev_s *priv, int offset) +{ + return getreg8(priv->config->base + offset); +} + +/**************************************************************************** + * Name: sam_serialout8 + ****************************************************************************/ + +static inline void sam_serialout8(struct sam_dev_s *priv, int offset, + uint8_t regval) +{ + putreg8(regval, priv->config->base + offset); +} + +/**************************************************************************** + * Name: sam_serialin16 + ****************************************************************************/ + +static inline uint16_t sam_serialin16(struct sam_dev_s *priv, int offset) +{ + return getreg16(priv->config->base + offset); +} + +/**************************************************************************** + * Name: sam_serialout16 + ****************************************************************************/ + +static inline void sam_serialout16(struct sam_dev_s *priv, int offset, + uint16_t regval) +{ + putreg16(regval, priv->config->base + offset); +} + +/**************************************************************************** + * Name: sam_disableallints + ****************************************************************************/ + +static void sam_disableallints(struct sam_dev_s *priv) +{ + /* Disable all interrupts */ + + sam_serialout8(priv, SAM_USART_INTENCLR_OFFSET, USART_INT_ALL); +} + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int sam_interrupt(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + uint8_t pending; + uint8_t intflag; + uint8_t inten; + + /* Get the set of pending USART interrupts (we are only interested in the + * unmasked interrupts). + */ + + intflag = sam_serialin8(priv, SAM_USART_INTFLAG_OFFSET); + inten = sam_serialin8(priv, SAM_USART_INTENCLR_OFFSET); + pending = intflag & inten; + + /* Handle an incoming, receive byte. The RXC flag is set when there is + * unread data in DATA register. This flag is cleared by reading the DATA + * register (or by disabling the receiver). + */ + + if ((pending & USART_INT_RXC) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + } + + /* Handle outgoing, transmit bytes. The DRE flag is set when the DATA + * register is empty and ready to be written. This flag is cleared by + * writing new data to the DATA register. If there is no further data to + * be transmitted, the serial driver will disable TX interrupts, prohibit + * further interrupts until TX interrupts are re-enabled. + */ + + if ((pending & USART_INT_DRE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: sam_usartN_interrupt + * + * Description: + * Handle each SERCOM USART interrupt by calling the common interrupt + * handling logic with the USART-specific state. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART0 +static int sam_usart0_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart0port); +} +#endif + +#ifdef SAMDL_HAVE_USART1 +static int sam_usart1_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart1port); +} +#endif + +#ifdef SAMDL_HAVE_USART2 +static int sam_usart2_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart2port); +} +#endif + +#ifdef SAMDL_HAVE_USART3 +static int sam_usart3_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart3port); +} +#endif + +#ifdef SAMDL_HAVE_USART4 +static int sam_usart4_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart4port); +} +#endif + +#ifdef SAMDL_HAVE_USART5 +static int sam_usart5_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart5port); +} +#endif + +/**************************************************************************** + * Name: sam_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int sam_setup(struct uart_dev_s *dev) +{ + int ret = 0; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + /* Configure the SERCOM as a USART. Don't reconfigure the console UART; + * that was already done in sam_lowputc.c. + */ + + if (!dev->isconsole) + { + ret = sam_usart_initialize(priv->config); + } +#endif + + return ret; +} + +/**************************************************************************** + * Name: sam_shutdown + * + * Description: + * Disable the USART. This method is called when the serial port is + * closed. The exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void sam_shutdown(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + /* Resetting the SERCOM restores all registers to the reget state and + * disables the SERCOM. Ignore any requests to shutown the console + * device (shouldn't happen). + */ + + if (!dev->isconsole) + { + sam_usart_reset(priv->config); + } +} + +/**************************************************************************** + * Name: sam_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int sam_attach(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + const struct sam_usart_config_s * const config = priv->config; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(config->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(config->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void sam_detach(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + const struct sam_usart_config_s * const config = priv->config; + + /* Disable interrupts at the SERCOM device and at the NVIC */ + + sam_disableallints(priv); + up_disable_irq(config->irq); + + /* Detach the interrupt handler */ + + irq_detach(config->irq); +} + +/**************************************************************************** + * Name: sam_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int sam_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct sam_dev_s *user = (struct sam_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct sam_dev_s)); + } + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int sam_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + /* Return read status */ + + *status = (uint32_t)sam_serialin16(priv, SAM_USART_STATUS_OFFSET); + + /* Then return the actual received byte */ + + return (int)sam_serialin16(priv, SAM_USART_DATA_OFFSET); +} + +/**************************************************************************** + * Name: sam_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void sam_rxint(struct uart_dev_s *dev, bool enable) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + sam_serialout8(priv, SAM_USART_INTENSET_OFFSET, USART_INT_RXC); +#endif + } + else + { + sam_serialout8(priv, SAM_USART_INTENCLR_OFFSET, USART_INT_RXC); + } +} + +/**************************************************************************** + * Name: sam_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool sam_rxavailable(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + return ((sam_serialin8(priv, SAM_USART_INTFLAG_OFFSET) & USART_INT_RXC) != 0); +} + +/**************************************************************************** + * Name: sam_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void sam_send(struct uart_dev_s *dev, int ch) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + sam_serialout16(priv, SAM_USART_DATA_OFFSET, (uint16_t)ch); +} + +/**************************************************************************** + * Name: sam_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void sam_txint(struct uart_dev_s *dev, bool enable) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + sam_serialout8(priv, SAM_USART_INTENSET_OFFSET, USART_INT_DRE); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + +#endif + } + else + { + /* Disable the TX interrupt */ + + sam_serialout8(priv, SAM_USART_INTENCLR_OFFSET, USART_INT_DRE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool sam_txempty(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + return ((sam_serialin8(priv, SAM_USART_INTFLAG_OFFSET) & USART_INT_DRE) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before sam_serialinit. + * + * NOTE: On this platform up_earlyserialinit() does not really do + * anything of consequence and probably could be eliminated with little + * effort. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable all USARTS */ + + sam_disableallints(TTYS0_DEV.priv); +#ifdef TTYS1_DEV + sam_disableallints(TTYS1_DEV.priv); +#endif +#ifdef TTYS2_DEV + sam_disableallints(TTYS2_DEV.priv); +#endif +#ifdef TTYS3_DEV + sam_disableallints(TTYS3_DEV.priv); +#endif +#ifdef TTYS4_DEV + sam_disableallints(TTYS4_DEV.priv); +#endif +#ifdef TTYS5_DEV + sam_disableallints(TTYS5_DEV.priv); +#endif + +#ifdef HAVE_SERIAL_CONSOLE + /* Mark the serial console (if any) */ + + CONSOLE_DEV.isconsole = true; +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that sam_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + irqstate_t flags; + + /* All interrupts must be disabled to prevent re-entrancy and to prevent + * interrupts from firing in the serial driver code. + */ + + flags = enter_critical_section(); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + sam_lowputc('\r'); + } + + sam_lowputc(ch); + leave_critical_section(flags); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + sam_lowputc('\r'); + } + + sam_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ +#endif /* SAMDL_HAVE_USART */ + diff --git a/arch/arm/src/samdl/sam_serial.h b/arch/arm/src/samdl/sam_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..7c634565bb5463aa3a6cd8a4df20a168b3206868 --- /dev/null +++ b/arch/arm/src/samdl/sam_serial.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_serial.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_SERIAL_H +#define __ARCH_ARM_SRC_SAMDL_SAM_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "sam_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_SERIAL_H */ diff --git a/arch/arm/src/samdl/sam_spi.c b/arch/arm/src/samdl/sam_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..2a7df796bac1498d4ada4b8e47f25eb67f556605 --- /dev/null +++ b/arch/arm/src/samdl/sam_spi.c @@ -0,0 +1,1587 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_spi.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * References: + * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "sam_pinmap.h" +#include "sam_gclk.h" +#include "sam_port.h" +#include "sam_sercom.h" +#include "sam_spi.h" + +#include + +#ifdef SAMDL_HAVE_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* Debug *******************************************************************/ +/* Check if SPI debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_SAMDL_SPI_REGDEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the one SPI chip select */ + +struct sam_spidev_s +{ + const struct spi_ops_s *ops; /* Externally visible part of the SPI interface */ + + /* Fixed configuration */ + + uint8_t sercom; /* Identifies the SERCOM peripheral */ +#if 0 /* Not used */ + uint8_t irq; /* SERCOM IRQ number */ +#endif + uint8_t gclkgen; /* Source GCLK generator */ + uint8_t slowgen; /* Slow GCLK generator */ + port_pinset_t pad0; /* Pin configuration for PAD0 */ + port_pinset_t pad1; /* Pin configuration for PAD1 */ + port_pinset_t pad2; /* Pin configuration for PAD2 */ + port_pinset_t pad3; /* Pin configuration for PAD3 */ + uint32_t muxconfig; /* Pad multiplexing configuration */ + uint32_t srcfreq; /* Source clock frequency */ + uintptr_t base; /* SERCOM base address */ +#if 0 /* Not used */ + xcpt_t handler; /* SERCOM interrupt handler */ +#endif + + /* Dynamic configuration */ + + sem_t spilock; /* Used to managed exclusive access to the bus */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + bool wr; /* Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, + uint32_t regval, uint32_t regaddr); +#else +# define spi_checkreg(priv,wr,regval,regaddr) (false) +#endif + +static uint8_t spi_getreg8(struct sam_spidev_s *priv, + unsigned int offset); +static void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval, + unsigned int offset); +static uint16_t spi_getreg16(struct sam_spidev_s *priv, + unsigned int offset); +static void spi_putreg16(struct sam_spidev_s *priv, uint16_t regval, + unsigned int offset); +static uint32_t spi_getreg32(struct sam_spidev_s *priv, + unsigned int offset); +static void spi_putreg32(struct sam_spidev_s *priv, uint32_t regval, + unsigned int offset); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg); +#else +# define spi_dumpregs(priv,msg) +#endif + +/* Interrupt handling */ + +#if 0 /* Not used */ +static int spi_interrupt(struct sam_spidev_s *dev); + +#ifdef SAMDL_HAVE_SPI0 +static int spi0_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_SPI1 +static int spi1_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_SPI2 +static int spi2_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_SPI3 +static int spi3_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_SPI4 +static int spi4_interrupt(int irq, void *context); +#endif +#ifdef SAMDL_HAVE_SPI5 +static int spi5_interrupt(int irq, void *context); +#endif +#endif + +/* SPI methods */ + +static int spi_lock(struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch); +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, + const void *buffer, size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, + size_t nwords); +#endif + +/* Initialization */ + +static void spi_wait_synchronization(struct sam_spidev_s *priv); +static void spi_pad_configure(struct sam_spidev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef SAMDL_HAVE_SPI0 +/* SPI0 driver operations */ + +static const struct spi_ops_s g_spi0ops = +{ + .lock = spi_lock, + .select = sam_spi0select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = sam_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi0dev = +{ + .ops = &g_spi0ops, + .sercom = 0, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM0, +#endif + .gclkgen = BOARD_SERCOM0_GCLKGEN, + .slowgen = BOARD_SERCOM0_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM0_PINMAP_PAD0, + .pad1 = BOARD_SERCOM0_PINMAP_PAD1, + .pad2 = BOARD_SERCOM0_PINMAP_PAD2, + .pad3 = BOARD_SERCOM0_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM0_MUXCONFIG, + .srcfreq = BOARD_SERCOM0_FREQUENCY, + .base = SAM_SERCOM0_BASE, +#if 0 /* Not used */ + .handler = spi0_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +#ifdef SAMDL_HAVE_SPI1 +/* SPI1 driver operations */ + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = sam_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI1 controller */ + +static struct sam_spidev_s g_spi1dev = +{ + .ops = &g_spi1ops, + .sercom = 1, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM1, +#endif + .gclkgen = BOARD_SERCOM1_GCLKGEN, + .slowgen = BOARD_SERCOM1_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM1_PINMAP_PAD0, + .pad1 = BOARD_SERCOM1_PINMAP_PAD1, + .pad2 = BOARD_SERCOM1_PINMAP_PAD2, + .pad3 = BOARD_SERCOM1_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM1_MUXCONFIG, + .srcfreq = BOARD_SERCOM1_FREQUENCY, + .base = SAM_SERCOM1_BASE, +#if 0 /* Not used */ + .handler = spi1_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +#ifdef SAMDL_HAVE_SPI2 +/* SPI2 driver operations */ + +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = sam_spi0select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI2 controller */ + +static struct sam_spidev_s g_spi2dev = +{ + .ops = &g_spi1ops, + .sercom = 2, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM2, +#endif + .gclkgen = BOARD_SERCOM2_GCLKGEN, + .slowgen = BOARD_SERCOM2_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM2_PINMAP_PAD0, + .pad1 = BOARD_SERCOM2_PINMAP_PAD1, + .pad2 = BOARD_SERCOM2_PINMAP_PAD2, + .pad3 = BOARD_SERCOM2_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM2_MUXCONFIG, + .srcfreq = BOARD_SERCOM2_FREQUENCY, + .base = SAM_SERCOM2_BASE, +#if 0 /* Not used */ + .handler = spi2_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +#ifdef SAMDL_HAVE_SPI3 +/* SPI3 driver operations */ + +static const struct spi_ops_s g_spi3ops = +{ + .lock = spi_lock, + .select = sam_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI3 controller */ + +static struct sam_spidev_s g_spi3dev = +{ + .ops = &g_spi3ops, + .sercom = 3, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM3, +#endif + .gclkgen = BOARD_SERCOM3_GCLKGEN, + .slowgen = BOARD_SERCOM3_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM3_PINMAP_PAD0, + .pad1 = BOARD_SERCOM3_PINMAP_PAD1, + .pad2 = BOARD_SERCOM3_PINMAP_PAD2, + .pad3 = BOARD_SERCOM3_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM3_MUXCONFIG, + .srcfreq = BOARD_SERCOM3_FREQUENCY, + .base = SAM_SERCOM3_BASE, +#if 0 /* Not used */ + .handler = spi3_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +#ifdef SAMDL_HAVE_SPI4 +/* SPI4 driver operations */ + +static const struct spi_ops_s g_spi4ops = +{ + .lock = spi_lock, + .select = sam_spi4select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi4status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi4cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI4 controller */ + +static struct sam_spidev_s g_spi4dev = +{ + .ops = &g_spi4ops, + .sercom = 4, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM4, +#endif + .gclkgen = BOARD_SERCOM4_GCLKGEN, + .slowgen = BOARD_SERCOM4_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM4_PINMAP_PAD0, + .pad1 = BOARD_SERCOM4_PINMAP_PAD1, + .pad2 = BOARD_SERCOM4_PINMAP_PAD2, + .pad3 = BOARD_SERCOM4_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM4_MUXCONFIG, + .srcfreq = BOARD_SERCOM4_FREQUENCY, + .base = SAM_SERCOM4_BASE, +#if 0 /* Not used */ + .handler = spi4_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +#ifdef SAMDL_HAVE_SPI5 +/* SPI5 driver operations */ + +static const struct spi_ops_s g_spi5ops = +{ + .lock = spi_lock, + .select = sam_spi5select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi5status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi5cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI5 controller */ + +static struct sam_spidev_s g_spi5dev = +{ + .ops = &g_spi5ops, + .sercom = 5, +#if 0 /* Not used */ + .irq = SAM_IRQ_SERCOM5, +#endif + .gclkgen = BOARD_SERCOM5_GCLKGEN, + .slowgen = BOARD_SERCOM5_SLOW_GCLKGEN, + .pad0 = BOARD_SERCOM5_PINMAP_PAD0, + .pad1 = BOARD_SERCOM5_PINMAP_PAD1, + .pad2 = BOARD_SERCOM5_PINMAP_PAD2, + .pad3 = BOARD_SERCOM5_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM5_MUXCONFIG, + .srcfreq = BOARD_SERCOM5_FREQUENCY, + .base = SAM_SERCOM5_BASE, +#if 0 /* Not used */ + .handler = spi5_interrupt, +#endif + .spilock = SEM_INITIALIZER(1), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, uint32_t regval, + uint32_t regaddr) +{ + if (wr == priv->wr && /* Same kind of access? */ + regval == priv->regval && /* Same value? */ + regaddr == priv->regaddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wr = wr; + priv->regval = regval; + priv->regaddr = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg8 + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static uint8_t spi_getreg8(struct sam_spidev_s *priv, unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + uint8_t regval = getreg8(regaddr); + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, false, (uint32_t)regval, regaddr)) + { + lldbg("%08x->%02x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: spi_putreg8 + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static void spi_putreg8(struct sam_spidev_s *priv, uint8_t regval, + unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, true, (uint32_t)regval, regaddr)) + { + lldbg("%08x<-%02x\n", regaddr, regval); + } +#endif + + putreg8(regval, regaddr); +} + +/**************************************************************************** + * Name: spi_getreg16 + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static uint16_t spi_getreg16(struct sam_spidev_s *priv, unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + uint16_t regval = getreg16(regaddr); + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, false, (uint32_t)regval, regaddr)) + { + lldbg("%08x->%04x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: spi_putreg16 + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static void spi_putreg16(struct sam_spidev_s *priv, uint16_t regval, + unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, true, (uint32_t)regval, regaddr)) + { + lldbg("%08x<-%04x\n", regaddr, regval); + } +#endif + + putreg16(regval, regaddr); +} + +/**************************************************************************** + * Name: spi_getreg32 + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static uint32_t spi_getreg32(struct sam_spidev_s *priv, unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: spi_putreg32 + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static void spi_putreg32(struct sam_spidev_s *priv, uint32_t regval, + unsigned int offset) +{ + uintptr_t regaddr = priv->base + offset; + +#ifdef CONFIG_SAMDL_SPI_REGDEBUG + if (spi_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * priv - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" CTRLA:%08x CTRLB:%08x DBGCTRL:%02x\n", + getreg32(priv->base + SAM_SPI_CTRLA_OFFSET), + getreg32(priv->base + SAM_SPI_CTRLB_OFFSET), + getreg8(priv->base + SAM_SPI_DBGCTRL_OFFSET)); + spivdbg(" BAUD:%02x INTEN:%02x INTFLAG:%02x\n", + getreg8(priv->base + SAM_SPI_BAUD_OFFSET), + getreg8(priv->base + SAM_SPI_INTENCLR_OFFSET), + getreg8(priv->base + SAM_SPI_INTFLAG_OFFSET)); + spivdbg(" STATUS:%04x ADDR:%08x\n", + getreg16(priv->base + SAM_SPI_STATUS_OFFSET), + getreg32(priv->base + SAM_SPI_ADDR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_interrupt + * + * Description: + * This is the SPI interrupt handler. It will be invoked when an + * interrupt received on the 'irq' indicating either that the DATA + * register is available for the next transmission (DRE) or that the + * DATA register holds a new incoming work. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int spi_interrupt(struct sam_spidev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + uint8_t pending; + uint8_t intflag; + uint8_t inten; + + /* Get the set of pending SPI interrupts (we are only interested in the + * unmasked interrupts). + */ + + intflag = sam_getreg8(priv, SAM_SPI_INTFLAG_OFFSET); + inten = sam_getreg8(priv, SAM_SPI_INTENCLR_OFFSET); + pending = intflag & inten; + + /* Handle an incoming, receive byte. The RXC flag is set when there is + * unread data in DATA register. This flag is cleared by reading the DATA + * register (or by disabling the receiver). + */ + + if ((pending & SPI_INT_RXC) != 0) + { + /* Received data ready... process incoming SPI ata */ +#warning Missing logic + } + + /* Handle outgoing, transmit bytes. The DRE flag is set when the DATA + * register is empty and ready to be written. This flag is cleared by + * writing new data to the DATA register. If there is no further data to + * be transmitted, the serial driver will disable TX interrupts, prohibit + * further interrupts until TX interrupts are re-enabled. + */ + + if ((pending & SPI_INT_DRE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ +#warning Missing logic + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: spiN_interrupt + * + * Description: + * Handle each SERCOM SPI interrupt by calling the common interrupt + * handling logic with the SPI-specific state. + * + ****************************************************************************/ + +#if 0 /* Not used */ +#ifdef SAMDL_HAVE_SPI0 +static int spi0_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi0dev); +} +#endif + +#ifdef SAMDL_HAVE_SPI1 +static int spi1_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi1dev); +} +#endif + +#ifdef SAMDL_HAVE_SPI2 +static int spi2_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi2dev); +} +#endif + +#ifdef SAMDL_HAVE_SPI3 +static int spi3_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi3dev); +} +#endif + +#ifdef SAMDL_HAVE_SPI4 +static int spi4_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi4dev); +} +#endif + +#ifdef SAMDL_HAVE_SPI5 +static int spi5_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi5dev); +} +#endif +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock priv bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(struct spi_dev_s *dev, bool lock) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)dev; + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->spilock) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->spilock); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)dev; + uint32_t maxfreq; + uint32_t actual; + uint32_t baud; + uint32_t ctrla; + + spivdbg("sercom=%d frequency=%d\n", priv->sercom, frequency); + + /* Check if the configured BAUD is within the valid range */ + + maxfreq = (priv->srcfreq >> 1); + if (frequency > maxfreq) + { + /* Set the frequency to the maximum */ + + spidbg("ERROR: Cannot realize frequency: %ld\n", (long)frequency); + frequency = maxfreq; + } + + /* Check if the requested frequency is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* For synchronous mode, the BAUAD rate (Fbaud) is generated from the + * source clock frequency (Fref) as follows: + * + * Fbaud = Fref / (2 * (BAUD + 1)) + * + * Or + * + * BAUD = (Fref / (2 * Fbaud)) - 1 + * + * Where BAUD <= 255 + */ + + baud = ((priv->srcfreq + frequency) / (frequency << 1)) - 1; + + /* Verify that the resulting if BAUD divisor is within range */ + + if (baud > 255) + { + spidbg("ERROR: BAUD is out of range: %ld\n", (long)baud); + baud = 255; + } + + /* Momentarily disable SPI while we apply the new BAUD setting (if it was + * previously enabled) + */ + + ctrla = spi_getreg32(priv, SAM_SPI_CTRLA_OFFSET); + if ((ctrla & SPI_CTRLA_ENABLE) != 0) + { + /* Disable SPI.. waiting for synchronization */ + + spi_putreg32(priv, ctrla & ~SPI_CTRLA_ENABLE, SAM_SPI_CTRLA_OFFSET); + spi_wait_synchronization(priv); + + /* Set the new BAUD value */ + + spi_putreg8(priv, (uint8_t)baud, SAM_SPI_BAUD_OFFSET); + + /* Re-enable SPI.. waiting for synchronization */ + + spi_putreg32(priv, ctrla, SAM_SPI_CTRLA_OFFSET); + spi_wait_synchronization(priv); + } + else + { + /* Set the new BAUD when the SPI is already disabled */ + + spi_putreg8(priv, (uint8_t)baud, SAM_SPI_BAUD_OFFSET); + } + + /* Calculate the new actual frequency */ + + actual = priv->srcfreq / ((baud + 1) << 1); + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spivdbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)dev; + uint32_t regval; + + spivdbg("sercom=%d mode=%d\n", priv->sercom, mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set the mode appropriately */ + + regval = spi_getreg32(priv, SAM_SPI_CTRLA_OFFSET); + regval &= ~(SPI_CTRLA_CPOL | SPI_CTRLA_CPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CTRLA_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CTRLA_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CTRLA_CPOL | SPI_CTRLA_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg32(priv, regval, SAM_SPI_CTRLA_OFFSET); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)dev; + uint32_t regval; + + spivdbg("sercom=%d nbits=%d\n", priv->sercom, nbits); + DEBUGASSERT(priv && nbits > 7 && nbits < 10); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set number of bits appropriately */ + + regval = spi_getreg32(priv, SAM_SPI_CTRLB_OFFSET); + regval &= ~SPI_CTRLB_CHSIZE_MASK; + + if (nbits == 9) + { + regval |= SPI_CTRLB_CHSIZE_9BITS; + } + + spi_putreg32(priv, regval, SAM_SPI_CTRLB_OFFSET); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd) +{ + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange can do this. Note: right now, this only deals with 8-bit + * words. If the SPI interface were configured for words of other sizes, + * this would fail. + */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange(dev, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; +} + +/**************************************************************************** + * Name: spi_exchange + * + * Description: + * Exchange a block of data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * Data must be 16-bit aligned in 9-bit data transfer mode. + * + ****************************************************************************/ + +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)dev; + const uint16_t *ptx16; + const uint8_t *ptx8; + uint16_t *prx16; + uint8_t *prx8; + uint16_t data; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Set up data receive and transmit pointers */ + + if (priv->nbits > 8) + { + ptx8 = NULL; + prx8 = NULL; + ptx16 = (const uint16_t *)txbuffer; + prx16 = (uint16_t *)rxbuffer; + } + else + { + ptx8 = (const uint8_t *)txbuffer; + prx8 = (uint8_t *)rxbuffer; + ptx16 = NULL; + prx16 = NULL; + } + + /* Loop, sending each word in the user-provided data buffer. + * + * Note 1: Right now, this only deals with 8-bit words. If the SPI + * interface were configured for words of other sizes, this + * would fail. + * Note 2: This loop might be made more efficient. Would logic + * like the following improve the throughput? Or would it + * just add the risk of overruns? + * + * Get word 1; + * Send word 1; Now word 1 is "in flight" + * nwords--; + * for (; nwords > 0; nwords--) + * { + * Get word N. + * Wait for DRE:: meaning that word N-1 has moved to the shift + * register. + * Disable interrupts to keep the following atomic + * Send word N. Now both work N-1 and N are "in flight" + * Wait for RXC: meaning that word N-1 is available + * Read word N-1. + * Re-enable interrupts. + * Save word N-1. + * } + * Wait for RXC: meaning that the final word is available + * Read the final word. + * Save the final word. + */ + + for (; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source) */ + + if (ptx8) + { + data = (uint16_t)*ptx8++; + } + else if (ptx16) + { + data = *ptx16++; + } + else + { + data = 0x01ff; + } + + /* Wait for any previous data written to the DATA register to be + * transferred to the serializer. + */ + + while ((spi_getreg8(priv, SAM_SPI_INTFLAG_OFFSET) & SPI_INT_DRE) == 0); + + /* Write the data to transmitted to the DATA Register (TDR) */ + + spi_putreg16(priv, data, SAM_SPI_DATA_OFFSET); + + /* Wait for the read data to be available in the DATA register. */ + + while ((spi_getreg8(priv, SAM_SPI_INTFLAG_OFFSET) & SPI_INT_RXC) == 0); + + /* Check for data overflow. The BUFOVF bit provides the status of the + * next DATA to be read. On buffer overflow, the corresponding DATA + * will be 0. + */ + + data = spi_getreg16(priv, SAM_SPI_STATUS_OFFSET); + if ((data & SPI_STATUS_BUFOVF) != 0) + { + spidbg("ERROR: Buffer overflow!\n"); + + /* Clear the buffer overflow flag */ + + spi_putreg16(priv, data, SAM_SPI_STATUS_OFFSET); + } + + /* Read the received data from the SPI DATA Register.. + * TODO: The following only works if nbits <= 8. + */ + + data = spi_getreg16(priv, SAM_SPI_DATA_OFFSET); + if (prx8) + { + *prx8++ = (uint8_t)data; + } + else if (prx16) + { + *prx16++ = (uint16_t)data; + } + } +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_wait_synchronization + * + * Description: + * Wait until the SERCOM SPI reports that it is synchronized. + * + ****************************************************************************/ + +static void spi_wait_synchronization(struct sam_spidev_s *priv) +{ + while ((spi_getreg16(priv, SAM_SPI_STATUS_OFFSET) & SPI_STATUS_SYNCBUSY) != 0); +} + +/**************************************************************************** + * Name: spi_pad_configure + * + * Description: + * Configure the SERCOM SPI pads. + * + ****************************************************************************/ + +static void spi_pad_configure(struct sam_spidev_s *priv) +{ + /* Configure SERCOM pads */ + + if (priv->pad0 != 0) + { + sam_configport(priv->pad0); + } + + if (priv->pad1 != 0) + { + sam_configport(priv->pad1); + } + + if (priv->pad2 != 0) + { + sam_configport(priv->pad2); + } + + if (priv->pad3 != 0) + { + sam_configport(priv->pad3); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * port - SPI "port" number (i.e., SERCOM number) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port) +{ + struct sam_spidev_s *priv; + irqstate_t flags; + uint32_t regval; +#ifdef CONFIG_ARCH_FAMILY_SAML21 + int channel; +#endif +#if 0 /* Not used */ + int ret; +#endif + + /* Get the port state structure */ + + spivdbg("port: %d \n", port); + +#ifdef SAMDL_HAVE_SPI0 + if (port == 0) + { + priv = &g_spi0dev; + } + else +#endif + +#ifdef SAMDL_HAVE_SPI1 + if (port == 1) + { + priv = &g_spi1dev; + } + else +#endif + +#ifdef SAMDL_HAVE_SPI2 + if (port == 2) + { + priv = &g_spi2dev; + } + else +#endif + +#ifdef SAMDL_HAVE_SPI3 + if (port == 3) + { + priv = &g_spi3dev; + } + else +#endif + +#ifdef SAMDL_HAVE_SPI4 + if (port == 4) + { + priv = &g_spi4dev; + } + else +#endif + +#ifdef SAMDL_HAVE_SPI5 + if (port == 5) + { + priv = &g_spi5dev; + } + else +#endif + { + spidbg("ERROR: Unsupported port: %d\n", port); + return NULL; + } + + /* Enable clocking to the SERCOM module in PM */ + + flags = enter_critical_section(); + sercom_enable(priv->sercom); + + /* Configure the GCLKs for the SERCOM module */ + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + sercom_coreclk_configure(priv->sercom, priv->gclkgen, false); + +#elif defined(CONFIG_ARCH_FAMILY_SAML21) + if (priv->sercom == 5) + { + channel = GCLK_CHAN_SERCOM5_CORE; + } + else + { + channel = priv->sercom + GCLK_CHAN_SERCOM0_CORE; + } + + sam_gclk_chan_enable(channel, config->gclkgen); +#endif + + sercom_slowclk_configure(priv->sercom, priv->slowgen); + + /* Set the SERCOM in SPI master mode (no address) */ + + regval = spi_getreg32(priv, SAM_SPI_CTRLA_OFFSET); + regval &= ~SPI_CTRLA_MODE_MASK; + regval |= (SPI_CTRLA_MODE_MASTER | SPI_CTRLA_FORM_SPI); + spi_putreg32(priv, regval, SAM_SPI_CTRLA_OFFSET); + + /* Configure pads */ + + spi_pad_configure(priv); + + /* Set an initial baud value. This will be changed by the upper-half + * driver as soon as it starts. + */ + + (void)spi_setfrequency((struct spi_dev_s *)priv, 400000); + + /* Set MSB first data order and the configured pad mux setting, + * Note that SPI mode 0 is assumed initially (CPOL=0 and CPHA=0). + */ + + regval = (SPI_CTRLA_MSBFIRST | priv->muxconfig); + spi_putreg32(priv, regval, SAM_SPI_CTRLA_OFFSET); + + /* Enable the receiver. Note that 8-bit data width is assumed initially */ + + regval = (SPI_CTRLB_RXEN | SPI_CTRLB_CHSIZE_8BITS); + spi_putreg32(priv, regval, SAM_SPI_CTRLB_OFFSET); + spi_wait_synchronization(priv); + + priv->nbits = 8; + + /* Enable SPI */ + + regval = spi_getreg32(priv, SAM_SPI_CTRLA_OFFSET); + regval |= SPI_CTRLA_ENABLE; + spi_putreg32(priv, regval, SAM_SPI_CTRLA_OFFSET); + spi_wait_synchronization(priv); + + /* Disable all interrupts at the SPI source and clear all pending + * status that we can. + */ + + spi_putreg8(priv, SPI_INT_ALL, SAM_SPI_INTENCLR_OFFSET); + spi_putreg8(priv, SPI_INT_ALL, SAM_SPI_INTFLAG_OFFSET); + spi_putreg16(priv, SPI_STATUS_CLRALL, SAM_SPI_STATUS_OFFSET); + +#if 0 /* Not used */ + /* Attach and enable the SERCOM interrupt handler */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret < 0) + { + spidbg("ERROR: Failed to attach interrupt: %d\n", irq); + return NULL; + } + + /* Enable SERCOM interrupts at the NVIC */ + + up_enable_irq(priv->irq); +#endif + + spi_dumpregs(priv, "After initialization"); + leave_critical_section(flags); + return (struct spi_dev_s *)priv; +} + +#endif /* SAMDL_HAVE_SPI */ diff --git a/arch/arm/src/samdl/sam_spi.h b/arch/arm/src/samdl/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..6185a5b3f0159b3ccefdbcb2d21a58ddc71b9c2c --- /dev/null +++ b/arch/arm/src/samdl/sam_spi.h @@ -0,0 +1,296 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_spi.h + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_SPI_H +#define __ARCH_ARM_SRC_SAMDL_SAM_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_config.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_spi.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_spi.h" +#endif + +#ifdef SAMDL_HAVE_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * port - SPI "port" number (i.e., SERCOM number) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s *sam_spibus_initialize(int port); + +/**************************************************************************** + * Name: sam_spi[n]select, sam_spi[n]status, and sam_spi[n]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They + * include: + * + * o sam_spi[n]select is a functions to manage the board-specific chip + * selects + * o sam_spi[n]status and sam_spi[n]cmddata: Implementations of the status + * and cmddata methods of the SPI interface defined by struct spi_ops_ + * (see include/nuttx/spi/spi.h). All other methods including + * sam_spibus_initialize()) are provided by common SAMD/L logic. + * + * Where [n] is the SERCOM number for the SPI module. + * + * To use this common SPI logic on your board: + * + * 1. Provide logic in sam_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide sam_spi[n]select() and sam_spi[n]status() functions in your + * board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * sam_spi[n]cmddata() functions in your board-specific logic. This + * function will perform cmd/data selection operations using GPIOs in + * the way your board is configured. + * 3. Add a call to sam_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by sam_spibus_initialize() may then be used to bind + * the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spi[n]select + * + * Description: + * PIO chip select pins may be programmed by the board specific logic in + * one of two different ways. First, the pins may be programmed as SPI + * peripherals. In that case, the pins are completely controlled by the + * SPI driver. This method still needs to be provided, but it may be only + * a stub. + * + * An alternative way to program the PIO chip select pins is as a normal + * GPIO output. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the GPIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * selected - TRUE:Select the device, FALSE:De-select the device + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_SPI0 +void sam_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +#ifdef SAMDL_HAVE_SPI1 +void sam_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +#ifdef SAMDL_HAVE_SPI2 +void sam_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +#ifdef SAMDL_HAVE_SPI3 +void sam_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +#ifdef SAMDL_HAVE_SPI4 +void sam_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +#ifdef SAMDL_HAVE_SPI5 +void sam_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +#endif + +/**************************************************************************** + * Name: sam_spi[n]status + * + * Description: + * Return status information associated with the SPI device. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Bit-encoded SPI status (see include/nuttx/spi/spi.h. + * + ****************************************************************************/ + +#ifdef SAMDL_HAVE_SPI0 +uint8_t sam_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +#ifdef SAMDL_HAVE_SPI1 +uint8_t sam_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +#ifdef SAMDL_HAVE_SPI2 +uint8_t sam_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +#ifdef SAMDL_HAVE_SPI3 +uint8_t sam_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +#ifdef SAMDL_HAVE_SPI4 +uint8_t sam_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +#ifdef SAMDL_HAVE_SPI5 +uint8_t sam_spi5status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +/**************************************************************************** + * Name: sam_spi[n]cmddata + * + * Description: + * Some SPI devices require an additional control to determine if the SPI + * data being sent is a command or is data. If CONFIG_SPI_CMDDATA then + * this function will be called to different be command and data transfers. + * + * This is often needed, for example, by LCD drivers. Some LCD hardware + * may be configured to use 9-bit data transfers with the 9th bit + * indicating command or data. That same hardware may be configurable, + * instead, to use 8-bit data but to require an additional, board- + * specific GPIO control to distinguish command and data. This function + * would be needed in that latter case. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Zero on success; a negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef SAMDL_HAVE_SPI0 +int sam_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef SAMDL_HAVE_SPI1 +int sam_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef SAMDL_HAVE_SPI2 +int sam_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef SAMDL_HAVE_SPI3 +int sam_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef SAMDL_HAVE_SPI4 +int sam_spi4cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef SAMDL_HAVE_SPI5 +int sam_spi5cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* SAMDL_HAVE_SPI */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_SPI_H */ diff --git a/arch/arm/src/samdl/sam_start.c b/arch/arm/src/samdl/sam_start.c new file mode 100644 index 0000000000000000000000000000000000000000..e31a1b274df320404f28896d39d68c8dc8ddd299 --- /dev/null +++ b/arch/arm/src/samdl/sam_start.c @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_start.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_config.h" +#include "sam_lowputc.h" +#include "sam_clockconfig.h" +#include "sam_userspace.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map: + * + * 0x0000:0000 - Beginning of FLASH. Address of exception vectors. + * 0x0003:ffff - End of flash (assuming 256KB of FLASH) + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap + * 0x2000:ffff - End of SRAM and end of heap (assuming 64KB of SRAM) + */ + +#define IDLE_STACK ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uint32_t g_idle_topstack = IDLE_STACK; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(HAVE_SERIAL_CONSOLE) +# define showprogress(c) sam_lowputc((uint32_t)c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Configure basic clocking */ + + sam_clockconfig(); + + /* Configure the uart early so that we can get debug output as soon as possible */ + + sam_lowsetup(); + showprogress('A'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('B'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + sam_userspace(); + showprogress('C'); +#endif + + /* Initialize onboard resources */ + + sam_boardinitialize(); + showprogress('D'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/samdl/sam_timerisr.c b/arch/arm/src/samdl/sam_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..327e8b72b037421a3948037decde0be14113f2ed --- /dev/null +++ b/arch/arm/src/samdl/sam_timerisr.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_timerisr.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * Then, for example, if the CPU clock is the the SysTick and + * BOARD_CPU_FREQUENCY is 48MHz and CLK_TCK is 100, then the reload value + * would be: + * + * SYSTICK_RELOAD = (48,000,000 / 100) - 1 + * = 479,999 + * = 0x752ff + * + * Which fits within the maximum 24-bit reload value. + */ + +#define SYSTICK_RELOAD ((BOARD_CPU_FREQUENCY / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(ARMV6M_SYSCON_SHPR3); + regval &= ~SYSCON_SHPR3_PRI_15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << SYSCON_SHPR3_PRI_15_SHIFT); + putreg32(regval, ARMV6M_SYSCON_SHPR3); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, ARMV6M_SYSTICK_RVR); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(SAM_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), ARMV6M_SYSTICK_CSR); + + /* And enable the timer interrupt */ + + up_enable_irq(SAM_IRQ_SYSTICK); +} diff --git a/arch/arm/src/samdl/sam_usart.c b/arch/arm/src/samdl/sam_usart.c new file mode 100644 index 0000000000000000000000000000000000000000..01a2d977c3df63d4ab334cfa2b56c54a5226ff0c --- /dev/null +++ b/arch/arm/src/samdl/sam_usart.c @@ -0,0 +1,242 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_usart.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_pinmap.h" +#include "sam_gclk.h" +#include "sam_usart.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef SAMDL_HAVE_USART0 +const struct sam_usart_config_s g_usart0config = +{ + .sercom = 0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .irq = SAM_IRQ_SERCOM0, + .gclkgen = BOARD_SERCOM0_GCLKGEN, + .slowgen = BOARD_SERCOM0_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART0_2STOP, + .baud = CONFIG_USART0_BAUD, + .pad0 = BOARD_SERCOM0_PINMAP_PAD0, + .pad1 = BOARD_SERCOM0_PINMAP_PAD1, + .pad2 = BOARD_SERCOM0_PINMAP_PAD2, + .pad3 = BOARD_SERCOM0_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM0_MUXCONFIG, + .frequency = BOARD_SERCOM0_FREQUENCY, + .base = SAM_SERCOM0_BASE, +}; +#endif + +#ifdef SAMDL_HAVE_USART1 +const struct sam_usart_config_s g_usart1config = +{ + .sercom = 1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .irq = SAM_IRQ_SERCOM1, + .gclkgen = BOARD_SERCOM1_GCLKGEN, + .slowgen = BOARD_SERCOM1_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .pad0 = BOARD_SERCOM1_PINMAP_PAD0, + .pad1 = BOARD_SERCOM1_PINMAP_PAD1, + .pad2 = BOARD_SERCOM1_PINMAP_PAD2, + .pad3 = BOARD_SERCOM1_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM1_MUXCONFIG, + .frequency = BOARD_SERCOM1_FREQUENCY, + .base = SAM_SERCOM1_BASE, +}; +#endif + +#ifdef SAMDL_HAVE_USART2 +const struct sam_usart_config_s g_usart2config = +{ + .sercom = 2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .irq = SAM_IRQ_SERCOM2, + .gclkgen = BOARD_SERCOM2_GCLKGEN, + .slowgen = BOARD_SERCOM2_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .pad0 = BOARD_SERCOM2_PINMAP_PAD0, + .pad1 = BOARD_SERCOM2_PINMAP_PAD1, + .pad2 = BOARD_SERCOM2_PINMAP_PAD2, + .pad3 = BOARD_SERCOM2_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM2_MUXCONFIG, + .frequency = BOARD_SERCOM2_FREQUENCY, + .base = SAM_SERCOM2_BASE, +}; +#endif + +#ifdef SAMDL_HAVE_USART3 +const struct sam_usart_config_s g_usart3config = +{ + .sercom = 3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .irq = SAM_IRQ_SERCOM3, + .gclkgen = BOARD_SERCOM3_GCLKGEN, + .slowgen = BOARD_SERCOM3_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .pad0 = BOARD_SERCOM3_PINMAP_PAD0, + .pad1 = BOARD_SERCOM3_PINMAP_PAD1, + .pad2 = BOARD_SERCOM3_PINMAP_PAD2, + .pad3 = BOARD_SERCOM3_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM3_MUXCONFIG, + .frequency = BOARD_SERCOM3_FREQUENCY, + .base = SAM_SERCOM3_BASE, +}; +#endif + +#ifdef SAMDL_HAVE_USART4 +const struct sam_usart_config_s g_usart4config = +{ + .sercom = 4, + .parity = CONFIG_USART4_PARITY, + .bits = CONFIG_USART4_BITS, + .irq = SAM_IRQ_SERCOM4, + .gclkgen = BOARD_SERCOM4_GCLKGEN, + .slowgen = BOARD_SERCOM4_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART4_2STOP, + .baud = CONFIG_USART4_BAUD, + .pad0 = BOARD_SERCOM4_PINMAP_PAD0, + .pad1 = BOARD_SERCOM4_PINMAP_PAD1, + .pad2 = BOARD_SERCOM4_PINMAP_PAD2, + .pad3 = BOARD_SERCOM4_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM4_MUXCONFIG, + .frequency = BOARD_SERCOM4_FREQUENCY, + .base = SAM_SERCOM4_BASE, +}; +#endif + +#ifdef SAMDL_HAVE_USART5 +const struct sam_usart_config_s g_usart5config = +{ + .sercom = 5, + .parity = CONFIG_USART5_PARITY, + .bits = CONFIG_USART5_BITS, + .irq = SAM_IRQ_SERCOM5, + .gclkgen = BOARD_SERCOM5_GCLKGEN, + .slowgen = BOARD_SERCOM5_SLOW_GCLKGEN, + .stopbits2 = CONFIG_USART5_2STOP, + .baud = CONFIG_USART5_BAUD, + .pad0 = BOARD_SERCOM5_PINMAP_PAD0, + .pad1 = BOARD_SERCOM5_PINMAP_PAD1, + .pad2 = BOARD_SERCOM5_PINMAP_PAD2, + .pad3 = BOARD_SERCOM5_PINMAP_PAD3, + .muxconfig = BOARD_SERCOM5_MUXCONFIG, + .frequency = BOARD_SERCOM5_FREQUENCY, + .base = SAM_SERCOM5_BASE, +}; +#endif + +const struct sam_usart_config_s *g_usartconfig[SAMDL_NSERCOM] = +{ +#if SAMDL_NSERCOM > 5 +#ifdef SAMDL_HAVE_USART5 + &g_usart5config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif + +#if SAMDL_NSERCOM > 1 +#ifdef SAMDL_HAVE_USART1 + &g_usart1config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif + +#if SAMDL_NSERCOM > 2 +#ifdef SAMDL_HAVE_USART2 + &g_usart2config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif + +#if SAMDL_NSERCOM > 3 +#ifdef SAMDL_HAVE_USART3 + &g_usart3config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif + +#if SAMDL_NSERCOM > 4 +#ifdef SAMDL_HAVE_USART4 + &g_usart4config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif + +#if SAMDL_NSERCOM > 5 +#ifdef SAMDL_HAVE_USART5 + &g_usart5config, +#else + (const struct sam_usart_config_s *)0, +#endif +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/samdl/sam_usart.h b/arch/arm/src/samdl/sam_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..19784dfae8cb9c9a0284295f9876be6e74150115 --- /dev/null +++ b/arch/arm/src/samdl/sam_usart.h @@ -0,0 +1,182 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_usart.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_USART_H +#define __ARCH_ARM_SRC_SAMDL_SAM_USART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_usart.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_usart.h" +#endif + +#include "sam_config.h" +#include "sam_port.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Pick the console USART configuration */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart0config) +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart1config) +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart2config) +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart3config) +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart4config) +#elif defined(CONFIG_USART5_SERIAL_CONSOLE) +# define g_consoleconfig (g_usart5config) +#else +# undef g_consoleconfig +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* This structure describes the static configuration of a USART */ + +struct sam_usart_config_s +{ + uint8_t sercom; /* Identifies the SERCOM peripheral */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-9) */ + uint8_t irq; /* SERCOM IRQ number */ + uint8_t gclkgen; /* Source GCLK generator */ + uint8_t slowgen; /* Slow GCLK generator */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ + uint32_t baud; /* Configured baud */ + port_pinset_t pad0; /* Pin configuration for PAD0 */ + port_pinset_t pad1; /* Pin configuration for PAD1 */ + port_pinset_t pad2; /* Pin configuration for PAD2 */ + port_pinset_t pad3; /* Pin configuration for PAD3 */ + uint32_t muxconfig; /* Pad multiplexing configuration */ + uint32_t frequency; /* Source clock frequency */ + uintptr_t base; /* SERCOM base address */ +}; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ +/************************************************************************************ + * Name: sam_wait_synchronization + * + * Description: + * Return true is the SERCOM USART reports that it is synchronizing. This inline + * function hides register differences between the SAMD20 and SAML21. + * + ***********************************************************************************/ + +#ifdef SAMDL_HAVE_USART +static inline bool usart_syncbusy(const struct sam_usart_config_s * const config) +{ +#if defined(CONFIG_ARCH_FAMILY_SAMD20) + return ((getreg16(config->base + SAM_USART_STATUS_OFFSET) & USART_STATUS_SYNCBUSY) != 0); +#elif defined(CONFIG_ARCH_FAMILY_SAMD21) || defined(CONFIG_ARCH_FAMILY_SAML21) + return ((getreg16(config->base + SAM_USART_SYNCBUSY_OFFSET) & USART_SYNCBUSY_ALL) != 0); +#else +# error Unrecognized SAMD/L family + return false; +#endif +} +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifdef SAMDL_HAVE_USART0 +EXTERN const struct sam_usart_config_s g_usart0config; +#endif + +#ifdef SAMDL_HAVE_USART1 +EXTERN const struct sam_usart_config_s g_usart1config; +#endif + +#ifdef SAMDL_HAVE_USART2 +EXTERN const struct sam_usart_config_s g_usart2config; +#endif + +#ifdef SAMDL_HAVE_USART3 +EXTERN const struct sam_usart_config_s g_usart3config; +#endif + +#ifdef SAMDL_HAVE_USART4 +EXTERN const struct sam_usart_config_s g_usart4config; +#endif + +#ifdef SAMDL_HAVE_USART5 +EXTERN const struct sam_usart_config_s g_usart5config; +#endif + +EXTERN const struct sam_usart_config_s *g_usartconfig[SAMDL_NSERCOM]; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_USART_H */ diff --git a/arch/arm/src/samdl/sam_userspace.c b/arch/arm/src/samdl/sam_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..613aa33b3c892cc11a860a121dc3aadf9257a00d --- /dev/null +++ b/arch/arm/src/samdl/sam_userspace.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_userspace.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "sam_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void sam_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/samdl/sam_userspace.h b/arch/arm/src/samdl/sam_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..ef911602b62531c50992486ef938db9ebbbf9d43 --- /dev/null +++ b/arch/arm/src/samdl/sam_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/samdl/sam_userspace.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_USERSPACE_H +#define __ARCH_ARM_SRC_SAMDL_SAM_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_USERSPACE_H */ diff --git a/arch/arm/src/samdl/samd_clockconfig.c b/arch/arm/src/samdl/samd_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..6dc0f4c76fc5896401f4743430e1b85bbdef028f --- /dev/null +++ b/arch/arm/src/samdl/samd_clockconfig.c @@ -0,0 +1,896 @@ +/**************************************************************************** + * arch/arm/src/samdl/samd_clockconfig.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * 1. "Atmel SAM D20J / SAM D20G / SAM D20E ARM-Based Microcontroller + * Datasheet", 42129J–SAM–12/2013 + * 2. "Atmel SAM D21E / SAM D21G / SAM D21J SMART ARM-Based Microcontroller + * Datasheet", Atmel-42181E–SAM-D21_Datasheet–02/2015 + * 3. Atmel sample code for the SAMD20. This code has an ASF license + * with is compatible with the NuttX BSD license, but includes the + * provision that this code not be used in non-Atmel products. That + * sample code was used only as a reference so I believe that only the + * NuttX BSD license applies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip/samd_pm.h" +#include "chip/samd_sysctrl.h" +#include "chip/samd_gclk.h" +#include "chip/samd_nvmctrl.h" +#include "sam_fuses.h" +#include "sam_gclk.h" + +#include + +#include "samd_periphclks.h" +#include "sam_clockconfig.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This structure describes the configuration of every enabled GCLK */ + +#ifdef BOARD_GCLK_ENABLE +static const struct sam_gclkconfig_s g_gclkconfig[] = +{ + /* GCLK generator 0 (Main Clock) */ + + { + .gclk = 0, +#ifdef BOARD_GCLK0_RUN_IN_STANDBY + .runstandby = true, +#endif +#ifdef BOARD_GCLK0_OUTPUT_ENABLE + .output = true, +#endif + .prescaler = BOARD_GCLK0_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK0_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } + + /* GCLK generator 1 */ + +#ifdef BOARD_GCLK1_ENABLE + , + { + .gclk = 1, +#ifdef BOARD_GCLK1_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK1_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK1_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK1_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 2 (RTC) */ + +#ifdef BOARD_GCLK2_ENABLE + , + { + .gclk = 2, +#ifdef BOARD_GCLK2_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK2_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK2_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK2_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 3 */ + +#ifdef BOARD_GCLK3_ENABLE + , + { + .gclk = 3, +#ifdef BOARD_GCLK3_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK3_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK3_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK3_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 4 */ + +#ifdef BOARD_GCLK4_ENABLE + , + { + .gclk = 4, +#ifdef BOARD_GCLK4_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK4_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK4_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK4_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 5 */ + +#ifdef BOARD_GCLK5_ENABLE + , + { + .gclk = 5, +#ifdef BOARD_GCLK5_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK5_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK5_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK5_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 6 */ + +#ifdef BOARD_GCLK6_ENABLE + , + { + .gclk = 6, +#ifdef BOARD_GCLK6_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK6_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK6_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK6_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 7 */ + +#ifdef BOARD_GCLK7_ENABLE + , + { + .gclk = 7, +#ifdef BOARD_GCLK7_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK7_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK7_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK7_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 8 */ + +#ifdef BOARD_GCLK8_ENABLE + , + { + .gclk = 8, +#ifdef BOARD_GCLK8_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK8_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK8_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK8_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif +}; + +#define NGCLKS_ENABLED (sizeof(g_gclkconfig) / sizeof(struct sam_gclkconfig_s)) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_flash_waitstates + * + * Description: + * Set the FLASH wait states based on settings in the board.h header file + * Depends on: + * + * BOARD_FLASH_WAITSTATES - Number of wait states + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_flash_waitstates(void) +{ + uint32_t regval; + + regval = getreg32(SAM_NVMCTRL_CTRLB); + regval &= ~NVMCTRL_CTRLB_RWS_MASK; + regval |= NVMCTRL_CTRLB_RWS(BOARD_FLASH_WAITSTATES); + putreg32(regval, SAM_NVMCTRL_CTRLB); +} + +/**************************************************************************** + * Name: sam_xosc_config + * + * Description: + * Configure XOSC based on settings in the board.h header file + * Depends on: + * + * BOARD_XOSC_ENABLE - Boolean (defined / not defined) + * BOARD_XOSC_FREQUENCY - In Hz + * BOARD_XOSC_STARTUPTIME - See SYSCTRL_XOSC_STARTUP_* definitions + * BOARD_XOSC_ISCRYSTAL - Boolean (defined / not defined) + * BOARD_XOSC_AMPGC - Boolean (defined / not defined) + * BOARD_XOSC_ONDEMAND - Boolean (defined / not defined) + * BOARD_XOSC_RUNINSTANDBY - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_XOSC_ENABLE +static inline void sam_xosc_config(void) +{ + uint16_t regval; + + /* Configure the XOSC clock */ + + regval = BOARD_XOSC_STARTUPTIME + +#ifdef BOARD_XOSC_ISCRYSTAL + /* XOSC is a crystal */ + + regval |= SYSCTRL_XOSC_XTALEN; +#endif + +#ifdef BOARD_XOSC_AMPGC + /* Enable automatic gain control */ + + regval |= SYSCTRL_XOSC_AMPGC; + +#else + /* Set gain if automatic gain control is not selected */ + +#if BOARD_XOSC_FREQUENCY <= 2000000 + regval |= SYSCTRL_XOSC_GAIN_2MHZ; +#elif BOARD_XOSC_FREQUENCY <= 4000000 + regval |= SYSCTRL_XOSC_GAIN_4MHZ; +#elif BOARD_XOSC_FREQUENCY <= 8000000 + regval |= SYSCTRL_XOSC_GAIN_8MHZ; +#elif BOARD_XOSC_FREQUENCY <= 16000000 + regval |= SYSCTRL_XOSC_GAIN_16MHZ; +#elif BOARD_XOSC_FREQUENCY <= 30000000 + regval |= SYSCTRL_XOSC_GAIN_30MHZ; +#else +# error BOARD_XOSC_FREQUENCY out of range +#endif +#endif /* BOARD_XOSC_AMPGC */ + +#ifdef BOARD_XOSC_ONDEMAND + regval |= SYSCTRL_XOSC_ONDEMAND; +#endif + +#ifdef BOARD_XOSC_RUNINSTANDBY + regval |= SYSCTRL_XOSC_RUNSTDBY; +#endif + + putreg16(regval, SAM_SYSCTRL_XOSC); + + /* Then enable the XOSC clock */ + + regval |= SYSCTRL_XOSC_ENABLE; + putreg16(regval, SAM_SYSCTRL_XOSC); +} +#else +# define sam_xosc_config() +#endif + +/**************************************************************************** + * Name: sam_xosc32k_config + * + * Description: + * Configure XOSC32K based on settings in the board.h header file. + * Depends on: + * + * BOARD_XOSC32K_ENABLE - Boolean (defined / not defined) + * BOARD_XOSC32K_FREQUENCY - In Hz + * BOARD_XOSC32K_STARTUPTIME - See SYSCTRL_XOSC32K_STARTUP_* definitions + * BOARD_XOSC32K_ISCRYSTAL - Boolean (defined / not defined) + * BOARD_XOSC32K_AAMPEN - Boolean (defined / not defined) + * BOARD_XOSC32K_EN1KHZ - Boolean (defined / not defined) + * BOARD_XOSC32K_EN32KHZ - Boolean (defined / not defined) + * BOARD_XOSC32K_ONDEMAND - Boolean (defined / not defined) + * BOARD_XOSC32K_RUNINSTANDBY - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_XOSC32K_ENABLE +static inline void sam_xosc32k_config(void) +{ + uint16_t regval; + + /* Configure XOSC32K */ + + regval = BOARD_XOSC32K_STARTUPTIME + +#ifdef BOARD_XOSC32K_ISCRYSTAL + regval |= SYSCTRL_XOSC32K_XTALEN; +#endif + +#ifdef BOARD_XOSC32K_AAMPEN + regval |= SYSCTRL_XOSC32K_AAMPEN; +#endif + +#ifdef BOARD_XOSC32K_EN1KHZ + regval |= SYSCTRL_XOSC32K_EN1K; +#endif + +#ifdef BOARD_XOSC32K_EN32KHZ + regval |= SYSCTRL_XOSC32K_EN32K; +#endif + +#ifdef BOARD_XOSC32K_ONDEMAND + regval |= SYSCTRL_XOSC32K_ONDEMAND; +#endif + +#ifdef BOARD_XOSC32K_RUNINSTANDBY + regval |= SYSCTRL_XOSC32K_RUNSTDBY; +#endif + + putreg16(regval, SAM_SYSCTRL_XOSC32K); + + /* Then enable the XOSC clock */ + + regval |= SYSCTRL_XOSC32K_ENABLE; + putreg16(regval, SAM_SYSCTRL_XOSC32K); +} +#else +# define sam_xosc32k_config() +#endif + +/**************************************************************************** + * Name: sam_osc32k_config + * + * Description: + * Configure OSC32K based on settings in the board.h header file. + * Depends on: + * + * BOARD_OSC32K_ENABLE - Boolean (defined / not defined) + * BOARD_OSC32K_FREQUENCY - In Hz + * BOARD_OSC32K_STARTUPTIME - See SYSCTRL_OSC32K_STARTUP_* definitions + * BOARD_OSC32K_EN1KHZ - Boolean (defined / not defined) + * BOARD_OSC32K_EN32KHZ - Boolean (defined / not defined) + * BOARD_OSC32K_ONDEMAND - Boolean (defined / not defined) + * BOARD_OSC32K_RUNINSTANDBY - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_OSC32K_ENABLE +static inline void sam_osc32k_config(void) +{ + uint32_t regval; + uint32_t calib; + + /* Recover OSC32K calibration data from OTP "fuse" memory */ + + regval = getreg32(SYSCTRL_FUSES_OSC32KCAL_ADDR); + calib = (regval & SYSCTRL_FUSES_OSC32KCAL_MASK) >> SYSCTRL_FUSES_OSC32KCAL_SHIFT; + regval = calib << SYSCTRL_OSC32K_CALIB_SHIFT; + + /* Configure OSC32K */ + + regval |= BOARD_OSC32K_STARTUPTIME; + +#ifdef BOARD_OSC32K_EN1KHZ + regval |= SYSCTRL_OSC32K_EN1K; +#endif + +#ifdef BOARD_OSC32K_EN32KHZ + regval |= SYSCTRL_OSC32K_EN32K; +#endif + +#ifdef BOARD_OSC32K_ONDEMAND + regval |= SYSCTRL_OSC32K_ONDEMAND; +#endif + +#ifdef BOARD_OSC32K_RUNINSTANDBY + regval |= SYSCTRL_OSC32K_RUNSTDBY; +#endif + + putreg32(regval, SAM_SYSCTRL_OSC32K); + + /* Then enable OSC32K */ + + regval |= SYSCTRL_OSC32K_ENABLE; + putreg32(regval, SAM_SYSCTRL_OSC32K); +} +#else +# define sam_osc32k_config() +#endif + +/**************************************************************************** + * Name: sam_osc8m_config + * + * Description: + * Configure OSC8M based on settings in the board.h header file. + * Depends on: + * + * BOARD_OSC8M_PRESCALER - See SYSCTRL_OSC8M_PRESC_DIV* definitions + * BOARD_OSC8M_ONDEMAND - Boolean (defined / not defined) + * BOARD_OSC8M_RUNINSTANDBY - Boolean (defined / not defined) + * + * On any reset the synchronous clocks start to their initial state: + * + * OSC8M is enabled and divided by 8 + * GCLK_MAIN uses OSC8M as source + * CPU and BUS clocks are undivided + * + * The reset state of the OSC8M register is: + * + * FFxx CCCC CCCC CCCC xxxx xxPP ORxx xxEx + * xx00 xxxx xxxx xxxx 0000 0011 1000 0010 + * + * FRANGE FF Loaded from FLASH calibration at startup + * CALIB CCC...C Loaded from FLASH calibration at startup + * PRESC PP 3 = Divide by 8 + * ONDEMAND O 1 + * RUNSTBY R 0 + * ENABLE 1 1 + * + * NOTE that since we are running from OSC8M, it cannot be disable! + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_osc8m_config(void) +{ + uint32_t regval; + + /* Configure OSC8M */ + + regval = getreg32(SAM_SYSCTRL_OSC8M); + regval &= ~(SYSCTRL_OSC8M_PRESC_MASK | SYSCTRL_OSC8M_ONDEMAND | + SYSCTRL_OSC8M_RUNSTDBY); + + /* Select the prescaler */ + + regval |= (BOARD_OSC8M_PRESCALER | SYSCTRL_OSC8M_ENABLE); + +#ifdef BOARD_OSC8M_ONDEMAND + /* Select on-demand oscillator controls */ + + regval |= SYSCTRL_OSC8M_ONDEMAND; +#endif + +#ifdef BOARD_OSC8M_RUNINSTANDBY + /* The oscillator continues to run in standby sleep mode */ + + regval |= SYSCTRL_OSC8M_RUNSTDBY; +#endif + + /* Set the OSC8M configuration */ + + putreg32(regval, SAM_SYSCTRL_OSC8M); +} + +/**************************************************************************** + * Name: sam_dfll_config + * + * Description: + * Configure the DFLL based on settings in the board.h header file. + * Depends on: + * + * BOARD_DFLL_OPENLOOP - Boolean (defined / not defined) + * BOARD_DFLL_TRACKAFTERFINELOCK - Boolean (defined / not defined) + * BOARD_DFLL_KEEPLOCKONWAKEUP - Boolean (defined / not defined) + * BOARD_DFLL_ENABLECHILLCYCLE - Boolean (defined / not defined) + * BOARD_DFLL_QUICKLOCK - Boolean (defined / not defined) + * BOARD_DFLL_ONDEMAND - Boolean (defined / not defined) + * BOARD_DFLL_COARSEVALUE - Value + * BOARD_DFLL_FINEVALUE - Value + * + * Open Loop mode only: + * BOARD_DFLL_COARSEVALUE - Value + * BOARD_DFLL_FINEVALUE - Value + * + * Closed loop mode only: + * BOARD_DFLL_SRCGCLKGEN - GCLK index + * BOARD_DFLL_MULTIPLIER - Value + * BOARD_DFLL_MAXCOARSESTEP - Value + * BOARD_DFLL_MAXFINESTEP - Value + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_DFLL_ENABLE +static inline void sam_dfll_config(void) +{ + uint16_t control; + uint32_t regval; + + /* Set up the DFLL control register */ + + control = SYSCTRL_DFLLCTRL_ENABLE; /* Enable the DFLL */ + +#ifndef BOARD_DFLL_OPENLOOP + control |= SYSCTRL_DFLLCTRL_MODE; /* Closed loop mode */ +#endif + +#ifndef BOARD_DFLL_TRACKAFTERFINELOCK + control |= SYSCTRL_DFLLCTRL_STABLE; /* FINE calibration fixed after a fine lock */ +#endif + +#ifndef BOARD_DFLL_KEEPLOCKONWAKEUP + control |= SYSCTRL_DFLLCTRL_LLAW; /* Lose lock after wake */ +#endif + +#ifndef BOARD_DFLL_ENABLECHILLCYCLE + control |= SYSCTRL_DFLLCTRL_CCDIS; /* Chill cycle disable */ +#endif + +#ifndef BOARD_DFLL_QUICKLOCK + control |= SYSCTRL_DFLLCTRL_QLDIS; /* Quick lock disable */ +#endif + + /* Then enable the DFLL (with ONDEMAND set to zero). */ + + putreg16(control, SAM_SYSCTRL_DFLLCTRL); + + /* Wait for the DFLL to synchronize */ + + while ((getreg32(SAM_SYSCTRL_PCLKSR) & SYSCTRL_INT_DFLLRDY) == 0); + + /* Set up the open loop mode multiplier register */ + +#ifndef BOARD_DFLL_OPENLOOP + regval = SYSCTRL_DFLLMUL_CSTEP(BOARD_DFLL_MAXCOARSESTEP) | + SYSCTRL_DFLLMUL_FSTEP(BOARD_DFLL_MAXFINESTEP) | + SYSCTRL_DFLLMUL_MUL(BOARD_DFLL_MULTIPLIER); + putreg32(regval, SAM_SYSCTRL_DFLLMUL); +#else + putreg32(0, SAM_SYSCTRL_DFLLMUL); +#endif + + /* Set up the DFLL value register */ + + regval = SYSCTRL_DFLLVAL_COARSE(BOARD_DFLL_COARSEVALUE) | + SYSCTRL_DFLLVAL_FINE(BOARD_DFLL_FINEVALUE); + putreg32(regval, SAM_SYSCTRL_DFLLVAL); + + /* Finally, set the state of the ONDEMAND bit if necessary */ + +#ifdef BOARD_DFLL_ONDEMAND + control |= SYSCTRL_DFLLCTRL_ONDEMAND; /* On demand control */ + putreg16(control, SAM_SYSCTRL_DFLLCTRL); +#endif +} +#else +# define sam_dfll_config() +#endif + +/**************************************************************************** + * Name: sam_dfll_reference + * + * Description: + * Enable DFLL reference clock if in closed loop mode. + * Depends on: + * + * BOARD_DFLL_SRCGCLKGEN - GCLK index + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(BOARD_GCLK_ENABLE) && defined(BOARD_DFLL_ENABLE) && \ + !defined(BOARD_DFLL_OPENLOOP) +static inline void sam_dfll_reference(void) +{ + uint16_t regval; + + /* Disabled the DFLL reference clock */ + + regval = GCLK_CLKCTRL_ID_DFLL48M; + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Wait for the clock to become disabled */ + + while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); + + /* Select the configured clock generator as the source for the DFLL + * reference clock. + * + * NOTE: We could enable write lock here to prevent further modification + */ + + regval = ((BOARD_DFLL_SRCGCLKGEN << GCLK_CLKCTRL_GEN_SHIFT) | + GCLK_CLKCTRL_ID_DFLL48M); + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* Enable the DFLL reference clock */ + + regval |= GCLK_CLKCTRL_CLKEN; + putreg16(regval, SAM_GCLK_CLKCTRL); + + /* The CLKCTRL.CLKEN bit must be synchronized to the generic clock domain. + * CLKCTRL.CLKEN will continue to read as its previous state until the + * synchronization is complete. + */ + + while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) == 0); +} +#else +# define sam_dfll_reference() +#endif + +/**************************************************************************** + * Name: sam_config_gclks + * + * Description: + * Configure GCLK(s) based on settings in the board.h header file. + * Depends on: + * + * Global enable/disable. + * + * BOARD_GCLK_ENABLE - Boolean (defined / not defined) + * + * For n=1-7: + * BOARD_GCLKn_ENABLE - Boolean (defined / not defined) + * + * For n=0-8: + * BOARD_GCLKn_RUN_IN_STANDBY - Boolean (defined / not defined) + * BOARD_GCLKn_CLOCK_SOURCE - See GCLK_GENCTRL_SRC_* definitions + * BOARD_GCLKn_PRESCALER - Value + * BOARD_GCLKn_OUTPUT_ENABLE - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_GCLK_ENABLE +static inline void sam_config_gclks(void) +{ + int i; + + /* Turn on the GCLK interface clock */ + + sam_gclk_enableperiph(); + + /* Reset the GCLK module */ + + putreg8(GCLK_CTRL_SWRST, SAM_GCLK_CTRL); + + /* Wait for the reset to complete */ + + while ((getreg8(SAM_GCLK_CTRL) & GCLK_CTRL_SWRST) != 0); + + /* Configure all GCLK generators, skipping GLCK_MAIN which is configured + * below. + */ + + for (i = 1; i < NGCLKS_ENABLED; i++) + { + sam_gclk_config(&g_gclkconfig[i]); + } + + /* Enable DFLL reference clock if the DFLL is enabled in closed loop mode */ + + sam_dfll_reference(); + + /* Configure the GCLK_MAIN last as it may depend on the DFLL or other + * generators + */ + + sam_gclk_config(&g_gclkconfig[0]); +} +#else +# define sam_config_gclks() +#endif + +/**************************************************************************** + * Name: sam_dividers + * + * Description: + * Setup PM main clock dividers to generate CPU, AHB, and APB clocks. + * Depends on: + * + * BOARD_CPU_DIVIDER - See PM_CPUSEL_CPUDIV_* definitions + * BOARD_CPU_FRQUENCY - In Hz + * BOARD_CPU_FAILDECT - Boolean (defined / not defined) + * BOARD_APBA_DIVIDER - See M_APBASEL_APBADIV_* definitions + * BOARD_APBA_FRQUENCY - In Hz + * BOARD_APBB_DIVIDER - See M_APBBSEL_APBBDIV_* definitions + * BOARD_APBB_FRQUENCY - In Hz + * BOARD_APBC_DIVIDER - See M_APBCSEL_APBCDIV_* definitions + * BOARD_APBC_FRQUENCY - In Hz + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_dividers(void) +{ +#ifdef PM_CTRL_CFDEN + uint8_t regval; +#endif + + /* Set the CPU divider using the divider value from the board.h header file */ + + putreg8(BOARD_CPU_DIVIDER, SAM_PM_CPUSEL); + +#ifdef PM_CTRL_CFDEN + /* Optionally, enable failure detection */ + + regval = getreg8(SAM_PM_CTRL); +#ifdef BOARD_CPU_FAILDECT + regval |= PM_CTRL_CFDEN; +#else + regval &= ~PM_CTRL_CFDEN; +#endif + putreg8(regval, SAM_PM_CTRL); +#endif + + /* Set the APBA, B, and C dividers */ + + putreg8(BOARD_APBA_DIVIDER, SAM_PM_APBASEL); + putreg8(BOARD_APBB_DIVIDER, SAM_PM_APBBSEL); + putreg8(BOARD_APBC_DIVIDER, SAM_PM_APBCSEL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_clockconfig(void) +{ + /* Clear pending interrupt status. */ + + putreg32(SYSCTRL_INT_ALL, SAM_SYSCTRL_INTFLAG); + + /* Set FLASH wait states */ + + sam_flash_waitstates(); + + /* Configure XOSC */ + + sam_xosc_config(); + + /* Configure XOSC32K */ + + sam_xosc32k_config(); + + /* Configure OSCK32K */ + + sam_osc32k_config(); + + /* Configure DFLL */ + + sam_dfll_config(); + + /* Configure OSC8M */ + + sam_osc8m_config(); + + /* Configure GCLK(s) */ + + sam_config_gclks(); + + /* Set CPU and BUS clock dividers */ + + sam_dividers(); +} + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21*/ diff --git a/arch/arm/src/samdl/samd_gclk.c b/arch/arm/src/samdl/samd_gclk.c new file mode 100644 index 0000000000000000000000000000000000000000..6a04ebf167f7df85bf4bc6266684568ee31d59a9 --- /dev/null +++ b/arch/arm/src/samdl/samd_gclk.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * arch/arm/src/samdl/samd_glck.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "sam_gclk.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gclck_waitsyncbusy + * + * Description: + * What until the SYNCBUSY bit is cleared. The SYNCBUSY bit was set when + * the synchronization of registers between clock domains is started. The + * SYNCBUSY bit is cleared when the synchronization of registers between + * the clock domains is complete. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_gclck_waitsyncbusy(void) +{ + while ((getreg8(SAM_GCLK_STATUS) & GCLK_STATUS_SYNCBUSY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gclk_config + * + * Description: + * Configure a single GCLK(s) based on settings in the config structure. + * + * Input Parameters: + * config - An instance of struct sam_gclkconfig describing the GCLK + * configuration. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_gclk_config(FAR const struct sam_gclkconfig_s *config) +{ + uint32_t genctrl; + uint32_t gendiv; + + /* Select the requested source clock for the generator */ + + genctrl = ((uint32_t)config->gclk << GCLK_GENCTRL_ID_SHIFT) | + ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT); + gendiv = ((uint32_t)config->gclk << GCLK_GENDIV_ID_SHIFT); + +#if 0 /* Not yet supported */ + /* Configure the clock to be either high or low when disabled */ + + if (config->level) + { + genctrl |= GCLK_GENCTRL_OOV; + } +#endif + + /* Configure if the clock output to I/O pin should be enabled */ + + if (config->output) + { + genctrl |= GCLK_GENCTRL_OE; + } + + /* Set the prescaler division factor */ + + if (config->prescaler > 1) + { + /* Check if division is a power of two */ + + if (((config->prescaler & (config->prescaler - 1)) == 0)) + { + /* Determine the index of the highest bit set to get the + * division factor that must be loaded into the division + * register. + */ + + uint32_t count = 0; + uint32_t mask; + + for (mask = 2; mask < (uint32_t)config->prescaler; mask <<= 1) + { + count++; + } + + /* Set binary divider power of 2 division factor */ + + gendiv |= count << GCLK_GENDIV_DIV_SHIFT; + genctrl |= GCLK_GENCTRL_DIVSEL; + } + else + { + /* Set integer division factor */ + + gendiv |= GCLK_GENDIV_DIV((uint32_t)config->prescaler); + + /* Enable non-binary division with increased duty cycle accuracy */ + + genctrl |= GCLK_GENCTRL_IDC; + } + } + + /* Enable or disable the clock in standby mode */ + + if (config->runstandby) + { + genctrl |= GCLK_GENCTRL_RUNSTDBY; + } + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(); + + /* Select the generator */ + + putreg32(((uint32_t)config->gclk << GCLK_GENDIV_ID_SHIFT), + SAM_GCLK_GENDIV); + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(); + + /* Write the new generator configuration */ + + putreg32(gendiv, SAM_GCLK_GENDIV); + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(); + + /* Enable the clock generator */ + + genctrl |= GCLK_GENCTRL_GENEN; + putreg32(genctrl, SAM_GCLK_GENCTRL); + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(); +} + +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ diff --git a/arch/arm/src/samdl/samd_periphclks.h b/arch/arm/src/samdl/samd_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..0ba3df0f879d10e4c79dc50a1e4c97bc5103dd4d --- /dev/null +++ b/arch/arm/src/samdl/samd_periphclks.h @@ -0,0 +1,266 @@ +/**************************************************************************** + * arch/arm/src/samdl/samd_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAMD_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMDL_SAMD_PERIPHCLKS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip/samd_pm.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define sam_apba_enableperiph(s) modifyreg32(SAM_PM_APBAMASK,0,s) + +#define sam_pac0_enableperiph() sam_apba_enableperiph(PM_APBAMASK_PAC0) +#define sam_pm_enableperiph() sam_apba_enableperiph(PM_APBAMASK_PM) +#define sam_sysctrl_enableperiph() sam_apba_enableperiph(PM_APBAMASK_SYSCTRL) +#define sam_gclk_enableperiph() sam_apba_enableperiph(PM_APBAMASK_GCLK) +#define sam_wdt_enableperiph() sam_apba_enableperiph(PM_APBAMASK_WDT) +#define sam_rtc_enableperiph() sam_apba_enableperiph(PM_APBAMASK_RTC) +#define sam_eic_enableperiph() sam_apba_enableperiph(PM_APBAMASK_EIC) + +#define sam_apbb_enableperiph(s) modifyreg32(SAM_PM_APBBMASK,0,s) + +#define sam_pac1_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_PAC1) +#define sam_dsu_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_DSU) +#define sam_nvmctrl_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_NVMCTRL) +#define sam_port_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_PORT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_dmac_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_DMAC) +# define sam_usb_enableperiph() sam_apbb_enableperiph(PM_APBBMASK_USB) +#endif + +#define sam_apbc_enableperiph(s) modifyreg32(SAM_PM_APBCMASK,0,s) + +#define sam_pac2_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_PAC2) +#define sam_devsys_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_EVSYS) +#define sam_sercom_enableperiph(n) sam_apbc_enableperiph(PM_APBCMASK_SERCOM(n)) +#define sam_sercom0_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM0) +#define sam_sercom1_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM1) +#define sam_sercom2_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM2) +#define sam_sercom3_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM3) +#define sam_sercom4_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM4) +#define sam_sercom5_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_SERCOM5) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define sam_tc0_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC0) +# define sam_tc1_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC1) +# define sam_tc2_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC2) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_tcc0_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TCC0) +# define sam_tcc1_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TCC1) +# define sam_tcc2_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TCC2) +#endif + +#define sam_tc3_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC3) +#define sam_tc4_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC4) +#define sam_tc5_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC5) +#define sam_tc6_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC6) +#define sam_tc7_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_TC7) +#define sam_adc_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_ADC) +#define sam_ac_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_AC) +#define sam_dac_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_DAC) +#define sam_ptc_enableperiph() sam_apbc_enableperiph(PM_APBCMASK_PTC) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_i2s_enableperiph() sam_apbc_enableperiph(PM_APBBMASK_I2S) +#endif + +#define sam_apba_disableperiph(s) modifyreg32(SAM_PM_APBAMASK,s,0) + +#define sam_pac0_disableperiph() sam_apba_disableperiph(PM_APBAMASK_PAC0) +#define sam_pm_disableperiph() sam_apba_disableperiph(PM_APBAMASK_PM) +#define sam_sysctrl_disableperiph() sam_apba_disableperiph(PM_APBAMASK_SYSCTRL) +#define sam_gclk_disableperiph() sam_apba_disableperiph(PM_APBAMASK_GCLK) +#define sam_wdt_disableperiph() sam_apba_disableperiph(PM_APBAMASK_WDT) +#define sam_rtc_disableperiph() sam_apba_disableperiph(PM_APBAMASK_RTC) +#define sam_eic_disableperiph() sam_apba_disableperiph(PM_APBAMASK_EIC) + +#define sam_apbb_disableperiph(s) modifyreg32(SAM_PM_APBBMASK,s,0) + +#define sam_pac1_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_PAC1) +#define sam_dsu_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_DSU) +#define sam_nvmctrl_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_NVMCTRL) +#define sam_port_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_PORT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_dmac_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_DMAC) +# define sam_usb_disableperiph() sam_apbb_disableperiph(PM_APBBMASK_USB) +#endif + +#define sam_apbc_disableperiph(s) modifyreg32(SAM_PM_APBCMASK,s,0) + +#define sam_pac2_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_PAC2) +#define sam_devsys_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_EVSYS) +#define sam_sercom_disableperiph(n) sam_apbc_disableperiph(PM_APBCMASK_SERCOM(n)) +#define sam_sercom0_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM0) +#define sam_sercom1_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM1) +#define sam_sercom2_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM2) +#define sam_sercom3_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM3) +#define sam_sercom4_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM4) +#define sam_sercom5_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_SERCOM5) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define sam_tc0_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC0) +# define sam_tc1_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC1) +# define sam_tc2_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC2) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_tcc0_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TCC0) +# define sam_tcc1_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TCC1) +# define sam_tcc2_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TCC2) +#endif + +#define sam_tc3_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC3) +#define sam_tc4_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC4) +#define sam_tc5_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC5) +#define sam_tc6_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC6) +#define sam_tc7_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_TC7) +#define sam_adc_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_ADC) +#define sam_ac_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_AC) +#define sam_dac_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_DAC) +#define sam_ptc_disableperiph() sam_apbc_disableperiph(PM_APBCMASK_PTC) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_i2s_disableperiph() sam_apbc_disableperiph(PM_APBBMASK_I2S) +#endif + +#define sam_apba_isenabled(s) (getreg32(SAM_PM_APBAMASK) & (s)) != 0) + +#define sam_pac0_isenabled() sam_apba_isenabled(PM_APBAMASK_PAC0) +#define sam_pm_isenabled() sam_apba_isenabled(PM_APBAMASK_PM) +#define sam_sysctrl_isenabled() sam_apba_isenabled(PM_APBAMASK_SYSCTRL) +#define sam_gclk_isenabled() sam_apba_isenabled(PM_APBAMASK_GCLK) +#define sam_wdt_isenabled() sam_apba_isenabled(PM_APBAMASK_WDT) +#define sam_rtc_isenabled() sam_apba_isenabled(PM_APBAMASK_RTC) +#define sam_eic_isenabled() sam_apba_isenabled(PM_APBAMASK_EIC) + +#define sam_apbb_isenabled(s) (getreg32(SAM_PM_APBBMASK) & (s)) != 0) + +#define sam_pac1_isenabled() sam_apbb_isenabled(PM_APBBMASK_PAC1) +#define sam_dsu_isenabled() sam_apbb_isenabled(PM_APBBMASK_DSU) +#define sam_nvmctrl_isenabled() sam_apbb_isenabled(PM_APBBMASK_NVMCTRL) +#define sam_port_isenabled() sam_apbb_isenabled(PM_APBBMASK_PORT) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_dmac_isenabled() sam_apbb_isenabled(PM_APBBMASK_DMAC) +# define sam_usb_isenabled() sam_apbb_isenabled(PM_APBBMASK_USB) +#endif + +#define sam_apbc_isenabled(s) (getreg32(SAM_PM_APBCMASK) & (s)) != 0) + +#define sam_pac2_isenabled() sam_apbc_isenabled(PM_APBCMASK_PAC2) +#define sam_devsys_isenabled() sam_apbc_isenabled(PM_APBCMASK_EVSYS) +#define sam_sercom_isenabled(n) sam_apbc_isenabled(PM_APBCMASK_SERCOM(n)) +#define sam_sercom0_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM0) +#define sam_sercom1_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM1) +#define sam_sercom2_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM2) +#define sam_sercom3_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM3) +#define sam_sercom4_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM4) +#define sam_sercom5_isenabled() sam_apbc_isenabled(PM_APBCMASK_SERCOM5) + +#ifdef CONFIG_ARCH_FAMILY_SAMD20 +# define sam_tc0_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC0) +# define sam_tc1_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC1) +# define sam_tc2_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC2) +#endif + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_tcc0_isenabled() sam_apbc_isenabled(PM_APBCMASK_TCC0) +# define sam_tcc1_isenabled() sam_apbc_isenabled(PM_APBCMASK_TCC1) +# define sam_tcc2_isenabled() sam_apbc_isenabled(PM_APBCMASK_TCC2) +#endif + +#define sam_tc3_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC3) +#define sam_tc4_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC4) +#define sam_tc5_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC5) +#define sam_tc6_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC6) +#define sam_tc7_isenabled() sam_apbc_isenabled(PM_APBCMASK_TC7) +#define sam_adc_isenabled() sam_apbc_isenabled(PM_APBCMASK_ADC) +#define sam_ac_isenabled() sam_apbc_isenabled(PM_APBCMASK_AC) +#define sam_dac_isenabled() sam_apbc_isenabled(PM_APBCMASK_DAC) +#define sam_ptc_isenabled() sam_apbc_isenabled(PM_APBCMASK_PTC) + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 +# define sam_i2s_isenabled() sam_apbc_isenabled(PM_APBBMASK_I2S) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_ARCH_FAMILY_SAMD20 || CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAMD_PERIPHCLKS_H */ diff --git a/arch/arm/src/samdl/saml_clockconfig.c b/arch/arm/src/samdl/saml_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..11dbaff10f665a9ca76986b6b475de5642f223f3 --- /dev/null +++ b/arch/arm/src/samdl/saml_clockconfig.c @@ -0,0 +1,1374 @@ +/**************************************************************************** + * arch/arm/src/samdl/saml_clockconfig.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * 1. "Atmel SAM L21E / SAM L21G / SAM L21J Smart ARM-Based Microcontroller + * Datasheet", Atmel-42385C-SAML21_Datasheet_Preliminary-03/20/15 + * 2. The SAMD20 samd_clockconfig.c file. See that file for additional + * references. + * 3. Atmel sample code for the SAML21. This code has an ASF license + * with is compatible with the NuttX BSD license, but includes the + * provision that this code not be used in non-Atmel products. That + * sample code was used only as a reference so I believe that only the + * NuttX BSD license applies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip/saml_pm.h" +#include "chip/saml_supc.h" +#include "chip/saml_oscctrl.h" +#include "chip/saml_osc32kctrl.h" +#include "chip/saml_gclk.h" +#include "chip/saml_nvmctrl.h" +#include "sam_gclk.h" + +#include + +#include "saml_periphclks.h" +#include "sam_clockconfig.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* BOARD_GCLK_ENABLE looks optional, but it is not */ + +#ifndef BOARD_GCLK_ENABLE +# warning BOARD_GCLK_ENABLE must be defined +# define BOARD_GCLK_ENABLE 1 +#endif + +/* Force enabling of the FDPLL reference clock */ + +#ifdef BOARD_FDPLL96M_ENABLE +# if BOARD_FDPLL96M_REFCLK == OSCCTRL_DPLLCTRLB_REFLCK_XOSC && \ + !defined(BOARD_XOSC_ENABLE) +# warning Forcing BOARD_XOSC_ENABLE for FDPLL96M +# define BOARD_XOSC_ENABLE 1 +# elif BOARD_FDPLL96M_REFCLK == OSCCTRL_DPLLCTRLB_REFLCK_XOSCK32K && \ + !defined(BOARD_XOSC32K_ENABLE) +# warning Forcing BOARD_XOSC32K_ENABLE for FDPLL96M +# define BOARD_XOSC32K_ENABLE 1 +# elif BOARD_FDPLL96M_REFCLK == OSCCTRL_DPLLCTRLB_REFLCK_GLCK && \ + !defined(BOARD_GCLK_ENABLE) +# warning Forcing BOARD_GCLK_ENABLE for FDPLL96M +# define BOARD_GCLK_ENABLE 1 +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline void sam_flash_waitstates(void); +static void sam_performance_level(uint8_t level); +#ifdef BOARD_XOSC_ENABLE +static inline void sam_xosc_config(void); +#endif +#ifdef BOARD_XOSC32K_ENABLE +static inline void sam_xosc32k_config(void); +#endif +#ifdef BOARD_OSC32K_ENABLE +static inline void sam_osc32k_config(void); +#endif +static inline void sam_osc16m_config(void); +#ifdef BOARD_DFLL48M_ENABLE +static inline void sam_dfll48m_config(void); +static inline void sam_dfll48m_enable(void); +#endif +#if defined(BOARD_GCLK_ENABLE) && defined(BOARD_DFLL48M_ENABLE) && \ + !defined(BOARD_DFLL48M_OPENLOOP) +static inline void sam_dfll48m_refclk(void); +#endif +#ifdef BOARD_FDPLL96M_ENABLE +static inline void sam_fdpll96m_config(void); +static inline void sam_fdpll96m_refclk(void); +#endif +#ifdef BOARD_GCLK_ENABLE +static inline void sam_config_gclks(void); +#endif +static inline void sam_cpu_dividers(void); +static inline void sam_periph_clocks(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This structure describes the configuration of every enabled GCLK */ + +#ifdef BOARD_GCLK_ENABLE +static const struct sam_gclkconfig_s g_gclkconfig[] = +{ + /* GCLK generator 0 (Main Clock) */ + + { + .gclk = 0, +#ifdef BOARD_GCLK0_RUN_IN_STANDBY + .runstandby = true, +#endif +#ifdef BOARD_GCLK0_OUTPUT_ENABLE + .output = true, +#endif + .prescaler = BOARD_GCLK0_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK0_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } + + /* GCLK generator 1 */ + +#ifdef BOARD_GCLK1_ENABLE + , + { + .gclk = 1, +#ifdef BOARD_GCLK1_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK1_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK1_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK1_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 2 (RTC) */ + +#ifdef BOARD_GCLK2_ENABLE + , + { + .gclk = 2, +#ifdef BOARD_GCLK2_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK2_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK2_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK2_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 3 */ + +#ifdef BOARD_GCLK3_ENABLE + , + { + .gclk = 3, +#ifdef BOARD_GCLK3_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK3_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK3_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK3_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 4 */ + +#ifdef BOARD_GCLK4_ENABLE + , + { + .gclk = 4, +#ifdef BOARD_GCLK4_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK4_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK4_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK4_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 5 */ + +#ifdef BOARD_GCLK5_ENABLE + , + { + .gclk = 5, +#ifdef BOARD_GCLK5_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK5_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK5_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK5_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 6 */ + +#ifdef BOARD_GCLK6_ENABLE + , + { + .gclk = 6, +#ifdef BOARD_GCLK6_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK6_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK6_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK6_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 7 */ + +#ifdef BOARD_GCLK7_ENABLE + , + { + .gclk = 7, +#ifdef BOARD_GCLK7_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK7_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK7_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK7_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif + + /* GCLK generator 8 */ + +#ifdef BOARD_GCLK8_ENABLE + , + { + .gclk = 8, +#ifdef BOARD_GCLK8_RUN_IN_STANDBY + .runstandby = true; +#endif +#ifdef BOARD_GCLK8_OUTPUT_ENABLE + .output = true; +#endif + .prescaler = BOARD_GCLK8_PRESCALER, + .clksrc = (uint8_t)(BOARD_GCLK8_CLOCK_SOURCE >> GCLK_GENCTRL_SRC_SHIFT), + } +#endif +}; + +#define NGCLKS_ENABLED (sizeof(g_gclkconfig) / sizeof(struct sam_gclkconfig_s)) +#endif + +/* These are temporary GLCK0 configuration that may be needed at power up */ + +static const struct sam_gclkconfig_s g_gclk0_default = +{ + .gclk = 0, + .prescaler = 1, + .clksrc = (uint8_t)(GCLK_GENCTRL_SRC_OSC16M >> GCLK_GENCTRL_SRC_SHIFT), +}; + +static const struct sam_gclkconfig_s g_gclk0_ulp32kconfig = +{ + .gclk = 0, + .prescaler = 1, + .clksrc = (uint8_t)(GCLK_GENCTRL_SRC_OSCULP32K >> GCLK_GENCTRL_SRC_SHIFT), +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_flash_waitstates + * + * Description: + * Set the FLASH wait states based on settings in the board.h header file + * Depends on: + * + * BOARD_FLASH_WAITSTATES - Number of wait states + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_flash_waitstates(void) +{ + uint32_t regval; + + /* Errate 13134: Correct the default value of the NVMCTRL.CTRLB.MANW bit */ + + regval = getreg32(SAM_NVMCTRL_CTRLB); + regval |= NVMCTRL_CTRLB_MANW; + putreg32(regval, SAM_NVMCTRL_CTRLB); + + /* Set the configured number of flash wait states */ + + regval &= ~NVMCTRL_CTRLB_RWS_MASK; + regval |= NVMCTRL_CTRLB_RWS(BOARD_FLASH_WAITSTATES); + putreg32(regval, SAM_NVMCTRL_CTRLB); +} + +/**************************************************************************** + * Name: sam_performance_level + * + * Description: + * "When scaling down the performance level, the bus frequency should be + * first scaled down in order to not exceed the maximum frequency allowed + * for the low performance level. + * + * "When scaling up the performance level (for example from PL0 to PL2), + * the bus frequency can be increased only once the performance level + * transition is completed, check the performance level status. + * + * Input Parameters: + * level - The new performance level + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_performance_level(uint8_t level) +{ + /* Check if we are already at this performance level */ + + if (level != (getreg8(SAM_PM_PLCFG) & PM_PLCFG_PLSEL_MASK)) + { + /* Clear performance level status and set the new performance level */ + + putreg8(PM_INT_PLRDY, SAM_PM_INTFLAG); + putreg8(level, SAM_PM_PLCFG); + + /* Wait for the new performance level to be ready */ + + while ((getreg16(SAM_PM_INTFLAG) & PM_INT_PLRDY) == 0); + } +} + +/**************************************************************************** + * Name: sam_xosc_config + * + * Description: + * Configure XOSC based on settings in the board.h header file + * Depends on: + * + * BOARD_XOSC_ENABLE - Boolean (defined / not defined) + * BOARD_XOSC_FREQUENCY - In Hz + * BOARD_XOSC_STARTUPTIME - See OSCCTRL_XOSCCTRL_STARTUP_* definitions + * BOARD_XOSC_ISCRYSTAL - Boolean (defined / not defined) + * BOARD_XOSC_AMPGC - Boolean (defined / not defined) + * BOARD_XOSC_ONDEMAND - Boolean (defined / not defined) + * BOARD_XOSC_RUNINSTANDBY - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_XOSC_ENABLE +static inline void sam_xosc_config(void) +{ + uint16_t regval; + + /* Configure the XOSC clock */ + + regval = getreg16(SAM_OSCCTRL_XOSCCTRL); + regval &= ~(OSCCTRL_XOSCCTRL_RUNSTDBY | OSCCTRL_XOSCCTRL_ONDEMAND | + OSCCTRL_XOSCCTRL_GAIN_MASK | OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_AMPGC | OSCCTRL_XOSCCTRL_STARTUP_MASK); + regval |= BOARD_XOSC_STARTUPTIME + +#ifdef BOARD_XOSC_ISCRYSTAL + /* XOSC is a crystal */ + + regval |= OSCCTRL_XOSCCTRL_XTALEN; +#endif + +#ifdef BOARD_XOSC_AMPGC + /* Enable automatic gain control */ + + regval |= OSCCTRL_XOSCCTRL_AMPGC; + +#else + /* Set gain if automatic gain control is not selected */ + +#if BOARD_XOSC_FREQUENCY <= 2000000 + regval |= OSCCTRL_XOSCCTRL_GAIN_2MHZ; +#elif BOARD_XOSC_FREQUENCY <= 4000000 + regval |= OSCCTRL_XOSCCTRL_GAIN_4MHZ; +#elif BOARD_XOSC_FREQUENCY <= 8000000 + regval |= OSCCTRL_XOSCCTRL_GAIN_8MHZ; +#elif BOARD_XOSC_FREQUENCY <= 16000000 + regval |= OSCCTRL_XOSCCTRL_GAIN_16MHZ; +#elif BOARD_XOSC_FREQUENCY <= 30000000 + regval |= OSCCTRL_XOSCCTRL_GAIN_30MHZ; +#else +# error BOARD_XOSC_FREQUENCY out of range +#endif +#endif /* BOARD_XOSC_AMPGC */ + +#ifdef BOARD_XOSC_ONDEMAND + regval |= OSCCTRL_XOSCCTRL_ONDEMAND; +#endif + +#ifdef BOARD_XOSC_RUNINSTANDBY + regval |= OSCCTRL_XOSCCTRL_RUNSTDBY; +#endif + + putreg16(regval, SAM_OSCCTRL_XOSCCTRL); + + /* Then enable the XOSC clock */ + + regval |= OSCCTRL_XOSCCTRL_ENABLE; + putreg16(regval, SAM_OSCCTRL_XOSCCTRL); +} +#else +# define sam_xosc_config() +#endif + +/**************************************************************************** + * Name: sam_xosc32k_config + * + * Description: + * Configure XOSC32K based on settings in the board.h header file. + * Depends on: + * + * BOARD_XOSC32K_ENABLE - Boolean (defined / not defined) + * BOARD_XOSC32K_FREQUENCY - In Hz + * BOARD_XOSC32K_STARTUPTIME - See OSC32KCTRL_XOSC32K_STARTUP_* definitions + * BOARD_XOSC32K_ISCRYSTAL - Boolean (defined / not defined) + * BOARD_XOSC32K_AAMPEN - Boolean (defined / not defined) + * BOARD_XOSC32K_EN1KHZ - Boolean (defined / not defined) + * BOARD_XOSC32K_EN32KHZ - Boolean (defined / not defined) + * BOARD_XOSC32K_ONDEMAND - Boolean (defined / not defined) + * BOARD_XOSC32K_RUNINSTANDBY - Boolean (defined / not defined) + * BOARD_XOSC32K_WRITELOCK - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_XOSC32K_ENABLE +static inline void sam_xosc32k_config(void) +{ + uint16_t regval; + + /* Configure XOSC32K (skipping the ONDEMANC SETTING until last) */ + + regval = getreg16(SAM_OSC32KCTRL_XOSC32K); + regval &= ~(OSC32KCTRL_XOSC32K_XTALEN | OSC32KCTRL_XOSC32K_EN32K | + OSC32KCTRL_XOSC32K_EN1K | OSC32KCTRL_XOSC32K_RUNSTDBY | + OSC32KCTRL_XOSC32K_ONDEMAND | OSC32KCTRL_XOSC32K_STARTUP_MASK | + OSC32KCTRL_XOSC32K_WRTLOCK); + regval |= BOARD_XOSC32K_STARTUPTIME; + +#ifdef BOARD_XOSC32K_ISCRYSTAL + regval |= OSC32KCTRL_XOSC32K_XTALEN; +#endif + +#ifdef BOARD_XOSC32K_EN1KHZ + regval |= OSC32KCTRL_XOSC32K_EN1K; +#endif + +#ifdef BOARD_XOSC32K_EN32KHZ + regval |= OSC32KCTRL_XOSC32K_EN32K; +#endif + +#ifdef BOARD_XOSC32K_RUNINSTANDBY + regval |= OSC32KCTRL_XOSC32K_RUNSTDBY; +#endif + + putreg16(regval, SAM_OSC32KCTRL_XOSC32K); + + /* Then enable the XOSC clock */ + + regval |= OSC32KCTRL_XOSC32K_ENABLE; + putreg16(regval, SAM_OSC32KCTRL_XOSC32K); + + /* Wait for XOSC32K to be ready */ + + while ((getreg32(SAM_OSC32KCTRL_STATUS) & OSC32KCTRL_INT_XOSC32KRDY) == 0); + +#ifdef BOARD_XOSC32K_ONDEMAND + /* Set the on-demand bit */ + + regval |= OSC32KCTRL_XOSC32K_ONDEMAND; + putreg16(regval, SAM_OSC32KCTRL_XOSC32K); +#endif + +#ifdef BOARD_XOSC32K_WRITELOCK + /* Lock this configuration until the next power up */ + + regval |= OSC32KCTRL_XOSC32K_WRTLOCK; + putreg16(regval, SAM_OSC32KCTRL_XOSC32K); +#endif +} +#else +# define sam_xosc32k_config() +#endif + +/**************************************************************************** + * Name: sam_osc32k_config + * + * Description: + * Configure OSC32K based on settings in the board.h header file. + * Depends on: + * + * BOARD_OSC32K_ENABLE - Boolean (defined / not defined) + * BOARD_OSC32K_FREQUENCY - In Hz + * BOARD_OSC32K_STARTUPTIME - See OSC32KCTRL_OSC32K_STARTUP_* definitions + * BOARD_OSC32K_EN1KHZ - Boolean (defined / not defined) + * BOARD_OSC32K_EN32KHZ - Boolean (defined / not defined) + * BOARD_OSC32K_ONDEMAND - Boolean (defined / not defined) + * BOARD_OSC32K_RUNINSTANDBY - Boolean (defined / not defined) + * BOARD_OSC32K_WRITELOCK - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_OSC32K_ENABLE +static inline void sam_osc32k_config(void) +{ + uint32_t regval; + + /* Configure OSC32K */ + + regval = getreg32(SAM_OSC32KCTRL_OSC32K); + regval &= ~(OSC32KCTRL_OSC32K_EN32K | OSC32KCTRL_OSC32K_EN1K | + OSC32KCTRL_OSC32K_RUNSTDBY | OSC32KCTRL_OSC32K_ONDEMAND | + OSC32KCTRL_OSC32K_STARTUP_MASK | OSC32KCTRL_OSC32K_WRTLOCK); + regval |= BOARD_OSC32K_STARTUPTIME; + +#ifdef BOARD_OSC32K_EN32KHZ + regval |= OSC32KCTRL_OSC32K_EN32K; +#endif + +#ifdef BOARD_OSC32K_EN1KHZ + regval |= OSC32KCTRL_OSC32K_EN1K; +#endif + +#ifdef BOARD_OSC32K_RUNINSTANDBY + regval |= OSC32KCTRL_OSC32K_RUNSTDBY; +#endif + +#ifdef BOARD_OSC32K_ONDEMAND + regval |= OSC32KCTRL_OSC32K_ONDEMAND; +#endif + + putreg32(regval, SAM_OSC32KCTRL_OSC32K); + + /* Then enable OSC32K */ + + regval |= OSC32KCTRL_OSC32K_ENABLE; + putreg32(regval, SAM_OSC32KCTRL_OSC32K); + +#ifdef BOARD_XOSC32K_WRITELOCK + /* Lock this configuration until the next power up */ + + regval |= OSC32KCTRL_OSC32K_WRTLOCK; + putreg16(regval, SAM_OSC32KCTRL_OSC32K); +#endif +} +#else +# define sam_osc32k_config() +#endif + +/**************************************************************************** + * Name: sam_osculp32k_config + * + * Description: + * Configure OSCULP32K + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define sam_osculp32k_config() + +/**************************************************************************** + * Name: sam_osc16m_config + * + * Description: + * Configure OSC16M based on settings in the board.h header file. + * Depends on: + * + * BOARD_OSC16M_FSEL - See OSCCTRL_OSC16MCTRL_FSEL_* definitions + * BOARD_OSC16M_ONDEMAND - Boolean (defined / not defined) + * BOARD_OSC16M_RUNINSTANDBY - Boolean (defined / not defined) + * + * On any reset the synchronous clocks start to their initial state: + * + * OSC16M is enabled and divided by 8 + * GCLK_MAIN uses OSC16M as source + * CPU and BUS clocks are undivided + * + * The reset state of the OSC16M register is: + * + * FFxx CCCC CCCC CCCC xxxx xxPP ORxx xxEx + * xx00 xxxx xxxx xxxx 0000 0011 1000 0010 + * + * FRANGE FF Loaded from FLASH calibration at startup + * CALIB CCC...C Loaded from FLASH calibration at startup + * PRESC PP 3 = Divide by 8 + * ONDEMAND O 1 + * RUNSTBY R 0 + * ENABLE 1 1 + * + * NOTE that since we are running from OSC16M, it cannot be disable! + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_osc16m_config(void) +{ + uint32_t regval; + bool enabled; + + /* After reset, OSC16M is enabled and serve4s as the default clock source + * at 4MHz. Since this particular logic only runs on reset, there is + * some additional unnecessary logic in the following. + */ + + /* Configure OSC16M */ + + regval = getreg32(SAM_OSCCTRL_OSC16MCTRL); + + /* Is OSC16M already enabled? Is it already running at the requested + * frequency? + */ + + enabled = ((regval & OSCCTRL_OSC16MCTRL_ENABLE) != 0); + if (enabled && (regval & OSCCTRL_OSC16MCTRL_FSEL_MASK) == BOARD_OSC16M_FSEL) + { + regval &= ~(OSCCTRL_OSC16MCTRL_ONDEMAND | OSCCTRL_OSC16MCTRL_RUNSTDBY); + +#ifdef BOARD_OSC16M_ONDEMAND + /* Select on-demand oscillator controls */ + + regval |= OSCCTRL_OSC16MCTRL_ONDEMAND; +#endif + +#ifdef BOARD_OSC16M_RUNINSTANDBY + /* The oscillator continues to run in standby sleep mode */ + + regval |= OSCCTRL_OSC16MCTRL_RUNSTDBY; +#endif + + /* Save the new OSC16M configuration */ + + putreg32(regval, SAM_OSCCTRL_OSC16MCTRL); + } + + /* Either the OSC16M is not running (which is not possible in this + * context) or else OSC16M is configured to run at a different frequency. + */ + + else + { + /* If it is enabled, then we are probably running on OSC16M now. + * Select OSCULP32K as new clock source for main clock temporarily. + * This depends on the fact the GCLK0 is enabled at reset. + */ + + if (enabled) + { + sam_gclk_config(&g_gclk0_ulp32kconfig); + + /* Disable OSC16M clock */ + + regval &= ~OSCCTRL_OSC16MCTRL_ENABLE; + putreg32(regval, SAM_OSCCTRL_OSC16MCTRL); + } + + /* Set the new OSC16M configuration */ + + regval &= ~(OSCCTRL_OSC16MCTRL_FSEL_MASK | OSCCTRL_OSC16MCTRL_RUNSTDBY | + OSCCTRL_OSC16MCTRL_ONDEMAND); + regval |= BOARD_OSC16M_FSEL; + +#ifdef BOARD_OSC16M_RUNINSTANDBY + /* The oscillator continues to run in standby sleep mode */ + + regval |= OSCCTRL_OSC16MCTRL_RUNSTDBY; +#endif + + /* Save the new OSC16M configuration */ + + putreg32(regval, SAM_OSCCTRL_OSC16MCTRL); + + /* Enable OSC16M */ + + regval |= OSCCTRL_OSC16MCTRL_ENABLE; + putreg32(regval, SAM_OSCCTRL_OSC16MCTRL); + + /* Wait for OSC16M to be ready */ + + while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_OSC16MRDY) == 0); + +#ifdef BOARD_OSC16M_ONDEMAND + /* Select on-demand oscillator controls */ + + regval |= OSCCTRL_OSC16MCTRL_ONDEMAND; + putreg32(regval, SAM_OSCCTRL_OSC16MCTRL); +#endif + + /* Re-select OSC16M for main clock again */ + + if (enabled) + { + sam_gclk_config(&g_gclk0_default); + } + } +} + +/**************************************************************************** + * Name: sam_dfll48m_config + * + * Description: + * Configure the DFLL48M based on settings in the board.h header file. + * Depends on: + * + * BOARD_DFLL48M_CLOSEDLOOP - Boolean (defined / not defined) + * BOARD_DFLL48M_OPENLOOP - Boolean (defined / not defined) + * BOARD_DFLL48M_RECOVERY - Boolean (defined / not defined) + * BOARD_DFLL48M_TRACKAFTERFINELOCK - Boolean (defined / not defined) + * BOARD_DFLL48M_KEEPLOCKONWAKEUP - Boolean (defined / not defined) + * BOARD_DFLL48M_ENABLECHILLCYCLE - Boolean (defined / not defined) + * BOARD_DFLL48M_QUICKLOCK - Boolean (defined / not defined) + * BOARD_DFLL48M_RUNINSTDBY - Boolean (defined / not defined) + * BOARD_DFLL48M_ONDEMAND - Boolean (defined / not defined) + * BOARD_DFLL48M_COARSEVALUE - Value + * BOARD_DFLL48M_FINEVALUE - Value + * + * Open Loop mode only: + * BOARD_DFLL48M_COARSEVALUE - Value + * BOARD_DFLL48M_FINEVALUE - Value + * + * Closed loop mode only: + * BOARD_DFLL48M_REFCLK_CLKGEN - GCLK index in the range {0..8} + * BOARD_DFLL48M_MULTIPLIER - Value + * BOARD_DFLL48M_MAXCOARSESTEP - Value + * BOARD_DFLL48M_MAXFINESTEP - Value + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_DFLL48M_ENABLE +static inline void sam_dfll48m_config(void) +{ + uint16_t control; + uint32_t regval; + + /* Disable ONDEMAND mode while writing configurations (Errata 9905). This + * is probably not necessary on the first time configuration after reset. + */ + + control = getreg16(SAM_OSCCTRL_DFLLCTRL); + control &= ~(OSCCTRL_DFLLCTRL_ENABLE | OSCCTRL_DFLLCTRL_ONDEMAND); + putreg16(control, SAM_OSCCTRL_DFLLCTRL); + + /* Wait for the DFLL to synchronize */ + + while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_DFLLRDY) == 0); + + /* Set up the DFLL control register */ + + control &= ~(OSCCTRL_DFLLCTRL_MODE | OSCCTRL_DFLLCTRL_STABLE | + OSCCTRL_DFLLCTRL_LLAW | OSCCTRL_DFLLCTRL_USBCRM | + OSCCTRL_DFLLCTRL_RUNSTDBY | OSCCTRL_DFLLCTRL_CCDIS | + OSCCTRL_DFLLCTRL_QLDIS | OSCCTRL_DFLLCTRL_BPLCKC | + OSCCTRL_DFLLCTRL_WAITLOCK); + +#if defined(BOARD_DFLL48M_CLOSEDLOOP) + control |= OSCCTRL_DFLLCTRL_MODE; /* Closed loop mode */ +#elif defined(BOARD_DFLL48M_RECOVERY) + control |= OSCCTRL_DFLLCTRL_USBCRM; /* USB clock recovery mode */ +#endif + +#ifndef BOARD_DFLL48M_TRACKAFTERFINELOCK + control |= OSCCTRL_DFLLCTRL_STABLE; /* FINE calibration fixed after a fine lock */ +#endif + +#ifndef BOARD_DFLL48M_KEEPLOCKONWAKEUP + control |= OSCCTRL_DFLLCTRL_LLAW; /* Lose lock after wake */ +#endif + +#ifdef BOARD_DFLL48M_RUNINSTDBY + control |= OSCCTRL_DFLLCTRL_RUNSTDBY; /* Run in standby */ +#endif + +#ifndef BOARD_DFLL48M_ENABLECHILLCYCLE + control |= OSCCTRL_DFLLCTRL_CCDIS; /* Chill cycle disable */ +#endif + +#ifndef BOARD_DFLL48M_QUICKLOCK + control |= OSCCTRL_DFLLCTRL_QLDIS; /* Quick lock disable */ +#endif + +#ifdef BOARD_DFLL48M_BPLCKC + control |= OSCCTRL_DFLLCTRL_BPLCKC; /* Bypass coarse clock */ +#endif + +#ifdef BOARD_DFLL48M_WAITLOCK + control |= OSCCTRL_DFLLCTRL_WAITLOCK; /* Wait lock */ +#endif + + /* Then enable the DFLL (with ONDEMAND set to zero). */ + + putreg16(control, SAM_OSCCTRL_DFLLCTRL); + + /* Wait for the DFLL to synchronize */ + + while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_DFLLRDY) == 0); + + /* Set up the open loop mode multiplier register */ + +#ifndef BOARD_DFLL48M_OPENLOOP + regval = OSCCTRL_DFLLMUL_CSTEP(BOARD_DFLL48M_MAXCOARSESTEP) | + OSCCTRL_DFLLMUL_FSTEP(BOARD_DFLL48M_MAXFINESTEP) | + OSCCTRL_DFLLMUL_MUL(BOARD_DFLL48M_MULTIPLIER); + putreg32(regval, SAM_OSCCTRL_DFLLMUL); +#else + putreg32(0, SAM_OSCCTRL_DFLLMUL); +#endif + + /* Set up the DFLL value register */ + + regval = OSCCTRL_DFLLVAL_COARSE(BOARD_DFLL48M_COARSEVALUE) | + OSCCTRL_DFLLVAL_FINE(BOARD_DFLL48M_FINEVALUE); + putreg32(regval, SAM_OSCCTRL_DFLLVAL); +} +#else +# define sam_dfll48m_config() +#endif + +/**************************************************************************** + * Name: sam_dfll48m_enable + * + * Description: + * Enable the DFLL48M. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_DFLL48M_ENABLE +static inline void sam_dfll48m_enable(void) +{ + uint16_t control; + + /* Enable the DFLL48M (with ONDEMAND still set to zero). */ + + control = getreg16(SAM_OSCCTRL_DFLLCTRL); + control |= OSCCTRL_DFLLCTRL_ENABLE; /* Enable the DFLL */ + putreg16(control, SAM_OSCCTRL_DFLLCTRL); + + /* Wait for the DFLL to synchronize */ + + while ((getreg32(SAM_OSCCTRL_STATUS) & OSCCTRL_INT_DFLLRDY) == 0); + + /* Finally, set the state of the ONDEMAND bit if necessary */ + +#ifdef BOARD_DFLL48M_ONDEMAND + control |= OSCCTRL_DFLLCTRL_ONDEMAND; /* On demand control */ + putreg16(control, SAM_OSCCTRL_DFLLCTRL); +#endif +} +#else +# define sam_dfll48m_enable() +#endif + +/**************************************************************************** + * Name: sam_dfll48m_refclk + * + * Description: + * Enable DFLL reference clock if in closed loop mode. + * Depends on: + * + * BOARD_DFLL48M_REFCLK_CLKGEN - GCLK index in the range {0..8} + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(BOARD_GCLK_ENABLE) && defined(BOARD_DFLL48M_ENABLE) && \ + !defined(BOARD_DFLL48M_OPENLOOP) +static inline void sam_dfll48m_refclk(void) +{ + sam_gclk_chan_enable(GCLK_CHAN_DFLL48M_REF, BOARD_DFLL48M_REFCLK_CLKGEN); +} +#else +# define sam_dfll48m_refclk() +#endif + +/**************************************************************************** + * Name: sam_fdpll96m_config + * + * Description: + * Configure and enable the DFLL based on settings in the board.h header + * file. + * Depends on: + * + * BOARD_FDPLL96M_ENABLE - Boolean (defined / not defined) + * BOARD_FDPLL96M_RUNINSTDBY - Boolean (defined / not defined) + * BOARD_FDPLL96M_ONDEMAND - Boolean (defined / not defined) + * BOARD_FDPLL96M_LBYPASS - Boolean (defined / not defined) + * BOARD_FDPLL96M_WUF - Boolean (defined / not defined) + * BOARD_FDPLL96M_LPEN - Boolean (defined / not defined) + * BOARD_FDPLL96M_FILTER - See OSCCTRL_DPLLCTRLB_FILTER_* definitions + * BOARD_FDPLL96M_REFCLK - See OSCCTRL_DPLLCTRLB_REFLCK_* definitions + * BOARD_FDPLL96M_LOCKTIME - See OSCCTRL_DPLLCTRLB_LTIME_* definitions + * BOARD_FDPLL96M_REFDIV - Numeric value, 1 - 2047 + * BOARD_FDPLL96M_PRESCALER - See OSCCTRL_DPLLPRESC_* definitions + * BOARD_FDPLL96M_REFFREQ - Numeric value + * BOARD_FDPLL96M_FREQUENCY - Numeric value + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_FDPLL96M_ENABLE +static inline void sam_fdpll96m_config(void) +{ + uint32_t ldr; + uint32_t refclk; + uint32_t regval; + uint8_t ldrfrac; + uint8_t ctrla; + + /* Get the reference clock frequency */ + + refclk = BOARD_FDPLL96M_REFFREQ; + +#if BOARD_FDPLL96M_REFCLK == OSCCTRL_DPLLCTRLB_REFLCK_XOSC + /* Only XOSC reference clock can be divided */ + + refclk = refclk / (2 * (BOARD_FDPLL96M_REFDIV + 1)); +#endif + + /* Calculate LDRFRAC and LDR */ + + ldr = (BOARD_FDPLL96M_FREQUENCY << 4) / refclk; + ldrfrac = (uint8_t)(ldr & 0x0f); + ldr = (ldr >> 4) - 1; + + /* Set DPLLCTRLA configuration (ut not the ONDEMAND bit) */ + + ctrla = 0; + +#ifdef BOARD_FDPLL96M_RUNINSTDBY + ctrla |= OSCCTRL_DPLLCTRLA_RUNSTDBY; +#endif + + putreg8(ctrla, SAM_OSCCTRL_DPLLCTRLA); + + /* Set the FDPLL96M ration register */ + + regval = OSCCTRL_DPLLRATIO_LDR(ldr) | OSCCTRL_DPLLRATIO_LDRFRAC(ldrfrac) + putreg32(reval, SAM_OSCCTRL_DPLLRATIO); + + /* Wait for synchronization */ + + while ((getreg8(SAM_OSCCTRL_DPLLSYNCBUSY) & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO) != 0); + + /* Set DPLLCTRLB configuration */ + + regval = BOARD_FDPLL96M_FILTER | BOARD_FDPLL96M_LOCKTIME | + BOARD_FDPLL96M_REFCLK | + OSCCTRL_DPLLCTRLB_DIV(BOARD_FDPLL96M_REFDIV); + +#ifdef BOARD_FDPLL96M_LBYPASS + regval |= OSCCTRL_DPLLCTRLB_LBYPASS; +#endif +#ifdef BOARD_FDPLL96M_WUF + regval |= OSCCTRL_DPLLCTRLB_WUF; +#endif +#ifdef BOARD_FDPLL96M_LPEN + regval |= OSCCTRL_DPLLCTRLB_LPEN; +#endif + + putreg8(regval, SAM_OSCCTRL_DPLLCTRLA); + + /* Set the prescaler value */ + + putreg8(BOARD_FDPLL96M_PRESCALER, SAM_ OSCCTRL_DPLLPRESC); + + /* Wait for synchronization */ + + while ((getreg8(SAM_OSCCTRL_DPLLSYNCBUSY) & OSCCTRL_DPLLSYNCBUSY_DPLLPRESC) != 0); + + /* Enable the FDPLL96M output */ + + ctrla |= OSCCTRL_DPLLCTRLA_ENABLE; + putreg8(ctrla, SAM_OSCCTRL_DPLLCTRLA); + + /* Wait for synchronization */ + + while ((getreg8(SAM_OSCCTRL_DPLLSYNCBUSY) & OSCCTRL_DPLLSYNCBUSY_ENABLE) != 0); + + /* Wait for the FPDLL96M to become locked and ready */ + + while ((getreg8(SAM_OSCCTRL_DPLLSTATUS) & + (OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK)) != + (OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK)); + +#ifdef BOARD_FDPLL96M_ONDEMAND + /* Now set the ONDEMAND bit if so configured */ + + ctrla |= OSCCTRL_DPLLCTRLA_ONDEMAND; + putreg8(ctrla, SAM_OSCCTRL_DPLLCTRLA); +#endif +} +#else +# define sam_fdpll96m_config() +#endif + +/**************************************************************************** + * Name: sam_fdpll96m_refclk + * + * Description: + * Enable FDPLL96M internal lock timer and reference clock. + * Depends on: + * + * BOARD_FDPLL96M_ENABLE - Boolean (defined / not defined) + * BOARD_FDPLL96M_REFCLK - See OSCCTRL_DPLLCTRLB_REFLCK_* definitions + * BOARD_FDPLL96M_REFCLK_CLKGEN - GCLK index in the range {0..8} + * BOARD_FDPLL96M_LOCKTIME_ENABLE - Boolean (defined / not defined) + * BOARD_FDPLL96M_LOCKTIME_CLKGEN - GCLK index in the range {0..8} + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(BOARD_GCLK_ENABLE) && defined(BOARD_FDPLL96M_ENABLE) +static inline void sam_fdpll96m_refclk(void) +{ +#ifdef BOARD_FDPLL96M_LOCKTIME_ENABLE + /* Enable the GCLK that is configured to the the FDPLL lock timer */ + + sam_gclk_chan_enable(GCLK_CHAN_DPLL_32K, BOARD_FDPLL96M_LOCKTIME_CLKGEN); +#endif + +#if BOARD_FDPLL96M_REFCLK == OSCCTRL_DPLLCTRLB_REFLCK_GLCK + /* Enable the GCLK that is configured to be the FDPLL reference clock */ + + sam_gclk_chan_enable(GCLK_CHAN_DPLL, BOARD_FDPLL96M_REFCLK_CLKGEN); +#endif +} +#else +# define sam_fdpll96m_refclk() +#endif + +/**************************************************************************** + * Name: sam_cpu_dividers + * + * Description: + * Setup PM main clock dividers to generate CPU and AHB. + * Depends on: + * + * BOARD_CPU_DIVIDER - See MCLK_CPUDIV_DIV* definitions + * BOARD_CPU_FRQUENCY - In Hz + * BOARD_CPU_FAILDECT - Boolean (defined / not defined) + * BOARD_LOWPOWER_DIVIDER - See MCLK_LPDIV_DIV_* definitions + * BOARD_LOWPOWER_FREQUENCY - In Hz + * BOARD_BACKUP_DIVIDER - See MCLK_BUPDIV_DIV_* definitions + * BOARD_BACKUP_FREQUENCY - In Hz + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_cpu_dividers(void) +{ + uint8_t regval; + + /* Set CPU divider and, optionally, enable failure detection */ + + putreg8(BOARD_CPU_DIVIDER, SAM_MCLK_CPUDIV); + + /* Enable/disabled clock failure detection */ + + regval = getreg8(SAM_MCLK_CTRLA); +#ifdef BOARD_CPU_FAILDECT + regval |= MCLK_CTRLA_CFDEN; +#else + regval &= ~MCLK_CTRLA_CFDEN; +#endif + putreg8(regval, SAM_MCLK_CTRLA); + + /* Setup up lower power and backup dividers */ + + putreg8(BOARD_LOWPOWER_DIVIDER, SAM_MCLK_LPDIV); + putreg8(BOARD_BACKUP_DIVIDER, SAM_MCLK_BUPDIV); +} + +/**************************************************************************** + * Name: sam_config_gclks + * + * Description: + * Configure GCLK(s) based on settings in the board.h header file. + * Depends on: + * + * Global enable/disable. + * + * BOARD_GCLK_ENABLE - *MUST* be defined + * + * For n=1-7: + * BOARD_GCLKn_ENABLE - Boolean (defined / not defined) + * + * For n=0-8: + * BOARD_GCLKn_RUN_IN_STANDBY - Boolean (defined / not defined) + * BOARD_GCLKn_CLOCK_SOURCE - See GCLK_GENCTRL_SRC_* definitions + * BOARD_GCLKn_PRESCALER - Value + * BOARD_GCLKn_OUTPUT_ENABLE - Boolean (defined / not defined) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef BOARD_GCLK_ENABLE +static inline void sam_config_gclks(void) +{ + int i; + + /* Turn on the GCLK interface clock */ + + sam_gclk_enableperiph(); + + /* Reset the GCLK module */ + + putreg8(GCLK_CTRLA_SWRST, SAM_GCLK_CTRLA); + + /* Wait for the reset to complete */ + + while ((getreg8(SAM_GCLK_CTRLA) & GCLK_CTRLA_SWRST) != 0); + + /* Configure all GCLK generators, skipping GLCK_MAIN which is configured + * below. + */ + + for (i = 1; i < NGCLKS_ENABLED; i++) + { + sam_gclk_config(&g_gclkconfig[i]); + } +} +#else +# define sam_config_gclks() +#endif + +/**************************************************************************** + * Name: sam_periph_clocks + * + * Description: + * Setup initial peripheral clocking: + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_periph_clocks(void) +{ +#warning Missing logic +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_clockconfig(void) +{ + /* Clear pending interrupt status. */ + + putreg32(OSCCTRL_INT_ALL, SAM_OSCCTRL_INTFLAG); + putreg32(OSC32KCTRL_INT_ALL, SAM_OSC32KCTRL_INTFLAG); + putreg32(SUPC_INT_ALL, SAM_SUPC_INTFLAG); + + /* Set FLASH wait states */ + + sam_flash_waitstates(); + + /* Switch to PL2 to be sure configuration of GCLK0 is safe */ + + sam_performance_level(PM_PLCFG_PLSEL_PL2); + + /* Configure XOSC */ + + sam_xosc_config(); + + /* Configure XOSC32K */ + + sam_xosc32k_config(); + + /* Configure OSCK32K */ + + sam_osc32k_config(); + + /* Configure OSCULPK32K */ + + sam_osculp32k_config(); + + /* Configure OSC16M */ + + sam_osc16m_config(); + + /* Configure DFLL48M */ + + sam_dfll48m_config(); + + /* Configure GCLK(s) */ + + sam_config_gclks(); + + /* Enable DFLL reference clock if the DFLL is enabled in closed loop mode */ + + sam_dfll48m_refclk(); + + /* Enable DFLL48M */ + + sam_dfll48m_enable(); + + /* Enable FDPLL reference clock if the DFLL is enabled */ + + sam_fdpll96m_refclk(); + + /* Configure and enable FDPLL96M */ + + sam_fdpll96m_config(); + + /* Setup CPU and BUS clocks */ + + sam_cpu_dividers(); + + /* Configure the GCLK_MAIN last as it may depend on the DFLL, FDPLL or + * other generators + */ + + sam_gclk_config(&g_gclkconfig[0]); + +#if BOARD_CPU_FREQUENCY <= 12000000 + /* If CPU frequency is less than 12MHz, scale down performance level to + * PL0. + */ + + sam_performance_level(PM_PLCFG_PLSEL_PL0); +#endif + + /* Set up initial peripheral clocking */ + + sam_periph_clocks(); +} + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ diff --git a/arch/arm/src/samdl/saml_gclk.c b/arch/arm/src/samdl/saml_gclk.c new file mode 100644 index 0000000000000000000000000000000000000000..afab80fbdfdcef9acb1522811f89b4ec00442c9b --- /dev/null +++ b/arch/arm/src/samdl/saml_gclk.c @@ -0,0 +1,296 @@ +/**************************************************************************** + * arch/arm/src/samdl/saml_glck.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "sam_gclk.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gclck_waitsyncbusy + * + * Description: + * What until the SYNCBUSY bit is cleared. The SYNCBUSY bit was set when + * the synchronization of registers between clock domains is started. The + * SYNCBUSY bit is cleared when the synchronization of registers between + * the clock domains is complete. + * + * Input Parameters: + * glck - GCLK clock index + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_gclck_waitsyncbusy(uint8_t gclk) +{ + uintptr_t gclkbit = GCLK_SYNCHBUSY_GENCTRL(gclk); + while ((getreg8(SAM_GCLK_SYNCHBUSY) & gclkbit) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gclk_config + * + * Description: + * Configure a single GCLK(s) based on settings in the config structure. + * + * Input Parameters: + * config - An instance of struct sam_gclkconfig describing the GCLK + * configuration. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_gclk_config(FAR const struct sam_gclkconfig_s *config) +{ + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + uint32_t genctrl; + + /* Select the requested source clock for the generator */ + + genctrl = ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT); + +#if 0 /* Not yet supported */ + /* Configure the clock to be either high or low when disabled */ + + if (config->level) + { + genctrl |= GCLK_GENCTRL_OOV; + } +#endif + + /* Configure if the clock output to I/O pin should be enabled */ + + if (config->output) + { + genctrl |= GCLK_GENCTRL_OE; + } + + /* Set the prescaler division factor */ + + if (config->prescaler > 1) + { + /* Check if division is a power of two */ + + if (((config->prescaler & (config->prescaler - 1)) == 0)) + { + /* Determine the index of the highest bit set to get the + * division factor that must be loaded into the division + * register. + */ + + uint32_t count = 0; + uint32_t mask; + + for (mask = 2; mask < (uint32_t)config->prescaler; mask <<= 1) + { + count++; + } + + /* Set binary divider power of 2 division factor */ + + genctrl |= count << GCLK_GENCTRL_DIV_SHIFT; + genctrl |= GCLK_GENCTRL_DIVSEL; + } + else + { + /* Set integer division factor */ + + genctrl |= GCLK_GENCTRL_DIV((uint32_t)config->prescaler); + + /* Enable non-binary division with increased duty cycle accuracy */ + + genctrl |= GCLK_GENCTRL_IDC; + } + } + + /* Enable or disable the clock in standby mode */ + + if (config->runstandby) + { + genctrl |= GCLK_GENCTRL_RUNSTDBY; + } + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(config->gclk); + + /* Preserve the GENEN bit */ + + regaddr = SAM_GCLK_GENCTRL(config->gclk); + + flags = enter_critical_section(); + regval = getreg32(regaddr); + regval &= GCLK_GENCTRL_GENEN; + genctrl |= regval; + + /* Configure the generator */ + + putreg32(genctrl, regaddr); + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(config->gclk); + leave_critical_section(flags); + sam_gclck_waitsyncbusy(config->gclk); + + /* Enable the clock generator */ + + flags = enter_critical_section(); + genctrl |= GCLK_GENCTRL_GENEN; + putreg32(genctrl, regaddr); + + /* Wait for synchronization */ + + sam_gclck_waitsyncbusy(config->gclk); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_gclk_chan_enable + * + * Description: + * Configure and enable a GCLK peripheral channel. + * + * Input Parameters: + * channel - Index of the GCLK channel to be enabled + * srcgen - The GCLK source generator index + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen) +{ + irqstate_t flags; + uint32_t regaddr; + uint32_t regval; + + /* Get the address of the peripheral channel control register */ + + regaddr = SAM_GCLK_PCHCTRL(channel); + + /* Disable generic clock channel */ + + flags = enter_critical_section(); + sam_gclk_chan_disable(channel); + + /* Configure the peripheral channel */ + + regval = GCLK_PCHCTRL_GEN(srcgen); + putreg32(regval, regaddr); + + /* Enable the peripheral channel */ + + regval |= GCLK_PCHCTRL_CHEN; + putreg32(regval, regaddr); + + /* Wait for clock synchronization */ + + while ((getreg32(regaddr) &GCLK_PCHCTRL_CHEN) == 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_gclk_chan_disable + * + * Description: + * Disable a GCLK peripheral channel. + * + * Input Parameters: + * channel - Index of the GCLK channel to be disabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_gclk_chan_disable(uint8_t channel) +{ + irqstate_t flags; + uint32_t regaddr; + uint32_t regval; + + /* Get the address of the peripheral channel control register */ + + regaddr = SAM_GCLK_PCHCTRL(channel); + + /* Disable generic clock channel */ + + flags = enter_critical_section(); + regval = getreg32(regaddr); + regval &= ~GCLK_PCHCTRL_CHEN; + putreg32(regval, regaddr); + + /* Wait for clock synchronization */ + + while ((getreg32(regaddr) &GCLK_PCHCTRL_CHEN) != 0); + leave_critical_section(flags); +} + +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ diff --git a/arch/arm/src/samdl/saml_periphclks.h b/arch/arm/src/samdl/saml_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..eb9f434754ebb003da01f4679bdb85270e09fc74 --- /dev/null +++ b/arch/arm/src/samdl/saml_periphclks.h @@ -0,0 +1,299 @@ +/**************************************************************************** + * arch/arm/src/samdl/saml_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAML_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMDL_SAML_PERIPHCLKS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip/saml_mclk.h" + +#ifdef CONFIG_ARCH_FAMILY_SAML21 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define sam_ahb_enableperiph(s) modifyreg32(SAM_MCLK_AHBMASK,0,s) + +#if 0 /* Not used, conflicting names */ +#define sam_apba_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_APBA) +#define sam_apbb_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_APBB) +#define sam_apbc_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_APBC) +#define sam_apbd_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_APBD) +#define sam_apbe_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_APBE) +#define sam_dsu_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_DSU) +#define sam_nvmctrl_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_NVMCTRL) +#endif +#define sam_dmac_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_DMAC) +#if 0 /* Not used, conflicting names */ +#define sam_usb_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_USB) +#define sam_pac_enableperiph() sam_ahb_enableperiph(MCLK_AHBMASK_PAC) +#endif + +#define sam_apba_enableperiph(s) modifyreg32(SAM_MCLK_APBAMASK,0,s) + +#define sam_pm_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_PM) +#define sam_mclk_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_MCLK) +#define sam_rstc_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_RSTC) +#define sam_oscctrl_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_OSCCTRL) +#define sam_osc32kctrl_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_OSC32KCTRL) +#define sam_supc_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_SUPC) +#define sam_gclk_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_GCLK) +#define sam_wdt_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_WDT) +#define sam_rtc_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_RTC) +#define sam_eic_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_EIC) +#define sam_port_enableperiph() sam_apba_enableperiph(MCLK_APBAMASK_PORT) + +#define sam_apbb_enableperiph(s) modifyreg32(SAM_MCLK_APBBMASK,0,s) + +#define sam_usb_enableperiph() sam_apbb_enableperiph(MCLK_APBBMASK_USB) +#define sam_dsu_enableperiph() sam_apbb_enableperiph(MCLK_APBBMASK_DSU) +#define sam_nvmctrl_enableperiph() sam_apbb_enableperiph(MCLK_APBBMASK_NVMCTRL) + +#define sam_apbc_enableperiph(s) modifyreg32(SAM_MCLK_APBCMASK,0,s) + +#define sam_sercom_enableperiph(n) sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM(n)) +#define sam_sercom0_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM0) +#define sam_sercom1_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM1) +#define sam_sercom2_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM2) +#define sam_sercom3_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM3) +#define sam_sercom4_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_SERCOM4) +#define sam_tcc0_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TCC0) +#define sam_tcc1_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TCC1) +#define sam_tcc2_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TCC2) +#define sam_tc0_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TC0) +#define sam_tc1_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TC1) +#define sam_tc2_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TC2) +#define sam_tc3_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TC3) +#define sam_dac_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_DAC) +#define sam_aes_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_AES) +#define sam_trng_enableperiph() sam_apbc_enableperiph(MCLK_APBCMASK_TRNG) + +#define sam_apbd_enableperiph(s) modifyreg32(SAM_MCLK_APBDMASK,0,s) + +#define sam_evsys_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_EVSYS) +#define sam_sercom5_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_SERCOM5) +#define sam_tc4_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_TC4) +#define sam_adc_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_ADC) +#define sam_ac_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_AC) +#define sam_ptc_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_PTC) +#define sam_opamp_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_OPAMP) +#define sam_ccl_enableperiph() sam_apbd_enableperiph(MCLK_APBDMASK_CCL) + +#define sam_apbe_enableperiph(s) modifyreg32(SAM_MCLK_APBEMASK,0,s) + +#define sam_pac_enableperiph() sam_apbe_enableperiph(MCLK_APBEMASK_PAC) + +#define sam_ahb_disableperiph(s) modifyreg32(SAM_MCLK_AHBMASK,s,0) + +#if 0 /* Not used, conflicting names */ +#define sam_apba_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_APBA) +#define sam_apbb_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_APBB) +#define sam_apbc_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_APBC) +#define sam_apbd_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_APBD) +#define sam_apbe_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_APBE) +#define sam_dsu_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_DSU) +#define sam_nvmctrl_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_NVMCTRL) +#endif +#define sam_dmac_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_DMAC) +#if 0 /* Not used, conflicting names */ +#define sam_usb_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_USB) +#define sam_pac_disableperiph() sam_ahb_disableperiph(MCLK_AHBMASK_PAC) +#endif + +#define sam_apba_disableperiph(s) modifyreg32(SAM_MCLK_APBAMASK,s,0) + +#define sam_pm_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_PM) +#define sam_mclk_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_MCLK) +#define sam_rstc_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_RSTC) +#define sam_oscctrl_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_OSCCTRL) +#define sam_osc32kctrl_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_OSC32KCTRL) +#define sam_supc_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_SUPC) +#define sam_gclk_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_GCLK) +#define sam_wdt_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_WDT) +#define sam_rtc_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_RTC) +#define sam_eic_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_EIC) +#define sam_port_disableperiph() sam_apba_disableperiph(MCLK_APBAMASK_PORT) + +#define sam_apbb_disableperiph(s) modifyreg32(SAM_MCLK_APBBMASK,s,0) + +#define sam_usb_disableperiph() sam_apbb_disableperiph(MCLK_APBBMASK_USB) +#define sam_dsu_disableperiph() sam_apbb_disableperiph(MCLK_APBBMASK_DSU) +#define sam_nvmctrl_disableperiph() sam_apbb_disableperiph(MCLK_APBBMASK_NVMCTRL) + +#define sam_apbc_disableperiph(s) modifyreg32(SAM_MCLK_APBCMASK,s,0) + +#define sam_sercom_disableperiph(n) sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM(n)) +#define sam_sercom0_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM0) +#define sam_sercom1_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM1) +#define sam_sercom2_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM2) +#define sam_sercom3_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM3) +#define sam_sercom4_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_SERCOM4) +#define sam_tcc0_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TCC0) +#define sam_tcc1_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TCC1) +#define sam_tcc2_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TCC2) +#define sam_tc0_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TC0) +#define sam_tc1_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TC1) +#define sam_tc2_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TC2) +#define sam_tc3_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TC3) +#define sam_dac_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_DAC) +#define sam_aes_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_AES) +#define sam_trng_disableperiph() sam_apbc_disableperiph(MCLK_APBCMASK_TRNG) + +#define sam_apbd_disableperiph(s) modifyreg32(SAM_MCLK_APBDMASK,s,0) + +#define sam_evsys_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_EVSYS) +#define sam_sercom5_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_SERCOM5) +#define sam_tc4_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_TC4) +#define sam_adc_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_ADC) +#define sam_ac_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_AC) +#define sam_ptc_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_PTC) +#define sam_opamp_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_OPAMP) +#define sam_ccl_disableperiph() sam_apbd_disableperiph(MCLK_APBDMASK_CCL) + +#define sam_apbe_disableperiph(s) modifyreg32(SAM_MCLK_APBEMASK,s,0) + +#define sam_pac_disableperiph() sam_apbe_disableperiph(MCLK_APBEMASK_PAC) + +#define sam_ahb_isenabled(s) (getreg32(SAM_MCLK_AHBMASK) & (s)) != 0) + +#if 0 /* Not used, conflicting names */ +#define sam_apba_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_APBA) +#define sam_apbb_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_APBB) +#define sam_apbc_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_APBC) +#define sam_apbd_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_APBD) +#define sam_apbe_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_APBE) +#define sam_dsu_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_DSU) +#define sam_nvmctrl_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_NVMCTRL) +#endif +#define sam_dmac_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_DMAC) +#if 0 /* Not used, conflicting names */ +#define sam_usb_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_USB) +#define sam_pac_isenabled() sam_ahb_isenabled(MCLK_AHBMASK_PAC) +#endif + +#define sam_apba_isenabled(s) (getreg32(SAM_MCLK_APBAMASK) & (s)) != 0) + +#define sam_pm_isenabled() sam_apba_isenabled(MCLK_APBAMASK_PM) +#define sam_mclk_isenabled() sam_apba_isenabled(MCLK_APBAMASK_MCLK) +#define sam_rstc_isenabled() sam_apba_isenabled(MCLK_APBAMASK_RSTC) +#define sam_oscctrl_isenabled() sam_apba_isenabled(MCLK_APBAMASK_OSCCTRL) +#define sam_osc32kctrl_isenabled() sam_apba_isenabled(MCLK_APBAMASK_OSC32KCTRL) +#define sam_supc_isenabled() sam_apba_isenabled(MCLK_APBAMASK_SUPC) +#define sam_gclk_isenabled() sam_apba_isenabled(MCLK_APBAMASK_GCLK) +#define sam_wdt_isenabled() sam_apba_isenabled(MCLK_APBAMASK_WDT) +#define sam_rtc_isenabled() sam_apba_isenabled(MCLK_APBAMASK_RTC) +#define sam_eic_isenabled() sam_apba_isenabled(MCLK_APBAMASK_EIC) +#define sam_port_isenabled() sam_apba_isenabled(MCLK_APBAMASK_PORT) + +#define sam_apbb_isenabled(s) (getreg32(SAM_MCLK_APBBMASK) & (s)) != 0) + +#define sam_usb_isenabled() sam_apbb_isenabled(MCLK_APBBMASK_USB) +#define sam_dsu_isenabled() sam_apbb_isenabled(MCLK_APBBMASK_DSU) +#define sam_nvmctrl_isenabled() sam_apbb_isenabled(MCLK_APBBMASK_NVMCTRL) + +#define sam_apbc_isenabled(s) (getreg32(SAM_MCLK_APBCMASK) & (s)) != 0) + +#define sam_sercom_isenabled(n) sam_apbc_isenabled(MCLK_APBCMASK_SERCOM(n)) +#define sam_sercom0_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_SERCOM0) +#define sam_sercom1_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_SERCOM1) +#define sam_sercom2_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_SERCOM2) +#define sam_sercom3_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_SERCOM3) +#define sam_sercom4_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_SERCOM4) +#define sam_tcc0_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TCC0) +#define sam_tcc1_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TCC1) +#define sam_tcc2_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TCC2) +#define sam_tc0_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TC0) +#define sam_tc1_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TC1) +#define sam_tc2_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TC2) +#define sam_tc3_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TC3) +#define sam_dac_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_DAC) +#define sam_aes_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_AES) +#define sam_trng_isenabled() sam_apbc_isenabled(MCLK_APBCMASK_TRNG) + +#define sam_apbd_isenabled(s) (getreg32(SAM_MCLK_APBDMASK) & (s)) != 0) + +#define sam_evsys_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_EVSYS) +#define sam_sercom5_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_SERCOM5) +#define sam_tc4_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_TC4) +#define sam_adc_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_ADC) +#define sam_ac_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_AC) +#define sam_ptc_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_PTC) +#define sam_opamp_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_OPAMP) +#define sam_ccl_isenabled() sam_apbd_isenabled(MCLK_APBDMASK_CCL) + +#define sam_apbe_isenabled(s) (getreg32(SAM_MCLK_APBEMASK) & (s)) != 0) + +#define sam_pac_isenabled() sam_apbe_isenabled(MCLK_APBEMASK_PAC) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_ARCH_FAMILY_SAML21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_SAML_PERIPHCLKS_H */ diff --git a/arch/arm/src/samv7/Kconfig b/arch/arm/src/samv7/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4af53ac0985778cb8c6a65948793f14b77f71b26 --- /dev/null +++ b/arch/arm/src/samv7/Kconfig @@ -0,0 +1,2509 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_SAMV7 + +comment "SAMV7 Configuration Options" + +# Chip Selection + +choice + prompt "Atmel SAMV7 Chip Selection" + default ARCH_CHIP_SAMV71Q21 + +config ARCH_CHIP_SAME70Q19 + bool "SAME70Q19" + select ARCH_CHIP_SAME70Q + +config ARCH_CHIP_SAME70Q20 + bool "SAME70Q20" + select ARCH_CHIP_SAME70Q + +config ARCH_CHIP_SAME70Q21 + bool "SAME70Q21" + select ARCH_CHIP_SAME70Q + +config ARCH_CHIP_SAME70N19 + bool "SAME70N10" + select ARCH_CHIP_SAME70N + +config ARCH_CHIP_SAME70N20 + bool "SAME70N20" + select ARCH_CHIP_SAME70N + +config ARCH_CHIP_SAME70N21 + bool "SAME70N21" + select ARCH_CHIP_SAME70N + +config ARCH_CHIP_SAME70J19 + bool "SAME70J10" + select ARCH_CHIP_SAME70J + +config ARCH_CHIP_SAME70J20 + bool "SAME70J20" + select ARCH_CHIP_SAME70J + +config ARCH_CHIP_SAME70J21 + bool "SAME70J21" + select ARCH_CHIP_SAME70J + +config ARCH_CHIP_SAMV71Q19 + bool "SAMV71Q19" + select ARCH_CHIP_SAMV71Q + +config ARCH_CHIP_SAMV71Q20 + bool "SAMV71Q20" + select ARCH_CHIP_SAMV71Q + +config ARCH_CHIP_SAMV71Q21 + bool "SAMV71Q21" + select ARCH_CHIP_SAMV71Q + +config ARCH_CHIP_SAMV71N19 + bool "SAMV71N19" + select ARCH_CHIP_SAMV71N + +config ARCH_CHIP_SAMV71N20 + bool "SAMV71N20" + select ARCH_CHIP_SAMV71N + +config ARCH_CHIP_SAMV71N21 + bool "SAMV71N21" + select ARCH_CHIP_SAMV71N + +config ARCH_CHIP_SAMV71J19 + bool "SAMV71J19" + select ARCH_CHIP_SAMV71J + +config ARCH_CHIP_SAMV71J20 + bool "SAMV71J20" + select ARCH_CHIP_SAMV71J + +config ARCH_CHIP_SAMV71J21 + bool "SAMV71J21" + select ARCH_CHIP_SAMV71J + +endchoice # Atmel SAMV7 Chip Selection + +config ARCH_CHIP_SAME70 + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +config ARCH_CHIP_SAME70Q + bool + default n + select ARCH_CHIP_SAME70 + select SAMV7_HAVE_MCAN1 + select SAMV7_HAVE_DAC1 + select SAMV7_HAVE_EBI + select SAMV7_HAVE_HSMCI0 + select SAMV7_HAVE_SDRAMC + select SAMV7_HAVE_SPI0 + select SAMV7_HAVE_SPI1 + select SAMV7_HAVE_TWIHS2 + select SAMV7_HAVE_USBHS + select SAMV7_HAVE_USART0 + select SAMV7_HAVE_USART1 + select SAMV7_HAVE_USART2 + +config ARCH_CHIP_SAME70N + bool + default n + select ARCH_CHIP_SAME70 + select SAMV7_HAVE_MCAN1 + select SAMV7_HAVE_DAC1 + select SAMV7_HAVE_HSMCI0 + select SAMV7_HAVE_SPI0 + select SAMV7_HAVE_TWIHS2 + select SAMV7_HAVE_USBHS + select SAMV7_HAVE_USART0 + select SAMV7_HAVE_USART1 + select SAMV7_HAVE_USART2 + +config ARCH_CHIP_SAME70J + bool + default n + select ARCH_CHIP_SAME70 + select SAMV7_QSPI_IS_SPI + select SAMV7_HAVE_USBFS + select SAMV7_HAVE_ISI8 + +config ARCH_CHIP_SAMV71 + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + select SAMV7_HAVE_MEDIALB + +config ARCH_CHIP_SAMV71Q + bool + default n + select ARCH_CHIP_SAMV71 + select SAMV7_HAVE_MCAN1 + select SAMV7_HAVE_DAC1 + select SAMV7_HAVE_EBI + select SAMV7_HAVE_HSMCI0 + select SAMV7_HAVE_SDRAMC + select SAMV7_HAVE_SPI0 + select SAMV7_HAVE_SPI1 + select SAMV7_HAVE_TWIHS2 + select SAMV7_HAVE_USBHS + select SAMV7_HAVE_USART0 + select SAMV7_HAVE_USART1 + select SAMV7_HAVE_USART2 + +config ARCH_CHIP_SAMV71N + bool + default n + select ARCH_CHIP_SAMV71 + select SAMV7_HAVE_MCAN1 + select SAMV7_HAVE_DAC1 + select SAMV7_HAVE_HSMCI0 + select SAMV7_HAVE_SPI0 + select SAMV7_HAVE_TWIHS2 + select SAMV7_HAVE_USBHS + select SAMV7_HAVE_USART0 + select SAMV7_HAVE_USART1 + select SAMV7_HAVE_USART2 + +config ARCH_CHIP_SAMV71J + bool + default n + select ARCH_CHIP_SAMV71 + select SAMV7_QSPI_IS_SPI + select SAMV7_HAVE_USBFS + select SAMV7_HAVE_ISI8 + +# Chip Capabilities + +config SAMV7_MCAN + bool + default n + +config SAMV7_HAVE_MCAN1 + bool + default n + +config SAMV7_HAVE_DAC1 + bool + default n + +config SAMV7_HAVE_EBI + bool + default n + +config SAMV7_EMAC + bool + default n + select ARMV7M_DCACHE_WRITETHROUGH if ARMV7M_DCACHE + select ARCH_HAVE_NETDEV_STATISTICS + ---help--- + NOTE that write-through caching is automatically selected. This is + to work around issues with the RX and TX descriptors with are 8-bytes + in size. But the D-Cache cache line size is 32-bytes. That means + that you cannot reload, clean or invalidate a descriptor without also + effecting three neighboring descriptors. Setting write through mode + eliminates the need for cleaning. If only reloading and invalidating + are done, then there is no problem. + +config SAMV7_HSMCI + bool + default n + +config SAMV7_HAVE_HSMCI0 + bool + default n + +config SAMV7_HAVE_ISI8 + bool + default n + +config SAMV7_HAVE_MEDIALB + bool + default n + +config SAMV7_HAVE_SDRAMC + bool + default n + +config SAMV7_HAVE_SPI0 + bool + default n + +config SAMV7_HAVE_SPI1 + bool + default n + +config SAMV7_QSPI_IS_SPI + bool + default n + +config SAMV7_SSC + bool + default n + +config SAMV7_HAVE_TC + bool + default n + +config SAMV7_HAVE_TWIHS2 + bool + default n + +config SAMV7_HAVE_USBFS + bool + default n + +config SAMV7_HAVE_USBHS + bool + default n + +config SAMV7_HAVE_USART0 + bool + default n + +config SAMV7_HAVE_USART1 + bool + default n + +config SAMV7_HAVE_USART2 + bool + default n + +config SAMV7_SPI + bool + default n + +config SAMV7_SPI_MASTER + bool + default n + +config SAMV7_SPI_SLAVE + bool + default n + +# Peripheral Selection + +menu "SAMV7 Peripheral Selection" + +config SAMV7_ACC + bool "Analog Comparator (ACC)" + default n + +config SAMV7_ADC + bool "12-bit ADC Controller (ADC)" + default n + +config SAMV7_AFEC0 + bool "Analog Front End 0 (AFEC0)" + default n + +config SAMV7_AFEC1 + bool "Analog Front End 1 (AFEC1)" + default n + +config SAMV7_MCAN0 + bool "CAN controller 0 (MCAN0)" + default n + select CAN + select ARCH_HAVE_CAN_ERRORS + select CAN_TXREADY + select SAMV7_MCAN + +config SAMV7_MCAN1 + bool "CAN controller 1 (MCAN1)" + default n + depends on SAMV7_HAVE_MCAN1 + select CAN + select ARCH_HAVE_CAN_ERRORS + select CAN_TXREADY + select SAMV7_MCAN + +config SAMV7_DAC0 + bool "Digital To Analog Converter 0 (DAC0)" + default n + +config SAMV7_DAC1 + bool "Digital To Analog Converter 1 (DAC1)" + default n + depends on SAMV7_HAVE_DAC1 + +config SAMV7_EBI + bool "External Bus Interface (EBI)" + default n + depends on SAMV7_HAVE_EBI + +config SAMV7_EMAC0 + bool "Ethernet MAC (GMAC)" + default n + select SAMV7_EMAC + select NETDEVICES + select ARCH_HAVE_PHY + +config SAMV7_XDMAC + bool "Central DMA (XDMA)" + default n + select ARCH_DMA + +config SAMV7_HSMCI0 + bool "High Speed Multimedia Card Interface (HSMCI)" + default n + depends on SAMV7_HAVE_HSMCI0 + select SAMV7_HSMCI + select ARCH_HAVE_SDIO + select MMCSD + +config SAMV7_ISI + bool "Image Sensor Interface (ISI)" + default n + +config SAMV7_MLB + bool "Media LB Interface" + default n + depends on SAMV7_HAVE_MEDIALB + +config SAMV7_PWM0 + bool "Pulse Width Modulation Controller 0 (PWM0)" + default n + +config SAMV7_PWM1 + bool "Pulse Width Modulation Controller 0 (PWM1)" + default n + +config SAMV7_QSPI + bool "Quad SPI (QSPI)" + default n + select ARCH_USE_MPU + select ARM_MPU + +config SAMV7_RTC + bool "Real Time Clock (RTC)" + default n + +config SAMV7_RTT + bool "Real Time Timer (RTT)" + default n + +config SAMV7_SDRAMC + bool "SDRAM Controller (SDRAMC)" + default n + depends on SAMV7_HAVE_SDRAMC + +config SAMV7_SMC + bool "Static Memory Controller (SMC)" + default n + +config SAMV7_SPI0 + bool "Serial Peripheral Interface 0 (SPI0)" + default n + depends on SAMV7_HAVE_SPI0 + select SAMV7_SPI + select SPI + +config SAMV7_SPI1 + bool "Serial Peripheral Interface 1 (SPI1)" + default n + depends on SAMV7_HAVE_SPI1 + select SAMV7_SPI + select SPI + +config SAMV7_SSC0 + bool "Synchronous Serial Controller (SSC)" + default n + select SAMV7_SSC + +config SAMV7_TC0 + bool "Timer Counter 0 (ch. 0, 1, 2) (TC0)" + default n + select SAMV7_HAVE_TC + +config SAMV7_TC1 + bool "Timer Counter 1 (ch. 3, 4, 5) (TC1)" + default n + select SAMV7_HAVE_TC + +config SAMV7_TC2 + bool "Timer Counter 2 (ch. 6, 7, 8) (TC2)" + default n + select SAMV7_HAVE_TC + +config SAMV7_TC3 + bool "Timer Counter 3 (ch. 9, 10, 11) (TC2)" + default n + select SAMV7_HAVE_TC + +config SAMV7_TRNG + bool "True Random Number Generator (TRNG)" + default n + select ARCH_HAVE_RNG + +config SAMV7_TWIHS0 + bool "Two-wire Interface 0 (TWIHS0)" + default n + +config SAMV7_TWIHS1 + bool "Two-wire Interface 1 (TWIHS1)" + default n + +config SAMV7_TWIHS2 + bool "Two-wire Interface 2 (TWIHS2)" + default n + depends on SAMV7_HAVE_TWIHS2 + +config SAMV7_UART0 + bool "UART 0" + default y + select ARCH_HAVE_UART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_UART1 + bool "UART 1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_UART2 + bool "UART 2" + default y + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_UART3 + bool "UART 3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_UART4 + bool "UART 4" + default y + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_USBDEVFS + bool "USB Device Full Speed (USBFS)" + default n + depends on SAMV7_HAVE_USBFS + select USBDEV + +config SAMV7_USBDEVHS + bool "USB Device High Speed (USBHS)" + default n + depends on SAMV7_HAVE_USBHS + select USBDEV + +config SAMV7_USBHOSTFS + bool "USB Host Full Speed (USBFS)" + default n + depends on SAMV7_HAVE_USBFS + select USBHOST + +config SAMV7_USBHOSTHS + bool "USB Host High Speed (USBHS)" + default n + depends on SAMV7_HAVE_USBHS + select USBHOST + +config SAMV7_USART0 + bool "USART 0" + default n + depends on SAMV7_HAVE_USART0 + select ARCH_HAVE_USART0 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_USART1 + bool "USART 1" + default n + depends on SAMV7_HAVE_USART1 + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_USART2 + bool "USART 2" + default n + depends on SAMV7_HAVE_USART2 + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config SAMV7_WDT + bool "Watchdog Timer (WDT)" + default n + select WATCHDOG + +config SAMV7_RSWDT + bool "Reinforced Safety Watchdog Timer (RSWDT)" + default n + select WATCHDOG + +endmenu # SAMV7 Peripheral Selection + +menuconfig SAMV7_GPIO_IRQ + bool "GPIO pin interrupts" + ---help--- + Enable support for interrupting GPIO pins + +if SAMV7_GPIO_IRQ + +config SAMV7_GPIOA_IRQ + bool "GPIOA interrupts" + default n + +config SAMV7_GPIOB_IRQ + bool "GPIOB interrupts" + default n + +config SAMV7_GPIOC_IRQ + bool "GPIOC interrupts" + default n + +config SAMV7_GPIOD_IRQ + bool "GPIOD interrupts" + default n + +config SAMV7_GPIOE_IRQ + bool "GPIOE interrupts" + default n + +endif # SAMV7_GPIO_IRQ + +if SAMV7_WDT || SAMV7_RSWDT + +menu "Watchdog Configuration" + +if SAMV7_WDT + +comment "Watchdog Configuration" + +config SAMV7_WDT_INTERRUPT + bool "Interrupt on timeout" + default n + ---help--- + The normal behavior is to reset everything when a watchdog timeout + occurs. An alternative behavior is to simply interrupt when the + timeout occurs. This setting enables that alternative behavior. + +config SAMV7_WDT_DEBUGHALT + bool "Halt on DEBUG" + default y if DEBUG + default n if !DEBUG + ---help--- + Halt the watchdog timer in the debug state + +config SAMV7_WDT_IDLEHALT + bool "Halt in IDLE" + default y + ---help--- + Halt the watchdog timer in the IDLE state + +config SAMV7_WDT_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enable low-level register debug output + +endif # SAMV7_WDT + +if SAMV7_RSWDT + +comment "Reinforced Safety Watchdog Configuration" + +config SAMV7_RSWDT_INTERRUPT + bool "Interrupt on timeout" + default n + ---help--- + The normal behavior is to reset everything when a watchdog timeout + occurs. An alternative behavior is to simply interrupt when the + timeout occurs. This setting enables that alternative behavior. + +config SAMV7_RSWDT_DEBUGHALT + bool "Halt on DEBUG" + default y if DEBUG + default n if !DEBUG + ---help--- + Halt the watchdog timer in the debug state + +config SAMV7_RSWDT_IDLEHALT + bool "Halt in IDLE" + default y + ---help--- + Halt the watchdog timer in the IDLE state + +config SAMV7_RSWDT_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enable low-level register debug output + +endif # SAMV7_RSWDT + +endmenu # Watchdog configuration + +endif # SAMV7_WDT || SAMV7_RSWDT + +menuconfig SAMV7_PROGMEM + bool "FLASH program memory" + ---help--- + Enable support FLASH interfaces as defined in include/nuttx/progmem.h + +if SAMV7_PROGMEM + +config SAMV7_PROGMEM_NSECTORS + int "Number of 128KB sectors" + default 4 + range 1 15 + ---help--- + This is the number of 128KB FLASH sectors at the end of the program + flash memory that will be reserved for use with by the interfaces + prototyped in include/nuttx/progmem.h + +endif # SAMV7_PROGMEM + +menu "SDRAM Configuration" + depends on SAMV7_SDRAMC + +config SAMV7_SDRAMSIZE + int "SDRAM size (bytes)" + default 0 + ---help--- + This is the usable size of the SDRAM. This may be a value less that + the actual size of the SDRAM if, for some reason, you wish to + reserve the end of SDRAM memory for some other purpose. + +config SAMV7_SDRAMHEAP + bool "SDRAM heap" + default y + ---help--- + Add the first SAMV7_SDRAMSIZE bytes of SDRAM to the heap. NOTE that + this requires also that MM_REGIONS be incremented to support another memory region. + +endmenu # SDRAM Configuration + +menu "SPI Device Driver Configuration" + depends on SAMV7_SPI + +choice + prompt "SPI0 Configuration" + default SAMV7_SPI0_MASTER + depends on SAMV7_SPI0 + +config SAMV7_SPI0_MASTER + bool "Master" + select SAMV7_SPI_MASTER + ---help--- + Configure SPI0 as an SPI master driver. Default: Master + +config SAMV7_SPI0_SLAVE + bool "Slave" + depends on EXPERIMENTAL + select SAMV7_SPI_SLAVE + ---help--- + Configure SPI0 as an SPI slave driver. Default: Master + +endchoice # SPI0 Configuration + +choice + prompt "SPI1 Configuration" + default SAMV7_SPI1_MASTER + depends on SAMV7_SPI1 + +config SAMV7_SPI1_MASTER + bool "Master" + select SAMV7_SPI_MASTER + ---help--- + Configure SPI1 as an SPI master driver. Default: Master + +config SAMV7_SPI1_SLAVE + bool "Slave" + depends on EXPERIMENTAL + select SAMV7_SPI_SLAVE + ---help--- + Configure SPI1 as an SPI slave driver. Default: Master + +endchoice # SPI1 Configuration + +if SAMV7_SPI_MASTER +comment "SPI Master Configuration" + +config SAMV7_SPI_CS_DECODING + bool "SPI Peripheral Chip Select Decoding" + default n + ---help--- + Use Peripheral Chip Select Decoding on SPI Master + +config SAMV7_SPI_DMA + bool "SPI DMA" + default n + depends on SAMV7_XDMAC + ---help--- + Use DMA to improve SPI transfer performance. + +config SAMV7_SPI_DMATHRESHOLD + int "SPI DMA threshold" + default 4 + depends on SAMV7_SPI_DMA + ---help--- + When SPI DMA is enabled, small DMA transfers will still be performed + by polling logic. But we need a threshold value to determine what + is small. That value is provided by SAMV7_SPI_DMATHRESHOLD. + +config SAMV7_SPI_DMADEBUG + bool "SPI DMA transfer debug" + depends on SAMV7_SPI_DMA && DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze SPI DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +endif # SAMV7_SPI_MASTER + +if SAMV7_SPI_SLAVE +comment "SPI Slave Configuration" + +config SAMV7_SPI_SLAVE_QSIZE + int "Output queue size" + default 8 + ---help--- + The number of words that an be retained in the controller driver's + output queue. + +endif # SAMV7_SPI_SLAVE + +config SAMV7_SPI_REGDEBUG + bool "SPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. + Requires also DEBUG. + +endmenu # SPI device driver options + +menu "QSPI Device Driver Configuration" + depends on SAMV7_QSPI && !SAMV7_QSPI_IS_SPI + +config SAMV7_QSPI_DLYBS + int "Delay Before QSCK (nsec)" + default 0 + +config SAMV7_QSPI_DLYBCT + int "Delay Between Consecutive Transfers (nsec)" + default 0 + +config SAMV7_QSPI_DMA + bool "QSPI DMA" + default n + depends on SAMV7_XDMAC + ---help--- + Use DMA to improve SPI transfer performance. + +config SAMV7_QSPI_DMATHRESHOLD + int "QSPI DMA threshold" + default 4 + depends on SAMV7_QSPI_DMA + ---help--- + When ASPI DMA is enabled, small DMA transfers will still be performed + by polling logic. But we need a threshold value to determine what + is small. That value is provided by SAMV7_QSPI_DMATHRESHOLD. + +config SAMV7_QSPI_DMADEBUG + bool "QSPI DMA transfer debug" + depends on SAMV7_QSPI_DMA && DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze QSPI DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAMV7_QSPI_REGDEBUG + bool "QSPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level QSPI device debug information. + Requires also DEBUG. + +endmenu # QSPI device driver options + +menu "TWIHS device driver options" + depends on SAMV7_TWIHS0 || SAMV7_TWIHS1 || SAMV7_TWIHS2 + +config SAMV7_TWIHS0_FREQUENCY + int "TWIHS0 Frequency" + default 100000 + depends on SAMV7_TWIHS0 + +config SAMV7_TWIHS1_FREQUENCY + int "TWIHS1 Frequency" + default 100000 + depends on SAMV7_TWIHS1 + +config SAMV7_TWIHS2_FREQUENCY + int "TWIHS2 Frequency" + default 100000 + depends on SAMV7_TWIHS2 + +config SAMV7_TWIHS_REGDEBUG + bool "TWIHS register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level TWIHS device debug information. + Very invasive! Requires also DEBUG. + +endmenu # TWIHS device driver options + +menu "SSC Configuration" + depends on SAMV7_SSC + +config SAMV7_SSC_MAXINFLIGHT + int "SSC queue size" + default 16 + ---help--- + This is the total number of transfers, both RX and TX, that can be + enqueue before the caller is required to wait. This setting + determines the number certain queue data structures that will be + pre-allocated. + +if SAMV7_SSC0 +comment "SSC0 Configuration" + +config SAMV7_SSC0_DATALEN + int "Data width (bits)" + default 16 + ---help--- + Data width in bits. This is a default value and may be change + via the I2S interface + +config SAMV7_SSC0_RX + bool "Enable I2C receiver" + default n + ---help--- + Enable I2S receipt logic + +if SAMV7_SSC0_RX + +choice + prompt "Receiver clock source" + default SAMV7_SSC0_RX_MCKDIV + +config SAMV7_SSC0_RX_RKINPUT + bool "RK input" + ---help--- + The SSC receiver clock is an external clock provided on the RK input + pin. Sample rate determined by the external clock frequency. + +config SAMV7_SSC0_RX_TXCLK + bool "Transmitter Clock" + ---help--- + The SSC receiver clock is transmitter clock. RX sample rate is the same + as the TX sample rate. + +config SAMV7_SSC0_RX_MCKDIV + bool "MCK/2" + ---help--- + The SSC receiver clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Receiver clock source + +if !SAMV7_SSC0_RX_RKINPUT +choice + prompt "Receiver output clock" + default SAMV7_SSC0_RX_RKOUTPUT_NONE + +config SAMV7_SSC0_RX_RKOUTPUT_NONE + bool "None" + +config SAMV7_SSC0_RX_RKOUTPUT_CONT + bool "Continuous" + +config SAMV7_SSC0_RX_RKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMV7_SSC0_RX_RKINPUT + +config SAMV7_SSC0_RX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 1 255 + ---help--- + This setting determines the pulse length of the Receive Frame Sync + signal in units of receive clock periods. + +config SAMV7_SSC0_RX_STTDLY + int "Receive Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + receive clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMV7_SSC0_RX + +config SAMV7_SSC0_TX + bool "Enable I2C transmitter" + default n + ---help--- + Enable I2S transmission logic + +if SAMV7_SSC0_TX + +choice + prompt "Transmitter clock source" + default SAMV7_SSC0_TX_MCKDIV + +config SAMV7_SSC0_TX_TKINPUT + bool "TK input" + ---help--- + The SSC transmitter clock is an external clock provided on the TK input + pin. Sample rate determined by the external clock frequency. + +config SAMV7_SSC0_TX_RXCLK + bool "Receiver Clock" + ---help--- + The SSC transmitter clock is receiver clock. TX sample rate is the same + as the RX sample rate. + +config SAMV7_SSC0_TX_MCKDIV + bool "MCK/2" + ---help--- + The SSC transmitter clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Transmitter clock source + +if !SAMV7_SSC0_TX_TKINPUT +choice + prompt "Transmitter output clock" + default SAMV7_SSC0_TX_TKOUTPUT_NONE + +config SAMV7_SSC0_TX_TKOUTPUT_NONE + bool "None" + +config SAMV7_SSC0_TX_TKOUTPUT_CONT + bool "Continuous" + +config SAMV7_SSC0_TX_TKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMV7_SSC0_TX_TKINPUT + +config SAMV7_SSC0_TX_FSLEN + int "Transmit Frame Sync Length" + default 1 + range 0 255 + ---help--- + This setting defines the length of the Transmit Frame Sync signal in + units of transmit clock periods. A value of zero disables this + feature. In that case the TD line is driven with the default value + during the Transmit Frame Sync signal. + +config SAMV7_SSC0_TX_STTDLY + int "Transmit Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + transmit clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMV7_SSC0_TX + +config SAMV7_SSC0_MCKDIV_SAMPLERATE + int "Sample rate" + default 48000 + depends on SAMV7_SSC0_RX_MCKDIV || SAMV7_SSC0_TX_MCKDIV + ---help--- + If the either the receiver or transmitter clock is provided by MCK/2 divided + down, then the sample rate must be provided. The bit rate will be the product + of the sample rate and the data width. The SSC driver will determine the best + divider to obtain that bit rate (up to 4095). If the bit rate can be realized + by dividing down the MCK/2, a compile time error will occur. + +config SAMV7_SSC0_LOOPBACK + bool "Loopback mode" + default n + depends on SAMV7_SSC0_TX && SAMV7_SSC0_RX + ---help--- + If both the receiver and transmitter are enabled, then the SSC can + be configured in loopback mode. This setting selects SSC loopback + and will cause the LOOP bit to be set in the SSC_RFMR register. In + this case, RD is connected to TD, RF is connected to TF and RK is + connected to TK. + +endif # SAMV7_SSC0 + +if SAMV7_SSC1 +comment "SSC1 Configuration" + +config SAMV7_SSC1_DATALEN + int "Data width (bits)" + default 16 + ---help--- + Data width in bits. This is a default value and may be change + via the I2S interface + +config SAMV7_SSC1_RX + bool "Enable I2C receiver" + default n + ---help--- + Enable I2S receipt logic + +if SAMV7_SSC1_RX + +choice + prompt "Receiver clock source" + default SAMV7_SSC1_RX_MCKDIV + +config SAMV7_SSC1_RX_RKINPUT + bool "RK input" + ---help--- + The SSC receiver clock is an external clock provided on the RK input + pin. Sample rate determined by the external clock frequency. + +config SAMV7_SSC1_RX_TXCLK + bool "Transmitter Clock" + ---help--- + The SSC receiver clock is transmitter clock. RX sample rate is the same + as the TX sample rate. + +config SAMV7_SSC1_RX_MCKDIV + bool "MCK/2" + ---help--- + The SSC receiver clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Receiver clock source + +if !SAMV7_SSC1_RX_RKINPUT +choice + prompt "Receiver output clock" + default SAMV7_SSC1_RX_RKOUTPUT_NONE + +config SAMV7_SSC1_RX_RKOUTPUT_NONE + bool "None" + +config SAMV7_SSC1_RX_RKOUTPUT_CONT + bool "Continuous" + +config SAMV7_SSC1_RX_RKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMV7_SSC1_RX_RKINPUT + +config SAMV7_SSC1_RX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 1 255 + ---help--- + This setting determines the pulse length of the Receive Frame Sync + signal in units of receive clock periods. + +config SAMV7_SSC1_RX_STTDLY + int "Receive Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data of + receive clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMV7_SSC1_RX + +config SAMV7_SSC1_TX + bool "Enable I2C transmitter" + default n + ---help--- + Enable I2S transmission logic + +if SAMV7_SSC1_TX + +choice + prompt "Transmitter clock source" + default SAMV7_SSC1_TX_MCKDIV + +config SAMV7_SSC1_TX_TKINPUT + bool "TK input" + ---help--- + The SSC transmitter clock is an external clock provided on the TK input + pin. Sample rate determined by the external clock frequency. + +config SAMV7_SSC1_TX_RXCLK + bool "Receiver Clock" + ---help--- + The SSC transmitter clock is receiver clock. TX sample rate is the same + as the RX sample rate. + +config SAMV7_SSC1_TX_MCKDIV + bool "MCK/2" + ---help--- + The SSC transmitter clock is the MCK/2 divided by a up to 4095. Desired + sample rate must be provided below. + +endchoice # Transmitter clock source + +if !SAMV7_SSC1_TX_TKINPUT +choice + prompt "Transmitter output clock" + default SAMV7_SSC1_TX_TKOUTPUT_NONE + +config SAMV7_SSC1_TX_TKOUTPUT_NONE + bool "None" + +config SAMV7_SSC1_TX_TKOUTPUT_CONT + bool "Continuous" + +config SAMV7_SSC1_TX_TKOUTPUT_XFR + bool "Only during transfers" + +endchoice # Receiver output clock +endif # !SAMV7_SSC1_TX_TKINPUT + +config SAMV7_SSC1_TX_FSLEN + int "Receive Frame Sync Length" + default 1 + range 0 255 + ---help--- + This setting defines the length of the Transmit Frame Sync signal in + units of transmit clock periods. A value of zero disables this + feature. In that case the TD line is driven with the default value + during the Transmit Frame Sync signal. + +config SAMV7_SSC1_TX_STTDLY + int "Transmit Start Delay Length" + default 0 + range 0 255 + ---help--- + This setting determines the pulse length to the start of data in + transmit clock periods. It must be greater than or equal to the RX + frame synch length. Zero means no start delay. + +endif # SAMV7_SSC1_TX + +config SAMV7_SSC1_MCKDIV_SAMPLERATE + int "Sample rate" + default 48000 + depends on SAMV7_SSC1_RX_MCKDIV || SAMV7_SSC1_TX_MCKDIV + ---help--- + If the either the receiver or transmitter clock is provided by MCK/2 divided + down, then the sample rate must be provided. The bit rate will be the product + of the sample rate and the data width. The SSC driver will determine the best + divider to obtain that bit rate (up to 4095). If the bit rate can be realized + by dividing down the MCK/2, a compile time error will occur. + +config SAMV7_SSC1_LOOPBACK + bool "Loopback mode" + default n + depends on SAMV7_SSC1_TX && SAMV7_SSC1_RX + ---help--- + If both the receiver and transmitter are enabled, then the SSC can + be configured in loopback mode. This setting selects SSC loopback + and will cause the LOOP bit to be set in the SSC_RFMR register. In + this case, RD is connected to TD, RF is connected to TF and RK is + connected to TK. + +endif # SAMV7_SSC1 + +config SAMV7_SSC_DMADEBUG + bool "SSC DMA transfer debug" + depends on DEBUG && DEBUG_DMA + default n + ---help--- + Enable special debug instrumentation analyze SSC DMA data transfers. + This logic is as non-invasive as possible: It samples DMA + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. + +config SAMV7_SSC_REGDEBUG + bool "SSC Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SSC device debug information. + Very invasive! Requires also DEBUG. + +config SAMV7_SSC_QDEBUG + bool "SSC Queue debug" + depends on DEBUG_I2S + default n + ---help--- + Enable instrumentation to debug audio buffer queue logic. + +config SAMV7_SSC_DUMPBUFFERS + bool "Dump Buffers" + depends on DEBUG_I2S + default n + ---help--- + Enable instrumentation to dump TX and RX buffers. + +endmenu # SSC Configuration + +if SAMV7_HAVE_TC +menu "Timer/counter Configuration" + +if SAMV7_TC0 + +config SAMV7_TC0_CLK0 + bool "Enable TC0 channel 0 clock input pin" + default n + +config SAMV7_TC0_TIOA0 + bool "Enable TC0 channel 0 output A" + default n + +config SAMV7_TC0_TIOB0 + bool "Enable TC0 channel 0 output B" + default n + +config SAMV7_TC0_CLK1 + bool "Enable TC0 channel 1 clock input pin" + default n + +config SAMV7_TC0_TIOA1 + bool "Enable TC0 channel 1 output A" + default n + +config SAMV7_TC0_TIOB1 + bool "Enable TC0 channel 1 output B" + default n + +config SAMV7_TC0_CLK2 + bool "Enable TC0 channel 2 clock input pin" + default n + +config SAMV7_TC0_TIOA2 + bool "Enable TC0 channel 2 output A" + default n + +config SAMV7_TC0_TIOB2 + bool "Enable TC0 channel 2 output B" + default n + +endif # SAMV7_TC0 + +if SAMV7_TC1 + +config SAMV7_TC1_CLK3 + bool "Enable TC1 channel 3 clock input pin" + default n + +config SAMV7_TC1_TIOA3 + bool "Enable TC1 channel 3 output A" + default n + +config SAMV7_TC1_TIOB3 + bool "Enable TC1 channel 3 output B" + default n + +config SAMV7_TC1_CLK4 + bool "Enable TC1 channel 4 clock input pin" + default n + +config SAMV7_TC1_TIOA4 + bool "Enable TC1 channel 4 output A" + default n + +config SAMV7_TC1_TIOB4 + bool "Enable TC1 channel 4 output B" + default n + +config SAMV7_TC1_CLK5 + bool "Enable TC1 channel 5 clock input pin" + default n + +config SAMV7_TC1_TIOA5 + bool "Enable TC1 channel 5 output A" + default n + +config SAMV7_TC1_TIOB5 + bool "Enable TC1 channel 5 output B" + default n + +endif # SAMV7_TC1 + +if SAMV7_TC2 + +config SAMV7_TC2_CLK6 + bool "Enable TC2 channel 6 clock input pin" + default n + +config SAMV7_TC2_TIOA6 + bool "Enable TC2 channel 6 output A" + default n + +config SAMV7_TC2_TIOB6 + bool "Enable TC2 channel 6 output B" + default n + +config SAMV7_TC2_CLK7 + bool "Enable TC2 channel 7 clock input pin" + default n + +config SAMV7_TC2_TIOA7 + bool "Enable TC2 channel 7 output A" + default n + +config SAMV7_TC2_TIOB7 + bool "Enable TC2 channel 7 output B" + default n + +config SAMV7_TC2_CLK8 + bool "Enable TC2 channel 8 clock input pin" + default n + +config SAMV7_TC2_TIOA8 + bool "Enable TC2 channel 8 output A" + default n + +config SAMV7_TC2_TIOB8 + bool "Enable TC2 channel 8 output B" + default n + +endif # SAMV7_TC2 + +if SAMV7_TC3 +config SAMV7_TC3_CLK9 + bool "Enable TC3 channel 9 clock input pin" + default n + +config SAMV7_TC3_TIOA9 + bool "Enable TC3 channel 9 output A" + default n + +config SAMV7_TC3_TIOB9 + bool "Enable TC3 channel 9 output B" + default n + +config SAMV7_TC3_CLK10 + bool "Enable TC3 channel 10 clock input pin" + default n + +config SAMV7_TC3_TIOA10 + bool "Enable TC3 channel 10 output A" + default n + +config SAMV7_TC3_TIOB10 + bool "Enable TC3 channel 10 output B" + default n + +config SAMV7_TC3_CLK11 + bool "Enable TC3 channel 11 clock input pin" + default n + +config SAMV7_TC3_TIOA11 + bool "Enable TC3 channel 11 output A" + default n + +config SAMV7_TC3_TIOB11 + bool "Enable TC3 channel 11 output B" + default n + +endif # SAMV7_TC3 + +config SAMV7_ONESHOT + bool "TC one-shot wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config SAMV7_FREERUN + bool "TC free-running wrapper" + default n if !SCHED_TICKLESS + default y if SCHED_TICKLESS + ---help--- + Enable a wrapper around the low level timer/counter functions to + support a free-running timer. + +if SCHED_TICKLESS + +config SAMV7_TICKLESS_ONESHOT + int "Tickless one-shot timer channel" + default 0 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the one-shot timer needed by the OS. + +config SAMV7_TICKLESS_FREERUN + int "Tickless free-running timer channel" + default 1 + range 0 8 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the free-running timer needed by the OS. + +endif + +config SAMV7_TC_DEBUG + bool "TC debug" + depends on DEBUG + default n + ---help--- + Output high level Timer/Counter device debug information. + Requires also DEBUG. If this option AND DEBUG_VERBOSE are + enabled, then the system will be overwhelmed the timer debug + output. If DEBUG_VERBOSE is disabled, then debug output will + only indicate if/when timer-related errors occur. This + latter mode is completely usable. + +config SAMV7_TC_REGDEBUG + bool "TC register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level Timer/Counter device debug + information. Very invasive! Requires also DEBUG. + +endmenu # Timer/counter Configuration +endif # SAMV7_HAVE_TC + +menu "HSMCI device driver options" + depends on SAMV7_HSMCI + +config SAMV7_HSMCI_RDPROOF + bool "Read Proof Enable" + default n + ---help--- + Enabling Read Proof allows to stop the HSMCI Clock during read + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAMV7_HSMCI_WRPROOF + bool "Write Proof Enable" + default n + ---help--- + Enabling Write Proof allows to stop the HSMCI Clock during write + access if the internal FIFO is full. This will guarantee data + integrity, not bandwidth. + +config SAMV7_HSMCI_UNALIGNED + bool "Unaligned I/O buffers" + default n + ---help--- + This option enables additional logic to handle unaligned buffers for + read and write SDIO operations. Normally this support is not + required because the HSCMI driver functions like a block driver and, + for example, when used with the FAT file system only transfers + aligned blocks of data. + + But under certain circumstances, the FAT file system WILL read + directly into the user buffer and then strict 32-bit alignment is + required. That condition is: When the user reads from the + beginning of a sector and at least a whole sector is being read. + + This option is not recommended. There are better ways to handle + the unalaigned case: + + # CONFIG_SAMV7_HSMCI_UNALIGNED is not set + Just return -EFAULT if unaligned + CONFIG_FAT_DIRECT_RETRY=y + If -EFAULT is returned, then try again with aligned + sector buffers. + +config SAMV7_HSMCI_XFRDEBUG + bool "HSMCI transfer debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI data transfers. + This logic is as non-invasive as possible: It samples HSMCI + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. If DEBUG_DMA is also + enabled, then DMA register will be collected as well. Requires also + DEBUG_FS and DEBUG_VERBOSE. + +config SAMV7_HSMCI_CMDDEBUG + bool "HSMCI command debug" + depends on DEBUG_FS && DEBUG_VERBOSE + default n + ---help--- + Enable special debug instrumentation analyze HSMCI commands. This + logic is as non-invasive as possible: It samples HSMCI registers at + key points in the data transfer and then dumps all of the registers + at the end of the transfer. If DEBUG_DMA is also enabled, then DMA + register will be collected as well. Requires also DEBUG_FS and + DEBUG_VERBOSE. + +config SAMV7_HSMCI_REGDEBUG + bool "HSMCI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level HSCMI device debug information. + Very invasive! Requires also DEBUG. + +endmenu # HSMCI device driver options + +menu "EMAC device driver options" + depends on SAMV7_EMAC0 + +config SAMV7_EMAC0_NRXBUFFERS + int "Number of RX buffers" + default 16 + ---help--- + EMAC buffer memory is segmented into 128 byte units (not + configurable). This setting provides the number of such 128 byte + units used for reception. This is also equal to the number of RX + descriptors that will be allocated The selected value must be an + even power of 2. + +config SAMV7_EMAC0_NTXBUFFERS + int "Number of TX buffers" + default 8 + ---help--- + EMAC buffer memory is segmented into full Ethernet packets (size + NET_BUFSIZE bytes). This setting provides the number of such packets + that can be in flight. This is also equal to the number of TX + descriptors that will be allocated. + +config SAMV7_EMAC0_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config SAMV7_EMAC0_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + SAMV7_EMAC0_PHYINIT is defined in the configuration then the board specific logic must + provide sam_phyinitialize(); The SAMV7 EMAC driver will call this function + one time before it first uses the PHY. + +choice + prompt "PHY interface" + default SAMV7_EMAC0_MII + +config SAMV7_EMAC0_MII + bool "MII" + ---help--- + Support Ethernet MII interface (vs RMII). + +config SAMV7_EMAC0_RMII + bool "RMII" + depends on !ARCH_CHIP_SAM4E + ---help--- + Support Ethernet RMII interface (vs MII). + +endchoice # PHY interface + +config SAMV7_EMAC0_CLAUSE45 + bool "Clause 45 MII" + depends on SAMV7_EMAC0_MII + ---help--- + MDIO was originally defined in Clause 22 of IEEE RFC802.3. In the + original specification, a single MDIO interface is able to access up + to 32 registers in 32 different PHY devices. To meet the needs the + expanding needs of 10-Gigabit Ethernet devices, Clause 45 of the + 802.3ae specification provided the following additions to MDIO: + + - Ability to access 65,536 registers in 32 different devices on + 32 different ports + - Additional OP-code and ST-code for Indirect Address register + access for 10 Gigabit Ethernet + - End-to-end fault signaling + - Multiple loopback points + - Low voltage electrical specification + + By default, Clause 22 PHYs will be supported unless this option is + selected. + +config SAMV7_EMAC0_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config SAMV7_EMAC0_ETHFD + bool "Full duplex" + default n + depends on !SAMV7_EMAC0_AUTONEG + ---help--- + If SAMV7_EMAC0_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config SAMV7_EMAC0_ETH100MBPS + bool "100 Mbps" + default n + depends on !SAMV7_EMAC0_AUTONEG + ---help--- + If SAMV7_EMAC0_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config SAMV7_EMAC0_PHYSR + int "PHY Status Register Address (decimal)" + depends on SAMV7_EMAC0_AUTONEG + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config SAMV7_EMAC0_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on SAMV7_EMAC0_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +if SAMV7_EMAC0_AUTONEG +if SAMV7_EMAC0_PHYSR_ALTCONFIG + +config SAMV7_EMAC0_PHYSR_ALTMODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config SAMV7_EMAC0_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config SAMV7_EMAC0_PHYSR_100HD + hex "100Base-T Half Duplex Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config SAMV7_EMAC0_PHYSR_10FD + hex "10Base-T Full Duplex Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config SAMV7_EMAC0_PHYSR_100FD + hex "100Base-T Full Duplex Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +endif # SAMV7_EMAC0_PHYSR_ALTCONFIG +if !SAMV7_EMAC0_PHYSR_ALTCONFIG + +config SAMV7_EMAC0_PHYSR_SPEED + hex "PHY Speed Mask" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config SAMV7_EMAC0_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config SAMV7_EMAC0_PHYSR_MODE + hex "PHY Mode Mask" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This provides the + bit mask for isolating the full or half duplex mode bits. + +config SAMV7_EMAC0_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + ---help--- + This must be provided if SAMV7_EMAC0_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +endif # !SAMV7_EMAC0_PHYSR_ALTCONFIG +endif # SAMV7_EMAC0_AUTONEG + +# These apply to both EMAC0 and EMAC1 (but are in the EMAC0 menu for now +# because there is not yet any SAMV7 chip that supports two Ethernet MACS + +config SAMV7_EMAC0_ISETH0 + bool + default y + +config SAMV7_EMAC_PREALLOCATE + bool "Preallocate buffers" + default n + ---help--- + Buffer an descriptor many may either be allocated from the memory + pool or pre-allocated to lie in .bss. This options selected pre- + allocated buffer memory. + +config SAMV7_EMAC_NBC + bool "Disable Broadcast" + default n + ---help--- + Select to disable receipt of broadcast packets. + +config SAMV7_EMAC_DEBUG + bool "Force EMAC0/1 DEBUG" + default n + depends on DEBUG && !DEBUG_NET + ---help--- + This option will force debug output from EMAC driver even without + network debug output enabled. This is not normally something + that would want to do but is convenient if you are debugging the + driver and do not want to get overloaded with other + network-related debug output. + +config SAMV7_EMAC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # EMAC0 device driver options + +menu "USB High Speed Device Controller driver (DCD) options" + depends on SAMV7_USBDEVHS + +config SAMV7_USBDEVHS_LOWPOWER + bool "Low-power mode" + default n + ---help--- + The USBHS can work in two modes: + + - Normal mode where High speed, Full speed and Low speed are + available. + - Low-power mode where only Full speed and Low speed are available. + + This options selects the low-power mode. In order to use high speed + mode, this option must be disabled and USBDEV_DUALSPEED must be + enabled. + +config SAMV7_USBHS_SCATTERGATHER + bool + default n + depends on EXPERIMENTAL + ---help--- + Scatter gather DMA is not yet supported + +config SAMV7_USBHS_NDTDS + int "Number of USBHS DMA transfer descriptors" + default 8 + ---help--- + DMA transfer descriptors are allocated in a pool at boot time. This + setting provides the number of DMA transfer descriptors to be + allocated. + +config SAMV7_USBHS_PREALLOCATE + bool "Pre-allocate DMA transfer descriptors" + default y + ---help--- + If this option is selected then DMA transfer descriptors will be + pre-allocated in .bss. Otherwise, the descriptors will be allocated + at start-up time with kmm_malloc(). This might be important if a larger + memory pool is available after startup. + +config SAMV7_USBHS_REGDEBUG + bool "Enable low-level USBHS register debug" + default n + depends on DEBUG + +endmenu # USB High Speed Device Controller driver (DCD) options + +if SAMV7_MCAN + +config SAMV7_MCAN_QUEUE_MODE + bool "MCAN QUEUE mode (vs FIFO mode)" + default n + +menu "MCAN device driver options" + +choice + prompt "MCAN clock source (PCK5)" + default SAMV7_MCAN_CLKSRC_MCK + +config SAMV7_MCAN_CLKSRC_SLOW + bool "Slow clock" + +config SAMV7_MCAN_CLKSRC_MAIN + bool "Main clock" + +config SAMV7_MCAN_CLKSRC_PLLA + bool "PLLA clock" + +config SAMV7_MCAN_CLKSRC_UPLL + bool "UPLL clock" + +config SAMV7_MCAN_CLKSRC_MCK + bool "Master clock" + +endchoice # MCAN clock source + +config SAMV7_MCAN_CLKSRC_PRESCALER + int "MCAN clock prescaler" + default 1 + range 1 1024 + ---help--- + The frequency associated with time quanta is derived by dividing + down the input frequency. This setting provides prescaler/divider + must lie the range of 1 to 1024. + +menu "MCAN0 device driver options" + depends on SAMV7_MCAN0 + +choice + prompt "MCAN0 mode" + default SAMV7_MCAN0_ISO11899_1 + +config SAMV7_MCAN0_ISO11899_1 + bool "ISO11898-1" + ---help--- + Enable ISO11898-1 mode + +config SAMV7_MCAN0_FD + bool "FD" + depends on CAN_FD + ---help--- + Enable FD mode + +config SAMV7_MCAN0_FD_BSW + bool "FD with fast bit rate switching" + depends on CAN_FD + ---help--- + Enable FD mode with fast bit rate switching mode. + +endchoice # MCAN0 mode + +config SAMV7_MCAN0_LOOPBACK + bool "Enable MCAN0 loopback mode" + default n + ---help--- + Enable the MCAN0 local loopback mode for testing purposes. + +config SAMV7_MCAN0_BITRATE + int "MCAN0 bitrate" + default 500000 + ---help--- + MCAN0 bitrate in bits per second. Required if SAMV7_MCAN0 is defined. + +config SAMV7_MCAN0_PROPSEG + int "MCAN0 PropSeg" + default 2 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_PHASESEG1 + int "MCAN0 PhaseSeg1" + default 11 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_PHASESEG2 + int "MCAN0 PhaseSeg2" + default 11 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_FSJW + int "MCAN0 synchronization jump width" + default 4 + range 1 5 + ---help--- + The duration of a synchronization jump is Tcan_clk x FSJW. + +config SAMV7_MCAN0_FBITRATE + int "MCAN0 fast bitrate" + default 2000000 + ---help--- + MCAN0 bitrate in bits per second. Required if SAMV7_MCAN0 is + defined. + +config SAMV7_MCAN0_FPROPSEG + int "MCAN0 fast PropSeg" + default 2 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_FPHASESEG1 + int "MCAN0 fast PhaseSeg1" + default 4 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_FPHASESEG2 + int "MCAN0 fast PhaseSeg2" + default 4 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN0_FFSJW + int "MCAN0 fast synchronization jump width" + default 2 + range 1 5 + ---help--- + The duration of a synchronization jump is Tcan_clk x FSJW. + +config SAMV7_MCAN0_NSTDFILTERS + int "MCAN0 number of standard filters" + default 8 + range 0 128 + ---help--- + Number of standard message ID filters. + +config SAMV7_MCAN0_NEXTFILTERS + int "MCAN0 number of extended filters" + default 8 + range 0 64 + depends on CAN_EXTID + ---help--- + Number of extended message ID filters. + +choice + prompt "MCAN0 RX FIFO0 element size" + default SAMV7_MCAN0_RXFIFO0_8BYTES + +config SAMV7_MCAN0_RXFIFO0_8BYTES + bool "8 bytes" + +config SAMV7_MCAN0_RXFIFO0_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO0_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN0_FD + +endchoice # MCAN0 RX buffer element size + +config SAMV7_MCAN0_RXFIFO0_SIZE + int "MCAN0 RX FIFO0 size" + default 8 + range 1 64 + ---help--- + Number of receive FIFO 0 elements. Zero disables FIFO 0. + +choice + prompt "MCAN0 RX FIFO1 element size" + default SAMV7_MCAN0_RXFIFO1_8BYTES + +config SAMV7_MCAN0_RXFIFO1_8BYTES + bool "8 bytes" + +config SAMV7_MCAN0_RXFIFO1_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXFIFO1_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN0_FD + +endchoice # MCAN0 RX buffer element size + +config SAMV7_MCAN0_RXFIFO1_SIZE + int "MCAN0 RX FIFO1 size" + default 4 + range 1 64 + ---help--- + Number of receive FIFO 1 elements for MCAN0. Zero disables FIFO 1. + +choice + prompt "MCAN0 RX buffer element size" + default SAMV7_MCAN0_RXBUFFER_8BYTES + +config SAMV7_MCAN0_RXBUFFER_8BYTES + bool "8 bytes" + +config SAMV7_MCAN0_RXBUFFER_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_RXBUFFER_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN0_FD + +endchoice # MCAN0 RX buffer element size + +config SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE + int "MCAN0 dedicated RX buffer size" + default 0 + range 0 64 + depends on EXPERIMENTAL + ---help--- + Number of dedicated RX buffer elements for MCAN0. + + NOTE: Dedicated RX buffers are not used in the current MCAN design. + +choice + prompt "MCAN0 TX buffer element size" + default SAMV7_MCAN0_TXBUFFER_8BYTES + +config SAMV7_MCAN0_TXBUFFER_8BYTES + bool "8 bytes" + +config SAMV7_MCAN0_TXBUFFER_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN0_FD + +config SAMV7_MCAN0_TXBUFFER_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN0_FD + +endchoice # MCAN0 TX buffer element size + +config SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE + int "MCAN0 dedicated TX buffer size" + default 0 + range 0 32 + depends on EXPERIMENTAL + ---help--- + Number of dedicated TX buffer elements for MCAN0. + + NOTE: Dedicated TX buffers are not used in the current MCAN design. + +config SAMV7_MCAN0_TXFIFOQ_SIZE + int "MCAN0 TX FIFO queue size" + default 4 + range 1 32 + ---help--- + Number of dedicated TX buffer elements for MCAN0. + +config SAMV7_MCAN0_TXEVENTFIFO_SIZE + int "MCAN0 TX event FIFO size" + default 0 + range 0 32 + depends on EXPERIMENTAL + ---help--- + Number of TX event FIFO elements for MCAN0. Zero disables TX event FIFO. + +endmenu # MCAN0 device driver options + +menu "MCAN1 device driver options" + depends on SAMV7_MCAN1 + +choice + prompt "MCAN1 mode" + default SAMV7_MCAN1_ISO11899_1 + +config SAMV7_MCAN1_ISO11899_1 + bool "ISO11898-1" + ---help--- + Enable ISO11898-1 mode + +config SAMV7_MCAN1_FD + bool "FD" + depends on CAN_FD + ---help--- + Enable FD mode + +config SAMV7_MCAN1_FD_BSW + bool "FD with fast bit rate switching" + depends on CAN_FD + ---help--- + Enable FD mode with fast bit rate switching mode. + +endchoice # MCAN0 mode + +config SAMV7_MCAN1_LOOPBACK + bool "Enable MCAN1 loopback mode" + default n + ---help--- + Enable the MCAN1 local loopback mode for testing purposes. + +config SAMV7_MCAN1_BITRATE + int "MCAN1 bitrate" + default 500000 + ---help--- + MCAN1 bitrate in bits per second. Required if SAMV7_MCAN1 is + defined. + +config SAMV7_MCAN1_PROPSEG + int "MCAN1 PropSeg" + default 2 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_PHASESEG1 + int "MCAN1 PhaseSeg1" + default 11 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_PHASESEG2 + int "MCAN1 PhaseSeg2" + default 11 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_FSJW + int "MCAN1 synchronization jump width" + default 4 + range 1 5 + ---help--- + The duration of a synchronization jump is Tcan_clk x FSJW. + +config SAMV7_MCAN1_FBITRATE + int "MCAN1 fast bitrate" + default 2000000 + ---help--- + MCAN1 bitrate in bits per second. Required if SAMV7_MCAN1 is + defined. + +config SAMV7_MCAN1_FPROPSEG + int "MCAN1 fast PropSeg" + default 2 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_FPHASESEG1 + int "MCAN1 fast PhaseSeg1" + default 4 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_FPHASESEG2 + int "MCAN1 fast PhaseSeg2" + default 4 + range 1 63 + ---help--- + The length of the bit time is Tquanta * (SyncSeg + PropSeg + PhaseSeg1 + PhaseSeg2). + +config SAMV7_MCAN1_FFSJW + int "MCAN1 fast synchronization jump width" + default 2 + range 1 5 + ---help--- + The duration of a synchronization jump is Tcan_clk x FSJW. + +config SAMV7_MCAN1_NSTDFILTERS + int "MCAN1 number of standard filters" + default 8 + range 0 128 + ---help--- + Number of standard message ID filters. + +config SAMV7_MCAN1_NEXTFILTERS + int "MCAN1 number of extended filters" + default 8 + range 0 64 + depends on CAN_EXTID + ---help--- + Number of extended message ID filters. + +choice + prompt "MCAN1 RX FIFO0 element size" + default SAMV7_MCAN1_RXFIFO0_8BYTES + +config SAMV7_MCAN1_RXFIFO0_8BYTES + bool "8 bytes" + +config SAMV7_MCAN1_RXFIFO0_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO0_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN1_FD + +endchoice # MCAN1 RX buffer element size + +config SAMV7_MCAN1_RXFIFO0_SIZE + int "MCAN1 RX FIFO0 size" + default 8 + range 1 64 + ---help--- + Number of receive FIFO 0 elements. Zero disables FIFO 0. + +choice + prompt "MCAN1 RX FIFO1 element size" + default SAMV7_MCAN1_RXFIFO1_8BYTES + +config SAMV7_MCAN1_RXFIFO1_8BYTES + bool "8 bytes" + +config SAMV7_MCAN1_RXFIFO1_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXFIFO1_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN1_FD + +endchoice # MCAN1 RX buffer element size + +config SAMV7_MCAN1_RXFIFO1_SIZE + int "MCAN1 RX FIFO1 size" + default 4 + range 1 64 + ---help--- + Number of receive FIFO 1 elements for MCAN1. Zero disables FIFO 1. + +choice + prompt "MCAN1 RX buffer element size" + default SAMV7_MCAN1_RXBUFFER_8BYTES + +config SAMV7_MCAN1_RXBUFFER_8BYTES + bool "8 bytes" + +config SAMV7_MCAN1_RXBUFFER_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_RXBUFFER_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN1_FD + +endchoice # MCAN1 RX buffer element size + +config SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE + int "MCAN1 dedicated RX buffer size" + default 0 + range 0 64 + depends on EXPERIMENTAL + ---help--- + Number of dedicated RX buffer elements for MCAN1. + + NOTE: Dedicated RX buffers are not used in the current MCAN design. + +choice + prompt "MCAN1 TX buffer element size" + default SAMV7_MCAN1_TXBUFFER_8BYTES + +config SAMV7_MCAN1_TXBUFFER_8BYTES + bool "8 bytes" + +config SAMV7_MCAN1_TXBUFFER_12BYTES + bool "12 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_16BYTES + bool "16 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_20BYTES + bool "20 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_24BYTES + bool "24 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_32BYTES + bool "32 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_48BYTES + bool "48 bytes" + depends on SAMV7_MCAN1_FD + +config SAMV7_MCAN1_TXBUFFER_64BYTES + bool "64 bytes" + depends on SAMV7_MCAN1_FD + +endchoice # MCAN1 TX buffer element size + +config SAMV7_MCAN1_TXEVENTFIFO_SIZE + int "MCAN1 TX event FIFO size" + default 0 + range 0 32 + depends on EXPERIMENTAL + ---help--- + Number of TX event FIFO elements for MCAN1. Zero disables TX event FIFO. + +config SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE + int "MCAN1 dedicated TX buffer size" + default 0 + range 0 32 + depends on EXPERIMENTAL + ---help--- + Number of dedicated TX buffer elements for MCAN1. + + NOTE: Dedicated TX buffers are not used in the current MCAN design. + +config SAMV7_MCAN1_TXFIFOQ_SIZE + int "MCAN1 TX FIFO queue" + default 4 + range 1 32 + ---help--- + Number of dedicated TX buffer elements for MCAN1. + +endmenu # MCAN1 device driver options + +config SAMV7_MCAN_REGDEBUG + bool "CAN Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level CAN device debug information. + Requires also DEBUG. + +endmenu # CAN device driver options +endif # SAMV7_MCAN +endif # ARCH_CHIP_SAMV7 diff --git a/arch/arm/src/samv7/Make.defs b/arch/arm/src/samv7/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..5d3dfc437bd98f6dafbde9d25551e7f9a3b91df0 --- /dev/null +++ b/arch/arm/src/samv7/Make.defs @@ -0,0 +1,212 @@ +############################################################################ +# arch/arm/src/samv7/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file. Only common vectors are support so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M7 files + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_memfault.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_vfork.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARMV7M_DCACHE),y) +CMN_CSRCS += arch_enable_dcache.c arch_disable_dcache.c +CMN_CSRCS += arch_invalidate_dcache.c arch_invalidate_dcache_all.c +ifneq ($(CONFIG_ARMV7M_DCACHE_WRITETHROUGH),y) +CMN_CSRCS += arch_clean_dcache.c arch_clean_dcache_all.c +CMN_CSRCS += arch_flush_dcache.c arch_flush_dcache_all.c +endif +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_ARM_MPU),y) +CMN_CSRCS += up_mpu.c +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Required SAMV7 files + +CHIP_ASRCS = +CHIP_CSRCS = sam_start.c sam_clockconfig.c sam_irq.c sam_allocateheap.c +CHIP_CSRCS += sam_lowputc.c sam_serial.c sam_gpio.c sam_pck.c + +# Configuration-dependent SAMV7 files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_timerisr.c +endif + +ifeq ($(CONFIG_ARM_MPU),y) +CHIP_CSRCS += sam_mpuinit.c +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += sam_userspace.c +endif +endif + +ifeq ($(CONFIG_SAMV7_GPIO_IRQ),y) +CHIP_CSRCS += sam_gpioirq.c +endif + +ifeq ($(CONFIG_SAMV7_XDMAC),y) +CHIP_CSRCS += sam_xdmac.c +endif + +ifeq ($(CONFIG_SAMV7_WDT),y) +CHIP_CSRCS += sam_wdt.c +endif + +ifeq ($(CONFIG_SAMV7_RSWDT),y) +CHIP_CSRCS += sam_rswdt.c +endif + +ifeq ($(CONFIG_SAMV7_SPI_MASTER),y) +CHIP_CSRCS += sam_spi.c +endif + +ifeq ($(CONFIG_SAMV7_SPI_SLAVE),y) +CHIP_CSRCS += sam_spi_slave.c +endif + +ifeq ($(CONFIG_SAMV7_QSPI),y) +CHIP_CSRCS += sam_qspi.c +endif + +ifeq ($(CONFIG_SAMV7_TWIHS0),y) +CHIP_CSRCS += sam_twihs.c +else ifeq ($(CONFIG_SAMV7_TWIHS1),y) +CHIP_CSRCS += sam_twihs.c +else ifeq ($(CONFIG_SAMV7_TWIHS2),y) +CHIP_CSRCS += sam_twihs.c +endif + +ifeq ($(CONFIG_SAMV7_SSC),y) +CHIP_CSRCS += sam_ssc.c +endif + +ifeq ($(CONFIG_SAMV7_HAVE_TC),y) +CHIP_CSRCS += sam_tc.c +ifeq ($(CONFIG_SAMV7_ONESHOT),y) +CHIP_CSRCS += sam_oneshot.c +endif +ifeq ($(CONFIG_SAMV7_FREERUN),y) +CHIP_CSRCS += sam_freerun.c +endif +ifeq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sam_tickless.c +endif +endif + +ifeq ($(CONFIG_SAMV7_HSMCI),y) +CHIP_CSRCS += sam_hsmci.c sam_hsmci_clkdiv.c +endif + +ifeq ($(CONFIG_SAMV7_EMAC),y) +CHIP_CSRCS += sam_emac.c sam_ethernet.c +endif + +ifeq ($(CONFIG_SAMV7_MCAN),y) +CHIP_CSRCS += sam_mcan.c +endif + +ifeq ($(CONFIG_SAMV7_USBDEVHS),y) +CHIP_CSRCS += sam_usbdevhs.c +endif + +ifeq ($(CONFIG_SAMV7_TRNG),y) +CHIP_CSRCS += sam_trng.c +endif + +ifeq ($(CONFIG_SAMV7_PROGMEM),y) +CHIP_CSRCS += sam_progmem.c +endif diff --git a/arch/arm/src/samv7/chip.h b/arch/arm/src/samv7/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..ff612a1080e86fc3cd50c0bcdb4421c6aa08e834 --- /dev/null +++ b/arch/arm/src/samv7/chip.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include +#include "chip/sam_memorymap.h" + +/* If the common ARMv7-M vector handling logic is used, then it expects + * the following definition in this file that provides the number of + * supported vectors external interrupts (which for the SAMV7 is the same + * as the number of peripheral identifiers). + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS NR_PIDS + +/* Cache line sizes (in bytes)for the SAMV71 */ + +#define ARMV7M_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7M_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_H */ diff --git a/arch/arm/src/samv7/chip/sam_afec.h b/arch/arm/src/samv7/chip/sam_afec.h new file mode 100644 index 0000000000000000000000000000000000000000..2f26bf79bc2b4a1f5b03025b14d37b14b8a020d6 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_afec.h @@ -0,0 +1,570 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_afec.h + * Analog-Front-End Controller (AFEC) definitions for the SAMV71 + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_AFEC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_AFEC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_ADC_NCHANNELS 12 /* 12 ADC Channels */ + +/* AFEC register offsets ****************************************************************/ + +#define SAM_AFEC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_AFEC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_AFEC_EMR_OFFSET 0x0008 /* Extended Mode Register */ +#define SAM_AFEC_SEQ1R_OFFSET 0x000c /* Channel Sequence 1 Register */ +#define SAM_AFEC_SEQ2R_OFFSET 0x0010 /* Channel Sequence 2 Register */ +#define SAM_AFEC_CHER_OFFSET 0x0014 /* Channel Enable Register */ +#define SAM_AFEC_CHDR_OFFSET 0x0018 /* Channel Disable Register */ +#define SAM_AFEC_CHSR_OFFSET 0x001c /* Channel Status Register */ +#define SAM_AFEC_LCDR_OFFSET 0x0020 /* Last Converted Data Register */ +#define SAM_AFEC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_AFEC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_AFEC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_AFEC_ISR_OFFSET 0x0030 /* Interrupt Status Register */ + /* 0x0034-0x0040 Reserved */ + /* 0x0044-0x0048 Reserved */ +#define SAM_AFEC_OVER_OFFSET 0x004c /* Overrun Status Register */ +#define SAM_AFEC_CWR_OFFSET 0x0050 /* Compare Window Register */ +#define SAM_AFEC_CGR_OFFSET 0x0054 /* Channel Gain Register */ +#define SAM_AFEC_CDOR_OFFSET 0x005c /* Channel Calibration DC Offset Register */ +#define SAM_AFEC_DIFFR_OFFSET 0x0060 /* Channel Differential Register */ +#define SAM_AFEC_CSELR_OFFSET 0x0064 /* Channel Register Selection */ +#define SAM_AFEC_CDR_OFFSET 0x0068 /* Channel Data Register */ +#define SAM_AFEC_COCR_OFFSET 0x006c /* Channel Offset Compensation Register */ +#define SAM_AFEC_TEMPMR_OFFSET 0x0070 /* Temperature Sensor Mode Register */ +#define SAM_AFEC_TEMPCWR_OFFSET 0x0074 /* Temperature Compare Window Register */ + /* 0x0078-0x0090 Reserved */ +#define SAM_AFEC_ACR_OFFSET 0x0094 /* Analog Control Register */ + /* 0x0098-0x009c Reserved */ +#define SAM_AFEC_SHMR_OFFSET 0x00a0 /* Sample & Hold Mode Register */ + /* 0x00a4-0x00ac Reserved */ +#define SAM_AFEC_COSR_OFFSET 0x00d0 /* Correction Select Register */ +#define SAM_AFEC_CVR_OFFSET 0x00d4 /* Correction Values Register */ +#define SAM_AFEC_CECR_OFFSET 0x00d8 /* Channel Error Correction Register */ + /* 0x00dc-0x00e0 Reserved */ +#define SAM_AFEC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_AFEC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00f8 Reserved */ + /* 0x0fc Reserved */ + +/* AFEC register addresses **************************************************************/ + +#define SAM_AFEC0_CR (SAM_AFEC0_BASE+SAM_AFEC_CR_OFFSET) +#define SAM_AFEC0_MR (SAM_AFEC0_BASE+SAM_AFEC_MR_OFFSET) +#define SAM_AFEC0_EMR (SAM_AFEC0_BASE+SAM_AFEC_EMR_OFFSET) +#define SAM_AFEC0_SEQ1R (SAM_AFEC0_BASE+SAM_AFEC_SEQ1R_OFFSET) +#define SAM_AFEC0_SEQ2R (SAM_AFEC0_BASE+SAM_AFEC_SEQ2R_OFFSET) +#define SAM_AFEC0_CHER (SAM_AFEC0_BASE+SAM_AFEC_CHER_OFFSET) +#define SAM_AFEC0_CHDR (SAM_AFEC0_BASE+SAM_AFEC_CHDR_OFFSET) +#define SAM_AFEC0_CHSR (SAM_AFEC0_BASE+SAM_AFEC_CHSR_OFFSET) +#define SAM_AFEC0_LCDR (SAM_AFEC0_BASE+SAM_AFEC_LCDR_OFFSET) +#define SAM_AFEC0_IER (SAM_AFEC0_BASE+SAM_AFEC_IER_OFFSET) +#define SAM_AFEC0_IDR (SAM_AFEC0_BASE+SAM_AFEC_IDR_OFFSET) +#define SAM_AFEC0_IMR (SAM_AFEC0_BASE+SAM_AFEC_IMR_OFFSET) +#define SAM_AFEC0_ISR (SAM_AFEC0_BASE+SAM_AFEC_ISR_OFFSET) +#define SAM_AFEC0_OVER (SAM_AFEC0_BASE+SAM_AFEC_OVER_OFFSET) +#define SAM_AFEC0_CWR (SAM_AFEC0_BASE+SAM_AFEC_CWR_OFFSET) +#define SAM_AFEC0_CGR (SAM_AFEC0_BASE+SAM_AFEC_CGR_OFFSET) +#define SAM_AFEC0_CDOR (SAM_AFEC0_BASE+SAM_AFEC_CDOR_OFFSET) +#define SAM_AFEC0_DIFFR (SAM_AFEC0_BASE+SAM_AFEC_DIFFR_OFFSET) +#define SAM_AFEC0_CSELR (SAM_AFEC0_BASE+SAM_AFEC_CSELR_OFFSET) +#define SAM_AFEC0_CDR (SAM_AFEC0_BASE+SAM_AFEC_CDR_OFFSET) +#define SAM_AFEC0_COCR (SAM_AFEC0_BASE+SAM_AFEC_COCR_OFFSET) +#define SAM_AFEC0_TEMPMR (SAM_AFEC0_BASE+SAM_AFEC_TEMPMR_OFFSET) +#define SAM_AFEC0_TEMPCWR (SAM_AFEC0_BASE+SAM_AFEC_TEMPCWR_OFFSET) +#define SAM_AFEC0_ACR (SAM_AFEC0_BASE+SAM_AFEC_ACR_OFFSET) +#define SAM_AFEC0_SHMR (SAM_AFEC0_BASE+SAM_AFEC_SHMR_OFFSET) +#define SAM_AFEC0_COSR (SAM_AFEC0_BASE+SAM_AFEC_COSR_OFFSET) +#define SAM_AFEC0_CVR (SAM_AFEC0_BASE+SAM_AFEC_CVR_OFFSET) +#define SAM_AFEC0_CECR (SAM_AFEC0_BASE+SAM_AFEC_CECR_OFFSET) +#define SAM_AFEC0_WPMR (SAM_AFEC0_BASE+SAM_AFEC_WPMR_OFFSET) +#define SAM_AFEC0_WPSR (SAM_AFEC0_BASE+SAM_AFEC_WPSR_OFFSET) + +#define SAM_AFEC1_CR (SAM_AFEC1_BASE+SAM_AFEC_CR_OFFSET) +#define SAM_AFEC1_MR (SAM_AFEC1_BASE+SAM_AFEC_MR_OFFSET) +#define SAM_AFEC1_EMR (SAM_AFEC1_BASE+SAM_AFEC_EMR_OFFSET) +#define SAM_AFEC1_SEQ1R (SAM_AFEC1_BASE+SAM_AFEC_SEQ1R_OFFSET) +#define SAM_AFEC1_SEQ2R (SAM_AFEC1_BASE+SAM_AFEC_SEQ2R_OFFSET) +#define SAM_AFEC1_CHER (SAM_AFEC1_BASE+SAM_AFEC_CHER_OFFSET) +#define SAM_AFEC1_CHDR (SAM_AFEC1_BASE+SAM_AFEC_CHDR_OFFSET) +#define SAM_AFEC1_CHSR (SAM_AFEC1_BASE+SAM_AFEC_CHSR_OFFSET) +#define SAM_AFEC1_LCDR (SAM_AFEC1_BASE+SAM_AFEC_LCDR_OFFSET) +#define SAM_AFEC1_IER (SAM_AFEC1_BASE+SAM_AFEC_IER_OFFSET) +#define SAM_AFEC1_IDR (SAM_AFEC1_BASE+SAM_AFEC_IDR_OFFSET) +#define SAM_AFEC1_IMR (SAM_AFEC1_BASE+SAM_AFEC_IMR_OFFSET) +#define SAM_AFEC1_ISR (SAM_AFEC1_BASE+SAM_AFEC_ISR_OFFSET) +#define SAM_AFEC1_OVER (SAM_AFEC1_BASE+SAM_AFEC_OVER_OFFSET) +#define SAM_AFEC1_CWR (SAM_AFEC1_BASE+SAM_AFEC_CWR_OFFSET) +#define SAM_AFEC1_CGR (SAM_AFEC1_BASE+SAM_AFEC_CGR_OFFSET) +#define SAM_AFEC1_CDOR (SAM_AFEC1_BASE+SAM_AFEC_CDOR_OFFSET) +#define SAM_AFEC1_DIFFR (SAM_AFEC1_BASE+SAM_AFEC_DIFFR_OFFSET) +#define SAM_AFEC1_CSELR (SAM_AFEC1_BASE+SAM_AFEC_CSELR_OFFSET) +#define SAM_AFEC1_CDR (SAM_AFEC1_BASE+SAM_AFEC_CDR_OFFSET) +#define SAM_AFEC1_COCR (SAM_AFEC1_BASE+SAM_AFEC_COCR_OFFSET) +#define SAM_AFEC1_TEMPMR (SAM_AFEC1_BASE+SAM_AFEC_TEMPMR_OFFSET) +#define SAM_AFEC1_TEMPCWR (SAM_AFEC1_BASE+SAM_AFEC_TEMPCWR_OFFSET) +#define SAM_AFEC1_ACR (SAM_AFEC1_BASE+SAM_AFEC_ACR_OFFSET) +#define SAM_AFEC1_SHMR (SAM_AFEC1_BASE+SAM_AFEC_SHMR_OFFSET) +#define SAM_AFEC1_COSR (SAM_AFEC1_BASE+SAM_AFEC_COSR_OFFSET) +#define SAM_AFEC1_CVR (SAM_AFEC1_BASE+SAM_AFEC_CVR_OFFSET) +#define SAM_AFEC1_CECR (SAM_AFEC1_BASE+SAM_AFEC_CECR_OFFSET) +#define SAM_AFEC1_WPMR (SAM_AFEC1_BASE+SAM_AFEC_WPMR_OFFSET) +#define SAM_AFEC1_WPSR (SAM_AFEC1_BASE+SAM_AFEC_WPSR_OFFSET) + +/* AFEC register bit definitions *******************************************************/ + +/* Control Register */ + +#define AFEC_CR_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define AFEC_CR_START (1 << 1) /* Bit 1: Start Conversion */ + +/* Mode Register */ + +#define AFEC_MR_TRGEN (1 << 0) /* Bit 0: Trigger Enable */ +#define AFEC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define AFEC_MR_TRGSEL_MASK (7 << AFEC_MR_TRGSEL_SHIFT) +# define AFEC_MR_TRGSEL_ADTRG (0 << AFEC_MR_TRGSEL_SHIFT) /* ADTRG */ +# define AFEC_MR_TRGSEL_TIOA0 (1 << AFEC_MR_TRGSEL_SHIFT) /* TIOA0 */ +# define AFEC_MR_TRGSEL_TIOA1 (2 << AFEC_MR_TRGSEL_SHIFT) /* TIOA1 */ +# define AFEC_MR_TRGSEL_TIOA2 (3 << AFEC_MR_TRGSEL_SHIFT) /* TIOA2 */ +# define AFEC_MR_TRGSEL_PWM0 (4 << AFEC_MR_TRGSEL_SHIFT) /* PWM Event Line 0 */ +# define AFEC_MR_TRGSEL_PWM1 (5 << AFEC_MR_TRGSEL_SHIFT) /* PWM Event Line 1 */ +# define AFEC_MR_TRGSEL_ACMP (6 << AFEC_MR_TRGSEL_SHIFT) /* Analog comparator */ +#define AFEC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ +#define AFEC_MR_FWUP (1 << 6) /* Bit 6: Fast Wake Up */ +#define AFEC_MR_FREERUN (1 << 7) /* Bit 7: Free Run Mode */ +#define AFEC_MR_PRESCAL_SHIFT (8) /* Bits 8-15: Prescaler Rate Selection */ +#define AFEC_MR_PRESCAL_MASK (0xff << AFEC_MR_PRESCAL_SHIFT) +# define AFEC_MR_PRESCAL(n) ((uint32_t)(n) << AFEC_MR_PRESCAL_SHIFT) +#define AFEC_MR_STARTUP_SHIFT (16) /* Bits 16-19: Start Up Time */ +#define AFEC_MR_STARTUP_MASK (15 << AFEC_MR_STARTUP_SHIFT) +# define AFEC_MR_STARTUP_0 (0 << AFEC_MR_STARTUP_SHIFT) /* 0 periods of ADCClock */ +# define AFEC_MR_STARTUP_8 (1 << AFEC_MR_STARTUP_SHIFT) /* 8 periods of ADCClock */ +# define AFEC_MR_STARTUP_16 (2 << AFEC_MR_STARTUP_SHIFT) /* 16 periods of ADCClock */ +# define AFEC_MR_STARTUP_24 (3 << AFEC_MR_STARTUP_SHIFT) /* 24 periods of ADCClock */ +# define AFEC_MR_STARTUP_64 (4 << AFEC_MR_STARTUP_SHIFT) /* 64 periods of ADCClock */ +# define AFEC_MR_STARTUP_80 (5 << AFEC_MR_STARTUP_SHIFT) /* 80 periods of ADCClock */ +# define AFEC_MR_STARTUP_96 (6 << AFEC_MR_STARTUP_SHIFT) /* 96 periods of ADCClock */ +# define AFEC_MR_STARTUP_112 (7 << AFEC_MR_STARTUP_SHIFT) /* 112 periods of ADCClock */ +# define AFEC_MR_STARTUP_512 (8 << AFEC_MR_STARTUP_SHIFT) /* 512 periods of ADCClock */ +# define AFEC_MR_STARTUP_576 (9 << AFEC_MR_STARTUP_SHIFT) /* 576 periods of ADCClock */ +# define AFEC_MR_STARTUP_640 (10 << AFEC_MR_STARTUP_SHIFT) /* 640 periods of ADCClock */ +# define AFEC_MR_STARTUP_704 (11 << AFEC_MR_STARTUP_SHIFT) /* 704 periods of ADCClock */ +# define AFEC_MR_STARTUP_768 (12 << AFEC_MR_STARTUP_SHIFT) /* 768 periods of ADCClock */ +# define AFEC_MR_STARTUP_832 (13 << AFEC_MR_STARTUP_SHIFT) /* 832 periods of ADCClock */ +# define AFEC_MR_STARTUP_896 (14 << AFEC_MR_STARTUP_SHIFT) /* 896 periods of ADCClock */ +# define AFEC_MR_STARTUP_960 (15 << AFEC_MR_STARTUP_SHIFT) /* 960 periods of ADCClock */ +#define AFEC_MR_SETTLING_SHIFT (20) /* Bits 20-21: Analog Settling Time */ +#define AFEC_MR_SETTLING_MASK (15 << AFEC_MR_SETTLING_SHIFT) +# define AFEC_MR_SETTLING_3 (0 << AFEC_MR_SETTLING_SHIFT) /* 3 periods of ADCClock */ +# define AFEC_MR_SETTLING_5 (1 << AFEC_MR_SETTLING_SHIFT) /* 5 periods of ADCClock */ +# define AFEC_MR_SETTLING_9 (2 << AFEC_MR_SETTLING_SHIFT) /* 9 periods of ADCClock */ +# define AFEC_MR_SETTLING_17 (3 << AFEC_MR_SETTLING_SHIFT) /* 17 periods of ADCClock */ +#define AFEC_MR_ONE (1 << 23) /* Bit 23: Must be one */ +#define AFEC_MR_TRACKTIM_SHIFT (24) /* Bits 24-27: Tracking Time */ +#define AFEC_MR_TRACKTIM_MASK (15 << AFEC_MR_TRACKTIM_SHIFT) +# define AFEC_MR_TRACKTIM(n) ((uint32_t)(n) << AFEC_MR_TRACKTIM_SHIFT) +#define AFEC_MR_TRANSFER_SHIFT (28) /* Bits 28-29: Transfer Period */ +#define AFEC_MR_TRANSFER_MASK (3 << AFEC_MR_TRANSFER_SHIFT) +# define AFEC_MR_TRANSFER(n) ((uint32_t)(n) << AFEC_MR_TRANSFER_SHIFT) +#define AFEC_MR_USEQ (1 << 31) /* Bit 31: Use Sequence Enable */ + +/* Extended Mode Register */ + +#define AFEC_EMR_CMPMODE_SHIFT (0) /* Bit 0-1: Comparison Mode */ +#define AFEC_EMR_CMPMODE_MASK (3 << AFEC_EMR_CMPMODE_SHIFT) +# define AFEC_EMR_CMPMODE_LOW (0 << AFEC_EMR_CMPMODE_SHIFT) /* Event when lower than low window threshold */ +# define AFEC_EMR_CMPMODE_HIGH (1 << AFEC_EMR_CMPMODE_SHIFT) /* Event when higher than high window threshold */ +# define AFEC_EMR_CMPMODE_IN (2 << AFEC_EMR_CMPMODE_SHIFT) /* Event when in comparison window */ +# define AFEC_EMR_CMPMODE_OUT (3 << AFEC_EMR_CMPMODE_SHIFT) /* Event when out of comparison window */ +#define AFEC_EMR_CMPSEL_SHIFT (3) /* Bit 3-7: Comparison Selected Channel */ +#define AFEC_EMR_CMPSEL_MASK (31 << AFEC_EMR_CMPSEL_SHIFT) +# define AFEC_EMR_CMPSEL(n) ((uint32_t)(n) << AFEC_EMR_CMPSEL_SHIFT) +#define AFEC_EMR_CMPALL (1 << 9) /* Bit 9: Compare All Channels */ +#define AFEC_EMR_CMPFILTER_SHIFT (12) /* Bits 12-13: Compare Event Filtering */ +#define AFEC_EMR_CMPFILTER_MASK (3 << AFEC_EMR_CMPFILTER_SHIFT) +# define AFEC_EMR_CMPFILTER(n) ((uint32_t)(n) << AFEC_EMR_CMPFILTER_SHIFT) +#define AFEC_EMR_RES_SHIFT (16) /* Bits 16-18: Resolution */ +#define AFEC_EMR_RES_MASK (7 << AFEC_EMR_RES_SHIFT) +# define AFEC_EMR_RES_NOAVG (0 << AFEC_EMR_RES_SHIFT) /* 12-bit resolution, AFEC sample rate is maximum (no averaging) */ +# define AFEC_EMR_RES_OSR4 (2 << AFEC_EMR_RES_SHIFT) /* 13-bit resolution, AFEC sample rate divided by 4 (averaging) */ +# define AFEC_EMR_RES_OSR16 (3 << AFEC_EMR_RES_SHIFT) /* 14-bit resolution, AFEC sample rate divided by 16 (averaging) */ +# define AFEC_EMR_RES_OSR64 (4 << AFEC_EMR_RES_SHIFT) /* 15-bit resolution, AFEC sample rate divided by 64 (averaging) */ +# define AFEC_EMR_RES_OSR256 (5 << AFEC_EMR_RES_SHIFT) /* 16-bit resolution, AFEC sample rate divided by 256 (averaging) */ +#define AFEC_EMR_TAG (1 << 24) /* Bit 24: TAG of the AFEC_LDCR register */ +#define AFEC_EMR_STM (1 << 25) /* Bit 25: Single Trigger Mode */ +#define AFEC_EMR_SIGNMODE_SHIFT (28) /* Bits 28-29: Sign mode */ +#define AFEC_EMR_SIGNMODE_MASK (3 << AFEC_EMR_SIGNMODE_SHIFT) +# define AFEC_EMR_SIGNMODE_SEUNSG (0 << AFEC_EMR_SIGNMODE_SHIFT) /* Single ended channels unsigned */ +# define AFEC_EMR_SIGNMODE_DFSIGN (0 << AFEC_EMR_SIGNMODE_SHIFT) /* Differential channels signed */ +# define AFEC_EMR_SIGNMODE_SESIGN (1 << AFEC_EMR_SIGNMODE_SHIFT) /* Singed ended channels signed */ +# define AFEC_EMR_SIGNMODE_DFUNSG (1 << AFEC_EMR_SIGNMODE_SHIFT) /* Differential channels unsiged */ +# define AFEC_EMR_SIGNMODE_UNSIGNED (2 << AFEC_EMR_SIGNMODE_SHIFT) /* All channels unsigned */ +# define AFEC_EMR_SIGNMODE_SIGNED (2 << AFEC_EMR_SIGNMODE_SHIFT) /* All channels signed */ + +/* Channel Sequence 1 Register */ + +#define AFEC_SEQ1R_USCH_SHIFT(n) ((n) << 2) /* n=0..7 */ +#define AFEC_SEQ1R_USCH_MASK(n) (15 << AFEC_SEQ1R_USCH_SHIFT(n)) +# define AFEC_SEQ1R_USCH(n,v) ((uint32_t)(v) << AFEC_SEQ1R_USCH_SHIFT(n)) +#define AFEC_SEQ1R_USCH0_SHIFT (0) /* Bits 0-3: User sequence number 0 */ +#define AFEC_SEQ1R_USCH0_MASK (15 << AFEC_SEQ1R_USCH0_SHIFT) +# define AFEC_SEQ1R_USCH0(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH0_SHIFT) +#define AFEC_SEQ1R_USCH1_SHIFT (4) /* Bits 4-7: User sequence number 1 */ +#define AFEC_SEQ1R_USCH1_MASK (15 << AFEC_SEQ1R_USCH1_SHIFT) +# define AFEC_SEQ1R_USCH1(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH1_SHIFT) +#define AFEC_SEQ1R_USCH2_SHIFT (8) /* Bits 8-11: User sequence number 2 */ +#define AFEC_SEQ1R_USCH2_MASK (15 << AFEC_SEQ1R_USCH2_SHIFT) +# define AFEC_SEQ1R_USCH2(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH2_SHIFT) +#define AFEC_SEQ1R_USCH3_SHIFT (12) /* Bits 12-15: User sequence number 3 */ +#define AFEC_SEQ1R_USCH3_MASK (15 << AFEC_SEQ1R_USCH3_SHIFT) +# define AFEC_SEQ1R_USCH3(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH3_SHIFT) +#define AFEC_SEQ1R_USCH4_SHIFT (16) /* Bits 16-19: User sequence number 4 */ +#define AFEC_SEQ1R_USCH4_MASK (15 << AFEC_SEQ1R_USCH4_SHIFT) +# define AFEC_SEQ1R_USCH4(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH4_SHIFT) +#define AFEC_SEQ1R_USCH5_SHIFT (20) /* Bits 20-23: User sequence number 5 */ +#define AFEC_SEQ1R_USCH5_MASK (15 << AFEC_SEQ1R_USCH5_SHIFT) +# define AFEC_SEQ1R_USCH5(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH5_SHIFT) +#define AFEC_SEQ1R_USCH6_SHIFT (24) /* Bits 24-27: User sequence number 6 */ +#define AFEC_SEQ1R_USCH6_MASK (15 << AFEC_SEQ1R_USCH6_SHIFT) +# define AFEC_SEQ1R_USCH6(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH6_SHIFT) +#define AFEC_SEQ1R_USCH7_SHIFT (28) /* Bits 28-31: User sequence number 7 */ +#define AFEC_SEQ1R_USCH7_MASK (15 << AFEC_SEQ1R_USCH7_SHIFT) +# define AFEC_SEQ1R_USCH7(v) ((uint32_t)(v) << AFEC_SEQ1R_USCH7_SHIFT) + +/* Channel Sequence 2 Register */ + +#define AFEC_SEQ2R_USCH_SHIFT(n) (((n)-8) << 2) /* n=8..15 */ +#define AFEC_SEQ2R_USCH_MASK(n) (15 << AFEC_SEQ2R_USCH_SHIFT(n)) +# define AFEC_SEQ2R_USCH(n,v) ((uint32_t)(v) << AFEC_SEQ2R_USCH_SHIFT(n)) +#define AFEC_SEQ2R_USCH8_SHIFT (0) /* Bits 0-3: User sequence number 8 */ +#define AFEC_SEQ2R_USCH8_MASK (15 << AFEC_SEQ2R_USCH8_SHIFT) +# define AFEC_SEQ2R_USCH8(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH8_SHIFT) +#define AFEC_SEQ2R_USCH9_SHIFT (4) /* Bits 4-7: User sequence number 9 */ +#define AFEC_SEQ2R_USCH9_MASK (15 << AFEC_SEQ2R_USCH9_SHIFT) +# define AFEC_SEQ2R_USCH9(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH9_SHIFT) +#define AFEC_SEQ2R_USCH10_SHIFT (8) /* Bits 8-11: User sequence number 10 */ +#define AFEC_SEQ2R_USCH10_MASK (15 << AFEC_SEQ2R_USCH10_SHIFT) +# define AFEC_SEQ2R_USCH10(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH10_SHIFT) +#define AFEC_SEQ2R_USCH11_SHIFT (12) /* Bits 12-15: User sequence number 11 */ +#define AFEC_SEQ2R_USCH11_MASK (15 << AFEC_SEQ2R_USCH11_SHIFT) +# define AFEC_SEQ2R_USCH11(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH11_SHIFT) +#define AFEC_SEQ2R_USCH12_SHIFT (16) /* Bits 16-19: User sequence number 12 */ +#define AFEC_SEQ2R_USCH12_MASK (15 << AFEC_SEQ2R_USCH12_SHIFT) +# define AFEC_SEQ2R_USCH12(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH12_SHIFT) +#define AFEC_SEQ2R_USCH13_SHIFT (20) /* Bits 20-23: User sequence number 13 */ +#define AFEC_SEQ2R_USCH13_MASK (15 << AFEC_SEQ2R_USCH13_SHIFT) +# define AFEC_SEQ2R_USCH13(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH13_SHIFT) +#define AFEC_SEQ2R_USCH14_SHIFT (24) /* Bits 24-27: User sequence number 14 */ +#define AFEC_SEQ2R_USCH14_MASK (15 << AFEC_SEQ2R_USCH14_SHIFT) +# define AFEC_SEQ2R_USCH14(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH14_SHIFT) +#define AFEC_SEQ2R_USCH15_SHIFT (28) /* Bits 28-31: User sequence number 15 */ +#define AFEC_SEQ2R_USCH15_MASK (15 << AFEC_SEQ2R_USCH15_SHIFT) +# define AFEC_SEQ2R_USCH15(v) ((uint32_t)(v) << AFEC_SEQ2R_USCH15_SHIFT) + +/* Channel Enable, Channel Disable, and Channel Status Registers */ + +#define AFEC_CH(n) (1 << (n)) +# define AFEC_CH0 (1 << 0) /* Bit 0: Channel 0 Enable */ +# define AFEC_CH1 (1 << 1) /* Bit 1: Channel 1 Enable */ +# define AFEC_CH2 (1 << 2) /* Bit 2: Channel 2 Enable */ +# define AFEC_CH3 (1 << 3) /* Bit 3: Channel 3 Enable */ +# define AFEC_CH4 (1 << 4) /* Bit 4: Channel 4 Enable */ +# define AFEC_CH5 (1 << 5) /* Bit 5: Channel 5 Enable */ +# define AFEC_CH6 (1 << 6) /* Bit 6: Channel 6 Enable */ +# define AFEC_CH7 (1 << 7) /* Bit 7: Channel 7 Enable */ +# define AFEC_CH8 (1 << 8) /* Bit 8: Channel 8 Enable */ +# define AFEC_CH9 (1 << 9) /* Bit 9: Channel 9 Enable */ +# define AFEC_CH10 (1 << 10) /* Bit 10: Channel 10 Enable */ +# define AFEC_CH11 (1 << 11) /* Bit 11: Channel 11 Enable */ +# define AFEC_CHALL (0x00000fff) + +/* Last Converted Data Register */ + +#define AFEC_LCDR_LDATA_SHIFT (0) /* Bits 0-15: Last Data Converted */ +#define AFEC_LCDR_LDATA_MASK (0xffff << AFEC_LCDR_LDATA_SHIFT) +#define AFEC_LCDR_CHANB_SHIFT (24) /* Bits 24-27: Channel number */ +#define AFEC_LCDR_CHANB_MASK (15 << AFEC_LCDR_CHANB_SHIFT) + +/* Interrupt Enable, Interrupt Disable, Interrupt Mask, and Interrupt Status Registers */ + +#define AFEC_INT_EOC(n) (1 << (n)) +# define AFEC_INT_EOC0 (1 << 0) /* Bit 0: End of Conversion 0 */ +# define AFEC_INT_EOC1 (1 << 1) /* Bit 1: End of Conversion 1 */ +# define AFEC_INT_EOC2 (1 << 2) /* Bit 2: End of Conversion 2 */ +# define AFEC_INT_EOC3 (1 << 3) /* Bit 3: End of Conversion 3 */ +# define AFEC_INT_EOC4 (1 << 4) /* Bit 4: End of Conversion 4 */ +# define AFEC_INT_EOC5 (1 << 5) /* Bit 5: End of Conversion 5 */ +# define AFEC_INT_EOC6 (1 << 6) /* Bit 6: End of Conversion 6 */ +# define AFEC_INT_EOC7 (1 << 7) /* Bit 7: End of Conversion 7 */ +# define AFEC_INT_EOC8 (1 << 8) /* Bit 8: End of Conversion 8 */ +# define AFEC_INT_EOC9 (1 << 9) /* Bit 9: End of Conversion 9 */ +# define AFEC_INT_EOC10 (1 << 10) /* Bit 10: End of Conversion 10 */ +# define AFEC_INT_EOC11 (1 << 11) /* Bit 11: End of Conversion 11 */ +# define AFEC_INT_EOCALL (0x00000fff) + +#define AFEC_INT_DRDY (1 << 24) /* Bit 24: Data Ready Interrupt */ +#define AFEC_INT_GOVRE (1 << 25) /* Bit 25: General Overrun Error */ +#define AFEC_INT_COMPE (1 << 26) /* Bit 26: Comparison Event Interrupt */ +#define AFEC_INT_TEMPCHG (1 << 30) /* Bit 30: Temperature Change Interrupt */ + +#define AFEC_INT_ALL (0x47000fff) + +/* Overrun Status Register */ + +#define AFEC_OVER_OVRE(n) (1 << (n)) +# define AFEC_OVER_OVRE0 (1 << 0) /* Bit 0: Overrun Error 0 */ +# define AFEC_OVER_OVRE1 (1 << 1) /* Bit 1: Overrun Error 1 */ +# define AFEC_OVER_OVRE2 (1 << 2) /* Bit 2: Overrun Error 2 */ +# define AFEC_OVER_OVRE3 (1 << 3) /* Bit 3: Overrun Error 3 */ +# define AFEC_OVER_OVRE4 (1 << 4) /* Bit 4: Overrun Error 4 */ +# define AFEC_OVER_OVRE5 (1 << 5) /* Bit 5: Overrun Error 5 */ +# define AFEC_OVER_OVRE6 (1 << 6) /* Bit 6: Overrun Error 6 */ +# define AFEC_OVER_OVRE7 (1 << 7) /* Bit 7: Overrun Error 7 */ +# define AFEC_OVER_OVRE8 (1 << 8) /* Bit 8: Overrun Error 8 */ +# define AFEC_OVER_OVRE9 (1 << 9) /* Bit 9: Overrun Error 9 */ +# define AFEC_OVER_OVRE10 (1 << 10) /* Bit 10: Overrun Error 10 */ +# define AFEC_OVER_OVRE11 (1 << 11) /* Bit 11: Overrun Error 11 */ + +/* Compare Window Register */ + +#define AFEC_CWR_LOWTHRES_SHIFT (0) /* Bits 0-11: Low Threshold */ +#define AFEC_CWR_LOWTHRES_MASK (0xfff << AFEC_CWR_LOWTHRES_SHIFT) +# define AFEC_CWR_LOWTHRES(n) ((uint32_t)(n) << AFEC_CWR_LOWTHRES_SHIFT) +#define AFEC_CWR_HIGHTHRES_SHIFT (16) /* Bits 16-27: High Threshold */ +#define AFEC_CWR_HIGHTHRES_MASK (0xfff << AFEC_CWR_LOWTHRES_SHIFT) +# define AFEC_CWR_HIGHTHRES(n)K ((uint32_t)(n) << AFEC_CWR_LOWTHRES_SHIFT) + +/* Channel Gain Register */ + +#define AFEC_CGR_GAIN_SHIFT(n) ((n) << 1) /* n=0..15 */ +#define AFEC_CGR_GAIN_MASK(n) (3 << AFEC_CGR_GAIN_SHIFT(n)) +# define AFEC_CGR_GAIN(n,v) ((uint32_t)(v) << AFEC_CGR_GAIN_SHIFT(n)) +#define AFEC_CGR_GAIN0_SHIFT (0) /* Bits 0-1: Gain for channel 0 */ +#define AFEC_CGR_GAIN0_MASK (3 << AFEC_CGR_GAIN0_SHIFT) +# define AFEC_CGR_GAIN0(v) ((uint32_t)(v) << AFEC_CGR_GAIN0_SHIFT) +#define AFEC_CGR_GAIN1_SHIFT (2) /* Bits 2-3: Gain for channel 1 */ +#define AFEC_CGR_GAIN1_MASK (3 << AFEC_CGR_GAIN1_SHIFT) +# define AFEC_CGR_GAIN1(v) ((uint32_t)(v) << AFEC_CGR_GAIN1_SHIFT) +#define AFEC_CGR_GAIN2_SHIFT (4) /* Bits 4-5: Gain for channel 2 */ +#define AFEC_CGR_GAIN2_MASK (3 << AFEC_CGR_GAIN2_SHIFT) +# define AFEC_CGR_GAIN2(v) ((uint32_t)(v) << AFEC_CGR_GAIN2_SHIFT) +#define AFEC_CGR_GAIN3_SHIFT (6) /* Bits 6-7: Gain for channel 3 */ +#define AFEC_CGR_GAIN3_MASK (3 << AFEC_CGR_GAIN3_SHIFT) +# define AFEC_CGR_GAIN3(v) ((uint32_t)(v) << AFEC_CGR_GAIN3_SHIFT) +#define AFEC_CGR_GAIN4_SHIFT (8) /* Bits 8-9: Gain for channel 4 */ +#define AFEC_CGR_GAIN4_MASK (3 << AFEC_CGR_GAIN4_SHIFT) +# define AFEC_CGR_GAIN4(v) ((uint32_t)(v) << AFEC_CGR_GAIN4_SHIFT) +#define AFEC_CGR_GAIN5_SHIFT (10) /* Bits 10-11: Gain for channel 5 */ +#define AFEC_CGR_GAIN5_MASK (3 << AFEC_CGR_GAIN5_SHIFT) +# define AFEC_CGR_GAIN5(v) ((uint32_t)(v) << AFEC_CGR_GAIN5_SHIFT) +#define AFEC_CGR_GAIN6_SHIFT (12) /* Bits 12-13: Gain for channel 6 */ +#define AFEC_CGR_GAIN6_MASK (3 << AFEC_CGR_GAIN6_SHIFT) +# define AFEC_CGR_GAIN6(v) ((uint32_t)(v) << AFEC_CGR_GAIN6_SHIFT) +#define AFEC_CGR_GAIN7_SHIFT (14) /* Bits 14-15: Gain for channel 7 */ +#define AFEC_CGR_GAIN7_MASK (3 << AFEC_CGR_GAIN7_SHIFT) +# define AFEC_CGR_GAIN7(v) ((uint32_t)(v) << AFEC_CGR_GAIN7_SHIFT) +#define AFEC_CGR_GAIN8_SHIFT (16) /* Bits 16-17: Gain for channel 8 */ +#define AFEC_CGR_GAIN8_MASK (3 << AFEC_CGR_GAIN8_SHIFT) +# define AFEC_CGR_GAIN8(v) ((uint32_t)(v) << AFEC_CGR_GAIN8_SHIFT) +#define AFEC_CGR_GAIN9_SHIFT (18) /* Bits 18-19: Gain for channel 9 */ +#define AFEC_CGR_GAIN9_MASK (3 << AFEC_CGR_GAIN9_SHIFT) +# define AFEC_CGR_GAIN9(v) ((uint32_t)(v) << AFEC_CGR_GAIN9_SHIFT) +#define AFEC_CGR_GAIN10_SHIFT (20) /* Bits 20-21: Gain for channel 10 */ +#define AFEC_CGR_GAIN10_MASK (3 << AFEC_CGR_GAIN10_SHIFT) +# define AFEC_CGR_GAIN10(v) ((uint32_t)(v) << AFEC_CGR_GAIN10_SHIFT) +#define AFEC_CGR_GAIN11_SHIFT (22) /* Bits 22-23: Gain for channel 11 */ +#define AFEC_CGR_GAIN11_MASK (3 << AFEC_CGR_GAIN11_SHIFT) +# define AFEC_CGR_GAIN11(v) ((uint32_t)(v) << AFEC_CGR_GAIN11_SHIFT) + +/* Channel Calibration DC Offset Register (Used in Automatic Calibration Procedure) */ + +#define AFEC_CDOR_OFF(n) (1 << (n)) +# define AFEC_CDOR_OFF0 (1 << 0) /* Bit 0: Offset for channel 0 */ +# define AFEC_CDOR_OFF1 (1 << 1) /* Bit 1: Offset for channel 1 */ +# define AFEC_CDOR_OFF2 (1 << 2) /* Bit 2: Offset for channel 2 */ +# define AFEC_CDOR_OFF3 (1 << 3) /* Bit 3: Offset for channel 3 */ +# define AFEC_CDOR_OFF4 (1 << 4) /* Bit 4: Offset for channel 4 */ +# define AFEC_CDOR_OFF5 (1 << 5) /* Bit 5: Offset for channel 5 */ +# define AFEC_CDOR_OFF6 (1 << 6) /* Bit 6: Offset for channel 6 */ +# define AFEC_CDOR_OFF7 (1 << 7) /* Bit 7: Offset for channel 7 */ +# define AFEC_CDOR_OFF8 (1 << 8) /* Bit 8: Offset for channel 8 */ +# define AFEC_CDOR_OFF9 (1 << 9) /* Bit 9: Offset for channel 9 */ +# define AFEC_CDOR_OFF10 (1 << 10) /* Bit 10: Offset for channel 10 */ +# define AFEC_CDOR_OFF11 (1 << 11) /* Bit 11: Offset for channel 11 */ + +/* Channel Differential Register */ + +#define AFEC_DIFFR_DIFF(n) (1 << (n)) +# define AFEC_DIFFR_DIFF0 (1 << 0) /* Bit 0: Differential inputs for channel 0 */ +# define AFEC_DIFFR_DIFF1 (1 << 1) /* Bit 1: Differential inputs for channel 1 */ +# define AFEC_DIFFR_DIFF2 (1 << 2) /* Bit 2: Differential inputs for channel 2 */ +# define AFEC_DIFFR_DIFF3 (1 << 3) /* Bit 3: Differential inputs for channel 3 */ +# define AFEC_DIFFR_DIFF4 (1 << 4) /* Bit 4: Differential inputs for channel 4 */ +# define AFEC_DIFFR_DIFF5 (1 << 5) /* Bit 5: Differential inputs for channel 5 */ +# define AFEC_DIFFR_DIFF6 (1 << 6) /* Bit 6: Differential inputs for channel 6 */ +# define AFEC_DIFFR_DIFF7 (1 << 7) /* Bit 7: Differential inputs for channel 7 */ +# define AFEC_DIFFR_DIFF8 (1 << 8) /* Bit 8: Differential inputs for channel 8 */ +# define AFEC_DIFFR_DIFF9 (1 << 9) /* Bit 9: Differential inputs for channel 9 */ +# define AFEC_DIFFR_DIFF10 (1 << 10) /* Bit 10: Differential inputs for channel 10 */ +# define AFEC_DIFFR_DIFF11 (1 << 11) /* Bit 11: Differential inputs for channel 11 */ + +/* Channel Selection Register */ + +#define AFEC_CSELR_CSEL_SHIFT (0) /* Bits 0-3: Channel Selection */ +#define AFEC_CSELR_CSEL_MASK (15 << AFEC_CSELR_CSEL_SHIFT) +# define AFEC_CSELR_CSEL(n) ((uint32_t)(n) << AFEC_CSELR_CSEL_SHIFT) + +/* Channel Data Register */ + +#define AFEC_CDR_MASK (0x0000ffff) /* Bits 0-15: Converted Data */ + +/* Channel Offset Compensation Register */ + +#define AFEC_COCR_MASK (0x00000fff) /* Bits 0-12: Analog Offset */ + +/* Temperature Sensor Mode Register */ + +#define AFEC_TEMPMR_RTCT (1 << 0) /* Bit 0: Temperature Sensor RTC Trigger mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_SHIFT (4) /* Bits 4-5: Temperature Comparison Mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_MASK (3 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) +# define AFEC_TEMPMR_TEMPCMPMOD_LOW (0 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is lower than low threshold */ +# define AFEC_TEMPMR_TEMPCMPMOD_HIGH (1 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is higher than high threshold */ +# define AFEC_TEMPMR_TEMPCMPMOD_IN (2 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is in the comparison window */ +# define AFEC_TEMPMR_TEMPCMPMOD_OUT (3 << AFEC_TEMPMR_TEMPCMPMOD_SHIFT) /* Event when data is out of the comparison window */ + +/* Temperature Compare Window Register */ + +#define AFEC_TEMPCWR_TLOWTHRES_SHIFT (0) /* Bits 0-15: Temperature Low Threshold */ +#define AFEC_TEMPCWR_TLOWTHRES_MASK (0xffff << AFEC_TEMPCWR_TLOWTHRES_SHIFT) +# define AFEC_TEMPCWR_TLOWTHRES(n) (0xffff << AFEC_TEMPCWR_TLOWTHRES_SHIFT) +#define AFEC_TEMPCWR_THIGHTHRES_SHIFT (16) /* Bits 16-31: Temperature High Threshold */ +#define AFEC_TEMPCWR_THIGHTHRES_MASK (0xffff << AFEC_TEMPCWR_THIGHTHRES_SHIFT) +# define AFEC_TEMPCWR_THIGHTHRES(n) ((uint32_t)(n) << AFEC_TEMPCWR_THIGHTHRES_SHIFT) + +/* Analog Control Register */ + +#define AFEC_ACR_PGA0EN (1 << 2) /* Bit 2: PGA0 Enable */ +#define AFEC_ACR_PGA1EN (1 << 3) /* Bit 3: PGA1 Enable */ +#define AFEC_ACR_IBCTL_SHIFT (9) /* Bits 8-9: AFEC Bias Current Control */ +#define AFEC_ACR_IBCTL_MASK (3 << AFEC_ACR_IBCTL_SHIFT) +# define AFEC_ACR_IBCTL(n) ((uint32_t)(n) << AFEC_ACR_IBCTL_SHIFT) + +/* Sample & Hold Mode Register */ + +#define AFEC_SHMR_DUAL(n) (1 << (n)) +# define AFEC_SHMR_DUAL0 (1 << 0) /* Bit 0: Dual Sample & Hold for channel 0 */ +# define AFEC_SHMR_DUAL1 (1 << 1) /* Bit 1: Dual Sample & Hold for channel 1 */ +# define AFEC_SHMR_DUAL2 (1 << 2) /* Bit 2: Dual Sample & Hold for channel 2 */ +# define AFEC_SHMR_DUAL3 (1 << 3) /* Bit 3: Dual Sample & Hold for channel 3 */ +# define AFEC_SHMR_DUAL4 (1 << 4) /* Bit 4: Dual Sample & Hold for channel 4 */ +# define AFEC_SHMR_DUAL5 (1 << 5) /* Bit 5: Dual Sample & Hold for channel 5 */ +# define AFEC_SHMR_DUAL6 (1 << 6) /* Bit 6: Dual Sample & Hold for channel 6 */ +# define AFEC_SHMR_DUAL7 (1 << 7) /* Bit 7: Dual Sample & Hold for channel 7 */ +# define AFEC_SHMR_DUAL8 (1 << 8) /* Bit 8: Dual Sample & Hold for channel 8 */ +# define AFEC_SHMR_DUAL9 (1 << 9) /* Bit 9: Dual Sample & Hold for channel 9 */ +# define AFEC_SHMR_DUAL10 (1 << 10) /* Bit 10: Dual Sample & Hold for channel 10 */ +# define AFEC_SHMR_DUAL11 (1 << 11) /* Bit 11: Dual Sample & Hold for channel 11 */ + +/* Correction Select Register */ + +#define AFEC_COSR_CSEL (1 << 0) /* Bit 0: Sample & Hold unit Correction Select */ + +/* Correction Values Register */ + +#define AFEC_CVR_OFFSETCORR_SHIFT (0) /* Bits 0-16: Offset Correction */ +#define AFEC_CVR_OFFSETCORR_MASK (0xffff << AFEC_CVR_OFFSETCORR_SHIFT) +# define AFEC_CVR_OFFSETCORR(n) ((uint32_t)(n) << AFEC_CVR_OFFSETCORR_SHIFT) +#define AFEC_CVR_GAINCORR_SHIFT (16) /* Bits 16-31: Gain Correction */ +#define AFEC_CVR_GAINCORR_MASK (0xffff << AFEC_CVR_GAINCORR_SHIFT) +# define AFEC_CVR_GAINCORR(n) ((uint32_t)(n) << AFEC_CVR_GAINCORR_SHIFT) + +/* Channel Error Correction Register */ + +#define AFEC_CECR_ECORR(n) (1 << (n)) +# define AFEC_CECR_ECORR0 (1 << 0) /* Bit 0: Error Correction Enable for channel 0 */ +# define AFEC_CECR_ECORR1 (1 << 1) /* Bit 1: Error Correction Enable for channel 1 */ +# define AFEC_CECR_ECORR2 (1 << 2) /* Bit 2: Error Correction Enable for channel 2 */ +# define AFEC_CECR_ECORR3 (1 << 3) /* Bit 3: Error Correction Enable for channel 3 */ +# define AFEC_CECR_ECORR4 (1 << 4) /* Bit 4: Error Correction Enable for channel 4 */ +# define AFEC_CECR_ECORR5 (1 << 5) /* Bit 5: Error Correction Enable for channel 5 */ +# define AFEC_CECR_ECORR6 (1 << 6) /* Bit 6: Error Correction Enable for channel 6 */ +# define AFEC_CECR_ECORR7 (1 << 7) /* Bit 7: Error Correction Enable for channel 7 */ +# define AFEC_CECR_ECORR8 (1 << 8) /* Bit 8: Error Correction Enable for channel 8 */ +# define AFEC_CECR_ECORR9 (1 << 9) /* Bit 9: Error Correction Enable for channel 9 */ +# define AFEC_CECR_ECORR10 (1 << 10) /* Bit 10: Error Correction Enable for channel 10 */ +# define AFEC_CECR_ECORR11 (1 << 11) /* Bit 11: Error Correction Enable for channel 11 */ + +/* Write Protect Mode Register */ + +#define AFEC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define AFEC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define AFEC_WPMR_WPKEY_MASK (0x00ffffff << AFEC_WPMR_WPKEY_SHIFT) +# define AFEC_WPMR_WPKEY (0x00414443 << AFEC_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define AFEC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define AFEC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define AFEC_WPSR_WPVSRC_MASK (0x0000ffff << AFEC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_AFEC_H */ diff --git a/arch/arm/src/samv7/chip/sam_chipid.h b/arch/arm/src/samv7/chip/sam_chipid.h new file mode 100644 index 0000000000000000000000000000000000000000..bc73e9bc7893ab221176aff4cc6c5af86962fc97 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_chipid.h @@ -0,0 +1,186 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_chipid.h + * CHIPID Register Definitions for the SAMV7 + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Michael Spahlinger + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_CHIPID_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_CHIPID_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* CHIPID register offsets **************************************************************/ + +#define SAM_CHIPID_CIDR_OFFSET 0x00 /* Chip ID Register */ +#define SAM_CHIPID_EXID_OFFSET 0x04 /* Chip ID Extension Register */ + +/* CHIPID register addresses ************************************************************/ + +#define SAM_CHIPID_CIDR (SAM_CHIPID_BASE+SAM_CHIPID_CIDR_OFFSET) +#define SAM_CHIPID_EXID (SAM_CHIPID_BASE+SAM_CHIPID_EXID_OFFSET) + +/* CHIPID register bit definitions ******************************************************/ + +#define CHIPID_CIDR_VERSION_SHIFT (0) /* Bits 0-4: Version of the Device */ +#define CHIPID_CIDR_VERSION_MASK (0x1f << CHIPID_CIDR_VERSION_SHIFT) +#define CHIPID_CIDR_EPROC_SHIFT (5) /* Bits 5-7: Embedded Processor */ +#define CHIPID_CIDR_EPROC_MASK (7 << CHIPID_CIDR_EPROC_SHIFT) +# define CHIPID_CIDR_EPROC_CORTEXM7 (0 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-M7*/ +# define CHIPID_CIDR_EPROC_ARM946ES (1 << CHIPID_CIDR_EPROC_SHIFT) /* ARM946E-S */ +# define CHIPID_CIDR_EPROC_ARM7TDMI (2 << CHIPID_CIDR_EPROC_SHIFT) /* ARM7TDMI */ +# define CHIPID_CIDR_EPROC_CORTEXM3 (3 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-M3 */ +# define CHIPID_CIDR_EPROC_ARM920T (4 << CHIPID_CIDR_EPROC_SHIFT) /* ARM920T */ +# define CHIPID_CIDR_EPROC_ARM926EJS (5 << CHIPID_CIDR_EPROC_SHIFT) /* ARM926EJ-S */ +# define CHIPID_CIDR_EPROC_CORTEXA5 (6 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-A5 */ +# define CHIPID_CIDR_EPROC_CORTEXM4 (7 << CHIPID_CIDR_EPROC_SHIFT) /* Cortex-M4 */ +#define CHIPID_CIDR_NVPSIZ_SHIFT (8) /* Bits 8-11: Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ_MASK (15 << CHIPID_CIDR_NVPSIZ_SHIFT) +# define CHIPID_CIDR_NVPSIZ_NONE (0 << CHIPID_CIDR_NVPSIZ_SHIFT) /* None */ +# define CHIPID_CIDR_NVPSIZ_8KB (1 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_NVPSIZ_16KB (2 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_NVPSIZ_32KB (3 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_NVPSIZ_64KB (5 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_NVPSIZ_128KB (7 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_NVPSIZ_256KB (9 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_NVPSIZ_512KB (10 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 512K bytes */ +# define CHIPID_CIDR_NVPSIZ_1MB (12 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 1024K bytes */ +# define CHIPID_CIDR_NVPSIZ_2MB (14 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 2048K bytes */ +#define CHIPID_CIDR_NVPSIZ2_SHIFT (12) /* Bits 12-15: Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ2_MASK (15 << CHIPID_CIDR_NVPSIZ_SHIFT) +# define CHIPID_CIDR_NVPSIZ2_NONE (0 << CHIPID_CIDR_NVPSIZ_SHIFT) /* None */ +# define CHIPID_CIDR_NVPSIZ2_8KB (1 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_NVPSIZ2_16KB (2 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_NVPSIZ2_32KB (3 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_NVPSIZ2_64KB (5 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_NVPSIZ2_128KB (7 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_NVPSIZ2_256KB (9 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_NVPSIZ2_512KB (10 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 512K bytes */ +# define CHIPID_CIDR_NVPSIZ2_1MB (12 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 1024K bytes */ +# define CHIPID_CIDR_NVPSIZ2_2MB (14 << CHIPID_CIDR_NVPSIZ_SHIFT) /* 2048K bytes */ +#define CHIPID_CIDR_SRAMSIZ_SHIFT (16) /* Bits 16-19: Internal SRAM Size */ +#define CHIPID_CIDR_SRAMSIZ_MASK (15 << CHIPID_CIDR_SRAMSIZ_SHIFT) +# define CHIPID_CIDR_SRAMSIZ_48KB (0 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 48K bytes */ +# define CHIPID_CIDR_SRAMSIZ_192KB (1 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 192K bytes */ +# define CHIPID_CIDR_SRAMSIZ_384KB (2 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 384K bytes */ +# define CHIPID_CIDR_SRAMSIZ_6KB (3 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 6K bytes */ +# define CHIPID_CIDR_SRAMSIZ_24KB (4 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 24K bytes */ +# define CHIPID_CIDR_SRAMSIZ_4KB (5 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 4K bytes */ +# define CHIPID_CIDR_SRAMSIZ_80KB (6 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 80K bytes */ +# define CHIPID_CIDR_SRAMSIZ_160KB (7 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 160K bytes */ +# define CHIPID_CIDR_SRAMSIZ_8KB (8 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 8K bytes */ +# define CHIPID_CIDR_SRAMSIZ_16KB (9 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 16K bytes */ +# define CHIPID_CIDR_SRAMSIZ_32KB (10 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 32K bytes */ +# define CHIPID_CIDR_SRAMSIZ_64KB (11 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 64K bytes */ +# define CHIPID_CIDR_SRAMSIZ_128KB (12 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 128K bytes */ +# define CHIPID_CIDR_SRAMSIZ_256KB (13 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 256K bytes */ +# define CHIPID_CIDR_SRAMSIZ_96KB (14 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 96K bytes */ +# define CHIPID_CIDR_SRAMSIZ_512KB (15 << CHIPID_CIDR_SRAMSIZ_SHIFT) /* 512K bytes */ +#define CHIPID_CIDR_ARCH_SHIFT (20) /* Bits 20-27: Architecture Identifier */ +#define CHIPID_CIDR_ARCH_MASK (0xff << CHIPID_CIDR_ARCH_SHIFT) +# define CHIPID_CIDR_ARCH_SAME70 (0x10 << CHIPID_CIDR_ARCH_SHIFT) /* SAM E70 Series */ +# define CHIPID_CIDR_ARCH_SAMS70 (0x11 << CHIPID_CIDR_ARCH_SHIFT) /* SAM S70 Series */ +# define CHIPID_CIDR_ARCH_SAMV71 (0x12 << CHIPID_CIDR_ARCH_SHIFT) /* SAM V71 Series */ +# define CHIPID_CIDR_ARCH_SAMV70 (0x13 << CHIPID_CIDR_ARCH_SHIFT) /* SAM V70 Series */ +# define CHIPID_CIDR_ARCH_AT91SAM9XX (0x19 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM9xx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM9XEXX (0x29 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM9XExx Series */ +# define CHIPID_CIDR_ARCH_AT91X34 (0x34 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x34 Series */ +# define CHIPID_CIDR_ARCH_CAP7 (0x37 << CHIPID_CIDR_ARCH_SHIFT) /* CAP7 Series */ +# define CHIPID_CIDR_ARCH_CAP9 (0x39 << CHIPID_CIDR_ARCH_SHIFT) /* CAP9 Series */ +# define CHIPID_CIDR_ARCH_CAP11 (0x3b << CHIPID_CIDR_ARCH_SHIFT) /* CAP11 Series */ +# define CHIPID_CIDR_ARCH_AT91X40 (0x40 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x40 Series */ +# define CHIPID_CIDR_ARCH_AT91X42 (0x42 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x42 Series */ +# define CHIPID_CIDR_ARCH_AT91X55 (0x55 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x55 Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7AXX (0x60 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Axx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7AQXX (0x61 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7AQxx Series */ +# define CHIPID_CIDR_ARCH_AT91X63 (0x63 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x63 Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SXX (0x70 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Sxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7XCXX (0x71 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7XCxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SEXX (0x72 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7SExx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7LXX (0x73 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Lxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7XXX (0x75 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7Xxx Series */ +# define CHIPID_CIDR_ARCH_AT91SAM7SLXX (0x76 << CHIPID_CIDR_ARCH_SHIFT) /* AT91SAM7SLxx Series */ +# define CHIPID_CIDR_ARCH_SAM3UXC (0x80 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3UxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3UXE (0x81 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3UxE Series (144-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3AXC (0x83 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3AxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXC (0x84 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXE (0x85 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxE Series (144-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3XXG (0x86 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3XxG Series (208/217-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXA (0x88 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXA (0x88 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4SxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXB (0x89 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXB (0x89 << CHIPID_CIDR_ARCH_SHIFT) /* SAM34xB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SXC (0x8a << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM4SXC (0x8a << CHIPID_CIDR_ARCH_SHIFT) /* SAM4SxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_AT91X92 (0x92 << CHIPID_CIDR_ARCH_SHIFT) /* AT91x92 Series */ +# define CHIPID_CIDR_ARCH_SAM3NXA (0x93 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxA Series (48-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3NXB (0x94 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3NXC (0x95 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3NxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3DXB (0x99 << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SDxB SAM3SDxB Series (64-pin version) */ +# define CHIPID_CIDR_ARCH_SAM3SDXC (0x9a << CHIPID_CIDR_ARCH_SHIFT) /* SAM3SDxC Series (100-pin version) */ +# define CHIPID_CIDR_ARCH_SAM5A (0xa5 << CHIPID_CIDR_ARCH_SHIFT) /* SAM5A */ +# define CHIPID_CIDR_ARCH_SAM4LA (0xb0 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxA Series */ +# define CHIPID_CIDR_ARCH_SAM4LB (0xb1 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxB Series */ +# define CHIPID_CIDR_ARCH_SAM4LC (0xb2 << CHIPID_CIDR_ARCH_SHIFT) /* SAM4LxC Series */ +# define CHIPID_CIDR_ARCH_AT75CXX (0xf0 << CHIPID_CIDR_ARCH_SHIFT) /* AT75Cxx Series */ +#define CHIPID_CIDR_NVPTYP_SHIFT (28) /* Bits 28-30: Nonvolatile Program Memory Type */ +#define CHIPID_CIDR_NVPTYP_MASK (7 << CHIPID_CIDR_NVPTYP_SHIFT) +# define CHIPID_CIDR_NVPTYP_ROM (0 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROM */ +# define CHIPID_CIDR_NVPTYP_FLASH (1 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROMless or on-chip Flash */ +# define CHIPID_CIDR_NVPTYP_SRAM (4 << CHIPID_CIDR_NVPTYP_SHIFT) /* SRAM emulating ROM */ +# define CHIPID_CIDR_NVPTYP_EFLASH (2 << CHIPID_CIDR_NVPTYP_SHIFT) /* Embedded Flash Memory */ +# define CHIPID_CIDR_NVPTYP_REFLASH (3 << CHIPID_CIDR_NVPTYP_SHIFT) /* ROM and Embedded Flash Memory */ +#define CHIPID_CIDR_EXT (1 << 31) /* Bit 31: Extension Flag */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_CHIPID_H */ diff --git a/arch/arm/src/samv7/chip/sam_eefc.h b/arch/arm/src/samv7/chip/sam_eefc.h new file mode 100644 index 0000000000000000000000000000000000000000..74d77f00b3ebad3277997ae5fe768661e1f6f1f9 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_eefc.h @@ -0,0 +1,166 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_eefc.h + * Enhanced Embedded Flash Controller (EEFC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EEFC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EEFC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* EEFC register offsets ****************************************************************/ + +#define SAM_EEFC_FMR_OFFSET 0x00 /* EEFC Flash Mode Register */ +#define SAM_EEFC_FCR_OFFSET 0x04 /* EEFC Flash Command Register */ +#define SAM_EEFC_FSR_OFFSET 0x08 /* EEFC Flash Status Register */ +#define SAM_EEFC_FRR_OFFSET 0x0c /* EEFC Flash Result Register */ +#define SAM_EEFC_WPMR_OFFSET 0xec /* EEFC Write Protection Mode Register */ + +/* EEFC register addresses **************************************************************/ + +#define SAM_EEFC_FMR (SAM_EEFC_BASE+SAM_EEFC_FMR_OFFSET) +#define SAM_EEFC_FCR (SAM_EEFC_BASE+SAM_EEFC_FCR_OFFSET) +#define SAM_EEFC_FSR (SAM_EEFC_BASE+SAM_EEFC_FSR_OFFSET) +#define SAM_EEFC_FRR (SAM_EEFC_BASE+SAM_EEFC_FRR_OFFSET) +#define SAM_EEFC_WPMR (SAM_EEFC_BASE+SAM_EEFC_WPMR_OFFSET) + +/* EEFC register bit definitions ********************************************************/ +/* EEFC Flash Mode Register */ + +#define EEFC_FMR_FRDY (1 << 0) /* Bit 0: Ready Interrupt Enable */ +#define EEFC_FMR_FWS_SHIFT (8) /* Bits 8-11: Flash Wait State */ +#define EEFC_FMR_FWS_MASK (15 << EEFC_FMR_FWS_SHIFT) +# define EEFC_FMR_FWS(n) ((n) << EEFC_FMR_FWS_SHIFT) +#define EEFC_FMR_SCOD (1 << 16) /* Bit 16: Sequential Code Optimization Disable */ +#define EEFC_FMR_CLOE (1 << 26) /* Bit 26: Code Loops Optimization Enable */ + +/* EEFC Flash Command Register */ + +#define FCMD_GETD (0) /* Get Flash Descriptor */ +#define FCMD_WP (1) /* Write page */ +#define FCMD_WPL (2) /* Write page and lock */ +#define FCMD_EWP (3) /* Erase page and write page */ +#define FCMD_EWPL (4) /* Erase page and write page then lock */ +#define FCMD_EA (5) /* Erase all */ +#define FCMD_EPA (7) /* Erase pages */ +#define FCMD_SLB (8) /* Set Lock Bit */ +#define FCMD_CLB (9) /* Clear Lock Bit */ +#define FCMD_GLB (10) /* Get Lock Bit */ +#define FCMD_SGPB (11) /* Set GPNVM Bit */ +#define FCMD_CGPB (12) /* Clear GPNVM Bit */ +#define FCMD_GGPB (13) /* Get GPNVM Bit */ +#define FCMD_STUI (14) /* Start Read Unique Identifier */ +#define FCMD_SPUI (15) /* Stop Read Unique Identifier */ +#define FCMD_GCALB (16) /* Get CALIB Bit */ +#define FCMD_ES (17) /* Erase Sector */ +#define FCMD_WUS (18) /* Write User Signature */ +#define FCMD_EUS (19) /* Erase User Signature */ +#define FCMD_STUS (20) /* Start Read User Signature */ +#define FCMD_SPUS (21) /* Stop Read User Signature */ + +#define EEFC_FCR_FCMD_SHIFT (0) /* Bits 0-7: Flash Command */ +#define EEFC_FCR_FCMD_MASK (0xff << EEFC_FCR_FCMD_SHIFT) +# define EEFC_FCR_FCMD(cmd) ((uint32_t)(cmd) << EEFC_FCR_FCMD_SHIFT) +# define EEFC_FCR_FCMD_GETD (0 << EEFC_FCR_FCMD_SHIFT) /* Get Flash Descriptor */ +# define EEFC_FCR_FCMD_WP (1 << EEFC_FCR_FCMD_SHIFT) /* Write page */ +# define EEFC_FCR_FCMD_WPL (2 << EEFC_FCR_FCMD_SHIFT) /* Write page and lock */ +# define EEFC_FCR_FCMD_EWP (3 << EEFC_FCR_FCMD_SHIFT) /* Erase page and write page */ +# define EEFC_FCR_FCMD_EWPL (4 << EEFC_FCR_FCMD_SHIFT) /* Erase page and write page then lock */ +# define EEFC_FCR_FCMD_EA (5 << EEFC_FCR_FCMD_SHIFT) /* Erase all */ +# define EEFC_FCR_FCMD_EPA (7 << EEFC_FCR_FCMD_SHIFT) /* Erase pages */ +# define EEFC_FCR_FCMD_SLB (8 << EEFC_FCR_FCMD_SHIFT) /* Set Lock Bit */ +# define EEFC_FCR_FCMD_CLB (9 << EEFC_FCR_FCMD_SHIFT) /* Clear Lock Bit */ +# define EEFC_FCR_FCMD_GLB (10 << EEFC_FCR_FCMD_SHIFT) /* Get Lock Bit */ +# define EEFC_FCR_FCMD_SGPB (11 << EEFC_FCR_FCMD_SHIFT) /* Set GPNVM Bit */ +# define EEFC_FCR_FCMD_CGPB (12 << EEFC_FCR_FCMD_SHIFT) /* Clear GPNVM Bit */ +# define EEFC_FCR_FCMD_GGPB (13 << EEFC_FCR_FCMD_SHIFT) /* Get GPNVM Bit */ +# define EEFC_FCR_FCMD_STUI (14 << EEFC_FCR_FCMD_SHIFT) /* Start Read Unique Identifier */ +# define EEFC_FCR_FCMD_SPUI (15 << EEFC_FCR_FCMD_SHIFT) /* Stop Read Unique Identifier */ +# define EEFC_FCR_FCMD_GCALB (16 << EEFC_FCR_FCMD_SHIFT) /* Get CALIB Bit */ +# define EEFC_FCR_FCMD_ES (17 << EEFC_FCR_FCMD_SHIFT) /* Erase Sector */ +# define EEFC_FCR_FCMD_WUS (18 << EEFC_FCR_FCMD_SHIFT) /* Write User Signature */ +# define EEFC_FCR_FCMD_EUS (19 << EEFC_FCR_FCMD_SHIFT) /* Erase User Signature */ +# define EEFC_FCR_FCMD_STUS (20 << EEFC_FCR_FCMD_SHIFT) /* Start Read User Signature */ +# define EEFC_FCR_FCMD_SPUS (21 << EEFC_FCR_FCMD_SHIFT) /* Stop Read User Signature */ +#define EEFC_FCR_FARG_SHIFT (8) /* Bits 8-23: Flash Command Argument */ +#define EEFC_FCR_FARG_MASK (0xffff << EEFC_FCR_FARG_SHIFT) +# define EEFC_FCR_FARG(arg) ((uint32_t)(arg) << EEFC_FCR_FARG_SHIFT) +#define EEFC_FCR_FKEY_SHIFT (24) /* Bits 24-31: Flash Writing Protection Key */ +#define EEFC_FCR_FKEY_MASK (0xff << EEFC_FCR_FKEY_SHIFT) +# define EEFC_FCR_FKEY_PASSWD (0x5a << EEFC_FCR_FKEY_SHIFT) + +/* EEFC Flash Status Register */ + +#define EEFC_FSR_FRDY (1 << 0) /* Bit 0: Flash Ready Status */ +#define EEFC_FSR_FCMDE (1 << 1) /* Bit 1: Flash Command Error Status */ +#define EEFC_FSR_FLOCKE (1 << 2) /* Bit 2: Flash Lock Error Status */ +#define EEFC_FSR_FLERR (1 << 3) /* Bit 3: Flash Error Status */ +#define EEFC_FSR_UECCELSB (1 << 16) /* Bit 16: Unique ECC Error on LSB Part */ +#define EEFC_FSR_MECCELSB (1 << 17) /* Bit 17: Multiple ECC Error on LSB Part */ +#define EEFC_FSR_UECCEMSB (1 << 18) /* Bit 18: Unique ECC Error on MSB Part */ +#define EEFC_FSR_MECCEMSB (1 << 19) /* Bit 19: Multiple ECC Error on MSB Part */ + +/* EEFC Flash Result Register -- 32-bit value */ + +/* EEFC Write Protect Mode Register */ + +#define EEFC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define EEFC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define EEFC_WPMR_WPKEY_MASK (0x00ffffff << EEFC_WPMR_WPKEY_SHIFT) +# define EEFC_WPMR_WPKEY (0x00454643 << EEFC_WPMR_WPKEY_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EEFC_H */ diff --git a/arch/arm/src/samv7/chip/sam_emac.h b/arch/arm/src/samv7/chip/sam_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..e0a0cbb9a724b21ba4df7ea2182997bc1c6502b4 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_emac.h @@ -0,0 +1,1046 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_emac.h + * This is the form of the EMAC interface used the the SAMV7. + * This is referred as GMAC in the documentation even though it does not support + * Gibabit Ethernet. + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EMAC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NEMAC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* EMAC Register Offsets ************************************************************/ + +#define SAM_EMAC_NCR_OFFSET 0x0000 /* Network Control Register */ +#define SAM_EMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */ +#define SAM_EMAC_NSR_OFFSET 0x0008 /* Network Status Register */ +#define SAM_EMAC_UR_OFFSET 0x000c /* User Register */ +#define SAM_EMAC_DCFGR_OFFSET 0x0010 /* DMA Configuration Register */ +#define SAM_EMAC_TSR_OFFSET 0x0014 /* Transmit Status Register */ +#define SAM_EMAC_RBQB_OFFSET 0x0018 /* Receive Buffer Queue Base Address */ +#define SAM_EMAC_TBQB_OFFSET 0x001c /* Transmit Buffer Queue Base Address */ +#define SAM_EMAC_RSR_OFFSET 0x0020 /* Receive Status Register */ +#define SAM_EMAC_ISR_OFFSET 0x0024 /* Interrupt Status Register */ +#define SAM_EMAC_IER_OFFSET 0x0028 /* Interrupt Enable Register */ +#define SAM_EMAC_IDR_OFFSET 0x002c /* Interrupt Disable Register */ +#define SAM_EMAC_IMR_OFFSET 0x0030 /* Interrupt Mask Register */ +#define SAM_EMAC_MAN_OFFSET 0x0034 /* PHY Maintenance Register */ +#define SAM_EMAC_RPQ_OFFSET 0x0038 /* Received Pause Quantum Register */ +#define SAM_EMAC_TPQ_OFFSET 0x003c /* Transmit Pause Quantum Register */ +#define SAM_EMAC_TPSF_OFFSET 0x0040 /* TX Partial Store and Forward Register */ +#define SAM_EMAC_RPSF_OFFSET 0x0044 /* RX Partial Store and Forward Register */ +#define SAM_EMAC_RJFML_OFFSET 0x0048 /* RX Jumbo Frame Max Length Register */ + /* 0x004c-0x007c: Reserved */ +#define SAM_EMAC_HRB_OFFSET 0x0080 /* Hash Register Bottom [31:0] Register */ +#define SAM_EMAC_HRT_OFFSET 0x0084 /* Hash Register Top [63:32] Register */ +#define SAM_EMAC_SAB1_OFFSET 0x0088 /* Specific Address 1 Bottom Register */ +#define SAM_EMAC_SAT1_OFFSET 0x008c /* Specific Address 1 Top Register */ +#define SAM_EMAC_SAB2_OFFSET 0x0090 /* Specific Address 2 Bottom Register */ +#define SAM_EMAC_SAT2_OFFSET 0x0094 /* Specific Address 2 Top Register */ +#define SAM_EMAC_SAB3_OFFSET 0x0098 /* Specific Address 3 Bottom Register */ +#define SAM_EMAC_SAT3_OFFSET 0x009c /* Specific Address 3 Top Register */ +#define SAM_EMAC_SAB4_OFFSET 0x00a0 /* Specific Address 4 Bottom Register */ +#define SAM_EMAC_SAT4_OFFSET 0x00a4 /* Specific Address 4 Top Register */ +#define SAM_EMAC_TIDM1_OFFSET 0x00a8 /* Type ID Match 1 Register */ +#define SAM_EMAC_TIDM2_OFFSET 0x00ac /* Type ID Match 2 Register */ +#define SAM_EMAC_TIDM3_OFFSET 0x00b0 /* Type ID Match 3 Register */ +#define SAM_EMAC_TIDM4_OFFSET 0x00b4 /* Type ID Match 4 Register */ +#define SAM_EMAC_WOL_OFFSET 0x00b8 /* Wake on LAN Register */ +#define SAM_EMAC_IPGS_OFFSET 0x00bc /* IPG Stretch Register */ +#define SAM_EMAC_SVLAN_OFFSET 0x00c0 /* Stacked VLAN Register */ +#define SAM_EMAC_TPFCP_OFFSET 0x00c4 /* Transmit PFC Pause Register */ +#define SAM_EMAC_SAMB1_OFFSET 0x00c8 /* Specific Address 1 Mask Bottom [31:0] Register */ +#define SAM_EMAC_SAMT1_OFFSET 0x00cc /* Specific Address 1 Mask Top [47:32] Register */ + /* 0x00d0-0xd8: Reserved */ +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC_NSC_OFFSET 0x00dc /* 1588 Timer Nanosecond Comparison Register */ +#define SAM_EMAC_SCL_OFFSET 0x00e0 /* 1588 Timer Second Comparison Low Register */ +#define SAM_EMAC_SCH_OFFSET 0x00e4 /* 1588 Timer Second Comparison High Register */ +#define SAM_EMAC_EFTSH_OFFSET 0x00e8 /* PTP Event Frame Transmitted Seconds High Register */ +#define SAM_EMAC_EFRSH_OFFSET 0x00ec /* PTP Event Frame Received Seconds High Register */ +#define SAM_EMAC_PEFTSH_OFFSET 0x00f0 /* PTP Peer Event Frame Transmitted Seconds High Register */ +#define SAM_EMAC_PEFRSH_OFFSET 0x00f4 /* PTP Peer Event Frame Received Seconds High Register */ + /*0x00f8-0x00fc: Reserved */ +/* Statistics registers */ + +#define SAM_EMAC_OTLO_OFFSET 0x0100 /* Octets Transmitted [31:0] Register */ +#define SAM_EMAC_OTHI_OFFSET 0x0104 /* Octets Transmitted [47:32] Register */ +#define SAM_EMAC_FT_OFFSET 0x0108 /* Frames Transmitted Register */ +#define SAM_EMAC_BCFT_OFFSET 0x010c /* Broadcast Frames Transmitted Register */ +#define SAM_EMAC_MFT_OFFSET 0x0110 /* Multicast Frames Transmitted Register */ +#define SAM_EMAC_PFT_OFFSET 0x0114 /* Pause Frames Transmitted Register */ +#define SAM_EMAC_BFT64_OFFSET 0x0118 /* 64 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT127_OFFSET 0x011c /* 65 to 127 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT255_OFFSET 0x0120 /* 128 to 255 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT511_OFFSET 0x0124 /* 256 to 511 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1023_OFFSET 0x0128 /* 512 to 1023 Byte Frames Transmitted Register */ +#define SAM_EMAC_TBFT1518_OFFSET 0x012c /* 1024 to 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_GTBFT1518_OFFSET 0x0130 /* Greater Than 1518 Byte Frames Transmitted Register */ +#define SAM_EMAC_TUR_OFFSET 0x0134 /* Transmit Under Runs Register */ +#define SAM_EMAC_SCF_OFFSET 0x0138 /* Single Collision Frames Register */ +#define SAM_EMAC_MCF_OFFSET 0x013c /* Multiple Collision Frames Register */ +#define SAM_EMAC_EC_OFFSET 0x0140 /* Excessive Collisions Register */ +#define SAM_EMAC_LC_OFFSET 0x0144 /* Late Collisions Register */ +#define SAM_EMAC_DTF_OFFSET 0x0148 /* Deferred Transmission Frames Register */ +#define SAM_EMAC_CSE_OFFSET 0x014c /* Carrier Sense Errors Register */ +#define SAM_EMAC_ORLO_OFFSET 0x0150 /* Octets Received [31:0] Received */ +#define SAM_EMAC_ORHI_OFFSET 0x0154 /* Octets Received [47:32] Received */ +#define SAM_EMAC_FR_OFFSET 0x0158 /* Frames Received Register */ +#define SAM_EMAC_BCFR_OFFSET 0x015C /* Broadcast Frames Received Register */ +#define SAM_EMAC_MFR_OFFSET 0x0160 /* Multicast Frames Received Register */ +#define SAM_EMAC_PFR_OFFSET 0x0164 /* Pause Frames Received Register */ +#define SAM_EMAC_BFR64_OFFSET 0x0168 /* 64 Byte Frames Received Register */ +#define SAM_EMAC_TBFR127_OFFSET 0x016c /* 65 to 127 Byte Frames Received Register */ +#define SAM_EMAC_TBFR255_OFFSET 0x0170 /* 128 to 255 Byte Frames Received Register */ +#define SAM_EMAC_TBFR511_OFFSET 0x0174 /* 256 to 511Byte Frames Received Register */ +#define SAM_EMAC_TBFR1023_OFFSET 0x0178 /* 512 to 1023 Byte Frames Received Register */ +#define SAM_EMAC_TBFR1518_OFFSET 0x017c /* 1024 to 1518 Byte Frames Received Register */ +#define SAM_EMAC_TMXBFR_OFFSET 0x0180 /* 1519 to Maximum Byte Frames Received Register */ +#define SAM_EMAC_UFR_OFFSET 0x0184 /* Undersize Frames Received Register */ +#define SAM_EMAC_OFR_OFFSET 0x0188 /* Oversize Frames Received Register */ +#define SAM_EMAC_JR_OFFSET 0x018c /* Jabbers Received Register */ +#define SAM_EMAC_FCSE_OFFSET 0x0190 /* Frame Check Sequence Errors Register */ +#define SAM_EMAC_LFFE_OFFSET 0x0194 /* Length Field Frame Errors Register */ +#define SAM_EMAC_RSE_OFFSET 0x0198 /* Receive Symbol Errors Register */ +#define SAM_EMAC_AE_OFFSET 0x019c /* Alignment Errors Register */ +#define SAM_EMAC_RRE_OFFSET 0x01a0 /* Receive Resource Errors Register */ +#define SAM_EMAC_ROE_OFFSET 0x01a4 /* Receive Overrun Register */ +#define SAM_EMAC_IHCE_OFFSET 0x01a8 /* IP Header Checksum Errors Register */ +#define SAM_EMAC_TCE_OFFSET 0x01ac /* TCP Checksum Errors Register */ +#define SAM_EMAC_UCE_OFFSET 0x01b0 /* UDP Checksum Errors Register */ + /* 0x01b4-0x01b8: Reserved */ +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC_TISUBN_OFFSET 0x01bc /* 1588 Timer Increment Sub-nanoseconds Register */ +#define SAM_EMAC_TSH_OFFSET 0x01c0 /* 1588 Timer Seconds High Register */ +#define SAM_EMAC_TSL_OFFSET 0x01d0 /* 1588 Timer Seconds Low Register */ +#define SAM_EMAC_TN_OFFSET 0x01d4 /* 1588 Timer Nanoseconds Register */ +#define SAM_EMAC_TA_OFFSET 0x01d8 /* 1588 Timer Adjust Register */ +#define SAM_EMAC_TI_OFFSET 0x01dc /* 1588 Timer Increment Register */ +#define SAM_EMAC_EFTSL_OFFSET 0x01e0 /* PTP Event Frame Transmitted Seconds Low */ +#define SAM_EMAC_EFTN_OFFSET 0x01e4 /* PTP Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_EFRSL_OFFSET 0x01e8 /* PTP Event Frame Received Seconds Low */ +#define SAM_EMAC_EFRN_OFFSET 0x01ec /* PTP Event Frame Received Nanoseconds */ +#define SAM_EMAC_PEFTSL_OFFSET 0x01f0 /* PTP Peer Event Frame Transmitted Seconds Low */ +#define SAM_EMAC_PEFTN_OFFSET 0x01f4 /* PTP Peer Event Frame Transmitted Nanoseconds */ +#define SAM_EMAC_PEFRSL_OFFSET 0x01f8 /* PTP Peer Event Frame Received Seconds Low */ +#define SAM_EMAC_PEFRN_OFFSET 0x01fc /* PTP Peer Event Frame Received Nanoseconds */ + /* 0x0200-0x03fc: Reserved */ +/* Priority Queue */ + +#define SAM_EMAC_ISRPQ_ISRPQ_OFFSET(n) (0x03fc+((n)<<2)) /* Interrupt Status Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_TBQBAPQ_OFFSET(n) (0x043c+((n)<<2)) /* Transmit Buffer Queue Base Address Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_RBQBAPQ_OFFSET(n) (0x047c+((n)<<2)) /* Receive Buffer Queue Base Address Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_RBSRPQ_OFFSET(n) (0x049c+((n)<<2)) /* Receive Buffer Size Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_CBSCR_OFFSET 0x04bc /* Credit-Based Shaping Control Register */ +#define SAM_EMAC_ISRPQ_CBSISQA_OFFSET 0x04c0 /* Credit-Based Shaping IdleSlope Register for Queue A */ +#define SAM_EMAC_ISRPQ_CBSISQB_OFFSET 0x04c4 /* Credit-Based Shaping IdleSlope Register for Queue B */ +#define SAM_EMAC_ISRPQ_ST1RPQ_OFFSET(n) (0x0500+((n)<<2)) /* Screening Type 1 Register Priority Queue, 0=1-3 */ +#define SAM_EMAC_ISRPQ_ST2RPQ_OFFSET(n) (0x0540+((n)<<2)) /* Screening Type 2 Register Priority Queue, 0=1-7 */ +#define SAM_EMAC_ISRPQ_IERPQ_OFFSET(n) (0x05fc+((n)<<2)) /* Interrupt Enable Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_IDRPQ_OFFSET(n) (0x061c+((n)<<2)) /* Interrupt Disable Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_IMRPQ_OFFSET(n) (0x063c+((n)<<2)) /* Interrupt Mask Register Priority Queue, n=1-3 */ +#define SAM_EMAC_ISRPQ_ST2ER_OFFSET(n) (0x06e0+((n)<<2)) /* Screening Type 2 Ethertype Register, n=0-3 */ +#define SAM_EMAC_ISRPQ_ST2CW0_OFFSET(n) (0x0700+((n)<<3)) /* Screening Type 2 Compare Word 0 Registerm, n=0-23 */ +#define SAM_EMAC_ISRPQ_ST2CW1_OFFSET(n) (0x0704+((n)<<3)) /* Screening Type 2 Compare Word 1 Register, n=0-23 */ + +/* EMAC Register Addresses **********************************************************/ + +/* EMAC0 base addresses */ + +#define SAM_EMAC0_NCR (SAM_EMAC0_BASE+SAM_EMAC_NCR_OFFSET) +#define SAM_EMAC0_NCFGR (SAM_EMAC0_BASE+SAM_EMAC_NCFGR_OFFSET) +#define SAM_EMAC0_NSR (SAM_EMAC0_BASE+SAM_EMAC_NSR_OFFSET) +#define SAM_EMAC0_TSR (SAM_EMAC0_BASE+SAM_EMAC_TSR_OFFSET) +#define SAM_EMAC0_UR (SAM_EMAC0_BASE+SAM_EMAC_UR_OFFSET) +#define SAM_EMAC0_DCFGR (SAM_EMAC0_BASE+SAM_EMAC_DCFGR_OFFSET) +#define SAM_EMAC0_RBQB (SAM_EMAC0_BASE+SAM_EMAC_RBQB_OFFSET) +#define SAM_EMAC0_TBQB (SAM_EMAC0_BASE+SAM_EMAC_TBQB_OFFSET) +#define SAM_EMAC0_RSR (SAM_EMAC0_BASE+SAM_EMAC_RSR_OFFSET) +#define SAM_EMAC0_ISR (SAM_EMAC0_BASE+SAM_EMAC_ISR_OFFSET) +#define SAM_EMAC0_IER (SAM_EMAC0_BASE+SAM_EMAC_IER_OFFSET) +#define SAM_EMAC0_IDR (SAM_EMAC0_BASE+SAM_EMAC_IDR_OFFSET) +#define SAM_EMAC0_IMR (SAM_EMAC0_BASE+SAM_EMAC_IMR_OFFSET) +#define SAM_EMAC0_MAN (SAM_EMAC0_BASE+SAM_EMAC_MAN_OFFSET) +#define SAM_EMAC0_RPQ (SAM_EMAC0_BASE+SAM_EMAC_RPQ_OFFSET) +#define SAM_EMAC0_TPQ (SAM_EMAC0_BASE+SAM_EMAC_TPQ_OFFSET) +#define SAM_EMAC0_TPSF (SAM_EMAC0_BASE+SAM_EMAC_TPSF_OFFSET) +#define SAM_EMAC0_RPSF (SAM_EMAC0_BASE+SAM_EMAC_RPSF_OFFSET) +#define SAM_EMAC0_RJFML (SAM_EMAC0_BASE+SAM_EMAC_RJFML_OFFSET) +#define SAM_EMAC0_HRB (SAM_EMAC0_BASE+SAM_EMAC_HRB_OFFSET) +#define SAM_EMAC0_HRT (SAM_EMAC0_BASE+SAM_EMAC_HRT_OFFSET) +#define SAM_EMAC0_SAB1 (SAM_EMAC0_BASE+SAM_EMAC_SAB1_OFFSET) +#define SAM_EMAC0_SAT1 (SAM_EMAC0_BASE+SAM_EMAC_SAT1_OFFSET) +#define SAM_EMAC0_SAB2 (SAM_EMAC0_BASE+SAM_EMAC_SAB2_OFFSET) +#define SAM_EMAC0_SAT2 (SAM_EMAC0_BASE+SAM_EMAC_SAT2_OFFSET) +#define SAM_EMAC0_SAB3 (SAM_EMAC0_BASE+SAM_EMAC_SAB3_OFFSET) +#define SAM_EMAC0_SAT3 (SAM_EMAC0_BASE+SAM_EMAC_SAT3_OFFSET) +#define SAM_EMAC0_SAB4 (SAM_EMAC0_BASE+SAM_EMAC_SAB4_OFFSET) +#define SAM_EMAC0_SAT4 (SAM_EMAC0_BASE+SAM_EMAC_SAT4_OFFSET) +#define SAM_EMAC0_TIDM1 (SAM_EMAC0_BASE+SAM_EMAC_TIDM1_OFFSET) +#define SAM_EMAC0_TIDM2 (SAM_EMAC0_BASE+SAM_EMAC_TIDM2_OFFSET) +#define SAM_EMAC0_TIDM3 (SAM_EMAC0_BASE+SAM_EMAC_TIDM3_OFFSET) +#define SAM_EMAC0_TIDM4 (SAM_EMAC0_BASE+SAM_EMAC_TIDM4_OFFSET) +#define SAM_EMAC0_IPGS (SAM_EMAC0_BASE+SAM_EMAC_IPGS_OFFSET) +#define SAM_EMAC0_SVLAN (SAM_EMAC0_BASE+SAM_EMAC_SVLAN_OFFSET) +#define SAM_EMAC0_TPFCP (SAM_EMAC0_BASE+SAM_EMAC_TPFCP_OFFSET) +#define SAM_EMAC0_SAMB1 (SAM_EMAC0_BASE+SAM_EMAC_SAMB1_OFFSET) +#define SAM_EMAC0_SAMT1 (SAM_EMAC0_BASE+SAM_EMAC_SAMT1_OFFSET) + +/* PTP/1588 Timer Registers */ + +#define SAM_EMAC0_NSC (SAM_EMAC0_BASE+SAM_EMAC_NSC_OFFSET) +#define SAM_EMAC0_SCL (SAM_EMAC0_BASE+SAM_EMAC_SCL_OFFSET) +#define SAM_EMAC0_SCH (SAM_EMAC0_BASE+SAM_EMAC_SCH_OFFSET) +#define SAM_EMAC0_EFTSH (SAM_EMAC0_BASE+SAM_EMAC_EFTSH_OFFSET) +#define SAM_EMAC0_EFRSH (SAM_EMAC0_BASE+SAM_EMAC_EFRSH_OFFSET) +#define SAM_EMAC0_PEFTSH (SAM_EMAC0_BASE+SAM_EMAC_PEFTSH_OFFSET) +#define SAM_EMAC0_PEFRSH (SAM_EMAC0_BASE+SAM_EMAC_PEFRSH_OFFSET) + +/* Statistics registers */ + +#define SAM_EMAC0_OTLO (SAM_EMAC0_BASE+SAM_EMAC_OTLO_OFFSET) +#define SAM_EMAC0_OTHI (SAM_EMAC0_BASE+SAM_EMAC_OTHI_OFFSET) +#define SAM_EMAC0_FT (SAM_EMAC0_BASE+SAM_EMAC_FT_OFFSET) +#define SAM_EMAC0_BCFT (SAM_EMAC0_BASE+SAM_EMAC_BCFT_OFFSET) +#define SAM_EMAC0_MFT (SAM_EMAC0_BASE+SAM_EMAC_MFT_OFFSET) +#define SAM_EMAC0_PFT (SAM_EMAC0_BASE+SAM_EMAC_PFT_OFFSET) +#define SAM_EMAC0_BFT64 (SAM_EMAC0_BASE+SAM_EMAC_BFT64_OFFSET) +#define SAM_EMAC0_TBFT127 (SAM_EMAC0_BASE+SAM_EMAC_TBFT127_OFFSET) +#define SAM_EMAC0_TBFT255 (SAM_EMAC0_BASE+SAM_EMAC_TBFT255_OFFSET) +#define SAM_EMAC0_TBFT511 (SAM_EMAC0_BASE+SAM_EMAC_TBFT511_OFFSET) +#define SAM_EMAC0_TBFT1023 (SAM_EMAC0_BASE+SAM_EMAC_TBFT1023_OFFSET) +#define SAM_EMAC0_TBFT1518 (SAM_EMAC0_BASE+SAM_EMAC_TBFT1518_OFFSET) +#define SAM_EMAC0_GTBFT1518 (SAM_EMAC0_BASE+SAM_EMAC_GTBFT1518_OFFSET) +#define SAM_EMAC0_TUR (SAM_EMAC0_BASE+SAM_EMAC_TUR_OFFSET) +#define SAM_EMAC0_SCF (SAM_EMAC0_BASE+SAM_EMAC_SCF_OFFSET) +#define SAM_EMAC0_MCF (SAM_EMAC0_BASE+SAM_EMAC_MCF_OFFSET) +#define SAM_EMAC0_EC (SAM_EMAC0_BASE+SAM_EMAC_EC_OFFSET) +#define SAM_EMAC0_LC (SAM_EMAC0_BASE+SAM_EMAC_LC_OFFSET) +#define SAM_EMAC0_DTF (SAM_EMAC0_BASE+SAM_EMAC_DTF_OFFSET) +#define SAM_EMAC0_CSE (SAM_EMAC0_BASE+SAM_EMAC_CSE_OFFSET) +#define SAM_EMAC0_ORLO (SAM_EMAC0_BASE+SAM_EMAC_ORLO_OFFSET) +#define SAM_EMAC0_ORHI (SAM_EMAC0_BASE+SAM_EMAC_ORHI_OFFSET) +#define SAM_EMAC0_FR (SAM_EMAC0_BASE+SAM_EMAC_FR_OFFSET) +#define SAM_EMAC0_BCFR (SAM_EMAC0_BASE+SAM_EMAC_BCFR_OFFSET) +#define SAM_EMAC0_MFR (SAM_EMAC0_BASE+SAM_EMAC_MFR_OFFSET) +#define SAM_EMAC0_PFR (SAM_EMAC0_BASE+SAM_EMAC_PFR_OFFSET) +#define SAM_EMAC0_BFR64 (SAM_EMAC0_BASE+SAM_EMAC_BFR64_OFFSET) +#define SAM_EMAC0_TBFR127 (SAM_EMAC0_BASE+SAM_EMAC_TBFR127_OFFSET) +#define SAM_EMAC0_TBFR255 (SAM_EMAC0_BASE+SAM_EMAC_TBFR255_OFFSET) +#define SAM_EMAC0_TBFR511 (SAM_EMAC0_BASE+SAM_EMAC_TBFR511_OFFSET) +#define SAM_EMAC0_TBFR1023 (SAM_EMAC0_BASE+SAM_EMAC_TBFR1023_OFFSET) +#define SAM_EMAC0_TBFR1518 (SAM_EMAC0_BASE+SAM_EMAC_TBFR1518_OFFSET) +#define SAM_EMAC0_TMXBFR (SAM_EMAC0_BASE+SAM_EMAC_TMXBFR_OFFSET) +#define SAM_EMAC0_UFR (SAM_EMAC0_BASE+SAM_EMAC_UFR_OFFSET) +#define SAM_EMAC0_OFR (SAM_EMAC0_BASE+SAM_EMAC_OFR_OFFSET) +#define SAM_EMAC0_JR (SAM_EMAC0_BASE+SAM_EMAC_JR_OFFSET) +#define SAM_EMAC0_FCSE (SAM_EMAC0_BASE+SAM_EMAC_FCSE_OFFSET) +#define SAM_EMAC0_LFFE (SAM_EMAC0_BASE+SAM_EMAC_LFFE_OFFSET) +#define SAM_EMAC0_RSE (SAM_EMAC0_BASE+SAM_EMAC_RSE_OFFSET) +#define SAM_EMAC0_AE (SAM_EMAC0_BASE+SAM_EMAC_AE_OFFSET) +#define SAM_EMAC0_RRE (SAM_EMAC0_BASE+SAM_EMAC_RRE_OFFSET) +#define SAM_EMAC0_ROE (SAM_EMAC0_BASE+SAM_EMAC_ROE_OFFSET) +#define SAM_EMAC0_IHCE (SAM_EMAC0_BASE+SAM_EMAC_IHCE_OFFSET) +#define SAM_EMAC0_TCE (SAM_EMAC0_BASE+SAM_EMAC_TCE_OFFSET) +#define SAM_EMAC0_UCE (SAM_EMAC0_BASE+SAM_EMAC_UCE_OFFSET) + +/* More PTP/1588 Timer Registers */ + +#define SAM_EMAC0_TISUBN (SAM_EMAC0_BASE+SAM_EMAC_TISUBN_OFFSET) +#define SAM_EMAC0_TSH (SAM_EMAC0_BASE+SAM_EMAC_TSH_OFFSET) +#define SAM_EMAC0_TSL (SAM_EMAC0_BASE+SAM_EMAC_TSL_OFFSET) +#define SAM_EMAC0_TN (SAM_EMAC0_BASE+SAM_EMAC_TN_OFFSET) +#define SAM_EMAC0_TA (SAM_EMAC0_BASE+SAM_EMAC_TA_OFFSET) +#define SAM_EMAC0_TI (SAM_EMAC0_BASE+SAM_EMAC_TI_OFFSET) +#define SAM_EMAC0_EFTSL (SAM_EMAC0_BASE+SAM_EMAC_EFTSL_OFFSET) +#define SAM_EMAC0_EFTN (SAM_EMAC0_BASE+SAM_EMAC_EFTN_OFFSET) +#define SAM_EMAC0_EFRSL (SAM_EMAC0_BASE+SAM_EMAC_EFRS_OFFSET) +#define SAM_EMAC0_EFRN (SAM_EMAC0_BASE+SAM_EMAC_EFRN_OFFSET) +#define SAM_EMAC0_PEFTSL (SAM_EMAC0_BASE+SAM_EMAC_PEFTSL_OFFSET) +#define SAM_EMAC0_PEFTN (SAM_EMAC0_BASE+SAM_EMAC_PEFTN_OFFSET) +#define SAM_EMAC0_PEFRSL (SAM_EMAC0_BASE+SAM_EMAC_PEFRSL_OFFSET) +#define SAM_EMAC0_PEFRN (SAM_EMAC0_BASE+SAM_EMAC_PEFRN_OFFSET) + +/* Priority Queue */ + +#define SAM_EMAC0_ISRPQ_ISRPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ISRPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_TBQBAPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_TBQBAPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_RBQBAPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_RBQBAPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_RBSRPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_RBSRPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_CBSCR (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_CBSCR_OFFSET) +#define SAM_EMAC0_ISRPQ_CBSISQA (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_CBSISQA_OFFSET) +#define SAM_EMAC0_ISRPQ_CBSISQB (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_CBSISQB_OFFSET) +#define SAM_EMAC0_ISRPQ_ST1RPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ST1RPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_ST2RPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ST2RPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_IERPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_IERPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_IDRPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_IDRPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_IMRPQ(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_IMRPQ_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_ST2ER(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ST2ER_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_ST2CW0(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ST2CW0_OFFSET(n)) +#define SAM_EMAC0_ISRPQ_ST2CW1(n) (SAM_EMAC0_BASE+SAM_EMAC_ISRPQ_ST2CW1_OFFSET(n)) + +#if SAMV7_NEMAC > 1 +/* EMAC1 base addresses */ + +# define SAM_EMAC1_NCR (SAM_EMAC1_BASE+SAM_EMAC_NCR_OFFSET) +# define SAM_EMAC1_NCFGR (SAM_EMAC1_BASE+SAM_EMAC_NCFGR_OFFSET) +# define SAM_EMAC1_NSR (SAM_EMAC1_BASE+SAM_EMAC_NSR_OFFSET) +# define SAM_EMAC1_TSR (SAM_EMAC1_BASE+SAM_EMAC_TSR_OFFSET) +# define SAM_EMAC1_UR (SAM_EMAC1_BASE+SAM_EMAC_UR_OFFSET) +# define SAM_EMAC1_DCFGR (SAM_EMAC1_BASE+SAM_EMAC_DCFGR_OFFSET) +# define SAM_EMAC1_RBQB (SAM_EMAC1_BASE+SAM_EMAC_RBQB_OFFSET) +# define SAM_EMAC1_TBQB (SAM_EMAC1_BASE+SAM_EMAC_TBQB_OFFSET) +# define SAM_EMAC1_RSR (SAM_EMAC1_BASE+SAM_EMAC_RSR_OFFSET) +# define SAM_EMAC1_ISR (SAM_EMAC1_BASE+SAM_EMAC_ISR_OFFSET) +# define SAM_EMAC1_IER (SAM_EMAC1_BASE+SAM_EMAC_IER_OFFSET) +# define SAM_EMAC1_IDR (SAM_EMAC1_BASE+SAM_EMAC_IDR_OFFSET) +# define SAM_EMAC1_IMR (SAM_EMAC1_BASE+SAM_EMAC_IMR_OFFSET) +# define SAM_EMAC1_MAN (SAM_EMAC1_BASE+SAM_EMAC_MAN_OFFSET) +# define SAM_EMAC1_RPQ (SAM_EMAC1_BASE+SAM_EMAC_RPQ_OFFSET) +# define SAM_EMAC1_TPQ (SAM_EMAC1_BASE+SAM_EMAC_TPQ_OFFSET) +# define SAM_EMAC1_TPSF (SAM_EMAC1_BASE+SAM_EMAC_TPSF_OFFSET) +# define SAM_EMAC1_RPSF (SAM_EMAC1_BASE+SAM_EMAC_RPSF_OFFSET) +# define SAM_EMAC1_RJFML (SAM_EMAC1_BASE+SAM_EMAC_RJFML_OFFSET) +# define SAM_EMAC1_HRB (SAM_EMAC1_BASE+SAM_EMAC_HRB_OFFSET) +# define SAM_EMAC1_HRT (SAM_EMAC1_BASE+SAM_EMAC_HRT_OFFSET) +# define SAM_EMAC1_SAB1 (SAM_EMAC1_BASE+SAM_EMAC_SAB1_OFFSET) +# define SAM_EMAC1_SAT1 (SAM_EMAC1_BASE+SAM_EMAC_SAT1_OFFSET) +# define SAM_EMAC1_SAB2 (SAM_EMAC1_BASE+SAM_EMAC_SAB2_OFFSET) +# define SAM_EMAC1_SAT2 (SAM_EMAC1_BASE+SAM_EMAC_SAT2_OFFSET) +# define SAM_EMAC1_SAB3 (SAM_EMAC1_BASE+SAM_EMAC_SAB3_OFFSET) +# define SAM_EMAC1_SAT3 (SAM_EMAC1_BASE+SAM_EMAC_SAT3_OFFSET) +# define SAM_EMAC1_SAB4 (SAM_EMAC1_BASE+SAM_EMAC_SAB4_OFFSET) +# define SAM_EMAC1_SAT4 (SAM_EMAC1_BASE+SAM_EMAC_SAT4_OFFSET) +# define SAM_EMAC1_TIDM1 (SAM_EMAC1_BASE+SAM_EMAC_TIDM1_OFFSET) +# define SAM_EMAC1_TIDM2 (SAM_EMAC1_BASE+SAM_EMAC_TIDM2_OFFSET) +# define SAM_EMAC1_TIDM3 (SAM_EMAC1_BASE+SAM_EMAC_TIDM3_OFFSET) +# define SAM_EMAC1_TIDM4 (SAM_EMAC1_BASE+SAM_EMAC_TIDM4_OFFSET) +# define SAM_EMAC1_IPGS (SAM_EMAC1_BASE+SAM_EMAC_IPGS_OFFSET) +# define SAM_EMAC1_SVLAN (SAM_EMAC1_BASE+SAM_EMAC_SVLAN_OFFSET) +# define SAM_EMAC1_TPFCP (SAM_EMAC1_BASE+SAM_EMAC_TPFCP_OFFSET) +# define SAM_EMAC1_SAMB1 (SAM_EMAC1_BASE+SAM_EMAC_SAMB1_OFFSET) +# define SAM_EMAC1_SAMT1 (SAM_EMAC1_BASE+SAM_EMAC_SAMT1_OFFSET) + +/* PTP/1588 Timer Registers */ + +# define SAM_EMAC1_NSC (SAM_EMAC1_BASE+SAM_EMAC_NSC_OFFSET) +# define SAM_EMAC1_SCL (SAM_EMAC1_BASE+SAM_EMAC_SCL_OFFSET) +# define SAM_EMAC1_SCH (SAM_EMAC1_BASE+SAM_EMAC_SCH_OFFSET) +# define SAM_EMAC1_EFTSH (SAM_EMAC1_BASE+SAM_EMAC_EFTSH_OFFSET) +# define SAM_EMAC1_EFRSH (SAM_EMAC1_BASE+SAM_EMAC_EFRSH_OFFSET) +# define SAM_EMAC1_PEFTSH (SAM_EMAC1_BASE+SAM_EMAC_PEFTSH_OFFSET) +# define SAM_EMAC1_PEFRSH (SAM_EMAC1_BASE+SAM_EMAC_PEFRSH_OFFSET) + +/* Statistics registers */ + +# define SAM_EMAC1_OTLO (SAM_EMAC1_BASE+SAM_EMAC_OTLO_OFFSET) +# define SAM_EMAC1_OTHI (SAM_EMAC1_BASE+SAM_EMAC_OTHI_OFFSET) +# define SAM_EMAC1_FT (SAM_EMAC1_BASE+SAM_EMAC_FT_OFFSET) +# define SAM_EMAC1_BCFT (SAM_EMAC1_BASE+SAM_EMAC_BCFT_OFFSET) +# define SAM_EMAC1_MFT (SAM_EMAC1_BASE+SAM_EMAC_MFT_OFFSET) +# define SAM_EMAC1_PFT (SAM_EMAC1_BASE+SAM_EMAC_PFT_OFFSET) +# define SAM_EMAC1_BFT64 (SAM_EMAC1_BASE+SAM_EMAC_BFT64_OFFSET) +# define SAM_EMAC1_TBFT127 (SAM_EMAC1_BASE+SAM_EMAC_TBFT127_OFFSET) +# define SAM_EMAC1_TBFT255 (SAM_EMAC1_BASE+SAM_EMAC_TBFT255_OFFSET) +# define SAM_EMAC1_TBFT511 (SAM_EMAC1_BASE+SAM_EMAC_TBFT511_OFFSET) +# define SAM_EMAC1_TBFT1023 (SAM_EMAC1_BASE+SAM_EMAC_TBFT1023_OFFSET) +# define SAM_EMAC1_TBFT1518 (SAM_EMAC1_BASE+SAM_EMAC_TBFT1518_OFFSET) +# define SAM_EMAC1_GTBFT1518 (SAM_EMAC1_BASE+SAM_EMAC_GTBFT1518_OFFSET) +# define SAM_EMAC1_TUR (SAM_EMAC1_BASE+SAM_EMAC_TUR_OFFSET) +# define SAM_EMAC1_SCF (SAM_EMAC1_BASE+SAM_EMAC_SCF_OFFSET) +# define SAM_EMAC1_MCF (SAM_EMAC1_BASE+SAM_EMAC_MCF_OFFSET) +# define SAM_EMAC1_EC (SAM_EMAC1_BASE+SAM_EMAC_EC_OFFSET) +# define SAM_EMAC1_LC (SAM_EMAC1_BASE+SAM_EMAC_LC_OFFSET) +# define SAM_EMAC1_DTF (SAM_EMAC1_BASE+SAM_EMAC_DTF_OFFSET) +# define SAM_EMAC1_CSE (SAM_EMAC1_BASE+SAM_EMAC_CSE_OFFSET) +# define SAM_EMAC1_ORLO (SAM_EMAC1_BASE+SAM_EMAC_ORLO_OFFSET) +# define SAM_EMAC1_ORHI (SAM_EMAC1_BASE+SAM_EMAC_ORHI_OFFSET) +# define SAM_EMAC1_FR (SAM_EMAC1_BASE+SAM_EMAC_FR_OFFSET) +# define SAM_EMAC1_BCFR (SAM_EMAC1_BASE+SAM_EMAC_BCFR_OFFSET) +# define SAM_EMAC1_MFR (SAM_EMAC1_BASE+SAM_EMAC_MFR_OFFSET) +# define SAM_EMAC1_PFR (SAM_EMAC1_BASE+SAM_EMAC_PFR_OFFSET) +# define SAM_EMAC1_BFR64 (SAM_EMAC1_BASE+SAM_EMAC_BFR64_OFFSET) +# define SAM_EMAC1_TBFR127 (SAM_EMAC1_BASE+SAM_EMAC_TBFR127_OFFSET) +# define SAM_EMAC1_TBFR255 (SAM_EMAC1_BASE+SAM_EMAC_TBFR255_OFFSET) +# define SAM_EMAC1_TBFR511 (SAM_EMAC1_BASE+SAM_EMAC_TBFR511_OFFSET) +# define SAM_EMAC1_TBFR1023 (SAM_EMAC1_BASE+SAM_EMAC_TBFR1023_OFFSET) +# define SAM_EMAC1_TBFR1518 (SAM_EMAC1_BASE+SAM_EMAC_TBFR1518_OFFSET) +# define SAM_EMAC1_TMXBFR (SAM_EMAC1_BASE+SAM_EMAC_TMXBFR_OFFSET) +# define SAM_EMAC1_UFR (SAM_EMAC1_BASE+SAM_EMAC_UFR_OFFSET) +# define SAM_EMAC1_OFR (SAM_EMAC1_BASE+SAM_EMAC_OFR_OFFSET) +# define SAM_EMAC1_JR (SAM_EMAC1_BASE+SAM_EMAC_JR_OFFSET) +# define SAM_EMAC1_FCSE (SAM_EMAC1_BASE+SAM_EMAC_FCSE_OFFSET) +# define SAM_EMAC1_LFFE (SAM_EMAC1_BASE+SAM_EMAC_LFFE_OFFSET) +# define SAM_EMAC1_RSE (SAM_EMAC1_BASE+SAM_EMAC_RSE_OFFSET) +# define SAM_EMAC1_AE (SAM_EMAC1_BASE+SAM_EMAC_AE_OFFSET) +# define SAM_EMAC1_RRE (SAM_EMAC1_BASE+SAM_EMAC_RRE_OFFSET) +# define SAM_EMAC1_ROE (SAM_EMAC1_BASE+SAM_EMAC_ROE_OFFSET) +# define SAM_EMAC1_IHCE (SAM_EMAC1_BASE+SAM_EMAC_IHCE_OFFSET) +# define SAM_EMAC1_TCE (SAM_EMAC1_BASE+SAM_EMAC_TCE_OFFSET) +# define SAM_EMAC1_UCE (SAM_EMAC1_BASE+SAM_EMAC_UCE_OFFSET) + +/* More PTP/1588 Timer Registers */ + +# define SAM_EMAC1_TISUBN (SAM_EMAC1_BASE+SAM_EMAC_TISUBN_OFFSET) +# define SAM_EMAC1_TSH (SAM_EMAC1_BASE+SAM_EMAC_TSH_OFFSET) +# define SAM_EMAC1_TSL (SAM_EMAC1_BASE+SAM_EMAC_TSL_OFFSET) +# define SAM_EMAC1_TN (SAM_EMAC1_BASE+SAM_EMAC_TN_OFFSET) +# define SAM_EMAC1_TA (SAM_EMAC1_BASE+SAM_EMAC_TA_OFFSET) +# define SAM_EMAC1_TI (SAM_EMAC1_BASE+SAM_EMAC_TI_OFFSET) +# define SAM_EMAC1_EFTSL (SAM_EMAC1_BASE+SAM_EMAC_EFTSL_OFFSET) +# define SAM_EMAC1_EFTN (SAM_EMAC1_BASE+SAM_EMAC_EFTN_OFFSET) +# define SAM_EMAC1_EFRSL (SAM_EMAC1_BASE+SAM_EMAC_EFRSL_OFFSET) +# define SAM_EMAC1_EFRN (SAM_EMAC1_BASE+SAM_EMAC_EFRN_OFFSET) +# define SAM_EMAC1_PEFTSL (SAM_EMAC1_BASE+SAM_EMAC_PEFTSL_OFFSET) +# define SAM_EMAC1_PEFTN (SAM_EMAC1_BASE+SAM_EMAC_PEFTN_OFFSET) +# define SAM_EMAC1_PEFRSL (SAM_EMAC1_BASE+SAM_EMAC_PEFRSL_OFFSET) +# define SAM_EMAC1_PEFRN (SAM_EMAC1_BASE+SAM_EMAC_PEFRN_OFFSET) + +/* Priority Queue */ + +# define SAM_EMAC1_ISRPQ_ISRPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ISRPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_TBQBAPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_TBQBAPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_RBQBAPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_RBQBAPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_RBSRPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_RBSRPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_CBSCR (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_CBSCR_OFFSET) +# define SAM_EMAC1_ISRPQ_CBSISQA (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_CBSISQA_OFFSET) +# define SAM_EMAC1_ISRPQ_CBSISQB (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_CBSISQB_OFFSET) +# define SAM_EMAC1_ISRPQ_ST1RPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ST1RPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_ST2RPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ST2RPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_IERPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_IERPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_IDRPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_IDRPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_IMRPQ(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_IMRPQ_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_ST2ER(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ST2ER_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_ST2CW0(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ST2CW0_OFFSET(n)) +# define SAM_EMAC1_ISRPQ_ST2CW1(n) (SAM_EMAC1_BASE+SAM_EMAC_ISRPQ_ST2CW1_OFFSET(n)) +#endif + +/* EMAC Register Bit Definitions ****************************************************/ + +/* Network Control Register */ + +#define EMAC_NCR_LBL (1 << 1) /* Bit 1: Loopback local */ +#define EMAC_NCR_RXEN (1 << 2) /* Bit 2: Receive enable */ +#define EMAC_NCR_TXEN (1 << 3) /* Bit 3: Transmit enable */ +#define EMAC_NCR_MPE (1 << 4) /* Bit 4: Management port enable */ +#define EMAC_NCR_CLRSTAT (1 << 5) /* Bit 5: Clear statistics registers */ +#define EMAC_NCR_INCSTAT (1 << 6) /* Bit 6: Increment statistics registers */ +#define EMAC_NCR_WESTAT (1 << 7) /* Bit 7: Write enable for statistics registers */ +#define EMAC_NCR_BP (1 << 8) /* Bit 8: Back pressure */ +#define EMAC_NCR_TSTART (1 << 9) /* Bit 9: Start transmission */ +#define EMAC_NCR_THALT (1 << 10) /* Bit 10: Transmit halt */ +#define EMAC_TXPF (1 << 11) /* Bit 11: Transmit Pause Frame */ +#define EMAC_TXZQPF (1 << 12) /* Bit 12: Transmit Zero Quantum Pause Frame */ +#define EMAC_SRTSM (1 << 15) /* Bit 15: Store Receive Time Stamp to Memory */ +#define EMAC_ENPBPR (1 << 16) /* Bit 16: Enable PFC Priority-based Pause Reception */ +#define EMAC_TXPBPF (1 << 17) /* Bit 17: Transmit PFC Priority-based Pause Frame */ +#define EMAC_FNP (1 << 18) /* Bit 18: Flush Next Packet */ + +/* Network Configuration Register */ + +#define EMAC_NCFGR_SPD (1 << 0) /* Bit 0: Speed */ +#define EMAC_NCFGR_FD (1 << 1) /* Bit 1: Full Duplex */ +#define EMAC_NCFGR_DNVLAN (1 << 2) /* Bit 2: Discard Non-VLAN FRAMES */ +#define EMAC_NCFGR_JFRAME (1 << 3) /* Bit 3: Jumbo Frames */ +#define EMAC_NCFGR_CAF (1 << 4) /* Bit 4: Copy All Frames */ +#define EMAC_NCFGR_NBC (1 << 5) /* Bit 5: No Broadcast */ +#define EMAC_NCFGR_MTIHEN (1 << 6) /* Bit 6: Multicast Hash Enable */ +#define EMAC_NCFGR_UNIHEN (1 << 7) /* Bit 7: Unicast Hash Enable */ +#define EMAC_NCFGR_MAXFS (1 << 8) /* Bit 8: 1536 Maximum Frame Size */ +#define EMAC_NCFGR_RTY (1 << 12) /* Bit 12: Retry test */ +#define EMAC_NCFGR_PEN (1 << 13) /* Bit 13: Pause Enable */ +#define EMAC_NCFGR_RXBUFO_SHIFT (14) /* Bits 14-15: Receive Buffer Offset */ +#define EMAC_NCFGR_RXBUFO_MASK (3 << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO(n) ((uint32_t)(n) << EMAC_NCFGR_RXBUFO_SHIFT) +# define EMAC_NCFGR_RXBUFO_NONE (0 << EMAC_NCFGR_RXBUFO_SHIFT) /* No offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_1 (1 << EMAC_NCFGR_RXBUFO_SHIFT) /* One-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_2 (2 << EMAC_NCFGR_RXBUFO_SHIFT) /* Two-byte offset from RX buffer start */ +# define EMAC_NCFGR_RXBUFO_3 (3 << EMAC_NCFGR_RXBUFO_SHIFT) /* Three-byte offset fromRX buffer start */ +#define EMAC_NCFGR_LFERD (1 << 16) /* Bit 16: Length Field Error Frame Discard */ +#define EMAC_NCFGR_RFCS (1 << 17) /* Bit 17: Remove FCS */ +#define EMAC_NCFGR_CLK_SHIFT (18) /* Bits 18-20: MDC clock divider */ +#define EMAC_NCFGR_CLK_MASK (7 << EMAC_NCFGR_CLK_SHIFT) +# define EMAC_NCFGR_CLK_DIV8 (0 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 8 (MCK up to 20 MHz) */ +# define EMAC_NCFGR_CLK_DIV16 (1 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 16 (MCK up to 40 MHz) */ +# define EMAC_NCFGR_CLK_DIV32 (2 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */ +# define EMAC_NCFGR_CLK_DIV48 (3 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 48 (MCK up to 120 MHz) */ +# define EMAC_NCFGR_CLK_DIV64 (4 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */ +# define EMAC_NCFGR_CLK_DIV96 (5 << EMAC_NCFGR_CLK_SHIFT) /* MCK divided by 96 (MCK up to 240 MHz) */ +#define EMAC_NCFGR_DBW_SHIFT (21) /* Bit 21-22: Data Bus Width */ +#define EMAC_NCFGR_DBW_MASK (3 << EMAC_NCFGR_DBW_SHIFT) +# define EMAC_NCFGR_DBW_ZERO (0 << EMAC_NCFGR_DBW_SHIFT) /* Must be zero */ +#define EMAC_NCFGR_DCPF (1 << 23) /* Bit 23: Disable Copy of Pause Frames */ +#define EMAC_NCFGR_RXCOEN (1 << 24) /* Bit 24: Receive Checksum Offload Enable */ +#define EMAC_NCFGR_EFRHD (1 << 25) /* Bit 25: Enable Frames Received in Half Duplex */ +#define EMAC_NCFGR_IRXFCS (1 << 26) /* Bit 26: Ignore RX FCS */ +#define EMAC_NCFGR_IPGSEN (1 << 28) /* Bit 28: IP Stretch Enable */ +#define EMAC_NCFGR_RXBP (1 << 29) /* Bit 29: Receive Bad Preamble */ +#define EMAC_NCFGR_IRXER (1 << 30) /* Bit 30: Ignore IPG GRXER */ + +/* Network Status Register */ + +#define EMAC_NSR_MDIO (1 << 1) /* Bit 1: Status of the MDIO input pin */ +#define EMAC_NSR_IDLE (1 << 2) /* Bit 2: PHY management logic is idle */ + +/* User Register */ + +#define EMAC_UR_RMII (1 << 0) /* Bit 0: Reduced MII Mode */ + +/* DMA Configuration Register */ + +#define EMAC_DCFGR_FBLDO_SHIFT (0) /* Bits 0-4: Fixed Burst Length for DMA Data Operations */ +#define EMAC_DCFGR_FBLDO_MASK (31 << EMAC_DCFGR_FBLDO_SHIFT) +# define EMAC_DCFGR_FBLDO_SINGLE (1 << EMAC_DCFGR_FBLDO_SHIFT) /* Always use SINGLE AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR4 (4 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR4 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR8 (8 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR8 AHB bursts */ +# define EMAC_DCFGR_FBLDO_INCR16 (16 << EMAC_DCFGR_FBLDO_SHIFT) /* Attempt to use INCR16 AHB bursts */ +#define EMAC_DCFGR_ESMA (1 << 6) /* Bit 6: Endian Swap Mode Enable for Management Descriptor Accesses */ +#define EMAC_DCFGR_ESPA (1 << 7) /* Bit 7: Endian Swap Mode Enable for Packet Data Accesses */ +#define EMAC_DCFGR_RXBMS_SHIFT (8) /* Bits 8-9: Receiver Packet Buffer Memory Size Select */ +#define EMAC_DCFGR_RXBMS_MASK (3 << EMAC_DCFGR_RXBMS_SHIFT) +# define EMAC_DCFGR_RXBMS_8TH (0 << EMAC_DCFGR_RXBMS_SHIFT) /* 4/8 Kbyte Memory Size */ +# define EMAC_DCFGR_RXBMS_4TH (1 << EMAC_DCFGR_RXBMS_SHIFT) /* 4/4 Kbytes Memory Size */ +# define EMAC_DCFGR_RXBMS_HALF (2 << EMAC_DCFGR_RXBMS_SHIFT) /* 4/2 Kbytes Memory Size */ +# define EMAC_DCFGR_RXBMS_FULL (3 << EMAC_DCFGR_RXBMS_SHIFT) /* 4 Kbytes Memory Size */ +#define EMAC_DCFGR_TXPBMS (1 << 10) /* Bit 10: Transmitter Packet Buffer Memory Size Select */ +#define EMAC_DCFGR_TXCOEN (1 << 11) /* Bit 11: Transmitter Checksum Generation Offload Enable */ +#define EMAC_DCFGR_DRBS_SHIFT (16) /* Bits 16-23: DMA Receive Buffer Size */ +#define EMAC_DCFGR_DRBS_MASK (0xff << EMAC_DCFGR_DRBS_SHIFT) +# define EMAC_DCFGR_DRBS(n) ((uint32_t)(n) << EMAC_DCFGR_DRBS_SHIFT) +#define EMAC_DCFGR_DDRP (1 << 24) /* Bit 24: DMA Discard Receive Packets */ + +/* Transmit Status Register */ + +#define EMAC_TSR_UBR (1 << 0) /* Bit 0: Used Bit Read */ +#define EMAC_TSR_COL (1 << 1) /* Bit 1: Collision Occurred */ +#define EMAC_TSR_RLE (1 << 2) /* Bit 2: Retry Limit exceeded */ +#define EMAC_TSR_TXGO (1 << 3) /* Bit 3: Transmit Go */ +#define EMAC_TSR_TFC (1 << 4) /* Bit 4: Transmit Frame Corruption due to AHB error */ +#define EMAC_TSR_TXCOMP (1 << 5) /* Bit 5: Transmit Complete */ +#define EMAC_TSR_HRESP (1 << 8) /* Bit 8: HRESP Not OK */ + +/* Receive Buffer Queue Pointer Register */ + +#define EMAC_RBQB_MASK (0xfffffffc) /* Bits 2-31: Receive buffer queue pointer address */ + +/* Transmit Buffer Queue Pointer Register */ + +#define EMAC_TBQB_MASK (0xfffffffc) /* Bits 2-31: Transmit buffer queue pointer address */ + +/* Receive Status Register */ + +#define EMAC_RSR_BNA (1 << 0) /* Bit 0: Buffer Not Available */ +#define EMAC_RSR_REC (1 << 1) /* Bit 1: Frame Received */ +#define EMAC_RSR_RXOVR (1 << 2) /* Bit 2: Receive Overrun */ +#define EMAC_RSR_HNO (1 << 3) /* Bit 3: HRESP Not OK */ + +/* Interrupt Status Register (ISR), Interrupt Enable Register (IER), Interrupt Disable Register (IDR) and Interrupt Mask Register (IMR) */ + +#define EMAC_INT_MFS (1 << 0) /* Bit 0: Management Frame Sent */ +#define EMAC_INT_RCOMP (1 << 1) /* Bit 1: Receive Complete */ +#define EMAC_INT_RXUBR (1 << 2) /* Bit 2: Receive Used Bit Read */ +#define EMAC_INT_TXUBR (1 << 3) /* Bit 3: Transmit Used Bit Read */ +#define EMAC_INT_TUR (1 << 4) /* Bit 4: Ethernet Transmit Buffer Underrun */ +#define EMAC_INT_RLEX (1 << 5) /* Bit 5: Retry Limit Exceeded */ +#define EMAC_INT_TFC (1 << 6) /* Bit 6: Transmit Frame Corruption due to AHB error */ +#define EMAC_INT_TCOMP (1 << 7) /* Bit 7: Transmit Complete */ +#define EMAC_INT_ROVR (1 << 10) /* Bit 10: Receive Overrun */ +#define EMAC_INT_HRESP (1 << 11) /* Bit 11: Hresp not OK */ +#define EMAC_INT_PFNZ (1 << 12) /* Bit 12: Pause Frame with Non-zero Pause Quantum Received */ +#define EMAC_INT_PTZ (1 << 13) /* Bit 13: Pause Time Zero */ +#define EMAC_INT_PTFR (1 << 14) /* Bit 14: Pause Frame Transmitted */ +#define EMAC_INT_EXINT (1 << 15) /* Bit 15: External Interrupt (not SR) */ +#define EMAC_INT_DRQFR (1 << 18) /* Bit 18: PTP Delay Request Frame Received */ +#define EMAC_INT_SFR (1 << 19) /* Bit 19: PTP Sync Frame Received */ +#define EMAC_INT_DRQFT (1 << 20) /* Bit 20: PTP Delay Request Frame Transmitted */ +#define EMAC_INT_SFT (1 << 21) /* Bit 21: PTP Sync Frame Transmitted */ +#define EMAC_INT_PDRQFR (1 << 22) /* Bit 22: PDelay Request Frame Received */ +#define EMAC_INT_PDRSFR (1 << 23) /* Bit 23: PDelay Response Frame Received */ +#define EMAC_INT_PDRQFT (1 << 24) /* Bit 24: PDelay Request Frame Transmitted */ +#define EMAC_INT_PDRSFT (1 << 25) /* Bit 25: PDelay Response Frame Transmitted */ +#define EMAC_INT_SRI (1 << 26) /* Bit 26: TSU Seconds Register Increment (not IMR) */ +#define EMAC_INT_WOL (1 << 28) /* Bit 28: Wake On LAN (not IMR) */ + +#define EMAC_INT_ALL (0x17fcfcff) +#define EMAC_INT_UNUSED (0xe8030300) + +/* PHY Maintenance Register */ + +#define EMAC_MAN_DATA_SHIFT (0) /* Bits 0-15: Read/write data */ +#define EMAC_MAN_DATA_MASK (0x0000ffff << EMAC_MAN_DATA_SHIFT) +# define EMAC_MAN_DATA(n) ((uint32_t)(n) << EMAC_MAN_DATA_SHIFT) +#define EMAC_MAN_WTN_SHIFT (16) /* Bits 16-17: Must be written to b10 */ +#define EMAC_MAN_WTN_MASK (3 << EMAC_MAN_WTN_SHIFT) +# define EMAC_MAN_WTN (2 << EMAC_MAN_WTN_SHIFT) +#define EMAC_MAN_REGA_SHIFT (18) /* Bits 18-22: Register Address */ +#define EMAC_MAN_REGA_MASK (31 << EMAC_MAN_REGA_SHIFT) +# define EMAC_MAN_REGA(n) ((uint32_t)(n) << EMAC_MAN_REGA_SHIFT) +#define EMAC_MAN_PHYA_SHIFT (23) /* Bits 23-27: PHY Address */ +#define EMAC_MAN_PHYA_MASK (31 << EMAC_MAN_PHYA_SHIFT) +# define EMAC_MAN_PHYA(n) ((uint32_t)(n) << EMAC_MAN_PHYA_SHIFT) +#define EMAC_MAN_OP_SHIFT (28) /* Bits 28-29: Operation */ +#define EMAC_MAN_OP_MASK (3 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_READ (2 << EMAC_MAN_OP_SHIFT) +# define EMAC_MAN_WRITE (1 << EMAC_MAN_OP_SHIFT) +#define EMAC_MAN_CLTTO (1 << 30) /* Bit 30: Clause 22 Operation */ +#define EMAC_MAN_WZO (0) /* Bit 31: Write ZERO */ + +/* Pause Time Register */ + +#define EMAC_RPQ_MASK (0x0000ffff) /* Bits 0-15: Received Pause Quantum */ + +/* Pause Frames Received Register */ + +#define EMAC_TPQ_MASK (0x0000ffff) /* Bits 0-15: Transmit Pause Quantum */ + +/* TX Partial Store and Forward Register */ + +#define EMAC_TPSF_TPB1ADR_SHIFT (0) /* Bits 0-11: Transmit Partial Store and Forward Address */ +#define EMAC_TPSF_TPB1ADR_MASK (0xfff << EMAC_TPSF_TPB1ADR_SHIFT) +# define EMAC_TPSF_TPB1ADR(n) ((uint32_t)(n) << EMAC_TPSF_TPB1ADR_SHIFT) +#define EMAC_TPSF_ENTXP (1 << 31) /* Bit 31: Enable TX Partial Store and Forward Operation */ + +/* RX Partial Store and Forward Register */ + +#define EMAC_RPSF_RPB1ADR_SHIFT (0) /* Bits 0-11: Recieve Partial Store and Forward Address */ +#define EMAC_RPSF_RPB1ADR_MASK (0xfff << EMAC_RPSF_RPB1ADR_SHIFT) +# define EMAC_RPSF_RPB1ADR(n) ((uint32_t)(n) << EMAC_RPSF_RPB1ADR_SHIFT) +#define EMAC_RPSF_ENRXP (1 << 31) /* Bit 31: Enable RX Partial Store and Forward Operation */ + +/* RX Jumbo Frame Max Length Register */ + +#define EMAC_RJFML_MASK 0x00003fff /* Bits 0-13: Frame Max Length */ + +/* Hash Register Bottom [31:0] Register (LS 32-bit hash address) */ +/* Hash Register Top [63:32] Register (MS 32-bit hash address) */ + +/* Specific Address 1 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Top [47:32] Register */ + +#define EMAC_SAT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 2 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 2 Top [47:32] Register */ + +#define EMAC_SAT2_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 3 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 3 Top [47:32] Register */ + +#define EMAC_SAT3_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Specific Address 4 Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 4 Top [47:32] Register */ + +#define EMAC_SAT4_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of the destination address */ + +/* Type ID Match Registers */ + +#define EMAC_TIDM_MASK (0x0000ffff) /* Bits 0-15: Type ID Match n */ + +/* Type ID Checking Register */ + +#define EMAC_TID_SHIFT (0) /* Bits 0-15: Type ID Match */ +#define EMAC_TID_MASK (0xffff << EMAC_TID_SHIFT) +# define EMAC_TID(n) ((uint32_t)(n) << EMAC_TID_SHIFT) +#define EMAC_TID_ENID (1 << 31) /* Bit 31: Enable Copying of TID Matched Frames */ + +/* Wake-up on LAN Register */ + +#define EMAC_WOL_IP_SHIFT (0) /* Bits 0-15: ARP Request IP Address */ +#define EMAC_WOL_IP_MASK (0x0000ffff << EMAC_WOL_IP_SHIFT) +# define EMAC_WOL_IP(n) ((uin32_t)(n) << EMAC_WOL_IP_SHIFT) +#define EMAC_WOL_MAG (1 << 16) /* Bit 16: Magic Packet Event Enable */ +#define EMAC_WOL_ARP (1 << 17) /* Bit 17: ARP Request Event Enable */ +#define EMAC_WOL_SA1 (1 << 18) /* Bit 18: Specific Address Register 1 Event Enable */ +#define EMAC_WOL_MTI (1 << 19) /* Bit 19: Multicast Hash Event Enable */ + +/* IPG Stretch Register */ + +#define EMAC_IPGS_FL_MASK (0x0000ffff) /* Bit 0-15: Frame Length */ + +/* Stacked VLAN Register */ + +#define EMAC_SVLAN_VLANTYPE_SHIFT (0) /* Bits 0-15: User Defined VLAN_TYPE Field */ +#define EMAC_SVLAN_VLANTYPE_MASK (0x0000ffff << EMAC_SVLAN_VLANTYPE_SHIFT) +# define EMAC_SVLAN_VLANTYPE(n) ((uint32_t)(n) << EMAC_SVLAN_VLANTYPE_SHIFT) +#define EMAC_SVLAN_ESVLAN (1 << 31) /* Bit 31: Enable Stacked VLAN Processing Mode */ + +/* Transmit PFC Pause Register */ + +#define EMAC_TPFCP_PEV_SHIFT (0) /* Bits 0-7: Priority Enable Vector */ +#define EMAC_TPFCP_PEV_MASK (0xff << EMAC_TPFCP_PEV_SHIFT) +# define EMAC_TPFCP_PEV(n) ((uint32_t)(n) << EMAC_TPFCP_PEV_SHIFT) +#define EMAC_TPFCP_PQ_SHIFT (8) /* Bits 8-15: Pause Quantum */ +#define EMAC_TPFCP_PQ_MASK (0xff << EMAC_TPFCP_PQ_SHIFT) +# define EMAC_TPFCP_PQ(n) ((uint32_t)(n) << EMAC_TPFCP_PQ_SHIFT) + +/* Specific Address 1 Mask Bottom [31:0] Register (LS 32-bit address) */ +/* Specific Address 1 Mask Top [47:32] Register (MS 16-bit address) */ + +#define EMAC_SAMT1_MASK (0x0000ffff) /* Bits 0-15: Bits 32-47 of Specific Address 1 Mask */ + +/* 1588 Timer Nanosecond Comparison Register */ + +#define EMAC_NSC_MASK (0x00cfffff) /* Bits 0-21: 1588 Timer Nanosecond Comparison Value */ + +/* 1588 Timer Second Comparison Low Register (32-bit value) */ +/* 1588 Timer Second Comparison High Register */ + +#define EMAC_SCH_MASK (0x0000ffff) /* Bits 0-15: 1588 Timer Second Comparison Value */ + +/* PTP Event Frame Transmitted Seconds High Register */ + +#define EMAC_EFTSH_MASK (0x0000ffff) /* Bits 0-15: Register Update */ + +/* PTP Event Frame Received Seconds High Register */ + +#define EMAC_EFRSH_MASK (0x0000ffff) /* Bits 0-15: Register Update */ + +/* PTP Peer Event Frame Transmitted Seconds High Register */ + +#define EMAC_PEFTSH_MASK (0x0000ffff) /* Bits 0-15: Register Update */ + +/* PTP Peer Event Frame Received Seconds High Register */ + +#define EMAC_PEFRSH_MASK (0x0000ffff) /* Bits 0-15: Register Update */ + +/* Statistics registers. Only masking is needed. + * + * Octets Transmitted [31:0] Register (OTLO) 32-bit + * Octets Transmitted [47:32] Register (OTHI) 16-bit + * Frames Transmitted Register (FT) 32-bit + * Broadcast Frames Transmitted Register (BCFT) 32-bit + * Multicast Frames Transmitted Register (MFT) 32-bit + * Pause Frames Transmitted Register (PFT) 16-bit + * 64 Byte Frames Transmitted Register (BFT64) 32-bit + * 65 to 127 Byte Frames Transmitted Register (TBFT127) 32-bit + * 128 to 255 Byte Frames Transmitted Register (TBFT255) 32-bit + * 256 to 511 Byte Frames Transmitted Register (TBFT511) 32-bit + * 512 to 1023 Byte Frames Transmitted Register (TBFT1023) 32-bit + * 1024 to 1518 Byte Frames Transmitted Register (TBFT1518) 32-bit + * Greater Than 1518 Byte Frames Transmitted Register (GTBFT1518) 32-bit + * Transmit Under Runs Register (TUR) 10-bit + * Single Collision Frames Register (SCF) 18-bit + * Multiple Collision Frames Register (MCF) 18-bit + * Excessive Collisions Register (EC) 10-bit + * Late Collisions Register (LC) 10-bit + * Deferred Transmission Frames Register (DTF) 18-bit + * Carrier Sense Errors Register (CSE) 10-bit + * Octets Received [31:0] Received (ORLO) 32-bit + * Octets Received [47:32] Received (ORHI) 16-bit + * Frames Received Register (FR) 32-bit + * Broadcast Frames Received Register (BCFR) 32-bit + * Multicast Frames Received Register (MFR) 32-bit + * Pause Frames Received Register (PFR) 32-bit + * 64 Byte Frames Received Register (BFR64) 32-bit + * 65 to 127 Byte Frames Received Register (TBFR127) 32-bit + * 128 to 255 Byte Frames Received Register (TBFR255) 32-bit + * 256 to 511Byte Frames Received Register (TBFR511) 32-bit + * 512 to 1023 Byte Frames Received Register (TBFR1023) 32-bit + * 1024 to 1518 Byte Frames Received Register (TBFR1518) 32-bit + * 1519 to Maximum Byte Frames Received Register (TMXBFR) 32-bit + * Undersize Frames Received Register (UFR) 10-bit + * Oversize Frames Received Register (OFR) 10-bit + * Jabbers Received Register (JR) 10-bit + * Frame Check Sequence Errors Register (FCSE) 10-bit + * Length Field Frame Errors Register (LFFE) 10-bit + * Receive Symbol Errors Register (RSE) 10-bit + * Alignment Errors Register (AE) 10-bit + * Receive Resource Errors Register (RRE) 18-bit + * Receive Overrun Register (ROE) 10-bit + * IP Header Checksum Errors Register (IHCE) 8-bit + * TCP Checksum Errors Register (TCE) 8-bit + * UDP Checksum Errors Register (UCE) 8-bit + */ + +/* PTP/1588 Timer Registers */ + +/* 1588 Timer Increment Sub-nanoseconds Register */ + +#define EMAC_TISUBN_MASK (0x0000ffff) /* Bits 0-15: LS Bits of Timer Increment Register */ + +/* 1588 Timer Seconds High Register (32-bit timer value) */ +/* 1588 Timer Seconds Low Register (32-bit timer value) */ +/* 1588 Timer Nanoseconds Register (30-bit timer value) */ + +#define EMAC_TN_MASK (0x3fffffff) /* Bit 0-29: Timer Count in Nanoseconds */ + +/* 1588 Timer Adjust Register */ + +#define EMAC_TA_ITDT_SHIFT (0) /* Bits 0-29: Increment/Decrement */ +#define EMAC_TA_ITDT_MASK (0x3fffffff << EMAC_TA_ITDT_SHIFT) +# define EMAC_TA_ITDT(n) ((uint32_t)(n) << EMAC_TA_ITDT_SHIFT) +#define EMAC_TA_ADJ (1 << 31) /* Bit 31: Adjust 1588 Timer */ + +/* 1588 Timer Increment Register */ + +#define EMAC_TI_CNS_SHIFT (0) /* Bits 0-7: Count Nanoseconds */ +#define EMAC_TI_CNS_MASK (0xff << EMAC_TI_CNS_SHIFT) +# define EMAC_TI_CNS(n) ((uint32_t)(n) << EMAC_TI_CNS_SHIFT) +#define EMAC_TI_ACNS_SHIFT (8) /* Bits 8-15: Alternative Count Nanoseconds */ +#define EMAC_TI_ACNS_MASK (0xff << EMAC_TI_ACNS_SHIFT) +# define EMAC_TI_ACNS(n) ((uint32_t)(n) << EMAC_TI_ACNS_SHIFT) +#define EMAC_TI_NIT_SHIFT (16) /* Bits 16-23: Number of Increments */ +#define EMAC_TI_NIT_MASK (0xff << EMAC_TI_NIT_SHIFT) +# define EMAC_TI_NIT(n) ((uint32_t)(n) << EMAC_TI_NIT_SHIFT) + +/* PTP Event Frame Transmitted Seconds Low (32-bit timer value) */ +/* PTP Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_EFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Event Frame Received Seconds Low (32-bit timer value) */ +/* PTP Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_EFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Transmitted Seconds Low (32-bit timer value) */ +/* PTP Peer Event Frame Transmitted Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFTN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* PTP Peer Event Frame Received Seconds Low (32-bit timer value) */ +/* PTP Peer Event Frame Received Nanoseconds (30-bit timer value) */ + +#define EMAC_PEFRN_MASK (0x3fffffff) /* Bit 0-29: Register Update */ + +/* Interrupt Status Register Priority Queue, Interrupt Enable Register Priority Queue, + * Interrupt Disable Register Priority Queue, and Interrupt Mask Register Priority Queue, + * n=1-3 + * + * This register uses a subset of the standard interrupt definitions: + * + * EMAC_INT_RCOMP Bit 1: Receive Complete + * EMAC_INT_RXUBR Bit 2: Receive Used Bit Read + * EMAC_INT_RLEX Bit 5: Retry Limit Exceeded + * EMAC_INT_TFC Bit 6: Transmit Frame Corruption due to AHB error + * EMAC_INT_TCOMP Bit 7: Transmit Complete + * EMAC_INT_ROVR Bit 10: Receive Overrun + * EMAC_INT_HRESP Bit 11: Hresp not OK + */ + +#define EMAC_INTPQ_ALL (0x00000ce6) +#define EMAC_INTPG_UNUSED (0xfffffe19) + +/* Transmit Buffer Queue Base Address Register Priority Queue, n=1-3 */ + +#define EMAC_ISRPQ_TBQBAPQ_MASK (0xfffffffc) /* Bits 2-31: Transmit Buffer Queue Base Address */ + +/* Receive Buffer Queue Base Address Register Priority Queue, n=1-3 */ + +#define EMAC_ISRPQ_RBQBAPQ_MASK (0xfffffffc) /* Bits 2-31: Receive Buffer Queue Base Address */ + +/* Receive Buffer Size Register Priority Queue, n=1-3 */ + +#define EMAC_ISRPQ_RBSRPQ_MASK (0x0000ffff) /* Bits 0-15: Receive Buffer Size */ + +/* Credit-Based Shaping Control Register */ + +#define EMAC_ISRPQ_CBSCR_QAE (1 << 0) /* Bit 0: Queue A CBS Enable */ +#define EMAC_ISRPQ_CBSCR_QBE (1 << 1) /* Bit 1: Queue B CBS Enable */ + +/* Credit-Based Shaping IdleSlope Register for Queue A (32-bit value) */ +/* Credit-Based Shaping IdleSlope Register for Queue B (32-bit value) */ + +/* Screening Type 1 Register Priority Queue, 0=1-3 */ + +#define EMAC_ISRPQ_ST1RPQ_QNB_SHIFT (0) /* Bits 0-2: Queue Number (0–2) */ +#define EMAC_ISRPQ_ST1RPQ_QNB_MASK (7 << EMAC_ISRPQ_ST1RPQ_QNB_SHIFT) +# define EMAC_ISRPQ_ST1RPQ_QNB(n) ((uint32_t)(n) << EMAC_ISRPQ_ST1RPQ_QNB_SHIFT) +#define EMAC_ISRPQ_ST1RPQ_DSTCM_SHIFT (4) /* Bits 4-11: Differentiated Services or Traffic Class Match */ +#define EMAC_ISRPQ_ST1RPQ_DSTCM_MASK (0xff << EMAC_ISRPQ_ST1RPQ_DSTCM_SHIFT) +# define EMAC_ISRPQ_ST1RPQ_DSTCM(n) ((uint32_t)(n) << EMAC_ISRPQ_ST1RPQ_DSTCM_SHIFT) +#define EMAC_ISRPQ_ST1RPQ_UDPM_SHIFT (12) /* Bits 12-27: UDP Port Match */ +#define EMAC_ISRPQ_ST1RPQ_UDPM_MASK (0xffff << EMAC_ISRPQ_ST1RPQ_UDPM_SHIFT) +# define EMAC_ISRPQ_ST1RPQ_UDPM(n) ((uint32_t)(n) << EMAC_ISRPQ_ST1RPQ_UDPM_SHIFT) +#define EMAC_ISRPQ_ST1RPQ_DSTCE (1 << 28) /* Bit 28: Differentiated Services or Traffic Class Match Enable */ +#define EMAC_ISRPQ_ST1RPQ_UDPE (1 << 29) /* Bit 29: UDP Port Match Enable */ + +/* Screening Type 2 Register Priority Queue, 0=1-7 */ + +#define EMAC_ISRPQ_ST2RPQ_QNB_SHIFT (0) /* Bits 0-3: Queue Number (0–2) */ +#define EMAC_ISRPQ_ST2RPQ_QNB_MASK (7 << EMAC_ISRPQ_ST2RPQ_QNB_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_QNB(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_QNB_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_VLANP_SHIFT (4) /* Bits 4-6: VLAN Priority */ +#define EMAC_ISRPQ_ST2RPQ_VLANP_MASK (7 << EMAC_ISRPQ_ST2RPQ_VLANP_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_VLANP(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_VLANP_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_VLANE (1 << 8) /* Bit 8: VLAN Enable */ +#define EMAC_ISRPQ_ST2RPQ_I2ETH_SHIFT (9) /* Bits 9-11: Index of Screening Type 2 EtherType register x */ +#define EMAC_ISRPQ_ST2RPQ_I2ETH_MASK (7 << EMAC_ISRPQ_ST2RPQ_I2ETH_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_I2ETH(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_I2ETH_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_ETHE (1 << 12) /* Bit 12: EtherType Enable */ +#define EMAC_ISRPQ_ST2RPQ_COMPA_SHIFT (13) /* Bits 13-17: Index of Screening Type 2 Compare Word 0/Word 1 register x */ +#define EMAC_ISRPQ_ST2RPQ_COMPA_MASK (31 << EMAC_ISRPQ_ST2RPQ_COMPA_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_COMPA(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_COMPA_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_COMPAE (1 << 18) /* Bit 18: Compare A Enable */ +#define EMAC_ISRPQ_ST2RPQ_COMPB_SHIFT (19) /* Bits 19-23: Index of Screening Type 2 Compare Word 0/Word 1 register x */ +#define EMAC_ISRPQ_ST2RPQ_COMPB_MASK (31 << EMAC_ISRPQ_ST2RPQ_COMPB_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_COMPB(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_COMPB_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_COMPBE (1 << 24) /* Bit 24: Compare B Enable */ +#define EMAC_ISRPQ_ST2RPQ_COMPC_SHIFT (25) /* Bits 25-29: Index of Screening Type 2 Compare Word 0/Word 1 register x */ +#define EMAC_ISRPQ_ST2RPQ_COMPC_MASK (31 << EMAC_ISRPQ_ST2RPQ_COMPC_SHIFT) +# define EMAC_ISRPQ_ST2RPQ_COMPC(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2RPQ_COMPC_SHIFT) +#define EMAC_ISRPQ_ST2RPQ_COMPCE (1 << 30) /* Bit 30: Compare C Enable */ + +/* Screening Type 2 Ethertype Register, n=0-3 */ + +#define EMAC_ISRPQ_ST2ER_MASK (0x0000ffff) /* Bits 0-15: Ethertype Compare Value */ + +/* Screening Type 2 Compare Word 0 Registerm, n=0-23 */ + +#define EMAC_ISRPQ_ST2CW0_MASK_SHIFT (0) /* Bits 0-15: Mask Value */ +#define EMAC_ISRPQ_ST2CW0_MASK_MASK (0xffff << EMAC_ISRPQ_ST2CW0_MASK_SHIFT) +# define EMAC_ISRPQ_ST2CW0_MASK(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2CW0_MASK_SHIFT) +#define EMAC_ISRPQ_ST2CW0_COMP_SHIFT (16) /* Bits 16-31: Compare Value */ +#define EMAC_ISRPQ_ST2CW0_COMP_MASK (0xffff << EMAC_ISRPQ_ST2CW0_COMP_SHIFT) +# define EMAC_ISRPQ_ST2CW0_COMP(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2CW0_COMP_SHIFT) + +/* Screening Type 2 Compare Word 1 Register, n=0-23 */ + +#define EMAC_ISRPQ_ST2CW1_OFFS_SHIFT (0) /* Bits 0-6: Offset Value in Bytes */ +#define EMAC_ISRPQ_ST2CW1_OFFS_MASK (0x7f << EMAC_ISRPQ_ST2CW1_OFFS_SHIFT) +# define EMAC_ISRPQ_ST2CW1_OFFS(n) ((uint32_t)(n) << EMAC_ISRPQ_ST2CW1_OFFS_SHIFT) +#define EMAC_ISRPQ_ST2CW1_STRT_SHIFT (7) /* Bits 7-8: Ethernet Frame Offset Start */ +#define EMAC_ISRPQ_ST2CW1_STRT_MASK (3 << EMAC_ISRPQ_ST2CW1_STRT_SHIFT) +# define EMAC_ISRPQ_ST2CW1_STRT_FRMSTRT (0 << EMAC_ISRPQ_ST2CW1_STRT_SHIFT) /* Offset from the start of the frame */ +# define EMAC_ISRPQ_ST2CW1_STRT_ETHTYP (1 << EMAC_ISRPQ_ST2CW1_STRT_SHIFT) /* Offset from the byte after the EtherType field */ +# define EMAC_ISRPQ_ST2CW1_STRT_IP (2 << EMAC_ISRPQ_ST2CW1_STRT_SHIFT) /* Offset from the byte after the IP header field */ +# define EMAC_ISRPQ_ST2CW1_STRT_TCPUDP (3 << EMAC_ISRPQ_ST2CW1_STRT_SHIFT) /* Offset from the byte after the TCP/UDP header field */ + +/* Descriptors **********************************************************************/ + +/* Receive buffer descriptor: Address word */ + +#define EMACRXD_ADDR_OWNER (1 << 0) /* Bit 0: 1=Software owns; 0=EMAC owns */ +#define EMACRXD_ADDR_WRAP (1 << 1) /* Bit 1: Last descriptor in list */ +#define EMACRXD_ADDR_MASK (0xfffffffc) /* Bits 2-31: Aligned buffer address */ + +/* Receive buffer descriptor: Control word */ + +#define EMACRXD_STA_FRLEN_SHIFT (0) /* Bits 0-12: Length of frame (not jumbo)*/ +#define EMACRXD_STA_FRLEN_MASK (0x00001fff << EMACRXD_STA_FRLEN_SHIFT) +#define EMACRXD_STA_JFRLEN_SHIFT (0) /* Bits 0-13: Length of frame (jumbo)*/ +#define EMACRXD_STA_JFRLEN_MASK (0x00003fff << EMACRXD_STA_JFRLEN_SHIFT) +#define EMACRXD_STA_BADFCS (1 << 13) /* Bit 13: Frame had bad FCS (not jumbo) */ +#define EMACRXD_STA_SOF (1 << 14) /* Bit 14: Start of frame */ +#define EMACRXD_STA_EOF (1 << 15) /* Bit 15: End of frame */ +#define EMACRXD_STA_CFI (1 << 16) /* Bit 16: Concatenation format indicator (CFI) bit */ +#define EMACRXD_STA_VLPRIO_SHIFT (17) /* Bits 17-19: VLAN priority */ +#define EMACRXD_STA_VLPRIO_MASK (7 << EMACRXD_STA_VLANPRIO_SHIFT) +#define EMACRXD_STA_PRIODET (1 << 20) /* Bit 20: Priority tag detected */ +#define EMACRXD_STA_VLANTAG (1 << 21) /* Bit 21: VLAN tag detected */ +#define EMACRXD_STA_TYPEID_SHIFT (22) /* Bit 22-23: Specific address register */ +#define EMACRXD_STA_TYPEID_MASK (3 << EMACRXD_STA_TYPEID_SHIFT) +# define EMACRXD_STA_TYPEID1 (0 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 1 match */ +# define EMACRXD_STA_TYPEID2 (1 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 2 match */ +# define EMACRXD_STA_TYPEID3 (2 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 3 match */ +# define EMACRXD_STA_TYPEID4 (3 << EMACRXD_STA_TYPEID_SHIFT) /* Type ID register 4 match */ +#define EMACRXD_STA_TYPEIDMATCH (1 << 24) /* Bit 24: Type ID register match found */ +#define EMACRXD_STA_SNAP (1 << 24) /* Bit 24: Frame was SNAP encoded */ +#define EMACRXD_STA_ADDR_SHIFT (25) /* Bit 25-26: Specific address register */ +#define EMACRXD_STA_ADDR_MASK (3 << EMACRXD_STA_ADDR_SHIFT) +# define EMACRXD_STA_ADDR1 (0 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 1 match */ +# define EMACRXD_STA_ADDR2 (1 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 2 match */ +# define EMACRXD_STA_ADDR3 (2 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 3 match */ +# define EMACRXD_STA_ADDR4 (3 << EMACRXD_STA_ADDR_SHIFT) /* Specific address register 4 match */ +#define EMACRXD_STA_ADDRMATCH (1 << 27) /* Bit 27: Specific address match found */ + /* Bit 28: Reserved */ +#define EMACRXD_STA_UCAST (1 << 29) /* Bit 29: Unicast hash match */ +#define EMACRXD_STA_MCAST (1 << 30) /* Bit 30: Multicast hash match */ +#define EMACRXD_STA_BCAST (1 << 31) /* Bit 31: Global all ones broadcast address detected */ + +/* Transmit buffer descriptor: Address word (un-aligned, 32-bit address */ +/* Transmit buffer descriptor: Control word */ + +#define EMACTXD_STA_BUFLEN_SHIFT (0) /* Bits 0-13: Length of buffer */ +#define EMACTXD_STA_BUFLEN_MASK (0x00003fff << EMACTXD_STA_BUFLEN_SHIFT) + /* Bit 14: Reserved */ +#define EMACTXD_STA_LAST (1 << 15) /* Bit 15: Last buffer in the current frame */ +#define EMACTXD_STA_NOCRC (1 << 16) /* Bit 16: No CRC */ + /* Bits 17-19: Reserved */ +#define EMACTXD_STA_CHKERR_SHIFT (20) /* Bits 20-22: Transmit IP/TCP/UDP checksum generation offload errors */ +#define EMACTXD_STA_CHKERR_MASK (7 << EMACTXD_STA_CHKERR_SHIFT) +# define EMACTXD_STA_CHKERR_NONE (0 << EMACTXD_STA_CHKERR_SHIFT) /* No Error */ +# define EMACTXD_STA_CHKERR_BADVLAN (1 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous VLAN type */ +# define EMACTXD_STA_CHKERR_BADSNAP (2 << EMACTXD_STA_CHKERR_SHIFT) /* Incomplete/erroneous SNAP type */ +# define EMACTXD_STA_CHKERR_NOTIP (3 << EMACTXD_STA_CHKERR_SHIFT) /* Not IP or invalid IP type */ +# define EMACTXD_STA_CHKERR_UNREC (4 << EMACTXD_STA_CHKERR_SHIFT) /* Not VLAN, SNAP, or IP */ +# define EMACTXD_STA_CHKERR_BADFRAG (5 << EMACTXD_STA_CHKERR_SHIFT) /* Unsupported fragmentation */ +# define EMACTXD_STA_CHKERR_PKTTYPE (6 << EMACTXD_STA_CHKERR_SHIFT) /* Not TCP or UDP */ +# define EMACTXD_STA_CHKERR_EPKT (7 << EMACTXD_STA_CHKERR_SHIFT) /* Premature end of packet */ + /* Bits 23-25: Reserved */ +#define EMACTXD_STA_LCOL (1 << 26) /* Bit 26: Late collision, transmit error detected */ +#define EMACTXD_STA_TFC (1 << 27) /* Bit 27: Transmit frame corruption due to AHB error */ + /* Bit 28: Reserved */ +#define EMACTXD_STA_TXERR (1 << 29) /* Bit 29: Retry limit exceeded, transmit error detected */ +#define EMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */ +#define EMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the EMAC to read from buffer */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Receive buffer descriptor */ + +struct emac_rxdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* RX status and controls */ +}; + +/* Transmit buffer descriptor */ + +struct emac_txdesc_s +{ + uint32_t addr; /* Buffer address */ + uint32_t status; /* TX status and controls */ +}; + +#endif /* SAMV7_NEMAC > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_EMAC_H */ diff --git a/arch/arm/src/samv7/chip/sam_hsmci.h b/arch/arm/src/samv7/chip/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..38b817ae8be7c7eab34d4a369a44a027aadecede --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_hsmci.h @@ -0,0 +1,366 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_hsmci.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_HSMCI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NHSMCI4 > 0 + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* HSMCI register offsets ***************************************************************/ + +#define SAM_HSMCI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_HSMCI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_HSMCI_DTOR_OFFSET 0x0008 /* Data Timeout Register */ +#define SAM_HSMCI_SDCR_OFFSET 0x000c /* SD/SDIO Card Register */ +#define SAM_HSMCI_ARGR_OFFSET 0x0010 /* Argument Register */ +#define SAM_HSMCI_CMDR_OFFSET 0x0014 /* Command Register */ +#define SAM_HSMCI_BLKR_OFFSET 0x0018 /* Block Register */ +#define SAM_HSMCI_CSTOR_OFFSET 0x001c /* Completion Signal Timeout Register */ +#define SAM_HSMCI_RSPR0_OFFSET 0x0020 /* Response Register 0 */ +#define SAM_HSMCI_RSPR1_OFFSET 0x0024 /* Response Register 1 */ +#define SAM_HSMCI_RSPR2_OFFSET 0x0028 /* Response Register 2 */ +#define SAM_HSMCI_RSPR3_OFFSET 0x002c /* Response Register 3 */ +#define SAM_HSMCI_RDR_OFFSET 0x0030 /* Receive Data Register */ +#define SAM_HSMCI_TDR_OFFSET 0x0034 /* Transmit Data Register */ + /* 0x0038-0x003c: Reserved */ +#define SAM_HSMCI_SR_OFFSET 0x0040 /* Status Register */ +#define SAM_HSMCI_IER_OFFSET 0x0044 /* Interrupt Enable Register */ +#define SAM_HSMCI_IDR_OFFSET 0x0048 /* Interrupt Disable Register */ +#define SAM_HSMCI_IMR_OFFSET 0x004c /* Interrupt Mask Register */ +#define SAM_HSMCI_DMA_OFFSET 0x0050 /* DMA Configuration Register */ +#define SAM_HSMCI_CFG_OFFSET 0x0054 /* Configuration Register */ + /* 0x0058-0x00e0: Reserved */ +#define SAM_HSMCI_WPMR_OFFSET 0x00e4 /* Write Protection Mode Register */ +#define SAM_HSMCI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0x00ec-0x00fc: Reserved */ + /* 0x0100-0x0124: Reserved for PCD registers */ +#define SAM_HSMCI_FIFO_OFFSET 0x0200 /* 0x0200-0x05fc FIFO Memory Aperture */ + +/* HSMCI register addresses *************************************************************/ + +#define SAM_HSMCI0_CR (SAM_HSMCI0_BASE+SAM_HSMCI_CR_OFFSET) +#define SAM_HSMCI0_MR (SAM_HSMCI0_BASE+SAM_HSMCI_MR_OFFSET) +#define SAM_HSMCI0_DTOR (SAM_HSMCI0_BASE+SAM_HSMCI_DTOR_OFFSET) +#define SAM_HSMCI0_SDCR (SAM_HSMCI0_BASE+SAM_HSMCI_SDCR_OFFSET) +#define SAM_HSMCI0_ARGR (SAM_HSMCI0_BASE+SAM_HSMCI_ARGR_OFFSET) +#define SAM_HSMCI0_CMDR (SAM_HSMCI0_BASE+SAM_HSMCI_CMDR_OFFSET) +#define SAM_HSMCI0_BLKR (SAM_HSMCI0_BASE+SAM_HSMCI_BLKR_OFFSET) +#define SAM_HSMCI0_CSTOR (SAM_HSMCI0_BASE+SAM_HSMCI_CSTOR_OFFSET) +#define SAM_HSMCI0_RSPR0 (SAM_HSMCI0_BASE+SAM_HSMCI_RSPR0_OFFSET) +#define SAM_HSMCI0_RSPR1 (SAM_HSMCI0_BASE+SAM_HSMCI_RSPR1_OFFSET) +#define SAM_HSMCI0_RSPR2 (SAM_HSMCI0_BASE+SAM_HSMCI_RSPR2_OFFSET) +#define SAM_HSMCI0_RSPR3 (SAM_HSMCI0_BASE+SAM_HSMCI_RSPR3_OFFSET) +#define SAM_HSMCI0_RDR (SAM_HSMCI0_BASE+SAM_HSMCI_RDR_OFFSET) +#define SAM_HSMCI0_TDR (SAM_HSMCI0_BASE+SAM_HSMCI_TDR_OFFSET) +#define SAM_HSMCI0_SR (SAM_HSMCI0_BASE+SAM_HSMCI_SR_OFFSET) +#define SAM_HSMCI0_IER (SAM_HSMCI0_BASE+SAM_HSMCI_IER_OFFSET) +#define SAM_HSMCI0_IDR (SAM_HSMCI0_BASE+SAM_HSMCI_IDR_OFFSET) +#define SAM_HSMCI0_IMR (SAM_HSMCI0_BASE+SAM_HSMCI_IMR_OFFSET) +#define SAM_HSMCI0_DMA (SAM_HSMCI0_BASE+SAM_HSMCI_DMA_OFFSET) +#define SAM_HSMCI0_CFG (SAM_HSMCI0_BASE+SAM_HSMCI_CFG_OFFSET) +#define SAM_HSMCI0_WPMR (SAM_HSMCI0_BASE+SAM_HSMCI_WPMR_OFFSET) +#define SAM_HSMCI0_WPSR (SAM_HSMCI0_BASE+SAM_HSMCI_WPSR_OFFSET) +#define SAM_HSMCI0_FIFO (SAM_HSMCI0_BASE+SAM_HSMCI_FIFO_OFFSET) + +#if SAMV7_NHSMCI4 > 1 +# define SAM_HSMCI1_CR (SAM_HSMCI1_BASE+SAM_HSMCI_CR_OFFSET) +# define SAM_HSMCI1_MR (SAM_HSMCI1_BASE+SAM_HSMCI_MR_OFFSET) +# define SAM_HSMCI1_DTOR (SAM_HSMCI1_BASE+SAM_HSMCI_DTOR_OFFSET) +# define SAM_HSMCI1_SDCR (SAM_HSMCI1_BASE+SAM_HSMCI_SDCR_OFFSET) +# define SAM_HSMCI1_ARGR (SAM_HSMCI1_BASE+SAM_HSMCI_ARGR_OFFSET) +# define SAM_HSMCI1_CMDR (SAM_HSMCI1_BASE+SAM_HSMCI_CMDR_OFFSET) +# define SAM_HSMCI1_BLKR (SAM_HSMCI1_BASE+SAM_HSMCI_BLKR_OFFSET) +# define SAM_HSMCI1_CSTOR (SAM_HSMCI1_BASE+SAM_HSMCI_CSTOR_OFFSET) +# define SAM_HSMCI1_RSPR0 (SAM_HSMCI1_BASE+SAM_HSMCI_RSPR0_OFFSET) +# define SAM_HSMCI1_RSPR1 (SAM_HSMCI1_BASE+SAM_HSMCI_RSPR1_OFFSET) +# define SAM_HSMCI1_RSPR2 (SAM_HSMCI1_BASE+SAM_HSMCI_RSPR2_OFFSET) +# define SAM_HSMCI1_RSPR3 (SAM_HSMCI1_BASE+SAM_HSMCI_RSPR3_OFFSET) +# define SAM_HSMCI1_RDR (SAM_HSMCI1_BASE+SAM_HSMCI_RDR_OFFSET) +# define SAM_HSMCI1_TDR (SAM_HSMCI1_BASE+SAM_HSMCI_TDR_OFFSET) +# define SAM_HSMCI1_SR (SAM_HSMCI1_BASE+SAM_HSMCI_SR_OFFSET) +# define SAM_HSMCI1_IER (SAM_HSMCI1_BASE+SAM_HSMCI_IER_OFFSET) +# define SAM_HSMCI1_IDR (SAM_HSMCI1_BASE+SAM_HSMCI_IDR_OFFSET) +# define SAM_HSMCI1_IMR (SAM_HSMCI1_BASE+SAM_HSMCI_IMR_OFFSET) +# define SAM_HSMCI1_DMA (SAM_HSMCI1_BASE+SAM_HSMCI_DMA_OFFSET) +# define SAM_HSMCI1_CFG (SAM_HSMCI1_BASE+SAM_HSMCI_CFG_OFFSET) +# define SAM_HSMCI1_WPMR (SAM_HSMCI1_BASE+SAM_HSMCI_WPMR_OFFSET) +# define SAM_HSMCI1_WPSR (SAM_HSMCI1_BASE+SAM_HSMCI_WPSR_OFFSET) +# define SAM_HSMCI1_FIFO (SAM_HSMCI1_BASE+SAM_HSMCI_FIFO_OFFSET) +#endif + +#if SAMV7_NHSMCI4 > 2 +# define SAM_HSMCI2_CR (SAM_HSMCI2_BASE+SAM_HSMCI_CR_OFFSET) +# define SAM_HSMCI2_MR (SAM_HSMCI2_BASE+SAM_HSMCI_MR_OFFSET) +# define SAM_HSMCI2_DTOR (SAM_HSMCI2_BASE+SAM_HSMCI_DTOR_OFFSET) +# define SAM_HSMCI2_SDCR (SAM_HSMCI2_BASE+SAM_HSMCI_SDCR_OFFSET) +# define SAM_HSMCI2_ARGR (SAM_HSMCI2_BASE+SAM_HSMCI_ARGR_OFFSET) +# define SAM_HSMCI2_CMDR (SAM_HSMCI2_BASE+SAM_HSMCI_CMDR_OFFSET) +# define SAM_HSMCI2_BLKR (SAM_HSMCI2_BASE+SAM_HSMCI_BLKR_OFFSET) +# define SAM_HSMCI2_CSTOR (SAM_HSMCI2_BASE+SAM_HSMCI_CSTOR_OFFSET) +# define SAM_HSMCI2_RSPR0 (SAM_HSMCI2_BASE+SAM_HSMCI_RSPR0_OFFSET) +# define SAM_HSMCI2_RSPR1 (SAM_HSMCI2_BASE+SAM_HSMCI_RSPR1_OFFSET) +# define SAM_HSMCI2_RSPR2 (SAM_HSMCI2_BASE+SAM_HSMCI_RSPR2_OFFSET) +# define SAM_HSMCI2_RSPR3 (SAM_HSMCI2_BASE+SAM_HSMCI_RSPR3_OFFSET) +# define SAM_HSMCI2_RDR (SAM_HSMCI2_BASE+SAM_HSMCI_RDR_OFFSET) +# define SAM_HSMCI2_TDR (SAM_HSMCI2_BASE+SAM_HSMCI_TDR_OFFSET) +# define SAM_HSMCI2_SR (SAM_HSMCI2_BASE+SAM_HSMCI_SR_OFFSET) +# define SAM_HSMCI2_IER (SAM_HSMCI2_BASE+SAM_HSMCI_IER_OFFSET) +# define SAM_HSMCI2_IDR (SAM_HSMCI2_BASE+SAM_HSMCI_IDR_OFFSET) +# define SAM_HSMCI2_IMR (SAM_HSMCI2_BASE+SAM_HSMCI_IMR_OFFSET) +# define SAM_HSMCI2_DMA (SAM_HSMCI2_BASE+SAM_HSMCI_DMA_OFFSET) +# define SAM_HSMCI2_CFG (SAM_HSMCI2_BASE+SAM_HSMCI_CFG_OFFSET) +# define SAM_HSMCI2_WPMR (SAM_HSMCI2_BASE+SAM_HSMCI_WPMR_OFFSET) +# define SAM_HSMCI2_WPSR (SAM_HSMCI2_BASE+SAM_HSMCI_WPSR_OFFSET) +# define SAM_HSMCI2_FIFO (SAM_HSMCI2_BASE+SAM_HSMCI_FIFO_OFFSET) +#endif + +/* HSMCI register bit definitions *******************************************************/ + +/* HSMCI Control Register */ + +#define HSMCI_CR_MCIEN (1 << 0) /* Bit 0: Multi-Media Interface Enable */ +#define HSMCI_CR_MCIDIS (1 << 1) /* Bit 1: Multi-Media Interface Disable */ +#define HSMCI_CR_PWSEN (1 << 2) /* Bit 2: Power Save Mode Enable */ +#define HSMCI_CR_PWSDIS (1 << 3) /* Bit 3: Power Save Mode Disable */ +#define HSMCI_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ + +/* HSMCI Mode Register */ + +#define HSMCI_MR_CLKDIV_SHIFT (0) /* Bits 0-7: Clock Divider */ +#define HSMCI_MR_CLKDIV_MASK (0xff << HSMCI_MR_CLKDIV_SHIFT) +# define HSMCI_MR_CLKDIV(n) ((uint32_t)(n) << HSMCI_MR_CLKDIV_SHIFT) +#define HSMCI_MR_PWSDIV_SHIFT (8) /* Bits 8-10: Power Saving Divider */ +#define HSMCI_MR_PWSDIV_MASK (7 << HSMCI_MR_PWSDIV_SHIFT) +# define HSMCI_MR_PWSDIV_MAX (7 << HSMCI_MR_PWSDIV_SHIFT) +#define HSMCI_MR_RDPROOF (1 << 11) /* Bit 11: Read Proof Enable */ +#define HSMCI_MR_WRPROOF (1 << 12) /* Bit 12: Write Proof Enable */ +#define HSMCI_MR_FBYTE (1 << 13) /* Bit 13: Force Byte Transfer */ +#define HSMCI_MR_PADV (1 << 14) /* Bit 14: Padding Value */ +#define HSMCI_MR_CLKODD (1 << 16) /* Bit 15: Clock divider is odd */ + +/* HSMCI Data Timeout Register */ + +#define HSMCI_DTOR_DTOCYC_SHIFT (0) /* Bits 0-3: Data Timeout Cycle Number */ +#define HSMCI_DTOR_DTOCYC_MASK (15 << HSMCI_DTOR_DTOCYC_SHIFT) +# define HSMCI_DTOR_DTOCYC_MAX (15 << HSMCI_DTOR_DTOCYC_SHIFT) +#define HSMCI_DTOR_DTOMUL_SHIFT (4) /* Bits 4-6: Data Timeout Multiplier */ +#define HSMCI_DTOR_DTOMUL_MASK (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1 (0 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_16 (1 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_128 (2 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_256 (3 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1024 (4 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_4096 (5 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_65536 (6 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_1048576 (7 << HSMCI_DTOR_DTOMUL_SHIFT) +# define HSMCI_DTOR_DTOMUL_MAX (7 << HSMCI_DTOR_DTOMUL_SHIFT) + +/* HSMCI SDCard/SDIO Register */ + +#define HSMCI_SDCR_SDCSEL_SHIFT (0) /* Bits 0-1: SDCard/SDIO Slot */ +#define HSMCI_SDCR_SDCSEL_MASK (3 << HSMCI_SDCR_SDCSEL_SHIFT) /* Slot A is selected */ +# define HSMCI_SDCR_SDCSEL_SLOTA (0 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTB (1 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTC (2 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +# define HSMCI_SDCR_SDCSEL_SLOTD (3 << HSMCI_SDCR_SDCSEL_SHIFT) /* Reserved */ +#define HSMCI_SDCR_SDCBUS_SHIFT (6) /* Bits 6-7: SDCard/SDIO Bus Width */ +#define HSMCI_SDCR_SDCBUS_MASK (3 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_1BIT (0 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_4BIT (2 << HSMCI_SDCR_SDCBUS_SHIFT) +# define HSMCI_SDCR_SDCBUS_8BIT (3 << HSMCI_SDCR_SDCBUS_SHIFT) + +/* HSMCI Argument Register (32-bit value) */ + +/* HSMCI Command Register */ + +#define HSMCI_CMDR_CMDNB_SHIFT (0) /* Bits 0-5: Command Number */ +#define HSMCI_CMDR_CMDNB_MASK (63 << HSMCI_CMDR_CMDNB_SHIFT) +#define HSMCI_CMDR_RSPTYP_SHIFT (6) /* Bits 6-7: Response Type */ +#define HSMCI_CMDR_RSPTYP_MASK (3 << HSMCI_CMDR_RSPTYP_SHIFT) +# define HSMCI_CMDR_RSPTYP_NONE (0 << HSMCI_CMDR_RSPTYP_SHIFT) /* No response */ +# define HSMCI_CMDR_RSPTYP_48BIT (1 << HSMCI_CMDR_RSPTYP_SHIFT) /* 48-bit response */ +# define HSMCI_CMDR_RSPTYP_136BIT (2 << HSMCI_CMDR_RSPTYP_SHIFT) /* 136-bit response */ +# define HSMCI_CMDR_RSPTYP_R1B (3 << HSMCI_CMDR_RSPTYP_SHIFT) /* R1b response type */ +#define HSMCI_CMDR_SPCMD_SHIFT (8) /* Bits 8-10: Special Command */ +#define HSMCI_CMDR_SPCMD_MASK (7 << HSMCI_CMDR_SPCMD_SHIFT) +# define HSMCI_CMDR_SPCMD_STD (0 << HSMCI_CMDR_SPCMD_SHIFT) /* Not a special CMD */ +# define HSMCI_CMDR_SPCMD_INIT (1 << HSMCI_CMDR_SPCMD_SHIFT) /* Initialization CMD */ +# define HSMCI_CMDR_SPCMD_SYNC (2 << HSMCI_CMDR_SPCMD_SHIFT) /* Synchronized CMD */ +# define HSMCI_CMDR_SPCMD_CEATA (3 << HSMCI_CMDR_SPCMD_SHIFT) /* CE-ATA Completion Signal disable CMD */ +# define HSMCI_CMDR_SPCMD_ITCMD (4 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt command */ +# define HSMCI_CMDR_SPCMD_ITRESP (5 << HSMCI_CMDR_SPCMD_SHIFT) /* Interrupt response */ +# define HSMCI_CMDR_SPCMD_BOR (6 << HSMCI_CMDR_SPCMD_SHIFT) /* Boot Operation Request */ +# define HSMCI_CMDR_SPCMD_EBO (7 << HSMCI_CMDR_SPCMD_SHIFT) /* End Boot Operation */ +#define HSMCI_CMDR_OPDCMD (1 << 11) /* Bit 11: Open Drain Command */ +#define HSMCI_CMDR_MAXLAT (1 << 12) /* Bit 12: Max Latency for Command to Response */ +#define HSMCI_CMDR_TRCMD_SHIFT (16) /* Bits 16-17: Transfer Command */ +#define HSMCI_CMDR_TRCMD_MASK (3 << HSMCI_CMDR_TRCMD_SHIFT) +# define HSMCI_CMDR_TRCMD_NONE (0 << HSMCI_CMDR_TRCMD_SHIFT) /* No data transfer */ +# define HSMCI_CMDR_TRCMD_START (1 << HSMCI_CMDR_TRCMD_SHIFT) /* Start data transfer */ +# define HSMCI_CMDR_TRCMD_STOP (2 << HSMCI_CMDR_TRCMD_SHIFT) /* Stop data transfer */ +#define HSMCI_CMDR_TRDIR (1 << 18) /* Bit 18: Transfer Direction */ +# define HSMCI_CMDR_TRDIR_WRITE (0 << 18) +# define HSMCI_CMDR_TRDIR_READ (1 << 18) +#define HSMCI_CMDR_TRTYP_SHIFT (19) /* Bits 19-21: Transfer Type */ +#define HSMCI_CMDR_TRTYP_MASK (7 << HSMCI_CMDR_TRTYP_SHIFT) +# define HSMCI_CMDR_TRTYP_SINGLE (0 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Single Block */ +# define HSMCI_CMDR_TRTYP_MULTIPLE (1 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC/SDCard Multiple Block */ +# define HSMCI_CMDR_TRTYP_STREAM (2 << HSMCI_CMDR_TRTYP_SHIFT) /* MMC Stream */ +# define HSMCI_CMDR_TRTYP_SDIOBYTE (4 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Byte */ +# define HSMCI_CMDR_TRTYP_SDIOBLK (5 << HSMCI_CMDR_TRTYP_SHIFT) /* SDIO Block */ +#define HSMCI_CMDR_IOSPCMD_SHIFT (24) /* Bits 24-25: SDIO Special Command */ +#define HSMCI_CMDR_IOSPCMD_MASK (3 << HSMCI_CMDR_IOSPCMD_SHIFT) +# define HSMCI_CMDR_IOSPCMD_STD (0 << HSMCI_CMDR_IOSPCMD_SHIFT) /* Not an SDIO Special Command */ +# define HSMCI_CMDR_IOSPCMD_SUSPEND (1 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Suspend Command */ +# define HSMCI_CMDR_IOSPCMD_RESUME (2 << HSMCI_CMDR_IOSPCMD_SHIFT) /* SDIO Resume Command */ +#define HSMCI_CMDR_ATACS (1 << 26) /* Bit 26: ATA with Command Completion Signal */ +#define HSMCI_CMDR_BOOTACK (1 << 27) /* Bit 27: Boot Operation Acknowledge */ + +/* HSMCI Block Register */ + +#define HSMCI_BLKR_BCNT_SHIFT (0) /* Bits 0-15: MMC/SDIO Block Count - SDIO Byte Count */ +#define HSMCI_BLKR_BCNT_MASK (0xffff << HSMCI_BLKR_BCNT_SHIFT) +# define HSMCI_BLKR_BCNT(n) ((uint32_t)(n) << HSMCI_BLKR_BCNT_SHIFT) +#define HSMCI_BLKR_BLKLEN_SHIFT (16) /* Bits 16-31: Data Block Length */ +#define HSMCI_BLKR_BLKLEN_MASK (0xffff << HSMCI_BLKR_BLKLEN_SHIFT) +# define HSMCI_BLKR_BLKLEN(n) ((uint32_t)(n) << HSMCI_BLKR_BLKLEN_SHIFT) + +/* HSMCI Completion Signal Timeout Register */ + +#define HSMCI_CSTOR_CSTOCYC_SHIFT (0) /* Bits 0-3: Completion Signal Timeout Cycle Number */ +#define HSMCI_CSTOR_CSTOCYC_MASK (15 << HSMCI_CSTOR_CSTOCYC_SHIFT) +# define HSMCI_CSTOR_CSTOCYC(n) ((uint32_t)(n) << HSMCI_CSTOR_CSTOCYC_SHIFT) +#define HSMCI_CSTOR_CSTOMUL_SHIFT (4) /* Bits 4-6: Completion Signal Timeout Multiplier */ +#define HSMCI_CSTOR_CSTOMUL_MASK (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1 (0 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_16 (1 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_128 (2 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_256 (3 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1024 (4 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_4096 (5 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_65536 (6 << HSMCI_CSTOR_CSTOMUL_SHIFT) +# define HSMCI_CSTOR_CSTOMUL_1048576 (7 << HSMCI_CSTOR_CSTOMUL_SHIFT) + +/* HSMCI Response Registers (32-bit data) */ +/* HSMCI Receive Data Registers (32-bit data) */ +/* HSMCI Transmit Data Registers (32-bit data) */ + +/* HSMCI Status Register, HSMCI Interrupt Enable Register, HSMCI Interrupt Disable + * Register, and HSMCI Interrupt Mask Register common bit-field definitions + */ + +#define HSMCI_INT_CMDRDY (1 << 0) /* Bit 0: Command Ready */ +#define HSMCI_INT_RXRDY (1 << 1) /* Bit 1: Receiver Ready */ +#define HSMCI_INT_TXRDY (1 << 2) /* Bit 2: Transmit Ready */ +#define HSMCI_INT_BLKE (1 << 3) /* Bit 3: Data Block Ended */ +#define HSMCI_INT_DTIP (1 << 4) /* Bit 4: Data Transfer in Progress */ +#define HSMCI_INT_NOTBUSY (1 << 5) /* Bit 6: HSMCI Not Busy */ +#define HSMCI_INT_SDIOIRQA (1 << 8) /* Bit 8: SDIO Interrupt for Slot A */ +#define HSMCI_INT_SDIOWAIT (1 << 12) /* Bit 12: SDIO Read Wait Operation Status */ +#define HSMCI_INT_CSRCV (1 << 13) /* Bit 13: CE-ATA Completion Signal Received */ +#define HSMCI_INT_RINDE (1 << 16) /* Bit 16: Response Index Error */ +#define HSMCI_INT_RDIRE (1 << 17) /* Bit 17: Response Direction Error */ +#define HSMCI_INT_RCRCE (1 << 18) /* Bit 18: Response CRC Error */ +#define HSMCI_INT_RENDE (1 << 19) /* Bit 19: Response End Bit Error */ +#define HSMCI_INT_RTOE (1 << 20) /* Bit 20: Response Time-out */ +#define HSMCI_INT_DCRCE (1 << 21) /* Bit 21: Data CRC Error */ +#define HSMCI_INT_DTOE (1 << 22) /* Bit 22: Data Time-out Error */ +#define HSMCI_INT_CSTOE (1 << 23) /* Bit 23: Completion Signal Time-out Error */ +#define HSMCI_INT_BLKOVRE (1 << 24) /* Bit 24: DMA Block Overrun Error */ +#define HSMCI_INT_FIFOEMPTY (1 << 26) /* Bit 26: FIFO empty flag */ +#define HSMCI_INT_XFRDONE (1 << 27) /* Bit 27: Transfer Done flag */ +#define HSMCI_INT_ACKRCV (1 << 28) /* Bit 28: Boot Operation Acknowledge Received */ +#define HSMCI_INT_ACKRCVE (1 << 29) /* Bit 29: Boot Operation Acknowledge Error */ +#define HSMCI_INT_OVRE (1 << 30) /* Bit 30: Overrun */ +#define HSMCI_INT_UNRE (1 << 31) /* Bit 31: Underrun */ + +/* HSMCI DMA Configuration Register */ + +#define HSMCI_DMA_CHKSIZE_SHIFT (4) /* Bits 4-6: DMA Channel Read and Write Chunk Size */ +#define HSMCI_DMA_CHKSIZE_MASK (7 << HSMCI_DMA_CHKSIZE_SHIFT) +# define HSMCI_DMA_CHKSIZE_1 (0 << HSMCI_DMA_CHKSIZE_SHIFT) /* 1 data available */ +# define HSMCI_DMA_CHKSIZE_4 (1 << HSMCI_DMA_CHKSIZE_SHIFT) /* 4 data available */ +# define HSMCI_DMA_CHKSIZE_8 (2 << HSMCI_DMA_CHKSIZE_SHIFT) /* 8 data available */ +# define HSMCI_DMA_CHKSIZE_16 (3 << HSMCI_DMA_CHKSIZE_SHIFT) /* 16 data available */ +# define HSMCI_DMA_CHKSIZE_32 (4 << HSMCI_DMA_CHKSIZE_SHIFT) /* 32 data available */ +#define HSMCI_DMA_DMAEN (1 << 8) /* Bit 8: DMA Hardware Handshaking Enable */ + +/* HSMCI Configuration Register */ + +#define HSMCI_CFG_FIFOMODE (1 << 0) /* Bit 0: HSMCI Internal FIFO control mode */ +#define HSMCI_CFG_FERRCTRL (1 << 4) /* Bit 4: Flow Error flag reset control mode */ +#define HSMCI_CFG_HSMODE (1 << 8) /* Bit 8: High Speed Mode */ +#define HSMCI_CFG_LSYNC (1 << 12) /* Bit 12: Synchronize on the last block */ + +/* HSMCI Write Protect Mode Register */ + +#define HSMCI_WPMR_WPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define HSMCI_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection Key password */ +#define HSMCI_WPMR_WPKEY_MASK (0x00ffffff << HSMCI_WPMR_WPKEY_SHIFT) +# define HSMCI_WPMR_WPKEY (0x004d4349 << HSMCI_WPMR_WPKEY_SHIFT) + +/* HSMCI Write Protect Status Register */ + +#define HSMCI_WPSR_WPVS (1 << 0) /* Bit 0: Write Protection Violation Status */ +#define HSMCI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define HSMCI_WPSR_WPVSRC_MASK (0xffff << HSMCI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* SAMV7_NHSMCI4 > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_HSMCI_H */ diff --git a/arch/arm/src/samv7/chip/sam_matrix.h b/arch/arm/src/samv7/chip/sam_matrix.h new file mode 100644 index 0000000000000000000000000000000000000000..e399ef3cc120522ef7b6628fef3f87ca127e83f6 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_matrix.h @@ -0,0 +1,335 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_matrix.h + * Bux matrix definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MATRIX_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MATRIX_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* MATRIX register offsets **************************************************************/ + +#define SAM_MATRIX_MCFG_OFFSET(n) ((n)<<2) +# define SAM_MATRIX_MCFG0_OFFSET 0x0000 /* Master Configuration Register 0 */ +# define SAM_MATRIX_MCFG1_OFFSET 0x0004 /* Master Configuration Register 1 */ +# define SAM_MATRIX_MCFG2_OFFSET 0x0008 /* Master Configuration Register 2 */ +# define SAM_MATRIX_MCFG3_OFFSET 0x000c /* Master Configuration Register 3 */ +# define SAM_MATRIX_MCFG4_OFFSET 0x0010 /* Master Configuration Register 4 */ +# define SAM_MATRIX_MCFG5_OFFSET 0x0014 /* Master Configuration Register 5 */ +# define SAM_MATRIX_MCFG6_OFFSET 0x0018 /* Master Configuration Register 6 */ +# define SAM_MATRIX_MCFG7_OFFSET 0x001c /* Master Configuration Register 7 */ +# define SAM_MATRIX_MCFG8_OFFSET 0x0020 /* Master Configuration Register 8 */ +# define SAM_MATRIX_MCFG9_OFFSET 0x0024 /* Master Configuration Register 9 */ +# define SAM_MATRIX_MCFG10_OFFSET 0x0028 /* Master Configuration Register 10 */ +# define SAM_MATRIX_MCFG11_OFFSET 0x002c /* Master Configuration Register 11 */ + /* 0x0030-0x003c: Reserved */ +#define SAM_MATRIX_SCFG_OFFSET(n) (0x0040+((n)<<2)) +# define SAM_MATRIX_SCFG0_OFFSET 0x0040 /* Slave Configuration Register 0 */ +# define SAM_MATRIX_SCFG1_OFFSET 0x0044 /* Slave Configuration Register 1 */ +# define SAM_MATRIX_SCFG2_OFFSET 0x0048 /* Slave Configuration Register 2 */ +# define SAM_MATRIX_SCFG3_OFFSET 0x004c /* Slave Configuration Register 3 */ +# define SAM_MATRIX_SCFG4_OFFSET 0x0050 /* Slave Configuration Register 4 */ +# define SAM_MATRIX_SCFG5_OFFSET 0x0054 /* Slave Configuration Register 5 */ +# define SAM_MATRIX_SCFG6_OFFSET 0x0058 /* Slave Configuration Register 6 */ +# define SAM_MATRIX_SCFG7_OFFSET 0x005c /* Slave Configuration Register 7 */ +# define SAM_MATRIX_SCFG8_OFFSET 0x0060 /* Slave Configuration Register 8 */ + /* 0x0064-0x007c: Reserved */ +#define SAM_MATRIX_PRAS_OFFSET(n) (0x0080+((n)<<3)) +# define SAM_MATRIX_PRAS0_OFFSET 0x0080 /* Priority Register A for Slave 0 */ +# define SAM_MATRIX_PRAS1_OFFSET 0x0088 /* Priority Register A for Slave 1 */ +# define SAM_MATRIX_PRAS2_OFFSET 0x0090 /* Priority Register A for Slave 2 */ +# define SAM_MATRIX_PRAS3_OFFSET 0x0098 /* Priority Register A for Slave 3 */ +# define SAM_MATRIX_PRAS4_OFFSET 0x00a0 /* Priority Register A for Slave 4 */ +# define SAM_MATRIX_PRAS5_OFFSET 0x00a8 /* Priority Register A for Slave 5 */ +# define SAM_MATRIX_PRAS6_OFFSET 0x00b0 /* Priority Register A for Slave 6 */ +# define SAM_MATRIX_PRAS7_OFFSET 0x00b8 /* Priority Register A for Slave 7 */ +# define SAM_MATRIX_PRAS8_OFFSET 0x00c0 /* Priority Register A for Slave 8 */ + +#define SAM_MATRIX_PRBS_OFFSET(n) (0x0084+((n)<<3)) +# define SAM_MATRIX_PRBS0_OFFSET 0x0084 /* Priority Register B for Slave 0 */ +# define SAM_MATRIX_PRBS1_OFFSET 0x008c /* Priority Register B for Slave 1 */ +# define SAM_MATRIX_PRBS2_OFFSET 0x0094 /* Priority Register B for Slave 2 */ +# define SAM_MATRIX_PRBS3_OFFSET 0x009c /* Priority Register B for Slave 3 */ +# define SAM_MATRIX_PRBS4_OFFSET 0x00a4 /* Priority Register B for Slave 4 */ +# define SAM_MATRIX_PRBS5_OFFSET 0x00ac /* Priority Register B for Slave 5 */ +# define SAM_MATRIX_PRBS6_OFFSET 0x00b4 /* Priority Register B for Slave 6 */ +# define SAM_MATRIX_PRBS7_OFFSET 0x00bc /* Priority Register B for Slave 7 */ +# define SAM_MATRIX_PRBS8_OFFSET 0x00c4 /* Priority Register B for Slave 8 */ + /* 0x006c8-0x00fc: Reserved */ +#define SAM_MATRIX_MRCR_OFFSET 0x0100 /* Master Remap Control Register */ + /* 0x0104-0x010c: Reserved */ +#define SAM_MATRIX_CAN0_OFFSET 0x0100 /* Master Remap Control Register */ +#define SAM_MATRIX_CCFG_SYSIO_OFFSET 0x0114 /* System I/O Configuration Register */ + /* 0x0118-0x0120: Reserved */ +#define SAM_MATRIX_CCFG_SMCNFCS_OFFSET 0x0124 /* SMC Chip Select NAND Flash Assignment Register */ + /* 0x0128-0x01e0: Reserved */ +#define SAM_MATRIX_WPMR_OFFSET 0x01e4 /* Write Protect Mode Register */ +#define SAM_MATRIX_WPSR_OFFSET 0x01e8 /* Write Protect Status Register */ + /* 0x0110-0x01fc: Reserved */ + +/* MATRIX register addresses ************************************************************/ + +#define SAM_MATRIX_MCFG(n)) (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n)) +# define SAM_MATRIX_MCFG0 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG0_OFFSET) +# define SAM_MATRIX_MCFG1 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG1_OFFSET) +# define SAM_MATRIX_MCFG2 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG2_OFFSET) +# define SAM_MATRIX_MCFG3 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG3_OFFSET) +# define SAM_MATRIX_MCFG4 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG4_OFFSET) +# define SAM_MATRIX_MCFG5 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG5_OFFSET) +# define SAM_MATRIX_MCFG6 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG6_OFFSET) +# define SAM_MATRIX_MCFG7 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG7_OFFSET) +# define SAM_MATRIX_MCFG8 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG8_OFFSET) +# define SAM_MATRIX_MCFG9 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG9_OFFSET) +# define SAM_MATRIX_MCFG10 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG10_OFFSET) +# define SAM_MATRIX_MCFG11 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG11_OFFSET) + +#define SAM_MATRIX_SCFG(n) (SAM_MATRIX_BASE+SAM_MATRIX_SCFG_OFFSET(n)) +# define SAM_MATRIX_SCFG0 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG0_OFFSET) +# define SAM_MATRIX_SCFG1 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG1_OFFSET) +# define SAM_MATRIX_SCFG2 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG2_OFFSET) +# define SAM_MATRIX_SCFG3 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG3_OFFSET) +# define SAM_MATRIX_SCFG4 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG4_OFFSET) +# define SAM_MATRIX_SCFG5 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG5_OFFSET) +# define SAM_MATRIX_SCFG6 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG6_OFFSET) +# define SAM_MATRIX_SCFG7 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG7_OFFSET) +# define SAM_MATRIX_SCFG8 (SAM_MATRIX_BASE+SAM_MATRIX_SCFG8_OFFSET) + +#define SAM_MATRIX_PRAS(n) (SAM_MATRIX_BASE+SAM_MATRIX_PRAS_OFFSET(n)) +# define SAM_MATRIX_PRAS0 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS0_OFFSET) +# define SAM_MATRIX_PRAS1 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS1_OFFSET) +# define SAM_MATRIX_PRAS2 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS2_OFFSET) +# define SAM_MATRIX_PRAS3 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS3_OFFSET) +# define SAM_MATRIX_PRAS4 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS4_OFFSET) +# define SAM_MATRIX_PRAS5 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS5_OFFSET) +# define SAM_MATRIX_PRAS6 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS6_OFFSET) +# define SAM_MATRIX_PRAS7 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS7_OFFSET) +# define SAM_MATRIX_PRAS8 (SAM_MATRIX_BASE+SAM_MATRIX_PRAS8_OFFSET) + +#define SAM_MATRIX_PRBS(n) (SAM_MATRIX_BASE+SAM_MATRIX_PRBS_OFFSET(n)) +# define SAM_MATRIX_PRBS0 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS0_OFFSET) +# define SAM_MATRIX_PRBS1 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS1_OFFSET) +# define SAM_MATRIX_PRBS2 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS2_OFFSET) +# define SAM_MATRIX_PRBS3 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS3_OFFSET) +# define SAM_MATRIX_PRBS4 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS4_OFFSET) +# define SAM_MATRIX_PRBS5 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS5_OFFSET) +# define SAM_MATRIX_PRBS6 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS6_OFFSET) +# define SAM_MATRIX_PRBS7 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS7_OFFSET) +# define SAM_MATRIX_PRBS8 (SAM_MATRIX_BASE+SAM_MATRIX_PRBS8_OFFSET) + +#define SAM_MATRIX_MRCR (SAM_MATRIX_BASE+SAM_MATRIX_MRCR_OFFSET) +#define SAM_MATRIX_CAN0 (SAM_MATRIX_BASE+SAM_MATRIX_CAN0_OFFSET) +#define SAM_MATRIX_CCFG_SYSIO (SAM_MATRIX_BASE+SAM_MATRIX_CCFG_SYSIO_OFFSET) +#define SAM_MATRIX_CCFG_SMCNFCS (SAM_MATRIX_BASE+SAM_MATRIX_CCFG_SMCNFCS_OFFSET) +#define SAM_MATRIX_WPMR (SAM_MATRIX_BASE+SAM_MATRIX_WPMR_OFFSET) +#define SAM_MATRIX_WPSR (SAM_MATRIX_BASE+SAM_MATRIX_WPSR_OFFSET) + +/* MATRIX register bit definitions ******************************************************/ +/* Master Configuration Registers */ + +#define MATRIX_MCFG_ULBT_SHIFT (0) /* Bits 0-2: Undefined Length Burst Type */ +#define MATRIX_MCFG_ULBT_MASK (7 << MATRIX_MCFG_ULBT_SHIFT) +# define MATRIX_MCFG_ULBT_INF (0 << MATRIX_MCFG_ULBT_SHIFT) /* Infinite Length Burst */ +# define MATRIX_MCFG_ULBT_SINGLE (1 << MATRIX_MCFG_ULBT_SHIFT) /* Single Access */ +# define MATRIX_MCFG_ULBT_4BEAT (2 << MATRIX_MCFG_ULBT_SHIFT) /* 4-beat Burst */ +# define MATRIX_MCFG_ULBT_8BEAT (3 << MATRIX_MCFG_ULBT_SHIFT) /* 8-beat Burst */ +# define MATRIX_MCFG_ULBT_16BEAT (4 << MATRIX_MCFG_ULBT_SHIFT) /* 16-beat Burst */ +# define MATRIX_MCFG_ULBT_32BEAT (5 << MATRIX_MCFG_ULBT_SHIFT) /* 32-beat Burst */ +# define MATRIX_MCFG_ULBT_64BEAT (6 << MATRIX_MCFG_ULBT_SHIFT) /* 64-beat Burst */ +# define MATRIX_MCFG_ULBT_128BEAT (7 << MATRIX_MCFG_ULBT_SHIFT) /* 128-beat Burst */ + +/* Bus Matrix Slave Configuration Registers */ + +#define MATRIX_SCFG_SLOTCYCLE_SHIFT (0) /* Bits 0-8: Maximum Number of Allowed Cycles for a Burst */ +#define MATRIX_SCFG_SLOTCYCLE_MASK (0x1ff << MATRIX_SCFG_SLOTCYCLE_SHIFT) +# define MATRIX_SCFG_SLOTCYCLE(n) ((uint32_t)(n) << MATRIX_SCFG_SLOTCYCLE_SHIFT) +#define MATRIX_SCFG_DEFMSTRTYPE_SHIFT (16) /* Bits 16-17: Default Master Type */ +#define MATRIX_SCFG_DEFMSTRTYPE_MASK (3 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_NONE (0 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_LAST (1 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define MATRIX_SCFG_DEFMSTRTYPE_FIXED (2 << MATRIX_SCFG_DEFMSTRTYPE_SHIFT) +#define MATRIX_SCFG_FIXEDDEFMSTR_SHIFT (18) /* Bits 18-21: Fixed Default Master */ +#define MATRIX_SCFG_FIXEDDEFMSTR_MASK (15 << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +# define MATRIX_SCFG0_FIXEDDEFMSTR(n) ((uint32_t)(n) << MATRIX_SCFG_FIXEDDEFMSTR_SHIFT) + +/* Bus Matrix Priority Registers A For Slaves */ + +#define MATRIX_PRAS_MPR_SHIFT(x) ((n)<<2) /* n=0-7 */ +#define MATRIX_PRAS_MPR_MASK(x) (3 << MATRIX_PRAS_MPR_SHIFT(x)) +# define MATRIX_PRAS_M0PR_SHIFT (0) /* Bits 0-1: Master 0 Priority */ +# define MATRIX_PRAS_M0PR_MASK (3 << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M0PR(n) ((uint32_t)(n) << MATRIX_PRAS_M0PR_SHIFT) +# define MATRIX_PRAS_M1PR_SHIFT (4) /* Bits 4-5: Master 1 Priority */ +# define MATRIX_PRAS_M1PR_MASK (3 << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M1PR(n) ((uint32_t)(n) << MATRIX_PRAS_M1PR_SHIFT) +# define MATRIX_PRAS_M2PR_SHIFT (8) /* Bits 8-9: Master 2 Priority */ +# define MATRIX_PRAS_M2PR_MASK (3 << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M2PR(n) ((uint32_t)(n) << MATRIX_PRAS_M2PR_SHIFT) +# define MATRIX_PRAS_M3PR_SHIFT (12) /* Bits 12-13: Master 3 Priority */ +# define MATRIX_PRAS_M3PR_MASK (3 << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M3PR(n) ((uint32_t)(n) << MATRIX_PRAS_M3PR_SHIFT) +# define MATRIX_PRAS_M4PR_SHIFT (16) /* Bits 16-17: Master 4 Priority */ +# define MATRIX_PRAS_M4PR_MASK (3 << MATRIX_PRAS_M4PR_SHIFT) +# define MATRIX_PRAS_M4PR(n) ((uint32_t)(n) << MATRIX_PRAS_M4PR_SHIFT) +# define MATRIX_PRAS_M5PR_SHIFT (20) /* Bits 20-21: Master 5 Priority */ +# define MATRIX_PRAS_M5PR_MASK (3 << MATRIX_PRAS_M5PR_SHIFT) +# define MATRIX_PRAS_M5PR(n) ((uint32_t)(n) << MATRIX_PRAS_M5PR_SHIFT) +# define MATRIX_PRAS_M6PR_SHIFT (24) /* Bits 24-25: Master 6 Priority */ +# define MATRIX_PRAS_M6PR_MASK (3 << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M6PR(n) ((uint32_t)(n) << MATRIX_PRAS_M6PR_SHIFT) +# define MATRIX_PRAS_M7PR_SHIFT (28) /* Bits 28-29: Master 7 Priority */ +# define MATRIX_PRAS_M7PR_MASK (3 << MATRIX_PRAS_M7PR_SHIFT) +# define MATRIX_PRAS_M7PR(n) ((uint32_t)(n) << MATRIX_PRAS_M7PR_SHIFT) + +/* Bus Matrix Priority Registers B For Slaves */ + +#define MATRIX_PRBS_MPR_SHIFT(x) (((n)-8) << 2) /* n = 8-11 */ +#define MATRIX_PRBS_MPR_MASK(x) (3 << MATRIX_PRBS_MPR_SHIFT(x)) +# define MATRIX_PRBS_M8PR_SHIFT (0) /* Bits 0-1: Master 8 Priority */ +# define MATRIX_PRBS_M8PR_MASK (3 << MATRIX_PRBS_M8PR_SHIFT) +# define MATRIX_PRBS_M8PR(n) ((uint32_t)(n) << MATRIX_PRBS_M8PR_SHIFT) +# define MATRIX_PRBS_M9PR_SHIFT (4) /* Bits 4-5: Master 9 Priority */ +# define MATRIX_PRBS_M9PR_MASK (3 << MATRIX_PRBS_M9PR_SHIFT) +# define MATRIX_PRBS_M9PR(n) ((uint32_t)(n) << MATRIX_PRBS_M9PR_SHIFT) +# define MATRIX_PRBS_M10PR_SHIFT (8) /* Bits 8-9: Master 10 Priority */ +# define MATRIX_PRBS_M10PR_MASK (3 << MATRIX_PRBS_M10PR_SHIFT) +# define MATRIX_PRBS_M10PR(n) ((uint32_t)(n) << MATRIX_PRBS_M10PR_SHIFT) +# define MATRIX_PRBS_M11PR_SHIFT (12) /* Bits 12-13: Master 11 Priority */ +# define MATRIX_PRBS_M11PR_MASK (3 << MATRIX_PRBS_M11PR_SHIFT) +# define MATRIX_PRBS_M11PR(n) ((uint32_t)(n) << MATRIX_PRBS_M11PR_SHIFT) + +/* Master Remap Control Register */ + +#define MATRIX_MRCR_RCB(n) (1 << (n)) /* n=0-11 */ +# define MATRIX_MRCR_RCB0 (1 << 0) /* Bit 0: Remap Command Bit for AHB Master 0 */ +# define MATRIX_MRCR_RCB1 (1 << 1) /* Bit 1: Remap Command Bit for AHB Master 1 */ +# define MATRIX_MRCR_RCB2 (1 << 2) /* Bit 2: Remap Command Bit for AHB Master 2 */ +# define MATRIX_MRCR_RCB3 (1 << 3) /* Bit 3: Remap Command Bit for AHB Master 3 */ +# define MATRIX_MRCR_RCB4 (1 << 4) /* Bit 4: Remap Command Bit for AHB Master 4 */ +# define MATRIX_MRCR_RCB5 (1 << 5) /* Bit 5: Remap Command Bit for AHB Master 5 */ +# define MATRIX_MRCR_RCB6 (1 << 6) /* Bit 6: Remap Command Bit for AHB Master 6 */ +# define MATRIX_MRCR_RCB7 (1 << 7) /* Bit 7: Remap Command Bit for AHB Master 7 */ +# define MATRIX_MRCR_RCB8 (1 << 8) /* Bit 8: Remap Command Bit for AHB Master 8 */ +# define MATRIX_MRCR_RCB9 (1 << 9) /* Bit 9: Remap Command Bit for AHB Master 9 */ +# define MATRIX_MRCR_RCB10 (1 << 10) /* Bit 10: Remap Command Bit for AHB Master 10 */ +# define MATRIX_MRCR_RCB11 (1 << 11) /* Bit 11: Remap Command Bit for AHB Master 11 */ + +/* CAN0 Configuration Register */ + +#define MATRIX_CAN0_RESERVED 0x000001ff /* Bits 0-9: Reserved */ +#define MATRIX_CAN0_CAN0DMABA_MASK 0xffff0000 /* Bits 16-31: CAN0 DMA Base Address */ + +/* System I/O and CAN1 Configuration Register */ + +#define MATRIX_CCFG_SYSIO_SYSIO(n) (1<<(n)) /* n=4-7, 12 */ +# define MATRIX_CCFG_SYSIO_SYSIO4 (1 << 4) /* Bit 4: PB4 or TDI Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO5 (1 << 5) /* Bit 5: PB5 or TDO/TRACESWO Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO6 (1 << 6) /* Bit 6: PB6 or TMS/SWDIO Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO7 (1 << 7) /* Bit 7: PB7 or TCK/SWCLK Assignment */ +# define MATRIX_CCFG_SYSIO_SYSIO12 (1 << 12) /* Bit 12: PB12 or ERASE Assignment */ +#define MATRIX_CCFG_CAN1DMABA_MASK 0xffff0000 /* Bits 16-31: CAN1 DMA Base Address */ + +/* SMC Chip Select NAND Flash Assignment Register */ + +#define MATRIX_CCFG_SMCNFCS_SMC_NFCS(n) (1<<(n)) /* Bit n: SMC NAND Flash Chip Select n Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS0 (1 << 0) /* Bit 0: SMC NAND Flash Chip Select 0 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS1 (1 << 1) /* Bit 1: SMC NAND Flash Chip Select 2 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS2 (1 << 2) /* Bit 2: SMC NAND Flash Chip Select 2 Assignment */ +# define MATRIX_CCFG_SMCNFCS_SMC_NFCS3 (1 << 3) /* Bit 3: SMC NAND Flash Chip Select 3 Assignment */ +#define MATRIX_CCFG_SMCNFCS_SDRAMEN (1 << 4) /* Bit 4: SDRAM Enable */ + +/* Write Protect Mode Register */ + +#define MATRIX_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define MATRIX_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (Write-only) */ +#define MATRIX_WPMR_WPKEY_MASK (0x00ffffff << MATRIX_WPMR_WPKEY_SHIFT) +# define MATRIX_WPMR_WPKEY (0x004d4154 << MATRIX_WPMR_WPKEY_SHIFT) + +/* Write Protect Status Register */ + +#define MATRIX_WPSR_WPVS (1 << 0) /* Bit 0: Enable Write Protect */ +#define MATRIX_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define MATRIX_WPSR_WPVSRC_MASK (0xffff << MATRIX_WPSR_WPVSRC_SHIFT) + +/* Masters ******************************************************************************/ + +#define MATRIX_MSTR_CORTEXM7_1 0 /* Cortex-M7 */ +#define MATRIX_MSTR_CORTEXM7_2 1 /* Cortex-M7 */ +#define MATRIX_MSTR_CORTEXM7_P 2 /* Cortex-M7 Peripheral Port */ +#define MATRIX_MSTR_ICM 3 /* Integrated Check Monitor */ +#define MATRIX_MSTR_XDMAC_1 4 /* XDMAC */ +#define MATRIX_MSTR_XDMAC_2 5 /* XDMAC */ +#define MATRIX_MSTR_ISI 6 /* ISI DMA */ +#define MATRIX_MSTR_MLB 7 /* Media LB */ +#define MATRIX_MSTR_USB 8 /* USB DMA */ +#define MATRIX_MSTR_EMAC 9 /* Ethernet MAC DMA */ +#define MATRIX_MSTR_CAN0 10 /* CAN0 DMA */ +#define MATRIX_MSTR_CAN1 11 /* CAN1 DMA */ + +/* Slaves *******************************************************************************/ + +#define MATRIX_SLAVE_ISRAM_1 0 /* Internal SRAM */ +#define MATRIX_SLAVE_ISRAM_2 1 /* Internal SRAM */ +#define MATRIX_SLAVE_IROM 2 /* Internal ROM */ +#define MATRIX_SLAVE_IFLASH 3 /* Internal Flash */ +#define MATRIX_SLAVE_USBRAM 4 /* USB High Speed Dual Port RAM (DPR) */ +#define MATRIX_SLAVE_EBI 5 /* External Bus Interface */ +#define MATRIX_SLAVE_QSPI 6 /* QSPI */ +#define MATRIX_SLAVE_PB 7 /* Peripheral Bridge */ +#define MATRIX_SLAVE_AHB 8 /* AHB Slave */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MATRIX_H */ diff --git a/arch/arm/src/samv7/chip/sam_mcan.h b/arch/arm/src/samv7/chip/sam_mcan.h new file mode 100644 index 0000000000000000000000000000000000000000..b3951aef703890ae6597eb7e2ac15516e15c774d --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_mcan.h @@ -0,0 +1,813 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_mcan.h + * Controller Area Network (MCAN) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MCAN_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MCAN_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* MCAN register offsets ****************************************************************/ + + /* 0x0000-0x0004 Reserved */ +#define SAM_MCAN_CUST_OFFSET 0x0008 /* Customer Register */ +#define SAM_MCAN_FBTP_OFFSET 0x000c /* Fast Bit Timing and Prescaler Register */ +#define SAM_MCAN_TEST_OFFSET 0x0010 /* Test Register */ +#define SAM_MCAN_RWD_OFFSET 0x0014 /* RAM Watchdog Register */ +#define SAM_MCAN_CCCR_OFFSET 0x0018 /* CC Control Register */ +#define SAM_MCAN_BTP_OFFSET 0x001c /* Bit Timing and Prescaler Register */ +#define SAM_MCAN_TSCC_OFFSET 0x0020 /* Timestamp Counter Configuration Register */ +#define SAM_MCAN_TSCV_OFFSET 0x0024 /* Timestamp Counter Value Register */ +#define SAM_MCAN_TOCC_OFFSET 0x0028 /* Timeout Counter Configuration Register */ +#define SAM_MCAN_TOCV_OFFSET 0x002c /* Timeout Counter Value Register */ + /* 0x0030-0x003c Reserved */ +#define SAM_MCAN_ECR_OFFSET 0x0040 /* Error Counter Register */ +#define SAM_MCAN_PSR_OFFSET 0x0044 /* Protocol Status Register */ + /* 0x0048-0x004c Reserved */ +#define SAM_MCAN_IR_OFFSET 0x0050 /* Interrupt Register*/ +#define SAM_MCAN_IE_OFFSET 0x0054 /* Interrupt Enable Register */ +#define SAM_MCAN_ILS_OFFSET 0x0058 /* Interrupt Line Select Register */ +#define SAM_MCAN_ILE_OFFSET 0x005c /* Interrupt Line Enable Register */ + /* 0x0060-0x007c Reserved */ +#define SAM_MCAN_GFC_OFFSET 0x0080 /* Global Filter Configuration Register */ +#define SAM_MCAN_SIDFC_OFFSET 0x0084 /* Standard ID Filter Configuration Register */ +#define SAM_MCAN_XIDFC_OFFSET 0x0088 /* Extended ID Filter Configuration Register */ + /* 0x008c Reserved */ +#define SAM_MCAN_XIDAM_OFFSET 0x0090 /* Extended ID AND Mask Register */ +#define SAM_MCAN_HPMS_OFFSET 0x0094 /* High Priority Message Status Register */ +#define SAM_MCAN_NDAT1_OFFSET 0x0098 /* New Data 1 Register */ +#define SAM_MCAN_NDAT2_OFFSET 0x009c /* New Data 2 Register */ +#define SAM_MCAN_RXF0C_OFFSET 0x00a0 /* Receive FIFO 0 Configuration Register */ +#define SAM_MCAN_RXF0S_OFFSET 0x00a4 /* Receive FIFO 0 Status Register */ +#define SAM_MCAN_RXF0A_OFFSET 0x00a8 /* Receive FIFO 0 Acknowledge Register */ +#define SAM_MCAN_RXBC_OFFSET 0x00ac /* Receive Rx Buffer Configuration Register */ +#define SAM_MCAN_RXF1C_OFFSET 0x00b0 /* Receive FIFO 1 Configuration Register */ +#define SAM_MCAN_RXF1S_OFFSET 0x00b4 /* Receive FIFO 1 Status Register */ +#define SAM_MCAN_RXF1A_OFFSET 0x00b8 /* Receive FIFO 1 Acknowledge Register */ +#define SAM_MCAN_RXESC_OFFSET 0x00bc /* Receive Buffer / FIFO Element Size Configuration Register */ +#define SAM_MCAN_TXBC_OFFSET 0x00c0 /* Transmit Buffer Configuration Register */ +#define SAM_MCAN_TXFQS_OFFSET 0x00c4 /* Transmit FIFO/Queue Status Register */ +#define SAM_MCAN_TXESC_OFFSET 0x00c8 /* Transmit Buffer Element Size Configuration Register */ +#define SAM_MCAN_TXBRP_OFFSET 0x00cc /* Transmit Buffer Request Pending Register */ +#define SAM_MCAN_TXBAR_OFFSET 0x00d0 /* Transmit Buffer Add Request Register */ +#define SAM_MCAN_TXBCR_OFFSET 0x00d4 /* Transmit Buffer Cancellation Request Register */ +#define SAM_MCAN_TXBTO_OFFSET 0x00d8 /* Transmit Buffer Transmission Occurred Register */ +#define SAM_MCAN_TXBCF_OFFSET 0x00dc /* Transmit Buffer Cancellation Finished Register */ +#define SAM_MCAN_TXBTIE_OFFSET 0x00e0 /* Transmit Buffer Transmission Interrupt Enable Register */ +#define SAM_MCAN_TXBCIE_OFFSET 0x00e4 /* Transmit Buffer Cancellation Finished Interrupt Enable Register */ + /* 0x00e8-0x00ec Reserved */ +#define SAM_MCAN_TXEFC_OFFSET 0x00f0 /* Transmit Event FIFO Configuration Register */ +#define SAM_MCAN_TXEFS_OFFSET 0x00f4 /* Transmit Event FIFO Status Register */ +#define SAM_MCAN_TXEFA_OFFSET 0x00f8 /* Transmit Event FIFO Acknowledge Register */ + /* 0x00fc Reserved */ + +/* MCAN register addresses **************************************************************/ + +#define SAM_MCAN0_CUST (SAM_MCAN0_BASE+SAM_MCAN_CUST_OFFSET) +#define SAM_MCAN0_FBTP (SAM_MCAN0_BASE+SAM_MCAN_FBTP_OFFSET) +#define SAM_MCAN0_TEST (SAM_MCAN0_BASE+SAM_MCAN_TEST_OFFSET) +#define SAM_MCAN0_RWD (SAM_MCAN0_BASE+SAM_MCAN_RWD_OFFSET) +#define SAM_MCAN0_CCCR (SAM_MCAN0_BASE+SAM_MCAN_CCCR_OFFSET) +#define SAM_MCAN0_BTP (SAM_MCAN0_BASE+SAM_MCAN_BTP_OFFSET) +#define SAM_MCAN0_TSCC (SAM_MCAN0_BASE+SAM_MCAN_TSCC_OFFSET) +#define SAM_MCAN0_TSCV (SAM_MCAN0_BASE+SAM_MCAN_TSCV_OFFSET) +#define SAM_MCAN0_TOCC (SAM_MCAN0_BASE+SAM_MCAN_TOCC_OFFSET) +#define SAM_MCAN0_TOCV (SAM_MCAN0_BASE+SAM_MCAN_TOCV_OFFSET) +#define SAM_MCAN0_ECR (SAM_MCAN0_BASE+SAM_MCAN_ECR_OFFSET) +#define SAM_MCAN0_PSR (SAM_MCAN0_BASE+SAM_MCAN_PSR_OFFSET) +#define SAM_MCAN0_IR (SAM_MCAN0_BASE+SAM_MCAN_IR_OFFSET) +#define SAM_MCAN0_IE (SAM_MCAN0_BASE+SAM_MCAN_IE_OFFSET) +#define SAM_MCAN0_ILS (SAM_MCAN0_BASE+SAM_MCAN_ILS_OFFSET) +#define SAM_MCAN0_ILE (SAM_MCAN0_BASE+SAM_MCAN_ILE_OFFSET) +#define SAM_MCAN0_GFC (SAM_MCAN0_BASE+SAM_MCAN_GFC_OFFSET) +#define SAM_MCAN0_SIDFC (SAM_MCAN0_BASE+SAM_MCAN_SIDFC_OFFSET) +#define SAM_MCAN0_XIDFC (SAM_MCAN0_BASE+SAM_MCAN_XIDFC_OFFSET) +#define SAM_MCAN0_XIDAM (SAM_MCAN0_BASE+SAM_MCAN_XIDAM_OFFSET) +#define SAM_MCAN0_HPMS (SAM_MCAN0_BASE+SAM_MCAN_HPMS_OFFSET) +#define SAM_MCAN0_NDAT1 (SAM_MCAN0_BASE+SAM_MCAN_NDAT1_OFFSET) +#define SAM_MCAN0_NDAT2 (SAM_MCAN0_BASE+SAM_MCAN_NDAT2_OFFSET) +#define SAM_MCAN0_RXF0C (SAM_MCAN0_BASE+SAM_MCAN_RXF0C_OFFSET) +#define SAM_MCAN0_RXF0S (SAM_MCAN0_BASE+SAM_MCAN_RXF0S_OFFSET) +#define SAM_MCAN0_RXF0A (SAM_MCAN0_BASE+SAM_MCAN_RXF0A_OFFSET) +#define SAM_MCAN0_RXBC (SAM_MCAN0_BASE+SAM_MCAN_RXBC_OFFSET) +#define SAM_MCAN0_RXF1C (SAM_MCAN0_BASE+SAM_MCAN_RXF1C_OFFSET) +#define SAM_MCAN0_RXF1S (SAM_MCAN0_BASE+SAM_MCAN_RXF1S_OFFSET) +#define SAM_MCAN0_RXF1A (SAM_MCAN0_BASE+SAM_MCAN_RXF1A_OFFSET) +#define SAM_MCAN0_RXESC (SAM_MCAN0_BASE+SAM_MCAN_RXESC_OFFSET) +#define SAM_MCAN0_TXBC (SAM_MCAN0_BASE+SAM_MCAN_TXBC_OFFSET) +#define SAM_MCAN0_TXFQS (SAM_MCAN0_BASE+SAM_MCAN_TXFQS_OFFSET) +#define SAM_MCAN0_TXESC (SAM_MCAN0_BASE+SAM_MCAN_TXESC_OFFSET) +#define SAM_MCAN0_TXBRP (SAM_MCAN0_BASE+SAM_MCAN_TXBRP_OFFSET) +#define SAM_MCAN0_TXBAR (SAM_MCAN0_BASE+SAM_MCAN_TXBAR_OFFSET) +#define SAM_MCAN0_TXBCR (SAM_MCAN0_BASE+SAM_MCAN_TXBCR_OFFSET) +#define SAM_MCAN0_TXBTO (SAM_MCAN0_BASE+SAM_MCAN_TXBTO_OFFSET) +#define SAM_MCAN0_TXBCF (SAM_MCAN0_BASE+SAM_MCAN_TXBCF_OFFSET) +#define SAM_MCAN0_TXBTIE (SAM_MCAN0_BASE+SAM_MCAN_TXBTIE_OFFSET) +#define SAM_MCAN0_TXBCIE (SAM_MCAN0_BASE+SAM_MCAN_TXBCIE_OFFSET) +#define SAM_MCAN0_TXEFC (SAM_MCAN0_BASE+SAM_MCAN_TXEFC_OFFSET) +#define SAM_MCAN0_TXEFS (SAM_MCAN0_BASE+SAM_MCAN_TXEFS_OFFSET) +#define SAM_MCAN0_TXEFA (SAM_MCAN0_BASE+SAM_MCAN_TXEFA_OFFSET) + +#define SAM_MCAN1_CUST (SAM_MCAN1_BASE+SAM_MCAN_CUST_OFFSET) +#define SAM_MCAN1_FBTP (SAM_MCAN1_BASE+SAM_MCAN_FBTP_OFFSET) +#define SAM_MCAN1_TEST (SAM_MCAN1_BASE+SAM_MCAN_TEST_OFFSET) +#define SAM_MCAN1_RWD (SAM_MCAN1_BASE+SAM_MCAN_RWD_OFFSET) +#define SAM_MCAN1_CCCR (SAM_MCAN1_BASE+SAM_MCAN_CCCR_OFFSET) +#define SAM_MCAN1_BTP (SAM_MCAN1_BASE+SAM_MCAN_BTP_OFFSET) +#define SAM_MCAN1_TSCC (SAM_MCAN1_BASE+SAM_MCAN_TSCC_OFFSET) +#define SAM_MCAN1_TSCV (SAM_MCAN1_BASE+SAM_MCAN_TSCV_OFFSET) +#define SAM_MCAN1_TOCC (SAM_MCAN1_BASE+SAM_MCAN_TOCC_OFFSET) +#define SAM_MCAN1_TOCV (SAM_MCAN1_BASE+SAM_MCAN_TOCV_OFFSET) +#define SAM_MCAN1_ECR (SAM_MCAN1_BASE+SAM_MCAN_ECR_OFFSET) +#define SAM_MCAN1_PSR (SAM_MCAN1_BASE+SAM_MCAN_PSR_OFFSET) +#define SAM_MCAN1_IR (SAM_MCAN1_BASE+SAM_MCAN_IR_OFFSET) +#define SAM_MCAN1_IE (SAM_MCAN1_BASE+SAM_MCAN_IE_OFFSET) +#define SAM_MCAN1_ILS (SAM_MCAN1_BASE+SAM_MCAN_ILS_OFFSET) +#define SAM_MCAN1_ILE (SAM_MCAN1_BASE+SAM_MCAN_ILE_OFFSET) +#define SAM_MCAN1_GFC (SAM_MCAN1_BASE+SAM_MCAN_GFC_OFFSET) +#define SAM_MCAN1_SIDFC (SAM_MCAN1_BASE+SAM_MCAN_SIDFC_OFFSET) +#define SAM_MCAN1_XIDFC (SAM_MCAN1_BASE+SAM_MCAN_XIDFC_OFFSET) +#define SAM_MCAN1_XIDAM (SAM_MCAN1_BASE+SAM_MCAN_XIDAM_OFFSET) +#define SAM_MCAN1_HPMS (SAM_MCAN1_BASE+SAM_MCAN_HPMS_OFFSET) +#define SAM_MCAN1_NDAT1 (SAM_MCAN1_BASE+SAM_MCAN_NDAT1_OFFSET) +#define SAM_MCAN1_NDAT2 (SAM_MCAN1_BASE+SAM_MCAN_NDAT2_OFFSET) +#define SAM_MCAN1_RXF0C (SAM_MCAN1_BASE+SAM_MCAN_RXF0C_OFFSET) +#define SAM_MCAN1_RXF0S (SAM_MCAN1_BASE+SAM_MCAN_RXF0S_OFFSET) +#define SAM_MCAN1_RXF0A (SAM_MCAN1_BASE+SAM_MCAN_RXF0A_OFFSET) +#define SAM_MCAN1_RXBC (SAM_MCAN1_BASE+SAM_MCAN_RXBC_OFFSET) +#define SAM_MCAN1_RXF1C (SAM_MCAN1_BASE+SAM_MCAN_RXF1C_OFFSET) +#define SAM_MCAN1_RXF1S (SAM_MCAN1_BASE+SAM_MCAN_RXF1S_OFFSET) +#define SAM_MCAN1_RXF1A (SAM_MCAN1_BASE+SAM_MCAN_RXF1A_OFFSET) +#define SAM_MCAN1_RXESC (SAM_MCAN1_BASE+SAM_MCAN_RXESC_OFFSET) +#define SAM_MCAN1_TXBC (SAM_MCAN1_BASE+SAM_MCAN_TXBC_OFFSET) +#define SAM_MCAN1_TXFQS (SAM_MCAN1_BASE+SAM_MCAN_TXFQS_OFFSET) +#define SAM_MCAN1_TXESC (SAM_MCAN1_BASE+SAM_MCAN_TXESC_OFFSET) +#define SAM_MCAN1_TXBRP (SAM_MCAN1_BASE+SAM_MCAN_TXBRP_OFFSET) +#define SAM_MCAN1_TXBAR (SAM_MCAN1_BASE+SAM_MCAN_TXBAR_OFFSET) +#define SAM_MCAN1_TXBCR (SAM_MCAN1_BASE+SAM_MCAN_TXBCR_OFFSET) +#define SAM_MCAN1_TXBTO (SAM_MCAN1_BASE+SAM_MCAN_TXBTO_OFFSET) +#define SAM_MCAN1_TXBCF (SAM_MCAN1_BASE+SAM_MCAN_TXBCF_OFFSET) +#define SAM_MCAN1_TXBTIE (SAM_MCAN1_BASE+SAM_MCAN_TXBTIE_OFFSET) +#define SAM_MCAN1_TXBCIE (SAM_MCAN1_BASE+SAM_MCAN_TXBCIE_OFFSET) +#define SAM_MCAN1_TXEFC (SAM_MCAN1_BASE+SAM_MCAN_TXEFC_OFFSET) +#define SAM_MCAN1_TXEFS (SAM_MCAN1_BASE+SAM_MCAN_TXEFS_OFFSET) +#define SAM_MCAN1_TXEFA (SAM_MCAN1_BASE+SAM_MCAN_TXEFA_OFFSET) + +/* MCAN register bit definitions ********************************************************/ + +/* Customer Register (32-bit value)*/ + +/* Fast Bit Timing and Prescaler Register */ + +#define MCAN_FBTP_FSJW_SHIFT (0) /* Bits 0-1: Fast (Re) Synchronization Jump Width */ +#define MCAN_FBTP_FSJW_MASK (3 << MCAN_FBTP_FSJW_SHIFT) +# define MCAN_FBTP_FSJW(n) ((uint32_t)(n) << MCAN_FBTP_FSJW_SHIFT) +#define MCAN_FBTP_FTSEG2_SHIFT (4) /* Bits 4-6: Fast Time Segment After Sample Point */ +#define MCAN_FBTP_FTSEG2_MASK (7 << MCAN_FBTP_FTSEG2_SHIFT) +# define MCAN_FBTP_FTSEG2(n) ((uint32_t)(n) << MCAN_FBTP_FTSEG2_SHIFT) +#define MCAN_FBTP_FTSEG1_SHIFT (8) /* Bits 8-11: Fast Time Segment Before Sample Point */ +#define MCAN_FBTP_FTSEG1_MASK (15 << MCAN_FBTP_FTSEG1_SHIFT) +# define MCAN_FBTP_FTSEG1(n) ((uint32_t)(n) << MCAN_FBTP_FTSEG1_SHIFT) +#define MCAN_FBTP_FBRP_SHIFT (16) /* Bits 16-20: Fast Baud Rate Prescaler */ +#define MCAN_FBTP_FBRP_MASK (31 << MCAN_FBTP_FBRP_SHIFT) +# define MCAN_FBTP_FBRP(n) ((uint32_t)(n) << MCAN_FBTP_FBRP_SHIFT) +#define MCAN_FBTP_TDC (1 << 23) /* Bit: 23: Transceiver Delay Compensation */ +#define MCAN_FBTP_TDCO_SHIFT (24) /* Bits 24-28: Transceiver Delay Compensation Offset */ +#define MCAN_FBTP_TDCO_MASK (31 << MCAN_FBTP_TDC_SHIFT) +# define MCAN_FBTP_TDCO(n) ((uint32_t)(n) << MCAN_FBTP_TDC_SHIFT) + +/* Test Register */ + +#define MCAN_TEST_LBCK (1 << 4) /* Bit 4: Loop Back Mode */ +#define MCAN_TEST_TX_SHIFT (5) /* Bits 5-6: Control of Transmit Pin */ +#define MCAN_TEST_TX_MASK (3 << MCAN_TEST_TX_SHIFT) +# define MCAN_TEST_TX_RESET (0 << MCAN_TEST_TX_SHIFT) /* Reset value */ +# define MCAN_TEST_TX_SPMON (1 << MCAN_TEST_TX_SHIFT) /* Sample Point can be monitored at CANTX */ +# define MCAN_TEST_TX_DOMINANT (2 << MCAN_TEST_TX_SHIFT) /* Dominant (0) level at CANTX. */ +# define MCAN_TEST_TX_RECESSIVE (3 << MCAN_TEST_TX_SHIFT) /* Recessive (1) at CANTX. */ +#define MCAN_TEST_RX (1 << 7) /* Bit 7: Receive Pin */ +#define MCAN_TEST_TDCV_SHIFT (8) /* Bits 8-13: Transceiver Delay Compensation Value */ +#define MCAN_TEST_TDCV_MASK (0x3f << MCAN_TEST_TDCV_SHIFT) +# define MCAN_TEST_TDCV(n) ((uint32_t)(n) << MCAN_TEST_TDCV_SHIFT) + +/* RAM Watchdog Register */ + +#define MCAN_RWD_WDC_SHIFT (0) /* Bits 0-7: Watchdog Configuration */ +#define MCAN_RWD_WDC_MASK (0xff << MCAN_RWD_WDC_SHIFT) +# define MCAN_RWD_WDC(n) ((uint32_t)(n) << MCAN_RWD_WDC_SHIFT) +#define MCAN_RWD_WDV_SHIFT (8) /* Bits 8-15: Watchdog Value */ +#define MCAN_RWD_WDV_MASK (0xff << MCAN_RWD_WDV_SHIFT) +# define MCAN_RWD_WDV(n) ((uint32_t)(n) << MCAN_RWD_WDV_SHIFT) + +/* CC Control Register */ + +#define MCAN_CCCR_INIT (1 << 0) /* Bit 0: Initialization */ +#define MCAN_CCCR_CCE (1 << 1) /* Bit 1: Configuration Change Enable */ +#define MCAN_CCCR_ASM (1 << 2) /* Bit 2: Restricted Operation Mode */ +#define MCAN_CCCR_CSA (1 << 3) /* Bit 3: Clock Stop Acknowledge */ +#define MCAN_CCCR_CSR (1 << 4) /* Bit 4: Clock Stop Request */ +#define MCAN_CCCR_MON (1 << 5) /* Bit 5: Bus Monitoring Mode */ +#define MCAN_CCCR_DAR (1 << 6) /* Bit 6: Disable Automatic Retransmission */ +#define MCAN_CCCR_TEST (1 << 7) /* Bit 7: Test Mode Enable */ +#define MCAN_CCCR_CME_SHIFT (8) /* Bits 8-9: CAN Mode Enable */ +#define MCAN_CCCR_CME_MASK (3 << MCAN_CCCR_CME_SHIFT) +# define MCAN_CCCR_CME_ISO11898_1 (0 << MCAN_CCCR_CME_SHIFT) /* CAN operation according to ISO11898-1 enabled */ +# define MCAN_CCCR_CME_FD (1 << MCAN_CCCR_CME_SHIFT) /* CAN FD operation enabled */ +# define MCAN_CCCR_CME_FD_BSW (2 << MCAN_CCCR_CME_SHIFT) /* CAN FD operation with bit rate switching enabled */ +#define MCAN_CCCR_CMR_SHIFT (10) /* Bits 10-11: CAN Mode Request */ +#define MCAN_CCCR_CMR_MASK (3 << MCAN_CCCR_CMR_SHIFT) +# define MCAN_CCCR_CMR_NOCHG (0 << MCAN_CCCR_CMR_SHIFT) /* No mode change */ +# define MCAN_CCCR_CMR_FD (1 << MCAN_CCCR_CMR_SHIFT) /* Request CAN FD operation */ +# define MCAN_CCCR_CMR_FD_BSW (2 << MCAN_CCCR_CMR_SHIFT) /* Request CAN FD operation with bit rate switching */ +# define MCAN_CCCR_CMR_ISO11898_1 (3 << MCAN_CCCR_CMR_SHIFT) /* Request CAN operation according ISO11898-1 */ +#define MCAN_CCCR_FDO (1 << 12) /* Bit 12: CAN FD Operation */ +#define MCAN_CCCR_FDBS (1 << 13) /* Bit 13: CAN FD Bit Rate Switching */ +#define MCAN_CCCR_TXP (1 << 14) /* Bit 14: Transmit Pause */ + +/* Bit Timing and Prescaler Register */ + +#define MCAN_BTP_SJW_SHIFT (0) /* Bits 0-3: (Re) Synchronization Jump Width */ +#define MCAN_BTP_SJW_MASK (15 << MCAN_BTP_SJW_SHIFT) +# define MCAN_BTP_SJW(n) ((uint32_t)(n) << MCAN_BTP_SJW_SHIFT) +#define MCAN_BTP_TSEG2_SHIFT (4) /* Bits 4-7: Time Segment After Sample Point */ +#define MCAN_BTP_TSEG2_MASK (15 << MCAN_BTP_TSEG2_SHIFT) +# define MCAN_BTP_TSEG2(n) ((uint32_t)(n) << MCAN_BTP_TSEG2_SHIFT) +#define MCAN_BTP_TSEG1_SHIFT (8) /* Bits 8-13: Time Segment Before Sample Point */ +#define MCAN_BTP_TSEG1_MASK (0x3f << MCAN_BTP_TSEG1_SHIFT) +# define MCAN_BTP_TSEG1(n) ((uint32_t)(n) << MCAN_BTP_TSEG1_SHIFT) +#define MCAN_BTP_BRP_SHIFT (16) /* Bits 16-25: Baud Rate Prescaler */ +#define MCAN_BTP_BRP_MASK (0x3ff << MCAN_BTP_BRP_SHIFT) +# define MCAN_BTP_BRP(n) ((uint32_t)(n) << MCAN_BTP_BRP_SHIFT) + +/* Timestamp Counter Configuration Register */ + +#define MCAN_TSCC_TSS_SHIFT (0) /* Bits 0-1: Timestamp Select */ +#define MCAN_TSCC_TSS_MASK (3 << MCAN_TSCC_TSS_SHIFT) +# define MCAN_TSCC_TSS_ ZERO (0 << MCAN_TSCC_TSS_SHIFT) /* Timestamp counter value always 0x0000 */ +# define MCAN_TSCC_TSS_TCP_INC (1 << MCAN_TSCC_TSS_SHIFT) /* Timestamp counter value incremented according to TCP */ +# define MCAN_TSCC_TSS_EXT_TS (2 << MCAN_TSCC_TSS_SHIFT) /* External timestamp counter value used */ +#define MCAN_TSCC_TCP_SHIFT (16) /* Bits 16-19: Timestamp Counter Prescaler */ +#define MCAN_TSCC_TCP_MASK (15 << MCAN_TSCC_TCP_SHIFT) +# define MCAN_TSCC_TCP(n) ((uint32_t)(n) << MCAN_TSCC_TCP_SHIFT) + +/* Timestamp Counter Value Register */ + +#define MCAN_TSCV_MASK 0x0000ffff /* Timestamp counter mask */ + +/* Timeout Counter Configuration Register */ + +#define MCAN_TOCC_ETOC (1 << 0) /* Bit 0: Enable Timeout Counter */ +#define MCAN_TOCC_TOS_SHIFT (1) /* Bits 1-2: Timeout Select */ +#define MCAN_TOCC_TOS_MASK (3 << MCAN_TOCC_TOS_SHIFT) +# define MCAN_TOCC_TOS_CONTINUOUS (0 << MCAN_TOCC_TOS_SHIFT) /* Continuous operation */ +# define MCAN_TOCC_TOS_TX_TIMEOUT (1 << MCAN_TOCC_TOS_SHIFT) /* Timeout controlled by Tx Event FIFO */ +# define MCAN_TOCC_TOS_RX0_TIMEOUT (2 << MCAN_TOCC_TOS_SHIFT) /* Timeout controlled by Receive FIFO 0 */ +# define MCAN_TOCC_TOS_RX1_TIMEOUT (3 << MCAN_TOCC_TOS_SHIFT) /* Timeout controlled by Receive FIFO 1 */ +#define MCAN_TOCC_TOP_SHIFT (16) /* Bits 16-31: Timeout Period */ +#define MCAN_TOCC_TOP_MASK (0xffff << MCAN_TOCC_TOP_SHIFT) +# define MCAN_TOCC_TOP(n) ((uint32_t)(n) << MCAN_TOCC_TOP_SHIFT) + +/* Timeout Counter Value Register */ + +#define MCAN_TOCV_MASK 0x0000ffff /* Timeout counter mask */ + +/* Error Counter Register */ + +#define MCAN_ECR_TEC_SHIFT (0) /* Bits 0-7: Transmit Error Counter */ +#define MCAN_ECR_TEC_MASK (0xff << MCAN_ECR_TEC_SHIFT) +# define MCAN_ECR_TEC(n) ((uint32_t)(n) << MCAN_ECR_TEC_SHIFT) +#define MCAN_ECR_REC_SHIFT (8) /* Bits 8-14: Receive Error Counter */ +#define MCAN_ECR_REC_MASK (0x7f << MCAN_ECR_REC_SHIFT) +# define MCAN_ECR_REC(n) ((uint32_t)(n) << MCAN_ECR_REC_SHIFT) +#define MCAN_ECR_RP (1 << 15) /* Bit 15: Receive Error Passive */ +#define MCAN_ECR_CEL_SHIFT (16) /* Bits 16-23: CAN Error Logging */ +#define MCAN_ECR_CEL_MASK (0xff << MCAN_ECR_CEL_SHIFT) +# define MCAN_ECR_CEL(n) ((uint32_t)(n) << MCAN_ECR_CEL_SHIFT) + +/* Protocol Status Register */ +/* Error codes */ + +#define MCAN_PSR_EC_NO_ERROR (0) /* No error occurred since LEC has been reset */ +#define MCAN_PSR_EC_STUFF_ERROR (1) /* More than 5 equal bits in a sequence */ +#define MCAN_PSR_EC_FORM_ERROR (2) /* Part of a received frame has wrong format */ +#define MCAN_PSR_EC_ACK_ERROR (3) /* Message not acknowledged by another node */ +#define MCAN_PSR_EC_BIT1_ERROR (4) /* Send with recessive level, but bus value was dominant */ +#define MCAN_PSR_EC_BIT0_ERROR (5) /* Send with dominant level, but bus value was recessive */ +#define MCAN_PSR_EC_CRC_ERROR (6) /* CRC received message incorrect */ +#define MCAN_PSR_EC_NO_CHANGE (7) /* No CAN bus event was detected since last read */ + +#define MCAN_PSR_LEC_SHIFT (0) /* Bits 0-2: Last Error Code */ +#define MCAN_PSR_LEC_MASK (7 << MCAN_PSR_LEC_SHIFT) +# define MCAN_PSR_LEC(n) ((uint32_t)(n) << MCAN_PSR_LEC_SHIFT) /* See error codes above */ +#define MCAN_PSR_ACT_SHIFT (3) /* Bits 3-4: Activity */ +#define MCAN_PSR_ACT_MASK (3 << MCAN_PSR_ACT_SHIFT) +# define MCAN_PSR_ACT_SYNCHING (0 << MCAN_PSR_ACT_SHIFT) /* Node is synchronizing on CAN communication */ +# define MCAN_PSR_ACT_IDLE (1 << MCAN_PSR_ACT_SHIFT) /* Node is neither receiver nor transmitter */ +# define MCAN_PSR_ACT_RECEIVER (2 << MCAN_PSR_ACT_SHIFT) /* Node is operating as receiver */ +# define MCAN_PSR_ACT_TRANSMITTER (3 << MCAN_PSR_ACT_SHIFT) /* Node is operating as transmitter */ +#define MCAN_PSR_EP (1 << 5) /* Bit 5: Error Passive */ +#define MCAN_PSR_EW (1 << 6) /* Bit 6: Warning Status */ +#define MCAN_PSR_BO (1 << 7) /* Bit 7: Bus_Off Status */ +#define MCAN_PSR_FLEC_SHIFT (8) /* Bits 8-10: Fast Last Error Code */ +#define MCAN_PSR_FLEC_MASK (7 << MCAN_PSR_FLEC_SHIFT) +# define MCAN_PSR_FLEC(n) ((uint32_t)(n) << MCAN_PSR_FLEC_SHIFT) /* See error codes above */ +#define MCAN_PSR_RESI (1 << 11) /* Bit 11: ESI Flag of Last Received CAN FD Message */ +#define MCAN_PSR_RBRS (1 << 12) /* Bit 12: BRS Flag of Last Received CAN FD Message */ +#define MCAN_PSR_REDL (1 << 13) /* Bit 13: Received a CAN FD Message */ + +/* Common bit definitions for Interrupt Register, Interrupt Enable Register, Interrupt + * Line Select Register + */ + +#define MCAN_INT_RF0N (1 << 0) /* Bit 0: Receive FIFO 0 New Message */ +#define MCAN_INT_RF0W (1 << 1) /* Bit 1: Receive FIFO 0 Watermark Reached */ +#define MCAN_INT_RF0F (1 << 2) /* Bit 2: Receive FIFO 0 Full */ +#define MCAN_INT_RF0L (1 << 3) /* Bit 3: Receive FIFO 0 Message Lost */ +#define MCAN_INT_RF1N (1 << 4) /* Bit 4: Receive FIFO 1 New Message */ +#define MCAN_INT_RF1W (1 << 5) /* Bit 5: Receive FIFO 1 Watermark Reached */ +#define MCAN_INT_RF1F (1 << 6) /* Bit 6: Receive FIFO 1 Full */ +#define MCAN_INT_RF1L (1 << 7) /* Bit 7: Receive FIFO 1 Message Lost */ +#define MCAN_INT_HPM (1 << 8) /* Bit 8: High Priority Message Received */ +#define MCAN_INT_TC (1 << 9) /* Bit 9: Transmission Completed */ +#define MCAN_INT_TCF (1 << 10) /* Bit 10: Transmission Cancellation Finished */ +#define MCAN_INT_TFE (1 << 11) /* Bit 11: Tx FIFO Empty */ +#define MCAN_INT_TEFN (1 << 12) /* Bit 12: Tx Event FIFO New Entry */ +#define MCAN_INT_TEFW (1 << 13) /* Bit 13: Tx Event FIFO Watermark Reached */ +#define MCAN_INT_TEFF (1 << 14) /* Bit 14: Tx Event FIFO Full */ +#define MCAN_INT_TEFL (1 << 15) /* Bit 15: Tx Event FIFO Element Lost */ +#define MCAN_INT_TSW (1 << 16) /* Bit 16: Timestamp Wraparound */ +#define MCAN_INT_MRAF (1 << 17) /* Bit 17: Message RAM Access Failure */ +#define MCAN_INT_TOO (1 << 18) /* Bit 18: Timeout Occurred */ +#define MCAN_INT_DRX (1 << 19) /* Bit 19: Message stored to Dedicated Receive Buffer */ +#define MCAN_INT_ELO (1 << 22) /* Bit 22: Error Logging Overflow */ +#define MCAN_INT_EP (1 << 23) /* Bit 23: Error Passive */ +#define MCAN_INT_EW (1 << 24) /* Bit 24: Warning Status */ +#define MCAN_INT_BO (1 << 25) /* Bit 25: Bus_Off Status */ +#define MCAN_INT_WDI (1 << 26) /* Bit 26: Watchdog Interrupt */ +#define MCAN_INT_CRCE (1 << 27) /* Bit 27: Receive CRC Error */ +#define MCAN_INT_BE (1 << 28) /* Bit 28: Bit Error */ +#define MCAN_INT_ACKE (1 << 29) /* Bit 29: Acknowledge Error */ +#define MCAN_INT_FOE (1 << 30) /* Bit 30: Format Error */ +#define MCAN_INT_STE (1 << 31) /* Bit 31: Stuff Error */ + +#define MCAN_INT_ALL (0xffcfffff) + +/* Interrupt Line Enable Register */ + +#define MCAN_ILE_EINT0 (1 << 0) /* Bit 0: Enable Interrupt Line 0 */ +#define MCAN_ILE_EINT1 (1 << 1) /* Bit 1: Enable Interrupt Line 1 */ + +/* Global Filter Configuration Register */ + +#define MCAN_GFC_RRFE (1 << 0) /* Bit 0: Reject Remote Frames Extended */ +#define MCAN_GFC_RRFS (1 << 1) /* Bit 1: Reject Remote Frames Standard */ +#define MCAN_GFC_ANFE_SHIFT (2) /* Bits 2-3: Accept Non-matching Frames Extended */ +#define MCAN_GFC_ANFE_MASK (3 << MCAN_GFC_ANFE_SHIFT) +# define MCAN_GFC_ANFE_RX_FIFO0 (0 << MCAN_GFC_ANFE_SHIFT) /* Message stored in Receive FIFO 0 */ +# define MCAN_GFC_ANFE_RX_FIFO1 (1 << MCAN_GFC_ANFE_SHIFT) /* Message stored in Receive FIFO 1 */ +# define MCAN_GFC_ANFE_REJECTED (2 << MCAN_GFC_ANFE_SHIFT) /* 2-3 Message rejected */ +#define MCAN_GFC_ANFS_SHIFT (4) /* Bits 4-5: Accept Non-matching Frames Standard */ +#define MCAN_GFC_ANFS_MASK (3 << MCAN_GFC_ANFS_SHIFT) +# define MCAN_GFC_ANFS_RX_FIFO0 (0 << MCAN_GFC_ANFS_SHIFT) /* Message stored in Receive FIFO 0 */ +# define MCAN_GFC_ANFS_RX_FIFO1 (1 << MCAN_GFC_ANFS_SHIFT) /* Message stored in Receive FIFO 1 */ +# define MCAN_GFC_ANFS_REJECTED (2 << MCAN_GFC_ANFS_SHIFT) /* 2-3 Message rejected */ + +/* Standard ID Filter Configuration Register */ + +#define MCAN_SIDFC_FLSSA_SHIFT (2) /* Bits 2-15: Filter List Standard Start Address */ +#define MCAN_SIDFC_FLSSA_MASK (0x3fff << MCAN_SIDFC_FLSSA_SHIFT) +# define MCAN_SIDFC_FLSSA(n) ((uint32_t)(n) << MCAN_SIDFC_FLSSA_SHIFT) +#define MCAN_SIDFC_LSS_SHIFT (16) /* Bits 16-23: List Size Standard */ +#define MCAN_SIDFC_LSS_MASK (0xff << MCAN_SIDFC_LSS_SHIFT) +# define MCAN_SIDFC_LSS(n) ((uint32_t)(n) << MCAN_SIDFC_LSS_SHIFT) + +/* Extended ID Filter Configuration Register */ + +#define MCAN_XIDFC_FLESA_SHIFT (2) /* Bits 2-15: Filter List Extended Start Address */ +#define MCAN_XIDFC_FLESA_MASK (0x3fff << MCAN_XIDFC_FLESA_SHIFT) +# define MCAN_XIDFC_FLESA(n) ((uint32_t)(n) << MCAN_XIDFC_FLESA_SHIFT) +#define MCAN_XIDFC_LSE_SHIFT (16) /* Bits 16-22: List Size Extended */ +#define MCAN_XIDFC_LSE_MASK (0x7f << MCAN_XIDFC_LSE_SHIFT) +# define MCAN_XIDFC_LSE(n) ((uint32_t)(n) << MCAN_XIDFC_LSE_SHIFT) + +/* Extended ID AND Mask Register */ + +#define MCAN_XIDAM_MASK 0x1fffffff /* Extended ID mask */ + +/* High Priority Message Status Register */ + +#define MCAN_HPMS_BIDX_SHIFT (0) /* Bits 0-5: Buffer Index */ +#define MCAN_HPMS_BIDX_MASK (0x3f << MCAN_HPMS_BIDX_SHIFT) +# define MCAN_HPMS_BIDX(n) ((uint32_t)(n) << MCAN_HPMS_BIDX_SHIFT) +#define MCAN_HPMS_MSI_SHIFT (6) /* Bits 6-7: Message Storage Indicator */ +#define MCAN_HPMS_MSI_MASK (3 << MCAN_HPMS_MSI_SHIFT) +# define MCAN_HPMS_MSI_NOFIFO (0 << MCAN_HPMS_MSI_SHIFT) /* No FIFO selected. */ +# define MCAN_HPMS_MSI_LOST (1 << MCAN_HPMS_MSI_SHIFT) /* FIFO message. */ +# define MCAN_HPMS_MSI_FIFO0 (2 << MCAN_HPMS_MSI_SHIFT) /* Message stored in FIFO 0. */ +# define MCAN_HPMS_MSI_FIFO1 (3 << MCAN_HPMS_MSI_SHIFT) /* Message stored in FIFO 1. */ +#define MCAN_HPMS_FIDX_SHIFT (8) /* Bits 8-14: Filter Index */ +#define MCAN_HPMS_FIDX_MASK (0x7f << MCAN_HPMS_FIDX_SHIFT) +# define MCAN_HPMS_FIDX(n) ((uint32_t)(n) << MCAN_HPMS_FIDX_SHIFT) +#define MCAN_HPMS_FLST (1 << 15) /* Bit 15: Filter List */ + +/* New Data 1 Register */ + +#define MCAN_NDAT1(n) (1 << (n)) /* New data for buffer n, n=0-31 */ + +/* New Data 2 Register */ + +#define MCAN_NDAT2(n) (1 << ((n)-32)) /* New data for buffer n, n=32-63 */ + +/* Receive FIFO 0 Configuration Register */ + +#define MCAN_RXF0C_F0SA_SHIFT (2) /* Bits 2-15: Receive FIFO 0 Start Address */ +#define MCAN_RXF0C_F0SA_MASK (0x3fff << MCAN_RXF0C_F0SA_SHIFT) +# define MCAN_RXF0C_F0SA(n) ((uint32_t)(n) << MCAN_RXF0C_F0SA_SHIFT) +#define MCAN_RXF0C_F0S_SHIFT (16) /* Bits 16-22: Receive FIFO 0 Size */ +#define MCAN_RXF0C_F0S_MASK (0x7f << MCAN_RXF0C_F0S_SHIFT) +# define MCAN_RXF0C_F0S(n) ((uint32_t)(n) << MCAN_RXF0C_F0S_SHIFT) +#define MCAN_RXF0C_F0WM_SHIFT (24) /* Bits 24-30: Receive FIFO 0 Watermark */ +#define MCAN_RXF0C_F0WM_MASK (0x7f << MCAN_RXF0C_F0WM_SHIFT) +# define MCAN_RXF0C_F0WM(n) ((uint32_t)(n) << MCAN_RXF0C_F0WM_SHIFT) +#define MCAN_RXF0C_F0OM (1 << 31) /* Bit 31: FIFO 0 Operation Mode */ + +/* Receive FIFO 0 Status Register */ + +#define MCAN_RXF0S_F0FL_SHIFT (0) /* Bits 0-6: Receive FIFO 0 Fill Level */ +#define MCAN_RXF0S_F0FL_MASK (0x7f << MCAN_RXF0S_F0FL_SHIFT) +# define MCAN_RXF0S_F0FL(n) ((uint32_t)(n) << MCAN_RXF0S_F0FL_SHIFT) +#define MCAN_RXF0S_F0GI_SHIFT (8) /* Bits 8-13: Receive FIFO 0 Get Index */ +#define MCAN_RXF0S_F0GI_MASK (0x3f << MCAN_RXF0S_F0GI_SHIFT) +# define MCAN_RXF0S_F0GI(n) ((uint32_t)(n) << MCAN_RXF0S_F0GI_SHIFT) +#define MCAN_RXF0S_F0PI_SHIFT (16) /* Bits 16-21: Receive FIFO 0 Put Index */ +#define MCAN_RXF0S_F0PI_MASK (0x3f << MCAN_RXF0S_F0PI_SHIFT) +# define MCAN_RXF0S_F0PI(n) ((uint32_t)(n) << MCAN_RXF0S_F0PI_SHIFT) +#define MCAN_RXF0S_F0F (1 << 24) /* Bit 24: Receive FIFO 0 Full */ +#define MCAN_RXF0S_RF0L (1 << 25) /* Bit 25: Receive FIFO 0 Message Lost */ + +/* Receive FIFO 0 Acknowledge Register */ + +#define MCAN_RXF0A_MASK 0x0000003f /* Receive FIFO 0 acknowledge index mask */ + +/* Receive Rx Buffer Configuration Register */ + +#define MCAN_RXBC_MASK 0x0000fffc /* Receive buffer start address mask */ + +/* Receive FIFO 1 Configuration Register */ + +#define MCAN_RXF1C_F1SA_SHIFT (2) /* Bits 2-15: Receive FIFO 1 Start Address */ +#define MCAN_RXF1C_F1SA_MASK (0x3fff << MCAN_RXF1C_F1SA_SHIFT) +# define MCAN_RXF1C_F1SA(n) ((uint32_t)(n) << MCAN_RXF1C_F1SA_SHIFT) +#define MCAN_RXF1C_F1S_SHIFT (16) /* Bits 16-22: Receive FIFO 1 Size */ +#define MCAN_RXF1C_F1S_MASK (0x7f << MCAN_RXF1C_F1S_SHIFT) +# define MCAN_RXF1C_F1S(n) ((uint32_t)(n) << MCAN_RXF1C_F1S_SHIFT) +#define MCAN_RXF1C_F1WM_SHIFT (24) /* Bits 24-30: Receive FIFO 1 Watermark */ +#define MCAN_RXF1C_F1WM_MASK (0x7f << MCAN_RXF1C_F1WM_SHIFT) +# define MCAN_RXF1C_F1WM(n) ((uint32_t)(n) << MCAN_RXF1C_F1WM_SHIFT) +#define MCAN_RXF1C_F1OM (1 << 31) /* Bit 31: FIFO 1 Operation Mode */ + +/* Receive FIFO 1 Status Register */ + +#define MCAN_RXF1S_F1FL_SHIFT (0) /* Bits 0-6: Receive FIFO 1 Fill Level */ +#define MCAN_RXF1S_F1FL_MASK (0x7f << MCAN_RXF1S_F1FL_SHIFT) +# define MCAN_RXF1S_F1FL(n) ((uint32_t)(n) << MCAN_RXF1S_F1FL_SHIFT) +#define MCAN_RXF1S_F1GI_SHIFT (8) /* Bits 8-13: Receive FIFO 1 Get Index */ +#define MCAN_RXF1S_F1GI_MASK (0x3f << MCAN_RXF1S_F1GI_SHIFT) +# define MCAN_RXF1S_F1GI(n) ((uint32_t)(n) << MCAN_RXF1S_F1GI_SHIFT) +#define MCAN_RXF1S_F1PI_SHIFT (16) /* Bits 16-21: Receive FIFO 1 Put Index */ +#define MCAN_RXF1S_F1PI_MASK (0x3f << MCAN_RXF1S_F1PI_SHIFT) +# define MCAN_RXF1S_F1PI(n) ((uint32_t)(n) << MCAN_RXF1S_F1PI_SHIFT) +#define MCAN_RXF1S_F1F (1 << 24) /* Bit 24: Receive FIFO 1 Full */ +#define MCAN_RXF1S_RF1L (1 << 25) /* Bit 25: Receive FIFO 1 Message Lost */ +#define MCAN_RXF1S_DMS_SHIFT (30) /* Bits 30-31: Debug Message Status */ +#define MCAN_RXF1S_DMS_MASK (3 << MCAN_RXF1S_DMS_SHIFT) +# define MCAN_RXF1S_DMS_IDLE (0 << MCAN_RXF1S_DMS_SHIFT) /* Idle state */ +# define MCAN_RXF1S_DMS_MSG_A (1 << MCAN_RXF1S_DMS_SHIFT) /* Debug message A received. */ +# define MCAN_RXF1S_DMS_MSG_AB (2 << MCAN_RXF1S_DMS_SHIFT) /* Debug messages A, B received. */ +# define MCAN_RXF1S_DMS_MSG_ABC (3 << MCAN_RXF1S_DMS_SHIFT) /* Debug messages A, B, C received, DMA request is set. */ + +/* Receive FIFO 1 Acknowledge Register */ + +#define MCAN_RXF1A_MASK 0x0000003f /* Receive FIFO 1 acknowledge index mask */ + +/* Receive Buffer / FIFO Element Size Configuration Register */ + +#define MCAN_RXESC_F0DS_SHIFT (0) /* Bits 0-2: Receive FIFO 0 Data Field Size */ +#define MCAN_RXESC_F0DS_MASK (7 << MCAN_RXESC_F0DS_SHIFT) +# define MCAN_RXESC_F0DS(n) ((uint32_t)(n) << MCAN_RXESC_F0DS_SHIFT) +# define MCAN_RXESC_F0DS_8B (0 << MCAN_RXESC_F0DS_SHIFT) /* 8-byte data field */ +# define MCAN_RXESC_F0DS_12B (1 << MCAN_RXESC_F0DS_SHIFT) /* 12-byte data field */ +# define MCAN_RXESC_F0DS_16B (2 << MCAN_RXESC_F0DS_SHIFT) /* 16-byte data field */ +# define MCAN_RXESC_F0DS_20B (3 << MCAN_RXESC_F0DS_SHIFT) /* 20-byte data field */ +# define MCAN_RXESC_F0DS_24B (4 << MCAN_RXESC_F0DS_SHIFT) /* 24-byte data field */ +# define MCAN_RXESC_F0DS_32B (5 << MCAN_RXESC_F0DS_SHIFT) /* 32-byte data field */ +# define MCAN_RXESC_F0DS_48B (6 << MCAN_RXESC_F0DS_SHIFT) /* 48-byte data field */ +# define MCAN_RXESC_F0DS_64B (7 << MCAN_RXESC_F0DS_SHIFT) /* 64-byte data field */ +#define MCAN_RXESC_F1DS_SHIFT (4) /* Bits 4-6: Receive FIFO 1 Data Field Size */ +#define MCAN_RXESC_F1DS_MASK (7 << MCAN_RXESC_F1DS_SHIFT) +# define MCAN_RXESC_F1DS(n) ((uint32_t)(n) << MCAN_RXESC_F1DS_SHIFT) +# define MCAN_RXESC_F1DS_8B (0 << MCAN_RXESC_F1DS_SHIFT) /* 8-byte data field */ +# define MCAN_RXESC_F1DS_12B (1 << MCAN_RXESC_F1DS_SHIFT) /* 12-byte data field */ +# define MCAN_RXESC_F1DS_16B (2 << MCAN_RXESC_F1DS_SHIFT) /* 16-byte data field */ +# define MCAN_RXESC_F1DS_20B (3 << MCAN_RXESC_F1DS_SHIFT) /* 20-byte data field */ +# define MCAN_RXESC_F1DS_24B (4 << MCAN_RXESC_F1DS_SHIFT) /* 24-byte data field */ +# define MCAN_RXESC_F1DS_32B (5 << MCAN_RXESC_F1DS_SHIFT) /* 32-byte data field */ +# define MCAN_RXESC_F1DS_48B (6 << MCAN_RXESC_F1DS_SHIFT) /* 48-byte data field */ +# define MCAN_RXESC_F1DS_64B (7 << MCAN_RXESC_F1DS_SHIFT) /* 64-byte data field */ +#define MCAN_RXESC_RBDS_SHIFT (8) /* Bits 8-10: Receive Buffer Data Field Size */ +#define MCAN_RXESC_RBDS_MASK (7 << MCAN_RXESC_RBDS_SHIFT) +# define MCAN_RXESC_RBDS(n) ((uint32_t)(n) << MCAN_RXESC_RBDS_SHIFT) +# define MCAN_RXESC_RBDS_8B (0 << MCAN_RXESC_RBDS_SHIFT) /* 8-byte data field */ +# define MCAN_RXESC_RBDS_12B (1 << MCAN_RXESC_RBDS_SHIFT) /* 12-byte data field */ +# define MCAN_RXESC_RBDS_16B (2 << MCAN_RXESC_RBDS_SHIFT) /* 16-byte data field */ +# define MCAN_RXESC_RBDS_20B (3 << MCAN_RXESC_RBDS_SHIFT) /* 20-byte data field */ +# define MCAN_RXESC_RBDS_24B (4 << MCAN_RXESC_RBDS_SHIFT) /* 24-byte data field */ +# define MCAN_RXESC_RBDS_32B (5 << MCAN_RXESC_RBDS_SHIFT) /* 32-byte data field */ +# define MCAN_RXESC_RBDS_48B (6 << MCAN_RXESC_RBDS_SHIFT) /* 48-byte data field */ +# define MCAN_RXESC_RBDS_64B (7 << MCAN_RXESC_RBDS_SHIFT) /* 64-byte data field */ + +/* Transmit Buffer Configuration Register */ + +#define MCAN_TXBC_TBSA_SHIFT (2) /* Bits 2-15: Tx Buffers Start Address */ +#define MCAN_TXBC_TBSA_MASK (0x3fff << MCAN_TXBC_TBSA_SHIFT) +# define MCAN_TXBC_TBSA(n) ((uint32_t)(n) << MCAN_TXBC_TBSA_SHIFT) +#define MCAN_TXBC_NDTB_SHIFT (16) /* Bits 16-21: Number of Dedicated Transmit Buffers */ +#define MCAN_TXBC_NDTB_MASK (0x3f << MCAN_TXBC_NDTB_SHIFT) +# define MCAN_TXBC_NDTB(n) ((uint32_t)(n) << MCAN_TXBC_NDTB_SHIFT) +#define MCAN_TXBC_TFQS_SHIFT (24) /* Bits 24-29: Transmit FIFO/Queue Size */ +#define MCAN_TXBC_TFQS_MASK (0x3f << MCAN_TXBC_TFQS_SHIFT) +# define MCAN_TXBC_TFQS(n) ((uint32_t)(n) << MCAN_TXBC_TFQS_SHIFT) +#define MCAN_TXBC_TFQM (1 << 30) /* Bit 30: Tx FIFO/Queue Mode */ + +/* Transmit FIFO/Queue Status Register */ + +#define MCAN_TXFQS_TFFL_SHIFT (0) /* Bits 0-5: Tx FIFO Free Level */ +#define MCAN_TXFQS_TFFL_MASK (0x3f << MCAN_TXFQS_TFFL_SHIFT) +# define MCAN_TXFQS_TFFL(n) ((uint32_t)(n) << MCAN_TXFQS_TFFL_SHIFT) +#define MCAN_TXFQS_TFGI_SHIFT (8) /* Bits 8-12: Tx FIFO Get Index */ +#define MCAN_TXFQS_TFGI_MASK (0x1f << MCAN_TXFQS_TFGI_SHIFT) +# define MCAN_TXFQS_TFGI(n) ((uint32_t)(n) << MCAN_TXFQS_TFGI_SHIFT) +#define MCAN_TXFQS_TFQPI_SHIFT (16) /* Bits 16-20: Tx FIFO/Queue Put Index */ +#define MCAN_TXFQS_TFQPI_MASK (0x1f << MCAN_TXFQS_TFQPI_SHIFT) +# define MCAN_TXFQS_TFQPI(n) ((uint32_t)(n) << MCAN_TXFQS_TFQPI_SHIFT) +#define MCAN_TXFQS_TFQF (1 << 21) /* Bit 21: Tx FIFO/Queue Full */ + +/* Transmit Buffer Element Size Configuration Register */ + +#define MCAN_TXESC_TBDS_SHIFT (0) /* Bits 0-2: Tx Buffer Data Field Size */ +#define MCAN_TXESC_TBDS_MASK (7 << MCAN_TXESC_TBDS_SHIFT) +# define MCAN_TXESC_TBDS(n) ((uint32_t)(n) << MCAN_TXESC_TBDS_SHIFT) +# define MCAN_TXESC_TBDS_8B (0 << MCAN_TXESC_TBDS_SHIFT) /* 8-byte data field */ +# define MCAN_TXESC_TBDS_12B (1 << MCAN_TXESC_TBDS_SHIFT) /* 12-byte data field */ +# define MCAN_TXESC_TBDS_16B (2 << MCAN_TXESC_TBDS_SHIFT) /* 16-byte data field */ +# define MCAN_TXESC_TBDS_20B (3 << MCAN_TXESC_TBDS_SHIFT) /* 20-byte data field */ +# define MCAN_TXESC_TBDS_24B (4 << MCAN_TXESC_TBDS_SHIFT) /* 24-byte data field */ +# define MCAN_TXESC_TBDS_32B (5 << MCAN_TXESC_TBDS_SHIFT) /* 32-byte data field */ +# define MCAN_TXESC_TBDS_48B (6 << MCAN_TXESC_TBDS_SHIFT) /* 48-byte data field */ +# define MCAN_TXESC_TBDS_64B (7 << MCAN_TXESC_TBDS_SHIFT) /* 64-byte data field */ + +/* Transmit Buffer Request Pending Register */ + +#define MCAN_TXBRP(n) (1 << (n)) /* Transmission request pending for buffer n, n=0-31 */ + +/* Transmit Buffer Add Request Register */ + +#define MCAN_TXBAR(n) (1 << (n)) /* Add request for transmit buffer n, n=0-31 */ + +/* Transmit Buffer Cancellation Request Register */ + +#define MCAN_TXBCR(n) (1 << (n)) /* Cancellation request for transmit buffer n, n=0-31 */ + +/* Transmit Buffer Transmission Occurred Register */ + +#define MCAN_TXBTO(n) (1 << (n)) /* Transmission occurred for buffer n, n=0-31 */ + +/* Transmit Buffer Cancellation Finished Register */ + +#define MCAN_TXBCF(n) (1 << (n)) /* Cancellation finished for transmit buffer n, n=0-31 */ + +/* Transmit Buffer Transmission Interrupt Enable Register */ + +#define MCAN_TXBTIE(n) (1 << (n)) /* Transmission interrupt enable for buffer n, n=0-31 */ + +/* Transmit Buffer Cancellation Finished Interrupt Enable Register */ + +#define MCAN_TXBTIE(n) (1 << (n)) /* Cancellation finished interrupt enable for transmit buffer n, n=0-31 */ + +/* Transmit Event FIFO Configuration Register */ + +#define MCAN_TXEFC_EFSA_SHIFT (2) /* Bits 2-15: Event FIFO Start Address */ +#define MCAN_TXEFC_EFSA_MASK (0x3fff << MCAN_TXEFC_EFSA_SHIFT) +# define MCAN_TXEFC_EFSA(n) ((uint32_t)(n) << MCAN_TXEFC_EFSA_SHIFT) +#define MCAN_TXEFC_EFS_SHIFT (16) /* Bits 16-21: Event FIFO Size */ +#define MCAN_TXEFC_EFS_MASK (0x3f << MCAN_TXEFC_EFS_SHIFT) +# define MCAN_TXEFC_EFS(n) ((uint32_t)(n) << MCAN_TXEFC_EFS_SHIFT) +#define MCAN_TXEFC_EFWM_SHIFT (24) /* Bits 24-29: Event FIFO Watermark */ +#define MCAN_TXEFC_EFWM_MASK (0x3f << MCAN_TXEFC_EFWM_SHIFT) +# define MCAN_TXEFC_EFWM(n) ((uint32_t)(n) << MCAN_TXEFC_EFWM_SHIFT) + +/* Transmit Event FIFO Status Register */ + +#define MCAN_TXEFS_EFFL_SHIFT (0) /* Bits 0-5: Event FIFO Fill Level */ +#define MCAN_TXEFS_EFFL_MASK (0x3f << MCAN_TXEFS_EFFL_SHIFT) +# define MCAN_TXEFS_EFFL(n) ((uint32_t)(n) << MCAN_TXEFS_EFFL_SHIFT) +#define MCAN_TXEFS_EFGI_SHIFT (8) /* Bits 8-12: Event FIFO Get Index */ +#define MCAN_TXEFS_EFGI_MASK (0x1f << MCAN_TXEFS_EFGI_SHIFT) +# define MCAN_TXEFS_EFGI(n) ((uint32_t)(n) << MCAN_TXEFS_EFGI_SHIFT) +#define MCAN_TXEFS_EFPI_SHIFT (16) /* Bits 16-20: Event FIFO Put Index */ +#define MCAN_TXEFS_EFPI_MASK (0x1f << MCAN_TXEFS_EFPI_SHIFT) +# define MCAN_TXEFS_EFPI(n) ((uint32_t)(n) << MCAN_TXEFS_EFPI_SHIFT) +#define MCAN_TXEFS_EFF (1 << 24) /* Bit 24: Event FIFO Full */ +#define MCAN_TXEFS_TEFL (1 << 25) /* Bit 25: Tx Event FIFO Element Lost */ + +/* Transmit Event FIFO Acknowledge Register */ + +#define MCAN_TXEFA_MASK 0x0000001f /* Event fifo acknowledge index mask */ + +/* Message RAM Definitions **************************************************************/ +/* Common Buffer and FIFO element bit definitions: + * + * --------------- ------------------- -------------------------------- + * RESOURCE R0 R1 + * --------------- ------------------- -------------------------------- + * RX Buffer: ESI, XTD, RTR, ID, ANMF, FIDX, EDL, BRS, DLC, RXTS + * RX FIFO: ESI, XTD, RTR, ID, ANMF, FIDX, EDL, BRS, DLC, RXTS + * TX buffer: XTD, RTR, ID, MM, EFC, DLC + * TX Event FIFO: ESI, XTD, RTR, ID, MM, ET, EDL, BRS, DLC, TXTS + * --------------- ------------------- -------------------------------- + */ + +/* Common */ + +#define BUFFER_R0_EXTID_SHIFT (0) /* Bits 0-28: Extended identifer */ +#define BUFFER_R0_EXTID_MASK (0x1fffffff << BUFFER_R0_EXTID_SHIFT) +# define BUFFER_R0_EXTID(n) ((uint32_t)(n) << BUFFER_R0_EXTID_SHIFT) +#define BUFFER_R0_STDID_SHIFT (18) /* Bits 18-28: Standard idendifier */ +#define BUFFER_R0_STDID_MASK (0x7ff << BUFFER_R0_STDID_SHIFT) +# define BUFFER_R0_STDID(n) ((uint32_t)(n) << BUFFER_R0_STDID_SHIFT) +#define BUFFER_R0_RTR (1 << 29) /* Bit 29: Remote Transmission Request */ +#define BUFFER_R0_XTD (1 << 30) /* Bit 30: Extended Identifier */ +#define BUFFER_R0_ESI (1 << 31) /* Bit 31: Error State Indicator */ + +/* Common */ + +#define BUFFER_R1_DLC_SHIFT (16) /* Bits 16-19: Date length code */ +#define BUFFER_R1_DLC_MASK (15 << BUFFER_R1_DLC_SHIFT) +# define BUFFER_R1_DLC(n) ((uint32_t)(n) << BUFFER_R1_DLC_SHIFT) +#define BUFFER_R1_BRS (1 << 20) /* Bit 20: Bit Rate Switch */ +#define BUFFER_R1_EDL (1 << 21) /* Bit 21: Extended Data Length */ + +/* RX buffer/RX FIFOs */ + +#define BUFFER_R1_RXTS_SHIFT (0) /* Bits 0-15: RX Timestamp */ +#define BUFFER_R1_RXTS_MASK (0xffff << BUFFER_R1_RXTS_SHIFT) +# define BUFFER_R1_RXTS(n) ((uint32_t)(n) << BUFFER_R1_RXTS_SHIFT) +#define BUFFER_R1_FIDX_SHIFT (24) /* Bits 24-30: Filter index */ +#define BUFFER_R1_FIDX_MASK (0x7f << BUFFER_R1_FIDX_SHIFT) +# define BUFFER_R1_FIDX(n) ((uint32_t)(n) << BUFFER_R1_FIDX_SHIFT) +#define BUFFER_R1_ANMF (1 << 31) /* Bit 31: Accepted Non-matching Frame */ + +/* TX buffer/TX Event FIFO */ + +#define BUFFER_R1_MM_SHIFT (24) /* Bits 24-31: Message Marker */ +#define BUFFER_R1_MM_MASK (0xffff << BUFFER_R1_MM_SHIFT) +# define BUFFER_R1_MM(n) ((uint32_t)(n) << BUFFER_R1_MM_SHIFT) + +/* TX buffer */ + +#define BUFFER_R1_EFC (1 << 23) /* Bit 23: Event FIFO Control */ + +/* TX Event FIFO */ + +#define BUFFER_R1_TXTS_SHIFT (0) /* Bits 0-15: TX Timestamp */ +#define BUFFER_R1_TXTS_MASK (0xffff << BUFFER_R1_TXTS_SHIFT) +# define BUFFER_R1_TXTS(n) ((uint32_t)(n) << BUFFER_R1_TXTS_SHIFT) +#define BUFFER_R1_ET_SHIFT (22) /* Bits 22-23: Event Type */ +#define BUFFER_R1_ET_MASK (15 << BUFFER_R1_ET_SHIFT) +# define BUFFER_R1_ET_TXEVENT (1 << BUFFER_R1_ET_SHIFT) /* Tx event */ +# define BUFFER_R1_ET_TXCANCEL (2 << BUFFER_R1_ET_SHIFT) /* Transmission despite cancellation */ + +/* Standard Message ID Filter Element */ + +#define STDFILTER_S0_SFID2_SHIFT (0) /* Bits 0-10: Standard Filter ID 2 */ +#define STDFILTER_S0_SFID2_MASK (0x3ff << STDFILTER_S0_SFID2_SHIFT) +# define STDFILTER_S0_SFID2(n) ((uint32_t)(n) << STDFILTER_S0_SFID2_SHIFT) +#define STDFILTER_S0_BUFFER_SHIFT (0) /* Bits 0-5: RX buffer start address */ +#define STDFILTER_S0_BUFFER_MASK (0x3f << STDFILTER_S0_BUFFER_SHIFT) +# define STDFILTER_S0_BUFFER(n) ((uint32_t)(n) << STDFILTER_S0_BUFFER_SHIFT) +#define STDFILTER_S0_ACTION_SHIFT (9) /* Bits 9-10: Action taken */ +#define STDFILTER_S0_ACTION_MASK (3 << STDFILTER_S0_ACTION_SHIFT) +# define STDFILTER_S0_RXBUFFER (0 << STDFILTER_S0_ACTION_SHIFT) /* Store message in a Rx buffer */ +# define STDFILTER_S0_DEBUGA (1 << STDFILTER_S0_ACTION_SHIFT) /* Debug Message A */ +# define STDFILTER_S0_DEBUGB (2 << STDFILTER_S0_ACTION_SHIFT) /* Debug Message B */ +# define STDFILTER_S0_DEBUGC (3 << STDFILTER_S0_ACTION_SHIFT) /* Debug Message C */ +#define STDFILTER_S0_SFID1_SHIFT (16) /* Bits 16-26: Standard Filter ID 2 */ +#define STDFILTER_S0_SFID1_MASK (0x3ff << STDFILTER_S0_SFID1_SHIFT) +# define STDFILTER_S0_SFID1(n) ((uint32_t)(n) << STDFILTER_S0_SFID1_SHIFT) +#define STDFILTER_S0_SFEC_SHIFT (17) /* Bits 27-29: Standard Filter Element Configuration */ +#define STDFILTER_S0_SFEC_MASK (7 << STDFILTER_S0_SFEC_SHIFT) +# define STDFILTER_S0_SFEC_DISABLE (0 << STDFILTER_S0_SFEC_SHIFT) /* Disable filter element */ +# define STDFILTER_S0_SFEC_FIFO0 (1 << STDFILTER_S0_SFEC_SHIFT) /* Store in Rx FIFO 0 on match */ +# define STDFILTER_S0_SFEC_FIFO1 (2 << STDFILTER_S0_SFEC_SHIFT) /* Store in Rx FIFO 1 on match */ +# define STDFILTER_S0_SFEC_REJECT (3 << STDFILTER_S0_SFEC_SHIFT) /* Reject ID on match */ +# define STDFILTER_S0_SFEC_PRIORITY (4 << STDFILTER_S0_SFEC_SHIFT) /* Set priority ion match */ +# define STDFILTER_S0_SFEC_PRIOFIFO0 (5 << STDFILTER_S0_SFEC_SHIFT) /* Set priority and store in FIFO 0 on match */ +# define STDFILTER_S0_SFEC_PRIOFIFO1 (6 << STDFILTER_S0_SFEC_SHIFT) /* Set priority and store in FIFO 1 on match */ +# define STDFILTER_S0_SFEC_BUFFER (7 << STDFILTER_S0_SFEC_SHIFT) /* Store into Rx Buffer or as debug message */ +#define STDFILTER_S0_SFT_SHIFT (30) /* Bits 30-31: Standard Filter Type */ +#define STDFILTER_S0_SFT_MASK (3 << STDFILTER_S0_SFT_SHIFT) +# define STDFILTER_S0_SFT_RANGE (0 << STDFILTER_S0_SFT_SHIFT) /* Range filter from SF1ID to SF2ID */ +# define STDFILTER_S0_SFT_DUAL (1 << STDFILTER_S0_SFT_SHIFT) /* Dual ID filter for SF1ID or SF2ID */ +# define STDFILTER_S0_SFT_CLASSIC (2 << STDFILTER_S0_SFT_SHIFT) /* Classic filter: SF1ID=filter SF2ID=mask */ + +/* Extended Message ID Filter Element */ + +#define EXTFILTER_F0_EFID1_SHIFT (0) /* Bits 0-28: Extended Filter ID 1 */ +#define EXTFILTER_F0_EFID1_MASK (0x1fffffff << EXTFILTER_F0_EFID1_SHIFT) +# define EXTFILTER_F0_EFID1(n) ((uint32_t)(n) << EXTFILTER_F0_EFID1_SHIFT) +#define EXTFILTER_F0_EFEC_SHIFT (29) /* Bits 29-31: Extended Filter Element Configuration */ +#define EXTFILTER_F0_EFEC_MASK (7 << EXTFILTER_F0_EFEC_SHIFT) +# define EXTFILTER_F0_EFEC_DISABLE (0 << EXTFILTER_F0_EFEC_SHIFT) /* Disable filter element */ +# define EXTFILTER_F0_EFEC_FIFO0 (1 << EXTFILTER_F0_EFEC_SHIFT) /* Store in Rx FIFO 0 on match */ +# define EXTFILTER_F0_EFEC_FIFO1 (2 << EXTFILTER_F0_EFEC_SHIFT) /* Store in Rx FIFO 1 on match */ +# define EXTFILTER_F0_EFEC_REJECT (3 << EXTFILTER_F0_EFEC_SHIFT) /* Reject ID on match */ +# define EXTFILTER_F0_EFEC_PRIORITY (4 << EXTFILTER_F0_EFEC_SHIFT) /* Set priority on match */ +# define EXTFILTER_F0_EFEC_PRIOFIFO0 (5 << EXTFILTER_F0_EFEC_SHIFT) /* Set priority and store in FIFO 0 on match */ +# define EXTFILTER_F0_EFEC_PRIOFIFO1 (6 << EXTFILTER_F0_EFEC_SHIFT) /* Set priority and store in FIFO 1 on match */ +# define EXTFILTER_F0_EFEC_BUFFER (7 << EXTFILTER_F0_EFEC_SHIFT) /* Store into Rx Buffer or as debug message */ + +#define EXTFILTER_F1_EFID2_SHIFT (0) /* Bits 0-28: Extended Filter ID 2 */ +#define EXTFILTER_F1_EFID2_MASK (0x1fffffff << EXTFILTER_F1_EFID2_SHIFT) +# define EXTFILTER_F1_EFID2(n) ((uint32_t)(n) << EXTFILTER_F1_EFID2_SHIFT) +#define EXTFILTER_F1_BUFFER_SHIFT (0) /* Bits 0-5: RX buffer start address */ +#define EXTFILTER_F1_BUFFER_MASK (0x3f << EXTFILTER_F1_BUFFER_SHIFT) +# define EXTFILTER_F1_BUFFER(n) ((uint32_t)(n) << EXTFILTER_F1_BUFFER_SHIFT) +#define EXTFILTER_F1_ACTION_SHIFT (9) /* Bits 9-10: Action taken */ +#define EXTFILTER_F1_ACTION_MASK (3 << EXTFILTER_F1_ACTION_SHIFT) +# define EXTFILTER_F1_RXBUFFER (0 << EXTFILTER_F1_ACTION_SHIFT) /* Store message in a Rx buffer */ +# define EXTFILTER_F1_DEBUGA (1 << EXTFILTER_F1_ACTION_SHIFT) /* Debug Message A */ +# define EXTFILTER_F1_DEBUGB (2 << EXTFILTER_F1_ACTION_SHIFT) /* Debug Message B */ +# define EXTFILTER_F1_DEBUGC (3 << EXTFILTER_F1_ACTION_SHIFT) /* Debug Message C */ +#define EXTFILTER_F1_EFT_SHIFT (30) /* Bits 30-31: Extended Filter Type */ +#define EXTFILTER_F1_EFT_MASK (3 << EXTFILTER_F1_EFT_SHIFT) +# define EXTFILTER_F1_EFT_RANGE (0 << EXTFILTER_F1_EFT_SHIFT) /* Range filter from SF1ID to SF2ID */ +# define EXTFILTER_F1_EFT_DUAL (1 << EXTFILTER_F1_EFT_SHIFT) /* Dual ID filter for SF1ID or SF2ID */ +# define EXTFILTER_F1_EFT_CLASSIC (2 << EXTFILTER_F1_EFT_SHIFT) /* Classic filter: SF1ID=filter SF2ID=mask */ +# define EXTFILTER_F1_EFT_NOXIDAM (2 << EXTFILTER_F1_EFT_SHIFT) /* Range filter from EF1ID to EF2ID, no XIDAM */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MCAN_H */ diff --git a/arch/arm/src/samv7/chip/sam_memorymap.h b/arch/arm/src/samv7/chip/sam_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..e3849a8500f9df76abbbb66c2f636282f95d8036 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_memorymap.h @@ -0,0 +1,53 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_SAMV71) +# include "chip/samv71_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_SAME70) +# include "chip/same70_memorymap.h" +#else +# error Unrecognized SAMV7 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_MEMORYMAP_H */ diff --git a/arch/arm/src/samv7/chip/sam_pinmap.h b/arch/arm/src/samv7/chip/sam_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..f0edd2218ea57e36b0a6a49c59c27f1b1c22314f --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_pinmap.h @@ -0,0 +1,54 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_pinmap.h + * + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PINMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_SAMV71) +# include "chip/samv71_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_SAME70) +# include "chip/same70_pinmap.h" +#else +# error Unrecognized SAMV7 architecture +#endif + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PINMAP_H */ + diff --git a/arch/arm/src/samv7/chip/sam_pio.h b/arch/arm/src/samv7/chip/sam_pio.h new file mode 100644 index 0000000000000000000000000000000000000000..29a415eb4104f46d78420cee19fe4264e961e324 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_pio.h @@ -0,0 +1,594 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam4e_pio.h + * Parallel Input/Output (PIO) Controller definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM4E_PIO_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM4E_PIO_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NPIO > 0 + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* Configuration ************************************************************************/ + +#define GPIO_HAVE_PULLDOWN 1 +#define GPIO_HAVE_PERIPHCD 1 +#define GPIO_HAVE_SCHMITT 1 +#undef GPIO_HAVE_DELAYR +#define GPIO_HAVE_DRIVER 1 +#define GPIO_HAVE_KEYPAD 1 + +/* Misc Helper Definitions **************************************************************/ + +#define PIOA (0) +#define PIOB (1) +#define PIOC (2) +#define PIOD (3) +#define PIOE (4) + +/* PIO register offsets *****************************************************************/ + +#define SAM_PIO_PER_OFFSET 0x0000 /* PIO Enable Register */ +#define SAM_PIO_PDR_OFFSET 0x0004 /* PIO Disable Register */ +#define SAM_PIO_PSR_OFFSET 0x0008 /* PIO Status Register */ + /* 0x000c: Reserved */ +#define SAM_PIO_OER_OFFSET 0x0010 /* Output Enable Register */ +#define SAM_PIO_ODR_OFFSET 0x0014 /* Output Disable Register */ +#define SAM_PIO_OSR_OFFSET 0x0018 /* Output Status Register */ + /* 0x001c: Reserved */ +#define SAM_PIO_IFER_OFFSET 0x0020 /* Glitch Input Filter Enable Register */ +#define SAM_PIO_IFDR_OFFSET 0x0024 /* Glitch Input Filter Disable Register */ +#define SAM_PIO_IFSR_OFFSET 0x0028 /* Glitch Input Filter Status Register */ + /* 0x002c: Reserved */ +#define SAM_PIO_SODR_OFFSET 0x0030 /* Set Output Data Register */ +#define SAM_PIO_CODR_OFFSET 0x0034 /* Clear Output Data Register */ +#define SAM_PIO_ODSR_OFFSET 0x0038 /* Output Data Status Register */ +#define SAM_PIO_PDSR_OFFSET 0x003c /* Pin Data Status Register */ +#define SAM_PIO_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define SAM_PIO_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define SAM_PIO_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define SAM_PIO_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define SAM_PIO_MDER_OFFSET 0x0050 /* Multi-driver Enable Register */ +#define SAM_PIO_MDDR_OFFSET 0x0054 /* Multi-driver Disable Register */ +#define SAM_PIO_MDSR_OFFSET 0x0058 /* Multi-driver Status Register */ + /* 0x005c: Reserved */ +#define SAM_PIO_PUDR_OFFSET 0x0060 /* Pull-up Disable Register */ +#define SAM_PIO_PUER_OFFSET 0x0064 /* Pull-up Enable Register */ +#define SAM_PIO_PUSR_OFFSET 0x0068 /* Pad Pull-up Status Register */ + /* 0x006c: Reserved */ +#define SAM_PIO_ABCDSR1_OFFSET 0x0070 /* Peripheral Select Register 1 */ +#define SAM_PIO_ABCDSR2_OFFSET 0x0074 /* Peripheral Select Register 2 */ + /* 0x0078-0x007c: Reserved */ +#define SAM_PIO_IFSCDR_OFFSET 0x0080 /* Input Filter Slow Clock Disable Register */ +#define SAM_PIO_IFSCER_OFFSET 0x0084 /* Input Filter Slow Clock Enable Register */ +#define SAM_PIO_IFSCSR_OFFSET 0x0088 /* Input Filter Slow Clock Status Register */ +#define SAM_PIO_SCDR_OFFSET 0x008c /* Slow Clock Divider Debouncing Register */ +#define SAM_PIO_PPDDR_OFFSET 0x0090 /* Pad Pull Down Disable Register */ +#define SAM_PIO_PPDER_OFFSET 0x0094 /* PIO Pad Pull Down Enable Register */ +#define SAM_PIO_PPDSR_OFFSET 0x0098 /* PIO Pad Pull Down Status Register */ + /* 0x009c: Reserved */ +#define SAM_PIO_OWER_OFFSET 0x00a0 /* Output Write Enable */ +#define SAM_PIO_OWDR_OFFSET 0x00a4 /* Output Write Disable */ +#define SAM_PIO_OWSR_OFFSET 0x00a8 /* Output Write Status Register */ + /* 0x00ac: Reserved */ +#define SAM_PIO_AIMER_OFFSET 0x00b0 /* Additional Interrupt Modes Enable Register */ +#define SAM_PIO_AIMDR_OFFSET 0x00b4 /* Additional Interrupt Modes Disables Register */ +#define SAM_PIO_AIMMR_OFFSET 0x00b8 /* Additional Interrupt Modes Mask Register */ + /* 0x00bc: Reserved */ +#define SAM_PIO_ESR_OFFSET 0x00c0 /* Edge Select Register */ +#define SAM_PIO_LSR_OFFSET 0x00c4 /* Level Select Register */ +#define SAM_PIO_ELSR_OFFSET 0x00c8 /* Edge/Level Status Register */ + /* 0x00cc: Reserved */ +#define SAM_PIO_FELLSR_OFFSET 0x00d0 /* Falling Edge/Low Level Select Register */ +#define SAM_PIO_REHLSR_OFFSET 0x00d4 /* Rising Edge/ High Level Select Register */ +#define SAM_PIO_FRLHSR_OFFSET 0x00d8 /* Fall/Rise - Low/High Status Register */ + /* 0x00dc: Reserved */ +#define SAM_PIO_LOCKSR_OFFSET 0x00e0 /* Lock Status */ +#define SAM_PIO_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PIO_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00fc: Reserved */ +#define SAM_PIO_SCHMITT_OFFSET 0x0100 /* Schmitt Trigger Register */ + /* 0x0104-0x114: Reserved */ +#define SAM_PIO_DRIVER_OFFSET 0x0118 /* I/O Drive Register */ + /* 0x011c: Reserved */ +#define SAM_PIO_KER_OFFSET 0x0120 /* Keypad Controller Enable Register */ +#define SAM_PIO_KRCR_OFFSET 0x0124 /* Keypad Controller Row Column Register */ +#define SAM_PIO_KDR_OFFSET 0x0128 /* Keypad Controller Debouncing Register */ +#define SAM_PIO_KIER_OFFSET 0x0130 /* Keypad Controller Interrupt Enable Register */ +#define SAM_PIO_KIDR_OFFSET 0x0134 /* Keypad Controller Interrupt Disable Register */ +#define SAM_PIO_KIMR_OFFSET 0x0138 /* Keypad Controller Interrupt Mask Register */ +#define SAM_PIO_KSR_OFFSET 0x013c /* Keypad Controller Status Register */ +#define SAM_PIO_KKPR_OFFSET 0x0140 /* Keypad Controller Key Press Register */ +#define SAM_PIO_KKRR_OFFSET 0x0144 /* Keypad Controller Key Release Register */ + /* 0x0148-0x14c: Reserved */ +#define SAM_PIO_PCMR_OFFSET 0x0150 /* Parallel Capture Mode Register */ +#define SAM_PIO_PCIER_OFFSET 0x0154 /* Parallel Capture Interrupt Enable Register */ +#define SAM_PIO_PCIDR_OFFSET 0x0158 /* Parallel Capture Interrupt Disable Register */ +#define SAM_PIO_PCIMR_OFFSET 0x015c /* Parallel Capture Interrupt Mask Register */ +#define SAM_PIO_PCISR_OFFSET 0x0160 /* Parallel Capture Interrupt Status Register */ +#define SAM_PIO_PCRHR_OFFSET 0x0164 /* Parallel Capture Reception Holding Register */ + /* 0x0168-0x018c: Reserved for PDC registers */ + +/* PIO register addresses ***************************************************************/ + + +#define SAM_PIOA_PER (SAM_PIOA_BASE+SAM_PIO_PER_OFFSET) +#define SAM_PIOA_PDR (SAM_PIOA_BASE+SAM_PIO_PDR_OFFSET) +#define SAM_PIOA_PSR (SAM_PIOA_BASE+SAM_PIO_PSR_OFFSET) +#define SAM_PIOA_OER (SAM_PIOA_BASE+SAM_PIO_OER_OFFSET) +#define SAM_PIOA_ODR (SAM_PIOA_BASE+SAM_PIO_ODR_OFFSET) +#define SAM_PIOA_OSR (SAM_PIOA_BASE+SAM_PIO_OSR_OFFSET) +#define SAM_PIOA_IFER (SAM_PIOA_BASE+SAM_PIO_IFER_OFFSET) +#define SAM_PIOA_IFDR (SAM_PIOA_BASE+SAM_PIO_IFDR_OFFSET) +#define SAM_PIOA_IFSR (SAM_PIOA_BASE+SAM_PIO_IFSR_OFFSET) +#define SAM_PIOA_SODR (SAM_PIOA_BASE+SAM_PIO_SODR_OFFSET) +#define SAM_PIOA_CODR (SAM_PIOA_BASE+SAM_PIO_CODR_OFFSET) +#define SAM_PIOA_ODSR (SAM_PIOA_BASE+SAM_PIO_ODSR_OFFSET) +#define SAM_PIOA_PDSR (SAM_PIOA_BASE+SAM_PIO_PDSR_OFFSET) +#define SAM_PIOA_IER (SAM_PIOA_BASE+SAM_PIO_IER_OFFSET) +#define SAM_PIOA_IDR (SAM_PIOA_BASE+SAM_PIO_IDR_OFFSET) +#define SAM_PIOA_IMR (SAM_PIOA_BASE+SAM_PIO_IMR_OFFSET) +#define SAM_PIOA_ISR (SAM_PIOA_BASE+SAM_PIO_ISR_OFFSET) +#define SAM_PIOA_MDER (SAM_PIOA_BASE+SAM_PIO_MDER_OFFSET) +#define SAM_PIOA_MDDR (SAM_PIOA_BASE+SAM_PIO_MDDR_OFFSET) +#define SAM_PIOA_MDSR (SAM_PIOA_BASE+SAM_PIO_MDSR_OFFSET) +#define SAM_PIOA_PUDR (SAM_PIOA_BASE+SAM_PIO_PUDR_OFFSET) +#define SAM_PIOA_PUER (SAM_PIOA_BASE+SAM_PIO_PUER_OFFSET) +#define SAM_PIOA_PUSR (SAM_PIOA_BASE+SAM_PIO_PUSR_OFFSET) +#define SAM_PIOA_ABCDSR1 (SAM_PIOA_BASE+SAM_PIO_ABCDSR1_OFFSET) +#define SAM_PIOA_ABCDSR2 (SAM_PIOA_BASE+SAM_PIO_ABCDSR2_OFFSET) +#define SAM_PIOA_IFSCDR (SAM_PIOA_BASE+SAM_PIO_IFSCDR_OFFSET) +#define SAM_PIOA_IFSCER (SAM_PIOA_BASE+SAM_PIO_IFSCER_OFFSET) +#define SAM_PIOA_IFSCSR (SAM_PIOA_BASE+SAM_PIO_IFSCSR_OFFSET) +#define SAM_PIOA_SCDR (SAM_PIOA_BASE+SAM_PIO_SCDR_OFFSET) +#define SAM_PIOA_PPDDR (SAM_PIOA_BASE+SAM_PIO_PPDDR_OFFSET) +#define SAM_PIOA_PPDER (SAM_PIOA_BASE+SAM_PIO_PPDER_OFFSET) +#define SAM_PIOA_PPDSR (SAM_PIOA_BASE+SAM_PIO_PPDSR_OFFSET) +#define SAM_PIOA_OWER (SAM_PIOA_BASE+SAM_PIO_OWER_OFFSET) +#define SAM_PIOA_OWDR (SAM_PIOA_BASE+SAM_PIO_OWDR_OFFSET) +#define SAM_PIOA_OWSR (SAM_PIOA_BASE+SAM_PIO_OWSR_OFFSET) +#define SAM_PIOA_AIMER (SAM_PIOA_BASE+SAM_PIO_AIMER_OFFSET) +#define SAM_PIOA_AIMDR (SAM_PIOA_BASE+SAM_PIO_AIMDR_OFFSET) +#define SAM_PIOA_AIMMR (SAM_PIOA_BASE+SAM_PIO_AIMMR_OFFSET) +#define SAM_PIOA_ESR (SAM_PIOA_BASE+SAM_PIO_ESR_OFFSET) +#define SAM_PIOA_LSR (SAM_PIOA_BASE+SAM_PIO_LSR_OFFSET) +#define SAM_PIOA_ELSR (SAM_PIOA_BASE+SAM_PIO_ELSR_OFFSET) +#define SAM_PIOA_FELLSR (SAM_PIOA_BASE+SAM_PIO_FELLSR_OFFSET) +#define SAM_PIOA_REHLSR (SAM_PIOA_BASE+SAM_PIO_REHLSR_OFFSET) +#define SAM_PIOA_FRLHSR (SAM_PIOA_BASE+SAM_PIO_FRLHSR_OFFSET) +#define SAM_PIOA_LOCKSR (SAM_PIOA_BASE+SAM_PIO_LOCKSR_OFFSET) +#define SAM_PIOA_WPMR (SAM_PIOA_BASE+SAM_PIO_WPMR_OFFSET) +#define SAM_PIOA_WPSR (SAM_PIOA_BASE+SAM_PIO_WPSR_OFFSET) +#define SAM_PIOA_SCHMITT (SAM_PIOA_BASE+SAM_PIO_SCHMITT_OFFSET) +#define SAM_PIOA_DRIVER (SAM_PIOA_BASE+SAM_PIO_DRIVER_OFFSET) +#define SAM_PIOA_KER (SAM_PIOA_BASE+SAM_PIO_KER_OFFSET) +#define SAM_PIOA_KRCR (SAM_PIOA_BASE+SAM_PIO_KRCR_OFFSET) +#define SAM_PIOA_KDR (SAM_PIOA_BASE+SAM_PIO_KDR_OFFSET) +#define SAM_PIOA_KIER (SAM_PIOA_BASE+SAM_PIO_KIER_OFFSET) +#define SAM_PIOA_KIDR (SAM_PIOA_BASE+SAM_PIO_KIDR_OFFSET) +#define SAM_PIOA_KIMR (SAM_PIOA_BASE+SAM_PIO_KIMR_OFFSET) +#define SAM_PIOA_KSR (SAM_PIOA_BASE+SAM_PIO_KSR_OFFSET) +#define SAM_PIOA_KKPR (SAM_PIOA_BASE+SAM_PIO_KKPR_OFFSET) +#define SAM_PIOA_KKRR (SAM_PIOA_BASE+SAM_PIO_KKRR_OFFSET) +#define SAM_PIOA_PCMR (SAM_PIOA_BASE+SAM_PIO_PCMR_OFFSET) +#define SAM_PIOA_PCIER (SAM_PIOA_BASE+SAM_PIO_PCIER_OFFSET) +#define SAM_PIOA_PCIDR (SAM_PIOA_BASE+SAM_PIO_PCIDR_OFFSET) +#define SAM_PIOA_PCIMR (SAM_PIOA_BASE+SAM_PIO_PCIMR_OFFSET) +#define SAM_PIOA_PCISR (SAM_PIOA_BASE+SAM_PIO_PCISR_OFFSET) +#define SAM_PIOA_PCRHR (SAM_PIOA_BASE+SAM_PIO_PCRHR_OFFSET + +#if SAMV7_NPIO > 1 +# define SAM_PIOB_PER (SAM_PIOB_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOB_PDR (SAM_PIOB_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOB_PSR (SAM_PIOB_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOB_OER (SAM_PIOB_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOB_ODR (SAM_PIOB_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOB_OSR (SAM_PIOB_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOB_IFER (SAM_PIOB_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOB_IFDR (SAM_PIOB_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOB_IFSR (SAM_PIOB_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOB_SODR (SAM_PIOB_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOB_CODR (SAM_PIOB_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOB_ODSR (SAM_PIOB_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOB_PDSR (SAM_PIOB_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOB_IER (SAM_PIOB_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOB_IDR (SAM_PIOB_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOB_IMR (SAM_PIOB_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOB_ISR (SAM_PIOB_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOB_MDER (SAM_PIOB_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOB_MDDR (SAM_PIOB_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOB_MDSR (SAM_PIOB_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOB_PUDR (SAM_PIOB_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOB_PUER (SAM_PIOB_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOB_PUSR (SAM_PIOB_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOB_ABCDSR1 (SAM_PIOB_BASE+SAM_PIO_ABCDSR1_OFFSET) +# define SAM_PIOB_ABCDSR2 (SAM_PIOB_BASE+SAM_PIO_ABCDSR2_OFFSET) +# define SAM_PIOB_IFSCDR (SAM_PIOB_BASE+SAM_PIO_IFSCDR_OFFSET) +# define SAM_PIOB_IFSCER (SAM_PIOB_BASE+SAM_PIO_IFSCER_OFFSET) +# define SAM_PIOB_IFSCSR (SAM_PIOB_BASE+SAM_PIO_IFSCSR_OFFSET) +# define SAM_PIOB_SCDR (SAM_PIOB_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOB_PPDDR (SAM_PIOB_BASE+SAM_PIO_PPDDR_OFFSET) +# define SAM_PIOB_PPDER (SAM_PIOB_BASE+SAM_PIO_PPDER_OFFSET) +# define SAM_PIOB_PPDSR (SAM_PIOB_BASE+SAM_PIO_PPDSR_OFFSET) +# define SAM_PIOB_OWER (SAM_PIOB_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOB_OWDR (SAM_PIOB_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOB_OWSR (SAM_PIOB_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOB_AIMER (SAM_PIOB_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOB_AIMDR (SAM_PIOB_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOB_AIMMR (SAM_PIOB_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOB_ESR (SAM_PIOB_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOB_LSR (SAM_PIOB_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOB_ELSR (SAM_PIOB_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOB_FELLSR (SAM_PIOB_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOB_REHLSR (SAM_PIOB_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOB_FRLHSR (SAM_PIOB_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOB_LOCKSR (SAM_PIOB_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOB_WPMR (SAM_PIOB_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOB_WPSR (SAM_PIOB_BASE+SAM_PIO_WPSR_OFFSET) +# define SAM_PIOB_SCHMITT (SAM_PIOB_BASE+SAM_PIO_SCHMITT_OFFSET) +# define SAM_PIOB_DRIVER (SAM_PIOB_BASE+SAM_PIO_DRIVER_OFFSET) +# define SAM_PIOB_KER (SAM_PIOB_BASE+SAM_PIO_KER_OFFSET) +# define SAM_PIOB_KRCR (SAM_PIOB_BASE+SAM_PIO_KRCR_OFFSET) +# define SAM_PIOB_KDR (SAM_PIOB_BASE+SAM_PIO_KDR_OFFSET) +# define SAM_PIOB_KIER (SAM_PIOB_BASE+SAM_PIO_KIER_OFFSET) +# define SAM_PIOB_KIDR (SAM_PIOB_BASE+SAM_PIO_KIDR_OFFSET) +# define SAM_PIOB_KIMR (SAM_PIOB_BASE+SAM_PIO_KIMR_OFFSET) +# define SAM_PIOB_KSR (SAM_PIOB_BASE+SAM_PIO_KSR_OFFSET) +# define SAM_PIOB_KKPR (SAM_PIOB_BASE+SAM_PIO_KKPR_OFFSET) +# define SAM_PIOB_KKRR (SAM_PIOB_BASE+SAM_PIO_KKRR_OFFSET) +# define SAM_PIOB_PCMR (SAM_PIOB_BASE+SAM_PIO_PCMR_OFFSET) +# define SAM_PIOB_PCIER (SAM_PIOB_BASE+SAM_PIO_PCIER_OFFSET) +# define SAM_PIOB_PCIDR (SAM_PIOB_BASE+SAM_PIO_PCIDR_OFFSET) +# define SAM_PIOB_PCIMR (SAM_PIOB_BASE+SAM_PIO_PCIMR_OFFSET) +# define SAM_PIOB_PCISR (SAM_PIOB_BASE+SAM_PIO_PCISR_OFFSET) +# define SAM_PIOB_PCRHR (SAM_PIOB_BASE+SAM_PIO_PCRHR_OFFSET +#endif + +#if SAMV7_NPIO > 2 +# define SAM_PIOC_PER (SAM_PIOC_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOC_PDR (SAM_PIOC_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOC_PSR (SAM_PIOC_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOC_OER (SAM_PIOC_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOC_ODR (SAM_PIOC_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOC_OSR (SAM_PIOC_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOC_IFER (SAM_PIOC_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOC_IFDR (SAM_PIOC_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOC_IFSR (SAM_PIOC_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOC_SODR (SAM_PIOC_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOC_CODR (SAM_PIOC_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOC_ODSR (SAM_PIOC_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOC_PDSR (SAM_PIOC_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOC_IER (SAM_PIOC_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOC_IDR (SAM_PIOC_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOC_IMR (SAM_PIOC_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOC_ISR (SAM_PIOC_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOC_MDER (SAM_PIOC_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOC_MDDR (SAM_PIOC_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOC_MDSR (SAM_PIOC_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOC_PUDR (SAM_PIOC_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOC_PUER (SAM_PIOC_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOC_PUSR (SAM_PIOC_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOC_ABCDSR1 (SAM_PIOC_BASE+SAM_PIO_ABCDSR1_OFFSET) +# define SAM_PIOC_ABCDSR2 (SAM_PIOC_BASE+SAM_PIO_ABCDSR2_OFFSET) +# define SAM_PIOC_IFSCDR (SAM_PIOC_BASE+SAM_PIO_IFSCDR_OFFSET) +# define SAM_PIOC_IFSCER (SAM_PIOC_BASE+SAM_PIO_IFSCER_OFFSET) +# define SAM_PIOC_IFSCSR (SAM_PIOC_BASE+SAM_PIO_IFSCSR_OFFSET) +# define SAM_PIOC_SCDR (SAM_PIOC_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOC_PPDDR (SAM_PIOC_BASE+SAM_PIO_PPDDR_OFFSET) +# define SAM_PIOC_PPDER (SAM_PIOC_BASE+SAM_PIO_PPDER_OFFSET) +# define SAM_PIOC_PPDSR (SAM_PIOC_BASE+SAM_PIO_PPDSR_OFFSET) +# define SAM_PIOC_OWER (SAM_PIOC_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOC_OWDR (SAM_PIOC_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOC_OWSR (SAM_PIOC_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOC_AIMER (SAM_PIOC_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOC_AIMDR (SAM_PIOC_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOC_AIMMR (SAM_PIOC_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOC_ESR (SAM_PIOC_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOC_LSR (SAM_PIOC_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOC_ELSR (SAM_PIOC_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOC_FELLSR (SAM_PIOC_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOC_REHLSR (SAM_PIOC_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOC_FRLHSR (SAM_PIOC_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOC_LOCKSR (SAM_PIOC_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOC_WPMR (SAM_PIOC_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOC_WPSR (SAM_PIOC_BASE+SAM_PIO_WPSR_OFFSET) +# define SAM_PIOC_SCHMITT (SAM_PIOC_BASE+SAM_PIO_SCHMITT_OFFSET) +# define SAM_PIOC_DRIVER (SAM_PIOC_BASE+SAM_PIO_DRIVER_OFFSET) +# define SAM_PIOC_KER (SAM_PIOC_BASE+SAM_PIO_KER_OFFSET) +# define SAM_PIOC_KRCR (SAM_PIOC_BASE+SAM_PIO_KRCR_OFFSET) +# define SAM_PIOC_KDR (SAM_PIOC_BASE+SAM_PIO_KDR_OFFSET) +# define SAM_PIOC_KIER (SAM_PIOC_BASE+SAM_PIO_KIER_OFFSET) +# define SAM_PIOC_KIDR (SAM_PIOC_BASE+SAM_PIO_KIDR_OFFSET) +# define SAM_PIOC_KIMR (SAM_PIOC_BASE+SAM_PIO_KIMR_OFFSET) +# define SAM_PIOC_KSR (SAM_PIOC_BASE+SAM_PIO_KSR_OFFSET) +# define SAM_PIOC_KKPR (SAM_PIOC_BASE+SAM_PIO_KKPR_OFFSET) +# define SAM_PIOC_KKRR (SAM_PIOC_BASE+SAM_PIO_KKRR_OFFSET) +# define SAM_PIOC_PCMR (SAM_PIOC_BASE+SAM_PIO_PCMR_OFFSET) +# define SAM_PIOC_PCIER (SAM_PIOC_BASE+SAM_PIO_PCIER_OFFSET) +# define SAM_PIOC_PCIDR (SAM_PIOC_BASE+SAM_PIO_PCIDR_OFFSET) +# define SAM_PIOC_PCIMR (SAM_PIOC_BASE+SAM_PIO_PCIMR_OFFSET) +# define SAM_PIOC_PCISR (SAM_PIOC_BASE+SAM_PIO_PCISR_OFFSET) +# define SAM_PIOC_PCRHR (SAM_PIOC_BASE+SAM_PIO_PCRHR_OFFSET +#endif + +#if SAMV7_NPIO > 3 +# define SAM_PIOD_PER (SAM_PIOD_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOD_PDR (SAM_PIOD_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOD_PSR (SAM_PIOD_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOD_OER (SAM_PIOD_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOD_ODR (SAM_PIOD_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOD_OSR (SAM_PIOD_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOD_IFER (SAM_PIOD_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOD_IFDR (SAM_PIOD_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOD_IFSR (SAM_PIOD_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOD_SODR (SAM_PIOD_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOD_CODR (SAM_PIOD_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOD_ODSR (SAM_PIOD_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOD_PDSR (SAM_PIOD_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOD_IER (SAM_PIOD_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOD_IDR (SAM_PIOD_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOD_IMR (SAM_PIOD_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOD_ISR (SAM_PIOD_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOD_MDER (SAM_PIOD_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOD_MDDR (SAM_PIOD_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOD_MDSR (SAM_PIOD_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOD_PUDR (SAM_PIOD_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOD_PUER (SAM_PIOD_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOD_PUSR (SAM_PIOD_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOD_ABCDSR1 (SAM_PIOD_BASE+SAM_PIO_ABCDSR1_OFFSET) +# define SAM_PIOD_ABCDSR2 (SAM_PIOD_BASE+SAM_PIO_ABCDSR2_OFFSET) +# define SAM_PIOD_IFSCDR (SAM_PIOD_BASE+SAM_PIO_IFSCDR_OFFSET) +# define SAM_PIOD_IFSCER (SAM_PIOD_BASE+SAM_PIO_IFSCER_OFFSET) +# define SAM_PIOD_IFSCSR (SAM_PIOD_BASE+SAM_PIO_IFSCSR_OFFSET) +# define SAM_PIOD_SCDR (SAM_PIOD_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOD_PPDDR (SAM_PIOD_BASE+SAM_PIO_PPDDR_OFFSET) +# define SAM_PIOD_PPDER (SAM_PIOD_BASE+SAM_PIO_PPDER_OFFSET) +# define SAM_PIOD_PPDSR (SAM_PIOD_BASE+SAM_PIO_PPDSR_OFFSET) +# define SAM_PIOD_OWER (SAM_PIOD_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOD_OWDR (SAM_PIOD_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOD_OWSR (SAM_PIOD_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOD_AIMER (SAM_PIOD_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOD_AIMDR (SAM_PIOD_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOD_AIMMR (SAM_PIOD_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOD_ESR (SAM_PIOD_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOD_LSR (SAM_PIOD_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOD_ELSR (SAM_PIOD_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOD_FELLSR (SAM_PIOD_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOD_REHLSR (SAM_PIOD_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOD_FRLHSR (SAM_PIOD_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOD_LOCKSR (SAM_PIOD_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOD_WPMR (SAM_PIOD_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOD_WPSR (SAM_PIOD_BASE+SAM_PIO_WPSR_OFFSET) +# define SAM_PIOD_SCHMITT (SAM_PIOD_BASE+SAM_PIO_SCHMITT_OFFSET) +# define SAM_PIOD_DRIVER (SAM_PIOD_BASE+SAM_PIO_DRIVER_OFFSET) +# define SAM_PIOD_KER (SAM_PIOD_BASE+SAM_PIO_KER_OFFSET) +# define SAM_PIOD_KRCR (SAM_PIOD_BASE+SAM_PIO_KRCR_OFFSET) +# define SAM_PIOD_KDR (SAM_PIOD_BASE+SAM_PIO_KDR_OFFSET) +# define SAM_PIOD_KIER (SAM_PIOD_BASE+SAM_PIO_KIER_OFFSET) +# define SAM_PIOD_KIDR (SAM_PIOD_BASE+SAM_PIO_KIDR_OFFSET) +# define SAM_PIOD_KIMR (SAM_PIOD_BASE+SAM_PIO_KIMR_OFFSET) +# define SAM_PIOD_KSR (SAM_PIOD_BASE+SAM_PIO_KSR_OFFSET) +# define SAM_PIOD_KKPR (SAM_PIOD_BASE+SAM_PIO_KKPR_OFFSET) +# define SAM_PIOD_KKRR (SAM_PIOD_BASE+SAM_PIO_KKRR_OFFSET) +# define SAM_PIOD_PCMR (SAM_PIOD_BASE+SAM_PIO_PCMR_OFFSET) +# define SAM_PIOD_PCIER (SAM_PIOD_BASE+SAM_PIO_PCIER_OFFSET) +# define SAM_PIOD_PCIDR (SAM_PIOD_BASE+SAM_PIO_PCIDR_OFFSET) +# define SAM_PIOD_PCIMR (SAM_PIOD_BASE+SAM_PIO_PCIMR_OFFSET) +# define SAM_PIOD_PCISR (SAM_PIOD_BASE+SAM_PIO_PCISR_OFFSET) +# define SAM_PIOD_PCRHR (SAM_PIOD_BASE+SAM_PIO_PCRHR_OFFSET +#endif + +#if SAMV7_NPIO > 4 +# define SAM_PIOE_PER (SAM_PIOE_BASE+SAM_PIO_PER_OFFSET) +# define SAM_PIOE_PDR (SAM_PIOE_BASE+SAM_PIO_PDR_OFFSET) +# define SAM_PIOE_PSR (SAM_PIOE_BASE+SAM_PIO_PSR_OFFSET) +# define SAM_PIOE_OER (SAM_PIOE_BASE+SAM_PIO_OER_OFFSET) +# define SAM_PIOE_ODR (SAM_PIOE_BASE+SAM_PIO_ODR_OFFSET) +# define SAM_PIOE_OSR (SAM_PIOE_BASE+SAM_PIO_OSR_OFFSET) +# define SAM_PIOE_IFER (SAM_PIOE_BASE+SAM_PIO_IFER_OFFSET) +# define SAM_PIOE_IFDR (SAM_PIOE_BASE+SAM_PIO_IFDR_OFFSET) +# define SAM_PIOE_IFSR (SAM_PIOE_BASE+SAM_PIO_IFSR_OFFSET) +# define SAM_PIOE_SODR (SAM_PIOE_BASE+SAM_PIO_SODR_OFFSET) +# define SAM_PIOE_CODR (SAM_PIOE_BASE+SAM_PIO_CODR_OFFSET) +# define SAM_PIOE_ODSR (SAM_PIOE_BASE+SAM_PIO_ODSR_OFFSET) +# define SAM_PIOE_PDSR (SAM_PIOE_BASE+SAM_PIO_PDSR_OFFSET) +# define SAM_PIOE_IER (SAM_PIOE_BASE+SAM_PIO_IER_OFFSET) +# define SAM_PIOE_IDR (SAM_PIOE_BASE+SAM_PIO_IDR_OFFSET) +# define SAM_PIOE_IMR (SAM_PIOE_BASE+SAM_PIO_IMR_OFFSET) +# define SAM_PIOE_ISR (SAM_PIOE_BASE+SAM_PIO_ISR_OFFSET) +# define SAM_PIOE_MDER (SAM_PIOE_BASE+SAM_PIO_MDER_OFFSET) +# define SAM_PIOE_MDDR (SAM_PIOE_BASE+SAM_PIO_MDDR_OFFSET) +# define SAM_PIOE_MDSR (SAM_PIOE_BASE+SAM_PIO_MDSR_OFFSET) +# define SAM_PIOE_PUDR (SAM_PIOE_BASE+SAM_PIO_PUDR_OFFSET) +# define SAM_PIOE_PUER (SAM_PIOE_BASE+SAM_PIO_PUER_OFFSET) +# define SAM_PIOE_PUSR (SAM_PIOE_BASE+SAM_PIO_PUSR_OFFSET) +# define SAM_PIOE_ABCDSR1 (SAM_PIOE_BASE+SAM_PIO_ABCDSR1_OFFSET) +# define SAM_PIOE_ABCDSR2 (SAM_PIOE_BASE+SAM_PIO_ABCDSR2_OFFSET) +# define SAM_PIOE_IFSCDR (SAM_PIOE_BASE+SAM_PIO_IFSCDR_OFFSET) +# define SAM_PIOE_IFSCER (SAM_PIOE_BASE+SAM_PIO_IFSCER_OFFSET) +# define SAM_PIOE_IFSCSR (SAM_PIOE_BASE+SAM_PIO_IFSCSR_OFFSET) +# define SAM_PIOE_SCDR (SAM_PIOE_BASE+SAM_PIO_SCDR_OFFSET) +# define SAM_PIOE_PPDDR (SAM_PIOE_BASE+SAM_PIO_PPDDR_OFFSET) +# define SAM_PIOE_PPDER (SAM_PIOE_BASE+SAM_PIO_PPDER_OFFSET) +# define SAM_PIOE_PPDSR (SAM_PIOE_BASE+SAM_PIO_PPDSR_OFFSET) +# define SAM_PIOE_OWER (SAM_PIOE_BASE+SAM_PIO_OWER_OFFSET) +# define SAM_PIOE_OWDR (SAM_PIOE_BASE+SAM_PIO_OWDR_OFFSET) +# define SAM_PIOE_OWSR (SAM_PIOE_BASE+SAM_PIO_OWSR_OFFSET) +# define SAM_PIOE_AIMER (SAM_PIOE_BASE+SAM_PIO_AIMER_OFFSET) +# define SAM_PIOE_AIMDR (SAM_PIOE_BASE+SAM_PIO_AIMDR_OFFSET) +# define SAM_PIOE_AIMMR (SAM_PIOE_BASE+SAM_PIO_AIMMR_OFFSET) +# define SAM_PIOE_ESR (SAM_PIOE_BASE+SAM_PIO_ESR_OFFSET) +# define SAM_PIOE_LSR (SAM_PIOE_BASE+SAM_PIO_LSR_OFFSET) +# define SAM_PIOE_ELSR (SAM_PIOE_BASE+SAM_PIO_ELSR_OFFSET) +# define SAM_PIOE_FELLSR (SAM_PIOE_BASE+SAM_PIO_FELLSR_OFFSET) +# define SAM_PIOE_REHLSR (SAM_PIOE_BASE+SAM_PIO_REHLSR_OFFSET) +# define SAM_PIOE_FRLHSR (SAM_PIOE_BASE+SAM_PIO_FRLHSR_OFFSET) +# define SAM_PIOE_LOCKSR (SAM_PIOE_BASE+SAM_PIO_LOCKSR_OFFSET) +# define SAM_PIOE_WPMR (SAM_PIOE_BASE+SAM_PIO_WPMR_OFFSET) +# define SAM_PIOE_WPSR (SAM_PIOE_BASE+SAM_PIO_WPSR_OFFSET) +# define SAM_PIOE_SCHMITT (SAM_PIOE_BASE+SAM_PIO_SCHMITT_OFFSET) +# define SAM_PIOE_DRIVER (SAM_PIOE_BASE+SAM_PIO_DRIVER_OFFSET) +# define SAM_PIOE_KER (SAM_PIOE_BASE+SAM_PIO_KER_OFFSET) +# define SAM_PIOE_KRCR (SAM_PIOE_BASE+SAM_PIO_KRCR_OFFSET) +# define SAM_PIOE_KDR (SAM_PIOE_BASE+SAM_PIO_KDR_OFFSET) +# define SAM_PIOE_KIER (SAM_PIOE_BASE+SAM_PIO_KIER_OFFSET) +# define SAM_PIOE_KIDR (SAM_PIOE_BASE+SAM_PIO_KIDR_OFFSET) +# define SAM_PIOE_KIMR (SAM_PIOE_BASE+SAM_PIO_KIMR_OFFSET) +# define SAM_PIOE_KSR (SAM_PIOE_BASE+SAM_PIO_KSR_OFFSET) +# define SAM_PIOE_KKPR (SAM_PIOE_BASE+SAM_PIO_KKPR_OFFSET) +# define SAM_PIOE_KKRR (SAM_PIOE_BASE+SAM_PIO_KKRR_OFFSET) +# define SAM_PIOE_PCMR (SAM_PIOE_BASE+SAM_PIO_PCMR_OFFSET) +# define SAM_PIOE_PCIER (SAM_PIOE_BASE+SAM_PIO_PCIER_OFFSET) +# define SAM_PIOE_PCIDR (SAM_PIOE_BASE+SAM_PIO_PCIDR_OFFSET) +# define SAM_PIOE_PCIMR (SAM_PIOE_BASE+SAM_PIO_PCIMR_OFFSET) +# define SAM_PIOE_PCISR (SAM_PIOE_BASE+SAM_PIO_PCISR_OFFSET) +# define SAM_PIOE_PCRHR (SAM_PIOE_BASE+SAM_PIO_PCRHR_OFFSET +#endif + +/* PIO register bit definitions *********************************************************/ + +/* Common bit definitions for ALMOST all IO registers (exceptions follow) */ + +#define PIO(n) (1 << (n)) /* Bit n: PIO n, n=0-31 */ + +/* PIO Slow Clock Divider Debouncing Register */ + +#define PIO_SCDR_MASK (0x3fff) /* Bits 0-13: Slow Clock Divider */ + +/* PIO Write Protect Mode Register */ + +#define PIO_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PIO_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PIO_WPMR_WPKEY_MASK (0xffffff << PIO_WPMR_WPKEY_SHIFT) +# define PIO_WPMR_WPKEY (0x50494f << PIO_WPMR_WPKEY_SHIFT) + +/* PIO Write Protect Status Register */ + +#define PIO_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PIO_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PIO_WPSR_WPVSRC_MASK (0xffff << PIO_WPSR_WPVSRC_SHIFT) + +/* Keypad Controller Enable Register */ + +#define PIO_KER_KCE (1 << 0) /* Bit 0: Keypad Controller Enable */ + +/* Keypad Controller Row Column Register */ + +#define PIO_KRCR_NBC_SHIFT (0) /* Bis 0-2: Number of Rows of the Keypad Matrix */ +#define PIO_KRCR_NBC_MASK (7 << PIO_KRCR_NBC_SHIFT) +# define PIO_KRCR_NBC(n) ((uint32_t)(n) << PIO_KRCR_NBC_SHIFT) +#define PIO_KRCR_NBR_SHIFT (8) /* Bis 8-10: Number of Columns of the Keypad Matrix */ +#define PIO_KRCR_NBR_MASK (7 << PIO_KRCR_NBR_SHIFT) +# define PIO_KRCR_NBR(n) ((uint32_t)(n) << PIO_KRCR_NBR_SHIFT) + +/* Keypad Controller Debouncing Register */ + +#define PIO_KDR_MASK 0x0000003ff /* Bits 0-9: Debouncing Value */ + +/* Keypad Controller Interrupt Enable, Disable, Mask, and Status Registers */ + +#define PIO_KINT_KPR (1 << 0) /* Bit 0: Key Press Interrupt */ +#define PIO_KINT_KRL (1 << 1) /* Bit 1: Key Release Interrupt Mask */ +#define PIO_KINT_NBKPR_SHIFT (8) /* Bits 8-9: Number of Simultaneous Key Presses (SR only) */ +#define PIO_KINT_NBKPR_MASK (3 << PIO_KINT_NBKPR_SHIFT) +#define PIO_KINT_NBKRL_SHIFT (16) /* Bits 16-17: Number of Simultaneous Key Releases (SR only) */ +#define PIO_KINT_NBKRL_MASK (3 << PIO_KINT_NBKRL_SHIFT) + +/* Keypad Controller Key Press and Register */ + +#define PIO_KKPR_KEYnROW_SHIFT(n) ((n) << 3) +#define PIO_KKPR_KEYnROW_MASK(n) (7 << PIO_KKPR_KEYnROW_SHIFT(n)) +#define PIO_KKPR_KEYnCOL_SHIFT(n) (4 + ((n) << 3)) +#define PIO_KKPR_KEYnCOL_MASK(n) (7 << PIO_KKPR_KEYnCOL_SHIFT(n)) +# define PIO_KKPR_KEY0ROW_SHIFT (0) /* Bits 0-2: Row Index of the First Detected Key Press */ +# define PIO_KKPR_KEY0ROW_MASK (7 << PIO_KKPR_KEY0ROW_SHIFT) +# define PIO_KKPR_KEY0COL_SHIFT (4) /* Bits 4-6: Column Index of the First Detected Key Press */ +# define PIO_KKPR_KEY0COLMASK (7 << PIO_KKPR_KEY0COL_SHIFT) +# define PIO_KKPR_KEY1ROW_SHIFT (8) /* Bits 8-10: Row Index of the Second Detected Key Press */ +# define PIO_KKPR_KEY1ROWMASK (7 << PIO_KKPR_KEY1ROW_SHIFT) +# define PIO_KKPR_KEY1COL_SHIFT (12) /* Bits 12-14: Column Index of the Second Detected Key Press */ +# define PIO_KKPR_KEY1COLMASK (7 << PIO_KKPR_KEY1COL_SHIFT) +# define PIO_KKPR_KEY2ROW_SHIFT (16) /* Bits 16-18: Row Index of the Third Detected Key Press */ +# define PIO_KKPR_KEY2ROWMASK (7 << PIO_KKPR_KEY2ROW_SHIFT) +# define PIO_KKPR_KEY2COL_SHIFT (20) /* Bits 20-22: Column Index of the Third Detected Key Press */ +# define PIO_KKPR_KEY2COLMASK (7 << PIO_KKPR_KEY2COL_SHIFT) +# define PIO_KKPR_KEY3ROW_SHIFT (24) /* Bits 24-26: Row Index of the Fourth Detected Key Press */ +# define PIO_KKPR_KEY3ROWMASK (7 << PIO_KKPR_KEY3ROW_SHIFT) +# define PIO_KKPR_KEY3COL_SHIFT (28) /* Bits 28-30: Column Index of the Fourth Detected Key Press */ +# define PIO_KKPR_KEY3COLMASK (7 << PIO_KKPR_KEY3COL_SHIFT) + +/* PIO Parallel Capture Mode Register */ + +#define PIO_PCMR_PCEN (1 << 0) /* Bit 0: Parallel Capture Mode Enable */ +#define PIO_PCMR_DSIZE_SHIFT (4) /* Bits 4-5: Parallel Capture Mode Data Size */ +#define PIO_PCMR_DSIZE_MASK (3 << PIO_PCMR_DSIZE_SHIFT) +# define PIO_PCMR_DSIZE_BYTE (0 << PIO_PCMR_DSIZE_SHIFT) /* 8-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_HWORD (1 << PIO_PCMR_DSIZE_SHIFT) /* 16-bit data in PIO_PCRHR */ +# define PIO_PCMR_DSIZE_WORD (2 << PIO_PCMR_DSIZE_SHIFT) /* 32-bit data in PIO_PCRHR */ +#define PIO_PCMR_ALWYS (1 << 9) /* Bit 9: Parallel Capture Mode Always Sampling */ +#define PIO_PCMR_HALFS (1 << 10) /* Bit 10: Parallel Capture Mode Half Sampling */ +#define PIO_PCMR_FRSTS (1 << 11) /* Bit 11: Parallel Capture Mode First Sample */ + +/* PIO Parallel Capture Interrupt Enable, Disable, Mask, and Status Registers */ + +#define PIOC_PCINT_DRDY (1 << 0) /* Bit 0: Parallel Capture Mode Data Ready Interrupt */ +#define PIOC_PCINT_OVRE (1 << 1) /* Bit 1: Parallel Capture Mode Overrun Error Interrupt */ +#define PIOC_PCINT_ENDRX (1 << 2) /* Bit 2: End of Reception Transfer Interrupt */ +#define PIOC_PCINT_RXBUFF (1 << 3) /* Bit 3: Reception Buffer Full Interrupt */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* SAMV7_NPIO > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM4E_PIO_H */ diff --git a/arch/arm/src/samv7/chip/sam_pmc.h b/arch/arm/src/samv7/chip/sam_pmc.h new file mode 100644 index 0000000000000000000000000000000000000000..ac4f570cbe8a4381a7211d3f3f976e1f40f1e0fa --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_pmc.h @@ -0,0 +1,466 @@ +/******************************************************************************************** + * arch/arm/src/samv7/chip/sam_pmc.h + * Power Management Controller (PMC) for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PMC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PMC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* PMC register offsets *********************************************************************/ + +#define SAM_PMC_SCER_OFFSET 0x0000 /* System Clock Enable Register */ +#define SAM_PMC_SCDR_OFFSET 0x0004 /* System Clock Disable Register */ +#define SAM_PMC_SCSR_OFFSET 0x0008 /* System Clock Status Register */ + /* 0x000c: Reserved */ +#define SAM_PMC_PCER0_OFFSET 0x0010 /* Peripheral Clock Enable Register 0 */ +#define SAM_PMC_PCDR0_OFFSET 0x0014 /* Peripheral Clock Disable Register 0 */ +#define SAM_PMC_PCSR0_OFFSET 0x0018 /* Peripheral Clock Status Register 0 */ + +#define SAM_PMC_CKGR_UCKR_OFFSET 0x001c /* UTMI Clock Register */ +#define SAM_PMC_CKGR_MOR_OFFSET 0x0020 /* Main Oscillator Register */ +#define SAM_PMC_CKGR_MCFR_OFFSET 0x0024 /* Main Clock Frequency Register */ +#define SAM_PMC_CKGR_PLLAR_OFFSET 0x0028 /* PLLA Register */ + /* 0x002c: Reserved */ +#define SAM_PMC_MCKR_OFFSET 0x0030 /* Master Clock Register */ + /* 0x0034 Reserved */ +#define SAM_PMC_USB_OFFSET 0x0038 /* USB Clock Register PMC_USB */ + /* 0x0034-0x003c Reserved (SAM3U) */ +#define SAM_PMC_PCK_OFFSET(n) (0x0040 + ((n) << 2)) +# define SAM_PMC_PCK0_OFFSET 0x0040 /* Programmable Clock 0 Register */ +# define SAM_PMC_PCK1_OFFSET 0x0044 /* Programmable Clock 1 Register */ +# define SAM_PMC_PCK2_OFFSET 0x0048 /* Programmable Clock 2 Register */ +# define SAM_PMC_PCK3_OFFSET 0x004c /* Programmable Clock 4 Register */ +# define SAM_PMC_PCK4_OFFSET 0x0050 /* Programmable Clock 5 Register */ +# define SAM_PMC_PCK5_OFFSET 0x0054 /* Programmable Clock 6 Register */ +# define SAM_PMC_PCK6_OFFSET 0x0058 /* Programmable Clock 7 Register */ + /* 0x005c: Reserved */ +#define SAM_PMC_IER_OFFSET 0x0060 /* Interrupt Enable Register */ +#define SAM_PMC_IDR_OFFSET 0x0064 /* Interrupt Disable Register */ +#define SAM_PMC_SR_OFFSET 0x0068 /* Status Register */ +#define SAM_PMC_IMR_OFFSET 0x006c /* Interrupt Mask Register */ +#define SAM_PMC_FSMR_OFFSET 0x0070 /* Fast Startup Mode Register */ +#define SAM_PMC_FSPR_OFFSET 0x0074 /* Fast Startup Polarity Register */ +#define SAM_PMC_FOCR_OFFSET 0x0078 /* Fault Output Clear Register */ + /* 0x007c-0x00e0: Reserved */ +#define SAM_PMC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_PMC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x00fc: Reserved */ +#define SAM_PMC_PCER1_OFFSET 0x0100 /* Peripheral Clock Enable Register 1 */ +#define SAM_PMC_PCDR1_OFFSET 0x0104 /* Peripheral Clock Disable Register 1 */ +#define SAM_PMC_PCSR1_OFFSET 0x0108 /* Peripheral Clock Status Register 1 */ +#define SAM_PMC_PCR_OFFSET 0x010c /* Peripheral Control Register */ +#define SAM_PMC_OCR_OFFSET 0x0110 /* Oscillator Calibration Register */ + +#define SAM_PMC_SLPWK_ER0_OFFSET 0x0114 /* SleepWalking Enable Register 0 */ +#define SAM_PMC_SLPWK_DR0_OFFSET 0x0118 /* SleepWalking Disable Register 0 */ +#define SAM_PMC_SLPWK_SR0_OFFSET 0x011c /* SleepWalking Status Register 0 */ +#define SAM_PMC_SLPWK_ASR0_OFFSET 0x0120 /* SleepWalking Activity Status Register 0 */ +#define SAM_PMC_SLPWK_ER1_OFFSET 0x0134 /* SleepWalking Enable Register 1 */ +#define SAM_PMC_SLPWK_DR1_OFFSET 0x0138 /* SleepWalking Disable Register 1 */ +#define SAM_PMC_SLPWK_SR1_OFFSET 0x013c /* SleepWalking Status Register 1 */ +#define SAM_PMC_SLPWK_ASR1_OFFSET 0x0140 /* SleepWalking Activity Status Register 1 */ +#define SAM_PMC_SLPWK_AIPR_OFFSET 0x0144 /* SleepWalking Activity In Progress Register */ + +/* PMC register addresses *******************************************************************/ + +#define SAM_PMC_SCER (SAM_PMC_BASE+SAM_PMC_SCER_OFFSET) +#define SAM_PMC_SCDR (SAM_PMC_BASE+SAM_PMC_SCDR_OFFSET) +#define SAM_PMC_SCSR (SAM_PMC_BASE+SAM_PMC_SCSR_OFFSET) +#define SAM_PMC_PCER0 (SAM_PMC_BASE+SAM_PMC_PCER0_OFFSET) +#define SAM_PMC_PCDR0 (SAM_PMC_BASE+SAM_PMC_PCDR0_OFFSET) +#define SAM_PMC_PCSR0 (SAM_PMC_BASE+SAM_PMC_PCSR0_OFFSET) + +#define SAM_PMC_CKGR_UCKR (SAM_PMC_BASE+SAM_PMC_CKGR_UCKR_OFFSET) +#define SAM_PMC_CKGR_MOR (SAM_PMC_BASE+SAM_PMC_CKGR_MOR_OFFSET) +#define SAM_PMC_CKGR_MCFR (SAM_PMC_BASE+SAM_PMC_CKGR_MCFR_OFFSET) +#define SAM_PMC_CKGR_PLLAR (SAM_PMC_BASE+SAM_PMC_CKGR_PLLAR_OFFSET) + +#define SAM_PMC_MCKR (SAM_PMC_BASE+SAM_PMC_MCKR_OFFSET) +#define SAM_PMC_USB (SAM_PMC_BASE+SAM_PMC_USB_OFFSET) + +#define SAM_PMC_PCK(n) (SAM_PMC_BASE+SAM_PMC_PCK_OFFSET(n)) +# define SAM_PMC_PCK0 (SAM_PMC_BASE+SAM_PMC_PCK0_OFFSET) +# define SAM_PMC_PCK1 (SAM_PMC_BASE+SAM_PMC_PCK1_OFFSET) +# define SAM_PMC_PCK2 (SAM_PMC_BASE+SAM_PMC_PCK2_OFFSET) +# define SAM_PMC_PCK3 (SAM_PMC_BASE+SAM_PMC_PCK3_OFFSET) +# define SAM_PMC_PCK4 (SAM_PMC_BASE+SAM_PMC_PCK4_OFFSET) +# define SAM_PMC_PCK5 (SAM_PMC_BASE+SAM_PMC_PCK5_OFFSET) +# define SAM_PMC_PCK6 (SAM_PMC_BASE+SAM_PMC_PCK6_OFFSET) + +#define SAM_PMC_IER (SAM_PMC_BASE+SAM_PMC_IER_OFFSET) +#define SAM_PMC_IDR (SAM_PMC_BASE+SAM_PMC_IDR_OFFSET) +#define SAM_PMC_SR (SAM_PMC_BASE+SAM_PMC_SR_OFFSET) +#define SAM_PMC_IMR (SAM_PMC_BASE+SAM_PMC_IMR_OFFSET) +#define SAM_PMC_FSMR (SAM_PMC_BASE+SAM_PMC_FSMR_OFFSET) +#define SAM_PMC_FSPR (SAM_PMC_BASE+SAM_PMC_FSPR_OFFSET) +#define SAM_PMC_FOCR (SAM_PMC_BASE+SAM_PMC_FOCR_OFFSET) +#define SAM_PMC_WPMR (SAM_PMC_BASE+SAM_PMC_WPMR_OFFSET) +#define SAM_PMC_WPSR (SAM_PMC_BASE+SAM_PMC_WPSR_OFFSET) +#define SAM_PMC_PCER1 (SAM_PMC_BASE+SAM_PMC_PCER1_OFFSET) +#define SAM_PMC_PCDR1 (SAM_PMC_BASE+SAM_PMC_PCDR1_OFFSET) +#define SAM_PMC_PCSR1 (SAM_PMC_BASE+SAM_PMC_PCSR1_OFFSET) +#define SAM_PMC_PCR (SAM_PMC_BASE+SAM_PMC_PCR_OFFSET) +#define SAM_PMC_OCR (SAM_PMC_BASE+SAM_PMC_OCR_OFFSET) + +#define SAM_PMC_SLPWK_ER0 (SAM_PMC_BASE+SAM_PMC_SLPWK_ER0_OFFSET) +#define SAM_PMC_SLPWK_DR0 (SAM_PMC_BASE+SAM_PMC_SLPWK_DR0_OFFSET) +#define SAM_PMC_SLPWK_SR0 (SAM_PMC_BASE+SAM_PMC_SLPWK_SR0_OFFSET) +#define SAM_PMC_SLPWK_ASR0 (SAM_PMC_BASE+SAM_PMC_SLPWK_ASR0_OFFSET) +#define SAM_PMC_SLPWK_ER1 (SAM_PMC_BASE+SAM_PMC_SLPWK_ER1_OFFSET) +#define SAM_PMC_SLPWK_DR1 (SAM_PMC_BASE+SAM_PMC_SLPWK_DR1_OFFSET) +#define SAM_PMC_SLPWK_SR1 (SAM_PMC_BASE+SAM_PMC_SLPWK_SR1_OFFSET) +#define SAM_PMC_SLPWK_ASR1 (SAM_PMC_BASE+SAM_PMC_SLPWK_ASR1_OFFSET) +#define SAM_PMC_SLPWK_AIPR (SAM_PMC_BASE+SAM_PMC_SLPWK_AIPR_OFFSET) + +/* PMC register bit definitions *************************************************************/ + +/* PMC System Clock Enable Register, PMC System Clock Disable Register, and PMC System + * Clock Status Register common bit-field definitions + */ + +#define PMC_USBCLK (1 << 5) /* Bit 5: Enable USB FS Clock */ +#define PMC_PCK(n) (1 << ((n) + 8)) +# define PMC_PCK0 (1 << 8) /* Bit 8: Programmable Clock 0 Output Enable */ +# define PMC_PCK1 (1 << 9) /* Bit 9: Programmable Clock 1 Output Enable */ +# define PMC_PCK2 (1 << 10) /* Bit 10: Programmable Clock 2 Output Enable */ +# define PMC_PCK3 (1 << 11) /* Bit 11: Programmable Clock 3 Output Enable */ +# define PMC_PCK4 (1 << 12) /* Bit 12: Programmable Clock 4 Output Enable */ +# define PMC_PCK5 (1 << 13) /* Bit 13: Programmable Clock 5 Output Enable */ +# define PMC_PCK6 (1 << 14) /* Bit 14: Programmable Clock 6 Output Enable */ + +/* PMC Peripheral Clock Enable Register, PMC Peripheral Clock Disable Register, and PMC + * Peripheral Clock Status Register common bit-field definitions. + */ + +#define PMC_PIDL(n) (1 << (n)) +# define PMC_PID7 (1 << 7) /* Bit 7: Peripheral Clock 7 Enable */ +# define PMC_PID8 (1 << 8) /* Bit 8: Peripheral Clock 8 Enable */ +# define PMC_PID9 (1 << 9) /* Bit 9: Peripheral Clock 9 Enable */ +# define PMC_PID10 (1 << 10) /* Bit 10: Peripheral Clock 10 Enable */ +# define PMC_PID11 (1 << 11) /* Bit 11: Peripheral Clock 11 Enable */ +# define PMC_PID12 (1 << 12) /* Bit 12: Peripheral Clock 12 Enable */ +# define PMC_PID13 (1 << 13) /* Bit 13: Peripheral Clock 13 Enable */ +# define PMC_PID14 (1 << 14) /* Bit 14: Peripheral Clock 14 Enable */ +# define PMC_PID15 (1 << 15) /* Bit 15: Peripheral Clock 15 Enable */ +# define PMC_PID16 (1 << 16) /* Bit 16: Peripheral Clock 16 Enable */ +# define PMC_PID17 (1 << 17) /* Bit 17: Peripheral Clock 17 Enable */ +# define PMC_PID18 (1 << 18) /* Bit 18: Peripheral Clock 18 Enable */ +# define PMC_PID19 (1 << 19) /* Bit 19: Peripheral Clock 19 Enable */ +# define PMC_PID20 (1 << 20) /* Bit 20: Peripheral Clock 20 Enable */ +# define PMC_PID21 (1 << 21) /* Bit 21: Peripheral Clock 21 Enable */ +# define PMC_PID22 (1 << 22) /* Bit 22: Peripheral Clock 22 Enable */ +# define PMC_PID23 (1 << 23) /* Bit 23: Peripheral Clock 23 Enable */ +# define PMC_PID24 (1 << 24) /* Bit 24: Peripheral Clock 24 Enable */ +# define PMC_PID25 (1 << 25) /* Bit 25: Peripheral Clock 25 Enable */ +# define PMC_PID26 (1 << 26) /* Bit 26: Peripheral Clock 26 Enable */ +# define PMC_PID27 (1 << 27) /* Bit 27: Peripheral Clock 27 Enable */ +# define PMC_PID28 (1 << 28) /* Bit 28: Peripheral Clock 28 Enable */ +# define PMC_PID29 (1 << 29) /* Bit 29: Peripheral Clock 29 Enable */ +# define PMC_PID30 (1 << 30) /* Bit 30: Peripheral Clock 30 Enable */ +# define PMC_PID31 (1 << 31) /* Bit 31: Peripheral Clock 31 Enable */ + +/* PMC UTMI Clock Configuration Register */ + +#define PMC_CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */ +#define PMC_CKGR_UCKR_UPLLCOUNT_SHIFT (20) /* Bits 20-23: UTMI PLL Start-up Time */ +#define PMC_CKGR_UCKR_UPLLCOUNT_MASK (15 << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) +# define PMC_CKGR_UCKR_UPLLCOUNT(n) ((uint32_t)(n) << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) +# define PMC_CKGR_UCKR_UPLLCOUNT_MAX (15 << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT) + +/* PMC Clock Generator Main Oscillator Register */ + +#define PMC_CKGR_MOR_MOSCXTEN (1 << 0) /* Bit 0: Main Crystal Oscillator Enable */ +#define PMC_CKGR_MOR_MOSCXTBY (1 << 1) /* Bit 1: Main Crystal Oscillator Bypass */ +#define PMC_CKGR_MOR_WAITMODE (1 << 2) /* Bit 2: Wait Mode Command */ +#define PMC_CKGR_MOR_MOSCRCEN (1 << 3) /* Bit 3: Main On-Chip RC Oscillator Enable */ +#define PMC_CKGR_MOR_MOSCRCF_SHIFT (4) /* Bits 4-6: Main On-Chip RC Oscillator Frequency Selection */ +#define PMC_CKGR_MOR_MOSCRCF_MASK (7 << PMC_CKGR_MOR_MOSCRCF_SHIFT) +# define PMC_CKGR_MOR_MOSCRCF_4MHz (0 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 4MHz (default) */ +# define PMC_CKGR_MOR_MOSCRCF_8MHz (1 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 8MHz */ +# define PMC_CKGR_MOR_MOSCRCF_12MHz (2 << PMC_CKGR_MOR_MOSCRCF_SHIFT) /* Fast RC Osc is 12MHz */ +#define PMC_CKGR_MOR_MOSCXTST_SHIFT (8) /* Bits 8-15: Main Crystal Oscillator Start-up Time */ +#define PMC_CKGR_MOR_MOSCXTST_MASK (0xff << PMC_CKGR_MOR_MOSCXTST_SHIFT) +# define PMC_CKGR_MOR_MOSCXTST(n) ((uint32_t)(n) << PMC_CKGR_MOR_MOSCXTST_SHIFT) +#define PMC_CKGR_MOR_KEY_SHIFT (16) /* Bits 16-23: Password */ +#define PMC_CKGR_MOR_KEY_MASK (0xff << PMC_CKGR_MOR_KEY_SHIFT) +# define PMC_CKGR_MOR_KEY (0x37 << PMC_CKGR_MOR_KEY_SHIFT) +#define PMC_CKGR_MOR_MOSCSEL (1 << 24) /* Bit 24: Main Oscillator Selection */ +#define PMC_CKGR_MOR_CFDEN (1 << 25) /* Bit 25: Clock Failure Detector Enable */ +#define PMC_CKGR_MOR_XT32KFME (1 << 26) /* Bit 26: Main Crystal Oscillator Enable */ + +/* PMC Clock Generator Main Clock Frequency Register */ + +#define PMC_CKGR_MCFR_MAINF_SHIFT (0) /* Bits 0-15: Main Clock Frequency */ +#define PMC_CKGR_MCFR_MAINF_MASK (0xffff << PMC_CKGR_MCFR_MAINF_SHIFT) +# define PMC_CKGR_MCFR_MAINF(n) ((uint32_t)(n) << PMC_CKGR_MCFR_MAINF_SHIFT) +#define PMC_CKGR_MCFR_MAINFRDY (1 << 16) /* Bit 16: Main Clock Ready */ +#define PMC_CKGR_MCFR_RCMEAS (1 << 20) /* Bit 20: RC Oscillator Frequency Measure (write-only) */ +#define PMC_CKGR_MCFR_CCSS (1 << 24) /* Bit 21: Counter Clock Source Selection */ +# define PMC_CKGR_MCFR_CCSS_RCOSC (0 << 24) /* 0=Clock of the MAINF counter is RC oscillator */ +# define PMC_CKGR_MCFR_CCSS_XTAL (1 << 24) /* 1=Clock of the MAINF counter is crystal oscillator */ + +/* PMC Clock Generator PLLA Register */ + +#define PMC_CKGR_PLLAR_DIV_SHIFT (0) /* Bits 0-7: Divider */ +#define PMC_CKGR_PLLAR_DIV_MASK (0xff << PMC_CKGR_PLLAR_DIV_SHIFT) +# define PMC_CKGR_PLLAR_DIV_ZERO (0 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is 0 */ +# define PMC_CKGR_PLLAR_DIV_BYPASS (1 << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider is bypassed (DIV=1) */ +# define PMC_CKGR_PLLAR_DIV(n) ((n) << PMC_CKGR_PLLAR_DIV_SHIFT) /* Divider output is DIV=n, n=2..255 */ +#define PMC_CKGR_PLLAR_COUNT_SHIFT (8) /* Bits 8-13: PLLA Counter */ +#define PMC_CKGR_PLLAR_COUNT_MASK (63 << PMC_CKGR_PLLAR_COUNT_SHIFT) +#define PMC_CKGR_PLLAR_MUL_SHIFT (16) /* Bits 16-26: PLLA Multiplier */ +#define PMC_CKGR_PLLAR_MUL_MASK (0x7ff << PMC_CKGR_PLLAR_MUL_SHIFT) +# define PMC_CKGR_PLLAR_MUL(n) ((uint32_t)(n) << PMC_CKGR_PLLAR_MUL_SHIFT) +#define PMC_CKGR_PLLAR_ONE (1 << 29) /* Bit 29: Always one */ + +/* PMC Master Clock Register */ + +#define PMC_MCKR_CSS_SHIFT (0) /* Bits 0-1: Master Clock Source Selection */ +#define PMC_MCKR_CSS_MASK (3 << PMC_MCKR_CSS_SHIFT) +# define PMC_MCKR_CSS_SLOW (0 << PMC_MCKR_CSS_SHIFT) /* Slow Clock */ +# define PMC_MCKR_CSS_MAIN (1 << PMC_MCKR_CSS_SHIFT) /* Main Clock */ +# define PMC_MCKR_CSS_PLLA (2 << PMC_MCKR_CSS_SHIFT) /* PLLA Clock */ +# define PMC_MCKR_CSS_UPLL (3 << PMC_MCKR_CSS_SHIFT) /* Divided UPLL Clock */ +#define PMC_MCKR_PRES_SHIFT (4) /* Bits 4-6: Processor Clock Prescaler */ +#define PMC_MCKR_PRES_MASK (7 << PMC_MCKR_PRES_SHIFT) +# define PMC_MCKR_PRES_DIV1 (0 << PMC_MCKR_PRES_SHIFT) /* Selected clock */ +# define PMC_MCKR_PRES_DIV2 (1 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 2 */ +# define PMC_MCKR_PRES_DIV4 (2 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 4 */ +# define PMC_MCKR_PRES_DIV8 (3 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 8 */ +# define PMC_MCKR_PRES_DIV16 (4 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 16 */ +# define PMC_MCKR_PRES_DIV32 (5 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 32 */ +# define PMC_MCKR_PRES_DIV64 (6 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 64 */ +# define PMC_MCKR_PRES_DIV3 (7 << PMC_MCKR_PRES_SHIFT) /* Selected clock divided by 3 */ +#define PMC_MCKR_MDIV_SHIFT (8) /* Bits 8-9: Master Clock Division */ +#define PMC_MCKR_MDIV_MASK (3 << PMC_MCKR_MDIV_SHIFT) +# define PMC_MCKR_MDIV_DIV1 (0 << PMC_MCKR_MDIV_SHIFT) /* Master Clock is Prescaler Output Clock / 1 */ +# define PMC_MCKR_MDIV_DIV2 (1 << PMC_MCKR_MDIV_SHIFT) /* Master Clock = Prescaler Output Clock / 2 */ +# define PMC_MCKR_MDIV_DIV4 (2 << PMC_MCKR_MDIV_SHIFT) /* Master Clock = Prescaler Output Clock / 4 */ +# define PMC_MCKR_MDIV_DIV3 (3 << PMC_MCKR_MDIV_SHIFT) /* Master Clock = Prescaler Output Clock / 3 */ +#define PMC_MCKR_PLLADIV2 (1 << 12) /* Bit 12: PLLA Divider */ + +/* USB Clock Register PMC_USB */ + +#define PMC_USB_USBS (1 << 0) /* Bit 0: USB Input Clock Selection */ +# define PMC_USB_USBS_PLLA (0 << 0) /* 0=USB clock input is PLLA */ +# define PMC_USB_USBS_UPLL (1 << 0) /* 1=USB clock input is UPLL */ +#define PMC_USB_USBDIV_SHIFT (8) /* Bits 8-11: Divider for USB Clock */ +#define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT) +# define PMC_USB_USBDIV(n) ((uint32_t)(n) << PMC_USB_USBDIV_SHIFT) + +/* PMC Programmable Clock Register (0,..,6) */ + +#define PMC_PCK_CSS_SHIFT (0) /* Bits 0-2: Master Clock Source Selection */ +#define PMC_PCK_CSS_MASK (7 << PMC_PCK_CSS_SHIFT) +# define PMC_PCK_CSS_SLOW (0 << PMC_PCK_CSS_SHIFT) /* Slow Clock */ +# define PMC_PCK_CSS_MAIN (1 << PMC_PCK_CSS_SHIFT) /* Main Clock */ +# define PMC_PCK_CSS_PLLA (2 << PMC_PCK_CSS_SHIFT) /* PLLA Clock */ +# define PMC_PCK_CSS_UPLL (3 << PMC_PCK_CSS_SHIFT) /* Divided UPLL Clock */ +# define PMC_PCK_CSS_MCK (4 << PMC_PCK_CSS_SHIFT) /* Master Clock */ +#define PMC_PCK_PRES_SHIFT (4) /* Bits 4-11: Programmable Clock Prescaler */ +#define PMC_PCK_PRES_MASK (0xff << PMC_PCK_PRES_SHIFT) +# define PMC_PCK_PRES(n) ((uint32_t)(n) << PMC_PCK_PRES_SHIFT) /* n=0..255 */ + +/* PMC Interrupt Enable Register, PMC Interrupt Disable Register, PMC Status Register, + * and PMC Interrupt Mask Register common bit-field definitions + */ + +#define PMC_INT_MOSCXTS (1 << 0) /* Bit 0: Main Crystal Oscillator Status Interrupt */ +#define PMC_INT_LOCKA (1 << 1) /* Bit 1: PLL A Lock Interrupt */ +#define PMC_INT_MCKRDY (1 << 3) /* Bit 3: Master Clock Ready Interrupt */ +#define PMC_INT_LOCKU (1 << 6) /* Bit 6: UTMI PLL Lock Interrupt */ +#define PMC_INT_PCKRDY(n) (1 << ((n)+8) +# define PMC_INT_PCKRDY0 (1 << 8) /* Bit 8: Programmable Clock Ready 0 Interrupt */ +# define PMC_INT_PCKRDY1 (1 << 9) /* Bit 9: Programmable Clock Ready 1 Interrupt */ +# define PMC_INT_PCKRDY2 (1 << 10) /* Bit 10: Programmable Clock Ready 2 Interrupt */ +# define PMC_INT_PCKRDY3 (1 << 11) /* Bit 11: Programmable Clock Ready 3 Interrupt */ +# define PMC_INT_PCKRDY4 (1 << 12) /* Bit 12: Programmable Clock Ready 4 Interrupt */ +# define PMC_INT_PCKRDY5 (1 << 13) /* Bit 13: Programmable Clock Ready 5 Interrupt */ +# define PMC_INT_PCKRDY6 (1 << 14) /* Bit 14: Programmable Clock Ready 6 Interrupt */ +#define PMC_INT_MOSCSELS (1 << 16) /* Bit 16: Main Oscillator Selection Status Interrupt */ +#define PMC_INT_MOSCRCS (1 << 17) /* Bit 17: Main On-Chip RC Status Interrupt */ +#define PMC_INT_CFDEV (1 << 18) /* Bit 18: Clock Failure Detector Event Interrupt */ +#define PMC_SR_CFDS (1 << 19) /* Bit 19: Clock Failure Detector Status (SR only) */ +#define PMC_SR_FOS (1 << 20) /* Bit 20: Clock Failure Detector Fault Output Status (SR only) */ +#define PMC_INT_XT32KERR (1 << 21) /* Bit 21: Slow Crystal Oscillator Error Interrupt */ + +/* PMC Fast Startup Mode Register and PMC Fast Startup Polarity Register common bit-field + * definitions + */ + +#define PMC_FSTI(n) (1 << (n)) +# define PMC_FSTI0 (1 << 0) /* Bit 0: Fast Startup Input 0 */ +# define PMC_FSTI1 (1 << 1) /* Bit 1: Fast Startup Input 1 */ +# define PMC_FSTI2 (1 << 2) /* Bit 2: Fast Startup Input 2 */ +# define PMC_FSTI3 (1 << 3) /* Bit 3: Fast Startup Input 3 */ +# define PMC_FSTI4 (1 << 4) /* Bit 4: Fast Startup Input 4 */ +# define PMC_FSTI5 (1 << 5) /* Bit 5: Fast Startup Input 5 */ +# define PMC_FSTI6 (1 << 6) /* Bit 6: Fast Startup Input 6 */ +# define PMC_FSTI7 (1 << 7) /* Bit 7: Fast Startup Input 7 */ +# define PMC_FSTI8 (1 << 8) /* Bit 8: Fast Startup Input 8 */ +# define PMC_FSTI9 (1 << 9) /* Bit 9: Fast Startup Input 9 */ +# define PMC_FSTI10 (1 << 10) /* Bit 10: Fast Startup Input 10 */ +# define PMC_FSTI11 (1 << 11) /* Bit 11: Fast Startup Input 11 */ +# define PMC_FSTI12 (1 << 12) /* Bit 12: Fast Startup Input 12 */ +# define PMC_FSTI13 (1 << 13) /* Bit 13: Fast Startup Input 13 */ +# define PMC_FSTI14 (1 << 14) /* Bit 14: Fast Startup Input 14 */ +# define PMC_FSTI15 (1 << 15) /* Bit 15: Fast Startup Input 15 */ +#define PMC_FSMR_RTTAL (1 << 16) /* Bit 16: RTT Alarm Enable (MR only) */ +#define PMC_FSMR_RTCAL (1 << 17) /* Bit 17: RTC Alarm Enable (MR only) */ +#define PMC_FSMR_USBAL (1 << 18) /* Bit 18: USB Alarm Enable (MR only) */ +#define PMC_FSMR_LPM (1 << 20) /* Bit 20: Low Power Mode (MR only) */ +#define PMC_FSMR_FLPM_SHIFT (21) /* Bit 21-22: Low Power Mode (MR only) */ +#define PMC_FSMR_FLPM_MASK (3 << PMC_FSMR_FLPM_SHIFT) +# define PMC_FSMR_FLPM_STANDBY (0 << PMC_FSMR_FLPM_SHIFT) /* Flash Standby Mode */ +# define PMC_FSMR_FLPM_PWRDOWN (1 << PMC_FSMR_FLPM_SHIFT) /* Flash deep power down mode */ +# define PMC_FSMR_FLPM_IDLE (2 << PMC_FSMR_FLPM_SHIFT) /* Idle mode */ +#define PMC_FSMR_FFLPM (1 << 23) /* Bit 20: Force Flash Low-power Mode (MR only) */ + +/* PMC Fault Output Clear Register */ + +#define PMC_FOCLR (1 << 0) /* Bit 0: Fault Output Clear */ + +/* PMC Write Protect Mode Register */ + +#define PMC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define PMC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define PMC_WPMR_WPKEY_MASK (0x00ffffff << PMC_WPMR_WPKEY_SHIFT) +# define PMC_WPMR_WPKEY (0x00504d43 << PMC_WPMR_WPKEY_SHIFT) + +/* PMC Write Protect Status Register */ + +#define PMC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define PMC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define PMC_WPSR_WPVSRC_MASK (0xffff << PMC_WPSR_WPVSRC_SHIFT) + +/* Peripheral Clock Enable Register 1, Peripheral Clock Disable Register 1, and Peripheral + * Clock Status Register 1 + */ + +#define PMC_PIDH(n) (1 << ((n) - 32)) +# define PMC_PID32 (1 << 0) /* Bit 0: PID32 */ +# define PMC_PID33 (1 << 1) /* Bit 1: PID33 */ +# define PMC_PID34 (1 << 2) /* Bit 2: PID34 */ +# define PMC_PID35 (1 << 3) /* Bit 3: PID35 */ +# define PMC_PID37 (1 << 5) /* Bit 5: PID37 */ +# define PMC_PID39 (1 << 7) /* Bit 7: PID39 */ +# define PMC_PID40 (1 << 8) /* Bit 8: PID40 */ +# define PMC_PID41 (1 << 9) /* Bit 9: PID41 */ +# define PMC_PID42 (1 << 10) /* Bit 10: PID42 */ +# define PMC_PID43 (1 << 11) /* Bit 11: PID43 */ +# define PMC_PID44 (1 << 12) /* Bit 12: PID44 */ +# define PMC_PID45 (1 << 13) /* Bit 13: PID45 */ +# define PMC_PID46 (1 << 14) /* Bit 14: PID46 */ +# define PMC_PID47 (1 << 15) /* Bit 15: PID47 */ +# define PMC_PID48 (1 << 16) /* Bit 16: PID48 */ +# define PMC_PID49 (1 << 17) /* Bit 17: PID49 */ +# define PMC_PID50 (1 << 18) /* Bit 18: PID50 */ +# define PMC_PID51 (1 << 19) /* Bit 19: PID51 */ +# define PMC_PID52 (1 << 20) /* Bit 20: PID52 */ +# define PMC_PID53 (1 << 21) /* Bit 21: PID53 */ +# define PMC_PID56 (1 << 24) /* Bit 24: PID56 */ +# define PMC_PID57 (1 << 25) /* Bit 25: PID57 */ +# define PMC_PID58 (1 << 26) /* Bit 26: PID58 */ +# define PMC_PID59 (1 << 27) /* Bit 27: PID59 */ +# define PMC_PID60 (1 << 28) /* Bit 28: PID60 */ + +/* Peripheral Control Register */ + +#define PMC_PCR_PID_SHIFT (0) /* Bits 0-5: Peripheral ID */ +#define PMC_PCR_PID_MASK (63 < PMC_PCR_PID_SHIFT) +# define PMC_PCR_PID(n) ((uint32_t)(n) < PMC_PCR_PID_SHIFT) +#define PMC_PCR_CMD (1 << 12) /* Bit 12: Command */ +#define PMC_PCR_DIV_SHIFT (16) /* Bits 16-17: Divisor Value */ +#define PMC_PCR_DIV_MASK (3 < PMC_PCR_DIV_SHIFT) +# define PMC_PCR_DIV1 (0 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK */ +# define PMC_PCR_DIV2 (1 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/2 */ +# define PMC_PCR_DIV4 (2 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/4 */ +# define PMC_PCR_DIV8 (3 < PMC_PCR_DIV_SHIFT) /* Peripheral clock is MCK/8 */ +#define PMC_PCR_EN (1 << 28) /* Bit 28: Enable */ + +/* Oscillator Calibration Register */ + +#define PMC_OCR_CAL4_SHIFT (0) /* Bits 0-6: 4MHzRC Oscillator Calibration */ +#define PMC_OCR_CAL4_MASK (0x7f << PMC_OCR_CAL4_SHIFT) +# define PMC_OCR_CAL4(n) ((uint32_t)(n) << PMC_OCR_CAL4_SHIFT) +#define PMC_OCR_SEL4 (1 << 7) /* Bit 7: Select 4MHz RC Oscillator Calibration */ +#define PMC_OCR_CAL8_SHIFT (8) /* Bits 8-14: 8MHzRC Oscillator Calibration */ +#define PMC_OCR_CAL8_MASK (0x7f << PMC_OCR_CAL8_SHIFT) +# define PMC_OCR_CAL8(n) ((uint32_t)(n) << PMC_OCR_CAL8_SHIFT) +#define PMC_OCR_SEL8 (1 << 15) /* Bit 15: Select 8MHz RC Oscillator Calibration */ +#define PMC_OCR_CAL12_SHIFT (16) /* Bits 16-22: 12MHzRC Oscillator Calibration */ +#define PMC_OCR_CAL12_MASK (0x7f << PMC_OCR_CAL12_SHIFT) +# define PMC_OCR_CAL12(n) ((uint32_t)(n) << PMC_OCR_CAL12_SHIFT) +#define PMC_OCR_SEL12 (1 << 23) /* Bit 23: Select 12MHz RC Oscillator Calibration */ + +/* SleepWalking Enable Register 0: Use PMC_PIDL definitions */ +/* SleepWalking Disable Register 0: Use PMC_PIDL definitions */ +/* SleepWalking Status Register 0: Use PMC_PIDL definitions */ +/* SleepWalking Activity Status Register 0: Use PMC_PIDL definitions */ + +/* SleepWalking Enable Register 1: Use PMC_PIDH definitions */ +/* SleepWalking Disable Register 1: Use PMC_PIDH definitions */ +/* SleepWalking Status Register 1: Use PMC_PIDH definitions */ +/* SleepWalking Activity Status Register 1: Use PMC_PIDH definitions */ + +/* SleepWalking Activity In Progress Register */ + +#define PMC_SLPWK_AIPR_AIP (0) /* Bit 0: Activity in progress */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_PMC_H */ diff --git a/arch/arm/src/samv7/chip/sam_qspi.h b/arch/arm/src/samv7/chip/sam_qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..55605634e448eece48f94c50dfe462b6995fb0ee --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_qspi.h @@ -0,0 +1,274 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_qspi.h + * Quad SPI (QSPI) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_QSPI_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_QSPI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NQSPI > 0 + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General Characteristics **************************************************************/ + +#define SAM_QSPI_MINBITS 8 /* Minimum word width */ +#define SAM_QSPI_MAXBITS 16 /* Maximum word width */ + +/* QSPI register offsets ****************************************************************/ + +#define SAM_QSPI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_QSPI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_QSPI_RDR_OFFSET 0x0008 /* Receive Data Register */ +#define SAM_QSPI_TDR_OFFSET 0x000c /* Transmit Data Register */ +#define SAM_QSPI_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_QSPI_IER_OFFSET 0x0014 /* Interrupt Enable Register */ +#define SAM_QSPI_IDR_OFFSET 0x0018 /* Interrupt Disable Register */ +#define SAM_QSPI_IMR_OFFSET 0x001c /* Interrupt Mask Register */ +#define SAM_QSPI_SCR_OFFSET 0x0020 /* Serial Clock Register */ +#define SAM_QSPI_IAR_OFFSET 0x0030 /* Instruction Address Register */ +#define SAM_QSPI_ICR_OFFSET 0x0034 /* Instruction Code Register */ +#define SAM_QSPI_IFR_OFFSET 0x0038 /* Instruction Frame Register */ + /* 0x003c Reserved */ +#define SAM_QSPI_SMR_OFFSET 0x0040 /* Scrambling Mode Register */ +#define SAM_QSPI_SKR_OFFSET 0x0044 /* Scrambling Key Register */ + /* 0x0048–0x00e0 Reserved */ +#define SAM_QSPI_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +#define SAM_QSPI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0xec-0xfc: Reserved */ + +/* QSPI register addresses **************************************************************/ + +#define SAM_QSPI0_CR (SAM_QSPI0_BASE+SAM_QSPI_CR_OFFSET) /* Control Register */ +#define SAM_QSPI0_MR (SAM_QSPI0_BASE+SAM_QSPI_MR_OFFSET) /* Mode Register */ +#define SAM_QSPI0_RDR (SAM_QSPI0_BASE+SAM_QSPI_RDR_OFFSET) /* Receive Data Register */ +#define SAM_QSPI0_TDR (SAM_QSPI0_BASE+SAM_QSPI_TDR_OFFSET) /* Transmit Data Register */ +#define SAM_QSPI0_SR (SAM_QSPI0_BASE+SAM_QSPI_SR_OFFSET) /* Status Register */ +#define SAM_QSPI0_IER (SAM_QSPI0_BASE+SAM_QSPI_IER_OFFSET) /* Interrupt Enable Register */ +#define SAM_QSPI0_IDR (SAM_QSPI0_BASE+SAM_QSPI_IDR_OFFSET) /* Interrupt Disable Register */ +#define SAM_QSPI0_IMR (SAM_QSPI0_BASE+SAM_QSPI_IMR_OFFSET) /* Interrupt Mask Register */ +#define SAM_QSPI0_SCR (SAM_QSPI0_BASE+SAM_QSPI_SCR_OFFSET) /* Serial Clock Register */ +#define SAM_QSPI0_IAR (SAM_QSPI0_BASE+SAM_QSPI_IAR_OFFSET) /* Instruction Address Register */ +#define SAM_QSPI0_ICR (SAM_QSPI0_BASE+SAM_QSPI_ICR_OFFSET) /* Instruction Code Register */ +#define SAM_QSPI0_IFR (SAM_QSPI0_BASE+SAM_QSPI_IFR_OFFSET) /* Instruction Frame Register */ +#define SAM_QSPI0_SMR (SAM_QSPI0_BASE+SAM_QSPI_SMR_OFFSET) /* Scrambling Mode Register */ +#define SAM_QSPI0_SKR (SAM_QSPI0_BASE+SAM_QSPI_SKR_OFFSET) /* Scrambling Key Register */ +#define SAM_QSPI0_WPCR (SAM_QSPI0_BASE+SAM_QSPI_WPCR_OFFSET) /* Write Protection Control Register */ +#define SAM_QSPI0_WPSR (SAM_QSPI0_BASE+SAM_QSPI_WPSR_OFFSET) /* Write Protection Status Register */ + +#if SAMV7_NQSPI > 1 +# define SAM_QSPI1_CR (SAM_QSPI1_BASE+SAM_QSPI_CR_OFFSET) /* Control Register */ +# define SAM_QSPI1_MR (SAM_QSPI1_BASE+SAM_QSPI_MR_OFFSET) /* Mode Register */ +# define SAM_QSPI1_RDR (SAM_QSPI1_BASE+SAM_QSPI_RDR_OFFSET) /* Receive Data Register */ +# define SAM_QSPI1_TDR (SAM_QSPI1_BASE+SAM_QSPI_TDR_OFFSET) /* Transmit Data Register */ +# define SAM_QSPI1_SR (SAM_QSPI1_BASE+SAM_QSPI_SR_OFFSET) /* Status Register */ +# define SAM_QSPI1_IER (SAM_QSPI1_BASE+SAM_QSPI_IER_OFFSET) /* Interrupt Enable Register */ +# define SAM_QSPI1_IDR (SAM_QSPI1_BASE+SAM_QSPI_IDR_OFFSET) /* Interrupt Disable Register */ +# define SAM_QSPI1_IMR (SAM_QSPI1_BASE+SAM_QSPI_IMR_OFFSET) /* Interrupt Mask Register */ +# define SAM_QSPI1_SCR (SAM_QSPI1_BASE+SAM_QSPI_SCR_OFFSET) /* Serial Clock Register */ +# define SAM_QSPI1_IAR (SAM_QSPI1_BASE+SAM_QSPI_IAR_OFFSET) /* Instruction Address Register */ +# define SAM_QSPI1_ICR (SAM_QSPI1_BASE+SAM_QSPI_ICR_OFFSET) /* Instruction Code Register */ +# define SAM_QSPI1_IFR (SAM_QSPI1_BASE+SAM_QSPI_IFR_OFFSET) /* Instruction Frame Register */ +# define SAM_QSPI1_SMR (SAM_QSPI1_BASE+SAM_QSPI_SMR_OFFSET) /* Scrambling Mode Register */ +# define SAM_QSPI1_SKR (SAM_QSPI1_BASE+SAM_QSPI_SKR_OFFSET) /* Scrambling Key Register */ +# define SAM_QSPI1_WPCR (SAM_QSPI1_BASE+SAM_QSPI_WPCR_OFFSET) /* Write Protection Control Register */ +# define SAM_QSPI1_WPSR (SAM_QSPI1_BASE+SAM_QSPI_WPSR_OFFSET) /* Write Protection Status Register */ +#endif + +/* QSPI register bit definitions ********************************************************/ + +/* QSPI Control Register */ + +#define QSPI_CR_QSPIEN (1 << 0) /* Bit 0: QSPI Enable */ +#define QSPI_CR_QSPIDIS (1 << 1) /* Bit 1: QSPI Disable */ +#define QSPI_CR_SWRST (1 << 7) /* Bit 7: QSPI Software Reset */ +#define QSPI_CR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* QSPI Mode Register */ + +#define QSPI_MR_SMM (1 << 0) /* Bit 0: Serial Memory Mode */ +#define QSPI_MR_LLB (1 << 1) /* Bit 1: Local Loopback Enable */ +#define QSPI_MR_WDRBT (1 << 2) /* Bit 2: Wait Data Read Before Transfer */ +#define QSPI_MR_CSMODE_SHIFT (4) /* Bits 4-5: Chip Select Mode */ +#define QSPI_MR_CSMODE_MASK (3 << QSPI_MR_CSMODE_SHIFT) +# define QSPI_MR_CSMODE_NRELOAD (0 << QSPI_MR_CSMODE_SHIFT) /* CS deasserted if TD not reloaded */ +# define QSPI_MR_CSMODE_LASTXFER (1 << QSPI_MR_CSMODE_SHIFT) /* CS deasserted when LASTXFER transferred */ +# define QSPI_MR_CSMODE_SYSTEM (2 << QSPI_MR_CSMODE_SHIFT) /* CS deasserted after each transfer */ +#define QSPI_MR_NBBITS_SHIFT (8) /* Bits 8-11: Number Of Bits Per Transfer */ +#define QSPI_MR_NBBITS_MASK (15 << QSPI_MR_NBBITS_SHIFT) +# define QSPI_MR_NBBITS(n) ((uint32_t)((n)-SAM_QSPI_MINBITS) << QSPI_MR_NBBITS_SHIFT) +# define QSPI_MR_NBBITS_8BIT (0 << QSPI_MR_NBBITS_SHIFT) /* 8 bits for transfer */ +# define QSPI_MR_NBBITS_9BIT (1 << QSPI_MR_NBBITS_SHIFT) /* 9 bits for transfer */ +# define QSPI_MR_NBBITS_10BIT (2 << QSPI_MR_NBBITS_SHIFT) /* 10 bits for transfer */ +# define QSPI_MR_NBBITS_11BIT (3 << QSPI_MR_NBBITS_SHIFT) /* 11 bits for transfer */ +# define QSPI_MR_NBBITS_12BIT (4 << QSPI_MR_NBBITS_SHIFT) /* 12 bits for transfer */ +# define QSPI_MR_NBBITS_13BIT (5 << QSPI_MR_NBBITS_SHIFT) /* 13 bits for transfer */ +# define QSPI_MR_NBBITS_14BIT (6 << QSPI_MR_NBBITS_SHIFT) /* 14 bits for transfer */ +# define QSPI_MR_NBBITS_15BIT (7 << QSPI_MR_NBBITS_SHIFT) /* 15 bits for transfer */ +# define QSPI_MR_NBBITS_16BIT (8 << QSPI_MR_NBBITS_SHIFT) /* 16 bits for transfer */ +#define QSPI_MR_DLYBCT_SHIFT (16) /* Bits 16-23: Delay Between Consecutive Transfers */ +#define QSPI_MR_DLYBCT_MASK (0xff << QSPI_MR_DLYBCT_SHIFT) +# define QSPI_MR_DLYBCT(n) ((uint32_t)(n) << QSPI_MR_DLYBCT_SHIFT) +#define QSPI_MR_DLYCS_SHIFT (24) /* Bits 24-31: Minimum Inactive QCS Delay */ +#define QSPI_MR_DLYCS_MASK (0xff << QSPI_MR_DLYCS_SHIFT) +# define QSPI_MR_DLYCS(n) ((uint32_t)(n) << QSPI_MR_DLYCS_SHIFT) + +/* QSPI Receive Data Register */ + +#define QSPI_RDR_RD_SHIFT (0) /* Bits 0-15: Receive Data */ +#define QSPI_RDR_RD_MASK (0xffff << QSPI_RDR_RD_SHIFT) + +/* QSPI Transmit Data Register */ + +#define QSPI_TDR_TD_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define QSPI_TDR_TD_MASK (0xffff << QSPI_TDR_TD_SHIFT) + +/* QSPI Status Register, QSPI Interrupt Enable Register, QSPI Interrupt Disable Register, + * and QSPI Interrupt Mask Register (common bit fields) + */ + +#define QSPI_INT_RDRF (1 << 0) /* Bit 0: Receive Data Register Full Interrupt */ +#define QSPI_INT_TDRE (1 << 1) /* Bit 1: Transmit Data Register Empty Interrupt */ +#define QSPI_INT_TXEMPTY (1 << 2) /* Bit 2: Transmission Registers Empty Interrupt */ +#define QSPI_INT_OVRES (1 << 3) /* Bit 3: Overrun Error Interrupt */ +#define QSPI_INT_CSR (1 << 8) /* Bit 8: Chip Select Rise Interrupt */ +#define QSPI_SR_CSS (1 << 9) /* Bit 9: Chip Select Status Interrupt */ +#define QSPI_SR_INSTRE (1 << 10) /* Bit 10: Instruction End Status Interrupt */ +#define QSPI_SR_QSPIENS (1 << 24) /* Bit 24: QSPI Enable Status (SR only) */ + +#define QSPI_INT_ALL (0x0000070f) + +/* Serial Clock Register */ + +#define QSPI_SCR_CPOL (1 << 0) /* Bit 0: Clock Polarity */ +#define QSPI_SCR_CPHA (1 << 1) /* Bit 1: Clock Phase */ +#define QSPI_SCR_SCBR_SHIFT (8) /* Bits 8-15: Serial Clock Baud Rate */ +#define QSPI_SCR_SCBR_MASK (0xff << QSPI_SCR_SCBR_SHIFT) +# define QSPI_SCR_SCBR(n) ((uint32_t)(n) << QSPI_SCR_SCBR_SHIFT) +#define QSPI_SCR_DLYBS_SHIFT (16) /* Bits 16-23: Delay Before QSCK */ +#define QSPI_SCR_DLYBS_MASK (0xff << QSPI_SCR_DLYBS_SHIFT) +# define QSPI_SCR_DLYBS(n) ((uint32_t)(n) << QSPI_SCR_DLYBS_SHIFT) + +/* Instruction Address Register (32-bit value) */ + +/* Instruction Code Register */ + +#define QSPI_ICR_INST_SHIFT (0) /* Bits 0-7: Instruction Code */ +#define QSPI_ICR_INST_MASK (0xff << QSPI_ICR_INST_SHIFT) +# define QSPI_ICR_INST(n) ((uint32_t)(n) << QSPI_ICR_INST_SHIFT) +#define QSPI_ICR_OPT_SHIFT (16) /* Bits 16-23: Option Code */ +#define QSPI_ICR_OPT_MASK (0xff << QSPI_ICR_OPT_SHIFT) +# define QSPI_ICR_OPT(n) ((uint32_t)(n) << QSPI_ICR_OPT_SHIFT) + +/* Instruction Frame Register */ + +#define QSPI_IFR_WIDTH_SHIFT (0) /* Bits 0-2: Width of Instruction Code, + * Address, Option Code and Data */ +#define QSPI_IFR_WIDTH_MASK (7 << QSPI_IFR_WIDTH_SHIFT) + /* Instruction Address-Option Data */ +# define QSPI_IFR_WIDTH_SINGLE (0 << QSPI_IFR_WIDTH_SHIFT) /* Single-bit Single-bit Single-bit */ +# define QSPI_IFR_WIDTH_DUALOUT (1 << QSPI_IFR_WIDTH_SHIFT) /* Single-bit Single-bit Dual */ +# define QSPI_IFR_WIDTH_QUADOUT (2 << QSPI_IFR_WIDTH_SHIFT) /* Single-bit Single-bit Quad */ +# define QSPI_IFR_WIDTH_DUALIO (3 << QSPI_IFR_WIDTH_SHIFT) /* Single-bit Dual Dual */ +# define QSPI_IFR_WIDTH_QUADIO (4 << QSPI_IFR_WIDTH_SHIFT) /* Single-bit Quad Quad */ +# define QSPI_IFR_WIDTH_DUALCMD (5 << QSPI_IFR_WIDTH_SHIFT) /* Dual Dual Dual */ +# define QSPI_IFR_WIDTH_QUADCMD (6 << QSPI_IFR_WIDTH_SHIFT) /* Quad Quad Quad */ +#define QSPI_IFR_INSTEN (1 << 4) /* Bit 4: Instruction Enable */ +#define QSPI_IFR_ADDREN (1 << 5) /* Bit 5: Address Enable */ +#define QSPI_IFR_OPTEN (1 << 6) /* Bit 6: Option Enable */ +#define QSPI_IFR_DATAEN (1 << 7) /* Bit 7: Data Enable */ +#define QSPI_IFR_OPTL_SHIFT (8) /* Bits 8-9: Option Code Length */ +#define QSPI_IFR_OPTL_MASK (3 << QSPI_IFR_OPTL_SHIFT) +# define QSPI_IFR_OPTL_1BIT (0 << QSPI_IFR_OPTL_SHIFT) /* Option is 1 bit */ +# define QSPI_IFR_OPTL_2BIT (1 << QSPI_IFR_OPTL_SHIFT) /* Option is 2 bits */ +# define QSPI_IFR_OPTL_4BIT (2 << QSPI_IFR_OPTL_SHIFT) /* Option is 4 bits */ +# define QSPI_IFR_OPTL_8BIT (3 << QSPI_IFR_OPTL_SHIFT) /* Option is 8 bits */ +#define QSPI_IFR_ADDRL (1 << 10) /* Bit 10: Address Length */ +# define QSPI_IFR_ADDRL_24BIT (0 << 10) /* 0=24-bit */ +# define QSPI_IFR_ADDRL_32BIT (1 << 10) /* 1=32-bit */ +#define QSPI_IFR_TFRTYP_SHIFT (12) /* Bits 12-13: Data Transfer Type */ +#define QSPI_IFR_TFRTYP_MASK (3 << QSPI_IFR_TFRTYP_SHIFT) +# define QSPI_IFR_TFRTYP_READ (0 << QSPI_IFR_TFRTYP_SHIFT) /* Read transfer from serial memory */ +# define QSPI_IFR_TFRTYP_RDMEM (1 << QSPI_IFR_TFRTYP_SHIFT) /* Read data transfer from serial memory */ +# define QSPI_IFR_TFRTYP_WRITE (2 << QSPI_IFR_TFRTYP_SHIFT) /* Write transfer into serial memory */ +# define QSPI_IFR_TFRTYP_WRMEM (3 << QSPI_IFR_TFRTYP_SHIFT) /* Write data transfer the serial memory */ +#define QSPI_IFR_CRM (1 << 14) /* Bit 14: Continuous Read Mode */ +#define QSPI_IFR_NBDUM_SHIFT (16) /* Bits 16-20: Number Of Dummy Cycles */ +#define QSPI_IFR_NBDUM_MASK (31 << QSPI_IFR_NBDUM_SHIFT) +# define QSPI_IFR_NBDUM(n) ((uint32_t)(n) << QSPI_IFR_NBDUM_SHIFT) + +/* Scrambling Mode Register */ + +#define QSPI_SMR_SCREN (1 << 0) /* Bit 0: Scrambling/Unscrambling Enable */ +#define QSPI_SMR_RVDIS (1 << 1) /* Bit 1: Scrambling/Unscrambling Random Value Disable */ + +/* Scrambling Key Register (32-bit value) */ + +/* QSPI Write Protection Control Register */ + +#define QSPI_WPCR_WPEN (1 << 0) /* Bit 0: QSPI Write Protection Enable */ +#define QSPI_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: QSPI Write Protection Key Password */ +#define QSPI_WPCR_WPKEY_MASK (0x00ffffff << QSPI_WPCR_WPKEY_SHIFT) +# define QSPI_WPCR_WPKEY (0x00515350 << QSPI_WPCR_WPKEY_SHIFT) + +/* QSPI Write Protection Status Register */ + +#define QSPI_WPSR_WPVS (1 << 0) /* Bit 0: QSPI Write Protection Violation Status */ +#define QSPI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-15: QSPI Write Protection Violation Source */ +#define QSPI_WPSR_WPVSRC_MASK (0xff << QSPI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* SAMV7_NQSPI > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_QSPI_H */ diff --git a/arch/arm/src/samv7/chip/sam_rstc.h b/arch/arm/src/samv7/chip/sam_rstc.h new file mode 100644 index 0000000000000000000000000000000000000000..ed15f4301510e6ac2d67da76bf242ef6c9e74fc5 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_rstc.h @@ -0,0 +1,110 @@ +/**************************************************************************************** + * arch/arm/src/samv71/chip/sam_rstc.h + * Reset Controller (RSTC) definitions for the SAMV71 + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Michael Spahlinger + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RSTC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RSTC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RSTC register offsets ****************************************************************/ + +#define SAM_RSTC_CR_OFFSET 0x00 /* Control Register */ +#define SAM_RSTC_SR_OFFSET 0x04 /* Status Register */ +#define SAM_RSTC_MR_OFFSET 0x08 /* Mode Register */ + +/* RSTC register addresses **************************************************************/ + +#define SAM_RSTC_CR (SAM_RSTC_BASE+SAM_RSTC_CR_OFFSET) +#define SAM_RSTC_SR (SAM_RSTC_BASE+SAM_RSTC_SR_OFFSET) +#define SAM_RSTC_MR (SAM_RSTC_BASE+SAM_RSTC_MR_OFFSET) + +/* RSTC register bit definitions ********************************************************/ + +/* Reset Controller Control Register */ + +#define RSTC_CR_PROCRST (1 << 0) /* Bit 0: Processor Reset */ +#define RSTC_CR_EXTRST (1 << 3) /* Bit 3: External Reset */ +#define RSTC_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define RSTC_CR_KEY_MASK (0xff << RSTC_CR_KEY_SHIFT) +# define RSTC_CR_KEY (0xa5 << RSTC_CR_KEY_SHIFT) + +/* Reset Controller Status Register */ + +#define RSTC_SR_URSTS (1 << 0) /* Bit 0: User Reset Status */ +#define RSTC_SR_RSTTYP_SHIFT (8) /* Bits 8-10: Reset Type */ +#define RSTC_SR_RSTTYP_MASK (7 << RSTC_SR_RSTTYP_SHIFT) +# define RSTC_SR_RSTTYP_PWRUP (0 << RSTC_SR_RSTTYP_SHIFT) /* General Reset */ +# define RSTC_SR_RSTTYP_BACKUP (1 << RSTC_SR_RSTTYP_SHIFT) /* Backup Reset */ +# define RSTC_SR_RSTTYP_WDOG (2 << RSTC_SR_RSTTYP_SHIFT) /* Watchdog Reset */ +# define RSTC_SR_RSTTYP_SWRST (3 << RSTC_SR_RSTTYP_SHIFT) /* Software Reset */ +# define RSTC_SR_RSTTYP_NRST (4 << RSTC_SR_RSTTYP_SHIFT) /* User Reset NRST pin */ +#define RSTC_SR_NRSTL (1 << 16) /* Bit 16: NRST Pin Level */ +#define RSTC_SR_SRCMP (1 << 17) /* Bit 17: Software Reset Command in Progress */ + +/* Reset Controller Mode Register */ + +#define RSTC_MR_URSTEN (1 << 0) /* Bit 0: User Reset Enable */ +#define RSTC_MR_URSTIEN (1 << 4) /* Bit 4: User Reset Interrupt Enable */ +#define RSTC_MR_ERSTL_SHIFT (8) /* Bits 8-11: External Reset Length */ +#define RSTC_MR_ERSTL_MASK (15 << RSTC_MR_ERSTL_SHIFT) +# define RSTC_MR_ERSTL(n) ((uint32_t)(n) << RSTC_MR_ERSTL_SHIFT) +#define RSTC_MR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define RSTC_MR_KEY_MASK (0xff << RSTC_CR_KEY_SHIFT) +# define RSTC_MR_KEY (0xa5 << RSTC_CR_KEY_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RSTC_H */ diff --git a/arch/arm/src/samv7/chip/sam_rtc.h b/arch/arm/src/samv7/chip/sam_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1feeb881f6edd12809ac8aa297d46cba0c4d82 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_rtc.h @@ -0,0 +1,270 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_rtc.h + * Real-time Clock (RTC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RTC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RTC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* RTC register offsets *****************************************************************/ + +#define SAM_RTC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_RTC_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_RTC_TIMR_OFFSET 0x0008 /* Time Register */ +#define SAM_RTC_CALR_OFFSET 0x000c /* Calendar Register */ +#define SAM_RTC_TIMALR_OFFSET 0x0010 /* Time Alarm Register */ +#define SAM_RTC_CALALR_OFFSET 0x0014 /* Calendar Alarm Register */ +#define SAM_RTC_SR_OFFSET 0x0018 /* Status Register */ +#define SAM_RTC_SCCR_OFFSET 0x001c /* Status Clear Command Register */ +#define SAM_RTC_IER_OFFSET 0x0020 /* Interrupt Enable Register */ +#define SAM_RTC_IDR_OFFSET 0x0024 /* Interrupt Disable Register */ +#define SAM_RTC_IMR_OFFSET 0x0028 /* Interrupt Mask Register */ +#define SAM_RTC_VER_OFFSET 0x002c /* Valid Entry Register */ + +/* RTC register addresses ***************************************************************/ + +#define SAM_RTC_CR (SAM_RTCC_VBASE+SAM_RTC_CR_OFFSET) +#define SAM_RTC_MR (SAM_RTCC_VBASE+SAM_RTC_MR_OFFSET) +#define SAM_RTC_TIMR (SAM_RTCC_VBASE+SAM_RTC_TIMR_OFFSET) +#define SAM_RTC_CALR (SAM_RTCC_VBASE+SAM_RTC_CALR_OFFSET) +#define SAM_RTC_TIMALR (SAM_RTCC_VBASE+SAM_RTC_TIMALR_OFFSET) +#define SAM_RTC_CALALR (SAM_RTCC_VBASE+SAM_RTC_CALALR_OFFSET) +#define SAM_RTC_SR (SAM_RTCC_VBASE+SAM_RTC_SR_OFFSET) +#define SAM_RTC_SCCR (SAM_RTCC_VBASE+SAM_RTC_SCCR_OFFSET) +#define SAM_RTC_IER (SAM_RTCC_VBASE+SAM_RTC_IER_OFFSET) +#define SAM_RTC_IDR (SAM_RTCC_VBASE+SAM_RTC_IDR_OFFSET) +#define SAM_RTC_IMR (SAM_RTCC_VBASE+SAM_RTC_IMR_OFFSET) +#define SAM_RTC_VER (SAM_RTCC_VBASE+SAM_RTC_VER_OFFSET) + +/* RTC register bit definitions *********************************************************/ + +/* RTC Control Register */ + +#define RTC_CR_UPDTIM (1 << 0) /* Bit 0: Update Request Time Register */ +#define RTC_CR_UPDCAL (1 << 1) /* Bit 1: Update Request Calendar Register */ +#define RTC_CR_TIMEVSEL_SHIFT (8) /* Bits 8-9: Time Event Selection */ +#define RTC_CR_TIMEVSEL_MASK (3 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIN (0 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_HOUR (1 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_MIDNIGHT (2 << RTC_CR_TIMEVSEL_SHIFT) +# define RTC_CR_TIMEVSEL_NOON (3 << RTC_CR_TIMEVSEL_SHIFT) +#define RTC_CR_CALEVSEL_SHIFT (16) /* Bits 16-17: Calendar Event Selection */ +#define RTC_CR_CALEVSEL_MASK (3 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_WEEK (0 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_MONTH (1 << RTC_CR_CALEVSEL_SHIFT) +# define RTC_CR_CALEVSEL_YEAR (2 << RTC_CR_CALEVSEL_SHIFT) + +/* RTC Mode Register */ + +#define RTC_MR_HRMOD (1 << 0) /* Bit 0: 12-/24-hour Mode */ +#define RTC_MR_PERSIAN (1 << 1) /* Bit 1: PERSIAN Calendar */ +#define RTC_MR_NEGPPM (1 << 4) /* Bit 4: NEGative PPM Correction */ +#define RTC_MR_CORRECTION_SHIFT (8) /* Bits 8-14: Slow Clock Correction */ +#define RTC_MR_CORRECTION_MASK (0x7f << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_CORRECTION_NONE (0 << RTC_MR_CORRECTION_SHIFT) +# define RTC_MR_CORRECTION(n) ((uint8_t)(n) << RTC_MR_CORRECTION_SHIFT) +#define RTC_MR_HIGHPPM (1 << 15) /* Bit 15: HIGH PPM Correction */ +#define RTC_MR_OUT0_SHIFT (16) /* Bits 16-18: RTCOUT0 OutputSource Selection */ +#define RTC_MR_OUT0_MASK (7 << RTC_MR_OUT0_SHIFT) +# define RTC_MR_OUT0_NO_WAVE (0 << RTC_MR_OUT0_SHIFT) /* No waveform, stuck at 0 */ +# define RTC_MR_OUT0_FREQ1HZ (1 << RTC_MR_OUT0_SHIFT) /* 1 Hz square wave */ +# define RTC_MR_OUT0_FREQ32HZ (2 << RTC_MR_OUT0_SHIFT) /* 32 Hz square wave */ +# define RTC_MR_OUT0_FREQ64HZ (3 << RTC_MR_OUT0_SHIFT) /* 64 Hz square wave */ +# define RTC_MR_OUT0_FREQ512HZ (4 << RTC_MR_OUT0_SHIFT) /* 512 Hz square wave */ +# define RTC_MR_OUT0_ALARM_TOGGLE (5 << RTC_MR_OUT0_SHIFT) /* Output toggles when alarm flag rises */ +# define RTC_MR_OUT0_ALARM_FLAG (6 << RTC_MR_OUT0_SHIFT) /* Output is a copy of the alarm flag */ +# define RTC_MR_OUT0_PROG_PULSE (7 << RTC_MR_OUT0_SHIFT) /* Duty cycle programmable pulse */ +#define RTC_MR_OUT1_SHIFT (10) /* Bits 20-22: RTCOUT1 Output Source Selection */ +#define RTC_MR_OUT1_MASK (7 << RTC_MR_OUT1_SHIFT) +# define RTC_MR_OUT1_NO_WAVE (0 << RTC_MR_OUT1_SHIFT) /* No waveform, stuck at 0 */ +# define RTC_MR_OUT1_FREQ1HZ (1 << RTC_MR_OUT1_SHIFT) /* 1 Hz square wave */ +# define RTC_MR_OUT1_FREQ32HZ (2 << RTC_MR_OUT1_SHIFT) /* 32 Hz square wave */ +# define RTC_MR_OUT1_FREQ64HZ (3 << RTC_MR_OUT1_SHIFT) /* 64 Hz square wave */ +# define RTC_MR_OUT1_FREQ512HZ (4 << RTC_MR_OUT1_SHIFT) /* 512 Hz square wave */ +# define RTC_MR_OUT1_ALARM_TOGGLE (5 << RTC_MR_OUT1_SHIFT) /* Output toggles when alarm flag rises */ +# define RTC_MR_OUT1_ALARM_FLAG (6 << RTC_MR_OUT1_SHIFT) /* Output is a copy of the alarm flag */ +# define RTC_MR_OUT1_PROG_PULSE (7 << RTC_MR_OUT1_SHIFT) /* Duty cycle programmable pulse */ +#define RTC_MR_THIGH_SHIFT (24) /* Bits 24-16: High Duration of the Output Pulse */ +#define RTC_MR_THIGH_MASK (7 << RTC_MR_THIGH_SHIFT) +# define RTC_MR_THIGH_31MS (0 << RTC_MR_THIGH_SHIFT) /* 31.2 ms */ +# define RTC_MR_THIGH_16MS (1 << RTC_MR_THIGH_SHIFT) /* 15.6 ms */ +# define RTC_MR_THIGH_4MS (2 << RTC_MR_THIGH_SHIFT) /* 3.91 ms */ +# define RTC_MR_THIGH_976US (3 << RTC_MR_THIGH_SHIFT) /* 976 μs */ +# define RTC_MR_THIGH_488US (4 << RTC_MR_THIGH_SHIFT) /* 488 μs */ +# define RTC_MR_THIGH_122US (5 << RTC_MR_THIGH_SHIFT) /* 122 μs */ +# define RTC_MR_THIGH_30US (6 << RTC_MR_THIGH_SHIFT) /* 30.5 μs */ +# define RTC_MR_THIGH_15US (7 << RTC_MR_THIGH_SHIFT) /* 15.2 μs */ +#define RTC_MR_TPERIOD_SHIFT (28) /* Bits 28-29: Period of the Output Pulse */ +#define RTC_MR_TPERIOD_MASK (3 << RTC_MR_TPERIOD_SHIFT) +# define RTC_MR_TPERIOD_ 1S (0 << RTC_MR_TPERIOD_SHIFT) /* 1 second */ +# define RTC_MR_TPERIOD_ 500MS (1 << RTC_MR_TPERIOD_SHIFT) /* 500 ms */ +# define RTC_MR_TPERIOD_ 250MS (2 << RTC_MR_TPERIOD_SHIFT) /* 250 ms */ +# define RTC_MR_TPERIOD_ 125MS (3 << RTC_MR_TPERIOD_SHIFT) /* 125 ms */ + +/* RTC Time Register */ + +#define RTC_TIMR_SEC_SHIFT (0) /* Bits 0-6: Current Second */ +#define RTC_TIMR_SEC_MASK (0x7f << RTC_TIMR_SEC_SHIFT) +# define RTC_TIMR_SEC(n) ((uint32_t)(n) << RTC_TIMR_SEC_SHIFT) +#define RTC_TIMR_MIN_SHIFT (8) /* Bits 8-14: Current Minute */ +#define RTC_TIMR_MIN_MASK (0x7f << RTC_TIMR_MIN_SHIFT) +# define RTC_TIMR_MIN(n) ((uint32_t)(n) << RTC_TIMR_MIN_SHIFT) +#define RTC_TIMR_HOUR_SHIFT (16) /* Bits 16-21: Current Hour */ +#define RTC_TIMR_HOUR_MASK (0x3f << RTC_TIMR_HOUR_SHIFT) +# define RTC_TIMR_HOUR(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_TIMR_AMPM (1 << 22) /* Bit 22: Ante Meridiem Post Meridiem Indicator */ + +/* RTC Calendar Register */ + +#define RTC_CALR_CENT_SHIFT (0) /* Bits 0-6: Current Century */ +#define RTC_CALR_CENT_MASK (0x7f << RTC_CALR_CENT_SHIFT) +# define RTC_CALR_CENT(n) ((uint32_t)(n) << RTC_TIMR_HOUR_SHIFT) +#define RTC_CALR_YEAR_SHIFT (8) /* Bits 8-15: Current Year */ +#define RTC_CALR_YEAR_MASK (0xff << RTC_CALR_YEAR_SHIFT) +# define RTC_CALR_YEAR(n) ((uint32_t)(n) << RTC_CALR_YEAR_SHIFT) +#define RTC_CALR_MONTH_SHIFT (16) /* Bits 16-20: Current Month */ +#define RTC_CALR_MONTH_MASK (0x1f << RTC_CALR_MONTH_SHIFT) +# define RTC_CALR_MONTH(n) ((uint32_t)(n) << RTC_CALR_MONTH_SHIFT) +#define RTC_CALR_DAY_SHIFT (21) /* Bits 21-23: Current Day in Current Week */ +#define RTC_CALR_DAY_MASK (7 << RTC_CALR_DAY_SHIFT) +# define RTC_CALR_DAY(n) ((uint32_t)(n) << RTC_CALR_DAY_SHIFT) +#define RTC_CALR_DATE_SHIFT (24) /* Bits 24-29: Current Day in Current Month */ +#define RTC_CALR_DATE_MASK (0x3f << RTC_CALR_DATE_SHIFT) +# define RTC_CALR_DATE(n) ((uint32_t)(n) << RTC_CALR_DATE_SHIFT) + +/* RTC Time Alarm Register */ + +#define RTC_TIMALR_SEC_SHIFT (0) /* Bits 0-6: Second Alarm */ +#define RTC_TIMALR_SEC_MASK (0x7f << RTC_TIMALR_SEC_SHIFT) +# define RTC_TIMALR_SEC(n) ((uint32_t)(n) << RTC_TIMALR_SEC_SHIFT) +#define RTC_TIMALR_SECEN (1 << 7) /* Bit 7: Second Alarm Enable */ +#define RTC_TIMALR_MIN_SHIFT (8) /* Bits 8-14: Minute Alarm */ +#define RTC_TIMALR_MIN_MASK (0x7f << RTC_TIMALR_MIN_SHIFT) +# define RTC_TIMALR_MIN(n) ((uint32_t)(n) << RTC_TIMALR_MIN_SHIFT) +#define RTC_TIMALR_MINEN (1 << 15) /* Bit 15: Minute Alarm Enable */ +#define RTC_TIMALR_HOUR_SHIFT (16) /* Bits 16-21: Hour Alarm */ +#define RTC_TIMALR_HOUR_MASK (0x3f << RTC_TIMALR_HOUR_SHIFT) +# define RTC_TIMALR_HOUR(n) ((uint32_t)(n) << RTC_TIMALR_HOUR_SHIFT) +#define RTC_TIMALR_AMPM (1 << 22) /* Bit 22: AM/PM Indicator */ +#define RTC_TIMALR_HOUREN (1 << 23) /* Bit 23: Hour Alarm Enable */ + +/* RTC Calendar Alarm Register */ + +#define RTC_CALALR_MONTH_SHIFT (16) /* Bits 16-20: Month Alarm */ +#define RTC_CALALR_MONTH_MASK (0x1f << RTC_CALALR_MONTH_SHIFT) +# define RTC_CALALR_MONTH(n) ((uint32_t)(n) << RTC_CALALR_MONTH_SHIFT) +#define RTC_CALALR_MTHEN (1 << 23) /* Bit 23: Month Alarm Enable */ +#define RTC_CALALR_DATE_SHIFT (24) /* Bits 24-29: Date Alarm */ +#define RTC_CALALR_DATE_MASK (0x3f << RTC_CALALR_DATE_SHIFT) +# define RTC_CALALR_DATE(n) ((uint32_t)(n) << RTC_CALALR_DATE_SHIFT) +#define RTC_CALALR_DATEEN (1 << 31) /* Bit 31: Date Alarm Enable */ + +/* RTC Status Register */ + +#define RTC_SR_ACKUPD (1 << 0) /* Bit 0: Acknowledge for Update */ +#define RTC_SR_ALARM (1 << 1) /* Bit 1: Alarm Flag */ +#define RTC_SR_SEC (1 << 2) /* Bit 2: Second Event */ +#define RTC_SR_TIMEV (1 << 3) /* Bit 3: Time Event */ +#define RTC_SR_CALEV (1 << 4) /* Bit 4: Calendar Event */ +#define RTC_SR_TDERR (1 << 5) /* Bit 5: Time and/or Date Free Running Error */ + +/* RTC Status Clear Command Register */ + +#define RTC_SCCR_ACKCLR (1 << 0) /* Bit 0: Acknowledge Clear */ +#define RTC_SCCR_ALRCLR (1 << 1) /* Bit 1: Alarm Clear */ +#define RTC_SCCR_SECCLR (1 << 2) /* Bit 2: Second Clear */ +#define RTC_SCCR_TIMCLR (1 << 3) /* Bit 3: Time Clear */ +#define RTC_SCCR_CALCLR (1 << 4) /* Bit 4: Calendar Clear */ +#define RTC_SCCR_TDERRCLR (1 << 5) /* Bit 5: Time and/or Date Free Running Error Clear */ + +/* RTC Interrupt Enable Register */ + +#define RTC_IER_ACKEN (1 << 0) /* Bit 0: Acknowledge Update Interrupt Enable */ +#define RTC_IER_ALREN (1 << 1) /* Bit 1: Alarm Interrupt Enable */ +#define RTC_IER_SECEN (1 << 2) /* Bit 2: Second Event Interrupt Enable */ +#define RTC_IER_TIMEN (1 << 3) /* Bit 3: Time Event Interrupt Enable */ +#define RTC_IER_CALEN (1 << 4) /* Bit 4: Calendar Event Interrupt Enable */ +#define RTC_IER_TDERREN (1 << 5) /* Bit 5: Time and/or Date Free Running Error Enable */ + +/* RTC Interrupt Disable Register */ + +#define RTC_IDR_ACKDIS (1 << 0) /* Bit 0: Acknowledge Update Interrupt Disable */ +#define RTC_IDR_ALRDIS (1 << 1) /* Bit 1: Alarm Interrupt Disable */ +#define RTC_IDR_SECDIS (1 << 2) /* Bit 2: Second Event Interrupt Disable */ +#define RTC_IDR_TIMDIS (1 << 3) /* Bit 3: Time Event Interrupt Disable */ +#define RTC_IDR_CALDIS (1 << 4) /* Bit 4: Calendar Event Interrupt Disable */ +#define RTC_IDR_TDERRDIS (1 << 5) /* Bit 5: Time and/or Date Free Running Error Disable */ + +/* RTC Interrupt Mask Register */ + +#define RTC_IMR_ACK (1 << 0) /* Bit 0: Acknowledge Update Interrupt Mask */ +#define RTC_IMR_ALR (1 << 1) /* Bit 1: Alarm Interrupt Mask */ +#define RTC_IMR_SEC (1 << 2) /* Bit 2: Second Event Interrupt Mask */ +#define RTC_IMR_TIM (1 << 3) /* Bit 3: Time Event Interrupt Mask */ +#define RTC_IMR_CAL (1 << 4) /* Bit 4: Calendar Event Interrupt Mask */ +#define RTC_IMR_TDERR (1 << 5) /* Bit 5: Time and/or Date Free Running Error Mask */ + +/* RTC Valid Entry Register */ + +#define RTC_VER_NVTIM (1 << 0) /* Bit 0: Non-valid Time */ +#define RTC_VER_NVCAL (1 << 1) /* Bit 1: Non-valid Calendar */ +#define RTC_VER_NVTIMALR (1 << 2) /* Bit 2: Non-valid Time Alarm */ +#define RTC_VER_NVCALALR (1 << 3) /* Bit 3: Non-valid Calendar Alarm */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_RTC_H */ diff --git a/arch/arm/src/samv7/chip/sam_sdramc.h b/arch/arm/src/samv7/chip/sam_sdramc.h new file mode 100644 index 0000000000000000000000000000000000000000..40653f52ee5b068c76a51368566055a63fe931d0 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_sdramc.h @@ -0,0 +1,207 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_sdramc.h + * SDRAM Controler (SDRAMC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SDRAMC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SDRAMC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SDRAMC register offsets **************************************************************/ + +#define SAM_SDRAMC_MR_OFFSET 0x0000 /* SDRAMC Mode Register */ +#define SAM_SDRAMC_TR_OFFSET 0x0004 /* SDRAMC Refresh Timer Register */ +#define SAM_SDRAMC_CR_OFFSET 0x0008 /* SDRAMC Configuration Register */ +#define SAM_SDRAMC_LPR_OFFSET 0x0010 /* SDRAMC Low Power Register */ +#define SAM_SDRAMC_IER_OFFSET 0x0014 /* SDRAMC Interrupt Enable Register */ +#define SAM_SDRAMC_IDR_OFFSET 0x0018 /* SDRAMC Interrupt Disable Register */ +#define SAM_SDRAMC_IMR_OFFSET 0x001c /* SDRAMC Interrupt Mask Register */ +#define SAM_SDRAMC_ISR_OFFSET 0x0020 /* SDRAMC Interrupt Status Register */ +#define SAM_SDRAMC_MDR_OFFSET 0x0024 /* SDRAMC Memory Device Register */ +#define SAM_SDRAMC_CFR1_OFFSET 0x0028 /* SDRAMC Configuration Register 1 */ +#define SAM_SDRAMC_OCMS_OFFSET 0x002c /* SDRAMC OCMS Register */ +#define SAM_SDRAMC_OCMS_KEY1_OFFSET 0x0030 /* SDRAMC OCMS KEY1 Register */ +#define SAM_SDRAMC_OCMS_KEY2_OFFSET 0x0034 /* SDRAMC OCMS KEY2 Register */ + +/* SDRAMC register addresses ************************************************************/ + +#define SAM_SDRAMC_MR (SAM_SDRAMC_BASE+SAM_SDRAMC_MR_OFFSET) +#define SAM_SDRAMC_TR (SAM_SDRAMC_BASE+SAM_SDRAMC_TR_OFFSET) +#define SAM_SDRAMC_CR (SAM_SDRAMC_BASE+SAM_SDRAMC_CR_OFFSET) +#define SAM_SDRAMC_LPR (SAM_SDRAMC_BASE+SAM_SDRAMC_LPR_OFFSET) +#define SAM_SDRAMC_IER (SAM_SDRAMC_BASE+SAM_SDRAMC_IER_OFFSET) +#define SAM_SDRAMC_IDR (SAM_SDRAMC_BASE+SAM_SDRAMC_IDR_OFFSET) +#define SAM_SDRAMC_IMR (SAM_SDRAMC_BASE+SAM_SDRAMC_IMR_OFFSET) +#define SAM_SDRAMC_ISR (SAM_SDRAMC_BASE+SAM_SDRAMC_ISR_OFFSET) +#define SAM_SDRAMC_MDR (SAM_SDRAMC_BASE+SAM_SDRAMC_MDR_OFFSET) +#define SAM_SDRAMC_CFR1 (SAM_SDRAMC_BASE+SAM_SDRAMC_CFR1_OFFSET) +#define SAM_SDRAMC_OCMS (SAM_SDRAMC_BASE+SAM_SDRAMC_OCMS_OFFSET) +#define SAM_SDRAMC_OCMS_KEY1 (SAM_SDRAMC_BASE+SAM_SDRAMC_OCMS_KEY1_OFFSET) +#define SAM_SDRAMC_OCMS_KEY2 (SAM_SDRAMC_BASE+SAM_SDRAMC_OCMS_KEY2_OFFSET) + +/* SDRAMC register bit definitions ******************************************************/ + +/* SDRAMC Mode Register */ + +#define SDRAMC_MR_MODE_SHIFT (0) /* Bits 0-2: SDRAMC Command Mode */ +#define SDRAMC_MR_MODE_MASK (7 << SDRAMC_MR_MODE_SHIFT) +# define SDRAMC_MR_MODE_NORMAL (0 << SDRAMC_MR_MODE_SHIFT) /* Normal mode */ +# define SDRAMC_MR_MODE_NOP (1 << SDRAMC_MR_MODE_SHIFT) /* NOP when SDRAM accessed */ +# define SDRAMC_MR_MODE_PRECHARGE (2 << SDRAMC_MR_MODE_SHIFT) /* All Banks Precharge when SDRAM accessed */ +# define SDRAMC_MR_MODE_LOADMODE (3 << SDRAMC_MR_MODE_SHIFT) /* Load Mode Register when SDRAM accessed */ +# define SDRAMC_MR_MODE_AUTOREFRESH (4 << SDRAMC_MR_MODE_SHIFT) /* Auto-Refresh when SDRAM accessed */ +# define SDRAMC_MR_MODE_EXTLOADMODE (5 << SDRAMC_MR_MODE_SHIFT) /* Extended Load Mode Register when SDRAM accessed */ +# define SDRAMC_MR_MODE_PWRDOWN (6 << SDRAMC_MR_MODE_SHIFT) /* Deep power-down mode */ + +/* SDRAMC Refresh Timer Register */ + +#define SDRAMC_TR_MASK 0x00000fff /* Bits 0-11: SDRAMC Refresh Timer Count */ + +/* SDRAMC Configuration Register */ + +#define SDRAMC_CR_NC_SHIFT (0) /* Bits 0-1: Number of Column Bits */ +#define SDRAMC_CR_NC_MASK (3 << SDRAMC_CR_NC_SHIFT) +# define SDRAMC_CR_NC_COL8 (0 << SDRAMC_CR_NC_SHIFT) /* 8 column bits */ +# define SDRAMC_CR_NC_COL9 (1 << SDRAMC_CR_NC_SHIFT) /* 9 column bits */ +# define SDRAMC_CR_NC_COL10 (2 << SDRAMC_CR_NC_SHIFT) /* 10 column bits */ +# define SDRAMC_CR_NC_COL11 (3 << SDRAMC_CR_NC_SHIFT) /* 11 column bits */ +#define SDRAMC_CR_NR_SHIFT (2) /* Bits 2-3: Number of Row Bits */ +#define SDRAMC_CR_NR_MASK (3 << SDRAMC_CR_NR_SHIFT) +# define SDRAMC_CR_NR_ROW11 (0 << SDRAMC_CR_NR_SHIFT) /* 11 row bits */ +# define SDRAMC_CR_NR_ROW12 (1 << SDRAMC_CR_NR_SHIFT) /* 12 row bits */ +# define SDRAMC_CR_NR_ROW13 (2 << SDRAMC_CR_NR_SHIFT) /* 13 row bits */ +#define SDRAMC_CR_NB (1 << 4) /* Bit 4: Number of Banks */ +# define SDRAMC_CR_NB_BANK2 (0 << 4) /* 0=2 banks */ +# define SDRAMC_CR_NB_BANK4 (1 << 4) /* 1=4 banks */ +#define SDRAMC_CR_CAS_SHIFT (5) /* Bits 5-6: CAS Latency */ +#define SDRAMC_CR_CAS_MASK (3 << SDRAMC_CR_CAS_SHIFT) +# define SDRAMC_CR_CAS_LATENCY1 (0 << SDRAMC_CR_CAS_SHIFT) /* 1 cycle CAS latency */ +# define SDRAMC_CR_CAS_LATENCY2 (1 << SDRAMC_CR_CAS_SHIFT) /* 2 cycle CAS latency */ +# define SDRAMC_CR_CAS_LATENCY3 (2 << SDRAMC_CR_CAS_SHIFT) /* 3 cycle CAS latency */ +#define SDRAMC_CR_DBW (1 << 7) /* Bit 7: Data Bus Width */ +#define SDRAMC_CR_TWR_SHIFT (8) /* Bits 8-11: Write Recovery Delay */ +#define SDRAMC_CR_TWR_MASK (15 << SDRAMC_CR_TWR_SHIFT) +# define SDRAMC_CR_TWR(n) ((uint32_t)(n) << SDRAMC_CR_TWR_SHIFT) +#define SDRAMC_CR_TRCTRFC_SHIFT (12) /* Bits 12-15: Row Cycle Delay and Row Refresh Cycle */ +#define SDRAMC_CR_TRCTRFC_MASK (15 << SDRAMC_CR_TRCTRFC_SHIFT) +# define SDRAMC_CR_TRCTRFC(n) ((uint32_t)(n) << SDRAMC_CR_TRCTRFC_SHIFT) +#define SDRAMC_CR_TRP_SHIFT (16) /* Bits 16-19: Row Precharge Delay */ +#define SDRAMC_CR_TRP_MASK (15 << SDRAMC_CR_TRP_SHIFT) +# define SDRAMC_CR_TRP(n) ((uint32_t)(n) << SDRAMC_CR_TRP_SHIFT) +#define SDRAMC_CR_TRCD_SHIFT (20) /* Bits 20-23: Row to Column Delay */ +#define SDRAMC_CR_TRCD_MASK (15 << SDRAMC_CR_TRCD_SHIFT) +# define SDRAMC_CR_TRCD(n) ((uint32_t)(n) << SDRAMC_CR_TRCD_SHIFT) +#define SDRAMC_CR_TRAS_SHIFT (24) /* Bits 24-27: Active to Precharge Delay */ +#define SDRAMC_CR_TRAS_MASK (15 << SDRAMC_CR_TRAS_SHIFT) +# define SDRAMC_CR_TRAS(n) ((uint32_t)(n) << SDRAMC_CR_TRAS_SHIFT) +#define SDRAMC_CR_TXSR_SHIFT (28) /* Bits 28-31: Exit Self Refresh to Active Delay */ +#define SDRAMC_CR_TXSR_MASK (15 << SDRAMC_CR_TXSR_SHIFT) +# define SDRAMC_CR_TXSR(n) ((uint32_t)(n) << SDRAMC_CR_TXSR_SHIFT) + +/* SDRAMC Low Power Register */ + +#define SDRAMC_LPR_LPCB_SHIFT (0) /* Bits 0-1: Low-power Configuration Bits */ +#define SDRAMC_LPR_LPCB_MASK (3 << SDRAMC_LPR_LPCB_SHIFT) +# define SDRAMC_LPR_LPCB_DISABLED (0 << SDRAMC_LPR_LPCB_SHIFT) /* Low Power Feature is inhibited */ +# define SDRAMC_LPR_LPCB_REFRESH (1 << SDRAMC_LPR_LPCB_SHIFT) /* Self-refresh to SDRAM device */ +# define SDRAMC_LPR_LPCB_PWRDOWN (2 << SDRAMC_LPR_LPCB_SHIFT) /* Power-down to SDRAM after accesses */ +# define SDRAMC_LPR_LPCB_DPPWRDOWN (3 << SDRAMC_LPR_LPCB_SHIFT) /* Deep Power-down the SDRAM device */ +#define SDRAMC_LPR_PASR_SHIFT (4) /* Bits 4-6: Partial Array Self-refresh */ +#define SDRAMC_LPR_PASR_MASK (7 << SDRAMC_LPR_PASR_SHIFT) +#define SDRAMC_LPR_TCSR_SHIFT (8) /* Bits 8-9: Temperature Compensated Self-Refresh */ +#define SDRAMC_LPR_TCSR_MASK (3 << SDRAMC_LPR_TCSR_SHIFT) +# define SDRAMC_LPR_TCSR(n) ((uint32_t)(n) << SDRAMC_LPR_TCSR_SHIFT) +#define SDRAMC_LPR_DS_SHIFT (10) /* Bits 10-11: Drive Strength */ +#define SDRAMC_LPR_DS_MASK (3 << SDRAMC_LPR_DS_SHIFT) +# define SDRAMC_LPR_DS(n) ((uint32_t)(n) << SDRAMC_LPR_DS_SHIFT) +#define SDRAMC_LPR_TIMEOUT_SHIFT (12) /* Bits 12-13: Time to Define When Low-power Mode Is Enabled */ +#define SDRAMC_LPR_TIMEOUT_MASK (3 << SDRAMC_LPR_TIMEOUT_SHIFT) +# define SDRAMC_LPR_TIMEOUT_LP (0 << SDRAMC_LPR_TIMEOUT_SHIFT) /* SDRAM low-power mode immediately */ +# define SDRAMC_LPR_TIMEOUT_LP64 (1 << SDRAMC_LPR_TIMEOUT_SHIFT) /* SDRAM low-power mode after 64 cycles */ +# define SDRAMC_LPR_TIMEOUT_LP128 (2 << SDRAMC_LPR_TIMEOUT_SHIFT) /* SDRAM low-power mode 128 cycles */ + +/* SDRAMC Interrupt Enable Register, SDRAMC Interrupt Disable Register, SDRAMC + * Interrupt Mask Register, and SDRAMC Interrupt Status Register. + */ + +#define SDRAMC_INT_RES (1 << 0) /* Bit 0: Refresh Error */ + +/* SDRAMC Memory Device Register */ + +#define SDRAMC_MDR_SHIFT (0) /* Bits 0-1: Memory Device Type */ +#define SDRAMC_MDR_MASK (3 << SDRAMC_MDR_SHIFT) +# define SDRAMC_MDR_SDRAM (0 << SDRAMC_MDR_SHIFT) /* SDRAM */ +# define SDRAMC_MDR_LPSDRAM (1 << SDRAMC_MDR_SHIFT) /* Low-power SDRAM */ + +/* SDRAMC Configuration Register 1 */ + +#define SDRAMC_CFR1_TMRD_SHIFT (0) /* Bits 0-3: Load Mode Register to Active/Refresh Command */ +#define SDRAMC_CFR1_TMRD_MASK (15 << SDRAMC_CFR1_TMRD_SHIFT) +# define SDRAMC_CFR1_TMRD(n) ((uint32_t)(n) << SDRAMC_CFR1_TMRD_SHIFT) +#define SDRAMC_CFR1_UNAL (1 << 8) /* Bit 8: Support Unaligned Access */ +# define SDRAMC_CFR1_UNAL_UNSUPP (0 << 8) /* 0=Unaligned access is not supported */ +# define SDRAMC_CFR1_UNAL_SUPPORTED (1 << 8) /* 1=Unaligned access is supported */ + +/* SDRAMC OCMS Register */ + +#define SDRAMC_OCMS_SDRSE (1 << 0) /* Bit 9: SDRAM Memory Controller Scrambling Enable */ + +/* SDRAMC OCMS KEY1 Register (32-bit value) */ +/* SDRAMC OCMS KEY2 Register (32-bit value) */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SDRAMC_H */ diff --git a/arch/arm/src/samv7/chip/sam_smc.h b/arch/arm/src/samv7/chip/sam_smc.h new file mode 100644 index 0000000000000000000000000000000000000000..3c69196711cb7452224de7039354ceac17dd241f --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_smc.h @@ -0,0 +1,213 @@ +/**************************************************************************************** + * arch/arm/src/ssamv7/chip/sam_smc.h + * Static Memory Controller (SMC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SMC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SMC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SMC register offsets *****************************************************************/ + +#define SAM_SMCCS_OFFSET(n) ((n) << 4) +# define SAM_SMCCS0_OFFSET 0x0000 /* SMC CS0 offset */ +# define SAM_SMCCS1_OFFSET 0x0010 /* SMC CS1 offset */ +# define SAM_SMCCS2_OFFSET 0x0020 /* SMC CS2 offset */ +# define SAM_SMCCS3_OFFSET 0x0030 /* SMC CS3 offset */ + +#define SAM_SMCCS_SETUP_OFFSET 0x0000 /* SMC Setup Register */ +#define SAM_SMCCS_PULSE_OFFSET 0x0004 /* SMC Pulse Register */ +#define SAM_SMCCS_CYCLE_OFFSET 0x0008 /* SMC Cycle Register */ +#define SAM_SMCCS_MODE_OFFSET 0x000c /* SMC Mode Register */ + +#define SAM_SMC_OCMS_OFFSET 0x0080 /* SMC OCMS Mode Register */ +#define SAM_SMC_KEY1_OFFSET 0x0084 /* SMC KEY1 Register */ +#define SAM_SMC_KEY2_OFFSET 0x0088 /* SMC KEY2 Register */ +#define SAM_SMC_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +#define SAM_SMC_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + +/* SMC register addresses ***************************************************************/ + +#define SAM_SMCCS_BASE(n) (SAM_SMC_BASE+SAM_SMCCS_OFFSET(n)) +# define SAM_SMC_CS0_BASE (SAM_SMC_BASE+SAM_SMCCS0_OFFSET) +# define SAM_SMC_CS1_BASE (SAM_SMC_BASE+SAM_SMCCS1_OFFSET) +# define SAM_SMC_CS2_BASE (SAM_SMC_BASE+SAM_SMCCS2_OFFSET) +# define SAM_SMC_CS3_BASE (SAM_SMC_BASE+SAM_SMCCS3_OFFSET) + +#define SAM_SMCCS_SETUP(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS_PULSE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS_CYCLE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_CYCLE_OFFSET) +#define SAM_SMCCS_MODE(n) (SAM_SMCCS_BASE(n)+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMCCS0_SETUP (SAM_SMC_CS0_BASE+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS0_PULSE (SAM_SMC_CS0_BASE+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS0_CYCLE (SAM_SMC_CS0_BASE+SAM_SMCCS_CYCLE_OFFSET) +#define SAM_SMCCS0_MODE (SAM_SMC_CS0_BASE+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMCCS1_SETUP (SAM_SMC_CS1_BASE+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS1_PULSE (SAM_SMC_CS1_BASE+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS1_CYCLE (SAM_SMC_CS1_BASE+SAM_SMCCS_CYCLE_OFFSET) +#define SAM_SMCCS1_MODE (SAM_SMC_CS1_BASE+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMCCS2_SETUP (SAM_SMC_CS2_BASE+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS2_PULSE (SAM_SMC_CS2_BASE+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS2_CYCLE (SAM_SMC_CS2_BASE+SAM_SMCCS_CYCLE_OFFSET) +#define SAM_SMCCS2_MODE (SAM_SMC_CS2_BASE+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMCCS3_SETUP (SAM_SMC_CS3_BASE+SAM_SMCCS_SETUP_OFFSET) +#define SAM_SMCCS3_PULSE (SAM_SMC_CS3_BASE+SAM_SMCCS_PULSE_OFFSET) +#define SAM_SMCCS3_CYCLE (SAM_SMC_CS3_BASE+SAM_SMCCS_CYCLE_OFFSET) +#define SAM_SMCCS3_MODE (SAM_SMC_CS3_BASE+SAM_SMCCS_MODE_OFFSET) + +#define SAM_SMC_OCMS (SAM_SMC_BASE+SAM_SMC_OCMS_OFFSET) +#define SAM_SMC_KEY1 (SAM_SMC_BASE+SAM_SMC_KEY1_OFFSET) +#define SAM_SMC_KEY2 (SAM_SMC_BASE+SAM_SMC_KEY2_OFFSET) +#define SAM_SMC_WPCR (SAM_SMC_BASE+SAM_SMC_WPCR_OFFSET) +#define SAM_SMC_WPSR (SAM_SMC_BASE+SAM_SMC_WPSR_OFFSET) + +/* SMC register bit definitions *********************************************************/ + +/* SMC Setup Register */ + +#define SMCCS_SETUP_NWESETUP_SHIFT (0) /* Bits 0-5: NWE Setup length */ +#define SMCCS_SETUP_NWESETUP_MASK (63 << SMCCS_SETUP_NWESETUP_SHIFT) +# define SMCCS_SETUP_NWESETUP(n) ((n) << SMCCS_SETUP_NWESETUP_SHIFT) +#define SMCCS_SETUP_NCSWRSETUP_SHIFT (8) /* Bits 8-13: NCS Setup length in Write access */ +#define SMCCS_SETUP_NCSWRSETUP_MASK (63 << SMCCS_SETUP_NCSWRSETUP_SHIFT) +# define SMCCS_SETUP_NCSWRSETUP(n) ((n) << SMCCS_SETUP_NCSWRSETUP_SHIFT) +#define SMCCS_SETUP_NRDSETUP_SHIFT (16) /* Bits 16-21: NRD Setup length */ +#define SMCCS_SETUP_NRDSETUP_MASK (63 << SMCCS_SETUP_NRDSETUP_SHIFT) +# define SMCCS_SETUP_NRDSETUP(n) ((n) << SMCCS_SETUP_NRDSETUP_SHIFT) +#define SMCCS_SETUP_NCSRDSETUP_SHIFT (24) /* Bits 24-29: NCS Setup length in Read access */ +#define SMCCS_SETUP_NCSRDSETUP_MASK (63 << SMCCS_SETUP_NCSRDSETUP_SHIFT) +# define SMCCS_SETUP_NCSRDSETUP(n) ((n) << SMCCS_SETUP_NCSRDSETUP_SHIFT) + +/* SMC Pulse Register */ + +#define SMCCS_PULSE_NWEPULSE_SHIFT (0) /* Bits 0-6: NWE Pulse Length */ +#define SMCCS_PULSE_NWEPULSE_MASK (127 << SMCCS_PULSE_NWEPULSE_SHIFT) +# define SMCCS_PULSE_NWEPULSE(n) ((n) << SMCCS_PULSE_NWEPULSE_SHIFT) +#define SMCCS_PULSE_NCSWRPULSE_SHIFT (8) /* Bits 8-14: NCS Pulse Length in WRITE Access */ +#define SMCCS_PULSE_NCSWRPULSE_MASK (127 << SMCCS_PULSE_NCSWRPULSE_SHIFT) +# define SMCCS_PULSE_NCSWRPULSE(n) ((n) << SMCCS_PULSE_NCSWRPULSE_SHIFT) +#define SMCCS_PULSE_NRDPULSE_SHIFT (16) /* Bits 16-22: NRD Pulse Length */ +#define SMCCS_PULSE_NRDPULSE_MASK (127 << SMCCS_PULSE_NRDPULSE_SHIFT) +# define SMCCS_PULSE_NRDPULSE(n) ((n) << SMCCS_PULSE_NRDPULSE_SHIFT) +#define SMCCS_PULSE_NCSRDPULSE_SHIFT (24) /* Bits 24-30: NCS Pulse Length in READ Access */ +#define SMCCS_PULSE_NCSRDPULSE_MASK (127 << SMCCS_PULSE_NCSRDPULSE_SHIFT) +# define SMCCS_PULSE_NCSRDPULSE(n) ((n) << SMCCS_PULSE_NCSRDPULSE_SHIFT) + +/* SMC Cycle Register */ + +#define SMCCS_CYCLE_NWECYCLE_SHIFT (0) /* Bits 0-8: Total Write Cycle Length */ +#define SMCCS_CYCLE_NWECYCLE_MASK (0x1ff << SMCCS_CYCLE_NWECYCLE_SHIFT) +# define SMCCS_CYCLE_NWECYCLE(n) ((n) << SMCCS_CYCLE_NWECYCLE_SHIFT) +#define SMCCS_CYCLE_NRDCYCLE_SHIFT (16) /* Bits 16-24: Total Read Cycle Length */ +#define SMCCS_CYCLE_NRDCYCLE_MASK (0x1ff << SMCCS_CYCLE_NRDCYCLE_SHIFT) +# define SMCCS_CYCLE_NRDCYCLE(n) ((n) << SMCCS_CYCLE_NRDCYCLE_SHIFT) + +/* SMC Mode Register */ + +#define SMCCS_MODE_READMODE (1 << 0) /* Bit 0: Read mode */ +#define SMCCS_MODE_WRITEMODE (1 << 1) /* Bit 1: Write mode */ +#define SMCCS_MODE_EXNWMODE_SHIFT (4) /* Bits 4-5: NWAIT Mode */ +#define SMCCS_MODE_EXNWMODE_MASK (3 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_DISABLED (0 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_FROZEN (2 << SMCCS_MODE_EXNWMODE_SHIFT) +# define SMCCS_EXNWMODE_READY (3 << SMCCS_MODE_EXNWMODE_SHIFT) +#define SMCCS_MODE_BAT (1 << 8) /* Bit 8: Byte Access Type */ +#define SMCCS_MODE_DBW_MASK (1 << 12) /* Bit 12: Data Bus Width */ +# define SMCCS_MODE_DBW_8BIT (0 << 12) /* 0=8-bit data bus */ +# define SMCCS_MODE_DBW_16BIT (1 << 12) /* 1=16-bit data bus */ +#define SMCCS_MODE_TDFCYCLES_SHIFT (16) /* Bits 16-19: Data Float Time */ +#define SMCCS_MODE_TDFCYCLES_MASK (15 << SMCCS_MODE_TDFCYCLES_SHIFT) +# define SMCCS_MODE_TDFCYCLES(n) ((uint32_t)(n) << SMCCS_MODE_TDFCYCLES_SHIFT) +#define SMCCS_MODE_TDFMODE (1 << 20) /* Bit 20: TDF Optimization */ +#define SMCCS_MODE_PMEN (1 << 24) /* Bit 24: Page Mode Enabled */ +#define SMCCS_MODE_PS_SHIFT (28) /* Bits 28-29: Page Size */ +#define SMCCS_MODE_PS_MASK (3 << SMCCS_MODE_PS_SHIFT) +# define SMCCS_MODE_PS_SIZE_4BYTES (0 << SMCCS_MODE_PS_SHIFT) /* 4 bytes */ +# define SMCCS_MODE_PS_SIZE_8BYTES (1 << SMCCS_MODE_PS_SHIFT) /* 8 bytes */ +# define SMCCS_MODE_PS_SIZE_16BYTES (2 << SMCCS_MODE_PS_SHIFT) /* 16 bytes */ +# define SMCCS_MODE_PS_SIZE_32BYTES (3 << SMCCS_MODE_PS_SHIFT) /* 32 bytes */ + +/* SMC OCMS Mode Register */ + +#define SMC_OCMS_SMSE (1 << 0) /* Bit 0: Static Memory Controller Scrambling Enable */ +#define SMC_OCMS_CSSE(n) (1 << ((n)+16)) /* Chip Select (n=0-3) Scrambling Enable */ +# define SMC_OCMS_CS0SE (1 << 16) /* Bit 16: Chip Select 0 Scrambling Enable */ +# define SMC_OCMS_CS1SE (1 << 17) /* Bit 17: Chip Select 1 Scrambling Enable */ +# define SMC_OCMS_CS2SE (1 << 18) /* Bit 18: Chip Select 2 Scrambling Enable */ +# define SMC_OCMS_CS3SE (1 << 19) /* Bit 19: Chip Select 3 Scrambling Enable */ + +/* SMC KEY1/2 Registers (32-bit data) */ + +/* SMC Write Protect Mode Register */ + +#define SMC_WPCR_WPPEN (1 << 0) /* Bit 0: Write Protection Enable */ +#define SMC_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protection KEY password */ +#define SMC_WPCR_WPKEY_MASK (0x00ffffff << SMC_WPCR_WPKEY_SHIFT) +# define SMC_WPCR_WPKEY (0x00534d43 << SMC_WPCR_WPKEY_SHIFT) + +/* SMC Write Protection Status */ + +#define SMC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Source */ +#define SMC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protection Violation Source */ +#define SMC_WPSR_WPVSRC_MASK (0xffff << SMC_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SMC_H */ diff --git a/arch/arm/src/samv7/chip/sam_spi.h b/arch/arm/src/samv7/chip/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..fe738b2e184a650e67aa47fe1ceeb6f3cb55c310 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_spi.h @@ -0,0 +1,232 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_spi.h + * Serial Peripheral Interface (SPI) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SPI_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SPI_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NSPI > 0 + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ +/* General definitions ******************************************************************/ + +#define SAM_SPI_NCS 4 /* Four chip selects */ + +/* SPI register offsets *****************************************************************/ + +#define SAM_SPI_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SPI_MR_OFFSET 0x0004 /* Mode Register */ +#define SAM_SPI_RDR_OFFSET 0x0008 /* Receive Data Register */ +#define SAM_SPI_TDR_OFFSET 0x000c /* Transmit Data Register */ +#define SAM_SPI_SR_OFFSET 0x0010 /* Status Register */ +#define SAM_SPI_IER_OFFSET 0x0014 /* Interrupt Enable Register */ +#define SAM_SPI_IDR_OFFSET 0x0018 /* Interrupt Disable Register */ +#define SAM_SPI_IMR_OFFSET 0x001c /* Interrupt Mask Register */ + /* 0x20-0x2c: Reserved */ +#define SAM_SPI_CSR0_OFFSET 0x0030 /* Chip Select Register 0 */ +#define SAM_SPI_CSR1_OFFSET 0x0034 /* Chip Select Register 1 */ +#define SAM_SPI_CSR2_OFFSET 0x0038 /* Chip Select Register 2 */ +#define SAM_SPI_CSR3_OFFSET 0x003c /* Chip Select Register 3 */ + /* 0x40-0xe0: Reserved */ +#define SAM_SPI_WPCR_OFFSET 0x00e4 /* Write Protection Control Register */ +#define SAM_SPI_WPSR_OFFSET 0x00e8 /* Write Protection Status Register */ + /* 0xec-0xfc: Reserved */ + +/* SPI register addresses ***************************************************************/ + +#define SAM_SPI0_CR (SAM_SPI0_BASE+SAM_SPI_CR_OFFSET) /* Control Register */ +#define SAM_SPI0_MR (SAM_SPI0_BASE+SAM_SPI_MR_OFFSET) /* Mode Register */ +#define SAM_SPI0_RDR (SAM_SPI0_BASE+SAM_SPI_RDR_OFFSET) /* Receive Data Register */ +#define SAM_SPI0_TDR (SAM_SPI0_BASE+SAM_SPI_TDR_OFFSET) /* Transmit Data Register */ +#define SAM_SPI0_SR (SAM_SPI0_BASE+SAM_SPI_SR_OFFSET) /* Status Register */ +#define SAM_SPI0_IER (SAM_SPI0_BASE+SAM_SPI_IER_OFFSET) /* Interrupt Enable Register */ +#define SAM_SPI0_IDR (SAM_SPI0_BASE+SAM_SPI_IDR_OFFSET) /* Interrupt Disable Register */ +#define SAM_SPI0_IMR (SAM_SPI0_BASE+SAM_SPI_IMR_OFFSET) /* Interrupt Mask Register */ +#define SAM_SPI0_CSR0 (SAM_SPI0_BASE+SAM_SPI_CSR0_OFFSET) /* Chip Select Register 0 */ +#define SAM_SPI0_CSR1 (SAM_SPI0_BASE+SAM_SPI_CSR1_OFFSET) /* Chip Select Register 1 */ +#define SAM_SPI0_CSR2 (SAM_SPI0_BASE+SAM_SPI_CSR2_OFFSET) /* Chip Select Register 2 */ +#define SAM_SPI0_CSR3 (SAM_SPI0_BASE+SAM_SPI_CSR3_OFFSET) /* Chip Select Register 3 */ +#define SAM_SPI0_WPCR (SAM_SPI0_BASE+SAM_SPI_WPCR_OFFSET) /* Write Protection Control Register */ +#define SAM_SPI0_WPSR (SAM_SPI0_BASE+SAM_SPI_WPSR_OFFSET) /* Write Protection Status Register */ + +#if SAMV7_NSPI > 1 +# define SAM_SPI1_CR (SAM_SPI1_BASE+SAM_SPI_CR_OFFSET) /* Control Register */ +# define SAM_SPI1_MR (SAM_SPI1_BASE+SAM_SPI_MR_OFFSET) /* Mode Register */ +# define SAM_SPI1_RDR (SAM_SPI1_BASE+SAM_SPI_RDR_OFFSET) /* Receive Data Register */ +# define SAM_SPI1_TDR (SAM_SPI1_BASE+SAM_SPI_TDR_OFFSET) /* Transmit Data Register */ +# define SAM_SPI1_SR (SAM_SPI1_BASE+SAM_SPI_SR_OFFSET) /* Status Register */ +# define SAM_SPI1_IER (SAM_SPI1_BASE+SAM_SPI_IER_OFFSET) /* Interrupt Enable Register */ +# define SAM_SPI1_IDR (SAM_SPI1_BASE+SAM_SPI_IDR_OFFSET) /* Interrupt Disable Register */ +# define SAM_SPI1_IMR (SAM_SPI1_BASE+SAM_SPI_IMR_OFFSET) /* Interrupt Mask Register */ +# define SAM_SPI1_CSR0 (SAM_SPI1_BASE+SAM_SPI_CSR0_OFFSET) /* Chip Select Register 0 */ +# define SAM_SPI1_CSR1 (SAM_SPI1_BASE+SAM_SPI_CSR1_OFFSET) /* Chip Select Register 1 */ +# define SAM_SPI1_CSR2 (SAM_SPI1_BASE+SAM_SPI_CSR2_OFFSET) /* Chip Select Register 2 */ +# define SAM_SPI1_CSR3 (SAM_SPI1_BASE+SAM_SPI_CSR3_OFFSET) /* Chip Select Register 3 */ +# define SAM_SPI1_WPCR (SAM_SPI1_BASE+SAM_SPI_WPCR_OFFSET) /* Write Protection Control Register */ +# define SAM_SPI1_WPSR (SAM_SPI1_BASE+SAM_SPI_WPSR_OFFSET) /* Write Protection Status Register */ +#endif + +/* SPI register bit definitions *********************************************************/ + +/* SPI Control Register */ + +#define SPI_CR_SPIEN (1 << 0) /* Bit 0: SPI Enable */ +#define SPI_CR_SPIDIS (1 << 1) /* Bit 1: SPI Disable */ +#define SPI_CR_SWRST (1 << 7) /* Bit 7: SPI Software Reset */ +#define SPI_CR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Mode Register */ + +#define SPI_MR_MSTR (1 << 0) /* Bit 0: 1=Master Mode */ +# define SPI_MR_SLAVE (0) /* 0=Slave Mode */ +#define SPI_MR_PS (1 << 1) /* Bit 1: Peripheral Select */ +#define SPI_MR_PCSDEC (1 << 2) /* Bit 2: Chip Select Decode */ +#define SPI_MR_MODFDIS (1 << 4) /* Bit 4: Mode Fault Detection */ +#define SPI_MR_WDRBT (1 << 5) /* Bit 5: Wait Data Read Before Transfer */ +#define SPI_MR_LLB (1 << 7) /* Bit 7: Local Loopback Enable */ +#define SPI_MR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_MR_PCS_MASK (15 << SPI_MR_PCS_SHIFT) +# define SPI_MR_PCS0 (0 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_MR_PCS1 (1 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_MR_PCS2 (3 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_MR_PCS3 (7 << SPI_MR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_MR_DLYBCS_SHIFT (24) /* Bits 24-31: Delay Between Chip Selects */ +#define SPI_MR_DLYBCS_MASK (0xff << SPI_MR_DLYBCS_SHIFT) +# define SPI_MR_DLYBCS(n) ((uint32_t)(n) << SPI_MR_DLYBCS_SHIFT) + +/* SPI Receive Data Register */ + +#define SPI_RDR_RD_SHIFT (0) /* Bits 0-15: Receive Data */ +#define SPI_RDR_RD_MASK (0xffff << SPI_RDR_RD_SHIFT) +#define SPI_RDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_RDR_PCS_MASK (15 << SPI_RDR_PCS_SHIFT) +# define SPI_RDR_PCS0 (0 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_RDR_PCS1 (1 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_RDR_PCS2 (3 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_RDR_PCS3 (7 << SPI_RDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ + +/* SPI Transmit Data Register */ + +#define SPI_TDR_TD_SHIFT (0) /* Bits 0-15: Transmit Data */ +#define SPI_TDR_TD_MASK (0xffff << SPI_TDR_TD_SHIFT) +#define SPI_TDR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_TDR_PCS_MASK (15 << SPI_TDR_PCS_SHIFT) +# define SPI_TDR_PCS0 (0 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1110 (w/PCSDEC=0) */ +# define SPI_TDR_PCS1 (1 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1101 (w/PCSDEC=0) */ +# define SPI_TDR_PCS2 (3 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 1011 (w/PCSDEC=0) */ +# define SPI_TDR_PCS3 (7 << SPI_TDR_PCS_SHIFT) /* NPCS[3:0] = 0111 (w/PCSDEC=0) */ +#define SPI_TDR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* SPI Status Register, SPI Interrupt Enable Register, SPI Interrupt Disable Register, + * and SPI Interrupt Mask Register (common bit fields) + */ + +#define SPI_INT_RDRF (1 << 0) /* Bit 0: Receive Data Register Full Interrupt */ +#define SPI_INT_TDRE (1 << 1) /* Bit 1: Transmit Data Register Empty Interrupt */ +#define SPI_INT_MODF (1 << 2) /* Bit 2: Mode Fault Error Interrupt */ +#define SPI_INT_OVRES (1 << 3) /* Bit 3: Overrun Error Interrupt */ +#define SPI_INT_NSSR (1 << 8) /* Bit 8: NSS Rising Interrupt */ +#define SPI_INT_TXEMPTY (1 << 9) /* Bit 9: Transmission Registers Empty Interrupt */ +#define SPI_INT_UNDES (1 << 10) /* Bit 10: Underrun Error Status Interrupt (slave) */ +#define SPI_SR_SPIENS (1 << 16) /* Bit 16: SPI Enable Status (SR only) */ + +#define SPI_INT_ALL (0x0000070f) + +/* SPI Chip Select Registers 0-3 */ + +#define SPI_CSR_CPOL (1 << 0) /* Bit 0: Clock Polarity */ +#define SPI_CSR_NCPHA (1 << 1) /* Bit 1: Clock Phase */ +#define SPI_CSR_CSNAAT (1 << 2) /* Bit 2: Chip Select Not Active After Transfer */ +#define SPI_CSR_CSAAT (1 << 3) /* Bit 3: Chip Select Active After Transfer */ +#define SPI_CSR_BITS_SHIFT (4) /* Bits 4-7: Bits Per Transfer */ +#define SPI_CSR_BITS_MASK (15 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_BITS(n) (((n)-8) << SPI_CSR_BITS_SHIFT) /* n, n=8-16 */ +# define SPI_CSR_BITS8 (0 << SPI_CSR_BITS_SHIFT) /* 8 */ +# define SPI_CSR_BITS9 (1 << SPI_CSR_BITS_SHIFT) /* 9 */ +# define SPI_CSR_BITS10 (2 << SPI_CSR_BITS_SHIFT) /* 10 */ +# define SPI_CSR_BITS11 (3 << SPI_CSR_BITS_SHIFT) /* 11 */ +# define SPI_CSR_BITS12 (4 << SPI_CSR_BITS_SHIFT) /* 12 */ +# define SPI_CSR_BITS13 (5 << SPI_CSR_BITS_SHIFT) /* 13 */ +# define SPI_CSR_BITS14 (6 << SPI_CSR_BITS_SHIFT) /* 14 */ +# define SPI_CSR_BITS15 (7 << SPI_CSR_BITS_SHIFT) /* 15 */ +# define SPI_CSR_BITS16 (8 << SPI_CSR_BITS_SHIFT) /* 16 */ +#define SPI_CSR_SCBR_SHIFT (8) /* Bits 8-15: Serial Clock Baud Rate */ +#define SPI_CSR_SCBR_MASK (0xff << SPI_CSR_SCBR_SHIFT) +# define SPI_CSR_SCBR(n) ((uint32_t)(n) << SPI_CSR_SCBR_SHIFT) +#define SPI_CSR_DLYBS_SHIFT (16) /* Bits 16-23: Delay Before SPCK */ +#define SPI_CSR_DLYBS_MASK (0xff << SPI_CSR_DLYBS_SHIFT) +# define SPI_CSR_DLYBS(n) ((uint32_t)(n) << SPI_CSR_DLYBS_SHIFT) +#define SPI_CSR_DLYBCT_SHIFT (24) /* Bits 24-31: Delay Between Consecutive Transfers */ +#define SPI_CSR_DLYBCT_MASK (0xff << SPI_CSR_DLYBCT_SHIFT) +# define SPI_CSR_DLYBCT(n) ((uint32_t)(n) << SPI_CSR_DLYBCT_SHIFT) + +/* SPI Write Protection Control Register */ + +#define SPI_WPCR_WPEN (1 << 0) /* Bit 0: SPI Write Protection Enable */ +#define SPI_WPCR_WPKEY_SHIFT (8) /* Bits 8-31: SPI Write Protection Key Password */ +#define SPI_WPCR_WPKEY_MASK (0x00ffffff << SPI_WPCR_WPKEY_SHIFT) +# define SPI_WPCR_WPKEY (0x00535049 << SPI_WPCR_WPKEY_SHIFT) + +/* SPI Write Protection Status Register */ + +#define SPI_WPSR_WPVS (1 << 0) /* Bit 0: SPI Write Protection Violation Status */ +#define SPI_WPSR_WPVSRC_SHIFT (8) /* Bits 8-15: SPI Write Protection Violation Source */ +#define SPI_WPSR_WPVSRC_MASK (0xff << SPI_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* SAMV7_NSPI > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SPI_H */ diff --git a/arch/arm/src/samv7/chip/sam_ssc.h b/arch/arm/src/samv7/chip/sam_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..98f34bc837386c08d75a92541e5feb4f3d8126e2 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_ssc.h @@ -0,0 +1,318 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_ssc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SSC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NSSC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + + /* The maximum clock speed allowed on the TK and RK pins is the peripheral clock + * divided by 2. + */ + +#define SAM_SSC_MAXPERCLK (BOARD_MCK_FREQUENCY >> 1) + +/* SSC Register Offsets *************************************************************/ + +#define SAM_SSC_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_SSC_CMR_OFFSET 0x0004 /* Clock Mode Register */ + /* 0x0008-0x000c Reserved */ +#define SAM_SSC_RCMR_OFFSET 0x0010 /* Receive Clock Mode Register */ +#define SAM_SSC_RFMR_OFFSET 0x0014 /* Receive Frame Mode Register */ +#define SAM_SSC_TCMR_OFFSET 0x0018 /* Transmit Clock Mode Register */ +#define SAM_SSC_TFMR_OFFSET 0x001c /* Transmit Frame Mode Register */ +#define SAM_SSC_RHR_OFFSET 0x0020 /* Receive Holding Register */ +#define SAM_SSC_THR_OFFSET 0x0024 /* Transmit Holding Register */ + /* 0x0028-0x002c Reserved */ +#define SAM_SSC_RSHR_OFFSET 0x0030 /* Receive Sync. Holding Register */ +#define SAM_SSC_TSHR_OFFSET 0x0034 /* Transmit Sync. Holding Register */ +#define SAM_SSC_RC0R_OFFSET 0x0038 /* Receive Compare 0 Register */ +#define SAM_SSC_RC1R_OFFSET 0x003c /* Receive Compare 1 Register */ +#define SAM_SSC_SR_OFFSET 0x0040 /* Status Register */ +#define SAM_SSC_IER_OFFSET 0x0044 /* Interrupt Enable Register */ +#define SAM_SSC_IDR_OFFSET 0x0048 /* Interrupt Disable Register */ +#define SAM_SSC_IMR_OFFSET 0x004c /* Interrupt Mask Register */ + /* 0x0050-0x00e0: Reserved */ +#define SAM_SSC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ +#define SAM_SSC_WPSR_OFFSET 0x00e8 /* Write Protect Status Register */ + /* 0x00ec-0x0124 Reserved */ + +/* SSC Register Addresses ***********************************************************/ + +#define SAM_SSC0_CR (SAM_SSC0_BASE+SAM_SSC_CR_OFFSET) +#define SAM_SSC0_CMR (SAM_SSC0_BASE+SAM_SSC_CMR_OFFSET) +#define SAM_SSC0_RCMR (SAM_SSC0_BASE+SAM_SSC_RCMR_OFFSET) +#define SAM_SSC0_RFMR (SAM_SSC0_BASE+SAM_SSC_RFMR_OFFSET) +#define SAM_SSC0_TCMR (SAM_SSC0_BASE+SAM_SSC_TCMR_OFFSET) +#define SAM_SSC0_TFMR (SAM_SSC0_BASE+SAM_SSC_TFMR_OFFSET) +#define SAM_SSC0_RHR (SAM_SSC0_BASE+SAM_SSC_RHR_OFFSET) +#define SAM_SSC0_THR (SAM_SSC0_BASE+SAM_SSC_THR_OFFSET) +#define SAM_SSC0_RSHR (SAM_SSC0_BASE+SAM_SSC_RSHR_OFFSET) +#define SAM_SSC0_TSHR (SAM_SSC0_BASE+SAM_SSC_TSHR_OFFSET) +#define SAM_SSC0_RC0R (SAM_SSC0_BASE+SAM_SSC_RC0R_OFFSET) +#define SAM_SSC0_RC1R (SAM_SSC0_BASE+SAM_SSC_RC1R_OFFSET) +#define SAM_SSC0_SR (SAM_SSC0_BASE+SAM_SSC_SR_OFFSET) +#define SAM_SSC0_IER (SAM_SSC0_BASE+SAM_SSC_IER_OFFSET) +#define SAM_SSC0_IDR (SAM_SSC0_BASE+SAM_SSC_IDR_OFFSET) +#define SAM_SSC0_IMR (SAM_SSC0_BASE+SAM_SSC_IMR_OFFSET) +#define SAM_SSC0_WPMR (SAM_SSC0_BASE+SAM_SSC_WPMR_OFFSET) +#define SAM_SSC0_WPSR (SAM_SSC0_BASE+SAM_SSC_WPSR_OFFSET) + +#if SAMV7_NSSC > 1 +# define SAM_SSC1_CR (SAM_SSC1_BASE+SAM_SSC_CR_OFFSET) +# define SAM_SSC1_CMR (SAM_SSC1_BASE+SAM_SSC_CMR_OFFSET) +# define SAM_SSC1_RCMR (SAM_SSC1_BASE+SAM_SSC_RCMR_OFFSET) +# define SAM_SSC1_RFMR (SAM_SSC1_BASE+SAM_SSC_RFMR_OFFSET) +# define SAM_SSC1_TCMR (SAM_SSC1_BASE+SAM_SSC_TCMR_OFFSET) +# define SAM_SSC1_TFMR (SAM_SSC1_BASE+SAM_SSC_TFMR_OFFSET) +# define SAM_SSC1_RHR (SAM_SSC1_BASE+SAM_SSC_RHR_OFFSET) +# define SAM_SSC1_THR (SAM_SSC1_BASE+SAM_SSC_THR_OFFSET) +# define SAM_SSC1_RSHR (SAM_SSC1_BASE+SAM_SSC_RSHR_OFFSET) +# define SAM_SSC1_TSHR (SAM_SSC1_BASE+SAM_SSC_TSHR_OFFSET) +# define SAM_SSC1_RC0R (SAM_SSC1_BASE+SAM_SSC_RC0R_OFFSET) +# define SAM_SSC1_RC1R (SAM_SSC1_BASE+SAM_SSC_RC1R_OFFSET) +# define SAM_SSC1_SR (SAM_SSC1_BASE+SAM_SSC_SR_OFFSET) +# define SAM_SSC1_IER (SAM_SSC1_BASE+SAM_SSC_IER_OFFSET) +# define SAM_SSC1_IDR (SAM_SSC1_BASE+SAM_SSC_IDR_OFFSET) +# define SAM_SSC1_IMR (SAM_SSC1_BASE+SAM_SSC_IMR_OFFSET) +# define SAM_SSC1_WPMR (SAM_SSC1_BASE+SAM_SSC_WPMR_OFFSET) +# define SAM_SSC1_WPSR (SAM_SSC1_BASE+SAM_SSC_WPSR_OFFSET) +#endif + +/* SSC Register Bit Definitions *****************************************************/ + +/* Control Register */ + +#define SSC_CR_RXEN (1 << 0) /* Bit 0: Receive Enable */ +#define SSC_CR_RXDIS (1 << 1) /* Bit 1: Receive Disable */ +#define SSC_CR_TXEN (1 << 8) /* Bit 8: Transmit Enable */ +#define SSC_CR_TXDIS (1 << 9) /* Bit 9: Transmit Disable */ +#define SSC_CR_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* Clock Mode Register */ + +#define SSC_CMR_DIV_MASK (0x00000fff) /* Bits 0-11: DIV: Clock Divider */ + +/* Receive Clock Mode Register */ + +#define SSC_RCMR_CKS_SHIFT (0) /* Bits 0-1: Receive Clock Selection */ +#define SSC_RCMR_CKS_MASK (3 << SSC_RCMR_CKS_SHIFT) +# define SSC_RCMR_CKS_MCK (0 << SSC_RCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_RCMR_CKS_TK (1 << SSC_RCMR_CKS_SHIFT) /* TK Clock signal */ +# define SSC_RCMR_CKS_RK (2 << SSC_RCMR_CKS_SHIFT) /* RK pin */ +#define SSC_RCMR_CKO_SHIFT (2) /* Bits 2-4: Receive Clock Output Mode Selection */ +#define SSC_RCMR_CKO_MASK (7 << SSC_RCMR_CKO_SHIFT) +# define SSC_RCMR_CKO_NONE (0 << SSC_RCMR_CKO_SHIFT) /* None, RK pin is an input */ +# define SSC_RCMR_CKO_CONT (1 << SSC_RCMR_CKO_SHIFT) /* Continuous Receive Clock, RK pin is an output */ +# define SSC_RCMR_CKO_TRANSFER (2 << SSC_RCMR_CKO_SHIFT) /* Receive Clock during transfers, RK pin is an output */ +#define SSC_RCMR_CKI (1 << 5) /* Bit 5: Receive Clock Inversion */ +#define SSC_RCMR_CKG_SHIFT (6) /* Bits 6-7: Receive Clock Gating Selection */ +#define SSC_RCMR_CKG_MASK (3 << SSC_RCMR_CKG_SHIFT) +# define SSC_RCMR_CKG_CONT (0 << SSC_RCMR_CKG_SHIFT) /* None */ +# define SSC_RCMR_CKG_ENRFLOW (2 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF Pin is Low */ +# define SSC_RCMR_CKG_ENRFHIGH (3 << SSC_RCMR_CKG_SHIFT) /* Receive Clock enabled only if RF Pin is High */ +#define SSC_RCMR_START_SHIFT (8) /* Bits 8-11: Receive Start Selection */ +#define SSC_RCMR_START_MASK (15 << SSC_RCMR_START_SHIFT) +# define SSC_RCMR_START_CONT (0 << SSC_RCMR_START_SHIFT) /* Continuous */ +# define SSC_RCMR_START_TRANSMIT (1 << SSC_RCMR_START_SHIFT) /* Transmit start */ +# define SSC_RCMR_START_LOW (2 << SSC_RCMR_START_SHIFT) /* Detection of a low level on RF signal */ +# define SSC_RCMR_START_HIGH (3 << SSC_RCMR_START_SHIFT) /* Detection of a high level on RF signal */ +# define SSC_RCMR_START_FALLING (4 << SSC_RCMR_START_SHIFT) /* Detection of a falling edge on RF signal */ +# define SSC_RCMR_START_RISING (5 << SSC_RCMR_START_SHIFT) /* Detection of a rising edge on RF signal */ +# define SSC_RCMR_START_LEVEL (6 << SSC_RCMR_START_SHIFT) /* Detection of any level change on RF signal */ +# define SSC_RCMR_START_EDGE (7 << SSC_RCMR_START_SHIFT) /* Detection of any edge on RF signal */ +# define SSC_RCMR_START_CMP0 (8 << SSC_RCMR_START_SHIFT) /* Compare 0 */ +#define SSC_RCMR_STOP (1 << 12) /* Bit 12: Receive Stop Selection */ +#define SSC_RCMR_STTDLY_SHIFT (16) /* Bits 16-23: Receive Start Delay */ +#define SSC_RCMR_STTDLY_MASK (0xff << SSC_RCMR_STTDLY_SHIFT) +# define SSC_RCMR_STTDLY(n) ((uint32_t)(n) << SSC_RCMR_STTDLY_SHIFT) +#define SSC_RCMR_PERIOD_SHIFT (24) /* Bits 24-31: Receive Period Divider Selection */ +#define SSC_RCMR_PERIOD_MASK (0xff << SSC_RCMR_PERIOD_SHIFT) +# define SSC_RCMR_PERIOD(n) ((uint32_t)(n) << SSC_RCMR_PERIOD_SHIFT) + +/* Receive Frame Mode Register */ + +#define SSC_RFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_RFMR_DATLEN_MASK (15 << SSC_RFMR_DATLEN_SHIFT) +# define SSC_RFMR_DATLEN(n) ((uint32_t)(n) << SSC_RFMR_DATLEN_SHIFT) +#define SSC_RFMR_LOOP (1 << 5) /* Bit 5: Loop Mode */ +#define SSC_RFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_RFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per Frame */ +#define SSC_RFMR_DATNB_MASK (15 << SSC_RFMR_DATNB_SHIFT) +# define SSC_RFMR_DATNB(n) ((uint32_t)(n) << SSC_RFMR_DATNB_SHIFT) +#define SSC_RFMR_FSLEN_SHIFT (16) /* Bits 16-19: Receive Frame Sync Length */ +#define SSC_RFMR_FSLEN_MASK (15 << SSC_RFMR_FSLEN_SHIFT) +# define SSC_RFMR_FSLEN(n) ((uint32_t)(n) << SSC_RFMR_FSLEN_SHIFT) +#define SSC_RFMR_FSOS_SHIFT (20) /* Bits 20-22: Receive Frame Sync Output Selection */ +#define SSC_RFMR_FSOS_MASK (7 << SSC_RFMR_FSOS_SHIFT) +# define SSC_RFMR_FSOS_NONE (0 << SSC_RFMR_FSOS_SHIFT) /* None, RF pin is an input */ +# define SSC_RFMR_FSOS_NEGATIVE (1 << SSC_RFMR_FSOS_SHIFT) /* Negative Pulse, RF pin is an output */ +# define SSC_RFMR_FSOS_POSITIVE (2 << SSC_RFMR_FSOS_SHIFT) /* Positive Pulse, RF pin is an output */ +# define SSC_RFMR_FSOS_LOW (3 << SSC_RFMR_FSOS_SHIFT) /* Low during transfer, RF pin is an output */ +# define SSC_RFMR_FSOS_HIGH (4 << SSC_RFMR_FSOS_SHIFT) /* High during transfer, RF pin is an output */ +# define SSC_RFMR_FSOS_TOGGLING (5 << SSC_RFMR_FSOS_SHIFT) /* Toggling each transfer, RF pin is an output */ +#define SSC_RFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detection */ +# define SSC_RFMR_FSEDGE_POS (0) /* Bit 24: 0=Positive Edge Detection */ +# define SSC_RFMR_FSEDGE_NEG (1 << 24) /* Bit 24: 1=Negative Edge Detection */ +#define SSC_RFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_RFMR_FSLENEXT_MASK (15 << SSC_RFMR_FSLENEXT_SHIFT) +# define SSC_RFMR_FSLENEXT(n) ((uint32_t)(n) << SSC_RFMR_FSLENEXT_SHIFT) + +/* Transmit Clock Mode Register */ + +#define SSC_TCMR_CKS_SHIFT (0) /* Bits 0-1: Transmit Clock Selection */ +#define SSC_TCMR_CKS_MASK (3 << SSC_TCMR_CKS_SHIFT) +# define SSC_TCMR_CKS_MCK (0 << SSC_TCMR_CKS_SHIFT) /* Divided Clock */ +# define SSC_TCMR_CKS_RK (1 << SSC_TCMR_CKS_SHIFT) /* RK Clock signal */ +# define SSC_TCMR_CKS_TK (2 << SSC_TCMR_CKS_SHIFT) /* TK pin */ +#define SSC_TCMR_CKO_SHIFT (2) /* Bits 2-4: Transmit Clock Output Mode Selection */ +#define SSC_TCMR_CKO_MASK (7 << SSC_TCMR_CKO_SHIFT) +# define SSC_TCMR_CKO_NONE (0 << SSC_TCMR_CKO_SHIFT) /* None, TK pin is an input */ +# define SSC_TCMR_CKO_CONT (1 << SSC_TCMR_CKO_SHIFT) /* Continuous Transmit Clock, TK pin is an output */ +# define SSC_TCMR_CKO_TRANSFER (2 << SSC_TCMR_CKO_SHIFT) /* Transmit Clock during transfers, TK pin is an output */ +#define SSC_TCMR_CKI (1 << 5) /* Bit 5: Transmit Clock Inversion */ +#define SSC_TCMR_CKG_SHIFT (6) /* Bits 6-7: Transmit Clock Gating Selection */ +#define SSC_TCMR_CKG_MASK (3 << SSC_TCMR_CKG_SHIFT) +# define SSC_TCMR_CKG_CONT (0 << SSC_TCMR_CKG_SHIFT) /* None */ +# define SSC_TCMR_CKG_ENTFLOW (1 << SSC_TCMR_CKG_SHIFT) /* Transmit Clock enabled only if TF pin is Low */ +# define SSC_TCMR_CKG_ENTFHIGH (2 << SSC_TCMR_CKG_SHIFT) /*Transmit Clock enabled only if TF pin is High */ +#define SSC_TCMR_START_SHIFT (8) /* Bits 8-11: Transmit Start Selection */ +#define SSC_TCMR_START_MASK (15 << SSC_TCMR_START_SHIFT) +# define SSC_TCMR_START_CONT (0 << SSC_TCMR_START_SHIFT) /* Continuous */ +# define SSC_TCMR_START_RECEIVE (1 << SSC_TCMR_START_SHIFT) /* Receive start */ +# define SSC_TCMR_START_LOW (2 << SSC_TCMR_START_SHIFT) /* Detection of a low level on TF signal */ +# define SSC_TCMR_START_HIGH (3 << SSC_TCMR_START_SHIFT) /* Detection of a high level on TF signal */ +# define SSC_TCMR_START_FALLING (4 << SSC_TCMR_START_SHIFT) /* Detection of a falling edge on TF signal */ +# define SSC_TCMR_START_RISING (5 << SSC_TCMR_START_SHIFT) /* Detection of a rising edge on TF signal */ +# define SSC_TCMR_START_LEVEL (6 << SSC_TCMR_START_SHIFT) /* Detection of any level change on TF signal */ +# define SSC_TCMR_START_EDGE (7 << SSC_TCMR_START_SHIFT) /* Detection of any edge on TF signal */ +#define SSC_TCMR_STTDLY_SHIFT (16) /* Bits 15-23: Transmit Start Delay */ +#define SSC_TCMR_STTDLY_MASK (0xff << SSC_TCMR_STTDLY_SHIFT) +# define SSC_TCMR_STTDLY(n) ((uint32_t)(n) << SSC_TCMR_STTDLY_SHIFT) +#define SSC_TCMR_PERIOD_SHIFT (24) /* Bits 24-31: Transmit Period Divider Selection */ +#define SSC_TCMR_PERIOD_MASK (0xff << SSC_TCMR_PERIOD_SHIFT) +# define SSC_TCMR_PERIOD(n) ((uint32_t)(n) << SSC_TCMR_PERIOD_SHIFT) + +/* Transmit Frame Mode Register */ + +#define SSC_TFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_TFMR_DATLEN_MASK (31 << SSC_TFMR_DATLEN_SHIFT) +# define SSC_TFMR_DATLEN(n) ((uint32_t)(n) << SSC_TFMR_DATLEN_SHIFT) +#define SSC_TFMR_DATDEF (1 << 5) /* Bit 5: Data Default Value */ +#define SSC_TFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_TFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per frame */ +#define SSC_TFMR_DATNB_MASK (15 << SSC_TFMR_DATNB_SHIFT) +# define SSC_TFMR_DATNB(n) ((uint32_t)(n) << SSC_TFMR_DATNB_SHIFT) +#define SSC_TFMR_FSLEN_SHIFT (16) /* Bits 16-19: Transmit Frame Sync Length */ +#define SSC_TFMR_FSLEN_MASK (15 << SSC_TFMR_FSLEN_SHIFT) +# define SSC_TFMR_FSLEN(n) ((uint32_t)(n) << SSC_TFMR_FSLEN_SHIFT) +#define SSC_TFMR_FSOS_SHIFT (20) /* Bits 20-22: Transmit Frame Sync Output Selection */ +#define SSC_TFMR_FSOS_MASK (7 << SSC_TFMR_FSOS_SHIFT) +# define SSC_TFMR_FSOS_NONE (0 << SSC_TFMR_FSOS_SHIFT) /* None, TF pin is an input */ +# define SSC_TFMR_FSOS_NEGATIVE (1 << SSC_TFMR_FSOS_SHIFT) /* Negative Pulse, TF pin is an output */ +# define SSC_TFMR_FSOS_POSITIVE (2 << SSC_TFMR_FSOS_SHIFT) /* Positive Pulse, TF pin is an output */ +# define SSC_TFMR_FSOS_LOW (3 << SSC_TFMR_FSOS_SHIFT) /* TF pin Driven Low during data transfer */ +# define SSC_TFMR_FSOS_HIGH (4 << SSC_TFMR_FSOS_SHIFT) /* TF pin Driven High during data transfer */ +# define SSC_TFMR_FSOS_TOGGLING (5 << SSC_TFMR_FSOS_SHIFT) /* TF pin Toggles at each start of data transfer */ +#define SSC_TFMR_FSDEN (1 << 23) /* Bit 23: Frame Sync Data Enable */ +#define SSC_TFMR_FSEDGE (1 << 24) /* Bit 24: Frame Sync Edge Detection */ +# define SSC_TFMR_FSEDGE_POS (0) /* Bit 24: 0=Positive Edge Detection */ +# define SSC_TFMR_FSEDGE_NEG (1 << 24) /* Bit 24: 1=Negative Edge Detection */ +#define SSC_TFMR_FSLENEXT_SHIFT (28) /* Bits 28-31: FSLEN Field Extension */ +#define SSC_TFMR_FSLENEXT_MASK (15 << SSC_TFMR_FSLENEXT_SHIFT) +# define SSC_TFMR_FSLENEXT(n) ((uint32_t)(n) << SSC_TFMR_FSLENEXT_SHIFT) + +/* Receive Holding Register (32-bit data value) */ +/* Transmit Holding Register (32-bit data value) */ + +/* Receive Sync. Holding Register */ + +#define SSC_RSHR_MASK (0x0000ffff) /* Bit 0-15: Receive Synchronization Data */ + +/* Transmit Sync. Holding Register */ + +#define SSC_TSHR_MASK (0x0000ffff) /* Bit 0-15: Transmit Synchronization Data */ + +/* Receive Compare 0 Register */ + +#define SSC_RC0R_MASK (0x0000ffff) /* Bit 0-15: Receive Compare Data 0 */ + +/* Receive Compare 1 Register */ + +#define SSC_RC1R_MASK (0x0000ffff) /* Bit 0-15: Receive Compare Data 1 */ + +/* Status Register , Interrupt Enable Register, Interrupt Disable Register, and + * Interrupt Mask Register + */ + +#define SSC_INT_TXRDY (1 << 0) /* Bit 0: Transmit Ready */ +#define SSC_INT_TXEMPTY (1 << 1) /* Bit 1: Transmit Empty */ +#define SSC_INT_RXRDY (1 << 4) /* Bit 4: Receive Ready */ +#define SSC_INT_OVRUN (1 << 5) /* Bit 5: Receive Overrun */ +#define SSC_INT_CP0 (1 << 8) /* Bit 8: Compare 0 */ +#define SSC_INT_CP1 (1 << 9) /* Bit 9: Compare 1 */ +#define SSC_INT_TXSYN (1 << 10) /* Bit 10: Transmit Sync */ +#define SSC_INT_RXSYN (1 << 11) /* Bit 11: Receive Sync */ +#define SSC_SR_TXEN (1 << 16) /* Bit 16: Transmit Enable (SR only) */ +#define SSC_SR_RXEN (1 << 17) /* Bit 17: Receive Enable (SR only) */ + +/* Write Protect Mode Register */ + +#define SSC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define SSC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define SSC_WPMR_WPKEY_MASK (0x00ffffff << SSC_WPMR_WPKEY_SHIFT) +# define SSC_WPMR_WPKEY (0x00535343 << SSC_WPMR_WPKEY_SHIFT) /* "SSC" in ASCII */ + +/* Write Protect Status Register */ + +#define SSC_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define SSC_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define SSC_WPSR_WPVSRC_MASK (0xffff << SSC_WPSR_WPVSRC_SHIFT) + +#endif /* SAMV7_NSSC > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SSC_H */ diff --git a/arch/arm/src/samv7/chip/sam_supc.h b/arch/arm/src/samv7/chip/sam_supc.h new file mode 100644 index 0000000000000000000000000000000000000000..878d3e464bdd2cdd48e17abfaac6e8450c4a23f9 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_supc.h @@ -0,0 +1,185 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_supc.h + * Supply Controller (SUPC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SUPC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SUPC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SUPC register offsets ****************************************************************/ + +#define SAM_SUPC_CR_OFFSET 0x0000 /* Supply Controller Control Register */ +#define SAM_SUPC_SMMR_OFFSET 0x0004 /* Supply Controller Supply Monitor Mode Register */ +#define SAM_SUPC_MR_OFFSET 0x0008 /* Supply Controller Mode Register */ +#define SAM_SUPC_WUMR_OFFSET 0x000c /* Supply Controller Wake Up Mode Register */ +#define SAM_SUPC_WUIR_OFFSET 0x0010 /* Supply Controller Wake Up Inputs Register */ +#define SAM_SUPC_SR_OFFSET 0x0014 /* Supply Controller Status Register */ + +/* SUPC register addresses **************************************************************/ + +#define SAM_SUPC_CR (SAM_SUPC_BASE+SAM_SUPC_CR_OFFSET) +#define SAM_SUPC_SMMR (SAM_SUPC_BASE+SAM_SUPC_SMMR_OFFSET) +#define SAM_SUPC_MR (SAM_SUPC_BASE+SAM_SUPC_MR_OFFSET) +#define SAM_SUPC_WUMR (SAM_SUPC_BASE+SAM_SUPC_WUMR_OFFSET) +#define SAM_SUPC_WUIR (SAM_SUPC_BASE+SAM_SUPC_WUIR_OFFSET) +#define SAM_SUPC_SR (SAM_SUPC_BASE+SAM_SUPC_SR_OFFSET) + +/* SUPC register bit definitions ********************************************************/ +/* Supply Controller Control Register */ + +#define SUPC_CR_VROFF (1 << 2) /* Bit 2: Voltage Regulator Off */ +#define SUPC_CR_XTALSEL (1 << 3) /* Bit 3: Crystal Oscillator Select */ +#define SUPC_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define SUPC_CR_KEY_MASK (0xff << SUPC_CR_KEY_SHIFT) +# define SUPR_CR_KEY (0xa5 << SUPC_CR_KEY_SHIFT) + +/* Supply Controller Supply Monitor Mode Register */ + +#define SUPC_SMMR_SMTH_SHIFT (0) /* Bits 0-3: Supply Monitor Threshold */ +#define SUPC_SMMR_SMTH_MASK (15 << SUPC_SMMR_SMTH_SHIFT) +# define SUPC_SMMR_SMTH(n) ((uint32_t)(n) << SUPC_SMMR_SMTH_SHIFT) +# define SUPC_SMMR_SMTH_1p6V (0 << SUPC_SMMR_SMTH_SHIFT) /* 1.58 < 1.60 < 1.62 */ +# define SUPC_SMMR_SMTH_1p7V (1 << SUPC_SMMR_SMTH_SHIFT) /* 1.70 < 1.72 < 1.74 */ +# define SUPC_SMMR_SMTH_1p8V (2 << SUPC_SMMR_SMTH_SHIFT) /* 1.82 < 1.84 < 1.86 */ +# define SUPC_SMMR_SMTH_2p0V (3 << SUPC_SMMR_SMTH_SHIFT) /* 1.94 < 1.96 < 1.98 */ +# define SUPC_SMMR_SMTH_2p1V (4 << SUPC_SMMR_SMTH_SHIFT) /* 2.05 < 2.08 < 2.11 */ +# define SUPC_SMMR_SMTH_2p2V (5 << SUPC_SMMR_SMTH_SHIFT) /* 2.17 < 2.20 < 2.23 */ +# define SUPC_SMMR_SMTH_2p3V (6 << SUPC_SMMR_SMTH_SHIFT) /* 2.29 < 2.32 < 2.35 */ +# define SUPC_SMMR_SMTH_2p4V (7 << SUPC_SMMR_SMTH_SHIFT) /* 2.41 < 2.44 < 2.47 */ +# define SUPC_SMMR_SMTH_2p6V (8 << SUPC_SMMR_SMTH_SHIFT) /* 2.53 < 2.56 < 2.59 */ +# define SUPC_SMMR_SMTH_2p7V (9 << SUPC_SMMR_SMTH_SHIFT) /* 2.65 < 2.68 < 2.71 */ +# define SUPC_SMMR_SMTH_2p8V (10 << SUPC_SMMR_SMTH_SHIFT) /* 2.77 < 2.80 < 2.83 */ +# define SUPC_SMMR_SMTH_2p9V (11 << SUPC_SMMR_SMTH_SHIFT) /* 2.90 < 2.92 < 2.95 */ +# define SUPC_SMMR_SMTH_3p0V (12 << SUPC_SMMR_SMTH_SHIFT) /* 3.00 < 3.04 < 3.07 */ +# define SUPC_SMMR_SMTH_3p2V (13 << SUPC_SMMR_SMTH_SHIFT) /* 3.12 < 3.16 < 3.20 */ +# define SUPC_SMMR_SMTH_3p3V (14 << SUPC_SMMR_SMTH_SHIFT) /* 3.24 < 3.28 < 3.32 */ +# define SUPC_SMMR_SMTH_3p4V (15 << SUPC_SMMR_SMTH_SHIFT) /* 3.36 < 3.40 < 3.44 */ +#define SUPC_SMMR_SMSMPL_SHIFT (8) /* Bits 8-10: Supply Monitor Sampling Period */ +#define SUPC_SMMR_SMSMPL_MASK (7 << SUPC_SMMR_SMSMPL_SHIFT) +# define SUPC_SMMR_SMSMPL_SMD (0 << SUPC_SMMR_SMSMPL_SHIFT) /* Supply Monitor disabled */ +# define SUPC_SMMR_SMSMPL_CSM (1 << SUPC_SMMR_SMSMPL_SHIFT) /* Continuous Supply Monitor */ +# define SUPC_SMMR_SMSMPL_32SLCK (2 << SUPC_SMMR_SMSMPL_SHIFT) /* Eevery 32 SLCK periods */ +# define SUPC_SMMR_SMSMPL_256SLCK (3 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 256 SLCK periods */ +# define SUPC_SMMR_SMSMPL_2048SLCK (4 << SUPC_SMMR_SMSMPL_SHIFT) /* Every 2,048 SLCK periods */ +#define SUPC_SMMR_SMRSTEN (1 << 12) /* Bit 12: Supply Monitor Reset Enable */ +#define SUPC_SMMR_SMIEN (1 << 13) /* Bit 13: Supply Monitor Interrupt Enable */ + +/* Supply Controller Mode Register */ + +#define SUPC_MR_BODRSTEN (1 << 12) /* Bit 12: Brownout Detector Reset Enable */ +#define SUPC_MR_BODDIS (1 << 13) /* Bit 13: Brownout Detector Disable */ +#define SUPC_MR_ONREG (1 << 14) /* Bit 14: Voltage Regulator enable */ +#define SUPC_MR_BKUPRETON (1 << 17) /* Bit 17: SRAM On In Backup Mode */ +#define SUPC_MR_OSCBYPASS (1 << 20) /* Bit 20: Oscillator Bypass */ +#define SUPC_MR_KEY_SHIFT (24) /* Bits 24-31: Password Key */ +#define SUPC_MR_KEY_MASK (0xff << SUPC_MR_KEY_SHIFT) +# define SUPC_MR_KEY (0xa5 << SUPC_MR_KEY_SHIFT) + +/* Supply Controller Wake Up Mode Register */ + +#define SUPC_WUMR_SMEN (1 << 1) /* Bit 1: Supply Monitor Wake Up Enable */ +#define SUPC_WUMR_RTTEN (1 << 2) /* Bit 2: Real Time Timer Wake Up Enable */ +#define SUPC_WUMR_RTCEN (1 << 3) /* Bit 3: Real Time Clock Wake Up Enable */ +#define SUPC_WUMR_LPDBCEN0 (1 << 5) /* Bit 5: Low power Debouncer ENable WKUP0 */ +#define SUPC_WUMR_LPDBCEN1 (1 << 6) /* Bit 6: Low power Debouncer ENable WKUP1 */ +#define SUPC_WUMR_LPDBCCLR (1 << 7) /* Bit 7: Low power Debouncer Clear */ +#define SUPC_WUMR_WKUPDBC_SHIFT (12) /* Bits 12-14: Wake Up Inputs Debouncer */ +#define SUPC_WUMR_WKUPDBC_MASK (7 << SUPC_WUMR_WKUPDBC_SHIFT) +# define SUPC_WUMR_WKUPDBC_1SCLK (0 << SUPC_WUMR_WKUPDBC_SHIFT) /* Immediate, no debouncing */ +# define SUPC_WUMR_WKUPDBC_3SCLK (1 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 3 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32SCLK (2 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_512SCLK (3 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 512 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_4096SCLK (4 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 4096 SLCK periods */ +# define SUPC_WUMR_WKUPDBC_32768SCLK (5 << SUPC_WUMR_WKUPDBC_SHIFT) /* Input active at least 32768 SLCK periods */ +#define SUPC_WUMR_LPDBC_SHIFT (16) /* Bits 16-18: Low Power Debouncer Period */ +#define SUPC_WUMR_LPDBC_MASK (7 << SUPC_WUMR_LPDBC_SHIFT) +# define SUPC_WUMR_LPDBC_DISABLE (0 << SUPC_WUMR_LPDBC_SHIFT) /* Disable low power debouncer */ +# define SUPC_WUMR_LPDBC_2_RTCOUT0 (1 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 2 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_3_RTCOUT0 (2 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 3 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_4_RTCOUT0 (3 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 4 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_5_RTCOUT0 (4 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 5 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_6_RTCOUT0 (5 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 6 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_7_RTCOUT0 (6 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 7 RTCOUT0 */ +# define SUPC_WUMR_LPDBC_8_RTCOUT0 (7 << SUPC_WUMR_LPDBC_SHIFT) /* WKUP0/1 for 8 RTCOUT0 */ + +/* System Controller Wake Up Inputs Register */ + +#define SUPC_WUIR_WKUPEN_SHIFT (0) /* Bits 0-13: Wake Up Input Enable 0 to 13 */ +#define SUPC_WUIR_WKUPEN_MASK (0x3fff << SUPC_WUIR_WKUPEN_SHIFT) +# define SUPC_WUIR_WKUPEN(n) ((1 << (n)) << SUPC_WUIR_WKUPEN_SHIFT) +#define SUPC_WUIR_WKUPT_SHIFT (16) /* Bits 16-31 Wake Up Input Transition 0 to 13 */ +#define SUPC_WUIR_WKUPT_MASK (0x3fff << SUPC_WUIR_WKUPT_SHIFT) +# define SUPC_WUIR_WKUPT(n) ((1 << (n)) << SUPC_WUIR_WKUPT_SHIFT) + +/* Supply Controller Status Register */ + +#define SUPC_SR_WKUPS (1 << 1) /* Bit 1: WKUP Wake Up Status */ +#define SUPC_SR_SMWS (1 << 2) /* Bit 2: Supply Monitor Detection Wake Up Status */ +#define SUPC_SR_BODRSTS (1 << 3) /* Bit 3: Brownout Detector Reset Status */ +#define SUPC_SR_SMRSTS (1 << 4) /* Bit 4: Supply Monitor Reset Status */ +#define SUPC_SR_SMS (1 << 5) /* Bit 5: Supply Monitor Status */ +#define SUPC_SR_SMOS (1 << 6) /* Bit 6: Supply Monitor Output Status */ +#define SUPC_SR_OSCSEL (1 << 7) /* Bit 7: 32-kHz Oscillator Selection Status */ +#define SUPC_SR_LPDBCS0 (1 << 13) /* Bit 13: Low Power Debouncer Wake Up Status on WKUP0 */ +#define SUPC_SR_LPDBCS1 (1 << 14) /* Bit 14: Low Power Debouncer Wake Up Status on WKUP1 */ +#define SUPC_SR_WKUPIS_SHIFT (16) /* Bits 16-29: WKUP Input Status 0 to 13 */ +#define SUPC_SR_WKUPIS_MASK (0x3fff << SUPC_SR_WKUPIS_SHIFT) +# define SUPC_SR_WKUPIS(n) (1 << (SUPC_SR_WKUPIS_SHIFT+(n))) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SUPC_H */ diff --git a/arch/arm/src/samv7/chip/sam_sysc.h b/arch/arm/src/samv7/chip/sam_sysc.h new file mode 100644 index 0000000000000000000000000000000000000000..d50a5239ce44084f579b65bd71ab3afe64eed994 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_sysc.h @@ -0,0 +1,81 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_sysc.h + * Supply Controller (SYSC) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SYSC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SYSC_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* SYSC register offsets ****************************************************************/ + +#define SAM_SYSC_WPMR_OFFSET 0x0004 /* Write Protection Mode Register */ + +/* SYSC register addresses **************************************************************/ + +#define SAM_SYSC_WPMR (SAM_SYSC_BASE+SAM_SYSC_WPMR_OFFSET) + +/* SYSC register bit definitions ********************************************************/ +/* System Controller Write Protect Mode Register */ + +#define SYSC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define SYSC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define SYSC_WPMR_WPKEY_MASK (0x00ffffff << SYSC_WPMR_WPKEY_SHIFT) +# define SYSC_WPMR_WPKEY (0x00525443 << SYSC_WPMR_WPKEY_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_SYSC_H */ diff --git a/arch/arm/src/samv7/chip/sam_tc.h b/arch/arm/src/samv7/chip/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..0492bb028c9d421967b2e0717777e27eda2966dc --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_tc.h @@ -0,0 +1,641 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_tc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAM_TC_NCHANNELS 3 /* Number of channels per TC peripheral */ + +/* TC Register Offsets **************************************************************/ + +#define SAM_TC_CHAN_OFFSET(n) ((n) << 6) /* Channel n offset */ +#define SAM_TC_CCR_OFFSET 0x0000 /* Channel Control Register */ +#define SAM_TC_CMR_OFFSET 0x0004 /* Channel Mode Register */ +#define SAM_TC_SMMR_OFFSET 0x0008 /* Stepper Motor Mode Register */ +#define SAM_TC_RAB_OFFSET 0x000c /* Register AB */ +#define SAM_TC_CV_OFFSET 0x0010 /* Counter Value */ +#define SAM_TC_RA_OFFSET 0x0014 /* Register A */ +#define SAM_TC_RB_OFFSET 0x0018 /* Register B */ +#define SAM_TC_RC_OFFSET 0x001c /* Register C */ +#define SAM_TC_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TC_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TC_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TC_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_TC_EMR_OFFSET 0x0030 /* Extended Mode Register */ + +#define SAM_TCn_CCR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CCR_OFFSET) +#define SAM_TCn_CMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CMR_OFFSET) +#define SAM_TCn_SMMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_SMMR_OFFSET) +#define SAM_TCn_RAB_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RAB_OFFSET) +#define SAM_TCn_CV_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_CV_OFFSET) +#define SAM_TCn_RA_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RA_OFFSET) +#define SAM_TCn_RB_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RB_OFFSET) +#define SAM_TCn_RC_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_RC_OFFSET) +#define SAM_TCn_SR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_SR_OFFSET) +#define SAM_TCn_IER_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IER_OFFSET) +#define SAM_TCn_IDR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IDR_OFFSET) +#define SAM_TCn_IMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_IMR_OFFSET) +#define SAM_TCn_EMR_OFFSET(n) (SAM_TC_CHAN_OFFSET(n)+SAM_TC_EMR_OFFSET) + +#define SAM_TC0_CCR_OFFSET SAM_TCn_CCR_OFFSET(0) +#define SAM_TC0_CMR_OFFSET SAM_TCn_CMR_OFFSET(0) +#define SAM_TC0_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(0) +#define SAM_TC0_RAB_OFFSET SAM_TCn_RAB_OFFSET(0) +#define SAM_TC0_CV_OFFSET SAM_TCn_CV_OFFSET(0) +#define SAM_TC0_RA_OFFSET SAM_TCn_RA_OFFSET(0) +#define SAM_TC0_RB_OFFSET SAM_TCn_RB_OFFSET(0) +#define SAM_TC0_RC_OFFSET SAM_TCn_RC_OFFSET(0) +#define SAM_TC0_SR_OFFSET SAM_TCn_SR_OFFSET(0) +#define SAM_TC0_IER_OFFSET SAM_TCn_IER_OFFSET(0) +#define SAM_TC0_IDR_OFFSET SAM_TCn_IDR_OFFSET(0) +#define SAM_TC0_IMR_OFFSET SAM_TCn_IMR_OFFSET(0) +#define SAM_TC0_EMR_OFFSET SAM_TCn_EMR_OFFSET(0) + +#define SAM_TC1_CCR_OFFSET SAM_TCn_CCR_OFFSET(1) +#define SAM_TC1_CMR_OFFSET SAM_TCn_CMR_OFFSET(1) +#define SAM_TC1_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(1) +#define SAM_TC1_RAB_OFFSET SAM_TCn_RAB_OFFSET(1) +#define SAM_TC1_CV_OFFSET SAM_TCn_CV_OFFSET(1) +#define SAM_TC1_RA_OFFSET SAM_TCn_RA_OFFSET(1) +#define SAM_TC1_RB_OFFSET SAM_TCn_RB_OFFSET(1) +#define SAM_TC1_RC_OFFSET SAM_TCn_RC_OFFSET(1) +#define SAM_TC1_SR_OFFSET SAM_TCn_SR_OFFSET(1) +#define SAM_TC1_IER_OFFSET SAM_TCn_IER_OFFSET(1) +#define SAM_TC1_IDR_OFFSET SAM_TCn_IDR_OFFSET(1) +#define SAM_TC1_IMR_OFFSET SAM_TCn_IMR_OFFSET(1) +#define SAM_TC1_EMR_OFFSET SAM_TCn_EMR_OFFSET(1) + +#define SAM_TC2_CCR_OFFSET SAM_TCn_CCR_OFFSET(2) +#define SAM_TC2_CMR_OFFSET SAM_TCn_CMR_OFFSET(2) +#define SAM_TC2_SMMR_OFFSET SAM_TCn_SMMR_OFFSET(2) +#define SAM_TC2_RAB_OFFSET SAM_TCn_RAB_OFFSET(2) +#define SAM_TC2_CV_OFFSET SAM_TCn_CV_OFFSET(2) +#define SAM_TC2_RA_OFFSET SAM_TCn_RA_OFFSET(2) +#define SAM_TC2_RB_OFFSET SAM_TCn_RB_OFFSET(2) +#define SAM_TC2_RC_OFFSET SAM_TCn_RC_OFFSET(2) +#define SAM_TC2_SR_OFFSET SAM_TCn_SR_OFFSET(2) +#define SAM_TC2_IER_OFFSET SAM_TCn_IER_OFFSET(2) +#define SAM_TC2_IDR_OFFSET SAM_TCn_IDR_OFFSET(2) +#define SAM_TC2_IMR_OFFSET SAM_TCn_IMR_OFFSET(2) +#define SAM_TC2_EMR_OFFSET SAM_TCn_EMR_OFFSET(2) + +#define SAM_TC_BCR_OFFSET 0x00c0 /* Block Control Register */ +#define SAM_TC_BMR_OFFSET 0x00c4 /* Block Mode Register */ +#define SAM_TC_QIER_OFFSET 0x00c8 /* QDEC Interrupt Enable Register */ +#define SAM_TC_QIDR_OFFSET 0x00cc /* QDEC Interrupt Disable Register */ +#define SAM_TC_QIMR_OFFSET 0x00d0 /* QDEC Interrupt Mask Register */ +#define SAM_TC_QISR_OFFSET 0x00d4 /* QDEC Interrupt Status Register */ +#define SAM_TC_FMR_OFFSET 0x00d8 /* Fault Mode Register */ +#define SAM_TC_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register */ + +/* TC Register Addresses ************************************************************/ + +#define SAM_TC012_CHAN_BASE(n) (SAM_TC012_BASE+SAM_TC_CHAN_OFFSET(n)) + +#define SAM_TC012_CCR(n) (SAM_TC012_BASE+SAM_TCn_CCR_OFFSET(n)) +#define SAM_TC012_CMR(n) (SAM_TC012_BASE+SAM_TCn_CMR_OFFSET(n)) +#define SAM_TC012_SMMR(n) (SAM_TC012_BASE+SAM_TCn_SMMR_OFFSET(n)) +#define SAM_TC012_RAB(n) (SAM_TC012_BASE+SAM_TCn_RAB_OFFSET(n)) +#define SAM_TC012_CV(n) (SAM_TC012_BASE+SAM_TCn_CV_OFFSET(n)) +#define SAM_TC012_RA(n) (SAM_TC012_BASE+SAM_TCn_RA_OFFSET(n)) +#define SAM_TC012_RB(n) (SAM_TC012_BASE+SAM_TCn_RB(n)) +#define SAM_TC012_RC(n) (SAM_TC012_BASE+SAM_TCn_RC_OFFSET(n)) +#define SAM_TC012_SR(n) (SAM_TC012_BASE+SAM_TCn_SR_OFFSET(n)) +#define SAM_TC012_IER(n) (SAM_TC012_BASE+SAM_TCn_IER_OFFSET(n)) +#define SAM_TC012_IDR(n) (SAM_TC012_BASE+SAM_TCn_IDR_OFFSET(n)) +#define SAM_TC012_IMR(n) (SAM_TC012_BASE+SAM_TCn_IMR_OFFSET(n)) +#define SAM_TC012_EMR(n) (SAM_TC012_BASE+SAM_TCn_EMR_OFFSET(n)) + +#define SAM_TC0_CCR SAM_TC012_CCR(0) +#define SAM_TC0_CMR SAM_TC012_CMR(0) +#define SAM_TC0_SMMR SAM_TC012_SMMR(0) +#define SAM_TC0_RAB SAM_TC012_RAB(0) +#define SAM_TC0_CV SAM_TC012_CV(0) +#define SAM_TC0_RA SAM_TC012_RA(0) +#define SAM_TC0_RB SAM_TC012_RB(0) +#define SAM_TC0_RC SAM_TC012_RC(0) +#define SAM_TC0_SR SAM_TC012_SR(0) +#define SAM_TC0_IER SAM_TC012_IER(0) +#define SAM_TC0_IDR SAM_TC012_IDR(0) +#define SAM_TC0_IMR SAM_TC012_IMR(0) +#define SAM_TC0_EMR SAM_TC012_EMR(0) + +#define SAM_TC1_CCR SAM_TC012_CCR(1) +#define SAM_TC1_CMR SAM_TC012_CMR(1) +#define SAM_TC1_SMMR SAM_TC012_SMMR(1) +#define SAM_TC1_RAB SAM_TC012_RAB(1) +#define SAM_TC1_CV SAM_TC012_CV(1) +#define SAM_TC1_RA SAM_TC012_RA(1) +#define SAM_TC1_RB SAM_TC012_RB(1) +#define SAM_TC1_RC SAM_TC012_RC(1) +#define SAM_TC1_SR SAM_TC012_SR(1) +#define SAM_TC1_IER SAM_TC012_IER(1) +#define SAM_TC1_IDR SAM_TC012_IDR(1) +#define SAM_TC1_IMR SAM_TC012_IMR(1) +#define SAM_TC1_EMR SAM_TC012_EMR(1) + +#define SAM_TC2_CCR SAM_TC012_CCR(2) +#define SAM_TC2_CMR SAM_TC012_CMR(2) +#define SAM_TC2_SMMR SAM_TC012_SMMR(2) +#define SAM_TC2_RAB SAM_TC012_RAB(2) +#define SAM_TC2_CV SAM_TC012_CV(2) +#define SAM_TC2_RA SAM_TC012_RA(2) +#define SAM_TC2_RB SAM_TC012_RB(2) +#define SAM_TC2_RC SAM_TC012_RC(2) +#define SAM_TC2_SR SAM_TC012_SR(2) +#define SAM_TC2_IER SAM_TC012_IER(2) +#define SAM_TC2_IDR SAM_TC012_IDR(2) +#define SAM_TC2_IMR SAM_TC012_IMR(2) +#define SAM_TC2_EMR SAM_TC012_EMR(2) + +#define SAM_TC012_BCR (SAM_TC012_BASE+SAM_TC_BCR_OFFSET) +#define SAM_TC012_BMR (SAM_TC012_BASE+SAM_TC_BMR_OFFSET) +#define SAM_TC012_QIER (SAM_TC012_BASE+SAM_TC_QIER_OFFSET) +#define SAM_TC012_QIDR (SAM_TC012_BASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC012_QIMR (SAM_TC012_BASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC012_QISR (SAM_TC012_BASE+SAM_TC_QISR_OFFSET) +#define SAM_TC012_FMR (SAM_TC012_BASE+SAM_TC_FMR_OFFSET) +#define SAM_TC012_WPMR (SAM_TC012_BASE+SAM_TC_WPMR_OFFSET) + +#define SAM_TC345_CHAN_BASE(n) (SAM_TC345_BASE+SAM_TC_CHAN_OFFSET((n)-3)) + +#define SAM_TC345_CCR(n) (SAM_TC345_BASE+SAM_TCn_CCR_OFFSET((n)-3)) +#define SAM_TC345_CMR(n) (SAM_TC345_BASE+SAM_TCn_CMR_OFFSET((n)-3)) +#define SAM_TC345_SMMR(n) (SAM_TC345_BASE+SAM_TCn_SMMR_OFFSET((n)-3)) +#define SAM_TC345_RAB(n) (SAM_TC345_BASE+SAM_TCn_RAB_OFFSET((n)-3)) +#define SAM_TC345_CV(n) (SAM_TC345_BASE+SAM_TCn_CV_OFFSET((n)-3)) +#define SAM_TC345_RA(n) (SAM_TC345_BASE+SAM_TCn_RA_OFFSET((n)-3)) +#define SAM_TC345_RB(n) (SAM_TC345_BASE+SAM_TCn_RB_OFFSET((n)-3)) +#define SAM_TC345_RC(n) (SAM_TC345_BASE+SAM_TCn_RC_OFFSET((n)-3)) +#define SAM_TC345_SR(n) (SAM_TC345_BASE+SAM_TCn_SR_OFFSET((n)-3)) +#define SAM_TC345_IER(n) (SAM_TC345_BASE+SAM_TCn_IER_OFFSET((n)-3)) +#define SAM_TC345_IDR(n) (SAM_TC345_BASE+SAM_TCn_IDR_OFFSET((n)-3)) +#define SAM_TC345_IMR(n) (SAM_TC345_BASE+SAM_TCn_IMR_OFFSET((n)-3)) +#define SAM_TC345_EMR(n) (SAM_TC345_BASE+SAM_TCn_EMR_OFFSET((n)-3)) + +#define SAM_TC3_CCR SAM_TC345_CCR(3) +#define SAM_TC3_CMR SAM_TC345_CMR(3) +#define SAM_TC3_SMMR SAM_TC345_SMMR(3) +#define SAM_TC3_RAB SAM_TC345_RAB(3) +#define SAM_TC3_CV SAM_TC345_CV(3) +#define SAM_TC3_RA SAM_TC345_RA(3) +#define SAM_TC3_RB SAM_TC345_RB(3) +#define SAM_TC3_RC SAM_TC345_RC(3) +#define SAM_TC3_SR SAM_TC345_SR(3) +#define SAM_TC3_IER SAM_TC345_IER(3) +#define SAM_TC3_IDR SAM_TC345_IDR(3) +#define SAM_TC3_IMR SAM_TC345_IMR(3) +#define SAM_TC3_EMR SAM_TC345_EMR(3) + +#define SAM_TC4_CCR SAM_TC345_CCR(4) +#define SAM_TC4_CMR SAM_TC345_CMR(4) +#define SAM_TC4_SMMR SAM_TC345_SMMR(4) +#define SAM_TC4_RAB SAM_TC345_RAB(4) +#define SAM_TC4_CV SAM_TC345_CV(4) +#define SAM_TC4_RA SAM_TC345_RA(4) +#define SAM_TC4_RB SAM_TC345_RB(4) +#define SAM_TC4_RC SAM_TC345_RC(4) +#define SAM_TC4_SR SAM_TC345_SR(4) +#define SAM_TC4_IER SAM_TC345_IER(4) +#define SAM_TC4_IDR SAM_TC345_IDR(4) +#define SAM_TC4_IMR SAM_TC345_IMR(4) +#define SAM_TC4_EMR SAM_TC345_EMR(4) + +#define SAM_TC5_CCR SAM_TC345_CCR(5) +#define SAM_TC5_CMR SAM_TC345_CMR(5) +#define SAM_TC5_SMMR SAM_TC345_SMMR(5) +#define SAM_TC5_RAB SAM_TC345_RAB(5) +#define SAM_TC5_CV SAM_TC345_CV(5) +#define SAM_TC5_RA SAM_TC345_RA(5) +#define SAM_TC5_RB SAM_TC345_RB(5) +#define SAM_TC5_RC SAM_TC345_RC(5) +#define SAM_TC5_SR SAM_TC345_SR(5) +#define SAM_TC5_IER SAM_TC345_IER(5) +#define SAM_TC5_IDR SAM_TC345_IDR(5) +#define SAM_TC5_IMR SAM_TC345_IMR(5) +#define SAM_TC5_EMR SAM_345_EMR(5) + +#define SAM_TC345_BCR (SAM_TC345_BASE+SAM_TC_BCR_OFFSET) +#define SAM_TC345_BMR (SAM_TC345_BASE+SAM_TC_BMR_OFFSET) +#define SAM_TC345_QIER (SAM_TC345_BASE+SAM_TC_QIER_OFFSET) +#define SAM_TC345_QIDR (SAM_TC345_BASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC345_QIMR (SAM_TC345_BASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC345_QISR (SAM_TC345_BASE+SAM_TC_QISR_OFFSET) +#define SAM_TC345_FMR (SAM_TC345_BASE+SAM_TC_FMR_OFFSET) +#define SAM_TC345_WPMR (SAM_TC345_BASE+SAM_TC_WPMR_OFFSET) + +#define SAM_TC678_CHAN_BASE(n) (SAM_TC678_BASE+SAM_TC_CHAN_OFFSET((n)-6)) + +#define SAM_TC678_CCRn(n) (SAM_TC678_BASE+SAM_TCn_CCR_OFFSET((n)-6)) +#define SAM_TC678_CMR(n) (SAM_TC678_BASE+SAM_TCn_CMR_OFFSET((n)-6)) +#define SAM_TC678_SMMR(n) (SAM_TC678_BASE+SAM_TCn_SMMR_OFFSET((n)-6)) +#define SAM_TC678_RAB(n) (SAM_TC678_BASE+SAM_TCn_RAB_OFFSET((n)-6)) +#define SAM_TC678_CV(n) (SAM_TC678_BASE+SAM_TCn_CV_OFFSET((n)-6)) +#define SAM_TC678_RA(n) (SAM_TC678_BASE+SAM_TCn_RA_OFFSET((n)-6)) +#define SAM_TC678_RB(n) (SAM_TC678_BASE+SAM_TCn_RB((n)-6)) +#define SAM_TC678_RC(n) (SAM_TC678_BASE+SAM_TCn_RC_OFFSET((n)-6)) +#define SAM_TC678_SR(n) (SAM_TC678_BASE+SAM_TCn_SR_OFFSET((n)-6)) +#define SAM_TC678_IER(n) (SAM_TC678_BASE+SAM_TCn_IER_OFFSET((n)-6)) +#define SAM_TC678_IDR(n) (SAM_TC678_BASE+SAM_TCn_IDR_OFFSET((n)-6)) +#define SAM_TC678_IMR(n) (SAM_TC678_BASE+SAM_TCn_IMR_OFFSET((n)-6)) +#define SAM_TC678_EMR(n) (SAM_TC678_BASE+SAM_TCn_EMR_OFFSET((n)-6)) + +#define SAM_TC6_CCR SAM_TC678_CCR(6) +#define SAM_TC6_CMR SAM_TC678_CMR(6) +#define SAM_TC6_SMMR SAM_TC678_SMMR(6) +#define SAM_TC6_RAB SAM_TC678_RAB(6) +#define SAM_TC6_CV SAM_TC678_CV(6) +#define SAM_TC6_RA SAM_TC678_RA(6) +#define SAM_TC6_RB SAM_TC678_RB(6) +#define SAM_TC6_RC SAM_TC678_RC(6) +#define SAM_TC6_SR SAM_TC678_SR(6) +#define SAM_TC6_IER SAM_TC678_IER(6) +#define SAM_TC6_IDR SAM_TC678_IDR(6) +#define SAM_TC6_IMR SAM_TC678_IMR(6) +#define SAM_TC6_EMR SAM_TC678_EMR(6) + +#define SAM_TC7_CCR SAM_TC678_CCR(7) +#define SAM_TC7_CMR SAM_TC678_CMR(7) +#define SAM_TC7_SMMR SAM_TC678_SMMR(7) +#define SAM_TC7_RAB SAM_TC678_RAB(7) +#define SAM_TC7_CV SAM_TC678_CV(7) +#define SAM_TC7_RA SAM_TC678_RA(7) +#define SAM_TC7_RB SAM_TC678_RB(7) +#define SAM_TC7_RC SAM_TC678_RC(7) +#define SAM_TC7_SR SAM_TC678_SR(7) +#define SAM_TC7_IER SAM_TC678_IER(7) +#define SAM_TC7_IDR SAM_TC678_IDR(7) +#define SAM_TC7_IMR SAM_TC678_IMR(7) +#define SAM_TC7_EMR SAM_TC678_EMR(7) + +#define SAM_TC8_CCR SAM_TC678_CCR(8) +#define SAM_TC8_CMR SAM_TC678_CMR(8) +#define SAM_TC8_SMMR SAM_TC678_SMMR(8) +#define SAM_TC8_RAB SAM_TC678_RAB(8) +#define SAM_TC8_CV SAM_TC678_CV(8) +#define SAM_TC8_RA SAM_TC678_RA(8) +#define SAM_TC8_RB SAM_TC678_RB(8) +#define SAM_TC8_RC SAM_TC678_RC(8) +#define SAM_TC8_SR SAM_TC678_SR(8) +#define SAM_TC8_IER SAM_TC678_IER(8) +#define SAM_TC8_IDR SAM_TC678_IDR(8) +#define SAM_TC8_IMR SAM_TC678_IMR(8) +#define SAM_TC8_EMR SAM_TC678_EMR(8) + +#define SAM_TC678_BCR (SAM_TC678_BASE+SAM_TC_BCR_OFFSET) +#define SAM_TC678_BMR (SAM_TC678_BASE+SAM_TC_BMR_OFFSET) +#define SAM_TC678_QIER (SAM_TC678_BASE+SAM_TC_QIER_OFFSET) +#define SAM_TC678_QIDR (SAM_TC678_BASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC678_QIMR (SAM_TC678_BASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC678_QISR (SAM_TC678_BASE+SAM_TC_QISR_OFFSET) +#define SAM_TC678_FMR (SAM_TC678_BASE+SAM_TC_FMR_OFFSET) +#define SAM_TC678_WPMR (SAM_TC678_BASE+SAM_TC_WPMR_OFFSET) + +#define SAM_TC901_CHAN_BASE(n) (SAM_TC901_BASE+SAM_TC_CHAN_OFFSET((n)-9)) + +#define SAM_TC901_CCRn(n) (SAM_TC901_BASE+SAM_TCn_CCR_OFFSET((n)-9)) +#define SAM_TC901_CMR(n) (SAM_TC901_BASE+SAM_TCn_CMR_OFFSET((n)-9)) +#define SAM_TC901_SMMR(n) (SAM_TC901_BASE+SAM_TCn_SMMR_OFFSET((n)-9)) +#define SAM_TC901_RAB(n) (SAM_TC901_BASE+SAM_TCn_RAB_OFFSET((n)-9)) +#define SAM_TC901_CV(n) (SAM_TC901_BASE+SAM_TCn_CV_OFFSET((n)-9)) +#define SAM_TC901_RA(n) (SAM_TC901_BASE+SAM_TCn_RA_OFFSET((n)-9)) +#define SAM_TC901_RB(n) (SAM_TC901_BASE+SAM_TCn_RB((n)-9)) +#define SAM_TC901_RC(n) (SAM_TC901_BASE+SAM_TCn_RC_OFFSET((n)-9)) +#define SAM_TC901_SR(n) (SAM_TC901_BASE+SAM_TCn_SR_OFFSET((n)-9)) +#define SAM_TC901_IER(n) (SAM_TC901_BASE+SAM_TCn_IER_OFFSET((n)-9)) +#define SAM_TC901_IDR(n) (SAM_TC901_BASE+SAM_TCn_IDR_OFFSET((n)-9)) +#define SAM_TC901_IMR(n) (SAM_TC901_BASE+SAM_TCn_IMR_OFFSET((n)-9)) +#define SAM_TC901_EMR(n) (SAM_TC901_BASE+SAM_TCn_EMR_OFFSET((n)-9)) + +#define SAM_TC9_CCR SAM_TC901_CCR(9) +#define SAM_TC9_CMR SAM_TC901_CMR(9) +#define SAM_TC9_SMMR SAM_TC901_SMMR(9) +#define SAM_TC9_RAB SAM_TC901_RAB(9) +#define SAM_TC9_CV SAM_TC901_CV(9) +#define SAM_TC9_RA SAM_TC901_RA(9) +#define SAM_TC9_RB SAM_TC901_RB(9) +#define SAM_TC9_RC SAM_TC901_RC(9) +#define SAM_TC9_SR SAM_TC901_SR(9) +#define SAM_TC9_IER SAM_TC901_IER(9) +#define SAM_TC9_IDR SAM_TC901_IDR(9) +#define SAM_TC9_IMR SAM_TC901_IMR(9) +#define SAM_TC9_EMR SAM_TC901_EMR(9) + +#define SAM_TC10_CCR SAM_TC901_CCR(10) +#define SAM_TC10_CMR SAM_TC901_CMR(10) +#define SAM_TC10_SMMR SAM_TC901_SMMR(10) +#define SAM_TC10_RAB SAM_TC901_RAB(10) +#define SAM_TC10_CV SAM_TC901_CV(10) +#define SAM_TC10_RA SAM_TC901_RA(10) +#define SAM_TC10_RB SAM_TC901_RB(10) +#define SAM_TC10_RC SAM_TC901_RC(10) +#define SAM_TC10_SR SAM_TC901_SR(10) +#define SAM_TC10_IER SAM_TC901_IER(10) +#define SAM_TC10_IDR SAM_TC901_IDR(10) +#define SAM_TC10_IMR SAM_TC901_IMR(10) +#define SAM_TC10_EMR SAM_TC901_EMR(10) + +#define SAM_TC11_CCR SAM_TC901_CCR(11) +#define SAM_TC11_CMR SAM_TC901_CMR(11) +#define SAM_TC11_SMMR SAM_TC901_SMMR(11) +#define SAM_TC11_RAB SAM_TC901_RAB(11) +#define SAM_TC11_CV SAM_TC901_CV(11) +#define SAM_TC11_RA SAM_TC901_RA(11) +#define SAM_TC11_RB SAM_TC901_RB(11) +#define SAM_TC11_RC SAM_TC901_RC(11) +#define SAM_TC11_SR SAM_TC901_SR(11) +#define SAM_TC11_IER SAM_TC901_IER(11) +#define SAM_TC11_IDR SAM_TC901_IDR(11) +#define SAM_TC11_IMR SAM_TC901_IMR(11) +#define SAM_TC11_EMR SAM_TC901_EMR(11) + +#define SAM_TC901_BCR (SAM_TC901_BASE+SAM_TC_BCR_OFFSET) +#define SAM_TC901_BMR (SAM_TC901_BASE+SAM_TC_BMR_OFFSET) +#define SAM_TC901_QIER (SAM_TC901_BASE+SAM_TC_QIER_OFFSET) +#define SAM_TC901_QIDR (SAM_TC901_BASE+SAM_TC_QIDR_OFFSET) +#define SAM_TC901_QIMR (SAM_TC901_BASE+SAM_TC_QIMR_OFFSET) +#define SAM_TC901_QISR (SAM_TC901_BASE+SAM_TC_QISR_OFFSET) +#define SAM_TC901_FMR (SAM_TC901_BASE+SAM_TC_FMR_OFFSET) +#define SAM_TC901_WPMR (SAM_TC901_BASE+SAM_TC_WPMR_OFFSET) + +/* TC Register Bit Definitions ******************************************************/ + +/* Channel Control Register */ + +#define TC_CCR_CLKEN (1 << 0) /* Bit 0: Counter Clock Enable Command */ +#define TC_CCR_CLKDIS (1 << 1) /* Bit 1: Counter Clock Disable Command */ +#define TC_CCR_SWTRG (1 << 2) /* Bit 2: Software Trigger Command */ + +/* Channel Mode Register -- All modes */ + +#define TC_CMR_TCCLKS_SHIFT (0) /* Bits 0-2: Clock Selection */ +#define TC_CMR_TCCLKS_MASK (7 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS(n) ((uint32_t)(n) << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TCLK1 (0 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK1 Clock selected */ +# define TC_CMR_TCCLKS_TCLK2 (1 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK2 Clock selected */ +# define TC_CMR_TCCLKS_TCLK3 (2 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK3 Clock selected */ +# define TC_CMR_TCCLKS_TCLK4 (3 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK4 Clock selected */ +# define TC_CMR_TCCLKS_TCLK5 (4 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK5 Clock selected */ +# define TC_CMR_TCCLKS_PCK6 TC_CMR_TCCLKS_TCLK1 /* TIMER_CLOCK1 is PCK6 */ +# define TC_CMR_TCCLKS_MCK8 TC_CMR_TCCLKS_TCLK2 /* TIMER_CLOCK2 is MCK/8 */ +# define TC_CMR_TCCLKS_MCK32 TC_CMR_TCCLKS_TCLK3 /* TIMER_CLOCK3 is MCK/32 */ +# define TC_CMR_TCCLKS_MCK128 TC_CMR_TCCLKS_TCLK4 /* TIMER_CLOCK4 is MCK/128 */ +# define TC_CMR_TCCLKS_SLCK TC_CMR_TCCLKS_TCLK5 /* TIMER_CLOCK5 is SLCK */ +# define TC_CMR_TCCLKS_XC0 (5 << TC_CMR_TCCLKS_SHIFT) /* XC0 Clock selected */ +# define TC_CMR_TCCLKS_XC1 (6 << TC_CMR_TCCLKS_SHIFT) /* XC1 Clock selected */ +# define TC_CMR_TCCLKS_XC2 (7 << TC_CMR_TCCLKS_SHIFT) /* XC2 Clock selected */ +#define TC_CMR_CLKI (1 << 3) /* Bit 3: Clock Invert */ +#define TC_CMR_BURST_SHIFT (4) /* Bits 4-5: Burst Signal Selection */ +#define TC_CMR_BURST_MASK (3 << TC_CMR_BURST_SHIFT) +# define TC_CMR_BURST_NONE (0 << TC_CMR_BURST_SHIFT) /* Clock not gated by external signal */ +# define TC_CMR_BURST_XC0 (1 << TC_CMR_BURST_SHIFT) /* XXC0 ANDed with clock */ +# define TC_CMR_BURST_XC1 (2 << TC_CMR_BURST_SHIFT) /* XC1 ANDed with clock */ +# define TC_CMR_BURST_XC2 (3 << TC_CMR_BURST_SHIFT) /* XC2 ANDed with clock */ + +/* Channel Mode Register -- Capture mode */ + +#define TC_CMR_LDBSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RB Loading */ +#define TC_CMR_LDBDIS (1 << 7) /* Bit 7: Counter Clock Disable with RB Loading */ +#define TC_CMR_ETRGEDG_SHIFT (8) /* Bits 8-9: External Trigger Edge Selection */ +#define TC_CMR_ETRGEDG_MASK (3 << TC_CMR_ETRGEDG_SHIFT) +# define TC_CMR_ETRGEDG_NONE (0 << TC_CMR_ETRGEDG_SHIFT) /* Clock not gated by external signal */ +# define TC_CMR_ETRGEDG_RISING (1 << TC_CMR_ETRGEDG_SHIFT) /* Rising edge */ +# define TC_CMR_ETRGEDG_FALLING (2 << TC_CMR_ETRGEDG_SHIFT) /* Falling edge */ +# define TC_CMR_ETRGEDG_BOTH (3 << TC_CMR_ETRGEDG_SHIFT) /* EDGE Each edge */ +#define TC_CMR_ABETRG (1 << 10) /* Bit 10: TIOA or TIOB External Trigger Selection */ +#define TC_CMR_CPCTRG (1 << 14) /* Bit 14: RC Compare Trigger Enable */ +#define TC_CMR_CAPTURE (0) /* Bit 15: 0=Capture Mode */ +#define TC_CMR_LDRA_SHIFT (16) /* Bits 16-17: RA Loading Edge Selection */ +#define TC_CMR_LDRA_MASK (3 << TC_CMR_LDRA_SHIFT) +# define TC_CMR_LDRA_NONE (0 << TC_CMR_LDRA_SHIFT) /* None */ +# define TC_CMR_LDRA_RISING (1 << TC_CMR_LDRA_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRA_FALLING (2 << TC_CMR_LDRA_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRA_BOTH (3 << TC_CMR_LDRA_SHIFT) /* Each edge of TIOA */ +#define TC_CMR_LDRB_SHIFT (18) /* Bits 18-19: RB Loading Edge Selection */ +#define TC_CMR_LDRB_MASK (3 << TC_CMR_LDRB_SHIFT) +# define TC_CMR_LDRB_NONE (0 << TC_CMR_LDRB_SHIFT) /* None */ +# define TC_CMR_LDRB_RISING (1 << TC_CMR_LDRB_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRB_FALLING (2 << TC_CMR_LDRB_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRB_BOTH (3 << TC_CMR_LDRB_SHIFT) /* Each edge of TIOA */ +#define TC_CMR_SBSMPLR_SHIFT (20) /* Bits 20-22: Loading Edge Subsampling Ratio */ +#define TC_CMR_SBSMPLR_MASK (7 << TC_CMR_SBSMPLR_SHIFT) +# define TC_CMR_SBSMPLR_ONE (0 << TC_CMR_SBSMPLR_SHIFT) /* Load on each selected edge */ +# define TC_CMR_SBSMPLR_HALF (1 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 2 selected edges */ +# define TC_CMR_SBSMPLR_4TH (2 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 4 selected edges */ +# define TC_CMR_SBSMPLR_8TH (3 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 8 selected edges */ +# define TC_CMR_SBSMPLR_16TH (4 << TC_CMR_SBSMPLR_SHIFT) /* Load on every 16 selected edges */ + +/* Channel Mode Register -- Waveform mode */ + +#define TC_CMR_CPCSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RC Compare */ +#define TC_CMR_CPCDIS (1 << 7) /* Bit 7: Counter Clock Disable with RC Compare */ +#define TC_CMR_EEVTEDG_SHIFT (8) /* Bits 8-9: External Event Edge Selection */ +#define TC_CMR_EEVTEDG_MASK (3 << TC_CMR_EEVTEDG_SHIFT) +# define TC_CMR_EEVTEDG_NONE (0 << TC_CMR_EEVTEDG_SHIFT) /* None */ +# define TC_CMR_EEVTEDG_RISING (1 << TC_CMR_EEVTEDG_SHIFT) /* Rising edge */ +# define TC_CMR_EEVTEDG_FALLING (2 << TC_CMR_EEVTEDG_SHIFT) /* Falling edge */ +# define TC_CMR_EEVTEDG_BOTH (3 << TC_CMR_EEVTEDG_SHIFT) /* Each edge */ +#define TC_CMR_EEVT_SHIFT (10) /* Bits 10-11: External Event Selection */ +#define TC_CMR_EEVT_MASK (3 << TC_CMR_EEVT_SHIFT) +# define TC_CMR_EEVT_TIOB (0 << TC_CMR_EEVT_SHIFT) /* TIOB(1) input */ +# define TC_CMR_EEVT_XC0 (1 << TC_CMR_EEVT_SHIFT) /* XC0 output */ +# define TC_CMR_EEVT_XC1 (2 << TC_CMR_EEVT_SHIFT) /* XC1 output */ +# define TC_CMR_EEVT_XC2 (3 << TC_CMR_EEVT_SHIFT) /* XC2 output */ +#define TC_CMR_ENETRG (1 << 12) /* Bit 12: External Event Trigger Enable */ +#define TC_CMR_WAVSEL_SHIFT (13) /* Bits 13-14: Waveform Selection */ +#define TC_CMR_WAVSEL_MASK (3 << TC_CMR_WAVSEL_SHIFT) +# define TC_CMR_WAVSEL_UP (0 << TC_CMR_WAVSEL_SHIFT) /* UP mode w/o trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPDOWN (1 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode w/o trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPRC (2 << TC_CMR_WAVSEL_SHIFT) /* UP mode w/ trigger on RC Compare */ +# define TC_CMR_WAVSEL_UPDOWNRC (3 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN w/ with trigger on RC Compare */ +#define TC_CMR_WAVE (1 << 15) /* Bit 15: 1=Waveform Mode */ +#define TC_CMR_ACPA_SHIFT (16) /* Bits 16-17: RA Compare Effect on TIOA */ +#define TC_CMR_ACPA_MASK (3 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_NONE (0 << TC_CMR_ACPA_SHIFT) /* None */ +# define TC_CMR_ACPA_SET (1 << TC_CMR_ACPA_SHIFT) /* Set */ +# define TC_CMR_ACPA_CLEAR (2 << TC_CMR_ACPA_SHIFT) /* Clear */ +# define TC_CMR_ACPA_TOGGLE (3 << TC_CMR_ACPA_SHIFT) /* Toggle */ +#define TC_CMR_ACPC_SHIFT (18) /* Bits 18-19: RC Compare Effect on TIOA */ +#define TC_CMR_ACPC_MASK (3 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_NONE (0 << TC_CMR_ACPC_SHIFT) /* None */ +# define TC_CMR_ACPC_SET (1 << TC_CMR_ACPC_SHIFT) /* Set */ +# define TC_CMR_ACPC_CLEAR (2 << TC_CMR_ACPC_SHIFT) /* Clear */ +# define TC_CMR_ACPC_TOGGLE (3 << TC_CMR_ACPC_SHIFT) /* Toggle */ +#define TC_CMR_AEEVT_SHIFT (20) /* Bits 20-21: External Event Effect on TIOA */ +#define TC_CMR_AEEVT_MASK (3 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_NONE (0 << TC_CMR_AEEVT_SHIFT) /* None */ +# define TC_CMR_AEEVT_SET (1 << TC_CMR_AEEVT_SHIFT) /* Set */ +# define TC_CMR_AEEVT_CLEAR (2 << TC_CMR_AEEVT_SHIFT) /* Clear */ +# define TC_CMR_AEEVT_TOGGLE (3 << TC_CMR_AEEVT_SHIFT) /* Toggle */ +#define TC_CMR_ASWTRG_SHIFT (22) /* Bits 22-23: Software Trigger Effect on TIOA */ +#define TC_CMR_ASWTRG_MASK (3 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_NONE (0 << TC_CMR_ASWTRG_SHIFT) /* None */ +# define TC_CMR_ASWTRG_SET (1 << TC_CMR_ASWTRG_SHIFT) /* Set */ +# define TC_CMR_ASWTRG_CLEAR (2 << TC_CMR_ASWTRG_SHIFT) /* Clear */ +# define TC_CMR_ASWTRG_TOGGLE (3 << TC_CMR_ASWTRG_SHIFT) /* Toggle */ +#define TC_CMR_BCPB_SHIFT (24) /* Bits 24-25: RB Compare Effect on TIOB */ +#define TC_CMR_BCPB_MASK (3 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_NONE (0 << TC_CMR_BCPB_SHIFT) /* None */ +# define TC_CMR_BCPB_SET (1 << TC_CMR_BCPB_SHIFT) /* Set */ +# define TC_CMR_BCPB_CLEAR (2 << TC_CMR_BCPB_SHIFT) /* Clear */ +# define TC_CMR_BCPB_TOGGLE (3 << TC_CMR_BCPB_SHIFT) /* Toggle */ +#define TC_CMR_BCPC_SHIFT (26) /* Bits 26-27: RC Compare Effect on TIOB */ +#define TC_CMR_BCPC_MASK (3 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_NONE (0 << TC_CMR_BCPC_SHIFT) /* None */ +# define TC_CMR_BCPC_SET (1 << TC_CMR_BCPC_SHIFT) /* Set */ +# define TC_CMR_BCPC_CLEAR (2 << TC_CMR_BCPC_SHIFT) /* Clear */ +# define TC_CMR_BCPC_TOGGLE (3 << TC_CMR_BCPC_SHIFT) /* Toggle */ +#define TC_CMR_BEEVT_SHIFT (28) /* Bits 28-29: External Event Effect on TIOB */ +#define TC_CMR_BEEVT_MASK (3 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_NONE (0 << TC_CMR_BEEVT_SHIFT) /* None */ +# define TC_CMR_BEEVT_SET (1 << TC_CMR_BEEVT_SHIFT) /* Set */ +# define TC_CMR_BEEVT_CLEAR (2 << TC_CMR_BEEVT_SHIFT) /* Clear */ +# define TC_CMR_BEEVT_TOGGLE (3 << TC_CMR_BEEVT_SHIFT) /* Toggle */ +#define TC_CMR_BSWTRG_SHIFT (30) /* Bits 30-31: Software Trigger Effect on TIOB */ +#define TC_CMR_BSWTRG_MASK (3 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_NONE (0 << TC_CMR_BSWTRG_SHIFT) /* None */ +# define TC_CMR_BSWTRG_SET (1 << TC_CMR_BSWTRG_SHIFT) /* Set */ +# define TC_CMR_BSWTRG_CLEAR (2 << TC_CMR_BSWTRG_SHIFT) /* Clear */ +# define TC_CMR_BSWTRG_TOGGLE (3 << TC_CMR_BSWTRG_SHIFT) /* Toggle */ + +/* Stepper Motor Mode Register */ + +#define TC_SMMR_GCEN (1 << 0) /* Bit 0: Gray Count Enable */ +#define TC_SMMR_DOWN (1 << 1) /* Bit 1: DOWN Count */ + +/* Register AB (32-bit capture value) */ +/* Counter Value (32-bit counter value) */ +/* Register A (32-bit value) */ +/* Register B (32-bit value) */ +/* Register C (32-bit value) */ + +/* Status Register, Interrupt Enable Register, Interrupt Disable Register, and + * Interrupt Mask Register + */ + +#define TC_INT_COVFS (1 << 0) /* Bit 0: Counter Overflow Status */ +#define TC_INT_LOVRS (1 << 1) /* Bit 1: Load Overrun Status */ +#define TC_INT_CPAS (1 << 2) /* Bit 2: RA Compare Status */ +#define TC_INT_CPBS (1 << 3) /* Bit 3: RB Compare Status */ +#define TC_INT_CPCS (1 << 4) /* Bit 4: RC Compare Status */ +#define TC_INT_LDRAS (1 << 5) /* Bit 5: RA Loading Status */ +#define TC_INT_LDRBS (1 << 6) /* Bit 6: RB Loading Status */ +#define TC_INT_ETRGS (1 << 7) /* Bit 7: External Trigger Status */ +#define TC_INT_ALL (0xff) + +#define TC_SR_CLKSTA (1 << 16) /* Bit 16: Clock Enabling Status */ +#define TC_SR_MTIOA (1 << 17) /* Bit 17: TIOA Mirror */ +#define TC_SR_MTIOB (1 << 18) /* Bit 18: TIOB Mirror */ + +/* Extended Mode Register */ + +#define TC_EMR_TRIGSRCA_SHIFT (0) /* Bits 0-1: Trigger source for input A */ +#define TC_EMR_TRIGSRCA_MASK (3 << TC_EMR_TRIGSRCA_SHIFT) +# define TC_EMR_TRIGSRCA_TIOA (0 << TC_EMR_TRIGSRCA_SHIFT) /* Trigger/capture input A driven by TIOAx */ +# define TC_EMR_TRIGSRCA_PWM (1 << TC_EMR_TRIGSRCA_SHIFT) /* Trigger/capture input A driven by PWMx */ +#define TC_EMR_TRIGSRCB_SHIFT (4) /* Bits 4-5: Trigger source for input B */ +#define TC_EMR_TRIGSRCB_MASK (3 << TC_EMR_TRIGSRCB_SHIFT) +# define TC_EMR_TRIGSRCB_TIOB (0 << TC_EMR_TRIGSRCB_SHIFT) /* Trigger/capture input B driven by TIOBx */ +# define TC_EMR_TRIGSRCB_PWM (1 << TC_EMR_TRIGSRCB_SHIFT) /* Trigger/capture input B driven PWMx */ +#define TC_EMR_NODIVCLK (1 << 8) /* Bit 8: No divided clock */ + +/* Block Control Register */ + +#define TC_BCR_SYNC (1 << 0) /* Bit 0: Synchro Command */ + +/* Block Mode Register */ + +#define TC_BMR_TC0XC0S_SHIFT (0) /* Bits 0-1: External Clock Signal 0 Selection */ +#define TC_BMR_TC0XC0S_MASK (3 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC0XC0S_TCLK0 (0 << TC_BMR_TC0XC0S_SHIFT) /* TCLK0 Signal to XC0 */ +# define TC_BMR_TC0XC0S_TIOA1 (2 << TC_BMR_TC0XC0S_SHIFT) /* TIOA1 Signal to XC0 */ +# define TC_BMR_TC0XC0S_TIOA2 (3 << TC_BMR_TC0XC0S_SHIFT) /* TIOA2 Signal to XC0 */ +#define TC_BMR_TC1XC1S_SHIFT (2) /* Bits 2-3: External Clock Signal 1 Selection */ +#define TC_BMR_TC1XC1S_MASK (3 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC1XC1S_TCLK1 (0 << TC_BMR_TC1XC1S_SHIFT) /* TCLK1 Signal to XC1 */ +# define TC_BMR_TC1XC1S_TIOA0 (2 << TC_BMR_TC1XC1S_SHIFT) /* TIOA0 Signal to XC1 */ +# define TC_BMR_TC1XC1S_TIOA2 (3 << TC_BMR_TC1XC1S_SHIFT) /* TIOA2 Signal to XC1 */ +#define TC_BMR_TC2XC2S_SHIFT (4) /* Bits 4-5: External Clock Signal 2 Selection */ +#define TC_BMR_TC2XC2S_MASK (3 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT) /* TCLK2 Signal to XC2 */ +# define TC_BMR_TC2XC2S_TIOA0 (2 << TC_BMR_TC2XC2S_SHIFT) /* TIOA0 Signal to XC2 */ +# define TC_BMR_TC2XC2S_TIOA1 (3 << TC_BMR_TC2XC2S_SHIFT) /* TIOA1 Signal to XC2 */ +#define TC_BMR_QDEN (1 << 8) /* Bit 8: Quadrature Decoder ENabled */ +#define TC_BMR_POSEN (1 << 9) /* Bit 9: POSition ENabled */ +#define TC_BMR_SPEEDEN (1 << 10) /* Bit 10: SPEED ENabled */ +#define TC_BMR_QDTRANS (1 << 11) /* Bit 11: Quadrature Decoding TRANSparent */ +#define TC_BMR_EDGPHA (1 << 12) /* Bit 12: EDGe on PHA count mode */ +#define TC_BMR_INVA (1 << 13) /* Bit 13: INVerted phA */ +#define TC_BMR_INVB (1 << 14) /* Bit 14: INVerted phB */ +#define TC_BMR_INVIDX (1 << 15) /* Bit 15: INVerted InDeX */ +#define TC_BMR_SWAP (1 << 16) /* Bit 16: SWAP PHA and PHB */ +#define TC_BMR_IDXPHB (1 << 17) /* Bit 17: InDeX pin is PHB pin */ +#define TC_BMR_MAXFILT_SHIFT (20) /* Bits 20-25: MAXimum FILTer */ +#define TC_BMR_MAXFILT_MASK (63 << TC_BMR_MAXFILT_SHIFT) +# define TC_BMR_MAXFILT(n) ((uint32_t)(n) << TC_BMR_MAXFILT_SHIFT) + +/* QDEC Interrupt Enable Register, QDEC Interrupt Disable Register, QDEC Interrupt Mask Register, and QDEC Interrupt Status Register. + */ + +#define TC_QINT_IDX (1 << 0) /* Bit 0: Index */ +#define TC_QINT_DIRCHG (1 << 1) /* Bit 1: Direction change */ +#define TC_QINT_QERR (1 << 2) /* Bit 2: Quadrature ERRor */ + +#define TC_QISR_DIRR (1 << 8) /* Bit 8: Direction */ + +/* Fault Mode Register */ + +#define TC_FMR_ENCF0 (1 << 0) /* Bit 0: ENable Compare Fault Channel 0 */ +#define TC_FMR_ENCF1 (1 << 1) /* Bit 1: ENable Compare Fault Channel 1 */ + +/* Write Protect Mode Register */ + +#define TC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define TC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */ +#define TC_WPMR_WPKEY_MASK (0xffffff << TC_WPMR_WPKEY_SHIFT) +# define TC_WPMR_WPKEY (0x54494d << TC_WPMR_WPKEY_SHIFT) /* "TIM" in ASCII */ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TC_H */ diff --git a/arch/arm/src/samv7/chip/sam_trng.h b/arch/arm/src/samv7/chip/sam_trng.h new file mode 100644 index 0000000000000000000000000000000000000000..5f4d2ef3a1e1f48091001f240786cb4ac1c6f40a --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_trng.h @@ -0,0 +1,85 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_trng.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TRNG_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TRNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/sam_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* TRNG Register Offsets ************************************************************/ + +#define SAM_TRNG_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_TRNG_IER_OFFSET 0x0010 /* Interrupt Enable Register */ +#define SAM_TRNG_IDR_OFFSET 0x0014 /* Interrupt Disable Register */ +#define SAM_TRNG_IMR_OFFSET 0x0018 /* Interrupt Mask Register */ +#define SAM_TRNG_ISR_OFFSET 0x001c /* Interrupt Status Register */ +#define SAM_TRNG_ODATA_OFFSET 0x0050 /* Output Data Register */ + +/* TRNG Register Addresses **********************************************************/ + +#define SAM_TRNG_CR (SAM_TRNG_BASE+SAM_TRNG_CR_OFFSET) +#define SAM_TRNG_IER (SAM_TRNG_BASE+SAM_TRNG_IER_OFFSET) +#define SAM_TRNG_IDR (SAM_TRNG_BASE+SAM_TRNG_IDR_OFFSET) +#define SAM_TRNG_IMR (SAM_TRNG_BASE+SAM_TRNG_IMR_OFFSET) +#define SAM_TRNG_ISR (SAM_TRNG_BASE+SAM_TRNG_ISR_OFFSET) +#define SAM_TRNG_ODATA (SAM_TRNG_BASE+SAM_TRNG_ODATA_OFFSET) + +/* TRNG Register Bit Definitions ****************************************************/ + +/* Control Register */ + +#define TRNG_CR_ENABLE (1 << 0) /* Bit 0: 1=Enables the TRNG */ +# define TRNG_CR_DISABLE (0) /* Bit 0: 0=Disables the TRNG */ +#define TRNG_CR_KEY_SHIFT (8) /* Bits 8-31: Security key */ +#define TRNG_CR_KEY_MASK (0xffffff << TRNG_CR_KEY_SHIFT) +# define TRNG_CR_KEY (0x524e47 << TRNG_CR_KEY_SHIFT) /* RNG in ASCII */ + +/* Interrupt Enable Register, Interrupt Disable Register, Interrupt Mask Register, + * and Interrupt Status Register + */ + +#define TRNG_INT_DATRDY (1 << 0) /* Bit 0: Data ready */ + +/* Output Data Register (32-bit output data) */ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TRNG_H */ diff --git a/arch/arm/src/samv7/chip/sam_twihs.h b/arch/arm/src/samv7/chip/sam_twihs.h new file mode 100644 index 0000000000000000000000000000000000000000..c036812de53812b7c4710415bd406cd688167f3e --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_twihs.h @@ -0,0 +1,306 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_twihs.h + * Two-wire Interface (TWIHS) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 SAMV7_NTWIHS PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TWIHS_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TWIHS_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +#if SAMV7_NTWIHS > 0 + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* TWIHS register offsets *****************************************************************/ + +#define SAM_TWIHS_CR_OFFSET 0x0000 /* Control Register */ +#define SAM_TWIHS_MMR_OFFSET 0x0004 /* Master Mode Register */ +#define SAM_TWIHS_SMR_OFFSET 0x0008 /* Slave Mode Register */ +#define SAM_TWIHS_IADR_OFFSET 0x000c /* Internal Address Register */ +#define SAM_TWIHS_CWGR_OFFSET 0x0010 /* Clock Waveform Generator Register */ + /* 0x0014-0x001c: Reserved */ +#define SAM_TWIHS_SR_OFFSET 0x0020 /* Status Register */ +#define SAM_TWIHS_IER_OFFSET 0x0024 /* Interrupt Enable Register */ +#define SAM_TWIHS_IDR_OFFSET 0x0028 /* Interrupt Disable Register */ +#define SAM_TWIHS_IMR_OFFSET 0x002c /* Interrupt Mask Register */ +#define SAM_TWIHS_RHR_OFFSET 0x0030 /* Receive Holding Register */ +#define SAM_TWIHS_THR_OFFSET 0x0034 /* Transmit Holding Register */ +#define SAM_TWIHS_SMBTR_OFFSET 0x0038 /* SMBus Timing Register */ +#define SAM_TWIHS_FILTR_OFFSET 0x0044 /* Filter Register */ +#define SAM_TWIHS_SWMR_OFFSET 0x004c /* SleepWalking Matching Register */ + /* 0x3c-0xe0: Reserved */ +#define SAM_TWIHS_WPMR_OFFSET 0x00e4 /* Protection Mode Register */ +#define SAM_TWIHS_WPSR_OFFSET 0x00e8 /* Protection Status Register */ + +/* TWIHS register addresses ***************************************************************/ + +#define SAM_TWIHS0_CR (SAM_TWIHS0_BASE+SAM_TWIHS_CR_OFFSET) +#define SAM_TWIHS0_MMR (SAM_TWIHS0_BASE+SAM_TWIHS_MMR_OFFSET) +#define SAM_TWIHS0_SMR (SAM_TWIHS0_BASE+SAM_TWIHS_SMR_OFFSET) +#define SAM_TWIHS0_IADR (SAM_TWIHS0_BASE+SAM_TWIHS_IADR_OFFSET) +#define SAM_TWIHS0_CWGR (SAM_TWIHS0_BASE+SAM_TWIHS_CWGR_OFFSET) +#define SAM_TWIHS0_SR (SAM_TWIHS0_BASE+SAM_TWIHS_SR_OFFSET) +#define SAM_TWIHS0_IER (SAM_TWIHS0_BASE+SAM_TWIHS_IER_OFFSET) +#define SAM_TWIHS0_IDR (SAM_TWIHS0_BASE+SAM_TWIHS_IDR_OFFSET) +#define SAM_TWIHS0_IMR (SAM_TWIHS0_BASE+SAM_TWIHS_IMR_OFFSET) +#define SAM_TWIHS0_RHR (SAM_TWIHS0_BASE+SAM_TWIHS_RHR_OFFSET) +#define SAM_TWIHS0_THR (SAM_TWIHS0_BASE+SAM_TWIHS_THR_OFFSET) +#define SAM_TWIHS0_SMBTR (SAM_TWIHS0_BASE+SAM_TWIHS_SMBTR_OFFSET) +#define SAM_TWIHS0_FILTR (SAM_TWIHS0_BASE+SAM_TWIHS_FILTR_OFFSET) +#define SAM_TWIHS0_SWMR (SAM_TWIHS0_BASE+SAM_TWIHS_SWMR_OFFSET) +#define SAM_TWIHS0_WPMR (SAM_TWIHS0_BASE+SAM_TWIHS_WPMR_OFFSET) +#define SAM_TWIHS0_WPSR (SAM_TWIHS0_BASE)+SAM_TWIHS_WPSR_OFFSET) + +#if SAMV7_NTWIHS > 1 +# define SAM_TWIHS1_CR (SAM_TWIHS1_BASE+SAM_TWIHS_CR_OFFSET) +# define SAM_TWIHS1_MMR (SAM_TWIHS1_BASE+SAM_TWIHS_MMR_OFFSET) +# define SAM_TWIHS1_SMR (SAM_TWIHS1_BASE+SAM_TWIHS_SMR_OFFSET) +# define SAM_TWIHS1_IADR (SAM_TWIHS1_BASE+SAM_TWIHS_IADR_OFFSET) +# define SAM_TWIHS1_CWGR (SAM_TWIHS1_BASE+SAM_TWIHS_CWGR_OFFSET) +# define SAM_TWIHS1_SR (SAM_TWIHS1_BASE+SAM_TWIHS_SR_OFFSET) +# define SAM_TWIHS1_IER (SAM_TWIHS1_BASE+SAM_TWIHS_IER_OFFSET) +# define SAM_TWIHS1_IDR (SAM_TWIHS1_BASE+SAM_TWIHS_IDR_OFFSET) +# define SAM_TWIHS1_IMR (SAM_TWIHS1_BASE+SAM_TWIHS_IMR_OFFSET) +# define SAM_TWIHS1_RHR (SAM_TWIHS1_BASE+SAM_TWIHS_RHR_OFFSET) +# define SAM_TWIHS1_THR (SAM_TWIHS1_BASE+SAM_TWIHS_THR_OFFSET) +# define SAM_TWIHS1_SMBTR (SAM_TWIHS1_BASE+SAM_TWIHS_SMBTR_OFFSET) +# define SAM_TWIHS1_FILTR (SAM_TWIHS1_BASE+SAM_TWIHS_FILTR_OFFSET) +# define SAM_TWIHS1_SWMR (SAM_TWIHS1_BASE+SAM_TWIHS_SWMR_OFFSET) +# define SAM_TWIHS1_WPMR (SAM_TWIHS1_BASE+SAM_TWIHS_WPMR_OFFSET) +# define SAM_TWIHS1_WPSR (SAM_TWIHS1_BASE)+SAM_TWIHS_WPSR_OFFSET) +#endif + +#if SAMV7_NTWIHS > 2 +# define SAM_TWIHS2_CR (SAM_TWIHS2_BASE+SAM_TWIHS_CR_OFFSET) +# define SAM_TWIHS2_MMR (SAM_TWIHS2_BASE+SAM_TWIHS_MMR_OFFSET) +# define SAM_TWIHS2_SMR (SAM_TWIHS2_BASE+SAM_TWIHS_SMR_OFFSET) +# define SAM_TWIHS2_IADR (SAM_TWIHS2_BASE+SAM_TWIHS_IADR_OFFSET) +# define SAM_TWIHS2_CWGR (SAM_TWIHS2_BASE+SAM_TWIHS_CWGR_OFFSET) +# define SAM_TWIHS2_SR (SAM_TWIHS2_BASE+SAM_TWIHS_SR_OFFSET) +# define SAM_TWIHS2_IER (SAM_TWIHS2_BASE+SAM_TWIHS_IER_OFFSET) +# define SAM_TWIHS2_IDR (SAM_TWIHS2_BASE+SAM_TWIHS_IDR_OFFSET) +# define SAM_TWIHS2_IMR (SAM_TWIHS2_BASE+SAM_TWIHS_IMR_OFFSET) +# define SAM_TWIHS2_RHR (SAM_TWIHS2_BASE+SAM_TWIHS_RHR_OFFSET) +# define SAM_TWIHS2_THR (SAM_TWIHS2_BASE+SAM_TWIHS_THR_OFFSET) +# define SAM_TWIHS2_SMBTR (SAM_TWIHS2_BASE+SAM_TWIHS_SMBTR_OFFSET) +# define SAM_TWIHS2_FILTR (SAM_TWIHS2_BASE+SAM_TWIHS_FILTR_OFFSET) +# define SAM_TWIHS2_SWMR (SAM_TWIHS2_BASE+SAM_TWIHS_SWMR_OFFSET) +# define SAM_TWIHS2_WPMR (SAM_TWIHS2_BASE+SAM_TWIHS_WPMR_OFFSET) +# define SAM_TWIHS2_WPSR (SAM_TWIHS2_BASE)+SAM_TWIHS_WPSR_OFFSET) +#endif + +/* TWIHS register bit definitions *********************************************************/ +/* TWIHS Control Register */ + +#define TWIHS_CR_START (1 << 0) /* Bit 0: Send SAMV7_NTWIHS START Condition */ +#define TWIHS_CR_STOP (1 << 1) /* Bit 1: Send SAMV7_NTWIHS STOP Condition */ +#define TWIHS_CR_MSEN (1 << 2) /* Bit 2: TWIHS Master Mode Enabled */ +#define TWIHS_CR_MSDIS (1 << 3) /* Bit 3: TWIHS Master Mode Disabled */ +#define TWIHS_CR_SVEN (1 << 4) /* Bit 4: TWIHS Slave Mode Enabled */ +#define TWIHS_CR_SVDIS (1 << 5) /* Bit 5: TWIHS Slave Mode Disabled */ +#define TWIHS_CR_QUICK (1 << 6) /* Bit 6: SMBUS Quick Command */ +#define TWIHS_CR_SWRST (1 << 7) /* Bit 7: Software Reset */ +#define TWIHS_CR_HSEN (1 << 8) /* Bit 8: TWIHS High-Speed Mode Enabled */ +#define TWIHS_CR_HSDIS (1 << 9) /* Bit 9: TWIHS High-Speed Mode Disabled */ +#define TWIHS_CR_SMBEN (1 << 10) /* Bit 10: SMBus Mode Enabled */ +#define TWIHS_CR_SMBDIS (1 << 11) /* Bit 11: SMBus Mode Disabled */ +#define TWIHS_CR_PECEN (1 << 12) /* Bit 12: Packet Error Checking Enable */ +#define TWIHS_CR_PECDIS (1 << 13) /* Bit 13: Packet Error Checking Disable */ +#define TWIHS_CR_PECRQ (1 << 14) /* Bit 14: PEC Request */ +#define TWIHS_CR_CLEAR (1 << 15) /* Bit 15: Bus CLEAR Command */ + +/* TWIHS Master Mode Register */ + +#define TWIHS_MMR_IADRSZ_SHIFT (8) /* Bits 8-9: Internal Device Address Size */ +#define TWIHS_MMR_IADRSZ_MASK (3 << TWIHS_MMR_IADRSZ_SHIFT) +# define TWIHS_MMR_IADRSZ_NONE (0 << TWIHS_MMR_IADRSZ_SHIFT) /* No internal device address */ +# define TWIHS_MMR_IADRSZ_1BYTE (1 << TWIHS_MMR_IADRSZ_SHIFT) /* One-byte internal device address */ +# define TWIHS_MMR_IADRSZ_2BYTE (2 << TWIHS_MMR_IADRSZ_SHIFT) /* Two-byte internal device address */ +# define TWIHS_MMR_IADRSZ_3BYTE (3 << TWIHS_MMR_IADRSZ_SHIFT) /* Three-byte internal device address */ +#define TWIHS_MMR_MREAD (1 << 12) /* Bit 12: Master Read Direction */ +#define TWIHS_MMR_DADR_SHIFT (16) /* Bits 16-22: Device Address */ +#define TWIHS_MMR_DADR_MASK (0x7f << TWIHS_MMR_DADR_SHIFT) +# define TWIHS_MMR_DADR(n) ((uint32_t)(n) << TWIHS_MMR_DADR_SHIFT) + +/* TWIHS Slave Mode Register */ + +#define TWIHS_SMR_NACKEN (1 << 0) /* Bit 0: Slave Receiver Data Phase NACK enable */ +#define TWIHS_SMR_SMDA (1 << 2) /* Bit 2: SMBus Default Address */ +#define TWIHS_SMR_SMHH (1 << 3) /* Bit 3: SMBus Host Header */ +#define TWIHS_SMR_SCLWSDIS (1 << 6) /* Bit 6: Clock Wait State Disable */ +#define TWIHS_SMR_MASK_SHIFT (8) /* Bits 8-14: Slave Address Mask */ +#define TWIHS_SMR_MASK_MASK (0x7f << TWIHS_SMR_MASK_SHIFT) +# define TWIHS_SMR_MASK(n) ((uint32_t)(n) << TWIHS_SMR_MASK_SHIFT) +#define TWIHS_SMR_SADR_SHIFT (16) /* Bits 16-22: Slave Address */ +#define TWIHS_SMR_SADR_MASK (0x7f << TWIHS_SMR_SADR_SHIFT) +# define TWIHS_SMR_SADR(n) ((uint32_t)(n) << TWIHS_SMR_SADR_SHIFT) +#define TWIHS_SMR_SADR1EN (1 << 28) /* Bit 28: Slave Address 1 Enable */ +#define TWIHS_SMR_SADR2EN (1 << 29) /* Bit 29: Slave Address 2 Enable */ +#define TWIHS_SMR_SADR3EN (1 << 20) /* Bit 20: Slave Address 3 Enable */ +#define TWIHS_SMR_DATAMEN (1 << 21) /* Bit 21: Data Matching Enable */ + +/* TWIHS Internal Address Register */ + +#define TWIHS_IADR_SHIFT (0) /* Bits 0-23: Internal Address */ +#define TWIHS_IADR_MASK (0x00ffffff << TWIHS_IADR_SHIFT) + +/* TWIHS Clock Waveform Generator Register */ + +#define TWIHS_CWGR_CLDIV_SHIFT (0) /* Bits 0-7: Clock Low Divider */ +#define TWIHS_CWGR_CLDIV_MASK (0xff << TWIHS_CWGR_CLDIV_SHIFT) +# define TWIHS_CWGR_CLDIV(n) ((uint32_t)(n) << TWIHS_CWGR_CLDIV_SHIFT) +#define TWIHS_CWGR_CHDIV_SHIFT (8) /* Bits 8-15: Clock High Divider */ +#define TWIHS_CWGR_CHDIV_MASK (0xff << TWIHS_CWGR_CLDIV_SHIFT) +# define TWIHS_CWGR_CHDIV(n) ((uint32_t)(n) << TWIHS_CWGR_CLDIV_SHIFT) +#define TWIHS_CWGR_CKDIV_SHIFT (16) /* Bits 16-18: Clock Divider */ +#define TWIHS_CWGR_CKDIV_MASK (7 << TWIHS_CWGR_CLDIV_SHIFT) +# define TWIHS_CWGR_CKDIV(n) ((uint32_t)(n) << TWIHS_CWGR_CLDIV_SHIFT) +#define TWIHS_CWGR_HOLD_SHIFT (24) /* Bits 24-28: TWD Hold Time Versus TWCK Falling */ +#define TWIHS_CWGR_HOLD_MASK (31 << TWIHS_CWGR_HOLD_SHIFT) +# define TWIHS_CWGR_HOLD(n) ((uint32_t)(n) << TWIHS_CWGR_HOLD_SHIFT) + +/* TWIHS Status Register, TWIHS Interrupt Enable Register, TWIHS Interrupt Disable + * Register, and TWIHS Interrupt Mask Register common bit fields. + */ + +#define TWIHS_INT_TXCOMP (1 << 0) /* Bit 0: Transmission Completed */ +#define TWIHS_INT_RXRDY (1 << 1) /* Bit 1: Receive Holding Register */ +#define TWIHS_INT_TXRDY (1 << 2) /* Bit 2: Transmit Holding Register Ready */ +#define TWIHS_SR_SVREAD (1 << 3) /* Bit 3: Slave Read (SR only) */ +#define TWIHS_INT_SVACC (1 << 4) /* Bit 4: Slave Access */ +#define TWIHS_INT_GACC (1 << 5) /* Bit 5: General Call Access */ +#define TWIHS_INT_OVRE (1 << 6) /* Bit 6: Overrun Error */ +#define TWIHS_INT_UNRE (1 << 7) /* Bit 7: Underrun Error */ +#define TWIHS_INT_NACK (1 << 8) /* Bit 8: Not Acknowledged */ +#define TWIHS_INT_ARBLST (1 << 9) /* Bit 9: Arbitration Lost */ +#define TWIHS_INT_SCLWS (1 << 10) /* Bit 10: Clock Wait State */ +#define TWIHS_INT_EOSACC (1 << 11) /* Bit 11: End Of Slave Access */ +#define TWIHS_INT_MCACK (1 << 16) /* Bit 16: Master Code Acknowledge */ +#define TWIHS_INT_TOUT (1 << 18) /* Bit 18: Timeout Error */ +#define TWIHS_INT_PECERR (1 << 19) /* Bit 19: PEC Error */ +#define TWIHS_INT_SMBDAM (1 << 20) /* Bit 20: SMBus Default Address Match */ +#define TWIHS_INT_SMBHHM (1 << 21) /* Bit 21: SMBus Host Header Address Match */ +#define TWIHS_INT_SCL (1 << 24) /* Bit 24: SCL Line Value (SR only) */ +#define TWIHS_INT_SDA (1 << 25) /* Bit 25: SDA Line Value (SR only) */ + +#define TWIHS_INT_ERRORS 0x000c03c0 +#define TWIHS_INT_ALL 0x033d0fff + +/* TWIHS Receive Holding Register */ + +#define TWIHS_RHR_RXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Receive Holding Data */ +#define TWIHS_RHR_RXDATA_MASK (0xff << TWIHS_RHR_RXDATA_SHIFT) + +/* TWIHS Transmit Holding Register */ + +#define TWIHS_THR_TXDATA_SHIFT (0) /* Bits 0-7: Master or Slave Transmit Holding Data */ +#define TWIHS_THR_TXDATA_MASK (0xff << TWIHS_THR_TXDATA_SHIFT) + + +/* SMBus Timing Register */ + +#define TWIHS_SMBTR_PRESC_SHIFT (0) /* Bits 0-3: SMBus Clock Prescaler */ +#define TWIHS_SMBTR_PRESC_MASK (15 << TWIHS_SMBTR_PRESC_SHIFT) +# define TWIHS_SMBTR_PRESC(n) ((uint32_t)(n) << TWIHS_SMBTR_PRESC_SHIFT) +#define TWIHS_SMBTR_TLOWS_SHIFT (8) /* Bits 8-15: Slave Clock Stretch Maximum */Cycles +#define TWIHS_SMBTR_TLOWS_MASK (0xff << TWIHS_SMBTR_TLOWS_SHIFT) +# define TWIHS_SMBTR_TLOWS(n) ((uint32_t)(n) << TWIHS_SMBTR_TLOWS_SHIFT) +#define TWIHS_SMBTR_TLOWM_SHIFT (16) /* Bits 16-23: Master Clock Stretch */Maximum Cycles +#define TWIHS_SMBTR_TLOWM_MASK (0xff << TWIHS_SMBTR_TLOWM_SHIFT) +# define TWIHS_SMBTR_TLOWM(n) ((uint32_t)(n) << TWIHS_SMBTR_TLOWM_SHIFT) +#define TWIHS_SMBTR_THMAX_SHIFT (24) /* Bits 24-24: Clock High Maximum Cycles */ +#define TWIHS_SMBTR_THMAX_MASK (0xff << TWIHS_SMBTR_THMAX_SHIFT) +# define TWIHS_SMBTR_THMAX(n) ((uint32_t)(n) << TWIHS_SMBTR_THMAX_SHIFT) + +/* Filter Register */ + +#define TWIHS_FILTR_FILT (1 << 0) /* Bit 0: RX Digital Filter */ +#define TWIHS_FILTR_PADFEN (1 << 1) /* Bit 1: PAD Filter Enable */ +#define TWIHS_FILTR_PADFCFG (1 << 2) /* Bit 2: PAD Filter Config */ +#define TWIHS_FILTR_THRES_SHIFT (8) /* Bits 8-10: Digital Filter Threshold */ +#define TWIHS_FILTR_THRES_MASK (7 << TWIHS_FILTR_THRES_SHIFT) +# define TWIHS_FILTR_THRES(n) ((uint32_t)(n) << TWIHS_FILTR_THRES_SHIFT) + +/* SleepWalking Matching Register */ + +#define TWIHS_SWMR_SADR1_SHIFT (0) /* Bits 0-6: Slave Address 1 */ +#define TWIHS_SWMR_SADR1_MASK (0x7f << TWIHS_SWMR_SADR1_SHIFT) +# define TWIHS_SWMR_SADR1(n) ((uint32_t)(n) << TWIHS_SWMR_SADR1_SHIFT) +#define TWIHS_SWMR_SADR2_SHIFT (8) /* Bits 8-24: Slave Address 2 */ +#define TWIHS_SWMR_SADR2_MASK (0x7f << TWIHS_SWMR_SADR2_SHIFT) +# define TWIHS_SWMR_SADR2(n) ((uint32_t)(n) << TWIHS_SWMR_SADR2_SHIFT) +#define TWIHS_SWMR_SADR3_SHIFT (16) /* Bits 16-22: Slave Address 3 */ +#define TWIHS_SWMR_SADR3_MASK (0x7f << TWIHS_SWMR_SADR3_SHIFT) +# define TWIHS_SWMR_SADR3(n) ((uint32_t)(n) << TWIHS_SWMR_SADR3_SHIFT) +#define TWIHS_SWMR_DATAM_SHIFT (24) /* Bits 24-31: Data Match */ +#define TWIHS_SWMR_DATAM_MASK (0xff << TWIHS_SWMR_DATAM_SHIFT) +# define TWIHS_SWMR_DATAM(n) ((uint32_t)(n) << TWIHS_SWMR_DATAM_SHIFT) + +/* Protection Mode Register */ + +#define TWIHS_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */ +#define TWIHS_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect Key */ +#define TWIHS_WPMR_WPKEY_MASK (0x00ffffff << TWIHS_WPMR_WPKEY_SHIFT) +# define TWIHS_WPMR_WPKEY (0x00545749 << TWIHS_WPMR_WPKEY_SHIFT) + +/* Protection Status Register */ + +#define TWIHS_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status */ +#define TWIHS_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source */ +#define TWIHS_WPSR_WPVSRC_MASK (0xffff << TWIHS_WPSR_WPVSRC_SHIFT) + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* SAMV7_NTWIHS > 0 */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_TWIHS_H */ diff --git a/arch/arm/src/samv7/chip/sam_uart.h b/arch/arm/src/samv7/chip/sam_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..c0fdac8acf7a691e791ff1c45da12ec0ff6e5e5c --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_uart.h @@ -0,0 +1,574 @@ +/************************************************************************************************ + * arch/arm/src/samv7/chip/sam_uart.h + * Universal Asynchronous Receiver Transmitter (UART) and Universal Synchronous Asynchronous + * Receiver Transmitter (USART) definitions for the SAMV71. + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UART_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UART_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include + +#include "arch/samv7/chip.h" +#include "chip/sam_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* UART register offsets ************************************************************************/ + +#define SAM_UART_CR_OFFSET 0x0000 /* Control Register (Common) */ +#define SAM_UART_MR_OFFSET 0x0004 /* Mode Register (Common) */ +#define SAM_UART_IER_OFFSET 0x0008 /* Interrupt Enable Register (Common) */ +#define SAM_UART_IDR_OFFSET 0x000c /* Interrupt Disable Register (Common) */ +#define SAM_UART_IMR_OFFSET 0x0010 /* Interrupt Mask Register (Common) */ +#define SAM_UART_SR_OFFSET 0x0014 /* [Channel] Status Register (Common) */ +#define SAM_UART_RHR_OFFSET 0x0018 /* Receive Holding Register (Common) */ +#define SAM_UART_THR_OFFSET 0x001c /* Transmit Holding Register (Common) */ +#define SAM_UART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register (Common) */ +#define SAM_UART_CMPR_OFFSET 0x0024 /* Comparison Register (UART only) */ +#define SAM_UART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register (USART only) */ +#define SAM_UART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register (USART only) */ + /* 0x0028-0x00e0: Reserved (UART) */ + /* 0x002c-0x004c: Reserved (USART) */ +#define SAM_UART_IFR_OFFSET 0x004c /* IrDA Filter Register (USART only) */ +#define SAM_UART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register (USART only) */ +#define SAM_UART_LINMR_OFFSET 0x0054 /* LIN Mode Register (USART only) */ +#define SAM_UART_LINIR_OFFSET 0x0058 /* LIN Identifier Register (USART only) */ +#define SAM_UART_LINBRR_OFFSET 0x005c /* LIN Baud Rate Register (USART only) */ +#define SAM_UART_LONMR_OFFSET 0x0060 /* LON Mode Register (USART only) */ +#define SAM_UART_LONPR_OFFSET 0x0064 /* LON Preamble Register (USART only) */ +#define SAM_UART_LONDL_OFFSET 0x0068 /* LON Data Length Register (USART only) */ +#define SAM_UART_LONL2HDR_OFFSET 0x006c /* LON L2HDR Register (USART only) */ +#define SAM_UART_LONBL_OFFSET 0x0070 /* LON Backlog Register (USART only) */ +#define SAM_UART_LONB1TX_OFFSET 0x0074 /* LON Beta1 Tx Register (USART only) */ +#define SAM_UART_LONB1RX_OFFSET 0x0078 /* LON Beta1 Rx Register (USART only) */ +#define SAM_UART_LONPRIO_OFFSET 0x007c /* LON Priority Register (USART only) */ +#define SAM_UART_IDTTX_OFFSET 0x0080 /* LON IDT Tx Register (USART only) */ +#define SAM_UART_IDTRX_OFFSET 0x0084 /* LON IDT Rx Register (USART only) */ +#define SAM_UART_ICDIFF_OFFSET 0x0088 /* IC DIFF Registe (USART only) */ + /* 0x008c-0x00e0: Reserved (USART) */ +#define SAM_UART_WPMR_OFFSET 0x00e4 /* Write Protect Mode Register (common) */ +#define SAM_UART_WPSR_OFFSET 0x00e8 /* Write Protect Status Register (USART only) */ + /* 0x00ec-0x00fc: Reserved (USART) */ + +/* UART register addresses **********************************************************************/ + +#if SAMV7_NUART > 0 +# define SAM_UART0_CR (SAM_UART0_BASE+SAM_UART_CR_OFFSET) +# define SAM_UART0_MR (SAM_UART0_BASE+SAM_UART_MR_OFFSET) +# define SAM_UART0_IER (SAM_UART0_BASE+SAM_UART_IER_OFFSET) +# define SAM_UART0_IDR (SAM_UART0_BASE+SAM_UART_IDR_OFFSET) +# define SAM_UART0_IMR (SAM_UART0_BASE+SAM_UART_IMR_OFFSET) +# define SAM_UART0_SR (SAM_UART0_BASE+SAM_UART_SR_OFFSET) +# define SAM_UART0_RHR (SAM_UART0_BASE+SAM_UART_RHR_OFFSET) +# define SAM_UART0_THR (SAM_UART0_BASE+SAM_UART_THR_OFFSET) +# define SAM_UART0_BRGR (SAM_UART0_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART0_CMPR (SAM_UART0_BASE+SAM_UART_CMPR_OFFSET) +#endif + +#if SAMV7_NUART > 1 +# define SAM_UART1_CR (SAM_UART1_BASE+SAM_UART_CR_OFFSET) +# define SAM_UART1_MR (SAM_UART1_BASE+SAM_UART_MR_OFFSET) +# define SAM_UART1_IER (SAM_UART1_BASE+SAM_UART_IER_OFFSET) +# define SAM_UART1_IDR (SAM_UART1_BASE+SAM_UART_IDR_OFFSET) +# define SAM_UART1_IMR (SAM_UART1_BASE+SAM_UART_IMR_OFFSET) +# define SAM_UART1_SR (SAM_UART1_BASE+SAM_UART_SR_OFFSET) +# define SAM_UART1_RHR (SAM_UART1_BASE+SAM_UART_RHR_OFFSET) +# define SAM_UART1_THR (SAM_UART1_BASE+SAM_UART_THR_OFFSET) +# define SAM_UART1_BRGR (SAM_UART1_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART1_CMPR (SAM_UART1_BASE+SAM_UART_CMPR_OFFSET) +#endif + +#if SAMV7_NUART > 2 +# define SAM_UART2_CR (SAM_UART2_BASE+SAM_UART_CR_OFFSET) +# define SAM_UART2_MR (SAM_UART2_BASE+SAM_UART_MR_OFFSET) +# define SAM_UART2_IER (SAM_UART2_BASE+SAM_UART_IER_OFFSET) +# define SAM_UART2_IDR (SAM_UART2_BASE+SAM_UART_IDR_OFFSET) +# define SAM_UART2_IMR (SAM_UART2_BASE+SAM_UART_IMR_OFFSET) +# define SAM_UART2_SR (SAM_UART2_BASE+SAM_UART_SR_OFFSET) +# define SAM_UART2_RHR (SAM_UART2_BASE+SAM_UART_RHR_OFFSET) +# define SAM_UART2_THR (SAM_UART2_BASE+SAM_UART_THR_OFFSET) +# define SAM_UART2_BRGR (SAM_UART2_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART2_CMPR (SAM_UART2_BASE+SAM_UART_CMPR_OFFSET) +#endif + +#if SAMV7_NUART > 3 +# define SAM_UART3_CR (SAM_UART3_BASE+SAM_UART_CR_OFFSET) +# define SAM_UART3_MR (SAM_UART3_BASE+SAM_UART_MR_OFFSET) +# define SAM_UART3_IER (SAM_UART3_BASE+SAM_UART_IER_OFFSET) +# define SAM_UART3_IDR (SAM_UART3_BASE+SAM_UART_IDR_OFFSET) +# define SAM_UART3_IMR (SAM_UART3_BASE+SAM_UART_IMR_OFFSET) +# define SAM_UART3_SR (SAM_UART3_BASE+SAM_UART_SR_OFFSET) +# define SAM_UART3_RHR (SAM_UART3_BASE+SAM_UART_RHR_OFFSET) +# define SAM_UART3_THR (SAM_UART3_BASE+SAM_UART_THR_OFFSET) +# define SAM_UART3_BRGR (SAM_UART3_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART3_CMPR (SAM_UART3_BASE+SAM_UART_CMPR_OFFSET) +#endif + +#if SAMV7_NUART > 4 +# define SAM_UART4_CR (SAM_UART4_BASE+SAM_UART_CR_OFFSET) +# define SAM_UART4_MR (SAM_UART4_BASE+SAM_UART_MR_OFFSET) +# define SAM_UART4_IER (SAM_UART4_BASE+SAM_UART_IER_OFFSET) +# define SAM_UART4_IDR (SAM_UART4_BASE+SAM_UART_IDR_OFFSET) +# define SAM_UART4_IMR (SAM_UART4_BASE+SAM_UART_IMR_OFFSET) +# define SAM_UART4_SR (SAM_UART4_BASE+SAM_UART_SR_OFFSET) +# define SAM_UART4_RHR (SAM_UART4_BASE+SAM_UART_RHR_OFFSET) +# define SAM_UART4_THR (SAM_UART4_BASE+SAM_UART_THR_OFFSET) +# define SAM_UART4_BRGR (SAM_UART4_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_UART4_CMPR (SAM_UART4_BASE+SAM_UART_CMPR_OFFSET) +#endif + +#if SAMV7_NUSART > 0 +# define SAM_USART0_CR (SAM_USART0_BASE+SAM_UART_CR_OFFSET) +# define SAM_USART0_MR (SAM_USART0_BASE+SAM_UART_MR_OFFSET) +# define SAM_USART0_IER (SAM_USART0_BASE+SAM_UART_IER_OFFSET) +# define SAM_USART0_IDR (SAM_USART0_BASE+SAM_UART_IDR_OFFSET) +# define SAM_USART0_IMR (SAM_USART0_BASE+SAM_UART_IMR_OFFSET) +# define SAM_USART0_SR (SAM_USART0_BASE+SAM_UART_SR_OFFSET) +# define SAM_USART0_RHR (SAM_USART0_BASE+SAM_UART_RHR_OFFSET) +# define SAM_USART0_THR (SAM_USART0_BASE+SAM_UART_THR_OFFSET) +# define SAM_USART0_BRGR (SAM_USART0_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART0_RTOR (SAM_USART0_BASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART0_TTGR (SAM_USART0_BASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART0_IFR (SAM_USART0_BASE+SAM_UART_IFR_OFFSET) +# define SAM_USART0_MAN (SAM_USART0_BASE+SAM_UART_MAN_OFFSET) +# define SAM_USART0_LINMR (SAM_USART0_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART0_LINIR (SAM_USART0_BASE+SAM_UART_LINIR_OFFSET) +# define SAM_USART0_LINBRR (SAM_USART0_BASE+SAM_UART_LINBRR_OFFSET) +# define SAM_USART0_LONMR (SAM_USART0_BASE+SAM_UART_LONMR_OFFSET) +# define SAM_USART0_LONPR (SAM_USART0_BASE+SAM_UART_LONPR_OFFSET) +# define SAM_USART0_LONDL (SAM_USART0_BASE+SAM_UART_LONDL_OFFSET) +# define SAM_USART0_LONL2HDR (SAM_USART0_BASE+SAM_UART_LONL2HDR_OFFSET) +# define SAM_USART0_LONBL (SAM_USART0_BASE+SAM_UART_LONBL_OFFSET) +# define SAM_USART0_LONB1TX (SAM_USART0_BASE+SAM_UART_LONB1TX_OFFSET) +# define SAM_USART0_LONB1RX (SAM_USART0_BASE+SAM_UART_LONB1RX_OFFSET) +# define SAM_USART0_LONPRIO (SAM_USART0_BASE+SAM_UART_LONPRIO_OFFSET) +# define SAM_USART0_IDTTX (SAM_USART0_BASE+SAM_UART_IDTTX_OFFSET) +# define SAM_USART0_IDTRX (SAM_USART0_BASE+SAM_UART_IDTRX_OFFSET) +# define SAM_USART0_ICDIFF (SAM_USART0_BASE+SAM_UART_ICDIFF_OFFSET) +# define SAM_USART0_WPMR (SAM_USART0_BASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART0_WPSR (SAM_USART0_BASE+SAM_UART_WPSR_OFFSET) +#endif + +#if SAMV7_NUSART > 1 +# define SAM_USART1_CR (SAM_USART1_BASE+SAM_UART_CR_OFFSET) +# define SAM_USART1_MR (SAM_USART1_BASE+SAM_UART_MR_OFFSET) +# define SAM_USART1_IER (SAM_USART1_BASE+SAM_UART_IER_OFFSET) +# define SAM_USART1_IDR (SAM_USART1_BASE+SAM_UART_IDR_OFFSET) +# define SAM_USART1_IMR (SAM_USART1_BASE+SAM_UART_IMR_OFFSET) +# define SAM_USART1_SR (SAM_USART1_BASE+SAM_UART_SR_OFFSET) +# define SAM_USART1_RHR (SAM_USART1_BASE+SAM_UART_RHR_OFFSET) +# define SAM_USART1_THR (SAM_USART1_BASE+SAM_UART_THR_OFFSET) +# define SAM_USART1_BRGR (SAM_USART1_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART1_RTOR (SAM_USART1_BASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART1_TTGR (SAM_USART1_BASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART1_IFR (SAM_USART1_BASE+SAM_UART_IFR_OFFSET) +# define SAM_USART1_MAN (SAM_USART1_BASE+SAM_UART_MAN_OFFSET) +# define SAM_USART1_LINMR (SAM_USART1_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART1_LINIR (SAM_USART1_BASE+SAM_UART_LINIR_OFFSET) +# define SAM_USART1_LINBRR (SAM_USART1_BASE+SAM_UART_LINBRR_OFFSET) +# define SAM_USART1_LONMR (SAM_USART1_BASE+SAM_UART_LONMR_OFFSET) +# define SAM_USART1_LONPR (SAM_USART1_BASE+SAM_UART_LONPR_OFFSET) +# define SAM_USART1_LONDL (SAM_USART1_BASE+SAM_UART_LONDL_OFFSET) +# define SAM_USART1_LONL2HDR (SAM_USART1_BASE+SAM_UART_LONL2HDR_OFFSET) +# define SAM_USART1_LONBL (SAM_USART1_BASE+SAM_UART_LONBL_OFFSET) +# define SAM_USART1_LONB1TX (SAM_USART1_BASE+SAM_UART_LONB1TX_OFFSET) +# define SAM_USART1_LONB1RX (SAM_USART1_BASE+SAM_UART_LONB1RX_OFFSET) +# define SAM_USART1_LONPRIO (SAM_USART1_BASE+SAM_UART_LONPRIO_OFFSET) +# define SAM_USART1_IDTTX (SAM_USART1_BASE+SAM_UART_IDTTX_OFFSET) +# define SAM_USART1_IDTRX (SAM_USART1_BASE+SAM_UART_IDTRX_OFFSET) +# define SAM_USART1_ICDIFF (SAM_USART1_BASE+SAM_UART_ICDIFF_OFFSET) +# define SAM_USART1_WPMR (SAM_USART1_BASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART1_WPSR (SAM_USART1_BASE+SAM_UART_WPSR_OFFSET) +#endif + +#if SAMV7_NUSART > 2 +# define SAM_USART2_CR (SAM_USART2_BASE+SAM_UART_CR_OFFSET) +# define SAM_USART2_MR (SAM_USART2_BASE+SAM_UART_MR_OFFSET) +# define SAM_USART2_IER (SAM_USART2_BASE+SAM_UART_IER_OFFSET) +# define SAM_USART2_IDR (SAM_USART2_BASE+SAM_UART_IDR_OFFSET) +# define SAM_USART2_IMR (SAM_USART2_BASE+SAM_UART_IMR_OFFSET) +# define SAM_USART2_SR (SAM_USART2_BASE+SAM_UART_SR_OFFSET) +# define SAM_USART2_RHR (SAM_USART2_BASE+SAM_UART_RHR_OFFSET) +# define SAM_USART2_THR (SAM_USART2_BASE+SAM_UART_THR_OFFSET) +# define SAM_USART2_BRGR (SAM_USART2_BASE+SAM_UART_BRGR_OFFSET) +# define SAM_USART2_RTOR (SAM_USART2_BASE+SAM_UART_RTOR_OFFSET) +# define SAM_USART2_TTGR (SAM_USART2_BASE+SAM_UART_TTGR_OFFSET) +# define SAM_USART2_IFR (SAM_USART2_BASE+SAM_UART_IFR_OFFSET) +# define SAM_USART2_MAN (SAM_USART2_BASE+SAM_UART_MAN_OFFSET) +# define SAM_USART2_LINMR (SAM_USART2_BASE+SAM_UART_LINMR_OFFSET) +# define SAM_USART2_LINIR (SAM_USART2_BASE+SAM_UART_LINIR_OFFSET) +# define SAM_USART2_LINBRR (SAM_USART2_BASE+SAM_UART_LINBRR_OFFSET) +# define SAM_USART2_LONMR (SAM_USART2_BASE+SAM_UART_LONMR_OFFSET) +# define SAM_USART2_LONPR (SAM_USART2_BASE+SAM_UART_LONPR_OFFSET) +# define SAM_USART2_LONDL (SAM_USART2_BASE+SAM_UART_LONDL_OFFSET) +# define SAM_USART2_LONL2HDR (SAM_USART2_BASE+SAM_UART_LONL2HDR_OFFSET) +# define SAM_USART2_LONBL (SAM_USART2_BASE+SAM_UART_LONBL_OFFSET) +# define SAM_USART2_LONB1TX (SAM_USART2_BASE+SAM_UART_LONB1TX_OFFSET) +# define SAM_USART2_LONB1RX (SAM_USART2_BASE+SAM_UART_LONB1RX_OFFSET) +# define SAM_USART2_LONPRIO (SAM_USART2_BASE+SAM_UART_LONPRIO_OFFSET) +# define SAM_USART2_IDTTX (SAM_USART2_BASE+SAM_UART_IDTTX_OFFSET) +# define SAM_USART2_IDTRX (SAM_USART2_BASE+SAM_UART_IDTRX_OFFSET) +# define SAM_USART2_ICDIFF (SAM_USART2_BASE+SAM_UART_ICDIFF_OFFSET) +# define SAM_USART2_WPMR (SAM_USART2_BASE+SAM_UART_WPMR_OFFSET) +# define SAM_USART2_WPSR (SAM_USART2_BASE+SAM_UART_WPSR_OFFSET) +#endif + +/* UART register bit definitions ****************************************************************/ + +/* UART Control Register */ + +#define UART_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver (Common) */ +#define UART_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter (Common) */ +#define UART_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable (Common) */ +#define UART_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable (Common) */ +#define UART_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable (Common) */ +#define UART_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable (Common) */ +#define UART_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits (Common, not SPI mode) */ +#define UART_CR_STTBRK (1 << 9) /* Bit 9: Start Break (USART, UART mode only) */ +#define UART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break (USART, UART mode only) */ +#define UART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out (USART, UART mode only) */ +#define UART_CR_REQCLR (1 << 12) /* Bit 12:Request Clear (UART only) */ +#define UART_CR_SENDA (1 << 12) /* Bit 12: Send Address (USART, UART mode only) */ +#define UART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out (USART, UART mode only) */ +#define UART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable (USART, UART mode only) */ +#define UART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select (USART, SPI mode only) */ +#define UART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable (USART, UART mode only) */ +#define UART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select (USART, SPI mode only) */ +#define UART_CR_LINABT (1 << 20) /* Bit 20: Abort LIN Transmission (USART, LIN mode only) */ +#define UART_CR_LINWKUP (1 << 21) /* Bit 21: Send LIN Wakeup Signal (USART, LIN mode only) */ + +/* UART Mode Register and USART Mode Register (UART MODE) */ + +#define UART_MR_MODE_SHIFT (0) /* Bits 0-3: (USART only) */ +#define UART_MR_MODE_MASK (15 << UART_MR_MODE_SHIFT) +# define UART_MR_MODE_NORMAL (0 << UART_MR_MODE_SHIFT) /* Normal */ +# define UART_MR_MODE_RS485 (1 << UART_MR_MODE_SHIFT) /* RS485 */ +# define UART_MR_MODE_HWHS (2 << UART_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define UART_MR_MODE_LON (9 << UART_MR_MODE_SHIFT) /* LON */ +# define UART_MR_MODE_SPIMSTR (14 << UART_MR_MODE_SHIFT) /* SPI Master (SPI mode only) */ +# define UART_MR_MODE_SPISLV (15 << UART_MR_MODE_SHIFT) /* SPI Slave (SPI mode only) */ +#define UART_MR_DFILTER (1 << 4) /* Bit 4: Receiver Digital Filter (UART only) */ +#define UART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection (USART only) */ +#define UART_MR_USCLKS_MASK (3 << UART_MR_USCLKS_SHIFT) +# define UART_MR_USCLKS_MCK (0 << UART_MR_USCLKS_SHIFT) /* MCK */ +# define UART_MR_USCLKS_MCKDIV (1 << UART_MR_USCLKS_SHIFT) /* MCK/DIV (DIV = 8) */ +# define UART_MR_USCLKS_PCK (2 << UART_MR_USCLKS_SHIFT) /* PMC programmable clock (PCK), UART mode */ +# define UART_MR_USCLKS_SCK (3 << UART_MR_USCLKS_SHIFT) /* SCK */ +#define UART_MR_CHRL_SHIFT (6) /* Bits 6-7: Character Length (USART only) */ +#define UART_MR_CHRL_MASK (3 << UART_MR_CHRL_SHIFT) +# define UART_MR_CHRL_5BITS (0 << UART_MR_CHRL_SHIFT) /* 5 bits), UART mode only */ +# define UART_MR_CHRL_6BITS (1 << UART_MR_CHRL_SHIFT) /* 6 bits), UART mode only */ +# define UART_MR_CHRL_7BITS (2 << UART_MR_CHRL_SHIFT) /* 7 bits), UART mode only */ +# define UART_MR_CHRL_8BITS (3 << UART_MR_CHRL_SHIFT) /* 8 bits */ +#define UART_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select (USART, UART mode only) */ +#define UART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase (USART, SPI mode only) */ +#define UART_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type (Common, UART mode) */ +#define UART_MR_PAR_MASK (7 << UART_MR_PAR_SHIFT) +# define UART_MR_PAR_EVEN (0 << UART_MR_PAR_SHIFT) /* Even parity (Common) */ +# define UART_MR_PAR_ODD (1 << UART_MR_PAR_SHIFT) /* Odd parity (Common) */ +# define UART_MR_PAR_SPACE (2 << UART_MR_PAR_SHIFT) /* Space: parity forced to 0 (Common) */ +# define UART_MR_PAR_MARK (3 << UART_MR_PAR_SHIFT) /* Mark: parity forced to 1 (Common) */ +# define UART_MR_PAR_NONE (4 << UART_MR_PAR_SHIFT) /* No parity (Common) */ +# define UART_MR_PAR_MULTIDROP (6 << UART_MR_PAR_SHIFT) /* Multidrop mode (USART only) */ +#define UART_MR_BRSRCCK (1 << 12) /* Bit 12: Baud Rate Source Clock (UART only) */ +#define UART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits (USART, UART mode only) */ +#define UART_MR_NBSTOP_MASK (3 << UART_MR_NBSTOP_SHIFT) +# define UART_MR_NBSTOP_1 (0 << UART_MR_NBSTOP_SHIFT) /* 1 stop bit 1 stop bit */ +# define UART_MR_NBSTOP_1p5 (1 << UART_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define UART_MR_NBSTOP_2 (2 << UART_MR_NBSTOP_SHIFT) /* 2 stop bits 2 stop bits */ +#define UART_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode (Common, UART mode) */ +#define UART_MR_CHMODE_MASK (3 << UART_MR_CHMODE_SHIFT) +# define UART_MR_CHMODE_NORMAL (0 << UART_MR_CHMODE_SHIFT) /* Normal Mode */ +# define UART_MR_CHMODE_ECHO (1 << UART_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define UART_MR_CHMODE_LLPBK (2 << UART_MR_CHMODE_SHIFT) /* Local Loopback */ +# define UART_MR_CHMODE_RLPBK (3 << UART_MR_CHMODE_SHIFT) /* Remote Loopback */ +#define UART_MR_MSBF (1 << 16) /* Bit 16: Most Significant Bit first (USART, UART mode only) */ +#define UART_MR_CPOL (1 << 16) /* Bit 16: SPI Clock Polarity (USART, SPI mode only) */ +#define UART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length (USART, UART mode only) */ +#define UART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select (USART only) */ +#define UART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode (USART, UART mode only) */ +#define UART_MR_WRDBT (1 << 20) /* Bit 20: Wait Read Data Before Transfer (USART, SPI mode only) */ +#define UART_MR_VARSYNC (1 << 22) /* Bit 22: Variable Synchronization of Command/Data Sync Start Frame Delimiter (USART, UART mode only) */ +#define UART_MR_IRFILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter (USART only) */ +#define UART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable (USART only) */ +#define UART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode (USART only) */ +#define UART_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector (USART only) */ + +/* UART Interrupt Enable Register, UART Interrupt Disable Register, UART Interrupt Mask + * Register, and UART Status Register common bit field definitions + */ + +#define UART_INT_RXRDY (1 << 0) /* Bit 0: RXRDY Interrupt (Common) */ +#define UART_INT_TXRDY (1 << 1) /* Bit 1: TXRDY Interrupt (Common) */ +#define UART_INT_RXBRK (1 << 2) /* Bit 2: Break Received/End of Break (USART, UART mode only) */ +#define UART_INT_OVRE (1 << 5) /* Bit 5: Overrun Error Interrupt (Common) */ +#define UART_INT_FRAME (1 << 6) /* Bit 6: Framing Error Interrupt (Common, UART mode) */ +#define UART_INT_LSF (1 << 6) /* Bit 6: LON Short Frame Error Interrupt Enablee (USART, LON mode only) */ +#define UART_INT_PARE (1 << 7) /* Bit 7: Parity Error Interrupt (Common, UART mode) */ +#define UART_INT_LCRCE (1 << 7) /* Bit 7: LON CRC Error Interrupt Enablee (USART, LON mode only) */ +#define UART_INT_TIMEOUT (1 << 8) /* Bit 8: Time-out Interrupt (USART, UART mode only) */ +#define UART_INT_TXEMPTY (1 << 9) /* Bit 9: TXEMPTY Interrupt (Common) */ +#define UART_INT_UNRE (1 << 10) /* Bit 10: SPI Underrun Error Interrupt (USART SPI mode only) */ +#define UART_INT_LINBK (1 << 13) /* Bit 13: LIN Break Sent or Break Received Interrupt (USART, LIN mode only) */ +#define UART_INT_LINID (1 << 14) /* Bit 14: LIN Identifier Sent or Identifier Received Interrupt (USART, LIN mode only) */ +#define UART_INT_CMP (1 << 15) /* Bit 15: Enable Comparison Interrupt (UART only) */ +#define UART_INT_LINTC (1 << 15) /* Bit 15: LIN Transfer Completed Interrupt (USART, LIN mode only) */ +#define UART_INT_CTSIC (1 << 19) /* Bit 19: Clear to Send Input Change Interrupt (USART, UART mode only) */ +#define UART_INT_MANE (1 << 24) /* Bit 24: Manchester Error Interrupt (USART. UART mode only) */ +#define UART_INT_LTXD (1 << 24) /* Bit 24: LON Transmission Done Interrupt Enable (USART, LON mode only) */ +#define UART_INT_LINBE (1 << 25) /* Bit 25: LIN Bus Error Interrupt (USART, LIN mode only)*/ +#define UART_INT_LCOL (1 << 25) /* Bit 25: LON Collision Interrupt Enable (USART, LON mode only) */ +#define UART_INT_LINISFE (1 << 26) /* Bit 26: LIN Inconsistent Synch Field Error Interrupt (USART, LIN mode only) */ +#define UART_INT_LFET (1 << 26) /* Bit 26: LON Frame Early Termination Interrupt Enable (USART, LON mode only) */ +#define UART_INT_LINIPE (1 << 27) /* Bit 27: LIN Identifier Parity Interrupt (USART, LIN mode only) */ +#define UART_INT_LRXD (1 << 27) /* Bit 27: LON Reception Done Interrupt Enable (USART, LON mode only) */ +#define UART_INT_LINCE (1 << 28) /* Bit 28: LIN Checksum Error Interrupt (USART, LIN mode only) */ +#define UART_INT_LBLOVFE (1 << 28) /* Bit 28: LON Backlog Overflow Error Interrupt Enable (USART, LON mode only) */ +#define UART_INT_LINSNRE (1 << 29) /* Bit 29: LIN Slave Not Responding Error Interrupt (USART, LIN mode only) */ + +#define UART_INT_ALLINTS 0x3f08e7e7 + +/* UART Receiver Holding Register */ + +#if 0 +# define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-7: Received Character (UART only) */ +# define UART_RHR_RXCHR_MASK (0xff << UART_RHR_RXCHR_SHIFT) +#endif +#define UART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character (USART only) */ +#define UART_RHR_RXCHR_MASK (0x1ff << UART_RHR_RXCHR_SHIFT) +#define UART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync (USART only) */ + +/* UART Transmit Holding Register */ + +#if 0 +# define UART_THR_TXCHR_SHIFT (0) /* Bits 0-7: Character to be Transmitted (UART only) */ +# define UART_THR_TXCHR_MASK (0xff << UART_THR_TXCHR_SHIFT) +#endif +#define UART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted (USART only) */ +#define UART_THR_TXCHR_MASK (0x1ff << UART_THR_TXCHR_SHIFT) +#define UART_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be tran (USART only) */ + +/* UART Baud Rate Generator Register */ + +#define UART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor (Common) */ +#define UART_BRGR_CD_MASK (0xffff << UART_BRGR_CD_SHIFT) +# define UART_BRGR_CD(n) ((uint32_t)(n) << UART_BRGR_CD_SHIFT) +#define UART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part (USART only) */ +#define UART_BRGR_FP_MASK (7 << UART_BRGR_FP_SHIFT) +# define UART_BRGR_FP(n) ((uint32_t)(n) << UART_BRGR_FP_SHIFT) + +/* Comparison Register (UART only) */ + +#define UART_CMPR_VAL1_SHIFT (0) /* Bits 0-7: First Comparison Value for Received Character */ +#define UART_CMPR_VAL1_MASK (0xff << UART_CMPR_VAL1_SHIFT) +# define UART_CMPR_VAL1(n) ((uint32_t)(n) << UART_CMPR_VAL1_SHIFT) +#define UART_CMPR_CMPMODE (1 << 12) /* Bit 12: Comparison Mode */ +#define UART_CMPR_CMPPAR (1 << 14) /* Bit 14: Compare Parity */ +#define UART_CMPR_VAL2_SHIFT (16) /* Bits 16-23: Second Comparison Value for Received Character */ +#define UART_CMPR_VAL2_MASK (0xff << UART_CMPR_VAL2_SHIFT0 +# define UART_CMPR_VAL2(n) ((uint32_t)(n) << UART_CMPR_VAL2_SHIFT0 + +/* USART Receiver Time-out Register (USART only) */ + +#define UART_RTOR_TO_SHIFT (0) /* Bits 0-16: Time-out Value (USART only) */ +#define UART_RTOR_TO_MASK (0x1ffff << UART_RTOR_TO_SHIFT) + +/* USART Transmitter Timeguard Register (USART only) */ + +#define UART_TTGR_TG_SHIFT (0) /* Bits 0-7: Timeguard Value (USART only) */ +#define UART_TTGR_TG_MASK (0xff << UART_TTGR_TG_SHIFT) + +#define UART_TTGR_PCYCLE_SHIFT (0) /* Bits 0-23: LON PCYCLE Length (USART, LON mode only) */ +#define UART_TTGR_PCYCLE_MASK (0xffffff << UART_TTGR_PCYCLE_SHIFT) + +/* USART FI DI RATIO Register (LON_MODE) + * REVISIT: In the preliminary datasheet, these bit fields are identified, but there no no + * defined address for the FIDL register. + */ + +#define UART_FIDL_BETA2_SHIFT (0) /* Bits 0-23: LON BETA2 Length (USART, LON mode only) */ +#define UART_FIDL_BETA2_MASK (0xffffff << UART_FIDL_BETA2_SHIFT) + +/* USART Manchester Configuration Register (USART only) */ + +#define UART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length (USART only) */ +#define UART_MAN_TXPL_MASK (15 << UART_MAN_TXPL_SHIFT) +# define UART_MAN_TXPL(n) ((uint32_t)(n) << UART_MAN_TXPL_SHIFT) +#define UART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern (USART only) */ +#define UART_MAN_TXPP_MASK (3 << UART_MAN_TXPP_SHIFT) +# define UART_MAN_TXPP_ALLONE (0 << UART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_TXPP_ALLZERO (1 << UART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_TXPP_ZEROONE (2 << UART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_TXPP_ONEZERO (3 << UART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity (USART only) */ +#define UART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length (USART only) */ +#define UART_MAN_RXPL_MASK (15 << UART_MAN_RXPL_SHIFT) +# define UART_MAN_RXPL(n) ((uint32_t)(n) << UART_MAN_RXPL_SHIFT) +#define UART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected (USART only) */ +#define UART_MAN_RXPP_MASK (3 << UART_MAN_RXPP_SHIFT) +# define UART_MAN_RXPP_ALLONE (0 << UART_MAN_RXPP_SHIFT) /* ALL_ONE */ +# define UART_MAN_RXPP_ALLZERO (1 << UART_MAN_RXPP_SHIFT) /* ALL_ZERO */ +# define UART_MAN_RXPP_ZEROONE (2 << UART_MAN_RXPP_SHIFT) /* ZERO_ONE */ +# define UART_MAN_RXPP_ONEZERO (3 << UART_MAN_RXPP_SHIFT) /* ONE_ZERO */ +#define UART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity (USART only) */ +#define UART_MAN_ONE (1 << 29) /* Bit 29: Must Be Set to 1 */ +#define UART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation (USART only) */ +#define UART_MAN_RXIDLEV (1 << 31) /* Bit 31: Receiver Idle Value */ + +/* LIN Mode Register (USART only) */ + +#define UART_LINMR_NACT_SHIFT (0) /* Bits 0-1: LIN Node Action */ +#define UART_LINMR_NACT_MASK (3 << UART_LINMR_NACT_SHIFT) +# define UART_LINMR_NACT_PUBLISH (0 << UART_LINMR_NACT_SHIFT) /* USART transmits response */ +# define UART_LINMR_NACT_SUBSCRIBE (1 << UART_LINMR_NACT_SHIFT) /* USART receives response */ +# define UART_LINMR_NACT_IGNORE (2 << UART_LINMR_NACT_SHIFT) /* USART does not transmit or receive response */ +#define UART_LINMR_PARDIS (1 << 2) /* Bit 2: Parity Disable */ +#define UART_LINMR_CHKDIS (1 << 3) /* Bit 3: Checksum Disable */ +#define UART_LINMR_CHKTYP (1 << 4) /* Bit 4: Checksum Type */ +#define UART_LINMR_DLM (1 << 5) /* Bit 5: Data Length Mode */ +#define UART_LINMR_FSDIS (1 << 6) /* Bit 6: Frame Slot Mode Disable */ +#define UART_LINMR_WKUPTYP (1 << 7) /* Bit 7: Wakeup Signal Type */ +#define UART_LINMR_DLC_SHIFT (8) /* Bits 8-15: Data Length Control */ +#define UART_LINMR_DLC_MASK (0xff << UART_LINMR_DLC_SHIFT) +# define UART_LINMR_DLC(n) ((uint32_t)(n) << UART_LINMR_DLC_SHIFT) +#define UART_LINMR_PDCM (1 << 16) /* Bit 16: PDC Mode */ + +/* LIN Identifier Register (USART only) */ + +#define UART_LINIR_MASK 0xff /* Bits 0-7: Identifier Character */ + +/* LIN Baud Rate Register (USART only) */ + +#define UART_LINBRR_LINCD_SHIFT (0) /* Bits 0-15: Clock Divider after Synchronization */ +#define UART_LINBRR_LINCD_MASK (0xffff << UART_LINBRR_LINCD_SHIFT) +# define UART_LINBRR_LINCD(n) ((uint32_t)(n) << UART_LINBRR_LINCD_SHIFT) +#define UART_LINBRR_LINFP_SHIFT (16) /* Bits 16-18: Fractional Part after Synchronization */ +#define UART_LINBRR_LINFP_MASK (7 << UART_LINBRR_LINFP_SHIFT) +# define UART_LINBRR_LINFP(n) ((uint32_t)(n) << UART_LINBRR_LINFP_SHIFT) + +/* LON Mode Register (USART only) */ + +#define UART_LONMR_COMMT (1 << 0) /* Bit 0: LON comm_type Parameter Value */ +#define UART_LONMR_COLDET (1 << 1) /* Bit 1: LON Collision Detection Feature */ +#define UART_LONMR_TCOL (1 << 2) /* Bit 2: Terminate Frame upon Collision Notification */ +#define UART_LONMR_CDTAIL (1 << 3) /* Bit 3: LON Collision Detection on Frame Tail */ +#define UART_LONMR_DMAM (1 << 4) /* Bit 4: LON DMA Mode */ +#define UART_LONMR_LCDS (1 << 5) /* Bit 5: LON Collision Detection Source */ +#define UART_LONMR_EOFS_SHIFT (16) /* Bits 16-23: End of Frame Condition Size */ +#define UART_LONMR_EOFS_MASK (0xff << UART_LONMR_EOFS_SHIFT) +# define UART_LONMR_EOFS(n) ((uint32_t)(n) << UART_LONMR_EOFS_SHIFT) + +/* LON Preamble Register (USART only) */ + +#define UART_LONPR_MASK 0x0000ffff /* Bits 0-15-LON preamble length */ + +/* LON Data Length Register (USART only) */ + +#define UART_LONDL_MASK 0x000000ff /* Bits 0-7: LON data length */ + +/* LON L2HDR Register (USART only) */ + +#define UART_LONL2HDR_BLI_SHIFT (0) /* Bits 0-5: LON Backlog Increment */ +#define UART_LONL2HDR_BLI_MASK (63 << UART_LONL2HDR_BLI_SHIFT) +# define UART_LONL2HDR_BLI(n) ((uint32_t)(n) << UART_LONL2HDR_BLI_SHIFT) +#define UART_LONL2HDR_ALTP (1 << 6) /* Bit 6: LON Alternate Path Bit */ +#define UART_LONL2HDR_PB (1 << 7) /* Bit 7: LON Priority Bit */ + +/* LON Backlog Register (USART only) */ + +#define UART_LONLBL_MASK 0x0000003f /* Bits 0-5: LON Backlog Value */ + +/* LON Beta1 Tx Register (USART only) */ + +#define UART_LONB1TX_MASK 0x00ffffff /* Bits 0-23: LON Beta1 Length after Transmission */ + +/* LON Beta1 Rx Register (USART only) */ + +#define UART_LONB1RX_MASK 0x00ffffff /* Bits 0-23: LON Beta1 Length after Reception */ + +/* LON Priority Register (USART only) */ + +#define UART_LONPRIO_PSNB_SHIFT (0) /* Bits 0-6: LON Priority Slot Number */ +#define UART_LONPRIO_PSNB_MASK (0x7f << UART_LONPRIO_PSNB_SHIFT) +# define UART_LONPRIO_PSNB(n) ((uint32_t)(n) << UART_LONPRIO_PSNB_SHIFT) +#define UART_LONPRIO_NPS_SHIFT (8) /* Bits 8-14: LON Node Priority Slot */ +#define UART_LONPRIO_NPS_MASK (0x7f << UART_LONPRIO_NPS_SHIFT) +# define UART_LONPRIO_NPS(n) ((uint32_t)(n) << UART_LONPRIO_NPS_SHIFT) + +/* LON IDT Tx Register (USART only) */ + +#define UART_IDTTX_MASK 0x00ffffff /* Bits 0-23: LON Indeterminate Time after Transmission */ + +/* LON IDT Rx Register (USART only) */ + +#define UART_IDTRX_MASK 0x00ffffff /* Bits 0-23: LON Indeterminate Time after Reception */ + +/* IC DIFF Registe (USART only) */ + +#define UART_ICDIFF_MASK 0x0000000f /* Bit 0-3: IC Differentiator Number */ + +/* USART Write Protect Mode Register (USART only) */ + +#define UART_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable (USART only) */ +#define UART_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY (USART only) */ +#define UART_WPMR_WPKEY_MASK (0x00ffffff << UART_WPMR_WPKEY_SHIFT) +# define UART_WPMR_WPKEY (0x00554152 << UART_WPMR_WPKEY_SHIFT) +# define USART_WPMR_WPKEY (0x00555341 << UART_WPMR_WPKEY_SHIFT) + +/* USART Write Protect Status Register (USART only) */ + +#define UART_WPSR_WPVS (1 << 0) /* Bit 0: Write Protect Violation Status (USART only) */ +#define UART_WPSR_WPVSRC_SHIFT (8) /* Bits 8-23: Write Protect Violation Source (USART only) */ +#define UART_WPSR_WPVSRC_MASK (0xffff << UART_WPSR_WPVSRC_SHIFT) + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +/************************************************************************************************ + * Public Data + ************************************************************************************************/ + +/************************************************************************************************ + * Public Functions + ************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UART_H */ diff --git a/arch/arm/src/samv7/chip/sam_usbhs.h b/arch/arm/src/samv7/chip/sam_usbhs.h new file mode 100644 index 0000000000000000000000000000000000000000..04c9c4db511a5e02b22127be43a88b27df18eec3 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_usbhs.h @@ -0,0 +1,805 @@ +/************************************************************************************************************ + * arch/arm/src/samv7/chip/sam_usbhs.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMV7D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_USBHS_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_USBHS_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ +/* General Definitions **************************************************************************************/ +/* Number of endpoints and DMA channels */ + +#define SAM_USBHS_NENDPOINTS 10 /* EP0-9 */ +#define SAM_USBHS_NDMACHANNELS 7 /* For DMA1-7 */ + +/* Capabilities and characteristics of endpoints */ + +#define SAM_USBHS_MAXPACKETSIZE(ep) (((unsigned)(ep) < 1) ? 64 : 1024) +#define SAM_USBHS_NBANKS(ep) (((unsigned)(ep) < 1) ? 1 : (((unsigned)(ep) < 3) ? 3 : 2)) +#define SAM_USBHS_DMA(ep) (((unsigned)(ep) < 1) ? false : (((unsigned)(ep) < 8) ? true : false)) + +/* Register offsets *****************************************************************************************/ +/* USBHS Device Controller Register Offsets */ + +#define SAM_USBHS_DEVCTRL_OFFSET 0x0000 /* Device General Control Register */ +#define SAM_USBHS_DEVISR_OFFSET 0x0004 /* Device Global Interrupt Status Register */ +#define SAM_USBHS_DEVICR_OFFSET 0x0008 /* Device Global Interrupt Clear Register */ +#define SAM_USBHS_DEVIFR_OFFSET 0x000c /* Device Global Interrupt Set Register */ +#define SAM_USBHS_DEVIMR_OFFSET 0x0010 /* Device Global Interrupt Mask Register */ +#define SAM_USBHS_DEVIDR_OFFSET 0x0014 /* Device Global Interrupt Disable Register */ +#define SAM_USBHS_DEVIER_OFFSET 0x0018 /* Device Global Interrupt Enable Register */ +#define SAM_USBHS_DEVEPT_OFFSET 0x001c /* Device Endpoint Register */ +#define SAM_USBHS_DEVFNUM_OFFSET 0x0020 /* Device Frame Number Register */ + +#define SAM_USBHS_DEVEPTCFG_OFFSET(n) (0x0100+((n)<<2)) /* Device Endpoint Configuration Register */ +#define SAM_USBHS_DEVEPTISR_OFFSET(n) (0x0130+((n)<<2)) /* Device Endpoint Status Register */ +#define SAM_USBHS_DEVEPTICR_OFFSET(n) (0x0160+((n)<<2)) /* Device Endpoint Clear Register */ +#define SAM_USBHS_DEVEPTIFR_OFFSET(n) (0x0190+((n)<<2)) /* Device Endpoint Set Register */ +#define SAM_USBHS_DEVEPTIMR_OFFSET(n) (0x01c0+((n)<<2)) /* Device Endpoint Mask Register */ +#define SAM_USBHS_DEVEPTIER_OFFSET(n) (0x01f0+((n)<<2)) /* Device Endpoint Enable Register */ +#define SAM_USBHS_DEVEPTIDR_OFFSET(n) (0x0220+((n)<<2)) /* Device Endpoint Disable Register */ + +#define SAM_USBHS_DEVDMANXTDSC_OFFSET(n) (0x0300+((n)<<4)) /* Device DMA Channel Next Descriptor Address Register */ +#define SAM_USBHS_DEVDMAADDR_OFFSET(n) (0x0304+((n)<<4)) /* Device DMA Channel Address Register */ +#define SAM_USBHS_DEVDMACTRL_OFFSET(n) (0x0308+((n)<<4)) /* Device DMA Channel Control Register */ +#define SAM_USBHS_DEVDMASTA_OFFSET(n) (0x030c+((n)<<4)) /* Device DMA Channel Status Register */ + +/* USBHS Mini-Host Controller Register Offsets */ + +#define SAM_USBHS_HSTCTRL_OFFSET 0x0400 /* Host General Control Register */ +#define SAM_USBHS_HSTISR_OFFSET 0x0404 /* Host Global Interrupt Status Register */ +#define SAM_USBHS_HSTICR_OFFSET 0x0408 /* Host Global Interrupt Clear Register */ +#define SAM_USBHS_HSTIFR_OFFSET 0x040c /* Host Global Interrupt Set Register */ +#define SAM_USBHS_HSTIMR_OFFSET 0x0410 /* Host Global Interrupt Mask Register */ +#define SAM_USBHS_HSTIDR_OFFSET 0x0414 /* Host Global Interrupt Disable Register */ +#define SAM_USBHS_HSTIER_OFFSET 0x0418 /* Host Global Interrupt Enable Register */ +#define SAM_USBHS_HSTPIP_OFFSET 0x041c /* Host Pipe Register */ +#define SAM_USBHS_HSTFNUM_OFFSET 0x0420 /* Host Frame Number Register */ +#define SAM_USBHS_HSTADDR1_OFFSET 0x0424 /* Host Address 1 Register */ +#define SAM_USBHS_HSTADDR2_OFFSET 0x0428 /* Host Address 2 Register */ +#define SAM_USBHS_HSTADDR3_OFFSET 0x042c /* Host Address 3 Register */ + +#define SAM_USBHS_HSTPIPCFG_OFFSET(n) (0x0500+((n)<<2)) /* Host Pipe Configuration Register */ +#define SAM_USBHS_HSTPIPISR_OFFSET(n) (0x0530+((n)<<2)) /* Host Pipe Status Register */ +#define SAM_USBHS_HSTPIPICR_OFFSET(n) (0x0560+((n)<<2)) /* Host Pipe Clear Register */ +#define SAM_USBHS_HSTPIPIFR_OFFSET(n) (0x0590+((n)<<2)) /* Host Pipe Set Register */ +#define SAM_USBHS_HSTPIPIMR_OFFSET(n) (0x05c0+((n)<<2)) /* Host Pipe Mask Register */ +#define SAM_USBHS_HSTPIPIER_OFFSET(n) (0x05f0+((n)<<2)) /* Host Pipe Enable Register */ +#define SAM_USBHS_HSTPIPIDR_OFFSET(n) (0x0620+((n)<<2)) /* Host Pipe Disable Register */ +#define SAM_USBHS_HSTPIPINRQ_OFFSET(n) (0x0650+((n)<<2)) /* Host Pipe IN Request Register */ +#define SAM_USBHS_HSTPIPERR_OFFSET(n) (0x0680+((n)<<2)) /* Host Pipe Error Register */ + +#define SAM_USBHS_HSTDMANXTDSC_OFFSET(n) (0x0700+((n)<<4)) /* Host DMA Channel Next Descriptor Address Register */ +#define SAM_USBHS_HSTDMAADDR_OFFSET(n) (0x0704+((n)<<4)) /* Host DMA Channel Address Register */ +#define SAM_USBHS_HSTDMACTRL_OFFSET(n) (0x0708+((n)<<4)) /* Host DMA Channel Control Register */ +#define SAM_USBHS_HSTDMASTA_OFFSET(n) (0x070c+((n)<<4)) /* Host DMA Channel Status Register */ + +/* USBHS General Register Offsets */ + +#define SAM_USBHS_CTRL_OFFSET 0x0800 /* General Control Register */ +#define SAM_USBHS_SR_OFFSET 0x0804 /* General Status Register */ +#define SAM_USBHS_SCR_OFFSET 0x0808 /* General Status Clear Register */ +#define SAM_USBHS_SFR_OFFSET 0x080c /* General Status Set Register */ + /* 0x0810-0x082c: Reserved */ + +/* Register addresses ***************************************************************************************/ + +/* USBHS Device Controller Register Addresses */ + +#define SAM_USBHS_DEVCTRL (SAM_USBHS_BASE+SAM_USBHS_DEVCTRL_OFFSET) +#define SAM_USBHS_DEVISR (SAM_USBHS_BASE+SAM_USBHS_DEVISR_OFFSET) +#define SAM_USBHS_DEVICR (SAM_USBHS_BASE+SAM_USBHS_DEVICR_OFFSET) +#define SAM_USBHS_DEVIFR (SAM_USBHS_BASE+SAM_USBHS_DEVIFR_OFFSET) +#define SAM_USBHS_DEVIMR (SAM_USBHS_BASE+SAM_USBHS_DEVIMR_OFFSET) +#define SAM_USBHS_DEVIDR (SAM_USBHS_BASE+SAM_USBHS_DEVIDR_OFFSET) +#define SAM_USBHS_DEVIER (SAM_USBHS_BASE+SAM_USBHS_DEVIER_OFFSET) +#define SAM_USBHS_DEVEPT (SAM_USBHS_BASE+SAM_USBHS_DEVEPT_OFFSET) +#define SAM_USBHS_DEVFNUM (SAM_USBHS_BASE+SAM_USBHS_DEVFNUM_OFFSET) + +#define SAM_USBHS_DEVEPTCFG(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTCFG_OFFSET(n)) +#define SAM_USBHS_DEVEPTISR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTISR_OFFSET(n)) +#define SAM_USBHS_DEVEPTICR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTICR_OFFSET(n)) +#define SAM_USBHS_DEVEPTIFR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTIFR_OFFSET(n)) +#define SAM_USBHS_DEVEPTIMR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTIMR_OFFSET(n)) +#define SAM_USBHS_DEVEPTIER(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTIER_OFFSET(n)) +#define SAM_USBHS_DEVEPTIDR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVEPTIDR_OFFSET(n)) + +#define SAM_USBHS_DEVDMANXTDSC(n) (SAM_USBHS_BASE+SAM_USBHS_DEVDMANXTDSC_OFFSET(n)) +#define SAM_USBHS_DEVDMAADDR(n) (SAM_USBHS_BASE+SAM_USBHS_DEVDMAADDR_OFFSET(n)) +#define SAM_USBHS_DEVDMACTRL(n) (SAM_USBHS_BASE+SAM_USBHS_DEVDMACTRL_OFFSET(n)) +#define SAM_USBHS_DEVDMASTA(n) (SAM_USBHS_BASE+SAM_USBHS_DEVDMASTA_OFFSET(n)) + +/* USBHS Mini-Host Controller Register Addresses */ + +#define SAM_USBHS_HSTCTRL (SAM_USBHS_BASE+SAM_USBHS_HSTCTRL_OFFSET) +#define SAM_USBHS_HSTISR (SAM_USBHS_BASE+SAM_USBHS_HSTISR_OFFSET) +#define SAM_USBHS_HSTICR (SAM_USBHS_BASE+SAM_USBHS_HSTICR_OFFSET) +#define SAM_USBHS_HSTIFR (SAM_USBHS_BASE+SAM_USBHS_HSTIFR_OFFSET) +#define SAM_USBHS_HSTIMR (SAM_USBHS_BASE+SAM_USBHS_HSTIMR_OFFSET) +#define SAM_USBHS_HSTIDR (SAM_USBHS_BASE+SAM_USBHS_HSTIDR_OFFSET) +#define SAM_USBHS_HSTIER (SAM_USBHS_BASE+SAM_USBHS_HSTIER_OFFSET) +#define SAM_USBHS_HSTPIP (SAM_USBHS_BASE+SAM_USBHS_HSTPIP_OFFSET) +#define SAM_USBHS_HSTFNUM (SAM_USBHS_BASE+SAM_USBHS_HSTFNUM_OFFSET) +#define SAM_USBHS_HSTADDR1 (SAM_USBHS_BASE+SAM_USBHS_HSTADDR1_OFFSET) +#define SAM_USBHS_HSTADDR2 (SAM_USBHS_BASE+SAM_USBHS_HSTADDR2_OFFSET) +#define SAM_USBHS_HSTADDR3 (SAM_USBHS_BASE+SAM_USBHS_HSTADDR3_OFFSET) + +#define SAM_USBHS_HSTPIPCFG(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPCFG_OFFSET(n)) +#define SAM_USBHS_HSTPIPISR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPISR_OFFSET(n)) +#define SAM_USBHS_HSTPIPICR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPICR_OFFSET(n)) +#define SAM_USBHS_HSTPIPIFR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPIFR_OFFSET(n)) +#define SAM_USBHS_HSTPIPIMR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPIMR_OFFSET(n)) +#define SAM_USBHS_HSTPIPIER(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPIER_OFFSET(n)) +#define SAM_USBHS_HSTPIPIDR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPIDR_OFFSET(n)) +#define SAM_USBHS_HSTPIPINRQ(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPINRQ_OFFSET(n)) +#define SAM_USBHS_HSTPIPERR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTPIPERR_OFFSET(n)) + +#define SAM_USBHS_HSTDMANXTDSC(n) (SAM_USBHS_BASE+SAM_USBHS_HSTDMANXTDSC_OFFSET(n)) +#define SAM_USBHS_HSTDMAADDR(n) (SAM_USBHS_BASE+SAM_USBHS_HSTDMAADDR_OFFSET(n)) +#define SAM_USBHS_HSTDMACTRL(n) (SAM_USBHS_BASE+SAM_USBHS_HSTDMACTRL_OFFSET(n)) +#define SAM_USBHS_HSTDMASTA(n) (SAM_USBHS_BASE+SAM_USBHS_HSTDMASTA_OFFSET(n) + +/* USBHS General Register Addresses */ + +#define SAM_USBHS_CTRL (SAM_USBHS_BASE+SAM_USBHS_CTRL_OFFSET) +#define SAM_USBHS_SR (SAM_USBHS_BASE+SAM_USBHS_SR_OFFSET) +#define SAM_USBHS_SCR (SAM_USBHS_BASE+SAM_USBHS_SCR_OFFSET) +#define SAM_USBHS_SFR (SAM_USBHS_BASE+SAM_USBHS_SFR_OFFSET) + +/* Register bit-field definitions ***************************************************************************/ + +/* USBHS Device Controller Register Bit Field Definitions */ +/* Device General Control Register */ + +#define USBHS_DEVCTRL_UADD_SHIFT (0) /* Bits 0-6: USBHS Address */ +#define USBHS_DEVCTRL_UADD_MASK (0x7f << USBHS_DEVCTRL_UADD_SHIFT) +# define USBHS_DEVCTRL_UADD(n) ((n) << USBHS_DEVCTRL_UADD_SHIFT) +#define USBHS_DEVCTRL_ADDEN (1 << 7) /* Bit 7: Function Address Enable */ +#define USBHS_DEVCTRL_DETACH (1 << 8) /* Bit 8: Detach Command */ +#define USBHS_DEVCTRL_RMWKUP (1 << 9) /* Bit 9: Send Remote Wake Up */ +#define USBHS_DEVCTRL_SPDCONF_SHIFT (10) /* Bits 10-11: Mode Configuration */ +#define USBHS_DEVCTRL_SPDCONF_MASK (3 << USBHS_DEVCTRL_SPDCONF_SHIFT) +# define USBHS_DEVCTRL_SPDCONF_NORMAL (0 << USBHS_DEVCTRL_SPDCONF_SHIFT) +# define USBHS_DEVCTRL_SPDCONF_LOWPOWER (1 << USBHS_DEVCTRL_SPDCONF_SHIFT) +#define USBHS_DEVCTRL_LS (1 << 12) /* Bit 12: Low-Speed Mode Force */ +#define USBHS_DEVCTRL_TSTJ (1 << 13) /* Bit 13: Test mode J */ +#define USBHS_DEVCTRL_TSTK (1 << 14) /* Bit 14: Test mode K */ +#define USBHS_DEVCTRL_TSTPCKT (1 << 15) /* Bit 15: Test packet mode */ +#define USBHS_DEVCTRL_OPMODE2 (1 << 16) /* Bit 16: Specific Operational mode */ + +/* Device Global Interrupt Status Register + * Device Global Interrupt Clear Register + * Device Global Interrupt Set Register + * Device Global Interrupt Mask Register + * Device Global Interrupt Disable Register + * Device Global Interrupt Enable Register + * + * (1) Not clear or set registers + * (2) Not clear register + */ + +#define USBHS_DEVINT_SUSPD (1 << 0) /* Bit 0: Suspend Interrupt */ +#define USBHS_DEVINT_MSOF (1 << 1) /* Bit 1: Micro Start Of Frame Interrupt */ +#define USBHS_DEVINT_SOF (1 << 2) /* Bit 2: Start Of Frame Interrupt */ +#define USBHS_DEVINT_EORST (1 << 3) /* Bit 3: End Of Reset Interrupt */ +#define USBHS_DEVINT_WAKEUP (1 << 4) /* Bit 4: Wake Up CPU Interrupt */ +#define USBHS_DEVINT_EORSM (1 << 5) /* Bit 5: End Of Resume Interrupt */ +#define USBHS_DEVINT_UPRSM (1 << 6) /* Bit 6: Upstream Resume Interrupt */ +#define USBHS_DEVINT_PEP_SHIFT (12) /* Bits 12-23: Endpoint interrupts (1) */ +#define USBHS_DEVINT_PEP_MASK (0xfff << USBHS_DEVINT_PEP_SHIFT) +# define USBHS_DEVINT_PEP(n) (1 << ((n)+12)) /* Endpoint n Interrupt, n=0-11 (1) */ +# define USBHS_DEVINT_PEP0 (1 << 12) /* Bit 12: Endpoint 0 Interrupt (1) */ +# define USBHS_DEVINT_PEP1 (1 << 13) /* Bit 13: Endpoint 1 Interrupt (1) */ +# define USBHS_DEVINT_PEP2 (1 << 14) /* Bit 14: Endpoint 2 Interrupt (1) */ +# define USBHS_DEVINT_PEP3 (1 << 15) /* Bit 15: Endpoint 3 Interrupt (1) */ +# define USBHS_DEVINT_PEP4 (1 << 16) /* Bit 16: Endpoint 4 Interrupt (1) */ +# define USBHS_DEVINT_PEP5 (1 << 17) /* Bit 17: Endpoint 5 Interrupt (1) */ +# define USBHS_DEVINT_PEP6 (1 << 18) /* Bit 18: Endpoint 6 Interrupt (1) */ +# define USBHS_DEVINT_PEP7 (1 << 19) /* Bit 19: Endpoint 7 Interrupt (1) */ +# define USBHS_DEVINT_PEP8 (1 << 20) /* Bit 20: Endpoint 8 Interrupt (1) */ +# define USBHS_DEVINT_PEP9 (1 << 21) /* Bit 21: Endpoint 9 Interrupt (1) */ +# define USBHS_DEVINT_PEP10 (1 << 22) /* Bit 22: Endpoint 10 Interrupt (1) */ +# define USBHS_DEVINT_PEP11 (1 << 23) /* Bit 23: Endpoint 11 Interrupt (1) */ +#define USBHS_DEVINT_DMA_SHIFT (25) /* Bits 25-31: DMA channel interrupts (2) */ +#define USBHS_DEVINT_DMA_MASK (0x7f << USBHS_DEVINT_DMA_SHIFT) +#define USBHS_DEVINT_DMA(n) (1 << ((n)+24)) /* DMA Channel n Interrupt, n=1-7 (2) */ +# define USBHS_DEVINT_DMA1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt (2) */ +# define USBHS_DEVINT_DMA2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt (2) */ +# define USBHS_DEVINT_DMA3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt (2) */ +# define USBHS_DEVINT_DMA4 (1 << 28) /* Bit 28: DMA Channel 4 Interrupt (2) */ +# define USBHS_DEVINT_DMA5 (1 << 29) /* Bit 29: DMA Channel 5 Interrupt (2) */ +# define USBHS_DEVINT_DMA6 (1 << 30) /* Bit 30: DMA Channel 6 Interrupt (2) */ +# define USBHS_DEVINT_DMA7 (1 << 31) /* Bit 31: DMA Channel 7 Interrupt (2) */ + +#define USBHS_DEVINT_ALL 0xfefff07f + +/* Device Endpoint Register */ + +#define USBHS_DEVEPT_EPEN(n) (1 << ((n))) /* Endpoint n Enable */ +# define USBHS_DEVEPT_EPEN0 (1 << 0) /* Bit 0: Endpoint 0 Enable */ +# define USBHS_DEVEPT_EPEN1 (1 << 1) /* Bit 1: Endpoint 1 Enable */ +# define USBHS_DEVEPT_EPEN2 (1 << 2) /* Bit 2: Endpoint 2 Enable */ +# define USBHS_DEVEPT_EPEN3 (1 << 3) /* Bit 3: Endpoint 3 Enable */ +# define USBHS_DEVEPT_EPEN4 (1 << 4) /* Bit 4: Endpoint 4 Enable */ +# define USBHS_DEVEPT_EPEN5 (1 << 5) /* Bit 5: Endpoint 5 Enable */ +# define USBHS_DEVEPT_EPEN6 (1 << 6) /* Bit 6: Endpoint 6 Enable */ +# define USBHS_DEVEPT_EPEN7 (1 << 7) /* Bit 7: Endpoint 7 Enable */ +# define USBHS_DEVEPT_EPEN8 (1 << 8) /* Bit 8: Endpoint 8 Enable */ +# define USBHS_DEVEPT_EPEN9 (1 << 9) /* Bit 9: Endpoint 9 Enable */ +# define USBHS_DEVEPT_ALLEPEN 0x000003ff +#define USBHS_DEVEPT_EPRST(n) (1 << ((n)+16)) /* Endpoint n Reset */ +# define USBHS_DEVEPT_EPRST0 (1 << 16) /* Bit 16: Endpoint 0 Reset */ +# define USBHS_DEVEPT_EPRST1 (1 << 17) /* Bit 17: Endpoint 1 Reset */ +# define USBHS_DEVEPT_EPRST2 (1 << 18) /* Bit 18: Endpoint 2 Reset */ +# define USBHS_DEVEPT_EPRST3 (1 << 19) /* Bit 19: Endpoint 3 Reset */ +# define USBHS_DEVEPT_EPRST4 (1 << 20) /* Bit 20: Endpoint 4 Reset */ +# define USBHS_DEVEPT_EPRST5 (1 << 21) /* Bit 21: Endpoint 5 Reset */ +# define USBHS_DEVEPT_EPRST6 (1 << 22) /* Bit 22: Endpoint 6 Reset */ +# define USBHS_DEVEPT_EPRST7 (1 << 23) /* Bit 23: Endpoint 7 Reset */ +# define USBHS_DEVEPT_EPRST8 (1 << 24) /* Bit 24: Endpoint 8 Reset */ +# define USBHS_DEVEPT_EPRST9 (1 << 25) /* Bit 25: Endpoint 9 Reset */ +# define USBHS_DEVEPT_ALLEPRST 0x03ff0000 + +/* Device Frame Number Register */ + +#define USBHS_DEVFNUM_MFNUM_SHIFT (0) /* Bits 0-2: Microframe Number */ +#define USBHS_DEVFNUM_MFNUM_MASK (7 << USBHS_DEVFNUM_MFNUM_SHIFT) +#define USBHS_DEVFNUM_FNUM_SHIFT (3) /* Bits 3-13: Frame Number */ +#define USBHS_DEVFNUM_FNUM_MASK (0x7ff << USBHS_DEVFNUM_FNUM_SHIFT) +#define USBHS_DEVFNUM_FNCERR (1 << 15) /* Bit 15: Frame Number CRC Error */ + +/* Device Endpoint Configuration Register */ + +#define USBHS_DEVEPTCFG_ALLOC (1 << 1) /* Bit 1: Endpoint Memory Allocate */ +#define USBHS_DEVEPTCFG_EPBK_SHIFT (2) /* Bits 2-3: Endpoint Banks */ +#define USBHS_DEVEPTCFG_EPBK_MASK (3 << USBHS_DEVEPTCFG_EPBK_SHIFT) +# define USBHS_DEVEPTCFG_EPBK(n) ((uint32_t)((n)-1) << USBHS_DEVEPTCFG_EPBK_SHIFT) +# define USBHS_DEVEPTCFG_EPBK_1BANK (0 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Single-bank endpoint */ +# define USBHS_DEVEPTCFG_EPBK_2BANK (1 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Double-bank endpoint */ +# define USBHS_DEVEPTCFG_EPBK_3BANK (2 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Triple-bank endpoint */ +#define USBHS_DEVEPTCFG_EPSIZE_SHIFT (4) /* Bits 4-6: Endpoint Size */ +#define USBHS_DEVEPTCFG_EPSIZE_MASK (7 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) +# define USBHS_DEVEPTCFG_EPSIZE_8 (0 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 8 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_16 (1 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 16 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_32 (2 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 32 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_64 (3 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 64 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_128 (4 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 128 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_256 (5 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 256 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_512 (6 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 512 bytes */ +# define USBHS_DEVEPTCFG_EPSIZE_1024 (7 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 1024 bytes */ +#define USBHS_DEVEPTCFG_EPDIR_SHIFT (8) /* Bit 8: Endpoint Direction */ +#define USBHS_DEVEPTCFG_EPDIR_MASK (1 << 8) /* Bit 8: Endpoint Direction */ +# define USBHS_DEVEPTCFG_EPDIR(n) ((uint32_t)(n) << 8) +#define USBHS_DEVEPTCFG_AUTOSW (1 << 9) /* Bit 9: Automatic Switch */ +#define USBHS_DEVEPTCFG_EPTYPE_SHIFT (11) /* Bits 11-12: Endpoint Type */ +#define USBHS_DEVEPTCFG_EPTYPE_MASK (3 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) +# define USBHS_DEVEPTCFG_EPTYPE(n) ((uint32_t)(n) << USBHS_DEVEPTCFG_EPTYPE_SHIFT) +# define USBHS_DEVEPTCFG_EPTYPE_CTRL (0 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Control endpoint */ +# define USBHS_DEVEPTCFG_EPTYPE_ISO (1 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Isochronous endpoint */ +# define USBHS_DEVEPTCFG_EPTYPE_BLK (2 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Bulk endpoint */ +# define USBHS_DEVEPTCFG_EPTYPE_INTRPT (3 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Interrupt endpoint */ +#define USBHS_DEVEPTCFG_NBTRANS_SHIFT (13) /* Bits 13-14: Number Transaction per uframe */ +#define USBHS_DEVEPTCFG_NBTRANS_MASK (3 << USBHS_DEVEPTCFG_NBTRANS_SHIFT) +# define USBHS_DEVEPTCFG_NBTRANS(n) ((uint32_t)(n) << USBHS_DEVEPTCFG_NBTRANS_SHIFT) + +/* Common Endpoint Interrupt Bit Definitions + * + * Device Endpoint Status Register + * Device Endpoint Clear Register + * Device Endpoint Set Register + * Device Endpoint Mask Register + * Device Endpoint Enable Register + * + * (1) Control, Bulk, Interrupt endpoints + * (2) Isochronous endpoints only + */ + +#define USBHS_DEVEPTINT_TXINI (1 << 0) /* Bit 0: Transmitted IN Data Interrupt */ +#define USBHS_DEVEPTINT_RXOUTI (1 << 1) /* Bit 1: Received OUT Data Interrupt */ +#define USBHS_DEVEPTINT_RXSTPI (1 << 2) /* Bit 2: Received SETUP Interrupt (2) */ +#define USBHS_DEVEPTINT_UNDERFI (1 << 2) /* Bit 2: Underflow Interrupt (3) */ +#define USBHS_DEVEPTINT_NAKOUTI (1 << 3) /* Bit 3: NAKed OUT Interrupt (2) */ +#define USBHS_DEVEPTINT_HBISOINERRI (1 << 3) /* Bit 3: High Bandwidth Isochronous IN Underflow Error Interrupt (3) */ +#define USBHS_DEVEPTINT_NAKINI (1 << 4) /* Bit 4: NAKed IN Interrupt (2) */ +#define USBHS_DEVEPTINT_HBISOFLUSHI (1 << 4) /* Bit 4: High Bandwidth Isochronous IN Flush Interrupt (3) */ +#define USBHS_DEVEPTINT_OVERFI (1 << 5) /* Bit 5: Overflow Interrupt */ +#define USBHS_DEVEPTINT_STALLEDI (1 << 6) /* Bit 6: STALLed Interrupt (2) */ +#define USBHS_DEVEPTINT_CRCERRI (1 << 6) /* Bit 6: CRC Error Interrupt (3) */ +#define USBHS_DEVEPTINT_SHRTPCKTI (1 << 7) /* Bit 7: Short Packet Interrupt */ + +/* Device Endpoint Mask, Device Endpoint Disable, and Device Endpoint Enable Registers only */ + +#define USBHS_DEVEPTINT_MDATAI (1 << 8) /* Bit 8: MData Interrupt (2) */ +#define USBHS_DEVEPTINT_DATAXI (1 << 9) /* Bit 9: DataX Interrupt (2) */ +#define USBHS_DEVEPTINT_ERRORTRANSI (1 << 10) /* Bit 10: Transaction Error Interrupt (2) */ + +/* Device Endpoint Set, Device Endpoint Mask, Device Endpoint Disable, and Device Endpoint Enable + * Registers only + */ + +#define USBHS_DEVEPTINT_NBUSYBKI (1 << 12) /* Bit 12: Number of Busy Banks Interrupt */ + +/* Device Endpoint Mask and Device Endpoint Enable Registers only */ + +#define USBHS_DEVEPTINT_KILLBKI (1 << 13) /* Bit 13: Kill IN Bank */ + +/* Device Endpoint Mask, Device Endpoint Disable, and Device Endpoint Enable Registers only */ + +#define USBHS_DEVEPTINT_FIFOCONI (1 << 14) /* Bit 14: FIFO Control */ +#define USBHS_DEVEPTINT_EPDISHDMAI (1 << 16) /* Bit 16: Endpoint Interrupts Disable HDMA Request */ +#define USBHS_DEVEPTINT_NYETDISI (1 << 17) /* Bit 17: NYET Token Disable (1) */ +#define USBHS_DEVEPTINT_RSTDTI (1 << 18) /* Bit 18: Reset Data Toggle */ +#define USBHS_DEVEPTINT_STALLRQI (1 << 19) /* Bit 19: STALL Request (1) */ + +#define USBHS_DEVEPTICR_ALLINTS 0x000000ff +#define USBHS_DEVEPTIFR_ALLINTS 0x000010ff +#define USBHS_DEVEPTIDR_ALLINTS 0x000d57ff +#define USBHS_DEVEPTIER_ALLINTS 0x000f77ff + +/* Device Endpoint Status Register only */ + +#define USBHS_DEVEPTISR_DTSEQ_SHIFT (8) /* Bits 8-9: Data Toggle Sequence */ +#define USBHS_DEVEPTISR_DTSEQ_MASK (3 << USBHS_DEVEPTISR_DTSEQ_SHIFT) +# define USBHS_DEVEPTISR_DTSEQ_DATA0 (0 << USBHS_DEVEPTISR_DTSEQ_SHIFT) /* Data0 toggle sequence */ +# define USBHS_DEVEPTISR_DTSEQ_DATA1 (1 << USBHS_DEVEPTISR_DTSEQ_SHIFT) /* Data1 toggle sequence */ +# define USBHS_DEVEPTISR_DTSEQ_DATA2 (2 << USBHS_DEVEPTISR_DTSEQ_SHIFT) /* Data1 toggle sequence (2) */ +# define USBHS_DEVEPTISR_DTSEQ_MDATA (3 << USBHS_DEVEPTISR_DTSEQ_SHIFT) /* MData toggle sequence (2) */ +#define USBHS_DEVEPTISR_ERRORTRANS (1 << 10) /* Bit 10: High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt (2) */ +#define USBHS_DEVEPTISR_NBUSYBK_SHIFT (12) /* Bits 12-13: Number of Busy Banks */ +#define USBHS_DEVEPTISR_NBUSYBK_MASK (3 << USBHS_DEVEPTISR_NBUSYBK_SHIFT) +# define USBHS_DEVEPTISR_NBUSYBK_0BUSY (0 << USBHS_DEVEPTISR_NBUSYBK_SHIFT) /* 0 busy bank (all banks free) */ +# define USBHS_DEVEPTISR_NBUSYBK_1BUSY (1 << USBHS_DEVEPTISR_NBUSYBK_SHIFT) /* 1 busy bank */ +# define USBHS_DEVEPTISR_NBUSYBK_2BUSY (2 << USBHS_DEVEPTISR_NBUSYBK_SHIFT) /* 2 busy banks */ +# define USBHS_DEVEPTISR_NBUSYBK_3BUSY (3 << USBHS_DEVEPTISR_NBUSYBK_SHIFT) /* 3 busy banks */ +#define USBHS_DEVEPTISR_CURRBK_SHIFT (14) /* Bits 14-15: Current Bank */ +#define USBHS_DEVEPTISR_CURRBK_MASK (3 << USBHS_DEVEPTISR_CURRBK_SHIFT) +# define USBHS_DEVEPTISR_CURRBK_BANK0 (0 << USBHS_DEVEPTISR_CURRBK_SHIFT) /* Current bank is bank0 */ +# define USBHS_DEVEPTISR_CURRBK_BANK1 (1 << USBHS_DEVEPTISR_CURRBK_SHIFT) /* Current bank is bank1 */ +# define USBHS_DEVEPTISR_CURRBK_BANK2 (2 << USBHS_DEVEPTISR_CURRBK_SHIFT) /* Current bank is bank2 */ +#define USBHS_DEVEPTISR_RWALL (1 << 16) /* Bit 16: Read/Write Allowed */ +#define USBHS_DEVEPTISR_CTRLDIR (1 << 17) /* Bit 17: Control Direction (1) */ +# define USBHS_DEVEPTISR_CTRLDIR_OUT (0 << 17) /* 0=Following packet is an OUT packet */ +# define USBHS_DEVEPTISR_CTRLDIR_IN (1 << 17) /* 1=Following packet is an IN packet */ +#define USBHS_DEVEPTISR_CFGOK (1 << 18) /* Bit 18: Configuration OK Status */ +#define USBHS_DEVEPTISR_BYCT_SHIFT (20) /* Bits 20-30: USBHS Byte Count */ +#define USBHS_DEVEPTISR_BYCT_MASK (0x7ff << USBHS_DEVEPTISR_BYCT_SHIFT) + +/* Device DMA Channel Next Descriptor Address Register (32-bit, 16 byte aligned address) */ +/* Device DMA Channel Address Register (32-bit address) */ + +/* Device DMA Channel Control Register */ + +#define USBHS_DEVDMACTRL_CMD_SHIFT (0) /* Bits 0-1: Command */ +#define USBHS_DEVDMACTRL_CMD_MASK (3 << USBHS_DEVDMACTRL_CMD_SHIFT) +# define USBHS_DEVDMACTRL_CHANNENB (1 << 0) /* Bit 0: Channel Enable Command */ +# define USBHS_DEVDMACTRL_LDNXTDSC (1 << 1) /* Bit 1: Load Next Channel Transfer Descriptor Enable Command */ +# define USBHS_DEVDMACTRL_STOPNOW (0 << USBHS_DEVDMACTRL_CMD_SHIFT) /* Stop now */ +# define USBHS_DEVDMACTRL_RUNSTOP (1 << USBHS_DEVDMACTRL_CMD_SHIFT) /* Run and stop at end of buffer */ +# define USBHS_DEVDMACTRL_LOADNEXT (2 << USBHS_DEVDMACTRL_CMD_SHIFT) /* Load next descriptor now */ +# define USBHS_DEVDMACTRL_RUNLINK (3 << USBHS_DEVDMACTRL_CMD_SHIFT) /* Run and link at end of buffer */ +#define USBHS_DEVDMACTRL_ENDTREN (1 << 2) /* Bit 2: End of Transfer Enable Control */ +#define USBHS_DEVDMACTRL_ENDBEN (1 << 3) /* Bit 3: End of Buffer Enable Control */ +#define USBHS_DEVDMACTRL_ENDTRIT (1 << 4) /* Bit 4: End of Transfer Interrupt Enable */ +#define USBHS_DEVDMACTRL_ENDBUFFIT (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define USBHS_DEVDMACTRL_DESCLDIT (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enable */ +#define USBHS_DEVDMACTRL_BURSTLCK (1 << 7) /* Bit 7: Burst Lock Enable */ +#define USBHS_DEVDMACTRL_BUFLEN_SHIFT (16) /* Bits 16-31: Buffer Byte Length */ +#define USBHS_DEVDMACTRL_BUFLEN_MASK (0xffff << USBHS_DEVDMACTRL_BUFLEN_SHIFT) +# define USBHS_DEVDMACTRL_BUFLEN(n) ((uint32_t)(n) << USBHS_DEVDMACTRL_BUFLEN_SHIFT) + +/* Device DMA Channel Status Register */ + +#define USBHS_DEVDMASTA_CHANNENB (1 << 0) /* Bit 0: Channel Enable Status */ +#define USBHS_DEVDMASTA_CHANNACT (1 << 1) /* Bit 1: Channel Active Status */ +#define USBHS_DEVDMASTA_ENDTRST (1 << 4) /* Bit 4: End of Transfer Status */ +#define USBHS_DEVDMASTA_ENDBUFFST (1 << 5) /* Bit 5: End of Buffer Status */ +#define USBHS_DEVDMASTA_DESCLDST (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define USBHS_DEVDMASTA_BUFCNT_SHIFT (16) /* Bits 16-31: Buffer Byte Count */ +#define USBHS_DEVDMASTA_BUFCNT_MASK (0xffff << USBHS_DEVDMASTA_BUFCNT_SHIFT) +# define USBHS_DEVDMASTA_BUFCNT(n) ((uint32_t)(n) << USBHS_DEVDMASTA_BUFCNT_SHIFT) + +/* USBHS Mini-Host Controller Register Bit Field Definitions */ +/* Host General Control Register */ + +#define USBHS_HSTCTRL_SOFE (1 << 8) /* Bit 8: Start of Frame Generation Enable */ +#define USBHS_HSTCTRL_RESET (1 << 9) /* Bit 9: Send USB Reset */ +#define USBHS_HSTCTRL_RESUME (1 << 10) /* Bit 10: Send USB Resume */ +#define USBHS_HSTCTRL_SPDCONF (12) /* Bits 12-13: Mode Configuration */ +#define USBHS_HSTCTRL_MASK (3 << USBHS_HSTCTRL_SPDCONF) +# define USBHS_HSTCTRL_NORMAL (0 << USBHS_HSTCTRL_SPDCONF) +# define USBHS_HSTCTRL_LOWPOWER (1 << USBHS_HSTCTRL_SPDCONF) + +/* Host Global Interrupt Status Register + * Host Global Interrupt Clear Register + * Host Global Interrupt Set Register + * Host Global Interrupt Mask Register + * Host Global Interrupt Disable Register + * Host Global Interrupt Enable Register + * + * (1) Not clear or set registers + * (2) Not clear register + */ + +#define USBHS_HSTINT_DCONNI (1 << 0) /* Bit 0: Device Connection Interrupt */ +#define USBHS_HSTINT_DDISCI (1 << 1) /* Bit 1: Device Disconnection Interrupt */ +#define USBHS_HSTINT_RSTI (1 << 2) /* Bit 2: USB Reset Sent Interrupt */ +#define USBHS_HSTINT_RSMEDI (1 << 3) /* Bit 3: Downstream Resume Sent Interrupt */ +#define USBHS_HSTINT_RXRSMI (1 << 4) /* Bit 4: Upstream Resume Received Interrupt */ +#define USBHS_HSTINT_HSOFI (1 << 5) /* Bit 5: Host Start of Frame Interrupt */ +#define USBHS_HSTINT_HWUPI (1 << 6) /* Bit 6: Host Wake-Up Interrupt */ +#define USBHS_HSTINT_PEP_SHIFT (12) /* Bits 12-23: Pipe interrupts (1) */ +#define USBHS_HSTINT_PEP_MASK (0xfff << USBHS_HSTINT_PEP_SHIFT) +# define USBHS_HSTINT_PEP(n) (1 << +((n)+12)) /* Pipe n Interrupt, n=0-11 (1) */ +# define USBHS_HSTINT_PEP0 (1 << 12) /* Bit 12: Pipe 0 Interrupt (1) */ +# define USBHS_HSTINT_PEP1 (1 << 13) /* Bit 13: Pipe 1 Interrupt (1) */ +# define USBHS_HSTINT_PEP2 (1 << 14) /* Bit 14: Pipe 2 Interrupt (1) */ +# define USBHS_HSTINT_PEP3 (1 << 15) /* Bit 15: Pipe 3 Interrupt (1) */ +# define USBHS_HSTINT_PEP4 (1 << 16) /* Bit 16: Pipe 4 Interrupt (1) */ +# define USBHS_HSTINT_PEP5 (1 << 17) /* Bit 17: Pipe 5 Interrupt (1) */ +# define USBHS_HSTINT_PEP6 (1 << 18) /* Bit 18: Pipe 6 Interrupt (1) */ +# define USBHS_HSTINT_PEP7 (1 << 19) /* Bit 19: Pipe 7 Interrupt (1) */ +# define USBHS_HSTINT_PEP8 (1 << 20) /* Bit 20: Pipe 8 Interrupt (1) */ +# define USBHS_HSTINT_PEP9 (1 << 21) /* Bit 21: Pipe 9 Interrupt (1) */ +# define USBHS_HSTINT_PEP10 (1 << 22) /* Bit 22: Pipe 10 Interrupt (1) */ +# define USBHS_HSTINT_PEP11 (1 << 23) /* Bit 23: Pipe 11 Interrupt (1) */ +#define USBHS_HSTINT_DMA_SHIFT (25) /* Bits 25-31: DMA channel interrupts (2) */ +#define USBHS_HSTINT_DMA_MASK (0x7f << USBHS_HSTINT_DMA_SHIFT) +#define USBHS_HSTINT_DMA(n) (1 << ((n)+24)) /* DMA Channel n Interrupt, n=1-7 (2) */ +# define USBHS_HSTINT_DMA1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt (2) */ +# define USBHS_HSTINT_DMA2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt (2) */ +# define USBHS_HSTINT_DMA3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt (2) */ +# define USBHS_HSTINT_DMA4 (1 << 28) /* Bit 28: DMA Channel 4 Interrupt (2) */ +# define USBHS_HSTINT_DMA5 (1 << 29) /* Bit 29: DMA Channel 5 Interrupt (2) */ +# define USBHS_HSTINT_DMA6 (1 << 30) /* Bit 30: DMA Channel 6 Interrupt (2) */ +# define USBHS_HSTINT_DMA7 (1 << 31) /* Bit 31: DMA Channel 7 Interrupt (2) */ + +/* Host Pipe Register */ + +#define USBHS_HSTPIP_PEN(n) (1 << ((n))) /* Pipe n Enable */ +# define USBHS_HSTPIP_PEN0 (1 << 0) /* Bit 0: Pipe 0 Enable */ +# define USBHS_HSTPIP_PEN1 (1 << 1) /* Bit 1: Pipe 1 Enable */ +# define USBHS_HSTPIP_PEN2 (1 << 2) /* Bit 2: Pipe 2 Enable */ +# define USBHS_HSTPIP_PEN3 (1 << 3) /* Bit 3: Pipe 3 Enable */ +# define USBHS_HSTPIP_PEN4 (1 << 4) /* Bit 4: Pipe 4 Enable */ +# define USBHS_HSTPIP_PEN5 (1 << 5) /* Bit 5: Pipe 5 Enable */ +# define USBHS_HSTPIP_PEN6 (1 << 6) /* Bit 6: Pipe 6 Enable */ +# define USBHS_HSTPIP_PEN7 (1 << 7) /* Bit 7: Pipe 7 Enable */ +# define USBHS_HSTPIP_PEN8 (1 << 8) /* Bit 8: Pipe 8 Enable */ +# define USBHS_HSTPIP_PEN9 (1 << 9) /* Bit 9: Pipe 9 Enable */ +#define USBHS_HSTPIP_PRST(n) (1 << ((n)+16)) /* Pipe n Reset */ +# define USBHS_HSTPIP_PRST0 (1 << 16) /* Bit 16: Pipe 0 Reset */ +# define USBHS_HSTPIP_PRST1 (1 << 17) /* Bit 17: Pipe 1 Reset */ +# define USBHS_HSTPIP_PRST2 (1 << 18) /* Bit 18: Pipe 2 Reset */ +# define USBHS_HSTPIP_PRST3 (1 << 19) /* Bit 19: Pipe 3 Reset */ +# define USBHS_HSTPIP_PRST4 (1 << 20) /* Bit 20: Pipe 4 Reset */ +# define USBHS_HSTPIP_PRST5 (1 << 21) /* Bit 21: Pipe 5 Reset */ +# define USBHS_HSTPIP_PRST6 (1 << 22) /* Bit 22: Pipe 6 Reset */ +# define USBHS_HSTPIP_PRST7 (1 << 23) /* Bit 23: Pipe 7 Reset */ +# define USBHS_HSTPIP_PRST8 (1 << 24) /* Bit 24: Pipe 8 Reset */ +# define USBHS_HSTPIP_PRST9 (1 << 25) /* Bit 25: Pipe 9 Reset */ + +/* Host Frame Number Register */ + +#define USBHS_HSTFNUM_MFNUM_SHIFT (0) /* Bits 0-2: Microframe Number */ +#define USBHS_HSTFNUM_MFNUM_MASK (7 << USBHS_HSTFNUM_MFNUM_SHIFT) +#define USBHS_HSTFNUM_FNUM_SHIFT (3) /* Bits 3-13: Frame Number */ +#define USBHS_HSTFNUM_FNUM_MASK (0x7ff << USBHS_HSTFNUM_FNUM_SHIFT) +#define USBHS_HSTFNUM_FLENHIGH_SHIFT (16) /* Bits 16-23: Frame Length */ +#define USBHS_HSTFNUM_FLENHIGH_MASK (0xff << USBHS_HSTFNUM_FLENHIGH_SHIFT) +# define USBHS_HSTFNUM_FLENHIGH(n) ((uint32_t)(n) << USBHS_HSTFNUM_FLENHIGH_SHIFT) + +/* Host Address 1 Register */ + +#define USBHS_HSTADDR1_HSTADDRP_SHIFT(n) ((n) << 3) /* USB Host Address */ +#define USBHS_HSTADDR1_HSTADDRP_MASK(n) (0x7f << USBHS_HSTADDR1_HSTADDRP_SHIFT(n)) +# define USBHS_HSTADDR1_HSTADDRP(n,v) ((uint32_t)(v) << USBHS_HSTADDR1_HSTADDRP_SHIFT(n)) + +#define USBHS_HSTADDR1_HSTADDRP0_SHIFT (0) /* Bits 0-6: USB Host Address */ +#define USBHS_HSTADDR1_HSTADDRP0_MASK (0x7f << USBHS_HSTADDR1_HSTADDRP0_SHIFT) +# define USBHS_HSTADDR1_HSTADDRP0(n) (0x7f << USBHS_HSTADDR1_HSTADDRP0_SHIFT) +#define USBHS_HSTADDR1_HSTADDRP1_SHIFT (8) /* Bits 8-14: USB Host Address */ +#define USBHS_HSTADDR1_HSTADDRP1_MASK (0x7f << USBHS_HSTADDR1_HSTADDRP1_SHIFT) +# define USBHS_HSTADDR1_HSTADDRP1(n) ((uint32_t)(n) << USBHS_HSTADDR1_HSTADDRP1_SHIFT) +#define USBHS_HSTADDR1_HSTADDRP2_SHIFT (16) /* Bits 16-22: USB Host Address */ +#define USBHS_HSTADDR1_HSTADDRP2_MASK (0x7f << USBHS_HSTADDR1_HSTADDRP2_SHIFT) +# define USBHS_HSTADDR1_HSTADDRP2(n) ((uint32_t)(n) << USBHS_HSTADDR1_HSTADDRP2_SHIFT) +#define USBHS_HSTADDR1_HSTADDRP3_SHIFT (24) /* Bits 24-30: USB Host Address */ +#define USBHS_HSTADDR1_HSTADDRP3_MASK (0x7f << USBHS_HSTADDR1_HSTADDRP3_SHIFT) +# define USBHS_HSTADDR1_HSTADDRP3(n) ((uint32_t)(n) << USBHS_HSTADDR1_HSTADDRP3_SHIFT) + +/* Host Address 2 Register */ + +#define USBHS_HSTADDR2_HSTADDRP_SHIFT(n) (((n)-4) << 3) /* USB Host Address */ +#define USBHS_HSTADDR2_HSTADDRP_MASK(n) (0x7f << USBHS_HSTADDR2_HSTADDRP_SHIFT(n)) +# define USBHS_HSTADDR2_HSTADDRP(n,v) ((uint32_t)(v) << USBHS_HSTADDR2_HSTADDRP_SHIFT(n)) + +#define USBHS_HSTADDR2_HSTADDRP4_SHIFT (0) /* Bits 0-6: USB Host Address */ +#define USBHS_HSTADDR2_HSTADDRP4_MASK (0x7f << USBHS_HSTADDR2_HSTADDRP4_SHIFT) +# define USBHS_HSTADDR2_HSTADDRP4(n) (0x7f << USBHS_HSTADDR2_HSTADDRP4_SHIFT) +#define USBHS_HSTADDR2_HSTADDRP5_SHIFT (8) /* Bits 8-14: USB Host Address */ +#define USBHS_HSTADDR2_HSTADDRP5_MASK (0x7f << USBHS_HSTADDR2_HSTADDRP5_SHIFT) +# define USBHS_HSTADDR2_HSTADDRP5(n) ((uint32_t)(n) << USBHS_HSTADDR2_HSTADDRP5_SHIFT) +#define USBHS_HSTADDR2_HSTADDRP6_SHIFT (16) /* Bits 16-22: USB Host Address */ +#define USBHS_HSTADDR2_HSTADDRP6_MASK (0x7f << USBHS_HSTADDR2_HSTADDRP6_SHIFT) +# define USBHS_HSTADDR2_HSTADDRP6(n) ((uint32_t)(n) << USBHS_HSTADDR2_HSTADDRP6_SHIFT) +#define USBHS_HSTADDR2_HSTADDRP7_SHIFT (24) /* Bits 24-30: USB Host Address */ +#define USBHS_HSTADDR2_HSTADDRP7_MASK (0x7f << USBHS_HSTADDR2_HSTADDRP7_SHIFT) +# define USBHS_HSTADDR2_HSTADDRP7(n) ((uint32_t)(n) << USBHS_HSTADDR2_HSTADDRP7_SHIFT) + +/* Host Address 3 Register */ + +#define USBHS_HSTADDR3_HSTADDRP_SHIFT(n) (((n)-8) << 3) /* USB Host Address */ +#define USBHS_HSTADDR3_HSTADDRP_MASK(n) (0x7f << USBHS_HSTADDR3_HSTADDRP_SHIFT(n)) +# define USBHS_HSTADDR3_HSTADDRP(n,v) ((uint32_t)(v) << USBHS_HSTADDR3_HSTADDRP_SHIFT(n)) + +#define USBHS_HSTADDR3_HSTADDRP8_SHIFT (0) /* Bits 0-6: USB Host Address */ +#define USBHS_HSTADDR3_HSTADDRP8_MASK (0x7f << USBHS_HSTADDR3_HSTADDRP8_SHIFT) +# define USBHS_HSTADDR3_HSTADDRP8(n) (0x7f << USBHS_HSTADDR3_HSTADDRP8_SHIFT) +#define USBHS_HSTADDR3_HSTADDRP9_SHIFT (8) /* Bits 8-14: USB Host Address */ +#define USBHS_HSTADDR3_HSTADDRP9_MASK (0x7f << USBHS_HSTADDR3_HSTADDRP9_SHIFT) +# define USBHS_HSTADDR3_HSTADDRP9(n) ((uint32_t)(n) << USBHS_HSTADDR3_HSTADDRP9_SHIFT) + +/* Host Pipe Configuration Register + * + * (1) Not for High-Speed Bulk OUT + * (2) For High-Speed Bulk Out + */ + +#define USBHS_HSTPIPCFG_ALLOC (1 << 0) /* Bit 0: Pipe Memory Allocate */ +#define USBHS_HSTPIPCFG_PBK_SHIFT (2) /* Bits 2-3: Pipe Banks */ +#define USBHS_HSTPIPCFG_PBK_MASK (3 << USBHS_HSTPIPCFG_PBK_SHIFT) +# define USBHS_HSTPIPCFG_PBK_1BANK (0 << USBHS_HSTPIPCFG_PBK_SHIFT) /* Single-bank pipe */ +# define USBHS_HSTPIPCFG_PBK_2BANK (1 << USBHS_HSTPIPCFG_PBK_SHIFT) /* Double-bank pipe */ +# define USBHS_HSTPIPCFG_PBK_3BANK (2 << USBHS_HSTPIPCFG_PBK_SHIFT) /* Triple-bank pipe */ +#define USBHS_HSTPIPCFG_PSIZE_SHIFT (4) /* Bits 4-6: Pipe Size */ +#define USBHS_HSTPIPCFG_PSIZE_MASK (7 << USBHS_HSTPIPCFG_PSIZE_SHIFT) +# define USBHS_HSTPIPCFG_PSIZE_8 (0 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 8 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_16 (1 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 16 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_32 (2 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 32 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_64 (3 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 64 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_128 (4 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 128 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_256 (5 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 256 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_512 (6 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 512 bytes */ +# define USBHS_HSTPIPCFG_PSIZE_1024 (7 << USBHS_HSTPIPCFG_PSIZE_SHIFT) /* 1024 bytes */ +#define USBHS_HSTPIPCFG_PTOKEN_SHIFT (8) /* Bits 8-9: Pipe Token */ +#define USBHS_HSTPIPCFG_PTOKEN_MASK (3 << USBHS_HSTPIPCFG_PTOKEN_SHIFT) +# define USBHS_HSTPIPCFG_PTOKEN_SETUP (0 << USBHS_HSTPIPCFG_PTOKEN_SHIFT) +# define USBHS_HSTPIPCFG_PTOKEN_IN (1 << USBHS_HSTPIPCFG_PTOKEN_SHIFT) +# define USBHS_HSTPIPCFG_PTOKEN_OUT (2 << USBHS_HSTPIPCFG_PTOKEN_SHIFT) +#define USBHS_HSTPIPCFG_AUTOSW (1 << 10) /* Bit 10: Automatic Switch */ +#define USBHS_HSTPIPCFG_PTYPE_SHIFT (12) /* Bits 12-13: Pipe Type */ +#define USBHS_HSTPIPCFG_PTYPE_MASK (3 << USBHS_HSTPIPCFG_PTYPE_SHIFT) +# define USBHS_HSTPIPCFG_PTYPE_CTRL (0 << USBHS_HSTPIPCFG_PTYPE_SHIFT) /* Control pipe */ +# define USBHS_HSTPIPCFG_PTYPE_ISO (1 << USBHS_HSTPIPCFG_PTYPE_SHIFT) /* Isochronous pipe */ +# define USBHS_HSTPIPCFG_PTYPE_BLK (2 << USBHS_HSTPIPCFG_PTYPE_SHIFT) /* Bulk pipe */ +# define USBHS_HSTPIPCFG_PTYPE_INTRPT (3 << USBHS_HSTPIPCFG_PTYPE_SHIFT) /* Interrupt pipe */ +#define USBHS_HSTPIPCFG_PEPNUM_SHIFT (16) /* Bits 16-19: Pipe Endpoint Number */ +#define USBHS_HSTPIPCFG_PEPNUM_MASK (15 << USBHS_HSTPIPCFG_PEPNUM_SHIFT) +# define USBHS_HSTPIPCFG_PEPNUM(n) ((uint32_t)(n) << USBHS_HSTPIPCFG_PEPNUM_SHIFT) +#define USBHS_HSTPIPCFG_PINGEN (1 << 20) /* Bit 20: Ping Enable (2) */ +#define USBHS_HSTPIPCFG_INTFRQ_SHIFT (24) /* Bits 24-31: Pipe Interrupt Request Frequency (1) */ +#define USBHS_HSTPIPCFG_INTFRQ_MASK (0xff << USBHS_HSTPIPCFG_INTFRQ_SHIFT) +# define USBHS_HSTPIPCFG_INTFRQ(n) ((uint32_t)(n) << USBHS_HSTPIPCFG_INTFRQ_SHIFT) +#define USBHS_HSTPIPCFG_BINTERVAL_SHIFT (24) /* Bits 24-31: Binterval Parameter for the Bulk-Out/Ping Transaction (2) */ +#define USBHS_HSTPIPCFG_BINTERVAL_MASK (0xff << USBHS_HSTPIPCFG_BINTERVAL_SHIFT) +# define USBHS_HSTPIPCFG_BINTERVAL(n) ((uint32_t)(n) << USBHS_HSTPIPCFG_BINTERVAL_SHIFT) + +/* Common Pipe Interrupt Bit Definitions: + * + * Host Pipe Status Register + * Host Pipe Clear Register + * Host Pipe Set Register + * Host Pipe Mask Register + * Host Pipe Enable Register + * Host Pipe Disable Register + * + * (1) Control and bulk pipes + * (2) Interrupt pipes + * (3) Isochronous pipes + */ + + /* All registers */ + +#define USBHS_HSTPIPINT_RXINI (1 << 0) /* Bit 0: Received IN Data Interrupt */ +#define USBHS_HSTPIPINT_TXOUTI (1 << 1) /* Bit 1: Transmitted OUT Data Interrupt */ +#define USBHS_HSTPIPINT_TXSTPI (1 << 2) /* Bit 2: Transmitted SETUP Interrupt (1) */ +#define USBHS_HSTPIPINT_UNDERFI (1 << 2) /* Bit 2: Underflow Interrupt (2,3) */ +#define USBHS_HSTPIPINT_PERRI (1 << 3) /* Bit 3: Pipe Error Interrupt */ +#define USBHS_HSTPIPINT_NAKEDI (1 << 4) /* Bit 4: NAKed Interrupt */ +#define USBHS_HSTPIPINT_OVERFI (1 << 5) /* Bit 5: Overflow Interrupt */ +#define USBHS_HSTPIPINT_RXSTALLDI (1 << 6) /* Bit 6: Received STALLed Interrupt (1,2) */ +#define USBHS_HSTPIPINT_CRCERRI (1 << 6) /* Bit 6: CRC Error Interrupt (3) */ +#define USBHS_HSTPIPINT_SHRTPCKTI (1 << 7) /* Bit 7: Short Packet Interrupt */ + +/* Host Pipe Set, Host Pipe Mask and Host Pipe Disable Registers only */ + +#define USBHS_HSTPIPINT_NBUSYBKI (1 << 12) /* Bit 12: Number of Busy Banks Interrupt Enable */ + +/* Host Pipe Mask and Host Pipe Disable Registers only */ + +#define USBHS_HSTPIPINT_FIFOCONI (1 << 14) /* Bit 14: FIFO Control */ +#define USBHS_HSTPIPINT_PDISHDMAI (1 << 16) /* Bit 16: Pipe Interrupts Disable HDMA Request Enable */ +#define USBHS_HSTPIPINT_PFREEZEI (1 << 17) /* Bit 17: Pipe Freeze */ +#define USBHS_HSTPIPINT_RSTDTI (1 << 18) /* Bit 18: Reset Data Toggle */ + +/* Host Pipe Status Register only */ + +#define USBHS_HSTPIPISR_DTSEQ_SHIFT (8) /* Bits 8-9: Data Toggle Sequence */ +#define USBHS_HSTPIPISR_DTSEQ_MASK (3 << USBHS_HSTPIPISR_DTSEQ_SHIFT) +# define USBHS_HSTPIPISR_DTSEQ_DATA0 (0 << USBHS_HSTPIPISR_DTSEQ_SHIFT) /* Data0 toggle sequence */ +# define USBHS_HSTPIPISR_DTSEQ_DATA1 (1 << USBHS_HSTPIPISR_DTSEQ_SHIFT) /* Data1 toggle sequence */ +#define USBHS_HSTPIPISR_NBUSYBK_SHIFT (12) /* Bits 12-13: Number of Busy Banks */ +#define USBHS_HSTPIPISR_NBUSYBK_MASK (3 << USBHS_HSTPIPISR_NBUSYBK_SHIFT) +# define USBHS_HSTPIPISR_NBUSYBK_0BUSY (0 << USBHS_HSTPIPISR_NBUSYBK_SHIFT) /* 0 busy bank (all banks free) */ +# define USBHS_HSTPIPISR_NBUSYBK_1BUSY (1 << USBHS_HSTPIPISR_NBUSYBK_SHIFT) /* 1 busy bank */ +# define USBHS_HSTPIPISR_NBUSYBK_2BUSY (2 << USBHS_HSTPIPISR_NBUSYBK_SHIFT) /* 2 busy banks */ +# define USBHS_HSTPIPISR_NBUSYBK_3BUSY (3 << USBHS_HSTPIPISR_NBUSYBK_SHIFT) /* 3 busy banks */ +#define USBHS_HSTPIPISR_CURRBK_SHIFT (14) /* Bits 14-15: Current Bank */ +#define USBHS_HSTPIPISR_CURRBK_MASK (3 << USBHS_HSTPIPISR_CURRBK_SHIFT) +# define USBHS_HSTPIPISR_CURRBK_BANK0 (0 << USBHS_HSTPIPISR_CURRBK_SHIFT) /* Current bank is bank0 */ +# define USBHS_HSTPIPISR_CURRBK_BANK1 (1 << USBHS_HSTPIPISR_CURRBK_SHIFT) /* Current bank is bank1 */ +# define USBHS_HSTPIPISR_CURRBK_BANK2 (2 << USBHS_HSTPIPISR_CURRBK_SHIFT) /* Current bank is bank2 */ +#define USBHS_HSTPIPISR_RWALL (1 << 16) /* Bit 16: Read/Write Allowed */ +#define USBHS_HSTPIPISR_CFGOK (1 << 18) /* Bit 18: Configuration OK Status */ +#define USBHS_HSTPIPISR_PBYCT_SHIFT (20) /* Bits 20-30: Pipe Byte Count */ +#define USBHS_HSTPIPISR_PBYCT_MASK (0x7ff << USBHS_HSTPIPISR_PBYCT_SHIFT) + +/* Host Pipe IN Request Register */ + +#define USBHS_HSTPIPINRQ_INRQ_SHIFT (0) /* Bits 0-7: IN Request Number before Freeze */ +#define USBHS_HSTPIPINRQ_INRQ_MASK (0xff << USBHS_HSTPIPINRQ_INRQ_SHIFT) +# define USBHS_HSTPIPINRQ_INRQ(n) ((uint32_t)(n) << USBHS_HSTPIPINRQ_INRQ_SHIFT) +#define USBHS_HSTPIPINRQ_INMODE (1 << 8) /* Bit 8: IN Request Mode */ + +/* Host Pipe Error Register */ + +#define USBHS_HSTPIPERR_DATATGL (1 << 0) /* Bit 0: Data Toggle Error */ +#define USBHS_HSTPIPERR_DATAPID (1 << 1) /* Bit 1: Data PID Error */ +#define USBHS_HSTPIPERR_PID (1 << 2) /* Bit 2: PID Error */ +#define USBHS_HSTPIPERR_TIMEOUT (1 << 3) /* Bit 3: Time-Out Error */ +#define USBHS_HSTPIPERR_CRC16 (1 << 4) /* Bit 4: CRC16 Error */ +#define USBHS_HSTPIPERR_COUNTER_SHIFT (5) /* Bits 5-6: Error Counter */ +#define USBHS_HSTPIPERR_COUNTER_MASK (3 << USBHS_HSTPIPERR_COUNTER_SHIFT) +# define USBHS_HSTPIPERR_COUNTER(n) ((uint32_t)(n) << USBHS_HSTPIPERR_COUNTER_SHIFT) + +/* Host DMA Channel Next Descriptor Address Register (32-bit address) */ +/* Host DMA Channel Address Register (32-bit address) */ + +/* Host DMA Channel Control Register */ + +#define USBHS_HSTDMACTRL_CMD_SHIFT (0) /* Bits 0-1: Command */ +#define USBHS_HSTDMACTRL_CMD_MASK (3 << USBHS_HSTDMACTRL_CMD_SHIFT) +# define USBHS_HSTDMACTRL_CHANNENB (1 << 0) /* Bit 0: Channel Enable Command */ +# define USBHS_HSTDMACTRL_LDNXTDSC (1 << 1) /* Bit 1: Load Next Channel Transfer Descriptor Enable Command */ +# define USBHS_HSTDMACTRL_STOPNOW (0 << USBHS_HSTDMACTRL_CMD_SHIFT) /* Stop now */ +# define USBHS_HSTDMACTRL_RUNSTOP (1 << USBHS_HSTDMACTRL_CMD_SHIFT) /* Run and stop at end of buffer */ +# define USBHS_HSTDMACTRL_LOADNEXT (2 << USBHS_HSTDMACTRL_CMD_SHIFT) /* Load next descriptor now */ +# define USBHS_HSTDMACTRL_RUNLINK (3 << USBHS_HSTDMACTRL_CMD_SHIFT) /* Run and link at end of buffer */ +#define USBHS_HSTDMACTRL_ENDTREN (1 << 2) /* Bit 2: End of Transfer Enable Control */ +#define USBHS_HSTDMACTRL_ENDBEN (1 << 3) /* Bit 3: End of Buffer Enable Control */ +#define USBHS_HSTDMACTRL_ENDTRIT (1 << 4) /* Bit 4: End of Transfer Interrupt Enable */ +#define USBHS_HSTDMACTRL_ENDBUFFIT (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define USBHS_HSTDMACTRL_DESCLDIT (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enable */ +#define USBHS_HSTDMACTRL_BURSTLCK (1 << 7) /* Bit 7: Burst Lock Enable */ +#define USBHS_HSTDMACTRL_BUFLEN_SHIFT (16) /* Bits 16-31: Buffer Byte Length */ +#define USBHS_HSTDMACTRL_BUFLEN_MASK (0xffff << USBHS_HSTDMACTRL_BUFLEN_SHIFT) +# define USBHS_HSTDMACTRL_BUFLEN(n) ((uint32_t)(n) << USBHS_HSTDMACTRL_BUFLEN_SHIFT) + +/* Host DMA Channel Status Register */ + +#define USBHS_HSTDMASTA_CHANNENB (1 << 0) /* Bit 0: Channel Enable Status */ +#define USBHS_HSTDMASTA_CHANNACT (1 << 1) /* Bit 1: Channel Active Status */ +#define USBHS_HSTDMASTA_ENDTRST (1 << 4) /* Bit 4: End of Transfer Status */ +#define USBHS_HSTDMASTA_ENDBUFFST (1 << 5) /* Bit 5: End of Buffer Status */ +#define USBHS_HSTDMASTA_DESCLDST (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define USBHS_HSTDMASTA_BUFCNT_SHIFT (16) /* Bits 16-31: Buffer Byte Count */ +# define USBHS_HSTDMASTA_BUFCNT(n) ((uint32_t)(n) << USBHS_HSTDMASTA_BUFCNT_SHIFT) + +/* USBHS General Register Bit Field Definitions */ +/* General Control Register */ + +#define USBHS_CTRL_RDERRE (1 << 4) /* Bit 4: Remote Device Connection Error Interrupt Enable */ +#define USBHS_CTRL_FRZCLK (1 << 14) /* Bit 14: Freeze USB Clock */ +#define USBHS_CTRL_USBE (1 << 15) /* Bit 15: USBHS Enable */ +#define USBHS_CTRL_UIDE (1 << 24) /* Bit 24: UOTGID Pin Enable */ +# define USBHS_CTRL_UIDE_UIMOD (0 << 24) /* 0=USB mode selected UIMOD bit. */ +# define USBHS_CTRL_UIDE_UOTGID (1 << 24) /* 1=USB mode selected by UOTGID */ +#define USBHS_CTRL_UIMOD_MASK (1 << 25) /* Bit 25: USBHS Mode */ +# define USBHS_CTRL_UIMOD_HOST (0 << 25) /* 0=Host mode */ +# define USBHS_CTRL_UIMOD_DEVICE (1 << 25) /* 1=Device mode */ + +/* General Status Register */ + +#define USBHS_SR_RDERRI (1 << 4) /* Bit 4: Remote Device Connection Error Interrupt (host mode) */ +#define USBHS_SR_VBUSRQ (1 << 9) /* Bit 9: VBus Request (host mode) */ +#define USBHS_SR_SPEED_SHIFT (12) /* Bits 12-13: Speed Status (device mode) */ +#define USBHS_SR_SPEED_MASK (3 << USBHS_SR_SPEED_SHIFT) +# define USBHS_SR_SPEED_FULL (0 << USBHS_SR_SPEED_SHIFT) /* Full-Speed mode */ +# define USBHS_SR_SPEED_HIGH (1 << USBHS_SR_SPEED_SHIFT) /* High-Speed mode */ +# define USBHS_SR_SPEED_LOW (2 << USBHS_SR_SPEED_SHIFT) /* Low-Speed mode */ +#define USBHS_SR_CLKUSABLE (1 << 14) /* Bit 14: UTMI Clock Usable */ + +/* General Status Clear Register */ + +#define USBHS_SCR_RDERRIC (1 << 4) /* Bit 4: Remote Device Connection Error Interrupt Clear */ +#define USBHS_SCR_VBUSRQC (1 << 9) /* Bit 9: VBus Request Clear */ + +/* General Status Set Register */ + +#define USBHS_SFR_RDERRIS (1 << 4) /* Bit 4: Remote Device Connection Error Interrupt Set */ +#define USBHS_SFR_VBUSRQS (1 << 9) /* Bit 9: VBus Request Set */ + +/************************************************************************************************************ + * Public Types + ************************************************************************************************************/ + +/* This structure defines the USBHS DMA Transfer Descriptor. Instances of DMA transfer + * descriptors must by aligned to 16-byte address boundaries. + * + * Each value contains the next value of each of three USBHS DMA registers. The first + * register value (USBHS_xxxDMANXTDSCx) is a link that can be used to chain sequences of + * DMA transfers. + */ + +struct usbhs_dtd_s +{ + uint32_t nxtd; /* Next Descriptor Address Register: USBHS_xxxDMANXTDSCx */ + uint32_t addr; /* DMA Channelx Address Register: USBHS_xxxDMAADDRESSx */ + uint32_t ctrl; /* DMA Channelx Control Register: USBHS_xxxDMACONTROLx */ +}; +#define SIZEOF_USPHS_DTD_S 12 + +/************************************************************************************************************ + * Public Data + ************************************************************************************************************/ + +/************************************************************************************************************ + * Public Functions + ************************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_USBHS_H */ diff --git a/arch/arm/src/samv7/chip/sam_utmi.h b/arch/arm/src/samv7/chip/sam_utmi.h new file mode 100644 index 0000000000000000000000000000000000000000..6d65d5480ed715a70f858b7c82d7a01831f4d2f6 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_utmi.h @@ -0,0 +1,92 @@ +/************************************************************************************************************ + * arch/arm/src/samv7/chip/sam_utmi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMV7D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UTMI_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UTMI_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ +/* Register offsets *****************************************************************************************/ + +#define SAM_UTMI_OHCIICR_OFFSET 0x0010 /* OHCI Interrupt Configuration Register */ +#define SAM_UTMI_CKTRIM_OFFSET 0x0030 /* UTMI Clock Trimming Register */ + +/* Register addresses ***************************************************************************************/ + +#define SAM_UTMI_OHCIICR (SAM_UTMI_BASE+SAM_UTMI_OHCIICR_OFFSET) +#define SAM_UTMI_CKTRIM (SAM_UTMI_BASE+SAM_UTMI_CKTRIM_OFFSET) + +/* Register bit-field definitions ***************************************************************************/ + +/* OHCI Interrupt Configuration Register */ + +#define UTMI_OHCIICR_RES0 (1 << 0) /* Bit 0: USB PORT0 Reset */ +#define UTMI_OHCIICR_ARIE (1 << 4) /* Bit 4: OHCI Asynchronous Resume Interrupt Enable */ +#define UTMI_OHCIICR_APPSTART (0 << 5) /* Bit 5: Reserved, must be zero */ +#define UTMI_OHCIICR_UDPPUDIS (1 << 23) /* Bit 23: USB Device Pull-up Disable */ + +/* UTMI Clock Trimming Register */ + +#define UTMI_CKTRIM_FREQ_SHIFT (0) /* Bits 0-1: UTMI Reference Clock Frequency */ +#define UTMI_CKTRIM_FREQ_MASK (3 << UTMI_CKTRIM_FREQ_SHIFT) +# define UTMI_CKTRIM_FREQ_XTAL12 (0 << UTMI_CKTRIM_FREQ_SHIFT) /* 12 MHz reference clock */ +# define UTMI_CKTRIM_FREQ_XTAL16 (1 << UTMI_CKTRIM_FREQ_SHIFT) /* 16 MHz reference clock */ + +/************************************************************************************************************ + * Public Types + ************************************************************************************************************/ + +/************************************************************************************************************ + * Public Data + ************************************************************************************************************/ + +/************************************************************************************************************ + * Public Functions + ************************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_UTMI_H */ diff --git a/arch/arm/src/samv7/chip/sam_wdt.h b/arch/arm/src/samv7/chip/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..3a949c3c97a90fc0fdfc24466b427c07d19c3006 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_wdt.h @@ -0,0 +1,117 @@ +/**************************************************************************************** + * arch/arm/src/samv7/chip/sam_wdt.h + * Watchdog Timer (WDT) definitions for the SAMV71 + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_WDT_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_WDT_H + +/**************************************************************************************** + * Included Files + ****************************************************************************************/ + +#include +#include + +#include "chip/sam_memorymap.h" + +/**************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************/ + +/* WDT register offsets *****************************************************************/ + +#define SAM_WDT_CR_OFFSET 0x00 /* Control Register */ +#define SAM_WDT_MR_OFFSET 0x04 /* Mode Register */ +#define SAM_WDT_SR_OFFSET 0x08 /* Status Register */ + +/* WDT register addresses ***************************************************************/ + +/* WDT: Legacy Watchdog Timer */ + +#define SAM_WDT_CR (SAM_WDT_BASE+SAM_WDT_CR_OFFSET) +#define SAM_WDT_MR (SAM_WDT_BASE+SAM_WDT_MR_OFFSET) +#define SAM_WDT_SR (SAM_WDT_BASE+SAM_WDT_SR_OFFSET) + +/* RSWDT: Reinforced Safety Watchdog Timer */ + +#define SAM_RSWDT_CR (SAM_RSWDT_BASE+SAM_WDT_CR_OFFSET) +#define SAM_RSWDT_MR (SAM_RSWDT_BASE+SAM_WDT_MR_OFFSET) +#define SAM_RSWDT_SR (SAM_RSWDT_BASE+SAM_WDT_SR_OFFSET) + +/* WDT register bit definitions *********************************************************/ +/* Watchdog Timer Control Register */ + +#define WDT_CR_WDRSTT (1 << 0) /* Bit 0: Watchdog Rest */ +#define WDT_CR_KEY_SHIFT (24) /* Bits 24-31: Password */ +#define WDT_CR_KEY_MASK (0xff << WDT_CR_KEY_SHIFT) +# define WDT_CR_KEY (0xa5 << WDT_CR_KEY_SHIFT) +# define RSWDT_CR_KEY (0xc4 << WDT_CR_KEY_SHIFT) + +/* Watchdog Timer Mode Register */ + +#define WDT_MR_WDV_SHIFT (0) /* Bits 0-11: Watchdog Counter Value */ +#define WDT_MR_WDV_MAX 0xfff +#define WDT_MR_WDV_MASK (WDT_MR_WDV_MAX << WDT_MR_WDV_SHIFT) +# define WDT_MR_WDV(n) ((uint32_t)(n) << WDT_MR_WDV_SHIFT) +#define WDT_MR_WDFIEN (1 << 12) /* Bit 12: Watchdog Fault Interrupt Enable */ +#define WDT_MR_WDRSTEN (1 << 13) /* Bit 13: Watchdog Reset Enable */ +#define RSWDT_MR_WDRPROC (1 << 14) /* Bit 14: Watchdog Reset Processor (RSWDT only) */ +#define WDT_MR_WDDIS (1 << 15) /* Bit 15: Watchdog Disable */ +#define WDT_MR_WDD_SHIFT (16) /* Bits 16-27: Watchdog Delta Value (WDT only) */ +#define WDT_MR_WDD_MAX 0xfff +#define WDT_MR_WDD_MASK (WDT_MR_WDD_MAX << WDT_MR_WDD_SHIFT) +# define WDT_MR_WDD(n) ((uint32_t)(n) << WDT_MR_WDD_SHIFT) +# define RSWDT_MR_WDD_ALLONES (0xfff << WDT_MR_WDD_SHIFT) +#define WDT_MR_WDDBGHLT (1 << 28) /* Bit 28: Watchdog Debug Halt */ +#define WDT_MR_WDIDLEHLT (1 << 29) /* Bit 29: Watchdog Idle Halt */ + +/* Watchdog Timer Status Register */ + +#define WDT_SR_WDUNF (1 << 0) /* Bit 0: Watchdog Underflow */ +#define WDT_SR_WDERR (1 << 1) /* Bit 1: Watchdog Error (WDT only) */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +/**************************************************************************************** + * Public Data + ****************************************************************************************/ + +/**************************************************************************************** + * Public Functions + ****************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_WDT_H */ diff --git a/arch/arm/src/samv7/chip/sam_xdmac.h b/arch/arm/src/samv7/chip/sam_xdmac.h new file mode 100644 index 0000000000000000000000000000000000000000..cac9a5857a6f4ba87048a1e8aec5c61d648f36a1 --- /dev/null +++ b/arch/arm/src/samv7/chip/sam_xdmac.h @@ -0,0 +1,463 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/sam_xdmac.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAM_XDMAC_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAM_XDMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Included Files + ************************************************************************************/ +/* XDMAC Register Offsets ***********************************************************/ + +#define SAM_XDMAC_GTYPE_OFFSET 0x0000 /* Global Type Register */ +#define SAM_XDMAC_GCFG_OFFSET 0x0004 /* Global Configuration Register */ +#define SAM_XDMAC_GWAC_OFFSET 0x0008 /* Global Weighted Arbiter Configuration Register */ +#define SAM_XDMAC_GIE_OFFSET 0x000c /* Global Interrupt Enable Register */ +#define SAM_XDMAC_GID_OFFSET 0x0010 /* Global Interrupt Disable Register */ +#define SAM_XDMAC_GIM_OFFSET 0x0014 /* Global Interrupt Mask Register */ +#define SAM_XDMAC_GIS_OFFSET 0x0018 /* Global Interrupt Status Register */ +#define SAM_XDMAC_GE_OFFSET 0x001c /* Global Channel Enable Register */ +#define SAM_XDMAC_GD_OFFSET 0x0020 /* Global Channel Disable Register */ +#define SAM_XDMAC_GS_OFFSET 0x0024 /* Global Channel Status Register */ +#define SAM_XDMAC_GRS_OFFSET 0x0028 /* Global Channel Read Suspend Register */ +#define SAM_XDMAC_GWS_OFFSET 0x002c /* Global Channel Write Suspend Register */ +#define SAM_XDMAC_GRWS_OFFSET 0x0030 /* Global Channel Read Write Suspend Register */ +#define SAM_XDMAC_GRWR_OFFSET 0x0034 /* Global Channel Read Write Resume Register */ +#define SAM_XDMAC_GSWR_OFFSET 0x0038 /* Global Channel Software Request Register */ +#define SAM_XDMAC_GSWS_OFFSET 0x003c /* Global Channel Software Request Status Register */ +#define SAM_XDMAC_GSWF_OFFSET 0x0040 /* Global Channel Software Flush Request Register */ + /* 0x0044–0x004c Reserved */ + +/* Offsets to the base of the DMA channel registers */ + +#define SAM_XDMACH_OFFSET(n) (0x0050 + ((n) << 6)) +# define SAM_XDMACH0_OFFSET 0x0050 +# define SAM_XDMACH1_OFFSET 0x0090 +# define SAM_XDMACH2_OFFSET 0x00d0 +# define SAM_XDMACH3_OFFSET 0x0110 +# define SAM_XDMACH4_OFFSET 0x0150 +# define SAM_XDMACH5_OFFSET 0x0190 +# define SAM_XDMACH6_OFFSET 0x01d0 +# define SAM_XDMACH7_OFFSET 0x0210 +# define SAM_XDMACH8_OFFSET 0x0250 +# define SAM_XDMACH9_OFFSET 0x0290 +# define SAM_XDMACH10_OFFSET 0x02d0 +# define SAM_XDMACH11_OFFSET 0x0310 +# define SAM_XDMACH12_OFFSET 0x0350 +# define SAM_XDMACH13_OFFSET 0x0390 +# define SAM_XDMACH14_OFFSET 0x03d0 +# define SAM_XDMACH15_OFFSET 0x0410 +# define SAM_XDMACH16_OFFSET 0x0450 +# define SAM_XDMACH17_OFFSET 0x0490 +# define SAM_XDMACH18_OFFSET 0x04d0 +# define SAM_XDMACH19_OFFSET 0x0510 +# define SAM_XDMACH20_OFFSET 0x0550 +# define SAM_XDMACH21_OFFSET 0x0590 +# define SAM_XDMACH22_OFFSET 0x05d0 +# define SAM_XDMACH23_OFFSET 0x0610 + +/* Offsets to channel registers relative to the base of the DMA channel registers */ + +#define SAM_XDMACH_CIE_OFFSET 0x0000 /* Channel Interrupt Enable Register */ +#define SAM_XDMACH_CID_OFFSET 0x0004 /* Channel Interrupt Disable Register */ +#define SAM_XDMACH_CIM_OFFSET 0x0008 /* Channel Interrupt Mask Register */ +#define SAM_XDMACH_CIS_OFFSET 0x000c /* Channel Interrupt Status Register */ +#define SAM_XDMACH_CSA_OFFSET 0x0010 /* Channel Source Address Register */ +#define SAM_XDMACH_CDA_OFFSET 0x0014 /* Channel Destination Address Register */ +#define SAM_XDMACH_CNDA_OFFSET 0x0018 /* Channel Next Descriptor Address Register */ +#define SAM_XDMACH_CNDC_OFFSET 0x001c /* Channel Next Descriptor Control Register */ +#define SAM_XDMACH_CUBC_OFFSET 0x0020 /* Channel Microblock Control Register */ +#define SAM_XDMACH_CBC_OFFSET 0x0024 /* Channel Block Control Register */ +#define SAM_XDMACH_CC_OFFSET 0x0028 /* Channel Configuration Register */ +#define SAM_XDMACH_CDSMSP_OFFSET 0x002c /* Channel Data Stride Memory Set Pattern */ +#define SAM_XDMACH_CSUS_OFFSET 0x0030 /* Channel Source Microblock Stride */ +#define SAM_XDMACH_CDUS_OFFSET 0x0034 /* Channel Destination Microblock Stride */ + /* 0x0038-0x003c Reserved */ + /* 0x0fec–0x0ffc Reserved */ + +/* XDMAC Register Addresses *********************************************************/ + +#define SAM_XDMAC_GTYPE (SAM_XDMAC_BASE+SAM_XDMAC_GTYPE_OFFSET) +#define SAM_XDMAC_GCFG (SAM_XDMAC_BASE+SAM_XDMAC_GCFG_OFFSET) +#define SAM_XDMAC_GWAC (SAM_XDMAC_BASE+SAM_XDMAC_GWAC_OFFSET) +#define SAM_XDMAC_GIE (SAM_XDMAC_BASE+SAM_XDMAC_GIE_OFFSET) +#define SAM_XDMAC_GID (SAM_XDMAC_BASE+SAM_XDMAC_GID_OFFSET) +#define SAM_XDMAC_GIM (SAM_XDMAC_BASE+SAM_XDMAC_GIM_OFFSET) +#define SAM_XDMAC_GIS (SAM_XDMAC_BASE+SAM_XDMAC_GIS_OFFSET) +#define SAM_XDMAC_GE (SAM_XDMAC_BASE+SAM_XDMAC_GE_OFFSET) +#define SAM_XDMAC_GD (SAM_XDMAC_BASE+SAM_XDMAC_GD_OFFSET) +#define SAM_XDMAC_GS (SAM_XDMAC_BASE+SAM_XDMAC_GS_OFFSET) +#define SAM_XDMAC_GRS (SAM_XDMAC_BASE+SAM_XDMAC_GRS_OFFSET) +#define SAM_XDMAC_GWS (SAM_XDMAC_BASE+SAM_XDMAC_GWS_OFFSET) +#define SAM_XDMAC_GRWS (SAM_XDMAC_BASE+SAM_XDMAC_GRWS_OFFSET) +#define SAM_XDMAC_GRWR (SAM_XDMAC_BASE+SAM_XDMAC_GRWR_OFFSET) +#define SAM_XDMAC_GSWR (SAM_XDMAC_BASE+SAM_XDMAC_GSWR_OFFSET) +#define SAM_XDMAC_GSWS (SAM_XDMAC_BASE+SAM_XDMAC_GSWS_OFFSET) +#define SAM_XDMAC_GSWF (SAM_XDMAC_BASE+SAM_XDMAC_GSWF_OFFSET) + +/* Base addresses of XDMAC channel registers */ + +#define SAM_XDMACH_BASE(n) (SAM_XDMAC_BASE+SAM_XDMACH_OFFSET(n)) +# define SAM_XDMACH0_BASE (SAM_XDMAC_BASE+SAM_XDMACH0_OFFSET) +# define SAM_XDMACH1_BASE (SAM_XDMAC_BASE+SAM_XDMACH1_OFFSET) +# define SAM_XDMACH2_BASE (SAM_XDMAC_BASE+SAM_XDMACH2_OFFSET) +# define SAM_XDMACH3_BASE (SAM_XDMAC_BASE+SAM_XDMACH3_OFFSET) +# define SAM_XDMACH4_BASE (SAM_XDMAC_BASE+SAM_XDMACH4_OFFSET) +# define SAM_XDMACH5_BASE (SAM_XDMAC_BASE+SAM_XDMACH5_OFFSET) +# define SAM_XDMACH6_BASE (SAM_XDMAC_BASE+SAM_XDMACH6_OFFSET) +# define SAM_XDMACH7_BASE (SAM_XDMAC_BASE+SAM_XDMACH7_OFFSET) +# define SAM_XDMACH8_BASE (SAM_XDMAC_BASE+SAM_XDMACH8_OFFSET) +# define SAM_XDMACH9_BASE (SAM_XDMAC_BASE+SAM_XDMACH9_OFFSET) +# define SAM_XDMACH10_BASE (SAM_XDMAC_BASE+SAM_XDMACH10_OFFSET) +# define SAM_XDMACH11_BASE (SAM_XDMAC_BASE+SAM_XDMACH11_OFFSET) +# define SAM_XDMACH12_BASE (SAM_XDMAC_BASE+SAM_XDMACH12_OFFSET) +# define SAM_XDMACH13_BASE (SAM_XDMAC_BASE+SAM_XDMACH13_OFFSET) +# define SAM_XDMACH14_BASE (SAM_XDMAC_BASE+SAM_XDMACH14_OFFSET) +# define SAM_XDMACH15_BASE (SAM_XDMAC_BASE+SAM_XDMACH15_OFFSET) +# define SAM_XDMACH16_BASE (SAM_XDMAC_BASE+SAM_XDMACH16_OFFSET) +# define SAM_XDMACH17_BASE (SAM_XDMAC_BASE+SAM_XDMACH17_OFFSET) +# define SAM_XDMACH18_BASE (SAM_XDMAC_BASE+SAM_XDMACH18_OFFSET) +# define SAM_XDMACH19_BASE (SAM_XDMAC_BASE+SAM_XDMACH19_OFFSET) +# define SAM_XDMACH20_BASE (SAM_XDMAC_BASE+SAM_XDMACH20_OFFSET) +# define SAM_XDMACH21_BASE (SAM_XDMAC_BASE+SAM_XDMACH21_OFFSET) +# define SAM_XDMACH22_BASE (SAM_XDMAC_BASE+SAM_XDMACH22_OFFSET) +# define SAM_XDMACH23_BASE (SAM_XDMAC_BASE+SAM_XDMACH23_OFFSET) + +/* Addresses of XDMAC channel registers */ + +#define SAM_XDMACH_CIE(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CIE_OFFSET) +#define SAM_XDMACH_CID(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CID_OFFSET) +#define SAM_XDMACH_CIM(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CIM_OFFSET) +#define SAM_XDMACH_CIS(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CIS_OFFSET) +#define SAM_XDMACH_CSA(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CSA_OFFSET) +#define SAM_XDMACH_CDA(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CDA_OFFSET) +#define SAM_XDMACH_CNDA(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CNDA_OFFSET) +#define SAM_XDMACH_CNDC(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CNDC_OFFSET) +#define SAM_XDMACH_CUBC(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CUBC_OFFSET) +#define SAM_XDMACH_CBC(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CBC_OFFSET) +#define SAM_XDMACH_CC(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CC_OFFSET) +#define SAM_XDMACH_CDSMSP(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CDSMSP_OFFSET) +#define SAM_XDMACH_CSUS(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CSUS_OFFSET) +#define SAM_XDMACH_CDUS(n) (SAM_XDMACH_BASE(n)+SAM_XDMACH_CDUS_OFFSET) + +/* XDMAC Register Bit Definitions ***************************************************/ + +/* Global Type Register */ + +#define XDMAC_GTYPE_NB_CH_SHIFT (0) /* Bits 0-4: Number of Channels Minus One */ +#define XDMAC_GTYPE_NB_CH_MASK (31 << XDMAC_GTYPE_NB_CH_SHIFT) + #define XDMAC_GTYPE_NB_CH(n) ((uint32_t)(n) << XDMAC_GTYPE_NB_CH_SHIFT) +#define XDMAC_GTYPE_FIFO_SZ_SHIFT (5) /* Bits 5-15: Number of Bytes */ +#define XDMAC_GTYPE_FIFO_SZ_MASK (0x7ff << XDMAC_GTYPE_FIFO_SZ_SHIFT) +# define XDMAC_GTYPE_FIFO_SZ(n) ((uint32_t)(n) << XDMAC_GTYPE_FIFO_SZ_SHIFT) +#define XDMAC_GTYPE_NB_REQ_SHIFT (16) /* Bits 16-22: Number of Peripheral Requests Minus One */ +#define XDMAC_GTYPE_NB_REQ_MASK (0x7f << XDMAC_GTYPE_NB_REQ_SHIFT) +# define XDMAC_GTYPE_NB_REQ(n) ((uint32_t)(n) << XDMAC_GTYPE_NB_REQ_SHIFT) + +/* Global Configuration Register */ + +#define XDMAC_GCFG_CGDISREG (1 << 0) /* Bit 0: Configuration Registers Clock Gating Disable */ +#define XDMAC_GCFG_CGDISPIPE (1 << 1) /* Bit 1: Pipeline Clock Gating Disable */ +#define XDMAC_GCFG_CGDISFIFO (1 << 2) /* Bit 2: FIFO Clock Gating Disable */ +#define XDMAC_GCFG_CGDISIF (1 << 3) /* Bit 3: Bus Interface Clock Gating Disable */ +#define XDMAC_GCFG_BXKBEN (1 << 8) /* Bit 8: Boundary X Kilo byte Enable */ + +/* Global Weighted Arbiter Configuration Register */ + +#define XDMAC_GWAC_PW0_SHIFT (0) /* Bits 0-3: Pool Weight 0 */ +#define XDMAC_GWAC_PW0_MASK (15 << XDMAC_GWAC_PW0_SHIFT) +# define XDMAC_GWAC_PW0(n) ((uint32_t)(n) << XDMAC_GWAC_PW0_SHIFT) +#define XDMAC_GWAC_PW1_SHIFT (4) /* Bits 4-7: Pool Weight 1 */ +#define XDMAC_GWAC_PW1_MASK (15 << XDMAC_GWAC_PW1_SHIFT) +# define XDMAC_GWAC_PW1(n) ((uint32_t)(n) << XDMAC_GWAC_PW1_SHIFT) +#define XDMAC_GWAC_PW2_SHIFT (8) /* Bits 8-11: Pool Weight 2 */ +#define XDMAC_GWAC_PW2_MASK (15 << XDMAC_GWAC_PW2_SHIFT) +# define XDMAC_GWAC_PW2(n) ((uint32_t)(n) << XDMAC_GWAC_PW2_SHIFT) +#define XDMAC_GWAC_PW3_SHIFT (12) /* Bits 12-15: Pool Weight 3 */ +#define XDMAC_GWAC_PW3_MASK (15 << XDMAC_GWAC_PW3_SHIFT) +# define XDMAC_GWAC_PW3(n) ((uint32_t)(n) << XDMAC_GWAC_PW3_SHIFT) + +/* All of these registers have the same layout: + * + * - Global Interrupt Enable Register, Global Interrupt Disable Register, Interrupt + * Mask Register, and Global Interrupt Status Register. + * + * - Global Channel Enable Register, Global Channel Disable Register, and Global + * Channel Status Register + * + * - Global Channel Read Suspend Register, Global Channel Write Suspend Register, + * Channel Read Write Suspend Register, and Global Channel Read Write Resume + * Register + * + * - Global Channel Software Request Register, Global Channel Software Request + * Status Register, and Global Channel Software Flush Request Register + */ + +#define XDMAC_CHAN(n) (1 << (n)) +#define XDMAC_CHAN_ALL (0x0000ffff) + +/* Channel Interrupt Enable Register, Channel Interrupt Disable Register, Channel + * Interrupt Mask Register, and Channel Interrupt Status Register. + */ + +#define XDMAC_CHINT_BI (1 << 0) /* Bit 0: End of Block Interrupt */ +#define XDMAC_CHINT_LI (1 << 1) /* Bit 1: End of Linked List Interrupt */ +#define XDMAC_CHINT_DI (1 << 2) /* Bit 2: End of Disable Interrupt */ +#define XDMAC_CHINT_FI (1 << 3) /* Bit 3: End of Flush Interrupt */ +#define XDMAC_CHINT_RBI (1 << 4) /* Bit 4: Read Bus Error Interrupt */ +#define XDMAC_CHINT_WBI (1 << 5) /* Bit 5: Write Bus Error Interrupt */ +#define XDMAC_CHINT_ROI (1 << 6) /* Bit 6: Request Overflow Error Interrupt Disable Bit */ + +#define XDMAC_CHINT_ERRORS (0x00000070) +#define XDMAC_CHINT_ALL (0x0000007f) + +/* Channel Source Address (SA) Register (aligned 32-bit address) */ +/* Channel Destination Address (DA) Register (aligned 32-bit address) */ + +/* Channel Next Descriptor Address (CNDA) Register (aligned 32-bit address) */ + +#define XDMACH_CNDA_NDAIF (1 << 0) /* Bit 0: Channel Next Descriptor Interface */ +#define XDMACH_CNDA_NDA_MASK (0xfffffffc) /* Bit 2-31: Channel Next Descriptor Address */ + +/* Channel Next Descriptor Control Register */ + +#define XDMACH_CNDC_NDE (1 << 0) /* Bit 0: Channel Next Descriptor Enable */ +#define XDMACH_CNDC_NDSUP (1 << 1) /* Bit 1: Channel Next Descriptor Source Update */ +#define XDMACH_CNDC_NDDUP (1 << 2) /* Bit 2: Channel Next Descriptor Destination Update */ +#define XDMACH_CNDC_NDVIEW_SHIFT (3) /* Bits 3-4: Channel Next Descriptor View */ +#define XDMACH_CNDC_NDVIEW_MASK (3 << XDMACH_CNDC_NDVIEW_SHIFT) +# define XDMACH_CNDC_NDVIEW_NDV0 (0 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 0 */ +# define XDMACH_CNDC_NDVIEW_NDV1 (1 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 1 */ +# define XDMACH_CNDC_NDVIEW_NDV2 (2 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 2 */ +# define XDMACH_CNDC_NDVIEW_NDV3 (3 << XDMACH_CNDC_NDVIEW_SHIFT) /* Next Descriptor View 3 */ + +/* Channel Microblock Control Register */ + +#define XDMACH_CUBC_UBLEN_SHIFT (0) /* Bits 0-23: Channel Microblock Length */ +#define XDMACH_CUBC_UBLEN_MASK (0x00ffffff << XDMACH_CUBC_UBLEN_SHIFT) +# define XDMACH_CUBC_UBLEN_MAX (0x00ffffff) + +/* Channel Block Control Register */ + +#define XDMACH_CBC_BLEN_MASK (0x000000fff) /* Bits 0-11: Channel Block Length */ + +/* Channel Configuration Register */ + +#define XDMACH_CC_TYPE (1 << 0) /* Bit 0: Channel Transfer Type */ +#define XDMACH_CC_MBSIZE_SHIFT (1) /* Bits 1-2: Channel Memory Burst Size */ +#define XDMACH_CC_MBSIZE_MASK (3 << XDMACH_CC_MBSIZE_SHIFT) +# define XDMACH_CC_MBSIZE(n) ((uint32_t)(n) << XDMACH_CC_MBSIZE_SHIFT) /* n=0-3 */ +# define XDMACH_CC_MBSIZE_1 (0 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to one */ +# define XDMACH_CC_MBSIZE_4 (1 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to four */ +# define XDMACH_CC_MBSIZE_8 (2 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to eight */ +# define XDMACH_CC_MBSIZE_16 (3 << XDMACH_CC_MBSIZE_SHIFT) /* The memory burst size is set to sixteen */ +#define XDMACH_CC_DSYNC (1 << 4) /* Bit 4: Channel Synchronization */ +#define XDMACH_CC_PROT (1 << 5) /* Bit 5: Channel Protection */ +#define XDMACH_CC_SWREQ (1 << 6) /* Bit 6: Channel Software Request Trigger */ +#define XDMACH_CC_MEMSET (1 << 7) /* Bit 7: Channel Fill Block of memory */ +#define XDMACH_CC_CSIZE_SHIFT (8) /* Bits 8-10: Channel Chunk Size */ +#define XDMACH_CC_CSIZE_MASK (7 << XDMACH_CC_CSIZE_SHIFT) +# define XDMACH_CC_CSIZE_1 (0 << XDMACH_CC_CSIZE_SHIFT) /* 1 data transferred */ +# define XDMACH_CC_CSIZE_2 (1 << XDMACH_CC_CSIZE_SHIFT) /* 2 data transferred */ +# define XDMACH_CC_CSIZE_4 (2 << XDMACH_CC_CSIZE_SHIFT) /* 4 data transferred */ +# define XDMACH_CC_CSIZE_8 (3 << XDMACH_CC_CSIZE_SHIFT) /* 8 data transferred */ +# define XDMACH_CC_CSIZE_16 (4 << XDMACH_CC_CSIZE_SHIFT) /* 16 data transferred */ +#define XDMACH_CC_DWIDTH_SHIFT (11) /* Bits 11-12: Channel Data Width */ +#define XDMACH_CC_DWIDTH_MASK (3 << XDMACH_CC_DWIDTH_SHIFT) +# define XDMACH_CC_DWIDTH_BYTE (0 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 8 bits */ +# define XDMACH_CC_DWIDTH_HWORD (1 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 16 bits */ +# define XDMACH_CC_DWIDTH_WORD (2 << XDMACH_CC_DWIDTH_SHIFT) /* The data size is set to 32 bits */ +#define XDMACH_CC_SIF (1 << 13) /* Bit 13: Channel Source Interface Identifier */ +#define XDMACH_CC_DIF (1 << 14) /* Bit 14: Channel Destination Interface Identifier */ +#define XDMACH_CC_SAM_SHIFT (16) /* Bits 16-17: Channel Source Addressing Mode */ +#define XDMACH_CC_SAM_MASK (3 << XDMACH_CC_SAM_SHIFT) +# define XDMACH_CC_SAM_FIXED (0 << XDMACH_CC_SAM_SHIFT) /* The address remains unchanged */ +# define XDMACH_CC_SAM_INCR (1 << XDMACH_CC_SAM_SHIFT) /* Address is incremented */ +# define XDMACH_CC_SAM_UBS (2 << XDMACH_CC_SAM_SHIFT) /* Microblock stride is added */ +# define XDMACH_CC_SAM_UBSDS (3 << XDMACH_CC_SAM_SHIFT) /* Microblock stride and data stride is added */ +#define XDMACH_CC_DAM_SHIFT (18) /* Bits 18-19: Channel Destination Addressing Mode */ +#define XDMACH_CC_DAM_MASK (3 << XDMACH_CC_DAM_SHIFT) +# define XDMACH_CC_DAM_FIXED (0 << XDMACH_CC_DAM_SHIFT) /* The address remains unchanged */ +# define XDMACH_CC_DAM_INCR (1 << XDMACH_CC_DAM_SHIFT) /* Address is incremented */ +# define XDMACH_CC_DAM_UBS (2 << XDMACH_CC_DAM_SHIFT) /* Microblock stride is added */ +# define XDMACH_CC_DAM_UBSDS (3 << XDMACH_CC_DAM_SHIFT) /* Microblock stride and data stride is added */ +#define XDMACH_CC_INITD (1 << 21) /* Bit 21: Channel Initialization Terminated */ +#define XDMACH_CC_RDIP (1 << 22) /* Bit 22: Read in Progress */ +#define XDMACH_CC_WRIP (1 << 23) /* Bit 23: Write in Progress */ +#define XDMACH_CC_PERID_SHIFT (24) /* Bits 24-30: Channel Peripheral Identifier */ +#define XDMACH_CC_PERID_MASK (0x7f << XDMACH_CC_PERID_SHIFT) +# define XDMACH_CC_PERID(n) ((uint32_t)(n) << XDMACH_CC_PERID_SHIFT) + +/* Channel Data Stride Memory Set Pattern */ + +#define XDMACH_CDSMSP_SDS_MSP_SHIFT (0) /* Bits 0-15: Channel Source Data stride or Memory Set Pattern */ +#define XDMACH_CDSMSP_SDS_MSP_MASK (0xffff << XDMACH_CDSMSP_SDS_MSP_SHIFT) +# define XDMACH_CDSMSP_SDS_MSP(n) ((uint32_t)(n) << XDMACH_CDSMSP_SDS_MSP_SHIFT) +#define XDMACH_CDSMSP_DDS_MSP_SHIFT (16) /* Bits 16-31: Channel Destination Data Stride or Memory Set Pattern */ +#define XDMACH_CDSMSP_DDS_MSP_MASK (0xffff << XDMACH_CDSMSP_DDS_MSP_SHIFT) +# define XDMACH_CDSMSP_DDS_MSP(n) ((uint32_t)(n) << XDMACH_CDSMSP_DDS_MSP_SHIFT) + +/* Channel Source Microblock Stride */ + +#define XDMACH_CSUS_SUBS_MASK (0x00ffffff) /* Bits 0-23: Channel Source Microblock Stride */ + +/* Channel Destination Microblock Stride */ + +#define XDMACH_CDUS_DUBS_MASK (0x00ffffff) /* Bits 0-23: Channel Destination Microblock Stride */ + +/* XDMA Channel Definitions *************************************************************/ + +#define XDMACH_HSMCI 0 +#define XDMACH_SPI0_TX 1 +#define XDMACH_SPI0_RX 2 +#define XDMACH_SPI1_TX 3 +#define XDMACH_SPI1_RX 4 +#define XDMACH_QSPI_TX 5 +#define XDMACH_QSPI_RX 6 +#define XDMACH_USART0_TX 7 +#define XDMACH_USART0_RX 8 +#define XDMACH_USART1_TX 9 +#define XDMACH_USART1_RX 10 +#define XDMACH_USART2_TX 11 +#define XDMACH_USART2_RX 12 +#define XDMACH_PWM0_TX 13 +#define XDMACH_TWIHS0_TX 14 +#define XDMACH_TWIHS0_RX 15 +#define XDMACH_TWIHS1_TX 16 +#define XDMACH_TWIHS1_RX 17 +#define XDMACH_TWIHS2_TX 18 +#define XDMACH_TWIHS2_RX 19 +#define XDMACH_UART0_TX 20 +#define XDMACH_UART0_RX 21 +#define XDMACH_UART1_TX 22 +#define XDMACH_UART1_RX 23 +#define XDMACH_UART2_TX 24 +#define XDMACH_UART2_RX 25 +#define XDMACH_UART3_TX 26 +#define XDMACH_UART3_RX 27 +#define XDMACH_UART4_TX 28 +#define XDMACH_UART4_RX 29 +#define XDMACH_DACC_TX 30 +#define XDMACH_SSC_TX 32 +#define XDMACH_SSC_RX 33 +#define XDMACH_PIOA_RX 34 +#define XDMACH_AFEC0_RX 35 +#define XDMACH_AFEC1_RX 36 +#define XDMACH_AES_TX 37 +#define XDMACH_AES_RX 38 +#define XDMACH_PWM1_TX 39 +#define XDMACH_TC0_RX 40 +#define XDMACH_TC1_RX 41 +#define XDMACH_TC2_RX 42 +#define XDMACH_TC3_RX 43 + +/* Descriptor structure member definitions **********************************************/ + +/* Next Descriptor Address (32-bit address) */ + +/* Microblock Control */ + +#define CHNEXT_UBC_UBLEN_SHIFT (0) /* Bits 0-23: Microblock Length */ +#define CHNEXT_UBC_UBLEN_MASK (0x00ffffff << CHNEXT_UBC_UBLEN_SHIFT) +# define CHNEXT_UBC_UBLEN(n) ((uint32_t)(n) << CHNEXT_UBC_UBLEN_SHIFT) +#define CHNEXT_UBC_NDE (1 << 24) /* Bit 24: Next Descriptor Enable */ +#define CHNEXT_UBC_NSEN (1 << 25) /* Bit 25: Next Descriptor Source Update */ +#define CHNEXT_UBC_NDEN (1 << 26) /* Bit 26: Next Descriptor Destination Update */ +#define CHNEXT_UBC_NVIEW_SHIFT (27) /* Bits 27-29: Next Descriptor View */ +#define CHNEXT_UBC_NVIEW_MASK (3 << CHNEXT_UBC_NVIEW_SHIFT) +# define CHNEXT_UBC_NVIEW_0 (0 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 0 */ +# define CHNEXT_UBC_NVIEW_1 (1 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 1 */ +# define CHNEXT_UBC_NVIEW_2 (2 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 2 */ +# define CHNEXT_UBC_NVIEW_3 (3 << CHNEXT_UBC_NVIEW_SHIFT) /* Next Descriptor View 3 */ + +/* Source Address (32-bit address) */ +/* Destination Address (32-bit address) */ + +/* Configuration Register */ +/* Block Control */ + +/* Data Stride (32-bit value) */ +/* Source Microblock Stride (32-bit value) */ +/* Destination Microblock Stride (32-bit value) */ + +/**************************************************************************************** + * Public Types + ****************************************************************************************/ + +struct chnext_view0_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t cta; /* Transfer Address */ +}; + +struct chnext_view1_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ +}; + +struct chnext_view2_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ + uint32_t cc; /* Configuration Register */ +}; + +struct chnext_view3_s +{ + uint32_t cnda; /* Next Descriptor Address */ + uint32_t cubc; /* Microblock Control */ + uint32_t csa; /* Source Address */ + uint32_t cda; /* Destination Address */ + uint32_t cc; /* Configuration Register */ + uint32_t cbc; /* Block Control */ + uint32_t cds; /* Data Stride */ + uint32_t csus; /* Source Microblock Stride */ + uint32_t cdus; /* Destination Microblock Stride */ +}; + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM_XDMAC_H */ diff --git a/arch/arm/src/samv7/chip/same70_memorymap.h b/arch/arm/src/samv7/chip/same70_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..421f93686fda93e76c85d000182ecbe6080291c5 --- /dev/null +++ b/arch/arm/src/samv7/chip/same70_memorymap.h @@ -0,0 +1,201 @@ +/************************************************************************************************ + * arch/arm/src/samv7/chip/same70_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAME70_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAME70_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_MEMORY_BASE 0x60000000 /* 0x60000000-0x7fffffff: Memories */ +#define SAM_QSPIMEM_BASE 0x80000000 /* 0x80000000-0x9fffffff: QSPI memory */ +#define SAM_AXIMX_BASE 0xa0000000 /* 0xa0000000-0x9fffffff: AXIMX */ +#define SAM_USBHSRAM_BASE 0xa0100000 /* 0xa0100000-0xa01fffff: USBHS RAM */ + /* 0xa0200000-0xdfffffff: Reserved */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x00ffffff: ITCM or Boot Memory */ +#define SAM_INTFLASH_BASE 0x00400000 /* 0x00400000-0x007fffff: Internal FLASH */ +#define SAM_INTROM_BASE 0x00800000 /* 0x00800000-0x00bfffff: Internal ROM */ + /* 0x00c00000-0x1fffffff: Reserved */ +/* Internal SRAM memory region */ + +#define SAM_DTCM_BASE 0x20000000 /* 0x20000000-0x203fffff: DTCM */ +#define SAM_SRAM_BASE 0x20400000 /* 0x20400000-0x20bfffff: SRAM */ + /* 0x20c00000-0x3fffffff: Reserved */ +/* Peripherals address region */ + +#define SAM_HSMCI0_BASE 0x40000000 /* 0x40000000-0x40003fff: High Speed Multimedia Card Interface */ +#define SAM_SSC0_BASE 0x40004000 /* 0x40004000-0x40007fff: Serial Synchronous Controller */ +#define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface 0 */ +#define SAM_TC012_BASE 0x4000c000 /* 0x4000c000-0x4000ffff: Timer Counters 0-2 */ +# define SAM_TC0_BASE 0x4000c000 /* 0x4000c000-0x4000c03f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x4000c040 /* 0x4000c040-0x4000c07f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x4000c080 /* 0x4000c080-0x4000c0bf: Timer Counter 2 */ + /* 0x4000c0c0-0x4000ffff Reserved */ +#define SAM_TC345_BASE 0x40010000 /* 0x40010000-0x40013fff: Timer Counters 3-5 */ +# define SAM_TC3_BASE 0x40010000 /* 0x40010000-0x4001003f: Timer Counter 3 */ +# define SAM_TC4_BASE 0x40010040 /* 0x40010040-0x4001007f: Timer Counter 4 */ +# define SAM_TC5_BASE 0x40010080 /* 0x40010080-0x400100bf: Timer Counter 5 */ + /* 0x400100c0-0x40013fff Reserved */ +#define SAM_TC678_BASE 0x40014000 /* 0x40014000-0x40017fff: Timer Counters 6-8 */ +# define SAM_TC6_BASE 0x40014000 /* 0x40014000-0x4001403f: Timer Counter 6 */ +# define SAM_TC7_BASE 0x40014040 /* 0x40014040-0x4001407f: Timer Counter 7 */ +# define SAM_TC8_BASE 0x40014080 /* 0x40014080-0x400140bf: Timer Counter 8 */ + /* 0x400140c0-0x40017fff: Reserved */ +#define SAM_TWIHS0_BASE 0x40018000 /* 0x40018000-0x4001bfff: Two-Wire Interface 0 (TWIHS0) */ +#define SAM_TWIHS1_BASE 0x4001c000 /* 0x4001c000-0x4001ffff: Two-Wire Interface 1 (TWIHS1) */ +#define SAM_PWM0_BASE 0x40020000 /* 0x40020000-0x40023fff: Pulse Width Modulation 0 */ +#define SAM_USART0_BASE 0x40024000 /* 0x40024000-0x40023fff: USART0 */ +#define SAM_USART1_BASE 0x40028000 /* 0x40028000-0x4002bfff: USART1 */ +#define SAM_USART2_BASE 0x4002c000 /* 0x4002c000-0x4002ffff: USART12*/ +#define SAM_MCAN0_BASE 0x40030000 /* 0x40030000-0x40033fff: Controller Area Network 0 (MCAN0) */ +#define SAM_MCAN1_BASE 0x40034000 /* 0x40034000-0x40037fff: Controller Area Network 1 (MCAN1) */ +#define SAM_USBHS_BASE 0x40038000 /* 0x40038000-0x4003bfff: USB High-Speed (USBHS) */ +#define SAM_AFEC0_BASE 0x4003c000 /* 0x4003c000-0x4003ffff: Analog Front End 0 (AFEC0) */ +#define SAM_DACC_BASE 0x40040000 /* 0x40040000-0x40043fff: Digital To Analog Converter (DACC) */ +#define SAM_ACC_BASE 0x40044000 /* 0x40044000-0x40047fff: Analog Comparator (ACC) */ +#define SAM_ICM_BASE 0x40048000 /* 0x40048000-0x4004bfff: Integrity Check Monitor (ICM) */ +#define SAM_ISI_BASE 0x4004c000 /* 0x4004c000-0x4004ffff: Image Sensor Interface (ISI) */ +#define SAM_EMAC0_BASE 0x40050000 /* 0x40050000-0x40053fff: EMAC0 (aka GMAC) */ +#define SAM_TC901_BASE 0x40054000 /* 0x40054000-0x40054fff: Timer Counters 9-11 */ +# define SAM_TC9_BASE 0x40054000 /* 0x40054000-0x4005403f: Timer Counter 9 */ +# define SAM_TC10_BASE 0x40054040 /* 0x40054040-0x4005407f: Timer Counter 10 */ +# define SAM_TC11_BASE 0x40054080 /* 0x40054080-0x400540bf: Timer Counter 11 */ + /* 0x400540c0-0x40057fff: Reserved */ +#define SAM_SPI1_BASE 0x40058000 /* 0x40058000-0x4005bfff: Serial Peripheral Interface 1 */ +#define SAM_PWM1_BASE 0x4005c000 /* 0x4005c000-0x4005ffff: Pulse Width Modulation 1 */ +#define SAM_TWIHS2_BASE 0x40060000 /* 0x40060000-0x40063fff: Two-Wire Interface 2 (TWIHS2) */ +#define SAM_AFEC1_BASE 0x40064000 /* 0x40064000-0x40067fff: Analog Front End 1 (AFEC1) */ + /* 0x40068000-0x4006bfff: Reserved */ +#define SAM_AES_BASE 0x4006c000 /* 0x4006c000-0x4006ffff: AES */ +#define SAM_TRNG_BASE 0x40070000 /* 0x40070000-0x40073fff: True Random Number Generator (TRNG) */ +#define SAM_BRAM_BASE 0x40074000 /* 0x40074000-0x40077fff: Backup SRAM (BRAM) */ +#define SAM_XDMAC_BASE 0x40078000 /* 0x40078000-0x4007bfff: Central DMA controller (XDMAC) */ +#define SAM_QSPI_BASE 0x4007c000 /* 0x4007c000-0x4007ffff: Quad SPI (QSPI) */ +#define SAM_SMC_BASE 0x40080000 /* 0x40080000-0x40083fff: Static Memory Controller (SMC) */ +#define SAM_SDRAMC_BASE 0x40084000 /* 0x40084000-0x40087fff: SDRAM Controller (SDRAMC) */ +#define SAM_MATRIX_BASE 0x40088000 /* 0x40088000-0x400e03ff: MATRIX */ +#define SAM_UTMI_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: USB Transmitter Macrocell Interface (UTMI) */ +#define SAM_PMC_BASE 0x400e0600 /* 0x400e0600-0x400e07ff: Power Management Controller (PMC) */ +#define SAM_UART0_BASE 0x400e0800 /* 0x400e0800-0x400e093f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0940 /* 0x400e0940-0x400e09ff: CHIP ID */ +#define SAM_UART1_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: UART 1 */ +#define SAM_EEFC_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Embedded Flash Controller (EEFC) */ +#define SAM_PIO_BASE 0x400e0e00 /* 0x400e0e00-0x400e13ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0e00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1200 /* 0x400e1200-0x400e13ff: Parallel I/O Controller C */ +# define SAM_PIOD_BASE 0x400e1400 /* 0x400e1400-0x400e15ff: Parallel I/O Controller D */ +# define SAM_PIOE_BASE 0x400e1600 /* 0x400e1600-0x400e17ff: Parallel I/O Controller E */ +#define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e1bff: System Controller */ +# define SAM_RSTC_BASE 0x400e1800 /* 0x400e1800-0x400e180f: Reset Controller (RSTC) */ +# define SAM_SUPC_BASE 0x400e1810 /* 0x400e1810-0x400e182f: Supply Controller (SUPC) */ +# define SAM_RTT_BASE 0x400e1830 /* 0x400e1830-0x400e184f: Real Time Timer (RTT) */ +# define SAM_WDT_BASE 0x400e1850 /* 0x400e1850-0x400e185f: Watchdog Timer (WDT) */ +# define SAM_RTC_BASE 0x400e1860 /* 0x400e1860-0x400e188f: Real Time Clock (RTC) */ +# define SAM_GPBR_BASE 0x400e1890 /* 0x400e1890-0x400e18ff: GPBR */ +# define SAM_SYSC_BASE 0x400e18e0 /* 0x400e1890-0x400e18ff: System Controller Common */ +# define SAM_RSWDT_BASE 0x400e1900 /* 0x400e1900-0x400e19ff: Reinforced Safety Watchdog Timer (RSWDT) */ +#define SAM_UART2_BASE 0x400e1a00 /* 0x400e1a00-0x400e1bff: UART 2 */ +#define SAM_UART3_BASE 0x400e1c00 /* 0x400e1c00-0x400e1dff: UART 3 */ +#define SAM_UART4_BASE 0x400e1e00 /* 0x400e1e00-0x400e1fff: UART 4 */ + /* 0x400e2000-0x5fffffff: Reserved */ +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x7fffffff: EBI Chip selects */ +# define SAM_EXTCSn_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: EBI Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: EBI Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: EBI Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x6fffffff: EBI Chip select 3 */ +#define SAM_SDRAMCS_BASE 0x70000000 /* 0x70000000-0x7fffffff: SDRAM chip select */ + +/* QSPI memory region */ + +#define SAM_QSPIMEM_SIZE 0x20000000 /* 0x80000000-0x9fffffff: QSPI memory */ + +/* System memory region */ + +#define SAM_PRIVPERIPH_BASE 0xe0000000 /* 0xe0000000-0xe00fffff: Private peripheral bus */ +#define SAM_VENDOR_BASE 0xe0100000 /* 0ex0100000-0xffffffff: Vendor-specific memory */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM4S_MEMORYMAP_H */ diff --git a/arch/arm/src/samv7/chip/same70_pinmap.h b/arch/arm/src/samv7/chip/same70_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..160963c00e8a5aa1feb4b62d24d4f403b3779157 --- /dev/null +++ b/arch/arm/src/samv7/chip/same70_pinmap.h @@ -0,0 +1,570 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/same70_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAME70_PINMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAME70_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions + * + * These are mostly for reference and are not in pin configuration. + */ + +#define GPIO_AFE0_AD0 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_AFE0_AD1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_AFE0_AD2 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_AFE0_AD3 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_AFE0_AD4 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_AFE0_AD5 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_AFE0_AD6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_AFE0_AD7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_AFE0_AD8 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_AFE0_AD9 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_AFE0_AD10 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN0) + +#define GPIO_AFE1_AD0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_AFE1_AD1 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_AFE1_AD2 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_AFE1_AD3 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_AFE1_AD4 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_AFE1_AD5 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_AFE1_AD6 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_AFE1_AD7 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_AFE1_AD8 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_AFE1_AD9 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_AFE1_AD10 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_AFE1_AD11 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN0) + +#define GPIO_DAC0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_DAC1 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN0) + +#define GPIO_ERASE (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN12) + +#define GPIO_PIODC0 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_PIODC1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_PIODC2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_PIODC3 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PIODC4 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_PIODC5 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PIODC6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PIODC7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PIODCCLK (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_PIODCEN1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PIODCEN2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN21) + +#define GPIO_RTCOUT0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_RTCOUT1 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN1) + +#define GPIO_SWCLK (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_SWDIO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_TCK (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_TDI (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_TDO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TMS (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_TRACESWO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) + +#define GPIO_WKUP0 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_WKUP1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_WKUP2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_WKUP3 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_WKUP4 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_WKUP5 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_WKUP6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_WKUP7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_WKUP8 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_WKUP9 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_WKUP10 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_WKUP11 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_WKUP12 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_WKUP13 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) + +#define GPIO_XIN (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN9) +#define GPIO_XIN32 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_XOUT (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN8) +#define GPIO_XOUT32 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN8) + +/* Peripheral Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the UART1 TX output PCK0 on PA4, then the following definition + * should appear in the board.h header file for that board: + * + * #define GPIO_UART1_TXD GPIO_UART1_TXD_1 + * + * The driver will then automatically configure PA6 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog Front End (AFE) */ + +#define GPIO_AFE0_ADTRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_AFE1_ADTRG (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) + +/* MCAN */ + +#define GPIO_MCAN0_RX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_MCAN0_TX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_MCAN1_RX_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_MCAN1_RX_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_MCAN1_TX_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_MCAN1_TX_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) + +/* Digital-to-Analog Convert (DAC) */ + +#define GPIO_DAC_DATRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) + +/* Ethernet MAC Controller (EMAC) */ + +#define GPIO_EMAC0_COL (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_EMAC0_CRS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_EMAC0_MDC (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_EMAC0_MDIO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_EMAC0_RX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_EMAC0_RX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_EMAC0_RX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_EMAC0_RX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_EMAC0_RXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) +#define GPIO_EMAC0_RXDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_EMAC0_RXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_EMAC0_TSUCOMP_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_EMAC0_TSUCOMP_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_EMAC0_TSUCOMP_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_EMAC0_TSUCOMP_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_EMAC0_TX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_EMAC0_TX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_EMAC0_TX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_EMAC0_TX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_EMAC0_TXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_EMAC0_TXEN (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_EMAC0_TXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) + +/* Image Sensor Interface (ISI) */ + +#define GPIO_ISI_D0 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_ISI_D1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_ISI_D2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_ISI_D3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_ISI_D4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_ISI_D5 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_ISI_D6 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_ISI_D7 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_ISI_D8 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_ISI_D9 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_ISI_D10 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_ISI_D11 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) +#define GPIO_ISI_HSYNC (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_ISI_PCK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_ISI_VSYNC (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) + +/* High-Speed Multimedia Card Interface (HSMCI) */ + +#define GPIO_MCI0_CK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_MCI0_CDA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_MCI0_DA0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_MCI0_DA1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_MCI0_DA2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_MCI0_DA3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_PCK0_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PCK0_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PCK2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_PCK2_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_PCK2_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWMC0_EXTRG0 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_PWMC0_EXTRG1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_PWMC0_FI0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWMC0_FI1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_PWMC0_FI2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_PWMC0_H0_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWMC0_H0_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_PWMC0_H0_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_PWMC0_H0_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWMC0_H0_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWMC0_H0_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_PWMC0_H1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_PWMC0_H1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_PWMC0_H1_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_PWMC0_H1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWMC0_H1_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PWMC0_H2_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_PWMC0_H2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWMC0_H2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_PWMC0_H2_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_PWMC0_H2_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWMC0_H3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_PWMC0_H3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWMC0_H3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_PWMC0_H3_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_PWMC0_H3_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWMC0_H3_6 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PWMC0_L0_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PWMC0_L0_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_PWMC0_L0_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWMC0_L0_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_PWMC0_L0_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_PWMC0_L0_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_PWMC0_L1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWMC0_L1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_PWMC0_L1_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWMC0_L1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_PWMC0_L1_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWMC0_L2_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWMC0_L2_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWMC0_L2_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_PWMC0_L2_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWMC0_L2_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWMC0_L2_6 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_PWMC0_L3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_PWMC0_L3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_PWMC0_L3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWMC0_L3_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_PWMC0_L3_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) + +#define GPIO_PWMC1_EXTRG0 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWMC1_EXTRG1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PWMC1_FI0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PWMC1_FI1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_PWMC1_FI2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_PWMC1_H0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_PWMC1_H0_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWMC1_H1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_PWMC1_H1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWMC1_H2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_PWMC1_H2_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PWMC1_H3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_PWMC1_H3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_PWMC1_L0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_PWMC1_L0_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWMC1_L1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_PWMC1_L1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWMC1_L2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_PWMC1_L2_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWMC1_L3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_PWMC1_L3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) + +/* Quad IO SPI (QSPI) */ + +#define GPIO_QSPI_CS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_QSPI_IO0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_QSPI_IO1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_QSPI_IO2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_QSPI_IO3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) +#define GPIO_QSPI_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +/* SDR-SDRAM Controller (SDRAMC) */ + +#define GPIO_SDRAMC_BA0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SDRAMC_BA1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SDRAMC_CAS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) +#define GPIO_SDRAMC_A10_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SDRAMC_A10_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_SDRAMC_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_SDRAMC_CKE (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) +#define GPIO_SDRAMC_CS_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SDRAMC_CS_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SDRAMC_RAS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_SDRAMC_WE (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN29) + +/* Static Memory Controller (SMC). Many pins shared with SDRAMC */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_SMC_A14 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A15 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SMC_A16 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SMC_A17 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SMC_A18 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SMC_A19 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SMC_A20 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SMC_A21 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_A22 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_A23 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_D8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN0) +#define GPIO_SMC_D9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN1) +#define GPIO_SMC_D10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_SMC_D11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_SMC_D12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_SMC_D13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_SMC_D14 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SMC_D15 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_SMC_NANDALE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_NANDCLE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NANDOE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_NANDWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_NBS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_NBS1 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_SMC_NCS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_NCS1_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_NCS1_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SMC_NCS2 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SMC_NCS3_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_NCS3_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_SMC_NRD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_NWAIT (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_SMC_NWR0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_SMC_NWR1 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN15) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_SPI0_MOSI (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_SPI0_SPCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) + +#define GPIO_SPI0_NSS (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_SPI0_NPCS2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_SPI0_NPCS3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) + +#define GPIO_SPI1_MISO (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SPI1_MOSI (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SPI1_SPCK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) + +#define GPIO_SPI1_NSS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SPI1_NPCS0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SPI1_NPCS1_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SPI1_NPCS1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_SPI1_NPCS2_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SPI1_NPCS2_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_SPI1_NPCS3_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SPI1_NPCS3_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) + +/* Synchronous Serial Controller (SSC) */ + +#define GPIO_SSC0_RD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SSC0_RF (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_SSC0_RK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SSC0_TD_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_SSC0_TD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_SSC0_TD_3 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_SSC0_TF (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_SSC0_TK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC0_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_TC0_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_TC1_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_TC1_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_TC1_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_TC2_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_TC2_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_TC2_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_TC3_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC3_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_TC3_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_TC4_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC4_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC4_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC5_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_TC5_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC5_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_TC6_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_TC6_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_TC6_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_TC7_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_TC7_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_TC7_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_TC8_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_TC8_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_TC8_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_TC9_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_TC9_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN0) +#define GPIO_TC9_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN1) +#define GPIO_TC10_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_TC10_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_TC10_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_TC11_TCLK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_TC11_TIOA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_TC11_TIOB (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) + +/* Trace Debug Port */ + +#define GPIO_TRACE_CLK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_TRACE_D0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_TRACE_D1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_TRACE_D2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_TRACE_D3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) + +/* Two Wire Interface (TWIHS) */ + +#define GPIO_TWIHS0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TWIHS0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TWIHS1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TWIHS1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_TWIHS2_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_TWIHS2_D (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) + +#define GPIO_UART1_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_UART1_TXD_1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_UART1_TXD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_UART1_TXD_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) + +#define GPIO_UART2_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_UART2_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) + +#define GPIO_UART3_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_UART3_TXD_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_UART3_TXD_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) + +#define GPIO_UART4_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_UART4_TXD_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_UART4_TXD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_USART0_DCD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_USART0_DSR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_USART0_DTR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_USART0_RI (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_USART0_RTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_USART0_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_USART0_SCK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_USART0_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) + +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_USART1_DCD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_USART1_DSR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_USART1_DTR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_USART1_LONCOL (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_USART1_RI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_USART1_TXD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) + +#define GPIO_USART2_CTS (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_USART2_DCD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_USART2_DSR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_USART2_DTR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_USART2_RI (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_USART2_RTS (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_USART2_RXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_USART2_SCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) +#define GPIO_USART2_TXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAME70_PINMAP_H */ diff --git a/arch/arm/src/samv7/chip/samv71_memorymap.h b/arch/arm/src/samv7/chip/samv71_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..97742117a98b5f6e2cdfac6eefd1d8032c96f2c9 --- /dev/null +++ b/arch/arm/src/samv7/chip/samv71_memorymap.h @@ -0,0 +1,201 @@ +/************************************************************************************************ + * arch/arm/src/samv7/chip/samv71_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAMV71_MEMORYMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAMV71_MEMORYMAP_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Address regions */ + +#define SAM_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: Code space */ +#define SAM_INTSRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: Internal SRAM */ +#define SAM_PERIPHERALS_BASE 0x40000000 /* 0x40000000-0x5fffffff: Peripherals */ +#define SAM_MEMORY_BASE 0x60000000 /* 0x60000000-0x7fffffff: Memories */ +#define SAM_QSPIMEM_BASE 0x80000000 /* 0x80000000-0x9fffffff: QSPI memory */ +#define SAM_AXIMX_BASE 0xa0000000 /* 0xa0000000-0x9fffffff: AXIMX */ +#define SAM_USBHSRAM_BASE 0xa0100000 /* 0xa0100000-0xa01fffff: USBHS RAM */ + /* 0xa0200000-0xdfffffff: Reserved */ +#define SAM_SYSTEM_BASE 0xe0000000 /* 0xe0000000-0xffffffff: System */ + +/* Code memory region */ + +#define SAM_BOOTMEMORY_BASE 0x00000000 /* 0x00000000-0x00ffffff: ITCM or Boot Memory */ +#define SAM_INTFLASH_BASE 0x00400000 /* 0x00400000-0x007fffff: Internal FLASH */ +#define SAM_INTROM_BASE 0x00800000 /* 0x00800000-0x00bfffff: Internal ROM */ + /* 0x00c00000-0x1fffffff: Reserved */ +/* Internal SRAM memory region */ + +#define SAM_DTCM_BASE 0x20000000 /* 0x20000000-0x203fffff: DTCM */ +#define SAM_SRAM_BASE 0x20400000 /* 0x20400000-0x20bfffff: SRAM */ + /* 0x20c00000-0x3fffffff: Reserved */ +/* Peripherals address region */ + +#define SAM_HSMCI0_BASE 0x40000000 /* 0x40000000-0x40003fff: High Speed Multimedia Card Interface */ +#define SAM_SSC0_BASE 0x40004000 /* 0x40004000-0x40007fff: Serial Synchronous Controller */ +#define SAM_SPI0_BASE 0x40008000 /* 0x40008000-0x4000bfff: Serial Peripheral Interface 0 */ +#define SAM_TC012_BASE 0x4000c000 /* 0x4000c000-0x4000ffff: Timer Counters 0-2 */ +# define SAM_TC0_BASE 0x4000c000 /* 0x4000c000-0x4000c03f: Timer Counter 0 */ +# define SAM_TC1_BASE 0x4000c040 /* 0x4000c040-0x4000c07f: Timer Counter 1 */ +# define SAM_TC2_BASE 0x4000c080 /* 0x4000c080-0x4000c0bf: Timer Counter 2 */ + /* 0x4000c0c0-0x4000ffff Reserved */ +#define SAM_TC345_BASE 0x40010000 /* 0x40010000-0x40013fff: Timer Counters 3-5 */ +# define SAM_TC3_BASE 0x40010000 /* 0x40010000-0x4001003f: Timer Counter 3 */ +# define SAM_TC4_BASE 0x40010040 /* 0x40010040-0x4001007f: Timer Counter 4 */ +# define SAM_TC5_BASE 0x40010080 /* 0x40010080-0x400100bf: Timer Counter 5 */ + /* 0x400100c0-0x40013fff Reserved */ +#define SAM_TC678_BASE 0x40014000 /* 0x40014000-0x40017fff: Timer Counters 6-8 */ +# define SAM_TC6_BASE 0x40014000 /* 0x40014000-0x4001403f: Timer Counter 6 */ +# define SAM_TC7_BASE 0x40014040 /* 0x40014040-0x4001407f: Timer Counter 7 */ +# define SAM_TC8_BASE 0x40014080 /* 0x40014080-0x400140bf: Timer Counter 8 */ + /* 0x400140c0-0x40017fff: Reserved */ +#define SAM_TWIHS0_BASE 0x40018000 /* 0x40018000-0x4001bfff: Two-Wire Interface 0 (TWIHS0) */ +#define SAM_TWIHS1_BASE 0x4001c000 /* 0x4001c000-0x4001ffff: Two-Wire Interface 1 (TWIHS1) */ +#define SAM_PWM0_BASE 0x40020000 /* 0x40020000-0x40023fff: Pulse Width Modulation 0 */ +#define SAM_USART0_BASE 0x40024000 /* 0x40024000-0x40023fff: USART0 */ +#define SAM_USART1_BASE 0x40028000 /* 0x40028000-0x4002bfff: USART1 */ +#define SAM_USART2_BASE 0x4002c000 /* 0x4002c000-0x4002ffff: USART12*/ +#define SAM_MCAN0_BASE 0x40030000 /* 0x40030000-0x40033fff: Controller Area Network 0 (MCAN0) */ +#define SAM_MCAN1_BASE 0x40034000 /* 0x40034000-0x40037fff: Controller Area Network 1 (MCAN1) */ +#define SAM_USBHS_BASE 0x40038000 /* 0x40038000-0x4003bfff: USB High-Speed (USBHS) */ +#define SAM_AFEC0_BASE 0x4003c000 /* 0x4003c000-0x4003ffff: Analog Front End 0 (AFEC0) */ +#define SAM_DACC_BASE 0x40040000 /* 0x40040000-0x40043fff: Digital To Analog Converter (DACC) */ +#define SAM_ACC_BASE 0x40044000 /* 0x40044000-0x40047fff: Analog Comparator (ACC) */ +#define SAM_ICM_BASE 0x40048000 /* 0x40048000-0x4004bfff: Integrity Check Monitor (ICM) */ +#define SAM_ISI_BASE 0x4004c000 /* 0x4004c000-0x4004ffff: Image Sensor Interface (ISI) */ +#define SAM_EMAC0_BASE 0x40050000 /* 0x40050000-0x40053fff: EMAC0 (aka GMAC) */ +#define SAM_TC901_BASE 0x40054000 /* 0x40054000-0x40054fff: Timer Counters 9-11 */ +# define SAM_TC9_BASE 0x40054000 /* 0x40054000-0x4005403f: Timer Counter 9 */ +# define SAM_TC10_BASE 0x40054040 /* 0x40054040-0x4005407f: Timer Counter 10 */ +# define SAM_TC11_BASE 0x40054080 /* 0x40054080-0x400540bf: Timer Counter 11 */ + /* 0x400540c0-0x40057fff: Reserved */ +#define SAM_SPI1_BASE 0x40058000 /* 0x40058000-0x4005bfff: Serial Peripheral Interface 1 */ +#define SAM_PWM1_BASE 0x4005c000 /* 0x4005c000-0x4005ffff: Pulse Width Modulation 1 */ +#define SAM_TWIHS2_BASE 0x40060000 /* 0x40060000-0x40063fff: Two-Wire Interface 2 (TWIHS2) */ +#define SAM_AFEC1_BASE 0x40064000 /* 0x40064000-0x40067fff: Analog Front End 1 (AFEC1) */ +#define SAM_MLB_BASE 0x40068000 /* 0x40068000-0x4006bfff: Media LB Interface (MLB) */ +#define SAM_AES_BASE 0x4006c000 /* 0x4006c000-0x4006ffff: AES */ +#define SAM_TRNG_BASE 0x40070000 /* 0x40070000-0x40073fff: True Random Number Generator (TRNG) */ +#define SAM_BRAM_BASE 0x40074000 /* 0x40074000-0x40077fff: Backup SRAM (BRAM) */ +#define SAM_XDMAC_BASE 0x40078000 /* 0x40078000-0x4007bfff: Central DMA controller (XDMAC) */ +#define SAM_QSPI_BASE 0x4007c000 /* 0x4007c000-0x4007ffff: Quad SPI (QSPI) */ +#define SAM_SMC_BASE 0x40080000 /* 0x40080000-0x40083fff: Static Memory Controller (SMC) */ +#define SAM_SDRAMC_BASE 0x40084000 /* 0x40084000-0x40087fff: SDRAM Controller (SDRAMC) */ +#define SAM_MATRIX_BASE 0x40088000 /* 0x40088000-0x400e03ff: MATRIX */ +#define SAM_UTMI_BASE 0x400e0400 /* 0x400e0400-0x400e05ff: USB Transmitter Macrocell Interface (UTMI) */ +#define SAM_PMC_BASE 0x400e0600 /* 0x400e0600-0x400e07ff: Power Management Controller (PMC) */ +#define SAM_UART0_BASE 0x400e0800 /* 0x400e0800-0x400e093f: UART 0 */ +#define SAM_CHIPID_BASE 0x400e0940 /* 0x400e0940-0x400e09ff: CHIP ID */ +#define SAM_UART1_BASE 0x400e0a00 /* 0x400e0a00-0x400e0bff: UART 1 */ +#define SAM_EEFC_BASE 0x400e0c00 /* 0x400e0c00-0x400e0dff: Embedded Flash Controller (EEFC) */ +#define SAM_PIO_BASE 0x400e0e00 /* 0x400e0e00-0x400e13ff: Parallel I/O Controllers */ +# define SAM_PION_BASE(n) (0x400e0e00 + ((n) << 9)) +# define SAM_PIOA_BASE 0x400e0e00 /* 0x400e0e00-0x400e0fff: Parallel I/O Controller A */ +# define SAM_PIOB_BASE 0x400e1000 /* 0x400e1000-0x400e11ff: Parallel I/O Controller B */ +# define SAM_PIOC_BASE 0x400e1200 /* 0x400e1200-0x400e13ff: Parallel I/O Controller C */ +# define SAM_PIOD_BASE 0x400e1400 /* 0x400e1400-0x400e15ff: Parallel I/O Controller D */ +# define SAM_PIOE_BASE 0x400e1600 /* 0x400e1600-0x400e17ff: Parallel I/O Controller E */ +#define SAM_SYSCTRLR_BASE 0x400e0000 /* 0x400e0000-0x400e1bff: System Controller */ +# define SAM_RSTC_BASE 0x400e1800 /* 0x400e1800-0x400e180f: Reset Controller (RSTC) */ +# define SAM_SUPC_BASE 0x400e1810 /* 0x400e1810-0x400e182f: Supply Controller (SUPC) */ +# define SAM_RTT_BASE 0x400e1830 /* 0x400e1830-0x400e184f: Real Time Timer (RTT) */ +# define SAM_WDT_BASE 0x400e1850 /* 0x400e1850-0x400e185f: Watchdog Timer(WDT) */ +# define SAM_RTC_BASE 0x400e1860 /* 0x400e1860-0x400e188f: Real Time Clock (RTC) */ +# define SAM_GPBR_BASE 0x400e1890 /* 0x400e1890-0x400e18ff: GPBR */ +# define SAM_SYSC_BASE 0x400e18e0 /* 0x400e1890-0x400e18ff: System Controller Common */ +# define SAM_RSWDT_BASE 0x400e1900 /* 0x400e1900-0x400e19ff: Reinforced Safety Watchdog Timer (RSWDT) */ +#define SAM_UART2_BASE 0x400e1a00 /* 0x400e1a00-0x400e1bff: UART 2 */ +#define SAM_UART3_BASE 0x400e1c00 /* 0x400e1c00-0x400e1dff: UART 3 */ +#define SAM_UART4_BASE 0x400e1e00 /* 0x400e1e00-0x400e1fff: UART 4 */ + /* 0x400e2000-0x5fffffff: Reserved */ +/* External RAM memory region */ + +#define SAM_EXTCS_BASE 0x60000000 /* 0x60000000-0x7fffffff: EBI Chip selects */ +# define SAM_EXTCSn_BASE(n) (0x60000000 + ((n) << 24)) +# define SAM_EXTCS0_BASE 0x60000000 /* 0x60000000-0x60ffffff: EBI Chip select 0 */ +# define SAM_EXTCS1_BASE 0x61000000 /* 0x61000000-0x601fffff: EBI Chip select 1 */ +# define SAM_EXTCS2_BASE 0x62000000 /* 0x62000000-0x62ffffff: EBI Chip select 2 */ +# define SAM_EXTCS3_BASE 0x63000000 /* 0x63000000-0x6fffffff: EBI Chip select 3 */ +#define SAM_SDRAMCS_BASE 0x70000000 /* 0x70000000-0x7fffffff: SDRAM chip select */ + +/* QSPI memory region */ + +#define SAM_QSPIMEM_SIZE 0x20000000 /* 0x80000000-0x9fffffff: QSPI memory */ + +/* System memory region */ + +#define SAM_PRIVPERIPH_BASE 0xe0000000 /* 0xe0000000-0xe00fffff: Private peripheral bus */ +#define SAM_VENDOR_BASE 0xe0100000 /* 0ex0100000-0xffffffff: Vendor-specific memory */ + +/************************************************************************************************ + * Public Types + ************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAM4S_MEMORYMAP_H */ diff --git a/arch/arm/src/samv7/chip/samv71_pinmap.h b/arch/arm/src/samv7/chip/samv71_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..497035e70c3d908c794fcb714118ee6b7b37222e --- /dev/null +++ b/arch/arm/src/samv7/chip/samv71_pinmap.h @@ -0,0 +1,576 @@ +/************************************************************************************ + * arch/arm/src/samv7/chip/samv71_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_CHIP_SAMV71_PINMAP_H +#define __ARCH_ARM_SRC_SAMV7_CHIP_SAMV71_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "sam_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO pin definitions *************************************************************/ +/* Alternate Pin Functions + * + * These are mostly for reference and are not in pin configuration. + */ + +#define GPIO_AFE0_AD0 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_AFE0_AD1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_AFE0_AD2 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_AFE0_AD3 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_AFE0_AD4 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_AFE0_AD5 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_AFE0_AD6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_AFE0_AD7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_AFE0_AD8 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_AFE0_AD9 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_AFE0_AD10 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN0) + +#define GPIO_AFE1_AD0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_AFE1_AD1 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_AFE1_AD2 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_AFE1_AD3 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_AFE1_AD4 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_AFE1_AD5 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_AFE1_AD6 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_AFE1_AD7 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_AFE1_AD8 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_AFE1_AD9 (GPIO_ALTERNATE | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_AFE1_AD10 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_AFE1_AD11 (GPIO_ALTERNATE | GPIO_PORT_PIOE | GPIO_PIN0) + +#define GPIO_DAC0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_DAC1 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN0) + +#define GPIO_ERASE (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN12) + +#define GPIO_PIODC0 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_PIODC1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_PIODC2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_PIODC3 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PIODC4 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_PIODC5 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PIODC6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PIODC7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PIODCCLK (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_PIODCEN1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PIODCEN2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN21) + +#define GPIO_RTCOUT0 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_RTCOUT1 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN1) + +#define GPIO_SWCLK (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_SWDIO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_TCK (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN7) +#define GPIO_TDI (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_TDO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TMS (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN6) +#define GPIO_TRACESWO (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) + +#define GPIO_WKUP0 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_WKUP1 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_WKUP2 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_WKUP3 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_WKUP4 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_WKUP5 (GPIO_ALTERNATE | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_WKUP6 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_WKUP7 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_WKUP8 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_WKUP9 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_WKUP10 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_WKUP11 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_WKUP12 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_WKUP13 (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN5) + +#define GPIO_XIN (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN9) +#define GPIO_XIN32 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_XOUT (GPIO_ALTERNATE | GPIO_PORT_PIOB | GPIO_PIN8) +#define GPIO_XOUT32 (GPIO_ALTERNATE | GPIO_PORT_PIOA | GPIO_PIN8) + +/* Peripheral Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if we + * wanted the UART1 TX output PCK0 on PA4, then the following definition + * should appear in the board.h header file for that board: + * + * #define GPIO_UART1_TXD GPIO_UART1_TXD_1 + * + * The driver will then automatically configure PA6 as the PCK0 pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* Analog Front End (AFE) */ + +#define GPIO_AFE0_ADTRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_AFE1_ADTRG (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) + +/* MCAN */ + +#define GPIO_MCAN0_RX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_MCAN0_TX (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_MCAN1_RX_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_MCAN1_RX_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_MCAN1_TX_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_MCAN1_TX_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) + +/* Digital-to-Analog Convert (DAC) */ + +#define GPIO_DAC_DATRG (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) + +/* Ethernet MAC Controller (EMAC) */ + +#define GPIO_EMAC0_COL (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_EMAC0_CRS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_EMAC0_MDC (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_EMAC0_MDIO (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_EMAC0_RX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_EMAC0_RX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_EMAC0_RX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_EMAC0_RX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_EMAC0_RXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) +#define GPIO_EMAC0_RXDV (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_EMAC0_RXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_EMAC0_TSUCOMP_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_EMAC0_TSUCOMP_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_EMAC0_TSUCOMP_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_EMAC0_TSUCOMP_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_EMAC0_TX0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_EMAC0_TX1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_EMAC0_TX2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_EMAC0_TX3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_EMAC0_TXCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_EMAC0_TXEN (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_EMAC0_TXER (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) + +/* Image Sensor Interface (ISI) */ + +#define GPIO_ISI_D0 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_ISI_D1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_ISI_D2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_ISI_D3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_ISI_D4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_ISI_D5 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_ISI_D6 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_ISI_D7 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_ISI_D8 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_ISI_D9 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_ISI_D10 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_ISI_D11 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) +#define GPIO_ISI_HSYNC (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_ISI_PCK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_ISI_VSYNC (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) + +/* High-Speed Multimedia Card Interface (HSMCI) */ + +#define GPIO_MCI0_CK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_MCI0_CDA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_MCI0_DA0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_MCI0_DA1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_MCI0_DA2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_MCI0_DA3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) + +/* MediaLB Interface (MLB) */ + +#define GPIO_MLB_CLK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_MLB_DAT (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_MLB_SIG (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) + +/* Programmable Clock Output */ + +#define GPIO_PCK0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) +#define GPIO_PCK0_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PCK0_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PCK1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PCK1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PCK2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PCK2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PCK2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_PCK2_4 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_PCK2_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) + +/* Pulse Width Modulation (PWM) */ + +#define GPIO_PWMC0_EXTRG0 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_PWMC0_EXTRG1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_PWMC0_FI0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_PWMC0_FI1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_PWMC0_FI2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN9) +#define GPIO_PWMC0_H0_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_PWMC0_H0_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_PWMC0_H0_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_PWMC0_H0_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWMC0_H0_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWMC0_H0_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN11) +#define GPIO_PWMC0_H1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN2) +#define GPIO_PWMC0_H1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) +#define GPIO_PWMC0_H1_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_PWMC0_H1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWMC0_H1_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_PWMC0_H2_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) +#define GPIO_PWMC0_H2_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWMC0_H2_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_PWMC0_H2_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_PWMC0_H2_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_PWMC0_H3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_PWMC0_H3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWMC0_H3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN7) +#define GPIO_PWMC0_H3_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_PWMC0_H3_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_PWMC0_H3_6 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_PWMC0_L0_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_PWMC0_L0_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_PWMC0_L0_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_PWMC0_L0_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_PWMC0_L0_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_PWMC0_L0_6 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_PWMC0_L1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN12) +#define GPIO_PWMC0_L1_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_PWMC0_L1_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_PWMC0_L1_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_PWMC0_L1_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_PWMC0_L2_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWMC0_L2_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_PWMC0_L2_3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_PWMC0_L2_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_PWMC0_L2_5 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_PWMC0_L2_6 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_PWMC0_L3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) +#define GPIO_PWMC0_L3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_PWMC0_L3_3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_PWMC0_L3_4 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_PWMC0_L3_5 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) + +#define GPIO_PWMC1_EXTRG0 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN30) +#define GPIO_PWMC1_EXTRG1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_PWMC1_FI0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_PWMC1_FI1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_PWMC1_FI2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_PWMC1_H0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_PWMC1_H0_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_PWMC1_H1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_PWMC1_H1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) +#define GPIO_PWMC1_H2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_PWMC1_H2_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_PWMC1_H3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN8) +#define GPIO_PWMC1_H3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_PWMC1_L0_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_PWMC1_L0_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_PWMC1_L1_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_PWMC1_L1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_PWMC1_L2_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_PWMC1_L2_2 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_PWMC1_L3_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_PWMC1_L3_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) + +/* Quad IO SPI (QSPI) */ + +#define GPIO_QSPI_CS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN11) +#define GPIO_QSPI_IO0 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN13) +#define GPIO_QSPI_IO1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN12) +#define GPIO_QSPI_IO2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN17) +#define GPIO_QSPI_IO3 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) +#define GPIO_QSPI_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN14) + +/* SDR-SDRAM Controller (SDRAMC) */ + +#define GPIO_SDRAMC_BA0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SDRAMC_BA1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SDRAMC_CAS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) +#define GPIO_SDRAMC_A10_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SDRAMC_A10_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN13) +#define GPIO_SDRAMC_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN23) +#define GPIO_SDRAMC_CKE (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN14) +#define GPIO_SDRAMC_CS_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SDRAMC_CS_2 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SDRAMC_RAS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) +#define GPIO_SDRAMC_WE (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN29) + +/* Static Memory Controller (SMC). Many pins shared with SDRAMC */ + +#define GPIO_SMC_A0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_A1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19) +#define GPIO_SMC_A2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN20) +#define GPIO_SMC_A3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN21) +#define GPIO_SMC_A4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN22) +#define GPIO_SMC_A5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_SMC_A6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_SMC_A7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SMC_A8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SMC_A9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SMC_A10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SMC_A11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SMC_A12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SMC_A13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_SMC_A14 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN18) +#define GPIO_SMC_A15 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN19) +#define GPIO_SMC_A16 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN20) +#define GPIO_SMC_A17 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_SMC_A18 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_SMC_A19 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_SMC_A20 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_SMC_A21 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_A22 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_A23 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_SMC_D0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN0) +#define GPIO_SMC_D1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN1) +#define GPIO_SMC_D2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN2) +#define GPIO_SMC_D3 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN3) +#define GPIO_SMC_D4 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN4) +#define GPIO_SMC_D5 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_SMC_D6 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_SMC_D7 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_SMC_D8 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN0) +#define GPIO_SMC_D9 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN1) +#define GPIO_SMC_D10 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_SMC_D11 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_SMC_D12 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_SMC_D13 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_SMC_D14 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_SMC_D15 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_SMC_NANDALE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN16) +#define GPIO_SMC_NANDCLE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN17) +#define GPIO_SMC_NANDOE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_SMC_NANDWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_SMC_NBS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN18) +#define GPIO_SMC_NBS1 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_SMC_NCS0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_SMC_NCS1_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN15) +#define GPIO_SMC_NCS1_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_SMC_NCS2 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SMC_NCS3_1 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_SMC_NCS3_2 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_SMC_NRD (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_SMC_NWAIT (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN13) +#define GPIO_SMC_NWE (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_SMC_NWR0 (GPIO_PERIPHA | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_SMC_NWR1 (GPIO_PERIPHC | GPIO_CFG_PULLUP | GPIO_PORT_PIOD | GPIO_PIN15) + +/* Serial Peripheral Interface (SPI) */ + +#define GPIO_SPI0_MISO (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN20) +#define GPIO_SPI0_MOSI (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_SPI0_SPCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) + +#define GPIO_SPI0_NSS (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS0 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_SPI0_NPCS1_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN31) +#define GPIO_SPI0_NPCS1_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_SPI0_NPCS2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN12) +#define GPIO_SPI0_NPCS3 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) + +#define GPIO_SPI1_MISO (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_SPI1_MOSI (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_SPI1_SPCK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) + +#define GPIO_SPI1_NSS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SPI1_NPCS0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_SPI1_NPCS1_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_SPI1_NPCS1_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_SPI1_NPCS2_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_SPI1_NPCS2_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_SPI1_NPCS3_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_SPI1_NPCS3_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) + +/* Synchronous Serial Controller (SSC) */ + +#define GPIO_SSC0_RD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) +#define GPIO_SSC0_RF (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_SSC0_RK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN22) +#define GPIO_SSC0_TD_1 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_SSC0_TD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN10) +#define GPIO_SSC0_TD_3 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_SSC0_TF (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_SSC0_TK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) + +/* Timer/Counters (TC) */ + +#define GPIO_TC0_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TC0_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN0) +#define GPIO_TC0_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN1) +#define GPIO_TC1_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_TC1_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN15) +#define GPIO_TC1_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN16) +#define GPIO_TC2_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_TC2_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_TC2_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_TC3_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN25) +#define GPIO_TC3_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN23) +#define GPIO_TC3_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN24) +#define GPIO_TC4_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN28) +#define GPIO_TC4_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN26) +#define GPIO_TC4_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN27) +#define GPIO_TC5_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN31) +#define GPIO_TC5_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN29) +#define GPIO_TC5_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN30) +#define GPIO_TC6_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN7) +#define GPIO_TC6_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN5) +#define GPIO_TC6_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN6) +#define GPIO_TC7_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN10) +#define GPIO_TC7_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN8) +#define GPIO_TC7_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN9) +#define GPIO_TC8_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN14) +#define GPIO_TC8_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN11) +#define GPIO_TC8_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOC | GPIO_PIN12) +#define GPIO_TC9_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN2) +#define GPIO_TC9_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN0) +#define GPIO_TC9_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN1) +#define GPIO_TC10_TCLK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN5) +#define GPIO_TC10_TIOA (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN3) +#define GPIO_TC10_TIOB (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOE | GPIO_PIN4) +#define GPIO_TC11_TCLK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN24) +#define GPIO_TC11_TIOA (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN21) +#define GPIO_TC11_TIOB (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN22) + +/* Trace Debug Port */ + +#define GPIO_TRACE_CLK (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN8) +#define GPIO_TRACE_D0 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_TRACE_D1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_TRACE_D2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_TRACE_D3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) + +/* Two Wire Interface (TWIHS) */ + +#define GPIO_TWIHS0_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_TWIHS0_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_TWIHS1_CK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN5) +#define GPIO_TWIHS1_D (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) +#define GPIO_TWIHS2_CK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_TWIHS2_D (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN27) + +/* Universal Asynchronous Receiver Transceiver (UART) */ + +#define GPIO_UART0_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN9) +#define GPIO_UART0_TXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN10) + +#define GPIO_UART1_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN5) +#define GPIO_UART1_TXD_1 (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) +#define GPIO_UART1_TXD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN4) +#define GPIO_UART1_TXD_3 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN6) + +#define GPIO_UART2_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN25) +#define GPIO_UART2_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN26) + +#define GPIO_UART3_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN28) +#define GPIO_UART3_TXD_1 (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN30) +#define GPIO_UART3_TXD_2 (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN31) + +#define GPIO_UART4_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_UART4_TXD_1 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_UART4_TXD_2 (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) + +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ + +#define GPIO_USART0_CTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN2) +#define GPIO_USART0_DCD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN0) +#define GPIO_USART0_DSR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN2) +#define GPIO_USART0_DTR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN1) +#define GPIO_USART0_RI (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN3) +#define GPIO_USART0_RTS (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN3) +#define GPIO_USART0_RXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN0) +#define GPIO_USART0_SCK (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN13) +#define GPIO_USART0_TXD (GPIO_PERIPHC | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN1) + +#define GPIO_USART1_CTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN25) +#define GPIO_USART1_DCD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN26) +#define GPIO_USART1_DSR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN28) +#define GPIO_USART1_DTR (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN27) +#define GPIO_USART1_LONCOL (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN3) +#define GPIO_USART1_RI (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN29) +#define GPIO_USART1_RTS (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN24) +#define GPIO_USART1_RXD (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN21) +#define GPIO_USART1_SCK (GPIO_PERIPHA | GPIO_CFG_DEFAULT | GPIO_PORT_PIOA | GPIO_PIN23) +#define GPIO_USART1_TXD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOB | GPIO_PIN4) + +#define GPIO_USART2_CTS (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN19) +#define GPIO_USART2_DCD (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN4) +#define GPIO_USART2_DSR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN6) +#define GPIO_USART2_DTR (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN5) +#define GPIO_USART2_RI (GPIO_PERIPHD | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN7) +#define GPIO_USART2_RTS (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN18) +#define GPIO_USART2_RXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN15) +#define GPIO_USART2_SCK (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN17) +#define GPIO_USART2_TXD (GPIO_PERIPHB | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | GPIO_PIN16) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_CHIP_SAMV71_PINMAP_H */ diff --git a/arch/arm/src/samv7/sam_allocateheap.c b/arch/arm/src/samv7/sam_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..1e8dc087963cf61db3374c70d6d209884174c25d --- /dev/null +++ b/arch/arm/src/samv7/sam_allocateheap.c @@ -0,0 +1,368 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_allocateheap.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_mpuinit.h" +#include "sam_periphclks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* All SAM's have SRAM. In addition, they may have external SRAM or SDRAM */ + +#define HAVE_SDRAM_REGION 0 /* Assume no external SDRAM */ +#define HAVE_EXTSRAM0_REGION 0 /* Assume no external SRAM at CS0 */ +#define HAVE_EXTSRAM1_REGION 0 /* Assume no external SRAM at CS1 */ +#define HAVE_EXTSRAM2_REGION 0 /* Assume no external SRAM at CS2 */ +#define HAVE_EXTSRAM3_REGION 0 /* Assume no external SRAM at CS3 */ + +/* Check if external SDRAM is supported and, if so, it is is intended + * to be used as heap. + */ + +#if !defined(CONFIG_SAMV7_SDRAMC) || !defined(CONFIG_SAMV7_SDRAMHEAP) +# undef CONFIG_SAMV7_SDRAMSIZE +# define CONFIG_SAMV7_SDRAMSIZE 0 +#endif + +/* Check if external SRAM is supported and, if so, it is is intended + * to be used as heap. + */ + +#if !defined(CONFIG_SAMV7_EXTSRAM0) || !defined(CONFIG_SAMV7_EXTSRAM0HEAP) +# undef CONFIG_SAMV7_EXTSRAM0SIZE +# define CONFIG_SAMV7_EXTSRAM0SIZE 0 +#endif + +#if !defined(CONFIG_SAMV7_EXTSRAM1) || !defined(CONFIG_SAMV7_EXTSRAM1HEAP) +# undef CONFIG_SAMV7_EXTSRAM1SIZE +# define CONFIG_SAMV7_EXTSRAM1SIZE 0 +#endif + +#if !defined(CONFIG_SAMV7_EXTSRAM2) || !defined(CONFIG_SAMV7_EXTSRAM2HEAP) +# undef CONFIG_SAMV7_EXTSRAM2SIZE +# define CONFIG_SAMV7_EXTSRAM2SIZE 0 +#endif + +#if !defined(CONFIG_SAMV7_EXTSRAM3) || !defined(CONFIG_SAMV7_EXTSRAM3HEAP) +# undef CONFIG_SAMV7_EXTSRAM3SIZE +# define CONFIG_SAMV7_EXTSRAM3SIZE 0 +#endif + +/* Now lets reconcile the number of configured regions with the available + * memory resource configured for use as a heap region. + */ + +#if CONFIG_SAMV7_SDRAMSIZE > 0 +# if CONFIG_MM_REGIONS > 1 +# undef HAVE_SDRAM_REGION +# define HAVE_SDRAM_REGION 1 +# else +# warning "CONFIG_MM_REGIONS < 2: SDRAM not included in HEAP" +# endif +#endif + +#if CONFIG_SAMV7_EXTSRAM0SIZE > 0 +# if CONFIG_MM_REGIONS > (HAVE_SDRAM_REGION + 1) +# undef HAVE_EXTSRAM0_REGION +# define HAVE_EXTSRAM0_REGION 1 +# else +# warning "CONFIG_MM_REGIONS too small: External SRAM0 not included in HEAP" +# endif +#endif + +#if CONFIG_SAMV7_EXTSRAM1SIZE > 0 +# if CONFIG_MM_REGIONS > (HAVE_SDRAM_REGION + HAVE_EXTSRAM0_REGION + 1) +# undef HAVE_EXTSRAM1_REGION +# define HAVE_EXTSRAM1_REGION 1 +# else +# warning "CONFIG_MM_REGIONS too small: External SRAM1 not included in HEAP" +# endif +#endif + +#if CONFIG_SAMV7_EXTSRAM2SIZE > 0 +# if CONFIG_MM_REGIONS > (HAVE_SDRAM_REGION + HAVE_EXTSRAM0_REGION + HAVE_EXTSRAM1_REGION + 1) +# undef HAVE_EXTSRAM2_REGION +# define HAVE_EXTSRAM2_REGION 1 +# else +# warning "CONFIG_MM_REGIONS too small: External SRAM2 not included in HEAP" +# endif +#endif + +#if CONFIG_SAMV7_EXTSRAM3SIZE > 0 +# if CONFIG_MM_REGIONS > (HAVE_SDRAM_REGION + HAVE_EXTSRAM0_REGION + HAVE_EXTSRAM1_REGION + HAVE_EXTSRAM2_REGION + 1) +# undef HAVE_EXTSRAM3_REGION +# define HAVE_EXTSRAM3_REGION 1 +# else +# warning "CONFIG_MM_REGIONS too small: External SRAM3 not included in HEAP" +# endif +#endif + +/* Check internal SRAM configuration */ + +#ifdef CONFIG_ARMV7M_DTCM +# define SRAM_BASE SAM_DTCM_BASE +#else +# define SRAM_BASE SAM_SRAM_BASE +#endif + +#if CONFIG_RAM_END > (SRAM_BASE+SAMV7_SRAM_SIZE) +# error "CONFIG_RAM_END is beyond the end of SRAM" +# undef CONFIG_RAM_END +# define CONFIG_RAM_END (SRAM_BASE+SAMV7_SRAM_SIZE) +#elif CONFIG_RAM_END < (SRAM_BASE+SAMV7_SRAM_SIZE) +# warning "CONFIG_RAM_END is before end of SRAM... not all of SRAM used" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + sam_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#if HAVE_SDRAM_REGION != 0 + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_SDRAMCS_BASE, CONFIG_SAMV7_SDRAMSIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_SDRAMCS_BASE, CONFIG_SAMV7_SDRAMSIZE); + +#endif /* HAVE_SDRAM_REGION */ + +#if HAVE_EXTSRAM0_REGION != 0 + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS0_BASE, CONFIG_SAMV7_EXTSRAM0SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS0_BASE, CONFIG_SAMV7_EXTSRAM0SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#if HAVE_EXTSRAM1_REGION != 0 + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS1_BASE, CONFIG_SAMV7_EXTSRAM1SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS1_BASE, CONFIG_SAMV7_EXTSRAM1SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#if HAVE_EXTSRAM2_REGION != 0 + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS2_BASE, CONFIG_SAMV7_EXTSRAM2SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS2_BASE, CONFIG_SAMV7_EXTSRAM2SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ + +#if HAVE_EXTSRAM3_REGION != 0 + /* Allow user access to the heap memory */ + + sam_mpu_uheap(SAM_EXTCS3_BASE, CONFIG_SAMV7_EXTSRAM3SIZE); + + /* Add the region */ + + kumm_addregion((FAR void *)SAM_EXTCS3_BASE, CONFIG_SAMV7_EXTSRAM3SIZE); + +#endif /* HAVE_EXTSRAM0_REGION */ +} +#endif /* CONFIG_MM_REGIONS > 1 */ diff --git a/arch/arm/src/samv7/sam_clockconfig.c b/arch/arm/src/samv7/sam_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..2538aadc75d4cc2aa5b5e2c72854803eb105a609 --- /dev/null +++ b/arch/arm/src/samv7/sam_clockconfig.c @@ -0,0 +1,448 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_clockconfig.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_clockconfig.h" +#include "chip/sam_pmc.h" +#include "chip/sam_eefc.h" +#include "chip/sam_wdt.h" +#include "chip/sam_supc.h" +#include "chip/sam_matrix.h" +#include "chip/sam_utmi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Board Settings **********************************************************/ +/* PMC register settings based on the board configuration values defined + * in board.h + */ + +#define BOARD_CKGR_MOR (BOARD_CKGR_MOR_MOSCXTENBY | PMC_CKGR_MOR_MOSCRCEN | \ + BOARD_CKGR_MOR_MOSCXTST | PMC_CKGR_MOR_KEY) +#define BOARD_CKGR_PLLAR (BOARD_CKGR_PLLAR_DIV | BOARD_CKGR_PLLAR_COUNT | \ + BOARD_CKGR_PLLAR_MUL | PMC_CKGR_PLLAR_ONE) + +#define BOARD_PMC_MCKR_FAST (PMC_MCKR_CSS_MAIN | BOARD_PMC_MCKR_PRES | \ + BOARD_PMC_MCKR_MDIV | BOARD_PMC_MCKR_UPLLDIV2) +#define BOARD_PMC_MCKR (BOARD_PMC_MCKR_CSS | BOARD_PMC_MCKR_PRES | \ + BOARD_PMC_MCKR_MDIV | BOARD_PMC_MCKR_UPLLDIV2) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_efcsetup + * + * Description: + * Configure wait states for embedded flash access + * + ****************************************************************************/ + +static inline void sam_efcsetup(void) +{ + uint32_t regval = EEFC_FMR_FWS(BOARD_FWS) | EEFC_FMR_CLOE; + putreg32(regval, SAM_EEFC_FMR); +} + +/**************************************************************************** + * Name: sam_wdtsetup + * + * Description: + * Disable the watchdog timer + * + ****************************************************************************/ + +static inline void sam_wdtsetup(void) +{ +#if !defined(CONFIG_SAMV7_WDT) || \ + (defined(CONFIG_WDT_ENABLED_ON_RESET) && defined(CONFIG_WDT_DISABLE_ON_RESET)) + putreg32(WDT_MR_WDDIS, SAM_WDT_MR); +#endif + +#if !defined(CONFIG_SAMV7_RSWDT) || \ + (defined(CONFIG_RSWDT_ENABLED_ON_RESET) && defined(CONFIG_RSWDT_DISABLE_ON_RESET)) + putreg32(WDT_MR_WDDIS, SAM_RSWDT_MR); +#endif +} + +/**************************************************************************** + * Name: sam_supcsetup + * + * Description: + * Select the external slow clock + * + ****************************************************************************/ + +static inline void sam_supcsetup(void) +{ +#ifdef BOARD_HAVE_SLOWXTAL + /* Check if the 32-kHz is already selected. The slow clock defaults to + * the RC oscillator, but the software can enable the crystal oscillator + * and select it as the slow clock source. + */ + + if ((getreg32(SAM_SUPC_SR) & SUPC_SR_OSCSEL) == 0) + { + uint32_t delay; + + putreg32((SUPC_CR_XTALSEL | SUPR_CR_KEY), SAM_SUPC_CR); + for (delay = 0; + (getreg32(SAM_SUPC_SR) & SUPC_SR_OSCSEL) == 0 && delay < UINT32_MAX; + delay++); + } +#endif +} + +/**************************************************************************** + * Name: sam_pmcwait + * + * Description: + * Wait for the specified PMC status bit to become "1" + * + ****************************************************************************/ + +static void sam_pmcwait(uint32_t bit) +{ + volatile uint32_t delay; + + for (delay = 0; + (getreg32(SAM_PMC_SR) & bit) == 0 && delay < UINT32_MAX; + delay++); +} + +/**************************************************************************** + * Name: sam_pmcsetup + * + * Description: + * Initialize clocking + * + ****************************************************************************/ + +static inline void sam_pmcsetup(void) +{ + uint32_t regval; + + /* Enable main oscillator (if it has not already been selected) */ + + if ((getreg32(SAM_PMC_CKGR_MOR) & PMC_CKGR_MOR_MOSCSEL) == 0) + { + /* "When the MOSCXTEN bit and the MOSCXTCNT are written in CKGR_MOR to + * enable the main oscillator, the MOSCXTS bit in the Power Management + * Controller Status Register (PMC_SR) is cleared and the counter starts + * counting down on the slow clock divided by 8 from the MOSCXTCNT + * value. ... When the counter reaches 0, the MOSCXTS bit is set, + * indicating that the main clock is valid." + */ + + putreg32(BOARD_CKGR_MOR, SAM_PMC_CKGR_MOR); + sam_pmcwait(PMC_INT_MOSCXTS); + } + + /* "Switch to the main oscillator. The selection is made by writing the + * MOSCSEL bit in the Main Oscillator Register (CKGR_MOR). The switch of + * the Main Clock source is glitch free, so there is no need to run out + * of SLCK, PLLACK or UPLLCK in order to change the selection. The MOSCSELS + * bit of the power Management Controller Status Register (PMC_SR) allows + * knowing when the switch sequence is done." + * + * MOSCSELS: Main Oscillator Selection Status + * 0 = Selection is done + * 1 = Selection is in progress + */ + + putreg32((BOARD_CKGR_MOR | PMC_CKGR_MOR_MOSCSEL), SAM_PMC_CKGR_MOR); + sam_pmcwait(PMC_INT_MOSCSELS); + + /* "Select the master clock. "The Master Clock selection is made by writing + * the CSS field (Clock Source Selection) in PMC_MCKR (Master Clock Register). + * The prescaler supports the division by a power of 2 of the selected clock + * between 1 and 64, and the division by 3. The PRES field in PMC_MCKR programs + * the prescaler. Each time PMC_MCKR is written to define a new Master Clock, + * the MCKRDY bit is cleared in PMC_SR. It reads 0 until the Master Clock is + * established. + */ + + regval = getreg32(SAM_PMC_MCKR); + regval &= ~PMC_MCKR_CSS_MASK; + regval |= PMC_MCKR_CSS_MAIN; + putreg32(regval, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); + + /* Setup PLLA and wait for LOCKA */ + + putreg32(BOARD_CKGR_PLLAR, SAM_PMC_CKGR_PLLAR); + sam_pmcwait(PMC_INT_LOCKA); + +#ifdef CONFIG_SAMV7_USBDEVHS + /* UTMI configuration: Enable port0, select 12/16 MHz MAINOSC crystal source */ + +#if BOARD_MAINOSC_FREQUENCY == 12000000 + putreg32(UTMI_CKTRIM_FREQ_XTAL12, SAM_UTMI_CKTRIM); +#elif BOARD_MAINOSC_FREQUENCY == 16000000 + putreg32(UTMI_CKTRIM_FREQ_XTAL16, SAM_UTMI_CKTRIM); +#else +# error ERROR: Unrecognized MAINSOSC frequency +#endif + +#ifdef CONFIG_SAMV7_USBDEVHS_LOWPOWER + /* Enable UTMI Clocking. The USBHS can work in two modes: + * + * - Normal mode where High speed, Full speed and Low speed are available. + * - Low-power mode where only Full speed and Low speed are available. + * + * Only the Low-power mode is mode is supported by the logic here. Normal + * mode logic is handled in the function sam_usbclock(). + */ + + /* UTMI Low-power mode, Full/Low Speed mode + * + * Enable the 48MHz FS Clock. + */ + + putreg32(PMC_USBCLK, SAM_PMC_SCER); + + /* Select the UTMI PLL as the USB PLL clock input (480MHz) with divider + * to get to 48MHz. UPLL output frequency is determined only by the + * 12/16MHz crystal selection above. + */ + + regval = PMC_USB_USBS_UPLL; + + if ((getreg32(SAM_PMC_MCKR) & PMC_MCKR_PLLADIV2) != 0) + { + /* Divider = 480 Mhz / 2 / 48 Mhz = 5 */ + + regval |= PMC_USB_USBDIV(4); + } + else + { + /* Divider = 480 Mhz / 1 / 48 Mhz = 10 */ + + regval |= PMC_USB_USBDIV(9); + } + + putreg32(regval, SAM_PMC_USB); + + /* Enable the UTMI PLL with the maximum start-up time */ + + regval = PMC_CKGR_UCKR_UPLLEN | PMC_CKGR_UCKR_UPLLCOUNT_MAX; + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* Wait for LOCKU */ + + sam_pmcwait(PMC_INT_LOCKU); + +#endif /* CONFIG_SAMV7_USBDEVHS_LOWPOWER */ +#endif /* CONFIG_SAMV7_USBDEVHS */ + + /* Switch to the fast clock and wait for MCKRDY */ + + putreg32(BOARD_PMC_MCKR_FAST, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); + + putreg32(BOARD_PMC_MCKR, SAM_PMC_MCKR); + sam_pmcwait(PMC_INT_MCKRDY); +} + +/**************************************************************************** + * Name: sam_enabledefaultmaster and sam_disabledefaultmaster + * + * Description: + * Enable/disable default master access + * + ****************************************************************************/ + +static inline void sam_enabledefaultmaster(void) +{ +#warning REVISIT +#if 0 /* REVISIT -- this is stuff left over from SAM3/4 */ + uint32_t regval; + + /* Set default master: SRAM0 -> Cortex-M7 System */ + + regval = getreg32(SAM_MATRIX_SCFG0); + regval |= (MATRIX_SCFG0_FIXEDDEFMSTR_ARMS | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG0); + + /* Set default master: SRAM1 -> Cortex-M7 System */ + + regval = getreg32(SAM_MATRIX_SCFG1); + regval |= (MATRIX_SCFG1_FIXEDDEFMSTR_ARMS | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG1); + + /* Set default master: Internal flash0 -> Cortex-M7 Instruction/Data */ + + regval = getreg32(SAM_MATRIX_SCFG3); + regval |= (MATRIX_SCFG3_FIXEDDEFMSTR_ARMC | MATRIX_SCFG_DEFMSTRTYPE_FIXED); + putreg32(regval, SAM_MATRIX_SCFG3); +#endif +} + +#if 0 /* Not used -- this is stuff left over from SAM3/4 */ +static inline void sam_disabledefaultmaster(void) +{ + uint32_t regval; + + /* Clear default master: SRAM0 -> Cortex-M7 System */ + + regval = getreg32(SAM_MATRIX_SCFG0); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG0); + + /* Clear default master: SRAM1 -> Cortex-M7 System */ + + regval = getreg32(SAM_MATRIX_SCFG1); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG1); + + /* Clear default master: Internal flash0 -> Cortex-M7 Instruction/Data */ + + regval = getreg32(SAM_MATRIX_SCFG3); + regval &= ~MATRIX_SCFG_DEFMSTRTYPE_MASK; + putreg32(regval, SAM_MATRIX_SCFG3); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAMV7. This does whatever setup is needed + * to put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. (After power-on reset, the + * SAMV7 is initially running on a 4MHz internal RC clock). This function + * also performs other low-level chip initialization of the chip including + * EFC, master clock, IRQ & watchdog configuration. + * + ****************************************************************************/ + +void sam_clockconfig(void) +{ + /* Configure embedded flash access */ + + sam_efcsetup(); + + /* Configure the watchdog timer */ + + sam_wdtsetup(); + + /* Setup the supply controller to use the external slow clock */ + + sam_supcsetup(); + + /* Initialize clocking */ + + sam_pmcsetup(); + + /* Optimize CPU setting for speed */ + + sam_enabledefaultmaster(); +} + +/**************************************************************************** + * Name: sam_usbclock + * + * Description: + * Enable USBHS clocking. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USBDEVHS) && !defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +void sam_usbclock(void) +{ + uint32_t regval; + + /* Enable UTMI Clocking. The USBHS can work in two modes: + * + * - Normal mode where High speed, Full speed and Low speed are available. + * - Low-power mode where only Full speed and Low speed are available. + * + * Only the normal mode is supported by this logic of this function. Low- + * power mode was handled in the sam_clockconfig(). + */ + + /* UTMI normal mode, High/Full/Low Speed + * + * Disable the 48MHz USB FS Clock. It is not used in this configuration + */ + + putreg32(PMC_USBCLK, SAM_PMC_SCDR); + + /* Select the UTMI PLL as the USB PLL clock input (480MHz) with a divider + * of 1. UPLL output frequency is determined only by the 12/16MHz crystal + * selection set in sam_clockconfig(). + */ + + putreg32(PMC_USB_USBS_UPLL, SAM_PMC_USB); + + /* Enable the UTMI PLL with the maximum start-up time */ + + regval = PMC_CKGR_UCKR_UPLLEN | PMC_CKGR_UCKR_UPLLCOUNT_MAX; + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* Wait for LOCKU */ + + sam_pmcwait(PMC_INT_LOCKU); +} + +#endif /* CONFIG_SAMV7_USBDEVHS && !CONFIG_SAMV7_USBDEVHS_LOWPOWER */ diff --git a/arch/arm/src/samv7/sam_clockconfig.h b/arch/arm/src/samv7/sam_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..f62d73290418f5b46855f2a88beb750ee6a1f3cf --- /dev/null +++ b/arch/arm/src/samv7/sam_clockconfig.h @@ -0,0 +1,108 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_clockconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_SAMV7_SAM_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAMV7. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void sam_clockconfig(void); + +/**************************************************************************** + * Name: sam_usbclock + * + * Description: + * Enable USBHS clocking. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USBDEVHS) && !defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +void sam_usbclock(void); +#else +# define sam_usbclock() +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_CLOCKCONFIG_H */ diff --git a/arch/arm/src/samv7/sam_config.h b/arch/arm/src/samv7/sam_config.h new file mode 100644 index 0000000000000000000000000000000000000000..242c2eb50375cbd2090d29359b8fe061574fc551 --- /dev/null +++ b/arch/arm/src/samv7/sam_config.h @@ -0,0 +1,338 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam-config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAMV7_CONFIG_H +#define __ARCH_ARM_SRC_SAMV7_SAMV7_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* GPIO IRQs ****************************************************************/ + +#ifndef CONFIG_SAMV7_GPIO_IRQ +# undef CONFIG_SAMV7_GPIOA_IRQ +# undef CONFIG_SAMV7_GPIOB_IRQ +# undef CONFIG_SAMV7_GPIOC_IRQ +# undef CONFIG_SAMV7_GPIOD_IRQ +# undef CONFIG_SAMV7_GPIOE_IRQ +#endif + +#if SAMV7_NPIO < 1 +# undef CONFIG_SAMV7_GPIOA_IRQ +#endif +#if SAMV7_NPIO < 2 +# undef CONFIG_SAMV7_GPIOB_IRQ +#endif +#if SAMV7_NPIO < 3 +# undef CONFIG_SAMV7_GPIOC_IRQ +#endif +#if SAMV7_NPIO < 4 +# undef CONFIG_SAMV7_GPIOD_IRQ +#endif +#if SAMV7_NPIO < 5 +# undef CONFIG_SAMV7_GPIOE_IRQ +#endif + +/* UARTs ********************************************************************/ +/* Don't enable UARTs not supported by the chip. */ + +#if SAMV7_NUART < 1 +# undef CONFIG_SAMV7_UART0 +# undef CONFIG_SAMV7_UART1 +# undef CONFIG_SAMV7_UART2 +# undef CONFIG_SAMV7_UART3 +# undef CONFIG_SAMV7_UART4 +#elif SAMV7_NUART < 2 +# undef CONFIG_SAMV7_UART1 +# undef CONFIG_SAMV7_UART2 +# undef CONFIG_SAMV7_UART3 +# undef CONFIG_SAMV7_UART4 +#elif SAMV7_NUART < 3 +# undef CONFIG_SAMV7_UART2 +# undef CONFIG_SAMV7_UART3 +# undef CONFIG_SAMV7_UART4 +#elif SAMV7_NUART < 4 +# undef CONFIG_SAMV7_UART3 +# undef CONFIG_SAMV7_UART4 +#elif SAMV7_NUART < 5 +# undef CONFIG_SAMV7_UART4 +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_SAMV7_UART0) || defined(CONFIG_SAMV7_UART1) || \ + defined(CONFIG_SAMV7_UART2) || defined(CONFIG_SAMV7_UART3) || \ + defined(CONFIG_SAMV7_UART4) +# define HAVE_UART_DEVICE 1 +#endif + +/* USARTs *******************************************************************/ +/* If the USART is not being used as a UART or for SPI, then it really isn't + * enabled for our purposes. + */ + +#if !defined(CONFIG_USART0_ISUART) && !defined(CONFIG_USART0_ISSPI) +# undef CONFIG_SAMV7_USART0 +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART0_IFLOWCONTROL +#endif + +#if !defined(CONFIG_USART1_ISUART) && !defined(CONFIG_USART1_ISSPI) +# undef CONFIG_SAMV7_USART1 +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART1_IFLOWCONTROL +#endif + +#if !defined(CONFIG_USART2_ISUART) && !defined(CONFIG_USART2_ISSPI) +# undef CONFIG_SAMV7_USART2 +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART2_IFLOWCONTROL +#endif + +/* Don't enable USARTs not supported by the chip. */ + +#if SAMV7_NUSART < 1 +# undef CONFIG_SAMV7_USART0 +# undef CONFIG_SAMV7_USART1 +# undef CONFIG_SAMV7_USART2 +#elif SAMV7_NUSART < 2 +# undef CONFIG_SAMV7_USART1 +# undef CONFIG_SAMV7_USART2 +#elif SAMV7_NUSART < 3 +# undef CONFIG_SAMV7_USART2 +#endif + +/* Are any USARTs enabled? */ + +#if defined(CONFIG_SAMV7_USART0) || defined(CONFIG_SAMV7_USART1) || \ + defined(CONFIG_SAMV7_USART2) +# undef HAVE_UART_DEVICE +# define HAVE_UART_DEVICE 1 +#endif + +/* UART Flow Control ********************************************************/ +/* UARTs do not support flow control */ + +#undef CONFIG_UART0_IFLOWCONTROL +#undef CONFIG_UART1_IFLOWCONTROL +#undef CONFIG_UART2_IFLOWCONTROL +#undef CONFIG_UART3_IFLOWCONTROL +#undef CONFIG_UART4_IFLOWCONTROL + +/* Hardware flow control requires using a DMAC channel (not yet supported) */ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +# warning XDMAC support is required for RTS hardware flow control +# undef CONFIG_SERIAL_IFLOWCONTROL +# undef CONFIG_USART0_IFLOWCONTROL +# undef CONFIG_USART1_IFLOWCONTROL +# undef CONFIG_USART2_IFLOWCONTROL +#endif + +/* Serial Console ***********************************************************/ +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,..,SAMV7_NUART, or USARTn, n=1,.., SAMV7_NUSART + */ + +#undef HAVE_SERIAL_CONSOLE +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_UART4) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_USART0) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_USART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_SAMV7_USART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +#endif + +/* SPI ******************************************************************************/ +/* Don't enable SPI peripherals not supported by the chip. */ + +#if SAMV7_NSPI < 1 +# undef CONFIG_SAMV7_SPI0 +# undef CONFIG_SAMV7_SPI0_MASTER +# undef CONFIG_SAMV7_SPI0_SLAVE +# undef CONFIG_SAMV7_SPI1 +# undef CONFIG_SAMV7_SPI1_MASTER +# undef CONFIG_SAMV7_SPI1_SLAVE +#elif SAMV7_NSPI < 2 +# undef CONFIG_SAMV7_SPI1 +# undef CONFIG_SAMV7_SPI1_MASTER +# undef CONFIG_SAMV7_SPI1_SLAVE +#endif + +#ifndef CONFIG_SAMV7_SPI +# undef CONFIG_SAMV7_SPI0 +# undef CONFIG_SAMV7_SPI0_MASTER +# undef CONFIG_SAMV7_SPI0_SLAVE +# undef CONFIG_SAMV7_SPI1 +# undef CONFIG_SAMV7_SPI1_MASTER +# undef CONFIG_SAMV7_SPI1_SLAVE +#endif + +/* Are any SPI peripherals enabled? */ + +#if !defined(CONFIG_SAMV7_SPI0) && !defined(CONFIG_SAMV7_SPI0) +# undef CONFIG_SAMV7_SPI +# undef CONFIG_SAMV7_SPI_MASTER +# undef CONFIG_SAMV7_SPI_SLAVE +#endif + +/* Each SPI peripheral must be enabled as a MASTER or as a SLAVE */ + +#ifndef CONFIG_SAMV7_SPI_MASTER +# undef CONFIG_SAMV7_SPI0_MASTER +# undef CONFIG_SAMV7_SPI1_MASTER +#endif + +#if !defined(CONFIG_SAMV7_SPI0_MASTER) && !defined(CONFIG_SAMV7_SPI1_MASTER) +# undef CONFIG_SAMV7_SPI_MASTER +#endif + +#ifndef CONFIG_SAMV7_SPI_SLAVE +# undef CONFIG_SAMV7_SPI0_SLAVE +# undef CONFIG_SAMV7_SPI1_SLAVE +#endif + +#if !defined(CONFIG_SAMV7_SPI0_SLAVE) && !defined(CONFIG_SAMV7_SPI1_SLAVE) +# undef CONFIG_SAMV7_SPI_SLAVE +#endif + +#if !defined(CONFIG_SAMV7_SPI_MASTER) && !defined(CONFIG_SAMV7_SPI_SLAVE) +# undef CONFIG_SAMV7_SPI +# undef CONFIG_SAMV7_SPI0 +# undef CONFIG_SAMV7_SPI1 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_SAMV7_SAMV7_CONFIG_H */ diff --git a/arch/arm/src/samv7/sam_emac.c b/arch/arm/src/samv7/sam_emac.c new file mode 100644 index 0000000000000000000000000000000000000000..39e14457dd4c56da3f2a6519b33ce04bf83e94dc --- /dev/null +++ b/arch/arm/src/samv7/sam_emac.c @@ -0,0 +1,5282 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_emac.c + * 10/100 Base-T Ethernet driver for the SAMV71. + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This logic derives from the SAMA5 Ethernet driver which, in turn, derived + * from the SAM4E Ethernet driver which used Atmel NoOS sample code for + * reference (only). Updates for SAMV7 queue logic derive Atmel sample code + * for the SAMV7-XULT evaluation board. The Atmel sample code has a BSD + * compatible license that requires this copyright notice: + * + * Copyright (c) 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_DEBUG) && defined(CONFIG_SAMV7_EMAC_DEBUG) + /* Force debug output (from this file only) */ + +# undef CONFIG_DEBUG_NET +# define CONFIG_DEBUG_NET 1 +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "chip/sam_pinmap.h" +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "sam_ethernet.h" + +#include + +#if defined(CONFIG_NET) && defined(CONFIG_SAMV7_EMAC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +/* EMAC0 Configuration ******************************************************/ + +#ifdef CONFIG_SAMV7_EMAC0 + /* Number of buffers for RX */ + +# ifndef CONFIG_SAMV7_EMAC0_NRXBUFFERS +# define CONFIG_SAMV7_EMAC0_NRXBUFFERS 16 +# endif + +# if CONFIG_SAMV7_EMAC0_NRXBUFFERS <= 1 +# error CONFIG_SAMV7_EMAC0_NRXBUFFERS invalid +# endif + + /* Number of buffers for TX */ + +# ifndef CONFIG_SAMV7_EMAC0_NTXBUFFERS +# define CONFIG_SAMV7_EMAC0_NTXBUFFERS 8 +# endif + +# if CONFIG_SAMV7_EMAC0_NTXBUFFERS <= 1 +# error CONFIG_SAMV7_EMAC0_NTXBUFFERS invalid +# endif + +# ifndef CONFIG_SAMV7_EMAC0_PHYADDR +# error "CONFIG_SAMV7_EMAC0_PHYADDR must be defined in the NuttX configuration" +# endif + +# if !defined(CONFIG_SAMV7_EMAC0_MII) && !defined(CONFIG_SAMV7_EMAC0_RMII) +# warning "Neither CONFIG_SAMV7_EMAC0_MII nor CONFIG_SAMV7_EMAC0_RMII defined" +# endif + +# if defined(CONFIG_SAMV7_EMAC0_MII) && defined(CONFIG_SAMV7_EMAC0_RMII) +# error "Both CONFIG_SAMV7_EMAC0_MII and CONFIG_SAMV7_EMAC0_RMII defined" +# endif + +# ifndef CONFIG_SAMV7_EMAC0_PHYSR +# error "CONFIG_SAMV7_EMAC0_PHYSR must be defined in the NuttX configuration" +# endif + +# ifdef CONFIG_SAMV7_EMAC0_AUTONEG +# ifdef CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE +# error "CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_10HD +# error "CONFIG_SAMV7_EMAC0_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_100HD +# error "CONFIG_SAMV7_EMAC0_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_10FD +# error "CONFIG_SAMV7_EMAC0_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_100FD +# error "CONFIG_SAMV7_EMAC0_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_SPEED +# error "CONFIG_SAMV7_EMAC0_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_100MBPS +# error "CONFIG_SAMV7_EMAC0_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_MODE +# error "CONFIG_SAMV7_EMAC0_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC0_PHYSR_FULLDUPLEX +# error "CONFIG_SAMV7_EMAC0_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +# endif + + /* PHY definitions */ + +# if defined(SAMV7_EMAC0_PHY_DM9161) +# define EMAC0_MII_OUI_MSB 0x0181 +# define EMAC0_MII_OUI_LSB 0x2e +# elif defined(SAMV7_EMAC0_PHY_LAN8700) +# define EMAC0_MII_OUI_MSB 0x0007 +# define EMAC0_MII_OUI_LSB 0x30 +# elif defined(SAMV7_EMAC0_PHY_KSZ8051) +# define EMAC0_MII_OUI_MSB 0x0022 +# define EMAC0_MII_OUI_LSB 0x05 +# elif defined(SAMV7_EMAC0_PHY_KSZ8061) +# define EMAC0_MII_OUI_MSB 0x0022 +# define EMAC0_MII_OUI_LSB 0x05 +# elif defined(SAMV7_EMAC0_PHY_KSZ8081) +# define EMAC0_MII_OUI_MSB 0x0022 +# define EMAC0_MII_OUI_LSB 0x05 +# else +# error EMAC PHY unrecognized +# endif +#endif /* CONFIG_SAMV7_EMAC0 */ + +/* EMAC1 Configuration ******************************************************/ + +#ifdef CONFIG_SAMV7_EMAC1 + /* Number of buffers for RX */ + +# ifndef CONFIG_SAMV7_EMAC1_NRXBUFFERS +# define CONFIG_SAMV7_EMAC1_NRXBUFFERS 16 +# endif + +# if CONFIG_SAMV7_EMAC1_NRXBUFFERS <= 1 +# error CONFIG_SAMV7_EMAC1_NRXBUFFERS invalid +# endif + + /* Number of buffers for TX */ + +# ifndef CONFIG_SAMV7_EMAC1_NTXBUFFERS +# define CONFIG_SAMV7_EMAC1_NTXBUFFERS 8 +# endif + +# if CONFIG_SAMV7_EMAC1_NTXBUFFERS <= 1 +# error CONFIG_SAMV7_EMAC1_NTXBUFFERS invalid +# endif + +# ifndef CONFIG_SAMV7_EMAC1_PHYADDR +# error "CONFIG_SAMV7_EMAC1_PHYADDR must be defined in the NuttX configuration" +# endif + +# if !defined(CONFIG_SAMV7_EMAC1_MII) && !defined(CONFIG_SAMV7_EMAC1_RMII) +# warning "Neither CONFIG_SAMV7_EMAC1_MII nor CONFIG_SAMV7_EMAC1_RMII defined" +# endif + +# if defined(CONFIG_SAMV7_EMAC1_MII) && defined(CONFIG_SAMV7_EMAC1_RMII) +# error "Both CONFIG_SAMV7_EMAC1_MII and CONFIG_SAMV7_EMAC1_RMII defined" +# endif + +# ifndef CONFIG_SAMV7_EMAC1_PHYSR +# error "CONFIG_SAMV7_EMAC1_PHYSR must be defined in the NuttX configuration" +# endif + +# ifdef CONFIG_SAMV7_EMAC1_AUTONEG +# ifdef CONFIG_SAMV7_EMAC1_PHYSR_ALTCONFIG +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_ALTMODE +# error "CONFIG_SAMV7_EMAC1_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_10HD +# error "CONFIG_SAMV7_EMAC1_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_100HD +# error "CONFIG_SAMV7_EMAC1_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_10FD +# error "CONFIG_SAMV7_EMAC1_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_100FD +# error "CONFIG_SAMV7_EMAC1_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_SPEED +# error "CONFIG_SAMV7_EMAC1_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_100MBPS +# error "CONFIG_SAMV7_EMAC1_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_MODE +# error "CONFIG_SAMV7_EMAC1_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_SAMV7_EMAC1_PHYSR_FULLDUPLEX +# error "CONFIG_SAMV7_EMAC1_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +# endif + + /* PHY definitions */ + +# if defined(SAMV7_EMAC1_PHY_DM9161) +# define EMAC1_MII_OUI_MSB 0x0181 +# define EMAC1_MII_OUI_LSB 0x2e +# elif defined(SAMV7_EMAC1_PHY_LAN8700) +# define EMAC1_MII_OUI_MSB 0x0007 +# define EMAC1_MII_OUI_LSB 0x30 +# elif defined(SAMV7_EMAC1_PHY_KSZ8051) +# define EMAC1_MII_OUI_MSB 0x0022 +# define EMAC1_MII_OUI_LSB 0x05 +# elif defined(SAMV7_EMAC1_PHY_KSZ8061) +# define EMAC1_MII_OUI_MSB 0x0022 +# define EMAC1_MII_OUI_LSB 0x05 +# elif defined(SAMV7_EMAC1_PHY_KSZ8081) +# define EMAC1_MII_OUI_MSB 0x0022 +# define EMAC1_MII_OUI_LSB 0x05 +# else +# error EMAC PHY unrecognized +# endif +#endif /* CONFIG_SAMV7_EMAC1 */ + +/* Common Configuration *****************************************************/ + +#undef CONFIG_SAMV7_EMAC_NBC + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMV7_EMAC_REGDEBUG +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define sam_dumppacket(m,a,n) +#endif + +/* EMAC buffer sizes, number of buffers, and number of descriptors *********** + * + * REVISIT: The CONFIG_NET_MULTIBUFFER might be useful. It might be possible + * to use this option to send and receive messages directly into the DMA + * buffers, saving a copy. There might be complications on the receiving + * side, however, where buffers may wrap and where the size of the received + * frame will typically be smaller than a full packet. + */ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER must not be set +#endif + +/* Queue identifiers/indices */ + +#define EMAC_QUEUE_0 0 +#define EMAC_QUEUE_1 1 +#define EMAC_QUEUE_2 2 +#define EMAC_NQUEUES 3 + +/* Interrupt settings */ + +#define EMAC_RX_INTS (EMAC_INT_RCOMP | EMAC_INT_RXUBR | EMAC_INT_ROVR) +#define EMAC_TXERR_INTS (EMAC_INT_TUR | EMAC_INT_RLEX | EMAC_INT_TFC | \ + EMAC_INT_HRESP) +#define EMAC_TX_INTS (EMAC_TXERR_INTS | EMAC_INT_TCOMP) + +/* Buffer Alignment. + * + * The EMAC peripheral requires that descriptors and buffers be aligned + * the 8-byte (2 word boundaries). However, if the data cache is enabled + * the a higher level of alignment is required. That is because the data + * will need to be invalidated and that cache invalidation will occur in + * multiples of full cache lines. + * + * In addition, padding may be required at the ends of the descriptors and + * buffers to protect data after the end of from invalidation. + */ + +#ifdef CONFIG_ARMV7M_DCACHE +/* Align to the cache line size which we assume is >= 8 */ + +# define EMAC_ALIGN ARMV7M_DCACHE_LINESIZE +# define EMAC_ALIGN_MASK (EMAC_ALIGN-1) +# define EMAC_ALIGN_UP(n) (((n) + EMAC_ALIGN_MASK) & ~EMAC_ALIGN_MASK) + +# define EMAC0_RX_DPADSIZE (EMAC0_RX_DESCSIZE & EMAC_ALIGN_MASK) +# define EMAC0_TX_DPADSIZE (EMAC0_TX_DESCSIZE & EMAC_ALIGN_MASK) +# define EMAC1_RX_DPADSIZE (EMAC1_RX_DESCSIZE & EMAC_ALIGN_MASK) +# define EMAC1_TX_DPADSIZE (EMAC1_TX_DESCSIZE & EMAC_ALIGN_MASK) + +#else +/* Use the minimum alignment requirement */ + +# define EMAC_ALIGN 8 +# define EMAC_ALIGN_MASK 7 +# define EMAC_ALIGN_UP(n) (((n) + 7) & ~7) + +# define EMAC0_RX_DPADSIZE 0 +# define EMAC0_TX_DPADSIZE 0 +# define EMAC1_RX_DPADSIZE 0 +# define EMAC1_TX_DPADSIZE 0 + +#endif + +/* Buffer sizes. + * + * RX buffer size if fixed at 128 bytes since fragmented incoming packets + * are handled. + */ + +#define EMAC_RX_UNITSIZE EMAC_ALIGN_UP(128) +#define EMAC_TX_UNITSIZE EMAC_ALIGN_UP(CONFIG_NET_ETH_MTU) +#define DUMMY_BUFSIZE EMAC_ALIGN_UP(128) +#define DUMMY_NBUFFERS 2 + +#define EMAC0_RX_DESCSIZE (CONFIG_SAMV7_EMAC0_NRXBUFFERS * sizeof(struct emac_rxdesc_s)) +#define EMAC0_TX_DESCSIZE (CONFIG_SAMV7_EMAC0_NTXBUFFERS * sizeof(struct emac_txdesc_s)) +#define EMAC0_RX_BUFSIZE (CONFIG_SAMV7_EMAC0_NRXBUFFERS * EMAC_RX_UNITSIZE) +#define EMAC0_TX_BUFSIZE (CONFIG_SAMV7_EMAC0_NTXBUFFERS * EMAC_TX_UNITSIZE) + +#define EMAC1_RX_DESCSIZE (CONFIG_SAMV7_EMAC1_NRXBUFFERS * sizeof(struct emac_rxdesc_s)) +#define EMAC1_TX_DESCSIZE (CONFIG_SAMV7_EMAC1_NTXBUFFERS * sizeof(struct emac_txdesc_s)) +#define EMAC1_RX_BUFSIZE (CONFIG_SAMV7_EMAC1_NRXBUFFERS * EMAC_RX_UNITSIZE) +#define EMAC1_TX_BUFSIZE (CONFIG_SAMV7_EMAC1_NTXBUFFERS * EMAC_TX_UNITSIZE) + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define SAM_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SAM_TXTIMEOUT (60*CLK_TCK) + +/* PHY read/write delays in loop counts */ + +#define PHY_RETRY_MAX 1000000 + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the EMAC + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure defines the constant an configured attributes of an EMAC */ + +struct sam_emacattr_s +{ + /* Basic hardware information */ + + uint32_t base; /* EMAC Register base address */ + xcpt_t handler; /* EMAC interrupt handler */ + uint8_t emac; /* EMACn, n=0 or 1 */ + uint8_t irq; /* EMAC interrupt number */ + + /* PHY Configuration */ + + uint8_t phyaddr; /* PHY address */ + uint8_t physr; /* PHY status register address */ + uint16_t msoui; /* MS 16 bits of the 18-bit OUI */ + uint8_t lsoui; /* LS 2 bits of the 18-bit OUI */ + bool rmii; /* True: RMII vs. False: MII */ + bool clause45; /* True: Clause 45 behavior */ +//bool autoneg; /* True: Autonegotiate rate and *plex */ + bool sralt; /* True: Alternate PHYSR bit access */ + + union + { + /* "Standard" form: Individual bits determine speed and half/full + * duplex. + */ + + struct + { + uint16_t stdmask; /* Mask for speed and *plex mode bits */ + uint16_t speed100; /* 100Base_t bit */ + uint16_t fduplex; /* Full duplex bit */ + } std; + + /* Alternative form: Speed and duplex are encoded in a single, + * multi-bit field. + */ + + struct + { + uint16_t altmask; /* Mask speed for mode bits */ + uint16_t hdx10; /* 10Base_T Half Duplex bit pattern */ + uint16_t hdx100; /* 100Base_T Half Duplex bit pattern */ + uint16_t fdx10; /* 10Base_T Half Duplex bit pattern */ + uint16_t fdx100; /* 100Base_T Half Duplex bit pattern */ + } alt; + } u; + + /* Buffer and descriptor configuration */ + + uint8_t ntxbuffers; /* Number of TX buffers */ + uint8_t nrxbuffers; /* Number of RX buffers */ + +#ifdef CONFIG_SAMV7_EMAC_PREALLOCATE + /* Attributes and addresses of preallocated buffers */ + + struct emac_txdesc_s *tx0desc; /* Preallocated TX descriptor list */ + struct emac_rxdesc_s *rx0desc; /* Preallocated RX descriptor list */ + uint8_t *tx0buffer; /* Preallocated TX buffers */ + uint8_t *rx0buffer; /* Preallocated RX buffers */ + + struct emac_txdesc_s *tx1desc; /* Preallocated TX dummy descriptor list */ + struct emac_rxdesc_s *rx1desc; /* Preallocated RX dummy descriptor list */ + uint8_t *tx1buffer; /* Preallocated TX dummy buffers */ + uint8_t *rx1buffer; /* Preallocated RX dummy buffers */ + +#endif +}; + +/* This structure describes one transfer queue */ + +struct sam_queue_s +{ + struct emac_rxdesc_s *rxdesc; /* Allocated RX descriptors */ + struct emac_txdesc_s *txdesc; /* Allocated TX descriptors */ + uint8_t *rxbuffer; /* Allocated RX buffers */ + uint8_t *txbuffer; /* Allocated TX buffers */ + uint16_t rxbufsize; /* Size of one RX buffer */ + uint16_t txbufsize; /* Size of one TX buffer */ + uint8_t nrxbuffers; /* Number of RX buffers/TDs */ + uint8_t rxndx; /* Current RX TD index */ + uint8_t ntxbuffers; /* Number of TX buffers/TDs */ + uint16_t txhead; /* Buffer head pointer */ + uint16_t txtail; /* Buffer tail pointer */ +}; + +/* The sam_emac_s encapsulates all state information for the EMAC peripheral */ + +struct sam_emac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to the NuttX network */ + + struct net_driver_s dev; /* Interface understood by the network */ + + /* Constant and configured attributes of the EMAC */ + + const struct sam_emacattr_s *attr; + + /* Used to track transmit and receive descriptors */ + + uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */ +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + uint8_t phytype; /* See SAMV7_EMAC0/1_PHY_TYPE definitions */ +#endif + + /* Transfer queues */ + + struct sam_queue_s xfrq[EMAC_NQUEUES]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_EMAC_REGDEBUG + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMV7_EMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, + uint32_t regval, uintptr_t address); +#endif + +static uint32_t sam_getreg(struct sam_emac_s *priv, uint16_t offset); +static void sam_putreg(struct sam_emac_s *priv, uint16_t offset, uint32_t val); + +/* Buffer management */ + +static uint16_t sam_txinuse(struct sam_emac_s *priv, int qid); +static uint16_t sam_txfree(struct sam_emac_s *priv, int qid); +static int sam_buffer_allocate(struct sam_emac_s *priv); +static void sam_buffer_free(struct sam_emac_s *priv); + +/* Common TX logic */ + +static int sam_transmit(struct sam_emac_s *priv, int qid); +static int sam_txpoll(struct net_driver_s *dev); +static void sam_dopoll(struct sam_emac_s *priv, int qid); + +/* Interrupt handling */ + +static int sam_recvframe(struct sam_emac_s *priv, int qid); +static void sam_receive(struct sam_emac_s *priv, int qid); +static void sam_txdone(struct sam_emac_s *priv, int qid); +static void sam_txerr_interrupt(FAR struct sam_emac_s *priv, int qid); +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv, + int qid); +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg); +#endif +static int sam_emac_interrupt(struct sam_emac_s *priv); +#ifdef CONFIG_SAMV7_EMAC0 +static int sam_emac0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_EMAC1 +static int sam_emac1_interrupt(int irq, void *context); +#endif + +/* Watchdog timer expirations */ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg); +#endif +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void sam_poll_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg); +#endif +static void sam_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int sam_ifup(struct net_driver_s *dev); +static int sam_ifdown(struct net_driver_s *dev); + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg); +#endif +static int sam_txavail(struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac); +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* PHY Initialization */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv); +#else +# define sam_phydump(priv) +#endif + +#if 0 /* Not used */ +static bool sam_is10hdx(struct sam_emac_s *priv, uint16_t physr); +#endif +static bool sam_is100hdx(struct sam_emac_s *priv, uint16_t physr); +static bool sam_is10fdx(struct sam_emac_s *priv, uint16_t physr); +static bool sam_is100fdx(struct sam_emac_s *priv, uint16_t physr); + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv); +#endif +static int sam_phywait(struct sam_emac_s *priv); +static int sam_phyreset(struct sam_emac_s *priv); +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr); +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval); +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval); +static int sam_autonegotiate(struct sam_emac_s *priv); +static bool sam_linkup(struct sam_emac_s *priv); +static int sam_phyinit(struct sam_emac_s *priv); + +/* EMAC Initialization */ + +static void sam_txreset(struct sam_emac_s *priv, int qid); +static void sam_rxreset(struct sam_emac_s *priv, int qid); +static void sam_emac_enableclk(struct sam_emac_s *priv); +#ifndef CONFIG_NETDEV_PHY_IOCTL +static void sam_emac_disableclk(struct sam_emac_s *priv); +#endif +static void sam_emac_reset(struct sam_emac_s *priv); +static void sam_macaddress(struct sam_emac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv); +#endif + +static int sam_queue0_configure(struct sam_emac_s *priv); +static int sam_queue_configure(struct sam_emac_s *priv, int qid); +static int sam_emac_configure(struct sam_emac_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_EMAC_PREALLOCATE +/* Preallocated data */ + +#ifdef CONFIG_SAMV7_EMAC0 +/* EMAC0 TX descriptors list */ + +static struct emac_txdesc_s g_emac0_tx0desc[CONFIG_SAMV7_EMAC0_NTXBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +#if EMAC0_TX_DPADSIZE > 0 +static uint8_t g_emac0_txdpad[EMAC0_TX_DPADSIZE] __atrribute__((used)); +#endif + +static struct emac_txdesc_s g_emac0_tx1desc[DUMMY_NBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC0 RX descriptors list */ + +static struct emac_rxdesc_s g_emac0_rx0desc[CONFIG_SAMV7_EMAC0_NRXBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +#if EMAC0_RX_DPADSIZE > 0 +static uint8_t g_emac0_rxdpad[EMAC0_RX_DPADSIZE] __atrribute__((used)); +#endif + +static struct emac_rxdesc_s g_emac0_rx1desc[DUMMY_NBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC0 Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_emac0_tx0buffer[EMAC0_TX_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +static uint8_t g_emac0_tx1buffer[DUMMY_NBUFFERS * DUMMY_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC0 Receive Buffers */ + +static uint8_t g_emac0_rx0buffer[EMAC0_RX_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +static uint8_t pRxDummyBuffer[DUMMY_NBUFFERS * DUMMY_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +#endif + +#ifdef CONFIG_SAMV7_EMAC1 +/* EMAC1 TX descriptors list */ + +static struct emac_txdesc_s g_emac1_tx1desc[CONFIG_SAMV7_EMAC1_NTXBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +#if EMAC1_TX_DPADSIZE > 0 +static uint8_t g_emac1_txdpad[EMAC1_TX_DPADSIZE] __atrribute__((used)); +#endif + +static struct emac_txdesc_s g_emac1_tx1desc[DUMMY_NBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC1 RX descriptors list */ + +static struct emac_rxdesc_s g_emac1_rx1desc[CONFIG_SAMV7_EMAC1_NRXBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +#if EMAC1_RX_DPADSIZE > 0 +static uint8_t g_emac1_rxdpad[EMAC1_RX_DPADSIZE] __atrribute__((used)); +#endif + +static struct emac_rxdesc_s g_emac1_rx1desc[DUMMY_NBUFFERS] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC1 Transmit Buffers + * + * Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries. + * Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address + * shall be set to 0 + */ + +static uint8_t g_emac1_tx1buffer[EMAC1_TX_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +static uint8_t g_emac1_tx1buffer[DUMMY_NBUFFERS * DUMMY_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +/* EMAC1 Receive Buffers */ + +static uint8_t g_emac1_rxbuffer[EMAC1_RX_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +static uint8_t g_emac1_rx1buffer[DUMMY_NBUFFERS * DUMMY_BUFSIZE] + __attribute__((aligned(EMAC_ALIGN))); + +#endif +#endif + +/* The driver state singletons */ + +#ifdef CONFIG_SAMV7_EMAC0 +static const struct sam_emacattr_s g_emac0_attr = +{ + /* Basic hardware information */ + + .base = SAM_EMAC0_BASE, + .handler = sam_emac0_interrupt, + .emac = EMAC0_INTF, + .irq = SAM_IRQ_EMAC0, + + /* PHY Configuration */ + + .phyaddr = CONFIG_SAMV7_EMAC0_PHYADDR, + .physr = CONFIG_SAMV7_EMAC0_PHYSR, + .msoui = EMAC0_MII_OUI_MSB, + .lsoui = EMAC0_MII_OUI_LSB, +#ifdef CONFIG_SAMV7_EMAC0_RMII + .rmii = true, +#endif +#ifdef CONFIG_SAMV7_EMAC0_CLAUSE45 + .clause45 = true, +#endif +#ifdef CONFIG_SAMV7_EMAC0_AUTONEG +//.autoneg = true, +#endif +#ifdef CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG + .sralt = true, +#endif + + .u = + { +#ifdef CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG + .alt = + { + .altmask = CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE, + .hdx10 = CONFIG_SAMV7_EMAC0_PHYSR_10HD, + .hdx100 = CONFIG_SAMV7_EMAC0_PHYSR_100HD, + .fdx10 = CONFIG_SAMV7_EMAC0_PHYSR_10FD, + .fdx100 = CONFIG_SAMV7_EMAC0_PHYSR_100FD, + }, +#else + .std = + { + .stdmask = (CONFIG_SAMV7_EMAC0_PHYSR_SPEED | CONFIG_SAMV7_EMAC0_PHYSR_MODE), + .speed100 = CONFIG_SAMV7_EMAC0_PHYSR_100MBPS, + .fduplex = CONFIG_SAMV7_EMAC0_PHYSR_FULLDUPLEX, + }, +#endif + }, + + /* Buffer and descriptor configuration */ + + .ntxbuffers = CONFIG_SAMV7_EMAC0_NTXBUFFERS, + .nrxbuffers = CONFIG_SAMV7_EMAC0_NRXBUFFERS, + +#ifdef CONFIG_SAMV7_EMAC_PREALLOCATE + /* Addresses of preallocated buffers */ + + .tx0desc = g_emac0_tx0desc, + .rx0desc = g_emac0_rx0desc, + .tx0buffer = g_emac0_tx0buffer, + .rx0buffer = g_emac0_rx0buffer, +#endif +}; + +static struct sam_emac_s g_emac0; +#endif + +#ifdef CONFIG_SAMV7_EMAC1 +static const struct sam_emacattr_s g_emac1_attr = +{ + /* Basic hardware information */ + + .base = SAM_EMAC1_BASE, + .handler = sam_emac1_interrupt, + .emac = EMAC1_INTF, + .irq = SAM_IRQ_EMAC1, + + /* PHY Configuration */ + + .phyaddr = CONFIG_SAMV7_EMAC1_PHYADDR, + .physr = CONFIG_SAMV7_EMAC1_PHYSR, + .msoui = EMAC1_MII_OUI_MSB, + .lsoui = EMAC1_MII_OUI_LSB, +#ifdef CONFIG_SAMV7_EMAC1_RMII + .rmii = true, +#endif +#ifdef CONFIG_SAMV7_EMAC1_CLAUSE45 + .clause45 = true, +#endif +#ifdef CONFIG_SAMV7_EMAC1_AUTONEG +//.autoneg = true, +#endif +#ifdef CONFIG_SAMV7_EMAC1_PHYSR_ALTCONFIG + .sralt = true, +#endif + + .u = + { +#ifdef CONFIG_SAMV7_EMAC1_PHYSR_ALTCONFIG + .alt = + { + .altmask = CONFIG_SAMV7_EMAC1_PHYSR_ALTMODE, + .hdx10 = CONFIG_SAMV7_EMAC1_PHYSR_10HD, + .hdx100 = CONFIG_SAMV7_EMAC1_PHYSR_100HD, + .fdx10 = CONFIG_SAMV7_EMAC1_PHYSR_10FD, + .fdx100 = CONFIG_SAMV7_EMAC1_PHYSR_100FD, + }, +#else + .std = + { + .stdmask = (CONFIG_SAMV7_EMAC1_PHYSR_SPEED | CONFIG_SAMV7_EMAC1_PHYSR_MODE), + .speed100 = CONFIG_SAMV7_EMAC1_PHYSR_100MBPS, + .fduplex = CONFIG_SAMV7_EMAC1_PHYSR_FULLDUPLEX, + }, +#endif + }, + + /* Buffer and descriptor configuration */ + + .ntxbuffers = CONFIG_SAMV7_EMAC1_NTXBUFFERS, + .nrxbuffers = CONFIG_SAMV7_EMAC1_NRXBUFFERS, + +#ifdef CONFIG_SAMV7_EMAC_PREALLOCATE + /* Attributes and addresses of preallocated buffers */ + + .txdesc = g_emac1_tx0desc, + .rxdesc = g_emac1_rx0desc, + .txbuffer = g_emac1_tx0buffer, + .rxbuffer = g_emac1_rxbuffer, +#endif +}; + +static struct sam_emac_s g_emac1; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_EMAC_REGDEBUG +static bool sam_checkreg(struct sam_emac_s *priv, bool wr, uint32_t regval, + uintptr_t regaddr) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + regaddr == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read a 32-bit EMAC register using an offset from the EMAC base address + * + ****************************************************************************/ + +static uint32_t sam_getreg(struct sam_emac_s *priv, uint16_t offset) +{ + uintptr_t regaddr = priv->attr->base + (uintptr_t)offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMV7_EMAC_REGDEBUG + if (sam_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write to a 32-bit EMAC register using an offset from the EMAC base + * address + * + ****************************************************************************/ + +static void sam_putreg(struct sam_emac_s *priv, uint16_t offset, + uint32_t regval) +{ + uintptr_t regaddr = priv->attr->base + (uintptr_t)offset; + +#ifdef CONFIG_SAMV7_EMAC_REGDEBUG + if (sam_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Function: sam_txinuse + * + * Description: + * Return the number of TX buffers in-use + * + * Input Parameters: + * priv - The EMAC driver state + * quid - The transfer queue to examine + * + * Returned Value: + * The number of TX buffers in-use + * + ****************************************************************************/ + +static uint16_t sam_txinuse(struct sam_emac_s *priv, int qid) +{ + struct sam_queue_s *xfrq = &priv->xfrq[qid]; + + uint32_t txhead32 = (uint32_t)xfrq->txhead; + if ((uint32_t)xfrq->txtail > txhead32) + { + txhead32 += xfrq->ntxbuffers; + } + + return (uint16_t)(txhead32 - (uint32_t)xfrq->txtail); +} + +/**************************************************************************** + * Function: sam_txfree + * + * Description: + * Return the number of TX buffers available + * + * Input Parameters: + * priv - The EMAC driver state + * qid - The transfer queue to examine + * + * Returned Value: + * The number of TX buffers available + * + ****************************************************************************/ + +static uint16_t sam_txfree(struct sam_emac_s *priv, int qid) +{ + /* The number available is equal to the total number of buffers, minus the + * number of buffers in use. Notice that that actual number of buffers is + * the configured size minus 1. + */ + + return (priv->xfrq[qid].ntxbuffers - 1) - sam_txinuse(priv, qid); +} + +/**************************************************************************** + * Function: sam_buffer_allocate + * + * Description: + * Allocate aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function degenerates to a few assignments. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +static int sam_buffer_allocate(struct sam_emac_s *priv) +{ +#ifdef CONFIG_SAMV7_EMAC_PREALLOCATE + struct sam_queue_s *xfrq; + int qid; + + /* Use pre-allocated buffers */ + + priv->xfrq[0].txdesc = priv->attr->tx0desc; + priv->xfrq[0].ntxbuffers = priv->attr->ntxbuffers; + priv->xfrq[0].rxdesc = priv->attr->rx0desc; + priv->xfrq[0].nrxbuffers = priv->attr->nrxbuffers; + + priv->xfrq[0].txbuffer = priv->attr->tx0buffer; + priv->xfrq[0].txbufsize = EMAC_TX_UNITSIZE; + priv->xfrq[0].rxbuffer = priv->attr->rx0buffer; + priv->xfrq[0].rxbufsize = EMAC_RX_UNITSIZE; + + /* Priority queues */ + + for (qid = 1; qid < EMAC_NQUEUES; qid++) + { + xfrq = &priv->xfrq[qid]; + + xfrq->txdesc = priv->attr->tx1desc; + xfrq->ntxbuffers = DUMMY_NBUFFERS; + xfrq->rxdesc = priv->attr->rx1desc; + xfrq->nrxbuffers = DUMMY_NBUFFERS; + + xfrq->txbuffer = priv->attr->tx1buffer; + xfrq->txbufsize = DUMMY_BUFSIZE; + xfrq->rxbuffer = priv->attr->rx1buffer; + xfrq->rxbufsize = DUMMY_BUFSIZE; + } + +#else + struct sam_queue_s *xfrq; + size_t allocsize; + int qid; + + /* Allocate Queue 0 buffers */ + + allocsize = EMAC_ALIGN_UP(priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s)); + priv->xfrq[0].txdesc = (struct emac_txdesc_s *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[0].txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->xfrq[0].txdesc, 0, allocsize); + priv->xfrq[0].ntxbuffers = priv->attr->ntxbuffers; + + allocsize = EMAC_ALIGN_UP(priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s)); + priv->xfrq[0].rxdesc = (struct emac_rxdesc_s *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[0].rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->xfrq[0].rxdesc, 0, allocsize); + priv->xfrq[0].nrxbuffers = priv->attr->nrxbuffers; + + allocsize = priv->attr->ntxbuffers * EMAC_TX_UNITSIZE; + priv->xfrq[0].txbuffer = (uint8_t *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[0].txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + priv->xfrq[0].txbufsize = EMAC_TX_UNITSIZE; + + allocsize = priv->attr->nrxbuffers * EMAC_RX_UNITSIZE; + priv->xfrq[0].rxbuffer = (uint8_t *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[0].rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + priv->xfrq[0].rxbufsize = EMAC_RX_UNITSIZE; + + /* Allocate Queue 1 buffers */ + + allocsize = EMAC_ALIGN_UP(DUMMY_NBUFFERS * sizeof(struct emac_txdesc_s)); + priv->xfrq[1].txdesc = (struct emac_txdesc_s *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[1].txdesc) + { + nlldbg("ERROR: Failed to allocate TX descriptors\n"); + return -ENOMEM; + } + + memset(priv->xfrq[1].txdesc, 0, allocsize); + priv->xfrq[1].ntxbuffers = DUMMY_NBUFFERS; + + allocsize = EMAC_ALIGN_UP(DUMMY_NBUFFERS * sizeof(struct emac_rxdesc_s)); + priv->xfrq[1].rxdesc = (struct emac_rxdesc_s *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[1].rxdesc) + { + nlldbg("ERROR: Failed to allocate RX descriptors\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + memset(priv->xfrq[1].rxdesc, 0, allocsize); + priv->xfrq[1].nrxbuffers = DUMMY_NBUFFERS; + + allocsize = DUMMY_NBUFFERS * DUMMY_BUFSIZE; + priv->xfrq[1].txbuffer = (uint8_t *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[1].txbuffer) + { + nlldbg("ERROR: Failed to allocate TX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + priv->xfrq[1].txbufsize = DUMMY_BUFSIZE; + + allocsize = DUMMY_NBUFFERS * DUMMY_BUFSIZE; + priv->xfrq[1].rxbuffer = (uint8_t *)kmm_memalign(EMAC_ALIGN, allocsize); + if (!priv->xfrq[1].rxbuffer) + { + nlldbg("ERROR: Failed to allocate RX buffer\n"); + sam_buffer_free(priv); + return -ENOMEM; + } + + priv->xfrq[1].rxbufsize = DUMMY_BUFSIZE; + + /* Clone the Priority Queue 1 allocations to the other priority queues */ + + for (qid = 2; qid < EMAC_NQUEUES; qid++) + { + xfrq = &priv->xfrq[qid]; + + xfrq->txdesc = priv->xfrq[1].txdesc; + xfrq->rxdesc = priv->xfrq[1].rxdesc; + + xfrq->txbuffer = priv->xfrq[1].txbuffer; + xfrq->rxbuffer = priv->xfrq[1].rxbuffer; + + xfrq->ntxbuffers = DUMMY_NBUFFERS; + xfrq->nrxbuffers = DUMMY_NBUFFERS; + + xfrq->txbufsize = DUMMY_BUFSIZE; + xfrq->rxbufsize = DUMMY_BUFSIZE; + } + +#endif + + /* Verify Alignment */ + + DEBUGASSERT(((uintptr_t)priv->xfrq[0].rxdesc & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[0].rxbuffer & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[0].txdesc & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[0].txbuffer & EMAC_ALIGN_MASK) == 0); + DEBUGASSERT(((uintptr_t)priv->xfrq[1].rxdesc & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[1].rxbuffer & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[1].txdesc & EMAC_ALIGN_MASK) == 0 && + ((uintptr_t)priv->xfrq[1].txbuffer & EMAC_ALIGN_MASK) == 0); + + return OK; +} + +/**************************************************************************** + * Function: sam_buffer_free + * + * Description: + * Free aligned TX and RX descriptors and buffers. For the case of + * pre-allocated structures, the function does nothing. + * + * Input Parameters: + * priv - The EMAC driver state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_buffer_free(struct sam_emac_s *priv) +{ +#ifndef CONFIG_SAMV7_EMAC_PREALLOCATE + struct sam_queue_s *xfrq; + int qid; + + /* Free allocated buffers */ + + for (qid = 0; qid < EMAC_NQUEUES; qid++) + { + xfrq = &priv->xfrq[qid]; + if (qid < 2) + { + if (xfrq->txdesc) + { + kmm_free(xfrq->txdesc); + xfrq->txdesc = NULL; + } + + if (xfrq->rxdesc) + { + kmm_free(xfrq->rxdesc); + xfrq->rxdesc = NULL; + } + + if (xfrq->txbuffer) + { + kmm_free(xfrq->txbuffer); + xfrq->txbuffer = NULL; + } + + if (xfrq->rxbuffer) + { + kmm_free(xfrq->rxbuffer); + xfrq->rxbuffer = NULL; + } + } + + xfrq->txdesc = NULL; + xfrq->rxdesc = NULL; + xfrq->txbuffer = NULL; + xfrq->rxbuffer = NULL; + } +#endif +} + +/**************************************************************************** + * Function: sam_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * REVISIT: This implementation does not support scatter-gather DMA. + * + * Parameters: + * priv - Reference to the driver state structure + * qid - The queue to send the frame + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_transmit(struct sam_emac_s *priv, int qid) +{ + struct net_driver_s *dev = &priv->dev; + volatile struct emac_txdesc_s *txdesc; + struct sam_queue_s *xfrq; + uint32_t regval; + uint32_t status; + uint16_t txhead; + + NETDEV_TXPACKETS(&priv->dev); + + /* Check parameter */ + + if (dev->d_len > EMAC_TX_UNITSIZE) + { + nlldbg("ERROR: Packet too big: %d\n", dev->d_len); + return -EINVAL; + } + + /* Pointer to the current TX descriptor */ + + xfrq = &priv->xfrq[qid]; + txhead = xfrq->txhead; + txdesc = &xfrq->txdesc[txhead]; + + nllvdbg("d_len: %d txhead[%d]: %d\n", dev->d_len, qid, xfrq->txhead); + sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len); + + /* If no free TX descriptor, buffer can't be sent */ + + if (sam_txfree(priv, qid) < 1) + { + nlldbg("ERROR: No free TX descriptors\n"); + return -EBUSY; + } + + /* Setup/Copy data to transmission buffer */ + + if (dev->d_len > 0) + { + /* Copy the data into the driver managed the ring buffer. If we + * wanted to support zero copy transfers, we would need to make sure + * that dev->d_buf and txdesc->addr refer to the same memory. + */ + + memcpy((void *)txdesc->addr, dev->d_buf, dev->d_len); + arch_clean_dcache((uint32_t)txdesc->addr, + (uint32_t)txdesc->addr + dev->d_len); + } + + /* Update TX descriptor status (with USED=0). */ + + status = dev->d_len | EMACTXD_STA_LAST; + if (txhead == xfrq->ntxbuffers - 1) + { + status |= EMACTXD_STA_WRAP; + } + + /* Update the descriptor status and flush the updated value to RAM */ + + txdesc->status = status; + arch_clean_dcache((uint32_t)txdesc, + (uint32_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Increment the head index */ + + if (++txhead >= xfrq->ntxbuffers) + { + txhead = 0; + } + + xfrq->txhead = txhead; + + /* Now start transmission (if it is not already done) */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_TSTART; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* REVISIT: Sometimes TSTART is missed? In this case, the symptom is + * that the packet is not sent until the next transfer when TXSTART + * is set again. + */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SAM_TXTIMEOUT, sam_txtimeout_expiry, 1, + (uint32_t)priv); + + /* Set d_len to zero meaning that the d_buf[] packet buffer is again + * available. + */ + + dev->d_len = 0; + + /* If we have no more available TX descriptors, then we must disable the + * RCOMP interrupt to stop further RX processing. Why? Because EACH RX + * packet that is dispatched is also an opportunity to replay with a TX + * packet. So, if we cannot handle an RX packet reply, then we disable + * all RX packet processing. + */ + + if (sam_txfree(priv, qid) < 1) + { + nllvdbg("Disabling RX interrupts\n"); + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_RCOMP); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_txpoll + * + * Description: + * The transmitter is available, check if the network has any outgoing + * packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int sam_txpoll(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + sam_transmit(priv, EMAC_QUEUE_0); + + /* Check if the there are any free TX descriptors. We cannot perform + * the TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv, EMAC_QUEUE_0) == 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: sam_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), + * 3. For certain TX errors (sam_txerr_interrupt), and + * 4. After a TX timeout to restart the sending process + * (sam_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * qid - The transfer queue to send packets on + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_dopoll(struct sam_emac_s *priv, int qid) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv, qid) > 0) + { + /* If we have the descriptor, then poll the network for new XMIT data. */ + + (void)devif_poll(dev, sam_txpoll); + } +} + +/**************************************************************************** + * Function: sam_recvframe + * + * Description: + * The function is called when a frame is received. It scans the RX + * descriptors of the received frame and assembles the full packet/ + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * qid - The transfer queue to receive the frame + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * - Global interrupts are disabled by interrupt handling logic. + * - The RX descriptor D-cache list has been invalided to force fetching + * from RAM. + * + ****************************************************************************/ + +static int sam_recvframe(struct sam_emac_s *priv, int qid) +{ + volatile struct emac_rxdesc_s *rxdesc; + struct sam_queue_s *xfrq; + struct net_driver_s *dev; + const uint8_t *src; + uint8_t *dest; + uint32_t rxndx; + uint32_t pktlen; + uint16_t copylen; + bool isframe; + + /* Process received RX descriptor. The ownership bit is set by the EMAC + * once it has successfully written a frame to memory. + */ + + dev = &priv->dev; + dev->d_len = 0; + + dest = dev->d_buf; + pktlen = 0; + + xfrq = &priv->xfrq[qid]; + rxndx = xfrq->rxndx; + rxdesc = &xfrq->rxdesc[rxndx]; + isframe = false; + + /* Invalidate the RX descriptor to force re-fetching from RAM. */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + + nllvdbg("Entry rxndx[%d]: %d\n", qid, rxndx); + + while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0) + { + NETDEV_RXFRAGMENTS(&priv->dev); + + /* The start of frame bit indicates the beginning of a frame. Discard + * any previous fragments. + */ + + if ((rxdesc->status & EMACRXD_STA_SOF) != 0) + { + /* Skip previous fragments. Loop incrementing the index to the + * start fragment until it is equal to the index with the SOF mark + */ + + while (rxndx != xfrq->rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &xfrq->rxdesc[xfrq->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index to the start fragment */ + + if (++xfrq->rxndx >= xfrq->nrxbuffers) + { + xfrq->rxndx = 0; + } + } + + /* Reset the packet data pointer and packet length */ + + dest = dev->d_buf; + pktlen = 0; + + /* Start to gather buffers into the packet buffer */ + + isframe = true; + } + + /* Increment the working index. rxndx points to the next fragment + * in this frame (or, if the LAST bit was set, to the first fragment + * of the next frame). + */ + + if (++rxndx >= xfrq->nrxbuffers) + { + rxndx = 0; + } + + /* Copy data into the packet buffer */ + + if (isframe) + { + if (rxndx == xfrq->rxndx) + { + nllvdbg("ERROR: No EOF (Invalid or buffers too small)\n"); + do + { + /* Give ownership back to the EMAC */ + + rxdesc = &xfrq->rxdesc[xfrq->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index */ + + if (++xfrq->rxndx >= xfrq->nrxbuffers) + { + xfrq->rxndx = 0; + } + } + while (rxndx != xfrq->rxndx); + + NETDEV_RXERRORS(&priv->dev); + return -EIO; + } + + /* Get the number of bytes to copy from the buffer */ + + copylen = EMAC_RX_UNITSIZE; + if ((pktlen + copylen) > CONFIG_NET_ETH_MTU) + { + copylen = CONFIG_NET_ETH_MTU - pktlen; + } + + /* Get the data source. Invalidate the source memory region to + * force reload from RAM. + */ + + src = (const uint8_t *)(rxdesc->addr & EMACRXD_ADDR_MASK); + arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); + + /* Copy the data from the driver managed the ring buffer. If we + * wanted to support zero copy transfers, we would need to make + * sure that dev->d_buf and rxdesc->addr refer to the same memory. + */ + + memcpy(dest, src, copylen); + dest += copylen; + pktlen += copylen; + + /* If the end of frame has been received, return the data */ + + if ((rxdesc->status & EMACRXD_STA_EOF) != 0) + { + /* Frame size from the EMAC */ + + dev->d_len = (rxdesc->status & EMACRXD_STA_FRLEN_MASK); + nllvdbg("packet %d-%d (%d)\n", xfrq->rxndx, rxndx, dev->d_len); + + /* All data have been copied in the application frame buffer, + * release the RX descriptor(s). Loop until all descriptors + * have been released up to the start of the next frame. + */ + + while (xfrq->rxndx != rxndx) + { + /* Give ownership back to the EMAC */ + + rxdesc = &xfrq->rxdesc[xfrq->rxndx]; + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* Increment the RX index of the descriptor that was just + * released. + */ + + if (++xfrq->rxndx >= xfrq->nrxbuffers) + { + xfrq->rxndx = 0; + } + } + + /* Check if the device packet buffer was large enough to accept + * all of the data. + */ + + nllvdbg("rxndx: %d d_len: %d\n", + xfrq->rxndx, dev->d_len); + if (pktlen < dev->d_len) + { + nlldbg("ERROR: Buffer size %d; frame size %d\n", + dev->d_len, pktlen); + NETDEV_RXERRORS(&priv->dev); + return -E2BIG; + } + + return OK; + } + } + + /* We found a descriptor that we own, but we have not encountered the + * SOF yet... discard this fragment and keep looking starting at the + * next fragment. + */ + + else + { + /* Give ownership back to the EMAC */ + + rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); + + /* Flush the modified RX descriptor to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + sizeof(struct emac_rxdesc_s)); + + /* rxndx already points to the next fragment to be examined. + * Use it to update the candidate Start-of-Frame. + */ + + xfrq->rxndx = rxndx; + } + + /* Set-up to process the next fragment. Get the RX descriptor + * associated with the next fragment. + */ + + rxdesc = &xfrq->rxdesc[rxndx]; + + /* Invalidate the RX descriptor to force re-fetching from RAM */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); + } + + /* No packet was found */ + + xfrq->rxndx = rxndx; + nllvdbg("Exit rxndx[%d]: %d\n", qid, xfrq->rxndx); + return -EAGAIN; +} + +/**************************************************************************** + * Function: sam_receive + * + * Description: + * An interrupt was received indicating the availability of one or more + * new RX packets in FIFO memory. + * + * Parameters: + * priv - Reference to the driver state structure + * qid - The transfer queue on which the packet was recieved + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void sam_receive(struct sam_emac_s *priv, int qid) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while sam_recvframe() successfully retrieves valid + * EMAC frames. + */ + + while (sam_recvframe(priv, qid) == OK) + { + sam_dumppacket("Received packet", dev->d_buf, dev->d_len); + NETDEV_RXPACKETS(&priv->dev); + + /* Check if the packet is a valid size for the network buffer + * configuration (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + NETDEV_RXERRORS(&priv->dev); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv, qid); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + sam_transmit(priv, qid); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + NETDEV_RXARP(&priv->dev); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + sam_transmit(priv, qid); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + NETDEV_RXDROPPED(&priv->dev); + } + } +} + +/**************************************************************************** + * Function: sam_txdone + * + * Description: + * An interrupt was received indicating that one or more frames have + * completed transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * qid - The transfer queue on which the packet was sent + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txdone(struct sam_emac_s *priv, int qid) +{ + struct emac_txdesc_s *txdesc; + struct sam_queue_s *xfrq; + uint16_t tail; + + /* Are there any outstanding transmissions? Loop until either (1) all of + * the TX descriptors have been examined, or (2) until we encounter the + * first descriptor that is still in use by the hardware. + */ + + xfrq = &priv->xfrq[qid]; + tail = xfrq->txtail; + + while (tail != xfrq->txhead) + { + /* Yes.. check the next buffer at the tail of the list */ + + txdesc = &xfrq->txdesc[tail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Break out of the loop if frame has not yet been sent. On TX + * completion, the GMAC sets the USED bit only into the very first + * buffer descriptor of the sent frame. Otherwise it updates this + * descriptor with status error bits. + */ + + if ((txdesc->status & EMACTXD_STA_USED) == 0) + { + /* The descriptor is still in use. Break out of the loop now. */ + + break; + } + + NETDEV_TXDONE(&priv->dev); + + /* Process all buffers of the current transmitted frame */ + + while (tail != xfrq->txhead && + (txdesc->status & EMACTXD_STA_LAST) == 0) + { + /* Increment the tail index */ + + if (++tail >= xfrq->ntxbuffers) + { + tail = 0; + } + + /* Get the next TX descriptor */ + + txdesc = &xfrq->txdesc[tail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + } + + /* Go to first buffer of the next frame */ + + if (tail != xfrq->txhead && + ++tail >= xfrq->ntxbuffers) + { + tail = 0; + } + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_EMAC_IER_OFFSET, EMAC_RX_INTS); + } + + /* Save the new tail index */ + + xfrq->txtail = tail; + + /* Then poll the network for new XMIT data */ + + sam_dopoll(priv, qid); +} + +/**************************************************************************** + * Function: sam_txerr_interrupt + * + * Description: + * TX error interrupt processing. + * + * Parameters: + * priv - Reference to the driver state structure + * quid - Index of the transfer queue that generated the interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static void sam_txerr_interrupt(FAR struct sam_emac_s *priv, int qid) +{ + struct emac_txdesc_s *txdesc; + struct sam_queue_s *xfrq; + uint32_t regval; + uint16_t tail; + + NETDEV_TXERRORS(&priv->dev); + + /* Clear TXEN bit into the Network Configuration Register. This is a + * workaround to recover from TX lockups that occurred on the sama5d3 gmac + * (r1p24f2) when using scatter-gather. This issue has never been + * seen on sama5d4 gmac (r1p31). + */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* The following step should be optional since this function is called + * directly by the IRQ handler. Indeed, according to Cadence + * documentation, the transmission is halted on errors such as + * too many retries or transmit under run. However it would becom + * mandatory if the call of this function were scheduled as a task by + * the IRQ handler (this is how Linux driver works). Then this function + * might compete with GMACD_Send(). + * + * Setting bit 10, tx_halt, of the Network Control Register is not enough: + * We should wait for bit 3, tx_go, of the Transmit Status Register to + * be cleared at transmit completion if a frame is being transmitted. + */ + + regval |= EMAC_NCR_THALT; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + while ((sam_getreg(priv, SAM_EMAC_TSR_OFFSET) & EMAC_TSR_TXGO) != 0); + + /* Treat frames in TX queue including the ones that caused the error. */ + + xfrq = &priv->xfrq[qid]; + tail = xfrq->txtail; + + while (tail != xfrq->txhead) + { + txdesc = &xfrq->txdesc[tail]; + + /* Make H/W updates to the TX descriptor visible to the CPU. */ + + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + + /* Go to the last buffer descriptor of the frame */ + + while (tail != xfrq->txhead && + (txdesc->status & EMACTXD_STA_LAST) == 0) + { + /* Increment the tail index */ + + if (++tail >= xfrq->ntxbuffers) + { + tail = 0; + } + + /* Get the next TX descriptor */ + + txdesc = &xfrq->txdesc[tail]; + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); + } + + /* Go to first buffer of the next frame */ + + if (tail != xfrq->txhead && + ++tail >= xfrq->ntxbuffers) + { + tail = 0; + } + } + + /* Save the new tail index */ + + xfrq->txtail = tail; + + /* Reset TX queue */ + + sam_txreset(priv, qid); + + /* Clear status */ + + regval = sam_getreg(priv, SAM_EMAC_TSR_OFFSET); + sam_putreg(priv, SAM_EMAC_TSR_OFFSET, regval); + + /* Now we are ready to start transmission again */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* At least one TX descriptor is available. Re-enable RX interrupts. + * RX interrupts may previously have been disabled when we ran out of + * TX descriptors (see comments in sam_transmit()). + */ + + sam_putreg(priv, SAM_EMAC_IER_OFFSET, EMAC_RX_INTS); + + /* Then poll the network for new XMIT data */ + + sam_dopoll(priv, qid); +} + +/**************************************************************************** + * Function: sam_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * quid - Index of the transfer queue that generated the interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void sam_interrupt_process(FAR struct sam_emac_s *priv, int qid) +{ + uint32_t isr; + uint32_t rsr; + uint32_t tsr; + uint32_t imr; + uint32_t regval; + uint32_t pending; + uint32_t clrbits; + + /* Read the interrupt status, RX status, and TX status registers. + * NOTE that the interrupt status register is cleared by this read. + */ + + isr = sam_getreg(priv, SAM_EMAC_ISR_OFFSET); + rsr = sam_getreg(priv, SAM_EMAC_RSR_OFFSET); + tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET); + + /* Make the pending interrupt status (probably not necessary) */ + + imr = sam_getreg(priv, SAM_EMAC_IMR_OFFSET); + pending = isr & ~(imr | EMAC_INT_UNUSED); + + nllvdbg("isr: %08x pending: %08x\n", isr, pending); + + /* Check for the receipt of an RX packet. + * + * RXCOMP indicates that a packet has been received and stored in memory. + * The RXCOMP bit is cleared when the interrupt status register was read. + * RSR:REC indicates that one or more frames have been received and placed + * in memory. This indication is cleared by writing a one to this bit. + */ + + if ((pending & EMAC_RX_INTS) != 0 || (rsr & EMAC_RSR_REC) != 0) + { + clrbits = EMAC_RSR_REC; + + /* Check for Receive Overrun. + * + * RSR:RXOVR will be set if the RX FIFO is not able to store the + * receive frame due to a FIFO overflow, or if the receive status + * was not taken at the end of the frame. This bit is also set in + * DMA packet buffer mode if the packet buffer overflows. For DMA + * operation, the buffer will be recovered if an overrun occurs. This + * bit is cleared when set to 1. + */ + + if ((rsr & EMAC_RSR_RXOVR) != 0) + { + nlldbg("ERROR: Receiver overrun RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_RXOVR; + } + + /* Check for buffer not available (BNA) + * + * RSR:BNA means that an attempt was made to get a new buffer and the + * pointer indicated that it was owned by the processor. The DMA will + * reread the pointer each time an end of frame is received until a + * valid pointer is found. This bit is set following each descriptor + * read attempt that fails, even if consecutive pointers are + * unsuccessful and software has in the mean time cleared the status + * flag. Cleared by writing a one to this bit. + */ + + if ((rsr & EMAC_RSR_BNA) != 0) + { + nlldbg("ERROR: Buffer not available RSR: %08x\n", rsr); + clrbits |= EMAC_RSR_BNA; + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_RSR_OFFSET, clrbits); + + /* Handle the received packet */ + + sam_receive(priv, qid); + } + + /* Check for TX errors */ + + if ((pending & EMAC_TXERR_INTS) != 0) + { + sam_txerr_interrupt(priv, qid); + } + + /* Check for the completion of a transmission. This should be done before + * checking for received data (because receiving can cause another transmission + * before we had a chance to handle the last one). + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read. + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + if ((pending & EMAC_INT_TCOMP) != 0 || (tsr & EMAC_TSR_TXCOMP) != 0) + { + /* A frame has been transmitted */ + /* Check for Retry Limit Exceeded (RLE) */ + + if ((tsr & EMAC_TSR_RLE) != 0) + { + /* Status RLE & Number of discarded buffers */ + + clrbits = EMAC_TSR_RLE | sam_txinuse(priv, qid); + sam_txreset(priv, qid); + + nlldbg("ERROR: Retry Limit Exceeded TSR: %08x\n", tsr); + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + + /* Check Collision Occurred (COL) */ + + if ((tsr & EMAC_TSR_COL) != 0) + { + nlldbg("ERROR: Collision occurred TSR: %08x\n", tsr); + NETDEV_TXERRORS(&priv->dev); + } + + /* Check Transmit Frame Corruption due to AHB error (TFC) */ + + if ((tsr & EMAC_TSR_TFC) != 0) + { + nlldbg("ERROR: Transmit Frame Corruption due to AHB error: %08x\n", tsr); + NETDEV_TXERRORS(&priv->dev); + } + + /* Clear status */ + + sam_putreg(priv, SAM_EMAC_TSR_OFFSET, tsr); + + /* And handle the TX done event */ + + sam_txdone(priv, qid); + } + +#ifdef CONFIG_DEBUG_NET + /* Check for response not OK */ + + if ((pending & EMAC_INT_HRESP) != 0) + { + nlldbg("ERROR: Hresp not OK\n"); + } + + /* Check for PAUSE Frame received (PFRE). + * + * ISR:PFRE indicates that a pause frame has been received with non-zero + * pause quantum. Cleared on a read. + */ + + if ((pending & EMAC_INT_PFNZ) != 0) + { + nlldbg("Pause frame received\n"); + } + + /* Check for Pause Time Zero (PTZ) + * + * ISR:PTZ is set Pause Time Zero + */ + + if ((pending & EMAC_INT_PTZ) != 0) + { + nlldbg("Pause TO!\n"); + } +#endif +} + +/**************************************************************************** + * Function: sam_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_interrupt_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_interrupt_process(priv, EMAC_QUEUE_0); + net_unlock(state); + + /* Re-enable Ethernet interrupts */ + + up_enable_irq(priv->attr->irq); +} +#endif + +/**************************************************************************** + * Function: sam_emac_interrupt + * + * Description: + * Common hardware interrupt handler + * + * Parameters: + * priv - Reference to the EMAC private state structure + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_interrupt(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NET_NOINTS + uint32_t tsr; + + /* Disable further Ethernet interrupts. Because Ethernet interrupts are + * also disabled if the TX timeout event occurs, there can be no race + * condition here. + */ + + up_disable_irq(priv->attr->irq); + + /* Check for the completion of a transmission. Careful: + * + * ISR:TCOMP is set when a frame has been transmitted. Cleared on read (so + * we cannot read it here). + * TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a + * one to this bit. + */ + + tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET); + if ((tsr & EMAC_TSR_TXCOMP) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be do race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_interrupt_work, priv, 0); + +#else + /* Process the interrupt now */ + + sam_interrupt_process(priv, EMAC_QUEUE_0); +#endif + + return OK; +} + +/**************************************************************************** + * Function: sam_emac0/1_interrupt + * + * Description: + * EMAC hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_EMAC0 +static int sam_emac0_interrupt(int irq, void *context) +{ + return sam_emac_interrupt(&g_emac0); +} +#endif + +#ifdef CONFIG_SAMV7_EMAC1 +static int sam_emac1_interrupt(int irq, void *context) +{ + return sam_emac_interrupt(&g_emac1); +} +#endif + +/**************************************************************************** + * Function: sam_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv) +{ + nlldbg("Timeout!\n"); + NETDEV_TXTIMEOUTS(&priv->dev); + + /* Reset the hardware. Just take the interface down, then back up again. */ + + sam_ifdown(&priv->dev); + sam_ifup(&priv->dev); + + /* Then poll the network for new XMIT data */ + + sam_dopoll(priv, EMAC_QUEUE_0); +} + +/**************************************************************************** + * Function: sam_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txtimeout_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + sam_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + */ + + up_disable_irq(priv->attr->irq); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txtimeout_work, priv, 0); +#else + /* Process the timeout now */ + + sam_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_poll_process(FAR struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the there are any free TX descriptors. We cannot perform the + * TX poll if we do not have buffering for another packet. + */ + + if (sam_txfree(priv, EMAC_QUEUE_0) > 0) + { + /* Update TCP timing states and poll the network for new XMIT data. */ + + (void)devif_timer(dev, sam_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: sam_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_poll_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void sam_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg); + } + +#else + /* Process the interrupt now */ + + sam_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: sam_ifup + * + * Description: + * NuttX Callback: Bring up the EMAC interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifup(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the EMAC interface for normal operation. */ + + nllvdbg("Initialize the EMAC\n"); + sam_emac_configure(priv); + sam_queue_configure(priv, EMAC_QUEUE_1); + sam_queue_configure(priv, EMAC_QUEUE_2); + sam_queue0_configure(priv); + + /* Set the MAC address (should have been configured while we were down) */ + + sam_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + sam_ipv6multicast(priv); +#endif + + /* Initialize for PHY access */ + + ret = sam_phyinit(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phyinit failed: %d\n", ret); + return ret; + } + + /* Auto Negotiate, working in RMII mode */ + + ret = sam_autonegotiate(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_autonegotiate failed: %d\n", ret); + return ret; + } + + while (sam_linkup(priv) == 0); + nllvdbg("Link detected \n"); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, (uint32_t)priv); + + /* Enable the EMAC interrupt */ + + priv->ifup = true; + up_enable_irq(priv->attr->irq); + return OK; +} + +/**************************************************************************** + * Function: sam_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_ifdown(struct net_driver_s *dev) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + irqstate_t flags; + + nlldbg("Taking the network down\n"); + + /* Disable the EMAC interrupt */ + + flags = enter_critical_section(); + up_disable_irq(priv->attr->irq); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the sam_ifup() always + * successfully brings the interface back up. + */ + + sam_emac_reset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: sam_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void sam_txavail_process(FAR struct sam_emac_s *priv) +{ + nllvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll the network for new XMIT data */ + + sam_dopoll(priv, EMAC_QUEUE_0); + } +} + +/**************************************************************************** + * Function: sam_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void sam_txavail_work(FAR void *arg) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + sam_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: sam_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int sam_txavail(struct net_driver_s *dev) +{ + FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, sam_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + sam_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_hashindx + * + * Description: + * Cacuclate the hash address register index. The hash address register + * is 64 bits long and takes up two locations in the memory map. The + * destination address is reduced to a 6-bit index into the 64-bit Hash + * Register using the following hash function: The hash function is an XOR + * of every sixth bit of the destination address. + * + * ndx:05 = da:05 ^ da:11 ^ da:17 ^ da:23 ^ da:29 ^ da:35 ^ da:41 ^ da:47 + * ndx:04 = da:04 ^ da:10 ^ da:16 ^ da:22 ^ da:28 ^ da:34 ^ da:40 ^ da:46 + * ndx:03 = da:03 ^ da:09 ^ da:15 ^ da:21 ^ da:27 ^ da:33 ^ da:39 ^ da:45 + * ndx:02 = da:02 ^ da:08 ^ da:14 ^ da:20 ^ da:26 ^ da:32 ^ da:38 ^ da:44 + * ndx:01 = da:01 ^ da:07 ^ da:13 ^ da:19 ^ da:25 ^ da:31 ^ da:37 ^ da:43 + * ndx:00 = da:00 ^ da:06 ^ da:12 ^ da:18 ^ da:24 ^ da:30 ^ da:36 ^ da:42 + * + * Where da:00 represents the least significant bit of the first byte + * received and da:47 represents the most significant bit of the last byte + * received. + * + * Input Parameters: + * mac - The multicast address to be hashed + * + * Returned Value: + * The 6-bit hash table index + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static unsigned int sam_hashindx(const uint8_t *mac) +{ + unsigned int ndx; + + /* Isolate: mac[0] + * ... 05 04 03 02 01 00] */ + + ndx = mac[0]; + + /* Isolate: mac[1] mac[0] + * ...11 10 09 08] [07 06 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + */ + + ndx ^= (mac[1] << 2) | (mac[0] >> 6); + + /* Isolate: mac[2] mac[1] + * ... 17 16] [15 14 13 12 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + */ + + ndx ^= (mac[2] << 4) | (mac[1] >> 4); + + /* Isolate: mac[2] + * [23 22 21 20 19 18 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + */ + + ndx ^= (mac[2] >> 2); + + /* Isolate: mac[3] + * ... 29 28 27 26 25 24] + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + */ + + ndx ^= mac[3]; + + /* Isolate: mac[4] mac[3] + * ... 35 34 33 32] [31 30 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + */ + + ndx ^= (mac[4] << 2) | (mac[3] >> 6); + + /* Isolate: mac[5] mac[4] + * ... 41 40] [39 38 37 36 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + */ + + ndx ^= (mac[5] << 4) | (mac[4] >> 4); + + /* Isolate: mac[5] + * [47 46 45 44 43 42 ... + * + * Accumulate: 05 04 03 02 01 00 + * XOR: 11 10 09 08 07 06 + * XOR: 17 16 15 14 13 12 + * XOR: 23 22 21 20 19 18 + * XOR: 29 28 27 26 25 24 + * XOR: 35 34 33 32 31 30 + * XOR: 41 40 39 38 37 36 + * XOR: 47 46 45 44 43 42 + */ + + ndx ^= (mac[5] >> 2); + + /* Mask out the garbage bits and return the 6-bit index */ + + return ndx & 0x3f; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regoffset; + unsigned int ndx; + unsigned int bit; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Add the multicast address to the hardware multicast hash table */ + + if (ndx >= 32) + { + regoffset = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regoffset = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regoffset); + regval |= bit; + sam_putreg(priv, regoffset, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~EMAC_NCFGR_UNIHEN; /* Disable unicast matching */ + regval |= EMAC_NCFGR_MTIHEN; /* Enable multicast matching */ + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + uint32_t regval; + unsigned int regoffset1; + unsigned int regoffset2; + unsigned int ndx; + unsigned int bit; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Calculate the 6-bit has table index */ + + ndx = sam_hashindx(mac); + + /* Remove the multicast address to the hardware multicast hast table */ + + if (ndx >= 32) + { + regoffset1 = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + regoffset2 = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + bit = 1 << (ndx - 32); /* Bit 0-31 */ + } + else + { + regoffset1 = SAM_EMAC_HRB_OFFSET; /* Hash Register Bottom [31:0] Register */ + regoffset2 = SAM_EMAC_HRT_OFFSET; /* Hash Register Top [63:32] Register */ + bit = 1 << ndx; /* Bit 0-31 */ + } + + regval = sam_getreg(priv, regoffset1); + regval &= ~bit; + sam_putreg(priv, regoffset1, regval); + + /* The unicast hash enable and the multicast hash enable bits in the + * Network Configuration Register enable the reception of hash matched + * frames: + * + * - A multicast match will be signalled if the multicast hash enable bit + * is set, da:00 is logic 1 and the hash index points to a bit set in + * the Hash Register. + * - A unicast match will be signalled if the unicast hash enable bit is + * set, da:00 is logic 0 and the hash index points to a bit set in the + * Hash Register. + */ + + /* Are all multicast address matches disabled? */ + + if (regval == 0 && sam_getreg(priv, regoffset2) == 0) + { + /* Yes.. disable all address matching */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_UNIHEN | EMAC_NCFGR_MTIHEN); + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: sam_ioctl + * + * Description: + * Handles driver ioctl calls: + * + * SIOCMIINOTIFY - Set up to received notifications from PHY interrupting + * events. + * + * SIOCGMIIPHY, SIOCGMIIREG, and SIOCSMIIREG: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int sam_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + struct sam_emac_s *priv = (struct sam_emac_s *)dev->d_private; + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = sam_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = priv->phyaddr; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Read from the requested register */ + + ret = sam_phyread(priv, req->phy_id, req->reg_num, &req->val_out); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t regval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Write to the requested register */ + + ret = sam_phywrite(priv, req->phy_id, req->reg_num, req->val_in); + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: sam_phydump + * + * Description: + * Dump the contents of PHY registers + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_VERBOSE) +static void sam_phydump(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t phyval; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + nllvdbg("%s Registers (Address %02x)\n", + priv->attr->rmii ? "RMII" : "MII", priv->phyaddr); + + sam_phyread(priv, priv->phyaddr, MII_MCR, &phyval); + nllvdbg(" MCR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_MSR, &phyval); + nllvdbg(" MSR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_ADVERTISE, &phyval); + nllvdbg(" ADVERTISE: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, MII_LPA, &phyval); + nllvdbg(" LPR: %04x\n", phyval); + sam_phyread(priv, priv->phyaddr, priv->attr->physr, &phyval); + nllvdbg(" PHYSR: %04x\n", phyval); + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); +} +#endif + +/**************************************************************************** + * Function: sam_is* + * + * Description: + * Helpers to simplify decoding PHY status register bits + * + * Parameters: + * physr - The value of the PHY status register + * + * Returned Value: + * True: The PHY configuration is selected; False; some other PHY + * configuration is selected. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static bool sam_is10hdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.hdx10; + } + else + { + mask = priv->attr->u.std.stdmask; + match = 0; + } + + return (physr & mask) == match; +} +#endif + +static bool sam_is100hdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.hdx100; + } + else + { + mask = priv->attr->u.std.stdmask; + match = priv->attr->u.std.speed100; + } + + return (physr & mask) == match; +} + +static bool sam_is10fdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.fdx10; + } + else + { + mask = priv->attr->u.std.stdmask; + match = priv->attr->u.std.fduplex; + } + + return (physr & mask) == match; +} + +static bool sam_is100fdx(struct sam_emac_s *priv, uint16_t physr) +{ + uint16_t mask; + uint16_t match; + + if (priv->attr->sralt) + { + mask = priv->attr->u.alt.altmask; + match = priv->attr->u.alt.fdx100; + } + else + { + mask = priv->attr->u.std.stdmask; + match = (priv->attr->u.std.fduplex | priv->attr->u.std.speed100); + } + + return (physr & mask) == match; +} + +/**************************************************************************** + * Function: sam_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int sam_phyintenable(struct sam_emac_s *priv) +{ +#if defined(SAMV7_EMAC0_PHY_KSZ8051) || defined(SAMV7_EMAC0_PHY_KSZ8061) || \ + defined(SAMV7_EMAC0_PHY_KSZ8081) || \ + defined(SAMV7_EMAC1_PHY_KSZ8051) || defined(SAMV7_EMAC1_PHY_KSZ8061) || \ + defined(SAMV7_EMAC1_PHY_KSZ8081) + uint32_t regval; + uint16_t phyval; + int ret; + + /* Does this MAC support a KSZ80x1 PHY? */ + + if (priv->phytype == SAMV7_PHY_KSZ8051 || + priv->phytype == SAMV7_PHY_KSZ8061 || + priv->phytype == SAMV7_PHY_KSZ8081) + { + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); + + /* Read the interrupt status register in order to clear any pending + * interrupts + */ + + ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval); + if (ret == OK) + { + /* Enable link up/down interrupts */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, + (MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); + } + + /* Disable management port (probably) */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + } + else +#endif + { + ndbg("ERROR: Unsupported PHY type: %d\n", priv->phytype); + ret = -ENOSYS; + } + + return ret; +} +#endif + +/**************************************************************************** + * Function: sam_phywait + * + * Description: + * Wait for the PHY to become IDLE + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +static int sam_phywait(struct sam_emac_s *priv) +{ + volatile unsigned int retries; + + /* Loop for the configured number of attempts */ + + for (retries = 0; retries < PHY_RETRY_MAX; retries++) + { + /* Is the PHY IDLE */ + + if ((sam_getreg(priv, SAM_EMAC_NSR_OFFSET) & EMAC_NSR_IDLE) != 0) + { + return OK; + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: sam_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyreset(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t mcr; + int timeout; + int ret; + + nllvdbg(" sam_phyreset\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Reset the PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + nlldbg("ERROR: sam_phywrite failed: %d\n", ret); + } + + /* Wait for the PHY reset to complete */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < 10; timeout++) + { + mcr = MII_MCR_RESET; + int result = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (result < 0) + { + nlldbg("ERROR: Failed to read the MCR register: %d\n", ret); + ret = result; + } + else if ((mcr & MII_MCR_RESET) == 0) + { + ret = OK; + break; + } + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyfind + * + * Description: + * Verify the PHY address and, if it is bad, try to one that works. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyfind(struct sam_emac_s *priv, uint8_t *phyaddr) +{ + uint32_t regval; + uint16_t phyval; + uint8_t candidate; + unsigned int offset; + int ret = -ESRCH; + + nllvdbg("Find a valid PHY address\n"); + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + candidate = *phyaddr; + + /* Check current candidate address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == priv->attr->msoui) + { + *phyaddr = candidate; + ret = OK; + } + + /* The current address does not work... try another */ + + else + { + nlldbg("ERROR: sam_phyread failed for PHY address %02x: %d\n", + candidate, ret); + + for (offset = 0; offset < 32; offset++) + { + /* Get the next candidate PHY address */ + + candidate = (candidate + 1) & 0x1f; + + /* Try reading the PHY ID from the candidate PHY address */ + + ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval); + if (ret == OK && phyval == priv->attr->msoui) + { + ret = OK; + break; + } + } + } + + if (ret == OK) + { + nllvdbg(" PHYID1: %04x PHY addr: %d\n", phyval, candidate); + *phyaddr = candidate; + sam_phyread(priv, candidate, priv->attr->physr, &phyval); + nllvdbg(" PHYSR: %04x PHY addr: %d\n", phyval, candidate); + } + + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phyread(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t *phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(0) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_READ | EMAC_MAN_WZO; + + if (!priv->attr->clause45) + { + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, + * bit 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; + } + + sam_putreg(priv, SAM_EMAC_MAN_OFFSET, regval); + + /* Wait until the PHY is again idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Return data */ + + *phyval = (uint16_t)(sam_getreg(priv, SAM_EMAC_MAN_OFFSET) & EMAC_MAN_DATA_MASK); + return OK; +} + +/**************************************************************************** + * Function: sam_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * priv - A reference to the private driver state structure + * phyaddr - The PHY device address + * regaddr - The PHY register address + * phyval - The 16-bit value to write to the PHY register. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_phywrite(struct sam_emac_s *priv, uint8_t phyaddr, + uint8_t regaddr, uint16_t phyval) +{ + uint32_t regval; + int ret; + + /* Make sure that the PHY is idle */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + /* Write the PHY Maintenance register */ + + regval = EMAC_MAN_DATA(phyval) | EMAC_MAN_WTN | EMAC_MAN_REGA(regaddr) | + EMAC_MAN_PHYA(phyaddr) | EMAC_MAN_WRITE | EMAC_MAN_WZO; + + if (!priv->attr->clause45) + { + /* CLTTO must be set for Clause 22 operation. To read clause 45 PHYs, + * bit 30 should be written with a 0 rather than a 1. + */ + + regval |= EMAC_MAN_CLTTO; + } + + sam_putreg(priv, SAM_EMAC_MAN_OFFSET, regval); + + /* Wait until the PHY is again IDLE */ + + ret = sam_phywait(priv); + if (ret < 0) + { + nlldbg("ERROR: sam_phywait failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Function: sam_autonegotiate + * + * Description: + * Autonegotiate speed and duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_autonegotiate(struct sam_emac_s *priv) +{ + uint32_t regval; + uint32_t ncr; + uint16_t phyid1; + uint16_t phyid2; + uint16_t mcr; + uint16_t msr; + uint16_t advertise; + uint16_t lpa; + int timeout; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Verify tht we can read the PHYID register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID1, &phyid1); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID1\n"); + goto errout; + } + + nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr); + + ret = sam_phyread(priv, priv->phyaddr, MII_PHYID2, &phyid2); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYID2\n"); + goto errout; + } + + nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr); + + if (phyid1 == priv->attr->msoui && + ((phyid2 & MII_PHYID2_OUI_MASK) >> MII_PHYID2_OUI_SHIFT) == + (uint16_t)priv->attr->lsoui) + { + nllvdbg(" Vendor Model Number: %04x\n", + (phyid2 & MII_PHYID2_MODEL_MASK) >> MII_PHYID2_MODEL_SHIFT); + nllvdbg(" Model Revision Number: %04x\n", + (phyid2 & MII_PHYID2_REV_MASK) >> MII_PHYID2_REV_SHIFT); + } + else + { + nlldbg("ERROR: PHY not recognized\n"); + } + + /* Setup control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr &= ~MII_MCR_ANENABLE; /* Remove autonegotiation enable */ + mcr &= ~(MII_MCR_LOOPBACK | MII_MCR_PDOWN); + mcr |= MII_MCR_ISOLATE; /* Electrically isolate PHY */ + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Set the Auto_negotiation Advertisement Register MII advertising for + * Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 + */ + + advertise = MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_8023; + + ret = sam_phywrite(priv, priv->phyaddr, MII_ADVERTISE, advertise); + if (ret < 0) + { + nlldbg("ERROR: Failed to write ANAR\n"); + goto errout; + } + + /* Read and modify control register */ + + ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MCR\n"); + goto errout; + } + + mcr |= (MII_MCR_SPEED100 | MII_MCR_ANENABLE | MII_MCR_FULLDPLX); + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + /* Restart Auto_negotiation */ + + mcr |= MII_MCR_ANRESTART; + mcr &= ~MII_MCR_ISOLATE; + + ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr); + if (ret < 0) + { + nlldbg("ERROR: Failed to write MCR\n"); + goto errout; + } + + nllvdbg(" MCR: %04x\n", mcr); + + /* Check AutoNegotiate complete */ + + timeout = 0; + for (; ; ) + { + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR\n"); + goto errout; + } + + /* Completed successfully? */ + + if ((msr & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. break out of the loop */ + + nllvdbg("AutoNegotiate complete\n"); + break; + } + + /* No.. check for a timeout */ + + if (++timeout >= PHY_RETRY_MAX) + { + nlldbg("ERROR: TimeOut\n"); + sam_phydump(priv); + ret = -ETIMEDOUT; + goto errout; + } + } + + /* Get the AutoNeg Link partner base page */ + + ret = sam_phyread(priv, priv->phyaddr, MII_LPA, &lpa); + if (ret < 0) + { + nlldbg("ERROR: Failed to read ANLPAR\n"); + goto errout; + } + + /* Setup the EMAC link speed */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if (((advertise & lpa) & MII_ADVERTISE_100BASETXFULL) != 0) + { + /* Set MII for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXFULL) != 0) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + else if (((advertise & lpa) & MII_ADVERTISE_100BASETXHALF) != 0) + { + /* Set MII for 100BaseTX and half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } +#if 0 + else if (((advertise & lpa) & MII_ADVERTISE_10BASETXHALF) != 0) + { + /* set MII for 10BaseT and half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Select RMII/MII */ + + ncr = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, + ncr & ~(EMAC_NCR_TXEN | EMAC_NCR_RXEN)); + + regval = sam_getreg(priv, SAM_EMAC_UR_OFFSET); + regval &= ~EMAC_UR_RMII; /* Assume RMII */ + + if (!priv->attr->rmii) + { + /* Not RMII, select MII */ + + regval |= EMAC_UR_RMII; + } + + sam_putreg(priv, SAM_EMAC_UR_OFFSET, regval); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, ncr); + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Function: sam_linkup + * + * Description: + * Check if the link is up + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * true: The link is up + * + ****************************************************************************/ + +static bool sam_linkup(struct sam_emac_s *priv) +{ + uint32_t regval; + uint16_t msr; + uint16_t physr; + bool linkup = false; + int ret; + + /* Enable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read MSR: %d\n", ret); + goto errout; + } + + if ((msr & MII_MSR_LINKSTATUS) == 0) + { + nlldbg("ERROR: MSR LinkStatus: %04x\n", msr); + goto errout; + } + + /* Re-configure Link speed */ + + ret = sam_phyread(priv, priv->phyaddr, priv->attr->physr, &physr); + if (ret < 0) + { + nlldbg("ERROR: Failed to read PHYSR: %d\n", ret); + goto errout; + } + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~(EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + + if ((msr & MII_MSR_100BASETXFULL) != 0 && sam_is100fdx(priv, physr)) + { + /* Set EMAC for 100BaseTX and Full Duplex */ + + regval |= (EMAC_NCFGR_SPD | EMAC_NCFGR_FD); + } + else if ((msr & MII_MSR_10BASETXFULL) != 0 && sam_is10fdx(priv, physr)) + { + /* Set MII for 10BaseT and Full Duplex */ + + regval |= EMAC_NCFGR_FD; + } + + else if ((msr & MII_MSR_100BASETXHALF) != 0 && sam_is100hdx(priv, physr)) + { + /* Set MII for 100BaseTX and Half Duplex */ + + regval |= EMAC_NCFGR_SPD; + } + +#if 0 + else if ((msr & MII_MSR_10BASETXHALF) != 0 && sam_is10hdx(priv, physr)) + { + /* Set MII for 10BaseT and Half Duplex */ + } +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Start the EMAC transfers */ + + nllvdbg("Link is up\n"); + linkup = true; + +errout: + /* Disable management port */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_MPE; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + return linkup; +} + +/**************************************************************************** + * Function: sam_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int sam_phyinit(struct sam_emac_s *priv) +{ + uint32_t regval; + uint32_t mck; + int ret; + + /* Configure PHY clocking */ + + regval = sam_getreg(priv, SAM_EMAC_NCFGR_OFFSET); + regval &= ~EMAC_NCFGR_CLK_MASK; + + mck = BOARD_MCK_FREQUENCY; + if (mck > (240*1000*1000)) + { + ndbg("ERROR: Cannot realize PHY clock\n"); + return -EINVAL; + } + else if (mck > (160*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV96; /* MCK divided by 64 (MCK up to 240 MHz) */ + } + else if (mck > (120*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */ + } + else if (mck > (80*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV48; /* MCK divided by 64 (MCK up to 120 MHz) */ + } + else if (mck > (40*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */ + } + else if (mck > (20*1000*1000)) + { + regval |= EMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */ + } + else + { + regval |= EMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */ + } + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + + /* Check the PHY Address */ + + priv->phyaddr = priv->attr->phyaddr; + ret = sam_phyfind(priv, &priv->phyaddr); + if (ret < 0) + { + nlldbg("ERROR: sam_phyfind failed: %d\n", ret); + return ret; + } + + if (priv->phyaddr != priv->attr->phyaddr) + { + sam_phyreset(priv); + } + + return OK; +} + +/**************************************************************************** + * Function: sam_ethgpioconfig + * + * Description: + * Configure PIOs for the EMAC0/1 RMII/MII interface. + * + * Signal Name Function MII RMII + * -------- --------------------------------- -------- ----------- + * TXCK Transmit Clock or Reference Clock TXCK REFCK + * TXEN Transmit Enable TXEN TXEN + * TX[3..0] Transmit Data TXD[3:0] TXD[1:0] + * TXER Transmit Coding Error TXER Not Used + * RXCK Receive Clock RXCK Not Used + * RXDV Receive Data Valid RXDV CRSDV + * RX[3..0] Receive Data RXD[3:0] RXD[1:0] + * RXER Receive Error RXER RXER + * CRS Carrier Sense and Data Valid CRS Not Used + * COL Collision Detect COL Not Used + * MDC Management Data Clock MDC MDC + * MDIO Management Data Input/Output MDIO MDIO + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void sam_ethgpioconfig(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMV7_EMAC0) + /* Configure EMAC0 PIO pins */ + + if (priv->attr->emac == EMAC0_INTF) + { + /* Configure PIO pins common to RMII and MII mode */ + + sam_configgpio(GPIO_EMAC0_TXCK); /* Transmit Clock (or Reference Clock) */ + sam_configgpio(GPIO_EMAC0_TXEN); /* Transmit Enable */ + sam_configgpio(GPIO_EMAC0_TX0); /* Transmit data TXD0 */ + sam_configgpio(GPIO_EMAC0_TX1); /* Transmit data TXD1 */ + sam_configgpio(GPIO_EMAC0_RXDV); /* Receive Data Valid */ + sam_configgpio(GPIO_EMAC0_RX0); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC0_RX1); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC0_RXER); /* Receive Error */ + sam_configgpio(GPIO_EMAC0_MDC); /* Management Data Clock */ + sam_configgpio(GPIO_EMAC0_MDIO); /* Management Data Input/Output */ + + /* Configure additional PIO pins to support EMAC in MII mode */ + + if (!priv->attr->rmii) + { + sam_configgpio(GPIO_EMAC0_TX2); /* Transmit data TXD2 */ + sam_configgpio(GPIO_EMAC0_TX3); /* Transmit data TXD3 */ + sam_configgpio(GPIO_EMAC0_TXER); /* Transmit Coding Error */ + sam_configgpio(GPIO_EMAC0_RXCK); /* Receive Clock */ + sam_configgpio(GPIO_EMAC0_RX2); /* Receive data RXD2 */ + sam_configgpio(GPIO_EMAC0_RX3); /* Receive data RXD3 */ + sam_configgpio(GPIO_EMAC0_CRS); /* Carrier Sense and Data Valid */ + sam_configgpio(GPIO_EMAC0_COL); /* Collision Detect */ + } + } + else +#endif + +#if defined(CONFIG_SAMV7_EMAC1) + /* Configure EMAC0 PIO pins */ + + if (priv->attr->emac == EMAC1_INTF) + { + /* Configure PIO pins common to RMII and MII mode */ + + sam_configgpio(GPIO_EMAC1_TXCK); /* Transmit Clock (or Reference Clock) */ + sam_configgpio(GPIO_EMAC1_TXEN); /* Transmit Enable */ + sam_configgpio(GPIO_EMAC1_TX0); /* Transmit data TXD0 */ + sam_configgpio(GPIO_EMAC1_TX1); /* Transmit data TXD1 */ + sam_configgpio(GPIO_EMAC1_RXDV); /* Receive Data Valid */ + sam_configgpio(GPIO_EMAC1_RX0); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC1_RX1); /* Receive data RXD0 */ + sam_configgpio(GPIO_EMAC1_RXER); /* Receive Error */ + sam_configgpio(GPIO_EMAC1_MDC); /* Management Data Clock */ + sam_configgpio(GPIO_EMAC1_MDIO); /* Management Data Input/Output */ + + /* Configure additional PIO pins to support EMAC in MII mode */ + + if (!priv->attr->rmii) + { + sam_configgpio(GPIO_EMAC1_TX2); /* Transmit data TXD2 */ + sam_configgpio(GPIO_EMAC1_TX3); /* Transmit data TXD3 */ + sam_configgpio(GPIO_EMAC1_TXER); /* Transmit Coding Error */ + sam_configgpio(GPIO_EMAC1_RXCK); /* Receive Clock */ + sam_configgpio(GPIO_EMAC1_RX2); /* Receive data RXD2 */ + sam_configgpio(GPIO_EMAC1_RX3); /* Receive data RXD3 */ + sam_configgpio(GPIO_EMAC1_CRS); /* Carrier Sense and Data Valid */ + sam_configgpio(GPIO_EMAC1_COL); /* Collision Detect */ + } + } + else +#endif + { + nvdbg("ERROR: emac=%d\n", priv->attr->emac); + } +} + +/**************************************************************************** + * Function: sam_txreset + * + * Description: + * Reset the transmit logic + * + * Parameters: + * priv - A reference to the private driver state structure + * qid - Identifies the queue to be reset + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_txreset(struct sam_emac_s *priv, int qid) +{ + struct emac_txdesc_s *txdesc; + struct sam_queue_s *xfrq; + uint8_t *txbuffer; + uintptr_t bufaddr; + uintptr_t regaddr; + uint32_t regval; + int ndx; + + /* Get some convenience pointers */ + + xfrq = &priv->xfrq[qid]; + txdesc = xfrq->txdesc; + txbuffer = xfrq->txbuffer; + + /* Disable TX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_TXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Configure the TX descriptors. */ + + xfrq->txhead = 0; + xfrq->txtail = 0; + + for (ndx = 0; ndx < xfrq->ntxbuffers; ndx++) + { + bufaddr = (uintptr_t)&txbuffer[ndx * xfrq->txbufsize]; + + /* Set the buffer address and mark the descriptor as in used by firmware */ + + txdesc[ndx].addr = bufaddr; + txdesc[ndx].status = EMACTXD_STA_USED; + } + + /* Mark the final descriptor in the list */ + + txdesc[xfrq->ntxbuffers - 1].status = + EMACTXD_STA_USED | EMACTXD_STA_WRAP; + + /* Flush the entire TX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + + xfrq->ntxbuffers * sizeof(struct emac_txdesc_s)); + + /* Set the Transmit Buffer Queue Pointer Register */ + + regaddr = qid ? SAM_EMAC_ISRPQ_TBQBAPQ_OFFSET(qid) : SAM_EMAC_TBQB_OFFSET; + sam_putreg(priv, regaddr, (uint32_t)txdesc); +} + +/**************************************************************************** + * Function: sam_rxreset + * + * Description: + * Reset the receive logic + * + * Parameters: + * priv - A reference to the private driver state structure + * qid - The transfer queue to be reset + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_rxreset(struct sam_emac_s *priv, int qid) +{ + struct emac_rxdesc_s *rxdesc; + struct sam_queue_s *xfrq; + uint8_t *rxbuffer; + uintptr_t bufaddr; + uintptr_t regaddr; + uint32_t regval; + int ndx; + + /* Get some convenience pointers */ + + xfrq = &priv->xfrq[qid]; + rxdesc = xfrq->rxdesc; + rxbuffer = xfrq->rxbuffer; + + /* Disable RX */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~EMAC_NCR_RXEN; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Configure the RX descriptors. */ + + xfrq->rxndx = 0; + for (ndx = 0; ndx < xfrq->nrxbuffers; ndx++) + { + bufaddr = (uintptr_t)&rxbuffer[ndx * xfrq->rxbufsize]; + DEBUGASSERT((bufaddr & ~EMACRXD_ADDR_MASK) == 0); + + /* Set the buffer address and remove EMACRXD_ADDR_OWNER and + * EMACRXD_ADDR_WRAP. + */ + + rxdesc[ndx].addr = bufaddr; + rxdesc[ndx].status = 0; + } + + /* Mark the final descriptor in the list */ + + rxdesc[xfrq->nrxbuffers - 1].addr |= EMACRXD_ADDR_WRAP; + + /* Flush the entire RX descriptor table to RAM */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + + xfrq->nrxbuffers * sizeof(struct emac_rxdesc_s)); + + /* Set the Receive Buffer Queue Pointer Register */ + + regaddr = qid ? SAM_EMAC_ISRPQ_RBQBAPQ_OFFSET(qid) : SAM_EMAC_RBQB_OFFSET; + sam_putreg(priv, regaddr, (uint32_t)rxdesc); +} + +/**************************************************************************** + * Function: sam_emac_enableclk + * + * Description: + * Enable clocking to the EMAC block + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_enableclk(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMV7_EMAC0) && defined(CONFIG_SAMV7_EMAC1) + /* Both EMAC blocks are selected, which are we enabling? */ + + if (priv->attr->emac == EMAC0_INTF) + { + sam_emac0_enableclk(); + } + else + { + sam_emac1_enableclk(); + } + +#elif defined(CONFIG_SAMV7_EMAC0) + /* Only EMAC0 is selected */ + + sam_emac0_enableclk(); + +#else + /* Only EMAC1 is selected */ + + sam_emac1_enableclk(); +#endif +} + +/**************************************************************************** + * Function: sam_emac_disableclk + * + * Description: + * Disable clocking to the EMAC block + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +#ifndef CONFIG_NETDEV_PHY_IOCTL +static void sam_emac_disableclk(struct sam_emac_s *priv) +{ +#if defined(CONFIG_SAMV7_EMAC0) && defined(CONFIG_SAMV7_EMAC1) + /* Both EMAC blocks are selected, which are we disabling? */ + + if (priv->attr->emac == EMAC0_INTF) + { + sam_emac0_disableclk(); + } + else + { + sam_emac1_disableclk(); + } + +#elif defined(CONFIG_SAMV7_EMAC0) + /* Only EMAC0 is selected */ + + sam_emac0_disableclk(); + +#else + /* Only EMAC1 is selected */ + + sam_emac1_disableclk(); +#endif +} +#endif + +/**************************************************************************** + * Function: sam_emac_reset + * + * Description: + * Reset the EMAC block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_emac_reset(struct sam_emac_s *priv) +{ +#ifdef CONFIG_NETDEV_PHY_IOCTL + uint32_t regval; + + /* We are supporting PHY IOCTLs, then do not reset the MAC. If we do, + * then we cannot communicate with the PHY. So, instead, just disable + * interrupts, cancel timers, and disable TX and RX. + */ + + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv, EMAC_QUEUE_0); + sam_rxreset(priv, EMAC_QUEUE_1); + sam_rxreset(priv, EMAC_QUEUE_2); + + sam_txreset(priv, EMAC_QUEUE_0); + sam_txreset(priv, EMAC_QUEUE_1); + sam_txreset(priv, EMAC_QUEUE_2); + + /* Disable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval &= ~(EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT); + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + +#else + /* Disable all EMAC interrupts */ + + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + + /* Reset RX and TX logic */ + + sam_rxreset(priv, EMAC_QUEUE_0); + sam_rxreset(priv, EMAC_QUEUE_1); + sam_rxreset(priv, EMAC_QUEUE_2); + + sam_txreset(priv, EMAC_QUEUE_0); + sam_txreset(priv, EMAC_QUEUE_1); + sam_txreset(priv, EMAC_QUEUE_2); + + /* Make sure that RX and TX are disabled; clear statistics registers */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT); + + /* Disable clocking to the EMAC peripheral */ + + sam_emac_disableclk(priv); + +#endif +} + +/**************************************************************************** + * Function: sam_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void sam_macaddress(struct sam_emac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address */ + + regval = (uint32_t)dev->d_mac.ether_addr_octet[0] | + (uint32_t)dev->d_mac.ether_addr_octet[1] << 8 | + (uint32_t)dev->d_mac.ether_addr_octet[2] << 16 | + (uint32_t)dev->d_mac.ether_addr_octet[3] << 24; + sam_putreg(priv, SAM_EMAC_SAB1_OFFSET, regval); + + regval = (uint32_t)dev->d_mac.ether_addr_octet[4] | + (uint32_t)dev->d_mac.ether_addr_octet[5] << 8; + sam_putreg(priv, SAM_EMAC_SAT1_OFFSET, regval); +} + +/**************************************************************************** + * Function: sam_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void sam_ipv6multicast(struct sam_emac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)sam_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)sam_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: sam_queue0_configure + * + * Description: + * Put transfer queue 0 in the operational state + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_queue0_configure(struct sam_emac_s *priv) +{ + uint32_t regval; + + /* Set up the DMA configuration register + * + * EMAC_DCFGR_FBLDO_INCR4 - Attempt to use INCR8 AHB bursts + * - No endian swap mode + * EMAC_DCFGR_RXBMS_FULL - 4 Kbytes Memory Size + * EMAC_DCFGR_TXPBMS - Full configured address space (4Kbytes) + * - No Checksum generation offload enable + * EMAC_DCFGR_DRBS - Set configured receive buffer size + * (units of 64 bytes) + */ + + regval = EMAC_DCFGR_FBLDO_INCR4 | EMAC_DCFGR_RXBMS_FULL | /* EMAC_DCFGR_TXPBMS | */ + EMAC_DCFGR_DRBS(priv->xfrq[0].rxbufsize >> 6); + sam_putreg(priv, SAM_EMAC_DCFGR_OFFSET, regval); + + /* Reset RX and TX */ + + sam_rxreset(priv, EMAC_QUEUE_0); + sam_txreset(priv, EMAC_QUEUE_0); + + /* Enable Rx and Tx, plus the statistics registers. */ + + regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); + regval |= EMAC_NCR_RXEN | EMAC_NCR_TXEN | EMAC_NCR_WESTAT; + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval); + + /* Setup the interrupts for TX events, RX events, and error events */ + + regval = EMAC_RX_INTS | EMAC_TX_INTS; + sam_putreg(priv, SAM_EMAC_IER_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Function: sam_queue_configure + * + * Description: + * Put transfer queue n, n=1..(EMAC_NQUEUES-1), in the operational state + * + * Parameters: + * priv - A reference to the private driver state structure + * qid - Identifies the transfer queue to be configured + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_queue_configure(struct sam_emac_s *priv, int qid) +{ + uint32_t regval; + + /* Set the receive buffer size */ + + regval = (uint32_t)priv->xfrq[qid].rxbufsize >> 6; + sam_putreg(priv, SAM_EMAC_ISRPQ_RBSRPQ_OFFSET(qid), regval); + + /* Reset RX and TX */ + + sam_rxreset(priv, qid); + sam_txreset(priv, qid); + + /* Setup interrupts for RX/TX completion events */ + + regval = EMAC_RX_INTS | EMAC_TX_INTS; + sam_putreg(priv, SAM_EMAC_ISRPQ_IERPQ_OFFSET(qid), regval); + return OK; +} + +/**************************************************************************** + * Function: sam_emac_configure + * + * Description: + * Configure the EMAC interface for normal operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int sam_emac_configure(struct sam_emac_s *priv) +{ + uint32_t regval; + + nllvdbg("Entry\n"); + + /* Enable clocking to the EMAC peripheral */ + + sam_emac_enableclk(priv); + + /* Disable TX, RX, clear statistics. Disable all interrupts. */ + + sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT); + sam_putreg(priv, SAM_EMAC_IDR_OFFSET, EMAC_INT_ALL); + sam_putreg(priv, SAM_EMAC_ISRPQ_IDRPQ_OFFSET(1), EMAC_INTPQ_ALL); + sam_putreg(priv, SAM_EMAC_ISRPQ_IDRPQ_OFFSET(2), EMAC_INTPQ_ALL); + + /* Clear all status bits in the receive status register. */ + + regval = (EMAC_RSR_RXOVR | EMAC_RSR_REC | EMAC_RSR_BNA | EMAC_RSR_HNO); + sam_putreg(priv, SAM_EMAC_RSR_OFFSET, regval); + + /* Clear all status bits in the transmit status register */ + + regval = (EMAC_TSR_UBR | EMAC_TSR_COL | EMAC_TSR_RLE | EMAC_TSR_TXGO | + EMAC_TSR_TFC | EMAC_TSR_TXCOMP | EMAC_TSR_HRESP); + sam_putreg(priv, SAM_EMAC_TSR_OFFSET, regval); + + /* Clear any pending interrupts */ + + (void)sam_getreg(priv, SAM_EMAC_ISR_OFFSET); + (void)sam_getreg(priv, SAM_EMAC_ISRPQ_ISRPQ_OFFSET(1)); + (void)sam_getreg(priv, SAM_EMAC_ISRPQ_ISRPQ_OFFSET(2)); + + /* Enable/disable the copy of data into the buffers, ignore broadcasts. + * Don't copy FCS. + */ + + regval = EMAC_NCFGR_FD | EMAC_NCFGR_DBW_ZERO | EMAC_NCFGR_CLK_DIV64 | + EMAC_NCFGR_MAXFS | EMAC_NCFGR_PEN | EMAC_NCFGR_RFCS; + +#ifdef CONFIG_NET_PROMISCUOUS + regval |= EMAC_NCFGR_CAF; +#endif + +#ifdef CONFIG_SAMV7_EMAC_NBC + regval |= EMAC_NCFGR_NBC; +#endif + + sam_putreg(priv, SAM_EMAC_NCFGR_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_emac_initialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * intf - If multiple EMAC peripherals are supported, this identifies the + * the EMAC peripheral being initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_emac_initialize(int intf) +{ + struct sam_emac_s *priv; + const struct sam_emacattr_s *attr; +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + uint8_t phytype; +#endif + int ret; + +#if defined(CONFIG_SAMV7_EMAC0) + if (intf == EMAC0_INTF) + { + priv = &g_emac0; + attr = &g_emac0_attr; + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + phytype = SAMV7_EMAC0_PHY_TYPE; +#endif + } + else +#endif +#if defined(CONFIG_SAMV7_EMAC1) + if (intf == EMAC1_INTF) + { + priv = &g_emac1; + attr = &g_emac1_attr; + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) + phytype = SAMV7_EMAC1_PHY_TYPE; +#endif + } + else +#endif + { + ndbg("ERROR: Interface %d not supported\n", intf); + return -EINVAL; + } + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct sam_emac_s)); + priv->attr = attr; /* Save the constant attributes */ + priv->dev.d_ifup = sam_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = sam_ifdown; /* I/F down callback */ + priv->dev.d_txavail = sam_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = sam_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = sam_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = sam_ioctl; /* Support PHY ioctl() calls */ +#ifdef CONFIG_ARCH_PHY_INTERRUPT + priv->phytype = phytype; /* Type of PHY on port */ +#endif +#endif + + priv->dev.d_private = priv; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); + if (!priv->txpoll) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout; + } + + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + if (!priv->txtimeout) + { + ndbg("ERROR: Failed to create periodic poll timer\n"); + ret = -EAGAIN; + goto errout_with_txpoll; + } + + /* Configure PIO pins to support EMAC */ + + sam_ethgpioconfig(priv); + + /* Allocate buffers */ + + ret = sam_buffer_allocate(priv); + if (ret < 0) + { + ndbg("ERROR: sam_buffer_allocate failed: %d\n", ret); + goto errout_with_txtimeout; + } + + /* Attach the IRQ to the driver. It will not be enabled at the AIC until + * the interface is in the 'up' state. + */ + + ret = irq_attach(priv->attr->irq, priv->attr->handler); + if (ret < 0) + { + ndbg("ERROR: Failed to attach the handler to the IRQ%d\n", priv->attr->irq); + goto errout_with_buffers; + } + + /* Enable clocking to the EMAC peripheral (just for sam_ifdown()) */ + + sam_emac_enableclk(priv); + + /* Put the interface in the down state (disabling clocking again). */ + + ret = sam_ifdown(&priv->dev); + if (ret < 0) + { + ndbg("ERROR: Failed to put the interface in the down state: %d\n", ret); + goto errout_with_buffers; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + ret = netdev_register(&priv->dev, NET_LL_ETHERNET); + if (ret >= 0) + { + return ret; + } + + ndbg("ERROR: netdev_register() failed: %d\n", ret); + +errout_with_buffers: + sam_buffer_free(priv); +errout_with_txtimeout: + wd_delete(priv->txtimeout); +errout_with_txpoll: + wd_delete(priv->txpoll); +errout: + return ret; +} + +/**************************************************************************** + * Function: sam_emac_setmacaddr + * + * Description: + * There are two ways that the Ethernet MAC address can be set: + * + * 1) Application level code can set the Ethernet MAC address using a + * netdev ioctl. The application level code have gotten the MAC + * address from some configuration parameter or by accessing some + * non-volatile storage containing the address. This is the + * "canonically correct" way to set the MAC address. + * 2) Alternatively, the board logic may support some other less obvious + * non-volatile storage and the board-level boot-up code may access + * this and use this interface to set the Ethernet MAC address more + * directly. This is mostly a kludge for the case where you just don't + * want to expose a application level storage interface. + * + * Input Parameters: + * intf - If multiple EMAC peripherals are supported, this identifies the + * the EMAC peripheral being initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +int sam_emac_setmacaddr(int intf, uint8_t mac[6]) +{ + struct sam_emac_s *priv; + struct net_driver_s *dev; + + /* Get the driver state structure */ + +#if defined(CONFIG_SAMV7_EMAC0) + if (intf == EMAC0_INTF) + { + priv = &g_emac0; + } + else +#endif +#if defined(CONFIG_SAMV7_EMAC1) + if (intf == EMAC1_INTF) + { + priv = &g_emac1; + } + else +#endif + { + ndbg("ERROR: Interface %d not supported\n", intf); + return -EINVAL; + } + + /* Copy the MAC address into the device structure */ + + dev = &priv->dev; + memcpy(dev->d_mac.ether_addr_octet, mac, 6); + + nvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + return OK; +} + +#endif /* CONFIG_NET && CONFIG_SAMV7_EMAC */ diff --git a/arch/arm/src/samv7/sam_ethernet.c b/arch/arm/src/samv7/sam_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..3e19d958738ce3d441328cd799771cf6636f34c1 --- /dev/null +++ b/arch/arm/src/samv7/sam_ethernet.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_ethernet.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "sam_ethernet.h" + +#ifdef CONFIG_NET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. This is just + * a shim to support the slightly different prototype of + * sam_emac_intiialize() and to provide support for future chips that + * may have multiple EMAC peripherals. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +void up_netinitialize(void) +{ +#ifdef CONFIG_SAMV7_EMAC0 + int ret; + +#ifdef CONFIG_SAMV7_EMAC0 + /* Initialize the EMAC0 driver */ + + ret = sam_emac_initialize(EMAC0_INTF); + if (ret < 0) + { + nlldbg("ERROR: up_emac_initialize(EMAC0) failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_SAMV7_EMAC1 + /* Initialize the EMAC1 driver */ + + ret = sam_emac_initialize(EMAC1_INTF); + if (ret < 0) + { + nlldbg("ERROR: up_emac_initialize(EMAC1) failed: %d\n", ret); + } +#endif +#endif +} + +#endif /* CONFIG_NET */ diff --git a/arch/arm/src/samv7/sam_ethernet.h b/arch/arm/src/samv7/sam_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..f2d45a4bdb7202c0cbe930f17d1a52123e57dda7 --- /dev/null +++ b/arch/arm/src/samv7/sam_ethernet.h @@ -0,0 +1,268 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_ethernet.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_ETHERNET_H +#define __ARCH_ARM_SRC_SAMV7_SAM_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/sam_emac.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Understood PHY types */ + +#define SAMV7_PHY_DM9161 0 +#define SAMV7_PHY_LAN8700 1 +#define SAMV7_PHY_KSZ8051 2 +#define SAMV7_PHY_KSZ8061 3 +#define SAMV7_PHY_KSZ8081 4 +#define SAMV7_PHY_KSZ90x1 5 + +/* Definitions for use with sam_phy_boardinitialize */ + +#define EMAC0_INTF 0 +#define EMAC1_INTF 1 + +/* Which is ETH0 and which is ETH1? */ + +#ifndef CONFIG_SAMV7_EMAC +# undef CONFIG_SAMV7_EMAC0_ISETH0 +# undef CONFIG_SAMV7_EMAC1_ISETH0 +#endif + +#if defined(CONFIG_SAMV7_EMAC0_ISETH0) && defined(CONFIG_SAMV7_EMAC1_ISETH0) +# error EMAC0 and EMAC2 cannot both be ETH0 +#endif + +#if defined(CONFIG_SAMV7_EMAC0_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMV7_EMAC0_PHY_DM9161 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMV7_EMAC0_PHY_LAN8700 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMV7_EMAC0_PHY_KSZ8051 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8061) +# define SAMV7_EMAC0_PHY_KSZ8061 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8061 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMV7_EMAC0_PHY_KSZ8081 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMV7_EMAC0_PHY_KSZ90x1 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMV7_EMAC0) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMV7_EMAC0_PHY_DM9161 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMV7_EMAC0_PHY_LAN8700 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMV7_EMAC0_PHY_KSZ8051 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8051 +# elif defined(CONFIG_ETH1_PHY_KSZ8061) +# define SAMV7_EMAC0_PHY_KSZ8061 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8061 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMV7_EMAC0_PHY_KSZ8081 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMV7_EMAC0_PHY_KSZ90x1 1 +# define SAMV7_EMAC0_PHY_TYPE SAMV7_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +#if defined(CONFIG_SAMV7_EMAC1_ISETH0) +# if defined(CONFIG_ETH0_PHY_DM9161) +# define SAMV7_EMAC1_PHY_DM9161 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_DM9161 +# elif defined(CONFIG_ETH0_PHY_LAN8700) +# define SAMV7_EMAC1_PHY_LAN8700 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_LAN8700 +# elif defined(CONFIG_ETH0_PHY_KSZ8051) +# define SAMV7_EMAC1_PHY_KSZ8051 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8051 +# elif defined(CONFIG_ETH0_PHY_KSZ8061) +# define SAMV7_EMAC1_PHY_KSZ8061 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8061 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMV7_EMAC1_PHY_KSZ8081 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8081 +# elif defined(CONFIG_ETH0_PHY_KSZ90x1) +# define SAMV7_EMAC1_PHY_KSZ90x1 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ90x1 +# else +# error ETH0 PHY unrecognized +# endif +#elif defined(CONFIG_SAMV7_EMAC1) +# if defined(CONFIG_ETH1_PHY_DM9161) +# define SAMV7_EMAC1_PHY_DM9161 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_DM9161 +# elif defined(CONFIG_ETH1_PHY_LAN8700) +# define SAMV7_EMAC1_PHY_LAN8700 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_LAN8700 +# elif defined(CONFIG_ETH1_PHY_KSZ8051) +# define SAMV7_EMAC1_PHY_KSZ8051 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8051 +# elif defined(CONFIG_ETH1_PHY_KSZ8061) +# define SAMV7_EMAC1_PHY_KSZ8061 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8061 +# elif defined(CONFIG_ETH0_PHY_KSZ8081) +# define SAMV7_EMAC1_PHY_KSZ8081 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ8081 +# elif defined(CONFIG_ETH1_PHY_KSZ90x1) +# define SAMV7_EMAC1_PHY_KSZ90x1 1 +# define SAMV7_EMAC1_PHY_TYPE SAMV7_PHY_KSZ90x1 +# else +# error ETH1 PHY unrecognized +# endif +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: sam_emac_initialize + * + * Description: + * Initialize the EMAC driver. + * + * Input Parameters: + * intf - If multiple EMAC peripherals are supported, this identifies the + * the EMAC peripheral being initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_EMAC +int sam_emac_initialize(int intf); +#endif + +/**************************************************************************** + * Function: sam_emac_setmacaddr + * + * Description: + * There are two ways that the Ethernet MAC address can be set: + * + * 1) Application level code can set the Ethernet MAC address using a + * netdev ioctl. The application level code have gotten the MAC + * address from some configuration parameter or by accessing some + * non-volatile storage containing the address. This is the + * "cannonically correct" way to set the MAC address. + * 2) Alterntively, the board logic may support some other less obvious + * non-volatile storage and the board-level boot-up code may access + * this and use this interface to set the Ethernet MAC address more + * directly. This is mostly a kludge for the case where you just don't + * want to expose a application level storage interface. + * + * Input Parameters: + * intf - If multiple EMAC peripherals are supported, this identifies the + * the EMAC peripheral being initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * Called very early in the initialization sequence. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_EMAC +int sam_emac_setmacaddr(int intf, uint8_t mac[6]); +#endif + +/************************************************************************************ + * Function: sam_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_SAMV7_PHYINIT is defined in the configuration then the board specific + * logic must provide sam_phyinitialize(); The SAMV7 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_PHYINIT +int sam_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_ETHERNET_H */ diff --git a/arch/arm/src/samv7/sam_freerun.c b/arch/arm/src/samv7/sam_freerun.c new file mode 100644 index 0000000000000000000000000000000000000000..c5eec516ddf7be1a4ede26d1a053f900258dc95b --- /dev/null +++ b/arch/arm/src/samv7/sam_freerun.c @@ -0,0 +1,322 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_freerun.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMV71 Series Data Sheet + * NuttX SAMA5 free-running timer driver + * Atmel NoOS sample code for the SAMA5D3. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam_freerun.h" + +#ifdef CONFIG_SAMV7_ONESHOT + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + /**************************************************************************** + * Name: sam_freerun_handler + * + * Description: + * Timer interrupt callback. When the freerun timer counter overflows, + * this interrupt will occur. We will just increment an overflow count. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_freerun_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_freerun_s *freerun = (struct sam_freerun_s *)arg; + DEBUGASSERT(freerun && freerun->overflow < UINT32_MAX); + freerun->overflow++; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/samv7/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t actual; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(freerun && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_clockselect(frequency, &cmr, &actual); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_clockselect failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, actual=%lu, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)actual, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * TC_CMR_TCCLKS - Returned by sam_tc_clockselect + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=0 - Don't stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UP - TC_CV is incremented from 0 to 0xffffffff + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NONE | TC_CMR_EEVTEDG_NONE | TC_CMR_EEVT_TIOB | + TC_CMR_WAVSEL_UP | TC_CMR_WAVE | TC_CMR_ACPA_NONE | + TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | TC_CMR_ASWTRG_NONE | + TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | TC_CMR_BEEVT_NONE | + TC_CMR_BSWTRG_NONE); + + freerun->tch = sam_tc_allocate(chan, cmr); + if (!freerun->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + freerun->chan = chan; + freerun->running = false; + freerun->overflow = 0; + + /* Set up to receive the callback when the counter overflow occurs */ + + (void)sam_tc_attach(freerun->tch, sam_freerun_handler, freerun, + TC_INT_COVFS); + + /* Start the counter */ + + sam_tc_start(freerun->tch); + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time from the free-running + * timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts) +{ + uint64_t usec; + uint32_t counter; + uint32_t verify; + uint32_t sr; + uint32_t overflow; + uint32_t sec; + irqstate_t flags; + + DEBUGASSERT(freerun && freerun->tch && ts); + + /* Temporarily disable the overflow counter. NOTE that we have to be careful + * here because sam_tc_getpending() will reset the pending interrupt status. + * If we do not handle the overflow here then, it will be lost. + */ + + flags = enter_critical_section(); + overflow = freerun->overflow; + counter = sam_tc_getcounter(freerun->tch); + sr = sam_tc_getpending(freerun->tch); + verify = sam_tc_getcounter(freerun->tch); + + /* If an interrupt was pending before we re-enabled interrupts, + * then the overflow needs to be incremented. + */ + + if ((sr & TC_INT_COVFS) != 0) + { + /* Increment the overflow count and use the value of the + * guaranteed to be AFTER the overflow occurred. + */ + + overflow++; + counter = verify; + + /* Update freerun overflow counter. */ + + freerun->overflow = overflow; + } + + leave_critical_section(flags); + + tcvdbg("counter=%lu (%lu) overflow=%lu, sr=%08lx\n", + (unsigned long)counter, (unsigned long)verify, + (unsigned long)overflow, (unsigned long)sr); + + /* Convert the whole thing to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = ((((uint64_t)overflow << 16) + (uint64_t)counter) * USEC_PER_SEC) / + sam_tc_divfreq(freerun->tch); + + /* And return the value of the timer */ + + sec = (uint32_t)(usec / USEC_PER_SEC); + ts->tv_sec = sec; + ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + tcvdbg("usec=%llu ts=(%lu, %lu)\n", + usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + + return OK; +} + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun) +{ + DEBUGASSERT(freerun && freerun->tch); + + /* Now we can disable the timer interrupt and disable the timer. */ + + sam_tc_attach(freerun->tch, NULL, NULL, 0); + sam_tc_stop(freerun->tch); + + /* Free the timer */ + + sam_tc_free(freerun->tch); + freerun->tch = NULL; + return OK; +} + +#endif /* CONFIG_SAMV7_ONESHOT */ diff --git a/arch/arm/src/samv7/sam_freerun.h b/arch/arm/src/samv7/sam_freerun.h new file mode 100644 index 0000000000000000000000000000000000000000..27ae59e633a04e7d121643207c08119b7b3cf859 --- /dev/null +++ b/arch/arm/src/samv7/sam_freerun.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_freerun.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_FREERUN_H +#define __ARCH_ARM_SRC_SAMV7_SAM_FREERUN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_tc.h" + +#ifdef CONFIG_SAMV7_FREERUN + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FREERUN_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The freerun client must allocate an instance of this structure and called + * sam_freerun_initialize() before using the freerun facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_freerun_s +{ + uint8_t chan; /* The timer/counter in use */ + bool running; /* True: the timer is running */ + uint32_t overflow; /* Timer counter overflow */ + TC_HANDLE tch; /* Handle returned by sam_tc_initialize() */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_freerun_initialize + * + * Description: + * Initialize the freerun timer wrapper + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/samv7/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan, + uint16_t resolution); + +/**************************************************************************** + * Name: sam_freerun_counter + * + * Description: + * Read the counter register of the free-running timer. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_counter(struct sam_freerun_s *freerun, struct timespec *ts); + +/**************************************************************************** + * Name: sam_freerun_uninitialize + * + * Description: + * Stop the free-running timer and release all resources that it uses. + * + * Input Parameters: + * freerun Caller allocated instance of the freerun state structure. This + * structure must have been previously initialized via a call to + * sam_freerun_initialize(); + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_freerun_uninitialize(struct sam_freerun_s *freerun); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMV7_FREERUN */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_FREERUN_H */ diff --git a/arch/arm/src/samv7/sam_gpio.c b/arch/arm/src/samv7/sam_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..628c1979f86edb230fcdc4a61284adc4df408004 --- /dev/null +++ b/arch/arm/src/samv7/sam_gpio.c @@ -0,0 +1,572 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_gpio.c + * General Purpose Input/Output (GPIO) logic for the SAMV71 + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_gpio.h" +#include "chip/sam_pio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +static const char g_portchar[SAMV7_NPIO] = +{ + 'A' +#if SAMV7_NPIO > 1 + , 'B' +#endif +#if SAMV7_NPIO > 2 + , 'C' +#endif +#if SAMV7_NPIO > 3 + , 'D' +#endif +#if SAMV7_NPIO > 4 + , 'E' +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const uintptr_t g_portbase[SAMV7_NPIO] = +{ + SAM_PIOA_BASE +#if SAMV7_NPIO > 1 + , SAM_PIOB_BASE +#endif +#if SAMV7_NPIO > 2 + , SAM_PIOC_BASE +#endif +#if SAMV7_NPIO > 3 + , SAM_PIOD_BASE +#endif +#if SAMV7_NPIO > 4 + , SAM_PIOE_BASE +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sam_configinput + * + * Description: + * Configure a GPIO input pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configinput(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ +#ifdef GPIO_HAVE_SCHMITT + uint32_t regval; +#endif + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Check if filtering should be enabled */ + + if ((cfgset & GPIO_CFG_DEGLITCH) != 0) + { + putreg32(pin, base + SAM_PIO_IFER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_IFDR_OFFSET); + } + +#ifdef GPIO_HAVE_SCHMITT + /* Enable/disable the Schmitt trigger */ + + regval = getreg32(base + SAM_PIO_SCHMITT_OFFSET); + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + regval |= pin; + } + else + { + regval &= ~pin; + } + + putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET); +#endif + +#ifdef GPIO_HAVE_DRIVER + /* Reset output drive strength (PIO outputs only) */ + + regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); + regval &= ~pin; + putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); +#endif + + /* Configure the pin as an input and enable the GPIO function */ + + putreg32(pin, base + SAM_PIO_ODR_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + + /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and + * IFDGSR registers. This would probably best be done with + * another, new API... perhaps sam_configfilter() + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_configoutput + * + * Description: + * Configure a GPIO output pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configoutput(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ +#ifdef GPIO_HAVE_DRIVER + uint32_t regval; +#endif + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + + /* Enable the open drain driver if requrested */ + + if ((cfgset & GPIO_CFG_OPENDRAIN) != 0) + { + putreg32(pin, base + SAM_PIO_MDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_MDDR_OFFSET); + } + + /* Set default value */ + + if ((cfgset & GPIO_OUTPUT_SET) != 0) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } + +#ifdef GPIO_HAVE_DRIVER + /* Select the pin output drive strength */ + + regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); + if ((cfgset & GPIO_OUTPUT_DRIVE) != GPIO_OUTPUT_LOW_DRIVE) + { + regval |= pin; + } + else + { + regval &= ~pin; + } + + putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); +#endif + + /* Configure the pin as an output and enable the GPIO function */ + + putreg32(pin, base + SAM_PIO_OER_OFFSET); + putreg32(pin, base + SAM_PIO_PER_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: sam_configperiph + * + * Description: + * Configure a GPIO pin driven by a peripheral A or B signal based on + * bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline int sam_configperiph(uintptr_t base, uint32_t pin, + gpio_pinset_t cfgset) +{ + uint32_t regval; + + /* Disable interrupts on the pin */ + + putreg32(pin, base + SAM_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base + SAM_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PUDR_OFFSET); + } + +#ifdef GPIO_HAVE_PULLDOWN + /* Enable/disable the pull-down as requested */ + + if ((cfgset & GPIO_CFG_PULLDOWN) != 0) + { + putreg32(pin, base + SAM_PIO_PPDER_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); + } +#endif + +#ifdef GPIO_HAVE_DRIVER + /* Reset output drive strength (PIO outputs only) */ + + regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); + regval &= ~pin; + putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); +#endif + +#ifdef GPIO_HAVE_PERIPHCD + /* Configure pin, depending upon the peripheral A, B, C or D + * + * PERIPHA: ABCDSR1[n] = 0 ABCDSR2[n] = 0 + * PERIPHB: ABCDSR1[n] = 1 ABCDSR2[n] = 0 + * PERIPHC: ABCDSR1[n] = 0 ABCDSR2[n] = 1 + * PERIPHD: ABCDSR1[n] = 1 ABCDSR2[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABCDSR1_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || + (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHC) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(regval, base + SAM_PIO_ABCDSR1_OFFSET); + + regval = getreg32(base + SAM_PIO_ABCDSR2_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || + (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHB) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(regval, base + SAM_PIO_ABCDSR2_OFFSET); + +#else + /* Configure pin, depending upon the peripheral A or B: + * + * PERIPHA: ABSR[n] = 0 + * PERIPHB: ABSR[n] = 1 + */ + + regval = getreg32(base + SAM_PIO_ABSR_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + + putreg32(regval, base + SAM_PIO_ABSR_OFFSET); +#endif + + /* Disable PIO functionality */ + + putreg32(pin, base + SAM_PIO_PDR_OFFSET); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int sam_configgpio(gpio_pinset_t cfgset) +{ + uintptr_t base = sam_gpio_base(cfgset); + uint32_t pin = sam_gpio_pinmask(cfgset); + irqstate_t flags; + int ret; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Enable writing to GPIO registers */ + + putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + + /* Handle the pin configuration according to pin type */ + + switch (cfgset & GPIO_MODE_MASK) + { + case GPIO_ALTERNATE: + case GPIO_INPUT: + ret = sam_configinput(base, pin, cfgset); + break; + + case GPIO_OUTPUT: + ret = sam_configoutput(base, pin, cfgset); + break; + + case GPIO_PERIPHA: + case GPIO_PERIPHB: +#ifdef GPIO_HAVE_PERIPHCD + case GPIO_PERIPHC: + case GPIO_PERIPHD: +#endif + ret = sam_configperiph(base, pin, cfgset); + break; + + default: + ret = -EINVAL; + break; + } + + /* Disable writing to GPIO registers */ + + putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: sam_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void sam_gpiowrite(gpio_pinset_t pinset, bool value) +{ + uintptr_t base = sam_gpio_base(pinset); + uint32_t pin = sam_gpio_pinmask(pinset); + + if (value) + { + putreg32(pin, base + SAM_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base + SAM_PIO_CODR_OFFSET); + } +} + +/**************************************************************************** + * Name: sam_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool sam_gpioread(gpio_pinset_t pinset) +{ + uintptr_t base = sam_gpio_base(pinset); + uint32_t pin = sam_gpio_pinmask(pinset); + uint32_t regval; + + if ((pinset & GPIO_MODE_MASK) == GPIO_OUTPUT) + { + regval = getreg32(base + SAM_PIO_ODSR_OFFSET); + } + else + { + regval = getreg32(base + SAM_PIO_PDSR_OFFSET); + } + + return (regval & pin) != 0; +} + +/************************************************************************************ + * Function: sam_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int port; + + /* Get the base address associated with the PIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = SAM_PION_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + lldbg("PIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" PSR: %08x OSR: %08x IFSR: %08x ODSR: %08x\n", + getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_OSR_OFFSET), + getreg32(base + SAM_PIO_IFSR_OFFSET), getreg32(base + SAM_PIO_ODSR_OFFSET)); + lldbg(" PDSR: %08x IMR: %08x ISR: %08x MDSR: %08x\n", + getreg32(base + SAM_PIO_PDSR_OFFSET), getreg32(base + SAM_PIO_IMR_OFFSET), + getreg32(base + SAM_PIO_ISR_OFFSET), getreg32(base + SAM_PIO_MDSR_OFFSET)); + lldbg(" ABCDSR: %08x %08x IFSCSR: %08x PPDSR: %08x\n", + getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET), + getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIO_PPDSR_OFFSET)); + lldbg(" PUSR: %08x SCDR: %08x OWSR: %08x AIMMR: %08x\n", + getreg32(base + SAM_PIO_PUSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET), + getreg32(base + SAM_PIO_OWSR_OFFSET), getreg32(base + SAM_PIO_AIMMR_OFFSET)); + lldbg(" ESR: %08x LSR: %08x ELSR: %08x FELLSR: %08x\n", + getreg32(base + SAM_PIO_ESR_OFFSET), getreg32(base + SAM_PIO_LSR_OFFSET), + getreg32(base + SAM_PIO_ELSR_OFFSET), getreg32(base + SAM_PIO_FELLSR_OFFSET)); + lldbg(" FRLHSR: %08x LOCKSR: %08x WPMR: %08x WPSR: %08x\n", + getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET), + getreg32(base + SAM_PIO_WPMR_OFFSET), getreg32(base + SAM_PIO_WPSR_OFFSET)); + lldbg(" PCMR: %08x PCIMR: %08x PCISR: %08x PCRHR: %08x\n", + getreg32(base + SAM_PIO_PCMR_OFFSET), getreg32(base + SAM_PIO_PCIMR_OFFSET), + getreg32(base + SAM_PIO_PCISR_OFFSET), getreg32(base + SAM_PIO_PCRHR_OFFSET)); + lldbg("SCHMITT: %08x DRIVER:%08x\n", + getreg32(base + SAM_PIO_SCHMITT_OFFSET), getreg32(base + SAM_PIO_DRIVER_OFFSET)); + lldbg(" KER: %08x KRCR: %08x KDR: %08x KIMR: %08x\n", + getreg32(base + SAM_PIO_KER_OFFSET), getreg32(base + SAM_PIO_KRCR_OFFSET), + getreg32(base + SAM_PIO_KDR_OFFSET), getreg32(base + SAM_PIO_KIMR_OFFSET)); + lldbg(" KSR: %08x KKPR: %08x KKRR: %08x\n", + getreg32(base + SAM_PIO_KSR_OFFSET), getreg32(base + SAM_PIO_KKPR_OFFSET), + getreg32(base + SAM_PIO_KKRR_OFFSET)); + lldbg(" PCMR: %08x PCIMR: %08x PCISR: %08x PCRHR: %08x\n", + getreg32(base + SAM_PIO_PCMR_OFFSET), getreg32(base + SAM_PIO_PCIMR_OFFSET), + getreg32(base + SAM_PIO_PCISR_OFFSET), getreg32(base + SAM_PIO_PCRHR_OFFSET)); + leave_critical_section(flags); + return OK; +} +#endif diff --git a/arch/arm/src/samv7/sam_gpio.h b/arch/arm/src/samv7/sam_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..4b5b6f5208b64a3b462dec6594d194ed06526c49 --- /dev/null +++ b/arch/arm/src/samv7/sam_gpio.h @@ -0,0 +1,374 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_GPIO_H +#define __ARCH_ARM_SRC_SAMV7_SAM_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bit-encoded input to sam_configgpio() ********************************************/ + +/* 32-bit Encoding: + * + * .... .... MMMC CCCC IIIV D... PPPB BBBB + */ + +/* Input/Output mode: + * + * .... .... MMM. .... .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (21) /* Bits 21-23: GPIO mode */ +#define GPIO_MODE_MASK (7 << GPIO_MODE_SHIFT) +# define GPIO_ALTERNATE (0 << GPIO_MODE_SHIFT) /* PIO alternate function */ +# define GPIO_INPUT (1 << GPIO_MODE_SHIFT) /* PIO Input */ +# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* PIO Output */ +# define GPIO_PERIPHA (3 << GPIO_MODE_SHIFT) /* Controlled by periph A signal */ +# define GPIO_PERIPHB (4 << GPIO_MODE_SHIFT) /* Controlled by periph B signal */ +# define GPIO_PERIPHC (5 << GPIO_MODE_SHIFT) /* Controlled by periph C signal */ +# define GPIO_PERIPHD (6 << GPIO_MODE_SHIFT) /* Controlled by periph D signal */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * .... .... ...C CCCC .... .... .... .... + */ + +#define GPIO_CFG_SHIFT (16) /* Bits 16-20: GPIO configuration bits */ +#define GPIO_CFG_MASK (31 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 16: Internal pull-up */ +# define GPIO_CFG_PULLDOWN (2 << GPIO_CFG_SHIFT) /* Bit 17: Internal pull-down */ +# define GPIO_CFG_DEGLITCH (4 << GPIO_CFG_SHIFT) /* Bit 18: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (8 << GPIO_CFG_SHIFT) /* Bit 19: Open drain */ +# define GPIO_CFG_SCHMITT (16 << GPIO_CFG_SHIFT) /* Bit 20: Schmitt trigger */ + +/* Additional interrupt modes: + * + * .... .... .... .... III. .... .... .... + */ + +#define GPIO_INT_SHIFT (13) /* Bits 13-15: GPIO interrupt bits */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define _GIO_INT_AIM (1 << 15) /* Bit 15: Additional Interrupt modes */ +# define _GPIO_INT_LEVEL (1 << 14) /* Bit 14: Level detection interrupt */ +# define _GPIO_INT_EDGE (0) /* (vs. Edge detection interrupt) */ +# define _GPIO_INT_RH (1 << 13) /* Bit 13: Rising edge/High level detection interrupt */ +# define _GPIO_INT_FL (0) /* (vs. Falling edge/Low level detection interrupt) */ + +# define GPIO_INT_HIGHLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_RH) +# define GPIO_INT_LOWLEVEL (_GIO_INT_AIM | _GPIO_INT_LEVEL | _GPIO_INT_FL) +# define GPIO_INT_RISING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_RH) +# define GPIO_INT_FALLING (_GIO_INT_AIM | _GPIO_INT_EDGE | _GPIO_INT_FL) +# define GPIO_INT_BOTHEDGES (0) + +/* If the pin is an GPIO output, then this identifies the initial output value: + * + * .... .... .... .... ...V .... .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 12) /* Bit 12: Initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* If the pin is an GPIO output, then this identifies the output drive strength: + * + * .... .... .... .... .... D... .... .... + */ + +#define GPIO_OUTPUT_DRIVE (1 << 11) /* Bit 11: Initial value of output */ +# define GPIO_OUTPUT_HIGH_DRIVE (1 << 11) + #define GPIO_OUTPUT_LOW_DRIVE (0) + +/* This identifies the GPIO port: + * + * .... .... .... .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOE (4 << GPIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * ..... .... ... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +#define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +#define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +#define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +#define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +#define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +#define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +#define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +#define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +#define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +#define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +#define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +#define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +#define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +#define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +#define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t gpio_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN const uintptr_t g_portbase[SAMV7_NPIO]; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_gpio_base + * + * Description: + * Return the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uintptr_t sam_gpio_base(gpio_pinset_t cfgset) +{ + int port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + DEBUGASSERT(port > GPIO_PORT_SHIFT; +} + +/**************************************************************************** + * Name: sam_gpio_pin + * + * Description: + * Return the PIO pin number + * + ****************************************************************************/ + +static inline int sam_gpio_pin(gpio_pinset_t cfgset) +{ + return (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; +} + +/**************************************************************************** + * Name: sam_gpio_pinmask + * + * Description: + * Return the PIO pin bit maskt + * + ****************************************************************************/ + +static inline int sam_gpio_pinmask(gpio_pinset_t cfgset) +{ + return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_GPIO_IRQ +void sam_gpioirqinitialize(void); +#else +# define sam_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: sam_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int sam_configgpio(gpio_pinset_t cfgset); + +/************************************************************************************ + * Name: sam_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void sam_gpiowrite(gpio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: sam_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool sam_gpioread(gpio_pinset_t pinset); + +/************************************************************************************ + * Name: sam_gpioirq + * + * Description: + * Configure an interrupt for the specified GPIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_GPIO_IRQ +void sam_gpioirq(gpio_pinset_t pinset); +#else +# define sam_gpioirq(pinset) +#endif + +/************************************************************************************ + * Name: sam_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_GPIO_IRQ +void sam_gpioirqenable(int irq); +#else +# define sam_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: sam_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_GPIO_IRQ +void sam_gpioirqdisable(int irq); +#else +# define sam_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: sam_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int sam_dumpgpio(uint32_t pinset, const char *msg); +#else +# define sam_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_GPIO_H */ diff --git a/arch/arm/src/samv7/sam_gpioirq.c b/arch/arm/src/samv7/sam_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..8929d1757799f24144465196ea8f8da13aae128a --- /dev/null +++ b/arch/arm/src/samv7/sam_gpioirq.c @@ -0,0 +1,429 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_gpioirq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "chip/sam_pmc.h" +#include "chip/sam_pio.h" + +#ifdef CONFIG_SAMV7_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpiobase + * + * Description: + * Return the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uint32_t sam_gpiobase(gpio_pinset_t pinset) +{ + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + return SAM_PION_BASE(port >> GPIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: sam_gpiopin + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline int sam_gpiopin(gpio_pinset_t pinset) +{ + return 1 << ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: sam_irqbase + * + * Description: + * Return gpio information associated with this IRQ + * + ****************************************************************************/ + +static int sam_irqbase(int irq, uint32_t *base, int *pin) +{ + if (irq >= SAM_IRQ_NIRQS) + { +#ifdef CONFIG_SAMV7_GPIOA_IRQ + if (irq <= SAM_IRQ_PA31) + { + *base = SAM_PIOA_BASE; + *pin = irq - SAM_IRQ_PA0; + return OK; + } +#endif +#ifdef CONFIG_SAMV7_GPIOB_IRQ + if (irq <= SAM_IRQ_PB31) + { + *base = SAM_PIOB_BASE; + *pin = irq - SAM_IRQ_PB0; + return OK; + } +#endif +#ifdef CONFIG_SAMV7_GPIOC_IRQ + if (irq <= SAM_IRQ_PC31) + { + *base = SAM_PIOC_BASE; + *pin = irq - SAM_IRQ_PC0; + return OK; + } +#endif +#ifdef CONFIG_SAMV7_GPIOD_IRQ + if (irq <= SAM_IRQ_PD31) + { + *base = SAM_PIOD_BASE; + *pin = irq - SAM_IRQ_PD0; + return OK; + } +#endif +#ifdef CONFIG_SAMV7_GPIOE_IRQ + if (irq <= SAM_IRQ_PE31) + { + *base = SAM_PIOE_BASE; + *pin = irq - SAM_IRQ_PE0; + return OK; + } +#endif + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: sam_gpioa/b/cinterrupt + * + * Description: + * Receive GPIOA/B/C interrupts + * + ****************************************************************************/ + +static int sam_gpiointerrupt(uint32_t base, int irq0, void *context) +{ + uint32_t pending; + uint32_t bit; + int irq; + + pending = getreg32(base + SAM_PIO_ISR_OFFSET) & getreg32(base + SAM_PIO_IMR_OFFSET); + for (bit = 1, irq = irq0; pending != 0; bit <<= 1, irq++) + { + if ((pending & bit) != 0) + { + /* Re-deliver the IRQ (recurses! We got here from irq_dispatch!) */ + + irq_dispatch(irq, context); + + /* Remove this from the set of pending interrupts */ + + pending &= ~bit; + } + } + return OK; +} + +#ifdef CONFIG_SAMV7_GPIOA_IRQ +static int sam_gpioainterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOA_BASE, SAM_IRQ_PA0, context); +} +#endif + +#ifdef CONFIG_SAMV7_GPIOB_IRQ +static int sam_gpiobinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOB_BASE, SAM_IRQ_PB0, context); +} +#endif + +#ifdef CONFIG_SAMV7_GPIOC_IRQ +static int sam_gpiocinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOC_BASE, SAM_IRQ_PC0, context); +} +#endif + +#ifdef CONFIG_SAMV7_GPIOD_IRQ +static int sam_gpiodinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOD_BASE, SAM_IRQ_PD0, context); +} +#endif + +#ifdef CONFIG_SAMV7_GPIOE_IRQ +static int sam_gpioeinterrupt(int irq, void *context) +{ + return sam_gpiointerrupt(SAM_PIOE_BASE, SAM_IRQ_PE0, context); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void sam_gpioirqinitialize(void) +{ + /* Configure GPIOA interrupts */ + +#ifdef CONFIG_SAMV7_GPIOA_IRQ + /* Enable GPIOA clocking */ + + sam_pioa_enableclk(); + + /* Clear and disable all GPIOA interrupts */ + + (void)getreg32(SAM_PIOA_ISR); + putreg32(0xffffffff, SAM_PIOA_IDR); + + /* Attach and enable the GPIOA IRQ */ + + (void)irq_attach(SAM_IRQ_PIOA, sam_gpioainterrupt); + up_enable_irq(SAM_IRQ_PIOA); +#endif + + /* Configure GPIOB interrupts */ + +#ifdef CONFIG_SAMV7_GPIOB_IRQ + /* Enable GPIOB clocking */ + + sam_piob_enableclk(); + + /* Clear and disable all GPIOB interrupts */ + + (void)getreg32(SAM_PIOB_ISR); + putreg32(0xffffffff, SAM_PIOB_IDR); + + /* Attach and enable the GPIOB IRQ */ + + (void)irq_attach(SAM_IRQ_PIOB, sam_gpiobinterrupt); + up_enable_irq(SAM_IRQ_PIOB); +#endif + + /* Configure GPIOC interrupts */ + +#ifdef CONFIG_SAMV7_GPIOC_IRQ + /* Enable GPIOC clocking */ + + sam_pioc_enableclk(); + + /* Clear and disable all GPIOC interrupts */ + + (void)getreg32(SAM_PIOC_ISR); + putreg32(0xffffffff, SAM_PIOC_IDR); + + /* Attach and enable the GPIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOC, sam_gpiocinterrupt); + up_enable_irq(SAM_IRQ_PIOC); +#endif + + /* Configure GPIOD interrupts */ + +#ifdef CONFIG_SAMV7_GPIOD_IRQ + /* Enable GPIOD clocking */ + + sam_piod_enableclk(); + + /* Clear and disable all GPIOD interrupts */ + + (void)getreg32(SAM_PIOD_ISR); + putreg32(0xffffffff, SAM_PIOD_IDR); + + /* Attach and enable the GPIOC IRQ */ + + (void)irq_attach(SAM_IRQ_PIOD, sam_gpiodinterrupt); + up_enable_irq(SAM_IRQ_PIOD); +#endif + + /* Configure GPIOE interrupts */ + +#ifdef CONFIG_SAMV7_GPIOE_IRQ + /* Enable GPIOE clocking */ + + sam_pioe_enableclk(); + + /* Clear and disable all GPIOE interrupts */ + + (void)getreg32(SAM_PIOE_ISR); + putreg32(0xffffffff, SAM_PIOE_IDR); + + /* Attach and enable the GPIOE IRQ */ + + (void)irq_attach(SAM_IRQ_PIOE, sam_gpioeinterrupt); + up_enable_irq(SAM_IRQ_PIOE); +#endif +} + +/************************************************************************************ + * Name: sam_gpioirq + * + * Description: + * Configure an interrupt for the specified GPIO pin. + * + ************************************************************************************/ + +void sam_gpioirq(gpio_pinset_t pinset) +{ + uint32_t base = sam_gpiobase(pinset); + int pin = sam_gpiopin(pinset); + + /* Are any additional interrupt modes selected? */ + + if ((pinset & _GIO_INT_AIM) != 0) + { + /* Yes.. Enable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMER_OFFSET); + + /* Level or edge detected interrupt? */ + + if ((pinset & _GPIO_INT_LEVEL) != 0) + { + putreg32(pin, base + SAM_PIO_LSR_OFFSET); /* Level */ + } + else + { + putreg32(pin, base + SAM_PIO_ESR_OFFSET); /* Edge */ + } + + /* High level/rising edge or low level /falling edge? */ + + if ((pinset & _GPIO_INT_RH) != 0) + { + putreg32(pin, base + SAM_PIO_REHLSR_OFFSET); /* High level/Rising edge */ + } + else + { + putreg32(pin, base + SAM_PIO_FELLSR_OFFSET); /* Low level/Falling edge */ + } + } + else + { + /* No.. Disable additional interrupt mode */ + + putreg32(pin, base + SAM_PIO_AIMDR_OFFSET); + } +} + +/************************************************************************************ + * Name: sam_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +void sam_gpioirqenable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Clear (all) pending interrupts and enable this pin interrupt */ + + //(void)getreg32(base + SAM_PIO_ISR_OFFSET); + putreg32((1 << pin), base + SAM_PIO_IER_OFFSET); + } +} + +/************************************************************************************ + * Name: sam_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +void sam_gpioirqdisable(int irq) +{ + uint32_t base; + int pin; + + if (sam_irqbase(irq, &base, &pin) == OK) + { + /* Disable this pin interrupt */ + + putreg32((1 << pin), base + SAM_PIO_IDR_OFFSET); + } +} + +#endif /* CONFIG_SAMV7_GPIO_IRQ */ diff --git a/arch/arm/src/samv7/sam_hsmci.c b/arch/arm/src/samv7/sam_hsmci.c new file mode 100644 index 0000000000000000000000000000000000000000..89d16b37928882b6ca1639d970f18ba3dbc79a7f --- /dev/null +++ b/arch/arm/src/samv7/sam_hsmci.c @@ -0,0 +1,3466 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_hsmci.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "sam_gpio.h" +#include "sam_xdmac.h" +#include "sam_periphclks.h" +#include "sam_hsmci.h" +#include "chip/sam_xdmac.h" +#include "chip/sam_pmc.h" +#include "chip/sam_hsmci.h" +#include "chip/sam_pinmap.h" + +#ifdef CONFIG_SAMV7_HSMCI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAMV7_XDMAC +# error "HSMCI support requires CONFIG_SAMV7_XDMAC" +#endif + +/* System Bus Interfaces */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71) || defined(CONFIG_ARCH_CHIP_SAME70) +# define HSMCI_SYSBUS_IF DMACH_FLAG_PERIPHAHB_AHB_IF1 +# define MEMORY_SYSBUS_IF DMACH_FLAG_MEMAHB_AHB_IF0 +#else +# error Missing bus interface definitions +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_SDIO_BLOCKSETUP +# error "This driver requires CONFIG_SDIO_BLOCKSETUP" +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE) +# undef CONFIG_SAMV7_HSMCI_CMDDEBUG +# undef CONFIG_SAMV7_HSMCI_XFRDEBUG +#endif + +#ifdef CONFIG_SAMV7_HSMCI_RDPROOF +# ifdef CONFIG_SAMV7_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS (HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF) +# else +# define HSMCU_PROOF_BITS HSMCI_MR_RDPROOF +# endif +#else +# ifdef CONFIG_SAMV7_HSMCI_WRPROOF +# define HSMCU_PROOF_BITS HSMCI_MR_WRPROOF +# else +# define HSMCU_PROOF_BITS (0) +# endif +#endif + +/* There is some unresolved issue with the SAMV7 DMA. TX DMA is currently + * disabled. + */ + +#undef HSCMI_NORXDMA /* Define to disable RX DMA */ +#define HSCMI_NOTXDMA 1 /* Define to disable TX DMA */ + +/* Timing */ + +#define HSMCI_CMDTIMEOUT (100000) +#define HSMCI_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define HSMCI_DTIMER_DATATIMEOUT (0x000fffff) + +/* DMA configuration flags */ + +#define HSMCI_DMA_CHKSIZE HSMCI_DMA_CHKSIZE_1 + +#define DMA_FLAGS(pid) \ + (DMACH_FLAG_PERIPHPID(pid) | HSMCI_SYSBUS_IF | \ + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \ + DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \ + DMACH_FLAG_MEMPID_MAX | MEMORY_SYSBUS_IF | \ + DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | \ + DMACH_FLAG_MEMCHUNKSIZE_4 | DMACH_FLAG_MEMBURST_1) + +/* Status errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_STATUS_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | \ + HSMCI_INT_RCRCE | HSMCI_INT_RDIRE | HSMCI_INT_RINDE) + +/* Response errors: + * + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_RTOE Response Time-out + * HSMCI_INT_RENDE Response End Bit Error + * HSMCI_INT_RCRCE Response CRC Error + * HSMCI_INT_RDIRE Response Direction Error + * HSMCI_INT_RINDE Response Index Error + */ + +#define HSMCI_RESPONSE_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RCRCE | \ + HSMCI_INT_RDIRE | HSMCI_INT_RINDE) +#define HSMCI_RESPONSE_NOCRC_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE | HSMCI_INT_RENDE | HSMCI_INT_RDIRE | \ + HSMCI_INT_RINDE) +#define HSMCI_RESPONSE_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_RTOE) + +/* Data transfer errors: + * + * HSMCI_INT_UNRE Data transmit underrun + * HSMCI_INT_OVRE Data receive overrun + * HSMCI_INT_BLKOVRE DMA receive block overrun error + * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) + * HSMCI_INT_DCRCE Data CRC Error + */ + +#define HSMCI_DATA_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \ + HSMCI_INT_DTOE | HSMCI_INT_DCRCE) + +#define HSMCI_DATA_TIMEOUT_ERRORS \ + (HSMCI_INT_CSTOE | HSMCI_INT_DTOE) + +#define HSMCI_DATA_RECV_ERRORS \ + (HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \ + HSMCI_INT_DCRCE) + +#define HSMCI_DATA_DMASEND_ERRORS \ + (HSMCI_INT_UNRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | HSMCI_INT_DCRCE) + +/* Data transfer status and interrupt mask bits. + * + * The XFRDONE flag in the HSMCI_SR indicates exactly when the read or + * write sequence is finished. + * + * 0: A transfer is in progress. + * 1: Command register is ready to operate and the data bus is in the idle state. + * + * DMADONE: DMA Transfer done + * + * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 1: DMA buffer transfer has completed. + */ + +#define HSMCI_RECV_INTS \ + (HSMCI_DATA_RECV_ERRORS | HSMCI_INT_RXRDY) +#define HSMCI_DMARECV_INTS \ + (HSMCI_DATA_RECV_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) +#define HSMCI_DMASEND_INTS \ + (HSMCI_DATA_DMASEND_ERRORS | HSMCI_INT_XFRDONE /* | HSMCI_INT_DMADONE */) + +/* Event waiting interrupt mask bits. + * + * CMDRDY (Command Ready): + * + * 0: A command is in progress + * 1: The last command has been sent. The CMDRDY flag is released 8 bits + * after the end of the card response. Cleared when writing in the HSMCI_CMDR + */ + +#define HSMCI_CMDRESP_INTS \ + (HSMCI_RESPONSE_ERRORS | HSMCI_INT_CMDRDY) +#define HSMCI_CMDRESP_NOCRC_INTS \ + (HSMCI_RESPONSE_NOCRC_ERRORS | HSMCI_INT_CMDRDY) + +/* Register logging support */ + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +# ifdef CONFIG_DEBUG_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define SAMPLENDX_TIMEOUT 5 +# define DEBUG_NDMASAMPLES 6 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define SAMPLENDX_TIMEOUT 3 +# define DEBUG_NDMASAMPLES 4 +# endif +#endif + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG +# define SAMPLENDX_AFTER_CMDR 0 +# define SAMPLENDX_AT_WAKEUP 1 +# define DEBUG_NCMDSAMPLES 2 +#endif + +/* Some semi-standard definitions */ + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Register logging support */ + +#if defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) || defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) +struct sam_hsmciregs_s +{ + uint32_t mr; /* Mode Register */ + uint32_t dtor; /* Data Timeout Register */ + uint32_t sdcr; /* SD/SDIO Card Register */ + uint32_t argr; /* Argument Register */ + uint32_t blkr; /* Block Register */ + uint32_t cstor; /* Completion Signal Timeout Register */ +#if 0 /* Reading these can cause loss of response data */ + uint32_t rsp0; /* Response Register 0 */ + uint32_t rsp1; /* Response Register 1 */ + uint32_t rsp2; /* Response Register 2 */ + uint32_t rsp3; /* Response Register 3 */ +#endif + uint32_t sr; /* Status Register */ + uint32_t imr; /* Interrupt Mask Register */ + uint32_t dma; /* DMA Configuration Register */ + uint32_t cfg; /* Configuration Register */ + uint32_t wpmr; /* Write Protection Mode Register */ + uint32_t wpsr; /* Write Protection Status Register */ +}; +#endif + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +struct sam_xfrregs_s +{ + struct sam_hsmciregs_s hsmci; +#ifdef CONFIG_DEBUG_DMA + struct sam_dmaregs_s dma; +#endif +}; +#endif + +/* This structure defines the state of the SAMV7 HSMCI interface */ + +struct sam_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* SAMV7-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t base; /* HSMCI register base address */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + uint8_t hsmci; /* HSMCI (0, 1, or 2) */ + volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ + volatile bool xfrbusy; /* TRUE: Transfer is in progress */ + volatile bool txbusy; /* TRUE: TX transfer is in progress (for delay calculation) */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + ssize_t remaining; /* Number of bytes remaining in the transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ + DMA_HANDLE dma; /* Handle for DMA channel */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_HSMCI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif + + /* Register logging support */ + +#if defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) && defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) + bool xfrinitialized; + bool cmdinitialized; +#endif +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG + uint8_t smplset; + struct sam_xfrregs_s xfrsamples[DEBUG_NDMASAMPLES]; +#endif +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG + struct sam_hsmciregs_s cmdsamples[DEBUG_NCMDSAMPLES]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_dev_s *priv); +#define sam_givesem(priv) (sem_post(&priv->waitsem)) + +#ifdef CONFIG_SAMV7_HSMCI_REGDEBUG +static bool sam_checkreg(struct sam_dev_s *priv, bool wr, + uint32_t value, uint32_t address); +#else +# define sam_checkreg(priv,wr,value,address) (false) +#endif + +static inline uint32_t sam_getreg(struct sam_dev_s *priv, + unsigned int offset); +static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, + unsigned int offset); + +static inline void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents); +static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static void sam_disablexfrints(struct sam_dev_s *priv); +static inline void sam_enableints(struct sam_dev_s *priv); + +static inline void sam_disable(struct sam_dev_s *priv); +static inline void sam_enable(struct sam_dev_s *priv); + +/* Register Sampling ********************************************************/ + +#if defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) || defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs); +static void sam_hsmcidump(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs, const char *msg); +#endif + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(struct sam_dev_s *priv); +static void sam_xfrsample(struct sam_dev_s *priv, int index); +static void sam_xfrdumpone(struct sam_dev_s *priv, int index, + const char *msg); +static void sam_xfrdump(struct sam_dev_s *priv); +#else +# define sam_xfrsampleinit(priv) +# define sam_xfrsample(priv,index) +# define sam_xfrdump(priv) +#endif + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(struct sam_dev_s *priv); +static inline void sam_cmdsample1(struct sam_dev_s *priv, int index3); +static inline void sam_cmdsample2(struct sam_dev_s *priv, int index, + uint32_t sr); +static void sam_cmddump(struct sam_dev_s *priv); +#else +# define sam_cmdsampleinit(priv) +# define sam_cmdsample1(priv,index) +# define sam_cmdsample2(priv,index,sr) +# define sam_cmddump(priv) +#endif + +/* DMA Helpers **************************************************************/ + +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t hsmci_regaddr(struct sam_dev_s *priv, + unsigned int offset); + +/* Data Transfer Helpers ****************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg); +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_notransfer(struct sam_dev_s *priv); + +/* Interrupt Handling *******************************************************/ + +static int sam_hsmci_interrupt(struct sam_dev_s *priv); +#ifdef CONFIG_SAMV7_HSMCI0 +static int sam_hsmci0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_HSMCI1 +static int sam_hsmci1_interrupt(int irq, void *context); +#endif + +/* SDIO interface methods ***************************************************/ + +/* Initialization/setup */ + +static void sam_reset(FAR struct sdio_dev_s *dev); +static uint8_t sam_status(FAR struct sdio_dev_s *dev); +static void sam_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void sam_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int sam_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks); +static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes); +static int sam_cancel(FAR struct sdio_dev_s *dev); +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + sam_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev); +#endif +#ifndef HSCMI_NORXDMA +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +#endif +#ifndef HSCMI_NOTXDMA +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void sam_callback(void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Callbacks */ + +static const struct sdio_dev_s g_callbacks = +{ + .reset = sam_reset, + .status = sam_status, + .widebus = sam_widebus, + .clock = sam_clock, + .attach = sam_attach, + .sendcmd = sam_sendcmd, + .blocksetup = sam_blocksetup, + .recvsetup = sam_recvsetup, + .sendsetup = sam_sendsetup, + .cancel = sam_cancel, + .waitresponse = sam_waitresponse, + .recvR1 = sam_recvshort, + .recvR2 = sam_recvlong, + .recvR3 = sam_recvshort, + .recvR4 = sam_recvnotimpl, + .recvR5 = sam_recvnotimpl, + .recvR6 = sam_recvshort, + .recvR7 = sam_recvshort, + .waitenable = sam_waitenable, + .eventwait = sam_eventwait, + .callbackenable = sam_callbackenable, + .registercallback = sam_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = sam_dmasupported, +#ifndef HSCMI_NORXDMA + .dmarecvsetup = sam_dmarecvsetup, +#else + .dmarecvsetup = sam_recvsetup, +#endif +#ifndef HSCMI_NOTXDMA + .dmasendsetup = sam_dmasendsetup, +#else + .dmasendsetup = sam_sendsetup, +#endif +#endif +}; + +/* Pre-allocate memory for each HSMCI device */ + +#ifdef CONFIG_SAMV7_HSMCI0 +static struct sam_dev_s g_hsmci0; +#endif +#ifdef CONFIG_SAMV7_HSMCI1 +static struct sam_dev_s g_hsmci1; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_REGDEBUG +static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = value; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Read an HSMCI register + * + ****************************************************************************/ + +static inline uint32_t sam_getreg(struct sam_dev_s *priv, unsigned int offset) +{ + uint32_t address = priv->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMV7_HSMCI_REGDEBUG + if (sam_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Write a value to an HSMCI register + * + ****************************************************************************/ + +static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, + unsigned int offset) +{ + uint32_t address = priv->base + offset; + +#ifdef CONFIG_SAMV7_HSMCI_REGDEBUG + if (sam_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: sam_configwaitints + * + * Description: + * Configure HSMCI interrupts needed to support the wait function. Wait + * interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * waitmask - The set of bits in the HSMCI MASK register to set + * waitevents - Waited for events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_configwaitints(struct sam_dev_s *priv, + uint32_t waitmask, + sdio_eventset_t waitevents) +{ + irqstate_t flags; + + /* Save all of the data in one, atomic operation. */ + + flags = enter_critical_section(); + priv->waitevents = waitevents; + priv->wkupevent = 0; + priv->waitmask = waitmask; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_disablewaitints + * + * Description: + * Disable HSMCI interrupts and save wakeup event. Called + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * wkupevent - Wake-up event(s) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + + flags = enter_critical_section(); + priv->waitevents = 0; + priv->wkupevent = wkupevent; + priv->waitmask = 0; + sam_putreg(priv, ~priv->xfrmask, SAM_HSMCI_IDR_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_configxfrints + * + * Description: + * Configure HSMCI interrupts needed to support the data transfer. Data + * transfer interrupts are configured here, but not enabled until + * sam_enableints() is called. Why? Because the XFRDONE interrupt + * is always pending until start the data transfer. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +{ + priv->xfrmask = xfrmask; +} + +/**************************************************************************** + * Name: sam_disablexfrints + * + * Description: + * Disable HSMCI interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * xfrmask - The set of bits in the HSMCI MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_disablexfrints(struct sam_dev_s *priv) +{ + irqstate_t flags = enter_critical_section(); + priv->xfrmask = 0; + sam_putreg(priv, ~priv->waitmask, SAM_HSMCI_IDR_OFFSET); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_enableints + * + * Description: + * Enable the previously configured HSMCI interrupts needed to suport the + * wait and transfer functions. + * + * Input Parameters: + * priv - A reference to the HSMCI device state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void sam_enableints(struct sam_dev_s *priv) +{ + /* Enable all interrupts associated with the waited-for event */ + + sam_putreg(priv, priv->xfrmask | priv->waitmask, SAM_HSMCI_IER_OFFSET); +} + +/**************************************************************************** + * Name: sam_disable + * + * Description: + * Disable the HSMCI + * + ****************************************************************************/ + +static inline void sam_disable(struct sam_dev_s *priv) +{ + /* Disable the MCI */ + + sam_putreg(priv, HSMCI_CR_MCIDIS, SAM_HSMCI_CR_OFFSET); + + /* Disable all the interrupts */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); +} + +/**************************************************************************** + * Name: sam_enable + * + * Description: + * Enable the HSMCI + * + ****************************************************************************/ + +static inline void sam_enable(struct sam_dev_s *priv) +{ + /* Enable the MCI and the Power Saving */ + + sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); +} + +/**************************************************************************** + * Register Sampling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmcisample + * + * Description: + * Sample HSMCI registers + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) || defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) +static void sam_hsmcisample(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs) +{ + regs->mr = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regs->dtor = sam_getreg(priv, SAM_HSMCI_DTOR_OFFSET); + regs->sdcr = sam_getreg(priv, SAM_HSMCI_SDCR_OFFSET); + regs->argr = sam_getreg(priv, SAM_HSMCI_ARGR_OFFSET); + regs->blkr = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + regs->cstor = sam_getreg(priv, SAM_HSMCI_CSTOR_OFFSET); +#if 0 /* Reading these can cause loss of response data */ + regs->rsp0 = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + regs->rsp1 = sam_getreg(priv, SAM_HSMCI_RSPR1_OFFSET); + regs->rsp2 = sam_getreg(priv, SAM_HSMCI_RSPR2_OFFSET); + regs->rsp3 = sam_getreg(priv, SAM_HSMCI_RSPR3_OFFSET); +#endif + regs->sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + regs->imr = sam_getreg(priv, SAM_HSMCI_IMR_OFFSET); + regs->dma = sam_getreg(priv, SAM_HSMCI_DMA_OFFSET); + regs->cfg = sam_getreg(priv, SAM_HSMCI_CFG_OFFSET); + regs->wpmr = sam_getreg(priv, SAM_HSMCI_WPMR_OFFSET); + regs->wpsr = sam_getreg(priv, SAM_HSMCI_WPSR_OFFSET); +} +#endif + +/**************************************************************************** + * Name: sam_hsmcidump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) || defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) +static void sam_hsmcidump(struct sam_dev_s *priv, + struct sam_hsmciregs_s *regs, const char *msg) +{ + fdbg("HSMCI Registers: %s\n", msg); + fdbg(" MR[%08x]: %08x\n", priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); + fdbg(" DTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); + fdbg(" SDCR[%08x]: %08x\n", priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); + fdbg(" ARGR[%08x]: %08x\n", priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); + fdbg(" BLKR[%08x]: %08x\n", priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); + fdbg(" CSTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); +#if 0 /* Reading these can cause loss of response data */ + fdbg(" RSPR0[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); + fdbg(" RSPR1[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); + fdbg(" RSPR2[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); + fdbg(" RSPR3[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); +#endif + fdbg(" SR[%08x]: %08x\n", priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); + fdbg(" IMR[%08x]: %08x\n", priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); + fdbg(" DMA[%08x]: %08x\n", priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); + fdbg(" CFG[%08x]: %08x\n", priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); + fdbg(" WPMR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); + fdbg(" WPSR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); +} +#endif + +/**************************************************************************** + * Name: sam_xfrsample + * + * Description: + * Sample HSMCI/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +static void sam_xfrsample(struct sam_dev_s *priv, int index) +{ + /* On a multiple block transfer, only sample on the first block */ + + if ((priv->smplset & (1 << index)) == 0) + { + struct sam_xfrregs_s *regs = &priv->xfrsamples[index]; + +#ifdef CONFIG_DEBUG_DMA + sam_dmasample(priv->dma, ®s->dma); +#endif + sam_hsmcisample(priv, ®s->hsmci); + priv->smplset |= (1 << index); + } +} +#endif + +/**************************************************************************** + * Name: sam_xfrsampleinit + * + * Description: + * Setup prior to collecting transfer samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +static void sam_xfrsampleinit(struct sam_dev_s *priv) +{ + priv->smplset = 0; + memset(priv->xfrsamples, 0xff, + DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s)); + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG + priv->xfrinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_xfrdumpone + * + * Description: + * Dump one transfer register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +static void sam_xfrdumpone(struct sam_dev_s *priv, int index, + const char *msg) +{ + if ((priv->smplset & (1 << index)) != 0) + { + struct sam_xfrregs_s *regs = &priv->xfrsamples[index]; + +#ifdef CONFIG_DEBUG_DMA + sam_dmadump(priv->dma, ®s->dma, msg); +#endif + sam_hsmcidump(priv, ®s->hsmci, msg); + } + else + { + fdbg("%s: Not collected\n", msg); + } +} +#endif + +/**************************************************************************** + * Name: sam_xfrdump + * + * Description: + * Dump all transfer-related, sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG +static void sam_xfrdump(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG + if (priv->xfrinitialized) +#endif + { + sam_xfrdumpone(priv, SAMPLENDX_BEFORE_SETUP, "Before setup"); +#ifdef CONFIG_DEBUG_DMA + sam_xfrdumpone(priv, SAMPLENDX_BEFORE_ENABLE, "Before DMA enable"); +#endif + sam_xfrdumpone(priv, SAMPLENDX_AFTER_SETUP, "After setup"); + sam_xfrdumpone(priv, SAMPLENDX_END_TRANSFER, "End of transfer"); +#ifdef CONFIG_DEBUG_DMA + sam_xfrdumpone(priv, SAMPLENDX_DMA_CALLBACK, "DMA Callback"); +#endif + sam_xfrdumpone(priv, SAMPLENDX_TIMEOUT, "Timeout"); + + priv->smplset = 0; +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG + priv->xfrinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * Name: sam_cmdsampleinit + * + * Description: + * Setup prior to collecting command/response samples + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG +static void sam_cmdsampleinit(struct sam_dev_s *priv) +{ + memset(priv->cmdsamples, 0xff, + DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s)); + +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG + priv->cmdinitialized = true; +#endif +} +#endif + +/**************************************************************************** + * Name: sam_cmdsample1 & 2 + * + * Description: + * Sample command/response registers + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG +static inline void sam_cmdsample1(struct sam_dev_s *priv, int index) +{ + sam_hsmcisample(priv, &priv->cmdsamples[index]); +} + +static inline void sam_cmdsample2(struct sam_dev_s *priv, int index, + uint32_t sr) +{ + sam_hsmcisample(priv, &priv->cmdsamples[index]); + priv->cmdsamples[index].sr = sr; +} +#endif + +/**************************************************************************** + * Name: sam_cmddump + * + * Description: + * Dump all command/response register data + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI_CMDDEBUG +static void sam_cmddump(struct sam_dev_s *priv) +{ +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG + if (priv->cmdinitialized) +#endif + { + sam_hsmcidump(priv, &priv->cmdsamples[SAMPLENDX_AFTER_CMDR], + "After command setup"); + sam_hsmcidump(priv, &priv->cmdsamples[SAMPLENDX_AT_WAKEUP], + "After wakeup"); +#ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG + priv->cmdinitialized = false; +#endif + } +} +#endif + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dmacallback + * + * Description: + * Called when HSMCI DMA completes + * + ****************************************************************************/ + +static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + sdio_eventset_t wkupevent; + + /* Is DMA still active? We can get this callback when sam_dmastop() is + * called too. + */ + + if (priv->dmabusy) + { + /* Mark the DMA not busy and sample DMA registers */ + + priv->dmabusy = false; + sam_xfrsample((struct sam_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Terminate the transfer with an I/O error in the event of a DMA failure */ + + if (result < 0) + { + wkupevent = (result == -ETIMEDOUT ? SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); + flldbg("ERROR: DMA failed: result=%d wkupevent=%04x\n", result, wkupevent); + + /* sam_endtransfer will terminate the transfer and wait up the waiting + * client in this case. + */ + + sam_endtransfer(priv, wkupevent); + } + + /* The DMA completed without error. Wake-up the waiting client if (1) both the + * HSMCI and DMA completion events, and (2) There is a client waiting for + * this event. + * + * If the HSMCI transfer event has already completed, it must have completed + * successfully (because the DMA was not cancelled). sam_endtransfer() should + * have already received the SDIOWAIT_TRANSFERDONE event, but this event would + * not yet have been recorded. We need to post the SDIOWAIT_TRANSFERDONE + * again in this case here. + * + * The timeout will remain active until sam_endwait() is eventually called + * so we should not have any concern about hangs if the HSMCI transfer never + * completed. + */ + + else if (!priv->xfrbusy && (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) + { + /* Okay.. wake up any waiting threads */ + + sam_endwait(priv, SDIOWAIT_TRANSFERDONE); + } + } +} + +/**************************************************************************** + * Name: hsmci_regaddr + * + * Description: + * Return the physical address of an HSMCI register + * + ****************************************************************************/ + +static inline uintptr_t hsmci_regaddr(struct sam_dev_s *priv, + unsigned int offset) +{ + return priv->base + offset; +} + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_eventtimeout(int argc, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + + DEBUGASSERT(argc == 1 && priv != NULL); + sam_xfrsample((struct sam_dev_s *)arg, SAMPLENDX_TIMEOUT); + + /* Make sure that any hung DMA is stopped. dmabusy == false is the cue + * so the DMA callback is ignored. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Make sure that any hung HSMCI transfer is stopped */ + + sam_disablexfrints(priv); + sam_notransfer(priv); + + /* Is a data timeout complete event expected? (should always be the case) */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + sam_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("ERROR: Timeout\n"); + } +} + +/**************************************************************************** + * Name: sam_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts and save wakeup event */ + + sam_disablewaitints(priv, wkupevent); + + /* Wake up the waiting thread */ + + sam_givesem(priv); +} + +/**************************************************************************** + * Name: sam_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the HSMCI interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + sam_disablexfrints(priv); + + /* No data transfer */ + + sam_notransfer(priv); + + /* DMA debug instrumentation */ + + sam_xfrsample(priv, SAMPLENDX_END_TRANSFER); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0) + { + /* dmabusy == false gives the DMA callback handler a clue about what + * is going on. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + } + + /* The transfer is complete. Wake-up the waiting client if (1) both the + * HSMCI and DMA completion events, and (2) There is a client waiting for + * this event. + * + * The timeout will remain active until sam_endwait() is eventually called + * so we should not have any concern about hangs if the DMA never completes. + */ + + if (!priv->dmabusy && (priv->waitevents & wkupevent) != 0) + { + /* Okay.. wake up any waiting threads */ + + sam_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Name: sam_notransfer + * + * Description: + * Setup for no transfer. This is called both before beginning a new + * transfer and when a transfer completes. In the first case, this is the + * default setup that is overridden by sam_dmarecvsetup or sam_dmasendsetup + * + * Input Parameters: + * priv - An instance of the HSMCI device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_notransfer(struct sam_dev_s *priv) +{ + uint32_t regval; + + /* Make read/write proof (or not). This is a legacy behavior: This really + * just needs be be done once at initialization time. + */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + + /* Clear the block size and count */ + + sam_putreg(priv, 0, SAM_HSMCI_BLKR_OFFSET); + + /* Clear transfer flags (DMA could still be active in a corner case) */ + + priv->xfrbusy = false; + priv->txbusy = false; +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmci_interrupt + * + * Description: + * HSMCI interrupt handler + * + * Input Parameters: + * irq - IRQ number of the interrupts + * context - Saved machine context at the time of the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_hsmci_interrupt(struct sam_dev_s *priv) +{ + uint32_t sr; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. */ + + for (; ; ) + { + /* Check the HSMCI status register. Mask out all bits that don't + * correspond to enabled interrupts. (This depends on the fact that + * bits are ordered the same in both the SR and IMR registers). If + * there are non-zero bits remaining, then we have work to do here. + */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + enabled = sr & sam_getreg(priv, SAM_HSMCI_IMR_OFFSET); + + if (enabled == 0) + { + break; + } + + /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal a data transfer event? */ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { + /* Yes.. Did the transfer complete with an error? */ + + if ((pending & HSMCI_DATA_ERRORS) != 0) + { + /* Yes.. Was it some kind of timeout error? */ + + flldbg("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) + { + /* Yes.. Terminate with a timeout. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + else + { + /* No.. Terminate with an I/O error. */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + + /* No, If RXRDY is enabled, then we are doing a non-DMA receive. + * We need to transfer word(s) from the RDR register to the user + * buffer. + */ + + else if ((pending & HSMCI_INT_RXRDY) != 0) + { +#ifdef CONFIG_SAMV7_HSMCI_UNALIGNED + uint32_t value; + + /* Interrupt mode data transfer support */ + + DEBUGASSERT(!priv->dmabusy && priv->xfrbusy && !priv->txbusy); + DEBUGASSERT(priv->buffer && priv->remaining > 0); + + /* Is the receiving buffer aligned? */ + + value = sam_getreg(priv, SAM_HSMCI_RDR_OFFSET); + + if (((uintptr_t)priv->buffer & 3) == 0 && + priv->remaining >= sizeof(uint32_t)) + { + /* Yes.. transfer 32-bits at a time */ + + *priv->buffer++ = value; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer 8-bits at a time (little endian source) */ + + uint8_t *dest8 = (uint8_t *)priv->buffer; + + /* Unpack little endian; write in native byte order */ + + *dest8++ = (value & 0xff); + if (--priv->remaining > 0) + { + *dest8++ = ((value >> 8) & 0xff); + + if (--priv->remaining > 0) + { + *dest8++ = ((value >> 16) & 0xff); + + if (--priv->remaining > 0) + { + *dest8++ = ((value >> 24) & 0xff); + } + } + } + + priv->buffer = (uint32_t *)dest8; + } +#else + /* Interrupt mode data transfer support */ + + DEBUGASSERT(!priv->dmabusy && priv->xfrbusy && !priv->txbusy); + DEBUGASSERT(priv->buffer && priv->remaining > 0); + + /* Transfer 32-bit aligned data */ + + *priv->buffer++ = sam_getreg(priv, SAM_HSMCI_RDR_OFFSET); + priv->remaining -= sizeof(uint32_t); +#endif + /* Are we finished? */ + + if (priv->remaining <= 0) + { + /* Yes.. End the transfer */ + + priv->buffer = NULL; + priv->remaining = 0; + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Otherwise it must be a DMA transfer that completed successfully */ + + else + { + /* End the transfer */ + + sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + sdio_eventset_t wkupevent = 0; + + /* Is this a Command-Response sequence completion event? */ + + if ((pending & priv->cmdrmask) != 0) + { + sam_cmdsample2(priv, SAMPLENDX_AT_WAKEUP, sr); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fllvdbg("ERROR: events: %08x SR: %08x\n", + priv->cmdrmask, enabled); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. signal a timeout error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + } + else + { + /* No.. signal some generic I/O error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + } + + /* Yes.. Is there a thread waiting for this event set? */ + + wkupevent &= priv->waitevents; + if (wkupevent != 0) + { + /* Yes.. wake the thread up */ + + sam_endwait(priv, wkupevent); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_hsmci0_interrupt, sam_hsmci1_interrupt, and sam_hsmci2_interrupt + * + * Description: + * HSMCI interrupt handler + * + * Input Parameters: + * irq - IRQ number of the interrupts + * context - Saved machine context at the time of the interrupt + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_HSMCI0 +static int sam_hsmci0_interrupt(int irq, void *context) +{ + return sam_hsmci_interrupt(&g_hsmci0); +} +#endif + +#ifdef CONFIG_SAMV7_HSMCI1 +static int sam_hsmci1_interrupt(int irq, void *context) +{ + return sam_hsmci_interrupt(&g_hsmci1); +} +#endif + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ +/**************************************************************************** + * Name: sam_reset + * + * Description: + * Reset the HSMCI controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)dev; + irqstate_t flags; + + /* Reset the MCI */ + + flags = enter_critical_section(); + sam_putreg(priv, HSMCI_CR_SWRST, SAM_HSMCI_CR_OFFSET); + + /* Disable the MCI */ + + sam_putreg(priv, HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS, SAM_HSMCI_CR_OFFSET); + + /* Disable all the interrupts */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); + + /* Set the Data Timeout Register */ + + sam_putreg(priv, HSMCI_DTOR_DTOCYC_MAX | HSMCI_DTOR_DTOMUL_MAX, + SAM_HSMCI_DTOR_OFFSET); + + /* Set the Mode Register for ID mode frequency (probably 400KHz) */ + + sam_clock(dev, CLOCK_IDMODE); + + /* Set the SDCard Register */ + + sam_putreg(priv, HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_4BIT, + SAM_HSMCI_SDCR_OFFSET); + + /* Enable the MCI controller */ + + sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); + + /* Disable the DMA interface */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Configure MCI */ + + sam_putreg(priv, HSMCI_CFG_FIFOMODE, SAM_HSMCI_CFG_OFFSET); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ + priv->dmabusy = false; /* No DMA in progress */ + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; /* Required for DMA support */ + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see sam_status_* defines) + * + ****************************************************************************/ + +static uint8_t sam_status(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: sam_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + + /* Set 1-bit or 4-bit bus by configuring the SDCBUS field of the SDCR register */ + + regval = sam_getreg(priv, SAM_HSMCI_SDCR_OFFSET); + regval &= ~HSMCI_SDCR_SDCBUS_MASK; + regval |= wide ? HSMCI_SDCR_SDCBUS_4BIT : HSMCI_SDCR_SDCBUS_1BIT; + sam_putreg(priv, regval, SAM_HSMCI_SDCR_OFFSET); + + /* Remember the setting */ + + priv->widebus = wide; +} + +/**************************************************************************** + * Name: sam_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + bool enable = true; + + /* Fetch the current mode register and mask out the clkdiv+clockodd (and pwsdiv) */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_CLKDIV_MASK | HSMCI_MR_PWSDIV_MASK | HSMCI_MR_CLKODD); + + /* These clock devisor values that must be defined in the board-specific + * board.h header file: HSMCI_INIT_CLKDIV, HSMCI_MMCXFR_CLKDIV, + * HSMCI_SDXFR_CLKDIV, and HSMCI_SDWIDEXFR_CLKDIV. + */ + + switch (rate) + { + default: + case CLOCK_SDIO_DISABLED: /* Clock is disabled */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + enable = false; + return; + + case CLOCK_IDMODE: /* Initial ID mode clocking (<400KHz) */ + regval |= HSMCI_INIT_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_MMC_TRANSFER: /* MMC normal operation clocking */ + regval |= HSMCI_MMCXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_1BIT: /* SD normal operation clocking (narrow 1-bit mode) */ + regval |= HSMCI_SDXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + + case CLOCK_SD_TRANSFER_4BIT: /* SD normal operation clocking (wide 4-bit mode) */ + regval |= HSMCI_SDWIDEXFR_CLKDIV | HSMCI_MR_PWSDIV_MAX; + break; + }; + + /* Set the new clock diver and make sure that the clock is enabled or + * disabled, whichever the case. + */ + + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + if (enable) + { + sam_enable(priv); + } + else + { + sam_disable(priv); + } +} + +/**************************************************************************** + * Name: sam_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int sam_attach(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + xcpt_t handler; + int irq; + int ret; + + /* Select the handler and IRQ */ + +#ifdef CONFIG_SAMV7_HSMCI0 + if (priv->hsmci == 0) + { + handler = sam_hsmci0_interrupt; + irq = SAM_IRQ_HSMCI0; + } + else +#endif +#ifdef CONFIG_SAMV7_HSMCI1 + if (priv->hsmci == 1) + { + handler = sam_hsmci1_interrupt; + irq = SAM_IRQ_HSMCI1; + } + else +#endif + { + DEBUGPANIC(); + return -EINVAL; /* Shouldn't happen */ + } + + /* Attach the HSMCI interrupt handler */ + + ret = irq_attach(irq, handler); + if (ret == OK) + { + + /* Disable all interrupts at the HSMCI controller and clear (most) static + * interrupt flags by reading the status register. + */ + + sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Enable HSMCI interrupts at the NVIC. They can now be enabled at + * the HSMCI controller as needed. + */ + + up_enable_irq(irq); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int sam_sendcmd(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + uint32_t cmdidx; + + sam_cmdsampleinit(priv); + + /* Set the HSMCI Argument value */ + + sam_putreg(priv, arg, SAM_HSMCI_ARGR_OFFSET); + + /* Construct the command valid, starting with the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval = cmdidx << HSMCI_CMDR_CMDNB_SHIFT; + + /* 'OR' in response related bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + /* No response */ + + case MMCSD_NO_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= HSMCI_CMDR_RSPTYP_NONE; + + break; + + /* 48-bit response with CRC */ + + case MMCSD_R1_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + case MMCSD_R1B_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + break; + + /* 48-bit response without CRC */ + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; + regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + break; + + /* 136-bit response with CRC */ + + case MMCSD_R2_RESPONSE: + priv->cmdrmask = HSMCI_CMDRESP_INTS; + regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + break; + } + + /* 'OR' in data transfer related bits */ + + switch (cmd & MMCSD_DATAXFR_MASK) + { +#if 0 /* No MMC support */ + case MMCSD_RDSTREAM: /* MMC Read stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + break; + + case MMCSD_WRSTREAM: /* MMC Write stream */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + break; +#endif + + case MMCSD_RDDATAXFR: /* Read block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_WRDATAXFR: /* Write block transfer */ + regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); + regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + break; + + case MMCSD_NODATAXFR: + default: + if ((cmd & MMCSD_STOPXFR) != 0) + { + regval |= HSMCI_CMDR_TRCMD_STOP; + } + break; + } + + /* 'OR' in Open Drain option */ + +#if 0 /* No MMC support */ + if ((cmd & MMCSD_OPENDRAIN) != 0) + { + regval |= HSMCI_CMDR_OPDCMD; + } +#endif + + /* Write the fully decorated command to CMDR */ + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + sam_putreg(priv, regval, SAM_HSMCI_CMDR_OFFSET); + sam_cmdsample1(priv, SAMPLENDX_AFTER_CMDR); + return OK; +} + +/**************************************************************************** + * Name: sam_blocksetup + * + * Description: + * Some hardward needs to be informed of the selected blocksize. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * blocklen - The selected block size. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, + unsigned int nblocks) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regval; + + DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535); + DEBUGASSERT(blocklen < 65535 && (blocklen & 3) == 0); + + /* Make read/write proof (or not). This is a legacy behavior: This really + * just needs be be done once at initialization time. + */ + + regval = sam_getreg(priv, SAM_HSMCI_MR_OFFSET); + regval &= ~(HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF); + regval |= HSMCU_PROOF_BITS; + sam_putreg(priv, regval, SAM_HSMCI_MR_OFFSET); + + /* Set the block size and count */ + + regval = (blocklen << HSMCI_BLKR_BLKLEN_SHIFT) | + (nblocks << HSMCI_BLKR_BCNT_SHIFT); + sam_putreg(priv, regval, SAM_HSMCI_BLKR_OFFSET); +} + +/**************************************************************************** + * Name: sam_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer in which to receive the data + * buflen - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + +#ifndef CONFIG_SAMV7_HSMCI_UNALIGNED + /* Default behavior is to transfer 32-bit values only */ + + if (((uintptr_t)buffer & 3) != 0 || (buflen & 3) != 0) + { + /* Return the -EFAULT error. */ + + return -EFAULT; + } +#endif + + /* Initialize register sampling */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Disable DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + /* Setup of the transfer configuration */ + + priv->dmabusy = false; + priv->xfrbusy = true; + priv->txbusy = false; + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + + /* And enable interrupts */ + + sam_configxfrints(priv, HSMCI_RECV_INTS); + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: sam_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer containing the data to send + * buflen - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + unsigned int remaining; + const uint32_t *src; + uint32_t sr; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + +#ifndef CONFIG_SAMV7_HSMCI_UNALIGNED + /* Default behavior is to transfer 32-bit values only */ + + if (((uintptr_t)buffer & 3) != 0 || (buflen & 3) != 0) + { + /* Return the -EFAULT error. */ + + return -EFAULT; + } +#endif + + /* Disable DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + sam_configxfrints(priv, HSMCI_DMASEND_INTS); + + priv->dmabusy = false; + priv->xfrbusy = true; + priv->txbusy = true; + + /* Nullify register sampling */ + + sam_xfrsampleinit(priv); + + /* Copy each word to the TX FIFO + * + * REVISIT: If TX data underruns occur, then it may be necessary to + * disable pre-emption around this loop. + */ + + src = (const uint32_t *)buffer; + remaining = buflen; + + while (remaining > 0) + { + /* Check the HSMCI status */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + if ((sr & HSMCI_DATA_DMASEND_ERRORS) != 0) + { + /* Some fatal error has occurred */ + + fdbg("ERROR: sr %08x\n", sr); + return -EIO; + } + else if ((sr & HSMCI_INT_TXRDY) != 0) + { + /* TXRDY -- transfer another word */ + +#ifdef CONFIG_SAMV7_HSMCI_UNALIGNED + /* First check: Do we we have 32-bit address alignment? Are we + * transferring a full 32-bits? + */ + + if (((uintptr_t)priv->buffer & 3) == 0 && + priv->remaining >= sizeof(uint32_t)) + { + /* Yes.. transfer 32-bits at a time */ + + sam_putreg(priv, *src++, SAM_HSMCI_TDR_OFFSET); + remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer 8-bits at a time (little endian destination) */ + + const uint8_t *src8 = (const uint8_t *)src; + uint32_t value; + + /* Read data in native byte order, pack little endian */ + + value = (uint32_t)*src8++; + if (--remaining > 0) + { + value |= ((uint32_t)*src8++ << 8); + + if (--remaining > 0) + { + value |= ((uint32_t)*src8++ << 16); + + if (--remaining > 0) + { + value |= ((uint32_t)*src8++ << 24); + } + } + } + + src = (const uint32_t *)src8; + sam_putreg(priv, value, SAM_HSMCI_TDR_OFFSET); + } +#else + /* Transfer 32-bit aligned data */ + + sam_putreg(priv, *src++, SAM_HSMCI_TDR_OFFSET); + remaining -= sizeof(uint32_t); +#endif + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_cancel(FAR struct sdio_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + sam_disablexfrints(priv); + sam_disablewaitints(priv, 0); + + /* No data transfer */ + + sam_notransfer(priv); + + /* Clearing (most) pending interrupt status by reading the status register */ + + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + * + * dmabusy == false let's the DMA callback know what is happening. + */ + + priv->dmabusy = false; + sam_dmastop(priv->dma); + + /* Disable the DMA handshaking */ + + sam_putreg(priv, 0, SAM_HSMCI_DMA_OFFSET); + + return OK; +} + +/**************************************************************************** + * Name: sam_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t sr; + uint32_t pending; + int32_t timeout; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + timeout = HSMCI_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_NO_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + timeout = HSMCI_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + for (; ; ) + { + /* Did a Command-Response sequence termination evernt occur? */ + + sr = sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + pending = sr & priv->cmdrmask; + + if (pending != 0) + { + sam_cmdsample2(priv, SAMPLENDX_AT_WAKEUP, sr); + sam_cmddump(priv); + + /* Yes.. Did the Command-Response sequence end with an error? */ + + if ((pending & HSMCI_RESPONSE_ERRORS) != 0) + { + /* Yes.. Was the error some kind of timeout? */ + + fdbg("ERROR: cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) + { + /* Yes.. return a timeout error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + else + { + /* No.. return some generic I/O error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + SDIOWAIT_ERROR; + return -EIO; + } + } + else + { + /* The Command-Response sequence ended with no error */ + + priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE; + return OK; + } + } + else if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x events: %08x SR: %08x\n", + cmd, priv->cmdrmask, sr); + + priv->wkupevent = SDIOWAIT_TIMEOUT; + return -ETIMEDOUT; + } + } +} + +/**************************************************************************** + * Name: sam_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a failure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intact and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int sam_recvshort(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rshort) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* These responses could have CRC errors: + * + * R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * But there is no parity on the R3 response and parity errors should + * be ignored. + * + * R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + ret = -EIO; + } + + /* Return the R1/R6 response */ + + else if (rshort) + { + *rshort = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + } + + priv->wkupevent = 0; + return ret; +} + +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + + /* Check for timeout errors */ + + if ((priv->wkupevent & SDIOWAIT_TIMEOUT) != 0) + { + fdbg("ERROR: timeout\n"); + ret = -EINVAL; + } + + /* Check for other errors */ + + else if ((priv->wkupevent & SDIOWAIT_ERROR) != 0) + { + fdbg("ERROR: Other error\n"); + ret = -EIO; + } + + /* Return the long response */ + + else if (rlong) + { + rlong[0] = sam_getreg(priv, SAM_HSMCI_RSPR0_OFFSET); + rlong[1] = sam_getreg(priv, SAM_HSMCI_RSPR1_OFFSET); + rlong[2] = sam_getreg(priv, SAM_HSMCI_RSPR2_OFFSET); + rlong[3] = sam_getreg(priv, SAM_HSMCI_RSPR3_OFFSET); + } + + priv->wkupevent = 0; + return ret; +} + +/* MMC responses not supported */ + +static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, + uint32_t cmd, uint32_t *rnotimpl) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + priv->wkupevent = 0; + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling either calling SDIO_DMARECVSETUP, + * SDIO_DMASENDSETUP, or or SDIO_WAITEVENT. This is the recommended + * ordering: + * + * SDIO_WAITENABLE: Discard any pending interrupts, enable event(s) + * of interest + * SDIO_DMARECVSETUP/ + * SDIO_DMASENDSETUP: Setup the logic that will trigger the event the + * event(s) of interest + * SDIO_WAITEVENT: Wait for the event of interest (which might + * already have occurred) + * + * This sequency should eliminate race conditions between the command/trasnfer + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + sam_disablewaitints(priv, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + + waitmask = 0; + if ((eventset & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0) + { + waitmask |= priv->cmdrmask; + } + + /* Clear (most) pending interrupts by reading the status register. + * No interrupts should be lost (assuming that interrupts were enabled + * before sam_waitenable() was called). Any interrupts that become + * pending after this point must be valid event indications. + */ + + (void)sam_getreg(priv, SAM_HSMCI_SR_OFFSET); + + /* Wait interrupts are configured here, but not enabled until + * sam_eventwait() is called. Why? Because the XFRDONE interrupt is + * always pending until start the data transfer. + */ + + sam_configwaitints(priv, waitmask, eventset); +} + +/**************************************************************************** + * Name: sam_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when sam_eventwait + * returns. SDIO_WAITEVENTS must be called again before sam_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + int ret; + + /* Since interrupts not been enabled to this point, any relevant events + * are pending and should not yet have occurred. + * REVISIT: Not true. DMA interrupts are enabled. + */ + + // DEBUGASSERT(priv->waitevents != 0 && priv->wkupevent == 0); + + /* Now enable event-related interrupts. If the events are pending, they + * may happen immediately here before entering the loop. + */ + + sam_enableints(priv); + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevent will + * be non-zero (and, hopefully, the semaphore count will also be non-zero). + */ + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase */ + + if (!timeout) + { + return SDIOWAIT_TIMEOUT; + } + + /* Start the watchdog timer. I am not sure why this is, but I am + * currently seeing some additional delays when DMA is used. + */ + + if (priv->txbusy) + { + /* TX transfers can be VERY long in the worst case */ + + timeout = MAX(5000, timeout); + } + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)sam_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling sam_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + sam_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + * When wkupevent becomes non-zero, further interrupts will have already + * been disabled. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + sam_cmddump(priv); + sam_xfrdump(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: sam_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in sam_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methods. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + sam_callback(priv); +} + +/**************************************************************************** + * Name: sam_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE. + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int sam_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: sam_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool sam_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: sam_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef HSCMI_NORXDMA +static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regaddr; + uint32_t memaddr; + uint32_t regval; + unsigned int blocksize; + unsigned int nblocks; + unsigned int offset; + unsigned int i; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + + /* 32-bit buffer alignment is required for DMA transfers */ + + if (((uintptr_t)buffer & 3) != 0 || (buflen & 3) != 0) + { +#ifdef CONFIG_SAMV7_HSMCI_UNALIGNED + /* Fall back and do an unaligned, non-DMA transfer */ + + return sam_recvsetup(dev, buffer, buflen); +#else + /* Return the -EFAULT error. */ + + return -EFAULT; +#endif + } + + /* How many blocks? That should have been saved by the sam_blocksetup() + * method earlier. + */ + + regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + + DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); + + /* Physical address of the HSCMI source register, either the TDR (for + * single transfers) or the first FIFO register, and the physical address + * of the buffer in RAM. + */ + + offset = (nblocks == 1 ? SAM_HSMCI_RDR_OFFSET : SAM_HSMCI_FIFO_OFFSET); + regaddr = hsmci_regaddr(priv, offset); + memaddr = (uintptr_t)buffer; + + /* Setup register sampling (only works for the case of nblocks == 1) */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Set DMA for each block */ + + for (i = 0; i < nblocks; i++) + { + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->dma, regaddr, memaddr, buflen); + + /* Update addresses for the next block */ + + regaddr += sizeof(uint32_t); + memaddr += blocksize; + } + + /* Enable DMA handshaking */ + + sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + priv->xfrbusy = true; + priv->txbusy = false; + sam_dmastart(priv->dma, sam_dmacallback, priv); + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is started with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMARECV_INTS); + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifndef HSCMI_NOTXDMA +static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint32_t regaddr; + uint32_t memaddr; + uint32_t regval; + unsigned int blocksize; + unsigned int nblocks; + unsigned int offset; + unsigned int i; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + + /* 32-bit buffer alignment is required for DMA transfers */ + + if (((uintptr_t)buffer & 3) != 0 || (buflen & 3) != 0) + { +#ifdef CONFIG_SAMV7_HSMCI_UNALIGNED + /* Fall back and do an unaligned, non-DMA transfer */ + + return sam_sendsetup(dev, buffer, buflen); +#else + /* Return the -EFAULT error. */ + + return -EFAULT; +#endif + } + + /* How many blocks? That should have been saved by the sam_blocksetup() + * method earlier. + */ + + regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + + DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); + + /* Physical address of the HSCMI source register, either the TDR (for + * single transfers) or the first FIFO register, and the physical address + * of the buffer in RAM. + */ + + offset = (nblocks == 1 ? SAM_HSMCI_TDR_OFFSET : SAM_HSMCI_FIFO_OFFSET); + regaddr = hsmci_regaddr(priv, offset); + memaddr = (uintptr_t)buffer; + + /* Setup register sampling (only works for the case of nblocks == 1) */ + + sam_xfrsampleinit(priv); + sam_xfrsample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Set DMA for each block */ + + for (i = 0; i < nblocks; i++) + { + /* Configure the TX DMA */ + + sam_dmatxsetup(priv->dma, regaddr, memaddr, buflen); + + /* Update addresses for the next block */ + + regaddr += sizeof(uint32_t); + memaddr += blocksize; + } + + /* Enable DMA handshaking */ + + sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Start the DMA */ + + priv->dmabusy = true; + priv->xfrbusy = true; + priv->txbusy = true; + sam_dmastart(priv->dma, sam_dmacallback, priv); + + /* Configure transfer-related interrupts. Transfer interrupts are not + * enabled until after the transfer is stard with an SD command (i.e., + * at the beginning of sam_eventwait(). + */ + + sam_xfrsample(priv, SAMPLENDX_AFTER_SETUP); + sam_configxfrints(priv, HSMCI_DMASEND_INTS); + return OK; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: sam_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void sam_callback(void *arg) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)arg; + irqstate_t flags; + int ret; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + flags = enter_critical_section(); + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* This function is called either from (1) the context of the calling + * thread or from the the context of (2) card detection logic. The + * caller may or may not have interrupts disabled (we have them + * disabled here!). + * + * So to minimize the possibility of recursive behavior and to assure + * that callback is always performed outside of the interrupt handling + * context and with interrupts enabled, the callback is always performed + * on the lower priority work thread. + */ + + /* First cancel any existing work */ + + ret = work_cancel(LPWORK, &priv->cbwork); + if (ret < 0) + { + /* NOTE: Currently, work_cancel only returns success */ + + fdbg("ERROR: Failed to cancel work: %d\n", ret); + } + + fllvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + ret = work_queue(LPWORK, &priv->cbwork, (worker_t)priv->callback, + priv->cbarg, 0); + if (ret < 0) + { + /* NOTE: Currently, work_queue only returns success */ + + fdbg("ERROR: Failed to schedule work: %d\n", ret); + } + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SD for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + struct sam_dev_s *priv; + uint32_t pid; + + /* Select the slot and perform slot-specific initialization. The + * semantics here are bad. There are three HSMCI peripherals that we + * will treat as "slots." In principle they could each peripheral could + * support 4 slots, A-D. However, selection of slots B, C, and D is + * listed as "reserved" in the HSMCI register definitions. So, at least + * for now, an* HSMCI peripheral does correspond to a slot. + */ + + fvdbg("slotno: %d\n", slotno); + +#ifdef CONFIG_SAMV7_HSMCI0 + if (slotno == 0) + { + /* Select HSMCI0 */ + + priv = &g_hsmci0; + + /* HSMCI0 Initialization */ + + priv->base = SAM_HSMCI0_BASE; + priv->hsmci = 0; + + /* Configure PIOs for 4-bit, wide-bus operation. NOTE: (1) the chip + * is capable of 8-bit wide bus operation but D4-D7 are not configured, + * (2) any card detection PIOs must be set up in board-specific logic. + * + * REVISIT: What about Slot B? + */ + + sam_configgpio(GPIO_MCI0_DA0); /* Data 0 of Slot A */ + sam_configgpio(GPIO_MCI0_DA1); /* Data 1 of Slot A */ + sam_configgpio(GPIO_MCI0_DA2); /* Data 2 of Slot A */ + sam_configgpio(GPIO_MCI0_DA3); /* Data 3 of Slot A */ + sam_configgpio(GPIO_MCI0_CK); /* Common SD clock */ + sam_configgpio(GPIO_MCI0_CDA); /* Command/Response of Slot A */ + + /* Enable the HSMCI0 peripheral clock. This really should be done in + * sam_enable (as well as disabling peripheral clocks in sam_disable(). + */ + + sam_hsmci0_enableclk(); + + /* For DMA channel selection */ + + pid = SAM_PID_HSMCI0; + } + else +#endif +#ifdef CONFIG_SAMV7_HSMCI1 + if (slotno == 1) + { + /* Select HSMCI1 */ + + priv = &g_hsmci1; + + /* HSMCI1 Initialization */ + + priv->base = SAM_HSMCI1_BASE; + priv->hsmci = 1; + + /* Configure PIOs for 4-bit, wide-bus operation. NOTE: (1) the chip + * is capable of 8-bit wide bus operation but D4-D7 are not configured, + * (2) any card detection PIOs must be set up in board-specific logic. + * + * REVISIT: What about Slot B? + */ + + sam_configgpio(GPIO_MCI1_DA0); /* Data 0 of Slot A */ + sam_configgpio(GPIO_MCI1_DA1); /* Data 1 of Slot A */ + sam_configgpio(GPIO_MCI1_DA2); /* Data 2 of Slot A */ + sam_configgpio(GPIO_MCI1_DA3); /* Data 3 of Slot A */ + sam_configgpio(GPIO_MCI1_CK); /* Common SD clock */ + sam_configgpio(GPIO_MCI1_CDA); /* Command/Response of Slot A */ + + /* Enable the HSMCI1 peripheral clock This really should be done in + * sam_enable (as well as disabling peripheral clocks in sam_disable(). + */ + + sam_hsmci1_enableclk(); + + /* For DMA channel selection */ + + pid = SAM_PID_HSMCI1; + } + else +#endif + { + DEBUGPANIC(); + return NULL; + } + + fvdbg("priv: %p base: %08x hsmci: %d pid: %d\n", + priv, priv->base, priv->hsmci, pid); + + /* Initialize the HSMCI slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + + /* Initialize the callbacks */ + + memcpy(&priv->dev, &g_callbacks, sizeof(struct sdio_dev_s)); + + /* Allocate a DMA channel */ + + priv->dma = sam_dmachannel(0, DMA_FLAGS(pid)); + DEBUGASSERT(priv->dma); + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + sam_reset(&priv->dev); + return &priv->dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- possibly from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status. Interrupts are disabled here because if we are + * not called from an interrupt handler, then the following steps must + * still be atomic. + */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + fllvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + sam_callback(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is write protected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} + +#endif /* CONFIG_SAMV7_HSMCI */ diff --git a/arch/arm/src/samv7/sam_hsmci.h b/arch/arm/src/samv7/sam_hsmci.h new file mode 100644 index 0000000000000000000000000000000000000000..fa5992082dacfc7bc58f3334ec5d05371440a315 --- /dev/null +++ b/arch/arm/src/samv7/sam_hsmci.h @@ -0,0 +1,175 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_hsmci.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_HSMCI_H +#define __ARCH_ARM_SRC_SAMV7_SAM_HSMCI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * NOTE: The primary use of this function is for cases where the clock + * frequencies are not known a priori and so HSMCI clock dividers must + * be determined dynamically. This is the case, for example, when we + * execute out of SDRAM. In that case, the clocking was set up by the + * bootloader that brought us into SDRAM and it is that bootloader that + * has configured the clocking. + * + * Input parameters: + * target - The target SD frequency + * + * Returned Value: + * A bitset containing the CLKDIV and CLKODD bits as needed to configure + * the HSMCI clock output. + * + ****************************************************************************/ + +uint32_t sam_hsmci_clkdiv(uint32_t target); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- possibly from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_HSMCI_H */ diff --git a/arch/arm/src/samv7/sam_hsmci_clkdiv.c b/arch/arm/src/samv7/sam_hsmci_clkdiv.c new file mode 100644 index 0000000000000000000000000000000000000000..83b85b6cb691eb54288cac59909168177000356b --- /dev/null +++ b/arch/arm/src/samv7/sam_hsmci_clkdiv.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_pmc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMV7D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "chip.h" +#include "chip/sam_hsmci.h" +#include "sam_hsmci.h" + +#ifdef CONFIG_SAMV7_HSMCI0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * NOTE: The primary use of this function is for cases where the clock + * frequencies are not known a priori and so HSMCI clock dividers must + * be determined dynamically. This is the case, for example, when we + * execute out of SDRAM. In that case, the clocking was set up by the + * bootloader that brought us into SDRAM and it is that bootloader that + * has configured the clocking. + * + * Input parameters: + * target - The target SD frequency + * + * Returned Value: + * A bitset containing the CLKDIV and CLKODD bits as needed to configure + * the HSMCI clock output. + * + ****************************************************************************/ + +uint32_t sam_hsmci_clkdiv(uint32_t target) +{ + uint32_t clkfulldiv; + uint32_t ret; + + /* Get the largest divisor does not exceed the target value */ + + clkfulldiv = (BOARD_MCK_FREQUENCY + target - 1) / target; + + if (clkfulldiv > 2) + { + clkfulldiv -= 2; + } + else + { + clkfulldiv = 0; + } + + if (clkfulldiv > 511) + { + clkfulldiv = 511; + } + + ret = (clkfulldiv >> 1) << HSMCI_MR_CLKDIV_SHIFT; + if ((clkfulldiv & 1) != 0) + { + ret |= HSMCI_MR_CLKODD; + } + + return ret; +} + +#endif /* CONFIG_SAMV7_HSMCI */ diff --git a/arch/arm/src/samv7/sam_irq.c b/arch/arm/src/samv7/sam_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..963b87db1daec5e15a714b763fb355068426c2e1 --- /dev/null +++ b/arch/arm/src/samv7/sam_irq.c @@ -0,0 +1,652 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_irq.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#ifdef CONFIG_SAMV7_GPIO_IRQ +# include "sam_gpio.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void sam_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); +#if SAM_IRQ_NEXTINT > 15 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 31 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 47 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 63 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); +#endif +#if SAM_IRQ_NEXTINT > 79 +# warning Missing logic +#endif + leave_critical_section(flags); +} +#else +# define sam_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: sam_nmi, sam_busfault, sam_usagefault, sam_pendsv, sam_dbgmonitor, + * sam_pendsv, sam_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int sam_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int sam_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int sam_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int sam_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int sam_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int sam_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: sam_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void sam_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: sam_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int sam_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + unsigned int extint = irq - SAM_IRQ_EXTINT; + + DEBUGASSERT(irq >= SAM_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= SAM_IRQ_EXTINT) + { +#if SAM_IRQ_NEXTINT <= 32 + if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else +#elif SAM_IRQ_NEXTINT <= 64 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else +#elif SAM_IRQ_NEXTINT <= 96 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < SAM_IRQ_NEXTINT) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else +#else +# warning Missing logic +#endif + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == SAM_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == SAM_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == SAM_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == SAM_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + uint32_t regval; +#endif + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(SAM_IRQ_SVCALL, up_svcall); + irq_attach(SAM_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(SAM_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + sam_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(SAM_IRQ_MEMFAULT, up_memfault); + up_enable_irq(SAM_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(SAM_IRQ_NMI, sam_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(SAM_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(SAM_IRQ_BUSFAULT, sam_busfault); + irq_attach(SAM_IRQ_USAGEFAULT, sam_usagefault); + irq_attach(SAM_IRQ_PENDSV, sam_pendsv); + irq_attach(SAM_IRQ_DBGMONITOR, sam_dbgmonitor); + irq_attach(SAM_IRQ_RESERVED, sam_reserved); +#endif + + sam_dumpnvic("initial", SAM_IRQ_NIRQS); + + /* If a debugger is connected, try to prevent it from catching hardfaults. + * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal + * operation. + */ + +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + regval = getreg32(NVIC_DEMCR); + regval &= ~NVIC_DEMCR_VCHARDERR; + putreg32(regval, NVIC_DEMCR); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_SAMV7_GPIO_IRQ + sam_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (sam_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= SAM_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_SAMV7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqdisable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + sam_dumpnvic("disable", irq); +#endif +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (sam_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= SAM_IRQ_EXTINT) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_SAMV7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqenable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + sam_dumpnvic("enable", irq); +#endif +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= SAM_IRQ_MEMFAULT && irq < SAM_IRQ_NIRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < SAM_IRQ_EXTINT) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= SAM_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + sam_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/samv7/sam_lowputc.c b/arch/arm/src/samv7/sam_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..502884cc0de504f918e458041b7298551a94949b --- /dev/null +++ b/arch/arm/src/samv7/sam_lowputc.c @@ -0,0 +1,439 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_lowputc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_config.h" +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "sam_lowputc.h" + +#include "chip/sam_uart.h" +#include "chip/sam_pinmap.h" +#include "chip/sam_matrix.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE + +/* BAUD definitions + * + * The source clock is selectable and could be one of: + * + * - The peripheral clock + * - A division of the peripheral clock, where the divider is product- + * dependent, but generally set to 8 + * - A processor/peripheral independent clock source fully programmable + * provided by PMC (PCK) + * - The external clock, available on the SCK pin + * + * Only the first two options are supported by this driver. The divided + * peripheral clock is only used for very low BAUD selections. + */ + +#define FAST_USART_CLOCK BOARD_MCK_FREQUENCY +#define SLOW_USART_CLOCK (BOARD_MCK_FREQUENCY >> 3) + +/* Select USART parameters for the selected console */ + +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART0_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART0_2STOP +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART1_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART2_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART2_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART2_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART2_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART3_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART3_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART3_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART3_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART3_2STOP +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_UART4_BASE +# define SAM_CONSOLE_BAUD CONFIG_UART4_BAUD +# define SAM_CONSOLE_BITS CONFIG_UART4_BITS +# define SAM_CONSOLE_PARITY CONFIG_UART4_PARITY +# define SAM_CONSOLE_2STOP CONFIG_UART4_2STOP +# elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART0_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART0_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART0_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART0_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART0_2STOP +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART1_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART1_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART1_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART1_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART1_2STOP +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define SAM_CONSOLE_BASE SAM_USART2_BASE +# define SAM_CONSOLE_BAUD CONFIG_USART2_BAUD +# define SAM_CONSOLE_BITS CONFIG_USART2_BITS +# define SAM_CONSOLE_PARITY CONFIG_USART2_PARITY +# define SAM_CONSOLE_2STOP CONFIG_USART2_2STOP +# else +# error "No CONFIG_U[S]ARTn_SERIAL_CONSOLE Setting" +# endif + +/* Select the settings for the mode register */ + +# if SAM_CONSOLE_BITS == 5 +# define MR_CHRL_VALUE UART_MR_CHRL_5BITS /* 5 bits */ +# elif SAM_CONSOLE_BITS == 6 +# define MR_CHRL_VALUE UART_MR_CHRL_6BITS /* 6 bits */ +# elif SAM_CONSOLE_BITS == 7 +# define MR_CHRL_VALUE UART_MR_CHRL_7BITS /* 7 bits */ +# elif SAM_CONSOLE_BITS == 8 +# define MR_CHRL_VALUE UART_MR_CHRL_8BITS /* 8 bits */ +# elif SAM_CONSOLE_BITS == 9 && !defined(CONFIG_UART0_SERIAL_CONSOLE) && \ + !defined(CONFIG_UART1_SERIAL_CONSOLE) +# define MR_CHRL_VALUE UART_MR_MODE9 +# else +# error "Invalid number of bits" +# endif + +# if SAM_CONSOLE_PARITY == 1 +# define MR_PAR_VALUE UART_MR_PAR_ODD +# elif SAM_CONSOLE_PARITY == 2 +# define MR_PAR_VALUE UART_MR_PAR_EVEN +# else +# define MR_PAR_VALUE UART_MR_PAR_NONE +# endif + +# if SAM_CONSOLE_2STOP != 0 +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_2 +# else +# define MR_NBSTOP_VALUE UART_MR_NBSTOP_1 +# endif + +# define MR_VALUE (UART_MR_MODE_NORMAL | UART_MR_USCLKS_MCK | \ + MR_CHRL_VALUE | MR_PAR_VALUE | MR_NBSTOP_VALUE) + +#endif /* HAVE_SERIAL_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & + UART_INT_TXEMPTY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, SAM_CONSOLE_BASE + SAM_UART_THR_OFFSET); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: sam_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void sam_lowsetup(void) +{ +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint64_t divb3; + uint32_t intpart; + uint32_t fracpart; + uint32_t regval; +#endif + + /* Enable clocking for all selected UART/USARTs */ + +#ifdef CONFIG_SAMV7_UART0 + sam_uart0_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART1 + sam_uart1_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART2 + sam_uart2_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART3 + sam_uart3_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART4 + sam_uart4_enableclk(); +#endif +#ifdef CONFIG_SAMV7_USART0 + sam_usart0_enableclk(); +#endif +#ifdef CONFIG_SAMV7_USART1 + sam_usart1_enableclk(); +#endif +#ifdef CONFIG_SAMV7_USART2 + sam_usart2_enableclk(); +#endif + + /* Configure UART pins for all selected UART/USARTs */ + +#ifdef CONFIG_SAMV7_UART0 + (void)sam_configgpio(GPIO_UART0_RXD); + (void)sam_configgpio(GPIO_UART0_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART1 + (void)sam_configgpio(GPIO_UART1_RXD); + (void)sam_configgpio(GPIO_UART1_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART2 + (void)sam_configgpio(GPIO_UART2_RXD); + (void)sam_configgpio(GPIO_UART2_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART3 + (void)sam_configgpio(GPIO_UART3_RXD); + (void)sam_configgpio(GPIO_UART3_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART4 + (void)sam_configgpio(GPIO_UART4_RXD); + (void)sam_configgpio(GPIO_UART4_TXD); +#endif + +#ifdef CONFIG_SAMV7_USART0 + (void)sam_configgpio(GPIO_USART0_RXD); + (void)sam_configgpio(GPIO_USART0_TXD); +#ifdef CONFIG_USART0_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART0_CTS); +#endif +#ifdef CONFIG_USART0_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART0_RTS); +#endif +#endif + +#ifdef CONFIG_SAMV7_USART1 + (void)sam_configgpio(GPIO_USART1_RXD); + (void)sam_configgpio(GPIO_USART1_TXD); +#ifdef CONFIG_USART1_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART1_CTS); +#endif +#ifdef CONFIG_USART1_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART1_RTS); +#endif + /* To use the USART1 as an USART, the SYSIO Pin4 must be bound to PB4 + * instead of TDI + */ + + uint32_t sysioreg = getreg32(SAM_MATRIX_CCFG_SYSIO); + sysioreg |= MATRIX_CCFG_SYSIO_SYSIO4; + putreg32(sysioreg, SAM_MATRIX_CCFG_SYSIO); +#endif + +#ifdef CONFIG_SAMV7_USART2 + (void)sam_configgpio(GPIO_USART2_RXD); + (void)sam_configgpio(GPIO_USART2_TXD); +#ifdef CONFIG_USART2_OFLOWCONTROL + (void)sam_configgpio(GPIO_USART2_CTS); +#endif +#ifdef CONFIG_USART2_IFLOWCONTROL + (void)sam_configgpio(GPIO_USART2_RTS); +#endif +#endif + + /* Configure the console (only) */ +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Reset and disable receiver and transmitter */ + + putreg32((UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS), + SAM_CONSOLE_BASE + SAM_UART_CR_OFFSET); + + /* Disable all interrupts */ + + putreg32(0xffffffff, SAM_CONSOLE_BASE + SAM_UART_IDR_OFFSET); + + /* Set up the mode register */ + + putreg32(MR_VALUE, SAM_CONSOLE_BASE + SAM_UART_MR_OFFSET); + + /* Configure the console baud: + * + * Fbaud = USART_CLOCK / (16 * divisor) + * divisor = USART_CLOCK / (16 * Fbaud) + * + * NOTE: Oversampling by 8 is not supported. This may limit BAUD rates + * for lower USART clocks. + */ + + divb3 = ((FAST_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) << 3) / + (SAM_CONSOLE_BAUD << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7); + + /* Retain the fast MR peripheral clock UNLESS unless using that clock + * would result in an excessively large divider. + * + * REVISIT: The fractional divider is not used. + */ + + if ((intpart & ~UART_BRGR_CD_MASK) != 0) + { + /* Use the divided USART clock */ + + divb3 = ((SLOW_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) << 3) / + (SAM_CONSOLE_BAUD << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7); + + /* Re-select the clock source */ + + regval = getreg32(SAM_CONSOLE_BASE + SAM_UART_MR_OFFSET); + regval &= ~UART_MR_USCLKS_MASK; + regval |= UART_MR_USCLKS_MCKDIV; + putreg32(regval, SAM_CONSOLE_BASE + SAM_UART_MR_OFFSET); + } + + /* Save the BAUD divider (the fractional part is not used for UARTs) */ + + regval = UART_BRGR_CD(intpart) | UART_BRGR_FP(fracpart); + putreg32(regval, SAM_CONSOLE_BASE + SAM_UART_BRGR_OFFSET); + + /* Enable receiver & transmitter */ + + putreg32((UART_CR_RXEN | UART_CR_TXEN), + SAM_CONSOLE_BASE + SAM_UART_CR_OFFSET); +#endif +} diff --git a/arch/arm/src/samv7/sam_lowputc.h b/arch/arm/src/samv7/sam_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..1b0c5f379af46425e11dcca58e7afb377f5eba1d --- /dev/null +++ b/arch/arm/src/samv7/sam_lowputc.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_lowputc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_LOWPUTC_H +#define __ARCH_ARM_SRC_SAMV7_SAM_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void sam_lowsetup(void); + +/************************************************************************************ + * Name: sam_boardinitialize + * + * Description: + * All SAMV7 architectures must provide the following entry point. This entry + * point is called early in the initialization -- after all memory has been + * configured and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +void sam_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_LOWPUTC_H */ diff --git a/arch/arm/src/samv7/sam_mcan.c b/arch/arm/src/samv7/sam_mcan.c new file mode 100644 index 0000000000000000000000000000000000000000..f1f8f788a2f3107cb946d7f666d8a8b1b1d2414c --- /dev/null +++ b/arch/arm/src/samv7/sam_mcan.c @@ -0,0 +1,3973 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_mcan.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * SAMV7D3 Series Data Sheet + * Atmel sample code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cache.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/sam_matrix.h" +#include "chip/sam_pinmap.h" +#include "sam_periphclks.h" +#include "sam_gpio.h" +#include "sam_mcan.h" + +#if defined(CONFIG_CAN) && defined(CONFIG_SAMV7_MCAN) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Common definitions *******************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a < b) ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) ((a > b) ? a : b) +#endif + +/* Clock source *************************************************************/ + +/* PCK5 is the programmable clock source, common to all MCAN controllers */ + +#if defined(CONFIG_SAMV7_MCAN_CLKSRC_SLOW) +# define SAMV7_MCAN_CLKSRC PMC_PCK_CSS_SLOW +# define SAMV7_MCAN_CLKSRC_FREQUENCY BOARD_SLOWCLK_FREQUENCY +#elif defined(CONFIG_SAMV7_MCAN_CLKSRC_PLLA) +# define SAMV7_MCAN_CLKSRC PMC_PCK_CSS_PLLA +# define SAMV7_MCAN_CLKSRC_FREQUENCY BOARD_PLLA_FREQUENCY +#elif defined(CONFIG_SAMV7_MCAN_CLKSRC_UPLL) +# define SAMV7_MCAN_CLKSRC PMC_PCK_CSS_UPLL +# define SAMV7_MCAN_CLKSRC_FREQUENCY BOARD_UPLL_FREQUENCY +#elif defined(CONFIG_SAMV7_MCAN_CLKSRC_MCK) +# define SAMV7_MCAN_CLKSRC PMC_PCK_CSS_MCK +# define SAMV7_MCAN_CLKSRC_FREQUENCY BOARD_MCK_FREQUENCY +#else /* if defined(CONFIG_SAMV7_MCAN_CLKSRC_MAIN */ +# define SAMV7_MCAN_CLKSRC PMC_PCK_CSS_MAIN +# define SAMV7_MCAN_CLKSRC_FREQUENCY BOARD_MAINOSC_FREQUENCY +#endif + +#ifndef CONFIG_SAMV7_MCAN_CLKSRC_PRESCALER +# define CONFIG_SAMV7_MCAN_CLKSRC_PRESCALER 1 +#endif + +#define SAMV7_MCANCLK_FREQUENCY \ + (SAMV7_MCAN_CLKSRC_FREQUENCY / CONFIG_SAMV7_MCAN_CLKSRC_PRESCALER) + +/* Buffer Alignment *********************************************************/ +/* Buffer Alignment. + * + * The MCAN peripheral does not require any data be aligned. However, if + * the data cache is enabled then alignment is required. That is because + * the data will need to be invalidated and that cache invalidation will + * occur in multiples of full change lines. + */ + +#ifdef CONFIG_ARMV7M_DCACHE +# define MCAN_ALIGN ARMV7M_DCACHE_LINESIZE +# define MCAN_ALIGN_MASK (MCAN_ALIGN-1) +# define MCAN_ALIGN_UP(n) (((n) + MCAN_ALIGN_MASK) & ~MCAN_ALIGN_MASK) + +# ifndef CONFIG_ARMV7M_DCACHE_WRITETHROUGH +# warning !!! This driver will not work without CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y!!! +# endif +#endif + +/* General Configuration ****************************************************/ + +#ifndef CONFIG_CAN_TXREADY +# warning WARNING!!! CONFIG_CAN_TXREADY is required by this driver +#endif + +/* MCAN0 Configuration ******************************************************/ + +#ifdef CONFIG_SAMV7_MCAN0 + +/* Bit timing */ + +# define MCAN0_TSEG1 (CONFIG_SAMV7_MCAN0_PROPSEG + CONFIG_SAMV7_MCAN0_PHASESEG1) +# define MCAN0_TSEG2 CONFIG_SAMV7_MCAN0_PHASESEG2 +# define MCAN0_BRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN0_TSEG1 + MCAN0_TSEG2 + 3) * \ + (float)CONFIG_SAMV7_MCAN0_BITRATE)) - 1)) +# define MCAN0_SJW (CONFIG_SAMV7_MCAN0_FSJW - 1) + +# if MCAN0_TSEG1 > 63 +# error Invalid MCAN0 TSEG1 +# endif +# if MCAN0_TSEG2 > 15 +# error Invalid MCAN0 TSEG2 +# endif +# if MCAN0_SJW > 15 +# error Invalid MCAN0 SJW +# endif + +# define MCAN0_FTSEG1 (CONFIG_SAMV7_MCAN0_FPROPSEG + CONFIG_SAMV7_MCAN0_FPHASESEG1) +# define MCAN0_FTSEG2 (CONFIG_SAMV7_MCAN0_FPHASESEG2) +# define MCAN0_FBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN0_FTSEG1 + MCAN0_FTSEG2 + 3) * \ + (float)CONFIG_SAMV7_MCAN0_FBITRATE)) - 1)) +# define MCAN0_FSJW (CONFIG_SAMV7_MCAN0_FFSJW - 1) + +# if MCAN0_FTSEG1 > 15 +# error Invalid MCAN0 FTSEG1 +# endif +# if MCAN0_FTSEG2 > 7 +# error Invalid MCAN0 FTSEG2 +# endif +# if MCAN0_FSJW > 3 +# error Invalid MCAN0 FSJW +# endif + +/* MCAN0 RX FIFO0 element size */ + +# if defined(CONFIG_SAMV7_MCAN0_RXFIFO0_8BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 8 +# define MCAN0_RXFIFO0_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_12BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 12 +# define MCAN0_RXFIFO0_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_16BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 16 +# define MCAN0_RXFIFO0_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_20BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 20 +# define MCAN0_RXFIFO0_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_24BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 24 +# define MCAN0_RXFIFO0_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_32BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 32 +# define MCAN0_RXFIFO0_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_48BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 48 +# define MCAN0_RXFIFO0_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO0_64BYTES) +# define MCAN0_RXFIFO0_ELEMENT_SIZE 64 +# define MCAN0_RXFIFO0_ENCODED_SIZE 7 +# else +# error Undefined MCAN0 RX FIFO0 element size +# endif + +# ifndef CONFIG_SAMV7_MCAN0_RXFIFO0_SIZE +# define CONFIG_SAMV7_MCAN0_RXFIFO0_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN0_RXFIFO0_SIZE > 64 +# error Invalid MCAN0 number of RX FIFO0 elements +# endif + +# define MCAN0_RXFIFO0_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_RXFIFO0_SIZE * \ + MCAN0_RXFIFO0_ELEMENT_SIZE + 8) +# define MCAN0_RXFIFO0_WORDS (MCAN0_RXFIFO0_BYTES >> 2) + +/* MCAN0 RX FIFO1 element size */ + +# if defined(CONFIG_SAMV7_MCAN0_RXFIFO1_8BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 8 +# define MCAN0_RXFIFO1_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_12BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 12 +# define MCAN0_RXFIFO1_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_16BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 16 +# define MCAN0_RXFIFO1_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_20BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 20 +# define MCAN0_RXFIFO1_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_24BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 24 +# define MCAN0_RXFIFO1_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_32BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 32 +# define MCAN0_RXFIFO1_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_48BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 48 +# define MCAN0_RXFIFO1_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN0_RXFIFO1_64BYTES) +# define MCAN0_RXFIFO1_ELEMENT_SIZE 64 +# define MCAN0_RXFIFO1_ENCODED_SIZE 7 +# else +# error Undefined MCAN0 RX FIFO1 element size +# endif + +# ifndef CONFIG_SAMV7_MCAN0_RXFIFO1_SIZE +# define CONFIG_SAMV7_MCAN0_RXFIFO1_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN0_RXFIFO1_SIZE > 64 +# error Invalid MCAN0 number of RX FIFO1 elements +# endif + +# define MCAN0_RXFIFO1_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_RXFIFO1_SIZE * \ + MCAN0_RXFIFO1_ELEMENT_SIZE + 8) +# define MCAN0_RXFIFO1_WORDS (MCAN0_RXFIFO1_BYTES >> 2) + +/* MCAN0 Filters */ + +# ifndef CONFIG_SAMV7_MCAN0_NSTDFILTERS +# define CONFIG_SAMV7_MCAN0_NSTDFILTERS 0 +# endif + +# if (CONFIG_SAMV7_MCAN0_NSTDFILTERS > 128) +# error Invalid MCAN0 number of Standard Filters +# endif + +# ifndef CONFIG_SAMV7_MCAN0_NEXTFILTERS +# define CONFIG_SAMV7_MCAN0_NEXTFILTERS 0 +# endif + +# if (CONFIG_SAMV7_MCAN0_NEXTFILTERS > 64) +# error Invalid MCAN0 number of Extended Filters +# endif + +# define MCAN0_STDFILTER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_NSTDFILTERS << 2) +# define MCAN0_STDFILTER_WORDS (MCAN0_STDFILTER_BYTES >> 2) + +# define MCAN0_EXTFILTER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_NEXTFILTERS << 3) +# define MCAN0_EXTFILTER_WORDS (MCAN0_EXTFILTER_BYTES >> 2) + +/* MCAN0 RX buffer element size */ + +# if defined(CONFIG_SAMV7_MCAN0_RXBUFFER_8BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 8 +# define MCAN0_RXBUFFER_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_12BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 12 +# define MCAN0_RXBUFFER_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_16BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 16 +# define MCAN0_RXBUFFER_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_20BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 20 +# define MCAN0_RXBUFFER_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_24BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 24 +# define MCAN0_RXBUFFER_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_32BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 32 +# define MCAN0_RXBUFFER_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_48BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 48 +# define MCAN0_RXBUFFER_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN0_RXBUFFER_64BYTES) +# define MCAN0_RXBUFFER_ELEMENT_SIZE 64 +# define MCAN0_RXBUFFER_ENCODED_SIZE 7 +# else +# error Undefined MCAN0 RX buffer element size +# endif + +# ifndef CONFIG_SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE +# define CONFIG_SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE > 64 +# error Invalid MCAN0 number of RX BUFFER elements +# endif + +# define MCAN0_DEDICATED_RXBUFFER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE * \ + MCAN0_RXBUFFER_ELEMENT_SIZE + 8) +# define MCAN0_DEDICATED_RXBUFFER_WORDS \ + (MCAN0_DEDICATED_RXBUFFER_BYTES >> 2) + +/* MCAN0 TX buffer element size */ + +# if defined(CONFIG_SAMV7_MCAN0_TXBUFFER_8BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 8 +# define MCAN0_TXBUFFER_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_12BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 12 +# define MCAN0_TXBUFFER_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_16BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 16 +# define MCAN0_TXBUFFER_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_20BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 20 +# define MCAN0_TXBUFFER_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_24BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 24 +# define MCAN0_TXBUFFER_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_32BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 32 +# define MCAN0_TXBUFFER_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_48BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 48 +# define MCAN0_TXBUFFER_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN0_TXBUFFER_64BYTES) +# define MCAN0_TXBUFFER_ELEMENT_SIZE 64 +# define MCAN0_TXBUFFER_ENCODED_SIZE 7 +# else +# error Undefined MCAN0 TX buffer element size +# endif + +# ifndef CONFIG_SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE +# define CONFIG_SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE 0 +# endif + +# define MCAN0_DEDICATED_TXBUFFER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE * \ + MCAN0_TXBUFFER_ELEMENT_SIZE + 8) +# define MCAN0_DEDICATED_TXBUFFER_WORDS \ + (MCAN0_DEDICATED_TXBUFFER_BYTES >> 2) + +/* MCAN0 TX FIFOs */ + +# ifndef CONFIG_SAMV7_MCAN0_TXFIFOQ_SIZE +# define CONFIG_SAMV7_MCAN0_TXFIFOQ_SIZE 0 +# endif + +# if (CONFIG_SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE + \ + CONFIG_SAMV7_MCAN0_TXFIFOQ_SIZE) > 32 +# error Invalid MCAN0 number of TX BUFFER elements +# endif + +# ifndef CONFIG_SAMV7_MCAN0_TXEVENTFIFO_SIZE +# define CONFIG_SAMV7_MCAN0_TXEVENTFIFO_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN0_TXEVENTFIFO_SIZE > 32 +# error Invalid MCAN0 number of TX EVENT FIFO elements +# endif + +# define MCAN0_TXEVENTFIFO_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_TXEVENTFIFO_SIZE << 3) +# define MCAN0_TXEVENTFIFO_WORDS \ + (MCAN0_TXEVENTFIFO_BYTES >> 2) + +# define MCAN0_TXFIFIOQ_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN0_TXFIFOQ_SIZE * \ + MCAN0_TXBUFFER_ELEMENT_SIZE + 8) +# define MCAN0_TXFIFIOQ_WORDS (MCAN0_TXFIFIOQ_BYTES >> 2) + +/* MCAN0 Message RAM */ + +# define MCAN0_STDFILTER_INDEX 0 +# define MCAN0_EXTFILTERS_INDEX (MCAN0_STDFILTER_INDEX + MCAN0_STDFILTER_WORDS) +# define MCAN0_RXFIFO0_INDEX (MCAN0_EXTFILTERS_INDEX + MCAN0_EXTFILTER_WORDS) +# define MCAN0_RXFIFO1_INDEX (MCAN0_RXFIFO0_INDEX + MCAN0_RXFIFO0_WORDS) +# define MCAN0_RXDEDICATED_INDEX (MCAN0_RXFIFO1_INDEX + MCAN0_RXFIFO1_WORDS) +# define MCAN0_TXEVENTFIFO_INDEX (MCAN0_RXDEDICATED_INDEX + MCAN0_DEDICATED_RXBUFFER_WORDS) +# define MCAN0_TXDEDICATED_INDEX (MCAN0_TXEVENTFIFO_INDEX + MCAN0_TXEVENTFIFO_WORDS) +# define MCAN0_TXFIFOQ_INDEX (MCAN0_TXDEDICATED_INDEX + MCAN0_DEDICATED_TXBUFFER_WORDS) +# define MCAN0_MSGRAM_WORDS (MCAN0_TXFIFOQ_INDEX + MCAN0_TXFIFIOQ_WORDS) + +#endif /* CONFIG_SAMV7_MCAN0 */ + +/* Loopback mode */ + +#undef SAMV7_MCAN_LOOPBACK +#if defined(CONFIG_SAMV7_MCAN0_LOOPBACK) || defined(CONFIG_SAMV7_MCAN1_LOOPBACK) +# define SAMV7_MCAN_LOOPBACK 1 +#endif + +/* MCAN1 Configuration ******************************************************/ + +#ifdef CONFIG_SAMV7_MCAN1 + /* Bit timing */ + +# define MCAN1_TSEG1 (CONFIG_SAMV7_MCAN1_PROPSEG + CONFIG_SAMV7_MCAN1_PHASESEG1) +# define MCAN1_TSEG2 CONFIG_SAMV7_MCAN1_PHASESEG2 +# define MCAN1_BRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN1_TSEG1 + MCAN1_TSEG2 + 3) * \ + (float)CONFIG_SAMV7_MCAN1_BITRATE)) - 1)) +# define MCAN1_SJW (CONFIG_SAMV7_MCAN1_FSJW - 1) + +# if MCAN1_TSEG1 > 63 +# error Invalid MCAN1 TSEG1 +# endif +# if MCAN1_TSEG2 > 15 +# error Invalid MCAN1 TSEG2 +# endif +# if MCAN1_SJW > 15 +# error Invalid MCAN1 SJW +# endif + +# define MCAN1_FTSEG1 (CONFIG_SAMV7_MCAN1_FPROPSEG + CONFIG_SAMV7_MCAN1_FPHASESEG1) +# define MCAN1_FTSEG2 (CONFIG_SAMV7_MCAN1_FPHASESEG2) +# define MCAN1_FBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN1_FTSEG1 + MCAN1_FTSEG2 + 3) * \ + (float)CONFIG_SAMV7_MCAN1_FBITRATE)) - 1)) +# define MCAN1_FSJW (CONFIG_SAMV7_MCAN1_FFSJW - 1) + +#if MCAN1_FTSEG1 > 15 +# error Invalid MCAN1 FTSEG1 +#endif +#if MCAN1_FTSEG2 > 7 +# error Invalid MCAN1 FTSEG2 +#endif +#if MCAN1_FSJW > 3 +# error Invalid MCAN1 FSJW +#endif + +/* MCAN1 RX FIFO0 element size */ + +# if defined(CONFIG_SAMV7_MCAN1_RXFIFO0_8BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 8 +# define MCAN1_RXFIFO0_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_12BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 12 +# define MCAN1_RXFIFO0_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_16BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 16 +# define MCAN1_RXFIFO0_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_20BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 20 +# define MCAN1_RXFIFO0_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_24BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 24 +# define MCAN1_RXFIFO0_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_32BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 32 +# define MCAN1_RXFIFO0_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_48BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 48 +# define MCAN1_RXFIFO0_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO0_64BYTES) +# define MCAN1_RXFIFO0_ELEMENT_SIZE 64 +# define MCAN1_RXFIFO0_ENCODED_SIZE 7 +# else +# error Undefined MCAN1 RX FIFO0 element size +# endif + +# ifndef CONFIG_SAMV7_MCAN1_RXFIFO0_SIZE +# define CONFIG_SAMV7_MCAN1_RXFIFO0_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN1_RXFIFO0_SIZE > 64 +# error Invalid MCAN1 number of RX FIFO 0 elements +# endif + +# define MCAN1_RXFIFO0_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_RXFIFO0_SIZE * \ + MCAN1_RXFIFO0_ELEMENT_SIZE + 8) +# define MCAN1_RXFIFO0_WORDS (MCAN1_RXFIFO0_BYTES >> 2) + +/* MCAN1 RX FIFO1 element size */ + +# if defined(CONFIG_SAMV7_MCAN1_RXFIFO1_8BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 8 +# define MCAN1_RXFIFO1_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_12BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 12 +# define MCAN1_RXFIFO1_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_16BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 16 +# define MCAN1_RXFIFO1_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_20BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 20 +# define MCAN1_RXFIFO1_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_24BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 24 +# define MCAN1_RXFIFO1_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_32BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 32 +# define MCAN1_RXFIFO1_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_48BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 48 +# define MCAN1_RXFIFO1_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN1_RXFIFO1_64BYTES) +# define MCAN1_RXFIFO1_ELEMENT_SIZE 64 +# define MCAN1_RXFIFO1_ENCODED_SIZE 7 +# else +# error Undefined MCAN1 RX FIFO1 element size +# endif + +# ifndef CONFIG_SAMV7_MCAN1_RXFIFO1_SIZE +# define CONFIG_SAMV7_MCAN1_RXFIFO1_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN1_RXFIFO1_SIZE > 64 +# error Invalid MCAN1 number of RX FIFO 0 elements +# endif + +# define MCAN1_RXFIFO1_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_RXFIFO1_SIZE * \ + MCAN1_RXFIFO1_ELEMENT_SIZE + 8) +# define MCAN1_RXFIFO1_WORDS (MCAN1_RXFIFO1_BYTES >> 2) + +/* MCAN1 Filters */ + +# ifndef CONFIG_SAMV7_MCAN1_NSTDFILTERS +# define CONFIG_SAMV7_MCAN1_NSTDFILTERS 0 +# endif + +# if CONFIG_SAMV7_MCAN1_NSTDFILTERS > 128 +# error Invalid MCAN1 number of Standard Filters +# endif + +# ifndef CONFIG_SAMV7_MCAN1_NEXTFILTERS +# define CONFIG_SAMV7_MCAN1_NEXTFILTERS 0 +# endif + +# if CONFIG_SAMV7_MCAN1_NEXTFILTERS > 64 +# error Invalid MCAN1 number of Extended Filters +# endif + +# define MCAN1_STDFILTER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_NSTDFILTERS << 2) +# define MCAN1_STDFILTER_WORDS (MCAN1_STDFILTER_BYTES >> 2) + +# define MCAN1_EXTFILTER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_NEXTFILTERS << 3) +# define MCAN1_EXTFILTER_WORDS (MCAN1_EXTFILTER_BYTES >> 2) + +/* MCAN1 RX buffer element size */ + +# if defined(CONFIG_SAMV7_MCAN1_RXBUFFER_8BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 8 +# define MCAN1_RXBUFFER_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_12BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 12 +# define MCAN1_RXBUFFER_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_16BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 16 +# define MCAN1_RXBUFFER_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_20BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 20 +# define MCAN1_RXBUFFER_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_24BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 24 +# define MCAN1_RXBUFFER_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_32BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 32 +# define MCAN1_RXBUFFER_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_48BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 48 +# define MCAN1_RXBUFFER_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN1_RXBUFFER_64BYTES) +# define MCAN1_RXBUFFER_ELEMENT_SIZE 64 +# define MCAN1_RXBUFFER_ENCODED_SIZE 7 +# else +# error Undefined MCAN1 RX buffer element size +# endif + +# ifndef CONFIG_SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE +# define CONFIG_SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE > 64 +# error Invalid MCAN1 number of RX BUFFER elements +# endif + +# define MCAN1_DEDICATED_RXBUFFER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE * \ + MCAN1_RXBUFFER_ELEMENT_SIZE + 8) +# define MCAN1_DEDICATED_RXBUFFER_WORDS \ + (MCAN1_DEDICATED_RXBUFFER_BYTES >> 2) + +/* MCAN1 TX buffer element size */ + +# if defined(CONFIG_SAMV7_MCAN1_TXBUFFER_8BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 8 +# define MCAN1_TXBUFFER_ENCODED_SIZE 0 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_12BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 12 +# define MCAN1_TXBUFFER_ENCODED_SIZE 1 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_16BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 16 +# define MCAN1_TXBUFFER_ENCODED_SIZE 2 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_20BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 20 +# define MCAN1_TXBUFFER_ENCODED_SIZE 3 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_24BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 24 +# define MCAN1_TXBUFFER_ENCODED_SIZE 4 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_32BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 32 +# define MCAN1_TXBUFFER_ENCODED_SIZE 5 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_48BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 48 +# define MCAN1_TXBUFFER_ENCODED_SIZE 6 +# elif defined(CONFIG_SAMV7_MCAN1_TXBUFFER_64BYTES) +# define MCAN1_TXBUFFER_ELEMENT_SIZE 64 +# define MCAN1_TXBUFFER_ENCODED_SIZE 7 +# else +# error Undefined MCAN1 TX buffer element size +# endif + +# ifndef CONFIG_SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE +# define CONFIG_SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE 0 +# endif + +# define MCAN1_DEDICATED_TXBUFFER_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE * \ + MCAN1_TXBUFFER_ELEMENT_SIZE + 8) +# define MCAN1_DEDICATED_TXBUFFER_WORDS \ + (MCAN1_DEDICATED_TXBUFFER_BYTES >> 2) + +/* MCAN1 TX FIFOs */ + +# ifndef CONFIG_SAMV7_MCAN1_TXFIFOQ_SIZE +# define CONFIG_SAMV7_MCAN1_TXFIFOQ_SIZE 0 +# endif + +# if (CONFIG_SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE + \ + CONFIG_SAMV7_MCAN1_TXFIFOQ_SIZE) > 32 +# error Invalid MCAN1 number of TX BUFFER elements +# endif + +# ifndef CONFIG_SAMV7_MCAN1_TXEVENTFIFO_SIZE +# define CONFIG_SAMV7_MCAN1_TXEVENTFIFO_SIZE 0 +# endif + +# if CONFIG_SAMV7_MCAN1_TXEVENTFIFO_SIZE > 32 +# error Invalid MCAN1 number of TX EVENT FIFO elements +# endif + +# define MCAN1_TXEVENTFIFO_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_TXEVENTFIFO_SIZE << 3) +# define MCAN1_TXEVENTFIFO_WORDS \ + (MCAN1_TXEVENTFIFO_BYTES >> 2) + +# define MCAN1_TXFIFIOQ_BYTES \ + MCAN_ALIGN_UP(CONFIG_SAMV7_MCAN1_TXFIFOQ_SIZE * \ + MCAN1_TXBUFFER_ELEMENT_SIZE + 8) +# define MCAN1_TXFIFIOQ_WORDS (MCAN1_TXFIFIOQ_BYTES >> 2) + +/* MCAN1 Message RAM */ + +# define MCAN1_STDFILTER_INDEX 0 +# define MCAN1_EXTFILTERS_INDEX (MCAN1_STDFILTER_INDEX + MCAN1_STDFILTER_WORDS) +# define MCAN1_RXFIFO0_INDEX (MCAN1_EXTFILTERS_INDEX + MCAN1_EXTFILTER_WORDS) +# define MCAN1_RXFIFO1_INDEX (MCAN1_RXFIFO0_INDEX + MCAN1_RXFIFO0_WORDS) +# define MCAN1_RXDEDICATED_INDEX (MCAN1_RXFIFO1_INDEX + MCAN1_RXFIFO1_WORDS) +# define MCAN1_TXEVENTFIFO_INDEX (MCAN1_RXDEDICATED_INDEX + MCAN1_DEDICATED_RXBUFFER_WORDS) +# define MCAN1_TXDEDICATED_INDEX (MCAN1_TXEVENTFIFO_INDEX + MCAN1_TXEVENTFIFO_WORDS) +# define MCAN1_TXFIFOQ_INDEX (MCAN1_TXDEDICATED_INDEX + MCAN1_DEDICATED_TXBUFFER_WORDS) +# define MCAN1_MSGRAM_WORDS (MCAN1_TXFIFOQ_INDEX + MCAN1_TXFIFIOQ_WORDS) + +#endif /* CONFIG_SAMV7_MCAN1 */ + +/* MCAN helpers *************************************************************/ + +#define MAILBOX_ADDRESS(a) ((uint32_t)(a) & 0x0000fffc) + +/* Interrupts ***************************************************************/ +/* Common interrupts + * + * MCAN_INT_TSW - Timestamp Wraparound + * MCAN_INT_MRAF - Message RAM Access Failure + * MCAN_INT_TOO - Timeout Occurred + * MCAN_INT_ELO - Error Logging Overflow + * MCAN_INT_EP - Error Passive + * MCAN_INT_EW - Warning Status + * MCAN_INT_BO - Bus_Off Status + * MCAN_INT_WDI - Watchdog Interrupt + */ + +#define MCAN_CMNERR_INTS (MCAN_INT_MRAF | MCAN_INT_TOO | MCAN_INT_EP | \ + MCAN_INT_BO | MCAN_INT_WDI) +#define MCAN_COMMON_INTS MCAN_CMNERR_INTS + +/* RXFIFO mode interrupts + * + * MCAN_INT_RF0N - Receive FIFO 0 New Message + * MCAN_INT_RF0W - Receive FIFO 0 Watermark Reached + * MCAN_INT_RF0F - Receive FIFO 0 Full + * MCAN_INT_RF0L - Receive FIFO 0 Message Lost + * MCAN_INT_RF1N - Receive FIFO 1 New Message + * MCAN_INT_RF1W - Receive FIFO 1 Watermark Reached + * MCAN_INT_RF1F - Receive FIFO 1 Full + * MCAN_INT_RF1L - Receive FIFO 1 Message Lost + * MCAN_INT_HPM - High Priority Message Received + * + * Dedicated RX Buffer mode interrupts + * + * MCAN_INT_DRX - Message stored to Dedicated Receive Buffer + * + * Mode-independent RX-related interrupts + * + * MCAN_INT_CRCE - Receive CRC Error + * MCAN_INT_FOE - Format Error + * MCAN_INT_STE - Stuff Error + */ + +#define MCAN_RXCOMMON_INTS (MCAN_INT_CRCE | MCAN_INT_FOE | MCAN_INT_STE) +#define MCAN_RXFIFO0_INTS (MCAN_INT_RF0N | MCAN_INT_RF0W | MCAN_INT_RF0L) +#define MCAN_RXFIFO1_INTS (MCAN_INT_RF1N | MCAN_INT_RF1W | MCAN_INT_RF1L) +#define MCAN_RXFIFO_INTS (MCAN_RXFIFO0_INTS | MCAN_RXFIFO1_INTS | \ + MCAN_INT_HPM | MCAN_RXCOMMON_INTS) +#define MCAN_RXDEDBUF_INTS (MCAN_INT_DRX | MCAN_RXCOMMON_INTS) + +#define MCAN_RXERR_INTS (MCAN_INT_RF0L | MCAN_INT_RF1L | MCAN_INT_CRCE | \ + MCAN_INT_FOE | MCAN_INT_STE) + +/* TX FIFOQ mode interrupts + * + * MCAN_INT_TFE - Tx FIFO Empty + * + * TX Event FIFO interrupts + * + * MCAN_INT_TEFN - Tx Event FIFO New Entry + * MCAN_INT_TEFW - Tx Event FIFO Watermark Reached + * MCAN_INT_TEFF - Tx Event FIFO Full + * MCAN_INT_TEFL - Tx Event FIFO Element Lost + * + * Mode-independent TX-related interrupts + * + * MCAN_INT_TC - Transmission Completed + * MCAN_INT_TCF - Transmission Cancellation Finished + * MCAN_INT_BE - Bit Error + * MCAN_INT_ACKE - Acknowledge Error + */ + +#define MCAN_TXCOMMON_INTS (MCAN_INT_TC | MCAN_INT_TCF | MCAN_INT_BE | \ + MCAN_INT_ACKE) +#define MCAN_TXFIFOQ_INTS (MCAN_INT_TFE | MCAN_TXCOMMON_INTS) +#define MCAN_TXEVFIFO_INTS (MCAN_INT_TEFN | MCAN_INT_TEFW | MCAN_INT_TEFF | \ + MCAN_INT_TEFL) +#define MCAN_TXDEDBUF_INTS MCAN_TXCOMMON_INTS + +#define MCAN_TXERR_INTS (MCAN_INT_TEFL | MCAN_INT_BE | MCAN_INT_ACKE) + +/* Common-, TX- and RX-Error-Mask */ + +#define MCAN_ANYERR_INTS (MCAN_CMNERR_INTS | MCAN_RXERR_INTS | MCAN_TXERR_INTS) + +/* Debug ********************************************************************/ +/* Debug configurations that may be enabled just for testing MCAN */ + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_CAN) +# undef CONFIG_SAMV7_MCAN_REGDEBUG +#endif + +#ifdef CONFIG_DEBUG_CAN +# define candbg dbg +# define canvdbg vdbg +# define canlldbg lldbg +# define canllvdbg llvdbg + +# ifdef CONFIG_SAMV7_MCAN_REGDEBUG +# define canregdbg lldbg +# else +# define canregdbg(x...) +# endif + +#else +# define candbg(x...) +# define canvdbg(x...) +# define canlldbg(x...) +# define canllvdbg(x...) +# define canregdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* CAN mode of operation */ + +enum sam_canmode_e +{ + MCAN_ISO11898_1_MODE = 0, /* CAN operation according to ISO11898-1 */ + MCAN_FD_MODE = 1, /* CAN FD operation */ + MCAN_FD_BSW_MODE = 2 /* CAN FD operation with bit rate switching */ +}; + +/* CAN driver state */ + +enum can_state_s +{ + MCAN_STATE_UNINIT = 0, /* Not yet initialized */ + MCAN_STATE_RESET, /* Initialized, reset state */ + MCAN_STATE_SETUP, /* can_setup() has been called */ +}; + +/* This structure describes the MCAN message RAM layout */ + +struct sam_msgram_s +{ + uint32_t *stdfilters; /* Standard filters */ + uint32_t *extfilters; /* Extended filters */ + uint32_t *rxfifo0; /* RX FIFO0 */ + uint32_t *rxfifo1; /* RX FIFO1 */ + uint32_t *rxdedicated; /* RX dedicated buffers */ + uint32_t *txeventfifo; /* TX event FIFO */ + uint32_t *txdedicated; /* TX dedicated buffers */ + uint32_t *txfifoq; /* TX FIFO queue */ +}; + +/* This structure provides the constant configuration of a MCAN peripheral */ + +struct sam_config_s +{ + gpio_pinset_t rxpinset; /* RX pin configuration */ + gpio_pinset_t txpinset; /* TX pin configuration */ + xcpt_t handler; /* MCAN common interrupt handler */ + uintptr_t base; /* Base address of the MCAN registers */ + uint32_t baud; /* Configured baud */ + uint32_t btp; /* Bit timing/prescaler register setting */ + uint32_t fbtp; /* Fast bit timing/prescaler register setting */ + uint8_t port; /* MCAN port number (1 or 2) */ + uint8_t pid; /* MCAN peripheral ID */ + uint8_t irq0; /* MCAN peripheral IRQ number for interrupt line 0 */ + uint8_t irq1; /* MCAN peripheral IRQ number for interrupt line 1 */ + uint8_t mode; /* See enum sam_canmode_e */ + uint8_t nstdfilters; /* Number of standard filters (up to 128) */ + uint8_t nextfilters; /* Number of extended filters (up to 64) */ + uint8_t nrxfifo0; /* Number of RX FIFO0 elements (up to 64) */ + uint8_t nrxfifo1; /* Number of RX FIFO1 elements (up to 64) */ + uint8_t nrxdedicated; /* Number of dedicated RX buffers (up to 64) */ + uint8_t ntxeventfifo; /* Number of TXevent FIFO elements (up to 32) */ + uint8_t ntxdedicated; /* Number of dedicated TX buffers (up to 64) */ + uint8_t ntxfifoq; /* Number of TX FIFO queue elements (up to 32) */ + uint8_t rxfifo0ecode; /* Encoded RX FIFO0 element size */ + uint8_t rxfifo0esize; /* RX FIFO0 element size (words) */ + uint8_t rxfifo1ecode; /* Encoded RX FIFO1 element size */ + uint8_t rxfifo1esize; /* RX FIFO1 element size (words) */ + uint8_t rxbufferecode; /* Encoded RX buffer element size */ + uint8_t rxbufferesize; /* RX buffer element size (words) */ + uint8_t txbufferecode; /* Encoded TX buffer element size */ + uint8_t txbufferesize; /* TX buffer element size (words) */ +#ifdef SAMV7_MCAN_LOOPBACK + bool loopback; /* True: Loopback mode */ +#endif + + /* MCAN message RAM layout */ + + struct sam_msgram_s msgram; +}; + +/* This structure provides the current state of a MCAN peripheral */ + +struct sam_mcan_s +{ + const struct sam_config_s *config; /* The constant configuration */ + uint8_t state; /* See enum can_state_s */ +#ifdef CONFIG_CAN_EXTID + uint8_t nextalloc; /* Number of allocated extended filters */ +#endif + uint8_t nstdalloc; /* Number of allocated standard filters */ + sem_t locksem; /* Enforces mutually exclusive access */ + sem_t txfsem; /* Used to wait for TX FIFO availability */ + uint32_t btp; /* Current bit timing */ + uint32_t fbtp; /* Current fast bit timing */ + uint32_t rxints; /* Configured RX interrupts */ + uint32_t txints; /* Configured TX interrupts */ +#ifdef CONFIG_CAN_ERRORS + uint32_t olderrors; /* Used to detect the changes in error states */ +#endif + +#ifdef CONFIG_CAN_EXTID + uint32_t extfilters[2]; /* Extended filter bit allocator. 2*32=64 */ +#endif + uint32_t stdfilters[4]; /* Standard filter bit allocator. 4*32=128 */ + +#ifdef CONFIG_SAMV7_MCAN_REGDEBUG + uintptr_t regaddr; /* Last register address read */ + uint32_t regval; /* Last value read from the register */ + unsigned int count; /* Number of times that the value was read */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* MCAN Register access */ + +static uint32_t mcan_getreg(FAR struct sam_mcan_s *priv, int offset); +static void mcan_putreg(FAR struct sam_mcan_s *priv, int offset, + uint32_t regval); +#ifdef CONFIG_SAMV7_MCAN_REGDEBUG +static void mcan_dumpregs(FAR struct sam_mcan_s *priv, FAR const char *msg); +#else +# define mcan_dumpregs(priv,msg) +#endif + +/* Semaphore helpers */ + +static void mcan_dev_lock(FAR struct sam_mcan_s *priv); +#define mcan_dev_unlock(priv) sem_post(&priv->locksem) + +static void mcan_buffer_reserve(FAR struct sam_mcan_s *priv); +static void mcan_buffer_release(FAR struct sam_mcan_s *priv); + +/* MCAN helpers */ + +static uint8_t mcan_dlc2bytes(FAR struct sam_mcan_s *priv, uint8_t dlc); +#if 0 /* Not used */ +static uint8_t mcan_bytes2dlc(FAR struct sam_mcan_s *priv, uint8_t nbytes); +#endif + +#ifdef CONFIG_CAN_EXTID +static int mcan_add_extfilter(FAR struct sam_mcan_s *priv, + FAR struct canioc_extfilter_s *extconfig); +static int mcan_del_extfilter(FAR struct sam_mcan_s *priv, int ndx); +#endif +static int mcan_add_stdfilter(FAR struct sam_mcan_s *priv, + FAR struct canioc_stdfilter_s *stdconfig); +static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx); + +/* CAN driver methods */ + +static void mcan_reset(FAR struct can_dev_s *dev); +static int mcan_setup(FAR struct can_dev_s *dev); +static void mcan_shutdown(FAR struct can_dev_s *dev); +static void mcan_rxint(FAR struct can_dev_s *dev, bool enable); +static void mcan_txint(FAR struct can_dev_s *dev, bool enable); +static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, + unsigned long arg); +static int mcan_remoterequest(FAR struct can_dev_s *dev, uint16_t id); +static int mcan_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg); +static bool mcan_txready(FAR struct can_dev_s *dev); +static bool mcan_txempty(FAR struct can_dev_s *dev); + +/* MCAN interrupt handling */ + +#if 0 /* Not Used */ +static bool mcan_dedicated_rxbuffer_available(FAR struct sam_mcan_s *priv, + int bufndx); +#endif +#ifdef CONFIG_CAN_ERRORS +static void mcan_error(FAR struct can_dev_s *dev, uint32_t status, + uint32_t oldstatus); +#endif +static void mcan_receive(FAR struct can_dev_s *dev, + FAR uint32_t *rxbuffer, unsigned long nwords); +static void mcan_interrupt(FAR struct can_dev_s *dev); +#ifdef CONFIG_SAMV7_MCAN0 +static int mcan0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_MCAN1 +static int mcan1_interrupt(int irq, void *context); +#endif + +/* Hardware initialization */ + +static int mcan_hw_initialize(FAR struct sam_mcan_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct can_ops_s g_mcanops = +{ + .co_reset = mcan_reset, + .co_setup = mcan_setup, + .co_shutdown = mcan_shutdown, + .co_rxint = mcan_rxint, + .co_txint = mcan_txint, + .co_ioctl = mcan_ioctl, + .co_remoterequest = mcan_remoterequest, + .co_send = mcan_send, + .co_txready = mcan_txready, + .co_txempty = mcan_txempty, +}; + +#ifdef CONFIG_SAMV7_MCAN0 +/* Message RAM allocation */ + +static uint32_t g_mcan0_msgram[MCAN0_MSGRAM_WORDS] +#ifdef CONFIG_ARMV7M_DCACHE + __attribute__((aligned(MCAN_ALIGN))); +#else + ; +#endif + +/* Constant configuration */ + +static const struct sam_config_s g_mcan0const = +{ + .rxpinset = GPIO_MCAN0_RX, + .txpinset = GPIO_MCAN0_TX, + .handler = mcan0_interrupt, + .base = SAM_MCAN0_BASE, + .baud = CONFIG_SAMV7_MCAN0_BITRATE, + .btp = MCAN_BTP_BRP(MCAN0_BRP) | MCAN_BTP_TSEG1(MCAN0_TSEG1) | + MCAN_BTP_TSEG2(MCAN0_TSEG2) | MCAN_BTP_SJW(MCAN0_SJW), + .fbtp = MCAN_FBTP_FBRP(MCAN0_FBRP) | MCAN_FBTP_FTSEG1(MCAN0_FTSEG1) | + MCAN_FBTP_FTSEG2(MCAN0_FTSEG2) | MCAN_FBTP_FSJW(MCAN0_FSJW), + .port = 0, + .pid = SAM_PID_MCAN00, + .irq0 = SAM_IRQ_MCAN00, + .irq1 = SAM_IRQ_MCAN01, +#if defined(CONFIG_SAMV7_MCAN0_ISO11899_1) + .mode = MCAN_ISO11898_1_MODE, +#elif defined(CONFIG_SAMV7_MCAN0_FD) + .mode = MCAN_FD_MODE, +#else /* if defined(CONFIG_SAMV7_MCAN0_FD_BSW) */ + .mode = MCAN_FD_BSW_MODE, +#endif + .nstdfilters = CONFIG_SAMV7_MCAN0_NSTDFILTERS, + .nextfilters = CONFIG_SAMV7_MCAN0_NEXTFILTERS, + .nrxfifo0 = CONFIG_SAMV7_MCAN0_RXFIFO0_SIZE, + .nrxfifo1 = CONFIG_SAMV7_MCAN0_RXFIFO1_SIZE, + .nrxdedicated = CONFIG_SAMV7_MCAN0_DEDICATED_RXBUFFER_SIZE, + .ntxeventfifo = CONFIG_SAMV7_MCAN0_TXEVENTFIFO_SIZE, + .ntxdedicated = CONFIG_SAMV7_MCAN0_DEDICATED_TXBUFFER_SIZE, + .ntxfifoq = CONFIG_SAMV7_MCAN0_TXFIFOQ_SIZE, + .rxfifo0ecode = MCAN0_RXFIFO0_ENCODED_SIZE, + .rxfifo0esize = (MCAN0_RXFIFO0_ELEMENT_SIZE / 4) + 2, + .rxfifo1ecode = MCAN0_RXFIFO1_ENCODED_SIZE, + .rxfifo1esize = (MCAN0_RXFIFO1_ELEMENT_SIZE / 4) + 2, + .rxbufferecode = MCAN0_RXBUFFER_ENCODED_SIZE, + .rxbufferesize = (MCAN0_RXBUFFER_ELEMENT_SIZE / 4) + 2, + .txbufferecode = MCAN0_TXBUFFER_ENCODED_SIZE, + .txbufferesize = (MCAN0_TXBUFFER_ELEMENT_SIZE / 4) + 2, + +#ifdef CONFIG_SAMV7_MCAN0_LOOPBACK + .loopback = true, +#endif + + /* MCAN0 Message RAM */ + + .msgram = + { + &g_mcan0_msgram[MCAN0_STDFILTER_INDEX], + &g_mcan0_msgram[MCAN0_EXTFILTERS_INDEX], + &g_mcan0_msgram[MCAN0_RXFIFO0_INDEX], + &g_mcan0_msgram[MCAN0_RXFIFO1_INDEX], + &g_mcan0_msgram[MCAN0_RXDEDICATED_INDEX], + &g_mcan0_msgram[MCAN0_TXEVENTFIFO_INDEX], + &g_mcan0_msgram[MCAN0_TXDEDICATED_INDEX], + &g_mcan0_msgram[MCAN0_TXFIFOQ_INDEX] + } +}; + +/* MCAN0 variable driver state */ + +static struct sam_mcan_s g_mcan0priv; +static struct can_dev_s g_mcan0dev; + +#endif /* CONFIG_SAMV7_MCAN0 */ + +#ifdef CONFIG_SAMV7_MCAN1 +/* MCAN1 message RAM allocation */ + +static uint32_t g_mcan1_msgram[MCAN1_MSGRAM_WORDS] +#ifdef CONFIG_ARMV7M_DCACHE + __attribute__((aligned(MCAN_ALIGN))); +#else + ; +#endif + +/* MCAN1 constant configuration */ + +static const struct sam_config_s g_mcan1const = +{ + .rxpinset = GPIO_MCAN1_RX, + .txpinset = GPIO_MCAN1_TX, + .handler = mcan1_interrupt, + .base = SAM_MCAN1_BASE, + .baud = CONFIG_SAMV7_MCAN1_BITRATE, + .btp = MCAN_BTP_BRP(MCAN1_BRP) | MCAN_BTP_TSEG1(MCAN1_TSEG1) | + MCAN_BTP_TSEG2(MCAN1_TSEG2) | MCAN_BTP_SJW(MCAN1_SJW), + .fbtp = MCAN_FBTP_FBRP(MCAN1_FBRP) | MCAN_FBTP_FTSEG1(MCAN1_FTSEG1) | + MCAN_FBTP_FTSEG2(MCAN1_FTSEG2) | MCAN_FBTP_FSJW(MCAN1_FSJW), + .port = 1, + .pid = SAM_PID_MCAN10, + .irq0 = SAM_IRQ_MCAN10, + .irq1 = SAM_IRQ_MCAN11, +#if defined(CONFIG_SAMV7_MCAN1_ISO11899_1) + .mode = MCAN_ISO11898_1_MODE, +#elif defined(CONFIG_SAMV7_MCAN1_FD) + .mode = MCAN_FD_MODE, +#else /* if defined(CONFIG_SAMV7_MCAN1_FD_BSW) */ + .mode = MCAN_FD_BSW_MODE, +#endif + .nstdfilters = CONFIG_SAMV7_MCAN1_NSTDFILTERS, + .nextfilters = CONFIG_SAMV7_MCAN1_NEXTFILTERS, + .nrxfifo0 = CONFIG_SAMV7_MCAN1_RXFIFO0_SIZE, + .nrxfifo1 = CONFIG_SAMV7_MCAN1_RXFIFO1_SIZE, + .nrxdedicated = CONFIG_SAMV7_MCAN1_DEDICATED_RXBUFFER_SIZE, + .ntxeventfifo = CONFIG_SAMV7_MCAN1_TXEVENTFIFO_SIZE, + .ntxdedicated = CONFIG_SAMV7_MCAN1_DEDICATED_TXBUFFER_SIZE, + .ntxfifoq = CONFIG_SAMV7_MCAN1_TXFIFOQ_SIZE, + .rxfifo0ecode = MCAN1_RXFIFO0_ENCODED_SIZE, + .rxfifo0esize = (MCAN1_RXFIFO0_ELEMENT_SIZE / 4) + 2, + .rxfifo1ecode = MCAN1_RXFIFO1_ENCODED_SIZE, + .rxfifo1esize = (MCAN1_RXFIFO1_ELEMENT_SIZE / 4) + 2, + .rxbufferecode = MCAN1_RXBUFFER_ENCODED_SIZE, + .rxbufferesize = (MCAN1_RXBUFFER_ELEMENT_SIZE / 4) + 2, + .txbufferecode = MCAN1_TXBUFFER_ENCODED_SIZE, + .txbufferesize = (MCAN1_TXBUFFER_ELEMENT_SIZE / 4) + 2, + +#ifdef CONFIG_SAMV7_MCAN1_LOOPBACK + .loopback = true, +#endif + /* MCAN0 Message RAM */ + + .msgram = + { + &g_mcan1_msgram[MCAN1_STDFILTER_INDEX], + &g_mcan1_msgram[MCAN1_EXTFILTERS_INDEX], + &g_mcan1_msgram[MCAN1_RXFIFO0_INDEX], + &g_mcan1_msgram[MCAN1_RXFIFO1_INDEX], + &g_mcan1_msgram[MCAN1_RXDEDICATED_INDEX], + &g_mcan1_msgram[MCAN1_TXEVENTFIFO_INDEX], + &g_mcan1_msgram[MCAN1_TXDEDICATED_INDEX], + &g_mcan1_msgram[MCAN1_TXFIFOQ_INDEX] + } +}; + +/* MCAN0 variable driver state */ + +static struct sam_mcan_s g_mcan1priv; +static struct can_dev_s g_mcan1dev; + +#endif /* CONFIG_SAMV7_MCAN1 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcan_getreg + * + * Description: + * Read the value of a MCAN register. + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_MCAN_REGDEBUG +static uint32_t mcan_getreg(FAR struct sam_mcan_s *priv, int offset) +{ + FAR const struct sam_config_s *config = priv->config; + uintptr_t regaddr; + uint32_t regval; + + /* Read the value from the register */ + + regaddr = config->base + offset; + regval = getreg32(regaddr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (regaddr == priv->regaddr && regval == priv->regval) + { + if (priv->count == 0xffffffff || ++priv->count > 3) + { + if (priv->count == 4) + { + lldbg("...\n"); + } + + return regval; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (priv->count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", priv->count - 3); + } + + /* Save the new address, value, and count */ + + priv->regaddr = regaddr; + priv->regval = regval; + priv->count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", regaddr, regval); + return regval; +} + +#else +static uint32_t mcan_getreg(FAR struct sam_mcan_s *priv, int offset) +{ + FAR const struct sam_config_s *config = priv->config; + return getreg32(config->base + offset); +} + +#endif + +/**************************************************************************** + * Name: mcan_putreg + * + * Description: + * Set the value of a MCAN register. + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * offset - The offset to the register to write + * regval - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_MCAN_REGDEBUG +static void mcan_putreg(FAR struct sam_mcan_s *priv, int offset, uint32_t regval) +{ + FAR const struct sam_config_s *config = priv->config; + uintptr_t regaddr = config->base + offset; + + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", regaddr, regval); + + /* Write the value */ + + putreg32(regval, regaddr); +} + +#else +static void mcan_putreg(FAR struct sam_mcan_s *priv, int offset, uint32_t regval) +{ + FAR const struct sam_config_s *config = priv->config; + putreg32(regval, config->base + offset); +} + +#endif + +/**************************************************************************** + * Name: mcan_dumpregs + * + * Description: + * Dump the contents of all MCAN control registers + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_MCAN_REGDEBUG +static void mcan_dumpregs(FAR struct sam_mcan_s *priv, FAR const char *msg) +{ + FAR const struct sam_config_s *config = priv->config; + + lldbg("MCAN%d Registers: %s\n", config->port, msg); + lldbg(" Base: %08x\n", config->base); + + lldbg(" CUST: %08x FBTP: %08x TEST: %08x RWD: %08x\n", + getreg32(config->base + SAM_MCAN_CUST_OFFSET), + getreg32(config->base + SAM_MCAN_FBTP_OFFSET), + getreg32(config->base + SAM_MCAN_TEST_OFFSET), + getreg32(config->base + SAM_MCAN_RWD_OFFSET)); + + lldbg(" CCCR: %08x BTP: %08x TSCC: %08x TSCV: %08x\n", + getreg32(config->base + SAM_MCAN_CCCR_OFFSET), + getreg32(config->base + SAM_MCAN_BTP_OFFSET), + getreg32(config->base + SAM_MCAN_TSCC_OFFSET), + getreg32(config->base + SAM_MCAN_TSCV_OFFSET)); + + lldbg(" TOCC: %08x TOCV: %08x ECR: %08x PSR: %08x\n", + getreg32(config->base + SAM_MCAN_TOCC_OFFSET), + getreg32(config->base + SAM_MCAN_TOCV_OFFSET), + getreg32(config->base + SAM_MCAN_ECR_OFFSET), + getreg32(config->base + SAM_MCAN_PSR_OFFSET)); + + lldbg(" IR: %08x IE: %08x ILS: %08x ILE: %08x\n", + getreg32(config->base + SAM_MCAN_IR_OFFSET), + getreg32(config->base + SAM_MCAN_IE_OFFSET), + getreg32(config->base + SAM_MCAN_ILS_OFFSET), + getreg32(config->base + SAM_MCAN_ILE_OFFSET)); + + lldbg(" GFC: %08x SIDFC: %08x XIDFC: %08x XIDAM: %08x\n", + getreg32(config->base + SAM_MCAN_GFC_OFFSET), + getreg32(config->base + SAM_MCAN_SIDFC_OFFSET), + getreg32(config->base + SAM_MCAN_XIDFC_OFFSET), + getreg32(config->base + SAM_MCAN_XIDAM_OFFSET)); + + lldbg(" HPMS: %08x NDAT1: %08x NDAT2: %08x RXF0C: %08x\n", + getreg32(config->base + SAM_MCAN_HPMS_OFFSET), + getreg32(config->base + SAM_MCAN_NDAT1_OFFSET), + getreg32(config->base + SAM_MCAN_NDAT2_OFFSET), + getreg32(config->base + SAM_MCAN_RXF0C_OFFSET)); + + lldbg(" RXF0S: %08x FXF0A: %08x RXBC: %08x RXF1C: %08x\n", + getreg32(config->base + SAM_MCAN_RXF0S_OFFSET), + getreg32(config->base + SAM_MCAN_RXF0A_OFFSET), + getreg32(config->base + SAM_MCAN_RXBC_OFFSET), + getreg32(config->base + SAM_MCAN_RXF1C_OFFSET)); + + lldbg(" RXF1S: %08x FXF1A: %08x RXESC: %08x TXBC: %08x\n", + getreg32(config->base + SAM_MCAN_RXF1S_OFFSET), + getreg32(config->base + SAM_MCAN_RXF1A_OFFSET), + getreg32(config->base + SAM_MCAN_RXESC_OFFSET), + getreg32(config->base + SAM_MCAN_TXBC_OFFSET)); + + lldbg(" TXFQS: %08x TXESC: %08x TXBRP: %08x TXBAR: %08x\n", + getreg32(config->base + SAM_MCAN_TXFQS_OFFSET), + getreg32(config->base + SAM_MCAN_TXESC_OFFSET), + getreg32(config->base + SAM_MCAN_TXBRP_OFFSET), + getreg32(config->base + SAM_MCAN_TXBAR_OFFSET)); + + lldbg(" TXBCR: %08x TXBTO: %08x TXBCF: %08x TXBTIE: %08x\n", + getreg32(config->base + SAM_MCAN_TXBCR_OFFSET), + getreg32(config->base + SAM_MCAN_TXBTO_OFFSET), + getreg32(config->base + SAM_MCAN_TXBCF_OFFSET), + getreg32(config->base + SAM_MCAN_TXBTIE_OFFSET)); + + lldbg("TXBCIE: %08x TXEFC: %08x TXEFS: %08x TXEFA: %08x\n", + getreg32(config->base + SAM_MCAN_TXBCIE_OFFSET), + getreg32(config->base + SAM_MCAN_TXEFC_OFFSET), + getreg32(config->base + SAM_MCAN_TXEFS_OFFSET), + getreg32(config->base + SAM_MCAN_TXEFA_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: mcan_dev_lock + * + * Description: + * Take the semaphore that enforces mutually exclusive access to device + * structures, handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_dev_lock(FAR struct sam_mcan_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->locksem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: mcan_buffer_reserve + * + * Description: + * Take the semaphore, decrementing the semaphore count to indicate that + * one fewer TX FIFOQ buffer is available. Handles any exceptional + * conditions. + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * + * Returned Value: + * None + * + * Assumptions: + * Called only non-interrupt logic via mcan_write(). We do not have + * exclusive access to the MCAN hardware and interrupts are not disabled. + * mcan_write() does lock the scheduler for reasons noted below. + * + ****************************************************************************/ + +static void mcan_buffer_reserve(FAR struct sam_mcan_s *priv) +{ + irqstate_t flags; + uint32_t txfqs1; + uint32_t txfqs2; +#ifndef CONFIG_SAMV7_MCAN_QUEUE_MODE + int tffl; +#endif + int sval; + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + /* We take some extra precautions here because it is possible that on + * certain error conditions, the semaphore count could get out of + * phase with the actual count of elements in the TX FIFO (I have + * never seen this happen, however. My paranoia). + * + * An missed TX interrupt could cause the semaphore count to fail to + * be incremented and, hence, to be too low. + */ + + for (; ; ) + { + /* Get the current queue status and semaphore count. */ + + flags = enter_critical_section(); + txfqs1 = mcan_getreg(priv, SAM_MCAN_TXFQS_OFFSET); + (void)sem_getvalue(&priv->txfsem, &sval); + txfqs2 = mcan_getreg(priv, SAM_MCAN_TXFQS_OFFSET); + + /* If the semaphore count and the TXFQS samples are in + * sync, then break out of the look with interrupts + * disabled. + */ + + if (txfqs1 == txfqs2) + { + break; + } + + /* Otherwise, re-enable interrupts to interrupts that may + * resynchronize, the semaphore count and try again. + */ + + leave_critical_section(flags); + } + +#ifdef CONFIG_SAMV7_MCAN_QUEUE_MODE + /* We only have one useful bit of information in the TXFQS: + * Is the TX FIFOQ full or not? We can only do limited checks + * with that single bit of information. + */ + + if ((txfqs1 & MCAN_TXFQS_TFQF) != 0) + { + /* The TX FIFOQ is full. The semaphore count should then be + * less than or equal to zero. If it is greater than zero, + * then reinitialize it to 0. + */ + + if (sval > 0) + { + candbg("ERROR: TX FIFOQ full but txfsem is %d\n", sval); + sem_reset(&priv->txfsem, 0); + } + } + + /* The FIFO is not full so the semaphore count should be greater + * than zero. If it is not, then we have missed a call to + * mcan_buffer_release(0). + * + * NOTE: Since there is no mutual exclusion, it might be possible + * that mcan_write() could be re-entered AFTER taking the semaphore + * and dropping the count to zero, but BEFORE adding the message + * to the TX FIFOQ. That corner case is handled in mcan_write() by + * locking the scheduler. + */ + + else if (sval <= 0) + { + candbg("ERROR: TX FIFOQ not full but txfsem is %d\n", sval); + + /* Less than zero means that another thread is waiting */ + + if (sval < 0) + { + /* Bump up the count by one and try again */ + + sem_post(&priv->txfsem); + leave_critical_section(flags); + continue; + } + + /* Exactly zero but the FIFO is not full. Just return without + * decrementing the count. + */ + + leave_critical_section(flags); + return; + } +#else + /* Tx FIFO Free Level */ + + tffl = (txfqs1 & MCAN_TXFQS_TFFL_MASK) >> MCAN_TXFQS_TFFL_SHIFT; + + /* Check if the configured number is less than the number of buffers + * in the chip + */ + + if (tffl > priv->config->ntxfifoq) + { + candbg("ERROR: TX FIFO reports %d but max is %d\n", + tffl, priv->config->ntxfifoq); + tffl = priv->config->ntxfifoq; + } + + /* REVISIT: There may be issues with this logic in a multi-thread + * environment. If there is only a single thread, then certainly + * sval and tff1 should match, but that may not be true in any multi- + * threaded use of this driver. + */ + + if (sval != tffl) + { + candbg("ERROR: TX FIFO reports %d but txfsem is %d\n", tffl, sval); + + /* Reset the semaphore count to the Tx FIFO free level. */ + + sem_reset(&priv->txfsem, tffl); + } +#endif + + /* The semaphore value is reasonable. Wait for the next TC interrupt. */ + + ret = sem_wait(&priv->txfsem); + leave_critical_section(flags); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: mcan_buffer_release + * + * Description: + * Release the semaphore, increment the semaphore count to indicate that + * one more TX FIFOQ buffer is available. + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * + * Returned Value: + * None + * + * Assumptions: + * This function is called only from the interrupt level in response to the + * complete of a transmission. + * + ****************************************************************************/ + +static void mcan_buffer_release(FAR struct sam_mcan_s *priv) +{ + int sval; + + /* We take some extra precautions here because it is possible that on + * certain error conditions, the semaphore count could get out of phase + * with the actual count of elements in the TX FIFO (I have never seen + * this happen, however. My paranoia). + * + * An extra TC interrupt could cause the count to be incremented too + * many times. + */ + + (void)sem_getvalue(&priv->txfsem, &sval); + if (sval < priv->config->ntxfifoq) + { + sem_post(&priv->txfsem); + } + else + { + candbg("ERROR: txfsem would increment beyond %d\n", + priv->config->ntxfifoq); + } +} + +/**************************************************************************** + * Name: mcan_dlc2bytes + * + * Description: + * In the CAN FD format, the coding of the DLC differs from the standard + * CAN format. The DLC codes 0 to 8 have the same coding as in standard + * CAN. But the codes 9 to 15 all imply a data field of 8 bytes with + * standard CAN. In CAN FD mode, the values 9 to 15 are encoded to values + * in the range 12 to 64. + * + * Input Parameter: + * dlc - the DLC value to convert to a byte count + * + * Returned Value: + * The number of bytes corresponding to the DLC value. + * + ****************************************************************************/ + +static uint8_t mcan_dlc2bytes(FAR struct sam_mcan_s *priv, uint8_t dlc) +{ + if (dlc > 8) + { +#ifdef CONFIG_CAN_FD + if (priv->config->mode == MCAN_ISO11898_1_MODE) + { + return 8; + } + else + { + switch (dlc) + { + case 9: + return 12; + case 10: + return 16; + case 11: + return 20; + case 12: + return 24; + case 13: + return 32; + case 14: + return 48; + default: + case 15: + return 64; + } + } +#else + return 8; +#endif + } + + return dlc; +} + +/**************************************************************************** + * Name: mcan_bytes2dlc + * + * Description: + * In the CAN FD format, the coding of the DLC differs from the standard + * CAN format. The DLC codes 0 to 8 have the same coding as in standard + * CAN. But the codes 9 to 15 all imply a data field of 8 bytes with + * standard CAN. In CAN FD mode, the values 9 to 15 are encoded to values + * in the range 12 to 64. + * + * Input Parameter: + * nbytes - the byte count to convert to a DLC value + * + * Returned Value: + * The encoded DLC value corresponding to at least that number of bytes. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static uint8_t mcan_bytes2dlc(FAR struct sam_mcan_s *priv, uint8_t nbytes) +{ + if (nbytes <= 8) + { + return nbytes; + } +#ifdef CONFIG_CAN_FD + else if (priv->mode == MCAN_ISO11898_1_MODE) + { + return 8; + } + else if (nbytes <= 12) + { + return 9; + } + else if (nbytes <= 16) + { + return 10; + } + else if (nbytes <= 20) + { + return 11; + } + else if (nbytes <= 24) + { + return 12; + } + else if (nbytes <= 32) + { + return 13; + } + else if (nbytes <= 48) + { + return 14; + } + else /* if (nbytes <= 64) */ + { + return 15; + } +#else + else + { + return 8; + } +#endif +} +#endif + +/**************************************************************************** + * Name: mcan_add_extfilter + * + * Description: + * Add an address filter for a extended 29 bit address. + * + * Input Parameters: + * priv - An instance of the MCAN driver state structure. + * extconfig - The configuration of the extended filter + * + * Returned Value: + * A non-negative filter ID is returned on success. Otherwise a negated + * errno value is returned to indicate the nature of the error. + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_EXTID +static int mcan_add_extfilter(FAR struct sam_mcan_s *priv, + FAR struct canioc_extfilter_s *extconfig) +{ + FAR const struct sam_config_s *config; + FAR uint32_t *extfilter; + uint32_t regval; + int word; + int bit; + int ndx; + + DEBUGASSERT(priv != NULL && priv->config != NULL && extconfig != NULL); + config = priv->config; + + /* Get exclusive excess to the MCAN hardware */ + + mcan_dev_lock(priv); + + /* Find an unused standard filter */ + + for (ndx = 0; ndx < config->nextfilters; ndx++) + { + /* Is this filter assigned? */ + + word = ndx >> 5; + bit = ndx & 0x1f; + + if ((priv->extfilters[word] & (1 << bit)) == 0) + { + /* No, assign the filter */ + + DEBUGASSERT(priv->nextalloc < priv->config->nstdfilters); + priv->extfilters[word] |= (1 << bit); + priv->nextalloc++; + + extfilter = config->msgram.extfilters + (ndx << 1); + + /* Format and write filter word F0 */ + + DEBUGASSERT(extconfig->xf_id1 <= CAN_MAX_EXTMSGID); + regval = EXTFILTER_F0_EFID1(extconfig->xf_id1); + + if (extconfig->xf_prio == 0) + { + regval |= EXTFILTER_F0_EFEC_FIFO0; + } + else + { + regval |= EXTFILTER_F0_EFEC_FIFO0; + } + + extfilter[0] = regval; + + /* Format and write filter word F1 */ + + DEBUGASSERT(extconfig->xf_id2 <= CAN_MAX_EXTMSGID); + regval = EXTFILTER_F1_EFID2(extconfig->xf_id2); + + switch (extconfig->xf_type) + { + default: + case CAN_FILTER_DUAL: + regval |= EXTFILTER_F1_EFT_DUAL; + break; + + case CAN_FILTER_MASK: + regval |= EXTFILTER_F1_EFT_CLASSIC; + break; + case CAN_FILTER_RANGE: + regval |= EXTFILTER_F1_EFT_RANGE; + break; + } + + extfilter[1] = regval; + + /* Flush the filter entry into physical RAM */ + + arch_clean_dcache((uintptr_t)extfilter, (uintptr_t)exfilter + 8); + + /* Is this the first extended filter? */ + + if (priv->nextalloc == 1) + { + /* Update the Global Filter Configuration so that received + * messages are rejected if they do not match the acceptance + * filter. + * + * ANFE=2: Discard all rejected frames + */ + + regval = mcan_getreg(priv, SAM_MCAN_GFC_OFFSET); + regval &= ~MCAN_GFC_ANFE_MASK; + regval |= MCAN_GFC_ANFE_REJECTED; + mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval); + } + + mcan_dev_unlock(priv); + return ndx; + } + } + + DEBUGASSERT(priv->nextalloc == priv->config->nextfilters); + mcan_dev_unlock(priv); + return -EAGAIN; +} +#endif + +/**************************************************************************** + * Name: mcan_del_extfilter + * + * Description: + * Remove an address filter for a standard 29 bit address. + * + * Input Parameters: + * priv - An instance of the MCAN driver state structure. + * ndx - The filter index previously returned by the mcan_add_extfilter(). + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the error. + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_EXTID +static int mcan_del_extfilter(FAR struct sam_mcan_s *priv, int ndx) +{ + FAR const struct sam_config_s *config; + FAR uint32_t *extfilter; + uint32_t regval; + int word; + int bit; + + DEBUGASSERT(priv != NULL && priv->config != NULL); + config = priv->config; + DEBUGASSERT(ndx < config->nextfilters); + + /* Get exclusive excess to the MCAN hardware */ + + mcan_dev_lock(priv); + + /* Release the filter */ + + word = ndx >> 5; + bit = ndx & 0x1f; + priv->extfilters[word] &= ~(1 << bit); + + DEBUGASSERT(priv->nextalloc > 0); + priv->nextalloc--; + + /* Was that the last extended filter? */ + + if (priv->nextalloc == 0) + { + /* If there are no extended filters, then modify Global Filter + * Configuration so that all rejected messages are places in RX + * FIFO0. + * + * ANFE=0: Store all rejected extended frame in RX FIFO0 + */ + + regval = mcan_getreg(priv, SAM_MCAN_GFC_OFFSET); + regval &= ~MCAN_GFC_ANFE_MASK; + regval |= MCAN_GFC_ANFE_RX_FIFO0; + mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval); + } + + /* Deactivate the filter last so that no messages are lost. */ + + extfilter = config->msgram.extfilters + (ndx << 1); + *extfilter++ = 0; + *extfilter = 0; + + mcan_dev_unlock(priv); + return OK; +} +#endif + +/**************************************************************************** + * Name: mcan_add_stdfilter + * + * Description: + * Add an address filter for a standard 11 bit address. + * + * Input Parameters: + * priv - An instance of the MCAN driver state structure. + * stdconfig - The configuration of the standard filter + * + * Returned Value: + * A non-negative filter ID is returned on success. Otherwise a negated + * errno value is returned to indicate the nature of the error. + * + ****************************************************************************/ + +static int mcan_add_stdfilter(FAR struct sam_mcan_s *priv, + FAR struct canioc_stdfilter_s *stdconfig) +{ + FAR const struct sam_config_s *config; + FAR uint32_t *stdfilter; + uint32_t regval; + int word; + int bit; + int ndx; + + DEBUGASSERT(priv != NULL && priv->config != NULL); + config = priv->config; + + /* Get exclusive excess to the MCAN hardware */ + + mcan_dev_lock(priv); + + /* Find an unused standard filter */ + + for (ndx = 0; ndx < config->nstdfilters; ndx++) + { + /* Is this filter assigned? */ + + word = ndx >> 5; + bit = ndx & 0x1f; + + if ((priv->stdfilters[word] & (1 << bit)) == 0) + { + /* No, assign the filter */ + + DEBUGASSERT(priv->nstdalloc < priv->config->nstdfilters); + priv->stdfilters[word] |= (1 << bit); + priv->nstdalloc++; + + /* Format and write filter word S0 */ + + stdfilter = config->msgram.stdfilters + ndx; + + DEBUGASSERT(stdconfig->sf_id1 <= CAN_MAX_STDMSGID); + regval = STDFILTER_S0_SFID1(stdconfig->sf_id1); + + DEBUGASSERT(stdconfig->sf_id2 <= CAN_MAX_STDMSGID); + regval |= STDFILTER_S0_SFID2(stdconfig->sf_id2); + + if (stdconfig->sf_prio == 0) + { + regval |= STDFILTER_S0_SFEC_FIFO0; + } + else + { + regval |= STDFILTER_S0_SFEC_FIFO1; + } + + switch (stdconfig->sf_type) + { + default: + case CAN_FILTER_DUAL: + regval |= STDFILTER_S0_SFT_DUAL; + break; + + case CAN_FILTER_MASK: + regval |= STDFILTER_S0_SFT_CLASSIC; + break; + case CAN_FILTER_RANGE: + regval |= STDFILTER_S0_SFT_RANGE; + break; + } + + *stdfilter = regval; + + /* Flush the filter entry into physical RAM */ + + arch_clean_dcache((uintptr_t)stdfilter, (uintptr_t)stdfilter + 4); + + /* Is this the first standard filter? */ + + if (priv->nstdalloc == 1) + { + /* Update the Global Filter Configuration so that received + * messages are rejected if they do not match the acceptance + * filter. + * + * ANFS=2: Discard all rejected frames + */ + + regval = mcan_getreg(priv, SAM_MCAN_GFC_OFFSET); + regval &= ~MCAN_GFC_ANFS_MASK; + regval |= MCAN_GFC_ANFS_REJECTED; + mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval); + } + + mcan_dev_unlock(priv); + return ndx; + } + } + + DEBUGASSERT(priv->nstdalloc == priv->config->nstdfilters); + mcan_dev_unlock(priv); + return -EAGAIN; +} + +/**************************************************************************** + * Name: mcan_del_stdfilter + * + * Description: + * Remove an address filter for a standard 29 bit address. + * + * Input Parameters: + * priv - An instance of the MCAN driver state structure. + * ndx - The filter index previously returned by the mcan_add_stdfilter(). + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the error. + * + ****************************************************************************/ + +static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx) +{ + FAR const struct sam_config_s *config; + FAR uint32_t *stdfilter; + uint32_t regval; + int word; + int bit; + + DEBUGASSERT(priv != NULL && priv->config != NULL); + config = priv->config; + DEBUGASSERT(ndx < config->nstdfilters); + + /* Get exclusive excess to the MCAN hardware */ + + mcan_dev_lock(priv); + + /* Release the filter */ + + word = ndx >> 5; + bit = ndx & 0x1f; + priv->stdfilters[word] &= ~(1 << bit); + + DEBUGASSERT(priv->nstdalloc > 0); + priv->nstdalloc--; + + /* Was that the last standard filter? */ + + if (priv->nstdalloc == 0) + { + /* If there are no standard filters, then modify Global Filter + * Configuration so that all rejected messages are places in RX + * FIFO0. + * + * ANFS=0: Store all rejected extended frame in RX FIFO0 + */ + + regval = mcan_getreg(priv, SAM_MCAN_GFC_OFFSET); + regval &= ~MCAN_GFC_ANFS_MASK; + regval |= MCAN_GFC_ANFS_RX_FIFO0; + mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval); + } + + /* Deactivate the filter last so that no messages are lost. */ + + stdfilter = config->msgram.stdfilters + ndx; + *stdfilter = 0; + + mcan_dev_unlock(priv); + return OK; +} + +/**************************************************************************** + * Name: mcan_reset + * + * Description: + * Reset the MCAN device. Called early to initialize the hardware. This + * function is called, before mcan_setup() and on error conditions. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_reset(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv; + FAR const struct sam_config_s *config; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("MCAN%d\n", config->port); + UNUSED(config); + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + + /* Disable all interrupts */ + + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, 0); + mcan_putreg(priv, SAM_MCAN_TXBTIE_OFFSET, 0); + + /* Make sure that all buffers are released. + * + * REVISIT: What if a thread is waiting for a buffer? The following + * will not wake up any waiting threads. + */ + + sem_destroy(&priv->txfsem); + sem_init(&priv->txfsem, 0, config->ntxfifoq); + + /* Disable peripheral clocking to the MCAN controller */ + + sam_disableperiph1(priv->config->pid); + priv->state = MCAN_STATE_RESET; + mcan_dev_unlock(priv); +} + +/**************************************************************************** + * Name: mcan_setup + * + * Description: + * Configure the MCAN. This method is called the first time that the MCAN + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching MCAN interrupts. + * All MCAN interrupts are disabled upon return. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int mcan_setup(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv; + FAR const struct sam_config_s *config; + int ret; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("MCAN%d pid: %d\n", config->port, config->pid); + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + + /* MCAN hardware initialization */ + + ret = mcan_hw_initialize(priv); + if (ret < 0) + { + canlldbg("MCAN%d H/W initialization failed: %d\n", config->port, ret); + return ret; + } + + mcan_dumpregs(priv, "After hardware initialization"); + + /* Attach the MCAN interrupt handlers */ + + ret = irq_attach(config->irq0, config->handler); + if (ret < 0) + { + canlldbg("Failed to attach MCAN%d line 0 IRQ (%d)", + config->port, config->irq0); + return ret; + } + + ret = irq_attach(config->irq1, config->handler); + if (ret < 0) + { + canlldbg("Failed to attach MCAN%d line 1 IRQ (%d)", + config->port, config->irq1); + return ret; + } + + /* Enable receive interrupts */ + + priv->state = MCAN_STATE_SETUP; + mcan_rxint(dev, true); + + mcan_dumpregs(priv, "After receive setup"); + + /* Enable the interrupts at the NVIC (they are still disabled at the MCAN + * peripheral). */ + + up_enable_irq(config->irq0); + up_enable_irq(config->irq1); + mcan_dev_unlock(priv); + return OK; +} + +/**************************************************************************** + * Name: mcan_shutdown + * + * Description: + * Disable the MCAN. This method is called when the MCAN device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_shutdown(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv; + FAR const struct sam_config_s *config; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv); + config = priv->config; + DEBUGASSERT(config); + + canllvdbg("MCAN%d\n", config->port); + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + + /* Disable MCAN interrupts at the NVIC */ + + up_disable_irq(config->irq0); + up_disable_irq(config->irq1); + + /* Disable all interrupts from the MCAN peripheral */ + + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, 0); + mcan_putreg(priv, SAM_MCAN_TXBTIE_OFFSET, 0); + + /* Detach the MCAN interrupt handler */ + + irq_detach(config->irq0); + irq_detach(config->irq1); + + /* Disable peripheral clocking to the MCAN controller */ + + sam_disableperiph1(priv->config->pid); + mcan_dev_unlock(priv); +} + +/**************************************************************************** + * Name: mcan_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_rxint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(priv && priv->config); + + canllvdbg("MCAN%d enable: %d\n", priv->config->port, enable); + + /* Enable/disable the receive interrupts */ + + flags = enter_critical_section(); + regval = mcan_getreg(priv, SAM_MCAN_IE_OFFSET); + + if (enable) + { + regval |= priv->rxints | MCAN_COMMON_INTS; + } + else + { + regval &= ~priv->rxints; + } + + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: mcan_txint + * + * Description: + * Call to enable or disable TX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_txint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(priv && priv->config); + + canllvdbg("MCAN%d enable: %d\n", priv->config->port, enable); + + /* Enable/disable the receive interrupts */ + + flags = enter_critical_section(); + regval = mcan_getreg(priv, SAM_MCAN_IE_OFFSET); + + if (enable) + { + regval |= priv->txints | MCAN_COMMON_INTS; + } + else + { + regval &= ~priv->txints; + } + + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: mcan_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct sam_mcan_s *priv; + int ret = -ENOTTY; + + canvdbg("cmd=%04x arg=%lu\n", cmd, arg); + + DEBUGASSERT(dev && dev->cd_priv); + priv = dev->cd_priv; + + /* Handle the command */ + + switch (cmd) + { + /* CANIOC_GET_BITTIMING: + * Description: Return the current bit timing settings + * Argument: A pointer to a write-able instance of struct + * canioc_bittiming_s in which current bit timing values + * will be returned. + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + */ + + case CANIOC_GET_BITTIMING: + { + FAR struct canioc_bittiming_s *bt = + (FAR struct canioc_bittiming_s *)arg; + uint32_t regval; + uint32_t brp; + + DEBUGASSERT(bt != NULL); + + regval = mcan_getreg(priv, SAM_MCAN_BTP_OFFSET); + bt->bt_sjw = ((regval & MCAN_BTP_SJW_MASK) >> MCAN_BTP_SJW_SHIFT) + 1; + bt->bt_tseg1 = ((regval & MCAN_BTP_TSEG1_MASK) >> MCAN_BTP_TSEG1_SHIFT) + 1; + bt->bt_tseg2 = ((regval & MCAN_BTP_TSEG2_MASK) >> MCAN_BTP_TSEG2_SHIFT) + 1; + + brp = ((regval & MCAN_BTP_BRP_MASK) >> MCAN_BTP_BRP_SHIFT) + 1; + bt->bt_baud = SAMV7_MCANCLK_FREQUENCY / brp / + (bt->bt_tseg1 + bt->bt_tseg2 + 1); + ret = OK; + } + break; + + /* CANIOC_SET_BITTIMING: + * Description: Set new current bit timing values + * Argument: A pointer to a read-able instance of struct + * canioc_bittiming_s in which the new bit timing values + * are provided. + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + * + * REVISIT: There is probably a limitation here: If there are multiple + * threads trying to send CAN packets, when one of these threads reconfigures + * the bitrate, the MCAN hardware will be reset and the context of operation + * will be lost. Hence, this IOCTL can only safely be executed in quiescent + * time periods. + */ + + case CANIOC_SET_BITTIMING: + { + FAR const struct canioc_bittiming_s *bt = + (FAR const struct canioc_bittiming_s *)arg; + irqstate_t flags; + uint32_t brp; + uint32_t tseg1; + uint32_t tseg2; + uint32_t sjw; + uint32_t ie; + uint8_t state; + + DEBUGASSERT(bt != NULL); + DEBUGASSERT(bt->bt_baud < SAMV7_MCANCLK_FREQUENCY); + DEBUGASSERT(bt->bt_sjw > 0 && bt->bt_sjw <= 16); + DEBUGASSERT(bt->bt_tseg1 > 1 && bt->bt_tseg1 <= 64); + DEBUGASSERT(bt->bt_tseg2 > 0 && bt->bt_tseg2 <= 16); + + /* Extract bit timing data */ + + tseg1 = bt->bt_tseg1 - 1; + tseg2 = bt->bt_tseg2 - 1; + sjw = bt->bt_sjw - 1; + + brp = (uint32_t) + (((float) SAMV7_MCANCLK_FREQUENCY / + ((float)(tseg1 + tseg2 + 3) * (float)bt->bt_baud)) - 1); + + /* Save the value of the new bit timing register */ + + flags = enter_critical_section(); + priv->btp = MCAN_BTP_BRP(brp) | MCAN_BTP_TSEG1(tseg1) | + MCAN_BTP_TSEG2(tseg2) | MCAN_BTP_SJW(sjw); + + /* We need to reset to instantiate the new timing. Save + * current state information so that recover to this + * state. + */ + + ie = mcan_getreg(priv, SAM_MCAN_IE_OFFSET); + state = priv->state; + + /* Reset the MCAN */ + + mcan_reset(dev); + ret = OK; + + /* If we have previously been setup, then setup again */ + + if (state == MCAN_STATE_SETUP) + { + ret = mcan_setup(dev); + } + + /* We we have successfully re-initialized, then restore the + * interrupt state. + * + * REVISIT: Since the hardware was reset, any pending TX + * activity was lost. Should we disable TX interrupts? + */ + + if (ret == OK) + { + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie & ~priv->txints); + } + + leave_critical_section(flags); + } + break; + +#ifdef CONFIG_CAN_EXTID + /* CANIOC_ADD_EXTFILTER: + * Description: Add an address filter for a extended 29 bit + * address. + * Argument: A reference to struct canioc_extfilter_s + * Returned Value: A non-negative filter ID is returned on success. + * Otherwise -1 (ERROR) is returned with the errno + * variable set to indicate the nature of the error. + */ + + case CANIOC_ADD_EXTFILTER: + { + DEBUGASSERT(arg != 0); + ret = mcan_add_extfilter(priv, (FAR struct canioc_extfilter_s *)arg); + } + break; + + /* CANIOC_DEL_EXTFILTER: + * Description: Remove an address filter for a standard 29 bit address. + * Argument: The filter index previously returned by the + * CANIOC_ADD_EXTFILTER command + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + */ + + case CANIOC_DEL_EXTFILTER: + { + DEBUGASSERT(arg <= priv->config->nextfilters); + ret = mcan_del_extfilter(priv, (int)arg); + } + break; +#endif + + /* CANIOC_ADD_STDFILTER: + * Description: Add an address filter for a standard 11 bit + * address. + * Argument: A reference to struct canioc_stdfilter_s + * Returned Value: A non-negative filter ID is returned on success. + * Otherwise -1 (ERROR) is returned with the errno + * variable set to indicate the nature of the error. + */ + + case CANIOC_ADD_STDFILTER: + { + DEBUGASSERT(arg != 0); + ret = mcan_add_stdfilter(priv, (FAR struct canioc_stdfilter_s *)arg); + } + break; + + /* CANIOC_DEL_STDFILTER: + * Description: Remove an address filter for a standard 11 bit address. + * Argument: The filter index previously returned by the + * CANIOC_ADD_STDFILTER command + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + */ + + case CANIOC_DEL_STDFILTER: + { + DEBUGASSERT(arg <= priv->config->nstdfilters); + ret = mcan_del_stdfilter(priv, (int)arg); + } + break; + + /* Unsupported/unrecognized command */ + + default: + candbg("ERROR: Unrecognized command: %04x\n", cmd); + break; + } + + /* No CAN ioctls are supported */ + + return ret; +} + +/**************************************************************************** + * Name: mcan_remoterequest + * + * Description: + * Send a remote request + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int mcan_remoterequest(FAR struct can_dev_s *dev, uint16_t id) +{ + /* REVISIT: Remote request not implemented */ + + return -ENOSYS; +} + +/**************************************************************************** + * Name: mcan_send + * + * Description: + * Send one can message. + * + * One CAN-message consists of a maximum of 10 bytes. A message is + * composed of at least the first 2 bytes (when there are no data bytes). + * + * Byte 0: Bits 0-7: Bits 3-10 of the 11-bit CAN identifier + * Byte 1: Bits 5-7: Bits 0-2 of the 11-bit CAN identifier + * Bit 4: Remote Transmission Request (RTR) + * Bits 0-3: Data Length Code (DLC) + * Bytes 2-10: CAN data + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int mcan_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) +{ + FAR struct sam_mcan_s *priv; + FAR const struct sam_config_s *config; + FAR uint32_t *txbuffer = 0; + FAR const uint8_t *src; + FAR uint8_t *dest; + uint32_t regval; + unsigned int msglen; + unsigned int ndx; + unsigned int nbytes; + unsigned int i; + + DEBUGASSERT(dev); + priv = dev->cd_priv; + DEBUGASSERT(priv && priv->config); + config = priv->config; + + canllvdbg("MCAN%d\n", config->port); + canllvdbg("MCAN%d ID: %d DLC: %d\n", + config->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc); + + /* That that FIFO elements were configured. + * + * REVISIT: Dedicated TX buffers are not used by this driver. + */ + + DEBUGASSERT(config->ntxfifoq > 0); + + /* Reserve a buffer for the transmission, waiting if necessary. When + * mcan_buffer_reserve() returns, we are guaranteed that the TX FIFOQ is + * not full and cannot become full at least until we add our packet to + * the FIFO. + * + * We can't get exclusive access to MCAN resources here because that + * lock the MCAN while we wait for a free buffer. Instead, the + * scheduler is locked here momentarily. See discussion in + * mcan_buffer_reserve() for an explanation. + * + * REVISIT: This needs to be extended in order to handler case where + * the MCAN device was opened O_NONBLOCK. + */ + + sched_lock(); + mcan_buffer_reserve(priv); + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + sched_unlock(); + + /* Get our reserved Tx FIFO/queue put index */ + + regval = mcan_getreg(priv, SAM_MCAN_TXFQS_OFFSET); + DEBUGASSERT((regval & MCAN_TXFQS_TFQF) == 0); + + ndx = (regval & MCAN_TXFQS_TFQPI_MASK) >> MCAN_TXFQS_TFQPI_SHIFT; + + /* And the TX buffer corresponding to this index */ + + txbuffer = config->msgram.txdedicated + ndx * config->txbufferesize; + + /* Format the TX FIFOQ entry + * + * Format word T1: + * Transfer message ID (ID) - Value from message structure + * Remote Transmission Request (RTR) - Value from message structure + * Extended Identifier (XTD) - Depends on configuration. + */ + +#ifdef CONFIG_CAN_EXTID + if (msg->cm_hdr.ch_extid) + { + DEBUGASSERT(msg->cm_hdr.ch_id <= CAN_MAX_EXTMSGID); + + regval = BUFFER_R0_EXTID(msg->cm_hdr.ch_id) | BUFFER_R0_XTD; + } + else +#endif + { + DEBUGASSERT(msg->cm_hdr.ch_id <= CAN_MAX_STDMSGID); + + regval = BUFFER_R0_STDID(msg->cm_hdr.ch_id); + } + + if (msg->cm_hdr.ch_rtr) + { + regval |= BUFFER_R0_RTR; + } + + txbuffer[0] = regval; + canregdbg("T0: %08x\n", regval); + + /* Format word T1: + * Data Length Code (DLC) - Value from message structure + * Event FIFO Control (EFC) - Do not store events. + * Message Marker (MM) - Always zero + */ + + txbuffer[1] = BUFFER_R1_DLC(msg->cm_hdr.ch_dlc); + canregdbg("T1: %08x\n", txbuffer[1]); + + /* Followed by the amount of data corresponding to the DLC (T2..) */ + + dest = (FAR uint8_t *)&txbuffer[2]; + src = msg->cm_data; + nbytes = mcan_dlc2bytes(priv, msg->cm_hdr.ch_dlc); + + for (i = 0; i < nbytes; i++) + { + /* Little endian is assumed */ + + *dest++ = *src++; + } + + /* Flush the D-Cache to memory before initiating the transfer */ + + msglen = 2 * sizeof(uint32_t) + nbytes; + arch_clean_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + msglen); + UNUSED(msglen); + + /* Enable transmit interrupts from the TX FIFOQ buffer by setting TC + * interrupt bit in IR (also requires that the TC interrupt is enabled) + */ + + mcan_putreg(priv, SAM_MCAN_TXBTIE_OFFSET, (1 << ndx)); + + /* And request to send the packet */ + + mcan_putreg(priv, SAM_MCAN_TXBAR_OFFSET, (1 << ndx)); + mcan_dev_unlock(priv); + + /* Report that the TX transfer is complete to the upper half logic. Of + * course, the transfer is not complete, but this early notification + * allows the upper half logic to free resources sooner. + * + * REVISIT: Should we disable interrupts? can_txdone() was designed to + * be called from an interrupt handler and, hence, may be unsafe when + * called from the tasking level. + */ + + (void)can_txdone(dev); + return OK; +} + +/**************************************************************************** + * Name: mcan_txready + * + * Description: + * Return true if the MCAN hardware can accept another TX message. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if the MCAN hardware is ready to accept another TX message. + * + ****************************************************************************/ + +static bool mcan_txready(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + uint32_t regval; + bool notfull; +#ifdef CONFIG_DEBUG + int sval; +#endif + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + + /* Return the state of the TX FIFOQ. Return TRUE if the TX FIFO/Queue is + * not full. + * + * REVISIT: Dedicated TX buffers are not supported. + */ + + regval = mcan_getreg(priv, SAM_MCAN_TXFQS_OFFSET); + notfull = ((regval & MCAN_TXFQS_TFQF) == 0); + +#ifdef CONFIG_DEBUG + /* As a sanity check, the txfsem should also track the number of elements + * the TX FIFO/queue. Make sure that they are consistent. + */ + + (void)sem_getvalue(&priv->txfsem, &sval); + DEBUGASSERT(((notfull && sval > 0) || (!notfull && sval <= 0)) && + (sval <= priv->config->ntxfifoq)); +#endif + + mcan_dev_unlock(priv); + return notfull; +} + +/**************************************************************************** + * Name: mcan_txempty + * + * Description: + * Return true if all message have been sent. If for example, the MCAN + * hardware implements FIFOs, then this would mean the transmit FIFO is + * empty. This method is called when the driver needs to make sure that + * all characters are "drained" from the TX hardware before calling + * co_shutdown(). + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if there are no pending TX transfers in the MCAN hardware. + * + ****************************************************************************/ + +static bool mcan_txempty(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + uint32_t regval; +#ifdef CONFIG_SAMV7_MCAN_QUEUE_MODE + int sval; +#else + int tffl; +#endif + bool empty; + + DEBUGASSERT(priv != NULL && priv->config != NULL); + + /* Get exclusive access to the MCAN peripheral */ + + mcan_dev_lock(priv); + + /* Return the state of the TX FIFOQ. Return TRUE if the TX FIFO/Queue is + * empty. We don't have a reliable indication that the FIFO is empty, so + * we have to use some heuristics. + * + * REVISIT: Dedicated TX buffers are not supported. + */ + + regval = mcan_getreg(priv, SAM_MCAN_TXFQS_OFFSET); + if (((regval & MCAN_TXFQS_TFQF) != 0)) + { + return false; + } + +#ifdef CONFIG_SAMV7_MCAN_QUEUE_MODE + /* The TX FIFO/Queue is not full, but is it empty? The txfsem should + * track the number of elements the TX FIFO/queue in use. + * + * Since the FIFO is not full, the semaphore count should be greater + * than zero. If it is equal to the full count of TX FIFO/Queue + * elements, then there is no transfer in progress. + */ + + (void)sem_getvalue(&priv->txfsem, &sval); + DEBUGASSERT(sval > 0 && sval <= priv->config->ntxfifoq); + + empty = (sval == priv->config->ntxfifoq); +#else + /* Tx FIFO Free Level */ + + tffl = (regval & MCAN_TXFQS_TFFL_MASK) >> MCAN_TXFQS_TFFL_SHIFT; + empty = (tffl >= priv->config->ntxfifoq); +#endif + + mcan_dev_unlock(priv); + return empty; +} + +/**************************************************************************** + * Name: mcan_dedicated_rxbuffer_available + * + * Description: + * Check if data is available in a dedicated RX buffer. + * + * Input Parameters: + * priv - MCAN-specific private data + * bufndx - Buffer index + * + * None + * Returned Value: + * True: Data is available + * + ****************************************************************************/ + +#if 0 /* Not Used */ +bool mcan_dedicated_rxbuffer_available(FAR struct sam_mcan_s *priv, int bufndx) +{ + if (bufndx < 32) + { + return (bool)(mcan->MCAN_NDAT1 & (1 << bufndx)); + } + else if (bufndx < 64) + { + return (bool)(mcan->MCAN_NDAT1 & (1 << (bufndx - 32))); + } + else + { + return false; + } +} +#endif + +/**************************************************************************** + * Name: mcan_error + * + * Description: + * Report a CAN error + * + * Input Parameters: + * dev - CAN-common state data + * status - Interrupt status with error bits set + * oldstatus - Previous Interrupt status with error bits set + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_ERRORS +static void mcan_error(FAR struct can_dev_s *dev, uint32_t status, + uint32_t oldstatus) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + struct can_hdr_s hdr; + uint32_t psr; + uint16_t errbits; + uint8_t data[CAN_ERROR_DLC]; + int ret; + + /* Encode error bits */ + + errbits = 0; + memset(data, 0, sizeof(data)); + + /* Always fill in "static" error conditions, but set the signaling bit + * only if the condition has changed (see IRQ-Flags below) + * They have to be filled in every time CAN_ERROR_CONTROLLER is set. + */ + + psr = mcan_getreg(priv, SAM_MCAN_PSR_OFFSET); + if (psr & MCAN_PSR_BO) + { + errbits |= CAN_ERROR_BUSOFF; + } + + if (psr & MCAN_PSR_EP) + { + data[1] |= (CAN_ERROR1_RXPASSIVE | CAN_ERROR1_TXPASSIVE); + } + + if (psr & MCAN_PSR_EW) + { + data[1] |= (CAN_ERROR1_RXWARNING | CAN_ERROR1_TXWARNING); + } + + if ((status & (MCAN_INT_EP | MCAN_INT_EW)) != 0) + { + /* "Error Passive" or "Error Warning" status changed */ + + errbits |= CAN_ERROR_CONTROLLER; + } + + if ((status & MCAN_INT_BO) != 0) + { + /* Bus_Off Status changed */ + + if (!(psr & MCAN_PSR_BO)) + { + errbits |= CAN_ERROR_RESTARTED; + } + } + + if ((status & (MCAN_INT_RF0L | MCAN_INT_RF1L)) != 0) + { + /* Receive FIFO 0 Message Lost */ + /* Receive FIFO 1 Message Lost */ + + errbits |= CAN_ERROR_CONTROLLER; + data[1] |= CAN_ERROR1_RXOVERFLOW; + } + else if ((oldstatus & (MCAN_INT_RF0L | MCAN_INT_RF1L)) != 0) + { + errbits |= CAN_ERROR_CONTROLLER; + } + + if ((status & MCAN_INT_TEFL) != 0) + { + /* Tx Event FIFO Element Lost */ + + errbits |= CAN_ERROR_CONTROLLER; + data[1] |= CAN_ERROR1_TXOVERFLOW; + } + else if ((oldstatus & MCAN_INT_TEFL) != 0) + { + errbits |= CAN_ERROR_CONTROLLER; + } + + if ((status & MCAN_INT_TOO) != 0) + { + /* Timeout Occurred */ + + errbits |= CAN_ERROR_TXTIMEOUT; + } + + if ((status & (MCAN_INT_MRAF | MCAN_INT_ELO)) != 0) + { + /* Message RAM Access Failure */ + /* Error Logging Overflow */ + + errbits |= CAN_ERROR_CONTROLLER; + data[1] |= CAN_ERROR1_UNSPEC; + } + else if ((oldstatus & (MCAN_INT_MRAF | MCAN_INT_ELO)) != 0) + { + errbits |= CAN_ERROR_CONTROLLER; + } + + if ((status & MCAN_INT_CRCE) != 0) + { + /* Receive CRC Error */ + + errbits |= CAN_ERROR_PROTOCOL; + data[3] |= (CAN_ERROR3_CRCSEQ | CAN_ERROR3_CRCDEL); + } + else if ((oldstatus & MCAN_INT_CRCE) != 0) + { + errbits |= CAN_ERROR_PROTOCOL; + } + + if ((status & MCAN_INT_BE) != 0) + { + /* Bit Error */ + + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_BIT; + } + else if ((oldstatus & MCAN_INT_BE) != 0) + { + errbits |= CAN_ERROR_PROTOCOL; + } + + if ((status & MCAN_INT_ACKE) != 0) + { + /* Acknowledge Error */ + + errbits |= CAN_ERROR_NOACK; + } + + if ((status & MCAN_INT_FOE) != 0) + { + /* Format Error */ + + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_FORM; + } + else if ((oldstatus & MCAN_INT_FOE) != 0) + { + errbits |= CAN_ERROR_PROTOCOL; + } + + if ((status & MCAN_INT_STE) != 0) + { + /* Stuff Error */ + + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_STUFF; + } + else if ((oldstatus & MCAN_INT_STE) != 0) + { + errbits |= CAN_ERROR_PROTOCOL; + } + + if (errbits != 0) + { + /* Format the CAN header for the error report. */ + + hdr.ch_id = errbits; + hdr.ch_dlc = CAN_ERROR_DLC; + hdr.ch_rtr = 0; + hdr.ch_error = 1; +#ifdef CONFIG_CAN_EXTID + hdr.ch_extid = 0; +#endif + hdr.ch_unused = 0; + + /* And provide the error report to the upper half logic */ + + ret = can_receive(dev, &hdr, data); + if (ret < 0) + { + canlldbg("ERROR: can_receive failed: %d\n", ret); + } + } +} +#endif /* CONFIG_CAN_ERRORS */ + +/**************************************************************************** + * Name: mcan_receive + * + * Description: + * Receive an MCAN messages + * + * Input Parameters: + * dev - CAN-common state data + * rxbuffer - The RX buffer containing the received messages + * nwords - The length of the RX buffer (element size in words). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_receive(FAR struct can_dev_s *dev, FAR uint32_t *rxbuffer, + unsigned long nwords) +{ + struct can_hdr_s hdr; + uint32_t regval; + unsigned int nbytes; + int ret; + + /* Invalidate the D-Cache so that we reread the RX buffer data from memory. */ + + nbytes = (nwords << 2); + arch_invalidate_dcache((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes); + + /* Format the CAN header */ + /* Work R0 contains the CAN ID */ + + regval = *rxbuffer++; + canregdbg("R0: %08x\n", regval); + +#ifdef CONFIG_CAN_ERRORS + hdr.ch_error = 0; +#endif + hdr.ch_unused = 0; + + if ((regval & BUFFER_R0_RTR) != 0) + { + hdr.ch_rtr = true; + } + else + { + hdr.ch_rtr = false; + } + +#ifdef CONFIG_CAN_EXTID + if ((regval & BUFFER_R0_XTD) != 0) + { + /* Save the extended ID of the newly received message */ + + hdr.ch_id = (regval & BUFFER_R0_EXTID_MASK) >> BUFFER_R0_EXTID_SHIFT; + hdr.ch_extid = true; + } + else + { + hdr.ch_id = (regval & BUFFER_R0_STDID_MASK) >> BUFFER_R0_STDID_SHIFT; + hdr.ch_extid = false; + } + +#else + if ((regval & BUFFER_R0_XTD) != 0) + { + /* Drop any messages with extended IDs */ + + return; + } + + /* Save the standard ID of the newly received message */ + + hdr.ch_id = (regval & BUFFER_R0_STDID_MASK) >> BUFFER_R0_STDID_SHIFT; +#endif + + /* Word R1 contains the DLC and timestamp */ + + regval = *rxbuffer++; + canregdbg("R1: %08x\n", regval); + + hdr.ch_dlc = (regval & BUFFER_R1_DLC_MASK) >> BUFFER_R1_DLC_SHIFT; + + /* And provide the CAN message to the upper half logic */ + + ret = can_receive(dev, &hdr, (FAR uint8_t *)rxbuffer); + if (ret < 0) + { + canlldbg("ERROR: can_receive failed: %d\n", ret); + } +} + +/**************************************************************************** + * Name: mcan_interrupt + * + * Description: + * Common MCAN interrupt handler + * + * Input Parameters: + * dev - CAN-common state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mcan_interrupt(FAR struct can_dev_s *dev) +{ + FAR struct sam_mcan_s *priv = dev->cd_priv; + FAR const struct sam_config_s *config; + uint32_t ir; + uint32_t ie; + uint32_t pending; + uint32_t regval; + unsigned int nelem; + unsigned int ndx; + bool handled; + + DEBUGASSERT(priv && priv->config); + config = priv->config; + + /* Loop while there are pending interrupt events */ + + do + { + /* Get the set of pending interrupts. */ + + ir = mcan_getreg(priv, SAM_MCAN_IR_OFFSET); + ie = mcan_getreg(priv, SAM_MCAN_IE_OFFSET); + + pending = (ir & ie); + handled = false; + + /* Check for any errors */ + + if ((pending & MCAN_ANYERR_INTS) != 0) + { + /* Check for common errors */ + + if ((pending & MCAN_CMNERR_INTS) != 0) + { + canlldbg("ERROR: Common %08x\n", pending & MCAN_CMNERR_INTS); + + /* Clear the error indications */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_CMNERR_INTS); + } + + /* Check for transmission errors */ + + if ((pending & MCAN_TXERR_INTS) != 0) + { + canlldbg("ERROR: TX %08x\n", pending & MCAN_TXERR_INTS); + + /* Clear the error indications */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_TXERR_INTS); + + /* REVISIT: Will MCAN_INT_TC also be set in the event of + * a transmission error? Each write must conclude with a + * call to man_buffer_release(), whether or not the write + * was successful. + * + * We assume that MCAN_INT_TC will be called for each + * message buffer. Except the transfer is cancelled. + * TODO: add handling for MCAN_INT_TCF + */ + } + + /* Check for reception errors */ + + if ((pending & MCAN_RXERR_INTS) != 0) + { + canlldbg("ERROR: RX %08x\n", pending & MCAN_RXERR_INTS); + + /* Clear the error indications */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_RXERR_INTS); + } + +#ifdef CONFIG_CAN_ERRORS + /* Report errors */ + + mcan_error(dev, pending & MCAN_ANYERR_INTS, priv->olderrors); + + priv->olderrors = (pending & MCAN_ANYERR_INTS); +#endif + handled = true; + } +#ifdef CONFIG_CAN_ERRORS + else if (priv->olderrors != 0) + { + /* All (old) errors cleared */ + + canlldbg("ERROR: CLEARED\n"); + + mcan_error(dev, 0, priv->olderrors); + + priv->olderrors = 0; + handled = true; + } +#endif + + /* Check for successful completion of a transmission */ + + if ((pending & MCAN_INT_TC) != 0) + { + /* Clear the pending TX completion interrupt (and all + * other TX-related interrupts) + */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, priv->txints); + + /* Indicate that there is one more buffer free in the TX FIFOQ by + * "releasing" it. This may have the effect of waking up a thread + * that has been waiting for a free TX FIFOQ buffer. + * + * REVISIT: TX dedicated buffers are not supported. + */ + + mcan_buffer_release(priv); + handled = true; + +#ifdef CONFIG_CAN_TXREADY + /* Inform the upper half driver that we are again ready to accept + * data in mcan_send(). + */ + + (void)can_txready(dev); +#endif + } + else if ((pending & priv->txints) != 0) + { + /* Clear unhandled TX events */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, priv->txints); + handled = true; + } + +#if 0 /* Not used */ + /* Check if a message has been stored to the dedicated RX buffer (DRX) */ + + if ((pending & MCAN_INT_DRX) != 0)) + { + int i; + + /* Clear the pending DRX interrupt */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_INT_DRX); + + /* Process each dedicated RX buffer */ + + for (i = 0; i < config->nrxdedicated; i++) + { + uint32_t *rxdedicated = &config->rxdedicated[i]; + + /* Check if datat is available in this dedicated RX buffer */ + + if (mcan_dedicated_rxbuffer_available(priv, i)) + { + /* Yes.. Invalidate the D-Cache to that data will be re- + * fetched from RAM. + * + * REVISIT: This will require 32-byte alignment. + */ + + arch_invalidata_dcache(); + mcan_receive(priv, rxdedicated, config->rxbufferesize); + + /* Clear the new data flag for the buffer */ + + if (i < 32) + { + sam_putreg(priv, SAM_MCAN_NDAT1_OFFSET, (1 << i); + } + else + { + sam_putreg(priv, SAM_MCAN_NDAT1_OFFSET, (1 << (i - 32)); + } + } + } + + handled = true; + } +#endif + + /* Clear the RX FIFO1 new message interrupt */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_INT_RF1N); + pending &= ~MCAN_INT_RF1N; + + /* We treat RX FIFO1 as the "high priority" queue: We will process + * all messages in RX FIFO1 before processing any message from RX + * FIFO0. + */ + + for (; ; ) + { + /* Check if there is anything in RX FIFO1 */ + + regval = mcan_getreg(priv, SAM_MCAN_RXF1S_OFFSET); + nelem = (regval & MCAN_RXF0S_F0FL_MASK) >> MCAN_RXF0S_F0FL_SHIFT; + if (nelem == 0) + { + /* Break out of the loop if RX FIFO1 is empty */ + + break; + } + + /* Clear the RX FIFO1 interrupt (and all other FIFO1-related + * interrupts) + */ + + /* Handle the newly received message in FIFO1 */ + + ndx = (regval & MCAN_RXF1S_F1GI_MASK) >> MCAN_RXF1S_F1GI_SHIFT; + + if ((regval & MCAN_RXF0S_RF0L) != 0) + { + canlldbg("ERROR: Message lost: %08x\n", regval); + } + else + { + mcan_receive(dev, + config->msgram.rxfifo1 + + (ndx * priv->config->rxfifo1esize), + priv->config->rxfifo1esize); + } + + /* Acknowledge reading the FIFO entry */ + + mcan_putreg(priv, SAM_MCAN_RXF1A_OFFSET, ndx); + handled = true; + } + + /* Check for successful reception of a new message in RX FIFO0 */ + /* Clear the RX FIFO0 new message interrupt */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_INT_RF0N); + pending &= ~MCAN_INT_RF0N; + + /* Check if there is anything in RX FIFO0 */ + + regval = mcan_getreg(priv, SAM_MCAN_RXF0S_OFFSET); + nelem = (regval & MCAN_RXF0S_F0FL_MASK) >> MCAN_RXF0S_F0FL_SHIFT; + if (nelem > 0) + { + /* Handle the newly received message in FIFO0 */ + + ndx = (regval & MCAN_RXF0S_F0GI_MASK) >> MCAN_RXF0S_F0GI_SHIFT; + + if ((regval & MCAN_RXF0S_RF0L) != 0) + { + canlldbg("ERROR: Message lost: %08x\n", regval); + } + else + { + mcan_receive(dev, + config->msgram.rxfifo0 + + (ndx * priv->config->rxfifo0esize), + priv->config->rxfifo0esize); + } + + /* Acknowledge reading the FIFO entry */ + + mcan_putreg(priv, SAM_MCAN_RXF0A_OFFSET, ndx); + handled = true; + } + + /* Clear unhandled RX interrupts */ + + if ((pending & priv->rxints) != 0) + { + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, priv->rxints); + } + } + while (handled); +} + +/**************************************************************************** + * Name: mcan0_interrupt + * + * Description: + * MCAN0 interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_MCAN0 +static int mcan0_interrupt(int irq, void *context) +{ + mcan_interrupt(&g_mcan0dev); + return OK; +} +#endif + +/**************************************************************************** + * Name: mcan1_interrupt + * + * Description: + * MCAN1 interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_MCAN1 +static int mcan1_interrupt(int irq, void *context) +{ + mcan_interrupt(&g_mcan1dev); + return OK; +} +#endif + +/**************************************************************************** + * Name: mcan_hw_initialize + * + * Description: + * MCAN hardware initialization + * + * Input Parameter: + * priv - A pointer to the private data structure for this MCAN peripheral + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int mcan_hw_initialize(struct sam_mcan_s *priv) +{ + FAR const struct sam_config_s *config = priv->config; + FAR uint32_t *msgram; + uint32_t regval; + uint32_t cntr; + uint32_t cmr; + + canllvdbg("MCAN%d\n", config->port); + + /* Configure MCAN pins */ + + sam_configgpio(config->rxpinset); + sam_configgpio(config->txpinset); + + /* Enable peripheral clocking */ + + sam_enableperiph1(config->pid); + + /* Enable the Initialization state */ + + regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); + regval |= MCAN_CCCR_INIT; + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + + /* Wait for initialization mode to take effect */ + + while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & MCAN_CCCR_INIT) == 0); + + /* Enable writing to configuration registers */ + + regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); + regval |= (MCAN_CCCR_INIT | MCAN_CCCR_CCE); + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + + /* Global Filter Configuration: + * + * ANFS=0: Store all non matching standard frame in RX FIFO0 + * ANFE=0: Store all non matching extended frame in RX FIFO0 + */ + + regval = MCAN_GFC_ANFE_RX_FIFO0 | MCAN_GFC_ANFS_RX_FIFO0; + mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval); + + /* Extended ID Filter AND mask */ + + mcan_putreg(priv, SAM_MCAN_XIDAM_OFFSET, 0x1fffffff); + + /* Disable all interrupts */ + + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, 0); + mcan_putreg(priv, SAM_MCAN_TXBTIE_OFFSET, 0); + + /* All interrupts directed to Line 0. But disable both interrupt lines 0 + * and 1 for now. + * + * REVISIT: Only interrupt line 0 is used by this driver. + */ + + mcan_putreg(priv, SAM_MCAN_ILS_OFFSET, 0); + mcan_putreg(priv, SAM_MCAN_ILE_OFFSET, 0); + + /* Clear all pending interrupts. */ + + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_INT_ALL); + + /* Configure MCAN bit timing */ + + mcan_putreg(priv, SAM_MCAN_BTP_OFFSET, priv->btp); + mcan_putreg(priv, SAM_MCAN_FBTP_OFFSET, priv->fbtp); + + /* Configure message RAM starting addresses and sizes. */ + + regval = MAILBOX_ADDRESS(config->msgram.stdfilters) | + MCAN_SIDFC_LSS(config->nstdfilters); + mcan_putreg(priv, SAM_MCAN_SIDFC_OFFSET, regval); + + regval = MAILBOX_ADDRESS(config->msgram.extfilters) | + MCAN_XIDFC_LSE(config->nextfilters); + mcan_putreg(priv, SAM_MCAN_XIDFC_OFFSET, regval); + + /* Configure RX FIFOs */ + + regval = MAILBOX_ADDRESS(config->msgram.rxfifo0) | + MCAN_RXF0C_F0S(config->nrxfifo0); + mcan_putreg(priv, SAM_MCAN_RXF0C_OFFSET, regval); + + regval = MAILBOX_ADDRESS(config->msgram.rxfifo1) | + MCAN_RXF1C_F1S(config->nrxfifo1); + mcan_putreg(priv, SAM_MCAN_RXF1C_OFFSET, regval); + + /* Watermark interrupt off, blocking mode */ + + regval = MAILBOX_ADDRESS(config->msgram.rxdedicated); + mcan_putreg(priv, SAM_MCAN_RXBC_OFFSET, regval); + + regval = MAILBOX_ADDRESS(config->msgram.txeventfifo) | + MCAN_TXEFC_EFS(config->ntxeventfifo); + mcan_putreg(priv, SAM_MCAN_TXEFC_OFFSET, regval); + + /* Watermark interrupt off */ + + regval = MAILBOX_ADDRESS(config->msgram.txdedicated) | + MCAN_TXBC_NDTB(config->ntxdedicated) | + MCAN_TXBC_TFQS(config->ntxfifoq); + mcan_putreg(priv, SAM_MCAN_TXBC_OFFSET, regval); + + regval = MCAN_RXESC_RBDS(config->rxbufferecode) | + MCAN_RXESC_F1DS(config->rxfifo1ecode) | + MCAN_RXESC_F0DS(config->rxfifo0ecode); + mcan_putreg(priv, SAM_MCAN_RXESC_OFFSET, regval); + + regval = MCAN_TXESC_TBDS(config->txbufferecode); + mcan_putreg(priv, SAM_MCAN_TXESC_OFFSET, regval); + + /* Configure Message Filters */ + /* Disable all standard filters */ + + msgram = config->msgram.stdfilters; + cntr = config->nstdfilters; + while (cntr > 0) + { + *msgram++ = STDFILTER_S0_SFEC_DISABLE; + cntr--; + } + + /* Disable all extended filters */ + + msgram = config->msgram.extfilters; + cntr = config->nextfilters; + while (cntr > 0) + { + *msgram = EXTFILTER_F0_EFEC_DISABLE; + msgram = msgram + 2; + cntr--; + } + + /* Clear new RX data flags */ + + mcan_putreg(priv, SAM_MCAN_NDAT1_OFFSET, 0xffffffff); + mcan_putreg(priv, SAM_MCAN_NDAT2_OFFSET, 0xffffffff); + + /* Select ISO11898-1 mode or FD mode with or without fast bit rate + * switching + */ + + regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); + regval &= ~(MCAN_CCCR_CME_MASK | MCAN_CCCR_CMR_MASK); + + switch (config->mode) + { + default: + case MCAN_ISO11898_1_MODE: + regval |= MCAN_CCCR_CME_ISO11898_1; + cmr = MCAN_CCCR_CMR_ISO11898_1; + break; + +#ifdef CONFIG_CAN_FD + case MCAN_FD_MODE: + regval |= MCAN_CCCR_CME_FD; + cmr = MCAN_CCCR_CMR_FD; + break; + + case MCAN_FD_BSW_MODE: + regval |= MCAN_CCCR_CME_FD_BSW; + cmr = MCAN_CCCR_CMR_FD_BSW; + break; +#endif + } + + /* Set the initial CAN mode */ + + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + + /* Request the mode change */ + + regval |= cmr; + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + +#if 0 /* Not necessary in initialization mode */ + /* Wait for the mode to take effect */ + + while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) != 0); +#endif + + /* Enable FIFO/Queue mode + * + * REVISIT: Dedicated TX buffers are not used. + */ + + regval = mcan_getreg(priv, SAM_MCAN_TXBC_OFFSET); +#ifdef CONFIG_SAMV7_MCAN_QUEUE_MODE + regval |= MCAN_TXBC_TFQM; +#else + regval &= ~MCAN_TXBC_TFQM; +#endif + mcan_putreg(priv, SAM_MCAN_TXBC_OFFSET, regval); + +#ifdef SAMV7_MCAN_LOOPBACK + /* Is loopback mode selected for this peripheral? */ + + if (config->loopback) + { + /* MCAN_CCCR_TEST - Test mode enable + * MCAN_CCCR_MON - Bus monitoring mode (for internal loopback) + * MCAN_TEST_LBCK - Loopback mode + */ + + regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); + regval |= (MCAN_CCCR_TEST | MCAN_CCCR_MON); + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + + regval = mcan_getreg(priv, SAM_MCAN_TEST_OFFSET); + regval |= MCAN_TEST_LBCK; + mcan_putreg(priv, SAM_MCAN_TEST_OFFSET, regval); + } +#endif + + /* Configure interrupt lines */ + /* Select RX-related interrupts */ + +#if 0 /* Dedicated RX buffers are not used by this driver */ + priv->rxints = MCAN_RXDEDBUF_INTS; +#else + priv->rxints = MCAN_RXFIFO_INTS; +#endif + + /* Select TX-related interrupts */ + +#if 0 /* Dedicated TX buffers are not used by this driver */ + priv->txints = MCAN_TXDEDBUF_INTS; +#else + priv->txints = MCAN_TXFIFOQ_INTS; +#endif + + /* Direct all interrupts to Line 0. + * + * Bits in the ILS register correspond to each MCAN interrupt; A bit + * set to '1' is directed to interrupt line 1; a bit cleared to '0' + * is directed interrupt line 0. + * + * REVISIT: Nothing is done here. Only interrupt line 0 is used by + * this driver and ILS was already cleared above. + */ + + /* Enable only interrupt line 0. */ + + mcan_putreg(priv, SAM_MCAN_ILE_OFFSET, MCAN_ILE_EINT0); + + /* Disable initialization mode to enable normal operation */ + + regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); + regval &= ~MCAN_CCCR_INIT; + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_mcan_initialize + * + * Description: + * Initialize the selected MCAN port + * + * Input Parameter: + * port - Port number (for hardware that has multiple MCAN interfaces), + * 0=MCAN0, 1=MCAN1 + * + * Returned Value: + * Valid CAN device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct can_dev_s *sam_mcan_initialize(int port) +{ + FAR struct can_dev_s *dev; + FAR struct sam_mcan_s *priv; + FAR const struct sam_config_s *config; + uint32_t regval; + + canvdbg("MCAN%d\n", port); + + /* Select PCK5 clock source and pre-scaler value. Both MCAN controllers + * use PCK5 to derive bit rate. + */ + + regval = PMC_PCK_PRES(CONFIG_SAMV7_MCAN_CLKSRC_PRESCALER - 1) | SAMV7_MCAN_CLKSRC; + putreg32(regval, SAM_PMC_PCK5); + + /* Enable PCK5 */ + + putreg32(PMC_PCK5, SAM_PMC_SCER); + + /* Select MCAN peripheral to be initialized */ + +#ifdef CONFIG_SAMV7_MCAN0 + if (port == MCAN0) + { + /* Select the MCAN0 device structure */ + + dev = &g_mcan0dev; + priv = &g_mcan0priv; + config = &g_mcan0const; + + /* Configure MCAN0 Message RAM Base Address */ + + regval = getreg32(SAM_MATRIX_CAN0); + regval &= MATRIX_CAN0_RESERVED; + regval |= (uint32_t)config->msgram.stdfilters & MATRIX_CAN0_CAN0DMABA_MASK; + putreg32(regval, SAM_MATRIX_CAN0); + } + else +#endif +#ifdef CONFIG_SAMV7_MCAN1 + if (port == MCAN1) + { + /* Select the MCAN1 device structure */ + + dev = &g_mcan1dev; + priv = &g_mcan1priv; + config = &g_mcan1const; + + /* Configure MCAN1 Message RAM Base Address */ + + regval = getreg32(SAM_MATRIX_CCFG_SYSIO); + regval &= ~MATRIX_CCFG_CAN1DMABA_MASK; + regval |= (uint32_t)config->msgram.stdfilters & MATRIX_CCFG_CAN1DMABA_MASK; + putreg32(regval, SAM_MATRIX_CCFG_SYSIO); + } + else +#endif + { + candbg("ERROR: Unsupported port %d\n", port); + return NULL; + } + + /* Is this the first time that we have handed out this device? */ + + if (priv->state == MCAN_STATE_UNINIT) + { + /* Yes, then perform one time data initialization */ + + memset(priv, 0, sizeof(struct sam_mcan_s)); + priv->config = config; + + /* Set the initial bit timing. This might change subsequently + * due to IOCTL command processing. + */ + + priv->btp = config->btp; + priv->fbtp = config->fbtp; + + /* Initialize semaphores */ + + sem_init(&priv->locksem, 0, 1); + sem_init(&priv->txfsem, 0, config->ntxfifoq); + + dev->cd_ops = &g_mcanops; + dev->cd_priv = (FAR void *)priv; + + /* And put the hardware in the initial state */ + + mcan_reset(dev); + } + + return dev; +} + +#endif /* CONFIG_CAN && CONFIG_SAMV7_MCAN */ diff --git a/arch/arm/src/samv7/sam_mcan.h b/arch/arm/src/samv7/sam_mcan.h new file mode 100644 index 0000000000000000000000000000000000000000..540800b37d360678914e46f162ac454d5e6ac7f5 --- /dev/null +++ b/arch/arm/src/samv7/sam_mcan.h @@ -0,0 +1,110 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_mcan.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_MCAN_H +#define __ARCH_ARM_SRC_SAMV7_SAM_MCAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_mcan.h" + +#include + +#if defined(CONFIG_CAN) && (defined(CONFIG_SAMV7_MCAN0) || \ + defined(CONFIG_SAMV7_MCAN1)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Port numbers for use with sam_mcan_initialize() */ + +#define MCAN0 0 +#define MCAN1 1 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_mcan_initialize + * + * Description: + * Initialize the selected MCAN port + * + * Input Parameter: + * port - Port number (for hardware that has multiple CAN interfaces), + * 0=MCAN0, 1=NCAN1 + * + * Returned Value: + * Valid CAN device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct can_dev_s; +FAR struct can_dev_s *sam_mcan_initialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_CAN && (CONFIG_SAMV7_MCAN0 || CONFIG_SAMV7_MCAN1) */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_MCAN_H */ diff --git a/arch/arm/src/samv7/sam_mpuinit.c b/arch/arm/src/samv7/sam_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..e9b0b3775431a95655d8d78e8d29c360e64f5071 --- /dev/null +++ b/arch/arm/src/samv7/sam_mpuinit.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * arch/arm/src/common/sam_mpuinit.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "cache.h" +#include "chip/sam_memorymap.h" + +#include "sam_mpuinit.h" + +#ifdef CONFIG_ARM_MPU + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_mpu_initialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3/4 + * resources. + * + ****************************************************************************/ + +void sam_mpu_initialize(void) +{ +#ifdef CONFIG_BUILD_PROTECTED + uintptr_t datastart; + uintptr_t dataend; +#endif + + /* Show MPU information */ + + mpu_showtype(); + +#ifdef CONFIG_ARMV7M_DCACHE + /* Memory barrier */ + + ARM_DMB(); + +#ifdef CONFIG_SAMV7_QSPI + /* Make QSPI memory region strongly ordered */ + + mpu_priv_stronglyordered(SAM_QSPIMEM_BASE, SAM_QSPIMEM_SIZE); + +#endif +#endif + +#ifdef CONFIG_BUILD_PROTECTED + /* Configure user flash and SRAM space */ + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart); + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(dataend >= datastart); + + mpu_user_intsram(datastart, dataend - datastart); +#endif + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: sam_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} +#endif + +#endif /* CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/samv7/sam_mpuinit.h b/arch/arm/src/samv7/sam_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..ef5a9d037aa3cb577681260f67b91a65589f970a --- /dev/null +++ b/arch/arm/src/samv7/sam_mpuinit.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_mpuinit.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_MPUINIT_H +#define __ARCH_ARM_SRC_SAMV7_SAM_MPUINIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_mpu_initialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted SAMV7 + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_ARM_MPU +void sam_mpu_initialize(void); +#else +# define sam_mpu_initialize() +#endif + +/**************************************************************************** + * Name: sam_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_mpu_uheap(uintptr_t start, size_t size); +#else +# define sam_mpu_uheap(start,size) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_MPUINIT_H */ diff --git a/arch/arm/src/samv7/sam_oneshot.c b/arch/arm/src/samv7/sam_oneshot.c new file mode 100644 index 0000000000000000000000000000000000000000..34fa89843e35612eae918203a6f119b446e3e7eb --- /dev/null +++ b/arch/arm/src/samv7/sam_oneshot.c @@ -0,0 +1,479 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_oneshot.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMV71 Series Data Sheet + * NuttX SAMA5 one-shot timer driver + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sam_oneshot.h" + +#ifdef CONFIG_SAMV7_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Timer interrupt callback. When the oneshot timer interrupt expires, + * this function will be called. It will forward the call to the next + * level up. + * + * Input Parameters: + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_oneshot_handler(TC_HANDLE tch, void *arg, uint32_t sr) +{ + struct sam_oneshot_s *oneshot = (struct sam_oneshot_s *)arg; + oneshot_handler_t oneshot_handler; + void *oneshot_arg; + + tcllvdbg("Expired...\n"); + DEBUGASSERT(oneshot && oneshot->handler); + + /* The clock was stopped, but not disabled when the RC match occurred. + * Disable the TC now and disable any further interrupts. + */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + /* The timer is no longer running */ + + oneshot->running = false; + + /* Forward the event, clearing out any vestiges */ + + oneshot_handler = (oneshot_handler_t)oneshot->handler; + oneshot->handler = NULL; + oneshot_arg = (void *)oneshot->arg; + oneshot->arg = NULL; + + oneshot_handler(oneshot_arg); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/samv7/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution) +{ + uint32_t frequency; + uint32_t actual; + uint32_t cmr; + int ret; + + tcvdbg("chan=%d resolution=%d usec\n", chan, resolution); + DEBUGASSERT(oneshot && resolution > 0); + + /* Get the TC frequency the corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + + /* The pre-calculate values to use when we start the timer */ + + ret = sam_tc_clockselect(frequency, &cmr, &actual); + if (ret < 0) + { + tcdbg("ERROR: sam_tc_clockselect failed: %d\n", ret); + return ret; + } + + tcvdbg("frequency=%lu, actual=%lu, cmr=%08lx\n", + (unsigned long)frequency, (unsigned long)actual, + (unsigned long)cmr); + + /* Allocate the timer/counter and select its mode of operation + * + * TC_CMR_TCCLKS - Returned by sam_tc_clockselect + * TC_CMR_CLKI=0 - Not inverted + * TC_CMR_BURST_NONE - Not gated by an external signal + * TC_CMR_CPCSTOP=1 - Stop the clock on an RC compare event + * TC_CMR_CPCDIS=0 - Don't disable the clock on an RC compare event + * TC_CMR_EEVTEDG_NONE - No external events (and, hence, no edges + * TC_CMR_EEVT_TIOB - ???? REVISIT + * TC_CMR_ENET=0 - External event trigger disabled + * TC_CMR_WAVSEL_UPRC - TC_CV is incremented from 0 to the value of RC, + * then automatically reset on a RC Compare + * TC_CMR_WAVE - Waveform mode + * TC_CMR_ACPA_NONE - RA compare has no effect on TIOA + * TC_CMR_ACPC_NONE - RC compare has no effect on TIOA + * TC_CMR_AEEVT_NONE - No external event effect on TIOA + * TC_CMR_ASWTRG_NONE - No software trigger effect on TIOA + * TC_CMR_BCPB_NONE - RB compare has no effect on TIOB + * TC_CMR_BCPC_NONE - RC compare has no effect on TIOB + * TC_CMR_BEEVT_NONE - No external event effect on TIOB + * TC_CMR_BSWTRG_NONE - No software trigger effect on TIOB + */ + + cmr |= (TC_CMR_BURST_NONE | TC_CMR_CPCSTOP | TC_CMR_EEVTEDG_NONE | + TC_CMR_EEVT_TIOB | TC_CMR_WAVSEL_UPRC | TC_CMR_WAVE | + TC_CMR_ACPA_NONE | TC_CMR_ACPC_NONE | TC_CMR_AEEVT_NONE | + TC_CMR_ASWTRG_NONE | TC_CMR_BCPB_NONE | TC_CMR_BCPC_NONE | + TC_CMR_BEEVT_NONE | TC_CMR_BSWTRG_NONE); + + oneshot->tch = sam_tc_allocate(chan, cmr); + if (!oneshot->tch) + { + tcdbg("ERROR: Failed to allocate timer channel %d\n", chan); + return -EBUSY; + } + + /* Initialize the remaining fields in the state structure and return + * success. + */ + + oneshot->chan = chan; + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts) +{ + uint64_t usec; + uint64_t regval; + irqstate_t flags; + + tcvdbg("handler=%p arg=%p, ts=(%lu, %lu)\n", + handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + DEBUGASSERT(oneshot && handler && ts); + + /* Was the oneshot already running? */ + + flags = enter_critical_section(); + if (oneshot->running) + { + /* Yes.. then cancel it */ + + tcvdbg("Already running... cancelling\n"); + (void)sam_oneshot_cancel(oneshot, NULL); + } + + /* Save the new handler and its argument */ + + oneshot->handler = handler; + oneshot->arg = arg; + + /* Express the delay in microseconds */ + + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); + + /* Get the timer counter frequency and determine the number of counts need to achieve the requested delay. + * + * frequency = ticks / second + * ticks = seconds * frequency + * = (usecs * frequency) / USEC_PER_SEC; + */ + + regval = (usec * (uint64_t)sam_tc_divfreq(oneshot->tch)) / USEC_PER_SEC; + + tcvdbg("usec=%llu regval=%08llx\n", usec, regval); + DEBUGASSERT(regval <= UINT16_MAX); + + /* Set up to receive the callback when the interrupt occurs */ + + (void)sam_tc_attach(oneshot->tch, sam_oneshot_handler, oneshot, + TC_INT_CPCS); + + /* Set RC so that an event will be triggered when TC_CV register counts + * up to RC. + */ + + sam_tc_setregister(oneshot->tch, TC_REGC, (uint32_t)regval); + + /* Start the counter */ + + sam_tc_start(oneshot->tch); + + /* Enable interrupts. We should get the callback when the interrupt + * occurs. + */ + + oneshot->running = true; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. ts may be zero in which case the time remaining + * is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts) +{ + irqstate_t flags; + uint64_t usec; + uint64_t sec; + uint64_t nsec; + uint32_t count; + uint32_t rc; + + /* Was the timer running? */ + + flags = enter_critical_section(); + if (!oneshot->running) + { + /* No.. Just return zero timer remaining and successful cancellation. + * This function may execute at a high rate with no timer running + * (as when pre-emption is enabled and disabled). + */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + leave_critical_section(flags); + return OK; + } + + /* Yes.. Get the timer counter and rc registers and stop the counter. If + * the counter expires while we are doing this, the counter clock will be + * stopped, but the clock will not be disabled. + * + * The expected behavior is that the the counter register will freezes at + * a value equal to the RC register when the timer expires. The counter + * should have values between 0 and RC in all other cased. + * + * REVISIT: This does not appear to be the case. + */ + + tcvdbg("Cancelling...\n"); + + count = sam_tc_getcounter(oneshot->tch); + rc = sam_tc_getregister(oneshot->tch, TC_REGC); + + /* Now we can disable the interrupt and stop the timer. */ + + sam_tc_attach(oneshot->tch, NULL, NULL, 0); + sam_tc_stop(oneshot->tch); + + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + leave_critical_section(flags); + + /* Did the caller provide us with a location to return the time + * remaining? + */ + + if (ts) + { + /* Yes.. then calculate and return the time remaining on the + * oneshot timer. + */ + + tcvdbg("rc=%lu count=%lu usec=%lu\n", + (unsigned long)rc, (unsigned long)count, (unsigned long)usec); + + /* REVISIT: I am not certain why the timer counter value sometimes + * exceeds RC. Might be a bug, or perhaps the counter does not stop + * in all cases. + */ + + if (count >= rc) + { + /* No time remaining (?) */ + + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + else + { + /* The total time remaining is the difference. Convert the that + * to units of microseconds. + * + * frequency = ticks / second + * seconds = ticks * frequency + * usecs = (ticks * USEC_PER_SEC) / frequency; + */ + + usec = (((uint64_t)(rc - count)) * USEC_PER_SEC) / + sam_tc_divfreq(oneshot->tch); + + /* Return the time remaining in the correct form */ + + sec = usec / USEC_PER_SEC; + nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC; + + ts->tv_sec = (time_t)sec; + ts->tv_nsec = (unsigned long)nsec; + } + + tcvdbg("remaining (%lu, %lu)\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + } + + return OK; +} + +/**************************************************************************** + * Name: sam_oneshot_max_delay + * + * Description: + * Return the maximum delay supported by the one shot timer (in + * microseconds). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * usec The location in which to return the maximum delay. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP +int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec) +{ + DEBUGASSERT(oneshot && usec); + *usec = (0xffffull * USEC_PER_SEC) / (uint64_t)sam_tc_divfreq(oneshot->tch); + return OK; +} +#endif + +#endif /* CONFIG_SAMV7_ONESHOT */ diff --git a/arch/arm/src/samv7/sam_oneshot.h b/arch/arm/src/samv7/sam_oneshot.h new file mode 100644 index 0000000000000000000000000000000000000000..62efde8047de7b2ded22784223cfaf018299b35b --- /dev/null +++ b/arch/arm/src/samv7/sam_oneshot.h @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_oneshot.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_ONESHOT_H +#define __ARCH_ARM_SRC_SAMV7_SAM_ONESHOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_tc.h" + +#ifdef CONFIG_SAMV7_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ONESHOT_INITIALIZED(s) (((s)->tch) != NULL) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the callback function that will be invoked when the oneshot + * timer expires. The oneshot fires, the client will receive: + * + * arg - The opaque argument provided when the interrupt was registered + */ + +typedef void (*oneshot_handler_t)(void *arg); + +/* The oneshot client must allocate an instance of this structure and called + * sam_oneshot_initialize() before using the oneshot facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct sam_oneshot_s +{ + uint8_t chan; /* The timer/counter in use */ + volatile bool running; /* True: the timer is running */ + TC_HANDLE tch; /* Handle returned by + * sam_tc_initialize() */ + volatile oneshot_handler_t handler; /* Oneshot expiration callback */ + volatile void *arg; /* The argument that will accompany + * the callback */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * chan Timer counter channel to be used. See the TC_CHAN* + * definitions in arch/arm/src/samv7/sam_tc.h. + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_initialize(struct sam_oneshot_s *oneshot, int chan, + uint16_t resolution); + +/**************************************************************************** + * Name: sam_oneshot_max_delay + * + * Description: + * Return the maximum delay supported by the one shot timer (in + * microseconds). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * usec The location in which to return the maximum delay. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP +int sam_oneshot_max_delay(struct sam_oneshot_s *oneshot, uint64_t *usec); +#endif + +/**************************************************************************** + * Name: sam_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sam_oneshot_start(struct sam_oneshot_s *oneshot, oneshot_handler_t handler, + void *arg, const struct timespec *ts); + +/**************************************************************************** + * Name: sam_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * sam_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int sam_oneshot_cancel(struct sam_oneshot_s *oneshot, struct timespec *ts); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMV7_ONESHOT */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_ONESHOT_H */ diff --git a/arch/arm/src/samv7/sam_pck.c b/arch/arm/src/samv7/sam_pck.c new file mode 100644 index 0000000000000000000000000000000000000000..c4dc27d0295f051496b6ffe238810cfce2e636a4 --- /dev/null +++ b/arch/arm/src/samv7/sam_pck.c @@ -0,0 +1,345 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_pck.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip/sam_pinmap.h" + +#include "up_arch.h" +#include "sam_gpio.h" + +#include "sam_pck.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sam_pck_configure + * + * Description: + * Configure a programmable clock output. The selected PCK is programmed + * to the selected frequency using either PLLA or the MCK as the source + * clock (depending on the value of the selected frequency). The clock + * is initially disabled. You must call sam_pck_enable() to enable the + * clock after it has been configured. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * clocksrc - MCK or SCK. If MCK is selected, the logic will automatically + * select the PLLACK clock if it seems like a better choice. + * frequency - Defines the desired frequency. The exact frequency may + * not be attainable. In this case, frequency is interpreted to be + * a not-to-exceed frequency. + * + * Returned Value: + * The actual frequency of the clock output. + * + ****************************************************************************/ + +uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc, + uint32_t frequency) +{ + uint32_t regval; + uint32_t clkin; + uint32_t actual; + uint32_t pres; + + /* Pick a clock source. Several are possible but only MCK, PLLA, the + * MAINCK,or SCK are supported here. + */ + + switch (clksrc) + { + case PCKSRC_MCK: /* Source clock = MCK or PLLACK */ + { + /* Pick either the MCK or the PLLACK, whichever will best realize + * the target frequency. + */ + + DEBUGASSERT(BOARD_MCK_FREQUENCY < BOARD_PLLA_FREQUENCY); + + /* Pick the PLLACK if it seems like a better choice */ + + if (frequency <= BOARD_MCK_FREQUENCY || + frequency < BOARD_PLLA_FREQUENCY / 64) + { + regval = PMC_PCK_CSS_MCK; + clkin = BOARD_MCK_FREQUENCY; + } + else + { + regval = PMC_PCK_CSS_PLLA; + clkin = BOARD_PLLA_FREQUENCY; + } + } + break; + + case PCKSRC_MAINCK: /* Source clock = MAIN clock */ + regval = PMC_PCK_CSS_MAIN; + clkin = BOARD_MAINOSC_FREQUENCY; + break; + + case PCKSRC_SCK: /* Source clock = SCK */ + regval = PMC_PCK_CSS_SLOW; + clkin = BOARD_SLOWCLK_FREQUENCY; + break; + + default: + dbg("ERROR: Unknown clock source\n"); + return 0; + } + + /* Programmable Clock frequency is selected clock freqency divided by PRES + 1 */ + + pres = clkin / frequency; + if (pres < 1) + { + pres = 1; + } + else if (pres > 256) + { + pres = 256; + } + + regval |= PMC_PCK_PRES(pres - 1); + actual = clkin / pres; + + /* Disable the programmable clock, configure the PCK output pin, then set + * the selected configuration. + */ + + switch (pckid) + { + case PCK0: + putreg32(PMC_PCK0, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK0 + (void)cam_configgpio(GPIO_PMC_PCK0); +#endif + putreg32(regval, SAM_PMC_PCK0); + break; + + case PCK1: + putreg32(PMC_PCK1, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK1 + (void)cam_configgpio(GPIO_PMC_PCK1); +#endif + putreg32(regval, SAM_PMC_PCK1); + break; + + case PCK2: + putreg32(PMC_PCK2, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK2 + (void)cam_configgpio(GPIO_PMC_PCK2); +#endif + putreg32(regval, SAM_PMC_PCK2); + break; + + case PCK3: + putreg32(PMC_PCK3, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK3 + (void)cam_configgpio(GPIO_PMC_PCK3); +#endif + putreg32(regval, SAM_PMC_PCK3); + break; + + case PCK4: + putreg32(PMC_PCK4, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK4 + (void)cam_configgpio(GPIO_PMC_PCK4); +#endif + putreg32(regval, SAM_PMC_PCK4); + break; + + case PCK5: + putreg32(PMC_PCK5, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK5 + (void)cam_configgpio(GPIO_PMC_PCK5); +#endif + putreg32(regval, SAM_PMC_PCK5); + break; + + case PCK6: + putreg32(PMC_PCK6, SAM_PMC_SCDR); +#ifdef GPIO_PMC_PCK6 + (void)cam_configgpio(GPIO_PMC_PCK6); +#endif + putreg32(regval, SAM_PMC_PCK6); + break; + + default: + return -EINVAL; + } + + /* And return the actual frequency */ + + return actual; +} + +/**************************************************************************** + * Function: sam_pck_frequency + * + * Description: + * Return the frequency if the programmable clock + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * + * Returned Value: + * The frequency of the programmable clock (which may or may not be + * enabled). + * + ****************************************************************************/ + +uint32_t sam_pck_frequency(enum pckid_e pckid) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t clkin; + uint32_t presc; + + /* Get the programmable clock configuration */ + + regaddr = SAM_PMC_PCK((int)pckid); + regval = getreg32(regaddr); + + /* Get the frequency of the clock source */ + + switch (regval & PMC_PCK_CSS_MASK) + { + case PMC_PCK_CSS_SLOW: /* Slow Clock */ + clkin = BOARD_SLOWCLK_FREQUENCY; + break; + + case PMC_PCK_CSS_MAIN: /* Main Clock */ + clkin = BOARD_MAINOSC_FREQUENCY; + break; + + case PMC_PCK_CSS_PLLA: /* PLLA Clock */ + clkin = BOARD_PLLA_FREQUENCY; + break; + +#ifdef BOARD_UPLL_FREQUENCY + case PMC_PCK_CSS_UPLL: /* Divided UPLL Clock */ + clkin = BOARD_UPLL_FREQUENCY; + break; +#endif + + case PMC_PCK_CSS_MCK: /* Master Clock */ + clkin = BOARD_MCK_FREQUENCY; + break; + + default: + dbg("ERROR: Unknown clock source\n"); + return 0; + } + + /* Get the prescaler value */ + + presc = (regval & PMC_PCK_PRES_MASK) >> PMC_PCK_PRES_SHIFT; + return clkin / (presc + 1); +} + +/**************************************************************************** + * Function: sam_pck_enable + * + * Description: + * Enable or disable a programmable clock output. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * enable - True: enable the clock output, False: disable the clock output + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_pck_enable(enum pckid_e pckid, bool enable) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Select the bit in the PMC_SDER or PMC_SCER corresponding to the + * programmable clock. + */ + + regval = PMC_PCK(pckid); + + /* Select the SDER or SCER */ + + regaddr = enable ? SAM_PMC_SCER : SAM_PMC_SCDR; + + /* And do the deed */ + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Function: sam_pck_isenabled + * + * Description: + * Return true if the programmable clock is enabled. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * + * Returned Value: + * True if the specified programmable clock is enabled + * + ****************************************************************************/ + +bool sam_pck_isenabled(enum pckid_e pckid) +{ + uint32_t mask; + + /* Select the bit in the PMC_SCSR corresponding to the programmable clock. */ + + mask = PMC_PCK(pckid); + + /* Return true if the bit is set */ + + return (getreg32(SAM_PMC_SCSR) & mask) != 0; +} diff --git a/arch/arm/src/samv7/sam_pck.h b/arch/arm/src/samv7/sam_pck.h new file mode 100644 index 0000000000000000000000000000000000000000..173fc0c53f50dc4fc3989094812e9b5c6c8d9410 --- /dev/null +++ b/arch/arm/src/samv7/sam_pck.h @@ -0,0 +1,172 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_pck.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARPCKNG IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_PCK_H +#define __ARCH_ARM_SRC_SAMV7_SAM_PCK_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* Identifies the programmable clock */ + +enum pckid_e +{ + PCK0 = 0, + PCK1, + PCK2, + PCK3, + PCK4, + PCK5, + PCK6, +}; + +enum pckid_clksrc_e +{ + PCKSRC_MCK = 0, /* Source clock is the master clock (MCK) or PLLA output (PLLACK) */ + PCKSRC_MAINCK, /* Source clock is the main clock (probably the XTAL) */ + PCKSRC_SCK /* Source clock is the slow clock (SCK) */ +}; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Function: sam_pck_configure + * + * Description: + * Configure a programmable clock output. The selected PCK is programmed + * to the selected frequency using either PLLA or the MCK as the source + * clock (depending on the value of the selected frequency). The clock + * is initially disabled. You must call sam_pck_enable() to enable the + * clock after it has been configured. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, or 2) + * clocksrc - MCK or SCK. If MCK is selected, the logic will automatically + * select the PLLACK clock if it seems like a better choice. + * frequency - Defines the desired frequency. The exact frequency may + * not be attainable. In this case, frequency is interpreted to be + * a not-to-exceed frequency. + * + * Returned Value: + * The actual frequency of the clock output. + * + ****************************************************************************/ + +uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc, + uint32_t frequency); + +/**************************************************************************** + * Function: sam_pck_frequency + * + * Description: + * Return the frequency if the programmable clock + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * + * Returned Value: + * The frequency of the programmable clock (which may or may not be + * enabled). + * + ****************************************************************************/ + +uint32_t sam_pck_frequency(enum pckid_e pckid); + +/**************************************************************************** + * Function: sam_pck_enable + * + * Description: + * Enable or disable a programmable clock output. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * enable - True: enable the clock output, False: disable the clock output + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_pck_enable(enum pckid_e pckid, bool enable); + +/**************************************************************************** + * Function: sam_pck_isenabled + * + * Description: + * Return true if the programmable clock is enabled. + * + * Input Parameters: + * pckid - Identifies the programmable clock output (0, 1, .., 6) + * + * Returned Value: + * True if the specified programmable clock is enabled + * + ****************************************************************************/ + +bool sam_pck_isenabled(enum pckid_e pckid); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_PCK_H */ diff --git a/arch/arm/src/samv7/sam_periphclks.h b/arch/arm/src/samv7/sam_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..26914393dae40b842232499b8651c7c9bdaec3ae --- /dev/null +++ b/arch/arm/src/samv7/sam_periphclks.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMV7_SAM_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_SAMV71) +# include "samv71_periphclks.h" +#elif defined(CONFIG_ARCH_CHIP_SAME70) +# include "same70_periphclks.h" +#else +# error Unrecognized SAMV7 architecture +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_PERIPHCLKS_H */ diff --git a/arch/arm/src/samv7/sam_progmem.c b/arch/arm/src/samv7/sam_progmem.c new file mode 100644 index 0000000000000000000000000000000000000000..41126bff7a76939ed6c48f027d300c9a1d02a6ab --- /dev/null +++ b/arch/arm/src/samv7/sam_progmem.c @@ -0,0 +1,739 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_progmem.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "cache.h" +#include "chip/sam_memorymap.h" + +#include "sam_progmem.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAMV7_PROGMEM_NSECTORS +# error CONFIG_SAMV7_PROGMEM_NSECTORS is not defined +#endif + +/* Chip dependencies */ + +#if defined(CONFIG_ARCH_CHIP_SAMV71) || defined(CONFIG_ARCH_CHIP_SAME70) +/* All sectors are 128KB and are uniform in size. + * The only execption is sector 0 which is subdivided into two small sectors + * of 8KB and one larger sector of 112KB. + * The page size is 515 bytes. However, the smallest thing that can be + * erased is four pages. We will refer to this as a "cluster". + */ + +# define SAMV7_SECTOR_SHIFT (17) /* 2**17 = 128KB */ +# define SAMV7_PAGE_SHIFT (9) /* 2**9 = 512B */ +# define SAMV7_CLUSTER_SHIFT (13) /* 2**13 = 8*KB = 16 pages */ +# define SAMV7_LOCK_REGION_SHIFT (13) /* 2**13 = 8*KB = 16 pages */ +#else +# error FLASH geometry for this SAMV7 chip not known +#endif + +/* Sizes and masks */ + +#define SAMV7_SECTOR_SIZE (1 << SAMV7_SECTOR_SHIFT) +#define SAMV7_SECTOR_MASK (SAMV7_SECTOR_SIZE - 1) + +#define SAMV7_PAGE_SIZE (1 << SAMV7_PAGE_SHIFT) +#define SAMV7_PAGE_WORDS (1 << (SAMV7_PAGE_SHIFT - 2)) +#define SAMV7_PAGE_MASK (SAMV7_PAGE_SIZE - 1) + +#define SAMV7_CLUSTER_SIZE (1 << SAMV7_CLUSTER_SHIFT) +#define SAMV7_CLUSTER_MASK (SAMV7_CLUSTER_SHIFT - 1) + +/* Relationships */ + +#define SAMV7_PAGE2SEC_SHIFT (SAMV7_SECTOR_SHIFT - SAMV7_PAGE_SHIFT) +#define SAMV7_PAGE_PER_SEC (1 << SAMV7_PAGE2SEC_SHIFT) + +#define SAMV7_PAGE2CLUST_SHIFT (SAMV7_CLUSTER_SHIFT - SAMV7_PAGE_SHIFT) +#define SAMV7_PAGE_PER_CLUSTER (1 << SAMV7_PAGE2CLUST_SHIFT) + +#define SAMV7_CLUST2SECT_SHIFT (SAMV7_SECTOR_SHIFT - SAMV7_CLUSTER_SHIFT) +#define SAMV7_CLUSTER_PER_SEC (1 << SAMV7_CLUST2SECT_SHIFT) + +/* Conversions */ + +#define SAMV7_BYTE2PAGE(o) ((o) >> SAMV7_PAGE_SHIFT) +#define SAMV7_BYTE2CLUST(o) ((o) >> SAMV7_CLUSTER_SHIFT) +#define SAMV7_BYTE2SECT(o) ((o) >> SAMV7_SECTOR_SHIFT) + +#define SAMV7_PAGE2BYTE(p) ((p) << SAMV7_PAGE_SHIFT) +#define SAMV7_PAGE2CLUST(p) ((p) >> SAMV7_PAGE2CLUST_SHIFT) +#define SAMV7_PAGE2SEC(p) ((p) >> SAMV7_PAGE2SEC_SHIFT) + +#define SAMV7_CLUST2BYTE(c) ((c) << SAMV7_CLUSTER_SHIFT) +#define SAMV7_CLUST2PAGE(c) ((c) << SAMV7_PAGE2CLUST_SHIFT) +#define SAMV7_CLUST2SEC(c) ((c) >> SAMV7_CLUST2SECT_SHIFT) + +#define SAMV7_SEC2BYTE(s) ((s) << SAMV7_SECTOR_SHIFT) +#define SAMV7_SEC2PAGE(s) ((s) << SAMV7_PAGE2SEC_SHIFT) +#define SAMV7_SEC2CLUST(s) ((s) << SAMV7_CLUST2SECT_SHIFT) + +/* Lock region */ + +#define SAMV7_LOCK_REGION_SIZE (1 << SAMV7_LOCK_REGION_SHIFT) +#define SAMV7_LOCK_REGION_MASK (SAMV7_LOCK_REGION_SIZE - 1) + +/* Total FLASH sizes */ + +#define SAMV7_TOTAL_NSECTORS (SAMV7_FLASH_SIZE >> SAMV7_SECTOR_SHIFT) +#define SAMV7_TOTAL_NPAGES SAMV7_SEC2PAGE(SAMV7_TOTAL_NSECTORS) +#define SAMV7_TOTAL_NCLUSTERS SAMV7_SEC2CLUST(SAMV7_TOTAL_NSECTORS) + +/* Start and size of the programmable region */ + +#define SAMV7_PROGMEM_NBYTES (CONFIG_SAMV7_PROGMEM_NSECTORS << SAMV7_SECTOR_SHIFT) +#define SAMV7_PROGMEM_END (SAM_INTFLASH_BASE + SAMV7_FLASH_SIZE) +#define SAMV7_PROGMEM_START (SAMV7_PROGMEM_END - SAMV7_PROGMEM_NBYTES) + +#define SAMV7_PROGMEM_NPAGES SAMV7_SEC2PAGE(CONFIG_SAMV7_PROGMEM_NSECTORS) +#define SAMV7_PROGMEM_ENDPAGE (SAMV7_TOTAL_NPAGES) +#define SAMV7_PROGMEM_STARTPAGE (SAMV7_PROGMEM_ENDPAGE - SAMV7_PROGMEM_NPAGES) + +#define SAMV7_PROGMEM_NCLUSTERS SAMV7_SEC2CLUST(CONFIG_SAMV7_PROGMEM_NSECTORS) +#define SAMV7_PROGMEM_ENDCLUST (SAMV7_TOTAL_NCLUSTERS) +#define SAMV7_PROGMEM_STARTCLUST (SAMV7_PROGMEM_ENDCLUST - SAMV7_PROGMEM_NCLUSTERS) + +#define SAMV7_PROGMEM_NSECTORS (CONFIG_SAMV7_PROGMEM_NSECTORS) +#define SAMV7_PROGMEM_ENDSEC (SAMV7_TOTAL_NSECTORS) +#define SAMV7_PROGMEM_STARTSEC (SAMV7_PROGMEM_ENDSEC - CONFIG_SAMV7_PROGMEM_NSECTORS) + +/* Misc stuff */ + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint32_t g_page_buffer[SAMV7_PAGE_WORDS]; +static sem_t g_page_sem; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: page_buffer_lock + * + * Description: + * Get exclusive access to the global page buffer + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void page_buffer_lock(void) +{ + while (sem_wait(&g_page_sem) < 0) + { + int errcode = errno; + + /* sem_wait should only fail if it was awakened by a signal */ + + DEBUGASSERT(errcode == EINTR); + if (errcode != EINTR) + { + break; + } + } +} + +#define page_buffer_unlock() sem_post(&g_page_sem) + +/**************************************************************************** + * Name: efc_command + * + * Description: + * Send a FLASH command + * + * Input Parameters: + * cmd - The FLASH command to be sent + * arg - The argument to accompany the command + * + * Returned Value: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +static int efc_command(uint32_t cmd, uint32_t arg) +{ + uint32_t regval; + + /* Write the command to the flash command register */ + + regval = EEFC_FCR_FCMD(cmd) | EEFC_FCR_FARG(arg) | EEFC_FCR_FKEY_PASSWD; + putreg32(regval, SAM_EEFC_FCR); + + /* Wait for the FLASH to become ready again */ + + do + { + regval = getreg32(SAM_EEFC_FSR); + } + while ((regval & EEFC_FSR_FRDY) == 0); + + /* Check for errors */ + + if ((regval & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)) != 0) + { + return -EIO; + } + else + { + return OK; + } +} + +/**************************************************************************** + * Name: efc_lock + * + * Description: + * Lock a region of FLASH + * + * Input Parameters: + * page - The first page to unlock + * npages - The number of consecutive pages to unlock + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int efc_lock(size_t page, size_t npages) +{ + size_t start_page; + size_t end_page; + size_t lockpage; + int ret; + + /* Align the page to the lock region */ + + end_page = page + npages; + start_page = page & SAMV7_LOCK_REGION_MASK; + + for (lockpage = start_page; + lockpage < end_page; + lockpage += SAMV7_LOCK_REGION_SIZE) + { + ret = efc_command(FCMD_SLB, lockpage); + if (ret < 0) + { + return ret; + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: efc_unlock + * + * Description: + * Make sure that the FLASH is unlocked + * + * Input Parameters: + * page - The first page to unlock + * npages - The number of consecutive pages to unlock + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int efc_unlock(size_t page, size_t npages) +{ + size_t start_page; + size_t end_page; + size_t lockpage; + int ret; + + /* Align the page to the lock region */ + + end_page = page + npages; + start_page = page & SAMV7_LOCK_REGION_MASK; + + for (lockpage = start_page; + lockpage < end_page; + lockpage += SAMV7_LOCK_REGION_SIZE) + { + ret = efc_command(FCMD_CLB, lockpage); + if (ret < 0) + { + return ret; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_progmem_initialize + * + * Description: + * Call to initialize FLASH programming memory access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_progmem_initialize(void) +{ + uint32_t regval; + + /* Make sure that the read interrupt is disabled */ + + regval = getreg32(SAM_EEFC_FMR); + regval &= ~EEFC_FMR_FRDY; + putreg32(regval, SAM_EEFC_FMR); + + /* Initialize the semaphore that manages exclusive access to the global + * page buffer. + */ + + sem_init(&g_page_sem, 0, 1); +} + +/**************************************************************************** + * Name: up_progmem_npages + * + * Description: + * Return number of clusters in the available FLASH memory. + * + ****************************************************************************/ + +size_t up_progmem_npages(void) +{ + return SAMV7_PROGMEM_NCLUSTERS; +} + +/**************************************************************************** + * Name: up_progmem_isuniform + * + * Description: + * Cluster size is uniform? Say 'yes' even though that is not strictly + * true do to the odd organization of sector 0. + * + ****************************************************************************/ + +bool up_progmem_isuniform(void) +{ + return true; +} + +/**************************************************************************** + * Name: up_progmem_pagesize + * + * Description: + * Return cluster size + * + ****************************************************************************/ + +size_t up_progmem_pagesize(size_t cluster) +{ + return SAMV7_CLUSTER_SIZE; +} + +/**************************************************************************** + * Name: up_progmem_getpage + * + * Description: + * Address to cluster conversion + * + * Input Parameters: + * address - Address with or without flash offset + * + * Returned Value: + * Page or negative value on error. The following errors are reported + * (errno is not set!): + * + * -EFAULT: On invalid address + * + ****************************************************************************/ + +ssize_t up_progmem_getpage(size_t address) +{ + if (address >= SAMV7_PROGMEM_START) + { + address -= SAMV7_PROGMEM_START; + } + + if (address >= SAMV7_PROGMEM_NBYTES) + { + return -EFAULT; + } + + return address >> SAMV7_CLUSTER_SHIFT; +} + +/**************************************************************************** + * Name: up_progmem_getaddress + * + * Description: + * Cluster to address conversion + * + * Input Parameters: + * cluster - cluster index + * + * Returned Value: + * Base address of given cluster, maximum size if cluster index is not valid. + * + ****************************************************************************/ + +size_t up_progmem_getaddress(size_t cluster) +{ + if (cluster >= SAMV7_PROGMEM_NCLUSTERS) + { + return SAMV7_PROGMEM_NBYTES; + } + + return (cluster << SAMV7_CLUSTER_SHIFT) + SAMV7_PROGMEM_START; +} + +/**************************************************************************** + * Name: up_progmem_erasepage + * + * Description: + * Erase selected cluster. + * + * Input Parameters: + * cluster - cluster index to be erased + * + * Returned Value: + * Page size or negative value on error. The following errors are reported + * (errno is not set!): + * + * -EFAULT: On invalid cluster + * -EIO: On unsuccessful erase + * -EROFS: On access to write protected area + * -EACCES: Insufficient permissions (read/write protected) + * -EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) + * + ****************************************************************************/ + +ssize_t up_progmem_erasepage(size_t cluster) +{ + uint32_t page; + uint32_t arg; + int ret; + + if (cluster >= SAMV7_PROGMEM_NCLUSTERS) + { + return -EFAULT; + } + + /* Get the page number of the start of the cluster */ + + page = SAMV7_CLUST2PAGE((uint32_t)cluster) + SAMV7_PROGMEM_STARTPAGE; + + /* Erase all pages in the cluster */ + + (void)efc_unlock(page, SAMV7_PAGE_PER_CLUSTER); + + /* Get FARG field for EPA command: + * + * The first page to be erased is specified in the FARG[15:2] field of + * the EEFC_FCR register. The first page number must be modulo 4, 8,16 or + * 32 according to the number of pages to erase at the same time. + * + * The 2 lowest bits of the FARG field define the number of pages to + * be erased (FARG[1:0]). + */ + +#if SAMV7_PAGE_PER_CLUSTER == 32 + arg = page | 3; /* Not valid for small 8 KB sectors */ +#elif SAMV7_PAGE_PER_CLUSTER == 16 + arg = page | 2; +#elif SAMV7_PAGE_PER_CLUSTER == 8 +# error Cluster size of 8 not suportted + arg = page | 1; /* 0nly valid for small 8 KB sectors */ +#elif SAMV7_PAGE_PER_CLUSTER == 4 +# error Cluster size of 4 not suportted + arg = page | 0; /* 0nly valid for small 8 KB sectors */ +#else +# error Unsupported/undefined pages-per-cluster size +#endif + + ret = efc_command(FCMD_EPA, arg); + if (ret < 0) + { + return ret; + } + + /* Verify that the cluster of pages is really erased */ + + if (up_progmem_ispageerased(cluster) == 0) + { + return SAMV7_CLUSTER_SIZE; /* Success */ + } + else + { + return -EIO; /* Failure */ + } +} + +/**************************************************************************** + * Name: up_progmem_ispageerased + * + * Description: + * Checks whether cluster is erased + * + * Input Parameters: + * cluster - cluster to be checked + * + * Returned Value: + * Returns number of bytes erased or negative value on error. If it + * returns zero then complete cluster is empty (erased). + * + * The following errors are reported (errno is not set!) + * -EFAULT: On invalid cluster + * + ****************************************************************************/ + +ssize_t up_progmem_ispageerased(size_t cluster) +{ + size_t address; + size_t nwritten; + int nleft; + + if (cluster >= SAMV7_PROGMEM_NCLUSTERS) + { + return -EFAULT; + } + + /* Flush and invalidate nvalidate D-Cache for this address range */ + + address = (cluster << SAMV7_CLUSTER_SHIFT) + SAMV7_PROGMEM_START; + arch_flush_dcache(address, address + SAMV7_CLUSTER_SIZE); + + /* Verify that the cluster is erased (i.e., all 0xff) */ + + for (nleft = SAMV7_CLUSTER_SIZE, nwritten = 0; + nleft > 0; + nleft--, address++) + { + if (getreg8(address) != 0xff) + { + nwritten++; + } + } + + return nwritten; +} + +/**************************************************************************** + * Name: up_progmem_write + * + * Description: + * Program data at given address + * + * Input Parameters: + * address - Address with or without flash offset + * buffer - Pointer to buffer + * buflen - Number of bytes to write + * + * Returned Value: + * Bytes written or negative value on error. The following errors are + * reported (errno is not set!) + * + * EINVAL: If buflen is not aligned with the flash boundaries (i.e. + * some MCU's require per half-word or even word access) + * EFAULT: On invalid address + * EIO: On unsuccessful write + * EROFS: On access to write protected area + * EACCES: Insufficient permissions (read/write protected) + * EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) + * + ****************************************************************************/ + +ssize_t up_progmem_write(size_t address, const void *buffer, size_t buflen) +{ + FAR uint32_t *dest; + FAR const uint32_t *src; + size_t written; + size_t xfrsize; + size_t offset; + size_t page; + size_t i; + int ret; + + /* Convert the address into a FLASH byte offset, if necessary */ + + offset = address; + if (address >= SAMV7_PROGMEM_START) + { + /* Convert address to an offset relative to be beginning of the + * writable FLASH region. + */ + + offset -= SAMV7_PROGMEM_START; + } + + /* Check for valid address range */ + + if ((offset + buflen) > SAMV7_PROGMEM_NBYTES) + { + return -EFAULT; + } + + /* Get the page number corresponding to the flash offset and the byte + * offset into the page. + */ + + page = SAMV7_BYTE2PAGE((uint32_t)offset) + SAMV7_PROGMEM_STARTPAGE; + offset &= SAMV7_PAGE_MASK; + + /* Get exclusive access to the global page buffer */ + + page_buffer_lock(); + + /* Make sure that the FLASH is unlocked */ + + (void)efc_unlock(page, SAMV7_BYTE2PAGE(buflen + SAMV7_PAGE_MASK)); + + /* Loop until all of the data has been written */ + + dest = (FAR uint32_t *)address; + written = 0; + + while (buflen > 0) + { + /* How much can we write into this page? */ + + xfrsize = MIN((size_t)SAMV7_PAGE_SIZE - offset, buflen) ; + + /* Do we need to use the intermediate buffer? */ + + if (offset == 0 && xfrsize == SAMV7_PAGE_SIZE) + { + /* No, we can take the data directly from the user buffer */ + + src = (FAR const uint32_t *)buffer; + } + else + { + /* Yes, copy data into global page buffer */ + + if (offset > 0) + { + memcpy(g_page_buffer, dest, offset); + } + + memcpy((uint8_t *)g_page_buffer + offset, buffer, xfrsize); + + if (offset + xfrsize < SAMV7_PAGE_SIZE) + { + memcpy((uint8_t *)g_page_buffer + offset + xfrsize, + (const uint8_t *)dest + offset + xfrsize, + SAMV7_PAGE_SIZE - offset - xfrsize); + } + + src = g_page_buffer; + } + + /* Write the page */ + + for (i = 0; i < (SAMV7_PAGE_SIZE / sizeof(uint32_t)); i++) + { + *dest++ = *src++; + ARM_DMB(); + } + + /* Flush the data cache to memory */ + + arch_clean_dcache(address, address + SAMV7_PAGE_SIZE); + + /* Send the write command */ + + ret = efc_command(FCMD_WP, page); + if (ret >= 0) + { + written += xfrsize; + } + + /* Adjust pointers and counts for the next time through the loop */ + + address += xfrsize; + dest = (FAR uint32_t *)address; + buffer = (FAR void *)((uintptr_t)buffer + xfrsize); + buflen -= xfrsize; + page++; + } + + page_buffer_unlock(); + return written; +} diff --git a/arch/arm/src/samv7/sam_progmem.h b/arch/arm/src/samv7/sam_progmem.h new file mode 100644 index 0000000000000000000000000000000000000000..6c2deaff7f081a2b3915af4653352e1dd6feacef --- /dev/null +++ b/arch/arm/src/samv7/sam_progmem.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_progmem.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_PROGMEM_H +#define __ARCH_ARM_SRC_SAMV7_SAM_PROGMEM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip/sam_eefc.h" + +#include + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_progmem_initialize + * + * Description: + * Call to initialize FLASH programming memory access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_progmem_initialize(void); + +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_PROGMEM_H */ diff --git a/arch/arm/src/samv7/sam_qspi.c b/arch/arm/src/samv7/sam_qspi.c new file mode 100644 index 0000000000000000000000000000000000000000..e63a6ce22b16a6419c1e71181d49e465bb260caf --- /dev/null +++ b/arch/arm/src/samv7/sam_qspi.c @@ -0,0 +1,1879 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_qspi.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "sam_gpio.h" +#include "sam_xdmac.h" +#include "sam_periphclks.h" +#include "sam_qspi.h" +#include "chip/sam_pmc.h" +#include "chip/sam_xdmac.h" +#include "chip/sam_qspi.h" +#include "chip/sam_pinmap.h" + +#ifdef CONFIG_SAMV7_QSPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAMV7_QSPI_DLYBS +# define CONFIG_SAMV7_QSPI_DLYBS 0 +#endif + +#ifndef CONFIG_SAMV7_QSPI_DLYBCT +# define CONFIG_SAMV7_QSPI_DLYBCT 0 +#endif + +/* When QSPI DMA is enabled, small DMA transfers will still be performed by + * polling logic. But we need a threshold value to determine what is small. + * That value is provided by CONFIG_SAMV7_QSPI_DMATHRESHOLD. + */ + +#ifndef CONFIG_SAMV7_QSPI_DMATHRESHOLD +# define CONFIG_SAMV7_QSPI_DMATHRESHOLD 4 +#endif + +#ifndef CONFIG_SAMV7_XDMAC +# undef CONFIG_SAMV7_QSPI_DMA +#endif + +#ifdef CONFIG_SAMV7_QSPI_DMA +# define SAMV7_QSPI0_DMA true +#endif + +#ifndef CONFIG_SAMV7_QSPI_DMA +# undef CONFIG_SAMV7_QSPI_DMADEBUG +#endif + +/* QSPI interrupts are not used */ + +#undef QSPI_USE_INTERRUPTS + +/* Clocking *****************************************************************/ +/* The QSPI Baud rate clock is generated by dividing the peripheral clock by + * a value between 1 and 255 + */ + +#define SAM_QSPI_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* QSPI memory synchronization */ + +#define MEMORY_SYNC() do { ARM_DSB(); ARM_ISB(); } while (0) + +/* The SAMV7x QSPI driver insists that transfers be performed in multiples + * of 32-bits. The alignment requirement only applies to RX DMA data. + */ + +#define ALIGN_SHIFT 2 +#define ALIGN_MASK 3 +#define ALIGN_UP(n) (((n)+ALIGN_MASK) & ~ALIGN_MASK) +#define IS_ALIGNED(n) (((uint32_t)(n) & ALIGN_MASK) == 0) + +/* Debug *******************************************************************/ +/* Check if QSPI debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_SAMV7_QSPI_DMADEBUG +# undef CONFIG_SAMV7_QSPI_REGDEBUG +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAMV7_QSPI_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define qspidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define qspivdbg lldbg +# else +# define qspivdbg(x...) +# endif +#else +# define qspidbg(x...) +# define qspivdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the QSPI controller. + * + * NOTE: Currently the SAMV7 supports only a single QSPI peripheral. Logic + * here is designed to support multiple QSPI peripherals. + */ + +struct sam_qspidev_s +{ + struct qspi_dev_s qspi; /* Externally visible part of the QSPI interface */ +#ifdef QSPI_USE_INTERRUPTS + xcpt_t handler; /* Interrupt handler */ +#endif + uint32_t base; /* QSPI controller register base address */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t intf; /* QSPI controller number (0) */ +#ifdef QSPI_USE_INTERRUPTS + uint8_t irq; /* Interrupt number */ +#endif + bool initialized; /* TRUE: Controller has been initialized */ + sem_t exclsem; /* Assures mutually exclusive access to QSPI */ + +#ifdef CONFIG_SAMV7_QSPI_DMA + bool candma; /* DMA is supported */ + uint8_t rxintf; /* RX hardware interface number */ + uint8_t txintf; /* TX hardware interface number */ + sem_t dmawait; /* Used to wait for DMA completion */ + WDOG_ID dmadog; /* Watchdog that handles DMA timeouts */ + int result; /* DMA result */ + DMA_HANDLE dmach; /* QSPI DMA handle */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_QSPI_DMADEBUG + struct sam_dmaregs_s dmaregs[DMA_NSAMPLES]; +#endif + +#ifdef CONFIG_SAMV7_QSPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addresslast; /* Last address */ + uint32_t valuelast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAMV7_QSPI_REGDEBUG +static bool qspi_checkreg(struct sam_qspidev_s *priv, bool wr, + uint32_t value, uint32_t address); +#else +# define qspi_checkreg(priv,wr,value,address) (false) +#endif + +static inline uint32_t qspi_getreg(struct sam_qspidev_s *priv, + unsigned int offset); +static inline void qspi_putreg(struct sam_qspidev_s *priv, uint32_t value, + unsigned int offset); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void qspi_dumpregs(struct sam_qspidev_s *priv, const char *msg); +#else +# define qspi_dumpregs(priv,msg) +#endif + +/* DMA support */ + +#ifdef CONFIG_SAMV7_QSPI_DMA +#ifdef CONFIG_SAMV7_QSPI_DMADEBUG +# define qspi_dma_sample(s,i) sam_dmasample((s)->dmach, &(s)->dmaregs[i]) +static void qspi_dma_sampleinit(struct sam_qspidev_s *priv); +static void qspi_dma_sampledone(struct sam_qspidev_s *priv); + +#else +# define qspi_dma_sample(s,i) +# define qspi_dma_sampleinit(s) +# define qspi_dma_sampledone(s) + +#endif + +static void qspi_dma_callback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t qspi_regaddr(struct sam_qspidev_s *priv, + unsigned int offset); +#endif + +static int qspi_memory_enable(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo); +#ifdef CONFIG_SAMV7_QSPI_DMA +static int qspi_memory_dma(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo); +#endif + +static int qspi_memory_nodma(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo); +static void qspi_memcpy(uint8_t *dest, const uint8_t *src, + size_t buflen); + +/* Interrupts */ + +#ifdef QSPI_USE_INTERRUPTS +static int qspi_interrupt(struct sam_qspidev_s *priv); +#ifdef CONFIG_SAMV7_QSPI +static int qspi0_interrupt(int irq, void *context); +#endif +#endif + +/* QSPI methods */ + +static int qspi_lock(struct qspi_dev_s *dev, bool lock); +static uint32_t qspi_setfrequency(struct qspi_dev_s *dev, uint32_t frequency); +static void qspi_setmode(struct qspi_dev_s *dev, enum qspi_mode_e mode); +static void qspi_setbits(struct qspi_dev_s *dev, int nbits); +static int qspi_command(struct qspi_dev_s *dev, + struct qspi_cmdinfo_s *cmdinfo); +static int qspi_memory(struct qspi_dev_s *dev, + struct qspi_meminfo_s *meminfo); +static FAR void *qspi_alloc(FAR struct qspi_dev_s *dev, size_t buflen); +static void qspi_free(FAR struct qspi_dev_s *dev, FAR void *buffer); + +/* Initialization */ + +static int qspi_hw_initialize(struct sam_qspidev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI +/* QSPI0 driver operations */ + +static const struct qspi_ops_s g_qspi0ops = +{ + .lock = qspi_lock, + .setfrequency = qspi_setfrequency, + .setmode = qspi_setmode, + .setbits = qspi_setbits, + .command = qspi_command, + .memory = qspi_memory, + .alloc = qspi_alloc, + .free = qspi_free, +}; + +/* This is the overall state of the QSPI0 controller */ + +static struct sam_qspidev_s g_qspi0dev = +{ + .qspi = + { + .ops = &g_qspi0ops, + }, + .base = SAM_QSPI_BASE, +#ifdef QSPI_USE_INTERRUPTS + .handler = qspi0_interrupt, +#endif + .intf = 0, +#ifdef QSPI_USE_INTERRUPTS + .irq = SAM_IRQ_QSPI, +#endif +#ifdef CONFIG_SAMV7_QSPI_DMA + .candma = SAMV7_QSPI0_DMA, + .rxintf = XDMACH_QSPI_RX, + .txintf = XDMACH_QSPI_TX, +#endif +}; +#endif /* CONFIG_SAMV7_QSPI */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: qspi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_REGDEBUG +static bool qspi_checkreg(struct sam_qspidev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->valuelast && /* Same value? */ + address == priv->addresslast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->valuelast = value; + priv->addresslast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: qspi_getreg + * + * Description: + * Read an QSPI register + * + ****************************************************************************/ + +static inline uint32_t qspi_getreg(struct sam_qspidev_s *priv, + unsigned int offset) +{ + uint32_t address = priv->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMV7_QSPI_REGDEBUG + if (qspi_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: qspi_putreg + * + * Description: + * Write a value to an QSPI register + * + ****************************************************************************/ + +static inline void qspi_putreg(struct sam_qspidev_s *priv, uint32_t value, + unsigned int offset) +{ + uint32_t address = priv->base + offset; + +#ifdef CONFIG_SAMV7_QSPI_REGDEBUG + if (qspi_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: qspi_dumpregs + * + * Description: + * Dump the contents of all QSPI registers + * + * Input Parameters: + * priv - The QSPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void qspi_dumpregs(struct sam_qspidev_s *priv, const char *msg) +{ + qspivdbg("%s:\n", msg); + qspivdbg(" MR:%08x SR:%08x IMR:%08x SCR:%08x\n", + getreg32(priv->base + SAM_QSPI_MR_OFFSET), + getreg32(priv->base + SAM_QSPI_SR_OFFSET), + getreg32(priv->base + SAM_QSPI_IMR_OFFSET), + getreg32(priv->base + SAM_QSPI_SCR_OFFSET)); + qspivdbg(" IAR:%08x ICR:%08x IFR:%08x SMR:%08x\n", + getreg32(priv->base + SAM_QSPI_IAR_OFFSET), + getreg32(priv->base + SAM_QSPI_ICR_OFFSET), + getreg32(priv->base + SAM_QSPI_IFR_OFFSET), + getreg32(priv->base + SAM_QSPI_SMR_OFFSET)); + qspivdbg(" WPCR:%08x WPSR:%08x\n", + getreg32(priv->base + SAM_QSPI_WPCR_OFFSET), + getreg32(priv->base + SAM_QSPI_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: qspi_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMV7_QSPI_DMADEBUG) + * + * Input Parameters: + * priv - QSPI driver instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMADEBUG +static void qspi_dma_sampleinit(struct sam_qspidev_s *priv) +{ + /* Put contents of register samples into a known state */ + + memset(priv->dmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(priv->dmach, &priv->dmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: qspi_dma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * priv - QSPI driver instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMADEBUG +static void qspi_dma_sampledone(struct sam_qspidev_s *priv) +{ + /* Sample the final registers */ + + sam_dmasample(priv->dmach, &priv->dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_INITIAL], + "Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_AFTER_SETUP], + "After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_AFTER_START], + "After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timed out, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + if (priv->result == -ETIMEDOUT) + { + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_TIMEOUT], + "At DMA timeout"); + } + else + { + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_CALLBACK], + "At DMA callback"); + } + + sam_dmadump(priv->dmach, &priv->dmaregs[DMA_END_TRANSFER], + "At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: qspi_dma_timeout + * + * Description: + * The watchdog timeout setup when a has expired without completion of a + * DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMA +static void qspi_dma_timeout(int argc, uint32_t arg) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Sample DMA registers at the time of the timeout */ + + qspi_dma_sample(priv, DMA_CALLBACK); + + /* Report timeout result, perhaps overwriting any failure reports from + * the TX callback. + */ + + priv->result = -ETIMEDOUT; + + /* Then wake up the waiting thread */ + + sem_post(&priv->dmawait); +} +#endif + +/**************************************************************************** + * Name: qspi_dma_callback + * + * Description: + * This callback function is invoked at the completion of the QSPI RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select structure + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMA +static void qspi_dma_callback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->dmadog); + + /* Sample DMA registers at the time of the callback */ + + qspi_dma_sample(priv, DMA_CALLBACK); + + /* Report the result of the transfer only if the TX callback has not already + * reported an error. + */ + + if (priv->result == -EBUSY) + { + /* Save the result of the transfer if no error was previously reported */ + + priv->result = result; + } + + /* Then wake up the waiting thread */ + + sem_post(&priv->dmawait); +} +#endif + +/**************************************************************************** + * Name: qspi_regaddr + * + * Description: + * Return the address of an QSPI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMA +static inline uintptr_t qspi_regaddr(struct sam_qspidev_s *priv, + unsigned int offset) +{ + return priv->base + offset; +} +#endif + +/**************************************************************************** + * Name: qspi_memory_enable + * + * Description: + * Enable the QSPI memory transfer + * + * Input Parameters: + * priv - Device-specific state data + * meminfo - Describes the memory transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +static int qspi_memory_enable(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo) +{ + uint32_t regval; + + /* Write the Instruction code register: + * + * QSPI_ICR_INST(cmd) 8-bit command + * QSPI_ICR_OPT(0) No option + */ + + regval = QSPI_ICR_INST(meminfo->cmd) | QSPI_ICR_OPT(0); + qspi_putreg(priv, regval, SAM_QSPI_ICR_OFFSET); + + /* Is memory data scrambled? */ + + if (QSPIMEM_ISSCRAMBLE(meminfo->flags)) + { + /* Yes.. set the scramble key */ + + qspi_putreg(priv, meminfo->key, SAM_QSPI_SKR_OFFSET); + + /* Enable the scrambler and enable/disable the random value in the + * key. + */ + + regval = QSPI_SMR_SCREN; + if (!QSPIMEM_ISRANDOM(meminfo->flags)) + { + /* Disable random value in key */ + + regval |= QSPI_SMR_RVDIS; + } + + qspi_putreg(priv, 0, SAM_QSPI_SMR_OFFSET); + } + else + { + /* Disable the scrambler */ + + qspi_putreg(priv, 0, SAM_QSPI_SKR_OFFSET); + qspi_putreg(priv, 0, SAM_QSPI_SMR_OFFSET); + } + + /* Write Instruction Frame Register: + * + * QSPI_IFR_WIDTH_? Instruction=single bit/Data depends on meminfo->flags + * QSPI_IFR_INSTEN=1 Instruction Enable + * QSPI_IFR_ADDREN=1 Address Enable + * QSPI_IFR_OPTEN=0 Option Disable + * QSPI_IFR_DATAEN=1 Data Enable + * QSPI_IFR_OPTL_* Not used (zero) + * QSPI_IFR_ADDRL=0/1 Depends on meminfo->addrlen; + * QSPI_IFR_TFRTYP_RD/WRMEM Depends on meminfo->flags + * QSPI_IFR_CRM=0 Not continuous read + * QSPI_IFR_NBDUM Depends on meminfo->dummies + */ + + regval = QSPI_IFR_INSTEN | QSPI_IFR_ADDREN | QSPI_IFR_DATAEN | + QSPI_IFR_NBDUM(meminfo->dummies); + + if (QSPIMEM_ISWRITE(meminfo->flags)) + { + regval |= QSPI_IFR_TFRTYP_WRMEM | QSPI_IFR_WIDTH_SINGLE; + } + else + { + if (QSPIMEM_ISQUADIO(meminfo->flags)) + { + regval |= QSPI_IFR_TFRTYP_RDMEM | QSPI_IFR_WIDTH_QUADIO; + } + else if (QSPIMEM_ISDUALIO(meminfo->flags)) + { + regval |= QSPI_IFR_TFRTYP_RDMEM | QSPI_IFR_WIDTH_DUALIO; + } + else + { + regval |= QSPI_IFR_TFRTYP_RDMEM | QSPI_IFR_WIDTH_SINGLE; + } + } + + if (meminfo->addrlen == 3) + { + regval |= QSPI_IFR_ADDRL_24BIT; + } + else if (meminfo->addrlen == 4) + { + regval |= QSPI_IFR_ADDRL_32BIT; + } + else + { + return -EINVAL; + } + + /* Write the instruction frame value */ + + qspi_putreg(priv, regval, SAM_QSPI_IFR_OFFSET); + (void)qspi_getreg(priv, SAM_QSPI_IFR_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: qspi_memory_dma + * + * Description: + * Perform one QSPI memory transfer using DMA + * + * Input Parameters: + * priv - Device-specific state data + * meminfo - Describes the memory transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_QSPI_DMA +static int qspi_memory_dma(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo) +{ + uintptr_t qspimem = SAM_QSPIMEM_BASE + meminfo->addr; + uint32_t dmaflags; + int ret; + + /* Initialize register sampling */ + + qspi_dma_sampleinit(priv); + + /* Determine DMA flags and setup the DMA */ + + dmaflags = DMACH_FLAG_FIFOCFG_LARGEST | DMACH_FLAG_PERIPHAHB_AHB_IF1 | + DMACH_FLAG_PERIPHISMEMORY | DMACH_FLAG_PERIPHINCREMENT | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | + DMACH_FLAG_MEMAHB_AHB_IF1 | DMACH_FLAG_MEMINCREMENT | + DMACH_FLAG_MEMCHUNKSIZE_1 | DMACH_FLAG_MEMBURST_16; + + if (QSPIMEM_ISWRITE(meminfo->flags)) + { + /* Configure TX DMA */ + + dmaflags |= ((uint32_t)priv->txintf << DMACH_FLAG_PERIPHPID_SHIFT) | + DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_MEMWIDTH_8BITS; + sam_dmaconfig(priv->dmach, dmaflags); + + /* Setup the TX DMA (peripheral-to-memory) */ + + ret = sam_dmatxsetup(priv->dmach, qspimem, (uint32_t)meminfo->buffer, + meminfo->buflen); + } + else + { + /* Configure RX DMA */ + + dmaflags |= ((uint32_t)priv->rxintf << DMACH_FLAG_PERIPHPID_SHIFT) | + DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_MEMWIDTH_32BITS; + sam_dmaconfig(priv->dmach, dmaflags); + + /* Setup the RX DMA (memory-to-peripheral) */ + + ret = sam_dmarxsetup(priv->dmach, qspimem, (uint32_t)meminfo->buffer, + meminfo->buflen); + } + + if (ret < 0) + { + qspidbg("ERROR: DMA setup failed: %d\n", ret); + return ret; + } + + qspi_dma_sample(priv, DMA_AFTER_SETUP); + + /* Enable the memory transfer */ + + qspi_memory_enable(priv, meminfo); + + /* Start the DMA */ + + priv->result = -EBUSY; + ret = sam_dmastart(priv->dmach, qspi_dma_callback, (void *)priv); + if (ret < 0) + { + qspidbg("ERROR: sam_dmastart failed: %d\n", ret); + return ret; + } + + qspi_dma_sample(priv, DMA_AFTER_START); + + /* Wait for DMA completion. This is done in a loop because there may be + * false alarm semaphore counts that cause sam_wait() not fail to wait + * or to wake-up prematurely (for example due to the receipt of a signal). + * We know that the DMA has completed when the result is anything other + * that -EBUSY. + */ + + do + { + /* Start (or re-start) the watchdog timeout */ + + ret = wd_start(priv->dmadog, DMA_TIMEOUT_TICKS, + (wdentry_t)qspi_dma_timeout, 1, (uint32_t)priv); + if (ret != OK) + { + qspidbg("ERROR: wd_start failed: %d\n", ret); + } + + /* Wait for the DMA complete */ + + ret = sem_wait(&priv->dmawait); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->dmadog); + + /* Check if we were awakened by an error of some kind */ + + if (ret < 0) + { + /* EINTR is not a failure. That simply means that the wait + * was awakened by a signal. + */ + + int errorcode = errno; + if (errorcode != EINTR) + { + DEBUGPANIC(); + return -errorcode; + } + } + + /* Not that we might be awakened before the wait is over due to + * residual counts on the semaphore. So, to handle, that case, + * we loop until something changes the DMA result to any value other + * than -EBUSY. + */ + } + while (priv->result == -EBUSY); + + /* Wait until the transmission registers are empty. */ + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_INT_TXEMPTY) == 0); + qspi_putreg(priv, QSPI_CR_LASTXFER, SAM_QSPI_CR_OFFSET); + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_SR_INSTRE) == 0); + MEMORY_SYNC(); + + /* Dump the sampled DMA registers */ + + qspi_dma_sampledone(priv); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + sam_dmastop(priv->dmach); + + /* Complain if the DMA fails */ + + if (priv->result) + { + qspidbg("ERROR: DMA failed with result: %d\n", priv->result); + } + + return priv->result; +} +#endif + +/**************************************************************************** + * Name: qspi_memory_nodma + * + * Description: + * Perform one QSPI memory transfer without using DMA + * + * Input Parameters: + * priv - Device-specific state data + * meminfo - Describes the memory transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +static int qspi_memory_nodma(struct sam_qspidev_s *priv, + struct qspi_meminfo_s *meminfo) +{ + uintptr_t qspimem = SAM_QSPIMEM_BASE + meminfo->addr; + + /* Enable the memory transfer */ + + qspi_memory_enable(priv, meminfo); + + /* Transfer data to/from QSPI memory */ + + if (QSPIMEM_ISWRITE(meminfo->flags)) + { + qspi_memcpy((uint8_t *)qspimem, (const uint8_t *)meminfo->buffer, + meminfo->buflen); + } + else + { + qspi_memcpy((uint8_t *)meminfo->buffer, (const uint8_t *)qspimem, + meminfo->buflen); + } + + MEMORY_SYNC(); + + /* Indicate the end of the transfer as soon as the transmission + * registers are empty. + */ + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_INT_TXEMPTY) == 0); + qspi_putreg(priv, QSPI_CR_LASTXFER, SAM_QSPI_CR_OFFSET); + + /* Wait for the end of the transfer + * + * REVISIT: If DMA is not used then large transfers could come through + * this path. In that case, there would be a benefit to waiting for an + * interrupt to signal the end of the transfer. + */ + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_SR_INSTRE) == 0); + return OK; +} + +/**************************************************************************** + * Name: qspi_memcpy + * + * Description: + * 32-bit version of memcpy. + * + * Input Parameters: + * dest - Destination address of the copy + * src - Source address of the copy + * buflen - The number of 32-bit words to copy. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void qspi_memcpy(uint8_t *dest, const uint8_t *src, size_t buflen) +{ + /* The size of the SPI transfer is equal to the bus access width. + * 8-bit transfers should result in in 8-bit SPI accesses. + */ + + for (; buflen > 0; buflen--) + { + *dest++ = *src++; + } +} + +/**************************************************************************** + * Name: qspi_lock + * + * Description: + * On QSPI buses where there are multiple devices, it will be necessary to + * lock QSPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the QSPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the QSPI is properly + * configured for the device. If the QSPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock QSPI bus, false: unlock QSPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int qspi_lock(struct qspi_dev_s *dev, bool lock) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + + qspivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: qspi_setfrequency + * + * Description: + * Set the QSPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The QSPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t qspi_setfrequency(struct qspi_dev_s *dev, uint32_t frequency) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + uint32_t actual; + uint32_t scbr; +#if CONFIG_SAMV7_QSPI_DLYBS > 0 + uint32_t dlybs; +#endif +#if CONFIG_SAMV7_QSPI_DLYBCT > 0 + uint32_t dlybct; +#endif + uint32_t regval; + + qspivdbg("frequency=%d\n", frequency); + DEBUGASSERT(priv); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* Configure QSPI to a frequency as close as possible to the requested + * frequency. + * + * QSCK frequency = QSPI_CLK / SCBR, or SCBR = QSPI_CLK / frequency + * + * Where SCBR can have the range 1 to 256 and the SCR register field holds + * SCBR - 1. NOTE that a "ceiling" type of calculation is performed. + * 'frequency' is treated as a not-to-exceed value. + */ + + scbr = (frequency + SAM_QSPI_CLOCK - 1) / frequency; + + /* Make sure that the divider is within range */ + + if (scbr < 1) + { + scbr = 1; + } + else if (scbr > 256) + { + scbr = 256; + } + + /* Save the new SCBR value (minus one) */ + + regval = qspi_getreg(priv, SAM_QSPI_SCR_OFFSET); + regval &= ~(QSPI_SCR_SCBR_MASK | QSPI_SCR_DLYBS_MASK); + regval |= (scbr - 1) << QSPI_SCR_SCBR_SHIFT; + + /* DLYBS: Delay Before QSCK. This field defines the delay from NPCS valid to the + * first valid QSCK transition. When DLYBS equals zero, the NPCS valid to QSCK + * transition is 1/2 the QSCK clock period. Otherwise, the following equations + * determine the delay: + * + * Delay Before QSCK = DLYBS / QSPI_CLK + * + * For a 100 nsec delay (assumes QSPI_CLK is an even multiple of MHz): + * + * DLYBS == 100 * QSPI_CLK / 1000000000 + * == (100 * (QSPI_CLK / 1000000)) / 1000 + */ + +#if CONFIG_SAMV7_QSPI_DLYBS > 0 + dlybs = (CONFIG_SAMV7_QSPI_DLYBS * (SAM_QSPI_CLOCK / 1000000)) / 1000; + regval |= dlybs << QSPI_SCR_DLYBS_SHIFT; +#endif + + qspi_putreg(priv, regval, SAM_QSPI_SCR_OFFSET); + + /* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay + * between two consecutive transfers with the same peripheral without removing + * the chip select. The delay is always inserted after each transfer and + * before removing the chip select if needed. + * + * Delay Between Consecutive Transfers = (32 x DLYBCT) / QSPI_CLK + * + * For a 500 nsec delay (assumes QSPI_CLK is an even multiple of MHz): + * + * DLYBCT = 500 * QSPI_CLK / 1000000000 / 32 + * = (500 * (QSPI_CLK / 1000000) / 1000 / 32 + */ + + regval = qspi_getreg(priv, SAM_QSPI_MR_OFFSET); + regval &= ~QSPI_MR_DLYBCT_MASK; + +#if CONFIG_SAMV7_QSPI_DLYBCT > 0 + dlybct = ((CONFIG_SAMV7_QSPI_DLYBCT * (SAM_QSPI_CLOCK /1000000)) / 1000 / 32; + regval |= dlybct << QSPI_MR_DLYBCT_SHIFT; +#endif + + qspi_putreg(priv, regval, SAM_QSPI_MR_OFFSET); + + /* Calculate the new actual frequency */ + + actual = SAM_QSPI_CLOCK / scbr; + qspivdbg("SCBR=%d actual=%d\n", scbr, actual); + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + qspivdbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: qspi_setmode + * + * Description: + * Set the QSPI mode. Optional. See enum qspi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The QSPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void qspi_setmode(struct qspi_dev_s *dev, enum qspi_mode_e mode) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + uint32_t regval; + + qspivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set the mode appropriately: + * + * QSPI CPOL CPHA + * MODE + * 0 0 0 + * 1 0 1 + * 2 1 0 + * 3 1 1 + */ + + regval = qspi_getreg(priv, SAM_QSPI_SCR_OFFSET); + regval &= ~(QSPI_SCR_CPOL | QSPI_SCR_CPHA); + + switch (mode) + { + case QSPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case QSPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= QSPI_SCR_CPHA; + break; + + case QSPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= QSPI_SCR_CPOL; + break; + + case QSPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (QSPI_SCR_CPOL | QSPI_SCR_CPHA); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + qspi_putreg(priv, regval, SAM_QSPI_SCR_OFFSET); + qspivdbg("SCR=%08x\n", regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: qspi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void qspi_setbits(struct qspi_dev_s *dev, int nbits) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + uint32_t regval; + + qspivdbg("nbits=%d\n", nbits); + DEBUGASSERT(priv != NULL); + DEBUGASSERT(nbits >= SAM_QSPI_MINBITS && nbits <= SAM_QSPI_MAXBITS); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set number of bits appropriately */ + + regval = qspi_getreg(priv, SAM_QSPI_MR_OFFSET); + regval &= ~QSPI_MR_NBBITS_MASK; + regval |= QSPI_MR_NBBITS(nbits); + qspi_putreg(priv, regval, SAM_QSPI_MR_OFFSET); + + qspivdbg("MR=%08x\n", regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: qspi_command + * + * Description: + * Perform one QSPI data transfer + * + * Input Parameters: + * dev - Device-specific state data + * cmdinfo - Describes the command transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +static int qspi_command(struct qspi_dev_s *dev, + struct qspi_cmdinfo_s *cmdinfo) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + uint32_t regval; + uint32_t ifr; + + DEBUGASSERT(priv != NULL && cmdinfo != NULL); + +#ifdef CONFIG_DEBUG_SPI + qspivdbg("Transfer:\n"); + qspivdbg(" flags: %02x\n", cmdinfo->flags); + qspivdbg(" cmd: %04x\n", cmdinfo->cmd); + + if (QSPICMD_ISADDRESS(cmdinfo->flags)) + { + qspivdbg(" address/length: %08lx/%d\n", + (unsigned long)cmdinfo->addr, cmdinfo->addrlen); + } + + if (QSPICMD_ISDATA(cmdinfo->flags)) + { + qspivdbg(" %s Data:\n", QSPICMD_ISWRITE(cmdinfo->flags) ? "Write" : "Read"); + qspivdbg(" buffer/length: %p/%d\n", cmdinfo->buffer, cmdinfo->buflen); + } +#endif + + DEBUGASSERT(cmdinfo->cmd < 256); + + /* Write the instruction address register */ + + ifr = 0; + if (QSPICMD_ISADDRESS(cmdinfo->flags)) + { + DEBUGASSERT(cmdinfo->addrlen == 3 || cmdinfo->addrlen == 4); + + /* Set the address in the IAR. This is required only if the + * instruction frame includes an address, but no data. When data is + * preset, the address of the instruction is determined by the address + * of QSPI memory accesses, and not by the content of the IAR. + */ + + qspi_putreg(priv, cmdinfo->addr, SAM_QSPI_IAR_OFFSET); + + /* Set/clear the address enable bit and the address size in the IFR */ + + ifr |= QSPI_IFR_ADDREN; + + if (cmdinfo->addrlen == 3) + { + ifr |= QSPI_IFR_ADDRL_24BIT; + } + else if (cmdinfo->addrlen == 4) + { + ifr |= QSPI_IFR_ADDRL_32BIT; + } + else + { + return -EINVAL; + } + } + + /* Write the Instruction code register: + * + * QSPI_ICR_INST(cmd) 8-bit command + * QSPI_ICR_OPT(0) No option + */ + + regval = QSPI_ICR_INST(cmdinfo->cmd) | QSPI_ICR_OPT(0); + qspi_putreg(priv, regval, SAM_QSPI_ICR_OFFSET); + + /* Does data accompany the command? */ + + if (QSPICMD_ISDATA(cmdinfo->flags)) + { + DEBUGASSERT(cmdinfo->buffer != NULL && cmdinfo->buflen > 0); + DEBUGASSERT(IS_ALIGNED(cmdinfo->buffer)); + + /* Write Instruction Frame Register: + * + * QSPI_IFR_WIDTH_SINGLE Instruction=single bit/Data single bit + * QSPI_IFR_INSTEN=1 Instruction Enable + * QSPI_IFR_ADDREN=? (See logic above) + * QSPI_IFR_OPTEN=0 Option Disable + * QSPI_IFR_DATAEN=1 Data Enable + * QSPI_IFR_OPTL_* Not used (zero) + * QSPI_IFR_ADDRL=0 Not used (zero) + * QSPI_IFR_TFRTYP_WRITE Write transfer into serial memory, OR + * QSPI_IFR_TFRTYP_READ Read transfer from serial memory + * QSPI_IFR_CRM=0 Not continuous read + * QSPI_IFR_NBDUM(0) No dummy cycles + */ + + ifr |= QSPI_IFR_WIDTH_SINGLE | QSPI_IFR_INSTEN | QSPI_IFR_DATAEN | + QSPI_IFR_NBDUM(0); + + /* Read or write operation? */ + + if (QSPICMD_ISWRITE(cmdinfo->flags)) + { + /* Set write data operation + * + * Write the IFR to the hardware. If the instructrion frame + * includes data, writing to the IFR does not trigger the + * instruction frame transfer. Rather, the instruction frame + * is triggered by the first access to QSPI memory. + */ + + ifr |= QSPI_IFR_TFRTYP_WRITE; + qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET); + + /* Read QSPI_IFR (dummy read) to synchronize APB and AHB + * accesses. + */ + + (void)qspi_getreg(priv, SAM_QSPI_IFR_OFFSET); + + /* Copy the data to write to QSPI_RAM */ + + qspi_memcpy((uint8_t *)SAM_QSPIMEM_BASE, + (const uint8_t *)cmdinfo->buffer, cmdinfo->buflen); + } + else + { + /* Set read data operation + * + * Write the IFR to the hardware. If the instructrion frame + * includes data, writing to the IFR does not trigger the + * instruction frame transfer. Rather, the instruction frame + * is triggered by the first access to QSPI memory. + */ + + ifr |= QSPI_IFR_TFRTYP_READ; + qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET); + + /* Read QSPI_IFR (dummy read) to synchronize APB and AHB + * accesses. + */ + + (void)qspi_getreg(priv, SAM_QSPI_IFR_OFFSET); + + /* Copy the data from QSPI memory into the user buffer */ + + qspi_memcpy((uint8_t *)cmdinfo->buffer, + (const uint8_t *)SAM_QSPIMEM_BASE, cmdinfo->buflen); + } + + MEMORY_SYNC(); + + /* Indicate the end of the transfer as soon as the transmission + * registers are empty. + */ + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_INT_TXEMPTY) == 0); + + qspi_putreg(priv, QSPI_CR_LASTXFER, SAM_QSPI_CR_OFFSET); + + /* Fall through to INSTRE wait */ + } + else + { + /* Write Instruction Frame Register: + * + * QSPI_IFR_WIDTH_SINGLE Instruction=single bit/Data single bit + * QSPI_IFR_INSTEN=1 Instruction Enable + * QSPI_IFR_ADDREN=? (See logic above) + * QSPI_IFR_OPTEN=0 Option Disable + * QSPI_IFR_DATAEN=0 Data Disable + * QSPI_IFR_OPTL_* Not used (zero) + * QSPI_IFR_ADDRL=0 Not used (zero) + * QSPI_IFR_TFRTYP_READ Shouldn't matter + * QSPI_IFR_CRM=0 Not continuous read + * QSPI_IFR_NBDUM(0) No dummy cycles + */ + + ifr |= QSPI_IFR_WIDTH_SINGLE | QSPI_IFR_INSTEN | QSPI_IFR_TFRTYP_READ | + QSPI_IFR_NBDUM(0); + qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET); + + MEMORY_SYNC(); + + /* If the insruction frame does not include data, writing to the IFR + * tiggers sending of the instruction frame. Fall through to INSTRE + * wait. + */ + } + + /* When the command has been sent, Instruction End Status (INTRE) will be + * set in the QSPI status register. + */ + + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_SR_INSTRE) == 0); + + return OK; +} + +/**************************************************************************** + * Name: qspi_memory + * + * Description: + * Perform one QSPI memory transfer + * + * Input Parameters: + * dev - Device-specific state data + * meminfo - Describes the memory transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +static int qspi_memory(struct qspi_dev_s *dev, + struct qspi_meminfo_s *meminfo) +{ + struct sam_qspidev_s *priv = (struct sam_qspidev_s *)dev; + + DEBUGASSERT(priv != NULL && meminfo != NULL); + + qspivdbg("Transfer:\n"); + qspivdbg(" flags: %02x\n", meminfo->flags); + qspivdbg(" cmd: %04x\n", meminfo->cmd); + qspivdbg(" address/length: %08lx/%d\n", + (unsigned long)meminfo->addr, meminfo->addrlen); + qspivdbg(" %s Data:\n", QSPIMEM_ISWRITE(meminfo->flags) ? "Write" : "Read"); + qspivdbg(" buffer/length: %p/%d\n", meminfo->buffer, meminfo->buflen); + +#ifdef CONFIG_SAMV7_QSPI_DMA + /* Can we perform DMA? Should we perform DMA? */ + + if (priv->candma && + meminfo->buflen > CONFIG_SAMV7_QSPI_DMATHRESHOLD && + IS_ALIGNED((uintptr_t)meminfo->buffer) && + IS_ALIGNED(meminfo->buflen)) + { + return qspi_memory_dma(priv, meminfo); + } + else +#endif + { + return qspi_memory_nodma(priv, meminfo); + } +} + +/**************************************************************************** + * Name: qspi_alloc + * + * Description: + * Allocate a buffer suitable for DMA data transfer + * + * Input Parameters: + * dev - Device-specific state data + * buflen - Buffer length to allocate in bytes + * + * Returned Value: + * Address of tha allocated memory on success; NULL is returned on any + * failure. + * + ****************************************************************************/ + +static FAR void *qspi_alloc(FAR struct qspi_dev_s *dev, size_t buflen) +{ + /* Here we exploit the internal knowlege the kmm_malloc() will return memory + * aligned to 64-bit addresses. The buffer length must be large enough to + * hold the rested buflen in units a 32-bits. + */ + + return kmm_malloc(ALIGN_UP(buflen)); +} + +/**************************************************************************** + * Name: QSPI_FREE + * + * Description: + * Free memory returned by QSPI_ALLOC + * + * Input Parameters: + * dev - Device-specific state data + * buffer - Buffer previously allocated via QSPI_ALLOC + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void qspi_free(FAR struct qspi_dev_s *dev, FAR void *buffer) +{ + if (buffer) + { + kmm_free(buffer); + } +} + +/**************************************************************************** + * Name: qspi_hw_initialize + * + * Description: + * Initialize the QSPI peripheral from hardware reset. + * + * Input Parameters: + * priv - Device state structure. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +static int qspi_hw_initialize(struct sam_qspidev_s *priv) +{ + uint32_t regval; + + /* Disable the QSPI */ + + qspi_putreg(priv, QSPI_CR_QSPIDIS, SAM_QSPI_CR_OFFSET); + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_SR_QSPIENS) != 0); + + /* Reset the QSPI (twice) */ + + qspi_putreg(priv, QSPI_CR_SWRST, SAM_QSPI_CR_OFFSET); + qspi_putreg(priv, QSPI_CR_SWRST, SAM_QSPI_CR_OFFSET); + + /* Configure the QSPI + * + * QSPI_MR_SMM - Serial Memory Mode + * QSPI_MR_CSMODE_LASTXFER - CS de-asserted when LASTXFER transferred + */ + + regval = QSPI_MR_SMM; + qspi_putreg(priv, regval, SAM_QSPI_MR_OFFSET); + + regval |= QSPI_MR_CSMODE_LASTXFER; + qspi_putreg(priv, regval, SAM_QSPI_MR_OFFSET); + + /* Set up the initial QSPI clock mode: + * + * Mode 0: CPOL=0; CPHA=0 + */ + + regval = qspi_getreg(priv, SAM_QSPI_SCR_OFFSET); + regval &= ~(QSPI_SCR_CPOL | QSPI_SCR_CPHA); + qspi_putreg(priv, regval, SAM_QSPI_SCR_OFFSET); + + regval |= QSPI_SCR_SCBR(1); + qspi_putreg(priv, regval, SAM_QSPI_SCR_OFFSET); + + /* 8-bit mode */ + + regval = qspi_getreg(priv, SAM_QSPI_MR_OFFSET); + regval &= ~QSPI_MR_NBBITS_MASK; + regval |= QSPI_MR_NBBITS_8BIT; + qspi_putreg(priv, regval, SAM_QSPI_MR_OFFSET); + + priv->nbits = 8; + + /* Enable QSPI */ + + qspi_putreg(priv, QSPI_CR_QSPIEN, SAM_QSPI_CR_OFFSET); + while ((qspi_getreg(priv, SAM_QSPI_SR_OFFSET) & QSPI_SR_QSPIENS) == 0); + + /* Flush any pending transfers */ + + (void)qspi_getreg(priv, SAM_QSPI_SR_OFFSET); + (void)qspi_getreg(priv, SAM_QSPI_RDR_OFFSET); + + qspi_dumpregs(priv, "After initialization"); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qspi_initialize + * + * Description: + * Initialize the selected QSPI port in master mode + * + * Input Parameter: + * intf - Interface number(must be zero) + * + * Returned Value: + * Valid QSPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct qspi_dev_s *sam_qspi_initialize(int intf) +{ + struct sam_qspidev_s *priv; + int ret; + + /* The supported SAM parts have only a single QSPI port */ + + qspivdbg("intf: %d\n", intf); + DEBUGASSERT(intf >= 0 && intf < SAMV7_NQSPI); + + /* Select the QSPI interface */ + +#ifdef CONFIG_SAMV7_QSPI + if (intf == 0) + { + /* If this function is called multiple times, the following operatinos + * will be performed multiple times. + */ + + /* Select QSPI0 */ + + priv = &g_qspi0dev; + + /* Enable clocking to the QSPI peripheral */ + + sam_qspi_enableclk(); + + /* Configure multiplexed pins as connected on the board. */ + + sam_configgpio(GPIO_QSPI_CS); + sam_configgpio(GPIO_QSPI_IO0); + sam_configgpio(GPIO_QSPI_IO1); + sam_configgpio(GPIO_QSPI_IO2); + sam_configgpio(GPIO_QSPI_IO3); + sam_configgpio(GPIO_QSPI_SCK); + } + else +#endif + { + qspidbg("ERROR: QSPI%d not supported\n", intf); + return NULL; + } + + /* Has the QSPI hardware been initialized? */ + + if (!priv->initialized) + { + /* No perform one time initialization */ + /* Initialize the QSPI semaphore that enforces mutually exclusive + * access to the QSPI registers. + */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_SAMV7_QSPI_DMA + /* Pre-allocate DMA channels. */ + + if (priv->candma) + { + priv->dmach = sam_dmachannel(0, 0); + if (!priv->dmach) + { + qspidbg("ERROR: Failed to allocate the DMA channel\n"); + priv->candma = false; + } + } + + /* Initialize the QSPI semaphore that is used to wake up the waiting + * thread when the DMA transfer completes. + */ + + sem_init(&priv->dmawait, 0, 0); + + /* Create a watchdog time to catch DMA timeouts */ + + priv->dmadog = wd_create(); + if (priv->dmadog == NULL) + { + qspidbg("ERROR: Failed to create wdog\n"); + goto errout_with_dmahandles; + } +#endif + +#ifdef QSPI_USE_INTERRUPTS + /* Attach the interrupt handler */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret < 0) + { + qspidbg("ERROR: Failed to attach irq %d\n", priv->irq); + goto errout_with_dmadog; + } +#endif + + /* Perform hardware initialization. Puts the QSPI into an active + * state. + */ + + ret = qspi_hw_initialize(priv); + if (ret < 0) + { + qspidbg("ERROR: Failed to initialize QSPI hardware\n"); + goto errout_with_irq; + } + + /* Enable interrupts at the NVIC */ + + priv->initialized = true; +#ifdef QSPI_USE_INTERRUPTS + up_enable_irq(priv->irq); +#endif + } + + return &priv->qspi; + +errout_with_irq: +#ifdef QSPI_USE_INTERRUPTS + irq_detach(priv->irq); + +errout_with_dmadog: +#endif +#ifdef CONFIG_SAMV7_QSPI_DMA + wd_delete(priv->dmadog); + +errout_with_dmahandles: + sem_destroy(&priv->dmawait); + + if (priv->dmach) + { + sam_dmafree(priv->dmach); + priv->dmach = NULL; + } +#endif + + sem_destroy(&priv->exclsem); + return NULL; +} +#endif /* CONFIG_SAMV7_QSPI */ diff --git a/arch/arm/src/samv7/sam_qspi.h b/arch/arm/src/samv7/sam_qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..85d2e57d6594a7a4984d1b14b3337b2e11e659b3 --- /dev/null +++ b/arch/arm/src/samv7/sam_qspi.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_qspi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_QSPI_H +#define __ARCH_ARM_SRC_SAMV7_SAM_QSPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "sam_config.h" + +#ifdef CONFIG_SAMV7_QSPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_qspi_initialize + * + * Description: + * Initialize the selected QSPI port in master mode + * + * Input Parameter: + * intf - Interface number(must be zero) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct qspi_dev_s; +FAR struct qspi_dev_s *sam_qspi_initialize(int intf); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMV7_QSPI */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_QSPI_H */ diff --git a/arch/arm/src/samv7/sam_rswdt.c b/arch/arm/src/samv7/sam_rswdt.c new file mode 100644 index 0000000000000000000000000000000000000000..61593a54c4dcadf39ed753b4c0ac4b3e63b9e99d --- /dev/null +++ b/arch/arm/src/samv7/sam_rswdt.c @@ -0,0 +1,706 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_rswdg.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_wdt.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SAMV7_RSWDT) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The Watchdog Timer uses the Slow Clock divided by 128 to establish the + * maximum Watchdog period to be 16 seconds (with a typical Slow Clock of + * 32768 kHz). + */ + +#ifndef BOARD_SCLK_FREQUENCY +# define BOARD_SCLK_FREQUENCY 32768 +#endif + +#define RSWDT_FREQUENCY (BOARD_SCLK_FREQUENCY / 128) + +/* At 32768Hz, the maximum timeout value will be: + * + * 4096 / RSWDT_FREQUENCY = 256 seconds or 16,000 milliseconds + * + * And the minimum (non-zero) timeout would be: + * + * 1 / RSWDT_FREQUENCY = 3.9 milliseconds + */ + +#define RSWDT_MINTIMEOUT ((1000 + RSWDT_FREQUENCY - 1) / RSWDT_FREQUENCY) +#define RSWDT_MAXTIMEOUT ((4096 * 1000) / RSWDT_FREQUENCY) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct sam_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT + xcpt_t handler; /* Current RSWDT interrupt handler */ +#endif + uint32_t timeout; /* The actual timeout value (milliseconds) */ + uint16_t reload; /* The 12-bit watchdog reload value */ + bool started; /* The timer has been started */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMV7_RSWDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +#else +# define sam_getreg(regaddr) getreg32(regaddr) +# define sam_putreg(regval,regaddr) putreg32(regval,regaddr) +#endif + +/* Interrupt hanlding *******************************************************/ + +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context); +#endif + +/* "Lower half" driver methods **********************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower); +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower); +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler); +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = sam_start, + .stop = sam_stop, + .keepalive = sam_keepalive, + .getstatus = sam_getstatus, + .settimeout = sam_settimeout, + .capture = sam_capture, + .ioctl = sam_ioctl, +}; + +/* "Lower half" driver state */ + +static struct sam_lowerhalf_s g_wdtdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMV7 register + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_RSWDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (regaddr == prevaddr && regval == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return regval; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = regaddr; + preval = regval; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%048\n", regaddr, regval); + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMV7 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_RSWDT_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", regaddr, regval); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * RSWDT early warning interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + /* Is there a registered handler? */ + + if (priv->handler) + { + /* Yes... NOTE: This interrupt service routine (ISR) must reload + * the RSWDT counter to prevent the reset. Otherwise, we will reset + * upon return. + */ + + priv->handler(irq, context); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (RSWDT_MR) can be written only once. Only + * a processor reset resets it. Writing the RSWDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return priv->started ? OK : -ENOSYS; +} + +/**************************************************************************** + * Name: sam_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (RSWDT_MR) can be written only once. Only + * a processor reset resets it. Writing the RSWDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the atchdog timer or "petting the dog". + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + wdvdbg("Entry\n"); + + /* Write RSWDT_CR_WDRSTT to the RSWDT CR regiser (along with the KEY value) + * will restart the watchdog timer. + */ + + sam_putreg(WDT_CR_WDRSTT | RSWDT_CR_KEY, SAM_RSWDT_CR); + return OK; +} + +/**************************************************************************** + * Name: sam_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * stawtus - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT + if (priv->handler) + { + status->flags |= WDFLAGS_CAPTURE; + } +#endif + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the watchdog expires (in milliseconds) + * + * REVISIT: I think this that this information is available. + */ + + status->timeleft = 0; + + wdvdbg("Status :\n"); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in millisecnds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + uint32_t reload; + uint32_t regval; + + DEBUGASSERT(priv); + wdvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < RSWDT_MINTIMEOUT || timeout >= RSWDT_MAXTIMEOUT) + { + wddbg("Cannot represent timeout: %d < %d > %d\n", + RSWDT_MINTIMEOUT, timeout, RSWDT_MAXTIMEOUT); + return -ERANGE; + } + + /* Calculate the reload value to achiee this (appoximate) timeout. + * + * Examples with RSWDT_FREQUENCY = 32768 / 128 = 256: + * timeout = 4 -> reload = 1 + * timeout = 16000 -> reload = 4096 + */ + + reload = (timeout * RSWDT_FREQUENCY + 500) / 1000; + if (reload < 1) + { + reload = 1; + } + else if (reload > 4095) + { + reload = 4095; + } + + /* Calculate and save the actual timeout value in milliseconds: + * + * timeout = 1000 * (reload + 1) / Fwwdg + */ + + priv->timeout = (1000 * reload + RSWDT_FREQUENCY/2) / RSWDT_FREQUENCY; + + /* Remember the selected values */ + + priv->reload = reload; + + wdvdbg("reload=%d timout: %d->%d\n", + reload, timeout, priv->timeout); + + /* Set the RSWDT_MR according to calculated value + * + * NOTE: The Watchdog Mode Register (RSWDT_MR) can be written only once. Only + * a processor reset resets it. Writing the RSWDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + regval = WDT_MR_WDV(reload) | RSWDT_MR_WDD_ALLONES; + +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT + /* Generate an interrupt whent he watchdog timer expires */ + + regval |= WDT_MR_WDFIEN; +#else + /* Reset (everything) if the watchdog timer expires. + * + * REVISIT: Set WDT_MR_WDRPROC so that only the processor is reset? + */ + + regval |= WDT_MR_WDRSTEN; +#endif + +#ifdef CONFIG_SAMV7_RSWDT_DEBUGHALT + /* Halt the watchdog in the debug state */ + + regval |= WDT_MR_WDDBGHLT; +#endif + +#ifdef CONFIG_SAMV7_RSWDT_IDLEHALT + /* Halt the watchdog in the IDLE mode */ + + regval |= WDT_MR_WDIDLEHLT; +#endif + + sam_putreg(regval, SAM_RSWDT_MR); + + /* NOTE: We had to start the watchdog here (because we cannot re-write the + * MR register). So sam_start will not be able to do anything. + */ + + priv->started = true; + + wdvdbg("Setup: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_RSWDT_CR), sam_getreg(SAM_RSWDT_MR), + sam_getreg(SAM_RSWDT_SR)); + + return OK; +} + +/**************************************************************************** + * Name: sam_capture + * + * Description: + * Don't reset on watchdog timer timeout; instead, call this user provider + * timeout handler. NOTE: Providing handler==NULL will restore the reset + * behavior. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new watchdog expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous watchdog expiration function pointer or NULL is there was + * no previous function pointer, i.e., if the previous behavior was + * reset-on-expiration (NULL is also returned if an error occurs). + * + ****************************************************************************/ + +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler) +{ +#ifndef CONFIG_SAMV7_RSWDT_INTERRUPT + wddbg("ERROR: Not configured for this mode\n"); + return NULL; +#else + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + irqstate_t flags; + xcpt_t oldhandler; + + DEBUGASSERT(priv); + wdvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + flags = enter_critical_section(); + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + /* Are we attaching or detaching the handler? */ + + if (handler) + { + /* Attaching... Enable the RSWDT interrupt */ + + up_enable_irq(SAM_IRQ_RSWDT); + } + else + { + /* Detaching... Disable the RSWDT interrupt */ + + up_disable_irq(SAM_IRQ_RSWDT); + } + + leave_critical_section(flags); + return oldhandler; +#endif +} + +/**************************************************************************** + * Name: sam_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctol command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + wdvdbg("cmd=%d arg=%ld\n", cmd, arg); + + /* No ioctls are supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdginitialize + * + * Description: + * Initialize the RSWDT watchdog time. The watchdog timer is initialized and + * registered as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * None + * + * Returned Values: + * None + * + ****************************************************************************/ + +int up_wdginitialize(void) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + wdvdbg("Entry: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_RSWDT_CR), sam_getreg(SAM_RSWDT_MR), + sam_getreg(SAM_RSWDT_SR)); + + /* Check if some previous logic was disabled the watchdog timer. Since the + * MR can be written only one time, we are out of business if that is the + * case. + */ + + DEBUGASSERT((sam_getreg(SAM_RSWDT_MR) & WDT_MR_WDDIS) == 0); + + /* No clock setup is required. The Watchdog Timer uses the Slow Clock + * divided by 128 to establish the maximum Watchdog period to be 16 seconds + * (with a typical Slow Clock of 32768 kHz). + */ + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_wdgops; + +#ifdef CONFIG_SAMV7_RSWDT_INTERRUPT + /* Attach our RSWDT interrupt handler (But don't enable it yet) */ + + (void)irq_attach(SAM_IRQ_RSWDT, sam_interrupt); +#endif + + /* Register the watchdog driver as /dev/rswdt */ + + (void)watchdog_register("/dev/rswdt", + (FAR struct watchdog_lowerhalf_s *)priv); + return OK; +} + +#endif /* CONFIG_WATCHDOG && CONFIG_SAMV7_RSWDT */ diff --git a/arch/arm/src/samv7/sam_serial.c b/arch/arm/src/samv7/sam_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..bb7827ea6366f8eed6d0e7d12c04cf0e80327552 --- /dev/null +++ b/arch/arm/src/samv7/sam_serial.c @@ -0,0 +1,1585 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_serial.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sam_config.h" +#include "chip/sam_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/* Which UART/USART with be tty0/console and which tty1-7? */ + +/* First pick the console and ttys0. This could be any of UART0-4, USART0-2 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_SAMV7_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# define USART0_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# define USART1_ASSIGNED 1 +# elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# define USART2_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-4, USART0-2 excluding the console + * UART. + */ + +#if defined(CONFIG_SAMV7_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-4 or USART0-1. It can't be UART0 + * because that was either assigned as ttyS0 or ttys1. One of these + * could also be the console. + */ + +#if defined(CONFIG_SAMV7_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS2_DEV g_usart0port /* USART0 is ttyS2 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-4 or USART0-2. It can't be UART0-1 + * because those have already been assigned to ttsyS0, 1, or 2. One of + * these could also be the console. + */ + +#if defined(CONFIG_SAMV7_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS3_DEV g_usart0port /* USART0 is ttyS3 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS3_DEV g_usart1port /* USART1 is ttyS3 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS3_DEV g_usart2port /* USART2 is ttyS3 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART3-4 or USART0-2. It can't be UART0-2 + * because those have already been assigned to ttsyS0, 1, 2 or 3. One of + * these could also be the console. + */ + +#if defined(CONFIG_SAMV7_UART3) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart3port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS4_DEV g_usart0port /* USART0 is ttyS4 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS4_DEV g_usart1port /* USART1 is ttyS4 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS4_DEV g_usart2port /* USART2 is ttyS4 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART4 or USART0-2. It can't be UART0-3 + * because those have already been assigned to ttsyS0, 1, 2, 3 or 4. One + * of these could also be the console. + */ + +#if defined(CONFIG_SAMV7_UART4) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS5_DEV g_usart0port /* USART0 is ttyS5 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS5_DEV g_usart1port /* USART1 is ttyS5 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS5_DEV g_usart2port /* USART2 is ttyS5 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys6. This could be one of USART0-2. It can't be UART0-4 + * because those have already been assigned to ttsyS0-5. One of + * One of USART0-2 could also be the console. + */ + +#if defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) && \ + !defined(USART0_ASSIGNED) +# define TTYS6_DEV g_usart0port /* USART0 is ttyS6 */ +# define USART0_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS6_DEV g_usart1port /* USART1 is ttyS6 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS6_DEV g_usart2port /* USART2 is ttyS6 */ +# define USART2_ASSIGNED 1 +#endif + +/* Pick ttys7. This could be one of USART1-2. It can't be UART0-4 + * or USART 1 because those have already been assigned to ttsyS0-6. + * One of of USART1-2 could also be the console. + */ + +#if defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) && \ + !defined(USART1_ASSIGNED) +# define TTYS7_DEV g_usart1port /* USART1 is ttyS7 */ +# define USART1_ASSIGNED 1 +#elif defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) && \ + !defined(USART2_ASSIGNED) +# define TTYS7_DEV g_usart2port /* USART2 is ttyS7 */ +# define USART2_ASSIGNED 1 +#endif + +/* BAUD definitions + * + * The source clock is selectable and could be one of: + * + * - The peripheral clock + * - A division of the peripheral clock, where the divider is product- + * dependent, but generally set to 8 + * - A processor/peripheral independent clock source fully programmable + * provided by PMC (PCK) + * - The external clock, available on the SCK pin + * + * Only the first two options are supported by this driver. The divided + * peripheral clock is only used for very low BAUD selections. + */ + +#define FAST_USART_CLOCK BOARD_MCK_FREQUENCY +#define SLOW_USART_CLOCK (BOARD_MCK_FREQUENCY >> 3) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sam_dev_s +{ + const uint32_t usartbase; /* Base address of USART registers */ + xcpt_t handler; /* Interrupt handler */ + uint32_t baud; /* Configured baud */ + uint32_t sr; /* Saved status bits */ + uint8_t irq; /* IRQ associated with this USART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-9) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; /* input flow control (RTS) enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int sam_setup(struct uart_dev_s *dev); +static void sam_shutdown(struct uart_dev_s *dev); +static int sam_attach(struct uart_dev_s *dev); +static void sam_detach(struct uart_dev_s *dev); +static int sam_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_SAMV7_UART0 +static int sam_uart0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_UART1 +static int sam_uart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_UART2 +static int sam_uart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_UART3 +static int sam_uart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_UART4 +static int sam_uart4_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) +static int sam_usart0_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) +static int sam_usart1_interrupt(int irq, void *context); +#endif +#if defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) +static int sam_usart2_interrupt(int irq, void *context); +#endif +static int sam_ioctl(struct file *filep, int cmd, unsigned long arg); +static int sam_receive(struct uart_dev_s *dev, uint32_t *status); +static void sam_rxint(struct uart_dev_s *dev, bool enable); +static bool sam_rxavailable(struct uart_dev_s *dev); +static void sam_send(struct uart_dev_s *dev, int ch); +static void sam_txint(struct uart_dev_s *dev, bool enable); +static bool sam_txready(struct uart_dev_s *dev); +static bool sam_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = sam_setup, + .shutdown = sam_shutdown, + .attach = sam_attach, + .detach = sam_detach, + .ioctl = sam_ioctl, + .receive = sam_receive, + .rxint = sam_rxint, + .rxavailable = sam_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = sam_send, + .txint = sam_txint, + .txready = sam_txready, + .txempty = sam_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_SAMV7_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMV7_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMV7_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMV7_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_SAMV7_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#if defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#if defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#if defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif + +/* This describes the state of the UART0 port. */ + +#ifdef CONFIG_SAMV7_UART0 +static struct sam_dev_s g_uart0priv = +{ + .usartbase = SAM_UART0_BASE, + .handler = sam_uart0_interrupt, + .baud = CONFIG_UART0_BAUD, + .irq = SAM_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the UART1 port. */ + +#ifdef CONFIG_SAMV7_UART1 +static struct sam_dev_s g_uart1priv = +{ + .usartbase = SAM_UART1_BASE, + .handler = sam_uart1_interrupt, + .baud = CONFIG_UART1_BAUD, + .irq = SAM_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the UART2 port. */ + +#ifdef CONFIG_SAMV7_UART2 +static struct sam_dev_s g_uart2priv = +{ + .usartbase = SAM_UART2_BASE, + .handler = sam_uart2_interrupt, + .baud = CONFIG_UART2_BAUD, + .irq = SAM_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the UART3 port. */ + +#ifdef CONFIG_SAMV7_UART3 +static struct sam_dev_s g_uart3priv = +{ + .usartbase = SAM_UART3_BASE, + .handler = sam_uart3_interrupt, + .baud = CONFIG_UART3_BAUD, + .irq = SAM_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the UART4 port. */ + +#ifdef CONFIG_SAMV7_UART4 +static struct sam_dev_s g_uart4priv = +{ + .usartbase = SAM_UART4_BASE, + .handler = sam_uart4_interrupt, + .baud = CONFIG_UART4_BAUD, + .irq = SAM_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the USART0 port. */ + +#if defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) +static struct sam_dev_s g_usart0priv = +{ + .usartbase = SAM_USART0_BASE, + .handler = sam_usart0_interrupt, + .baud = CONFIG_USART0_BAUD, + .irq = SAM_IRQ_USART0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +#if defined(CONFIG_USART0_OFLOWCONTROL) || defined(CONFIG_USART0_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the USART1 port. */ + +#if defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) +static struct sam_dev_s g_usart1priv = +{ + .usartbase = SAM_USART1_BASE, + .handler = sam_usart1_interrupt, + .baud = CONFIG_USART1_BAUD, + .irq = SAM_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, +#if defined(CONFIG_USART1_OFLOWCONTROL) || defined(CONFIG_USART1_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the USART2 port. */ + +#if defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) +static struct sam_dev_s g_usart2priv = +{ + .usartbase = SAM_USART2_BASE, + .handler = sam_usart2_interrupt, + .baud = CONFIG_USART2_BAUD, + .irq = SAM_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +#if defined(CONFIG_USART2_OFLOWCONTROL) || defined(CONFIG_USART2_IFLOWCONTROL) + .flowc = true, +#endif +}; + +static uart_dev_t g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_serialin + ****************************************************************************/ + +static inline uint32_t sam_serialin(struct sam_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: sam_serialout + ****************************************************************************/ + +static inline void sam_serialout(struct sam_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: sam_restoreusartint + ****************************************************************************/ + +static inline void sam_restoreusartint(struct sam_dev_s *priv, uint32_t imr) +{ + /* Restore the previous interrupt state (assuming all interrupts disabled) */ + + sam_serialout(priv, SAM_UART_IER_OFFSET, imr); +} + +/**************************************************************************** + * Name: sam_disableallints + ****************************************************************************/ + +static void sam_disableallints(struct sam_dev_s *priv, uint32_t *imr) +{ + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + if (imr) + { + /* Return the current interrupt mask */ + + *imr = sam_serialin(priv, SAM_UART_IMR_OFFSET); + } + + /* Disable all interrupts */ + + sam_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_ALLINTS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int sam_setup(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t divb3; + uint32_t intpart; + uint32_t fracpart; + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled and the pins were configured in sam_lowsetup(). + */ + + /* The shutdown method will put the UART in a known, disabled state */ + + sam_shutdown(dev); + + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source + */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + /* "Setting the USART to operate with hardware handshaking is performed by + * writing the USART_MODE field in the Mode Register (US_MR) to the value + * 0x2. ... Using this mode requires using the PDC or DMAC channel for + * reception. The transmitter can handle hardware handshaking in any case." + */ + + if (priv->flowc) + { + /* Enable hardware flow control and MCK as the timing source + * (the divided clock source may be reselected below). + */ + + regval = (UART_MR_MODE_HWHS | UART_MR_USCLKS_MCK); + } + else +#endif + { + /* Set up the mode register. Start with normal UART mode and the MCK + * as the timing source (the divided clock source may be reselected + * below). + */ + + regval = (UART_MR_MODE_NORMAL | UART_MR_USCLKS_MCK); + } + + /* OR in settings for the selected number of bits */ + + if (priv->bits == 5) + { + regval |= UART_MR_CHRL_5BITS; /* 5 bits */ + } + else if (priv->bits == 6) + { + regval |= UART_MR_CHRL_6BITS; /* 6 bits */ + } + else if (priv->bits == 7) + { + regval |= UART_MR_CHRL_7BITS; /* 7 bits */ + } +#ifdef HAVE_UART_DEVICE + else if (priv->bits == 9 +#if defined(CONFIG_SAMV7_UART0) + && priv->usartbase != SAM_UART0_BASE +#endif +#if defined(CONFIG_SAMV7_UART1) + && priv->usartbase != SAM_UART1_BASE +#endif + ) + { + regval |= UART_MR_MODE9; /* 9 bits */ + } +#endif + else /* if (priv->bits == 8) */ + { + regval |= UART_MR_CHRL_8BITS; /* 8 bits (default) */ + } + + /* OR in settings for the selected parity */ + + if (priv->parity == 1) + { + regval |= UART_MR_PAR_ODD; + } + else if (priv->parity == 2) + { + regval |= UART_MR_PAR_EVEN; + } + else + { + regval |= UART_MR_PAR_NONE; + } + + /* OR in settings for the number of stop bits */ + + if (priv->stopbits2) + { + regval |= UART_MR_NBSTOP_2; + } + else + { + regval |= UART_MR_NBSTOP_1; + } + + /* And save the new mode register value */ + + sam_serialout(priv, SAM_UART_MR_OFFSET, regval); + + /* Configure the console baud: + * + * Fbaud = USART_CLOCK / (16 * divisor) + * divisor = USART_CLOCK / (16 * Fbaud) + * + * NOTE: Oversampling by 8 is not supported. This may limit BAUD rates + * for lower USART clocks. + */ + + divb3 = ((FAST_USART_CLOCK + (priv->baud << 3)) << 3) / + (priv->baud << 4); + intpart = divb3 >> 3; + fracpart = divb3 & 7; + + /* Retain the fast MR peripheral clock UNLESS unless using that clock + * would result in an excessively large divider. + * + * REVISIT: The fractional divider is not used. + */ + + if ((intpart & ~UART_BRGR_CD_MASK) != 0) + { + /* Use the divided USART clock */ + + divb3 = ((SLOW_USART_CLOCK + (priv->baud << 3)) << 3) / + (priv->baud << 4); + intpart = divb3 >> 3; + fracpart = divb3 & 7; + + /* Re-select the clock source */ + + regval = sam_serialin(priv, SAM_UART_MR_OFFSET); + regval &= ~UART_MR_USCLKS_MASK; + regval |= UART_MR_USCLKS_MCKDIV; + sam_serialout(priv, SAM_UART_MR_OFFSET, regval); + } + + /* Save the BAUD divider (the fractional part is not used for UARTs) */ + + regval = UART_BRGR_CD(intpart) | UART_BRGR_FP(fracpart); + sam_serialout(priv, SAM_UART_BRGR_OFFSET, regval); + + /* Enable receiver & transmitter */ + + sam_serialout(priv, SAM_UART_CR_OFFSET, (UART_CR_RXEN | UART_CR_TXEN)); +#endif + + return OK; +} + +/**************************************************************************** + * Name: sam_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void sam_shutdown(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + /* Reset and disable receiver and transmitter */ + + sam_serialout(priv, SAM_UART_CR_OFFSET, + (UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | + UART_CR_TXDIS)); + + /* Disable all interrupts */ + + sam_disableallints(priv, NULL); +} + +/**************************************************************************** + * Name: sam_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int sam_attach(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: sam_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void sam_detach(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * This is the common UART/USART interrupt handler. It will be invoked + * when an interrupt received on the device. It should call + * uart_transmitchars or uart_receivechar to perform the appropriate data + * transfers. + * + ****************************************************************************/ + +static int sam_interrupt(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv; + uint32_t pending; + uint32_t imr; + int passes; + bool handled; + + DEBUGASSERT(dev && dev->priv); + priv = (struct sam_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, until we have + * been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the UART/USART status (we are only interested in the unmasked interrupts). */ + + priv->sr = sam_serialin(priv, SAM_UART_SR_OFFSET); + imr = sam_serialin(priv, SAM_UART_IMR_OFFSET); + pending = priv->sr & imr; + + /* Handle an incoming, receive byte. RXRDY: At least one complete character + * has been received and US_RHR has not yet been read. + */ + + if ((pending & UART_INT_RXRDY) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes. TXRDY: There is no character in the + * US_THR. + */ + + if ((pending & UART_INT_TXRDY) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_uart[n]_interrupt + * + * Description: + * UART interrupt handlers + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_UART0 +static int sam_uart0_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_uart0port); +} +#endif +#ifdef CONFIG_SAMV7_UART1 +static int sam_uart1_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_uart1port); +} +#endif +#ifdef CONFIG_SAMV7_UART2 +static int sam_uart2_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_uart2port); +} +#endif +#ifdef CONFIG_SAMV7_UART3 +static int sam_uart3_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_uart3port); +} +#endif +#ifdef CONFIG_SAMV7_UART4 +static int sam_uart4_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_uart4port); +} +#endif + +/**************************************************************************** + * Name: sam_usart[n]_interrupt + * + * Description: + * USART interrupt handlers + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USART0) && defined(CONFIG_USART0_ISUART) +static int sam_usart0_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart0port); +} +#endif +#if defined(CONFIG_SAMV7_USART1) && defined(CONFIG_USART1_ISUART) +static int sam_usart1_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart1port); +} +#endif +#if defined(CONFIG_SAMV7_USART2) && defined(CONFIG_USART2_ISUART) +static int sam_usart2_interrupt(int irq, void *context) +{ + return sam_interrupt(&g_usart2port); +} +#endif + +/**************************************************************************** + * Name: sam_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int sam_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct sam_dev_s *user = (struct sam_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct sam_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Return baud */ + + cfsetispeed(termiosp, priv->baud); + + /* Return parity */ + + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; + + /* Return flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= (priv->flowc) ? (CCTS_OFLOW | CRTS_IFLOW): 0; +#endif + /* Return number of bits */ + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + default: + case 8: + termiosp->c_cflag |= CS8; + break; + + case 9: + termiosp->c_cflag |= CS8 /* CS9 */; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + uint32_t baud; + uint32_t imr; + uint8_t parity; + uint8_t nbits; + bool stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flowc; +#endif + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Decode baud. */ + + ret = OK; + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + nbits = 5; + break; + + case CS6: + nbits = 6; + break; + + case CS7: + nbits = 7; + break; + + case CS8: + nbits = 8; + break; +#if 0 + case CS9: + nbits = 9; + break; +#endif + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) != 0; + + /* Decode flow control */ + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + flowc = (termiosp->c_cflag & (CCTS_OFLOW | CRTS_IFLOW)) != 0; +#endif + /* Verify that all settings are valid before committing */ + + if (ret == OK) + { + /* Commit */ + + priv->baud = baud; + priv->parity = parity; + priv->bits = nbits; + priv->stopbits2 = stop2; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flowc = flowc; +#endif + /* effect the changes immediately - note that we do not + * implement TCSADRAIN / TCSAFLUSH + */ + + sam_disableallints(priv, &imr); + ret = sam_setup(dev); + + /* Restore the interrupt state */ + + sam_restoreusartint(priv, imr); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int sam_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + /* Return the error information in the saved status */ + + *status = priv->sr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return (int)(sam_serialin(priv, SAM_UART_RHR_OFFSET) & 0xff); +} + +/**************************************************************************** + * Name: sam_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void sam_rxint(struct uart_dev_s *dev, bool enable) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + sam_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_RXRDY); +#endif + } + else + { + sam_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_RXRDY); + } +} + +/**************************************************************************** + * Name: sam_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool sam_rxavailable(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + return ((sam_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_RXRDY) != 0); +} + +/**************************************************************************** + * Name: sam_send + * + * Description: + * This method will send one byte on the UART/USART + * + ****************************************************************************/ + +static void sam_send(struct uart_dev_s *dev, int ch) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + sam_serialout(priv, SAM_UART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: sam_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void sam_txint(struct uart_dev_s *dev, bool enable) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + sam_serialout(priv, SAM_UART_IER_OFFSET, UART_INT_TXRDY); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + +#endif + } + else + { + /* Disable the TX interrupt */ + + sam_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_TXRDY); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_txready + * + * Description: + * Return true if the transmit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool sam_txready(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + return ((sam_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXRDY) != 0); +} + +/**************************************************************************** + * Name: sam_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool sam_txempty(struct uart_dev_s *dev) +{ + struct sam_dev_s *priv = (struct sam_dev_s *)dev->priv; + return ((sam_serialin(priv, SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* NOTE: All GPIO configuration for the USARTs was performed in + * sam_lowsetup + */ + + /* Disable all USARTS */ + + sam_disableallints(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + sam_disableallints(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + sam_disableallints(TTYS2_DEV.priv, NULL); +#endif +#ifdef TTYS3_DEV + sam_disableallints(TTYS3_DEV.priv, NULL); +#endif +#ifdef TTYS4_DEV + sam_disableallints(TTYS4_DEV.priv, NULL); +#endif +#ifdef TTYS5_DEV + sam_disableallints(TTYS5_DEV.priv, NULL); +#endif +#ifdef TTYS6_DEV + sam_disableallints(TTYS6_DEV.priv, NULL); +#endif +#ifdef TTYS7_DEV + sam_disableallints(TTYS7_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + sam_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +#ifdef TTYS6_DEV + (void)uart_register("/dev/ttyS6", &TTYS6_DEV); +#endif +#ifdef TTYS7_DEV + (void)uart_register("/dev/ttyS7", &TTYS7_DEV); +#endif +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/samv7/sam_spi.c b/arch/arm/src/samv7/sam_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..0d9f1ec32a114158e17c99b619a4323b251d4b2f --- /dev/null +++ b/arch/arm/src/samv7/sam_spi.c @@ -0,0 +1,1941 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_spi.c + * + * Copyright (C) 2015=2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "sam_gpio.h" +#include "sam_xdmac.h" +#include "sam_periphclks.h" +#include "sam_spi.h" +#include "chip/sam_pmc.h" +#include "chip/sam_xdmac.h" +#include "chip/sam_spi.h" +#include "chip/sam_pinmap.h" + +#ifdef CONFIG_SAMV7_SPI_MASTER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* When SPI DMA is enabled, small DMA transfers will still be performed by + * polling logic. But we need a threshold value to determine what is small. + * That value is provided by CONFIG_SAMV7_SPI_DMATHRESHOLD. + */ + +#ifndef CONFIG_SAMV7_SPI_DMATHRESHOLD +# define CONFIG_SAMV7_SPI_DMATHRESHOLD 4 +#endif + +#ifdef CONFIG_SAMV7_SPI_DMA + +# if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_XDMAC) +# define SAMV7_SPI0_DMA true +# else +# define SAMV7_SPI0_DMA false +# endif + +# if defined(CONFIG_SAMV7_SPI1_MASTER) && defined(CONFIG_SAMV7_XDMAC) +# define SAMV7_SPI1_DMA true +# else +# define SAMV7_SPI1_DMA false +# endif +#endif + +#ifndef CONFIG_SAMV7_SPI_DMA +# undef CONFIG_SAMV7_SPI_DMADEBUG +#endif + +/* Clocking *****************************************************************/ +/* The SPI Baud rate clock is generated by dividing the peripheral clock by + * a value between 1 and 255 + */ + +#define SAM_SPI_CLOCK BOARD_MCK_FREQUENCY /* Frequency of the main clock */ + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* Debug *******************************************************************/ +/* Check if SPI debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_SAMV7_SPI_DMADEBUG +# undef CONFIG_SAMV7_SPI_REGDEBUG +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAMV7_SPI_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the one SPI chip select */ + +struct sam_spics_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + +#if defined(CONFIG_SAMV7_SPI0_MASTER) || defined(CONFIG_SAMV7_SPI1_MASTER) + uint8_t spino; /* SPI controller number (0 or 1) */ +#endif + uint8_t cs; /* Chip select number */ + +#ifdef CONFIG_SAMV7_SPI_DMA + bool candma; /* DMA is supported */ + sem_t dmawait; /* Used to wait for DMA completion */ + WDOG_ID dmadog; /* Watchdog that handles DMA timeouts */ + int result; /* DMA result */ + DMA_HANDLE rxdma; /* SPI RX DMA handle */ + DMA_HANDLE txdma; /* SPI TX DMA handle */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_SPI_DMADEBUG + struct sam_dmaregs_s rxdmaregs[DMA_NSAMPLES]; + struct sam_dmaregs_s txdmaregs[DMA_NSAMPLES]; +#endif +}; + +/* Type of board-specific SPI status function */ + +typedef void (*select_t)(enum spi_dev_e devid, bool selected); + +/* Chip select register offsets */ + +/* The overall state of one SPI controller */ + +struct sam_spidev_s +{ + uint32_t base; /* SPI controller register base address */ + sem_t spisem; /* Assures mutually exclusive access to SPI */ + select_t select; /* SPI select call-out */ + bool initialized; /* TRUE: Controller has been initialized */ +#ifdef CONFIG_SAMV7_SPI_DMA + uint8_t pid; /* SPI peripheral ID */ +#endif + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addresslast; /* Last address */ + uint32_t valuelast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, + uint32_t value, uint32_t address); +#else +# define spi_checkreg(spi,wr,value,address) (false) +#endif + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset); +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset); +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg); +#else +# define spi_dumpregs(spi,msg) +#endif + +static inline void spi_flush(struct sam_spidev_s *spi); +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics); + +/* DMA support */ + +#ifdef CONFIG_SAMV7_SPI_DMA + +#ifdef CONFIG_SAMV7_SPI_DMADEBUG +# define spi_rxdma_sample(s,i) sam_dmasample((s)->rxdma, &(s)->rxdmaregs[i]) +# define spi_txdma_sample(s,i) sam_dmasample((s)->txdma, &(s)->txdmaregs[i]) +static void spi_dma_sampleinit(struct sam_spics_s *spics); +static void spi_dma_sampledone(struct sam_spics_s *spics); + +#else +# define spi_rxdma_sample(s,i) +# define spi_txdma_sample(s,i) +# define spi_dma_sampleinit(s) +# define spi_dma_sampledone(s) + +#endif + +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result); +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result); +static inline uintptr_t spi_regaddr(struct sam_spics_s *spics, + unsigned int offset); +#endif + +/* SPI master methods */ + +static int spi_lock(struct spi_dev_s *dev, bool lock); +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch); +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, + const void *txbuffer, void *rxbuffer, size_t nwords); +#endif +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, + const void *buffer, size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps chip select numbers (0-3 or 1-15) to CSR register offsets */ + +#if defined(CONFIG_SAMV7_SPI_CS_DECODING) +static const uint8_t g_csroffset[16] = +{ + 0, /* the CS counts from 1 to 15 */ + SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, + SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, + SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, + SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET +}; +#else +static const uint8_t g_csroffset[4] = +{ + SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET, + SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET +}; +#endif + +#ifdef CONFIG_SAMV7_SPI0_MASTER +/* SPI0 driver operations */ + +static const struct spi_ops_s g_spi0ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = sam_spi0status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi0cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi0dev = +{ + .base = SAM_SPI0_BASE, + .select = sam_spi0select, +#ifdef CONFIG_SAMV7_SPI_DMA + .pid = SAM_PID_SPI0, +#endif +}; +#endif + +#ifdef CONFIG_SAMV7_SPI1_MASTER +/* SPI1 driver operations */ + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = spi_select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = sam_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = sam_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif + .registercallback = 0, /* Not implemented */ +}; + +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi1dev = +{ + .base = SAM_SPI1_BASE, + .select = sam_spi1select, +#ifdef CONFIG_SAMV7_SPI_DMA + .pid = SAM_PID_SPI1, +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *spi, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == spi->wrlast && /* Same kind of access? */ + value == spi->valuelast && /* Same value? */ + address == spi->addresslast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + spi->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (spi->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", spi->ntimes); + } + + /* Save information about the new access */ + + spi->wrlast = wr; + spi->valuelast = value; + spi->addresslast = address; + spi->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t spi_getreg(struct sam_spidev_s *spi, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + if (spi_checkreg(spi, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value, + unsigned int offset) +{ + uint32_t address = spi->base + offset; + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + if (spi_checkreg(spi, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * spi - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" MR:%08x SR:%08x IMR:%08x\n", + getreg32(spi->base + SAM_SPI_MR_OFFSET), + getreg32(spi->base + SAM_SPI_SR_OFFSET), + getreg32(spi->base + SAM_SPI_IMR_OFFSET)); + spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n", + getreg32(spi->base + SAM_SPI_CSR0_OFFSET), + getreg32(spi->base + SAM_SPI_CSR1_OFFSET), + getreg32(spi->base + SAM_SPI_CSR2_OFFSET), + getreg32(spi->base + SAM_SPI_CSR3_OFFSET)); + spivdbg(" WPCR:%08x WPSR:%08x\n", + getreg32(spi->base + SAM_SPI_WPCR_OFFSET), + getreg32(spi->base + SAM_SPI_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_device + * + * Description: + * Given a chip select instance, return a pointer to the parent SPI + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_spidev_s *spi_device(struct sam_spics_s *spics) +{ +#if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_SPI1_MASTER) + return spics->spino ? &g_spi1dev : &g_spi0dev; +#elif defined(CONFIG_SAMV7_SPI0_MASTER) + return &g_spi0dev; +#else + return &g_spi1dev; +#endif +} + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Make sure that there are now dangling SPI transfer in progress + * + * Input Parameters: + * spi - SPI controller state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_flush(struct sam_spidev_s *spi) +{ + /* Make sure the no TX activity is in progress... waiting if necessary */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TXEMPTY) == 0); + + /* Then make sure that there is no pending RX data .. reading as + * discarding as necessary. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) != 0) + { + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + } +} + +/**************************************************************************** + * Name: spi_cs2pcs + * + * Description: + * Map the chip select number to the bit-set PCS field used in the SPI + * registers. A chip select number is used for indexing and identifying + * chip selects. However, the chip select information is represented by + * a bit set in the SPI registers. This function maps those chip select + * numbers to the correct bit set. + * + * The SAMx7 Processors can handle the chip selects in two different modes. + * The first and default mode assigns one of the four chip select pins + * to one hardware slave. In this mode the function behaviors like: + * + * CS Returned Spec Effective + * No. PCS Value NPCS + * ---- -------- -------- -------- + * 0 0000 xxx0 1110 + * 1 0001 xx01 1101 + * 2 0011 x011 1011 + * 3 0111 0111 0111 + * + * The second mode, activated via CONFIG_SAMV7_SPI_CS_DECODING uses the four + * chip select pins in "encoded mode" which means, that up to 15 slaves can + * be selected via an additional multiplex electronic to decode the values + * represented by the four lines. In that mode this function returns the + * Bitmask the chip select number represents itself. + * + * Input Parameters: + * spics - Device-specific state data + * + * Returned Value: + * Bitmask the pcs part of the SPI data transfer register should be switched + * to for the chip select used. + * + ****************************************************************************/ + +static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics) +{ +#ifndef CONFIG_SAMV7_SPI_CS_DECODING + return ((uint32_t)1 << (spics->cs)) - 1; +#else + return spics->cs; +#endif +} + +/**************************************************************************** + * Name: spi_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMV7_SPI_DMADEBUG) + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMADEBUG +static void spi_dma_sampleinit(struct sam_spics_s *spics) +{ + /* Put contents of register samples into a known state */ + + memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: spi_dma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * spics - Chip select doing the DMA + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMADEBUG +static void spi_dma_sampledone(struct sam_spics_s *spics) +{ + /* Sample the final registers */ + + sam_dmasample(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER]); + sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL], + "TX: Initial Registers"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_INITIAL], + "RX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_SETUP], + "TX: After DMA Setup"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_SETUP], + "RX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_AFTER_START], + "TX: After DMA Start"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_AFTER_START], + "RX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timed out, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_CALLBACK], + "TX: At DMA callback"); + + /* Register values at the end of the DMA */ + + if (spics->result == -ETIMEDOUT) + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_TIMEOUT], + "RX: At DMA timeout"); + } + else + { + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_CALLBACK], + "RX: At DMA callback"); + } + + sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER], + "TX: At End-of-Transfer"); + sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER], + "RX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: spi_dmatimeout + * + * Description: + * The watchdog timeout setup when a has expired without completion of a + * DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_dmatimeout(int argc, uint32_t arg) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Sample DMA registers at the time of the timeout */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report timeout result, perhaps overwriting any failure reports from + * the TX callback. + */ + + spics->result = -ETIMEDOUT; + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_rxcallback + * + * Description: + * This callback function is invoked at the completion of the SPI RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select structure + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Sample DMA registers at the time of the callback */ + + spi_rxdma_sample(spics, DMA_CALLBACK); + + /* Report the result of the transfer only if the TX callback has not already + * reported an error. + */ + + if (spics->result == -EBUSY) + { + /* Save the result of the transfer if no error was previously reported */ + + spics->result = result; + } + + /* Then wake up the waiting thread */ + + sem_post(&spics->dmawait); +} +#endif + +/**************************************************************************** + * Name: spi_txcallback + * + * Description: + * This callback function is invoked at the completion of the SPI TX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select structure + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_txcallback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)arg; + DEBUGASSERT(spics != NULL); + + spi_txdma_sample(spics, DMA_CALLBACK); + + /* Do nothing on the TX callback unless an error is reported. This + * callback is not really important because the SPI exchange is not + * complete until the RX callback is received. + */ + + if (result != OK && spics->result == -EBUSY) + { + /* Save the result of the transfer if an error is reported */ + + spics->result = result; + } +} +#endif + +/**************************************************************************** + * Name: spi_regaddr + * + * Description: + * Return the address of an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMA +static inline uintptr_t spi_regaddr(struct sam_spics_s *spics, + unsigned int offset) +{ + struct sam_spidev_s *spi = spi_device(spics); + return spi->base + offset; +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(struct spi_dev_s *dev, bool lock) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&spi->spisem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&spi->spisem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_select + * + * Description: + * This function does not actually set the chip select line. Rather, it + * simply maps the device ID into a chip select number and retains that + * chip select number for later use. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static void spi_select(struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + + /* Are we selecting or de-selecting the device? */ + + spivdbg("selected=%d\n", selected); + if (selected) + { + spivdbg("cs=%d\n", spics->cs); + + /* Before writing the TDR, the PCS field in the SPI_MR register must be set + * in order to select a slave. + */ + + regval = spi_getreg(spi, SAM_SPI_MR_OFFSET); + regval &= ~SPI_MR_PCS_MASK; + regval |= (spi_cs2pcs(spics) << SPI_MR_PCS_SHIFT); + spi_putreg(spi, regval, SAM_SPI_MR_OFFSET); + } + + /* Perform any board-specific chip select operations. PIO chip select + * pins may be programmed by the board specific logic in one of two + * different ways. First, the pins may be programmed as SPI peripherals. + * In that case, the pins are completely controlled by the SPI driver. + * The sam_spi[0|1]select methods still needs to be provided, but they + * may be only stubs. + * + * An alternative way to program the PIO chip select pins is as normal + * PIO outputs. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + */ + + spi->select(devid, selected); +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t actual; + uint32_t scbr; + uint32_t dlybs; + uint32_t dlybct; + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d frequency=%d\n", spics->cs, frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (spics->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return spics->actual; + } + + /* Configure SPI to a frequency as close as possible to the requested frequency. + * + * SPCK frequency = SPI_CLK / SCBR, or SCBR = SPI_CLK / frequency + */ + + scbr = SAM_SPI_CLOCK / frequency; + + if (scbr < 8) + { + scbr = 8; + } + else if (scbr > 254) + { + scbr = 254; + } + + scbr = (scbr + 1) & ~1; + + /* Save the new scbr value */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK); + regval |= scbr << SPI_CSR_SCBR_SHIFT; + + /* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the + * first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK + * transition is 1/2 the SPCK clock period. Otherwise, the following equations + * determine the delay: + * + * Delay Before SPCK = DLYBS / SPI_CLK + * + * For a 2uS delay + * + * DLYBS = SPI_CLK * 0.000002 = SPI_CLK / 500000 + */ + + dlybs = SAM_SPI_CLOCK / 500000; + regval |= dlybs << SPI_CSR_DLYBS_SHIFT; + + /* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay + * between two consecutive transfers with the same peripheral without removing + * the chip select. The delay is always inserted after each transfer and + * before removing the chip select if needed. + * + * Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK + * + * For a 5uS delay: + * + * DLYBCT = SPI_CLK * 0.000005 / 32 = SPI_CLK / 200000 / 32 + */ + + dlybct = SAM_SPI_CLOCK / 200000 / 32; + regval |= dlybct << SPI_CSR_DLYBCT_SHIFT; + spi_putreg(spi, regval, offset); + + /* Calculate the new actual frequency */ + + actual = SAM_SPI_CLOCK / scbr; + spivdbg("csr[offset=%02x]=%08x actual=%d\n", offset, regval, actual); + + /* Save the frequency setting */ + + spics->frequency = frequency; + spics->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d mode=%d\n", spics->cs, mode); + + /* Has the mode changed? */ + + if (mode != spics->mode) + { + /* Yes... Set the mode appropriately: + * + * SPI CPOL NCPHA + * MODE + * 0 0 1 + * 1 0 0 + * 2 1 1 + * 3 1 0 + */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; NCPHA=1 */ + regval |= SPI_CSR_NCPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; NCPHA=0 */ + break; + + case SPIDEV_MODE2: /* CPOL=1; NCPHA=1 */ + regval |= (SPI_CSR_CPOL | SPI_CSR_NCPHA); + break; + + case SPIDEV_MODE3: /* CPOL=1; NCPHA=0 */ + regval |= SPI_CSR_CPOL; + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(spi, regval, offset); + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + spics->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(struct spi_dev_s *dev, int nbits) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t regval; + unsigned int offset; + + spivdbg("cs=%d nbits=%d\n", spics->cs, nbits); + DEBUGASSERT(spics && nbits > 7 && nbits < 17); + + /* Has the number of bits changed? */ + + if (nbits != spics->nbits) + { + /* Yes... Set number of bits appropriately */ + + offset = (unsigned int)g_csroffset[spics->cs]; + regval = spi_getreg(spi, offset); + regval &= ~SPI_CSR_BITS_MASK; + regval |= SPI_CSR_BITS(nbits); + spi_putreg(spi, regval, offset); + + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + spics->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd) +{ + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange can do this. Note: right now, this only deals with 8-bit + * words. If the SPI interface were configured for words of other sizes, + * this would fail. + */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange(dev, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; +} + +/**************************************************************************** + * Name: spi_exchange (and spi_exchange_nodma) + * + * Description: + * Exchange a block of data from SPI. There are two versions of this + * function: (1) One that is enabled only when CONFIG_SAMV7_SPI_DMA=y + * that performs DMA SPI transfers, but only when a larger block of + * data is being transferred. And (2) another version that does polled + * SPI transfers. When CONFIG_SAMV7_SPI_DMA=n the latter is the only + * version avaialable; when CONFIG_SAMV7_SPI_DMA=y, this version is only + * used for short SPI transfers and gets renamed as spi_exchange_nodma). + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_exchange_nodma(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#else +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +#endif +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t pcs; + uint32_t data; + uint16_t *rxptr16; + uint16_t *txptr16; + uint8_t *rxptr8; + uint8_t *txptr8; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Set up PCS bits */ + + pcs = spi_cs2pcs(spics) << SPI_TDR_PCS_SHIFT; + + /* Set up working pointers */ + + if (spics->nbits > 8) + { + rxptr16 = (uint16_t *)rxbuffer; + txptr16 = (uint16_t *)txbuffer; + rxptr8 = NULL; + txptr8 = NULL; + } + else + { + rxptr16 = NULL; + txptr16 = NULL; + rxptr8 = (uint8_t *)rxbuffer; + txptr8 = (uint8_t *)txbuffer; + } + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Loop, sending each word in the user-provided data buffer. + * + * Note 1: Good SPI performance would require that we implement DMA + * transfers! + * Note 2: This loop might be made more efficient. Would logic + * like the following improve the throughput? Or would it + * just add the risk of overruns? + * + * Get word 1; + * Send word 1; Now word 1 is "in flight" + * nwords--; + * for ( ; nwords > 0; nwords--) + * { + * Get word N. + * Wait for TDRE meaning that word N-1 has moved to the shift + * register. + * Disable interrupts to keep the following atomic + * Send word N. Now both work N-1 and N are "in flight" + * Wait for RDRF meaning that word N-1 is available + * Read word N-1. + * Re-enable interrupts. + * Save word N-1. + * } + * Wait for RDRF meaning that the final word is available + * Read the final word. + * Save the final word. + */ + + for (; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source). */ + + if (txptr8) + { + data = (uint32_t)*txptr8++; + } + else if (txptr16) + { + data = (uint32_t)*txptr16++; + } + else + { + data = 0xffff; + } + + /* Set the PCS field in the value written to the TDR */ + + data |= pcs; + + /* Do we need to set the LASTXFER bit in the TDR value too? */ + +#ifdef CONFIG_SPI_VARSELECT + if (nwords == 1) + { + data |= SPI_TDR_LASTXFER; + } +#endif + + /* Wait for any previous data written to the TDR to be transferred + * to the serializer. + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_TDRE) == 0); + + /* Write the data to transmitted to the Transmit Data Register (TDR) */ + + spi_putreg(spi, data, SAM_SPI_TDR_OFFSET); + + /* Wait for the read data to be available in the RDR. + * TODO: Data transfer rates would be improved using the RX FIFO + * (and also DMA) + */ + + while ((spi_getreg(spi, SAM_SPI_SR_OFFSET) & SPI_INT_RDRF) == 0); + + /* Read the received data from the SPI Data Register. */ + + data = spi_getreg(spi, SAM_SPI_RDR_OFFSET); + if (rxptr8) + { + *rxptr8++ = (uint8_t)data; + } + else if (rxptr16) + { + *rxptr16++ = (uint16_t)data; + } + } +} + +#ifdef CONFIG_SAMV7_SPI_DMA +static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, + void *rxbuffer, size_t nwords) +{ + struct sam_spics_s *spics = (struct sam_spics_s *)dev; + struct sam_spidev_s *spi = spi_device(spics); + uint32_t rxflags; + uint32_t txflags; + uint32_t txdummy; + uint32_t rxdummy; + uint32_t regaddr; + uint32_t memaddr; + uint32_t width; + size_t nbytes; + int ret; + + /* Convert the number of word to a number of bytes */ + + nbytes = (spics->nbits > 8) ? nwords << 1 : nwords; + + /* If we cannot do DMA -OR- if this is a small SPI transfer, then let + * spi_exchange_nodma() do the work. + */ + + if (!spics->candma || nbytes <= CONFIG_SAMV7_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + spics = (struct sam_spics_s *)dev; + spi = spi_device(spics); + DEBUGASSERT(spics && spi); + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(spi); + + /* Sample initial DMA registers */ + + spi_dma_sampleinit(spics); + + /* Select the source and destination width bits */ + + if (spics->nbits > 8) + { + width = (DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_MEMWIDTH_16BITS); + } + else + { + width = (DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_MEMWIDTH_8BITS); + } + + /* Configure the DMA channels. There are four different cases: + * + * 1) A true exchange with the memory address incrementing on both + * RX and TX channels, + * 2) A read operation with the memory address incrementing only on + * the receive channel, + * 3) A write operation where the memory address increments only on + * the receive channel, and + * 4) A corner case where there the memory address does not increment + * on either channel. This case might be used in certain cases + * where you want to assure that certain number of clocks are + * provided on the SPI bus. + */ + + /* Configure the RX DMA channel */ + + rxflags = DMACH_FLAG_FIFOCFG_LARGEST | DMACH_FLAG_PERIPHPID(spi->pid) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | + DMACH_FLAG_MEMCHUNKSIZE_1; + + /* Set the source and destination width bits */ + + rxflags |= width; + + /* Handle the case where there is no sink buffer */ + + if (!rxbuffer) + { + /* No sink data buffer. Point to our dummy buffer and leave + * the rxflags so that no address increment is performed. + */ + + rxbuffer = (void *)&rxdummy; + } + else + { + /* A receive buffer is available. + * + * Invalidate the RX buffer memory to force re-fetching from RAM when + * the DMA completes + */ + + arch_invalidate_dcache((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes); + + /* Use normal RX memory incrementing. */ + + rxflags |= DMACH_FLAG_MEMINCREMENT; + } + + /* Configure the TX DMA channel */ + + txflags = DMACH_FLAG_FIFOCFG_LARGEST | DMACH_FLAG_PERIPHPID(spi->pid) | + DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | + DMACH_FLAG_MEMCHUNKSIZE_1; + + /* Set the source and destination width bits */ + + txflags |= width; + + /* Handle the case where there is no source buffer */ + + if (!txbuffer) + { + /* No source data buffer. Point to our dummy buffer and leave + * the txflags so that no address increment is performed. + */ + + txdummy = 0xffffffff; + txbuffer = (const void *)&txdummy; + } + else + { + /* Source data is available. Use normal TX memory incrementing. */ + + txflags |= DMACH_FLAG_MEMINCREMENT; + } + + /* Then configure the DMA channels to make it so */ + + sam_dmaconfig(spics->rxdma, rxflags); + sam_dmaconfig(spics->txdma, txflags); + + /* Configure the RX side of the exchange transfer */ + + regaddr = spi_regaddr(spics, SAM_SPI_RDR_OFFSET); + memaddr = (uintptr_t)rxbuffer; + + ret = sam_dmarxsetup(spics->rxdma, regaddr, memaddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmarxsetup failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_SETUP); + + /* Configure the TX side of the exchange transfer */ + + regaddr = spi_regaddr(spics, SAM_SPI_TDR_OFFSET); + memaddr = (uintptr_t)txbuffer; + + ret = sam_dmatxsetup(spics->txdma, regaddr, memaddr, nwords); + if (ret < 0) + { + dmadbg("ERROR: sam_dmatxsetup failed: %d\n", ret); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_SETUP); + + /* Start the DMA transfer */ + + spics->result = -EBUSY; + ret = sam_dmastart(spics->rxdma, spi_rxcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + return; + } + + spi_rxdma_sample(spics, DMA_AFTER_START); + + ret = sam_dmastart(spics->txdma, spi_txcallback, (void *)spics); + if (ret < 0) + { + dmadbg("ERROR: RX sam_dmastart failed: %d\n", ret); + sam_dmastop(spics->rxdma); + return; + } + + spi_txdma_sample(spics, DMA_AFTER_START); + + /* Wait for DMA completion. This is done in a loop because there may be + * false alarm semaphore counts that cause sam_wait() not fail to wait + * or to wake-up prematurely (for example due to the receipt of a signal). + * We know that the DMA has completed when the result is anything other + * that -EBUSY. + */ + + do + { + /* Start (or re-start) the watchdog timeout */ + + ret = wd_start(spics->dmadog, DMA_TIMEOUT_TICKS, + (wdentry_t)spi_dmatimeout, 1, (uint32_t)spics); + if (ret != OK) + { + spidbg("ERROR: wd_start failed: %d\n", ret); + } + + /* Wait for the DMA complete */ + + ret = sem_wait(&spics->dmawait); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(spics->dmadog); + + /* Check if we were awakened by an error of some kind */ + + if (ret < 0) + { + /* EINTR is not a failure. That simply means that the wait + * was awakened by a signal. + */ + + int errorcode = errno; + if (errorcode != EINTR) + { + DEBUGPANIC(); + return; + } + } + + /* Not that we might be awakened before the wait is over due to + * residual counts on the semaphore. So, to handle, that case, + * we loop until something changes the DMA result to any value other + * than -EBUSY. + */ + } + while (spics->result == -EBUSY); + + /* Dump the sampled DMA registers */ + + spi_dma_sampledone(spics); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + sam_dmastop(spics->rxdma); + sam_dmastop(spics->txdma); + + /* All we can do is complain if the DMA fails */ + + if (spics->result) + { + spidbg("ERROR: DMA failed with result: %d\n", spics->result); + } +} +#endif /* CONFIG_SAMV7_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, + size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port in master mode + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *sam_spibus_initialize(int port) +{ + FAR struct sam_spidev_s *spi; + FAR struct sam_spics_s *spics; + int csno = (port & __SPI_CS_MASK) >> __SPI_CS_SHIFT; + int spino = (port & __SPI_SPI_MASK) >> __SPI_SPI_SHIFT; + irqstate_t flags; + uint32_t regval; + unsigned int offset; + + /* The support SAM parts have only a single SPI port */ + + spivdbg("port: %d csno: %d spino: %d\n", port, csno, spino); + DEBUGASSERT(csno >= 0 && csno <= SAM_SPI_NCS); + +#if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_SPI1_MASTER) + DEBUGASSERT(spino >= 0 && spino <= 1); +#elif defined(CONFIG_SAMV7_SPI0_MASTER) + DEBUGASSERT(spino == 0); +#else + DEBUGASSERT(spino == 1); +#endif + + /* Allocate a new state structure for this chip select. NOTE that there + * is no protection if the same chip select is used in two different + * chip select structures. + */ + + spics = (struct sam_spics_s *)zalloc(sizeof(struct sam_spics_s)); + if (!spics) + { + spidbg("ERROR: Failed to allocate a chip select structure\n"); + return NULL; + } + + /* Set up the initial state for this chip select structure. Other fields + * were zeroed by zalloc(). + */ + +#ifdef CONFIG_SAMV7_SPI_DMA + /* Can we do DMA on this peripheral? */ + + spics->candma = spino ? SAMV7_SPI1_DMA : SAMV7_SPI0_DMA; + + /* Pre-allocate DMA channels. */ + + if (spics->candma) + { + spics->rxdma = sam_dmachannel(0, 0); + if (!spics->rxdma) + { + spidbg("ERROR: Failed to allocate the RX DMA channel\n"); + spics->candma = false; + } + } + + if (spics->candma) + { + spics->txdma = sam_dmachannel(0, 0); + if (!spics->txdma) + { + spidbg("ERROR: Failed to allocate the TX DMA channel\n"); + sam_dmafree(spics->rxdma); + spics->rxdma = NULL; + spics->candma = false; + } + } +#endif + + /* Select the SPI operations */ + +#if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_SPI1_MASTER) + spics->spidev.ops = spino ? &g_spi1ops : &g_spi0ops; +#elif defined(CONFIG_SAMV7_SPI0_MASTER) + spics->spidev.ops = &g_spi0ops; +#else + spics->spidev.ops = &g_spi1ops; +#endif + + /* Save the chip select and SPI controller numbers */ + + spics->cs = csno; +#if defined(CONFIG_SAMV7_SPI0_MASTER) || defined(CONFIG_SAMV7_SPI1_MASTER) + spics->spino = spino; +#endif + + /* Get the SPI device structure associated with the chip select */ + + spi = spi_device(spics); + + /* Has the SPI hardware been initialized? */ + + if (!spi->initialized) + { + /* Enable clocking to the SPI block */ + + flags = enter_critical_section(); +#if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_SPI1_MASTER) + if (spino == 0) +#endif +#if defined(CONFIG_SAMV7_SPI0_MASTER) + { + sam_spi0_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configgpio(GPIO_SPI0_MISO); + sam_configgpio(GPIO_SPI0_MOSI); + sam_configgpio(GPIO_SPI0_SPCK); + } +#endif +#if defined(CONFIG_SAMV7_SPI0_MASTER) && defined(CONFIG_SAMV7_SPI1_MASTER) + else +#endif +#if defined(CONFIG_SAMV7_SPI1_MASTER) + { + sam_spi1_enableclk(); + + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + + sam_configgpio(GPIO_SPI1_MISO); + sam_configgpio(GPIO_SPI1_MOSI); + sam_configgpio(GPIO_SPI1_SPCK); + } +#endif + + /* Disable SPI clocking */ + + spi_putreg(spi, SPI_CR_SPIDIS, SAM_SPI_CR_OFFSET); + + /* Execute a software reset of the SPI (twice) */ + + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + spi_putreg(spi, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + leave_critical_section(flags); + + /* Configure the SPI mode register */ + +#if defined(CONFIG_SAMV7_SPI_CS_DECODING) + /* Enable Peripheral Chip Select Decoding? */ + + spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCSDEC, + SAM_SPI_MR_OFFSET); +#else + spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS, SAM_SPI_MR_OFFSET); +#endif + + /* And enable the SPI */ + + spi_putreg(spi, SPI_CR_SPIEN, SAM_SPI_CR_OFFSET); + up_mdelay(20); + + /* Flush any pending transfers */ + + (void)spi_getreg(spi, SAM_SPI_SR_OFFSET); + (void)spi_getreg(spi, SAM_SPI_RDR_OFFSET); + + /* Initialize the SPI semaphore that enforces mutually exclusive + * access to the SPI registers. + */ + + sem_init(&spi->spisem, 0, 1); + spi->initialized = true; + +#ifdef CONFIG_SAMV7_SPI_DMA + /* Initialize the SPI semaphore that is used to wake up the waiting + * thread when the DMA transfer completes. + */ + + sem_init(&spics->dmawait, 0, 0); + + /* Create a watchdog time to catch DMA timeouts */ + + spics->dmadog = wd_create(); + DEBUGASSERT(spics->dmadog); +#endif + + spi_dumpregs(spi, "After initialization"); + } + + /* Set to mode=0 and nbits=8 and impossible frequency. The SPI will only + * be reconfigured if there is a change. + */ + + offset = (unsigned int)g_csroffset[csno]; + regval = spi_getreg(spi, offset); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK); + regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8)); + spi_putreg(spi, regval, offset); + + spics->nbits = 8; + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + return &spics->spidev; +} +#endif /* CONFIG_SAMV7_SPI_MASTER */ diff --git a/arch/arm/src/samv7/sam_spi.h b/arch/arm/src/samv7/sam_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..dded6425348497f87b016f548c9f7b7b8778317f --- /dev/null +++ b/arch/arm/src/samv7/sam_spi.h @@ -0,0 +1,326 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_spi.h + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_SPI_H +#define __ARCH_ARM_SRC_SAMV7_SAM_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "sam_config.h" + +#ifdef CONFIG_SAMV7_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The SPI port number used as an input to sam_spibus_initialize encodes + * information about the SPI controller (0 or 1) and the SPI chip select + * (0-3). + * + * NOTE that this is this is backward compatible with older implementations + * that support only SPI0 and provide only the chip select number to + * sam_spibus_initialize(). + */ + +#ifdef CONFIG_SAMV7_SPI_CS_DECODING + +# define __SPI_CS_SHIFT (0) /* Bits 0-3: SPI chip select number */ +# define __SPI_CS_MASK (15 << __SPI_CS_SHIFT) + +# define __SPI_SPI_SHIFT (4) /* Bit 4: SPI controller number */ +# define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT) +# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */ +# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */ + +# define SPI0_CS1 (__SPI_SPI0 | 1) +# define SPI0_CS2 (__SPI_SPI0 | 2) +# define SPI0_CS3 (__SPI_SPI0 | 3) +# define SPI0_CS4 (__SPI_SPI0 | 4) +# define SPI0_CS5 (__SPI_SPI0 | 5) +# define SPI0_CS6 (__SPI_SPI0 | 6) +# define SPI0_CS7 (__SPI_SPI0 | 7) +# define SPI0_CS8 (__SPI_SPI0 | 8) +# define SPI0_CS9 (__SPI_SPI0 | 9) +# define SPI0_CS10 (__SPI_SPI0 | 10) +# define SPI0_CS11 (__SPI_SPI0 | 11) +# define SPI0_CS12 (__SPI_SPI0 | 12) +# define SPI0_CS13 (__SPI_SPI0 | 13) +# define SPI0_CS14 (__SPI_SPI0 | 14) +# define SPI0_CS15 (__SPI_SPI0 | 15) + +# define SPI1_CS1 (__SPI_SPI1 | 1) +# define SPI1_CS2 (__SPI_SPI1 | 2) +# define SPI1_CS3 (__SPI_SPI1 | 3) +# define SPI1_CS4 (__SPI_SPI1 | 4) +# define SPI1_CS5 (__SPI_SPI1 | 5) +# define SPI1_CS6 (__SPI_SPI1 | 6) +# define SPI1_CS7 (__SPI_SPI1 | 7) +# define SPI1_CS8 (__SPI_SPI1 | 8) +# define SPI1_CS9 (__SPI_SPI1 | 9) +# define SPI1_CS10 (__SPI_SPI1 | 10) +# define SPI1_CS11 (__SPI_SPI1 | 11) +# define SPI1_CS12 (__SPI_SPI1 | 12) +# define SPI1_CS13 (__SPI_SPI1 | 13) +# define SPI1_CS14 (__SPI_SPI1 | 14) +# define SPI1_CS15 (__SPI_SPI1 | 15) + +#else /* CONFIG_SAMV7_SPI_CS_DECODING */ + +# define __SPI_CS_SHIFT (0) /* Bits 0-1: SPI chip select number */ +# define __SPI_CS_MASK (3 << __SPI_CS_SHIFT) +# define __SPI_CS0 (0 << __SPI_CS_SHIFT) +# define __SPI_CS1 (1 << __SPI_CS_SHIFT) +# define __SPI_CS2 (2 << __SPI_CS_SHIFT) +# define __SPI_CS3 (3 << __SPI_CS_SHIFT) +# define __SPI_SPI_SHIFT (2) /* Bit 2: SPI controller number */ +# define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT) +# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */ +# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */ + +# define SPI0_CS0 (__SPI_SPI0 | __SPI_CS0) +# define SPI0_CS1 (__SPI_SPI0 | __SPI_CS1) +# define SPI0_CS2 (__SPI_SPI0 | __SPI_CS2) +# define SPI0_CS3 (__SPI_SPI0 | __SPI_CS3) + +# define SPI1_CS0 (__SPI_SPI1 | __SPI_CS0) +# define SPI1_CS1 (__SPI_SPI1 | __SPI_CS1) +# define SPI1_CS2 (__SPI_SPI1 | __SPI_CS2) +# define SPI1_CS3 (__SPI_SPI1 | __SPI_CS3) + +#endif /* CONFIG_SAMV7_SPI_CS_DECODING */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ +struct spi_sctrlr_s; /* Forward reference */ + +/**************************************************************************** + * Name: sam_spibus_initialize + * + * Description: + * Initialize the selected SPI port in master mode + * + * Input Parameter: + * cs - Chip select number (identifying the "logical" SPI port) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *sam_spibus_initialize(int port); + +/**************************************************************************** + * Name: sam_spi_slave_initialize + * + * Description: + * Initialize the selected SPI port in slave mode. + * + * Input Parameter: + * port - Chip select number identifying the "logical" SPI port. Includes + * encoded port and chip select information. + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_sctrlr_s *sam_spi_slave_initialize(int port); + +/**************************************************************************** + * Name: sam_spi[0|1]select, sam_spi[0|1]status, and sam_spi[0|1]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. + * They include: + * + * o sam_spi[0|1]select is a functions to manage the board-specific chip + * selects + * o sam_spi[0|1]status and sam_spi[0|1]cmddata: Implementations of the + * status and cmddata methods of the SPI interface defined by struct + * spi_ops_ (see include/nuttx/spi/spi.h). All other methods including + * sam_spibus_initialize()) are provided by common SAM3/4 logic. + * + * To use this common SPI logic on your board: + * + * 1. Provide logic in sam_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in + * our board-specific logic. These functions will perform chip selection + * and status operations using PIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * sam_spi[0|1]cmddata() functions in your board-specific logic. This + * function will perform cmd/data selection operations using PIOs in + * the way your board is configured. + * 3. Add a call to sam_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by sam_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spi[0|1]select + * + * Description: + * PIO chip select pins may be programmed by the board specific logic in + * one of two different ways. First, the pins may be programmed as SPI + * peripherals. In that case, the pins are completely controlled by the + * SPI driver. This method still needs to be provided, but it may be only + * a stub. + * + * An alternative way to program the PIO chip select pins is as a normal + * PIO output. In that case, the automatic control of the CS pins is + * bypassed and this function must provide control of the chip select. + * NOTE: In this case, the PIO output pin does *not* have to be the + * same as the NPCS pin normal associated with the chip select number. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * selected - TRUE:Select the device, FALSE:De-select the device + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI0_MASTER +void sam_spi0select(enum spi_dev_e devid, bool selected); +#endif +#ifdef CONFIG_SAMV7_SPI1_MASTER +void sam_spi1select(enum spi_dev_e devid, bool selected); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]status + * + * Description: + * Return status information associated with the SPI device. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Bit-encoded SPI status (see include/nuttx/spi/spi.h. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI0 +uint8_t sam_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif +#ifdef CONFIG_SAMV7_SPI1 +uint8_t sam_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#endif + +/**************************************************************************** + * Name: sam_spi[0|1]cmddata + * + * Description: + * Some SPI devices require an additional control to determine if the SPI + * data being sent is a command or is data. If CONFIG_SPI_CMDDATA then + * this function will be called to different be command and data transfers. + * + * This is often needed, for example, by LCD drivers. Some LCD hardware + * may be configured to use 9-bit data transfers with the 9th bit + * indicating command or data. That same hardware may be configurable, + * instead, to use 8-bit data but to require an additional, board- + * specific PIO control to distinguish command and data. This function + * would be needed in that latter case. + * + * Input Parameters: + * dev - SPI device info + * devid - Identifies the (logical) device + * + * Returned Values: + * Zero on success; a negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_SAMV7_SPI0_MASTER +int sam_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#ifdef CONFIG_SAMV7_SPI1_MASTER +int sam_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif /* CONFIG_SPI_CMDDATA */ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SAMV7_SPI */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_SPI_H */ diff --git a/arch/arm/src/samv7/sam_spi_slave.c b/arch/arm/src/samv7/sam_spi_slave.c new file mode 100644 index 0000000000000000000000000000000000000000..a210541ce695f19126de993a8660928f42752629 --- /dev/null +++ b/arch/arm/src/samv7/sam_spi_slave.c @@ -0,0 +1,1294 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_spi_slave.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" + +#include "sam_config.h" +#include "sam_gpio.h" +#include "sam_periphclks.h" +#include "sam_spi.h" + +#include "chip/sam_spi.h" +#include "chip/sam_pinmap.h" +#include + +#ifdef CONFIG_SAMV7_SPI_SLAVE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SAMV7_SPI_SLAVE_QSIZE +# define CONFIG_SAMV7_SPI_SLAVE_QSIZE 8 +#endif + +/* Debug *******************************************************************/ +/* Check if SPI debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The overall state of one SPI controller */ + +struct sam_spidev_s +{ + struct spi_sctrlr_s sctrlr; /* Externally visible part of the SPI slave + * controller interface */ + struct spi_sdev_s *sdev; /* Bound SPI slave device interface */ + xcpt_t handler; /* SPI interrupt handler */ + uint32_t base; /* SPI controller register base address */ + sem_t spisem; /* Assures mutually exclusive access to SPI */ + uint16_t outval; /* Default shift-out value */ + uint16_t irq; /* SPI IRQ number */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t spino; /* SPI controller number (0 or 1) */ + bool initialized; /* True: Controller has been initialized */ + bool nss; /* True: Chip selected */ + + /* Output queue */ + + uint8_t head; /* Location of next value */ + uint8_t tail; /* Index of first value */ + + uint16_t outq[CONFIG_SAMV7_SPI_SLAVE_QSIZE]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addresslast; /* Last address */ + uint32_t valuelast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, + uint32_t value, uint32_t address); +#else +# define spi_checkreg(priv,wr,value,address) (false) +#endif + +static uint32_t spi_getreg(struct sam_spidev_s *priv, + unsigned int offset); +static void spi_putreg(struct sam_spidev_s *priv, uint32_t value, + unsigned int offset); + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg); +#else +# define spi_dumpregs(priv,msg) +#endif + +static void spi_semtake(struct sam_spidev_s *priv); +#define spi_semgive(priv) (sem_post(&(priv)->spisem)) + +/* Interrupt Handling */ + +static int spi_interrupt(struct sam_spidev_s *priv); +#ifdef CONFIG_SAMV7_SPI0_SLAVE +static int spi0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_SAMV7_SPI1_SLAVE +static int spi1_interrupt(int irq, void *context); +#endif + +/* SPI Helpers */ + +static uint16_t spi_dequeue(struct sam_spidev_s *priv); +static void spi_setmode(struct sam_spidev_s *priv, + enum spi_smode_e mode); +static void spi_setbits(struct sam_spidev_s *priv, + int nbits); + +/* SPI slave controller methods */ + +static void spi_bind(struct spi_sctrlr_s *sctrlr, + struct spi_sdev_s *sdev, enum spi_smode_e mode, + int nbits); +static void spi_unbind(struct spi_sctrlr_s *sctrlr); +static int spi_enqueue(struct spi_sctrlr_s *sctrlr, uint16_t data); +static bool spi_qfull(struct spi_sctrlr_s *sctrlr); +static void spi_qflush(struct spi_sctrlr_s *sctrlr); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps chip select numbers (0-3) to CSR register offsets */ + +static const uint8_t g_csroffset[4] = +{ + SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET, + SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET +}; + +/* SPI slave controller driver operations */ + +static const struct spi_sctrlrops_s g_sctrlr_ops = +{ + .bind = spi_bind, + .unbind = spi_unbind, + .enqueue = spi_enqueue, + .qfull = spi_qfull, + .qflush = spi_qflush, +}; + +#ifdef CONFIG_SAMV7_SPI0_SLAVE +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi0_sctrlr; +#endif + +#ifdef CONFIG_SAMV7_SPI1_SLAVE +/* This is the overall state of the SPI0 controller */ + +static struct sam_spidev_s g_spi1_sctrlr; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG +static bool spi_checkreg(struct sam_spidev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->valuelast && /* Same value? */ + address == priv->addresslast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->valuelast = value; + priv->addresslast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static uint32_t spi_getreg(struct sam_spidev_s *priv, unsigned int offset) +{ + uint32_t address = priv->base + offset; + uint32_t value = getreg32(address); + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + if (spi_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } +#endif + + return value; +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static void spi_putreg(struct sam_spidev_s *priv, uint32_t value, + unsigned int offset) +{ + uint32_t address = priv->base + offset; + +#ifdef CONFIG_SAMV7_SPI_REGDEBUG + if (spi_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } +#endif + + putreg32(value, address); +} + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * priv - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(struct sam_spidev_s *priv, const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" MR:%08x SR:%08x IMR:%08x\n", + getreg32(priv->base + SAM_SPI_MR_OFFSET), + getreg32(priv->base + SAM_SPI_SR_OFFSET), + getreg32(priv->base + SAM_SPI_IMR_OFFSET)); + spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n", + getreg32(priv->base + SAM_SPI_CSR0_OFFSET), + getreg32(priv->base + SAM_SPI_CSR1_OFFSET), + getreg32(priv->base + SAM_SPI_CSR2_OFFSET), + getreg32(priv->base + SAM_SPI_CSR3_OFFSET)); + spivdbg(" WPCR:%08x WPSR:%08x\n", + getreg32(priv->base + SAM_SPI_WPCR_OFFSET), + getreg32(priv->base + SAM_SPI_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_semtake + * + * Description: + * Take the semaphore that enforces mutually exclusive access to SPI + * resources, handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the MCAN peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_semtake(struct sam_spidev_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->spisem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: spi_interrupt + * + * Description: + * Common SPI interrupt handler + * + * Input Parameters: + * priv - SPI controller CS state + * + * Returned Value: + * Standard interrupt return value. + * + ****************************************************************************/ + +static int spi_interrupt(struct sam_spidev_s *priv) +{ + uint32_t sr; + uint32_t imr; + uint32_t pending; + uint32_t regval; + + /* We loop because the TDRE interrupt will probably immediately follow the + * RDRF interrupt and we might be able to catch it in this handler + * execution. + */ + + for (; ; ) + { + /* Get the current set of pending/enabled interrupts */ + + sr = spi_getreg(priv, SAM_SPI_SR_OFFSET); + imr = spi_getreg(priv, SAM_SPI_IMR_OFFSET); + pending = sr & imr; + + /* Return from the interrupt handler when all pending interrupts have + * been processed. + */ + + if (pending == 0) + { + return OK; + } + + /* TThe SPI waits until NSS goes active before receiving the serial + * clock from an external master. When NSS falls, the clock is + * validated and the data is loaded in the SPI_RDR depending on the + * BITS field configured in the SPI_CSR0. These bits are processed + * following a phase and a polarity defined respectively by the NCPHA + * and CPOL bits in the SPI_CSR0. + * + * When all bits are processed, the received data is transferred in + * the SPI_RDR and the RDRF bit rises. If the SPI_RDR has not been + * read before new data is received, the Overrun Error Status (OVRES) + * bit in the SPI_SR is set. As long as this flag is set, data is + * loaded in the SPI_RDR. The user must read SPI_SR to clear the OVRES + * bit. + */ + +#ifdef CONFIG_DEBUG_SPI + /* Check the RX data overflow condition */ + + if ((pending & SPI_INT_OVRES) != 0) + { + /* If debug is enabled, report any overrun errors */ + + spidbg("Error: Overrun (OVRES): %08x\n", pending); + + /* OVRES was cleared by the status read. */ + } +#endif + + /* Check for the availability of RX data */ + + if ((pending & SPI_INT_RDRF) != 0) + { + uint16_t data; + + /* We get no indication of the falling edge of NSS. But if we are + * here then it must have fallen. + */ + + if (priv->nss) + { + priv->nss = false; + SPI_SDEV_SELECT(priv->sdev, true); + } + + /* Read the RDR to get the data and to clear the pending RDRF + * interrupt. + */ + + regval = spi_getreg(priv, SAM_SPI_RDR_OFFSET); + data = (uint16_t)((regval & SPI_RDR_RD_MASK) >> SPI_RDR_RD_SHIFT); + + /* Enable TXDR/OVRE interrupts */ + + regval = (SPI_INT_TDRE | SPI_INT_UNDES); + spi_putreg(priv, regval, SAM_SPI_IER_OFFSET); + + /* Report the receipt of data to the SPI device driver */ + + SPI_SDEV_RECEIVE(priv->sdev, data); + } + + /* When a transfer starts, the data shifted out is the data present + * in the Shift register. If no data has been written in the SPI_TDR, + * the last data received is transferred. If no data has been received + * since the last reset, all bits are transmitted low, as the Shift + * register resets to 0. + * + * When a first data is written in the SPI_TDR, it is transferred + * immediately in the Shift register and the TDRE flag rises. If new + * data is written, it remains in the SPI_TDR until a transfer occurs, + * i.e., NSS falls and there is a valid clock on the SPCK pin. When + * the transfer occurs, the last data written in the SPI_TDR is + * transferred in the Shift register and the TDRE flag rises. This + * enables frequent updates of critical variables with single transfers. + * + * Then, new data is loaded in the Shift register from the SPI_TDR. If + * no character is ready to be transmitted, i.e., no character has been + * written in the SPI_TDR since the last load from the SPI_TDR to the + * Shift register, the SPI_TDR is retransmitted. In this case the + * Underrun Error Status Flag (UNDES) is set in the SPI_SR. + */ + +#ifdef CONFIG_DEBUG_SPI + /* Check the TX data underflow condition */ + + if ((pending & SPI_INT_UNDES) != 0) + { + /* If debug is enabled, report any overrun errors */ + + spidbg("Error: Underrun (UNDEX): %08x\n", pending); + + /* UNDES was cleared by the status read. */ + } +#endif + + /* Output the next TX data */ + + if ((pending & SPI_INT_TDRE) != 0) + { + /* Get the next output value and write it to the TDR + * The TDRE interrupt is cleared by writing to the from RDR. + */ + + regval = spi_dequeue(priv); + spi_putreg(priv, regval, SAM_SPI_TDR_OFFSET); + } + + /* The SPI slave hardware provides only an event when NSS rises + * which may or many not happen at the end of a transfer. NSSR was + * cleared by the status read. + */ + + if ((pending & SPI_INT_NSSR) != 0) + { + /* Disable further TXDR/OVRE interrupts */ + + regval = (SPI_INT_TDRE | SPI_INT_UNDES); + spi_putreg(priv, regval, SAM_SPI_IDR_OFFSET); + + /* Report the state change to the SPI device driver */ + + priv->nss = true; + SPI_SDEV_SELECT(priv->sdev, false); + } + } + + return OK; +} + +/**************************************************************************** + * Name: spi0_interrupt + * + * Description: + * SPI0 interrupt handler + * + * Input Parameters: + * Standard interrupt input parameters + * + * Returned Value: + * Standard interrupt return value. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI0_SLAVE +static int spi0_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi0_sctrlr); +} +#endif + +/**************************************************************************** + * Name: spi1_interrupt + * + * Description: + * SPI1 interrupt handler + * + * Input Parameters: + * Standard interrupt input parameters + * + * Returned Value: + * Standard interrupt return value. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SPI1_SLAVE +static int spi1_interrupt(int irq, void *context) +{ + return spi_interrupt(&g_spi1_sctrlr); +} +#endif + +/**************************************************************************** + * Name: spi_dequeue + * + * Description: + * Return the next queued output value. If nothing is in the output queue, + * then return the last value obtained from getdata(); + * + * Input Parameters: + * priv - SPI controller CS state + * + * Assumptions: + * Called only from the SPI interrupt handler so all interrupts are + * disabled. + * + ****************************************************************************/ + +static uint16_t spi_dequeue(struct sam_spidev_s *priv) +{ + uint32_t regval; + uint16_t ret; + int next; + + /* Is the queue empty? */ + + if (priv->head != priv->tail) + { + /* No, take the oldest value from the tail of the cicular buffer */ + + ret = priv->outq[priv->tail]; + + /* Update the tail index, handling wraparound */ + + next = priv->tail + 1; + if (next >= CONFIG_SAMV7_SPI_SLAVE_QSIZE) + { + next = 0; + } + + priv->tail = next; + + /* If the queue is empty Disable further TXDR/OVRE interrupts until + * spi_enqueue() is called or until we received another command. We + * do this only for the case where NSS is non-functional (tied to + * ground) and we need to end transfers in some fashion. + */ + + if (priv->head == next) + { + regval = (SPI_INT_TDRE | SPI_INT_UNDES); + spi_putreg(priv, regval, SAM_SPI_IDR_OFFSET); + } + } + else + { + /* Yes, return the last value we got from the getdata() method */ + + ret = priv->outval; + + /* Disable further TXDR/OVRE interrupts until spi_enqueue() is called. */ + + regval = (SPI_INT_TDRE | SPI_INT_UNDES); + spi_putreg(priv, regval, SAM_SPI_IDR_OFFSET); + } + + return ret; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. See enum spi_smode_e for mode definitions + * + * Input Parameters: + * priv - SPI device data structure + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(struct sam_spidev_s *priv, enum spi_smode_e mode) +{ + uint32_t regval; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set the mode appropriately: + * + * SPI CPOL NCPHA + * MODE + * 0 0 1 + * 1 0 0 + * 2 1 1 + * 3 1 0 + */ + + regval = spi_getreg(priv, SAM_SPI_CSR0_OFFSET); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA); + + switch (mode) + { + case SPISLAVE_MODE0: /* CPOL=0; NCPHA=1 */ + regval |= SPI_CSR_NCPHA; + break; + + case SPISLAVE_MODE1: /* CPOL=0; NCPHA=0 */ + break; + + case SPISLAVE_MODE2: /* CPOL=1; NCPHA=1 */ + regval |= (SPI_CSR_CPOL | SPI_CSR_NCPHA); + break; + + case SPISLAVE_MODE3: /* CPOL=1; NCPHA=0 */ + regval |= SPI_CSR_CPOL; + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(priv, regval, SAM_SPI_CSR0_OFFSET); + spivdbg("csr0=%08x\n", regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * priv - SPI device data structure + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(struct sam_spidev_s *priv, int nbits) +{ + uint32_t regval; + + spivdbg("nbits=%d\n", nbits); + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set number of bits appropriately */ + + regval = spi_getreg(priv, SAM_SPI_CSR0_OFFSET); + regval &= ~SPI_CSR_BITS_MASK; + regval |= SPI_CSR_BITS(nbits); + spi_putreg(priv, regval, SAM_SPI_CSR0_OFFSET); + + spivdbg("csr0=%08x\n", regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_bind + * + * Description: + * Bind the SPI slave device interface to the SPI slave controller + * interface and configure the SPI interface. Upon return, the SPI + * slave controller driver is fully operational and ready to perform + * transfers. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * sdev - SPI slave device interface instance + * mode - The SPI mode requested + * nbits - The number of bits requests. + * If value is greater > 0 then it implies MSB first + * If value is below < 0, then it implies LSB first with -nbits + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_bind(struct spi_sctrlr_s *sctrlr, + struct spi_sdev_s *sdev, enum spi_smode_e mode, + int nbits) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; + uint32_t regval; + + spivdbg("sdev=%p mode=%d nbits=%d\n", sdv, mode, nbits); + + DEBUGASSERT(priv != NULL && priv->sdev == NULL && sdev != NULL); + + /* Get exclusive access to the SPI device */ + + spi_semtake(priv); + + /* Bind the SPI slave device interface instance to the SPI slave + * controller interface. + */ + + priv->sdev = sdev; + + /* Call the slaved device's select() and cmddata() methods to indicate + * the initial state of the chip select and command/data discretes. + * + * NOTE: Unless we reconfigure the NSS GPIO pin, it may not be possible + * to read the NSS pin value (I haven't actually tried just reading it). + * And, since the is no interrupt on the falling edge of NSS, we get no + * notification when we are selected... not until the arrival of data. + * + * REVISIT: A board-level interface would be required in order to support + * the Command/Data indication (not yet impklemented). + */ + + SPI_SDEV_SELECT(sdev, false); +#warning Missing logic + SPI_SDEV_CMDDATA(sdev, false); + + /* Discard any queued data */ + + priv->head = 0; + priv->tail = 0; + + /* Call the slave device's getdata() method to get the value that will + * be shifted out the SPI clock is detected. + */ + + priv->outval = SPI_SDEV_GETDATA(sdev); + spi_putreg(priv, priv->outval, SAM_SPI_TDR_OFFSET); + + /* Setup to begin normal SPI operation */ + + spi_setmode(priv, mode); + spi_setbits(priv, nbits); + + /* Clear pending interrupts by reading the SPI Status Register */ + + regval = spi_getreg(priv, SAM_SPI_SR_OFFSET); + UNUSED(regval); + + /* Enable SPI interrupts (already enabled at the NVIC): + * + * Data Transfer: + * SPI_INT_RDRF - Receive Data Register Full Interrupt + * SPI_INT_TDRE - Transmit Data Register Empty Interrupt + * SPI_INT_NSSR - NSS Rising Interrupt + * + * Transfer Errors (for DEBUG purposes only): + * SPI_INT_OVRES - Overrun Error Interrupt + * SPI_INT_UNDES - Underrun Error Status Interrupt (slave) + * + * Not Used: + * SPI_INT_MODF - Mode Fault Error Interrupt + * SPI_INT_TXEMPTY - Transmission Registers Empty Interrupt + * + * TX interrupts (SPI_INT_TDRE and SPI_INT_UNDES) are not enabled until + * the transfer of data actually starts. + */ + + regval = (SPI_INT_RDRF | SPI_INT_NSSR); +#ifdef CONFIG_DEBUG_SPI + regval |= SPI_INT_OVRES; +#endif + + spi_putreg(priv, regval, SAM_SPI_IER_OFFSET); + + spi_semgive(priv); +} + +/**************************************************************************** + * Name: spi_unbind + * + * Description: + * Un-bind the SPI slave device interface from the SPI slave controller + * interface. Reset the SPI interface and restore the SPI slave + * controller driver to its initial state, + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_unbind(struct spi_sctrlr_s *sctrlr) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; + + DEBUGASSERT(priv != NULL); + spivdbg("Unbinding %p\n", priv->sdev); + + DEBUGASSERT(priv->sdev != NULL); + + /* Get exclusive access to the SPI device */ + + spi_semtake(priv); + + /* Disable SPI interrupts (still enabled at the NVIC) */ + + spi_putreg(priv, SPI_INT_ALL, SAM_SPI_IDR_OFFSET); + + /* Unbind the SPI slave interface */ + + priv->sdev = NULL; + + /* Disable the SPI peripheral */ + + spi_putreg(priv, SPI_CR_SPIDIS, SAM_SPI_CR_OFFSET); + + /* Execute a software reset of the SPI (twice) */ + + spi_putreg(priv, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + spi_putreg(priv, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + + spi_semgive(priv); +} + +/**************************************************************************** + * Name: spi_enqueue + * + * Description: + * Enqueue the next value to be shifted out from the interface. This adds + * the word the controller driver for a subsequent transfer but has no + * effect on anyin-process or currently "committed" transfers + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * data - Command/data mode data value to be shifted out. The width of + * the data must be the same as the nbits parameter previously + * provided to the bind() methods. + * + * Returned Value: + * Zero if the word was successfully queue; A negated errno valid is + * returned on any failure to enqueue the word (such as if the queue is + * full). + * + ****************************************************************************/ + +static int spi_enqueue(struct spi_sctrlr_s *sctrlr, uint16_t data) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; + irqstate_t flags; + uint32_t regval; + int next; + int ret; + + spivdbg("data=%04x\n", data); + DEBUGASSERT(priv != NULL && priv->sdev != NULL); + + /* Get exclusive access to the SPI device */ + + spi_semtake(priv); + + /* Check if this word would overflow the circular buffer + * + * Interrupts are disabled briefly. + */ + + flags = enter_critical_section(); + next = priv->head + 1; + if (next >= CONFIG_SAMV7_SPI_SLAVE_QSIZE) + { + next = 0; + } + + if (next == priv->tail) + { + ret = -ENOSPC; + } + else + { + /* Save this new word as the next word to shifted out. The current + * word written to the TX data registers is "committed" and will not + * be overwritten. + */ + + priv->outq[priv->head] = data; + priv->head = next; + ret = OK; + + /* Enable TX interrupts if we have begun the transfer */ + + if (!priv->nss) + { + /* Enable TXDR/OVRE interrupts */ + + regval = (SPI_INT_TDRE | SPI_INT_UNDES); + spi_putreg(priv, regval, SAM_SPI_IER_OFFSET); + } + } + + leave_critical_section(flags); + spi_semgive(priv); + return ret; +} + +/**************************************************************************** + * Name: spi_qfull + * + * Description: + * Return true if the queue is full or false if there is space to add an + * additional word to the queue. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * true if the output wueue is full + * + ****************************************************************************/ + +static bool spi_qfull(struct spi_sctrlr_s *sctrlr) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; + irqstate_t flags; + int next; + bool ret; + + DEBUGASSERT(priv != NULL && priv->sdev != NULL); + + /* Get exclusive access to the SPI device */ + + spi_semtake(priv); + + /* Check if another word would overflow the circular buffer + * + * Interrupts are disabled briefly. + */ + + flags = enter_critical_section(); + next = priv->head + 1; + if (next >= CONFIG_SAMV7_SPI_SLAVE_QSIZE) + { + next = 0; + } + + ret = (next == priv->tail); + leave_critical_section(flags); + spi_semgive(priv); + return ret; +} + +/**************************************************************************** + * Name: spi_qflush + * + * Description: + * Discard all saved values in the output queue. On return from this + * function the output queue will be empty. Any in-progress or otherwise + * "committed" output values may not be flushed. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_qflush(struct spi_sctrlr_s *sctrlr) +{ + struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; + irqstate_t flags; + + spivdbg("data=%04x\n", data); + + DEBUGASSERT(priv != NULL && priv->sdev != NULL); + + /* Get exclusive access to the SPI device */ + + spi_semtake(priv); + + /* Mark the buffer empty, momentarily disabling interrupts */ + + flags = enter_critical_section(); + priv->head = 0; + priv->tail = 0; + leave_critical_section(flags); + spi_semgive(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_spi_slave_initialize + * + * Description: + * Initialize the selected SPI port in slave mode. + * + * Input Parameter: + * port - Chip select number identifying the "logical" SPI port. Includes + * encoded port and chip select information. + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_sctrlr_s *sam_spi_slave_initialize(int port) +{ + struct sam_spidev_s *priv; + int spino = (port & __SPI_SPI_MASK) >> __SPI_SPI_SHIFT; + irqstate_t flags; + uint32_t regval; + + /* The support SAM parts have only a single SPI port */ + + spivdbg("port: %d spino: %d\n", port, spino); + +#if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE) + DEBUGASSERT(spino >= 0 && spino <= 1); +#elif defined(CONFIG_SAMV7_SPI0_SLAVE) + DEBUGASSERT(spino == 0); +#else + DEBUGASSERT(spino == 1); +#endif + +#if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE) + if (spino == 0) + { + priv = &g_spi0_sctrlr; + } + else + { + priv = &g_spi1_sctrlr; + } + +#elif defined(CONFIG_SAMV7_SPI0_SLAVE) + priv = &g_spi0_sctrlr; + +#elif defined(CONFIG_SAMV7_SPI1_SLAVE) + priv = &g_spi1_sctrlr; +#endif + + /* Set up the initial state for this chip select structure. Other fields + * are zeroed. + */ + + memset(priv, 0, sizeof(struct sam_spidev_s)); + + /* Initialize the SPI operations */ + + priv->sctrlr.ops = &g_sctrlr_ops; + + /* Save the SPI controller number */ + + priv->spino = spino; + + /* Has the SPI hardware been initialized? */ + + if (!priv->initialized) + { + /* Enable clocking to the SPI block */ + + flags = enter_critical_section(); +#if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE) + if (spino == 0) +#endif +#if defined(CONFIG_SAMV7_SPI0_SLAVE) + { + /* Set the SPI0 register base address and interrupt information */ + + priv->base = SAM_SPI0_BASE, + priv->irq = SAM_IRQ_SPI0; + priv->handler = spi0_interrupt; + + /* Enable peripheral clocking to SPI0 */ + + sam_spi0_enableclk(); + + /* Configure multiplexed pins as connected on the board. */ + + sam_configgpio(GPIO_SPI0_MISO); /* Output */ + sam_configgpio(GPIO_SPI0_MOSI); /* Input */ + sam_configgpio(GPIO_SPI0_SPCK); /* Drives slave */ + sam_configgpio(GPIO_SPI0_NSS); /* aka NPCS0 */ + } +#endif +#if defined(CONFIG_SAMV7_SPI0_SLAVE) && defined(CONFIG_SAMV7_SPI1_SLAVE) + else +#endif +#if defined(CONFIG_SAMV7_SPI1_SLAVE) + { + /* Set the SPI1 register base address and interrupt information */ + + priv->base = SAM_SPI1_BASE, + priv->irq = SAM_IRQ_SPI1; + priv->handler = spi1_interrupt; + + /* Enable peripheral clocking to SPI1 */ + + sam_spi1_enableclk(); + + /* Configure multiplexed pins as connected on the board. */ + + sam_configgpio(GPIO_SPI1_MISO); /* Output */ + sam_configgpio(GPIO_SPI1_MOSI); /* Input */ + sam_configgpio(GPIO_SPI1_SPCK); /* Drives slave */ + sam_configgpio(GPIO_SPI0_NSS); /* aka NPCS0 */ + } +#endif + + /* Disable the SPI peripheral */ + + spi_putreg(priv, SPI_CR_SPIDIS, SAM_SPI_CR_OFFSET); + + /* Execute a software reset of the SPI (twice) */ + + spi_putreg(priv, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + spi_putreg(priv, SPI_CR_SWRST, SAM_SPI_CR_OFFSET); + leave_critical_section(flags); + + /* Configure the SPI mode register */ + + spi_putreg(priv, SPI_MR_SLAVE | SPI_MR_MODFDIS, SAM_SPI_MR_OFFSET); + + /* And enable the SPI */ + + spi_putreg(priv, SPI_CR_SPIEN, SAM_SPI_CR_OFFSET); + up_mdelay(20); + + /* Flush any pending interrupts/transfers */ + + (void)spi_getreg(priv, SAM_SPI_SR_OFFSET); + (void)spi_getreg(priv, SAM_SPI_RDR_OFFSET); + + /* Initialize the SPI semaphore that enforces mutually exclusive + * access to the SPI registers. + */ + + sem_init(&priv->spisem, 0, 1); + priv->nss = true; + priv->initialized = true; + + /* Disable all SPI interrupts at the SPI peripheral */ + + spi_putreg(priv, SPI_INT_ALL, SAM_SPI_IDR_OFFSET); + + /* Attach and enable interrupts at the NVIC */ + + DEBUGVERIFY(irq_attach(priv->irq, priv->handler)); + up_enable_irq(priv->irq); + + spi_dumpregs(priv, "After initialization"); + } + + /* Set to mode=0 and nbits=8 */ + + regval = spi_getreg(priv, SAM_SPI_CSR0_OFFSET); + regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK); + regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8)); + spi_putreg(priv, regval, SAM_SPI_CSR0_OFFSET); + + priv->nbits = 8; + spivdbg("csr[offset=%02x]=%08x\n", offset, regval); + + return &priv->sctrlr; +} +#endif /* CONFIG_SAMV7_SPI_SLAVE */ diff --git a/arch/arm/src/samv7/sam_ssc.c b/arch/arm/src/samv7/sam_ssc.c new file mode 100644 index 0000000000000000000000000000000000000000..107d120de7a35f462f369aacc0031033b2ad31e4 --- /dev/null +++ b/arch/arm/src/samv7/sam_ssc.c @@ -0,0 +1,3506 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_ssc.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cache.h" + +#include "sam_gpio.h" +#include "sam_xdmac.h" +#include "sam_periphclks.h" +#include "sam_ssc.h" +#include "chip/sam_pmc.h" +#include "chip/sam_ssc.h" +#include "chip/sam_pinmap.h" + +#if defined(CONFIG_SAMV7_SSC0) || defined(CONFIG_SAMV7_SSC1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_SCHED_WORKQUEUE +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#endif + +#ifndef CONFIG_AUDIO +# error CONFIG_AUDIO required by this driver +#endif + +#ifndef CONFIG_SAMV7_SSC_MAXINFLIGHT +# define CONFIG_SAMV7_SSC_MAXINFLIGHT 16 +#endif + +/* Assume no RX/TX support until we learn better */ + +#undef SSC_HAVE_RX +#undef SSC_HAVE_TX + +/* Check for SSC0 support */ + +#if defined(CONFIG_SAMV7_SSC0) + +# ifndef CONFIG_SAMV7_XDMAC +# error CONFIG_SAMV7_XDMAC required by SSC0 +# endif + + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + +# ifndef CONFIG_SAMV7_SSC0_DATALEN +# define CONFIG_SAMV7_SSC0_DATALEN 16 +# endif + +# if CONFIG_SAMV7_SSC0_DATALEN == 8 +# define SAMV7_SSC0_DATAMASK 0 +# elif CONFIG_SAMV7_SSC0_DATALEN == 16 +# define SAMV7_SSC0_DATAMASK 1 +# elif CONFIG_SAMV7_SSC0_DATALEN == 32 +# define SAMV7_SSC0_DATAMASK 3 +# elif CONFIG_SAMV7_SSC0_DATALEN < 2 || CONFIG_SAMV7_SSC0_DATALEN > 32 +# error Invalid value for CONFIG_SAMV7_SSC0_DATALEN +# else +# error Valid but supported value for CONFIG_SAMV7_SSC0_DATALEN +# endif + +/* Check for SSC0 RX support */ + +# if defined(CONFIG_SAMV7_SSC0_RX) +# define SSC_HAVE_RX 1 + +# ifndef CONFIG_SSC0_RX_FSLEN +# define CONFIG_SSC0_RX_FSLEN 1 +# endif + +# if CONFIG_SSC0_RX_FSLEN < 1 || CONFIG_SSC0_RX_FSLEN > 255 +# error Invalid value for CONFIG_SSC0_RX_FSLEN +# endif + +# ifndef CONFIG_SSC0_RX_STTDLY +# define CONFIG_SSC0_RX_STTDLY CONFIG_SSC0_RX_FSLEN +# endif + +# if CONFIG_SSC0_RX_STTDLY < 0 || \ + CONFIG_SSC0_RX_STTDLY < CONFIG_SSC0_RX_FSLEN || \ + CONFIG_SSC0_RX_STTDLY > 255 +# error Invalid value for CONFIG_SSC0_RX_STTDLY +# endif +# endif + +/* Check for SSC0 TX support */ + +# if defined(CONFIG_SAMV7_SSC0_TX) +# define SSC_HAVE_TX 1 + +# ifndef CONFIG_SSC0_TX_FSLEN +# define CONFIG_SSC0_TX_FSLEN 0 +# endif + +# if CONFIG_SSC0_TX_FSLEN < 0 || CONFIG_SSC0_TX_FSLEN > 255 +# error Invalid value for CONFIG_SSC0_TX_FSLEN +# endif + +# ifndef CONFIG_SSC0_TX_STTDLY +# if CONFIG_SSC0_TX_FSLEN > 0 +# define CONFIG_SSC0_TX_STTDLY CONFIG_SSC0_TX_FSLEN +# else +# define CONFIG_SSC0_TX_STTDLY 0 +# endif +# endif + +# if CONFIG_SSC0_TX_STTDLY < 0 || \ + CONFIG_SSC0_TX_STTDLY < CONFIG_SSC0_TX_FSLEN || \ + CONFIG_SSC0_TX_STTDLY > 255 +# error Invalid value for CONFIG_SSC0_TX_STTDLY +# endif +# endif + +#endif + +/* Check for SSC1 support */ + +#if defined(CONFIG_SAMV7_SSC1) + +# ifndef CONFIG_SAMV7_XDMAC +# error CONFIG_SAMV7_XDMAC required by SSC1 +# endif + + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + +# ifndef CONFIG_SAMV7_SSC1_DATALEN +# define CONFIG_SAMV7_SSC1_DATALEN 16 +# endif + +# if CONFIG_SAMV7_SSC1_DATALEN == 8 +# define SAMV7_SSC1_DATAMASK 0 +# elif CONFIG_SAMV7_SSC1_DATALEN == 16 +# define SAMV7_SSC1_DATAMASK 1 +# elif CONFIG_SAMV7_SSC1_DATALEN == 32 +# define SAMV7_SSC1_DATAMASK 3 +# elif CONFIG_SAMV7_SSC1_DATALEN < 2 || CONFIG_SAMV7_SSC1_DATALEN > 32 +# error Invalid value for CONFIG_SAMV7_SSC1_DATALEN +# else +# error Valid but supported value for CONFIG_SAMV7_SSC1_DATALEN +# endif + +/* Check for SSC1 RX support */ + +# if defined(CONFIG_SAMV7_SSC1_RX) +# define SSC_HAVE_RX 1 + +# ifndef CONFIG_SSC1_RX_FSLEN +# define CONFIG_SSC1_RX_FSLEN 1 +# endif + +# if CONFIG_SSC1_RX_FSLEN < 1 || CONFIG_SSC1_RX_FSLEN > 255 +# error Invalid value for CONFIG_SSC1_RX_FSLEN +# endif + +# ifndef CONFIG_SSC1_RX_STTDLY +# define CONFIG_SSC1_RX_STTDLY CONFIG_SSC1_RX_FSLEN +# endif + +# if CONFIG_SSC1_RX_STTDLY < 0 || \ + CONFIG_SSC1_RX_STTDLY < CONFIG_SSC1_RX_FSLEN || \ + CONFIG_SSC1_RX_STTDLY > 255 +# error Invalid value for CONFIG_SSC1_RX_STTDLY +# endif + +# endif + +/* Check for SSC1 TX support */ + +# if defined(CONFIG_SAMV7_SSC1_TX) +# define SSC_HAVE_TX 1 + +# ifndef CONFIG_SSC1_TX_FSLEN +# define CONFIG_SSC1_TX_FSLEN 0 +# endif + +# if CONFIG_SSC1_TX_FSLEN < 0 || CONFIG_SSC1_TX_FSLEN > 255 +# error Invalid value for CONFIG_SSC1_TX_FSLEN +# endif + +# ifndef CONFIG_SSC1_TX_STTDLY +# if CONFIG_SSC1_TX_FSLEN > 0 +# define CONFIG_SSC1_TX_STTDLY CONFIG_SSC1_TX_FSLEN +# else +# define CONFIG_SSC1_TX_STTDLY 0 +# endif +# endif + +# if CONFIG_SSC1_TX_STTDLY < 0 || \ + CONFIG_SSC1_TX_STTDLY < CONFIG_SSC1_TX_FSLEN || \ + CONFIG_SSC1_TX_STTDLY > 255 +# error Invalid value for CONFIG_SSC1_TX_STTDLY +# endif +# endif + +#endif + +/* Check if we need to build RX and/or TX support */ + +#if defined(SSC_HAVE_RX) || defined(SSC_HAVE_TX) + +/* Check if we need the sample rate to set MCK/2 divider */ + +#undef SSC_HAVE_MCK2 +#undef SSC0_HAVE_MCK2 +#undef SSC1_HAVE_MCK2 + +#if (defined(CONFIG_SAMV7_SSC0_RX) && defined(CONFIG_SAMV7_SSC0_RX_MCKDIV)) || \ + (defined(CONFIG_SAMV7_SSC0_TX) && defined(CONFIG_SAMV7_SSC0_TX_MCKDIV)) +# define SSC0_HAVE_MCK2 1 +#endif + +#if (defined(CONFIG_SAMV7_SSC1_RX) && defined(CONFIG_SAMV7_SSC1_RX_MCKDIV)) || \ + (defined(CONFIG_SAMV7_SSC1_TX) && defined(CONFIG_SAMV7_SSC1_TX_MCKDIV)) +# define SSC1_HAVE_MCK2 1 +#endif + +#if defined(SSC0_HAVE_MCK2) || defined(SSC1_HAVE_MCK2) +# define SSC_HAVE_MCK2 1 +#endif + +/* Waveform: + * + * |<---------------- PERIOD --------------->| + * ----+ +-----------------------------------+ +--- + * | | | | + * +-----+ +----+ + * |FSLEN| + * |<-STTDLY->|<--DATALEN-->|<--DATALEN-->| | + * |<-----DATALEN * DATNB----->| + * + * TK/RK is assumed to be a negative pulse + * DATALEN is configurable: CONFIG_SAMV7_SSCx_DATALEN + * FSLEN is configuration: CONFIG_SAMV7_SSCx_RX/TX_FSLEN + * FSLEN and STTDLY are fixed at two clocks + * DATNB is fixed a one work + * + * REVISIT: These will probably need to be configurable + */ + +#define SSC_DATNB (1) /* Number words per per frame */ +#define SCC_PERIOD(s,d) ((s) + (d) * SSC_DATNB) + +/* Clocking *****************************************************************/ + +/* Clock source definitions */ + +#define SSC_CLKSRC_NONE 0 /* No clock */ +#define SSC_CLKSRC_MCKDIV 1 /* Clock source is MCK divided down */ +#define SSC_CLKSRC_RXOUT 2 /* Transmitter clock source is the receiver clock */ +#define SSC_CLKSRC_TXOUT 2 /* Receiver clock source is the transmitter clock */ +#define SSC_CLKSRC_TKIN 3 /* Transmitter clock source is TK */ +#define SSC_CLKSRC_RKIN 3 /* Receiver clock source is RK */ + +/* Clock output definitions */ + +#define SSC_CLKOUT_NONE 0 /* No output clock */ +#define SSC_CLKOUT_CONT 1 /* Continuous */ +#define SSC_CLKOUT_XFER 2 /* Only output clock during transfers */ + +/* System Bus Interfaces + * REVISIT: I believe that the SAMV1 has only a single APB. + */ + +#warning REVISIT +#define DMACH_FLAG_PERIPH_IF DMACH_FLAG_PERIPHAHB_AHB_IF0 +#define DMACH_FLAG_MEM_IF DMACH_FLAG_MEMAHB_AHB_IF0 + +/* DMA configuration */ + +#define DMA8_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_8BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +#define DMA16_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_16BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +#define DMA32_FLAGS \ + (DMACH_FLAG_PERIPH_IF | DMACH_FLAG_PERIPHH2SEL | \ + DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_32BITS | \ + DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \ + DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_32BITS | \ + DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \ + DMACH_FLAG_MEMBURST_4) + +/* DMA timeout. The value is not critical; we just don't want the system to + * hang in the event that a DMA does not finish. This is set to + */ + +#define DMA_TIMEOUT_MS (800) +#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS) + +/* Debug *******************************************************************/ +/* Check if SSC debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_I2S +#endif + +#ifndef CONFIG_DEBUG_I2S +# undef CONFIG_SAMV7_SSC_DMADEBUG +# undef CONFIG_SAMV7_SSC_REGDEBUG +# undef CONFIG_SAMV7_SSC_QDEBUG +# undef CONFIG_SAMV7_SSC_DUMPBUFFERS +#endif + +#ifndef CONFIG_DEBUG_DMA +# undef CONFIG_SAMV7_SSC_DMADEBUG +#endif + +#ifdef CONFIG_DEBUG_I2S +# define i2sdbg dbg +# define i2slldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define i2svdbg dbg +# define i2sllvdbg lldbg +# else +# define i2svdbg(x...) +# endif +#else +# define i2sdbg(x...) +# define i2slldbg(x...) +# define i2svdbg(x...) +# define i2sllvdbg(x...) +#endif + +#define DMA_INITIAL 0 +#define DMA_AFTER_SETUP 1 +#define DMA_AFTER_START 2 +#define DMA_CALLBACK 3 +#define DMA_TIMEOUT 3 +#define DMA_END_TRANSFER 4 +#define DMA_NSAMPLES 5 + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* I2S buffer container */ + +struct sam_buffer_s +{ + struct sam_buffer_s *flink; /* Supports a singly linked list */ + i2s_callback_t callback; /* Function to call when the transfer completes */ + uint32_t timeout; /* The timeout value to use with DMA transfers */ + void *arg; /* The argument to be returned with the callback */ + struct ap_buffer_s *apb; /* The audio buffer */ + int result; /* The result of the transfer */ +}; + +/* This structure describes the state of one receiver or transmitter transport */ + +struct sam_transport_s +{ + DMA_HANDLE dma; /* SSC DMA handle */ + WDOG_ID dog; /* Watchdog that handles DMA timeouts */ + sq_queue_t pend; /* A queue of pending transfers */ + sq_queue_t act; /* A queue of active transfers */ + sq_queue_t done; /* A queue of completed transfers */ + struct work_s work; /* Supports worker thread operations */ + +#ifdef CONFIG_SAMV7_SSC_DMADEBUG + struct sam_dmaregs_s dmaregs[DMA_NSAMPLES]; +#endif +}; + +/* The state of the one SSC peripheral */ + +struct sam_ssc_s +{ + struct i2s_dev_s dev; /* Externally visible I2S interface */ + uintptr_t base; /* SSC controller register base address */ + sem_t exclsem; /* Assures mutually exclusive acess to SSC */ + uint8_t datalen; /* Data width (8, 16, or 32) */ +#ifdef CONFIG_DEBUG + uint8_t align; /* Log2 of data width (0, 1, or 3) */ +#endif + uint8_t pid; /* Peripheral ID */ + uint8_t rxfslen; /* RX frame sync length */ + uint8_t txfslen; /* TX frame sync length */ + uint8_t rxsttdly; /* RX start delay */ + uint8_t txsttdly; /* TX start delay */ + uint8_t rxenab:1; /* True: RX transfers enabled */ + uint8_t txenab:1; /* True: TX transfers enabled */ + uint8_t loopback:1; /* True: Loopback mode */ + uint8_t sscno:1; /* SSC controller number (0 or 1) */ + uint8_t rxclk:2; /* Receiver clock source. See SSC_CLKSRC_* definitions */ + uint8_t txclk:2; /* Transmitter clock source. See SSC_CLKSRC_* definitions */ + uint8_t rxout:2; /* Receiver clock output. See SSC_CLKOUT_* definitions */ + uint8_t txout:2; /* Transmitter clock output. See SSC_CLKOUT_* definitions */ + uint32_t frequency; /* SSC clock frequency */ +#ifdef SSC_HAVE_MCK2 + uint32_t samplerate; /* Data sample rate (determines only MCK/2 divider) */ +#endif + +#ifdef SSC_HAVE_RX + struct sam_transport_s rx; /* RX transport state */ +#endif +#ifdef SSC_HAVE_TX + struct sam_transport_s tx; /* TX transport state */ +#endif + + /* Pre-allocated pool of buffer containers */ + + sem_t bufsem; /* Buffer wait semaphore */ + struct sam_buffer_s *freelist; /* A list a free buffer containers */ + struct sam_buffer_s containers[CONFIG_SAMV7_SSC_MAXINFLIGHT]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_SSC_REGDEBUG + bool wr; /* Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int count; /* Number of times */ +#endif /* CONFIG_SAMV7_SSC_REGDEBUG */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register helpers */ + +#ifdef CONFIG_SAMV7_SSC_REGDEBUG +static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval, + uint32_t regaddr); +#else +# define ssc_checkreg(priv,wr,regval,regaddr) (false) +#endif + +static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, unsigned int offset); +static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset, + uint32_t regval); +static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv, + unsigned int offset); + +#if defined(CONFIG_DEBUG_I2S) && defined(CONFIG_DEBUG_VERBOSE) +static void scc_dump_regs(struct sam_ssc_s *priv, const char *msg); +#else +# define scc_dump_regs(s,m) +#endif + +#ifdef CONFIG_SAMV7_SSC_QDEBUG +static void ssc_dump_queues(struct sam_transport_s *xpt, + const char *msg); +# define ssc_dump_rxqueues(s,m) ssc_dump_queues(&(s)->rx,m) +# define ssc_dump_txqueues(s,m) ssc_dump_queues(&(s)->tx,m) +#else +# define ssc_dump_rxqueues(s,m) +# define ssc_dump_txqueues(s,m) +#endif + +#ifdef CONFIG_SAMV7_SSC_DUMPBUFFERS +# define ssc_init_buffer(b,s) memset(b, 0x55, s); +# define ssc_dump_buffer(m,b,s) lib_dumpbuffer(m,b,s) +#else +# define ssc_init_buffer(b,s) +# define ssc_dump_buffer(m,b,s) +#endif + +/* Semaphore helpers */ + +static void ssc_exclsem_take(struct sam_ssc_s *priv); +#define ssc_exclsem_give(priv) sem_post(&priv->exclsem) + +static void ssc_bufsem_take(struct sam_ssc_s *priv); +#define ssc_bufsem_give(priv) sem_post(&priv->bufsem) + +/* Buffer container helpers */ + +static struct sam_buffer_s * + ssc_buf_allocate(struct sam_ssc_s *priv); +static void ssc_buf_free(struct sam_ssc_s *priv, + struct sam_buffer_s *bfcontainer); +static void ssc_buf_initialize(struct sam_ssc_s *priv); + +/* DMA support */ + +#ifdef CONFIG_SAMV7_SSC_DMADEBUG +static void ssc_dma_sampleinit(struct sam_ssc_s *priv, + struct sam_transport_s *xpt); +#endif + +#if defined(CONFIG_SAMV7_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +# define ssc_rxdma_sample(s,i) sam_dmasample((s)->rx.dma, &(s)->rx.dmaregs[i]) +# define ssc_rxdma_sampleinit(s) ssc_dma_sampleinit(s, &(s)->rx) +static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result); + +#else +# define ssc_rxdma_sample(s,i) +# define ssc_rxdma_sampleinit(s) +# define ssc_rxdma_sampledone(s,r) + +#endif + +#if defined(CONFIG_SAMV7_SSC_DMADEBUG) && defined(SSC_HAVE_TX) +# define ssc_txdma_sample(s,i) sam_dmasample((s)->tx.dma, &(s)->tx.dmaregs[i]) +# define ssc_txdma_sampleinit(s) ssc_dma_sampleinit(s, &(s)->tx) +static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result); + +#else +# define ssc_txdma_sample(s,i) +# define ssc_txdma_sampleinit(s) +# define ssc_txdma_sampledone(s,r) + +#endif + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_timeout(int argc, uint32_t arg); +static int ssc_rxdma_setup(struct sam_ssc_s *priv); +static void ssc_rx_worker(void *arg); +static void ssc_rx_schedule(struct sam_ssc_s *priv, int result); +static void ssc_rxdma_callback(DMA_HANDLE handle, void *arg, int result); +#endif +#ifdef SSC_HAVE_TX +static void ssc_txdma_timeout(int argc, uint32_t arg); +static int ssc_txdma_setup(struct sam_ssc_s *priv); +static void ssc_tx_worker(void *arg); +static void ssc_tx_schedule(struct sam_ssc_s *priv, int result); +static void ssc_txdma_callback(DMA_HANDLE handle, void *arg, int result); +#endif + +/* I2S methods (and close friends) */ + +static int ssc_checkwidth(struct sam_ssc_s *priv, int bits); + +static uint32_t ssc_rxsamplerate(struct i2s_dev_s *dev, uint32_t rate); +static uint32_t ssc_rxdatawidth(struct i2s_dev_s *dev, int bits); +static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout); +static uint32_t ssc_txsamplerate(struct i2s_dev_s *dev, uint32_t rate); +static uint32_t ssc_txdatawidth(struct i2s_dev_s *dev, int bits); +static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, + uint32_t timeout); + +/* Initialization */ + +#ifdef SSC_HAVE_RX +static int ssc_rx_configure(struct sam_ssc_s *priv); +#endif +#ifdef SSC_HAVE_TX +static int ssc_tx_configure(struct sam_ssc_s *priv); +#endif +static uint32_t ssc_mck2divider(struct sam_ssc_s *priv); +static void ssc_clocking(struct sam_ssc_s *priv); +static int ssc_dma_flags(struct sam_ssc_s *priv, uint32_t *dmaflags); +static int ssc_dma_allocate(struct sam_ssc_s *priv); +static void ssc_dma_free(struct sam_ssc_s *priv); +#ifdef CONFIG_SAMV7_SSC0 +static void ssc0_configure(struct sam_ssc_s *priv); +#endif +#ifdef CONFIG_SAMV7_SSC1 +static void ssc1_configure(struct sam_ssc_s *priv); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* I2S device operations */ + +static const struct i2s_ops_s g_sscops = +{ + /* Receiver methods */ + + .i2s_rxsamplerate = ssc_rxsamplerate, + .i2s_rxdatawidth = ssc_rxdatawidth, + .i2s_receive = ssc_receive, + + /* Transmitter methods */ + + .i2s_txsamplerate = ssc_txsamplerate, + .i2s_txdatawidth = ssc_txdatawidth, + .i2s_send = ssc_send, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssc_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SSC_REGDEBUG +static bool ssc_checkreg(struct sam_ssc_s *priv, bool wr, uint32_t regval, + uint32_t regaddr) +{ + if (wr == priv->wr && /* Same kind of access? */ + regval == priv->regval && /* Same value? */ + regaddr == priv->regaddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->count++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->count > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->count); + } + + /* Save information about the new access */ + + priv->wr = wr; + priv->regval = regval; + priv->regaddr = regaddr; + priv->count = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: ssc_getreg + * + * Description: + * Read an SSC register + * + ****************************************************************************/ + +static inline uint32_t ssc_getreg(struct sam_ssc_s *priv, + unsigned int offset) +{ + uint32_t regaddr = priv->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMV7_SSC_REGDEBUG + if (ssc_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: ssc_putreg + * + * Description: + * Write a value to an SSC register + * + ****************************************************************************/ + +static inline void ssc_putreg(struct sam_ssc_s *priv, unsigned int offset, + uint32_t regval) +{ + uint32_t regaddr = priv->base + offset; + +#ifdef CONFIG_SAMV7_SSC_REGDEBUG + if (ssc_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: ssc_regaddr + * + * Description: + * Return the address of an SSC register + * + ****************************************************************************/ + +static inline uintptr_t ssc_regaddr(struct sam_ssc_s *priv, unsigned int offset) +{ + return priv->base + offset; +} + +/**************************************************************************** + * Name: scc_dump_regs + * + * Description: + * Dump the contents of all SSC registers + * + * Input Parameters: + * priv - The SSC controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_I2S) && defined(CONFIG_DEBUG_VERBOSE) +static void scc_dump_regs(struct sam_ssc_s *priv, const char *msg) +{ + i2svdbg("SSC%d: %s\n", priv->sscno, msg); + i2svdbg(" CMR:%08x RCMR:%08x RFMR:%08x TCMR:%08x\n", + getreg32(priv->base + SAM_SSC_CMR_OFFSET), + getreg32(priv->base + SAM_SSC_RCMR_OFFSET), + getreg32(priv->base + SAM_SSC_RFMR_OFFSET), + getreg32(priv->base + SAM_SSC_TCMR_OFFSET)); + i2svdbg(" TFMR:%08x RC0R:%08x RC1R:%08x SR:%08x\n", + getreg32(priv->base + SAM_SSC_TFMR_OFFSET), + getreg32(priv->base + SAM_SSC_RC0R_OFFSET), + getreg32(priv->base + SAM_SSC_RC1R_OFFSET), + getreg32(priv->base + SAM_SSC_SR_OFFSET)); + i2svdbg(" IMR:%08x WPMR:%08x WPSR:%08x\n", + getreg32(priv->base + SAM_SSC_IMR_OFFSET), + getreg32(priv->base + SAM_SSC_WPMR_OFFSET), + getreg32(priv->base + SAM_SSC_WPSR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: ssc_dump_queues + * + * Description: + * Dump the contents of transport queues + * + * Input Parameters: + * priv - The SSC controller to dump + * xpt - The transport to be dumped + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SSC_QDEBUG +static void ssc_dump_queue(sq_queue_t *queue) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + sq_entry_t *entry; + + for (entry = queue->head; entry; entry = entry->flink) + { + bfcontainer = (struct sam_buffer_s *)entry; + apb = bfcontainer->apb; + + if (!apb) + { + i2sllvdbg(" %p: No buffer\n", bfcontainer); + } + else + { + i2sllvdbg(" %p: buffer=%p nmaxbytes=%d nbytes=%d\n", + bfcontainer, apb, apb->nmaxbytes, apb->nbytes); + } + } +} + +static void ssc_dump_queues(struct sam_transport_s *xpt, const char *msg) +{ + irqstate_t flags; + + flags = enter_critical_section(); + i2sllvdbg("%s\n", msg); + i2sllvdbg(" Pending:\n"); + ssc_dump_queue(&xpt->pend); + i2sllvdbg(" Active:\n"); + ssc_dump_queue(&xpt->act); + i2sllvdbg(" Done:\n"); + ssc_dump_queue(&xpt->done); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: ssc_exclsem_take + * + * Description: + * Take the exclusive access semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the SSC peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_exclsem_take(struct sam_ssc_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->exclsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: ssc_bufsem_take + * + * Description: + * Take the buffer semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the SSC peripheral state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_bufsem_take(struct sam_ssc_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->bufsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: ssc_buf_allocate + * + * Description: + * Allocate a buffer container by removing the one at the head of the + * free list + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * A non-NULL pointer to the allocate buffer container on success; NULL if + * there are no available buffer containers. + * + * Assumptions: + * The caller does NOT have exclusive access to the SSC state structure. + * That would result in a deadlock! + * + ****************************************************************************/ + +static struct sam_buffer_s *ssc_buf_allocate(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + + /* Set aside a buffer container. By doing this, we guarantee that we will + * have at least one free buffer container. + */ + + ssc_bufsem_take(priv); + + /* Get the buffer from the head of the free list */ + + flags = enter_critical_section(); + bfcontainer = priv->freelist; + ASSERT(bfcontainer); + + /* Unlink the buffer from the freelist */ + + priv->freelist = bfcontainer->flink; + leave_critical_section(flags); + return bfcontainer; +} + +/**************************************************************************** + * Name: ssc_buf_free + * + * Description: + * Free buffer container by adding it to the head of the free list + * + * Input Parameters: + * priv - SSC state instance + * bfcontainer - The buffer container to be freed + * + * Returned Value: + * None + * + * Assumptions: + * The caller has exclusive access to the SSC state structure + * + ****************************************************************************/ + +static void ssc_buf_free(struct sam_ssc_s *priv, struct sam_buffer_s *bfcontainer) +{ + irqstate_t flags; + + /* Put the buffer container back on the free list */ + + flags = enter_critical_section(); + bfcontainer->flink = priv->freelist; + priv->freelist = bfcontainer; + leave_critical_section(flags); + + /* Wake up any threads waiting for a buffer container */ + + ssc_bufsem_give(priv); +} + +/**************************************************************************** + * Name: ssc_buf_initialize + * + * Description: + * Initialize the buffer container allocator by adding all of the + * pre-allocated buffer containers to the free list + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + * Assumptions: + * Called early in SSC initialization so that there are no issues with + * concurrency. + * + ****************************************************************************/ + +static void ssc_buf_initialize(struct sam_ssc_s *priv) +{ + int i; + + priv->freelist = NULL; + sem_init(&priv->bufsem, 0, CONFIG_SAMV7_SSC_MAXINFLIGHT); + + for (i = 0; i < CONFIG_SAMV7_SSC_MAXINFLIGHT; i++) + { + ssc_buf_free(priv, &priv->containers[i]); + } +} + +/**************************************************************************** + * Name: ssc_dma_sampleinit + * + * Description: + * Initialize sampling of DMA registers (if CONFIG_SAMV7_SSC_DMADEBUG) + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +static void ssc_dma_sampleinit(struct sam_ssc_s *priv, + struct sam_transport_s *xpt) +{ + /* Put contents of register samples into a known state */ + + memset(xpt->dmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s)); + + /* Then get the initial samples */ + + sam_dmasample(xpt->dma, &xpt->dmaregs[DMA_INITIAL]); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_sampledone + * + * Description: + * Dump sampled RX DMA registers + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_SSC_DMADEBUG) && defined(SSC_HAVE_RX) +static void ssc_rxdma_sampledone(struct sam_ssc_s *priv, int result) +{ + lldbg("result: %d\n", result); + + /* Sample the final registers */ + + sam_dmasample(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_INITIAL], + "RX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_AFTER_SETUP], + "RX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_AFTER_START], + "RX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + * + * If the DMA timedout, then there will not be any RX DMA + * callback samples. There is probably no TX DMA callback + * samples either, but we don't know for sure. + */ + + if (result == -ETIMEDOUT || result == -EINTR) + { + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_TIMEOUT], + "RX: At DMA timeout"); + } + else + { + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_CALLBACK], + "RX: At DMA callback"); + } + + sam_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER], + "RX: At End-of-Transfer"); + + scc_dump_regs(priv, "RX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_sampledone + * + * Description: + * Dump sampled DMA registers + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_SSC_DMADEBUG) && defined(SSC_HAVE_TX) +static void ssc_txdma_sampledone(struct sam_ssc_s *priv, int result) +{ + lldbg("result: %d\n", result); + + /* Sample the final registers */ + + sam_dmasample(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER]); + + /* Then dump the sampled DMA registers */ + /* Initial register values */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_INITIAL], + "TX: Initial Registers"); + + /* Register values after DMA setup */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_AFTER_SETUP], + "TX: After DMA Setup"); + + /* Register values after DMA start */ + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_AFTER_START], + "TX: After DMA Start"); + + /* Register values at the time of the TX and RX DMA callbacks + * -OR- DMA timeout. + */ + + if (result == -ETIMEDOUT || result == -EINTR) + { + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_TIMEOUT], + "TX: At DMA timeout"); + } + else + { + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_CALLBACK], + "TX: At DMA callback"); + } + + sam_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER], + "TX: At End-of-Transfer"); + + scc_dump_regs(priv, "TX: At End-of-Transfer"); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_timeout + * + * Description: + * The RX watchdog timeout without completion of the RX DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_timeout(int argc, uint32_t arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Sample DMA registers at the time of the timeout */ + + ssc_rxdma_sample(priv, DMA_TIMEOUT); + + /* Cancel the DMA */ + + sam_dmastop(priv->rx.dma); + + /* Then schedule completion of the transfer to occur on the worker thread. + * NOTE: sam_dmastop() will call the DMA complete callback with an error + * of -EINTR. So the following is just insurance and should have no + * effect if the worker is already schedule. + */ + + ssc_rx_schedule(priv, -ETIMEDOUT); +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_setup + * + * Description: + * Setup and initiate the next RX DMA transfer + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static int ssc_rxdma_setup(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + uintptr_t regaddr; + uintptr_t memaddr; + uint32_t timeout; + bool notimeout; + int ret; + + /* If there is already an active transmission in progress, then bail + * returning success. + */ + + if (!sq_empty(&priv->rx.act)) + { + return OK; + } + + /* If there are no pending transfer, then bail returning success */ + + if (sq_empty(&priv->rx.pend)) + { + return OK; + } + + /* Initialize DMA register sampling */ + + ssc_rxdma_sampleinit(priv); + + /* Loop, adding each pending DMA */ + + timeout = 0; + notimeout = false; + + do + { + /* Remove the pending RX transfer at the head of the RX pending queue. */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.pend); + DEBUGASSERT(bfcontainer && bfcontainer->apb); + + apb = bfcontainer->apb; + DEBUGASSERT(((uintptr_t)apb->samp % priv->align) == 0); + + /* No data received yet */ + + apb->nbytes = 0; + apb->curbyte = 0; + + /* Physical address of the SSC RHR register and of the buffer location + * in RAM. + */ + + regaddr = ssc_regaddr(priv, SAM_SSC_RHR_OFFSET); + memaddr = (uintptr_t)apb->samp; + + /* Configure the RX DMA */ + + sam_dmarxsetup(priv->rx.dma, regaddr, memaddr, apb->nmaxbytes); + + /* Increment the DMA timeout */ + + if (bfcontainer->timeout > 0) + { + timeout += bfcontainer->timeout; + } + else + { + notimeout = true; + } + + /* Add the container to the list of active DMAs */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.act); + + /* Invalidate the data cache so that nothing gets flush into the + * DMA buffer after starting the DMA transfer. + */ +#warning Not yet supported +#if 0 + arch_invalidate_dcache((uintptr_t)apb->samp, + (uintptr_t)apb->samp + apb->nmaxbytes); +#endif + } +#if 1 /* REVISIT: Chained RX transfers */ + while (0); +#else + while (!sq_empty(&priv->rx.pend)); +#endif + + /* Sample DMA registers */ + + ssc_rxdma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA, saving the container as the current active transfer */ + + sam_dmastart(priv->rx.dma, ssc_rxdma_callback, priv); + ssc_rxdma_sample(priv, DMA_AFTER_START); + + /* Enable the receiver */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXEN); + + /* Start a watchdog to catch DMA timeouts */ + + if (!notimeout) + { + ret = wd_start(priv->rx.dog, timeout, (wdentry_t)ssc_rxdma_timeout, + 1, (uint32_t)priv); + + /* Check if we have successfully started the watchdog timer. Note + * that we do nothing in the case of failure to start the timer. We + * are already committed to the DMA anyway. Let's just hope that the + * DMA does not hang. + */ + + if (ret < 0) + { + i2slldbg("ERROR: wd_start failed: %d\n", errno); + } + } + + ssc_dump_rxqueues(priv, "RX DMA started"); + return OK; +} +#endif + +/**************************************************************************** + * Name: ssc_rx_worker + * + * Description: + * RX transfer done worker + * + * Input Parameters: + * arg - the SSC device instance cast to void* + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rx_worker(void *arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + irqstate_t flags; + + DEBUGASSERT(priv); + + /* When the transfer was started, the active buffer containers were removed + * from the rx.pend queue and saved in the rx.act queue. We get here when the + * DMA is finished... either successfully, with a DMA error, or with a DMA + * timeout. + * + * In any case, the buffer containers in rx.act will be moved to the end + * of the rx.done queue and rx.act queue will be emptied before this worker + * is started. + * + * REVISIT: Normal DMA callback processing should restart the DMA + * immediately to avoid audio artifacts at the boundaries between DMA + * transfers. Unfortunately, the DMA callback occurs at the interrupt + * level and we cannot call dma_rxsetup() from the interrupt level. + * So we have to start the next DMA here. + */ + + i2svdbg("rx.act.head=%p rx.done.head=%p\n", + priv->rx.act.head, priv->rx.done.head); + ssc_dump_rxqueues(priv, "RX worker start"); + + /* Check if the DMA is IDLE */ + + if (sq_empty(&priv->rx.act)) + { +#ifdef CONFIG_SAMV7_SSC_DMADEBUG + bfcontainer = (struct sam_buffer_s *)sq_peek(&priv->rx.done); + if (bfcontainer) + { + /* Dump the DMA registers */ + + ssc_rxdma_sampledone(priv, bfcontainer->result); + } +#endif + + /* Then start the next DMA. This must be done with interrupts + * disabled. + */ + + flags = enter_critical_section(); + (void)ssc_rxdma_setup(priv); + leave_critical_section(flags); + } + + /* Process each buffer in the rx.done queue */ + + while (sq_peek(&priv->rx.done) != NULL) + { + /* Remove the buffer container from the rx.done queue. NOTE that + * interrupts must be enabled to do this because the rx.done queue is + * also modified from the interrupt level. + */ + + flags = enter_critical_section(); + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.done); + leave_critical_section(flags); + + DEBUGASSERT(bfcontainer && bfcontainer->apb && bfcontainer->callback); + apb = bfcontainer->apb; + + /* If the DMA was successful, then update the number of valid bytes in + * the audio buffer. + */ + + if (bfcontainer->result == OK) + { + apb->nbytes = apb->nmaxbytes; + } + + ssc_dump_buffer("Received", apb->samp, apb->nbytes); + + /* Perform the RX transfer done callback */ + + bfcontainer->callback(&priv->dev, apb, bfcontainer->arg, + bfcontainer->result); + + /* Release our reference on the audio buffer. This may very likely + * cause the audio buffer to be freed. + */ + + apb_free(apb); + + /* And release the buffer container */ + + ssc_buf_free(priv, bfcontainer); + } + + ssc_dump_rxqueues(priv, "RX worker done"); +} +#endif + +/**************************************************************************** + * Name: ssc_rx_schedule + * + * Description: + * An RX DMA completion or timeout has occurred. Schedule processing on + * the working thread. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rx_schedule(struct sam_ssc_s *priv, int result) +{ + struct sam_buffer_s *bfcontainer; + int ret; + + /* Upon entry, the transfer(s) that just completed are the ones in the + * priv->rx.act queue. NOTE: In certain conditions, this function may + * be called an additional time, hence, we can't assert this to be true. + * For example, in the case of a timeout, this function will be called by + * both indirectly via the sam_dmastop() logic and directly via the + * ssc_rxdma_timeout() logic. + */ + + ssc_dump_rxqueues(priv, "RX schedule"); + + /* Move all entries from the rx.act queue to the rx.done queue */ + + while (!sq_empty(&priv->rx.act)) + { + /* Remove the next buffer container from the rx.act list */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->rx.act); + + /* Report the result of the transfer */ + + bfcontainer->result = result; + + /* Add the completed buffer container to the tail of the rx.done queue */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.done); + } + + /* If the worker has completed running, then reschedule the working thread. + * REVISIT: There may be a race condition here. So we do nothing is the + * worker is not available. + */ + + if (work_available(&priv->rx.work)) + { + /* Schedule the TX DMA done processing to occur on the worker thread. */ + + ret = work_queue(HPWORK, &priv->rx.work, ssc_rx_worker, priv, 0); + if (ret != 0) + { + i2slldbg("ERROR: Failed to queue RX work: %d\n", ret); + } + } +} +#endif + +/**************************************************************************** + * Name: ssc_rxdma_callback + * + * Description: + * This callback function is invoked at the completion of the SSC RX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_RX +static void ssc_rxdma_callback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->rx.dog); + + /* Sample DMA registers at the time of the DMA completion */ + + ssc_rxdma_sample(priv, DMA_CALLBACK); + + /* REVISIT: We would like to the next DMA started here so that we do not + * get audio glitches at the boundaries between DMA transfers. + * Unfortunately, we cannot call sam_dmasetup() from an interrupt handler! + */ + + /* Then schedule completion of the transfer to occur on the worker thread */ + + ssc_rx_schedule(priv, result); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_timeout + * + * Description: + * The RX watchdog timeout without completion of the RX DMA. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_txdma_timeout(int argc, uint32_t arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Sample DMA registers at the time of the timeout */ + + ssc_txdma_sample(priv, DMA_TIMEOUT); + + /* Cancel the DMA */ + + sam_dmastop(priv->tx.dma); + + /* Then schedule completion of the transfer to occur on the worker thread. + * NOTE: sam_dmastop() will call the DMA complete callback with an error + * of -EINTR. So the following is just insurance and should have no + * effect if the worker is already schedule. + */ + + ssc_tx_schedule(priv, -ETIMEDOUT); +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_setup + * + * Description: + * Setup and initiate the next TX DMA transfer + * + * Input Parameters: + * priv - SSC state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static int ssc_txdma_setup(struct sam_ssc_s *priv) +{ + struct sam_buffer_s *bfcontainer; + struct ap_buffer_s *apb; + uintptr_t samp; + uintptr_t regaddr; + uintptr_t memaddr; + uint32_t timeout; + apb_samp_t nbytes; + bool notimeout; + int ret; + + /* If there is already an active transmission in progress, then bail + * returning success. + */ + + if (!sq_empty(&priv->tx.act)) + { + return OK; + } + + /* If there are no pending transfer, then bail returning success */ + + if (sq_empty(&priv->tx.pend)) + { + return OK; + } + + /* Initialize DMA register sampling */ + + ssc_txdma_sampleinit(priv); + + /* Loop, adding each pending DMA */ + + timeout = 0; + notimeout = false; + + do + { + /* Remove the pending TX transfer at the head of the TX pending queue. */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.pend); + DEBUGASSERT(bfcontainer && bfcontainer->apb); + + apb = bfcontainer->apb; + + /* Get the transfer information, accounting for any data offset */ + + samp = (uintptr_t)&apb->samp[apb->curbyte]; + nbytes = apb->nbytes - apb->curbyte; + DEBUGASSERT((samp & priv->align) == 0 && (nbytes & priv->align) == 0); + + /* Physical address of the SSC THR register and of the buffer location + * in RAM. + */ + + regaddr = ssc_regaddr(priv, SAM_SSC_THR_OFFSET); + memaddr = (uintptr_t)samp; + + /* Configure the TX DMA */ + + sam_dmatxsetup(priv->tx.dma, regaddr, memaddr, nbytes); + + /* Increment the DMA timeout */ + + if (bfcontainer->timeout > 0) + { + timeout += bfcontainer->timeout; + } + else + { + notimeout = true; + } + + /* Add the container to the list of active DMAs */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.act); + + /* Flush the data cache so that everything is in the physical memory + * before starting the DMA. + */ +#warning REVISIT +#if 1 + arch_invalidate_dcache_all(); +#else + arch_clean_dcache(samp, samp + nbytes); +#endif + } +#if 1 /* REVISIT: Chained TX transfers */ + while (0); +#else + while (!sq_empty(&priv->tx.pend)); +#endif + + /* Sample DMA registers */ + + ssc_txdma_sample(priv, DMA_AFTER_SETUP); + + /* Start the DMA, saving the container as the current active transfer */ + + sam_dmastart(priv->tx.dma, ssc_txdma_callback, priv); + ssc_txdma_sample(priv, DMA_AFTER_START); + + /* Enable the transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_TXEN); + + /* Start a watchdog to catch DMA timeouts */ + + if (!notimeout) + { + ret = wd_start(priv->tx.dog, timeout, (wdentry_t)ssc_txdma_timeout, + 1, (uint32_t)priv); + + /* Check if we have successfully started the watchdog timer. Note + * that we do nothing in the case of failure to start the timer. We + * are already committed to the DMA anyway. Let's just hope that the + * DMA does not hang. + */ + + if (ret < 0) + { + i2slldbg("ERROR: wd_start failed: %d\n", errno); + } + } + + ssc_dump_txqueues(priv, "TX DMA started"); + return OK; +} +#endif + +/**************************************************************************** + * Name: ssc_tx_worker + * + * Description: + * TX transfer done worker + * + * Input Parameters: + * arg - the SSC device instance cast to void* + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_tx_worker(void *arg) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + + DEBUGASSERT(priv); + + /* When the transfer was started, the active buffer containers were removed + * from the tx.pend queue and saved in the tx.act queue. We get here when the + * DMA is finished... either successfully, with a DMA error, or with a DMA + * timeout. + * + * In any case, the buffer containers in tx.act will be moved to the end + * of the tx.done queue and tx.act will be emptied before this worker is + * started. + * + * REVISIT: Normal DMA callback processing should restart the DMA + * immediately to avoid audio artifacts at the boundaries between DMA + * transfers. Unfortunately, the DMA callback occurs at the interrupt + * level and we cannot call dma_txsetup() from the interrupt level. + * So we have to start the next DMA here. + */ + + i2svdbg("tx.act.head=%p tx.done.head=%p\n", + priv->tx.act.head, priv->tx.done.head); + ssc_dump_txqueues(priv, "TX worker start"); + + /* Check if the DMA is IDLE */ + + if (sq_empty(&priv->tx.act)) + { +#ifdef CONFIG_SAMV7_SSC_DMADEBUG + bfcontainer = (struct sam_buffer_s *)sq_peek(&priv->tx.done); + if (bfcontainer) + { + /* Dump the DMA registers */ + + ssc_txdma_sampledone(priv, bfcontainer->result); + } +#endif + + /* Then start the next DMA. This must be done with interrupts + * disabled. + */ + + flags = enter_critical_section(); + (void)ssc_txdma_setup(priv); + leave_critical_section(flags); + } + + /* Process each buffer in the tx.done queue */ + + while (sq_peek(&priv->tx.done) != NULL) + { + /* Remove the buffer container from the tx.done queue. NOTE that + * interrupts must be enabled to do this because the tx.done queue is + * also modified from the interrupt level. + */ + + flags = enter_critical_section(); + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.done); + leave_critical_section(flags); + + /* Perform the TX transfer done callback */ + + DEBUGASSERT(bfcontainer && bfcontainer->callback); + bfcontainer->callback(&priv->dev, bfcontainer->apb, + bfcontainer->arg, bfcontainer->result); + + /* Release our reference on the audio buffer. This may very likely + * cause the audio buffer to be freed. + */ + + apb_free(bfcontainer->apb); + + /* And release the buffer container */ + + ssc_buf_free(priv, bfcontainer); + } + + ssc_dump_txqueues(priv, "TX worker done"); +} +#endif + +/**************************************************************************** + * Name: ssc_tx_schedule + * + * Description: + * An TX DMA completion or timeout has occurred. Schedule processing on + * the working thread. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + * Assumptions: + * - Interrupts are disabled + * - The TX timeout has been canceled. + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_tx_schedule(struct sam_ssc_s *priv, int result) +{ + struct sam_buffer_s *bfcontainer; + int ret; + + /* Upon entry, the transfer(s) that just completed are the ones in the + * priv->tx.act queue. NOTE: In certain conditions, this function may + * be called an additional time, hence, we can't assert this to be true. + * For example, in the case of a timeout, this function will be called by + * both indirectly via the sam_dmastop() logic and directly via the + * ssc_txdma_timeout() logic. + */ + + ssc_dump_txqueues(priv, "TX schedule"); + + /* Move all entries from the tx.act queue to the tx.done queue */ + + while (!sq_empty(&priv->tx.act)) + { + /* Remove the next buffer container from the tx.act list */ + + bfcontainer = (struct sam_buffer_s *)sq_remfirst(&priv->tx.act); + + /* Report the result of the transfer */ + + bfcontainer->result = result; + + /* Add the completed buffer container to the tail of the tx.done queue */ + + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.done); + } + + /* If the worker has completed running, then reschedule the working thread. + * REVISIT: There may be a race condition here. So we do nothing is the + * worker is not available. + */ + + if (work_available(&priv->tx.work)) + { + /* Schedule the TX DMA done processing to occur on the worker thread. */ + + ret = work_queue(HPWORK, &priv->tx.work, ssc_tx_worker, priv, 0); + if (ret != 0) + { + i2slldbg("ERROR: Failed to queue TX work: %d\n", ret); + } + } +} +#endif + +/**************************************************************************** + * Name: ssc_txdma_callback + * + * Description: + * This callback function is invoked at the completion of the SSC TX DMA. + * + * Input Parameters: + * handle - The DMA handler + * arg - A pointer to the chip select struction + * result - The result of the DMA transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SSC_HAVE_TX +static void ssc_txdma_callback(DMA_HANDLE handle, void *arg, int result) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)arg; + DEBUGASSERT(priv != NULL); + + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->tx.dog); + + /* Sample DMA registers at the time of the DMA completion */ + + ssc_txdma_sample(priv, DMA_CALLBACK); + + /* REVISIT: We would like to the next DMA started here so that we do not + * get audio glitches at the boundaries between DMA transfers. + * Unfortunately, we cannot call sam_dmasetup() from an interrupt handler! + */ + + /* Then schedule completion of the transfer to occur on the worker thread */ + + ssc_tx_schedule(priv, result); +} +#endif + +/**************************************************************************** + * Name: ssc_checkwidth + * + * Description: + * Check for a valid bit width. The SSC is capable of handling most any + * bit width from 2 to 32, but the DMA logic in this driver is constrained + * to 8-, 16-, and 32-bit data widths + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static int ssc_checkwidth(struct sam_ssc_s *priv, int bits) +{ + /* The SSC can handle most any bit width from 2 to 32. However, the DMA + * logic here is constrained to byte, half-word, and word sizes. + */ + + switch (bits) + { + case 8: +#ifdef CONFIG_DEBUG + priv->align = 0; +#endif + break; + + case 16: +#ifdef CONFIG_DEBUG + priv->align = 1; +#endif + break; + + case 32: +#ifdef CONFIG_DEBUG + priv->align = 3; +#endif + break; + + default: + i2sdbg("ERROR: Unsupported or invalid data width: %d\n", bits); + return (bits < 2 || bits > 32) ? -EINVAL : -ENOSYS; + } + + /* Save the new data width */ + + priv->datalen = bits; + return OK; +} + +/**************************************************************************** + * Name: ssc_rxsamplerate + * + * Description: + * Set the I2S RX sample rate. NOTE: This will have no effect if (1) the + * driver does not support an I2C receiver or if (2) the sample rate is + * driven by the I2C frame clock. This may also have unexpected side- + * effects of the RX sample is coupled with the TX sample rate. + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_rxsamplerate(struct i2s_dev_s *dev, uint32_t rate) +{ +#if defined(SSC_HAVE_RX) && defined(SSC_HAVE_MCK2) + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + DEBUGASSERT(priv && priv->samplerate > 0 && rate > 0); + + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->rxclk == SSC_CLKSRC_MCKDIV) + { + /* Save the new sample rate and update the MCK/2 divider */ + + priv->samplerate = rate; + return ssc_mck2divider(priv); + } +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_rxdatawidth + * + * Description: + * Set the I2S RX data width. The RX bitrate is determined by + * sample_rate * data_width. + * + * Input Parameters: + * dev - Device-specific state data + * width - The I2S data with in bits. + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_rxdatawidth(struct i2s_dev_s *dev, int bits) +{ +#ifdef SSC_HAVE_RX + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + uint32_t dmaflags; + int ret; + + DEBUGASSERT(priv && bits > 1); + + /* Check if this is a bit width that we are configured to handle */ + + ret = ssc_checkwidth(priv, bits); + if (ret < 0) + { + i2sdbg("ERROR: ssc_checkwidth failed: %d\n", ret); + return 0; + } + + /* Update the DMA flags */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return 0; + } + + /* Reconfigure the RX DMA (and TX DMA if applicable) */ + + sam_dmaconfig(priv->rx.dma, dmaflags); +#ifdef SSC_HAVE_RX + if (priv->txenab) + { + sam_dmaconfig(priv->tx.dma, dmaflags); + } +#endif + +#ifdef SSC_HAVE_MCK2 + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->rxclk == SSC_CLKSRC_MCKDIV) + { + /* Update the MCK/2 divider. bitrate is samplerate * datawidth. */ + + return ssc_mck2divider(priv); + } +#endif +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_receive + * + * Description: + * Receive a block of data from I2S. + * + * Input Parameters: + * dev - Device-specific state data + * apb - A pointer to the audio buffer in which to recieve data + * callback - A user provided callback function that will be called at + * the completion of the transfer. The callback will be + * performed in the context of the worker thread. + * arg - An opaque argument that will be provided to the callback + * when the transfer complete + * timeout - The timeout value to use. The transfer will be canceled + * and an ETIMEDOUT error will be reported if this timeout + * elapsed without completion of the DMA transfer. Units + * are system clock ticks. Zero means no timeout. + * + * Returned Value: + * OK on success; a negated errno value on failure. NOTE: This function + * only enqueues the transfer and returns immediately. Success here only + * means that the transfer was enqueued correctly. + * + * When the transfer is complete, a 'result' value will be provided as + * an argument to the callback function that will indicate if the transfer + * failed. + * + ****************************************************************************/ + +static int ssc_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; +#ifdef SSC_HAVE_RX + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + int ret; +#endif + + DEBUGASSERT(priv && apb && ((uintptr_t)apb->samp & priv->align) == 0); + i2svdbg("apb=%p nmaxbytes=%d arg=%p timeout=%d\n", + apb, apb->nmaxbytes, arg, timeout); + + ssc_init_buffer(apb->samp, apb->nmaxbytes); + +#ifdef SSC_HAVE_RX + /* Allocate a buffer container in advance */ + + bfcontainer = ssc_buf_allocate(priv); + DEBUGASSERT(bfcontainer); + + /* Get exclusive access to the SSC driver data */ + + ssc_exclsem_take(priv); + + /* Has the RX channel been enabled? */ + + if (!priv->rxenab) + { + i2sdbg("ERROR: SSC%d has no receiver\n", priv->sscno); + ret = -EAGAIN; + goto errout_with_exclsem; + } + + /* Add a reference to the audio buffer */ + + apb_reference(apb); + + /* Initialize the buffer container structure */ + + bfcontainer->callback = (void *)callback; + bfcontainer->timeout = timeout; + bfcontainer->arg = arg; + bfcontainer->apb = apb; + bfcontainer->result = -EBUSY; + + /* Add the buffer container to the end of the RX pending queue */ + + flags = enter_critical_section(); + sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend); + ssc_dump_rxqueues(priv, "Receving"); + + /* Then start the next transfer. If there is already a transfer in progess, + * then this will do nothing. + */ + + ret = ssc_rxdma_setup(priv); + DEBUGASSERT(ret == OK); + leave_critical_section(flags); + ssc_exclsem_give(priv); + return OK; + +errout_with_exclsem: + ssc_exclsem_give(priv); + ssc_buf_free(priv, bfcontainer); + return ret; + +#else + i2sdbg("ERROR: SSC%d has no receiver\n", priv->sscno); + UNUSED(priv); + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: ssc_txsamplerate + * + * Description: + * Set the I2S TX sample rate. NOTE: This will have no effect if (1) the + * driver does not support an I2C transmitter or if (2) the sample rate is + * driven by the I2C frame clock. This may also have unexpected side- + * effects of the TX sample is coupled with the RX sample rate. + * + * Input Parameters: + * dev - Device-specific state data + * rate - The I2S sample rate in samples (not bits) per second + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_txsamplerate(struct i2s_dev_s *dev, uint32_t rate) +{ +#if defined(SSC_HAVE_TX) && defined(SSC_HAVE_MCK2) + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + DEBUGASSERT(priv && priv->samplerate > 0 && rate > 0); + + /* Check if the receiver is driven by the MCK/2 */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + /* Save the new sample rate and update the MCK/2 divider */ + + priv->samplerate = rate; + return ssc_mck2divider(priv); + } +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_txdatawidth + * + * Description: + * Set the I2S TX data width. The TX bitrate is determined by + * sample_rate * data_width. + * + * Input Parameters: + * dev - Device-specific state data + * width - The I2S data with in bits. + * + * Returned Value: + * Returns the resulting bitrate + * + ****************************************************************************/ + +static uint32_t ssc_txdatawidth(struct i2s_dev_s *dev, int bits) +{ +#ifdef SSC_HAVE_TX + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; + uint32_t dmaflags; + int ret; + + DEBUGASSERT(priv && bits > 1); + + /* Check if this is a bit width that we are configured to handle */ + + ret = ssc_checkwidth(priv, bits); + if (ret < 0) + { + i2sdbg("ERROR: ssc_checkwidth failed: %d\n", ret); + return 0; + } + + /* Upate the DMA flags */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return 0; + } + + /* Reconfigure the RX DMA (and RX DMA if applicable) */ + + sam_dmaconfig(priv->tx.dma, dmaflags); +#ifdef SSC_HAVE_RX + if (priv->rxenab) + { + sam_dmaconfig(priv->rx.dma, dmaflags); + } +#endif + +#ifdef SSC_HAVE_MCK2 + /* Check if the transmitter is driven by the MCK/2 */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + /* Update the MCK/2 divider. bitrate is samplerate * datawidth. */ + + return ssc_mck2divider(priv); + } +#endif +#endif + + return 0; +} + +/**************************************************************************** + * Name: ssc_send + * + * Description: + * Send a block of data on I2S. + * + * Input Parameters: + * dev - Device-specific state data + * apb - A pointer to the audio buffer from which to send data + * callback - A user provided callback function that will be called at + * the completion of the transfer. The callback will be + * performed in the context of the worker thread. + * arg - An opaque argument that will be provided to the callback + * when the transfer complete + * timeout - The timeout value to use. The transfer will be canceled + * and an ETIMEDOUT error will be reported if this timeout + * elapsed without completion of the DMA transfer. Units + * are system clock ticks. Zero means no timeout. + * + * Returned Value: + * OK on success; a negated errno value on failure. NOTE: This function + * only enqueues the transfer and returns immediately. Success here only + * means that the transfer was enqueued correctly. + * + * When the transfer is complete, a 'result' value will be provided as + * an argument to the callback function that will indicate if the transfer + * failed. + * + ****************************************************************************/ + +static int ssc_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, + i2s_callback_t callback, void *arg, uint32_t timeout) +{ + struct sam_ssc_s *priv = (struct sam_ssc_s *)dev; +#ifdef SSC_HAVE_TX + struct sam_buffer_s *bfcontainer; + irqstate_t flags; + int ret; +#endif + + /* Make sure that we have valid pointers that that the data has uint32_t + * alignment. + */ + + DEBUGASSERT(priv && apb); + i2svdbg("apb=%p nbytes=%d arg=%p timeout=%d\n", + apb, apb->nbytes - apb->curbyte, arg, timeout); + + ssc_dump_buffer("Sending", &apb->samp[apb->curbyte], + apb->nbytes - apb->curbyte); + DEBUGASSERT(((uintptr_t)&apb->samp[apb->curbyte] & priv->align) == 0); + +#ifdef SSC_HAVE_TX + /* Allocate a buffer container in advance */ + + bfcontainer = ssc_buf_allocate(priv); + DEBUGASSERT(bfcontainer); + + /* Get exclusive access to the SSC driver data */ + + ssc_exclsem_take(priv); + + /* Has the TX channel been enabled? */ + + if (!priv->txenab) + { + i2sdbg("ERROR: SSC%d has no transmitter\n", priv->sscno); + ret = -EAGAIN; + goto errout_with_exclsem; + } + + /* Add a reference to the audio buffer */ + + apb_reference(apb); + + /* Initialize the buffer container structure */ + + bfcontainer->callback = (void *)callback; + bfcontainer->timeout = timeout; + bfcontainer->arg = arg; + bfcontainer->apb = apb; + bfcontainer->result = -EBUSY; + + /* Add the buffer container to the end of the TX pending queue */ + + flags = enter_critical_section(); + sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend); + ssc_dump_txqueues(priv, "Transmitting"); + + /* Then start the next transfer. If there is already a transfer in progess, + * then this will do nothing. + */ + + ret = ssc_txdma_setup(priv); + DEBUGASSERT(ret == OK); + leave_critical_section(flags); + ssc_exclsem_give(priv); + return OK; + +errout_with_exclsem: + ssc_exclsem_give(priv); + ssc_buf_free(priv, bfcontainer); + return ret; + +#else + i2sdbg("ERROR: SSC%d has no transmitter\n", priv->sscno); + UNUSED(priv); + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: ssc_rx/tx_configure + * + * Description: + * Configure the SSC receiver and transmitter. + * + * Input Parameters: + * priv - Fully initialized SSC device structure. + * + * Returned Value: + * OK is returned on failure. A negated errno value is returned on failure. + * + ****************************************************************************/ + +static int ssc_rx_configure(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_RX + uint32_t regval; + uint32_t fslen; + + /* Get the RX sync time (in RX clocks) */ + + DEBUGASSERT(priv->rxfslen > 0); + fslen = priv->rxfslen - 1; + + /* RCMR settings */ + /* Configure the receiver input clock */ + + regval = 0; + switch (priv->rxclk) + { + case SSC_CLKSRC_RKIN: /* Receiver clock source is RK */ + regval = SSC_RCMR_CKS_RK; + break; + + case SSC_CLKSRC_TXOUT: /* Receiver clock source is the transmitter clock */ + regval = SSC_RCMR_CKS_TK; + break; + + case SSC_CLKSRC_MCKDIV: /* Clock source is MCK divided down */ +#ifdef SSC_HAVE_MCK2 + DEBUGASSERT(priv->samplerate > 0); + regval = SSC_RCMR_CKS_MCK; + break; +#endif + + case SSC_CLKSRC_NONE: /* No clock */ + default: + i2sdbg("ERROR: No receiver clock\n"); + return -EINVAL; + } + + /* Configure the receiver output clock */ + + switch (priv->rxout) + { + case SSC_CLKOUT_CONT: /* Continuous */ + regval |= SSC_RCMR_CKO_CONT; + break; + + case SSC_CLKOUT_XFER: /* Only output clock during transfers */ + regval |= SSC_RCMR_CKO_TRANSFER; + break; + + case SSC_CLKOUT_NONE: /* No output clock */ + regval |= SSC_RCMR_CKO_NONE; + break; + + default: + i2sdbg("ERROR: Invalid clock output selection\n"); + return -EINVAL; + } + + /* REVISIT: Some of these settings will need to be configurable as well. + * Currently hardcoded to: + * + * SSC_RCMR_CKI Receive clock inversion + * SSC_RCMR_CKG_CONT No receive clock gating + * SSC_RCMR_START_EDGE Detection of any edge on RF signal + * SSC_RCMR_STOP Not selected + * SSC_RCMR_STTDLY(1) Receive start delay = 1 (same as FSLEN) + * SSC_RCMR_PERIOD(0) Receive period divider = 0 + * + * REVISIT: This implementation assumes that on the transmitter + * can be the master (i.e, can generate the TK/RK clocking. + */ + + regval |= (SSC_RCMR_CKI | SSC_RCMR_CKG_CONT | SSC_RCMR_START_EDGE | + SSC_RCMR_STTDLY(priv->rxsttdly) | SSC_RCMR_PERIOD(0)); + ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, regval); + + /* RFMR settings. Some of these settings will need to be configurable as well. + * Currently hardcoded to: + * + * SSC_RFMR_DATLEN(n) 'n' deterimined by configuration + * SSC_RFMR_LOOP Determined by configuration + * SSC_RFMR_MSBF Most significant bit first + * SSC_RFMR_DATNB(n) Data number 'n' per frame (hard-coded) + * SSC_RFMR_FSLEN Set to LS 4 bits of (CONFIG_SSCx_RX_FSLEN-1) + * SSC_RFMR_FSLEN(1) Pulse length = FSLEN + (FSLEN_EXT * 16) + 1 = 2 clocks + * SSC_RFMR_FSOS_NONE RF pin is always in input + * SSC_RFMR_FSEDGE_POS Positive frame sync edge detection + * SSC_RFMR_FSLENEXT I Set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + */ + + regval = (SSC_RFMR_DATLEN(CONFIG_SAMV7_SSC0_DATALEN - 1) | SSC_RFMR_MSBF | + SSC_RFMR_DATNB(SSC_DATNB - 1) | SSC_RFMR_FSOS_NONE); + + /* Set the RX frame synch */ + + regval |= (SSC_RFMR_FSLEN(fslen & 0x0f) | SSC_RFMR_FSLENEXT((fslen >> 4) & 0x0f)); + + /* Loopback mode? */ + + if (priv->loopback) + { + regval |= SSC_RFMR_LOOP; + } + + ssc_putreg(priv, SAM_SSC_RFMR_OFFSET, regval); + +#else + ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, 0); + ssc_putreg(priv, SAM_SSC_RFMR_OFFSET, 0); + +#endif + + /* Disable the receiver */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS); + return OK; +} + +static int ssc_tx_configure(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_TX + uint32_t regval; + uint32_t fslen; + uint32_t period; + + /* Get the TX synch in (in TX clocks) */ + + fslen = priv->txfslen > 0 ? priv->txfslen - 1 : 0; + + /* From the start delay and the datalength , we can get the full + * period of the waveform. + */ + + period = SCC_PERIOD(priv->txsttdly, priv->datalen); + + /* TCMR settings */ + /* Configure the transmitter input clock */ + + regval = 0; + switch (priv->txclk) + { + case SSC_CLKSRC_TKIN: /* Transmitter clock source is TK */ + regval = SSC_TCMR_CKS_TK; + break; + + case SSC_CLKSRC_RXOUT: /* Transmitter clock source is the receiver clock */ + regval = SSC_TCMR_CKS_RK; + break; + + case SSC_CLKSRC_MCKDIV: /* Clock source is MCK divided down */ +#ifdef SSC_HAVE_MCK2 + DEBUGASSERT(priv->samplerate > 0); + regval = SSC_TCMR_CKS_MCK; + break; +#endif + + case SSC_CLKSRC_NONE: /* No clock */ + default: + i2sdbg("ERROR: No transmitter clock\n"); + return -EINVAL; + } + + /* Configure the receiver output clock */ + + switch (priv->txout) + { + case SSC_CLKOUT_CONT: /* Continuous */ + regval |= SSC_TCMR_CKO_CONT; + break; + + case SSC_CLKOUT_XFER: /* Only output clock during transfers */ + regval |= SSC_TCMR_CKO_TRANSFER; + break; + + case SSC_CLKOUT_NONE: /* No output clock */ + regval |= SSC_TCMR_CKO_NONE; + break; + + default: + i2sdbg("ERROR: Invalid clock output selection\n"); + return -EINVAL; + } + + /* REVISIT: Some of these settings will need to be configurable as well. + * Currently hard-coded to: + * + * SSC_RCMR_CKI No transmitter clock inversion + * SSC_RCMR_CKG_CONT No transmit clock gating + * SSC_TCMR_STTDLY(1) Receive start delay = 2 clocks (same as FSLEN) + * + * If master (i.e., provides clocking): + * SSC_TCMR_START_CONT When data written to THR + * SSC_TCMR_PERIOD(n) 'n' depends on the datawidth + * + * If slave (i.e., receives clocking): + * SSC_TCMR_START_EDGE Detection of any edge on TF signal + * SSC_TCMR_PERIOD(0) Receive period divider = 0 + * + * The period signal is generated at clocks = 2 x (PERIOD+1), or + * PERIOD = (clocks / 2) - 1. + */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_CONT | + SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(period / 2 - 1)); + } + else + { + regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_EDGE | + SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(0)); + } + + ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, regval); + + /* TFMR settings. Some of these settings will need to be configurable as well. + * Currently set to: + * + * SSC_TFMR_DATLEN(n) 'n' determined by configuration + * SSC_TFMR_DATDEF Data default = 0 + * SSC_TFMR_MSBF Most significant bit first + * SSC_TFMR_DATNB(n) Data number 'n' per frame (hard-coded) + * SSC_TFMR_FSDEN Enabled if CONFIG_SSCx_TX_FSLEN > 0 + * SSC_TFMR_FSLEN If enabled, set to LS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + * SSC_TFMR_FSLENEXT If enabled, set to MS 4 bits of (CONFIG_SSCx_TX_FSLEN-1) + * + * If master (i.e., provides clocking): + * SSC_TFMR_FSOS_NEGATIVE Negative pulse TF output + * + * If slave (i.e, receives clocking): + * SSC_TFMR_FSOS_NONE TF is an output + */ + + if (priv->txclk == SSC_CLKSRC_MCKDIV) + { + regval = (SSC_TFMR_DATLEN(priv->datalen - 1) | + SSC_TFMR_MSBF | SSC_TFMR_DATNB(SSC_DATNB - 1) | + SSC_TFMR_FSOS_NEGATIVE); + } + else + { + regval = (SSC_TFMR_DATLEN(priv->datalen - 1) | + SSC_TFMR_MSBF | SSC_TFMR_DATNB(SSC_DATNB - 1) | + SSC_TFMR_FSOS_NONE); + } + + /* Is the TX frame synch enabled? */ + + if (priv->txfslen > 0) + { + /* Yes.. Set the FSDEN bit and the FSLEN field */ + + regval |= (SSC_TFMR_FSDEN | SSC_TFMR_FSLEN(fslen & 0x0f) | + SSC_TFMR_FSLENEXT((fslen >> 4) & 0x0f)); + } + + ssc_putreg(priv, SAM_SSC_TFMR_OFFSET, regval); + +#else + ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, 0); + ssc_putreg(priv, SAM_SSC_TFMR_OFFSET, 0); + +#endif + + /* Disable the transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_TXDIS); + return OK; +} + +/**************************************************************************** + * Name: ssc_mck2divider + * + * Description: + * Setup the MCK/2 divider based on the currently selected data width and + * the sample rate + * + * Input Parameter: + * priv - I2C device structure (only the sample rate and data length is + * needed at this point). + * + * Returned Value: + * The current bitrate + * + ****************************************************************************/ + +static uint32_t ssc_mck2divider(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_MCK2 + uint32_t bitrate; + uint32_t regval; + DEBUGASSERT(priv && priv->samplerate > 0 && priv->datalen > 0); + + /* A zero sample rate means to disable the MCK/2 clock */ + + if (priv->samplerate == 0) + { + bitrate = 0; + regval = 0; + } + else + { + /* Calculate the new bitrate in Hz */ + + bitrate = priv->samplerate * priv->datalen; + + /* Calculate the new MCK/2 divider from the bitrate. The divided clock + * equals: + * + * bitrate = MCK / (2 * div) + * div = MCK / (2 * bitrate) + * + * The maximum bit rate is MCK/2. The minimum bit rate is + * MCK/2 x 4095 = MCK/8190. + */ + + regval = (BOARD_MCK_FREQUENCY + bitrate) / (bitrate << 1); + } + + /* Configure MCK/2 divider */ + + ssc_putreg(priv, SAM_SSC_CMR_OFFSET, regval); + return bitrate; +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: ssc_clocking + * + * Description: + * Enable and configure clocking to the SSC + * + * Input Parameter: + * priv - Partially initialized I2C device structure (only the PID is + * needed at this point). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_clocking(struct sam_ssc_s *priv) +{ + uint32_t regval; + uint32_t mck; + + /* Determine the maximum SSC peripheral clock frequency */ + + mck = BOARD_MCK_FREQUENCY; +#ifdef SAMV7_HAVE_PMC_PCR_DIV + DEBUGASSERT((mck >> 3) <= SAM_SSC_MAXPERCLK); + + if (mck <= SAM_SSC_MAXPERCLK) + { + priv->frequency = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= SAM_SSC_MAXPERCLK) + { + priv->frequency = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= SAM_SSC_MAXPERCLK) + { + priv->frequency = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else /* if ((mck >> 3) <= SAM_SSC_MAXPERCLK) */ + { + priv->frequency = (mck >> 3); + regval = PMC_PCR_DIV8; + } + +#else + /* No PCR_DIV field */ + + priv->frequency = mck; + regval = 0; +#endif + + /* Set the maximum SSC peripheral clock frequency */ + + regval |= PMC_PCR_PID(priv->pid) | PMC_PCR_CMD | PMC_PCR_EN; + putreg32(regval, SAM_PMC_PCR); + + /* Reset, disable receiver & transmitter */ + + ssc_putreg(priv, SAM_SSC_CR_OFFSET, SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST); + + /* Configure MCK/2 divider */ + + (void)ssc_mck2divider(priv); + + /* Enable peripheral clocking */ + + sam_enableperiph1(priv->pid); + + i2svdbg("PCSR1=%08x PCR=%08x CMR=%08x\n", + getreg32(SAM_PMC_PCSR1), regval, + ssc_getreg(priv, SAM_SSC_CMR_OFFSET)); +} + +/**************************************************************************** + * Name: ssc_dma_flags + * + * Description: + * Determine DMA FLAGS based on PID and data width + * + * Input Parameters: + * priv - Partially initialized I2C device structure. + * dmaflags - Location to return the DMA flags. + * + * Returned Value: + * OK on success; a negated errno value on failure + * + ****************************************************************************/ + +static int ssc_dma_flags(struct sam_ssc_s *priv, uint32_t *dmaflags) +{ + uint32_t flags; + + switch (priv->datalen) + { + case 8: + flags = DMA8_FLAGS; + break; + + case 16: + flags = DMA16_FLAGS; + break; + + case 32: + flags = DMA32_FLAGS; + break; + + default: + i2sdbg("ERROR: Unsupported data width: %d\n", priv->datalen); + return -ENOSYS; + } + + *dmaflags = (flags | DMACH_FLAG_PERIPHPID(priv->pid)); + return OK; +} + +/**************************************************************************** + * Name: ssc_dma_allocate + * + * Description: + * Allocate SCC DMA channels + * + * Input Parameters: + * priv - Partially initialized I2C device structure. This function + * will complete the DMA specific portions of the initialization + * + * Returned Value: + * OK on success; A negated errno value on failure. + * + ****************************************************************************/ + +static int ssc_dma_allocate(struct sam_ssc_s *priv) +{ + uint32_t dmaflags; + int ret; + + /* Get the DMA flags for this channel */ + + ret = ssc_dma_flags(priv, &dmaflags); + if (ret < 0) + { + i2sdbg("ERROR: ssc_dma_flags failed: %d\n", ret); + return ret; + } + + /* Allocate DMA channels. */ + +#ifdef SSC_HAVE_RX + if (priv->rxenab) + { + /* Allocate an RX DMA channel */ + + priv->rx.dma = sam_dmachannel(0, dmaflags); + if (!priv->rx.dma) + { + i2sdbg("ERROR: Failed to allocate the RX DMA channel\n"); + goto errout; + } + + /* Create a watchdog time to catch RX DMA timeouts */ + + priv->rx.dog = wd_create(); + if (!priv->rx.dog) + { + i2sdbg("ERROR: Failed to create the RX DMA watchdog\n"); + goto errout; + } + } +#endif + +#ifdef SSC_HAVE_TX + if (priv->txenab) + { + /* Allocate a TX DMA channel */ + + priv->tx.dma = sam_dmachannel(0, dmaflags); + if (!priv->tx.dma) + { + i2sdbg("ERROR: Failed to allocate the TX DMA channel\n"); + goto errout; + } + + /* Create a watchdog time to catch TX DMA timeouts */ + + priv->tx.dog = wd_create(); + if (!priv->tx.dog) + { + i2sdbg("ERROR: Failed to create the TX DMA watchdog\n"); + goto errout; + } + } +#endif + + /* Success exit */ + + return OK; + + /* Error exit */ + +errout: + ssc_dma_free(priv); + return -ENOMEM; +} + +/**************************************************************************** + * Name: ssc_dma_free + * + * Description: + * Release DMA-related resources allocated by ssc_dma_allocate() + * + * Input Parameters: + * priv - Partially initialized I2C device structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssc_dma_free(struct sam_ssc_s *priv) +{ +#ifdef SSC_HAVE_TX + if (priv->tx.dog) + { + wd_delete(priv->tx.dog); + } + + if (priv->tx.dma) + { + sam_dmafree(priv->tx.dma); + } +#endif + +#ifdef SSC_HAVE_RX + if (priv->rx.dog) + { + wd_delete(priv->rx.dog); + } + + if (priv->rx.dma) + { + sam_dmafree(priv->rx.dma); + } +#endif +} + +/**************************************************************************** + * Name: ssc0/1_configure + * + * Description: + * Configure SSC0 and/or SSC1 + * + * Input Parameters: + * priv - Partially initialized I2C device structure. These functions + * will complete the SSC specific portions of the initialization + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_SSC0 +static void ssc0_configure(struct sam_ssc_s *priv) +{ + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + +#ifdef CONFIG_SAMV7_SSC0_RX + priv->rxenab = true; + + /* Configure the receiver data (RD) and receiver frame synchro (RF) pins */ + + sam_configgpio(GPIO_SSC0_RD); + sam_configgpio(GPIO_SSC0_RF); + +#if defined(CONFIG_SAMV7_SSC0_RX_RKINPUT) + /* Configure the RK pin only if we are using an external clock to drive + * the receiver clock. + * + * REVISIT: The SSC is also capable of generated the receiver clock + * output on the RK pin. + */ + + sam_configgpio(GPIO_SSC0_RK); /* External clock received on the RK I/O pad */ + priv->rxclk = SSC_CLKSRC_RKIN; + +#elif defined(CONFIG_SAMV7_SSC0_RX_TXCLK) + priv->rxclk = SSC_CLKSRC_TXOUT; + +#elif defined(CONFIG_SAMV7_SSC0_RX_MCKDIV) + priv->rxclk = SSC_CLKSRC_MCKDIV; + +#else + priv->rxclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember parameters of the configured waveform */ + + priv->rxfslen = CONFIG_SSC0_RX_FSLEN; + priv->rxsttdly = CONFIG_SSC0_RX_STTDLY; + + /* Remember the configured RX clock output */ + +#if defined(CONFIG_SAMV7_SSC0_RX_RKOUTPUT_CONT) + priv->rxout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMV7_SSC0_RX_RKOUTPUT_XFR) + priv->rxout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMV7_SSC0_RX_RKOUTPUT_NONE) */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->rxenab = false; + priv->rxclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMV7_SSC0_RX */ + +#ifdef CONFIG_SAMV7_SSC0_TX + priv->txenab = true; + + /* Configure the transmitter data (TD) and transmitter frame synchro (TF) + * pins + */ + + sam_configgpio(GPIO_SSC0_TD); + sam_configgpio(GPIO_SSC0_TF); + +#if defined(CONFIG_SAMV7_SSC0_TX_TKINPUT) + /* Configure the TK pin only if we are using an external clock to drive + * the transmitter clock. + * + * REVISIT: The SSC is also capable of generated the transmitter clock + * output on the TK pin. + */ + + sam_configgpio(GPIO_SSC0_TK); /* External clock received on the TK I/O pad */ + priv->txclk = SSC_CLKSRC_TKIN; + +#elif defined(CONFIG_SAMV7_SSC0_TX_RXCLK) + priv->txclk = SSC_CLKSRC_RXOUT; + +#elif defined(CONFIG_SAMV7_SSC0_TX_MCKDIV) + priv->txclk = SSC_CLKSRC_MCKDIV; + +#else + priv->txclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember the configured TX clock output */ + +#if defined(CONFIG_SAMV7_SSC0_TX_TKOUTPUT_CONT) + priv->txout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMV7_SSC0_TX_TKOUTPUT_XFR) + priv->txout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMV7_SSC0_TX_TKOUTPUT_NONE) */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->txenab = false; + priv->txclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMV7_SSC0_TX */ + + /* Remember parameters of the configured waveform */ + + priv->txfslen = CONFIG_SSC0_TX_FSLEN; + priv->txsttdly = CONFIG_SSC0_TX_STTDLY; + + /* Set/clear loopback mode */ + +#if defined(CONFIG_SAMV7_SSC0_RX) && defined(CONFIG_SAMV7_SSC0_TX) && \ + defined(CONFIG_SAMV7_SSC0_LOOPBACK) + priv->loopback = true; +#else + priv->loopback = false; +#endif + + /* Does the receiver or transmitter need to have the MCK divider set up? */ + +#if defined(SSC0_HAVE_MCK2) + priv->samplerate = CONFIG_SAMV7_SSC0_MCKDIV_SAMPLERATE; +#elif defined(SSC_HAVE_MCK2) + priv->samplerate = 0; +#endif + + /* Configure driver state specific to this SSC peripheral */ + + priv->base = SAM_SSC0_BASE; + priv->datalen = CONFIG_SAMV7_SSC0_DATALEN; +#ifdef CONFIG_DEBUG + priv->align = SAMV7_SSC0_DATAMASK; +#endif + priv->pid = SAM_PID_SSC0; +} +#endif + +#ifdef CONFIG_SAMV7_SSC1 +static void ssc1_configure(struct sam_ssc_s *priv) +{ + /* Configure multiplexed pins as connected on the board. Chip + * select pins must be selected by board-specific logic. + */ + +#ifdef CONFIG_SAMV7_SSC1_RX + priv->rxenab = true; + + /* Configure the receiver data (RD) and receiver frame synchro (RF) pins */ + + sam_configgpio(GPIO_SSC1_RD); + sam_configgpio(GPIO_SSC1_RF); + +#ifdef CONFIG_SAMV7_SSC1_RX_RKINPUT + /* Configure the RK pin only if we are using an external clock to drive + * the receiver clock. + * + * REVISIT: The SSC is also capable of generated the receiver clock + * output on the RK pin. + */ + + sam_configgpio(GPIO_SSC1_RK); /* External clock received on the RK I/O pad */ + priv->rxclk = SSC_CLKSRC_RKIN; + +#elif defined(CONFIG_SAMV7_SSC1_RX_TXCLK) + priv->rxclk = SSC_CLKSRC_TXOUT; + +#elif defined(CONFIG_SAMV7_SSC1_RX_MCKDIV) + priv->rxclk = SSC_CLKSRC_MCKDIV; + +#else + priv->rxclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember parameters of the configured waveform */ + + priv->rxfslen = CONFIG_SSC1_RX_FSLEN; + priv->rxsttdly = CONFIG_SSC1_RX_STTDLY; + + /* Remember the configured RX clock output */ + +#if defined(CONFIG_SAMV7_SSC1_RX_RKOUTPUT_CONT) + priv->rxout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMV7_SSC1_RX_RKOUTPUT_XFR) + priv->rxout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMV7_SSC1_RX_RKOUTPUT_NONE) */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->rxenab = false; + priv->rxclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->rxout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMV7_SSC1_RX */ + +#ifdef CONFIG_SAMV7_SSC1_TX + priv->txenab = true; + + /* Configure the transmitter data (TD) and transmitter frame synchro (TF) + * pins + */ + + sam_configgpio(GPIO_SSC1_TD); + sam_configgpio(GPIO_SSC1_TF); + +#if defined(CONFIG_SAMV7_SSC1_TX_TKINPUT) + /* Configure the TK pin only if we are using an external clock to drive + * the transmitter clock. + * + * REVISIT: The SSC is also capable of generated the transmitter clock + * output on the TK pin. + */ + + sam_configgpio(GPIO_SSC1_TK); /* External clock received on the TK I/O pad */ + priv->txclk = SSC_CLKSRC_TKIN; + +#elif defined(CONFIG_SAMV7_SSC1_TX_RXCLK) + priv->txclk = SSC_CLKSRC_RXOUT; + +#elif defined(CONFIG_SAMV7_SSC1_TX_MCKDIV) + priv->txclk = SSC_CLKSRC_MCKDIV; + +#else + priv->txclk = SSC_CLKSRC_NONE; + +#endif + + /* Remember the configured TX clock output */ + +#if defined(CONFIG_SAMV7_SSC1_TX_TKOUTPUT_CONT) + priv->txout = SSC_CLKOUT_CONT; /* Continuous */ +#elif defined(CONFIG_SAMV7_SSC1_TX_TKOUTPUT_XFR) + priv->txout = SSC_CLKOUT_XFER; /* Only output clock during transfers */ +#else /* if defined(CONFIG_SAMV7_SSC1_TX_TKOUTPUT_NONE) */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ +#endif + +#else + priv->txenab = false; + priv->txclk = SSC_CLKSRC_NONE; /* No input clock */ + priv->txout = SSC_CLKOUT_NONE; /* No output clock */ + +#endif /* CONFIG_SAMV7_SSC1_TX */ + + /* Remember parameters of the configured waveform */ + + priv->txfslen = CONFIG_SSC1_TX_FSLEN; + priv->txsttdly = CONFIG_SSC1_TX_STTDLY; + + /* Set/clear loopback mode */ + +#if defined(CONFIG_SAMV7_SSC1_RX) && defined(CONFIG_SAMV7_SSC1_TX) && \ + defined(CONFIG_SAMV7_SSC1_LOOPBACK) + priv->loopback = true; +#else + priv->loopback = false; +#endif + + /* Does the receiver or transmitter need to have the MCK divider set up? */ + +#if defined(SSC1_HAVE_MCK2) + priv->samplerate = CONFIG_SAMV7_SSC1_MCKDIV_SAMPLERATE; +#elif defined(SSC_HAVE_MCK2) + priv->samplerate = 0; +#endif + + /* Configure driver state specific to this SSC peripheral */ + + priv->base = SAM_SSC1_BASE; + priv->datalen = CONFIG_SAMV7_SSC1_DATALEN; +#ifdef CONFIG_DEBUG + priv->align = SAMV7_SSC1_DATAMASK; +#endif + priv->pid = SAM_PID_SSC1; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ssc_initialize + * + * Description: + * Initialize the selected SSC port + * + * Input Parameter: + * port - I2S "port" number (identifying the "logical" SSC port) + * + * Returned Value: + * Valid SSC device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct i2s_dev_s *sam_ssc_initialize(int port) +{ + struct sam_ssc_s *priv; + irqstate_t flags; + int ret; + + /* The support SAM parts have only a single SSC port */ + + i2svdbg("port: %d\n", port); + + /* Allocate a new state structure for this chip select. NOTE that there + * is no protection if the same chip select is used in two different + * chip select structures. + */ + + priv = (struct sam_ssc_s *)zalloc(sizeof(struct sam_ssc_s)); + if (!priv) + { + i2sdbg("ERROR: Failed to allocate a chip select structure\n"); + return NULL; + } + + /* Set up the initial state for this chip select structure. Other fields + * were zeroed by zalloc(). + */ + + /* Initialize the common parts for the SSC device structure */ + + sem_init(&priv->exclsem, 0, 1); + priv->dev.ops = &g_sscops; + priv->sscno = port; + + /* Initialize buffering */ + + ssc_buf_initialize(priv); + + flags = enter_critical_section(); +#ifdef CONFIG_SAMV7_SSC0 + if (port == 0) + { + ssc0_configure(priv); + } + else +#endif /* CONFIG_SAMV7_SSC0 */ +#ifdef CONFIG_SAMV7_SSC1 + if (port == 1) + { + ssc1_configure(priv); + } + else +#endif /* CONFIG_SAMV7_SSC1 */ + { + i2sdbg("ERROR: Unsupported I2S port: %d\n", port); + goto errout_with_alloc; + } + + /* Allocate DMA channels */ + + ret = ssc_dma_allocate(priv); + if (ret < 0) + { + goto errout_with_alloc; + } + + /* Configure and enable clocking */ + + ssc_clocking(priv); + + /* Configure the receiver */ + + ret = ssc_rx_configure(priv); + if (ret < 0) + { + i2sdbg("ERROR: Failed to configure the receiver: %d\n", ret); + goto errout_with_clocking; + } + + /* Configure the transmitter */ + + ret = ssc_tx_configure(priv); + if (ret < 0) + { + i2sdbg("ERROR: Failed to configure the transmitter: %d\n", ret); + goto errout_with_clocking; + } + + leave_critical_section(flags); + scc_dump_regs(priv, "After initialization"); + + /* Success exit */ + + return &priv->dev; + + /* Failure exits */ + +errout_with_clocking: + sam_disableperiph1(priv->pid); + ssc_dma_free(priv); + +errout_with_alloc: + sem_destroy(&priv->exclsem); + kmm_free(priv); + return NULL; +} + +#endif /* SSC_HAVE_RX || SSC_HAVE_TX */ +#endif /* CONFIG_SAMV7_SSC0 || CONFIG_SAMV7_SSC1 */ diff --git a/arch/arm/src/samv7/sam_ssc.h b/arch/arm/src/samv7/sam_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..567b655c3629a7bf11d8675f67abc83157d5f7af --- /dev/null +++ b/arch/arm/src/samv7/sam_ssc.h @@ -0,0 +1,101 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_ssc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_SSC_H +#define __ARCH_ARM_SRC_SAMV7_SAM_SSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/sam_ssc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_ssc_initialize + * + * Description: + * Initialize the selected I2S port. + * + * Input Parameter: + * Port number (for hardware that has multiple I2S interfaces) + * + * Returned Value: + * Valid I2S device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2s_dev_s *sam_ssc_initialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_SSC_H */ diff --git a/arch/arm/src/samv7/sam_start.c b/arch/arm/src/samv7/sam_start.c new file mode 100644 index 0000000000000000000000000000000000000000..9d5331721f8ac341f6d845fb3ae179dabc291e34 --- /dev/null +++ b/arch/arm/src/samv7/sam_start.c @@ -0,0 +1,416 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_start.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "cache.h" +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +#include "sam_clockconfig.h" +#include "sam_mpuinit.h" +#include "sam_userspace.h" +#include "sam_start.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Memory Map ***************************************************************/ +/* 0x0400:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x041f:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x2000:0000 - Start of internal SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2005:ffff - End of internal SRAM and end of heap (a + */ + +#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void sam_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: sam_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void sam_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void sam_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define sam_fpuconfig() +#endif + +/**************************************************************************** + * Name: sam_tcmenable + * + * Description: + * Enable/disable tightly coupled memories. Size of tightly coupled + * memory regions is controlled by GPNVM Bits 7-8. + * + ****************************************************************************/ + +static inline void sam_tcmenable(void) +{ + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Assure that GPNVM 7-8 settings are as expected */ +#warning Missing logic + + /* Enabled/disabled ITCM */ + +#ifdef CONFIG_ARMV7M_ITCM + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_ITCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_ITCMCR); + + /* Enabled/disabled DTCM */ + +#ifdef CONFIG_ARMV7M_DTCM + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_DTCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_DTCMCR); + + ARM_DSB(); + ARM_ISB(); + +#ifdef CONFIG_ARMV7M_ITCM + /* Copy TCM code from flash to ITCM */ + +#warning Missing logic +#endif +} + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is geive by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs. This should be done before sam_clockconfig() is + * called (in case it has some dependency on initialized C variables). + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + sam_clockconfig(); + sam_fpuconfig(); + sam_lowsetup(); + + /* Enable/disable tightly coupled memories */ + + sam_tcmenable(); + + /* Initialize onboard resources */ + + sam_boardinitialize(); + +#ifdef CONFIG_ARM_MPU + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segements. + */ + +#ifdef CONFIG_BUILD_PROTECTED + sam_userspace(); +#endif + + /* Configure the MPU to permit user-space access to its FLASH and RAM (for + * CONFIG_BUILD_PROTECTED) or to manage cache properties (for + * CONFIG_SAMV7_QSPI). + */ + + sam_mpu_initialize(); +#endif + + /* Enable I- and D-Caches */ + + arch_dcache_writethrough(); + arch_enable_icache(); + arch_enable_dcache(); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Then start NuttX */ + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/samv7/sam_start.h b/arch/arm/src/samv7/sam_start.h new file mode 100644 index 0000000000000000000000000000000000000000..5374db9e90ed50d53c270521c425a90df75c569f --- /dev/null +++ b/arch/arm/src/samv7/sam_start.h @@ -0,0 +1,126 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_start.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_START_H +#define __ARCH_ARM_SRC_SAMV7_SAM_START_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the linker + * script. _ebss lies at the end of the BSS region. The idle task stack starts at + * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is + * the thread that the system boots on and, eventually, becomes the IDLE, do + * nothing task that runs only when there is nothing else to run. The heap + * continues from there until the end of memory. g_idle_topstack is a read-only + * variable the provides this computed address. + */ + +EXTERN const uintptr_t g_idle_topstack; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void sam_lowsetup(void); + +/************************************************************************************ + * Name: sam_boardinitialize + * + * Description: + * All SAMV7 architectures must provide the following entry point. This entry + * point is called early in the initialization -- after clocking and memory have + * been configured but before caches have been enabled and before any devices have + * been initialized. + * + ************************************************************************************/ + +void sam_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_START_H */ diff --git a/arch/arm/src/samv7/sam_tc.c b/arch/arm/src/samv7/sam_tc.c new file mode 100644 index 0000000000000000000000000000000000000000..03569857765ab3d2f74d711f04e53c02384a0940 --- /dev/null +++ b/arch/arm/src/samv7/sam_tc.c @@ -0,0 +1,1759 @@ +/**************************************************************************** + * arch/arm/src/SAMV7/sam_tc.c + * + * Copyright (C) 2015=2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMV71 Series Data Sheet + * NuttX SAMA5 timer/counter driver + * Atmel NoOS sample code for the SAMA5D3. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_periphclks.h" +#include "chip/sam_pinmap.h" +#include "chip/sam_pmc.h" +#include "sam_gpio.h" +#include "sam_pck.h" +#include "sam_tc.h" + +#if defined(CONFIG_SAMV7_TC0) || defined(CONFIG_SAMV7_TC1) || \ + defined(CONFIG_SAMV7_TC2) || defined(CONFIG_SAMV7_TC3) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes the static configuration of a TC channel */ + +struct sam_chconfig_s +{ + uintptr_t base; /* Channel register base address */ + uint8_t pid; /* Peripheral ID */ + uint8_t irq; /* IRQ number */ + xcpt_t handler; /* Timer interrupt handler */ + gpio_pinset_t clkset; /* CLK input PIO configuration */ + gpio_pinset_t tioaset; /* Output A PIO configuration */ + gpio_pinset_t tiobset; /* Output B PIO configuration */ +}; + +/* This structure describes the static configuration of a TC */ + +struct sam_tcconfig_s +{ + uintptr_t base; /* TC register base address */ + uint8_t tc; /* Timer/counter number */ + + /* Channels */ + + struct sam_chconfig_s channel[3]; +}; + +/* This structure describes one timer counter channel */ + +struct sam_tc_s; +struct sam_chan_s +{ + struct sam_tc_s *tc; /* Parent timer/counter */ + uintptr_t base; /* Channel register base address */ + tc_handler_t handler; /* User timer interrupt handler */ + void *arg; /* User interrupt handler argument */ + uint8_t chan; /* Channel number (0, 1, 2, ... 11} */ + bool inuse; /* True: channel is in use */ +}; + +/* This structure describes one timer/counter */ + +struct sam_tc_s +{ + sem_t exclsem; /* Assures mutually exclusive access to TC */ + uintptr_t base; /* Register base address */ + uint8_t tc; /* Timer/channel number {0, 1, 2, 3} */ + bool initialized; /* True: Timer/counter has been initialized */ + + /* Channels */ + + struct sam_chan_s channel[3]; + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_TC_REGDEBUG + bool wr; /* True:Last was a write */ + uint32_t regaddr; /* Last address */ + uint32_t regval; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/* Type of the MCK divider lookup table */ + +struct mck_divsrc_s +{ + uint8_t log2; /* Log2 of the divider */ + uint8_t tcclks; /* CMR TCCLCKS setting */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void sam_takesem(struct sam_tc_s *tc); +#define sam_givesem(tc) (sem_post(&tc->exclsem)) + +#ifdef CONFIG_SAMV7_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg); +static bool sam_checkreg(struct sam_tc_s *tc, bool wr, uint32_t regaddr, + uint32_t regval); +#else +# define sam_regdump(chan,msg) +# define sam_checkreg(tc,wr,regaddr,regval) (false) +#endif + +static inline uint32_t sam_tc_getreg(struct sam_chan_s *chan, + unsigned int offset); +static inline void sam_tc_putreg(struct sam_chan_s *chan, + unsigned int offset, uint32_t regval); + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset); +static inline void sam_chan_putreg(struct sam_chan_s *chan, + unsigned int offset, uint32_t regval); + +/* Interrupt Handling *******************************************************/ + +static int sam_tc_interrupt(struct sam_tc_s *tc, struct sam_chan_s *chan); + +#ifdef CONFIG_SAMV7_TC0 +static int sam_tc0_interrupt(int irq, void *context); +static int sam_tc1_interrupt(int irq, void *context); +static int sam_tc2_interrupt(int irq, void *context); +#endif + +#ifdef CONFIG_SAMV7_TC1 +static int sam_tc3_interrupt(int irq, void *context); +static int sam_tc4_interrupt(int irq, void *context); +static int sam_tc5_interrupt(int irq, void *context); +#endif + +#ifdef CONFIG_SAMV7_TC2 +static int sam_tc6_interrupt(int irq, void *context); +static int sam_tc7_interrupt(int irq, void *context); +static int sam_tc8_interrupt(int irq, void *context); +#endif + +#ifdef CONFIG_SAMV7_TC3 +static int sam_tc9_interrupt(int irq, void *context); +static int sam_tc10_interrupt(int irq, void *context); +static int sam_tc11_interrupt(int irq, void *context); +#endif + +/* Initialization ***********************************************************/ + +static uint32_t sam_tc_mckfreq_lookup(uint32_t ftcin, int ndx); +static inline uint32_t sam_tc_tcclks_lookup(int ndx); +static int sam_tc_mcksrc(uint32_t frequency, uint32_t *tcclks, + uint32_t *actual); +static inline struct sam_chan_s *sam_tc_initialize(int channel); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Static timer configuration */ + +#ifdef CONFIG_SAMV7_TC0 +static const struct sam_tcconfig_s g_tc012config = +{ + .base = SAM_TC012_BASE, + .tc = 0, + .channel = + { + [0] = + { + .base = SAM_TC012_CHAN_BASE(0), + .handler = sam_tc0_interrupt, + .pid = SAM_PID_TC0, + .irq = SAM_IRQ_TC0, + +#ifdef CONFIG_SAMV7_TC0_CLK0 + .clkset = GPIO_TC0_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOA0 + .tioaset = GPIO_TC0_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOB0 + .tiobset = GPIO_TC0_TIOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC012_CHAN_BASE(1), + .handler = sam_tc1_interrupt, + .pid = SAM_PID_TC1, + .irq = SAM_IRQ_TC1, + +#ifdef CONFIG_SAMV7_TC0_CLK1 + .clkset = GPIO_TC1_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOA1 + .tioaset = GPIO_TC1_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOB1 + .tiobset = GPIO_TC1_TIOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC012_CHAN_BASE(2), + .handler = sam_tc2_interrupt, + .pid = SAM_PID_TC2, + .irq = SAM_IRQ_TC2, + +#ifdef CONFIG_SAMV7_TC0_CLK2 + .clkset = GPIO_TC2_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOA2 + .tioaset = GPIO_TC2_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC0_TIOB2 + .tiobset = GPIO_TC2_TIOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +#ifdef CONFIG_SAMV7_TC1 +static const struct sam_tcconfig_s g_tc345config = +{ + .base = SAM_TC345_BASE, + .tc = 1, + .channel = + { + [0] = + { + .base = SAM_TC345_CHAN_BASE(3), + .handler = sam_tc3_interrupt, + .pid = SAM_PID_TC3, + .irq = SAM_IRQ_TC3, + +#ifdef CONFIG_SAMV7_TC1_CLK3 + .clkset = GPIO_TC3_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOA3 + .tioaset = GPIO_TC3_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOB3 + .tiobset = GPIO_TC3_TIOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC345_CHAN_BASE(4), + .handler = sam_tc4_interrupt, + .pid = SAM_PID_TC4, + .irq = SAM_IRQ_TC4, + +#ifdef CONFIG_SAMV7_TC1_CLK4 + .clkset = GPIO_TC4_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOA4 + .tioaset = GPIO_TC4_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOB4 + .tiobset = GPIO_TC4_TIOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC345_CHAN_BASE(5), + .handler = sam_tc5_interrupt, + .pid = SAM_PID_TC5, + .irq = SAM_IRQ_TC5, + +#ifdef CONFIG_SAMV7_TC1_CLK5 + .clkset = GPIO_TC5_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOA5 + .tioaset = GPIO_TC5_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC1_TIOB5 + .tiobset = GPIO_TC5_TIOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +#ifdef CONFIG_SAMV7_TC2 +static const struct sam_tcconfig_s g_tc678config = +{ + .base = SAM_TC678_BASE, + .tc = 2, + .channel = + { + [0] = + { + .base = SAM_TC678_CHAN_BASE(6), + .handler = sam_tc6_interrupt, + .pid = SAM_PID_TC6, + .irq = SAM_IRQ_TC6, + +#ifdef CONFIG_SAMV7_TC2_CLK6 + .clkset = GPIO_TC6_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA6 + .tioaset = GPIO_TC6_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB6 + .tiobset = GPIO_TC6_TIOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC678_CHAN_BASE(7), + .handler = sam_tc7_interrupt, + .pid = SAM_PID_TC7, + .irq = SAM_IRQ_TC7, + +#ifdef CONFIG_SAMV7_TC2_CLK7 + .clkset = GPIO_TC7_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA7 + .tioaset = GPIO_TC7_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB7 + .tiobset = GPIO_TC7_TIOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC345_CHAN_BASE(8), + .handler = sam_tc8_interrupt, + .pid = SAM_PID_TC8, + .irq = SAM_IRQ_TC8, + +#ifdef CONFIG_SAMV7_TC2_CLK8 + .clkset = GPIO_TC8_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA8 + .tioaset = GPIO_TC8_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB8 + .tiobset = GPIO_TC8_TIOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +#ifdef CONFIG_SAMV7_TC3 +static const struct sam_tcconfig_s g_tc901config = +{ + .base = SAM_TC901_BASE, + .tc = 3, + .channel = + { + [0] = + { + .base = SAM_TC901_CHAN_BASE(9), + .handler = sam_tc9_interrupt, + .pid = SAM_PID_TC9, + .irq = SAM_IRQ_TC9, + +#ifdef CONFIG_SAMV7_TC2_CLK9 + .clkset = GPIO_TC9_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA9 + .tioaset = GPIO_TC9_TIOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB9 + .tiobset = GPIO_TC9_TIOB, +#else + .tiobset = 0, +#endif + }, + [1] = + { + .base = SAM_TC901_CHAN_BASE(10), + .handler = sam_tc10_interrupt, + .pid = SAM_PID_TC10, + .irq = SAM_IRQ_TC10, + +#ifdef CONFIG_SAMV7_TC2_CLK10 + .clkset = GPIO_TC10_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA10 + .tioaset = GPIO_TC10_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB10 + .tiobset = GPIO_TC10_IOB, +#else + .tiobset = 0, +#endif + }, + [2] = + { + .base = SAM_TC345_CHAN_BASE(11), + .handler = sam_tc11_interrupt, + .pid = SAM_PID_TC11, + .irq = SAM_IRQ_TC11, + +#ifdef CONFIG_SAMV7_TC2_CLK11 + .clkset = GPIO_TC11_CLK, +#else + .clkset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOA11 + .tioaset = GPIO_TC11_IOA, +#else + .tioaset = 0, +#endif +#ifdef CONFIG_SAMV7_TC2_TIOB11 + .tiobset = GPIO_TC11_IOB, +#else + .tiobset = 0, +#endif + }, + }, +}; +#endif + +/* Timer/counter state */ + +#ifdef CONFIG_SAMV7_TC0 +static struct sam_tc_s g_tc012; +#endif + +#ifdef CONFIG_SAMV7_TC1 +static struct sam_tc_s g_tc345; +#endif + +#ifdef CONFIG_SAMV7_TC2 +static struct sam_tc_s g_tc678; +#endif + +#ifdef CONFIG_SAMV7_TC3 +static struct sam_tc_s g_tc901; +#endif + +/* TC frequency data. This table provides the frequency for each selection of TCCLK */ + +#define TC_NDIVIDERS 3 +#define TC_NDIVOPTIONS 4 + +/* This is the list of divider values: divider = (1 << value) */ + +static struct mck_divsrc_s g_log2divider[TC_NDIVOPTIONS] = +{ + /* TIMER_CLOCK1(0) -> PCK6 */ + {3, 1}, /* TIMER_CLOCK2(1) -> MCK/8 */ + {5, 2}, /* TIMER_CLOCK3(2) -> MCK/32 */ + {7, 3}, /* TIMER_CLOCK4(3) -> MCK/128 */ + {0, 4}, /* TIMER_CLOCK5(4) -> SLCK (No MCK divider) */ +}; + +/* TC register lookup used by sam_tc_setregister */ + +#define TC_NREGISTERS 3 + +static const uint8_t g_regoffset[TC_NREGISTERS] = +{ + SAM_TC_RA_OFFSET, /* Register A */ + SAM_TC_RB_OFFSET, /* Register B */ + SAM_TC_RC_OFFSET /* Register C */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sam_takesem(struct sam_tc_s *tc) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&tc->exclsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: sam_regdump + * + * Description: + * Dump all timer/counter channel and global registers + * + * NOTE: The status register is not read because reading the status + * register clears bits and, hence, may cause lost interrupts. + * + * Input Parameters: + * chan - The timer/counter channel state + * msg - Message to print with the data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TC_REGDEBUG +static void sam_regdump(struct sam_chan_s *chan, const char *msg) +{ + struct sam_tc_s *tc = chan->tc; + uintptr_t base; + + base = tc->base; + lldbg("TC%d [%08x]: %s\n", tc->tc, (int)base, msg); + lldbg(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n", + getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET), + getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET)); + + base = chan->base; + lldbg("TC%d Channel %d [%08x]: %s\n", tc->tc, chan->chan, (int)base, msg); + lldbg(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n", + getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET), + getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET)); + lldbg(" RA: %08x RB: %08x RC: %08x IMR: %08x\n", + getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET), + getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_IMR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * tc - The timer/counter peripheral state + * wr - True:write access false:read access + * regval - The regiser value associated with the access + * regaddr - The address of the register being accessed + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TC_REGDEBUG +static bool sam_checkreg(struct sam_tc_s *tc, bool wr, uint32_t regaddr, + uint32_t regval) +{ + if (wr == tc->wr && /* Same kind of access? */ + regaddr == tc->regaddr && /* Same register address? */ + regval == tc->regval) /* Same register value? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + tc->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (tc->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", tc->ntimes); + } + + /* Save information about the new access */ + + tc->wr = wr; + tc->regval = regval; + tc->regaddr = regaddr; + tc->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: sam_tc_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t sam_tc_getreg(struct sam_chan_s *chan, + unsigned int offset) +{ + struct sam_tc_s *tc = chan->tc; + uint32_t regaddr = tc->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMV7_TC_REGDEBUG + if (sam_checkreg(tc, false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_tc_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void sam_tc_putreg(struct sam_chan_s *chan, uint32_t regval, + unsigned int offset) +{ + struct sam_tc_s *tc = chan->tc; + uint32_t regaddr = tc->base + offset; + +#ifdef CONFIG_SAMV7_TC_REGDEBUG + if (sam_checkreg(tc, true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: sam_chan_getreg + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan, + unsigned int offset) +{ + uint32_t regaddr = chan->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_SAMV7_TC_REGDEBUG + if (sam_checkreg(chan->tc, false, regaddr, regval)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: sam_chan_putreg + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset, + uint32_t regval) +{ + uint32_t regaddr = chan->base + offset; + +#ifdef CONFIG_SAMV7_TC_REGDEBUG + if (sam_checkreg(chan->tc, true, regaddr, regval)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_interrupt + * + * Description: + * Common timer channel interrupt handling. + * + * Input Parameters: + * tc Timer/counter state instance + * chan Channel state instance + * + * Returned Value: + * OK on success; a negated errno value on failure + * + ****************************************************************************/ + +static int sam_tc_interrupt(struct sam_tc_s *tc, struct sam_chan_s *chan) +{ + uint32_t sr; + uint32_t imr; + uint32_t pending; + + /* Get the interrupt status for this channel */ + + sr = sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + imr = sam_chan_getreg(chan, SAM_TC_IMR_OFFSET); + pending = sr & imr; + + tcllvdbg("TC%d Channel %d: pending=%08lx\n", + tc->tc, chan->chan, (unsigned long)pending); + + /* Are there any pending interrupts for this channel? */ + + if (pending != 0) + { + /* Yes... if we have pending interrupts then interrupts must be + * enabled and we must have a handler attached. + */ + + DEBUGASSERT(chan->handler); + if (chan->handler) + { + /* Execute the callback */ + + chan->handler(chan, chan->arg, sr); + } + else + { + /* Should never happen */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_tcABC_interrupt + * + * Description: + * Timer block interrupt handlers + * + * Input Parameters: + * chan TC channel structure + * sr The status register value that generated the interrupt + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TC0 +static int sam_tc0_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc012, &g_tc012.channel[0]); +} + +static int sam_tc1_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc012, &g_tc012.channel[1]); +} + +static int sam_tc2_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc012, &g_tc012.channel[2]); +} +#endif + +#ifdef CONFIG_SAMV7_TC1 +static int sam_tc3_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc345, &g_tc345.channel[0]); +} + +static int sam_tc4_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc345, &g_tc345.channel[1]); +} + +static int sam_tc5_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc345, &g_tc345.channel[2]); +} +#endif + +#ifdef CONFIG_SAMV7_TC2 +static int sam_tc6_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc678, &g_tc678.channel[0]); +} + +static int sam_tc7_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc678, &g_tc678.channel[1]); +} + +static int sam_tc8_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc678, &g_tc678.channel[2]); +} +#endif + +#ifdef CONFIG_SAMV7_TC3 +static int sam_tc9_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc901, &g_tc901.channel[0]); +} + +static int sam_tc10_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc901, &g_tc901.channel[1]); +} + +static int sam_tc11_interrupt(int irq, void *context) +{ + return sam_tc_interrupt(&g_tc901, &g_tc901.channel[2]); +} +#endif + +/**************************************************************************** + * Initialization + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tc_mckfreq_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the + * value of the divided frequency. The slow clock source is treated as + * though it were a divided down MCK frequency. + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The divided frequency value + * + ****************************************************************************/ + +static uint32_t sam_tc_mckfreq_lookup(uint32_t ftcin, int ndx) +{ + /* The final option is to use the SLOW clock */ + + if (ndx >= TC_NDIVIDERS) + { + return BOARD_SLOWCLK_FREQUENCY; + } + else + { + return ftcin >> g_log2divider[ndx].log2; + } +} + +/**************************************************************************** + * Name: sam_tc_tcclks_lookup + * + * Description: + * Given the TC input frequency (Ftcin) and a divider index, return the + * value of the divided frequency. The slow clock source is treated as + * though it were a divided down MCK frequency. + * + * Input Parameters: + * ftcin - TC input frequency + * ndx - Divider index + * + * Returned Value: + * The divided frequency value + * + ****************************************************************************/ + +static inline uint32_t sam_tc_tcclks_lookup(int ndx) +{ + unsigned int index = g_log2divider[ndx].tcclks; + return TC_CMR_TCCLKS(index); +} + +/**************************************************************************** + * Name: sam_tc_mcksrc + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / div) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * tcclks TCCLKS field value for divisor. + * actual The actual freqency of the MCK + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +static int sam_tc_mcksrc(uint32_t frequency, uint32_t *tcclks, + uint32_t *actual) +{ + uint32_t fselect; + uint32_t fnext; + int ndx = 0; + + tcvdbg("frequency=%d\n", frequency); + + /* Satisfy lower bound. That is, the value of the divider such that: + * + * frequency >= (tc_input_frequency * 65536) / divider. + */ + + for (; ndx < TC_NDIVIDERS; ndx++) + { + fselect = sam_tc_mckfreq_lookup(BOARD_MCK_FREQUENCY, ndx); + if (frequency >= (fselect >> 16)) + { + break; + } + } + + if (ndx >= TC_NDIVIDERS) + { + /* If no divisor can be found, return -ERANGE */ + + tcdbg("Lower bound search failed\n"); + return -ERANGE; + } + + /* Try to maximize DIV while still satisfying upper bound. That the + * value of the divider such that: + * + * frequency < tc_input_frequency / divider. + */ + + for (; ndx < TC_NDIVIDERS; ndx++) + { + fnext = sam_tc_mckfreq_lookup(BOARD_MCK_FREQUENCY, ndx + 1); + if (frequency > fnext) + { + break; + } + + fselect = fnext; + } + + /* Return the actual frequency and the TCCLKS selection */ + + *actual = fselect; + *tcclks = sam_tc_tcclks_lookup(ndx); + return OK; +} + +/**************************************************************************** + * Name: sam_tc_initialize + * + * Description: + * There is no global, one-time initialization of timer/counter data + * structures. Rather, this function is called each time that a channel + * is allocated and, if the channel has not been initialized, it will be + * initialized then. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * + * Returned Value: + * A pointer to the initialized timer channel structure associated with tc + * and channel. NULL is returned on any failure. + * + * On successful return, the caller holds the tc exclusive access semaphore. + * + ****************************************************************************/ + +static inline struct sam_chan_s *sam_tc_initialize(int channel) +{ + struct sam_tc_s *tc; + const struct sam_tcconfig_s *tcconfig; + struct sam_chan_s *chan; + const struct sam_chconfig_s *chconfig; + irqstate_t flags; + uint32_t regval; + int chndx; + int ch; + int chfirst; + + /* Select the timer/counter and get the index associated with the + * channel. + */ + +#ifdef CONFIG_SAMV7_TC0 + if (channel >= 0 && channel < 3) + { + tc = &g_tc012; + tcconfig = &g_tc012config; + chfirst = 0; + } + else +#endif +#ifdef CONFIG_SAMV7_TC1 + if (channel >= 3 && channel < 6) + { + tc = &g_tc345; + tcconfig = &g_tc345config; + chfirst = 3; + } + else +#endif +#ifdef CONFIG_SAMV7_TC2 + if (channel >= 6 && channel < 9) + { + tc = &g_tc678; + tcconfig = &g_tc678config; + chfirst = 6; + } + else +#endif +#ifdef CONFIG_SAMV7_TC3 + if (channel >= 9 && channel < 12) + { + tc = &g_tc901; + tcconfig = &g_tc901config; + chfirst = 9; + } + else +#endif + { + /* Timer/counter is not invalid or not enabled */ + + tcdbg("ERROR: Bad channel number: %d\n", channel); + return NULL; + } + + /* Has the timer/counter been initialized. We have to be careful here + * because there is no semaphore protection. + */ + + flags = enter_critical_section(); + if (!tc->initialized) + { + /* Initialize the timer counter data structure. */ + + memset(tc, 0, sizeof(struct sam_tc_s)); + sem_init(&tc->exclsem, 0, 1); + tc->base = tcconfig->base; + tc->tc = tcconfig->tc; + + /* Initialize the channels */ + + for (chndx = 0, ch = chfirst; chndx < SAM_TC_NCHANNELS; chndx++) + { + /* Initialize the channel data structure */ + + chan = &tc->channel[chndx]; + chconfig = &tcconfig->channel[chndx]; + + chan->base = chconfig->base; + chan->tc = tc; + chan->chan = ch++; + + /* Disable and clear all channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + } + + /* Now the timer/counter is initialized */ + + tc->initialized = true; + } + + /* Get exclusive access to the timer/count data structure */ + + sam_takesem(tc); + leave_critical_section(flags); + + /* Is the requested channel already in-use? */ + + chndx = channel - chfirst; + chan = &tc->channel[chndx]; + + if (chan->inuse) + { + /* Yes.. return a failure */ + + tcdbg("Channel %d is in-use\n", channel); + sam_givesem(tc); + return NULL; + } + + chconfig = &tcconfig->channel[chndx]; + + /* Configure channel input/output pins */ + + if (chconfig->clkset) + { + /* Configure clock input pin */ + + sam_configgpio(chconfig->clkset); + } + + if (chconfig->tioaset) + { + /* Configure output A pin */ + + sam_configgpio(chconfig->tioaset); + } + + if (chconfig->tiobset) + { + /* Configure output B pin */ + + sam_configgpio(chconfig->tiobset); + } + + /* Enable clocking to the timer counter */ + + if (chconfig->pid < 32) + { + sam_enableperiph0(chconfig->pid); + } + else + { + sam_enableperiph1(chconfig->pid); + } + + /* Set the maximum TC peripheral clock frequency. + * REVISIT: This is from the SAMA5. Does it apply here? + */ + + regval = PMC_PCR_PID(chconfig->pid) | PMC_PCR_CMD | PMC_PCR_EN; + putreg32(regval, SAM_PMC_PCR); + + /* Attach the timer interrupt handler and enable the timer interrupts */ + + (void)irq_attach(chconfig->irq, chconfig->handler); + up_enable_irq(chconfig->irq); + + /* Mark the channel "inuse" */ + + chan->inuse = true; + + /* And return the channel with the semaphore locked */ + + sam_regdump(chan, "Initialized"); + return chan; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode) +{ + struct sam_chan_s *chan; + + /* Initialize the timer/counter data (if necessary) and get exclusive + * access to the requested channel. + */ + + tcvdbg("channel=%d mode=%08x\n", channel, mode); + + chan = sam_tc_initialize(channel); + if (chan) + { + /* Disable TC clock */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + + /* Disable channel interrupts */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL); + + /* Clear and pending status */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* And set the requested mode */ + + sam_chan_putreg(chan, SAM_TC_CMR_OFFSET, mode); + sam_regdump(chan, "Allocated"); + sam_givesem(chan->tc); + } + + /* Return an opaque reference to the channel */ + + tcvdbg("Returning %p\n", chan); + return (TC_HANDLE)chan; +} + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Freeing %p channel=%d inuse=%d\n", chan, chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Make sure that interrupts are detached and disabled and that the channel + * is stopped and disabled. + */ + + sam_tc_attach(handle, NULL, NULL, 0); + sam_tc_stop(handle); + + /* Mark the channel as available */ + + chan->inuse = false; +} + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Starting channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + /* Read the SR to clear any pending interrupts on this channel */ + + (void)sam_chan_getreg(chan, SAM_TC_SR_OFFSET); + + /* Then enable the timer (by setting the CLKEN bit). Setting SWTRIG + * will also reset the timer counter and starting the timer. + */ + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKEN | TC_CCR_SWTRG); + sam_regdump(chan, "Started"); +} + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + tcvdbg("Stopping channel %d inuse=%d\n", chan->chan, chan->inuse); + DEBUGASSERT(chan && chan->inuse); + + sam_chan_putreg(chan, SAM_TC_CCR_OFFSET, TC_CCR_CLKDIS); + sam_regdump(chan, "Stopped"); +} + +/**************************************************************************** + * Name: sam_tc_attach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. + * + * Returned Value: + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + tc_handler_t oldhandler; + irqstate_t flags; + + DEBUGASSERT(chan); + + /* Remember the old interrupt handler and set the new handler */ + + flags = enter_critical_section(); + oldhandler = chan->handler; + chan->handler = handler; + + /* Don't enable interrupt if we are detaching no matter what the caller + * says. + */ + + if (!handler) + { + arg = NULL; + mask = 0; + } + + chan->arg = arg; + + /* Now enable interrupt as requested */ + + sam_chan_putreg(chan, SAM_TC_IDR_OFFSET, TC_INT_ALL & ~mask); + sam_chan_putreg(chan, SAM_TC_IER_OFFSET, TC_INT_ALL & mask); + leave_critical_section(flags); + + return oldhandler; +} + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrupt status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_SR_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + + DEBUGASSERT(chan && regid < TC_NREGISTERS); + + tcvdbg("Channel %d: Set register RC%d to %08lx\n", + chan->chan, regid, (unsigned long)regval); + + sam_chan_putreg(chan, g_regoffset[regid], regval); + sam_regdump(chan, "Set register"); +} + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, g_regoffset[regid]); +} + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + DEBUGASSERT(chan); + return sam_chan_getreg(chan, SAM_TC_CV_OFFSET); +} + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle) +{ + struct sam_chan_s *chan = (struct sam_chan_s *)handle; + uint32_t regval; + int tcclks; + + DEBUGASSERT(chan); + + /* Get the the TC_CMR register contents for this channel and extract the + * TCCLKS index. + */ + + regval = sam_chan_getreg(chan, SAM_TC_CMR_OFFSET); + tcclks = (regval & TC_CMR_TCCLKS_MASK) >> TC_CMR_TCCLKS_SHIFT; + + /* And use the TCCLKS index to calculate the timer counter frequency */ + + if (tcclks == 0) + { + /* The tcclks value of 0 corresponds to PCK6 */ + + return sam_pck_frequency(PCK6); + } + else + { + /* Values of tcclks in the range {1,5} correspond to the divided + * down MCK or to the slow clock. + */ + + return sam_tc_mckfreq_lookup(BOARD_MCK_FREQUENCY, tcclks - 1); + } +} + +/**************************************************************************** + * Name: sam_tc_clockselect + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / div) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * tcclks TCCLKS field value for divisor. + * actual The actual freqency of the MCK + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_clockselect(uint32_t frequency, uint32_t *tcclks, + uint32_t *actual) +{ + uint32_t mck_actual; + uint32_t mck_tcclks; + uint32_t mck_error; + int ret; + + /* Try to satisfy the requested frequency with the MCK or slow clock */ + + ret = sam_tc_mcksrc(frequency, &mck_tcclks, &mck_actual); + if (ret < 0) + { + mck_error = UINT32_MAX; + } + else + { + /* Get the absolute value of the frequency error */ + + if (mck_actual > frequency) + { + mck_error = mck_actual - frequency; + } + else + { + mck_error = frequency - mck_actual; + } + } + + /* See if we do better with PCK6 */ + + if (sam_pck_isenabled(PCK6)) + { + uint32_t pck6_actual; + uint32_t pck6_error; + + /* Get the absolute value of the frequency error */ + + pck6_actual = sam_pck_frequency(PCK6); + if (pck6_actual > frequency) + { + pck6_error = pck6_actual - frequency; + } + else + { + pck6_error = frequency - pck6_actual; + } + + /* Return the PCK6 selection if the error is smaller */ + + if (pck6_error < mck_error) + { + /* Return the PCK selection */ + + if (actual) + { + tcvdbg("return actual=%lu\n", (unsigned long)fselect); + *actual = pck6_actual; + } + + /* Return the TCCLKS selection */ + + if (tcclks) + { + tcvdbg("return tcclks=%08lx\n", (unsigned long)TC_CMR_TCCLKS_PCK6); + *tcclks = TC_CMR_TCCLKS_PCK6; + } + + /* Return success */ + + return OK; + } + } + + /* Return the MCK/slow clock selection */ + + if (actual) + { + tcvdbg("return actual=%lu\n", (unsigned long)mck_actual); + *actual = mck_actual; + } + + /* Return the TCCLKS selection */ + + if (tcclks) + { + tcvdbg("return tcclks=%08lx\n", (unsigned long)mck_tcclks); + *tcclks = mck_tcclks; + } + + /* Return success */ + + return ret; +} + +#endif /* CONFIG_SAMV7_TC0 || CONFIG_SAMV7_TC1 || CONFIG_SAMV7_TC2 || CONFIG_SAMV7_TC3 */ diff --git a/arch/arm/src/samv7/sam_tc.h b/arch/arm/src/samv7/sam_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..5dda45ece993f7e0f17d4b7ea323ee55b701c5b3 --- /dev/null +++ b/arch/arm/src/samv7/sam_tc.h @@ -0,0 +1,367 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_tc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_TC_H +#define __ARCH_ARM_SRC_SAMV7_SAM_TC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "chip/sam_tc.h" + +#if defined(CONFIG_SAMV7_TC0) || defined(CONFIG_SAMV7_TC1) || \ + defined(CONFIG_SAMV7_TC2) || defined(CONFIG_SAMV7_TC3) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The timer/counter and channel arguments to sam_tc_allocate() */ + +#define TC_CHAN0 0 /* TC0 */ +#define TC_CHAN1 1 +#define TC_CHAN2 2 +#define TC_CHAN3 3 /* TC1 */ +#define TC_CHAN4 4 +#define TC_CHAN5 5 +#define TC_CHAN6 6 /* TC2 */ +#define TC_CHAN7 7 +#define TC_CHAN8 8 + +/* Register identifier used with sam_tc_setregister */ + +#define TC_REGA 0 +#define TC_REGB 1 +#define TC_REGC 2 + +/* Timer debug is enabled if any timer client is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_ANALOG +# undef CONFIG_SAMV7_TC_REGDEBUG +#endif + +#if !defined(CONFIG_SAMV7_TC_DEBUG) && defined(CONFIG_SAMV7_ADC) && defined(CONFIG_DEBUG_ANALOG) +# define CONFIG_SAMV7_TC_DEBUG 1 +#endif + +/* Timer/counter debug output */ + +#ifdef CONFIG_SAMV7_TC_DEBUG +# define tcdbg dbg +# define tcvdbg vdbg +# define tclldbg lldbg +# define tcllvdbg llvdbg +#else +# define tcdbg(x...) +# define tcvdbg(x...) +# define tclldbg(x...) +# define tcllvdbg(x...) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* An opaque handle used to represent a timer channel */ + +typedef void *TC_HANDLE; + +/* Timer interrupt callback. When a timer interrupt expires, the client will + * receive: + * + * tch - The handle that represents the timer state + * arg - An opaque argument provided when the interrupt was registered + * sr - The value of the timer interrupt status register at the time + * that the interrupt occurred. + */ + +typedef void (*tc_handler_t)(TC_HANDLE tch, void *arg, uint32_t sr); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_tc_allocate + * + * Description: + * Configures a Timer Counter to operate in the given mode. The timer is + * stopped after configuration and must be restarted with sam_tc_start(). + * All the interrupts of the timer are also disabled. + * + * Input Parameters: + * channel TC channel number (see TC_CHANx definitions) + * mode Operating mode (TC_CMR value). + * + * Returned Value: + * On success, a non-NULL handle value is returned. This handle may be + * used with subsequent timer/counter interfaces to manage the timer. A + * NULL handle value is returned on a failure. + * + ****************************************************************************/ + +TC_HANDLE sam_tc_allocate(int channel, int mode); + +/**************************************************************************** + * Name: sam_tc_free + * + * Description: + * Release the handle previously allocated by sam_tc_allocate(). + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_free(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_start + * + * Description: + * Reset and Start the TC Channel. Enables the timer clock and performs a + * software reset to start the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_start(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_stop + * + * Description: + * Stop TC Channel. Disables the timer clock, stopping the counting. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * + ****************************************************************************/ + +void sam_tc_stop(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_attach/sam_tc_detach + * + * Description: + * Attach or detach an interrupt handler to the timer interrupt. The + * interrupt is detached if the handler argument is NULL. + * + * Input Parameters: + * handle The handle that represents the timer state + * handler The interrupt handler that will be invoked when the interrupt + * condition occurs + * arg An opaque argument that will be provided when the interrupt + * handler callback is executed. Ignored if handler is NULL. + * mask The value of the timer interrupt mask register that defines + * which interrupts should be disabled. Ignored if handler is + * NULL. + * + * Returned Value: + * The address of the previous handler, if any. + * + ****************************************************************************/ + +tc_handler_t sam_tc_attach(TC_HANDLE handle, tc_handler_t handler, + void *arg, uint32_t mask); + +#define sam_tc_detach(h) sam_tc_attach(h, NULL, NULL, 0) + +/**************************************************************************** + * Name: sam_tc_getpending + * + * Description: + * Return the current contents of the interrutp status register, clearing + * all pending interrupts. + * + * Input Parameters: + * handle The handle that represents the timer state + * + * Returned Value: + * The value of the channel interrupt status register. + * + ****************************************************************************/ + +uint32_t sam_tc_getpending(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_setregister + * + * Description: + * Set TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * regval Then value to set in the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_tc_setregister(TC_HANDLE handle, int regid, uint32_t regval); + +/**************************************************************************** + * Name: sam_tc_getregister + * + * Description: + * Get the current value of the TC_REGA, TC_REGB, or TC_REGC register. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * regid One of {TC_REGA, TC_REGB, or TC_REGC} + * + * Returned Value: + * The value of the specified register. + * + ****************************************************************************/ + +uint32_t sam_tc_getregister(TC_HANDLE handle, int regid); + +/**************************************************************************** + * Name: sam_tc_getcounter + * + * Description: + * Return the current value of the timer counter register + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The current value of the timer counter register for this channel. + * + ****************************************************************************/ + +uint32_t sam_tc_getcounter(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_infreq + * + * Description: + * Return the timer input frequency, that is, the MCK frequency divided + * down so that the timer/counter is driven within its maximum frequency. + * + * Input Parameters: + * None + * + * Returned Value: + * The timer input frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_infreq(void); + +/**************************************************************************** + * Name: sam_tc_divfreq + * + * Description: + * Return the divided timer input frequency that is currently driving the + * the timer counter. + * + * Input Parameters: + * handle Channel handle previously allocated by sam_tc_allocate() + * + * Returned Value: + * The timer counter frequency. + * + ****************************************************************************/ + +uint32_t sam_tc_divfreq(TC_HANDLE handle); + +/**************************************************************************** + * Name: sam_tc_clockselect + * + * Description: + * Finds the best MCK divisor given the timer frequency and MCK. The + * result is guaranteed to satisfy the following equation: + * + * (Ftcin / (div * 65536)) <= freq <= (Ftcin / div) + * + * where: + * freq - the desired frequency + * Ftcin - The timer/counter input frequency + * div - With DIV being the highest possible value. + * + * Input Parameters: + * frequency Desired timer frequency. + * tcclks TCCLKS field value for divisor. + * actual The actual freqency of the MCK + * + * Returned Value: + * Zero (OK) if a proper divisor has been found, otherwise a negated errno + * value indicating the nature of the failure. + * + ****************************************************************************/ + +int sam_tc_clockselect(uint32_t frequency, uint32_t *tcclks, + uint32_t *actual); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SAMV7_TC0 || CONFIG_SAMV7_TC1 || CONFIG_SAMV7_TC2 || CONFIG_SAMV7_TC3 */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_TC_H */ diff --git a/arch/arm/src/samv7/sam_tickless.c b/arch/arm/src/samv7/sam_tickless.c new file mode 100644 index 0000000000000000000000000000000000000000..33cbc948c1b73776b1026be0dfb7f09499f3be8a --- /dev/null +++ b/arch/arm/src/samv7/sam_tickless.c @@ -0,0 +1,402 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_tickless.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Tickless OS Support. + * + * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts + * is suppressed and the platform specific code is expected to provide the + * following custom functions. + * + * void up_timer_initialize(void): Initializes the timer facilities. Called + * early in the initialization sequence (by up_intialize()). + * int up_timer_gettime(FAR struct timespec *ts): Returns the current + * time from the platform specific time source. + * int up_timer_cancel(void): Cancels the interval timer. + * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts) + * the interval timer. + * + * The RTOS will provide the following interfaces for use by the platform- + * specific interval timer implementation: + * + * void sched_timer_expiration(void): Called by the platform-specific + * logic when the interval timer expires. + * + ****************************************************************************/ +/**************************************************************************** + * SAMV7 Timer Usage + * + * This current implementation uses two timers: A one-shot timer to provide + * the timed events and a free running timer to provide the current time. + * Since timers are a limited resource, that could be an issue on some + * systems. + * + * We could do the job with a single timer if we were to keep the single + * timer in a free-running at all times. The SAMV7 timer/counters have + * 16-bit counters with the capability to generate a compare interrupt when + * the timer matches a compare value but also to continue counting without + * stopping (giving another, different interrupt when the timer rolls over + * from 0xffff to zero). So we could potentially just set the compare at + * the number of ticks you want PLUS the current value of timer. Then you + * could have both with a single timer: An interval timer and a free- + * running counter with the same timer! + * + * Patches are welcome! + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "sam_oneshot.h" +#include "sam_freerun.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SAMV7_HAVE_TC +# error Timer/counters must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMV7_ONESHOT +# error CONFIG_SAMV7_ONESHOT must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMV7_FREERUN +# error CONFIG_SAMV7_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMV7_TICKLESS_FREERUN +# error CONFIG_SAMV7_TICKLESS_FREERUN must be selected for the Tickless OS option +#endif + +#ifndef CONFIG_SAMV7_TICKLESS_ONESHOT +# error CONFIG_SAMV7_TICKLESS_ONESHOT must be selected for the Tickless OS option +#endif + +#if CONFIG_SAMV7_TICKLESS_ONESHOT == 0 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 0 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 1 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 1 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 2 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 2 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 3 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 3 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 4 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 4 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 5 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 5 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 6 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 6 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 7 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 7 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 8 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 8 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 9 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 9 && CONFIG_SAMV7_TC3 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 10 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 10 && CONFIG_SAMV7_TC3 not selected +#elif CONFIG_SAMV7_TICKLESS_ONESHOT == 11 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_ONESHOT == 11 && CONFIG_SAMV7_TC3 not selected +#endif + +#if CONFIG_SAMV7_TICKLESS_ONESHOT < 0 || CONFIG_SAMV7_TICKLESS_ONESHOT > 11 +# error CONFIG_SAMV7_TICKLESS_ONESHOT is not valid +#endif + +#if CONFIG_SAMV7_TICKLESS_FREERUN == 0 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 0 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 1 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 1 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 2 && !defined(CONFIG_SAMV7_TC0) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 2 && CONFIG_SAMV7_TC0 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 3 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 3 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 4 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 4 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 5 && !defined(CONFIG_SAMV7_TC1) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 5 && CONFIG_SAMV7_TC1 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 6 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 6 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 7 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 7 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 8 && !defined(CONFIG_SAMV7_TC2) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 8 && CONFIG_SAMV7_TC2 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 9 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 9 && CONFIG_SAMV7_TC3 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 10 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 10 && CONFIG_SAMV7_TC3 not selected +#elif CONFIG_SAMV7_TICKLESS_FREERUN == 11 && !defined(CONFIG_SAMV7_TC3) +# error CONFIG_SAMV7_TICKLESS_FREERUN == 11 && CONFIG_SAMV7_TC3 not selected +#endif + +#if CONFIG_SAMV7_TICKLESS_FREERUN < 0 || CONFIG_SAMV7_TICKLESS_FREERUN > 11 +# error CONFIG_SAMV7_TICKLESS_FREERUN is not valid +#endif + +#if CONFIG_SAMV7_TICKLESS_FREERUN == CONFIG_SAMV7_TICKLESS_ONESHOT +# error CONFIG_SAMV7_TICKLESS_FREERUN is the same as CONFIG_SAMV7_TICKLESS_ONESHOT +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sam_tickless_s +{ + struct sam_oneshot_s oneshot; + struct sam_freerun_s freerun; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct sam_tickless_s g_tickless; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_oneshot_handler + * + * Description: + * Called when the one shot timer expires + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +static void sam_oneshot_handler(void *arg) +{ + tcllvdbg("Expired...\n"); + sched_timer_expiration(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Initializes all platform-specific timer facilities. This function is + * called early in the initialization sequence by up_intialize(). + * On return, the current up-time should be available from + * up_timer_gettime() and the interval timer is ready for use (but not + * actively timing. + * + * Provided by platform-specific code and called from the architecture- + * specific logic. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + int ret; + + /* Initialize the one-shot timer */ + + ret = sam_oneshot_initialize(&g_tickless.oneshot, + CONFIG_SAMV7_TICKLESS_ONESHOT, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_oneshot_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(ONESHOT_INITIALIZED(&g_tickless.oneshot)); + + /* Initialize the free-running timer */ + + ret = sam_freerun_initialize(&g_tickless.freerun, + CONFIG_SAMV7_TICKLESS_FREERUN, + CONFIG_USEC_PER_TICK); + if (ret < 0) + { + tclldbg("ERROR: sam_freerun_initialize failed\n"); + PANIC(); + } + + DEBUGASSERT(FREERUN_INITIALIZED(&g_tickless.freerun)); +} + +/**************************************************************************** + * Name: up_timer_gettime + * + * Description: + * Return the elapsed time since power-up (or, more correctly, since + * up_timer_initialize() was called). This function is functionally + * equivalent to: + * + * int clock_gettime(clockid_t clockid, FAR struct timespec *ts); + * + * when clockid is CLOCK_MONOTONIC. + * + * This function provides the basis for reporting the current time and + * also is used to eliminate error build-up from small errors in interval + * time calculations. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the location in which to return the up-time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * Called from the the normal tasking context. The implementation must + * provide whatever mutual exclusion is necessary for correct operation. + * This can include disabling interrupts in order to assure atomic register + * operations. + * + ****************************************************************************/ + +int up_timer_gettime(FAR struct timespec *ts) +{ + return FREERUN_INITIALIZED(&g_tickless.freerun) ? + sam_freerun_counter(&g_tickless.freerun, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_cancel + * + * Description: + * Cancel the interval timer and return the time remaining on the timer. + * These two steps need to be as nearly atomic as possible. + * sched_timer_expiration() will not be called unless the timer is + * restarted with up_timer_start(). + * + * If, as a race condition, the timer has already expired when this + * function is called, then that pending interrupt must be cleared so + * that up_timer_start() and the remaining time of zero should be + * returned. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Location to return the remaining time. Zero should be returned + * if the timer is not active. ts may be zero in which case the + * time remaining is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_cancel(FAR struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_cancel(&g_tickless.oneshot, ts) : + -EAGAIN; +} + +/**************************************************************************** + * Name: up_timer_start + * + * Description: + * Start the interval timer. sched_timer_expiration() will be + * called at the completion of the timeout (unless up_timer_cancel + * is called to stop the timing. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the time interval until sched_timer_expiration() is + * called. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +int up_timer_start(FAR const struct timespec *ts) +{ + return ONESHOT_INITIALIZED(&g_tickless.oneshot) ? + sam_oneshot_start(&g_tickless.oneshot, sam_oneshot_handler, NULL, ts) : + -EAGAIN; +} +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/samv7/sam_timerisr.c b/arch/arm/src/samv7/sam_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..9e167aeae708cbec6b41e45b91458c1bae7d3c10 --- /dev/null +++ b/arch/arm/src/samv7/sam_timerisr.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select MCU-specific settings + * + * The SysTick timer is driven by the output of the Mast Clock Controller + * prescaler output (i.e., the MDIV output divider is not applied so that + * the driving frequency is the same as the CPU frequency). + * + * The SysTick calibration value is fixed to 37500 which allows the generation + * of a time base of 1 ms with SysTick clock to the maximum frequency on + * MCK divided by 8. (?) + */ + +#define SAM_SYSTICK_CLOCK BOARD_CPU_FREQUENCY + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + */ + +#define SYSTICK_RELOAD ((SAM_SYSTICK_CLOCK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + putreg32(0, NVIC_SYSTICK_CURRENT); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(SAM_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts (no divide-by-8) */ + + regval = (NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE); + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(SAM_IRQ_SYSTICK); +} diff --git a/arch/arm/src/samv7/sam_trng.c b/arch/arm/src/samv7/sam_trng.c new file mode 100644 index 0000000000000000000000000000000000000000..3a76b924e1fac122c4a213f013aabdaaabe02729 --- /dev/null +++ b/arch/arm/src/samv7/sam_trng.c @@ -0,0 +1,390 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_trng.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from the SAMA5D3 TRNG Nuttx driver which, in turn, derives, in + * part, from Max Holtzberg's STM32 RNG Nuttx driver: + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "sam_periphclks.h" +#include "sam_trng.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Interrupts */ + +static int sam_interrupt(int irq, void *context); + +/* Character driver methods */ + +static ssize_t sam_read(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct trng_dev_s +{ + sem_t exclsem; /* Enforces exclusive access to the TRNG */ + sem_t waitsem; /* Wait for buffer full */ + uint32_t *samples; /* Current buffer being filled */ + size_t maxsamples; /* Size of the current buffer (in 32-bit words) */ + volatile size_t nsamples; /* Number of samples currently buffered */ + volatile bool first; /* The first random number must be handled differently */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct trng_dev_s g_trngdev; + +static const struct file_operations g_trngops = +{ + 0, /* open */ + 0, /* close */ + sam_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * The TRNG interrupt handler + * + * Input Parameters: + * + * Returned Value: + * + * + ****************************************************************************/ + +static int sam_interrupt(int irq, void *context) +{ + uint32_t odata; + + /* Loop where there are samples available to be read and/or until the user + * buffer is filled. Each sample requires only 84 clocks it is likely + * that we will loop here. + */ + + for (; ; ) + { + /* Read the random sample (before checking DATRDY -- but probably not + * necessary) + */ + + odata = getreg32(SAM_TRNG_ODATA); + + /* Verify that sample data is available (DATARDY is cleared when the + * interrupt status regiser is read) + */ + + if ((getreg32(SAM_TRNG_ISR) & TRNG_INT_DATRDY) == 0) + { + /* No? Then return and continue processing on the next interrupt. */ + + return OK; + } + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting + * the RNGEN bit should not be used, but saved for comparison with the + * next generated random number. Each subsequent generated random number + * has to be compared with the previously generated number. The test + * fails if any two compared numbers are equal (continuous random number + * generator test). + */ + + if (g_trngdev.nsamples == 0) + { + /* This is the first sample we have taken. Save it for subsequent + * comparison. + */ + + g_trngdev.samples[0] = odata; + g_trngdev.nsamples = 1; + continue; + } + + /* This is not the first sample. Check if the new sample differs from + * the preceding sample. + */ + + else if (odata == g_trngdev.samples[g_trngdev.nsamples - 1]) + { + /* Two samples with the same value. Discard this one and try again. */ + + continue; + } + + /* This sample differs from the previous value. Have we discarded the + * first sample yet? + */ + + if (g_trngdev.first) + { + /* No, discard it now by replacing it with the new sample */ + + g_trngdev.samples[0] = odata; + g_trngdev.nsamples = 1; + g_trngdev.first = false; + } + + /* Yes.. the first sample has been dicarded */ + + else + { + /* Add the new random number to the buffer */ + + g_trngdev.samples[g_trngdev.nsamples] = odata; + g_trngdev.nsamples++; + } + + /* Have all of the requested samples been saved? */ + + if (g_trngdev.nsamples == g_trngdev.maxsamples) + { + /* Yes.. disable any further interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* And wakeup the waiting read thread. */ + + sem_post(&g_trngdev.waitsem); + return OK; + } + } +} + +/**************************************************************************** + * Name: sam_read + * + * Description: + * This is the standard, NuttX character driver read method + * + * Input Parameters: + * filep - The VFS file instance + * buffer - Buffer in which to return the random samples + * buflen - The length of the buffer + * + * Returned Value: + * + ****************************************************************************/ + +static ssize_t sam_read(struct file *filep, char *buffer, size_t buflen) +{ + ssize_t retval; + int ret; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Get exclusive access to the TRNG harware */ + + if (sem_wait(&g_trngdev.exclsem) != OK) + { + /* This is probably -EINTR meaning that we were awakened by a signal */ + + return -errno; + } + + /* Save the buffer information. */ + + DEBUGASSERT(((uintptr_t)buffer & 3) == 0); + + g_trngdev.samples = (uint32_t *)buffer; + g_trngdev.maxsamples = buflen >> 2; + g_trngdev.nsamples = 0; + g_trngdev.first = true; + + /* Enable the TRNG */ + + putreg32(TRNG_CR_ENABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Clear any pending TRNG interrupts by reading the interrupt status + * register + */ + + (void)getreg32(SAM_TRNG_ISR); + + /* Enable TRNG interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IER); + + /* Wait until the buffer is filled */ + + while (g_trngdev.nsamples < g_trngdev.maxsamples) + { + ret = sem_wait(&g_trngdev.waitsem); + + fvdbg("Awakened: nsamples=%d maxsamples=%d ret=%d\n", + g_trngdev.nsamples, g_trngdev.maxsamples, ret); + + if (ret < 0) + { + /* We must have been awakened by a signal */ + + if (g_trngdev.nsamples > 0) + { + break; + } + else + { + retval = -errno; + goto errout; + } + } + } + + /* Success... calculate the number of bytes to return */ + + retval = g_trngdev.nsamples << 2; + +errout: + + /* Disable TRNG interrupts */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Release our lock on the TRNG hardware */ + + sem_post(&g_trngdev.exclsem); + + fvdbg("Return %d\n", (int)retval); + return retval; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_rnginitialize + * + * Description: + * Initialize the TRNG hardware and register the /dev/randome driver. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_rnginitialize(void) +{ + int ret; + + fvdbg("Initializing TRNG hardware\n"); + + /* Initialize the device structure */ + + memset(&g_trngdev, 0, sizeof(struct trng_dev_s)); + sem_init(&g_trngdev.exclsem, 0, 1); + sem_init(&g_trngdev.waitsem, 0, 0); + + /* Enable clocking to the TRNG */ + + sam_trng_enableclk(); + + /* Initialize the TRNG interrupt */ + + if (irq_attach(SAM_IRQ_TRNG, sam_interrupt)) + { + fdbg("ERROR: Failed to attach to IRQ%d\n", SAM_IRQ_TRNG); + return; + } + + /* Disable the interrupts at the TRNG */ + + putreg32(TRNG_INT_DATRDY, SAM_TRNG_IDR); + + /* Disable the TRNG */ + + putreg32(TRNG_CR_DISABLE | TRNG_CR_KEY, SAM_TRNG_CR); + + /* Register the character driver */ + + ret = register_driver("/dev/random", &g_trngops, 0644, NULL); + if (ret < 0) + { + fdbg("ERROR: Failed to register /dev/random\n"); + return; + } + + /* Enable the TRNG interrupt at the AIC */ + + up_enable_irq(SAM_IRQ_TRNG); +} diff --git a/arch/arm/src/samv7/sam_trng.h b/arch/arm/src/samv7/sam_trng.h new file mode 100644 index 0000000000000000000000000000000000000000..cd3c9f24b922b66a9af51500481dba677f3e9409 --- /dev/null +++ b/arch/arm/src/samv7/sam_trng.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_trng.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_TRNG_H +#define __ARCH_ARM_SRC_SAMV7_SAM_TRNG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_trng.h" + +#if defined(CONFIG_DEV_RANDOM) && defined(CONFIG_SAMV7_TRNG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_DEV_RANDOM && CONFIG_SAMV7_TRNG */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_TRNG_H */ diff --git a/arch/arm/src/samv7/sam_twihs.c b/arch/arm/src/samv7/sam_twihs.c new file mode 100644 index 0000000000000000000000000000000000000000..f11ae78cbb3074b84accec359c60912bbc480157 --- /dev/null +++ b/arch/arm/src/samv7/sam_twihs.c @@ -0,0 +1,1402 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_twihs.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This driver derives from the SAMA5Dx TWIHS driver. References: + * SAMA5D3 Series Data Sheet + * Atmel NoOS sample code. + * + * The Atmel sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2011, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/sam_pmc.h" +#include "chip/sam_pinmap.h" + +#include "sam_periphclks.h" +#include "sam_gpio.h" +#include "sam_twihs.h" + +#if defined(CONFIG_SAMV7_TWIHS0) || defined(CONFIG_SAMV7_TWIHS1) || \ + defined(CONFIG_SAMV7_TWIHS2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_SAMV7_TWIHS0_FREQUENCY +# define CONFIG_SAMV7_TWIHS0_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAMV7_TWIHS1_FREQUENCY +# define CONFIG_SAMV7_TWIHS1_FREQUENCY 100000 +#endif + +#ifndef CONFIG_SAMV7_TWIHS2_FREQUENCY +# define CONFIG_SAMV7_TWIHS2_FREQUENCY 100000 +#endif + +/* Driver internal definitions *************************************************/ +/* If verbose I2C debug output is enable, then allow more time before we declare + * a timeout. The debug output from twi_interrupt will really slow things down! + * + * With a very slow clock (say 100,000 Hz), less than 100 usec would be required + * to transfer on byte. So these define a "long" timeout. + */ + +#if defined(CONFIG_DEBUG_I2C) && defined(CONFIG_DEBUG_VERBOSE) +# define TWIHS_TIMEOUT_MSPB (50) /* 50 msec/byte */ +#else +# define TWIHS_TIMEOUT_MSPB (5) /* 5 msec/byte */ +#endif + +/* Clocking to the TWIHS module(s) is provided by the main clock, divided down + * as necessary. + * REVISIT -- This number came from the SAMA5Dx driver. + */ + +#define TWIHS_MAX_FREQUENCY 66000000 /* Maximum TWIHS frequency */ + +/* Macros to convert a I2C pin to a PIO open-drain output */ + +#define I2C_INPUT (PIO_INPUT | PIO_CFG_PULLUP) +#define I2C_OUTPUT (PIO_OUTPUT | PIO_CFG_OPENDRAIN | PIO_OUTPUT_SET) + +#define MKI2C_INPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_INPUT) +#define MKI2C_OUTPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ***********************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +# define i2clldbg lldbg +# define i2cllvdbg llvdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +# define i2clldbg(x...) +# define i2cllvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Invariant attributes of a TWIHS bus */ + +struct twi_attr_s +{ + uint8_t twi; /* TWIHS device number (for debug output) */ + uint8_t pid; /* TWIHS peripheral ID */ + uint16_t irq; /* IRQ number for this TWIHS bus */ + gpio_pinset_t sclcfg; /* TWIHS CK pin configuration (SCL in I2C-ese) */ + gpio_pinset_t sdacfg; /* TWIHS D pin configuration (SDA in I2C-ese) */ + uintptr_t base; /* Base address of TWIHS registers */ + xcpt_t handler; /* TWIHS interrupt handler */ +}; + +/* State of a TWIHS bus */ + +struct twi_dev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + const struct twi_attr_s *attr; /* Invariant attributes of TWIHS device */ + struct i2c_msg_s *msg; /* Message list */ + uint32_t twiclk; /* TWIHS input clock frequency */ + uint32_t frequency; /* TWIHS transfer clock frequency */ + bool initd; /* True :device has been initialized */ + uint8_t msgc; /* Number of message in the message list */ + + sem_t exclsem; /* Only one thread can access at a time */ + sem_t waitsem; /* Wait for TWIHS transfer completion */ + WDOG_ID timeout; /* Watchdog to recover from bus hangs */ + volatile int result; /* The result of the transfer */ + volatile int xfrd; /* Number of bytes transfers */ + + /* Debug stuff */ + +#ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helper functions */ + +static void twi_takesem(sem_t *sem); +#define twi_givesem(sem) (sem_post(sem)) + +#ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, + uint32_t value, uintptr_t address); +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address); +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value); +#else +# define twi_checkreg(priv,wr,value,address) (false) +# define twi_putabs(p,a,v) putreg32(v,a) +# define twi_getabs(p,a) getreg32(a) +#endif + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, + unsigned int offset); +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value); + +/* I2C transfer helper functions */ + +static int twi_wait(struct twi_dev_s *priv, unsigned int size); +static void twi_wakeup(struct twi_dev_s *priv, int result); +static int twi_interrupt(struct twi_dev_s *priv); +#ifdef CONFIG_SAMV7_TWIHS0 +static int twi0_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAMV7_TWIHS1 +static int twi1_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_SAMV7_TWIHS2 +static int twi2_interrupt(int irq, FAR void *context); +#endif +static void twi_timeout(int argc, uint32_t arg, ...); + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg); +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg); + +/* I2C device operations */ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s * dev); +#endif + +/* Initialization */ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency); +static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TWIHS0 +static const struct twi_attr_s g_twi0attr = +{ + .twi = 0, + .pid = SAM_PID_TWIHS0, + .irq = SAM_IRQ_TWIHS0, + .sclcfg = GPIO_TWIHS0_CK, + .sdacfg = GPIO_TWIHS0_D, + .base = SAM_TWIHS0_BASE, + .handler = twi0_interrupt, +}; + +static struct twi_dev_s g_twi0; +#endif + +#ifdef CONFIG_SAMV7_TWIHS1 +static const struct twi_attr_s g_twi1attr = +{ + .twi = 1, + .pid = SAM_PID_TWIHS1, + .irq = SAM_IRQ_TWIHS1, + .sclcfg = GPIO_TWIHS1_CK, + .sdacfg = GPIO_TWIHS1_D, + .base = SAM_TWIHS1_BASE, + .handler = twi1_interrupt, +}; + +static struct twi_dev_s g_twi1; +#endif + +#ifdef CONFIG_SAMV7_TWIHS2 +static const struct twi_attr_s g_twi2attr = +{ + .twi = 2, + .pid = SAM_PID_TWIHS2, + .irq = SAM_IRQ_TWIHS2, + .sclcfg = GPIO_TWIHS2_CK, + .sdacfg = GPIO_TWIHS2_D, + .base = SAM_TWIHS2_BASE, + .handler = twi2_interrupt, +}; + +static struct twi_dev_s g_twi2; +#endif + +static const struct i2c_ops_s g_twiops = +{ + .transfer = twi_transfer +#ifdef CONFIG_I2C_RESET + , .reset = twi_reset +#endif +}; + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: twi_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wake-ups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void twi_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: twi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * value - The value to be written + * address - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * false: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG +static bool twi_checkreg(struct twi_dev_s *priv, bool wr, uint32_t value, + uint32_t address) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + value == priv->vallast && /* Same value? */ + address == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = value; + priv->addrlast = address; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: twi_getabs + * + * Description: + * Read any 32-bit register using an absolute + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG +static uint32_t twi_getabs(struct twi_dev_s *priv, uintptr_t address) +{ + uint32_t value = getreg32(address); + + if (twi_checkreg(priv, false, value, address)) + { + lldbg("%08x->%08x\n", address, value); + } + + return value; +} +#endif + +/**************************************************************************** + * Name: twi_putabs + * + * Description: + * Write to any 32-bit register using an absolute address + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_TWIHSHS_REGDEBUG +static void twi_putabs(struct twi_dev_s *priv, uintptr_t address, + uint32_t value) +{ + if (twi_checkreg(priv, true, value, address)) + { + lldbg("%08x<-%08x\n", address, value); + } + + putreg32(value, address); +} +#endif + +/**************************************************************************** + * Name: twi_getrel + * + * Description: + * Read a TWIHS register using an offset relative to the TWIHS base address + * + ****************************************************************************/ + +static inline uint32_t twi_getrel(struct twi_dev_s *priv, unsigned int offset) +{ + return twi_getabs(priv, priv->attr->base + offset); +} + +/**************************************************************************** + * Name: twi_putrel + * + * Description: + * Write a value to a TWIHS register using an offset relative to the TWIHS base + * address. + * + ****************************************************************************/ + +static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset, + uint32_t value) +{ + twi_putabs(priv, priv->attr->base + offset, value); +} + +/**************************************************************************** + * I2C transfer helper functions + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_wait + * + * Description: + * Perform a I2C transfer start + * + * Assumptions: + * Interrupts are disabled + * + ****************************************************************************/ + +static int twi_wait(struct twi_dev_s *priv, unsigned int size) +{ + uint32_t timeout; + + /* Calculate a timeout value based on the size of the transfer + * + * ticks = msec-per-byte * bytes / msec-per-tick + * + * There is no concern about arithmetic overflow for reasonable transfer sizes. + */ + + timeout = MSEC2TICK(TWIHS_TIMEOUT_MSPB); + if (timeout < 1) + { + timeout = 1; + } + + /* Then start the timeout. This timeout is needed to avoid hangs if/when an + * TWIHS transfer stalls. + */ + + wd_start(priv->timeout, (timeout * size), twi_timeout, 1, (uint32_t)priv); + + /* Wait for either the TWIHS transfer or the timeout to complete */ + + do + { + i2cvdbg("TWIHS%d Waiting...\n", priv->attr->twi); + twi_takesem(&priv->waitsem); + i2cvdbg("TWIHS%d Awakened with result: %d\n", + priv->attr->twi, priv->result); + } + while (priv->result == -EBUSY); + + /* We get here via twi_wakeup. The watchdog timer has been disabled and + * all further interrupts for the TWIHS have been disabled. + */ + + return priv->result; +} + +/**************************************************************************** + * Name: twi_wakeup + * + * Description: + * A terminal event has occurred. Wake-up the waiting thread + * + ****************************************************************************/ + +static void twi_wakeup(struct twi_dev_s *priv, int result) +{ + /* Cancel any pending timeout */ + + wd_cancel(priv->timeout); + + /* Disable any further TWIHS interrupts */ + + twi_putrel(priv, SAM_TWIHS_IDR_OFFSET, TWIHS_INT_ALL); + + /* Wake up the waiting thread with the result of the transfer */ + + priv->result = result; + twi_givesem(&priv->waitsem); +} + +/**************************************************************************** + * Name: twi_interrupt + * + * Description: + * The TWIHS Interrupt Handler + * + ****************************************************************************/ + +static int twi_interrupt(struct twi_dev_s *priv) +{ + struct i2c_msg_s *msg; + uint32_t sr; + uint32_t imr; + uint32_t pending; + uint32_t regval; + + /* Retrieve masked interrupt status */ + + sr = twi_getrel(priv, SAM_TWIHS_SR_OFFSET); + imr = twi_getrel(priv, SAM_TWIHS_IMR_OFFSET); + pending = sr & imr; + + i2cllvdbg("TWIHS%d pending: %08x\n", priv->attr->twi, pending); + + /* Byte received */ + + msg = priv->msg; + if ((pending & TWIHS_INT_RXRDY) != 0) + { + msg->buffer[priv->xfrd] = twi_getrel(priv, SAM_TWIHS_RHR_OFFSET); + priv->xfrd++; + + /* Check for transfer complete */ + + if (priv->xfrd >= msg->length) + { + struct i2c_msg_s *next = (msg + 1); + + /* Is there another message to after this one? Does it require a + * restart? + */ + + if (priv->msgc <= 1 || (next->flags & I2C_M_NORESTART) == 0) + { + /* The transfer is complete. Disable the RXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWIHS_IDR_OFFSET, TWIHS_INT_RXRDY); + twi_putrel(priv, SAM_TWIHS_IER_OFFSET, TWIHS_INT_TXCOMP); + } + else + { + /* No.. just switch to the next message and continue receiving. + * On the next RXRDY, we will continue with the first byt of the + * next message. + */ + + DEBUGASSERT((next->flags & I2C_M_READ) != 0); + priv->msg = next; + priv->msgc--; + priv->xfrd = 0; + } + } + + /* Not yet complete, but will the next be the last byte? */ + + else if (priv->xfrd == (msg->length - 1)) + { + struct i2c_msg_s *next = (msg + 1); + + /* Is there another message to after this one? Does it require a + * restart? + */ + + if (priv->msgc <= 1 || (next->flags & I2C_M_NORESTART) == 0) + { + /* This is the last message OR a restart is required before + * the next mesage. Send the stop signal. + */ + + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_STOP); + } + } + } + + /* Check for errors. We must check for errors *before* checking TXRDY or + * TXCMP because the error can be signaled in combination with TXRDY or + * TXCOMP. + */ + + else if ((pending & TWIHS_INT_ERRORS) != 0) + { + /* Wake up the thread with an I/O error indication */ + + i2clldbg("ERROR: TWIHS%d pending: %08x\n", priv->attr->twi, pending); + twi_wakeup(priv, -EIO); + } + + /* Byte sent */ + + else if ((pending & TWIHS_INT_TXRDY) != 0) + { + /* Transfer finished? */ + + if (priv->xfrd >= msg->length) + { + struct i2c_msg_s *next = (msg + 1); + + /* Is there another message to after this one? Does it require a + * restart? + */ + + if (priv->msgc <= 1 || (next->flags & I2C_M_NORESTART) == 0) + { + /* The transfer is complete. Disable the TXRDY interrupt and + * enable the TXCOMP interrupt + */ + + twi_putrel(priv, SAM_TWIHS_IDR_OFFSET, TWIHS_INT_TXRDY); + twi_putrel(priv, SAM_TWIHS_IER_OFFSET, TWIHS_INT_TXCOMP); + + /* Send the STOP condition */ + + regval = twi_getrel(priv, SAM_TWIHS_CR_OFFSET); + regval |= TWIHS_CR_STOP; + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, regval); + } + else + { + /* No.. just switch to the next message and continue sending. */ + + DEBUGASSERT((next->flags & I2C_M_READ) == 0); + priv->msg = next; + priv->msgc--; + + twi_putrel(priv, SAM_TWIHS_THR_OFFSET, next->buffer[0]); + priv->xfrd = 1; + } + } + + /* No, there are more bytes remaining to be sent */ + + else + { + twi_putrel(priv, SAM_TWIHS_THR_OFFSET, msg->buffer[priv->xfrd]); + priv->xfrd++; + } + } + + /* Transfer complete, Occurs on message only if the STOP bit was set on + * the previously sent byte. + */ + + else if ((pending & TWIHS_INT_TXCOMP) != 0) + { + twi_putrel(priv, SAM_TWIHS_IDR_OFFSET, TWIHS_INT_TXCOMP); + + /* Is there another message to send? */ + + if (priv->msgc > 1) + { + /* Yes... start the next message */ + + priv->msg++; + priv->msgc--; + twi_startmessage(priv, priv->msg); + } + else + { + /* No.. we made it to the end of the message list with no errors. + * Cancel any timeout and wake up the waiting thread with a + * success indication. + */ + + twi_wakeup(priv, OK); + } + } + + return OK; +} + +#ifdef CONFIG_SAMV7_TWIHS0 +static int twi0_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi0); +} +#endif + +#ifdef CONFIG_SAMV7_TWIHS1 +static int twi1_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi1); +} +#endif + +#ifdef CONFIG_SAMV7_TWIHS2 +static int twi2_interrupt(int irq, FAR void *context) +{ + return twi_interrupt(&g_twi2); +} +#endif + +/**************************************************************************** + * Name: twi_timeout + * + * Description: + * Watchdog timer for timeout of TWIHS operation + * + * Assumptions: + * Called from the timer interrupt handler with interrupts disabled. + * + ****************************************************************************/ + +static void twi_timeout(int argc, uint32_t arg, ...) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)arg; + + i2clldbg("ERROR: TWIHS%d Timeout!\n", priv->attr->twi); + twi_wakeup(priv, -ETIMEDOUT); +} + +/**************************************************************************** + * Name: twi_startread + * + * Description: + * Start the next read message + * + ****************************************************************************/ + +static void twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set STOP signal if only one byte is sent */ + + if (msg->length == 1) + { + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_STOP); + } + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWIHS_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWIHS_MMR_OFFSET, TWIHS_MMR_IADRSZ_NONE | TWIHS_MMR_MREAD | + TWIHS_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWIHS_IADR_OFFSET, 0); + + /* Enable read interrupt and send the START condition */ + + twi_putrel(priv, SAM_TWIHS_IER_OFFSET, TWIHS_INT_RXRDY | TWIHS_INT_ERRORS); + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_START); +} + +/**************************************************************************** + * Name: twi_startwrite + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + /* Setup for the transfer */ + + priv->result = -EBUSY; + priv->xfrd = 0; + + /* Set slave address and number of internal address bytes. */ + + twi_putrel(priv, SAM_TWIHS_MMR_OFFSET, 0); + twi_putrel(priv, SAM_TWIHS_MMR_OFFSET, TWIHS_MMR_IADRSZ_NONE | TWIHS_MMR_DADR(msg->addr)); + + /* Set internal address bytes (not used) */ + + twi_putrel(priv, SAM_TWIHS_IADR_OFFSET, 0); + + /* Write first byte to send. */ + + twi_putrel(priv, SAM_TWIHS_THR_OFFSET, msg->buffer[priv->xfrd++]); + + /* Enable write interrupt */ + + twi_putrel(priv, SAM_TWIHS_IER_OFFSET, TWIHS_INT_TXRDY | TWIHS_INT_ERRORS); +} + +/**************************************************************************** + * Name: twi_startmessage + * + * Description: + * Start the next write message + * + ****************************************************************************/ + +static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg) +{ + if ((msg->flags & I2C_M_READ) != 0) + { + twi_startread(priv, msg); + } + else + { + twi_startwrite(priv, msg); + } +} + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_transfer + * + * Description: + * Receive a block of data on I2C using the previously selected I2C + * frequency and slave address. + * + * Returned Value: + * Returns zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int twi_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)dev; + irqstate_t flags; + unsigned int size; + int i; + int ret; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + i2cvdbg("TWIHS%d count: %d\n", priv->attr->twi, count); + + /* Calculate the total transfer size so that we can calculate a reasonable + * timeout value. + */ + + size = 0; + for (i = 0; i < count; i++) + { + size += msgs[i].length; + } + + DEBUGASSERT(size > 0); + + /* Get exclusive access to the device */ + + twi_takesem(&priv->exclsem); + + /* Setup the message transfer */ + + priv->msg = msgs; + priv->msgc = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + twi_setfrequency(priv, msgs->frequency); + + /* Initiate the transfer. The rest will be handled from interrupt + * logic. Interrupts must be disabled to prevent re-entrance from the + * interrupt level. + */ + + flags = enter_critical_section(); + twi_startmessage(priv, msgs); + + /* And wait for the transfers to complete. Interrupts will be re-enabled + * while we are waiting. + */ + + ret = twi_wait(priv, size); + if (ret < 0) + { + i2cdbg("ERROR: Transfer failed: %d\n", ret); + } + + leave_critical_section(flags); + twi_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: twi_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int twi_reset(FAR struct i2c_master_s *dev) +{ + struct twi_dev_s *priv = (struct twi_dev_s *)dev; + unsigned int clockcnt; + unsigned int stretchcnt; + uint32_t sclpin; + uint32_t sdapin; + int ret; + + ASSERT(priv); + + /* Get exclusive access to the TWIHS device */ + + twi_takesem(&priv->exclsem); + + /* Disable TWIHS interrupts */ + + up_disable_irq(priv->attr->irq); + + /* Use PIO configuration to un-wedge the bus. + * + * Reconfigure both pins as open drain outputs with initial output value + * "high" (i.e., floating since these are open-drain outputs). + */ + + sclpin = MKI2C_OUTPUT(priv->attr->sclcfg); + sdapin = MKI2C_OUTPUT(priv->attr->sdacfg); + + sam_configgpio(sclpin); + sam_configgpio(sdapin); + + /* Peripheral clocking must be enabled in order to read valid data from + * the output pin (clocking is enabled automatically for pins configured + * as inputs). + */ + + sam_pio_forceclk(sclpin, true); + sam_pio_forceclk(sdapin, true); + + /* Clock the bus until any slaves currently driving it low let it float. + * Reading from the output will return the actual sensed level on the + * SDA pin (not the level that we wrote). + */ + + clockcnt = 0; + while (sam_pioread(sdapin) == false) + { + /* Give up if we have tried too hard */ + + if (clockcnt++ > 10) + { + ret = -ETIMEDOUT; + goto errout_with_lock; + } + + /* Sniff to make sure that clock stretching has finished. SCL should + * be floating high here unless something is driving it low. + * + * If the bus never relaxes, the reset has failed. + */ + + stretchcnt = 0; + while (sam_pioread(sclpin) == false) + { + /* Give up if we have tried too hard */ + + if (stretchcnt++ > 10) + { + ret = -EAGAIN; + goto errout_with_lock; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + sam_piowrite(sclpin, false); + up_udelay(10); + + /* Drive SCL high (floating) again */ + + sam_piowrite(sclpin, true); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + sam_piowrite(sdapin, false); + up_udelay(10); + sam_piowrite(sclpin, false); + up_udelay(10); + + sam_piowrite(sclpin, true); + up_udelay(10); + sam_piowrite(sdapin, true); + up_udelay(10); + + /* Clocking is no longer forced */ + + sam_pio_forceclk(sclpin, false); + sam_pio_forceclk(sdapin, false); + + /* Re-initialize the port hardware */ + + twi_hw_initialize(priv, priv->frequency); + ret = OK; + +errout_with_lock: + + /* Release our lock on the bus */ + + twi_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Initialization + ****************************************************************************/ + +/**************************************************************************** + * Name: twi_enableclk + * + * Description: + * Enable clocking on the selected TWIHS + * + ****************************************************************************/ + +static void twi_enableclk(struct twi_dev_s *priv) +{ + int pid; + + /* Get the peripheral ID associated with the TWIHS device port and enable + * clocking to the TWIHS block. + */ + + pid = priv->attr->pid; + if (pid < 32) + { + sam_enableperiph0(pid); + } + else + { + sam_enableperiph1(pid); + } +} + +/**************************************************************************** + * Name: twi_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void twi_setfrequency(struct twi_dev_s *priv, uint32_t frequency) +{ + unsigned int ckdiv; + unsigned int cldiv; + uint32_t regval; + + if (frequency != priv->frequency) + { + /* Configure TWIHS output clocking, trying each value of CKDIV {0..7} */ + + for (ckdiv = 0; ckdiv < 8; ckdiv++) + { + /* Calculate the CLDIV value using the current CKDIV guess */ + + cldiv = ((priv->twiclk / (frequency << 1)) - 4) / (1 << ckdiv); + + /* Is CLDIV in range? */ + + if (cldiv <= 255) + { + /* Yes, break out and use it */ + + break; + } + } + + /* Then setup the TWIHS Clock Waveform Generator Register, using the same + * value for CLDIV and CHDIV (for 1:1 duty). + */ + + twi_putrel(priv, SAM_TWIHS_CWGR_OFFSET, 0); + + regval = ((uint32_t)ckdiv << TWIHS_CWGR_CKDIV_SHIFT) | + ((uint32_t)cldiv << TWIHS_CWGR_CHDIV_SHIFT) | + ((uint32_t)cldiv << TWIHS_CWGR_CLDIV_SHIFT); + twi_putrel(priv, SAM_TWIHS_CWGR_OFFSET, regval); + + /* Save the requested frequency */ + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: twi_hw_initialize + * + * Description: + * Initialize/Re-initialize the TWIHS peripheral. This logic performs only + * repeatable initialization after either (1) the one-time initialization, or + * (2) after each bus reset. + * + ****************************************************************************/ + +static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency) +{ + irqstate_t flags = enter_critical_section(); + uint32_t regval; + uint32_t mck; + + i2cvdbg("TWIHS%d Initializing\n", priv->attr->twi); + + /* Configure PIO pins */ + + sam_configgpio(priv->attr->sclcfg); + sam_configgpio(priv->attr->sdacfg); + + /* Enable peripheral clocking */ + + twi_enableclk(priv); + + /* SVEN: TWIHS Slave Mode Enabled */ + + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_SVEN); + + /* Reset the TWIHS */ + + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_SWRST); + (void)twi_getrel(priv, SAM_TWIHS_RHR_OFFSET); + + /* TWIHS Slave Mode Disabled, TWIHS Master Mode Disabled. */ + + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_SVDIS); + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_MSDIS); + + /* Set master mode */ + + twi_putrel(priv, SAM_TWIHS_CR_OFFSET, TWIHS_CR_MSEN); + + /* Determine the maximum valid frequency setting */ + + mck = BOARD_MCK_FREQUENCY; + +#ifdef SAMV7_HAVE_PMC_PCR_DIV + /* Select the optimal value for the PCR DIV field */ + + DEBUGASSERT((mck >> 3) <= TWIHS_MAX_FREQUENCY); + if (mck <= TWIHS_MAX_FREQUENCY) + { + priv->twiclk = mck; + regval = PMC_PCR_DIV1; + } + else if ((mck >> 1) <= TWIHS_MAX_FREQUENCY) + { + priv->twiclk = (mck >> 1); + regval = PMC_PCR_DIV2; + } + else if ((mck >> 2) <= TWIHS_MAX_FREQUENCY) + { + priv->twiclk = (mck >> 2); + regval = PMC_PCR_DIV4; + } + else /* if ((mck >> 3) <= TWIHS_MAX_FREQUENCY) */ + { + priv->twiclk = (mck >> 3); + regval = PMC_PCR_DIV8; + } + +#else + /* No DIV field in the PCR register */ + + priv->twiclk = mck; + regval = 0; + +#endif /* SAMV7_HAVE_PMC_PCR_DIV */ + + /* Set the TWIHS peripheral input clock to the maximum, valid frequency */ + + regval |= PMC_PCR_PID(priv->attr->pid) | PMC_PCR_CMD | PMC_PCR_EN; + twi_putabs(priv, SAM_PMC_PCR, regval); + + /* Set the initial TWIHS data transfer frequency */ + + twi_setfrequency(priv, frequency); + + /* Enable Interrupts */ + + up_enable_irq(priv->attr->irq); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize a TWIHS device for I2C operation + * + ****************************************************************************/ + +struct i2c_master_s *sam_i2cbus_initialize(int bus) +{ + struct twi_dev_s *priv; + uint32_t frequency; + irqstate_t flags; + int ret; + + i2cvdbg("Initializing TWIHS%d\n", bus); + +#ifdef CONFIG_SAMV7_TWIHS0 + if (bus == 0) + { + /* Select up TWIHS0 and setup invariant attributes */ + + priv = &g_twi0; + priv->attr = &g_twi0attr; + + /* Select the (initial) TWIHS frequency */ + + frequency = CONFIG_SAMV7_TWIHS0_FREQUENCY; + } + else +#endif +#ifdef CONFIG_SAMV7_TWIHS1 + if (bus == 1) + { + /* Select up TWIHS1 and setup invariant attributes */ + + priv = &g_twi1; + priv->attr = &g_twi1attr; + + /* Select the (initial) TWIHS frequency */ + + frequency = CONFIG_SAMV7_TWIHS1_FREQUENCY; + } + else +#endif +#ifdef CONFIG_SAMV7_TWIHS2 + if (bus == 2) + { + /* Select up TWIHS2 and setup invariant attributes */ + + priv = &g_twi2; + priv->attr = &g_twi2attr; + + /* Select the (initial) TWIHS frequency */ + + frequency = CONFIG_SAMV7_TWIHS2_FREQUENCY; + } + else +#endif + { + i2cdbg("ERROR: Unsupported bus: TWIHS%d\n", bus); + return NULL; + } + + /* Perform one-time TWIHS initialization */ + + flags = enter_critical_section(); + + /* Has the device already been initialized? */ + + if (!priv->initd) + { + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + if (priv->timeout == NULL) + { + idbg("ERROR: Failed to allocate a timer\n"); + goto errout_with_irq; + } + + /* Attach Interrupt Handler */ + + ret = irq_attach(priv->attr->irq, priv->attr->handler); + if (ret < 0) + { + idbg("ERROR: Failed to attach irq %d\n", priv->attr->irq); + goto errout_with_wdog; + } + + /* Initialize the TWIHS driver structure */ + + priv->dev.ops = &g_twiops; + + (void)sem_init(&priv->exclsem, 0, 1); + (void)sem_init(&priv->waitsem, 0, 0); + + /* Perform repeatable TWIHS hardware initialization */ + + twi_hw_initialize(priv, frequency); + + /* Now it has been initialized */ + + priv->initd = true; + } + + leave_critical_section(flags); + return &priv->dev; + +errout_with_wdog: + wd_delete(priv->timeout); + priv->timeout = NULL; + +errout_with_irq: + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C device + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + struct twi_dev_s *priv = (struct twi_dev_s *) dev; + irqstate_t flags; + + i2cvdbg("TWIHS%d Un-initializing\n", priv->attr->twi); + + /* Disable TWIHS interrupts */ + + flags = enter_critical_section(); + up_disable_irq(priv->attr->irq); + + /* Reset data structures */ + + sem_destroy(&priv->exclsem); + sem_destroy(&priv->waitsem); + + /* Free the watchdog timer */ + + wd_delete(priv->timeout); + priv->timeout = NULL; + + /* Detach Interrupt Handler */ + + (void)irq_detach(priv->attr->irq); + + priv->initd = false; + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_SAMV7_TWIHS0 || CONFIG_SAMV7_TWIHS1 || CONFIG_SAMV7_TWIHS2 */ diff --git a/arch/arm/src/samv7/sam_twihs.h b/arch/arm/src/samv7/sam_twihs.h new file mode 100644 index 0000000000000000000000000000000000000000..79f85a70e3894e6ddfc9afe708b496d90905b493 --- /dev/null +++ b/arch/arm/src/samv7/sam_twihs.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_twih.h + * + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_TWIHS_H +#define __ARCH_ARM_SRC_SAMV7_SAM_TWIHS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip/sam_twihs.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *sam_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: sam_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the sam_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_TWIHS_H */ diff --git a/arch/arm/src/samv7/sam_usbdev.h b/arch/arm/src/samv7/sam_usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..823871f16258c6ea3000a95195a9ba464de927c5 --- /dev/null +++ b/arch/arm/src/samv7/sam_usbdev.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_usbdev.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_USBDEV_H +#define __ARCH_ARM_SRC_SAMV7_SAM_USBDEV_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include +#include + +#include "chip/sam_usbhs.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: sam_usbsuspend + * + * Description: + * Board logic must provide the sam_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +void sam_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_USBDEV_H */ + diff --git a/arch/arm/src/samv7/sam_usbdevhs.c b/arch/arm/src/samv7/sam_usbdevhs.c new file mode 100644 index 0000000000000000000000000000000000000000..0c1f242acc227250185847d172081b811ea11e4e --- /dev/null +++ b/arch/arm/src/samv7/sam_usbdevhs.c @@ -0,0 +1,5011 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_usbdevhs.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This code derives from the UDPHS device controller driver for the SAMA5D3. + * That code, in turn, includes some reference logic extracted from the + * SAMA5D3 sample code. That Atmel sample code has a BSD compatible license + * that requires this copyright notice: + * + * Copyright (c) 2009, Atmel Corporation + * + * Additional updates for the SAMV7 was taken from Atmel sample code for the + * SAMV71: + * + * Copyright (c) 2014, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Atmel, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "cache.h" + +#include "chip.h" +#include "sam_periphclks.h" +#include "chip/sam_usbhs.h" +#include "sam_clockconfig.h" +#include "sam_usbdev.h" + +#if defined(CONFIG_USBDEV) && defined(CONFIG_SAMV7_USBDEVHS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +/* Number of DMA transfer descriptors. Default: 8 */ + +#ifndef CONFIG_SAMV7_USBDEVHS_NDTDS +# define CONFIG_SAMV7_USBDEVHS_NDTDS 8 +#endif + +#ifndef CONFIG_USBDEV_DMA +# warning Currently CONFIG_USBDEV_DMA must be set to make all endpoints working +#endif + +#if defined(CONFIG_USBDEV_DUALSPEED) && defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +# error CONFIG_USBDEV_DUALSPEED must not be defined with full-speed only support +#endif + +#if !defined(CONFIG_USBDEV_DUALSPEED) && !defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +# warning CONFIG_USBDEV_DUALSPEED should be defined for high speed support +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_SAMV7_USBHS_REGDEBUG +#endif + +/* Not yet supported */ + +#undef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER + +/* Driver Definitions *******************************************************/ +/* Initial interrupt mask: Reset + Suspend + Correct Transfer */ + +#define SAM_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_CTRM) + +/* Endpoint definitions */ + +#define EP0 (0) +#define SAM_EPSET_ALL (0xffff) /* All endpoints */ +#define SAM_EPSET_NOTEP0 (0xfffe) /* All endpoints except EP0 */ +#define SAM_EPSET_DMA (0x01fe) /* All endpoints that support DMA transfers */ +#define SAM_EP_BIT(ep) (1 << (ep)) +#define SAM_EP0_MAXPACKET (64) /* EP0 Max. packet size */ + +/* DMA FIFO */ + +#define DMA_MAX_FIFO_SIZE (65536/1) /* Max size of the FMA FIFO */ +#define EPT_FIFO_SIZE 16384 /* FIFO space size in units of 32-bit words */ + +/* USB-related masks */ + +#define REQRECIPIENT_MASK (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK) + +/* Endpoint register masks (handling toggle fields) */ + +#define EPR_NOTOG_MASK (USB_EPR_CTR_RX | USB_EPR_SETUP | USB_EPR_EPTYPE_MASK |\ + USB_EPR_EP_KIND | USB_EPR_CTR_TX | USB_EPR_EA_MASK) +#define EPR_TXDTOG_MASK (USB_EPR_STATTX_MASK | EPR_NOTOG_MASK) +#define EPR_RXDTOG_MASK (USB_EPR_STATRX_MASK | EPR_NOTOG_MASK) + +/* Cache-related */ + +#define MEMORY_SYNC() do { ARM_DSB();ARM_ISB(); } while (0) + +/* Request queue operations *************************************************/ + +#define sam_rqempty(q) ((q)->head == NULL) +#define sam_rqpeek(q) ((q)->head) + +/* Buffer Alignment ********************************************************* + * + * DMA buffers be aligned the 8-byte (2 word boundaries). However, if the + * data cache is enabled the a higher level of alignment is required. That + * is because the data will need to be invalidated and that cache + * invalidation will occur in multiples of full cache lines. + */ + +#ifdef CONFIG_ARMV7M_DCACHE +/* Align to the cache line size which we assume is >= 8 */ + +# define USBHS_ALIGN ARMV7M_DCACHE_LINESIZE +# define USBHS_ALIGN_MASK (USBHS_ALIGN-1) +# define USBHS_ALIGN_DOWN(n) ((n) & ~USBHS_ALIGN_MASK) +# define USBHS_ALIGN_UP(n) (((n) + USBHS_ALIGN_MASK) & ~USBHS_ALIGN_MASK) + +# ifndef CONFIG_ARMV7M_DCACHE_WRITETHROUGH +# warning !!! This driver will not work without CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y!!! +# endif + +#else +/* Use the minimum alignment requirement */ + +# define USBHS_ALIGN 8 +# define USBHS_ALIGN_MASK 7 +# define USBHS_ALIGN_DOWN(n) ((n) & ~7) +# define USBHS_ALIGN_UP(n) (((n) + 7) & ~7) + +#endif + +/* USB trace ****************************************************************/ +/* Trace error codes */ + +#define SAM_TRACEERR_ALLOCFAIL 0x0001 +#define SAM_TRACEERR_BADCLEARFEATURE 0x0002 +#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003 +#define SAM_TRACEERR_BADEPGETSTATUS 0x0004 +#define SAM_TRACEERR_BADEOBSTATE 0x0005 +#define SAM_TRACEERR_BADEPNO 0x0006 +#define SAM_TRACEERR_BADEPTYPE 0x0007 +#define SAM_TRACEERR_BADGETCONFIG 0x0008 +#define SAM_TRACEERR_BADGETSETDESC 0x0009 +#define SAM_TRACEERR_BADGETSTATUS 0x000a +#define SAM_TRACEERR_BADSETADDRESS 0x000b +#define SAM_TRACEERR_BADSETCONFIG 0x000c +#define SAM_TRACEERR_BADSETFEATURE 0x000d +#define SAM_TRACEERR_BINDFAILED 0x000e +#define SAM_TRACEERR_DISPATCHSTALL 0x000f +#define SAM_TRACEERR_DMAERR 0x0010 +#define SAM_TRACEERR_DRIVER 0x0011 +#define SAM_TRACEERR_DRIVERREGISTERED 0x0012 +#define SAM_TRACERR_REMAINING 0x0013 +#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0014 +#define SAM_TRACEERR_EP0SETUPSTALLED 0x0015 +#define SAM_TRACEERR_EPOUTNULLPACKET 0x0016 +#define SAM_TRACEERR_EPRESERVE 0x0017 +#define SAM_TRACEERR_NCFGOK 0x0018 +#define SAM_TRACEERR_INVALIDCTRLREQ 0x0019 +#define SAM_TRACEERR_IRQREGISTRATION 0x001a +#define SAM_TRACEERR_NOTCONFIGURED 0x001b +#define SAM_TRACEERR_REQABORTED 0x001c +#define SAM_TRACEERR_TXINERR 0x001d + +/* Trace interrupt codes */ + +#define SAM_TRACEINTID_ADDRESSED 0x0001 +#define SAM_TRACEINTID_CLEARFEATURE 0x0002 +#define SAM_TRACEINTID_INTSUSPD 0x0003 +#define SAM_TRACEINTID_DEVGETSTATUS 0x0004 +#define SAM_TRACEINTID_DISPATCH 0x0005 +#define SAM_TRACEINTID_DMA 0x0006 +#define SAM_TRACEINTID_DMAEOB 0x0007 +#define SAM_TRACEINTID_DMAEOC 0x0008 +#define SAM_TRACEINTID_ENDRESET 0x0009 +#define SAM_TRACEINTID_EP 0x000a +#define SAM_TRACEINTID_EP0SETUPIN 0x000b +#define SAM_TRACEINTID_EP0SETUPOUT 0x000c +#define SAM_TRACEINTID_EP0SETUPSETADDRESS 0x000d +#define SAM_TRACEINTID_EPDMAINT 0x000e +#define SAM_TRACEINTID_EPGETSTATUS 0x000f +#define SAM_TRACEINTID_EPINQEMPTY 0x0010 +#define SAM_TRACEINTID_EPINT 0x0011 +#define SAM_TRACEINTID_EPOUTQEMPTY 0x0012 +#define SAM_TRACEINTID_GETCONFIG 0x0013 +#define SAM_TRACEINTID_GETSETDESC 0x0014 +#define SAM_TRACEINTID_GETSETIF 0x0015 +#define SAM_TRACEINTID_GETSTATUS 0x0016 +#define SAM_TRACEINTID_IFGETSTATUS 0x0017 +#define SAM_TRACEINTID_INTERRUPT 0x0018 +#define SAM_TRACEINTID_INTSOF 0x0019 +#define SAM_TRACEINTID_INTMSOF 0x001a +#define SAM_TRACEINTID_NOSTDREQ 0x001b +#define SAM_TRACEINTID_PENDING 0x001c +#define SAM_TRACEINTID_RXRDY 0x001d +#define SAM_TRACEINTID_RXSETUP 0x001e +#define SAM_TRACEINTID_SETCONFIG 0x001f +#define SAM_TRACEINTID_SETFEATURE 0x0020 +#define SAM_TRACEINTID_SPEED 0x0021 +#define SAM_TRACEINTID_STALLSNT 0x0022 +#define SAM_TRACEINTID_SYNCHFRAME 0x0023 +#define SAM_TRACEINTID_TXINI 0x0024 +#define SAM_TRACEINTID_UPSTRRES 0x0025 +#define SAM_TRACEINTID_WAKEUP 0x0026 + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/* Byte ordering in host-based values */ + +#ifdef CONFIG_ENDIAN_BIG +# define LSB 1 +# define MSB 0 +#else +# define LSB 0 +# define MSB 1 +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ +/* State of an endpoint */ + +enum sam_epstate_e +{ + /* --- All Endpoints --- */ + USBHS_EPSTATE_DISABLED = 0, /* Endpoint is disabled */ + USBHS_EPSTATE_STALLED, /* Endpoint is stalled */ + USBHS_EPSTATE_IDLE, /* Endpoint is idle (i.e. ready for transmission) */ + USBHS_EPSTATE_SENDING, /* Endpoint is sending data */ + USBHS_EPSTATE_NBUSYBK, /* Endpoint DMA complete, waiting for NBUSYBK==0 */ + USBHS_EPSTATE_RECEIVING, /* Endpoint is receiving data */ + /* --- Endpoint 0 Only --- */ + USBHS_EPSTATE_EP0DATAOUT, /* Endpoint 0 is receiving SETUP OUT data */ + USBHS_EPSTATE_EP0STATUSIN, /* Endpoint 0 is sending SETUP status */ + USBHS_EPSTATE_EP0ADDRESS /* Address change is pending completion of status */ +}; + +/* The overall state of the device */ + +enum sam_devstate_e +{ + USBHS_DEVSTATE_SUSPENDED = 0, /* The device is currently suspended */ + USBHS_DEVSTATE_POWERED, /* Host is providing +5V through the USB cable */ + USBHS_DEVSTATE_DEFAULT, /* Device has been reset */ + USBHS_DEVSTATE_ADDRESSED, /* The device has been given an address on the bus */ + USBHS_DEVSTATE_CONFIGURED /* A valid configuration has been selected. */ +}; + +/* The result of EP0 SETUP processing */ + +enum sam_ep0setup_e +{ + USBHS_EP0SETUP_SUCCESS = 0, /* The SETUP was handle without incident */ + USBHS_EP0SETUP_DISPATCHED, /* The SETUP was forwarded to the class driver */ + USBHS_EP0SETUP_ADDRESS, /* A new device address is pending */ + USBHS_EP0SETUP_STALL /* An error occurred */ +}; + +/* DMA transfer descriptor */ + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +struct sam_dtd_s +{ + struct usbhs_dtd_s hw; /* These are the fields as seen by the hardware */ + uint32_t pad; /* Pad to 16 bytes to support arrays of descriptors */ +}; +#define SIZEOF_SAM_DTD_S 16 +#endif + +/* The following is used to manage lists of free DMA transfer descriptors */ + +struct sam_list_s +{ + struct sam_list_s *flink; /* Link to next entry in the list */ + /* Variable length entry data follows */ +}; + +union wb_u +{ + uint16_t w; + uint8_t b[2]; +}; + +/* A container for a request so that the request make be retained in a list */ + +struct sam_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct sam_req_s *flink; /* Supports a singly linked list */ + uint16_t inflight; /* Number of TX bytes written to FIFO */ +}; + +/* The head of a queue of requests */ + +struct sam_rqhead_s +{ + struct sam_req_s *head; /* Requests are added to the head of the list */ + struct sam_req_s *tail; /* Requests are removed from the tail of the list */ +}; + +/* This is the internal representation of an endpoint */ + +struct sam_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct sam_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* SAMV7-specific fields */ + + struct sam_usbdev_s *dev; /* Reference to private driver data */ + struct sam_rqhead_s reqq; /* Read/write request queue */ +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER + struct sam_dtd_s *dtdll; /* Head of the DMA transfer descriptor list */ +#endif + volatile uint8_t epstate; /* State of the endpoint (see enum sam_epstate_e) */ + volatile uint8_t bank; /* Current reception bank (0 or 1) */ + uint8_t stalled:1; /* true: Endpoint is stalled */ + uint8_t halted:1; /* true: Endpoint feature halted */ + uint8_t zlpneeded:1; /* Zero length packet needed at end of transfer */ + uint8_t zlpsent:1; /* Zero length packet has been sent */ +}; + +struct sam_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structsam_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* USBHS-specific fields */ + + struct usb_ctrlreq_s ctrl; /* Last EP0 request */ + uint8_t devstate; /* State of the device (see enum sam_devstate_e) */ + uint8_t prevstate; /* Previous state of the device before SUSPEND */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint16_t epavail; /* Bitset of available endpoints */ + + /* DMA Transfer descriptors */ + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER + struct sam_dtd_s *tdfree; /* A list of free transfer descriptors */ +#ifndef CONFIG_SAMV7_USBDEVHS_PREALLOCATE + struct sam_dtd_s *tdpool; /* Pool of allocated DMA transfer descriptors */ +#endif +#endif + + /* The endpoint list */ + + struct sam_ep_s eplist[SAM_USBHS_NENDPOINTS]; + + /* EP0 data buffer. For data that is included in an EP0 SETUP OUT + * transaction. In this case, no request is in place from the class + * driver and the incoming data is caught in this buffer. The size + * of valid dat in the buffer is given by ctrlreg.len[]. For the + * case of EP0 SETUP IN transaction, the normal request mechanism is + * used and the class driver provides the buffering. + */ + + uint8_t ep0out[SAM_EP0_MAXPACKET]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_SAMV7_USBHS_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite); +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +static void sam_dumpep(struct sam_usbdev_s *priv, int epno); +#else +static inline uint32_t sam_getreg(uintptr_t regaddr); +static inline void sam_putreg(uint32_t regval, uintptr_t regaddr); +# define sam_dumpep(priv,epno) +#endif + +/* Suspend/Resume Helpers ***************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv); +static void sam_resume(struct sam_usbdev_s *priv); + +/* DMA Transfer Helpers *****************************************************/ + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +static struct sam_dtd_s *sam_dtd_alloc(struct sam_usbdev_s *priv); +static void sam_dtd_free(struct sam_usbdev_s *priv, struct sam_dtd_s *dtd); +#endif +static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq, + uint32_t dmacontrol); +static void sam_dma_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); +static void sam_dma_rdsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); + +/* Request Helpers **********************************************************/ + +static struct sam_req_s * + sam_req_dequeue(struct sam_rqhead_s *queue); +static void sam_req_enqueue(struct sam_rqhead_s *queue, + struct sam_req_s *req); +static inline void + sam_req_abort(struct sam_ep_s *privep, + struct sam_req_s *privreq, int16_t result); +static void sam_req_complete(struct sam_ep_s *privep, int16_t result); +static void sam_ep_fifocon(unsigned int epno); +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq); +static int sam_req_write(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static void sam_req_rddone(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, struct sam_req_s *privreq, + uint16_t recvsize); +static void sam_req_rdenable(uint8_t epno); +static void sam_req_rddisable(uint8_t epno); +static int sam_req_read(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, uint16_t recvsize); +static void sam_req_cancel(struct sam_ep_s *privep, int16_t status); + +/* Interrupt level processing ***********************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen); +static void sam_ctrlep_write(struct sam_ep_s *privep, const uint8_t *buffer, + size_t buflen); +static void sam_ep_write(struct sam_ep_s *privep, const uint8_t *buffer, + size_t buflen); +static void sam_ep0_dispatch(struct sam_usbdev_s *priv); +static void sam_ep0_setup(struct sam_usbdev_s *priv); +#ifdef CONFIG_USBDEV_DMA +static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno); +#endif +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno); +static int sam_usbhs_interrupt(int irq, void *context); + +/* Endpoint helpers *********************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno); +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset); +static inline struct sam_ep_s * + sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset); +static inline void + sam_ep_unreserve(struct sam_usbdev_s *priv, + struct sam_ep_s *privep); +static inline bool + sam_ep_reserved(struct sam_usbdev_s *priv, int epno); +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc); +static inline int + sam_ep0_configure(struct sam_usbdev_s *priv); + +/* Endpoint operations ******************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int sam_ep_disable(struct usbdev_ep_s *ep); +static struct usbdev_req_s * + sam_ep_allocreq(struct usbdev_ep_s *ep); +static void sam_ep_freereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes); +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf); +#endif +static int sam_ep_submit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_cancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations *****************************************/ + +static struct usbdev_ep_s * + sam_allocep(struct usbdev_s *dev, uint8_t epno, bool in, + uint8_t eptype); +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep); +static int sam_getframe(struct usbdev_s *dev); +static int sam_wakeup(struct usbdev_s *dev); +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int sam_pullup(FAR struct usbdev_s *dev, bool enable); + +/* Initialization/Reset *****************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv); +static void sam_hw_setup(struct sam_usbdev_s *priv); +static void sam_sw_setup(struct sam_usbdev_s *priv); +static void sam_hw_shutdown(struct sam_usbdev_s *priv); +static void sam_sw_shutdown(struct sam_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct sam_usbdev_s g_usbhs; + +static const struct usbdev_epops_s g_epops = +{ + .configure = sam_ep_configure, + .disable = sam_ep_disable, + .allocreq = sam_ep_allocreq, + .freereq = sam_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = sam_ep_allocbuffer, + .freebuffer = sam_ep_freebuffer, +#endif + .submit = sam_ep_submit, + .cancel = sam_ep_cancel, + .stall = sam_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = sam_allocep, + .freeep = sam_freeep, + .getframe = sam_getframe, + .wakeup = sam_wakeup, + .selfpowered = sam_selfpowered, + .pullup = sam_pullup, +}; + +/* This describes endpoint 0 */ + +static const struct usb_epdesc_s g_ep0desc = +{ + .len = USB_SIZEOF_EPDESC, + .type = USB_DESC_TYPE_ENDPOINT, + .addr = EP0, + .attr = USB_EP_ATTR_XFER_CONTROL, + .mxpacketsize = {64, 0}, + .interval = 0 +}; + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +#ifdef CONFIG_SAMV7_USBDEVHS_PREALLOCATE +/* This is a properly aligned pool of preallocated DMA transfer descriptors */ + +static struct sam_dtd_s g_dtdpool[CONFIG_SAMV7_USBDEVHS_NDTDS] + __attribute__ ((aligned(16))); +#endif +#endif + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(SAM_TRACEERR_ALLOCFAIL), + TRACE_STR(SAM_TRACEERR_BADCLEARFEATURE), + TRACE_STR(SAM_TRACEERR_BADDEVGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADEOBSTATE), + TRACE_STR(SAM_TRACEERR_BADEPNO), + TRACE_STR(SAM_TRACEERR_BADEPTYPE), + TRACE_STR(SAM_TRACEERR_BADGETCONFIG), + TRACE_STR(SAM_TRACEERR_BADGETSETDESC), + TRACE_STR(SAM_TRACEERR_BADGETSTATUS), + TRACE_STR(SAM_TRACEERR_BADSETADDRESS), + TRACE_STR(SAM_TRACEERR_BADSETCONFIG), + TRACE_STR(SAM_TRACEERR_BADSETFEATURE), + TRACE_STR(SAM_TRACEERR_BINDFAILED), + TRACE_STR(SAM_TRACEERR_DISPATCHSTALL), + TRACE_STR(SAM_TRACEERR_DMAERR), + TRACE_STR(SAM_TRACEERR_DRIVER), + TRACE_STR(SAM_TRACEERR_DRIVERREGISTERED), + TRACE_STR(SAM_TRACERR_REMAINING), + TRACE_STR(SAM_TRACEERR_EP0SETUPOUTSIZE), + TRACE_STR(SAM_TRACEERR_EP0SETUPSTALLED), + TRACE_STR(SAM_TRACEERR_EPOUTNULLPACKET), + TRACE_STR(SAM_TRACEERR_EPRESERVE), + TRACE_STR(SAM_TRACEERR_NCFGOK), + TRACE_STR(SAM_TRACEERR_INVALIDCTRLREQ), + TRACE_STR(SAM_TRACEERR_IRQREGISTRATION), + TRACE_STR(SAM_TRACEERR_NOTCONFIGURED), + TRACE_STR(SAM_TRACEERR_REQABORTED), + TRACE_STR(SAM_TRACEERR_TXINERR), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(SAM_TRACEINTID_ADDRESSED), + TRACE_STR(SAM_TRACEINTID_CLEARFEATURE), + TRACE_STR(SAM_TRACEINTID_INTSUSPD), + TRACE_STR(SAM_TRACEINTID_DEVGETSTATUS), + TRACE_STR(SAM_TRACEINTID_DISPATCH), + TRACE_STR(SAM_TRACEINTID_DMA), + TRACE_STR(SAM_TRACEINTID_DMAEOB), + TRACE_STR(SAM_TRACEINTID_DMAEOC), + TRACE_STR(SAM_TRACEINTID_ENDRESET), + TRACE_STR(SAM_TRACEINTID_EP), + TRACE_STR(SAM_TRACEINTID_EP0SETUPIN), + TRACE_STR(SAM_TRACEINTID_EP0SETUPOUT), + TRACE_STR(SAM_TRACEINTID_EP0SETUPSETADDRESS), + TRACE_STR(SAM_TRACEINTID_EPDMAINT), + TRACE_STR(SAM_TRACEINTID_EPGETSTATUS), + TRACE_STR(SAM_TRACEINTID_EPINQEMPTY), + TRACE_STR(SAM_TRACEINTID_EPINT), + TRACE_STR(SAM_TRACEINTID_EPOUTQEMPTY), + TRACE_STR(SAM_TRACEINTID_GETCONFIG), + TRACE_STR(SAM_TRACEINTID_GETSETDESC), + TRACE_STR(SAM_TRACEINTID_GETSETIF), + TRACE_STR(SAM_TRACEINTID_GETSTATUS), + TRACE_STR(SAM_TRACEINTID_IFGETSTATUS), + TRACE_STR(SAM_TRACEINTID_INTERRUPT), + TRACE_STR(SAM_TRACEINTID_INTSOF), + TRACE_STR(SAM_TRACEINTID_INTMSOF), + TRACE_STR(SAM_TRACEINTID_NOSTDREQ), + TRACE_STR(SAM_TRACEINTID_PENDING), + TRACE_STR(SAM_TRACEINTID_RXRDY), + TRACE_STR(SAM_TRACEINTID_RXSETUP), + TRACE_STR(SAM_TRACEINTID_SETCONFIG), + TRACE_STR(SAM_TRACEINTID_SETFEATURE), + TRACE_STR(SAM_TRACEINTID_SPEED), + TRACE_STR(SAM_TRACEINTID_STALLSNT), + TRACE_STR(SAM_TRACEINTID_SYNCHFRAME), + TRACE_STR(SAM_TRACEINTID_TXINI), + TRACE_STR(SAM_TRACEINTID_UPSTRRES), + TRACE_STR(SAM_TRACEINTID_WAKEUP), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_printreg + * + * Description: + * Print the contents of a SAMV7 USBHS register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBHS_REGDEBUG +static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + lldbg("%p%s%08x\n", regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: sam_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a SAMV7 + * USBHS register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBHS_REGDEBUG +static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite) +{ + static uintptr_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + sam_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + sam_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMV7 register + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBHS_REGDEBUG +static uint32_t sam_getreg(uintptr_t regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t sam_getreg(uintptr_t regaddr) +{ + return getreg32(regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMV7 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBHS_REGDEBUG +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Check if we need to print this value */ + + sam_checkreg(regaddr, regval, true); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#else +static inline void sam_putreg(uint32_t regval, uint32_t regaddr) +{ + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_dumpep + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USBHS_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_dumpep(struct sam_usbdev_s *priv, int epno) +{ + /* Global Registers */ + + lldbg("Global Register:\n"); + lldbg(" CTRL: %08x\n", sam_getreg(SAM_USBHS_DEVCTRL)); + lldbg(" ISR: %08x\n", sam_getreg(SAM_USBHS_DEVISR)); + lldbg(" IMR: %08x\n", sam_getreg(SAM_USBHS_DEVIMR)); + lldbg(" EPT: %08x\n", sam_getreg(SAM_USBHS_DEVEPT)); + lldbg(" FNUM: %08x\n", sam_getreg(SAM_USBHS_DEVFNUM)); + + /* Endpoint registers */ + + lldbg("Endpoint %d Register:\n", epno); + lldbg(" CFG: %08x\n", sam_getreg(SAM_USBHS_DEVEPTCFG(epno))); + lldbg(" ISR: %08x\n", sam_getreg(SAM_USBHS_DEVEPTISR(epno))); + lldbg(" IMR: %08x\n", sam_getreg(SAM_USBHS_DEVEPTIMR(epno))); + + lldbg("DMA %d Register:\n", epno); + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + lldbg(" NXTDSC: %08x\n", sam_getreg(SAM_USBHS_DEVDMANXTDSC(epno))); + lldbg(" ADDRESS: %08x\n", sam_getreg(SAM_USBHS_DEVDMAADDR(epno))); + lldbg(" CONTROL: %08x\n", sam_getreg(SAM_USBHS_DEVDMACTRL(epno))); + lldbg(" STATUS: %08x\n", sam_getreg(SAM_USBHS_DEVDMASTA(epno))); + } + else + { + lldbg(" None\n"); + } +} +#endif + +/**************************************************************************** + * DMA + ****************************************************************************/ +/**************************************************************************** + * Name: sam_dtd_alloc + * + * Description: + * Allocate a DMA transfer descriptor by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +static struct sam_dtd_s *sam_dtd_alloc(struct sam_usbdev_s *priv) +{ + struct sam_dtd_s *dtd; + + /* Remove the DMA transfer descriptor from the freelist */ + + dtd = (struct sam_dtd_s *)g_usbhs.dtdfree; + if (dtd) + { + g_usbhs.dtdfree = ((struct sam_list_s *)dtd)->flink; + memset(dtd, 0, sizeof(struct sam_dtd_s)); + } + + return dtd; +} +#endif + +/**************************************************************************** + * Name: sam_dtd_free + * + * Description: + * Free a DMA transfer descriptor by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +static void sam_dtd_free(struct sam_usbdev_s *priv, struct sam_dtd_s *dtd) +{ + struct sam_list_s *entry = (struct sam_list_s *)dtd; + + /* Put the dtd structure back into the free list */ + + entry->flink = g_usbhs.dtdfree; + g_usbhs.dtdfree = entry; +} +#endif + +/**************************************************************************** + * Name: sam_dma_single + * + * Description: + * Setup a start a single buffer DMA. + * + * Assumption: Called as part of USBHS interrupt handling + * + ****************************************************************************/ + +static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq, + uint32_t dmacontrol) +{ + uintptr_t buffer; + + /* Not all endpoints support DMA */ + + DEBUGASSERT((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0); + + /* Flush the contents of the DMA buffer to RAM */ + + buffer = (uintptr_t)&privreq->req.buf[privreq->req.xfrd]; + arch_clean_dcache(buffer, buffer + privreq->inflight); + + /* Set up the DMA */ + + sam_putreg((uint32_t)buffer, SAM_USBHS_DEVDMAADDR(epno)); + + /* Clear any pending interrupts then enable the DMA interrupt */ + + (void)sam_getreg(SAM_USBHS_DEVDMASTA(epno)); + sam_putreg(USBHS_DEVINT_DMA(epno), SAM_USBHS_DEVIER); + + /* Setup and enable the DMA */ + + sam_putreg(0, SAM_USBHS_DEVDMACTRL(epno)); + + dmacontrol |= USBHS_DEVDMACTRL_BUFLEN(privreq->inflight); + sam_putreg(dmacontrol, SAM_USBHS_DEVDMACTRL(epno)); +} + +/**************************************************************************** + * Name: sam_dma_wrsetup + * + * Description: + * Process the next queued write request for an endpoint that supports DMA. + * + ****************************************************************************/ + +static void sam_dma_wrsetup(struct sam_usbdev_s *priv, struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + int remaining; + int epno; + + /* Switch to the sending state */ + + privep->epstate = USBHS_EPSTATE_SENDING; + privreq->inflight = 0; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* How many bytes remain to be transferred in the request? */ + + remaining = (int)privreq->req.len - (int)privreq->req.xfrd; + DEBUGASSERT(remaining >= 0 && remaining <= (int)privreq->req.len); + + /* If there are no bytes to send, then send a zero length packet */ + + if (remaining > 0) + { + /* Clip the transfer to the size of the DMA FIFO */ + +#if USBDEV_MAXREQUEUST > DMA_MAX_FIFO_SIZE + if (remaining > DMA_MAX_FIFO_SIZE) + { + privreq->inflight = DMA_MAX_FIFO_SIZE; + privep->zlpneeded = false; + } + else +#endif + { + privreq->inflight = remaining; + + /* If the size is an exact multple of full packets, then note if + * we need to send a zero length packet next. + */ + + privep->zlpneeded = + ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0 && + (remaining % privep->ep.maxpacket) == 0); + } + + /* And perform the single DMA transfer. + * + * 32.6.10.6 Bulk IN or Interrupt IN: Sending a Buffer Using DMA + * - END_B_EN: The endpoint can validate the packet (according to the + * values programmed in the AUTO_VALID and SHRT_PCKT fields of + * USBHS_EPTCTLx.) ... + * - END_BUFFIT: generate an interrupt when the BUFF_COUNT in + * USBHS_DMASTATUSx reaches 0. + * - CHANN_ENB: Run and stop at end of buffer + */ + + sam_dma_single(epno, privreq, + USBHS_DEVDMACTRL_ENDBEN | USBHS_DEVDMACTRL_ENDBUFFIT | + USBHS_DEVDMACTRL_CHANNENB); + } + + /* Enable the endpoint interrupt */ + + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIER); +} + +/**************************************************************************** + * Name: sam_dma_rdsetup + * + * Description: + * Process the next queued read request for an endpoint that supports DMA. + * + ****************************************************************************/ + +static void sam_dma_rdsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + uint32_t regval; + int remaining; + int epno; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* How many more bytes can we append to the request buffer? */ + + remaining = (int)privreq->req.len - (int)privreq->req.xfrd; + DEBUGASSERT(remaining > 0 && remaining <= (int)privreq->req.len && + privep->epstate == USBHS_EPSTATE_RECEIVING); + + /* Clip the DMA transfer size to the size available in the user buffer */ + +#if USBDEV_MAXREQUEUST > DMA_MAX_FIFO_SIZE + if (remaining > DMA_MAX_FIFO_SIZE) + { + privreq->inflight = DMA_MAX_FIFO_SIZE; + } + else +#endif + { + privreq->inflight = remaining; + } + + /* And perform the single DMA transfer. + * + * 32.6.10.12 Bulk OUT or Interrupt OUT: Sending a Buffer Using DMA + * - END_B_EN: Can be used for OUT packet truncation (discarding of + * unbuffered packet data) at the end of DMA buffer. + * - END_BUFFIT: Generate an interrupt when BUFF_COUNT in the + * USBHS_DMASTATUSx register reaches 0. + * - END_TR_EN: End of transfer enable, the USBHS device can put an + * end to the current DMA transfer, in case of a short packet. + * - END_TR_IT: End of transfer interrupt enable, an interrupt is sent + * after the last USB packet has been transferred by the DMA, if the + * USB transfer ended with a short packet. (Beneficial when the + * receive size is unknown.) + * - CHANN_ENB: Run and stop at end of buffer. + */ + + regval = USBHS_DEVDMACTRL_ENDBEN | USBHS_DEVDMACTRL_ENDBUFFIT | + USBHS_DEVDMACTRL_ENDTREN | USBHS_DEVDMACTRL_ENDTRIT | + USBHS_DEVDMACTRL_CHANNENB; + + sam_dma_single(epno, privreq, regval); +} + +/**************************************************************************** + * Request Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_req_dequeue + ****************************************************************************/ + +static struct sam_req_s *sam_req_dequeue(struct sam_rqhead_s *queue) +{ + struct sam_req_s *ret = queue->head; + + if (ret) + { + queue->head = ret->flink; + if (!queue->head) + { + queue->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_req_enqueue + ****************************************************************************/ + +static void sam_req_enqueue(struct sam_rqhead_s *queue, struct sam_req_s *req) +{ + req->flink = NULL; + if (!queue->head) + { + queue->head = req; + queue->tail = req; + } + else + { + queue->tail->flink = req; + queue->tail = req; + } +} + +/**************************************************************************** + * Name: sam_req_abort + ****************************************************************************/ + +static inline void +sam_req_abort(struct sam_ep_s *privep, struct sam_req_s *privreq, int16_t result) +{ + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_REQABORTED), + (uint16_t)USB_EPNO(privep->ep.eplog)); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: sam_req_complete + ****************************************************************************/ + +static void sam_req_complete(struct sam_ep_s *privep, int16_t result) +{ + struct sam_req_s *privreq; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = sam_req_dequeue(&privep->reqq); + leave_critical_section(flags); + + if (privreq) + { + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Reset the endpoint state and restore the stalled indication */ + + privep->epstate = USBHS_EPSTATE_IDLE; + privep->zlpneeded = false; + privep->zlpsent = false; + } +} + +/**************************************************************************** + * Name: sam_ep_fifocon + * + * Description: + * IN data has been loaded in the endpoint FIFO. Manage the endpoint to + * (1) initiate sending of the data and (2) receive the TXIN interrupt + * when the transfer completes. + * + ****************************************************************************/ + +static void sam_ep_fifocon(unsigned int epno) +{ + /* Clear FIFOCON to indicate that the packet is ready to send (this works + * even for zero length packets). We will get an TXIN interrupt with + * FIFCON=1 when the transfer completes. Then we are able to send the + * next packet. + */ + + sam_putreg(USBHS_DEVEPTINT_FIFOCONI, SAM_USBHS_DEVEPTIDR(epno)); + + /* Clear the NAK IN bit to stop NAKing IN tokens from the host. We now + * have data ready to go. + * + * REVISIT: I don't think the USBHS_DEVEPTINT_NAKINI is necessary. + */ + + sam_putreg(USBHS_DEVEPTINT_NAKINI, SAM_USBHS_DEVEPTICR(epno)); + + /* Enable the TXIN interrupt on the endpoint */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIER(epno)); +} + +/**************************************************************************** + * Name: sam_req_wrsetup + * + * Description: + * Process the next queued write request for an endpoint that does not + * support DMA. + * + ****************************************************************************/ + +static void sam_req_wrsetup(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq) +{ + uint32_t regval; + const uint8_t *buf; + uint8_t epno; + unsigned int eptype; + int nbytes; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Get the number of bytes remaining to be sent. */ + + DEBUGASSERT(privreq->req.xfrd < privreq->req.len); + nbytes = privreq->req.len - privreq->req.xfrd; + + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + privep->zlpneeded = false; + if (nbytes > privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + } + else if (nbytes == privep->ep.maxpacket) + { + /* If the size is exactly a full packet, then note if we need to + * send a zero length packet next. + */ + + privep->zlpneeded = + ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + } + + /* This is the new number of bytes "in-flight" */ + + privreq->inflight = nbytes; + usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes); + + /* The new buffer pointer is the started of the buffer plus the number + * of bytes successfully transferred plus the number of bytes previously + * "in-flight". + */ + + buf = privreq->req.buf + privreq->req.xfrd; + + /* How we send packets differs for control endpoints */ + + regval = sam_getreg(SAM_USBHS_DEVEPTCFG(epno)); + eptype = regval & USBHS_DEVEPTCFG_EPTYPE_MASK; + + if (eptype == USBHS_DEVEPTCFG_EPTYPE_CTRL) + { + sam_ctrlep_write(privep, buf, nbytes); + } + else + { + sam_ep_write(privep, buf, nbytes); + } +} + +/**************************************************************************** + * Name: sam_req_write + * + * Description: + * Process the next queued write request. This function is called in one + * of three contexts: (1) When the endpoint is IDLE and a new write request + * is submitted (with interrupts disabled), (2) from interrupt handling + * when the current transfer completes (either DMA or FIFO), or (3) when + * resuming a stalled IN or control endpoint. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is the number of bytes + * to transfer and 'xfrd' and 'inflight' must be zero. + * + * When this function starts a transfer it will update the request + * 'inflight' field to indicate the size of the transfer. + * + * When the transfer completes, the the 'inflight' field must hold the + * number of bytes that have completed the transfer. This function will + * update 'xfrd' with the new size of the transfer. + * + ****************************************************************************/ + +static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + struct sam_req_s *privreq; + uint32_t regval; + uint32_t eptype; + uint8_t epno; + int bytesleft; + + /* Get the unadorned endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* We get here when an IN endpoint interrupt occurs. So now we know that + * there is no TX transfer in progress. + */ + + while (privep->epstate == USBHS_EPSTATE_IDLE) + { + /* Check the request from the head of the endpoint request queue */ + + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* There is no TX transfer in progress and no new pending TX + * requests to send. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPINQEMPTY), 0); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_USBHS_DEVEPTCFG(epno)); + eptype = regval & USBHS_DEVEPTCFG_EPTYPE_MASK; + + /* Disable interrupts on non-control endpoints */ + + if (eptype != USBHS_DEVEPTCFG_EPTYPE_CTRL) + { + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + } + + /* Clear and Disable the TXIN interrupt */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIDR(epno)); + return -ENOENT; + } + + ullvdbg("epno=%d req=%p: len=%d xfrd=%d inflight=%d zlpneeded=%d\n", + epno, privreq, privreq->req.len, privreq->req.xfrd, + privreq->inflight, privep->zlpneeded); + + /* Handle any bytes in flight. */ + + privreq->req.xfrd += privreq->inflight; + privreq->inflight = 0; + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + if (bytesleft > 0) + { + /* The way that we handle the transfer is going to depend on + * whether or not this endpoint supports DMA. In either case + * the endpoint state will transition to SENDING. + */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + sam_dma_wrsetup(priv, privep, privreq); + } + else + { + sam_req_wrsetup(priv, privep, privreq); + } + } + + /* No data to send... This can happen on one of two ways: + * (1) The last packet sent was the final packet of a transfer. + * If it was also exactly maxpacketsize and the protocol expects + * a zero length packet to follow then privep->zlpneeded will be + * set. Or (2) we called with a request packet that has + * len == 0 (privep->zlpneeded will not be set). Either case + * means that it is time to send a zero length packet and complete + * this transfer. + */ + + else if ((privreq->req.len == 0 || privep->zlpneeded) && !privep->zlpsent) + { + /* If we get here, then we sent the last of the data on the + * previous pass and we need to send the zero length packet now. + * + * A Zero Length Packet can be sent by clearing just the FIFOCON + * flag in the USBHS_DEVTEPTIDRx register + */ + + privep->epstate = USBHS_EPSTATE_SENDING; + privep->zlpneeded = false; + privep->zlpsent = true; + privreq->inflight = 0; + + /* Initiate the zero length transfer and configure to receive the + * transfer complete interrupt. + */ + + sam_ep_fifocon(epno); + } + + /* If all of the bytes were sent (including any final zero length + * packet) then we are finished with the request buffer and we can + * return the request buffer to the class driver. The state will + * remain IDLE only if nothing else was put in flight. + * + * Note that we will then loop to check to check the next queued + * write request. + */ + + if (privep->epstate == USBHS_EPSTATE_IDLE) + { + /* Return the write request to the class driver */ + + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + privreq->req.xfrd); + + DEBUGASSERT(privreq->req.len == privreq->req.xfrd); + sam_req_complete(privep, OK); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_req_rddone + * + * Description: + * The last non-DMA OUT transfer has completed. Read 'recvsize' byts from + * the FIFO into the read request buffer. + * + ****************************************************************************/ + +static void sam_req_rddone(struct sam_usbdev_s *priv, + struct sam_ep_s *privep, + struct sam_req_s *privreq, uint16_t recvsize) +{ + const uint8_t *fifo; + uint8_t *dest; + int remaining; + int readlen; + int epno; + + /* Get the number of bytes that can be received. This is the size of the + * user-provided request buffer, minus the number of bytes already + * transferred to the user-buffer. + */ + + remaining = privreq->req.len - privreq->req.xfrd; + + /* Read the smaller of the number of bytes available in FIFO and the + * size remaining in the request buffer provided by the caller. + */ + + readlen = MIN(remaining, recvsize); + privreq->req.xfrd += readlen; + + /* Get the source and destination transfer addresses */ + + epno = USB_EPNO(privep->ep.eplog); + fifo = (const uint8_t *) + ((uint32_t *)SAM_USBHSRAM_BASE + (EPT_FIFO_SIZE * epno)); + dest = privreq->req.buf + privreq->req.xfrd; + + /* Retrieve packet from the FIFO */ + + for (; readlen > 0; readlen--) + { + *dest++ = *fifo++; + } + + MEMORY_SYNC(); +} + +/**************************************************************************** + * Name: sam_req_rdenable + * + * Description: + * Make sure that the endpoint RXRDY_TXTK interrupt is enabled in order + * to receive the next incoming packet + * + ****************************************************************************/ + +static void sam_req_rdenable(uint8_t epno) +{ + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIER); + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTIER(epno)); +} + +/**************************************************************************** + * Name: sam_req_rddisable + * + * Description: + * Disable endpoint interrupts + * + ****************************************************************************/ + +static void sam_req_rddisable(uint8_t epno) +{ + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTIDR(epno)); +} + +/**************************************************************************** + * Name: sam_req_read + * + * Description: + * Complete the last read request, return the read request to the class + * implementation, and try to started the next queued read request. + * + * This function is called in one of three contexts: (1) When the endpoint + * is IDLE and a new read request is submitted (with interrupts disabled), + * (2) from interrupt handling when the current transfer completes (either + * DMA or FIFO), or (3) when resuming a stalled OUT or control endpoint. + * + * There is a fundamental difference between receiving packets via DMA and + * via the FIFO: + * + * - When receiving data via DMA, then data has already been transferred + * and this function is called on the terminating event. The transfer + * is complete and we just need to check for end of request events and + * if we need to setup the transfer for the next request. + * - When receiving via the FIFO, the transfer is not complete. The + * data is in the FIFO and must be transferred from the FIFO to the + * request buffer. No setup is needed for the next transfer other than + * assuring that the endpoint RXRDY_TXTK interrupt is enabled. + * + * Calling rules: + * + * The transfer state must IDLE + * + * When a request is queued, the request 'len' is size of the request + * buffer. Any OUT request can be received that will fit in this + * buffer. 'xfrd' and 'inflight' in the request must be zero + * If sam_req_read() is called to start a new transfer, the recvsize + * parameter must be zero. + * + * When this function starts a DMA transfer it will update the request + * 'inflight' field to hold the maximum size of the transfer; but + * 'inflight' is not used with FIFO transfers. + * + * When the transfer completes, the 'recvsize' parameter must be the + * size of the transfer that just completed. For the case of DMA, + * that is the size of the DMA transfer that has just been written to + * memory; for the FIFO transfer, recvsize is the number of bytes + * waiting in the FIFO to be read. + * + ****************************************************************************/ + +static int sam_req_read(struct sam_usbdev_s *priv, struct sam_ep_s *privep, + uint16_t recvsize) +{ + struct sam_req_s *privreq; + uint32_t regval; + uint32_t eptype; + uint8_t epno; + + DEBUGASSERT(priv && privep && privep->epstate == USBHS_EPSTATE_IDLE); + + /* Loop in case we need to handle multiple read requests */ + + while (privep->epstate == USBHS_EPSTATE_IDLE) + { + /* Check the request from the head of the endpoint request queue */ + + epno = USB_EPNO(privep->ep.eplog); + privreq = sam_rqpeek(&privep->reqq); + if (!privreq) + { + /* No packet to receive data */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPOUTQEMPTY), epno); + return -ENOENT; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + epno, privreq->req.len, privreq->req.xfrd); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPOUTNULLPACKET), 0); + sam_req_complete(privep, OK); + recvsize = 0; + continue; + } + + usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), recvsize); + + /* Update the number of bytes transferred with the received size */ + + privreq->req.xfrd += recvsize; + privreq->inflight = 0; + + /* If this was not a DMA transfer, read the incoming data from the FIFO */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) == 0) + { + sam_req_rddone(priv, privep, privreq, recvsize); + } + + /* In case we go through the loop again */ + + recvsize = 0; + + /* If nothing has yet be transferred into the read request, then + * indicate that we are in the RECEIVING state and, if the endpoint + * supports DMA, setup the receive DMA. + */ + + if (privreq->req.xfrd == 0) + { + /* Set the RECEIVING state */ + + privep->epstate = USBHS_EPSTATE_RECEIVING; + + /* If the endpoint supports DMA, set up the DMA now */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + /* Set up the next DMA. We will come through this logic path + * again with xrfd != 0 when the DMA completes. + */ + + sam_dma_rdsetup(priv, privep, privreq); + } + + /* No DMA for this endpoint and we have an available, empty read + * request. We need to wait for data to become avaialable. + */ + + else + { + /* Enable endpoint RXRDY_TXTK interrupts */ + + sam_req_rdenable(epno); + } + } + + /* We will not try to accumulate packet data here. If anything + * has been received, we will complete the transfer immediately and + * give the data to the class driver. The idea is that we will let the + * receiving be in-charge if incoming buffer. + */ + + else + { + /* Return the read request to the class driver. */ + + usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd); + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTIDR(epno)); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_USBHS_DEVEPTCFG(epno)); + eptype = regval & USBHS_DEVEPTCFG_EPTYPE_MASK; + + /* Disable endpoint interrupts if not the control endpoint */ + + if (eptype != USBHS_DEVEPTCFG_EPTYPE_CTRL) + { + sam_req_rddisable(epno); + } + + /* And complete the request */ + + privep->epstate = USBHS_EPSTATE_IDLE; + sam_req_complete(privep, OK); + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_req_cancel + ****************************************************************************/ + +static void sam_req_cancel(struct sam_ep_s *privep, int16_t result) +{ + uint32_t regval; + uint8_t epno; + + /* Disable endpoint interrupts if not endpoint 0 */ + + epno = USB_EPNO(privep->ep.eplog); + if (epno != 0) + { + regval = USBHS_DEVINT_DMA(epno) | USBHS_DEVINT_PEP(epno); + sam_putreg(regval, SAM_USBHS_DEVIDR); + } + + /* Then complete every queued request with the specified status */ + + while (!sam_rqempty(&privep->reqq)) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + (sam_rqpeek(&privep->reqq))->req.xfrd); + sam_req_complete(privep, result); + } +} + +/**************************************************************************** + * Interrupt Level Processing + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep0_read + * + * Description: + * Read a general USB request from the USBHS FIFO + * + ****************************************************************************/ + +static void sam_ep0_read(uint8_t *buffer, size_t buflen) +{ + volatile const uint8_t *fifo; + + /* Retrieve packet from the FIFO */ + + fifo = (volatile const uint8_t *)SAM_USBHSRAM_BASE; + for (; buflen > 0; buflen--) + { + *buffer++ = *fifo++; + } + + MEMORY_SYNC(); +} + +/**************************************************************************** + * Name: sam_ctrlep_write + * + * Description: + * Process the next queued write request for a control endpoint. + * + ****************************************************************************/ + +static void sam_ctrlep_write(struct sam_ep_s *privep, const uint8_t *buffer, + size_t buflen) +{ + volatile uint8_t *fifo; + unsigned int epno; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Write packet in the FIFO buffer */ + + fifo = (uint8_t *) + ((uint32_t *)SAM_USBHSRAM_BASE + (EPT_FIFO_SIZE * epno)); + + for (; buflen > 0; buflen--) + { + *fifo++ = *buffer++; + } + + MEMORY_SYNC(); + + /* Indicate that there is data in the TX packet memory. This will + * be cleared when the next NAKIN interrupt is received. + */ + + privep->epstate = USBHS_EPSTATE_SENDING; + + /* The FIFO Control (USBHS_DEVEPTIMRx.FIFOCON) bit and the Read/Write + * Allowed (USBHS_DEVEPTISRx.RWALL) bit are irrelevant for control + * endpoints. The user never uses them on these endpoints. + */ + + /* USBHS_DEVEPTISRx.TXINI is cleared by software (by writing a one to + * the Transmitted IN Data Interrupt Clear bit (USBHS_DEVEPTIDRx.TXINIC) + * to acknowledge the interrupt, which has no effect on the endpoint + * FIFO. This acknowledges the interrupt and sends the packet. + */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIDR(epno)); + + /* Clear the NAKIN bit to stop NAKing IN tokens from the host. We now + * have data ready to go. + */ + + sam_putreg((USBHS_DEVEPTINT_NAKINI | USBHS_DEVEPTINT_TXINI), + SAM_USBHS_DEVEPTICR(epno)); + + /* Enable the TXIN interrupt on the endpoint */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIER(epno)); +} + +/**************************************************************************** + * Name: sam_ep_write + * + * Description: + * Process the next queued write request for a control endpoint. + * + ****************************************************************************/ + +static void sam_ep_write(struct sam_ep_s *privep, const uint8_t *buffer, + size_t buflen) +{ + volatile uint8_t *fifo; + unsigned int epno; + + /* Get the endpoint number */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Write packet in the FIFO buffer */ + + fifo = (uint8_t *) + ((uint32_t *)SAM_USBHSRAM_BASE + (EPT_FIFO_SIZE * epno)); + + for (; buflen; buflen--) + { + *fifo++ = *buffer++; + } + + MEMORY_SYNC(); + + /* Indicate that there is data in the TX packet memory. This will + * be cleared when the next data out interrupt is received. + */ + + privep->epstate = USBHS_EPSTATE_SENDING; + + /* Initiate the transfer and configure to receive the transfer complete + * interrupt. + */ + + sam_ep_fifocon(epno); +} + +/**************************************************************************** + * Name: sam_ep0_dispatch + ****************************************************************************/ + +static void sam_ep0_dispatch(struct sam_usbdev_s *priv) +{ + uint8_t *dataout; + size_t outlen; + int ret; + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Assume IN SETUP (or OUT SETUP with no data) */ + + dataout = NULL; + outlen = 0; + + /* Was this an OUT SETUP command? */ + + if (USB_REQ_ISOUT(priv->ctrl.type)) + { + uint16_t tmplen = GETUINT16(priv->ctrl.len); + if (tmplen > 0) + { + dataout = priv->ep0out; + outlen = tmplen; + } + } + + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, + dataout, outlen); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DISPATCHSTALL), 0); + (void)sam_ep_stall(&priv->eplist[EP0].ep, false); + } + } +} + +/**************************************************************************** + * Name: sam_ep0_setup + ****************************************************************************/ + +static void sam_ep0_setup(struct sam_usbdev_s *priv) +{ + struct sam_ep_s *ep0 = &priv->eplist[EP0]; + struct sam_ep_s *privep; + union wb_u value; + union wb_u index; + union wb_u len; + union wb_u response; + enum sam_ep0setup_e ep0result; + uint32_t regval; + uint8_t epno; + int nbytes = 0; /* Assume zero-length packet */ + int ret; + + /* Terminate any pending requests */ + + sam_req_cancel(ep0, -EPROTO); + + /* Assume NOT stalled; no TX in progress */ + + ep0->stalled = 0; + ep0->epstate = USBHS_EPSTATE_IDLE; + + /* And extract the little-endian 16-bit values to host order */ + + value.w = GETUINT16(priv->ctrl.value); + index.w = GETUINT16(priv->ctrl.index); + len.w = GETUINT16(priv->ctrl.len); + + ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + + /* Dispatch any non-standard requests */ + + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standar requests */ + + sam_ep0_dispatch(priv); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + ep0result = USBHS_EP0SETUP_SUCCESS; + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPGETSTATUS), epno); + if (epno >= SAM_USBHS_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPGETSTATUS), epno); + ep0result = USBHS_EP0SETUP_STALL; + } + else + { + privep = &priv->eplist[epno]; + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ + + if (privep->stalled) + { + /* Endpoint stalled */ + + response.b[LSB] = 1; /* Stalled */ + } + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADDEVGETSTATUS), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSTATUS), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* Let the class implementation handle all recipients (except for the + * endpoint recipient) + */ + + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + else + { + /* Endpoint recipient */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_USBHS_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 0; + + ret = sam_ep_stall(&privep->ep, true); + if (ret < 0) + { + ep0result = USBHS_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADCLEARFEATURE), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETFEATURE), priv->ctrl.type); + if (((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + ullvdbg("test mode: %d\n", index.w); + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* The class driver handles all recipients except recipient=endpoint */ + + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + else + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < SAM_USBHS_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 1; + + ret = sam_ep_stall(&privep->ep, false); + if (ret < 0) + { + ep0result = USBHS_EP0SETUP_STALL; + } + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETFEATURE), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETADDRESS), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + else + { + /* Note that setting of the device address will be deferred. A + * zero-length packet will be sent and the device address will + * be set when the zero-length packet transfer completes. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPSETADDRESS), value.w); + + /* Write this address to the USB Address (USBHS_DEVCTRL.UADD) field + * but do not yet enable (USBHS_DEVCTRL.ADDEN) so the actual address is + * still 0. + * + * USBHS_DEVCTRL.UADD and USBHS_DEVCTRL.ADDEN must not be written all + * at once. + */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval &= ~(USBHS_DEVCTRL_UADD_MASK | USBHS_DEVCTRL_ADDEN); + regval |= USBHS_DEVCTRL_UADD(value.w); + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + ep0result = USBHS_EP0SETUP_ADDRESS; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETSETDESC), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADGETCONFIG), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index.w == 0 && len.w == 0) + { + /* The request seems valid... let the class implementation handle it. + * If the class implementation accespts it new configuration, it will + * call sam_ep_configure() to configure the endpoints. + */ + + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADSETCONFIG), 0); + ep0result = USBHS_EP0SETUP_STALL; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_GETSETIF), priv->ctrl.type); + sam_ep0_dispatch(priv); + ep0result = USBHS_EP0SETUP_DISPATCHED; + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); + ep0result = USBHS_EP0SETUP_STALL; + } + break; + } + + /* Restrict the data length to the length requested in the setup packet */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* At this point, the request has been handled and there are three + * (or four) possible outcomes: + * + * 1a. ep0result == USBHS_EP0SETUP_SUCCESS + * + * The setup request was successfully handled above and a response + * packet must be sent (may be a zero length packet). + * + * 1b. ep0result == USBHS_EP0SETUP_ADDRESS + * + * A special case is the case where epstate=USBHS_EPSTATE_EP0ADDRESS. + * This means that the above processing generated an additional state + * where we need to wait until we complete the status phase before + * applying the new device address. + * + * 2. ep0result == USBHS_EP0SETUP_DISPATCHED; + * + * The request was forwarded to the class implementation. In case, + * EP0 IN data may have already been sent and the EP0 IN response + * has already been queued? Or perhaps the endpoint has already + * been stalled? This is all under the control of the class driver. + * + * NOTE that for the case of non-standard SETUP requested, those + * requests were forwarded to the class driver and we don't even get + * to this logic. + * + * 3. ep0result == USBHS_EP0SETUP_STALL; + * + * An error was detected in either the above logic or by the class + * implementation logic. + */ + + switch (ep0result) + { + case USBHS_EP0SETUP_SUCCESS: + { + /* Send the response (might be a zero-length packet) */ + + sam_ctrlep_write(ep0, response.b, nbytes); + ep0->epstate = USBHS_EPSTATE_EP0STATUSIN; + } + break; + + case USBHS_EP0SETUP_ADDRESS: + { + /* Send the response (might be a zero-length packet) */ + + sam_ctrlep_write(ep0, response.b, nbytes); + ep0->epstate = USBHS_EPSTATE_EP0ADDRESS; + } + break; + + case USBHS_EP0SETUP_STALL: + { + /* Stall EP0 */ + + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPSTALLED), + priv->ctrl.req); + + (void)sam_ep_stall(&priv->eplist[EP0].ep, false); + } + break; + + case USBHS_EP0SETUP_DISPATCHED: + default: + break; + } +} + +/**************************************************************************** + * Name: sam_dma_interrupt + * + * Description: + * Handle the USBHS DMA interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno) +{ + struct sam_ep_s *privep; + struct sam_req_s *privreq; + uintptr_t regaddr; + uint32_t regval; + uint32_t dmastatus; + uint8_t *buf; + int bufcnt; + int xfrsize; + + /* Not all endpoints support DMA */ + + DEBUGASSERT((unsigned)epno < SAM_USBHS_NENDPOINTS && + (SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0); + + /* Get the endpoint structure */ + + privep = &priv->eplist[epno]; + + /* Get the request from the head of the endpoint request queue */ + + privreq = sam_rqpeek(&privep->reqq); + DEBUGASSERT(privreq); + + /* Disable DMA interrupt to avoid receiving 2 (B_EN and TR_EN) */ + + regaddr = SAM_USBHS_DEVDMACTRL(epno); + regval = sam_getreg(regaddr); + regval &= ~(USBHS_DEVDMACTRL_ENDTREN | USBHS_DEVDMACTRL_ENDBEN); + sam_putreg(regval, regaddr); + + /* Get the result of the DMA operation */ + + dmastatus = sam_getreg(SAM_USBHS_DEVDMASTA(epno)); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPDMAINT), dmastatus); + + /* Disable DMA interrupt to avoid receiving 2 (B_EN and TR_EN) */ + + regaddr = SAM_USBHS_DEVDMACTRL(epno); + regval = sam_getreg(regaddr); + regval &= ~(USBHS_DEVDMACTRL_ENDTREN | USBHS_DEVDMACTRL_ENDBEN); + sam_putreg(regval, regaddr); + + /* Check for end of the buffer. Set by hardware when the BUFF_COUNT + * downcount reaches zero. This could be either an IN or OUT transfer. + */ + + if ((dmastatus & USBHS_DEVDMASTA_ENDBUFFST) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOB), (uint16_t)dmastatus); + + /* BUFF_COUNT holds the number of untransmitted bytes. BUFF_COUNT is + * equal to zero in case of good transfer. BUFF_COUNT was set to + * the 'inflight' count when the DMA started and the BUFF_COUNT has + * now decremented to zero + */ + + /* This is just debug logic that only does any if USB debug or tracing + * are enabled. This just verifies that BUFF_COUNT is zero. + */ + + bufcnt = (dmastatus & USBHS_DEVDMASTA_BUFCNT_MASK) + >> USBHS_DEVDMASTA_BUFCNT_SHIFT; + + if (bufcnt != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACERR_REMAINING), bufcnt); + } + + /* Were we sending? Or receiving? */ + + if (privep->epstate == USBHS_EPSTATE_SENDING) + { + uint32_t nbusybk; + uint32_t byct; + + /* This is an IN endpoint. Continuing processing the write + * request. + */ + + DEBUGASSERT(USB_ISEPIN(privep->ep.eplog)); + + /* Assume that will wait for the NBUSYBKS interrupt. Enable it + * now. We do this PRIOR to sampling the BYCT and BUSBK + * fields to avoid the race condition that would occur if + * the interrupt were enabled afterward. + */ + + sam_putreg(USBHS_DEVEPTINT_NBUSYBKI, SAM_USBHS_DEVEPTIER(epno)); + + /* Have all of the bytes in the FIFO been transmitted to the + * host? + * + * BYCT == 0 Means that all of the data has been transferred + * out of the FIFO. + * Warning: This field may be updated one clock cycle + * after the RWALL bit changes, so the user should not + * poll this field as an interrupt bit. + * NBUSYBK == 0 Indicates that all banks that have been sent to + * the host. + */ + + regval = sam_getreg(SAM_USBHS_DEVEPTISR(epno)); + byct = (regval & USBHS_DEVEPTISR_BYCT_MASK) >> + USBHS_DEVEPTISR_BYCT_SHIFT; + nbusybk = (regval & USBHS_DEVEPTISR_NBUSYBK_MASK) >> + USBHS_DEVEPTISR_NBUSYBK_SHIFT; + + if (byct > 0 || nbusybk > 0) + { + /* Not all of the data has been sent to the host. A NBUSYBKE + * interrupt will be generated later. It has already been enabled. + * Now wait for the transfer to complete. + */ + + privep->epstate = USBHS_EPSTATE_NBUSYBK; + } + else + { + /* All bytes have been sent to the host. We must call + * sam_req_write() now in the IDLE state with the number of + * bytes transferred in 'inflight'. There must not be a + * pending TXIN interrupt when sam_req_write() is called. + */ + + sam_putreg(USBHS_DEVEPTINT_NBUSYBKI, SAM_USBHS_DEVEPTIDR(epno)); + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + } + else if (privep->epstate == USBHS_EPSTATE_RECEIVING) + { + /* privreg->inflight holds the total transfer size */ + + xfrsize = privreq->inflight; + privreq->inflight = 0; + + /* This is an OUT endpoint. Invalidate the data cache for + * region that just completed DMA. This will force the + * buffer data to be reloaded from RAM when it is accessed. + * + * REVISIT: If the buffer is not aligned to the cacheline + * size the cached data might be lost at the boundaries. + */ + + DEBUGASSERT(USB_ISEPOUT(privep->ep.eplog)); + buf = &privreq->req.buf[privreq->req.xfrd]; + arch_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize); + + /* Complete this transfer, return the request to the class + * implementation, and try to start the next, queue read request. + * We must call sam_req_read in the IDLE state, 'inflight' is + * ignored (should be zero) and the transfer size is passed as + * an argument to sam_req_read(). + */ + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_read(priv, privep, xfrsize); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEOBSTATE), bufcnt); + } + } + + /* Check for end of channel transfer. END_TR_ST is set by hardware when + * the last packet transfer is complete iff END_TR_EN is set in the + * DMACONTROL register. The request is complete. + * + * "Used for OUT transfers only. + * + * "0 = USB end of transfer is ignored. + * "1 = USBHS device can put an end to the current buffer transfer. + * + * "When set, a BULK or INTERRUPT short packet or the last packet of + * an ISOCHRONOUS (micro) frame (DATAX) will close the current buffer + * and the USBHS_DMASTATUSx register END_TR_ST flag will be raised." + */ + + else if ((dmastatus & USBHS_DEVDMASTA_ENDTRST) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOC), (uint16_t)dmastatus); + DEBUGASSERT(privep->epstate == USBHS_EPSTATE_RECEIVING && + USB_ISEPOUT(privep->ep.eplog)); + + /* Get the number of bytes transferred from the DMA status. + * + * BUFF_COUNT holds the number of untransmitted bytes. In this case, + * BUFF_COUNT should not be zero. BUFF_COUNT was set to the + * 'inflight' count when the DMA started so the difference will + * give us the actual size of the transfer. + */ + + bufcnt = ((dmastatus & USBHS_DEVDMASTA_BUFCNT_MASK) + >> USBHS_DEVDMASTA_BUFCNT_SHIFT); + xfrsize = privreq->inflight - bufcnt; + privreq->inflight = 0; + + /* Invalidate the data cache for region that just completed DMA. + * This will force the buffer data to be reloaded from RAM. + * + * REVISIT: If the buffer is not aligned to the cacheline size the + * cached data might be lost at the boundaries. + */ + + buf = &privreq->req.buf[privreq->req.xfrd]; + arch_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize); + + /* Complete this transfer, return the request to the class + * implementation, and try to start the next, queue read request. + */ + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_read(priv, privep, xfrsize); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DMAERR), (uint16_t)dmastatus); + + /* Return the request buffer to the class implementation with the I/O + * error indication. + */ + + sam_req_complete(privep, -EIO); + } +} +#endif + +/**************************************************************************** + * Name: sam_ep_interrupt + * + * Description: + * Handle the USBHS endpoint interrupt + * + ****************************************************************************/ + +static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno) +{ + struct sam_ep_s *privep; + uint32_t eptisr; + uint32_t eptype; + uint32_t regval; + uint16_t pktsize; + + DEBUGASSERT((unsigned)epno < SAM_USBHS_NENDPOINTS); + + /* Get the endpoint structure */ + + privep = &priv->eplist[epno]; + + /* Get the endpoint status */ + + eptisr = sam_getreg(SAM_USBHS_DEVEPTISR(epno)); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EPINT), eptisr); + + /* Get the endpoint type */ + + regval = sam_getreg(SAM_USBHS_DEVEPTCFG(epno)); + eptype = regval & USBHS_DEVEPTCFG_EPTYPE_MASK; + +#ifdef CONFIG_USBDEV_DMA + /* Check for IN DMA packet sent and NBUSYBKS transitioning to zero. This + * is the USBHS_DEVEPTINT_NBUSYBKI interrupt. There is no indication of + * the pending USBHS_DEVEPTINT_NBUSYBKI in the status register. We depend + * on (a) NBUSYBKS == 0, and (c) state == USBHS_EPSTATE_NBUSYBK. + */ + + if ((eptisr & USBHS_DEVEPTISR_NBUSYBK_MASK) == 0 && + privep->epstate == USBHS_EPSTATE_NBUSYBK) + { + /* Clear the pending NBUSYBKS (and TXIN) interrupts */ + + sam_putreg(USBHS_DEVEPTINT_TXINI | USBHS_DEVEPTINT_NBUSYBKI, + SAM_USBHS_DEVEPTICR(epno)); + + /* Disable further NBUSYBKS interrupts */ + + sam_putreg(USBHS_DEVEPTINT_NBUSYBKI, SAM_USBHS_DEVEPTIDR(epno)); + + /* Continue/resume processing the write requests. */ + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + else +#endif + + /* IN packet sent */ + + if ((eptisr & USBHS_DEVEPTINT_TXINI) != 0 && + (sam_getreg(SAM_USBHS_DEVEPTIMR(epno)) & USBHS_DEVEPTINT_TXINI) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_TXINI), (uint16_t)eptisr); + + /* Sending state. This is the completion of a "normal" write request + * transfer. In this case, we need to resume request processing in + * order to send the next outgoing packet. + */ + + if (privep->epstate == USBHS_EPSTATE_SENDING || + privep->epstate == USBHS_EPSTATE_EP0STATUSIN) + { + /* A control endpoint clears the TXIN bit after new data is written + * to the fifo inside the function "sam_ctrlep_write" + * (sam_req_write -> sam_req_wrsetup -> sam_ctrlep_write). + * All other Endpoints needs to clear the bit here. + * + * REVISIT: normally all other endpoints also have to reset the bit + * at a later point. + * + * Continue/resume processing the write requests. + */ + + if (eptype != USBHS_DEVEPTCFG_EPTYPE_CTRL) + { + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); + } + + privep->epstate = USBHS_EPSTATE_IDLE; + (void)sam_req_write(priv, privep); + } + + /* Setting of the device address is a special case. The address was + * obtained when a preceding SETADDRESS SETUP command was processed. + * But the address is not set until the final SETUP status phase + * completes. This interrupt indicates the completion of that status + * phase and now we set the address. + */ + + else if (privep->epstate == USBHS_EPSTATE_EP0ADDRESS) + { + DEBUGASSERT(epno == EP0); + + /* Enable the address previously set in the SETUP processing. + * USBHS_DEVCTRL.UADD and USBHS_DEVCTRL.ADDEN must not be written + * all at once. + */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval |= USBHS_DEVCTRL_ADDEN; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ADDRESSED), + (regval & USBHS_DEVCTRL_UADD_MASK) << USBHS_DEVCTRL_UADD_SHIFT); + + /* Go to the addressed state. EP0 is now IDLE. */ + + priv->devstate = USBHS_DEVSTATE_ADDRESSED; + privep->epstate = USBHS_EPSTATE_IDLE; + + /* Acknowledge then disable the further TXIN interrupts on EP0. */ + + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIDR(epno)); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_TXINERR), privep->epstate); + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTICR(epno)); + sam_putreg(USBHS_DEVEPTINT_TXINI, SAM_USBHS_DEVEPTIDR(epno)); + } + } + + /* OUT packet received */ + + if ((eptisr & USBHS_DEVEPTINT_RXOUTI) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXRDY), (uint16_t)eptisr); + + /* Are we receiving data for a read request? */ + + if (privep->epstate == USBHS_EPSTATE_RECEIVING) + { + /* Yes, get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((eptisr & USBHS_DEVEPTISR_BYCT_MASK) >> USBHS_DEVEPTISR_BYCT_SHIFT); + + /* And continue processing the read request, clearing RXOUT in + * order to receive more data. + */ + + privep->epstate = USBHS_EPSTATE_IDLE; + sam_req_read(priv, privep, pktsize); + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTICR(epno)); + } + + /* Did we just receive the data associated with an OUT SETUP command? */ + + else if (privep->epstate == USBHS_EPSTATE_EP0DATAOUT) + { + uint16_t len; + + /* Yes.. back to the IDLE state */ + + privep->epstate = USBHS_EPSTATE_IDLE; + + /* Get the size of the packet that we just received */ + + pktsize = (uint16_t) + ((eptisr & USBHS_DEVEPTISR_BYCT_MASK) >> USBHS_DEVEPTISR_BYCT_SHIFT); + + /* Get the size that we expected to receive */ + + len = GETUINT16(priv->ctrl.len); + if (len == pktsize) + { + /* Copy the OUT data from the EP0 FIFO into a special EP0 buffer + * and clear RXOUT in order to receive more data. + */ + + sam_ep0_read(priv->ep0out, len); + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTICR(epno)); + + /* And handle the EP0 SETUP now. */ + + sam_ep0_setup(priv); + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EP0SETUPOUTSIZE), pktsize); + + /* STALL and discard received data. */ + + (void)sam_ep_stall(&privep->ep, false); + sam_putreg(USBHS_DEVEPTINT_STALLRQI, SAM_USBHS_DEVEPTICR(epno)); + } + } + else + { + /* Check if ACK received on a Control EP */ + + if (eptype == USBHS_DEVEPTCFG_EPTYPE_CTRL && + (eptisr & USBHS_DEVEPTISR_BYCT_MASK) == 0) + { + } + + /* Data has been STALLed */ + + else if ((eptisr & USBHS_DEVEPTINT_STALLEDI) != 0) + { + } + + /* NAK the data */ + + else + { + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + } + + /* Acknowledge the interrupt. */ + + sam_putreg(USBHS_DEVEPTINT_RXOUTI, SAM_USBHS_DEVEPTICR(epno)); + } + } + + /* STALL sent */ + + if ((eptisr & USBHS_DEVEPTINT_STALLEDI) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_STALLSNT), (uint16_t)eptisr); + + /* Acknowledge */ + + sam_putreg(USBHS_DEVEPTINT_STALLEDI, SAM_USBHS_DEVEPTICR(epno)); + + /* ISO error */ + + if (eptype == USBHS_DEVEPTCFG_EPTYPE_ISO) + { + privep->epstate = USBHS_EPSTATE_IDLE; + sam_req_complete(privep, -EIO); + } + + /* If EP is not halted, clear STALL */ + + else if (privep->epstate != USBHS_EPSTATE_STALLED) + { + sam_putreg(USBHS_DEVEPTINT_STALLEDI, SAM_USBHS_DEVEPTIDR(epno)); + } + } + + /* SETUP packet received */ + + if ((eptisr & USBHS_DEVEPTINT_RXSTPI) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_RXSETUP), (uint16_t)eptisr); + + /* If a request transfer was pending, complete it. Handle the case + * where during the status phase of a control write transfer, the host + * receives the device ZLP and ack it, but the ack is not received by the + * device + */ + + if (privep->epstate == USBHS_EPSTATE_RECEIVING || + privep->epstate == USBHS_EPSTATE_SENDING) + { + sam_req_complete(privep, -EPROTO); + } + + /* ISO Err Flow */ + + if (eptype == USBHS_DEVEPTCFG_EPTYPE_ISO) + { + /* Acknowledge setup packet */ + + sam_putreg(USBHS_DEVEPTINT_RXSTPI, SAM_USBHS_DEVEPTICR(epno)); + } + else + { + uint16_t len; + + /* Copy setup data from the EP0 FIFO into the driver structure. */ + + sam_ep0_read((uint8_t *)&priv->ctrl, USB_SIZEOF_CTRLREQ); + + /* Acknowledge setup packet */ + + sam_putreg(USBHS_DEVEPTINT_RXSTPI, SAM_USBHS_DEVEPTICR(epno)); + + /* Check for a SETUP IN transaction */ + + len = GETUINT16(priv->ctrl.len); + if (USB_REQ_ISOUT(priv->ctrl.type) && len > 0) + { + /* Yes.. then we have to wait for the OUT data phase to + * complete before processing the SETUP command. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPOUT), priv->ctrl.req); + privep->epstate = USBHS_EPSTATE_EP0DATAOUT; + } + else + { + /* This is an SETUP IN command (or a SETUP IN with no data). + * Handle the EP0 SETUP now. + */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPIN), len); + privep->epstate = USBHS_EPSTATE_IDLE; + sam_ep0_setup(priv); + } + } + } +} + +/**************************************************************************** + * Name: sam_usbhs_interrupt + * + * Description: + * Handle the USBHS interrupt + * + ****************************************************************************/ + +static int sam_usbhs_interrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USBHS controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_usbhs; + uint32_t devisr; + uint32_t pending; + uint32_t regval; + int i; + + /* Get the set of pending interrupts */ + + devisr = sam_getreg(SAM_USBHS_DEVISR); + usbtrace(TRACE_INTENTRY(SAM_TRACEINTID_INTERRUPT), devisr); + + regval = sam_getreg(SAM_USBHS_DEVIMR); + pending = devisr & regval; + + /* Handle all pending USBHS interrupts (and new interrupts that become + * pending) + */ + + while (pending) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_PENDING), (uint16_t)pending); + + /* Suspend, treated last */ + + if (pending == USBHS_DEVINT_SUSPD) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_INTSUSPD), (uint16_t)pending); + + /* Un-freeze the clock */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Disable suspend interrupts */ + + sam_putreg(USBHS_DEVINT_SUSPD, SAM_USBHS_DEVIDR); + + /* Enable wakeup interrupts */ + + sam_putreg(USBHS_DEVINT_WAKEUP | USBHS_DEVINT_EORSM, SAM_USBHS_DEVIER); + + /* Acknowledge the suspend interrupt */ + + sam_putreg(USBHS_DEVINT_SUSPD | USBHS_DEVINT_WAKEUP, SAM_USBHS_DEVICR); + + /* Inform board logic that USB is suspended */ + + sam_suspend(priv); + + /* Re-freeze the clock */ + + regval |= USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + } + + /* SOF interrupt */ + + else if ((pending & USBHS_DEVINT_SOF) != 0) + { + /* Acknowledge interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_INTSOF), (uint16_t)pending); + sam_putreg(USBHS_DEVINT_SOF, SAM_USBHS_DEVICR); + } + + /* MSOF interrupt */ + + else if ((pending & USBHS_DEVINT_MSOF) != 0) + { + /* Acknowledge interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_INTMSOF), (uint16_t)pending); + sam_putreg(USBHS_DEVINT_MSOF, SAM_USBHS_DEVICR); + } + + /* Resume */ + + else if ((pending & USBHS_DEVINT_WAKEUP) != 0 || + (pending & USBHS_DEVINT_EORSM) != 0) + { + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_WAKEUP), (uint16_t)pending); + sam_resume(priv); + + /* Un-freeze the clock */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Acknowledge interrupt */ + + sam_putreg(USBHS_DEVINT_WAKEUP | USBHS_DEVINT_EORSM | USBHS_DEVINT_SUSPD, + SAM_USBHS_DEVICR); + + /* Disable wakeup interrupts */ + + sam_putreg(USBHS_DEVINT_WAKEUP, SAM_USBHS_DEVIDR); + + /* Enable suspend interrupts and clear */ + + sam_putreg(USBHS_DEVINT_EORSM | USBHS_DEVINT_SUSPD, SAM_USBHS_DEVIER); + } + + /* End of Reset. + * + * The USB bus reset is managed by hardware. It is initiated by a connected + * host. When a USB reset is detected on the USB line, the following + * operations are performed by the controller: + * + * - All endpoints are disabled, except the default control endpoint. + * - The default control endpoint is reset + * - The data toggle sequence of the default control endpoint is cleared. + * - At the end of the reset process, the End of Reset (USBHS_DEVISR.EORST) + * bit is set. + * - During a reset, the USBHS automatically switches to High-speed mode + * if the host is High-speed-capable (the reset is called High-speed + * reset). The user should observe the USBHS_SR.SPEED field to know + * the speed running at the end of the reset (USBHS_DEVISR.EORST = 1). + */ + + else if ((pending & USBHS_DEVINT_EORST) != 0) + { + /* Sample the USBHS SR register at the time of the EORST event. */ + + regval = sam_getreg(SAM_USBHS_SR); + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_ENDRESET), regval); + + /* Acknowledge the interrupt, clear pending wakeup and suspend + * status as we.. + */ + + sam_putreg(USBHS_DEVINT_WAKEUP | USBHS_DEVINT_SUSPD | + USBHS_DEVINT_EORST, + SAM_USBHS_DEVICR); + + /* Enable suspend interrupts */ + + sam_putreg(USBHS_DEVINT_SUSPD, SAM_USBHS_DEVIER); + + /* Handle the reset (will select full speed mode) */ + + sam_reset(priv); + + /* Get the correct speed mode reported by the hardware */ + + switch (regval & USBHS_SR_SPEED_MASK) + { + default: + case USBHS_SR_SPEED_FULL: + priv->usbdev.speed = USB_SPEED_FULL; + break; + + case USBHS_SR_SPEED_HIGH: + priv->usbdev.speed = USB_SPEED_HIGH; + break; + + case USBHS_SR_SPEED_LOW: + priv->usbdev.speed = USB_SPEED_LOW; + break; + } + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_SPEED), + priv->usbdev.speed); + } + + /* Upstream resume */ + + else if ((pending & USBHS_DEVINT_UPRSM) != 0) + { + /* Acknowledge interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_UPSTRRES), (uint16_t)pending); + sam_putreg(USBHS_DEVINT_UPRSM, SAM_USBHS_DEVICR); + } + +#ifdef CONFIG_USBDEV_DMA + /* Endpoint DMA interrupts */ + + else if ((pending & USBHS_DEVINT_DMA_MASK) != 0) + { + /* Each endpoint DMA ineterrupt is cleared when the + * USBHS_DEVDMASTATUSx interrupt source is cleared. + */ + + /* Process each pending endpoint DMA interrupt */ + + for (i = 1; i <= SAM_USBHS_NDMACHANNELS; i++) + { + /* Is there a DMA interrupt pending for endpoint i? */ + + if ((pending & USBHS_DEVINT_DMA(i)) != 0) + { + /* Yes.. process the endpoint i DMA interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMA), (uint16_t)i); + sam_dma_interrupt(priv, i); + } + } + } +#endif + + /* Endpoint Interrupts */ + + else if ((pending & USBHS_DEVINT_PEP_MASK) != 0) + { + /* Each endpoint interrupt is cleared when the interrupt source + * is serviced. + */ + + /* Process each pending endpoint interrupt */ + + for (i = 0; i < SAM_USBHS_NENDPOINTS; i++) + { + /* Is there an interrupt pending for endpoint i? */ + + if ((pending & USBHS_DEVINT_PEP(i)) != 0) + { + /* Yes.. process the endpoint i interrupt */ + + usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP), (uint16_t)i); + sam_ep_interrupt(priv, i); + } + } + } + + /* Re-sample the set of pending interrupts */ + + devisr = sam_getreg(SAM_USBHS_DEVISR); + regval = sam_getreg(SAM_USBHS_DEVIMR); + pending = devisr & regval; + } + + usbtrace(TRACE_INTEXIT(SAM_TRACEINTID_INTERRUPT), devisr); + MEMORY_SYNC(); + return OK; +} + +/**************************************************************************** + * Suspend/Resume Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: sam_suspend + ****************************************************************************/ + +static void sam_suspend(struct sam_usbdev_s *priv) +{ + /* Don't do anything if the device is already suspended */ + + if (priv->devstate != USBHS_DEVSTATE_SUSPENDED) + { + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* Switch to the Suspended state */ + + priv->prevstate = priv->devstate; + priv->devstate = USBHS_DEVSTATE_SUSPENDED; + + /* Disable clocking to the USBHS peripheral + * + * NOTE: The Atmel sample code disables USB clocking here (via the PMC + * CKGR_UCKR). However, we cannot really do that here because that + * clocking is also needed by the UHPHS host. + */ + + sam_usbhs_disableclk(); + + /* Let the board-specific logic know that we have entered the + * suspend state. This may trigger additional reduced power + * consumption measures. + */ + + sam_usbsuspend((struct usbdev_s *)priv, false); + } +} + +/**************************************************************************** + * Name: sam_resume + ****************************************************************************/ + +static void sam_resume(struct sam_usbdev_s *priv) +{ + uint32_t regval; + + /* This function is called when either (1) a WKUP interrupt is received from + * the host PC, or (2) the class device implementation calls the wakeup() + * method. + */ + + /* Don't do anything if the device was not suspended */ + + if (priv->devstate == USBHS_DEVSTATE_SUSPENDED) + { + /* Un-freeze clocking */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Revert to the previous state */ + + priv->devstate = priv->prevstate; + + /* Restore full power -- whatever that means forSC this particular board */ + /* Restore full power -- whatever that means for this particular board */ + + sam_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + } +} + +/**************************************************************************** + * Endpoint Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_ep_reset + * + * Description + * Reset and disable a set of endpoints. + * + ****************************************************************************/ + +static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno) +{ + struct sam_ep_s *privep = &priv->eplist[epno]; + uint32_t regval; + + /* Disable endpoint interrupt */ + + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + + /* Cancel any queued requests. Since they are cancelled with status + * -ESHUTDOWN, then will not be requeued until the configuration is reset. + * NOTE: This should not be necessary... the CLASS_DISCONNECT above + * should result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Put the endpoint in reset */ + + regval = sam_getreg(SAM_USBHS_DEVEPT); + regval |= USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + /* Reset endpoint status */ + + privep->epstate = USBHS_EPSTATE_DISABLED; + privep->stalled = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + privep->bank = 0; + + /* Take the endpoint out of reset */ + + regval &= ~USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); +} + +/**************************************************************************** + * Name: sam_epset_reset + * + * Description + * Reset and disable a set of endpoints. + * + ****************************************************************************/ + +static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset) +{ + uint32_t bit; + int epno; + + /* Reset each endpoint in the set */ + + for (epno = 0, bit = 1, epset &= SAM_EPSET_ALL; + epno < SAM_USBHS_NENDPOINTS && epset != 0; + epno++, bit <<= 1) + { + /* Is this endpoint in the set? */ + + if ((epset & bit) != 0) + { + /* Yes.. reset it */ + + sam_ep_reset(priv, epno); + epset &= ~bit; + } + } +} + +/**************************************************************************** + * Name: sam_ep_reserve + * + * Description: + * Find and un-reserved endpoint number and reserve it for the caller. + * + ****************************************************************************/ + +static inline struct sam_ep_s * +sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset) +{ + struct sam_ep_s *privep = NULL; + irqstate_t flags; + int epndx = 0; + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints + * (skipping EP0) + */ + + for (epndx = 1; epndx < SAM_USBHS_NENDPOINTS; epndx++) + { + uint8_t bit = SAM_EP_BIT(epndx); + if ((epset & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail &= ~bit; + + /* And return the pointer to the standard endpoint structure */ + + privep = &priv->eplist[epndx]; + break; + } + } + } + + leave_critical_section(flags); + return privep; +} + +/**************************************************************************** + * Name: sam_ep_unreserve + * + * Description: + * The endpoint is no long in-used. It will be un-reserved and can be + * re-used if needed. + * + ****************************************************************************/ + +static inline void +sam_ep_unreserve(struct sam_usbdev_s *priv, struct sam_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= SAM_EP_BIT(USB_EPNO(privep->ep.eplog)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_ep_reserved + * + * Description: + * Check if the endpoint has already been allocated. + * + ****************************************************************************/ + +static inline bool +sam_ep_reserved(struct sam_usbdev_s *priv, int epno) +{ + return ((priv->epavail & SAM_EP_BIT(epno)) == 0); +} + +/**************************************************************************** + * Name: sam_ep_configure_internal + * + * Description: + * This is the internal implementation of the endpoint configuration logic + * and implements the endpoint configuration method of the usbdev_ep_s + * interface. As an internal interface, it will be used to configure + * endpoint 0 which is not available to the class implementation. + * + ****************************************************************************/ + +static int sam_ep_configure_internal(struct sam_ep_s *privep, + const struct usb_epdesc_s *desc) +{ + struct sam_usbdev_s *priv; + uintptr_t regaddr; + uint32_t regval; + uint16_t maxpacket; + uint8_t epno; + uint8_t eptype; + uint8_t nbtrans; + bool dirin; + + uvdbg("len: %02x type: %02x addr: %02x attr: %02x " + "maxpacketsize: %02x %02x interval: %02x\n", + desc->len, desc->type, desc->addr, desc->attr, + desc->mxpacketsize[0], desc->mxpacketsize[1], + desc->interval); + + /* Decode the endpoint descriptor */ + + epno = USB_EPNO(desc->addr); + dirin = (desc->addr & USB_DIR_MASK) == USB_REQ_DIR_IN; + eptype = (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) >> USB_EP_ATTR_XFERTYPE_SHIFT; + maxpacket = GETUINT16(desc->mxpacketsize); + nbtrans = 1; + + /* Initialize the endpoint structure */ + + priv = privep->dev; + privep->ep.eplog = desc->addr; /* Includes direction */ + privep->epstate = USBHS_EPSTATE_IDLE; + privep->bank = SAM_USBHS_NBANKS(epno); + + /* Special case maxpacket handling for high-speed endpoints */ + + if (priv->usbdev.speed == USB_SPEED_HIGH) + { + /* HS Interval, 125us */ + /* MPS: Bits 12:11 specify NB_TRANS, as USB 2.0 Spec. */ + + nbtrans = ((maxpacket >> 11) & 3); + if (nbtrans == 3) + { + nbtrans = 1; + } + else + { + nbtrans++; + } + + /* nbtrans = 0: Reserved to endpoint that does not have the high- + * bandwidth isochronous capability. + * nbtrans = 1: Default value: one transaction per microframe. + * nbtrans = 2: Two transactions per microframe. This endpoint + * should be configured as double-bank. + * nbtrans = 3 Three transactions per microframe. This endpoint + * should be configured as triple-bank + */ + + if (privep->bank < nbtrans) + { + nbtrans = privep->bank; + } + + /* Mask, bit 10..0 is the max packet size */ + + maxpacket &= 0x7ff; + } + + privep->ep.maxpacket = maxpacket; + + /* Initialize the endpoint hardware */ + /* Disable the endpoint */ + + regval = sam_getreg(SAM_USBHS_DEVEPT); + regval &= ~USBHS_DEVEPT_EPEN(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + sam_putreg(USBHS_DEVEPTIDR_ALLINTS, SAM_USBHS_DEVEPTIDR(epno)); + + /* Clear toggle and stall indications */ + + sam_putreg(USBHS_DEVEPTISR_DTSEQ_MASK | USBHS_DEVEPTINT_STALLEDI, + SAM_USBHS_DEVEPTICR(epno)); + + /* Reset the endpoint */ + + regval = sam_getreg(SAM_USBHS_DEVEPT); + regval |= USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + regval &= ~USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + /* If this is EP0, disable interrupts now */ + + if (eptype == USB_EP_ATTR_XFER_CONTROL) + { + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + } + + /* Enable the endpoint */ + + regval = sam_getreg(SAM_USBHS_DEVEPT); + regval |= USBHS_DEVEPT_EPEN(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + /* Configure the endpoint */ + + regval = USBHS_DEVEPTCFG_ALLOC | + USBHS_DEVEPTCFG_EPDIR(dirin) | + USBHS_DEVEPTCFG_EPTYPE(eptype) | + USBHS_DEVEPTCFG_EPBK(privep->bank) | + USBHS_DEVEPTCFG_NBTRANS(nbtrans); + + if (maxpacket <= 8) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_8; + } + else if (maxpacket <= 16) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_16; + } + else if (maxpacket <= 32) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_32; + } + else if (maxpacket <= 64) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_64; + } + else if (maxpacket <= 128) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_128; + } + else if (maxpacket <= 256) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_256; + } + else if (maxpacket <= 512) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_512; + } + else if (maxpacket <= 1024) + { + regval |= USBHS_DEVEPTCFG_EPSIZE_1024; + } + else + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPTYPE), eptype); + DEBUGPANIC(); + regval |= USBHS_DEVEPTCFG_EPSIZE_8; + } + + regaddr = SAM_USBHS_DEVEPTCFG(epno); + sam_putreg(regval, regaddr); + + /* Verify that the CFGOK flag is set. This flag is set if the + * endpoint size and the number of banks are correct compared to + * the FIFO maximum capacity and the maximum number of allowed banks. + */ + + regaddr = SAM_USBHS_DEVEPTISR(epno); + if ((sam_getreg(regaddr) & USBHS_DEVEPTISR_CFGOK) == 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_NCFGOK), epno); + return -EINVAL; + } + + /* Enable the endpoint. The way that the endpoint is enabled depends of + * if the endpoint supports DMA transfers or not. + */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + /* Select AUTO_VALID so that the hardware will manage FIFCON. */ + + regaddr = SAM_USBHS_DEVEPTCFG(epno); + regval |= USBHS_DEVEPTCFG_AUTOSW; + sam_putreg(regval, SAM_USBHS_DEVEPTCFG(epno)); + } + else + { + /* No DMA... Software will manage FIFOCON. */ + + regval = USBHS_DEVEPTINT_KILLBKI | USBHS_DEVEPTINT_RXSTPI; + sam_putreg(regval, SAM_USBHS_DEVEPTIER(epno)); + } + + /* If this is EP0, enable interrupts now */ + + if (eptype == USB_EP_ATTR_XFER_CONTROL) + { + /* Enable the endpoint 0 RX interrupts */ + + regaddr = SAM_USBHS_DEVEPTIER(epno); + regval = USBHS_DEVEPTINT_RXOUTI | USBHS_DEVEPTINT_RXSTPI; + sam_putreg(regval, regaddr); + + /* Enable endpoint 0 general interrupts */ + + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIER); + } +#ifdef CONFIG_USBDEV_DMA + else + { + /* Enable automatic bank switching */ + + regaddr = SAM_USBHS_DEVEPTIER(epno); + regval = sam_getreg(regaddr); + regval |= USBHS_DEVEPTCFG_AUTOSW; + sam_putreg(regval, regaddr); + } +#endif + + sam_dumpep(priv, epno); + return OK; +} + +/**************************************************************************** + * Name: sam_ep0_configure + * + * Description: + * Configure EP0 for normal operation. + * + ****************************************************************************/ + +static inline int sam_ep0_configure(struct sam_usbdev_s *priv) +{ + return sam_ep_configure_internal(&priv->eplist[EP0], &g_ep0desc); +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_ep_configure + * + * Description: + * This is the endpoint configuration method of the usbdev_ep_s interface. + * + ****************************************************************************/ + +static int sam_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + int ret; + + /* Verify parameters. Endpoint 0 is not available at this interface */ + +#if defined(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE) + uint8_t epno = USB_EPNO(desc->addr); + usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno); + + DEBUGASSERT(ep && desc && epno > 0 && epno < SAM_USBHS_NENDPOINTS); + DEBUGASSERT(epno == USB_EPNO(ep->eplog)); +#endif + + /* This logic is implemented in sam_ep_configure_internal */ + + ret = sam_ep_configure_internal(privep, desc); + if (ret == OK && last) + { + /* If this was the last endpoint, then the class driver is fully + * configured. + */ + + priv = privep->dev; + priv->devstate = USBHS_DEVSTATE_CONFIGURED; + } + + return ret; +} + +/**************************************************************************** + * Name: sam_ep_disable + * + * Description: + * This is the disable() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_disable(struct usbdev_ep_s *ep) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + + DEBUGASSERT(ep != NULL); + + epno = USB_EPNO(ep->eplog); + usbtrace(TRACE_EPDISABLE, epno); + + /* Reset the endpoint and cancel any ongoing activity */ + + flags = enter_critical_section(); + priv = privep->dev; + sam_ep_reset(priv, epno); + + /* Revert to the addressed-but-not-configured state */ + + priv->devstate = USBHS_DEVSTATE_ADDRESSED; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_allocreq + * + * Description: + * This is the allocreq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static struct usbdev_req_s *sam_ep_allocreq(struct usbdev_ep_s *ep) +{ + struct sam_req_s *privreq; + + DEBUGASSERT(ep != NULL); + usbtrace(TRACE_EPALLOCREQ, USB_EPNO(ep->eplog)); + + privreq = (struct sam_req_s *)kmm_malloc(sizeof(struct sam_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct sam_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: sam_ep_freereq + * + * Description: + * This is the freereq() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static void sam_ep_freereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + + DEBUGASSERT(ep != NULL && req != NULL); + usbtrace(TRACE_EPFREEREQ, USB_EPNO(ep->eplog)); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: sam_ep_allocbuffer + * + * Description: + * This is the allocbuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *sam_ep_allocbuffer(struct usbdev_ep_s *ep, uint16_t nbytes) +{ + /* Allocate properly aligned memory */ + + return kmm_memalign(USBHS_ALIGN, USBHS_ALIGN_UP(nbytes)); +} +#endif + +/**************************************************************************** + * Name: sam_ep_freebuffer + * + * Description: + * This is the freebuffer() method of the USB device endpoint structure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void sam_ep_freebuffer(struct usbdev_ep_s *ep, void *buf) +{ + /* There is no special buffer requirement to free aligned DMA buffers */ + + kumm_free(buf); +} +#endif + +/**************************************************************************** + * Name: sam_ep_submit + * + * Description: + * This is the submit() method of the USB device endpoint structure. + * + ****************************************************************************/ + +static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_req_s *privreq = (struct sam_req_s *)req; + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + struct sam_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + int ret = OK; + + DEBUGASSERT(ep != NULL && req != NULL && req->callback != NULL && req->buf != NULL); + usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); + priv = privep->dev; + DEBUGASSERT(priv->driver != NULL); + + /* Handle the request from the class driver */ + + epno = USB_EPNO(ep->eplog); + req->result = -EINPROGRESS; + req->xfrd = 0; + privreq->inflight = 0; + flags = enter_critical_section(); + + /* Handle IN (device-to-host) requests. NOTE: If the class device is + * using the bi-directional EP0, then we assume that they intend the EP0 + * IN functionality (EP0 SETUP OUT data receipt does not use requests). + */ + + if (USB_ISEPIN(ep->eplog) || epno == EP0) + { + /* If the endpoint is stalled, then fail any attempts to write + * through the endpoint. + */ + + if (privep->stalled) + { + sam_req_abort(privep, privreq, -EBUSY); + ulldbg("ERROR: stalled\n"); + ret = -EPERM; + } + else + { + /* Add the new request to the request queue for the IN endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_INREQQUEUED(epno), req->len); + + /* If the IN endpoint is IDLE, then transfer the data now */ + + if (privep->epstate == USBHS_EPSTATE_IDLE) + { + ret = sam_req_write(priv, privep); + } + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + sam_req_enqueue(&privep->reqq, privreq); + usbtrace(TRACE_OUTREQQUEUED(epno), req->len); + + /* If the OUT endpoint IDLE, then setup the read */ + + if (privep->epstate == USBHS_EPSTATE_IDLE) + { + ret = sam_req_read(priv, privep, 0); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: sam_ep_cancel + ****************************************************************************/ + +static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct sam_ep_s *privep = (struct sam_ep_s *)ep; + irqstate_t flags; + + DEBUGASSERT(ep != NULL && req != NULL); + usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); + + flags = enter_critical_section(); + sam_req_cancel(privep, -EAGAIN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: sam_ep_stall + ****************************************************************************/ + +static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume) +{ + struct sam_ep_s *privep; + struct sam_usbdev_s *priv; + uint8_t epno = USB_EPNO(ep->eplog); + uintptr_t regaddr; + uint32_t regval; + irqstate_t flags; + + DEBUGASSERT(ep != NULL); + + /* Check that endpoint is in Idle state */ + + privep = (struct sam_ep_s *)ep; + DEBUGASSERT(/* privep->epstate == USBHS_EPSTATE_IDLE && */ privep->dev); + + priv = (struct sam_usbdev_s *)privep->dev; + epno = USB_EPNO(ep->eplog); + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, USB_EPNO(ep->eplog)); + + /* Handle the resume condition */ + + if (resume) + { + /* Check if the endpoint is halted */ + + if (privep->epstate == USBHS_EPSTATE_STALLED) + { + usbtrace(TRACE_EPRESUME, epno); + privep->stalled = false; + + /* Return endpoint to Idle state */ + + privep->epstate = USBHS_EPSTATE_IDLE; + + /* Clear FORCESTALL request + * REVISIT: Data sheet says to reset toggle to DATA0 only on OUT + * endpoints. + */ + + /* Clear FORCESTALL flag */ + + sam_putreg(USBHS_DEVEPTINT_STALLEDI, SAM_USBHS_DEVEPTIDR(epno)); + + regaddr = SAM_USBHS_DEVEPTCFG(epno); + regval = sam_getreg(regaddr); + regval |= USBHS_DEVEPTCFG_AUTOSW; + sam_putreg(regval, regaddr); + + /* Reset the endpoint */ + + regval = sam_getreg(SAM_USBHS_DEVEPT); + regval |= USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + regval &= ~USBHS_DEVEPT_EPRST(epno); + sam_putreg(regval, SAM_USBHS_DEVEPT); + + /* Resuming any blocked data transfers on the endpoint */ + + if (epno == 0 || USB_ISEPIN(ep->eplog)) + { + /* IN endpoint (or EP0). Restart any queued write requests */ + + (void)sam_req_write(priv, privep); + } + else + { + /* OUT endpoint. Restart any queued read requests. */ + + (void)sam_req_read(priv, privep, 0); + } + } + } + + /* Handle the stall condition */ + + else + { + /* Check that endpoint is enabled and not already in Halt state */ + + if ((privep->epstate != USBHS_EPSTATE_DISABLED) && + (privep->epstate != USBHS_EPSTATE_STALLED)) + { + usbtrace(TRACE_EPSTALL, epno); + + /* If this is an IN endpoint (or endpoint 0), then cancel all + * of the pending write requests. + */ + + if (epno == 0 || USB_ISEPIN(ep->eplog)) + { + sam_req_cancel(privep, -EPERM); + } + + /* Otherwise, it is an OUT endpoint. Complete any read request + * currently in progress (it will get requeued immediately). + */ + + else if (privep->epstate == USBHS_EPSTATE_RECEIVING) + { + sam_req_complete(privep, -EPERM); + } + + /* Put endpoint into stalled state */ + + privep->epstate = USBHS_EPSTATE_STALLED; + privep->stalled = true; + + regaddr = SAM_USBHS_DEVEPTCFG(epno); + regval = sam_getreg(regaddr); + regval &= ~USBHS_DEVEPTCFG_AUTOSW; + sam_putreg(regval, regaddr); + + sam_putreg(USBHS_DEVEPTINT_STALLRQI, SAM_USBHS_DEVEPTIER(epno)); + + /* Disable endpoint/DMA interrupts. They not be re-enabled until + * the stall is cleared and the next transfer is started. It + * would, of course, be a bad idea to do this on EP0 since it is + * a SETUP request that is going to clear the STALL. + */ + + if (epno != 0) + { + regval = sam_getreg(SAM_USBHS_DEVIDR); + regval |= USBHS_DEVINT_PEP(epno); + +#ifdef CONFIG_USBDEV_DMA + if (SAM_USBHS_DMA(epno)) + { + /* Disable the endpoint DMA interrupt */ + + regval |= USBHS_DEVINT_DMA(epno); + } +#endif + sam_putreg(regval, SAM_USBHS_DEVIDR); + } + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: sam_allocep + * + * Description: + * This is the allocep() method of the USB device driver interface + * + ****************************************************************************/ + +static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno, + bool in, uint8_t eptype) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + struct sam_ep_s *privep = NULL; + uint16_t epset = SAM_EPSET_NOTEP0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno); + DEBUGASSERT(dev != NULL); + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epno >= SAM_USBHS_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset = SAM_EP_BIT(epno); + } + + /* Check if the selected endpoint number is available */ + + privep = sam_ep_reserve(priv, epset); + if (!privep) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPRESERVE), (uint16_t)epset); + return NULL; + } + + return &privep->ep; +} + +/**************************************************************************** + * Name: sam_freeep + * + * Description: + * This is the freeep() method of the USB device driver interface + * + ****************************************************************************/ + +static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) +{ + struct sam_usbdev_s *priv; + struct sam_ep_s *privep; + + DEBUGASSERT(dev != NULL && ep != NULL); + + priv = (struct sam_usbdev_s *)dev; + privep = (struct sam_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)USB_EPNO(ep->eplog)); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + sam_ep_unreserve(priv, privep); + } +} + +/**************************************************************************** + * Name: sam_getframe + * + * Description: + * This is the getframe() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + uint16_t frameno; + + DEBUGASSERT(dev != NULL); + + /* Return the last frame number detected by the hardware */ + + regval = sam_getreg(SAM_USBHS_DEVFNUM); + frameno = (regval & USBHS_DEVFNUM_FNUM_MASK) >> USBHS_DEVFNUM_FNUM_SHIFT; + + usbtrace(TRACE_DEVGETFRAME, frameno); + return frameno; +} + +/**************************************************************************** + * Name: sam_wakeup + * + * Description: + * This is the wakeup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_wakeup(struct usbdev_s *dev) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + irqstate_t flags; + uint32_t regval; + + usbtrace(TRACE_DEVWAKEUP, 0); + DEBUGASSERT(dev != NULL); + + /* Resume normal operation */ + + flags = enter_critical_section(); + sam_resume(priv); + + /* Activate a remote wakeup. Setting this bit forces an external interrupt + * on the USBHS controller for Remote Wake UP purposes. An Upstream Resume + * is sent only after the USBHS bus has been in SUSPEND state for at least 5 + * ms. + */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval |= USBHS_DEVCTRL_RMWKUP; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + leave_critical_section(flags); + + /* This bit is automatically cleared by hardware at the end of the Upstream + * Resume + */ + + while ((sam_getreg(SAM_USBHS_DEVCTRL) & USBHS_DEVCTRL_RMWKUP) != 0); + return OK; +} + +/**************************************************************************** + * Name: sam_selfpowered + * + * Description: + * This is the selfpowered() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + DEBUGASSERT(dev != NULL); + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: sam_pullup + * + * Description: + * This is the pullup() method of the USB device driver interface + * + ****************************************************************************/ + +static int sam_pullup(FAR struct usbdev_s *dev, bool enable) +{ + struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev; + irqstate_t flags; + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + flags = enter_critical_section(); + if (enable) + { + /* Un-freeze clocking. + * + * When the clock is frozen, on certain bits in the USBCH_CTRL + * register can be modified (FRZCLK, USBE, and LS). In addition, + * only the asynchronous interrupt sources can trigger the USB + * interrupt: + * + * - Wake-up Interrupt (USBHS_DEVISR.WAKEUP) + * - Host Wake-up Interrupt (USBHS_HSTISR.HWUPI) + */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* DETACH=0: USBHS is attached. ARMs the USBHS to pull up the DP line + * when the USBHS is no longer suspended. + */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval &= ~USBHS_DEVCTRL_DETACH; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + priv->usbdev.speed = USB_SPEED_FULL; + + /* There are several possibilities: + * + * 1. The device may not be plugged into a host. In that case, the + * hardware will be in a suspended state. When an idle USB bus state + * has been detected for 3 ms , the controller sets the Suspend + * (USBHS_DEVISR.SUSP) interrupt bit. + * 2. We may have been suspended but a WAKEUP event has already occurred. + * The USBHS_DEVISR.WAKEUP interrupt bit is set when a non-idle event + * is detected, it can occur whether the controller is in the Suspend + * mode or not. The USBHS_DEVISR.SUSP and USBHS_DEVISR.WAKEUP interrupts + * are thus independent, except that one bit is cleared when the other is set. + * 3. Because we have already enabled the pull-up, that event may have already + * have been reset by the host. + */ + + regval = sam_getreg(SAM_USBHS_DEVISR); + if ((regval & USBHS_DEVINT_SUSPD) == 0) + { + /* If the USBHS detects activity on the BUS, then it will not be + * suspended. In that case, next event that we expect to see is a + * reset from the connected host. When a USB reset is detected on + * the USB line, the following operations are performed by the + * controller: + * + * - All endpoints are disabled, except the default control + * endpoint. + * - The default control endpoint is reset + * - The data toggle sequence of the default control endpoint is + * cleared. + * - At the end of the reset process, the End of Reset + * (USBHS_DEVISR.EORST) bit is set. + * - During a reset, the USBHS automatically switches to High- + * speed mode if the host is High-speed-capable (the reset is + * called High-speed reset). The user should observe the + * USBHS_SR.SPEED field to know the speed running at the end + * of the reset (USBHS_DEVISR.EORST = 1). + * + * The class implementation should not call this method with + * enable == true until is is fully initialized and ready to + * accept connections. + */ + + /* Enable expected interrupts */ + + sam_putreg(USBHS_DEVINT_EORST | USBHS_DEVINT_EORSM | + USBHS_DEVINT_SUSPD, + SAM_USBHS_DEVIER); + + /* Leave the clock unfrozen */ + } + else + { + /* If there is no host connected (no bus activity), then we + * might get a SUSPend interrupt instead of a End of Reset. In + * the case, we would like to keep the clock frozen until the + * host is connected. + * + * The strategy here was taken from the SAMV7 sample code: It + * will force a SUSPend event. Then disable clocking. We will + * take the SUSPend interrupt (because it is already pending), + * but after the clock is frozen, only a WAKEUP interrupt can be + * received. + */ + + /* Enable wakeup interrupts */ + + sam_putreg(USBHS_DEVINT_WAKEUP | USBHS_DEVINT_EORSM, + SAM_USBHS_DEVIER); + + /* Enable expected interrupts */ + + sam_putreg(USBHS_DEVINT_EORST | USBHS_DEVINT_WAKEUP | + USBHS_DEVINT_SUSPD, + SAM_USBHS_DEVIER); + + /* Clear pending interrupts */ + + sam_putreg(USBHS_DEVINT_EORST | USBHS_DEVINT_SUSPD, + SAM_USBHS_DEVICR); + + /* Force the first suspend event */ + + sam_putreg(USBHS_DEVINT_SUSPD, SAM_USBHS_DEVIFR); + sam_putreg(USBHS_DEVINT_WAKEUP, SAM_USBHS_DEVICR); + + /* Refreeze the clock and wait for the wakeup event */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval |= USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + } + } + else + { + /* DETACH=1: USBHS is detached, UTMI transceiver is suspended. */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval |= USBHS_DEVCTRL_DETACH; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Freeze clocking */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval |= USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Device returns to the Powered state */ + + if (priv->devstate > USBHS_DEVSTATE_POWERED) + { + priv->devstate = USBHS_DEVSTATE_POWERED; + } + + if (priv->prevstate > USBHS_DEVSTATE_POWERED) + { + priv->prevstate = USBHS_DEVSTATE_POWERED; + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Initialization/Reset + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_reset + ****************************************************************************/ + +static void sam_reset(struct sam_usbdev_s *priv) +{ + uint32_t regval; + uint8_t epno; + + /* Unfreeze clocking to the USBHS peripheral. */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Tell the class driver that we are disconnected. The class driver + * should then accept any new configurations. + */ + + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + + /* The device enters the Default state */ + /* Disable the device address */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval &= ~(USBHS_DEVCTRL_UADD_MASK | USBHS_DEVCTRL_ADDEN); + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Revert to the un-addressed, default state */ + + priv->devstate = USBHS_DEVSTATE_DEFAULT; + + /* Reset and disable all endpoints. Then re-configure EP0 */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + sam_ep0_configure(priv); + + /* Reset endpoint data structures */ + + for (epno = 0; epno < SAM_USBHS_NENDPOINTS; epno++) + { + struct sam_ep_s *privep = &priv->eplist[epno]; + + /* Cancel any queued requests. Since they are cancelled + * with status -ESHUTDOWN, then will not be re-queued + * until the configuration is reset. NOTE: This should + * not be necessary... the CLASS_DISCONNECT above should + * result in the class implementation calling sam_ep_disable + * for each of its configured endpoints. + */ + + sam_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->halted = false; + privep->zlpneeded = false; + privep->zlpsent = false; + } + + /* Re-configure the USB controller in its initial, unconnected state */ + + priv->usbdev.speed = USB_SPEED_FULL; + + /* Enable normal operational interrupts (including endpoint 0) */ + + regval = USBHS_DEVINT_EORST | USBHS_DEVINT_WAKEUP | USBHS_DEVINT_SUSPD | + USBHS_DEVINT_PEP0; + sam_putreg(regval, SAM_USBHS_DEVIER); + + sam_dumpep(priv, EP0); +} + +/**************************************************************************** + * Name: sam_hw_setup + ****************************************************************************/ + +static void sam_hw_setup(struct sam_usbdev_s *priv) +{ + uint32_t regval; + int i; + + /* Disable USB hardware. Will perform a reset of most resisters. */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval &= ~USBHS_CTRL_USBE; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Configure USBHS pins. Nothing needs to be done: HDM and HDP are the + * primary pin functions and there are no alternatives. + */ + + /* Enable clocking to the USBHS peripheral. + * + * The clock for the USBHS bus interface is generated by the Power + * Management Controller (PMC). Before enabling the USB clock in the + * PMC, the USBHS must be enabled (by writing a one to the + * USBHS_CTRL.USBE bit and a zero to the USBHS_CTRL.FRZCLK bit). + * + * The USBHS can work in two modes: + * + * - Normal mode (SPDCONF = 0) where High speed, Full speed and Low + * speed are available. + * - Low-power mode (SPDCONF = 1) where Full speed and Low speed are + * available. + * + * Only the normal mode is supported by this driver. For Normal mode: + * + * 1. Enable the USBHS peripheral clock (PMC_PCER). + * 2. Enable the USBHS (UIMOD = 1, USBE = 1, FRZCLK = 0). + * 3. Enable the UPLL 480 MHz. + * 4. Wait for the UPLL 480 MHz to be considered as locked by the PMC. + * + * Steps 3 and 4 are performed in sam_usbclock.c. + */ + + /* Enable the USBHS peripheral clock (PMC_PCER) */ + + sam_usbhs_enableclk(); + + /* Enable USBHS peripheral (USBE = 1) in device mode (UIMOD = 1) and + * unfreeze clocking (FRZCLK = 0) + */ + + regval |= USBHS_CTRL_UIMOD_DEVICE; + sam_putreg(regval, SAM_USBHS_CTRL); + + regval |= USBHS_CTRL_USBE; + sam_putreg(regval, SAM_USBHS_CTRL); + + regval &= ~USBHS_CTRL_UIDE; + sam_putreg(regval, SAM_USBHS_CTRL); + + regval &= ~USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Enable the UPLL */ + + sam_usbclock(); + + /* Select High Speed or force Full Speed */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval &= ~USBHS_DEVCTRL_SPDCONF_MASK; +#ifdef CONFIG_SAMV7_USBDEVHS_LOWPOWER + regval |= USBHS_DEVCTRL_SPDCONF_LOWPOWER; +#else + regval |= USBHS_DEVCTRL_SPDCONF_NORMAL; +#endif + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Wait for UTMI clocking to be usable */ + + while ((sam_getreg(SAM_USBHS_SR) & USBHS_SR_CLKUSABLE) == 0); + + /* Make sure that we are not in Forced Low-Speed mode */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval &= ~USBHS_DEVCTRL_LS; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Reset and disable all endpoints, re-initializing endpoint 0. */ + + sam_epset_reset(priv, SAM_EPSET_ALL); + sam_ep0_configure(priv); + + /* Disconnect the device */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval |= USBHS_DEVCTRL_DETACH; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Initialize DMA channels */ + + for (i = 1; i <= SAM_USBHS_NDMACHANNELS; i++) + { + /* Stop any DMA transfer */ + + sam_putreg(0, SAM_USBHS_DEVDMACTRL(i)); + } + + /* Disable all endpoint interrupts. Disable all endpoints */ + + sam_putreg(USBHS_DEVEPT_ALLEPEN, SAM_USBHS_DEVIDR); + sam_putreg(0, SAM_USBHS_DEVEPT); + + /* Disable each endpoint interrupt */ + + for (i = 0; i < SAM_USBHS_NENDPOINTS; i++) + { + /* Disable endpoint interrupts */ + + sam_putreg(USBHS_DEVEPTIDR_ALLINTS, SAM_USBHS_DEVEPTIDR(i)); + + /* Clear endpoint status */ + + sam_putreg(USBHS_DEVEPTICR_ALLINTS, SAM_USBHS_DEVEPTICR(i)); + } + + /* Disable all interrupts */ + + sam_putreg(USBHS_DEVINT_ALL, SAM_USBHS_DEVIDR); + + /* Initialization complete... Freeze the clock */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval |= USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); +} + +/**************************************************************************** + * Name: sam_sw_setup + ****************************************************************************/ + +static void sam_sw_setup(struct sam_usbdev_s *priv) +{ + int epno; + +#ifdef CONFIG_SAMV7_USBDEVHS_SCATTERGATHER +#ifndef CONFIG_SAMV7_USBDEVHS_PREALLOCATE + int i; + + /* Allocate a pool of free DMA transfer descriptors */ + + priv->dtdpool = (struct sam_dtd_s *) + kmm_memalign(16, CONFIG_SAMV7_USBDEVHS_NDTDS * sizeof(struct sam_dtd_s)); + if (!priv->dtdpool) + { + udbg("ERROR: Failed to allocate the DMA transfer descriptor pool\n"); + return NULL; + } + + /* Initialize the list of free DMA transfer descriptors */ + + for (i = 0; i < CONFIG_SAMV7_USBDEVHS_NDTDS; i++) + { + /* Put the transfer descriptor in a free list */ + + sam_td_free(&priv->dtdpool[i]); + } + +#else + /* Initialize the list of free DMA transfer descriptors */ + + DEBUGASSERT(((uintptr_t)&g_dtdpool & 15) == 0); + for (i = 0; i < CONFIG_SAMV7_USBDEVHS_NDTDS; i++) + { + /* Put the transfer descriptor in a free list */ + + sam_td_free(&g_dtdpool[i]); + } + +#endif /* CONFIG_SAMV7_USBDEVHS_PREALLOCATE */ +#endif /* CONFIG_SAMV7_USBDEVHS_SCATTERGATHER */ + + /* Initialize the device state structure. NOTE: many fields + * have the initial value of zero and, hence, are not explicitly + * initialized here. + */ + + memset(priv, 0, sizeof(struct sam_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[EP0].ep; + priv->epavail = SAM_EPSET_ALL & ~SAM_EP_BIT(EP0); + priv->devstate = USBHS_DEVSTATE_SUSPENDED; + priv->prevstate = USBHS_DEVSTATE_POWERED; + + /* Initialize the endpoint list */ + + for (epno = 0; epno < SAM_USBHS_NENDPOINTS; epno++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the (physical) endpoint number which is just the index to the + * endpoint. + */ + + priv->eplist[epno].ep.ops = &g_epops; + priv->eplist[epno].dev = priv; + priv->eplist[epno].ep.eplog = epno; + + /* We will use a maxpacket size for supported for each endpoint */ + + priv->eplist[epno].ep.maxpacket = SAM_USBHS_MAXPACKETSIZE(epno); + } + +#if CONFIG_USBDEV_EP0_MAXSIZE < SAM_EP0_MAXPACKET + /* Select a smaller endpoint size for EP0 if so configured */ + + priv->eplist[EP0].ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; +#endif +} + +/**************************************************************************** + * Name: sam_hw_shutdown + ****************************************************************************/ + +static void sam_hw_shutdown(struct sam_usbdev_s *priv) +{ + uint32_t regval; + + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable all interrupts */ + + sam_putreg(USBHS_DEVINT_ALL, SAM_USBHS_DEVIDR); + + /* Clear all pending interrupt status */ + + sam_putreg(USBHS_DEVINT_ALL, SAM_USBHS_DEVICR); + + /* DETACH=1: USBHS is detached, UTMI transceiver is suspended. */ + + regval = sam_getreg(SAM_USBHS_DEVCTRL); + regval |= USBHS_DEVCTRL_DETACH; + sam_putreg(regval, SAM_USBHS_DEVCTRL); + + /* Freeze clocking */ + + regval = sam_getreg(SAM_USBHS_CTRL); + regval |= USBHS_CTRL_FRZCLK; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Disable USB hardware */ + + regval &= ~USBHS_CTRL_USBE; + sam_putreg(regval, SAM_USBHS_CTRL); + + /* Disable clocking to the USBHS peripheral */ + + sam_usbhs_disableclk(); +} + +/**************************************************************************** + * Name: sam_sw_shutdown + ****************************************************************************/ + +static void sam_sw_shutdown(struct sam_usbdev_s *priv) +{ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_usbinitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_usbhs; + + usbtrace(TRACE_DEVINIT, 0); + + /* Software initialization */ + + sam_sw_setup(priv); + + /* Power up and initialize USB controller. Interrupts from the USBHS + * controller are initialized here, but will not be enabled at the NVIC + * until the class driver is installed. + */ + + sam_hw_setup(priv); + + /* Attach USB controller interrupt handlers. The hardware will not be + * initialized and interrupts will not be enabled until the class device + * driver is bound. Getting the IRQs here only makes sure that we have + * them when we need them later. + */ + + if (irq_attach(SAM_IRQ_USBHS, sam_usbhs_interrupt) != 0) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_IRQREGISTRATION), + (uint16_t)SAM_IRQ_USBHS); + goto errout; + } + + + /* Enable USB controller interrupts at the NVIC. Interrupts are still + * disabled at the USBHS. + */ + + up_enable_irq(SAM_IRQ_USBHS); + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + struct sam_usbdev_s *priv = &g_usbhs; + irqstate_t flags; + + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + flags = enter_critical_section(); + usbtrace(TRACE_DEVUNINIT, 0); + + /* Disable and detach the USBHS IRQ */ + + up_disable_irq(SAM_IRQ_USBHS); + irq_detach(SAM_IRQ_USBHS); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Put the hardware in an inactive state */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_usbhs; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + DEBUGASSERT(driver != NULL && + driver->ops->bind != NULL && + driver->ops->unbind != NULL && + driver->ops->disconnect != NULL && + driver->ops->setup != NULL); + DEBUGASSERT(priv->driver == NULL); + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret != OK) + { + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver. If the USB device is connected to a + * USB host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct sam_usbdev_s *priv = &g_usbhs; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + DEBUGASSERT(driver == priv->driver); + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts (but keep them attached) */ + + up_disable_irq(SAM_IRQ_USBHS); + + /* Put the hardware in an inactive state. Then bring the hardware back up + * in the initial state. This is essentially the same state as we were + * in when up_usbinitialize() was first called. + */ + + sam_hw_shutdown(priv); + sam_sw_shutdown(priv); + + sam_sw_setup(priv); + sam_hw_setup(priv); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_SAMV7_USBDEVHS */ diff --git a/arch/arm/src/samv7/sam_userspace.c b/arch/arm/src/samv7/sam_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..255d59919a1e5450f3518e52ce5fcb305c61a7d4 --- /dev/null +++ b/arch/arm/src/samv7/sam_userspace.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_userspace.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "sam_mpuinit.h" +#include "sam_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + * Assumptions: + * The D-Cache has not yet been enabled. + * + ****************************************************************************/ + +void sam_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/samv7/sam_userspace.h b/arch/arm/src/samv7/sam_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..f290bb07aa63da04c46f89a43dfe3de5f115fbe7 --- /dev/null +++ b/arch/arm/src/samv7/sam_userspace.h @@ -0,0 +1,105 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_userspace.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_USERSPACE_H +#define __ARCH_ARM_SRC_SAMV7_SAM_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: sam_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void sam_userspace(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_USERSPACE_H */ diff --git a/arch/arm/src/samv7/sam_wdt.c b/arch/arm/src/samv7/sam_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..3f8e858ead3db431b00d2a44d304dbd9b8acb41a --- /dev/null +++ b/arch/arm/src/samv7/sam_wdt.c @@ -0,0 +1,706 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_wdg.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_wdt.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SAMV7_WDT) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The Watchdog Timer uses the Slow Clock divided by 128 to establish the + * maximum Watchdog period to be 16 seconds (with a typical Slow Clock of + * 32768 kHz). + */ + +#ifndef BOARD_SCLK_FREQUENCY +# define BOARD_SCLK_FREQUENCY 32768 +#endif + +#define WDT_FREQUENCY (BOARD_SCLK_FREQUENCY / 128) + +/* At 32768Hz, the maximum timeout value will be: + * + * 4096 / WDT_FREQUENCY = 256 seconds or 16,000 milliseconds + * + * And the minimum (non-zero) timeout would be: + * + * 1 / WDT_FREQUENCY = 3.9 milliseconds + */ + +#define WDT_MINTIMEOUT ((1000 + WDT_FREQUENCY - 1) / WDT_FREQUENCY) +#define WDT_MAXTIMEOUT ((4096 * 1000) / WDT_FREQUENCY) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct sam_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ +#ifdef CONFIG_SAMV7_WDT_INTERRUPT + xcpt_t handler; /* Current WDT interrupt handler */ +#endif + uint32_t timeout; /* The actual timeout value (milliseconds) */ + uint16_t reload; /* The 12-bit watchdog reload value */ + bool started; /* The timer has been started */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_SAMV7_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr); +static void sam_putreg(uint32_t regval, uintptr_t regaddr); +#else +# define sam_getreg(regaddr) getreg32(regaddr) +# define sam_putreg(regval,regaddr) putreg32(regval,regaddr) +#endif + +/* Interrupt hanlding *******************************************************/ + +#ifdef CONFIG_SAMV7_WDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context); +#endif + +/* "Lower half" driver methods **********************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower); +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower); +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler); +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = sam_start, + .stop = sam_stop, + .keepalive = sam_keepalive, + .getstatus = sam_getstatus, + .settimeout = sam_settimeout, + .capture = sam_capture, + .ioctl = sam_ioctl, +}; + +/* "Lower half" driver state */ + +static struct sam_lowerhalf_s g_wdtdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_getreg + * + * Description: + * Get the contents of an SAMV7 register + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t sam_getreg(uintptr_t regaddr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint32_t preval = 0; + + /* Read the value from the register */ + + uint32_t regval = getreg32(regaddr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (regaddr == prevaddr && regval == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return regval; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = regaddr; + preval = regval; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%048\n", regaddr, regval); + return regval; +} +#endif + +/**************************************************************************** + * Name: sam_putreg + * + * Description: + * Set the contents of an SAMV7 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_WDT_REGDEBUG) && defined(CONFIG_DEBUG) +static void sam_putreg(uint32_t regval, uintptr_t regaddr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", regaddr, regval); + + /* Write the value */ + + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: sam_interrupt + * + * Description: + * WDT early warning interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_WDT_INTERRUPT +static int sam_interrupt(int irq, FAR void *context) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + /* Is there a registered handler? */ + + if (priv->handler) + { + /* Yes... NOTE: This interrupt service routine (ISR) must reload + * the WDT counter to prevent the reset. Otherwise, we will reset + * upon return. + */ + + priv->handler(irq, context); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: sam_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return priv->started ? OK : -ENOSYS; +} + +/**************************************************************************** + * Name: sam_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* The watchdog timer is enabled or disabled by writing to the MR register. + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sam_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the atchdog timer or "petting the dog". + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + wdvdbg("Entry\n"); + + /* Write WDT_CR_WDRSTT to the WDT CR regiser (along with the KEY value) + * will restart the watchdog timer. + */ + + sam_putreg(WDT_CR_WDRSTT | WDT_CR_KEY, SAM_WDT_CR); + return OK; +} + +/**************************************************************************** + * Name: sam_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * stawtus - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + +#ifdef CONFIG_SAMV7_WDT_INTERRUPT + if (priv->handler) + { + status->flags |= WDFLAGS_CAPTURE; + } +#endif + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the watchdog expires (in milliseconds) + * + * REVISIT: I think this that this information is available. + */ + + status->timeleft = 0; + + wdvdbg("Status :\n"); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: sam_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in millisecnds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + uint32_t reload; + uint32_t regval; + + DEBUGASSERT(priv); + wdvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < WDT_MINTIMEOUT || timeout >= WDT_MAXTIMEOUT) + { + wddbg("Cannot represent timeout: %d < %d > %d\n", + WDT_MINTIMEOUT, timeout, WDT_MAXTIMEOUT); + return -ERANGE; + } + + /* Calculate the reload value to achiee this (appoximate) timeout. + * + * Examples with WDT_FREQUENCY = 32768 / 128 = 256: + * timeout = 4 -> reload = 1 + * timeout = 16000 -> reload = 4096 + */ + + reload = (timeout * WDT_FREQUENCY + 500) / 1000; + if (reload < 1) + { + reload = 1; + } + else if (reload > 4095) + { + reload = 4095; + } + + /* Calculate and save the actual timeout value in milliseconds: + * + * timeout = 1000 * (reload + 1) / Fwwdg + */ + + priv->timeout = (1000 * reload + WDT_FREQUENCY/2) / WDT_FREQUENCY; + + /* Remember the selected values */ + + priv->reload = reload; + + wdvdbg("reload=%d timout: %d->%d\n", + reload, timeout, priv->timeout); + + /* Set the WDT_MR according to calculated value + * + * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only + * a processor reset resets it. Writing the WDT_MR register reloads the + * timer with the newly programmed mode parameters. + */ + + regval = WDT_MR_WDV(reload) | WDT_MR_WDD(reload); + +#ifdef CONFIG_SAMV7_WDT_INTERRUPT + /* Generate an interrupt whent he watchdog timer expires */ + + regval |= WDT_MR_WDFIEN; +#else + /* Reset (everything) if the watchdog timer expires. + * + * REVISIT: Set WDT_MR_WDRPROC so that only the processor is reset? + */ + + regval |= WDT_MR_WDRSTEN; +#endif + +#ifdef CONFIG_SAMV7_WDT_DEBUGHALT + /* Halt the watchdog in the debug state */ + + regval |= WDT_MR_WDDBGHLT; +#endif + +#ifdef CONFIG_SAMV7_WDT_IDLEHALT + /* Halt the watchdog in the IDLE mode */ + + regval |= WDT_MR_WDIDLEHLT; +#endif + + sam_putreg(regval, SAM_WDT_MR); + + /* NOTE: We had to start the watchdog here (because we cannot re-write the + * MR register). So sam_start will not be able to do anything. + */ + + priv->started = true; + + wdvdbg("Setup: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_WDT_CR), sam_getreg(SAM_WDT_MR), + sam_getreg(SAM_WDT_SR)); + + return OK; +} + +/**************************************************************************** + * Name: sam_capture + * + * Description: + * Don't reset on watchdog timer timeout; instead, call this user provider + * timeout handler. NOTE: Providing handler==NULL will restore the reset + * behavior. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new watchdog expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous watchdog expiration function pointer or NULL is there was + * no previous function pointer, i.e., if the previous behavior was + * reset-on-expiration (NULL is also returned if an error occurs). + * + ****************************************************************************/ + +static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler) +{ +#ifndef CONFIG_SAMV7_WDT_INTERRUPT + wddbg("ERROR: Not configured for this mode\n"); + return NULL; +#else + FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower; + irqstate_t flags; + xcpt_t oldhandler; + + DEBUGASSERT(priv); + wdvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + flags = enter_critical_section(); + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + /* Are we attaching or detaching the handler? */ + + if (handler) + { + /* Attaching... Enable the WDT interrupt */ + + up_enable_irq(SAM_IRQ_WDT); + } + else + { + /* Detaching... Disable the WDT interrupt */ + + up_disable_irq(SAM_IRQ_WDT); + } + + leave_critical_section(flags); + return oldhandler; +#endif +} + +/**************************************************************************** + * Name: sam_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctol command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + wdvdbg("cmd=%d arg=%ld\n", cmd, arg); + + /* No ioctls are supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdginitialize + * + * Description: + * Initialize the WDT watchdog time. The watchdog timer is initialized and + * registered as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * None + * + * Returned Values: + * None + * + ****************************************************************************/ + +int up_wdginitialize(void) +{ + FAR struct sam_lowerhalf_s *priv = &g_wdtdev; + + wdvdbg("Entry: CR: %08x MR: %08x SR: %08x\n", + sam_getreg(SAM_WDT_CR), sam_getreg(SAM_WDT_MR), + sam_getreg(SAM_WDT_SR)); + + /* Check if some previous logic was disabled the watchdog timer. Since the + * MR can be written only one time, we are out of business if that is the + * case. + */ + + DEBUGASSERT((sam_getreg(SAM_WDT_MR) & WDT_MR_WDDIS) == 0); + + /* No clock setup is required. The Watchdog Timer uses the Slow Clock + * divided by 128 to establish the maximum Watchdog period to be 16 seconds + * (with a typical Slow Clock of 32768 kHz). + */ + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_wdgops; + +#ifdef CONFIG_SAMV7_WDT_INTERRUPT + /* Attach our WDT interrupt handler (But don't enable it yet) */ + + (void)irq_attach(SAM_IRQ_WDT, sam_interrupt); +#endif + + /* Register the watchdog driver as /dev/wdt */ + + (void)watchdog_register("/dev/wdt", + (FAR struct watchdog_lowerhalf_s *)priv); + return OK; +} + +#endif /* CONFIG_WATCHDOG && CONFIG_SAMV7_WDT */ diff --git a/arch/arm/src/samv7/sam_wdt.h b/arch/arm/src/samv7/sam_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..d5d7c50728b5334609e5e27987df4e30852904dd --- /dev/null +++ b/arch/arm/src/samv7/sam_wdt.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_wdt.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_WDT_H +#define __ARCH_ARM_SRC_SAMV7_SAM_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/sam_wdt.h" + +#ifdef CONFIG_WATCHDOG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_WATCHDOG */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_WDT_H */ diff --git a/arch/arm/src/samv7/sam_xdmac.c b/arch/arm/src/samv7/sam_xdmac.c new file mode 100644 index 0000000000000000000000000000000000000000..5519c87c7907573e289ede4b07365505505257cb --- /dev/null +++ b/arch/arm/src/samv7/sam_xdmac.c @@ -0,0 +1,2103 @@ +/**************************************************************************** + * arch/arm/src/samv7/sam_xdmac.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "cache.h" +#include "up_internal.h" +#include "sched/sched.h" + +#include "sam_xdmac.h" +#include "sam_periphclks.h" +#include "chip/sam_pmc.h" +#include "chip/sam_xdmac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Condition out the whole file unless DMA is selected in the configuration */ + +#ifdef CONFIG_SAMV7_XDMAC + +/* If SAMV7 DMA support is enabled, then OS DMA support should also be + * enabled + */ + +#ifndef CONFIG_ARCH_DMA +# warning "SAMV7 DMA enabled but CONFIG_ARCH_DMA disabled" +#endif + +/* Check the number of link list descriptors to allocate */ + +#ifndef CONFIG_SAMV7_NLLDESC +# define CONFIG_SAMV7_NLLDESC SAMV7_NDMACHAN +#endif + +#if CONFIG_SAMV7_NLLDESC < SAMV7_NDMACHAN +# warning "At least SAMV7_NDMACHAN descriptors must be allocated" + +# undef CONFIG_SAMV7_NLLDESC +# define CONFIG_SAMV7_NLLDESC SAMV7_NDMACHAN +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure maps a peripheral ID to an DMA channel */ + +struct sam_pidmap_s +{ + uint8_t pid; /* Peripheral identifier */ + uint8_t pchan; /* DMA channel */ +}; + +/* This structure describes one DMA channel */ + +struct sam_xdmach_s +{ + uint8_t chan; /* DMA channel number (0-15) */ + bool inuse; /* TRUE: The DMA channel is in use */ + bool rx; /* TRUE: Peripheral to memory transfer */ + uint32_t flags; /* DMA channel flags */ + uint32_t base; /* DMA register channel base address */ + uint32_t cc; /* Pre-calculated CC register for transfer */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ + uint32_t rxaddr; /* RX memory address to be invalidated */ + size_t rxsize; /* Size of RX memory region */ + struct chnext_view1_s *llhead; /* DMA link list head */ + struct chnext_view1_s *lltail; /* DMA link list head */ +}; + +/* This structure describes the state of one DMA controller */ + +struct sam_xdmac_s +{ + /* These semaphores protect the DMA channel and descriptor tables */ + + sem_t chsem; /* Protects channel table */ + sem_t dsem; /* Protects descriptor table */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Channel Control (CC) Register field lookups */ + +static const uint32_t g_chanwidth[3] = +{ + XDMACH_CC_DWIDTH_BYTE, + XDMACH_CC_DWIDTH_HWORD, + XDMACH_CC_DWIDTH_WORD, +}; + +/* These tables map peripheral IDs to channels. A lookup is performed + * before each DMA transfer in order to map the peripheral IDs to the + * correct channel. This must be done because the channel can change with + * the direction of the transfer. + */ + +/* RX DMA: */ + +static const struct sam_pidmap_s g_xdmac_rxchan[] = +{ + { SAM_PID_HSMCI0, XDMACH_HSMCI }, /* HSMCI Receive/Transmit */ + { SAM_PID_SPI0, XDMACH_SPI0_RX }, /* SPI0 Receive */ + { SAM_PID_SPI1, XDMACH_SPI1_RX }, /* SPI1 Receive */ + { SAM_PID_QSPI, XDMACH_QSPI_RX }, /* QSPI Receive */ + { SAM_PID_USART0, XDMACH_USART0_RX }, /* USART0 Receive */ + { SAM_PID_USART1, XDMACH_USART1_RX }, /* USART1 Receive */ + { SAM_PID_USART2, XDMACH_USART2_RX }, /* USART2 Receive */ + { SAM_PID_TWIHS0, XDMACH_TWIHS0_RX }, /* TWIHS0 Receive */ + { SAM_PID_TWIHS1, XDMACH_TWIHS1_RX }, /* TWIHS1 Receive */ + { SAM_PID_TWIHS2, XDMACH_TWIHS2_RX }, /* TWIHS2 Receive */ + { SAM_PID_UART0, XDMACH_UART0_RX }, /* UART0 Receive */ + { SAM_PID_UART1, XDMACH_UART1_RX }, /* UART1 Receive */ + { SAM_PID_UART2, XDMACH_UART2_RX }, /* UART2 Receive */ + { SAM_PID_UART3, XDMACH_UART3_RX }, /* UART3 Receive */ + { SAM_PID_UART4, XDMACH_UART4_RX }, /* UART4 Receive */ + { SAM_PID_SSC0, XDMACH_SSC_RX }, /* SSC Receive */ + { SAM_PID_PIOA, XDMACH_PIOA_RX }, /* PIOA Receive */ + { SAM_PID_AFEC0, XDMACH_AFEC0_RX }, /* AFEC0 Receive */ + { SAM_PID_AFEC1, XDMACH_AFEC1_RX }, /* AFEC1 Receive */ + { SAM_PID_AES, XDMACH_AES_RX }, /* AES Receive */ + { SAM_PID_TC0, XDMACH_TC0_RX }, /* TC0 Receive */ + { SAM_PID_TC1, XDMACH_TC1_RX }, /* TC1 Receive */ + { SAM_PID_TC2, XDMACH_TC2_RX }, /* TC2 Receive */ + { SAM_PID_TC3, XDMACH_TC3_RX } /* TC3 Receive */ +}; +#define NXDMAC_RXCHANNELS (sizeof(g_xdmac_rxchan) / sizeof(struct sam_pidmap_s)) + +/* TX DMA: */ + +static const struct sam_pidmap_s g_xdmac_txchan[] = +{ + { SAM_PID_HSMCI0, XDMACH_HSMCI }, /* HSMCI Receive/Transmit */ + { SAM_PID_SPI0, XDMACH_SPI0_TX }, /* SPI0 Transmit */ + { SAM_PID_SPI1, XDMACH_SPI1_TX }, /* SPI1 Transmit */ + { SAM_PID_QSPI, XDMACH_QSPI_TX }, /* QSPI Transmit */ + { SAM_PID_USART0, XDMACH_USART0_TX }, /* USART0 Transmit */ + { SAM_PID_USART1, XDMACH_USART1_TX }, /* USART1 Transmit */ + { SAM_PID_USART2, XDMACH_USART2_TX }, /* USART2 Transmit */ + { SAM_PID_PWM0, XDMACH_PWM0_TX }, /* PWM0 Transmit */ + { SAM_PID_TWIHS0, XDMACH_TWIHS0_TX }, /* TWIHS0 Transmit */ + { SAM_PID_TWIHS1, XDMACH_TWIHS1_TX }, /* TWIHS1 Transmit */ + { SAM_PID_TWIHS2, XDMACH_TWIHS2_TX }, /* TWIHS2 Transmit */ + { SAM_PID_UART0, XDMACH_UART0_TX }, /* UART0 Transmit */ + { SAM_PID_UART1, XDMACH_UART1_TX }, /* UART1 Transmit */ + { SAM_PID_UART2, XDMACH_UART2_TX }, /* UART2 Transmit */ + { SAM_PID_UART3, XDMACH_UART3_TX }, /* UART3 Transmit */ + { SAM_PID_UART4, XDMACH_UART4_TX }, /* UART4 Transmit */ + { SAM_PID_DACC, XDMACH_DACC_TX }, /* DACC Transmit */ + { SAM_PID_SSC0, XDMACH_SSC_TX }, /* SSC Transmit */ + { SAM_PID_AES, XDMACH_AES_TX }, /* AES Transmit */ + { SAM_PID_PWM1, XDMACH_PWM1_TX } /* PWM01Transmit */ +}; +#define NXDMAC_TXCHANNELS (sizeof(g_xdmac_txchan) / sizeof(struct sam_pidmap_s)) + +/* This array describes the available link list descriptors */ + +struct chnext_view1_s g_lldesc[CONFIG_SAMV7_NLLDESC]; + +/* This array describes the state of each XDMAC channel 0 */ + +static struct sam_xdmach_s g_xdmach[SAMV7_NDMACHAN] = +{ +#if SAMV7_NDMACHAN > 0 + { + .chan = 0, + .base = SAM_XDMACH0_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 1 + { + .chan = 1, + .base = SAM_XDMACH1_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 2 + { + .chan = 2, + .base = SAM_XDMACH2_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 3 + { + .chan = 3, + .base = SAM_XDMACH3_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 4 + { + .chan = 4, + .base = SAM_XDMACH4_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 5 + { + .chan = 5, + .base = SAM_XDMACH5_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 6 + { + .chan = 6, + .base = SAM_XDMACH6_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 7 + { + .chan = 7, + .base = SAM_XDMACH7_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 8 + { + .chan = 8, + .base = SAM_XDMACH8_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 9 + { + .chan = 9, + .base = SAM_XDMACH9_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 10 + { + .chan = 10, + .base = SAM_XDMACH10_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 11 + { + .chan = 11, + .base = SAM_XDMACH11_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 12 + { + .chan = 12, + .base = SAM_XDMACH12_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 13 + { + .chan = 13, + .base = SAM_XDMACH13_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 14 + { + .chan = 14, + .base = SAM_XDMACH14_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 15 + { + .chan = 15, + .base = SAM_XDMACH15_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 16 + { + .chan = 16, + .base = SAM_XDMACH16_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 17 + { + .chan = 17, + .base = SAM_XDMACH17_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 18 + { + .chan = 18, + .base = SAM_XDMACH18_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 19 + { + .chan = 19, + .base = SAM_XDMACH19_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 20 + { + .chan = 20, + .base = SAM_XDMACH10_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 21 + { + .chan = 21, + .base = SAM_XDMACH11_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 22 + { + .chan = 22, + .base = SAM_XDMACH22_BASE, + }, +#endif +#if SAMV7_NDMACHAN > 23 + { + .chan = 23, + .base = SAM_XDMACH23_BASE, + } +#endif +}; + +/* This describes the overall state of DMA controller */ + +static struct sam_xdmac_s g_xdmac; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_takechsem() and sam_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table + * + ****************************************************************************/ + +static void sam_takechsem(struct sam_xdmac_s *xdmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&xdmac->chsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givechsem(struct sam_xdmac_s *xdmac) +{ + (void)sem_post(&xdmac->chsem); +} + +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +static void sam_takedsem(struct sam_xdmac_s *xdmac) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&xdmac->dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(struct sam_xdmac_s *xdmac) +{ + (void)sem_post(&xdmac->dsem); +} + +/**************************************************************************** + * Name: sam_getdmac + * + * Description: + * Read a global XDMAC register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmac(struct sam_xdmac_s *xdmac, + unsigned int offset) +{ + return getreg32(SAM_XDMAC_BASE + offset); +} + +/**************************************************************************** + * Name: sam_putdmac + * + * Description: + * Write a value to a global XDMAC register + * + ****************************************************************************/ + +static inline void sam_putdmac(struct sam_xdmac_s *xdmac, uint32_t value, + unsigned int offset) +{ + putreg32(value, SAM_XDMAC_BASE + offset); +} + +/**************************************************************************** + * Name: sam_getdmach + * + * Description: + * Read a XDMAC channel register + * + ****************************************************************************/ + +static inline uint32_t sam_getdmach(struct sam_xdmach_s *xdmach, + unsigned int offset) +{ + return getreg32(xdmach->base + offset); +} + +/**************************************************************************** + * Name: sam_putdmach + * + * Description: + * Write a value to a XDMAC channel register + * + ****************************************************************************/ + +static inline void sam_putdmach(struct sam_xdmach_s *xdmach, uint32_t value, + unsigned int offset) +{ + putreg32(value, xdmach->base + offset); +} + +/**************************************************************************** + * Name: sam_controller + * + * Description: + * Given a DMA channel instance, return a pointer to the parent DMA + * controller instance. + * + ****************************************************************************/ + +static inline struct sam_xdmac_s *sam_controller(struct sam_xdmach_s *xdmach) +{ + /* This function is useful only on the SAMV7D4 where there are two + * XDMAC controllers. + */ + + return &g_xdmac; +} + +/**************************************************************************** + * Name: sam_physramaddr and sam_virtramaddr + * + * Description: + * Useful only if address mapping is required. If needed, these should + * problem be moved to file contain common address mapping logic + * (sam_memories) + * + ****************************************************************************/ + +static inline uintptr_t sam_physramaddr(uintptr_t virtaddr) +{ +#warning REVISIT -- Do DCTM address need to be remapped for DMA? + return virtaddr; +} + +static inline uintptr_t sam_virtramaddr(uintptr_t physaddr) +{ +#warning REVISIT -- Do DCTM address need to be remapped for DMA? + return physaddr; +} + +/**************************************************************************** + * Name: sam_channel, sam_source_channel, and sam_sink_channel + * + * Description: + * Return the RX or TX channel associated with a PID. As a clarification: + * + * The source channel refers to the source of data for the DMA. This is, + * either (1) memory for a TX DMA or (2) a peripheral register for an RX + * DMA. + * + * The sink channel is the recipient of the DMA data. This is either + * (1) memory for an RX DMA, or (2) a peripheral register for a TX DMA. + * + ****************************************************************************/ + +static uint8_t sam_channel(uint8_t pid, const struct sam_pidmap_s *table, + unsigned int nentries) +{ + int i; + + /* Search until either the entry with the matching PID is found or until + * all of the table entries have been examined without finding the PID. + */ + + for (i = 0; i < nentries; i++, table++) + { + if (table->pid == pid) + { + return table->pchan; + } + } + + dmadbg("No channel found for pid %d\n", pid); + DEBUGPANIC(); + return 0x3f; +} + +static uint32_t sam_source_channel(struct sam_xdmach_s *xdmach, uint8_t pid) +{ + return (uint32_t)sam_channel(pid, g_xdmac_rxchan, NXDMAC_RXCHANNELS); +} + +static uint32_t sam_sink_channel(struct sam_xdmach_s *xdmach, uint8_t pid) +{ + return (uint32_t)sam_channel(pid, g_xdmac_txchan, NXDMAC_TXCHANNELS); +} + +/**************************************************************************** + * Name: sam_maxtransfer + * + * Description: + * Maximum number of bytes that can be sent in one transfer + * + ****************************************************************************/ + +static size_t sam_maxtransfer(struct sam_xdmach_s *xdmach) +{ + unsigned int xfrwidth; + size_t maxtransfer; + + /* Get the maximum transfer size in bytes */ + + xfrwidth = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (xfrwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + maxtransfer = XDMACH_CUBC_UBLEN_MAX; + break; + + case 1: /* 16 bits, 2 bytes */ + maxtransfer = 2 * XDMACH_CUBC_UBLEN_MAX; + break; + + case 2: /* 32 bits 4 bytes */ + maxtransfer = 4 * XDMACH_CUBC_UBLEN_MAX; + break; + + case 3: /* 64 bits, 8 bytes */ + maxtransfer = 8 * XDMACH_CUBC_UBLEN_MAX; + break; + } + + return maxtransfer; +} + +/**************************************************************************** + * Name: sam_ntxtransfers + * + * Description: + * Number of TX transfers via DMA + * + ****************************************************************************/ + +static uint32_t sam_ntxtransfers(struct sam_xdmach_s *xdmach, + uint32_t dmasize) +{ + unsigned int srcwidth; + + /* Adjust the source transfer size for the source chunk size (memory + * chunk size). BTSIZE is "the number of transfers to be performed, that + * is, for writes it refers to the number of source width transfers + * to perform when XDMAC is flow controller. For Reads, BTSIZE refers to + * the number of transfers completed on the Source Interface. ..." + */ + + srcwidth = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + + switch (srcwidth) + { + default: + case 0: /* 8 bits, 1 byte */ + break; + + case 1: /* 16 bits, 2 bytes */ + dmasize = (dmasize + 1) >> 1; + break; + + case 2: /* 32 bits, 4 bytes */ + dmasize = (dmasize + 3) >> 2; + break; + + case 3: /* 64 bits, 8 bytes */ + dmasize = (dmasize + 7) >> 3; + break; + } + + return dmasize; +} + +/**************************************************************************** + * Name: sam_cubc + * + * Description: + * Calculate the CUBC transfer size + * + ****************************************************************************/ + +static inline uint32_t sam_cubc(struct sam_xdmach_s *xdmach, + uint32_t dmasize) +{ + uint32_t ntransfers; + + /* Set the buffer transfer size field. This is the number of transfers to + * be performed, that is, the number of source width transfers to perform. + */ + + ntransfers = sam_ntxtransfers(xdmach, dmasize); + + DEBUGASSERT(ntransfers <= XDMACH_CUBC_UBLEN_MAX); + return (ntransfers << XDMACH_CUBC_UBLEN_SHIFT); +} + +/**************************************************************************** + * Name: sam_txcc + * + * Description: + * Decode the flags to get the correct Channel Control (CC) Register bit + * settings for a transmit (memory to peripheral) transfer. + * + * Single Block: + * 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * 2. Program MBSIZE to the memory burst size used. + * 3. Program SAM/DAM to the memory addressing scheme. + * 4. Program SYNC to select the peripheral transfer direction. + * 5. Set PROT to activate a secure channel. + * 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + * 7. Program DWIDTH to configure the transfer data width. + * 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + * 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + * + ****************************************************************************/ + +static inline uint32_t sam_txcc(struct sam_xdmach_s *xdmach) +{ + uint32_t regval = 0; + uint32_t field; + + /* 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * + * By convention, TX refers to a memory to peripheral transfer. So the + * source is memory. Is the "peripheral" destination a peripheral? or + * it is really memory? + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral synchronized mode */ + + regval |= XDMACH_CC_TYPE; + } + + /* 2. Program MBSIZE to the memory burst size used. + * + * NOTE: This assumes the same encoding in the DMACH flags as in the CC + * register MBSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_MEMBURST_MASK) >> + DMACH_FLAG_MEMBURST_SHIFT; + regval |= (field << XDMACH_CC_MBSIZE_SHIFT); + + /* 3. Program SAM/DAM to the memory addressing scheme. + * + * NOTE: This assumes that 0 means non-incrementing. + * TX -> Source is memory. + */ + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + regval |= XDMACH_CC_SAM_INCR; + } + + /* TX -> Destination is peripheral. */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + regval |= XDMACH_CC_DAM_INCR; + } + + /* 4. Program DSYNC to select the peripheral transfer direction. + * + * TX -> Memory to peripheral + */ + + regval |= XDMACH_CC_DSYNC; + +#if 0 /* REVISIT */ + /* 5. Set PROT to activate a secure channel (REVISIT). */ + + regval |= XDMACH_CC_PROT; /* Channel is unsecured */ +#endif + + /* 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Peripheral synchronized mode -- set chunk size. + * NOTE that we assume that encoding in the XDMACH flags is the same + * as in the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) >> + DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + } + + /* 7. Program DWIDTH to configure the transfer data width. + * + * NOTE that we assume that encoding in the XDMACH flags is the same as in + * the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + regval |= (field << XDMACH_CC_DWIDTH_SHIFT); + + /* 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * + * TX -> Source is memory + */ + + if ((xdmach->flags & DMACH_FLAG_MEMAHB_MASK) == DMACH_FLAG_MEMAHB_AHB_IF1) + { + regval |= XDMACH_CC_SIF; + } + + /* TX -> Destination is peripheral */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHAHB_MASK) == DMACH_FLAG_PERIPHAHB_AHB_IF1) + { + regval |= XDMACH_CC_DIF; + } + + /* 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + int pid; + + /* Get the PID from the DMACH flags */ + + pid = (xdmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> + DMACH_FLAG_PERIPHPID_SHIFT; + + /* Look up the DMA channel code for TX: Peripheral is the sink. */ + + field = sam_sink_channel(xdmach, pid); + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + +#if 0 /* Not supported */ + /* 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + */ + + regval |= XDMACH_CC_SWREQ; +#endif + } + + return regval; +} + +/**************************************************************************** + * Name: sam_rxcc + * + * Description: + * Decode the flags to get the correct Channel Control (CC) Register bit + * settings for a receive (peripheral to memory) transfer. + * + * 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * 2. Program MBSIZE to the memory burst size used. + * 3. Program SAM/DAM to the memory addressing scheme. + * 4. Program SYNC to select the peripheral transfer direction. + * 5. Set PROT to activate a secure channel. + * 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + * 7. Program DWIDTH to configure the transfer data width. + * 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + * 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + * + ****************************************************************************/ + +static inline uint32_t sam_rxcc(struct sam_xdmach_s *xdmach) +{ + uint32_t regval = 0; + uint32_t field; + + /* 1. Clear TYPE for a memory to memory transfer, otherwise set + * this bit for memory to/from peripheral transfer. + * + * By convention, RX refers to a peripheral to memory transfer. So the + * source is peripheral. Is the "peripheral" source a peripheral? or + * is it also memory? + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Yes.. Use peripheral synchronized mode */ + + regval |= XDMACH_CC_TYPE; + } + + /* 2. Program MBSIZE to the memory burst size used. + * + * NOTE: This assumes the same encoding in the DMACH flags as in the CC + * register MBSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_MEMBURST_MASK) >> + DMACH_FLAG_MEMBURST_SHIFT; + regval |= (field << XDMACH_CC_MBSIZE_SHIFT); + + /* 3. Program SAM/DAM to the memory addressing scheme. + * + * NOTE: This assumes that 0 means non-incrementing. + * RX -> Source is peripheral. + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + regval |= XDMACH_CC_SAM_INCR; + } + + /* RX -> Destination is memory. */ + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + regval |= XDMACH_CC_DAM_INCR; + } + + /* 4. Program DSYNC to select the peripheral transfer direction. + * + * RX -> Peripheral to memory (DSYNC == 0) + */ + +#if 0 /* REVISIT */ + /* 5. Set PROT to activate a secure channel (REVISIT) */ + + regval |= XDMACH_CC_PROT; /* Channel is unsecured */ +#endif + + /* 6. Program CSIZE to configure the channel chunk size (only + * relevant for peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + /* Peripheral synchronized mode -- set chunk size. + * NOTE that we assume that encoding in the XDMACH flags is the same + * as in the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK) >> + DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT; + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + } + + /* 7. Program DWIDTH to configure the transfer data width. + * + * NOTE that we assume that encoding in the XDMACH flags is the same as in + * the CC register CSIZE field. + */ + + field = (xdmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> + DMACH_FLAG_PERIPHWIDTH_SHIFT; + regval |= (field << XDMACH_CC_DWIDTH_SHIFT); + + /* 8. Program SIF, DIF to configure the master interface + * used to read data and write data respectively. + * + * RX -> Source is peripheral + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHAHB_MASK) == DMACH_FLAG_PERIPHAHB_AHB_IF1) + { + regval |= XDMACH_CC_SIF; + } + + /* RX -> Destination is memory */ + + if ((xdmach->flags & DMACH_FLAG_MEMAHB_MASK) == DMACH_FLAG_MEMAHB_AHB_IF1) + { + regval |= XDMACH_CC_DIF; + } + + /* 9. Program PERID to select the active hardware request line + * (only relevant for a peripheral synchronized transfer). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0) + { + int pid; + + /* Get the PID from the DMACH flags */ + + pid = (xdmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> + DMACH_FLAG_PERIPHPID_SHIFT; + + /* Look up the DMA channel code for RX: Peripheral is the source. */ + + field = sam_source_channel(xdmach, pid); + regval |= (field << XDMACH_CC_CSIZE_SHIFT); + +#if 0 /* Not supported */ + /* 10. Set SWREQ to use software request (only relevant for a + * peripheral synchronized transfer). + */ + + regval |= XDMACH_CC_SWREQ; +#endif + } + + return regval; +} + +/**************************************************************************** + * Name: sam_allocdesc + * + * Description: + * Allocate and add one descriptor to the DMA channel's link list. + * + * NOTE: link list entries are freed by the DMA interrupt handler. + * However, since the setting/clearing of the 'in use' indication is + * atomic, no special actions need be performed. It would be a good thing + * to add logic to handle the case where all of the entries are exhausted + * and we could wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct chnext_view1_s * +sam_allocdesc(struct sam_xdmach_s *xdmach, struct chnext_view1_s *prev, + uint32_t csa, uint32_t cda, uint32_t cubc) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *descr = NULL; + int i; + + /* Sanity check -- csa == 0 is the indication that the link is unused. + * Obviously setting it to zero would break that usage. + */ + +#ifdef CONFIG_DEBUG + if (csa != 0) +#endif + { + /* Table a descriptor table semaphore count. When we get one, then there + * is at least one free descriptor in the table and it is ours. + */ + + sam_takedsem(xdmac); + + /* Examine each link list entry to find an available one -- i.e., one + * with csa == 0. That csa field is set to zero by the DMA transfer + * complete interrupt handler. The following should be safe because + * that is an atomic operation. + */ + + sam_takechsem(xdmac); + for (i = 0; i < CONFIG_SAMV7_NLLDESC; i++) + { + if (g_lldesc[i].csa == 0) + { + /* We have it. Initialize the new link list entry */ + + descr = &g_lldesc[i]; + descr->cnda = 0; /* Next Descriptor Address */ + descr->cubc = cubc; /* Channel Microblock Control Register */ + descr->csa = csa; /* Source address */ + descr->cda = cda; /* Destination address */ + + /* And then hook it at the tail of the link list */ + + if (!prev) + { + /* There is no previous link. This is the new head of + * the list + */ + + DEBUGASSERT(xdmach->llhead == NULL && xdmach->lltail == NULL); + xdmach->llhead = descr; + } + else + { + DEBUGASSERT(xdmach->llhead != NULL && xdmach->lltail == prev); + + /* When the second link is added to the list, that is the + * cue that we are going to do the link list transfer. + * + * Set the NDE field in the previous descriptor; Clear the + * NDE field in the final descriptor. + */ + + prev->cubc |= CHNEXT_UBC_NDE; + + /* Link the previous tail to the new tail. + * REVISIT: This assumes that the next description is fetched + * via AHB IF0. + */ + + prev->cnda = (uint32_t)sam_physramaddr((uintptr_t)descr); + } + + /* In any event, this is the new tail of the list */ + + xdmach->lltail = descr; + + /* Assume that we will be doing multiple buffer transfers and that + * that hardware will be accessing the descriptor via DMA. + */ + + arch_clean_dcache((uintptr_t)descr, + (uintptr_t)descr + sizeof(struct chnext_view1_s)); + break; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + sam_givechsem(xdmac); + DEBUGASSERT(descr != NULL); + } + + return descr; +} + +/**************************************************************************** + * Name: sam_freelinklist + * + * Description: + * Free all descriptors in the DMA channel's link list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_freelinklist(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *descr; + uintptr_t paddr; + + /* Get the head of the link list and detach the link list from the DMA + * channel + */ + + descr = xdmach->llhead; + xdmach->llhead = NULL; + xdmach->lltail = NULL; + + while (descr != NULL) + { + /* Valid, in-use descriptors never have csa == 0 */ + + DEBUGASSERT(descr->csa != 0); + + /* Get the physical address of the next descriptor in the list */ + + paddr = descr->cnda; + + /* Free the descriptor by simply nullifying it and bumping up the + * semaphore count. + */ + + memset(descr, 0, sizeof(struct chnext_view1_s)); + sam_givedsem(xdmac); + + /* Get the virtual address of the next descriptor in the list */ + + descr = (struct chnext_view1_s *)sam_virtramaddr(paddr); + } +} + +/**************************************************************************** + * Name: sam_txbuffer + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_txbuffer(struct sam_xdmach_s *xdmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t cubc; + + /* If we are appending a buffer to a linklist, then re-use the previously + * calculated CC register value. Otherwise, create the CC register value + * from the properties of the transfer. + */ + + if (!xdmach->llhead) + { + xdmach->cc = sam_txcc(xdmach); + } + + /* Calculate the number of transfers for CUBC */ + + cubc = sam_cubc(xdmach, nbytes); + cubc |= (CHNEXT_UBC_NVIEW_1 | CHNEXT_UBC_NSEN); + + /* Add the new link list entry */ + + if (!sam_allocdesc(xdmach, xdmach->lltail, maddr, paddr, cubc)) + { + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_rxbuffer + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. + * + ****************************************************************************/ + +static int sam_rxbuffer(struct sam_xdmach_s *xdmach, uint32_t paddr, + uint32_t maddr, size_t nbytes) +{ + uint32_t cubc; + + /* If we are appending a buffer to a linklist, then re-use the previously + * calculated CC register value. Otherwise, create the CC register value + * from the properties of the transfer. + */ + + if (!xdmach->llhead) + { + xdmach->cc = sam_rxcc(xdmach); + } + + /* Calculate the number of transfers for CUBC */ + + cubc = sam_cubc(xdmach, nbytes); + cubc |= (CHNEXT_UBC_NVIEW_1 | CHNEXT_UBC_NSEN); + + /* Add the new link list entry */ + + if (!sam_allocdesc(xdmach, xdmach->lltail, paddr, maddr, cubc)) + { + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: sam_single + * + * Description: + * Start a single buffer DMA. + * + ****************************************************************************/ + +static inline int sam_single(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + struct chnext_view1_s *llhead = xdmach->llhead; + + /* 1. Read the XDMAC Global Channel Status Register (XDMAC_GS) to choose a + * free channel. + * + * In this implementation, the free channel is assigned in a different + * manner. + */ + + /* 2. Clear any pending interrupts from any previous XDMAC transfer by + * reading the XDMAC Channel Interrupt Status Register (CIS). + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* 3. Write the starting source address in the Channel Source Address (CSA) + * Register. + */ + + DEBUGASSERT(llhead != NULL && llhead->csa != 0); + sam_putdmach(xdmach, llhead->csa, SAM_XDMACH_CSA_OFFSET); + + /* 4. Write the starting destination address in the Channel Destination + * Address Register (CDA). + */ + + sam_putdmach(xdmach, llhead->cda, SAM_XDMACH_CDA_OFFSET); + + /* 5. Program field UBLEN in the XDMAC Channel Microblock Control (CUBC) + * Register with the number of data. + */ + + sam_putdmach(xdmach, llhead->cubc, SAM_XDMACH_CUBC_OFFSET); + + /* 6. Program the Channel Control (CC) Register */ + + sam_putdmach(xdmach, xdmach->cc, SAM_XDMACH_CC_OFFSET); + + /* 7. Clear the following five registers: + * + * XDMAC Channel Next Descriptor Control (CNDC) Register + * XDMAC Channel Block Control (CBC) Register + * XDMAC Channel Data Stride Memory Set Pattern (CDSMSP) Register + * XDMAC Channel Source Microblock Stride (CSUS) Register + * XDMAC Channel Destination Microblock Stride (CDUS)Register + * + * This respectively indicates that the linked list is disabled, there is + * only one block and striding is disabled + */ + + sam_putdmach(xdmach, 0, SAM_XDMACH_CNDC_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CBC_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CDSMSP_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CSUS_OFFSET); + sam_putdmach(xdmach, 0, SAM_XDMACH_CDUS_OFFSET); + + /* 8. Enable the Microblock interrupt by setting the "End of Block" + * interrupt bit in the XDMAC Channel Interrupt Enable (CIE) Register. + */ + + sam_putdmach(xdmach, XDMAC_CHINT_BI | XDMAC_CHINT_ERRORS, + SAM_XDMACH_CIE_OFFSET); + + /* Enable the Channel Interrupt Enable bit by setting the corresponding + * bit in the XDMAC Global Interrupt Enable (GIE) Register. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GIE_OFFSET); + + /* 9. Enable the channel by setting the corresponding bit in the + * XDMAC Global Channel Enable (GE) Register. The channel bit will + * be set in the GS register by hardware. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GE_OFFSET); + + /* 10. The DMA has been started. Once completed, the DMA channel sets the + * corresponding "End of Block Interrupt" Status bit in the channel + * CIS register and generates an global interrupt for the channel. + * The channel bit will be cleared in the GS register by hardware. + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_multiple + * + * Description: + * Start a multiple buffer DMA. + * + ****************************************************************************/ + +static inline int sam_multiple(struct sam_xdmach_s *xdmach) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); +#ifdef CONFIG_DEBUG + struct chnext_view1_s *llhead = xdmach->llhead; +#endif + uintptr_t paddr; + uint32_t regval; + + DEBUGASSERT(llhead != NULL && llhead->csa != 0); + + /* 1. Read the XDMAC Global Channel Status Register (XDMAC_GS) to choose a + * free channel. + * + * In this implementation, the free channel is assigned in a different + * manner. + */ + + /* 2. Clear any pending interrupts from any previous XDMAC transfer by + * reading the XDMAC Channel Interrupt Status Register (CIS). + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* 3. Build a linked list of transfer descriptors in memory. The + * descriptor view is programmable on a per descriptor basis. The + * linked list items structure must be word aligned. CUBC NDE + * must be configured to 0 in the last descriptor to terminate the + * list. + * + * This was done during the RX/TX setup phases of the DMA transfer. + */ + + /* Since we are using view1, I imagine that we need to set the Channel + * Control (CC) Register. + */ + + sam_putdmach(xdmach, xdmach->cc, SAM_XDMACH_CC_OFFSET); + + /* 4. Program field NDA in the XDMAC Channel Next Descriptor Address + * (CNDA) Register with the first descriptor address and bit NDAIF + * with the master interface identifier. + * + * REVIST: Using NDAIF=0. Is that correct? + */ + + paddr = sam_physramaddr((uintptr_t)xdmach->llhead); + sam_putdmach(xdmach, (uint32_t)paddr, SAM_XDMACH_CNDA_OFFSET); + + /* 5. Program the CNDC register: + * + * a. Set NDE to enable the descriptor fetch. + * b. Set NDSUP to update the source address at the descriptor fetch + * time, otherwise clear this bit. + * c. Set NDDUP to update the destination address at the descriptor + * fetch time, otherwise clear this bit. + * d. Program the NDVIEW field to define the length of the first + * descriptor. + */ + + regval = (XDMACH_CNDC_NDE | XDMACH_CNDC_NDVIEW_NDV2); + + /* Update the source address if this is a memory-to-* transfer. + * + * TYPE = 0 -> memory-to-memory + * TYPE = 1 && DSYNC = 1 -> memory-to-peripheral + */ + + if ((xdmach->cc & XDMACH_CC_TYPE) == 0 || + (xdmach->cc & XDMACH_CC_DSYNC) != 0) + { + regval |= XDMACH_CNDC_NDSUP; + } + + /* Update the destination address if this is a *-to-memory transfer. + * + * TYPE = 0 -> memory-to-memory + * TYPE = 1 && DSYNC = 0 -> peripheral-to-memory + */ + + if ((xdmach->cc & XDMACH_CC_TYPE) == 0 || + (xdmach->cc & XDMACH_CC_TYPE) == 0) + { + regval |= XDMACH_CNDC_NDDUP; + } + + sam_putdmach(xdmach, regval, SAM_XDMACH_CNDC_OFFSET); + + /* 6. Enable the End of Linked List interrupt by setting the LI bit in the + * CIE register. + */ + + sam_putdmach(xdmach, XDMAC_CHINT_LI | XDMAC_CHINT_ERRORS, + SAM_XDMACH_CIE_OFFSET); + + /* Enable the Channel Interrupt Enable bit by setting the corresponding + * bit in the XDMAC Global Interrupt Enable (GIE) Register. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GIE_OFFSET); + + /* 7. Enable the channel by setting the corresponding bit in the + * XDMAC Global Channel Enable (GE) Register. The channel bit will + * be set in the GS register by hardware. + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GE_OFFSET); + + /* 8. The DMA has been started. Once completed, the DMA channel sets the + * corresponding "End of Block Interrupt" Status bit in the channel + * CIS register and generates an global interrupt for the channel. + * The channel bit will be cleared in the GS register by hardware. + */ + + return OK; +} + +/**************************************************************************** + * Name: sam_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void sam_dmaterminate(struct sam_xdmach_s *xdmach, int result) +{ + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + uint32_t chanbit = XDMAC_CHAN(xdmach->chan); + + /* Disable all channel interrupts */ + + sam_putdmac(xdmac, chanbit, SAM_XDMAC_GID_OFFSET); + sam_putdmach(xdmach, XDMAC_CHINT_ALL, SAM_XDMACH_CID_OFFSET); + + /* Under normal operation, the software enables a channel by setting the + * associated bit in the Global Channel Enable (GE) Register. The hardware + * then disables a channel on transfer completion by clearing channel bit + * in the GS register. To disable a channel, setting the channel bit in the + * GD register and poll the channel bit in GS register to determine when + * the channel has been disabled. + */ + + sam_putdmac(xdmac, chanbit, SAM_XDMAC_GD_OFFSET); + while ((sam_getdmac(xdmac, SAM_XDMAC_GS_OFFSET) & chanbit) != 0); + + /* Free the linklist */ + + sam_freelinklist(xdmach); + + /* Perform the DMA complete callback */ + + if (xdmach->callback) + { + xdmach->callback((DMA_HANDLE)xdmach, xdmach->arg, result); + } + + xdmach->callback = NULL; + xdmach->arg = NULL; +} + +/**************************************************************************** + * Name: sam_xdmac_interrupt + * + * Description: + * DMA interrupt handler + * + ****************************************************************************/ + +static int sam_xdmac_interrupt(int irq, void *context) +{ + struct sam_xdmac_s *xdmac = &g_xdmac; + struct sam_xdmach_s *xdmach; + unsigned int chndx; + uint32_t gpending; + uint32_t chpending; + uint32_t bit; + + /* Get the set of pending, unmasked global XDMAC interrupts */ + + gpending = sam_getdmac(xdmac, SAM_XDMAC_GIS_OFFSET) & + sam_getdmac(xdmac, SAM_XDMAC_GIM_OFFSET); + + /* Yes.. Check each bit to see which channel(s) have interrupted */ + + for (chndx = 0; chndx < SAMV7_NDMACHAN && gpending != 0; chndx++) + { + /* Are any interrupts pending for this channel? */ + + bit = XDMAC_CHAN(chndx); + if ((gpending & bit) != 0) + { + xdmach = &g_xdmach[chndx]; + + /* Get the set of interrupts pending for this channel */ + + chpending = sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET) & + sam_getdmach(xdmach, SAM_XDMACH_CIM_OFFSET); + + /* Yes.. Did an error occur? */ + + if ((chpending & XDMAC_CHINT_ERRORS) != 0) + { + /* Yes... Terminate the transfer with an error? */ + + dmalldbg("ERROR: DMA failed: %08x\n", chpending); + sam_dmaterminate(xdmach, -EIO); + } + + /* Is the transfer complete? */ + + else if ((chpending & (XDMAC_CHINT_BI | XDMAC_CHINT_LI)) != 0) + { + /* Yes.. Terminate the transfer with success */ + + sam_dmaterminate(xdmach, OK); + } + + /* Else what? */ + + else + { + dmalldbg("ERROR: Unexpected interrupt: %08x\n", chpending); + DEBUGPANIC(); + } + + /* Clear the bit in the sampled set of pending global interrupts */ + + gpending &= !bit; + } + } + + return OK; +} + +/**************************************************************************** + * Name: sam_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmainitialize(struct sam_xdmac_s *xdmac) +{ + /* Disable all DMA interrupts */ + + sam_putdmac(xdmac, XDMAC_CHAN_ALL, SAM_XDMAC_GID_OFFSET); + + /* Disable all DMA channels */ + + sam_putdmac(xdmac, XDMAC_CHAN_ALL, SAM_XDMAC_GD_OFFSET); + + /* Initialize semaphores */ + + sem_init(&xdmac->chsem, 0, 1); + sem_init(&xdmac->dsem, 0, SAMV7_NDMACHAN); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + dmallvdbg("Initialize XDMAC\n"); + + /* Enable peripheral clock */ + + sam_xdmac_enableclk(); + + /* Attach DMA interrupt vector */ + + (void)irq_attach(SAM_IRQ_XDMAC, sam_xdmac_interrupt); + + /* Initialize the controller */ + + sam_dmainitialize(&g_xdmac); + + /* Enable the IRQ at the AIC (still disabled at the DMA controller) */ + + up_enable_irq(SAM_IRQ_XDMAC); +} + +/**************************************************************************** + * Name: sam_dmachannel + * + * Allocate a DMA channel. This function sets aside a DMA channel then + * gives the caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is + * the 'peripheral' and the other is 'memory'. Howerver, the interface + * could still be used if, for example, both sides were memory although + * the naming would be awkward. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* + * DMA channel handle. NULL is returned on any failure. + * + ****************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags) +{ + struct sam_xdmac_s *xdmac = &g_xdmac; + struct sam_xdmach_s *xdmach; + unsigned int chndx; + + /* Search for an available DMA channel with at least the requested FIFO + * size. + */ + + xdmach = NULL; + sam_takechsem(xdmac); + for (chndx = 0; chndx < SAMV7_NDMACHAN; chndx++) + { + struct sam_xdmach_s *candidate = &g_xdmach[chndx]; + if (!candidate->inuse) + { + xdmach = candidate; + xdmach->inuse = true; + + /* Clear the pending Interrupt Status bits by reading the XDMAC + * Channel Interrupt Status (CIS) Register + */ + + (void)sam_getdmach(xdmach, SAM_XDMACH_CIS_OFFSET); + + /* Disable the channel by writing one to the write-only Global + * Channel Disable (GD) Register + */ + + sam_putdmac(xdmac, XDMAC_CHAN(chndx), SAM_XDMAC_GD_OFFSET); + + /* Set the DMA channel flags. */ + + xdmach->flags = chflags; + break; + } + } + + sam_givechsem(xdmac); + + /* Show the result of the allocation */ + + if (xdmach) + { + dmavdbg("XDMAC%d CH%d: chflags: %08x returning xdmach: %p\n", + (int)dmacno, xdmach->chan, (int)chflags, xdmach); + } + else + { + dmadbg("ERROR: Failed allocate XDMAC%d channel\n", (int)dmacno); + } + + return (DMA_HANDLE)xdmach; +} + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + + /* Set the new DMA channel flags. */ + + xdmach->flags = chflags; + dmavdbg("XDMAC CH%d: chflags: %08x\n", xdmach->chan, (int)chflags); +} + +/**************************************************************************** + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until sam_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + struct sam_xdmac_s *xdmac; + + dmavdbg("xdmach: %p\n", xdmach); + DEBUGASSERT((xdmach != NULL) && (xdmach->inuse)); + + xdmac = sam_controller(xdmach); + + /* Make sure that the channel is disabled by writing one to the write-only + * Global Channel Disable (GD) Register + */ + + sam_putdmac(xdmac, XDMAC_CHAN(xdmach->chan), SAM_XDMAC_GD_OFFSET); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + xdmach->flags = 0; + xdmach->inuse = false; /* No longer in use */ +} + +/**************************************************************************** + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("xdmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + xdmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(xdmach); + dmavdbg("llhead: %p lltail: %p\n", xdmach->llhead, xdmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(xdmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_txbuffer(xdmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_txbuffer(xdmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was not an RX transfer. + */ + + xdmach->rx = false; + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This + * function may be called multiple times to handle large and/or dis- + * continuous transfers. Calls to sam_dmatxsetup() and sam_dmarxsetup() + * must not be intermixed on the same transfer, however. + * + ****************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t nbytes) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + size_t maxtransfer; + size_t remaining; + int ret = OK; + + dmavdbg("xdmach: %p paddr: %08x maddr: %08x nbytes: %d\n", + xdmach, (int)paddr, (int)maddr, (int)nbytes); + DEBUGASSERT(xdmach); + dmavdbg("llhead: %p lltail: %p\n", xdmach->llhead, xdmach->lltail); + + /* The maximum transfer size in bytes depends upon the maximum number of + * transfers and the number of bytes per transfer. + */ + + maxtransfer = sam_maxtransfer(xdmach); + remaining = nbytes; + + /* If this is a large transfer, break it up into smaller buffers */ + + while (remaining > maxtransfer) + { + /* Set up the maximum size transfer */ + + ret = sam_rxbuffer(xdmach, paddr, maddr, maxtransfer); + if (ret == OK); + { + /* Decrement the number of bytes left to transfer */ + + remaining -= maxtransfer; + + /* Increment the memory & peripheral address (if it is appropriate to + * do so). + */ + + if ((xdmach->flags & DMACH_FLAG_PERIPHINCREMENT) != 0) + { + paddr += maxtransfer; + } + + if ((xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0) + { + maddr += maxtransfer; + } + } + } + + /* Then set up the final buffer transfer */ + + if (ret == OK && remaining > 0) + { + ret = sam_rxbuffer(xdmach, paddr, maddr, remaining); + } + + /* Save an indication so that the DMA interrupt completion logic will know + * that this was an RX transfer and will invalidate the cache. + */ + + xdmach->rx = true; + xdmach->rxaddr = maddr; + xdmach->rxsize = (xdmach->flags & DMACH_FLAG_MEMINCREMENT) != 0 ? nbytes : sizeof(uint32_t); + + /* Clean caches associated with the DMA memory */ + + arch_clean_dcache(maddr, maddr + nbytes); + return ret; +} + +/**************************************************************************** + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + int ret = -EINVAL; + + dmavdbg("xdmach: %p callback: %p arg: %p\n", xdmach, callback, arg); + DEBUGASSERT(xdmach != NULL); + + /* Verify that the DMA has been setup (i.e., at least one entry in the + * link list). + */ + + if (xdmach->llhead) + { + /* Save the callback info. This will be invoked when the DMA completes */ + + xdmach->callback = callback; + xdmach->arg = arg; + + /* If this is an RX DMA (peripheral-to-memory), then flush and + * invalidate the data cache to force reloading from memory when the + * DMA completes. + */ + + if (xdmach->rx) + { + arch_flush_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize); + } + + /* Is this a single block transfer? Or a multiple block transfer? */ + + if (xdmach->llhead == xdmach->lltail) + { + ret = sam_single(xdmach); + } + else + { + ret = sam_multiple(xdmach); + } + } + + return ret; +} + +/**************************************************************************** + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is + * reset and sam_dmarx/txsetup() must be called before sam_dmastart() can be + * called again + * + ****************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + irqstate_t flags; + + dmavdbg("xdmach: %p\n", xdmach); + DEBUGASSERT(xdmach != NULL); + + flags = enter_critical_section(); + sam_dmaterminate(xdmach, -EINTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + struct sam_xdmac_s *xdmac = sam_controller(xdmach); + irqstate_t flags; + + /* Sample global registers. NOTE: reading GIS clears interrupts, but + * that should be okay IF interrupts are enabled when this function is + * called. But there is a race condition where this instrumentation could + * cause lost interrupts. + */ + + flags = enter_critical_section(); + + regs->gtype = sam_getdmac(xdmac, SAM_XDMAC_GTYPE_OFFSET); + regs->gcfg = sam_getdmac(xdmac, SAM_XDMAC_GCFG_OFFSET); + regs->gwac = sam_getdmac(xdmac, SAM_XDMAC_GWAC_OFFSET); + regs->gim = sam_getdmac(xdmac, SAM_XDMAC_GIM_OFFSET); + regs->gs = sam_getdmac(xdmac, SAM_XDMAC_GS_OFFSET); + regs->grs = sam_getdmac(xdmac, SAM_XDMAC_GRS_OFFSET); + regs->gws = sam_getdmac(xdmac, SAM_XDMAC_GWS_OFFSET); + regs->gsws = sam_getdmac(xdmac, SAM_XDMAC_GSWS_OFFSET); + + /* Sample channel registers */ + + regs->cim = sam_getdmach(xdmach, SAM_XDMACH_CIM_OFFSET); + regs->csa = sam_getdmach(xdmach, SAM_XDMACH_CSA_OFFSET); + regs->cda = sam_getdmach(xdmach, SAM_XDMACH_CDA_OFFSET); + regs->cnda = sam_getdmach(xdmach, SAM_XDMACH_CNDA_OFFSET); + regs->cndc = sam_getdmach(xdmach, SAM_XDMACH_CNDC_OFFSET); + regs->cubc = sam_getdmach(xdmach, SAM_XDMACH_CUBC_OFFSET); + regs->cbc = sam_getdmach(xdmach, SAM_XDMACH_CBC_OFFSET); + regs->cc = sam_getdmach(xdmach, SAM_XDMACH_CC_OFFSET); + regs->cdsmsp = sam_getdmach(xdmach, SAM_XDMACH_CDSMSP_OFFSET); + regs->csus = sam_getdmach(xdmach, SAM_XDMACH_CSUS_OFFSET); + regs->cdus = sam_getdmach(xdmach, SAM_XDMACH_CDUS_OFFSET); + + leave_critical_section(flags); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by sam_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, + const char *msg) +{ + struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle; + + dmadbg("%s\n", msg); + dmadbg(" DMA Global Registers:\n"); + dmadbg(" GTYPE[%08x]: %08x\n", SAM_XDMAC_GTYPE, regs->gtype); + dmadbg(" GCFG[%08x]: %08x\n", SAM_XDMAC_GCFG, regs->gcfg); + dmadbg(" GWAC[%08x]: %08x\n", SAM_XDMAC_GWAC, regs->gwac); + dmadbg(" GIM[%08x]: %08x\n", SAM_XDMAC_GIM, regs->gim); + dmadbg(" GS[%08x]: %08x\n", SAM_XDMAC_GS, regs->gs); + dmadbg(" GRS[%08x]: %08x\n", SAM_XDMAC_GRS, regs->grs); + dmadbg(" GWS[%08x]: %08x\n", SAM_XDMAC_GWS, regs->gws); + dmadbg(" GSWS[%08x]: %08x\n", SAM_XDMAC_GSWS, regs->gsws); + dmadbg(" DMA Channel Registers:\n"); + dmadbg(" CIM[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CIM_OFFSET, regs->cim); + dmadbg(" CSA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CSA_OFFSET, regs->csa); + dmadbg(" CDA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDA_OFFSET, regs->cda); + dmadbg(" CNDA[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CNDA_OFFSET, regs->cnda); + dmadbg(" CNDC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CNDC_OFFSET, regs->cndc); + dmadbg(" CUBC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CUBC_OFFSET, regs->cubc); + dmadbg(" CBC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CBC_OFFSET, regs->cbc); + dmadbg(" CC[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CC_OFFSET, regs->cc); + dmadbg(" CDSMSP[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDSMSP_OFFSET, regs->cdsmsp); + dmadbg(" CSUS[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CSUS_OFFSET, regs->csus); + dmadbg(" CDUS[%08x]: %08x\n", xdmach->base + SAM_XDMACH_CDUS_OFFSET, regs->cdus); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_SAMV7_XDMAC */ diff --git a/arch/arm/src/samv7/sam_xdmac.h b/arch/arm/src/samv7/sam_xdmac.h new file mode 100644 index 0000000000000000000000000000000000000000..fe98581d08b7ecad25863eafbd2a630f483b7456 --- /dev/null +++ b/arch/arm/src/samv7/sam_xdmac.h @@ -0,0 +1,371 @@ +/************************************************************************************ + * arch/arm/src/samv7/sam_dmac.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_XDMAC_H +#define __ARCH_ARM_SRC_SAMV7_SAM_XDMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +#endif + +/* DMA ******************************************************************************/ + +/* Flags used to characterize the DMA channel. The naming convention is that one + * side is the peripheral and the other is memory (however, the interface could still + * be used if, for example, both sides were memory although the naming would be + * awkward) + * + * Encoding: + * + * .... .... .... MMMM .PPP PPPP PPPP PPPP + * .... .... .... .... .... .... .... .... Configurable properties of the channel + * .... .... .... .... .PPP PPPP PPPP PPPP Peripheral endpoint characteristics + * .... .... .... MMMM .... .... .... .... Memory endpoint characteristics + */ + +/* Bits 0-1: Configurable properties of the channel + * + * .... .... .... .... .... .... .... .... Configurable properties of the channel + * + * NOTE: Many "peripheral" attributes are really "channel" attributes for + * the samv7D4's XDMAC since it does not support peripheral-to-peripheral + * DMA. + */ + +# define DMACH_FLAG_FIFOCFG_LARGEST (0) /* No FIFO controls */ +# define DMACH_FLAG_FIFOCFG_HALF (0) +# define DMACH_FLAG_FIFOCFG_SINGLE (0) + +/* Bits 0-15: Peripheral endpoint characteristics + * + * .... .... .... .... .PPP PPPP PPPP PPPP Peripheral endpoint characteristics + * .... .... .... .... .... .... .III IIII Peripheral ID, range 0-67 + * .... .... .... .... .... .... .... .... No HW Handshaking + * .... .... .... .... .... .... P... .... 0=memory; 1=peripheral + * .... .... .... .... .... ...N .... .... Peripheral ABH layer number + * .... .... .... .... .... .WW. .... .... Peripheral width + * .... .... .... .... .... A... .... .... Auto-increment peripheral address + * .... .... .... .... .SSS .... .... .... Peripheral chunk size + */ + +#define DMACH_FLAG_PERIPHPID_SHIFT (0) /* Bits 0-7: Peripheral PID */ +#define DMACH_FLAG_PERIPHPID_MASK (0x7f << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID(n) ((uint32_t)(n) << DMACH_FLAG_PERIPHPID_SHIFT) +# define DMACH_FLAG_PERIPHPID_MAX DMACH_FLAG_PERIPHPID_MASK +#define DMACH_FLAG_PERIPHH2SEL (0) /* No HW handshaking */ +#define DMACH_FLAG_PERIPHIS_MASK (1 << 7) /* Bit 7: Peripheral type */ +# define DMACH_FLAG_PERIPHISPERIPH (1 << 7) /* Bit 7: 1 = Peripheral */ +# define DMACH_FLAG_PERIPHISMEMORY (0 << 7) /* Bit 7: 0 = Memory */ +#define DMACH_FLAG_PERIPHAHB_MASK (1 << 8) /* Bit 8: Peripheral ABH layer 1 */ +# define DMACH_FLAG_PERIPHAHB_AHB_IF0 (0) +# define DMACH_FLAG_PERIPHAHB_AHB_IF1 DMACH_FLAG_PERIPHAHB_MASK +#define DMACH_FLAG_PERIPHWIDTH_SHIFT (9) /* Bits 9-10: Peripheral width */ +#define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) +# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */ +# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */ +# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */ +# define DMACH_FLAG_PERIPHWIDTH_64BITS (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 64 bits */ +#define DMACH_FLAG_PERIPHINCREMENT (1 << 11) /* Bit 11: Auto-increment peripheral address */ +#define DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT (12) /* Bits 12-14: Peripheral chunk size */ +#define DMACH_FLAG_PERIPHCHUNKSIZE_MASK (7 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) +# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=1 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_2 (1 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* No chunksize=2 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_4 (2 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=4 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_8 (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=8 */ +# define DMACH_FLAG_PERIPHCHUNKSIZE_16 (4 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize=16 */ + +/* Bits 16-19: Memory endpoint characteristics + * + * .... .... .... MMMM .... .... .... .... Memory endpoint characteristics + * .... .... .... .... .... .... .... .... No memory peripheral ID, range 0-49 + * .... .... .... .... .... .... .... .... No HW Handshaking + * .... .... .... .... .... .... .... .... No peripheral-to-peripheral + * .... .... .... ...N .... .... .... .... Memory ABH layer number + * .... .... .... .... .... .... .... .... No memory width + * .... .... .... ..A. .... .... .... .... Auto-increment memory address + * .... .... .... .... .... .... .... .... No memory chunk size + * .... .... .... BB.. .... .... .... .... Memory burst size + */ + +#define DMACH_FLAG_MEMPID(n) (0) /* No memory peripheral identifier */ +# define DMACH_FLAG_MEMPID_MAX (0) +#define DMACH_FLAG_MEMH2SEL (0) /* No HW handshaking */ +#define DMACH_FLAG_MEMISPERIPH (0) /* No peripheral-to-peripheral */ +#define DMACH_FLAG_MEMAHB_MASK (1 << 16) /* Bit 16: Memory ABH layer 1 */ +# define DMACH_FLAG_MEMAHB_AHB_IF0 (0) +# define DMACH_FLAG_MEMAHB_AHB_IF1 DMACH_FLAG_MEMAHB_MASK + +#define DMACH_FLAG_MEMWIDTH_8BITS (0) /* Only peripheral data width */ +#define DMACH_FLAG_MEMWIDTH_16BITS (0) +#define DMACH_FLAG_MEMWIDTH_32BITS (0) +#define DMACH_FLAG_MEMWIDTH_64BITS (0) + +#define DMACH_FLAG_MEMINCREMENT (1 << 17) /* Bit 17: Auto-increment memory address */ + +#define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Only peripheral chunk size */ +#define DMACH_FLAG_MEMCHUNKSIZE_2 (0) +#define DMACH_FLAG_MEMCHUNKSIZE_4 (0) +#define DMACH_FLAG_MEMCHUNKSIZE_8 (0) +#define DMACH_FLAG_MEMCHUNKSIZE_16 (0) + +#define DMACH_FLAG_MEMBURST_SHIFT (18) /* Bits 18-19: Memory burst size */ +#define DMACH_FLAG_MEMBURST_MASK (3 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_1 (0 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_4 (1 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_8 (2 << DMACH_FLAG_MEMBURST_SHIFT) +# define DMACH_FLAG_MEMBURST_16 (3 << DMACH_FLAG_MEMBURST_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct sam_dmaregs_s +{ + /* Global Registers. + * + * This includes all readable global XDMAC registers except for the global + * interrupt status register (XDMAC_GIS). Reading from the status + * register could cause loss of interrupts. + */ + + uint32_t gtype; /* Global Type Register */ + uint32_t gcfg; /* Global Configuration Register */ + uint32_t gwac; /* Global Weighted Arbiter Configuration Register */ + uint32_t gim; /* Global Interrupt Mask Register */ + uint32_t gs; /* Global Channel Status Register */ + uint32_t grs; /* Global Channel Read Suspend Register */ + uint32_t gws; /* Global Channel Write Suspend Register */ + uint32_t gsws; /* Global Channel Software Request Status Register */ + + /* Channel Registers + * + * This includes all readable XDMAC channel registers except for the + * channel interrupt status register (XDMAC_CIS). Reading from the status + * register could cause loss of interrupts. + */ + + uint32_t cim; /* Channel Interrupt Mask Register */ + uint32_t csa; /* Channel Source Address Register */ + uint32_t cda; /* Channel Destination Address Register */ + uint32_t cnda; /* Channel Next Descriptor Address Register */ + uint32_t cndc; /* Channel Next Descriptor Control Register */ + uint32_t cubc; /* Channel Microblock Control Register */ + uint32_t cbc; /* Channel Block Control Register */ + uint32_t cc; /* Channel Configuration Register */ + uint32_t cdsmsp; /* Channel Data Stride Memory Set Pattern */ + uint32_t csus; /* Channel Source Microblock Stride */ + uint32_t cdus; /* Channel Destination Microblock Stride */ +}; +#endif /* CONFIG_DEBUG_DMA */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel then gives the + * caller exclusive access to the DMA channel. + * + * The naming convention in all of the DMA interfaces is that one side is the + * 'peripheral' and the other is 'memory'. However, the interface could still + * be used if, for example, both sides were memory although the naming would be + * awkward. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* DMA + * channel handle. NULL is returned on any failure. + * + ************************************************************************************/ + +DMA_HANDLE sam_dmachannel(uint8_t dmacno, uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmaconfig + * + * Description: + * There are two channel usage models: (1) The channel is allocated and configured + * in one step. This is the typical case where a DMA channel performs a constant + * role. The alternative is (2) where the DMA channel is reconfigured on the fly. + * In this case, the chflags provided to sam_dmachannel are not used and + * sam_dmaconfig() is called before each DMA to configure the DMA channel + * appropriately. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmaconfig(DMA_HANDLE handle, uint32_t chflags); + +/************************************************************************************ + * Name: sam_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be + * used again until sam_dmachannel() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ************************************************************************************/ + +void sam_dmafree(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmatxsetup + * + * Description: + * Configure DMA for transmit of one buffer (memory to peripheral). This function + * may be called multiple times to handle large and/or discontinuous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes); + +/************************************************************************************ + * Name: sam_dmarxsetup + * + * Description: + * Configure DMA for receipt of one buffer (peripheral to memory). This function + * may be called multiple times to handle large and/or discontinuous transfers. + * Calls to sam_dmatxsetup() and sam_dmarxsetup() must not be intermixed on the + * same transfer, however. + * + ************************************************************************************/ + +int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes); + +/************************************************************************************ + * Name: sam_dmastart + * + * Description: + * Start the DMA transfer + * + ************************************************************************************/ + +int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/************************************************************************************ + * Name: sam_dmastop + * + * Description: + * Cancel the DMA. After sam_dmastop() is called, the DMA channel is reset and + * sam_dmarx/txsetup() must be called before sam_dmastart() can be called again + * + ************************************************************************************/ + +void sam_dmastop(DMA_HANDLE handle); + +/************************************************************************************ + * Name: sam_dmasample + * + * Description: + * Sample DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs); +#else +# define sam_dmasample(handle,regs) +#endif + +/************************************************************************************ + * Name: sam_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, const char *msg); +#else +# define sam_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_XDMAC_H */ diff --git a/arch/arm/src/samv7/same70_periphclks.h b/arch/arm/src/samv7/same70_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..bf0dd59677f740672cc5b9b37cf11c4abffdd550 --- /dev/null +++ b/arch/arm/src/samv7/same70_periphclks.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/arm/src/samv7/same70_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAME70_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMV7_SAME70_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() +#define sam_rstc_enableclk() +#define sam_rtc_enableclk() +#define sam_rtt_enableclk() +#define sam_wdt0_enableclk() +#define sam_pmc_enableclk() +#define sam_efc_enableclk() + +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_hsmci0_enableclk() sam_enableperiph0(SAM_PID_HSMCI0) +#define sam_twihs0_enableclk() sam_enableperiph0(SAM_PID_TWIHS0) +#define sam_twihs1_enableclk() sam_enableperiph0(SAM_PID_TWIHS1) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_ssc_enableclk() sam_enableperiph0(SAM_PID_SSC0) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph0(SAM_PID_TC5) +#define sam_afec0_enableclk() sam_enableperiph0(SAM_PID_AFEC0) +#define sam_dacc_enableclk() sam_enableperiph0(SAM_PID_DACC) +#define sam_pwm0_enableclk() sam_enableperiph0(SAM_PID_PWM0) + +#define sam_icm_enableclk() sam_enableperiph1(SAM_PID_ICM) +#define sam_acc_enableclk() sam_enableperiph1(SAM_PID_ACC) +#define sam_usbhs_enableclk() sam_enableperiph1(SAM_PID_USBHS) +#define sam_mcan00_enableclk() sam_enableperiph1(SAM_PID_MCAN00) +#define sam_mcan01_enableclk() +#define sam_mcan10_enableclk() sam_enableperiph1(SAM_PID_MCAN10) +#define sam_mcan11_enableclk() +#define sam_emac0_enableclk() sam_enableperiph1(SAM_PID_EMAC0) +#define sam_afec1_enableclk() sam_enableperiph1(SAM_PID_AFEC1) +#define sam_twihs2_enableclk() sam_enableperiph1(SAM_PID_TWIHS2) +#define sam_spi1_enableclk() sam_enableperiph1(SAM_PID_SPI1) +#define sam_qspi_enableclk() sam_enableperiph1(SAM_PID_QSPI) +#define sam_uart2_enableclk() sam_enableperiph1(SAM_PID_UART2) +#define sam_uart3_enableclk() sam_enableperiph1(SAM_PID_UART3) +#define sam_uart4_enableclk() sam_enableperiph1(SAM_PID_UART4) +#define sam_tc6_enableclk() sam_enableperiph1(SAM_PID_TC6) +#define sam_tc7_enableclk() sam_enableperiph1(SAM_PID_TC7) +#define sam_tc8_enableclk() sam_enableperiph1(SAM_PID_TC8) +#define sam_tc9_enableclk() sam_enableperiph1(SAM_PID_TC9) +#define sam_tc10_enableclk() sam_enableperiph1(SAM_PID_TC10) +#define sam_tc11_enableclk() sam_enableperiph1(SAM_PID_TC11) +#define sam_aes_enableclk() sam_enableperiph1(SAM_PID_AES) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_xdmac_enableclk() sam_enableperiph1(SAM_PID_XDMAC) +#define sam_isi_enableclk() sam_enableperiph1(SAM_PID_ISI) +#define sam_pwm1_enableclk() sam_enableperiph1(SAM_PID_PWM1) +#define sam_fpu_enableclk() +#define sam_sdramc_enableclk() sam_enableperiph1(SAM_PID_SDRAMC) /* REVISIT: Does this exist? */ +#define sam_wdt1_enableclk() + +#define sam_ccw_enableclk() + +#define sam_supc_disableclk() +#define sam_rstc_disableclk() +#define sam_rtc_disableclk() +#define sam_rtt_disableclk() +#define sam_wdt0_disableclk() +#define sam_pmc_disableclk() +#define sam_efc_disableclk() + +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_hsmci0_disableclk() sam_disableperiph0(SAM_PID_HSMCI0) +#define sam_twihs0_disableclk() sam_disableperiph0(SAM_PID_TWIHS0) +#define sam_twihs1_disableclk() sam_disableperiph0(SAM_PID_TWIHS1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_ssc_disableclk() sam_disableperiph0(SAM_PID_SSC0) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph0(SAM_PID_TC5) +#define sam_afec0_disableclk() sam_disableperiph0(SAM_PID_AFEC0) +#define sam_dacc_disableclk() sam_disableperiph0(SAM_PID_DACC) +#define sam_pwm0_disableclk() sam_disableperiph0(SAM_PID_PWM0) + +#define sam_icm_disableclk() sam_disableperiph1(SAM_PID_ICM) +#define sam_acc_disableclk() sam_disableperiph1(SAM_PID_ACC) +#define sam_usbhs_disableclk() sam_disableperiph1(SAM_PID_USBHS) +#define sam_mcan00_disableclk() sam_disableperiph1(SAM_PID_MCAN00) +#define sam_mcan01_disableclk() +#define sam_mcan10_disableclk() sam_disableperiph1(SAM_PID_MCAN10) +#define sam_mcan11_disableclk() +#define sam_emac0_disableclk() sam_disableperiph1(SAM_PID_EMAC0) +#define sam_afec1_disableclk() sam_disableperiph1(SAM_PID_AFEC1) +#define sam_twihs2_disableclk() sam_disableperiph1(SAM_PID_TWIHS2) +#define sam_spi1_disableclk() sam_disableperiph1(SAM_PID_SPI1) +#define sam_qspi_disableclk() sam_disableperiph1(SAM_PID_QSPI) +#define sam_uart2_disableclk() sam_disableperiph1(SAM_PID_UART2) +#define sam_uart3_disableclk() sam_disableperiph1(SAM_PID_UART3) +#define sam_uart4_disableclk() sam_disableperiph1(SAM_PID_UART4) +#define sam_tc6_disableclk() sam_disableperiph1(SAM_PID_TC6) +#define sam_tc7_disableclk() sam_disableperiph1(SAM_PID_TC7) +#define sam_tc8_disableclk() sam_disableperiph1(SAM_PID_TC8) +#define sam_tc9_disableclk() sam_disableperiph1(SAM_PID_TC9) +#define sam_tc10_disableclk() sam_disableperiph1(SAM_PID_TC10) +#define sam_tc11_disableclk() sam_disableperiph1(SAM_PID_TC11) +#define sam_aes_disableclk() sam_disableperiph1(SAM_PID_AES) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_xdmac_disableclk() sam_disableperiph1(SAM_PID_XDMAC) +#define sam_isi_disableclk() sam_disableperiph1(SAM_PID_ISI) +#define sam_pwm1_disableclk() sam_disableperiph1(SAM_PID_PWM1) +#define sam_fpu_disableclk() +#define sam_sdramc_disableclk() sam_disableperiph1(SAM_PID_SDRAMC) /* REVISIT: Does this exist? */ +#define sam_wdt1_disableclk() + +#define sam_ccw_disableclk() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAME70_PERIPHCLKS_H */ diff --git a/arch/arm/src/samv7/samv71_periphclks.h b/arch/arm/src/samv7/samv71_periphclks.h new file mode 100644 index 0000000000000000000000000000000000000000..91f078fcbbdf5563bb088f2b20e305f90d1f408a --- /dev/null +++ b/arch/arm/src/samv7/samv71_periphclks.h @@ -0,0 +1,227 @@ +/************************************************************************************ + * arch/arm/src/samv7/samv71_periphclks.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAMV71_PERIPHCLKS_H +#define __ARCH_ARM_SRC_SAMV7_SAMV71_PERIPHCLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "chip/sam_pmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helper macros */ + +#define sam_enableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCER0) +#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1) +#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PCDR0) +#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCDR1) + +#define sam_supc_enableclk() +#define sam_rstc_enableclk() +#define sam_rtc_enableclk() +#define sam_rtt_enableclk() +#define sam_wdt0_enableclk() +#define sam_pmc_enableclk() +#define sam_efc_enableclk() + +#define sam_uart0_enableclk() sam_enableperiph0(SAM_PID_UART0) +#define sam_uart1_enableclk() sam_enableperiph0(SAM_PID_UART1) +#define sam_smc_enableclk() sam_enableperiph0(SAM_PID_SMC) +#define sam_pioa_enableclk() sam_enableperiph0(SAM_PID_PIOA) +#define sam_piob_enableclk() sam_enableperiph0(SAM_PID_PIOB) +#define sam_pioc_enableclk() sam_enableperiph0(SAM_PID_PIOC) +#define sam_usart0_enableclk() sam_enableperiph0(SAM_PID_USART0) +#define sam_usart1_enableclk() sam_enableperiph0(SAM_PID_USART1) +#define sam_usart2_enableclk() sam_enableperiph0(SAM_PID_USART2) +#define sam_piod_enableclk() sam_enableperiph0(SAM_PID_PIOD) +#define sam_pioe_enableclk() sam_enableperiph0(SAM_PID_PIOE) +#define sam_hsmci0_enableclk() sam_enableperiph0(SAM_PID_HSMCI0) +#define sam_twihs0_enableclk() sam_enableperiph0(SAM_PID_TWIHS0) +#define sam_twihs1_enableclk() sam_enableperiph0(SAM_PID_TWIHS1) +#define sam_spi0_enableclk() sam_enableperiph0(SAM_PID_SPI0) +#define sam_ssc_enableclk() sam_enableperiph0(SAM_PID_SSC0) +#define sam_tc0_enableclk() sam_enableperiph0(SAM_PID_TC0) +#define sam_tc1_enableclk() sam_enableperiph0(SAM_PID_TC1) +#define sam_tc2_enableclk() sam_enableperiph0(SAM_PID_TC2) +#define sam_tc3_enableclk() sam_enableperiph0(SAM_PID_TC3) +#define sam_tc4_enableclk() sam_enableperiph0(SAM_PID_TC4) +#define sam_tc5_enableclk() sam_enableperiph0(SAM_PID_TC5) +#define sam_afec0_enableclk() sam_enableperiph0(SAM_PID_AFEC0) +#define sam_dacc_enableclk() sam_enableperiph0(SAM_PID_DACC) +#define sam_pwm0_enableclk() sam_enableperiph0(SAM_PID_PWM0) + +#define sam_icm_enableclk() sam_enableperiph1(SAM_PID_ICM) +#define sam_acc_enableclk() sam_enableperiph1(SAM_PID_ACC) +#define sam_usbhs_enableclk() sam_enableperiph1(SAM_PID_USBHS) +#define sam_mcan00_enableclk() sam_enableperiph1(SAM_PID_MCAN00) +#define sam_mcan01_enableclk() +#define sam_mcan10_enableclk() sam_enableperiph1(SAM_PID_MCAN10) +#define sam_mcan11_enableclk() +#define sam_emac0_enableclk() sam_enableperiph1(SAM_PID_EMAC0) +#define sam_afec1_enableclk() sam_enableperiph1(SAM_PID_AFEC1) +#define sam_twihs2_enableclk() sam_enableperiph1(SAM_PID_TWIHS2) +#define sam_spi1_enableclk() sam_enableperiph1(SAM_PID_SPI1) +#define sam_qspi_enableclk() sam_enableperiph1(SAM_PID_QSPI) +#define sam_uart2_enableclk() sam_enableperiph1(SAM_PID_UART2) +#define sam_uart3_enableclk() sam_enableperiph1(SAM_PID_UART3) +#define sam_uart4_enableclk() sam_enableperiph1(SAM_PID_UART4) +#define sam_tc6_enableclk() sam_enableperiph1(SAM_PID_TC6) +#define sam_tc7_enableclk() sam_enableperiph1(SAM_PID_TC7) +#define sam_tc8_enableclk() sam_enableperiph1(SAM_PID_TC8) +#define sam_tc9_enableclk() sam_enableperiph1(SAM_PID_TC9) +#define sam_tc10_enableclk() sam_enableperiph1(SAM_PID_TC10) +#define sam_tc11_enableclk() sam_enableperiph1(SAM_PID_TC11) +#define sam_mlb0_enableclk() sam_enableperiph1(SAM_PID_MLB0) +#define sam_mlb1_enableclk() +#define sam_aes_enableclk() sam_enableperiph1(SAM_PID_AES) +#define sam_trng_enableclk() sam_enableperiph1(SAM_PID_TRNG) +#define sam_xdmac_enableclk() sam_enableperiph1(SAM_PID_XDMAC) +#define sam_isi_enableclk() sam_enableperiph1(SAM_PID_ISI) +#define sam_pwm1_enableclk() sam_enableperiph1(SAM_PID_PWM1) +#define sam_fpu_enableclk() +#define sam_sdramc_enableclk() sam_enableperiph1(SAM_PID_SDRAMC) /* REVISIT: Does this exist? */ +#define sam_wdt1_enableclk() + +#define sam_ccw_enableclk() + +#define sam_supc_disableclk() +#define sam_rstc_disableclk() +#define sam_rtc_disableclk() +#define sam_rtt_disableclk() +#define sam_wdt0_disableclk() +#define sam_pmc_disableclk() +#define sam_efc_disableclk() + +#define sam_uart0_disableclk() sam_disableperiph0(SAM_PID_UART0) +#define sam_uart1_disableclk() sam_disableperiph0(SAM_PID_UART1) +#define sam_smc_disableclk() sam_disableperiph0(SAM_PID_SMC) +#define sam_pioa_disableclk() sam_disableperiph0(SAM_PID_PIOA) +#define sam_piob_disableclk() sam_disableperiph0(SAM_PID_PIOB) +#define sam_pioc_disableclk() sam_disableperiph0(SAM_PID_PIOC) +#define sam_usart0_disableclk() sam_disableperiph0(SAM_PID_USART0) +#define sam_usart1_disableclk() sam_disableperiph0(SAM_PID_USART1) +#define sam_usart2_disableclk() sam_disableperiph0(SAM_PID_USART2) +#define sam_piod_disableclk() sam_disableperiph0(SAM_PID_PIOD) +#define sam_pioe_disableclk() sam_disableperiph0(SAM_PID_PIOE) +#define sam_hsmci0_disableclk() sam_disableperiph0(SAM_PID_HSMCI0) +#define sam_twihs0_disableclk() sam_disableperiph0(SAM_PID_TWIHS0) +#define sam_twihs1_disableclk() sam_disableperiph0(SAM_PID_TWIHS1) +#define sam_spi0_disableclk() sam_disableperiph0(SAM_PID_SPI0) +#define sam_ssc_disableclk() sam_disableperiph0(SAM_PID_SSC0) +#define sam_tc0_disableclk() sam_disableperiph0(SAM_PID_TC0) +#define sam_tc1_disableclk() sam_disableperiph0(SAM_PID_TC1) +#define sam_tc2_disableclk() sam_disableperiph0(SAM_PID_TC2) +#define sam_tc3_disableclk() sam_disableperiph0(SAM_PID_TC3) +#define sam_tc4_disableclk() sam_disableperiph0(SAM_PID_TC4) +#define sam_tc5_disableclk() sam_disableperiph0(SAM_PID_TC5) +#define sam_afec0_disableclk() sam_disableperiph0(SAM_PID_AFEC0) +#define sam_dacc_disableclk() sam_disableperiph0(SAM_PID_DACC) +#define sam_pwm0_disableclk() sam_disableperiph0(SAM_PID_PWM0) + +#define sam_icm_disableclk() sam_disableperiph1(SAM_PID_ICM) +#define sam_acc_disableclk() sam_disableperiph1(SAM_PID_ACC) +#define sam_usbhs_disableclk() sam_disableperiph1(SAM_PID_USBHS) +#define sam_mcan00_disableclk() sam_disableperiph1(SAM_PID_MCAN00) +#define sam_mcan01_disableclk() +#define sam_mcan10_disableclk() sam_disableperiph1(SAM_PID_MCAN10) +#define sam_mcan11_disableclk() +#define sam_emac0_disableclk() sam_disableperiph1(SAM_PID_EMAC0) +#define sam_afec1_disableclk() sam_disableperiph1(SAM_PID_AFEC1) +#define sam_twihs2_disableclk() sam_disableperiph1(SAM_PID_TWIHS2) +#define sam_spi1_disableclk() sam_disableperiph1(SAM_PID_SPI1) +#define sam_qspi_disableclk() sam_disableperiph1(SAM_PID_QSPI) +#define sam_uart2_disableclk() sam_disableperiph1(SAM_PID_UART2) +#define sam_uart3_disableclk() sam_disableperiph1(SAM_PID_UART3) +#define sam_uart4_disableclk() sam_disableperiph1(SAM_PID_UART4) +#define sam_tc6_disableclk() sam_disableperiph1(SAM_PID_TC6) +#define sam_tc7_disableclk() sam_disableperiph1(SAM_PID_TC7) +#define sam_tc8_disableclk() sam_disableperiph1(SAM_PID_TC8) +#define sam_tc9_disableclk() sam_disableperiph1(SAM_PID_TC9) +#define sam_tc10_disableclk() sam_disableperiph1(SAM_PID_TC10) +#define sam_tc11_disableclk() sam_disableperiph1(SAM_PID_TC11) +#define sam_mlb0_disableclk() sam_disableperiph1(SAM_PID_MLB0) +#define sam_mlb1_disableclk() +#define sam_aes_disableclk() sam_disableperiph1(SAM_PID_AES) +#define sam_trng_disableclk() sam_disableperiph1(SAM_PID_TRNG) +#define sam_xdmac_disableclk() sam_disableperiph1(SAM_PID_XDMAC) +#define sam_isi_disableclk() sam_disableperiph1(SAM_PID_ISI) +#define sam_pwm1_disableclk() sam_disableperiph1(SAM_PID_PWM1) +#define sam_fpu_disableclk() +#define sam_sdramc_disableclk() sam_disableperiph1(SAM_PID_SDRAMC) /* REVISIT: Does this exist? */ +#define sam_wdt1_disableclk() + +#define sam_ccw_disableclk() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAMV71_PERIPHCLKS_H */ diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4c4dd327c0c2a42b921f4678d2e6f922df0948b9 --- /dev/null +++ b/arch/arm/src/stm32/Kconfig @@ -0,0 +1,6539 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "STM32 Configuration Options" + +choice + prompt "STM32 Chip Selection" + default ARCH_CHIP_STM32F103ZE + depends on ARCH_CHIP_STM32 + +config ARCH_CHIP_STM32L151C6 + bool "STM32L151C6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151C8 + bool "STM32L151C8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151CB + bool "STM32L151CB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151R6 + bool "STM32L151R6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151R8 + bool "STM32L151R8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151RB + bool "STM32L151RB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151V6 + bool "STM32L151V6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151V8 + bool "STM32L151V8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L151VB + bool "STM32L151VB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM + +config ARCH_CHIP_STM32L152C6 + bool "STM32L152C6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x16 LCD interface + +config ARCH_CHIP_STM32L152C8 + bool "STM32L152C8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x16 LCD interface + +config ARCH_CHIP_STM32L152CB + bool "STM32L152CB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 48-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM with + 4x16 LCD interface + +config ARCH_CHIP_STM32L152R6 + bool "STM32L152R6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x32/8x28 LCD interface + +config ARCH_CHIP_STM32L152R8 + bool "STM32L152R8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x32/8x28 LCD interface + +config ARCH_CHIP_STM32L152RB + bool "STM32L152RB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 64-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM with + 4x32/8x28 LCD interface + +config ARCH_CHIP_STM32L152V6 + bool "STM32L152V6" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 32KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x44/8x40 LCD interface + +config ARCH_CHIP_STM32L152V8 + bool "STM32L152V8" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 64KB FLASH, 10KB SRAM, 4KB EEPRROM with + 4x44/8x40 LCD interface + +config ARCH_CHIP_STM32L152VB + bool "STM32L152VB" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + ---help--- + STM32L 100-pin EnergyLite, 128KB FLASH, 16KB SRAM, 4KB EEPRROM with + 4x44/8x40 LCD interface + +config ARCH_CHIP_STM32L162ZD + bool "STM32L162ZD" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + select STM32_HIGHDENSITY + select STM32_HAVE_AES + ---help--- + STM32L 144-pin EnergyLite, 384KB FLASH, 48KB SRAM, 12KB EEPRROM with + 8x40 LCD interface + +config ARCH_CHIP_STM32L162VE + bool "STM32L162VE" + select ARCH_CORTEXM3 + select STM32_STM32L15XX + select STM32_ENERGYLITE + select STM32_HIGHDENSITY + select STM32_HAVE_AES + ---help--- + STM32L 100-pin EnergyLite, 512KB FLASH, 80KB SRAM, 16KB EEPRROM with + 8x40 LCD interface + +config ARCH_CHIP_STM32F100C8 + bool "STM32F100C8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100CB + bool "STM32F100CB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100R8 + bool "STM32F100R8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100RB + bool "STM32F100RB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100RC + bool "STM32F100RC" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100RD + bool "STM32F100RD" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100RE + bool "STM32F100RE" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100V8 + bool "STM32F100V8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100VB + bool "STM32F100VB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100VC + bool "STM32F100VC" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100VD + bool "STM32F100VD" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F100VE + bool "STM32F100VE" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_VALUELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F102CB + bool "STM32F102CB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_USBACCESSLINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103T8 + bool "STM32F103T8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103TB + bool "STM32F103TB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103C4 + bool "STM32F103C4" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_LOWDENSITY + +config ARCH_CHIP_STM32F103C8 + bool "STM32F103C8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103CB + bool "STM32F103CB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103R8 + bool "STM32F103R8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103RB + bool "STM32F103RB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103RC + bool "STM32F103RC" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103RD + bool "STM32F103RD" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103RE + bool "STM32F103RE" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103RG + bool "STM32F103RG" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103V8 + bool "STM32F103V8" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103VB + bool "STM32F103VB" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_MEDIUMDENSITY + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103VC + bool "STM32F103VC" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103VE + bool "STM32F103VE" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F103ZE + bool "STM32F103ZE" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_PERFORMANCELINE + select STM32_HIGHDENSITY + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F105VB + bool "STM32F105VBT7" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_CONNECTIVITYLINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F107VC + bool "STM32F107VC" + select ARCH_CORTEXM3 + select STM32_STM32F10XX + select STM32_CONNECTIVITYLINE + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_TIM4 + +config ARCH_CHIP_STM32F205RG + bool "STM32F205RG" + select ARCH_CORTEXM3 + select STM32_STM32F20XX + select STM32_STM32F205 + +config ARCH_CHIP_STM32F207IG + bool "STM32F207IG" + select ARCH_CORTEXM3 + select STM32_STM32F20XX + select STM32_STM32F207 + +config ARCH_CHIP_STM32F207ZE + bool "STM32F207ZE" + select ARCH_CORTEXM3 + select STM32_STM32F20XX + select STM32_STM32F207 + +config ARCH_CHIP_STM32F302K6 + bool "STM32F302K6" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_I2C3 + +config ARCH_CHIP_STM32F302K8 + bool "STM32F302K8" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_I2C3 + +config ARCH_CHIP_STM32F302CB + bool "STM32F302CB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + +config ARCH_CHIP_STM32F302CC + bool "STM32F302CC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + +config ARCH_CHIP_STM32F302RB + bool "STM32F302RB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + +config ARCH_CHIP_STM32F302RC + bool "STM32F302RC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + +config ARCH_CHIP_STM32F302VB + bool "STM32F302VB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + +config ARCH_CHIP_STM32F302VC + bool "STM32F302VC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F302 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC2 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + +config ARCH_CHIP_STM32F303K6 + bool "STM32F303K6" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F303K8 + bool "STM32F303K8" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F303C6 + bool "STM32F303C6" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_USART3 + +config ARCH_CHIP_STM32F303C8 + bool "STM32F303C8" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_USART3 + +config ARCH_CHIP_STM32F303CB + bool "STM32F303CB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303CC + bool "STM32F303CC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303RB + bool "STM32F303RB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303RC + bool "STM32F303RC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303RD + bool "STM32F303RD" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_ADC4 + select STM32_HAVE_I2C2 + select STM32_HAVE_I2C3 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_SPI4 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303RE + bool "STM32F303RE" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_ADC4 + select STM32_HAVE_I2C2 + select STM32_HAVE_I2C3 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_SPI4 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303VB + bool "STM32F303VB" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F303VC + bool "STM32F303VC" + select ARCH_CORTEXM4 + select STM32_STM32F30XX + select STM32_STM32F303 + select ARCH_HAVE_FPU + select STM32_HAVE_ADC3 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM8 + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USBDEV + +config ARCH_CHIP_STM32F372C8 + bool "STM32F372C8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372R8 + bool "STM32F372R8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372V8 + bool "STM32F372V8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372CB + bool "STM32F372CB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372RB + bool "STM32F372RB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372VB + bool "STM32F372VB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372CC + bool "STM32F372CC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372RC + bool "STM32F372RC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F372VC + bool "STM32F372VC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373C8 + bool "STM32F373C8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373R8 + bool "STM32F373R8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373V8 + bool "STM32F373V8" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373CB + bool "STM32F373CB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373RB + bool "STM32F373RB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373VB + bool "STM32F373VB" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373CC + bool "STM32F373CC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373RC + bool "STM32F373RC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F373VC + bool "STM32F373VC" + select ARCH_CORTEXM4 + select STM32_STM32F37XX + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F401RE + bool "STM32F401RE" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F401 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F411RE + bool "STM32F411RE" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F411 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F405RG + bool "STM32F405RG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F405 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F405VG + bool "STM32F405VG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F405 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F405ZG + bool "STM32F405ZG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F405 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407VE + bool "STM32F407VE" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407VG + bool "STM32F407VG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407ZE + bool "STM32F407ZE" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407ZG + bool "STM32F407ZG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407IE + bool "STM32F407IE" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F407IG + bool "STM32F407IG" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F407 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F427V + bool "STM32F427V" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F427 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F427Z + bool "STM32F427Z" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F427 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F427I + bool "STM32F427I" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F427 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F429V + bool "STM32F429V" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F429 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F429Z + bool "STM32F429Z" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F429 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F429I + bool "STM32F429I" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F429 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F429B + bool "STM32F429B" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F429 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F429N + bool "STM32F429N" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F429 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F446M + bool "STM32F446M" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F446 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F446R + bool "STM32F446R" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F446 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F446V + bool "STM32F446V" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F446 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F446Z + bool "STM32F446Z" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F446 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F469A + bool "STM32F469A" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F469 + select ARCH_HAVE_FPU + +config ARCH_CHIP_STM32F469I + bool "STM32F469I" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F469 + select ARCH_HAVE_FPU + select STM32_HAVE_ETHMAC + +config ARCH_CHIP_STM32F469B + bool "STM32F469B" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F469 + select ARCH_HAVE_FPU + select STM32_HAVE_ETHMAC + +config ARCH_CHIP_STM32F469N + bool "STM32F469N" + select ARCH_CORTEXM4 + select STM32_STM32F40XX + select STM32_STM32F469 + select ARCH_HAVE_FPU + select STM32_HAVE_ETHMAC + +endchoice + +choice + prompt "Override Flash Size Designator" + default STM32_FLASH_CONFIG_DEFAULT + depends on ARCH_CHIP_STM32 + ---help--- + STM32F series parts numbering (sans the package type) ends with a number or letter + that designates the FLASH size. + + Designator Size in KiB + 4 16 + 6 32 + 8 64 + B 128 + C 256 + D 384 + E 512 + F 768 + G 1024 + I 2048 + + This configuration option defaults to using the configuration based on that designator + or the default smaller size if there is no last character designator is present in the + STM32 Chip Selection. + + Examples: + If the STM32F407VE is chosen, the Flash configuration would be 'E', if a variant of + the part with a 2048 KiB Flash is released in the future one could simply select + the 'I' designator here. + + If an STM32F42xxx or Series parts is chosen the default Flash configuration will be 'G' + and can be set herein to 'I' to choose the larger FLASH part. + +config STM32_FLASH_CONFIG_DEFAULT + bool "Default" + +config STM32_FLASH_CONFIG_4 + bool "4 16KiB" + +config STM32_FLASH_CONFIG_6 + bool "6 32KiB" + +config STM32_FLASH_CONFIG_8 + bool "8 64KiB" + +config STM32_FLASH_CONFIG_B + bool "B 128KiB" + +config STM32_FLASH_CONFIG_C + bool "C 256KiB" + +config STM32_FLASH_CONFIG_D + bool "D 384KiB" + +config STM32_FLASH_CONFIG_E + bool "E 512KiB" + +config STM32_FLASH_CONFIG_F + bool "F 768KiB" + +config STM32_FLASH_CONFIG_G + bool "G 1024KiB" + +config STM32_FLASH_CONFIG_I + bool "I 2048KiB" + +endchoice + +# This is really 15XX/16XX, but we treat the two the same. +config STM32_STM32L15XX + bool + default n + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM4 + select STM32_HAVE_RTC_SUBSECONDS if !STM32_LOWDENSITY + +config STM32_ENERGYLITE + bool + default n + select STM32_HAVE_USBDEV + select STM32_HAVE_USART3 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_ADC2 + +config STM32_STM32F10XX + bool + default n + select STM32_HAVE_SPI2 if STM32_HIGHDENSITY || STM32_MEDIUMDENSITY + select STM32_HAVE_SPI3 if STM32_HIGHDENSITY || STM32_MEDIUMDENSITY + select STM32_HAVE_RTC_COUNTER + select STM32_HAVE_TIM3 + +config STM32_VALUELINE + bool + default n + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_TIM15 + select STM32_HAVE_TIM16 + select STM32_HAVE_TIM17 + select STM32_HAVE_ADC2 + select STM32_HAVE_SPI2 if STM32_HIGHDENSITY + select STM32_HAVE_SPI3 if STM32_HIGHDENSITY + +config STM32_CONNECTIVITYLINE + bool + default n + select STM32_HAVE_OTGFS + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_ADC2 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_ETHMAC + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + +config STM32_PERFORMANCELINE + bool + default n + select STM32_HAVE_USBDEV + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_ADC2 + select STM32_HAVE_CAN1 + +config STM32_USBACCESSLINE + bool + default n + select STM32_HAVE_USBDEV + select STM32_HAVE_FSMC + select STM32_HAVE_USART3 + select STM32_HAVE_SPI2 + +config STM32_HIGHDENSITY + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + +config STM32_MEDIUMDENSITY + bool + default n + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + +config STM32_LOWDENSITY + bool + default n + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_ADC2 + select STM32_HAVE_CAN1 if !STM32_VALUELINE + +config STM32_STM32F20XX + bool + default n + +config STM32_STM32F205 + bool + default n + select STM32_HAVE_OTGFS + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_I2C3 + select STM32_HAVE_RNG + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + +config STM32_STM32F207 + bool + default n + select STM32_HAVE_OTGFS + select STM32_HAVE_FSMC + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_I2C3 + select STM32_HAVE_RNG + select STM32_HAVE_ETHMAC + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + +config STM32_STM32F30XX + bool + default n + select STM32_HAVE_CAN1 + select STM32_HAVE_DAC1 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM15 + select STM32_HAVE_TIM16 + select STM32_HAVE_TIM17 + +config STM32_STM32F302 + bool + default n + select STM32_HAVE_I2C2 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_TIM4 + select STM32_HAVE_USBDEV + +config STM32_STM32F303 + bool + default n + select STM32_HAVE_ADC2 + select STM32_HAVE_CCM + select STM32_HAVE_DAC2 + select STM32_HAVE_TIM7 + +config STM32_STM32F37XX + bool + default n + select STM32_HAVE_USBDEV + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM4 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM15 + select STM32_HAVE_TIM16 + select STM32_HAVE_TIM17 + select STM32_HAVE_CAN1 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_I2C2 + select STM32_HAVE_USART3 + +config STM32_STM32F40XX + bool + default n + select STM32_HAVE_OTGFS + select STM32_HAVE_TIM3 + select STM32_HAVE_TIM4 + select STM32_HAVE_SPI2 + select STM32_HAVE_SPI3 + select STM32_HAVE_I2C2 + select STM32_HAVE_I2C3 + +config STM32_STM32F401 + bool + default n + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + +config STM32_STM32F411 + bool + default n + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_SPI4 + select STM32_HAVE_SPI5 + +config STM32_STM32F405 + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_CCM + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_RNG + +config STM32_STM32F407 + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_CCM + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM2 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_RNG + select STM32_HAVE_ETHMAC + +# This is really 427/437, but we treat the two the same. +config STM32_STM32F427 + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_CCM + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_UART7 + select STM32_HAVE_UART8 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM5 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_RNG + select STM32_HAVE_ETHMAC + select STM32_HAVE_SPI4 + select STM32_HAVE_SPI5 + select STM32_HAVE_SPI6 + +# This is really 429/439, but we treat the two the same. +config STM32_STM32F429 + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_LTDC + select STM32_HAVE_CCM + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_UART7 + select STM32_HAVE_UART8 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_RNG + select STM32_HAVE_ETHMAC + select STM32_HAVE_SPI4 + select STM32_HAVE_SPI5 + select STM32_HAVE_SPI6 + +config STM32_STM32F446 + bool + default n + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_SPI4 + select STM32_HAVE_SAIPLL + select STM32_HAVE_I2SPLL + +# This is really 469/479, but we treat the two the same. +config STM32_STM32F469 + bool + default n + select STM32_HAVE_FSMC + select STM32_HAVE_LTDC + select STM32_HAVE_CCM + select STM32_HAVE_USART3 + select STM32_HAVE_UART4 + select STM32_HAVE_UART5 + select STM32_HAVE_USART6 + select STM32_HAVE_UART7 + select STM32_HAVE_UART8 + select STM32_HAVE_TIM1 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 + select STM32_HAVE_TIM8 + select STM32_HAVE_TIM9 + select STM32_HAVE_TIM10 + select STM32_HAVE_TIM11 + select STM32_HAVE_TIM12 + select STM32_HAVE_TIM13 + select STM32_HAVE_TIM14 + select STM32_HAVE_ADC2 + select STM32_HAVE_ADC3 + select STM32_HAVE_CAN1 + select STM32_HAVE_CAN2 + select STM32_HAVE_DAC1 + select STM32_HAVE_DAC2 + select STM32_HAVE_RNG + select STM32_HAVE_SPI4 + select STM32_HAVE_SPI5 + select STM32_HAVE_SPI6 + +config STM32_DFU + bool "DFU bootloader" + default n + depends on !STM32_VALUELINE + ---help--- + Configure and position code for use with the STMicro DFU bootloader. Do + not select this option if you will load code using JTAG/SWM. + +menu "STM32 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config STM32_HAVE_CCM + bool + default n + +config STM32_HAVE_USBDEV + bool + default n + +config STM32_HAVE_OTGFS + bool + default n + +config STM32_HAVE_FSMC + bool + default n + +config STM32_HAVE_LTDC + bool + default n + +config STM32_HAVE_USART3 + bool + default n + +config STM32_HAVE_UART4 + bool + default n + +config STM32_HAVE_UART5 + bool + default n + +config STM32_HAVE_USART6 + bool + default n + +config STM32_HAVE_UART7 + bool + default n + +config STM32_HAVE_UART8 + bool + default n + +config STM32_HAVE_TIM1 + bool + default n + +config STM32_HAVE_TIM2 + bool + default n + +config STM32_HAVE_TIM3 + bool + default n + +config STM32_HAVE_TIM4 + bool + default n + +config STM32_HAVE_TIM5 + bool + default n + +config STM32_HAVE_TIM6 + bool + default n + +config STM32_HAVE_TIM7 + bool + default n + +config STM32_HAVE_TIM8 + bool + default n + +config STM32_HAVE_TIM9 + bool + default n + +config STM32_HAVE_TIM10 + bool + default n + +config STM32_HAVE_TIM11 + bool + default n + +config STM32_HAVE_TIM12 + bool + default n + +config STM32_HAVE_TIM13 + bool + default n + +config STM32_HAVE_TIM14 + bool + default n + +config STM32_HAVE_TIM15 + bool + default n + +config STM32_HAVE_TIM16 + bool + default n + +config STM32_HAVE_TIM17 + bool + default n + +config STM32_HAVE_ADC2 + bool + default n + +config STM32_HAVE_ADC3 + bool + default n + +config STM32_HAVE_ADC4 + bool + default n + +config STM32_HAVE_ADC1_DMA + bool + default n + +config STM32_HAVE_ADC2_DMA + bool + default n + +config STM32_HAVE_ADC3_DMA + bool + default n + +config STM32_HAVE_ADC4_DMA + bool + default n + +config STM32_HAVE_CAN1 + bool + default n + +config STM32_HAVE_CAN2 + bool + default n + +config STM32_HAVE_DAC1 + bool + default n + +config STM32_HAVE_DAC2 + bool + default n + +config STM32_HAVE_RNG + bool + default n + +config STM32_HAVE_ETHMAC + bool + default n + +config STM32_HAVE_I2C2 + bool + default n + +config STM32_HAVE_I2C3 + bool + default n + +config STM32_HAVE_SPI2 + bool + default n + +config STM32_HAVE_SPI3 + bool + default n + +config STM32_HAVE_SPI4 + bool + default n + +config STM32_HAVE_SPI5 + bool + default n + +config STM32_HAVE_SPI6 + bool + default n + +config STM32_HAVE_SAIPLL + bool + default n + +config STM32_HAVE_I2SPLL + bool + default n + +# These are the peripheral selections proper + +config STM32_ADC1 + bool "ADC1" + default n + select STM32_ADC + select STM32_HAVE_ADC1_DMA if STM32_STM32F10XX && STM32_DMA1 + select STM32_HAVE_ADC1_DMA if !STM32_STM32F10XX && STM32_DMA2 + +config STM32_ADC2 + bool "ADC2" + default n + select STM32_ADC + depends on STM32_HAVE_ADC2 + select STM32_HAVE_ADC2_DMA if STM32_DMA2 + +config STM32_ADC3 + bool "ADC3" + default n + select STM32_ADC + depends on STM32_HAVE_ADC3 + select STM32_HAVE_ADC3_DMA if STM32_DMA2 + +config STM32_ADC4 + bool "ADC4" + default n + select STM32_ADC + depends on STM32_HAVE_ADC4 + select STM32_HAVE_ADC4_DMA if STM32_DMA2 + +config STM32_COMP + bool "COMP" + default n + depends on STM32_STM32L15XX + +config STM32_BKP + bool "BKP" + default n + depends on STM32_STM32F10XX + +config STM32_BKPSRAM + bool "Enable BKP RAM Domain" + default n + depends on STM32_STM32F207 || STM32_STM32F40XX + +config STM32_CAN1 + bool "CAN1" + default n + select CAN + select STM32_CAN + depends on STM32_HAVE_CAN1 + +config STM32_CAN2 + bool "CAN2" + default n + select CAN + select STM32_CAN + depends on STM32_HAVE_CAN2 + +config STM32_CCMDATARAM + bool "CMD/DATA RAM" + default n + depends on STM32_STM32F40XX + +config STM32_AES + bool "128-bit AES" + default n + depends on STM32_HAVE_AES + select CRYPTO_AES192_DISABLE if CRYPTO_ALGTEST + select CRYPTO_AES256_DISABLE if CRYPTO_ALGTEST + +config STM32_CEC + bool "CEC" + default n + depends on STM32_VALUELINE + +config STM32_CRC + bool "CRC" + default n + +config STM32_CRYP + bool "CRYP" + default n + depends on STM32_STM32F207 || STM32_STM32F40XX + +config STM32_DMA1 + bool "DMA1" + default n + select ARCH_DMA + +config STM32_DMA2 + bool "DMA2" + default n + select ARCH_DMA + depends on !STM32_VALUELINE || (STM32_VALUELINE && STM32_HIGHDENSITY) + +config STM32_DAC1 + bool "DAC1" + default n + depends on STM32_HAVE_DAC1 + select STM32_DAC + +config STM32_DAC2 + bool "DAC2" + default n + depends on STM32_HAVE_DAC2 + select STM32_DAC + +config STM32_DCMI + bool "DCMI" + default n + depends on STM32_STM32F207 || STM32_STM32F40XX + +config STM32_ETHMAC + bool "Ethernet MAC" + default n + depends on STM32_HAVE_ETHMAC + select NETDEVICES + select ARCH_HAVE_PHY + +config STM32_FSMC + bool "FSMC" + default n + depends on STM32_HAVE_FSMC + +config STM32_HASH + bool "HASH" + default n + depends on STM32_STM32F207 || STM32_STM32F40XX + +config STM32_I2C1 + bool "I2C1" + default n + select STM32_I2C + +config STM32_I2C2 + bool "I2C2" + default n + depends on STM32_HAVE_I2C2 + select STM32_I2C + +config STM32_I2C3 + bool "I2C3" + default n + depends on STM32_HAVE_I2C3 + select STM32_I2C + +config STM32_LTDC + bool "LTDC" + default n + depends on STM32_HAVE_LTDC + ---help--- + The STM32 LTDC is an LCD-TFT Display Controller available on + the STM32F429 and STM32F439 devices. It is a standard parallel + video interface (HSYNC, VSYNC, etc.) for controlling TFT + LCD displays. + +config STM32_DMA2D + bool "DMA2D" + default n + depends on STM32_STM32F429 + ---help--- + The STM32 DMA2D is an Chrom-Art Accelerator for image manipulation + available on the STM32F429 and STM32F439 devices. + +config STM32_OTGFS + bool "OTG FS" + default n + depends on STM32_HAVE_OTGFS + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32_OTGHS + bool "OTG HS" + default n + depends on STM32_STM32F207 || STM32_STM32F40XX || STM32_STM32F429 + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32_PWR + bool "PWR" + default n + +config STM32_RNG + bool "RNG" + default n + depends on STM32_HAVE_RNG + select ARCH_HAVE_RNG + +config STM32_SDIO + bool "SDIO" + default n + depends on !STM32_CONNECTIVITYLINE && !STM32_VALUELINE + select ARCH_HAVE_SDIO + select ARCH_HAVE_SDIOWAIT_WRCOMPLETE + select SDIO_PREFLIGHT + +config STM32_SPI1 + bool "SPI1" + default n + select SPI + select STM32_SPI + +config STM32_SPI2 + bool "SPI2" + default n + depends on STM32_HAVE_SPI2 + select SPI + select STM32_SPI + +config STM32_SPI3 + bool "SPI3" + default n + depends on STM32_HAVE_SPI3 + select SPI + select STM32_SPI + +config STM32_SPI4 + bool "SPI4" + default n + depends on STM32_HAVE_SPI4 + select SPI + select STM32_SPI + +config STM32_SPI5 + bool "SPI5" + default n + depends on STM32_HAVE_SPI5 + select SPI + select STM32_SPI + +config STM32_SPI6 + bool "SPI6" + default n + depends on STM32_HAVE_SPI6 + select SPI + select STM32_SPI + +config STM32_SYSCFG + bool "SYSCFG" + default y + depends on STM32_STM32L15XX || STM32_STM32F30XX || STM32_STM32F37XX || STM32_STM32F207 || STM32_STM32F40XX + +config STM32_TIM1 + bool "TIM1" + default n + depends on STM32_HAVE_TIM1 + +config STM32_TIM2 + bool "TIM2" + default n + +config STM32_TIM3 + bool "TIM3" + default n + depends on STM32_HAVE_TIM3 + +config STM32_TIM4 + bool "TIM4" + default n + depends on STM32_HAVE_TIM4 + +config STM32_TIM5 + bool "TIM5" + default n + depends on STM32_HAVE_TIM5 + +config STM32_TIM6 + bool "TIM6" + default n + depends on STM32_HAVE_TIM6 + +config STM32_TIM7 + bool "TIM7" + default n + depends on STM32_HAVE_TIM7 + +config STM32_TIM8 + bool "TIM8" + default n + depends on STM32_HAVE_TIM8 + +config STM32_TIM9 + bool "TIM9" + default n + depends on STM32_HAVE_TIM9 + +config STM32_TIM10 + bool "TIM10" + default n + depends on STM32_HAVE_TIM10 + +config STM32_TIM11 + bool "TIM11" + default n + depends on STM32_HAVE_TIM11 + +config STM32_TIM12 + bool "TIM12" + default n + depends on STM32_HAVE_TIM12 + +config STM32_TIM13 + bool "TIM13" + default n + depends on STM32_HAVE_TIM13 + +config STM32_TIM14 + bool "TIM14" + default n + depends on STM32_HAVE_TIM14 + +config STM32_TIM15 + bool "TIM15" + default n + depends on STM32_HAVE_TIM15 + +config STM32_TIM16 + bool "TIM16" + default n + depends on STM32_HAVE_TIM16 + +config STM32_TIM17 + bool "TIM17" + default n + depends on STM32_HAVE_TIM17 + +config STM32_TSC + bool "TSC" + default n + depends on STM32_STM32F30XX + +config STM32_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32_USART + +config STM32_USART2 + bool "USART2" + default n + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32_USART + +config STM32_USART3 + bool "USART3" + default n + depends on STM32_HAVE_USART3 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART3 + select STM32_USART + +config STM32_UART4 + bool "UART4" + default n + depends on STM32_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART4 + select STM32_USART + +config STM32_UART5 + bool "UART5" + default n + depends on STM32_HAVE_UART5 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART5 + select STM32_USART + +config STM32_USART6 + bool "USART6" + default n + depends on STM32_HAVE_USART6 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART6 + select STM32_USART + +config STM32_UART7 + bool "UART7" + default n + depends on STM32_HAVE_UART7 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART7 + select STM32_USART + +config STM32_UART8 + bool "UART8" + default n + depends on STM32_HAVE_UART8 + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART8 + select STM32_USART + +config STM32_USB + bool "USB Device" + default n + depends on STM32_HAVE_USBDEV + select USBDEV + +config STM32_LCD + bool "Segment LCD" + default n + depends on STM32_STM32L15XX + +config STM32_IWDG + bool "IWDG" + default n + select WATCHDOG + +config STM32_WWDG + bool "WWDG" + default n + select WATCHDOG + +endmenu + +config STM32_ADC + bool + +config STM32_DAC + bool + +config STM32_SPI + bool + +config STM32_I2C + bool + +config STM32_CAN + bool + +config STM32_NOEXT_VECTORS + bool "Disable the ARMv7-M EXT vectors" + default n + ---help--- + Sometimes you may not need any Vector support beyond SysTick + and wish to save memory. This applies only to ARMv7-M architectures. + +menu "Alternate Pin Mapping" + +choice + prompt "CAN1 Alternate Pin Mappings" + depends on STM32_STM32F10XX && STM32_CAN1 + default STM32_CAN1_NO_REMAP + +config STM32_CAN1_NO_REMAP + bool "No pin remapping" + +config STM32_CAN1_REMAP1 + bool "CAN1 alternate pin remapping #1" + +config STM32_CAN1_REMAP2 + bool "CAN1 alternate pin remapping #2" + +endchoice + +config STM32_CAN2_REMAP + bool "CAN2 Alternate Pin Mapping" + default n + depends on STM32_CONNECTIVITYLINE && STM32_CAN2 + +config STM32_CEC_REMAP + bool "CEC Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_CEC + +config STM32_ETH_REMAP + bool "Ethernet Alternate Pin Mapping" + default n + depends on STM32_CONNECTIVITYLINE && STM32_ETHMAC + +config STM32_I2C1_REMAP + bool "I2C1 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_I2C1 + +config STM32_SPI1_REMAP + bool "SPI1 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_SPI1 + +config STM32_SPI3_REMAP + bool "SPI3 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_SPI3 && !STM32_VALUELINE + +choice + prompt "TIM1 Alternate Pin Mappings" + depends on STM32_STM32F10XX && STM32_TIM1 + default STM32_TIM1_NO_REMAP + +config STM32_TIM1_NO_REMAP + bool "No pin remapping" + +config STM32_TIM1_FULL_REMAP + bool "Full pin remapping" + +config STM32_TIM1_PARTIAL_REMAP + bool "Partial pin remapping" + +endchoice + +choice + prompt "TIM2 Alternate Pin Mappings" + depends on STM32_STM32F10XX && STM32_TIM2 + default STM32_TIM2_NO_REMAP + +config STM32_TIM2_NO_REMAP + bool "No pin remapping" + +config STM32_TIM2_FULL_REMAP + bool "Full pin remapping" + +config STM32_TIM2_PARTIAL_REMAP_1 + bool "Partial pin remapping #1" + +config STM32_TIM2_PARTIAL_REMAP_2 + bool "Partial pin remapping #2" + +endchoice + +choice + prompt "TIM3 Alternate Pin Mappings" + depends on STM32_STM32F10XX && STM32_TIM3 + default STM32_TIM3_NO_REMAP + +config STM32_TIM3_NO_REMAP + bool "No pin remapping" + +config STM32_TIM3_FULL_REMAP + bool "Full pin remapping" + +config STM32_TIM3_PARTIAL_REMAP + bool "Partial pin remapping" + +endchoice + +config STM32_TIM4_REMAP + bool "TIM4 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM4 + +config STM32_TIM9_REMAP + bool "TIM9 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM9 + +config STM32_TIM10_REMAP + bool "TIM10 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM10 + +config STM32_TIM11_REMAP + bool "TIM11 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM11 + +config STM32_TIM12_REMAP + bool "TIM12 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM12 + +config STM32_TIM13_REMAP + bool "TIM13 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM13 + +config STM32_TIM14_REMAP + bool "TIM14 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM14 + +config STM32_TIM15_REMAP + bool "TIM15 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM15 + +config STM32_TIM16_REMAP + bool "TIM16 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM16 + +config STM32_TIM17_REMAP + bool "TIM17 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_TIM17 + +config STM32_USART1_REMAP + bool "USART1 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_USART1 + +config STM32_USART2_REMAP + bool "USART2 Alternate Pin Mapping" + default n + depends on STM32_STM32F10XX && STM32_USART2 + +choice + prompt "USART3 Alternate Pin Mappings" + depends on STM32_STM32F10XX && STM32_USART3 + default STM32_USART3_NO_REMAP + +config STM32_USART3_NO_REMAP + bool "No pin remapping" + +config STM32_USART3_FULL_REMAP + bool "Full pin remapping" + +config STM32_USART3_PARTIAL_REMAP + bool "Partial pin remapping" + +endchoice + +endmenu + +config STM32_FLASH_PREFETCH + bool "Enable FLASH Pre-fetch" + depends on STM32_STM32F207 || STM32_STM32F40XX + default y if STM32_STM32F427 || STM32_STM32F429 || STM32_STM32F446 + default n + ---help--- + Enable FLASH prefetch and F2 and F4 parts (FLASH pre-fetch is always enabled + on F1 parts). Some early revisions of F4 parts do not support FLASH pre-fetch + properly and enabling this option may interfere with ADC accuracy. + +choice + prompt "JTAG Configuration" + default STM32_JTAG_DISABLE + ---help--- + JTAG Enable settings (by default JTAG-DP and SW-DP are disabled) + +config STM32_JTAG_DISABLE + bool "Disable all JTAG clocking" + +config STM32_JTAG_FULL_ENABLE + bool "Enable full SWJ (JTAG-DP + SW-DP)" + +config STM32_JTAG_NOJNTRST_ENABLE + bool "Enable full SWJ (JTAG-DP + SW-DP) but without JNTRST" + +config STM32_JTAG_SW_ENABLE + bool "Set JTAG-DP disabled and SW-DP enabled" + +endchoice + +config STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG + bool "Disable IDLE Sleep (WFI) in debug mode" + default n + ---help--- + In debug configuration, disables the WFI instruction in the IDLE loop + to prevent the JTAG from disconnecting. With some JTAG debuggers, such + as the ST-LINK2 with OpenOCD, if the ARM is put to sleep via the WFI + instruction, the debugger will disconnect, terminating the debug session. + +config STM32_FORCEPOWER + bool "Force power" + default n + ---help--- + Timer and I2C devices may need to the following to force power to be applied + unconditionally at power up. (Otherwise, the device is powered when it is + initialized). + +config ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG + bool "Custom clock configuration" + default n + ---help--- + Enables special, board-specific STM32 clock configuration. + +config STM32_SAIPLL + bool "SAIPLL" + default n + depends on STM32_HAVE_SAIPLL + ---help--- + The STM32F446 has a separate PLL for the SAI block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32_I2SPLL + bool "I2SPLL" + default n + depends on STM32_HAVE_I2SPLL + ---help--- + The STM32F446 has a separate PLL for the I2S block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32_CCMEXCLUDE + bool "Exclude CCM SRAM from the heap" + default y if ARCH_DMA || ELF + depends on STM32_HAVE_CCM + ---help--- + Exclude CCM SRAM from the HEAP because (1) it cannot be used for DMA + and (2) it appears to be impossible to execute ELF modules from CCM + RAM. + +config STM32_CCM_PROCFS + bool "CCM PROCFS support" + default n + depends on !DISABLE_MOUNTPOINT && FS_PROCFS && FS_PROCFS_REGISTER + ---help--- + Select to build in support for /proc/ccm. Reading from /proc/ccm + will provide statistics about CCM memory use similar to what you + would get from mallinfo() for the user heap. + +config STM32_DMACAPABLE + bool "Workaround non-DMA capable memory" + depends on ARCH_DMA + default y if STM32_STM32F40XX && !STM32_CCMEXCLUDE + default n if !STM32_STM32F40XX || STM32_CCMEXCLUDE + ---help--- + This option enables the DMA interface stm32_dmacapable that can be + used to check if it is possible to do DMA from the selected address. + Drivers then may use this information to determine if they should + attempt the DMA or fall back to a different transfer method. + +config STM32_FSMC_SRAM + bool "External SRAM on FSMC" + default n + depends on STM32_FSMC + select ARCH_HAVE_HEAP2 + ---help--- + In addition to internal SRAM, SRAM may also be available through the FSMC. + +config STM32_TIM1_PWM + bool "TIM1 PWM" + default n + depends on STM32_TIM1 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 1 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM1 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM1_PWM + +config STM32_TIM1_MODE + int "TIM1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM1_CHANNEL1 + bool "TIM1 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM1_CHANNEL1 + +config STM32_TIM1_CH1MODE + int "TIM1 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM1_CH1OUT + bool "TIM1 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM1_CHANNEL1 + +config STM32_TIM1_CHANNEL2 + bool "TIM1 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM1_CHANNEL2 + +config STM32_TIM1_CH2MODE + int "TIM1 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM1_CH2OUT + bool "TIM1 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM1_CHANNEL2 + +config STM32_TIM1_CHANNEL3 + bool "TIM1 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM1_CHANNEL3 + +config STM32_TIM1_CH3MODE + int "TIM1 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM1_CH3OUT + bool "TIM1 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM1_CHANNEL3 + +config STM32_TIM1_CHANNEL4 + bool "TIM1 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM1_CHANNEL4 + +config STM32_TIM1_CH4MODE + int "TIM1 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM1_CH4OUT + bool "TIM1 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM1_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM1_CHANNEL + int "TIM1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM1_CHMODE + int "TIM1 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM1_PWM + +config STM32_TIM2_PWM + bool "TIM2 PWM" + default n + depends on STM32_TIM2 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 2 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM2 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM2_PWM + +config STM32_TIM2_MODE + int "TIM2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM2_CHANNEL1 + bool "TIM2 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM2_CHANNEL1 + +config STM32_TIM2_CH1MODE + int "TIM2 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM2_CH1OUT + bool "TIM2 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM2_CHANNEL1 + +config STM32_TIM2_CHANNEL2 + bool "TIM2 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM2_CHANNEL2 + +config STM32_TIM2_CH2MODE + int "TIM2 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM2_CH2OUT + bool "TIM2 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM2_CHANNEL2 + +config STM32_TIM2_CHANNEL3 + bool "TIM2 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM2_CHANNEL3 + +config STM32_TIM2_CH3MODE + int "TIM2 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM2_CH3OUT + bool "TIM2 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM2_CHANNEL3 + +config STM32_TIM2_CHANNEL4 + bool "TIM2 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM2_CHANNEL4 + +config STM32_TIM2_CH4MODE + int "TIM2 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM2_CH4OUT + bool "TIM2 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM2_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM2_CHANNEL + int "TIM2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM2 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM2_CHMODE + int "TIM2 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM2_PWM + +config STM32_TIM3_PWM + bool "TIM3 PWM" + default n + depends on STM32_TIM3 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 3 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM3 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM3_PWM + +config STM32_TIM3_MODE + int "TIM3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM3_CHANNEL1 + bool "TIM3 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM3_CHANNEL1 + +config STM32_TIM3_CH1MODE + int "TIM3 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM3_CH1OUT + bool "TIM3 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM3_CHANNEL1 + +config STM32_TIM3_CHANNEL2 + bool "TIM3 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM3_CHANNEL2 + +config STM32_TIM3_CH2MODE + int "TIM3 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM3_CH2OUT + bool "TIM3 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM3_CHANNEL2 + +config STM32_TIM3_CHANNEL3 + bool "TIM3 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM3_CHANNEL3 + +config STM32_TIM3_CH3MODE + int "TIM3 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM3_CH3OUT + bool "TIM3 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM3_CHANNEL3 + +config STM32_TIM3_CHANNEL4 + bool "TIM3 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM3_CHANNEL4 + +config STM32_TIM3_CH4MODE + int "TIM3 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM3_CH4OUT + bool "TIM3 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM3_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM3_CHANNEL + int "TIM3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM3 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM3_CHMODE + int "TIM3 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM3_PWM + +config STM32_TIM4_PWM + bool "TIM4 PWM" + default n + depends on STM32_TIM4 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 4 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM4 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM4_PWM + +config STM32_TIM4_MODE + int "TIM4 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM4_CHANNEL1 + bool "TIM4 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM4_CHANNEL1 + +config STM32_TIM4_CH1MODE + int "TIM4 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM4_CH1OUT + bool "TIM4 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM4_CHANNEL1 + +config STM32_TIM4_CHANNEL2 + bool "TIM4 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM4_CHANNEL2 + +config STM32_TIM4_CH2MODE + int "TIM4 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM4_CH2OUT + bool "TIM4 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM4_CHANNEL2 + +config STM32_TIM4_CHANNEL3 + bool "TIM4 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM4_CHANNEL3 + +config STM32_TIM4_CH3MODE + int "TIM4 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM4_CH3OUT + bool "TIM4 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM4_CHANNEL3 + +config STM32_TIM4_CHANNEL4 + bool "TIM4 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM4_CHANNEL4 + +config STM32_TIM4_CH4MODE + int "TIM4 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM4_CH4OUT + bool "TIM4 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM4_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM4_CHANNEL + int "TIM4 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM4 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM4_CHMODE + int "TIM4 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM4_PWM + +config STM32_TIM5_PWM + bool "TIM5 PWM" + default n + depends on STM32_TIM5 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 5 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM5 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM5_PWM + +config STM32_TIM5_MODE + int "TIM5 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM5_CHANNEL1 + bool "TIM5 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM5_CHANNEL1 + +config STM32_TIM5_CH1MODE + int "TIM5 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM5_CH1OUT + bool "TIM5 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM5_CHANNEL1 + +config STM32_TIM5_CHANNEL2 + bool "TIM5 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM5_CHANNEL2 + +config STM32_TIM5_CH2MODE + int "TIM5 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM5_CH2OUT + bool "TIM5 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM5_CHANNEL2 + +config STM32_TIM5_CHANNEL3 + bool "TIM5 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM5_CHANNEL3 + +config STM32_TIM5_CH3MODE + int "TIM5 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM5_CH3OUT + bool "TIM5 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM5_CHANNEL3 + +config STM32_TIM5_CHANNEL4 + bool "TIM5 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM5_CHANNEL4 + +config STM32_TIM5_CH4MODE + int "TIM5 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM5_CH4OUT + bool "TIM5 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM5_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM5_CHANNEL + int "TIM5 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM5 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM5_CHMODE + int "TIM5 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM5_PWM + +config STM32_TIM8_PWM + bool "TIM8 PWM" + default n + depends on STM32_TIM8 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 8 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM8 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM8_PWM + +config STM32_TIM8_MODE + int "TIM8 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32_PWM_MULTICHAN + +config STM32_TIM8_CHANNEL1 + bool "TIM8 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM8_CHANNEL1 + +config STM32_TIM8_CH1MODE + int "TIM8 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM8_CH1OUT + bool "TIM8 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM8_CHANNEL1 + +config STM32_TIM8_CHANNEL2 + bool "TIM8 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM8_CHANNEL2 + +config STM32_TIM8_CH2MODE + int "TIM8 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM8_CH2OUT + bool "TIM8 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM8_CHANNEL2 + +config STM32_TIM8_CHANNEL3 + bool "TIM8 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM8_CHANNEL3 + +config STM32_TIM8_CH3MODE + int "TIM8 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM8_CH3OUT + bool "TIM8 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM8_CHANNEL3 + +config STM32_TIM8_CHANNEL4 + bool "TIM8 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM8_CHANNEL4 + +config STM32_TIM8_CH4MODE + int "TIM8 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM8_CH4OUT + bool "TIM8 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM8_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM8_CHANNEL + int "TIM8 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM8 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM8_CHMODE + int "TIM8 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM8_PWM + +config STM32_TIM9_PWM + bool "TIM9 PWM" + default n + depends on STM32_TIM9 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 9 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM9 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM9_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM9_CHANNEL1 + bool "TIM9 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM9_CHANNEL1 + +config STM32_TIM9_CH1MODE + int "TIM9 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM9_CH1OUT + bool "TIM9 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM9_CHANNEL1 + +config STM32_TIM9_CHANNEL2 + bool "TIM9 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM9_CHANNEL2 + +config STM32_TIM9_CH2MODE + int "TIM9 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM9_CH2OUT + bool "TIM9 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM9_CHANNEL2 + +config STM32_TIM9_CHANNEL3 + bool "TIM9 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM9_CHANNEL3 + +config STM32_TIM9_CH3MODE + int "TIM9 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM9_CH3OUT + bool "TIM9 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM9_CHANNEL3 + +config STM32_TIM9_CHANNEL4 + bool "TIM9 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM9_CHANNEL4 + +config STM32_TIM9_CH4MODE + int "TIM9 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM9_CH4OUT + bool "TIM9 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM9_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM9_CHANNEL + int "TIM9 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM9 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM9_CHMODE + int "TIM9 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM9_PWM + +config STM32_TIM10_PWM + bool "TIM10 PWM" + default n + depends on STM32_TIM10 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 10 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM10 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM10_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM10_CHANNEL1 + bool "TIM10 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM10_CHANNEL1 + +config STM32_TIM10_CH1MODE + int "TIM10 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM10_CH1OUT + bool "TIM10 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM10_CHANNEL1 + +config STM32_TIM10_CHANNEL2 + bool "TIM10 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM10_CHANNEL2 + +config STM32_TIM10_CH2MODE + int "TIM10 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM10_CH2OUT + bool "TIM10 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM10_CHANNEL2 + +config STM32_TIM10_CHANNEL3 + bool "TIM10 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM10_CHANNEL3 + +config STM32_TIM10_CH3MODE + int "TIM10 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM10_CH3OUT + bool "TIM10 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM10_CHANNEL3 + +config STM32_TIM10_CHANNEL4 + bool "TIM10 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM10_CHANNEL4 + +config STM32_TIM10_CH4MODE + int "TIM10 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM10_CH4OUT + bool "TIM10 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM10_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM10_CHANNEL + int "TIM10 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM10 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM10_CHMODE + int "TIM10 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM10_PWM + +config STM32_TIM11_PWM + bool "TIM11 PWM" + default n + depends on STM32_TIM11 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 11 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM11 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM11_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM11_CHANNEL1 + bool "TIM11 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM11_CHANNEL1 + +config STM32_TIM11_CH1MODE + int "TIM11 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM11_CH1OUT + bool "TIM11 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM11_CHANNEL1 + +config STM32_TIM11_CHANNEL2 + bool "TIM11 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM11_CHANNEL2 + +config STM32_TIM11_CH2MODE + int "TIM11 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM11_CH2OUT + bool "TIM11 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM11_CHANNEL2 + +config STM32_TIM11_CHANNEL3 + bool "TIM11 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM11_CHANNEL3 + +config STM32_TIM11_CH3MODE + int "TIM11 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM11_CH3OUT + bool "TIM11 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM11_CHANNEL3 + +config STM32_TIM11_CHANNEL4 + bool "TIM11 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM11_CHANNEL4 + +config STM32_TIM11_CH4MODE + int "TIM11 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM11_CH4OUT + bool "TIM11 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM11_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM11_CHANNEL + int "TIM11 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM11 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM11_CHMODE + int "TIM11 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM11_PWM + +config STM32_TIM12_PWM + bool "TIM12 PWM" + default n + depends on STM32_TIM12 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 12 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM12 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM12_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM12_CHANNEL1 + bool "TIM12 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM12_CHANNEL1 + +config STM32_TIM12_CH1MODE + int "TIM12 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM12_CH1OUT + bool "TIM12 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM12_CHANNEL1 + +config STM32_TIM12_CHANNEL2 + bool "TIM12 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM12_CHANNEL2 + +config STM32_TIM12_CH2MODE + int "TIM12 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM12_CH2OUT + bool "TIM12 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM12_CHANNEL2 + +config STM32_TIM12_CHANNEL3 + bool "TIM12 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM12_CHANNEL3 + +config STM32_TIM12_CH3MODE + int "TIM12 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM12_CH3OUT + bool "TIM12 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM12_CHANNEL3 + +config STM32_TIM12_CHANNEL4 + bool "TIM12 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM12_CHANNEL4 + +config STM32_TIM12_CH4MODE + int "TIM12 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM12_CH4OUT + bool "TIM12 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM12_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM12_CHANNEL + int "TIM12 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM12 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM12_CHMODE + int "TIM12 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM12_PWM + +config STM32_TIM13_PWM + bool "TIM13 PWM" + default n + depends on STM32_TIM13 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 13 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM13 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM13_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM13_CHANNEL1 + bool "TIM13 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM13_CHANNEL1 + +config STM32_TIM13_CH1MODE + int "TIM13 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM13_CH1OUT + bool "TIM13 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM13_CHANNEL1 + +config STM32_TIM13_CHANNEL2 + bool "TIM13 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM13_CHANNEL2 + +config STM32_TIM13_CH2MODE + int "TIM13 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM13_CH2OUT + bool "TIM13 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM13_CHANNEL2 + +config STM32_TIM13_CHANNEL3 + bool "TIM13 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM13_CHANNEL3 + +config STM32_TIM13_CH3MODE + int "TIM13 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM13_CH3OUT + bool "TIM13 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM13_CHANNEL3 + +config STM32_TIM13_CHANNEL4 + bool "TIM13 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM13_CHANNEL4 + +config STM32_TIM13_CH4MODE + int "TIM13 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM13_CH4OUT + bool "TIM13 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM13_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM13_CHANNEL + int "TIM13 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM13 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM13_CHMODE + int "TIM13 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM13_PWM + +config STM32_TIM14_PWM + bool "TIM14 PWM" + default n + depends on STM32_TIM14 + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 14 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM14 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM14_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM14_CHANNEL1 + bool "TIM14 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM14_CHANNEL1 + +config STM32_TIM14_CH1MODE + int "TIM14 Channel 1 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM14_CH1OUT + bool "TIM14 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM14_CHANNEL1 + +config STM32_TIM14_CHANNEL2 + bool "TIM14 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM14_CHANNEL2 + +config STM32_TIM14_CH2MODE + int "TIM14 Channel 2 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM14_CH2OUT + bool "TIM14 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM14_CHANNEL2 + +config STM32_TIM14_CHANNEL3 + bool "TIM14 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32_TIM14_CHANNEL3 + +config STM32_TIM14_CH3MODE + int "TIM14 Channel 3 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM14_CH3OUT + bool "TIM14 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM14_CHANNEL3 + +config STM32_TIM14_CHANNEL4 + bool "TIM14 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32_TIM14_CHANNEL4 + +config STM32_TIM14_CH4MODE + int "TIM14 Channel 4 Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM14_CH4OUT + bool "TIM14 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM14_CHANNEL4 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM14_CHANNEL + int "TIM14 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM14 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32_TIM14_CHMODE + int "TIM14 Channel Mode" + default 0 + range 0 5 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM14_PWM + +config STM32_TIM15_PWM + bool "TIM15 PWM" + default n + depends on STM32_TIM15 + ---help--- + Reserve timer 15 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM15 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM15_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM15_CHANNEL1 + bool "TIM15 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM15_CHANNEL1 + +config STM32_TIM15_CH1MODE + int "TIM15 Channel 1 Mode" + default 0 + range 0 3 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM15_CH1OUT + bool "TIM15 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM15_CHANNEL1 + +config STM32_TIM15_CHANNEL2 + bool "TIM15 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32_TIM15_CHANNEL2 + +config STM32_TIM15_CH2MODE + int "TIM15 Channel 2 Mode" + default 0 + range 0 3 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +config STM32_TIM15_CH2OUT + bool "TIM15 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM15_CHANNEL2 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM15_CHANNEL + int "TIM15 PWM Output Channel" + default 1 + range 1 2 + ---help--- + If TIM15 is enabled for PWM usage, you also need specifies the timer output + channel {1,2} + +config STM32_TIM15_CHMODE + int "TIM15 Channel Mode" + default 0 + range 0 3 if STM32_STM32F30XX + range 0 1 if !STM32_STM32F30XX + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM15_PWM + +config STM32_TIM16_PWM + bool "TIM16 PWM" + default n + depends on STM32_TIM16 + ---help--- + Reserve timer 16 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM16 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM16_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM16_CHANNEL1 + bool "TIM16 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM16_CHANNEL1 + +config STM32_TIM16_CH1MODE + int "TIM16 Channel 1 Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +config STM32_TIM16_CH1OUT + bool "TIM16 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM16_CHANNEL1 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM16_CHANNEL + int "TIM16 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM16 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +config STM32_TIM16_CHMODE + int "TIM16 Channel Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM16_PWM + +config STM32_TIM17_PWM + bool "TIM17 PWM" + default n + depends on STM32_TIM17 + ---help--- + Reserve timer 17 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32_TIM17 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32_TIM17_PWM + +if STM32_PWM_MULTICHAN + +config STM32_TIM17_CHANNEL1 + bool "TIM17 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32_TIM17_CHANNEL1 + +config STM32_TIM17_CH1MODE + int "TIM17 Channel 1 Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +config STM32_TIM17_CH1OUT + bool "TIM17 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM17_CHANNEL1 + +endif # STM32_PWM_MULTICHAN + +if !STM32_PWM_MULTICHAN + +config STM32_TIM17_CHANNEL + int "TIM17 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM17 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +config STM32_TIM17_CHMODE + int "TIM17 Channel Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +endif # !STM32_PWM_MULTICHAN + +endif # STM32_TIM17_PWM + +config STM32_PWM_MULTICHAN + bool "PWM Multiple Output Channels" + default n + depends on STM32_TIM1_PWM || STM32_TIM2_PWM || STM32_TIM3_PWM || STM32_TIM4_PWM || STM32_TIM5_PWM || STM32_TIM8_PWM || STM32_TIM9_PWM || STM32_TIM10_PWM || STM32_TIM11_PWM || STM32_TIM12_PWM || STM32_TIM13_PWM || STM32_TIM14_PWM || STM32_TIM15_PWM || STM32_TIM16_PWM || STM32_TIM17_PWM + select ARCH_HAVE_PWM_MULTICHAN + ---help--- + Specifies that the PWM driver supports multiple output + channels per timer. + +config STM32_TIM1_ADC + bool "TIM1 ADC" + default n + depends on STM32_TIM1 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM1 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM1 ADC channel" + default STM32_TIM1_ADC1 + depends on STM32_TIM1_ADC + +config STM32_TIM1_ADC1 + bool "TIM1 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM1 to trigger ADC1 + +config STM32_TIM1_ADC2 + bool "TIM1 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM1 to trigger ADC2 + +config STM32_TIM1_ADC3 + bool "TIM1 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM1 to trigger ADC3 + +endchoice + +config STM32_TIM2_ADC + bool "TIM2 ADC" + default n + depends on STM32_TIM2 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM2 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM2 ADC channel" + default STM32_TIM2_ADC1 + depends on STM32_TIM2_ADC + +config STM32_TIM2_ADC1 + bool "TIM2 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM2 to trigger ADC1 + +config STM32_TIM2_ADC2 + bool "TIM2 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM2 to trigger ADC2 + +config STM32_TIM2_ADC3 + bool "TIM2 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM2 to trigger ADC3 + +endchoice + +config STM32_TIM3_ADC + bool "TIM3 ADC" + default n + depends on STM32_TIM3 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM3 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM3 ADC channel" + default STM32_TIM3_ADC1 + depends on STM32_TIM3_ADC + +config STM32_TIM3_ADC1 + bool "TIM3 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM3 to trigger ADC1 + +config STM32_TIM3_ADC2 + bool "TIM3 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM3 to trigger ADC2 + +config STM32_TIM3_ADC3 + bool "TIM3 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM3 to trigger ADC3 + +endchoice + +config STM32_TIM4_ADC + bool "TIM4 ADC" + default n + depends on STM32_TIM4 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM4 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM4 ADC channel" + default STM32_TIM4_ADC1 + depends on STM32_TIM4_ADC + +config STM32_TIM4_ADC1 + bool "TIM4 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM4 to trigger ADC1 + +config STM32_TIM4_ADC2 + bool "TIM4 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM4 to trigger ADC2 + +config STM32_TIM4_ADC3 + bool "TIM4 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM4 to trigger ADC3 + +endchoice + +config STM32_TIM5_ADC + bool "TIM5 ADC" + default n + depends on STM32_TIM5 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM5 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM5 ADC channel" + default STM32_TIM5_ADC1 + depends on STM32_TIM5_ADC + +config STM32_TIM5_ADC1 + bool "TIM5 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM5 to trigger ADC1 + +config STM32_TIM5_ADC2 + bool "TIM5 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM5 to trigger ADC2 + +config STM32_TIM5_ADC3 + bool "TIM5 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM5 to trigger ADC3 + +endchoice + +config STM32_TIM8_ADC + bool "TIM8 ADC" + default n + depends on STM32_TIM8 && STM32_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32_TIM8 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM8 ADC channel" + default STM32_TIM8_ADC1 + depends on STM32_TIM8_ADC + +config STM32_TIM8_ADC1 + bool "TIM8 ADC channel 1" + depends on STM32_ADC1 + select HAVE_ADC1_TIMER + ---help--- + Reserve TIM8 to trigger ADC1 + +config STM32_TIM8_ADC2 + bool "TIM8 ADC channel 2" + depends on STM32_ADC2 + select HAVE_ADC2_TIMER + ---help--- + Reserve TIM8 to trigger ADC2 + +config STM32_TIM8_ADC3 + bool "TIM8 ADC channel 3" + depends on STM32_ADC3 + select HAVE_ADC3_TIMER + ---help--- + Reserve TIM8 to trigger ADC3 + +endchoice + +config HAVE_ADC1_TIMER + bool + +config HAVE_ADC2_TIMER + bool + +config HAVE_ADC3_TIMER + bool + +config STM32_ADC1_SAMPLE_FREQUENCY + int "ADC1 Sampling Frequency" + default 100 + depends on HAVE_ADC1_TIMER + ---help--- + ADC1 sampling frequency. Default: 100Hz + +config STM32_ADC1_TIMTRIG + int "ADC1 Timer Trigger" + default 0 + range 0 4 + depends on HAVE_ADC1_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32_ADC2_SAMPLE_FREQUENCY + int "ADC2 Sampling Frequency" + default 100 + depends on HAVE_ADC2_TIMER + ---help--- + ADC2 sampling frequency. Default: 100Hz + +config STM32_ADC2_TIMTRIG + int "ADC2 Timer Trigger" + default 0 + range 0 4 + depends on HAVE_ADC2_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32_ADC3_SAMPLE_FREQUENCY + int "ADC3 Sampling Frequency" + default 100 + depends on HAVE_ADC3_TIMER + ---help--- + ADC3 sampling frequency. Default: 100Hz + +config STM32_ADC3_TIMTRIG + int "ADC3 Timer Trigger" + default 0 + range 0 4 + depends on HAVE_ADC3_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32_TIM1_DAC + bool "TIM1 DAC" + default n + depends on STM32_TIM1 && STM32_DAC + ---help--- + Reserve timer 1 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM1 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM1 DAC channel" + default STM32_TIM1_DAC1 + depends on STM32_TIM1_DAC + +config STM32_TIM1_DAC1 + bool "TIM1 DAC channel 1" + ---help--- + Reserve TIM1 to trigger DAC1 + +config STM32_TIM1_DAC2 + bool "TIM1 DAC channel 2" + ---help--- + Reserve TIM1 to trigger DAC2 + +endchoice + +config STM32_TIM2_DAC + bool "TIM2 DAC" + default n + depends on STM32_TIM2 && STM32_DAC + ---help--- + Reserve timer 2 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM2 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM2 DAC channel" + default STM32_TIM2_DAC1 + depends on STM32_TIM2_DAC + +config STM32_TIM2_DAC1 + bool "TIM2 DAC channel 1" + ---help--- + Reserve TIM2 to trigger DAC1 + +config STM32_TIM2_DAC2 + bool "TIM2 DAC channel 2" + ---help--- + Reserve TIM2 to trigger DAC2 + +endchoice + +config STM32_TIM3_DAC + bool "TIM3 DAC" + default n + depends on STM32_TIM3 && STM32_DAC + ---help--- + Reserve timer 3 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM3 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM3 DAC channel" + default STM32_TIM3_DAC1 + depends on STM32_TIM3_DAC + +config STM32_TIM3_DAC1 + bool "TIM3 DAC channel 1" + ---help--- + Reserve TIM3 to trigger DAC1 + +config STM32_TIM3_DAC2 + bool "TIM3 DAC channel 2" + ---help--- + Reserve TIM3 to trigger DAC2 + +endchoice + +config STM32_TIM4_DAC + bool "TIM4 DAC" + default n + depends on STM32_TIM4 && STM32_DAC + ---help--- + Reserve timer 4 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM4 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM4 DAC channel" + default STM32_TIM4_DAC1 + depends on STM32_TIM4_DAC + +config STM32_TIM4_DAC1 + bool "TIM4 DAC channel 1" + ---help--- + Reserve TIM4 to trigger DAC1 + +config STM32_TIM4_DAC2 + bool "TIM4 DAC channel 2" + ---help--- + Reserve TIM4 to trigger DAC2 + +endchoice + +config STM32_TIM5_DAC + bool "TIM5 DAC" + default n + depends on STM32_TIM5 && STM32_DAC + ---help--- + Reserve timer 5 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM5 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM5 DAC channel" + default STM32_TIM5_DAC1 + depends on STM32_TIM5_DAC + +config STM32_TIM5_DAC1 + bool "TIM5 DAC channel 1" + ---help--- + Reserve TIM5 to trigger DAC1 + +config STM32_TIM5_DAC2 + bool "TIM5 DAC channel 2" + ---help--- + Reserve TIM5 to trigger DAC2 + +endchoice + +config STM32_TIM6_DAC + bool "TIM6 DAC" + default n + depends on STM32_TIM6 && STM32_DAC + ---help--- + Reserve timer 6 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM6 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM6 DAC channel" + default STM32_TIM6_DAC1 + depends on STM32_TIM6_DAC + +config STM32_TIM6_DAC1 + bool "TIM6 DAC channel 1" + ---help--- + Reserve TIM6 to trigger DAC1 + +config STM32_TIM6_DAC2 + bool "TIM6 DAC channel 2" + ---help--- + Reserve TIM6 to trigger DAC2 + +endchoice + +config STM32_TIM7_DAC + bool "TIM7 DAC" + default n + depends on STM32_TIM7 && STM32_DAC + ---help--- + Reserve timer 7 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM7 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM7 DAC channel" + default STM32_TIM7_DAC1 + depends on STM32_TIM7_DAC + +config STM32_TIM7_DAC1 + bool "TIM7 DAC channel 1" + ---help--- + Reserve TIM7 to trigger DAC1 + +config STM32_TIM7_DAC2 + bool "TIM7 DAC channel 2" + ---help--- + Reserve TIM7 to trigger DAC2 + +endchoice + +config STM32_TIM8_DAC + bool "TIM8 DAC" + default n + depends on STM32_TIM8 && STM32_DAC + ---help--- + Reserve timer 8 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM8 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM8 DAC channel" + default STM32_TIM8_DAC1 + depends on STM32_TIM8_DAC + +config STM32_TIM8_DAC1 + bool "TIM8 DAC channel 1" + ---help--- + Reserve TIM8 to trigger DAC1 + +config STM32_TIM8_DAC2 + bool "TIM8 DAC channel 2" + ---help--- + Reserve TIM8 to trigger DAC2 + +endchoice + +config STM32_TIM9_DAC + bool "TIM9 DAC" + default n + depends on STM32_TIM9 && STM32_DAC + ---help--- + Reserve timer 9 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM9 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM9 DAC channel" + default STM32_TIM9_DAC1 + depends on STM32_TIM9_DAC + +config STM32_TIM9_DAC1 + bool "TIM9 DAC channel 1" + ---help--- + Reserve TIM9 to trigger DAC1 + +config STM32_TIM9_DAC2 + bool "TIM9 DAC channel 2" + ---help--- + Reserve TIM9 to trigger DAC2 + +endchoice + +config STM32_TIM10_DAC + bool "TIM10 DAC" + default n + depends on STM32_TIM10 && STM32_DAC + ---help--- + Reserve timer 10 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM10 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM10 DAC channel" + default STM32_TIM10_DAC1 + depends on STM32_TIM10_DAC + +config STM32_TIM10_DAC1 + bool "TIM10 DAC channel 1" + ---help--- + Reserve TIM10 to trigger DAC1 + +config STM32_TIM10_DAC2 + bool "TIM10 DAC channel 2" + ---help--- + Reserve TIM10 to trigger DAC2 + +endchoice + +config STM32_TIM11_DAC + bool "TIM11 DAC" + default n + depends on STM32_TIM11 && STM32_DAC + ---help--- + Reserve timer 11 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM11 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM11 DAC channel" + default STM32_TIM11_DAC1 + depends on STM32_TIM11_DAC + +config STM32_TIM11_DAC1 + bool "TIM11 DAC channel 1" + ---help--- + Reserve TIM11 to trigger DAC1 + +config STM32_TIM11_DAC2 + bool "TIM11 DAC channel 2" + ---help--- + Reserve TIM11 to trigger DAC2 + +endchoice + +config STM32_TIM12_DAC + bool "TIM12 DAC" + default n + depends on STM32_TIM12 && STM32_DAC + ---help--- + Reserve timer 12 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM12 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM12 DAC channel" + default STM32_TIM12_DAC1 + depends on STM32_TIM12_DAC + +config STM32_TIM12_DAC1 + bool "TIM12 DAC channel 1" + ---help--- + Reserve TIM12 to trigger DAC1 + +config STM32_TIM12_DAC2 + bool "TIM12 DAC channel 2" + ---help--- + Reserve TIM12 to trigger DAC2 + +endchoice + +config STM32_TIM13_DAC + bool "TIM13 DAC" + default n + depends on STM32_TIM13 && STM32_DAC + ---help--- + Reserve timer 13 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM13 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM13 DAC channel" + default STM32_TIM13_DAC1 + depends on STM32_TIM13_DAC + +config STM32_TIM13_DAC1 + bool "TIM13 DAC channel 1" + ---help--- + Reserve TIM13 to trigger DAC1 + +config STM32_TIM13_DAC2 + bool "TIM13 DAC channel 2" + ---help--- + Reserve TIM13 to trigger DAC2 + +endchoice + +config STM32_TIM14_DAC + bool "TIM14 DAC" + default n + depends on STM32_TIM14 && STM32_DAC + ---help--- + Reserve timer 14 for use by DAC + + Timer devices may be used for different purposes. If STM32_TIM14 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM14 DAC channel" + default STM32_TIM14_DAC1 + depends on STM32_TIM14_DAC + +config STM32_TIM14_DAC1 + bool "TIM14 DAC channel 1" + ---help--- + Reserve TIM14 to trigger DAC1 + +config STM32_TIM14_DAC2 + bool "TIM14 DAC channel 2" + ---help--- + Reserve TIM14 to trigger DAC2 + +endchoice + +config STM32_TIM1_CAP + bool "TIM1 Capture" + default n + depends on STM32_HAVE_TIM1 + ---help--- + Reserve timer 1 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM2_CAP + bool "TIM2 Capture" + default n + depends on STM32_HAVE_TIM2 + ---help--- + Reserve timer 2 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM3_CAP + bool "TIM3 Capture" + default n + depends on STM32_HAVE_TIM3 + ---help--- + Reserve timer 3 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM4_CAP + bool "TIM4 Capture" + default n + depends on STM32_HAVE_TIM4 + ---help--- + Reserve timer 4 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM5_CAP + bool "TIM5 Capture" + default n + depends on STM32_HAVE_TIM5 + ---help--- + Reserve timer 5 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM8_CAP + bool "TIM8 Capture" + default n + depends on STM32_HAVE_TIM8 + ---help--- + Reserve timer 8 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM9_CAP + bool "TIM9 Capture" + default n + depends on STM32_HAVE_TIM9 + ---help--- + Reserve timer 9 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM10_CAP + bool "TIM10 Capture" + default n + depends on STM32_HAVE_TIM10 + ---help--- + Reserve timer 10 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM11_CAP + bool "TIM11 Capture" + default n + depends on STM32_HAVE_TIM11 + ---help--- + Reserve timer 11 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM12_CAP + bool "TIM12 Capture" + default n + depends on STM32_HAVE_TIM12 + ---help--- + Reserve timer 12 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM13_CAP + bool "TIM13 Capture" + default n + depends on STM32_HAVE_TIM13 + ---help--- + Reserve timer 13 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32_TIM14_CAP + bool "TIM14 Capture" + default n + depends on STM32_HAVE_TIM14 + ---help--- + Reserve timer 14 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +menu "ADC Configuration" + depends on STM32_ADC + +config STM32_ADC1_DMA + bool "ADC1 DMA" + depends on STM32_ADC1 && STM32_HAVE_ADC1_DMA + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32_ADC2_DMA + bool "ADC2 DMA" + depends on STM32_ADC2 && STM32_HAVE_ADC2_DMA + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32_ADC3_DMA + bool "ADC3 DMA" + depends on STM32_ADC3 && STM32_HAVE_ADC3_DMA + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32_ADC4_DMA + bool "ADC4 DMA" + depends on STM32_ADC4 && STM32_HAVE_ADC4_DMA + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +endmenu + +menu "DAC Configuration" + depends on STM32_DAC1 || STM32_DAC2 + +config STM32_DAC1_DMA + bool "DAC1 DMA" + depends on STM32_DAC1 + default n + ---help--- + If DMA is selected, then a timer and output frequency must also be + provided to support the DMA transfer. The DMA transfer could be + supported by and EXTI trigger, but this feature is not currently + supported by the driver. + +if STM32_DAC1_DMA + +config STM32_DAC1_TIMER + int "DAC1 timer" + range 2 8 + +config STM32_DAC1_TIMER_FREQUENCY + int "DAC1 timer frequency" + default 0 + +endif + +config STM32_DAC2_DMA + bool "DAC2 DMA" + depends on STM32_DAC2 + default n + ---help--- + If DMA is selected, then a timer and output frequency must also be + provided to support the DMA transfer. The DMA transfer could be + supported by and EXTI trigger, but this feature is not currently + supported by the driver. + +if STM32_DAC2_DMA + +config STM32_DAC2_TIMER + int "DAC2 timer" + default 0 + range 2 8 + +config STM32_DAC2_TIMER_FREQUENCY + int "DAC2 timer frequency" + default 0 + +endif + +config STM32_DAC_DMA_BUFFER_SIZE + int "DAC DMA buffer size" + default 256 + +endmenu + +config STM32_USART + bool + +menu "U[S]ART Configuration" + depends on STM32_USART + +config USART1_RS485 + bool "RS-485 on USART1" + default n + depends on STM32_USART1 + ---help--- + Enable RS-485 interface on USART1. Your board config will have to + provide GPIO_USART1_RS485_DIR pin definition. Currently it cannot be + used with USART1_RXDMA. + +config USART1_RS485_DIR_POLARITY + int "USART1 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART1_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART1. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART1_RXDMA + bool "USART1 Rx DMA" + default n + depends on STM32_USART1 && (((STM32_STM32F10XX || STM32_STM32L15XX) && STM32_DMA1) || (!STM32_STM32F10XX && STM32_DMA2)) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART2_RS485 + bool "RS-485 on USART2" + default n + depends on STM32_USART2 + ---help--- + Enable RS-485 interface on USART2. Your board config will have to + provide GPIO_USART2_RS485_DIR pin definition. Currently it cannot be + used with USART2_RXDMA. + +config USART2_RS485_DIR_POLARITY + int "USART2 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART2_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART2. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART2_RXDMA + bool "USART2 Rx DMA" + default n + depends on STM32_USART2 && STM32_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART3_RS485 + bool "RS-485 on USART3" + default n + depends on STM32_USART3 + ---help--- + Enable RS-485 interface on USART3. Your board config will have to + provide GPIO_USART3_RS485_DIR pin definition. Currently it cannot be + used with USART3_RXDMA. + +config USART3_RS485_DIR_POLARITY + int "USART3 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART3_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART3. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART3_RXDMA + bool "USART3 Rx DMA" + default n + depends on STM32_USART3 && STM32_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART4_RS485 + bool "RS-485 on UART4" + default n + depends on STM32_UART4 + ---help--- + Enable RS-485 interface on UART4. Your board config will have to + provide GPIO_UART4_RS485_DIR pin definition. Currently it cannot be + used with UART4_RXDMA. + +config UART4_RS485_DIR_POLARITY + int "UART4 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART4_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART4. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART4_RXDMA + bool "UART4 Rx DMA" + default n + depends on STM32_UART4 && STM32_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART5_RS485 + bool "RS-485 on UART5" + default n + depends on STM32_UART5 + ---help--- + Enable RS-485 interface on UART5. Your board config will have to + provide GPIO_UART5_RS485_DIR pin definition. Currently it cannot be + used with UART5_RXDMA. + +config UART5_RS485_DIR_POLARITY + int "UART5 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART5_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART5. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART5_RXDMA + bool "UART5 Rx DMA" + default n + depends on STM32_UART5 && STM32_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART6_RS485 + bool "RS-485 on USART6" + default n + depends on STM32_USART6 + ---help--- + Enable RS-485 interface on USART6. Your board config will have to + provide GPIO_USART6_RS485_DIR pin definition. Currently it cannot be + used with USART6_RXDMA. + +config USART6_RS485_DIR_POLARITY + int "USART6 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART6_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART6. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART6_RXDMA + bool "USART6 Rx DMA" + default n + depends on STM32_USART6 && STM32_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART7_RS485 + bool "RS-485 on UART7" + default n + depends on STM32_UART7 + ---help--- + Enable RS-485 interface on UART7. Your board config will have to + provide GPIO_UART7_RS485_DIR pin definition. Currently it cannot be + used with UART7_RXDMA. + +config UART7_RS485_DIR_POLARITY + int "UART7 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART7_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART7. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART7_RXDMA + bool "UART7 Rx DMA" + default n + depends on STM32_UART7 && STM32_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART8_RS485 + bool "RS-485 on UART8" + default n + depends on STM32_UART8 + ---help--- + Enable RS-485 interface on UART8. Your board config will have to + provide GPIO_UART8_RS485_DIR pin definition. Currently it cannot be + used with UART8_RXDMA. + +config UART8_RS485_DIR_POLARITY + int "UART8 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART8_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART8. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART8_RXDMA + bool "UART8 Rx DMA" + default n + depends on STM32_UART8 && STM32_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_UART4 || STM32_UART5 || STM32_USART6 || STM32_UART7 || STM32_UART8 + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + console is always on /dev/ttyS0. If more than one UART is in use this + can, however, have the side-effect that all port mappings + (hardware USART1 -> /dev/ttyS0) change if the console is moved to another + UART. This is in particular relevant if a project uses the USB console + in some configs and a serial console in other configs, but does not + want the side effect of having all serial port names change when just + the console is moved from serial to USB. + +config STM32_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + depends on STM32_USART + default n + ---help--- + Enable UART RTS flow control using Software. Because STM + Current STM32 have broken HW based RTS behavior (they assert + nRTS after every byte received) Enable this setting workaround + this issue by useing software based management of RTS + +endmenu + +config STM32_USART_SINGLEWIRE + bool "Single Wire Support" + default n + depends on STM32_USART + ---help--- + Enable single wire UART support. The option enables support for the + TIOCSSINGLEWIRE ioctl in the STM32 serial driver. + +menu "SPI Configuration" + depends on STM32_SPI + +config STM32_SPI_INTERRUPTS + bool "Interrupt driver SPI" + default n + ---help--- + Select to enable interrupt driven SPI support. Non-interrupt-driven, + poll-waiting is recommended if the interrupt rate would be to high in + the interrupt driven case. + +config STM32_SPI_DMA + bool "SPI DMA" + default n + ---help--- + Use DMA to improve SPI transfer performance. Cannot be used with STM32_SPI_INTERRUPT. + +endmenu + +menu "I2C Configuration" + depends on STM32_I2C + +config STM32_I2C_ALT + bool "Alternate I2C implementation" + default n if !STM32_PERFORMANCELINE + default y if STM32_PERFORMANCELINE + depends on !STM32_STM32F30XX + ---help--- + This selection enables an alternative I2C driver. This alternate + driver implements some rather complex workarounds for errata against + the STM32 F103 "Performance Line". This selection is an option + because: (1) It has not yet been fully verified and (2) It is not + certain that he scope of this workaround is needed only for the F103. + +config STM32_I2C_DYNTIMEO + bool "Use dynamic timeouts" + default n + depends on STM32_I2C + +config STM32_I2C_DYNTIMEO_USECPERBYTE + int "Timeout Microseconds per Byte" + default 500 + depends on STM32_I2C_DYNTIMEO + +config STM32_I2C_DYNTIMEO_STARTSTOP + int "Timeout for Start/Stop (Milliseconds)" + default 1000 + depends on STM32_I2C_DYNTIMEO + +config STM32_I2CTIMEOSEC + int "Timeout seconds" + default 0 + depends on STM32_I2C + +config STM32_I2CTIMEOMS + int "Timeout Milliseconds" + default 500 + depends on STM32_I2C && !STM32_I2C_DYNTIMEO + +config STM32_I2CTIMEOTICKS + int "Timeout for Done and Stop (ticks)" + default 500 + depends on STM32_I2C && !STM32_I2C_DYNTIMEO + +config STM32_I2C_DUTY16_9 + bool "Frequency with Tlow/Thigh = 16/9 " + default n + depends on STM32_I2C + +endmenu + +menu "SDIO Configuration" + depends on STM32_SDIO + +config SDIO_DMA + bool "Support DMA data transfers" + default y if STM32_DMA2 + depends on STM32_DMA2 + ---help--- + Support DMA data transfers. Requires STM32_SDIO and config STM32_DMA2. + +config SDIO_PRI + hex "SDIO interrupt priority" + default 128 + depends on ARCH_IRQPRIO && EXPERIMENTAL + ---help--- + Select SDIO interrupt priority. Default: 128. + +config SDIO_DMAPRIO + hex "SDIO DMA priority" + default 0x00001000 if STM32_STM32F10XX + default 0x00010000 if !STM32_STM32F10XX + ---help--- + Select SDIO DMA prority. + + For STM32 F1 family, options are: 0x00000000 low, 0x00001000 medium, + 0x00002000 high, 0x00003000 very high. Default: medium. + + For other STM32's, options are: 0x00000000 low, 0x00010000 medium, + 0x00020000 high, 0x00030000 very high. Default: medium. + +config SDIO_WIDTH_D1_ONLY + bool "Use D1 only" + default n + ---help--- + Select 1-bit transfer mode. Default: 4-bit transfer mode. + +endmenu + +if STM32_BKPSRAM + +config STM32_BBSRAM + bool "BBSRAM File Support" + default n + +config STM32_BBSRAM_FILES + int "Max Files to support in BBSRAM" + default 4 + +config STM32_SAVE_CRASHDUMP + bool "Enable Saving Panic to BBSRAM" + default n + +endif # STM32_BKPSRAM + +config STM32_HAVE_RTC_COUNTER + bool + default n + +config STM32_HAVE_RTC_SUBSECONDS + bool + default n + +config RTC_MAGIC_REG + int "The BKP register used to store/check the Magic value to determine if RTC is set already" + default 0 + range 0 19 + depends on RTC && !STM32_HAVE_RTC_COUNTER + +config RTC_MAGIC + hex "Value used as Magic to determine if RTC is set already" + default 0xfacefeee + depends on RTC && !STM32_HAVE_RTC_COUNTER + +choice + prompt "RTC clock source" + default RTC_LSECLOCK + depends on RTC + +config RTC_LSECLOCK + bool "LSE clock" + ---help--- + Drive the RTC with the LSE clock + +config RTC_LSICLOCK + bool "LSI clock" + ---help--- + Drive the RTC with the LSI clock + +config RTC_HSECLOCK + bool "HSE clock" + ---help--- + Drive the RTC with the HSE clock, divided down to 1MHz. + +endchoice + +if STM32_ETHMAC +menu "Ethernet MAC configuration" + +config STM32_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config STM32_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + STM32_PHYINIT is defined in the configuration then the board specific logic must + provide stm32_phyinitialize(); The STM32 Ethernet driver will call this function + one time before it first uses the PHY. + +config STM32_MII + bool "Use MII interface" + default n + ---help--- + Support Ethernet MII interface. + +choice + prompt "MII clock configuration" + default STM32_MII_MCO if STM32_STM32F10XX + default STM32_MII_MCO1 if STM32_STM32F207 || STM32_STM32F40XX + depends on STM32_MII + +config STM32_MII_MCO + bool "Use MC0 as MII clock" + depends on STM32_STM32F10XX + ---help--- + Use MCO to clock the MII interface. Default: Use MC0 + +config STM32_MII_MCO1 + bool "Use MC01 as MII clock" + depends on (STM32_STM32F207 || STM32_STM32F40XX) + ---help--- + Use MCO1 to clock the MII interface. Default: Use MC01 + +config STM32_MII_MCO2 + bool "Use MC02 as MII clock" + depends on (STM32_STM32F207 || STM32_STM32F40XX) + ---help--- + Use MCO2 to clock the MII interface. Default: Use MC01 + +config STM32_MII_EXTCLK + bool "External MII clock" + ---help--- + Clocking is provided by external logic. Don't use MCO for MII + clock. Default: Use MC0[1] + +endchoice + +config STM32_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config STM32_ETHFD + bool "Full duplex" + default n + depends on !STM32_AUTONEG + ---help--- + If STM32_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config STM32_ETH100MBPS + bool "100 Mbps" + default n + depends on !STM32_AUTONEG + ---help--- + If STM32_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config STM32_PHYSR + int "PHY Status Register Address (decimal)" + depends on STM32_AUTONEG + ---help--- + This must be provided if STM32_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config STM32_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on STM32_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +config STM32_PHYSR_SPEED + hex "PHY Speed Mask" + depends on STM32_AUTONEG && !STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config STM32_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + depends on STM32_AUTONEG && !STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config STM32_PHYSR_MODE + hex "PHY Mode Mask" + depends on STM32_AUTONEG && !STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config STM32_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + depends on STM32_AUTONEG && !STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +config STM32_PHYSR_ALTMODE + hex "PHY Mode Mask" + depends on STM32_AUTONEG && STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config STM32_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + depends on STM32_AUTONEG && STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config STM32_PHYSR_100HD + hex "100Base-T Half Duplex Value" + depends on STM32_AUTONEG && STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config STM32_PHYSR_10FD + hex "10Base-T Full Duplex Value" + depends on STM32_AUTONEG && STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config STM32_PHYSR_100FD + hex "100Base-T Full Duplex Value" + depends on STM32_AUTONEG && STM32_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +config STM32_ETH_PTP + bool "Precision Time Protocol (PTP)" + default n + ---help--- + Precision Time Protocol (PTP). Not supported but some hooks are indicated + with this condition. + +config STM32_RMII + bool + default y if !STM32_MII + +choice + prompt "RMII clock configuration" + default STM32_RMII_MCO if STM32_STM32F10XX + default STM32_RMII_MCO1 if STM32_STM32F207 || STM32_STM32F40XX + depends on STM32_RMII + +config STM32_RMII_MCO + bool "Use MC0 as RMII clock" + depends on STM32_STM32F10XX + ---help--- + Use MCO to clock the RMII interface. Default: Use MC0 + +config STM32_RMII_MCO1 + bool "Use MC01 as RMII clock" + depends on (STM32_STM32F207 || STM32_STM32F40XX) + ---help--- + Use MCO1 to clock the RMII interface. Default: Use MC01 + +config STM32_RMII_MCO2 + bool "Use MC02 as RMII clock" + depends on (STM32_STM32F207 || STM32_STM32F40XX) + ---help--- + Use MCO2 to clock the RMII interface. Default: Use MC01 + +config STM32_RMII_EXTCLK + bool "External RMII clock" + ---help--- + Clocking is provided by external logic. Don't use MCO for RMII + clock. Default: Use MC0[1] + +endchoice + +config STM32_ETHMAC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu +endif + +menu "USB FS Host Configuration" + +config STM32_OTGFS_RXFIFO_SIZE + int "Rx Packet Size" + default 128 + depends on USBHOST && STM32_OTGFS + ---help--- + Size of the RX FIFO in 32-bit words. Default 128 (512 bytes) + +config STM32_OTGFS_NPTXFIFO_SIZE + int "Non-periodic Tx FIFO Size" + default 96 + depends on USBHOST && STM32_OTGFS + ---help--- + Size of the non-periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config STM32_OTGFS_PTXFIFO_SIZE + int "Periodic Tx FIFO size" + default 128 + depends on USBHOST && STM32_OTGFS + ---help--- + Size of the periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config STM32_OTGFS_DESCSIZE + int "Descriptor Size" + default 128 + depends on USBHOST && STM32_OTGFS + ---help--- + Maximum size to allocate for descriptor memory descriptor. Default: 128 + +config STM32_OTGFS_SOFINTR + bool "Enable SOF interrupts" + default n + depends on USBHOST && STM32_OTGFS + ---help--- + Enable SOF interrupts. Why would you ever want to do that? + +endmenu + +menu "USB HS Host Configuration" + +config STM32_OTGHS_RXFIFO_SIZE + int "Rx Packet Size" + default 128 + depends on USBHOST && STM32_OTGHS + ---help--- + Size of the RX FIFO in 32-bit words. Default 128 (512 bytes) + +config STM32_OTGHS_NPTXFIFO_SIZE + int "Non-periodic Tx FIFO Size" + default 96 + depends on USBHOST && STM32_OTGHS + ---help--- + Size of the non-periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config STM32_OTGHS_PTXFIFO_SIZE + int "Periodic Tx FIFO size" + default 128 + depends on USBHOST && STM32_OTGHS + ---help--- + Size of the periodic Tx FIFO in 32-bit words. Default 96 (384 bytes) + +config STM32_OTGHS_DESCSIZE + int "Descriptor Size" + default 128 + depends on USBHOST && STM32_OTGHS + ---help--- + Maximum size to allocate for descriptor memory descriptor. Default: 128 + +config STM32_OTGHS_SOFINTR + bool "Enable SOF interrupts" + default n + depends on USBHOST && STM32_OTGHS + ---help--- + Enable SOF interrupts. Why would you ever want to do that? + +endmenu + +menu "USB Host Debug Configuration" + +config STM32_USBHOST_REGDEBUG + bool "Register-Level Debug" + default n + depends on USBHOST && (STM32_OTGFS || STM32_OTGHS) + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +config STM32_USBHOST_PKTDUMP + bool "Packet Dump Debug" + default n + depends on USBHOST && (STM32_OTGFS || STM32_OTGHS) + ---help--- + Dump all incoming and outgoing USB packets. Depends on DEBUG. + +endmenu + +comment "USB Device Configuration" + +config STM32_USB_ITRMP + bool "Re-map USB interrupt" + default n if !STM32_CAN1 + default y if STM32_CAN1 + depends on STM32_USB && STM32_STM32F30XX + ---help--- + The legacy USB in the F1 series shared interrupt lines with USB + device and CAN1. In the F3 series, a hardware options was added to + either retain the legacy F1 behavior or to map the USB interrupts to + there own dedicated vectors. The option is available only for the + F3 family and selects the use of the dedicated USB interrupts. + +menu "CAN driver configuration" + depends on STM32_CAN1 || STM32_CAN2 + +config CAN1_BAUD + int "CAN1 BAUD" + default 250000 + depends on STM32_CAN1 + ---help--- + CAN1 BAUD rate. Required if STM32_CAN1 is defined. + +config CAN2_BAUD + int "CAN2 BAUD" + default 250000 + depends on STM32_CAN2 + ---help--- + CAN2 BAUD rate. Required if STM32_CAN2 is defined. + +config CAN_TSEG1 + int "TSEG1 quanta" + default 6 + ---help--- + The number of CAN time quanta in segment 1. Default: 6 + +config CAN_TSEG2 + int "TSEG2 quanta" + default 7 + ---help--- + The number of CAN time quanta in segment 2. Default: 7 +endmenu + +if STM32_LTDC + +menu "LTDC Configuration" + +config STM32_LTDC_INTERFACE + bool "LTDC interface support" + default n + ---help--- + Enable the ltdc interface to support ltdc layer control. + +config STM32_LTDC_BACKLIGHT + bool "Backlight support" + default y + +config STM32_LTDC_DEFBACKLIGHT + hex "Default backlight level" + default 0xf0 + +config STM32_LTDC_BACKCOLOR + hex "Background color" + default 0x0 + ---help--- + This is the background color that will be used as the LTDC + background layer color. It is an RGB888 format value. + +config STM32_LTDC_DITHER + bool "Dither support" + default n + +config STM32_LTDC_DITHER_RED + depends on STM32_LTDC_DITHER + int "Dither red width" + range 0 7 + default 2 + ---help--- + This is the dither red width. + +config STM32_LTDC_DITHER_GREEN + depends on STM32_LTDC_DITHER + int "Dither green width" + range 0 7 + default 2 + ---help--- + This is the dither green width. + +config STM32_LTDC_DITHER_BLUE + depends on STM32_LTDC_DITHER + int "Dither blue width" + range 0 7 + default 2 + ---help--- + This is the dither blue width. + +config STM32_LTDC_FB_BASE + hex "Framebuffer memory start address" + ---help--- + If you are using the the LTDC, then you must provide the address + of the start of the framebuffer. This address will typically + be in the SRAM or SDRAM memory region of the FSMC. + +config STM32_LTDC_FB_SIZE + int "Framebuffer memory size (bytes)" + default 0 + +choice + prompt "Layer 1 color format" + default STM32_LTDC_L1_RGB565 + +config STM32_LTDC_L1_L8 + bool "8 bpp L8 (8-bit CLUT)" + +config STM32_LTDC_L1_AL44 + bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)" + +config STM32_LTDC_L1_AL88 + bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)" + +config STM32_LTDC_L1_RGB565 + bool "16 bpp RGB 565" + +config STM32_LTDC_L1_ARGB4444 + bool "16 bpp ARGB 4444" + +config STM32_LTDC_L1_ARGB1555 + bool "16 bpp ARGB 1555" + +config STM32_LTDC_L1_RGB888 + bool "24 bpp RGB 888" + +config STM32_LTDC_L1_ARGB8888 + bool "32 bpp ARGB 8888" + +endchoice # Layer 1 color format + +config STM32_LTDC_L2 + bool "Enable Layer 2 support" + default y + +if STM32_LTDC_L2 + +choice + prompt "Layer 2 (top layer) color format" + default STM32_LTDC_L2_RGB565 + +config STM32_LTDC_L2_L8 + bool "8 bpp L8 (8-bit CLUT)" + +config STM32_LTDC_L2_AL44 + bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)" + +config STM32_LTDC_L2_AL88 + bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)" + +config STM32_LTDC_L2_RGB565 + bool "16 bpp RGB 565" + +config STM32_LTDC_L2_ARGB4444 + bool "16 bpp ARGB 4444" + +config STM32_LTDC_L2_ARGB1555 + bool "16 bpp ARGB 1555" + +config STM32_LTDC_L2_RGB888 + bool "24 bpp RGB 888" + +config STM32_LTDC_L2_ARGB8888 + bool "32 bpp ARGB 8888" + +endchoice # Layer 2 color format + +endif # STM32_LTDC_L2 + +if STM32_LTDC_L1_L8 || STM32_LTDC_L2_L8 + +config FB_CMAP + bool "Enable color map support" + default y + ---help--- + Enabling color map support is neccessary for ltdc L8 format. + +config FB_TRANSPARENCY + bool "Enable transparency color map support" + default y + ---help--- + Enabling transparency color map support is neccessary for ltdc L8 format. + +endif +endmenu + +endif # STM32_LTDC + +if STM32_DMA2D + +menu "DMA2D Configuration" + +config STM32_DMA2D_NLAYERS + int "Number DMA2D layers" + default 2 + ---help--- + Number of allocatable DMA2D layers except the LTDC layer. + +menu "Supported pixel format" + +config STM32_DMA2D_L8 + depends on FB_CMAP + bool "8 bpp L8 (8-bit CLUT)" + default y + +config STM32_DMA2D_AL44 + depends on FB_CMAP + bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)" + default n + +config STM32_DMA2D_AL88 + depends on FB_CMAP + bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)" + default n + +config STM32_DMA2D_RGB565 + bool "16 bpp RGB 565" + default y + +config STM32_DMA2D_ARGB4444 + bool "16 bpp ARGB 4444" + default n + +config STM32_DMA2D_ARGB1555 + bool "16 bpp ARGB 1555" + default n + +config STM32_DMA2D_RGB888 + bool "24 bpp RGB 888" + default y + +config STM32_DMA2D_ARGB8888 + bool "32 bpp ARGB 8888" + default n + +endmenu +endmenu +endif # STM32_DMA2D + +menu "QEncoder Driver" + depends on QENCODER + depends on STM32_TIM1 || STM32_TIM2 || STM32_TIM3 || STM32_TIM4 || STM32_TIM5 || STM32_TIM8 + +config STM32_TIM1_QE + bool "TIM1" + default n + depends on STM32_TIM1 + ---help--- + Reserve TIM1 for use by QEncoder. + +if STM32_TIM1_QE + +config STM32_TIM1_QECLKOUT + int "TIM1 output clock" + default 2800000 + ---help--- + The output clock of TIM1. + +endif + +config STM32_TIM2_QE + bool "TIM2" + default n + depends on STM32_TIM2 + ---help--- + Reserve TIM2 for use by QEncoder. + +if STM32_TIM2_QE + +config STM32_TIM2_QECLKOUT + int "TIM2 output clock" + default 2800000 + ---help--- + The output clock of TIM2. + +endif + +config STM32_TIM3_QE + bool "TIM3" + default n + depends on STM32_TIM3 + ---help--- + Reserve TIM3 for use by QEncoder. + +if STM32_TIM3_QE + +config STM32_TIM3_QECLKOUT + int "TIM3 output clock" + default 2800000 + ---help--- + The output clock of TIM3. + +endif + +config STM32_TIM4_QE + bool "TIM4" + default n + depends on STM32_TIM4 + ---help--- + Reserve TIM4 for use by QEncoder. + +if STM32_TIM4_QE + +config STM32_TIM4_QECLKOUT + int "TIM4 output clock" + default 2800000 + ---help--- + The output clock of TIM4. + +endif + +config STM32_TIM5_QE + bool "TIM5" + default n + depends on STM32_TIM5 + ---help--- + Reserve TIM5 for use by QEncoder. + +if STM32_TIM5_QE + +config STM32_TIM5_QECLKOUT + int "TIM5 output clock" + default 2800000 + ---help--- + The output clock of TIM5. + +endif + +config STM32_TIM8_QE + bool "TIM8" + default n + depends on STM32_TIM8 + ---help--- + Reserve TIM8 for use by QEncoder. + +if STM32_TIM8_QE + +config STM32_TIM8_QECLKOUT + int "TIM8 output clock" + default 2800000 + ---help--- + The output clock of TIM8. + +endif + +config STM32_QENCODER_FILTER + bool "Enable filtering on STM32 QEncoder input" + default y + +choice + depends on STM32_QENCODER_FILTER + prompt "Input channel sampling frequency" + default STM32_QENCODER_SAMPLE_FDTS_4 + +config STM32_QENCODER_SAMPLE_FDTS + bool "fDTS" + +config STM32_QENCODER_SAMPLE_CKINT + bool "fCK_INT" + +config STM32_QENCODER_SAMPLE_FDTS_2 + bool "fDTS/2" + +config STM32_QENCODER_SAMPLE_FDTS_4 + bool "fDTS/4" + +config STM32_QENCODER_SAMPLE_FDTS_8 + bool "fDTS/8" + +config STM32_QENCODER_SAMPLE_FDTS_16 + bool "fDTS/16" + +config STM32_QENCODER_SAMPLE_FDTS_32 + bool "fDTS/32" + +endchoice + +choice + depends on STM32_QENCODER_FILTER + prompt "Input channel event count" + default STM32_QENCODER_SAMPLE_EVENT_6 + +config STM32_QENCODER_SAMPLE_EVENT_1 + depends on STM32_QENCODER_SAMPLE_FDTS + bool "1" + +config STM32_QENCODER_SAMPLE_EVENT_2 + depends on STM32_QENCODER_SAMPLE_CKINT + bool "2" + +config STM32_QENCODER_SAMPLE_EVENT_4 + depends on STM32_QENCODER_SAMPLE_CKINT + bool "4" + +config STM32_QENCODER_SAMPLE_EVENT_5 + depends on STM32_QENCODER_SAMPLE_FDTS_16 || STM32_QENCODER_SAMPLE_FDTS_32 + bool "5" + +config STM32_QENCODER_SAMPLE_EVENT_6 + depends on !STM32_QENCODER_SAMPLE_FDTS && !STM32_QENCODER_SAMPLE_CKINT + bool "6" + +config STM32_QENCODER_SAMPLE_EVENT_8 + depends on !STM32_QENCODER_SAMPLE_FDTS + bool "8" + +endchoice + +endmenu diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..64034976b5ac7796516eb242d71a553987356c60 --- /dev/null +++ b/arch/arm/src/stm32/Make.defs @@ -0,0 +1,256 @@ +############################################################################ +# arch/arm/src/stm32/Make.defs +# +# Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +HEAD_ASRC = +else +HEAD_ASRC = stm32_vectors.S +endif + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vfork.c + +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y) +CMN_CSRCS += up_itm_syslog.c +endif + +CHIP_ASRCS = + +CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c +CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c +CHIP_CSRCS += stm32_dma.c stm32_lowputc.c stm32_serial.c stm32_spi.c +CHIP_CSRCS += stm32_sdio.c stm32_tim.c stm32_waste.c stm32_ccm.c stm32_uid.c +CHIP_CSRCS += stm32_capture.c + +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += stm32_tim_lowerhalf.c +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += stm32_timerisr.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CHIP_ASRCS += stm32_vectors.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c +endif + +ifeq ($(CONFIG_STM32_CCM_PROCFS),y) +CHIP_CSRCS += stm32_procfs_ccm.c +endif + +ifeq ($(CONFIG_STM32_I2C_ALT),y) +CHIP_CSRCS += stm32_i2c_alt.c +else +ifeq ($(CONFIG_STM32_STM32F30XX),y) +CHIP_CSRCS += stm32f30xxx_i2c.c +else +CHIP_CSRCS += stm32_i2c.c +endif +endif + +ifeq ($(CONFIG_USBDEV),y) +ifeq ($(CONFIG_STM32_USB),y) +CHIP_CSRCS += stm32_usbdev.c +endif +ifeq ($(CONFIG_STM32_OTGFS),y) +CHIP_CSRCS += stm32_otgfsdev.c +endif +ifeq ($(CONFIG_STM32_OTGHS),y) +CHIP_CSRCS += stm32_otghsdev.c +endif +endif + +ifeq ($(CONFIG_USBHOST),y) +ifeq ($(CONFIG_STM32_OTGFS),y) +CHIP_CSRCS += stm32_otgfshost.c +endif +ifeq ($(CONFIG_STM32_OTGHS),y) +CHIP_CSRCS += stm32_otghshost.c +endif +endif + +ifeq ($(CONFIG_USBHOST),y) +ifeq ($(CONFIG_USBHOST_TRACE),y) +CHIP_CSRCS += stm32_usbhost.c +else +ifeq ($(CONFIG_DEBUG_USB),y) +CHIP_CSRCS += stm32_usbhost.c +endif +endif +endif + +ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += stm32_idle.c +endif + +CHIP_CSRCS += stm32_pmstop.c stm32_pmstandby.c stm32_pmsleep.c + +ifneq ($(CONFIG_ARCH_CUSTOM_PMINIT),y) +CHIP_CSRCS += stm32_pminitialize.c +endif + +ifeq ($(CONFIG_STM32_ETHMAC),y) +CHIP_CSRCS += stm32_eth.c +endif + +ifeq ($(CONFIG_STM32_PWR),y) +CHIP_CSRCS += stm32_pwr.c stm32_exti_pwr.c +endif + +ifeq ($(CONFIG_RTC),y) +CHIP_CSRCS += stm32_rtc.c +ifeq ($(CONFIG_RTC_ALARM),y) +CHIP_CSRCS += stm32_exti_alarm.c +endif +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += stm32_rtc_lowerhalf.c +endif +endif + +ifeq ($(CONFIG_ADC),y) +CHIP_CSRCS += stm32_adc.c +endif + +ifeq ($(CONFIG_DAC),y) +CHIP_CSRCS += stm32_dac.c +endif + +ifeq ($(CONFIG_STM32_RNG),y) +CHIP_CSRCS += stm32_rng.c +endif + +ifeq ($(CONFIG_STM32_LTDC),y) +CHIP_CSRCS += stm32_ltdc.c +endif + +ifeq ($(CONFIG_STM32_DMA2D),y) +CHIP_CSRCS += stm32_dma2d.c +endif + +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += stm32_pwm.c +endif + +ifeq ($(CONFIG_QENCODER),y) +CHIP_CSRCS += stm32_qencoder.c +endif + +ifeq ($(CONFIG_CAN),y) +CHIP_CSRCS += stm32_can.c +endif + +ifeq ($(CONFIG_STM32_IWDG),y) +CHIP_CSRCS += stm32_iwdg.c +endif + +ifeq ($(CONFIG_STM32_WWDG),y) +CHIP_CSRCS += stm32_wwdg.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += stm32_dumpgpio.c +endif + +ifeq ($(CONFIG_STM32_AES),y) +CHIP_CSRCS += stm32_aes.c +endif + +ifeq ($(CONFIG_STM32_BBSRAM),y) +CHIP_CSRCS += stm32_bbsram.c +endif diff --git a/arch/arm/src/stm32/chip.h b/arch/arm/src/stm32/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..bba330edfaf7741f1a4d150cbefa3e63f2c1dc8f --- /dev/null +++ b/arch/arm/src/stm32/chip.h @@ -0,0 +1,169 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_H +#define __ARCH_ARM_SRC_STM32_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +/* Include the chip pin configuration file */ + +/* STM32L EnergyLite Line ***********************************************************/ + +#if defined(CONFIG_STM32_ENERGYLITE) + +/* STM32L15xx family */ + +# if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_pinmap.h" +# else +# error "Unsupported EnergyLite chip" +# endif + +/* STM32 F1 Family ******************************************************************/ + +#elif defined(CONFIG_STM32_STM32F10XX) + +/* STM32F100 Value Line */ + +# if defined(CONFIG_STM32_VALUELINE) +# include "chip/stm32f100_pinmap.h" + +/* STM32 F102 USB Access Medium Density Family */ +# elif defined(CONFIG_ARCH_CHIP_STM32F102CB) +# include "chip/stm32f102_pinmap.h" + +/* STM32 F103 Low / Medium Density Family */ +# elif defined(CONFIG_ARCH_CHIP_STM32F103C4) || \ + defined(CONFIG_ARCH_CHIP_STM32F103C8) || \ + defined(CONFIG_ARCH_CHIP_STM32F103CB) +# include "chip/stm32f103c_pinmap.h" + +/* STM32 F103 High Density Family */ +/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and differ + * only in the available FLASH and SRAM. + */ + +# elif defined(CONFIG_ARCH_CHIP_STM32F103RB) || \ + defined(CONFIG_ARCH_CHIP_STM32F103RC) || \ + defined(CONFIG_ARCH_CHIP_STM32F103RD) || \ + defined(CONFIG_ARCH_CHIP_STM32F103RE) || \ + defined(CONFIG_ARCH_CHIP_STM32F103RG) +# include "chip/stm32f103r_pinmap.h" + +/* STM32F103VC, STM32F103VD, and STM32F103VE are all provided in 100 pin packages and differ + * only in the available FLASH and SRAM. + */ + +# elif defined(CONFIG_ARCH_CHIP_STM32F103VC) || defined(CONFIG_ARCH_CHIP_STM32F103VE) +# include "chip/stm32f103v_pinmap.h" + +/* STM32F103ZC, STM32F103ZD, and STM32F103ZE are all provided in 144 pin packages and differ + * only in the available FLASH and SRAM. + */ +# elif defined(CONFIG_ARCH_CHIP_STM32F103ZE) +# include "chip/stm32f103z_pinmap.h" + +/* STM32 F105/F107 Connectivity Line */ + +# elif defined(CONFIG_ARCH_CHIP_STM32F105VB) +# include "chip/stm32f105v_pinmap.h" + +# elif defined(CONFIG_ARCH_CHIP_STM32F107VC) +# include "chip/stm32f107v_pinmap.h" +# else +# error "Unsupported STM32F10XXX chip" +# endif + +/* STM32 F2 Family ******************************************************************/ + +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_pinmap.h" + +/* STM32 F3 Family ******************************************************************/ + +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_pinmap.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_pinmap.h" + +/* STM32 F4 Family ******************************************************************/ + +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_pinmap.h" +#else +# error "No pinmap file for this STM32 chip" +#endif + +/* If the common ARMv7-M vector handling logic is used, then include the + * required vector definitions as well. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR +# if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_vectors.h" +# elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_vectors.h" +# elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_vectors.h" +# elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_vectors.h" +# elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_vectors.h" +# elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_vectors.h" +# else +# error "No vector file for this STM32 family" +# endif +#endif + +/* Include the chip memory map. */ + +#include "chip/stm32_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_adc.h b/arch/arm/src/stm32/chip/stm32_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..3a59ba25a8879f260bc86a38cb35f96e6dc27ba6 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_adc.h @@ -0,0 +1,889 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_adc.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_ADC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_ADC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_ADC_SR_OFFSET 0x0000 /* ADC status register (32-bit) */ +#define STM32_ADC_CR1_OFFSET 0x0004 /* ADC control register 1 (32-bit) */ +#define STM32_ADC_CR2_OFFSET 0x0008 /* ADC control register 2 (32-bit) */ +#define STM32_ADC_SMPR1_OFFSET 0x000c /* ADC sample time register 1 (32-bit) */ +#define STM32_ADC_SMPR2_OFFSET 0x0010 /* ADC sample time register 2 (32-bit) */ +#ifndef CONFIG_STM32_STM32L15XX +# define STM32_ADC_JOFR1_OFFSET 0x0014 /* ADC injected channel data offset register 1 (32-bit) */ +# define STM32_ADC_JOFR2_OFFSET 0x0018 /* ADC injected channel data offset register 2 (32-bit) */ +# define STM32_ADC_JOFR3_OFFSET 0x001c /* ADC injected channel data offset register 3 (32-bit) */ +# define STM32_ADC_JOFR4_OFFSET 0x0020 /* ADC injected channel data offset register 4 (32-bit) */ +# define STM32_ADC_HTR_OFFSET 0x0024 /* ADC watchdog high threshold register (32-bit) */ +# define STM32_ADC_LTR_OFFSET 0x0028 /* ADC watchdog low threshold register (32-bit) */ +# define STM32_ADC_SQR1_OFFSET 0x002c /* ADC regular sequence register 1 (32-bit) */ +# define STM32_ADC_SQR2_OFFSET 0x0030 /* ADC regular sequence register 2 (32-bit) */ +# define STM32_ADC_SQR3_OFFSET 0x0034 /* ADC regular sequence register 3 (32-bit) */ +# define STM32_ADC_JSQR_OFFSET 0x0038 /* ADC injected sequence register (32-bit) */ +# define STM32_ADC_JDR1_OFFSET 0x003c /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR2_OFFSET 0x0040 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR3_OFFSET 0x0044 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR4_OFFSET 0x0048 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_DR_OFFSET 0x004c /* ADC regular data register (32-bit) */ +#else +# define STM32_ADC_SMPR3_OFFSET 0x0014 /* ADC sample time register 3 (32-bit) */ +# define STM32_ADC_JOFR1_OFFSET 0x0018 /* ADC injected channel data offset register 1 (32-bit) */ +# define STM32_ADC_JOFR2_OFFSET 0x001c /* ADC injected channel data offset register 2 (32-bit) */ +# define STM32_ADC_JOFR3_OFFSET 0x0020 /* ADC injected channel data offset register 3 (32-bit) */ +# define STM32_ADC_JOFR4_OFFSET 0x0024 /* ADC injected channel data offset register 4 (32-bit) */ +# define STM32_ADC_HTR_OFFSET 0x0028 /* ADC watchdog high threshold register (32-bit) */ +# define STM32_ADC_LTR_OFFSET 0x002c /* ADC watchdog low threshold register (32-bit) */ +# define STM32_ADC_SQR1_OFFSET 0x0030 /* ADC regular sequence register 1 (32-bit) */ +# define STM32_ADC_SQR2_OFFSET 0x0034 /* ADC regular sequence register 2 (32-bit) */ +# define STM32_ADC_SQR3_OFFSET 0x0038 /* ADC regular sequence register 3 (32-bit) */ +# define STM32_ADC_SQR4_OFFSET 0x003c /* ADC regular sequence register 4 (32-bit) */ +# define STM32_ADC_SQR5_OFFSET 0x0040 /* ADC regular sequence register 5 (32-bit) */ +# define STM32_ADC_JSQR_OFFSET 0x0044 /* ADC injected sequence register (32-bit) */ +# define STM32_ADC_JDR1_OFFSET 0x0048 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR2_OFFSET 0x004c /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR3_OFFSET 0x0050 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_JDR4_OFFSET 0x0054 /* ADC injected data register 1 (32-bit) */ +# define STM32_ADC_DR_OFFSET 0x0058 /* ADC regular data register (32-bit) */ +# define STM32_ADC_SMPR0_OFFSET 0X005c /* ADC sample time register 3 (32-bit) */ +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define STM32_ADC_CSR_OFFSET 0x0000 /* Common status register */ +# define STM32_ADC_CCR_OFFSET 0x0004 /* Common control register */ +# ifndef CONFIG_STM32_STM32L15XX +# define STM32_ADC_CDR_OFFSET 0x0008 /* Data register for dual and triple modes */ +# endif +#endif + +/* Register Addresses *******************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +# define STM32_ADC1_BASE STM32_ADC_BASE +#endif + +#if STM32_NADC > 0 +# define STM32_ADC1_SR (STM32_ADC1_BASE+STM32_ADC_SR_OFFSET) +# define STM32_ADC1_CR1 (STM32_ADC1_BASE+STM32_ADC_CR1_OFFSET) +# define STM32_ADC1_CR2 (STM32_ADC1_BASE+STM32_ADC_CR2_OFFSET) +# define STM32_ADC1_SMPR1 (STM32_ADC1_BASE+STM32_ADC_SMPR1_OFFSET) +# define STM32_ADC1_SMPR2 (STM32_ADC1_BASE+STM32_ADC_SMPR2_OFFSET) +# ifdef CONFIG_STM32_STM32L15XX +# define STM32_ADC1_SMPR3 (STM32_ADC1_BASE+STM32_ADC_SMPR3_OFFSET) +# endif +# define STM32_ADC1_JOFR1 (STM32_ADC1_BASE+STM32_ADC_JOFR1_OFFSET) +# define STM32_ADC1_JOFR2 (STM32_ADC1_BASE+STM32_ADC_JOFR2_OFFSET) +# define STM32_ADC1_JOFR3 (STM32_ADC1_BASE+STM32_ADC_JOFR3_OFFSET) +# define STM32_ADC1_JOFR4 (STM32_ADC1_BASE+STM32_ADC_JOFR4_OFFSET) +# define STM32_ADC1_HTR (STM32_ADC1_BASE+STM32_ADC_HTR_OFFSET) +# define STM32_ADC1_LTR (STM32_ADC1_BASE+STM32_ADC_LTR_OFFSET) +# define STM32_ADC1_SQR1 (STM32_ADC1_BASE+STM32_ADC_SQR1_OFFSET) +# define STM32_ADC1_SQR2 (STM32_ADC1_BASE+STM32_ADC_SQR2_OFFSET) +# define STM32_ADC1_SQR3 (STM32_ADC1_BASE+STM32_ADC_SQR3_OFFSET) +# ifdef CONFIG_STM32_STM32L15XX +# define STM32_ADC1_SQR4 (STM32_ADC1_BASE+STM32_ADC_SQR4_OFFSET) +# define STM32_ADC1_SQR5 (STM32_ADC1_BASE+STM32_ADC_SQR5_OFFSET) +# endif +# define STM32_ADC1_JSQR (STM32_ADC1_BASE+STM32_ADC_JSQR_OFFSET) +# define STM32_ADC1_JDR1 (STM32_ADC1_BASE+STM32_ADC_JDR1_OFFSET) +# define STM32_ADC1_JDR2 (STM32_ADC1_BASE+STM32_ADC_JDR2_OFFSET) +# define STM32_ADC1_JDR3 (STM32_ADC1_BASE+STM32_ADC_JDR3_OFFSET) +# define STM32_ADC1_JDR4 (STM32_ADC1_BASE+STM32_ADC_JDR4_OFFSET) +# define STM32_ADC1_DR (STM32_ADC1_BASE+STM32_ADC_DR_OFFSET) +# ifdef CONFIG_STM32_STM32L15XX +# define STM32_ADC1_SMPR0 (STM32_ADC1_BASE+STM32_ADC_SMPR0_OFFSET) +# endif +#endif + +#if STM32_NADC > 1 +# define STM32_ADC2_SR (STM32_ADC2_BASE+STM32_ADC_SR_OFFSET) +# define STM32_ADC2_CR1 (STM32_ADC2_BASE+STM32_ADC_CR1_OFFSET) +# define STM32_ADC2_CR2 (STM32_ADC2_BASE+STM32_ADC_CR2_OFFSET) +# define STM32_ADC2_SMPR1 (STM32_ADC2_BASE+STM32_ADC_SMPR1_OFFSET) +# define STM32_ADC2_SMPR2 (STM32_ADC2_BASE+STM32_ADC_SMPR2_OFFSET) +# define STM32_ADC2_JOFR1 (STM32_ADC2_BASE+STM32_ADC_JOFR1_OFFSET) +# define STM32_ADC2_JOFR2 (STM32_ADC2_BASE+STM32_ADC_JOFR2_OFFSET) +# define STM32_ADC2_JOFR3 (STM32_ADC2_BASE+STM32_ADC_JOFR3_OFFSET) +# define STM32_ADC2_JOFR4 (STM32_ADC2_BASE+STM32_ADC_JOFR4_OFFSET) +# define STM32_ADC2_HTR (STM32_ADC2_BASE+STM32_ADC_HTR_OFFSET) +# define STM32_ADC2_LTR (STM32_ADC2_BASE+STM32_ADC_LTR_OFFSET) +# define STM32_ADC2_SQR1 (STM32_ADC2_BASE+STM32_ADC_SQR1_OFFSET) +# define STM32_ADC2_SQR2 (STM32_ADC2_BASE+STM32_ADC_SQR2_OFFSET) +# define STM32_ADC2_SQR3 (STM32_ADC2_BASE+STM32_ADC_SQR3_OFFSET) +# define STM32_ADC2_JSQR (STM32_ADC2_BASE+STM32_ADC_JSQR_OFFSET) +# define STM32_ADC2_JDR1 (STM32_ADC2_BASE+STM32_ADC_JDR1_OFFSET) +# define STM32_ADC2_JDR2 (STM32_ADC2_BASE+STM32_ADC_JDR2_OFFSET) +# define STM32_ADC2_JDR3 (STM32_ADC2_BASE+STM32_ADC_JDR3_OFFSET) +# define STM32_ADC2_JDR4 (STM32_ADC2_BASE+STM32_ADC_JDR4_OFFSET) +# define STM32_ADC2_DR (STM32_ADC2_BASE+STM32_ADC_DR_OFFSET) +#endif + +#if STM32_NADC > 2 +# define STM32_ADC3_SR (STM32_ADC3_BASE+STM32_ADC_SR_OFFSET) +# define STM32_ADC3_CR1 (STM32_ADC3_BASE+STM32_ADC_CR1_OFFSET) +# define STM32_ADC3_CR2 (STM32_ADC3_BASE+STM32_ADC_CR2_OFFSET) +# define STM32_ADC3_SMPR1 (STM32_ADC3_BASE+STM32_ADC_SMPR1_OFFSET) +# define STM32_ADC3_SMPR2 (STM32_ADC3_BASE+STM32_ADC_SMPR2_OFFSET) +# define STM32_ADC3_JOFR1 (STM32_ADC3_BASE+STM32_ADC_JOFR1_OFFSET) +# define STM32_ADC3_JOFR2 (STM32_ADC3_BASE+STM32_ADC_JOFR2_OFFSET) +# define STM32_ADC3_JOFR3 (STM32_ADC3_BASE+STM32_ADC_JOFR3_OFFSET) +# define STM32_ADC3_JOFR4 (STM32_ADC3_BASE+STM32_ADC_JOFR4_OFFSET) +# define STM32_ADC3_HTR (STM32_ADC3_BASE+STM32_ADC_HTR_OFFSET) +# define STM32_ADC3_LTR (STM32_ADC3_BASE+STM32_ADC_LTR_OFFSET) +# define STM32_ADC3_SQR1 (STM32_ADC3_BASE+STM32_ADC_SQR1_OFFSET) +# define STM32_ADC3_SQR2 (STM32_ADC3_BASE+STM32_ADC_SQR2_OFFSET) +# define STM32_ADC3_SQR3 (STM32_ADC3_BASE+STM32_ADC_SQR3_OFFSET) +# define STM32_ADC3_JSQR (STM32_ADC3_BASE+STM32_ADC_JSQR_OFFSET) +# define STM32_ADC3_JDR1 (STM32_ADC3_BASE+STM32_ADC_JDR1_OFFSET) +# define STM32_ADC3_JDR2 (STM32_ADC3_BASE+STM32_ADC_JDR2_OFFSET) +# define STM32_ADC3_JDR3 (STM32_ADC3_BASE+STM32_ADC_JDR3_OFFSET) +# define STM32_ADC3_JDR4 (STM32_ADC3_BASE+STM32_ADC_JDR4_OFFSET) +# define STM32_ADC3_DR (STM32_ADC3_BASE+STM32_ADC_DR_OFFSET) +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define STM32_ADC_CSR (STM32_ADCCMN_BASE+STM32_ADC_CSR_OFFSET) +# define STM32_ADC_CCR (STM32_ADCCMN_BASE+STM32_ADC_CCR_OFFSET) +# ifndef CONFIG_STM32_STM32L15XX +# define STM32_ADC_CDR (STM32_ADCCMN_BASE+STM32_ADC_CDR_OFFSET) +# endif +#endif + +/* Register Bitfield Definitions ********************************************************************/ + +/* ADC status register */ + +#define ADC_SR_AWD (1 << 0) /* Bit 0 : Analog watchdog flag */ +#define ADC_SR_EOC (1 << 1) /* Bit 1 : End of conversion */ +#define ADC_SR_JEOC (1 << 2) /* Bit 2 : Injected channel end of conversion */ +#define ADC_SR_JSTRT (1 << 3) /* Bit 3 : Injected channel Start flag */ +#define ADC_SR_STRT (1 << 4) /* Bit 4 : Regular channel Start flag */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define ADC_SR_OVR (1 << 5) /* Bit 5 : Overrun */ +#endif +#if defined(CONFIG_STM32_STM32L15XX) +# define ADC_SR_ADONS (1 << 6) /* Bit 6 : ADC ON status. Set and cleared by HW */ +# define ADC_SR_RCNR (1 << 8) /* Bit 8 : Regular channel not ready. Set and cleared by HW */ +# define ADC_SR_JCNR (1 << 9) /* Bit 9 : Injected channel not ready. Set and cleared by HW */ +#endif + +/* ADC control register 1 */ + +#define ADC_CR1_AWDCH_SHIFT (0) /* Bits 4-0: Analog watchdog channel select bits */ +#define ADC_CR1_AWDCH_MASK (0x1f << ADC_CR1_AWDCH_SHIFT) + +#define ADC_CR1_EOCIE (1 << 5) /* Bit 5: Interrupt enable for EOC */ +#define ADC_CR1_AWDIE (1 << 6) /* Bit 6: Analog Watchdog interrupt enable */ +#define ADC_CR1_JEOCIE (1 << 7) /* Bit 7: Interrupt enable for injected channels */ +#define ADC_CR1_SCAN (1 << 8) /* Bit 8: Scan mode */ +#define ADC_CR1_AWDSGL (1 << 9) /* Bit 9: Enable the watchdog on a single channel in scan mode */ +#define ADC_CR1_JAUTO (1 << 10) /* Bit 10: Automatic Injected Group conversion */ +#define ADC_CR1_DISCEN (1 << 11) /* Bit 11: Discontinuous mode on regular channels */ +#define ADC_CR1_JDISCEN (1 << 12) /* Bit 12: Discontinuous mode on injected channels */ + +#define ADC_CR1_DISCNUM_SHIFT (13) /* Bits 15-13: Discontinuous mode channel count */ +#define ADC_CR1_DISCNUM_MASK (0x07 << ADC_CR1_DISCNUM_SHIFT) + +#if defined(CONFIG_STM32_STM32L15XX) +# define ADC_CR1_PDD (1 << 16) /* Bit 16 : Power down during the delay phase. This bit must be written only when ADON=0 */ +# define ADC_CR1_PDI (1 << 17) /* Bit 17 : Power down during the idle phase. This bit must + * be written only when ADON=0 */ +#endif + +#ifdef CONFIG_STM32_STM32F10XX +# define ADC_CR1_DUALMOD_SHIFT (16) /* Bits 19-16: Dual mode selection */ +# define ADC_CR1_DUALMOD_MASK (0x0f << ADC_CR1_DUALMOD_SHIFT) +# define ADC_CR1_IND (0 << ADC_CR1_DUALMOD_SHIFT) /* 0000: Independent mode */ +# define ADC_CR1_RSIS (1 << ADC_CR1_DUALMOD_SHIFT) /* 0001: Combined regular simultaneous + injected simultaneous mode */ +# define ADC_CR1_RSAT (2 << ADC_CR1_DUALMOD_SHIFT) /* 0010: Combined regular simultaneous + alternate trigger mode */ +# define ADC_CR1_ISFI (3 << ADC_CR1_DUALMOD_SHIFT) /* 0011: Combined injected simultaneous + fast interleaved mode */ +# define ADC_CR1_ISFL (4 << ADC_CR1_DUALMOD_SHIFT) /* 0100: Combined injected simultaneous + slow Interleaved mode */ +# define ADC_CR1_IS (5 << ADC_CR1_DUALMOD_SHIFT) /* 0101: Injected simultaneous mode only */ +# define ADC_CR1_RS (6 << ADC_CR1_DUALMOD_SHIFT) /* 0110: Regular simultaneous mode only */ +# define ADC_CR1_FI (7 << ADC_CR1_DUALMOD_SHIFT) /* 0111: Fast interleaved mode only */ +# define ADC_CR1_SI (8 << ADC_CR1_DUALMOD_SHIFT) /* 1000: Slow interleaved mode only */ +# define ADC_CR1_AT (9 << ADC_CR1_DUALMOD_SHIFT) /* 1001: Alternate trigger mode only */ +#endif + +#define ADC_CR1_JAWDEN (1 << 22) /* Bit 22: Analog watchdog enable on injected channels */ +#define ADC_CR1_AWDEN (1 << 23) /* Bit 23: Analog watchdog enable on regular channels */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define ADC_CR1_RES_SHIFT (24) /* Bits 24-25: Resolution */ +# define ADC_CR1_RES_MASK (3 << ADC_CR1_RES_SHIFT) +# define ADC_CR1_RES_12BIT (0 << ADC_CR1_RES_SHIFT) /* 15 ADCCLK cycles. For STM32L15XX: 12 ADCCLK cycles */ +# define ADC_CR1_RES_10BIT (1 << ADC_CR1_RES_SHIFT) /* 13 ADCCLK cycles. For STM32L15XX: 11 ADCCLK cycles */ +# define ADC_CR1_RES_8BIT (2 << ADC_CR1_RES_SHIFT) /* 11 ADCCLK cycles. For STM32L15XX: 9 ADCCLK cycles */ +# define ADC_CR1_RES_6BIT (3 << ADC_CR1_RES_SHIFT) /* 9 ADCCLK cycles. For STM32L15XX: 7 ADCCLK cycles */ +# define ADC_CR1_OVRIE (1 << 26) /* Bit 26: Overrun interrupt enable */ +#endif + +/* ADC control register 2 */ + +#define ADC_CR2_ADON (1 << 0) /* Bit 0: A/D Converter ON / OFF */ +#define ADC_CR2_CONT (1 << 1) /* Bit 1: Continuous Conversion */ + +#ifdef CONFIG_STM32_STM32F10XX +# define ADC_CR2_CAL (1 << 2) /* Bit 2: A/D Calibration */ +#elif defined(CONFIG_STM32_STM32L15XX) +# define ADC_CR2_CFG (1 << 2) /* Bit 2 : ADC configuration. This bit must be modified only when no + * conversion is on going. This bit is available in high and medium+ + * density devices only. + */ +#endif + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_CR2_RSTCAL (1 << 3) /* Bit 3: Reset Calibration */ +#endif + +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_CR2_DELS_SHIFT (4) /* Bits 2-0: Delay selection */ +# define ADC_CR2_DELS_MASK (0x07 << ADC_CR2_DELS_SHIFT) +# +# define ADC_CR2_DELS_NODEL (0x0 << ADC_CR2_DELS_SHIFT) /* No delay */ +# define ADC_CR2_DELS_TILLRD (0x01 << ADC_CR2_DELS_SHIFT) /* Until the converted data have been read */ +# define ADC_CR2_DELS_APB7 (0x02 << ADC_CR2_DELS_SHIFT) /* 7 APB clock cycles after the end of conversion */ +# define ADC_CR2_DELS_APB15 (0x03 << ADC_CR2_DELS_SHIFT) /* 15 APB clock cycles after the end of conversion */ +# define ADC_CR2_DELS_APB31 (0x04 << ADC_CR2_DELS_SHIFT) /* 31 APB clock cycles after the end of conversion */ +# define ADC_CR2_DELS_APB63 (0x05 << ADC_CR2_DELS_SHIFT) /* 63 APB clock cycles after the end of conversion */ +# define ADC_CR2_DELS_APB127 (0x06 << ADC_CR2_DELS_SHIFT) /* 127 APB clock cycles after the end of conversion */ +# define ADC_CR2_DELS_APB255 (0x07 << ADC_CR2_DELS_SHIFT) /* 255 APB clock cycles after the end of conversion */ +#endif + +#define ADC_CR2_DMA (1 << 8) /* Bit 8: Direct Memory access mode */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define ADC_CR2_DDS (1 << 9) /* Bit 9: DMA disable selection (for single ADC mode) */ +# define ADC_CR2_EOCS (1 << 10) /* Bit 10: End of conversion selection */ +#endif + +#define ADC_CR2_ALIGN (1 << 11) /* Bit 11: Data Alignment */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) + /* Bits 12-15: Reserved */ +# define ADC_CR2_JEXTSEL_SHIFT (16) /* Bits 16-19: External event select for injected group */ +# define ADC_CR2_JEXTSEL_MASK (0x0F << ADC_CR2_JEXTSEL_SHIFT) +# ifdef CONFIG_STM32_STM32L15XX +# define ADC_CR2_JEXTSEL_T9CC1 (0x00 << ADC_CR2_JEXTSEL_SHIFT) /* 0000: Timer 9 CC1 event */ +# define ADC_CR2_JEXTSEL_T9TRGO (0x01 << ADC_CR2_JEXTSEL_SHIFT) /* 0001: Timer 9 TRGO event */ +# define ADC_CR2_JEXTSEL_T2TRGO (0x02 << ADC_CR2_JEXTSEL_SHIFT) /* 0010: Timer 2 TRGO event*/ +# define ADC_CR2_JEXTSEL_T2CC1 (0x03 << ADC_CR2_JEXTSEL_SHIFT) /* 0011: Timer 2 CC1 event */ +# define ADC_CR2_JEXTSEL_T3CC4 (0x04 << ADC_CR2_JEXTSEL_SHIFT) /* 0100: Timer 3 CC4 event */ +# define ADC_CR2_JEXTSEL_T4TRGO (0x05 << ADC_CR2_JEXTSEL_SHIFT) /* 0101: Timer 4 TRGO event */ +# define ADC_CR2_JEXTSEL_T4CC1 (0x06 << ADC_CR2_JEXTSEL_SHIFT) /* 0110: Timer 4 CC1 event */ +# define ADC_CR2_JEXTSEL_T4CC2 (0x07 << ADC_CR2_JEXTSEL_SHIFT) /* 0111: Timer 4 CC2 event */ +# define ADC_CR2_JEXTSEL_T4CC3 (0x08 << ADC_CR2_JEXTSEL_SHIFT) /* 1000: Timer 4 CC3 event */ +# define ADC_CR2_JEXTSEL_T10CC1 (0x09 << ADC_CR2_JEXTSEL_SHIFT) /* 1001: Timer 10 CC1 event */ +# define ADC_CR2_JEXTSEL_T7TRGO (0x0A << ADC_CR2_JEXTSEL_SHIFT) /* 1010: Timer 7 TRGO event */ +# define ADC_CR2_JEXTSEL_EXTI15 (0x0F << ADC_CR2_JEXTSEL_SHIFT) /* 1111: EXTI line 15 */ +# else +# define ADC_CR2_JEXTSEL_T1CC4 (0x00 << ADC_CR2_JEXTSEL_SHIFT) /* 0000: Timer 1 CC4 event */ +# define ADC_CR2_JEXTSEL_T1TRGO (0x01 << ADC_CR2_JEXTSEL_SHIFT) /* 0001: Timer 1 TRGO event */ +# define ADC_CR2_JEXTSEL_T2CC1 (0x02 << ADC_CR2_JEXTSEL_SHIFT) /* 0010: Timer 2 CC1 event */ +# define ADC_CR2_JEXTSEL_T2TRGO (0x03 << ADC_CR2_JEXTSEL_SHIFT) /* 0011: Timer 2 TRGO event */ +# define ADC_CR2_JEXTSEL_T3CC2 (0x04 << ADC_CR2_JEXTSEL_SHIFT) /* 0100: Timer 3 CC2 event */ +# define ADC_CR2_JEXTSEL_T3CC4 (0x05 << ADC_CR2_JEXTSEL_SHIFT) /* 0101: Timer 3 CC4 event */ +# define ADC_CR2_JEXTSEL_T4CC1 (0x06 << ADC_CR2_JEXTSEL_SHIFT) /* 0110: Timer 4 CC1 event */ +# define ADC_CR2_JEXTSEL_T4CC2 (0x07 << ADC_CR2_JEXTSEL_SHIFT) /* 0111: Timer 4 CC2 event */ +# define ADC_CR2_JEXTSEL_T4CC3 (0x08 << ADC_CR2_JEXTSEL_SHIFT) /* 1000: Timer 4 CC3 event */ +# define ADC_CR2_JEXTSEL_T4TRGO (0x09 << ADC_CR2_JEXTSEL_SHIFT) /* 1001: Timer 4 TRGO event */ +# define ADC_CR2_JEXTSEL_T5CC4 (0x0A << ADC_CR2_JEXTSEL_SHIFT) /* 1010: Timer 5 CC4 event */ +# define ADC_CR2_JEXTSEL_T5TRGO (0x0B << ADC_CR2_JEXTSEL_SHIFT) /* 1011: Timer 5 TRGO event */ +# define ADC_CR2_JEXTSEL_T8CC2 (0x0C << ADC_CR2_JEXTSEL_SHIFT) /* 1100: Timer 8 CC2 event */ +# define ADC_CR2_JEXTSEL_T8CC3 (0x0D << ADC_CR2_JEXTSEL_SHIFT) /* 1101: Timer 8 CC3 event */ +# define ADC_CR2_JEXTSEL_T8CC4 (0x0E << ADC_CR2_JEXTSEL_SHIFT) /* 1110: Timer 8 CC4 event */ +# define ADC_CR2_JEXTSEL_EXTI15 (0x0F << ADC_CR2_JEXTSEL_SHIFT) /* 1111: EXTI line 15 */ +# endif + +# define ADC_CR2_JEXTEN_SHIFT (20) /* Bits 20-21: External trigger enable for injected channels */ +# define ADC_CR2_JEXTEN_MASK (3 << ADC_CR2_JEXTEN_SHIFT) +# define ADC_CR2_JEXTEN_NONE (0 << ADC_CR2_JEXTEN_SHIFT) /* 00: Trigger detection disabled */ +# define ADC_CR2_JEXTEN_RISING (1 << ADC_CR2_JEXTEN_SHIFT) /* 01: Trigger detection on the rising edge */ +# define ADC_CR2_JEXTEN_FALLING (2 << ADC_CR2_JEXTEN_SHIFT) /* 10: Trigger detection on the falling edge */ +# define ADC_CR2_JEXTEN_BOTH (3 << ADC_CR2_JEXTEN_SHIFT) /* 11: Trigger detection on both the rising and falling edges */ + +# define ADC_CR2_JSWSTART (1 << 22) /* Bit 22: Start Conversion of injected channels */ + /* Bit 23: Reserved, must be kept at reset value. */ +# define ADC_CR2_EXTSEL_SHIFT (24) /* Bits 24-27: External Event Select for regular group */ +# define ADC_CR2_EXTSEL_MASK (0x0F << ADC_CR2_EXTSEL_SHIFT) +# ifdef CONFIG_STM32_STM32L15XX +# define ADC_CR2_EXTSEL_T9CC2 (0x00 << ADC_CR2_EXTSEL_SHIFT) /* 0000: Timer 9 CC2 event */ +# define ADC_CR2_EXTSEL_T9TRGO (0x01 << ADC_CR2_EXTSEL_SHIFT) /* 0001: Timer 9 TRGO event */ +# define ADC_CR2_EXTSEL_T2CC3 (0x02 << ADC_CR2_EXTSEL_SHIFT) /* 0010: Timer 2 CC3 event */ +# define ADC_CR2_EXTSEL_T2CC2 (0x03 << ADC_CR2_EXTSEL_SHIFT) /* 0011: Timer 2 CC2 event */ +# define ADC_CR2_EXTSEL_T3TRGO (0x04 << ADC_CR2_EXTSEL_SHIFT) /* 0100: Timer 3 TRGO event */ +# define ADC_CR2_EXTSEL_T4CC4 (0x05 << ADC_CR2_EXTSEL_SHIFT) /* 0101: Timer 4 CC4 event */ +# define ADC_CR2_EXTSEL_T2TRGO (0x06 << ADC_CR2_EXTSEL_SHIFT) /* 0110: Timer 2 TRGO event */ +# define ADC_CR2_EXTSEL_T3CC1 (0x07 << ADC_CR2_EXTSEL_SHIFT) /* 0111: Timer 3 CC1 event */ +# define ADC_CR2_EXTSEL_T3CC3 (0x08 << ADC_CR2_EXTSEL_SHIFT) /* 1000: Timer 3 CC3 event */ +# define ADC_CR2_EXTSEL_T4TRGO (0x09 << ADC_CR2_EXTSEL_SHIFT) /* 1001: Timer 4 TRGO event */ +# define ADC_CR2_EXTSEL_T6TRGO (0x0A << ADC_CR2_EXTSEL_SHIFT) /* 1010: Timer 6 TRGO event */ +# define ADC_CR2_EXTSEL_EXTI11 (0x0F << ADC_CR2_EXTSEL_SHIFT) /* 1111: EXTI line 11 */ +# else +# define ADC_CR2_EXTSEL_T1CC1 (0x0 << ADC_CR2_EXTSEL_SHIFT) /* 0000: Timer 1 CC1 event */ +# define ADC_CR2_EXTSEL_T1CC2 (0x01 << ADC_CR2_EXTSEL_SHIFT) /* 0001: Timer 1 CC2 event */ +# define ADC_CR2_EXTSEL_T1CC3 (0x02 << ADC_CR2_EXTSEL_SHIFT) /* 0010: Timer 1 CC3 event */ +# define ADC_CR2_EXTSEL_T2CC2 (0x03 << ADC_CR2_EXTSEL_SHIFT) /* 0011: Timer 2 CC2 event */ +# define ADC_CR2_EXTSEL_T2CC3 (0x04 << ADC_CR2_EXTSEL_SHIFT) /* 0100: Timer 2 CC3 event */ +# define ADC_CR2_EXTSEL_T2CC4 (0x05 << ADC_CR2_EXTSEL_SHIFT) /* 0101: Timer 2 CC4 event */ +# define ADC_CR2_EXTSEL_T2TRGO (0x06 << ADC_CR2_EXTSEL_SHIFT) /* 0110: Timer 2 TRGO event */ +# define ADC_CR2_EXTSEL_T3CC1 (0x07 << ADC_CR2_EXTSEL_SHIFT) /* 0111: Timer 3 CC1 event */ +# define ADC_CR2_EXTSEL_T3TRGO (0x08 << ADC_CR2_EXTSEL_SHIFT) /* 1000: Timer 3 TRGO event */ +# define ADC_CR2_EXTSEL_T4CC4 (0x09 << ADC_CR2_EXTSEL_SHIFT) /* 1001: Timer 4 CC4 event */ +# define ADC_CR2_EXTSEL_T5CC1 (0x0A << ADC_CR2_EXTSEL_SHIFT) /* 1010: Timer 5 CC1 event */ +# define ADC_CR2_EXTSEL_T5CC2 (0x0B << ADC_CR2_EXTSEL_SHIFT) /* 1011: Timer 5 CC2 event */ +# define ADC_CR2_EXTSEL_T5CC3 (0x0C << ADC_CR2_EXTSEL_SHIFT) /* 1100: Timer 5 CC3 event */ +# define ADC_CR2_EXTSEL_T8CC1 (0x0D << ADC_CR2_EXTSEL_SHIFT) /* 1101: Timer 8 CC1 event */ +# define ADC_CR2_EXTSEL_T8TRGO (0x0E << ADC_CR2_EXTSEL_SHIFT) /* 1110: Timer 8 TRGO event */ +# define ADC_CR2_EXTSEL_EXTI11 (0x0F << ADC_CR2_EXTSEL_SHIFT) /* 1111: EXTI line 11 */ +# endif + +# define ADC_CR2_EXTEN_SHIFT (28) /* Bits 28-29: External trigger enable for regular channels */ +# define ADC_CR2_EXTEN_MASK (3 << ADC_CR2_EXTEN_SHIFT) +# define ADC_CR2_EXTEN_NONE (0 << ADC_CR2_EXTEN_SHIFT) /* 00: Trigger detection disabled */ +# define ADC_CR2_EXTEN_RISING (1 << ADC_CR2_EXTEN_SHIFT) /* 01: Trigger detection on the rising edge */ +# define ADC_CR2_EXTEN_FALLING (2 << ADC_CR2_EXTEN_SHIFT) /* 10: Trigger detection on the falling edge */ +# define ADC_CR2_EXTEN_BOTH (3 << ADC_CR2_EXTEN_SHIFT) /* 11: Trigger detection on both the rising and falling edges */ + +# define ADC_CR2_SWSTART (1 << 30) /* Bit 30: Start Conversion of regular channels */ + +#else +# define ADC_CR2_JEXTSEL_SHIFT (12) /* Bits 12-14: External event select for injected group */ +# define ADC_CR2_JEXTSEL_MASK (7 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_T1TRGO (0 << ADC_CR2_JEXTSEL_SHIFT) /* 000: Timer 1 TRGO event */ +# define ADC_CR2_JEXTSEL_T1CC4 (1 << ADC_CR2_JEXTSEL_SHIFT) /* 001: Timer 1 CC4 event */ +# define ADC_CR2_JEXTSEL_T2TRGO (2 << ADC_CR2_JEXTSEL_SHIFT) /* 010: Timer 2 TRGO event */ +# define ADC_CR2_JEXTSEL_T2CC1 (3 << ADC_CR2_JEXTSEL_SHIFT) /* 011: Timer 2 CC1 event */ +# define ADC_CR2_JEXTSEL_T3CC4 (4 << ADC_CR2_JEXTSEL_SHIFT) /* 100: Timer 3 CC4 event */ +# define ADC_CR2_JEXTSEL_T4TRGO (5 << ADC_CR2_JEXTSEL_SHIFT) /* 101: Timer 4 TRGO event */ +# define ADC_CR2_JEXTSEL_EXTI15 (6 << ADC_CR2_JEXTSEL_SHIFT) /* 110: EXTI line 15 */ +# define ADC_CR2_JEXTSEL_SWSTART (7 << ADC_CR2_JEXTSEL_SHIFT) /* 111: JSWSTART */ + +# define ADC_CR2_JEXTTRIG (1 << 15) /* Bit 15: External Trigger Conversion mode for injected channels */ +# define ADC_CR2_EXTSEL_SHIFT (17) /* Bits 19-17: External Event Select for regular group */ +# define ADC_CR2_EXTSEL_MASK (7 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_T1CC1 (0 << ADC_CR2_EXTSEL_SHIFT) /* 000: Timer 1 CC1 event */ +# define ADC_CR2_EXTSEL_T1CC2 (1 << ADC_CR2_EXTSEL_SHIFT) /* 001: Timer 1 CC2 event */ +# define ADC_CR2_EXTSEL_T1CC3 (2 << ADC_CR2_EXTSEL_SHIFT) /* 010: Timer 1 CC3 event */ +# define ADC_CR2_EXTSEL_T2CC2 (3 << ADC_CR2_EXTSEL_SHIFT) /* 011: Timer 2 CC2 event */ +# define ADC_CR2_EXTSEL_T3TRGO (4 << ADC_CR2_EXTSEL_SHIFT) /* 100: Timer 3 TRGO event */ +# define ADC_CR2_EXTSEL_T4CC4 (5 << ADC_CR2_EXTSEL_SHIFT) /* 101: Timer 4 CC4 event */ +# define ADC_CR2_EXTSEL_EXTI11 (6 << ADC_CR2_EXTSEL_SHIFT) /* 110: EXTI line 11 */ +# define ADC_CR2_EXTSEL_SWSTART (7 << ADC_CR2_EXTSEL_SHIFT) /* 111: SWSTART */ + +# define ADC_CR2_EXTTRIG (1 << 20) /* Bit 20: External Trigger Conversion mode for regular channels */ +# define ADC_CR2_JSWSTART (1 << 21) /* Bit 21: Start Conversion of injected channels */ +# define ADC_CR2_SWSTART (1 << 22) /* Bit 22: Start Conversion of regular channels */ +# define ADC_CR2_TSVREFE (1 << 23) /* Bit 23: Temperature Sensor and VREFINT Enable */ +#endif + +/* ADC sample time register 1 */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + +# define ADC_SMPR_3 0 /* 000: 3 cycles */ +# define ADC_SMPR_15 1 /* 001: 15 cycles */ +# define ADC_SMPR_28 2 /* 010: 28 cycles */ +# define ADC_SMPR_56 3 /* 011: 56 cycles */ +# define ADC_SMPR_84 4 /* 100: 84 cycles */ +# define ADC_SMPR_112 5 /* 101: 112 cycles */ +# define ADC_SMPR_144 6 /* 110: 144 cycles */ +# define ADC_SMPR_480 7 /* 111: 480 cycles */ + +#elif !defined(CONFIG_STM32_STM32L15XX) && !defined(CONFIG_STM32_STM32F20XX) && !defined(CONFIG_STM32_STM32F40XX) + +# define ADC_SMPR_1p5 0 /* 000: 1.5 cycles */ +# define ADC_SMPR_7p5 1 /* 001: 7.5 cycles */ +# define ADC_SMPR_13p5 2 /* 010: 13.5 cycles */ +# define ADC_SMPR_28p5 3 /* 011: 28.5 cycles */ +# define ADC_SMPR_41p5 4 /* 100: 41.5 cycles */ +# define ADC_SMPR_55p5 5 /* 101: 55.5 cycles */ +# define ADC_SMPR_71p5 6 /* 110: 71.5 cycles */ +# define ADC_SMPR_239p5 7 /* 111: 239.5 cycles */ + +#elif defined(CONFIG_STM32_STM32L15XX) + +# define ADC_SMPR_4 0 /* 000: 3 cycles */ +# define ADC_SMPR_9 1 /* 001: 9 cycles */ +# define ADC_SMPR_16 2 /* 010: 16 cycles */ +# define ADC_SMPR_24 3 /* 011: 24 cycles */ +# define ADC_SMPR_48 4 /* 100: 48 cycles */ +# define ADC_SMPR_96 5 /* 101: 96 cycles */ +# define ADC_SMPR_192 6 /* 110: 192 cycles */ +# define ADC_SMPR_384 7 /* 111: 384 cycles */ + +#endif + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_SMPR1_SMP10_SHIFT (0) /* Bits 0-2: Channel 10 Sample time selection */ +# define ADC_SMPR1_SMP10_MASK (7 << ADC_SMPR1_SMP10_SHIFT) +# define ADC_SMPR1_SMP11_SHIFT (3) /* Bits 3-5: Channel 11 Sample time selection */ +# define ADC_SMPR1_SMP11_MASK (7 << ADC_SMPR1_SMP11_SHIFT) +# define ADC_SMPR1_SMP12_SHIFT (6) /* Bits 6-8: Channel 12 Sample time selection */ +# define ADC_SMPR1_SMP12_MASK (7 << ADC_SMPR1_SMP12_SHIFT) +# define ADC_SMPR1_SMP13_SHIFT (9) /* Bits 9-11: Channel 13 Sample time selection */ +# define ADC_SMPR1_SMP13_MASK (7 << ADC_SMPR1_SMP13_SHIFT) +# define ADC_SMPR1_SMP14_SHIFT (12) /* Bits 12-14: Channel 14 Sample time selection */ +# define ADC_SMPR1_SMP14_MASK (7 << ADC_SMPR1_SMP14_SHIFT) +# define ADC_SMPR1_SMP15_SHIFT (15) /* Bits 15-17: Channel 15 Sample time selection */ +# define ADC_SMPR1_SMP15_MASK (7 << ADC_SMPR1_SMP15_SHIFT) +# define ADC_SMPR1_SMP16_SHIFT (18) /* Bits 18-20: Channel 16 Sample time selection */ +# define ADC_SMPR1_SMP16_MASK (7 << ADC_SMPR1_SMP16_SHIFT) +# define ADC_SMPR1_SMP17_SHIFT (21) /* Bits 21-23: Channel 17 Sample time selection */ +# define ADC_SMPR1_SMP17_MASK (7 << ADC_SMPR1_SMP17_SHIFT) +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ADC_SMPR1_SMP18_SHIFT (21) /* Bits 24-26: Channel 18 Sample time selection */ +# define ADC_SMPR1_SMP18_MASK (7 << ADC_SMPR1_SMP17_SHIFT) +# endif +#else +# define ADC_SMPR1_SMP20_SHIFT (0) /* Bits 0-2: Channel 20 Sample time selection */ +# define ADC_SMPR1_SMP20_MASK (7 << ADC_SMPR1_SMP20_SHIFT) +# define ADC_SMPR1_SMP21_SHIFT (3) /* Bits 3-5: Channel 21 Sample time selection */ +# define ADC_SMPR1_SMP21_MASK (7 << ADC_SMPR1_SMP21_SHIFT) +# define ADC_SMPR1_SMP22_SHIFT (6) /* Bits 6-8: Channel 22 Sample time selection */ +# define ADC_SMPR1_SMP22_MASK (7 << ADC_SMPR1_SMP22_SHIFT) +# define ADC_SMPR1_SMP23_SHIFT (9) /* Bits 9-11: Channel 23 Sample time selection */ +# define ADC_SMPR1_SMP23_MASK (7 << ADC_SMPR1_SMP23_SHIFT) +# define ADC_SMPR1_SMP24_SHIFT (12) /* Bits 12-14: Channel 24 Sample time selection */ +# define ADC_SMPR1_SMP24_MASK (7 << ADC_SMPR1_SMP24_SHIFT) +# define ADC_SMPR1_SMP25_SHIFT (15) /* Bits 15-17: Channel 25 Sample time selection */ +# define ADC_SMPR1_SMP25_MASK (7 << ADC_SMPR1_SMP25_SHIFT) +# define ADC_SMPR1_SMP26_SHIFT (18) /* Bits 18-20: Channel 26 Sample time selection */ +# define ADC_SMPR1_SMP26_MASK (7 << ADC_SMPR1_SMP26_SHIFT) +# define ADC_SMPR1_SMP27_SHIFT (21) /* Bits 21-23: Channel 27 Sample time selection */ +# define ADC_SMPR1_SMP27_MASK (7 << ADC_SMPR1_SMP27_SHIFT) +# define ADC_SMPR1_SMP28_SHIFT (24) /* Bits 24-26: Channel 28 Sample time selection */ +# define ADC_SMPR1_SMP28_MASK (7 << ADC_SMPR1_SMP28_SHIFT) +# define ADC_SMPR1_SMP29_SHIFT (27) /* Bits 27-29: Channel 29 Sample time selection */ +# define ADC_SMPR1_SMP29_MASK (7 << ADC_SMPR1_SMP29_SHIFT) +#endif + +/* ADC sample time register 2 */ + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_SMPR2_SMP0_SHIFT (0) /* Bits 2-0: Channel 0 Sample time selection */ +# define ADC_SMPR2_SMP0_MASK (7 << ADC_SMPR2_SMP0_SHIFT) +# define ADC_SMPR2_SMP1_SHIFT (3) /* Bits 5-3: Channel 1 Sample time selection */ +# define ADC_SMPR2_SMP1_MASK (7 << ADC_SMPR2_SMP1_SHIFT) +# define ADC_SMPR2_SMP2_SHIFT (6) /* Bits 8-6: Channel 2 Sample time selection */ +# define ADC_SMPR2_SMP2_MASK (7 << ADC_SMPR2_SMP2_SHIFT) +# define ADC_SMPR2_SMP3_SHIFT (9) /* Bits 11-9: Channel 3 Sample time selection */ +# define ADC_SMPR2_SMP3_MASK (7 << ADC_SMPR2_SMP3_SHIFT) +# define ADC_SMPR2_SMP4_SHIFT (12) /* Bits 14-12: Channel 4 Sample time selection */ +# define ADC_SMPR2_SMP4_MASK (7 << ADC_SMPR2_SMP4_SHIFT) +# define ADC_SMPR2_SMP5_SHIFT (15) /* Bits 17-15: Channel 5 Sample time selection */ +# define ADC_SMPR2_SMP5_MASK (7 << ADC_SMPR2_SMP5_SHIFT) +# define ADC_SMPR2_SMP6_SHIFT (18) /* Bits 20-18: Channel 6 Sample time selection */ +# define ADC_SMPR2_SMP6_MASK (7 << ADC_SMPR2_SMP6_SHIFT) +# define ADC_SMPR2_SMP7_SHIFT (21) /* Bits 23-21: Channel 7 Sample time selection */ +# define ADC_SMPR2_SMP7_MASK (7 << ADC_SMPR2_SMP7_SHIFT) +# define ADC_SMPR2_SMP8_SHIFT (24) /* Bits 26-24: Channel 8 Sample time selection */ +# define ADC_SMPR2_SMP8_MASK (7 << ADC_SMPR2_SMP8_SHIFT) +# define ADC_SMPR2_SMP9_SHIFT (27) /* Bits 29-27: Channel 9 Sample time selection */ +# define ADC_SMPR2_SMP9_MASK (7 << ADC_SMPR2_SMP9_SHIFT) +#else +# define ADC_SMPR2_SMP10_SHIFT (0) /* Bits 0-2: Channel 10 Sample time selection */ +# define ADC_SMPR2_SMP10_MASK (7 << ADC_SMPR2_SMP10_SHIFT) +# define ADC_SMPR2_SMP11_SHIFT (3) /* Bits 3-5: Channel 11 Sample time selection */ +# define ADC_SMPR2_SMP11_MASK (7 << ADC_SMPR2_SMP11_SHIFT) +# define ADC_SMPR2_SMP12_SHIFT (6) /* Bits 6-8: Channel 12 Sample time selection */ +# define ADC_SMPR2_SMP12_MASK (7 << ADC_SMPR2_SMP12_SHIFT) +# define ADC_SMPR2_SMP13_SHIFT (9) /* Bits 9-11: Channel 13 Sample time selection */ +# define ADC_SMPR2_SMP13_MASK (7 << ADC_SMPR2_SMP13_SHIFT) +# define ADC_SMPR2_SMP14_SHIFT (12) /* Bits 12-14: Channel 14 Sample time selection */ +# define ADC_SMPR2_SMP14_MASK (7 << ADC_SMPR2_SMP14_SHIFT) +# define ADC_SMPR2_SMP15_SHIFT (15) /* Bits 15-17: Channel 15 Sample time selection */ +# define ADC_SMPR2_SMP15_MASK (7 << ADC_SMPR2_SMP15_SHIFT) +# define ADC_SMPR2_SMP16_SHIFT (18) /* Bits 18-20: Channel 16 Sample time selection */ +# define ADC_SMPR2_SMP16_MASK (7 << ADC_SMPR2_SMP16_SHIFT) +# define ADC_SMPR2_SMP17_SHIFT (21) /* Bits 21-23: Channel 17 Sample time selection */ +# define ADC_SMPR2_SMP17_MASK (7 << ADC_SMPR2_SMP17_SHIFT) +# define ADC_SMPR2_SMP18_SHIFT (24) /* Bits 24-26: Channel 18 Sample time selection */ +# define ADC_SMPR2_SMP18_MASK (7 << ADC_SMPR2_SMP18_SHIFT) +# define ADC_SMPR2_SMP19_SHIFT (27) /* Bits 27-29: Channel 18 Sample time selection */ +# define ADC_SMPR2_SMP19_MASK (7 << ADC_SMPR2_SMP19_SHIFT) +#endif + +/* ADC sample time register 3 */ + +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_SMPR3_SMP0_SHIFT (0) /* Bits 2-0: Channel 0 Sample time selection */ +# define ADC_SMPR3_SMP0_MASK (7 << ADC_SMPR3_SMP0_SHIFT) +# define ADC_SMPR3_SMP1_SHIFT (3) /* Bits 5-3: Channel 1 Sample time selection */ +# define ADC_SMPR3_SMP1_MASK (7 << ADC_SMPR3_SMP1_SHIFT) +# define ADC_SMPR3_SMP2_SHIFT (6) /* Bits 8-6: Channel 2 Sample time selection */ +# define ADC_SMPR3_SMP2_MASK (7 << ADC_SMPR3_SMP2_SHIFT) +# define ADC_SMPR3_SMP3_SHIFT (9) /* Bits 11-9: Channel 3 Sample time selection */ +# define ADC_SMPR3_SMP3_MASK (7 << ADC_SMPR3_SMP3_SHIFT) +# define ADC_SMPR3_SMP4_SHIFT (12) /* Bits 14-12: Channel 4 Sample time selection */ +# define ADC_SMPR3_SMP4_MASK (7 << ADC_SMPR3_SMP4_SHIFT) +# define ADC_SMPR3_SMP5_SHIFT (15) /* Bits 17-15: Channel 5 Sample time selection */ +# define ADC_SMPR3_SMP5_MASK (7 << ADC_SMPR3_SMP5_SHIFT) +# define ADC_SMPR3_SMP6_SHIFT (18) /* Bits 20-18: Channel 6 Sample time selection */ +# define ADC_SMPR3_SMP6_MASK (7 << ADC_SMPR3_SMP6_SHIFT) +# define ADC_SMPR3_SMP7_SHIFT (21) /* Bits 23-21: Channel 7 Sample time selection */ +# define ADC_SMPR3_SMP7_MASK (7 << ADC_SMPR3_SMP7_SHIFT) +# define ADC_SMPR3_SMP8_SHIFT (24) /* Bits 26-24: Channel 8 Sample time selection */ +# define ADC_SMPR3_SMP8_MASK (7 << ADC_SMPR3_SMP8_SHIFT) +# define ADC_SMPR3_SMP9_SHIFT (27) /* Bits 29-27: Channel 9 Sample time selection */ +# define ADC_SMPR3_SMP9_MASK (7 << ADC_SMPR3_SMP9_SHIFT) +#endif + +/* ADC sample time register 0 */ + +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_SMPR3_SMP30_SHIFT (0) /* Bits 2-0: Channel 30 Sample time selection */ +# define ADC_SMPR3_SMP30_MASK (7 << ADC_SMPR3_SMP30_SHIFT) +# define ADC_SMPR3_SMP31_SHIFT (3) /* Bits 5-3: Channel 31 Sample time selection */ +# define ADC_SMPR3_SMP31_MASK (7 << ADC_SMPR3_SMP31_SHIFT) +#endif +/* ADC injected channel data offset register 1-4 */ + +#define ADC_JOFR_SHIFT (0) /* Bits 11-0: Data offset for injected channel x */ +#define ADC_JOFR_MASK (0x0fff << ADC_JOFR_SHIFT) + +/* ADC watchdog high threshold register */ + +#define ADC_HTR_SHIFT (0) /* Bits 11-0: Analog watchdog high threshold */ +#define ADC_HTR_MASK (0x0fff << ADC_HTR_SHIFT) + +/* ADC watchdog low threshold register */ + +#define ADC_LTR_SHIFT (0) /* Bits 11-0: Analog watchdog low threshold */ +#define ADC_LTR_MASK (0x0fff << ADC_LTR_SHIFT) + +/* ADC regular sequence register 1 */ + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_SQR1_SQ13_SHIFT (0) /* Bits 4-0: 13th conversion in regular sequence */ +# define ADC_SQR1_SQ13_MASK (0x1f << ADC_SQR1_SQ13_SHIFT) +# define ADC_SQR1_SQ14_SHIFT (5) /* Bits 9-5: 14th conversion in regular sequence */ +# define ADC_SQR1_SQ14_MASK (0x1f << ADC_SQR1_SQ14_SHIFT) +# define ADC_SQR1_SQ15_SHIFT (10) /* Bits 14-10: 15th conversion in regular sequence */ +# define ADC_SQR1_SQ15_MASK (0x1f << ADC_SQR1_SQ15_SHIFT) +# define ADC_SQR1_SQ16_SHIFT (15) /* Bits 19-15: 16th conversion in regular sequence */ +# define ADC_SQR1_SQ16_MASK (0x1f << ADC_SQR1_SQ16_SHIFT) +# define ADC_SQR1_L_SHIFT (20) /* Bits 23-20: Regular channel sequence length */ +# define ADC_SQR1_L_MASK (0x0f << ADC_SQR1_L_SHIFT) +# define ADC_SQR1_RESERVED (0xff000000) +# define ADC_SQR1_FIRST (13) +# define ADC_SQR1_LAST (16) +# define ADC_SQR1_SQ_OFFSET (0) +#else +# define ADC_SQR1_SQ25_SHIFT (0) /* Bits 4-0: 25th conversion in regular sequence */ +# define ADC_SQR1_SQ25_MASK (0x1f << ADC_SQR1_SQ25_SHIFT) +# define ADC_SQR1_SQ26_SHIFT (5) /* Bits 9-5: 26th conversion in regular sequence */ +# define ADC_SQR1_SQ26_MASK (0x1f << ADC_SQR1_SQ26_SHIFT) +# define ADC_SQR1_SQ27_SHIFT (10) /* Bits 14-10: 27th conversion in regular sequence */ +# define ADC_SQR1_SQ27_MASK (0x1f << ADC_SQR1_SQ27_SHIFT) +# define ADC_SQR1_SQ28_SHIFT (15) /* Bits 19-15: 28th conversion in regular sequence */ +# define ADC_SQR1_SQ28_MASK (0x1f << ADC_SQR1_SQ28_SHIFT) +# define ADC_SQR1_L_SHIFT (20) /* Bits 24-20: Regular channel sequence length */ +# define ADC_SQR1_L_MASK (0x1f << ADC_SQR1_L_SHIFT) +# define ADC_SQR1_RESERVED (0xff000000) +# define ADC_SQR1_FIRST (25) +# define ADC_SQR1_LAST (28) +# define ADC_SQR1_SQ_OFFSET (0) +#endif + +/* ADC regular sequence register 2 */ + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_SQR2_SQ7_SHIFT (0) /* Bits 4-0: 7th conversion in regular sequence */ +# define ADC_SQR2_SQ7_MASK (0x1f << ADC_SQR2_SQ7_SHIFT) +# define ADC_SQR2_SQ8_SHIFT (5) /* Bits 9-5: 8th conversion in regular sequence */ +# define ADC_SQR2_SQ8_MASK (0x1f << ADC_SQR2_SQ8_SHIFT) +# define ADC_SQR2_SQ9_SHIFT (10) /* Bits 14-10: 9th conversion in regular sequence */ +# define ADC_SQR2_SQ9_MASK (0x1f << ADC_SQR2_SQ9_SHIFT) +# define ADC_SQR2_SQ10_SHIFT (15) /* Bits 19-15: 10th conversion in regular sequence */ +# define ADC_SQR2_SQ10_MASK (0x1f << ADC_SQR2_SQ10_SHIFT) +# define ADC_SQR2_SQ11_SHIFT (20) /* Bits 24-20: 11th conversion in regular sequence */ +# define ADC_SQR2_SQ11_MASK (0x1f << ADC_SQR2_SQ11_SHIFT ) +# define ADC_SQR2_SQ12_SHIFT (25) /* Bits 29-25: 12th conversion in regular sequence */ +# define ADC_SQR2_SQ12_MASK (0x1f << ADC_SQR2_SQ12_SHIFT) +# define ADC_SQR2_RESERVED (0xc0000000) +# define ADC_SQR2_FIRST (7) +# define ADC_SQR2_LAST (12) +# define ADC_SQR2_SQ_OFFSET (0) +#else +# define ADC_SQR2_SQ19_SHIFT (0) /* Bits 4-0: 19th conversion in regular sequence */ +# define ADC_SQR2_SQ19_MASK (0x1f << ADC_SQR2_SQ19_SHIFT) +# define ADC_SQR2_SQ20_SHIFT (5) /* Bits 9-5: 20th conversion in regular sequence */ +# define ADC_SQR2_SQ20_MASK (0x1f << ADC_SQR2_SQ20_SHIFT) +# define ADC_SQR2_SQ21_SHIFT (10) /* Bits 14-10: 21th conversion in regular sequence */ +# define ADC_SQR2_SQ21_MASK (0x1f << ADC_SQR2_SQ21_SHIFT) +# define ADC_SQR2_SQ22_SHIFT (15) /* Bits 19-15: 22th conversion in regular sequence */ +# define ADC_SQR2_SQ22_MASK (0x1f << ADC_SQR2_SQ22_SHIFT) +# define ADC_SQR2_SQ23_SHIFT (20) /* Bits 24-20: 23th conversion in regular sequence */ +# define ADC_SQR2_SQ23_MASK (0x1f << ADC_SQR2_SQ23_SHIFT ) +# define ADC_SQR2_SQ24_SHIFT (25) /* Bits 29-25: 24th conversion in regular sequence */ +# define ADC_SQR2_SQ24_MASK (0x1f << ADC_SQR2_SQ24_SHIFT) +# define ADC_SQR2_RESERVED (0xc0000000) +# define ADC_SQR2_FIRST (19) +# define ADC_SQR2_LAST (24) +# define ADC_SQR2_SQ_OFFSET (0) +#endif + +/* ADC regular sequence register 3 */ + +#ifndef CONFIG_STM32_STM32L15XX +# define ADC_SQR3_SQ1_SHIFT (0) /* Bits 4-0: 1st conversion in regular sequence */ +# define ADC_SQR3_SQ1_MASK (0x1f << ADC_SQR3_SQ1_SHIFT) +# define ADC_SQR3_SQ2_SHIFT (5) /* Bits 9-5: 2nd conversion in regular sequence */ +# define ADC_SQR3_SQ2_MASK (0x1f << ADC_SQR3_SQ2_SHIFT) +# define ADC_SQR3_SQ3_SHIFT (10) /* Bits 14-10: 3rd conversion in regular sequence */ +# define ADC_SQR3_SQ3_MASK (0x1f << ADC_SQR3_SQ3_SHIFT) +# define ADC_SQR3_SQ4_SHIFT (15) /* Bits 19-15: 4th conversion in regular sequence */ +# define ADC_SQR3_SQ4_MASK (0x1f << ADC_SQR3_SQ4_SHIFT) +# define ADC_SQR3_SQ5_SHIFT (20) /* Bits 24-20: 5th conversion in regular sequence */ +# define ADC_SQR3_SQ5_MASK (0x1f << ADC_SQR3_SQ5_SHIFT ) +# define ADC_SQR3_SQ6_SHIFT (25) /* Bits 29-25: 6th conversion in regular sequence */ +# define ADC_SQR3_SQ6_MASK (0x1f << ADC_SQR3_SQ6_SHIFT) +# define ADC_SQR3_RESERVED (0xc0000000) +# define ADC_SQR3_FIRST (1) +# define ADC_SQR3_LAST (6) +# define ADC_SQR3_SQ_OFFSET (0) +#else +# define ADC_SQR3_SQ13_SHIFT (0) /* Bits 4-0: 13th conversion in regular sequence */ +# define ADC_SQR3_SQ13_MASK (0x1f << ADC_SQR3_SQ13_SHIFT) +# define ADC_SQR3_SQ14_SHIFT (5) /* Bits 9-5: 14th conversion in regular sequence */ +# define ADC_SQR3_SQ14_MASK (0x1f << ADC_SQR3_SQ14_SHIFT) +# define ADC_SQR3_SQ15_SHIFT (10) /* Bits 14-10: 15th conversion in regular sequence */ +# define ADC_SQR3_SQ15_MASK (0x1f << ADC_SQR3_SQ15_SHIFT) +# define ADC_SQR3_SQ16_SHIFT (15) /* Bits 19-15: 16th conversion in regular sequence */ +# define ADC_SQR3_SQ16_MASK (0x1f << ADC_SQR3_SQ16_SHIFT) +# define ADC_SQR3_SQ17_SHIFT (20) /* Bits 24-20: 17th conversion in regular sequence */ +# define ADC_SQR3_SQ17_MASK (0x1f << ADC_SQR3_SQ17_SHIFT ) +# define ADC_SQR3_SQ18_SHIFT (25) /* Bits 29-25: 18th conversion in regular sequence */ +# define ADC_SQR3_SQ18_MASK (0x1f << ADC_SQR3_SQ18_SHIFT) +# define ADC_SQR3_RESERVED (0xc0000000) +# define ADC_SQR3_FIRST (13) +# define ADC_SQR3_LAST (18) +# define ADC_SQR3_SQ_OFFSET (0) +#endif + +/* ADC regular sequence register 4 */ + +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_SQR4_SQ7_SHIFT (0) /* Bits 4-0: 7th conversion in regular sequence */ +# define ADC_SQR4_SQ7_MASK (0x1f << ADC_SQR4_SQ7_SHIFT) +# define ADC_SQR4_SQ8_SHIFT (5) /* Bits 9-5: 8th conversion in regular sequence */ +# define ADC_SQR4_SQ8_MASK (0x1f << ADC_SQR4_SQ8_SHIFT) +# define ADC_SQR4_SQ9_SHIFT (10) /* Bits 14-10: 9th conversion in regular sequence */ +# define ADC_SQR4_SQ9_MASK (0x1f << ADC_SQR4_SQ9_SHIFT) +# define ADC_SQR4_SQ10_SHIFT (15) /* Bits 19-15: 10th conversion in regular sequence */ +# define ADC_SQR4_SQ10_MASK (0x1f << ADC_SQR4_SQ10_SHIFT) +# define ADC_SQR4_SQ11_SHIFT (20) /* Bits 24-20: 11th conversion in regular sequence */ +# define ADC_SQR4_SQ11_MASK (0x1f << ADC_SQR4_SQ11_SHIFT ) +# define ADC_SQR4_SQ12_SHIFT (25) /* Bits 29-25: 12th conversion in regular sequence */ +# define ADC_SQR4_SQ12_MASK (0x1f << ADC_SQR4_SQ12_SHIFT) +# define ADC_SQR4_RESERVED (0xc0000000) +# define ADC_SQR4_FIRST (7) +# define ADC_SQR4_LAST (12) +# define ADC_SQR4_SQ_OFFSET (0) +#endif + +/* ADC regular sequence register 5 */ + +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_SQR5_SQ1_SHIFT (0) /* Bits 4-0: 1st conversion in regular sequence */ +# define ADC_SQR5_SQ1_MASK (0x1f << ADC_SQR5_SQ1_SHIFT) +# define ADC_SQR5_SQ2_SHIFT (5) /* Bits 9-5: 2nd conversion in regular sequence */ +# define ADC_SQR5_SQ2_MASK (0x1f << ADC_SQR5_SQ2_SHIFT) +# define ADC_SQR5_SQ3_SHIFT (10) /* Bits 14-10: 3rd conversion in regular sequence */ +# define ADC_SQR5_SQ3_MASK (0x1f << ADC_SQR5_SQ3_SHIFT) +# define ADC_SQR5_SQ4_SHIFT (15) /* Bits 19-15: 4th conversion in regular sequence */ +# define ADC_SQR5_SQ4_MASK (0x1f << ADC_SQR5_SQ4_SHIFT) +# define ADC_SQR5_SQ5_SHIFT (20) /* Bits 24-20: 5th conversion in regular sequence */ +# define ADC_SQR5_SQ5_MASK (0x1f << ADC_SQR5_SQ5_SHIFT ) +# define ADC_SQR5_SQ6_SHIFT (25) /* Bits 29-25: 6th conversion in regular sequence */ +# define ADC_SQR5_SQ6_MASK (0x1f << ADC_SQR5_SQ6_SHIFT) +# define ADC_SQR5_RESERVED (0xc0000000) +# define ADC_SQR5_FIRST (1) +# define ADC_SQR5_LAST (6) +# define ADC_SQR5_SQ_OFFSET (0) +#endif + +/* Offset between SQ bits */ + +#define ADC_SQ_OFFSET (5) + +/* ADC injected sequence register */ + +#define ADC_JSQR_JSQ1_SHIFT (0) /* Bits 4-0: 1st conversion in injected sequence */ +#define ADC_JSQR_JSQ1_MASK (0x1f << ADC_JSQR_JSQ1_SHIFT) +#define ADC_JSQR_JSQ2_SHIFT (5) /* Bits 9-5: 2nd conversion in injected sequence */ +#define ADC_JSQR_JSQ2_MASK (0x1f << ADC_JSQR_JSQ2_SHIFT) +#define ADC_JSQR_JSQ3_SHIFT (10) /* Bits 14-10: 3rd conversion in injected sequence */ +#define ADC_JSQR_JSQ3_MASK (0x1f << ADC_JSQR_JSQ3_SHIFT) +#define ADC_JSQR_JSQ4_SHIFT (15) /* Bits 19-15: 4th conversion in injected sequence */ +#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT) +#define ADC_JSQR_JL_SHIFT (20) /* Bits 21-20: Injected Sequence length */ +#define ADC_JSQR_JL_MASK (3 << ADC_JSQR_JL_SHIFT) + +/* ADC injected data register 1-4 */ + +#define ADC_JDR_JDATA_SHIFT (0) /* Bits 15-0: Injected data */ +#define ADC_JDR_JDATA_MASK (0xffff << ADC_JDR_JDATA_SHIFT) + +/* ADC regular data register */ + +#define ADC_DR_RDATA_SHIFT (0) /* Bits 15-0 Regular data */ +#define ADC_DR_RDATA_MASK (0xffff << ADC_DR_RDATA_SHIFT) + +#ifdef CONFIG_STM32_STM32F10XX +# define ADC_DR_ADC2DATA_SHIFT (16) /* Bits 31-16: ADC2 data */ +# define ADC_DR_ADC2DATA_MASK (0xffff << ADC_DR_ADC2DATA_SHIFT) +#endif + +/* Common status register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# +# define ADC_CSR_AWD1 (1 << 0) /* Bit 0: Analog watchdog flag of ADC1 (copy of AWD in ADC1_SR) */ +# define ADC_CSR_EOC1 (1 << 1) /* Bit 1: End of conversion of ADC1 (copy of EOC in ADC1_SR) */ +# define ADC_CSR_JEOC1 (1 << 2) /* Bit 2: Injected channel end of conversion of ADC1 (copy of JEOC in ADC1_SR) */ +# define ADC_CSR_JSTRT1 (1 << 3) /* Bit 3: Injected channel Start flag of ADC1 (copy of JSTRT in ADC1_SR) */ +# define ADC_CSR_STRT1 (1 << 4) /* Bit 4: Regular channel Start flag of ADC1 (copy of STRT in ADC1_SR) */ +# define ADC_CSR_OVR1 (1 << 5) /* Bit 5: Overrun flag of ADC1 (copy of OVR in ADC1_SR) */ +# /* Bits 6-7: Reserved, must be kept at reset value. */ +#ifdef CONFIG_STM32_STM32L15XX +# define ADC_CSR_ADONS1 (1 << 6) /* Bit 6: ADON Status of ADC1. This bit is a copy of the ADONS bit in the ADC_SR register. */ +#endif +# +# ifndef CONFIG_STM32_STM32L15XX +# define ADC_CSR_AWD2 (1 << 8) /* Bit 8: Analog watchdog flag of ADC2 (copy of AWD in ADC2_SR) */ +# define ADC_CSR_EOC2 (1 << 9) /* Bit 9: End of conversion of ADC2 (copy of EOC in ADC2_SR) */ +# define ADC_CSR_JEOC2 (1 << 10) /* Bit 10: Injected channel end of conversion of ADC2 (copy of JEOC in ADC2_SR) */ +# define ADC_CSR_JSTRT2 (1 << 11) /* Bit 11: Injected channel Start flag of ADC2 (copy of JSTRT in ADC2_SR) */ +# define ADC_CSR_STRT2 (1 << 12) /* Bit 12: Regular channel Start flag of ADC2 (copy of STRT in ADC2_SR) */ +# define ADC_CSR_OVR2 (1 << 13) /* Bit 13: Overrun flag of ADC2 (copy of OVR in ADC2_SR) */ +# /* Bits 14-15: Reserved, must be kept at reset value. */ +# define ADC_CSR_AWD3 (1 << 16) /* Bit 16: ADC3 Analog watchdog flag (copy of AWD in ADC3_SR) */ +# define ADC_CSR_EOC3 (1 << 17) /* Bit 17: ADC3 End of conversion (copy of EOC in ADC3_SR) */ +# define ADC_CSR_JEOC3 (1 << 18) /* Bit 18: ADC3 Injected channel end of conversion (copy of JEOC in ADC3_SR) */ +# define ADC_CSR_JSTRT3 (1 << 19) /* Bit 19: ADC3 Injected channel Start flag (copy of JSTRT in ADC3_SR) */ +# define ADC_CSR_STRT3 (1 << 20) /* Bit 20: ADC3 Regular channel Start flag (copy of STRT in ADC3_SR). */ +# define ADC_CSR_OVR3 (1 << 21) /* Bit 21: ADC3 overrun flag (copy of OVR in ADC3_SR). */ +# /* Bits 22-31: Reserved, must be kept at reset value. */ +# endif +# +#endif + +/* Common control register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ADC_CCR_MULTI_SHIFT (0) /* Bits 0-4: Multi ADC mode selection */ +# define ADC_CCR_MULTI_MASK (31 << ADC_CCR_MULTI_SHIFT) +# define ADC_CCR_MULTI_NONE (0 << ADC_CCR_MULTI_SHIFT) /* 00000: Independent mode */ + /* 00001 to 01001: Dual mode (ADC1 and ADC2), ADC3 independent */ +# define ADC_CCR_MULTI_RSISM2 (1 << ADC_CCR_MULTI_SHIFT) /* 00001: Combined regular simultaneous + injected simultaneous mode */ +# define ADC_CCR_MULTI_RSATM2 (2 << ADC_CCR_MULTI_SHIFT) /* 00010: Combined regular simultaneous + alternate trigger mode */ +# define ADC_CCR_MULTI_ISM2 (5 << ADC_CCR_MULTI_SHIFT) /* 00101: Injected simultaneous mode only */ +# define ADC_CCR_MULTI_RSM2 (6 << ADC_CCR_MULTI_SHIFT) /* 00110: Regular simultaneous mode only */ +# define ADC_CCR_MULTI_IM2 (7 << ADC_CCR_MULTI_SHIFT) /* 00111: interleaved mode only */ +# define ADC_CCR_MULTI_ATM2 (9 << ADC_CCR_MULTI_SHIFT) /* 01001: Alternate trigger mode only */ + /* 10001 to 11001: Triple mode (ADC1, 2 and 3) */ +# define ADC_CCR_MULTI_RSISM3 (17 << ADC_CCR_MULTI_SHIFT) /* 10001: Combined regular simultaneous + injected simultaneous mode */ +# define ADC_CCR_MULTI_RSATM3 (18 << ADC_CCR_MULTI_SHIFT) /* 10010: Combined regular simultaneous + alternate trigger mode */ +# define ADC_CCR_MULTI_ISM3 (21 << ADC_CCR_MULTI_SHIFT) /* 10101: Injected simultaneous mode only */ +# define ADC_CCR_MULTI_RSM3 (22 << ADC_CCR_MULTI_SHIFT) /* 10110: Regular simultaneous mode only */ +# define ADC_CCR_MULTI_IM3 (23 << ADC_CCR_MULTI_SHIFT) /* 10111: interleaved mode only */ +# define ADC_CCR_MULTI_ATM3 (25 << ADC_CCR_MULTI_SHIFT) /* 11001: Alternate trigger mode only */ + /* Bits 5-7: Reserved, must be kept at reset value. */ +# define ADC_CCR_DELAY_SHIFT (8) /* Bits 8-11: Delay between 2 sampling phases */ +# define ADC_CCR_DELAY_MASK (15 << ADC_CCR_DELAY_SHIFT) +# define ADC_CCR_DELAY(n) (((n)-5) << ADC_CCR_DELAY_SHIFT) /* n * TADCCLK, n=5-20 */ + /* Bit 12 Reserved, must be kept at reset value. */ +# define ADC_CCR_DDS (1 << 13) /* Bit 13: DMA disable selection (for multi-ADC mode) */ + +# define ADC_CCR_DMA_SHIFT (14) /* Bits 14-15: Direct memory access mode for multi ADC mode */ +# define ADC_CCR_DMA_MASK (3 << ADC_CCR_DMA_SHIFT) +# define ADC_CCR_DMA_DISABLED (0 << ADC_CCR_DMA_SHIFT) /* 00: DMA mode disabled */ +# define ADC_CCR_DMA_MODE1 (1 << ADC_CCR_DMA_SHIFT) /* 01: DMA mode 1 enabled */ +# define ADC_CCR_DMA_MODE2 (2 << ADC_CCR_DMA_SHIFT) /* 10: DMA mode 2 enabled */ +# define ADC_CCR_DMA_MODE3 (3 << ADC_CCR_DMA_SHIFT) /* 11: DMA mode 3 enabled */ + +# define ADC_CCR_ADCPRE_SHIFT (16) /* Bits 16-17: ADC prescaler */ +# define ADC_CCR_ADCPRE_MASK (3 << ADC_CCR_ADCPRE_SHIFT) +# define ADC_CCR_ADCPRE_DIV2 (0 << ADC_CCR_ADCPRE_SHIFT) /* 00: PCLK2 divided by 2 */ +# define ADC_CCR_ADCPRE_DIV4 (1 << ADC_CCR_ADCPRE_SHIFT) /* 01: PCLK2 divided by 4 */ +# define ADC_CCR_ADCPRE_DIV6 (2 << ADC_CCR_ADCPRE_SHIFT) /* 10: PCLK2 divided by 6 */ +# define ADC_CCR_ADCPRE_DIV8 (3 << ADC_CCR_ADCPRE_SHIFT) /* 11: PCLK2 divided by 8 */ + /* Bits 18-21: Reserved, must be kept at reset value. */ +# define ADC_CCR_VBATE (1 << 22) /* Bit 22: VBAT enable */ +# define ADC_CCR_TSVREFE (1 << 23) /* Bit 23: Temperature sensor and VREFINT enable */ + /* Bits 24-31 Reserved, must be kept at reset value. */ +#elif defined(CONFIG_STM32_STM32L15XX) + /* Bits 15-0: Reserved, must be kept at reset value */ +# define ADC_CCR_ADCPRE_SHIFT (16) /* Bits 16-17: ADC prescaler */ +# define ADC_CCR_ADCPRE_MASK (3 << ADC_CCR_ADCPRE_SHIFT) +# define ADC_CCR_ADCPRE_DIV1 (0 << ADC_CCR_ADCPRE_SHIFT) /* HSI divided by 1 */ +# define ADC_CCR_ADCPRE_DIV2 (1 << ADC_CCR_ADCPRE_SHIFT) /* HSI divided by 2 */ +# define ADC_CCR_ADCPRE_DIV4 (2 << ADC_CCR_ADCPRE_SHIFT) /* HSI divided by 4 */ + /* 11: Reserved */ + /* Bits 22-18: Reserved, must be kept at reset value */ +# define ADC_CCR_TSVREFE (1 << 23) /* Bit 23: Temperature sensor and VREFINT enable */ + /* Bits 31-24: Reserved, must be kept at reset value */ +#endif + +/* Data register for dual and triple modes (32-bit data with no named fields) */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_ADC_H */ diff --git a/arch/arm/src/stm32/chip/stm32_bkp.h b/arch/arm/src/stm32/chip/stm32_bkp.h new file mode 100644 index 0000000000000000000000000000000000000000..5bda839a88d56f2d360fe302806d03b6b98af12a --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_bkp.h @@ -0,0 +1,190 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_bkp.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_BKP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_BKP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_STM32_HIGHDENSITY) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define CONFIG_STM32_NBKP_BYTES 84 +# define CONFIG_STM32_NBKP_REGS 42 +#else +# define CONFIG_STM32_NBKP_BYTES 20 +# define CONFIG_STM32_NBKP_REGS 10 +#endif + +/* Register Offsets *****************************************************************/ + +#if defined(CONFIG_STM32_HIGHDENSITY) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_BKP_DR_OFFSET(n) ((n) > 10 ? 0x0040+4*((n)-10) : 0x0004+4*(n)) +#else +# define STM32_BKP_DR_OFFSET(n) (0x0004+4*(n)) +#endif + +#define STM32_BKP_DR1_OFFSET 0x0004 /* Backup data register 1 */ +#define STM32_BKP_DR2_OFFSET 0x0008 /* Backup data register 2 */ +#define STM32_BKP_DR3_OFFSET 0x000c /* Backup data register 3 */ +#define STM32_BKP_DR4_OFFSET 0x0010 /* Backup data register 4 */ +#define STM32_BKP_DR5_OFFSET 0x0014 /* Backup data register 5 */ +#define STM32_BKP_DR6_OFFSET 0x0018 /* Backup data register 6 */ +#define STM32_BKP_DR7_OFFSET 0x001c /* Backup data register 7 */ +#define STM32_BKP_DR8_OFFSET 0x0020 /* Backup data register 8 */ +#define STM32_BKP_DR9_OFFSET 0x0024 /* Backup data register 9 */ +#define STM32_BKP_DR10_OFFSET 0x0028 /* Backup data register 10 */ + +#define STM32_BKP_RTCCR_OFFSET 0x002c /* RTC clock calibration register */ +#define STM32_BKP_CR_OFFSET 0x0030 /* Backup control register */ +#define STM32_BKP_CSR_OFFSET 0x0034 /* Backup control/status register */ + +#if defined(CONFIG_STM32_HIGHDENSITY) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_BKP_DR11_OFFSET 0x0040 /* Backup data register 11 */ +# define STM32_BKP_DR12_OFFSET 0x0044 /* Backup data register 12 */ +# define STM32_BKP_DR13_OFFSET 0x0048 /* Backup data register 13 */ +# define STM32_BKP_DR14_OFFSET 0x004c /* Backup data register 14 */ +# define STM32_BKP_DR15_OFFSET 0x0050 /* Backup data register 15 */ +# define STM32_BKP_DR16_OFFSET 0x0054 /* Backup data register 16 */ +# define STM32_BKP_DR17_OFFSET 0x0058 /* Backup data register 17 */ +# define STM32_BKP_DR18_OFFSET 0x005c /* Backup data register 18 */ +# define STM32_BKP_DR19_OFFSET 0x0060 /* Backup data register 19 */ +# define STM32_BKP_DR20_OFFSET 0x0064 /* Backup data register 20 */ +# define STM32_BKP_DR21_OFFSET 0x0068 /* Backup data register 21 */ +# define STM32_BKP_DR22_OFFSET 0x006c /* Backup data register 22 */ +# define STM32_BKP_DR23_OFFSET 0x0070 /* Backup data register 23 */ +# define STM32_BKP_DR24_OFFSET 0x0074 /* Backup data register 24 */ +# define STM32_BKP_DR25_OFFSET 0x0078 /* Backup data register 25 */ +# define STM32_BKP_DR26_OFFSET 0x007c /* Backup data register 26 */ +# define STM32_BKP_DR27_OFFSET 0x0080 /* Backup data register 27 */ +# define STM32_BKP_DR28_OFFSET 0x0084 /* Backup data register 28 */ +# define STM32_BKP_DR29_OFFSET 0x0088 /* Backup data register 29 */ +# define STM32_BKP_DR30_OFFSET 0x008c /* Backup data register 30 */ +# define STM32_BKP_DR31_OFFSET 0x0090 /* Backup data register 31 */ +# define STM32_BKP_DR32_OFFSET 0x0094 /* Backup data register 32 */ +# define STM32_BKP_DR33_OFFSET 0x0098 /* Backup data register 33 */ +# define STM32_BKP_DR34_OFFSET 0x009c /* Backup data register 34 */ +# define STM32_BKP_DR35_OFFSET 0x00a0 /* Backup data register 35 */ +# define STM32_BKP_DR36_OFFSET 0x00a4 /* Backup data register 36 */ +# define STM32_BKP_DR37_OFFSET 0x00a8 /* Backup data register 37 */ +# define STM32_BKP_DR38_OFFSET 0x00ac /* Backup data register 38 */ +# define STM32_BKP_DR39_OFFSET 0x00b0 /* Backup data register 39 */ +# define STM32_BKP_DR40_OFFSET 0x00b4 /* Backup data register 40 */ +# define STM32_BKP_DR41_OFFSET 0x00b8 /* Backup data register 41 */ +# define STM32_BKP_DR42_OFFSET 0x00bc /* Backup data register 42 */ +#endif + +/* Register Addresses ***************************************************************/ + +#define STM32_BKP_RTCCR (STM32_BKP_BASE+STM32_BKP_RTCCR_OFFSET) +#define STM32_BKP_CR (STM32_BKP_BASE+STM32_BKP_CR_OFFSET) +#define STM32_BKP_CSR (STM32_BKP_BASE+STM32_BKP_CSR_OFFSET) + +#define STM32_BKP_DR(n) (STM32_BKP_BASE+STM32_BKP_DR_OFFSET(n)) +#define STM32_BKP_DR1 (STM32_BKP_BASE+STM32_BKP_DR1_OFFSET) +#define STM32_BKP_DR2 (STM32_BKP_BASE+STM32_BKP_DR2_OFFSET) +#define STM32_BKP_DR3 (STM32_BKP_BASE+STM32_BKP_DR3_OFFSET) +#define STM32_BKP_DR4 (STM32_BKP_BASE+STM32_BKP_DR4_OFFSET) +#define STM32_BKP_DR5 (STM32_BKP_BASE+STM32_BKP_DR5_OFFSET) +#define STM32_BKP_DR6 (STM32_BKP_BASE+STM32_BKP_DR6_OFFSET) +#define STM32_BKP_DR7 (STM32_BKP_BASE+STM32_BKP_DR7_OFFSET) +#define STM32_BKP_DR8 (STM32_BKP_BASE+STM32_BKP_DR8_OFFSET) +#define STM32_BKP_DR9 (STM32_BKP_BASE+STM32_BKP_DR9_OFFSET) +#define STM32_BKP_DR10 (STM32_BKP_BASE+STM32_BKP_DR10_OFFSET) + +#if defined(CONFIG_STM32_HIGHDENSITY) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_BKP_DR11 (STM32_BKP_BASE+STM32_BKP_DR11_OFFSET) +# define STM32_BKP_DR12 (STM32_BKP_BASE+STM32_BKP_DR12_OFFSET) +# define STM32_BKP_DR13 (STM32_BKP_BASE+STM32_BKP_DR13_OFFSET) +# define STM32_BKP_DR14 (STM32_BKP_BASE+STM32_BKP_DR14_OFFSET) +# define STM32_BKP_DR15 (STM32_BKP_BASE+STM32_BKP_DR15_OFFSET) +# define STM32_BKP_DR16 (STM32_BKP_BASE+STM32_BKP_DR16_OFFSET) +# define STM32_BKP_DR17 (STM32_BKP_BASE+STM32_BKP_DR17_OFFSET) +# define STM32_BKP_DR18 (STM32_BKP_BASE+STM32_BKP_DR18_OFFSET) +# define STM32_BKP_DR19 (STM32_BKP_BASE+STM32_BKP_DR19_OFFSET) +# define STM32_BKP_DR20 (STM32_BKP_BASE+STM32_BKP_DR20_OFFSET) +# define STM32_BKP_DR21 (STM32_BKP_BASE+STM32_BKP_DR21_OFFSET) +# define STM32_BKP_DR22 (STM32_BKP_BASE+STM32_BKP_DR22_OFFSET) +# define STM32_BKP_DR23 (STM32_BKP_BASE+STM32_BKP_DR23_OFFSET) +# define STM32_BKP_DR24 (STM32_BKP_BASE+STM32_BKP_DR24_OFFSET) +# define STM32_BKP_DR25 (STM32_BKP_BASE+STM32_BKP_DR25_OFFSET) +# define STM32_BKP_DR26 (STM32_BKP_BASE+STM32_BKP_DR26_OFFSET) +# define STM32_BKP_DR27 (STM32_BKP_BASE+STM32_BKP_DR27_OFFSET) +# define STM32_BKP_DR28 (STM32_BKP_BASE+STM32_BKP_DR28_OFFSET) +# define STM32_BKP_DR29 (STM32_BKP_BASE+STM32_BKP_DR29_OFFSET) +# define STM32_BKP_DR30 (STM32_BKP_BASE+STM32_BKP_DR30_OFFSET) +# define STM32_BKP_DR31 (STM32_BKP_BASE+STM32_BKP_DR31_OFFSET) +# define STM32_BKP_DR32 (STM32_BKP_BASE+STM32_BKP_DR32_OFFSET) +# define STM32_BKP_DR33 (STM32_BKP_BASE+STM32_BKP_DR33_OFFSET) +# define STM32_BKP_DR34 (STM32_BKP_BASE+STM32_BKP_DR34_OFFSET) +# define STM32_BKP_DR35 (STM32_BKP_BASE+STM32_BKP_DR35_OFFSET) +# define STM32_BKP_DR36 (STM32_BKP_BASE+STM32_BKP_DR36_OFFSET) +# define STM32_BKP_DR37 (STM32_BKP_BASE+STM32_BKP_DR37_OFFSET) +# define STM32_BKP_DR38 (STM32_BKP_BASE+STM32_BKP_DR38_OFFSET) +# define STM32_BKP_DR39 (STM32_BKP_BASE+STM32_BKP_DR39_OFFSET) +# define STM32_BKP_DR40 (STM32_BKP_BASE+STM32_BKP_DR40_OFFSET) +# define STM32_BKP_DR41 (STM32_BKP_BASE+STM32_BKP_DR41_OFFSET) +# define STM32_BKP_DR42 (STM32_BKP_BASE+STM32_BKP_DR42_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* RTC clock calibration register */ + +#define BKP_RTCCR_CAL_SHIFT (0) /* Bits 6-0: Calibration value */ +#define BKP_RTCCR_CAL_MASK (0x7f << BKP_RTCCR_CAL_SHIFT) +#define BKP_RTCCR_CCO (1 << 7) /* Bit 7: Calibration Clock Output */ +#define BKP_RTCCR_ASOE (1 << 8) /* Bit 8: Alarm or Second Output Enable */ +#define BKP_RTCCR_ASOS (1 << 9) /* Bit 9: Alarm or Second Output Selection */ + +/* Backup control register */ + +#define BKP_CR_TPE (1 << 0) /* Bit 0: TAMPER pin enable */ +#define BKP_CR_TPAL (1 << 1) /* Bit 1: TAMPER pin active level */ + +/* Backup control/status register */ + +#define BKP_CSR_CTE (1 << 0) /* Bit 0: Clear Tamper event */ +#define BKP_CSR_CTI (1 << 1) /* Bit 1: Clear Tamper Interrupt */ +#define BKP_CSR_TPIE (1 << 2) /* Bit 2: TAMPER Pin interrupt enable */ +#define BKP_CSR_TEF (1 << 8) /* Bit 8: Tamper Event Flag */ +#define BKP_CSR_TIF (1 << 9) /* Bit 9: Tamper Interrupt Flag */ + +/* Backup data register */ + +#define BKP_DR_SHIFT (0) /* Bits 1510: Backup data */ +#define BKP_DR_MASK (0xffff << BKP_DR_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_BKP_H */ diff --git a/arch/arm/src/stm32/chip/stm32_can.h b/arch/arm/src/stm32/chip/stm32_can.h new file mode 100644 index 0000000000000000000000000000000000000000..d64332d1d932092e5f1c8ebda04b147aae7dbddf --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_can.h @@ -0,0 +1,506 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_can.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_CAN_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* 3 TX mailboxes */ + +#define CAN_TXMBOX1 0 +#define CAN_TXMBOX2 1 +#define CAN_TXMBOX3 2 + +/* 2 RX mailboxes */ + +#define CAN_RXMBOX1 0 +#define CAN_RXMBOX2 1 + +/* Number of filters depends on silicon */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_NFILTERS 28 +#else +# define CAN_NFILTERS 14 +#endif + +/* Register Offsets *****************************************************************/ + +/* CAN control and status registers */ + +#define STM32_CAN_MCR_OFFSET 0x0000 /* CAN master control register */ +#define STM32_CAN_MSR_OFFSET 0x0004 /* CAN master status register */ +#define STM32_CAN_TSR_OFFSET 0x0008 /* CAN transmit status register */ +#define STM32_CAN_RF0R_OFFSET 0x000c /* CAN receive FIFO 0 register */ +#define STM32_CAN_RF1R_OFFSET 0x0010 /* CAN receive FIFO 1 register */ +#define STM32_CAN_IER_OFFSET 0x0014 /* CAN interrupt enable register */ +#define STM32_CAN_ESR_OFFSET 0x0018 /* CAN error status register */ +#define STM32_CAN_BTR_OFFSET 0x001c /* CAN bit timing register */ + +/* CAN mailbox registers (3 TX and 2 RX) */ + +#define STM32_CAN_TIR_OFFSET(m) (0x0180+((m)<<4)) +#define STM32_CAN_TI0R_OFFSET 0x0180 /* TX mailbox identifier register 0 */ +#define STM32_CAN_TI1R_OFFSET 0x0190 /* TX mailbox identifier register 1 */ +#define STM32_CAN_TI2R_OFFSET 0x01a0 /* TX mailbox identifier register 2 */ + +#define STM32_CAN_TDTR_OFFSET(m) (0x0184+((m)<<4)) +#define STM32_CAN_TDT0R_OFFSET 0x0184 /* Mailbox data length control and time stamp register 0 */ +#define STM32_CAN_TDT1R_OFFSET 0x0194 /* Mailbox data length control and time stamp register 1 */ +#define STM32_CAN_TDT2R_OFFSET 0x01a4 /* Mailbox data length control and time stamp register 2 */ + +#define STM32_CAN_TDLR_OFFSET(m) (0x0188+((m)<<4)) +#define STM32_CAN_TDL0R_OFFSET 0x0188 /* Mailbox data low register 0 */ +#define STM32_CAN_TDL1R_OFFSET 0x0198 /* Mailbox data low register 1 */ +#define STM32_CAN_TDL2R_OFFSET 0x01a8 /* Mailbox data low register 2 */ + +#define STM32_CAN_TDHR_OFFSET(m) (0x018c+((m)<<4)) +#define STM32_CAN_TDH0R_OFFSET 0x018c /* Mailbox data high register 0 */ +#define STM32_CAN_TDH1R_OFFSET 0x019c /* Mailbox data high register 1 */ +#define STM32_CAN_TDH2R_OFFSET 0x01ac /* Mailbox data high register 2 */ + +#define STM32_CAN_RIR_OFFSET(m) (0x01b0+((m)<<4)) +#define STM32_CAN_RI0R_OFFSET 0x01b0 /* Rx FIFO mailbox identifier register 0 */ +#define STM32_CAN_RI1R_OFFSET 0x01c0 /* Rx FIFO mailbox identifier register 1 */ + +#define STM32_CAN_RDTR_OFFSET(m) (0x01b4+((m)<<4)) +#define STM32_CAN_RDT0R_OFFSET 0x01b4 /* Rx FIFO mailbox data length control and time stamp register 0 */ +#define STM32_CAN_RDT1R_OFFSET 0x01c4 /* Rx FIFO mailbox data length control and time stamp register 1 */ + +#define STM32_CAN_RDLR_OFFSET(m) (0x01b8+((m)<<4)) +#define STM32_CAN_RDL0R_OFFSET 0x01b8 /* Receive FIFO mailbox data low register 0 */ +#define STM32_CAN_RDL1R_OFFSET 0x01c8 /* Receive FIFO mailbox data low register 1 */ + +#define STM32_CAN_RDHR_OFFSET(m) (0x01bc+((m)<<4)) +#define STM32_CAN_RDH0R_OFFSET 0x01bc /* Receive FIFO mailbox data high register 0 */ +#define STM32_CAN_RDH1R_OFFSET 0x01cc /* Receive FIFO mailbox data high register 1 */ + +/* CAN filter registers */ + +#define STM32_CAN_FMR_OFFSET 0x0200 /* CAN filter master register */ +#define STM32_CAN_FM1R_OFFSET 0x0204 /* CAN filter mode register */ +#define STM32_CAN_FS1R_OFFSET 0x020c /* CAN filter scale register */ +#define STM32_CAN_FFA1R_OFFSET 0x0214 /* CAN filter FIFO assignment register */ +#define STM32_CAN_FA1R_OFFSET 0x021c /* CAN filter activation register */ + +/* There are 14 or 28 filter banks (depending) on the device. Each filter bank is + * composed of two 32-bit registers, CAN_FiR: + * F0R1 Offset 0x240 + * F0R2 Offset 0x244 + * F1R1 Offset 0x248 + * F1R2 Offset 0x24c + * ... + */ + +#define STM32_CAN_FIR_OFFSET(f,i) (0x240+((f)<<3)+(((i)-1)<<2)) + +/* Register Addresses ***************************************************************/ + +#if STM32_NCAN > 0 +# define STM32_CAN1_MCR (STM32_CAN1_BASE+STM32_CAN_MCR_OFFSET) +# define STM32_CAN1_MSR (STM32_CAN1_BASE+STM32_CAN_MSR_OFFSET) +# define STM32_CAN1_TSR (STM32_CAN1_BASE+STM32_CAN_TSR_OFFSET) +# define STM32_CAN1_RF0R (STM32_CAN1_BASE+STM32_CAN_RF0R_OFFSET) +# define STM32_CAN1_RF1R (STM32_CAN1_BASE+STM32_CAN_RF1R_OFFSET) +# define STM32_CAN1_IER (STM32_CAN1_BASE+STM32_CAN_IER_OFFSET) +# define STM32_CAN1_ESR (STM32_CAN1_BASE+STM32_CAN_ESR_OFFSET) +# define STM32_CAN1_BTR (STM32_CAN1_BASE+STM32_CAN_BTR_OFFSET) + +# define STM32_CAN1_TIR(m) (STM32_CAN1_BASE+STM32_CAN_TIR_OFFSET(m)) +# define STM32_CAN1_TI0R (STM32_CAN1_BASE+STM32_CAN_TI0R_OFFSET) +# define STM32_CAN1_TI1R (STM32_CAN1_BASE+STM32_CAN_TI1R_OFFSET) +# define STM32_CAN1_TI2R (STM32_CAN1_BASE+STM32_CAN_TI2R_OFFSET) + +# define STM32_CAN1_TDTR(m) (STM32_CAN1_BASE+STM32_CAN_TDTR_OFFSET(m)) +# define STM32_CAN1_TDT0R (STM32_CAN1_BASE+STM32_CAN_TDT0R_OFFSET) +# define STM32_CAN1_TDT1R (STM32_CAN1_BASE+STM32_CAN_TDT1R_OFFSET) +# define STM32_CAN1_TDT2R (STM32_CAN1_BASE+STM32_CAN_TDT2R_OFFSET) + +# define STM32_CAN1_TDLR(m) (STM32_CAN1_BASE+STM32_CAN_TDLR_OFFSET(m)) +# define STM32_CAN1_TDL0R (STM32_CAN1_BASE+STM32_CAN_TDL0R_OFFSET) +# define STM32_CAN1_TDL1R (STM32_CAN1_BASE+STM32_CAN_TDL1R_OFFSET) +# define STM32_CAN1_TDL2R (STM32_CAN1_BASE+STM32_CAN_TDL2R_OFFSET) + +# define STM32_CAN1_TDHR(m) (STM32_CAN1_BASE+STM32_CAN_TDHR_OFFSET(m)) +# define STM32_CAN1_TDH0R (STM32_CAN1_BASE+STM32_CAN_TDH0R_OFFSET) +# define STM32_CAN1_TDH1R (STM32_CAN1_BASE+STM32_CAN_TDH1R_OFFSET) +# define STM32_CAN1_TDH2R (STM32_CAN1_BASE+STM32_CAN_TDH2R_OFFSET) + +# define STM32_CAN1_RIR(m) (STM32_CAN1_BASE+STM32_CAN_RIR_OFFSET(m)) +# define STM32_CAN1_RI0R (STM32_CAN1_BASE+STM32_CAN_RI0R_OFFSET) +# define STM32_CAN1_RI1R (STM32_CAN1_BASE+STM32_CAN_RI1R_OFFSET) + +# define STM32_CAN1_RDTR(m) (STM32_CAN1_BASE+STM32_CAN_RDTR_OFFSET(m)) +# define STM32_CAN1_RDT0R (STM32_CAN1_BASE+STM32_CAN_RDT0R_OFFSET) +# define STM32_CAN1_RDT1R (STM32_CAN1_BASE+STM32_CAN_RDT1R_OFFSET) + +# define STM32_CAN1_RDLR(m) (STM32_CAN1_BASE+STM32_CAN_RDLR_OFFSET(m)) +# define STM32_CAN1_RDL0R (STM32_CAN1_BASE+STM32_CAN_RDL0R_OFFSET) +# define STM32_CAN1_RDL1R (STM32_CAN1_BASE+STM32_CAN_RDL1R_OFFSET) + +# define STM32_CAN1_RDHR(m) (STM32_CAN1_BASE+STM32_CAN_RDHR_OFFSET(m)) +# define STM32_CAN1_RDH0R (STM32_CAN1_BASE+STM32_CAN_RDH0R_OFFSET) +# define STM32_CAN1_RDH1R (STM32_CAN1_BASE+STM32_CAN_RDH1R_OFFSET) + +# define STM32_CAN1_FMR (STM32_CAN1_BASE+STM32_CAN_FMR_OFFSET) +# define STM32_CAN1_FM1R (STM32_CAN1_BASE+STM32_CAN_FM1R_OFFSET) +# define STM32_CAN1_FS1R (STM32_CAN1_BASE+STM32_CAN_FS1R_OFFSET) +# define STM32_CAN1_FFA1R (STM32_CAN1_BASE+STM32_CAN_FFA1R_OFFSET) +# define STM32_CAN1_FA1R (STM32_CAN1_BASE+STM32_CAN_FA1R_OFFSET) +# define STM32_CAN1_FIR(b,i) (STM32_CAN1_BASE+STM32_CAN_FIR_OFFSET(b,i)) +#endif + +#if STM32_NCAN > 1 +# define STM32_CAN2_MCR (STM32_CAN2_BASE+STM32_CAN_MCR_OFFSET) +# define STM32_CAN2_MSR (STM32_CAN2_BASE+STM32_CAN_MSR_OFFSET) +# define STM32_CAN2_TSR (STM32_CAN2_BASE+STM32_CAN_TSR_OFFSET) +# define STM32_CAN2_RF0R (STM32_CAN2_BASE+STM32_CAN_RF0R_OFFSET) +# define STM32_CAN2_RF1R (STM32_CAN2_BASE+STM32_CAN_RF1R_OFFSET) +# define STM32_CAN2_IER (STM32_CAN2_BASE+STM32_CAN_IER_OFFSET) +# define STM32_CAN2_ESR (STM32_CAN2_BASE+STM32_CAN_ESR_OFFSET) +# define STM32_CAN2_BTR (STM32_CAN2_BASE+STM32_CAN_BTR_OFFSET) + +# define STM32_CAN2_TIR(m) (STM32_CAN2_BASE+STM32_CAN_TIR_OFFSET(m)) +# define STM32_CAN2_TI0R (STM32_CAN2_BASE+STM32_CAN_TI0R_OFFSET) +# define STM32_CAN2_TI1R (STM32_CAN2_BASE+STM32_CAN_TI1R_OFFSET) +# define STM32_CAN2_TI2R (STM32_CAN2_BASE+STM32_CAN_TI2R_OFFSET) + +# define STM32_CAN2_TDTR(m) (STM32_CAN2_BASE+STM32_CAN_TDTR_OFFSET(m)) +# define STM32_CAN2_TDT0R (STM32_CAN2_BASE+STM32_CAN_TDT0R_OFFSET) +# define STM32_CAN2_TDT1R (STM32_CAN2_BASE+STM32_CAN_TDT1R_OFFSET) +# define STM32_CAN2_TDT2R (STM32_CAN2_BASE+STM32_CAN_TDT2R_OFFSET) + +# define STM32_CAN2_TDLR(m) (STM32_CAN2_BASE+STM32_CAN_TDLR_OFFSET(m)) +# define STM32_CAN2_TDL0R (STM32_CAN2_BASE+STM32_CAN_TDL0R_OFFSET) +# define STM32_CAN2_TDL1R (STM32_CAN2_BASE+STM32_CAN_TDL1R_OFFSET) +# define STM32_CAN2_TDL2R (STM32_CAN2_BASE+STM32_CAN_TDL2R_OFFSET) + +# define STM32_CAN2_TDHR(m) (STM32_CAN2_BASE+STM32_CAN_TDHR_OFFSET(m)) +# define STM32_CAN2_TDH0R (STM32_CAN2_BASE+STM32_CAN_TDH0R_OFFSET) +# define STM32_CAN2_TDH1R (STM32_CAN2_BASE+STM32_CAN_TDH1R_OFFSET) +# define STM32_CAN2_TDH2R (STM32_CAN2_BASE+STM32_CAN_TDH2R_OFFSET) + +# define STM32_CAN2_RIR(m) (STM32_CAN2_BASE+STM32_CAN_RIR_OFFSET(m)) +# define STM32_CAN2_RI0R (STM32_CAN2_BASE+STM32_CAN_RI0R_OFFSET) +# define STM32_CAN2_RI1R (STM32_CAN2_BASE+STM32_CAN_RI1R_OFFSET) + +# define STM32_CAN2_RDTR(m) (STM32_CAN2_BASE+STM32_CAN_RDTR_OFFSET(m)) +# define STM32_CAN2_RDT0R (STM32_CAN2_BASE+STM32_CAN_RDT0R_OFFSET) +# define STM32_CAN2_RDT1R (STM32_CAN2_BASE+STM32_CAN_RDT1R_OFFSET) + +# define STM32_CAN2_RDLR(m) (STM32_CAN2_BASE+STM32_CAN_RDLR_OFFSET(m)) +# define STM32_CAN2_RDL0R (STM32_CAN2_BASE+STM32_CAN_RDL0R_OFFSET) +# define STM32_CAN2_RDL1R (STM32_CAN2_BASE+STM32_CAN_RDL1R_OFFSET) + +# define STM32_CAN2_RDHR(m) (STM32_CAN2_BASE+STM32_CAN_RDHR_OFFSET(m)) +# define STM32_CAN2_RDH0R (STM32_CAN2_BASE+STM32_CAN_RDH0R_OFFSET) +# define STM32_CAN2_RDH1R (STM32_CAN2_BASE+STM32_CAN_RDH1R_OFFSET) + +# define STM32_CAN2_FMR (STM32_CAN2_BASE+STM32_CAN_FMR_OFFSET) +# define STM32_CAN2_FM1R (STM32_CAN2_BASE+STM32_CAN_FM1R_OFFSET) +# define STM32_CAN2_FS1R (STM32_CAN2_BASE+STM32_CAN_FS1R_OFFSET) +# define STM32_CAN2_FFA1R (STM32_CAN2_BASE+STM32_CAN_FFA1R_OFFSET) +# define STM32_CAN2_FA1R (STM32_CAN2_BASE+STM32_CAN_FA1R_OFFSET) +# define STM32_CAN2_FIR(b,i) (STM32_CAN2_BASE+STM32_CAN_FIR_OFFSET(b,i)) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* CAN master control register */ + +#define CAN_MCR_INRQ (1 << 0) /* Bit 0: Initialization Request */ +#define CAN_MCR_SLEEP (1 << 1) /* Bit 1: Sleep Mode Request */ +#define CAN_MCR_TXFP (1 << 2) /* Bit 2: Transmit FIFO Priority */ +#define CAN_MCR_RFLM (1 << 3) /* Bit 3: Receive FIFO Locked Mode */ +#define CAN_MCR_NART (1 << 4) /* Bit 4: No Automatic Retransmission */ +#define CAN_MCR_AWUM (1 << 5) /* Bit 5: Automatic Wakeup Mode */ +#define CAN_MCR_ABOM (1 << 6) /* Bit 6: Automatic Bus-Off Management */ +#define CAN_MCR_TTCM (1 << 7) /* Bit 7: Time Triggered Communication Mode Enable */ +#define CAN_MCR_RESET (1 << 15) /* Bit 15: bxCAN software master reset */ +#define CAN_MCR_DBF (1 << 16) /* Bit 16: Debug freeze */ + +/* CAN master status register */ + +#define CAN_MSR_INAK (1 << 0) /* Bit 0: Initialization Acknowledge */ +#define CAN_MSR_SLAK (1 << 1) /* Bit 1: Sleep Acknowledge */ +#define CAN_MSR_ERRI (1 << 2) /* Bit 2: Error Interrupt */ +#define CAN_MSR_WKUI (1 << 3) /* Bit 3: Wakeup Interrupt */ +#define CAN_MSR_SLAKI (1 << 4) /* Bit 4: Sleep acknowledge interrupt */ +#define CAN_MSR_TXM (1 << 8) /* Bit 8: Transmit Mode */ +#define CAN_MSR_RXM (1 << 9) /* Bit 9: Receive Mode */ +#define CAN_MSR_SAMP (1 << 10) /* Bit 10: Last Sample Point */ +#define CAN_MSR_RX (1 << 11) /* Bit 11: CAN Rx Signal */ + +/* CAN transmit status register */ + +#define CAN_TSR_RQCP0 (1 << 0) /* Bit 0: Request Completed Mailbox 0 */ +#define CAN_TSR_TXOK0 (1 << 1) /* Bit 1 : Transmission OK of Mailbox 0 */ +#define CAN_TSR_ALST0 (1 << 2) /* Bit 2 : Arbitration Lost for Mailbox 0 */ +#define CAN_TSR_TERR0 (1 << 3) /* Bit 3 : Transmission Error of Mailbox 0 */ +#define CAN_TSR_ABRQ0 (1 << 7) /* Bit 7 : Abort Request for Mailbox 0 */ +#define CAN_TSR_RQCP1 (1 << 8) /* Bit 8 : Request Completed Mailbox 1 */ +#define CAN_TSR_TXOK1 (1 << 9) /* Bit 9 : Transmission OK of Mailbox 1 */ +#define CAN_TSR_ALST1 (1 << 10) /* Bit 10 : Arbitration Lost for Mailbox 1 */ +#define CAN_TSR_TERR1 (1 << 11) /* Bit 11 : Transmission Error of Mailbox 1 */ +#define CAN_TSR_ABRQ1 (1 << 15) /* Bit 15 : Abort Request for Mailbox 1 */ +#define CAN_TSR_RQCP2 (1 << 16) /* Bit 16 : Request Completed Mailbox 2 */ +#define CAN_TSR_TXOK2 (1 << 17) /* Bit 17 : Transmission OK of Mailbox 2 */ +#define CAN_TSR_ALST2 (1 << 18) /* Bit 18: Arbitration Lost for Mailbox 2 */ +#define CAN_TSR_TERR2 (1 << 19) /* Bit 19: Transmission Error of Mailbox 2 */ +#define CAN_TSR_ABRQ2 (1 << 23) /* Bit 23: Abort Request for Mailbox 2 */ +#define CAN_TSR_CODE_SHIFT (24) /* Bits 25-24: Mailbox Code */ +#define CAN_TSR_CODE_MASK (3 << CAN_TSR_CODE_SHIFT) +#define CAN_TSR_TME0 (1 << 26) /* Bit 26: Transmit Mailbox 0 Empty */ +#define CAN_TSR_TME1 (1 << 27) /* Bit 27: Transmit Mailbox 1 Empty */ +#define CAN_TSR_TME2 (1 << 28) /* Bit 28: Transmit Mailbox 2 Empty */ +#define CAN_TSR_LOW0 (1 << 29) /* Bit 29: Lowest Priority Flag for Mailbox 0 */ +#define CAN_TSR_LOW1 (1 << 30) /* Bit 30: Lowest Priority Flag for Mailbox 1 */ +#define CAN_TSR_LOW2 (1 << 31) /* Bit 31: Lowest Priority Flag for Mailbox 2 */ + +/* CAN receive FIFO 0/1 registers */ + +#define CAN_RFR_FMP_SHIFT (0) /* Bits 1-0: FIFO Message Pending */ +#define CAN_RFR_FMP_MASK (3 << CAN_RFR_FMP_SHIFT) +#define CAN_RFR_FULL (1 << 3) /* Bit 3: FIFO 0 Full */ +#define CAN_RFR_FOVR (1 << 4) /* Bit 4: FIFO 0 Overrun */ +#define CAN_RFR_RFOM (1 << 5) /* Bit 5: Release FIFO 0 Output Mailbox */ + +/* CAN interrupt enable register */ + +#define CAN_IER_TMEIE (1 << 0) /* Bit 0: Transmit Mailbox Empty Interrupt Enable */ +#define CAN_IER_FMPIE0 (1 << 1) /* Bit 1: FIFO Message Pending Interrupt Enable */ +#define CAN_IER_FFIE0 (1 << 2) /* Bit 2: FIFO Full Interrupt Enable */ +#define CAN_IER_FOVIE0 (1 << 3) /* Bit 3: FIFO Overrun Interrupt Enable */ +#define CAN_IER_FMPIE1 (1 << 4) /* Bit 4: FIFO Message Pending Interrupt Enable */ +#define CAN_IER_FFIE1 (1 << 5) /* Bit 5: FIFO Full Interrupt Enable */ +#define CAN_IER_FOVIE1 (1 << 6) /* Bit 6: FIFO Overrun Interrupt Enable */ +#define CAN_IER_EWGIE (1 << 8) /* Bit 8: Error Warning Interrupt Enable */ +#define CAN_IER_EPVIE (1 << 9) /* Bit 9: Error Passive Interrupt Enable */ +#define CAN_IER_BOFIE (1 << 10) /* Bit 10: Bus-Off Interrupt Enable */ +#define CAN_IER_LECIE (1 << 11) /* Bit 11: Last Error Code Interrupt Enable */ +#define CAN_IER_ERRIE (1 << 15) /* Bit 15: Error Interrupt Enable */ +#define CAN_IER_WKUIE (1 << 16) /* Bit 16: Wakeup Interrupt Enable */ +#define CAN_IER_SLKIE (1 << 17) /* Bit 17: Sleep Interrupt Enable */ + +/* CAN error status register */ + +#define CAN_ESR_EWGF (1 << 0) /* Bit 0: Error Warning Flag */ +#define CAN_ESR_EPVF (1 << 1) /* Bit 1: Error Passive Flag */ +#define CAN_ESR_BOFF (1 << 2) /* Bit 2: Bus-Off Flag */ +#define CAN_ESR_LEC_SHIFT (4) /* Bits 6-4: Last Error Code */ +#define CAN_ESR_LEC_MASK (7 << CAN_ESR_LEC_SHIFT) +# define CAN_ESR_NOERROR (0 << CAN_ESR_LEC_SHIFT) /* 000: No Error */ +# define CAN_ESR_STUFFERROR (1 << CAN_ESR_LEC_SHIFT) /* 001: Stuff Error */ +# define CAN_ESR_FORMERROR (2 << CAN_ESR_LEC_SHIFT) /* 010: Form Error */ +# define CAN_ESR_ACKERROR (3 << CAN_ESR_LEC_SHIFT) /* 011: Acknowledgment Error */ +# define CAN_ESR_BRECERROR (4 << CAN_ESR_LEC_SHIFT) /* 100: Bit recessive Error */ +# define CAN_ESR_BDOMERROR (5 << CAN_ESR_LEC_SHIFT) /* 101: Bit dominant Error */ +# define CAN_ESR_CRCERRPR (6 << CAN_ESR_LEC_SHIFT) /* 110: CRC Error */ +# define CAN_ESR_SWERROR (7 << CAN_ESR_LEC_SHIFT) /* 111: Set by software */ +#define CAN_ESR_TEC_SHIFT (16) /* Bits 23-16: LS byte of the 9-bit Transmit Error Counter */ +#define CAN_ESR_TEC_MASK (0xff << CAN_ESR_TEC_SHIF) +#define CAN_ESR_REC_SHIFT (24) /* Bits 31-24: Receive Error Counter */ +#define CAN_ESR_REC_MASK (0xff << CAN_ESR_REC_SHIFT) + +/* CAN bit timing register */ + +#define CAN_BTR_BRP_SHIFT (0) /* Bits 9-0: Baud Rate Prescaler */ +#define CAN_BTR_BRP_MASK (0x03ff << CAN_BTR_BRP_SHIFT) +#define CAN_BTR_TS1_SHIFT (16) /* Bits 19-16: Time Segment 1 */ +#define CAN_BTR_TS1_MASK (0x0f << CAN_BTR_TS1_SHIFT) +#define CAN_BTR_TS2_SHIFT (20) /* Bits 22-20: Time Segment 2 */ +#define CAN_BTR_TS2_MASK (7 << CAN_BTR_TS2_SHIFT) +#define CAN_BTR_SJW_SHIFT (24) /* Bits 25-24: Resynchronization Jump Width */ +#define CAN_BTR_SJW_MASK (3 << CAN_BTR_SJW_SHIFT) +#define CAN_BTR_LBKM (1 << 30) /* Bit 30: Loop Back Mode (Debug) */ +#define CAN_BTR_SILM (1 << 31) /* Bit 31: Silent Mode (Debug) */ + +#define CAN_BTR_BRP_MAX (1024) /* Maximum BTR value (without decrement) */ +#define CAN_BTR_TSEG1_MAX (16) /* Maximum TSEG1 value (without decrement) */ +#define CAN_BTR_TSEG2_MAX (8) /* Maximum TSEG2 value (without decrement) */ + +/* TX mailbox identifier register */ + +#define CAN_TIR_TXRQ (1 << 0) /* Bit 0: Transmit Mailbox Request */ +#define CAN_TIR_RTR (1 << 1) /* Bit 1: Remote Transmission Request */ +#define CAN_TIR_IDE (1 << 2) /* Bit 2: Identifier Extension */ +#define CAN_TIR_EXID_SHIFT (3) /* Bit 3-31: Extended Identifier */ +#define CAN_TIR_EXID_MASK (0x1fffffff << CAN_TIR_EXID_SHIFT) +#define CAN_TIR_STID_SHIFT (21) /* Bits 21-31: Standard Identifier */ +#define CAN_TIR_STID_MASK (0x07ff << CAN_TIR_STID_SHIFT) + +/* Mailbox data length control and time stamp register */ + +#define CAN_TDTR_DLC_SHIFT (0) /* Bits 3:0: Data Length Code */ +#define CAN_TDTR_DLC_MASK (0x0f << CAN_TDTR_DLC_SHIFT) +#define CAN_TDTR_TGT (1 << 8) /* Bit 8: Transmit Global Time */ +#define CAN_TDTR_TIME_SHIFT (16) /* Bits 31:16: Message Time Stamp */ +#define CAN_TDTR_TIME_MASK (0xffff << CAN_TDTR_TIME_SHIFT) + +/* Mailbox data low register */ + +#define CAN_TDLR_DATA0_SHIFT (0) /* Bits 7-0: Data Byte 0 */ +#define CAN_TDLR_DATA0_MASK (0xff << CAN_TDLR_DATA0_SHIFT) +#define CAN_TDLR_DATA1_SHIFT (8) /* Bits 15-8: Data Byte 1 */ +#define CAN_TDLR_DATA1_MASK (0xff << CAN_TDLR_DATA1_SHIFT) +#define CAN_TDLR_DATA2_SHIFT (16) /* Bits 23-16: Data Byte 2 */ +#define CAN_TDLR_DATA2_MASK (0xff << CAN_TDLR_DATA2_SHIFT) +#define CAN_TDLR_DATA3_SHIFT (24) /* Bits 31-24: Data Byte 3 */ +#define CAN_TDLR_DATA3_MASK (0xff << CAN_TDLR_DATA3_SHIFT) + +/* Mailbox data high register */ + +#define CAN_TDHR_DATA4_SHIFT (0) /* Bits 7-0: Data Byte 4 */ +#define CAN_TDHR_DATA4_MASK (0xff << CAN_TDHR_DATA4_SHIFT) +#define CAN_TDHR_DATA5_SHIFT (8) /* Bits 15-8: Data Byte 5 */ +#define CAN_TDHR_DATA5_MASK (0xff << CAN_TDHR_DATA5_SHIFT) +#define CAN_TDHR_DATA6_SHIFT (16) /* Bits 23-16: Data Byte 6 */ +#define CAN_TDHR_DATA6_MASK (0xff << CAN_TDHR_DATA6_SHIFT) +#define CAN_TDHR_DATA7_SHIFT (24) /* Bits 31-24: Data Byte 7 */ +#define CAN_TDHR_DATA7_MASK (0xff << CAN_TDHR_DATA7_SHIFT) + +/* Rx FIFO mailbox identifier register */ + +#define CAN_RIR_RTR (1 << 1) /* Bit 1: Remote Transmission Request */ +#define CAN_RIR_IDE (1 << 2) /* Bit 2: Identifier Extension */ +#define CAN_RIR_EXID_SHIFT (3) /* Bit 3-31: Extended Identifier */ +#define CAN_RIR_EXID_MASK (0x1fffffff << CAN_RIR_EXID_SHIFT) +#define CAN_RIR_STID_SHIFT (21) /* Bits 21-31: Standard Identifier */ +#define CAN_RIR_STID_MASK (0x07ff << CAN_RIR_STID_SHIFT) + +/* Receive FIFO mailbox data length control and time stamp register */ + +#define CAN_RDTR_DLC_SHIFT (0) /* Bits 3:0: Data Length Code */ +#define CAN_RDTR_DLC_MASK (0x0f << CAN_RDTR_DLC_SHIFT) +#define CAN_RDTR_FM_SHIFT (8) /* Bits 15-8: Filter Match Index */ +#define CAN_RDTR_FM_MASK (0xff << CAN_RDTR_FM_SHIFT) +#define CAN_RDTR_TIME_SHIFT (16) /* Bits 31:16: Message Time Stamp */ +#define CAN_RDTR_TIME_MASK (0xffff << CAN_RDTR_TIME_SHIFT) + +/* Receive FIFO mailbox data low register */ + +#define CAN_RDLR_DATA0_SHIFT (0) /* Bits 7-0: Data Byte 0 */ +#define CAN_RDLR_DATA0_MASK (0xff << CAN_RDLR_DATA0_SHIFT) +#define CAN_RDLR_DATA1_SHIFT (8) /* Bits 15-8: Data Byte 1 */ +#define CAN_RDLR_DATA1_MASK (0xff << CAN_RDLR_DATA1_SHIFT) +#define CAN_RDLR_DATA2_SHIFT (16) /* Bits 23-16: Data Byte 2 */ +#define CAN_RDLR_DATA2_MASK (0xff << CAN_RDLR_DATA2_SHIFT) +#define CAN_RDLR_DATA3_SHIFT (24) /* Bits 31-24: Data Byte 3 */ +#define CAN_RDLR_DATA3_MASK (0xff << CAN_RDLR_DATA3_SHIFT) + +/* Receive FIFO mailbox data high register */ + +#define CAN_RDHR_DATA4_SHIFT (0) /* Bits 7-0: Data Byte 4 */ +#define CAN_RDHR_DATA4_MASK (0xff << CAN_RDHR_DATA4_SHIFT) +#define CAN_RDHR_DATA5_SHIFT (8) /* Bits 15-8: Data Byte 5 */ +#define CAN_RDHR_DATA5_MASK (0xff << CAN_RDHR_DATA5_SHIFT) +#define CAN_RDHR_DATA6_SHIFT (16) /* Bits 23-16: Data Byte 6 */ +#define CAN_RDHR_DATA6_MASK (0xff << CAN_RDHR_DATA6_SHIFT) +#define CAN_RDHR_DATA7_SHIFT (24) /* Bits 31-24: Data Byte 7 */ +#define CAN_RDHR_DATA7_MASK (0xff << CAN_RDHR_DATA7_SHIFT) + +/* CAN filter master register */ + +#define CAN_FMR_FINIT (1 << 0) /* Bit 0: Filter Init Mode */ +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_FMR_CAN2SB_SHIFT (8) /* Bits 13-8: CAN2 start bank */ +# define CAN_FMR_CAN2SB_MASK (0x3f << CAN_FMR_CAN2SB_SHIFT) +#endif + +/* CAN filter mode register */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_FM1R_FBM_SHIFT (0) /* Bits 13:0: Filter Mode */ +# define CAN_FM1R_FBM_MASK (0x3fff << CAN_FM1R_FBM_SHIFT) +#else +# define CAN_FM1R_FBM_SHIFT (0) /* Bits 27:0: Filter Mode */ +# define CAN_FM1R_FBM_MASK (0x0fffffff << CAN_FM1R_FBM_SHIFT) +#endif + +/* CAN filter scale register */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_FS1R_FSC_SHIFT (0) /* Bits 13:0: Filter Scale Configuration */ +# define CAN_FS1R_FSC_MASK (0x3fff << CAN_FS1R_FSC_SHIFT) +#else +# define CAN_FS1R_FSC_SHIFT (0) /* Bits 27:0: Filter Scale Configuration */ +# define CAN_FS1R_FSC_MASK (0x0fffffff << CAN_FS1R_FSC_SHIFT) +#endif + +/* CAN filter FIFO assignment register */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_FFA1R_FFA_SHIFT (0) /* Bits 13:0: Filter FIFO Assignment */ +# define CAN_FFA1R_FFA_MASK (0x3fff << CAN_FFA1R_FFA_SHIFT) +#else +# define CAN_FFA1R_FFA_SHIFT (0) /* Bits 27:0: Filter FIFO Assignment */ +# define CAN_FFA1R_FFA_MASK (0x0fffffff << CAN_FFA1R_FFA_SHIFT) +#endif + +/* CAN filter activation register */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CAN_FA1R_FACT_SHIFT (0) /* Bits 13:0: Filter Active */ +# define CAN_FA1R_FACT_MASK (0x3fff << CAN_FA1R_FACT_SHIFT) +#else +# define CAN_FA1R_FACT_SHIFT (0) /* Bits 27:0: Filter Active */ +# define CAN_FA1R_FACT_MASK (0x0fffffff << CAN_FA1R_FACT_SHIFT) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_CAN_H */ diff --git a/arch/arm/src/stm32/chip/stm32_dac.h b/arch/arm/src/stm32/chip/stm32_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..8669421fa4db4ba462db3f83d43ba3b8facb58b3 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_dac.h @@ -0,0 +1,258 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_dac.h + * + * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_DAC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_DAC_CR_OFFSET 0x0000 /* DAC control register */ +#define STM32_DAC_SWTRIGR_OFFSET 0x0004 /* DAC software trigger register */ +#define STM32_DAC_DHR12R1_OFFSET 0x0008 /* DAC channel1 12-bit right-aligned data holding register */ +#define STM32_DAC_DHR12L1_OFFSET 0x000c /* DAC channel1 12-bit left aligned data holding register */ +#define STM32_DAC_DHR8R1_OFFSET 0x0010 /* DAC channel1 8-bit right aligned data holding register */ +#define STM32_DAC_DHR12R2_OFFSET 0x0014 /* DAC channel2 12-bit right aligned data holding register */ +#define STM32_DAC_DHR12L2_OFFSET 0x0018 /* DAC channel2 12-bit left aligned data holding register */ +#define STM32_DAC_DHR8R2_OFFSET 0x001c /* DAC channel2 8-bit right-aligned data holding register */ +#define STM32_DAC_DHR12RD_OFFSET 0x0020 /* Dual DAC 12-bit right-aligned data holding register */ +#define STM32_DAC_DHR12LD_OFFSET 0x0024 /* DUAL DAC 12-bit left aligned data holding register */ +#define STM32_DAC_DHR8RD_OFFSET 0x0028 /* DUAL DAC 8-bit right aligned data holding register */ +#define STM32_DAC_DOR1_OFFSET 0x002c /* DAC channel1 data output register */ +#define STM32_DAC_DOR2_OFFSET 0x0030 /* DAC channel2 data output register */ +#define STM32_DAC_SR_OFFSET 0x0034 /* DAC status register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_DAC_CR (STM32_DAC_BASE+STM32_DAC_CR_OFFSET) +#define STM32_DAC_SWTRIGR (STM32_DAC_BASE+STM32_DAC_SWTRIGR_OFFSET) +#define STM32_DAC_DHR12R1 (STM32_DAC_BASE+STM32_DAC_DHR12R1_OFFSET) +#define STM32_DAC_DHR12L1 (STM32_DAC_BASE+STM32_DAC_DHR12L1_OFFSET) +#define STM32_DAC_DHR8R1 (STM32_DAC_BASE+STM32_DAC_DHR8R1_OFFSET) +#define STM32_DAC_DHR12R2 (STM32_DAC_BASE+STM32_DAC_DHR12R2_OFFSET) +#define STM32_DAC_DHR12L2 (STM32_DAC_BASE+STM32_DAC_DHR12L2_OFFSET) +#define STM32_DAC_DHR8R2 (STM32_DAC_BASE+STM32_DAC_DHR8R2_OFFSET) +#define STM32_DAC_DHR12RD (STM32_DAC_BASE+STM32_DAC_DHR12RD_OFFSET) +#define STM32_DAC_DHR12LD (STM32_DAC_BASE+STM32_DAC_DHR12LD_OFFSET) +#define STM32_DAC_DHR8RD (STM32_DAC_BASE+STM32_DAC_DHR8RD_OFFSET) +#define STM32_DAC_DOR1 (STM32_DAC_BASE+STM32_DAC_DOR1_OFFSET) +#define STM32_DAC_DOR2 (STM32_DAC_BASE+STM32_DAC_DOR2_OFFSET) +#define STM32_DAC_SR (STM32_DAC_BASE+STM32_DAC_SR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* DAC control register */ +/* These definitions may be used for 16-bit values of either channel */ + +#define DAC_CR_EN (1 << 0) /* Bit 0: DAC channel enable */ +#define DAC_CR_BOFF (1 << 1) /* Bit 1: DAC channel output buffer disable */ +#define DAC_CR_TEN (1 << 2) /* Bit 2: DAC channel trigger enable */ +#define DAC_CR_TSEL_SHIFT (3) /* Bits 3-5: DAC channel trigger selection */ +#define DAC_CR_TSEL_MASK (7 << DAC_CR_TSEL_SHIFT) +# define DAC_CR_TSEL_TIM6 (0 << DAC_CR_TSEL_SHIFT) /* Timer 6 TRGO event */ +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define DAC_CR_TSEL_TIM3 (1 << DAC_CR_TSEL_SHIFT) /* Timer 3 TRGO event */ +#else +# define DAC_CR_TSEL_TIM8 (1 << DAC_CR_TSEL_SHIFT) /* Timer 8 TRGO event */ +#endif +# define DAC_CR_TSEL_TIM7 (2 << DAC_CR_TSEL_SHIFT) /* Timer 7 TRGO event */ +# define DAC_CR_TSEL_TIM5 (3 << DAC_CR_TSEL_SHIFT) /* Timer 5 TRGO event */ +# define DAC_CR_TSEL_TIM2 (4 << DAC_CR_TSEL_SHIFT) /* Timer 2 TRGO event */ +# define DAC_CR_TSEL_TIM4 (5 << DAC_CR_TSEL_SHIFT) /* Timer 4 TRGO event */ +# define DAC_CR_TSEL_EXT9 (6 << DAC_CR_TSEL_SHIFT) /* External line9 */ +# define DAC_CR_TSEL_SW (7 << DAC_CR_TSEL_SHIFT) /* Software trigger */ +#define DAC_CR_WAVE_SHIFT (6) /* Bits 6-7: DAC channel noise/triangle wave generation */ +#define DAC_CR_WAVE_MASK (3 << DAC_CR_WAVE_SHIFT) +# define DAC_CR_WAVE_DISABLED (0 << DAC_CR_WAVE_SHIFT) /* Wave generation disabled */ +# define DAC_CR_WAVE_NOISE (1 << DAC_CR_WAVE_SHIFT) /* Noise wave generation enabled */ +# define DAC_CR_WAVE_TRIANGLE (2 << DAC_CR_WAVE_SHIFT) /* Triangle wave generation enabled */ +#define DAC_CR_MAMP_SHIFT (8) /* Bits 8-11: DAC channel mask/amplitude selector */ +#define DAC_CR_MAMP_MASK (15 << DAC_CR_MAMP_SHIFT) +# define DAC_CR_MAMP_AMP1 (0 << DAC_CR_MAMP1_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */ +# define DAC_CR_MAMP_AMP3 (1 << DAC_CR_MAMP_SHIFT) /* Unmask bits[1:0] of LFSR/triangle amplitude=3 */ +# define DAC_CR_MAMP_AMP7 (2 << DAC_CR_MAMP_SHIFT) /* Unmask bits[2:0] of LFSR/triangle amplitude=7 */ +# define DAC_CR_MAMP_AMP15 (3 << DAC_CR_MAMP_SHIFT) /* Unmask bits[3:0] of LFSR/triangle amplitude=15 */ +# define DAC_CR_MAMP_AMP31 (4 << DAC_CR_MAMP_SHIFT) /* Unmask bits[4:0] of LFSR/triangle amplitude=31 */ +# define DAC_CR_MAMP_AMP63 (5 << DAC_CR_MAMP_SHIFT) /* Unmask bits[5:0] of LFSR/triangle amplitude=63 */ +# define DAC_CR_MAMP_AMP127 (6 << DAC_CR_MAMP_SHIFT) /* Unmask bits[6:0] of LFSR/triangle amplitude=127 */ +# define DAC_CR_MAMP_AMP255 (7 << DAC_CR_MAMP_SHIFT) /* Unmask bits[7:0] of LFSR/triangle amplitude=255 */ +# define DAC_CR_MAMP_AMP511 (8 << DAC_CR_MAMP_SHIFT) /* Unmask bits[8:0] of LFSR/triangle amplitude=511 */ +# define DAC_CR_MAMP_AMP1023 (9 << DAC_CR_MAMP_SHIFT) /* Unmask bits[9:0] of LFSR/triangle amplitude=1023 */ +# define DAC_CR_MAMP_AMP2047 (10 << DAC_CR_MAMP_SHIFT) /* Unmask bits[10:0] of LFSR/triangle amplitude=2047 */ +# define DAC_CR_MAMP_AMP4095 (11 << DAC_CR_MAMP_SHIFT) /* Unmask bits[11:0] of LFSR/triangle amplitude=4095 */ +#define DAC_CR_DMAEN (1 << 12) /* Bit 12: DAC channel DMA enable */ +#define DAC_CR_DMAUDRIE (1 << 13) /* Bit 13: DAC channel DMA Underrun Interrupt enable */ + +/* These definitions may be used with the full, 32-bit register */ + +#define DAC_CR_EN1 (1 << 0) /* Bit 0: DAC channel1 enable */ +#define DAC_CR_BOFF1 (1 << 1) /* Bit 1: DAC channel1 output buffer disable */ +#define DAC_CR_TEN1 (1 << 2) /* Bit 2: DAC channel1 trigger enable */ +#define DAC_CR_TSEL1_SHIFT (3) /* Bits 3-5: DAC channel1 trigger selection */ +#define DAC_CR_TSEL1_MASK (7 << DAC_CR_TSEL1_SHIFT) +# define DAC_CR_TSEL1_TIM6 (0 << DAC_CR_TSEL1_SHIFT) /* Timer 6 TRGO event */ +# define DAC_CR_TSEL1_TIM8 (1 << DAC_CR_TSEL1_SHIFT) /* Timer 8 TRGO event */ +# define DAC_CR_TSEL1_TIM7 (2 << DAC_CR_TSEL1_SHIFT) /* Timer 7 TRGO event */ +# define DAC_CR_TSEL1_TIM5 (3 << DAC_CR_TSEL1_SHIFT) /* Timer 5 TRGO event */ +# define DAC_CR_TSEL1_TIM2 (4 << DAC_CR_TSEL1_SHIFT) /* Timer 2 TRGO event */ +# define DAC_CR_TSEL1_TIM4 (5 << DAC_CR_TSEL1_SHIFT) /* Timer 4 TRGO event */ +# define DAC_CR_TSEL1_EXT9 (6 << DAC_CR_TSEL1_SHIFT) /* External line9 */ +# define DAC_CR_TSEL1_SW (7 << DAC_CR_TSEL1_SHIFT) /* Software trigger */ +#define DAC_CR_WAVE1_SHIFT (6) /* Bits 6-7: DAC channel1 noise/triangle wave generation */enable +#define DAC_CR_WAVE1_MASK (3 << DAC_CR_WAVE1_SHIFT) +# define DAC_CR_WAVE1_DISABLED (0 << DAC_CR_WAVE1_SHIFT) /* Wave generation disabled */ +# define DAC_CR_WAVE1_NOISE (1 << DAC_CR_WAVE1_SHIFT) /* Noise wave generation enabled */ +# define DAC_CR_WAVE1_TRIANGLE (2 << DAC_CR_WAVE1_SHIFT) /* Triangle wave generation enabled */ +#define DAC_CR_MAMP1_SHIFT (8) /* Bits 8-11: DAC channel1 mask/amplitude selector */ +#define DAC_CR_MAMP1_MASK (15 << DAC_CR_MAMP1_SHIFT) +# define DAC_CR_MAMP1_AMP1 (0 << DAC_CR_MAMP1_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */ +# define DAC_CR_MAMP1_AMP3 (1 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[1:0] of LFSR/triangle amplitude=3 */ +# define DAC_CR_MAMP1_AMP7 (2 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[2:0] of LFSR/triangle amplitude=7 */ +# define DAC_CR_MAMP1_AMP15 (3 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[3:0] of LFSR/triangle amplitude=15 */ +# define DAC_CR_MAMP1_AMP31 (4 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[4:0] of LFSR/triangle amplitude=31 */ +# define DAC_CR_MAMP1_AMP63 (5 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[5:0] of LFSR/triangle amplitude=63 */ +# define DAC_CR_MAMP1_AMP127 (6 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[6:0] of LFSR/triangle amplitude=127 */ +# define DAC_CR_MAMP1_AMP255 (7 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[7:0] of LFSR/triangle amplitude=255 */ +# define DAC_CR_MAMP1_AMP511 (8 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[8:0] of LFSR/triangle amplitude=511 */ +# define DAC_CR_MAMP1_AMP1023 (9 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[9:0] of LFSR/triangle amplitude=1023 */ +# define DAC_CR_MAMP1_AMP2047 (10 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[10:0] of LFSR/triangle amplitude=2047 */ +# define DAC_CR_MAMP1_AMP4095 (11 << DAC_CR_MAMP1_SHIFT) /* Unmask bits[11:0] of LFSR/triangle amplitude=4095 */ +#define DAC_CR_DMAEN1 (1 << 12) /* Bit 12: DAC channel1 DMA enable */ +#define DAC_CR_DMAUDRIE1 (1 << 13) /* Bit 13: DAC channel1 DMA Underrun Interrupt enable */ + +#define DAC_CR_EN2 (1 << 16) /* Bit 16: DAC channel2 enable */ +#define DAC_CR_BOFF2 (1 << 17) /* Bit 17: DAC channel2 output buffer disable */ +#define DAC_CR_TEN2 (1 << 18) /* Bit 18: DAC channel2 trigger enable */ +#define DAC_CR_TSEL2_SHIFT (19) /* Bits 19-21: DAC channel2 trigger selection */ +#define DAC_CR_TSEL2_MASK (7 << DAC_CR_TSEL2_SHIFT) +# define DAC_CR_TSEL2_TIM6 (0 << DAC_CR_TSEL2_SHIFT) /* Timer 6 TRGO event */ +# define DAC_CR_TSEL2_TIM8 (1 << DAC_CR_TSEL2_SHIFT) /* Timer 8 TRGO event */ +# define DAC_CR_TSEL2_TIM7 (2 << DAC_CR_TSEL2_SHIFT) /* Timer 7 TRGO event */ +# define DAC_CR_TSEL2_TIM5 (3 << DAC_CR_TSEL2_SHIFT) /* Timer 5 TRGO event */ +# define DAC_CR_TSEL2_TIM2 (4 << DAC_CR_TSEL2_SHIFT) /* Timer 2 TRGO event */ +# define DAC_CR_TSEL2_TIM4 (5 << DAC_CR_TSEL2_SHIFT) /* Timer 4 TRGO event */ +# define DAC_CR_TSEL2_EXT9 (6 << DAC_CR_TSEL2_SHIFT) /* External line9 */ +# define DAC_CR_TSEL2_SW (7 << DAC_CR_TSEL2_SHIFT) /* Software trigger */ +#define DAC_CR_WAVE2_SHIFT (22) /* Bit 22-23: DAC channel2 noise/triangle wave generation enable */ +#define DAC_CR_WAVE2_MASK (3 << DAC_CR_WAVE2_SHIFT) +# define DAC_CR_WAVE2_DISABLED (0 << DAC_CR_WAVE2_SHIFT) /* Wave generation disabled */ +# define DAC_CR_WAVE2_NOISE (1 << DAC_CR_WAVE2_SHIFT) /* Noise wave generation enabled */ +# define DAC_CR_WAVE2_TRIANGLE (2 << DAC_CR_WAVE2_SHIFT) /* Triangle wave generation enabled */ +#define DAC_CR_MAMP2_SHIFT (24) /* Bit 24-27: DAC channel2 mask/amplitude selector */ +#define DAC_CR_MAMP2_MASK (15 << DAC_CR_MAMP2_SHIFT) +# define DAC_CR_MAMP2_AMP1 (0 << DAC_CR_MAMP2_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */ +# define DAC_CR_MAMP2_AMP3 (1 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[1:0] of LFSR/triangle amplitude=3 */ +# define DAC_CR_MAMP2_AMP7 (2 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[2:0] of LFSR/triangle amplitude=7 */ +# define DAC_CR_MAMP2_AMP15 (3 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[3:0] of LFSR/triangle amplitude=15 */ +# define DAC_CR_MAMP2_AMP31 (4 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[4:0] of LFSR/triangle amplitude=31 */ +# define DAC_CR_MAMP2_AMP63 (5 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[5:0] of LFSR/triangle amplitude=63 */ +# define DAC_CR_MAMP2_AMP127 (6 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[6:0] of LFSR/triangle amplitude=127 */ +# define DAC_CR_MAMP2_AMP255 (7 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[7:0] of LFSR/triangle amplitude=255 */ +# define DAC_CR_MAMP2_AMP511 (8 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[8:0] of LFSR/triangle amplitude=511 */ +# define DAC_CR_MAMP2_AMP1023 (9 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[9:0] of LFSR/triangle amplitude=1023 */ +# define DAC_CR_MAMP2_AMP2047 (10 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[10:0] of LFSR/triangle amplitude=2047 */ +# define DAC_CR_MAMP2_AMP4095 (11 << DAC_CR_MAMP2_SHIFT) /* Unmask bits[11:0] of LFSR/triangle amplitude=4095 */ +#define DAC_CR_DMAEN2 (1 << 28) /* Bit 28: DAC channel2 DMA enable */ +#define DAC_CR_DMAUDRIE2 (1 << 29) /* Bits 29: DAC channel2 DMA underrun interrupt enable */ + +/* DAC software trigger register */ + +#define DAC_SWTRIGR_SWTRIG(n) (1 << ((n)-1)) +#define DAC_SWTRIGR_SWTRIG1 (1 << 0) /* Bit 0: DAC channel1 software trigger */ +#define DAC_SWTRIGR_SWTRIG2 (1 << 1) /* Bit 1: DAC channel2 software trigger */ + +/* DAC channel1/2 12-bit right-aligned data holding register */ + +#define DAC_DHR12R_MASK (0x0fff) + +/* DAC channel1/2 12-bit left aligned data holding register */ + +#define DAC_DHR12L_MASK (0xfff0) + +/* DAC channel1/2 8-bit right aligned data holding register */ + +#define DAC_DHR8R_MASK (0x00ff) + +/* Dual DAC 12-bit right-aligned data holding register */ + +#define DAC_DHR12RD_DACC_SHIFT(n) (1 << (((n)-1) << 4)) +#define DAC_DHR12RD_DACC_MASK(n) (0xfff << DAC_DHR12RD_DACC_SHIFT(n)) + +#define DAC_DHR12RD_DACC1_SHIFT (0) /* Bits 0-11: DAC channel1 12-bit right-aligned data */ +#define DAC_DHR12RD_DACC1_MASK (0xfff << DAC_DHR12RD_DACC2_SHIFT) +#define DAC_DHR12RD_DACC2_SHIFT (16) /* Bits 16-27: DAC channel2 12-bit right-aligned data */ +#define DAC_DHR12RD_DACC2_MASK (0xfff << DAC_DHR12RD_DACC2_SHIFT) + +/* Dual DAC 12-bit left-aligned data holding register */ + +#define DAC_DHR12LD_DACC_SHIFT(n) ((1 << (((n)-1) << 4)) + 4) +#define DAC_DHR12LD_DACC_MASK(n) (0xfff << DAC_DHR12LD_DACC_SHIFT(n)) + +#define DAC_DHR12LD_DACC1_SHIFT (4) /* Bits 4-15: DAC channel1 12-bit left-aligned data */ +#define DAC_DHR12LD_DACC1_MASK (0xfff << DAC_DHR12LD_DACC1_SHIFT) +#define DAC_DHR12LD_DACC2_SHIFT (20) /* Bits 20-31: DAC channel2 12-bit left-aligned data */ +#define DAC_DHR12LD_DACC2_MASK (0xfff << DAC_DHR12LD_DACC2_SHIFT) + +/* DUAL DAC 8-bit right aligned data holding register */ + +#define DAC_DHR8RD_DACC_SHIFT(n) (1 << (((n)-1) << 3)) +#define DAC_DHR8RD_DACC_MASK(n) (0xff << DAC_DHR8RD_DACC_SHIFT(n)) + +#define DAC_DHR8RD_DACC1_SHIFT (0) /* Bits 0-7: DAC channel1 8-bit right-aligned data */ +#define DAC_DHR8RD_DACC1_MASK (0xff << DAC_DHR8RD_DACC1_SHIFT) +#define DAC_DHR8RD_DACC2_SHIFT (8) /* Bits 8-15: DAC channel2 8-bit right-aligned data */ +#define DAC_DHR8RD_DACC2_MASK (0xff << DAC_DHR8RD_DACC2_SHIFT) + +/* DAC channel1/2 data output register */ + +#define DAC_DOR_MASK (0x0fff) + +/* DAC status register */ + +#define DAC_SR_DMAUDR(n) ((1 << (((n)-1) << 4)) + 13) +#define DAC_SR_DMAUDR1 (1 << 13) /* Bit 13: DAC channel1 DMA underrun flag */ +#define DAC_SR_DMAUDR2 (1 << 29) /* Bit 29: DAC channel2 DMA underrun flag */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_DAC_H */ diff --git a/arch/arm/src/stm32/chip/stm32_dbgmcu.h b/arch/arm/src/stm32/chip/stm32_dbgmcu.h new file mode 100644 index 0000000000000000000000000000000000000000..dc22cd2e7be0630e3c62150d0f8aa7793f2abf39 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_dbgmcu.h @@ -0,0 +1,169 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_dbgmcu.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_DBGMCU_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_DBGMCU_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Addresses *******************************************************************************/ + +#define STM32_DBGMCU_IDCODE 0xe0042000 /* MCU identifier */ +#define STM32_DBGMCU_CR 0xe0042004 /* MCU debug */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define STM32_DBGMCU_APB1_FZ 0xe0042008 /* Debug MCU APB1 freeze register */ +# define STM32_DBGMCU_APB2_FZ 0xe004200c /* Debug MCU APB2 freeze register */ +#endif + +/* Register Bitfield Definitions ********************************************************************/ + +/* MCU identifier */ + +#define DBGMCU_IDCODE_DEVID_SHIFT (0) /* Bits 11-0: Device Identifier */ +#define DBGMCU_IDCODE_DEVID_MASK (0x0fff << DBGMCU_IDCODE_DEVID_SHIFT) +#define DBGMCU_IDCODE_REVID_SHIFT (16) /* Bits 31-16: Revision Identifier */ +#define DBGMCU_IDCODE_REVID_MASK (0xffff << DBGMCU_IDCODE_REVID_SHIFT) + +/* MCU debug */ + +#define DBGMCU_CR_SLEEP (1 << 0) /* Bit 0: Debug Sleep Mode */ +#define DBGMCU_CR_STOP (1 << 1) /* Bit 1: Debug Stop Mode */ +#define DBGMCU_CR_STANDBY (1 << 2) /* Bit 2: Debug Standby mode */ +#define DBGMCU_CR_TRACEIOEN (1 << 5) /* Bit 5: Trace enabled */ + +#define DBGMCU_CR_TRACEMODE_SHIFT (6) /* Bits 7-6: Trace mode pin assignement */ +#define DBGMCU_CR_TRACEMODE_MASK (3 << DBGMCU_CR_TRACEMODE_SHIFT) +# define DBGMCU_CR_ASYNCH (0 << DBGMCU_CR_TRACEMODE_SHIFT) /* Asynchronous Mode */ +# define DBGMCU_CR_SYNCH1 (1 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=1 */ +# define DBGMCU_CR_SYNCH2 (2 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=2 */ +# define DBGMCU_CR_SYNCH4 (3 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=4 */ + +#ifdef CONFIG_STM32_STM32F10XX +# define DBGMCU_CR_IWDGSTOP (1 << 8) /* Bit 8: Independent Watchdog stopped when core is halted */ +# define DBGMCU_CR_WWDGSTOP (1 << 9) /* Bit 9: Window Watchdog stopped when core is halted */ +# define DBGMCU_CR_TIM1STOP (1 << 10) /* Bit 10: TIM1 stopped when core is halted */ +# define DBGMCU_CR_TIM2STOP (1 << 11) /* Bit 11: TIM2 stopped when core is halted */ +# define DBGMCU_CR_TIM3STOP (1 << 12) /* Bit 12: TIM3 stopped when core is halted */ +# define DBGMCU_CR_TIM4STOP (1 << 13) /* Bit 13: TIM4 stopped when core is halted */ +# define DBGMCU_CR_CAN1STOP (1 << 14) /* Bit 14: CAN1 stopped when core is halted */ +# define DBGMCU_CR_SMBUS1STOP (1 << 15) /* Bit 15: I2C1 SMBUS timeout mode stopped when core is halted */ +# define DBGMCU_CR_SMBUS2STOP (1 << 16) /* Bit 16: I2C2 SMBUS timeout mode stopped when core is halted */ +# define DBGMCU_CR_TIM8STOP (1 << 17) /* Bit 17: TIM8 stopped when core is halted */ +# define DBGMCU_CR_TIM5STOP (1 << 18) /* Bit 18: TIM5 stopped when core is halted */ +# define DBGMCU_CR_TIM6STOP (1 << 19) /* Bit 19: TIM6 stopped when core is halted */ +# define DBGMCU_CR_TIM7STOP (1 << 20) /* Bit 20: TIM7 stopped when core is halted */ +# define DBGMCU_CR_CAN2STOP (1 << 21) /* Bit 21: CAN2 stopped when core is halted */ +#endif + +/* Debug MCU APB1 freeze register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define DBGMCU_APB1_TIM2STOP (1 << 0) /* Bit 0: TIM2 stopped when core is halted */ +# define DBGMCU_APB1_TIM3STOP (1 << 1) /* Bit 1: TIM3 stopped when core is halted */ +# define DBGMCU_APB1_TIM4STOP (1 << 2) /* Bit 2: TIM4 stopped when core is halted */ +# define DBGMCU_APB1_TIM5STOP (1 << 3) /* Bit 3: TIM5 stopped when core is halted */ +# define DBGMCU_APB1_TIM6STOP (1 << 4) /* Bit 4: TIM6 stopped when core is halted */ +# define DBGMCU_APB1_TIM7STOP (1 << 5) /* Bit 5: TIM7 stopped when core is halted */ +# define DBGMCU_APB1_TIM12STOP (1 << 6) /* Bit 6: TIM12 stopped when core is halted */ +# define DBGMCU_APB1_TIM13STOP (1 << 7) /* Bit 7: TIM13 stopped when core is halted */ +# define DBGMCU_APB1_TIM14STOP (1 << 8) /* Bit 7: TIM14 stopped when core is halted */ +# define DBGMCU_APB1_RTCSTOP (1 << 10) /* Bit 10: RTC stopped when Core is halted */ +# define DBGMCU_APB1_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */ +# define DBGMCU_APB1_IWDGSTOP (1 << 12) /* Bit 12: Independent Watchdog stopped when core is halted */ +# define DBGMCU_APB1_I2C1STOP (1 << 21) /* Bit 21: SMBUS timeout mode stopped when Core is halted */ +# define DBGMCU_APB1_I2C2STOP (1 << 22) /* Bit 22: SMBUS timeout mode stopped when Core is halted */ +# define DBGMCU_APB1_I2C3STOP (1 << 23) /* Bit 23: SMBUS timeout mode stopped when Core is halted */ +# define DBGMCU_APB1_CAN1STOP (1 << 25) /* Bit 25: CAN1 stopped when core is halted */ +# define DBGMCU_APB1_CAN2STOP (1 << 26) /* Bit 26: CAN2 stopped when core is halted */ +#elif defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32L15XX) +# define DBGMCU_APB1_TIM2STOP (1 << 0) /* Bit 0: TIM2 stopped when core is halted */ +# define DBGMCU_APB1_TIM3STOP (1 << 1) /* Bit 1: TIM3 stopped when core is halted */ +# define DBGMCU_APB1_TIM4STOP (1 << 2) /* Bit 2: TIM4 stopped when core is halted */ +# define DBGMCU_APB1_TIM6STOP (1 << 4) /* Bit 4: TIM6 stopped when core is halted */ +# define DBGMCU_APB1_TIM7STOP (1 << 5) /* Bit 5: TIM7 stopped when core is halted */ +# define DBGMCU_APB1_RTCSTOP (1 << 10) /* Bit 10: RTC stopped when Core is halted */ +# define DBGMCU_APB1_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */ +# define DBGMCU_APB1_IWDGSTOP (1 << 12) /* Bit 12: Independent Watchdog stopped when core is halted */ +# define DBGMCU_APB1_I2C1STOP (1 << 21) /* Bit 21: SMBUS timeout mode stopped when Core is halted */ +# define DBGMCU_APB1_I2C2STOP (1 << 22) /* Bit 22: SMBUS timeout mode stopped when Core is halted */ +# if defined(CONFIG_STM32_STM32F30XX) +# define DBGMCU_APB1_CAN1STOP (1 << 25) /* Bit 25: CAN1 stopped when core is halted */ +# endif +#endif + +/* Debug MCU APB2 freeze register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define DBGMCU_APB2_TIM1STOP (1 << 0) /* Bit 0: TIM1 stopped when core is halted */ +# define DBGMCU_APB2_TIM8STOP (1 << 1) /* Bit 1: TIM8 stopped when core is halted */ +# define DBGMCU_APB2_TIM9STOP (1 << 16) /* Bit 16: TIM9 stopped when core is halted */ +# define DBGMCU_APB2_TIM10STOP (1 << 17) /* Bit 17: TIM10 stopped when core is halted */ +# define DBGMCU_APB2_TIM11STOP (1 << 18) /* Bit 18: TIM11 stopped when core is halted */ +#elif defined(CONFIG_STM32_STM32F30XX) +# define DBGMCU_APB2_TIM1STOP (1 << 0) /* Bit 0: TIM1 stopped when core is halted */ +# define DBGMCU_APB2_TIM8STOP (1 << 1) /* Bit 1: TIM8 stopped when core is halted */ +# define DBGMCU_APB2_TIM15STOP (1 << 2) /* Bit 2: TIM15 stopped when core is halted */ +# define DBGMCU_APB2_TIM16STOP (1 << 3) /* Bit 3: TIM16 stopped when core is halted */ +# define DBGMCU_APB2_TIM17STOP (1 << 4) /* Bit 4: TIM17 stopped when core is halted */ +#elif defined(CONFIG_STM32_STM32L15XX) +# define DBGMCU_APB2_TIM9STOP (1 << 2) /* Bit 2: TIM9 stopped when core is halted */ +# define DBGMCU_APB2_TIM10STOP (1 << 3) /* Bit 3: TIM10 stopped when core is halted */ +# define DBGMCU_APB2_TIM11STOP (1 << 4) /* Bit 4: TIM11 stopped when core is halted */ +#endif + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_DBGMCU_H */ diff --git a/arch/arm/src/stm32/chip/stm32_dma2d.h b/arch/arm/src/stm32/chip/stm32_dma2d.h new file mode 100644 index 0000000000000000000000000000000000000000..7a44561a1dbf0a48e3c295f57bb3f0c4afe88c83 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_dma2d.h @@ -0,0 +1,230 @@ +/**************************************************************************** + * arch/arm/src/stm32/chip/stm32_dma2d.h + * + * Copyright (C) 2014-2015 Marco Krahl. All rights reserved. + * Author: Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/stm32_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_DMA2D_NCLUT 256 /* Number of entries in the CLUT */ + +/* DMA2D Register Offsets ****************************************************/ + +#define STM32_DMA2D_CR_OFFSET 0x0000 /* DMA2D Control Register */ +#define STM32_DMA2D_ISR_OFFSET 0x0004 /* DMA2D Interrupt Status Register */ +#define STM32_DMA2D_IFCR_OFFSET 0x0008 /* DMA2D Interrupt Flag Clear Register */ +#define STM32_DMA2D_FGMAR_OFFSET 0x000C /* DMA2D Foreground Memory Address Register */ +#define STM32_DMA2D_FGOR_OFFSET 0x0010 /* DMA2D Foreground Offset Register */ +#define STM32_DMA2D_BGMAR_OFFSET 0x0014 /* DMA2D Background Memory Address Register */ +#define STM32_DMA2D_BGOR_OFFSET 0x0018 /* DMA2D Background Offset Register */ +#define STM32_DMA2D_FGPFCCR_OFFSET 0x001C /* DMA2D Foreground PFC Control Register */ +#define STM32_DMA2D_FGCOLR_OFFSET 0x0020 /* DMA2D Foreground Color Register */ +#define STM32_DMA2D_BGPFCCR_OFFSET 0x0024 /* DMA2D Background PFC Control Register */ +#define STM32_DMA2D_BGCOLR_OFFSET 0x0028 /* DMA2D Background Color Register */ +#define STM32_DMA2D_FGCMAR_OFFSET 0x002C /* DMA2D Foreground CLUT Memory Address Register */ +#define STM32_DMA2D_BGCMAR_OFFSET 0x0030 /* DMA2D Background CLUT Memory Address Register */ +#define STM32_DMA2D_OPFCCR_OFFSET 0x0034 /* DMA2D Output PFC Control Register */ +#define STM32_DMA2D_OCOLR_OFFSET 0x0038 /* DMA2D Output Color Register */ +#define STM32_DMA2D_OMAR_OFFSET 0x003C /* DMA2D Output Memory Address Register */ +#define STM32_DMA2D_OOR_OFFSET 0x0040 /* DMA2D Output Offset Register */ +#define STM32_DMA2D_NLR_OFFSET 0x0044 /* DMA2D Number Of Line Register */ +#define STM32_DMA2D_LWR_OFFSET 0x0048 /* DMA2D Line Watermark Register */ +#define STM32_DMA2D_AMTCR_OFFSET 0x004C /* DMA2D AHB Master Time Configuration Register */ + +/* DMA2D Register Addresses **************************************************/ + +#define STM32_DMA2D_CR (STM32_DMA2D_BASE+STM32_DMA2D_CR_OFFSET) +#define STM32_DMA2D_ISR (STM32_DMA2D_BASE+STM32_DMA2D_ISR_OFFSET) +#define STM32_DMA2D_IFCR (STM32_DMA2D_BASE+STM32_DMA2D_IFCR_OFFSET) +#define STM32_DMA2D_FGMAR (STM32_DMA2D_BASE+STM32_DMA2D_FGMAR_OFFSET) +#define STM32_DMA2D_FGOR (STM32_DMA2D_BASE+STM32_DMA2D_FGOR_OFFSET) +#define STM32_DMA2D_BGMAR (STM32_DMA2D_BASE+STM32_DMA2D_BGMAR_OFFSET) +#define STM32_DMA2D_BGOR (STM32_DMA2D_BASE+STM32_DMA2D_BGOR_OFFSET) +#define STM32_DMA2D_FGPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_FGPFCCR_OFFSET) +#define STM32_DMA2D_FGCOLR (STM32_DMA2D_BASE+STM32_DMA2D_FGCOLR_OFFSET) +#define STM32_DMA2D_BGPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_BGPFCCR_OFFSET) +#define STM32_DMA2D_BGCOLR (STM32_DMA2D_BASE+STM32_DMA2D_BGCOLR_OFFSET) +#define STM32_DMA2D_FGCMAR (STM32_DMA2D_BASE+STM32_DMA2D_FGCMAR_OFFSET) +#define STM32_DMA2D_BGCMAR (STM32_DMA2D_BASE+STM32_DMA2D_BGCMAR_OFFSET) +#define STM32_DMA2D_OPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_OPFCCR_OFFSET) +#define STM32_DMA2D_OCOLR (STM32_DMA2D_BASE+STM32_DMA2D_OCOLR_OFFSET) +#define STM32_DMA2D_OMAR (STM32_DMA2D_BASE+STM32_DMA2D_OMAR_OFFSET) +#define STM32_DMA2D_OOR (STM32_DMA2D_BASE+STM32_DMA2D_OOR_OFFSET) +#define STM32_DMA2D_NLR (STM32_DMA2D_BASE+STM32_DMA2D_NLR_OFFSET) +#define STM32_DMA2D_LWR (STM32_DMA2D_BASE+STM32_DMA2D_LWR_OFFSET) + +/* DMA2D Register Bit Definitions ********************************************/ + +/* DMA2D Control Register */ + +#define DMA2D_CR_START (1 << 0) /* Start Bit */ +#define DMA2D_CR_SUSP (1 << 1) /* Suspend Bit */ +#define DMA2D_CR_ABORT (1 << 2) /* Abort Bit */ +#define DMA2D_CR_TEIE (1 << 8) /* Transfer Error Interupt Enable Bit */ +#define DMA2D_CR_TCIE (1 << 9) /* Transfer Complete Interrupt Enable Bit */ +#define DMA2D_CR_TWIE (1 << 10) /* Transfer Watermark Interrupt Enable Bit */ +#define DMA2D_CR_CAEIE (1 << 11) /* CLUT Access Error Interrupt Enable Bit */ +#define DMA2D_CR_CTCIE (1 << 12) /* CLUT Transfer Complete Interrupt Enable Bit */ +#define DMA2D_CR_CEIE (1 << 13) /* Configuration Error Interrupt Enable Bit */ +#define DMA2D_CR_MODE_SHIFT (16) /* Bits 16-17 DMA2D mode Bits */ +#define DMA2D_CR_MODE_MASK (3 << DMA2D_CR_MODE_SHIFT) +#define DMA2D_CR_MODE(n) ((uint32_t)(n) << DMA2D_CR_MODE_SHIFT) + +/* DMA2D Interrupt Status Register */ + +#define DMA2D_ISR_TEIF (1 << 0) /* Transfer error interrupt flag */ +#define DMA2D_ISR_TCIF (1 << 1) /* Transfer Complete Interrupt flag */ +#define DMA2D_ISR_TWIF (1 << 2) /* Transfer Watermark Interrupt flag */ +#define DMA2D_ISR_CAEIF (1 << 3) /* CLUT Access Error Interrupt flag */ +#define DMA2D_ISR_CTCIF (1 << 4) /* CLUT Transfer Complete Interrupt flag */ +#define DMA2D_ISR_CEIF (1 << 5) /* Configuration Error Interrupt flag */ + +/* DMA2D Interrupt Flag Clear Register */ + +#define DMA2D_IFCR_CTEIF (1 << 0) /* Clear Transfer Interrupt Flag */ +#define DMA2D_IFCR_CTCIF (1 << 1) /* Clear Transfer Complete Interrupt Flag */ +#define DMA2D_IFCR_CTWIF (1 << 2) /* Clear Transfer Watermark Interrupt Flag */ +#define DMA2D_IFCR_CAECIF (1 << 3) /* Clear CLUT Access Error Interrupt Flag */ +#define DMA2D_IFCR_CCTCIF (1 << 4) /* Clear CLUT Transfer Complete Interrupt Flag */ +#define DMA2D_IFCR_CCEIF (1 << 5) /* Clear Configuration Error Interrupt Flag */ + +/* DMA2D Foreground Memory Access Register */ + +/* DMA2D Background Memory Access Register */ + +/* DMA2D Foreground/Background Offset Register */ + +#define DMA2D_xGOR_SHIFT (0) /* Bits 0-13 Line Offset */ +#define DMA2D_xGOR_MASK (0x3FFF << DMA2D_xGOR_SHIFT) +#define DMA2D_xGOR(n) ((uint32_t)(n) << DMA2D_xGOR_SHIFT) + +/* DMA2D Foreground/Background PFC Control Register */ + +#define DMA2D_xGPFCCR_CM_SHIFT (0) /* Bits 0-3 Color Mode */ +#define DMA2D_xGPFCCR_CM_MASK (0xF << DMA2D_xGPFCCR_CM_SHIFT) +#define DMA2D_xGPFCCR_CM(n) ((uint32_t)(n) << DMA2D_xGPFCCR_CM_SHIFT) +#define DMA2D_xGPFCCR_CCM (1 << 4) /* CLUT Color Mode */ +#define DMA2D_xGPFCCR_START (1 << 5) /* Start */ +#define DMA2D_xGPFCCR_CS_SHIFT (8) /* Bits 8-15 CLUT Size */ +#define DMA2D_xGPFCCR_CS_MASK (0xFF << DMA2D_xGPFCCR_CS_SHIFT) +#define DMA2D_xGPFCCR_CS(n) ((uint32_t)(n) << DMA2D_xGPFCCR_CS_SHIFT) +#define DMA2D_xGPFCCR_AM_SHIFT (16) /* Bits 16-17 Alpha Mode */ +#define DMA2D_xGPFCCR_AM_MASK (3 << DMA2D_xGPFCCR_AM_SHIFT) +#define DMA2D_xGPFCCR_AM(n) ((uint32_t)(n) << DMA2D_xGPFCCR_AM_SHIFT) +#define DMA2D_xGPFCCR_ALPHA_SHIFT (24) /* Bits 24-31 Alpha Value */ +#define DMA2D_xGPFCCR_ALPHA_MASK (0xFF << DMA2D_xGPFCCR_ALPHA_SHIFT) +#define DMA2D_xGPFCCR_ALPHA(n) ((uint32_t)(n) << DMA2D_xGPFCCR_ALPHA_SHIFT) + +/* DMA2D Foreground/Background Color Register */ + +#define DMA2D_xGCOLR_BLUE_SHIFT (0) /* Bits 0-7 Blue Value */ +#define DMA2D_xGCOLR_BLUE_MASK (0xFF << DMA2D_xGCOLR_BLUE_SHIFT) +#define DMA2D_xGCOLR_BLUE(n) ((uint32_t)(n) << DMA2D_xGCOLR_BLUE_SHIFT) +#define DMA2D_xGCOLR_GREEN_SHIFT (8) /* Bits 8-15 Green Value */ +#define DMA2D_xGCOLR_GREEN_MASK (0xFF << DMA2D_xGCOLR_GREEN_SHIFT) +#define DMA2D_xGCOLR_GREEN(n) ((uint32_t)(n) << DMA2D_xGCOLR_GREEN_SHIFT) +#define DMA2D_xGCOLR_RED_SHIFT (16) /* Bits 16-23 Red Value */ +#define DMA2D_xGCOLR_RED_MASK (0xFF << DMA2D_xGCOLR_RED_SHIFT) +#define DMA2D_xGCOLR_RED(n) ((uint32_t)(n) << DMA2D_xGCOLR_RED_SHIFT) + +/* DMA2D Foreground CLUT Memory Address Register */ + +/* DMA2D Background CLUT Memory Address Register */ + +/* DMA2D Output PFC Control Register */ + +#define DMA2D_OPFCCR_CM_SHIFT (0) /* Bits 0-2 Color Mode */ +#define DMA2D_OPFCCR_CM_MASK (7 << DMA2D_OPFCCR_CM_SHIFT) +#define DMA2D_OPFCCR_CM(n) ((uint32_t)(n) << DMA2D_OPFCCR_CM_SHIFT) + +/* DMA2D Output Color Register */ + +#define DMA2D_OCOLR_BLUE_SHIFT (0) /* Bits 0-7 Blue Value */ +#define DMA2D_OCOLR_BLUE_MASK (0xFF << DMA2D_OCOLR_BLUE_SHIFT) +#define DMA2D_OCOLR_BLUE(n) ((uint32_t)(n) << DMA2D_OCOLR_BLUE_SHIFT) +#define DMA2D_OCOLR_GREEN_SHIFT (8) /* Bits 8-15 Green Value */ +#define DMA2D_OCOLR_GREEN_MASK (0xFF << DMA2D_OCOLR_GREEN_SHIFT) +#define DMA2D_OCOLR_GREEN(n) ((uint32_t)(n) << DMA2D_OCOLR_GREEN_SHIFT) +#define DMA2D_OCOLR_RED_SHIFT (16) /* Bits 16-23 Red Value */ +#define DMA2D_OCOLR_RED_MASK (0xFF << DMA2D_OCOLR_RED_SHIFT) +#define DMA2D_OCOLR_RED(n) ((uint32_t)(n) << DMA2D_OCOLR_RED_SHIFT) +#define DMA2D_OCOLR_ALPHA_SHIFT (24) /* Bits 24-31 Alpha Value */ +#define DMA2D_OCOLR_ALPHA_MASK (0xFF << DMA2D_OCOLR_ALPHA_SHIFT) +#define DMA2D_OCOLR_ALPHA(n) ((uint32_t)(n) << DMA2D_OCOLR_ALPHA_SHIFT) + +/* DMA2D Output Memory Address Register */ + +/* DMA2D Output Offset Register */ + +#define DMA2D_OOR_LO_SHIFT (0) /* Bits 0-13 Line Offset */ +#define DMA2D_OOR_LO_MASK (0x3FFF << DMA2D_OOR_LO_SHIFT) +#define DMA2D_OOR_LO(n) ((uint32_t)(n) << DMA2D_OOR_LO_SHIFT) + +/* DMA2D Number Of Line Register */ + +#define DMA2D_NLR_NL_SHIFT (0) /* Bits 0-15 Number Of Lines */ +#define DMA2D_NLR_NL_MASK (0xFFFF << DMA2D_NLR_NL_SHIFT) +#define DMA2D_NLR_NL(n) ((uint32_t)(n) << DMA2D_NLR_NL_SHIFT) +#define DMA2D_NLR_PL_SHIFT (16) /* Bits 16-29 Pixel per Lines */ +#define DMA2D_NLR_PL_MASK (0x3FFF << DMA2D_NLR_PL_SHIFT) +#define DMA2D_NLR_PL(n) ((uint32_t)(n) << DMA2D_NLR_PL_SHIFT) + +/* DMA2D Line Watermark Register */ + +#define DMA2D_LWR_LW_SHIFT (0) /* Bits 0-15 Line Watermark */ +#define DMA2D_LWR_LW_MASK (0xFFFF << DMA2D_LWR_LW_SHIFT) +#define DMA2D_LWR_LW(n) ((uint32_t)(n) << DMA2D_LWR_LW_SHIFT) + +/* DMA2D AHB Master Timer Configuration Register */ + +#define DMA2D_AMTCR_EN (1 << 0) /* Enable */ +#define DMA2D_AMTCR_DT_SHIFT (0) /* Bits 8-15 Dead Time */ +#define DMA2D_AMTCR_DT_MASK (0xFF << DMA2D_AMTCR_DT_SHIFT) +#define DMA2D_AMTCR_DT(n) ((uint32_t)(n) << DMA2D_AMTCR_DT_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H */ diff --git a/arch/arm/src/stm32/chip/stm32_eth.h b/arch/arm/src/stm32/chip/stm32_eth.h new file mode 100644 index 0000000000000000000000000000000000000000..ac078aacbee4b337492ab6941d70d998932ee71a --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_eth.h @@ -0,0 +1,841 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_eth.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_ETH_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_ETH_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +#if STM32_NETHERNET > 0 + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ +/* MAC Registers */ + +#define STM32_ETH_MACCR_OFFSET 0x0000 /* Ethernet MAC configuration register */ +#define STM32_ETH_MACFFR_OFFSET 0x0004 /* Ethernet MAC frame filter register */ +#define STM32_ETH_MACHTHR_OFFSET 0x0008 /* Ethernet MAC hash table high register */ +#define STM32_ETH_MACHTLR_OFFSET 0x000c /* Ethernet MAC hash table low register */ +#define STM32_ETH_MACMIIAR_OFFSET 0x0010 /* Ethernet MAC MII address register */ +#define STM32_ETH_MACMIIDR_OFFSET 0x0014 /* Ethernet MAC MII data register */ +#define STM32_ETH_MACFCR_OFFSET 0x0018 /* Ethernet MAC flow control register */ +#define STM32_ETH_MACVLANTR_OFFSET 0x001c /* Ethernet MAC VLAN tag register */ +#define STM32_ETH_MACRWUFFR_OFFSET 0x0028 /* Ethernet MAC remote wakeup frame filter reg */ +#define STM32_ETH_MACPMTCSR_OFFSET 0x002c /* Ethernet MAC PMT control and status register */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_ETH_MACDBGR_OFFSET 0x0034 /* Ethernet MAC debug register */ +#endif +#define STM32_ETH_MACSR_OFFSET 0x0038 /* Ethernet MAC interrupt status register */ +#define STM32_ETH_MACIMR_OFFSET 0x003c /* Ethernet MAC interrupt mask register */ +#define STM32_ETH_MACA0HR_OFFSET 0x0040 /* Ethernet MAC address 0 high register */ +#define STM32_ETH_MACA0LR_OFFSET 0x0044 /* Ethernet MAC address 0 low register */ +#define STM32_ETH_MACA1HR_OFFSET 0x0048 /* Ethernet MAC address 1 high register */ +#define STM32_ETH_MACA1LR_OFFSET 0x004c /* Ethernet MAC address1 low register */ +#define STM32_ETH_MACA2HR_OFFSET 0x0050 /* Ethernet MAC address 2 high register */ +#define STM32_ETH_MACA2LR_OFFSET 0x0054 /* Ethernet MAC address 2 low register */ +#define STM32_ETH_MACA3HR_OFFSET 0x0058 /* Ethernet MAC address 3 high register */ +#define STM32_ETH_MACA3LR_OFFSET 0x005c /* Ethernet MAC address 3 low register */ + +/* MMC Registers */ + +#define STM32_ETH_MMCCR_OFFSET 0x0100 /* Ethernet MMC control register */ +#define STM32_ETH_MMCRIR_OFFSET 0x0104 /* Ethernet MMC receive interrupt register */ +#define STM32_ETH_MMCTIR_OFFSET 0x0108 /* Ethernet MMC transmit interrupt register */ +#define STM32_ETH_MMCRIMR_OFFSET 0x010c /* Ethernet MMC receive interrupt mask register */ +#define STM32_ETH_MMCTIMR_OFFSET 0x0110 /* Ethernet MMC transmit interrupt mask register */ +#define STM32_ETH_MMCTGFSCCR_OFFSET 0x014c /* Ethernet MMC transmitted good frames counter register (single collision) */ +#define STM32_ETH_MMCTGFMSCCR_OFFSET 0x0150 /* Ethernet MMC transmitted good frames counter register (multiple-collision) */ +#define STM32_ETH_MMCTGFCR_OFFSET 0x0168 /* Ethernet MMC transmitted good frames counter register */ +#define STM32_ETH_MMCRFCECR_OFFSET 0x0194 /* Ethernet MMC received frames with CRC error counter register */ +#define STM32_ETH_MMCRFAECR_OFFSET 0x0198 /* Ethernet MMC received frames with alignment error counter */ +#define STM32_ETH_MMCRGUFCR_OFFSET 0x01c4 /* MMC received good unicast frames counter register */ + +/* IEEE 1588 time stamp registers */ + +#define STM32_ETH_PTPTSCR_OFFSET 0x0700 /* Ethernet PTP time stamp control register */ +#define STM32_ETH_PTPSSIR_OFFSET 0x0704 /* Ethernet PTP subsecond increment register */ +#define STM32_ETH_PTPTSHR_OFFSET 0x0708 /* Ethernet PTP time stamp high register */ +#define STM32_ETH_PTPTSLR_OFFSET 0x070c /* Ethernet PTP time stamp low register */ +#define STM32_ETH_PTPTSHUR_OFFSET 0x0710 /* Ethernet PTP time stamp high update register */ +#define STM32_ETH_PTPTSLUR_OFFSET 0x0714 /* Ethernet PTP time stamp low update register */ +#define STM32_ETH_PTPTSAR_OFFSET 0x0718 /* Ethernet PTP time stamp addend register */ +#define STM32_ETH_PTPTTHR_OFFSET 0x071c /* Ethernet PTP target time high register */ +#define STM32_ETH_PTPTTLR_OFFSET 0x0720 /* Ethernet PTP target time low register */ +#define STM32_ETH_PTPTSSR_OFFSET 0x0728 /* Ethernet PTP time stamp status register */ +#define STM32_ETH_PTPPPSCR_OFFSET 0x072c /* Ethernet PTP PPS control register */ + +/* DMA Registers */ + +#define STM32_ETH_DMABMR_OFFSET 0x1000 /* Ethernet DMA bus mode register */ +#define STM32_ETH_DMATPDR_OFFSET 0x1004 /* Ethernet DMA transmit poll demand register */ +#define STM32_ETH_DMARPDR_OFFSET 0x1008 /* Ethernet DMA receive poll demand register */ +#define STM32_ETH_DMARDLAR_OFFSET 0x100c /* Ethernet DMA receive descriptor list address register */ +#define STM32_ETH_DMATDLAR_OFFSET 0x1010 /* Ethernet DMA transmit descriptor list address register */ +#define STM32_ETH_DMASR_OFFSET 0x1014 /* Ethernet DMA status register */ +#define STM32_ETH_DMAOMR_OFFSET 0x1018 /* Ethernet DMA operation mode register */ +#define STM32_ETH_DMAIER_OFFSET 0x101c /* Ethernet DMA interrupt enable register */ +#define STM32_ETH_DMAMFBOC_OFFSET 0x1020 /* Ethernet DMA missed frame and buffer overflow counter register */ +#define STM32_ETH_DMARSWTR_OFFSET 0x1024 /* Ethernet DMA receive status watchdog timer register */ +#define STM32_ETH_DMACHTDR_OFFSET 0x1048 /* Ethernet DMA current host transmit descriptor register */ +#define STM32_ETH_DMACHRDR_OFFSET 0x104c /* Ethernet DMA current host receive descriptor register */ +#define STM32_ETH_DMACHTBAR_OFFSET 0x1050 /* Ethernet DMA current host transmit buffer address register */ +#define STM32_ETH_DMACHRBAR_OFFSET 0x1054 /* Ethernet DMA current host receive buffer address register */ + +/* Register Base Addresses **************************************************************************/ +/* MAC Registers */ + +#define STM32_ETH_MACCR (STM32_ETHERNET_BASE+STM32_ETH_MACCR_OFFSET) +#define STM32_ETH_MACFFR (STM32_ETHERNET_BASE+STM32_ETH_MACFFR_OFFSET) +#define STM32_ETH_MACHTHR (STM32_ETHERNET_BASE+STM32_ETH_MACHTHR_OFFSET) +#define STM32_ETH_MACHTLR (STM32_ETHERNET_BASE+STM32_ETH_MACHTLR_OFFSET) +#define STM32_ETH_MACMIIAR (STM32_ETHERNET_BASE+STM32_ETH_MACMIIAR_OFFSET) +#define STM32_ETH_MACMIIDR (STM32_ETHERNET_BASE+STM32_ETH_MACMIIDR_OFFSET) +#define STM32_ETH_MACFCR (STM32_ETHERNET_BASE+STM32_ETH_MACFCR_OFFSET) +#define STM32_ETH_MACVLANTR (STM32_ETHERNET_BASE+STM32_ETH_MACVLANTR_OFFSET) +#define STM32_ETH_MACRWUFFR (STM32_ETHERNET_BASE+STM32_ETH_MACRWUFFR_OFFSET) +#define STM32_ETH_MACPMTCSR (STM32_ETHERNET_BASE+STM32_ETH_MACPMTCSR_OFFSET) +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_ETH_MACDBGR (STM32_ETHERNET_BASE+STM32_ETH_MACDBGR_OFFSET) +#endif +#define STM32_ETH_MACSR (STM32_ETHERNET_BASE+STM32_ETH_MACSR_OFFSET) +#define STM32_ETH_MACIMR (STM32_ETHERNET_BASE+STM32_ETH_MACIMR_OFFSET) +#define STM32_ETH_MACA0HR (STM32_ETHERNET_BASE+STM32_ETH_MACA0HR_OFFSET) +#define STM32_ETH_MACA0LR (STM32_ETHERNET_BASE+STM32_ETH_MACA0LR_OFFSET) +#define STM32_ETH_MACA1HR (STM32_ETHERNET_BASE+STM32_ETH_MACA1HR_OFFSET) +#define STM32_ETH_MACA1LR (STM32_ETHERNET_BASE+STM32_ETH_MACA1LR_OFFSET) +#define STM32_ETH_MACA2HR (STM32_ETHERNET_BASE+STM32_ETH_MACA2HR_OFFSET) +#define STM32_ETH_MACA2LR (STM32_ETHERNET_BASE+STM32_ETH_MACA2LR_OFFSET) +#define STM32_ETH_MACA3HR (STM32_ETHERNET_BASE+STM32_ETH_MACA3HR_OFFSET) +#define STM32_ETH_MACA3LR (STM32_ETHERNET_BASE+STM32_ETH_MACA3LR_OFFSET) + +/* MMC Registers */ + +#define STM32_ETH_MMCC (STM32_ETHERNET_BASE+STM32_ETH_MMCCR_OFFSET) +#define STM32_ETH_MMCRIR (STM32_ETHERNET_BASE+STM32_ETH_MMCRIR_OFFSET) +#define STM32_ETH_MMCTIR (STM32_ETHERNET_BASE+STM32_ETH_MMCTIR_OFFSET) +#define STM32_ETH_MMCRIMR (STM32_ETHERNET_BASE+STM32_ETH_MMCRIMR_OFFSET) +#define STM32_ETH_MMCTIMR (STM32_ETHERNET_BASE+STM32_ETH_MMCTIMR_OFFSET) +#define STM32_ETH_MMCTGFSCCR (STM32_ETHERNET_BASE+STM32_ETH_MMCTGFSCCR_OFFSET) +#define STM32_ETH_MMCTGFMSCCR (STM32_ETHERNET_BASE+STM32_ETH_MMCTGFMSCCR_OFFSET) +#define STM32_ETH_MMCTGFCR (STM32_ETHERNET_BASE+STM32_ETH_MMCTGFCR_OFFSET) +#define STM32_ETH_MMCRFCECR (STM32_ETHERNET_BASE+STM32_ETH_MMCRFCECR_OFFSET) +#define STM32_ETH_MMCRFAECR (STM32_ETHERNET_BASE+STM32_ETH_MMCRFAECR_OFFSET) +#define STM32_ETH_MMCRGUFCR (STM32_ETHERNET_BASE+STM32_ETH_MMCRGUFCR_OFFSET) + +/* IEEE 1588 time stamp registers */ + +#define STM32_ETH_PTPTSCR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSCR_OFFSET) +#define STM32_ETH_PTPSSIR (STM32_ETHERNET_BASE+STM32_ETH_PTPSSIR_OFFSET) +#define STM32_ETH_PTPTSHR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSHR_OFFSET) +#define STM32_ETH_PTPTSLR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSLR_OFFSET) +#define STM32_ETH_PTPTSHUR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSHUR_OFFSET) +#define STM32_ETH_PTPTSLUR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSLUR_OFFSET) +#define STM32_ETH_PTPTSAR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSAR_OFFSET) +#define STM32_ETH_PTPTTHR (STM32_ETHERNET_BASE+STM32_ETH_PTPTTHR_OFFSET) +#define STM32_ETH_PTPTTLR (STM32_ETHERNET_BASE+STM32_ETH_PTPTTLR_OFFSET) +#define STM32_ETH_PTPTSSR (STM32_ETHERNET_BASE+STM32_ETH_PTPTSSR_OFFSET) +#define STM32_ETH_PTPPPSCR (STM32_ETHERNET_BASE+STM32_ETH_PTPPPSCR_OFFSET) + +/* DMA Registers */ + +#define STM32_ETH_DMABMR (STM32_ETHERNET_BASE+STM32_ETH_DMABMR_OFFSET) +#define STM32_ETH_DMATPDR (STM32_ETHERNET_BASE+STM32_ETH_DMATPDR_OFFSET) +#define STM32_ETH_DMARPDR (STM32_ETHERNET_BASE+STM32_ETH_DMARPDR_OFFSET) +#define STM32_ETH_DMARDLAR (STM32_ETHERNET_BASE+STM32_ETH_DMARDLAR_OFFSET) +#define STM32_ETH_DMATDLAR (STM32_ETHERNET_BASE+STM32_ETH_DMATDLAR_OFFSET) +#define STM32_ETH_DMASR (STM32_ETHERNET_BASE+STM32_ETH_DMASR_OFFSET) +#define STM32_ETH_DMAOMR (STM32_ETHERNET_BASE+STM32_ETH_DMAOMR_OFFSET) +#define STM32_ETH_DMAIER (STM32_ETHERNET_BASE+STM32_ETH_DMAIER_OFFSET) +#define STM32_ETH_DMAMFBOC (STM32_ETHERNET_BASE+STM32_ETH_DMAMFBOC_OFFSET) +#define STM32_ETH_DMARSWTR (STM32_ETHERNET_BASE+STM32_ETH_DMARSWTR_OFFSET) +#define STM32_ETH_DMACHTDR (STM32_ETHERNET_BASE+STM32_ETH_DMACHTDR_OFFSET) +#define STM32_ETH_DMACHRDR (STM32_ETHERNET_BASE+STM32_ETH_DMACHRDR_OFFSET) +#define STM32_ETH_DMACHTBAR (STM32_ETHERNET_BASE+STM32_ETH_DMACHTBAR_OFFSET) +#define STM32_ETH_DMACHRBAR (STM32_ETHERNET_BASE+STM32_ETH_DMACHRBAR_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ +/* MAC Registers */ + +/* Ethernet MAC configuration register */ + +#define ETH_MACCR_RE (1 << 2) /* Bit 2: Receiver enable */ +#define ETH_MACCR_TE (1 << 3) /* Bit 3: Transmitter enable */ +#define ETH_MACCR_DC (1 << 4) /* Bit 4: Deferral check */ +#define ETH_MACCR_BL_SHIFT (5) /* Bits 5-6: Back-off limit */ +#define ETH_MACCR_BL_MASK (3 << ETH_MACCR_BL_SHIFT) +# define ETH_MACCR_BL_10 (0 << ETH_MACCR_BL_SHIFT) /* 00: k = min (n, 10) */ +# define ETH_MACCR_BL_8 (1 << ETH_MACCR_BL_SHIFT) /* 01: k = min (n, 8) */ +# define ETH_MACCR_BL_4 (2 << ETH_MACCR_BL_SHIFT) /* 10: k = min (n, 4) */ +# define ETH_MACCR_BL_1 (3 << ETH_MACCR_BL_SHIFT) /* 11: k = min (n, 1) */ +#define ETH_MACCR_APCS (1 << 7) /* Bit 7: Automatic pad/CRC stripping */ +#define ETH_MACCR_RD (1 << 9) /* Bit 9: Retry disable */ +#define ETH_MACCR_IPCO (1 << 10) /* Bit 10: IPv4 checksum offload */ +#define ETH_MACCR_DM (1 << 11) /* Bit 11: Duplex mode */ +#define ETH_MACCR_LM (1 << 12) /* Bit 12: Loopback mode */ +#define ETH_MACCR_ROD (1 << 13) /* Bit 13: Receive own disable */ +#define ETH_MACCR_FES (1 << 14) /* Bit 14: Fast Ethernet speed */ +#define ETH_MACCR_CSD (1 << 16) /* Bit 16: Carrier sense disable */ +#define ETH_MACCR_IFG_SHIFT (17) /* Bits 17-19: Interframe gap */ +#define ETH_MACCR_IFG_MASK (7 << ETH_MACCR_IFG_SHIFT) +# define ETH_MACCR_IFG(n) ((12-((n) >> 3)) << ETH_MACCR_IFG_SHIFT) /* n bit times, n=40,48,..96 */ +#define ETH_MACCR_JD (1 << 22) /* Bit 22: Jabber disable */ +#define ETH_MACCR_WD (1 << 23) /* Bit 23: Watchdog disable */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ETH_MACCR_CSTF (1 << 25) /* Bits 25: CRC stripping for Type frames */ +#endif + +/* Ethernet MAC frame filter register */ + +#define ETH_MACFFR_PM (1 << 0) /* Bit 0: Promiscuous mode */ +#define ETH_MACFFR_HU (1 << 1) /* Bit 1: Hash unicast */ +#define ETH_MACFFR_HM (1 << 2) /* Bit 2: Hash multicast */ +#define ETH_MACFFR_DAIF (1 << 3) /* Bit 3: Destination address inverse filtering */ +#define ETH_MACFFR_PAM (1 << 4) /* Bit 4: Pass all multicast */ +#define ETH_MACFFR_BFD (1 << 5) /* Bit 5: Broadcast frames disable */ +#define ETH_MACFFR_PCF_SHIFT (6) /* Bits 6-7: Pass control frames */ +#define ETH_MACFFR_PCF_MASK (3 << ETH_MACFFR_PCF_SHIFT) +# define ETH_MACFFR_PCF_NONE (0 << ETH_MACFFR_PCF_SHIFT) /* Prevents all control frames */ +# define ETH_MACFFR_PCF_PAUSE (1 << ETH_MACFFR_PCF_SHIFT) /* Prevents all except Pause control frames */ +# define ETH_MACFFR_PCF_ALL (2 << ETH_MACFFR_PCF_SHIFT) /* Forwards all control frames */ +# define ETH_MACFFR_PCF_FILTER (3 << ETH_MACFFR_PCF_SHIFT) /* Forwards all that pass address filter */ +#define ETH_MACFFR_SAIF (1 << 8) /* Bit 8: Source address inverse filtering */ +#define ETH_MACFFR_SAF (1 << 9) /* Bit 9: Source address filter */ +#define ETH_MACFFR_HPF (1 << 10) /* Bit 10: Hash or perfect filter */ +#define ETH_MACFFR_RA (1 << 31) /* Bit 31: Receive all */ + +/* Ethernet MAC hash table high/low registers (32-bit values) */ + +/* Ethernet MAC MII address register */ + +#define ETH_MACMIIAR_MB (1 << 0) /* Bit 0: MII busy */ +#define ETH_MACMIIAR_MW (1 << 1) /* Bit 1: MII write */ +#define ETH_MACMIIAR_CR_SHIFT (2) /* Bits 2-4: Clock range */ +#define ETH_MACMIIAR_CR_MASK (7 << ETH_MACMIIAR_CR_SHIFT) +#if 0 /* Per the reference manual */ +# define ETH_MACMIIAR_CR_60_100 (0 << ETH_MACMIIAR_CR_SHIFT) /* 000 60-100 MHzHCLK/42 */ +# define ETH_MACMIIAR_CR_100_168 (1 << ETH_MACMIIAR_CR_SHIFT) /* 001 100-168 MHz HCLK/62 */ +# define ETH_MACMIIAR_CR_20_35 (2 << ETH_MACMIIAR_CR_SHIFT) /* 010 20-35 MHz HCLK/16 */ +# define ETH_MACMIIAR_CR_35_60 (3 << ETH_MACMIIAR_CR_SHIFT) /* 011 35-60 MHz HCLK/26 */ +#else /* Per the driver example */ +# define ETH_MACMIIAR_CR_60_100 (0 << ETH_MACMIIAR_CR_SHIFT) /* 000 60-100 MHz HCLK/42 */ +# define ETH_MACMIIAR_CR_100_150 (1 << ETH_MACMIIAR_CR_SHIFT) /* 001 100-150 MHz HCLK/62 */ +# define ETH_MACMIIAR_CR_20_35 (2 << ETH_MACMIIAR_CR_SHIFT) /* 010 20-35 MHz HCLK/16 */ +# define ETH_MACMIIAR_CR_35_60 (3 << ETH_MACMIIAR_CR_SHIFT) /* 011 35-60 MHz HCLK/26 */ +# define ETH_MACMIIAR_CR_150_180 (4 << ETH_MACMIIAR_CR_SHIFT) /* 100 150-180 MHz HCLK/102 */ +#endif +#define ETH_MACMIIAR_MR_SHIFT (6) /* Bits 6-10: MII register */ +#define ETH_MACMIIAR_MR_MASK (31 << ETH_MACMIIAR_MR_SHIFT) +#define ETH_MACMIIAR_PA_SHIFT (11) /* Bits 11-15: PHY address */ +#define ETH_MACMIIAR_PA_MASK (31 << ETH_MACMIIAR_PA_SHIFT) + +/* Ethernet MAC MII data register */ + +#define ETH_MACMIIDR_MASK (0xffff) + +/* Ethernet MAC flow control register */ + +#define ETH_MACFCR_FCB_BPA (1 << 0) /* Bit 0: Flow control busy/back pressure activate */ +#define ETH_MACFCR_TFCE (1 << 1) /* Bit 1: Transmit flow control enable */ +#define ETH_MACFCR_RFCE (1 << 2) /* Bit 2: Receive flow control enable */ +#define ETH_MACFCR_UPFD (1 << 3) /* Bit 3: Unicast pause frame detect */ +#define ETH_MACFCR_PLT_SHIFT (4) /* Bits 4-5: Pause low threshold */ +#define ETH_MACFCR_PLT_MASK (3 << ETH_MACFCR_PLT_SHIFT) +# define ETH_MACFCR_PLT_M4 (0 << ETH_MACFCR_PLT_SHIFT) /* 00 Pause - 4 slot times */ +# define ETH_MACFCR_PLT_M28 (1 << ETH_MACFCR_PLT_SHIFT) /* 01 Pause - 28 slot times */ +# define ETH_MACFCR_PLT_M144 (2 << ETH_MACFCR_PLT_SHIFT) /* 10 Pause - 144 slot times */ +# define ETH_MACFCR_PLT_M256 (3 << ETH_MACFCR_PLT_SHIFT) /* 11 Pause -s 256 slot times */ +#define ETH_MACFCR_ZQPD (1 << 7) /* Bit 7: Zero-quanta pause disable */ +#define ETH_MACFCR_PT_SHIFT (16) /* Bits 16-31: Pause time */ +#define ETH_MACFCR_PT_MASK (0xffff << ETH_MACFCR_PT_SHIFT) + +/* Ethernet MAC VLAN tag register */ + +#define ETH_MACVLANTR_VLANTI_SHIFT (0) /* Bits 0-15: VLAN tag identifier (for receive frames) */ +#define ETH_MACVLANTR_VLANTI_MASK (0xffff << ETH_MACVLANTR_VLANTI_SHIFT) +#define ETH_MACVLANTR_VLANTC (1 << 16) /* Bit 16: 12-bit VLAN tag comparison */ + +/* Ethernet MAC remote wakeup frame filter reg. Provides 32-bit access to remote + * remote wake-up filters. + */ + +/* Ethernet MAC PMT control and status register */ + +#define ETH_MACPMTCSR_PD (1 << 0) /* Bit 0: Power down */ +#define ETH_MACPMTCSR_MPE (1 << 1) /* Bit 1: Magic Packet enable */ +#define ETH_MACPMTCSR_WFE (1 << 2) /* Bit 2: Wakeup frame enable */ +#define ETH_MACPMTCSR_MPR (1 << 5) /* Bit 5: Magic packet received */ +#define ETH_MACPMTCSR_WFR (1 << 6) /* Bit 6: Wakeup frame received */ +#define ETH_MACPMTCSR_GU (1 << 9) /* Bit 9: Global unicast */ + +/* Ethernet MAC debug register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + +#define ETH_MACDBGR_MMRPEA (1 << 0) /* Bit 0: MAC MII receive protocol engine active */ +#define ETH_MACDBGR_MSFRWCS_SHIFT (1) /* Bits 1-2: MAC small FIFO read / write controllers status */ +#define ETH_MACDBGR_MSFRWCS_MASK (3 << ETH_MACDBGR_MSFRWCS_SHIFT) +#define ETH_MACDBGR_RFWRA (1 << 4) /* Bit 4: Rx FIFO write controller active */ +#define ETH_MACDBGR_RFRCS_SHIFT (5) /* Bits 5-6: Rx FIFO read controller status */ +#define ETH_MACDBGR_RFRCS_MASK (3 << ETH_MACDBGR_RFRCS_SHIFT) +# define ETH_MACDBGR_RFRCS_IDLE (0 << ETH_MACDBGR_RFRCS_SHIFT) /* 00: IDLE state */ +# define ETH_MACDBGR_RFRCS_RFRAME (1 << ETH_MACDBGR_RFRCS_SHIFT) /* 01: Reading frame data */ +# define ETH_MACDBGR_RFRCS_RSTATUS (2 << ETH_MACDBGR_RFRCS_SHIFT) /* 10: Reading frame status (or time-stamp) */ +# define ETH_MACDBGR_RFRCS_FLUSHING (3 << ETH_MACDBGR_RFRCS_SHIFT) /* 11: Flushing the frame data and status */ +#define ETH_MACDBGR_RFFL_SHIFT (8) /* Bits 8-9: Rx FIFO fill level */ +#define ETH_MACDBGR_RFFL_MASK (3 << ETH_MACDBGR_RFFL_SHIFT) +# define ETH_MACDBGR_RFFL_EMPTY (0 << ETH_MACDBGR_RFFL_SHIFT) /* 00: RxFIFO empty */ +# define ETH_MACDBGR_RFFL_DEACT (1 << ETH_MACDBGR_RFFL_SHIFT) /* 01: RxFIFO fill-level below flow-control de-activate threshold */ +# define ETH_MACDBGR_RFFL_ACTIV (2 << ETH_MACDBGR_RFFL_SHIFT) /* 10: RxFIFO fill-level above flow-control activate threshold */ +# define ETH_MACDBGR_RFFL_FULL (3 << ETH_MACDBGR_RFFL_SHIFT) /* 11: RxFIFO full */ +#define ETH_MACDBGR_MMTEA (1 << 16) /* Bit 16: MAC MII transmit engine active */ +#define ETH_MACDBGR_MTFCS_SHIFT (17) /* Bits 17-18: MAC transmit frame controller status */ +#define ETH_MACDBGR_MTFCS_MASK (3 << ETH_MACDBGR_MTFCS_SHIFT) +# define ETH_MACDBGR_MTFCS_IDLE (0 << ETH_MACDBGR_MTFCS_SHIFT) /* 00: Idle */ +# define ETH_MACDBGR_MTFCS_WAITING (1 << ETH_MACDBGR_MTFCS_SHIFT) /* 01: Waiting for Status of previous frame or IFG/backoff period to be over */ +# define ETH_MACDBGR_MTFCS_PAUSE (2 << ETH_MACDBGR_MTFCS_SHIFT) /* 10: Generating and transmitting a Pause control frame */ +# define ETH_MACDBGR_MTFCS_FRAME (3 << ETH_MACDBGR_MTFCS_SHIFT) /* 11: Transferring input frame for transmission */ +#define ETH_MACDBGR_MTP (1 << 19) /* Bit 19: MAC transmitter in pause */ +#define ETH_MACDBGR_TFRS_SHIFT (20) /* Bits 20-21: Tx FIFO read status */ +#define ETH_MACDBGR_TFRS_MASK (3 << ETH_MACDBGR_TFRS_SHIFT) +# define ETH_MACDBGR_TFRS_IDLE (0 << ETH_MACDBGR_TFRS_SHIFT) /* 00: Idle state */ +# define ETH_MACDBGR_TFRS_READ (1 << ETH_MACDBGR_TFRS_SHIFT) /* 01: Read state */ +# define ETH_MACDBGR_TFRS_WAITING (2 << ETH_MACDBGR_TFRS_SHIFT) /* 10: Waiting for TxStatus from MAC transmitter */ +# define ETH_MACDBGR_TFRS_WRITING (3 << ETH_MACDBGR_TFRS_SHIFT) /* 11: Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MACDBGR_TFWA (1 << 22) /* Bit 22: Tx FIFO write active */ +#define ETH_MACDBGR_TFNE (1 << 24) /* Bit 24: Tx FIFO not empty */ +#define ETH_MACDBGR_TFF (1 << 25) /* Bit 25: Tx FIFO full */ + +#endif + +/* Ethernet MAC interrupt status register */ + +#define ETH_MACSR_PMTS (1 << 3) /* Bit 3: PMT status */ +#define ETH_MACSR_MMCS (1 << 4) /* Bit 4: MMC status */ +#define ETH_MACSR_MMCRS (1 << 5) /* Bit 5: MMC receive status */ +#define ETH_MACSR_MMCTS (1 << 6) /* Bit 6: MMC transmit status */ +#define ETH_MACSR_TSTS (1 << 9) /* Bit 9: Time stamp trigger status */ + +/* Ethernet MAC interrupt mask register */ + +#define ETH_MACIMR_PMTIM (1 << 3) /* Bit 3: PMT interrupt mask */ +#define ETH_MACIMR_TSTIM (1 << 9) /* Bit 9: Time stamp trigger interrupt mask */ +#define ETH_MACIMR_ALLINTS (ETH_MACIMR_PMTIM|ETH_MACIMR_TSTIM) + +/* Ethernet MAC address 0 high register */ + +#define ETH_MACA0HR_MACA0H_SHIFT (0) /* Bits 0-15: MAC address0 high [47:32] */ +#define ETH_MACA0HR_MACA0H_MASK (0xffff << ETH_MACA0HR_MACA0H_SHIFT) +#define ETH_MACA0HR_MO (1 << 31) /* Bit 31:Always */ + +/* Ethernet MAC address 0 low register (MAC address0 low [31:0]) */ + +/* Ethernet MAC address 1 high register */ + +#define ETH_MACA1HR_MACA1H_SHIFT (0) /* Bits 0-15: MAC address1 high [47:32] */ +#define ETH_MACA1HR_MACA1H_MASK (0xffff << ETH_MACA1HR_MACA1H_SHIFT) +#define ETH_MACA1HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA1HR_MBC_MASK (0x3f << ETH_MACA1HR_MBC_SHIFT) +# define ETH_MACA1HR_MBC_40_47 (0x20 << ETH_MACA1HR_MBC_SHIFT) /* Bit 29: ETH_MACA1HR [8-15] */ +# define ETH_MACA1HR_MBC_32_39 (0x10 << ETH_MACA1HR_MBC_SHIFT) /* Bit 28: ETH_MACA1HR [0-7] */ +# define ETH_MACA1HR_MBC_24_31 (0x08 << ETH_MACA1HR_MBC_SHIFT) /* Bit 27: ETH_MACA1LR [24-31] */ +# define ETH_MACA1HR_MBC_16_23 (0x04 << ETH_MACA1HR_MBC_SHIFT) /* Bit 26: ETH_MACA1LR [16-23] */ +# define ETH_MACA1HR_MBC_8_15 (0x02 << ETH_MACA1HR_MBC_SHIFT) /* Bit 25: ETH_MACA1LR [8-15] */ +# define ETH_MACA1HR_MBC_0_7 (0x01 << ETH_MACA1HR_MBC_SHIFT) /* Bit 24: ETH_MACA1LR [0-7] */ +#define ETH_MACA1HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA1HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address1 low register (MAC address1 low [31:0]) */ + +/* Ethernet MAC address 2 high register */ + +#define ETH_MACA2HR_MACA2H_SHIFT (0) /* Bits 0-15: MAC address2 high [47:32] */ +#define ETH_MACA2HR_MACA2H_MASK (0xffff << ETH_MACA2HR_MACA2H_SHIFT) +#define ETH_MACA2HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA2HR_MBC_MASK (0x3f << ETH_MACA2HR_MBC_SHIFT) +# define ETH_MACA2HR_MBC_40_47 (0x20 << ETH_MACA2HR_MBC_SHIFT) /* Bit 29: ETH_MACA2HR [8-15] */ +# define ETH_MACA2HR_MBC_32_39 (0x10 << ETH_MACA2HR_MBC_SHIFT) /* Bit 28: ETH_MACA2HR [0-7] */ +# define ETH_MACA2HR_MBC_24_31 (0x08 << ETH_MACA2HR_MBC_SHIFT) /* Bit 27: ETH_MACA2LR [24-31] */ +# define ETH_MACA2HR_MBC_16_23 (0x04 << ETH_MACA2HR_MBC_SHIFT) /* Bit 26: ETH_MACA2LR [16-23] */ +# define ETH_MACA2HR_MBC_8_15 (0x02 << ETH_MACA2HR_MBC_SHIFT) /* Bit 25: ETH_MACA2LR [8-15] */ +# define ETH_MACA2HR_MBC_0_7 (0x01 << ETH_MACA2HR_MBC_SHIFT) /* Bit 24: ETH_MACA2LR [0-7] */ +#define ETH_MACA2HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA2HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address 2 low register (MAC address2 low [31:0]) */ + +/* Ethernet MAC address 3 high register */ + +#define ETH_MACA3HR_MACA3H_SHIFT (0) /* Bits 0-15: MAC address3 high [47:32] */ +#define ETH_MACA3HR_MACA3H_MASK (0xffff << ETH_MACA3HR_MACA3H_SHIFT) +#define ETH_MACA3HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA3HR_MBC_MASK (0x3f << ETH_MACA3HR_MBC_SHIFT) +# define ETH_MACA3HR_MBC_40_47 (0x20 << ETH_MACA3HR_MBC_SHIFT) /* Bit 29: ETH_MACA3HR [8-15] */ +# define ETH_MACA3HR_MBC_32_39 (0x10 << ETH_MACA3HR_MBC_SHIFT) /* Bit 28: ETH_MACA3HR [0-7] */ +# define ETH_MACA3HR_MBC_24_31 (0x08 << ETH_MACA3HR_MBC_SHIFT) /* Bit 27: ETH_MACA3LR [24-31] */ +# define ETH_MACA3HR_MBC_16_23 (0x04 << ETH_MACA3HR_MBC_SHIFT) /* Bit 26: ETH_MACA3LR [16-23] */ +# define ETH_MACA3HR_MBC_8_15 (0x02 << ETH_MACA3HR_MBC_SHIFT) /* Bit 25: ETH_MACA3LR [8-15] */ +# define ETH_MACA3HR_MBC_0_7 (0x01 << ETH_MACA3HR_MBC_SHIFT) /* Bit 24: ETH_MACA3LR [0-7] */ +#define ETH_MACA3HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA3HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address 3 low register (MAC address3 low [31:0]) */ + +/* MMC Registers */ + +/* Ethernet MMC control register */ + +#define ETH_MMCCR_CR (1 << 0) /* Bit 0: Counter reset */ +#define ETH_MMCCR_CSR (1 << 1) /* Bit 1: Counter stop rollover */ +#define ETH_MMCCR_ROR (1 << 2) /* Bit 2: Reset on read */ +#define ETH_MMCCR_MCF (1 << 3) /* Bit 3: MMC counter freeze */ +#define ETH_MMCCR_MCP (1 << 4) /* Bit 4: MMC counter preset */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ETH_MMCCR_MCFHP (1 << 5) /* Bit 5: MMC counter Full-Half preset */ +#endif + +/* Ethernet MMC receive interrupt and interrupt mask registers */ + +#define ETH_MMCRI_RFCE (1 << 5) /* Bit 5: Received frame CRC error */ +#define ETH_MMCRI_RFAE (1 << 6) /* Bit 6: Received frames alignment error */ +#define ETH_MMCRI_RGUF (1 << 17) /* Bit 17: Received good unicast frames */ + +/* Ethernet MMC transmit interrupt and interrupt mask register */ + +#define ETH_MMCTI_TGFSC (1 << 14) /* Bit 14: Transmitted good frames single collision */ +#define ETH_MMCTI_TGFMSC (1 << 15) /* Bit 15: Transmitted good frames more single collision */ +#define ETH_MMCTI_TGF (1 << 21) /* Bit 21: Transmitted good frames */ + +/* 32-bit counters: + * + * Ethernet MMC transmitted good frames counter register (single collision) + * Ethernet MMC transmitted good frames counter register (multiple-collision) + * Ethernet MMC transmitted good frames counter register + * Ethernet MMC received frames with CRC error counter register + * Ethernet MMC received frames with alignment error counter + * MMC received good unicast frames counter register + */ + +/* IEEE 1588 time stamp registers */ + +/* Ethernet PTP time stamp control register */ + +#define ETH_PTPTSCR_TSE (1 << 0) /* Bit 0: Time stamp enable */ +#define ETH_PTPTSCR_TSFCU (1 << 1) /* Bit 1: Time stamp fine or coarse update */ +#define ETH_PTPTSCR_TSSTI (1 << 2) /* Bit 2: Time stamp system time initialize */ +#define ETH_PTPTSCR_TSSTU (1 << 3) /* Bit 3: Time stamp system time update */ +#define ETH_PTPTSCR_TSITE (1 << 4) /* Bit 4: Time stamp interrupt trigger enable */ +#define ETH_PTPTSCR_TSARU (1 << 5) /* Bit 5: Time stamp addend register update */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +#define ETH_PTPTSCR_TSSARFE (1 << 8) /* Bit 8: Time stamp snapshot for all received frames enable */ +#define ETH_PTPTSCR_TSSSR (1 << 9) /* Bit 9: Time stamp subsecond rollover: digital or binary rollover control */ +#define ETH_PTPTSCR_TSPTPPSV2E (1 << 10) /* Bit 10: Time stamp PTP packet snooping for version2 format enable */ +#define ETH_PTPTSCR_TSSPTPOEFE (1 << 11) /* Bit 11: Time stamp snapshot for PTP over ethernet frames enable */ +#define ETH_PTPTSCR_TSSIPV6FE (1 << 12) /* Bit 12: Time stamp snapshot for IPv6 frames enable */ +#define ETH_PTPTSCR_TSSIPV4FE (1 << 13) /* Bit 13: Time stamp snapshot for IPv4 frames enable */ +#define ETH_PTPTSCR_TSSEME (1 << 14) /* Bit 14: Time stamp snapshot for event message enable */ +#define ETH_PTPTSCR_TSSMRME (1 << 15) /* Bit 15: Time stamp snapshot for message relevant to master enable */ +#define ETH_PTPTSCR_TSCNT_SHIFT (16) /* Bits 16-17: Time stamp clock node type */ +#define ETH_PTPTSCR_TSCNT_MASK (3 << ETH_PTPTSCR_TSCNT_SHIFT) +# define ETH_PTPTSCR_TSCNT_ORDINARY (0 << ETH_PTPTSCR_TSCNT_SHIFT) /* 00: Ordinary clock */ +# define ETH_PTPTSCR_TSCNT_BOUNDARY (1 << ETH_PTPTSCR_TSCNT_SHIFT) /* 01: Boundary clock */ +# define ETH_PTPTSCR_TSCNT_E2E (2 << ETH_PTPTSCR_TSCNT_SHIFT) /* 10: End-to-end transparent clock */ +# define ETH_PTPTSCR_TSCNT_P2P (3 << ETH_PTPTSCR_TSCNT_SHIFT) /* 11: Peer-to-peer transparent clock */ +#define ETH_PTPTSCR_TSPFFMAE (1 << 18) /* Bit 18: Time stamp PTP frame filtering MAC address enable */ +#endif + +/* Ethernet PTP subsecond increment register */ + +#define ETH_PTPSSIR_MASK (0xff) + +/* Ethernet PTP time stamp high register (32-bit) */ + +/* Ethernet PTP time stamp low register */ + +#define ETH_PTPTSLR_STPNS (1 << 31) /* Bit 31: System time positive or negative sign */ +#define ETH_PTPTSLR_MASK (0x7fffffff) /* Bits 0-30: System time subseconds */ + +/* Ethernet PTP time stamp high update register (32-bit) */ + +/* Ethernet PTP time stamp low update register */ + +#define ETH_PTPTSLU_TSUPNS (1 << 31) /* Bit 31: System time positive or negative sign */ +#define ETH_PTPTSLU_MASK (0x7fffffff) /* Bits 0-30: Time stamp update subsecond */ + +/* Ethernet PTP time stamp addend register (32-bit) */ +/* Ethernet PTP target time high register (32-bit) */ +/* Ethernet PTP target time low register (32-bit) */ + +/* Ethernet PTP time stamp status register */ + +#define ETH_PTPTSSR_TSSO (1 << 0) /* Bit 0: Time stamp second overflow */ +#define ETH_PTPTSSR_TSTTR (1 << 1) /* Bit 1: Time stamp target time reached */ + +/* Ethernet PTP PPS control register */ + +#define ETH_PTPPPSCR_PPSFREQ_SHIFT (0) /* Bits 0-3: PPS frequency selection */ +#define ETH_PTPPPSCR_PPSFREQ_MASK (15 << ETH_PTPPPSCR_PPSFREQ_SHIFT) +# define ETH_PTPPPSCR_PPSFREQ_1HZ (0 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 1 Hz with pulse width of 125/100 ms for binary/digital rollover */ +# define ETH_PTPPPSCR_PPSFREQ_2HZ (1 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 2 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_4HZ (2 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 4 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_8HZ (3 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 8 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_16HZ (4 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 16 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_32HZ (5 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 32 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_64HZ (6 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 64 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_128HZ (7 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 128 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_256HZ (8 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 256 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_512HZ (9 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 512 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_1KHZ (10 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 1024 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_2KHZ (11 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 2048 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_4KHZ (12 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 4096 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_8KHZ (13 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 8192 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_16KHZ (14 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 16384 Hz with 50% duty cycle */ +# define ETH_PTPPPSCR_PPSFREQ_32KHZ (15 << ETH_PTPPPSCR_PPSFREQ_SHIFT) /* 32768 Hz with 50% duty cycle */ + +/* DMA Registers */ + +/* Ethernet DMA bus mode register */ + +#define ETH_DMABMR_SR (1 << 0) /* Bit 0: Software reset */ +#define ETH_DMABMR_DA (1 << 1) /* Bit 1: DMA Arbitration */ +#define ETH_DMABMR_DSL_SHIFT (2) /* Bits 2-6: Descriptor skip length */ +#define ETH_DMABMR_DSL_MASK (31 << ETH_DMABMR_DSL_SHIFT) +# define ETH_DMABMR_DSL(n) ((n) << ETH_DMABMR_DSL_SHIFT) +#define ETH_DMABMR_EDFE (1 << 7) /* Bit 7: Enhanced descriptor format enable */ +#define ETH_DMABMR_PBL_SHIFT (8) /* Bits 8-13: Programmable burst length */ +# define ETH_DMABMR_PBL(n) ((n) << ETH_DMABMR_PBL_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMR_PBL_MASK (0x3f << ETH_DMABMR_PBL_SHIFT) +#define ETH_DMABMR_RTPR_SHIFT (14) /* Bits 14-15: Rx Tx priority ratio */ +#define ETH_DMABMR_RTPR_MASK (3 << ETH_DMABMR_RTPR_SHIFT) +# define ETH_DMABMR_RTPR_1TO1 (0 << ETH_DMABMR_RTPR_SHIFT) /* 00: 1:1 */ +# define ETH_DMABMR_RTPR_2TO1 (1 << ETH_DMABMR_RTPR_SHIFT) /* 01: 2:1 */ +# define ETH_DMABMR_RTPR_3TO1 (2 << ETH_DMABMR_RTPR_SHIFT) /* 10: 3:1 */ +# define ETH_DMABMR_RTPR_4TO1 (3 << ETH_DMABMR_RTPR_SHIFT) /* 11: 4:1 */ +#define ETH_DMABMR_FB (1 << 16) /* Bit 16: Fixed burst */ +#define ETH_DMABMR_RDP_SHIFT (17) /* Bits 17-22: Rx DMA PBL */ +#define ETH_DMABMR_RDP_MASK (0x3f << ETH_DMABMR_RDP_SHIFT) +# define ETH_DMABMR_RDP(n) ((n) << ETH_DMABMR_RDP_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMR_USP (1 << 23) /* Bit 23: Use separate PBL */ +#define ETH_DMABMR_FPM (1 << 24) /* Bit 24: 4xPBL mode */ +#define ETH_DMABMR_AAB (1 << 25) /* Bit 25: Address-aligned beats */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ETH_DMABMR_MB (1 << 26) /* Bit 26: Mixed burst */ +#endif + +/* Ethernet DMA transmit poll demand register (32-bit) */ +/* Ethernet DMA receive poll demand register (32-bit) */ +/* Ethernet DMA receive descriptor list address register (32-bit address) */ +/* Ethernet DMA transmit descriptor list address register (32-bit address) */ + +/* Interrupt bit definitions common between the DMA status register (DMASR) and + * the DMA interrupt enable register (DMAIER). + */ + +#define ETH_DMAINT_TI (1 << 0) /* Bit 0: Transmit interrupt */ +#define ETH_DMAINT_TPSI (1 << 1) /* Bit 1: Transmit process stopped interrupt */ +#define ETH_DMAINT_TBUI (1 << 2) /* Bit 2: Transmit buffer unavailable interrupt */ +#define ETH_DMAINT_TJTI (1 << 3) /* Bit 3: Transmit jabber timeout interrupt */ +#define ETH_DMAINT_ROI (1 << 4) /* Bit 4: Overflow interrupt */ +#define ETH_DMAINT_TUI (1 << 5) /* Bit 5: Underflow interrupt */ +#define ETH_DMAINT_RI (1 << 6) /* Bit 6: Receive interrupt */ +#define ETH_DMAINT_RBUI (1 << 7) /* Bit 7: Receive buffer unavailable interrupt */ +#define ETH_DMAINT_RPSI (1 << 8) /* Bit 8: Receive process stopped interrupt */ +#define ETH_DMAINT_RWTI (1 << 9) /* Bit 9: Receive watchdog timeout interrupt */ +#define ETH_DMAINT_ETI (1 << 10) /* Bit 10: Early transmit interrupt */ +#define ETH_DMAINT_FBEI (1 << 13) /* Bit 13: Fatal bus error interrupt */ +#define ETH_DMAINT_ERI (1 << 14) /* Bit 14: Early receive interrupt */ +#define ETH_DMAINT_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */ +#define ETH_DMAINT_NIS (1 << 16) /* Bit 16: Normal interrupt summary */ + +/* Ethernet DMA status register (in addition to the interrupt bits above */ + +#define ETH_DMASR_RPS_SHIFT (17) /* Bits 17-19: Receive process state */ +#define ETH_DMASR_RPS_MASK (7 << ETH_DMASR_RPS_SHIFT) +# define ETH_DMASR_RPS_STOPPED (0 << ETH_DMASR_RPS_SHIFT) /* 000: Stopped: Reset or Stop Receive Command issued */ +# define ETH_DMASR_RPS_RXDESC (1 << ETH_DMASR_RPS_SHIFT) /* 001: Running: Fetching receive transfer descriptor */ +# define ETH_DMASR_RPS_WAITING (3 << ETH_DMASR_RPS_SHIFT) /* 011: Running: Waiting for receive packet */ +# define ETH_DMASR_RPS_SUSPENDED (4 << ETH_DMASR_RPS_SHIFT) /* 100: Suspended: Receive descriptor unavailable */ +# define ETH_DMASR_RPS_CLOSING (5 << ETH_DMASR_RPS_SHIFT) /* 101: Running: Closing receive descriptor */ +# define ETH_DMASR_RPS_TRANSFER (6 << ETH_DMASR_RPS_SHIFT) /* 111: Running: Transferring the receive data to memory */ +#define ETH_DMASR_TPS_SHIFT (20) /* Bits 20-22: Transmit process state */ +#define ETH_DMASR_TPS_MASK (7 << ETH_DMASR_TPS_SHIFT) +# define ETH_DMASR_TPS_STOPPED (0 << ETH_DMASR_TPS_SHIFT) /* 000: Stopped; Reset or Stop Transmit Command issued */ +# define ETH_DMASR_TPS_TXDESC (1 << ETH_DMASR_TPS_SHIFT) /* 001: Running; Fetching transmit transfer descriptor */ +# define ETH_DMASR_TPS_WAITING (2 << ETH_DMASR_TPS_SHIFT) /* 010: Running; Waiting for status */ +# define ETH_DMASR_TPS_TRANSFER (3 << ETH_DMASR_TPS_SHIFT) /* 011: Running; Reading data and queuing to transmit (TxFIFO) */ +# define ETH_DMASR_TPS_SUSPENDED (6 << ETH_DMASR_TPS_SHIFT) /* 110: Suspended; Transmit descriptor unavailable or buffer underflow */ +# define ETH_DMASR_TPS_CLOSING (7 << ETH_DMASR_TPS_SHIFT) /* 111: Running; Closing transmit descriptor */ +#define ETH_DMASR_EBS_SHIFT (23) /* Bits 23-25: Error bits status */ +#define ETH_DMASR_EBS_MASK (7 << ETH_DMASR_EBS_SHIFT) +#define ETH_DMASR_EBS_TXDMS (1 << ETH_DMASR_EBS_SHIFT) /* Bit 23 1 Error during data transfer by TxDMA */ +#define ETH_DMASR_EBS_READ (2 << ETH_DMASR_EBS_SHIFT) /* Bit 24 1 Error during read transfer */ +#define ETH_DMASR_EBS_DESC (4 << ETH_DMASR_EBS_SHIFT) /* Bit 25 1 Error during descriptor access */ +#define ETH_DMASR_MMCS (1 << 27) /* Bit 27: MMC status */ +#define ETH_DMASR_PMTS (1 << 28) /* Bit 28: PMT status */ +#define ETH_DMASR_TSTS (1 << 29) /* Bit 29: Time stamp trigger status */ + +/* Ethernet DMA operation mode register */ + +#define ETH_DMAOMR_SR (1 << 1) /* Bit 1: Start/stop receive */ +#define ETH_DMAOMR_OSF (1 << 2) /* Bit 2: Operate on second frame */ +#define ETH_DMAOMR_RTC_SHIFT (3) /* Bits 3-4: Receive threshold control */ +#define ETH_DMAOMR_RTC_MASK (3 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_64 (0 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_32 (1 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_96 (2 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_128 (3 << ETH_DMAOMR_RTC_SHIFT) +#define ETH_DMAOMR_FUGF (1 << 6) /* Bit 6: Forward undersized good frames */ +#define ETH_DMAOMR_FEF (1 << 7) /* Bit 7: Forward error frames */ +#define ETH_DMAOMR_ST (1 << 13) /* Bit 13: Start/stop transmission */ +#define ETH_DMAOMR_TTC_SHIFT (14) /* Bits 14-16: Transmit threshold control */ +#define ETH_DMAOMR_TTC_MASK (7 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_64 (0 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_128 (1 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_192 (2 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_256 (3 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_40 (4 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_32 (5 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_24 (6 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_16 (7 << ETH_DMAOMR_TTC_SHIFT) +#define ETH_DMAOMR_FTF (1 << 20) /* Bit 20: Flush transmit FIFO */ +#define ETH_DMAOMR_TSF (1 << 21) /* Bit 21: Transmit store and forward */ +#define ETH_DMAOMR_DFRF (1 << 24) /* Bit 24: Disable flushing of received frames */ +#define ETH_DMAOMR_RSF (1 << 25) /* Bit 25: Receive store and forward */ +#define ETH_DMAOMR_DTCEFD (1 << 26) /* Bit 26: Dropping of TCP/IP checksum error frames disable */ + +/* Ethernet DMA missed frame and buffer overflow counter register */ + +#define ETH_DMAMFBOC_MFC_SHIFT (0) /* Bits 0-15: Missed frames by the controller */ +#define ETH_DMAMFBOC_MFC_MASK (0xffff << ETH_DMAMFBOC_MFC_SHIFT) +#define ETH_DMAMFBOC_OMFC (1 << 16) /* Bit 16: Overflow bit for missed frame counter */ +#define ETH_DMAMFBOC_MFA_SHIFT (17) /* Bits 17-27: Missed frames by the application */ +#define ETH_DMAMFBOC_MFA_MASK (0x7ff << ETH_DMAMFBOC_MFA_SHIFT) +#define ETH_DMAMFBOC_OFOC (1 << 28) /* Bit 28: Overflow bit for FIFO overflow counter */ + +/* Ethernet DMA receive status watchdog timer register */ + +#define ETH_DMARSWTR_MASK (0xff) + +/* Ethernet DMA current host transmit descriptor register (32-bit address) */ +/* Ethernet DMA current host receive descriptor register (32-bit address) */ +/* Ethernet DMA current host transmit buffer address register (32-bit address) */ +/* Ethernet DMA current host receive buffer address register (32-bit address) */ + +/* DMA Descriptors **********************************************************************************/ +/* TDES0: Transmit descriptor Word0 */ + +#define ETH_TDES0_DB (1 << 0) /* Bit 0: Deferred bit */ +#define ETH_TDES0_UF (1 << 1) /* Bit 1: Underflow error */ +#define ETH_TDES0_ED (1 << 2) /* Bit 2: Excessive deferral */ +#define ETH_TDES0_CC_SHIFT (3) /* Bits 3-6: Collision count */ +#define ETH_TDES0_CC_MASK (15 << ETH_TDES0_CC_SHIFT) +#define ETH_TDES0_VF (1 << 7) /* Bit 7: VLAN frame */ +#define ETH_TDES0_EC (1 << 8) /* Bit 8: Excessive collision */ +#define ETH_TDES0_LCO (1 << 9) /* Bit 9: Late collision */ +#define ETH_TDES0_NC (1 << 10) /* Bit 10: No carrier */ +#define ETH_TDES0_LCA (1 << 11) /* Bit 11: Loss of carrier */ +#define ETH_TDES0_IPE (1 << 12) /* Bit 12: IP payload error */ +#define ETH_TDES0_FF (1 << 13) /* Bit 13: Frame flushed */ +#define ETH_TDES0_JT (1 << 14) /* Bit 14: Jabber timeout */ +#define ETH_TDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_TDES0_IHE (1 << 16) /* Bit 16: IP header error */ +#define ETH_TDES0_TTSS (1 << 17) /* Bit 17: Transmit time stamp status */ +#define ETH_TDES0_TCH (1 << 20) /* Bit 20: Second address chained */ +#define ETH_TDES0_TER (1 << 21) /* Bit 21: Transmit end of ring */ +#define ETH_TDES0_CIC_SHIFT (22) /* Bits 22-23: Checksum insertion control */ +#define ETH_TDES0_CIC_MASK (3 << ETH_TDES0_CIC_SHIFT) +# define ETH_TDES0_CIC_DISABLED (0 << ETH_TDES0_CIC_SHIFT) /* Checksum disabled */ +# define ETH_TDES0_CIC_IH (1 << ETH_TDES0_CIC_SHIFT) /* IP header checksum enabled */ +# define ETH_TDES0_CIC_IHPL (2 << ETH_TDES0_CIC_SHIFT) /* IP header and payload checksum enabled */ +# define ETH_TDES0_CIC_ALL (3 << ETH_TDES0_CIC_SHIFT) /* IP Header, payload, and pseudo-header checksum enabled */ +#define ETH_TDES0_TTSE (1 << 25) /* Bit 25: Transmit time stamp enable */ +#define ETH_TDES0_DP (1 << 26) /* Bit 26: Disable pad */ +#define ETH_TDES0_DC (1 << 27) /* Bit 27: Disable CRC */ +#define ETH_TDES0_FS (1 << 28) /* Bit 28: First segment */ +#define ETH_TDES0_LS (1 << 29) /* Bit 29: Last segment */ +#define ETH_TDES0_IC (1 << 30) /* Bit 30: Interrupt on completion */ +#define ETH_TDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* TDES1: Transmit descriptor Word1 */ + +#define ETH_TDES1_TBS1_SHIFT (0) /* Bits 0-12: Transmit buffer 1 size */ +#define ETH_TDES1_TBS1_MASK (0x1fff << ETH_TDES1_TBS1_SHIFT) +#define ETH_TDES1_TBS2_SHIFT (16) /* Bits 16-28: Transmit buffer 2 size */ +#define ETH_TDES1_TBS2_MASK (0x1fff << ETH_TDES1_TBS2_SHIFT) + +/* TDES2: Transmit descriptor Word2 (32-bit address) */ +/* TDES3: Transmit descriptor Word3 (32-bit address) */ +/* TDES6: Transmit descriptor Word6 (32-bit time stamp) */ +/* TDES7: Transmit descriptor Word7 (32-bit time stamp) */ + +/* RDES0: Receive descriptor Word0 */ + +#define ETH_RDES0_PCE (1 << 0) /* Bit 0: Payload checksum error */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ETH_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#endif +#define ETH_RDES0_CE (1 << 1) /* Bit 1: CRC error */ +#define ETH_RDES0_DBE (1 << 2) /* Bit 2: Dribble bit error */ +#define ETH_RDES0_RE (1 << 3) /* Bit 3: Receive error */ +#define ETH_RDES0_RWT (1 << 4) /* Bit 4: Receive watchdog timeout */ +#define ETH_RDES0_FT (1 << 5) /* Bit 5: Frame type */ +#define ETH_RDES0_LCO (1 << 6) /* Bit 6: Late collision */ +#define ETH_RDES0_TSV (1 << 7) /* Bit 7: Time stamp valid */ +#define ETH_RDES0_IPHCE (1 << 7) /* Bit 7: IPv header checksum error */ +#define ETH_RDES0_LS (1 << 8) /* Bit 8: Last descriptor */ +#define ETH_RDES0_FS (1 << 9) /* Bit 9: First descriptor */ +#define ETH_RDES0_VLAN (1 << 10) /* Bit 10: VLAN tag */ +#define ETH_RDES0_OE (1 << 11) /* Bit 11: Overflow error */ +#define ETH_RDES0_LE (1 << 12) /* Bit 12: Length error */ +#define ETH_RDES0_SAF (1 << 13) /* Bit 13: Source address filter fail */ +#define ETH_RDES0_DE (1 << 14) /* Bit 14: Descriptor error */ +#define ETH_RDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_RDES0_FL_SHIFT (16) /* Bits 16-29: Frame length */ +#define ETH_RDES0_FL_MASK (0x3fff << ETH_RDES0_FL_SHIFT) +#define ETH_RDES0_AFM (1 << 30) /* Bit 30: Destination address filter fail */ +#define ETH_RDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* RDES1: Receive descriptor Word1 */ + +#define ETH_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ +#define ETH_RDES1_RBS1_MASK (0x1fff << ETH_RDES1_RBS1_SHIFT) + /* Bit 13: Reserved */ +#define ETH_RDES1_RCH (1 << 14) /* Bit 14: Second address chained */ +#define ETH_RDES1_RER (1 << 15) /* Bit 15: Receive end of ring */ +#define ETH_RDES1_RBS2_SHIFT (16) /* Bits 16-28: Receive buffer 2 size */ +#define ETH_RDES1_RBS2_MASK (0x1fff << ETH_RDES1_RBS2_SHIFT) +#define ETH_RDES1_DIC (1 << 31) /* Bit 31: Disable interrupt on completion */ + +/* RDES2: Receive descriptor Word2 (32-bit address) */ +/* RDES3: Receive descriptor Word3 (32-bit address) */ + +/* RDES4: Receive descriptor Word4 */ + +#define ETH_RDES4_IPPT_SHIFT (0) /* Bits 0-2: IP payload type */ +#define ETH_RDES4_IPPT_MASK (7 << ETH_RDES4_IPPT_SHIFT) +# define ETH_RDES4_IPPT_UDP (1 << ETH_RDES4_IPPT_SHIFT) /* UDP payload in IP datagram */ +# define ETH_RDES4_IPPT_TCP (2 << ETH_RDES4_IPPT_SHIFT) /* TCP payload in IP datagram */ +# define ETH_RDES4_IPPT_ICMP (3 << ETH_RDES4_IPPT_SHIFT) /* ICMP payload in IP datagram */ +#define ETH_RDES4_IPHE (1 << 3) /* Bit 3: IP header error */ +#define ETH_RDES4_IPPE (1 << 4) /* Bit 4: IP payload error */ +#define ETH_RDES4_IPCB (1 << 5) /* Bit 5: IP checksum bypassed */ +#define ETH_RDES4_IPV4PR (1 << 6) /* Bit 6: IPv4 packet received */ +#define ETH_RDES4_IPV6PR (1 << 7) /* Bit 7: IPv6 packet received */ +#define ETH_RDES4_PMT_SHIFT (8) /* Bits 8-11: PTP message type */ +#define ETH_RDES4_PMT_MASK (15 << ETH_RDES4_PMT_SHIFT) +# define ETH_RDES4_PMT_NONE (0 << ETH_RDES4_PMT_SHIFT) /* No PTP message received */ +# define ETH_RDES4_PMT_SYNC (1 << ETH_RDES4_PMT_SHIFT) /* SYNC (all clock types) */ +# define ETH_RDES4_PMT_FOLLOWUP (2 << ETH_RDES4_PMT_SHIFT) /* Follow_Up (all clock types) */ +# define ETH_RDES4_PMT_DELAYREQ (3 << ETH_RDES4_PMT_SHIFT) /* Delay_Req (all clock types) */ +# define ETH_RDES4_PMT_DELAYRESP (4 << ETH_RDES4_PMT_SHIFT) /* Delay_Resp (all clock types) */ +# define ETH_RDES4_PMT_PDELREQAM (5 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Req (in peer-to-peer + * transparent clock) or Announce (in + * ordinary or boundary clock) */ +# define ETH_RDES4_PMT_PDELREQMM (6 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Resp (in peer-to-peer + * transparent clock) or Management (in + * ordinary or boundary clock) */ +# define ETH_RDES4_PMT_PDELREQFUS (7 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Resp_Follow_Up (in + * peer-to-peer transparent clock) or + * Signaling (for ordinary or boundary + * clock) */ +#define ETH_RDES4_PFT (1 << 12) /* Bit 12: PTP frame type */ +#define ETH_RDES4_PV (1 << 13) /* Bit 13: PTP version */ + +/* RDES5: Receive descriptor Word5 - Reserved */ +/* RDES6: Receive descriptor Word6 (32-bit time stamp) */ +/* RDES7: Receive descriptor Word7 (32-bit time stamp) */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Ethernet TX DMA Descriptor */ + +struct eth_txdesc_s +{ + /* Normal DMA descriptor words */ + + volatile uint32_t tdes0; /* Status */ + volatile uint32_t tdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t tdes2; /* Buffer1 address pointer */ + volatile uint32_t tdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp */ + +#ifdef CONFIG_STM32_ETH_ENHANCEDDESC + volatile uint32_t tdes4; /* Reserved */ + volatile uint32_t tdes5; /* Reserved */ + volatile uint32_t tdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t tdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/* Ethernet RX DMA Descriptor */ + +struct eth_rxdesc_s +{ + volatile uint32_t rdes0; /* Status */ + volatile uint32_t rdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t rdes2; /* Buffer1 address pointer */ + volatile uint32_t rdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp and PTP support */ + +#ifdef CONFIG_STM32_ETH_ENHANCEDDESC + volatile uint32_t rdes4; /* Extended status for PTP receive descriptor */ + volatile uint32_t rdes5; /* Reserved */ + volatile uint32_t rdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t rdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* STM32_NETHERNET > 0 */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_ETH_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_exti.h b/arch/arm/src/stm32/chip/stm32_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..a3092ca0e4295e0aa2d88bc6969e96875c9e896c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_exti.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_exti.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F10XX) +# ifdef CONFIG_STM32_CONNECTIVITYLINE +# define STM32_NEXTI 20 +# define STM32_EXTI_MASK 0x000fffff +# else +# define STM32_NEXTI 19 +# define STM32_EXTI_MASK 0x0007ffff +# endif +#elif defined(CONFIG_STM32_STM32F30XX) +# define STM32_NEXTI1 31 +# define STM32_EXTI1_MASK 0xffffffff +# define STM32_NEXTI2 4 +# define STM32_EXTI2_MASK 0x0000000f +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_NEXTI 23 +# define STM32_EXTI_MASK 0x007fffff +#endif + +#define STM32_EXTI_BIT(n) (1 << (n)) + +/* Register Offsets *****************************************************************/ + +#if defined(CONFIG_STM32_STM32F30XX) +# define STM32_EXTI1_OFFSET 0x0000 /* Offset to EXTI1 registers */ +# define STM32_EXTI2_OFFSET 0x0018 /* Offset to EXTI2 registers */ +#endif + +#define STM32_EXTI_IMR_OFFSET 0x0000 /* Interrupt mask register */ +#define STM32_EXTI_EMR_OFFSET 0x0004 /* Event mask register */ +#define STM32_EXTI_RTSR_OFFSET 0x0008 /* Rising Trigger selection register */ +#define STM32_EXTI_FTSR_OFFSET 0x000c /* Falling Trigger selection register */ +#define STM32_EXTI_SWIER_OFFSET 0x0010 /* Software interrupt event register */ +#define STM32_EXTI_PR_OFFSET 0x0014 /* Pending register */ + +/* Register Addresses ***************************************************************/ + +#if defined(CONFIG_STM32_STM32F30XX) +# define STM32_EXTI1_BASE (STM32_EXTI_BASE+STM32_EXTI1_OFFSET) +# define STM32_EXTI2_BASE (STM32_EXTI_BASE+STM32_EXTI2_OFFSET) + +# define STM32_EXTI1_IMR (STM32_EXTI1_BASE+STM32_EXTI_IMR_OFFSET) +# define STM32_EXTI1_EMR (STM32_EXTI1_BASE+STM32_EXTI_EMR_OFFSET) +# define STM32_EXTI1_RTSR (STM32_EXTI1_BASE+STM32_EXTI_RTSR_OFFSET) +# define STM32_EXTI1_FTSR (STM32_EXTI1_BASE+STM32_EXTI_FTSR_OFFSET) +# define STM32_EXTI1_SWIER (STM32_EXTI1_BASE+STM32_EXTI_SWIER_OFFSET) +# define STM32_EXTI1_PR (STM32_EXTI1_BASE+STM32_EXTI_PR_OFFSET) + +# define STM32_EXTI2_IMR (STM32_EXTI2_BASE+STM32_EXTI_IMR_OFFSET) +# define STM32_EXTI2_EMR (STM32_EXTI2_BASE+STM32_EXTI_EMR_OFFSET) +# define STM32_EXTI2_RTSR (STM32_EXTI2_BASE+STM32_EXTI_RTSR_OFFSET) +# define STM32_EXTI2_FTSR (STM32_EXTI2_BASE+STM32_EXTI_FTSR_OFFSET) +# define STM32_EXTI2_SWIER (STM32_EXTI2_BASE+STM32_EXTI_SWIER_OFFSET) +# define STM32_EXTI2_PR (STM32_EXTI2_BASE+STM32_EXTI_PR_OFFSET) + +# define STM32_EXTI_IMR STM32_EXTI1_IMR +# define STM32_EXTI_EMR STM32_EXTI1_EMR +# define STM32_EXTI_RTSR STM32_EXTI1_RTSR +# define STM32_EXTI_FTSR STM32_EXTI1_FTSR +# define STM32_EXTI_SWIER STM32_EXTI1_SWIER +# define STM32_EXTI_PR STM32_EXTI1_PR + +#else +# define STM32_EXTI_IMR (STM32_EXTI_BASE+STM32_EXTI_IMR_OFFSET) +# define STM32_EXTI_EMR (STM32_EXTI_BASE+STM32_EXTI_EMR_OFFSET) +# define STM32_EXTI_RTSR (STM32_EXTI_BASE+STM32_EXTI_RTSR_OFFSET) +# define STM32_EXTI_FTSR (STM32_EXTI_BASE+STM32_EXTI_FTSR_OFFSET) +# define STM32_EXTI_SWIER (STM32_EXTI_BASE+STM32_EXTI_SWIER_OFFSET) +# define STM32_EXTI_PR (STM32_EXTI_BASE+STM32_EXTI_PR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* EXTI lines > 15 are associated with internal devices: */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32L15XX) +# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */ +# define EXTI_USB_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB Wakeup event */ +# ifdef CONFIG_STM32_CONNECTIVITYLINE +# define EXTI_ETH_WAKEUP (1 << 19) /* EXTI line 19 is connected to the Ethernet Wakeup event */ +# endif +#elif defined(CONFIG_STM32_STM32L15XX) +# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */ +# define EXTI_USB_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB Device FS Wakeup event */ +# define EXTI_RTC_TAMPER (1 << 19) /* EXTI line 19 is connected to the RTC Tamper and TimeStamp events */ +# define EXTI_RTC_WAKEUP (1 << 20) /* EXTI line 20 is connected to the RTC Wakeup event */ +# define EXTI_RTC_CMP1 (1 << 21) /* EXTI line 21 is connected to the Comparator 1 wakeup event */ +# define EXTI_RTC_CMP2 (1 << 22) /* EXTI line 22 is connected to the Comparator 2 wakeup event */ +# define EXTI_RTC_ACQUIRE (1 << 23) /* EXTI line 23 is connected to the channel acquisition interrupt */ +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */ +# define EXTI_OTGFS_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB OTG FS Wakeup event */ +# define EXTI_ETH_WAKEUP (1 << 19) /* EXTI line 19 is connected to the Ethernet Wakeup event */ +# define EXTI_OTGHS_WAKEUP (1 << 20) /* EXTI line 20 is connected to the USB OTG HS Wakeup event */ +# define EXTI_RTC_TAMPER (1 << 21) /* EXTI line 21 is connected to the RTC Tamper and TimeStamp events */ +# define EXTI_RTC_TIMESTAMP (1 << 21) /* EXTI line 21 is connected to the RTC Tamper and TimeStamp events */ +# define EXTI_RTC_WAKEUP (1 << 22) /* EXTI line 22 is connected to the RTC Wakeup event */ +#elif defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */ +# define EXTI_OTGFS_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB OTG FS Wakeup event */ +# define EXTI_RTC_TAMPER (1 << 19) /* EXTI line 19 is connected to the RTC Tamper and TimeStamp events */ +# define EXTI_RTC_TIMESTAMP (1 << 19) /* EXTI line 19 is connected to the RTC Tamper and TimeStamp events */ +# define EXTI_RTC_WAKEUP (1 << 20) /* EXTI line 20 is connected to the RTC Wakeup event */ +#endif + +/* Interrupt mask register */ + +#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR_MASK STM32_EXTI_MASK + +/* Event mask register */ + +#define EXTI_EMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR_MASK STM32_EXTI_MASK + +/* Rising Trigger selection register */ + +#define EXTI_RTSR_BIT(n) STM32_EXTI_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR_MASK STM32_EXTI_MASK + +/* Falling Trigger selection register */ + +#define EXTI_FTSR_BIT(n) STM32_EXTI_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR_MASK STM32_EXTI_MASK + +/* Software interrupt event register */ + +#define EXTI_SWIER_BIT(n) STM32_EXTI_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER_MASK STM32_EXTI_MASK + +/* Pending register */ + +#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR_MASK STM32_EXTI_MASK + +/* Compatibility Definitions ********************************************************/ + +#if defined(CONFIG_STM32_STM32F30XX) +# define STM32_NEXTI STM32_NEXTI1 +# define STM32_EXTI_MASK STM32_EXTI1_MASK +# define STM32_EXTI_IMR STM32_EXTI1_IMR +# define STM32_EXTI_EMR STM32_EXTI1_EMR +# define STM32_EXTI_RTSR STM32_EXTI1_RTSR +# define STM32_EXTI_FTSR STM32_EXTI1_FTSR +# define STM32_EXTI_SWIER STM32_EXTI1_SWIER +# define STM32_EXTI_PR STM32_EXTI1_PR +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32/chip/stm32_flash.h b/arch/arm/src/stm32/chip/stm32_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..c031492752724b6b63f0fa54a58d77ab14923135 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_flash.h @@ -0,0 +1,391 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_flash.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define _K(x) ((x)*1024) + +#if !defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_4) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_6) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_8) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_B) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_C) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_D) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_E) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_F) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_G) && \ + !defined(CONFIG_STM32_FLASH_CONFIG_I) +# define CONFIG_STM32_FLASH_CONFIG_DEFAULT +#endif + +#if defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) +# if defined(CONFIG_STM32_STM32L15XX) + +/* The STM32 L15xx/L16xx can support up to 384KB of FLASH. (In reality, supported + * L15xx parts have no more than 128KB). The program memory block is divided into + * 96 sectors of 4 Kbytes each, and each sector is further split up into 16 pages of + * 256 bytes each. The sector is the write protection granularity. In total, the + * program memory block contains 1536 pages. + */ + +# define STM32_FLASH_NPAGES 1536 +# define STM32_FLASH_PAGESIZE 256 + +# elif defined(CONFIG_STM32_LOWDENSITY) +# define STM32_FLASH_NPAGES 32 +# define STM32_FLASH_PAGESIZE 1024 + +# elif defined(CONFIG_STM32_MEDIUMDENSITY) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 1024 + +# elif defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 2048 + +# elif defined(CONFIG_STM32_HIGHDENSITY) +# define STM32_FLASH_NPAGES 256 +# define STM32_FLASH_PAGESIZE 2048 + +# elif defined(CONFIG_STM32_STM32F30XX) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 2048 + +# elif defined(CONFIG_STM32_STM32F37XX) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 2048 + +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_NPAGES 8 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (3 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64),_K(128), _K(128), _K(128)} + + /* STM32F4 has mixed page size */ + +# undef STM32_FLASH_PAGESIZE +# endif +#endif /* CONFIG_STM32_FLASH_CONFIG_DEFAULT */ + +/* Override of the Flash Has been Chosen */ + +#if !defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) + +/* Define the Valid Configuration the F2 and F4 */ + +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + +# if defined(CONFIG_STM32_FLASH_CONFIG_B) +# define STM32_FLASH_NPAGES 5 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_C) +# define STM32_FLASH_NPAGES 6 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (1 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_D) && defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_NPAGES 7 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (2 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_E) +# define STM32_FLASH_NPAGES 8 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (3 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128), _K(128)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_F) && defined(CONFIG_STM32_STM32F20XX) +# define STM32_FLASH_NPAGES 9 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (4 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128), _K(128), \ + _K(128)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_G) +# define STM32_FLASH_NPAGES 12 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (7 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128), _K(128), \ + _K(128), _K(128), _K(128), _K(128)} + +# elif defined(CONFIG_STM32_FLASH_CONFIG_I) && defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_NPAGES 24 +# define STM32_FLASH_SIZE _K((4 * 16) + (1 * 64) + (7 * 128)) + \ + _K((4 * 16) + (1 * 64) + (7 * 128)) +# define STM32_FLASH_SIZES {_K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128), _K(128), \ + _K(128), _K(128), _K(128), _K(128), \ + _K(16), _K(16), _K(16), _K(16), \ + _K(64), _K(128), _K(128), _K(128), \ + _K(128), _K(128), _K(128), _K(128)} +# endif + +/* Define the Valid Configuration the F1 and F3 */ + +# else +# if defined(CONFIG_STM32_FLASH_CONFIG_4) +# define STM32_FLASH_NPAGES 16 +# define STM32_FLASH_PAGESIZE 1024 +# elif defined(CONFIG_STM32_FLASH_CONFIG_6) +# define STM32_FLASH_NPAGES 32 +# define STM32_FLASH_PAGESIZE 1024 +# elif defined(CONFIG_STM32_FLASH_CONFIG_8) +# define STM32_FLASH_NPAGES 64 +# define STM32_FLASH_PAGESIZE 1024 +# elif defined(CONFIG_STM32_FLASH_CONFIG_B) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 1024 +# elif defined(CONFIG_STM32_FLASH_CONFIG_C) +# define STM32_FLASH_NPAGES 128 +# define STM32_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32_FLASH_CONFIG_D) +# define STM32_FLASH_NPAGES 192 +# define STM32_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32_FLASH_CONFIG_E) +# define STM32_FLASH_NPAGES 256 +# define STM32_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32_FLASH_CONFIG_F) +# define STM32_FLASH_NPAGES 384 +# define STM32_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32_FLASH_CONFIG_G) +# define STM32_FLASH_NPAGES 512 +# define STM32_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32_FLASH_CONFIG_I) +# endif +# endif +#endif + +#ifdef STM32_FLASH_PAGESIZE +# define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * STM32_FLASH_PAGESIZE) +#endif /* def STM32_FLASH_PAGESIZE */ + +/* Register Offsets *****************************************************************/ + +#define STM32_FLASH_ACR_OFFSET 0x0000 +#define STM32_FLASH_KEYR_OFFSET 0x0004 +#define STM32_FLASH_OPTKEYR_OFFSET 0x0008 +#define STM32_FLASH_SR_OFFSET 0x000c +#define STM32_FLASH_CR_OFFSET 0x0010 + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) +# define STM32_FLASH_AR_OFFSET 0x0014 +# define STM32_FLASH_OBR_OFFSET 0x001c +# define STM32_FLASH_WRPR_OFFSET 0x0020 +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_OPTCR_OFFSET 0x0014 +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define STM32_FLASH_OPTCR1_OFFSET 0x0018 +#endif + +/* Register Addresses ***************************************************************/ + +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE+STM32_FLASH_ACR_OFFSET) +#define STM32_FLASH_KEYR (STM32_FLASHIF_BASE+STM32_FLASH_KEYR_OFFSET) +#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) +#define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) +#define STM32_FLASH_CR (STM32_FLASHIF_BASE+STM32_FLASH_CR_OFFSET) + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) +# define STM32_FLASH_AR (STM32_FLASHIF_BASE+STM32_FLASH_AR_OFFSET) +# define STM32_FLASH_OBR (STM32_FLASHIF_BASE+STM32_FLASH_OBR_OFFSET) +# define STM32_FLASH_WRPR (STM32_FLASHIF_BASE+STM32_FLASH_WRPR_OFFSET) +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_OPTCR (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR_OFFSET) +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define STM32_FLASH_OPTCR1 (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR1_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ +/* Flash Access Control Register (ACR) */ + +#if defined(CONFIG_STM32_STM32L15XX) +# define FLASH_ACR_LATENCY (1 << 0) /* Bit 0: Latency */ +# define FLASH_ACR_PRFTEN (1 << 1) /* Bit 1: Prefetch enable */ +# define FLASH_ACR_ACC64 (1 << 2) /* Bit 2: 64-bit access */ +# define FLASH_ACR_SLEEP_PD (1 << 3) /* Bit 3: Flash mode during Sleep */ +# define FLASH_ACR_RUN_PD (1 << 4) /* Bit 4: Flash mode during Run */ +#else +# define FLASH_ACR_LATENCY_SHIFT (0) +# define FLASH_ACR_LATENCY_MASK (7 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* n wait states */ +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 000: Zero wait states */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 001: One wait state */ +# define FLASH_ACR_LATENCY_2 (2 << FLASH_ACR_LATENCY_SHIFT) /* 010: Two wait states */ +# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 011: Three wait states */ +# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 100: Four wait states */ +# define FLASH_ACR_LATENCY_5 (5 << FLASH_ACR_LATENCY_SHIFT) /* 101: Five wait states */ +# define FLASH_ACR_LATENCY_6 (6 << FLASH_ACR_LATENCY_SHIFT) /* 110: Six wait states */ +# define FLASH_ACR_LATENCY_7 (7 << FLASH_ACR_LATENCY_SHIFT) /* 111: Seven wait states */ + +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) +# define FLASH_ACR_HLFCYA (1 << 3) /* Bit 3: FLASH half cycle access */ +# define FLASH_ACR_PRTFBE (1 << 4) /* Bit 4: FLASH prefetch enable */ +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define FLASH_ACR_PRFTBS (1 << 5) /* Bit 5: FLASH prefetch buffer status */ +# endif +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define FLASH_ACR_PRFTEN (1 << 8) /* FLASH prefetch enable */ +# define FLASH_ACR_ICEN (1 << 9) /* Bit 9: Instruction cache enable */ +# define FLASH_ACR_DCEN (1 << 10) /* Bit 10: Data cache enable */ +# define FLASH_ACR_ICRST (1 << 11) /* Bit 11: Instruction cache reset */ +# define FLASH_ACR_DCRST (1 << 12) /* Bit 12: Data cache reset */ +# endif +#endif + +/* Flash Status Register (SR) */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) +# define FLASH_SR_BSY (1 << 0) /* Busy */ +# define FLASH_SR_PGERR (1 << 2) /* Programming Error */ +# define FLASH_SR_WRPRT_ERR (1 << 4) /* Write Protection Error */ +# define FLASH_SR_EOP (1 << 5) /* End of Operation */ +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define FLASH_SR_EOP (1 << 0) /* Bit 0: End of operation */ +# define FLASH_SR_OPERR (1 << 1) /* Bit 1: Operation error */ +# define FLASH_SR_WRPERR (1 << 4) /* Bit 4: Write protection error */ +# define FLASH_SR_PGAERR (1 << 5) /* Bit 5: Programming alignment error */ +# define FLASH_SR_PGPERR (1 << 6) /* Bit 6: Programming parallelism error */ +# define FLASH_SR_PGSERR (1 << 7) /* Bit 7: Programming sequence error */ +# define FLASH_SR_BSY (1 << 16) /* Bit 16: Busy */ +#endif + +/* Flash Control Register (CR) */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) +# define FLASH_CR_PG (1 << 0) /* Bit 0: Program Page */ +# define FLASH_CR_PER (1 << 1) /* Bit 1: Page Erase */ +# define FLASH_CR_MER (1 << 2) /* Bit 2: Mass Erase */ +# define FLASH_CR_OPTPG (1 << 4) /* Bit 4: Option Byte Programming */ +# define FLASH_CR_OPTER (1 << 5) /* Bit 5: Option Byte Erase */ +# define FLASH_CR_STRT (1 << 6) /* Bit 6: Start Erase */ +# define FLASH_CR_LOCK (1 << 7) /* Bit 7: Page Locked or Lock Page */ +# define FLASH_CR_OPTWRE (1 << 9) /* Bit 8: Option Bytes Write Enable */ +# define FLASH_CR_ERRIE (1 << 10) /* Bit 10: Error Interrupt Enable */ +# define FLASH_CR_EOPIE (1 << 12) /* Bit 12: End of Program Interrupt Enable */ +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define FLASH_CR_OBL_LAUNCH (1 << 13) /* Bit 13: Force option byte loading */ +# endif +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define FLASH_CR_PG (1 << 0) /* Bit 0: Programming */ +# define FLASH_CR_SER (1 << 1) /* Bit 1: Sector Erase */ +# define FLASH_CR_MER (1 << 2) /* Bit 2: Mass Erase sectors 0..11 */ +# define FLASH_CR_SNB_SHIFT (3) /* Bits 3-6: Sector number */ +# define FLASH_CR_SNB_MASK (15 << FLASH_CR_SNB_SHIFT) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define FLASH_CR_SNB(n) (((n % 12) << FLASH_CR_SNB_SHIFT) | ((n / 12) << 7)) /* Sector n, n=0..23 */ +#else +# define FLASH_CR_SNB(n) ((n) << FLASH_CR_SNB_SHIFT) /* Sector n, n=0..11 */ +#endif +# define FLASH_CR_PSIZE_SHIFT (8) /* Bits 8-9: Program size */ +# define FLASH_CR_PSIZE_MASK (3 << FLASH_CR_PSIZE_SHIFT) +# define FLASH_CR_PSIZE_X8 (0 << FLASH_CR_PSIZE_SHIFT) /* 00 program x8 */ +# define FLASH_CR_PSIZE_X16 (1 << FLASH_CR_PSIZE_SHIFT) /* 01 program x16 */ +# define FLASH_CR_PSIZE_X32 (2 << FLASH_CR_PSIZE_SHIFT) /* 10 program x32 */ +# define FLASH_CR_PSIZE_X64 (3 << FLASH_CR_PSIZE_SHIFT) /* 11 program x64 */ +# define FLASH_CR_STRT (1 << 16) /* Bit 16: Start Erase */ +# define FLASH_CR_EOPIE (1 << 24) /* Bit 24: End of operation interrupt enable */ +# define FLASH_CR_ERRIE (1 << 25) /* Bit 25: Error interrupt enable */ +# define FLASH_CR_LOCK (1 << 31) /* Bit 31: Lock */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define FLASH_CR_MER1 (1 << 15) /* Bit 15: Mass Erase sectors 12..23 */ +#endif + +/* Flash Option Control Register (OPTCR) */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define FLASH_OPTCR_OPTLOCK (1 << 0) /* Bit 0: Option lock */ +# define FLASH_OPTCR_OPTSTRT (1 << 1) /* Bit 1: Option start */ +# define FLASH_OPTCR_BORLEV_SHIFT (2) /* Bits 2-3: BOR reset Level */ +# define FLASH_OPTCR_BORLEV_MASK (3 << FLASH_OPTCR_BORLEV_SHIFT) +# define FLASH_OPTCR_VBOR3 (0 << FLASH_OPTCR_BORLEV_SHIFT) /* 00: BOR Level 3 */ +# define FLASH_OPTCR_VBOR2 (1 << FLASH_OPTCR_BORLEV_SHIFT) /* 01: BOR Level 2 */ +# define FLASH_OPTCR_VBOR1 (2 << FLASH_OPTCR_BORLEV_SHIFT) /* 10: BOR Level 1 */ +# define FLASH_OPTCR_VBOR0 (3 << FLASH_OPTCR_BORLEV_SHIFT) /* 11: BOR off */ +# define FLASH_OPTCR_USER_SHIFT (5) /* Bits 5-7: User option bytes */ +# define FLASH_OPTCR_USER_MASK (7 << FLASH_OPTCR_USER_SHIFT) +# define FLASH_OPTCR_NRST_STDBY (1 << 7) /* Bit 7: nRST_STDBY */ +# define FLASH_OPTCR_NRST_STOP (1 << 6) /* Bit 6: nRST_STOP */ +# define FLASH_OPTCR_WDG_SW (1 << 5) /* Bit 5: WDG_SW */ +# define FLASH_OPTCR_RDP_SHIFT (8) /* Bits 8-15: Read protect */ +# define FLASH_OPTCR_RDP_MASK (0xff << FLASH_OPTCR_RDP_SHIFT) +# define FLASH_OPTCR_NWRP_SHIFT (16) /* Bits 16-27: Not write protect */ +# define FLASH_OPTCR_NWRP_MASK (0xfff << FLASH_OPTCR_NWRP_SHIFT) +#endif + +/* Flash Option Control Register (OPTCR1) */ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define FLASH_OPTCR1_NWRP_SHIFT (16) /* Bits 16-27: Not write protect (high bank) */ +# define FLASH_OPTCR1_NWRP_MASK (0xfff << FLASH_OPTCR_NWRP_SHIFT) + +# define FLASH_OPTCR1_BFB2_SHIFT (4) /* Bits 4: Dual-bank Boot option byte */ +# define FLASH_OPTCR1_BFB2_MASK (1 << FLASH_OPTCR_NWRP_SHIFT) + +#endif + +#if defined(CONFIG_STM32_STM32F446) +# define FLASH_OPTCR1_NWRP_SHIFT (16) /* Bits 16-23: Not write protect (high bank) */ +# define FLASH_OPTCR1_NWRP_MASK (0xff << FLASH_OPTCR_NWRP_SHIFT) +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void stm32_flash_lock(void); +void stm32_flash_unlock(void); + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H */ diff --git a/arch/arm/src/stm32/chip/stm32_i2c.h b/arch/arm/src/stm32/chip/stm32_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..682059772c34bd562be1158db2ad43e567c5bdcb --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_i2c.h @@ -0,0 +1,213 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_i2c.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_I2C_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_I2C_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_I2C_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32_I2C_CR2_OFFSET 0x0004 /* Control register 2 (16-bit) */ +#define STM32_I2C_OAR1_OFFSET 0x0008 /* Own address register 1 (16-bit) */ +#define STM32_I2C_OAR2_OFFSET 0x000c /* Own address register 2 (16-bit) */ +#define STM32_I2C_DR_OFFSET 0x0010 /* Data register (16-bit) */ +#define STM32_I2C_SR1_OFFSET 0x0014 /* Status register 1 (16-bit) */ +#define STM32_I2C_SR2_OFFSET 0x0018 /* Status register 2 (16-bit) */ +#define STM32_I2C_CCR_OFFSET 0x001c /* Clock control register (16-bit) */ +#define STM32_I2C_TRISE_OFFSET 0x0020 /* TRISE Register (16-bit) */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) +# define STM32_I2C_FLTR_OFFSET 0x0024 /* FLTR Register (16-bit) */ +#endif + +/* Register Addresses ***************************************************************/ + +#if STM32_NI2C > 0 +# define STM32_I2C1_CR1 (STM32_I2C1_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C1_CR2 (STM32_I2C1_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C1_OAR1 (STM32_I2C1_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C1_OAR2 (STM32_I2C1_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C1_DR (STM32_I2C1_BASE+STM32_I2C_DR_OFFSET) +# define STM32_I2C1_SR1 (STM32_I2C1_BASE+STM32_I2C_SR1_OFFSET) +# define STM32_I2C1_SR2 (STM32_I2C1_BASE+STM32_I2C_SR2_OFFSET) +# define STM32_I2C1_CCR (STM32_I2C1_BASE+STM32_I2C_CCR_OFFSET) +# define STM32_I2C1_TRISE (STM32_I2C1_BASE+STM32_I2C_TRISE_OFFSET) +# ifdef STM32_I2C_FLTR_OFFSET +# define STM32_I2C1_FLTR (STM32_I2C1_BASE+STM32_I2C_FLTR_OFFSET) +# endif +#endif + +#if STM32_NI2C > 1 +# define STM32_I2C2_CR1 (STM32_I2C2_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C2_CR2 (STM32_I2C2_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C2_OAR1 (STM32_I2C2_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C2_OAR2 (STM32_I2C2_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C2_DR (STM32_I2C2_BASE+STM32_I2C_DR_OFFSET) +# define STM32_I2C2_SR1 (STM32_I2C2_BASE+STM32_I2C_SR1_OFFSET) +# define STM32_I2C2_SR2 (STM32_I2C2_BASE+STM32_I2C_SR2_OFFSET) +# define STM32_I2C2_CCR (STM32_I2C2_BASE+STM32_I2C_CCR_OFFSET) +# define STM32_I2C2_TRISE (STM32_I2C2_BASE+STM32_I2C_TRISE_OFFSET) +# ifdef STM32_I2C_FLTR_OFFSET +# define STM32_I2C2_FLTR (STM32_I2C2_BASE+STM32_I2C_FLTR_OFFSET) +# endif +#endif + +#if STM32_NI2C > 2 +# define STM32_I2C3_CR1 (STM32_I2C3_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C3_CR2 (STM32_I2C3_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C3_OAR1 (STM32_I2C3_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C3_OAR2 (STM32_I2C3_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C3_DR (STM32_I2C3_BASE+STM32_I2C_DR_OFFSET) +# define STM32_I2C3_SR1 (STM32_I2C3_BASE+STM32_I2C_SR1_OFFSET) +# define STM32_I2C3_SR2 (STM32_I2C3_BASE+STM32_I2C_SR2_OFFSET) +# define STM32_I2C3_CCR (STM32_I2C3_BASE+STM32_I2C_CCR_OFFSET) +# define STM32_I2C3_TRISE (STM32_I2C3_BASE+STM32_I2C_TRISE_OFFSET) +# ifdef STM32_I2C_FLTR_OFFSET +# define STM32_I2C3_FLTR (STM32_I2C3_BASE+STM32_I2C_FLTR_OFFSET) +# endif +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define I2C_CR1_PE (1 << 0) /* Bit 0: Peripheral Enable */ +#define I2C_CR1_SMBUS (1 << 1) /* Bit 1: SMBus Mode */ +#define I2C_CR1_SMBTYPE (1 << 3) /* Bit 3: SMBus Type */ +#define I2C_CR1_ENARP (1 << 4) /* Bit 4: ARP Enable */ +#define I2C_CR1_ENPEC (1 << 5) /* Bit 5: PEC Enable */ +#define I2C_CR1_ENGC (1 << 6) /* Bit 6: General Call Enable */ +#define I2C_CR1_NOSTRETCH (1 << 7) /* Bit 7: Clock Stretching Disable (Slave mode) */ +#define I2C_CR1_START (1 << 8) /* Bit 8: Start Generation */ +#define I2C_CR1_STOP (1 << 9) /* Bit 9: Stop Generation */ +#define I2C_CR1_ACK (1 << 10) /* Bit 10: Acknowledge Enable */ +#define I2C_CR1_POS (1 << 11) /* Bit 11: Acknowledge/PEC Position (for data reception) */ +#define I2C_CR1_PEC (1 << 12) /* Bit 12: Packet Error Checking */ +#define I2C_CR1_ALERT (1 << 13) /* Bit 13: SMBus Alert */ +#define I2C_CR1_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* Control register 2 */ + +#define I2C_CR2_FREQ_SHIFT (0) /* Bits 5-0: Peripheral Clock Frequency */ +#define I2C_CR2_FREQ_MASK (0x3f << I2C_CR2_FREQ_SHIFT) +#define I2C_CR2_ITERREN (1 << 8) /* Bit 8: Error Interrupt Enable */ +#define I2C_CR2_ITEVFEN (1 << 9) /* Bit 9: Event Interrupt Enable */ +#define I2C_CR2_ITBUFEN (1 << 10) /* Bit 10: Buffer Interrupt Enable */ +#define I2C_CR2_DMAEN (1 << 11) /* Bit 11: DMA Requests Enable */ +#define I2C_CR2_LAST (1 << 12) /* Bit 12: DMA Last Transfer */ + +#define I2C_CR2_ALLINTS (I2C_CR2_ITERREN|I2C_CR2_ITEVFEN|I2C_CR2_ITBUFEN) + +/* Own address register 1 */ + +#define I2C_OAR1_ADD0 (1 << 0) /* Bit 0: Interface Address */ +#define I2C_OAR1_ADD8_SHIFT (1) /* Bits 7-1: Interface Address */ +#define I2C_OAR1_ADD8_MASK (0x007f << I2C_OAR1_ADD8_SHIFT) +#define I2C_OAR1_ADD10_SHIFT (1) /* Bits 9-1: Interface Address (10-bit addressing mode)*/ +#define I2C_OAR1_ADD10_MASK (0x01ff << I2C_OAR1_ADD10_SHIFT) +#define I2C_OAR1_ONE (1 << 14) /* Bit 14: Must be configured and kept at 1 */ +#define I2C_OAR1_ADDMODE (1 << 15) /* Bit 15: Addressing Mode (Slave mode) */ + +/* Own address register 2 */ + +#define I2C_OAR2_ENDUAL (1 << 0) /* Bit 0: Dual addressing mode enable */ +#define I2C_OAR2_ADD2_SHIFT (1) /* Bits 7-1: Interface address */ +#define I2C_OAR2_ADD2_MASK (0x7f << I2C_OAR2_ADD2_SHIFT) + +/* Data register */ + +#define I2C_DR_SHIFT (0) /* Bits 7-0: 8-bit Data Register */ +#define I2C_DR_MASK (0x00ff << I2C_DR_SHIFT) + +/* Status register 1 */ + +#define I2C_SR1_SB (1 << 0) /* Bit 0: Start Bit (Master mode) */ +#define I2C_SR1_ADDR (1 << 1) /* Bit 1: Address sent (master mode)/matched (slave mode) */ +#define I2C_SR1_BTF (1 << 2) /* Bit 2: Byte Transfer Finished */ +#define I2C_SR1_ADD10 (1 << 3) /* Bit 3: 10-bit header sent (Master mode) */ +#define I2C_SR1_STOPF (1 << 4) /* Bit 4: Stop detection (Slave mode) */ + /* Bit 5: Reserved */ +#define I2C_SR1_RXNE (1 << 6) /* Bit 6: Data Register not Empty (receivers) */ +#define I2C_SR1_TXE (1 << 7) /* Bit 7: Data Register Empty (transmitters) */ +#define I2C_SR1_BERR (1 << 8) /* Bit 8: Bus Error */ +#define I2C_SR1_ARLO (1 << 9) /* Bit 9: Arbitration Lost (master mode) */ +#define I2C_SR1_AF (1 << 10) /* Bit 10: Acknowledge Failure */ +#define I2C_SR1_OVR (1 << 11) /* Bit 11: Overrun/Underrun */ +#define I2C_SR1_PECERR (1 << 12) /* Bit 12: PEC Error in reception */ + /* Bit 13: Reserved */ +#define I2C_SR1_TIMEOUT (1 << 14) /* Bit 14: Timeout or Tlow Error */ +#define I2C_SR1_SMBALERT (1 << 15) /* Bit 15: SMBus Alert */ + +#define I2C_SR1_ERRORMASK (I2C_SR1_BERR|I2C_SR1_ARLO|I2C_SR1_AF|I2C_SR1_OVR|\ + I2C_SR1_PECERR|I2C_SR1_TIMEOUT|I2C_SR1_SMBALERT) + +/* Status register 2 */ + +#define I2C_SR2_MSL (1 << 0) /* Bit 0: Master/Slave */ +#define I2C_SR2_BUSY (1 << 1) /* Bit 1: Bus Busy */ +#define I2C_SR2_TRA (1 << 2) /* Bit 2: Transmitter/Receiver */ +#define I2C_SR2_GENCALL (1 << 4) /* Bit 4: General Call Address (Slave mode) */ +#define I2C_SR2_SMBDEFAULT (1 << 5) /* Bit 5: SMBus Device Default Address (Slave mode) */ +#define I2C_SR2_SMBHOST (1 << 6) /* Bit 6: SMBus Host Header (Slave mode) */ +#define I2C_SR2_DUALF (1 << 7) /* Bit 7: Dual Flag (Slave mode) */ +#define I2C_SR2_PEC_SHIFT (8) /* Bits 15-8: Packet Error Checking Register */ +#define I2C_SR2_PEC_MASK (0xff << I2C_SR2_PEC_SHIFT) + +/* Clock control register */ + +#define I2C_CCR_CCR_SHIFT (0) /* Bits 11-0: Clock Control Register in Fast/Standard mode (Master mode) */ +#define I2C_CCR_CCR_MASK (0x0fff << I2C_CCR_CCR_SHIFT) +#define I2C_CCR_DUTY (1 << 14) /* Bit 14: Fast Mode Duty Cycle */ +#define I2C_CCR_FS (1 << 15) /* Bit 15: Fast Mode Selection */ + +/* TRISE Register */ + +#define I2C_TRISE_SHIFT (0) /* Bits 5-0: Maximum Rise Time in Fast/Standard mode (Master mode) */ +#define I2C_TRISE_MASK (0x3f << I2C_TRISE_SHIFT) + +/* FLTR Register */ + +#ifdef STM32_I2C_FLTR_OFFSET +# define I2C_FLTR_ANOFF (1 << 4) /* Bit 4: Analog noise filter disable */ +# define I2C_FLTR_DNF_SHIFT 0 /* Bits 0-3: Digital noise filter */ +# define I2C_FLTR_DNF_MASK (0xf << I2C_FLTR_DNF_SHIFT) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_I2C_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_lcd.h b/arch/arm/src/stm32/chip/stm32_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..70d6be548941ae2016464a23b9a7397444173ab6 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_lcd.h @@ -0,0 +1,213 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_lcd.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32_LCD_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32_LCD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/* These definitions are valid only if the MCU supports a segment LCD */ + +#if STM32_NLCD > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_LCD_CR_OFFSET 0x0000 /* LCD control register */ +#define STM32_LCD_FCR_OFFSET 0x0004 /* LCD frame control register */ +#define STM32_LCD_SR_OFFSET 0x0008 /* LCD status register */ +#define STM32_LCD_CLR_OFFSET 0x000c /* LCD clear register */ + +#define STM32_LCD_RAM_OFFSET(n) (0x0014 + ((n) << 3)) /* LCD display memory, COMn */ +#define STM32_LCD_RAML_OFFSET(n) (0x0014 + ((n) << 3)) /* LCD display memory, COMn, S00-S31 */ +#define STM32_LCD_RAMH_OFFSET(n) (0x0018 + ((n) << 3)) /* LCD display memory, COMn, S32-S39 */ + +#define STM32_LCD_RAM0L_OFFSET 0x0014 /* LCD display memory, COM0, S00-S31 */ +#define STM32_LCD_RAM0H_OFFSET 0x0018 /* LCD display memory, COM0, S32-S39 */ +#define STM32_LCD_RAM1L_OFFSET 0x001c /* LCD display memory, COM1, S00-S31 */ +#define STM32_LCD_RAM1H_OFFSET 0x0020 /* LCD display memory, COM1, S32-S39 */ +#define STM32_LCD_RAM2L_OFFSET 0x0024 /* LCD display memory, COM2, S00-S31 */ +#define STM32_LCD_RAM2H_OFFSET 0x0028 /* LCD display memory, COM2, S32-S39 */ +#define STM32_LCD_RAM3L_OFFSET 0x002c /* LCD display memory, COM3, S00-S31 */ +#define STM32_LCD_RAM3H_OFFSET 0x0020 /* LCD display memory, COM3, S32-S39 */ +#define STM32_LCD_RAM4L_OFFSET 0x0034 /* LCD display memory, COM4, S00-S31 */ +#define STM32_LCD_RAM4H_OFFSET 0x0038 /* LCD display memory, COM4, S32-S39 */ +#define STM32_LCD_RAM5L_OFFSET 0x003c /* LCD display memory, COM5, S00-S31 */ +#define STM32_LCD_RAM5H_OFFSET 0x0040 /* LCD display memory, COM5, S32-S39 */ +#define STM32_LCD_RAM6L_OFFSET 0x0044 /* LCD display memory, COM6, S00-S31 */ +#define STM32_LCD_RAM6H_OFFSET 0x0048 /* LCD display memory, COM6, S32-S39 */ +#define STM32_LCD_RAM7L_OFFSET 0x004c /* LCD display memory, COM7, S00-S31 */ +#define STM32_LCD_RAM7H_OFFSET 0x0050 /* LCD display memory, COM7, S32-S39 */ + +/* Register Addresses ***************************************************************/ + +#define STM32_LCD_CR (STM32_LCD_BASE+STM32_LCD_CR_OFFSET) +#define STM32_LCD_FCR (STM32_LCD_BASE+STM32_LCD_FCR_OFFSET) +#define STM32_LCD_SR (STM32_LCD_BASE+STM32_LCD_SR_OFFSET) +#define STM32_LCD_CLR (STM32_LCD_BASE+STM32_LCD_CLR_OFFSET) + +#define STM32_LCD_RAM(n) (STM32_LCD_BASE+STM32_LCD_RAM_OFFSET(n)) +#define STM32_LCD_RAML(n) (STM32_LCD_BASE+STM32_LCD_RAML_OFFSET(n)) +#define STM32_LCD_RAMH(n) (STM32_LCD_BASE+STM32_LCD_RAMH_OFFSET(n)) + +#define STM32_LCD_RAM0L (STM32_LCD_BASE+STM32_LCD_RAM0L_OFFSET) +#define STM32_LCD_RAM0H (STM32_LCD_BASE+STM32_LCD_RAM0H_OFFSET) +#define STM32_LCD_RAM1L (STM32_LCD_BASE+STM32_LCD_RAM1L_OFFSET) +#define STM32_LCD_RAM1H (STM32_LCD_BASE+STM32_LCD_RAM1H_OFFSET) +#define STM32_LCD_RAM2L (STM32_LCD_BASE+STM32_LCD_RAM2L_OFFSET) +#define STM32_LCD_RAM2H (STM32_LCD_BASE+STM32_LCD_RAM2H_OFFSET) +#define STM32_LCD_RAM3L (STM32_LCD_BASE+STM32_LCD_RAM3L_OFFSET) +#define STM32_LCD_RAM3H (STM32_LCD_BASE+STM32_LCD_RAM3H_OFFSET) +#define STM32_LCD_RAM4L (STM32_LCD_BASE+STM32_LCD_RAM4L_OFFSET) +#define STM32_LCD_RAM4H (STM32_LCD_BASE+STM32_LCD_RAM4H_OFFSET) +#define STM32_LCD_RAM5L (STM32_LCD_BASE+STM32_LCD_RAM5L_OFFSET) +#define STM32_LCD_RAM5H (STM32_LCD_BASE+STM32_LCD_RAM5H_OFFSET) +#define STM32_LCD_RAM6L (STM32_LCD_BASE+STM32_LCD_RAM6L_OFFSET) +#define STM32_LCD_RAM6H (STM32_LCD_BASE+STM32_LCD_RAM6H_OFFSET) +#define STM32_LCD_RAM7L (STM32_LCD_BASE+STM32_LCD_RAM7L_OFFSET) +#define STM32_LCD_RAM7H (STM32_LCD_BASE+STM32_LCD_RAM7H_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* LCD control register */ + +#define LCD_CR_LCDEN (1 << 0) /* Bit 0: LCD controller enable */ +#define LCD_CR_VSEL (1 << 1) /* Bit 1: Voltage source selection */ +#define LCD_CR_DUTY_SHIFT (2) /* Bits 2-4: Duty selection */ +#define LCD_CR_DUTY_MASK (7 << LCD_CR_DUTY_SHIFT) +# define LCD_CR_DUTY_STATIC (0 << LCD_CR_DUTY_SHIFT) /* 000: Static duty */ +# define LCD_CR_DUTY_1TO2 (1 << LCD_CR_DUTY_SHIFT) /* 001: 1/2 duty */ +# define LCD_CR_DUTY_1TO3 (2 << LCD_CR_DUTY_SHIFT) /* 010: 1/3 duty */ +# define LCD_CR_DUTY_1TO4 (3 << LCD_CR_DUTY_SHIFT) /* 011: 1/4 duty */ +# define LCD_CR_DUTY_1TO8 (4 << LCD_CR_DUTY_SHIFT) /* 100: 1/8 duty */ +#define LCD_CR_BIAS_SHIFT (5) /* Bits 5-6: Bias selector */ +#define LCD_CR_BIAS_MASK (3 << LCD_CR_BIAS_SHIFT) +# define LCD_CR_BIAS_1TO4 (0 << LCD_CR_BIAS_SHIFT) /* 00: Bias 1/4 */ +# define LCD_CR_BIAS_1TO2 (1 << LCD_CR_BIAS_SHIFT) /* 01: Bias 1/2 */ +# define LCD_CR_BIAS_1TO3 (2 << LCD_CR_BIAS_SHIFT) /* 10: Bias 1/3 */ +#define LCD_CR_MUX_SEG (1 << 7) /* Bit 7: Mux segment enable */ + /* Bits 8-31 Reserved */ + +/* LCD frame control register */ + +#define LCD_FCR_HD (1 << 0) /* Bit 0: High drive enable */ +#define LCD_FCR_SOFIE (1 << 1) /* Bit 1: Start of frame interrupt enable */ + /* Bit 2 Reserved */ +#define LCD_FCR_UDDIE (1 << 3) /* Bit 3: Update display done interrupt enable */ +#define LCD_FCR_PON_SHIFT (4) /* Bits 4-6: Pulse ON duration */ +#define LCD_FCR_PON_MASK (7 << LCD_FCR_PON_SHIFT) +# define LCD_FCR_PON(n) ((n) << LCD_FCR_PON_SHIFT) /* n=0-7 */ +#define LCD_FCR_DEAD_SHIFT (7) /* Bits 7-9: Dead time duration */ +#define LCD_FCR_DEAD_MASK (7 << LCD_FCR_DEAD_SHIFT) +# define LCD_FCR_DEAD_NONE (0 << LCD_FCR_DEAD_SHIFT) +# define LCD_FCR_DEAD(n) ((n) << LCD_FCR_DEAD_SHIFT) /* n=1..7 */ +#define LCD_FCR_CC_SHIFT (10) /* Bits 10-12: Contrast control */ +#define LCD_FCR_CC_MASK (7 << LCD_FCR_CC_SHIFT) +# define LCD_FCR_CC_VLCD(n) ((n) << LCD_FCR_CC_SHIFT) /* VLCDn, n=0..7 */ +#define LCD_FCR_BLINKF_SHIFT (13) /* Bits 13-15: Blink frequency selection */ +#define LCD_FCR_BLINKF_MASK (7 << LCD_FCR_BLINKF_SHIFT) +# define LCD_FCR_BLINKF_DIV8 (0 << LCD_FCR_BLINKF_SHIFT) /* 000: fLCD/8 */ +# define LCD_FCR_BLINKF_DIV16 (1 << LCD_FCR_BLINKF_SHIFT) /* 001: fLCD/16 */ +# define LCD_FCR_BLINKF_DIV32 (2 << LCD_FCR_BLINKF_SHIFT) /* 010: fLCD/32 */ +# define LCD_FCR_BLINKF_DIV64 (3 << LCD_FCR_BLINKF_SHIFT) /* 011: fLCD/64 */ +# define LCD_FCR_BLINKF_DIV128 (4 << LCD_FCR_BLINKF_SHIFT) /* 100: fLCD/128 */ +# define LCD_FCR_BLINKF_DIV256 (5 << LCD_FCR_BLINKF_SHIFT) /* 101: fLCD/256 */ +# define LCD_FCR_BLINKF_DIV512 (6 << LCD_FCR_BLINKF_SHIFT) /* 110: fLCD/512 */ +# define LCD_FCR_BLINKF_DIV1024 (7 << LCD_FCR_BLINKF_SHIFT) /* 111: fLCD/1024 */ +#define LCD_FCR_BLINK_SHIFT (16) /* Bits 16-17: Blink mode selection */ +#define LCD_FCR_BLINK_MASK (3 << LCD_FCR_BLINK_SHIFT) +# define LCD_FCR_BLINK_DISABLE (0 << LCD_FCR_BLINK_SHIFT) /* 00: Blink disabled */ +# define LCD_FCR_BLINK_S0C0 (1 << LCD_FCR_BLINK_SHIFT) /* 01: Blink enabled on SEG[0], COM[0] (1 pixel) */ +# define LCD_FCR_BLINK_S0CALL (2 << LCD_FCR_BLINK_SHIFT) /* 10: Blink enabled on SEG[0], all COMs */ +# define LCD_FCR_BLINK_SALLCALL (3 << LCD_FCR_BLINK_SHIFT) /* 11: Blink enabled on all SEGs and all COMs */ +#define LCD_FCR_DIV_SHIFT (18) /* Bits 18-21: DIV clock divider */ +#define LCD_FCR_DIV_MASK (15 << LCD_FCR_DIV_SHIFT) +# define LCD_FCR_DIV(n) (((n)-16) << LCD_FCR_DIV_SHIFT) /* n=16-31 */ +#define LCD_FCR_PS_SHIFT (22) /* Bits 22-25: PS 16-bit prescaler */ +#define LCD_FCR_PS_MASK (15 << LCD_FCR_PS_SHIFT) +# define LCD_FCR_PS_DIV1 (0 << LCD_FCR_PS_SHIFT) /* 0000: ck_ps = LCDCLK */ +# define LCD_FCR_PS_DIV2 (1 << LCD_FCR_PS_SHIFT) /* 0001: ck_ps = LCDCLK/2 */ +# define LCD_FCR_PS_DIV4 (2 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/4 */ +# define LCD_FCR_PS_DIV8 (3 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/8 */ +# define LCD_FCR_PS_DIV16 (4 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/16 */ +# define LCD_FCR_PS_DIV32 (5 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/32 */ +# define LCD_FCR_PS_DIV64 (6 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/64 */ +# define LCD_FCR_PS_DIV128 (7 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/128 */ +# define LCD_FCR_PS_DIV256 (8 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/256 */ +# define LCD_FCR_PS_DIV512 (9 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/512 */ +# define LCD_FCR_PS_DIV1024 (10 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/1024 */ +# define LCD_FCR_PS_DIV2048 (11 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/2048 */ +# define LCD_FCR_PS_DIV4096 (12 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/4096 */ +# define LCD_FCR_PS_DIV8192 (13 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/8192 */ +# define LCD_FCR_PS_DIV16384 (14 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/16384 */ +# define LCD_FCR_PS_DIV32768 (15 << LCD_FCR_PS_SHIFT) /* 0011: ck_ps = LCDCLK/32768 */ + /* Bits 26-31 Reserved */ + +/* LCD status register */ + +#define LCD_SR_ENS (1 << 0) /* Bit 0: LCD enabled status */ +#define LCD_SR_SOF (1 << 1) /* Bit 1: Start of frame flag */ +#define LCD_SR_UDR (1 << 2) /* Bit 2: Update display request */ +#define LCD_SR_UDD (1 << 3) /* Bit 3: Update Display Done */ +#define LCD_SR_RDY (1 << 4) /* Bit 4: Ready flag */ +#define LCD_SR_FCRSF (1 << 5) /* Bit 5: LCD Frame Control Register Synchronization flag */ + /* Bits 6-31 Reserved */ + +/* LCD clear register */ + + /* Bit 0 Reserved */ +#define LCD_CLR_SOFC (1 << 1) /* Bit 1: Start of frame flag clear */ + /* Bit 2 Reserved */ +#define LCD_CLR_UDDC (1 << 2) /* Bit 3: Update display done clear */ + /* Bits 31:2-31 Reserved */ + +/* LCD display memory, COMn, S00-S31 */ + +#define LCD_RAML_S(n) (1 << (n)) + +/* LCD display memory, COMn, S32-S39 */ + +#define LCD_RAMH_S(n) (1 << ((n)-32)) + +#endif /* STM32_NLCD */ +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32_LCD_H */ diff --git a/arch/arm/src/stm32/chip/stm32_ltdc.h b/arch/arm/src/stm32/chip/stm32_ltdc.h new file mode 100644 index 0000000000000000000000000000000000000000..8ae45ddaa4d1234e6b536eedc562d98b5d288d9c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_ltdc.h @@ -0,0 +1,381 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_ltdc.h + * + * Copyright (C) 2013 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_LTDC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_LTDC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip/stm32_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_LTDC_NCLUT 256 /* Number of entries in the CLUTs */ + +/* LCDC Register Offsets ************************************************************/ + +#define STM32_LTDC_SSCR_OFFSET 0x0008 /* LTDC Synchronization Size Config Register */ +#define STM32_LTDC_BPCR_OFFSET 0x000c /* LTDC Back Porch Configuration Register */ +#define STM32_LTDC_AWCR_OFFSET 0x0010 /* LTDC Active Width Configuration Register */ +#define STM32_LTDC_TWCR_OFFSET 0x0014 /* LTDC Total Width Configuration Register */ +#define STM32_LTDC_GCR_OFFSET 0x0018 /* LTDC Global Control Register */ + /* 0x0020 Reserved */ +#define STM32_LTDC_SRCR_OFFSET 0x0024 /* LTDC Shadow Reload Configuration Register */ + /* 0x0028 Reserved */ +#define STM32_LTDC_BCCR_OFFSET 0x002C /* LTDC Background Color Configuration Register */ + /* 0x0030 Reserved */ +#define STM32_LTDC_IER_OFFSET 0x0034 /* LTDC Interrupt Enable Register */ +#define STM32_LTDC_ISR_OFFSET 0x0038 /* LTDC Interrupt Status Register */ +#define STM32_LTDC_ICR_OFFSET 0x003C /* LTDC Interrupt Clear Register */ +#define STM32_LTDC_LIPCR_OFFSET 0x0040 /* LTDC Line Interrupt Position Config Register */ +#define STM32_LTDC_CPSR_OFFSET 0x0044 /* LTDC Current Position Status Register */ +#define STM32_LTDC_CDSR_OFFSET 0x0048 /* LTDC Current Display Status Register */ + /* 0x004c-0x0080 Reserved */ + +#define STM32_LTDC_L1CR_OFFSET 0x0084 /* LTDC Layer 1 Control Register */ +#define STM32_LTDC_L1WHPCR_OFFSET 0x0088 /* LTDC Layer 1 Window Horiz Pos Config Register */ +#define STM32_LTDC_L1WVPCR_OFFSET 0x008C /* LTDC Layer 1 Window Vert Pos Config Register */ +#define STM32_LTDC_L1CKCR_OFFSET 0x0090 /* LTDC Layer 1 Color Keying Config Register */ +#define STM32_LTDC_L1PFCR_OFFSET 0x0094 /* LTDC Layer 1 Pixel Format Configuration Register */ +#define STM32_LTDC_L1CACR_OFFSET 0x0098 /* LTDC Layer 1 Constant Alpha Config Register */ +#define STM32_LTDC_L1DCCR_OFFSET 0x009C /* LTDC Layer 1 Default Color Config Register */ +#define STM32_LTDC_L1BFCR_OFFSET 0x00A0 /* LTDC Layer 1 Blending Factors Config Register */ + /* 0x00A4-0x00A8 Reserved */ +#define STM32_LTDC_L1CFBAR_OFFSET 0x00AC /* LTDC Layer 1 Color Frame Buffer Address Register */ +#define STM32_LTDC_L1CFBLR_OFFSET 0x00B0 /* LTDC Layer 1 Color Frame Buffer Length Register */ +#define STM32_LTDC_L1CFBLNR_OFFSET 0x00B4 /* LTDC Layer 1 Color Frame Buffer Line Number Register */ + /* 0x00B8-0x00C0 Reserved */ +#define STM32_LTDC_L1CLUTWR_OFFSET 0x00C4 /* LTDC Layer 1 CLUT Write Register */ + /* 0x00C8-0x0100 Reserved */ +#define STM32_LTDC_L2CR_OFFSET 0x0104 /* LTDC Layer 2 Control Register */ +#define STM32_LTDC_L2WHPCR_OFFSET 0x0108 /* LTDC Layer 2 Window Horiz Pos Config Register */ +#define STM32_LTDC_L2WVPCR_OFFSET 0x010C /* LTDC Layer 2 Window Vert Pos Config Register */ +#define STM32_LTDC_L2CKCR_OFFSET 0x0110 /* LTDC Layer 2 Color Keying Config Register */ +#define STM32_LTDC_L2PFCR_OFFSET 0x0114 /* LTDC Layer 2 Pixel Format Configuration Register */ +#define STM32_LTDC_L2CACR_OFFSET 0x0118 /* LTDC Layer 2 Constant Alpha Config Register */ +#define STM32_LTDC_L2DCCR_OFFSET 0x011C /* LTDC Layer 2 Default Color Config Register */ +#define STM32_LTDC_L2BFCR_OFFSET 0x0120 /* LTDC Layer 2 Blending Factors Config Register */ + /* 0x0124-0x0128 Reserved */ +#define STM32_LTDC_L2CFBAR_OFFSET 0x012C /* LTDC Layer 2 Color Frame Buffer Address Register */ +#define STM32_LTDC_L2CFBLR_OFFSET 0x0130 /* LTDC Layer 2 Color Frame Buffer Length Register */ +#define STM32_LTDC_L2CFBLNR_OFFSET 0x0134 /* LTDC Layer 2 Color Frame Buffer Line Number Register */ + /* 0x0138-0x0130 Reserved */ +#define STM32_LTDC_L2CLUTWR_OFFSET 0x0144 /* LTDC Layer 2 CLUT Write Register */ + /* 0x0148-0x03ff Reserved */ + +/* LTDC Register Addresses *********************************************************/ + +#define STM32_LTDC_SSCR (STM32_LTDC_BASE+STM32_LTDC_SSCR_OFFSET) +#define STM32_LTDC_BPCR (STM32_LTDC_BASE+STM32_LTDC_BPCR_OFFSET) +#define STM32_LTDC_AWCR (STM32_LTDC_BASE+STM32_LTDC_AWCR_OFFSET) +#define STM32_LTDC_TWCR (STM32_LTDC_BASE+STM32_LTDC_TWCR_OFFSET) +#define STM32_LTDC_GCR (STM32_LTDC_BASE+STM32_LTDC_GCR_OFFSET) +#define STM32_LTDC_SRCR (STM32_LTDC_BASE+STM32_LTDC_SRCR_OFFSET) +#define STM32_LTDC_BCCR (STM32_LTDC_BASE+STM32_LTDC_BCCR_OFFSET) +#define STM32_LTDC_IER (STM32_LTDC_BASE+STM32_LTDC_IER_OFFSET) +#define STM32_LTDC_ISR (STM32_LTDC_BASE+STM32_LTDC_ISR_OFFSET) +#define STM32_LTDC_ICR (STM32_LTDC_BASE+STM32_LTDC_ICR_OFFSET) +#define STM32_LTDC_LIPCR (STM32_LTDC_BASE+STM32_LTDC_LIPCR_OFFSET) +#define STM32_LTDC_CPSR (STM32_LTDC_BASE+STM32_LTDC_CPSR_OFFSET) +#define STM32_LTDC_CDSR (STM32_LTDC_BASE+STM32_LTDC_CDSR_OFFSET) + +#define STM32_LTDC_L1CR (STM32_LTDC_BASE+STM32_LTDC_L1CR_OFFSET) +#define STM32_LTDC_L1WHPCR (STM32_LTDC_BASE+STM32_LTDC_L1WHPCR_OFFSET) +#define STM32_LTDC_L1WVPCR (STM32_LTDC_BASE+STM32_LTDC_L1WVPCR_OFFSET) +#define STM32_LTDC_L1CKCR (STM32_LTDC_BASE+STM32_LTDC_L1CKCR_OFFSET) +#define STM32_LTDC_L1PFCR (STM32_LTDC_BASE+STM32_LTDC_L1PFCR_OFFSET) +#define STM32_LTDC_L1CACR (STM32_LTDC_BASE+STM32_LTDC_L1CACR_OFFSET) +#define STM32_LTDC_L1DCCR (STM32_LTDC_BASE+STM32_LTDC_L1DCCR_OFFSET) +#define STM32_LTDC_L1BFCR (STM32_LTDC_BASE+STM32_LTDC_L1BFCR_OFFSET) +#define STM32_LTDC_L1CFBAR (STM32_LTDC_BASE+STM32_LTDC_L1CFBAR_OFFSET) +#define STM32_LTDC_L1CFBLR (STM32_LTDC_BASE+STM32_LTDC_L1CFBLR_OFFSET) +#define STM32_LTDC_L1CFBLNR (STM32_LTDC_BASE+STM32_LTDC_L1CFBLNR_OFFSET) +#define STM32_LTDC_L1CLUTWR (STM32_LTDC_BASE+STM32_LTDC_L1CLUTWR_OFFSET) + +#define STM32_LTDC_L2CR (STM32_LTDC_BASE+STM32_LTDC_L2CR_OFFSET) +#define STM32_LTDC_L2WHPCR (STM32_LTDC_BASE+STM32_LTDC_L2WHPCR_OFFSET) +#define STM32_LTDC_L2WVPCR (STM32_LTDC_BASE+STM32_LTDC_L2WVPCR_OFFSET) +#define STM32_LTDC_L2CKCR (STM32_LTDC_BASE+STM32_LTDC_L2CKCR_OFFSET) +#define STM32_LTDC_L2PFCR (STM32_LTDC_BASE+STM32_LTDC_L2PFCR_OFFSET) +#define STM32_LTDC_L2CACR (STM32_LTDC_BASE+STM32_LTDC_L2CACR_OFFSET) +#define STM32_LTDC_L2DCCR (STM32_LTDC_BASE+STM32_LTDC_L2DCCR_OFFSET) +#define STM32_LTDC_L2BFCR (STM32_LTDC_BASE+STM32_LTDC_L2BFCR_OFFSET) +#define STM32_LTDC_L2CFBAR (STM32_LTDC_BASE+STM32_LTDC_L2CFBAR_OFFSET) +#define STM32_LTDC_L2CFBLR (STM32_LTDC_BASE+STM32_LTDC_L2CFBLR_OFFSET) +#define STM32_LTDC_L2CFBLNR (STM32_LTDC_BASE+STM32_LTDC_L2CFBLNR_OFFSET) +#define STM32_LTDC_L2CLUTWR (STM32_LTDC_BASE+STM32_LTDC_L2CLUTWR_OFFSET) + +/* LTDC Register Bit Definitions ***************************************************/ + +/* LTDC Synchronization Size Configuration Register */ + +#define LTDC_SSCR_VSH_SHIFT (0) /* Bits 0-10: Vertical Sync Height (scan lines) */ +#define LTDC_SSCR_VSH_MASK (0x7ff << LTDC_SSCR_VSH_SHIFT) +# define LTDC_SSCR_VSH(n) ((uint32_t)(n) << LTDC_SSCR_VSH_SHIFT) +#define LTDC_SSCR_HSW_SHIFT (16) /* Bits 16-27: Horizontal Sync Width (pixel clocks) */ +#define LTDC_SSCR_HSW_MASK (0xfff << LTDC_SSCR_HSW_SHIFT) +# define LTDC_SSCR_HSW(n) ((uint32_t)(n) << LTDC_SSCR_HSW_SHIFT) + +/* LTDC Back Porch Configuration Register */ + +#define LTDC_BPCR_AVBP_SHIFT (0) /* Bits 0-10: Accumulated Vertical back porch (scan lines) */ +#define LTDC_BPCR_AVBP_MASK (0x7ff << LTDC_BPCR_AVBP_SHIFT) +# define LTDC_BPCR_AVBP(n) ((uint32_t)(n) << LTDC_BPCR_AVBP_SHIFT) +#define LTDC_BPCR_AHBP_SHIFT (16) /* Bits 16-27: Accumulated Horizontal back porch (pixel clocks) */ +#define LTDC_BPCR_AHBP_MASK (0xfff << LTDC_BPCR_AVBP_SHIFT) +# define LTDC_BPCR_AHBP(n) ((uint32_t)(n) << LTDC_BPCR_AHBP_SHIFT) + +/* LTDC Active Width Configuration Register */ + +#define LTDC_AWCR_AAH_SHIFT (0) /* Bits 0-10: Accumulated Active Height (scan lines) */ +#define LTDC_AWCR_AAH_MASK (0x7ff << LTDC_AWCR_AAH_SHIFT) +# define LTDC_AWCR_AAH(n) ((uint32_t)(n) << LTDC_AWCR_AAH_SHIFT) +#define LTDC_AWCR_AAW_SHIFT (16) /* Bits 16-27: Accumulated Active Width (pixel clocks) */ +#define LTDC_AWCR_AAW_MASK (0xfff << LTDC_AWCR_AAW_SHIFT) +# define LTDC_AWCR_AAW(n) ((uint32_t)(n) << LTDC_AWCR_AAW_SHIFT) + +/* LTDC Total Width Configuration Register */ + +#define LTDC_TWCR_TOTALH_SHIFT (0) /* Bits 0-10: Total Height (scan lines) */ +#define LTDC_TWCR_TOTALH_MASK (0x7ff << LTDC_TWCR_TOTALH_SHIFT) +# define LTDC_TWCR_TOTALH(n) ((uint32_t)(n) << LTDC_TWCR_TOTALH_SHIFT) +#define LTDC_TWCR_TOTALW_SHIFT (16) /* Bits 16-27: Total Width (pixel clocks) */ +#define LTDC_TWCR_TOTALW_MASK (0xfff << LTDC_TWCR_TOTALW_SHIFT) +# define LTDC_TWCR_TOTALW(n) ((uint32_t)(n) << LTDC_TWCR_TOTALW_SHIFT) + +/* LTDC Global Control Register */ + +#define LTDC_GCR_LTDCEN (1 << 0) /* Bit 0: LCD-TFT Controller Enable Bit */ +#define LTDC_GCR_DBW_SHIFT (4) /* Bits 4-6: Dither Blue Width */ +#define LTDC_GCR_DBW_MASK (0x7 << LTDC_GCR_DBW_SHIFT) +# define LTDC_GCR_DBW(n) ((uint32_t)(n) << LTDC_GCR_DBW_SHIFT) +#define LTDC_GCR_DGW_SHIFT (8) /* Bits 8-10: Dither Green Width */ +#define LTDC_GCR_DGW_MASK (0x7 << LTDC_GCR_DGW_SHIFT) +# define LTDC_GCR_DGW(n) ((uint32_t)(n) << LTDC_GCR_DGW_SHIFT) +#define LTDC_GCR_DRW_SHIFT (12) /* Bits 12-14: Dither Red Width */ +#define LTDC_GCR_DRW_MASK (0x7 << LTDC_GCR_DRW_SHIFT) +# define LTDC_GCR_DRW(n) ((uint32_t)(n) << LTDC_GCR_DRW_SHIFT) +#define LTDC_GCR_DEN (1 << 16) /* Bit 16: Dither Enable */ +#define LTDC_GCR_PCPOL (1 << 28) /* Bit 28: Pixel Clock Polarity */ +#define LTDC_GCR_DEPOL (1 << 29) /* Bit 29: Data Enable Polarity */ +#define LTDC_GCR_VSPOL (1 << 30) /* Bit 30: Vertical Sync Polarity */ +#define LTDC_GCR_HSPOL (1 << 31) /* Bit 31: Horizontal Sync Polarity */ + +/* LTDC Shadow Reload Configuration Register */ + +#define LTDC_SRCR_IMR (1 << 0) /* Bit 0: Immediate Reload */ +#define LTDC_SRCR_VBR (1 << 1) /* Bit 1: Vertical Blanking Reload */ + +/* LTDC Background Color Configuration Register */ + +#define LTDC_BCCR_BCBLUE_SHIFT (0) /* Bits 0-7: Background Color Blue Value */ +#define LTDC_BCCR_BCBLUE_MASK (0xFF << LTDC_BCCR_BCBLUE_SHIFT) +# define LTDC_BCCR_BCBLUE(n) ((uint32_t)(n) << LTDC_BCCR_BCBLUE_SHIFT) +#define LTDC_BCCR_BCGREEN_SHIFT (8) /* Bits 8-15: Background Color Green Value */ +#define LTDC_BCCR_BCGREEN_MASK (0xFF << LTDC_BCCR_BCGREEN_SHIFT) +# define LTDC_BCCR_BCGREEN(n) ((uint32_t)(n) << LTDC_BCCR_BCGREEN_SHIFT) +#define LTDC_BCCR_BCRED_SHIFT (16) /* Bits 16-23: Background Color Red Value */ +#define LTDC_BCCR_BCRED_MASK (0xFF << LTDC_BCCR_BCRED_SHIFT) +# define LTDC_BCCR_BCRED(n) ((uint32_t)(n) << LTDC_BCCR_BCRED_SHIFT) + +/* LTDC Interrupt Enable Register */ + +#define LTDC_IER_LIE (1 << 0) /* Bit 0: Line Interrupt Enable */ +#define LTDC_IER_FUIE (1 << 1) /* Bit 1: FIFO Underrun Interrupt Enable */ +#define LTDC_IER_TERRIE (1 << 2) /* Bit 2: Transfer Error Interrupt Enable */ +#define LTDC_IER_RRIE (1 << 3) /* Bit 3: Register Reload Interrupt Enable */ + +/* LTDC Interrupt Status Register */ + +#define LTDC_ISR_LIF (1 << 0) /* Bit 0: Line Interrupt Flag */ +#define LTDC_ISR_FUIF (1 << 1) /* Bit 1: FIFO Underrun Interrupt Flag */ +#define LTDC_IER_TERRIF (1 << 2) /* Bit 2: Transfer Error Interrupt Flag */ +#define LTDC_ISR_RRIF (1 << 3) /* Bit 3: Register Reload Interrupt Flag */ + +/* LTDC Interrupt Clear Register */ + +#define LTDC_ICR_CLIF (1 << 0) /* Bit 0: Clear Line Interrupt Flag */ +#define LTDC_ICR_CFUIF (1 << 1) /* Bit 1: Clear FIFO Underrun Interrupt Flag */ +#define LTDC_ICR_CTERRIF (1 << 2) /* Bit 2: Clear Transfer Error Interrupt Flag */ +#define LTDC_ICR_CRRIF (1 << 3) /* Bit 3: Clear Register Reload Interrupt Flag */ + +/* LTDC Line Interrupt Posittion Configuration Register */ + +#define LTDC_LIPCR_LIPOS_SHIFT (0) /* Bits 0-10: Line Interrupt Position */ +#define LTDC_LIPCR_LIPOS_MASK (0x7FF << LTDC_LIPCR_LIPOS_SHIFT) +# define LTDC_LIPCR_LIPOS(n) ((uint32_t)(n) << LTDC_LIPCR_LIPOS_SHIFT) + +/* LTDC Current Position Status Register */ + +#define LTDC_CPSR_CYPOS_SHIFT (0) /* Bits 0-15: Current Y Position */ +#define LTDC_CPSR_CYPOS_MASK (0xFFFF << LTDC_CPSR_CYPOS_SHIFT) +# define LTDC_CPSR_CYPOS(n) ((uint32_t)(n) << LTDC_CPSR_CYPOS_SHIFT) +#define LTDC_CPSR_CXPOS_SHIFT (16) /* Bits 15-31: Current X Position */ +#define LTDC_CPSR_CXPOS_MASK (0xFFFF << LTDC_CPSR_CXPOS_SHIFT) +# define LTDC_CPSR_CXPOS(n) ((uint32_t)(n) << LTDC_CPSR_CXPOS_SHIFT) + +/* LTDC Current Display Status Register */ + +#define LTDC_CDSR_VDES (1 << 0) /* Bit 0: Vertical Data Enable display Status */ +#define LTDC_CDSR_HDES (1 << 1) /* Bit 1: Horizontal Data Enable display Status */ +#define LTDC_CDSR_VSYNCS (1 << 2) /* Bit 2: Vertical Sync display Status */ +#define LTDC_CDSR_HSYNCS (1 << 3) /* Bit 3: Horizontal Sync display Status */ + +/* LTDC Layer x Control Register */ + +#define LTDC_LxCR_LEN (1 << 0) /* Bit 0: Layer Enable */ +#define LTDC_LxCR_COLKEN (1 << 1) /* Bit 1: Color Keying Enable */ +#define LTDC_LxCR_CLUTEN (1 << 4) /* Bit 4: Color Look-Up Table Enable */ + +/* LTDC Layer x Window Horizontal Position Configuration Register */ + +#define LTDC_LxWHPCR_WHSTPOS_SHIFT (0) /* Bits 0-11: Window Horizontal Start Position */ +#define LTDC_LxWHPCR_WHSTPOS_MASK (0xFFF << LTDC_LxWHPCR_WHSTPOS_SHIFT) +# define LTDC_LxWHPCR_WHSTPOS(n) ((uint32_t)(n) << LTDC_LxWHPCR_WHSTPOS_SHIFT) +#define LTDC_LxWHPCR_WHSPPOS_SHIFT (16) /* Bits 16-27: Window Horizontal Stop Position */ +#define LTDC_LxWHPCR_WHSPPOS_MASK (0xFFF << LTDC_LxWHPCR_WHSPPOS_SHIFT) +# define LTDC_LxWHPCR_WHSPPOS(n) ((uint32_t)(n) << LTDC_LxWHPCR_WHSPPOS_SHIFT) + +/* LTDC Layer x Window Vertical Position Configuration Register */ + +#define LTDC_LxWVPCR_WVSTPOS_SHIFT (0) /* Bits 0-10: Window Vertical Start Position */ +#define LTDC_LxWVPCR_WVSTPOS_MASK (0x7FF << LTDC_LxWVPCR_WVSTPOS_SHIFT) +# define LTDC_LxWVPCR_WVSTPOS(n) ((uint32_t)(n) << LTDC_LxWVPCR_WVSTPOS_SHIFT) +#define LTDC_LxWVPCR_WVSPPOS_SHIFT (16) /* Bits 16-26: Window Vertical Stop Position */ +#define LTDC_LxWVPCR_WVSPPOS_MASK (0x7FF << LTDC_LxWVPCR_WVSPPOS_SHIFT) +# define LTDC_LxWVPCR_WVSPPOS(n) ((uint32_t)(n) << LTDC_LxWVPCR_WVSPPOS_SHIFT) + +/* LTDC Layer x Color Keying Configuration Register */ + +#define LTDC_LxCKCR_CKBLUE_SHIFT (0) /* Bits 0-7: Color Key Blue Value */ +#define LTDC_LxCKCR_CKBLUE_MASK (0xFF << LTDC_LxCKCR_CKBLUE_SHIFT) +# define LTDC_LxCKCR_CKBLUE(n) ((uint32_t)(n) << LTDC_LxCKCR_CKBLUE_SHIFT) +#define LTDC_LxCKCR_CKGREEN_SHIFT (8) /* Bits 8-15: Color Key Green Value */ +#define LTDC_LxCKCR_CKGREEN_MASK (0xFF << LTDC_LxCKCR_CKGREEN_SHIFT) +# define LTDC_LxCKCR_CKGREEN(n) ((uint32_t)(n) << LTDC_LxCKCR_CKGREEN_SHIFT) +#define LTDC_LxCKCR_CKRED_SHIFT (16) /* Bits 16-23: Color Key Red Value */ +#define LTDC_LxCKCR_CKRED_MASK (0xFF << LTDC_LxCKCR_CKRED_SHIFT) +# define LTDC_LxCKCR_CKRED(n) ((uint32_t)(n) << LTDC_LxCKCR_CKRED_SHIFT) + +/* LTDC Layer x Pixel Format Configuration Register */ + +#define LTDC_LxPFCR_PF_SHIFT (0) /* Bits 0-2: Pixel Format */ +#define LTDC_LxPFCR_PF_MASK (0x7 << LTDC_LxPFCR_PF_SHIFT) +# define LTDC_LxPFCR_PF(n) ((uint32_t)(n) << LTDC_LxPFCR_PF_SHIFT) + +#define LTDC_PF_ARGB8888 0 +#define LTDC_PF_RGB888 1 +#define LTDC_PF_RGB565 2 +#define LTDC_PF_ARGB1555 3 +#define LTDC_PF_ARGB4444 4 +#define LTDC_PF_L8 5 /* 8-bit Luninance (CLUT lookup) */ +#define LTDC_PF_AL44 6 /* 4-bit Alpha, 4-bit Luminance */ +#define LTDC_PF_AL88 7 /* 8-bit Alpha, 8-bit Luminance */ + +/* LTDC Layer x Constant Alpha Configuration Register */ + +#define LTDC_LxCACR_CONSTA_SHIFT (0) /* Bits 0-7: Constant Alpha */ +#define LTDC_LxCACR_CONSTA_MASK (0x7 << LTDC_LxCACR_CONSTA_SHIFT) +# define LTDC_LxCACR_CONSTA(n) ((uint32_t)(n) << LTDC_LxCACR_CONSTA_SHIFT) + +/* LTDC Layer x Default Color Configuration Register */ + +#define LTDC_LxDCCR_DCBLUE_SHIFT (0) /* Bits 0-7: Default Color Blue Value */ +#define LTDC_LxDCCR_DCBLUE_MASK (0xFF << LTDC_LxDCCR_DCBLUE_SHIFT) +# define LTDC_LxDCCR_DCBLUE(n) ((uint32_t)(n) << LTDC_LxDCCR_DCBLUE_SHIFT) +#define LTDC_LxDCCR_DCGREEN_SHIFT (8) /* Bits 8-15: Default Color Green Value */ +#define LTDC_LxDCCR_DCGREEN_MASK (0xFF << LTDC_LxDCCR_DCGREEN_SHIFT) +# define LTDC_LxDCCR_DCGREEN(n) ((uint32_t)(n) << LTDC_LxDCCR_DCGREEN_SHIFT) +#define LTDC_LxDCCR_DCRED_SHIFT (16) /* Bits 16-23: Default Color Red Value */ +#define LTDC_LxDCCR_DCRED_MASK (0xFF << LTDC_LxDCCR_DCRED_SHIFT) +# define LTDC_LxDCCR_DCRED(n) ((uint32_t)(n) << LTDC_LxDCCR_DCRED_SHIFT) +#define LTDC_LxDCCR_DCALPHA_SHIFT (24) /* Bits 24-31: Default Color Alpha Value */ +#define LTDC_LxDCCR_DCALPHA_MASK (0xFF << LTDC_LxDCCR_DCALPHA_SHIFT) +# define LTDC_LxDCCR_DCALPHA(n) ((uint32_t)(n) << LTDC_LxDCCR_DCALPHA_SHIFT) + +/* LTDC Layer x Blending Factors Configuration Register */ + +#define LTDC_LxBFCR_BF2_SHIFT (0) /* Bits 0-2: Blending Factor 2 */ +#define LTDC_LxBFCR_BF2_MASK (0x7 << LTDC_LxBFCR_BF2_SHIFT) +# define LTDC_LxBFCR_BF2(n) ((uint32_t)(n) << LTDC_LxBFCR_BF2_SHIFT) +#define LTDC_LxBFCR_BF1_SHIFT (8) /* Bits 8-10: Blending Factor 1 */ +#define LTDC_LxBFCR_BF1_MASK (0x7 << LTDC_LxBFCR_BF1_SHIFT) +# define LTDC_LxBFCR_BF1(n) ((uint32_t)(n) << LTDC_LxBFCR_BF1_SHIFT) + +#define LTDC_BF1_CONST_ALPHA 0x04 /* Constant Alpha */ +#define LTDC_BF1_PIXEL_ALPHA 0x06 /* Pixel Alpha x Constant Alpha */ +#define LTDC_BF2_CONST_ALPHA 0x05 /* Constant Alpha */ +#define LTDC_BF2_PIXEL_ALPHA 0x07 /* Pixel Alpha x Constant Alpha */ + +/* LTDC Layer x Color Frame Buffer Length Configuration Register */ + +#define LTDC_LxCFBLR_CFBLL_SHIFT (0) /* Bits 0-12: Color Frame Buffer Line Length */ +#define LTDC_LxCFBLR_CFBLL_MASK (0x1FFF << LTDC_LxCFBLR_CFBLL_SHIFT) +# define LTDC_LxCFBLR_CFBLL(n) ((uint32_t)(n) << LTDC_LxCFBLR_CFBLL_SHIFT) +#define LTDC_LxCFBLR_CFBP_SHIFT (16) /* Bits 16-28: Color Frame Buffer Pitch */ +#define LTDC_LxCFBLR_CFBP_MASK (0x1FFF << LTDC_LxCFBLR_CFBP_SHIFT) +# define LTDC_LxCFBLR_CFBP(n) ((uint32_t)(n) << LTDC_LxCFBLR_CFBP_SHIFT) + +/* LTDC Layer x Color Frame Buffer Line Number Register */ + +#define LTDC_LxCFBLNR_LN_SHIFT (0) /* Bits 0-10: Color Frame Buffer Line Number */ +#define LTDC_LxCFBLNR_LN_MASK (0x7FF << LTDC_LxCFBLNR_LN_SHIFT) +# define LTDC_LxCFBLNR_LN(n) ((uint32_t)(n) << LTDC_LxCFBLNR_LN_SHIFT) + +/* LTDC Layer x CLUT Write Register */ + +#define LTDC_LxCLUTWR_BLUE_SHIFT (0) /* Bits 0-7: Default Color Blue Value */ +#define LTDC_LxCLUTWR_BLUE_MASK (0xFF << LTDC_LxCLUTWR_BLUE_SHIFT) +# define LTDC_LxCLUTWR_BLUE(n) ((uint32_t)(n) << LTDC_LxCLUTWR_BLUE_SHIFT) +#define LTDC_LxCLUTWR_GREEN_SHIFT (8) /* Bits 8-15: Default Color Green Value */ +#define LTDC_LxCLUTWR_GREEN_MASK (0xFF << LTDC_LxCLUTWR_GREEN_SHIFT) +# define LTDC_LxCLUTWR_GREEN(n) ((uint32_t)(n) << LTDC_LxCLUTWR_GREEN_SHIFT) +#define LTDC_LxCLUTWR_RED_SHIFT (16) /* Bits 16-23: Default Color Red Value */ +#define LTDC_LxCLUTWR_RED_MASK (0xFF << LTDC_LxCLUTWR_RED_SHIFT) +# define LTDC_LxCLUTWR_RED(n) ((uint32_t)(n) << LTDC_LxCLUTWR_RED_SHIFT) +#define LTDC_LxCLUTWR_CLUTADD_SHIFT (24) /* Bits 24-31: CLUT Address */ +#define LTDC_LxCLUTWR_CLUTADD_MASK (0xFF << LTDC_LxCLUTWR_CLUTADD_SHIFT) +# define LTDC_LxCLUTWR_CLUTADD(n) ((uint32_t)(n) << LTDC_LxCLUTWR_CLUTADD_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_LTDC_H */ diff --git a/arch/arm/src/stm32/chip/stm32_memorymap.h b/arch/arm/src/stm32/chip/stm32_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..28f6590033cafb5da2b109572d8be837a2602504 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_memorymap.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_memorymap.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_memorymap.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_memorymap.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_memorymap.h" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_memorymap.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_memorymap.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_memorymap.h" +#else +# error "Unsupported STM32 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_otgfs.h b/arch/arm/src/stm32/chip/stm32_otgfs.h new file mode 100644 index 0000000000000000000000000000000000000000..575214e6482b987f54937e5ab159831174f9aadb --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_otgfs.h @@ -0,0 +1,1018 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_otgfs.h + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGFS_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGFS_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* General definitions */ + +#define OTGFS_EPTYPE_CTRL (0) /* Control */ +#define OTGFS_EPTYPE_ISOC (1) /* Isochronous */ +#define OTGFS_EPTYPE_BULK (2) /* Bulk */ +#define OTGFS_EPTYPE_INTR (3) /* Interrupt */ + +#define OTGFS_PID_DATA0 (0) +#define OTGFS_PID_DATA2 (1) +#define OTGFS_PID_DATA1 (2) +#define OTGFS_PID_MDATA (3) /* Non-control */ +#define OTGFS_PID_SETUP (3) /* Control */ + +/* Register Offsets *********************************************************************************/ +/* Core global control and status registers */ + +#define STM32_OTGFS_GOTGCTL_OFFSET 0x0000 /* Control and status register */ +#define STM32_OTGFS_GOTGINT_OFFSET 0x0004 /* Interrupt register */ +#define STM32_OTGFS_GAHBCFG_OFFSET 0x0008 /* AHB configuration register */ +#define STM32_OTGFS_GUSBCFG_OFFSET 0x000c /* USB configuration register */ +#define STM32_OTGFS_GRSTCTL_OFFSET 0x0010 /* Reset register */ +#define STM32_OTGFS_GINTSTS_OFFSET 0x0014 /* Core interrupt register */ +#define STM32_OTGFS_GINTMSK_OFFSET 0x0018 /* Interrupt mask register */ +#define STM32_OTGFS_GRXSTSR_OFFSET 0x001c /* Receive status debug read/OTG status read register */ +#define STM32_OTGFS_GRXSTSP_OFFSET 0x0020 /* Receive status debug read/OTG status pop register */ +#define STM32_OTGFS_GRXFSIZ_OFFSET 0x0024 /* Receive FIFO size register */ +#define STM32_OTGFS_HNPTXFSIZ_OFFSET 0x0028 /* Host non-periodic transmit FIFO size register */ +#define STM32_OTGFS_DIEPTXF0_OFFSET 0x0028 /* Endpoint 0 Transmit FIFO size */ +#define STM32_OTGFS_HNPTXSTS_OFFSET 0x002c /* Non-periodic transmit FIFO/queue status register */ +#define STM32_OTGFS_GCCFG_OFFSET 0x0038 /* General core configuration register */ +#define STM32_OTGFS_CID_OFFSET 0x003c /* Core ID register */ +#define STM32_OTGFS_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ + +#define STM32_OTGFS_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) +#define STM32_OTGFS_DIEPTXF1_OFFSET 0x0104 /* Device IN endpoint transmit FIFO1 size register */ +#define STM32_OTGFS_DIEPTXF2_OFFSET 0x0108 /* Device IN endpoint transmit FIFO2 size register */ +#define STM32_OTGFS_DIEPTXF3_OFFSET 0x010c /* Device IN endpoint transmit FIFO3 size register */ + +/* Host-mode control and status registers */ + +#define STM32_OTGFS_HCFG_OFFSET 0x0400 /* Host configuration register */ +#define STM32_OTGFS_HFIR_OFFSET 0x0404 /* Host frame interval register */ +#define STM32_OTGFS_HFNUM_OFFSET 0x0408 /* Host frame number/frame time remaining register */ +#define STM32_OTGFS_HPTXSTS_OFFSET 0x0410 /* Host periodic transmit FIFO/queue status register */ +#define STM32_OTGFS_HAINT_OFFSET 0x0414 /* Host all channels interrupt register */ +#define STM32_OTGFS_HAINTMSK_OFFSET 0x0418 /* Host all channels interrupt mask register */ +#define STM32_OTGFS_HPRT_OFFSET 0x0440 /* Host port control and status register */ + +#define STM32_OTGFS_CHAN_OFFSET(n) (0x500 + ((n) << 5) +#define STM32_OTGFS_HCCHAR_CHOFFSET 0x0000 /* Host channel characteristics register */ +#define STM32_OTGFS_HCINT_CHOFFSET 0x0008 /* Host channel interrupt register */ +#define STM32_OTGFS_HCINTMSK_CHOFFSET 0x000c /* Host channel interrupt mask register */ +#define STM32_OTGFS_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */ + +#define STM32_OTGFS_HCCHAR_OFFSET(n) (0x500 + ((n) << 5)) +#define STM32_OTGFS_HCCHAR0_OFFSET 0x0500 /* Host channel-0 characteristics register */ +#define STM32_OTGFS_HCCHAR1_OFFSET 0x0520 /* Host channel-1 characteristics register */ +#define STM32_OTGFS_HCCHAR2_OFFSET 0x0540 /* Host channel-2 characteristics register */ +#define STM32_OTGFS_HCCHAR3_OFFSET 0x0560 /* Host channel-3 characteristics register */ +#define STM32_OTGFS_HCCHAR4_OFFSET 0x0580 /* Host channel-4 characteristics register */ +#define STM32_OTGFS_HCCHAR5_OFFSET 0x05a0 /* Host channel-5 characteristics register */ +#define STM32_OTGFS_HCCHAR6_OFFSET 0x05c0 /* Host channel-6 characteristics register */ +#define STM32_OTGFS_HCCHAR7_OFFSET 0x05e0 /* Host channel-7 characteristics register */ + +#define STM32_OTGFS_HCINT_OFFSET(n) (0x508 + ((n) << 5)) +#define STM32_OTGFS_HCINT0_OFFSET 0x0508 /* Host channel-0 interrupt register */ +#define STM32_OTGFS_HCINT1_OFFSET 0x0528 /* Host channel-1 interrupt register */ +#define STM32_OTGFS_HCINT2_OFFSET 0x0548 /* Host channel-2 interrupt register */ +#define STM32_OTGFS_HCINT3_OFFSET 0x0568 /* Host channel-3 interrupt register */ +#define STM32_OTGFS_HCINT4_OFFSET 0x0588 /* Host channel-4 interrupt register */ +#define STM32_OTGFS_HCINT5_OFFSET 0x05a8 /* Host channel-5 interrupt register */ +#define STM32_OTGFS_HCINT6_OFFSET 0x05c8 /* Host channel-6 interrupt register */ +#define STM32_OTGFS_HCINT7_OFFSET 0x05e8 /* Host channel-7 interrupt register */ + +#define STM32_OTGFS_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5)) +#define STM32_OTGFS_HCINTMSK0_OFFSET 0x050c /* Host channel-0 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK1_OFFSET 0x052c /* Host channel-1 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK2_OFFSET 0x054c /* Host channel-2 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK3_OFFSET 0x056c /* Host channel-3 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK4_OFFSET 0x058c /* Host channel-4 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK5_OFFSET 0x05ac /* Host channel-5 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK6_OFFSET 0x05cc /* Host channel-6 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK7_OFFSET 0x05ec /* Host channel-7 interrupt mask register */ + +#define STM32_OTGFS_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5)) +#define STM32_OTGFS_HCTSIZ0_OFFSET 0x0510 /* Host channel-0 interrupt register */ +#define STM32_OTGFS_HCTSIZ1_OFFSET 0x0530 /* Host channel-1 interrupt register */ +#define STM32_OTGFS_HCTSIZ2_OFFSET 0x0550 /* Host channel-2 interrupt register */ +#define STM32_OTGFS_HCTSIZ3_OFFSET 0x0570 /* Host channel-3 interrupt register */ +#define STM32_OTGFS_HCTSIZ4_OFFSET 0x0590 /* Host channel-4 interrupt register */ +#define STM32_OTGFS_HCTSIZ5_OFFSET 0x05b0 /* Host channel-5 interrupt register */ +#define STM32_OTGFS_HCTSIZ6_OFFSET 0x05d0 /* Host channel-6 interrupt register */ +#define STM32_OTGFS_HCTSIZ7_OFFSET 0x05f0 /* Host channel-7 interrupt register */ + +/* Device-mode control and status registers */ + +#define STM32_OTGFS_DCFG_OFFSET 0x0800 /* Device configuration register */ +#define STM32_OTGFS_DCTL_OFFSET 0x0804 /* Device control register */ +#define STM32_OTGFS_DSTS_OFFSET 0x0808 /* Device status register */ +#define STM32_OTGFS_DIEPMSK_OFFSET 0x0810 /* Device IN endpoint common interrupt mask register */ +#define STM32_OTGFS_DOEPMSK_OFFSET 0x0814 /* Device OUT endpoint common interrupt mask register */ +#define STM32_OTGFS_DAINT_OFFSET 0x0818 /* Device all endpoints interrupt register */ +#define STM32_OTGFS_DAINTMSK_OFFSET 0x081c /* All endpoints interrupt mask register */ +#define STM32_OTGFS_DVBUSDIS_OFFSET 0x0828 /* Device VBUS discharge time register */ +#define STM32_OTGFS_DVBUSPULSE_OFFSET 0x082c /* Device VBUS pulsing time register */ +#define STM32_OTGFS_DIEPEMPMSK_OFFSET 0x0834 /* Device IN endpoint FIFO empty interrupt mask register */ + +#define STM32_OTGFS_DIEP_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGFS_DIEPCTL_EPOFFSET 0x0000 /* Device endpoint control register */ +#define STM32_OTGFS_DIEPINT_EPOFFSET 0x0008 /* Device endpoint interrupt register */ +#define STM32_OTGFS_DIEPTSIZ_EPOFFSET 0x0010 /* Device IN endpoint transfer size register */ +#define STM32_OTGFS_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */ + +#define STM32_OTGFS_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGFS_DIEPCTL0_OFFSET 0x0900 /* Device control IN endpoint 0 control register */ +#define STM32_OTGFS_DIEPCTL1_OFFSET 0x0920 /* Device control IN endpoint 2 control register */ +#define STM32_OTGFS_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */ +#define STM32_OTGFS_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */ + +#define STM32_OTGFS_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5)) +#define STM32_OTGFS_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */ +#define STM32_OTGFS_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */ +#define STM32_OTGFS_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */ +#define STM32_OTGFS_DIEPINT3_OFFSET 0x0968 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGFS_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5)) +#define STM32_OTGFS_DIEPTSIZ0_OFFSET 0x0910 /* Device IN endpoint 0 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ1_OFFSET 0x0930 /* Device IN endpoint 1 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ2_OFFSET 0x0950 /* Device IN endpoint 2 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ3_OFFSET 0x0970 /* Device IN endpoint 3 transfer size register */ + +#define STM32_OTGFS_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5)) +#define STM32_OTGFS_DTXFSTS0_OFFSET 0x0918 /* Device OUT endpoint-0 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS1_OFFSET 0x0938 /* Device OUT endpoint-1 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 TxFIFO status register */ + +#define STM32_OTGFS_DOEP_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGFS_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */ +#define STM32_OTGFS_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */ + +#define STM32_OTGFS_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGFS_DOEPCTL0_OFFSET 0x00b00 /* Device OUT endpoint 0 control register */ +#define STM32_OTGFS_DOEPCTL1_OFFSET 0x00b20 /* Device OUT endpoint 1 control register */ +#define STM32_OTGFS_DOEPCTL2_OFFSET 0x00b40 /* Device OUT endpoint 2 control register */ +#define STM32_OTGFS_DOEPCTL3_OFFSET 0x00b60 /* Device OUT endpoint 3 control register */ + +#define STM32_OTGFS_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5)) +#define STM32_OTGFS_DOEPINT0_OFFSET 0x00b08 /* Device endpoint-0 interrupt register */ +#define STM32_OTGFS_DOEPINT1_OFFSET 0x00b28 /* Device endpoint-1 interrupt register */ +#define STM32_OTGFS_DOEPINT2_OFFSET 0x00b48 /* Device endpoint-2 interrupt register */ +#define STM32_OTGFS_DOEPINT3_OFFSET 0x00b68 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGFS_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5)) +#define STM32_OTGFS_DOEPTSIZ0_OFFSET 0x00b10 /* Device OUT endpoint-0 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ1_OFFSET 0x00b30 /* Device OUT endpoint-1 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ2_OFFSET 0x00b50 /* Device OUT endpoint-2 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ3_OFFSET 0x00b70 /* Device OUT endpoint-3 transfer size register */ + +/* Power and clock gating registers */ + +#define STM32_OTGFS_PCGCCTL_OFFSET 0x0e00 /* Power and clock gating control register */ + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGFS_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12)) +#define STM32_OTGFS_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12)) + +#define STM32_OTGFS_DFIFO_DEP0_OFFSET 0x1000 /* 0x1000-0x1ffc Device IN/OUT Endpoint 0 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH0_OFFSET 0x1000 /* 0x1000-0x1ffc Host OUT/IN Channel 0 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP1_OFFSET 0x2000 /* 0x2000-0x2ffc Device IN/OUT Endpoint 1 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH1_OFFSET 0x2000 /* 0x2000-0x2ffc Host OUT/IN Channel 1 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP2_OFFSET 0x3000 /* 0x3000-0x3ffc Device IN/OUT Endpoint 2 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH2_OFFSET 0x3000 /* 0x3000-0x3ffc Host OUT/IN Channel 2 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP3_OFFSET 0x4000 /* 0x4000-0x4ffc Device IN/OUT Endpoint 3 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH3_OFFSET 0x4000 /* 0x4000-0x4ffc Host OUT/IN Channel 3 DFIFO Read/Write Access */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_OTGFS_GOTGCTL (STM32_OTGFS_BASE+STM32_OTGFS_GOTGCTL_OFFSET) +#define STM32_OTGFS_GOTGINT (STM32_OTGFS_BASE+STM32_OTGFS_GOTGINT_OFFSET) +#define STM32_OTGFS_GAHBCFG (STM32_OTGFS_BASE+STM32_OTGFS_GAHBCFG_OFFSET) +#define STM32_OTGFS_GUSBCFG (STM32_OTGFS_BASE+STM32_OTGFS_GUSBCFG_OFFSET) +#define STM32_OTGFS_GRSTCTL (STM32_OTGFS_BASE+STM32_OTGFS_GRSTCTL_OFFSET) +#define STM32_OTGFS_GINTSTS (STM32_OTGFS_BASE+STM32_OTGFS_GINTSTS_OFFSET) +#define STM32_OTGFS_GINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_GINTMSK_OFFSET) +#define STM32_OTGFS_GRXSTSR (STM32_OTGFS_BASE+STM32_OTGFS_GRXSTSR_OFFSET) +#define STM32_OTGFS_GRXSTSP (STM32_OTGFS_BASE+STM32_OTGFS_GRXSTSP_OFFSET) +#define STM32_OTGFS_GRXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_GRXFSIZ_OFFSET) +#define STM32_OTGFS_HNPTXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_HNPTXFSIZ_OFFSET) +#define STM32_OTGFS_DIEPTXF0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF0_OFFSET) +#define STM32_OTGFS_HNPTXSTS (STM32_OTGFS_BASE+STM32_OTGFS_HNPTXSTS_OFFSET) +#define STM32_OTGFS_GCCFG (STM32_OTGFS_BASE+STM32_OTGFS_GCCFG_OFFSET) +#define STM32_OTGFS_CID (STM32_OTGFS_BASE+STM32_OTGFS_CID_OFFSET) +#define STM32_OTGFS_HPTXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_HPTXFSIZ_OFFSET) + +#define STM32_OTGFS_DIEPTXF(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF_OFFSET(n)) +#define STM32_OTGFS_DIEPTXF1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF1_OFFSET) +#define STM32_OTGFS_DIEPTXF2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF2_OFFSET) +#define STM32_OTGFS_DIEPTXF3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF3_OFFSET) + +/* Host-mode control and status registers */ + +#define STM32_OTGFS_HCFG (STM32_OTGFS_BASE+STM32_OTGFS_HCFG_OFFSET) +#define STM32_OTGFS_HFIR (STM32_OTGFS_BASE+STM32_OTGFS_HFIR_OFFSET) +#define STM32_OTGFS_HFNUM (STM32_OTGFS_BASE+STM32_OTGFS_HFNUM_OFFSET) +#define STM32_OTGFS_HPTXSTS (STM32_OTGFS_BASE+STM32_OTGFS_HPTXSTS_OFFSET) +#define STM32_OTGFS_HAINT (STM32_OTGFS_BASE+STM32_OTGFS_HAINT_OFFSET) +#define STM32_OTGFS_HAINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_HAINTMSK_OFFSET) +#define STM32_OTGFS_HPRT (STM32_OTGFS_BASE+STM32_OTGFS_HPRT_OFFSET) + +#define STM32_OTGFS_CHAN(n) (STM32_OTGFS_BASE+STM32_OTGFS_CHAN_OFFSET(n)) + +#define STM32_OTGFS_HCCHAR(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR_OFFSET(n)) +#define STM32_OTGFS_HCCHAR0 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR0_OFFSET) +#define STM32_OTGFS_HCCHAR1 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR1_OFFSET) +#define STM32_OTGFS_HCCHAR2 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR2_OFFSET) +#define STM32_OTGFS_HCCHAR3 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR3_OFFSET) +#define STM32_OTGFS_HCCHAR4 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR4_OFFSET) +#define STM32_OTGFS_HCCHAR5 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR5_OFFSET) +#define STM32_OTGFS_HCCHAR6 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR6_OFFSET) +#define STM32_OTGFS_HCCHAR7 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR7_OFFSET) + +#define STM32_OTGFS_HCINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCINT_OFFSET(n)) +#define STM32_OTGFS_HCINT0 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT0_OFFSET) +#define STM32_OTGFS_HCINT1 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT1_OFFSET) +#define STM32_OTGFS_HCINT2 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT2_OFFSET) +#define STM32_OTGFS_HCINT3 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT3_OFFSET) +#define STM32_OTGFS_HCINT4 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT4_OFFSET) +#define STM32_OTGFS_HCINT5 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT5_OFFSET) +#define STM32_OTGFS_HCINT6 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT6_OFFSET) +#define STM32_OTGFS_HCINT7 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT7_OFFSET) + +#define STM32_OTGFS_HCINTMSK(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK_OFFSET(n)) +#define STM32_OTGFS_HCINTMSK0 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK0_OFFSET) +#define STM32_OTGFS_HCINTMSK1 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK1_OFFSET) +#define STM32_OTGFS_HCINTMSK2 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK2_OFFSET) +#define STM32_OTGFS_HCINTMSK3 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK3_OFFSET) +#define STM32_OTGFS_HCINTMSK4 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK4_OFFSET) +#define STM32_OTGFS_HCINTMSK5 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK5_OFFSET) +#define STM32_OTGFS_HCINTMSK6 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK6_OFFSET) +#define STM32_OTGFS_HCINTMSK7 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK7_OFFSET)_ + +#define STM32_OTGFS_HCTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ_OFFSET(n)) +#define STM32_OTGFS_HCTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ0_OFFSET) +#define STM32_OTGFS_HCTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ1_OFFSET) +#define STM32_OTGFS_HCTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ2_OFFSET) +#define STM32_OTGFS_HCTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ3_OFFSET) +#define STM32_OTGFS_HCTSIZ4 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ4_OFFSET) +#define STM32_OTGFS_HCTSIZ5 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ5_OFFSET) +#define STM32_OTGFS_HCTSIZ6 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ6_OFFSET) +#define STM32_OTGFS_HCTSIZ7 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ7_OFFSET) + +/* Device-mode control and status registers */ + +#define STM32_OTGFS_DCFG (STM32_OTGFS_BASE+STM32_OTGFS_DCFG_OFFSET) +#define STM32_OTGFS_DCTL (STM32_OTGFS_BASE+STM32_OTGFS_DCTL_OFFSET) +#define STM32_OTGFS_DSTS (STM32_OTGFS_BASE+STM32_OTGFS_DSTS_OFFSET) +#define STM32_OTGFS_DIEPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DIEPMSK_OFFSET) +#define STM32_OTGFS_DOEPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DOEPMSK_OFFSET) +#define STM32_OTGFS_DAINT (STM32_OTGFS_BASE+STM32_OTGFS_DAINT_OFFSET) +#define STM32_OTGFS_DAINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_DAINTMSK_OFFSET) +#define STM32_OTGFS_DVBUSDIS (STM32_OTGFS_BASE+STM32_OTGFS_DVBUSDIS_OFFSET) +#define STM32_OTGFS_DVBUSPULSE (STM32_OTGFS_BASE+STM32_OTGFS_DVBUSPULSE_OFFSET) +#define STM32_OTGFS_DIEPEMPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DIEPEMPMSK_OFFSET) + +#define STM32_OTGFS_DIEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEP_OFFSET(n)) + +#define STM32_OTGFS_DIEPCTL(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL_OFFSET(n)) +#define STM32_OTGFS_DIEPCTL0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL0_OFFSET) +#define STM32_OTGFS_DIEPCTL1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL1_OFFSET) +#define STM32_OTGFS_DIEPCTL2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL2_OFFSET) +#define STM32_OTGFS_DIEPCTL3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL3_OFFSET) + +#define STM32_OTGFS_DIEPINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT_OFFSET(n)) +#define STM32_OTGFS_DIEPINT0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT0_OFFSET) +#define STM32_OTGFS_DIEPINT1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT1_OFFSET) +#define STM32_OTGFS_DIEPINT2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT2_OFFSET) +#define STM32_OTGFS_DIEPINT3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT3_OFFSET) + +#define STM32_OTGFS_DIEPTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ_OFFSET(n)) +#define STM32_OTGFS_DIEPTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ0_OFFSET) +#define STM32_OTGFS_DIEPTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ1_OFFSET) +#define STM32_OTGFS_DIEPTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ2_OFFSET) +#define STM32_OTGFS_DIEPTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ3_OFFSET) + +#define STM32_OTGFS_DTXFSTS(n) (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS_OFFSET(n)) +#define STM32_OTGFS_DTXFSTS0 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS0_OFFSET) +#define STM32_OTGFS_DTXFSTS1 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS1_OFFSET) +#define STM32_OTGFS_DTXFSTS2 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS2_OFFSET) +#define STM32_OTGFS_DTXFSTS3 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS3_OFFSET) + +#define STM32_OTGFS_DOEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEP_OFFSET(n)) + +#define STM32_OTGFS_DOEPCTL(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL_OFFSET(n)) +#define STM32_OTGFS_DOEPCTL0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL0_OFFSET) +#define STM32_OTGFS_DOEPCTL1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL1_OFFSET) +#define STM32_OTGFS_DOEPCTL2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL2_OFFSET) +#define STM32_OTGFS_DOEPCTL3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL3_OFFSET) + +#define STM32_OTGFS_DOEPINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT_OFFSET(n)) +#define STM32_OTGFS_DOEPINT0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT0_OFFSET) +#define STM32_OTGFS_DOEPINT1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT1_OFFSET) +#define STM32_OTGFS_DOEPINT2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT2_OFFSET) +#define STM32_OTGFS_DOEPINT3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT3_OFFSET) + +#define STM32_OTGFS_DOEPTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ_OFFSET(n)) +#define STM32_OTGFS_DOEPTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ0_OFFSET) +#define STM32_OTGFS_DOEPTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ1_OFFSET) +#define STM32_OTGFS_DOEPTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ2_OFFSET) +#define STM32_OTGFS_DOEPTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ3_OFFSET) + +/* Power and clock gating registers */ + +#define STM32_OTGFS_PCGCCTL (STM32_OTGFS_BASE+STM32_OTGFS_PCGCCTL_OFFSET) + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGFS_DFIFO_DEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP_OFFSET(n)) +#define STM32_OTGFS_DFIFO_HCH(n) (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH_OFFSET(n)) + +#define STM32_OTGFS_DFIFO_DEP0 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP0_OFFSET) +#define STM32_OTGFS_DFIFO_HCH0 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH0_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP1 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP1_OFFSET) +#define STM32_OTGFS_DFIFO_HCH1 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH1_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP2 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP2_OFFSET) +#define STM32_OTGFS_DFIFO_HCH2 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH2_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP3 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP3_OFFSET) +#define STM32_OTGFS_DFIFO_HCH3 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH3_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* Core global control and status registers */ + +/* Control and status register */ + +#define OTGFS_GOTGCTL_SRQSCS (1 << 0) /* Bit 0: Session request success */ +#define OTGFS_GOTGCTL_SRQ (1 << 1) /* Bit 1: Session request */ + /* Bits 2-72 Reserved, must be kept at reset value */ +#define OTGFS_GOTGCTL_HNGSCS (1 << 8) /* Bit 8: Host negotiation success */ +#define OTGFS_GOTGCTL_HNPRQ (1 << 9) /* Bit 9: HNP request */ +#define OTGFS_GOTGCTL_HSHNPEN (1 << 10) /* Bit 10: host set HNP enable */ +#define OTGFS_GOTGCTL_DHNPEN (1 << 11) /* Bit 11: Device HNP enabled */ + /* Bits 12-15: Reserved, must be kept at reset value */ +#define OTGFS_GOTGCTL_CIDSTS (1 << 16) /* Bit 16: Connector ID status */ +#define OTGFS_GOTGCTL_DBCT (1 << 17) /* Bit 17: Long/short debounce time */ +#define OTGFS_GOTGCTL_ASVLD (1 << 18) /* Bit 18: A-session valid */ +#define OTGFS_GOTGCTL_BSVLD (1 << 19) /* Bit 19: B-session valid */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Interrupt register */ + /* Bits 1:0 Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_SEDET (1 << 2) /* Bit 2: Session end detected */ + /* Bits 3-7: Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_SRSSCHG (1 << 8) /* Bit 8: Session request success status change */ +#define OTGFS_GOTGINT_HNSSCHG (1 << 9) /* Bit 9: Host negotiation success status change */ + /* Bits 16:10 Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_HNGDET (1 << 17) /* Bit 17: Host negotiation detected */ +#define OTGFS_GOTGINT_ADTOCHG (1 << 18) /* Bit 18: A-device timeout change */ +#define OTGFS_GOTGINT_DBCDNE (1 << 19) /* Bit 19: Debounce done */ + /* Bits 2-31: Reserved, must be kept at reset value */ + +/* AHB configuration register */ + +#define OTGFS_GAHBCFG_GINTMSK (1 << 0) /* Bit 0: Global interrupt mask */ + /* Bits 1-6: Reserved, must be kept at reset value */ +#define OTGFS_GAHBCFG_TXFELVL (1 << 7) /* Bit 7: TxFIFO empty level */ +#define OTGFS_GAHBCFG_PTXFELVL (1 << 8) /* Bit 8: Periodic TxFIFO empty level */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* USB configuration register */ + +#define OTGFS_GUSBCFG_TOCAL_SHIFT (0) /* Bits 0-2: FS timeout calibration */ +#define OTGFS_GUSBCFG_TOCAL_MASK (7 << OTGFS_GUSBCFG_TOCAL_SHIFT) + /* Bits 3-5: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_PHYSEL (1 << 6) /* Bit 6: Full Speed serial transceiver select */ + /* Bit 7: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_SRPCAP (1 << 8) /* Bit 8: SRP-capable */ +#define OTGFS_GUSBCFG_HNPCAP (1 << 9) /* Bit 9: HNP-capable */ +#define OTGFS_GUSBCFG_TRDT_SHIFT (10) /* Bits 10-13: USB turnaround time */ +#define OTGFS_GUSBCFG_TRDT_MASK (15 << OTGFS_GUSBCFG_TRDT_SHIFT) +# define OTGFS_GUSBCFG_TRDT(n) ((n) << OTGFS_GUSBCFG_TRDT_SHIFT) + /* Bits 14-28: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_FHMOD (1 << 29) /* Bit 29: Force host mode */ +#define OTGFS_GUSBCFG_FDMOD (1 << 30) /* Bit 30: Force device mode */ +#define OTGFS_GUSBCFG_CTXPKT (1 << 31) /* Bit 31: Corrupt Tx packet */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Reset register */ + +#define OTGFS_GRSTCTL_CSRST (1 << 0) /* Bit 0: Core soft reset */ +#define OTGFS_GRSTCTL_HSRST (1 << 1) /* Bit 1: HCLK soft reset */ +#define OTGFS_GRSTCTL_FCRST (1 << 2) /* Bit 2: Host frame counter reset */ + /* Bit 3 Reserved, must be kept at reset value */ +#define OTGFS_GRSTCTL_RXFFLSH (1 << 4) /* Bit 4: RxFIFO flush */ +#define OTGFS_GRSTCTL_TXFFLSH (1 << 5) /* Bit 5: TxFIFO flush */ +#define OTGFS_GRSTCTL_TXFNUM_SHIFT (6) /* Bits 6-10: TxFIFO number */ +#define OTGFS_GRSTCTL_TXFNUM_MASK (31 << OTGFS_GRSTCTL_TXFNUM_SHIFT) +# define OTGFS_GRSTCTL_TXFNUM_HNONPER (0 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Non-periodic TxFIFO flush in host mode */ +# define OTGFS_GRSTCTL_TXFNUM_HPER (1 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Periodic TxFIFO flush in host mode */ +# define OTGFS_GRSTCTL_TXFNUM_HALL (16 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in host mode.*/ +# define OTGFS_GRSTCTL_TXFNUM_D(n) ((n) << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* TXFIFO n flush in device mode, n=0-15 */ +# define OTGFS_GRSTCTL_TXFNUM_DALL (16 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in device mode.*/ + /* Bits 11-31: Reserved, must be kept at reset value */ +#define OTGFS_GRSTCTL_AHBIDL (1 << 31) /* Bit 31: AHB master idle */ + +/* Core interrupt and Interrupt mask registers */ + +#define OTGFS_GINTSTS_CMOD (1 << 0) /* Bit 0: Current mode of operation */ +# define OTGFS_GINTSTS_DEVMODE (0) +# define OTGFS_GINTSTS_HOSTMODE (OTGFS_GINTSTS_CMOD) +#define OTGFS_GINT_MMIS (1 << 1) /* Bit 1: Mode mismatch interrupt */ +#define OTGFS_GINT_OTG (1 << 2) /* Bit 2: OTG interrupt */ +#define OTGFS_GINT_SOF (1 << 3) /* Bit 3: Start of frame */ +#define OTGFS_GINT_RXFLVL (1 << 4) /* Bit 4: RxFIFO non-empty */ +#define OTGFS_GINT_NPTXFE (1 << 5) /* Bit 5: Non-periodic TxFIFO empty */ +#define OTGFS_GINT_GINAKEFF (1 << 6) /* Bit 6: Global IN non-periodic NAK effective */ +#define OTGFS_GINT_GONAKEFF (1 << 7) /* Bit 7: Global OUT NAK effective */ + /* Bits 8-9: Reserved, must be kept at reset value */ +#define OTGFS_GINT_ESUSP (1 << 10) /* Bit 10: Early suspend */ +#define OTGFS_GINT_USBSUSP (1 << 11) /* Bit 11: USB suspend */ +#define OTGFS_GINT_USBRST (1 << 12) /* Bit 12: USB reset */ +#define OTGFS_GINT_ENUMDNE (1 << 13) /* Bit 13: Enumeration done */ +#define OTGFS_GINT_ISOODRP (1 << 14) /* Bit 14: Isochronous OUT packet dropped interrupt */ +#define OTGFS_GINT_EOPF (1 << 15) /* Bit 15: End of periodic frame interrupt */ + /* Bits 16 Reserved, must be kept at reset value */ +#define OTGFS_GINTMSK_EPMISM (1 << 17) /* Bit 17: Endpoint mismatch interrupt mask */ +#define OTGFS_GINT_IEP (1 << 18) /* Bit 18: IN endpoint interrupt */ +#define OTGFS_GINT_OEP (1 << 19) /* Bit 19: OUT endpoint interrupt */ +#define OTGFS_GINT_IISOIXFR (1 << 20) /* Bit 20: Incomplete isochronous IN transfer */ +#define OTGFS_GINT_IISOOXFR (1 << 21) /* Bit 21: Incomplete isochronous OUT transfer (device) */ +#define OTGFS_GINT_IPXFR (1 << 21) /* Bit 21: Incomplete periodic transfer (host) */ + /* Bits 22-23: Reserved, must be kept at reset value */ +#define OTGFS_GINT_HPRT (1 << 24) /* Bit 24: Host port interrupt */ +#define OTGFS_GINT_HC (1 << 25) /* Bit 25: Host channels interrupt */ +#define OTGFS_GINT_PTXFE (1 << 26) /* Bit 26: Periodic TxFIFO empty */ + /* Bit 27 Reserved, must be kept at reset value */ +#define OTGFS_GINT_CIDSCHG (1 << 28) /* Bit 28: Connector ID status change */ +#define OTGFS_GINT_DISC (1 << 29) /* Bit 29: Disconnect detected interrupt */ +#define OTGFS_GINT_SRQ (1 << 30) /* Bit 30: Session request/new session detected interrupt */ +#define OTGFS_GINT_WKUP (1 << 31) /* Bit 31: Resume/remote wakeup detected interrupt */ + +/* Receive status debug read/OTG status read and pop registers (host mode) */ + +#define OTGFS_GRXSTSH_CHNUM_SHIFT (0) /* Bits 0-3: Channel number */ +#define OTGFS_GRXSTSH_CHNUM_MASK (15 << OTGFS_GRXSTSH_CHNUM_SHIFT) +#define OTGFS_GRXSTSH_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGFS_GRXSTSH_BCNT_MASK (0x7ff << OTGFS_GRXSTSH_BCNT_SHIFT) +#define OTGFS_GRXSTSH_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGFS_GRXSTSH_DPID_MASK (3 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA0 (0 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA2 (1 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA1 (2 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_MDATA (3 << OTGFS_GRXSTSH_DPID_SHIFT) +#define OTGFS_GRXSTSH_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGFS_GRXSTSH_PKTSTS_MASK (15 << OTGFS_GRXSTSH_PKTSTS_SHIFT) +# define OTGFS_GRXSTSH_PKTSTS_INRECVD (2 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* IN data packet received */ +# define OTGFS_GRXSTSH_PKTSTS_INDONE (3 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* IN transfer completed */ +# define OTGFS_GRXSTSH_PKTSTS_DTOGERR (5 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* Data toggle error */ +# define OTGFS_GRXSTSH_PKTSTS_HALTED (7 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* Channel halted */ + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Receive status debug read/OTG status read and pop registers (device mode) */ + +#define OTGFS_GRXSTSD_EPNUM_SHIFT (0) /* Bits 0-3: Endpoint number */ +#define OTGFS_GRXSTSD_EPNUM_MASK (15 << OTGFS_GRXSTSD_EPNUM_SHIFT) +#define OTGFS_GRXSTSD_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGFS_GRXSTSD_BCNT_MASK (0x7ff << OTGFS_GRXSTSD_BCNT_SHIFT) +#define OTGFS_GRXSTSD_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGFS_GRXSTSD_DPID_MASK (3 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA0 (0 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA2 (1 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA1 (2 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_MDATA (3 << OTGFS_GRXSTSD_DPID_SHIFT) +#define OTGFS_GRXSTSD_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGFS_GRXSTSD_PKTSTS_MASK (15 << OTGFS_GRXSTSD_PKTSTS_SHIFT) +# define OTGFS_GRXSTSD_PKTSTS_OUTNAK (1 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* Global OUT NAK */ +# define OTGFS_GRXSTSD_PKTSTS_OUTRECVD (2 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* OUT data packet received */ +# define OTGFS_GRXSTSD_PKTSTS_OUTDONE (3 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* OUT transfer completed */ +# define OTGFS_GRXSTSD_PKTSTS_SETUPDONE (4 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* SETUP transaction completed */ +# define OTGFS_GRXSTSD_PKTSTS_SETUPRECVD (6 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* SETUP data packet received */ +#define OTGFS_GRXSTSD_FRMNUM_SHIFT (21) /* Bits 21-24: Frame number */ +#define OTGFS_GRXSTSD_FRMNUM_MASK (15 << OTGFS_GRXSTSD_FRMNUM_SHIFT) + /* Bits 25-31: Reserved, must be kept at reset value */ +/* Receive FIFO size register */ + +#define OTGFS_GRXFSIZ_MASK (0xffff) + +/* Host non-periodic transmit FIFO size register */ + +#define OTGFS_HNPTXFSIZ_NPTXFSA_SHIFT (0) /* Bits 0-15: Non-periodic transmit RAM start address */ +#define OTGFS_HNPTXFSIZ_NPTXFSA_MASK (0xffff << OTGFS_HNPTXFSIZ_NPTXFSA_SHIFT) +#define OTGFS_HNPTXFSIZ_NPTXFD_SHIFT (16) /* Bits 16-31: Non-periodic TxFIFO depth */ +#define OTGFS_HNPTXFSIZ_NPTXFD_MASK (0xffff << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGFS_HNPTXFSIZ_NPTXFD_MIN (16 << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGFS_HNPTXFSIZ_NPTXFD_MAX (256 << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) + +/* Endpoint 0 Transmit FIFO size */ + +#define OTGFS_DIEPTXF0_TX0FD_SHIFT (0) /* Bits 0-15: Endpoint 0 transmit RAM start address */ +#define OTGFS_DIEPTXF0_TX0FD_MASK (0xffff << OTGFS_DIEPTXF0_TX0FD_SHIFT) +#define OTGFS_DIEPTXF0_TX0FSA_SHIFT (16) /* Bits 16-31: Endpoint 0 TxFIFO depth */ +#define OTGFS_DIEPTXF0_TX0FSA_MASK (0xffff << OTGFS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGFS_DIEPTXF0_TX0FSA_MIN (16 << OTGFS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGFS_DIEPTXF0_TX0FSA_MAX (256 << OTGFS_DIEPTXF0_TX0FSA_SHIFT) + +/* Non-periodic transmit FIFO/queue status register */ + +#define OTGFS_HNPTXSTS_NPTXFSAV_SHIFT (0) /* Bits 0-15: Non-periodic TxFIFO space available */ +#define OTGFS_HNPTXSTS_NPTXFSAV_MASK (0xffff << OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) +# define OTGFS_HNPTXSTS_NPTXFSAV_FULL (0 << OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) +#define OTGFS_HNPTXSTS_NPTQXSAV_SHIFT (16) /* Bits 16-23: Non-periodic transmit request queue space available */ +#define OTGFS_HNPTXSTS_NPTQXSAV_MASK (0xff << OTGFS_HNPTXSTS_NPTQXSAV_SHIFT) +# define OTGFS_HNPTXSTS_NPTQXSAV_FULL (0 << OTGFS_HNPTXSTS_NPTQXSAV_SHIFT) +#define OTGFS_HNPTXSTS_NPTXQTOP_SHIFT (24) /* Bits 24-30: Top of the non-periodic transmit request queue */ +#define OTGFS_HNPTXSTS_NPTXQTOP_MASK (0x7f << OTGFS_HNPTXSTS_NPTXQTOP_SHIFT) +# define OTGFS_HNPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGFS_HNPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Status */ +# define OTGFS_HNPTXSTS_TYPE_MASK (3 << OTGFS_HNPTXSTS_TYPE_SHIFT) +# define OTGFS_HNPTXSTS_TYPE_INOUT (0 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGFS_HNPTXSTS_TYPE_ZLP (1 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet (device IN/host OUT) */ +# define OTGFS_HNPTXSTS_TYPE_HALT (3 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* Channel halt command */ +# define OTGFS_HNPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGFS_HNPTXSTS_CHNUM_MASK (15 << OTGFS_HNPTXSTS_CHNUM_SHIFT) +# define OTGFS_HNPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGFS_HNPTXSTS_EPNUM_MASK (15 << OTGFS_HNPTXSTS_EPNUM_SHIFT) + /* Bit 31 Reserved, must be kept at reset value */ +/* General core configuration register */ + /* Bits 15:0 Reserved, must be kept at reset value */ +#define OTGFS_GCCFG_PWRDWN (1 << 16) /* Bit 16: Power down */ + /* Bit 17 Reserved, must be kept at reset value */ +#define OTGFS_GCCFG_VBUSASEN (1 << 18) /* Bit 18: Enable the VBUS sensing “A” device */ +#define OTGFS_GCCFG_VBUSBSEN (1 << 19) /* Bit 19: Enable the VBUS sensing “B” device */ +#define OTGFS_GCCFG_SOFOUTEN (1 << 20) /* Bit 20: SOF output enable */ +#define OTGFS_GCCFG_NOVBUSSENS (1 << 21) /* Bit 21: VBUS sensing disable option */ + /* Bits 31:22 Reserved, must be kept at reset value */ +/* Core ID register (32-bit product ID) */ + +/* Host periodic transmit FIFO size register */ + +#define OTGFS_HPTXFSIZ_PTXSA_SHIFT (0) /* Bits 0-15: Host periodic TxFIFO start address */ +#define OTGFS_HPTXFSIZ_PTXSA_MASK (0xffff << OTGFS_HPTXFSIZ_PTXSA_SHIFT) +#define OTGFS_HPTXFSIZ_PTXFD_SHIFT (16) /* Bits 16-31: Host periodic TxFIFO depth */ +#define OTGFS_HPTXFSIZ_PTXFD_MASK (0xffff << OTGFS_HPTXFSIZ_PTXFD_SHIFT) + +/* Device IN endpoint transmit FIFOn size register */ + +#define OTGFS_DIEPTXF_INEPTXSA_SHIFT (0) /* Bits 0-15: IN endpoint FIFOx transmit RAM start address */ +#define OTGFS_DIEPTXF_INEPTXSA_MASK (0xffff << OTGFS_DIEPTXF_INEPTXSA_SHIFT) +#define OTGFS_DIEPTXF_INEPTXFD_SHIFT (16) /* Bits 16-31: IN endpoint TxFIFO depth */ +#define OTGFS_DIEPTXF_INEPTXFD_MASK (0xffff << OTGFS_DIEPTXF_INEPTXFD_SHIFT) +# define OTGFS_DIEPTXF_INEPTXFD_MIN (16 << OTGFS_DIEPTXF_INEPTXFD_MASK) + +/* Host-mode control and status registers */ + +/* Host configuration register */ + +#define OTGFS_HCFG_FSLSPCS_SHIFT (0) /* Bits 0-1: FS/LS PHY clock select */ +#define OTGFS_HCFG_FSLSPCS_MASK (3 << OTGFS_HCFG_FSLSPCS_SHIFT) +# define OTGFS_HCFG_FSLSPCS_FS48MHz (1 << OTGFS_HCFG_FSLSPCS_SHIFT) /* FS host mode, PHY clock is running at 48 MHz */ +# define OTGFS_HCFG_FSLSPCS_LS48MHz (1 << OTGFS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 48 MHz PHY clock frequency */ +# define OTGFS_HCFG_FSLSPCS_LS6MHz (2 << OTGFS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 6 MHz PHY clock frequency */ +#define OTGFS_HCFG_FSLSS (1 << 2) /* Bit 2: FS- and LS-only support */ + /* Bits 31:3 Reserved, must be kept at reset value */ +/* Host frame interval register */ + +#define OTGFS_HFIR_MASK (0xffff) + +/* Host frame number/frame time remaining register */ + +#define OTGFS_HFNUM_FRNUM_SHIFT (0) /* Bits 0-15: Frame number */ +#define OTGFS_HFNUM_FRNUM_MASK (0xffff << OTGFS_HFNUM_FRNUM_SHIFT) +#define OTGFS_HFNUM_FTREM_SHIFT (16) /* Bits 16-31: Frame time remaining */ +#define OTGFS_HFNUM_FTREM_MASK (0xffff << OTGFS_HFNUM_FTREM_SHIFT) + +/* Host periodic transmit FIFO/queue status register */ + +#define OTGFS_HPTXSTS_PTXFSAVL_SHIFT (0) /* Bits 0-15: Periodic transmit data FIFO space available */ +#define OTGFS_HPTXSTS_PTXFSAVL_MASK (0xffff << OTGFS_HPTXSTS_PTXFSAVL_SHIFT) +# define OTGFS_HPTXSTS_PTXFSAVL_FULL (0 << OTGFS_HPTXSTS_PTXFSAVL_SHIFT) +#define OTGFS_HPTXSTS_PTXQSAV_SHIFT (16) /* Bits 16-23: Periodic transmit request queue space available */ +#define OTGFS_HPTXSTS_PTXQSAV_MASK (0xff << OTGFS_HPTXSTS_PTXQSAV_SHIFT) +# define OTGFS_HPTXSTS_PTXQSAV_FULL (0 << OTGFS_HPTXSTS_PTXQSAV_SHIFT) +#define OTGFS_HPTXSTS_PTXQTOP_SHIFT (24) /* Bits 24-31: Top of the periodic transmit request queue */ +#define OTGFS_HPTXSTS_PTXQTOP_MASK (0x7f << OTGFS_HPTXSTS_PTXQTOP_SHIFT) +# define OTGFS_HPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGFS_HPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Type */ +# define OTGFS_HPTXSTS_TYPE_MASK (3 << OTGFS_HPTXSTS_TYPE_SHIFT) +# define OTGFS_HPTXSTS_TYPE_INOUT (0 << OTGFS_HPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGFS_HPTXSTS_TYPE_ZLP (1 << OTGFS_HPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet */ +# define OTGFS_HPTXSTS_TYPE_HALT (3 << OTGFS_HPTXSTS_TYPE_SHIFT) /* Disable channel command */ +# define OTGFS_HPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGFS_HPTXSTS_EPNUM_MASK (15 << OTGFS_HPTXSTS_EPNUM_SHIFT) +# define OTGFS_HPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGFS_HPTXSTS_CHNUM_MASK (15 << OTGFS_HPTXSTS_CHNUM_SHIFT) +# define OTGFS_HPTXSTS_ODD (1 << 24) /* Bit 31: Send in odd (vs even) frame */ + +/* Host all channels interrupt and all channels interrupt mask registers */ + +#define OTGFS_HAINT(n) (1 << (n)) /* Bits 15:0 HAINTM: Channel interrupt */ + +/* Host port control and status register */ + +#define OTGFS_HPRT_PCSTS (1 << 0) /* Bit 0: Port connect status */ +#define OTGFS_HPRT_PCDET (1 << 1) /* Bit 1: Port connect detected */ +#define OTGFS_HPRT_PENA (1 << 2) /* Bit 2: Port enable */ +#define OTGFS_HPRT_PENCHNG (1 << 3) /* Bit 3: Port enable/disable change */ +#define OTGFS_HPRT_POCA (1 << 4) /* Bit 4: Port overcurrent active */ +#define OTGFS_HPRT_POCCHNG (1 << 5) /* Bit 5: Port overcurrent change */ +#define OTGFS_HPRT_PRES (1 << 6) /* Bit 6: Port resume */ +#define OTGFS_HPRT_PSUSP (1 << 7) /* Bit 7: Port suspend */ +#define OTGFS_HPRT_PRST (1 << 8) /* Bit 8: Port reset */ + /* Bit 9: Reserved, must be kept at reset value */ +#define OTGFS_HPRT_PLSTS_SHIFT (10) /* Bits 10-11: Port line status */ +#define OTGFS_HPRT_PLSTS_MASK (3 << OTGFS_HPRT_PLSTS_SHIFT) +# define OTGFS_HPRT_PLSTS_DP (1 << 10) /* Bit 10: Logic level of OTG_FS_FS_DP */ +# define OTGFS_HPRT_PLSTS_DM (1 << 11) /* Bit 11: Logic level of OTG_FS_FS_DM */ +#define OTGFS_HPRT_PPWR (1 << 12) /* Bit 12: Port power */ +#define OTGFS_HPRT_PTCTL_SHIFT (13) /* Bits 13-16: Port test control */ +#define OTGFS_HPRT_PTCTL_MASK (15 << OTGFS_HPRT_PTCTL_SHIFT) +# define OTGFS_HPRT_PTCTL_DISABLED (0 << OTGFS_HPRT_PTCTL_SHIFT) /* Test mode disabled */ +# define OTGFS_HPRT_PTCTL_J (1 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_J mode */ +# define OTGFS_HPRT_PTCTL_L (2 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_K mode */ +# define OTGFS_HPRT_PTCTL_SE0_NAK (3 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGFS_HPRT_PTCTL_PACKET (4 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_Packet mode */ +# define OTGFS_HPRT_PTCTL_FORCE (5 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_Force_Enable */ +#define OTGFS_HPRT_PSPD_SHIFT (17) /* Bits 17-18: Port speed */ +#define OTGFS_HPRT_PSPD_MASK (3 << OTGFS_HPRT_PSPD_SHIFT) +# define OTGFS_HPRT_PSPD_FS (1 << OTGFS_HPRT_PSPD_SHIFT) /* Full speed */ +# define OTGFS_HPRT_PSPD_LS (2 << OTGFS_HPRT_PSPD_SHIFT) /* Low speed */ + /* Bits 19-31: Reserved, must be kept at reset value */ + +/* Host channel-n characteristics register */ + +#define OTGFS_HCCHAR_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_HCCHAR_MPSIZ_MASK (0x7ff << OTGFS_HCCHAR_MPSIZ_SHIFT) +#define OTGFS_HCCHAR_EPNUM_SHIFT (11) /* Bits 11-14: Endpoint number */ +#define OTGFS_HCCHAR_EPNUM_MASK (15 << OTGFS_HCCHAR_EPNUM_SHIFT) +#define OTGFS_HCCHAR_EPDIR (1 << 15) /* Bit 15: Endpoint direction */ +# define OTGFS_HCCHAR_EPDIR_OUT (0) +# define OTGFS_HCCHAR_EPDIR_IN OTGFS_HCCHAR_EPDIR + /* Bit 16 Reserved, must be kept at reset value */ +#define OTGFS_HCCHAR_LSDEV (1 << 17) /* Bit 17: Low-speed device */ +#define OTGFS_HCCHAR_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_HCCHAR_EPTYP_MASK (3 << OTGFS_HCCHAR_EPTYP_SHIFT) +# define OTGFS_HCCHAR_EPTYP_CTRL (0 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Control */ +# define OTGFS_HCCHAR_EPTYP_ISOC (1 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_HCCHAR_EPTYP_BULK (2 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_HCCHAR_EPTYP_INTR (3 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Interrupt */ +#define OTGFS_HCCHAR_MCNT_SHIFT (20) /* Bits 20-21: Multicount */ +#define OTGFS_HCCHAR_MCNT_MASK (3 << OTGFS_HCCHAR_MCNT_SHIFT) +#define OTGFS_HCCHAR_DAD_SHIFT (22) /* Bits 22-28: Device address */ +#define OTGFS_HCCHAR_DAD_MASK (0x7f << OTGFS_HCCHAR_DAD_SHIFT) +#define OTGFS_HCCHAR_ODDFRM (1 << 29) /* Bit 29: Odd frame */ +#define OTGFS_HCCHAR_CHDIS (1 << 30) /* Bit 30: Channel disable */ +#define OTGFS_HCCHAR_CHENA (1 << 31) /* Bit 31: Channel enable */ + +/* Host channel-n interrupt and Host channel-0 interrupt mask registers */ + +#define OTGFS_HCINT_XFRC (1 << 0) /* Bit 0: Transfer completed */ +#define OTGFS_HCINT_CHH (1 << 1) /* Bit 1: Channel halted */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_HCINT_STALL (1 << 3) /* Bit 3: STALL response received interrupt */ +#define OTGFS_HCINT_NAK (1 << 4) /* Bit 4: NAK response received interrupt */ +#define OTGFS_HCINT_ACK (1 << 5) /* Bit 5: ACK response received/transmitted interrupt */ +#define OTGFS_HCINT_NYET (1 << 6) /* Bit 6: Response received interrupt */ +#define OTGFS_HCINT_TXERR (1 << 7) /* Bit 7: Transaction error */ +#define OTGFS_HCINT_BBERR (1 << 8) /* Bit 8: Babble error */ +#define OTGFS_HCINT_FRMOR (1 << 9) /* Bit 9: Frame overrun */ +#define OTGFS_HCINT_DTERR (1 << 10) /* Bit 10: Data toggle error */ + /* Bits 11-31 Reserved, must be kept at reset value */ +/* Host channel-n interrupt register */ + +#define OTGFS_HCTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_HCTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_HCTSIZ_XFRSIZ_SHIFT) +#define OTGFS_HCTSIZ_PKTCNT_SHIFT (19) /* Bits 19-28: Packet count */ +#define OTGFS_HCTSIZ_PKTCNT_MASK (0x3ff << OTGFS_HCTSIZ_PKTCNT_SHIFT) +#define OTGFS_HCTSIZ_DPID_SHIFT (29) /* Bits 29-30: Data PID */ +#define OTGFS_HCTSIZ_DPID_MASK (3 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA0 (0 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA2 (1 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA1 (2 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_MDATA (3 << OTGFS_HCTSIZ_DPID_SHIFT) /* Non-control */ +# define OTGFS_HCTSIZ_PID_SETUP (3 << OTGFS_HCTSIZ_DPID_SHIFT) /* Control */ + /* Bit 31 Reserved, must be kept at reset value */ +/* Device-mode control and status registers */ + +/* Device configuration register */ + +#define OTGFS_DCFG_DSPD_SHIFT (0) /* Bits 0-1: Device speed */ +#define OTGFS_DCFG_DSPD_MASK (3 << OTGFS_DCFG_DSPD_SHIFT) +# define OTGFS_DCFG_DSPD_FS (3 << OTGFS_DCFG_DSPD_SHIFT) /* Full speed */ +#define OTGFS_DCFG_NZLSOHSK (1 << 2) /* Bit 2: Non-zero-length status OUT handshake */ + /* Bit 3: Reserved, must be kept at reset value */ +#define OTGFS_DCFG_DAD_SHIFT (4) /* Bits 4-10: Device address */ +#define OTGFS_DCFG_DAD_MASK (0x7f << OTGFS_DCFG_DAD_SHIFT) +#define OTGFS_DCFG_PFIVL_SHIFT (11) /* Bits 11-12: Periodic frame interval */ +#define OTGFS_DCFG_PFIVL_MASK (3 << OTGFS_DCFG_PFIVL_SHIFT) +# define OTGFS_DCFG_PFIVL_80PCT (0 << OTGFS_DCFG_PFIVL_SHIFT) /* 80% of the frame interval */ +# define OTGFS_DCFG_PFIVL_85PCT (1 << OTGFS_DCFG_PFIVL_SHIFT) /* 85% of the frame interval */ +# define OTGFS_DCFG_PFIVL_90PCT (2 << OTGFS_DCFG_PFIVL_SHIFT) /* 90% of the frame interval */ +# define OTGFS_DCFG_PFIVL_95PCT (3 << OTGFS_DCFG_PFIVL_SHIFT) /* 95% of the frame interval */ + /* Bits 13-31 Reserved, must be kept at reset value */ +/* Device control register */ + +#define OTGFS_TESTMODE_DISABLED (0) /* Test mode disabled */ +#define OTGFS_TESTMODE_J (1) /* Test_J mode */ +#define OTGFS_TESTMODE_K (2) /* Test_K mode */ +#define OTGFS_TESTMODE_SE0_NAK (3) /* Test_SE0_NAK mode */ +#define OTGFS_TESTMODE_PACKET (4) /* Test_Packet mode */ +#define OTGFS_TESTMODE_FORCE (5) /* Test_Force_Enable */ + +#define OTGFS_DCTL_RWUSIG (1 << 0) /* Bit 0: Remote wakeup signaling */ +#define OTGFS_DCTL_SDIS (1 << 1) /* Bit 1: Soft disconnect */ +#define OTGFS_DCTL_GINSTS (1 << 2) /* Bit 2: Global IN NAK status */ +#define OTGFS_DCTL_GONSTS (1 << 3) /* Bit 3: Global OUT NAK status */ +#define OTGFS_DCTL_TCTL_SHIFT (4) /* Bits 4-6: Test control */ +#define OTGFS_DCTL_TCTL_MASK (7 << OTGFS_DCTL_TCTL_SHIFT) +# define OTGFS_DCTL_TCTL_DISABLED (0 << OTGFS_DCTL_TCTL_SHIFT) /* Test mode disabled */ +# define OTGFS_DCTL_TCTL_J (1 << OTGFS_DCTL_TCTL_SHIFT) /* Test_J mode */ +# define OTGFS_DCTL_TCTL_K (2 << OTGFS_DCTL_TCTL_SHIFT) /* Test_K mode */ +# define OTGFS_DCTL_TCTL_SE0_NAK (3 << OTGFS_DCTL_TCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGFS_DCTL_TCTL_PACKET (4 << OTGFS_DCTL_TCTL_SHIFT) /* Test_Packet mode */ +# define OTGFS_DCTL_TCTL_FORCE (5 << OTGFS_DCTL_TCTL_SHIFT) /* Test_Force_Enable */ +#define OTGFS_DCTL_SGINAK (1 << 7) /* Bit 7: Set global IN NAK */ +#define OTGFS_DCTL_CGINAK (1 << 8) /* Bit 8: Clear global IN NAK */ +#define OTGFS_DCTL_SGONAK (1 << 9) /* Bit 9: Set global OUT NAK */ +#define OTGFS_DCTL_CGONAK (1 << 10) /* Bit 10: Clear global OUT NAK */ +#define OTGFS_DCTL_POPRGDNE (1 << 11) /* Bit 11: Power-on programming done */ + /* Bits 12-31: Reserved, must be kept at reset value */ +/* Device status register */ + +#define OTGFS_DSTS_SUSPSTS (1 << 0) /* Bit 0: Suspend status */ +#define OTGFS_DSTS_ENUMSPD_SHIFT (1) /* Bits 1-2: Enumerated speed */ +#define OTGFS_DSTS_ENUMSPD_MASK (3 << OTGFS_DSTS_ENUMSPD_SHIFT) +# define OTGFS_DSTS_ENUMSPD_FS (3 << OTGFS_DSTS_ENUMSPD_MASK) /* Full speed */ + /* Bits 4-7: Reserved, must be kept at reset value */ +#define OTGFS_DSTS_EERR (1 << 3) /* Bit 3: Erratic error */ +#define OTGFS_DSTS_SOFFN_SHIFT (8) /* Bits 8-21: Frame number of the received SOF */ +#define OTGFS_DSTS_SOFFN_MASK (0x3fff << OTGFS_DSTS_SOFFN_SHIFT) +#define OTGFS_DSTS_SOFFN0 (1 << 8) /* Bits 8: Frame number even/odd bit */ +#define OTGFS_DSTS_SOFFN_EVEN 0 +#define OTGFS_DSTS_SOFFN_ODD OTGFS_DSTS_SOFFN0 + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Device IN endpoint common interrupt mask register */ + +#define OTGFS_DIEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGFS_DIEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DIEPMSK_TOM (1 << 3) /* Bit 3: Timeout condition mask (Non-isochronous endpoints) */ +#define OTGFS_DIEPMSK_ITTXFEMSK (1 << 4) /* Bit 4: IN token received when TxFIFO empty mask */ +#define OTGFS_DIEPMSK_INEPNMM (1 << 5) /* Bit 5: IN token received with EP mismatch mask */ +#define OTGFS_DIEPMSK_INEPNEM (1 << 6) /* Bit 6: IN endpoint NAK effective mask */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint common interrupt mask register */ + +#define OTGFS_DOEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGFS_DOEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DOEPMSK_STUPM (1 << 3) /* Bit 3: SETUP phase done mask */ +#define OTGFS_DOEPMSK_OTEPDM (1 << 4) /* Bit 4: OUT token received when endpoint disabled mask */ + /* Bits 5-31: Reserved, must be kept at reset value */ +/* Device all endpoints interrupt and All endpoints interrupt mask registers */ + +#define OTGFS_DAINT_IEP_SHIFT (0) /* Bits 0-15: IN endpoint interrupt bits */ +#define OTGFS_DAINT_IEP_MASK (0xffff << OTGFS_DAINT_IEP_SHIFT) +# define OTGFS_DAINT_IEP(n) (1 << (n)) +#define OTGFS_DAINT_OEP_SHIFT (16) /* Bits 16-31: OUT endpoint interrupt bits */ +#define OTGFS_DAINT_OEP_MASK (0xffff << OTGFS_DAINT_OEP_SHIFT) +# define OTGFS_DAINT_OEP(n) (1 << ((n)+16)) + +/* Device VBUS discharge time register */ + +#define OTGFS_DVBUSDIS_MASK (0xffff) + +/* Device VBUS pulsing time register */ + +#define OTGFS_DVBUSPULSE_MASK (0xfff) + +/* Device IN endpoint FIFO empty interrupt mask register */ + +#define OTGFS_DIEPEMPMSK(n) (1 << (n)) + +/* Device control IN endpoint 0 control register */ + +#define OTGFS_DIEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGFS_DIEPCTL0_MPSIZ_MASK (3 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) +# define OTGFS_DIEPCTL0_MPSIZ_64 (0 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_32 (1 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_16 (2 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_8 (3 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DIEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DIEPCTL0_EPTYP_MASK (3 << OTGFS_DIEPCTL0_EPTYP_SHIFT) +# define OTGFS_DIEPCTL0_EPTYP_CTRL (0 << OTGFS_DIEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGFS_DIEPCTL0_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGFS_DIEPCTL0_TXFNUM_MASK (15 << OTGFS_DIEPCTL0_TXFNUM_SHIFT) +#define OTGFS_DIEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DIEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DIEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device control IN endpoint n control register */ + +#define OTGFS_DIEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_DIEPCTL_MPSIZ_MASK (0x7ff << OTGFS_DIEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGFS_DIEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame */ +# define OTGFS_DIEPCTL_EVEN (0) +# define OTGFS_DIEPCTL_ODD OTGFS_DIEPCTL_EONUM +# define OTGFS_DIEPCTL_DATA0 (0) +# define OTGFS_DIEPCTL_DATA1 OTGFS_DIEPCTL_EONUM +#define OTGFS_DIEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DIEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DIEPCTL_EPTYP_MASK (3 << OTGFS_DIEPCTL_EPTYP_SHIFT) +# define OTGFS_DIEPCTL_EPTYP_CTRL (0 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGFS_DIEPCTL_EPTYP_ISOC (1 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_DIEPCTL_EPTYP_BULK (2 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_DIEPCTL_EPTYP_INTR (3 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Interrupt */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGFS_DIEPCTL_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGFS_DIEPCTL_TXFNUM_MASK (15 << OTGFS_DIEPCTL_TXFNUM_SHIFT) +#define OTGFS_DIEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DIEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGFS_DIEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGFS_DIEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous)) */ +#define OTGFS_DIEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous) */ +#define OTGFS_DIEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DIEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGFS_DIEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGFS_DIEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DIEPINT_TOC (1 << 3) /* Bit 3: Timeout condition */ +#define OTGFS_DIEPINT_ITTXFE (1 << 4) /* Bit 4: IN token received when TxFIFO is empty */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGFS_DIEPINT_INEPNE (1 << 6) /* Bit 6: IN endpoint NAK effective */ +#define OTGFS_DIEPINT_TXFE (1 << 7) /* Bit 7: Transmit FIFO empty */ + /* Bits 8-31: Reserved, must be kept at reset value */ +/* Device IN endpoint 0 transfer size register */ + +#define OTGFS_DIEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGFS_DIEPTSIZ0_XFRSIZ_MASK (0x7f << OTGFS_DIEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGFS_DIEPTSIZ0_PKTCNT_SHIFT (19) /* Bits 19-20: Packet count */ +#define OTGFS_DIEPTSIZ0_PKTCNT_MASK (3 << OTGFS_DIEPTSIZ0_PKTCNT_SHIFT) + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Device IN endpoint n transfer size register */ + +#define OTGFS_DIEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_DIEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_DIEPTSIZ_XFRSIZ_SHIFT) +#define OTGFS_DIEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGFS_DIEPTSIZ_PKTCNT_MASK (0x3ff << OTGFS_DIEPTSIZ_PKTCNT_SHIFT) +#define OTGFS_DIEPTSIZ_MCNT_SHIFT (29) /* Bits 29-30: Multi count */ +#define OTGFS_DIEPTSIZ_MCNT_MASK (3 << OTGFS_DIEPTSIZ_MCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint TxFIFO status register */ + +#define OTGFS_DTXFSTS_MASK (0xffff) + +/* Device OUT endpoint 0 control register */ + +#define OTGFS_DOEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGFS_DOEPCTL0_MPSIZ_MASK (3 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) +# define OTGFS_DOEPCTL0_MPSIZ_64 (0 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_32 (1 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_16 (2 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_8 (3 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DOEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DOEPCTL0_EPTYP_MASK (3 << OTGFS_DOEPCTL0_EPTYP_SHIFT) +# define OTGFS_DOEPCTL0_EPTYP_CTRL (0 << OTGFS_DOEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ +#define OTGFS_DOEPCTL0_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGFS_DOEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DOEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DOEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device OUT endpoint n control register */ + +#define OTGFS_DOEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_DOEPCTL_MPSIZ_MASK (0x7ff << OTGFS_DOEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGFS_DOEPCTL_DPID (1 << 16) /* Bit 16: Endpoint data PID (interrupt/buld) */ +# define OTGFS_DOEPCTL_DATA0 (0) +# define OTGFS_DOEPCTL_DATA1 OTGFS_DOEPCTL_DPID +#define OTGFS_DOEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame (isochronous) */ +# define OTGFS_DOEPCTL_EVEN (0) +# define OTGFS_DOEPCTL_ODD OTGFS_DOEPCTL_EONUM +#define OTGFS_DOEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DOEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DOEPCTL_EPTYP_MASK (3 << OTGFS_DOEPCTL_EPTYP_SHIFT) +# define OTGFS_DOEPCTL_EPTYP_CTRL (0 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGFS_DOEPCTL_EPTYP_ISOC (1 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_DOEPCTL_EPTYP_BULK (2 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_DOEPCTL_EPTYP_INTR (3 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Interrupt */ +#define OTGFS_DOEPCTL_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGFS_DOEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DOEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGFS_DOEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGFS_DOEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous) */ +#define OTGFS_DOEPCTL_SD1PID (1 << 29) /* Bit 29: Set DATA1 PID (interrupt/bulk) */ +#define OTGFS_DOEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous */ +#define OTGFS_DOEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DOEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGFS_DOEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGFS_DOEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DOEPINT_SETUP (1 << 3) /* Bit 3: SETUP phase done */ +#define OTGFS_DOEPINT_OTEPDIS (1 << 4) /* Bit 4: OUT token received when endpoint disabled */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGFS_DOEPINT_B2BSTUP (1 << 6) /* Bit 6: Back-to-back SETUP packets received */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-0 transfer size register */ + +#define OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGFS_DOEPTSIZ0_XFRSIZ_MASK (0x7f << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGFS_DOEPTSIZ0_PKTCNT (1 << 19) /* Bit 19 PKTCNT: Packet count */ + /* Bits 20-28: Reserved, must be kept at reset value */ +#define OTGFS_DOEPTSIZ0_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGFS_DOEPTSIZ0_STUPCNT_MASK (3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-n transfer size register */ + +#define OTGFS_DOEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_DOEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_DOEPTSIZ_XFRSIZ_SHIFT) +#define OTGFS_DOEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGFS_DOEPTSIZ_PKTCNT_MASK (0x3ff << OTGFS_DOEPTSIZ_PKTCNT_SHIFT) +#define OTGFS_DOEPTSIZ_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGFS_DOEPTSIZ_STUPCNT_MASK (3 << OTGFS_DOEPTSIZ_STUPCNT_SHIFT) +#define OTGFS_DOEPTSIZ_RXDPID_SHIFT (29) /* Bits 29-30: Received data PID */ +#define OTGFS_DOEPTSIZ_RXDPID_MASK (3 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA0 (0 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA2 (1 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA1 (2 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_MDATA (3 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Power and clock gating control register */ + +#define OTGFS_PCGCCTL_STPPCLK (1 << 0) /* Bit 0: Stop PHY clock */ +#define OTGFS_PCGCCTL_GATEHCLK (1 << 1) /* Bit 1: Gate HCLK */ + /* Bits 2-3: Reserved, must be kept at reset value */ +#define OTGFS_PCGCCTL_PHYSUSP (1 << 4) /* Bit 4: PHY Suspended */ + /* Bits 5-31: Reserved, must be kept at reset value */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGFS_H */ diff --git a/arch/arm/src/stm32/chip/stm32_otghs.h b/arch/arm/src/stm32/chip/stm32_otghs.h new file mode 100644 index 0000000000000000000000000000000000000000..42b442226216a7877bb9c1b59f87104538c9033e --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_otghs.h @@ -0,0 +1,1052 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_otghs.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGHS_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGHS_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* General definitions */ + +#define OTGHS_EPTYPE_CTRL (0) /* Control */ +#define OTGHS_EPTYPE_ISOC (1) /* Isochronous */ +#define OTGHS_EPTYPE_BULK (2) /* Bulk */ +#define OTGHS_EPTYPE_INTR (3) /* Interrupt */ + +#define OTGHS_PID_DATA0 (0) +#define OTGHS_PID_DATA2 (1) +#define OTGHS_PID_DATA1 (2) +#define OTGHS_PID_MDATA (3) /* Non-control */ +#define OTGHS_PID_SETUP (3) /* Control */ + +/* If OTGHS2 is defined (FS mode of the HS module), then remap the OTGHS base address */ + +/* Register Offsets *********************************************************************************/ +/* Core global control and status registers */ + +#define STM32_OTGHS_GOTGCTL_OFFSET 0x0000 /* Control and status register */ +#define STM32_OTGHS_GOTGINT_OFFSET 0x0004 /* Interrupt register */ +#define STM32_OTGHS_GAHBCFG_OFFSET 0x0008 /* AHB configuration register */ +#define STM32_OTGHS_GUSBCFG_OFFSET 0x000c /* USB configuration register */ +#define STM32_OTGHS_GRSTCTL_OFFSET 0x0010 /* Reset register */ +#define STM32_OTGHS_GINTSTS_OFFSET 0x0014 /* Core interrupt register */ +#define STM32_OTGHS_GINTMSK_OFFSET 0x0018 /* Interrupt mask register */ +#define STM32_OTGHS_GRXSTSR_OFFSET 0x001c /* Receive status debug read/OTG status read register */ +#define STM32_OTGHS_GRXSTSP_OFFSET 0x0020 /* Receive status debug read/OTG status pop register */ +#define STM32_OTGHS_GRXFSIZ_OFFSET 0x0024 /* Receive FIFO size register */ +#define STM32_OTGHS_HNPTXFSIZ_OFFSET 0x0028 /* Host non-periodic transmit FIFO size register */ +#define STM32_OTGHS_DIEPTXF0_OFFSET 0x0028 /* Endpoint 0 Transmit FIFO size */ +#define STM32_OTGHS_HNPTXSTS_OFFSET 0x002c /* Non-periodic transmit FIFO/queue status register */ +#define STM32_OTGHS_GCCFG_OFFSET 0x0038 /* general core configuration register */ +#define STM32_OTGHS_CID_OFFSET 0x003c /* Core ID register */ +#define STM32_OTGHS_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ + +#define STM32_OTGHS_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) +#define STM32_OTGHS_DIEPTXF1_OFFSET 0x0104 /* Device IN endpoint transmit FIFO1 size register */ +#define STM32_OTGHS_DIEPTXF2_OFFSET 0x0108 /* Device IN endpoint transmit FIFO2 size register */ +#define STM32_OTGHS_DIEPTXF3_OFFSET 0x010c /* Device IN endpoint transmit FIFO3 size register */ + +/* Host-mode control and status registers */ + +#define STM32_OTGHS_HCFG_OFFSET 0x0400 /* Host configuration register */ +#define STM32_OTGHS_HFIR_OFFSET 0x0404 /* Host frame interval register */ +#define STM32_OTGHS_HFNUM_OFFSET 0x0408 /* Host frame number/frame time remaining register */ +#define STM32_OTGHS_HPTXSTS_OFFSET 0x0410 /* Host periodic transmit FIFO/queue status register */ +#define STM32_OTGHS_HAINT_OFFSET 0x0414 /* Host all channels interrupt register */ +#define STM32_OTGHS_HAINTMSK_OFFSET 0x0418 /* Host all channels interrupt mask register */ +#define STM32_OTGHS_HPRT_OFFSET 0x0440 /* Host port control and status register */ + +#define STM32_OTGHS_CHAN_OFFSET(n) (0x500 + ((n) << 5) +#define STM32_OTGHS_HCCHAR_CHOFFSET 0x0000 /* Host channel characteristics register */ +#define STM32_OTGHS_HCINT_CHOFFSET 0x0008 /* Host channel interrupt register */ +#define STM32_OTGHS_HCINTMSK_CHOFFSET 0x000c /* Host channel interrupt mask register */ +#define STM32_OTGHS_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */ + +#define STM32_OTGHS_HCCHAR_OFFSET(n) (0x500 + ((n) << 5)) +#define STM32_OTGHS_HCCHAR0_OFFSET 0x0500 /* Host channel-0 characteristics register */ +#define STM32_OTGHS_HCCHAR1_OFFSET 0x0520 /* Host channel-1 characteristics register */ +#define STM32_OTGHS_HCCHAR2_OFFSET 0x0540 /* Host channel-2 characteristics register */ +#define STM32_OTGHS_HCCHAR3_OFFSET 0x0560 /* Host channel-3 characteristics register */ +#define STM32_OTGHS_HCCHAR4_OFFSET 0x0580 /* Host channel-4 characteristics register */ +#define STM32_OTGHS_HCCHAR5_OFFSET 0x05a0 /* Host channel-5 characteristics register */ +#define STM32_OTGHS_HCCHAR6_OFFSET 0x05c0 /* Host channel-6 characteristics register */ +#define STM32_OTGHS_HCCHAR7_OFFSET 0x05e0 /* Host channel-7 characteristics register */ +#define STM32_OTGHS_HCCHAR8_OFFSET 0x0600 /* Host channel-8 characteristics register */ +#define STM32_OTGHS_HCCHAR9_OFFSET 0x0620 /* Host channel-9 characteristics register */ +#define STM32_OTGHS_HCCHAR10_OFFSET 0x0640 /* Host channel-10 caracteristics register */ +#define STM32_OTGHS_HCCHAR11_OFFSET 0x0660 /* Host channel-11 characteristics register */ + +#define STM32_OTGHS_HCINT_OFFSET(n) (0x508 + ((n) << 5)) +#define STM32_OTGHS_HCINT0_OFFSET 0x0508 /* Host channel-0 interrupt register */ +#define STM32_OTGHS_HCINT1_OFFSET 0x0528 /* Host channel-1 interrupt register */ +#define STM32_OTGHS_HCINT2_OFFSET 0x0548 /* Host channel-2 interrupt register */ +#define STM32_OTGHS_HCINT3_OFFSET 0x0568 /* Host channel-3 interrupt register */ +#define STM32_OTGHS_HCINT4_OFFSET 0x0588 /* Host channel-4 interrupt register */ +#define STM32_OTGHS_HCINT5_OFFSET 0x05a8 /* Host channel-5 interrupt register */ +#define STM32_OTGHS_HCINT6_OFFSET 0x05c8 /* Host channel-6 interrupt register */ +#define STM32_OTGHS_HCINT7_OFFSET 0x05e8 /* Host channel-7 interrupt register */ +#define STM32_OTGHS_HCINT8_OFFSET 0x0608 /* Host channel-8 interrupt register */ +#define STM32_OTGHS_HCINT9_OFFSET 0x0628 /* Host channel-9 interrupt register */ +#define STM32_OTGHS_HCINT10_OFFSET 0x0648 /* Host channel-10 interrupt register */ +#define STM32_OTGHS_HCINT11_OFFSET 0x0668 /* Host channel-11 interrupt register */ + +#define STM32_OTGHS_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5)) +#define STM32_OTGHS_HCINTMSK0_OFFSET 0x050c /* Host channel-0 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK1_OFFSET 0x052c /* Host channel-1 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK2_OFFSET 0x054c /* Host channel-2 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK3_OFFSET 0x056c /* Host channel-3 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK4_OFFSET 0x058c /* Host channel-4 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK5_OFFSET 0x05ac /* Host channel-5 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK6_OFFSET 0x05cc /* Host channel-6 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK7_OFFSET 0x05ec /* Host channel-7 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK8_OFFSET 0x060c /* Host channel-8 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK9_OFFSET 0x062c /* Host channel-9 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK10_OFFSET 0x064c /* Host channel-10 interrupt mask register */ +#define STM32_OTGHS_HCINTMSK11_OFFSET 0x068c /* Host channel-11 interrupt mask register */ + +#define STM32_OTGHS_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5)) +#define STM32_OTGHS_HCTSIZ0_OFFSET 0x0510 /* Host channel-0 interrupt register */ +#define STM32_OTGHS_HCTSIZ1_OFFSET 0x0530 /* Host channel-1 interrupt register */ +#define STM32_OTGHS_HCTSIZ2_OFFSET 0x0550 /* Host channel-2 interrupt register */ +#define STM32_OTGHS_HCTSIZ3_OFFSET 0x0570 /* Host channel-3 interrupt register */ +#define STM32_OTGHS_HCTSIZ4_OFFSET 0x0590 /* Host channel-4 interrupt register */ +#define STM32_OTGHS_HCTSIZ5_OFFSET 0x05b0 /* Host channel-5 interrupt register */ +#define STM32_OTGHS_HCTSIZ6_OFFSET 0x05d0 /* Host channel-6 interrupt register */ +#define STM32_OTGHS_HCTSIZ7_OFFSET 0x06f0 /* Host channel-7 interrupt register */ +#define STM32_OTGHS_HCTSIZ8_OFFSET 0x0610 /* Host channel-8 interrupt register */ +#define STM32_OTGHS_HCTSIZ9_OFFSET 0x0630 /* Host channel-9 interrupt register */ +#define STM32_OTGHS_HCTSIZ10_OFFSET 0x0650 /* Host channel-10 interrupt register */ +#define STM32_OTGHS_HCTSIZ11_OFFSET 0x05f0 /* Host channel-11 interrupt register */ + +/* Device-mode control and status registers */ + +#define STM32_OTGHS_DCFG_OFFSET 0x0800 /* Device configuration register */ +#define STM32_OTGHS_DCTL_OFFSET 0x0804 /* Device control register */ +#define STM32_OTGHS_DSTS_OFFSET 0x0808 /* Device status register */ +#define STM32_OTGHS_DIEPMSK_OFFSET 0x0810 /* Device IN endpoint common interrupt mask register */ +#define STM32_OTGHS_DOEPMSK_OFFSET 0x0814 /* Device OUT endpoint common interrupt mask register */ +#define STM32_OTGHS_DAINT_OFFSET 0x0818 /* Device all endpoints interrupt register */ +#define STM32_OTGHS_DAINTMSK_OFFSET 0x081c /* All endpoints interrupt mask register */ +#define STM32_OTGHS_DVBUSDIS_OFFSET 0x0828 /* Device VBUS discharge time register */ +#define STM32_OTGHS_DVBUSPULSE_OFFSET 0x082c /* Device VBUS pulsing time register */ +#define STM32_OTGHS_DIEPEMPMSK_OFFSET 0x0834 /* Device IN endpoint FIFO empty interrupt mask register */ + +#define STM32_OTGHS_DIEP_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGHS_DIEPCTL_EPOFFSET 0x0000 /* Device endpoint control register */ +#define STM32_OTGHS_DIEPINT_EPOFFSET 0x0008 /* Device endpoint interrupt register */ +#define STM32_OTGHS_DIEPTSIZ_EPOFFSET 0x0010 /* Device IN endpoint transfer size register */ +#define STM32_OTGHS_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */ + +#define STM32_OTGHS_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGHS_DIEPCTL0_OFFSET 0x0900 /* Device control IN endpoint 0 control register */ +#define STM32_OTGHS_DIEPCTL1_OFFSET 0x0920 /* Device control IN endpoint 2 control register */ +#define STM32_OTGHS_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */ +#define STM32_OTGHS_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */ + +#define STM32_OTGHS_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5)) +#define STM32_OTGHS_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */ +#define STM32_OTGHS_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */ +#define STM32_OTGHS_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */ +#define STM32_OTGHS_DIEPINT3_OFFSET 0x0968 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGHS_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5)) +#define STM32_OTGHS_DIEPTSIZ0_OFFSET 0x0910 /* Device IN endpoint 0 transfer size register */ +#define STM32_OTGHS_DIEPTSIZ1_OFFSET 0x0930 /* Device IN endpoint 1 transfer size register */ +#define STM32_OTGHS_DIEPTSIZ2_OFFSET 0x0950 /* Device IN endpoint 2 transfer size register */ +#define STM32_OTGHS_DIEPTSIZ3_OFFSET 0x0970 /* Device IN endpoint 3 transfer size register */ + +#define STM32_OTGHS_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5)) +#define STM32_OTGHS_DTXFSTS0_OFFSET 0x0918 /* Device OUT endpoint-0 TxFIFO status register */ +#define STM32_OTGHS_DTXFSTS1_OFFSET 0x0938 /* Device OUT endpoint-1 TxFIFO status register */ +#define STM32_OTGHS_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 TxFIFO status register */ +#define STM32_OTGHS_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 TxFIFO status register */ + +#define STM32_OTGHS_DOEP_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGHS_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */ +#define STM32_OTGHS_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */ + +#define STM32_OTGHS_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGHS_DOEPCTL0_OFFSET 0x00b00 /* Device OUT endpoint 0 control register */ +#define STM32_OTGHS_DOEPCTL1_OFFSET 0x00b20 /* Device OUT endpoint 1 control register */ +#define STM32_OTGHS_DOEPCTL2_OFFSET 0x00b40 /* Device OUT endpoint 2 control register */ +#define STM32_OTGHS_DOEPCTL3_OFFSET 0x00b60 /* Device OUT endpoint 3 control register */ + +#define STM32_OTGHS_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5)) +#define STM32_OTGHS_DOEPINT0_OFFSET 0x00b08 /* Device endpoint-0 interrupt register */ +#define STM32_OTGHS_DOEPINT1_OFFSET 0x00b28 /* Device endpoint-1 interrupt register */ +#define STM32_OTGHS_DOEPINT2_OFFSET 0x00b48 /* Device endpoint-2 interrupt register */ +#define STM32_OTGHS_DOEPINT3_OFFSET 0x00b68 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGHS_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5)) +#define STM32_OTGHS_DOEPTSIZ0_OFFSET 0x00b10 /* Device OUT endpoint-0 transfer size register */ +#define STM32_OTGHS_DOEPTSIZ1_OFFSET 0x00b30 /* Device OUT endpoint-1 transfer size register */ +#define STM32_OTGHS_DOEPTSIZ2_OFFSET 0x00b50 /* Device OUT endpoint-2 transfer size register */ +#define STM32_OTGHS_DOEPTSIZ3_OFFSET 0x00b70 /* Device OUT endpoint-3 transfer size register */ + +/* Power and clock gating registers */ + +#define STM32_OTGHS_PCGCCTL_OFFSET 0x0e00 /* Power and clock gating control register */ + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGHS_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12)) +#define STM32_OTGHS_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12)) + +#define STM32_OTGHS_DFIFO_DEP0_OFFSET 0x1000 /* 0x1000-0x1ffc Device IN/OUT Endpoint 0 DFIFO Write/Read Access */ +#define STM32_OTGHS_DFIFO_HCH0_OFFSET 0x1000 /* 0x1000-0x1ffc Host OUT/IN Channel 0 DFIFO Read/Write Access */ + +#define STM32_OTGHS_DFIFO_DEP1_OFFSET 0x2000 /* 0x2000-0x2ffc Device IN/OUT Endpoint 1 DFIFO Write/Read Access */ +#define STM32_OTGHS_DFIFO_HCH1_OFFSET 0x2000 /* 0x2000-0x2ffc Host OUT/IN Channel 1 DFIFO Read/Write Access */ + +#define STM32_OTGHS_DFIFO_DEP2_OFFSET 0x3000 /* 0x3000-0x3ffc Device IN/OUT Endpoint 2 DFIFO Write/Read Access */ +#define STM32_OTGHS_DFIFO_HCH2_OFFSET 0x3000 /* 0x3000-0x3ffc Host OUT/IN Channel 2 DFIFO Read/Write Access */ + +#define STM32_OTGHS_DFIFO_DEP3_OFFSET 0x4000 /* 0x4000-0x4ffc Device IN/OUT Endpoint 3 DFIFO Write/Read Access */ +#define STM32_OTGHS_DFIFO_HCH3_OFFSET 0x4000 /* 0x4000-0x4ffc Host OUT/IN Channel 3 DFIFO Read/Write Access */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_OTGHS_GOTGCTL (STM32_OTGHS_BASE+STM32_OTGHS_GOTGCTL_OFFSET) +#define STM32_OTGHS_GOTGINT (STM32_OTGHS_BASE+STM32_OTGHS_GOTGINT_OFFSET) +#define STM32_OTGHS_GAHBCFG (STM32_OTGHS_BASE+STM32_OTGHS_GAHBCFG_OFFSET) +#define STM32_OTGHS_GUSBCFG (STM32_OTGHS_BASE+STM32_OTGHS_GUSBCFG_OFFSET) +#define STM32_OTGHS_GRSTCTL (STM32_OTGHS_BASE+STM32_OTGHS_GRSTCTL_OFFSET) +#define STM32_OTGHS_GINTSTS (STM32_OTGHS_BASE+STM32_OTGHS_GINTSTS_OFFSET) +#define STM32_OTGHS_GINTMSK (STM32_OTGHS_BASE+STM32_OTGHS_GINTMSK_OFFSET) +#define STM32_OTGHS_GRXSTSR (STM32_OTGHS_BASE+STM32_OTGHS_GRXSTSR_OFFSET) +#define STM32_OTGHS_GRXSTSP (STM32_OTGHS_BASE+STM32_OTGHS_GRXSTSP_OFFSET) +#define STM32_OTGHS_GRXFSIZ (STM32_OTGHS_BASE+STM32_OTGHS_GRXFSIZ_OFFSET) +#define STM32_OTGHS_HNPTXFSIZ (STM32_OTGHS_BASE+STM32_OTGHS_HNPTXFSIZ_OFFSET) +#define STM32_OTGHS_DIEPTXF0 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTXF0_OFFSET) +#define STM32_OTGHS_HNPTXSTS (STM32_OTGHS_BASE+STM32_OTGHS_HNPTXSTS_OFFSET) +#define STM32_OTGHS_GCCFG (STM32_OTGHS_BASE+STM32_OTGHS_GCCFG_OFFSET) +#define STM32_OTGHS_CID (STM32_OTGHS_BASE+STM32_OTGHS_CID_OFFSET) +#define STM32_OTGHS_HPTXFSIZ (STM32_OTGHS_BASE+STM32_OTGHS_HPTXFSIZ_OFFSET) + +#define STM32_OTGHS_DIEPTXF(n) (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTXF_OFFSET(n)) +#define STM32_OTGHS_DIEPTXF1 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTXF1_OFFSET) +#define STM32_OTGHS_DIEPTXF2 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTXF2_OFFSET) +#define STM32_OTGHS_DIEPTXF3 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTXF3_OFFSET) + +/* Host-mode control and status registers */ + +#define STM32_OTGHS_HCFG (STM32_OTGHS_BASE+STM32_OTGHS_HCFG_OFFSET) +#define STM32_OTGHS_HFIR (STM32_OTGHS_BASE+STM32_OTGHS_HFIR_OFFSET) +#define STM32_OTGHS_HFNUM (STM32_OTGHS_BASE+STM32_OTGHS_HFNUM_OFFSET) +#define STM32_OTGHS_HPTXSTS (STM32_OTGHS_BASE+STM32_OTGHS_HPTXSTS_OFFSET) +#define STM32_OTGHS_HAINT (STM32_OTGHS_BASE+STM32_OTGHS_HAINT_OFFSET) +#define STM32_OTGHS_HAINTMSK (STM32_OTGHS_BASE+STM32_OTGHS_HAINTMSK_OFFSET) +#define STM32_OTGHS_HPRT (STM32_OTGHS_BASE+STM32_OTGHS_HPRT_OFFSET) + +#define STM32_OTGHS_CHAN(n) (STM32_OTGHS_BASE+STM32_OTGHS_CHAN_OFFSET(n)) + +#define STM32_OTGHS_HCCHAR(n) (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR_OFFSET(n)) +#define STM32_OTGHS_HCCHAR0 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR0_OFFSET) +#define STM32_OTGHS_HCCHAR1 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR1_OFFSET) +#define STM32_OTGHS_HCCHAR2 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR2_OFFSET) +#define STM32_OTGHS_HCCHAR3 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR3_OFFSET) +#define STM32_OTGHS_HCCHAR4 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR4_OFFSET) +#define STM32_OTGHS_HCCHAR5 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR5_OFFSET) +#define STM32_OTGHS_HCCHAR6 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR6_OFFSET) +#define STM32_OTGHS_HCCHAR7 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR7_OFFSET) +#define STM32_OTGHS_HCCHAR8 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR8_OFFSET) +#define STM32_OTGHS_HCCHAR9 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR9_OFFSET) +#define STM32_OTGHS_HCCHAR10 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR10_OFFSET) +#define STM32_OTGHS_HCCHAR11 (STM32_OTGHS_BASE+STM32_OTGHS_HCCHAR11_OFFSET) + +#define STM32_OTGHS_HCINT(n) (STM32_OTGHS_BASE+STM32_OTGHS_HCINT_OFFSET(n)) +#define STM32_OTGHS_HCINT0 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT0_OFFSET) +#define STM32_OTGHS_HCINT1 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT1_OFFSET) +#define STM32_OTGHS_HCINT2 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT2_OFFSET) +#define STM32_OTGHS_HCINT3 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT3_OFFSET) +#define STM32_OTGHS_HCINT4 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT4_OFFSET) +#define STM32_OTGHS_HCINT5 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT5_OFFSET) +#define STM32_OTGHS_HCINT6 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT6_OFFSET) +#define STM32_OTGHS_HCINT7 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT7_OFFSET) +#define STM32_OTGHS_HCINT8 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT8_OFFSET) +#define STM32_OTGHS_HCINT9 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT9_OFFSET) +#define STM32_OTGHS_HCINT10 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT10_OFFSET) +#define STM32_OTGHS_HCINT11 (STM32_OTGHS_BASE+STM32_OTGHS_HCINT11_OFFSET) + +#define STM32_OTGHS_HCINTMSK(n) (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK_OFFSET(n)) +#define STM32_OTGHS_HCINTMSK0 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK0_OFFSET) +#define STM32_OTGHS_HCINTMSK1 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK1_OFFSET) +#define STM32_OTGHS_HCINTMSK2 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK2_OFFSET) +#define STM32_OTGHS_HCINTMSK3 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK3_OFFSET) +#define STM32_OTGHS_HCINTMSK4 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK4_OFFSET) +#define STM32_OTGHS_HCINTMSK5 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK5_OFFSET) +#define STM32_OTGHS_HCINTMSK6 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK6_OFFSET) +#define STM32_OTGHS_HCINTMSK7 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK7_OFFSET) +#define STM32_OTGHS_HCINTMSK8 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK8_OFFSET) +#define STM32_OTGHS_HCINTMSK9 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK9_OFFSET) +#define STM32_OTGHS_HCINTMSK10 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK10_OFFSET) +#define STM32_OTGHS_HCINTMSK11 (STM32_OTGHS_BASE+STM32_OTGHS_HCINTMSK11_OFFSET) + +#define STM32_OTGHS_HCTSIZ(n) (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ_OFFSET(n)) +#define STM32_OTGHS_HCTSIZ0 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ0_OFFSET) +#define STM32_OTGHS_HCTSIZ1 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ1_OFFSET) +#define STM32_OTGHS_HCTSIZ2 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ2_OFFSET) +#define STM32_OTGHS_HCTSIZ3 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ3_OFFSET) +#define STM32_OTGHS_HCTSIZ4 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ4_OFFSET) +#define STM32_OTGHS_HCTSIZ5 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ5_OFFSET) +#define STM32_OTGHS_HCTSIZ6 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ6_OFFSET) +#define STM32_OTGHS_HCTSIZ7 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ7_OFFSET) +#define STM32_OTGHS_HCTSIZ8 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ8_OFFSET) +#define STM32_OTGHS_HCTSIZ9 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ9_OFFSET) +#define STM32_OTGHS_HCTSIZ10 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ10_OFFSET) +#define STM32_OTGHS_HCTSIZ11 (STM32_OTGHS_BASE+STM32_OTGHS_HCTSIZ11_OFFSET) + +/* Device-mode control and status registers */ + +#define STM32_OTGHS_DCFG (STM32_OTGHS_BASE+STM32_OTGHS_DCFG_OFFSET) +#define STM32_OTGHS_DCTL (STM32_OTGHS_BASE+STM32_OTGHS_DCTL_OFFSET) +#define STM32_OTGHS_DSTS (STM32_OTGHS_BASE+STM32_OTGHS_DSTS_OFFSET) +#define STM32_OTGHS_DIEPMSK (STM32_OTGHS_BASE+STM32_OTGHS_DIEPMSK_OFFSET) +#define STM32_OTGHS_DOEPMSK (STM32_OTGHS_BASE+STM32_OTGHS_DOEPMSK_OFFSET) +#define STM32_OTGHS_DAINT (STM32_OTGHS_BASE+STM32_OTGHS_DAINT_OFFSET) +#define STM32_OTGHS_DAINTMSK (STM32_OTGHS_BASE+STM32_OTGHS_DAINTMSK_OFFSET) +#define STM32_OTGHS_DVBUSDIS (STM32_OTGHS_BASE+STM32_OTGHS_DVBUSDIS_OFFSET) +#define STM32_OTGHS_DVBUSPULSE (STM32_OTGHS_BASE+STM32_OTGHS_DVBUSPULSE_OFFSET) +#define STM32_OTGHS_DIEPEMPMSK (STM32_OTGHS_BASE+STM32_OTGHS_DIEPEMPMSK_OFFSET) + +#define STM32_OTGHS_DIEP(n) (STM32_OTGHS_BASE+STM32_OTGHS_DIEP_OFFSET(n)) + +#define STM32_OTGHS_DIEPCTL(n) (STM32_OTGHS_BASE+STM32_OTGHS_DIEPCTL_OFFSET(n)) +#define STM32_OTGHS_DIEPCTL0 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPCTL0_OFFSET) +#define STM32_OTGHS_DIEPCTL1 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPCTL1_OFFSET) +#define STM32_OTGHS_DIEPCTL2 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPCTL2_OFFSET) +#define STM32_OTGHS_DIEPCTL3 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPCTL3_OFFSET) + +#define STM32_OTGHS_DIEPINT(n) (STM32_OTGHS_BASE+STM32_OTGHS_DIEPINT_OFFSET(n)) +#define STM32_OTGHS_DIEPINT0 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPINT0_OFFSET) +#define STM32_OTGHS_DIEPINT1 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPINT1_OFFSET) +#define STM32_OTGHS_DIEPINT2 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPINT2_OFFSET) +#define STM32_OTGHS_DIEPINT3 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPINT3_OFFSET) + +#define STM32_OTGHS_DIEPTSIZ(n) (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTSIZ_OFFSET(n)) +#define STM32_OTGHS_DIEPTSIZ0 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTSIZ0_OFFSET) +#define STM32_OTGHS_DIEPTSIZ1 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTSIZ1_OFFSET) +#define STM32_OTGHS_DIEPTSIZ2 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTSIZ2_OFFSET) +#define STM32_OTGHS_DIEPTSIZ3 (STM32_OTGHS_BASE+STM32_OTGHS_DIEPTSIZ3_OFFSET) + +#define STM32_OTGHS_DTXFSTS(n) (STM32_OTGHS_BASE+STM32_OTGHS_DTXFSTS_OFFSET(n)) +#define STM32_OTGHS_DTXFSTS0 (STM32_OTGHS_BASE+STM32_OTGHS_DTXFSTS0_OFFSET) +#define STM32_OTGHS_DTXFSTS1 (STM32_OTGHS_BASE+STM32_OTGHS_DTXFSTS1_OFFSET) +#define STM32_OTGHS_DTXFSTS2 (STM32_OTGHS_BASE+STM32_OTGHS_DTXFSTS2_OFFSET) +#define STM32_OTGHS_DTXFSTS3 (STM32_OTGHS_BASE+STM32_OTGHS_DTXFSTS3_OFFSET) + +#define STM32_OTGHS_DOEP(n) (STM32_OTGHS_BASE+STM32_OTGHS_DOEP_OFFSET(n)) + +#define STM32_OTGHS_DOEPCTL(n) (STM32_OTGHS_BASE+STM32_OTGHS_DOEPCTL_OFFSET(n)) +#define STM32_OTGHS_DOEPCTL0 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPCTL0_OFFSET) +#define STM32_OTGHS_DOEPCTL1 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPCTL1_OFFSET) +#define STM32_OTGHS_DOEPCTL2 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPCTL2_OFFSET) +#define STM32_OTGHS_DOEPCTL3 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPCTL3_OFFSET) + +#define STM32_OTGHS_DOEPINT(n) (STM32_OTGHS_BASE+STM32_OTGHS_DOEPINT_OFFSET(n)) +#define STM32_OTGHS_DOEPINT0 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPINT0_OFFSET) +#define STM32_OTGHS_DOEPINT1 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPINT1_OFFSET) +#define STM32_OTGHS_DOEPINT2 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPINT2_OFFSET) +#define STM32_OTGHS_DOEPINT3 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPINT3_OFFSET) + +#define STM32_OTGHS_DOEPTSIZ(n) (STM32_OTGHS_BASE+STM32_OTGHS_DOEPTSIZ_OFFSET(n)) +#define STM32_OTGHS_DOEPTSIZ0 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPTSIZ0_OFFSET) +#define STM32_OTGHS_DOEPTSIZ1 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPTSIZ1_OFFSET) +#define STM32_OTGHS_DOEPTSIZ2 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPTSIZ2_OFFSET) +#define STM32_OTGHS_DOEPTSIZ3 (STM32_OTGHS_BASE+STM32_OTGHS_DOEPTSIZ3_OFFSET) + +/* Power and clock gating registers */ + +#define STM32_OTGHS_PCGCCTL (STM32_OTGHS_BASE+STM32_OTGHS_PCGCCTL_OFFSET) + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGHS_DFIFO_DEP(n) (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_DEP_OFFSET(n)) +#define STM32_OTGHS_DFIFO_HCH(n) (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_HCH_OFFSET(n)) + +#define STM32_OTGHS_DFIFO_DEP0 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_DEP0_OFFSET) +#define STM32_OTGHS_DFIFO_HCH0 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_HCH0_OFFSET) + +#define STM32_OTGHS_DFIFO_DEP1 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_DEP1_OFFSET) +#define STM32_OTGHS_DFIFO_HCH1 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_HCH1_OFFSET) + +#define STM32_OTGHS_DFIFO_DEP2 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_DEP2_OFFSET) +#define STM32_OTGHS_DFIFO_HCH2 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_HCH2_OFFSET) + +#define STM32_OTGHS_DFIFO_DEP3 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_DEP3_OFFSET) +#define STM32_OTGHS_DFIFO_HCH3 (STM32_OTGHS_BASE+STM32_OTGHS_DFIFO_HCH3_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* Core global control and status registers */ + +/* Control and status register */ + +#define OTGHS_GOTGCTL_SRQSCS (1 << 0) /* Bit 0: Session request success */ +#define OTGHS_GOTGCTL_SRQ (1 << 1) /* Bit 1: Session request */ + /* Bits 2-72 Reserved, must be kept at reset value */ +#define OTGHS_GOTGCTL_HNGSCS (1 << 8) /* Bit 8: Host negotiation success */ +#define OTGHS_GOTGCTL_HNPRQ (1 << 9) /* Bit 9: HNP request */ +#define OTGHS_GOTGCTL_HSHNPEN (1 << 10) /* Bit 10: host set HNP enable */ +#define OTGHS_GOTGCTL_DHNPEN (1 << 11) /* Bit 11: Device HNP enabled */ + /* Bits 12-15: Reserved, must be kept at reset value */ +#define OTGHS_GOTGCTL_CIDSTS (1 << 16) /* Bit 16: Connector ID status */ +#define OTGHS_GOTGCTL_DBCT (1 << 17) /* Bit 17: Long/short debounce time */ +#define OTGHS_GOTGCTL_ASVLD (1 << 18) /* Bit 18: A-session valid */ +#define OTGHS_GOTGCTL_BSVLD (1 << 19) /* Bit 19: B-session valid */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Interrupt register */ + /* Bits 1:0 Reserved, must be kept at reset value */ +#define OTGHS_GOTGINT_SEDET (1 << 2) /* Bit 2: Session end detected */ + /* Bits 3-7: Reserved, must be kept at reset value */ +#define OTGHS_GOTGINT_SRSSCHG (1 << 8) /* Bit 8: Session request success status change */ +#define OTGHS_GOTGINT_HNSSCHG (1 << 9) /* Bit 9: Host negotiation success status change */ + /* Bits 16:10 Reserved, must be kept at reset value */ +#define OTGHS_GOTGINT_HNGDET (1 << 17) /* Bit 17: Host negotiation detected */ +#define OTGHS_GOTGINT_ADTOCHG (1 << 18) /* Bit 18: A-device timeout change */ +#define OTGHS_GOTGINT_DBCDNE (1 << 19) /* Bit 19: Debounce done */ + /* Bits 2-31: Reserved, must be kept at reset value */ + +/* AHB configuration register */ + +#define OTGHS_GAHBCFG_GINTMSK (1 << 0) /* Bit 0: Global interrupt mask */ + /* Bits 1-6: Reserved, must be kept at reset value */ +#define OTGHS_GAHBCFG_TXFELVL (1 << 7) /* Bit 7: TxFIFO empty level */ +#define OTGHS_GAHBCFG_PTXFELVL (1 << 8) /* Bit 8: Periodic TxFIFO empty level */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* USB configuration register */ + +#define OTGHS_GUSBCFG_TOCAL_SHIFT (0) /* Bits 0-2: FS timeout calibration */ +#define OTGHS_GUSBCFG_TOCAL_MASK (7 << OTGHS_GUSBCFG_TOCAL_SHIFT) + /* Bits 3-5: Reserved, must be kept at reset value */ +#define OTGHS_GUSBCFG_PHYSEL (1 << 6) /* Bit 6: Full Speed serial transceiver select */ + /* Bit 7: Reserved, must be kept at reset value */ +#define OTGHS_GUSBCFG_SRPCAP (1 << 8) /* Bit 8: SRP-capable */ +#define OTGHS_GUSBCFG_HNPCAP (1 << 9) /* Bit 9: HNP-capable */ +#define OTGHS_GUSBCFG_TRDT_SHIFT (10) /* Bits 10-13: USB turnaround time */ +#define OTGHS_GUSBCFG_TRDT_MASK (15 << OTGHS_GUSBCFG_TRDT_SHIFT) +# define OTGHS_GUSBCFG_TRDT(n) ((n) << OTGHS_GUSBCFG_TRDT_SHIFT) + /* Bits 14-28: Reserved, must be kept at reset value */ +#define OTGHS_GUSBCFG_FHMOD (1 << 29) /* Bit 29: Force host mode */ +#define OTGHS_GUSBCFG_FDMOD (1 << 30) /* Bit 30: Force device mode */ +#define OTGHS_GUSBCFG_CTXPKT (1 << 31) /* Bit 31: Corrupt Tx packet */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Reset register */ + +#define OTGHS_GRSTCTL_CSRST (1 << 0) /* Bit 0: Core soft reset */ +#define OTGHS_GRSTCTL_HSRST (1 << 1) /* Bit 1: HCLK soft reset */ +#define OTGHS_GRSTCTL_FCRST (1 << 2) /* Bit 2: Host frame counter reset */ + /* Bit 3 Reserved, must be kept at reset value */ +#define OTGHS_GRSTCTL_RXFFLSH (1 << 4) /* Bit 4: RxFIFO flush */ +#define OTGHS_GRSTCTL_TXFFLSH (1 << 5) /* Bit 5: TxFIFO flush */ +#define OTGHS_GRSTCTL_TXFNUM_SHIFT (10) /* Bits 6-10: TxFIFO number */ +#define OTGHS_GRSTCTL_TXFNUM_MASK (31 << OTGHS_GRSTCTL_TXFNUM_SHIFT) +# define OTGHS_GRSTCTL_TXFNUM_HNONPER (0 << OTGHS_GRSTCTL_TXFNUM_SHIFT) /* Non-periodic TxFIFO flush in host mode */ +# define OTGHS_GRSTCTL_TXFNUM_HPER (1 << OTGHS_GRSTCTL_TXFNUM_SHIFT) /* Periodic TxFIFO flush in host mode */ +# define OTGHS_GRSTCTL_TXFNUM_HALL (16 << OTGHS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in host mode.*/ +# define OTGHS_GRSTCTL_TXFNUM_D(n) ((n) << OTGHS_GRSTCTL_TXFNUM_SHIFT) /* TXFIFO n flush in device mode, n=0-15 */ +# define OTGHS_GRSTCTL_TXFNUM_DALL (16 << OTGHS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in device mode.*/ + /* Bits 11-31: Reserved, must be kept at reset value */ +#define OTGHS_GRSTCTL_AHBIDL (1 << 31) /* Bit 31: AHB master idle */ + +/* Core interrupt and Interrupt mask registers */ + +#define OTGHS_GINTSTS_CMOD (1 << 0) /* Bit 0: Current mode of operation */ +# define OTGHS_GINTSTS_DEVMODE (0) +# define OTGHS_GINTSTS_HOSTMODE (OTGHS_GINTSTS_CMOD) +#define OTGHS_GINT_MMIS (1 << 1) /* Bit 1: Mode mismatch interrupt */ +#define OTGHS_GINT_OTG (1 << 2) /* Bit 2: OTG interrupt */ +#define OTGHS_GINT_SOF (1 << 3) /* Bit 3: Start of frame */ +#define OTGHS_GINT_RXFLVL (1 << 4) /* Bit 4: RxFIFO non-empty */ +#define OTGHS_GINT_NPTXFE (1 << 5) /* Bit 5: Non-periodic TxFIFO empty */ +#define OTGHS_GINT_GINAKEFF (1 << 6) /* Bit 6: Global IN non-periodic NAK effective */ +#define OTGHS_GINT_GONAKEFF (1 << 7) /* Bit 7: Global OUT NAK effective */ + /* Bits 8-9: Reserved, must be kept at reset value */ +#define OTGHS_GINT_ESUSP (1 << 10) /* Bit 10: Early suspend */ +#define OTGHS_GINT_USBSUSP (1 << 11) /* Bit 11: USB suspend */ +#define OTGHS_GINT_USBRST (1 << 12) /* Bit 12: USB reset */ +#define OTGHS_GINT_ENUMDNE (1 << 13) /* Bit 13: Enumeration done */ +#define OTGHS_GINT_ISOODRP (1 << 14) /* Bit 14: Isochronous OUT packet dropped interrupt */ +#define OTGHS_GINT_EOPF (1 << 15) /* Bit 15: End of periodic frame interrupt */ + /* Bits 16 Reserved, must be kept at reset value */ +#define OTGHS_GINTMSK_EPMISM (1 << 17) /* Bit 17: Endpoint mismatch interrupt mask */ +#define OTGHS_GINT_IEP (1 << 18) /* Bit 18: IN endpoint interrupt */ +#define OTGHS_GINT_OEP (1 << 19) /* Bit 19: OUT endpoint interrupt */ +#define OTGHS_GINT_IISOIXFR (1 << 20) /* Bit 20: Incomplete isochronous IN transfer */ +#define OTGHS_GINT_IISOOXFR (1 << 21) /* Bit 21: Incomplete isochronous OUT transfer */ +#define OTGHS_GINT_IPXFR (1 << 21) /* Bit 21: Incomplete periodic transfer (host) */ + /* Bits 22-23: Reserved, must be kept at reset value */ +#define OTGHS_GINT_HPRT (1 << 24) /* Bit 24: Host port interrupt */ +#define OTGHS_GINT_HC (1 << 25) /* Bit 25: Host channels interrupt */ +#define OTGHS_GINT_PTXFE (1 << 26) /* Bit 26: Periodic TxFIFO empty */ + /* Bit 27 Reserved, must be kept at reset value */ +#define OTGHS_GINT_CIDSCHG (1 << 28) /* Bit 28: Connector ID status change */ +#define OTGHS_GINT_DISC (1 << 29) /* Bit 29: Disconnect detected interrupt */ +#define OTGHS_GINT_SRQ (1 << 30) /* Bit 30: Session request/new session detected interrupt */ +#define OTGHS_GINT_WKUP (1 << 31) /* Bit 31: Resume/remote wakeup detected interrupt */ + +/* Receive status debug read/OTG status read and pop registers (host mode) */ + +#define OTGHS_GRXSTSH_CHNUM_SHIFT (0) /* Bits 0-3: Channel number */ +#define OTGHS_GRXSTSH_CHNUM_MASK (15 << OTGHS_GRXSTSH_CHNUM_SHIFT) +#define OTGHS_GRXSTSH_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGHS_GRXSTSH_BCNT_MASK (0x7ff << OTGHS_GRXSTSH_BCNT_SHIFT) +#define OTGHS_GRXSTSH_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGHS_GRXSTSH_DPID_MASK (3 << OTGHS_GRXSTSH_DPID_SHIFT) +# define OTGHS_GRXSTSH_DPID_DATA0 (0 << OTGHS_GRXSTSH_DPID_SHIFT) +# define OTGHS_GRXSTSH_DPID_DATA2 (1 << OTGHS_GRXSTSH_DPID_SHIFT) +# define OTGHS_GRXSTSH_DPID_DATA1 (2 << OTGHS_GRXSTSH_DPID_SHIFT) +# define OTGHS_GRXSTSH_DPID_MDATA (3 << OTGHS_GRXSTSH_DPID_SHIFT) +#define OTGHS_GRXSTSH_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGHS_GRXSTSH_PKTSTS_MASK (15 << OTGHS_GRXSTSH_PKTSTS_SHIFT) +# define OTGHS_GRXSTSH_PKTSTS_INRECVD (2 << OTGHS_GRXSTSH_PKTSTS_SHIFT) /* IN data packet received */ +# define OTGHS_GRXSTSH_PKTSTS_INDONE (3 << OTGHS_GRXSTSH_PKTSTS_SHIFT) /* IN transfer completed */ +# define OTGHS_GRXSTSH_PKTSTS_DTOGERR (5 << OTGHS_GRXSTSH_PKTSTS_SHIFT) /* Data toggle error */ +# define OTGHS_GRXSTSH_PKTSTS_HALTED (7 << OTGHS_GRXSTSH_PKTSTS_SHIFT) /* Channel halted */ + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Receive status debug read/OTG status read and pop registers (device mode) */ + +#define OTGHS_GRXSTSD_EPNUM_SHIFT (0) /* Bits 0-3: Endpoint number */ +#define OTGHS_GRXSTSD_EPNUM_MASK (15 << OTGHS_GRXSTSD_EPNUM_SHIFT) +#define OTGHS_GRXSTSD_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGHS_GRXSTSD_BCNT_MASK (0x7ff << OTGHS_GRXSTSD_BCNT_SHIFT) +#define OTGHS_GRXSTSD_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGHS_GRXSTSD_DPID_MASK (3 << OTGHS_GRXSTSD_DPID_SHIFT) +# define OTGHS_GRXSTSD_DPID_DATA0 (0 << OTGHS_GRXSTSD_DPID_SHIFT) +# define OTGHS_GRXSTSD_DPID_DATA2 (1 << OTGHS_GRXSTSD_DPID_SHIFT) +# define OTGHS_GRXSTSD_DPID_DATA1 (2 << OTGHS_GRXSTSD_DPID_SHIFT) +# define OTGHS_GRXSTSD_DPID_MDATA (3 << OTGHS_GRXSTSD_DPID_SHIFT) +#define OTGHS_GRXSTSD_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGHS_GRXSTSD_PKTSTS_MASK (15 << OTGHS_GRXSTSD_PKTSTS_SHIFT) +# define OTGHS_GRXSTSD_PKTSTS_OUTNAK (1 << OTGHS_GRXSTSD_PKTSTS_SHIFT) /* Global OUT NAK */ +# define OTGHS_GRXSTSD_PKTSTS_OUTRECVD (2 << OTGHS_GRXSTSD_PKTSTS_SHIFT) /* OUT data packet received */ +# define OTGHS_GRXSTSD_PKTSTS_OUTDONE (3 << OTGHS_GRXSTSD_PKTSTS_SHIFT) /* OUT transfer completed */ +# define OTGHS_GRXSTSD_PKTSTS_SETUPDONE (4 << OTGHS_GRXSTSD_PKTSTS_SHIFT) /* SETUP transaction completed */ +# define OTGHS_GRXSTSD_PKTSTS_SETUPRECVD (6 << OTGHS_GRXSTSD_PKTSTS_SHIFT) /* SETUP data packet received */ +#define OTGHS_GRXSTSD_FRMNUM_SHIFT (21) /* Bits 21-24: Frame number */ +#define OTGHS_GRXSTSD_FRMNUM_MASK (15 << OTGHS_GRXSTSD_FRMNUM_SHIFT) + /* Bits 25-31: Reserved, must be kept at reset value */ +/* Receive FIFO size register */ + +#define OTGHS_GRXFSIZ_MASK (0xffff) + +/* Host non-periodic transmit FIFO size register */ + +#define OTGHS_HNPTXFSIZ_NPTXFSA_SHIFT (0) /* Bits 0-15: Non-periodic transmit RAM start address */ +#define OTGHS_HNPTXFSIZ_NPTXFSA_MASK (0xffff << OTGHS_HNPTXFSIZ_NPTXFSA_SHIFT) +#define OTGHS_HNPTXFSIZ_NPTXFD_SHIFT (16) /* Bits 16-31: Non-periodic TxFIFO depth */ +#define OTGHS_HNPTXFSIZ_NPTXFD_MASK (0xffff << OTGHS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGHS_HNPTXFSIZ_NPTXFD_MIN (16 << OTGHS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGHS_HNPTXFSIZ_NPTXFD_MAX (256 << OTGHS_HNPTXFSIZ_NPTXFD_SHIFT) + +/* Endpoint 0 Transmit FIFO size */ + +#define OTGHS_DIEPTXF0_TX0FD_SHIFT (0) /* Bits 0-15: Endpoint 0 transmit RAM start address */ +#define OTGHS_DIEPTXF0_TX0FD_MASK (0xffff << OTGHS_DIEPTXF0_TX0FD_SHIFT) +#define OTGHS_DIEPTXF0_TX0FSA_SHIFT (16) /* Bits 16-31: Endpoint 0 TxFIFO depth */ +#define OTGHS_DIEPTXF0_TX0FSA_MASK (0xffff << OTGHS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGHS_DIEPTXF0_TX0FSA_MIN (16 << OTGHS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGHS_DIEPTXF0_TX0FSA_MAX (256 << OTGHS_DIEPTXF0_TX0FSA_SHIFT) + +/* Non-periodic transmit FIFO/queue status register */ + +#define OTGHS_HNPTXSTS_NPTXFSAV_SHIFT (0) /* Bits 0-15: Non-periodic TxFIFO space available */ +#define OTGHS_HNPTXSTS_NPTXFSAV_MASK (0xffff << OTGHS_HNPTXSTS_NPTXFSAV_SHIFT) +# define OTGHS_HNPTXSTS_NPTXFSAV_FULL (0 << OTGHS_HNPTXSTS_NPTXFSAV_SHIFT) +#define OTGHS_HNPTXSTS_NPTQXSAV_SHIFT (16) /* Bits 16-23: Non-periodic transmit request queue space available */ +#define OTGHS_HNPTXSTS_NPTQXSAV_MASK (0xff << OTGHS_HNPTXSTS_NPTQXSAV_SHIFT) +# define OTGHS_HNPTXSTS_NPTQXSAV_FULL (0 << OTGHS_HNPTXSTS_NPTQXSAV_SHIFT) +#define OTGHS_HNPTXSTS_NPTXQTOP_SHIFT (24) /* Bits 24-30: Top of the non-periodic transmit request queue */ +#define OTGHS_HNPTXSTS_NPTXQTOP_MASK (0x7f << OTGHS_HNPTXSTS_NPTXQTOP_SHIFT) +# define OTGHS_HNPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGHS_HNPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Status */ +# define OTGHS_HNPTXSTS_TYPE_MASK (3 << OTGHS_HNPTXSTS_TYPE_SHIFT) +# define OTGHS_HNPTXSTS_TYPE_INOUT (0 << OTGHS_HNPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGHS_HNPTXSTS_TYPE_ZLP (1 << OTGHS_HNPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet (device IN/host OUT) */ +# define OTGHS_HNPTXSTS_TYPE_HALT (3 << OTGHS_HNPTXSTS_TYPE_SHIFT) /* Channel halt command */ +# define OTGHS_HNPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGHS_HNPTXSTS_CHNUM_MASK (15 << OTGHS_HNPTXSTS_CHNUM_SHIFT) +# define OTGHS_HNPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGHS_HNPTXSTS_EPNUM_MASK (15 << OTGHS_HNPTXSTS_EPNUM_SHIFT) + /* Bit 31 Reserved, must be kept at reset value */ +/* General core configuration register */ + /* Bits 15:0 Reserved, must be kept at reset value */ +#define OTGHS_GCCFG_PWRDWN (1 << 16) /* Bit 16: Power down */ + /* Bit 17 Reserved, must be kept at reset value */ +#define OTGHS_GCCFG_VBUSASEN (1 << 18) /* Bit 18: Enable the VBUS sensing “A” device */ +#define OTGHS_GCCFG_VBUSBSEN (1 << 19) /* Bit 19: Enable the VBUS sensing “B” device */ +#define OTGHS_GCCFG_SOFOUTEN (1 << 20) /* Bit 20: SOF output enable */ +#define OTGHS_GCCFG_NOVBUSSENS (1 << 21) /* Bit 21: VBUS sensing disable option */ + /* Bits 31:22 Reserved, must be kept at reset value */ +/* Core ID register (32-bit product ID) */ + +/* Host periodic transmit FIFO size register */ + +#define OTGHS_HPTXFSIZ_PTXSA_SHIFT (0) /* Bits 0-15: Host periodic TxFIFO start address */ +#define OTGHS_HPTXFSIZ_PTXSA_MASK (0xffff << OTGHS_HPTXFSIZ_PTXSA_SHIFT) +#define OTGHS_HPTXFSIZ_PTXFD_SHIFT (16) /* Bits 16-31: Host periodic TxFIFO depth */ +#define OTGHS_HPTXFSIZ_PTXFD_MASK (0xffff << OTGHS_HPTXFSIZ_PTXFD_SHIFT) + +/* Device IN endpoint transmit FIFOn size register */ + +#define OTGHS_DIEPTXF_INEPTXSA_SHIFT (0) /* Bits 0-15: IN endpoint FIFOx transmit RAM start address */ +#define OTGHS_DIEPTXF_INEPTXSA_MASK (0xffff << OTGHS_DIEPTXF_INEPTXSA_SHIFT) +#define OTGHS_DIEPTXF_INEPTXFD_SHIFT (16) /* Bits 16-31: IN endpoint TxFIFO depth */ +#define OTGHS_DIEPTXF_INEPTXFD_MASK (0xffff << OTGHS_DIEPTXF_INEPTXFD_SHIFT) +# define OTGHS_DIEPTXF_INEPTXFD_MIN (16 << OTGHS_DIEPTXF_INEPTXFD_MASK) + +/* Host-mode control and status registers */ + +/* Host configuration register */ + +#define OTGHS_HCFG_FSLSPCS_SHIFT (0) /* Bits 0-1: FS/LS PHY clock select */ +#define OTGHS_HCFG_FSLSPCS_MASK (3 << OTGHS_HCFG_FSLSPCS_SHIFT) +# define OTGHS_HCFG_FSLSPCS_FS48MHz (1 << OTGHS_HCFG_FSLSPCS_SHIFT) /* FS host mode, PHY clock is running at 48 MHz */ +# define OTGHS_HCFG_FSLSPCS_LS48MHz (1 << OTGHS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 48 MHz PHY clock frequency */ +# define OTGHS_HCFG_FSLSPCS_LS6MHz (2 << OTGHS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 6 MHz PHY clock frequency */ +#define OTGHS_HCFG_FSLSS (1 << 2) /* Bit 2: FS- and LS-only support */ + /* Bits 31:3 Reserved, must be kept at reset value */ +/* Host frame interval register */ + +#define OTGHS_HFIR_MASK (0xffff) + +/* Host frame number/frame time remaining register */ + +#define OTGHS_HFNUM_FRNUM_SHIFT (0) /* Bits 0-15: Frame number */ +#define OTGHS_HFNUM_FRNUM_MASK (0xffff << OTGHS_HFNUM_FRNUM_SHIFT) +#define OTGHS_HFNUM_FTREM_SHIFT (16) /* Bits 16-31: Frame time remaining */ +#define OTGHS_HFNUM_FTREM_MASK (0xffff << OTGHS_HFNUM_FTREM_SHIFT) + +/* Host periodic transmit FIFO/queue status register */ + +#define OTGHS_HPTXSTS_PTXFSAVL_SHIFT (0) /* Bits 0-15: Periodic transmit data FIFO space available */ +#define OTGHS_HPTXSTS_PTXFSAVL_MASK (0xffff << OTGHS_HPTXSTS_PTXFSAVL_SHIFT) +# define OTGHS_HPTXSTS_PTXFSAVL_FULL (0 << OTGHS_HPTXSTS_PTXFSAVL_SHIFT) +#define OTGHS_HPTXSTS_PTXQSAV_SHIFT (16) /* Bits 16-23: Periodic transmit request queue space available */ +#define OTGHS_HPTXSTS_PTXQSAV_MASK (0xff << OTGHS_HPTXSTS_PTXQSAV_SHIFT) +# define OTGHS_HPTXSTS_PTXQSAV_FULL (0 << OTGHS_HPTXSTS_PTXQSAV_SHIFT) +#define OTGHS_HPTXSTS_PTXQTOP_SHIFT (24) /* Bits 24-31: Top of the periodic transmit request queue */ +#define OTGHS_HPTXSTS_PTXQTOP_MASK (0x7f << OTGHS_HPTXSTS_PTXQTOP_SHIFT) +# define OTGHS_HPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGHS_HPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Type */ +# define OTGHS_HPTXSTS_TYPE_MASK (3 << OTGHS_HPTXSTS_TYPE_SHIFT) +# define OTGHS_HPTXSTS_TYPE_INOUT (0 << OTGHS_HPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGHS_HPTXSTS_TYPE_ZLP (1 << OTGHS_HPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet */ +# define OTGHS_HPTXSTS_TYPE_HALT (3 << OTGHS_HPTXSTS_TYPE_SHIFT) /* Disable channel command */ +# define OTGHS_HPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGHS_HPTXSTS_EPNUM_MASK (15 << OTGHS_HPTXSTS_EPNUM_SHIFT) +# define OTGHS_HPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGHS_HPTXSTS_CHNUM_MASK (15 << OTGHS_HPTXSTS_CHNUM_SHIFT) +# define OTGHS_HPTXSTS_ODD (1 << 24) /* Bit 31: Send in odd (vs even) frame */ + +/* Host all channels interrupt and all channels interrupt mask registers */ + +#define OTGHS_HAINT(n) (1 << (n)) /* Bits 15:0 HAINTM: Channel interrupt */ + +/* Host port control and status register */ + +#define OTGHS_HPRT_PCSTS (1 << 0) /* Bit 0: Port connect status */ +#define OTGHS_HPRT_PCDET (1 << 1) /* Bit 1: Port connect detected */ +#define OTGHS_HPRT_PENA (1 << 2) /* Bit 2: Port enable */ +#define OTGHS_HPRT_PENCHNG (1 << 3) /* Bit 3: Port enable/disable change */ +#define OTGHS_HPRT_POCA (1 << 4) /* Bit 4: Port overcurrent active */ +#define OTGHS_HPRT_POCCHNG (1 << 5) /* Bit 5: Port overcurrent change */ +#define OTGHS_HPRT_PRES (1 << 6) /* Bit 6: Port resume */ +#define OTGHS_HPRT_PSUSP (1 << 7) /* Bit 7: Port suspend */ +#define OTGHS_HPRT_PRST (1 << 8) /* Bit 8: Port reset */ + /* Bit 9: Reserved, must be kept at reset value */ +#define OTGHS_HPRT_PLSTS_SHIFT (10) /* Bits 10-11: Port line status */ +#define OTGHS_HPRT_PLSTS_MASK (3 << OTGHS_HPRT_PLSTS_SHIFT) +# define OTGHS_HPRT_PLSTS_DP (1 << 10) /* Bit 10: Logic level of OTG_FS_FS_DP */ +# define OTGHS_HPRT_PLSTS_DM (1 << 11) /* Bit 11: Logic level of OTG_FS_FS_DM */ +#define OTGHS_HPRT_PPWR (1 << 12) /* Bit 12: Port power */ +#define OTGHS_HPRT_PTCTL_SHIFT (13) /* Bits 13-16: Port test control */ +#define OTGHS_HPRT_PTCTL_MASK (15 << OTGHS_HPRT_PTCTL_SHIFT) +# define OTGHS_HPRT_PTCTL_DISABLED (0 << OTGHS_HPRT_PTCTL_SHIFT) /* Test mode disabled */ +# define OTGHS_HPRT_PTCTL_J (1 << OTGHS_HPRT_PTCTL_SHIFT) /* Test_J mode */ +# define OTGHS_HPRT_PTCTL_L (2 << OTGHS_HPRT_PTCTL_SHIFT) /* Test_K mode */ +# define OTGHS_HPRT_PTCTL_SE0_NAK (3 << OTGHS_HPRT_PTCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGHS_HPRT_PTCTL_PACKET (4 << OTGHS_HPRT_PTCTL_SHIFT) /* Test_Packet mode */ +# define OTGHS_HPRT_PTCTL_FORCE (5 << OTGHS_HPRT_PTCTL_SHIFT) /* Test_Force_Enable */ +#define OTGHS_HPRT_PSPD_SHIFT (17) /* Bits 17-18: Port speed */ +#define OTGHS_HPRT_PSPD_MASK (3 << OTGHS_HPRT_PSPD_SHIFT) +# define OTGHS_HPRT_PSPD_FS (1 << OTGHS_HPRT_PSPD_SHIFT) /* Full speed */ +# define OTGHS_HPRT_PSPD_LS (2 << OTGHS_HPRT_PSPD_SHIFT) /* Low speed */ + /* Bits 19-31: Reserved, must be kept at reset value */ + +/* Host channel-n characteristics register */ + +#define OTGHS_HCCHAR_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGHS_HCCHAR_MPSIZ_MASK (0x7ff << OTGHS_HCCHAR_MPSIZ_SHIFT) +#define OTGHS_HCCHAR_EPNUM_SHIFT (11) /* Bits 11-14: Endpoint number */ +#define OTGHS_HCCHAR_EPNUM_MASK (15 << OTGHS_HCCHAR_EPNUM_SHIFT) +#define OTGHS_HCCHAR_EPDIR (1 << 15) /* Bit 15: Endpoint direction */ +# define OTGHS_HCCHAR_EPDIR_OUT (0) +# define OTGHS_HCCHAR_EPDIR_IN OTGHS_HCCHAR_EPDIR + /* Bit 16 Reserved, must be kept at reset value */ +#define OTGHS_HCCHAR_LSDEV (1 << 17) /* Bit 17: Low-speed device */ +#define OTGHS_HCCHAR_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGHS_HCCHAR_EPTYP_MASK (3 << OTGHS_HCCHAR_EPTYP_SHIFT) +# define OTGHS_HCCHAR_EPTYP_CTRL (0 << OTGHS_HCCHAR_EPTYP_SHIFT) /* Control */ +# define OTGHS_HCCHAR_EPTYP_ISOC (1 << OTGHS_HCCHAR_EPTYP_SHIFT) /* Isochronous */ +# define OTGHS_HCCHAR_EPTYP_BULK (2 << OTGHS_HCCHAR_EPTYP_SHIFT) /* Bulk */ +# define OTGHS_HCCHAR_EPTYP_INTR (3 << OTGHS_HCCHAR_EPTYP_SHIFT) /* Interrupt */ +#define OTGHS_HCCHAR_MCNT_SHIFT (20) /* Bits 20-21: Multicount */ +#define OTGHS_HCCHAR_MCNT_MASK (3 << OTGHS_HCCHAR_MCNT_SHIFT) +#define OTGHS_HCCHAR_DAD_SHIFT (22) /* Bits 22-28: Device address */ +#define OTGHS_HCCHAR_DAD_MASK (0x7f << OTGHS_HCCHAR_DAD_SHIFT) +#define OTGHS_HCCHAR_ODDFRM (1 << 29) /* Bit 29: Odd frame */ +#define OTGHS_HCCHAR_CHDIS (1 << 30) /* Bit 30: Channel disable */ +#define OTGHS_HCCHAR_CHENA (1 << 31) /* Bit 31: Channel enable */ + +/* Host channel-n interrupt and Host channel-0 interrupt mask registers */ + +#define OTGHS_HCINT_XFRC (1 << 0) /* Bit 0: Transfer completed */ +#define OTGHS_HCINT_CHH (1 << 1) /* Bit 1: Channel halted */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGHS_HCINT_STALL (1 << 3) /* Bit 3: STALL response received interrupt */ +#define OTGHS_HCINT_NAK (1 << 4) /* Bit 4: NAK response received interrupt */ +#define OTGHS_HCINT_ACK (1 << 5) /* Bit 5: ACK response received/transmitted interrupt */ +#define OTGHS_HCINT_NYET (1 << 6) /* Bit 6: Response received interrupt */ +#define OTGHS_HCINT_TXERR (1 << 7) /* Bit 7: Transaction error */ +#define OTGHS_HCINT_BBERR (1 << 8) /* Bit 8: Babble error */ +#define OTGHS_HCINT_FRMOR (1 << 9) /* Bit 9: Frame overrun */ +#define OTGHS_HCINT_DTERR (1 << 10) /* Bit 10: Data toggle error */ + /* Bits 11-31 Reserved, must be kept at reset value */ +/* Host channel-n interrupt register */ + +#define OTGHS_HCTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGHS_HCTSIZ_XFRSIZ_MASK (0x7ffff << OTGHS_HCTSIZ_XFRSIZ_SHIFT) +#define OTGHS_HCTSIZ_PKTCNT_SHIFT (19) /* Bits 19-28: Packet count */ +#define OTGHS_HCTSIZ_PKTCNT_MASK (0x3ff << OTGHS_HCTSIZ_PKTCNT_SHIFT) +#define OTGHS_HCTSIZ_DPID_SHIFT (29) /* Bits 29-30: Data PID */ +#define OTGHS_HCTSIZ_DPID_MASK (3 << OTGHS_HCTSIZ_DPID_SHIFT) +# define OTGHS_HCTSIZ_DPID_DATA0 (0 << OTGHS_HCTSIZ_DPID_SHIFT) +# define OTGHS_HCTSIZ_DPID_DATA2 (1 << OTGHS_HCTSIZ_DPID_SHIFT) +# define OTGHS_HCTSIZ_DPID_DATA1 (2 << OTGHS_HCTSIZ_DPID_SHIFT) +# define OTGHS_HCTSIZ_DPID_MDATA (3 << OTGHS_HCTSIZ_DPID_SHIFT) /* Non-control */ +# define OTGHS_HCTSIZ_PID_SETUP (3 << OTGHS_HCTSIZ_DPID_SHIFT) /* Control */ + /* Bit 31 Reserved, must be kept at reset value */ +/* Device-mode control and status registers */ + +/* Device configuration register */ + +#define OTGHS_DCFG_DSPD_SHIFT (0) /* Bits 0-1: Device speed */ +#define OTGHS_DCFG_DSPD_MASK (3 << OTGHS_DCFG_DSPD_SHIFT) +# define OTGHS_DCFG_DSPD_FS (3 << OTGHS_DCFG_DSPD_SHIFT) /* Full speed */ +#define OTGHS_DCFG_NZLSOHSK (1 << 2) /* Bit 2: Non-zero-length status OUT handshake */ + /* Bit 3: Reserved, must be kept at reset value */ +#define OTGHS_DCFG_DAD_SHIFT (4) /* Bits 4-10: Device address */ +#define OTGHS_DCFG_DAD_MASK (0x7f << OTGHS_DCFG_DAD_SHIFT) +#define OTGHS_DCFG_PFIVL_SHIFT (11) /* Bits 11-12: Periodic frame interval */ +#define OTGHS_DCFG_PFIVL_MASK (3 << OTGHS_DCFG_PFIVL_SHIFT) +# define OTGHS_DCFG_PFIVL_80PCT (0 << OTGHS_DCFG_PFIVL_SHIFT) /* 80% of the frame interval */ +# define OTGHS_DCFG_PFIVL_85PCT (1 << OTGHS_DCFG_PFIVL_SHIFT) /* 85% of the frame interval */ +# define OTGHS_DCFG_PFIVL_90PCT (2 << OTGHS_DCFG_PFIVL_SHIFT) /* 90% of the frame interval */ +# define OTGHS_DCFG_PFIVL_95PCT (3 << OTGHS_DCFG_PFIVL_SHIFT) /* 95% of the frame interval */ + /* Bits 13-31 Reserved, must be kept at reset value */ +/* Device control register */ + +#define OTGHS_TESTMODE_DISABLED (0) /* Test mode disabled */ +#define OTGHS_TESTMODE_J (1) /* Test_J mode */ +#define OTGHS_TESTMODE_K (2) /* Test_K mode */ +#define OTGHS_TESTMODE_SE0_NAK (3) /* Test_SE0_NAK mode */ +#define OTGHS_TESTMODE_PACKET (4) /* Test_Packet mode */ +#define OTGHS_TESTMODE_FORCE (5) /* Test_Force_Enable */ + +#define OTGHS_DCTL_RWUSIG (1 << 0) /* Bit 0: Remote wakeup signaling */ +#define OTGHS_DCTL_SDIS (1 << 1) /* Bit 1: Soft disconnect */ +#define OTGHS_DCTL_GINSTS (1 << 2) /* Bit 2: Global IN NAK status */ +#define OTGHS_DCTL_GONSTS (1 << 3) /* Bit 3: Global OUT NAK status */ +#define OTGHS_DCTL_TCTL_SHIFT (4) /* Bits 4-6: Test control */ +#define OTGHS_DCTL_TCTL_MASK (7 << OTGHS_DCTL_TCTL_SHIFT) +# define OTGHS_DCTL_TCTL_DISABLED (0 << OTGHS_DCTL_TCTL_SHIFT) /* Test mode disabled */ +# define OTGHS_DCTL_TCTL_J (1 << OTGHS_DCTL_TCTL_SHIFT) /* Test_J mode */ +# define OTGHS_DCTL_TCTL_K (2 << OTGHS_DCTL_TCTL_SHIFT) /* Test_K mode */ +# define OTGHS_DCTL_TCTL_SE0_NAK (3 << OTGHS_DCTL_TCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGHS_DCTL_TCTL_PACKET (4 << OTGHS_DCTL_TCTL_SHIFT) /* Test_Packet mode */ +# define OTGHS_DCTL_TCTL_FORCE (5 << OTGHS_DCTL_TCTL_SHIFT) /* Test_Force_Enable */ +#define OTGHS_DCTL_SGINAK (1 << 7) /* Bit 7: Set global IN NAK */ +#define OTGHS_DCTL_CGINAK (1 << 8) /* Bit 8: Clear global IN NAK */ +#define OTGHS_DCTL_SGONAK (1 << 9) /* Bit 9: Set global OUT NAK */ +#define OTGHS_DCTL_CGONAK (1 << 10) /* Bit 10: Clear global OUT NAK */ +#define OTGHS_DCTL_POPRGDNE (1 << 11) /* Bit 11: Power-on programming done */ + /* Bits 12-31: Reserved, must be kept at reset value */ +/* Device status register */ + +#define OTGHS_DSTS_SUSPSTS (1 << 0) /* Bit 0: Suspend status */ +#define OTGHS_DSTS_ENUMSPD_SHIFT (1) /* Bits 1-2: Enumerated speed */ +#define OTGHS_DSTS_ENUMSPD_MASK (3 << OTGHS_DSTS_ENUMSPD_SHIFT) +# define OTGHS_DSTS_ENUMSPD_FS (3 << OTGHS_DSTS_ENUMSPD_MASK) /* Full speed */ + /* Bits 4-7: Reserved, must be kept at reset value */ +#define OTGHS_DSTS_EERR (1 << 3) /* Bit 3: Erratic error */ +#define OTGHS_DSTS_SOFFN_SHIFT (8) /* Bits 8-21: Frame number of the received SOF */ +#define OTGHS_DSTS_SOFFN_MASK (0x3fff << OTGHS_DSTS_SOFFN_SHIFT) +#define OTGHS_DSTS_SOFFN0 (1 << 8) /* Bits 8: Frame number even/odd bit */ +#define OTGHS_DSTS_SOFFN_EVEN 0 +#define OTGHS_DSTS_SOFFN_ODD OTGHS_DSTS_SOFFN0 + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Device IN endpoint common interrupt mask register */ + +#define OTGHS_DIEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGHS_DIEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGHS_DIEPMSK_TOM (1 << 3) /* Bit 3: Timeout condition mask (Non-isochronous endpoints) */ +#define OTGHS_DIEPMSK_ITTXFEMSK (1 << 4) /* Bit 4: IN token received when TxFIFO empty mask */ +#define OTGHS_DIEPMSK_INEPNMM (1 << 5) /* Bit 5: IN token received with EP mismatch mask */ +#define OTGHS_DIEPMSK_INEPNEM (1 << 6) /* Bit 6: IN endpoint NAK effective mask */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint common interrupt mask register */ + +#define OTGHS_DOEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGHS_DOEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGHS_DOEPMSK_STUPM (1 << 3) /* Bit 3: SETUP phase done mask */ +#define OTGHS_DOEPMSK_OTEPDM (1 << 4) /* Bit 4: OUT token received when endpoint disabled mask */ + /* Bits 5-31: Reserved, must be kept at reset value */ +/* Device all endpoints interrupt and All endpoints interrupt mask registers */ + +#define OTGHS_DAINT_IEP_SHIFT (0) /* Bits 0-15: IN endpoint interrupt bits */ +#define OTGHS_DAINT_IEP_MASK (0xffff << OTGHS_DAINT_IEP_SHIFT) +# define OTGHS_DAINT_IEP(n) (1 << (n)) +#define OTGHS_DAINT_OEP_SHIFT (16) /* Bits 16-31: OUT endpoint interrupt bits */ +#define OTGHS_DAINT_OEP_MASK (0xffff << OTGHS_DAINT_OEP_SHIFT) +# define OTGHS_DAINT_OEP(n) (1 << ((n)+16)) + +/* Device VBUS discharge time register */ + +#define OTGHS_DVBUSDIS_MASK (0xffff) + +/* Device VBUS pulsing time register */ + +#define OTGHS_DVBUSPULSE_MASK (0xfff) + +/* Device IN endpoint FIFO empty interrupt mask register */ + +#define OTGHS_DIEPEMPMSK(n) (1 << (n)) + +/* Device control IN endpoint 0 control register */ + +#define OTGHS_DIEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGHS_DIEPCTL0_MPSIZ_MASK (3 << OTGHS_DIEPCTL0_MPSIZ_SHIFT) +# define OTGHS_DIEPCTL0_MPSIZ_64 (0 << OTGHS_DIEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGHS_DIEPCTL0_MPSIZ_32 (1 << OTGHS_DIEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGHS_DIEPCTL0_MPSIZ_16 (2 << OTGHS_DIEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGHS_DIEPCTL0_MPSIZ_8 (3 << OTGHS_DIEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGHS_DIEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGHS_DIEPCTL0_EPTYP_MASK (3 << OTGHS_DIEPCTL0_EPTYP_SHIFT) +# define OTGHS_DIEPCTL0_EPTYP_CTRL (0 << OTGHS_DIEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGHS_DIEPCTL0_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGHS_DIEPCTL0_TXFNUM_MASK (15 << OTGHS_DIEPCTL0_TXFNUM_SHIFT) +#define OTGHS_DIEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGHS_DIEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGHS_DIEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device control IN endpoint n control register */ + +#define OTGHS_DIEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGHS_DIEPCTL_MPSIZ_MASK (0x7ff << OTGHS_DIEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGHS_DIEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame */ +# define OTGHS_DIEPCTL_EVEN (0) +# define OTGHS_DIEPCTL_ODD OTGHS_DIEPCTL_EONUM +# define OTGHS_DIEPCTL_DATA0 (0) +# define OTGHS_DIEPCTL_DATA1 OTGHS_DIEPCTL_EONUM +#define OTGHS_DIEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGHS_DIEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGHS_DIEPCTL_EPTYP_MASK (3 << OTGHS_DIEPCTL_EPTYP_SHIFT) +# define OTGHS_DIEPCTL_EPTYP_CTRL (0 << OTGHS_DIEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGHS_DIEPCTL_EPTYP_ISOC (1 << OTGHS_DIEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGHS_DIEPCTL_EPTYP_BULK (2 << OTGHS_DIEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGHS_DIEPCTL_EPTYP_INTR (3 << OTGHS_DIEPCTL_EPTYP_SHIFT) /* Interrupt */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGHS_DIEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGHS_DIEPCTL_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGHS_DIEPCTL_TXFNUM_MASK (15 << OTGHS_DIEPCTL_TXFNUM_SHIFT) +#define OTGHS_DIEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGHS_DIEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGHS_DIEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGHS_DIEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous)) */ +#define OTGHS_DIEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous) */ +#define OTGHS_DIEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGHS_DIEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGHS_DIEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGHS_DIEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGHS_DIEPINT_TOC (1 << 3) /* Bit 3: Timeout condition */ +#define OTGHS_DIEPINT_ITTXFE (1 << 4) /* Bit 4: IN token received when TxFIFO is empty */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGHS_DIEPINT_INEPNE (1 << 6) /* Bit 6: IN endpoint NAK effective */ +#define OTGHS_DIEPINT_TXFE (1 << 7) /* Bit 7: Transmit FIFO empty */ + /* Bits 8-31: Reserved, must be kept at reset value */ +/* Device IN endpoint 0 transfer size register */ + +#define OTGHS_DIEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGHS_DIEPTSIZ0_XFRSIZ_MASK (0x7f << OTGHS_DIEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGHS_DIEPTSIZ0_PKTCNT_SHIFT (19) /* Bits 19-20: Packet count */ +#define OTGHS_DIEPTSIZ0_PKTCNT_MASK (3 << OTGHS_DIEPTSIZ0_PKTCNT_SHIFT) + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Device IN endpoint n transfer size register */ + +#define OTGHS_DIEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGHS_DIEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGHS_DIEPTSIZ_XFRSIZ_SHIFT) +#define OTGHS_DIEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGHS_DIEPTSIZ_PKTCNT_MASK (0x3ff << OTGHS_DIEPTSIZ_PKTCNT_SHIFT) +#define OTGHS_DIEPTSIZ_MCNT_SHIFT (29) /* Bits 29-30: Multi count */ +#define OTGHS_DIEPTSIZ_MCNT_MASK (3 << OTGHS_DIEPTSIZ_MCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint TxFIFO status register */ + +#define OTGHS_DTXFSTS_MASK (0xffff) + +/* Device OUT endpoint 0 control register */ + +#define OTGHS_DOEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGHS_DOEPCTL0_MPSIZ_MASK (3 << OTGHS_DOEPCTL0_MPSIZ_SHIFT) +# define OTGHS_DOEPCTL0_MPSIZ_64 (0 << OTGHS_DOEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGHS_DOEPCTL0_MPSIZ_32 (1 << OTGHS_DOEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGHS_DOEPCTL0_MPSIZ_16 (2 << OTGHS_DOEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGHS_DOEPCTL0_MPSIZ_8 (3 << OTGHS_DOEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGHS_DOEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGHS_DOEPCTL0_EPTYP_MASK (3 << OTGHS_DOEPCTL0_EPTYP_SHIFT) +# define OTGHS_DOEPCTL0_EPTYP_CTRL (0 << OTGHS_DOEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ +#define OTGHS_DOEPCTL0_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGHS_DOEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGHS_DOEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGHS_DOEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device OUT endpoint n control register */ + +#define OTGHS_DOEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGHS_DOEPCTL_MPSIZ_MASK (0x7ff << OTGHS_DOEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGHS_DOEPCTL_DPID (1 << 16) /* Bit 16: Endpoint data PID (interrupt/buld) */ +# define OTGHS_DOEPCTL_DATA0 (0) +# define OTGHS_DOEPCTL_DATA1 OTGHS_DOEPCTL_DPID +#define OTGHS_DOEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame (isochronous) */ +# define OTGHS_DOEPCTL_EVEN (0) +# define OTGHS_DOEPCTL_ODD OTGHS_DOEPCTL_EONUM +#define OTGHS_DOEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGHS_DOEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGHS_DOEPCTL_EPTYP_MASK (3 << OTGHS_DOEPCTL_EPTYP_SHIFT) +# define OTGHS_DOEPCTL_EPTYP_CTRL (0 << OTGHS_DOEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGHS_DOEPCTL_EPTYP_ISOC (1 << OTGHS_DOEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGHS_DOEPCTL_EPTYP_BULK (2 << OTGHS_DOEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGHS_DOEPCTL_EPTYP_INTR (3 << OTGHS_DOEPCTL_EPTYP_SHIFT) /* Interrupt */ +#define OTGHS_DOEPCTL_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGHS_DOEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGHS_DOEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGHS_DOEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGHS_DOEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGHS_DOEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous) */ +#define OTGHS_DOEPCTL_SD1PID (1 << 29) /* Bit 29: Set DATA1 PID (interrupt/bulk) */ +#define OTGHS_DOEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous */ +#define OTGHS_DOEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGHS_DOEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGHS_DOEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGHS_DOEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGHS_DOEPINT_SETUP (1 << 3) /* Bit 3: SETUP phase done */ +#define OTGHS_DOEPINT_OTEPDIS (1 << 4) /* Bit 4: OUT token received when endpoint disabled */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGHS_DOEPINT_B2BSTUP (1 << 6) /* Bit 6: Back-to-back SETUP packets received */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-0 transfer size register */ + +#define OTGHS_DOEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGHS_DOEPTSIZ0_XFRSIZ_MASK (0x7f << OTGHS_DOEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGHS_DOEPTSIZ0_PKTCNT (1 << 19) /* Bit 19 PKTCNT: Packet count */ + /* Bits 20-28: Reserved, must be kept at reset value */ +#define OTGHS_DOEPTSIZ0_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGHS_DOEPTSIZ0_STUPCNT_MASK (3 << OTGHS_DOEPTSIZ0_STUPCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-n transfer size register */ + +#define OTGHS_DOEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGHS_DOEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGHS_DOEPTSIZ_XFRSIZ_SHIFT) +#define OTGHS_DOEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGHS_DOEPTSIZ_PKTCNT_MASK (0x3ff << OTGHS_DOEPTSIZ_PKTCNT_SHIFT) +#define OTGHS_DOEPTSIZ_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGHS_DOEPTSIZ_STUPCNT_MASK (3 << OTGHS_DOEPTSIZ_STUPCNT_SHIFT) +#define OTGHS_DOEPTSIZ_RXDPID_SHIFT (29) /* Bits 29-30: Received data PID */ +#define OTGHS_DOEPTSIZ_RXDPID_MASK (3 << OTGHS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGHS_DOEPTSIZ_RXDPID_DATA0 (0 << OTGHS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGHS_DOEPTSIZ_RXDPID_DATA2 (1 << OTGHS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGHS_DOEPTSIZ_RXDPID_DATA1 (2 << OTGHS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGHS_DOEPTSIZ_RXDPID_MDATA (3 << OTGHS_DOEPTSIZ_RXDPID_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Power and clock gating control register */ + +#define OTGHS_PCGCCTL_STPPCLK (1 << 0) /* Bit 0: Stop PHY clock */ +#define OTGHS_PCGCCTL_GATEHCLK (1 << 1) /* Bit 1: Gate HCLK */ + /* Bits 2-3: Reserved, must be kept at reset value */ +#define OTGHS_PCGCCTL_PHYSUSP (1 << 4) /* Bit 4: PHY Suspended */ + /* Bits 5-31: Reserved, must be kept at reset value */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_OTGHS_H */ diff --git a/arch/arm/src/stm32/chip/stm32_pwr.h b/arch/arm/src/stm32/chip/stm32_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..9c1e64e57bd09492762306770b730d18b7922aa9 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_pwr.h @@ -0,0 +1,165 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_pwr.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_PWR_CR_OFFSET 0x0000 /* Power control register */ +#define STM32_PWR_CSR_OFFSET 0x0004 /* Power control/status register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_PWR_CR (STM32_PWR_BASE+STM32_PWR_CR_OFFSET) +#define STM32_PWR_CSR (STM32_PWR_BASE+STM32_PWR_CSR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Power control register */ + +#define PWR_CR_LPDS (1 << 0) /* Bit 0: Low-Power Deepsleep/sleep; low power run */ +#define PWR_CR_PDDS (1 << 1) /* Bit 1: Power Down Deepsleep */ +#define PWR_CR_CWUF (1 << 2) /* Bit 2: Clear Wakeup Flag */ +#define PWR_CR_CSBF (1 << 3) /* Bit 3: Clear Standby Flag */ +#define PWR_CR_PVDE (1 << 4) /* Bit 4: Power Voltage Detector Enable */ + +#define PWR_CR_PLS_SHIFT (5) /* Bits 7-5: PVD Level Selection */ +#define PWR_CR_PLS_MASK (7 << PWR_CR_PLS_SHIFT) +# if defined(CONFIG_STM32_STM32L15XX) +# define PWR_CR_1p9V (0 << PWR_CR_PLS_SHIFT) /* 000: 1.9 V */ +# define PWR_CR_2p1V (1 << PWR_CR_PLS_SHIFT) /* 001: 2.1 V */ +# define PWR_CR_2p3V (2 << PWR_CR_PLS_SHIFT) /* 010: 2.3 V */ +# define PWR_CR_2p5V (3 << PWR_CR_PLS_SHIFT) /* 011: 2.5 V */ +# define PWR_CR_2p7V (4 << PWR_CR_PLS_SHIFT) /* 100: 2.7 V */ +# define PWR_CR_2p9V (5 << PWR_CR_PLS_SHIFT) /* 101: 2.9 V */ +# define PWR_CR_3p1V (6 << PWR_CR_PLS_SHIFT) /* 110: 3.1 V */ +# define PWR_CR_EXT (7 << PWR_CR_PLS_SHIFT) /* 111: External input analog voltage */ +# else +# define PWR_CR_2p2V (0 << PWR_CR_PLS_SHIFT) /* 000: 2.2V */ +# define PWR_CR_2p3V (1 << PWR_CR_PLS_SHIFT) /* 001: 2.3V */ +# define PWR_CR_2p4V (2 << PWR_CR_PLS_SHIFT) /* 010: 2.4V */ +# define PWR_CR_2p5V (3 << PWR_CR_PLS_SHIFT) /* 011: 2.5V */ +# define PWR_CR_2p6V (4 << PWR_CR_PLS_SHIFT) /* 100: 2.6V */ +# define PWR_CR_2p7V (5 << PWR_CR_PLS_SHIFT) /* 101: 2.7V */ +# define PWR_CR_2p8V (6 << PWR_CR_PLS_SHIFT) /* 110: 2.8V */ +# define PWR_CR_2p9V (7 << PWR_CR_PLS_SHIFT) /* 111: 2.9V */ +# endif +#define PWR_CR_DBP (1 << 8) /* Bit 8: Disable Backup Domain write protection */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define PWR_CR_FPDS (1 << 9) /* Bit 9: Flash power down in Stop mode */ +# if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define PWR_CR_ADCDC1 (1 << 13) /* Bit 13: see AN4073 for details */ +# define PWR_CR_VOS_MASK (3 << 14) /* Bits 14-15: Regulator voltage scaling output selection */ +# define PWR_CR_VOS_SCALE_1 (3 << 14) /* Fmax = 168MHz */ +# define PWR_CR_VOS_SCALE_2 (2 << 14) /* Fmax = 144MHz */ +# define PWR_CR_VOS_SCALE_3 (1 << 14) /* Fmax = 120MHz */ +# else +# define PWR_CR_VOS (1 << 14) /* Bit 14: Regulator voltage scaling output selection */ + /* 0: Fmax = 144MHz 1: Fmax = 168MHz */ +# endif +#endif + +#if defined(CONFIG_STM32_STM32L15XX) +# define PWR_CR_ULP (1 << 9) /* Ultralow power mode */ +# define PWR_CR_FWU (1 << 10) /* Fast wake-up */ +# define PWR_CR_VOS_MASK (3 << 11) /* Bits 11-12: Regulator voltage scaling output selection */ +# define PWR_CR_VOS_SCALE_1 (1 << 11) /* 1.8 V (range 1) PLL VCO Max = 96MHz */ +# define PWR_CR_VOS_SCALE_2 (2 << 11) /* 1.5 V (range 2) PLL VCO Max = 64MHz */ +# define PWR_CR_VOS_SCALE_3 (3 << 11) /* 1.2 V (range 3) PLL VCO Max = 24MHz */ +# define PWR_CR_LPRUN (1 << 14) /* Low power run mode */ +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define PWR_CR_ODEN (1 << 16) /* Over Drive enable */ +# define PWR_CR_ODSWEN (1 << 17) /* Over Drive switch enabled */ +#endif + +#if defined(CONFIG_STM32_STM32F446) +# define PWR_CR_FMSSR (1 << 20) /* Flash Memory Stop while System Run */ +# define PWR_CR_FISSR (1 << 21) /* Flash Interface Stop while System Run*/ +#endif + +/* Power control/status register */ + +#define PWR_CSR_WUF (1 << 0) /* Bit 0: Wakeup Flag */ +#define PWR_CSR_SBF (1 << 1) /* Bit 1: Standby Flag */ +#define PWR_CSR_PVDO (1 << 2) /* Bit 2: PVD Output */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define PWR_CSR_BRR (1 << 3) /* Bit 3: Backup regulator ready */ +#elif defined(CONFIG_STM32_STM32L15XX) +# define PWR_CSR_VREFINTRDYF (1 << 3) /* Bit 3: Internal voltage reference (VREFINT) ready flag */ +# define PWR_CSR_VOSF (1 << 4) /* Bit 4: Voltage Scaling select flag */ +# define PWR_CSR_REGLPF (1 << 5) /* Bit 5: Regulator LP flag */ +#endif + +#if defined(CONFIG_STM32_STM32F30XX) +# define PWR_CSR_EWUP1 (1 << 8) /* Bit 8: Enable WKUP1 pin */ +# define PWR_CSR_EWUP2 (1 << 9) /* Bit 9: Enable WKUP2 pin */ +#elif defined(CONFIG_STM32_STM32L15XX) +# define PWR_CSR_EWUP1 (1 << 8) /* Bit 8: Enable WKUP1 pin */ +# define PWR_CSR_EWUP2 (1 << 9) /* Bit 9: Enable WKUP2 pin */ +# define PWR_CSR_EWUP3 (1 << 10) /* Bit 8: Enable WKUP3 pin */ +#else +# define PWR_CSR_EWUP (1 << 8) /* Bit 8: Enable WKUP pin */ +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define PWR_CSR_BRE (1 << 9) /* Bit 9: Backup regulator enable */ +# define PWR_CSR_VOSRDY (1 << 14) /* Bit 14: Regulator voltage scaling output selection ready bite */ +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define PWR_CSR_ODRDY (1 << 16) /* Over Drive generator ready */ +# define PWR_CSR_ODSWRDY (1 << 17) /* Over Drive Switch ready */ +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_PWR_H */ diff --git a/arch/arm/src/stm32/chip/stm32_rng.h b/arch/arm/src/stm32/chip/stm32_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..5e31d58174f551fde883ea2595d7c9e972a62bfb --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_rng.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_rng.h + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RNG_CR_OFFSET 0x0000 /* RNG Control Register */ +#define STM32_RNG_SR_OFFSET 0x0004 /* RNG Status Register */ +#define STM32_RNG_DR_OFFSET 0x0008 /* RNG Data Register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RNG_CR (STM32_RNG_BASE+STM32_RNG_CR_OFFSET) +#define STM32_RNG_SR (STM32_RNG_BASE+STM32_RNG_SR_OFFSET) +#define STM32_RNG_DR (STM32_RNG_BASE+STM32_RNG_DR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RNG Control Register */ + +#define RNG_CR_RNGEN (1 << 2) /* Bit 2: RNG enable */ +#define RNG_CR_IE (1 << 3) /* Bit 3: Interrupt enable */ + +/* RNG Status Register */ + +#define RNG_SR_DRDY (1 << 0) /* Bit 0: Data ready */ +#define RNG_SR_CECS (1 << 1) /* Bit 1: Clock error current status */ +#define RNG_SR_SECS (1 << 2) /* Bit 2: Seed error current status */ +#define RNG_SR_CEIS (1 << 5) /* Bit 5: Clock error interrupt status */ +#define RNG_SR_SEIS (1 << 6) /* Bit 6: Seed error interrupt status */ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H */ diff --git a/arch/arm/src/stm32/chip/stm32_rtc.h b/arch/arm/src/stm32/chip/stm32_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..e5004c5ab8f8fe602e5780c367163e391d1a3a1d --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_rtc.h @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_rtc.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_RTC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_RTC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RTC_CRH_OFFSET 0x0000 /* RTC control register High (16-bit) */ +#define STM32_RTC_CRL_OFFSET 0x0004 /* RTC control register low (16-bit) */ +#define STM32_RTC_PRLH_OFFSET 0x0008 /* RTC prescaler load register high (16-bit) */ +#define STM32_RTC_PRLL_OFFSET 0x000c /* RTC prescaler load register low (16-bit) */ +#define STM32_RTC_DIVH_OFFSET 0x0010 /* RTC prescaler divider register high (16-bit) */ +#define STM32_RTC_DIVL_OFFSET 0x0014 /* RTC prescaler divider register low (16-bit) */ +#define STM32_RTC_CNTH_OFFSET 0x0018 /* RTC counter register high (16-bit) */ +#define STM32_RTC_CNTL_OFFSET 0x001c /* RTC counter register low (16-bit) */ +#define STM32_RTC_ALRH_OFFSET 0x0020 /* RTC alarm register high (16-bit) */ +#define STM32_RTC_ALRL_OFFSET 0x0024 /* RTC alarm register low (16-bit) */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RTC_CRH (STM32_RTC_BASE+STM32_RTC_CRH_OFFSET) +#define STM32_RTC_CRL (STM32_RTC_BASE+STM32_RTC_CRL_OFFSET) +#define STM32_RTC_PRLH (STM32_RTC_BASE+STM32_RTC_PRLH_OFFSET) +#define STM32_RTC_PRLL (STM32_RTC_BASE+STM32_RTC_PRLL_OFFSET) +#define STM32_RTC_DIVH (STM32_RTC_BASE+STM32_RTC_DIVH_OFFSET) +#define STM32_RTC_DIVL (STM32_RTC_BASE+STM32_RTC_DIVL_OFFSET) +#define STM32_RTC_CNTH (STM32_RTC_BASE+STM32_RTC_CNTH_OFFSET) +#define STM32_RTC_CNTL (STM32_RTC_BASE+STM32_RTC_CNTL_OFFSET) +#define STM32_RTC_ALRH (STM32_RTC_BASE+STM32_RTC_ALRH_OFFSET) +#define STM32_RTC_ALRL (STM32_RTC_BASE+STM32_RTC_ALRL_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RTC control register High (16-bit) */ + +#define RTC_CRH_SECIE (1 << 0) /* Bit 0 : Second Interrupt Enable */ +#define RTC_CRH_ALRIE (1 << 1) /* Bit 1: Alarm Interrupt Enable */ +#define RTC_CRH_OWIE (1 << 2) /* Bit 2: OverfloW Interrupt Enable */ + +/* RTC control register low (16-bit) */ + +#define RTC_CRL_SECF (1 << 0) /* Bit 0: Second Flag */ +#define RTC_CRL_ALRF (1 << 1) /* Bit 1: Alarm Flag */ +#define RTC_CRL_OWF (1 << 2) /* Bit 2: Overflow Flag */ +#define RTC_CRL_RSF (1 << 3) /* Bit 3: Registers Synchronized Flag */ +#define RTC_CRL_CNF (1 << 4) /* Bit 4: Configuration Flag */ +#define RTC_CRL_RTOFF (1 << 5) /* Bit 5: RTC operation OFF */ + +/* RTC prescaler load register high (16-bit) */ + +#define RTC_PRLH_PRL_SHIFT (0) /* Bits 3-0: RTC Prescaler Reload Value High */ +#define RTC_PRLH_PRL_MASK (0x0f << RTC_PRLH_PRL_SHIFT) + +/* RTC prescaler divider register high (16-bit) */ + +#define RTC_DIVH_RTC_DIV_SHIFT (0) /* Bits 3-0: RTC Clock Divider High */ +#define RTC_DIVH_RTC_DIV_MASK (0x0f << RTC_DIVH_RTC_DIV_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_RTC_H */ diff --git a/arch/arm/src/stm32/chip/stm32_rtcc.h b/arch/arm/src/stm32/chip/stm32_rtcc.h new file mode 100644 index 0000000000000000000000000000000000000000..076a4187e8b97dbbcebda7ca6f29dcc6278738bc --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_rtcc.h @@ -0,0 +1,417 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_rtcc.h.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_RTCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_RTCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RTC_TR_OFFSET 0x0000 /* RTC time register */ +#define STM32_RTC_DR_OFFSET 0x0004 /* RTC date register */ +#define STM32_RTC_CR_OFFSET 0x0008 /* RTC control register */ +#define STM32_RTC_ISR_OFFSET 0x000c /* RTC initialization and status register */ +#define STM32_RTC_PRER_OFFSET 0x0010 /* RTC prescaler register */ +#define STM32_RTC_WUTR_OFFSET 0x0014 /* RTC wakeup timer register */ +#ifndef CONFIG_STM32_STM32F30XX +# define STM32_RTC_CALIBR_OFFSET 0x0018 /* RTC calibration register */ +#endif +#define STM32_RTC_ALRMAR_OFFSET 0x001c /* RTC alarm A register */ +#define STM32_RTC_ALRMBR_OFFSET 0x0020 /* RTC alarm B register */ +#define STM32_RTC_WPR_OFFSET 0x0024 /* RTC write protection register */ +#define STM32_RTC_SSR_OFFSET 0x0028 /* RTC sub second register */ +#define STM32_RTC_SHIFTR_OFFSET 0x002c /* RTC shift control register */ +#define STM32_RTC_TSTR_OFFSET 0x0030 /* RTC time stamp time register */ +#define STM32_RTC_TSDR_OFFSET 0x0034 /* RTC time stamp date register */ +#define STM32_RTC_TSSSR_OFFSET 0x0038 /* RTC timestamp sub second register */ +#define STM32_RTC_CALR_OFFSET 0x003c /* RTC calibration register */ +#define STM32_RTC_TAFCR_OFFSET 0x0040 /* RTC tamper and alternate function configuration register */ +#define STM32_RTC_ALRMASSR_OFFSET 0x0044 /* RTC alarm A sub second register */ +#define STM32_RTC_ALRMBSSR_OFFSET 0x0048 /* RTC alarm B sub second register */ + +#define STM32_RTC_BKR_OFFSET(n) (0x0050+((n)<<2)) +#define STM32_RTC_BK0R_OFFSET 0x0050 /* RTC backup register 0 */ +#define STM32_RTC_BK1R_OFFSET 0x0054 /* RTC backup register 1 */ +#define STM32_RTC_BK2R_OFFSET 0x0058 /* RTC backup register 2 */ +#define STM32_RTC_BK3R_OFFSET 0x005c /* RTC backup register 3 */ +#define STM32_RTC_BK4R_OFFSET 0x0060 /* RTC backup register 4 */ +#define STM32_RTC_BK5R_OFFSET 0x0064 /* RTC backup register 5 */ +#define STM32_RTC_BK6R_OFFSET 0x0068 /* RTC backup register 6 */ +#define STM32_RTC_BK7R_OFFSET 0x006c /* RTC backup register 7 */ +#define STM32_RTC_BK8R_OFFSET 0x0070 /* RTC backup register 8 */ +#define STM32_RTC_BK9R_OFFSET 0x0074 /* RTC backup register 9 */ +#define STM32_RTC_BK10R_OFFSET 0x0078 /* RTC backup register 10 */ +#define STM32_RTC_BK11R_OFFSET 0x007c /* RTC backup register 11 */ +#define STM32_RTC_BK12R_OFFSET 0x0080 /* RTC backup register 12 */ +#define STM32_RTC_BK13R_OFFSET 0x0084 /* RTC backup register 13 */ +#define STM32_RTC_BK14R_OFFSET 0x0088 /* RTC backup register 14 */ +#define STM32_RTC_BK15R_OFFSET 0x008c /* RTC backup register 15 */ +#ifndef CONFIG_STM32_STM32F30XX +# define STM32_RTC_BK16R_OFFSET 0x0090 /* RTC backup register 16 */ +# define STM32_RTC_BK17R_OFFSET 0x0094 /* RTC backup register 17 */ +# define STM32_RTC_BK18R_OFFSET 0x0098 /* RTC backup register 18 */ +# define STM32_RTC_BK19R_OFFSET 0x009c /* RTC backup register 19 */ +#endif +#ifdef CONFIG_STM32_STM32L15XX +# define STM32_RTC_BK20R_OFFSET 0x00a0 /* RTC backup register 20 */ +# define STM32_RTC_BK21R_OFFSET 0x00a4 /* RTC backup register 21 */ +# define STM32_RTC_BK22R_OFFSET 0x00a8 /* RTC backup register 22 */ +# define STM32_RTC_BK23R_OFFSET 0x00ac /* RTC backup register 23 */ +# define STM32_RTC_BK24R_OFFSET 0x00b0 /* RTC backup register 24 */ +# define STM32_RTC_BK25R_OFFSET 0x00b4 /* RTC backup register 25 */ +# define STM32_RTC_BK26R_OFFSET 0x00b8 /* RTC backup register 26 */ +# define STM32_RTC_BK27R_OFFSET 0x00bc /* RTC backup register 27 */ +# define STM32_RTC_BK28R_OFFSET 0x00c0 /* RTC backup register 28 */ +# define STM32_RTC_BK29R_OFFSET 0x00c4 /* RTC backup register 29 */ +# define STM32_RTC_BK30R_OFFSET 0x00c8 /* RTC backup register 30 */ +# define STM32_RTC_BK31R_OFFSET 0x00cc /* RTC backup register 31 */ +#endif + +/* Register Addresses ***************************************************************/ + +#define STM32_RTC_TR (STM32_RTC_BASE+STM32_RTC_TR_OFFSET) +#define STM32_RTC_DR (STM32_RTC_BASE+STM32_RTC_DR_OFFSET) +#define STM32_RTC_CR (STM32_RTC_BASE+STM32_RTC_CR_OFFSET) +#define STM32_RTC_ISR (STM32_RTC_BASE+STM32_RTC_ISR_OFFSET) +#define STM32_RTC_PRER (STM32_RTC_BASE+STM32_RTC_PRER_OFFSET) +#define STM32_RTC_WUTR (STM32_RTC_BASE+STM32_RTC_WUTR_OFFSET) +#ifndef CONFIG_STM32_STM32F30XX +# define STM32_RTC_CALIBR (STM32_RTC_BASE+STM32_RTC_CALIBR_OFFSET) +#endif +#define STM32_RTC_ALRMAR (STM32_RTC_BASE+STM32_RTC_ALRMAR_OFFSET) +#define STM32_RTC_ALRMBR (STM32_RTC_BASE+STM32_RTC_ALRMBR_OFFSET) +#define STM32_RTC_WPR (STM32_RTC_BASE+STM32_RTC_WPR_OFFSET) +#define STM32_RTC_SSR (STM32_RTC_BASE+STM32_RTC_SSR_OFFSET) +#define STM32_RTC_SHIFTR (STM32_RTC_BASE+STM32_RTC_SHIFTR_OFFSET) +#define STM32_RTC_TSTR (STM32_RTC_BASE+STM32_RTC_TSTR_OFFSET) +#define STM32_RTC_TSDR (STM32_RTC_BASE+STM32_RTC_TSDR_OFFSET) +#define STM32_RTC_TSSSR (STM32_RTC_BASE+STM32_RTC_TSSSR_OFFSET) +#define STM32_RTC_CALR (STM32_RTC_BASE+STM32_RTC_CALR_OFFSET) +#define STM32_RTC_TAFCR (STM32_RTC_BASE+STM32_RTC_TAFCR_OFFSET) +#define STM32_RTC_ALRMASSR (STM32_RTC_BASE+STM32_RTC_ALRMASSR_OFFSET) +#define STM32_RTC_ALRMBSSR (STM32_RTC_BASE+STM32_RTC_ALRMBSSR_OFFSET) + +#define STM32_RTC_BKR(n) (STM32_RTC_BASE+STM32_RTC_BKR_OFFSET(n)) +#define STM32_RTC_BK0R (STM32_RTC_BASE+STM32_RTC_BK0R_OFFSET) +#define STM32_RTC_BK1R (STM32_RTC_BASE+STM32_RTC_BK1R_OFFSET) +#define STM32_RTC_BK2R (STM32_RTC_BASE+STM32_RTC_BK2R_OFFSET) +#define STM32_RTC_BK3R (STM32_RTC_BASE+STM32_RTC_BK3R_OFFSET) +#define STM32_RTC_BK4R (STM32_RTC_BASE+STM32_RTC_BK4R_OFFSET) +#define STM32_RTC_BK5R (STM32_RTC_BASE+STM32_RTC_BK5R_OFFSET) +#define STM32_RTC_BK6R (STM32_RTC_BASE+STM32_RTC_BK6R_OFFSET) +#define STM32_RTC_BK7R (STM32_RTC_BASE+STM32_RTC_BK7R_OFFSET) +#define STM32_RTC_BK8R (STM32_RTC_BASE+STM32_RTC_BK8R_OFFSET) +#define STM32_RTC_BK9R (STM32_RTC_BASE+STM32_RTC_BK9R_OFFSET) +#define STM32_RTC_BK10R (STM32_RTC_BASE+STM32_RTC_BK10R_OFFSET) +#define STM32_RTC_BK11R (STM32_RTC_BASE+STM32_RTC_BK11R_OFFSET) +#define STM32_RTC_BK12R (STM32_RTC_BASE+STM32_RTC_BK12R_OFFSET) +#define STM32_RTC_BK13R (STM32_RTC_BASE+STM32_RTC_BK13R_OFFSET) +#define STM32_RTC_BK14R (STM32_RTC_BASE+STM32_RTC_BK14R_OFFSET) +#define STM32_RTC_BK15R (STM32_RTC_BASE+STM32_RTC_BK15R_OFFSET) +#ifndef CONFIG_STM32_STM32F30XX +# define STM32_RTC_BK16R (STM32_RTC_BASE+STM32_RTC_BK16R_OFFSET) +# define STM32_RTC_BK17R (STM32_RTC_BASE+STM32_RTC_BK17R_OFFSET) +# define STM32_RTC_BK18R (STM32_RTC_BASE+STM32_RTC_BK18R_OFFSET) +# define STM32_RTC_BK19R (STM32_RTC_BASE+STM32_RTC_BK19R_OFFSET) +#endif +#ifdef CONFIG_STM32_STM32L15XX +# define STM32_RTC_BK20R (STM32_RTC_BASE+STM32_RTC_BK20R_OFFSET) +# define STM32_RTC_BK21R (STM32_RTC_BASE+STM32_RTC_BK21R_OFFSET) +# define STM32_RTC_BK22R (STM32_RTC_BASE+STM32_RTC_BK22R_OFFSET) +# define STM32_RTC_BK23R (STM32_RTC_BASE+STM32_RTC_BK23R_OFFSET) +# define STM32_RTC_BK24R (STM32_RTC_BASE+STM32_RTC_BK24R_OFFSET) +# define STM32_RTC_BK25R (STM32_RTC_BASE+STM32_RTC_BK25R_OFFSET) +# define STM32_RTC_BK26R (STM32_RTC_BASE+STM32_RTC_BK26R_OFFSET) +# define STM32_RTC_BK27R (STM32_RTC_BASE+STM32_RTC_BK27R_OFFSET) +# define STM32_RTC_BK28R (STM32_RTC_BASE+STM32_RTC_BK28R_OFFSET) +# define STM32_RTC_BK29R (STM32_RTC_BASE+STM32_RTC_BK29R_OFFSET) +# define STM32_RTC_BK30R (STM32_RTC_BASE+STM32_RTC_BK30R_OFFSET) +# define STM32_RTC_BK31R (STM32_RTC_BASE+STM32_RTC_BK31R_OFFSET) +#endif + +#ifdef CONFIG_STM32_STM32F30XX +# define STM32_RTC_BKCOUNT 16 +#elif defined(CONFIG_STM32_STM32L15XX) +# define STM32_RTC_BKCOUNT 32 +#else +# define STM32_RTC_BKCOUNT 20 +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* RTC time register */ + +#define RTC_TR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format */ +#define RTC_TR_SU_MASK (15 << RTC_TR_SU_SHIFT) +#define RTC_TR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format */ +#define RTC_TR_ST_MASK (7 << RTC_TR_ST_SHIFT) +#define RTC_TR_MNU_SHIFT (8) /* Bit 8-11: Minute units in BCD format */ +#define RTC_TR_MNU_MASK (15 << RTC_TR_MNU_SHIFT) +#define RTC_TR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format */ +#define RTC_TR_MNT_MASK (7 << RTC_TR_MNT_SHIFT) +#define RTC_TR_HU_SHIFT (16) /* Bit 16-19: Hour units in BCD format */ +#define RTC_TR_HU_MASK (15 << RTC_TR_HU_SHIFT) +#define RTC_TR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format */ +#define RTC_TR_HT_MASK (3 << RTC_TR_HT_SHIFT) +#define RTC_TR_PM (1 << 22) /* Bit 22: AM/PM notation */ +#define RTC_TR_RESERVED_BITS (0xff808080) + +/* RTC date register */ + +#define RTC_DR_DU_SHIFT (0) /* Bits 0-3: Date units in BCD format */ +#define RTC_DR_DU_MASK (15 << RTC_DR_DU_SHIFT) +#define RTC_DR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */ +#define RTC_DR_DT_MASK (3 << RTC_DR_DT_SHIFT) +#define RTC_DR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */ +#define RTC_DR_MU_MASK (15 << RTC_DR_MU_SHIFT) +#define RTC_DR_MT (1 << 12) /* Bit 12: Month tens in BCD format */ +#define RTC_DR_WDU_SHIFT (13) /* Bits 13-15: Week day units */ +#define RTC_DR_WDU_MASK (7 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_MONDAY (1 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_TUESDAY (2 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_WEDNESDAY (3 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_THURSDAY (4 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_FRIDAY (5 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_SATURDAY (6 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_SUNDAY (7 << RTC_DR_WDU_SHIFT) +#define RTC_DR_YU_SHIFT (16) /* Bits 16-19: Year units in BCD format */ +#define RTC_DR_YU_MASK (15 << RTC_DR_YU_SHIFT) +#define RTC_DR_YT_SHIFT (20) /* Bits 20-23: Year tens in BCD format */ +#define RTC_DR_YT_MASK (15 << RTC_DR_YT_SHIFT) +#define RTC_DR_RESERVED_BITS (0xff0000c0) + +/* RTC control register */ + +#define RTC_CR_WUCKSEL_SHIFT (0) /* Bits 0-2: Wakeup clock selection */ +#define RTC_CR_WUCKSEL_MASK (7 << RTC_CR_WUCKSEL_SHIFT) +# define RTC_CR_WUCKSEL_RTCDIV16 (0 << RTC_CR_WUCKSEL_SHIFT) /* 000: RTC/16 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV8 (1 << RTC_CR_WUCKSEL_SHIFT) /* 001: RTC/8 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV4 (2 << RTC_CR_WUCKSEL_SHIFT) /* 010: RTC/4 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV2 (3 << RTC_CR_WUCKSEL_SHIFT) /* 011: RTC/2 clock is selected */ +# define RTC_CR_WUCKSEL_CKSPRE (4 << RTC_CR_WUCKSEL_SHIFT) /* 10x: ck_spre clock is selected */ +# define RTC_CR_WUCKSEL_CKSPREADD (6 << RTC_CR_WUCKSEL_SHIFT) /* 11x: ck_spr clock and 216 added WUT counter */ +#define RTC_CR_TSEDGE (1 << 3) /* Bit 3: Timestamp event active edge */ +#define RTC_CR_REFCKON (1 << 4) /* Bit 4: Reference clock detection enable (50 or 60 Hz) */ +#define RTC_CR_BYPSHAD (1 << 5) /* Bit 5: Bypass the shadow registers */ +#define RTC_CR_FMT (1 << 6) /* Bit 6: Hour format */ +#define RTC_CR_DCE (1 << 7) /* Bit 7: Coarse digital calibration enable */ +#define RTC_CR_ALRAE (1 << 8) /* Bit 8: Alarm A enable */ +#define RTC_CR_ALRBE (1 << 9) /* Bit 9: Alarm B enable */ +#define RTC_CR_WUTE (1 << 10) /* Bit 10: Wakeup timer enable */ +#define RTC_CR_TSE (1 << 11) /* Bit 11: Time stamp enable */ +#define RTC_CR_ALRAIE (1 << 12) /* Bit 12: Alarm A interrupt enable */ +#define RTC_CR_ALRBIE (1 << 13) /* Bit 13: Alarm B interrupt enable */ +#define RTC_CR_WUTIE (1 << 14) /* Bit 14: Wakeup timer interrupt enable */ +#define RTC_CR_TSIE (1 << 15) /* Bit 15: Timestamp interrupt enable */ +#define RTC_CR_ADD1H (1 << 16) /* Bit 16: Add 1 hour (summer time change) */ +#define RTC_CR_SUB1H (1 << 17) /* Bit 17: Subtract 1 hour (winter time change) */ +#define RTC_CR_BKP (1 << 18) /* Bit 18: Backup */ +#define RTC_CR_COSEL (1 << 19) /* Bit 19 : Calibration output selection */ +#define RTC_CR_POL (1 << 20) /* Bit 20: Output polarity */ +#define RTC_CR_OSEL_SHIFT (21) /* Bits 21-22: Output selection */ +#define RTC_CR_OSEL_MASK (3 << RTC_CR_OSEL_SHIFT) +# define RTC_CR_OSEL_DISABLED (0 << RTC_CR_OSEL_SHIFT) /* 00: Output disabled */ +# define RTC_CR_OSEL_ALRMA (1 << RTC_CR_OSEL_SHIFT) /* 01: Alarm A output enabled */ +# define RTC_CR_OSEL_ALRMB (2 << RTC_CR_OSEL_SHIFT) /* 10: Alarm B output enabled */ +# define RTC_CR_OSEL_WUT (3 << RTC_CR_OSEL_SHIFT) /* 11: Wakeup output enabled */ +#define RTC_CR_COE (1 << 23) /* Bit 23: Calibration output enable */ + +/* RTC initialization and status register */ + +#define RTC_ISR_ALRAWF (1 << 0) /* Bit 0: Alarm A write flag */ +#define RTC_ISR_ALRBWF (1 << 1) /* Bit 1: Alarm B write flag */ +#define RTC_ISR_WUTWF (1 << 2) /* Bit 2: Wakeup timer write flag */ +#define RTC_ISR_SHPF (1 << 3) /* Bit 3: Shift operation pending */ +#define RTC_ISR_INITS (1 << 4) /* Bit 4: Initialization status flag */ +#define RTC_ISR_RSF (1 << 5) /* Bit 5: Registers synchronization flag */ +#define RTC_ISR_INITF (1 << 6) /* Bit 6: Initialization flag */ +#define RTC_ISR_INIT (1 << 7) /* Bit 7: Initialization mode */ +#define RTC_ISR_ALRAF (1 << 8) /* Bit 8: Alarm A flag */ +#define RTC_ISR_ALRBF (1 << 9) /* Bit 9: Alarm B flag */ +#define RTC_ISR_WUTF (1 << 10) /* Bit 10: Wakeup timer flag */ +#define RTC_ISR_TSF (1 << 11) /* Bit 11: Timestamp flag */ +#define RTC_ISR_TSOVF (1 << 12) /* Bit 12: Timestamp overflow flag */ +#define RTC_ISR_TAMP1F (1 << 13) /* Bit 13: Tamper detection flag */ +#define RTC_ISR_TAMP2F (1 << 14) /* Bit 14: TAMPER2 detection flag */ +#ifdef CONFIG_STM32_STM32L15XX +# define RTC_ISR_TAMP3F (1 << 15) /* Bit 15: TAMPER3 detection flag */ +#endif +#define RTC_ISR_RECALPF (1 << 16) /* Bit 16: Recalibration pending Flag */ +#define RTC_ISR_ALLFLAGS (0x00017fff) + +/* RTC prescaler register */ + +#define RTC_PRER_PREDIV_S_SHIFT (0) /* Bits 0-14: Synchronous prescaler factor */ +#define RTC_PRER_PREDIV_S_MASK (0x7fff << RTC_PRER_PREDIV_S_SHIFT) +#define RTC_PRER_PREDIV_A_SHIFT (16) /* Bits 16-22: Asynchronous prescaler factor */ +#define RTC_PRER_PREDIV_A_MASK (0x7f << RTC_PRER_PREDIV_A_SHIFT) + +/* RTC wakeup timer register */ + +#define RTC_WUTR_MASK (0xffff) /* Bits 15:0 Wakeup auto-reload value bits */ + +/* RTC calibration register */ + +#ifndef CONFIG_STM32_STM32F30XX +# define RTC_CALIBR_DCS (1 << 7) /* Bit 7 Digital calibration sign */ +# define RTC_CALIBR_DC_SHIFT (0) /* Bits 4:0 0-4: Digital calibration */ +# define RTC_CALIBR_DC_MASK (31 << RTC_CALIBR_DC_SHIFT) +# define RTC_CALIBR_DC(n) (((n) >> 2) << RTC_CALIBR_DC_SHIFT) /* n= 0, 4, 8, ... 126 */ +#endif + +/* RTC alarm A/B registers */ + +#define RTC_ALRMR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */ +#define RTC_ALRMR_SU_MASK (15 << RTC_ALRMR_SU_SHIFT) +#define RTC_ALRMR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */ +#define RTC_ALRMR_ST_MASK (7 << RTC_ALRMR_ST_SHIFT) +#define RTC_ALRMR_MSK1 (1 << 7) /* Bit 7 : Alarm A seconds mask */ +#define RTC_ALRMR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */ +#define RTC_ALRMR_MNU_MASK (15 << RTC_ALRMR_MNU_SHIFT) +#define RTC_ALRMR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */ +#define RTC_ALRMR_MNT_MASK (7 << RTC_ALRMR_MNT_SHIFT) +#define RTC_ALRMR_MSK2 (1 << 15) /* Bit 15 : Alarm A minutes mask */ +#define RTC_ALRMR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */ +#define RTC_ALRMR_HU_MASK (15 << RTC_ALRMR_HU_SHIFT) +#define RTC_ALRMR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */ +#define RTC_ALRMR_HT_MASK (3 << RTC_ALRMR_HT_SHIFT) +#define RTC_ALRMR_PM (1 << 22) /* Bit 22 : AM/PM notation */ +#define RTC_ALRMR_MSK3 (1 << 23) /* Bit 23 : Alarm A hours mask */ +#define RTC_ALRMR_DU_SHIFT (24) /* Bits 24-27: Date units or day in BCD format. */ +#define RTC_ALRMR_DU_MASK (15 << RTC_ALRMR_DU_SHIFT) +#define RTC_ALRMR_DT_SHIFT (28) /* Bits 28-29: Date tens in BCD format. */ +#define RTC_ALRMR_DT_MASK (3 << RTC_ALRMR_DT_SHIFT) +#define RTC_ALRMR_WDSEL (1 << 30) /* Bit 30: Week day selection */ +#define RTC_ALRMR_MSK4 (1 << 31) /* Bit 31: Alarm A date mask */ + +/* RTC write protection register */ + +#define RTC_WPR_MASK (0xff) /* Bits 0-7: Write protection key */ + +/* RTC sub second register */ + +#define RTC_SSR_MASK (0xffff) /* Bits 0-15: Sub second value */ + +/* RTC shift control register */ + +#define RTC_SHIFTR_SUBFS_SHIFT (0) /* Bits 0-14: Subtract a fraction of a second */ +#define RTC_SHIFTR_SUBFS_MASK (0x7ffff << RTC_SHIFTR_SUBFS_SHIFT) +#define RTC_SHIFTR_ADD1S (1 << 31) /* Bit 31: Add one second */ + +/* RTC time stamp time register */ + +#define RTC_TSTR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */ +#define RTC_TSTR_SU_MASK (15 << RTC_TSTR_SU_SHIFT) +#define RTC_TSTR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */ +#define RTC_TSTR_ST_MASK (7 << RTC_TSTR_ST_SHIFT) +#define RTC_TSTR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */ +#define RTC_TSTR_MNU_MASK (15 << RTC_TSTR_MNU_SHIFT) +#define RTC_TSTR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */ +#define RTC_TSTR_MNT_MASK (7 << RTC_TSTR_MNT_SHIFT) +#define RTC_TSTR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */ +#define RTC_TSTR_HU_MASK (15 << RTC_TSTR_HU_SHIFT) +#define RTC_TSTR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */ +#define RTC_TSTR_HT_MASK (3 << RTC_TSTR_HT_SHIFT) +#define RTC_TSTR_PM (1 << 22) /* Bit 22: AM/PM notation */ + +/* RTC time stamp date register */ + +#define RTC_TSDR_DU_SHIFT (0) /* Bit 0-3: Date units in BCD format */ +#define RTC_TSDR_DU_MASK (15 << RTC_TSDR_DU_SHIFT) */ +#define RTC_TSDR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */ +#define RTC_TSDR_DT_MASK (3 << RTC_TSDR_DT_SHIFT) +#define RTC_TSDR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */ +#define RTC_TSDR_MU_MASK (xx << RTC_TSDR_MU_SHIFT) +#define RTC_TSDR_MT (1 << 12) /* Bit 12: Month tens in BCD format */ +#define RTC_TSDR_WDU_SHIFT (13) /* Bits 13-15: Week day units */ +#define RTC_TSDR_WDU_MASK (7 << RTC_TSDR_WDU_SHIFT) + +/* RTC timestamp sub second register */ + +#define RTC_TSSSR_MASK (0xffff) /* Bits 0-15: Sub second value */ + +/* RTC calibration register */ + +#define RTC_CALR_CALM_SHIFT (0) /* Bits 0-8: Calibration minus */ +#define RTC_CALR_CALM_MASK (0x1ff << RTC_CALR_CALM_SHIFT) +#define RTC_CALR_CALW16 (1 << 13) /* Bit 13: Use a 16-second calibration cycle period */ +#define RTC_CALR_CALW8 (1 << 14) /* Bit 14: Use an 8-second calibration cycle period */ +#define RTC_CALR_CALP (1 << 15) /* Bit 15: Increase frequency of RTC by 488.5 ppm */ + +/* RTC tamper and alternate function configuration register */ + +#define RTC_TAFCR_TAMP1E (1 << 0) /* Bit 0: RTC_TAMP1 input detection enable */ +#define RTC_TAFCR_TAMP1TRG (1 << 1) /* Bit 1: Active level for RTC_TAMP1 input */ +#define RTC_TAFCR_TAMPIE (1 << 2) /* Bit 2: Tamper interrupt enable */ +#define RTC_TAFCR_TAMP3E (1 << 5) /* Bit 5: RTC_TAMP3 detection enable */ +#define RTC_TAFCR_TAMP3TRG (1 << 6) /* Bit 6: Active level for RTC_TAMP3 input */ +#define RTC_TAFCR_TAMPTS (1 << 7) /* Bit 7: Activate timestamp on tamper detection event */ +#define RTC_TAFCR_TAMPFREQ_SHIFT (8) /* Bits 8-10: Tamper sampling frequency */ +#define RTC_TAFCR_TAMPFREQ_MASK (7 << RTC_TAFCR_TAMPFREQ_SHIFT) +# define RTC_TAFCR_TAMPFREQ_DIV32768 (0 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 32768 (1 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV16384 (1 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 16384 (2 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV8192 (2 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 8192 (4 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV4096 (3 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 4096 (8 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV2048 (4 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 2048 (16 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV1024 (5 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 1024 (32 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV512 (6 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 512 (64 Hz) */ +# define RTC_TAFCR_TAMPFREQ_DIV256 (7 << RTC_TAFCR_TAMPFREQ_SHIFT) /* RTCCLK / 256 (128 Hz) */ +#define RTC_TAFCR_TAMPFLT_SHIFT (11) /* Bits 11-12: RTC_TAMPx filter count */ +#define RTC_TAFCR_TAMPFLT_MASK (3 << RTC_TAFCR_TAMPFLT_SHIFT) +#define RTC_TAFCR_TAMPPRCH_SHIFT (13) /* Bits 13-14: RTC_TAMPx precharge duration */ +#define RTC_TAFCR_TAMPPRCH_MASK (3 << RTC_TAFCR_TAMPPRCH_SHIFT) +# define RTC_TAFCR_TAMPPRCH_1CYCLE (0 << RTC_TAFCR_TAMPPRCH_SHIFT) /* 1 RTCCLK cycle */ +# define RTC_TAFCR_TAMPPRCH_2CYCLES (1 << RTC_TAFCR_TAMPPRCH_SHIFT) /* 2 RTCCLK cycles */ +# define RTC_TAFCR_TAMPPRCH_4CYCLES (2 << RTC_TAFCR_TAMPPRCH_SHIFT) /* 4 RTCCLK cycles */ +# define RTC_TAFCR_TAMPPRCH_5CYCLES (3 << RTC_TAFCR_TAMPPRCH_SHIFT) /* 8 RTCCLK cycles */ +#define RTC_TAFCR_TAMPPUDIS (1 << 15) /* Bit 15: RTC_TAMPx pull-up disable */ +#define RTC_TAFCR_PC13VALUE (1 << 18) /* Bit 18: RTC_ALARM output type/PC13 value */ +#define RTC_TAFCR_PC13MODE (1 << 19) /* Bit 19: PC13 mode */ +#define RTC_TAFCR_PC14VALUE (1 << 20) /* Bit 20: PC14 value */ +#define RTC_TAFCR_PC14MODE (1 << 21) /* Bit 21: PC14 mode */ +#define RTC_TAFCR_PC15VALUE (1 << 22) /* Bit 22: PC15 value */ +#define RTC_TAFCR_PC15MODE (1 << 23) /* Bit 23: PC15 mode */ + +/* RTC alarm A/B sub second register */ + +#define RTC_ALRMSSR_SS_SHIFT (0) /* Bits 0-14: Sub second value */ +#define RTC_ALRMSSR_SS_MASK (0x7fff << RTC_ALRMSSR_SS_SHIFT) +#define RTC_ALRMSSR_MASKSS_SHIFT (24) /* Bits 24-27: Mask the most-significant bits starting at this bit */ +#define RTC_ALRMSSR_MASKSS_MASK (0xf << RTC_ALRMSSR_MASKSS_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_RTCC_H */ diff --git a/arch/arm/src/stm32/chip/stm32_sdio.h b/arch/arm/src/stm32/chip/stm32_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..7f1a68b485e92165bac8bfb2875e8f38dd8067a5 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_sdio.h @@ -0,0 +1,291 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_sdio.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_SDIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_SDIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_SDIO_POWER_OFFSET 0x0000 /* SDIO power control register */ +#define STM32_SDIO_CLKCR_OFFSET 0x0004 /* SDI clock control register */ +#define STM32_SDIO_ARG_OFFSET 0x0008 /* SDIO argument register */ +#define STM32_SDIO_CMD_OFFSET 0x000c /* SDIO command register */ +#define STM32_SDIO_RESPCMD_OFFSET 0x0010 /* SDIO command response register */ +#define STM32_SDIO_RESP_OFFSET(n) (0x0010+4*(n)) +#define STM32_SDIO_RESP1_OFFSET 0x0014 /* SDIO response 1 register */ +#define STM32_SDIO_RESP2_OFFSET 0x0018 /* SDIO response 2 register */ +#define STM32_SDIO_RESP3_OFFSET 0x001c /* SDIO response 3 register */ +#define STM32_SDIO_RESP4_OFFSET 0x0020 /* SDIO response 4 register */ +#define STM32_SDIO_DTIMER_OFFSET 0x0024 /* SDIO data timer register */ +#define STM32_SDIO_DLEN_OFFSET 0x0028 /* SDIO data length register */ +#define STM32_SDIO_DCTRL_OFFSET 0x002c /* SDIO data control register */ +#define STM32_SDIO_DCOUNT_OFFSET 0x0030 /* SDIO data counter register */ +#define STM32_SDIO_STA_OFFSET 0x0034 /* SDIO status register */ +#define STM32_SDIO_ICR_OFFSET 0x0038 /* SDIO interrupt clear register */ +#define STM32_SDIO_MASK_OFFSET 0x003c /* SDIO mask register */ +#define STM32_SDIO_FIFOCNT_OFFSET 0x0048 /* SDIO FIFO counter register */ +#define STM32_SDIO_FIFO_OFFSET 0x0080 /* SDIO data FIFO register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_SDIO_POWER (STM32_SDIO_BASE+STM32_SDIO_POWER_OFFSET) +#define STM32_SDIO_CLKCR (STM32_SDIO_BASE+STM32_SDIO_CLKCR_OFFSET) +#define STM32_SDIO_ARG (STM32_SDIO_BASE+STM32_SDIO_ARG_OFFSET) +#define STM32_SDIO_CMD (STM32_SDIO_BASE+STM32_SDIO_CMD_OFFSET) +#define STM32_SDIO_RESPCMD (STM32_SDIO_BASE+STM32_SDIO_RESPCMD_OFFSET) +#define STM32_SDIO_RESP(n) (STM32_SDIO_BASE+STM32_SDIO_RESP_OFFSET(n)) +#define STM32_SDIO_RESP1 (STM32_SDIO_BASE+STM32_SDIO_RESP1_OFFSET) +#define STM32_SDIO_RESP2 (STM32_SDIO_BASE+STM32_SDIO_RESP2_OFFSET) +#define STM32_SDIO_RESP3 (STM32_SDIO_BASE+STM32_SDIO_RESP3_OFFSET) +#define STM32_SDIO_RESP4 (STM32_SDIO_BASE+STM32_SDIO_RESP4_OFFSET) +#define STM32_SDIO_DTIMER (STM32_SDIO_BASE+STM32_SDIO_DTIMER_OFFSET) +#define STM32_SDIO_DLEN (STM32_SDIO_BASE+STM32_SDIO_DLEN_OFFSET) +#define STM32_SDIO_DCTRL (STM32_SDIO_BASE+STM32_SDIO_DCTRL_OFFSET) +#define STM32_SDIO_DCOUNT (STM32_SDIO_BASE+STM32_SDIO_DCOUNT_OFFSET) +#define STM32_SDIO_STA (STM32_SDIO_BASE+STM32_SDIO_STA_OFFSET) +#define STM32_SDIO_ICR (STM32_SDIO_BASE+STM32_SDIO_ICR_OFFSET) +#define STM32_SDIO_MASK (STM32_SDIO_BASE+STM32_SDIO_MASK_OFFSET) +#define STM32_SDIO_FIFOCNT (STM32_SDIO_BASE+STM32_SDIO_FIFOCNT_OFFSET) +#define STM32_SDIO_FIFO (STM32_SDIO_BASE+STM32_SDIO_FIFO_OFFSET) + +/* Bit-band (BB) base addresses ****************************************************/ + +#define STM32_SDIO_OFFSET (STM32_SDIO_BASE-STM32_PERIPH_BASE) + +#define STM32_SDIO_POWER_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_POWER_OFFSET)<<5)) +#define STM32_SDIO_CLKCR_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_CLKCR_OFFSET)<<5)) +#define STM32_SDIO_ARG_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_ARG_OFFSET)<<5)) +#define STM32_SDIO_CMD_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_CMD_OFFSET)<<5)) +#define STM32_SDIO_RESPCMD_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESPCMD_OFFSET)<<5)) +#define STM32_SDIO_RESP_BB(n) (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP_OFFSET(n))<<5)) +#define STM32_SDIO_RESP1_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP1_OFFSET)<<5)) +#define STM32_SDIO_RESP2_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP2_OFFSET)<<5)) +#define STM32_SDIO_RESP3_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP3_OFFSET)<<5)) +#define STM32_SDIO_RESP4_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP4_OFFSET)<<5)) +#define STM32_SDIO_DTIMER_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DTIMER_OFFSET)<<5)) +#define STM32_SDIO_DLEN_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DLEN_OFFSET)<<5)) +#define STM32_SDIO_DCTRL_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DCTRL_OFFSET)<<5)) +#define STM32_SDIO_DCOUNT_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DCOUNT_OFFSET)<<5)) +#define STM32_SDIO_STA_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_STA_OFFSET)<<5)) +#define STM32_SDIO_ICR_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_ICR_OFFSET)<<5)) +#define STM32_SDIO_MASK_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_MASK_OFFSET)<<5)) +#define STM32_SDIO_FIFOCNT_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_FIFOCNT_OFFSET)<<5)) +#define STM32_SDIO_FIFO_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_FIFO_OFFSET)<<5)) + +/* Register Bitfield Definitions ****************************************************/ + +#define SDIO_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ +#define SDIO_POWER_PWRCTRL_MASK (3 << SDIO_POWER_PWRCTRL_SHIFT) +# define SDIO_POWER_PWRCTRL_OFF (0 << SDIO_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */ +# define SDIO_POWER_PWRCTRL_PWRUP (2 << SDIO_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */ +# define SDIO_POWER_PWRCTRL_ON (3 << SDIO_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */ + +#define SDIO_POWER_RESET (0) /* Reset value */ + +#define SDIO_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ +#define SDIO_CLKCR_CLKDIV_MASK (0xff << SDIO_CLKCR_CLKDIV_SHIFT) +#define SDIO_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ +#define SDIO_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ +#define SDIO_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ +#define SDIO_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */ +#define SDIO_CLKCR_WIDBUS_MASK (3 << SDIO_CLKCR_WIDBUS_SHIFT) +# define SDIO_CLKCR_WIDBUS_D1 (0 << SDIO_CLKCR_WIDBUS_SHIFT) /* 00: Default (SDIO_D0) */ +# define SDIO_CLKCR_WIDBUS_D4 (1 << SDIO_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (SDIO_D[3:0]) */ +# define SDIO_CLKCR_WIDBUS_D8 (2 << SDIO_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (SDIO_D[7:0]) */ +#define SDIO_CLKCR_NEGEDGE (1 << 13) /* Bit 13: SDIO_CK dephasing selection bit */ +#define SDIO_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */ + +#define SDIO_CLKCR_RESET (0) /* Reset value */ +#define SDIO_ARG_RESET (0) /* Reset value */ + +#define SDIO_CLKCR_CLKEN_BB (STM32_SDIO_CLKCR_BB + (8 * 4)) +#define SDIO_CLKCR_PWRSAV_BB (STM32_SDIO_CLKCR_BB + (9 * 4)) +#define SDIO_CLKCR_BYPASS_BB (STM32_SDIO_CLKCR_BB + (10 * 4)) +#define SDIO_CLKCR_NEGEDGE_BB (STM32_SDIO_CLKCR_BB + (13 * 4)) +#define SDIO_CLKCR_HWFC_EN_BB (STM32_SDIO_CLKCR_BB + (14 * 4)) + +#define SDIO_CMD_CMDINDEX_SHIFT (0) +#define SDIO_CMD_CMDINDEX_MASK (0x3f << SDIO_CMD_CMDINDEX_SHIFT) +#define SDIO_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ +#define SDIO_CMD_WAITRESP_MASK (3 << SDIO_CMD_WAITRESP_SHIFT) +# define SDIO_CMD_NORESPONSE (0 << SDIO_CMD_WAITRESP_SHIFT) /* 00/10: No response */ +# define SDIO_CMD_SHORTRESPONSE (1 << SDIO_CMD_WAITRESP_SHIFT) /* 01: Short response */ +# define SDIO_CMD_LONGRESPONSE (3 << SDIO_CMD_WAITRESP_SHIFT) /* 11: Long response */ +#define SDIO_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ +#define SDIO_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ +#define SDIO_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ +#define SDIO_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */ +#define SDIO_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */ +#define SDIO_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */ +#define SDIO_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */ + +#define SDIO_CMD_RESET (0) /* Reset value */ + +#define SDIO_CMD_WAITINT_BB (STM32_SDIO_CMD_BB + (8 * 4)) +#define SDIO_CMD_WAITPEND_BB (STM32_SDIO_CMD_BB + (9 * 4)) +#define SDIO_CMD_CPSMEN_BB (STM32_SDIO_CMD_BB + (10 * 4)) +#define SDIO_CMD_SUSPEND_BB (STM32_SDIO_CMD_BB + (11 * 4)) +#define SDIO_CMD_ENCMD_BB (STM32_SDIO_CMD_BB + (12 * 4)) +#define SDIO_CMD_NIEN_BB (STM32_SDIO_CMD_BB + (13 * 4)) +#define SDIO_CMD_ATACMD_BB (STM32_SDIO_CMD_BB + (14 * 4)) + +#define SDIO_RESPCMD_SHIFT (0) +#define SDIO_RESPCMD_MASK (0x3f << SDIO_RESPCMD_SHIFT) + +#define SDIO_DTIMER_RESET (0) /* Reset value */ + +#define SDIO_DLEN_SHIFT (0) +#define SDIO_DLEN_MASK (0x01ffffff << SDIO_DLEN_SHIFT) + +#define SDIO_DLEN_RESET (0) /* Reset value */ + +#define SDIO_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ +#define SDIO_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ +#define SDIO_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ +#define SDIO_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ +#define SDIO_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */ +#define SDIO_DCTRL_DBLOCKSIZE_MASK (15 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_1BYTE (0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_2BYTES (1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_4BYTES (2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_8BYTES (3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_16BYTES (4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_32BYTES (5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_64BYTES (6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_128BYTES (7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_256BYTES (8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_512BYTES (9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_1KBYTE (10 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_2KBYTES (11 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_4KBYTES (12 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_8KBYTES (13 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_16KBYTES (14 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */ +#define SDIO_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */ +#define SDIO_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */ +#define SDIO_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */ + +#define SDIO_DCTRL_RESET (0) /* Reset value */ + +#define SDIO_DCTRL_DTEN_BB (STM32_SDIO_DCTRL_BB + (0 * 4)) +#define SDIO_DCTRL_DTDIR_BB (STM32_SDIO_DCTRL_BB + (1 * 4)) +#define SDIO_DCTRL_DTMODE_BB (STM32_SDIO_DCTRL_BB + (2 * 4)) +#define SDIO_DCTRL_DMAEN_BB (STM32_SDIO_DCTRL_BB + (3 * 4)) +#define SDIO_DCTRL_RWSTART_BB (STM32_SDIO_DCTRL_BB + (8 * 4)) +#define SDIO_DCTRL_RWSTOP_BB (STM32_SDIO_DCTRL_BB + (9 * 4)) +#define SDIO_DCTRL_RWMOD_BB (STM32_SDIO_DCTRL_BB + (10 * 4)) +#define SDIO_DCTRL_SDIOEN_BB (STM32_SDIO_DCTRL_BB + (11 * 4)) + +#define SDIO_DATACOUNT_SHIFT (0) +#define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT) + +#define SDIO_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ +#define SDIO_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ +#define SDIO_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ +#define SDIO_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ +#define SDIO_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ +#define SDIO_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ +#define SDIO_STA_CMDREND (1 << 6) /* Bit 6: Command response received */ +#define SDIO_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */ +#define SDIO_STA_DATAEND (1 << 8) /* Bit 8: Data end */ +#define SDIO_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ +#define SDIO_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ +#define SDIO_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ +#define SDIO_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ +#define SDIO_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */ +#define SDIO_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ +#define SDIO_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ +#define SDIO_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ +#define SDIO_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ +#define SDIO_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ +#define SDIO_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ +#define SDIO_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ +#define SDIO_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ +#define SDIO_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */ +#define SDIO_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */ + +#define SDIO_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ +#define SDIO_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ +#define SDIO_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ +#define SDIO_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ +#define SDIO_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ +#define SDIO_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ +#define SDIO_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ +#define SDIO_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ +#define SDIO_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ +#define SDIO_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ +#define SDIO_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ +#define SDIO_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */ +#define SDIO_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */ + +#define SDIO_ICR_RESET 0x00c007ff +#define SDIO_ICR_STATICFLAGS 0x000005ff + +#define SDIO_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ +#define SDIO_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ +#define SDIO_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ +#define SDIO_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ +#define SDIO_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ +#define SDIO_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ +#define SDIO_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ +#define SDIO_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ +#define SDIO_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ +#define SDIO_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ +#define SDIO_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ +#define SDIO_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ +#define SDIO_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ +#define SDIO_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ +#define SDIO_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ +#define SDIO_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ +#define SDIO_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ +#define SDIO_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ +#define SDIO_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ +#define SDIO_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ +#define SDIO_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ +#define SDIO_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ +#define SDIO_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */ +#define SDIO_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */ + +#define SDIO_MASK_RESET (0) + +#define SDIO_FIFOCNT_SHIFT (0) +#define SDIO_FIFOCNT_MASK (0x01ffffff << SDIO_FIFOCNT_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_SDIO_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_spi.h b/arch/arm/src/stm32/chip/stm32_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..bdbabab33461794d0f645bbbd2c496f85e188e8b --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_spi.h @@ -0,0 +1,255 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_spi.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32_SPI_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Maximum allowed speed as per specifications for all SPIs */ + +#if defined(CONFIG_STM32_STM32F40XX) +# define STM32_SPI_CLK_MAX 37500000UL +#else +# define STM32_SPI_CLK_MAX 18000000UL +#endif + +/* Register Offsets *****************************************************************/ + +#define STM32_SPI_CR1_OFFSET 0x0000 /* SPI Control Register 1 (16-bit) */ +#define STM32_SPI_CR2_OFFSET 0x0004 /* SPI control register 2 (16-bit) */ +#define STM32_SPI_SR_OFFSET 0x0008 /* SPI status register (16-bit) */ +#define STM32_SPI_DR_OFFSET 0x000c /* SPI data register (16-bit) */ +#define STM32_SPI_CRCPR_OFFSET 0x0010 /* SPI CRC polynomial register (16-bit) */ +#define STM32_SPI_RXCRCR_OFFSET 0x0014 /* SPI Rx CRC register (16-bit) */ +#define STM32_SPI_TXCRCR_OFFSET 0x0018 /* SPI Tx CRC register (16-bit) */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define STM32_SPI_I2SCFGR_OFFSET 0x001c /* I2S configuration register */ +# define STM32_SPI_I2SPR_OFFSET 0x0020 /* I2S prescaler register */ +#endif + +/* Register Addresses ***************************************************************/ + +#if STM32_NSPI > 0 +# define STM32_SPI1_CR1 (STM32_SPI1_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI1_CR2 (STM32_SPI1_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI1_SR (STM32_SPI1_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI1_DR (STM32_SPI1_BASE+STM32_SPI_DR_OFFSET) +# define STM32_SPI1_CRCPR (STM32_SPI1_BASE+STM32_SPI_CRCPR_OFFSET) +# define STM32_SPI1_RXCRCR (STM32_SPI1_BASE+STM32_SPI_RXCRCR_OFFSET) +# define STM32_SPI1_TXCRCR (STM32_SPI1_BASE+STM32_SPI_TXCRCR_OFFSET) +#endif + +#if STM32_NSPI > 1 +# define STM32_SPI2_CR1 (STM32_SPI2_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI2_CR2 (STM32_SPI2_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI2_SR (STM32_SPI2_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI2_DR (STM32_SPI2_BASE+STM32_SPI_DR_OFFSET) +# define STM32_SPI2_CRCPR (STM32_SPI2_BASE+STM32_SPI_CRCPR_OFFSET) +# define STM32_SPI2_RXCRCR (STM32_SPI2_BASE+STM32_SPI_RXCRCR_OFFSET) +# define STM32_SPI2_TXCRCR (STM32_SPI2_BASE+STM32_SPI_TXCRCR_OFFSET) +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define STM32_SPI2_I2SCFGR (STM32_SPI2_BASE+STM32_SPI_I2SCFGR_OFFSET) +# define STM32_SPI2_I2SPR (STM32_SPI2_BASE+STM32_SPI_I2SPR_OFFSET) +# endif +#endif + +#if STM32_NSPI > 2 +# define STM32_SPI3_CR1 (STM32_SPI3_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI3_CR2 (STM32_SPI3_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI3_SR (STM32_SPI3_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI3_DR (STM32_SPI3_BASE+STM32_SPI_DR_OFFSET) +# define STM32_SPI3_CRCPR (STM32_SPI3_BASE+STM32_SPI_CRCPR_OFFSET) +# define STM32_SPI3_RXCRCR (STM32_SPI3_BASE+STM32_SPI_RXCRCR_OFFSET) +# define STM32_SPI3_TXCRCR (STM32_SPI3_BASE+STM32_SPI_TXCRCR_OFFSET) +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define STM32_SPI3_I2SCFGR (STM32_SPI3_BASE+STM32_SPI_I2SCFGR_OFFSET) +# define STM32_SPI3_I2SPR (STM32_SPI3_BASE+STM32_SPI_I2SPR_OFFSET) +# endif +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* SPI Control Register 1 */ + +#define SPI_CR1_CPHA (1 << 0) /* Bit 0: Clock Phase */ +#define SPI_CR1_CPOL (1 << 1) /* Bit 1: Clock Polarity */ +#define SPI_CR1_MSTR (1 << 2) /* Bit 2: Master Selection */ +#define SPI_CR1_BR_SHIFT (3) /* Bits 5:3 Baud Rate Control */ +#define SPI_CR1_BR_MASK (7 << SPI_CR1_BR_SHIFT) +# define SPI_CR1_FPCLCKd2 (0 << SPI_CR1_BR_SHIFT) /* 000: fPCLK/2 */ +# define SPI_CR1_FPCLCKd4 (1 << SPI_CR1_BR_SHIFT) /* 001: fPCLK/4 */ +# define SPI_CR1_FPCLCKd8 (2 << SPI_CR1_BR_SHIFT) /* 010: fPCLK/8 */ +# define SPI_CR1_FPCLCKd16 (3 << SPI_CR1_BR_SHIFT) /* 011: fPCLK/16 */ +# define SPI_CR1_FPCLCKd32 (4 << SPI_CR1_BR_SHIFT) /* 100: fPCLK/32 */ +# define SPI_CR1_FPCLCKd64 (5 << SPI_CR1_BR_SHIFT) /* 101: fPCLK/64 */ +# define SPI_CR1_FPCLCKd128 (6 << SPI_CR1_BR_SHIFT) /* 110: fPCLK/128 */ +# define SPI_CR1_FPCLCKd256 (7 << SPI_CR1_BR_SHIFT) /* 111: fPCLK/256 */ +#define SPI_CR1_SPE (1 << 6) /* Bit 6: SPI Enable */ +#define SPI_CR1_LSBFIRST (1 << 7) /* Bit 7: Frame Format */ +#define SPI_CR1_SSI (1 << 8) /* Bit 8: Internal slave select */ +#define SPI_CR1_SSM (1 << 9) /* Bit 9: Software slave management */ +#define SPI_CR1_RXONLY (1 << 10) /* Bit 10: Receive only */ +#define SPI_CR1_DFF (1 << 11) /* Bit 11: Data Frame Format */ +#define SPI_CR1_CRCNEXT (1 << 12) /* Bit 12: Transmit CRC next */ +#define SPI_CR1_CRCEN (1 << 13) /* Bit 13: Hardware CRC calculation enable */ +#define SPI_CR1_BIDIOE (1 << 14) /* Bit 14: Output enable in bidirectional mode */ +#define SPI_CR1_BIDIMODE (1 << 15) /* Bit 15: Bidirectional data mode enable */ + +/* SPI Control Register 2 */ + +#define SPI_CR2_RXDMAEN (1 << 0) /* Bit 0: Rx Buffer DMA Enable */ +#define SPI_CR2_TXDMAEN (1 << 1) /* Bit 1: Tx Buffer DMA Enable */ +#define SPI_CR2_SSOE (1 << 2) /* Bit 2: SS Output Enable */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define SPI_CR2_FRF (1 << 4) /* Bit 4: Frame format */ +#endif + +#define SPI_CR2_ERRIE (1 << 5) /* Bit 5: Error interrupt enable */ +#define SPI_CR2_RXNEIE (1 << 6) /* Bit 6: RX buffer not empty interrupt enable */ +#define SPI_CR2_TXEIE (1 << 7) /* Bit 7: Tx buffer empty interrupt enable */ + +#ifdef CONFIG_STM32_STM32F30XX +#define SPI_CR1_DS_SHIFT (8) /* Bits 8-11: Data size */ +#define SPI_CR1_DS_MASK (15 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_4BIT (3 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_5BIT (4 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_6BIT (5 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_7BIT (6 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_8BIT (7 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_9BIT (8 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_10BIT (9 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_11BIT (10 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_12BIT (11 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_13BIT (12 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_14BIT (13 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_15BIT (14 << SPI_CR1_DS_SHIFT) +# define SPI_CR1_DS_16BIT (15 << SPI_CR1_DS_SHIFT) +#define SPI_CR2_FRXTH (1 << 12) /* Bit 12: FIFO reception threshold */ +#define SPI_CR2_LDMARX (1 << 13) /* Bit 13: Last DMA transfer for receptione */ +#define SPI_CR2_LDMATX (1 << 14) /* Bit 14: Last DMA transfer for transmission */ +#endif + +/* SPI status register */ + +#define SPI_SR_RXNE (1 << 0) /* Bit 0: Receive buffer not empty */ +#define SPI_SR_TXE (1 << 1) /* Bit 1: Transmit buffer empty */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define SPI_SR_CHSIDE (1 << 2) /* Bit 2: Channel side */ +# define SPI_SR_UDR (1 << 3) /* Bit 3: Underrun flag */ +#endif + +#define SPI_SR_CRCERR (1 << 4) /* Bit 4: CRC error flag */ +#define SPI_SR_MODF (1 << 5) /* Bit 5: Mode fault */ +#define SPI_SR_OVR (1 << 6) /* Bit 6: Overrun flag */ +#define SPI_SR_BSY (1 << 7) /* Bit 7: Busy flag */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define SPI_SR_TIFRFE (1 << 8) /* Bit 8: TI frame format error */ +#endif + +#ifdef CONFIG_STM32_STM32F30XX +#define SPI_CR1_FRLVL_SHIFT (9) /* Bits 9-10: FIFO reception level */ +#define SPI_CR1_FRLVL_MASK (3 << SPI_CR1_FRLVL_SHIFT) +# define SPI_CR1_FRLVL_EMPTY (0 << SPI_CR1_FRLVL_SHIFT) /* FIFO empty */ +# define SPI_CR1_FRLVL_QUARTER (1 << SPI_CR1_FRLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_CR1_FRLVL_HALF (2 << SPI_CR1_FRLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_CR1_FRLVL_FULL (3 << SPI_CR1_FRLVL_SHIFT) /* FIFO full */ +#define SPI_CR1_FTLVL_SHIFT (11) /* Bits 11-12: FIFO transmission level */ +#define SPI_CR1_FTLVL_MASK (3 << SPI_CR1_FTLVL_SHIFT) +# define SPI_CR1_FTLVL_EMPTY (0 << SPI_CR1_FTLVL_SHIFT) /* FIFO empty */ +# define SPI_CR1_FTLVL_QUARTER (1 << SPI_CR1_FTLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_CR1_FTLVL_HALF (2 << SPI_CR1_FTLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_CR1_FTLVL_FULL (3 << SPI_CR1_FTLVL_SHIFT) /* FIFO full */ +#endif + +/* I2S configuration register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define SPI_I2SCFGR_CHLEN (1 << 0) /* Bit 0: Channel length (number of bits per audio channel) */ +# define SPI_I2SCFGR_DATLEN_SHIFT (1) /* Bit 1-2: Data length to be transferred */ +# define SPI_I2SCFGR_DATLEN_MASK (3 << SPI_I2SCFGR_DATLEN_SHIFT) +# define SPI_I2SCFGR_DATLEN_16BIT (0 << SPI_I2SCFGR_DATLEN_SHIFT) /* 00: 16-bit data length */ +# define SPI_I2SCFGR_DATLEN_8BIT (1 << SPI_I2SCFGR_DATLEN_SHIFT) /* 01: 24-bit data length */ +# define SPI_I2SCFGR_DATLEN_32BIT (2 << SPI_I2SCFGR_DATLEN_SHIFT) /* 10: 32-bit data length */ +# define SPI_I2SCFGR_CKPOL (1 << 3) /* Bit 3: Steady state clock polarity */ +# define SPI_I2SCFGR_I2SSTD_SHIFT (4) /* Bit 4-5: I2S standard selection */ +# define SPI_I2SCFGR_I2SSTD_MASK (3 << SPI_I2SCFGR_I2SSTD_SHIFT) +# define SPI_I2SCFGR_I2SSTD_PHILLIPS (xx << SPI_I2SCFGR_I2SSTD_SHIFT) /* 00: I2S Phillips standard. */ +# define SPI_I2SCFGR_I2SSTD_MSB (0 << SPI_I2SCFGR_I2SSTD_SHIFT) /* 01: MSB justified standard (left justified) */ +# define SPI_I2SCFGR_I2SSTD_LSB (2 << SPI_I2SCFGR_I2SSTD_SHIFT) /* 10: LSB justified standard (right justified) */ +# define SPI_I2SCFGR_I2SSTD_PCM (3 << SPI_I2SCFGR_I2SSTD_SHIFT) /* 11: PCM standard */ +# define SPI_I2SCFGR_PCMSYNC (1 << 7) /* Bit 7: PCM frame synchronization */ +# define SPI_I2SCFGR_I2SCFG_SHIFT (8) /* Bit 8-9: I2S configuration mode */ +# define SPI_I2SCFGR_I2SCFG_MASK (3 << SPI_I2SCFGR_I2SCFG_SHIFT) +# define SPI_I2SCFGR_I2SCFG_STX (0 << SPI_I2SCFGR_I2SCFG_SHIFT) /* 00: Slave - transmit */ +# define SPI_I2SCFGR_I2SCFG_SRX (1 << SPI_I2SCFGR_I2SCFG_SHIFT) /* 01: Slave - receive */ +# define SPI_I2SCFGR_I2SCFG_MTX (2 << SPI_I2SCFGR_I2SCFG_SHIFT) /* 10: Master - transmit */ +# define SPI_I2SCFGR_I2SCFG_MRX (3 << SPI_I2SCFGR_I2SCFG_SHIFT) /* 11: Master - receive */ +# define SPI_I2SCFGR_I2SE (1 << 10) /* Bit 10: I2S Enable */ +# define SPI_I2SCFGR_I2SMOD (1 << 11) /* Bit 11: I2S mode selection */ +#endif + +/* I2S prescaler register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define SPI_I2SPR_I2SDIV_SHIFT (0) /* Bit 0-7: I2S Linear prescaler */ +# define SPI_I2SPR_I2SDIV_MASK (0xff << SPI_I2SPR_I2SDIV_SHIFT) +# define SPI_I2SPR_ODD (1 << 8) /* Bit 8: Odd factor for the prescaler */ +# define SPI_I2SPR_MCKOE (1 << 9) /* Bit 9: Master clock output enable */ +#endif + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32_SPI_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_tim.h b/arch/arm/src/stm32/chip/stm32_tim.h new file mode 100644 index 0000000000000000000000000000000000000000..56c748a98f46b4a98ed70feb46be41c3e0162f8c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_tim.h @@ -0,0 +1,1341 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32_tim.h + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_TIM_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_TIM_H + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +/* Basic Timers - TIM6 and TIM7 */ + +#define STM32_BTIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32_BTIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit) */ +#define STM32_BTIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32_BTIM_SR_OFFSET 0x0010 /* Status register (16-bit) */ +#define STM32_BTIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32_BTIM_CNT_OFFSET 0x0024 /* Counter (16-bit) */ +#define STM32_BTIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32_BTIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit) */ + +/* 16-/32-bit General Timers with DMA: TIM2, TM3, TIM4, and TIM5 + * 16-bit General Timers without DMA: TIM9, TIM10, TIM11, TIM12, TIM13, and TIM14 + * For the STM32F10xx all timers are 16-bit. + * For the STM32F20xx and STM32F40xx, TIM2 and 5 are 32-bit + * The STM32 F1 Value Line and the STM32 F3 have variant general purpose registers + * that are not yet fully covered in this header file. + */ + +#define STM32_GTIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32_GTIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit, TIM2-5 only) */ +#define STM32_GTIM_SMCR_OFFSET 0x0008 /* Slave mode control register (16-bit, TIM2-5 only) */ +#define STM32_GTIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32_GTIM_SR_OFFSET 0x0010 /* Status register (16-bit) */ +#define STM32_GTIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32_GTIM_CCMR1_OFFSET 0x0018 /* Capture/compare mode register 1 (16-bit) */ +#define STM32_GTIM_CCMR2_OFFSET 0x001c /* Capture/compare mode register 2 (16-bit, TIM2-5 only) */ +#define STM32_GTIM_CCER_OFFSET 0x0020 /* Capture/compare enable register (16-bit) */ +#define STM32_GTIM_CNT_OFFSET 0x0024 /* Counter (16-bit* or 32-bit STM3240 TIM2 and 5 only) */ +#define STM32_GTIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32_GTIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit) */ +#define STM32_GTIM_CCR1_OFFSET 0x0034 /* Capture/compare register 1 (16-bit or 32-bit STM3240 TIM2/5 only) */ +#define STM32_GTIM_CCR2_OFFSET 0x0038 /* Capture/compare register 2 (16-bit TIM2-5 only or 32-bit STM32 F4 TIM2/5 or STM2 F3 TIM15 only) */ +#define STM32_GTIM_CCR3_OFFSET 0x003c /* Capture/compare register 3 (16-bit TIM2-5 only or 32-bit STM32 F4 TIM2/5 only) */ +#define STM32_GTIM_CCR4_OFFSET 0x0040 /* Capture/compare register 4 (16-bit TIM2-5 only or 32-bit STM32 F4 TIM2/5 only) */ +#define STM32_GTIM_DCR_OFFSET 0x0048 /* DMA control register (16-bit, TIM2-5 only) */ +#define STM32_GTIM_DMAR_OFFSET 0x004c /* DMA address for burst mode (16-bit, TIM2-5 only) */ + +/* The Option register is available on in the + * + * STM32 F1 value line, F2 and F4: TIM2, TIM5, and TIM11 + * STM32 F3 (and possibly the F1 value line): TIM16 + */ + +#define STM32_GTIM_OR_OFFSET 0x0050 /* Timer 2/5/11/16 option register */ + +/* TIM16, and 17 only. + * Only available in the STM32 F1 Value Line and the STM32 F3 family. + */ + +#define STM32_GTIM_RCR_OFFSET 0x002c /* Repetition counter register (TIM16/TIM17) */ +#define STM32_GTIM_BDTR_OFFSET 0x0044 /* Break and dead-time register (TIM16/TIM17) */ + +/* Advanced Timers - TIM1 and TIM8 */ + +#define STM32_ATIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32_ATIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit*) */ +#define STM32_ATIM_SMCR_OFFSET 0x0008 /* Slave mode control register (16-bit) */ +#define STM32_ATIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32_ATIM_SR_OFFSET 0x0010 /* Status register (16-bit*) */ +#define STM32_ATIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32_ATIM_CCMR1_OFFSET 0x0018 /* Capture/compare mode register 1 (16-bit*) */ +#define STM32_ATIM_CCMR2_OFFSET 0x001c /* Capture/compare mode register 2 (16-bit*) */ +#define STM32_ATIM_CCER_OFFSET 0x0020 /* Capture/compare enable register (16-bit*) */ +#define STM32_ATIM_CNT_OFFSET 0x0024 /* Counter (16-bit) */ +#define STM32_ATIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32_ATIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit) */ +#define STM32_ATIM_RCR_OFFSET 0x0030 /* Repetition counter register (16-bit) */ +#define STM32_ATIM_CCR1_OFFSET 0x0034 /* Capture/compare register 1 (16-bit) */ +#define STM32_ATIM_CCR2_OFFSET 0x0038 /* Capture/compare register 2 (16-bit) */ +#define STM32_ATIM_CCR3_OFFSET 0x003c /* Capture/compare register 3 (16-bit) */ +#define STM32_ATIM_CCR4_OFFSET 0x0040 /* Capture/compare register 4 (16-bit) */ +#define STM32_ATIM_BDTR_OFFSET 0x0044 /* Break and dead-time register (16-bit*) */ +#define STM32_ATIM_DCR_OFFSET 0x0048 /* DMA control register (16-bit) */ +#define STM32_ATIM_DMAR_OFFSET 0x004c /* DMA address for burst mode (16-bit) */ + +/* *Note that many of the above registers are 32-bits wide on the F3 */ + +#ifdef CONFIG_STM32_STM32F30XX +# define STM32_ATIM_CCMR3_OFFSET 0x0054 /* Capture/compare mode register 3 (32-bit) */ +# define STM32_ATIM_CCR5_OFFSET 0x0058 /* Capture/compare register 4 (16-bit) */ +# define STM32_ATIM_CCR6_OFFSET 0x005c /* Capture/compare register 4 (32-bit) */ +#endif + +/* Register Addresses *******************************************************************************/ + +/* Advanced Timers - TIM1 and TIM8 */ + +#if STM32_NATIM > 0 +# define STM32_TIM1_CR1 (STM32_TIM1_BASE+STM32_ATIM_CR1_OFFSET) +# define STM32_TIM1_CR2 (STM32_TIM1_BASE+STM32_ATIM_CR2_OFFSET) +# define STM32_TIM1_SMCR (STM32_TIM1_BASE+STM32_ATIM_SMCR_OFFSET) +# define STM32_TIM1_DIER (STM32_TIM1_BASE+STM32_ATIM_DIER_OFFSET) +# define STM32_TIM1_SR (STM32_TIM1_BASE+STM32_ATIM_SR_OFFSET) +# define STM32_TIM1_EGR (STM32_TIM1_BASE+STM32_ATIM_EGR_OFFSET) +# define STM32_TIM1_CCMR1 (STM32_TIM1_BASE+STM32_ATIM_CCMR1_OFFSET) +# define STM32_TIM1_CCMR2 (STM32_TIM1_BASE+STM32_ATIM_CCMR2_OFFSET) +# define STM32_TIM1_CCER (STM32_TIM1_BASE+STM32_ATIM_CCER_OFFSET) +# define STM32_TIM1_CNT (STM32_TIM1_BASE+STM32_ATIM_CNT_OFFSET) +# define STM32_TIM1_PSC (STM32_TIM1_BASE+STM32_ATIM_PSC_OFFSET) +# define STM32_TIM1_ARR (STM32_TIM1_BASE+STM32_ATIM_ARR_OFFSET) +# define STM32_TIM1_RCR (STM32_TIM1_BASE+STM32_ATIM_RCR_OFFSET) +# define STM32_TIM1_CCR1 (STM32_TIM1_BASE+STM32_ATIM_CCR1_OFFSET) +# define STM32_TIM1_CCR2 (STM32_TIM1_BASE+STM32_ATIM_CCR2_OFFSET) +# define STM32_TIM1_CCR3 (STM32_TIM1_BASE+STM32_ATIM_CCR3_OFFSET) +# define STM32_TIM1_CCR4 (STM32_TIM1_BASE+STM32_ATIM_CCR4_OFFSET) +# define STM32_TIM1_BDTR (STM32_TIM1_BASE+STM32_ATIM_BDTR_OFFSET) +# define STM32_TIM1_DCR (STM32_TIM1_BASE+STM32_ATIM_DCR_OFFSET) +# define STM32_TIM1_DMAR (STM32_TIM1_BASE+STM32_ATIM_DMAR_OFFSET) +# ifdef CONFIG_STM32_STM32F30XX +# define STM32_TIM1_CCMR3 (STM32_TIM1_BASE+STM32_ATIM_CCMR3_OFFSET) +# define STM32_TIM1_CCR5 (STM32_TIM1_BASE+STM32_ATIM_CCR5_OFFSET) +# define STM32_TIM1_CCR6 (STM32_TIM1_BASE+STM32_ATIM_CCR6_OFFSET) +# endif +#endif + +#if STM32_NATIM > 1 +# define STM32_TIM8_CR1 (STM32_TIM8_BASE+STM32_ATIM_CR1_OFFSET) +# define STM32_TIM8_CR2 (STM32_TIM8_BASE+STM32_ATIM_CR2_OFFSET) +# define STM32_TIM8_SMCR (STM32_TIM8_BASE+STM32_ATIM_SMCR_OFFSET) +# define STM32_TIM8_DIER (STM32_TIM8_BASE+STM32_ATIM_DIER_OFFSET) +# define STM32_TIM8_SR (STM32_TIM8_BASE+STM32_ATIM_SR_OFFSET) +# define STM32_TIM8_EGR (STM32_TIM8_BASE+STM32_ATIM_EGR_OFFSET) +# define STM32_TIM8_CCMR1 (STM32_TIM8_BASE+STM32_ATIM_CCMR1_OFFSET) +# define STM32_TIM8_CCMR2 (STM32_TIM8_BASE+STM32_ATIM_CCMR2_OFFSET) +# define STM32_TIM8_CCER (STM32_TIM8_BASE+STM32_ATIM_CCER_OFFSET) +# define STM32_TIM8_CNT (STM32_TIM8_BASE+STM32_ATIM_CNT_OFFSET) +# define STM32_TIM8_PSC (STM32_TIM8_BASE+STM32_ATIM_PSC_OFFSET) +# define STM32_TIM8_ARR (STM32_TIM8_BASE+STM32_ATIM_ARR_OFFSET) +# define STM32_TIM8_RCR (STM32_TIM8_BASE+STM32_ATIM_RCR_OFFSET) +# define STM32_TIM8_CCR1 (STM32_TIM8_BASE+STM32_ATIM_CCR1_OFFSET) +# define STM32_TIM8_CCR2 (STM32_TIM8_BASE+STM32_ATIM_CCR2_OFFSET) +# define STM32_TIM8_CCR3 (STM32_TIM8_BASE+STM32_ATIM_CCR3_OFFSET) +# define STM32_TIM8_CCR4 (STM32_TIM8_BASE+STM32_ATIM_CCR4_OFFSET) +# define STM32_TIM8_BDTR (STM32_TIM8_BASE+STM32_ATIM_BDTR_OFFSET) +# define STM32_TIM8_DCR (STM32_TIM8_BASE+STM32_ATIM_DCR_OFFSET) +# define STM32_TIM8_DMAR (STM32_TIM8_BASE+STM32_ATIM_DMAR_OFFSET) +# ifdef CONFIG_STM32_STM32F30XX +# define STM32_TIM8_CCMR3 (STM32_TIM8_BASE+STM32_ATIM_CCMR3_OFFSET) +# define STM32_TIM8_CCR5 (STM32_TIM8_BASE+STM32_ATIM_CCR5_OFFSET) +# define STM32_TIM8_CCR6 (STM32_TIM8_BASE+STM32_ATIM_CCR6_OFFSET) +# endif +#endif + +/* 16-/32-bit General Timers - TIM2, TIM3, TIM4, and TIM5 with DMA. + * For the STM32F10xx all timers are 16-bit. + * For the STM32F2xx and STM32F40xx, TIM2 and 5 are 32-bit + */ + +#if STM32_NGTIM > 0 +# define STM32_TIM2_CR1 (STM32_TIM2_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM2_CR2 (STM32_TIM2_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM2_SMCR (STM32_TIM2_BASE+STM32_GTIM_SMCR_OFFSET) +# define STM32_TIM2_DIER (STM32_TIM2_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM2_SR (STM32_TIM2_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM2_EGR (STM32_TIM2_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM2_CCMR1 (STM32_TIM2_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM2_CCMR2 (STM32_TIM2_BASE+STM32_GTIM_CCMR2_OFFSET) +# define STM32_TIM2_CCER (STM32_TIM2_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM2_CNT (STM32_TIM2_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM2_PSC (STM32_TIM2_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM2_ARR (STM32_TIM2_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM2_CCR1 (STM32_TIM2_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM2_CCR2 (STM32_TIM2_BASE+STM32_GTIM_CCR2_OFFSET) +# define STM32_TIM2_CCR3 (STM32_TIM2_BASE+STM32_GTIM_CCR3_OFFSET) +# define STM32_TIM2_CCR4 (STM32_TIM2_BASE+STM32_GTIM_CCR4_OFFSET) +# define STM32_TIM2_DCR (STM32_TIM2_BASE+STM32_GTIM_DCR_OFFSET) +# define STM32_TIM2_DMAR (STM32_TIM2_BASE+STM32_GTIM_DMAR_OFFSET) +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_TIM2_OR (STM32_TIM2_BASE+STM32_GTIM_OR_OFFSET) +# endif +#endif + +#if STM32_NGTIM > 1 +# define STM32_TIM3_CR1 (STM32_TIM3_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM3_CR2 (STM32_TIM3_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM3_SMCR (STM32_TIM3_BASE+STM32_GTIM_SMCR_OFFSET) +# define STM32_TIM3_DIER (STM32_TIM3_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM3_SR (STM32_TIM3_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM3_EGR (STM32_TIM3_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM3_CCMR1 (STM32_TIM3_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM3_CCMR2 (STM32_TIM3_BASE+STM32_GTIM_CCMR2_OFFSET) +# define STM32_TIM3_CCER (STM32_TIM3_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM3_CNT (STM32_TIM3_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM3_PSC (STM32_TIM3_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM3_ARR (STM32_TIM3_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM3_CCR1 (STM32_TIM3_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM3_CCR2 (STM32_TIM3_BASE+STM32_GTIM_CCR2_OFFSET) +# define STM32_TIM3_CCR3 (STM32_TIM3_BASE+STM32_GTIM_CCR3_OFFSET) +# define STM32_TIM3_CCR4 (STM32_TIM3_BASE+STM32_GTIM_CCR4_OFFSET) +# define STM32_TIM3_DCR (STM32_TIM3_BASE+STM32_GTIM_DCR_OFFSET) +# define STM32_TIM3_DMAR (STM32_TIM3_BASE+STM32_GTIM_DMAR_OFFSET) +#endif + +#if STM32_NGTIM > 2 +# define STM32_TIM4_CR1 (STM32_TIM4_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM4_CR2 (STM32_TIM4_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM4_SMCR (STM32_TIM4_BASE+STM32_GTIM_SMCR_OFFSET) +# define STM32_TIM4_DIER (STM32_TIM4_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM4_SR (STM32_TIM4_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM4_EGR (STM32_TIM4_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM4_CCMR1 (STM32_TIM4_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM4_CCMR2 (STM32_TIM4_BASE+STM32_GTIM_CCMR2_OFFSET) +# define STM32_TIM4_CCER (STM32_TIM4_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM4_CNT (STM32_TIM4_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM4_PSC (STM32_TIM4_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM4_ARR (STM32_TIM4_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM4_CCR1 (STM32_TIM4_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM4_CCR2 (STM32_TIM4_BASE+STM32_GTIM_CCR2_OFFSET) +# define STM32_TIM4_CCR3 (STM32_TIM4_BASE+STM32_GTIM_CCR3_OFFSET) +# define STM32_TIM4_CCR4 (STM32_TIM4_BASE+STM32_GTIM_CCR4_OFFSET) +# define STM32_TIM4_DCR (STM32_TIM4_BASE+STM32_GTIM_DCR_OFFSET) +# define STM32_TIM4_DMAR (STM32_TIM4_BASE+STM32_GTIM_DMAR_OFFSET) +#endif + +#if STM32_NGTIM > 3 +# define STM32_TIM5_CR1 (STM32_TIM5_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM5_CR2 (STM32_TIM5_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM5_SMCR (STM32_TIM5_BASE+STM32_GTIM_SMCR_OFFSET) +# define STM32_TIM5_DIER (STM32_TIM5_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM5_SR (STM32_TIM5_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM5_EGR (STM32_TIM5_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM5_CCMR1 (STM32_TIM5_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM5_CCMR2 (STM32_TIM5_BASE+STM32_GTIM_CCMR2_OFFSET) +# define STM32_TIM5_CCER (STM32_TIM5_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM5_CNT (STM32_TIM5_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM5_PSC (STM32_TIM5_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM5_ARR (STM32_TIM5_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM5_CCR1 (STM32_TIM5_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM5_CCR2 (STM32_TIM5_BASE+STM32_GTIM_CCR2_OFFSET) +# define STM32_TIM5_CCR3 (STM32_TIM5_BASE+STM32_GTIM_CCR3_OFFSET) +# define STM32_TIM5_CCR4 (STM32_TIM5_BASE+STM32_GTIM_CCR4_OFFSET) +# define STM32_TIM5_DCR (STM32_TIM5_BASE+STM32_GTIM_DCR_OFFSET) +# define STM32_TIM5_DMAR (STM32_TIM5_BASE+STM32_GTIM_DMAR_OFFSET) +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_TIM5_OR (STM32_TIM5_BASE+STM32_GTIM_OR_OFFSET) +# endif +#endif + +#define STM32_TIM15_CR1 (STM32_TIM15_BASE+STM32_GTIM_CR1_OFFSET) +#define STM32_TIM15_CR2 (STM32_TIM15_BASE+STM32_GTIM_CR2_OFFSET) +#define STM32_TIM15_SMCR (STM32_TIM15_BASE+STM32_GTIM_SMCR_OFFSET) +#define STM32_TIM15_DIER (STM32_TIM15_BASE+STM32_GTIM_DIER_OFFSET) +#define STM32_TIM15_SR (STM32_TIM15_BASE+STM32_GTIM_SR_OFFSET) +#define STM32_TIM15_EGR (STM32_TIM15_BASE+STM32_GTIM_EGR_OFFSET) +#define STM32_TIM15_CCMR1 (STM32_TIM15_BASE+STM32_GTIM_CCMR1_OFFSET) +#define STM32_TIM15_CCER (STM32_TIM15_BASE+STM32_GTIM_CCER_OFFSET) +#define STM32_TIM15_CNT (STM32_TIM15_BASE+STM32_GTIM_CNT_OFFSET) +#define STM32_TIM15_PSC (STM32_TIM15_BASE+STM32_GTIM_PSC_OFFSET) +#define STM32_TIM15_ARR (STM32_TIM15_BASE+STM32_GTIM_ARR_OFFSET) +#define STM32_TIM15_RCR (STM32_TIM15_BASE+STM32_GTIM_RCR_OFFSET) +#define STM32_TIM15_CCR1 (STM32_TIM15_BASE+STM32_GTIM_CCR1_OFFSET) +#define STM32_TIM15_CCR2 (STM32_TIM15_BASE+STM32_GTIM_CCR2_OFFSET) +#define STM32_TIM15_BDTR (STM32_TIM15_BASE+STM32_GTIM_BDTR_OFFSET) +#define STM32_TIM15_DCR (STM32_TIM15_BASE+STM32_GTIM_DCR_OFFSET) +#define STM32_TIM15_DMAR (STM32_TIM15_BASE+STM32_GTIM_DMAR_OFFSET) + +#define STM32_TIM16_CR1 (STM32_TIM16_BASE+STM32_GTIM_CR1_OFFSET) +#define STM32_TIM16_CR2 (STM32_TIM16_BASE+STM32_GTIM_CR2_OFFSET) +#define STM32_TIM16_DIER (STM32_TIM16_BASE+STM32_GTIM_DIER_OFFSET) +#define STM32_TIM16_SR (STM32_TIM16_BASE+STM32_GTIM_SR_OFFSET) +#define STM32_TIM16_EGR (STM32_TIM16_BASE+STM32_GTIM_EGR_OFFSET) +#define STM32_TIM16_CCMR1 (STM32_TIM16_BASE+STM32_GTIM_CCMR1_OFFSET) +#define STM32_TIM16_CCMR2 (STM32_TIM16_BASE+STM32_GTIM_CCMR2_OFFSET) +#define STM32_TIM16_CCER (STM32_TIM16_BASE+STM32_GTIM_CCER_OFFSET) +#define STM32_TIM16_CNT (STM32_TIM16_BASE+STM32_GTIM_CNT_OFFSET) +#define STM32_TIM16_PSC (STM32_TIM16_BASE+STM32_GTIM_PSC_OFFSET) +#define STM32_TIM16_ARR (STM32_TIM16_BASE+STM32_GTIM_ARR_OFFSET) +#define STM32_TIM16_RCR (STM32_TIM16_BASE+STM32_GTIM_RCR_OFFSET) +#define STM32_TIM16_CCR1 (STM32_TIM16_BASE+STM32_GTIM_CCR1_OFFSET) +#define STM32_TIM16_BDTR (STM32_TIM16_BASE+STM32_GTIM_BDTR_OFFSET) +#define STM32_TIM16_DCR (STM32_TIM16_BASE+STM32_GTIM_DCR_OFFSET) +#define STM32_TIM16_DMAR (STM32_TIM16_BASE+STM32_GTIM_DMAR_OFFSET) +#define STM32_TIM16_OR (STM32_TIM16_BASE+STM32_GTIM_OR_OFFSET) + +#define STM32_TIM17_CR1 (STM32_TIM17_BASE+STM32_GTIM_CR1_OFFSET) +#define STM32_TIM17_CR2 (STM32_TIM17_BASE+STM32_GTIM_CR2_OFFSET) +#define STM32_TIM17_DIER (STM32_TIM17_BASE+STM32_GTIM_DIER_OFFSET) +#define STM32_TIM17_SR (STM32_TIM17_BASE+STM32_GTIM_SR_OFFSET) +#define STM32_TIM17_EGR (STM32_TIM17_BASE+STM32_GTIM_EGR_OFFSET) +#define STM32_TIM17_CCMR1 (STM32_TIM17_BASE+STM32_GTIM_CCMR1_OFFSET) +#define STM32_TIM17_CCMR2 (STM32_TIM17_BASE+STM32_GTIM_CCMR2_OFFSET) +#define STM32_TIM17_CCER (STM32_TIM17_BASE+STM32_GTIM_CCER_OFFSET) +#define STM32_TIM17_CNT (STM32_TIM17_BASE+STM32_GTIM_CNT_OFFSET) +#define STM32_TIM17_PSC (STM32_TIM17_BASE+STM32_GTIM_PSC_OFFSET) +#define STM32_TIM17_ARR (STM32_TIM17_BASE+STM32_GTIM_ARR_OFFSET) +#define STM32_TIM17_RCR (STM32_TIM17_BASE+STM32_GTIM_RCR_OFFSET) +#define STM32_TIM17_CCR1 (STM32_TIM17_BASE+STM32_GTIM_CCR1_OFFSET) +#define STM32_TIM17_BDTR (STM32_TIM17_BASE+STM32_GTIM_BDTR_OFFSET) +#define STM32_TIM17_DCR (STM32_TIM17_BASE+STM32_GTIM_DCR_OFFSET) +#define STM32_TIM17_DMAR (STM32_TIM17_BASE+STM32_GTIM_DMAR_OFFSET) + +/* 16-bit General Timers - TIM9-14 without DMA. Note that (1) these timers + * support only a subset of the general timer registers are supported, and + * (2) TIM9 and TIM12 differ from the others. + */ + +#if STM32_NGTIMNDMA > 0 +# define STM32_TIM9_CR1 (STM32_TIM9_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM9_CR2 (STM32_TIM9_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM9_DIER (STM32_TIM9_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM9_SR (STM32_TIM9_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM9_EGR (STM32_TIM9_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM9_CCMR1 (STM32_TIM9_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM9_CCER (STM32_TIM9_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM9_CNT (STM32_TIM9_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM9_PSC (STM32_TIM9_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM9_ARR (STM32_TIM9_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM9_CCR1 (STM32_TIM9_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM9_CCR2 (STM32_TIM9_BASE+STM32_GTIM_CCR2_OFFSET) +#endif + +#if STM32_NGTIMNDMA > 1 +# define STM32_TIM10_CR1 (STM32_TIM10_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM10_DIER (STM32_TIM10_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM10_SR (STM32_TIM10_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM10_EGR (STM32_TIM10_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM10_CCMR1 (STM32_TIM10_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM10_CCER (STM32_TIM10_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM10_CNT (STM32_TIM10_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM10_PSC (STM32_TIM10_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM10_ARR (STM32_TIM10_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM10_CCR1 (STM32_TIM10_BASE+STM32_GTIM_CCR1_OFFSET) +#endif + +#if STM32_NGTIMNDMA > 2 +# define STM32_TIM11_CR1 (STM32_TIM11_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM11_DIER (STM32_TIM11_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM11_SR (STM32_TIM11_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM11_EGR (STM32_TIM11_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM11_CCMR1 (STM32_TIM11_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM11_CCER (STM32_TIM11_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM11_CNT (STM32_TIM11_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM11_PSC (STM32_TIM11_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM11_ARR (STM32_TIM11_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM11_CCR1 (STM32_TIM11_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM11_OR (STM32_TIM11_BASE+STM32_GTIM_OR_OFFSET) +#endif + +#if STM32_NGTIMNDMA > 3 +# define STM32_TIM12_CR1 (STM32_TIM12_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM12_CR2 (STM32_TIM9_BASE+STM32_GTIM_CR2_OFFSET) +# define STM32_TIM12_DIER (STM32_TIM12_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM12_SR (STM32_TIM12_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM12_EGR (STM32_TIM12_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM12_CCMR1 (STM32_TIM12_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM12_CCER (STM32_TIM12_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM12_CNT (STM32_TIM12_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM12_PSC (STM32_TIM12_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM12_ARR (STM32_TIM12_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM12_CCR1 (STM32_TIM12_BASE+STM32_GTIM_CCR1_OFFSET) +# define STM32_TIM12_CCR2 (STM32_TIM12_BASE+STM32_GTIM_CCR2_OFFSET) +#endif + +#if STM32_NGTIMNDMA > 4 +# define STM32_TIM13_CR1 (STM32_TIM13_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM13_DIER (STM32_TIM13_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM13_SR (STM32_TIM13_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM13_EGR (STM32_TIM13_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM13_CCMR1 (STM32_TIM13_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM13_CCER (STM32_TIM13_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM13_CNT (STM32_TIM13_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM13_PSC (STM32_TIM13_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM13_ARR (STM32_TIM13_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM13_CCR1 (STM32_TIM13_BASE+STM32_GTIM_CCR1_OFFSET) +#endif + +#if STM32_NGTIMNDMA > 5 +# define STM32_TIM14_CR1 (STM32_TIM14_BASE+STM32_GTIM_CR1_OFFSET) +# define STM32_TIM14_DIER (STM32_TIM14_BASE+STM32_GTIM_DIER_OFFSET) +# define STM32_TIM14_SR (STM32_TIM14_BASE+STM32_GTIM_SR_OFFSET) +# define STM32_TIM14_EGR (STM32_TIM14_BASE+STM32_GTIM_EGR_OFFSET) +# define STM32_TIM14_CCMR1 (STM32_TIM14_BASE+STM32_GTIM_CCMR1_OFFSET) +# define STM32_TIM14_CCER (STM32_TIM14_BASE+STM32_GTIM_CCER_OFFSET) +# define STM32_TIM14_CNT (STM32_TIM14_BASE+STM32_GTIM_CNT_OFFSET) +# define STM32_TIM14_PSC (STM32_TIM14_BASE+STM32_GTIM_PSC_OFFSET) +# define STM32_TIM14_ARR (STM32_TIM14_BASE+STM32_GTIM_ARR_OFFSET) +# define STM32_TIM14_CCR1 (STM32_TIM14_BASE+STM32_GTIM_CCR1_OFFSET) +#endif + +/* Basic Timers - TIM6 and TIM7 */ + +#if STM32_NBTIM > 0 +# define STM32_TIM6_CR1 (STM32_TIM6_BASE+STM32_BTIM_CR1_OFFSET) +# define STM32_TIM6_CR2 (STM32_TIM6_BASE+STM32_BTIM_CR2_OFFSET) +# define STM32_TIM6_DIER (STM32_TIM6_BASE+STM32_BTIM_DIER_OFFSET) +# define STM32_TIM6_SR (STM32_TIM6_BASE+STM32_BTIM_SR_OFFSET) +# define STM32_TIM6_EGR (STM32_TIM6_BASE+STM32_BTIM_EGR_OFFSET) +# define STM32_TIM6_CNT (STM32_TIM6_BASE+STM32_BTIM_CNT_OFFSET) +# define STM32_TIM6_PSC (STM32_TIM6_BASE+STM32_BTIM_PSC_OFFSET) +# define STM32_TIM6_ARR (STM32_TIM6_BASE+STM32_BTIM_ARR_OFFSET) +#endif + +#if STM32_NBTIM > 1 +# define STM32_TIM7_CR1 (STM32_TIM7_BASE+STM32_BTIM_CR1_OFFSET) +# define STM32_TIM7_CR2 (STM32_TIM7_BASE+STM32_BTIM_CR2_OFFSET) +# define STM32_TIM7_DIER (STM32_TIM7_BASE+STM32_BTIM_DIER_OFFSET) +# define STM32_TIM7_SR (STM32_TIM7_BASE+STM32_BTIM_SR_OFFSET) +# define STM32_TIM7_EGR (STM32_TIM7_BASE+STM32_BTIM_EGR_OFFSET) +# define STM32_TIM7_CNT (STM32_TIM7_BASE+STM32_BTIM_CNT_OFFSET) +# define STM32_TIM7_PSC (STM32_TIM7_BASE+STM32_BTIM_PSC_OFFSET) +# define STM32_TIM7_ARR (STM32_TIM7_BASE+STM32_BTIM_ARR_OFFSET) +#endif + +/* Register Bitfield Definitions ********************************************************************/ + +/* Control register 1 */ + +#define ATIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define ATIM_CR1_UDIS (1 << 1) /* Bit 1: Update disable */ +#define ATIM_CR1_URS (1 << 2) /* Bit 2: Update request source */ +#define ATIM_CR1_OPM (1 << 3) /* Bit 3: One pulse mode */ +#define ATIM_CR1_DIR (1 << 4) /* Bit 4: Direction */ +#define ATIM_CR1_CMS_SHIFT (5) /* Bits 6-5: Center-aligned mode selection */ +#define ATIM_CR1_CMS_MASK (3 << ATIM_CR1_CMS_SHIFT) +# define ATIM_CR1_EDGE (0 << ATIM_CR1_CMS_SHIFT) /* 00: Edge-aligned mode */ +# define ATIM_CR1_CENTER1 (1 << ATIM_CR1_CMS_SHIFT) /* 01: Center-aligned mode 1 */ +# define ATIM_CR1_CENTER2 (2 << ATIM_CR1_CMS_SHIFT) /* 10: Center-aligned mode 2 */ +# define ATIM_CR1_CENTER3 (3 << ATIM_CR1_CMS_SHIFT) /* 11: Center-aligned mode 3 */ +#define ATIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-reload preload enable */ +#define ATIM_CR1_CKD_SHIFT (8) /* Bits 9-8: Clock division */ +#define ATIM_CR1_CKD_MASK (3 << ATIM_CR1_CKD_SHIFT) +# define ATIM_CR1_TCKINT (0 << ATIM_CR1_CKD_SHIFT) /* 00: tDTS=tCK_INT */ +# define ATIM_CR1_2TCKINT (1 << ATIM_CR1_CKD_SHIFT) /* 01: tDTS=2*tCK_INT */ +# define ATIM_CR1_4TCKINT (2 << ATIM_CR1_CKD_SHIFT) /* 10: tDTS=4*tCK_INT */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ +#endif + +/* Control register 2 */ + +#define ATIM_CR2_CCPC (1 << 0) /* Bit 0: Capture/Compare Preloaded Control */ +#define ATIM_CR2_CCUS (1 << 2) /* Bit 2: Capture/Compare Control Update Selection */ +#define ATIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection */ +#define ATIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */ +#define ATIM_CR2_MMS_MASK (7 << ATIM_CR2_MMS_SHIFT) +# define ATIM_CR2_MMS_RESET (0 << ATIM_CR2_MMS_SHIFT) /* 000: Reset - TIMx_EGR UG bit is TRGO */ +# define ATIM_CR2_MMS_ENABLE (1 << ATIM_CR2_MMS_SHIFT) /* 001: Enable - CNT_EN is TRGO */ +# define ATIM_CR2_MMS_UPDATE (2 << ATIM_CR2_MMS_SHIFT) /* 010: Update event is TRGO */ +# define ATIM_CR2_MMS_COMPP (3 << ATIM_CR2_MMS_SHIFT) /* 010: Compare Pulse - CC1IF flag */ +# define ATIM_CR2_MMS_OC1REF (4 << ATIM_CR2_MMS_SHIFT) /* 100: Compare OC1REF is TRGO */ +# define ATIM_CR2_MMS_OC2REF (5 << ATIM_CR2_MMS_SHIFT) /* 101: Compare OC2REF is TRGO */ +# define ATIM_CR2_MMS_OC3REF (6 << ATIM_CR2_MMS_SHIFT) /* 110: Compare OC3REF is TRGO */ +# define ATIM_CR2_MMS_OC4REF (7 << ATIM_CR2_MMS_SHIFT) /* 111: Compare OC4REF is TRGO */ +#define ATIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection */ +#define ATIM_CR2_OIS1 (1 << 8) /* Bit 8: Output Idle state 1 (OC1 output) */ +#define ATIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) */ +#define ATIM_CR2_OIS2 (1 << 10) /* Bit 10: Output Idle state 2 (OC2 output) */ +#define ATIM_CR2_OIS2N (1 << 11) /* Bit 11: Output Idle state 2 (OC2N output) */ +#define ATIM_CR2_OIS3 (1 << 12) /* Bit 12: Output Idle state 3 (OC3 output) */ +#define ATIM_CR2_OIS3N (1 << 13) /* Bit 13: Output Idle state 3 (OC3N output) */ +#define ATIM_CR2_OIS4 (1 << 14) /* Bit 14: Output Idle state 4 (OC4 output) */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CR2_OIS5 (1 << 16) /* Bit 16: OOutput Idle state 5 (OC5 output) */ +# define ATIM_CR2_OIS6 (1 << 18) /* Bit 18: Output Idle state 6 (OC6 output) */ +# define ATIM_CR2_MMS2_SHIFT (20) /* Bits 20-23: Master Mode Selection 2 */ +# define ATIM_CR2_MMS2_MASK (15 << ATIM_CR2_MMS2_SHIFT) +# define ATIM_CR2_MMS2_RESET (0 << ATIM_CR2_MMS2_SHIFT) /* 0000: Reset - TIMx_EGR UG bit is TRG9 */ +# define ATIM_CR2_MMS2_ENABLE (1 << ATIM_CR2_MMS2_SHIFT) /* 0001: Enable - CNT_EN is TRGO2 */ +# define ATIM_CR2_MMS2_UPDATE (2 << ATIM_CR2_MMS2_SHIFT) /* 0010: Update event is TRGH0*/ +# define ATIM_CR2_MMS2_COMPP (3 << ATIM_CR2_MMS2_SHIFT) /* 0010: Compare Pulse - CC1IF flag */ +# define ATIM_CR2_MMS2_OC1REF (4 << ATIM_CR2_MMS2_SHIFT) /* 0100: Compare OC1REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC2REF (5 << ATIM_CR2_MMS2_SHIFT) /* 0101: Compare OC2REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC3REF (6 << ATIM_CR2_MMS2_SHIFT) /* 0110: Compare OC3REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC4REF (7 << ATIM_CR2_MMS2_SHIFT) /* 0111: Compare OC4REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC5REF (8 << ATIM_CR2_MMS2_SHIFT) /* 1000: Compare OC5REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC6REF (9 << ATIM_CR2_MMS2_SHIFT) /* 1001: Compare OC6REF is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC4 (10 << ATIM_CR2_MMS2_SHIFT) /* 1010: Compare pulse - OC4REF edge is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC6 (11 << ATIM_CR2_MMS2_SHIFT) /* 1011: Compare pulse - OC6REF edge is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC4R6R (12 << ATIM_CR2_MMS2_SHIFT) /* 1100: Compare pulse - OC4REF/OC6REF rising */ +# define ATIM_CR2_MMS2_CMPOC4R6F (13 << ATIM_CR2_MMS2_SHIFT) /* 1101: Compare pulse - OC4REF rising/OC6REF falling */ +# define ATIM_CR2_MMS2_CMPOC5R6R (14 << ATIM_CR2_MMS2_SHIFT) /* 1110: Compare pulse - OC5REF/OC6REF rising */ +# define ATIM_CR2_MMS2_CMPOC5R6F (15 << ATIM_CR2_MMS2_SHIFT) /* 1111: Compare pulse - OC5REF rising/OC6REF falling */ +#endif + +/* Slave mode control register */ + +#define ATIM_SMCR_SMS_SHIFT (0) /* Bits 0-2: Slave mode selection */ +#define ATIM_SMCR_SMS_MASK (7 << ATIM_SMCR_SMS_SHIFT) +# define ATIM_SMCR_DISAB (0 << ATIM_SMCR_SMS_SHIFT) /* 000: Slave mode disabled */ +# define ATIM_SMCR_ENCMD1 (1 << ATIM_SMCR_SMS_SHIFT) /* 001: Encoder mode 1 */ +# define ATIM_SMCR_ENCMD2 (2 << ATIM_SMCR_SMS_SHIFT) /* 010: Encoder mode 2 */ +# define ATIM_SMCR_ENCMD3 (3 << ATIM_SMCR_SMS_SHIFT) /* 011: Encoder mode 3 */ +# define ATIM_SMCR_RESET (4 << ATIM_SMCR_SMS_SHIFT) /* 100: Reset Mode */ +# define ATIM_SMCR_GATED (5 << ATIM_SMCR_SMS_SHIFT) /* 101: Gated Mode */ +# define ATIM_SMCR_TRIGGER (6 << ATIM_SMCR_SMS_SHIFT) /* 110: Trigger Mode */ +# define ATIM_SMCR_EXTCLK1 (7 << ATIM_SMCR_SMS_SHIFT) /* 111: External Clock Mode 1 */ +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_SMCR_OCCS (1 << 3) /* Bit 3: OCREF clear selection */ +#endif +#define ATIM_SMCR_TS_SHIFT (4) /* Bits 4-6: Trigger selection */ +#define ATIM_SMCR_TS_MASK (7 << ATIM_SMCR_TS_SHIFT) +# define ATIM_SMCR_ITR0 (0 << ATIM_SMCR_TS_SHIFT) /* 000: Internal trigger 0 (ITR0) */ +# define ATIM_SMCR_ITR1 (1 << ATIM_SMCR_TS_SHIFT) /* 001: Internal trigger 1 (ITR1) */ +# define ATIM_SMCR_ITR2 (2 << ATIM_SMCR_TS_SHIFT) /* 010: Internal trigger 2 (ITR2) */ +# define ATIM_SMCR_ITR3 (3 << ATIM_SMCR_TS_SHIFT) /* 011: Internal trigger 3 (ITR3) */ +# define ATIM_SMCR_T1FED (4 << ATIM_SMCR_TS_SHIFT) /* 100: TI1 Edge Detector (TI1F_ED) */ +# define ATIM_SMCR_TI1FP1 (5 << ATIM_SMCR_TS_SHIFT) /* 101: Filtered Timer Input 1 (TI1FP1) */ +# define ATIM_SMCR_T12FP2 (6 << ATIM_SMCR_TS_SHIFT) /* 110: Filtered Timer Input 2 (TI2FP2) */ +# define ATIM_SMCR_ETRF (7 << ATIM_SMCR_TS_SHIFT) /* 111: External Trigger input (ETRF) */ +#define ATIM_SMCR_MSM (1 << 7) /* Bit 7: Master/slave mode */ +#define ATIM_SMCR_ETF_SHIFT (8) /* Bits 8-11: External trigger filter */ +#define ATIM_SMCR_ETF_MASK (0x0f << ATIM_SMCR_ETF_SHIFT) +# define ATIM_SMCR_NOFILT (0 << ATIM_SMCR_ETF_SHIFT) /* 0000: No filter, sampling is done at fDTS */ +# define ATIM_SMCR_FCKINT2 (1 << ATIM_SMCR_ETF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_SMCR_FCKINT4 (2 << ATIM_SMCR_ETF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_SMCR_FCKINT8 (3 << ATIM_SMCR_ETF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_SMCR_FDTSd26 (4 << ATIM_SMCR_ETF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_SMCR_FDTSd28 (5 << ATIM_SMCR_ETF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_SMCR_FDTSd46 (6 << ATIM_SMCR_ETF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_SMCR_FDTSd48 (7 << ATIM_SMCR_ETF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_SMCR_FDTSd86 (8 << ATIM_SMCR_ETF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_SMCR_FDTSd88 (9 << ATIM_SMCR_ETF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_SMCR_FDTSd165 (10 << ATIM_SMCR_ETF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_SMCR_FDTSd166 (11 << ATIM_SMCR_ETF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_SMCR_FDTSd168 (12 << ATIM_SMCR_ETF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_SMCR_FDTSd325 (13 << ATIM_SMCR_ETF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_SMCR_FDTSd326 (14 << ATIM_SMCR_ETF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_SMCR_FDTSd328 (15 << ATIM_SMCR_ETF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define ATIM_SMCR_ETPS_SHIFT (12) /* Bits 12-13: External trigger prescaler */ +#define ATIM_SMCR_ETPS_MASK (3 << ATIM_SMCR_ETPS_SHIFT) +# define ATIM_SMCR_PSCOFF (0 << ATIM_SMCR_ETPS_SHIFT) /* 00: Prescaler OFF */ +# define ATIM_SMCR_ETRPd2 (1 << ATIM_SMCR_ETPS_SHIFT) /* 01: ETRP frequency divided by 2 */ +# define ATIM_SMCR_ETRPd4 (2 << ATIM_SMCR_ETPS_SHIFT) /* 10: ETRP frequency divided by 4 */ +# define ATIM_SMCR_ETRPd8 (3 << ATIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ +#define ATIM_SMCR_ECE (1 << 14) /* Bit 14: External clock enable */ +#define ATIM_SMCR_ETP (1 << 15) /* Bit 15: External trigger polarity */ +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ +#endif + +/* DMA/Interrupt enable register */ + +#define ATIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define ATIM_DIER_CC1IE (1 << 1) /* Bit 1: Capture/Compare 1 interrupt enable */ +#define ATIM_DIER_CC2IE (1 << 2) /* Bit 2: Capture/Compare 2 interrupt enable */ +#define ATIM_DIER_CC3IE (1 << 3) /* Bit 3: Capture/Compare 3 interrupt enable */ +#define ATIM_DIER_CC4IE (1 << 4) /* Bit 4: Capture/Compare 4 interrupt enable */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define ATIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable */ +#endif + +#define ATIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define ATIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable */ +#endif + +#define ATIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable */ +#define ATIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable */ +#define ATIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable */ +#define ATIM_DIER_CC3DE (1 << 11) /* Bit 11: Capture/Compare 3 DMA request enable */ +#define ATIM_DIER_CC4DE (1 << 12) /* Bit 12: Capture/Compare 4 DMA request enable */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define ATIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable */ +#endif + +#define ATIM_DIER_TDE (1 << 14) /* Bit 14: Trigger DMA request enable */ + +/* Status register */ + +#define ATIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt Flag */ +#define ATIM_SR_CC1IF (1 << 1) /* Bit 1: Capture/Compare 1 interrupt Flag */ +#define ATIM_SR_CC2IF (1 << 2) /* Bit 2: Capture/Compare 2 interrupt Flag */ +#define ATIM_SR_CC3IF (1 << 3) /* Bit 3: Capture/Compare 3 interrupt Flag */ +#define ATIM_SR_CC4IF (1 << 4) /* Bit 4: Capture/Compare 4 interrupt Flag */ +#define ATIM_SR_COMIF (1 << 5) /* Bit 5: COM interrupt Flag */ +#define ATIM_SR_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ +#elif defined(CONFIG_STM32_STM32F30XX) +# define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ +# define ATIM_SR_B2IF (1 << 8) /* Bit 8: Break 2 interrupt Flag */ +#endif + +#define ATIM_SR_CC1OF (1 << 9) /* Bit 9: Capture/Compare 1 Overcapture Flag */ +#define ATIM_SR_CC2OF (1 << 10) /* Bit 10: Capture/Compare 2 Overcapture Flag */ +#define ATIM_SR_CC3OF (1 << 11) /* Bit 11: Capture/Compare 3 Overcapture Flag */ +#define ATIM_SR_CC4OF (1 << 12) /* Bit 12: Capture/Compare 4 Overcapture Flag */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_SR_CC5IF (1 << 16) /* Bit 16: Compare 5 interrupt flag */ +# define ATIM_SR_CC6IF (1 << 17) /* Bit 17: Compare 6 interrupt flag */ +#endif + +/* Event generation register */ + +#define ATIM_EGR_UG (1 << 0) /* Bit 0: Update Generation */ +#define ATIM_EGR_CC1G (1 << 1) /* Bit 1: Capture/Compare 1 Generation */ +#define ATIM_EGR_CC2G (1 << 2) /* Bit 2: Capture/Compare 2 Generation */ +#define ATIM_EGR_CC3G (1 << 3) /* Bit 3: Capture/Compare 3 Generation */ +#define ATIM_EGR_CC4G (1 << 4) /* Bit 4: Capture/Compare 4 Generation */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define ATIM_EGR_COMG (1 << 5) /* Bit 5: Capture/Compare Control Update Generation */ +#endif + +#define ATIM_EGR_TG (1 << 6) /* Bit 6: Trigger Generation */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ +#elif defined(CONFIG_STM32_STM32F30XX) +# define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ +# define ATIM_EGR_B2G (1 << 8) /* Bit 8: Break 2 Generation */ +#endif + +/* Capture/compare mode register 1 -- Output compare mode */ + +#define ATIM_CCMR1_CC1S_SHIFT (0) /* Bits 1-0: Capture/Compare 1 Selection */ +#define ATIM_CCMR1_CC1S_MASK (3 << ATIM_CCMR1_CC1S_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_OC1FE (1 << 2) /* Bit 2: Output Compare 1 Fast enable */ +#define ATIM_CCMR1_OC1PE (1 << 3) /* Bit 3: Output Compare 1 Preload enable */ +#define ATIM_CCMR1_OC1M_SHIFT (4) /* Bits 6-4: Output Compare 1 Mode */ +#define ATIM_CCMR1_OC1M_MASK (7 << ATIM_CCMR1_OC1M_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_OC1CE (1 << 7) /* Bit 7: Output Compare 1Clear Enable */ +#define ATIM_CCMR1_CC2S_SHIFT (8) /* Bits 8-9: Capture/Compare 2 Selection */ +#define ATIM_CCMR1_CC2S_MASK (3 << ATIM_CCMR1_CC2S_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_OC2FE (1 << 10) /* Bit 10: Output Compare 2 Fast enable */ +#define ATIM_CCMR1_OC2PE (1 << 11) /* Bit 11: Output Compare 2 Preload enable */ +#define ATIM_CCMR1_OC2M_SHIFT (12) /* Bits 14-12: Output Compare 2 Mode */ +#define ATIM_CCMR1_OC2M_MASK (7 << ATIM_CCMR1_OC2M_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ +# define ATIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ +#endif + +/* Common CCMR (unshifted) Capture/Compare Selection bit-field definitions */ + +#define ATIM_CCMR_CCS_CCOUT (0) /* 00: CCx channel output */ +#define ATIM_CCMR_CCS_CCIN1 (1) /* 01: CCx channel input, ICx is TIx */ +#define ATIM_CCMR_CCS_CCIN2 (2) /* 10: CCx channel input, ICx is TIy */ +#define ATIM_CCMR_CCS_CCINTRC (3) /* 11: CCx channel input, ICx is TRC */ + +/* Common CCMR (unshifted) Compare Mode bit field definitions */ + +#define ATIM_CCMR_MODE_FRZN (0) /* 000: Frozen */ +#define ATIM_CCMR_MODE_CHACT (1) /* 001: Channel x active on match */ +#define ATIM_CCMR_MODE_CHINACT (2) /* 010: Channel x inactive on match */ +#define ATIM_CCMR_MODE_OCREFTOG (3) /* 011: OCxREF toggle ATIM_CNT=ATIM_CCRx */ +#define ATIM_CCMR_MODE_OCREFLO (4) /* 100: OCxREF forced low */ +#define ATIM_CCMR_MODE_OCREFHI (5) /* 101: OCxREF forced high */ +#define ATIM_CCMR_MODE_PWM1 (6) /* 110: PWM mode 1 */ +#define ATIM_CCMR_MODE_PWM2 (7) /* 111: PWM mode 2 */ +#define ATIM_CCMR_MODE_COMBINED1 (12) /* 1100: Combined PWM mode 1 */ +#define ATIM_CCMR_MODE_COMBINED2 (13) /* 1101: Combined PWM mode 2 */ +#define ATIM_CCMR_MODE_ASYMMETRIC1 (14) /* 1110: Asymmetric PWM mode 1 */ +#define ATIM_CCMR_MODE_ASYMMETRIC2 (15) /* 1111: Asymmetric PWM mode 2 */ + +/* Capture/compare mode register 1 -- Input capture mode */ + + /* Bits 1-0:(same as output compare mode) */ +#define ATIM_CCMR1_IC1PSC_SHIFT (2) /* Bits 3-2: Input Capture 1 Prescaler */ +#define ATIM_CCMR1_IC1PSC_MASK (3 << ATIM_CCMR1_IC1PSC_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_IC1F_SHIFT (4) /* Bits 7-4: Input Capture 1 Filter */ +#define ATIM_CCMR1_IC1F_MASK (0x0f << ATIM_CCMR1_IC1F_SHIFT) + /* (See common (unshifted) bit field definitions below) */ + /* Bits 9:8 (same as output compare mode) */ +#define ATIM_CCMR1_IC2PSC_SHIFT (10) /* Bits 11:10: Input Capture 2 Prescaler */ +#define ATIM_CCMR1_IC2PSC_MASK (3 << ATIM_CCMR1_IC2PSC_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +#define ATIM_CCMR1_IC2F_SHIFT (12) /* Bits 15-12: Input Capture 2 Filter */ +#define ATIM_CCMR1_IC2F_MASK (0x0f << ATIM_CCMR1_IC2F_SHIFT) + /* (See common (unshifted) bit field definitions below) */ + +/* Common CCMR (unshifted) Input Capture Prescaler bit-field definitions */ + +#define ATIM_CCMR_ICPSC_NOPSC (0) /* 00: no prescaler, capture each edge */ +#define ATIM_CCMR_ICPSC_EVENTS2 (1) /* 01: capture once every 2 events */ +#define ATIM_CCMR_ICPSC_EVENTS4 (2) /* 10: capture once every 4 events */ +#define ATIM_CCMR_ICPSC_EVENTS8 (3) /* 11: capture once every 8 events */ + +/* Common CCMR (unshifted) Input Capture Filter bit-field definitions */ + +#define ATIM_CCMR_ICF_NOFILT (0) /* 0000: No filter, sampling at fDTS */ +#define ATIM_CCMR_ICF_FCKINT2 (1) /* 0001: fSAMPLING=fCK_INT, N=2 */ +#define ATIM_CCMR_ICF_FCKINT4 (2) /* 0010: fSAMPLING=fCK_INT, N=4 */ +#define ATIM_CCMR_ICF_FCKINT8 (3) /* 0011: fSAMPLING=fCK_INT, N=8 */ +#define ATIM_CCMR_ICF_FDTSd26 (4) /* 0100: fSAMPLING=fDTS/2, N=6 */ +#define ATIM_CCMR_ICF_FDTSd28 (5) /* 0101: fSAMPLING=fDTS/2, N=8 */ +#define ATIM_CCMR_ICF_FDTSd46 (6) /* 0110: fSAMPLING=fDTS/4, N=6 */ +#define ATIM_CCMR_ICF_FDTSd48 (7) /* 0111: fSAMPLING=fDTS/4, N=8 */ +#define ATIM_CCMR_ICF_FDTSd86 (8) /* 1000: fSAMPLING=fDTS/8, N=6 */ +#define ATIM_CCMR_ICF_FDTSd88 (9) /* 1001: fSAMPLING=fDTS/8, N=8 */ +#define ATIM_CCMR_ICF_FDTSd165 (10) /* 1010: fSAMPLING=fDTS/16, N=5 */ +#define ATIM_CCMR_ICF_FDTSd166 (11) /* 1011: fSAMPLING=fDTS/16, N=6 */ +#define ATIM_CCMR_ICF_FDTSd168 (12) /* 1100: fSAMPLING=fDTS/16, N=8 */ +#define ATIM_CCMR_ICF_FDTSd325 (13) /* 1101: fSAMPLING=fDTS/32, N=5 */ +#define ATIM_CCMR_ICF_FDTSd326 (14) /* 1110: fSAMPLING=fDTS/32, N=6 */ +#define ATIM_CCMR_ICF_FDTSd328 (15) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* Capture/compare mode register 2 - Output Compare mode */ + +#define ATIM_CCMR2_CC3S_SHIFT (0) /* Bits 1-0: Capture/Compare 3 Selection */ +#define ATIM_CCMR2_CC3S_MASK (3 << ATIM_CCMR2_CC3S_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_OC3FE (1 << 2) /* Bit 2: Output Compare 3 Fast enable */ +#define ATIM_CCMR2_OC3PE (1 << 3) /* Bit 3: Output Compare 3 Preload enable */ +#define ATIM_CCMR2_OC3M_SHIFT (4) /* Bits 6-4: Output Compare 3 Mode */ +#define ATIM_CCMR2_OC3M_MASK (7 << ATIM_CCMR2_OC3M_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_OC3CE (1 << 7) /* Bit 7: Output Compare 3 Clear Enable */ +#define ATIM_CCMR2_CC4S_SHIFT (8) /* Bits 9-8: Capture/Compare 4 Selection */ +#define ATIM_CCMR2_CC4S_MASK (3 << ATIM_CCMR2_CC4S_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_OC4FE (1 << 10) /* Bit 10: Output Compare 4 Fast enable */ +#define ATIM_CCMR2_OC4PE (1 << 11) /* Bit 11: Output Compare 4 Preload enable */ +#define ATIM_CCMR2_OC4M_SHIFT (12) /* Bits 14-12: Output Compare 4 Mode */ +#define ATIM_CCMR2_OC4M_MASK (7 << ATIM_CCMR2_OC4M_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_OC4CE (1 << 15) /* Bit 15: Output Compare 4 Clear Enable */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CCMR2_OC3M (1 << 16) /* Bit 16: Output Compare 3 mode - bit 3 */ +# define ATIM_CCMR2_OC4M (1 << 24) /* Bit 24: Output Compare 4 mode - bit 3 */ +#endif + +/* Capture/compare mode register 2 - Input Capture Mode */ + + /* Bits 1-0:(same as output compare mode) */ +#define ATIM_CCMR2_IC3PSC_SHIFT (2) /* Bits 3-2: Input Capture 3 Prescaler */ +#define ATIM_CCMR1_IC3PSC_MASK (3 << ATIM_CCMR2_IC3PSC_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_IC3F_SHIFT (4) /* Bits 7-4: Input Capture 3 Filter */ +#define ATIM_CCMR2_IC3F_MASK (0x0f << ATIM_CCMR2_IC3F_SHIFT) + /* (See common (unshifted) bit field definitions above) */ + /* Bits 9:8 (same as output compare mode) */ +#define ATIM_CCMR2_IC4PSC_SHIFT (10) /* Bits 11:10: Input Capture 4 Prescaler */ +#define ATIM_CCMR2_IC4PSC_MASK (3 << ATIM_CCMR2_IC4PSC_SHIFT) + /* (See common (unshifted) bit field definitions above) */ +#define ATIM_CCMR2_IC4F_SHIFT (12) /* Bits 15-12: Input Capture 4 Filter */ +#define ATIM_CCMR2_IC4F_MASK (0x0f << ATIM_CCMR2_IC4F_SHIFT) + /* (See common (unshifted) bit field definitions above) */ + +/* Capture/compare mode register 3 -- Output compare mode */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CCMR3_OC5FE (1 << 2) /* Bit 2: Output Compare 5 Fast enable */ +# define ATIM_CCMR3_OC5PE (1 << 3) /* Bit 3: Output Compare 5 Preload enable */ +# define ATIM_CCMR3_OC5M_SHIFT (4) /* Bits 6-4: Output Compare 5 Mode */ +# define ATIM_CCMR3_OC5M_MASK (7 << ATIM_CCMR3_OC5M_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +# define ATIM_CCMR3_OC5CE (1 << 7) /* Bit 7: Output Compare 5 Clear Enable */ +# define ATIM_CCMR3_OC6FE (1 << 10) /* Bit 10: Output Compare 6 Fast enable */ +# define ATIM_CCMR3_OC6PE (1 << 11) /* Bit 11: Output Compare 6 Preload enable */ +# define ATIM_CCMR3_OC6M_SHIFT (12) /* Bits 14-12: Output Compare 7 Mode */ +# define ATIM_CCMR3_OC6M_MASK (7 << ATIM_CCMR3_OC6M_SHIFT) + /* (See common (unshifted) bit field definitions below) */ +# define ATIM_CCMR3_OC6CE (1 << 15) /* Bit 15: Output Compare 7 Clear Enable */ + +# define ATIM_CCMR3_OC5M (1 << 16) /* Bit 16: Output Compare 5 mode - bit 3 */ +# define ATIM_CCMR3_OC6M (1 << 24) /* Bit 24: Output Compare 6 mode - bit 3 */ +#endif + +/* Capture/compare enable register */ + +#define ATIM_CCER_CC1E (1 << 0) /* Bit 0: Capture/Compare 1 output enable */ +#define ATIM_CCER_CC1P (1 << 1) /* Bit 1: Capture/Compare 1 output Polarity */ +#define ATIM_CCER_CC1NE (1 << 2) /* Bit 2: Capture/Compare 1 Complementary output enable */ +#define ATIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 Complementary output polarity */ +#define ATIM_CCER_CC2E (1 << 4) /* Bit 4: Capture/Compare 2 output enable */ +#define ATIM_CCER_CC2P (1 << 5) /* Bit 5: Capture/Compare 2 output Polarity */ +#define ATIM_CCER_CC2NE (1 << 6) /* Bit 6: Capture/Compare 2 Complementary output enable */ +#define ATIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 Complementary output polarity */ +#define ATIM_CCER_CC3E (1 << 8) /* Bit 8: Capture/Compare 3 output enable */ +#define ATIM_CCER_CC3P (1 << 9) /* Bit 9: Capture/Compare 3 output Polarity */ +#define ATIM_CCER_CC3NE (1 << 10) /* Bit 10: Capture/Compare 3 Complementary output enable */ +#define ATIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 Complementary output polarity */ +#define ATIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable */ +#define ATIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +# define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ +#elif defined(CONFIG_STM32_STM32F30XX) +# define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ +# define ATIM_CCER_CC5E (1 << 16) /* Bit 16: Capture/Compare 5 output enable */ +# define ATIM_CCER_CC5P (1 << 17) /* Bit 17: Capture/Compare 5 output Polarity */ +# define ATIM_CCER_CC6E (1 << 20) /* Bit 20: Capture/Compare 6 output enable */ +# define ATIM_CCER_CC6P (1 << 21) /* Bit 21: Capture/Compare 6 output Polarity */ +#endif + +/* 16-bit counter register */ + +#define ATIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ +#define ATIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CCER_UIFCPY (1 << 31) /* Bit 31: UIF copy */ +#endif + +/* Repetition counter register */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_RCR_REP_SHIFT (0) /* Bits 0-15: Repetition Counter Value */ +# define ATIM_RCR_REP_MASK (0xffff << ATIM_RCR_REP_SHIFT) + +# define ATIM_RCR_REP_MAX 32768 /* REVISIT */ +#else +# define ATIM_RCR_REP_SHIFT (0) /* Bits 0-7: Repetition Counter Value */ +# define ATIM_RCR_REP_MASK (0xff << ATIM_RCR_REP_SHIFT) + +# define ATIM_RCR_REP_MAX 128 +#endif + +/* Capture/compare registers (CCR) */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_CCR5_GC5C1 (1 << 29) /* Bit 29: Group Channel 5 and Channel 1 */ +# define ATIM_CCR5_GC5C2 (1 << 30) /* Bit 30: Group Channel 5 and Channel 2 */ +# define ATIM_CCR5_GC5C3 (1 << 31) /* Bit 31: Group Channel 5 and Channel 3 */ +#endif + +#define ATIM_CCR_MASK (0xffff) + +/* Break and dead-time register */ + +#define ATIM_BDTR_DTG_SHIFT (0) /* Bits 7:0 [7:0]: Dead-Time Generator set-up */ +#define ATIM_BDTR_DTG_MASK (0xff << ATIM_BDTR_DTG_SHIFT) +#define ATIM_BDTR_LOCK_SHIFT (8) /* Bits 9:8 [1:0]: Lock Configuration */ +#define ATIM_BDTR_LOCK_MASK (3 << ATIM_BDTR_LOCK_SHIFT) +# define ATIM_BDTR_LOCKOFF (0 << ATIM_BDTR_LOCK_SHIFT) /* 00: LOCK OFF - No bit is write protected */ +# define ATIM_BDTR_LOCK1 (1 << ATIM_BDTR_LOCK_SHIFT) /* 01: LOCK Level 1 protection */ +# define ATIM_BDTR_LOCK2 (2 << ATIM_BDTR_LOCK_SHIFT) /* 10: LOCK Level 2 protection */ +# define ATIM_BDTR_LOCK3 (3 << ATIM_BDTR_LOCK_SHIFT) /* 11: LOCK Level 3 protection */ */ +#define ATIM_BDTR_OSSI (1 << 10) /* Bit 10: Off-State Selection for Idle mode */ +#define ATIM_BDTR_OSSR (1 << 11) /* Bit 11: Off-State Selection for Run mode */ +#define ATIM_BDTR_BKE (1 << 12) /* Bit 12: Break enable */ +#define ATIM_BDTR_BKP (1 << 13) /* Bit 13: Break Polarity */ +#define ATIM_BDTR_AOE (1 << 14) /* Bit 14: Automatic Output enable */ +#define ATIM_BDTR_MOE (1 << 15) /* Bit 15: Main Output enable */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ATIM_BDTR_BKF_SHIFT (16) /* Bits 16-19: Break filter */ +# define ATIM_BDTR_BKF_MASK (15 << ATIM_BDTR_BKF_SHIFT) +# define ATIM_BDTR_BKF_NOFILT (0 << ATIM_BDTR_BKF_SHIFT) /* 0000: No filter, BRK acts asynchronously */ +# define ATIM_BDTR_BKF_FCKINT2 (1 << ATIM_BDTR_BKF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_BDTR_BKF_FCKINT4 (2 << ATIM_BDTR_BKF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_BDTR_BKF_FCKINT8 (3 << ATIM_BDTR_BKF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_BDTR_BKF_FDTSd26 (4 << ATIM_BDTR_BKF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_BDTR_BKF_FDTSd28 (5 << ATIM_BDTR_BKF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_BDTR_BKF_FDTSd36 (6 << ATIM_BDTR_BKF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_BDTR_BKF_FDTSd38 (7 << ATIM_BDTR_BKF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_BDTR_BKF_FDTSd86 (8 << ATIM_BDTR_BKF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_BDTR_BKF_FDTSd88 (9 << ATIM_BDTR_BKF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_BDTR_BKF_FDTSd165 (10 << ATIM_BDTR_BKF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_BDTR_BKF_FDTSd166 (11 << ATIM_BDTR_BKF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_BDTR_BKF_FDTSd168 (12 << ATIM_BDTR_BKF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_BDTR_BKF_FDTSd325 (13 << ATIM_BDTR_BKF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_BDTR_BKF_FDTSd326 (14 << ATIM_BDTR_BKF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_BDTR_BKF_FDTSd328 (15 << ATIM_BDTR_BKF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +# define ATIM_BDTR_BK2F_SHIFT (20) /* Bits 20-23: Break 2 filter */ +# define ATIM_BDTR_BK2F_MASK (15 << ATIM_BDTR_BK2F_SHIFT) +# define ATIM_BDTR_BK2F_NOFILT (0 << ATIM_BDTR_BK2F_SHIFT) /* 0000: No filter, BRK 2 acts asynchronously */ +# define ATIM_BDTR_BK2F_FCKINT2 (1 << ATIM_BDTR_BK2F_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_BDTR_BK2F_FCKINT4 (2 << ATIM_BDTR_BK2F_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_BDTR_BK2F_FCKINT8 (3 << ATIM_BDTR_BK2F_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd26 (4 << ATIM_BDTR_BK2F_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd28 (5 << ATIM_BDTR_BK2F_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd36 (6 << ATIM_BDTR_BK2F_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd38 (7 << ATIM_BDTR_BK2F_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd86 (8 << ATIM_BDTR_BK2F_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd88 (9 << ATIM_BDTR_BK2F_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd165 (10 << ATIM_BDTR_BK2F_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_BDTR_BK2F_FDTSd166 (11 << ATIM_BDTR_BK2F_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd168 (12 << ATIM_BDTR_BK2F_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd325 (13 << ATIM_BDTR_BK2F_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_BDTR_BK2F_FDTSd326 (14 << ATIM_BDTR_BK2F_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd328 (15 << ATIM_BDTR_BK2F_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +# define ATIM_BDTR_BK2E (1 << 24) /* Bit 24: Break 2 enable */ +# define ATIM_BDTR_BK2P (1 << 1525 /* Bit 25:Break 2 polarity */ +#endif + +/* DMA control register */ + +#define ATIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */ +#define ATIM_DCR_DBA_MASK (0x1f << ATIM_DCR_DBA_SHIFT) +#define ATIM_DCR_DBL_SHIFT (8) /* Bits 12-8: DMA Burst Length */ +#define ATIM_DCR_DBL_MASK (0x1f << ATIM_DCR_DBL_SHIFT) +# define ATIM_DCR_DBL(n) (((n)-1) << ATIM_DCR_DBL_SHIFT) /* n transfers, n = 1..18 */ + +/* Control register 1 (TIM2-5 and TIM9-14) */ + +#define GTIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define GTIM_CR1_UDIS (1 << 1) /* Bit 1: Update Disable */ +#define GTIM_CR1_URS (1 << 2) /* Bit 2: Update Request Source */ +#define GTIM_CR1_OPM (1 << 3) /* Bit 3: One Pulse Mode (TIM2-5, 9, and 12 only) */ +#define GTIM_CR1_DIR (1 << 4) /* Bit 4: Direction (TIM2-5 only) */ +#define GTIM_CR1_CMS_SHIFT (5) /* Bits 6-5: Center-aligned Mode Selection (TIM2-5 only) */ +#define GTIM_CR1_CMS_MASK (3 << GTIM_CR1_CMS_SHIFT) +# define GTIM_CR1_EDGE (0 << GTIM_CR1_CMS_SHIFT) /* 00: Edge-aligned mode. */ +# define GTIM_CR1_CENTER1 (1 << GTIM_CR1_CMS_SHIFT) /* 01: Center-aligned mode 1 */ +# define GTIM_CR1_CENTER2 (2 << GTIM_CR1_CMS_SHIFT) /* 10: Center-aligned mode 2 */ +# define GTIM_CR1_CENTER3 (3 << GTIM_CR1_CMS_SHIFT) /* 11: Center-aligned mode 3 */ +#define GTIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-Reload Preload enable */ +#define GTIM_CR1_CKD_SHIFT (8) /* Bits 9-8: Clock Division */ +#define GTIM_CR1_CKD_MASK (3 << GTIM_CR1_CKD_SHIFT) +# define GTIM_CR1_TCKINT (0 << GTIM_CR1_CKD_SHIFT) /* 00: tDTS = tCK_INT */ +# define GTIM_CR1_2TCKINT (1 << GTIM_CR1_CKD_SHIFT) /* 01: tDTS = 2 x tCK_INT */ +# define GTIM_CR1_4TCKINT (2 << GTIM_CR1_CKD_SHIFT) /* 10: tDTS = 4 x tCK_INT */ + +#ifdef CONFIG_STM32_STM32F30XX +# define GTIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ +#endif + +/* Control register 2 (TIM2-5, TIM9-12, and TIM15-17 only) */ + +#define GTIM_CR2_CCPC (1 << 0) /* Bit 0: Capture/compare preloaded control (TIM15-17 only) */ +#define GTIM_CR2_CCUS (1 << 2) /* Bit 2: Capture/compare control update selection (TIM15-17 only) */ +#define GTIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection (TIM2-5,1,&16 only) */ +#define GTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection (not TIM16) */ +#define GTIM_CR2_MMS_MASK (7 << GTIM_CR2_MMS_SHIFT) +# define GTIM_CR2_MMS_RESET (0 << GTIM_CR2_MMS_SHIFT) /* 000: Reset */ +# define GTIM_CR2_MMS_ENABLE (1 << GTIM_CR2_MMS_SHIFT) /* 001: Enable */ +# define GTIM_CR2_MMS_UPDATE (2 << GTIM_CR2_MMS_SHIFT) /* 010: Update */ +# define GTIM_CR2_MMS_COMPP (3 << GTIM_CR2_MMS_SHIFT) /* 011: Compare Pulse */ +# define GTIM_CR2_MMS_OC1REF (4 << GTIM_CR2_MMS_SHIFT) /* 100: Compare - OC1REF signal is used as trigger output (TRGO) */ +# define GTIM_CR2_MMS_OC2REF (5 << GTIM_CR2_MMS_SHIFT) /* 101: Compare - OC2REF signal is used as trigger output (TRGO) */ +# define GTIM_CR2_MMS_OC3REF (6 << GTIM_CR2_MMS_SHIFT) /* 110: Compare - OC3REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */ +# define GTIM_CR2_MMS_OC4REF (7 << GTIM_CR2_MMS_SHIFT) /* 111: Compare - OC4REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */ +#define GTIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection (not TIM16) */ +#define GTIM_CR2_OIS1 (1 << 8) /* Bit 8: COutput Idle state 1 (OC1 output) (TIM15-17 only) */ +#define GTIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) (TIM15-17 only) */ +#define GTIM_CR2_OIS2 (1 << 10) /* Bit 10: Output idle state 2 (OC2 output) (TIM15 only) */ + +/* Slave mode control register (TIM2-5 and TIM15 only) */ + +#define GTIM_SMCR_SMS_SHIFT (0) /* Bits 2-0: Slave Mode Selection */ +#define GTIM_SMCR_SMS_MASK (7 << GTIM_SMCR_SMS_SHIFT) +# define GTIM_SMCR_DISAB (0 << GTIM_SMCR_SMS_SHIFT) /* 000: Slave mode disabled */ +# define GTIM_SMCR_ENCMD1 (1 << GTIM_SMCR_SMS_SHIFT) /* 001: Encoder mode 1 */ +# define GTIM_SMCR_ENCMD2 (2 << GTIM_SMCR_SMS_SHIFT) /* 010: Encoder mode 2 */ +# define GTIM_SMCR_ENCMD3 (3 << GTIM_SMCR_SMS_SHIFT) /* 011: Encoder mode 3 */ +# define GTIM_SMCR_RESET (4 << GTIM_SMCR_SMS_SHIFT) /* 100: Reset Mode */ +# define GTIM_SMCR_GATED (5 << GTIM_SMCR_SMS_SHIFT) /* 101: Gated Mode */ +# define GTIM_SMCR_TRIGGER (6 << GTIM_SMCR_SMS_SHIFT) /* 110: Trigger Mode */ +# define GTIM_SMCR_EXTCLK1 (7 << GTIM_SMCR_SMS_SHIFT) /* 111: External Clock Mode 1 */ +#define GTIM_SMCR_TS_SHIFT (4) /* Bits 6-4: Trigger Selection */ +#define GTIM_SMCR_TS_MASK (7 << GTIM_SMCR_TS_SHIFT) +# define GTIM_SMCR_ITR0 (0 << GTIM_SMCR_TS_SHIFT) /* 000: Internal Trigger 0 (ITR0). TIM1 */ +# define GTIM_SMCR_ITR1 (1 << GTIM_SMCR_TS_SHIFT) /* 001: Internal Trigger 1 (ITR1). TIM2 */ +# define GTIM_SMCR_ITR2 (2 << GTIM_SMCR_TS_SHIFT) /* 010: Internal Trigger 2 (ITR2). TIM3 */ +# define GTIM_SMCR_ITR3 (3 << GTIM_SMCR_TS_SHIFT) /* 011: Internal Trigger 3 (ITR3). TIM4 */ +# define GTIM_SMCR_TI1FED (4 << GTIM_SMCR_TS_SHIFT) /* 100: TI1 Edge Detector (TI1F_ED) */ +# define GTIM_SMCR_TI1FP1 (5 << GTIM_SMCR_TS_SHIFT) /* 101: Filtered Timer Input 1 (TI1FP1) */ +# define GTIM_SMCR_TI2FP2 (6 << GTIM_SMCR_TS_SHIFT) /* 110: Filtered Timer Input 2 (TI2FP2) */ +# define GTIM_SMCR_ETRF (7 << GTIM_SMCR_TS_SHIFT) /* 111: External Trigger input (ETRF) */ +#define GTIM_SMCR_MSM (1 << 7) /* Bit 7: Master/Slave mode */ +#define GTIM_SMCR_ETF_SHIFT (8) /* Bits 11-8: External Trigger Filter (not TIM15) */ +#define GTIM_SMCR_ETF_MASK (0x0f << GTIM_SMCR_ETF_SHIFT) +# define GTIM_SMCR_NOFILT (0 << GTIM_SMCR_ETF_SHIFT) /* 0000: No filter, sampling is done at fDTS */ +# define GTIM_SMCR_FCKINT2 (1 << GTIM_SMCR_ETF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define GTIM_SMCR_FCKINT4 (2 << GTIM_SMCR_ETF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define GTIM_SMCR_FCKINT8 (3 << GTIM_SMCR_ETF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define GTIM_SMCR_FDTSd26 (4 << GTIM_SMCR_ETF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define GTIM_SMCR_FDTSd28 (5 << GTIM_SMCR_ETF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define GTIM_SMCR_FDTSd36 (6 << GTIM_SMCR_ETF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define GTIM_SMCR_FDTSd38 (7 << GTIM_SMCR_ETF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define GTIM_SMCR_FDTSd86 (8 << GTIM_SMCR_ETF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define GTIM_SMCR_FDTSd88 (9 << GTIM_SMCR_ETF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define GTIM_SMCR_FDTSd165 (10 << GTIM_SMCR_ETF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define GTIM_SMCR_FDTSd166 (11 << GTIM_SMCR_ETF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define GTIM_SMCR_FDTSd168 (12 << GTIM_SMCR_ETF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define GTIM_SMCR_FDTSd325 (13 << GTIM_SMCR_ETF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define GTIM_SMCR_FDTSd326 (14 << GTIM_SMCR_ETF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define GTIM_SMCR_FDTSd328 (15 << GTIM_SMCR_ETF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define GTIM_SMCR_ETPS_SHIFT (12) /* Bits 13-12: External Trigger Prescaler (not TIM15) */ +#define GTIM_SMCR_ETPS_MASK (3 << GTIM_SMCR_ETPS_SHIFT) +# define GTIM_SMCR_PSCOFF (0 << GTIM_SMCR_ETPS_SHIFT) /* 00: Prescaler OFF */ +# define GTIM_SMCR_ETRPd2 (1 << GTIM_SMCR_ETPS_SHIFT) /* 01: ETRP frequency divided by 2 */ +# define GTIM_SMCR_ETRPd4 (2 << GTIM_SMCR_ETPS_SHIFT) /* 10: ETRP frequency divided by 4 */ +# define GTIM_SMCR_ETRPd8 (3 << GTIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ +#define GTIM_SMCR_ECE (1 << 14) /* Bit 14: External Clock enable */ +#define GTIM_SMCR_ETP (1 << 15) /* Bit 15: External Trigger Polarity */ +#ifdef CONFIG_STM32_STM32F30XX +# define GTIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ +#endif + +/* DMA/Interrupt enable register (TIM2-5 and TIM9-14) */ + +#define GTIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define GTIM_DIER_CC1IE (1 << 1) /* Bit 1: Capture/Compare 1 interrupt enable */ +#define GTIM_DIER_CC2IE (1 << 2) /* Bit 2: Capture/Compare 2 interrupt enable (TIM2-5,9,12,&15 only) */ +#define GTIM_DIER_CC3IE (1 << 3) /* Bit 3: Capture/Compare 3 interrupt enable (TIM2-5 only) */ +#define GTIM_DIER_CC4IE (1 << 4) /* Bit 4: Capture/Compare 4 interrupt enable (TIM2-5 only) */ +#define GTIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable (TIM15-17 only) */ +#define GTIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable (TIM2-5,9,&12 only) */ +#define GTIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable (TIM15-17 only) */ +#define GTIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable (TIM2-5&15-17 only) */ +#define GTIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable (TIM2-5&15-17 only) */ +#define GTIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable (TIM2-5&15 only) */ +#define GTIM_DIER_CC3DE (1 << 11) /* Bit 11: Capture/Compare 3 DMA request enable (TIM2-5 only) */ +#define GTIM_DIER_CC4DE (1 << 12) /* Bit 12: Capture/Compare 4 DMA request enable (TIM2-5 only) */ +#define GTIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable (TIM15-17 only) */ +#define GTIM_DIER_TDE (1 << 14) /* Bit 14: Trigger DMA request enable (TIM2-5&15-17 only) */ + +/* Status register */ + +#define GTIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt flag */ +#define GTIM_SR_CC1IF (1 << 1) /* Bit 1: Capture/compare 1 interrupt flag */ +#define GTIM_SR_CC2IF (1 << 2) /* Bit 2: Capture/Compare 2 interrupt flag (TIM2-5,9,12,&15 only) */ +#define GTIM_SR_CC3IF (1 << 3) /* Bit 3: Capture/Compare 3 interrupt flag (TIM2-5 only) */ +#define GTIM_SR_CC4IF (1 << 4) /* Bit 4: Capture/Compare 4 interrupt flag (TIM2-5 only) */ +#define GTIM_SR_COMIF (1 << 5) /* Bit 5: COM interrupt flag (TIM15-17 only) */ +#define GTIM_SR_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag (TIM2-5,9,12&15-17 only) */ +#define GTIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt flag (TIM15-17 only) */ +#define GTIM_SR_CC1OF (1 << 9) /* Bit 9: Capture/Compare 1 Overcapture flag */ +#define GTIM_SR_CC2OF (1 << 10) /* Bit 10: Capture/Compare 2 Overcapture flag (TIM2-5,9,12&15 only) */ +#define GTIM_SR_CC3OF (1 << 11) /* Bit 11: Capture/Compare 3 Overcapture flag (TIM2-5 only) */ +#define GTIM_SR_CC4OF (1 << 12) /* Bit 12: Capture/Compare 4 Overcapture flag (TIM2-5 only) */ + +/* Event generation register (TIM2-5 and TIM9-14) */ + +#define GTIM_EGR_UG (1 << 0) /* Bit 0: Update generation */ +#define GTIM_EGR_CC1G (1 << 1) /* Bit 1: Capture/compare 1 generation */ +#define GTIM_EGR_CC2G (1 << 2) /* Bit 2: Capture/compare 2 generation (TIM2-5,9,12,&15 only) */ +#define GTIM_EGR_CC3G (1 << 3) /* Bit 3: Capture/compare 3 generation (TIM2-5 only) */ +#define GTIM_EGR_CC4G (1 << 4) /* Bit 4: Capture/compare 4 generation (TIM2-5 only) */ +#define GTIM_EGR_COMIG (1 << 5) /* Bit 5: Capture/Compare control update generation (TIM15-17 only) */ +#define GTIM_EGR_TG (1 << 6) /* Bit 6: Trigger generation (TIM2-5,9,12&16-17 only) */ +#define GTIM_EGR_BG (1 << 7) /* Bit 7: Break generation (TIM15-17 only) */ + +/* Capture/compare mode register 1 - Output compare mode (TIM2-5 and TIM9-14) */ + +#define GTIM_CCMR1_CC1S_SHIFT (0) /* Bits 1-0: Capture/Compare 1 Selection */ +#define GTIM_CCMR1_CC1S_MASK (3 << GTIM_CCMR1_CC1S_SHIFT) + /* (See common CCMR Capture/Compare Selection definitions below) */ +#define GTIM_CCMR1_OC1FE (1 << 2) /* Bit 2: Output Compare 1 Fast enable */ +#define GTIM_CCMR1_OC1PE (1 << 3) /* Bit 3: Output Compare 1 Preload enable */ +#define GTIM_CCMR1_OC1M_SHIFT (4) /* Bits 6-4: Output Compare 1 Mode */ +#define GTIM_CCMR1_OC1M_MASK (7 << GTIM_CCMR1_OC1M_SHIFT) + /* (See common CCMR Output Compare Mode definitions below) */ +#define GTIM_CCMR1_OC1CE (1 << 7) /* Bit 7: Output Compare 1Clear Enable */ +#define GTIM_CCMR1_CC2S_SHIFT (8) /* Bits 9-8: Capture/Compare 2 Selection */ +#define GTIM_CCMR1_CC2S_MASK (3 << GTIM_CCMR1_CC2S_SHIFT) + /* (See common CCMR Capture/Compare Selection definitions below) */ +#define GTIM_CCMR1_OC2FE (1 << 10) /* Bit 10: Output Compare 2 Fast enable */ +#define GTIM_CCMR1_OC2PE (1 << 11) /* Bit 11: Output Compare 2 Preload enable */ +#define GTIM_CCMR1_OC2M_SHIFT (12) /* Bits 14-12: Output Compare 2 Mode */ +#define GTIM_CCMR1_OC2M_MASK (7 << GTIM_CCMR1_OC2M_SHIFT) + /* (See common CCMR Output Compare Mode definitions below) */ +#define GTIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ + +#ifdef CONFIG_STM32_STM32F30XX +# define GTIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ +# define GTIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ +#endif + +/* Common CCMR (unshifted) Capture/Compare Selection bit-field definitions */ + +#define GTIM_CCMR_CCS_CCOUT (0) /* 00: CCx channel output */ +#define GTIM_CCMR_CCS_CCIN1 (1) /* 01: CCx channel input, ICx is TIx */ +#define GTIM_CCMR_CCS_CCIN2 (2) /* 10: CCx channel input, ICx is TIy */ +#define GTIM_CCMR_CCS_CCINTRC (3) /* 11: CCx channel input, ICx is TRC */ + +/* Common CCMR (unshifted) Compare Mode bit field definitions */ + +#define GTIM_CCMR_MODE_FRZN (0) /* 000: Frozen */ +#define GTIM_CCMR_MODE_CHACT (1) /* 001: Channel x active on match */ +#define GTIM_CCMR_MODE_CHINACT (2) /* 010: Channel x inactive on match */ +#define GTIM_CCMR_MODE_OCREFTOG (3) /* 011: OCxREF toggle ATIM_CNT=ATIM_CCRx */ +#define GTIM_CCMR_MODE_OCREFLO (4) /* 100: OCxREF forced low */ +#define GTIM_CCMR_MODE_OCREFHI (5) /* 101: OCxREF forced high */ +#define GTIM_CCMR_MODE_PWM1 (6) /* 110: PWM mode 1 */ +#define GTIM_CCMR_MODE_PWM2 (7) /* 111: PWM mode 2 */ + +/* Capture/compare mode register 1 - Input capture mode (TIM2-5 and TIM9-14) */ + + /* Bits 1-0 (Same as Output Compare Mode) */ +#define GTIM_CCMR1_IC1PSC_SHIFT (2) /* Bits 3-2: Input Capture 1 Prescaler */ +#define GTIM_CCMR1_IC1PSC_MASK (3 << GTIM_CCMR1_IC1PSC_SHIFT) + /* (See common CCMR Input Capture Prescaler definitions below) */ +#define GTIM_CCMR1_IC1F_SHIFT (4) /* Bits 7-4: Input Capture 1 Filter */ +#define GTIM_CCMR1_IC1F_MASK (0x0f << GTIM_CCMR1_IC1F_SHIFT) + /* (See common CCMR Input Capture Filter definitions below) */ + /* Bits 9-8: (Same as Output Compare Mode) */ +#define GTIM_CCMR1_IC2PSC_SHIFT (10) /* Bits 11-10: Input Capture 2 Prescaler */ +#define GTIM_CCMR1_IC2PSC_MASK (3 << GTIM_CCMR1_IC2PSC_SHIFT) + /* (See common CCMR Input Capture Prescaler definitions below) */ +#define GTIM_CCMR1_IC2F_SHIFT (12) /* Bits 15-12: Input Capture 2 Filter */ +#define GTIM_CCMR1_IC2F_MASK (0x0f << GTIM_CCMR1_IC2F_SHIFT) + /* (See common CCMR Input Capture Filter definitions below) */ + +/* Common CCMR (unshifted) Input Capture Prescaler bit-field definitions */ + +#define GTIM_CCMR_ICPSC_NOPSC (0) /* 00: no prescaler, capture each edge */ +#define GTIM_CCMR_ICPSC_EVENTS2 (1) /* 01: capture once every 2 events */ +#define GTIM_CCMR_ICPSC_EVENTS4 (2) /* 10: capture once every 4 events */ +#define GTIM_CCMR_ICPSC_EVENTS8 (3) /* 11: capture once every 8 events */ + +/* Common CCMR (unshifted) Input Capture Filter bit-field definitions */ + +#define GTIM_CCMR_ICF_NOFILT (0) /* 0000: No filter, sampling at fDTS */ +#define GTIM_CCMR_ICF_FCKINT2 (1) /* 0001: fSAMPLING=fCK_INT, N=2 */ +#define GTIM_CCMR_ICF_FCKINT4 (2) /* 0010: fSAMPLING=fCK_INT, N=4 */ +#define GTIM_CCMR_ICF_FCKINT8 (3) /* 0011: fSAMPLING=fCK_INT, N=8 */ +#define GTIM_CCMR_ICF_FDTSd26 (4) /* 0100: fSAMPLING=fDTS/2, N=6 */ +#define GTIM_CCMR_ICF_FDTSd28 (5) /* 0101: fSAMPLING=fDTS/2, N=8 */ +#define GTIM_CCMR_ICF_FDTSd46 (6) /* 0110: fSAMPLING=fDTS/4, N=6 */ +#define GTIM_CCMR_ICF_FDTSd48 (7) /* 0111: fSAMPLING=fDTS/4, N=8 */ +#define GTIM_CCMR_ICF_FDTSd86 (8) /* 1000: fSAMPLING=fDTS/8, N=6 */ +#define GTIM_CCMR_ICF_FDTSd88 (9) /* 1001: fSAMPLING=fDTS/8, N=8 */ +#define GTIM_CCMR_ICF_FDTSd165 (10) /* 1010: fSAMPLING=fDTS/16, N=5 */ +#define GTIM_CCMR_ICF_FDTSd166 (11) /* 1011: fSAMPLING=fDTS/16, N=6 */ +#define GTIM_CCMR_ICF_FDTSd168 (12) /* 1100: fSAMPLING=fDTS/16, N=8 */ +#define GTIM_CCMR_ICF_FDTSd325 (13) /* 1101: fSAMPLING=fDTS/32, N=5 */ +#define GTIM_CCMR_ICF_FDTSd326 (14) /* 1110: fSAMPLING=fDTS/32, N=6 */ +#define GTIM_CCMR_ICF_FDTSd328 (15) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* Capture/compare mode register 2 - Output Compare mode (TIM2-5 only) */ + +#define GTIM_CCMR2_CC3S_SHIFT (0) /* Bits 1-0: Capture/Compare 3 Selection */ +#define GTIM_CCMR2_CC3S_MASK (3 << GTIM_CCMR2_CC3S_SHIFT) + /* (See common CCMR Capture/Compare Selection definitions above) */ +#define GTIM_CCMR2_OC3FE (1 << 2) /* Bit 2: Output Compare 3 Fast enable */ +#define GTIM_CCMR2_OC3PE (1 << 3) /* Bit 3: Output Compare 3 Preload enable */ +#define GTIM_CCMR2_OC3M_SHIFT (4) /* Bits 6-4: Output Compare 3 Mode */ +#define GTIM_CCMR2_OC3M_MASK (7 << GTIM_CCMR2_OC3M_SHIFT) + /* (See common CCMR Output Compare Mode definitions above) */ +#define GTIM_CCMR2_OC3CE (1 << 7) /* Bit 7: Output Compare 3 Clear Enable */ +#define GTIM_CCMR2_CC4S_SHIFT (8) /* Bits 9-8: Capture/Compare 4 Selection */ +#define GTIM_CCMR2_CC4S_MASK (3 << GTIM_CCMR2_CC4S_SHIFT) + /* (See common CCMR Capture/Compare Selection definitions above) */ +#define GTIM_CCMR2_OC4FE (1 << 10) /* Bit 10: Output Compare 4 Fast enable */ +#define GTIM_CCMR2_OC4PE (1 << 11) /* Bit 11: Output Compare 4 Preload enable */ +#define GTIM_CCMR2_OC4M_SHIFT (12) /* Bits 14-12: Output Compare 4 Mode */ +#define GTIM_CCMR2_OC4M_MASK (7 << GTIM_CCMR2_OC4M_SHIFT) + /* (See common CCMR Output Compare Mode definitions above) */ +#define GTIM_CCMR2_OC4CE (1 << 15) /* Bit 15: Output Compare 4 Clear Enable */ + +/* Capture/compare mode register 2 - Input capture mode (TIM2-5 only) */ + + /* Bits 1-0 (Same as Output Compare Mode) */ +#define GTIM_CCMR2_IC3PSC_SHIFT (2) /* Bits 3-2: Input Capture 3 Prescaler */ +#define GTIM_CCMR2_IC3PSC_MASK (3 << GTIM_CCMR2_IC3PSC_SHIFT) + /* (See common CCMR Input Capture Prescaler definitions below) */ +#define GTIM_CCMR2_IC3F_SHIFT (4) /* Bits 7-4: Input Capture 3 Filter */ +#define GTIM_CCMR2_IC3F_MASK (0x0f << GTIM_CCMR2_IC3F_SHIFT) + /* (See common CCMR Input Capture Filter definitions below) */ + /* Bits 9-8: (Same as Output Compare Mode) */ +#define GTIM_CCMR2_IC4PSC_SHIFT (10) /* Bits 11-10: Input Capture 4 Prescaler */ +#define GTIM_CCMR2_IC4PSC_MASK (3 << GTIM_CCMR2_IC4PSC_SHIFT) + /* (See common CCMR Input Capture Prescaler definitions below) */ +#define GTIM_CCMR2_IC4F_SHIFT (12) /* Bits 15-12: Input Capture 4 Filter */ +#define GTIM_CCMR2_IC4F_MASK (0x0f << GTIM_CCMR2_IC4F_SHIFT) + /* (See common CCMR Input Capture Filter definitions below) */ + +/* Capture/compare enable register (TIM1 and TIM8, TIM2-5 and TIM9-14) */ + +#define GTIM_CCER_CC1E (1 << 0) /* Bit 0: Capture/Compare 1 output enable */ +#define GTIM_CCER_CC1P (1 << 1) /* Bit 1: Capture/Compare 1 output polarity */ +#define GTIM_CCER_CC1NE (1 << 2) /* Bit 2: Capture/Compare 1 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 output Polarity (F2,F3,F4 and TIM15-17) */ +#define GTIM_CCER_CC2E (1 << 4) /* Bit 4: Capture/Compare 2 output enable (TIM2-5,9&12 only) */ +#define GTIM_CCER_CC2P (1 << 5) /* Bit 5: Capture/Compare 2 output polarity (TIM2-5,9&12 only) */ +#define GTIM_CCER_CC2NE (1 << 6) /* Bit 6: Capture/Compare 2 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 output Polarity (F2,F3,F4 and TIM2-5,9,12&15 only) */ +#define GTIM_CCER_CC3E (1 << 8) /* Bit 8: Capture/Compare 3 output enable (TIM2-5 only) */ +#define GTIM_CCER_CC3P (1 << 9) /* Bit 9: Capture/Compare 3 output Polarity (TIM2-5 only) */ +#define GTIM_CCER_CC3NE (1 << 10) /* Bit 10: Capture/Compare 3 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 output Polarity (F2,F4 and TIM2-5 only) */ +#define GTIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable (TIM2-5 only) */ +#define GTIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity (TIM2-5 only) */ +#define GTIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity */ + +/* 16-bit counter register */ + +#define GTIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ +#define GTIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) + +#ifdef CONFIG_STM32_STM32F30XX +# define GTIM_CCER_UIFCPY (1 << 31) /* Bit 31: UIF copy */ +#endif + +/* Repitition counter (TIM15-17 only) */ + +#define GTIM_RCR_REP_SHIFT (0) /* Bits 0-7: Repetition Counter Value */ +#define GTIM_RCR_REP_MASK (0xff << GTIM_RCR_REP_SHIFT) + +#define GTIM_RCR_REP_MAX 128 + +/* Break and dead-time register (TIM15-17 only */ + +#define GTIM_BDTR_DTG_SHIFT (0) /* Bits 7:0 [7:0]: Dead-Time Generator set-up */ +#define GTIM_BDTR_DTG_MASK (0xff << GTIM_BDTR_DTG_SHIFT) +#define GTIM_BDTR_LOCK_SHIFT (8) /* Bits 9:8 [1:0]: Lock Configuration */ +#define GTIM_BDTR_LOCK_MASK (3 << GTIM_BDTR_LOCK_SHIFT) +# define GTIM_BDTR_LOCKOFF (0 << GTIM_BDTR_LOCK_SHIFT) /* 00: LOCK OFF - No bit is write protected */ +# define GTIM_BDTR_LOCK1 (1 << GTIM_BDTR_LOCK_SHIFT) /* 01: LOCK Level 1 protection */ +# define GTIM_BDTR_LOCK2 (2 << GTIM_BDTR_LOCK_SHIFT) /* 10: LOCK Level 2 protection */ +# define GTIM_BDTR_LOCK3 (3 << GTIM_BDTR_LOCK_SHIFT) /* 11: LOCK Level 3 protection */ */ +#define GTIM_BDTR_OSSI (1 << 10) /* Bit 10: Off-State Selection for Idle mode */ +#define GTIM_BDTR_OSSR (1 << 11) /* Bit 11: Off-State Selection for Run mode */ +#define GTIM_BDTR_BKE (1 << 12) /* Bit 12: Break enable */ +#define GTIM_BDTR_BKP (1 << 13) /* Bit 13: Break Polarity */ +#define GTIM_BDTR_AOE (1 << 14) /* Bit 14: Automatic Output enable */ +#define GTIM_BDTR_MOE (1 << 15) /* Bit 15: Main Output enable */ +#define GTIM_BDTR_BKF_SHIFT (16) /* Bits 16-19: Break filter */ +#define GTIM_BDTR_BKF_MASK (15 << GTIM_BDTR_BKF_SHIFT) +# define GTIM_BDTR_BKF_NOFILT (0 << GTIM_BDTR_BKF_SHIFT) /* 0000: No filter, BRK acts asynchronously */ +# define GTIM_BDTR_BKF_FCKINT2 (1 << GTIM_BDTR_BKF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define GTIM_BDTR_BKF_FCKINT4 (2 << GTIM_BDTR_BKF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define GTIM_BDTR_BKF_FCKINT8 (3 << GTIM_BDTR_BKF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define GTIM_BDTR_BKF_FDTSd26 (4 << GTIM_BDTR_BKF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define GTIM_BDTR_BKF_FDTSd28 (5 << GTIM_BDTR_BKF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define GTIM_BDTR_BKF_FDTSd36 (6 << GTIM_BDTR_BKF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define GTIM_BDTR_BKF_FDTSd38 (7 << GTIM_BDTR_BKF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define GTIM_BDTR_BKF_FDTSd86 (8 << GTIM_BDTR_BKF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define GTIM_BDTR_BKF_FDTSd88 (9 << GTIM_BDTR_BKF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define GTIM_BDTR_BKF_FDTSd165 (10 << GTIM_BDTR_BKF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define GTIM_BDTR_BKF_FDTSd166 (11 << GTIM_BDTR_BKF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define GTIM_BDTR_BKF_FDTSd168 (12 << GTIM_BDTR_BKF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define GTIM_BDTR_BKF_FDTSd325 (13 << GTIM_BDTR_BKF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define GTIM_BDTR_BKF_FDTSd326 (14 << GTIM_BDTR_BKF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define GTIM_BDTR_BKF_FDTSd328 (15 << GTIM_BDTR_BKF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* DMA control register */ + +#define GTIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */ +#define GTIM_DCR_DBA_MASK (0x1f << GTIM_DCR_DBA_SHIFT) +#define GTIM_DCR_DBL_SHIFT (8) /* Bits 12-8: DMA Burst Length */ +#define GTIM_DCR_DBL_MASK (0x1f << GTIM_DCR_DBL_SHIFT) + +/* Timer 2/5 option register */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define TIM2_OR_ITR1_RMP_SHIFT (10) /* Bits 10-11: Internal trigger 1 remap */ +# define TIM2_OR_ITR1_RMP_MASK (3 << TIM2_OR_ITR1_RMP_SHIFT) +# define TIM2_OR_ITR1_TIM8_TRGOUT (0 << TIM2_OR_ITR1_RMP_SHIFT) /* 00: TIM2_ITR1 input connected to TIM8_TRGOUT */ +# define TIM2_OR_ITR1_PTP (1 << TIM2_OR_ITR1_RMP_SHIFT) /* 01: TIM2_ITR1 input connected to PTP trigger output */ +# define TIM2_OR_ITR1_OTGFSSOF (2 << TIM2_OR_ITR1_RMP_SHIFT) /* 10: TIM2_ITR1 input connected to OTG FS SOF */ +# define TIM2_OR_ITR1_OTGHSSOF (3 << TIM2_OR_ITR1_RMP_SHIFT) /* 11: TIM2_ITR1 input connected to OTG HS SOF */ + +# define TIM5_OR_TI4_RMP_SHIFT (6) /* Bits 6-7: Internal trigger 4 remap */ +# define TIM5_OR_TI4_RMP_MASK (3 << TIM5_OR_TI4_RMP_SHIFT) +# define TIM5_OR_TI4_GPIO (0 << TIM5_OR_TI4_RMP_SHIFT) /* 00: TIM5_CH4 input connected to GPIO */ +# define TIM5_OR_TI4_LSI (1 << TIM5_OR_TI4_RMP_SHIFT) /* 01: TIM5_CH4 input connected to LSI internal clock */ +# define TIM5_OR_TI4_LSE (2 << TIM5_OR_TI4_RMP_SHIFT) /* 10: TIM5_CH4 input connected to LSE internal clock */ +# define TIM5_OR_TI4_RTC (3 << TIM5_OR_TI4_RMP_SHIFT) /* 11: TIM5_CH4 input connected to RTC output event */ + +# define TIM11_OR_TI1_RMP_SHIFT (6) /* Bits 6-7: Internal trigger 4 remap */ +# define TIM11_OR_TI1_RMP_MASK (3 << TIM11_OR_TI1_RMP_SHIFT) +# define TIM11_OR_TI1_GPIO (0 << TIM11_OR_TI1_RMP_SHIFT) /* 00-11: TIM11_CH1 input connected to GPIO */ +# define TIM11_OR_TI1_HSERTC (3 << TIM11_OR_TI1_RMP_SHIFT) /* 11: TIM11_CH1 input connected to HSE_RTC clock */ +#endif + +/* Timer 16 Option Register */ + +#ifdef CONFIG_STM32_STM32F30XX +# define TIM16_OR_RMP_SHIFT (0) /* Bits 0-1: Timer 16 input 1 connection */ +# define TIM16_OR_RMP_MASK (3 << TIM16_OR_RMP_SHIFT) +# define TIM16_OR_RMP_GPRIO (3 << TIM16_OR_RMP_SHIFT) /* TIM16 TI1 is connected to GPIO */ +# define TIM16_OR_RMP_RTC (3 << TIM16_OR_RMP_SHIFT) /* TIM16 TI1 is connected to RTC_clock */ +# define TIM16_OR_RMP_HSEd32 (3 << TIM16_OR_RMP_SHIFT) /* TIM16 TI1 is connected to HSE/32 */ +# define TIM16_OR_RMP_MCO (3 << TIM16_OR_RMP_SHIFT) /* TIM16 TI1 is connected to MCO */ +#endif + +/* Control register 1 */ + +#define BTIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define BTIM_CR1_UDIS (1 << 1) /* Bit 1: Update Disable */ +#define BTIM_CR1_URS (1 << 2) /* Bit 2: Update Request Source */ +#define BTIM_CR1_OPM (1 << 3) /* Bit 3: One Pulse Mode */ +#define BTIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-Reload Preload enable */ + +/* Control register 2 */ + +#define BTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */ +#define BTIM_CR2_MMS_MASK (7 << BTIM_CR2_MMS_SHIFT) +# define BTIM_CR2_RESET (0 << BTIM_CR2_MMS_SHIFT) /* 000: Reset */ +# define BTIM_CR2_ENAB (1 << BTIM_CR2_MMS_SHIFT) /* 001: Enable */ +# define BTIM_CR2_UPDT (2 << BTIM_CR2_MMS_SHIFT) /* 010: Update */ + +/* DMA/Interrupt enable register */ + +#define BTIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define BTIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable */ + +/* Status register */ + +#define BTIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt flag */ + +/* Event generation register */ + +#define BTIM_EGR_UG (1 << 0) /* Bit 0: Update generation */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_TIM_H */ diff --git a/arch/arm/src/stm32/chip/stm32_usbdev.h b/arch/arm/src/stm32/chip/stm32_usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..f4013485cad8a8c3581c2b3f010c4cb11da1bcb5 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_usbdev.h @@ -0,0 +1,237 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_usbdev.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_USBDEV_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_USBDEV_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) \ + || defined(CONFIG_STM32_STM32F37XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +/* Endpoint Registers */ + +#define STM32_USB_EPR_OFFSET(n) ((n) << 2) /* USB endpoint n register (16-bits) */ +#define STM32_USB_EP0R_OFFSET 0x0000 /* USB endpoint 0 register (16-bits) */ +#define STM32_USB_EP1R_OFFSET 0x0004 /* USB endpoint 1 register (16-bits) */ +#define STM32_USB_EP2R_OFFSET 0x0008 /* USB endpoint 2 register (16-bits) */ +#define STM32_USB_EP3R_OFFSET 0x000c /* USB endpoint 3 register (16-bits) */ +#define STM32_USB_EP4R_OFFSET 0x0010 /* USB endpoint 4 register (16-bits) */ +#define STM32_USB_EP5R_OFFSET 0x0014 /* USB endpoint 5 register (16-bits) */ +#define STM32_USB_EP6R_OFFSET 0x0018 /* USB endpoint 6 register (16-bits) */ +#define STM32_USB_EP7R_OFFSET 0x001c /* USB endpoint 7 register (16-bits) */ + +/* Common Registers */ + +#define STM32_USB_CNTR_OFFSET 0x0040 /* USB control register (16-bits) */ +#define STM32_USB_ISTR_OFFSET 0x0044 /* USB interrupt status register (16-bits) */ +#define STM32_USB_FNR_OFFSET 0x0048 /* USB frame number register (16-bits) */ +#define STM32_USB_DADDR_OFFSET 0x004c /* USB device address (16-bits) */ +#define STM32_USB_BTABLE_OFFSET 0x0050 /* Buffer table address (16-bits) */ + +/* Buffer Descriptor Table (Relatative to BTABLE address) */ + +#define STM32_USB_ADDR_TX_WOFFSET (0) /* Transmission buffer address n (16-bits) */ +#define STM32_USB_COUNT_TX_WOFFSET (2) /* Transmission byte count n (16-bits) */ +#define STM32_USB_ADDR_RX_WOFFSET (4) /* Reception buffer address n (16-bits) */ +#define STM32_USB_COUNT_RX_WOFFSET (6) /* Reception byte count n (16-bits) */ + +#define STM32_USB_BTABLE_RADDR(ep,o) ((((uint32_t)getreg16(STM32_USB_BTABLE) + ((ep) << 3)) + (o)) << 1) +#define STM32_USB_ADDR_TX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_ADDR_TX_WOFFSET) +#define STM32_USB_COUNT_TX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_COUNT_TX_WOFFSET) +#define STM32_USB_ADDR_RX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_ADDR_RX_WOFFSET) +#define STM32_USB_COUNT_RX_OFFSET(ep) STM32_USB_BTABLE_RADDR(ep,STM32_USB_COUNT_RX_WOFFSET) + +/* Register Addresses ***************************************************************/ + +/* Endpoint Registers */ + +#define STM32_USB_EPR(n) (STM32_USB_BASE+STM32_USB_EPR_OFFSET(n)) +#define STM32_USB_EP0R (STM32_USB_BASE+STM32_USB_EP0R_OFFSET) +#define STM32_USB_EP1R (STM32_USB_BASE+STM32_USB_EP1R_OFFSET) +#define STM32_USB_EP2R (STM32_USB_BASE+STM32_USB_EP2R_OFFSET) +#define STM32_USB_EP3R (STM32_USB_BASE+STM32_USB_EP3R_OFFSET) +#define STM32_USB_EP4R (STM32_USB_BASE+STM32_USB_EP4R_OFFSET) +#define STM32_USB_EP5R (STM32_USB_BASE+STM32_USB_EP5R_OFFSET) +#define STM32_USB_EP6R (STM32_USB_BASE+STM32_USB_EP6R_OFFSET) +#define STM32_USB_EP7R (STM32_USB_BASE+STM32_USB_EP7R_OFFSET) + +/* Common Registers */ + +#define STM32_USB_CNTR (STM32_USB_BASE+STM32_USB_CNTR_OFFSET) +#define STM32_USB_ISTR (STM32_USB_BASE+STM32_USB_ISTR_OFFSET) +#define STM32_USB_FNR (STM32_USB_BASE+STM32_USB_FNR_OFFSET) +#define STM32_USB_DADDR (STM32_USB_BASE+STM32_USB_DADDR_OFFSET) +#define STM32_USB_BTABLE (STM32_USB_BASE+STM32_USB_BTABLE_OFFSET) + +/* Buffer Descriptor Table (Relatative to BTABLE address) */ + +#define STM32_USB_BTABLE_ADDR(ep,o) (STM32_USBRAM_BASE+STM32_USB_BTABLE_RADDR(ep,o)) +#define STM32_USB_ADDR_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_TX_WOFFSET) +#define STM32_USB_COUNT_TX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_TX_WOFFSET) +#define STM32_USB_ADDR_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_ADDR_RX_WOFFSET) +#define STM32_USB_COUNT_RX(ep) STM32_USB_BTABLE_ADDR(ep,STM32_USB_COUNT_RX_WOFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* USB endpoint register */ + +#define USB_EPR_EA_SHIFT (0) /* Bits 3:0 [3:0]: Endpoint Address */ +#define USB_EPR_EA_MASK (0X0f << USB_EPR_EA_SHIFT) +#define USB_EPR_STATTX_SHIFT (4) /* Bits 5-4: Status bits, for transmission transfers */ +#define USB_EPR_STATTX_MASK (3 << USB_EPR_STATTX_SHIFT) +# define USB_EPR_STATTX_DIS (0 << USB_EPR_STATTX_SHIFT) /* EndPoint TX DISabled */ +# define USB_EPR_STATTX_STALL (1 << USB_EPR_STATTX_SHIFT) /* EndPoint TX STALLed */ +# define USB_EPR_STATTX_NAK (2 << USB_EPR_STATTX_SHIFT) /* EndPoint TX NAKed */ +# define USB_EPR_STATTX_VALID (3 << USB_EPR_STATTX_SHIFT) /* EndPoint TX VALID */ +# define USB_EPR_STATTX_DTOG1 (1 << USB_EPR_STATTX_SHIFT) /* EndPoint TX Data Toggle bit1 */ +# define USB_EPR_STATTX_DTOG2 (2 << USB_EPR_STATTX_SHIFT) /* EndPoint TX Data Toggle bit2 */ +#define USB_EPR_DTOG_TX (1 << 6) /* Bit 6: Data Toggle, for transmission transfers */ +#define USB_EPR_CTR_TX (1 << 7) /* Bit 7: Correct Transfer for transmission */ +#define USB_EPR_EP_KIND (1 << 8) /* Bit 8: Endpoint Kind */ +#define USB_EPR_EPTYPE_SHIFT (9) /* Bits 10-9: Endpoint type */ +#define USB_EPR_EPTYPE_MASK (3 << USB_EPR_EPTYPE_SHIFT) +# define USB_EPR_EPTYPE_BULK (0 << USB_EPR_EPTYPE_SHIFT) /* EndPoint BULK */ +# define USB_EPR_EPTYPE_CONTROL (1 << USB_EPR_EPTYPE_SHIFT) /* EndPoint CONTROL */ +# define USB_EPR_EPTYPE_ISOC (2 << USB_EPR_EPTYPE_SHIFT) /* EndPoint ISOCHRONOUS */ +# define USB_EPR_EPTYPE_INTERRUPT (3 << USB_EPR_EPTYPE_SHIFT) /* EndPoint INTERRUPT */ +#define USB_EPR_SETUP (1 << 11) /* Bit 11: Setup transaction completed */ +#define USB_EPR_STATRX_SHIFT (12) /* Bits 13-12: Status bits, for reception transfers */ +#define USB_EPR_STATRX_MASK (3 << USB_EPR_STATRX_SHIFT) +# define USB_EPR_STATRX_DIS (0 << USB_EPR_STATRX_SHIFT) /* EndPoint RX DISabled */ +# define USB_EPR_STATRX_STALL (1 << USB_EPR_STATRX_SHIFT) /* EndPoint RX STALLed */ +# define USB_EPR_STATRX_NAK (2 << USB_EPR_STATRX_SHIFT) /* EndPoint RX NAKed */ +# define USB_EPR_STATRX_VALID (3 << USB_EPR_STATRX_SHIFT) /* EndPoint RX VALID */ +# define USB_EPR_STATRX_DTOG1 (1 << USB_EPR_STATRX_SHIFT) /* EndPoint RX Data TOGgle bit1 */ +# define USB_EPR_STATRX_DTOG2 (2 << USB_EPR_STATRX_SHIFT) /* EndPoint RX Data TOGgle bit1 */ +#define USB_EPR_DTOG_RX (1 << 14) /* Bit 14: Data Toggle, for reception transfers */ +#define USB_EPR_CTR_RX (1 << 15) /* Bit 15: Correct Transfer for reception */ + +/* USB control register */ + +#define USB_CNTR_FRES (1 << 0) /* Bit 0: Force USB Reset */ +#define USB_CNTR_PDWN (1 << 1) /* Bit 1: Power down */ +#define USB_CNTR_LPMODE (1 << 2) /* Bit 2: Low-power mode */ +#define USB_CNTR_FSUSP (1 << 3) /* Bit 3: Force suspend */ +#define USB_CNTR_RESUME (1 << 4) /* Bit 4: Resume request */ +#define USB_CNTR_ESOFM (1 << 8) /* Bit 8: Expected Start Of Frame Interrupt Mask */ +#define USB_CNTR_SOFM (1 << 9) /* Bit 9: Start Of Frame Interrupt Mask */ +#define USB_CNTR_RESETM (1 << 10) /* Bit 10: USB Reset Interrupt Mask */ +#define USB_CNTR_SUSPM (1 << 11) /* Bit 11: Suspend mode Interrupt Mask */ +#define USB_CNTR_WKUPM (1 << 12) /* Bit 12: Wakeup Interrupt Mask */ +#define USB_CNTR_ERRM (1 << 13) /* Bit 13: Error Interrupt Mask */ +#define USB_CNTR_DMAOVRNM (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun Interrupt Mask */ +#define USB_CNTR_CTRM (1 << 15) /* Bit 15: Correct Transfer Interrupt Mask */ + +#define USB_CNTR_ALLINTS (USB_CNTR_ESOFM|USB_CNTR_SOFM|USB_CNTR_RESETM|USB_CNTR_SUSPM|\ + USB_CNTR_WKUPM|USB_CNTR_ERRM|USB_CNTR_DMAOVRNM|USB_CNTR_CTRM) + +/* USB interrupt status register */ + +#define USB_ISTR_EPID_SHIFT (0) /* Bits 3-0: Endpoint Identifier */ +#define USB_ISTR_EPID_MASK (0x0f << USB_ISTR_EPID_SHIFT) +#define USB_ISTR_DIR (1 << 4) /* Bit 4: Direction of transaction */ +#define USB_ISTR_ESOF (1 << 8) /* Bit 8: Expected Start Of Frame */ +#define USB_ISTR_SOF (1 << 9) /* Bit 9: Start Of Frame */ +#define USB_ISTR_RESET (1 << 10) /* Bit 10: USB RESET request */ +#define USB_ISTR_SUSP (1 << 11) /* Bit 11: Suspend mode request */ +#define USB_ISTR_WKUP (1 << 12) /* Bit 12: Wake up */ +#define USB_ISTR_ERR (1 << 13) /* Bit 13: Error */ +#define USB_ISTR_DMAOVRN (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun */ +#define USB_ISTR_CTR (1 << 15) /* Bit 15: Correct Transfer */ + +#define USB_ISTR_ALLINTS (USB_ISTR_ESOF|USB_ISTR_SOF|USB_ISTR_RESET|USB_ISTR_SUSP|\ + USB_ISTR_WKUP|USB_ISTR_ERR|USB_ISTR_DMAOVRN|USB_ISTR_CTR) + +/* USB frame number register */ + +#define USB_FNR_FN_SHIFT (0) /* Bits 10-0: Frame Number */ +#define USB_FNR_FN_MASK (0x07ff << USB_FNR_FN_SHIFT) +#define USB_FNR_LSOF_SHIFT (11) /* Bits 12-11: Lost SOF */ +#define USB_FNR_LSOF_MASK (3 << USB_FNR_LSOF_SHIFT) +#define USB_FNR_LCK (1 << 13) /* Bit 13: Locked */ +#define USB_FNR_RXDM (1 << 14) /* Bit 14: Receive Data - Line Status */ +#define USB_FNR_RXDP (1 << 15) /* Bit 15: Receive Data + Line Status */ + +/* USB device address */ + +#define USB_DADDR_ADD_SHIFT (0) /* Bits 6-0: Device Address */ +#define USB_DADDR_ADD_MASK (0x7f << USB_DADDR_ADD_SHIFT) +#define USB_DADDR_EF (1 << 7) /* Bit 7: Enable Function */ + +/* Buffer table address */ + +#define USB_BTABLE_SHIFT (3) /* Bits 15:3: Buffer Table */ +#define USB_BTABLE_MASK (0x1fff << USB_BTABLE_SHIFT) + +/* Transmission buffer address */ + +#define USB_ADDR_TX_ZERO (1 << 0) /* Bit 0 Must always be written as ‘0’ */ +#define USB_ADDR_TX_SHIFT (1) /* Bits 15-1: Transmission Buffer Address */ +#define USB_ADDR_TX_MASK (0x7fff << USB_ADDR_ADDR_TX_SHIFT) + +/* Transmission byte count */ + +#define USB_COUNT_TX_SHIFT (0) /* Bits 9-0: Transmission Byte Count */ +#define USB_COUNT_TX_MASK (0x03ff << USB_COUNT_COUNT_TX_SHIFT) + +/* Reception buffer address */ + +#define USB_ADDR_RX_ZERO (1 << 0) /* Bit 0 This bit must always be written as ‘0’ */ +#define USB_ADDR_RX_SHIFT (1) /* Bits 15:1 ADDRn_RX[15:1]: Reception Buffer Address */ +#define USB_ADDR_RX_MASK (0x7fff << USB_ADDR_RX_SHIFT) + +/* Reception byte count */ + +#define USB_COUNT_RX_BL_SIZE (1 << 15) /* Bit 15: BLock SIZE. */ +#define USB_COUNT_RX_NUM_BLOCK_SHIFT (10) /* Bits 14-10: Number of blocks */ +#define USB_COUNT_RX_NUM_BLOCK_MASK (0x1f << USB_COUNT_RX_NUM_BLOCK_SHIFT) +#define USB_COUNT_RX_SHIFT (0) /* Bits 9-0: Reception Byte Count */ +#define USB_COUNT_RX_MASK (0x03ff << USB_COUNT_RX_SHIFT) + +#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F30XX || CONFIG_STM32_STM32F37XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_USBDEV_H */ + diff --git a/arch/arm/src/stm32/chip/stm32_wdg.h b/arch/arm/src/stm32/chip/stm32_wdg.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f2916f4b7c3c4a7f08b4689b8500b56237753e --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32_wdg.h @@ -0,0 +1,162 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_wdg.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_WDG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32_WDG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_IWDG_KR_OFFSET 0x0000 /* Key register (32-bit) */ +#define STM32_IWDG_PR_OFFSET 0x0004 /* Prescaler register (32-bit) */ +#define STM32_IWDG_RLR_OFFSET 0x0008 /* Reload register (32-bit) */ +#define STM32_IWDG_SR_OFFSET 0x000c /* Status register (32-bit) */ +#if defined(CONFIG_STM32_STM32F30XX) +# define STM32_IWDG_WINR_OFFSET 0x000c /* Window register (32-bit) */ +#endif + +#define STM32_WWDG_CR_OFFSET 0x0000 /* Control Register (32-bit) */ +#define STM32_WWDG_CFR_OFFSET 0x0004 /* Configuration register (32-bit) */ +#define STM32_WWDG_SR_OFFSET 0x0008 /* Status register (32-bit) */ + +/* Register Addresses ***************************************************************/ + +#define STM32_IWDG_KR (STM32_IWDG_BASE+STM32_IWDG_KR_OFFSET) +#define STM32_IWDG_PR (STM32_IWDG_BASE+STM32_IWDG_PR_OFFSET) +#define STM32_IWDG_RLR (STM32_IWDG_BASE+STM32_IWDG_RLR_OFFSET) +#define STM32_IWDG_SR (STM32_IWDG_BASE+STM32_IWDG_SR_OFFSET) +#if defined(CONFIG_STM32_STM32F30XX) +# define STM32_IWDG_WINR (STM32_IWDG_BASE+STM32_IWDG_WINR_OFFSET) +#endif + +#define STM32_WWDG_CR (STM32_WWDG_BASE+STM32_WWDG_CR_OFFSET) +#define STM32_WWDG_CFR (STM32_WWDG_BASE+STM32_WWDG_CFR_OFFSET) +#define STM32_WWDG_SR (STM32_WWDG_BASE+STM32_WWDG_SR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Key register (32-bit) */ + +#define IWDG_KR_KEY_SHIFT (0) /* Bits 15-0: Key value (write only, read 0000h) */ +#define IWDG_KR_KEY_MASK (0xffff << IWDG_KR_KEY_SHIFT) + +#define IWDG_KR_KEY_ENABLE (0x5555) /* Enable register access */ +#define IWDG_KR_KEY_DISABLE (0x0000) /* Disable register access */ +#define IWDG_KR_KEY_RELOAD (0xaaaa) /* Reload the counter */ +#define IWDG_KR_KEY_START (0xcccc) /* Start the watchdog */ + +/* Prescaler register (32-bit) */ + +#define IWDG_PR_SHIFT (0) /* Bits 2-0: Prescaler divider */ +#define IWDG_PR_MASK (7 << IWDG_PR_SHIFT) +# define IWDG_PR_DIV4 (0 << IWDG_PR_SHIFT) /* 000: divider /4 */ +# define IWDG_PR_DIV8 (1 << IWDG_PR_SHIFT) /* 001: divider /8 */ +# define IWDG_PR_DIV16 (2 << IWDG_PR_SHIFT) /* 010: divider /16 */ +# define IWDG_PR_DIV32 (3 << IWDG_PR_SHIFT) /* 011: divider /32 */ +# define IWDG_PR_DIV64 (4 << IWDG_PR_SHIFT) /* 100: divider /64 */ +# define IWDG_PR_DIV128 (5 << IWDG_PR_SHIFT) /* 101: divider /128 */ +# define IWDG_PR_DIV256 (6 << IWDG_PR_SHIFT) /* 11x: divider /256 */ + +/* Reload register (32-bit) */ + +#define IWDG_RLR_RL_SHIFT (0) /* Bits11:0 RL[11:0]: Watchdog counter reload value */ +#define IWDG_RLR_RL_MASK (0x0fff << IWDG_RLR_RL_SHIFT) + +#define IWDG_RLR_MAX (0xfff) + +/* Status register (32-bit) */ + +#define IWDG_SR_PVU (1 << 0) /* Bit 0: Watchdog prescaler value update */ +#define IWDG_SR_RVU (1 << 1) /* Bit 1: Watchdog counter reload value update */ + +#if defined(CONFIG_STM32_STM32F30XX) +# define IWDG_SR_WVU (1 << 2) /* Bit 2: */ +#endif + +/* Window register (32-bit) */ + +#if defined(CONFIG_STM32_STM32F30XX) +# define IWDG_WINR_SHIFT (0) +# define IWDG_WINR_MASK (0x0fff << IWDG_WINR_SHIFT) +#endif + +/* Control Register (32-bit) */ + +#define WWDG_CR_T_SHIFT (0) /* Bits 6:0 T[6:0]: 7-bit counter (MSB to LSB) */ +#define WWDG_CR_T_MASK (0x7f << WWDG_CR_T_SHIFT) +# define WWDG_CR_T_MAX (0x3f << WWDG_CR_T_SHIFT) +# define WWDG_CR_T_RESET (0x40 << WWDG_CR_T_SHIFT) +#define WWDG_CR_WDGA (1 << 7) /* Bit 7: Activation bit */ + +/* Configuration register (32-bit) */ + +#define WWDG_CFR_W_SHIFT (0) /* Bits 6:0 W[6:0] 7-bit window value */ +#define WWDG_CFR_W_MASK (0x7f << WWDG_CFR_W_SHIFT) +#define WWDG_CFR_WDGTB_SHIFT (7) /* Bits 8:7 [1:0]: Timer Base */ +#define WWDG_CFR_WDGTB_MASK (3 << WWDG_CFR_WDGTB_SHIFT) +# define WWDG_CFR_PCLK1 (0 << WWDG_CFR_WDGTB_SHIFT) /* 00: CK Counter Clock (PCLK1 div 4096) div 1 */ +# define WWDG_CFR_PCLK1d2 (1 << WWDG_CFR_WDGTB_SHIFT) /* 01: CK Counter Clock (PCLK1 div 4096) div 2 */ +# define WWDG_CFR_PCLK1d4 (2 << WWDG_CFR_WDGTB_SHIFT) /* 10: CK Counter Clock (PCLK1 div 4096) div 4 */ +# define WWDG_CFR_PCLK1d8 (3 << WWDG_CFR_WDGTB_SHIFT) /* 11: CK Counter Clock (PCLK1 div 4096) div 8 */ +#define WWDG_CFR_EWI (1 << 9) /* Bit 9: Early Wakeup Interrupt */ + +/* Status register (32-bit) */ + +#define WWDG_SR_EWIF (1 << 0) /* Bit 0: Early Wakeup Interrupt Flag */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_WDG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f100_pinmap.h b/arch/arm/src/stm32/chip/stm32f100_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..3f8715058375cde92f56900b83cba3035d723fe3 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f100_pinmap.h @@ -0,0 +1,395 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f100_pinmap.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2012 Michael Smith. All Rights reserved. + * Author: Gregory Nutt + * Uros Platise + * Michael Smith + * Freddie Chopin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F100_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F100_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +/* CEC */ +#if defined(CONFIG_STM32_CEC_REMAP) +# define GPIO_CEC (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#else +# define GPIO_CEC (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +#endif + +/* DAC + * Note from RM0041, 11.2: "Once the DAC channelx is enabled, the corresponding + * GPIO pin (PA4 or PA5) is automatically connected to the analog converter + * output (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 + * pin should first be configured to analog (AIN)." + */ + +#define GPIO_DAC_OUT1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) + +/* FSMC */ + +/* TODO - VL devices in 100- and 144-pin packages have FSMC */ + +/* I2C */ + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +/* SPI */ + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +/* TIMERS */ + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#if defined(CONFIG_STM32_TIM12_REMAP) +# define GPIO_TIM12_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM12_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM12_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM12_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#else +# define GPIO_TIM12_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +# define GPIO_TIM12_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN4) +# define GPIO_TIM12_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) +# define GPIO_TIM12_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN5) +#endif + +#if defined(CONFIG_STM32_TIM13_REMAP) +# define GPIO_TIM13_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM13_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +#else +# define GPIO_TIM13_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM13_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +#endif + +#if defined(CONFIG_STM32_TIM14_REMAP) +# define GPIO_TIM14_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM14_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM14_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM14_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#endif + +#if defined(CONFIG_STM32_TIM15_REMAP) +# define GPIO_TIM15_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM15_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM15_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN15) +# define GPIO_TIM15_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#else +# define GPIO_TIM15_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM15_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM15_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM15_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif +#define GPIO_TIM15_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_TIM16_REMAP) +# define GPIO_TIM16_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM16_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +#else +# define GPIO_TIM16_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM16_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +#endif +#define GPIO_TIM16_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM16_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) + +#if defined(CONFIG_STM32_TIM17_REMAP) +# define GPIO_TIM17_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM17_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#else +# define GPIO_TIM17_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM17_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif +#define GPIO_TIM17_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM17_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) + +/* USART */ + +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_UART4_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +#define GPIO_UART4_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) + +#define GPIO_UART5_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_UART5_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F100_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f102_pinmap.h b/arch/arm/src/stm32/chip/stm32f102_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..d2911da8645d6d3cca4c9e39851fd17b58022817 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f102_pinmap.h @@ -0,0 +1,258 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f102_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Laurent Latil + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F102_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F102_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +#define GPIO_ADC12_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC12_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC12_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC12_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC12_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC12_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC12_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC12_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC12_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC12_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif +#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + + +#if defined(CONFIG_STM32_TIM4_FULL_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif + +/* USARTS */ + +#define GPIO_USART1_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_WKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) + +/* These GPIOs are shared with JTAG / SWD. */ + +#if defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN13) +# define GPIO_PA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN14) +#endif +#if defined (CONFIG_STM32_JTAG_SW_ENABLE) || defined(CONFIG_STM32_JTAG_NOJNTRST_ENABLE) || defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PB4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# if defined (CONFIG_STM32_JTAG_SW_ENABLE) || defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_PB3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# endif +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F102_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f103c_pinmap.h b/arch/arm/src/stm32/chip/stm32f103c_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..35838f70b07d6f3eb6976552ddfd31c8dc9f8bd4 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f103c_pinmap.h @@ -0,0 +1,276 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f103c_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Laurent Latil + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The Medium-density STM32F103Cx is packaged in a LQFP48/UFQFPN48 and does not + * have the full complement of remapping. + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F103C_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103C_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +#define GPIO_ADC12_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC12_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC12_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC12_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# error CAN1_REMAP2 not supported on this architecture +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#if !defined(CONFIG_STM32_LOWDENSITY) +# define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +# define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#endif + +#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#if !defined(CONFIG_STM32_LOWDENSITY) +# define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +# define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# error TIM3_FULL_REMAP not supported +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif +#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + +#if !defined(CONFIG_STM32_LOWDENSITY) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif + +#if 0 /* Needs further investigation */ +#if defined(CONFIG_STM32_TRACESWO_REMAP) +# define GPIO_TRACESWO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#endif +#endif + +#define GPIO_USART1_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# error CONFIG_STM32_USART2_REMAP not supported on this architecture +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# error CONFIG_STM32_USART3_FULL_REMAP not supported on this architecture +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# error CONFIG_STM32_USART3_PARTIAL_REMAP not supported on this architecture +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_WKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) + +/* These GPIOs are shared with JTAG / SWD. */ + +#if defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN13) +# define GPIO_PA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN14) +#endif +#if defined (CONFIG_STM32_JTAG_SW_ENABLE) || defined(CONFIG_STM32_JTAG_NOJNTRST_ENABLE) || defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PB4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# if defined (CONFIG_STM32_JTAG_SW_ENABLE) || defined(CONFIG_STM32_JTAG_DISABLE) +# define GPIO_PA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_PB3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# endif +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F103C_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f103r_pinmap.h b/arch/arm/src/stm32/chip/stm32f103r_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..de73b1acb10e304dec845e8c7c45a2e238fc5b02 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f103r_pinmap.h @@ -0,0 +1,358 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f103r_pinmap.h + * + * Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F103R_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103R_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* ADC */ + +#define GPIO_ADC123_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC123_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC123_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC123_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC3_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC3_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC3_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC3_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC3_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC123_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC123_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC123_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC123_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC12_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC12_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +/* TIMERS */ + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#define GPIO_TIM8_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) + +/* USART */ + +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +/* SPI */ + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_SPI3_REMAP) +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#endif + +/* I2C */ + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +/* CAN */ + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN0) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + + +/* SDIO */ + +#define GPIO_SDIO_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) + +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY +# define GPIO_SDIO_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +# define GPIO_SDIO_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SDIO_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SDIO_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_SDIO_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +# define GPIO_SDIO_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_SDIO_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#endif + +#define GPIO_SDIO_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDIO_CMD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN2) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F103R_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f103v_pinmap.h b/arch/arm/src/stm32/chip/stm32f103v_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..61895a74e9bfe76368f1d79ad55fa373ae477168 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f103v_pinmap.h @@ -0,0 +1,418 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f103v_pinmap.h + * + * Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Laurent Latil + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F103V_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103V_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +#define GPIO_ADC12_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC12_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC12_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC12_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC12_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC12_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC12_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC12_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC12_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC12_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN0) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + +/* SDIO */ + +#define GPIO_SDIO_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) + +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY +# define GPIO_SDIO_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +# define GPIO_SDIO_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SDIO_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SDIO_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_SDIO_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +# define GPIO_SDIO_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_SDIO_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#endif + +#define GPIO_SDIO_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDIO_CMD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN2) + +/* FSMC: NOR/PSRAM/SRAM (NPS) */ + +#define GPIO_NPS_A16 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_NPS_A17 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_NPS_A18 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_NPS_A19 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_NPS_A20 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_NPS_A21 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_NPS_A22 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_NPS_A23 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) + +#define GPIO_NPS_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_NPS_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_NPS_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_NPS_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_NPS_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_NPS_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_NPS_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_NPS_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_NPS_D8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_NPS_D9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_NPS_D10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_NPS_D11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_NPS_D12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_NPS_D13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_NPS_D14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_NPS_D15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) + +#define GPIO_NPS_CLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_NPS_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_NPS_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_NPS_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_NPS_NE1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) + +#if 0 /* Needs further investigation */ +#define GPIO_DAC_OUT1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#endif + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_I2S2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_I2S3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_USB_DM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USB_DP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_SPI3_REMAP) +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_TAMPER_RTC (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN13) +#endif + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif +#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif +#define GPIO_TIM4_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#if 0 /* Needs further investigation */ +#define GPIO_TRACECK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#if defined(CONFIG_STM32_TRACESWO_REMAP) +# define GPIO_TRACESWO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#endif +#endif + +#define GPIO_USART1_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_UART4_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_WKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) + +/* Some GPIOs are accessible only as remapped, alternate functions */ + +#if 0 /* Needs further investigation */ +#define GPIO_PA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_PB3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F103V_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f103z_pinmap.h b/arch/arm/src/stm32/chip/stm32f103z_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..54b09d233507d5d005f0eacb54168dea1e90df20 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f103z_pinmap.h @@ -0,0 +1,590 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f103z_pinmap.h + * + * Copyright (C) 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F103Z_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F103Z_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ADC3_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) + +/* DAC - "Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)." + */ + +#define GPIO_DAC_OUT1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) + +/* TIMERS */ + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#define GPIO_TIM8_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) + +/* USART */ + +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +/* SPI */ + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +# define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +# define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_SPI3_REMAP) +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#endif + +/* I2C */ + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif + +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +/* CAN */ + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN0) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + +/* FSMC: CF */ + +#define GPIO_CF_A0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_CF_A1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_CF_A2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_CF_A3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN3) +#define GPIO_CF_A4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN4) +#define GPIO_CF_A5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN5) +#define GPIO_CF_A6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN12) +#define GPIO_CF_A7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN13) +#define GPIO_CF_A8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN14) +#define GPIO_CF_A9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN15) +#define GPIO_CF_A10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN0) +#define GPIO_CF_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_CF_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_CF_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CF_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CF_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_CF_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_CF_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_CF_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_CF_D8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_CF_D9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_CF_D10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_CF_D11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_CF_D12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_CF_D13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_CF_D14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_CF_D15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_CF_NIORD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_CF_NREG (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN7) +#define GPIO_CF_NIOWR (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN8) +#define GPIO_CF_CD (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_CF_INTR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_CF_NIOS16 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN11) +#define GPIO_CF_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_CF_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_CF_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_CF_NCE41 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_CF_NCE42 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN11) + +/* FSMC: CF/IDE */ + +#define GPIO_CFIDE_A0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_CFIDE_A1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_CFIDE_A2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_CFIDE_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_CFIDE_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_CFIDE_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CFIDE_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CFIDE_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_CFIDE_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_CFIDE_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_CFIDE_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_CFIDE_D8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_CFIDE_D9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_CFIDE_D10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_CFIDE_D11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_CFIDE_D12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_CFIDE_D13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_CFIDE_D14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_CFIDE_D15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_CFIDE_NIORD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_CFIDE_NREG (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN7) +#define GPIO_CFIDE_NIOWR (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN8) +#define GPIO_CFIDE_CD (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_CFIDE_INTR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_CFIDE_NIOS16 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN11) +#define GPIO_CFIDE_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_CFIDE_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_CFIDE_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_CFIDE_NCE41 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_CFIDE_NCE42 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN11) + +/* SDIO */ + +#define GPIO_SDIO_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) + +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY +# define GPIO_SDIO_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +# define GPIO_SDIO_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SDIO_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SDIO_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_SDIO_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +# define GPIO_SDIO_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_SDIO_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#endif + +#define GPIO_SDIO_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDIO_CMD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN2) + +/* FSMC: NOR/PSRAM/SRAM (NPS) */ + +#define GPIO_NPS_A0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_NPS_A1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_NPS_A2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_NPS_A3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN3) +#define GPIO_NPS_A4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN4) +#define GPIO_NPS_A5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN5) +#define GPIO_NPS_A6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN12) +#define GPIO_NPS_A7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN13) +#define GPIO_NPS_A8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN14) +#define GPIO_NPS_A9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTF|GPIO_PIN15) +#define GPIO_NPS_A10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN0) +#define GPIO_NPS_A11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN1) +#define GPIO_NPS_A12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN2) +#define GPIO_NPS_A13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN3) +#define GPIO_NPS_A14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN4) +#define GPIO_NPS_A15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN5) +#define GPIO_NPS_A16 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_NPS_A17 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_NPS_A18 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_NPS_A19 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_NPS_A20 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_NPS_A21 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_NPS_A22 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_NPS_A23 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_NPS_A24 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN13) +#define GPIO_NPS_A25 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_NPS_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_NPS_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_NPS_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_NPS_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_NPS_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_NPS_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_NPS_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_NPS_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_NPS_D8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_NPS_D9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_NPS_D10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_NPS_D11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_NPS_D12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_NPS_D13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_NPS_D14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_NPS_D15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_NPS_CLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_NPS_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_NPS_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_NPS_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_NPS_NE1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_NPS_NE2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_NPS_NE3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_NPS_NE4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_NPS_NBL0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_NPS_NBL1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN1) + +/* FSMC: NOR/PSRAM Multiplex (NPM) */ + +#define GPIO_NPM_A16 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_NPM_A17 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_NPM_A18 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_NPM_A19 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_NPM_A20 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_NPM_A21 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_NPM_A22 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_NPM_A23 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_NPM_DA0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_NPM_DA1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_NPM_DA2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_NPM_DA3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_NPM_DA4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_NPM_DA5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_NPM_DA6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_NPM_DA7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_NPM_DA8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_NPM_DA9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_NPM_DA10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_NPM_DA11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_NPM_DA12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_NPM_DA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_NPM_DA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_NPM_DA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_NPM_CLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_NPM_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_NPM_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_NPM_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_NPM_NE1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_NPM_NE2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_NPM_NE3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_NPM_NE4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_NPM_A24 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN13) +#define GPIO_NPM_A25 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_NPM_NBL0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_NPM_NBL1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN1) + +/* FSMC: NAND */ + +#define GPIO_NAND_D4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_NAND_D5 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_NAND_D6 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_NAND_D7 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_NAND_D8 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_NAND_D9 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_NAND_D10 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_NAND_D11 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_NAND_D12 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_NAND_D13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_NAND_D14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_NAND_D15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_NAND_CLE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_NAND_ALE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_NAND_D0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_NAND_D1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_NAND_INT2 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTG|GPIO_PIN6) +#define GPIO_NAND_INT3 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTG|GPIO_PIN7) +#define GPIO_NAND_D2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_NAND_D3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_NAND_NOE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_NAND_NWE (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_NAND_NWAIT (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +#define GPIO_NAND_NCE2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_NAND_NCE3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTG|GPIO_PIN9) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F103Z_PINMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f105v_pinmap.h b/arch/arm/src/stm32/chip/stm32f105v_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..71ffe846487cb26032143e1d9ae69ff2cc282caa --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f105v_pinmap.h @@ -0,0 +1,414 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f105v_pinmap.h + * + * Copyright (C) 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F105V_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F105V_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +#define GPIO_ADC12_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC12_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC12_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC12_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC12_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC12_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC12_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC12_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC12_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC12_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN0) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + +#if defined(CONFIG_STM32_CAN2_REMAP) +# define GPIO_CAN2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_CAN2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +#else +# define GPIO_CAN2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_CAN2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_DAC_OUT1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_ETH_MDC (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ETH_MDIO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ETH_MIICOL (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ETH_MIICRSWKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ETH_MIIRXCLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) + +#if defined(CONFIG_STM32_ETH_REMAP) +# define GPIO_ETH_MIIRXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +# define GPIO_ETH_MIIRXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_ETH_MIIRXD2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +# define GPIO_ETH_MIIRXD3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_ETH_MIIRXDV (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#else +# define GPIO_ETH_MIIRXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN4) +# define GPIO_ETH_MIIRXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN5) +# define GPIO_ETH_MIIRXD2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_ETH_MIIRXD3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +# define GPIO_ETH_MIIRXDV (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_ETH_MIIRXER (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_ETH_MIITXCLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_MIITXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_MIITXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_MIITXD2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ETH_MIITXD3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_ETH_MIITXEN (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_PPSOUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_ETH_RMIICRSDV (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH_RMIIREFCLK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH_RMIIRXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH_RMIIRXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH_RMIITXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_RMIITXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_RMIITXEN (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#endif + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_I2S3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_OTGFS_DM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTGFS_DP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTGFS_ID (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTGFS_SOF (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_OTGFS_VBUS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_SPI3_REMAP) +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_TAMPER_RTC (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN13) +#endif + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif +#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif +#define GPIO_TIM4_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#if 0 /* Needs further investigation */ +#define GPIO_TRACECK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#if defined(CONFIG_STM32_TRACESWO_REMAP) +# define GPIO_TRACESWO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#endif +#endif + +#define GPIO_USART1_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_UART4_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_WKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) + +/* Some GPIOs are accessible only as remapped, alternate functions */ + +#if 0 /* Needs further investigation */ +#define GPIO_PA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_PB3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F105V_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f107v_pinmap.h b/arch/arm/src/stm32/chip/stm32f107v_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..33af4826428ea10c99c676c002c1690c0c4db0be --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f107v_pinmap.h @@ -0,0 +1,420 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f107v_pinmap.h + * + * Copyright (C) 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F107V_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F107V_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions: */ + +#define GPIO_ADC12_IN0 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC12_IN1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC12_IN10 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC12_IN11 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC12_IN12 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC12_IN13 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC12_IN14 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC12_IN15 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC12_IN2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC12_IN3 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC12_IN4 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC12_IN5 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC12_IN6 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC12_IN7 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC12_IN8 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC12_IN9 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) + +#if defined(CONFIG_STM32_CAN1_REMAP1) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#elif defined(CONFIG_STM32_CAN1_REMAP2) +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN0) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_CAN1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_CAN1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#endif + +#if defined(CONFIG_STM32_CAN2_REMAP) +# define GPIO_CAN2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_CAN2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +#else +# define GPIO_CAN2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_CAN2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_DAC_OUT1 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_INPUT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#endif + +/* Section 29.3 in the stm32 datasheet (Doc ID 13902 Rev 14) */ + +#define GPIO_ETH_MDC (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ETH_MDIO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ETH_MII_COL (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ETH_MII_CRS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ETH_MII_RX_CLK (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#if defined(CONFIG_STM32_ETH_REMAP) +# define GPIO_ETH_MII_RXD0 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +# define GPIO_ETH_MII_RXD1 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_ETH_MII_RXD2 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN11) +# define GPIO_ETH_MII_RXD3 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_ETH_MII_RX_DV (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +#else +# define GPIO_ETH_MII_RXD0 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN4) +# define GPIO_ETH_MII_RXD1 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN5) +# define GPIO_ETH_MII_RXD2 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_ETH_MII_RXD3 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +# define GPIO_ETH_MII_RX_DV (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_ETH_MII_RX_ER (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_ETH_MII_TX_CLK (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_MII_TXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_MII_TXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_MII_TXD2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ETH_MII_TXD3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_ETH_MII_TX_EN (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_PPS_OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_ETH_RMII_REF_CLK (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#if defined(CONFIG_STM32_ETH_REMAP) +# define GPIO_ETH_RMII_CRS_DV (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_ETH_RMII_RXD0 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN9) +# define GPIO_ETH_RMII_RXD1 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +#else +# define GPIO_ETH_RMII_CRS_DV (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_ETH_RMII_RXD0 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN4) +# define GPIO_ETH_RMII_RXD1 (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN5) +#endif +#define GPIO_ETH_RMII_TXD0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_RMII_TXD1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_RMII_TX_EN (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) + +#if defined(CONFIG_STM32_I2C1_REMAP) +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#else +# define GPIO_I2C1_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_I2C1_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +#endif +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT|GPIO_CNF_AFOD|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_I2S3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_WS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_MCO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_OTGFS_DM (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTGFS_DP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTGFS_ID (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTGFS_SOF (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_OTGFS_VBUS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) + +#if defined(CONFIG_STM32_SPI1_REMAP) +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#else +# define GPIO_SPI1_NSS (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI1_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN5) +# define GPIO_SPI1_MISO (GPIO_INPUT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_SPI1_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +#endif + +#define GPIO_SPI2_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) + +#if defined(CONFIG_STM32_SPI3_REMAP) +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_SPI3_NSS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_SPI3_SCK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_SPI3_MISO (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI3_MOSI (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +#endif + +#if 0 /* Needs further investigation */ +#define GPIO_TAMPER_RTC (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN13) +#endif + +#if defined(CONFIG_STM32_TIM1_FULL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN7) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN9) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN15) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN8) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN10) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN12) +#elif defined(CONFIG_STM32_TIM1_PARTIAL_REMAP) +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM1_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN12) +# define GPIO_TIM1_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +# define GPIO_TIM1_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_TIM1_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN10) +# define GPIO_TIM1_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN11) +# define GPIO_TIM1_BKIN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN12) +# define GPIO_TIM1_CH1N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN13) +# define GPIO_TIM1_CH2N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +# define GPIO_TIM1_CH3N (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN15) +#endif + +#if defined(CONFIG_STM32_TIM2_FULL_REMAP) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_1) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#elif defined(CONFIG_STM32_TIM2_PARTIAL_REMAP_2) +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN11) +#else +# define GPIO_TIM2_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +# define GPIO_TIM2_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_TIM2_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_TIM2_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_TIM2_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_TIM3_FULL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN9) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN9) +#elif defined(CONFIG_STM32_TIM3_PARTIAL_REMAP) +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_TIM3_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN6) +# define GPIO_TIM3_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_TIM3_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_TIM3_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +# define GPIO_TIM3_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN1) +#endif +#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) + +#if defined(CONFIG_STM32_TIM4_REMAP) +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN13) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN14) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN15) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN15) +#else +# define GPIO_TIM4_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_TIM4_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN7) +# define GPIO_TIM4_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM4_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM4_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN9) +#endif +#define GPIO_TIM4_ETR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH2IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH3IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH4IN (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN3) + +#if 0 /* Needs further investigation */ +#define GPIO_TRACECK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTE|GPIO_PIN6) +#if defined(CONFIG_STM32_TRACESWO_REMAP) +# define GPIO_TRACESWO (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#endif +#endif + +#define GPIO_USART1_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN8) +#if defined(CONFIG_STM32_USART1_REMAP) +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN7) +#else +# define GPIO_USART1_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) +# define GPIO_USART1_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_USART2_REMAP) +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN3) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN4) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN5) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN6) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN7) +#else +# define GPIO_USART2_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +# define GPIO_USART2_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN1) +# define GPIO_USART2_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN2) +# define GPIO_USART2_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +# define GPIO_USART2_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_USART3_FULL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN8) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN9) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN10) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN11) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTD|GPIO_PIN12) +#elif defined(CONFIG_STM32_USART3_PARTIAL_REMAP) +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#else +# define GPIO_USART3_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN10) +# define GPIO_USART3_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN11) +# define GPIO_USART3_CK (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN12) +# define GPIO_USART3_CTS (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN13) +# define GPIO_USART3_RTS (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN14) +#endif + +#define GPIO_UART4_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_WKUP (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN0) + +/* Some GPIOs are accessible only as remapped, alternate functions */ + +#if 0 /* Needs further investigation */ +#define GPIO_PA13 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_PB3 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4 (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTB|GPIO_PIN4) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F107V_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_dma.h b/arch/arm/src/stm32/chip/stm32f10xxx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..a24c611a50a2b2099369a0adf2ad33ce728df9b0 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_dma.h @@ -0,0 +1,608 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xxx_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_DMA_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_DMA_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* These definitions apply to both the STM32 F1 and F3 families */ +/* 12 Channels Total: 7 DMA1 Channels(1-7) and 5 DMA2 channels (1-5) */ + +#define DMA1 0 +#define DMA2 1 +#define DMA3 2 +#define DMA4 3 +#define DMA5 4 +#define DMA6 5 +#define DMA7 6 + +/* Register Offsets *****************************************************************/ + +#define STM32_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */ +#define STM32_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */ + +#define STM32_DMACHAN_OFFSET(n) (0x0014*(n)) +#define STM32_DMACHAN1_OFFSET 0x0000 +#define STM32_DMACHAN2_OFFSET 0x0014 +#define STM32_DMACHAN3_OFFSET 0x0028 +#define STM32_DMACHAN4_OFFSET 0x003c +#define STM32_DMACHAN5_OFFSET 0x0050 +#define STM32_DMACHAN6_OFFSET 0x0064 +#define STM32_DMACHAN7_OFFSET 0x0078 + +#define STM32_DMACHAN_CCR_OFFSET 0x0008 /* DMA channel configuration register */ +#define STM32_DMACHAN_CNDTR_OFFSET 0x000c /* DMA channel number of data register */ +#define STM32_DMACHAN_CPAR_OFFSET 0x0010 /* DMA channel peripheral address register */ +#define STM32_DMACHAN_CMAR_OFFSET 0x0014 /* DMA channel 1 memory address register */ + +#define STM32_DMA_CCR_OFFSET(n) (STM32_DMACHAN_CCR_OFFSET+STM32_DMACHAN_OFFSET(n)) +#define STM32_DMA_CNDTR_OFFSET(n) (STM32_DMACHAN_CNDTR_OFFSET+STM32_DMACHAN_OFFSET(n)) +#define STM32_DMA_CPAR_OFFSET(n) (STM32_DMACHAN_CPAR_OFFSET+STM32_DMACHAN_OFFSET(n)) +#define STM32_DMA_CMAR_OFFSET(n) (STM32_DMACHAN_CMAR_OFFSET+STM32_DMACHAN_OFFSET(n)) + +#define STM32_DMA_CCR1_OFFSET 0x0008 /* DMA channel 1 configuration register */ +#define STM32_DMA_CCR2_OFFSET 0x001c /* DMA channel 2 configuration register */ +#define STM32_DMA_CCR3_OFFSET 0x0030 /* DMA channel 3 configuration register */ +#define STM32_DMA_CCR4_OFFSET 0x0044 /* DMA channel 4 configuration register */ +#define STM32_DMA_CCR5_OFFSET 0x0058 /* DMA channel 5 configuration register */ +#define STM32_DMA_CCR6_OFFSET 0x006c /* DMA channel 6 configuration register */ +#define STM32_DMA_CCR7_OFFSET 0x0080 /* DMA channel 7 configuration register */ + +#define STM32_DMA_CNDTR1_OFFSET 0x000c /* DMA channel 1 number of data register */ +#define STM32_DMA_CNDTR2_OFFSET 0x0020 /* DMA channel 2 number of data register */ +#define STM32_DMA_CNDTR3_OFFSET 0x0034 /* DMA channel 3 number of data register */ +#define STM32_DMA_CNDTR4_OFFSET 0x0048 /* DMA channel 4 number of data register */ +#define STM32_DMA_CNDTR5_OFFSET 0x005c /* DMA channel 5 number of data register */ +#define STM32_DMA_CNDTR6_OFFSET 0x0070 /* DMA channel 6 number of data register */ +#define STM32_DMA_CNDTR7_OFFSET 0x0084 /* DMA channel 7 number of data register */ + +#define STM32_DMA_CPAR1_OFFSET 0x0010 /* DMA channel 1 peripheral address register */ +#define STM32_DMA_CPAR2_OFFSET 0x0024 /* DMA channel 2 peripheral address register */ +#define STM32_DMA_CPAR3_OFFSET 0x0038 /* DMA channel 3 peripheral address register */ +#define STM32_DMA_CPAR4_OFFSET 0x004c /* DMA channel 4 peripheral address register */ +#define STM32_DMA_CPAR5_OFFSET 0x0060 /* DMA channel 5 peripheral address register */ +#define STM32_DMA_CPAR6_OFFSET 0x0074 /* DMA channel 6 peripheral address register */ +#define STM32_DMA_CPAR7_OFFSET 0x0088 /* DMA channel 7 peripheral address register */ + +#define STM32_DMA_CMAR1_OFFSET 0x0014 /* DMA channel 1 memory address register */ +#define STM32_DMA_CMAR2_OFFSET 0x0028 /* DMA channel 2 memory address register */ +#define STM32_DMA_CMAR3_OFFSET 0x003c /* DMA channel 3 memory address register */ +#define STM32_DMA_CMAR4_OFFSET 0x0050 /* DMA channel 4 memory address register */ +#define STM32_DMA_CMAR5_OFFSET 0x0064 /* DMA channel 5 memory address register */ +#define STM32_DMA_CMAR6_OFFSET 0x0078 /* DMA channel 6 memory address register */ +#define STM32_DMA_CMAR7_OFFSET 0x008c /* DMA channel 7 memory address register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_DMA1_ISRC (STM32_DMA1_BASE+STM32_DMA_ISR_OFFSET) +#define STM32_DMA1_IFCR (STM32_DMA1_BASE+STM32_DMA_IFCR_OFFSET) + +#define STM32_DMA1_CCR(n) (STM32_DMA1_BASE+STM32_DMA_CCR_OFFSET(n)) +#define STM32_DMA1_CCR1 (STM32_DMA1_BASE+STM32_DMA_CCR1_OFFSET) +#define STM32_DMA1_CCR2 (STM32_DMA1_BASE+STM32_DMA_CCR2_OFFSET) +#define STM32_DMA1_CCR3 (STM32_DMA1_BASE+STM32_DMA_CCR3_OFFSET) +#define STM32_DMA1_CCR4 (STM32_DMA1_BASE+STM32_DMA_CCR4_OFFSET) +#define STM32_DMA1_CCR5 (STM32_DMA1_BASE+STM32_DMA_CCR5_OFFSET) +#define STM32_DMA1_CCR6 (STM32_DMA1_BASE+STM32_DMA_CCR6_OFFSET) +#define STM32_DMA1_CCR7 (STM32_DMA1_BASE+STM32_DMA_CCR7_OFFSET) + +#define STM32_DMA1_CNDTR(n) (STM32_DMA1_BASE+STM32_DMA_CNDTR_OFFSET(n)) +#define STM32_DMA1_CNDTR1 (STM32_DMA1_BASE+STM32_DMA_CNDTR1_OFFSET) +#define STM32_DMA1_CNDTR2 (STM32_DMA1_BASE+STM32_DMA_CNDTR2_OFFSET) +#define STM32_DMA1_CNDTR3 (STM32_DMA1_BASE+STM32_DMA_CNDTR3_OFFSET) +#define STM32_DMA1_CNDTR4 (STM32_DMA1_BASE+STM32_DMA_CNDTR4_OFFSET) +#define STM32_DMA1_CNDTR5 (STM32_DMA1_BASE+STM32_DMA_CNDTR5_OFFSET) +#define STM32_DMA1_CNDTR6 (STM32_DMA1_BASE+STM32_DMA_CNDTR6_OFFSET) +#define STM32_DMA1_CNDTR7 (STM32_DMA1_BASE+STM32_DMA_CNDTR7_OFFSET) + +#define STM32_DMA1_CPAR(n) (STM32_DMA1_BASE+STM32_DMA_CPAR_OFFSET(n)) +#define STM32_DMA1_CPAR1 (STM32_DMA1_BASE+STM32_DMA_CPAR1_OFFSET) +#define STM32_DMA1_CPAR2 (STM32_DMA1_BASE+STM32_DMA_CPAR2_OFFSET) +#define STM32_DMA1_CPAR3 (STM32_DMA1_BASE+STM32_DMA_CPAR3_OFFSET) +#define STM32_DMA1_CPAR4 (STM32_DMA1_BASE+STM32_DMA_CPAR4_OFFSET) +#define STM32_DMA1_CPAR5 (STM32_DMA1_BASE+STM32_DMA_CPAR5_OFFSET) +#define STM32_DMA1_CPAR6 (STM32_DMA1_BASE+STM32_DMA_CPAR6_OFFSET) +#define STM32_DMA1_CPAR7 (STM32_DMA1_BASE+STM32_DMA_CPAR7_OFFSET) + +#define STM32_DMA1_CMAR(n) (STM32_DMA1_BASE+STM32_DMA_CMAR_OFFSET(n)) +#define STM32_DMA1_CMAR1 (STM32_DMA1_BASE+STM32_DMA_CMAR1_OFFSET) +#define STM32_DMA1_CMAR2 (STM32_DMA1_BASE+STM32_DMA_CMAR2_OFFSET) +#define STM32_DMA1_CMAR3 (STM32_DMA1_BASE+STM32_DMA_CMAR3_OFFSET) +#define STM32_DMA1_CMAR4 (STM32_DMA1_BASE+STM32_DMA_CMAR4_OFFSET) +#define STM32_DMA1_CMAR5 (STM32_DMA1_BASE+STM32_DMA_CMAR5_OFFSET) +#define STM32_DMA1_CMAR6 (STM32_DMA1_BASE+STM32_DMA_CMAR6_OFFSET) +#define STM32_DMA1_CMAR7 (STM32_DMA1_BASE+STM32_DMA_CMAR7_OFFSET) + +#define STM32_DMA2_ISRC (STM32_DMA2_BASE+STM32_DMA_ISR_OFFSET) +#define STM32_DMA2_IFCR (STM32_DMA2_BASE+STM32_DMA_IFCR_OFFSET) + +#define STM32_DMA2_CCR(n) (STM32_DMA2_BASE+STM32_DMA_CCR_OFFSET(n)) +#define STM32_DMA2_CCR1 (STM32_DMA2_BASE+STM32_DMA_CCR1_OFFSET) +#define STM32_DMA2_CCR2 (STM32_DMA2_BASE+STM32_DMA_CCR2_OFFSET) +#define STM32_DMA2_CCR3 (STM32_DMA2_BASE+STM32_DMA_CCR3_OFFSET) +#define STM32_DMA2_CCR4 (STM32_DMA2_BASE+STM32_DMA_CCR4_OFFSET) +#define STM32_DMA2_CCR5 (STM32_DMA2_BASE+STM32_DMA_CCR5_OFFSET) + +#define STM32_DMA2_CNDTR(n) (STM32_DMA2_BASE+STM32_DMA_CNDTR_OFFSET(n)) +#define STM32_DMA2_CNDTR1 (STM32_DMA2_BASE+STM32_DMA_CNDTR1_OFFSET) +#define STM32_DMA2_CNDTR2 (STM32_DMA2_BASE+STM32_DMA_CNDTR2_OFFSET) +#define STM32_DMA2_CNDTR3 (STM32_DMA2_BASE+STM32_DMA_CNDTR3_OFFSET) +#define STM32_DMA2_CNDTR4 (STM32_DMA2_BASE+STM32_DMA_CNDTR4_OFFSET) +#define STM32_DMA2_CNDTR5 (STM32_DMA2_BASE+STM32_DMA_CNDTR5_OFFSET) + +#define STM32_DMA2_CPAR(n) (STM32_DMA2_BASE+STM32_DMA_CPAR_OFFSET(n)) +#define STM32_DMA2_CPAR1 (STM32_DMA2_BASE+STM32_DMA_CPAR1_OFFSET) +#define STM32_DMA2_CPAR2 (STM32_DMA2_BASE+STM32_DMA_CPAR2_OFFSET) +#define STM32_DMA2_CPAR3 (STM32_DMA2_BASE+STM32_DMA_CPAR3_OFFSET) +#define STM32_DMA2_CPAR4 (STM32_DMA2_BASE+STM32_DMA_CPAR4_OFFSET) +#define STM32_DMA2_CPAR5 (STM32_DMA2_BASE+STM32_DMA_CPAR5_OFFSET) + +#define STM32_DMA2_CMAR(n) (STM32_DMA2_BASE+STM32_DMA_CMAR_OFFSET(n)) +#define STM32_DMA2_CMAR1 (STM32_DMA2_BASE+STM32_DMA_CMAR1_OFFSET) +#define STM32_DMA2_CMAR2 (STM32_DMA2_BASE+STM32_DMA_CMAR2_OFFSET) +#define STM32_DMA2_CMAR3 (STM32_DMA2_BASE+STM32_DMA_CMAR3_OFFSET) +#define STM32_DMA2_CMAR4 (STM32_DMA2_BASE+STM32_DMA_CMAR4_OFFSET) +#define STM32_DMA2_CMAR5 (STM32_DMA2_BASE+STM32_DMA_CMAR5_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_CHAN_SHIFT(n) ((n) << 2) +#define DMA_CHAN_MASK 0x0f +#define DMA_CHAN_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */ +#define DMA_CHAN_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */ +#define DMA_CHAN_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */ +#define DMA_CHAN_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */ + +/* DMA interrupt status register */ + +#define DMA_ISR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_ISR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */ +#define DMA_ISR_CHAN1_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN1_SHIFT) +#define DMA_ISR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */ +#define DMA_ISR_CHAN2_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN2_SHIFT) +#define DMA_ISR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */ +#define DMA_ISR_CHAN3_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN3_SHIFT) +#define DMA_ISR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */ +#define DMA_ISR_CHAN4_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN4_SHIFT) +#define DMA_ISR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */ +#define DMA_ISR_CHAN5_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN5_SHIFT) +#define DMA_ISR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */ +#define DMA_ISR_CHAN6_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN6_SHIFT) +#define DMA_ISR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */ +#define DMA_ISR_CHAN7_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN7_SHIFT) + +#define DMA_ISR_GIF(n) (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TCIF(n) (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_HTIF(n) (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TEIF(n) (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n)) + +/* DMA interrupt flag clear register */ + +#define DMA_IFCR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_IFCR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt flag clear */ +#define DMA_IFCR_CHAN1_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN1_SHIFT) +#define DMA_IFCR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt flag clear */ +#define DMA_IFCR_CHAN2_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN2_SHIFT) +#define DMA_IFCR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt flag clear */ +#define DMA_IFCR_CHAN3_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN3_SHIFT) +#define DMA_IFCR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt flag clear */ +#define DMA_IFCR_CHAN4_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN4_SHIFT) +#define DMA_IFCR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt flag clear */ +#define DMA_IFCR_CHAN5_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN5_SHIFT) +#define DMA_IFCR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt flag clear */ +#define DMA_IFCR_CHAN6_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN6_SHIFT) +#define DMA_IFCR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt flag clear */ +#define DMA_IFCR_CHAN7_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN7_SHIFT) +#define DMA_IFCR_ALLCHANNELS (0x0fffffff) + +#define DMA_IFCR_CGIF(n) (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTCIF(n) (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHTIF(n) (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTEIF(n) (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) + +/* DMA channel configuration register */ + +#define DMA_CCR_EN (1 << 0) /* Bit 0: Channel enable */ +#define DMA_CCR_TCIE (1 << 1) /* Bit 1: Transfer complete interrupt enable */ +#define DMA_CCR_HTIE (1 << 2) /* Bit 2: Half Transfer interrupt enable */ +#define DMA_CCR_TEIE (1 << 3) /* Bit 3: Transfer error interrupt enable */ +#define DMA_CCR_DIR (1 << 4) /* Bit 4: Data transfer direction */ +#define DMA_CCR_CIRC (1 << 5) /* Bit 5: Circular mode */ +#define DMA_CCR_PINC (1 << 6) /* Bit 6: Peripheral increment mode */ +#define DMA_CCR_MINC (1 << 7) /* Bit 7: Memory increment mode */ +#define DMA_CCR_PSIZE_SHIFT (8) /* Bits 8-9: Peripheral size */ +#define DMA_CCR_PSIZE_MASK (3 << DMA_CCR_PSIZE_SHIFT) +# define DMA_CCR_PSIZE_8BITS (0 << DMA_CCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_PSIZE_16BITS (1 << DMA_CCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_PSIZE_32BITS (2 << DMA_CCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_MSIZE_SHIFT (10) /* Bits 10-11: Memory size */ +#define DMA_CCR_MSIZE_MASK (3 << DMA_CCR_MSIZE_SHIFT) +# define DMA_CCR_MSIZE_8BITS (0 << DMA_CCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_MSIZE_16BITS (1 << DMA_CCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_MSIZE_32BITS (2 << DMA_CCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_PL_SHIFT (12) /* Bits 12-13: Channel Priority level */ +#define DMA_CCR_PL_MASK (3 << DMA_CCR_PL_SHIFT) +# define DMA_CCR_PRILO (0 << DMA_CCR_PL_SHIFT) /* 00: Low */ +# define DMA_CCR_PRIMED (1 << DMA_CCR_PL_SHIFT) /* 01: Medium */ +# define DMA_CCR_PRIHI (2 << DMA_CCR_PL_SHIFT) /* 10: High */ +# define DMA_CCR_PRIVERYHI (3 << DMA_CCR_PL_SHIFT) /* 11: Very high */ +#define DMA_CCR_MEM2MEM (1 << 14) /* Bit 14: Memory to memory mode */ + +#define DMA_CCR_ALLINTS (DMA_CCR_TEIE|DMA_CCR_HTIE|DMA_CCR_TCIE) + +/* DMA channel number of data register */ + +#define DMA_CNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_CNDTR_NDT_MASK (0xffff << DMA_CNDTR_NDT_SHIFT) + +/* DMA Channel mapping. Each DMA channel has a mapping to several possible + * sources/sinks of data. The requests from peripherals assigned to a channel + * are simply OR'ed together before entering the DMA block. This means that only + * one request on a given channel can be enabled at once. + * + * Alternative DMA channel selections are provided with a numeric suffix like _1, + * _2, etc. Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. + */ + +#define STM32_DMA1_CHAN1 (0) +#define STM32_DMA1_CHAN2 (1) +#define STM32_DMA1_CHAN3 (2) +#define STM32_DMA1_CHAN4 (3) +#define STM32_DMA1_CHAN5 (4) +#define STM32_DMA1_CHAN6 (5) +#define STM32_DMA1_CHAN7 (6) + +#define STM32_DMA2_CHAN1 (7) +#define STM32_DMA2_CHAN2 (8) +#define STM32_DMA2_CHAN3 (9) +#define STM32_DMA2_CHAN4 (10) +#define STM32_DMA2_CHAN5 (11) + +#if defined(CONFIG_STM32_STM32L15XX) + +# define DMACHAN_ADC1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM2_CH3 STM32_DMA1_CHAN1 +# define DMACHAN_TIM4_CH1 STM32_DMA1_CHAN1 + +# define DMACHAN_SPI1_RX STM32_DMA1_CHAN2 +# define DMACHAN_USART3_TX STM32_DMA1_CHAN2 +# define DMACHAN_TIM2_UP STM32_DMA1_CHAN2 +# define DMACHAN_TIM3_CH3 STM32_DMA1_CHAN2 +# define DMACHAN_TIM6_UP STM32_DMA1_CHAN2 +# define DMACHAN_DAC_CHAN1 STM32_DMA1_CHAN2 + +# define DMACHAN_SPI1_TX STM32_DMA1_CHAN3 +# define DMACHAN_USART3_RX STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_CH4 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_UP STM32_DMA1_CHAN3 +# define DMACHAN_TIM7_UP STM32_DMA1_CHAN3 +# define DMACHAN_DAC_CHAN2 STM32_DMA1_CHAN3 + +# define DMACHAN_SPI2_RX STM32_DMA1_CHAN4 +# define DMACHAN_USART1_TX STM32_DMA1_CHAN4 +# define DMACHAN_I2C2_TX STM32_DMA1_CHAN4 +# define DMACHAN_TIM4_CH2 STM32_DMA1_CHAN4 + +# define DMACHAN_SPI2_TX STM32_DMA1_CHAN5 +# define DMACHAN_USART1_RX STM32_DMA1_CHAN5 +# define DMACHAN_I2C2_RX STM32_DMA1_CHAN5 +# define DMACHAN_TIM2_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM4_CH3 STM32_DMA1_CHAN5 + +# define DMACHAN_USART2_RX STM32_DMA1_CHAN6 +# define DMACHAN_I2C1_TX STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_CH1 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_TRIG STM32_DMA1_CHAN6 + +# define DMACHAN_USART2_TX STM32_DMA1_CHAN7 +# define DMACHAN_I2C1_RX STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH2 STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH4 STM32_DMA1_CHAN7 +# define DMACHAN_TIM4_UP STM32_DMA1_CHAN7 + +# define DMACHAN_SPI3_RX STM32_DMA2_CHAN1 +# define DMACHAN_UART5_TX STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_CH4 STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_TRIG STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_COM STM32_DMA2_CHAN1 + +# define DMACHAN_SPI3_TX STM32_DMA2_CHAN2 +# define DMACHAN_UART5_RX STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_CH3 STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_UP STM32_DMA2_CHAN2 + +# define DMACHAN_UART4_RX STM32_DMA2_CHAN3 +# define DMACHAN_AES_OUT STM32_DMA2_CHAN3 + +# define DMACHAN_TIM5_CH2 STM32_DMA2_CHAN4 +# define DMACHAN_SDIO STM32_DMA2_CHAN4 + +# define DMACHAN_UART4_TX STM32_DMA2_CHAN5 +# define DMACHAN_TIM5_CH1 STM32_DMA2_CHAN5 +# define DMACHAN_AES_IN STM32_DMA2_CHAN5 + +#elif defined(CONFIG_STM32_STM32F10XX) + +# define DMACHAN_ADC1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM2_CH3 STM32_DMA1_CHAN1 +# define DMACHAN_TIM4_CH1 STM32_DMA1_CHAN1 + +# define DMACHAN_SPI1_RX STM32_DMA1_CHAN2 +# define DMACHAN_USART3_TX STM32_DMA1_CHAN2 +# define DMACHAN_TIM1_CH1 STM32_DMA1_CHAN2 +# define DMACHAN_TIM2_UP STM32_DMA1_CHAN2 +# define DMACHAN_TIM3_CH3 STM32_DMA1_CHAN2 + +# define DMACHAN_SPI1_TX STM32_DMA1_CHAN3 +# define DMACHAN_USART3_RX STM32_DMA1_CHAN3 +# define DMACHAN_TIM1_CH2 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_CH4 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_UP STM32_DMA1_CHAN3 + +# define DMACHAN_SPI2_RX STM32_DMA1_CHAN4 +# define DMACHAN_I2S2_RX STM32_DMA1_CHAN4 +# define DMACHAN_USART1_TX STM32_DMA1_CHAN4 +# define DMACHAN_I2C2_TX STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_CH4 STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_TRIG STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_COM STM32_DMA1_CHAN4 +# define DMACHAN_TIM4_CH2 STM32_DMA1_CHAN4 + +# define DMACHAN_SPI2_TX STM32_DMA1_CHAN5 +# define DMACHAN_I2S2_TX STM32_DMA1_CHAN5 +# define DMACHAN_USART1_RX STM32_DMA1_CHAN5 +# define DMACHAN_I2C2_RX STM32_DMA1_CHAN5 +# define DMACHAN_TIM1_UP STM32_DMA1_CHAN5 +# define DMACHAN_TIM2_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM4_CH3 STM32_DMA1_CHAN5 + +# define DMACHAN_USART2_RX STM32_DMA1_CHAN6 +# define DMACHAN_I2C1_TX STM32_DMA1_CHAN6 +# define DMACHAN_TIM1_CH3 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_CH1 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_TRIG STM32_DMA1_CHAN6 + +# define DMACHAN_USART2_TX STM32_DMA1_CHAN7 +# define DMACHAN_I2C1_RX STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH2 STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH4 STM32_DMA1_CHAN7 +# define DMACHAN_TIM4_UP STM32_DMA1_CHAN7 + +# define DMACHAN_SPI3_RX STM32_DMA2_CHAN1 +# define DMACHAN_I2S3_RX STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_CH4 STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_TRIG STM32_DMA2_CHAN1 +# define DMACHAN_TIM8_CH3 STM32_DMA2_CHAN1 +# define DMACHAN_TIM8_UP STM32_DMA2_CHAN1 + +# define DMACHAN_SPI3_TX STM32_DMA2_CHAN2 +# define DMACHAN_I2S3_TX STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_CH3 STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_UP STM32_DMA2_CHAN2 +# define DMACHAN_TIM8_TRIG STM32_DMA2_CHAN2 +# define DMACHAN_TIM8_COM STM32_DMA2_CHAN2 + +# define DMACHAN_UART4_RX STM32_DMA2_CHAN3 +# define DMACHAN_TIM6_UP STM32_DMA2_CHAN3 +# define DMACHAN_DAC_CHAN1 STM32_DMA2_CHAN3 +# define DMACHAN_TIM8_CH1 STM32_DMA2_CHAN3 + +# define DMACHAN_SDIO STM32_DMA2_CHAN4 +# define DMACHAN_TIM5_CH2 STM32_DMA2_CHAN4 +# define DMACHAN_TIM7_UP STM32_DMA2_CHAN4 +# define DMACHAN_DAC_CHAN2 STM32_DMA2_CHAN4 + +# define DMACHAN_ADC3 STM32_DMA2_CHAN5 +# define DMACHAN_UART4_TX STM32_DMA2_CHAN5 +# define DMACHAN_TIM5_CH1 STM32_DMA2_CHAN5 +# define DMACHAN_TIM8_CH2 STM32_DMA2_CHAN5 + +#elif defined(CONFIG_STM32_STM32F30XX) + +# define DMACHAN_ADC1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM2_CH3 STM32_DMA1_CHAN1 +# define DMACHAN_TIM4_CH1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM17_CH1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM17_UP STM32_DMA1_CHAN1 + +# define DMACHAN_SPI1_RX STM32_DMA1_CHAN2 +# define DMACHAN_USART3_TX STM32_DMA1_CHAN2 +# define DMACHAN_TIM1_CH1 STM32_DMA1_CHAN2 +# define DMACHAN_TIM2_UP STM32_DMA1_CHAN2 +# define DMACHAN_TIM3_CH3 STM32_DMA1_CHAN2 + +# define DMACHAN_SPI1_TX STM32_DMA1_CHAN3 +# define DMACHAN_USART3_RX STM32_DMA1_CHAN3 +# define DMACHAN_TIM1_CH2_1 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_CH4 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_UP_2 STM32_DMA1_CHAN3 + +# define DMACHAN_SPI2_RX STM32_DMA1_CHAN4 +# define DMACHAN_I2S2_RX STM32_DMA1_CHAN4 +# define DMACHAN_USART1_TX STM32_DMA1_CHAN4 +# define DMACHAN_I2C2_TX STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_CH4 STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_TRIG STM32_DMA1_CHAN4 +# define DMACHAN_TIM1_COM STM32_DMA1_CHAN4 +# define DMACHAN_TIM4_CH2 STM32_DMA1_CHAN4 +# define DMACHAN_TIM7_UP_1 STM32_DMA1_CHAN4 +# define DMACHAN_DAC_CH2 STM32_DMA1_CHAN4 + +# define DMACHAN_SPI2_TX STM32_DMA1_CHAN5 +# define DMACHAN_I2S2_TX STM32_DMA1_CHAN5 +# define DMACHAN_USART1_RX STM32_DMA1_CHAN5 +# define DMACHAN_I2C2_RX STM32_DMA1_CHAN5 +# define DMACHAN_TIM1_UP STM32_DMA1_CHAN5 +# define DMACHAN_TIM2_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM4_CH3 STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_UP STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_TRIG STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_COM STM32_DMA1_CHAN5 + +# define DMACHAN_USART2_RX STM32_DMA1_CHAN6 +# define DMACHAN_I2C1_TX STM32_DMA1_CHAN6 +# define DMACHAN_TIM1_CH3 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_CH1 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_TRIG STM32_DMA1_CHAN6 +# define DMACHAN_TIM16_CH1 STM32_DMA1_CHAN6 +# define DMACHAN_TIM16_UP STM32_DMA1_CHAN6 + +# define DMACHAN_USART2_TX STM32_DMA1_CHAN7 +# define DMACHAN_I2C1_RX STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH2 STM32_DMA1_CHAN7 +# define DMACHAN_TIM2_CH4 STM32_DMA1_CHAN7 +# define DMACHAN_TIM4_UP STM32_DMA1_CHAN7 +# define DMACHAN_TIM17_CH1_2 STM32_DMA1_CHAN7 +# define DMACHAN_TIM17_UP_2 STM32_DMA1_CHAN7 + +# define DMACHAN_ADC2_1 STM32_DMA2_CHAN1 +# define DMACHAN_SPI3_RX STM32_DMA2_CHAN1 +# define DMACHAN_I2S3_RX STM32_DMA2_CHAN1 +# define DMACHAN_TIM8_CH3 STM32_DMA2_CHAN1 +# define DMACHAN_TIM8_UP STM32_DMA2_CHAN1 + +# define DMACHAN_ADC4_1 STM32_DMA2_CHAN2 +# define DMACHAN_SPI3_TX STM32_DMA2_CHAN2 +# define DMACHAN_I2S3_TX STM32_DMA2_CHAN2 +# define DMACHAN_TIM8_CH4 STM32_DMA2_CHAN2 +# define DMACHAN_TIM8_TRIG STM32_DMA2_CHAN2 +# define DMACHAN_TIM8_COM STM32_DMA2_CHAN2 + +# define DMACHAN_ADC2_2 STM32_DMA2_CHAN3 +# define DMACHAN_UART4_RX STM32_DMA2_CHAN3 +# define DMACHAN_TIM6_UP STM32_DMA2_CHAN3 +# define DMACHAN_DAC_CHAN1 STM32_DMA2_CHAN3 +# define DMACHAN_TIM8_CH1 STM32_DMA2_CHAN3 + +# define DMACHAN_ADC4_2 STM32_DMA2_CHAN4 +# define DMACHAN_TIM7_UP_2 STM32_DMA2_CHAN4 +# define DMACHAN_DAC_CHAN2 STM32_DMA2_CHAN4 + +# define DMACHAN_ADC3 STM32_DMA2_CHAN5 +# define DMACHAN_UART4_TX STM32_DMA2_CHAN5 +# define DMACHAN_TIM8_CH2 STM32_DMA2_CHAN5 + +#elif defined(CONFIG_STM32_STM32F37XX) + +# define DMACHAN_ADC1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM2_CH3 STM32_DMA1_CHAN1 +# define DMACHAN_TIM4_CH1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM17_CH1 STM32_DMA1_CHAN1 +# define DMACHAN_TIM17_UP STM32_DMA1_CHAN1 + +# define DMACHAN_SPI1_RX STM32_DMA1_CHAN2 +# define DMACHAN_USART3_TX STM32_DMA1_CHAN2 +# define DMACHAN_TIM2_UP STM32_DMA1_CHAN2 +# define DMACHAN_TIM3_CH3 STM32_DMA1_CHAN2 +# define DMACHAN_TIM19_CH1 STM32_DMA1_CHAN2 + +# define DMACHAN_SPI1_TX STM32_DMA1_CHAN3 +# define DMACHAN_USART3_RX STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_CH4 STM32_DMA1_CHAN3 +# define DMACHAN_TIM3_UP STM32_DMA1_CHAN3 +# define DMACHAN_TIM6_UP STM32_DMA1_CHAN3 +# define DMACHAN_DAC1_CH1 STM32_DMA1_CHAN3 +# define DMACHAN_TIM16_CH1 STM32_DMA1_CHAN3 +# define DMACHAN_TIM16_UP STM32_DMA1_CHAN3 +# define DMACHAN_TIM19_CH2 STM32_DMA1_CHAN3 + +# define DMACHAN_SPI2_RX STM32_DMA1_CHAN4 +# define DMACHAN_USART1_TX STM32_DMA1_CHAN4 +# define DMACHAN_I2C2_TX STM32_DMA1_CHAN4 +# define DMACHAN_TIM4_CH2 STM32_DMA1_CHAN4 +# define DMACHAN_TIM7_UP STM32_DMA1_CHAN4 +# define DMACHAN_DAC1_CH2 STM32_DMA1_CHAN4 +# define DMACHAN_TIM19_UP STM32_DMA1_CHAN4 + +# define DMACHAN_SPI2_TX STM32_DMA1_CHAN5 +# define DMACHAN_USART1_RX STM32_DMA1_CHAN5 +# define DMACHAN_I2C2_RX STM32_DMA1_CHAN5 +# define DMACHAN_TIM2_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM4_CH3 STM32_DMA1_CHAN5 +# define DMACHAN_TIM18_UP STM32_DMA1_CHAN5 +# define DMACHAN_DAC2_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_CH1 STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_UP STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_TRIG STM32_DMA1_CHAN5 +# define DMACHAN_TIM15_COM STM32_DMA1_CHAN5 + +# define DMACHAN_USART2_RX STM32_DMA1_CHAN6 +# define DMACHAN_I2C1_TX STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_CH1 STM32_DMA1_CHAN6 +# define DMACHAN_TIM3_TRIG STM32_DMA1_CHAN6 +# define DMACHAN_TIM16_CH1_2 STM32_DMA1_CHAN6 +# define DMACHAN_TIM16_UP_2 STM32_DMA1_CHAN6 + +# define DMACHAN_USART2_TX STM32_DMA1_CHAN7 +# define DMACHAN_I2C1_RX STM32_DMA1_CHAN6 +# define DMACHAN_TIM2_CH2 STM32_DMA1_CHAN6 +# define DMACHAN_TIM2_CH4 STM32_DMA1_CHAN6 +# define DMACHAN_TIM4_UP STM32_DMA1_CHAN6 +# define DMACHAN_TIM17_CH1_2 STM32_DMA1_CHAN6 +# define DMACHAN_TIM17_UP_2 STM32_DMA1_CHAN6 + +# define DMACHAN_SPI3_RX STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_CH4 STM32_DMA2_CHAN1 +# define DMACHAN_TIM5_TRIG STM32_DMA2_CHAN1 + +# define DMACHAN_SPI3_TX STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_CH3 STM32_DMA2_CHAN2 +# define DMACHAN_TIM5_UP STM32_DMA2_CHAN2 + +# define DMACHAN_SDADC1 STM32_DMA2_CHAN3 +# define DMACHAN_TIM6_UP_2 STM32_DMA2_CHAN3 +# define DMACHAN_DAC1_CH1_2 STM32_DMA2_CHAN3 + +# define DMACHAN_SDADC2 STM32_DMA2_CHAN4 +# define DMACHAN_TIM5_CH2 STM32_DMA2_CHAN4 +# define DMACHAN_TIM7_UP_2 STM32_DMA2_CHAN4 +# define DMACHAN_DAC1_CH2_2 STM32_DMA2_CHAN4 + +# define DMACHAN_SDADC3 STM32_DMA2_CHAN5 +# define DMACHAN_TIM5_CH1 STM32_DMA2_CHAN5 +# define DMACHAN_TIM18_UP_2 STM32_DMA2_CHAN5 +# define DMACHAN_DAC2_CH1_2 STM32_DMA2_CHAN5 + +#else +# error "Unknown DMA channel assignments" +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_DMA_H */ diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h b/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..11c333434515c36a752aed627b9832fcf7ceb73d --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h @@ -0,0 +1,400 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xxx_gpio.h + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_NGPIO_PORTS ((STM32_NGPIO + 15) >> 4) + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_CRL_OFFSET 0x0000 /* Port configuration register low */ +#define STM32_GPIO_CRH_OFFSET 0x0004 /* Port configuration register high */ +#define STM32_GPIO_IDR_OFFSET 0x0008 /* Port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x000c /* Port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0010 /* Port bit set/reset register */ +#define STM32_GPIO_BRR_OFFSET 0x0014 /* Port bit reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x0018 /* Port configuration lock register */ + +#define STM32_AFIO_EVCR_OFFSET 0x0000 /* Event control register */ +#define STM32_AFIO_MAPR_OFFSET 0x0004 /* AF remap and debug I/O configuration register */ +#define STM32_AFIO_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_AFIO_EXTICR1_OFFSET 0x0008 /* External interrupt configuration register 1 */ +#define STM32_AFIO_EXTICR2_OFFSET 0x000c /* External interrupt configuration register 2 */ +#define STM32_AFIO_EXTICR3_OFFSET 0x0010 /* External interrupt configuration register 3 */ +#define STM32_AFIO_EXTICR4_OFFSET 0x0014 /* External interrupt configuration register 4 */ +#define STM32_AFIO_MAPR2_OFFSET 0x001c /* AF remap and debug I/O configuration register 2 */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NGPIO_PORTS > 0 +# define STM32_GPIOA_CRL (STM32_GPIOA_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOA_CRH (STM32_GPIOA_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOA_BRR (STM32_GPIOA_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 1 +# define STM32_GPIOB_CRL (STM32_GPIOB_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOB_CRH (STM32_GPIOB_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOB_BRR (STM32_GPIOB_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 2 +# define STM32_GPIOC_CRL (STM32_GPIOC_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOC_CRH (STM32_GPIOC_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOC_BRR (STM32_GPIOC_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 3 +# define STM32_GPIOD_CRL (STM32_GPIOD_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOD_CRH (STM32_GPIOD_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOD_BRR (STM32_GPIOD_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 4 +# define STM32_GPIOE_CRL (STM32_GPIOE_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOE_CRH (STM32_GPIOE_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOE_BRR (STM32_GPIOE_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 5 +# define STM32_GPIOF_CRL (STM32_GPIOF_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOF_CRH (STM32_GPIOF_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOF_BRR (STM32_GPIOF_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 6 +# define STM32_GPIOG_CRL (STM32_GPIOG_BASE+STM32_GPIO_CRL_OFFSET) +# define STM32_GPIOG_CRH (STM32_GPIOG_BASE+STM32_GPIO_CRH_OFFSET) +# define STM32_GPIOG_IDR (STM32_GPIOG_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOG_ODR (STM32_GPIOG_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOG_BSRR (STM32_GPIOG_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOG_BRR (STM32_GPIOG_BASE+STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOG_LCKR (STM32_GPIOG_BASE+STM32_GPIO_LCKR_OFFSET) +#endif + +#define STM32_AFIO_EVCR (STM32_AFIO_BASE+STM32_AFIO_EVCR_OFFSET) +#define STM32_AFIO_MAPR (STM32_AFIO_BASE+STM32_AFIO_MAPR_OFFSET) +#define STM32_AFIO_EXTICR(p) (STM32_AFIO_BASE+STM32_AFIO_EXTICR_OFFSET(p)) +#define STM32_AFIO_EXTICR1 (STM32_AFIO_BASE+STM32_AFIO_EXTICR1_OFFSET) +#define STM32_AFIO_EXTICR2 (STM32_AFIO_BASE+STM32_AFIO_EXTICR2_OFFSET) +#define STM32_AFIO_EXTICR3 (STM32_AFIO_BASE+STM32_AFIO_EXTICR3_OFFSET) +#define STM32_AFIO_EXTICR4 (STM32_AFIO_BASE+STM32_AFIO_EXTICR4_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Port configuration register low */ + +#define GPIO_CR_MODE_SHIFT(n) ((n) << 2) +#define GPIO_CR_MODE_MASK(n) (3 << GPIO_CR_MODE_SHIFT(n)) +#define GPIO_CR_CNF_SHIFT(n) (2 + ((n) << 2)) +#define GPIO_CR_CNF_MASK(n) (3 << GPIO_CR_CNF_SHIFT(n)) + +#define GPIO_CR_MODECNF_SHIFT(n) ((n) << 2) +#define GPIO_CR_MODECNF_MASK(n) (0x0f << GPIO_CR_MODECNF_SHIFT(n)) + +#define GPIO_CRL_MODE0_SHIFT (0) /* Bits 1:0: Port mode bits */ +#define GPIO_CRL_MODE0_MASK (3 << GPIO_CRL_MODE0_SHIFT) +#define GPIO_CRL_CNF0_SHIFT (2) /* Bits 3:2: Port configuration bits */ +#define GPIO_CRL_CNF0_MASK (3 << GPIO_CRL_CNF0_SHIFT) +#define GPIO_CRL_MODE1_SHIFT (4) /* Bits 5:4: Port mode bits */ +#define GPIO_CRL_MODE1_MASK (3 << GPIO_CRL_MODE1_SHIFT) +#define GPIO_CRL_CNF1_SHIFT (6) /* Bits 7:6: Port configuration bits */ +#define GPIO_CRL_CNF1_MASK (3 << GPIO_CRL_CNF1_SHIFT) +#define GPIO_CRL_MODE2_SHIFT (8) /* Bits 9:8: Port mode bits */ +#define GPIO_CRL_MODE2_MASK (3 << GPIO_CRL_MODE2_SHIFT) +#define GPIO_CRL_CNF2_SHIFT (10) /* Bits 11:10: Port configuration bits */ +#define GPIO_CRL_CNF2_MASK (3 << GPIO_CRL_CNF2_SHIFT) +#define GPIO_CRL_MODE3_SHIFT (12) /* Bits 13:12: Port mode bits */ +#define GPIO_CRL_MODE3_MASK (3 << GPIO_CRL_MODE3_SHIFT) +#define GPIO_CRL_CNF3_SHIFT (14) /* Bits 15:14: Port configuration bits */ +#define GPIO_CRL_CNF3_MASK (3 << GPIO_CRL_CNF3_SHIFT) +#define GPIO_CRL_MODE4_SHIFT (16) /* Bits 17:16: Port mode bits */ +#define GPIO_CRL_MODE4_MASK (3 << GPIO_CRL_MODE4_SHIFT) +#define GPIO_CRL_CNF4_SHIFT (18) /* Bits 19:18: Port configuration bits */ +#define GPIO_CRL_CNF4_MASK (3 << GPIO_CRL_CNF4_SHIFT) +#define GPIO_CRL_MODE5_SHIFT (20) /* Bits 21:20: Port mode bits */ +#define GPIO_CRL_MODE5_MASK (3 << GPIO_CRL_MODE5_SHIFT) +#define GPIO_CRL_CNF5_SHIFT (22) /* Bits 23:22: Port configuration bits */ +#define GPIO_CRL_CNF5_MASK (3 << GPIO_CRL_CNF5_SHIFT) +#define GPIO_CRL_MODE6_SHIFT (24) /* Bits 25:24: Port mode bits */ +#define GPIO_CRL_MODE6_MASK (3 << GPIO_CRL_MODE6_SHIFT) +#define GPIO_CRL_CNF6_SHIFT (26) /* Bits 27:26: Port configuration bits */ +#define GPIO_CRL_CNF6_MASK (3 << GPIO_CRL_CNF6_SHIFT) +#define GPIO_CRL_MODE7_SHIFT (28) /* Bits 29:28: Port mode bits */ +#define GPIO_CRL_MODE7_MASK (3 << GPIO_CRL_MODE7_SHIFT) +#define GPIO_CRL_CNF7_SHIFT (30) /* Bits 31:30: Port configuration bits */ +#define GPIO_CRL_CNF7_MASK (3 << GPIO_CRL_CNF7_SHIFT) + +#define GPIO_CR_CNF_INANALOG (0) /* 00: Analog input mode */ +#define GPIO_CR_CNF_INFLOAT (1) /* 01: Floating input (reset state) */ +#define GPIO_CR_CNF_INPULLUD (2) /* 10: Input with pull-up / pull-down */ + +#define GPIO_CR_CNF_OUTPP (0) /* 00: General purpose output push-pull */ +#define GPIO_CR_CNF_OUTOD (1) /* 01: General purpose output Open-drain */ +#define GPIO_CR_CNF_ALTPP (2) /* 10: Alternate function output Push-pull */ +#define GPIO_CR_CNF_ALTOD (3) /* 11: Alternate function output Open-drain */ + +#define GPIO_CR_MODE_INRST (0) /* 00: Input mode (reset state) */ +#define GPIO_CR_MODE_OUT10MHz (1) /* 01: Output mode, max speed 10 MHz */ +#define GPIO_CR_MODE_OUT2MHz (2) /* 10: Output mode, max speed 2 MHz */ +#define GPIO_CR_MODE_OUT50MHz (3) /* 11: Output mode, max speed 50 MHz */ + +/* Port configuration register high */ + +#define GPIO_CRH_MODE8_SHIFT (0) /* Bits 1:0: Port mode bits */ +#define GPIO_CRH_MODE8_MASK (3 << GPIO_CRH_MODE8_SHIFT) +#define GPIO_CRH_CNF8_SHIFT (2) /* Bits 3:2: Port configuration bits */ +#define GPIO_CRH_CNF8_MASK (3 << GPIO_CRH_CNF8_SHIFT) +#define GPIO_CRH_MODE9_SHIFT (4) /* Bits 5:4: Port mode bits */ +#define GPIO_CRH_MODE9_MASK (3 << GPIO_CRH_MODE9_SHIFT) +#define GPIO_CRH_CNF9_SHIFT (6) /* Bits 7:6: Port configuration bits */ +#define GPIO_CRH_CNF9_MASK (3 << GPIO_CRH_CNF9_SHIFT) +#define GPIO_CRH_MODE10_SHIFT (8) /* Bits 9:8: Port mode bits */ +#define GPIO_CRH_MODE10_MASK (3 << GPIO_CRH_MODE10_SHIFT) +#define GPIO_CRH_CNF10_SHIFT (10) /* Bits 11:10: Port configuration bits */ +#define GPIO_CRH_CNF10_MASK (3 << GPIO_CRH_CNF10_SHIFT) +#define GPIO_CRH_MODE11_SHIFT (12) /* Bits 13:12: Port mode bits */ +#define GPIO_CRH_MODE11_MASK (3 << GPIO_CRH_MODE11_SHIFT) +#define GPIO_CRH_CNF11_SHIFT (14) /* Bits 15:14: Port configuration bits */ +#define GPIO_CRH_CNF11_MASK (3 << GPIO_CRH_CNF11_SHIFT) +#define GPIO_CRH_MODE12_SHIFT (16) /* Bits 17:16: Port mode bits */ +#define GPIO_CRH_MODE12_MASK (3 << GPIO_CRH_MODE12_SHIFT) +#define GPIO_CRH_CNF12_SHIFT (18) /* Bits 19:18: Port configuration bits */ +#define GPIO_CRH_CNF12_MASK (3 << GPIO_CRH_CNF12_SHIFT) +#define GPIO_CRH_MODE13_SHIFT (20) /* Bits 21:20: Port mode bits */ +#define GPIO_CRH_MODE13_MASK (3 << GPIO_CRH_MODE13_SHIFT) +#define GPIO_CRH_CNF13_SHIFT (22) /* Bits 23:22: Port configuration bits */ +#define GPIO_CRH_CNF13_MASK (3 << GPIO_CRH_CNF13_SHIFT) +#define GPIO_CRH_MODE14_SHIFT (24) /* Bits 25:24: Port mode bits */ +#define GPIO_CRH_MODE14_MASK (3 << GPIO_CRH_MODE14_SHIFT) +#define GPIO_CRH_CNF14_SHIFT (26) /* Bits 27:26: Port configuration bits */ +#define GPIO_CRH_CNF14_MASK (3 << GPIO_CRH_CNF14_SHIFT) +#define GPIO_CRH_MODE15_SHIFT (28) /* Bits 29:28: Port mode bits */ +#define GPIO_CRH_MODE15_MASK (3 << GPIO_CRH_MODE15_SHIFT) +#define GPIO_CRH_CNF15_SHIFT (30) /* Bits 31:30: Port configuration bits */ +#define GPIO_CRL_CNF15_MASK (3 << GPIO_CRL_CNF15_SHIFT) + +/* Port input/ouput data register */ + +#define GPIO_IDR(n) (1 << (n)) +#define GPIO_ODR(n) (1 << (n)) + +/* Port bit set/reset register */ + +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BRR(n) (1 << (n)) + +/* Port configuration lock register */ + +#define GPIO_LCKR_LCKK (1 << 16) /* Bit 16: Lock key */ +#define GPIO_LCKR_LCK(n) (1 << (n)) + +/* Event control register */ + +#define AFIO_EVCR_PIN_SHIFT (0) /* Bits 3-0: Pin selection */ +#define AFIO_EVCR_PIN_MASK (0x0f << AFIO_EVCR_PIN_SHIFT) +#define AFIO_EVCR_PORT_SHIFT (4) /* Bits 6-4: Port selection */ +#define AFIO_EVCR_PORT_MASK (7 << AFIO_EVCR_PORT_SHIFT) +# define AFIO_EVCR_PORTA (0 << AFIO_EVCR_PORT_SHIFT) /* 000: PA selected */ +# define AFIO_EVCR_PORTB (1 << AFIO_EVCR_PORT_SHIFT) /* 001: PB selected */ +# define AFIO_EVCR_PORTC (2 << AFIO_EVCR_PORT_SHIFT) /* 010: PC selected */ +# define AFIO_EVCR_PORTD (3 << AFIO_EVCR_PORT_SHIFT) /* 011: PD selected */ +# define AFIO_EVCR_PORTE (4 << AFIO_EVCR_PORT_SHIFT) /* 100: PE selected */ +#define AFIO_EVCR_EVOE (1 << 7) /* Bit 7: Event Output Enable */ + +/* AF remap and debug I/O configuration register */ + +#define AFIO_MAPR_SPI1_REMAP (1 << 0) /* Bit 0: SPI1 remapping */ +#define AFIO_MAPR_I2C1_REMAP (1 << 1) /* Bit 1: I2C1 remapping */ +#define AFIO_MAPR_USART1_REMAP (1 << 2) /* Bit 2: USART1 remapping */ +#define AFIO_MAPR_USART2_REMAP (1 << 3) /* Bit 3: USART2 remapping */ +#define AFIO_MAPR_USART3_REMAP_SHIFT (4) /* Bits 5-4: USART3 remapping */ +#define AFIO_MAPR_USART3_REMAP_MASK (3 << AFIO_MAPR_USART3_REMAP_SHIFT) +# define AFIO_MAPR_USART3_NOREMAP (0 << AFIO_MAPR_USART3_REMAP_SHIFT) /* 00: No remap */ +# define AFIO_MAPR_USART3_PARTREMAP (1 << AFIO_MAPR_USART3_REMAP_SHIFT) /* 01: Partial remap */ +# define AFIO_MAPR_USART3_FULLREMAP (3 << AFIO_MAPR_USART3_REMAP_SHIFT) /* 11: Full remap */ +#define AFIO_MAPR_TIM1_REMAP_SHIFT (6) /* Bits 7-6: TIM1 remapping */ +#define AFIO_MAPR_TIM1_REMAP_MASK (3 << AFIO_MAPR_TIM1_REMAP_SHIFT) +# define AFIO_MAPR_TIM1_NOREMAP (0 << AFIO_MAPR_TIM1_REMAP_SHIFT) /* 00: No remap */ +# define AFIO_MAPR_TIM1_PARTREMAP (1 << AFIO_MAPR_TIM1_REMAP_SHIFT) /* 01: Partial remap */ +# define AFIO_MAPR_TIM1_FULLREMAP (3 << AFIO_MAPR_TIM1_REMAP_SHIFT) /* 11: Full remap */ +#define AFIO_MAPR_TIM2_REMAP_SHIFT (8) /* Bits 9-8: TIM2 remapping */ +#define AFIO_MAPR_TIM2_REMAP_MASK (3 << AFIO_MAPR_TIM2_REMAP_SHIFT) +# define AFIO_MAPR_TIM2_NOREMAP (0 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 00: No remap */ +# define AFIO_MAPR_TIM2_PARTREMAP1 (1 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 01: Partial remap */ +# define AFIO_MAPR_TIM2_PARTREMAP2 (2 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 10: Partial remap */ +# define AFIO_MAPR_TIM2_FULLREMAP (3 << AFIO_MAPR_TIM2_REMAP_SHIFT) /* 11: Full remap */ +#define AFIO_MAPR_TIM3_REMAP_SHIFT (10) /* Bits 11-10: TIM3 remapping */ +#define AFIO_MAPR_TIM3_REMAP_MASK (3 << AFIO_MAPR_TIM3_REMAP_SHIFT) +# define AFIO_MAPR_TIM3_NOREMAP (0 << AFIO_MAPR_TIM3_REMAP_SHIFT) /* 00: No remap */ +# define AFIO_MAPR_TIM3_PARTREMAP (2 << AFIO_MAPR_TIM3_REMAP_SHIFT) /* 10: Partial remap */ +# define AFIO_MAPR_TIM3_FULLREMAP (3 << AFIO_MAPR_TIM3_REMAP_SHIFT) /* 11: Full remap */ +#define AFIO_MAPR_TIM4_REMAP (1 << 12) /* Bit 12: TIM4 remapping */ +#define AFIO_MAPR_CAN1_REMAP_SHIFT (13) /* Bits 14-13: CAN Alternate function remapping */ +#define AFIO_MAPR_CAN1_REMAP_MASK (3 << AFIO_MAPR_CAN1_REMAP_SHIFT) +# define AFIO_MAPR_PA1112 (0 << AFIO_MAPR_CAN1_REMAP_SHIFT) /* 00: CANRX mapped to PA11, CANTX mapped to PA12 */ +# define AFIO_MAPR_PB89 (2 << AFIO_MAPR_CAN1_REMAP_SHIFT) /* 10: CANRX mapped to PB8, CANTX mapped to PB9 */ +# define AFIO_MAPR_PD01 (3 << AFIO_MAPR_CAN1_REMAP_SHIFT) /* 11: CANRX mapped to PD0, CANTX mapped to PD1 */ +#define AFIO_MAPR_PD01_REMAP (1 << 15) /* Bit 15 : Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +#define AFIO_MAPR_TIM5CH4_IREMAP (1 << 16) /* Bit 16: TIM5 channel4 internal remap */ + /* Bits 17-20: Reserved */ +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define AFIO_MAPR_ETH_REMAP (1 << 21) /* Bit 21: Ethernet MAC I/O remapping */ +# define AFIO_MAPR_CAN2_REMAP (1 << 22) /* Bit 22: CAN2 I/O remapping */ +# define AFIO_MAPR_MII_RMII_SEL (1 << 23) /* Bit 23: MII or RMII selection */ +#endif +#define AFIO_MAPR_SWJ_CFG_SHIFT (24) /* Bits 26-24: Serial Wire JTAG configuration */ +#define AFIO_MAPR_SWJ_CFG_MASK (7 << AFIO_MAPR_SWJ_CFG_SHIFT) +# define AFIO_MAPR_SWJRST (0 << AFIO_MAPR_SWJ_CFG_SHIFT) /* 000: Full SWJ (JTAG-DP + SW-DP): Reset State */ +# define AFIO_MAPR_SWJ (1 << AFIO_MAPR_SWJ_CFG_SHIFT) /* 001: Full SWJ (JTAG-DP + SW-DP) but without JNTRST */ +# define AFIO_MAPR_SWDP (2 << AFIO_MAPR_SWJ_CFG_SHIFT) /* 010: JTAG-DP Disabled and SW-DP Enabled */ +# define AFIO_MAPR_DISAB (4 << AFIO_MAPR_SWJ_CFG_SHIFT) /* 100: JTAG-DP Disabled and SW-DP Disabled */ + /* Bit 27: Reserved */ +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define AFIO_MAPR_SPI3_REMAP (1 << 28) /* Bit 28: SPI3 remapping */ +# define AFIO_MAPR_TIM2ITR1_IREMAP (1 << 29) /* Bit 29: TIM2 internal trigger 1 remapping */ +# define AFIO_MAPR_PTP_PPS_REMAP (1 << 30) /* Bit 30: Ethernet PTP PPS remapping */ +#endif + /* Bit 31: Reserved */ +/* External interrupt configuration register 1 */ + +#define AFIO_EXTICR_PORT_MASK (0x0f) +#define AFIO_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define AFIO_EXTICR_EXTI_MASK(g) (AFIO_EXTICR_PORT_MASK << (AFIO_EXTICR_EXTI_SHIFT(g))) + +#define AFIO_EXTICR1_EXTI0_SHIFT (0) /* Bits 3-0: EXTI 0 configuration */ +#define AFIO_EXTICR1_EXTI0_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR1_EXTI0_SHIFT) +#define AFIO_EXTICR1_EXTI1_SHIFT (4) /* Bits 7-4: EXTI 1 configuration */ +#define AFIO_EXTICR1_EXTI1_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR1_EXTI1_SHIFT) +#define AFIO_EXTICR1_EXTI2_SHIFT (8) /* Bits 11-8: EXTI 2 configuration */ +#define AFIO_EXTICR1_EXTI2_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR1_EXTI2_SHIFT) +#define AFIO_EXTICR1_EXTI3_SHIFT (12) /* Bits 15-12: EXTI 3 configuration */ +#define AFIO_EXTICR1_EXTI3_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR1_EXTI3_SHIFT) + +#define AFIO_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define AFIO_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define AFIO_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define AFIO_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define AFIO_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define AFIO_EXTICR_PORTF (5) /* 0101: PF[x] pin */ +#define AFIO_EXTICR_PORTG (6) /* 0110: PG[x] pin */ + +/* External interrupt configuration register 2 */ + +#define AFIO_EXTICR2_EXTI4_SHIFT (0) /* Bits 3-0: EXTI 4 configuration */ +#define AFIO_EXTICR2_EXTI4_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR2_EXTI4_SHIFT) +#define AFIO_EXTICR2_EXTI5_SHIFT (4) /* Bits 7-4: EXTI 5 configuration */ +#define AFIO_EXTICR2_EXTI5_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR2_EXTI5_SHIFT) +#define AFIO_EXTICR2_EXTI6_SHIFT (8) /* Bits 11-8: EXTI 6 configuration */ +#define AFIO_EXTICR2_EXTI6_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR2_EXTI6_SHIFT) +#define AFIO_EXTICR2_EXTI7_SHIFT (12) /* Bits 15-12: EXTI 7 configuration */ +#define AFIO_EXTICR2_EXTI7_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR2_EXTI7_SHIFT) + +/* External interrupt configuration register 3 */ + +#define AFIO_EXTICR3_EXTI8_SHIFT (0) /* Bits 3-0: EXTI 8 configuration */ +#define AFIO_EXTICR3_EXTI8_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR3_EXTI8_SHIFT) +#define AFIO_EXTICR3_EXTI9_SHIFT (4) /* Bits 7-4: EXTI 9 configuration */ +#define AFIO_EXTICR3_EXTI9_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR3_EXTI9_SHIFT) +#define AFIO_EXTICR3_EXTI10_SHIFT (8) /* Bits 11-8: EXTI 10 configuration */ +#define AFIO_EXTICR3_EXTI10_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR3_EXTI10_SHIFT) +#define AFIO_EXTICR3_EXTI11_SHIFT (12) /* Bits 15-12: EXTI 11 configuration */ +#define AFIO_EXTICR3_EXTI11_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR3_EXTI11_SHIFT) + +/* External interrupt configuration register 4 */ + +#define AFIO_EXTICR4_EXTI12_SHIFT (0) /* Bits 3-0: EXTI 12 configuration */ +#define AFIO_EXTICR4_EXTI12_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR4_EXTI12_SHIFT) +#define AFIO_EXTICR4_EXTI13_SHIFT (4) /* Bits 7-4: EXTI 13 configuration */ +#define AFIO_EXTICR4_EXTI13_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR4_EXTI13_SHIFT) +#define AFIO_EXTICR4_EXTI14_SHIFT (8) /* Bits 11-8: EXTI 14 configuration */ +#define AFIO_EXTICR4_EXTI14_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR4_EXTI14_SHIFT) +#define AFIO_EXTICR4_EXTI15_SHIFT (12) /* Bits 15-12: EXTI 15 configuration */ +#define AFIO_EXTICR4_EXTI15_MASK (AFIO_EXTICR_PORT_MASK << AFIO_EXTICR4_EXTI15_SHIFT) + +/* AF remap and debug I/O configuration register 2 */ + +#ifdef CONFIG_STM32_VALUELINE +# define AFIO_MAPR2_TIM15_REMAP (1 << 0) /* Bit 0: TIM15 remapping */ +# define AFIO_MAPR2_TIM16_REMAP (1 << 1) /* Bit 1: TIM16 remapping */ +# define AFIO_MAPR2_TIM17_REMAP (1 << 2) /* Bit 2: TIM17 remapping */ +# define AFIO_MAPR2_CEC_REMAP (1 << 3) /* Bit 3: CEC remapping */ +# define AFIO_MAPR2_TIM1_DMA_REMAP (1 << 4) /* Bit 4: TIM1 DMA remapping */ +#else +# define AFIO_MAPR2_TIM9_REMAP (1 << 5) /* Bit 5: TIM9 remapping */ +# define AFIO_MAPR2_TIM10_REMAP (1 << 6) /* Bit 6: TIM10 remapping */ +# define AFIO_MAPR2_TIM11_REMAP (1 << 7) /* Bit 7: TIM11 remapping */ +#endif +#define AFIO_MAPR2_TIM13_REMAP (1 << 8) /* Bit 8: TIM13 remapping */ +#define AFIO_MAPR2_TIM14_REMAP (1 << 9) /* Bit 9: TIM14 remapping */ +#define AFIO_MAPR2_FSMC_NADV (1 << 10) /* Bit 10: NADV connect/disconnect */ +#ifdef CONFIG_STM32_VALUELINE +# define AFIO_MAPR2_TIM67_DAC_DMA_REMAP (1 << 11) /* Bit 11: TIM67_DAC DMA remapping */ +# define AFIO_MAPR2_TIM12_REMAP (1 << 12) /* Bit 12: TIM12 remapping */ +# define AFIO_MAPR2_MISC_REMAP (1 << 13) /* Bit 13: Miscellaneous features remapping */ +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_GPIO_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..9a1cbcd5fb5fde31b93c5412344debf37e14f6a8 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h @@ -0,0 +1,163 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xxx_memorymap.h + * + * Copyright (C) 2009, 2011, 3013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* FLASH and SRAM *******************************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000 - Up to 512Kb */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000 - 64Kb SRAM */ +#define STM32_SRAMBB_BASE 0x22000000 +#define STM32_PERIPH_BASE 0x40000000 + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) + +/* System Memory Addresses **********************************************************/ + +#define STM32_SYSMEM_UID 0x1ffff7e8 /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x1ffff7e0 /* This bitfield indicates the size of + * the device Flash memory expressed + * in Kbytes. Example: 0x0080 = 128 + * Kbytes + */ + +/* Register Base Address ************************************************************/ + +/* APB1 bus */ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000 - 0x400003ff: TIM2 timer */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400 - 0x400007ff: TIM3 timer */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800 - 0x40000bff: TIM4 timer */ +#define STM32_TIM5_BASE 0x40000c00 /* 0x40000c00 - 0x40000fff: TIM5 timer */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000 - 0x400013ff: TIM6 timer */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400 - 0x400007ff: TIM7 timer */ +#define STM32_TIM12_BASE 0x40001800 /* 0x40001800 - 0x40001bff: TIM12 timer */ +#define STM32_TIM13_BASE 0x40001c00 /* 0x40001c00 - 0x40001fff: TIM13 timer */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000 - 0x400023ff: TIM14 timer */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800 - 0x40002bff: RTC */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002C00 - 0x40002fff: Window watchdog (WWDG) */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000 - 0x400033ff: Independent watchdog (IWDG) */ + /* 0x40003400 - 0x400037ff: Reserved */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800 - 0x40003bff: SPI2/I2S2 */ +#define STM32_I2S2_BASE 0x40003800 +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00 - 0x40003fff: SPI3/I2S3 */ +#define STM32_I2S3_BASE 0x40003c00 + /* 0x40004000 - 0x400043ff: Reserved */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400 - 0x400047ff: USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800 - 0x40004bff: USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00 - 0x40004fff: UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000 - 0x400053ff: UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400 - 0x400057ff: I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800 - 0x40005Bff: I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00 - 0x40005fff: USB device FS registers */ +#define STM32_USBRAM_BASE 0x40006000 /* 0x40006000 - 0x400063ff: Shared USB/CAN SRAM 512 bytes */ +#define STM32_CANRAM_BASE 0x40006000 /* 0x40006000 - 0x400063ff: Shared USB/CAN SRAM 512 bytes */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400 - 0x400067ff: bxCAN1 */ +#define STM32_CAN2_BASE 0x40006800 /* 0x40006800 - 0x40006bff: bxCAN2 */ +#define STM32_BKP_BASE 0x40006c00 /* 0x40006c00 - 0x40006fff: Backup registers (BKP) */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000 - 0x400073ff: Power control PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400 - 0x400077ff: DAC */ +#define STM32_CEC_BASE 0x40007800 /* 0x40007800 - 0x40007bff: CEC */ + /* 0x40007c00 - 0x4000ffff: Reserved */ +/* APB2 bus */ + +#define STM32_AFIO_BASE 0x40010000 /* 0x40010000 - 0x400103ff: AFIO */ +#define STM32_EXTI_BASE 0x40010400 /* 0x40010400 - 0x400107ff: EXTI */ +#define STM32_GPIOA_BASE 0x40010800 /* 0x40010800 - 0x40010bff: GPIO Port A */ +#define STM32_GPIOB_BASE 0X40010c00 /* 0X40010c00 - 0x40010fff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x40011000 /* 0x40011000 - 0x400113ff: GPIO Port C */ +#define STM32_GPIOD_BASE 0x40011400 /* 0x40011400 - 0x400117ff: GPIO Port D */ +#define STM32_GPIOE_BASE 0x40011800 /* 0x40011800 - 0x40011bff: GPIO Port E */ +#define STM32_GPIOF_BASE 0x40011c00 /* 0x4001c000 - 0x400111ff: GPIO Port F */ +#define STM32_GPIOG_BASE 0x40012000 /* 0x40012000 - 0x400123ff: GPIO Port G */ +#define STM32_ADC1_BASE 0x40012400 /* 0x40012400 - 0x400127ff: ADC1 */ +#define STM32_ADC2_BASE 0x40012800 /* 0x40012800 - 0x40012bff: ADC2 */ +#define STM32_TIM1_BASE 0x40012c00 /* 0x40012c00 - 0x40012fff: TIM1 timer */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000 - 0x400133ff: SPI1 */ +#define STM32_TIM8_BASE 0x40013400 /* 0x40013400 - 0x400137ff: TIM8 timer */ +#define STM32_USART1_BASE 0x40013800 /* 0x40013800 - 0x40013bff: USART1 */ +#define STM32_ADC3_BASE 0x40012800 /* 0x40012800 - 0x40013c00: ADC3 */ + /* 0x40013c00 - 0x40013fff: Reserved */ +#define STM32_TIM15_BASE 0x40014400 /* 0x40014400 - 0x400147ff: TIM15 */ +#define STM32_TIM16_BASE 0x40014400 /* 0x40014400 - 0x400147ff: TIM16 */ +#define STM32_TIM17_BASE 0x40014800 /* 0x40014800 - 0x40014bff: TIM17 */ + /* 0x40014c00 - 0x4001ffff: Reserved */ + +/* AHB bus */ + +#define STM32_SDIO_BASE 0x40018000 /* 0x40018000 - 0x400183ff: SDIO */ + /* 0x40018400 - 0x40017fff: Reserved */ +#define STM32_DMA1_BASE 0x40020000 /* 0x40020000 - 0x400203ff: DMA1 */ +#define STM32_DMA2_BASE 0x40020400 /* 0x40020000 - 0x400207ff: DMA2 */ + /* 0x40020800 - 0x40020fff: Reserved */ +#define STM32_RCC_BASE 0x40021000 /* 0x40021000 - 0x400213ff: Reset and Clock control RCC */ + /* 0x40021400 - 0x40021fff: Reserved */ +#define STM32_OTGFS_BASE 0x50000000 /* 0x50000000 - 0x500003ff: USB OTG FS */ +#define STM32_FLASHIF_BASE 0x40022000 /* 0x40022000 - 0x400223ff: Flash memory interface */ +#define STM32_CRC_BASE 0x40028000 /* 0x40023000 - 0x400233ff: CRC */ + /* 0x40023400 - 0x40027fff: Reserved */ +#define STM32_ETHERNET_BASE 0x40028000 /* 0x40028000 - 0x40029fff: Ethernet */ + /* 0x40030000 - 0x4fffffff: Reserved */ + +/* Peripheral BB base */ + +#define STM32_PERIPHBB_BASE 0x42000000 + +/* Flexible SRAM controller (FSMC) */ + +#define STM32_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +#define STM32_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +#define STM32_FSMC_BANK4 0x90000000 /* 0x90000000-0x9fffffff: 256Mb PC CARD*/ +#define STM32_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_FSMC_BANK1) + +#define STM32_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: 512Mb FSMC register block */ + +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..35b2ad8156c2547103e02290501bcf97c4c7b96c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_rcc.h @@ -0,0 +1,468 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xx_rcc.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_RCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_CFGR_OFFSET 0x0004 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x0008 /* Clock interrupt register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x000c /* APB2 Peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0010 /* APB1 Peripheral reset register */ +#define STM32_RCC_AHBENR_OFFSET 0x0014 /* AHB Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0018 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x001c /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0020 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0024 /* Control/status register */ +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define STM32_RCC_AHBRSTR_OFFSET 0x0028 /* AHB Reset register */ +#endif +#if defined(CONFIG_STM32_VALUELINE) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_RCC_CFGR2_OFFSET 0x002c /* Clock configuration register 2 */ +#endif + +/* Register Addresses ***************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_AHBENR (STM32_RCC_BASE+STM32_RCC_AHBENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define STM32_RCC_AHBRSTR (STM32_RCC_BASE+STM32_RCC_AHBRSTR_OFFSET) +#endif +#if defined(CONFIG_STM32_VALUELINE) || defined(CONFIG_STM32_CONNECTIVITYLINE) +# define STM32_RCC_CFGR2 (STM32_RCC_BASE+STM32_RCC_CFGR2_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define RCC_CR_PLL2ON (1 << 26) /* Bit 26: PLL2 enable */ +# define RCC_CR_PLL2RDY (1 << 27) /* Bit 27: PLL2 clock ready flag */ +# define RCC_CR_PLL3ON (1 << 28) /* Bit 28: PLL3 enable */ +# define RCC_CR_PLL3RDY (1 << 29) /* Bit 29: PLL3 ready flag */ +#endif + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 1-0: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 3-2: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 7-4: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 10-8: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 13-11: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_ADCPRE_SHIFT (14) /* Bits 15-14: ADC prescaler */ +#define RCC_CFGR_ADCPRE_MASK (3 << RCC_CFGR_ADCPRE_SHIFT) +# define RCC_CFGR_PLCK2d2 (0 << RCC_CFGR_ADCPRE_SHIFT) /* 00: PLCK2 divided by 2 */ +# define RCC_CFGR_PLCK2d4 (1 << RCC_CFGR_ADCPRE_SHIFT) /* 01: PLCK2 divided by 4 */ +# define RCC_CFGR_PLCK2d6 (2 << RCC_CFGR_ADCPRE_SHIFT) /* 10: PLCK2 divided by 6 */ +# define RCC_CFGR_PLCK2d8 (3 << RCC_CFGR_ADCPRE_SHIFT) /* 11: PLCK2 divided by 8 */ +#define RCC_CFGR_PLLSRC (1 << 16) /* Bit 16: PLL entry clock source */ +#define RCC_CFGR_PLLXTPRE (1 << 17) /* Bit 17: HSE divider for PLL entry */ +#define RCC_CFGR_PLLMUL_SHIFT (18) /* Bits 21-18: PLL Multiplication Factor */ +#define RCC_CFGR_PLLMUL_MASK (0x0f << RCC_CFGR_PLLMUL_SHIFT) +# define RCC_CFGR_PLLMUL_CLKx2 (0 << RCC_CFGR_PLLMUL_SHIFT) /* 0000: PLL input clock x 2 */ +# define RCC_CFGR_PLLMUL_CLKx3 (1 << RCC_CFGR_PLLMUL_SHIFT) /* 0001: PLL input clock x 3 */ +# define RCC_CFGR_PLLMUL_CLKx4 (2 << RCC_CFGR_PLLMUL_SHIFT) /* 0010: PLL input clock x 4 */ +# define RCC_CFGR_PLLMUL_CLKx5 (3 << RCC_CFGR_PLLMUL_SHIFT) /* 0011: PLL input clock x 5 */ +# define RCC_CFGR_PLLMUL_CLKx6 (4 << RCC_CFGR_PLLMUL_SHIFT) /* 0100: PLL input clock x 6 */ +# define RCC_CFGR_PLLMUL_CLKx7 (5 << RCC_CFGR_PLLMUL_SHIFT) /* 0101: PLL input clock x 7 */ +# define RCC_CFGR_PLLMUL_CLKx8 (6 << RCC_CFGR_PLLMUL_SHIFT) /* 0110: PLL input clock x 8 */ +# define RCC_CFGR_PLLMUL_CLKx9 (7 << RCC_CFGR_PLLMUL_SHIFT) /* 0111: PLL input clock x 9 */ +# define RCC_CFGR_PLLMUL_CLKx10 (8 << RCC_CFGR_PLLMUL_SHIFT) /* 1000: PLL input clock x 10 */ +# define RCC_CFGR_PLLMUL_CLKx11 (9 << RCC_CFGR_PLLMUL_SHIFT) /* 1001: PLL input clock x 11 */ +# define RCC_CFGR_PLLMUL_CLKx12 (10 << RCC_CFGR_PLLMUL_SHIFT) /* 1010: PLL input clock x 12 */ +# define RCC_CFGR_PLLMUL_CLKx13 (11 << RCC_CFGR_PLLMUL_SHIFT) /* 1011: PLL input clock x 13 */ +# define RCC_CFGR_PLLMUL_CLKx14 (12 << RCC_CFGR_PLLMUL_SHIFT) /* 1100: PLL input clock x 14 */ +# define RCC_CFGR_PLLMUL_CLKx15 (13 << RCC_CFGR_PLLMUL_SHIFT) /* 1101: PLL input clock x 15 */ +# define RCC_CFGR_PLLMUL_CLKx16 (14 << RCC_CFGR_PLLMUL_SHIFT) /* 111x: PLL input clock x 16 */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_CFGR_USBPRE (1 << 22) /* Bit 22: USB FS prescaler */ +#endif +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define RCC_CFGR_OTGFSPRE (1 << 22) /* Bit 22: OTG FS prescaler */ +#endif +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 27-24: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (15 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_NOCLK (0 << RCC_CFGR_MCO_SHIFT) /* 00xx: No clock */ +# define RCC_CFGR_SYSCLK (4 << RCC_CFGR_MCO_SHIFT) /* 0100: System clock selected */ +# define RCC_CFGR_INTCLK (5 << RCC_CFGR_MCO_SHIFT) /* 0101: Internal 8 MHz RC oscillator clock selected */ +# define RCC_CFGR_EXTCLK (6 << RCC_CFGR_MCO_SHIFT) /* 0110: External 1-25 MHz oscillator clock selected */ +# define RCC_CFGR_PLLCLKd2 (7 << RCC_CFGR_MCO_SHIFT) /* 0111: PLL clock divided by 2 selected */ +# define RCC_CFGR_PLL2CLK (8 << RCC_CFGR_MCO_SHIFT) /* 1000: PLL2 clock selected */ +# define RCC_CFGR_PLL3CLKd2 (9 << RCC_CFGR_MCO_SHIFT) /* 1001: PLL3 clock devided by 2 selected */ +# define RCC_CFGR_XT1 (10 << RCC_CFGR_MCO_SHIFT) /* 1010: external 3-25 MHz oscillator clock selected (for Ethernet) */ +# define RCC_CFGR_PLL3CLK (11 << RCC_CFGR_MCO_SHIFT) /* 1011: PLL3 clock selected (for Ethernet) */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_AFIORST (1 << 0) /* Bit 0: Alternate Function I/O reset */ +#define RCC_APB2RSTR_IOPARST (1 << 2) /* Bit 2: I/O port A reset */ +#define RCC_APB2RSTR_IOPBRST (1 << 3) /* Bit 3: IO port B reset */ +#define RCC_APB2RSTR_IOPCRST (1 << 4) /* Bit 4: IO port C reset */ +#define RCC_APB2RSTR_IOPDRST (1 << 5) /* Bit 5: IO port D reset */ +#define RCC_APB2RSTR_IOPERST (1 << 6) /* Bit 6: IO port E reset */ +#define RCC_APB2RSTR_IOPFRST (1 << 7) /* Bit 7: IO port F reset */ +#define RCC_APB2RSTR_IOPGRST (1 << 8) /* Bit 8: IO port G reset */ +#define RCC_APB2RSTR_ADC1RST (1 << 9) /* Bit 9: ADC 1 interface reset */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2RSTR_ADC2RST (1 << 10) /* Bit 10: ADC 2 interface reset */ +#endif +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 Timer reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 Timer reset */ +#endif +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2RSTR_ADC3RST (1 << 15) /* Bit 15: ADC3 interface reset */ +#else +# define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +# define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +# define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#endif + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: Timer 4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 3: Timer 5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: Timer 6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: Timer 7 reset */ +#ifdef CONFIG_STM32_VALUELINE +# define RCC_APB1RSTR_TIM12RST (1 << 6) /* Bit 6: TIM12 reset */ +# define RCC_APB1RSTR_TIM13RST (1 << 7) /* Bit 7: TIM13 reset */ +# define RCC_APB1RSTR_TIM14RST (1 << 8) /* Bit 8: TIM14 reset */ +#endif +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window Watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: UART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: UART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB1RSTR_USBRST (1 << 23) /* Bit 23: USB reset */ +# define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +# define RCC_APB1RSTR_CAN2RST (1 << 26) /* Bit 26: CAN2 reset */ +#endif +#define RCC_APB1RSTR_BKPRST (1 << 27) /* Bit 27: Backup interface reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC interface reset */ +#ifdef CONFIG_STM32_VALUELINE +# define RCC_APB1RSTR_CECRST (1 << 30) /* Bit 30: CEC reset */ +#endif + +/* AHB Peripheral Clock enable register */ + +#define RCC_AHBENR_DMA1EN (1 << 0) /* Bit 0: DMA1 clock enable */ +#define RCC_AHBENR_DMA2EN (1 << 1) /* Bit 1: DMA2 clock enable */ +#define RCC_AHBENR_SRAMEN (1 << 2) /* Bit 2: SRAM interface clock enable */ +#define RCC_AHBENR_FLITFEN (1 << 4) /* Bit 4: FLITF clock enable */ +#define RCC_AHBENR_CRCEN (1 << 6) /* Bit 6: CRC clock enable */ +#define RCC_AHBENR_FSMCEN (1 << 8) /* Bit 8: FSMC clock enable */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_AHBENR_SDIOEN (1 << 10) /* Bit 10: SDIO clock enable */ +#endif +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define RCC_AHBENR_OTGFSEN (1 << 12) /* Bit 12: USB OTG FS clock enable */ +# define RCC_AHBENR_ETHMACEN (1 << 14) /* Bit 14: Ethernet MAC clock enable */ +# define RCC_AHBENR_ETHMACTXEN (1 << 15) /* Bit 15: Ethernet MAC TX clock enable */ +# define RCC_AHBENR_ETHMACRXEN (1 << 16) /* Bit 16: Ethernet MAC RX clock enable */ +#endif + +/* AHB peripheral clock reset register (RCC_AHBRSTR) */ + +#ifdef CONFIG_STM32_CONNECTIVITYLINE +# define RCC_AHBRSTR_OTGFSRST (1 << 12) /* USB OTG FS reset */ +# define RCC_AHBRSTR_ETHMACRST (1 << 14) /* Ethernet MAC reset */ +#endif + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_AFIOEN (1 << 0) /* Bit 0: Alternate Function I/O clock enable */ +#define RCC_APB2ENR_IOPEN(n) (1 << ((n)+2)) +#define RCC_APB2ENR_IOPAEN (1 << 2) /* Bit 2: I/O port A clock enable */ +#define RCC_APB2ENR_IOPBEN (1 << 3) /* Bit 3: I/O port B clock enable */ +#define RCC_APB2ENR_IOPCEN (1 << 4) /* Bit 4: I/O port C clock enable */ +#define RCC_APB2ENR_IOPDEN (1 << 5) /* Bit 5: I/O port D clock enable */ +#define RCC_APB2ENR_IOPEEN (1 << 6) /* Bit 6: I/O port E clock enable */ +#define RCC_APB2ENR_IOPFEN (1 << 7) /* Bit 7: I/O port F clock enable */ +#define RCC_APB2ENR_IOPGEN (1 << 8) /* Bit 8: I/O port G clock enable */ +#define RCC_APB2ENR_ADC1EN (1 << 9) /* Bit 9: ADC 1 interface clock enable */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2ENR_ADC2EN (1 << 10) /* Bit 10: ADC 2 interface clock enable */ +#endif +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 Timer clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI 1 clock enable */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 Timer clock enable */ +#endif +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB2ENR_ADC3EN (1 << 15) /* Bit 14: ADC3 interface clock enable */ +#else +# define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 clock enable */ +# define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 clock enable */ +# define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 clock enable */ +#endif + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: Timer 4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 3: Timer 5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: Timer 6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: Timer 7 clock enable */ +#ifdef CONFIG_STM32_VALUELINE +# define RCC_APB1ENR_TIM12EN (1 << 6) /* Bit 6: Timer 12 clock enable */ +# define RCC_APB1ENR_TIM13EN (1 << 7) /* Bit 7: Timer 13 clock enable */ +# define RCC_APB1ENR_TIM14EN (1 << 8) /* Bit 8: Timer 14 clock enable */ +#endif +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window Watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI 3 clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART 4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART 5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C 2 clock enable */ +#ifndef CONFIG_STM32_VALUELINE +# define RCC_APB1ENR_USBEN (1 << 23) /* Bit 23: USB clock enable */ +# define RCC_APB1ENR_CAN1EN (1 << 25) /* Bit 25: CAN1 clock enable */ +# define RCC_APB1ENR_CAN2EN (1 << 26) /* Bit 25: CAN2 clock enable */ +#endif +#define RCC_APB1ENR_BKPEN (1 << 27) /* Bit 27: Backup interface clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ +#ifdef CONFIG_STM32_VALUELINE +# define RCC_APB1ENR_CECEN (1 << 30) /* Bit 30: CEC clock enable */ +#endif + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +#if defined(CONFIG_STM32_VALUELINE) || defined(CONFIG_STM32_CONNECTIVITYLINE) + +/* Clock configuration register 2 (For value line and connectivity line only) */ + +#define RCC_CFGR2_PREDIV1_SHIFT (0) +#define RCC_CFGR2_PREDIV1_MASK (0x0f << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d1 (0 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d2 (1 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d3 (2 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d4 (3 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d5 (4 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d6 (5 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d7 (6 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d8 (7 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d9 (8 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d10 (9 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d11 (10 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d12 (11 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d13 (12 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d14 (13 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d15 (14 << RCC_CFGR2_PREDIV1_SHIFT) +# define RCC_CFGR2_PREDIV1d16 (15 << RCC_CFGR2_PREDIV1_SHIFT) + +#endif + +#ifdef CONFIG_STM32_CONNECTIVITYLINE + +#define RCC_CFGR2_PREDIV2_SHIFT (4) +#define RCC_CFGR2_PREDIV2_MASK (0x0f << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d1 (0 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d2 (1 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d3 (2 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d4 (3 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d5 (4 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d6 (5 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d7 (6 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d8 (7 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d9 (8 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d10 (9 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d11 (10 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d12 (11 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d13 (12 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d14 (13 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d15 (14 << RCC_CFGR2_PREDIV2_SHIFT) +# define RCC_CFGR2_PREDIV2d16 (15 << RCC_CFGR2_PREDIV2_SHIFT) + +#define RCC_CFGR2_PLL2MUL_SHIFT (8) +#define RCC_CFGR2_PLL2MUL_MASK (0x0f << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx8 (6 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx9 (7 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx10 (8 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx11 (9 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx12 (10 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx13 (11 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx14 (12 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx16 (14 << RCC_CFGR2_PLL2MUL_SHIFT) +# define RCC_CFGR2_PLL2MULx20 (15 << RCC_CFGR2_PLL2MUL_SHIFT) + +#define RCC_CFGR2_PLL3MUL_SHIFT (12) +#define RCC_CFGR2_PLL3MUL_MASK (0x0f << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx8 (6 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx9 (7 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx10 (8 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx11 (9 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx12 (10 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx13 (11 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx14 (12 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx16 (14 << RCC_CFGR2_PLL3MUL_SHIFT) +# define RCC_CFGR2_PLL3MULx20 (15 << RCC_CFGR2_PLL3MUL_SHIFT) + +#define RCC_CFGR2_PREDIV1SRC_SHIFT (16) +#define RCC_CFGR2_PREDIV1SRC_MASK (0x01 << RCC_CFGR2_PREDIV1SRC_SHIFT) +# define RCC_CFGR2_PREDIV1SRC_HSE (0 << RCC_CFGR2_PREDIV1SRC_SHIFT) +# define RCC_CFGR2_PREDIV1SRC_PLL2 (1 << RCC_CFGR2_PREDIV1SRC_SHIFT) + +#define RCC_CFGR2_I2S2SRC_SHIFT (17) +#define RCC_CFGR2_I2S2SRC_MASK (0x01 << RCC_CFGR2_I2S2SRC_SHIFT) +# define RCC_CFGR2_I2S2SRC_SYSCLK (0 << RCC_CFGR2_I2S2SRC_SHIFT) +# define RCC_CFGR2_I2S2SRC_PLL3 (1 << RCC_CFGR2_I2S2SRC_SHIFT) + +#define RCC_CFGR2_I2S3SRC_SHIFT (17) +#define RCC_CFGR2_I2S3SRC_MASK (0x01 << RCC_CFGR2_I2S3SRC_SHIFT) +# define RCC_CFGR2_I2S3SRC_SYSCLK (0 << RCC_CFGR2_I2S3SRC_SHIFT) +# define RCC_CFGR2_I2S3SRC_PLL3 (1 << RCC_CFGR2_I2S3SRC_SHIFT) + +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F10XXX_RCC_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_uart.h b/arch/arm/src/stm32/chip/stm32f10xxx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..414f34c9094418a70983a7e54af1a63d54eb2056 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_uart.h @@ -0,0 +1,217 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xxx_uart.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32F10XXX_UART_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32F10XXX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_SR_OFFSET 0x0000 /* Status register (32-bits) */ +#define STM32_USART_DR_OFFSET 0x0004 /* Data register (32-bits) */ +#define STM32_USART_BRR_OFFSET 0x0008 /* Baud Rate Register (32-bits) */ +#define STM32_USART_CR1_OFFSET 0x000c /* Control register 1 (32-bits) */ +#define STM32_USART_CR2_OFFSET 0x0010 /* Control register 2 (32-bits) */ +#define STM32_USART_CR3_OFFSET 0x0014 /* Control register 3 (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0018 /* Guard time and prescaler register (32-bits) */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NUSART > 0 +# define STM32_USART1_SR (STM32_USART1_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART1_DR (STM32_USART1_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_SR (STM32_USART2_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART2_DR (STM32_USART2_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_SR (STM32_USART3_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART3_DR (STM32_USART3_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_SR (STM32_UART4_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART4_DR (STM32_UART4_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_SR (STM32_UART5_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART5_DR (STM32_UART5_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Status register */ + +#define USART_SR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_SR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_SR_NE (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_SR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_SR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_SR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_SR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_SR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_SR_LBD (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_SR_CTS (1 << 9) /* Bit 9: CTS Flag */ + +#define USART_SR_ALLBITS (0x03ff) +#define USART_SR_CLRBITS (USART_SR_CTS|USART_SR_LBD) /* Cleared by SW write to SR */ + +/* Data register */ + +#define USART_DR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_DR_MASK (0xff << USART_DR_SHIFT) + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Control register 1 */ + +#define USART_CR1_SBK (1 << 0) /* Bit 0: Send Break */ +#define USART_CR1_RWU (1 << 1) /* Bit 1: Receiver wakeup */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M (1 << 12) /* Bit 12: word length */ +#define USART_CR1_UE (1 << 13) /* Bit 13: USART Enable */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE|USART_CR1_TCIE|USART_CR1_PEIE) + +/* Control register 2 */ + +#define USART_CR2_ADD_SHIFT (0) /* Bits 3-0: Address of the USART node */ +#define USART_CR2_ADD_MASK (0x0f << USART_CR2_ADD_SHIFT) +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Compatibility definitions ********************************************************/ +/* F3 Transmit/Read registers */ + +#define STM32_USART_RDR_OFFSET STM32_USART_DR_OFFSET /* Receive data register */ +#define STM32_USART_TDR_OFFSET STM32_USART_DR_OFFSET /* Transmit data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32F10XXX_UART_H */ diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h b/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..24822c37d3eae5237c93f560f397d9d725263771 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f10xxx_vectors.h @@ -0,0 +1,284 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f10xxx_vectors.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies ach STM32F10xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f10xxx_irq.h. + * stm32_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +#if defined(CONFIG_STM32_VALUELINE) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 61 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 61 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* Vector 16+0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* Vector 16+1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* Vector 16+2: Tamper interrupt */ +VECTOR(stm32_rtc, STM32_IRQ_RTC) /* Vector 16+3: RTC Wakeup through EXTI line interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* Vector 16+4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* Vector 16+5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* Vector 16+6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* Vector 16+7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* Vector 16+8: EXTI Line 2 interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* Vector 16+9: EXTI Line 3 interrupt */ +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* Vector 16+10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* Vector 16+11: DMA1 Channel 1 global interrupt */ +VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* Vector 16+12: DMA1 Channel 2 global interrupt */ +VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* Vector 16+13: DMA1 Channel 3 global interrupt */ +VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* Vector 16+14: DMA1 Channel 4 global interrupt */ +VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* Vector 16+15: DMA1 Channel 5 global interrupt */ +VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* Vector 16+16: DMA1 Channel 6 global interrupt */ +VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* Vector 16+17: DMA1 Channel 7 global interrupt */ +VECTOR(stm32_adc1, STM32_IRQ_ADC1) /* Vector 16+18: ADC1 global interrupt */ +UNUSED(STM32_IRQ_RESERVED0) /* Vector 16+19: Reserved 0 */ +UNUSED(STM32_IRQ_RESERVED1) /* Vector 16+20: Reserved 1 */ +UNUSED(STM32_IRQ_RESERVED2) /* Vector 16+21: Reserved 2 */ +UNUSED(STM32_IRQ_RESERVED3) /* Vector 16+22: Reserved 3 */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* Vector 16+23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* Vector 16+24: TIM1 Break interrupt; TIM15 global interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* Vector 16+25: TIM1 Update interrupt; TIM16 global interrupt */ +VECTOR(stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM) /* Vector 16+26: TIM1 Trigger and Commutation interrupts; TIM17 global interrupt */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* Vector 16+27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* Vector 16+28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* Vector 16+29: TIM3 global interrupt */ +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* Vector 16+30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* Vector 16+31: I2C1 event interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* Vector 16+32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* Vector 16+33: I2C2 event interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* Vector 16+34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* Vector 16+35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* Vector 16+36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* Vector 16+37: USART1 global interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* Vector 16+38: USART2 global interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* Vector 16+39: USART3 global interrupt */ +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* Vector 16+40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalr, STM32_IRQ_RTCALR) /* Vector 16+41: RTC alarms (A and B) through EXTI line interrupt */ +VECTOR(stm32_cec, STM32_IRQ_CEC) /* Vector 16+42: CEC global interrupt */ +VECTOR(stm32_tim12, STM32_IRQ_TIM12) /* Vector 16+43: TIM12 global interrupt */ +VECTOR(stm32_tim13, STM32_IRQ_TIM13) /* Vector 16+44: TIM13 global interrupt */ +VECTOR(stm32_tim14, STM32_IRQ_TIM14) /* Vector 16+45: TIM14 global interrupt */ +UNUSED(STM32_IRQ_RESERVED4) /* Vector 16+46: Reserved 4 */ +UNUSED(STM32_IRQ_RESERVED5) /* Vector 16+47: Reserved 5 */ +VECTOR(stm32_fsmc, STM32_IRQ_FSMC) /* Vector 16+48: FSMC global interrupt */ +UNUSED(STM32_IRQ_RESERVED6) /* Vector 16+49: Reserved 6 */ +VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* Vector 16+50: TIM5 global interrupt */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* Vector 16+51: SPI3 global interrupt */ +VECTOR(stm32_uart4, STM32_IRQ_UART4) /* Vector 16+52: USART2 global interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* Vector 16+53: USART5 global interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* Vector 16+54: TIM6 global interrupt */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* Vector 16+55: TIM7 global interrupt */ +VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* Vector 16+56: DMA2 Channel 1 global interrupt */ +VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* Vector 16+57: DMA2 Channel 2 global interrupt */ +VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* Vector 16+58: DMA2 Channel 3 global interrupt */ +VECTOR(stm32_dma2ch45, STM32_IRQ_DMA2CH45) /* Vector 16+59: DMA2 Channel 4 and 5 global interrupt */ +VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* Vector 16+60: DMA2 Channel 5 global interrupt */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#elif defined(CONFIG_STM32_CONNECTIVITYLINE) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 68 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 68 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* Vector 16+0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* Vector 16+1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* Vector 16+2: Tamper interrupt */ +VECTOR(stm32_rtc, STM32_IRQ_RTC) /* Vector 16+3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* Vector 16+4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* Vector 16+5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* Vector 16+6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* Vector 16+7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* Vector 16+8: EXTI Line 2 interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* Vector 16+9: EXTI Line 3 interrupt */ +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* Vector 16+10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* Vector 16+11: DMA1 Channel 1 global interrupt */ +VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* Vector 16+12: DMA1 Channel 2 global interrupt */ +VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* Vector 16+13: DMA1 Channel 3 global interrupt */ +VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* Vector 16+14: DMA1 Channel 4 global interrupt */ +VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* Vector 16+15: DMA1 Channel 5 global interrupt */ +VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* Vector 16+16: DMA1 Channel 6 global interrupt */ +VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* Vector 16+17: DMA1 Channel 7 global interrupt */ +VECTOR(stm32_adc12, STM32_IRQ_ADC12) /* Vector 16+18: ADC1 and ADC2 global interrupt */ +VECTOR(stm32_can1tx, STM32_IRQ_CAN1TX) /* Vector 16+19: CAN1 TX interrupts */ +VECTOR(stm32_can1rx0, STM32_IRQ_CAN1RX0) /* Vector 16+20: CAN1 RX0 interrupts */ +VECTOR(stm32_can1rx, STM32_IRQ_CAN1RX1) /* Vector 16+21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* Vector 16+22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* Vector 16+23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* Vector 16+24: TIM1 Break interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* Vector 16+25: TIM1 Update interrupt */ +VECTOR(stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM) /* Vector 16+26: TIM1 Trigger and Commutation interrupts */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* Vector 16+27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* Vector 16+28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* Vector 16+29: TIM3 global interrupt */ +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* Vector 16+30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* Vector 16+31: I2C1 event interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* Vector 16+32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* Vector 16+33: I2C2 event interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* Vector 16+34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* Vector 16+35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* Vector 16+36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* Vector 16+37: USART1 global interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* Vector 16+38: USART2 global interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* Vector 16+39: USART3 global interrupt */ +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* Vector 16+40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalr, STM32_IRQ_RTCALRM) /* Vector 16+41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_otgfswkup, STM32_IRQ_OTGFSWKUP) /* Vector 16+42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +UNUSED(STM32_IRQ_RESERVED0) /* Vector 16+43: Reserved 0 */ +UNUSED(STM32_IRQ_RESERVED1) /* Vector 16+44: Reserved 1 */ +UNUSED(STM32_IRQ_RESERVED2) /* Vector 16+55: Reserved 2 */ +UNUSED(STM32_IRQ_RESERVED3) /* Vector 16+46: Reserved 3 */ +UNUSED(STM32_IRQ_RESERVED4) /* Vector 16+47: Reserved 4 */ +UNUSED(STM32_IRQ_RESERVED5) /* Vector 16+48: Reserved 5 */ +UNUSED(STM32_IRQ_RESERVED6) /* Vector 16+49: Reserved 6 */ +VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* Vector 16+50: TIM5 global interrupt */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3 ) /* Vector 16+51: SPI3 global interrupt */ +VECTOR(stm32_uart4 , STM32_IRQ_UART4) /* Vector 16+52: UART4 global interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* Vector 16+53: UART5 global interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* Vector 16+54: TIM6 global interrupt */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* Vector 16+55: TIM7 global interrupt */ +VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* Vector 16+56: DMA2 Channel 1 global interrupt */ +VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* Vector 16+57: DMA2 Channel 2 global interrupt */ +VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* Vector 16+58: DMA2 Channel 3 global interrupt */ +VECTOR(stm32_dma2ch4, STM32_IRQ_DMA2CH4) /* Vector 16+59: DMA2 Channel 4 global interrupt */ +VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* Vector 16+60: DMA2 Channel 5 global interrupt */ +VECTOR(stm32_eth, STM32_IRQ_ETH) /* Vector 16+61: Ethernet global interrupt */ +VECTOR(stm32_ethwkup, STM32_IRQ_ETHWKUP) /* Vector 16+62: Ethernet Wakeup through EXTI line interrupt */ +VECTOR(stm32_can2tx, STM32_IRQ_CAN2TX) /* Vector 16+63: CAN2 TX interrupts */ +VECTOR(stm32_can2rx0, STM32_IRQ_CAN2RX0) /* Vector 16+64: CAN2 RX0 interrupts */ +VECTOR(stm32_can2rx1, STM32_IRQ_CAN2RX1) /* Vector 16+65: CAN2 RX1 interrupt */ +VECTOR(stm32_can2sce, STM32_IRQ_CAN2SCE) /* Vector 16+66: CAN2 SCE interrupt */ +VECTOR(stm32_otgfs, STM32_IRQ_OTGFS) /* Vector 16+67: USB On The Go FS global interrupt */ + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ +#else /* CONFIG_STM32_CONNECTIVITYLINE */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 60 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 60 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* Vector 16+0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* Vector 16+1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* Vector 16+2: Tamper interrupt */ +VECTOR(stm32_rtc, STM32_IRQ_RTC) /* Vector 16+3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* Vector 16+4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* Vector 16+5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* Vector 16+6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* Vector 16+7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* Vector 16+8: EXTI Line 2 interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* Vector 16+9: EXTI Line 3 interrupt */ +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* Vector 16+10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* Vector 16+11: DMA1 Channel 1 global interrupt */ +VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* Vector 16+12: DMA1 Channel 2 global interrupt */ +VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* Vector 16+13: DMA1 Channel 3 global interrupt */ +VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* Vector 16+14: DMA1 Channel 4 global interrupt */ +VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* Vector 16+15: DMA1 Channel 5 global interrupt */ +VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* Vector 16+16: DMA1 Channel 6 global interrupt */ +VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* Vector 16+17: DMA1 Channel 7 global interrupt */ +VECTOR(stm32_adc12, STM32_IRQ_ADC12) /* Vector 16+18: ADC1 and ADC2 global interrupt */ +VECTOR(stm32_usbhpcantx, STM32_IRQ_USBHPCANTX) /* Vector 16+19: USB High Priority or CAN TX interrupts*/ +VECTOR(stm32_usblpcanrx0, STM32_IRQ_USBLPCANRX0) /* Vector 16+20: USB Low Priority or CAN RX0 interrupts*/ +VECTOR(stm32_can1rx1, STM32_IRQ_CAN1RX1) /* Vector 16+21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* Vector 16+22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* Vector 16+23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* Vector 16+24: TIM1 Break interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* Vector 16+25: TIM1 Update interrupt */ +VECTOR(stm32_tim1rtgcom, STM32_IRQ_TIM1TRGCOM) /* Vector 16+26: TIM1 Trigger and Commutation interrupts */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* Vector 16+27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* Vector 16+28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* Vector 16+29: TIM3 global interrupt */ +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* Vector 16+30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* Vector 16+31: I2C1 event interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* Vector 16+32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* Vector 16+33: I2C2 event interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* Vector 16+34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* Vector 16+35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* Vector 16+36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* Vector 16+37: USART1 global interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* Vector 16+38: USART2 global interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* Vector 16+39: USART3 global interrupt */ +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* Vector 16+40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalr, STM32_IRQ_RTCALRM) /* Vector 16+41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP) /* Vector 16+42: USB wakeup from suspend through EXTI line interrupt*/ +VECTOR(stm32_tim8brk, STM32_IRQ_TIM8BRK) /* Vector 16+43: TIM8 Break interrupt */ +VECTOR(stm32_tim8up, STM32_IRQ_TIM8UP) /* Vector 16+44: TIM8 Update interrupt */ +VECTOR(stm32_tim8trgcom, STM32_IRQ_TIM8TRGCOM) /* Vector 16+45: TIM8 Trigger and Commutation interrupts */ +VECTOR(stm32_tim8cc, STM32_IRQ_TIM8CC) /* Vector 16+46: TIM8 Capture Compare interrupt */ +VECTOR(stm32_adc3, STM32_IRQ_ADC3) /* Vector 16+47: ADC3 global interrupt */ +VECTOR(stm32_fsmc, STM32_IRQ_FSMC) /* Vector 16+48: FSMC global interrupt */ +VECTOR(stm32_sdio, STM32_IRQ_SDIO) /* Vector 16+49: SDIO global interrupt */ +VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* Vector 16+50: TIM5 global interrupt */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* Vector 16+51: SPI3 global interrupt */ +VECTOR(stm32_uart4, STM32_IRQ_UART4) /* Vector 16+52: UART4 global interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* Vector 16+53: UART5 global interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* Vector 16+54: TIM6 global interrupt */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* Vector 16+55: TIM7 global interrupt */ +VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* Vector 16+56: DMA2 Channel 1 global interrupt */ +VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* Vector 16+57: DMA2 Channel 2 global interrupt */ +VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* Vector 16+58: DMA2 Channel 3 global interrupt */ +VECTOR(stm32_dma2ch45, STM32_IRQ_DMA2CH45) /* Vector 16+59: DMA2 Channel 4&5 global interrupt */ + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ +#endif /* CONFIG_STM32_CONNECTIVITYLINE */ diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_dma.h b/arch/arm/src/stm32/chip/stm32f20xxx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..f3660fb1dbd49705515655366312b23fe10e6e91 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_dma.h @@ -0,0 +1,520 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_dma.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_DMA_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_DMA_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* 2 DMA controllers */ + +#define DMA1 (0) +#define DMA2 (1) + +/* 8 DMA streams */ + +#define DMA_STREAM0 (0) +#define DMA_STREAM1 (1) +#define DMA_STREAM2 (2) +#define DMA_STREAM3 (3) +#define DMA_STREAM4 (4) +#define DMA_STREAM5 (5) +#define DMA_STREAM6 (6) +#define DMA_STREAM7 (7) + +/* 8 DMA channels */ + +#define DMA_CHAN0 (0) +#define DMA_CHAN1 (1) +#define DMA_CHAN2 (2) +#define DMA_CHAN3 (3) +#define DMA_CHAN4 (4) +#define DMA_CHAN5 (5) +#define DMA_CHAN6 (6) +#define DMA_CHAN7 (7) + +/* Register Offsets *****************************************************************/ + +#define STM32_DMA_LISR_OFFSET 0x0000 /* DMA low interrupt status register */ +#define STM32_DMA_HISR_OFFSET 0x0004 /* DMA high interrupt status register */ +#define STM32_DMA_LIFCR_OFFSET 0x0008 /* DMA low interrupt flag clear register */ +#define STM32_DMA_HIFCR_OFFSET 0x000c /* DMA high interrupt flag clear register */ + +#define STM32_DMA_OFFSET(n) (0x0010+0x0018*(n)) +#define STM32_DMA_SCR_OFFSET 0x0000 /* DMA stream n configuration register */ +#define STM32_DMA_SNDTR_OFFSET 0x0004 /* DMA stream n number of data register */ +#define STM32_DMA_SPAR_OFFSET 0x0008 /* DMA stream n peripheral address register */ +#define STM32_DMA_SM0AR_OFFSET 0x000c /* DMA stream n memory 0 address register */ +#define STM32_DMA_SM1AR_OFFSET 0x0010 /* DMA stream n memory 1 address register */ +#define STM32_DMA_SFCR_OFFSET 0x0014 /* DMA stream n FIFO control register */ + +#define STM32_DMA_S0CR_OFFSET 0x0010 /* DMA stream 0 configuration register */ +#define STM32_DMA_S1CR_OFFSET 0x0028 /* DMA stream 1 configuration register */ +#define STM32_DMA_S2CR_OFFSET 0x0040 /* DMA stream 2 configuration register */ +#define STM32_DMA_S3CR_OFFSET 0x0058 /* DMA stream 3 configuration register */ +#define STM32_DMA_S4CR_OFFSET 0x0070 /* DMA stream 4 configuration register */ +#define STM32_DMA_S5CR_OFFSET 0x0088 /* DMA stream 5 configuration register */ +#define STM32_DMA_S6CR_OFFSET 0x00a0 /* DMA stream 6 configuration register */ +#define STM32_DMA_S7CR_OFFSET 0x00b8 /* DMA stream 7 configuration register */ + +#define STM32_DMA_S0NDTR_OFFSET 0x0014 /* DMA stream 0 number of data register */ +#define STM32_DMA_S1NDTR_OFFSET 0x002c /* DMA stream 1 number of data register */ +#define STM32_DMA_S2NDTR_OFFSET 0x0044 /* DMA stream 2 number of data register */ +#define STM32_DMA_S3NDTR_OFFSET 0x005c /* DMA stream 3 number of data register */ +#define STM32_DMA_S4NDTR_OFFSET 0x0074 /* DMA stream 4 number of data register */ +#define STM32_DMA_S5NDTR_OFFSET 0x008c /* DMA stream 5 number of data register */ +#define STM32_DMA_S6NDTR_OFFSET 0x00a4 /* DMA stream 6 number of data register */ +#define STM32_DMA_S7NDTR_OFFSET 0x00bc /* DMA stream 7 number of data register */ + +#define STM32_DMA_S0PAR_OFFSET 0x0018 /* DMA stream 0 peripheral address register */ +#define STM32_DMA_S1PAR_OFFSET 0x0030 /* DMA stream 1 peripheral address register */ +#define STM32_DMA_S2PAR_OFFSET 0x0048 /* DMA stream 2 peripheral address register */ +#define STM32_DMA_S3PAR_OFFSET 0x0060 /* DMA stream 3 peripheral address register */ +#define STM32_DMA_S4PAR_OFFSET 0x0078 /* DMA stream 4 peripheral address register */ +#define STM32_DMA_S5PAR_OFFSET 0x0090 /* DMA stream 5 peripheral address register */ +#define STM32_DMA_S6PAR_OFFSET 0x00a8 /* DMA stream 6 peripheral address register */ +#define STM32_DMA_S7PAR_OFFSET 0x00c0 /* DMA stream 7 peripheral address register */ + +#define STM32_DMA_S0M0AR_OFFSET 0x001c /* DMA stream 0 memory 0 address register */ +#define STM32_DMA_S1M0AR_OFFSET 0x0034 /* DMA stream 1 memory 0 address register */ +#define STM32_DMA_S2M0AR_OFFSET 0x004c /* DMA stream 2 memory 0 address register */ +#define STM32_DMA_S3M0AR_OFFSET 0x0064 /* DMA stream 3 memory 0 address register */ +#define STM32_DMA_S4M0AR_OFFSET 0x007c /* DMA stream 4 memory 0 address register */ +#define STM32_DMA_S5M0AR_OFFSET 0x0094 /* DMA stream 5 memory 0 address register */ +#define STM32_DMA_S6M0AR_OFFSET 0x00ac /* DMA stream 6 memory 0 address register */ +#define STM32_DMA_S7M0AR_OFFSET 0x00c4 /* DMA stream 7 memory 0 address register */ + +#define STM32_DMA_S0M1AR_OFFSET 0x0020 /* DMA stream 0 memory 1 address register */ +#define STM32_DMA_S1M1AR_OFFSET 0x0038 /* DMA stream 1 memory 1 address register */ +#define STM32_DMA_S2M1AR_OFFSET 0x0050 /* DMA stream 2 memory 1 address register */ +#define STM32_DMA_S3M1AR_OFFSET 0x0068 /* DMA stream 3 memory 1 address register */ +#define STM32_DMA_S4M1AR_OFFSET 0x0080 /* DMA stream 4 memory 1 address register */ +#define STM32_DMA_S5M1AR_OFFSET 0x0098 /* DMA stream 5 memory 1 address register */ +#define STM32_DMA_S6M1AR_OFFSET 0x00b0 /* DMA stream 6 memory 1 address register */ +#define STM32_DMA_S7M1AR_OFFSET 0x00c8 /* DMA stream 7 memory 1 address register */ + +#define STM32_DMA_S0FCR_OFFSET 0x0024 /* DMA stream 0 FIFO control register */ +#define STM32_DMA_S1FCR_OFFSET 0x003c /* DMA stream 1 FIFO control register */ +#define STM32_DMA_S2FCR_OFFSET 0x0054 /* DMA stream 2 FIFO control register */ +#define STM32_DMA_S3FCR_OFFSET 0x006c /* DMA stream 3 FIFO control register */ +#define STM32_DMA_S4FCR_OFFSET 0x0084 /* DMA stream 4 FIFO control register */ +#define STM32_DMA_S5FCR_OFFSET 0x009c /* DMA stream 5 FIFO control register */ +#define STM32_DMA_S6FCR_OFFSET 0x00b4 /* DMA stream 6 FIFO control register */ +#define STM32_DMA_S7FCR_OFFSET 0x00cc /* DMA stream 7 FIFO control register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_DMA1_LISRC (STM32_DMA1_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA1_HISRC (STM32_DMA1_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA1_LIFCR (STM32_DMA1_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA1_HIFCR (STM32_DMA1_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA1_SCR(n) (STM32_DMA1_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0CR (STM32_DMA1_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA1_S1CR (STM32_DMA1_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA1_S2CR (STM32_DMA1_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA1_S3CR (STM32_DMA1_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA1_S4CR (STM32_DMA1_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA1_S5CR (STM32_DMA1_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA1_S6CR (STM32_DMA1_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA1_S7CR (STM32_DMA1_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA1_SNDTR(n) (STM32_DMA1_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0NDTR (STM32_DMA1_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA1_S1NDTR (STM32_DMA1_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA1_S2NDTR (STM32_DMA1_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA1_S3NDTR (STM32_DMA1_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA1_S4NDTR (STM32_DMA1_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA1_S5NDTR (STM32_DMA1_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA1_S6NDTR (STM32_DMA1_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA1_S7NDTR (STM32_DMA1_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA1_SPAR(n) (STM32_DMA1_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0PAR (STM32_DMA1_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA1_S1PAR (STM32_DMA1_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA1_S2PAR (STM32_DMA1_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA1_S3PAR (STM32_DMA1_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA1_S4PAR (STM32_DMA1_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA1_S5PAR (STM32_DMA1_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA1_S6PAR (STM32_DMA1_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA1_S7PAR (STM32_DMA1_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA1_SM0AR(n) (STM32_DMA1_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M0AR (STM32_DMA1_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA1_S1M0AR (STM32_DMA1_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA1_S2M0AR (STM32_DMA1_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA1_S3M0AR (STM32_DMA1_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA1_S4M0AR (STM32_DMA1_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA1_S5M0AR (STM32_DMA1_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA1_S6M0AR (STM32_DMA1_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA1_S7M0AR (STM32_DMA1_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA1_SM1AR(n) (STM32_DMA1_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M1AR (STM32_DMA1_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA1_S1M1AR (STM32_DMA1_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA1_S2M1AR (STM32_DMA1_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA1_S3M1AR (STM32_DMA1_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA1_S4M1AR (STM32_DMA1_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA1_S5M1AR (STM32_DMA1_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA1_S6M1AR (STM32_DMA1_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA1_S7M1AR (STM32_DMA1_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA1_SFCR(n) (STM32_DMA1_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0FCR (STM32_DMA1_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA1_S1FCR (STM32_DMA1_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA1_S2FCR (STM32_DMA1_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA1_S3FCR (STM32_DMA1_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA1_S4FCR (STM32_DMA1_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA1_S5FCR (STM32_DMA1_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA1_S6FCR (STM32_DMA1_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA1_S7FCR (STM32_DMA1_BASE+STM32_DMA_S7FCR_OFFSET) + +#define STM32_DMA2_LISRC (STM32_DMA2_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA2_HISRC (STM32_DMA2_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA2_LIFCR (STM32_DMA2_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA2_HIFCR (STM32_DMA2_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA2_SCR(n) (STM32_DMA2_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0CR (STM32_DMA2_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA2_S1CR (STM32_DMA2_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA2_S2CR (STM32_DMA2_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA2_S3CR (STM32_DMA2_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA2_S4CR (STM32_DMA2_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA2_S5CR (STM32_DMA2_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA2_S6CR (STM32_DMA2_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA2_S7CR (STM32_DMA2_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA2_SNDTR(n) (STM32_DMA2_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0NDTR (STM32_DMA2_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA2_S1NDTR (STM32_DMA2_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA2_S2NDTR (STM32_DMA2_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA2_S3NDTR (STM32_DMA2_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA2_S4NDTR (STM32_DMA2_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA2_S5NDTR (STM32_DMA2_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA2_S6NDTR (STM32_DMA2_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA2_S7NDTR (STM32_DMA2_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA2_SPAR(n) (STM32_DMA2_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0PAR (STM32_DMA2_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA2_S1PAR (STM32_DMA2_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA2_S2PAR (STM32_DMA2_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA2_S3PAR (STM32_DMA2_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA2_S4PAR (STM32_DMA2_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA2_S5PAR (STM32_DMA2_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA2_S6PAR (STM32_DMA2_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA2_S7PAR (STM32_DMA2_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA2_SM0AR(n) (STM32_DMA2_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M0AR (STM32_DMA2_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA2_S1M0AR (STM32_DMA2_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA2_S2M0AR (STM32_DMA2_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA2_S3M0AR (STM32_DMA2_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA2_S4M0AR (STM32_DMA2_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA2_S5M0AR (STM32_DMA2_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA2_S6M0AR (STM32_DMA2_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA2_S7M0AR (STM32_DMA2_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA2_SM1AR(n) (STM32_DMA2_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M1AR (STM32_DMA2_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA2_S1M1AR (STM32_DMA2_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA2_S2M1AR (STM32_DMA2_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA2_S3M1AR (STM32_DMA2_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA2_S4M1AR (STM32_DMA2_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA2_S5M1AR (STM32_DMA2_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA2_S6M1AR (STM32_DMA2_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA2_S7M1AR (STM32_DMA2_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA2_SFCR(n) (STM32_DMA2_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0FCR (STM32_DMA2_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA2_S1FCR (STM32_DMA2_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA2_S2FCR (STM32_DMA2_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA2_S3FCR (STM32_DMA2_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA2_S4FCR (STM32_DMA2_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA2_S5FCR (STM32_DMA2_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA2_S6FCR (STM32_DMA2_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA2_S7FCR (STM32_DMA2_BASE+STM32_DMA_S7FCR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_STREAM_MASK 0x3f +#define DMA_STREAM_FEIF_BIT (1 << 0) /* Bit 0: Stream FIFO error interrupt flag */ +#define DMA_STREAM_DMEIF_BIT (1 << 2) /* Bit 2: Stream direct mode error interrupt flag */ +#define DMA_STREAM_TEIF_BIT (1 << 3) /* Bit 3: Stream Transfer Error flag */ +#define DMA_STREAM_HTIF_BIT (1 << 4) /* Bit 4: Stream Half Transfer flag */ +#define DMA_STREAM_TCIF_BIT (1 << 5) /* Bit 5: Stream Transfer Complete flag */ + +/* DMA interrupt status register and interrupt flag clear register field defintions */ + +#define DMA_INT_STREAM0_SHIFT (0) /* Bits 0-5: DMA Stream 0 interrupt */ +#define DMA_INT_STREAM0_MASK (DMA_STREAM_MASK << DMA_INT_STREAM0_SHIFT) +#define DMA_INT_STREAM1_SHIFT (6) /* Bits 6-11: DMA Stream 1 interrupt */ +#define DMA_INT_STREAM1_MASK (DMA_STREAM_MASK << DMA_INT_STREAM1_SHIFT) +#define DMA_INT_STREAM2_SHIFT (16) /* Bits 16-21: DMA Stream 2 interrupt */ +#define DMA_INT_STREAM2_MASK (DMA_STREAM_MASK << DMA_INT_STREAM2_SHIFT) +#define DMA_INT_STREAM3_SHIFT (22) /* Bits 22-27: DMA Stream 3 interrupt */ +#define DMA_INT_STREAM3_MASK (DMA_STREAM_MASK << DMA_INT_STREAM3_SHIFT) + +#define DMA_INT_STREAM4_SHIFT (0) /* Bits 0-5: DMA Stream 4 interrupt */ +#define DMA_INT_STREAM4_MASK (DMA_STREAM_MASK << DMA_INT_STREAM4_SHIFT) +#define DMA_INT_STREAM5_SHIFT (6) /* Bits 6-11: DMA Stream 5 interrupt */ +#define DMA_INT_STREAM5_MASK (DMA_STREAM_MASK << DMA_INT_STREAM5_SHIFT) +#define DMA_INT_STREAM6_SHIFT (16) /* Bits 16-21: DMA Stream 6 interrupt */ +#define DMA_INT_STREAM6_MASK (DMA_STREAM_MASK << DMA_INT_STREAM6_SHIFT) +#define DMA_INT_STREAM7_SHIFT (22) /* Bits 22-27: DMA Stream 7 interrupt */ +#define DMA_INT_STREAM7_MASK (DMA_STREAM_MASK << DMA_INT_STREAM7_SHIFT) + +/* DMA stream configuration register */ + +#define DMA_SCR_EN (1 << 0) /* Bit 0: Stream enable */ +#define DMA_SCR_DMEIE (1 << 1) /* Bit 1: Direct mode error interrupt enable */ +#define DMA_SCR_TEIE (1 << 2) /* Bit 2: Transfer error interrupt enable */ +#define DMA_SCR_HTIE (1 << 3) /* Bit 3: Half Transfer interrupt enable */ +#define DMA_SCR_TCIE (1 << 4) /* Bit 4: Transfer complete interrupt enable */ +#define DMA_SCR_PFCTRL (1 << 5) /* Bit 5: Peripheral flow controller */ +#define DMA_SCR_DIR_SHIFT (6) /* Bits 6-7: Data transfer direction */ +#define DMA_SCR_DIR_MASK (3 << DMA_SCR_DIR_SHIFT) +# define DMA_SCR_DIR_P2M (0 << DMA_SCR_DIR_SHIFT) /* 00: Peripheral-to-memory */ +# define DMA_SCR_DIR_M2P (1 << DMA_SCR_DIR_SHIFT) /* 01: Memory-to-peripheral */ +# define DMA_SCR_DIR_M2M (2 << DMA_SCR_DIR_SHIFT) /* 10: Memory-to-memory */ +#define DMA_SCR_CIRC (1 << 8) /* Bit 8: Circular mode */ +#define DMA_SCR_PINC (1 << 9) /* Bit 9: Peripheral increment mode */ +#define DMA_SCR_MINC (1 << 10) /* Bit 10: Memory increment mode */ +#define DMA_SCR_PSIZE_SHIFT (11) /* Bits 11-12: Peripheral size */ +#define DMA_SCR_PSIZE_MASK (3 << DMA_SCR_PSIZE_SHIFT) +# define DMA_SCR_PSIZE_8BITS (0 << DMA_SCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_PSIZE_16BITS (1 << DMA_SCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_PSIZE_32BITS (2 << DMA_SCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_MSIZE_SHIFT (13) /* Bits 13-14: Memory size */ +#define DMA_SCR_MSIZE_MASK (3 << DMA_SCR_MSIZE_SHIFT) +# define DMA_SCR_MSIZE_8BITS (0 << DMA_SCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_MSIZE_16BITS (1 << DMA_SCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_MSIZE_32BITS (2 << DMA_SCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_PINCOS (1 << 15) /* Bit 15: Peripheral increment offset size */ +#define DMA_SCR_PL_SHIFT (16) /* Bits 16-17: Stream Priority level */ +#define DMA_SCR_PL_MASK (3 << DMA_SCR_PL_SHIFT) +# define DMA_SCR_PRILO (0 << DMA_SCR_PL_SHIFT) /* 00: Low */ +# define DMA_SCR_PRIMED (1 << DMA_SCR_PL_SHIFT) /* 01: Medium */ +# define DMA_SCR_PRIHI (2 << DMA_SCR_PL_SHIFT) /* 10: High */ +# define DMA_SCR_PRIVERYHI (3 << DMA_SCR_PL_SHIFT) /* 11: Very high */ +#define DMA_SCR_DBM (1 << 18) /* Bit 15: Double buffer mode */ +#define DMA_SCR_CT (1 << 19) /* Bit 19: Current target */ +#define DMA_SCR_PBURST_SHIFT (21) /* Bits 21-22: Peripheral burst transfer configuration */ +#define DMA_SCR_PBURST_MASK (3 << DMA_SCR_PBURST_SHIFT) +# define DMA_SCR_PBURST_SINGLE (0 << DMA_SCR_PBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_PBURST_INCR4 (1 << DMA_SCR_PBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_PBURST_INCR8 (2 << DMA_SCR_PBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_PBURST_INCR16 (3 << DMA_SCR_PBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_MBURST_SHIFT (23) /* Bits 23-24: Memory burst transfer configuration */ +#define DMA_SCR_MBURST_MASK (3 << DMA_SCR_MBURST_SHIFT) +# define DMA_SCR_MBURST_SINGLE (0 << DMA_SCR_MBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_MBURST_INCR4 (1 << DMA_SCR_MBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_MBURST_INCR8 (2 << DMA_SCR_MBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_MBURST_INCR16 (3 << DMA_SCR_MBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_CHSEL_SHIFT (25) /* Bits 25-27: Channel selection */ +#define DMA_SCR_CHSEL_MASK (7 << DMA_SCR_CHSEL_SHIFT) +# define DMA_SCR_CHSEL(n) ((n) << DMA_SCR_CHSEL_SHIFT) + +#define DMA_SCR_ALLINTS (DMA_SCR_DMEIE|DMA_SCR_TEIE|DMA_SCR_HTIE|DMA_SCR_TCIE) + +/* DMA stream number of data register */ + +#define DMA_SNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_SNDTR_NDT_MASK (0xffff << DMA_SNDTR_NDT_SHIFT) + +/* DMA stream n FIFO control register */ + +#define DMA_SFCR_FTH_SHIFT (0) /* Bits 0-1: FIFO threshold selection */ +#define DMA_SFCR_FTH_MASK (3 << DMA_SFCR_FTH_SHIFT) +# define DMA_SFCR_FTH_QUARTER (0 << DMA_SFCR_FTH_SHIFT) /* 1/4 full FIFO */ +# define DMA_SFCR_FTH_HALF (1 << DMA_SFCR_FTH_SHIFT) /* 1/2 full FIFO */ +# define DMA_SFCR_FTH_3QUARTER (2 << DMA_SFCR_FTH_SHIFT) /* 3/4 full FIFO */ +# define DMA_SFCR_FTH_FULL (3 << DMA_SFCR_FTH_SHIFT) /* full FIFO */ +#define DMA_SFCR_DMDIS (1 << 2) /* Bit 2: Direct mode disable */ +#define DMA_SFCR_FS_SHIFT (3) /* Bits 3-5: FIFO status */ +#define DMA_SFCR_FS_MASK (7 << DMA_SFCR_FS_SHIFT) +# define DMA_SFCR_FS_QUARTER (0 << DMA_SFCR_FS_SHIFT) /* 0 < fifo_level < 1/4 */ +# define DMA_SFCR_FS_HALF (1 << DMA_SFCR_FS_SHIFT) /* 1/4 = fifo_level < 1/2 */ +# define DMA_SFCR_FS_3QUARTER (2 << DMA_SFCR_FS_SHIFT) /* 1/2 = fifo_level < 3/4 */ +# define DMA_SFCR_FS_ALMOSTFULL (3 << DMA_SFCR_FS_SHIFT) /* 3/4 = fifo_level < full */ +# define DMA_SFCR_FS_EMPTY (4 << DMA_SFCR_FS_SHIFT) /* FIFO is empty */ +# define DMA_SFCR_FS_FULL (5 << DMA_SFCR_FS_SHIFT) /* FIFO is full */ + /* Bit 6: Reserved */ +#define DMA_SFCR_FEIE (1 << 7) /* Bit 7: FIFO error interrupt enable */ + /* Bits 8-31: Reserved */ + +/* DMA Stream mapping. Each DMA stream has a mapping to several possible + * sources/sinks of data. The requests from peripherals assigned to a stream + * are simply OR'ed together before entering the DMA block. This means that only + * one request on a given stream can be enabled at once. + * + * Alternative stream selections are provided with a numeric suffix like _1, _2, etc. + * The DMA driver, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * SPI3_RX connects via DMA STREAM0, then following should be application-specific + * mapping should be used: + * + * #define DMAMAP_SPI3_RX DMAMAP_SPI3_RX_1 + */ + +#define STM32_DMA_MAP(d,s,c) ((d) << 6 | (s) << 3 | (c)) +#define STM32_DMA_CONTROLLER(m) (((m) >> 6) & 1) +#define STM32_DMA_STREAM(m) (((m) >> 3) & 7) +#define STM32_DMA_CHANNEL(m) ((m) & 7) + +#define DMAMAP_SPI3_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_SPI3_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_SPI2_RX STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN0) +#define DMAMAP_SPI2_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_SPI3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN0) +#define DMAMAP_SPI3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN0) + +#define DMAMAP_I2C1_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN1) +#define DMAMAP_TIM7_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_TIM7_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN1) +#define DMAMAP_I2C1_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN1) +#define DMAMAP_I2C1_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN1) +#define DMAMAP_I2C1_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_TIM4_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_I2S2_EXT_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN2) +#define DMAMAP_TIM4_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN2) +#define DMAMAP_I2S2_EXT_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN2) +#define DMAMAP_I2S3_EXT_TX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_TIM4_UP STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_TIM4_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_I2S3_EXT_RX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN3) +#define DMAMAP_TIM2_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN3) +#define DMAMAP_TIM2_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_I2C3_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_I2S2_EXT_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN3) +#define DMAMAP_I2C3_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN3) +#define DMAMAP_TIM2_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN3) +#define DMAMAP_TIM2_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) + +#define DMAMAP_UART5_RX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN4) +#define DMAMAP_USART3_RX STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN4) +#define DMAMAP_UART4_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_USART3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_UART4_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN4) +#define DMAMAP_USART2_RX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_USART2_TX STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_UART5_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN4) + +#define DMAMAP_TIM3_CH4 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_TIM3_UP STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_TIM3_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_TRIG STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN5) +#define DMAMAP_TIM3_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM5_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM5_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM6_UP STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_I2C2_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_I2C2_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_USART3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN7) +#define DMAMAP_DAC1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN7) +#define DMAMAP_DAC2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN7) +#define DMAMAP_I2C2_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN7) + +#define DMAMAP_ADC1_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_TIM8_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_ADC1_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_TIM1_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) + +#define DMAMAP_DCMI_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN1) +#define DMAMAP_ADC2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_ADC2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN1) +#define DMAMAP_DCMI_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_ADC3_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_ADC3_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN2) +#define DMAMAP_CRYP_OUT STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_CRYP_IN STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_HASH_IN STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_SPI1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN3) +#define DMAMAP_SPI1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_SPI1_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN3) +#define DMAMAP_SPI1_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN3) + +#define DMAMAP_USART1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_SDIO_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_USART1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_SDIO_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_USART1_TX STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN4) + +#define DMAMAP_USART6_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN5) +#define DMAMAP_USART6_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_USART6_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN5) +#define DMAMAP_USART6_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM1_TRIG_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM1_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM1_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM1_CH1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM1_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_TRIG_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_COM STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_UP STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN6) +#define DMAMAP_TIM1_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM8_UP STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_TIM8_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_TIM8_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_TIM8_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN7) +#define DMAMAP_TIM8_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_TRIG STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_COM STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_DMA_H */ diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h b/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..9bdb562ef3301403cd9b62ec196b1ae17f6fdff0 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_gpio.h @@ -0,0 +1,370 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_gpio.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_NGPIO_PORTS ((STM32_NGPIO + 15) >> 4) + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NGPIO_PORTS > 0 +# define STM32_GPIOA_MODER (STM32_GPIOA_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOA_AFRL (STM32_GPIOA_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOA_AFRH (STM32_GPIOA_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 1 +# define STM32_GPIOB_MODER (STM32_GPIOB_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOB_AFRL (STM32_GPIOB_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOB_AFRH (STM32_GPIOB_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 2 +# define STM32_GPIOC_MODER (STM32_GPIOC_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOC_AFRL (STM32_GPIOC_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOC_AFRH (STM32_GPIOC_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 3 +# define STM32_GPIOD_MODER (STM32_GPIOD_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOD_AFRL (STM32_GPIOD_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOD_AFRH (STM32_GPIOD_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 4 +# define STM32_GPIOE_MODER (STM32_GPIOE_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOE_AFRL (STM32_GPIOE_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOE_AFRH (STM32_GPIOE_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 5 +# define STM32_GPIOF_MODER (STM32_GPIOF_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOF_AFRL (STM32_GPIOF_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOF_AFRH (STM32_GPIOF_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 6 +# define STM32_GPIOG_MODER (STM32_GPIOG_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOG_OTYPER (STM32_GPIOG_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOG_OSPEED (STM32_GPIOG_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOG_PUPDR (STM32_GPIOG_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOG_IDR (STM32_GPIOG_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOG_ODR (STM32_GPIOG_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOG_BSRR (STM32_GPIOG_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOG_LCKR (STM32_GPIOG_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOG_AFRL (STM32_GPIOG_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOG_AFRH (STM32_GPIOG_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 7 +# define STM32_GPIOH_MODER (STM32_GPIOH_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOH_OTYPER (STM32_GPIOH_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOH_OSPEED (STM32_GPIOH_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOH_PUPDR (STM32_GPIOH_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOH_IDR (STM32_GPIOH_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOH_ODR (STM32_GPIOH_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOH_BSRR (STM32_GPIOH_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOH_LCKR (STM32_GPIOH_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOH_AFRL (STM32_GPIOH_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOH_AFRH (STM32_GPIOH_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 8 +# define STM32_GPIOI_MODER (STM32_GPIOI_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOI_OTYPER (STM32_GPIOI_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOI_OSPEED (STM32_GPIOI_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOI_PUPDR (STM32_GPIOI_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOI_IDR (STM32_GPIOI_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOI_ODR (STM32_GPIOI_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOI_BSRR (STM32_GPIOI_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOI_LCKR (STM32_GPIOI_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOI_AFRL (STM32_GPIOI_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOI_AFRH (STM32_GPIOI_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (2) /* 50 MHz Fast speed */ +#define GPIO_OSPEED_100MHz (3) /* 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_GPIO_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..9c64929a0b06c2114bfd14b3e4367f2c71fd8d36 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h @@ -0,0 +1,214 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_memorymap.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F20XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +# define STM32_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3&4 block */ +# define STM32_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32_FSMC_BANK4 0x90000000 /* 0x90000000-0x9fffffff: 256Mb PC CARD*/ +#define STM32_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: 512Mb FSMC register block */ + /* 0xc0000000-0xdfffffff: 512Mb (not used) */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) +#define STM32_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_FSMC_BANK1) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x0fffffff: Reserved */ +#define STM32_CCMRAM_BASE 0x10000000 /* 0x10000000-0x1000ffff: 64Kb CCM data RAM */ + /* 0x10010000-0x1ffeffff: Reserved */ +#define STM32_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32_OPTION_BASE 0x1fffc000 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32_SYSMEM_UID 0x1fff7a10 /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x1fff7a22 /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x0400 corresponds + * to 1024 Kbytes. + */ + +/* SRAM Base Addresses **************************************************************/ + + /* 0x20000000-0x2001bfff: 112Kb aliased by bit-banding */ + /* 0x2001c000-0x2001ffff: 16Kb aliased by bit-banding */ +#define STM32_SRAMBB_BASE 0x22000000 /* 0x22000000- : SRAM bit-band region */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x400023ff: APB1 */ + /* 0x40002400-0x400027ff: Reserved */ + /* 0x40002800-0x400077ff: APB1 */ + /* 0x40007800-0x4000ffff: Reserved */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x400023ff: APB2 */ + /* 0x40013400-0x400137ff: Reserved */ + /* 0x40013800-0x40013bff: SYSCFG */ +#define STM32_EXTI_BASE 0x40013c00 /* 0x40013c00-0x40013fff: EXTI */ + /* 0x40014000-0x40014bff: APB2 */ + /* 0x40014c00-0x4001ffff: Reserved */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x400223ff: APB1 */ + /* 0x40022400-0x40022fff: Reserved */ + /* 0x40023000-0x400233ff: CRC */ + /* 0x40023400-0x400237ff: Reserved */ + /* 0x40023800-0x40023bff: Reset and Clock control RCC */ + /* 0x40023c00-0x400293ff: AHB1 (?) */ + /* 0x40029400-0x4fffffff: Reserved (?) */ +#define STM32_AHB2_BASE 0x50000000 /* 0x50000000-0x5003ffff: AHB2 */ + /* 0x50040000-0x5004ffff: Reserved */ + /* 0x50050000-0x500503ff: AHB2 */ + /* 0x50050400-0x500607ff: Reserved */ + /* 0x50060800-0x50060bff: AHB2 */ + /* 0x50060c00-0x5fffffff: Reserved */ + +/* FSMC Base Addresses **************************************************************/ + +#define STM32_AHB3_BASE 0x60000000 /* 0x60000000-0xa0000fff: AHB3 */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff: TIM2 timer */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff: TIM3 timer */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff: TIM4 timer */ +#define STM32_TIM5_BASE 0x40000c00 /* 0x40000c00-0x40000fff: TIM5 timer */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff: TIM6 timer */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff: TIM7 timer */ +#define STM32_TIM12_BASE 0x40001800 /* 0x40001800-0x40001bff: TIM12 timer */ +#define STM32_TIM13_BASE 0x40001c00 /* 0x40001c00-0x40001fff: TIM13 timer */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000-0x400023ff: TIM14 timer */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff: RTC & BKP registers */ +#define STM32_BKP_BASE 0x40002850 +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff: Window watchdog (WWDG) */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff: Independent watchdog (IWDG) */ +#define STM32_I2S2EXT_BASE 0x40003400 /* 0x40003400-0x400037ff: I2S2ext */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff: SPI2/I2S2 */ +#define STM32_I2S2_BASE 0x40003800 +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff: SPI3/I2S3 */ +#define STM32_I2S3_BASE 0x40003c00 +#define STM32_I2S3EXT_BASE 0x40004000 /* 0x40003400-0x400043ff: I2S3ext */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff: USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff: USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff: UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff: UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff: I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005Bff: I2C2 */ +#define STM32_I2C3_BASE 0x40005c00 /* 0x40005c00-0x40005fff: I2C3 */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff: bxCAN1 */ +#define STM32_CAN2_BASE 0x40006800 /* 0x40006800-0x40006bff: bxCAN2 */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff: Power control PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400-0x400077ff: DAC */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_TIM1_BASE 0x40010000 /* 0x40010000-0x400103ff: TIM1 timer */ +#define STM32_TIM8_BASE 0x40010400 /* 0x40010400-0x400107ff: TIM8 timer */ +#define STM32_USART1_BASE 0x40011000 /* 0x40011000-0x400113ff: USART1 */ +#define STM32_USART6_BASE 0x40011400 /* 0x40011400-0x400117ff: USART6 */ +#define STM32_ADC_BASE 0x40012000 /* 0x40012000-0x400123ff: ADC1-3 */ +# define STM32_ADC1_BASE 0x40012000 /* ADC1 */ +# define STM32_ADC2_BASE 0x40012100 /* ADC2 */ +# define STM32_ADC3_BASE 0x40012200 /* ADC3 */ +# define STM32_ADCCMN_BASE 0x40012300 /* Common */ +#define STM32_SDIO_BASE 0x40012c00 /* 0x40012c00-0x40012fff: SDIO */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff: SPI1 */ +#define STM32_SYSCFG_BASE 0x40013800 /* 0x40013800-0x40013bff: SYSCFG */ +#define STM32_EXTI_BASE 0x40013c00 /* 0x40013c00-0x40013fff: EXTI */ +#define STM32_TIM9_BASE 0x40014000 /* 0x40014000-0x400143ff: TIM9 timer */ +#define STM32_TIM10_BASE 0x40014400 /* 0x40014400-0x400147ff: TIM10 timer */ +#define STM32_TIM11_BASE 0x40014800 /* 0x40014800-0x40014bff: TIM11 timer */ + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32_GPIOA_BASE 0x40020000 /* 0x40020000-0x400203ff: GPIO Port A */ +#define STM32_GPIOB_BASE 0x40020400 /* 0x40020400-0x400207ff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x40020800 /* 0x40020800-0x40020bff: GPIO Port C */ +#define STM32_GPIOD_BASE 0X40020C00 /* 0x40020c00-0x40020fff: GPIO Port D */ +#define STM32_GPIOE_BASE 0x40021000 /* 0x40021000-0x400213ff: GPIO Port E */ +#define STM32_GPIOF_BASE 0x40021400 /* 0x40021400-0x400217ff: GPIO Port F */ +#define STM32_GPIOG_BASE 0x40021800 /* 0x40021800-0x40021bff: GPIO Port G */ +#define STM32_GPIOH_BASE 0x40021C00 /* 0x40021C00-0x40021fff: GPIO Port H */ +#define STM32_GPIOI_BASE 0x40022000 /* 0x40022000-0x400223ff: GPIO Port I */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ +#define STM32_RCC_BASE 0x40023800 /* 0x40023800-0x40023bff: Reset and Clock control RCC */ +#define STM32_FLASHIF_BASE 0x40023c00 /* 0x40023c00-0x40023fff: Flash memory interface */ +#define STM32_BKPSRAM_BASE 0x40024000 /* 0x40024000-0x40024fff: Backup SRAM (BKPSRAM) */ +#define STM32_DMA1_BASE 0x40026000 /* 0x40026000-0x400263ff: DMA1 */ +#define STM32_DMA2_BASE 0x40026400 /* 0x40026400-0x400267ff: DMA2 */ +#define STM32_ETHERNET_BASE 0x40028000 /* 0x40028000-0x400283ff: Ethernet MAC */ + /* 0x40028400-0x400287ff: Ethernet MAC */ + /* 0x40028800-0x40028bff: Ethernet MAC */ + /* 0x40028c00-0x40028fff: Ethernet MAC */ + /* 0x40029000-0x400293ff: Ethernet MAC */ +#define STM32_OTGHS_BASE 0x40040000 /* 0x40040000-0x4007ffff: USB OTG HS */ +#define STM32_PERIPHBB_BASE 0x42000000 /* Peripheral bit-band region */ + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32_OTGFS_BASE 0x50000000 /* 0x50000000-0x5003ffff: USB OTG FS */ +#define STM32_DCMI_BASE 0x50050000 /* 0x50050000-0x500503ff: DCMI */ +#define STM32_CRYP_BASE 0x50060000 /* 0x50060000-0x500603ff: CRYP */ +#define STM32_HASH_BASE 0x50060400 /* 0x50060400-0x500607ff: HASH */ +#define STM32_RNG_BASE 0x50060800 /* 0x50060800-0x50060bff: RNG */ + +/* Cortex-M3 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..b613922d8fd265630ca982cff8bb500ee101a00c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h @@ -0,0 +1,695 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_pinmap.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32F20xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN14 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN15 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) + +/* CAN */ + +#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN1_RX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CAN1_TX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) + +#define GPIO_CAN2_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_CAN2_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_CAN2_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN2_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +/* DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* Digital Camera Interface (DCMI) */ + +#define GPIO_DCMI_D0_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN9) +#define GPIO_DCMI_D0_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_DCMI_D0_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN9) +#define GPIO_DCMI_D1_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN10) +#define GPIO_DCMI_D1_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_DCMI_D1_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN10) +#define GPIO_DCMI_D2_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN8) +#define GPIO_DCMI_D2_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN0) +#define GPIO_DCMI_D2_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN11) +#define GPIO_DCMI_D3_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN9) +#define GPIO_DCMI_D3_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN1) +#define GPIO_DCMI_D3_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN12) +#define GPIO_DCMI_D4_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_DCMI_D4_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_DCMI_D4_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN14) +#define GPIO_DCMI_D5_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_DCMI_D5_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN4) +#define GPIO_DCMI_D6_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_DCMI_D6_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_DCMI_D6_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN6) +#define GPIO_DCMI_D7_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_DCMI_D7_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_DCMI_D7_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN7) +#define GPIO_DCMI_D8_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_DCMI_D8_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN1) +#define GPIO_DCMI_D9_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_DCMI_D9_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN2) +#define GPIO_DCMI_D10_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_DCMI_D10_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN3) +#define GPIO_DCMI_D11_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN2) +#define GPIO_DCMI_D11_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN15) +#define GPIO_DCMI_D12 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN11) +#define GPIO_DCMI_D13_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN15) +#define GPIO_DCMI_D13_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN0) +#define GPIO_DCMI_HSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DCMI_HSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN8) +#define GPIO_DCMI_PIXCK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_DCMI_VSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN7) +#define GPIO_DCMI_VSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN5) + +/* Clocks outputs */ + +#define GPIO_MCO1 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO2 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) + +/* Ethernet MAC */ + +#define GPIO_ETH_MDC (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ETH_MDIO (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ETH_MII_COL_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ETH_MII_COL_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_ETH_MII_CRS_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ETH_MII_CRS_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_ETH_MII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH_MII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH_MII_RXD2_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ETH_MII_RXD2_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_ETH_MII_RXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ETH_MII_RXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN7) +#define GPIO_ETH_MII_RX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH_MII_RX_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH_MII_RX_ER_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_ETH_MII_RX_ER_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_ETH_MII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_MII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_ETH_MII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_MII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_ETH_MII_TXD2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ETH_MII_TXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_ETH_MII_TXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN2) +#define GPIO_ETH_MII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_MII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_MII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#define GPIO_ETH_PPS_OUT_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_ETH_PPS_OUT_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN8) +#define GPIO_ETH_RMII_CRS_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH_RMII_REF_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH_RMII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH_RMII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH_RMII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_RMII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_ETH_RMII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_RMII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_ETH_RMII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_RMII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_RMII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) + +/* Flexible Static Memory Controller (FSMC) */ + +#define GPIO_FSMC_A0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FSMC_A1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FSMC_A2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FSMC_A3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FSMC_A4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FSMC_A5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FSMC_A6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FSMC_A7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FSMC_A8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FSMC_A9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FSMC_A10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FSMC_A11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FSMC_A12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FSMC_A13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FSMC_A14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FSMC_A15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FSMC_A16 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FSMC_A17 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FSMC_A18 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FSMC_A19 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FSMC_A20 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FSMC_A21 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FSMC_A22 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FSMC_A23 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FSMC_A24 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FSMC_A25 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_FSMC_NBL1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FSMC_CD (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_FSMC_CLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FSMC_D0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FSMC_D1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FSMC_D2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FSMC_D3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FSMC_D4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FSMC_D5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FSMC_D6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FSMC_D7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FSMC_D8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FSMC_D9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FSMC_D10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FSMC_D11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FSMC_D12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FSMC_D13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FSMC_D14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FSMC_D15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_FSMC_INT2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN6) +#define GPIO_FSMC_INT3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FSMC_INTR (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN10) +#define GPIO_FSMC_NBL0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FSMC_NCE2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FSMC_NCE3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FSMC_NCE4_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FSMC_NCE4_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN11) +#define GPIO_FSMC_NE1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FSMC_NE2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FSMC_NE3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FSMC_NE4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FSMC_NIORD (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_FSMC_NIOWR (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN8) +#define GPIO_FSMC_NL (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FSMC_NOE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FSMC_NREG (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN7) +#define GPIO_FSMC_NWAIT (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FSMC_NWE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN5) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN4) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN5) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C2_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) + +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN8) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) + +/* I2S */ + +#define GPIO_I2S2_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2S2_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_CK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN1) +#define GPIO_I2S2_MCK (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN15) +#define GPIO_I2S2_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN3) +#define GPIO_I2S2_SD_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2S2_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2S2_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2S2_WS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN0) + +#define GPIO_I2S2EXT_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2S2EXT_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN2) +#define GPIO_I2S2EXT_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN2) + +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S3_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_I2S3EXT_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN11) +#define GPIO_I2S3EXT_SD_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) + +#define GPIO_I2S_CKIN (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) + +/* JTAG */ + +#define GPIO_JTCK_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_JTMS_SWDIO (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_JTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) + +/* OTG FS/HS (VBUS PA9 is not an alternate configuration) */ + +#define GPIO_OTGFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTGFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTGFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTGFS_SCL (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN8) +#define GPIO_OTGFS_SDA (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN9) +#define GPIO_OTGFS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_OTGHS_DM (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN14) +#define GPIO_OTGHS_DP (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN15) +#define GPIO_OTGHS_ID (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTGHS_INTN_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OTGFS_INTN_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN6) +#define GPIO_OTGHS_SCL (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OTGHS_SDA (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN11) +#define GPIO_OTGHS_SOF (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN4) +#define GPIO_OTGHS_ULPI_CK (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_D0 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_D1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_OTGHS_ULPI_D2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OTGHS_ULPI_D3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OTGHS_ULPI_D4 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#define GPIO_OTGHS_ULPI_D5 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTGHS_ULPI_D6 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN13) +#define GPIO_OTGHS_ULPI_D7 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_DIR_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN2) +#define GPIO_OTGHS_ULPI_DIR_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN11) +#define GPIO_OTGHS_ULPI_NXT_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_NXT_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN4) +#define GPIO_OTGHS_ULPI_STP (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN0) + +/* RTC */ + +#define GPIO_RTC_50HZ (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN15) + +/* SDIO */ + +#define GPIO_SDIO_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDIO_CMD (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDIO_D0 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDIO_D1 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDIO_D2 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDIO_D3 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDIO_D4 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDIO_D5 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDIO_D6 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDIO_D7 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN2) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN3) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN0) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN1) + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) + +/* Timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) + +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13) +#define GPIO_TIM8_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH2N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN14) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN15) +#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15) +#define GPIO_TIM8_CH3IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH4IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3) + +#define GPIO_TIM9_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM9_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) + +#define GPIO_TIM10_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM10_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) + +#define GPIO_TIM11_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM11_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_TIM12_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6) +#define GPIO_TIM12_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_TIM12_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN15) +#define GPIO_TIM12_CH2IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9) +#define GPIO_TIM12_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN15) +#define GPIO_TIM12_CH2OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) + +#define GPIO_TIM13_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM13_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) + +#define GPIO_TIM14_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM14_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) + +/* Trace */ + +#define GPIO_TRACECLK (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TRACESWO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) + +/* UARTs/USARTs */ + +#define GPIO_USART1_CK (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) + +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_USART6_CK_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN8) +#define GPIO_USART6_CK_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN7) +#define GPIO_USART6_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART6_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN15) +#define GPIO_USART6_RTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN12) +#define GPIO_USART6_RTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN8) +#define GPIO_USART6_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_USART6_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART6_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_USART6_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_PINMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..1057541f5e8ec8b43762f6552163bb2e364bc374 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_rcc.h @@ -0,0 +1,506 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f20xxx_rcc.h + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_RCC_H + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_PLLCFG_OFFSET 0x0004 /* PLL configuration register */ +#define STM32_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x000c /* Clock interrupt register */ +#define STM32_RCC_AHB1RSTR_OFFSET 0x0010 /* AHB1 peripheral reset register */ +#define STM32_RCC_AHB2RSTR_OFFSET 0x0014 /* AHB2 peripheral reset register */ +#define STM32_RCC_AHB3RSTR_OFFSET 0x0018 /* AHB3 peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0020 /* APB1 Peripheral reset register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x0024 /* APB2 Peripheral reset register */ +#define STM32_RCC_AHB1ENR_OFFSET 0x0030 /* AHB1 Peripheral Clock enable register */ +#define STM32_RCC_AHB2ENR_OFFSET 0x0034 /* AHB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB3ENR_OFFSET 0x0038 /* AHB3 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x0040 /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0044 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB1LPENR_OFFSET 0x0050 /* RCC AHB1 low power modeperipheral clock enable register */ +#define STM32_RCC_AH2BLPENR_OFFSET 0x0054 /* RCC AHB2 low power modeperipheral clock enable register */ +#define STM32_RCC_AH3BLPENR_OFFSET 0x0058 /* RCC AHB3 low power modeperipheral clock enable register */ +#define STM32_RCC_APB1LPENR_OFFSET 0x0060 /* RCC APB1 low power modeperipheral clock enable register */ +#define STM32_RCC_APB2LPENR_OFFSET 0x0064 /* RCC APB2 low power modeperipheral clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0070 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0074 /* Control/status register */ +#define STM32_RCC_SSCGR_OFFSET 0x0080 /* Spread spectrum clock generation register */ +#define STM32_RCC_PLLI2SCFGR_OFFSET 0x0084 /* PLLI2S configuration register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_PLLCFG (STM32_RCC_BASE+STM32_RCC_PLLCFG_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_AHB1RSTR (STM32_RCC_BASE+STM32_RCC_AHB1RSTR_OFFSET) +#define STM32_RCC_AHB2RSTR (STM32_RCC_BASE+STM32_RCC_AHB2RSTR_OFFSET) +#define STM32_RCC_AHB3RSTR (STM32_RCC_BASE+STM32_RCC_AHB3RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_AHB1ENR (STM32_RCC_BASE+STM32_RCC_AHB1ENR_OFFSET) +#define STM32_RCC_AHB2ENR (STM32_RCC_BASE+STM32_RCC_AHB2ENR_OFFSET) +#define STM32_RCC_AHB3ENR (STM32_RCC_BASE+STM32_RCC_AHB3ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_AHB1LPENR (STM32_RCC_BASE+STM32_RCC_AHB1LPENR_OFFSET) +#define STM32_RCC_AH2BLPENR (STM32_RCC_BASE+STM32_RCC_AH2BLPENR) +#define STM32_RCC_AH3BLPENR (STM32_RCC_BASE+STM32_RCC_AH3BLPENR_OFFSET) +#define STM32_RCC_APB1LPENR (STM32_RCC_BASE+STM32_RCC_APB1LPENR_OFFSET) +#define STM32_RCC_APB2LPENR (STM32_RCC_BASE+STM32_RCC_APB2LPENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#define STM32_RCC_SSCGR (STM32_RCC_BASE+STM32_RCC_SSCGR_OFFSET) +#define STM32_RCC_PLLI2SCFGR (STM32_RCC_BASE+STM32_RCC_PLLI2SCFGR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#define RCC_CR_PLLI2SON (1 << 26) /* Bit 26: PLLI2S enable */ +#define RCC_CR_PLLI2SRDY (1 << 27) /* Bit 27: PLLI2S clock ready flag */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLM_SHIFT (0) /* Bits 0-5: Main PLL (PLL) and audio PLL (PLLI2S) + * input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x3f << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n) << RCC_PLLCFG_PLLM_SHIFT) /* n = 2..63 */ +#define RCC_PLLCFG_PLLN_SHIFT (6) /* Bits 6-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x1ff << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 2..432 */ +#define RCC_PLLCFG_PLLP_SHIFT (16) /* Bits 16-17: Main PLL (PLL) main system clock divider */ +#define RCC_PLLCFG_PLLP_MASK (3 << RCC_PLLCFG_PLLP_SHIFT) +# define RCC_PLLCFG_PLLP(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLP_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLP_2 (0 << RCC_PLLCFG_PLLP_SHIFT) /* 00: PLLP = 2 */ +# define RCC_PLLCFG_PLLP_4 (1 << RCC_PLLCFG_PLLP_SHIFT) /* 01: PLLP = 4 */ +# define RCC_PLLCFG_PLLP_6 (2 << RCC_PLLCFG_PLLP_SHIFT) /* 10: PLLP = 6 */ +# define RCC_PLLCFG_PLLP_8 (3 << RCC_PLLCFG_PLLP_SHIFT) /* 11: PLLP = 8 */ +#define RCC_PLLCFG_PLLSRC (1 << 22) /* Bit 22: Main PLL(PLL) and audio PLL (PLLI2S) + * entry clock source */ +# define RCC_PLLCFG_PLLSRC_HSI (0) +# define RCC_PLLCFG_PLLSRC_HSE RCC_PLLCFG_PLLSRC +#define RCC_PLLCFG_PLLQ_SHIFT (24) /* Bits 24-27: Main PLL (PLL) divider + * (USB OTG FS, SDIO and RNG clocks) */ +#define RCC_PLLCFG_PLLQ_MASK (15 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((n) << RCC_PLLCFG_PLLQ_SHIFT) /* n=2..15 */ + +#define RCC_PLLCFG_RESET (0x24003010) /* PLLCFG reset value */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (10) /* Bits 10-12: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (13) /* Bits 13-15: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_RTCPRE_SHIFT (16) /* Bits 16-20: APB High speed prescaler (APB2) */ +#define RCC_CFGR_RTCPRE_MASK (31 << RCC_CFGR_RTCPRE_SHIFT) +# define RCC_CFGR_RTCPRE(n) ((n) << RCC_CFGR_RTCPRE_SHIFT) /* HSE/n, n=1..31 */ +#define RCC_CFGR_MCO1_SHIFT (21) /* Bits 21-22: Microcontroller Clock Output */ +#define RCC_CFGR_MCO1_MASK (3 << RCC_CFGR_MCO1_SHIFT) +# define RCC_CFGR_MCO1_HSI (0 << RCC_CFGR_MCO1_SHIFT) /* 00: HSI clock selected */ +# define RCC_CFGR_MCO1_LSE (1 << RCC_CFGR_MCO1_SHIFT) /* 01: LSE oscillator selected */ +# define RCC_CFGR_MCO1_HSE (2 << RCC_CFGR_MCO1_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO1_PLL (3 << RCC_CFGR_MCO1_SHIFT) /* 11: PLL clock selected */ +#define RCC_CFGR_I2SSRC (1 << 23) /* Bit 23: I2S clock selection */ +#define RCC_CFGR_MCO1PRE_SHIFT (24) /* Bits 24-26: MCO1 prescaler */ +#define RCC_CFGR_MCO1PRE_MASK (7 << RCC_CFGR_MCO1PRE_SHIFT) +# define RCC_CFGR_MCO1PRE_NONE (0 << RCC_CFGR_MCO1PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO1PRE_DIV2 (4 << RCC_CFGR_MCO1PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO1PRE_DIV3 (5 << RCC_CFGR_MCO1PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO1PRE_DIV4 (6 << RCC_CFGR_MCO1PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO1PRE_DIV5 (7 << RCC_CFGR_MCO1PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2PRE_SHIFT (27) /* Bits 27-29: MCO2 prescaler */ +#define RCC_CFGR_MCO2PRE_MASK (7 << RCC_CFGR_MCO2PRE_SHIFT) +# define RCC_CFGR_MCO2PRE_NONE (0 << RCC_CFGR_MCO2PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO2PRE_DIV2 (4 << RCC_CFGR_MCO2PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO2PRE_DIV3 (5 << RCC_CFGR_MCO2PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO2PRE_DIV4 (6 << RCC_CFGR_MCO2PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO2PRE_DIV5 (7 << RCC_CFGR_MCO2PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2_SHIFT (30) /* Bits 30-31: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_MASK (3 << RCC_CFGR_MCO2_SHIFT) +# define RCC_CFGR_MCO2_SYSCLK (0 << RCC_CFGR_MCO2_SHIFT) /* 00: System clock (SYSCLK) selected */ +# define RCC_CFGR_MCO2_PLLI2S (1 << RCC_CFGR_MCO2_SHIFT) /* 01: PLLI2S clock selected */ +# define RCC_CFGR_MCO2_HSE (2 << RCC_CFGR_MCO2_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO2_PLL (3 << RCC_CFGR_MCO2_SHIFT) /* 11: PLL clock selected */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_PLLI2SRDYF (1 << 5) /* Bit 5: PLLI2S Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_PLLI2SRDYIE (1 << 13) /* Bit 13: PLLI2S Ready Interrupt enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_PLLI2SRDYC (1 << 21) /* Bit 21: PLLI2S Ready Interrupt clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB1RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB1RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB1RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB1RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB1RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB1RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB1RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12 IO port I reset */ +#define RCC_AHB1RSTR_DMA1RST (1 << 21) /* Bit 21: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 22) /* Bit 22: DMA2 reset */ +#define RCC_AHB1RSTR_ETHMACRST (1 << 25) /* Bit 25: Ethernet MAC reset */ +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) /* Bit 29: USB OTG HS module reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_DCMIRST (1 << 0) /* Bit 0: Camera interface reset */ +#define RCC_AHB2RSTR_CRYPRST (1 << 4) /* Bit 4: Cryptographic module reset */ +#define RCC_AHB2RSTR_HASHRST (1 << 5) /* Bit 5: Hash module reset */ +#define RCC_AHB2RSTR_RNGRST (1 << 6) /* Bit 6: Random number generator module reset */ +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) /* Bit 7: USB OTG FS module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */ + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR_TIM12RST (1 << 6) /* Bit 6: TIM12 reset */ +#define RCC_APB1RSTR_TIM13RST (1 << 7) /* Bit 7: TIM13 reset */ +#define RCC_APB1RSTR_TIM14RST (1 << 8) /* Bit 8: TIM14 reset */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: USART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: USART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR_CAN2RST (1 << 26) /* Bit 26: CAN2 reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC reset */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_TIM1RST (1 << 0) /* Bit 0: TIM1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 1) /* Bit 1: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 4) /* Bit 4: USART1 reset */ +#define RCC_APB2RSTR_USART6RST (1 << 5) /* Bit 5: USART6 reset */ +#define RCC_APB2RSTR_ADCRST (1 << 8) /* Bit 8: ADC interface reset (common to all ADCs) */ +#define RCC_APB2RSTR_SDIORST (1 << 11) /* Bit 11: SDIO reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) /* Bit 14: System configuration controller reset */ +#define RCC_APB2RSTR_TIM9RST (1 << 16) /* Bit 16: TIM9 reset */ +#define RCC_APB2RSTR_TIM10RST (1 << 17) /* Bit 17: TIM10 reset */ +#define RCC_APB2RSTR_TIM11RST (1 << 18) /* Bit 18: TIM11 reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_GPIOEN(n) (1 << (n)) +#define RCC_AHB1ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A clock enable */ +#define RCC_AHB1ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B clock enable */ +#define RCC_AHB1ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C clock enable */ +#define RCC_AHB1ENR_GPIODEN (1 << 3) /* Bit 3: IO port D clock enable */ +#define RCC_AHB1ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E clock enable */ +#define RCC_AHB1ENR_GPIOFEN (1 << 5) /* Bit 5: IO port F clock enable */ +#define RCC_AHB1ENR_GPIOGEN (1 << 6) /* Bit 6: IO port G clock enable */ +#define RCC_AHB1ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H clock enable */ +#define RCC_AHB1ENR_GPIOIEN (1 << 8) /* Bit 8: IO port I clock enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC clock enable */ +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable */ +#define RCC_AHB1ENR_DMA1EN (1 << 21) /* Bit 21: DMA1 clock enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 22) /* Bit 22: DMA2 clock enable */ +#define RCC_AHB1ENR_ETHMACEN (1 << 25) /* Bit 25: Ethernet MAC clock enable */ +#define RCC_AHB1ENR_ETHMACTXEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable */ +#define RCC_AHB1ENR_ETHMACRXEN (1 << 27) /* Bit 27: Ethernet Reception clock enable */ +#define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable */ +#define RCC_AHB1ENR_OTGHSEN (1 << 29) /* Bit 29: USB OTG HS clock enable */ +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable */ + +/* AHB2 Peripheral Clock enable register */ + +#define RCC_AHB2ENR_DCMIEN (1 << 0) /* Bit 0: Camera interface enable */ +#define RCC_AHB2ENR_CRYPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable */ +#define RCC_AHB2ENR_HASHEN (1 << 5) /* Bit 5: Hash modules clock enable */ +#define RCC_AHB2ENR_RNGEN (1 << 6) /* Bit 6: Random number generator clock enable */ +#define RCC_AHB2ENR_OTGFSEN (1 << 7) /* Bit 7: USB OTG FS clock enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module clock enable */ + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: TIM2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: TIM3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: TIM4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 3: TIM5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: TIM6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: TIM7 clock enable */ +#define RCC_APB1ENR_TIM12EN (1 << 6) /* Bit 6: TIM12 clock enable */ +#define RCC_APB1ENR_TIM13EN (1 << 7) /* Bit 7: TIM13 clock enable */ +#define RCC_APB1ENR_TIM14EN (1 << 8) /* Bit 8: TIM14 clock enable */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI3 clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C2 clock enable */ +#define RCC_APB1ENR_I2C3EN (1 << 23) /* Bit 23: I2C3 clock enable */ +#define RCC_APB1ENR_CAN1EN (1 << 25) /* Bit 25: CAN 1 clock enable */ +#define RCC_APB1ENR_CAN2EN (1 << 26) /* Bit 26: CAN 2 clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ +#define RCC_APB1ENR_UART7EN (1 << 30) /* Bit 30: UART7 clock enable */ +#define RCC_APB1ENR_UART8EN (1 << 31) /* Bit 31: UART8 clock enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_TIM1EN (1 << 0) /* Bit 0: TIM1 clock enable */ +#define RCC_APB2ENR_TIM8EN (1 << 1) /* Bit 1: TIM8 clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 4) /* Bit 4: USART1 clock enable */ +#define RCC_APB2ENR_USART6EN (1 << 5) /* Bit 5: USART6 clock enable */ +#define RCC_APB2ENR_ADC1EN (1 << 8) /* Bit 8: ADC1 clock enable */ +#define RCC_APB2ENR_ADC2EN (1 << 9) /* Bit 9: ADC2 clock enable */ +#define RCC_APB2ENR_ADC3EN (1 << 10) /* Bit 10: ADC3 clock enable */ +#define RCC_APB2ENR_SDIOEN (1 << 11) /* Bit 11: SDIO clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 clock enable */ +#define RCC_APB2ENR_SYSCFGEN (1 << 14) /* Bit 14: System configuration controller clock enable */ +#define RCC_APB2ENR_TIM9EN (1 << 16) /* Bit 16: TIM9 clock enable */ +#define RCC_APB2ENR_TIM10EN (1 << 17) /* Bit 17: TIM10 clock enable */ +#define RCC_APB2ENR_TIM11EN (1 << 18) /* Bit 18: TIM11 clock enable */ + +/* RCC AHB1 low power modeperipheral clock enable register */ + +#define RCC_AHB1LPENR_GPIOLPEN(n) (1 << (n)) +#define RCC_AHB1LPENR_GPIOALPEN (1 << 0) /* Bit 0: IO port A clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOBLPEN (1 << 1) /* Bit 1: IO port B clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOCLPEN (1 << 2) /* Bit 2: IO port C clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIODLPEN (1 << 3) /* Bit 3: IO port D clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOELPEN (1 << 4) /* Bit 4: IO port E clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOFLPEN (1 << 5) /* Bit 5: IO port F clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOGLPEN (1 << 6) /* Bit 6: IO port G clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOHLPEN (1 << 7) /* Bit 7: IO port H clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOILPEN (1 << 8) /* Bit 8: IO port I clock enable during Sleep mode */ +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) /* Bit 12: CRC clock enable during Sleep mode */ +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) /* Bit 15: Flash interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) /* Bit 16: SRAM 1 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) /* Bit 17: SRAM 2 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) /* Bit 21: DMA1 clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) /* Bit 22: DMA2 clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) /* Bit 25: Ethernet MAC clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHMACTXLPEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHMACRXLPEN (1 << 27) /* Bit 27: Ethernet Reception clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHMACPTPLPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable during Sleep mode */ +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) /* Bit 29: USB OTG HS clock enable during Sleep mode */ +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable during Sleep mode */ + +/* RCC AHB2 low power modeperipheral clock enable register */ + +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) /* Bit 0: Camera interface enable during Sleep mode */ +#define RCC_AHB2LPENR_CRYPLPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable during Sleep mode */ +#define RCC_AHB2LPENR_HASHLPEN (1 << 5) /* Bit 5: Hash modules clock enable during Sleep mode */ +#define RCC_AHB2LPENR_RNGLPEN (1 << 6) /* Bit 6: Random number generator clock enable during Sleep mode */ +#define RCC_AHB2LPENR_OTGFLPSEN (1 << 7) /* Bit 7: USB OTG FS clock enable during Sleep mode */ + +/* RCC AHB3 low power modeperipheral clock enable register */ + +#define RCC_AHB3LPENR_FSMLPEN (1 << 0) /* Bit 0: Flexible static memory controller module clock + * enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register */ + +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) /* Bit 0: TIM2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) /* Bit 1: TIM3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) /* Bit 2: TIM4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) /* Bit 3: TIM5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) /* Bit 4: TIM6 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) /* Bit 5: TIM7 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) /* Bit 6: TIM12 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) /* Bit 7: TIM13 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) /* Bit 8: TIM14 clock enable during Sleep mode */ +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) /* Bit 11: Window watchdog clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) /* Bit 14: SPI2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) /* Bit 15: SPI3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_USART2LPEN (1 << 17) /* Bit 17: USART 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_USART3LPEN (1 << 18) /* Bit 18: USART3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART4LPEN (1 << 19) /* Bit 19: UART4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART5LPEN (1 << 20) /* Bit 20: UART5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) /* Bit 21: I2C1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) /* Bit 22: I2C2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) /* Bit 23: I2C3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) /* Bit 25: CAN 1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) /* Bit 26: CAN 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_PWRLPEN (1 << 28) /* Bit 28: Power interface clock enable during Sleep mode */ +#define RCC_APB1LPENR_DACLPEN (1 << 29) /* Bit 29: DAC interface clock enable during Sleep mode */ + +/* RCC APB2 low power modeperipheral clock enable register */ + +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) /* Bit 0: TIM1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) /* Bit 1: TIM8 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART1LPEN (1 << 4) /* Bit 4: USART1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART6LPEN (1 << 5) /* Bit 5: USART6 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) /* Bit 8: ADC1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) /* Bit 9: ADC2 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) /* Bit 10: ADC3 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SDIOLPEN (1 << 11) /* Bit 11: SDIO clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) /* Bit 12: SPI1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) /* Bit 14: System configuration controller clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) /* Bit 16: TIM9 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) /* Bit 17: TIM10 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) /* Bit 18: TIM11 clock enable during Sleep mode */ + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_BORRSTF (1 << 25) /* Bit 25: BOR reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* Spread spectrum clock generation register */ + +#define RCC_SSCGR_MODPER_SHIFT (0) /* Bit 0-12: Modulation period */ +#define RCC_SSCGR_MODPER_MASK (0x1fff << RCC_SSCGR_MODPER_SHIFT) +# define RCC_SSCGR_MODPER(n) ((n) << RCC_SSCGR_MODPER_SHIFT) +#define RCC_SSCGR_INCSTEP_SHIFT (13) /* Bit 13-27: Incrementation step */ +#define RCC_SSCGR_INCSTEP_MASK (0x7fff << RCC_SSCGR_INCSTEP_SHIFT) +# define RCC_SSCGR_INCSTEP(n) ((n) << RCC_SSCGR_INCSTEP_SHIFT) +#define RCC_SSCGR_SPREADSEL (1 << 30) /* Bit 30: Spread Select */ +#define RCC_SSCGR_SSCGEN (1 << 31) /* Bit 31: Spread spectrum modulation enable */ + +/* PLLI2S configuration register */ + +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT (6) /* Bits 6-14: PLLI2S multiplication factor for VCO */ +#define RCC_PLLI2SCFGR_PLLI2SN_MASK (0x1ff << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) +#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT (28) /* Bits 28-30: PLLI2S division factor for I2S clocks */ +#define RCC_PLLI2SCFGR_PLLI2SR_MASK (7 << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_RCC_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f20xxx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..7f92a73f4c42b148d765e9ca79cbcf606c61d608 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_syscfg.h @@ -0,0 +1,151 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f20xxx_syscfg.h + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#ifdef CONFIG_STM32_STM32F20XX + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +#define STM32_SYSCFG_CMPCR_OFFSET 0x0020 /* Compensation cell control register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_MEMRMP (STM32_SYSCFG_BASE+STM32_SYSCFG_MEMRMP_OFFSET) +#define STM32_SYSCFG_PMC (STM32_SYSCFG_BASE+STM32_SYSCFG_PMC_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +#define STM32_SYSCFG_CMPCR (STM32_SYSCFG_BASE+STM32_SYSCFG_CMPCR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_MEMRMP_MASK (3 << SYSCFG_MEMRMP_SHIFT) +# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 00: Main Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 01: System Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_FSMC (2 << SYSCFG_MEMRMP_SHIFT) /* 10: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 11: Embedded SRAM (112kB) mapped at 0x0000 0000 */ + +/* SYSCFG peripheral mode configuration register */ + +#define SYSCFG_PMC_MII_RMII_SEL (1 << 23) /* Bit 23: Ethernet PHY interface selection */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ +#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */ +#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* Compensation cell control register */ + +#define SYSCFG_CMPCR_CMPPD (1 << 0) /* Bit 0: Compensation cell power-down */ +#define SYSCFG_CMPCR_READY (1 << 8) /* Bit 8: Compensation cell ready flag */ + +#endif /* CONFIG_STM32_STM32F20XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F20XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_uart.h b/arch/arm/src/stm32/chip/stm32f20xxx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..5e5b4449de00fde9d4e4fb4825e824c034eab3c0 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_uart.h @@ -0,0 +1,229 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_uart.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32F20XXX_UART_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32F20XXX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_SR_OFFSET 0x0000 /* Status register (32-bits) */ +#define STM32_USART_DR_OFFSET 0x0004 /* Data register (32-bits) */ +#define STM32_USART_BRR_OFFSET 0x0008 /* Baud Rate Register (32-bits) */ +#define STM32_USART_CR1_OFFSET 0x000c /* Control register 1 (32-bits) */ +#define STM32_USART_CR2_OFFSET 0x0010 /* Control register 2 (32-bits) */ +#define STM32_USART_CR3_OFFSET 0x0014 /* Control register 3 (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0018 /* Guard time and prescaler register (32-bits) */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NUSART > 0 +# define STM32_USART1_SR (STM32_USART1_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART1_DR (STM32_USART1_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_SR (STM32_USART2_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART2_DR (STM32_USART2_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_SR (STM32_USART3_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART3_DR (STM32_USART3_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_SR (STM32_UART4_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART4_DR (STM32_UART4_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_SR (STM32_UART5_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART5_DR (STM32_UART5_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 5 +# define STM32_USART6_SR (STM32_USART6_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART6_DR (STM32_USART6_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART6_BRR (STM32_USART6_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART6_CR1 (STM32_USART6_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART6_CR2 (STM32_USART6_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART6_CR3 (STM32_USART6_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART6_GTPR (STM32_USART6_BASE+STM32_USART_GTPR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Status register */ + +#define USART_SR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_SR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_SR_NE (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_SR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_SR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_SR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_SR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_SR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_SR_LBD (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_SR_CTS (1 << 9) /* Bit 9: CTS Flag */ + +#define USART_SR_ALLBITS (0x03ff) +#define USART_SR_CLRBITS (USART_SR_CTS|USART_SR_LBD) /* Cleared by SW write to SR */ + +/* Data register */ + +#define USART_DR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_DR_MASK (0xff << USART_DR_SHIFT) + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Control register 1 */ + +#define USART_CR1_SBK (1 << 0) /* Bit 0: Send Break */ +#define USART_CR1_RWU (1 << 1) /* Bit 1: Receiver wakeup */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M (1 << 12) /* Bit 12: word length */ +#define USART_CR1_UE (1 << 13) /* Bit 13: USART Enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE|USART_CR1_TCIE|USART_CR1_PEIE) + +/* Control register 2 */ + +#define USART_CR2_ADD_SHIFT (0) /* Bits 3-0: Address of the USART node */ +#define USART_CR2_ADD_MASK (0x0f << USART_CR2_ADD_SHIFT) +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */ + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Compatibility definitions ********************************************************/ +/* F3 Transmit/Read registers */ + +#define STM32_USART_RDR_OFFSET STM32_USART_DR_OFFSET /* Receive data register */ +#define STM32_USART_TDR_OFFSET STM32_USART_DR_OFFSET /* Transmit data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32F20XXX_UART_H */ diff --git a/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h b/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..1fac7a39271c8d1a787d80c7b58c828a9b2602c2 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f20xxx_vectors.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f20xxx_vectors.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ + +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies ach STM32F20xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f20xxx_irq.h. + * stm32_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 82 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 82 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* Vector 16+0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* Vector 16+1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* Vector 16+2: Tamper and time stamp interrupts */ +VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* Vector 16+3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* Vector 16+4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* Vector 16+5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* Vector 16+6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* Vector 16+7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* Vector 16+8: EXTI Line 2 interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* Vector 16+9: EXTI Line 3 interrupt */ +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* Vector 16+10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1s0, STM32_IRQ_DMA1S0) /* Vector 16+11: DMA1 Stream 0 global interrupt */ +VECTOR(stm32_dma1s1, STM32_IRQ_DMA1S1) /* Vector 16+12: DMA1 Stream 1 global interrupt */ +VECTOR(stm32_dma1s2, STM32_IRQ_DMA1S2) /* Vector 16+13: DMA1 Stream 2 global interrupt */ +VECTOR(stm32_dma1s3, STM32_IRQ_DMA1S3) /* Vector 16+14: DMA1 Stream 3 global interrupt */ +VECTOR(stm32_dma1s4, STM32_IRQ_DMA1S4) /* Vector 16+15: DMA1 Stream 4 global interrupt */ +VECTOR(stm32_dma1s5, STM32_IRQ_DMA1S5) /* Vector 16+16: DMA1 Stream 5 global interrupt */ +VECTOR(stm32_dma1s6, STM32_IRQ_DMA1S6) /* Vector 16+17: DMA1 Stream 6 global interrupt */ +VECTOR(stm32_adc, STM32_IRQ_ADC) /* Vector 16+18: ADC1, ADC2, and ADC3 global interrupt */ +VECTOR(stm32_can1tx, STM32_IRQ_CAN1TX) /* Vector 16+19: CAN1 TX interrupts */ +VECTOR(stm32_can1rx0, STM32_IRQ_CAN1RX0) /* Vector 16+20: CAN1 RX0 interrupts */ +VECTOR(stm32_can1rx1, STM32_IRQ_CAN1RX1) /* Vector 16+21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* Vector 16+22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* Vector 16+23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* Vector 16+24: TIM1 Break interrupt/TIM9 global interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* Vector 16+25: TIM1 Update interrupt/TIM10 global interrupt */ +VECTOR(stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM) /* Vector 16+26: TIM1 Trigger and Commutation interrupts/TIM11 global interrupt */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* Vector 16+27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* Vector 16+28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* Vector 16+29: TIM3 global interrupt */ +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* Vector 16+30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* Vector 16+31: I2C1 event interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* Vector 16+32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* Vector 16+33: I2C2 event interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* Vector 16+34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* Vector 16+35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* Vector 16+36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* Vector 16+37: USART1 global interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* Vector 16+38: USART2 global interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* Vector 16+39: USART3 global interrupt */ +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* Vector 16+40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* Vector 16+41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_otgfswkup, STM32_IRQ_OTGFSWKUP) /* Vector 16+42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +VECTOR(stm32_tim8brk, STM32_IRQ_TIM8BRK) /* Vector 16+43: TIM8 Break interrupt/TIM12 global interrupt */ +VECTOR(stm32_tim8up, STM32_IRQ_TIM8UP) /* Vector 16+44: TIM8 Update interrup/TIM13 global interrupt */ +VECTOR(stm32_tim8trgcom, STM32_IRQ_TIM8TRGCOM) /* Vector 16+45: TIM8 Trigger and Commutation interrupts/TIM14 global interrupt */ +VECTOR(stm32_tim8cc, STM32_IRQ_TIM8CC) /* Vector 16+46: TIM8 Capture Compare interrupt */ +VECTOR(stm32_dma1s7, STM32_IRQ_DMA1S7) /* Vector 16+47: DMA1 Stream 7 global interrupt */ +VECTOR(stm32_fsmc, STM32_IRQ_FSMC) /* Vector 16+48: FSMC global interrupt */ +VECTOR(stm32_sdio, STM32_IRQ_SDIO) /* Vector 16+49: SDIO global interrupt */ +VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* Vector 16+50: TIM5 global interrupt */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* Vector 16+51: SPI3 global interrupt */ +VECTOR(stm32_uart4, STM32_IRQ_UART4) /* Vector 16+52: UART4 global interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* Vector 16+53: UART5 global interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* Vector 16+54: TIM6 global interrupt/DAC1 and DAC2 underrun error interrupts */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* Vector 16+55: TIM7 global interrupt */ +VECTOR(stm32_dma2s0, STM32_IRQ_DMA2S0) /* Vector 16+56: DMA2 Stream 0 global interrupt */ +VECTOR(stm32_dma2s1, STM32_IRQ_DMA2S1) /* Vector 16+57: DMA2 Stream 1 global interrupt */ +VECTOR(stm32_dma2s2, STM32_IRQ_DMA2S2) /* Vector 16+58: DMA2 Stream 2 global interrupt */ +VECTOR(stm32_dma2s3, STM32_IRQ_DMA2S3) /* Vector 16+59: DMA2 Stream 3 global interrupt */ +VECTOR(stm32_dma2s4, STM32_IRQ_DMA2S4) /* Vector 16+60: DMA2 Stream 4 global interrupt */ +VECTOR(stm32_eth, STM32_IRQ_ETH) /* Vector 16+61: Ethernet global interrupt */ +VECTOR(stm32_ethwkup, STM32_IRQ_ETHWKUP) /* Vector 16+62: Ethernet Wakeup through EXTI line interrupt */ +VECTOR(stm32_can2tx, STM32_IRQ_CAN2TX) /* Vector 16+63: CAN2 TX interrupts */ +VECTOR(stm32_can2rx0, STM32_IRQ_CAN2RX0) /* Vector 16+64: CAN2 RX0 interrupts */ +VECTOR(stm32_can2rx1, STM32_IRQ_CAN2RX1) /* Vector 16+65: CAN2 RX1 interrupt */ +VECTOR(stm32_can2sce, STM32_IRQ_CAN2SCE) /* Vector 16+66: CAN2 SCE interrupt */ +VECTOR(stm32_otgfs, STM32_IRQ_OTGFS) /* Vector 16+67: USB On The Go FS global interrupt */ +VECTOR(stm32_dma2s5, STM32_IRQ_DMA2S5) /* Vector 16+68: DMA2 Stream 5 global interrupt */ +VECTOR(stm32_dma2s6, STM32_IRQ_DMA2S6) /* Vector 16+69: DMA2 Stream 6 global interrupt */ +VECTOR(stm32_dma2s7, STM32_IRQ_DMA2S7) /* Vector 16+70: DMA2 Stream 7 global interrupt */ +VECTOR(stm32_usart6, STM32_IRQ_USART6) /* Vector 16+71: USART6 global interrupt */ +VECTOR(stm32_i2c3ev, STM32_IRQ_I2C3EV) /* Vector 16+72: I2C3 event interrupt */ +VECTOR(stm32_i2c3er, STM32_IRQ_I2C3ER) /* Vector 16+73: I2C3 error interrupt */ +VECTOR(stm32_otghsep1out, STM32_IRQ_OTGHSEP1OUT) /* Vector 16+74: USB On The Go HS End Point 1 Out global interrupt */ +VECTOR(stm32_otghsep1in, STM32_IRQ_OTGHSEP1IN) /* Vector 16+75: USB On The Go HS End Point 1 In global interrupt */ +VECTOR(stm32_otghswkup, STM32_IRQ_OTGHSWKUP) /* Vector 16+76: USB On The Go HS Wakeup through EXTI interrupt */ +VECTOR(stm32_otghs, STM32_IRQ_OTGHS) /* Vector 16+77: USB On The Go HS global interrupt */ +VECTOR(stm32_dcmi, STM32_IRQ_DCMI) /* Vector 16+78: DCMI global interrupt */ +VECTOR(stm32_cryp, STM32_IRQ_CRYP) /* Vector 16+79: CRYP crypto global interrupt */ +VECTOR(stm32_hash, STM32_IRQ_HASH) /* Vector 16+80: Hash and Rng global interrupt */ + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_adc.h b/arch/arm/src/stm32/chip/stm32f30xxx_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..5763260eb9ce2a079cf18513f2c7195d209d5808 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_adc.h @@ -0,0 +1,620 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f30xxx_adc.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_ADC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_ADC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ +/* Register Offsets for Each ADC (ADC1, 2, 3, and 4). At offset 0x0000 for master and offset 0x0100 + * for slave. + */ + +#define STM32_ADC_ISR_OFFSET 0x0000 /* ADC interrupt and status register */ +#define STM32_ADC_IER_OFFSET 0x0004 /* ADC interrupt enable register */ +#define STM32_ADC_CR_OFFSET 0x0008 /* ADC control register */ +#define STM32_ADC_CFGR_OFFSET 0x000c /* ADC configuration register */ +#define STM32_ADC_SMPR1_OFFSET 0x0014 /* ADC sample time register 1 */ +#define STM32_ADC_SMPR2_OFFSET 0x0018 /* ADC sample time register 2 */ +#define STM32_ADC_TR1_OFFSET 0x0020 /* ADC watchdog threshold register 1 */ +#define STM32_ADC_TR2_OFFSET 0x0020 /* ADC watchdog threshold register 2 */ +#define STM32_ADC_TR3_OFFSET 0x0020 /* ADC watchdog threshold register 3 */ +#define STM32_ADC_SQR1_OFFSET 0x0030 /* ADC regular sequence register 1 */ +#define STM32_ADC_SQR2_OFFSET 0x0034 /* ADC regular sequence register 2 */ +#define STM32_ADC_SQR3_OFFSET 0x0038 /* ADC regular sequence register 3 */ +#define STM32_ADC_SQR4_OFFSET 0x003c /* ADC regular sequence register 4 */ +#define STM32_ADC_DR_OFFSET 0x0040 /* ADC regular data register */ +#define STM32_ADC_JSQR_OFFSET 0x004c /* ADC injected sequence register */ +#define STM32_ADC_OFR1_OFFSET 0x0060 /* ADC offset register 1 */ +#define STM32_ADC_OFR2_OFFSET 0x0064 /* ADC offset register 2 */ +#define STM32_ADC_OFR3_OFFSET 0x0068 /* ADC offset register 3 */ +#define STM32_ADC_OFR4_OFFSET 0x006c /* ADC data offset register 4 */ +#define STM32_ADC_JDR1_OFFSET 0x0080 /* ADC injected data register 1 */ +#define STM32_ADC_JDR2_OFFSET 0x0084 /* ADC injected data register 2 */ +#define STM32_ADC_JDR3_OFFSET 0x0088 /* ADC injected data register 3 */ +#define STM32_ADC_JDR4_OFFSET 0x008c /* ADC injected data register 4 */ +#define STM32_ADC_AWD2CR_OFFSET 0x00a0 /* ADC analog watchdog 2 configuration register */ +#define STM32_ADC_AWD3CR_OFFSET 0x00a4 /* ADC analog watchdog 3 configuration register */ +#define STM32_ADC_DIFSEL_OFFSET 0x00b0 /* ADC differential mode selection register 2 */ +#define STM32_ADC_CALFACT_OFFSET 0x00b4 /* ADC calibration factors */ + +/* Master and Slave ADC Common Registers */ + +#define STM32_ADC_CSR_OFFSET 0x0000 /* Common status register */ +#define STM32_ADC_CCR_OFFSET 0x0008 /* Common control register */ +#define STM32_ADC_CDR_OFFSET 0x000c /* Common regular data register for dual mode */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_ADC1_ISR (STM32_ADC1_BASE+STM32_ADC_ISR_OFFSET) +#define STM32_ADC1_IER (STM32_ADC1_BASE+STM32_ADC_IER_OFFSET) +#define STM32_ADC1_CR (STM32_ADC1_BASE+STM32_ADC_CR_OFFSET) +#define STM32_ADC1_CFGR (STM32_ADC1_BASE+STM32_ADC_CFGR_OFFSET) +#define STM32_ADC1_SMPR1 (STM32_ADC1_BASE+STM32_ADC_SMPR1_OFFSET) +#define STM32_ADC1_SMPR2 (STM32_ADC1_BASE+STM32_ADC_SMPR2_OFFSET) +#define STM32_ADC1_TR1 (STM32_ADC1_BASE+STM32_ADC_TR1_OFFSET) +#define STM32_ADC1_TR2 (STM32_ADC1_BASE+STM32_ADC_TR2_OFFSET) +#define STM32_ADC1_TR3 (STM32_ADC1_BASE+STM32_ADC_TR3_OFFSET) +#define STM32_ADC1_SQR1 (STM32_ADC1_BASE+STM32_ADC_SQR1_OFFSET) +#define STM32_ADC1_SQR2 (STM32_ADC1_BASE+STM32_ADC_SQR2_OFFSET) +#define STM32_ADC1_SQR3 (STM32_ADC1_BASE+STM32_ADC_SQR3_OFFSET) +#define STM32_ADC1_SQR4 (STM32_ADC1_BASE+STM32_ADC_SQR4_OFFSET) +#define STM32_ADC1_DR (STM32_ADC1_BASE+STM32_ADC_DR_OFFSET) +#define STM32_ADC1_JSQR (STM32_ADC1_BASE+STM32_ADC_JSQR_OFFSET) +#define STM32_ADC1_OFR1 (STM32_ADC1_BASE+STM32_ADC_OFR1_OFFSET) +#define STM32_ADC1_OFR2 (STM32_ADC1_BASE+STM32_ADC_OFR2_OFFSET) +#define STM32_ADC1_OFR3 (STM32_ADC1_BASE+STM32_ADC_OFR3_OFFSET) +#define STM32_ADC1_OFR4 (STM32_ADC1_BASE+STM32_ADC_OFR4_OFFSET) +#define STM32_ADC1_JDR1 (STM32_ADC1_BASE+STM32_ADC_JDR1_OFFSET) +#define STM32_ADC1_JDR2 (STM32_ADC1_BASE+STM32_ADC_JDR2_OFFSET) +#define STM32_ADC1_JDR3 (STM32_ADC1_BASE+STM32_ADC_JDR3_OFFSET) +#define STM32_ADC1_JDR4 (STM32_ADC1_BASE+STM32_ADC_JDR4_OFFSET) +#define STM32_ADC1_AWD2CR (STM32_ADC1_BASE+STM32_ADC_AWD2CR_OFFSET) +#define STM32_ADC1_AWD3CR (STM32_ADC1_BASE+STM32_ADC_AWD3CR_OFFSET) +#define STM32_ADC1_DIFSEL (STM32_ADC1_BASE+STM32_ADC_DIFSEL_OFFSET) +#define STM32_ADC1_CALFACT (STM32_ADC1_BASE+STM32_ADC_CALFACT_OFFSET) + +#define STM32_ADC2_ISR (STM32_ADC2_BASE+STM32_ADC_ISR_OFFSET) +#define STM32_ADC2_IER (STM32_ADC2_BASE+STM32_ADC_IER_OFFSET) +#define STM32_ADC2_CR (STM32_ADC2_BASE+STM32_ADC_CR_OFFSET) +#define STM32_ADC2_CFGR (STM32_ADC2_BASE+STM32_ADC_CFGR_OFFSET) +#define STM32_ADC2_SMPR1 (STM32_ADC2_BASE+STM32_ADC_SMPR1_OFFSET) +#define STM32_ADC2_SMPR2 (STM32_ADC2_BASE+STM32_ADC_SMPR2_OFFSET) +#define STM32_ADC2_TR1 (STM32_ADC2_BASE+STM32_ADC_TR1_OFFSET) +#define STM32_ADC2_TR2 (STM32_ADC2_BASE+STM32_ADC_TR2_OFFSET) +#define STM32_ADC2_TR3 (STM32_ADC2_BASE+STM32_ADC_TR3_OFFSET) +#define STM32_ADC2_SQR1 (STM32_ADC2_BASE+STM32_ADC_SQR1_OFFSET) +#define STM32_ADC2_SQR2 (STM32_ADC2_BASE+STM32_ADC_SQR2_OFFSET) +#define STM32_ADC2_SQR3 (STM32_ADC2_BASE+STM32_ADC_SQR3_OFFSET) +#define STM32_ADC2_SQR4 (STM32_ADC2_BASE+STM32_ADC_SQR4_OFFSET) +#define STM32_ADC2_DR (STM32_ADC2_BASE+STM32_ADC_DR_OFFSET) +#define STM32_ADC2_JSQR (STM32_ADC2_BASE+STM32_ADC_JSQR_OFFSET) +#define STM32_ADC2_OFR1 (STM32_ADC2_BASE+STM32_ADC_OFR1_OFFSET) +#define STM32_ADC2_OFR2 (STM32_ADC2_BASE+STM32_ADC_OFR2_OFFSET) +#define STM32_ADC2_OFR3 (STM32_ADC2_BASE+STM32_ADC_OFR3_OFFSET) +#define STM32_ADC2_OFR4 (STM32_ADC2_BASE+STM32_ADC_OFR4_OFFSET) +#define STM32_ADC2_JDR1 (STM32_ADC2_BASE+STM32_ADC_JDR1_OFFSET) +#define STM32_ADC2_JDR2 (STM32_ADC2_BASE+STM32_ADC_JDR2_OFFSET) +#define STM32_ADC2_JDR3 (STM32_ADC2_BASE+STM32_ADC_JDR3_OFFSET) +#define STM32_ADC2_JDR4 (STM32_ADC2_BASE+STM32_ADC_JDR4_OFFSET) +#define STM32_ADC2_AWD2CR (STM32_ADC2_BASE+STM32_ADC_AWD2CR_OFFSET) +#define STM32_ADC2_AWD3CR (STM32_ADC2_BASE+STM32_ADC_AWD3CR_OFFSET) +#define STM32_ADC2_DIFSEL (STM32_ADC2_BASE+STM32_ADC_DIFSEL_OFFSET) +#define STM32_ADC2_CALFACT (STM32_ADC2_BASE+STM32_ADC_CALFACT_OFFSET) + +#define STM32_ADC12_CSR (STM32_ADC12_BASE+STM32_ADC_CSR_OFFSET) +#define STM32_ADC12_CCR (STM32_ADC12_BASE+STM32_ADC_CCR_OFFSET) +#define STM32_ADC12_CDR (STM32_ADC12_BASE+STM32_ADC_CDR_OFFSET) + +#define STM32_ADC3_ISR (STM32_ADC3_BASE+STM32_ADC_ISR_OFFSET) +#define STM32_ADC3_IER (STM32_ADC3_BASE+STM32_ADC_IER_OFFSET) +#define STM32_ADC3_CR (STM32_ADC3_BASE+STM32_ADC_CR_OFFSET) +#define STM32_ADC3_CFGR (STM32_ADC3_BASE+STM32_ADC_CFGR_OFFSET) +#define STM32_ADC3_SMPR1 (STM32_ADC3_BASE+STM32_ADC_SMPR1_OFFSET) +#define STM32_ADC3_SMPR2 (STM32_ADC3_BASE+STM32_ADC_SMPR2_OFFSET) +#define STM32_ADC3_TR1 (STM32_ADC3_BASE+STM32_ADC_TR1_OFFSET) +#define STM32_ADC3_TR2 (STM32_ADC3_BASE+STM32_ADC_TR2_OFFSET) +#define STM32_ADC3_TR3 (STM32_ADC3_BASE+STM32_ADC_TR3_OFFSET) +#define STM32_ADC3_SQR1 (STM32_ADC3_BASE+STM32_ADC_SQR1_OFFSET) +#define STM32_ADC3_SQR2 (STM32_ADC3_BASE+STM32_ADC_SQR2_OFFSET) +#define STM32_ADC3_SQR3 (STM32_ADC3_BASE+STM32_ADC_SQR3_OFFSET) +#define STM32_ADC3_SQR4 (STM32_ADC3_BASE+STM32_ADC_SQR4_OFFSET) +#define STM32_ADC3_DR (STM32_ADC3_BASE+STM32_ADC_DR_OFFSET) +#define STM32_ADC3_JSQR (STM32_ADC3_BASE+STM32_ADC_JSQR_OFFSET) +#define STM32_ADC3_OFR1 (STM32_ADC3_BASE+STM32_ADC_OFR1_OFFSET) +#define STM32_ADC3_OFR2 (STM32_ADC3_BASE+STM32_ADC_OFR2_OFFSET) +#define STM32_ADC3_OFR3 (STM32_ADC3_BASE+STM32_ADC_OFR3_OFFSET) +#define STM32_ADC3_OFR4 (STM32_ADC3_BASE+STM32_ADC_OFR4_OFFSET) +#define STM32_ADC3_JDR1 (STM32_ADC3_BASE+STM32_ADC_JDR1_OFFSET) +#define STM32_ADC3_JDR2 (STM32_ADC3_BASE+STM32_ADC_JDR2_OFFSET) +#define STM32_ADC3_JDR3 (STM32_ADC3_BASE+STM32_ADC_JDR3_OFFSET) +#define STM32_ADC3_JDR4 (STM32_ADC3_BASE+STM32_ADC_JDR4_OFFSET) +#define STM32_ADC3_AWD2CR (STM32_ADC3_BASE+STM32_ADC_AWD2CR_OFFSET) +#define STM32_ADC3_AWD3CR (STM32_ADC3_BASE+STM32_ADC_AWD3CR_OFFSET) +#define STM32_ADC3_DIFSEL (STM32_ADC3_BASE+STM32_ADC_DIFSEL_OFFSET) +#define STM32_ADC3_CALFACT (STM32_ADC3_BASE+STM32_ADC_CALFACT_OFFSET) + +#define STM32_ADC4_ISR (STM32_ADC4_BASE+STM32_ADC_ISR_OFFSET) +#define STM32_ADC4_IER (STM32_ADC4_BASE+STM32_ADC_IER_OFFSET) +#define STM32_ADC4_CR (STM32_ADC4_BASE+STM32_ADC_CR_OFFSET) +#define STM32_ADC4_CFGR (STM32_ADC4_BASE+STM32_ADC_CFGR_OFFSET) +#define STM32_ADC4_SMPR1 (STM32_ADC4_BASE+STM32_ADC_SMPR1_OFFSET) +#define STM32_ADC4_SMPR2 (STM32_ADC4_BASE+STM32_ADC_SMPR2_OFFSET) +#define STM32_ADC4_TR1 (STM32_ADC4_BASE+STM32_ADC_TR1_OFFSET) +#define STM32_ADC4_TR2 (STM32_ADC4_BASE+STM32_ADC_TR2_OFFSET) +#define STM32_ADC4_TR3 (STM32_ADC4_BASE+STM32_ADC_TR3_OFFSET) +#define STM32_ADC4_SQR1 (STM32_ADC4_BASE+STM32_ADC_SQR1_OFFSET) +#define STM32_ADC4_SQR2 (STM32_ADC4_BASE+STM32_ADC_SQR2_OFFSET) +#define STM32_ADC4_SQR3 (STM32_ADC4_BASE+STM32_ADC_SQR3_OFFSET) +#define STM32_ADC4_SQR4 (STM32_ADC4_BASE+STM32_ADC_SQR4_OFFSET) +#define STM32_ADC4_DR (STM32_ADC4_BASE+STM32_ADC_DR_OFFSET) +#define STM32_ADC4_JSQR (STM32_ADC4_BASE+STM32_ADC_JSQR_OFFSET) +#define STM32_ADC4_OFR1 (STM32_ADC4_BASE+STM32_ADC_OFR1_OFFSET) +#define STM32_ADC4_OFR2 (STM32_ADC4_BASE+STM32_ADC_OFR2_OFFSET) +#define STM32_ADC4_OFR3 (STM32_ADC4_BASE+STM32_ADC_OFR3_OFFSET) +#define STM32_ADC4_OFR4 (STM32_ADC4_BASE+STM32_ADC_OFR4_OFFSET) +#define STM32_ADC4_JDR1 (STM32_ADC4_BASE+STM32_ADC_JDR1_OFFSET) +#define STM32_ADC4_JDR2 (STM32_ADC4_BASE+STM32_ADC_JDR2_OFFSET) +#define STM32_ADC4_JDR3 (STM32_ADC4_BASE+STM32_ADC_JDR3_OFFSET) +#define STM32_ADC4_JDR4 (STM32_ADC4_BASE+STM32_ADC_JDR4_OFFSET) +#define STM32_ADC4_AWD2CR (STM32_ADC4_BASE+STM32_ADC_AWD2CR_OFFSET) +#define STM32_ADC4_AWD3CR (STM32_ADC4_BASE+STM32_ADC_AWD3CR_OFFSET) +#define STM32_ADC4_DIFSEL (STM32_ADC4_BASE+STM32_ADC_DIFSEL_OFFSET) +#define STM32_ADC4_CALFACT (STM32_ADC4_BASE+STM32_ADC_CALFACT_OFFSET) + +#define STM32_ADC34_CSR (STM32_ADC34_BASE+STM32_ADC_CSR_OFFSET) +#define STM32_ADC34_CCR (STM32_ADC34_BASE+STM32_ADC_CCR_OFFSET) +#define STM32_ADC34_CDR (STM32_ADC34_BASE+STM32_ADC_CDR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* ADC interrupt and status register (ISR) and ADC interrupt enable register (IER) */ + +#define ADC_INT_ARDY (1 << 0) /* Bit 0: ADC ready */ +#define ADC_INT_EOSMP (1 << 1) /* Bit 1: End of sampling flag */ +#define ADC_INT_EOC (1 << 2) /* Bit 2: End of conversion */ +#define ADC_INT_EOS (1 << 3) /* Bit 3: End of regular sequence flag */ +#define ADC_INT_OVR (1 << 4) /* Bit 4: Overrun */ +#define ADC_INT_JEOC (1 << 5) /* Bit 5: Injected channel end of conversion */ +#define ADC_INT_JEOS (1 << 6) /* Bit 6: Injected channel end of sequence flag */ +#define ADC_INT_AWD1 (1 << 7) /* Bit 7: Analog watchdog 1 flag */ +#define ADC_INT_AWD2 (1 << 8) /* Bit 8: Analog watchdog 2 flag */ +#define ADC_INT_AWD3 (1 << 9) /* Bit 9: Analog watchdog 3 flag */ +#define ADC_INT_JQOVF (1 << 10) /* Bit 10: Injected context queue overflow */ + +/* ADC control register */ + +#define ADC_CR_ADEN (1 << 0) /* Bit 0: ADC enable control */ +#define ADC_CR_ADDIS (1 << 1) /* Bit 1: ADC disable command */ +#define ADC_CR_ADSTART (1 << 2) /* Bit 2: ADC start of regular conversion */ +#define ADC_CR_JADSTART (1 << 3) /* Bit 3: ADC start of injected conversion */ +#define ADC_CR_ADSTP (1 << 4) /* Bit 4: ADC stop of regular conversion command */ +#define ADC_CR_JADSTP (1 << 5) /* Bit 5: ADC stop of injected conversion command */ +#define ADC_CR_ADVREGEN_SHIFT (28) /* Bits 28-29: ADC voltage regulator enable */ +#define ADC_CR_ADVREGEN_MASK (3 << ADC_CR_ADVREGEN_SHIFT) +# define ADC_CR_ADVREGEN_INTER (0 << ADC_CR_ADVREGEN_SHIFT) /* Intermediate state */ +# define ADC_CR_ADVREGEN_ENABLED (1 << ADC_CR_ADVREGEN_SHIFT) /* ADC Voltage regulator enabled */ +# define ADC_CR_ADVREGEN_DISABLED (2 << ADC_CR_ADVREGEN_SHIFT) /* ADC Voltage regulator disabled */ +#define ADC_CR_ADCALDIF (1 << 30) /* Bit 30: Differential mode for calibration */ +#define ADC_CR_ADCAL (1 << 31) /* Bit 31: ADC calibration */ + +/* ADC configuration register */ + +#define ADC_CFGR_DMAEN (1 << 0) /* Bit 0: Direct memory access enable */ +#define ADC_CFGR_DMACFG (1 << 1) /* Bit 1: Direct memory access configuration */ +#define ADC_CFGR_RES_SHIFT (3) /* Bits 3-4: Data resolution */ +#define ADC_CFGR_RES_MASK (3 << ADC_CFGR_RES_SHIFT) +# define ADC_CFGR_RES_12BIT (0 << ADC_CFGR_RES_SHIFT) /* 15 ADCCLK clyes */ +# define ADC_CFGR_RES_10BIT (1 << ADC_CFGR_RES_SHIFT) /* 13 ADCCLK clyes */ +# define ADC_CFGR_RES_8BIT (2 << ADC_CFGR_RES_SHIFT) /* 11 ADCCLK clyes */ +# define ADC_CFGR_RES_6BIT (3 << ADC_CFGR_RES_SHIFT) /* 9 ADCCLK clyes */ +#define ADC_CFGR_ALIGN (1 << 5) /* Bit 5: Data Alignment */ +#define ADC_CFGR_EXTSEL_SHIFT (6) /* Bits 6-9: External Event Select for regular group */ +#define ADC_CFGR_EXTSEL_MASK (15 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T1CC1 (0 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T1CC2 (1 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T1CC3 (2 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T2CC2 (3 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T3TRGO (4 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T4CC4 (5 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_EXTI11 (6 << ADC_CFGR_EXTSEL_SHIFT) /* 0110: EXTI line 11 */ +# define ADC12_CFGR_EXTSEL_T8TRGO (7 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T1TRGO (9 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T2TRGO (11 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T4TRGO (12 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T6TRGO (13 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T15TRGO (14 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC12_CFGR_EXTSEL_T3CC4 (15 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T3CC1 (0 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T2CC3 (1 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T1CC3 (2 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T8CC1 (3 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T8TRGO (4 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T20TRGO (5 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T4CC1 (6 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T2TRGO (7 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T1TRGO (9 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T3TRGO (11 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T4TRGO (12 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T7TRGO (13 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T15TRGO (14 << ADC_CFGR_EXTSEL_SHIFT) +# define ADC34_CFGR_EXTSEL_T2CC1 (15 << ADC_CFGR_EXTSEL_SHIFT) +#define ADC_CFGR_EXTEN_SHIFT (10) /* Bits 10-11: External trigger/polarity selection regular channels */ +#define ADC_CFGR_EXTEN_MASK (3 << ADC_CFGR_EXTEN_SHIFT) +# define ADC_CFGR_EXTEN_NONE (0 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection disabled */ +# define ADC_CFGR_EXTEN_RISING (1 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on the rising edge */ +# define ADC_CFGR_EXTEN_FALLING (2 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on the falling edge */ +# define ADC_CFGR_EXTEN_BOTH (3 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on both edges */ +#define ADC_CFGR_OVRMOD (1 << 12) /* Bit 12: Overrun Mode */ +#define ADC_CFGR_CONT (1 << 13) /* Bit 13: Continuous mode for regular conversions */ +#define ADC_CFGR_AUTDLY (1 << 14) /* Bit 14: Delayed conversion mode */ +#define ADC_CFGR_DISCEN (1 << 16) /* Bit 16: Discontinuous mode on regular channels */ +#define ADC_CFGR_DISCNUM_SHIFT (17) /* Bits 17-19: Discontinuous mode channel count */ +#define ADC_CFGR_DISCNUM_MASK (7 << ADC_CFGR_DISCNUM_SHIFT) +# define ADC_CFGR_DISCNUM(n) (((n) - 1) << ADC_CFGR_DISCNUM_SHIFT) /* n = 1..8 channels */ +#define ADC_CFGR_JDISCEN (1 << 20) /* Bit 20: Discontinuous mode on injected channels */ +#define ADC_CFGR_JQM (1 << 21) /* Bit 21: JSQR queue mode */ +#define ADC_CFGR_AWD1SGL (1 << 22) /* Bit 22: Enable watchdog on single/all channels */ +#define ADC_CFGR_AWD1EN (1 << 23) /* Bit 23: Analog watchdog enable 1 regular channels */ +#define ADC_CFGR_JAWD1EN (1 << 22) /* Bit 22: Analog watchdog enable 1 injected channels */ +#define ADC_CFGR_JAUTO (1 << 25) /* Bit 25: Automatic Injected Group conversion */ +#define ADC_CFGR_AWD1CH_SHIFT (26) /* Bits 26-30: Analog watchdog 1 channel select bits */ +#define ADC_CFGR_AWD1CH_MASK (31 << ADC_CFGR_AWD1CH_SHIFT) +# define ADC_CFGR_AWD1CH_DISABLED (0 << ADC_CFGR_AWD1CH_SHIFT) + +/* ADC sample time register 1 */ + +#define ADC_SMPR_1p5 0 /* 000: 1.5 cycles */ +#define ADC_SMPR_2p5 1 /* 001: 2.5 cycles */ +#define ADC_SMPR_4p5 2 /* 010: 4.5 cycles */ +#define ADC_SMPR_7p5 3 /* 011: 7.5 cycles */ +#define ADC_SMPR_19p5 4 /* 100: 19.5 cycles */ +#define ADC_SMPR_61p5 5 /* 101: 61.5 cycles */ +#define ADC_SMPR_181p5 6 /* 110: 181.5 cycles */ +#define ADC_SMPR_601p5 7 /* 111: 601.5 cycles */ + +#define ADC_SMPR1_SMP1_SHIFT (3) /* Bits 5-3: Channel 1 Sample time selection */ +#define ADC_SMPR1_SMP1_MASK (7 << ADC_SMPR1_SMP1_SHIFT) +#define ADC_SMPR1_SMP2_SHIFT (6) /* Bits 8-6: Channel 2 Sample time selection */ +#define ADC_SMPR1_SMP2_MASK (7 << ADC_SMPR1_SMP2_SHIFT) +#define ADC_SMPR1_SMP3_SHIFT (9) /* Bits 11-9: Channel 3 Sample time selection */ +#define ADC_SMPR1_SMP3_MASK (7 << ADC_SMPR1_SMP3_SHIFT) +#define ADC_SMPR1_SMP4_SHIFT (12) /* Bits 14-12: Channel 4 Sample time selection */ +#define ADC_SMPR1_SMP4_MASK (7 << ADC_SMPR1_SMP4_SHIFT) +#define ADC_SMPR1_SMP5_SHIFT (15) /* Bits 17-15: Channel 5 Sample time selection */ +#define ADC_SMPR1_SMP5_MASK (7 << ADC_SMPR1_SMP5_SHIFT) +#define ADC_SMPR1_SMP6_SHIFT (18) /* Bits 20-18: Channel 6 Sample time selection */ +#define ADC_SMPR1_SMP6_MASK (7 << ADC_SMPR1_SMP6_SHIFT) +#define ADC_SMPR1_SMP7_SHIFT (21) /* Bits 23-21: Channel 7 Sample time selection */ +#define ADC_SMPR1_SMP7_MASK (7 << ADC_SMPR1_SMP7_SHIFT) +#define ADC_SMPR1_SMP8_SHIFT (24) /* Bits 26-24: Channel 8 Sample time selection */ +#define ADC_SMPR1_SMP8_MASK (7 << ADC_SMPR1_SMP8_SHIFT) +#define ADC_SMPR1_SMP9_SHIFT (27) /* Bits 29-27: Channel 9 Sample time selection */ +#define ADC_SMPR1_SMP9_MASK (7 << ADC_SMPR1_SMP9_SHIFT) + +/* ADC sample time register 2 */ + +#define ADC_SMPR2_SMP10_SHIFT (0) /* Bits 0-2: Channel 10 Sample time selection */ +#define ADC_SMPR2_SMP10_MASK (7 << ADC_SMPR2_SMP10_SHIFT) +#define ADC_SMPR2_SMP11_SHIFT (3) /* Bits 3-5: Channel 11 Sample time selection */ +#define ADC_SMPR2_SMP11_MASK (7 << ADC_SMPR2_SMP11_SHIFT) +#define ADC_SMPR2_SMP12_SHIFT (6) /* Bits 6-8: Channel 12 Sample time selection */ +#define ADC_SMPR2_SMP12_MASK (7 << ADC_SMPR2_SMP12_SHIFT) +#define ADC_SMPR2_SMP13_SHIFT (9) /* Bits 9-11: Channel 13 Sample time selection */ +#define ADC_SMPR2_SMP13_MASK (7 << ADC_SMPR2_SMP13_SHIFT) +#define ADC_SMPR2_SMP14_SHIFT (12) /* Bits 12-14: Channel 14 Sample time selection */ +#define ADC_SMPR2_SMP14_MASK (7 << ADC_SMPR2_SMP14_SHIFT) +#define ADC_SMPR2_SMP15_SHIFT (15) /* Bits 15-17: Channel 15 Sample time selection */ +#define ADC_SMPR2_SMP15_MASK (7 << ADC_SMPR2_SMP15_SHIFT) +#define ADC_SMPR2_SMP16_SHIFT (18) /* Bits 18-20: Channel 16 Sample time selection */ +#define ADC_SMPR2_SMP16_MASK (7 << ADC_SMPR2_SMP16_SHIFT) +#define ADC_SMPR2_SMP17_SHIFT (21) /* Bits 21-23: Channel 17 Sample time selection */ +#define ADC_SMPR2_SMP17_MASK (7 << ADC_SMPR2_SMP17_SHIFT) +#define ADC_SMPR2_SMP18_SHIFT (21) /* Bits 24-26: Channel 18 Sample time selection */ +#define ADC_SMPR2_SMP18_MASK (7 << ADC_SMPR2_SMP17_SHIFT) + +/* ADC watchdog threshold register 1 */ + +#define ADC_TR1_LT_SHIFT (0) /* Bits 0-11: Analog watchdog 1 lower threshold */ +#define ADC_TR1_LT_MASK (0x0fff << ADC_TR1_LT_SHIFT) +#define ADC_TR1_HT_SHIFT (16) /* Bits 16-27: Analog watchdog 1 higher threshold */ +#define ADC_TR1_HT_MASK (0x0fff << ADC_TR1_HT_SHIFT) + +/* ADC watchdog threshold register 2 */ + +#define ADC_TR2_LT_SHIFT (0) /* Bits 0-7: Analog watchdog 2 lower threshold */ +#define ADC_TR2_LT_MASK (0xff << ADC_TR2_LT_SHIFT) +#define ADC_TR2_HT_SHIFT (16) /* Bits 16-23: Analog watchdog 2 higher threshold */ +#define ADC_TR2_HT_MASK (0xff << ADC_TR2_HT_SHIFT) + +/* ADC watchdog threshold register 3 */ + +#define ADC_TR3_LT_SHIFT (0) /* Bits 0-7: Analog watchdog 3 lower threshold */ +#define ADC_TR3_LT_MASK (0xff << ADC_TR3_LT_SHIFT) +#define ADC_TR3_HT_SHIFT (16) /* Bits 16-23: Analog watchdog 3 higher threshold */ +#define ADC_TR3_HT_MASK (0xff << ADC_TR3_HT_SHIFT) + +/* Offset between SQ bits */ + +#define ADC_SQ_OFFSET (6) + +/* ADC regular sequence register 1 */ + +#define ADC_SQR1_L_SHIFT (0) /* Bits 0-3: Regular channel sequence length */ +#define ADC_SQR1_L_MASK (0x0f << ADC_SQR1_L_SHIFT) +#define ADC_SQR1_SQ1_SHIFT (6) /* Bits 6-10: 13th conversion in regular sequence */ +#define ADC_SQR1_SQ1_MASK (0x1f << ADC_SQR1_SQ1_SHIFT) +#define ADC_SQR1_SQ2_SHIFT (12) /* Bits 12-16: 2nd conversion in regular sequence */ +#define ADC_SQR1_SQ2_MASK (0x1f << ADC_SQR1_SQ2_SHIFT) +#define ADC_SQR1_SQ3_SHIFT (18) /* Bits 18-22: 3rd conversion in regular sequence */ +#define ADC_SQR1_SQ3_MASK (0x1f << ADC_SQR1_SQ3_SHIFT) +#define ADC_SQR1_SQ4_SHIFT (24) /* Bits 24-28: 4th conversion in regular sequence */ +#define ADC_SQR1_SQ4_MASK (0x1f << ADC_SQR1_SQ4_SHIFT) +#define ADC_SQR1_RESERVED (0xe0820830) +#define ADC_SQR1_FIRST (1) +#define ADC_SQR1_LAST (4) +#define ADC_SQR1_SQ_OFFSET (1*ADC_SQ_OFFSET) + +/* ADC regular sequence register 2 */ + +#define ADC_SQR2_SQ5_SHIFT (0) /* Bits 4-0: 5th conversion in regular sequence */ +#define ADC_SQR2_SQ5_MASK (0x1f << ADC_SQR2_SQ5_SHIFT) +#define ADC_SQR2_SQ6_SHIFT (6) /* Bits 6-10: 6th conversion in regular sequence */ +#define ADC_SQR2_SQ6_MASK (0x1f << ADC_SQR2_SQ6_SHIFT) +#define ADC_SQR2_SQ7_SHIFT (12) /* Bits 12-16: 7th conversion in regular sequence */ +#define ADC_SQR2_SQ7_MASK (0x1f << ADC_SQR2_SQ7_SHIFT) +#define ADC_SQR2_SQ8_SHIFT (18) /* Bits 18-22: 8th conversion in regular sequence */ +#define ADC_SQR2_SQ8_MASK (0x1f << ADC_SQR2_SQ8_SHIFT) +#define ADC_SQR2_SQ9_SHIFT (24) /* Bits 24-28: 9th conversion in regular sequence */ +#define ADC_SQR2_SQ9_MASK (0x1f << ADC_SQR2_SQ9_SHIFT) +#define ADC_SQR2_RESERVED (0xe0820820) +#define ADC_SQR2_FIRST (5) +#define ADC_SQR2_LAST (9) +#define ADC_SQR2_SQ_OFFSET (0) + +/* ADC regular sequence register 3 */ + +#define ADC_SQR3_SQ10_SHIFT (0) /* Bits 4-0: 10th conversion in regular sequence */ +#define ADC_SQR3_SQ10_MASK (0x1f << ADC_SQR3_SQ10_SHIFT) +#define ADC_SQR3_SQ11_SHIFT (6) /* Bits 6-10: 11th conversion in regular sequence */ +#define ADC_SQR3_SQ11_MASK (0x1f << ADC_SQR3_SQ11_SHIFT) +#define ADC_SQR3_SQ12_SHIFT (12) /* Bits 12-16: 12th conversion in regular sequence */ +#define ADC_SQR3_SQ12_MASK (0x1f << ADC_SQR3_SQ12_SHIFT) +#define ADC_SQR3_SQ13_SHIFT (18) /* Bits 18-22: 13th conversion in regular sequence */ +#define ADC_SQR3_SQ13_MASK (0x1f << ADC_SQR3_SQ13_SHIFT) +#define ADC_SQR3_SQ14_SHIFT (24) /* Bits 24-28: 14th conversion in regular sequence */ +#define ADC_SQR3_SQ14_MASK (0x1f << ADC_SQR3_SQ14_SHIFT) +#define ADC_SQR3_RESERVED (0xe0820820) +#define ADC_SQR3_FIRST (10) +#define ADC_SQR3_LAST (14) +#define ADC_SQR3_SQ_OFFSET (0) + +/* ADC regular sequence register 4 */ + +#define ADC_SQR4_SQ15_SHIFT (0) /* Bits 4-0: 15th conversion in regular sequence */ +#define ADC_SQR4_SQ15_MASK (0x1f << ADC_SQR4_SQ15_SHIFT) +#define ADC_SQR4_SQ16_SHIFT (6) /* Bits 6-10: 16th conversion in regular sequence */ +#define ADC_SQR4_SQ16_MASK (0x1f << ADC_SQR4_SQ16_SHIFT) +#define ADC_SQR4_RESERVED (0xfffff820) +#define ADC_SQR4_FIRST (15) +#define ADC_SQR4_LAST (16) +#define ADC_SQR4_SQ_OFFSET (0) + +/* ADC regular data register */ + +#define ADC_DR_RDATA_SHIFT (0) +#define ADC_DR_RDATA_MASK (0xffff << ADC_DR_RDATA_SHIFT) + +/* ADC injected sequence register */ + +#define ADC_JSQR_JL_SHIFT (0) /* Bits 0-1: Injected Sequence length */ +#define ADC_JSQR_JL_MASK (3 << ADC_JSQR_JL_SHIFT) +# define ADC_JSQR_JL(n) (((n)-1) << ADC_JSQR_JL_SHIFT) /* n=1..4 */ +#define ADC_JSQR_JEXTSEL_SHIFT (2) /* Bits 2-5: External Trigger Selection for injected group */ +#define ADC_JSQR_JEXTSEL_MASK (15 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T1TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T1CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T2TRGO (2 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T2CC1 (3 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T3CC4 (4 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T4TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T20TRGO (6 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T8CC4 (7 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T8TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T3CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T3TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T3CC1 (13 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T6TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC12_JSQR_JEXTSEL_T15TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T1TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T1CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T4CC3 (2 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T8CC2 (3 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T8CC4 (4 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T20TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T4CC4 (6 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T4TRGO (7 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T8TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T1CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T3TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T2TRGO (13 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T7TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC34_JSQR_JEXTSEL_T15TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +# define ADC_JSQR_JEXTEN_SHIFT (6) /* Bits 6-7: External trigger selection for injected greoup */ +# define ADC_JSQR_JEXTEN_MASK (3 << ADC_JSQR_JEXTEN_SHIFT) +# define ADC_JSQR_JEXTEN_NONE (0 << ADC_JSQR_JEXTEN_SHIFT) /* 00: Trigger detection disabled */ +# define ADC_JSQR_JEXTEN_RISING (1 << ADC_JSQR_JEXTEN_SHIFT) /* 01: Trigger detection on the rising edge */ +# define ADC_JSQR_JEXTEN_FALLING (2 << ADC_JSQR_JEXTEN_SHIFT) /* 10: Trigger detection on the falling edge */ +# define ADC_JSQR_JEXTEN_BOTH (3 << ADC_JSQR_JEXTEN_SHIFT) /* 11: Trigger detection on both the rising and falling edges */ +#define ADC_JSQR_JSQ1_SHIFT (8) /* Bits 8-12: 1st conversion in injected sequence */ +#define ADC_JSQR_JSQ1_MASK (0x1f << ADC_JSQR_JSQ1_SHIFT) +# define ADC_JSQR_JSQ1(ch) ((ch) << ADC_JSQR_JSQ1_SHIFT) /* Channel number 1..18 */ +#define ADC_JSQR_JSQ2_SHIFT (14) /* Bits 14-18: 2nd conversion in injected sequence */ +#define ADC_JSQR_JSQ2_MASK (0x1f << ADC_JSQR_JSQ2_MASK) +# define ADC_JSQR_JSQ2(ch) ((ch) << ADC_JSQR_JSQ2_MASK) /* Channel number 1..18 */ +#define ADC_JSQR_JSQ3_SHIFT (20) /* Bits 20-24: 3rd conversion in injected sequence */ +#define ADC_JSQR_JSQ3_MASK (0x1f << ADC_JSQR_JSQ3_SHIFT) +# define ADC_JSQR_JSQ3(ch) ((ch) << ADC_JSQR_JSQ3_SHIFT) /* Channel number 1..18 */ +#define ADC_JSQR_JSQ4_SHIFT (26) /* Bits 26-30: 4th conversion in injected sequence */ +#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT) +# define ADC_JSQR_JSQ4(ch) ((ch) << ADC_JSQR_JSQ4_SHIFT) /* Channel number 1..18 */ + +/* ADC offset register 1, 2, 3, and 4 */ + +#define ADC_OFR_OFFSETY_SHIFT (0) /* Bits 0-11: Data offset y for channel OFFSETY_CH */ +#define ADC_OFR_OFFSETY_MASK (0x0fff << ADC_OFR_OFFSETY_SHIFT) +# define ADC_OFR_OFFSETY(offset) ((offset) << ADC_OFR_OFFSETY_SHIFT) +#define ADC_OFR_OFFSETY_CH_SHIFT (26) /* Bits 26-30: Channel selection for data offset y */ +#define ADC_OFR_OFFSETY_CH_MASK (31 << ADC_OFR_OFFSETY_CH_SHIFT) +# define ADC_OFR_OFFSETY_CH(ch) ((ch) << ADC_OFR_OFFSETY_CH_SHIFT) +#define ADC_OFR_OFFSETY_EN (1 << 31) /* Bit 31: Offset y enable */ + +/* ADC injected data register 1, 2, 3, and 4 */ + +#define ADC_JDR_JDATA_SHIFT (0) +#define ADC_JDR_JDATA_MASK (0xffff << ADC_JDR_JDATA_SHIFT) + +/* ADC analog watchdog 2 configuration register */ + +#define ADC_AWD2CR_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 2 channel selection */ +#define ADC_AWD2CR_CH_MASK (0x3ffff << ADC_AWD2CR_CH_SHIFT) +# define ADC_AWD2CR_CH(n) (1 << (n)) /* Channel n=1..18 */ + +/* ADC analog watchdog 3 configuration register */ + +#define ADC_AWD3CR_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 2 channel selection */ +#define ADC_AWD3CR_CH_MASK (0x3ffff << ADC_AWD3CR_CH_SHIFT) +# define ADC_AWD3CR_CH(n) (1 << (n)) /* Channel n=1..18 */ + +/* ADC differential mode selection register 2 */ +#define ADC_DIFSEL_ + +#define ADC_DIFSEL_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 2 channel selection */ +#define ADC_DIFSEL_CH_MASK (0x3ffff << ADC_DIFSEL_CH_SHIFT) +# define ADC_DIFSEL_CH(n) (1 << (n)) /* Channel n=1..18 */ + +/* ADC calibration factors */ + +#define ADC_CALFACT_S_SHIFT (0) /* Bits 0-6: Calibration factors in single-ended mode */ +#define ADC_CALFACT_S_MASK (0x7f << ADC_CALFACT_S_SHIFT) +#define ADC_CALFACT_D_SHIFT (16) /* Bits 16-22: Calibration Factors indifferential mode */ +#define ADC_CALFACT_D_MASK (0x7f << ADC_CALFACT_D_SHIFT) + +/* Common status register */ + +#define ADC_CSR_ADRDY_MST (1 << 0) /* Bit 0: Master ADC ready */ +#define ADC_CSR_EOSMP_MST (1 << 1) /* Bit 1: End of Sampling phase flag (master ADC) */ +#define ADC_CSR_EOC_MST (1 << 2) /* Bit 2: End of regular conversion (master ADC) */ +#define ADC_CSR_EOS_MST (1 << 3) /* Bit 3: End of regular sequence flag (master ADC) */ +#define ADC_CSR_OVR_MST (1 << 4) /* Bit 4: Overrun flag (master ADC) */ +#define ADC_CSR_JEOC_MST (1 << 5) /* Bit 5: End of injected conversion flag (master ADC) */ +#define ADC_CSR_JEOS_MST (1 << 6) /* Bit 6: End of injected sequence flag (master ADC) */ +#define ADC_CSR_AWD1_MST (1 << 7) /* Bit 7: Analog watchdog 1 flag (master ADC) */ +#define ADC_CSR_AWD2_MST (1 << 8) /* Bit 8: Analog watchdog 2 flag (master ADC) */ +#define ADC_CSR_AWD3_MST (1 << 9) /* Bit 9: Analog watchdog 3 flag (master ADC) */ +#define ADC_CSR_JQOVF_MST (1 << 10) /* Bit 10: Injected Context Queue Overflow flag (master ADC) */ +#define ADC_CSR_ADRDY_SLV (1 << 16) /* Bit 16: Slave ADC ready */ +#define ADC_CSR_EOSMP_SLV (1 << 17) /* Bit 17: End of Sampling phase flag (slave ADC) */ +#define ADC_CSR_EOC_SLV (1 << 18) /* Bit 18: End of regular conversion (slave ADC) */ +#define ADC_CSR_EOS_SLV (1 << 19) /* Bit 19: End of regular sequence flag (slave ADC) */ +#define ADC_CSR_OVR_SLV (1 << 20) /* Bit 20: Overrun flag (slave ADC) */ +#define ADC_CSR_JEOC_SLV (1 << 21) /* Bit 21: End of injected conversion flag (slave ADC) */ +#define ADC_CSR_JEOS_SLV (1 << 22) /* Bit 22: End of injected sequence flag (slave ADC) */ +#define ADC_CSR_AWD1_SLV (1 << 23) /* Bit 23: Analog watchdog 1 flag (slave ADC) */ +#define ADC_CSR_AWD2_SLV (1 << 24) /* Bit 24: Analog watchdog 2 flag (slave ADC) */ +#define ADC_CSR_AWD3_SLV (1 << 25) /* Bit 25: Analog watchdog 3 flag (slave ADC) */ +#define ADC_CSR_JQOVF_SLV (1 << 26) /* Bit 26: Injected Context Queue Overflow flag (slave ADC) */ + +/* Common control register */ + +#define ADC_CCR_DUAL_SHIFT (0) /* Bits 0-4: Dual ADC mode selection */ +#define ADC_CCR_DUAL_MASK (31 << ADC_CCR_DUAL_SHIFT) +# define ADC_CCR_DUAL_IND (0 << ADC_CCR_DUAL_SHIFT) /* Independent mode */ +# define ADC_CCR_DUAL_DUAL (1 << ADC_CCR_DUAL_SHIFT) /* Dual mode, master/slave ADCs together */ +# define ADC_CCR_DUAL_SIMINJ (1 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + injected sim. */ +# define ADC_CCR_DUAL_SIMALT (2 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + alternate trigger */ +# define ADC_CCR_DUAL_INJECTED (5 << ADC_CCR_DUAL_SHIFT) /* Injected simultaneous mode only */ +# define ADC_CCR_DUAL_SIM (6 << ADC_CCR_DUAL_SHIFT) /* Regular simultaneous mode only */ +# define ADC_CCR_DUAL_INTERLEAVE (7 << ADC_CCR_DUAL_SHIFT) /* Interleaved mode only */ +# define ADC_CCR_DUAL_ALT (9 << ADC_CCR_DUAL_SHIFT) /* Alternate trigger mode only */ +#define ADC_CCR_DELAY_SHIFT (8) /* Bits 8-11: Delay between 2 sampling phases */ +#define ADC_CCR_DELAY_MASK (15 << ADC_CCR_DELAY_SHIFT) +# define ADC_CCR_DELAY(n) (((n)-1) << ADC_CCR_DELAY_SHIFT) /* n * TADCCLK, 1-13 */ +#define ADC_CCR_DMACFG (1 << 13) /* Bit 13: DMA configuration (for dual ADC mode) */ +#define ADC_CCR_MDMA_SHIFT (14) /* Bits 14-15: Direct memory access mode for dual ADC mode */ +#define ADC_CCR_MDMA_MASK (3 << ADC_CCR_MDMA_SHIFT) +# define ADC_CCR_MDMA_DISABLED (0 << ADC_CCR_MDMA_SHIFT) /* MDMA mode disabled */ +# define ADC_CCR_MDMA_10_12 (2 << ADC_CCR_MDMA_SHIFT) /* MDMA mode enabled (12 / 10-bit) */ +# define ADC_CCR_MDMA_6_8 (3 << ADC_CCR_MDMA_SHIFT) /* MDMA mode enabled (8 / 6-bit) */ +#define ADC_CCR_CKMODE_SHIFT (16) /* Bits 16-17: ADC clock mode */ +#define ADC_CCR_CKMODE_MASK (15 << ADC_CCR_CKMODE_SHIFT) +# define ADC_CCR_CKMODE_ASYNCH (0 << ADC_CCR_CKMODE_SHIFT) /* Asynchronous clock mode */ +# define ADC_CCR_CKMODE_SYNCH_DIV1 (1 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 1 */ +# define ADC_CCR_CKMODE_SYNCH_DIV2 (2 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 2 */ +# define ADC_CCR_CKMODE_SYNCH_DIV4 (3 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 4 */ +#define ADC_CCR_VREFEN (1 << 22) /* Bit 22: VREFINT enable */ +#define ADC_CCR_TSEN (1 << 23) /* Bit 23: Temperature sensor enable */ +#define ADC_CCR_VBATEN (1 << 24) /* Bit 22: VBAT enable */ + +/* Common regular data register for dual mode */ + +#define ADC_CDR_RDATA_MST_SHIFT (0) /* Bits 0-15: Regular data of the master ADC */ +#define ADC_CDR_RDATA_MST_MASK (0xffff << ADC_CDR_RDATA_MST_SHIFT) +#define ADC_CDR_RDATA_SLV_SHIFT (16) /* Bits 16-31: Regular data of the slave ADC */ +#define ADC_CDR_RDATA_SLV_MASK (0xffff << ADC_CDR_RDATA_SLV_SHIFT) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_ADC_H */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_gpio.h b/arch/arm/src/stm32/chip/stm32f30xxx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..fef3f2149d80035a02123f539d4e285bb10f6b6b --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_gpio.h @@ -0,0 +1,332 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_gpio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alther the number of GPIO pins varies from 37 to 87, there are always 6 GPIO + * ports in the STM32 F302/F303 parts. + */ + +#define STM32_NGPIO_PORTS (6) + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ +#define STM32_GPIO_BRR_OFFSET 0x0028 /* GPIO port bit reset register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_GPIOA_MODER (STM32_GPIOA_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOA_AFRL (STM32_GPIOA_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOA_AFRH (STM32_GPIOA_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOA_BRR (STM32_GPIOA_BASE+STM32_GPIO_BRR_OFFSET) + +#define STM32_GPIOB_MODER (STM32_GPIOB_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOB_AFRL (STM32_GPIOB_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOB_AFRH (STM32_GPIOB_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOB_BRR (STM32_GPIOB_BASE+STM32_GPIO_BRR_OFFSET) + +#define STM32_GPIOC_MODER (STM32_GPIOC_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOC_AFRL (STM32_GPIOC_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOC_AFRH (STM32_GPIOC_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOC_BRR (STM32_GPIOC_BASE+STM32_GPIO_BRR_OFFSET) + +#define STM32_GPIOD_MODER (STM32_GPIOD_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOD_AFRL (STM32_GPIOD_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOD_AFRH (STM32_GPIOD_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOD_BRR (STM32_GPIOD_BASE+STM32_GPIO_BRR_OFFSET) + +#define STM32_GPIOE_MODER (STM32_GPIOE_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOE_AFRL (STM32_GPIOE_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOE_AFRH (STM32_GPIOE_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOE_BRR (STM32_GPIOE_BASE+STM32_GPIO_BRR_OFFSET) + +#define STM32_GPIOF_MODER (STM32_GPIOF_BASE+STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE+STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE+STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE+STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOF_AFRL (STM32_GPIOF_BASE+STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOF_AFRH (STM32_GPIOF_BASE+STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOF_BRR (STM32_GPIOF_BASE+STM32_GPIO_BRR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=OuTput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (3) /* 50 MHz High speed */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +/* GPIO port bit reset register */ + +#define GPIO_BRR(n) (1 << (n)) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_GPIO_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_i2c.h b/arch/arm/src/stm32/chip/stm32f30xxx_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..310bc1023497ec6b7798ae977b210c08f853ecc8 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_i2c.h @@ -0,0 +1,250 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_I2C_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_I2C_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_I2C_CR1_OFFSET 0x0000 /* Control register 1 (32-bit) */ +#define STM32_I2C_CR2_OFFSET 0x0004 /* Control register 2 (32-bit) */ +#define STM32_I2C_OAR1_OFFSET 0x0008 /* Own address register 1 (16-bit) */ +#define STM32_I2C_OAR2_OFFSET 0x000c /* Own address register 2 (16-bit) */ +#define STM32_I2C_TIMINGR_OFFSET 0x0010 /* Timing register */ +#define STM32_I2C_TIMEOUTR_OFFSET 0x0014 /* Timeout register */ +#define STM32_I2C_ISR_OFFSET 0x0018 /* Interrupt and Status register */ +#define STM32_I2C_ICR_OFFSET 0x001c /* Interrupt clear register */ +#define STM32_I2C_PECR_OFFSET 0x0020 /* Packet error checking register */ +#define STM32_I2C_RXDR_OFFSET 0x0024 /* Receive data register */ +#define STM32_I2C_TXDR_OFFSET 0x0028 /* Transmit data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NI2C > 0 +# define STM32_I2C1_CR1 (STM32_I2C1_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C1_CR2 (STM32_I2C1_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C1_OAR1 (STM32_I2C1_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C1_OAR2 (STM32_I2C1_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C1_TIMINGR (STM32_I2C1_BASE+STM32_I2C_TIMINGR_OFFSET) +# define STM32_I2C1_TIMEOUTR (STM32_I2C1_BASE+STM32_I2C_TIMEOUTR_OFFSET) +# define STM32_I2C1_ISR (STM32_I2C1_BASE+STM32_I2C_ISR_OFFSET) +# define STM32_I2C1_ICR (STM32_I2C1_BASE+STM32_I2C_ICR_OFFSET) +# define STM32_I2C1_PECR (STM32_I2C1_BASE+STM32_I2C_PECR_OFFSET) +# define STM32_I2C1_RXDR (STM32_I2C1_BASE+STM32_I2C_RXDR_OFFSET) +# define STM32_I2C1_TXDR (STM32_I2C1_BASE+STM32_I2C_TXDR_OFFSET) +#endif + +#if STM32_NI2C > 1 +# define STM32_I2C2_CR1 (STM32_I2C2_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C2_CR2 (STM32_I2C2_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C2_OAR1 (STM32_I2C2_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C2_OAR2 (STM32_I2C2_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C2_TIMINGR (STM32_I2C2_BASE+STM32_I2C_TIMINGR_OFFSET) +# define STM32_I2C2_TIMEOUTR (STM32_I2C2_BASE+STM32_I2C_TIMEOUTR_OFFSET) +# define STM32_I2C2_ISR (STM32_I2C2_BASE+STM32_I2C_ISR_OFFSET) +# define STM32_I2C2_ICR (STM32_I2C2_BASE+STM32_I2C_ICR_OFFSET) +# define STM32_I2C2_PECR (STM32_I2C2_BASE+STM32_I2C_PECR_OFFSET) +# define STM32_I2C2_RXDR (STM32_I2C2_BASE+STM32_I2C_RXDR_OFFSET) +# define STM32_I2C2_TXDR (STM32_I2C2_BASE+STM32_I2C_TXDR_OFFSET) +#endif + +#if STM32_NI2C > 2 +# define STM32_I2C3_CR1 (STM32_I2C3_BASE+STM32_I2C_CR1_OFFSET) +# define STM32_I2C3_CR2 (STM32_I2C3_BASE+STM32_I2C_CR2_OFFSET) +# define STM32_I2C3_OAR1 (STM32_I2C3_BASE+STM32_I2C_OAR1_OFFSET) +# define STM32_I2C3_OAR2 (STM32_I2C3_BASE+STM32_I2C_OAR2_OFFSET) +# define STM32_I2C3_TIMINGR (STM32_I2C3_BASE+STM32_I2C_TIMINGR_OFFSET) +# define STM32_I2C3_TIMEOUTR (STM32_I2C3_BASE+STM32_I2C_TIMEOUTR_OFFSET) +# define STM32_I2C3_ISR (STM32_I2C3_BASE+STM32_I2C_ISR_OFFSET) +# define STM32_I2C3_ICR (STM32_I2C3_BASE+STM32_I2C_ICR_OFFSET) +# define STM32_I2C3_PECR (STM32_I2C3_BASE+STM32_I2C_PECR_OFFSET) +# define STM32_I2C3_RXDR (STM32_I2C3_BASE+STM32_I2C_RXDR_OFFSET) +# define STM32_I2C3_TXDR (STM32_I2C3_BASE+STM32_I2C_TXDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define I2C_CR1_PE (1 << 0) /* Bit 0: Peripheral Enable */ +#define I2C_CR1_TXIE (1 << 1) /* Bit 1: TX Interrupt enable */ +#define I2C_CR1_RXIE (1 << 2) /* Bit 2: RX Interrupt enable */ +#define I2C_CR1_ADDRIE (1 << 3) /* Bit 3: Address match interrupt enable (slave) */ +#define I2C_CR1_NACKIE (1 << 4) /* Bit 4: Not acknowledge received interrupt enable */ +#define I2C_CR1_STOPIE (1 << 5) /* Bit 5: STOP detection interrupt enable */ +#define I2C_CR1_TCIE (1 << 6) /* Bit 6: Transfer Complete interrupt enable */ +#define I2C_CR1_ERRIE (1 << 7) /* Bit 7: Error interrupts enable */ +#define I2C_CR1_DNF_SHIFT (8) /* Bits 8-11: Digital noise filter */ +#define I2C_CR1_DNF_MASK (15 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF_DISABLE (0 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF(n) ((n) << I2C_CR1_DNF_SHIFT) /* Up to n * Ti2cclk, n=1..15 */ +#define I2C_CR1_ANFOFF (1 << 12) /* Bit 12: Analog noise filter OFF */ +#define I2C_CR1_TXDMAEN (1 << 14) /* Bit 14: DMA transmission requests enable */ +#define I2C_CR1_RXDMAEN (1 << 15) /* Bit 15: DMA reception requests enable */ +#define I2C_CR1_SBC (1 << 16) /* Bit 16: Slave byte control */ +#define I2C_CR1_NOSTRETCH (1 << 17) /* Bit 17: Clock stretching disable */ +#define I2C_CR1_WUPEN (1 << 18) /* Bit 18: Wakeup from STOP enable */ +#define I2C_CR1_GCEN (1 << 19) /* Bit 19: General call enable */ +#define I2C_CR1_SMBHEN (1 << 20) /* Bit 20: SMBus Host address enable */ +#define I2C_CR1_SMBDEN (1 << 21) /* Bit 21: SMBus Device Default address enable */ +#define I2C_CR1_ALERTEN (1 << 22) /* Bit 22: SMBus alert enable */ +#define I2C_CR1_PECEN (1 << 23) /* Bit 23: PEC enable */ + +/* Control register 2 */ + +#define I2C_CR2_SADD10_SHIFT (0) /* Bits 0-9: Slave 10-bit address (master) */ +#define I2C_CR2_SADD10_MASK (0x3ff << I2C_CR2_SADD10_SHIFT) +#define I2C_CR2_SADD7_SHIFT (1) /* Bits 1-7: Slave 7-bit address (master) */ +#define I2C_CR2_SADD7_MASK (0x7f << I2C_CR2_SADD7_SHIFT) +#define I2C_CR2_RD_WRN (1 << 10) /* Bit 10: Transfer direction (master) */ +#define I2C_CR2_ADD10 (1 << 11) /* Bit 11: 10-bit addressing mode (master) */ +#define I2C_CR2_HEAD10R (1 << 12) /* Bit 12: 10-bit address header only read direction (master) */ +#define I2C_CR2_START (1 << 13) /* Bit 13: Start generation */ +#define I2C_CR2_STOP (1 << 14) /* Bit 14: Stop generation (master) */ +#define I2C_CR2_NACK (1 << 15) /* Bit 15: NACK generation (slave) */ +#define I2C_CR2_NBYTES_SHIFT (16) /* Bits 16-23: Number of bytes */ +#define I2C_CR2_NBYTES_MASK (0xff << I2C_CR2_NBYTES_SHIFT) +#define I2C_CR2_RELOAD (1 << 24) /* Bit 24: NBYTES reload mode */ +#define I2C_CR2_AUTOEND (1 << 25) /* Bit 25: Automatic end mode (master) */ +#define I2C_CR2_PECBYTE (1 << 26) /* Bit 26: Packet error checking byte */ + +/* Own address register 1 */ + +#define I2C_OAR1_OA1_10_SHIFT (0) /* Bits 0-9: 10-bit interface address */ +#define I2C_OAR1_OA1_10_MASK (0x3ff << I2C_OAR1_OA1_10_SHIFT) +#define I2C_OAR1_OA1_7_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR1_OA1_7_MASK (0x7f << I2C_OAR1_OA1_7_SHIFT) +#define I2C_OAR1_OA1MODE (1 << 10) /* Bit 10: Own Address 1 10-bit mode */ +#define I2C_OAR1_ONE (1 << 14) /* Bit 14: always keep on in software */ +#define I2C_OAR1_OA1EN (1 << 15) /* Bit 15: Own Address 1 enable */ + +/* Own address register 2 */ + +#define I2C_OAR2_OA2_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR2_OA2_MASK (0x7f << I2C_OAR2_OA2_SHIFT) +#define I2C_OAR2_OA2MSK_SHIFT (8) /* Bits 8-10: Own Address 2 masks */ +#define I2C_OAR2_OA2MSK_MASK (7 << I2C_OAR2_OA2MSK_SHIFT) +# define I2C_OAR2_OA2MSK_NONE (0 << I2C_OAR2_OA2MSK_SHIFT) /* No mask */ +# define I2C_OAR2_OA2MSK_2_7 (1 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:2] are compared */ +# define I2C_OAR2_OA2MSK_3_7 (2 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:3] are compared */ +# define I2C_OAR2_OA2MSK_4_7 (3 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:4] are compared */ +# define I2C_OAR2_OA2MSK_5_7 (4 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:5] are compared */ +# define I2C_OAR2_OA2MSK_6_7 (5 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:6] are compared */ +# define I2C_OAR2_OA2MSK_7 (6 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7] is compared */ +# define I2C_OAR2_OA2MSK_ALL (7 << I2C_OAR2_OA2MSK_SHIFT) /* All 7-bit addresses acknowledged */ +#define I2C_OAR2_OA2EN (1 << 15) /* Bit 15: Own Address 2 enable */ + +/* Timing register */ + +#define I2C_TIMINGR_SCLL_SHIFT (0) /* Bits 0-7: SCL low period (master) */ +#define I2C_TIMINGR_SCLL_MASK (0xff << I2C_TIMINGR_SCLL_SHIFT) +# define I2C_TIMINGR_SCLL(n) (((n)-1) << I2C_TIMINGR_SCLL_SHIFT) /* tSCLL = n x tPRESC */ + +#define I2C_TIMINGR_SCLH_SHIFT (8) /* Bits 8-15: SCL high period (master) */ +#define I2C_TIMINGR_SCLH_MASK (0xff << I2C_TIMINGR_SCLH_SHIFT) +# define I2C_TIMINGR_SCLH(n) (((n)-1) << I2C_TIMINGR_SCLH_SHIFT) /* tSCLH = n x tPRESC */ + +#define I2C_TIMINGR_SDADEL_SHIFT (16) /* Bits 16-19: Data hold time */ +#define I2C_TIMINGR_SDADEL_MASK (15 << I2C_TIMINGR_SDADEL_SHIFT) +# define I2C_TIMINGR_SDADEL(n) ((n) << I2C_TIMINGR_SDADEL_SHIFT) /* tSDADEL= n x tPRESC */ + +#define I2C_TIMINGR_SCLDEL_SHIFT (20) /* Bits 20-23: Data setup time */ +#define I2C_TIMINGR_SCLDEL_MASK (15 << I2C_TIMINGR_SCLDEL_SHIFT) +# define I2C_TIMINGR_SCLDEL(n) (((n)-1) << I2C_TIMINGR_SCLDEL_SHIFT) /* tSCLDEL = n x tPRESC */ + +#define I2C_TIMINGR_PRESC_SHIFT (28) /* Bits 28-31: Timing prescaler */ +#define I2C_TIMINGR_PRESC_MASK (15 << I2C_TIMINGR_PRESC_SHIFT) +# define I2C_TIMINGR_PRESC(n) (((n)-1) << I2C_TIMINGR_PRESC_SHIFT) /* tPRESC = n x tI2CCLK */ + +/* Timeout register */ + +#define I2C_TIMEOUTR_A_SHIFT (0) /* Bits 0-11: Bus Timeout A */ +#define I2C_TIMEOUTR_A_MASK (0x0fff << I2C_TIMEOUTR_A_SHIFT) +# define I2C_TIMEOUTR_A(n) ((n) << I2C_TIMEOUTR_A_SHIFT) +#define I2C_TIMEOUTR_TIDLE (1 << 12) /* Bit 12: Idle clock timeout detection */ +#define I2C_TIMEOUTR_TIMOUTEN (1 << 15) /* Bit 15: Clock timeout enable */ +#define I2C_TIMEOUTR_B_SHIFT (16) /* Bits 16-27: Bus Timeout B */ +#define I2C_TIMEOUTR_B_MASK (0x0fff << I2C_TIMEOUTR_B_SHIFT) +# define I2C_TIMEOUTR_B(n) ((n) << I2C_TIMEOUTR_B_SHIFT) +#define I2C_TIMEOUTR_TEXTEN (1 << 31) /* Bits 31: Extended clock timeout enable */ + +/* Interrupt and Status register and interrupt clear register */ +/* Common interrupt bits */ + +#define I2C_INT_ADDR (1 << 3) /* Bit 3: Address matched (slave) */ +#define I2C_INT_NACK (1 << 4) /* Bit 4: Not Acknowledge received flag */ +#define I2C_INT_STOP (1 << 5) /* Bit 5: Stop detection flag */ +#define I2C_INT_BERR (1 << 8) /* Bit 8: Bus error */ +#define I2C_INT_ARLO (1 << 9) /* Bit 9: Arbitration lost */ +#define I2C_INT_OVR (1 << 10) /* Bit 10: Overrun/Underrun (slave) */ +#define I2C_INT_PECERR (1 << 11) /* Bit 11: PEC Error in reception */ +#define I2C_INT_TIMEOUT (1 << 12) /* Bit 12: Timeout or tLOW detection flag */ +#define I2C_INT_ALERT (1 << 13) /* Bit 13: SMBus alert */ + +/* Fields unique to the Interrupt and Status register */ + +#define I2C_ISR_TXE (1 << 0) /* Bit 0: Transmit data register empty (transmitters) */ +#define I2C_ISR_TXIS (1 << 1) /* Bit 1: Transmit interrupt status (transmitters) */ +#define I2C_ISR_RXNE (1 << 2) /* Bit 2: Receive data register not empty (receivers) */ +#define I2C_ISR_TC (1 << 6) /* Bit 6: Transfer Complete (master) */ +#define I2C_ISR_TCR (1 << 7) /* Bit 7: Transfer Complete Reload */ +#define I2C_ISR_BUSY (1 << 15) /* Bit 15: Bus busy */ +#define I2C_ISR_DIR (1 << 16) /* Bit 16: Transfer direction (slave) */ +#define I2C_ISR_ADDCODE_SHIFT (17) /* Bits 17-23: Address match code (slave) */ +#define I2C_ISR_ADDCODE_MASK (0x7f << I2C_ISR_ADDCODE_SHIFT) + +#define I2C_ISR_ERRORMASK (I2C_INT_BERR | I2C_INT_ARLO | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT) + +#define I2C_ICR_CLEARMASK (I2C_INT_ADDR | I2C_INT_NACK | I2C_INT_STOP | I2C_INT_BERR | I2C_INT_ARLO \ + | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT | I2C_INT_ALERT) + +/* Packet error checking register */ + +#define I2C_PECR_MASK (0xff) + +/* Receive data register */ + +#define I2C_RXDR_MASK (0xff) + +/* Transmit data register */ + +#define I2C_TXDR_MASK (0xff) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_I2C_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f30xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..51cca40eef5b276b5c2e291f89e6c142ae05e6f3 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_memorymap.h @@ -0,0 +1,164 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ + /* 0x60000000-0xdfffffff: Reserved */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x0fffffff: Reserved */ +#define STM32_CCMRAM_BASE 0x10000000 /* 0x10000000-0x1000ffff: 64Kb CCM data RAM */ + /* 0x10010000-0x1ffeffff: Reserved */ +#define STM32_SYSMEM_BASE 0x1fffd800 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32_OPTION_BASE 0x1ffff800 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32_SYSMEM_UID 0x1ffff7ac /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x1ffff7cc /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x040 corresponds + * to 64 Kbytes + */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x40009fff: APB1 */ + /* 0x4000a000-0x4000ffff: Reserved */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x40006bff: APB2 */ + /* 0x40016c00-0x4001ffff: Reserved */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x400243ff: APB1 */ + /* 0x40024400-0x4007ffff: Reserved */ +#define STM32_AHB2_BASE 0x48000000 /* 0x48000000-0x480017ff: AHB2 */ + /* 0x48001800-0x4fffFfff: Reserved */ +#define STM32_AHB3_BASE 0x50000000 /* 0x50000000-0x500007ff: AHB3 */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff TIM2 */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff TIM3 */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff TIM4 */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff TIM6 */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff TIM7 */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff RTC */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff WWDG */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff IWDG */ +#define STM32_I2S2EXT_BASE 0x40003400 /* 0x40003400-0x400037ff I2S2ext */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff SPI2, or */ +#define STM32_I2S2_BASE 0x40003800 /* 0x40003800-0x40003bff I2S2 */ +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff SPI3, or */ +#define STM32_I2S3_BASE 0x40003c00 /* 0x40003c00-0x40003fff I2S3 */ +#define STM32_I2S3EXT_BASE 0x40004000 /* 0x40004000-0x400043ff I2S3ext */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00-0x40005fff USB device FS */ +#define STM32_USBRAM_BASE 0x40006000 /* 0x40006000-0x400063ff USB SRAM 512B */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff bxCAN */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400-0x400077ff DAC (dual) */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103FF SYSCFG + COMP + OPAMP */ +#define STM32_EXTI_BASE 0x40010400 /* 0x40010400-0x400107FF EXTI */ +#define STM32_TIM1_BASE 0x40012c00 /* 0x40012c00-0x40012fff TIM1 */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */ +#define STM32_TIM8_BASE 0x40013400 /* 0x40013400-0x400137ff TIM8 */ +#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */ +#define STM32_TIM15_BASE 0x40014000 /* 0x40014000-0x400143ff TIM15 */ +#define STM32_TIM16_BASE 0x40014400 /* 0x40014400-0x400147ff TIM16 */ +#define STM32_TIM17_BASE 0x40014800 /* 0x40014800-0x40014bff TIM17 */ + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32_DMA1_BASE 0x40020000 /* 0x40020000-0x400203ff: DMA1 */ +#define STM32_DMA2_BASE 0x40020400 /* 0x40020400-0x400207ff: DMA2 */ +#define STM32_RCC_BASE 0x40021000 /* 0x40021000-0x400213ff: Reset and Clock control RCC */ +#define STM32_FLASHIF_BASE 0x40022000 /* 0x40022000-0x400223ff: Flash memory interface */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ +#define STM32_TSC_BASE 0x40024000 /* 0x40024000-0x400243ff: TSC */ + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32_GPIOA_BASE 0x48000000 /* 0x48000000-0x480003ff: GPIO Port A */ +#define STM32_GPIOB_BASE 0x48000400 /* 0x48000400-0x480007ff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x48000800 /* 0x48000800-0x48000bff: GPIO Port C */ +#define STM32_GPIOD_BASE 0X48000C00 /* 0x48000c00-0x48000fff: GPIO Port D */ +#define STM32_GPIOE_BASE 0x48001000 /* 0x48001000-0x480013ff: GPIO Port E */ +#define STM32_GPIOF_BASE 0x48001400 /* 0x48001400-0x480017ff: GPIO Port F */ + +/* AHB3 Base Addresses **************************************************************/ + +#define STM32_ADC1_BASE 0x50000000 /* 0x5000004c-0x5000004c: Master ADC1 */ +#define STM32_ADC2_BASE 0x50000100 /* 0x5000014c-0x500001ff: Slave ADC2 */ +#define STM32_ADC12_BASE 0x50000300 /* 0x50000300-0x50000308: ADC12 Common */ +#define STM32_ADC3_BASE 0x50000400 /* 0x5000044c-0x5000044c: Master ADC3 */ +#define STM32_ADC4_BASE 0x50000500 /* 0x5000054c-0x500005ff: Slave ADC4 */ +#define STM32_ADC34_BASE 0x50000700 /* 0x50000700-0x50000708: ADC34 Common */ + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M4 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..0c513ecad88f2a69ff0d8911324f8b017c4dac65 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h @@ -0,0 +1,669 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32F30xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN2) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN13) + +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN2) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN14) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN15) + +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN9) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN13) +#define GPIO_ADC3_IN5 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN10) +#define GPIO_ADC3_IN8 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN11) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN12) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN13) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN14) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN7) +#define GPIO_ADC3_IN14 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN10) +#define GPIO_ADC3_IN15 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN11) +#define GPIO_ADC3_IN16 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN12) + +#define GPIO_ADC4_IN1 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN14) +#define GPIO_ADC4_IN2 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN15) +#define GPIO_ADC4_IN3 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ADC4_IN4 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN14) +#define GPIO_ADC4_IN5 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN15) +#define GPIO_ADC4_IN6 (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN8) +#define GPIO_ADC4_IN7 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN10) +#define GPIO_ADC4_IN8 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN11) +#define GPIO_ADC4_IN9 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN12) +#define GPIO_ADC4_IN10 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN13) +#define GPIO_ADC4_IN11 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN14) +#define GPIO_ADC4_IN12 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN8) +#define GPIO_ADC4_IN13 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN9) + +/* CAN */ + +#define GPIO_CAN_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CAN_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN_TX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_25MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) + +/* Comparator Outputs */ + +#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN4) +#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN0) +#define GPIO_COMP1_OUT_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN11) +#define GPIO_COMP1_OUT_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN6) +#define GPIO_COMP1_OUT_5 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN8) +#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN2) +#define GPIO_COMP2_OUT_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN7) +#define GPIO_COMP2_OUT_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN9) +#define GPIO_COMP3_OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN8) +#define GPIO_COMP3_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN8) +#define GPIO_COMP4_OUT (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN1) +#define GPIO_COMP5_OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN7) +#define GPIO_COMP5_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN9) +#define GPIO_COMP6_OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN6) +#define GPIO_COMP6_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN10) +#define GPIO_COMP7_OUT (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN2) + +/* DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN14) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN6) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN10) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) + +/* I2S */ + +#define GPIO_I2S2_CK (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_MCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2S2_MCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_SD (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_I2S2_WS (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2EXT_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2S3EXT_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S3EXT_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN11) + +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_MCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2S3_MCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2S3_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_I2S_CKIN (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) + +/* IR */ + +#define GPIO_IR_OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN13) +#define GPIO_IR_OUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN9) + +/* JTAG/SWD */ + +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO_TRACES_WO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_NJTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SWCLK_JTCK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_SWDIO_JTMS (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) + +/* MCO */ + +#define GPIO_MCO (GPIO_ALT|GPIO_AF0|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN3) + +#define GPIO_SPI2_MISO (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MOSI (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN15) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN10) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN9) + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) + +/* Timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_TIM1_BKIN_4 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_5 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_6 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM1_BKIN2_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_TIM1_BKIN2_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH1N_4 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_5 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_4 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_4 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1_ETR_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1_ETR_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_TIM2_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_TIM2_CH3OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_TIM2_CH4OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TIM3_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TIM3_CH2OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TIM3_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM3_CH4OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM3_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM3_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM4_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM4_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM4_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM4_ETR_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN2) +#define GPIO_TIM8_BKIN_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_5 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_BKIN2_1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN2_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_TIM8_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM8_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) +#define GPIO_TIM8_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM8_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_TIM8_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM8_CH2N_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_TIM8_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM8_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_TIM8_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_TIM15_BKIN (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM15_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM15_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) + +#define GPIO_TIM16_BKIN (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM16_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM16_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM16_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM16_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM16_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM16_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_TIM17_BKIN_1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM17_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1N (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) + +/* TSC */ + +#define GPIO_TSC_G1_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TSC_G1_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TSC_G1_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TSC_G1_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TSC_G2_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TSC_G2_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TSC_G2_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TSC_G2_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TSC_G3_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN5) +#define GPIO_TSC_G3_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TSC_G3_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TSC_G3_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN2) +#define GPIO_TSC_G4_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TSC_G4_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TSC_G4_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TSC_G4_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN14) +#define GPIO_TSC_G5_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TSC_G5_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TSC_G5_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TSC_G5_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TSC_G6_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TSC_G6_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TSC_G6_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TSC_G6_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TSC_G7_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TSC_G7_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TSC_G7_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TSC_G7_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TSC_G8_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TSC_G8_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TSC_G8_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TSC_G8_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TSC_SYNC_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TSC_SYNC_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN8) + +/* Trace */ + +#define GPIO_TRACECK (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) + +/* USARTs/UARTs */ + +#define GPIO_USART1_CK (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN5) +#define GPIO_USART1_RX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN4) +#define GPIO_USART1_TX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN5) +#define GPIO_USART2_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART2_RX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN14) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART2_TX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN13) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTF|GPIO_PIN6) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN8) + +#define GPIO_UART4_RX (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF5|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) + +/* USB */ + +#define GPIO_USB_DM (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USB_DP (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) + +/* Event Outputs */ + +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA1_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN1) +#define GPIO_PA2_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN2) +#define GPIO_PA3_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN3) +#define GPIO_PA4_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN4) +#define GPIO_PA5_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN5) +#define GPIO_PA6_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN6) +#define GPIO_PA7_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN7) +#define GPIO_PA8_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN8) +#define GPIO_PA9_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN9) +#define GPIO_PA10_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN10) +#define GPIO_PA11_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN11) +#define GPIO_PA12_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN12) +#define GPIO_PA13_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_PB0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN0) +#define GPIO_PB1_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN1) +#define GPIO_PB2_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN2) +#define GPIO_PB3_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN4) +#define GPIO_PB5_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN5) +#define GPIO_PB6_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN6) +#define GPIO_PB7_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN7) +#define GPIO_PB8_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN8) +#define GPIO_PB9_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN9) +#define GPIO_PB10_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN10) +#define GPIO_PB11_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN11) +#define GPIO_PB12_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN12) +#define GPIO_PB13_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN13) +#define GPIO_PB14_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN14) +#define GPIO_PB15_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN15) + +#define GPIO_PC0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN0) +#define GPIO_PC1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN1) +#define GPIO_PC2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN2) +#define GPIO_PC3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN3) +#define GPIO_PC4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN4) +#define GPIO_PC5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5) +#define GPIO_PC6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN6) +#define GPIO_PC7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN7) +#define GPIO_PC8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN8) +#define GPIO_PC9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN9) +#define GPIO_PC10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN10) +#define GPIO_PC11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PC12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_PD0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN0) +#define GPIO_PD1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN1) +#define GPIO_PD2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN2) +#define GPIO_PD3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN3) +#define GPIO_PD4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN4) +#define GPIO_PD5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN5) +#define GPIO_PD6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PD7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN7) +#define GPIO_PD8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN8) +#define GPIO_PD9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN9) +#define GPIO_PD10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN10) +#define GPIO_PD11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN11) +#define GPIO_PD12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN12) +#define GPIO_PD13_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN13) +#define GPIO_PD14_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN14) +#define GPIO_PD15_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN15) + +#define GPIO_PE0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN0) +#define GPIO_PE1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN1) +#define GPIO_PE2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN2) +#define GPIO_PE3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN3) +#define GPIO_PE4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN4) +#define GPIO_PE5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN5) +#define GPIO_PE6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN6) +#define GPIO_PE7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN7) +#define GPIO_PE8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_PE9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN9) +#define GPIO_PE10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_PE11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN11) +#define GPIO_PE12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_PE13_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN13) +#define GPIO_PE14_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN14) +#define GPIO_PE15_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) + +#define GPIO_PF2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN2) +#define GPIO_PF4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN4) +#define GPIO_PF6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN6) +#define GPIO_PF9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN9) +#define GPIO_PF10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN10) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f30xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..e0cd8bb4392e792cd82beb860de4fc28dc738377 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_rcc.h @@ -0,0 +1,398 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xx_rcc.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_RCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_CFGR_OFFSET 0x0004 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x0008 /* Clock interrupt register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x000c /* APB2 Peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0010 /* APB1 Peripheral reset register */ +#define STM32_RCC_AHBENR_OFFSET 0x0014 /* AHB Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0018 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x001c /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0020 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0024 /* Control/status register */ +#define STM32_RCC_AHBRSTR_OFFSET 0x0028 /* AHB Reset register */ +#define STM32_RCC_CFGR2_OFFSET 0x002c /* Clock configuration register 2 */ +#define STM32_RCC_CFGR3_OFFSET 0x0030 /* Clock configuration register 3 */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_AHBENR (STM32_RCC_BASE+STM32_RCC_AHBENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#define STM32_RCC_AHBRSTR (STM32_RCC_BASE+STM32_RCC_AHBRSTR_OFFSET) +#define STM32_RCC_CFGR2 (STM32_RCC_BASE+STM32_RCC_CFGR2_OFFSET) +#define STM32_RCC_CFGR3 (STM32_RCC_BASE+STM32_RCC_CFGR3_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 1-0: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 3-2: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 7-4: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 10-8: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 13-11: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PLLSRC (1 << 16) /* Bit 16: PLL entry clock source */ +#define RCC_CFGR_PLLXTPRE (1 << 17) /* Bit 17: HSE divider for PLL entry */ +#define RCC_CFGR_PLLMUL_SHIFT (18) /* Bits 21-18: PLL Multiplication Factor */ +#define RCC_CFGR_PLLMUL_MASK (0x0f << RCC_CFGR_PLLMUL_SHIFT) +# define RCC_CFGR_PLLMUL_CLKx2 (0 << RCC_CFGR_PLLMUL_SHIFT) /* 0000: PLL input clock x 2 */ +# define RCC_CFGR_PLLMUL_CLKx3 (1 << RCC_CFGR_PLLMUL_SHIFT) /* 0001: PLL input clock x 3 */ +# define RCC_CFGR_PLLMUL_CLKx4 (2 << RCC_CFGR_PLLMUL_SHIFT) /* 0010: PLL input clock x 4 */ +# define RCC_CFGR_PLLMUL_CLKx5 (3 << RCC_CFGR_PLLMUL_SHIFT) /* 0011: PLL input clock x 5 */ +# define RCC_CFGR_PLLMUL_CLKx6 (4 << RCC_CFGR_PLLMUL_SHIFT) /* 0100: PLL input clock x 6 */ +# define RCC_CFGR_PLLMUL_CLKx7 (5 << RCC_CFGR_PLLMUL_SHIFT) /* 0101: PLL input clock x 7 */ +# define RCC_CFGR_PLLMUL_CLKx8 (6 << RCC_CFGR_PLLMUL_SHIFT) /* 0110: PLL input clock x 8 */ +# define RCC_CFGR_PLLMUL_CLKx9 (7 << RCC_CFGR_PLLMUL_SHIFT) /* 0111: PLL input clock x 9 */ +# define RCC_CFGR_PLLMUL_CLKx10 (8 << RCC_CFGR_PLLMUL_SHIFT) /* 1000: PLL input clock x 10 */ +# define RCC_CFGR_PLLMUL_CLKx11 (9 << RCC_CFGR_PLLMUL_SHIFT) /* 1001: PLL input clock x 11 */ +# define RCC_CFGR_PLLMUL_CLKx12 (10 << RCC_CFGR_PLLMUL_SHIFT) /* 1010: PLL input clock x 12 */ +# define RCC_CFGR_PLLMUL_CLKx13 (11 << RCC_CFGR_PLLMUL_SHIFT) /* 1011: PLL input clock x 13 */ +# define RCC_CFGR_PLLMUL_CLKx14 (12 << RCC_CFGR_PLLMUL_SHIFT) /* 1100: PLL input clock x 14 */ +# define RCC_CFGR_PLLMUL_CLKx15 (13 << RCC_CFGR_PLLMUL_SHIFT) /* 1101: PLL input clock x 15 */ +# define RCC_CFGR_PLLMUL_CLKx16 (14 << RCC_CFGR_PLLMUL_SHIFT) /* 111x: PLL input clock x 16 */ +#define RCC_CFGR_USBPRE (1 << 22) /* Bit 22: USB prescaler */ +#define RCC_CFGR_I2SSRC (1 << 23) /* Bit 23: I2S external clock source selection */ +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 26-24: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (3 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_MCO_DISABLED (0 << RCC_CFGR_MCO_SHIFT) /* 000: MCO output disabled, no clock on MCO */ +# define RCC_CFGR_MCO_LSICLK (2 << RCC_CFGR_MCO_SHIFT) /* 010: LSI clock selected */ +# define RCC_CFGR_MCO_LSECLK (3 << RCC_CFGR_MCO_SHIFT) /* 011: LSE clock selected */ +# define RCC_CFGR_MCO_SYSCLK (4 << RCC_CFGR_MCO_SHIFT) /* 100: System clock (SYSCLK) selected */ +# define RCC_CFGR_MCO_HSICLK (5 << RCC_CFGR_MCO_SHIFT) /* 101: HSI clock selected */ +# define RCC_CFGR_MCO_HSECLK (6 << RCC_CFGR_MCO_SHIFT) /* 101: HSE clock selected */ +# define RCC_CFGR_PLLCLKd2 (7 << RCC_CFGR_MCO_SHIFT) /* 111: PLL clock divided by 2 selected */ +#define RCC_CFGR_MCOF (1 << 28) /* Bit 23: Microcontroller Clock Output Flag */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: SYSCFG, Comparators and operational amplifiers reset */ +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 Timer reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 Timer reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: Timer 4 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: Timer 6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: Timer 7 reset */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window Watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: UART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: UART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_USBRST (1 << 23) /* Bit 23: USB reset */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC interface reset */ + +/* AHB Peripheral Clock enable register */ + +#define RCC_AHBENR_DMA1EN (1 << 0) /* Bit 0: DMA1 clock enable */ +#define RCC_AHBENR_DMA2EN (1 << 1) /* Bit 1: DMA2 clock enable */ +#define RCC_AHBENR_SRAMEN (1 << 2) /* Bit 2: SRAM interface clock enable */ +#define RCC_AHBENR_FLITFEN (1 << 4) /* Bit 4: FLITF clock enable */ +#define RCC_AHBENR_CRCEN (1 << 6) /* Bit 6: CRC clock enable */ +#define RCC_AHBENR_IOPAEN (1 << 17) /* Bit 17: I/O port A clock enable */ +#define RCC_AHBENR_IOPBEN (1 << 18) /* Bit 17: I/O port B clock enable */ +#define RCC_AHBENR_IOPCEN (1 << 19) /* Bit 17: I/O port C clock enable */ +#define RCC_AHBENR_IOPDEN (1 << 20) /* Bit 17: I/O port D clock enable */ +#define RCC_AHBENR_IOPEEN (1 << 21) /* Bit 17: I/O port E clock enable */ +#define RCC_AHBENR_IOPFEN (1 << 22) /* Bit 17: I/O port F clock enable */ +#define RCC_AHBENR_TSCEN (1 << 24) /* Bit 24: TSCEN: Touch sensing controller clock enable */ +#define RCC_AHBENR_ADC12EN (1 << 28) /* Bit 28: ADC1 and ADC2 enable */ +#define RCC_AHBENR_ADC34EN (1 << 29) /* Bit 28: ADC3 and ADC4 enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: SYSCFG clock enable */ +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 Timer clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI 1 clock enable */ +#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 Timer clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 clock enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 clock enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 clock enable */ + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: Timer 4 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: Timer 6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: Timer 7 clock enable */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window Watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI 3 clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART 4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART 5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C 2 clock enable */ +#define RCC_APB1ENR_USBEN (1 << 23) /* Bit 23: USB clock enable */ +#define RCC_APB1ENR_CAN1EN (1 << 25) /* Bit 25: CAN1 clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 4:3: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' lower driving capability */ +# define RCC_BDCR_LSEDRV_MEDLOW (1 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' medium low driving capability */ +# define RCC_BDCR_LSEDRV_MEDHIGH (2 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' medium high driving capability */ +# define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' higher driving capability */ +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* AHB peripheral clock reset register (RCC_AHBRSTR) */ + +#define RCC_AHBRSTR_IOPARST (1 << 17) /* Bit 17: I/O port A reset */ +#define RCC_AHBRSTR_IOPBRST (1 << 18) /* Bit 18: I/O port B reset */ +#define RCC_AHBRSTR_IOPCRST (1 << 29) /* Bit 19: I/O port C reset */ +#define RCC_AHBRSTR_IOPDRST (1 << 20) /* Bit 20: I/O port D reset */ +#define RCC_AHBRSTR_IOPERST (1 << 21) /* Bit 21: I/O port E reset */ +#define RCC_AHBRSTR_IOPFRST (1 << 22) /* Bit 22: I/O port F reset */ +#define RCC_AHBRSTR_TSCRST (1 << 24) /* Bit 24: Touch sensing controller reset */ +#define RCC_AHBRSTR_ADC12RST (1 << 28) /* Bit 28: ADC1 and ADC2 reset */ +#define RCC_AHBRSTR_ADC34RST (1 << 29) /* Bit 29: ADC3 and ADC4 reset */ + +/* Clock configuration register 2 */ + +#define RCC_CFGR2_PREDIV_SHIFT (0) /* Bits 0-3: PREDIV division factor */ +#define RCC_CFGR2_PREDIV_MASK (15 << RCC_CFGR2_PREDIV_SHIFT) +# define RCC_CFGR2_PREDIVd1 (0 << RCC_CFGR2_PREDIV_SHIFT) /* 0000: HSE input to PLL not divided */ +# define RCC_CFGR2_PREDIVd2 (1 << RCC_CFGR2_PREDIV_SHIFT) /* 0001: HSE input to PLL divided by 2 */ +# define RCC_CFGR2_PREDIVd3 (2 << RCC_CFGR2_PREDIV_SHIFT) /* 0010: HSE input to PLL divided by 3 */ +# define RCC_CFGR2_PREDIVd4 (3 << RCC_CFGR2_PREDIV_SHIFT) /* 0011: HSE input to PLL divided by 4 */ +# define RCC_CFGR2_PREDIVd5 (4 << RCC_CFGR2_PREDIV_SHIFT) /* 0100: HSE input to PLL divided by 5 */ +# define RCC_CFGR2_PREDIVd6 (5 << RCC_CFGR2_PREDIV_SHIFT) /* 0101: HSE input to PLL divided by 6 */ +# define RCC_CFGR2_PREDIVd7 (6 << RCC_CFGR2_PREDIV_SHIFT) /* 0110: HSE input to PLL divided by 7 */ +# define RCC_CFGR2_PREDIVd8 (7 << RCC_CFGR2_PREDIV_SHIFT) /* 0111: HSE input to PLL divided by 8 */ +# define RCC_CFGR2_PREDIVd9 (8 << RCC_CFGR2_PREDIV_SHIFT) /* 1000: HSE input to PLL divided by 9 */ +# define RCC_CFGR2_PREDIVd10 (9 << RCC_CFGR2_PREDIV_SHIFT) /* 1001: HSE input to PLL divided by 10 */ +# define RCC_CFGR2_PREDIVd11 (10 << RCC_CFGR2_PREDIV_SHIFT) /* 1010: HSE input to PLL divided by 11 */ +# define RCC_CFGR2_PREDIVd12 (11 << RCC_CFGR2_PREDIV_SHIFT) /* 1011: HSE input to PLL divided by 12 */ +# define RCC_CFGR2_PREDIVd13 (12 << RCC_CFGR2_PREDIV_SHIFT) /* 1100: HSE input to PLL divided by 13 */ +# define RCC_CFGR2_PREDIVd14 (13 << RCC_CFGR2_PREDIV_SHIFT) /* 1101: HSE input to PLL divided by 14 */ +# define RCC_CFGR2_PREDIVd15 (14 << RCC_CFGR2_PREDIV_SHIFT) /* 1110: HSE input to PLL divided by 15 */ +# define RCC_CFGR2_PREDIVd16 (15 << RCC_CFGR2_PREDIV_SHIFT) /* 1111: HSE input to PLL divided by 16 */ +#define RCC_CFGR2_ADC12PRES_SHIFT (4) /* Bits 4-8: ADC12 prescaler */ +#define RCC_CFGR2_ADC12PRES_MASK (31 << RCC_CFGR2_ADC12PRES_SHIFT) +# define RCC_CFGR2_ADC12DISABLED (0 << RCC_CFGR2_ADC12PRES_SHIFT) /* 0xxxx: ADC12 clock disabled */ +# define RCC_CFGR2_ADC12PRESd1 (16 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10000: PLL clock divided by 1 */ +# define RCC_CFGR2_ADC12PRESd2 (17 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10001: PLL clock divided by 2 */ +# define RCC_CFGR2_ADC12PRESd4 (18 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10010: PLL clock divided by 4 */ +# define RCC_CFGR2_ADC12PRESd6 (16 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10011: PLL clock divided by 6 */ +# define RCC_CFGR2_ADC12PRESd8 (20 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10100: PLL clock divided by 8 */ +# define RCC_CFGR2_ADC12PRESd10 (21 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10101: PLL clock divided by 10 */ +# define RCC_CFGR2_ADC12PRESd12 (22 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10110: PLL clock divided by 12 */ +# define RCC_CFGR2_ADC12PRESd16 (23 << RCC_CFGR2_ADC12PRES_SHIFT) /* 10111: PLL clock divided by 16 */ +# define RCC_CFGR2_ADC12PRESd32 (24 << RCC_CFGR2_ADC12PRES_SHIFT) /* 11000: PLL clock divided by 32 */ +# define RCC_CFGR2_ADC12PRESd64 (25 << RCC_CFGR2_ADC12PRES_SHIFT) /* 11001: PLL clock divided by 64 */ +# define RCC_CFGR2_ADC12PRESd128 (26 << RCC_CFGR2_ADC12PRES_SHIFT) /* 11010: PLL clock divided by 128 */ +# define RCC_CFGR2_ADC12PRESd256 (27 << RCC_CFGR2_ADC12PRES_SHIFT) /* 11011: PLL clock divided by 256 */ +#define RCC_CFGR2_ADC34PRES_SHIFT (9) /* Bits 9-13: ADC34 prescaler */ +#define RCC_CFGR2_ADC34PRES_MASK (31 << RCC_CFGR2_ADC34PRES_SHIFT) +# define RCC_CFGR2_ADC34DISABLED (0 << RCC_CFGR2_ADC34PRES_SHIFT) /* 0xxxx: ADC34 clock disabled */ +# define RCC_CFGR2_ADC34PRESd1 (16 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10000: PLL clock divided by 1 */ +# define RCC_CFGR2_ADC34PRESd2 (17 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10001: PLL clock divided by 2 */ +# define RCC_CFGR2_ADC34PRESd4 (18 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10010: PLL clock divided by 4 */ +# define RCC_CFGR2_ADC34PRESd6 (16 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10011: PLL clock divided by 6 */ +# define RCC_CFGR2_ADC34PRESd8 (20 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10100: PLL clock divided by 8 */ +# define RCC_CFGR2_ADC34PRESd10 (21 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10101: PLL clock divided by 10 */ +# define RCC_CFGR2_ADC34PRESd12 (22 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10110: PLL clock divided by 12 */ +# define RCC_CFGR2_ADC34PRESd16 (23 << RCC_CFGR2_ADC34PRES_SHIFT) /* 10111: PLL clock divided by 16 */ +# define RCC_CFGR2_ADC34PRESd32 (24 << RCC_CFGR2_ADC34PRES_SHIFT) /* 11000: PLL clock divided by 32 */ +# define RCC_CFGR2_ADC34PRESd64 (25 << RCC_CFGR2_ADC34PRES_SHIFT) /* 11001: PLL clock divided by 64 */ +# define RCC_CFGR2_ADC34PRESd128 (26 << RCC_CFGR2_ADC34PRES_SHIFT) /* 11010: PLL clock divided by 128 */ +# define RCC_CFGR2_ADC34PRESd256 (27 << RCC_CFGR2_ADC34PRES_SHIFT) /* 11011: PLL clock divided by 256 */ + +/* Clock configuration register 2 */ + +#define RCC_CFGR3_USART1SW_SHIFT (9) /* Bits 0-1: USART1 clock source selection */ +#define RCC_CFGR3_USART1SW_MASK (3 << RCC_CFGR3_USART1SW_SHIFT) +# define RCC_CFGR3_USART1SW_PCLK (0 << RCC_CFGR3_USART1SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART1SW_SYSCLK (1 << RCC_CFGR3_USART1SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART1SW_HSI (0 << RCC_CFGR3_USART1SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_I2C1SW (1 << 4) /* Bit 4: I2C1 clock source selection */ +#define RCC_CFGR3_I2C2SW (1 << 5) /* Bit 5: I2C2 clock source selection */ +#define RCC_CFGR3_TIM1SW (1 << 8) /* Bit 8: Timer1 clock source selection */ +#define RCC_CFGR3_TIM8SW (1 << 9) /* Bit 9: Timer8 clock source selection */ +#define RCC_CFGR3_USART2SW_SHIFT (16) /* Bits 16-17: USART2 clock source selection */ +#define RCC_CFGR3_USART2SW_MASK (3 << RCC_CFGR3_USART2SW_SHIFT) +# define RCC_CFGR3_USART2SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART2SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART2SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART2SW_HSI (0 << RCC_CFGR3_USART2SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_USART3SW_SHIFT (18) /* Bits 18-19: USART3 clock source selection */ +#define RCC_CFGR3_USART3SW_MASK (3 << RCC_CFGR3_USART3SW_SHIFT) +# define RCC_CFGR3_USART3SW_PCLK (0 << RCC_CFGR3_USART3SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART3SW_SYSCLK (1 << RCC_CFGR3_USART3SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART3SW_LSE (2 << RCC_CFGR3_USART3SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART3SW_HSI (0 << RCC_CFGR3_USART3SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_UART4SW_SHIFT (20) /* Bits 20-21: UART4 clock source selection */ +#define RCC_CFGR3_UART4SW_MASK (3 << RCC_CFGR3_UART4SW_SHIFT) +# define RCC_CFGR3_UART4SW_PCLK (0 << RCC_CFGR3_UART4SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_UART4SW_SYSCLK (1 << RCC_CFGR3_UART4SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_UART4SW_LSE (2 << RCC_CFGR3_UART4SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_UART4SW_HSI (0 << RCC_CFGR3_UART4SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_UART5SW_SHIFT (22) /* Bits 22-23: UART5 clock source selection */ +#define RCC_CFGR3_UART5SW_MASK (3 << RCC_CFGR3_UART5SW_SHIFT) +# define RCC_CFGR3_UART5SW_PCLK (0 << RCC_CFGR3_UART5SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_UART5SW_SYSCLK (1 << RCC_CFGR3_UART5SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_UART5SW_LSE (2 << RCC_CFGR3_UART5SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_UART5SW_HSI (0 << RCC_CFGR3_UART5SW_SHIFT) /* HSI clock */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_RCC_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..1f19e74dcc8444fd04a6ab64577cb1f15869d100 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h @@ -0,0 +1,177 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#ifdef CONFIG_STM32_STM32F30XX + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_CFGR1_OFFSET 0x0000 /* SYSCFG configuration register 1 */ +#define STM32_SYSCFG_RCR_OFFSET 0x0004 /* SYSCFG CCM SRAM protection register */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +#define STM32_SYSCFG_CFGR2_OFFSET 0x0018 /* SYSCFG configuration register 2 */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_CFGR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR1_OFFSET) +#define STM32_SYSCFG_RCR (STM32_SYSCFG_BASE+STM32_SYSCFG_RCR_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +#define STM32_SYSCFG_CFGR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR2_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_CFGR1_MEMMODE_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_CFGR1_MEMMODE_MASK (3 << SYSCFG_CFGR1_MEMMODE_SHIFT) +# define SYSCFG_CFGR1_MEMMODE_FLASH (0 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 00: Main Flash at 0x00000000 */ +# define SYSCFG_CFGR1_MEMMODE_SYSTEM (1 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 01: System Flash at 0x00000000 */ +# define SYSCFG_CFGR1_MEMMODE_SRAM (3 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 11: Embedded SRAM at 0x00000000 */ +#define SYSCFG_CFGR1_USB_ITRMP (1 << 5) /* Bit 5: USB interrupt remap */ +#define SYSCFG_CFGR1_TIM1_ITR3RMP (1 << 6) /* Bit 6: Timer 1 ITR3 selection */ +#define SYSCFG_CFGR1_DAC_TRIGRMP (1 << 7) /* Bit 7: DAC trigger remap (when TSEL = 001) */ +#define SYSCFG_CFGR1_ADC24_DMARMP (1 << 8) /* Bit 8: ADC24 DMA remapping bit */ +#define SYSCFG_CFGR1_TIM16_DMARMP (1 << 11) /* Bit 11: TIM16 DMA request remapping bit */ +#define SYSCFG_CFGR1_TIM17_DMARMP (1 << 12) /* Bit 12: TIM17 DMA request remapping bit */ +#define SYSCFG_CFGR1_TIM6_DMARMP (1 << 13) /* Bit 13: TIM6 DMA remap, or */ +#define SYSCFG_CFGR1_DAC1_DMARMP (1 << 13) /* Bit 13: DAC channel DMA remap */ +#define SYSCFG_CFGR1_TIM7_DMARMP (1 << 14) /* Bit 14: TIM7 DMA remap */ +#define SYSCFG_CFGR1_DAC2_DMARMP (1 << 14) /* Bit 14: DAC channel2 DMA remap */ +#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (0) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ +#define SYSCFG_CFGR1_I2C_PBXFMP_MASK (15 << SYSCFG_CFGR1_I2C_PBXFMP_SHIFT) +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 fast mode Plus driving capability */ +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 fast mode Plus driving capability */ +#define SYSCFG_CFGR1_ENCMODE_SHIFT (22) /* Bits 22-23: Encoder mode */ +#define SYSCFG_CFGR1_ENCMODE_MASK (3 << SYSCFG_CFGR1_ENCMODE_SHIFT) +# define SYSCFG_CFGR1_ENCMODE_NONE (0 << SYSCFG_CFGR1_ENCMODE_SHIFT) /* No redirection */ +# define SYSCFG_CFGR1_ENCMODE_TIM2 (1 << SYSCFG_CFGR1_ENCMODE_SHIFT) /* TIM2 I2C1-2 -> TIM15 IC1/2 */ +# define SYSCFG_CFGR1_ENCMODE_TIM3 (2 << SYSCFG_CFGR1_ENCMODE_SHIFT) /* TIM3 I2C1-2 -> TIM15 IC1/2 */ +# define SYSCFG_CFGR1_ENCMODE_TIM4 (3 << SYSCFG_CFGR1_ENCMODE_SHIFT) /* TIM4 I2C1-2 -> TIM15 IC1/2 */ +#define SYSCFG_CFGR1_FPUIE_SHIFT (26) /* Bits 26-31: Floating Point Unit interrupts enable bits */ +#define SYSCFG_CFGR1_FPUIE_MASK (63 << SYSCFG_CFGR1_FPUIE_SHIFT) +# define SYSCFG_CFGR1_FPUIE_INVALIDOP (1 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Invalid operation interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_DIVZERO (2 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Divide-by-zero interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_UNDERFLOW (4 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Underflow interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_OVERFLOW (8 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Overflow interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_DENORMAL (16 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Input denormal interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_INEXACT (32 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Inexact interrupt enable */ + +/* SYSCFG CCM SRAM protection register */ + +#define SYSCFG_RCR(page) (1 << (page)) /* Bit n: Write protection page n */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* SYSCFG configuration register 2 */ + +#define SYSCFG_CFGR2_LOCKUPLOCK (1 << 0) /* Bit 0: Cortex-M4 Hardfault output bit enable */ +#define SYSCFG_CFGR2_SRAM_PARITYLOCK (1 << 1) /* Bit 1: RAM parity lock */ +#define SYSCFG_CFGR2_PVDLOCK (1 << 2) /* Bit 2: PVD lock enable */ +#define SYSCFG_CFGR2_BYPADDPAR (1 << 4) /* Bit 4: Bypass address bit 29 in parity calculation */ +#define SYSCFG_CFGR2_SRAM_PEF (1 << 8) /* Bit 8: SRAM parity error */ + +#endif /* CONFIG_STM32_STM32F30XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F30XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_uart.h b/arch/arm/src/stm32/chip/stm32f30xxx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..9a55a921a720bc3b6d41ee86c9c7b98663be2355 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_uart.h @@ -0,0 +1,350 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_uart.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32F30XXX_UART_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32F30XXX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_CR1_OFFSET 0x0000 /* Control register 1 */ +#define STM32_USART_CR2_OFFSET 0x0004 /* Control register 2 */ +#define STM32_USART_CR3_OFFSET 0x0008 /* Control register 3 */ +#define STM32_USART_BRR_OFFSET 0x000c /* Baud Rate Register (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ +#define STM32_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ +#define STM32_USART_RQR_OFFSET 0x0018 /* Request register */ +#define STM32_USART_ISR_OFFSET 0x001c /* Interrupt & status register */ +#define STM32_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ +#define STM32_USART_RDR_OFFSET 0x0024 /* Receive data register */ +#define STM32_USART_TDR_OFFSET 0x0028 /* Transmit data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NUSART > 0 +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART1_RTOR (STM32_USART1_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART1_RQR (STM32_USART1_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART1_ISR (STM32_USART1_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART1_ICR (STM32_USART1_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART1_RDR (STM32_USART1_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART1_TDR (STM32_USART1_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART2_RTOR (STM32_USART2_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART2_RQR (STM32_USART2_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART2_ISR (STM32_USART2_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART2_ICR (STM32_USART2_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART2_RDR (STM32_USART2_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART2_TDR (STM32_USART2_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART3_RTOR (STM32_USART3_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART3_RQR (STM32_USART3_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART3_ISR (STM32_USART3_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART3_ICR (STM32_USART3_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART3_RDR (STM32_USART3_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART3_TDR (STM32_USART3_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_GTPR (STM32_UART4_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART4_RTOR (STM32_UART4_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART4_RQR (STM32_UART4_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART4_GTPR (STM32_UART4_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART4_ISR (STM32_UART4_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART4_ICR (STM32_UART4_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART4_RDR (STM32_UART4_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART4_TDR (STM32_UART4_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_GTPR (STM32_UART5_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART5_RTOR (STM32_UART5_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART5_RQR (STM32_UART5_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART5_GTPR (STM32_UART5_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART5_ISR (STM32_UART5_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART5_ICR (STM32_UART5_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART5_RDR (STM32_UART5_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART5_TDR (STM32_UART5_BASE+STM32_USART_TDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define USART_CR1_UE (1 << 0) /* Bit 0: USART enable */ +#define USART_CR1_UESM (1 << 1) /* Bit 1: USART enable in Stop mode */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ + +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Receiver wakeup method */ +#define USART_CR1_M (1 << 12) /* Bit 12: Word length */ +#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ +#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ +#define USART_CR1_DEDT_SHIFT (16) /* Bits 16-20: Driver Enable deassertion time */ +#define USART_CR1_DEDT_MASK (31 << USART_CR1_DEDT_SHIFT) +#define USART_CR1_DEAT_SHIFT (21) /* Bits 21-25: Driver Enable assertion time */ +#define USART_CR1_DEAT_MASK (31 << USART_CR1_DEAT_SHIFT) +#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of Block interrupt enable */ + +#define USART_CR1_ALLINTS \ + (USART_CR1_IDLEIE | USART_CR1_RXNEIE | USART_CR1_TCIE | USART_CR1_TXEIE |\ + USART_CR1_PEIE | USART_CR1_CMIE |USART_CR1_RTOIE | USART_CR1_EOBIE) + +/* Control register 2 */ + +#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: :7-/4-bit Address Detection */ +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ +#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ +#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ +#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ +#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto baud rate enable */ +#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Auto baud rate mode */ +#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) +# define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* Start bit */ +# define USART_CR2_ABRMOD_FALL (1 << USART_CR2_ABRMOD_SHIFT) /* Falling edge measurement */ +# define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 0x7F frame detection */ +# define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 0x55 frame detection */ +#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ +#define USART_CR2_ADD4L_SHIFT (24) /* Bits 24-17: Address[3:0]:of the USART node */ +#define USART_CR2_ADD4L_MASK (15 << USART_CR2_ADD4_SHIFT) +#define USART_CR2_ADD4H_SHIFT (28) /* Bits 28-31: Address[4:0] of the USART node */ +#define USART_CR2_ADD4H_MASK (15 << USART_CR2_ADD4_SHIFT) +#define USART_CR2_ADD8_SHIFT (24) /* Bits 24-31: Address[7:0] of the USART node */ +#define USART_CR2_ADD8_MASK (255 << USART_CR2_ADD8_SHIFT) + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */ +#define USART_CR1_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ +#define USART_CR1_DDRE (1 << 13) /* Bit 13: DMA Disable on Reception Error */ +#define USART_CR1_DEM (1 << 14) /* Bit 14: Driver enable mode */ +#define USART_CR1_DEP (1 << 15) /* Bit 15: Driver enable polarity selection */ +#define USART_CR1_SCARCNT_SHIFT (17) /* Bit 17-19: Smartcard auto-retry count */ +#define USART_CR1_SCARCNT_MASK (7 << USART_CR1_SCARCNT_SHIFT) +#define USART_CR1_WUS_SHIFT (20) /* Bit 20-21: Wakeup from Stop mode interrupt */ +#define USART_CR1_WUS_MASK (3 << USART_CR1_WUS_SHIFT) +# define USART_CR1_WUS_ADDRMAT (0 << USART_CR1_WUS_SHIFT) /* Active on address match */ +# define USART_CR1_WUS_STARTBIT (2 << USART_CR1_WUS_SHIFT) /* Active on Start bit */ +# define USART_CR1_WUS_RXNE (3 << USART_CR1_WUS_SHIFT) /* Active on RXNE */ +#define USART_CR1_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ + +/* Baud Rate Register */ + +#define USART_BRR_SHIFT (0) /* Bits 0-15: USARTDIV[15:0] OVER8=0*/ +#define USART_BRR_MASK (0xffff << USART_BRR_SHIFT) +#define USART_BRR_0_3_SHIFT (0) /* Bits 0-2: USARTDIV[3:0] OVER8=1 */ +#define USART_BRR_0_3_MASK (0x0fff << USART_BRR_0_3_SHIFT) +#define USART_BRR_4_7_SHIFT (0) /* Bits 4-15: USARTDIV[15:4] OVER8=1*/ +#define USART_BRR_4_7_MASK (0xffff << USART_BRR_4_7_SHIFT) + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Receiver timeout register */ + +#define USART_RTOR_RTO_SHIFT (0) /* Bits 0-23: Receiver timeout value */ +#define USART_RTOR_RTO_MASK (0xffffff << USART_RTOR_RTO_SHIFT) +#define USART_RTOR_BLEN_SHIFT (24) /* Bits 24-31: Block Length */ +#define USART_RTOR_BLEN_MASK (0xff << USART_RTOR_BLEN_SHIFT) + +/* Request register */ + +#define USART_RQR_ABRRQ (1 << 0) /* Bit 0: Auto baud rate request */ +#define USART_RQR_SBKRQ (1 << 1) /* Bit 1: Send break request */ +#define USART_RQR_MMRQ (1 << 2) /* Bit 2: Mute mode request */ +#define USART_RQR_RXFRQ (1 << 3) /* Bit 3: Receive data flush request */ +#define USART_RQR_TXFRQ (1 << 4) /* Bit 4: Transmit data flush request */ + +/* Interrupt & status register */ + +#define USART_ISR_PE (1 << 0) /* Bit 0: Parity error */ +#define USART_ISR_FE (1 << 1) /* Bit 1: Framing error */ +#define USART_ISR_NF (1 << 2) /* Bit 2: Noise detected flag */ +#define USART_ISR_ORE (1 << 3) /* Bit 3: Overrun error */ +#define USART_ISR_IDLE (1 << 4) /* Bit 4: Idle line detected */ +#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read data register not empty */ +#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission complete */ +#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit data register empty */ +#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN break detection flag */ +#define USART_ISR_CTSIF (1 << 9) /* Bit 9: CTS interrupt flag */ +#define USART_ISR_CTS (1 << 10) /* Bit 10: CTS flag */ +#define USART_ISR_RTOF (1 << 11) /* Bit 11: Receiver timeout */ +#define USART_ISR_EOBF (1 << 12) /* Bit 12: End of block flag */ +#define USART_ISR_ABRE (1 << 14) /* Bit 14: Auto baud rate error */ +#define USART_ISR_ABRF (1 << 15) /* Bit 15: Auto baud rate flag */ +#define USART_ISR_BUSY (1 << 16) /* Bit 16: Busy flag */ +#define USART_ISR_CMF (1 << 17) /* Bit 17: Character match flag */ +#define USART_ISR_SBKF (1 << 18) /* Bit 18: Send break flag */ +#define USART_ISR_ISRRWU (1 << 19) /* Bit 19: Receiver wakeup from Mute mode */ +#define USART_ISR_WUF (1 << 20) /* Bit 20: Wakeup from Stop mode flag */ +#define USART_ISR_TEACK (1 << 21) /* Bit 21: Transmit enable acknowledge flag */ +#define USART_ISR_REACK (1 << 22) /* Bit 22: Receive enable acknowledge flag */ + +#define USART_ISR_ALLBITS (0x007fdfff) + +/* Interrupt flag clear register */ + +#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ +#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ +#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected flag *clear flag */ +#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ +#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ +#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete */ +#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ +#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS interrupt clear flag */ +#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ +#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ +#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ + +#define USART_ICR_ALLBITS (0x00121b5f) + +/* Receive data register */ + +#define USART_RDR_SHIFT (0) /* Bits 8:0: Receive data value */ +#define USART_RDR_MASK (0x1ff << USART_RDR_SHIFT) + +/* Transmit data register */ + +#define USART_TDR_SHIFT (0) /* Bits 8:0: Transmit data value */ +#define USART_TDR_MASK (0x1ff << USART_TDR_SHIFT) + +/* Compatibility definitions ********************************************************/ +/* F1/F2/F4 Status register */ + +#define STM32_USART_SR_OFFSET STM32_USART_ISR_OFFSET + +#define USART_SR_PE USART_ISR_PE /* Parity Error */ +#define USART_SR_FE USART_ISR_FE /* Framing error */ +#define USART_SR_NE USART_ISR_NF /* Noise detected flag */ +#define USART_SR_ORE USART_ISR_ORE /* Overrun error */ +#define USART_SR_IDLE USART_ISR_IDLE /* IDLE line detected */ +#define USART_SR_RXNE USART_ISR_RXNE /* Read Data Register Not Empty */ +#define USART_SR_TC USART_ISR_TC /* Transmission Complete */ +#define USART_SR_TXE USART_ISR_TXE /* Transmit Data Register Empty */ +#define USART_SR_LBD USART_ISR_LBDF /* LIN Break Detection Flag */ +#define USART_SR_CTS USART_ISR_CTS /* Bit 9: CTS Flag */ + +#define USART_SR_ALLBITS USART_ISR_ALLBITS + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32F30XXX_UART_H */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_vectors.h b/arch/arm/src/stm32/chip/stm32f30xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..e28ecb591f5938c186a697686f6d40a7e8e80f88 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f30xxx_vectors.h @@ -0,0 +1,149 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f30xxx_vectors.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies each STM32F30xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f30xxx_irq.h. + * stm32_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 82 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 82 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* 0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* 1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* 2: Tamper or Time stamp interrupt */ +VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* 3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* 4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* 5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* 6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* 7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* 8: EXTI Line 2 or TSC interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* 9: EXTI Line 3 interrupt */ + +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* 10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* 11: DMA1 channel 1 global interrupt */ +VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* 12: DMA1 channel 2 global interrupt */ +VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* 13: DMA1 channel 3 global interrupt */ +VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* 14: DMA1 channel 4 global interrupt */ +VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* 15: DMA1 channel 5 global interrupt */ +VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* 16: DMA1 channel 6 global interrupt */ +VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* 17: DMA1 channel 7 global interrupt */ +VECTOR(stm32_adc12, STM32_IRQ_ADC12) /* 18: ADC1/ADC2 global interrupt */ +VECTOR(stm32_can1tx, STM32_IRQ_CAN1TX) /* 19: USB High Priority or CAN1 TX interrupts */ + +VECTOR(stm32_can1rx0, STM32_IRQ_CAN1RX0) /* 20: USB Low Priority or CAN1 RX0 interrupts*/ +VECTOR(stm32_can1rx1, STM32_IRQ_CAN1RX1) /* 21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* 22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* 23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* 24: TIM1 Break or TIM15 global interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* 25: TIM1 Update or TIM16 global interrupt */ +VECTOR(stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM) /* 26: TIM1 Trigger or TIM17 global interrupt */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* 27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* 28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* 29: TIM3 global interrupt */ + +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* 30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* 31: I2C1 event or EXTI Line23 interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* 32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* 33: I2C2 event or EXTI Line24 interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* 34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* 35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* 36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* 37: USART1 global or EXTI Line 25 interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* 38: USART2 global or EXTI Line 26 interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* 39: USART3 global or EXTI Line 28 interrupt */ + +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* 40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* 41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_ext18, STM32_IRQ_EXT18) /* 42: USB wakeup or EXTI Line 18 interrupt */ +VECTOR(stm32_tim8brk, STM32_IRQ_TIM8BRK) /* 43: TIM8 Break interrupt */ +VECTOR(stm32_tim8up, STM32_IRQ_TIM8UP) /* 44: TIM8 Update interrupt */ +VECTOR(stm32_tim8trgcom, STM32_IRQ_TIM8TRGCOM) /* 45: TIM8 Trigger and Commutation interrupts */ +VECTOR(stm32_tim8cc, STM32_IRQ_TIM8CC) /* 46: TIM8 Capture Compare interrupt */ +VECTOR(stm32_adc3, STM32_IRQ_ADC3) /* 47: ADC3 global interrupt */ +UNUSED(STM32_IRQ_RESERVED48) /* 48: Reserved */ +UNUSED(STM32_IRQ_RESERVED49) /* 49: Reserved */ + +UNUSED(STM32_IRQ_RESERVED50) /* 50: Reserved */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* 51: SPI3 global interrupt */ +VECTOR(stm32_uart4, STM32_IRQ_UART4) /* 52: UART4 global or EXTI Line 34 interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* 53: UART5 global or EXTI Line 35 interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* 54: TIM6 global or DAC1/2 underrun interrupts */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* 55: TIM7 global interrupt */ +VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* 56: DMA2 channel 1 global interrupt */ +VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* 57: DMA2 channel 2 global interrupt */ +VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* 58: DMA2 channel 3 global interrupt */ +VECTOR(stm32_dma2ch4, STM32_IRQ_DMA2CH4) /* 59: DMA2 channel 4 global interrupt */ + +VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* 60: DMA2 channel 5 global interrupt */ +VECTOR(stm32_adc4, STM32_IRQ_ADC4) /* 61: ADC4 global interrupt */ +UNUSED(STM32_IRQ_RESERVED62) /* 62: Reserved */ +UNUSED(STM32_IRQ_RESERVED63) /* 63: Reserved */ +VECTOR(stm32_comp123, STM32_IRQ_COMP123) /* 64: COMP1-3 or EXTI Lines 21-2 and 29 interrupts */ +VECTOR(stm32_comp456, STM32_IRQ_COMP456) /* 65: COMP4-6 or EXTI Lines 30-2 interrupts */ +VECTOR(stm32_comp7, STM32_IRQ_COMP7) /* 66: COMP7 or EXTI Line 33 interrupt */ +UNUSED(STM32_IRQ_RESERVED67) /* 67: Reserved */ +UNUSED(STM32_IRQ_RESERVED68) /* 68: Reserved */ +UNUSED(STM32_IRQ_RESERVED69) /* 69: Reserved */ + +UNUSED(STM32_IRQ_RESERVED70) /* 70: Reserved */ +UNUSED(STM32_IRQ_RESERVED71) /* 71: Reserved */ +UNUSED(STM32_IRQ_RESERVED72) /* 72: Reserved */ +UNUSED(STM32_IRQ_RESERVED73) /* 73: Reserved */ +VECTOR(stm32_usbhp, STM32_IRQ_USBHP_2) /* 74: USB High priority interrupt */ +VECTOR(stm32_usblp, STM32_IRQ_USBLP_2) /* 75: USB Low priority interrupt */ +VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP_2) /* 76: USB wakeup from suspend through EXTI line interrupt*/ +UNUSED(STM32_IRQ_RESERVED77) /* 77: Reserved */ +UNUSED(STM32_IRQ_RESERVED78) /* 78: Reserved */ +UNUSED(STM32_IRQ_RESERVED79) /* 79: Reserved */ + +UNUSED(STM32_IRQ_RESERVED80) /* 80: Reserved */ +VECTOR(stm32_fpu, STM32_IRQ_FPU) /* 81: FPU global interrupt */ + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..a9116019bfe3dbf298a9a9218468b7dccdc331c3 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h @@ -0,0 +1,157 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ + /* 0x60000000-0xdfffffff: Reserved */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x1ffeffff: Reserved */ +#define STM32_SYSMEM_BASE 0x1fffd800 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32_OPTION_BASE 0x1ffff800 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32_SYSMEM_UID 0x1ffff7ac /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x1ffff7cc /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x040 corresponds + * to 64 Kbytes + */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x40009fff: APB1 */ + /* 0x4000a000-0x4000ffff: Reserved */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x40006bff: APB2 */ + /* 0x40016c00-0x4001ffff: Reserved */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x400243ff: APB1 */ + /* 0x40024400-0x4007ffff: Reserved */ +#define STM32_AHB2_BASE 0x48000000 /* 0x48000000-0x480017ff: AHB2 */ + /* 0x48001800-0x4fffFfff: Reserved */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff TIM2 */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff TIM3 */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff TIM4 */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff TIM6 */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff TIM7 */ +#define STM32_TIM12_BASE 0x40001800 /* 0x40001800-0x40001bff TIM12 */ +#define STM32_TIM13_BASE 0x40001c00 /* 0x40001c00-0x40001fff TIM13 */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000-0x400023ff TIM14 */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff RTC */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff WWDG */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff IWDG */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff SPI2, or */ +#define STM32_I2S2_BASE 0x40003800 /* 0x40003800-0x40003bff I2S2 */ +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff SPI3, or */ +#define STM32_I2S3_BASE 0x40003c00 /* 0x40003c00-0x40003fff I2S3 */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff USART3 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00-0x40005fff USB device FS */ +#define STM32_USBRAM_BASE 0x40006000 /* 0x40006000-0x400063ff USB SRAM 512B */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff bxCAN */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */ +#define STM32_DAC1_BASE 0x40007400 /* 0x40007400-0x400077ff DAC1 */ +#define STM32_CEC_BASE 0x40007800 /* 0x40007800-0x40007bff CEC */ +#define STM32_DAC2_BASE 0x40009800 /* 0x40009800-0x40009bff DAC2 */ +#define STM32_TIM18_BASE 0x40009c00 /* 0x40009c00-0x40009fff TIM18 */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103FF SYSCFG + COMP + OPAMP */ +#define STM32_EXTI_BASE 0x40010400 /* 0x40010400-0x400107FF EXTI */ +#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC1 */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */ +#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */ +#define STM32_TIM15_BASE 0x40014000 /* 0x40014000-0x400143ff TIM15 */ +#define STM32_TIM16_BASE 0x40014400 /* 0x40014400-0x400147ff TIM16 */ +#define STM32_TIM17_BASE 0x40014800 /* 0x40014800-0x40014bff TIM17 */ +#define STM32_TIM19_BASE 0x40015c00 /* 0x40015c00-0x40015fff TIM19 */ +#define STM32_SDADC1_BASE 0x40016000 /* 0x40016000-0x400163ff SDADC1 */ +#define STM32_SDADC2_BASE 0x40016400 /* 0x40016000-0x400167ff SDADC2 */ +#define STM32_SDADC3_BASE 0x40016800 /* 0x40016000-0x40016bff SDADC3 */ + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32_DMA1_BASE 0x40020000 /* 0x40020000-0x400203ff: DMA1 */ +#define STM32_DMA2_BASE 0x40020400 /* 0x40020400-0x400207ff: DMA2 */ +#define STM32_RCC_BASE 0x40021000 /* 0x40021000-0x400213ff: Reset and Clock control RCC */ +#define STM32_FLASHIF_BASE 0x40022000 /* 0x40022000-0x400223ff: Flash memory interface */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ +#define STM32_TSC_BASE 0x40024000 /* 0x40024000-0x400243ff: TSC */ + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32_GPIOA_BASE 0x48000000 /* 0x48000000-0x480003ff: GPIO Port A */ +#define STM32_GPIOB_BASE 0x48000400 /* 0x48000400-0x480007ff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x48000800 /* 0x48000800-0x48000bff: GPIO Port C */ +#define STM32_GPIOD_BASE 0X48000C00 /* 0x48000c00-0x48000fff: GPIO Port D */ +#define STM32_GPIOE_BASE 0x48001000 /* 0x48001000-0x480013ff: GPIO Port E */ +#define STM32_GPIOF_BASE 0x48001400 /* 0x48001400-0x480017ff: GPIO Port F */ + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M4 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..6f48b4bf1e87308d0423cceac8f97d72359c59ab --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h @@ -0,0 +1,549 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32F37xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* CAN */ + +#define GPIO_CAN_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) + + +/* Comparator Outputs */ +#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN0) +#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN11) +#define GPIO_COMP1_OUT_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN6) +#define GPIO_COMP1_OUT_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN8) +#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN2) +#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +#define GPIO_COMP2_OUT_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN7) +#define GPIO_COMP2_OUT_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN9) + + +/* DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DACy_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + +#define GPIO_DAC1_1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC1_2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_DAC2_1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN14) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN6) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN10) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN7) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) + +/* I2S */ + +#define GPIO_I2S1_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +#define GPIO_I2S1_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN12) +#define GPIO_I2S1_CK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S1_CK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S1_MCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN6) +#define GPIO_I2S1_MCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN13) +#define GPIO_I2S1_MCK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S1_MCK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN8) +#define GPIO_I2S1_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2S1_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN0) +#define GPIO_I2S1_SD_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S1_SD_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2S1_SD_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN6) +#define GPIO_I2S1_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S1_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN11) +#define GPIO_I2S1_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2S1_WS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN6) + +#define GPIO_I2S2_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2S2_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2S2_CK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN10) +#define GPIO_I2S2_CK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN7) +#define GPIO_I2S2_CK_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN8) +#define GPIO_I2S2_MCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2S2_MCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2S2_MCK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN2) +#define GPIO_I2S2_MCK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN3) +#define GPIO_I2S2_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN10) +#define GPIO_I2S2_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_I2S2_SD_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN3) +#define GPIO_I2S2_SD_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN4) +#define GPIO_I2S2_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN11) +#define GPIO_I2S2_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2S2_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN6) + +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN1) +#define GPIO_I2S3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CK_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_MCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN2) +#define GPIO_I2S3_MCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S3_MCK_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN11) +#define GPIO_I2S3_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN3) +#define GPIO_I2S3_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S3_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) + +/* IR */ + +#define GPIO_IR_OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN13) +#define GPIO_IR_OUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN9) + +/* JTAG/SWD */ + +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO_TRACES_WO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_NJTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SWCLK_JTCK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_SWDIO_JTMS (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) + +/* MCO */ + +#define GPIO_MCO (GPIO_ALT|GPIO_AF0|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN13) +#define GPIO_SPI1_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MISO_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_SPI1_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_SPI1_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI1_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN4) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) + + +/* Timers */ + +#define GPIO_TIM2_CH1_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1_ETR_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN11) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH2OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM3_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM4_CH4OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM4_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM4_ETR_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM4_ETR_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM15_BKIN (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM15_CH2IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM15_CH2OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) + +#define GPIO_TIM16_BKIN (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM16_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM16_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM16_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM16_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM16_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1IN_5 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1OUT_5 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TIM16_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_TIM17_BKIN_1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM17_CH1IN_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1OUT_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1IN_2 (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1OUT_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF10|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM17_CH1IN_3 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1OUT_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1IN_4 (GPIO_ALT|GPIO_FLOAT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1OUT_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1N (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) + +/* TSC */ + +#define GPIO_TSC_G1_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TSC_G1_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TSC_G1_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TSC_G1_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TSC_G2_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN4) +#define GPIO_TSC_G2_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TSC_G2_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TSC_G2_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TSC_G3_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN5) +#define GPIO_TSC_G3_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TSC_G3_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TSC_G3_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN2) +#define GPIO_TSC_G4_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TSC_G4_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TSC_G4_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN13) +#define GPIO_TSC_G4_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN14) +#define GPIO_TSC_G5_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TSC_G5_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TSC_G5_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TSC_G5_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TSC_G6_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TSC_G6_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TSC_G6_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TSC_G6_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TSC_G7_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TSC_G7_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TSC_G7_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TSC_G7_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TSC_G8_IO1 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TSC_G8_IO2 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TSC_G8_IO3 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TSC_G8_IO4 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TSC_SYNC_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TSC_SYNC_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN8) + +/* Trace */ + +#define GPIO_TRACECK (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) + +/* USARTs/UARTs */ + +#define GPIO_USART1_CK (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN5) +#define GPIO_USART1_RX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN4) +#define GPIO_USART1_TX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN5) +#define GPIO_USART2_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CK_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTF|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART2_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART2_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN7) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTF|GPIO_PIN6) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN8) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN8) + +/* USB */ + +#define GPIO_USB_DM (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USB_DP (GPIO_ALT|GPIO_PUSHPULL|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN12) + +/* Event Outputs */ + +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA1_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN1) +#define GPIO_PA2_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN2) +#define GPIO_PA3_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN3) +#define GPIO_PA4_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN4) +#define GPIO_PA5_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN5) +#define GPIO_PA6_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN6) +#define GPIO_PA7_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN7) +#define GPIO_PA8_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN8) +#define GPIO_PA9_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN9) +#define GPIO_PA10_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN10) +#define GPIO_PA11_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN11) +#define GPIO_PA12_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN12) +#define GPIO_PA13_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_PB0_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN0) +#define GPIO_PB1_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN1) +#define GPIO_PB2_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN2) +#define GPIO_PB3_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN4) +#define GPIO_PB5_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN5) +#define GPIO_PB6_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN6) +#define GPIO_PB7_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN7) +#define GPIO_PB8_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN8) +#define GPIO_PB9_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN9) +#define GPIO_PB10_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN10) +#define GPIO_PB11_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN11) +#define GPIO_PB12_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN12) +#define GPIO_PB13_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN13) +#define GPIO_PB14_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN14) +#define GPIO_PB15_EVENT_OUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN15) + +#define GPIO_PC0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN0) +#define GPIO_PC1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN1) +#define GPIO_PC2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN2) +#define GPIO_PC3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN3) +#define GPIO_PC4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN4) +#define GPIO_PC5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5) +#define GPIO_PC6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN6) +#define GPIO_PC7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN7) +#define GPIO_PC8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN8) +#define GPIO_PC9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN9) +#define GPIO_PC10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN10) +#define GPIO_PC11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PC12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_PD0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN0) +#define GPIO_PD1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN1) +#define GPIO_PD2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN2) +#define GPIO_PD3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN3) +#define GPIO_PD4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN4) +#define GPIO_PD5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN5) +#define GPIO_PD6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PD7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN7) +#define GPIO_PD8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN8) +#define GPIO_PD9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN9) +#define GPIO_PD10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN10) +#define GPIO_PD11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN11) +#define GPIO_PD12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN12) +#define GPIO_PD13_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN13) +#define GPIO_PD14_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN14) +#define GPIO_PD15_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN15) + +#define GPIO_PE0_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN0) +#define GPIO_PE1_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN1) +#define GPIO_PE2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN2) +#define GPIO_PE3_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN3) +#define GPIO_PE4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN4) +#define GPIO_PE5_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN5) +#define GPIO_PE6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN6) +#define GPIO_PE7_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN7) +#define GPIO_PE8_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_PE9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN9) +#define GPIO_PE10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_PE11_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN11) +#define GPIO_PE12_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_PE13_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN13) +#define GPIO_PE14_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN14) +#define GPIO_PE15_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) + +#define GPIO_PF2_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN2) +#define GPIO_PF4_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN4) +#define GPIO_PF6_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN6) +#define GPIO_PF9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN9) +#define GPIO_PF10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN10) + + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_PINMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..9c48bbd5d576bfac794f26bbf743379fde2d3454 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h @@ -0,0 +1,384 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f37xx_rcc.h + * For STM32F37xx advanced ARM-based 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_RCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_CFGR_OFFSET 0x0004 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x0008 /* Clock interrupt register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x000c /* APB2 Peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0010 /* APB1 Peripheral reset register */ +#define STM32_RCC_AHBENR_OFFSET 0x0014 /* AHB Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0018 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x001c /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0020 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0024 /* Control/status register */ +#define STM32_RCC_AHBRSTR_OFFSET 0x0028 /* AHB Reset register */ +#define STM32_RCC_CFGR2_OFFSET 0x002c /* Clock configuration register 2 */ +#define STM32_RCC_CFGR3_OFFSET 0x0030 /* Clock configuration register 3 */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_AHBENR (STM32_RCC_BASE+STM32_RCC_AHBENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#define STM32_RCC_AHBRSTR (STM32_RCC_BASE+STM32_RCC_AHBRSTR_OFFSET) +#define STM32_RCC_CFGR2 (STM32_RCC_BASE+STM32_RCC_CFGR2_OFFSET) +#define STM32_RCC_CFGR3 (STM32_RCC_BASE+STM32_RCC_CFGR3_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 1-0: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 3-2: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 7-4: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 10-8: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 13-11: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PLLSRC (1 << 16) /* Bit 16: PLL entry clock source */ +#define RCC_CFGR_PLLXTPRE (1 << 17) /* Bit 17: HSE divider for PLL entry */ +#define RCC_CFGR_PLLMUL_SHIFT (18) /* Bits 21-18: PLL Multiplication Factor */ +#define RCC_CFGR_PLLMUL_MASK (0x0f << RCC_CFGR_PLLMUL_SHIFT) +# define RCC_CFGR_PLLMUL_CLKx2 (0 << RCC_CFGR_PLLMUL_SHIFT) /* 0000: PLL input clock x 2 */ +# define RCC_CFGR_PLLMUL_CLKx3 (1 << RCC_CFGR_PLLMUL_SHIFT) /* 0001: PLL input clock x 3 */ +# define RCC_CFGR_PLLMUL_CLKx4 (2 << RCC_CFGR_PLLMUL_SHIFT) /* 0010: PLL input clock x 4 */ +# define RCC_CFGR_PLLMUL_CLKx5 (3 << RCC_CFGR_PLLMUL_SHIFT) /* 0011: PLL input clock x 5 */ +# define RCC_CFGR_PLLMUL_CLKx6 (4 << RCC_CFGR_PLLMUL_SHIFT) /* 0100: PLL input clock x 6 */ +# define RCC_CFGR_PLLMUL_CLKx7 (5 << RCC_CFGR_PLLMUL_SHIFT) /* 0101: PLL input clock x 7 */ +# define RCC_CFGR_PLLMUL_CLKx8 (6 << RCC_CFGR_PLLMUL_SHIFT) /* 0110: PLL input clock x 8 */ +# define RCC_CFGR_PLLMUL_CLKx9 (7 << RCC_CFGR_PLLMUL_SHIFT) /* 0111: PLL input clock x 9 */ +# define RCC_CFGR_PLLMUL_CLKx10 (8 << RCC_CFGR_PLLMUL_SHIFT) /* 1000: PLL input clock x 10 */ +# define RCC_CFGR_PLLMUL_CLKx11 (9 << RCC_CFGR_PLLMUL_SHIFT) /* 1001: PLL input clock x 11 */ +# define RCC_CFGR_PLLMUL_CLKx12 (10 << RCC_CFGR_PLLMUL_SHIFT) /* 1010: PLL input clock x 12 */ +# define RCC_CFGR_PLLMUL_CLKx13 (11 << RCC_CFGR_PLLMUL_SHIFT) /* 1011: PLL input clock x 13 */ +# define RCC_CFGR_PLLMUL_CLKx14 (12 << RCC_CFGR_PLLMUL_SHIFT) /* 1100: PLL input clock x 14 */ +# define RCC_CFGR_PLLMUL_CLKx15 (13 << RCC_CFGR_PLLMUL_SHIFT) /* 1101: PLL input clock x 15 */ +# define RCC_CFGR_PLLMUL_CLKx16 (14 << RCC_CFGR_PLLMUL_SHIFT) /* 111x: PLL input clock x 16 */ +#define RCC_CFGR_USBPRE (1 << 22) /* Bit 22: USB prescaler */ +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 26-24: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (3 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_MCO_DISABLED (0 << RCC_CFGR_MCO_SHIFT) /* 000: MCO output disabled, no clock on MCO */ +# define RCC_CFGR_MCO_LSICLK (2 << RCC_CFGR_MCO_SHIFT) /* 010: LSI clock selected */ +# define RCC_CFGR_MCO_LSECLK (3 << RCC_CFGR_MCO_SHIFT) /* 011: LSE clock selected */ +# define RCC_CFGR_MCO_SYSCLK (4 << RCC_CFGR_MCO_SHIFT) /* 100: System clock (SYSCLK) selected */ +# define RCC_CFGR_MCO_HSICLK (5 << RCC_CFGR_MCO_SHIFT) /* 101: HSI clock selected */ +# define RCC_CFGR_MCO_HSECLK (6 << RCC_CFGR_MCO_SHIFT) /* 101: HSE clock selected */ +# define RCC_CFGR_PLLCLKd2 (7 << RCC_CFGR_MCO_SHIFT) /* 111: PLL clock divided by 2 selected */ +#define RCC_CFGR_SDADCPRE_SHIFT (24) /* Bits 27-31: SDADC Prescaler */ +#define RCC_CFGR_SDADCPRE_MASK (31 << RCC_CFGR_SDADCPRE_SHIFT) +# define RCC_CFGR_SDADCPRE_DIV2 (0 << RCC_CFGR_SDADCPRE_SHIFT) /* 0xxxx: System clock divided by 2 */ +# define RCC_CFGR_SDADCPRE_DIV4 (17 << RCC_CFGR_SDADCPRE_SHIFT) /* 10001: System clock divided by 4 */ +# define RCC_CFGR_SDADCPRE_DIV6 (18 << RCC_CFGR_SDADCPRE_SHIFT) /* 10010: System clock divided by 6 */ +# define RCC_CFGR_SDADCPRE_DIV8 (19 << RCC_CFGR_SDADCPRE_SHIFT) /* 10011: System clock divided by 8 */ +# define RCC_CFGR_SDADCPRE_DIV10 (20 << RCC_CFGR_SDADCPRE_SHIFT) /* 10100: System clock divided by 10 */ +# define RCC_CFGR_SDADCPRE_DIV12 (21 << RCC_CFGR_SDADCPRE_SHIFT) /* 10101: System clock divided by 12 */ +# define RCC_CFGR_SDADCPRE_DIV14 (22 << RCC_CFGR_SDADCPRE_SHIFT) /* 10110: System clock divided by 14 */ +# define RCC_CFGR_SDADCPRE_DIV16 (23 << RCC_CFGR_SDADCPRE_SHIFT) /* 10111: System clock divided by 16 */ +# define RCC_CFGR_SDADCPRE_DIV20 (24 << RCC_CFGR_SDADCPRE_SHIFT) /* 11000: System clock divided by 20 */ +# define RCC_CFGR_SDADCPRE_DIV24 (25 << RCC_CFGR_SDADCPRE_SHIFT) /* 11001: System clock divided by 24 */ +# define RCC_CFGR_SDADCPRE_DIV28 (26 << RCC_CFGR_SDADCPRE_SHIFT) /* 11010: System clock divided by 28 */ +# define RCC_CFGR_SDADCPRE_DIV32 (27 << RCC_CFGR_SDADCPRE_SHIFT) /* 11011: System clock divided by 32 */ +# define RCC_CFGR_SDADCPRE_DIV36 (28 << RCC_CFGR_SDADCPRE_SHIFT) /* 11100: System clock divided by 36 */ +# define RCC_CFGR_SDADCPRE_DIV40 (29 << RCC_CFGR_SDADCPRE_SHIFT) /* 11101: System clock divided by 40 */ +# define RCC_CFGR_SDADCPRE_DIV44 (30 << RCC_CFGR_SDADCPRE_SHIFT) /* 11110: System clock divided by 44 */ +# define RCC_CFGR_SDADCPRE_DIV48 (31 << RCC_CFGR_SDADCPRE_SHIFT) /* 11111: System clock divided by 48 */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: SYSCFG, Comparators and operational amplifiers reset */ +#define RCC_APB2RSTR_ADC1RST (1 << 9) /* Bit 9: ADC1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#define RCC_APB2RSTR_TIM19RST (1 << 19) /* Bit 19: TIM19 reset */ +#define RCC_APB2RSTR_SDADC1RST (1 << 24) /* Bit 24: SDADC1 reset */ +#define RCC_APB2RSTR_SDADC2RST (1 << 25) /* Bit 25: SDADC2 reset */ +#define RCC_APB2RSTR_SDADC3RST (1 << 26) /* Bit 26: SDADC3 reset */ + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: Timer 4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 2: Timer 5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: Timer 6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: Timer 7 reset */ +#define RCC_APB1RSTR_TIM12RST (1 << 6) /* Bit 6: Timer 12 reset */ +#define RCC_APB1RSTR_TIM13RST (1 << 7) /* Bit 7: Timer 13 reset */ +#define RCC_APB1RSTR_TIM14RST (1 << 8) /* Bit 8: Timer 14 reset */ +#define RCC_APB1RSTR_TIM18RST (1 << 9) /* Bit 9: Timer 18 reset */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window Watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_USBRST (1 << 23) /* Bit 23: USB reset */ +#define RCC_APB1RSTR_CANRST (1 << 25) /* Bit 25: CAN reset */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN reset */ +#define RCC_APB1RSTR_DAC2RST (1 << 26) /* Bit 26: DAC1 interface reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DAC1RST (1 << 29) /* Bit 29: DAC1 interface reset */ +#define RCC_APB1RSTR_CECRST (1 << 30) /* Bit 30: CEC reset */ + +/* AHB Peripheral Clock enable register */ + +#define RCC_AHBENR_DMA1EN (1 << 0) /* Bit 0: DMA1 clock enable */ +#define RCC_AHBENR_DMA2EN (1 << 1) /* Bit 1: DMA2 clock enable */ +#define RCC_AHBENR_SRAMEN (1 << 2) /* Bit 2: SRAM interface clock enable */ +#define RCC_AHBENR_FLITFEN (1 << 4) /* Bit 4: FLITF clock enable */ +#define RCC_AHBENR_CRCEN (1 << 6) /* Bit 6: CRC clock enable */ +#define RCC_AHBENR_IOPAEN (1 << 17) /* Bit 17: I/O port A clock enable */ +#define RCC_AHBENR_IOPBEN (1 << 18) /* Bit 17: I/O port B clock enable */ +#define RCC_AHBENR_IOPCEN (1 << 19) /* Bit 17: I/O port C clock enable */ +#define RCC_AHBENR_IOPDEN (1 << 20) /* Bit 17: I/O port D clock enable */ +#define RCC_AHBENR_IOPEEN (1 << 21) /* Bit 17: I/O port E clock enable */ +#define RCC_AHBENR_IOPFEN (1 << 22) /* Bit 17: I/O port F clock enable */ +#define RCC_AHBENR_TSCEN (1 << 24) /* Bit 24: TSCEN: Touch sensing controller clock enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: SYSCFG, Comparators and operational amplifiers clock enable */ +#define RCC_APB2ENR_ADC1EN (1 << 9) /* Bit 9: ADC1 clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI 1 clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 clock enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 clock enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 clock enable */ +#define RCC_APB2ENR_TIM19EN (1 << 19) /* Bit 19: TIM19 clock enable */ +#define RCC_APB2ENR_SDADC1EN (1 << 24) /* Bit 24: SDADC1 clock enable */ +#define RCC_APB2ENR_SDADC2EN (1 << 25) /* Bit 25: SDADC2 clock enable */ +#define RCC_APB2ENR_SDADC3EN (1 << 26) /* Bit 26: SDADC3 clock enable */ + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: Timer 4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 2: Timer 5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: Timer 6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: Timer 7 clock enable */ +#define RCC_APB1ENR_TIM12EN (1 << 6) /* Bit 6: Timer 12 clock enable */ +#define RCC_APB1ENR_TIM13EN (1 << 7) /* Bit 7: Timer 13 clock enable */ +#define RCC_APB1ENR_TIM14EN (1 << 8) /* Bit 8: Timer 14 clock enable */ +#define RCC_APB1ENR_TIM18EN (1 << 9) /* Bit 9: Timer 18 clock enable */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window Watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI 3 clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C 2 clock enable */ +#define RCC_APB1ENR_USBEN (1 << 23) /* Bit 23: USB clock enable */ +#define RCC_APB1ENR_CANEN (1 << 25) /* Bit 25: CAN clock enable */ +#define RCC_APB1ENR_DAC2EN (1 << 26) /* Bit 26: DAC1 interface clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DAC1EN (1 << 29) /* Bit 29: DAC1 interface clock enable */ +#define RCC_APB1ENR_CECEN (1 << 30) /* Bit 30: CEC clock enable */ + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 4:3: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' lower driving capability */ +# define RCC_BDCR_LSEDRV_MEDLOW (1 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' medium low driving capability */ +# define RCC_BDCR_LSEDRV_MEDHIGH (2 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' medium high driving capability */ +# define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) /* 'Xtal mode' higher driving capability */ +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* AHB peripheral clock reset register (RCC_AHBRSTR) */ + +#define RCC_AHBRSTR_IOPARST (1 << 17) /* Bit 17: I/O port A reset */ +#define RCC_AHBRSTR_IOPBRST (1 << 18) /* Bit 18: I/O port B reset */ +#define RCC_AHBRSTR_IOPCRST (1 << 29) /* Bit 19: I/O port C reset */ +#define RCC_AHBRSTR_IOPDRST (1 << 20) /* Bit 20: I/O port D reset */ +#define RCC_AHBRSTR_IOPERST (1 << 21) /* Bit 21: I/O port E reset */ +#define RCC_AHBRSTR_IOPFRST (1 << 22) /* Bit 22: I/O port F reset */ +#define RCC_AHBRSTR_TSCRST (1 << 24) /* Bit 24: Touch sensing controller reset */ + +/* Clock configuration register 2 */ + +#define RCC_CFGR2_PREDIV_SHIFT (0) /* Bits 0-3: PREDIV division factor */ +#define RCC_CFGR2_PREDIV_MASK (15 << RCC_CFGR2_PREDIV_SHIFT) +# define RCC_CFGR2_PREDIVd1 (0 << RCC_CFGR2_PREDIV_SHIFT) /* 0000: HSE input to PLL not divided */ +# define RCC_CFGR2_PREDIVd2 (1 << RCC_CFGR2_PREDIV_SHIFT) /* 0001: HSE input to PLL divided by 2 */ +# define RCC_CFGR2_PREDIVd3 (2 << RCC_CFGR2_PREDIV_SHIFT) /* 0010: HSE input to PLL divided by 3 */ +# define RCC_CFGR2_PREDIVd4 (3 << RCC_CFGR2_PREDIV_SHIFT) /* 0011: HSE input to PLL divided by 4 */ +# define RCC_CFGR2_PREDIVd5 (4 << RCC_CFGR2_PREDIV_SHIFT) /* 0100: HSE input to PLL divided by 5 */ +# define RCC_CFGR2_PREDIVd6 (5 << RCC_CFGR2_PREDIV_SHIFT) /* 0101: HSE input to PLL divided by 6 */ +# define RCC_CFGR2_PREDIVd7 (6 << RCC_CFGR2_PREDIV_SHIFT) /* 0110: HSE input to PLL divided by 7 */ +# define RCC_CFGR2_PREDIVd8 (7 << RCC_CFGR2_PREDIV_SHIFT) /* 0111: HSE input to PLL divided by 8 */ +# define RCC_CFGR2_PREDIVd9 (8 << RCC_CFGR2_PREDIV_SHIFT) /* 1000: HSE input to PLL divided by 9 */ +# define RCC_CFGR2_PREDIVd10 (9 << RCC_CFGR2_PREDIV_SHIFT) /* 1001: HSE input to PLL divided by 10 */ +# define RCC_CFGR2_PREDIVd11 (10 << RCC_CFGR2_PREDIV_SHIFT) /* 1010: HSE input to PLL divided by 11 */ +# define RCC_CFGR2_PREDIVd12 (11 << RCC_CFGR2_PREDIV_SHIFT) /* 1011: HSE input to PLL divided by 12 */ +# define RCC_CFGR2_PREDIVd13 (12 << RCC_CFGR2_PREDIV_SHIFT) /* 1100: HSE input to PLL divided by 13 */ +# define RCC_CFGR2_PREDIVd14 (13 << RCC_CFGR2_PREDIV_SHIFT) /* 1101: HSE input to PLL divided by 14 */ +# define RCC_CFGR2_PREDIVd15 (14 << RCC_CFGR2_PREDIV_SHIFT) /* 1110: HSE input to PLL divided by 15 */ +# define RCC_CFGR2_PREDIVd16 (15 << RCC_CFGR2_PREDIV_SHIFT) /* 1111: HSE input to PLL divided by 16 */ + +/* Clock configuration register 3 */ + +#define RCC_CFGR3_USART1SW_SHIFT (0) /* Bits 0-1: USART1 clock source selection */ +#define RCC_CFGR3_USART1SW_MASK (3 << RCC_CFGR3_USART1SW_SHIFT) +# define RCC_CFGR3_USART1SW_PCLK (0 << RCC_CFGR3_USART1SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART1SW_SYSCLK (1 << RCC_CFGR3_USART1SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART1SW_HSI (0 << RCC_CFGR3_USART1SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_I2C1SW (1 << 4) /* Bit 4: I2C1 clock source selection */ +#define RCC_CFGR3_I2C2SW (1 << 5) /* Bit 5: I2C2 clock source selection */ +#define RCC_CFGR3_CECSW (1 << 6) /* Bit 6: CEC clock source selection */ +#define RCC_CFGR3_USART2SW_SHIFT (16) /* Bits 16-17: USART2 clock source selection */ +#define RCC_CFGR3_USART2SW_MASK (3 << RCC_CFGR3_USART2SW_SHIFT) +# define RCC_CFGR3_USART2SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART2SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART2SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART2SW_HSI (0 << RCC_CFGR3_USART2SW_SHIFT) /* HSI clock */ +#define RCC_CFGR3_USART3SW_SHIFT (18) /* Bits 18-19: USART3 clock source selection */ +#define RCC_CFGR3_USART3SW_MASK (3 << RCC_CFGR3_USART3SW_SHIFT) +# define RCC_CFGR3_USART3SW_PCLK (0 << RCC_CFGR3_USART3SW_SHIFT) /* PCLK */ +# define RCC_CFGR3_USART3SW_SYSCLK (1 << RCC_CFGR3_USART3SW_SHIFT) /* System clock (SYSCLK) */ +# define RCC_CFGR3_USART3SW_LSE (2 << RCC_CFGR3_USART3SW_SHIFT) /* LSE clock */ +# define RCC_CFGR3_USART3SW_HSI (0 << RCC_CFGR3_USART3SW_SHIFT) /* HSI clock */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_RCC_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f37xxx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..2219009ef7da2fedd208c27d7d7bfe87ab3efafa --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_syscfg.h @@ -0,0 +1,166 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f37xxx_syscfg.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#ifdef CONFIG_STM32_STM32F37XX + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_CFGR1_OFFSET 0x0000 /* SYSCFG configuration register 1 */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +#define STM32_SYSCFG_CFGR2_OFFSET 0x0018 /* SYSCFG configuration register 2 */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_CFGR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR1_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +#define STM32_SYSCFG_CFGR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR2_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_CFGR1_MEMMODE_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_CFGR1_MEMMODE_MASK (3 << SYSCFG_CFGR1_MEMMODE_SHIFT) +# define SYSCFG_CFGR1_MEMMODE_FLASH (0 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 00: Main Flash at 0x00000000 */ +# define SYSCFG_CFGR1_MEMMODE_SYSTEM (1 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 01: System Flash at 0x00000000 */ +# define SYSCFG_CFGR1_MEMMODE_SRAM (3 << SYSCFG_CFGR1_MEMMODE_SHIFT) /* 11: Embedded SRAM at 0x00000000 */ +#define SYSCFG_CFGR1_TIM16_DMARMP (1 << 11) /* Bit 11: TIM16 DMA request remapping bit */ +#define SYSCFG_CFGR1_TIM17_DMARMP (1 << 12) /* Bit 12: TIM17 DMA request remapping bit */ +#define SYSCFG_CFGR1_TIM6_DMARMP (1 << 13) /* Bit 13: TIM6 DMA remap, or */ +#define SYSCFG_CFGR1_DAC1_CH1_DMARMP (1 << 13) /* Bit 13: DAC 1 channel 2 DMA remap */ +#define SYSCFG_CFGR1_TIM7_DMARMP (1 << 14) /* Bit 14: TIM7 DMA remap */ +#define SYSCFG_CFGR1_DAC1_CH2_DMARMP (1 << 14) /* Bit 14: DAC 1 channel 2 DMA remap */ +#define SYSCFG_CFGR1_TIM18_DMARMP (1 << 15) /* Bit 15: TIM18 DMA remap */ +#define SYSCFG_CFGR1_DAC2_CH1_DMARMP (1 << 15) /* Bit 15: DAC 2 channel 1 DMA remap */ +#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (16) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ +#define SYSCFG_CFGR1_I2C_PBXFMP_MASK (15 << SYSCFG_CFGR1_I2C_PBXFMP_SHIFT) +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 fast mode Plus driving capability */ +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 fast mode Plus driving capability */ +#define SYSCFG_CFGR1_VBAT (1 << 24) /* Bit 24: VBat monitor enable */ +#define SYSCFG_CFGR1_FPUIE_SHIFT (26) /* Bits 26-31: Floating Point Unit interrupts enable bits */ +#define SYSCFG_CFGR1_FPUIE_MASK (63 << SYSCFG_CFGR1_FPUIE_SHIFT) +# define SYSCFG_CFGR1_FPUIE_INVALIDOP (1 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Invalid operation interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_DIVZERO (2 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Divide-by-zero interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_UNDERFLOW (4 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Underflow interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_OVERFLOW (8 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Overflow interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_DENORMAL (16 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Input denormal interrupt enable */ +# define SYSCFG_CFGR1_FPUIE_INEXACT (32 << SYSCFG_CFGR1_FPUIE_SHIFT) /* Inexact interrupt enable */ + + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: Reserved */ +#define SYSCFG_EXTICR_PORTE (5) /* 0101: PF[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* SYSCFG configuration register 2 */ + +#define SYSCFG_CFGR2_LOCKUPLOCK (1 << 0) /* Bit 0: Cortex-M4 Hardfault output bit enable */ +#define SYSCFG_CFGR2_SRAM_PARITYLOCK (1 << 1) /* Bit 1: RAM parity lock */ +#define SYSCFG_CFGR2_PVDLOCK (1 << 2) /* Bit 2: PVD lock enable */ +#define SYSCFG_CFGR2_SRAM_PEF (1 << 8) /* Bit 8: SRAM parity error */ + +#endif /* CONFIG_STM32_STM32F37XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_vectors.h b/arch/arm/src/stm32/chip/stm32f37xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..c85269daf5d58fe1859f1e031309cdca3eab9cf1 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_vectors.h @@ -0,0 +1,150 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f37xxx_vectors.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies each STM32F37xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f37xxx_irq.h. + * stm32_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 82 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 82 + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* 0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* 1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* 2: Tamper or Time stamp interrupt */ +VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* 3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* 4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* 5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* 6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* 7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* 8: EXTI Line 2 or TSC interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* 9: EXTI Line 3 interrupt */ + +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* 10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* 11: DMA1 channel 1 global interrupt */ +VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* 12: DMA1 channel 2 global interrupt */ +VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* 13: DMA1 channel 3 global interrupt */ +VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* 14: DMA1 channel 4 global interrupt */ +VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* 15: DMA1 channel 5 global interrupt */ +VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* 16: DMA1 channel 6 global interrupt */ +VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* 17: DMA1 channel 7 global interrupt */ +VECTOR(stm32_adc1, STM32_IRQ_ADC1) /* 18: ADC1 global interrupt */ +VECTOR(stm32_can1tx, STM32_IRQ_CAN1TX) /* 19: CAN1 TX interrupts */ + +VECTOR(stm32_can1rx0, STM32_IRQ_CAN1RX0) /* 20: CAN1 RX0 interrupts*/ +VECTOR(stm32_can1rx1, STM32_IRQ_CAN1RX1) /* 21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* 22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* 23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim15, STM32_IRQ_TIM15) /* 24: TIM15 global interrupt */ +VECTOR(stm32_tim16, STM32_IRQ_TIM16) /* 25: TIM16 global interrupt */ +VECTOR(stm32_tim17, STM32_IRQ_TIM17) /* 26: TIM17 global interrupt */ +VECTOR(stm32_tim18, STM32_IRQ_TIM18) /* 27: TIM18 global interrupt or DAC2 interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* 28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* 29: TIM3 global interrupt */ + +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* 30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* 31: I2C1 event or EXTI Line23 interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* 32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* 33: I2C2 event or EXTI Line24 interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* 34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* 35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* 36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* 37: USART1 global or EXTI Line 25 interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* 38: USART2 global or EXTI Line 26 interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* 39: USART3 global or EXTI Line 28 interrupt */ + +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* 40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* 41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_cec, STM32_IRQ_CEC) /* 42: CEC global interrupt */ +VECTOR(stm32_tim12, STM32_IRQ_TIM12) /* 43: TIM12 global interrupt */ +VECTOR(stm32_tim13, STM32_IRQ_TIM13) /* 44: TIM13 global interrupt */ +VECTOR(stm32_tim14, STM32_IRQ_TIM14) /* 45: TIM14 global interrupt */ +UNUSED(STM32_IRQ_RESERVED46) /* 46: Reserved */ +UNUSED(STM32_IRQ_RESERVED47) /* 47: Reserved */ +UNUSED(STM32_IRQ_RESERVED48) /* 48: Reserved */ +UNUSED(STM32_IRQ_RESERVED49) /* 49: Reserved */ + +UNUSED(STM32_IRQ_RESERVED50) /* 50: Reserved */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* 51: SPI3 global interrupt */ +UNUSED(STM32_IRQ_RESERVED52) /* 52: Reserved */ +UNUSED(STM32_IRQ_RESERVED53) /* 53: Reserved */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* 54: TIM6 global or DAC1 underrun interrupts */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* 55: TIM7 global interrupt */ +VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* 56: DMA2 channel 1 global interrupt */ +VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* 57: DMA2 channel 2 global interrupt */ +VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* 58: DMA2 channel 3 global interrupt */ +VECTOR(stm32_dma2ch4, STM32_IRQ_DMA2CH4) /* 59: DMA2 channel 4 global interrupt */ + +VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* 60: DMA2 channel 5 global interrupt */ +VECTOR(stm32_sdadc1, STM32_IRQ_SDADC1) /* 61: SDADC1 global interrupt */ +VECTOR(stm32_sdadc2, STM32_IRQ_SDADC2) /* 62: SDADC2 global interrupt */ +VECTOR(stm32_sdadc3, STM32_IRQ_SDADC3) /* 63: SDADC3 global interrupt */ +VECTOR(stm32_comp12, STM32_IRQ_COMP12) /* 64: COMP1-2 */ +UNUSED(STM32_IRQ_RESERVED65) /* 65: Reserved */ +UNUSED(STM32_IRQ_RESERVED66) /* 66: Reserved */ +UNUSED(STM32_IRQ_RESERVED67) /* 67: Reserved */ +UNUSED(STM32_IRQ_RESERVED68) /* 68: Reserved */ +UNUSED(STM32_IRQ_RESERVED69) /* 69: Reserved */ + +UNUSED(STM32_IRQ_RESERVED70) /* 70: Reserved */ +UNUSED(STM32_IRQ_RESERVED71) /* 71: Reserved */ +UNUSED(STM32_IRQ_RESERVED72) /* 72: Reserved */ +UNUSED(STM32_IRQ_RESERVED73) /* 73: Reserved */ +VECTOR(stm32_usbhp, STM32_IRQ_USBHP) /* 74: USB High priority interrupt */ +VECTOR(stm32_usblp, STM32_IRQ_USBLP) /* 75: USB Low priority interrupt */ +VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP) /* 76: USB wakeup from suspend through EXTI line interrupt*/ +UNUSED(STM32_IRQ_RESERVED77) /* 77: Reserved */ +UNUSED(STM32_IRQ_RESERVED78) /* 78: Reserved */ +UNUSED(STM32_IRQ_RESERVED79) /* 79: Reserved */ + +UNUSED(STM32_IRQ_RESERVED80) /* 80: Reserved */ +VECTOR(stm32_fpu, STM32_IRQ_FPU) /* 81: FPU global interrupt */ + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_dma.h b/arch/arm/src/stm32/chip/stm32f40xxx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..13dbc0e3e86bab1fab376d172ecbd845612142a3 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_dma.h @@ -0,0 +1,561 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_dma.h + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_DMA_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_DMA_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* 2 DMA controllers */ + +#define DMA1 (0) +#define DMA2 (1) + +/* 8 DMA streams */ + +#define DMA_STREAM0 (0) +#define DMA_STREAM1 (1) +#define DMA_STREAM2 (2) +#define DMA_STREAM3 (3) +#define DMA_STREAM4 (4) +#define DMA_STREAM5 (5) +#define DMA_STREAM6 (6) +#define DMA_STREAM7 (7) + +/* 8 DMA channels */ + +#define DMA_CHAN0 (0) +#define DMA_CHAN1 (1) +#define DMA_CHAN2 (2) +#define DMA_CHAN3 (3) +#define DMA_CHAN4 (4) +#define DMA_CHAN5 (5) +#define DMA_CHAN6 (6) +#define DMA_CHAN7 (7) + +/* Register Offsets *****************************************************************/ + +#define STM32_DMA_LISR_OFFSET 0x0000 /* DMA low interrupt status register */ +#define STM32_DMA_HISR_OFFSET 0x0004 /* DMA high interrupt status register */ +#define STM32_DMA_LIFCR_OFFSET 0x0008 /* DMA low interrupt flag clear register */ +#define STM32_DMA_HIFCR_OFFSET 0x000c /* DMA high interrupt flag clear register */ + +#define STM32_DMA_OFFSET(n) (0x0010+0x0018*(n)) +#define STM32_DMA_SCR_OFFSET 0x0000 /* DMA stream n configuration register */ +#define STM32_DMA_SNDTR_OFFSET 0x0004 /* DMA stream n number of data register */ +#define STM32_DMA_SPAR_OFFSET 0x0008 /* DMA stream n peripheral address register */ +#define STM32_DMA_SM0AR_OFFSET 0x000c /* DMA stream n memory 0 address register */ +#define STM32_DMA_SM1AR_OFFSET 0x0010 /* DMA stream n memory 1 address register */ +#define STM32_DMA_SFCR_OFFSET 0x0014 /* DMA stream n FIFO control register */ + +#define STM32_DMA_S0CR_OFFSET 0x0010 /* DMA stream 0 configuration register */ +#define STM32_DMA_S1CR_OFFSET 0x0028 /* DMA stream 1 configuration register */ +#define STM32_DMA_S2CR_OFFSET 0x0040 /* DMA stream 2 configuration register */ +#define STM32_DMA_S3CR_OFFSET 0x0058 /* DMA stream 3 configuration register */ +#define STM32_DMA_S4CR_OFFSET 0x0070 /* DMA stream 4 configuration register */ +#define STM32_DMA_S5CR_OFFSET 0x0088 /* DMA stream 5 configuration register */ +#define STM32_DMA_S6CR_OFFSET 0x00a0 /* DMA stream 6 configuration register */ +#define STM32_DMA_S7CR_OFFSET 0x00b8 /* DMA stream 7 configuration register */ + +#define STM32_DMA_S0NDTR_OFFSET 0x0014 /* DMA stream 0 number of data register */ +#define STM32_DMA_S1NDTR_OFFSET 0x002c /* DMA stream 1 number of data register */ +#define STM32_DMA_S2NDTR_OFFSET 0x0044 /* DMA stream 2 number of data register */ +#define STM32_DMA_S3NDTR_OFFSET 0x005c /* DMA stream 3 number of data register */ +#define STM32_DMA_S4NDTR_OFFSET 0x0074 /* DMA stream 4 number of data register */ +#define STM32_DMA_S5NDTR_OFFSET 0x008c /* DMA stream 5 number of data register */ +#define STM32_DMA_S6NDTR_OFFSET 0x00a4 /* DMA stream 6 number of data register */ +#define STM32_DMA_S7NDTR_OFFSET 0x00bc /* DMA stream 7 number of data register */ + +#define STM32_DMA_S0PAR_OFFSET 0x0018 /* DMA stream 0 peripheral address register */ +#define STM32_DMA_S1PAR_OFFSET 0x0030 /* DMA stream 1 peripheral address register */ +#define STM32_DMA_S2PAR_OFFSET 0x0048 /* DMA stream 2 peripheral address register */ +#define STM32_DMA_S3PAR_OFFSET 0x0060 /* DMA stream 3 peripheral address register */ +#define STM32_DMA_S4PAR_OFFSET 0x0078 /* DMA stream 4 peripheral address register */ +#define STM32_DMA_S5PAR_OFFSET 0x0090 /* DMA stream 5 peripheral address register */ +#define STM32_DMA_S6PAR_OFFSET 0x00a8 /* DMA stream 6 peripheral address register */ +#define STM32_DMA_S7PAR_OFFSET 0x00c0 /* DMA stream 7 peripheral address register */ + +#define STM32_DMA_S0M0AR_OFFSET 0x001c /* DMA stream 0 memory 0 address register */ +#define STM32_DMA_S1M0AR_OFFSET 0x0034 /* DMA stream 1 memory 0 address register */ +#define STM32_DMA_S2M0AR_OFFSET 0x004c /* DMA stream 2 memory 0 address register */ +#define STM32_DMA_S3M0AR_OFFSET 0x0064 /* DMA stream 3 memory 0 address register */ +#define STM32_DMA_S4M0AR_OFFSET 0x007c /* DMA stream 4 memory 0 address register */ +#define STM32_DMA_S5M0AR_OFFSET 0x0094 /* DMA stream 5 memory 0 address register */ +#define STM32_DMA_S6M0AR_OFFSET 0x00ac /* DMA stream 6 memory 0 address register */ +#define STM32_DMA_S7M0AR_OFFSET 0x00c4 /* DMA stream 7 memory 0 address register */ + +#define STM32_DMA_S0M1AR_OFFSET 0x0020 /* DMA stream 0 memory 1 address register */ +#define STM32_DMA_S1M1AR_OFFSET 0x0038 /* DMA stream 1 memory 1 address register */ +#define STM32_DMA_S2M1AR_OFFSET 0x0050 /* DMA stream 2 memory 1 address register */ +#define STM32_DMA_S3M1AR_OFFSET 0x0068 /* DMA stream 3 memory 1 address register */ +#define STM32_DMA_S4M1AR_OFFSET 0x0080 /* DMA stream 4 memory 1 address register */ +#define STM32_DMA_S5M1AR_OFFSET 0x0098 /* DMA stream 5 memory 1 address register */ +#define STM32_DMA_S6M1AR_OFFSET 0x00b0 /* DMA stream 6 memory 1 address register */ +#define STM32_DMA_S7M1AR_OFFSET 0x00c8 /* DMA stream 7 memory 1 address register */ + +#define STM32_DMA_S0FCR_OFFSET 0x0024 /* DMA stream 0 FIFO control register */ +#define STM32_DMA_S1FCR_OFFSET 0x003c /* DMA stream 1 FIFO control register */ +#define STM32_DMA_S2FCR_OFFSET 0x0054 /* DMA stream 2 FIFO control register */ +#define STM32_DMA_S3FCR_OFFSET 0x006c /* DMA stream 3 FIFO control register */ +#define STM32_DMA_S4FCR_OFFSET 0x0084 /* DMA stream 4 FIFO control register */ +#define STM32_DMA_S5FCR_OFFSET 0x009c /* DMA stream 5 FIFO control register */ +#define STM32_DMA_S6FCR_OFFSET 0x00b4 /* DMA stream 6 FIFO control register */ +#define STM32_DMA_S7FCR_OFFSET 0x00cc /* DMA stream 7 FIFO control register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_DMA1_LISRC (STM32_DMA1_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA1_HISRC (STM32_DMA1_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA1_LIFCR (STM32_DMA1_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA1_HIFCR (STM32_DMA1_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA1_SCR(n) (STM32_DMA1_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0CR (STM32_DMA1_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA1_S1CR (STM32_DMA1_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA1_S2CR (STM32_DMA1_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA1_S3CR (STM32_DMA1_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA1_S4CR (STM32_DMA1_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA1_S5CR (STM32_DMA1_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA1_S6CR (STM32_DMA1_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA1_S7CR (STM32_DMA1_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA1_SNDTR(n) (STM32_DMA1_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0NDTR (STM32_DMA1_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA1_S1NDTR (STM32_DMA1_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA1_S2NDTR (STM32_DMA1_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA1_S3NDTR (STM32_DMA1_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA1_S4NDTR (STM32_DMA1_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA1_S5NDTR (STM32_DMA1_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA1_S6NDTR (STM32_DMA1_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA1_S7NDTR (STM32_DMA1_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA1_SPAR(n) (STM32_DMA1_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0PAR (STM32_DMA1_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA1_S1PAR (STM32_DMA1_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA1_S2PAR (STM32_DMA1_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA1_S3PAR (STM32_DMA1_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA1_S4PAR (STM32_DMA1_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA1_S5PAR (STM32_DMA1_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA1_S6PAR (STM32_DMA1_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA1_S7PAR (STM32_DMA1_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA1_SM0AR(n) (STM32_DMA1_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M0AR (STM32_DMA1_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA1_S1M0AR (STM32_DMA1_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA1_S2M0AR (STM32_DMA1_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA1_S3M0AR (STM32_DMA1_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA1_S4M0AR (STM32_DMA1_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA1_S5M0AR (STM32_DMA1_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA1_S6M0AR (STM32_DMA1_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA1_S7M0AR (STM32_DMA1_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA1_SM1AR(n) (STM32_DMA1_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M1AR (STM32_DMA1_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA1_S1M1AR (STM32_DMA1_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA1_S2M1AR (STM32_DMA1_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA1_S3M1AR (STM32_DMA1_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA1_S4M1AR (STM32_DMA1_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA1_S5M1AR (STM32_DMA1_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA1_S6M1AR (STM32_DMA1_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA1_S7M1AR (STM32_DMA1_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA1_SFCR(n) (STM32_DMA1_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0FCR (STM32_DMA1_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA1_S1FCR (STM32_DMA1_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA1_S2FCR (STM32_DMA1_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA1_S3FCR (STM32_DMA1_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA1_S4FCR (STM32_DMA1_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA1_S5FCR (STM32_DMA1_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA1_S6FCR (STM32_DMA1_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA1_S7FCR (STM32_DMA1_BASE+STM32_DMA_S7FCR_OFFSET) + +#define STM32_DMA2_LISRC (STM32_DMA2_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA2_HISRC (STM32_DMA2_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA2_LIFCR (STM32_DMA2_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA2_HIFCR (STM32_DMA2_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA2_SCR(n) (STM32_DMA2_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0CR (STM32_DMA2_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA2_S1CR (STM32_DMA2_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA2_S2CR (STM32_DMA2_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA2_S3CR (STM32_DMA2_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA2_S4CR (STM32_DMA2_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA2_S5CR (STM32_DMA2_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA2_S6CR (STM32_DMA2_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA2_S7CR (STM32_DMA2_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA2_SNDTR(n) (STM32_DMA2_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0NDTR (STM32_DMA2_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA2_S1NDTR (STM32_DMA2_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA2_S2NDTR (STM32_DMA2_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA2_S3NDTR (STM32_DMA2_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA2_S4NDTR (STM32_DMA2_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA2_S5NDTR (STM32_DMA2_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA2_S6NDTR (STM32_DMA2_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA2_S7NDTR (STM32_DMA2_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA2_SPAR(n) (STM32_DMA2_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0PAR (STM32_DMA2_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA2_S1PAR (STM32_DMA2_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA2_S2PAR (STM32_DMA2_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA2_S3PAR (STM32_DMA2_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA2_S4PAR (STM32_DMA2_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA2_S5PAR (STM32_DMA2_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA2_S6PAR (STM32_DMA2_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA2_S7PAR (STM32_DMA2_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA2_SM0AR(n) (STM32_DMA2_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M0AR (STM32_DMA2_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA2_S1M0AR (STM32_DMA2_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA2_S2M0AR (STM32_DMA2_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA2_S3M0AR (STM32_DMA2_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA2_S4M0AR (STM32_DMA2_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA2_S5M0AR (STM32_DMA2_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA2_S6M0AR (STM32_DMA2_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA2_S7M0AR (STM32_DMA2_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA2_SM1AR(n) (STM32_DMA2_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M1AR (STM32_DMA2_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA2_S1M1AR (STM32_DMA2_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA2_S2M1AR (STM32_DMA2_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA2_S3M1AR (STM32_DMA2_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA2_S4M1AR (STM32_DMA2_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA2_S5M1AR (STM32_DMA2_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA2_S6M1AR (STM32_DMA2_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA2_S7M1AR (STM32_DMA2_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA2_SFCR(n) (STM32_DMA2_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0FCR (STM32_DMA2_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA2_S1FCR (STM32_DMA2_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA2_S2FCR (STM32_DMA2_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA2_S3FCR (STM32_DMA2_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA2_S4FCR (STM32_DMA2_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA2_S5FCR (STM32_DMA2_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA2_S6FCR (STM32_DMA2_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA2_S7FCR (STM32_DMA2_BASE+STM32_DMA_S7FCR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_STREAM_MASK 0x3f +#define DMA_STREAM_FEIF_BIT (1 << 0) /* Bit 0: Stream FIFO error interrupt flag */ +#define DMA_STREAM_DMEIF_BIT (1 << 2) /* Bit 2: Stream direct mode error interrupt flag */ +#define DMA_STREAM_TEIF_BIT (1 << 3) /* Bit 3: Stream Transfer Error flag */ +#define DMA_STREAM_HTIF_BIT (1 << 4) /* Bit 4: Stream Half Transfer flag */ +#define DMA_STREAM_TCIF_BIT (1 << 5) /* Bit 5: Stream Transfer Complete flag */ + +/* DMA interrupt status register and interrupt flag clear register field defintions */ + +#define DMA_INT_STREAM0_SHIFT (0) /* Bits 0-5: DMA Stream 0 interrupt */ +#define DMA_INT_STREAM0_MASK (DMA_STREAM_MASK << DMA_INT_STREAM0_SHIFT) +#define DMA_INT_STREAM1_SHIFT (6) /* Bits 6-11: DMA Stream 1 interrupt */ +#define DMA_INT_STREAM1_MASK (DMA_STREAM_MASK << DMA_INT_STREAM1_SHIFT) +#define DMA_INT_STREAM2_SHIFT (16) /* Bits 16-21: DMA Stream 2 interrupt */ +#define DMA_INT_STREAM2_MASK (DMA_STREAM_MASK << DMA_INT_STREAM2_SHIFT) +#define DMA_INT_STREAM3_SHIFT (22) /* Bits 22-27: DMA Stream 3 interrupt */ +#define DMA_INT_STREAM3_MASK (DMA_STREAM_MASK << DMA_INT_STREAM3_SHIFT) + +#define DMA_INT_STREAM4_SHIFT (0) /* Bits 0-5: DMA Stream 4 interrupt */ +#define DMA_INT_STREAM4_MASK (DMA_STREAM_MASK << DMA_INT_STREAM4_SHIFT) +#define DMA_INT_STREAM5_SHIFT (6) /* Bits 6-11: DMA Stream 5 interrupt */ +#define DMA_INT_STREAM5_MASK (DMA_STREAM_MASK << DMA_INT_STREAM5_SHIFT) +#define DMA_INT_STREAM6_SHIFT (16) /* Bits 16-21: DMA Stream 6 interrupt */ +#define DMA_INT_STREAM6_MASK (DMA_STREAM_MASK << DMA_INT_STREAM6_SHIFT) +#define DMA_INT_STREAM7_SHIFT (22) /* Bits 22-27: DMA Stream 7 interrupt */ +#define DMA_INT_STREAM7_MASK (DMA_STREAM_MASK << DMA_INT_STREAM7_SHIFT) + +/* DMA stream configuration register */ + +#define DMA_SCR_EN (1 << 0) /* Bit 0: Stream enable */ +#define DMA_SCR_DMEIE (1 << 1) /* Bit 1: Direct mode error interrupt enable */ +#define DMA_SCR_TEIE (1 << 2) /* Bit 2: Transfer error interrupt enable */ +#define DMA_SCR_HTIE (1 << 3) /* Bit 3: Half Transfer interrupt enable */ +#define DMA_SCR_TCIE (1 << 4) /* Bit 4: Transfer complete interrupt enable */ +#define DMA_SCR_PFCTRL (1 << 5) /* Bit 5: Peripheral flow controller */ +#define DMA_SCR_DIR_SHIFT (6) /* Bits 6-7: Data transfer direction */ +#define DMA_SCR_DIR_MASK (3 << DMA_SCR_DIR_SHIFT) +# define DMA_SCR_DIR_P2M (0 << DMA_SCR_DIR_SHIFT) /* 00: Peripheral-to-memory */ +# define DMA_SCR_DIR_M2P (1 << DMA_SCR_DIR_SHIFT) /* 01: Memory-to-peripheral */ +# define DMA_SCR_DIR_M2M (2 << DMA_SCR_DIR_SHIFT) /* 10: Memory-to-memory */ +#define DMA_SCR_CIRC (1 << 8) /* Bit 8: Circular mode */ +#define DMA_SCR_PINC (1 << 9) /* Bit 9: Peripheral increment mode */ +#define DMA_SCR_MINC (1 << 10) /* Bit 10: Memory increment mode */ +#define DMA_SCR_PSIZE_SHIFT (11) /* Bits 11-12: Peripheral size */ +#define DMA_SCR_PSIZE_MASK (3 << DMA_SCR_PSIZE_SHIFT) +# define DMA_SCR_PSIZE_8BITS (0 << DMA_SCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_PSIZE_16BITS (1 << DMA_SCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_PSIZE_32BITS (2 << DMA_SCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_MSIZE_SHIFT (13) /* Bits 13-14: Memory size */ +#define DMA_SCR_MSIZE_MASK (3 << DMA_SCR_MSIZE_SHIFT) +# define DMA_SCR_MSIZE_8BITS (0 << DMA_SCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_MSIZE_16BITS (1 << DMA_SCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_MSIZE_32BITS (2 << DMA_SCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_PINCOS (1 << 15) /* Bit 15: Peripheral increment offset size */ +#define DMA_SCR_PL_SHIFT (16) /* Bits 16-17: Stream Priority level */ +#define DMA_SCR_PL_MASK (3 << DMA_SCR_PL_SHIFT) +# define DMA_SCR_PRILO (0 << DMA_SCR_PL_SHIFT) /* 00: Low */ +# define DMA_SCR_PRIMED (1 << DMA_SCR_PL_SHIFT) /* 01: Medium */ +# define DMA_SCR_PRIHI (2 << DMA_SCR_PL_SHIFT) /* 10: High */ +# define DMA_SCR_PRIVERYHI (3 << DMA_SCR_PL_SHIFT) /* 11: Very high */ +#define DMA_SCR_DBM (1 << 18) /* Bit 15: Double buffer mode */ +#define DMA_SCR_CT (1 << 19) /* Bit 19: Current target */ +#define DMA_SCR_PBURST_SHIFT (21) /* Bits 21-22: Peripheral burst transfer configuration */ +#define DMA_SCR_PBURST_MASK (3 << DMA_SCR_PBURST_SHIFT) +# define DMA_SCR_PBURST_SINGLE (0 << DMA_SCR_PBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_PBURST_INCR4 (1 << DMA_SCR_PBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_PBURST_INCR8 (2 << DMA_SCR_PBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_PBURST_INCR16 (3 << DMA_SCR_PBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_MBURST_SHIFT (23) /* Bits 23-24: Memory burst transfer configuration */ +#define DMA_SCR_MBURST_MASK (3 << DMA_SCR_MBURST_SHIFT) +# define DMA_SCR_MBURST_SINGLE (0 << DMA_SCR_MBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_MBURST_INCR4 (1 << DMA_SCR_MBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_MBURST_INCR8 (2 << DMA_SCR_MBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_MBURST_INCR16 (3 << DMA_SCR_MBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_CHSEL_SHIFT (25) /* Bits 25-27: Channel selection */ +#define DMA_SCR_CHSEL_MASK (7 << DMA_SCR_CHSEL_SHIFT) +# define DMA_SCR_CHSEL(n) ((n) << DMA_SCR_CHSEL_SHIFT) + +#define DMA_SCR_ALLINTS (DMA_SCR_DMEIE|DMA_SCR_TEIE|DMA_SCR_HTIE|DMA_SCR_TCIE) + +/* DMA stream number of data register */ + +#define DMA_SNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_SNDTR_NDT_MASK (0xffff << DMA_SNDTR_NDT_SHIFT) + +/* DMA stream n FIFO control register */ + +#define DMA_SFCR_FTH_SHIFT (0) /* Bits 0-1: FIFO threshold selection */ +#define DMA_SFCR_FTH_MASK (3 << DMA_SFCR_FTH_SHIFT) +# define DMA_SFCR_FTH_QUARTER (0 << DMA_SFCR_FTH_SHIFT) /* 1/4 full FIFO */ +# define DMA_SFCR_FTH_HALF (1 << DMA_SFCR_FTH_SHIFT) /* 1/2 full FIFO */ +# define DMA_SFCR_FTH_3QUARTER (2 << DMA_SFCR_FTH_SHIFT) /* 3/4 full FIFO */ +# define DMA_SFCR_FTH_FULL (3 << DMA_SFCR_FTH_SHIFT) /* full FIFO */ +#define DMA_SFCR_DMDIS (1 << 2) /* Bit 2: Direct mode disable */ +#define DMA_SFCR_FS_SHIFT (3) /* Bits 3-5: FIFO status */ +#define DMA_SFCR_FS_MASK (7 << DMA_SFCR_FS_SHIFT) +# define DMA_SFCR_FS_QUARTER (0 << DMA_SFCR_FS_SHIFT) /* 0 < fifo_level < 1/4 */ +# define DMA_SFCR_FS_HALF (1 << DMA_SFCR_FS_SHIFT) /* 1/4 = fifo_level < 1/2 */ +# define DMA_SFCR_FS_3QUARTER (2 << DMA_SFCR_FS_SHIFT) /* 1/2 = fifo_level < 3/4 */ +# define DMA_SFCR_FS_ALMOSTFULL (3 << DMA_SFCR_FS_SHIFT) /* 3/4 = fifo_level < full */ +# define DMA_SFCR_FS_EMPTY (4 << DMA_SFCR_FS_SHIFT) /* FIFO is empty */ +# define DMA_SFCR_FS_FULL (5 << DMA_SFCR_FS_SHIFT) /* FIFO is full */ + /* Bit 6: Reserved */ +#define DMA_SFCR_FEIE (1 << 7) /* Bit 7: FIFO error interrupt enable */ + /* Bits 8-31: Reserved */ + +/* DMA Stream mapping. Each DMA stream has a mapping to several possible + * sources/sinks of data. The requests from peripherals assigned to a stream + * are simply OR'ed together before entering the DMA block. This means that only + * one request on a given stream can be enabled at once. + * + * Alternative stream selections are provided with a numeric suffix like _1, _2, etc. + * The DMA driver, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * SPI3_RX connects via DMA STREAM0, then following should be application-specific + * mapping should be used: + * + * #define DMAMAP_SPI3_RX DMAMAP_SPI3_RX_1 + */ + +#define STM32_DMA_MAP(d,s,c) ((d) << 6 | (s) << 3 | (c)) +#define STM32_DMA_CONTROLLER(m) (((m) >> 6) & 1) +#define STM32_DMA_STREAM(m) (((m) >> 3) & 7) +#define STM32_DMA_CHANNEL(m) ((m) & 7) + +#define DMAMAP_SPI3_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_SPI3_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_SPI2_RX STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN0) +#define DMAMAP_SPI2_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_SPI3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN0) +#define DMAMAP_SPI3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN0) + +#define DMAMAP_I2C1_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN1) +#define DMAMAP_TIM7_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_TIM7_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN1) +#define DMAMAP_I2C1_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN1) +#define DMAMAP_I2C1_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN1) +#define DMAMAP_I2C1_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_TIM4_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_I2S2_EXT_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN2) +#define DMAMAP_TIM4_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN2) +#define DMAMAP_I2S2_EXT_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN2) +#define DMAMAP_I2S3_EXT_TX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_TIM4_UP STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_TIM4_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_I2S3_EXT_RX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN3) +#define DMAMAP_TIM2_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN3) +#define DMAMAP_TIM2_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_I2C3_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_I2S2_EXT_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN3) +#define DMAMAP_I2C3_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN3) +#define DMAMAP_TIM2_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN3) +#define DMAMAP_TIM2_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) + +#define DMAMAP_UART5_RX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN4) +#define DMAMAP_USART3_RX STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN4) +#define DMAMAP_UART4_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_USART3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_UART4_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN4) +#define DMAMAP_USART2_RX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_USART2_TX STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_UART5_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN4) + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_UART8_TX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN5) +# define DMAMAP_UART7_TX STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN5) +#endif +#define DMAMAP_TIM3_CH4 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_TIM3_UP STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_UART7_RX STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN5) +#endif +#define DMAMAP_TIM3_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_TRIG STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN5) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_UART8_RX STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN5) +#endif +#define DMAMAP_TIM3_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM5_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM5_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM6_UP STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_I2C2_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_I2C2_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_USART3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN7) +#define DMAMAP_DAC1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN7) +#define DMAMAP_DAC2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN7) +#define DMAMAP_I2C2_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN7) + +#define DMAMAP_ADC1_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_TIM8_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_ADC1_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_TIM1_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) + +#define DMAMAP_DCMI_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN1) +#define DMAMAP_ADC2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_ADC2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN1) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_SPI6_TX STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN1) +# define DMAMAP_SPI6_RX STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN1) +#endif +#define DMAMAP_DCMI_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_ADC3_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_ADC3_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN2) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_SPI5_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN2) +# define DMAMAP_SPI5_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN2) +#endif +#define DMAMAP_CRYP_OUT STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_CRYP_IN STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_HASH_IN STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_SPI1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN3) +#define DMAMAP_SPI1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_SPI1_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN3) +#define DMAMAP_SPI1_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN3) + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define DMAMAP_SPI4_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN4) +# define DMAMAP_SPI4_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN4) +#endif +#define DMAMAP_USART1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_SDIO_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_USART1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_SDIO_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_USART1_TX STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN4) + +#define DMAMAP_USART6_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN5) +#define DMAMAP_USART6_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN5) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define DMAMAP_SPI4_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN5) +# define DMAMAP_SPI4_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN5) +#endif +#define DMAMAP_USART6_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN5) +#define DMAMAP_USART6_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM1_TRIG_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM1_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM1_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM1_CH1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM1_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_TRIG_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_COM STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_UP STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN6) +#define DMAMAP_TIM1_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM8_UP STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_TIM8_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_TIM8_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_TIM8_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN7) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define DMAMAP_SPI5_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN7) +# define DMAMAP_SPI5_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN7) +#endif +#define DMAMAP_TIM8_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_TRIG STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_COM STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_DMA_H */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h b/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..7d4b33b666a97649fcc063d567313d04e24c6fc8 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_gpio.h @@ -0,0 +1,396 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_gpio.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_NGPIO_PORTS ((STM32_NGPIO + 15) >> 4) + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NGPIO_PORTS > 0 +# define STM32_GPIOA_MODER (STM32_GPIOA_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOA_AFRL (STM32_GPIOA_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOA_AFRH (STM32_GPIOA_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 1 +# define STM32_GPIOB_MODER (STM32_GPIOB_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOB_AFRL (STM32_GPIOB_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOB_AFRH (STM32_GPIOB_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 2 +# define STM32_GPIOC_MODER (STM32_GPIOC_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOC_AFRL (STM32_GPIOC_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOC_AFRH (STM32_GPIOC_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 3 +# define STM32_GPIOD_MODER (STM32_GPIOD_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOD_AFRL (STM32_GPIOD_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOD_AFRH (STM32_GPIOD_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 4 +# define STM32_GPIOE_MODER (STM32_GPIOE_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOE_AFRL (STM32_GPIOE_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOE_AFRH (STM32_GPIOE_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 5 +# define STM32_GPIOF_MODER (STM32_GPIOF_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOF_AFRL (STM32_GPIOF_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOF_AFRH (STM32_GPIOF_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 6 +# define STM32_GPIOG_MODER (STM32_GPIOG_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOG_OTYPER (STM32_GPIOG_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOG_OSPEED (STM32_GPIOG_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOG_PUPDR (STM32_GPIOG_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOG_IDR (STM32_GPIOG_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOG_ODR (STM32_GPIOG_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOG_BSRR (STM32_GPIOG_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOG_LCKR (STM32_GPIOG_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOG_AFRL (STM32_GPIOG_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOG_AFRH (STM32_GPIOG_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 7 +# define STM32_GPIOH_MODER (STM32_GPIOH_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOH_OTYPER (STM32_GPIOH_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOH_OSPEED (STM32_GPIOH_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOH_PUPDR (STM32_GPIOH_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOH_IDR (STM32_GPIOH_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOH_ODR (STM32_GPIOH_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOH_BSRR (STM32_GPIOH_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOH_LCKR (STM32_GPIOH_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOH_AFRL (STM32_GPIOH_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOH_AFRH (STM32_GPIOH_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 8 +# define STM32_GPIOI_MODER (STM32_GPIOI_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOI_OTYPER (STM32_GPIOI_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOI_OSPEED (STM32_GPIOI_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOI_PUPDR (STM32_GPIOI_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOI_IDR (STM32_GPIOI_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOI_ODR (STM32_GPIOI_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOI_BSRR (STM32_GPIOI_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOI_LCKR (STM32_GPIOI_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOI_AFRL (STM32_GPIOI_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOI_AFRH (STM32_GPIOI_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 9 +# define STM32_GPIOJ_MODER (STM32_GPIOJ_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOJ_OTYPER (STM32_GPIOJ_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOJ_OSPEED (STM32_GPIOJ_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOJ_PUPDR (STM32_GPIOJ_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOJ_IDR (STM32_GPIOJ_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOJ_ODR (STM32_GPIOJ_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOJ_BSRR (STM32_GPIOJ_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOJ_LCKR (STM32_GPIOJ_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOJ_AFRL (STM32_GPIOJ_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOJ_AFRH (STM32_GPIOJ_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 10 +# define STM32_GPIOK_MODER (STM32_GPIOK_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOK_OTYPER (STM32_GPIOK_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOK_OSPEED (STM32_GPIOK_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOK_PUPDR (STM32_GPIOK_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOK_IDR (STM32_GPIOK_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOK_ODR (STM32_GPIOK_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOK_BSRR (STM32_GPIOK_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOK_LCKR (STM32_GPIOK_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOK_AFRL (STM32_GPIOK_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOK_AFRH (STM32_GPIOK_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (2) /* 50 MHz Fast speed */ +#define GPIO_OSPEED_100MHz (3) /* 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_GPIO_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..8b493e916ca806a938348a84fc0f65a650dd1b01 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h @@ -0,0 +1,224 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_memorymap.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +# define STM32_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3&4 block */ +# define STM32_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32_FSMC_BANK4 0x90000000 /* 0x90000000-0x9fffffff: 256Mb PC CARD*/ +#define STM32_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: 512Mb FSMC register block */ + /* 0xc0000000-0xdfffffff: 512Mb (not used) */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) +#define STM32_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_FSMC_BANK1) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x0fffffff: Reserved */ +#define STM32_CCMRAM_BASE 0x10000000 /* 0x10000000-0x1000ffff: 64Kb CCM data RAM */ + /* 0x10010000-0x1ffeffff: Reserved */ +#define STM32_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32_OPTION_BASE 0x1fffc000 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32_SYSMEM_UID 0x1fff7a10 /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x1fff7a22 /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x0400 corresponds + * to 1024 Kbytes. + */ + +/* SRAM Base Addresses **************************************************************/ + + /* 0x20000000-0x2001bfff: 112Kb aliased by bit-banding */ + /* 0x2001c000-0x2001ffff: 16Kb aliased by bit-banding */ +#define STM32_SRAMBB_BASE 0x22000000 /* 0x22000000- : SRAM bit-band region */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x400023ff: APB1 */ + /* 0x40002400-0x400027ff: Reserved */ + /* 0x40002800-0x400077ff: APB1 */ + /* 0x40007800-0x4000ffff: Reserved */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x400023ff: APB2 */ + /* 0x40013400-0x400137ff: Reserved */ + /* 0x40013800-0x40013bff: SYSCFG */ +#define STM32_EXTI_BASE 0x40013c00 /* 0x40013c00-0x40013fff: EXTI */ + /* 0x40014000-0x40014bff: APB2 */ + /* 0x40014c00-0x4001ffff: Reserved */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x400223ff: APB1 */ + /* 0x40022400-0x40022fff: Reserved */ + /* 0x40023000-0x400233ff: CRC */ + /* 0x40023400-0x400237ff: Reserved */ + /* 0x40023800-0x40023bff: Reset and Clock control RCC */ + /* 0x40023c00-0x400293ff: AHB1 (?) */ + /* 0x40029400-0x4fffffff: Reserved (?) */ +#define STM32_AHB2_BASE 0x50000000 /* 0x50000000-0x5003ffff: AHB2 */ + /* 0x50040000-0x5004ffff: Reserved */ + /* 0x50050000-0x500503ff: AHB2 */ + /* 0x50050400-0x500607ff: Reserved */ + /* 0x50060800-0x50060bff: AHB2 */ + /* 0x50060c00-0x5fffffff: Reserved */ + +/* FSMC Base Addresses **************************************************************/ + +#define STM32_AHB3_BASE 0x60000000 /* 0x60000000-0xa0000fff: AHB3 */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff: TIM2 timer */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff: TIM3 timer */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff: TIM4 timer */ +#define STM32_TIM5_BASE 0x40000c00 /* 0x40000c00-0x40000fff: TIM5 timer */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff: TIM6 timer */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff: TIM7 timer */ +#define STM32_TIM12_BASE 0x40001800 /* 0x40001800-0x40001bff: TIM12 timer */ +#define STM32_TIM13_BASE 0x40001c00 /* 0x40001c00-0x40001fff: TIM13 timer */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000-0x400023ff: TIM14 timer */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff: RTC & BKP registers */ +#define STM32_BKP_BASE 0x40002850 +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff: Window watchdog (WWDG) */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff: Independent watchdog (IWDG) */ +#define STM32_I2S2EXT_BASE 0x40003400 /* 0x40003400-0x400037ff: I2S2ext */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff: SPI2/I2S2 */ +#define STM32_I2S2_BASE 0x40003800 +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff: SPI3/I2S3 */ +#define STM32_I2S3_BASE 0x40003c00 +#define STM32_I2S3EXT_BASE 0x40004000 /* 0x40003400-0x400043ff: I2S3ext */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff: USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff: USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff: UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff: UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff: I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005Bff: I2C2 */ +#define STM32_I2C3_BASE 0x40005c00 /* 0x40005c00-0x40005fff: I2C3 */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff: bxCAN1 */ +#define STM32_CAN2_BASE 0x40006800 /* 0x40006800-0x40006bff: bxCAN2 */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff: Power control PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400-0x400077ff: DAC */ +#define STM32_UART7_BASE 0x40007800 /* 0x40007800-0x40007bff: UART7 */ +#define STM32_UART8_BASE 0x40007c00 /* 0x40007c00-0x40007fff: UART8 */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_TIM1_BASE 0x40010000 /* 0x40010000-0x400103ff: TIM1 timer */ +#define STM32_TIM8_BASE 0x40010400 /* 0x40010400-0x400107ff: TIM8 timer */ +#define STM32_USART1_BASE 0x40011000 /* 0x40011000-0x400113ff: USART1 */ +#define STM32_USART6_BASE 0x40011400 /* 0x40011400-0x400117ff: USART6 */ +#define STM32_ADC_BASE 0x40012000 /* 0x40012000-0x400123ff: ADC1-3 */ +# define STM32_ADC1_BASE 0x40012000 /* ADC1 */ +# define STM32_ADC2_BASE 0x40012100 /* ADC2 */ +# define STM32_ADC3_BASE 0x40012200 /* ADC3 */ +# define STM32_ADCCMN_BASE 0x40012300 /* Common */ +#define STM32_SDIO_BASE 0x40012c00 /* 0x40012c00-0x40012fff: SDIO */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff: SPI1 */ +#define STM32_SPI4_BASE 0x40013400 /* 0x40013000-0x400137ff: SPI4 */ +#define STM32_SYSCFG_BASE 0x40013800 /* 0x40013800-0x40013bff: SYSCFG */ +#define STM32_EXTI_BASE 0x40013c00 /* 0x40013c00-0x40013fff: EXTI */ +#define STM32_TIM9_BASE 0x40014000 /* 0x40014000-0x400143ff: TIM9 timer */ +#define STM32_TIM10_BASE 0x40014400 /* 0x40014400-0x400147ff: TIM10 timer */ +#define STM32_TIM11_BASE 0x40014800 /* 0x40014800-0x40014bff: TIM11 timer */ +#define STM32_SPI5_BASE 0x40015000 /* 0x40015000-0x400153ff: SPI5 */ +#define STM32_SPI6_BASE 0x40015400 /* 0x40015400-0x400157ff: SPI6 */ +#define STM32_SAI1_BASE 0x40015800 /* 0x40015800-0x40015Bff: SAI1 */ +#define STM32_LTDC_BASE 0x40016800 /* 0x40016800-0x40016Bff: LTDC (LCD-TFT) */ + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32_GPIOA_BASE 0x40020000 /* 0x40020000-0x400203ff: GPIO Port A */ +#define STM32_GPIOB_BASE 0x40020400 /* 0x40020400-0x400207ff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x40020800 /* 0x40020800-0x40020bff: GPIO Port C */ +#define STM32_GPIOD_BASE 0X40020C00 /* 0x40020c00-0x40020fff: GPIO Port D */ +#define STM32_GPIOE_BASE 0x40021000 /* 0x40021000-0x400213ff: GPIO Port E */ +#define STM32_GPIOF_BASE 0x40021400 /* 0x40021400-0x400217ff: GPIO Port F */ +#define STM32_GPIOG_BASE 0x40021800 /* 0x40021800-0x40021bff: GPIO Port G */ +#define STM32_GPIOH_BASE 0x40021C00 /* 0x40021C00-0x40021fff: GPIO Port H */ +#define STM32_GPIOI_BASE 0x40022000 /* 0x40022000-0x400223ff: GPIO Port I */ +#define STM32_GPIOJ_BASE 0x40022400 /* 0x40022400-0x400227ff: GPIO Port J */ +#define STM32_GPIOK_BASE 0x40022800 /* 0x40022800-0x40022Bff: GPIO Port K */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ +#define STM32_RCC_BASE 0x40023800 /* 0x40023800-0x40023bff: Reset and Clock control RCC */ +#define STM32_FLASHIF_BASE 0x40023c00 /* 0x40023c00-0x40023fff: Flash memory interface */ +#define STM32_BKPSRAM_BASE 0x40024000 /* 0x40024000-0x40024fff: Backup SRAM (BKPSRAM) */ +#define STM32_DMA1_BASE 0x40026000 /* 0x40026000-0x400263ff: DMA1 */ +#define STM32_DMA2_BASE 0x40026400 /* 0x40026400-0x400267ff: DMA2 */ +#define STM32_ETHERNET_BASE 0x40028000 /* 0x40028000-0x400283ff: Ethernet MAC */ + /* 0x40028400-0x400287ff: Ethernet MAC */ + /* 0x40028800-0x40028bff: Ethernet MAC */ + /* 0x40028c00-0x40028fff: Ethernet MAC */ + /* 0x40029000-0x400293ff: Ethernet MAC */ +#define STM32_DMA2D_BASE 0x4002B000 /* 0x4002B000-0x4002BBFF: DMA2D */ +#define STM32_OTGHS_BASE 0x40040000 /* 0x40040000-0x4007ffff: USB OTG HS */ +#define STM32_PERIPHBB_BASE 0x42000000 /* Peripheral bit-band region */ + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32_OTGFS_BASE 0x50000000 /* 0x50000000-0x5003ffff: USB OTG FS */ +#define STM32_DCMI_BASE 0x50050000 /* 0x50050000-0x500503ff: DCMI */ +#define STM32_CRYP_BASE 0x50060000 /* 0x50060000-0x500603ff: CRYP */ +#define STM32_HASH_BASE 0x50060400 /* 0x50060400-0x500607ff: HASH */ +#define STM32_RNG_BASE 0x50060800 /* 0x50060800-0x50060bff: RNG */ + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..02664a0ba907b7f617fa69f7c09d48089d4d6137 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h @@ -0,0 +1,1169 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32F40xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects via PA11 on some board, then the following definitions should + * appear in the board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configure PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN8 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN14 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN15 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) + +/* CAN */ + +#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN1_RX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CAN1_TX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) + +#define GPIO_CAN2_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_CAN2_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_CAN2_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN2_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +/* DAC - "Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* Digital Camera Interface (DCMI) */ + +#define GPIO_DCMI_D0_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN9) +#define GPIO_DCMI_D0_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_DCMI_D0_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN9) +#define GPIO_DCMI_D1_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN10) +#define GPIO_DCMI_D1_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_DCMI_D1_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN10) +#define GPIO_DCMI_D2_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN8) +#define GPIO_DCMI_D2_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN0) +#define GPIO_DCMI_D2_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN11) +#define GPIO_DCMI_D3_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN9) +#define GPIO_DCMI_D3_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN1) +#define GPIO_DCMI_D3_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN12) +#define GPIO_DCMI_D4_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_DCMI_D4_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_DCMI_D4_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN14) +#define GPIO_DCMI_D5_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_DCMI_D5_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN4) +#define GPIO_DCMI_D6_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_DCMI_D6_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_DCMI_D6_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN6) +#define GPIO_DCMI_D7_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_DCMI_D7_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_DCMI_D7_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN7) +#define GPIO_DCMI_D8_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_DCMI_D8_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN1) +#define GPIO_DCMI_D9_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_DCMI_D9_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN2) +#define GPIO_DCMI_D10_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_DCMI_D10_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN3) +#define GPIO_DCMI_D11_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN2) +#define GPIO_DCMI_D11_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN15) +#define GPIO_DCMI_D13_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN15) +#define GPIO_DCMI_D13_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN0) +#define GPIO_DCMI_HSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DCMI_HSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN8) +#define GPIO_DCMI_PIXCLK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_DCMI_VSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN7) +#define GPIO_DCMI_VSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN5) + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_DCMI_D2_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN10) +# define GPIO_DCMI_D3_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN11) +# define GPIO_DCMI_D5_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN3) +# define GPIO_DCMI_D8_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN6) +# define GPIO_DCMI_D9_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN7) +# define GPIO_DCMI_D10_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6) +# define GPIO_DCMI_D11_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN10) +# define GPIO_DCMI_D12_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN11) +# define GPIO_DCMI_D12_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN6) +# define GPIO_DCMI_D13_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN7) +# define GPIO_DCMI_VSYNC_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN9) +#else +# define GPIO_DCMI_D12 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN11) +#endif + +/* Clocks outputs */ + +#define GPIO_MCO1 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO2 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) + +/* Ethernet MAC */ + +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_ETH_MDC (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN1) +# define GPIO_ETH_MDIO (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +# define GPIO_ETH_MII_COL_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +# define GPIO_ETH_MII_COL_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +# define GPIO_ETH_MII_CRS_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +# define GPIO_ETH_MII_CRS_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +# define GPIO_ETH_MII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +# define GPIO_ETH_MII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +# define GPIO_ETH_MII_RXD2_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +# define GPIO_ETH_MII_RXD2_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +# define GPIO_ETH_MII_RXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +# define GPIO_ETH_MII_RXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN7) +# define GPIO_ETH_MII_RX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +# define GPIO_ETH_MII_RX_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +# define GPIO_ETH_MII_RX_ER_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +# define GPIO_ETH_MII_RX_ER_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +# define GPIO_ETH_MII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +# define GPIO_ETH_MII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +# define GPIO_ETH_MII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +# define GPIO_ETH_MII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +# define GPIO_ETH_MII_TXD2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +# define GPIO_ETH_MII_TXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +# define GPIO_ETH_MII_TXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN2) +# define GPIO_ETH_MII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +# define GPIO_ETH_MII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +# define GPIO_ETH_MII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +# define GPIO_ETH_PPS_OUT_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +# define GPIO_ETH_PPS_OUT_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN8) +# define GPIO_ETH_RMII_CRS_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +# define GPIO_ETH_RMII_REF_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +# define GPIO_ETH_RMII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +# define GPIO_ETH_RMII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +# define GPIO_ETH_RMII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +# define GPIO_ETH_RMII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +# define GPIO_ETH_RMII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +# define GPIO_ETH_RMII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +# define GPIO_ETH_RMII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +# define GPIO_ETH_RMII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +# define GPIO_ETH_RMII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#endif + +/* Flexible Static Memory Controller (FSMC) */ + +#define GPIO_FSMC_A0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FSMC_A1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FSMC_A2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FSMC_A3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FSMC_A4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FSMC_A5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FSMC_A6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FSMC_A7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FSMC_A8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FSMC_A9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FSMC_A10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FSMC_A11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FSMC_A12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FSMC_A13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FSMC_A14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FSMC_A15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FSMC_A16 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FSMC_A17 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FSMC_A18 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FSMC_A19 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FSMC_A20 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FSMC_A21 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FSMC_A22 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FSMC_A23 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FSMC_A24 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FSMC_A25 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_FSMC_NBL1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FSMC_CLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FSMC_D0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FSMC_D1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FSMC_D2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FSMC_D3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FSMC_D4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FSMC_D5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FSMC_D6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FSMC_D7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FSMC_D8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FSMC_D9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FSMC_D10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FSMC_D11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FSMC_D12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FSMC_D13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FSMC_D14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FSMC_D15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_FSMC_NBL0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FSMC_NE1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FSMC_NE2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FSMC_NE3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FSMC_NE4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FSMC_NL (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FSMC_NOE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FSMC_NWAIT (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FSMC_NWE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_FSMC_INT3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FSMC_NCE3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) + +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define GPIO_FSMC_CD (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN9) +# define GPIO_FSMC_INT2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN6) +# define GPIO_FSMC_INTR (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN10) +# define GPIO_FSMC_NCE2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN7) +# define GPIO_FSMC_NCE4_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN10) +# define GPIO_FSMC_NCE4_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN11) +# define GPIO_FSMC_NIORD (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN6) +# define GPIO_FSMC_NIOWR (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN8) +# define GPIO_FSMC_NREG (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN7) +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_FSMC_SDCKE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN3) +# define GPIO_FSMC_SDCKE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN5) +# define GPIO_FSMC_SDNE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN2) +# define GPIO_FSMC_SDNE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN4) +# define GPIO_FSMC_SDNWE_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN7) +# define GPIO_FSMC_SDNWE_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN0) +# define GPIO_FSMC_SDNRAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN11) +# define GPIO_FSMC_SDCLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN8) +# define GPIO_FSMC_SDNCAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN15) +# define GPIO_FSMC_BA0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4) +# define GPIO_FSMC_BA1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5) +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_FSMC_D16 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN8) +# define GPIO_FSMC_D17 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN9) +# define GPIO_FSMC_D18 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN10) +# define GPIO_FSMC_D19 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN11) +# define GPIO_FSMC_D20 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN12) +# define GPIO_FSMC_D21 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN13) +# define GPIO_FSMC_D22 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN14) +# define GPIO_FSMC_D23 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN15) +# define GPIO_FSMC_D24 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN0) +# define GPIO_FSMC_D25 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN1) +# define GPIO_FSMC_D26 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN2) +# define GPIO_FSMC_D27 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN3) +# define GPIO_FSMC_D28 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN6) +# define GPIO_FSMC_D29 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN7) +# define GPIO_FSMC_D30 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN9) +# define GPIO_FSMC_D31 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN10) +# define GPIO_FSMC_NBL2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN4) +# define GPIO_FSMC_NBL3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN5) +# define GPIO_FSMC_SDCKE0_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN2) +# define GPIO_FSMC_SDCKE1_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_FSMC_SDCKE1_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN7) +# define GPIO_FSMC_SDNE0_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN3) +# define GPIO_FSMC_SDNE1_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN6) +# define GPIO_FSMC_SDNE1_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN6) +# define GPIO_FSMC_SDNWE_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN5) +#endif + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_FSMC_SDCKE1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN5) +# define GPIO_FSMC_SDNE1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN6) +#endif + +#if defined(CONFIG_STM32_STM32F469) +# define GPIO_FSMC_CLE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN11) +# define GPIO_FSMC_ALE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN12) +#endif + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN4) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN5) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C2_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_I2C2_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN3) +# define GPIO_I2C2_SDA_5 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN12) +#endif + +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN8) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_I2C3_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN4) +#endif + +/* I2S */ + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_I2S1_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +# define GPIO_I2S1_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN3) +# define GPIO_I2S1_MCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN6) +# define GPIO_I2S1_MCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN4) +# define GPIO_I2S1_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +# define GPIO_I2S1_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +# define GPIO_I2S1_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) +# define GPIO_I2S1_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#endif + +#define GPIO_I2S2_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2S2_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_CK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN1) +#define GPIO_I2S2_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_I2S2_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN3) +#define GPIO_I2S2_SD_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2S2_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2S2_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN0) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_I2S2_CK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN3) +# define GPIO_I2S2_SD_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN1) +#endif +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_I2S2_CK_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_I2S2_CK_6 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN7) +# define GPIO_I2S2_MCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN6) +# define GPIO_I2S2_MCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN6) +# define GPIO_I2S2_WS_7 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) +# define GPIO_I2S2_WS_8 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN1) +#else +# define GPIO_I2S2_MCK (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN6) +#endif + +#define GPIO_I2S2EXT_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2S2EXT_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN2) +#define GPIO_I2S2EXT_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN2) + +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S3_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_I2S3_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN6) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_I2S3_SD_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN0) +# define GPIO_I2S3_SD_5 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN2) +# define GPIO_I2S3_SD_6 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN1) +# define GPIO_I2S3_SD_7 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN1) +# define GPIO_I2S3_SD_8 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN0) +# define GPIO_I2S3_SD_9 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +# define GPIO_I2S3_SD_10 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN6) +#else +# define GPIO_I2S3EXT_SD_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) +#endif + +#define GPIO_I2S3EXT_SD_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN11) + +#define GPIO_I2S_CKIN (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) + +/* JTAG */ + +#define GPIO_JTCK_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_JTMS_SWDIO (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_JTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) + +/* OTG FS/HS (VBUS PA9 is not an alternate configuration) */ + +#define GPIO_OTGFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTGFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTGFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTGFS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_OTGHSFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_OTGHSFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_OTGHSFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_OTGHS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_OTGHS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_OTGHS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTGHS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_OTGHS_ULPI_CK (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_D0 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_D1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_OTGHS_ULPI_D2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OTGHS_ULPI_D3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OTGHS_ULPI_D5 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTGHS_ULPI_D6 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN13) +#define GPIO_OTGHS_ULPI_D7 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_DIR_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN2) +#define GPIO_OTGHS_ULPI_DIR_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN11) +#define GPIO_OTGHS_ULPI_NXT_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_NXT_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN4) +#define GPIO_OTGHS_ULPI_STP (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN0) + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_OTGHS_ULPI_D4_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +# define GPIO_OTGHS_ULPI_D4_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN2) +#else +# define GPIO_OTGHS_ULPI_D4 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#endif + +/* RTC */ + +#define GPIO_RTC_50HZ (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN15) + +/* SDIO */ + +#define GPIO_SDIO_CMD (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDIO_D0 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDIO_D3 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDIO_D4 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDIO_D5 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDIO_D6 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDIO_D7 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SDIO_CK_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +# define GPIO_SDIO_CK_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN2) +# define GPIO_SDIO_D1_1 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +# define GPIO_SDIO_D1_2 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +# define GPIO_SDIO_D2_1 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +# define GPIO_SDIO_D2_2 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#else +# define GPIO_SDIO_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +# define GPIO_SDIO_D1 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +# define GPIO_SDIO_D2 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#endif + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN2) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN3) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN0) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN1) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN3) +#endif +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_SPI2_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN1) +# define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SPI2_NSS_4 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +# define GPIO_SPI2_NSS_5 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN1) +# define GPIO_SPI2_SCK_6 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) +#endif + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SPI3_MOSI_4 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN0) +# define GPIO_SPI3_MOSI_5 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN2) +# define GPIO_SPI3_MOSI_6 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN1) +# define GPIO_SPI3_MOSI_7 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN0) +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_SPI4_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN5) +# define GPIO_SPI4_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN13) +# define GPIO_SPI4_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN6) +# define GPIO_SPI4_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN14) +# define GPIO_SPI4_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN4) +# define GPIO_SPI4_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) +# define GPIO_SPI4_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN2) +# define GPIO_SPI4_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN12) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SPI4_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN0) +#endif + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_SPI5_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN8) +# define GPIO_SPI5_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN7) +# define GPIO_SPI5_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +# define GPIO_SPI5_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN11) +# define GPIO_SPI5_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +# define GPIO_SPI5_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN5) +# define GPIO_SPI5_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN7) +# define GPIO_SPI5_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN6) + +# define GPIO_SPI6_MISO (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN12) +# define GPIO_SPI6_MOSI (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN14) +# define GPIO_SPI6_NSS (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN8) +# define GPIO_SPI6_SCK (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN13) +#endif + +/* Timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) + +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13) +#define GPIO_TIM8_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH2N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN14) +#define GPIO_TIM8_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15) +#define GPIO_TIM8_CH3IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH4IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3) + +#define GPIO_TIM9_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM9_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) + +#define GPIO_TIM10_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM10_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) + +#define GPIO_TIM11_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM11_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_TIM12_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6) +#define GPIO_TIM12_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_TIM12_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM12_CH2IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9) +#define GPIO_TIM12_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM12_CH2OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) + +#define GPIO_TIM13_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM13_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) + +#define GPIO_TIM14_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM14_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_TIM2_CH1IN_4 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM2_CH1OUT_4 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +# define GPIO_TIM2_CH2IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM2_CH2OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +# define GPIO_TIM2_CH4IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN2) +# define GPIO_TIM2_CH4OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN2) +# define GPIO_TIM2_ETR_4 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#endif + +/* Trace */ + +#define GPIO_TRACECLK (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACESWO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) + +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_TRACED0_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +# define GPIO_TRACED1_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#else +# define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +# define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#endif + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_TRACED0_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TRACED1_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN3) +#endif + +#if defined(CONFIG_STM32_STM32F469) +# define GPIO_TRACED0_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN1) +# define GPIO_TRACED0_4 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN13) +# define GPIO_TRACED1_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN8) +# define GPIO_TRACED1_4 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN14) +# define GPIO_TRACED2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +# define GPIO_TRACED2_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN2) +# define GPIO_TRACED3_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +# define GPIO_TRACED3_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN12) +#else +# define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +# define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +#endif + +/* UARTs/USARTs */ + +#define GPIO_USART1_CK (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN9) +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#endif +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_UART4_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN0) +# define GPIO_UART4_RTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#endif +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_UART5_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN9) +# define GPIO_UART5_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#endif +#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_USART6_CK_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN8) +#define GPIO_USART6_CK_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN7) +#define GPIO_USART6_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART6_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN15) +#define GPIO_USART6_RTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN12) +#define GPIO_USART6_RTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN8) +#define GPIO_USART6_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_USART6_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART6_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_USART6_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_UART7_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN7) +# define GPIO_UART7_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +# define GPIO_UART7_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN8) +# define GPIO_UART7_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) + +# define GPIO_UART8_RX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN0) +# define GPIO_UART8_TX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN1) +#endif + +/* LCD-TFT Display Controller (LTDC) */ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define GPIO_LTDC_R0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +# define GPIO_LTDC_R0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN15) +# define GPIO_LTDC_R1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +# define GPIO_LTDC_R1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN0) +# define GPIO_LTDC_R2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +# define GPIO_LTDC_R2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN8) +# define GPIO_LTDC_R2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN1) +# define GPIO_LTDC_R3_1 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +# define GPIO_LTDC_R3_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +# define GPIO_LTDC_R3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN2) +# define GPIO_LTDC_R4_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +# define GPIO_LTDC_R4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +# define GPIO_LTDC_R4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN3) +# define GPIO_LTDC_R5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +# define GPIO_LTDC_R5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +# define GPIO_LTDC_R5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN4) +# define GPIO_LTDC_R6_1 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +# define GPIO_LTDC_R6_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +# define GPIO_LTDC_R6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN5) +# define GPIO_LTDC_R6_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +# define GPIO_LTDC_R7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +# define GPIO_LTDC_R7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN15) +# define GPIO_LTDC_R7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN6) + +# define GPIO_LTDC_G0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +# define GPIO_LTDC_G0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN7) +# define GPIO_LTDC_G1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) +# define GPIO_LTDC_G1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN8) +# define GPIO_LTDC_G2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +# define GPIO_LTDC_G2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) +# define GPIO_LTDC_G2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN9) +# define GPIO_LTDC_G3_1 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +# define GPIO_LTDC_G3_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN14) +# define GPIO_LTDC_G3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN10) +# define GPIO_LTDC_G3_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +# define GPIO_LTDC_G4_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +# define GPIO_LTDC_G4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN15) +# define GPIO_LTDC_G4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN11) +# define GPIO_LTDC_G5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +# define GPIO_LTDC_G5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) +# define GPIO_LTDC_G5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN0) +# define GPIO_LTDC_G6_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +# define GPIO_LTDC_G6_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN1) +# define GPIO_LTDC_G6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN1) +# define GPIO_LTDC_G7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN3) +# define GPIO_LTDC_G7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +# define GPIO_LTDC_G7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN2) + +# define GPIO_LTDC_B0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN4) +# define GPIO_LTDC_B0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN12) +# define GPIO_LTDC_B1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +# define GPIO_LTDC_B1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN13) +# define GPIO_LTDC_B2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +# define GPIO_LTDC_B2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +# define GPIO_LTDC_B2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN14) +# define GPIO_LTDC_B3_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +# define GPIO_LTDC_B3_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) +# define GPIO_LTDC_B3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN15) +# define GPIO_LTDC_B4_1 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +# define GPIO_LTDC_B4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN12) +# define GPIO_LTDC_B4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN4) +# define GPIO_LTDC_B4_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN3) +# define GPIO_LTDC_B5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +# define GPIO_LTDC_B5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +# define GPIO_LTDC_B5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN4) +# define GPIO_LTDC_B6_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +# define GPIO_LTDC_B6_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +# define GPIO_LTDC_B6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN5) +# define GPIO_LTDC_B7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +# define GPIO_LTDC_B7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +# define GPIO_LTDC_B7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN6) + +# define GPIO_LTDC_VSYNC_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) +# define GPIO_LTDC_VSYNC_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +# define GPIO_LTDC_VSYNC_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN13) +# define GPIO_LTDC_HSYNC_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +# define GPIO_LTDC_HSYNC_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +# define GPIO_LTDC_HSYNC_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN12) +# define GPIO_LTDC_DE_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN10) +# define GPIO_LTDC_DE_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +# define GPIO_LTDC_DE_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN7) +# define GPIO_LTDC_CLK_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN7) +# define GPIO_LTDC_CLK_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +# define GPIO_LTDC_CLK_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN14) +#endif + +/* Quad SPI */ + +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_QUADSPI_BK1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN8) +# define GPIO_QUADSPI_BK1_IO0_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN9) +# define GPIO_QUADSPI_BK1_IO0_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN11) +# define GPIO_QUADSPI_BK1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN9) +# define GPIO_QUADSPI_BK1_IO1_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN10) +# define GPIO_QUADSPI_BK1_IO1_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN12) +# define GPIO_QUADSPI_BK1_IO2_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN2) +# define GPIO_QUADSPI_BK1_IO2_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN7) +# define GPIO_QUADSPI_BK1_IO3_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN1) +# define GPIO_QUADSPI_BK1_IO3_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN13) +# define GPIO_QUADSPI_BK1_IO3_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN6) +# define GPIO_QUADSPI_BK1_NCS_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN6) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_QUADSPI_BK1_NCS_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN6) +#elif defined(CONFIG_STM32_STM32F469) +# define GPIO_QUADSPI_BK1_NCS_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#endif + +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_QUADSPI_BK2_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN7) +# define GPIO_QUADSPI_BK2_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN8) +# define GPIO_QUADSPI_BK2_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN9) +# define GPIO_QUADSPI_BK2_IO2_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN9) +# define GPIO_QUADSPI_BK2_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10) +# define GPIO_QUADSPI_BK2_IO3_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN14) +# define GPIO_QUADSPI_BK2_NCS (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN11) +#endif +#if defined(CONFIG_STM32_STM32F469) +# define GPIO_QUADSPI_BK2_IO0_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTH|GPIO_PIN2) +# define GPIO_QUADSPI_BK2_IO1_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTH|GPIO_PIN3) +#endif + +/* SPDIFRX */ + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SPDIFRX_IN0_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN11) +# define GPIO_SPDIFRX_IN0_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN7) +# define GPIO_SPDIFRX_IN0_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN7) +# define GPIO_SPDIFRX_IN1_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN12) +# define GPIO_SPDIFRX_IN1_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN8) +# define GPIO_SPDIFRX_IN1_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN7) +# define GPIO_SPDIFRX_IN2_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN8) +# define GPIO_SPDIFRX_IN2_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN4) +# define GPIO_SPDIFRX_IN3_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN9) +# define GPIO_SPDIFRX_IN3_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN5) +#endif + +/* Serial Audio Interface */ + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SAI1_FS_A_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN4) +# define GPIO_SAI1_FS_A_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN3) +# define GPIO_SAI1_FS_B_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN9) +# define GPIO_SAI1_FS_B_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN9) +# define GPIO_SAI1_MCLK_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN2) +# define GPIO_SAI1_MCLK_B_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN7) +# define GPIO_SAI1_MCLK_B_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN0) +# define GPIO_SAI1_SCK_A_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN5) +# define GPIO_SAI1_SCK_A_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN10) +# define GPIO_SAI1_SCK_B_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN8) +# define GPIO_SAI1_SCK_B_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN12) +# define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN2) +# define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN9) +#elif defined(CONFIG_STM32_STM32F469) +# define GPIO_SAI1_FS_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN4) +# define GPIO_SAI1_FS_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN9) +# define GPIO_SAI1_MCLK_A_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN2) +# define GPIO_SAI1_MCLK_A_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN7) +# define GPIO_SAI1_MCLK_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN7) +# define GPIO_SAI1_SCK_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN5) +# define GPIO_SAI1_SCK_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN8) +#endif + +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN1) +# define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN6) +# define GPIO_SAI1_SD_A_4 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN6) +# define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN3) +# define GPIO_SAI1_SD_B_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN6) +#endif + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_SAI2_FS_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN12) +# define GPIO_SAI2_FS_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13) +# define GPIO_SAI2_FS_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN9) +# define GPIO_SAI2_FS_B_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +# define GPIO_SAI2_MCLK_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN0) +# define GPIO_SAI2_MCLK_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN1) +# define GPIO_SAI2_MCLK_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14) +# define GPIO_SAI2_SCK_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN13) +# define GPIO_SAI2_SCK_A_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN14) +# define GPIO_SAI2_SCK_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12) +# define GPIO_SAI2_SCK_B_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN2) +# define GPIO_SAI2_SD_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN11) +# define GPIO_SAI2_SD_A_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +# define GPIO_SAI2_SD_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN10) +# define GPIO_SAI2_SD_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11) +# define GPIO_SAI2_SD_B_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN11) +#endif + +/* HDMI-CEC Controller */ + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_HDMICEC_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN6) +# define GPIO_HDMICEC_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN15) +#endif + +/* FMPI2C */ + +#if defined(CONFIG_STM32_STM32F446) +# define GPIO_FMPI2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN6) +# define GPIO_FMPI2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) +# define GPIO_FMPI2C1_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN14) +# define GPIO_FMPI2C1_SCL_4 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN14) + +# define GPIO_FMPI2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN7) +# define GPIO_FMPI2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +# define GPIO_FMPI2C1_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN15) +# define GPIO_FMPI2C1_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15) + +# define GPIO_FMPI2C1_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11) +# define GPIO_FMPI2C1_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..a81f798c18bd50499b94098e11f186f62e5410c2 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_rcc.h @@ -0,0 +1,891 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f40xxx_rcc.h + * + * Copyright (C) 2009, 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_RCC_H + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_PLLCFG_OFFSET 0x0004 /* PLL configuration register */ +#define STM32_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x000c /* Clock interrupt register */ +#define STM32_RCC_AHB1RSTR_OFFSET 0x0010 /* AHB1 peripheral reset register */ +#define STM32_RCC_AHB2RSTR_OFFSET 0x0014 /* AHB2 peripheral reset register */ +#define STM32_RCC_AHB3RSTR_OFFSET 0x0018 /* AHB3 peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0020 /* APB1 Peripheral reset register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x0024 /* APB2 Peripheral reset register */ +#define STM32_RCC_AHB1ENR_OFFSET 0x0030 /* AHB1 Peripheral Clock enable register */ +#define STM32_RCC_AHB2ENR_OFFSET 0x0034 /* AHB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB3ENR_OFFSET 0x0038 /* AHB3 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x0040 /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0044 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB1LPENR_OFFSET 0x0050 /* RCC AHB1 low power mode peripheral clock enable register */ +#define STM32_RCC_AHB2LPENR_OFFSET 0x0054 /* RCC AHB2 low power mode peripheral clock enable register */ +#define STM32_RCC_AHB3LPENR_OFFSET 0x0058 /* RCC AHB3 low power mode peripheral clock enable register */ +#define STM32_RCC_APB1LPENR_OFFSET 0x0060 /* RCC APB1 low power mode peripheral clock enable register */ +#define STM32_RCC_APB2LPENR_OFFSET 0x0064 /* RCC APB2 low power mode peripheral clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0070 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0074 /* Control/status register */ +#define STM32_RCC_SSCGR_OFFSET 0x0080 /* Spread spectrum clock generation register */ +#define STM32_RCC_PLLI2SCFGR_OFFSET 0x0084 /* PLLI2S configuration register */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define STM32_RCC_PLLSAICFGR_OFFSET 0x0088 /* PLLSAI configuration register */ +# define STM32_RCC_DCKCFGR_OFFSET 0x008c /* Dedicated clocks configuration register */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define STM32_RCC_CKGATENR_OFFSET 0x0090 /* Clock gating for the specified IPs */ +# define STM32_RCC_DCKCFGR2_OFFSET 0x0094 /* Dedicated clocks configuration register */ +#endif + +/* Register Addresses *******************************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_PLLCFG (STM32_RCC_BASE+STM32_RCC_PLLCFG_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_AHB1RSTR (STM32_RCC_BASE+STM32_RCC_AHB1RSTR_OFFSET) +#define STM32_RCC_AHB2RSTR (STM32_RCC_BASE+STM32_RCC_AHB2RSTR_OFFSET) +#define STM32_RCC_AHB3RSTR (STM32_RCC_BASE+STM32_RCC_AHB3RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_AHB1ENR (STM32_RCC_BASE+STM32_RCC_AHB1ENR_OFFSET) +#define STM32_RCC_AHB2ENR (STM32_RCC_BASE+STM32_RCC_AHB2ENR_OFFSET) +#define STM32_RCC_AHB3ENR (STM32_RCC_BASE+STM32_RCC_AHB3ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_AHB1LPENR (STM32_RCC_BASE+STM32_RCC_AHB1LPENR_OFFSET) +#define STM32_RCC_AHB2LPENR (STM32_RCC_BASE+STM32_RCC_AHB2LPENR) +#define STM32_RCC_AHB3LPENR (STM32_RCC_BASE+STM32_RCC_AHB3LPENR_OFFSET) +#define STM32_RCC_APB1LPENR (STM32_RCC_BASE+STM32_RCC_APB1LPENR_OFFSET) +#define STM32_RCC_APB2LPENR (STM32_RCC_BASE+STM32_RCC_APB2LPENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#define STM32_RCC_SSCGR (STM32_RCC_BASE+STM32_RCC_SSCGR_OFFSET) +#define STM32_RCC_PLLI2SCFGR (STM32_RCC_BASE+STM32_RCC_PLLI2SCFGR_OFFSET) +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +#define STM32_RCC_PLLSAICFGR (STM32_RCC_BASE+STM32_RCC_PLLSAICFGR_OFFSET) +#define STM32_RCC_DCKCFGR (STM32_RCC_BASE+STM32_RCC_DCKCFGR_OFFSET) +#endif +#if defined(CONFIG_STM32_STM32F446) +# define STM32_RCC_CKGATENR (STM32_RCC_BASE+STM32_RCC_CKGATENR_OFFSET) +# define STM32_RCC_DCKCFGR2 (STM32_RCC_BASE+STM32_RCC_DCKCFGR2_OFFSET) +#endif + +/* Register Bitfield Definitions ********************************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#define RCC_CR_PLLI2SON (1 << 26) /* Bit 26: PLLI2S enable */ +#define RCC_CR_PLLI2SRDY (1 << 27) /* Bit 27: PLLI2S clock ready flag */ +#define RCC_CR_PLLSAION (1 << 28) /* Bit 28: PLLSAI enable */ +#define RCC_CR_PLLSAIRDY (1 << 29) /* Bit 29: PLLSAI clock ready flag */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLM_SHIFT (0) /* Bits 0-5: Main PLL (PLL) and audio PLL (PLLI2S) + * input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x3f << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n) << RCC_PLLCFG_PLLM_SHIFT) /* n = 2..63 */ +#define RCC_PLLCFG_PLLN_SHIFT (6) /* Bits 6-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x1ff << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 2..432 */ +#define RCC_PLLCFG_PLLP_SHIFT (16) /* Bits 16-17: Main PLL (PLL) main system clock divider */ +#define RCC_PLLCFG_PLLP_MASK (3 << RCC_PLLCFG_PLLP_SHIFT) +# define RCC_PLLCFG_PLLP(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLP_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLP_2 (0 << RCC_PLLCFG_PLLP_SHIFT) /* 00: PLLP = 2 */ +# define RCC_PLLCFG_PLLP_4 (1 << RCC_PLLCFG_PLLP_SHIFT) /* 01: PLLP = 4 */ +# define RCC_PLLCFG_PLLP_6 (2 << RCC_PLLCFG_PLLP_SHIFT) /* 10: PLLP = 6 */ +# define RCC_PLLCFG_PLLP_8 (3 << RCC_PLLCFG_PLLP_SHIFT) /* 11: PLLP = 8 */ +#define RCC_PLLCFG_PLLSRC (1 << 22) /* Bit 22: Main PLL(PLL) and audio PLL (PLLI2S) + * entry clock source */ +# define RCC_PLLCFG_PLLSRC_HSI (0) +# define RCC_PLLCFG_PLLSRC_HSE RCC_PLLCFG_PLLSRC +#define RCC_PLLCFG_PLLQ_SHIFT (24) /* Bits 24-27: Main PLL (PLL) divider + * (USB OTG FS, SDIO and RNG clocks) */ +#define RCC_PLLCFG_PLLQ_MASK (15 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((n) << RCC_PLLCFG_PLLQ_SHIFT) /* n=2..15 */ + +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_PLLCFG_PLLR_SHIFT (28) /* Bits 28-30: Main PLLR (PLLR) divider + * (I2Ss, SAIs, SYSTEM and SPDIF-Rx clocks) */ +# define RCC_PLLCFG_PLLR_MASK (7 << RCC_PLLCFG_PLLR_SHIFT) +# define RCC_PLLCFG_PLLR(n) ((n) << RCC_PLLCFG_PLLR_SHIFT) /* n=1..7 */ +#endif + +#define RCC_PLLCFG_RESET (0x24003010) /* PLLCFG reset value */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (10) /* Bits 10-12: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (13) /* Bits 13-15: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_RTCPRE_SHIFT (16) /* Bits 16-20: APB High speed prescaler (APB2) */ +#define RCC_CFGR_RTCPRE_MASK (31 << RCC_CFGR_RTCPRE_SHIFT) +# define RCC_CFGR_RTCPRE(n) ((n) << RCC_CFGR_RTCPRE_SHIFT) /* HSE/n, n=1..31 */ +#define RCC_CFGR_MCO1_SHIFT (21) /* Bits 21-22: Microcontroller Clock Output */ +#define RCC_CFGR_MCO1_MASK (3 << RCC_CFGR_MCO1_SHIFT) +# define RCC_CFGR_MCO1_HSI (0 << RCC_CFGR_MCO1_SHIFT) /* 00: HSI clock selected */ +# define RCC_CFGR_MCO1_LSE (1 << RCC_CFGR_MCO1_SHIFT) /* 01: LSE oscillator selected */ +# define RCC_CFGR_MCO1_HSE (2 << RCC_CFGR_MCO1_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO1_PLL (3 << RCC_CFGR_MCO1_SHIFT) /* 11: PLL clock selected */ +#define RCC_CFGR_I2SSRC (1 << 23) /* Bit 23: I2S clock selection */ +#define RCC_CFGR_MCO1PRE_SHIFT (24) /* Bits 24-26: MCO1 prescaler */ +#define RCC_CFGR_MCO1PRE_MASK (7 << RCC_CFGR_MCO1PRE_SHIFT) +# define RCC_CFGR_MCO1PRE_NONE (0 << RCC_CFGR_MCO1PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO1PRE_DIV2 (4 << RCC_CFGR_MCO1PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO1PRE_DIV3 (5 << RCC_CFGR_MCO1PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO1PRE_DIV4 (6 << RCC_CFGR_MCO1PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO1PRE_DIV5 (7 << RCC_CFGR_MCO1PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2PRE_SHIFT (27) /* Bits 27-29: MCO2 prescaler */ +#define RCC_CFGR_MCO2PRE_MASK (7 << RCC_CFGR_MCO2PRE_SHIFT) +# define RCC_CFGR_MCO2PRE_NONE (0 << RCC_CFGR_MCO2PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO2PRE_DIV2 (4 << RCC_CFGR_MCO2PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO2PRE_DIV3 (5 << RCC_CFGR_MCO2PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO2PRE_DIV4 (6 << RCC_CFGR_MCO2PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO2PRE_DIV5 (7 << RCC_CFGR_MCO2PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2_SHIFT (30) /* Bits 30-31: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_MASK (3 << RCC_CFGR_MCO2_SHIFT) +# define RCC_CFGR_MCO2_SYSCLK (0 << RCC_CFGR_MCO2_SHIFT) /* 00: System clock (SYSCLK) selected */ +# define RCC_CFGR_MCO2_PLLI2S (1 << RCC_CFGR_MCO2_SHIFT) /* 01: PLLI2S clock selected */ +# define RCC_CFGR_MCO2_HSE (2 << RCC_CFGR_MCO2_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO2_PLL (3 << RCC_CFGR_MCO2_SHIFT) /* 11: PLL clock selected */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_PLLI2SRDYF (1 << 5) /* Bit 5: PLLI2S Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_PLLI2SRDYIE (1 << 13) /* Bit 13: PLLI2S Ready Interrupt enable */ +#define RCC_CIR_PLLSAIRDYIE (1 << 14) /* Bit 14: PLLSAI Ready Interrupt enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_PLLI2SRDYC (1 << 21) /* Bit 21: PLLI2S Ready Interrupt clear */ +#define RCC_CIR_PLLSAIRDYC (1 << 22) /* Bit 22: PLLSAI Ready Interrupt clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB1RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB1RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB1RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB1RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB1RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB1RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB1RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1RSTR_GPIOIRST (1 << 8) /* Bit 8: IO port I reset */ +#endif +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1RSTR_GPIOJRST (1 << 9) /* Bit 9: IO port J reset */ +# define RCC_AHB1RSTR_GPIOKRST (1 << 10) /* Bit 10: IO port K reset */ +#endif +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12 CRC reset */ +#define RCC_AHB1RSTR_DMA1RST (1 << 21) /* Bit 21: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 22) /* Bit 22: DMA2 reset */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1RSTR_DMA2DRST (1 << 23) /* Bit 23: DMA2D reset */ +# define RCC_AHB1RSTR_ETHMACRST (1 << 25) /* Bit 25: Ethernet MAC reset */ +#endif +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) /* Bit 29: USB OTG HS module reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_DCMIRST (1 << 0) /* Bit 0: Camera interface reset */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB2RSTR_CRYPRST (1 << 4) /* Bit 4: Cryptographic module reset */ +# define RCC_AHB2RSTR_HASHRST (1 << 5) /* Bit 5: Hash module reset */ +# define RCC_AHB2RSTR_RNGRST (1 << 6) /* Bit 6: Random number generator module reset */ +#endif +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) /* Bit 7: USB OTG FS module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_AHB3RSTR_QSPIRST (1 << 1) /* Bit 1: QUADSPI memory controller module reset */ +#endif + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR_TIM12RST (1 << 6) /* Bit 6: TIM12 reset */ +#define RCC_APB1RSTR_TIM13RST (1 << 7) /* Bit 7: TIM13 reset */ +#define RCC_APB1RSTR_TIM14RST (1 << 8) /* Bit 8: TIM14 reset */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: USART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: USART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR_CAN2RST (1 << 26) /* Bit 26: CAN2 reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC reset */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB1RSTR_UART7RST (1 << 30) /* Bit 30: USART 7 reset */ +# define RCC_APB1RSTR_UART8RST (1 << 31) /* Bit 31: USART 8 reset */ +#endif + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_TIM1RST (1 << 0) /* Bit 0: TIM1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 1) /* Bit 1: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 4) /* Bit 4: USART1 reset */ +#define RCC_APB2RSTR_USART6RST (1 << 5) /* Bit 5: USART6 reset */ +#define RCC_APB2RSTR_ADCRST (1 << 8) /* Bit 8: ADC interface reset (common to all ADCs) */ +#define RCC_APB2RSTR_SDIORST (1 << 11) /* Bit 11: SDIO reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2RSTR_SPI4RST (1 << 13) /* Bit 13: SPI4 reset */ +#endif +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) /* Bit 14: System configuration controller reset */ +#define RCC_APB2RSTR_TIM9RST (1 << 16) /* Bit 16: TIM9 reset */ +#define RCC_APB2RSTR_TIM10RST (1 << 17) /* Bit 17: TIM10 reset */ +#define RCC_APB2RSTR_TIM11RST (1 << 18) /* Bit 18: TIM11 reset */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB2RSTR_SPI5RST (1 << 20) /* Bit 20: SPI 5 reset */ +# define RCC_APB2RSTR_SPI6RST (1 << 21) /* Bit 21: SPI 6 reset */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2RSTR_SAI1RST (1 << 22) /* Bit 22: SAI 1 reset */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB2RSTR_SAI2RST (1 << 23) /* Bit 23: SAI 2 reset */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2RSTR_LTDCRST (1 << 26) /* Bit 26: LTDC reset */ +#endif +#if defined(CONFIG_STM32_STM32F469) +# define RCC_APB2RSTR_DSIRST (1 << 27) /* Bit 27: DSI reset */ +#endif + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_GPIOEN(n) (1 << (n)) +#define RCC_AHB1ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A clock enable */ +#define RCC_AHB1ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B clock enable */ +#define RCC_AHB1ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C clock enable */ +#define RCC_AHB1ENR_GPIODEN (1 << 3) /* Bit 3: IO port D clock enable */ +#define RCC_AHB1ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E clock enable */ +#define RCC_AHB1ENR_GPIOFEN (1 << 5) /* Bit 5: IO port F clock enable */ +#define RCC_AHB1ENR_GPIOGEN (1 << 6) /* Bit 6: IO port G clock enable */ +#define RCC_AHB1ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H clock enable */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1ENR_GPIOIEN (1 << 8) /* Bit 8: IO port I clock enable */ +#endif +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1ENR_GPIOJEN (1 << 9) /* Bit 9: IO port J clock enable */ +# define RCC_AHB1ENR_GPIOKEN (1 << 10) /* Bit 10: IO port K clock enable */ +#endif +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC clock enable */ +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1ENR_CCMDATARAMEN (1 << 20) /* Bit 20: CCM data RAM clock enable */ +#endif +#define RCC_AHB1ENR_DMA1EN (1 << 21) /* Bit 21: DMA1 clock enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 22) /* Bit 22: DMA2 clock enable */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1ENR_DMA2DEN (1 << 23) /* Bit 23: DMA2D clock enable */ +# define RCC_AHB1ENR_ETHMACEN (1 << 25) /* Bit 25: Ethernet MAC clock enable */ +# define RCC_AHB1ENR_ETHMACTXEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable */ +# define RCC_AHB1ENR_ETHMACRXEN (1 << 27) /* Bit 27: Ethernet Reception clock enable */ +# define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable */ +#endif +#define RCC_AHB1ENR_OTGHSEN (1 << 29) /* Bit 29: USB OTG HS clock enable */ +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable */ + +/* AHB2 Peripheral Clock enable register */ + +#define RCC_AHB2ENR_DCMIEN (1 << 0) /* Bit 0: Camera interface enable */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB2ENR_CRYPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable */ +# define RCC_AHB2ENR_HASHEN (1 << 5) /* Bit 5: Hash modules clock enable */ +# define RCC_AHB2ENR_RNGEN (1 << 6) /* Bit 6: Random number generator clock enable */ +#endif +#define RCC_AHB2ENR_OTGFSEN (1 << 7) /* Bit 7: USB OTG FS clock enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module clock enable */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_AHB3ENR_QSPIEN (1 << 1) /* Bit 1: QUADSPI memory controller module clock enable */ +#endif + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: TIM2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: TIM3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: TIM4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 3: TIM5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: TIM6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: TIM7 clock enable */ +#define RCC_APB1ENR_TIM12EN (1 << 6) /* Bit 6: TIM12 clock enable */ +#define RCC_APB1ENR_TIM13EN (1 << 7) /* Bit 7: TIM13 clock enable */ +#define RCC_APB1ENR_TIM14EN (1 << 8) /* Bit 8: TIM14 clock enable */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI3 clock enable */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1ENR_SPDIFRX (1 << 16) /* Bit 16: SPDIF-Rx clock enable */ +#endif +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C2 clock enable */ +#define RCC_APB1ENR_I2C3EN (1 << 23) /* Bit 23: I2C3 clock enable */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1ENR_FMPI2C1EN (1 << 24) /* Bit 24: FMPI2C1 clock enable */ +#endif +#define RCC_APB1ENR_CAN1EN (1 << 25) /* Bit 25: CAN 1 clock enable */ +#define RCC_APB1ENR_CAN2EN (1 << 26) /* Bit 26: CAN 2 clock enable */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1ENR_CECEN (1 << 27) /* Bit 27: CEC clock enable */ +#endif +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB1ENR_UART7EN (1 << 30) /* Bit 30: UART7 clock enable */ +# define RCC_APB1ENR_UART8EN (1 << 31) /* Bit 31: UART8 clock enable */ +#endif + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_TIM1EN (1 << 0) /* Bit 0: TIM1 clock enable */ +#define RCC_APB2ENR_TIM8EN (1 << 1) /* Bit 1: TIM8 clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 4) /* Bit 4: USART1 clock enable */ +#define RCC_APB2ENR_USART6EN (1 << 5) /* Bit 5: USART6 clock enable */ +#define RCC_APB2ENR_ADC1EN (1 << 8) /* Bit 8: ADC1 clock enable */ +#define RCC_APB2ENR_ADC2EN (1 << 9) /* Bit 9: ADC2 clock enable */ +#define RCC_APB2ENR_ADC3EN (1 << 10) /* Bit 10: ADC3 clock enable */ +#define RCC_APB2ENR_SDIOEN (1 << 11) /* Bit 11: SDIO clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 clock enable */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2ENR_SPI4EN (1 << 13) /* Bit 13: SPI4 clock enable */ +#endif +#define RCC_APB2ENR_SYSCFGEN (1 << 14) /* Bit 14: System configuration controller clock enable */ +#define RCC_APB2ENR_TIM9EN (1 << 16) /* Bit 16: TIM9 clock enable */ +#define RCC_APB2ENR_TIM10EN (1 << 17) /* Bit 17: TIM10 clock enable */ +#define RCC_APB2ENR_TIM11EN (1 << 18) /* Bit 18: TIM11 clock enable */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB2ENR_SPI5EN (1 << 20) /* Bit 20: SPI5 clock enable */ +# define RCC_APB2ENR_SPI6EN (1 << 21) /* Bit 21: SPI6 clock enable */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2ENR_SAI1EN (1 << 22) /* Bit 22: SAI1 clock enable */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB2ENR_SAI2EN (1 << 23) /* Bit 23: SAI2 clock enable */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2ENR_LTDCEN (1 << 26) /* Bit 26: LTDC clock enable */ +#endif +#if defined(CONFIG_STM32_STM32F469) +# define RCC_APB2ENR_DSIEN (1 << 27) /* Bit 27: DSI clock enable */ +#endif + +/* RCC AHB1 low power mode peripheral clock enable register */ + +#define RCC_AHB1LPENR_GPIOLPEN(n) (1 << (n)) +#define RCC_AHB1LPENR_GPIOALPEN (1 << 0) /* Bit 0: IO port A clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOBLPEN (1 << 1) /* Bit 1: IO port B clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOCLPEN (1 << 2) /* Bit 2: IO port C clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIODLPEN (1 << 3) /* Bit 3: IO port D clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOELPEN (1 << 4) /* Bit 4: IO port E clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOFLPEN (1 << 5) /* Bit 5: IO port F clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOGLPEN (1 << 6) /* Bit 6: IO port G clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOHLPEN (1 << 7) /* Bit 7: IO port H clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1LPENR_GPIOILPEN (1 << 8) /* Bit 8: IO port I clock enable during Sleep mode */ +#endif +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1LPENR_GPIOJLPEN (1 << 9) /* Bit 9: IO port J clock enable during Sleep mode */ +# define RCC_AHB1LPENR_GPIOKLPEN (1 << 10) /* Bit 10: IO port K clock enable during Sleep mode */ +#endif +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) /* Bit 12: CRC clock enable during Sleep mode */ +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) /* Bit 15: Flash interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) /* Bit 16: SRAM 1 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) /* Bit 17: SRAM 2 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1LPENR_SRAM3LPEN (1 << 19) /* Bit 19: SRAM 3 interface clock enable during Sleep mode */ +#endif +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) /* Bit 21: DMA1 clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) /* Bit 22: DMA2 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB1LPENR_DMA2DLPEN (1 << 23) /* Bit 23: DMA2D clock enable during Sleep mode */ +# define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) /* Bit 25: Ethernet MAC clock enable during Sleep mode */ +# define RCC_AHB1LPENR_ETHMACTXLPEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable during Sleep mode */ +# define RCC_AHB1LPENR_ETHMACRXLPEN (1 << 27) /* Bit 27: Ethernet Reception clock enable during Sleep mode */ +# define RCC_AHB1LPENR_ETHMACPTPLPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable during Sleep mode */ +#endif +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) /* Bit 29: USB OTG HS clock enable during Sleep mode */ +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable during Sleep mode */ + +/* RCC AHB2 low power mode peripheral clock enable register */ + +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) /* Bit 0: Camera interface enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_AHB2LPENR_CRYPLPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable during Sleep mode */ +# define RCC_AHB2LPENR_HASHLPEN (1 << 5) /* Bit 5: Hash modules clock enable during Sleep mode */ +# define RCC_AHB2LPENR_RNGLPEN (1 << 6) /* Bit 6: Random number generator clock enable during Sleep mode */ +#endif +#define RCC_AHB2LPENR_OTGFLPSEN (1 << 7) /* Bit 7: USB OTG FS clock enable during Sleep mode */ + +/* RCC AHB3 low power mode peripheral clock enable register */ + +#define RCC_AHB3LPENR_FSMCLPEN (1 << 0) /* Bit 0: Flexible static memory controller module clock + * enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_AHB3LPENR_QSPILPEN (1 << 1) /* Bit 1: QUADSPI memory controller module clock enable + * during Sleep mode */ +#endif + +/* RCC APB1 low power mode peripheral clock enable register */ + +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) /* Bit 0: TIM2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) /* Bit 1: TIM3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) /* Bit 2: TIM4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) /* Bit 3: TIM5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) /* Bit 4: TIM6 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) /* Bit 5: TIM7 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) /* Bit 6: TIM12 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) /* Bit 7: TIM13 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) /* Bit 8: TIM14 clock enable during Sleep mode */ +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) /* Bit 11: Window watchdog clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) /* Bit 14: SPI2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) /* Bit 15: SPI3 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1LPENR_SPDIFRXLPEN (1 << 16) /* Bit 16: SPDIF-Rx clock enable during Sleep mode */ +#endif +#define RCC_APB1LPENR_USART2LPEN (1 << 17) /* Bit 17: USART 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_USART3LPEN (1 << 18) /* Bit 18: USART3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART4LPEN (1 << 19) /* Bit 19: UART4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART5LPEN (1 << 20) /* Bit 20: UART5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) /* Bit 21: I2C1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) /* Bit 22: I2C2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) /* Bit 23: I2C3 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1LPENR_FMPI2C1LPEN (1 << 24) /* Bit 24: FMPI2C1 clock enable during Sleep mode */ +#endif +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) /* Bit 25: CAN 1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) /* Bit 26: CAN 2 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB1LPENR_CECLPEN (1 << 27) /* Bit 27: CEC clock enable during Sleep mode */ +#endif +#define RCC_APB1LPENR_PWRLPEN (1 << 28) /* Bit 28: Power interface clock enable during Sleep mode */ +#define RCC_APB1LPENR_DACLPEN (1 << 29) /* Bit 29: DAC interface clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB1LPENR_UART7LPEN (1 << 30) /* Bit 30: UART7 clock enable during Sleep mode */ +# define RCC_APB1LPENR_UART8LPEN (1 << 31) /* Bit 31: UART8 clock enable during Sleep mode */ +#endif + +/* RCC APB2 low power mode peripheral clock enable register */ + +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) /* Bit 0: TIM1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) /* Bit 1: TIM8 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART1LPEN (1 << 4) /* Bit 4: USART1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART6LPEN (1 << 5) /* Bit 5: USART6 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) /* Bit 8: ADC1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) /* Bit 9: ADC2 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) /* Bit 10: ADC3 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SDIOLPEN (1 << 11) /* Bit 11: SDIO clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) /* Bit 12: SPI1 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2LPENR_SPI4LPEN (1 << 13) /* Bit 13: SPI4 clock enable during Sleep mode */ +#endif +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) /* Bit 14: System configuration controller clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) /* Bit 16: TIM9 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) /* Bit 17: TIM10 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) /* Bit 18: TIM11 clock enable during Sleep mode */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_APB2LPENR_SPI5LPEN (1 << 20) /* Bit 20: SPI5 clock enable during Sleep mode */ +# define RCC_APB2LPENR_SPI6LPEN (1 << 21) /* Bit 21: SPI6 clock enable during Sleep mode */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2LPENR_SAI1LPEN (1 << 22) /* Bit 22: SAI1 clock enable during Sleep mode */ +#endif +#if defined(CONFIG_STM32_STM32F446) +# define RCC_APB2LPENR_SAI2LPEN (1 << 23) /* Bit 23: SAI2 clock enable during Sleep mode */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +# define RCC_APB2LPENR_LTDCLPEN (1 << 26) /* Bit 26: LTDC clock enable during Sleep mode */ +#endif +#if defined(CONFIG_STM32_STM32F469) +# define RCC_APB2LPENR_DSILPEN (1 << 27) /* Bit 27: DSI clock enable during Sleep mode */ +#endif + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_BDCR_LSEMOD_SHIFT (3) /* Bit 3: External Low Speed oscillator mode */ +# define RCC_BDCR_LSEMOD_MASK (1 << RCC_BDCR_LSEMOD_SHIFT) +# define RCC_BDCR_LSEMOD_LOWPWR (0 << RCC_BDCR_LSEMOD_SHIFT) /* LSE oscillator "low power" mode selection */ +# define RCC_BDCR_LSEMOD_HIDRIVE (1 << RCC_BDCR_LSEMOD_SHIFT) /* LSE oscillator "high drive" mode selection */ +#endif +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_BORRSTF (1 << 25) /* Bit 25: BOR reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* Spread spectrum clock generation register */ + +#define RCC_SSCGR_MODPER_SHIFT (0) /* Bit 0-12: Modulation period */ +#define RCC_SSCGR_MODPER_MASK (0x1fff << RCC_SSCGR_MODPER_SHIFT) +# define RCC_SSCGR_MODPER(n) ((n) << RCC_SSCGR_MODPER_SHIFT) +#define RCC_SSCGR_INCSTEP_SHIFT (13) /* Bit 13-27: Incrementation step */ +#define RCC_SSCGR_INCSTEP_MASK (0x7fff << RCC_SSCGR_INCSTEP_SHIFT) +# define RCC_SSCGR_INCSTEP(n) ((n) << RCC_SSCGR_INCSTEP_SHIFT) +#define RCC_SSCGR_SPREADSEL (1 << 30) /* Bit 30: Spread Select */ +#define RCC_SSCGR_SSCGEN (1 << 31) /* Bit 31: Spread spectrum modulation enable */ + +/* PLLI2S configuration register */ + +#if defined(CONFIG_STM32_STM32F446) +# define RCC_PLLI2SCFGR_PLLI2SM_SHIFT (0) /* Bits 0-5: Division factor M for audio PLL + * (PLLI2S) input clock */ +# define RCC_PLLI2SCFGR_PLLI2SM_MASK (0x3f << RCC_PLLI2SCFGR_PLLI2SM_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SM(n) ((n) << RCC_PLLI2SCFGR_PLLI2SM_SHIFT) +#endif +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT (6) /* Bits 6-14: PLLI2S N multiplication factor for VCO */ +#define RCC_PLLI2SCFGR_PLLI2SN_MASK (0x1ff << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SN(n) ((n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) +#if defined(CONFIG_STM32_STM32F446) +# define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIF-Rx clock */ +# define RCC_PLLI2SCFGR_PLLI2SP_MASK (0x3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) + /* Set PLLI2S P to 2,4,6,8 */ +# define RCC_PLLI2SCFGR_PLLI2SP(n) (((((n)-2)/2) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) & RCC_PLLI2SCFGR_PLLI2SP_MASK) +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAI1 clock */ +# define RCC_PLLI2SCFGR_PLLI2SQ_MASK (0xf << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SQ(n) ((n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) +#endif +#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT (28) /* Bits 28-30: PLLI2S division factor for I2S clocks */ +#define RCC_PLLI2SCFGR_PLLI2SR_MASK (7 << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SR(n) ((n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) + +/* PLLSAI configuration register */ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# if defined(CONFIG_STM32_STM32F446) +# define RCC_PLLSAICFGR_PLLSAIM_SHIFT (0) /* Bits 0-5: Division factor M for audio PLLSAI + * input clock */ +# define RCC_PLLSAICFGR_PLLSAIM_MASK (0x3f << RCC_PLLSAICFGR_PLLSAIM_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIM(n) ((n) << RCC_PLLSAICFGR_PLLSAIM_SHIFT) +# endif +# define RCC_PLLSAICFGR_PLLSAIN_SHIFT (6) /* Bits 6-14: PLLSAI divider (N) for VCO */ +# define RCC_PLLSAICFGR_PLLSAIN_MASK (0x1ff << RCC_PLLSAICFGR_PLLSAIN_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT) +# if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48 MHz clock */ +# define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT) + /* Set PLLSAI P to 2,4,6,8 */ +# define RCC_PLLSAICFGR_PLLSAIP(n) (((((n)-2)/2) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) & RCC_PLLSAICFGR_PLLSAIP_MASK) +# endif +# define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */ +# define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) +# if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_PLLSAICFGR_PLLSAIR_SHIFT (28) /* Bits 28-30: PLLSAI division factor for LCD clock */ +# define RCC_PLLSAICFGR_PLLSAIR_MASK (7 << RCC_PLLSAICFGR_PLLSAIR_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIR(n) ((n) << RCC_PLLSAICFGR_PLLSAIR_SHIFT) +# endif +#endif + +/* Dedicated clocks configuration register */ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define RCC_DCKCFGR_PLLI2SDIVQ_SHIFT (0) /* Bits 0-4: PLLI2S division 1..32 factor for I2S clock */ +# define RCC_DCKCFGR_PLLI2SDIVQ_MASK (0x1f << RCC_DCKCFGR_PLLI2SDIVQ_SHIFT) +# define RCC_DCKCFGR_PLLI2SDIVQ(n) (((n)-1) << RCC_DCKCFGR_PLLI2SDIVQ_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVQ_SHIFT (8) /* Bits 8-12: PLLSAI division 1..32 factor for SAI clock */ +# define RCC_DCKCFGR_PLLSAIDIVQ_MASK (0x1f << RCC_DCKCFGR_PLLSAIDIVQ_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVQ(n) (((n)-1) << RCC_DCKCFGR_PLLSAIDIVQ_SHIFT) +# if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define RCC_DCKCFGR_PLLSAIDIVR_SHIFT (16) /* Bits 16-17: PLLSAI division factor for LCD_CLK clock */ +# define RCC_DCKCFGR_PLLSAIDIVR_MASK (0x3 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVR_DIV2 (0 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVR_DIV4 (1 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVR_DIV8 (2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR_PLLSAIDIVR_DIV16 (3 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR_SAI1ASRC_SHIFT (20) /* Bits 20-21: SAI1-A clock source selection */ +# define RCC_DCKCFGR_SAI1ASRC_MASK (0x3 << RCC_DCKCFGR_SAI1ASRC_SHIFT) +# define RCC_DCKCFGR_SAI1ASRC_PLLSAI (0 << RCC_DCKCFGR_SAI1ASRC_SHIFT) +# define RCC_DCKCFGR_SAI1ASRC_PLLI2S (1 << RCC_DCKCFGR_SAI1ASRC_SHIFT) +# define RCC_DCKCFGR_SAI1ASRC_ALTERNATE (2 << RCC_DCKCFGR_SAI1ASRC_SHIFT) +# define RCC_DCKCFGR_SAI1BSRC_SHIFT (22) /* Bits 22-23: SAI1-B clock source selection */ +# define RCC_DCKCFGR_SAI1BSRC_MASK (0x3 << RCC_DCKCFGR_SAI1BSRC_SHIFT) +# define RCC_DCKCFGR_SAI1BSRC_PLLSAI (0 << RCC_DCKCFGR_SAI1BSRC_SHIFT) +# define RCC_DCKCFGR_SAI1BSRC_PLLI2S (1 << RCC_DCKCFGR_SAI1BSRC_SHIFT) +# define RCC_DCKCFGR_SAI1BSRC_ALTERNATE (2 << RCC_DCKCFGR_SAI1BSRC_SHIFT) +# endif +# if defined(CONFIG_STM32_STM32F446) +# define RCC_DCKCFGR_SAI1SRC_SHIFT (20) /* Bits 20-21: SAI1 clock source selection */ +# define RCC_DCKCFGR_SAI1SRC_MASK (0x3 << RCC_DCKCFGR_SAI1SRC_SHIFT) +# define RCC_DCKCFGR_SAI1SRC_PLLSAI (0 << RCC_DCKCFGR_SAI1SRC_SHIFT) +# define RCC_DCKCFGR_SAI1SRC_PLLI2S (1 << RCC_DCKCFGR_SAI1SRC_SHIFT) +# define RCC_DCKCFGR_SAI1SRC_PLL (2 << RCC_DCKCFGR_SAI1SRC_SHIFT) +# define RCC_DCKCFGR_SAI1SRC_I2S_CKIN (3 << RCC_DCKCFGR_SAI1SRC_SHIFT) +# define RCC_DCKCFGR_SAI2SRC_SHIFT (22) /* Bits 22-23: SAI2 clock source selection */ +# define RCC_DCKCFGR_SAI2SRC_MASK (0x3 << RCC_DCKCFGR_SAI2SRC_SHIFT) +# define RCC_DCKCFGR_SAI2SRC_PLLSAI (0 << RCC_DCKCFGR_SAI2SRC_SHIFT) +# define RCC_DCKCFGR_SAI2SRC_PLLI2S (1 << RCC_DCKCFGR_SAI2SRC_SHIFT) +# define RCC_DCKCFGR_SAI2SRC_PLL (2 << RCC_DCKCFGR_SAI2SRC_SHIFT) +# define RCC_DCKCFGR_SAI2SRC_HSX (3 << RCC_DCKCFGR_SAI2SRC_SHIFT) +# endif +# define RCC_DCKCFGR_TIMPRE (1 << 24) /* Bit 24: Timer clock prescaler selection */ +# if defined(CONFIG_STM32_STM32F446) +# define RCC_DCKCFGR_I2S1SRC_SHIFT (25) /* Bits 25-26: I2S APB1 clock source selection */ +# define RCC_DCKCFGR_I2S1SRC_MASK (0x3 << RCC_DCKCFGR_I2S1SRC_SHIFT) +# define RCC_DCKCFGR_I2S1SRC_PLLI2S (0 << RCC_DCKCFGR_I2S1SRC_SHIFT) +# define RCC_DCKCFGR_I2S1SRC_I2S_CKIN (1 << RCC_DCKCFGR_I2S1SRC_SHIFT) +# define RCC_DCKCFGR_I2S1SRC_PLL (2 << RCC_DCKCFGR_I2S1SRC_SHIFT) +# define RCC_DCKCFGR_I2S1SRC_HSX (3 << RCC_DCKCFGR_I2S1SRC_SHIFT) +# define RCC_DCKCFGR_I2S2SRC_SHIFT (28) /* Bits 28-29: I2S APB2 clock source selection */ +# define RCC_DCKCFGR_I2S2SRC_MASK (0x3 << RCC_DCKCFGR_I2S2SRC_SHIFT) +# define RCC_DCKCFGR_I2S2SRC_PLLI2S (0 << RCC_DCKCFGR_I2S2SRC_SHIFT) +# define RCC_DCKCFGR_I2S2SRC_I2S_CKIN (1 << RCC_DCKCFGR_I2S2SRC_SHIFT) +# define RCC_DCKCFGR_I2S2SRC_PLL (2 << RCC_DCKCFGR_I2S2SRC_SHIFT) +# define RCC_DCKCFGR_I2S2SRC_HSX (3 << RCC_DCKCFGR_I2S2SRC_SHIFT) +# endif +# if defined(CONFIG_STM32_STM32F469) +# define RCC_DCKCFGR_48MSEL_SHIFT (27) /* Bit 27: 48 MHz clock source selection */ +# define RCC_DCKCFGR_48MSEL_MASK (1 << RCC_DCKCFGR_48MSEL_SHIFT) +# define RCC_DCKCFGR_48MSEL_PLL (0 << RCC_DCKCFGR_48MSEL_SHIFT) /* 48 MHz clock from PLL is selected */ +# define RCC_DCKCFGR_48MSEL_PLLSAI (1 << RCC_DCKCFGR_48MSEL_SHIFT) /* 48 MHz clock from PLLSAI is selected */ +# define RCC_DCKCFGR_SDMMCSEL_SHIFT (28) /* Bit 28: SDMMC clock source selection */ +# define RCC_DCKCFGR_SDMMCSEL_MASK (1 << RCC_DCKCFGR_SDMMCSEL_SHIFT) +# define RCC_DCKCFGR_SDMMCSEL_48MHZ (0 << RCC_DCKCFGR_SDMMCSEL_SHIFT) /* 48 MHz clock is selected as SDMMC clock */ +# define RCC_DCKCFGR_SDMMCSEL_SYSCLK (1 << RCC_DCKCFGR_SDMMCSEL_SHIFT) /* System clock is selected as SDMMC clock */ +# define RCC_DCKCFGR_DSISEL_SHIFT (29) /* Bit 29: DSI clock selection */ +# define RCC_DCKCFGR_DSISEL_MASK (1 << RCC_DCKCFGR_DSISEL_SHIFT) +# define RCC_DCKCFGR_DSISEL_DSIPHY (0 << RCC_DCKCFGR_DSISEL_SHIFT) /* DSI-PHY clock is selected as DSI clock */ +# define RCC_DCKCFGR_DSISEL_PLL (1 << RCC_DCKCFGR_DSISEL_SHIFT) /* PLL clock is selected as DSI clock */ +# endif +#endif + +/* RCC clocks gated enable register */ + +#if defined(CONFIG_STM32_STM32F446) +# define RCC_CKGATENR_AHB2APB1_CKEN (1 << 0) /* Bit 0: AHB to APB1 Bridge clock enable */ +# define RCC_CKGATENR_AHB2APB2_CKEN (1 << 1) /* Bit 1: AHB to APB2 Bridge clock enable */ +# define RCC_CKGATENR_CM4DBG_CKEN (1 << 2) /* Bit 2: Cortex M4 ETM clock enable */ +# define RCC_CKGATENR_SPARE_CKEN (1 << 3) /* Bit 3: Spare clock enable */ +# define RCC_CKGATENR_SRAM_CKEN (1 << 4) /* Bit 4: SRAM controller clock enable */ +# define RCC_CKGATENR_FLITF_CKEN (1 << 5) /* Bit 5: Flash Interface clock enable */ +# define RCC_CKGATENR_RCC_CKEN (1 << 6) /* Bit 6: RCC clock enable */ +#endif + +/* Dedicated clocks configuration register 2 */ + +#if defined(CONFIG_STM32_STM32F446) +# define RCC_DCKCFGR2_FMPI2C1SEL_SHIFT (22) /* Bits 22-23: I2C4 clock source selection */ +# define RCC_DCKCFGR2_FMPI2C1SEL_MASK (3 << RCC_DCKCFGR2_FMPI2C1SEL_SHIFT) +# define RCC_DCKCFGR2_FMPI2C1SEL_APB (0 << RCC_DCKCFGR2_FMPI2C1SEL_SHIFT) /* APB1 clock (PCLK1) is selected as I2C 4 clock */ +# define RCC_DCKCFGR2_FMPI2C1SEL_SYSCLK (1 << RCC_DCKCFGR2_FMPI2C1SEL_SHIFT) /* System clock is selected as I2C 4 clock */ +# define RCC_DCKCFGR2_FMPI2C1SEL_HSI (2 << RCC_DCKCFGR2_FMPI2C1SEL_SHIFT) /* HSI clock is selected as I2C 4 clock */ +# define RCC_DCKCFGR2_CECSEL_SHIFT (26) /* Bit 26: HDMI-CEC clock source selection */ +# define RCC_DCKCFGR2_CECSEL_MASK (1 << RCC_DCKCFGR2_CECSEL_SHIFT) +# define RCC_DCKCFGR2_CECSEL_LSE (0 << RCC_DCKCFGR2_CECSEL_SHIFT) /* LSE clock is selected as HDMI-CEC clock */ +# define RCC_DCKCFGR2_CECSEL_HSI (1 << RCC_DCKCFGR2_CECSEL_SHIFT) /* HSI clock is selected as HDMI-CEC clock */ +# define RCC_DCKCFGR2_CK48MSEL_SHIFT (27) /* Bit 27: 48 MHz clock source selection */ +# define RCC_DCKCFGR2_CK48MSEL_MASK (1 << RCC_DCKCFGR2_CK48MSEL_SHIFT) +# define RCC_DCKCFGR2_CK48MSEL_PLL (0 << RCC_DCKCFGR2_CK48MSEL_SHIFT) /* 48 MHz clock from PLL is selected */ +# define RCC_DCKCFGR2_CK48MSEL_PLLSAI (1 << RCC_DCKCFGR2_CK48MSEL_SHIFT) /* 48 MHz clock from PLLSAI is selected */ +# define RCC_DCKCFGR2_SDIOSEL_SHIFT (28) /* Bit 28: SDIO clock source selection */ +# define RCC_DCKCFGR2_SDIOSEL_MASK (1 << RCC_DCKCFGR2_SDIOSEL_SHIFT) +# define RCC_DCKCFGR2_SDIOSEL_48MHZ (0 << RCC_DCKCFGR2_SDIOSEL_SHIFT) /* 48 MHz clock is selected as SDMMC clock */ +# define RCC_DCKCFGR2_SDIOSEL_SYSCLK (1 << RCC_DCKCFGR2_SDIOSEL_SHIFT) /* System clock is selected as SDMMC clock */ +# define RCC_DCKCFGR2_SPDIFRXSEL_SHIFT (29) /* Bit 29: SPDIF-Rx clock selection */ +# define RCC_DCKCFGR2_SPDIFRXSEL_MASK (1 << RCC_DCKCFGR2_SPDIFRXSEL_SHIFT) +# define RCC_DCKCFGR2_SPDIFRXSEL_PLL (0 << RCC_DCKCFGR2_SPDIFRXSEL_SHIFT) /* PLL clock is selected as SPDIF-Rx clock */ +# define RCC_DCKCFGR2_SPDIFRXSEL_PLLI2S (1 << RCC_DCKCFGR2_SPDIFRXSEL_SHIFT) /* PLLI2S clock is selected as SPDIF-Rx clock */ +#endif + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_RCC_H */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f40xxx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..57068a2b8dd4433efc5aa6375b7e5f83abdf0405 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_syscfg.h @@ -0,0 +1,202 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f40xxx_syscfg.h + * + * Copyright (C) 2011, 2013, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#ifdef CONFIG_STM32_STM32F40XX + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +#define STM32_SYSCFG_CMPCR_OFFSET 0x0020 /* Compensation cell control register */ +#if defined(CONFIG_STM32_STM32F446) +# define STM32_SYSCFG_CFGR_OFFSET 0x002c /* SYSCFG configuration register */ +#endif + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_MEMRMP (STM32_SYSCFG_BASE+STM32_SYSCFG_MEMRMP_OFFSET) +#define STM32_SYSCFG_PMC (STM32_SYSCFG_BASE+STM32_SYSCFG_PMC_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +#define STM32_SYSCFG_CMPCR (STM32_SYSCFG_BASE+STM32_SYSCFG_CMPCR_OFFSET) +#if defined(CONFIG_STM32_STM32F446) +# define STM32_SYSCFG_CFGR (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR_OFFSET) +#endif + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_MEMRMP_MASK (3 << SYSCFG_MEMRMP_SHIFT) +# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 00: Main Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 01: System Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_FSMC (2 << SYSCFG_MEMRMP_SHIFT) /* 10: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 11: Embedded SRAM (112kB) mapped at 0x0000 0000 */ + +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define SYSCFG_FBMODE_SHIFT (8) /* Bit 8 FB_MODE: Flash Bank mode selection */ +# define SYSCFG_FBMODE_MASK (1 << SYSCFG_FBMODE_SHIFT) +# define SYSCFG_FBMODE_FB12 (0 << SYSCFG_FBMODE_SHIFT) /* 0: Flash Bank 1 is mapped at 0x0800 0000 and + * Flash Bank 2 is mapped at 0x0810 0000 */ +# define SYSCFG_FBMODE_FB21 (1 << SYSCFG_FBMODE_SHIFT) /* 1: Flash Bank 2 is mapped at 0x0800 0000 and + * Flash Bank 1 is mapped at 0x0810 0000 */ +#endif + +#define SYSCFG_SWPFMC_SHIFT (10) /* Bits 10:11 SWP_FMC: FMC memory mapping swap */ +#define SYSCFG_SWPFMC_MASK (3 << SYSCFG_SWPFMC_SHIFT) +# define SYSCFG_SWPFMC_NOSWAP (0 << SYSCFG_SWPFMC_SHIFT) /* 00: No FMC memory mapping swap */ +# define SYSCFG_SWPFMC_SWAP (1 << SYSCFG_SWPFMC_SHIFT) /* 01: SDRAM banks and NAND Bank 2/PCCARD mapping are swapped */ + +/* SYSCFG peripheral mode configuration register */ + +#define SYSCFG_PMC_ADC1DC2 (1 << 16) /* Bit 16: See AN4073 */ +#define SYSCFG_PMC_ADC2DC2 (1 << 17) /* Bit 17: See AN4073 */ +#define SYSCFG_PMC_ADC3DC2 (1 << 18) /* Bit 18: See AN4073 */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define SYSCFG_PMC_MII_RMII_SEL (1 << 23) /* Bit 23: Ethernet PHY interface selection */ +#endif + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ +#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */ +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +# define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin */ +#endif +#if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) || \ + defined(CONFIG_STM32_STM32F469) +# define SYSCFG_EXTICR_PORTJ (9) /* 1001: PJ[x] pin */ +# define SYSCFG_EXTICR_PORTK (10) /* 1010: PK[x] pin */ +#endif + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 configuration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 configuration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 configuration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 configuration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 configuration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 configuration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 configuration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 configuration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 configuration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 configuration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 configuration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 configuration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 configuration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 configuration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 configuration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 configuration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* Compensation cell control register */ + +#define SYSCFG_CMPCR_CMPPD (1 << 0) /* Bit 0: Compensation cell power-down */ +#define SYSCFG_CMPCR_READY (1 << 8) /* Bit 8: Compensation cell ready flag */ + +/* SYSCFG configuration register */ + +#if defined(CONFIG_STM32_STM32F446) +# define SYSCFG_CFGR_FMPI2C1_SCL (1 << 0) /* Bit 0: Forces FM+ drive capability on SCL */ +# define SYSCFG_CFGR_FMPI2C1_SDA (1 << 1) /* Bit 8: Forces FM+ drive capability on SDA */ +#endif + +#endif /* CONFIG_STM32_STM32F40XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F40XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_uart.h b/arch/arm/src/stm32/chip/stm32f40xxx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..824ea9515b5daa77455203a9b9483ab53f4770df --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_uart.h @@ -0,0 +1,247 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_uart.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32F40XXX_UART_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32F40XXX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_SR_OFFSET 0x0000 /* Status register (32-bits) */ +#define STM32_USART_DR_OFFSET 0x0004 /* Data register (32-bits) */ +#define STM32_USART_BRR_OFFSET 0x0008 /* Baud Rate Register (32-bits) */ +#define STM32_USART_CR1_OFFSET 0x000c /* Control register 1 (32-bits) */ +#define STM32_USART_CR2_OFFSET 0x0010 /* Control register 2 (32-bits) */ +#define STM32_USART_CR3_OFFSET 0x0014 /* Control register 3 (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0018 /* Guard time and prescaler register (32-bits) */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NUSART > 0 +# define STM32_USART1_SR (STM32_USART1_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART1_DR (STM32_USART1_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_SR (STM32_USART2_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART2_DR (STM32_USART2_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_SR (STM32_USART3_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART3_DR (STM32_USART3_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_SR (STM32_UART4_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART4_DR (STM32_UART4_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_SR (STM32_UART5_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART5_DR (STM32_UART5_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 5 +# define STM32_USART6_SR (STM32_USART6_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART6_DR (STM32_USART6_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART6_BRR (STM32_USART6_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART6_CR1 (STM32_USART6_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART6_CR2 (STM32_USART6_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART6_CR3 (STM32_USART6_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART6_GTPR (STM32_USART6_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 6 +# define STM32_UART7_SR (STM32_UART7_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART7_DR (STM32_UART7_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART7_BRR (STM32_UART7_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART7_CR1 (STM32_UART7_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART7_CR2 (STM32_UART7_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART7_CR3 (STM32_UART7_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 7 +# define STM32_UART8_SR (STM32_UART8_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART8_DR (STM32_UART8_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART8_BRR (STM32_UART8_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART8_CR1 (STM32_UART8_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART8_CR2 (STM32_UART8_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART8_CR3 (STM32_UART8_BASE+STM32_USART_CR3_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Status register */ + +#define USART_SR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_SR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_SR_NE (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_SR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_SR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_SR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_SR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_SR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_SR_LBD (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_SR_CTS (1 << 9) /* Bit 9: CTS Flag */ + +#define USART_SR_ALLBITS (0x03ff) +#define USART_SR_CLRBITS (USART_SR_CTS|USART_SR_LBD) /* Cleared by SW write to SR */ + +/* Data register */ + +#define USART_DR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_DR_MASK (0xff << USART_DR_SHIFT) + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Control register 1 */ + +#define USART_CR1_SBK (1 << 0) /* Bit 0: Send Break */ +#define USART_CR1_RWU (1 << 1) /* Bit 1: Receiver wakeup */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M (1 << 12) /* Bit 12: word length */ +#define USART_CR1_UE (1 << 13) /* Bit 13: USART Enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE|USART_CR1_TCIE|USART_CR1_PEIE) + +/* Control register 2 */ + +#define USART_CR2_ADD_SHIFT (0) /* Bits 3-0: Address of the USART node */ +#define USART_CR2_ADD_MASK (0x0f << USART_CR2_ADD_SHIFT) +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */ + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Compatibility definitions ********************************************************/ +/* F3 Transmit/Read registers */ + +#define STM32_USART_RDR_OFFSET STM32_USART_DR_OFFSET /* Receive data register */ +#define STM32_USART_TDR_OFFSET STM32_USART_DR_OFFSET /* Transmit data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32F40XXX_UART_H */ diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h b/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..b661cecbc53a867869e6fa3e971bcc984ea2636c --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f40xxx_vectors.h @@ -0,0 +1,212 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32f40xxx_vectors.h + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ + +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies each STM32F40xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f40xxx_irq.h. + * stm32_vectors.S will define the VECTOR macro in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve interrupt table entries for I/O interrupts. */ + +# if defined(CONFIG_STM32_STM32F401) || defined(CONFIG_STM32_STM32F411) || \ + defined(CONFIG_STM32_STM32F405) || defined(CONFIG_STM32_STM32F407) +# define ARMV7M_PERIPHERAL_INTERRUPTS 82 +# elif defined(CONFIG_STM32_STM32F427) +# define ARMV7M_PERIPHERAL_INTERRUPTS 87 +# elif defined(CONFIG_STM32_STM32F429) +# define ARMV7M_PERIPHERAL_INTERRUPTS 91 +# elif defined(CONFIG_STM32_STM32F446) +# define ARMV7M_PERIPHERAL_INTERRUPTS 97 +# elif defined(CONFIG_STM32_STM32F469) +# define ARMV7M_PERIPHERAL_INTERRUPTS 93 +# endif + +#else + +VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* Vector 16+0: Window Watchdog interrupt */ +VECTOR(stm32_pvd, STM32_IRQ_PVD) /* Vector 16+1: PVD through EXTI Line detection interrupt */ +VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* Vector 16+2: Tamper and time stamp interrupts */ +VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* Vector 16+3: RTC global interrupt */ +VECTOR(stm32_flash, STM32_IRQ_FLASH) /* Vector 16+4: Flash global interrupt */ +VECTOR(stm32_rcc, STM32_IRQ_RCC) /* Vector 16+5: RCC global interrupt */ +VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* Vector 16+6: EXTI Line 0 interrupt */ +VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* Vector 16+7: EXTI Line 1 interrupt */ +VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* Vector 16+8: EXTI Line 2 interrupt */ +VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* Vector 16+9: EXTI Line 3 interrupt */ +VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* Vector 16+10: EXTI Line 4 interrupt */ +VECTOR(stm32_dma1s0, STM32_IRQ_DMA1S0) /* Vector 16+11: DMA1 Stream 0 global interrupt */ +VECTOR(stm32_dma1s1, STM32_IRQ_DMA1S1) /* Vector 16+12: DMA1 Stream 1 global interrupt */ +VECTOR(stm32_dma1s2, STM32_IRQ_DMA1S2) /* Vector 16+13: DMA1 Stream 2 global interrupt */ +VECTOR(stm32_dma1s3, STM32_IRQ_DMA1S3) /* Vector 16+14: DMA1 Stream 3 global interrupt */ +VECTOR(stm32_dma1s4, STM32_IRQ_DMA1S4) /* Vector 16+15: DMA1 Stream 4 global interrupt */ +VECTOR(stm32_dma1s5, STM32_IRQ_DMA1S5) /* Vector 16+16: DMA1 Stream 5 global interrupt */ +VECTOR(stm32_dma1s6, STM32_IRQ_DMA1S6) /* Vector 16+17: DMA1 Stream 6 global interrupt */ +VECTOR(stm32_adc, STM32_IRQ_ADC) /* Vector 16+18: ADC1, ADC2, and ADC3 global interrupt */ +VECTOR(stm32_can1tx, STM32_IRQ_CAN1TX) /* Vector 16+19: CAN1 TX interrupts */ +VECTOR(stm32_can1rx0, STM32_IRQ_CAN1RX0) /* Vector 16+20: CAN1 RX0 interrupts */ +VECTOR(stm32_can1rx1, STM32_IRQ_CAN1RX1) /* Vector 16+21: CAN1 RX1 interrupt */ +VECTOR(stm32_can1sce, STM32_IRQ_CAN1SCE) /* Vector 16+22: CAN1 SCE interrupt */ +VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* Vector 16+23: EXTI Line[9:5] interrupts */ +VECTOR(stm32_tim1brk, STM32_IRQ_TIM1BRK) /* Vector 16+24: TIM1 Break interrupt/TIM9 global interrupt */ +VECTOR(stm32_tim1up, STM32_IRQ_TIM1UP) /* Vector 16+25: TIM1 Update interrupt/TIM10 global interrupt */ +VECTOR(stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM) /* Vector 16+26: TIM1 Trigger and Commutation interrupts/TIM11 global interrupt */ +VECTOR(stm32_tim1cc, STM32_IRQ_TIM1CC) /* Vector 16+27: TIM1 Capture Compare interrupt */ +VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* Vector 16+28: TIM2 global interrupt */ +VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* Vector 16+29: TIM3 global interrupt */ +VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* Vector 16+30: TIM4 global interrupt */ +VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* Vector 16+31: I2C1 event interrupt */ +VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* Vector 16+32: I2C1 error interrupt */ +VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* Vector 16+33: I2C2 event interrupt */ +VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* Vector 16+34: I2C2 error interrupt */ +VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* Vector 16+35: SPI1 global interrupt */ +VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* Vector 16+36: SPI2 global interrupt */ +VECTOR(stm32_usart1, STM32_IRQ_USART1) /* Vector 16+37: USART1 global interrupt */ +VECTOR(stm32_usart2, STM32_IRQ_USART2) /* Vector 16+38: USART2 global interrupt */ +VECTOR(stm32_usart3, STM32_IRQ_USART3) /* Vector 16+39: USART3 global interrupt */ +VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* Vector 16+40: EXTI Line[15:10] interrupts */ +VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* Vector 16+41: RTC alarm through EXTI line interrupt */ +VECTOR(stm32_otgfswkup, STM32_IRQ_OTGFSWKUP) /* Vector 16+42: USB On-The-Go FS Wakeup through EXTI line interrupt */ +VECTOR(stm32_tim8brk, STM32_IRQ_TIM8BRK) /* Vector 16+43: TIM8 Break interrupt/TIM12 global interrupt */ +VECTOR(stm32_tim8up, STM32_IRQ_TIM8UP) /* Vector 16+44: TIM8 Update interrupt/TIM13 global interrupt */ +VECTOR(stm32_tim8trgcom, STM32_IRQ_TIM8TRGCOM) /* Vector 16+45: TIM8 Trigger and Commutation interrupts/TIM14 global interrupt */ +VECTOR(stm32_tim8cc, STM32_IRQ_TIM8CC) /* Vector 16+46: TIM8 Capture Compare interrupt */ +VECTOR(stm32_dma1s7, STM32_IRQ_DMA1S7) /* Vector 16+47: DMA1 Stream 7 global interrupt */ +VECTOR(stm32_fsmc, STM32_IRQ_FSMC) /* Vector 16+48: FSMC global interrupt */ +VECTOR(stm32_sdio, STM32_IRQ_SDIO) /* Vector 16+49: SDIO global interrupt */ +VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* Vector 16+50: TIM5 global interrupt */ +VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* Vector 16+51: SPI3 global interrupt */ +VECTOR(stm32_uart4, STM32_IRQ_UART4) /* Vector 16+52: UART4 global interrupt */ +VECTOR(stm32_uart5, STM32_IRQ_UART5) /* Vector 16+53: UART5 global interrupt */ +VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* Vector 16+54: TIM6 global interrupt/DAC1 and DAC2 underrun error interrupts */ +VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* Vector 16+55: TIM7 global interrupt */ +VECTOR(stm32_dma2s0, STM32_IRQ_DMA2S0) /* Vector 16+56: DMA2 Stream 0 global interrupt */ +VECTOR(stm32_dma2s1, STM32_IRQ_DMA2S1) /* Vector 16+57: DMA2 Stream 1 global interrupt */ +VECTOR(stm32_dma2s2, STM32_IRQ_DMA2S2) /* Vector 16+58: DMA2 Stream 2 global interrupt */ +VECTOR(stm32_dma2s3, STM32_IRQ_DMA2S3) /* Vector 16+59: DMA2 Stream 3 global interrupt */ +VECTOR(stm32_dma2s4, STM32_IRQ_DMA2S4) /* Vector 16+60: DMA2 Stream 4 global interrupt */ +#if defined(CONFIG_STM32_STM32F446) +UNUSED(STM32_IRQ_RESERVED61) /* Vector 16+61: Reserved */ +UNUSED(STM32_IRQ_RESERVED62) /* Vector 16+62: Reserved */ +#else +VECTOR(stm32_eth, STM32_IRQ_ETH) /* Vector 16+61: Ethernet global interrupt */ +VECTOR(stm32_ethwkup, STM32_IRQ_ETHWKUP) /* Vector 16+62: Ethernet Wakeup through EXTI line interrupt */ +#endif +VECTOR(stm32_can2tx, STM32_IRQ_CAN2TX) /* Vector 16+63: CAN2 TX interrupts */ +VECTOR(stm32_can2rx0, STM32_IRQ_CAN2RX0) /* Vector 16+64: CAN2 RX0 interrupts */ +VECTOR(stm32_can2rx1, STM32_IRQ_CAN2RX1) /* Vector 16+65: CAN2 RX1 interrupt */ +VECTOR(stm32_can2sce, STM32_IRQ_CAN2SCE) /* Vector 16+66: CAN2 SCE interrupt */ +VECTOR(stm32_otgfs, STM32_IRQ_OTGFS) /* Vector 16+67: USB On The Go FS global interrupt */ +VECTOR(stm32_dma2s5, STM32_IRQ_DMA2S5) /* Vector 16+68: DMA2 Stream 5 global interrupt */ +VECTOR(stm32_dma2s6, STM32_IRQ_DMA2S6) /* Vector 16+69: DMA2 Stream 6 global interrupt */ +VECTOR(stm32_dma2s7, STM32_IRQ_DMA2S7) /* Vector 16+70: DMA2 Stream 7 global interrupt */ +VECTOR(stm32_usart6, STM32_IRQ_USART6) /* Vector 16+71: USART6 global interrupt */ +VECTOR(stm32_i2c3ev, STM32_IRQ_I2C3EV) /* Vector 16+72: I2C3 event interrupt */ +VECTOR(stm32_i2c3er, STM32_IRQ_I2C3ER) /* Vector 16+73: I2C3 error interrupt */ +VECTOR(stm32_otghsep1out, STM32_IRQ_OTGHSEP1OUT) /* Vector 16+74: USB On The Go HS End Point 1 Out global interrupt */ +VECTOR(stm32_otghsep1in, STM32_IRQ_OTGHSEP1IN) /* Vector 16+75: USB On The Go HS End Point 1 In global interrupt */ +VECTOR(stm32_otghswkup, STM32_IRQ_OTGHSWKUP) /* Vector 16+76: USB On The Go HS Wakeup through EXTI interrupt */ +VECTOR(stm32_otghs, STM32_IRQ_OTGHS) /* Vector 16+77: USB On The Go HS global interrupt */ +VECTOR(stm32_dcmi, STM32_IRQ_DCMI) /* Vector 16+78: DCMI global interrupt */ +#if defined(CONFIG_STM32_STM32F446) +UNUSED(STM32_IRQ_RESERVED79) /* Vector 16+79: Reserved */ +UNUSED(STM32_IRQ_RESERVED80) /* Vector 16+80: Reserved */ +#else +VECTOR(stm32_cryp, STM32_IRQ_CRYP) /* Vector 16+79: CRYP crypto global interrupt */ +VECTOR(stm32_hash, STM32_IRQ_HASH) /* Vector 16+80: Hash and Rng global interrupt */ +#endif +VECTOR(stm32_fpu, STM32_IRQ_FPU) /* Vector 16+81: FPU global interrupt */ +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_uart7, STM32_IRQ_UART7) /* Vector 16+82: UART7 interrupt */ +VECTOR(stm32_uart8, STM32_IRQ_UART8) /* Vector 16+83: UART8 interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +UNUSED(STM32_IRQ_RESERVED82) /* Vector 16+82: Reserved */ +UNUSED(STM32_IRQ_RESERVED83) /* Vector 16+83: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_spi4, STM32_IRQ_SPI4) /* Vector 16+84: SPI4 interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_spi5, STM32_IRQ_SPI5) /* Vector 16+85: SPI5 interrupt */ +VECTOR(stm32_spi6, STM32_IRQ_SPI6) /* Vector 16+86: SPI6 interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +UNUSED(STM32_IRQ_RESERVED85) /* Vector 16+85: Reserved */ +UNUSED(STM32_IRQ_RESERVED86) /* Vector 16+86: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F446) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_sai1, STM32_IRQ_SAI1) /* Vector 16+87: SAI1 interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_ltdcint, STM32_IRQ_LTDCINT) /* Vector 16+88: LTDC interrupt */ +VECTOR(stm32_ltdcerrint, STM32_IRQ_LTDCERRINT) /* Vector 16+89: LTDC Error interrupt */ +VECTOR(stm32_dma2d, STM32_IRQ_DMA2D) /* Vector 16+90: DMA2D interrupt */ +#elif defined(CONFIG_STM32_STM32F446) +UNUSED(STM32_IRQ_RESERVED88) /* Vector 16+88: Reserved */ +UNUSED(STM32_IRQ_RESERVED89) /* Vector 16+89: Reserved */ +UNUSED(STM32_IRQ_RESERVED90) /* Vector 16+90: Reserved */ +#endif +#if defined(CONFIG_STM32_STM32F446) +VECTOR(stm32_sai2, STM32_IRQ_SAI2) /* Vector 16+91: SAI2 Global interrupt */ +VECTOR(stm32_quadspi, STM32_IRQ_QUADSPI) /* Vector 16+92: QuadSPI Global interrupt */ +#elif defined(CONFIG_STM32_STM32F469) +VECTOR(stm32_quadspi, STM32_IRQ_QUADSPI) /* Vector 16+91: QuadSPI Global interrupt */ +VECTOR(stm32_dsi, STM32_IRQ_DSI) /* Vector 16+92: DSI Global interrupt */ +#endif +#if defined(CONFIG_STM32_STM32F446) +VECTOR(stm32_hdmicec, STM32_IRQ_HDMICEC) /* Vector 16+93: HDMI-CEC Global interrupt */ +VECTOR(stm32_spdifrx, STM32_IRQ_SPDIFRX) /* Vector 16+94: SPDIF-Rx Global interrupt */ +VECTOR(stm32_fmpi2c1, STM32_IRQ_FMPI2C1) /* Vector 16+95: FMPI2C1 event interrupt */ +VECTOR(stm32_fmpi2c1err, STM32_IRQ_FMPI2C1ERR) /* Vector 16+96: FMPI2C1 Error event interrupt */ +#endif + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ diff --git a/arch/arm/src/stm32/chip/stm32fxxxxx_otgfs.h b/arch/arm/src/stm32/chip/stm32fxxxxx_otgfs.h new file mode 100644 index 0000000000000000000000000000000000000000..b0f431ab06f808bdc4a24948eeecdff090fb151a --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32fxxxxx_otgfs.h @@ -0,0 +1,1041 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32fxxxxx_otgfs.h + * + * Copyright (C) 2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32FXXXXX_OTGFS_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32FXXXXX_OTGFS_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* General definitions */ + +#define OTGFS_EPTYPE_CTRL (0) /* Control */ +#define OTGFS_EPTYPE_ISOC (1) /* Isochronous */ +#define OTGFS_EPTYPE_BULK (2) /* Bulk */ +#define OTGFS_EPTYPE_INTR (3) /* Interrupt */ + +#define OTGFS_PID_DATA0 (0) +#define OTGFS_PID_DATA2 (1) +#define OTGFS_PID_DATA1 (2) +#define OTGFS_PID_MDATA (3) /* Non-control */ +#define OTGFS_PID_SETUP (3) /* Control */ + +/* Register Offsets *********************************************************************************/ +/* Core global control and status registers */ + +#define STM32_OTGFS_GOTGCTL_OFFSET 0x0000 /* Control and status register */ +#define STM32_OTGFS_GOTGINT_OFFSET 0x0004 /* Interrupt register */ +#define STM32_OTGFS_GAHBCFG_OFFSET 0x0008 /* AHB configuration register */ +#define STM32_OTGFS_GUSBCFG_OFFSET 0x000c /* USB configuration register */ +#define STM32_OTGFS_GRSTCTL_OFFSET 0x0010 /* Reset register */ +#define STM32_OTGFS_GINTSTS_OFFSET 0x0014 /* Core interrupt register */ +#define STM32_OTGFS_GINTMSK_OFFSET 0x0018 /* Interrupt mask register */ +#define STM32_OTGFS_GRXSTSR_OFFSET 0x001c /* Receive status debug read/OTG status read register */ +#define STM32_OTGFS_GRXSTSP_OFFSET 0x0020 /* Receive status debug read/OTG status pop register */ +#define STM32_OTGFS_GRXFSIZ_OFFSET 0x0024 /* Receive FIFO size register */ +#define STM32_OTGFS_HNPTXFSIZ_OFFSET 0x0028 /* Host non-periodic transmit FIFO size register */ +#define STM32_OTGFS_DIEPTXF0_OFFSET 0x0028 /* Endpoint 0 Transmit FIFO size */ +#define STM32_OTGFS_HNPTXSTS_OFFSET 0x002c /* Non-periodic transmit FIFO/queue status register */ +#define STM32_OTGFS_GCCFG_OFFSET 0x0038 /* General core configuration register */ +#define STM32_OTGFS_CID_OFFSET 0x003c /* Core ID register */ +#define STM32_OTGFS_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ + +#define STM32_OTGFS_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) +#define STM32_OTGFS_DIEPTXF1_OFFSET 0x0104 /* Device IN endpoint transmit FIFO1 size register */ +#define STM32_OTGFS_DIEPTXF2_OFFSET 0x0108 /* Device IN endpoint transmit FIFO2 size register */ +#define STM32_OTGFS_DIEPTXF3_OFFSET 0x010c /* Device IN endpoint transmit FIFO3 size register */ + +/* Host-mode control and status registers */ + +#define STM32_OTGFS_HCFG_OFFSET 0x0400 /* Host configuration register */ +#define STM32_OTGFS_HFIR_OFFSET 0x0404 /* Host frame interval register */ +#define STM32_OTGFS_HFNUM_OFFSET 0x0408 /* Host frame number/frame time remaining register */ +#define STM32_OTGFS_HPTXSTS_OFFSET 0x0410 /* Host periodic transmit FIFO/queue status register */ +#define STM32_OTGFS_HAINT_OFFSET 0x0414 /* Host all channels interrupt register */ +#define STM32_OTGFS_HAINTMSK_OFFSET 0x0418 /* Host all channels interrupt mask register */ +#define STM32_OTGFS_HPRT_OFFSET 0x0440 /* Host port control and status register */ + +#define STM32_OTGFS_CHAN_OFFSET(n) (0x500 + ((n) << 5) +#define STM32_OTGFS_HCCHAR_CHOFFSET 0x0000 /* Host channel characteristics register */ +#define STM32_OTGFS_HCINT_CHOFFSET 0x0008 /* Host channel interrupt register */ +#define STM32_OTGFS_HCINTMSK_CHOFFSET 0x000c /* Host channel interrupt mask register */ +#define STM32_OTGFS_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */ + +#define STM32_OTGFS_HCCHAR_OFFSET(n) (0x500 + ((n) << 5)) +#define STM32_OTGFS_HCCHAR0_OFFSET 0x0500 /* Host channel-0 characteristics register */ +#define STM32_OTGFS_HCCHAR1_OFFSET 0x0520 /* Host channel-1 characteristics register */ +#define STM32_OTGFS_HCCHAR2_OFFSET 0x0540 /* Host channel-2 characteristics register */ +#define STM32_OTGFS_HCCHAR3_OFFSET 0x0560 /* Host channel-3 characteristics register */ +#define STM32_OTGFS_HCCHAR4_OFFSET 0x0580 /* Host channel-4 characteristics register */ +#define STM32_OTGFS_HCCHAR5_OFFSET 0x05a0 /* Host channel-5 characteristics register */ +#define STM32_OTGFS_HCCHAR6_OFFSET 0x05c0 /* Host channel-6 characteristics register */ +#define STM32_OTGFS_HCCHAR7_OFFSET 0x05e0 /* Host channel-7 characteristics register */ + +#define STM32_OTGFS_HCINT_OFFSET(n) (0x508 + ((n) << 5)) +#define STM32_OTGFS_HCINT0_OFFSET 0x0508 /* Host channel-0 interrupt register */ +#define STM32_OTGFS_HCINT1_OFFSET 0x0528 /* Host channel-1 interrupt register */ +#define STM32_OTGFS_HCINT2_OFFSET 0x0548 /* Host channel-2 interrupt register */ +#define STM32_OTGFS_HCINT3_OFFSET 0x0568 /* Host channel-3 interrupt register */ +#define STM32_OTGFS_HCINT4_OFFSET 0x0588 /* Host channel-4 interrupt register */ +#define STM32_OTGFS_HCINT5_OFFSET 0x05a8 /* Host channel-5 interrupt register */ +#define STM32_OTGFS_HCINT6_OFFSET 0x05c8 /* Host channel-6 interrupt register */ +#define STM32_OTGFS_HCINT7_OFFSET 0x05e8 /* Host channel-7 interrupt register */ + +#define STM32_OTGFS_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5)) +#define STM32_OTGFS_HCINTMSK0_OFFSET 0x050c /* Host channel-0 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK1_OFFSET 0x052c /* Host channel-1 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK2_OFFSET 0x054c /* Host channel-2 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK3_OFFSET 0x056c /* Host channel-3 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK4_OFFSET 0x058c /* Host channel-4 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK5_OFFSET 0x05ac /* Host channel-5 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK6_OFFSET 0x05cc /* Host channel-6 interrupt mask register */ +#define STM32_OTGFS_HCINTMSK7_OFFSET 0x05ec /* Host channel-7 interrupt mask register */ + +#define STM32_OTGFS_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5)) +#define STM32_OTGFS_HCTSIZ0_OFFSET 0x0510 /* Host channel-0 interrupt register */ +#define STM32_OTGFS_HCTSIZ1_OFFSET 0x0530 /* Host channel-1 interrupt register */ +#define STM32_OTGFS_HCTSIZ2_OFFSET 0x0550 /* Host channel-2 interrupt register */ +#define STM32_OTGFS_HCTSIZ3_OFFSET 0x0570 /* Host channel-3 interrupt register */ +#define STM32_OTGFS_HCTSIZ4_OFFSET 0x0590 /* Host channel-4 interrupt register */ +#define STM32_OTGFS_HCTSIZ5_OFFSET 0x05b0 /* Host channel-5 interrupt register */ +#define STM32_OTGFS_HCTSIZ6_OFFSET 0x05d0 /* Host channel-6 interrupt register */ +#define STM32_OTGFS_HCTSIZ7_OFFSET 0x05f0 /* Host channel-7 interrupt register */ + +/* Device-mode control and status registers */ + +#define STM32_OTGFS_DCFG_OFFSET 0x0800 /* Device configuration register */ +#define STM32_OTGFS_DCTL_OFFSET 0x0804 /* Device control register */ +#define STM32_OTGFS_DSTS_OFFSET 0x0808 /* Device status register */ +#define STM32_OTGFS_DIEPMSK_OFFSET 0x0810 /* Device IN endpoint common interrupt mask register */ +#define STM32_OTGFS_DOEPMSK_OFFSET 0x0814 /* Device OUT endpoint common interrupt mask register */ +#define STM32_OTGFS_DAINT_OFFSET 0x0818 /* Device all endpoints interrupt register */ +#define STM32_OTGFS_DAINTMSK_OFFSET 0x081c /* All endpoints interrupt mask register */ +#define STM32_OTGFS_DVBUSDIS_OFFSET 0x0828 /* Device VBUS discharge time register */ +#define STM32_OTGFS_DVBUSPULSE_OFFSET 0x082c /* Device VBUS pulsing time register */ +#define STM32_OTGFS_DIEPEMPMSK_OFFSET 0x0834 /* Device IN endpoint FIFO empty interrupt mask register */ + +#define STM32_OTGFS_DIEP_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGFS_DIEPCTL_EPOFFSET 0x0000 /* Device endpoint control register */ +#define STM32_OTGFS_DIEPINT_EPOFFSET 0x0008 /* Device endpoint interrupt register */ +#define STM32_OTGFS_DIEPTSIZ_EPOFFSET 0x0010 /* Device IN endpoint transfer size register */ +#define STM32_OTGFS_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */ + +#define STM32_OTGFS_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTGFS_DIEPCTL0_OFFSET 0x0900 /* Device control IN endpoint 0 control register */ +#define STM32_OTGFS_DIEPCTL1_OFFSET 0x0920 /* Device control IN endpoint 2 control register */ +#define STM32_OTGFS_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */ +#define STM32_OTGFS_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */ + +#define STM32_OTGFS_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5)) +#define STM32_OTGFS_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */ +#define STM32_OTGFS_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */ +#define STM32_OTGFS_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */ +#define STM32_OTGFS_DIEPINT3_OFFSET 0x0968 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGFS_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5)) +#define STM32_OTGFS_DIEPTSIZ0_OFFSET 0x0910 /* Device IN endpoint 0 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ1_OFFSET 0x0930 /* Device IN endpoint 1 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ2_OFFSET 0x0950 /* Device IN endpoint 2 transfer size register */ +#define STM32_OTGFS_DIEPTSIZ3_OFFSET 0x0970 /* Device IN endpoint 3 transfer size register */ + +#define STM32_OTGFS_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5)) +#define STM32_OTGFS_DTXFSTS0_OFFSET 0x0918 /* Device OUT endpoint-0 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS1_OFFSET 0x0938 /* Device OUT endpoint-1 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 TxFIFO status register */ +#define STM32_OTGFS_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 TxFIFO status register */ + +#define STM32_OTGFS_DOEP_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGFS_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */ +#define STM32_OTGFS_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */ + +#define STM32_OTGFS_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTGFS_DOEPCTL0_OFFSET 0x00b00 /* Device OUT endpoint 0 control register */ +#define STM32_OTGFS_DOEPCTL1_OFFSET 0x00b20 /* Device OUT endpoint 1 control register */ +#define STM32_OTGFS_DOEPCTL2_OFFSET 0x00b40 /* Device OUT endpoint 2 control register */ +#define STM32_OTGFS_DOEPCTL3_OFFSET 0x00b60 /* Device OUT endpoint 3 control register */ + +#define STM32_OTGFS_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5)) +#define STM32_OTGFS_DOEPINT0_OFFSET 0x00b08 /* Device endpoint-0 interrupt register */ +#define STM32_OTGFS_DOEPINT1_OFFSET 0x00b28 /* Device endpoint-1 interrupt register */ +#define STM32_OTGFS_DOEPINT2_OFFSET 0x00b48 /* Device endpoint-2 interrupt register */ +#define STM32_OTGFS_DOEPINT3_OFFSET 0x00b68 /* Device endpoint-3 interrupt register */ + +#define STM32_OTGFS_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5)) +#define STM32_OTGFS_DOEPTSIZ0_OFFSET 0x00b10 /* Device OUT endpoint-0 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ1_OFFSET 0x00b30 /* Device OUT endpoint-1 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ2_OFFSET 0x00b50 /* Device OUT endpoint-2 transfer size register */ +#define STM32_OTGFS_DOEPTSIZ3_OFFSET 0x00b70 /* Device OUT endpoint-3 transfer size register */ + +/* Power and clock gating registers */ + +#define STM32_OTGFS_PCGCCTL_OFFSET 0x0e00 /* Power and clock gating control register */ + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGFS_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12)) +#define STM32_OTGFS_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12)) + +#define STM32_OTGFS_DFIFO_DEP0_OFFSET 0x1000 /* 0x1000-0x1ffc Device IN/OUT Endpoint 0 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH0_OFFSET 0x1000 /* 0x1000-0x1ffc Host OUT/IN Channel 0 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP1_OFFSET 0x2000 /* 0x2000-0x2ffc Device IN/OUT Endpoint 1 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH1_OFFSET 0x2000 /* 0x2000-0x2ffc Host OUT/IN Channel 1 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP2_OFFSET 0x3000 /* 0x3000-0x3ffc Device IN/OUT Endpoint 2 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH2_OFFSET 0x3000 /* 0x3000-0x3ffc Host OUT/IN Channel 2 DFIFO Read/Write Access */ + +#define STM32_OTGFS_DFIFO_DEP3_OFFSET 0x4000 /* 0x4000-0x4ffc Device IN/OUT Endpoint 3 DFIFO Write/Read Access */ +#define STM32_OTGFS_DFIFO_HCH3_OFFSET 0x4000 /* 0x4000-0x4ffc Host OUT/IN Channel 3 DFIFO Read/Write Access */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_OTGFS_GOTGCTL (STM32_OTGFS_BASE+STM32_OTGFS_GOTGCTL_OFFSET) +#define STM32_OTGFS_GOTGINT (STM32_OTGFS_BASE+STM32_OTGFS_GOTGINT_OFFSET) +#define STM32_OTGFS_GAHBCFG (STM32_OTGFS_BASE+STM32_OTGFS_GAHBCFG_OFFSET) +#define STM32_OTGFS_GUSBCFG (STM32_OTGFS_BASE+STM32_OTGFS_GUSBCFG_OFFSET) +#define STM32_OTGFS_GRSTCTL (STM32_OTGFS_BASE+STM32_OTGFS_GRSTCTL_OFFSET) +#define STM32_OTGFS_GINTSTS (STM32_OTGFS_BASE+STM32_OTGFS_GINTSTS_OFFSET) +#define STM32_OTGFS_GINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_GINTMSK_OFFSET) +#define STM32_OTGFS_GRXSTSR (STM32_OTGFS_BASE+STM32_OTGFS_GRXSTSR_OFFSET) +#define STM32_OTGFS_GRXSTSP (STM32_OTGFS_BASE+STM32_OTGFS_GRXSTSP_OFFSET) +#define STM32_OTGFS_GRXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_GRXFSIZ_OFFSET) +#define STM32_OTGFS_HNPTXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_HNPTXFSIZ_OFFSET) +#define STM32_OTGFS_DIEPTXF0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF0_OFFSET) +#define STM32_OTGFS_HNPTXSTS (STM32_OTGFS_BASE+STM32_OTGFS_HNPTXSTS_OFFSET) +#define STM32_OTGFS_GCCFG (STM32_OTGFS_BASE+STM32_OTGFS_GCCFG_OFFSET) +#define STM32_OTGFS_CID (STM32_OTGFS_BASE+STM32_OTGFS_CID_OFFSET) +#define STM32_OTGFS_HPTXFSIZ (STM32_OTGFS_BASE+STM32_OTGFS_HPTXFSIZ_OFFSET) + +#define STM32_OTGFS_DIEPTXF(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF_OFFSET(n)) +#define STM32_OTGFS_DIEPTXF1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF1_OFFSET) +#define STM32_OTGFS_DIEPTXF2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF2_OFFSET) +#define STM32_OTGFS_DIEPTXF3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTXF3_OFFSET) + +/* Host-mode control and status registers */ + +#define STM32_OTGFS_HCFG (STM32_OTGFS_BASE+STM32_OTGFS_HCFG_OFFSET) +#define STM32_OTGFS_HFIR (STM32_OTGFS_BASE+STM32_OTGFS_HFIR_OFFSET) +#define STM32_OTGFS_HFNUM (STM32_OTGFS_BASE+STM32_OTGFS_HFNUM_OFFSET) +#define STM32_OTGFS_HPTXSTS (STM32_OTGFS_BASE+STM32_OTGFS_HPTXSTS_OFFSET) +#define STM32_OTGFS_HAINT (STM32_OTGFS_BASE+STM32_OTGFS_HAINT_OFFSET) +#define STM32_OTGFS_HAINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_HAINTMSK_OFFSET) +#define STM32_OTGFS_HPRT (STM32_OTGFS_BASE+STM32_OTGFS_HPRT_OFFSET) + +#define STM32_OTGFS_CHAN(n) (STM32_OTGFS_BASE+STM32_OTGFS_CHAN_OFFSET(n)) + +#define STM32_OTGFS_HCCHAR(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR_OFFSET(n)) +#define STM32_OTGFS_HCCHAR0 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR0_OFFSET) +#define STM32_OTGFS_HCCHAR1 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR1_OFFSET) +#define STM32_OTGFS_HCCHAR2 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR2_OFFSET) +#define STM32_OTGFS_HCCHAR3 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR3_OFFSET) +#define STM32_OTGFS_HCCHAR4 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR4_OFFSET) +#define STM32_OTGFS_HCCHAR5 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR5_OFFSET) +#define STM32_OTGFS_HCCHAR6 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR6_OFFSET) +#define STM32_OTGFS_HCCHAR7 (STM32_OTGFS_BASE+STM32_OTGFS_HCCHAR7_OFFSET) + +#define STM32_OTGFS_HCINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCINT_OFFSET(n)) +#define STM32_OTGFS_HCINT0 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT0_OFFSET) +#define STM32_OTGFS_HCINT1 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT1_OFFSET) +#define STM32_OTGFS_HCINT2 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT2_OFFSET) +#define STM32_OTGFS_HCINT3 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT3_OFFSET) +#define STM32_OTGFS_HCINT4 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT4_OFFSET) +#define STM32_OTGFS_HCINT5 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT5_OFFSET) +#define STM32_OTGFS_HCINT6 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT6_OFFSET) +#define STM32_OTGFS_HCINT7 (STM32_OTGFS_BASE+STM32_OTGFS_HCINT7_OFFSET) + +#define STM32_OTGFS_HCINTMSK(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK_OFFSET(n)) +#define STM32_OTGFS_HCINTMSK0 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK0_OFFSET) +#define STM32_OTGFS_HCINTMSK1 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK1_OFFSET) +#define STM32_OTGFS_HCINTMSK2 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK2_OFFSET) +#define STM32_OTGFS_HCINTMSK3 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK3_OFFSET) +#define STM32_OTGFS_HCINTMSK4 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK4_OFFSET) +#define STM32_OTGFS_HCINTMSK5 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK5_OFFSET) +#define STM32_OTGFS_HCINTMSK6 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK6_OFFSET) +#define STM32_OTGFS_HCINTMSK7 (STM32_OTGFS_BASE+STM32_OTGFS_HCINTMSK7_OFFSET)_ + +#define STM32_OTGFS_HCTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ_OFFSET(n)) +#define STM32_OTGFS_HCTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ0_OFFSET) +#define STM32_OTGFS_HCTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ1_OFFSET) +#define STM32_OTGFS_HCTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ2_OFFSET) +#define STM32_OTGFS_HCTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ3_OFFSET) +#define STM32_OTGFS_HCTSIZ4 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ4_OFFSET) +#define STM32_OTGFS_HCTSIZ5 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ5_OFFSET) +#define STM32_OTGFS_HCTSIZ6 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ6_OFFSET) +#define STM32_OTGFS_HCTSIZ7 (STM32_OTGFS_BASE+STM32_OTGFS_HCTSIZ7_OFFSET) + +/* Device-mode control and status registers */ + +#define STM32_OTGFS_DCFG (STM32_OTGFS_BASE+STM32_OTGFS_DCFG_OFFSET) +#define STM32_OTGFS_DCTL (STM32_OTGFS_BASE+STM32_OTGFS_DCTL_OFFSET) +#define STM32_OTGFS_DSTS (STM32_OTGFS_BASE+STM32_OTGFS_DSTS_OFFSET) +#define STM32_OTGFS_DIEPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DIEPMSK_OFFSET) +#define STM32_OTGFS_DOEPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DOEPMSK_OFFSET) +#define STM32_OTGFS_DAINT (STM32_OTGFS_BASE+STM32_OTGFS_DAINT_OFFSET) +#define STM32_OTGFS_DAINTMSK (STM32_OTGFS_BASE+STM32_OTGFS_DAINTMSK_OFFSET) +#define STM32_OTGFS_DVBUSDIS (STM32_OTGFS_BASE+STM32_OTGFS_DVBUSDIS_OFFSET) +#define STM32_OTGFS_DVBUSPULSE (STM32_OTGFS_BASE+STM32_OTGFS_DVBUSPULSE_OFFSET) +#define STM32_OTGFS_DIEPEMPMSK (STM32_OTGFS_BASE+STM32_OTGFS_DIEPEMPMSK_OFFSET) + +#define STM32_OTGFS_DIEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEP_OFFSET(n)) + +#define STM32_OTGFS_DIEPCTL(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL_OFFSET(n)) +#define STM32_OTGFS_DIEPCTL0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL0_OFFSET) +#define STM32_OTGFS_DIEPCTL1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL1_OFFSET) +#define STM32_OTGFS_DIEPCTL2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL2_OFFSET) +#define STM32_OTGFS_DIEPCTL3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPCTL3_OFFSET) + +#define STM32_OTGFS_DIEPINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT_OFFSET(n)) +#define STM32_OTGFS_DIEPINT0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT0_OFFSET) +#define STM32_OTGFS_DIEPINT1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT1_OFFSET) +#define STM32_OTGFS_DIEPINT2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT2_OFFSET) +#define STM32_OTGFS_DIEPINT3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPINT3_OFFSET) + +#define STM32_OTGFS_DIEPTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ_OFFSET(n)) +#define STM32_OTGFS_DIEPTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ0_OFFSET) +#define STM32_OTGFS_DIEPTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ1_OFFSET) +#define STM32_OTGFS_DIEPTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ2_OFFSET) +#define STM32_OTGFS_DIEPTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_DIEPTSIZ3_OFFSET) + +#define STM32_OTGFS_DTXFSTS(n) (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS_OFFSET(n)) +#define STM32_OTGFS_DTXFSTS0 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS0_OFFSET) +#define STM32_OTGFS_DTXFSTS1 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS1_OFFSET) +#define STM32_OTGFS_DTXFSTS2 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS2_OFFSET) +#define STM32_OTGFS_DTXFSTS3 (STM32_OTGFS_BASE+STM32_OTGFS_DTXFSTS3_OFFSET) + +#define STM32_OTGFS_DOEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEP_OFFSET(n)) + +#define STM32_OTGFS_DOEPCTL(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL_OFFSET(n)) +#define STM32_OTGFS_DOEPCTL0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL0_OFFSET) +#define STM32_OTGFS_DOEPCTL1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL1_OFFSET) +#define STM32_OTGFS_DOEPCTL2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL2_OFFSET) +#define STM32_OTGFS_DOEPCTL3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPCTL3_OFFSET) + +#define STM32_OTGFS_DOEPINT(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT_OFFSET(n)) +#define STM32_OTGFS_DOEPINT0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT0_OFFSET) +#define STM32_OTGFS_DOEPINT1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT1_OFFSET) +#define STM32_OTGFS_DOEPINT2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT2_OFFSET) +#define STM32_OTGFS_DOEPINT3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPINT3_OFFSET) + +#define STM32_OTGFS_DOEPTSIZ(n) (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ_OFFSET(n)) +#define STM32_OTGFS_DOEPTSIZ0 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ0_OFFSET) +#define STM32_OTGFS_DOEPTSIZ1 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ1_OFFSET) +#define STM32_OTGFS_DOEPTSIZ2 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ2_OFFSET) +#define STM32_OTGFS_DOEPTSIZ3 (STM32_OTGFS_BASE+STM32_OTGFS_DOEPTSIZ3_OFFSET) + +/* Power and clock gating registers */ + +#define STM32_OTGFS_PCGCCTL (STM32_OTGFS_BASE+STM32_OTGFS_PCGCCTL_OFFSET) + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTGFS_DFIFO_DEP(n) (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP_OFFSET(n)) +#define STM32_OTGFS_DFIFO_HCH(n) (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH_OFFSET(n)) + +#define STM32_OTGFS_DFIFO_DEP0 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP0_OFFSET) +#define STM32_OTGFS_DFIFO_HCH0 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH0_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP1 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP1_OFFSET) +#define STM32_OTGFS_DFIFO_HCH1 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH1_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP2 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP2_OFFSET) +#define STM32_OTGFS_DFIFO_HCH2 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH2_OFFSET) + +#define STM32_OTGFS_DFIFO_DEP3 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_DEP3_OFFSET) +#define STM32_OTGFS_DFIFO_HCH3 (STM32_OTGFS_BASE+STM32_OTGFS_DFIFO_HCH3_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* Core global control and status registers */ + +/* Control and status register */ + +#define OTGFS_GOTGCTL_SRQSCS (1 << 0) /* Bit 0: Session request success */ +#define OTGFS_GOTGCTL_SRQ (1 << 1) /* Bit 1: Session request */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GOTGCTL_VBVALOEN (1 << 2) /* Bit 2: VBUS valid override enable */ +# define OTGFS_GOTGCTL_VBVALOVAL (1 << 3) /* Bit 3: VBUS valid override value */ +# define OTGFS_GOTGCTL_AVALOEN (1 << 4) /* Bit 4: A-peripheral session valid override enable */ +# define OTGFS_GOTGCTL_AVALOVAL (1 << 5) /* Bit 5: A-peripheral session valid override value */ +# define OTGFS_GOTGCTL_BVALOEN (1 << 6) /* Bit 6: B-peripheral session valid override enable */ +# define OTGFS_GOTGCTL_BVALOVAL (1 << 7) /* Bit 7: B-peripheral session valid override value */ +#endif +#define OTGFS_GOTGCTL_HNGSCS (1 << 8) /* Bit 8: Host negotiation success */ +#define OTGFS_GOTGCTL_HNPRQ (1 << 9) /* Bit 9: HNP request */ +#define OTGFS_GOTGCTL_HSHNPEN (1 << 10) /* Bit 10: host set HNP enable */ +#define OTGFS_GOTGCTL_DHNPEN (1 << 11) /* Bit 11: Device HNP enabled */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GOTGCTL_EHEN (1 << 12) /* Bit 12: Embedded host enable */ +#endif + /* Bits 13-15: Reserved, must be kept at reset value */ +#define OTGFS_GOTGCTL_CIDSTS (1 << 16) /* Bit 16: Connector ID status */ +#define OTGFS_GOTGCTL_DBCT (1 << 17) /* Bit 17: Long/short debounce time */ +#define OTGFS_GOTGCTL_ASVLD (1 << 18) /* Bit 18: A-session valid */ +#define OTGFS_GOTGCTL_BSVLD (1 << 19) /* Bit 19: B-session valid */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GOTGCTL_OTGVER (1 << 20) /* Bit 20: OTG version */ +#endif + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Interrupt register */ + /* Bits 1:0 Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_SEDET (1 << 2) /* Bit 2: Session end detected */ + /* Bits 3-7: Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_SRSSCHG (1 << 8) /* Bit 8: Session request success status change */ +#define OTGFS_GOTGINT_HNSSCHG (1 << 9) /* Bit 9: Host negotiation success status change */ + /* Bits 16:10 Reserved, must be kept at reset value */ +#define OTGFS_GOTGINT_HNGDET (1 << 17) /* Bit 17: Host negotiation detected */ +#define OTGFS_GOTGINT_ADTOCHG (1 << 18) /* Bit 18: A-device timeout change */ +#define OTGFS_GOTGINT_DBCDNE (1 << 19) /* Bit 19: Debounce done */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GOTGINT_IDCHNG (1 << 20) /* Bit 20: Change in ID pin input value */ +#endif + /* Bits 21-31: Reserved, must be kept at reset value */ + +/* AHB configuration register */ + +#define OTGFS_GAHBCFG_GINTMSK (1 << 0) /* Bit 0: Global interrupt mask */ + /* Bits 1-6: Reserved, must be kept at reset value */ +#define OTGFS_GAHBCFG_TXFELVL (1 << 7) /* Bit 7: TxFIFO empty level */ +#define OTGFS_GAHBCFG_PTXFELVL (1 << 8) /* Bit 8: Periodic TxFIFO empty level */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* USB configuration register */ + +#define OTGFS_GUSBCFG_TOCAL_SHIFT (0) /* Bits 0-2: FS timeout calibration */ +#define OTGFS_GUSBCFG_TOCAL_MASK (7 << OTGFS_GUSBCFG_TOCAL_SHIFT) + /* Bits 3-5: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_PHYSEL (1 << 6) /* Bit 6: Full Speed serial transceiver select */ + /* Bit 7: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_SRPCAP (1 << 8) /* Bit 8: SRP-capable */ +#define OTGFS_GUSBCFG_HNPCAP (1 << 9) /* Bit 9: HNP-capable */ +#define OTGFS_GUSBCFG_TRDT_SHIFT (10) /* Bits 10-13: USB turnaround time */ +#define OTGFS_GUSBCFG_TRDT_MASK (15 << OTGFS_GUSBCFG_TRDT_SHIFT) +# define OTGFS_GUSBCFG_TRDT(n) ((n) << OTGFS_GUSBCFG_TRDT_SHIFT) + /* Bits 14-28: Reserved, must be kept at reset value */ +#define OTGFS_GUSBCFG_FHMOD (1 << 29) /* Bit 29: Force host mode */ +#define OTGFS_GUSBCFG_FDMOD (1 << 30) /* Bit 30: Force device mode */ +#define OTGFS_GUSBCFG_CTXPKT (1 << 31) /* Bit 31: Corrupt Tx packet */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Reset register */ + +#define OTGFS_GRSTCTL_CSRST (1 << 0) /* Bit 0: Core soft reset */ +#define OTGFS_GRSTCTL_HSRST (1 << 1) /* Bit 1: HCLK soft reset */ +#define OTGFS_GRSTCTL_FCRST (1 << 2) /* Bit 2: Host frame counter reset */ + /* Bit 3 Reserved, must be kept at reset value */ +#define OTGFS_GRSTCTL_RXFFLSH (1 << 4) /* Bit 4: RxFIFO flush */ +#define OTGFS_GRSTCTL_TXFFLSH (1 << 5) /* Bit 5: TxFIFO flush */ +#define OTGFS_GRSTCTL_TXFNUM_SHIFT (6) /* Bits 6-10: TxFIFO number */ +#define OTGFS_GRSTCTL_TXFNUM_MASK (31 << OTGFS_GRSTCTL_TXFNUM_SHIFT) +# define OTGFS_GRSTCTL_TXFNUM_HNONPER (0 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Non-periodic TxFIFO flush in host mode */ +# define OTGFS_GRSTCTL_TXFNUM_HPER (1 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Periodic TxFIFO flush in host mode */ +# define OTGFS_GRSTCTL_TXFNUM_HALL (16 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in host mode.*/ +# define OTGFS_GRSTCTL_TXFNUM_D(n) ((n) << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* TXFIFO n flush in device mode, n=0-15 */ +# define OTGFS_GRSTCTL_TXFNUM_DALL (16 << OTGFS_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in device mode.*/ + /* Bits 11-31: Reserved, must be kept at reset value */ +#define OTGFS_GRSTCTL_AHBIDL (1 << 31) /* Bit 31: AHB master idle */ + +/* Core interrupt and Interrupt mask registers */ + +#define OTGFS_GINTSTS_CMOD (1 << 0) /* Bit 0: Current mode of operation */ +# define OTGFS_GINTSTS_DEVMODE (0) +# define OTGFS_GINTSTS_HOSTMODE (OTGFS_GINTSTS_CMOD) +#define OTGFS_GINT_MMIS (1 << 1) /* Bit 1: Mode mismatch interrupt */ +#define OTGFS_GINT_OTG (1 << 2) /* Bit 2: OTG interrupt */ +#define OTGFS_GINT_SOF (1 << 3) /* Bit 3: Start of frame */ +#define OTGFS_GINT_RXFLVL (1 << 4) /* Bit 4: RxFIFO non-empty */ +#define OTGFS_GINT_NPTXFE (1 << 5) /* Bit 5: Non-periodic TxFIFO empty */ +#define OTGFS_GINT_GINAKEFF (1 << 6) /* Bit 6: Global IN non-periodic NAK effective */ +#define OTGFS_GINT_GONAKEFF (1 << 7) /* Bit 7: Global OUT NAK effective */ + /* Bits 8-9: Reserved, must be kept at reset value */ +#define OTGFS_GINT_ESUSP (1 << 10) /* Bit 10: Early suspend */ +#define OTGFS_GINT_USBSUSP (1 << 11) /* Bit 11: USB suspend */ +#define OTGFS_GINT_USBRST (1 << 12) /* Bit 12: USB reset */ +#define OTGFS_GINT_ENUMDNE (1 << 13) /* Bit 13: Enumeration done */ +#define OTGFS_GINT_ISOODRP (1 << 14) /* Bit 14: Isochronous OUT packet dropped interrupt */ +#define OTGFS_GINT_EOPF (1 << 15) /* Bit 15: End of periodic frame interrupt */ + /* Bits 16 Reserved, must be kept at reset value */ +#define OTGFS_GINTMSK_EPMISM (1 << 17) /* Bit 17: Endpoint mismatch interrupt mask */ +#define OTGFS_GINT_IEP (1 << 18) /* Bit 18: IN endpoint interrupt */ +#define OTGFS_GINT_OEP (1 << 19) /* Bit 19: OUT endpoint interrupt */ +#define OTGFS_GINT_IISOIXFR (1 << 20) /* Bit 20: Incomplete isochronous IN transfer */ +#define OTGFS_GINT_IISOOXFR (1 << 21) /* Bit 21: Incomplete isochronous OUT transfer (device) */ +#define OTGFS_GINT_IPXFR (1 << 21) /* Bit 21: Incomplete periodic transfer (host) */ + /* Bit 22: Reserved, must be kept at reset value */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GINT_RSTDET (1 << 23) /* Bit 23: Reset detected interrupt */ +#endif +#define OTGFS_GINT_HPRT (1 << 24) /* Bit 24: Host port interrupt */ +#define OTGFS_GINT_HC (1 << 25) /* Bit 25: Host channels interrupt */ +#define OTGFS_GINT_PTXFE (1 << 26) /* Bit 26: Periodic TxFIFO empty */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GINT_LPMINT (1 << 27) /* Bit 27: LPM interrupt */ +#endif +#define OTGFS_GINT_CIDSCHG (1 << 28) /* Bit 28: Connector ID status change */ +#define OTGFS_GINT_DISC (1 << 29) /* Bit 29: Disconnect detected interrupt */ +#define OTGFS_GINT_SRQ (1 << 30) /* Bit 30: Session request/new session detected interrupt */ +#define OTGFS_GINT_WKUP (1 << 31) /* Bit 31: Resume/remote wakeup detected interrupt */ + +/* Receive status debug read/OTG status read and pop registers (host mode) */ + +#define OTGFS_GRXSTSH_CHNUM_SHIFT (0) /* Bits 0-3: Channel number */ +#define OTGFS_GRXSTSH_CHNUM_MASK (15 << OTGFS_GRXSTSH_CHNUM_SHIFT) +#define OTGFS_GRXSTSH_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGFS_GRXSTSH_BCNT_MASK (0x7ff << OTGFS_GRXSTSH_BCNT_SHIFT) +#define OTGFS_GRXSTSH_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGFS_GRXSTSH_DPID_MASK (3 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA0 (0 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA2 (1 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_DATA1 (2 << OTGFS_GRXSTSH_DPID_SHIFT) +# define OTGFS_GRXSTSH_DPID_MDATA (3 << OTGFS_GRXSTSH_DPID_SHIFT) +#define OTGFS_GRXSTSH_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGFS_GRXSTSH_PKTSTS_MASK (15 << OTGFS_GRXSTSH_PKTSTS_SHIFT) +# define OTGFS_GRXSTSH_PKTSTS_INRECVD (2 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* IN data packet received */ +# define OTGFS_GRXSTSH_PKTSTS_INDONE (3 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* IN transfer completed */ +# define OTGFS_GRXSTSH_PKTSTS_DTOGERR (5 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* Data toggle error */ +# define OTGFS_GRXSTSH_PKTSTS_HALTED (7 << OTGFS_GRXSTSH_PKTSTS_SHIFT) /* Channel halted */ + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Receive status debug read/OTG status read and pop registers (device mode) */ + +#define OTGFS_GRXSTSD_EPNUM_SHIFT (0) /* Bits 0-3: Endpoint number */ +#define OTGFS_GRXSTSD_EPNUM_MASK (15 << OTGFS_GRXSTSD_EPNUM_SHIFT) +#define OTGFS_GRXSTSD_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTGFS_GRXSTSD_BCNT_MASK (0x7ff << OTGFS_GRXSTSD_BCNT_SHIFT) +#define OTGFS_GRXSTSD_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTGFS_GRXSTSD_DPID_MASK (3 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA0 (0 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA2 (1 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_DATA1 (2 << OTGFS_GRXSTSD_DPID_SHIFT) +# define OTGFS_GRXSTSD_DPID_MDATA (3 << OTGFS_GRXSTSD_DPID_SHIFT) +#define OTGFS_GRXSTSD_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTGFS_GRXSTSD_PKTSTS_MASK (15 << OTGFS_GRXSTSD_PKTSTS_SHIFT) +# define OTGFS_GRXSTSD_PKTSTS_OUTNAK (1 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* Global OUT NAK */ +# define OTGFS_GRXSTSD_PKTSTS_OUTRECVD (2 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* OUT data packet received */ +# define OTGFS_GRXSTSD_PKTSTS_OUTDONE (3 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* OUT transfer completed */ +# define OTGFS_GRXSTSD_PKTSTS_SETUPDONE (4 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* SETUP transaction completed */ +# define OTGFS_GRXSTSD_PKTSTS_SETUPRECVD (6 << OTGFS_GRXSTSD_PKTSTS_SHIFT) /* SETUP data packet received */ +#define OTGFS_GRXSTSD_FRMNUM_SHIFT (21) /* Bits 21-24: Frame number */ +#define OTGFS_GRXSTSD_FRMNUM_MASK (15 << OTGFS_GRXSTSD_FRMNUM_SHIFT) + /* Bits 25-31: Reserved, must be kept at reset value */ +/* Receive FIFO size register */ + +#define OTGFS_GRXFSIZ_MASK (0xffff) + +/* Host non-periodic transmit FIFO size register */ + +#define OTGFS_HNPTXFSIZ_NPTXFSA_SHIFT (0) /* Bits 0-15: Non-periodic transmit RAM start address */ +#define OTGFS_HNPTXFSIZ_NPTXFSA_MASK (0xffff << OTGFS_HNPTXFSIZ_NPTXFSA_SHIFT) +#define OTGFS_HNPTXFSIZ_NPTXFD_SHIFT (16) /* Bits 16-31: Non-periodic TxFIFO depth */ +#define OTGFS_HNPTXFSIZ_NPTXFD_MASK (0xffff << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGFS_HNPTXFSIZ_NPTXFD_MIN (16 << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTGFS_HNPTXFSIZ_NPTXFD_MAX (256 << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT) + +/* Endpoint 0 Transmit FIFO size */ + +#define OTGFS_DIEPTXF0_TX0FD_SHIFT (0) /* Bits 0-15: Endpoint 0 transmit RAM start address */ +#define OTGFS_DIEPTXF0_TX0FD_MASK (0xffff << OTGFS_DIEPTXF0_TX0FD_SHIFT) +#define OTGFS_DIEPTXF0_TX0FSA_SHIFT (16) /* Bits 16-31: Endpoint 0 TxFIFO depth */ +#define OTGFS_DIEPTXF0_TX0FSA_MASK (0xffff << OTGFS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGFS_DIEPTXF0_TX0FSA_MIN (16 << OTGFS_DIEPTXF0_TX0FSA_SHIFT) +# define OTGFS_DIEPTXF0_TX0FSA_MAX (256 << OTGFS_DIEPTXF0_TX0FSA_SHIFT) + +/* Non-periodic transmit FIFO/queue status register */ + +#define OTGFS_HNPTXSTS_NPTXFSAV_SHIFT (0) /* Bits 0-15: Non-periodic TxFIFO space available */ +#define OTGFS_HNPTXSTS_NPTXFSAV_MASK (0xffff << OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) +# define OTGFS_HNPTXSTS_NPTXFSAV_FULL (0 << OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) +#define OTGFS_HNPTXSTS_NPTQXSAV_SHIFT (16) /* Bits 16-23: Non-periodic transmit request queue space available */ +#define OTGFS_HNPTXSTS_NPTQXSAV_MASK (0xff << OTGFS_HNPTXSTS_NPTQXSAV_SHIFT) +# define OTGFS_HNPTXSTS_NPTQXSAV_FULL (0 << OTGFS_HNPTXSTS_NPTQXSAV_SHIFT) +#define OTGFS_HNPTXSTS_NPTXQTOP_SHIFT (24) /* Bits 24-30: Top of the non-periodic transmit request queue */ +#define OTGFS_HNPTXSTS_NPTXQTOP_MASK (0x7f << OTGFS_HNPTXSTS_NPTXQTOP_SHIFT) +# define OTGFS_HNPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGFS_HNPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Status */ +# define OTGFS_HNPTXSTS_TYPE_MASK (3 << OTGFS_HNPTXSTS_TYPE_SHIFT) +# define OTGFS_HNPTXSTS_TYPE_INOUT (0 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGFS_HNPTXSTS_TYPE_ZLP (1 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet (device IN/host OUT) */ +# define OTGFS_HNPTXSTS_TYPE_HALT (3 << OTGFS_HNPTXSTS_TYPE_SHIFT) /* Channel halt command */ +# define OTGFS_HNPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGFS_HNPTXSTS_CHNUM_MASK (15 << OTGFS_HNPTXSTS_CHNUM_SHIFT) +# define OTGFS_HNPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGFS_HNPTXSTS_EPNUM_MASK (15 << OTGFS_HNPTXSTS_EPNUM_SHIFT) + /* Bit 31 Reserved, must be kept at reset value */ +/* General core configuration register */ + /* Bits 0-15: Reserved, must be kept at reset value */ +#define OTGFS_GCCFG_PWRDWN (1 << 16) /* Bit 16: Power down */ + /* Bit 17 Reserved, must be kept at reset value */ +#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +# define OTGFS_GCCFG_VBDEN (1 << 21) /* Bit 21: USB VBUS detection enable */ +#else +# define OTGFS_GCCFG_VBUSASEN (1 << 18) /* Bit 18: Enable the VBUS sensing A device */ +# define OTGFS_GCCFG_VBUSBSEN (1 << 19) /* Bit 19: Enable the VBUS sensing B device */ +# define OTGFS_GCCFG_SOFOUTEN (1 << 20) /* Bit 20: SOF output enable */ +# define OTGFS_GCCFG_NOVBUSSENS (1 << 21) /* Bit 21: VBUS sensing disable option */ +#endif + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Core ID register (32-bit product ID) */ + +/* Host periodic transmit FIFO size register */ + +#define OTGFS_HPTXFSIZ_PTXSA_SHIFT (0) /* Bits 0-15: Host periodic TxFIFO start address */ +#define OTGFS_HPTXFSIZ_PTXSA_MASK (0xffff << OTGFS_HPTXFSIZ_PTXSA_SHIFT) +#define OTGFS_HPTXFSIZ_PTXFD_SHIFT (16) /* Bits 16-31: Host periodic TxFIFO depth */ +#define OTGFS_HPTXFSIZ_PTXFD_MASK (0xffff << OTGFS_HPTXFSIZ_PTXFD_SHIFT) + +/* Device IN endpoint transmit FIFOn size register */ + +#define OTGFS_DIEPTXF_INEPTXSA_SHIFT (0) /* Bits 0-15: IN endpoint FIFOx transmit RAM start address */ +#define OTGFS_DIEPTXF_INEPTXSA_MASK (0xffff << OTGFS_DIEPTXF_INEPTXSA_SHIFT) +#define OTGFS_DIEPTXF_INEPTXFD_SHIFT (16) /* Bits 16-31: IN endpoint TxFIFO depth */ +#define OTGFS_DIEPTXF_INEPTXFD_MASK (0xffff << OTGFS_DIEPTXF_INEPTXFD_SHIFT) +# define OTGFS_DIEPTXF_INEPTXFD_MIN (16 << OTGFS_DIEPTXF_INEPTXFD_MASK) + +/* Host-mode control and status registers */ + +/* Host configuration register */ + +#define OTGFS_HCFG_FSLSPCS_SHIFT (0) /* Bits 0-1: FS/LS PHY clock select */ +#define OTGFS_HCFG_FSLSPCS_MASK (3 << OTGFS_HCFG_FSLSPCS_SHIFT) +# define OTGFS_HCFG_FSLSPCS_FS48MHz (1 << OTGFS_HCFG_FSLSPCS_SHIFT) /* FS host mode, PHY clock is running at 48 MHz */ +# define OTGFS_HCFG_FSLSPCS_LS48MHz (1 << OTGFS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 48 MHz PHY clock frequency */ +# define OTGFS_HCFG_FSLSPCS_LS6MHz (2 << OTGFS_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 6 MHz PHY clock frequency */ +#define OTGFS_HCFG_FSLSS (1 << 2) /* Bit 2: FS- and LS-only support */ + /* Bits 31:3 Reserved, must be kept at reset value */ +/* Host frame interval register */ + +#define OTGFS_HFIR_MASK (0xffff) + +/* Host frame number/frame time remaining register */ + +#define OTGFS_HFNUM_FRNUM_SHIFT (0) /* Bits 0-15: Frame number */ +#define OTGFS_HFNUM_FRNUM_MASK (0xffff << OTGFS_HFNUM_FRNUM_SHIFT) +#define OTGFS_HFNUM_FTREM_SHIFT (16) /* Bits 16-31: Frame time remaining */ +#define OTGFS_HFNUM_FTREM_MASK (0xffff << OTGFS_HFNUM_FTREM_SHIFT) + +/* Host periodic transmit FIFO/queue status register */ + +#define OTGFS_HPTXSTS_PTXFSAVL_SHIFT (0) /* Bits 0-15: Periodic transmit data FIFO space available */ +#define OTGFS_HPTXSTS_PTXFSAVL_MASK (0xffff << OTGFS_HPTXSTS_PTXFSAVL_SHIFT) +# define OTGFS_HPTXSTS_PTXFSAVL_FULL (0 << OTGFS_HPTXSTS_PTXFSAVL_SHIFT) +#define OTGFS_HPTXSTS_PTXQSAV_SHIFT (16) /* Bits 16-23: Periodic transmit request queue space available */ +#define OTGFS_HPTXSTS_PTXQSAV_MASK (0xff << OTGFS_HPTXSTS_PTXQSAV_SHIFT) +# define OTGFS_HPTXSTS_PTXQSAV_FULL (0 << OTGFS_HPTXSTS_PTXQSAV_SHIFT) +#define OTGFS_HPTXSTS_PTXQTOP_SHIFT (24) /* Bits 24-31: Top of the periodic transmit request queue */ +#define OTGFS_HPTXSTS_PTXQTOP_MASK (0x7f << OTGFS_HPTXSTS_PTXQTOP_SHIFT) +# define OTGFS_HPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTGFS_HPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Type */ +# define OTGFS_HPTXSTS_TYPE_MASK (3 << OTGFS_HPTXSTS_TYPE_SHIFT) +# define OTGFS_HPTXSTS_TYPE_INOUT (0 << OTGFS_HPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTGFS_HPTXSTS_TYPE_ZLP (1 << OTGFS_HPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet */ +# define OTGFS_HPTXSTS_TYPE_HALT (3 << OTGFS_HPTXSTS_TYPE_SHIFT) /* Disable channel command */ +# define OTGFS_HPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTGFS_HPTXSTS_EPNUM_MASK (15 << OTGFS_HPTXSTS_EPNUM_SHIFT) +# define OTGFS_HPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTGFS_HPTXSTS_CHNUM_MASK (15 << OTGFS_HPTXSTS_CHNUM_SHIFT) +# define OTGFS_HPTXSTS_ODD (1 << 24) /* Bit 31: Send in odd (vs even) frame */ + +/* Host all channels interrupt and all channels interrupt mask registers */ + +#define OTGFS_HAINT(n) (1 << (n)) /* Bits 15:0 HAINTM: Channel interrupt */ + +/* Host port control and status register */ + +#define OTGFS_HPRT_PCSTS (1 << 0) /* Bit 0: Port connect status */ +#define OTGFS_HPRT_PCDET (1 << 1) /* Bit 1: Port connect detected */ +#define OTGFS_HPRT_PENA (1 << 2) /* Bit 2: Port enable */ +#define OTGFS_HPRT_PENCHNG (1 << 3) /* Bit 3: Port enable/disable change */ +#define OTGFS_HPRT_POCA (1 << 4) /* Bit 4: Port overcurrent active */ +#define OTGFS_HPRT_POCCHNG (1 << 5) /* Bit 5: Port overcurrent change */ +#define OTGFS_HPRT_PRES (1 << 6) /* Bit 6: Port resume */ +#define OTGFS_HPRT_PSUSP (1 << 7) /* Bit 7: Port suspend */ +#define OTGFS_HPRT_PRST (1 << 8) /* Bit 8: Port reset */ + /* Bit 9: Reserved, must be kept at reset value */ +#define OTGFS_HPRT_PLSTS_SHIFT (10) /* Bits 10-11: Port line status */ +#define OTGFS_HPRT_PLSTS_MASK (3 << OTGFS_HPRT_PLSTS_SHIFT) +# define OTGFS_HPRT_PLSTS_DP (1 << 10) /* Bit 10: Logic level of OTG_FS_FS_DP */ +# define OTGFS_HPRT_PLSTS_DM (1 << 11) /* Bit 11: Logic level of OTG_FS_FS_DM */ +#define OTGFS_HPRT_PPWR (1 << 12) /* Bit 12: Port power */ +#define OTGFS_HPRT_PTCTL_SHIFT (13) /* Bits 13-16: Port test control */ +#define OTGFS_HPRT_PTCTL_MASK (15 << OTGFS_HPRT_PTCTL_SHIFT) +# define OTGFS_HPRT_PTCTL_DISABLED (0 << OTGFS_HPRT_PTCTL_SHIFT) /* Test mode disabled */ +# define OTGFS_HPRT_PTCTL_J (1 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_J mode */ +# define OTGFS_HPRT_PTCTL_L (2 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_K mode */ +# define OTGFS_HPRT_PTCTL_SE0_NAK (3 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGFS_HPRT_PTCTL_PACKET (4 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_Packet mode */ +# define OTGFS_HPRT_PTCTL_FORCE (5 << OTGFS_HPRT_PTCTL_SHIFT) /* Test_Force_Enable */ +#define OTGFS_HPRT_PSPD_SHIFT (17) /* Bits 17-18: Port speed */ +#define OTGFS_HPRT_PSPD_MASK (3 << OTGFS_HPRT_PSPD_SHIFT) +# define OTGFS_HPRT_PSPD_FS (1 << OTGFS_HPRT_PSPD_SHIFT) /* Full speed */ +# define OTGFS_HPRT_PSPD_LS (2 << OTGFS_HPRT_PSPD_SHIFT) /* Low speed */ + /* Bits 19-31: Reserved, must be kept at reset value */ + +/* Host channel-n characteristics register */ + +#define OTGFS_HCCHAR_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_HCCHAR_MPSIZ_MASK (0x7ff << OTGFS_HCCHAR_MPSIZ_SHIFT) +#define OTGFS_HCCHAR_EPNUM_SHIFT (11) /* Bits 11-14: Endpoint number */ +#define OTGFS_HCCHAR_EPNUM_MASK (15 << OTGFS_HCCHAR_EPNUM_SHIFT) +#define OTGFS_HCCHAR_EPDIR (1 << 15) /* Bit 15: Endpoint direction */ +# define OTGFS_HCCHAR_EPDIR_OUT (0) +# define OTGFS_HCCHAR_EPDIR_IN OTGFS_HCCHAR_EPDIR + /* Bit 16 Reserved, must be kept at reset value */ +#define OTGFS_HCCHAR_LSDEV (1 << 17) /* Bit 17: Low-speed device */ +#define OTGFS_HCCHAR_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_HCCHAR_EPTYP_MASK (3 << OTGFS_HCCHAR_EPTYP_SHIFT) +# define OTGFS_HCCHAR_EPTYP_CTRL (0 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Control */ +# define OTGFS_HCCHAR_EPTYP_ISOC (1 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_HCCHAR_EPTYP_BULK (2 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_HCCHAR_EPTYP_INTR (3 << OTGFS_HCCHAR_EPTYP_SHIFT) /* Interrupt */ +#define OTGFS_HCCHAR_MCNT_SHIFT (20) /* Bits 20-21: Multicount */ +#define OTGFS_HCCHAR_MCNT_MASK (3 << OTGFS_HCCHAR_MCNT_SHIFT) +#define OTGFS_HCCHAR_DAD_SHIFT (22) /* Bits 22-28: Device address */ +#define OTGFS_HCCHAR_DAD_MASK (0x7f << OTGFS_HCCHAR_DAD_SHIFT) +#define OTGFS_HCCHAR_ODDFRM (1 << 29) /* Bit 29: Odd frame */ +#define OTGFS_HCCHAR_CHDIS (1 << 30) /* Bit 30: Channel disable */ +#define OTGFS_HCCHAR_CHENA (1 << 31) /* Bit 31: Channel enable */ + +/* Host channel-n interrupt and Host channel-0 interrupt mask registers */ + +#define OTGFS_HCINT_XFRC (1 << 0) /* Bit 0: Transfer completed */ +#define OTGFS_HCINT_CHH (1 << 1) /* Bit 1: Channel halted */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_HCINT_STALL (1 << 3) /* Bit 3: STALL response received interrupt */ +#define OTGFS_HCINT_NAK (1 << 4) /* Bit 4: NAK response received interrupt */ +#define OTGFS_HCINT_ACK (1 << 5) /* Bit 5: ACK response received/transmitted interrupt */ +#define OTGFS_HCINT_NYET (1 << 6) /* Bit 6: Response received interrupt */ +#define OTGFS_HCINT_TXERR (1 << 7) /* Bit 7: Transaction error */ +#define OTGFS_HCINT_BBERR (1 << 8) /* Bit 8: Babble error */ +#define OTGFS_HCINT_FRMOR (1 << 9) /* Bit 9: Frame overrun */ +#define OTGFS_HCINT_DTERR (1 << 10) /* Bit 10: Data toggle error */ + /* Bits 11-31 Reserved, must be kept at reset value */ +/* Host channel-n interrupt register */ + +#define OTGFS_HCTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_HCTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_HCTSIZ_XFRSIZ_SHIFT) +#define OTGFS_HCTSIZ_PKTCNT_SHIFT (19) /* Bits 19-28: Packet count */ +#define OTGFS_HCTSIZ_PKTCNT_MASK (0x3ff << OTGFS_HCTSIZ_PKTCNT_SHIFT) +#define OTGFS_HCTSIZ_DPID_SHIFT (29) /* Bits 29-30: Data PID */ +#define OTGFS_HCTSIZ_DPID_MASK (3 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA0 (0 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA2 (1 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_DATA1 (2 << OTGFS_HCTSIZ_DPID_SHIFT) +# define OTGFS_HCTSIZ_DPID_MDATA (3 << OTGFS_HCTSIZ_DPID_SHIFT) /* Non-control */ +# define OTGFS_HCTSIZ_PID_SETUP (3 << OTGFS_HCTSIZ_DPID_SHIFT) /* Control */ + /* Bit 31 Reserved, must be kept at reset value */ +/* Device-mode control and status registers */ + +/* Device configuration register */ + +#define OTGFS_DCFG_DSPD_SHIFT (0) /* Bits 0-1: Device speed */ +#define OTGFS_DCFG_DSPD_MASK (3 << OTGFS_DCFG_DSPD_SHIFT) +# define OTGFS_DCFG_DSPD_FS (3 << OTGFS_DCFG_DSPD_SHIFT) /* Full speed */ +#define OTGFS_DCFG_NZLSOHSK (1 << 2) /* Bit 2: Non-zero-length status OUT handshake */ + /* Bit 3: Reserved, must be kept at reset value */ +#define OTGFS_DCFG_DAD_SHIFT (4) /* Bits 4-10: Device address */ +#define OTGFS_DCFG_DAD_MASK (0x7f << OTGFS_DCFG_DAD_SHIFT) +#define OTGFS_DCFG_PFIVL_SHIFT (11) /* Bits 11-12: Periodic frame interval */ +#define OTGFS_DCFG_PFIVL_MASK (3 << OTGFS_DCFG_PFIVL_SHIFT) +# define OTGFS_DCFG_PFIVL_80PCT (0 << OTGFS_DCFG_PFIVL_SHIFT) /* 80% of the frame interval */ +# define OTGFS_DCFG_PFIVL_85PCT (1 << OTGFS_DCFG_PFIVL_SHIFT) /* 85% of the frame interval */ +# define OTGFS_DCFG_PFIVL_90PCT (2 << OTGFS_DCFG_PFIVL_SHIFT) /* 90% of the frame interval */ +# define OTGFS_DCFG_PFIVL_95PCT (3 << OTGFS_DCFG_PFIVL_SHIFT) /* 95% of the frame interval */ + /* Bits 13-31 Reserved, must be kept at reset value */ +/* Device control register */ + +#define OTGFS_TESTMODE_DISABLED (0) /* Test mode disabled */ +#define OTGFS_TESTMODE_J (1) /* Test_J mode */ +#define OTGFS_TESTMODE_K (2) /* Test_K mode */ +#define OTGFS_TESTMODE_SE0_NAK (3) /* Test_SE0_NAK mode */ +#define OTGFS_TESTMODE_PACKET (4) /* Test_Packet mode */ +#define OTGFS_TESTMODE_FORCE (5) /* Test_Force_Enable */ + +#define OTGFS_DCTL_RWUSIG (1 << 0) /* Bit 0: Remote wakeup signaling */ +#define OTGFS_DCTL_SDIS (1 << 1) /* Bit 1: Soft disconnect */ +#define OTGFS_DCTL_GINSTS (1 << 2) /* Bit 2: Global IN NAK status */ +#define OTGFS_DCTL_GONSTS (1 << 3) /* Bit 3: Global OUT NAK status */ +#define OTGFS_DCTL_TCTL_SHIFT (4) /* Bits 4-6: Test control */ +#define OTGFS_DCTL_TCTL_MASK (7 << OTGFS_DCTL_TCTL_SHIFT) +# define OTGFS_DCTL_TCTL_DISABLED (0 << OTGFS_DCTL_TCTL_SHIFT) /* Test mode disabled */ +# define OTGFS_DCTL_TCTL_J (1 << OTGFS_DCTL_TCTL_SHIFT) /* Test_J mode */ +# define OTGFS_DCTL_TCTL_K (2 << OTGFS_DCTL_TCTL_SHIFT) /* Test_K mode */ +# define OTGFS_DCTL_TCTL_SE0_NAK (3 << OTGFS_DCTL_TCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTGFS_DCTL_TCTL_PACKET (4 << OTGFS_DCTL_TCTL_SHIFT) /* Test_Packet mode */ +# define OTGFS_DCTL_TCTL_FORCE (5 << OTGFS_DCTL_TCTL_SHIFT) /* Test_Force_Enable */ +#define OTGFS_DCTL_SGINAK (1 << 7) /* Bit 7: Set global IN NAK */ +#define OTGFS_DCTL_CGINAK (1 << 8) /* Bit 8: Clear global IN NAK */ +#define OTGFS_DCTL_SGONAK (1 << 9) /* Bit 9: Set global OUT NAK */ +#define OTGFS_DCTL_CGONAK (1 << 10) /* Bit 10: Clear global OUT NAK */ +#define OTGFS_DCTL_POPRGDNE (1 << 11) /* Bit 11: Power-on programming done */ + /* Bits 12-31: Reserved, must be kept at reset value */ +/* Device status register */ + +#define OTGFS_DSTS_SUSPSTS (1 << 0) /* Bit 0: Suspend status */ +#define OTGFS_DSTS_ENUMSPD_SHIFT (1) /* Bits 1-2: Enumerated speed */ +#define OTGFS_DSTS_ENUMSPD_MASK (3 << OTGFS_DSTS_ENUMSPD_SHIFT) +# define OTGFS_DSTS_ENUMSPD_FS (3 << OTGFS_DSTS_ENUMSPD_MASK) /* Full speed */ + /* Bits 4-7: Reserved, must be kept at reset value */ +#define OTGFS_DSTS_EERR (1 << 3) /* Bit 3: Erratic error */ +#define OTGFS_DSTS_SOFFN_SHIFT (8) /* Bits 8-21: Frame number of the received SOF */ +#define OTGFS_DSTS_SOFFN_MASK (0x3fff << OTGFS_DSTS_SOFFN_SHIFT) +#define OTGFS_DSTS_SOFFN0 (1 << 8) /* Bits 8: Frame number even/odd bit */ +#define OTGFS_DSTS_SOFFN_EVEN 0 +#define OTGFS_DSTS_SOFFN_ODD OTGFS_DSTS_SOFFN0 + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Device IN endpoint common interrupt mask register */ + +#define OTGFS_DIEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGFS_DIEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DIEPMSK_TOM (1 << 3) /* Bit 3: Timeout condition mask (Non-isochronous endpoints) */ +#define OTGFS_DIEPMSK_ITTXFEMSK (1 << 4) /* Bit 4: IN token received when TxFIFO empty mask */ +#define OTGFS_DIEPMSK_INEPNMM (1 << 5) /* Bit 5: IN token received with EP mismatch mask */ +#define OTGFS_DIEPMSK_INEPNEM (1 << 6) /* Bit 6: IN endpoint NAK effective mask */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint common interrupt mask register */ + +#define OTGFS_DOEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTGFS_DOEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DOEPMSK_STUPM (1 << 3) /* Bit 3: SETUP phase done mask */ +#define OTGFS_DOEPMSK_OTEPDM (1 << 4) /* Bit 4: OUT token received when endpoint disabled mask */ + /* Bits 5-31: Reserved, must be kept at reset value */ +/* Device all endpoints interrupt and All endpoints interrupt mask registers */ + +#define OTGFS_DAINT_IEP_SHIFT (0) /* Bits 0-15: IN endpoint interrupt bits */ +#define OTGFS_DAINT_IEP_MASK (0xffff << OTGFS_DAINT_IEP_SHIFT) +# define OTGFS_DAINT_IEP(n) (1 << (n)) +#define OTGFS_DAINT_OEP_SHIFT (16) /* Bits 16-31: OUT endpoint interrupt bits */ +#define OTGFS_DAINT_OEP_MASK (0xffff << OTGFS_DAINT_OEP_SHIFT) +# define OTGFS_DAINT_OEP(n) (1 << ((n)+16)) + +/* Device VBUS discharge time register */ + +#define OTGFS_DVBUSDIS_MASK (0xffff) + +/* Device VBUS pulsing time register */ + +#define OTGFS_DVBUSPULSE_MASK (0xfff) + +/* Device IN endpoint FIFO empty interrupt mask register */ + +#define OTGFS_DIEPEMPMSK(n) (1 << (n)) + +/* Device control IN endpoint 0 control register */ + +#define OTGFS_DIEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGFS_DIEPCTL0_MPSIZ_MASK (3 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) +# define OTGFS_DIEPCTL0_MPSIZ_64 (0 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_32 (1 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_16 (2 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGFS_DIEPCTL0_MPSIZ_8 (3 << OTGFS_DIEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DIEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DIEPCTL0_EPTYP_MASK (3 << OTGFS_DIEPCTL0_EPTYP_SHIFT) +# define OTGFS_DIEPCTL0_EPTYP_CTRL (0 << OTGFS_DIEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGFS_DIEPCTL0_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGFS_DIEPCTL0_TXFNUM_MASK (15 << OTGFS_DIEPCTL0_TXFNUM_SHIFT) +#define OTGFS_DIEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DIEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DIEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device control IN endpoint n control register */ + +#define OTGFS_DIEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_DIEPCTL_MPSIZ_MASK (0x7ff << OTGFS_DIEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGFS_DIEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame */ +# define OTGFS_DIEPCTL_EVEN (0) +# define OTGFS_DIEPCTL_ODD OTGFS_DIEPCTL_EONUM +# define OTGFS_DIEPCTL_DATA0 (0) +# define OTGFS_DIEPCTL_DATA1 OTGFS_DIEPCTL_EONUM +#define OTGFS_DIEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DIEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DIEPCTL_EPTYP_MASK (3 << OTGFS_DIEPCTL_EPTYP_SHIFT) +# define OTGFS_DIEPCTL_EPTYP_CTRL (0 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGFS_DIEPCTL_EPTYP_ISOC (1 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_DIEPCTL_EPTYP_BULK (2 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_DIEPCTL_EPTYP_INTR (3 << OTGFS_DIEPCTL_EPTYP_SHIFT) /* Interrupt */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTGFS_DIEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTGFS_DIEPCTL_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTGFS_DIEPCTL_TXFNUM_MASK (15 << OTGFS_DIEPCTL_TXFNUM_SHIFT) +#define OTGFS_DIEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DIEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGFS_DIEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGFS_DIEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous)) */ +#define OTGFS_DIEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous) */ +#define OTGFS_DIEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DIEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGFS_DIEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGFS_DIEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DIEPINT_TOC (1 << 3) /* Bit 3: Timeout condition */ +#define OTGFS_DIEPINT_ITTXFE (1 << 4) /* Bit 4: IN token received when TxFIFO is empty */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGFS_DIEPINT_INEPNE (1 << 6) /* Bit 6: IN endpoint NAK effective */ +#define OTGFS_DIEPINT_TXFE (1 << 7) /* Bit 7: Transmit FIFO empty */ + /* Bits 8-31: Reserved, must be kept at reset value */ +/* Device IN endpoint 0 transfer size register */ + +#define OTGFS_DIEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGFS_DIEPTSIZ0_XFRSIZ_MASK (0x7f << OTGFS_DIEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGFS_DIEPTSIZ0_PKTCNT_SHIFT (19) /* Bits 19-20: Packet count */ +#define OTGFS_DIEPTSIZ0_PKTCNT_MASK (3 << OTGFS_DIEPTSIZ0_PKTCNT_SHIFT) + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Device IN endpoint n transfer size register */ + +#define OTGFS_DIEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_DIEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_DIEPTSIZ_XFRSIZ_SHIFT) +#define OTGFS_DIEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGFS_DIEPTSIZ_PKTCNT_MASK (0x3ff << OTGFS_DIEPTSIZ_PKTCNT_SHIFT) +#define OTGFS_DIEPTSIZ_MCNT_SHIFT (29) /* Bits 29-30: Multi count */ +#define OTGFS_DIEPTSIZ_MCNT_MASK (3 << OTGFS_DIEPTSIZ_MCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint TxFIFO status register */ + +#define OTGFS_DTXFSTS_MASK (0xffff) + +/* Device OUT endpoint 0 control register */ + +#define OTGFS_DOEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTGFS_DOEPCTL0_MPSIZ_MASK (3 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) +# define OTGFS_DOEPCTL0_MPSIZ_64 (0 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_32 (1 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_16 (2 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTGFS_DOEPCTL0_MPSIZ_8 (3 << OTGFS_DOEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DOEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DOEPCTL0_EPTYP_MASK (3 << OTGFS_DOEPCTL0_EPTYP_SHIFT) +# define OTGFS_DOEPCTL0_EPTYP_CTRL (0 << OTGFS_DOEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ +#define OTGFS_DOEPCTL0_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGFS_DOEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DOEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DOEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device OUT endpoint n control register */ + +#define OTGFS_DOEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTGFS_DOEPCTL_MPSIZ_MASK (0x7ff << OTGFS_DOEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTGFS_DOEPCTL_DPID (1 << 16) /* Bit 16: Endpoint data PID (interrupt/buld) */ +# define OTGFS_DOEPCTL_DATA0 (0) +# define OTGFS_DOEPCTL_DATA1 OTGFS_DOEPCTL_DPID +#define OTGFS_DOEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame (isochronous) */ +# define OTGFS_DOEPCTL_EVEN (0) +# define OTGFS_DOEPCTL_ODD OTGFS_DOEPCTL_EONUM +#define OTGFS_DOEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTGFS_DOEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTGFS_DOEPCTL_EPTYP_MASK (3 << OTGFS_DOEPCTL_EPTYP_SHIFT) +# define OTGFS_DOEPCTL_EPTYP_CTRL (0 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Control */ +# define OTGFS_DOEPCTL_EPTYP_ISOC (1 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTGFS_DOEPCTL_EPTYP_BULK (2 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTGFS_DOEPCTL_EPTYP_INTR (3 << OTGFS_DOEPCTL_EPTYP_SHIFT) /* Interrupt */ +#define OTGFS_DOEPCTL_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTGFS_DOEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTGFS_DOEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTGFS_DOEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTGFS_DOEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTGFS_DOEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous) */ +#define OTGFS_DOEPCTL_SD1PID (1 << 29) /* Bit 29: Set DATA1 PID (interrupt/bulk) */ +#define OTGFS_DOEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous */ +#define OTGFS_DOEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTGFS_DOEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTGFS_DOEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTGFS_DOEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTGFS_DOEPINT_SETUP (1 << 3) /* Bit 3: SETUP phase done */ +#define OTGFS_DOEPINT_OTEPDIS (1 << 4) /* Bit 4: OUT token received when endpoint disabled */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTGFS_DOEPINT_B2BSTUP (1 << 6) /* Bit 6: Back-to-back SETUP packets received */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-0 transfer size register */ + +#define OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTGFS_DOEPTSIZ0_XFRSIZ_MASK (0x7f << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTGFS_DOEPTSIZ0_PKTCNT (1 << 19) /* Bit 19 PKTCNT: Packet count */ + /* Bits 20-28: Reserved, must be kept at reset value */ +#define OTGFS_DOEPTSIZ0_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGFS_DOEPTSIZ0_STUPCNT_MASK (3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-n transfer size register */ + +#define OTGFS_DOEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTGFS_DOEPTSIZ_XFRSIZ_MASK (0x7ffff << OTGFS_DOEPTSIZ_XFRSIZ_SHIFT) +#define OTGFS_DOEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTGFS_DOEPTSIZ_PKTCNT_MASK (0x3ff << OTGFS_DOEPTSIZ_PKTCNT_SHIFT) +#define OTGFS_DOEPTSIZ_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTGFS_DOEPTSIZ_STUPCNT_MASK (3 << OTGFS_DOEPTSIZ_STUPCNT_SHIFT) +#define OTGFS_DOEPTSIZ_RXDPID_SHIFT (29) /* Bits 29-30: Received data PID */ +#define OTGFS_DOEPTSIZ_RXDPID_MASK (3 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA0 (0 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA2 (1 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_DATA1 (2 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) +# define OTGFS_DOEPTSIZ_RXDPID_MDATA (3 << OTGFS_DOEPTSIZ_RXDPID_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Power and clock gating control register */ + +#define OTGFS_PCGCCTL_STPPCLK (1 << 0) /* Bit 0: Stop PHY clock */ +#define OTGFS_PCGCCTL_GATEHCLK (1 << 1) /* Bit 1: Gate HCLK */ + /* Bits 2-3: Reserved, must be kept at reset value */ +#define OTGFS_PCGCCTL_PHYSUSP (1 << 4) /* Bit 4: PHY Suspended */ + /* Bits 5-31: Reserved, must be kept at reset value */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32FXXXXX_OTGFS_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_aes.h b/arch/arm/src/stm32/chip/stm32l15xxx_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..a692a314405c602f0e05e8bedead9c331fdd8bf1 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_aes.h @@ -0,0 +1,117 @@ +/******************************************************************************************** + * arch/arm/src/stm32/chip/stm32l15xxx_aes.h + * AES hardware accelerator for STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_AES_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_AES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32l15xxx_memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* AES register offsets *********************************************************************/ + +#define STM32_AES_CR_OFFSET 0x0000 /* Control Register */ +#define STM32_AES_SR_OFFSET 0x0004 /* Status Register */ +#define STM32_AES_DINR_OFFSET 0x0008 /* Data Input Register */ +#define STM32_AES_DOUTR_OFFSET 0x000C /* Data Output Register */ +#define STM32_AES_KEYR0_OFFSET 0x0010 /* AES Key Register 0 */ +#define STM32_AES_KEYR1_OFFSET 0x0014 /* AES Key Register 1 */ +#define STM32_AES_KEYR2_OFFSET 0x0018 /* AES Key Register 2 */ +#define STM32_AES_KEYR3_OFFSET 0x001C /* AES Key Register 3 */ +#define STM32_AES_IVR0_OFFSET 0x0020 /* AES Initialization Vector Register 0 */ +#define STM32_AES_IVR1_OFFSET 0x0024 /* AES Initialization Vector Register 1 */ +#define STM32_AES_IVR2_OFFSET 0x0028 /* AES Initialization Vector Register 2 */ +#define STM32_AES_IVR3_OFFSET 0x002C /* AES Initialization Vector Register 3 */ + +/* AES register addresses *******************************************************************/ + +#define STM32_AES_CR (STM32_AES_BASE + STM32_AES_CR_OFFSET) +#define STM32_AES_SR (STM32_AES_BASE + STM32_AES_SR_OFFSET) +#define STM32_AES_DINR (STM32_AES_BASE + STM32_AES_DINR_OFFSET) +#define STM32_AES_DOUTR (STM32_AES_BASE + STM32_AES_DOUTR_OFFSET) +#define STM32_AES_KEYR0 (STM32_AES_BASE + STM32_AES_KEYR0_OFFSET) +#define STM32_AES_KEYR1 (STM32_AES_BASE + STM32_AES_KEYR1_OFFSET) +#define STM32_AES_KEYR2 (STM32_AES_BASE + STM32_AES_KEYR2_OFFSET) +#define STM32_AES_KEYR3 (STM32_AES_BASE + STM32_AES_KEYR3_OFFSET) +#define STM32_AES_IVR0 (STM32_AES_BASE + STM32_AES_IVR0_OFFSET) +#define STM32_AES_IVR1 (STM32_AES_BASE + STM32_AES_IVR1_OFFSET) +#define STM32_AES_IVR2 (STM32_AES_BASE + STM32_AES_IVR2_OFFSET) +#define STM32_AES_IVR3 (STM32_AES_BASE + STM32_AES_IVR3_OFFSET) + +/* AES register bit definitions *************************************************************/ + +/* AES_CR register */ + +#define AES_CR_EN (1 << 0) /* AES Enable */ +#define AES_CR_DATATYPE (1 << 1) /* Data type selection */ +# define AES_CR_DATATYPE_LE (0x0 << 1) +# define AES_CR_DATATYPE_BE (0x2 << 1) + +#define AES_CR_MODE (1 << 3) /* AES Mode of operation */ +# define AES_CR_MODE_ENCRYPT (0x0 << 3) +# define AES_CR_MODE_KEYDERIV (0x1 << 3) +# define AES_CR_MODE_DECRYPT (0x2 << 3) +# define AES_CR_MODE_DECRYPT_KEYDERIV (0x3 << 3) + +#define AES_CR_CHMOD (1 << 5) /* AES Chaining Mode */ +# define AES_CR_CHMOD_ECB (0x0 << 5) +# define AES_CR_CHMOD_CBC (0x1 << 5) +# define AES_CR_CHMOD_CTR (0x2 << 5) + +#define AES_CR_CCFC (1 << 7) /* Computation Complete Flag Clear */ +#define AES_CR_ERRC (1 << 8) /* Error Clear */ +#define AES_CR_CCIE (1 << 9) /* Computation Complete Interrupt Enable */ +#define AES_CR_ERRIE (1 << 10) /* Error Interrupt Enable */ +#define AES_CR_DMAINEN (1 << 11) /* DMA Enable Input */ +#define AES_CR_DMAOUTEN (1 << 12) /* DMA Enable Output */ + +/* AES_SR register */ + +#define AES_SR_CCF (1 << 0) /* Computation Complete Flag */ +#define AES_SR_RDERR (1 << 1) /* Read Error Flag */ +#define AES_SR_WRERR (1 << 2) /* Write Error Flag */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_AES_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_gpio.h b/arch/arm/src/stm32/chip/stm32l15xxx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..0b339505ab80ee057cf3ca5f98db91c9d8180c61 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_gpio.h @@ -0,0 +1,358 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xxx_gpio.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_NGPIO_PORTS ((STM32_NGPIO + 15) >> 4) + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NGPIO_PORTS > 0 +# define STM32_GPIOA_MODER (STM32_GPIOA_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOA_AFRL (STM32_GPIOA_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOA_AFRH (STM32_GPIOA_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 1 +# define STM32_GPIOB_MODER (STM32_GPIOB_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOB_AFRL (STM32_GPIOB_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOB_AFRH (STM32_GPIOB_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 2 +# define STM32_GPIOC_MODER (STM32_GPIOC_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOC_AFRL (STM32_GPIOC_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOC_AFRH (STM32_GPIOC_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 3 +# define STM32_GPIOD_MODER (STM32_GPIOD_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOD_AFRL (STM32_GPIOD_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOD_AFRH (STM32_GPIOD_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 4 +# define STM32_GPIOE_MODER (STM32_GPIOE_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOE_AFRL (STM32_GPIOE_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOE_AFRH (STM32_GPIOE_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 5 +# define STM32_GPIOH_MODER (STM32_GPIOH_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOH_OTYPER (STM32_GPIOH_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOH_OSPEED (STM32_GPIOH_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOH_PUPDR (STM32_GPIOH_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOH_IDR (STM32_GPIOH_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOH_ODR (STM32_GPIOH_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOH_BSRR (STM32_GPIOH_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOH_LCKR (STM32_GPIOH_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOH_AFRL (STM32_GPIOH_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOH_AFRH (STM32_GPIOH_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 6 +# define STM32_GPIOF_MODER (STM32_GPIOF_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOF_AFRL (STM32_GPIOF_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOF_AFRH (STM32_GPIOF_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +#if STM32_NGPIO_PORTS > 7 +# define STM32_GPIOG_MODER (STM32_GPIOG_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOG_OTYPER (STM32_GPIOG_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOG_OSPEED (STM32_GPIOG_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOG_PUPDR (STM32_GPIOG_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOG_IDR (STM32_GPIOG_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOG_ODR (STM32_GPIOG_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOG_BSRR (STM32_GPIOG_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOG_LCKR (STM32_GPIOG_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOG_AFRL (STM32_GPIOG_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOG_AFRH (STM32_GPIOG_BASE+STM32_GPIO_AFRH_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_400KHz (0) /* 400 kHz Very low speed */ +#define GPIO_OSPEED_2MHz (1) /* 2 MHz Low speed */ +#define GPIO_OSPEED_10MHz (2) /* 10 MHz Medium speed */ +#define GPIO_OSPEED_40MHz (3) /* 40 MHz High speed */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_GPIO_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32l15xxx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..1760ec140048c498bc76e146a59a87835d8e8735 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_memorymap.h @@ -0,0 +1,146 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xxx_memorymap.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32L15XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ + /* 0x60000000-0xdfffffff: Reserved */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x07ffffff: Aliased boot memory */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x0807ffff: Program FLASH memory */ +#define STM32_EEPROM_BASE 0x08080000 /* 0x08080000-0x08083fff: Data FLASH memory */ +#define STM32_SYSMEM_BASE 0x1ff00000 /* 0x1ff00000-0x1ff00fff: System memory */ + /* 0x1ff01000-0x1fff7fff: Reserved */ +#define STM32_OPTION_BASE 0x1ff80000 /* 0x1fffc000-0x1ff8001f: Option bytes */ + /* 0x1ff80020-0x1fffffff: Reserved */ + +/* SRAM Base Addresses **************************************************************/ + +#define STM32_SRAMBB_BASE 0x22000000 /* SRAM bit-band base */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x40007c03: APB1 */ + /* 0x40007c04-0x4000ffff: Reserved */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x40013bff: APB2 */ + /* 0x40013c00-0x4001ffff: Reserved */ +#define STM32_AHB_BASE 0x40020000 /* 0x40020000-0xa0000fff: AHB */ + /* 0xa0001000-0x4fffffff: Reserved */ +#define STM32_PERIPHBB_BASE 0x42000000 /* Peripheral bit-band base */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff TIM2 */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff TIM3 */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff TIM4 */ +#define STM32_TIM5_BASE 0x40000c00 /* 0x40000c00-0x40000fff TIM5 */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff TIM6 */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff TIM7 */ +#define STM32_LCD_BASE 0x40002400 /* 0x40002400-0x400027ff LCD */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff RTC */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff WWDG */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff IWDG */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff SPI2 */ +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff SPI3 */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00-0x40005fff USB device FS */ +#define STM32_USBRAM_BASE 0x40006000 /* 0x40006000-0x400063ff USB SRAM 512B */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400-0x400077ff DAC (dual) */ +#define STM32_DAC_COMP 0x40007c00 /* 0x40007c00-0x40007c03 COMP */ +#define STM32_DAC_RI 0x40007c04 /* 0x40007c04-0x40007c5b RI */ +#define STM32_DAC_OPAMP 0x40007c5c /* 0x40007c5c-0x40007fff OPAMP */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103FF SYSCFG */ +#define STM32_EXTI_BASE 0x40010400 /* 0x40010400-0x400107FF EXTI */ +#define STM32_TIM9_BASE 0x40010800 /* 0x40010800-0x40010bff TIM9 */ +#define STM32_TIM10_BASE 0x40010c00 /* 0x40010c00-0x40010fff TIM10 */ +#define STM32_ADC_BASE 0x40012400 /* 0x40012400-0x400127ff ADC */ +#define STM32_ADCCMN_BASE (STM32_ADC_BASE+0x300) /* ADC Common */ +#define STM32_SDIO_BASE 0x40012c00 /* 0x40012c00-0x40012fff SDIO */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */ +#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */ + +/* AHB Base Addresses ***************************************************************/ + +#define STM32_GPIOA_BASE 0x40020000 /* 0x40020000-0x400203ff GPIO Port A */ +#define STM32_GPIOB_BASE 0x40020400 /* 0x40020400-0x400207ff GPIO Port B */ +#define STM32_GPIOC_BASE 0x40020800 /* 0x40020800-0x40020bff GPIO Port C */ +#define STM32_GPIOD_BASE 0x40020c00 /* 0x40020c00-0x40020fff GPIO Port D */ +#define STM32_GPIOE_BASE 0x40021000 /* 0x40021000-0x400213ff GPIO Port E */ +#define STM32_GPIOH_BASE 0x40021400 /* 0x40021400-0x400217ff GPIO Port H */ +#define STM32_GPIOF_BASE 0x40021800 /* 0x40021800-0x40021bff GPIO Port F */ +#define STM32_GPIOG_BASE 0x40021c00 /* 0x40021c00-0x40021fff GPIO Port G */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff CRC */ +#define STM32_RCC_BASE 0x40023800 /* 0x40023800-0x40023bff RCC */ +#define STM32_FLASHIF_BASE 0x40023c00 /* 0x40023c00-0x40023fff Flash memory interface */ +#define STM32_DMA1_BASE 0x40026000 /* 0x40026000-0x400263ff DMA1 */ +#define STM32_DMA2_BASE 0x40026400 /* 0x40026400-0x400267ff DMA2 */ +#define STM32_AES_BASE 0x50060000 /* 0x50060000-0x500603ff AES */ +#define STM32_FSMC_BASE 0xa0000000 /* 0xa0000000-0xa0000fff FSMC */ + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32l15xxx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..b6efefd0d17c0b466b51dc53393946f3038b3693 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_pinmap.h @@ -0,0 +1,616 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xxx_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear in the board.h header file for that board: + * + * #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 + * + * The driver will then automatically configre PB6 as the I2C1 SCL pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +#define GPIO_BOOT1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN2) + +/* ADC + * + * ADC_IN16 is internal temperature sensor + * ADC_IN17 is internal Vrefint + */ + +#define GPIO_ADC1_IN0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN5) + +#define GPIO_ADC1_IN18 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN12) +#define GPIO_ADC1_IN19 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN13) +#define GPIO_ADC1_IN20 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN14) +#define GPIO_ADC1_IN21 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN15) +#define GPIO_ADC1_IN22 (GPIO_ANALOG | GPIO_PORTE | GPIO_PIN7) +#define GPIO_ADC1_IN23 (GPIO_ANALOG | GPIO_PORTE | GPIO_PIN8) +#define GPIO_ADC1_IN24 (GPIO_ANALOG | GPIO_PORTE | GPIO_PIN9) +#define GPIO_ADC1_IN25 (GPIO_ANALOG | GPIO_PORTE | GPIO_PIN10) + +#define GPIO_ADC1_IN27 (GPIO_ANALOG | GPIO_PORTF | GPIO_PIN6) +#define GPIO_ADC1_IN28 (GPIO_ANALOG | GPIO_PORTF | GPIO_PIN7) +#define GPIO_ADC1_IN29 (GPIO_ANALOG | GPIO_PORTF | GPIO_PIN8) +#define GPIO_ADC1_IN30 (GPIO_ANALOG | GPIO_PORTF | GPIO_PIN9) +#define GPIO_ADC1_IN31 (GPIO_ANALOG | GPIO_PORTF | GPIO_PIN10) + +/* DAC */ + +#define GPIO_DAC_OUT1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4) +#define GPIO_DAC_OUT2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN5) +#define GPIO_I2C2_SCL (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN10) +#define GPIO_I2C2_SDA (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_OPENDRAIN | GPIO_PORTB | GPIO_PIN11) +#define GPIO_I2C2_SMBA (GPIO_ALT | GPIO_AF4 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN12) + +/* JTAG/Trace */ + +#define GPIO_JTCK_SWCLK (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_JTMS_SWDAT (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN13) +#define GPIO_JTRST (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN4) + +#define GPIO_TRACECK (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN6) + +/* LCD */ + +#define GPIO_LCD_COM0 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_LCD_COM1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_LCD_COM2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_LCD_COM3 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_LCD_COM4 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_LCD_COM5 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_LCD_COM6 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_LCD_COM7 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_LCD_SEG0 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_LCD_SEG1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_LCD_SEG2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_LCD_SEG3 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_LCD_SEG4 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_LCD_SEG5 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_LCD_SEG6 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_LCD_SEG7 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_LCD_SEG8 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_LCD_SEG9 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_LCD_SEG10 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_LCD_SEG11 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_LCD_SEG12 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_LCD_SEG13 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_LCD_SEG14 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_LCD_SEG15 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_LCD_SEG16 (GPIO_ALT | GPIO_AF11 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_LCD_SEG17 (GPIO_ALT | GPIO_AF11 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_LCD_SEG18 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_LCD_SEG19 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_LCD_SEG20 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_LCD_SEG21 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_LCD_SEG22 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN4) +#define GPIO_LCD_SEG23 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN5) +#define GPIO_LCD_SEG24 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN6) +#define GPIO_LCD_SEG25 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN7) +#define GPIO_LCD_SEG26 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN8) +#define GPIO_LCD_SEG27 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN9) +#define GPIO_LCD_SEG28_1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_LCD_SEG28_2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN8) +#define GPIO_LCD_SEG29_1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_LCD_SEG29_2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN9) +#define GPIO_LCD_SEG30_1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_LCD_SEG30_2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN10) +#define GPIO_LCD_SEG31_1 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN11) +#define GPIO_LCD_SEG31_2 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_LCD_SEG32 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_LCD_SEG33 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN13) +#define GPIO_LCD_SEG34 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN14) +#define GPIO_LCD_SEG35 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_LCD_SEG36 (GPIO_ALT | GPIO_AF11 | GPIO_PORTE | GPIO_PIN0) +#define GPIO_LCD_SEG37 (GPIO_ALT | GPIO_AF11 | GPIO_PORTE | GPIO_PIN1) +#define GPIO_LCD_SEG38 (GPIO_ALT | GPIO_AF11 | GPIO_PORTE | GPIO_PIN2) +#define GPIO_LCD_SEG39 (GPIO_ALT | GPIO_AF11 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_LCD_SEG40 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_LCD_SEG41 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_LCD_SEG42 (GPIO_ALT | GPIO_AF11 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_LCD_SEG43 (GPIO_ALT | GPIO_AF11 | GPIO_PORTD | GPIO_PIN2) + +/* Clocking */ + +#define GPIO_MCO (GPIO_ALT | GPIO_AF0 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN8) +#define GPIO_OSC32_IN (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN14) +#define GPIO_OSC32_OUT (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN15) +#define GPIO_OSC_IN (GPIO_ALT | GPIO_AF0 | GPIO_PORTH | GPIO_PIN0) +#define GPIO_OSC_OUT (GPIO_ALT | GPIO_AF0 | GPIO_PORTH | GPIO_PIN1) + +/* Event outputs */ + +#define GPIO_PA0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_PA1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_PA2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_PA3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_PA4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_PA5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_PA6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_PA7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_PA8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_PA9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_PA10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_PA11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_PA12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_PA13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN13) +#define GPIO_PA14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN14) +#define GPIO_PA15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_PB0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_PB1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_PB2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN2) +#define GPIO_PB3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_PB4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_PB5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_PB6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN6) +#define GPIO_PB7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN7) +#define GPIO_PB8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_PB9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_PB10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_PB11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_PB12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_PB13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_PB14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_PB15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_PC0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_PC1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_PC2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_PC3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_PC4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN4) +#define GPIO_PC5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN5) +#define GPIO_PC6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN6) +#define GPIO_PC7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN7) +#define GPIO_PC8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN8) +#define GPIO_PC9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN9) +#define GPIO_PC10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_PC11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_PC12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_PC13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN13) +#define GPIO_PC14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN14) +#define GPIO_PC15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTC | GPIO_PIN15) +#define GPIO_PD0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_PD1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN1) +#define GPIO_PD2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_PD3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_PD4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_PD5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN5) +#define GPIO_PD6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN6) +#define GPIO_PD7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN7) +#define GPIO_PD8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN8) +#define GPIO_PD9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN9) +#define GPIO_PD10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN10) +#define GPIO_PD11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN11) +#define GPIO_PD12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_PD13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN13) +#define GPIO_PD14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN14) +#define GPIO_PD15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_PE0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN0) +#define GPIO_PE1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN1) +#define GPIO_PE2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN2) +#define GPIO_PE3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_PE4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN4) +#define GPIO_PE5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN5) +#define GPIO_PE6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN6) +#define GPIO_PE7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN7) +#define GPIO_PE8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN8) +#define GPIO_PE9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN9) +#define GPIO_PE10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN10) +#define GPIO_PE11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN11) +#define GPIO_PE12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN12) +#define GPIO_PE13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN13) +#define GPIO_PE14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_PE15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_PF0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN0) +#define GPIO_PF1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN1) +#define GPIO_PF2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN2) +#define GPIO_PF3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN3) +#define GPIO_PF4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN4) +#define GPIO_PF5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN5) +#define GPIO_PF6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN6) +#define GPIO_PF7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN7) +#define GPIO_PF8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN8) +#define GPIO_PF9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN9) +#define GPIO_PF10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN10) +#define GPIO_PF11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN11) +#define GPIO_PF12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN12) +#define GPIO_PF13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN13) +#define GPIO_PF14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN14) +#define GPIO_PF15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTF | GPIO_PIN15) +#define GPIO_PG0_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN0) +#define GPIO_PG1_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN1) +#define GPIO_PG2_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN2) +#define GPIO_PG3_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN3) +#define GPIO_PG4_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN4) +#define GPIO_PG5_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN5) +#define GPIO_PG6_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN6) +#define GPIO_PG7_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN7) +#define GPIO_PG8_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN8) +#define GPIO_PG9_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN9) +#define GPIO_PG10_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN10) +#define GPIO_PG11_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN11) +#define GPIO_PG12_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN12) +#define GPIO_PG13_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN13) +#define GPIO_PG14_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN14) +#define GPIO_PG15_EVENT_OUT (GPIO_ALT | GPIO_AF15 | GPIO_PORTG | GPIO_PIN15) + +/* RTC */ + +#define GPIO_RTC_OUT (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN13) +#define GPIO_RTC_REFIN (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_RTC_TAMP1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN13) +#define GPIO_RTC_TS (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN13) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_SPI1_MISO_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_SPI1_MISO_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_SPI1_MISO_4 (GPIO_ALT | GPIO_AF5 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_SPI1_MOSI_4 (GPIO_ALT | GPIO_AF5 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_SPI1_NSS_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_SPI1_NSS_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTE | GPIO_PIN12) +#define GPIO_SPI1_SCK_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_SPI1_SCK_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTE | GPIO_PIN13) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_SPI2_NSS_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_SPI2_SCK_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_SPI2_SCK_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTD | GPIO_PIN1) + +#define GPIO_SPI3_MISO_1 (GPIO_ALT | GPIO_AF6 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT | GPIO_AF6 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT | GPIO_AF6 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT | GPIO_AF6 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_SPI3_NSS_1 (GPIO_ALT | GPIO_AF6 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_SPI3_NSS_2 (GPIO_ALT | GPIO_AF6 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_SPI3_SCK_1 (GPIO_ALT | GPIO_AF6 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT | GPIO_AF6 | GPIO_PORTC | GPIO_PIN10) + +/* Timers */ + +#define GPIO_TIM2_CH1_ETR_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TIM2_CH1_ETR_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN15) +#define GPIO_TIM2_CH1_ETR_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN9) +#define GPIO_TIM2_CH1_ETR_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN5) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TIM2_CH2IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TIM2_CH2IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TIM2_CH3IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TIM2_CH3IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN11) +#define GPIO_TIM2_CH4IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN12) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF1 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN12) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN6) +#define GPIO_TIM3_CH1IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN5) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN7) +#define GPIO_TIM3_CH2IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN8) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTC | GPIO_PIN9) +#define GPIO_TIM3_ETR_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN2) +#define GPIO_TIM3_ETR_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN6) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN7) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT |GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN0) + +#define GPIO_TIM5_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TIM5_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TIM5_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM5_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM5_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN7) +#define GPIO_TIM5_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN7) +#define GPIO_TIM5_CH3IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM5_CH3OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM5_CH3IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN8) +#define GPIO_TIM5_CH3OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN8) +#define GPIO_TIM5_CH4IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN4) +#define GPIO_TIM5_CH4OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN4) +#define GPIO_TIM5_CH4IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN9) +#define GPIO_TIM5_CH4OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN9) +#define GPIO_TIM5_ETR (GPIO_ALT | GPIO_FLOAT | GPIO_AF2 | GPIO_SPEED_40MHz | GPIO_PORTF | GPIO_PIN6) + +#define GPIO_TIM9_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM9_CH1IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN13) +#define GPIO_TIM9_CH1IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN0) +#define GPIO_TIM9_CH1IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TIM9_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM9_CH1OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN13) +#define GPIO_TIM9_CH1OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN0) +#define GPIO_TIM9_CH1OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TIM9_CH2IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM9_CH2IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TIM9_CH2IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN7) +#define GPIO_TIM9_CH2IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN6) +#define GPIO_TIM9_CH2OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM9_CH2OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TIM9_CH2OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTD | GPIO_PIN7) +#define GPIO_TIM9_CH2OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN6) + +#define GPIO_TIM10_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM10_CH1IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TIM10_CH1IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TIM10_CH1IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN0) +#define GPIO_TIM10_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM10_CH1OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TIM10_CH1OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TIM10_CH1OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN0) + +#define GPIO_TIM11_CH1IN_1 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM11_CH1IN_2 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN15) +#define GPIO_TIM11_CH1IN_3 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TIM11_CH1IN_4 (GPIO_ALT | GPIO_FLOAT | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN1) +#define GPIO_TIM11_CH1OUT_1 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM11_CH1OUT_2 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN15) +#define GPIO_TIM11_CH1OUT_3 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TIM11_CH1OUT_4 (GPIO_ALT | GPIO_PUSHPULL | GPIO_AF3 | GPIO_SPEED_40MHz | GPIO_PORTE | GPIO_PIN1) + +#define GPIO_TIMX_IC1_1 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TIMX_IC1_2 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_TIMX_IC1_3 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_TIMX_IC1_4 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_TIMX_IC1_5 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_TIMX_IC1_6 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_TIMX_IC1_7 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN4) +#define GPIO_TIMX_IC1_8 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN8) +#define GPIO_TIMX_IC1_9 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_TIMX_IC1_10 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_TIMX_IC1_11 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_TIMX_IC1_12 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN8) +#define GPIO_TIMX_IC1_13 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN0) +#define GPIO_TIMX_IC1_14 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN12) +#define GPIO_TIMX_IC1_15 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TIMX_IC1_16 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN8) + +#define GPIO_TIMX_IC2_1 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIMX_IC2_2 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN13) +#define GPIO_TIMX_IC2_3 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_TIMX_IC2_4 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_TIMX_IC2_5 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_TIMX_IC2_6 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN13) +#define GPIO_TIMX_IC2_7 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN5) +#define GPIO_TIMX_IC2_8 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN9) +#define GPIO_TIMX_IC2_9 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN1) +#define GPIO_TIMX_IC2_10 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN13) +#define GPIO_TIMX_IC2_11 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN5) +#define GPIO_TIMX_IC2_12 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN9) +#define GPIO_TIMX_IC2_13 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN1) +#define GPIO_TIMX_IC2_14 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN13) +#define GPIO_TIMX_IC2_15 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TIMX_IC2_16 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN9) + +#define GPIO_TIMX_IC3_1 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_TIMX_IC3_2 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN14) +#define GPIO_TIMX_IC3_3 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIMX_IC3_4 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIMX_IC3_5 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_TIMX_IC3_6 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN14) +#define GPIO_TIMX_IC3_7 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_TIMX_IC3_8 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN6) +#define GPIO_TIMX_IC3_9 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN10) +#define GPIO_TIMX_IC3_10 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN14) +#define GPIO_TIMX_IC3_11 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_TIMX_IC3_12 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN6) +#define GPIO_TIMX_IC3_13 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIMX_IC3_14 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_TIMX_IC3_15 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN2) +#define GPIO_TIMX_IC3_16 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN6) + +#define GPIO_TIMX_IC4_1 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_TIMX_IC4_2 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_TIMX_IC4_3 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIMX_IC4_4 (GPIO_ALT | GPIO_AF14 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIMX_IC4_5 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_TIMX_IC4_6 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN15) +#define GPIO_TIMX_IC4_7 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_TIMX_IC4_8 (GPIO_ALT | GPIO_AF14 | GPIO_PORTC | GPIO_PIN7) +#define GPIO_TIMX_IC4_9 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN11) +#define GPIO_TIMX_IC4_10 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_TIMX_IC4_11 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_TIMX_IC4_12 (GPIO_ALT | GPIO_AF14 | GPIO_PORTD | GPIO_PIN7) +#define GPIO_TIMX_IC4_13 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIMX_IC4_14 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_TIMX_IC4_15 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TIMX_IC4_16 (GPIO_ALT | GPIO_AF14 | GPIO_PORTE | GPIO_PIN7) + +/* USART */ + +#define GPIO_USART1_CK (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN7) +#define GPIO_USART1_TX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN6) + +#define GPIO_USART2_CK_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_USART3_CTS_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_USART3_RX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN9) +#define GPIO_USART3_TX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF7 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN8) + +#define GPIO_UART4_RX (GPIO_ALT | GPIO_PULLUP | GPIO_AF8 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN11) +#define GPIO_UART4_TX (GPIO_ALT | GPIO_PULLUP | GPIO_AF8 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN10) + +#define GPIO_UART5_RX (GPIO_ALT | GPIO_PULLUP | GPIO_AF8 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT | GPIO_PULLUP | GPIO_AF8 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN12) + +/* USB */ + +#define GPIO_USB_DM (GPIO_ALT | GPIO_AF10 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USB_DP (GPIO_ALT | GPIO_AF10 | GPIO_SPEED_40MHz | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN12) + +/* Wakeup inputs */ + +#define GPIO_WKUP1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_WKUP2 (GPIO_ALT | GPIO_AF9 | GPIO_PORTC | GPIO_PIN13) +#define GPIO_WKUP3 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN6) + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_rcc.h b/arch/arm/src/stm32/chip/stm32l15xxx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..026d50ec0871be4c4f08756f70e3dcabbeee2d4b --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_rcc.h @@ -0,0 +1,464 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xx_rcc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_RCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_ICSCR_OFFSET 0x0004 /* Internal clock sources calibration register */ +#define STM32_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x000c /* Clock interrupt register */ +#define STM32_RCC_AHBRSTR_OFFSET 0x0010 /* AHB Peripheral reset register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x0014 /* APB2 Peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0018 /* APB1 Peripheral reset register */ +#define STM32_RCC_AHBENR_OFFSET 0x001c /* AHB Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0020 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x0024 /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_AHBLPENR_OFFSET 0x0028 /* AHB peripheral clock enable in low power mode register */ +#define STM32_RCC_APB2LPENR_OFFSET 0x002c /* APB2 peripheral clock enable in low power mode register */ +#define STM32_RCC_APB1LPENR_OFFSET 0x0030 /* APB1 peripheral clock enable in low power mode register */ +#define STM32_RCC_CSR_OFFSET 0x0034 /* Control/status register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_ICSCR (STM32_RCC_BASE+STM32_RCC_ICSCR_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_AHBRSTR (STM32_RCC_BASE+STM32_RCC_AHBRSTR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_AHBENR (STM32_RCC_BASE+STM32_RCC_AHBENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_AHBLPENR (STM32_RCC_BASE+STM32_RCC_AHBLPENR_OFFSET) +#define STM32_RCC_APB2LPENR (STM32_RCC_BASE+STM32_RCC_APB2LPENR_OFFSET) +#define STM32_RCC_APB1LPENR (STM32_RCC_BASE+STM32_RCC_APB1LPENR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal high speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal high speed clock ready flag */ + /* Bits 2-7: Reserved */ +#define RCC_CR_MSION (1 << 8) /* Bit 8: MSI clock enable */ +#define RCC_CR_MSIRDY (1 << 9) /* Bit 9: MSI clock ready flag */ + /* Bits 10-15: Reserved */ +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External high speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External high speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External high speed clock bypass */ + /* Bits 19-23: Reserved */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ + /* Bits 26-27: Reserved */ +#define RCC_CR_CSSON (1 << 28) /* Bit 16: Clock security system enable */ +#define RCC_CR_RTCPRE_SHIFT (29) /* Bits 29-30: RTC/LCD prescaler */ +#define RCC_CR_RTCPRE_MASK (3 << RCC_CR_RTCPRE_SHIFT) + /* Bit 31: Reserved */ +#define RCC_CR_RSTVAL 0x00000300 + +/* Internal clock sources calibration register */ + +#define RCC_ICSCR_HSICAL_SHIFT (0) /* Bits 0-7: Internal high speed clock calibration */ +#define RCC_ICSCR_HSICAL_MASK (0xff << RCC_ICSCR_HSICAL_SHIFT) +#define RCC_ICSCR_HSITRIM_SHIFT (8) /* Bits 8-12: High speed internal clock trimming */ +#define RCC_ICSCR_HSITRIM_MASK (0x1f << RCC_ICSCR_HSITRIM_SHIFT) +#define RCC_ICSCR_MSIRANGE_SHIFT (13) /* Bits 13-15: MSI clock ranges */ +#define RCC_ICSCR_MSIRANGE_MASK (7 << RCC_ICSCR_MSIRANGE_SHIFT) +# define RCC_ICSCR_MSIRANGE_0 (0 << RCC_ICSCR_MSIRANGE_SHIFT) /* 000: Range 0 around 65.536 kHz */ +# define RCC_ICSCR_MSIRANGE_1 (1 << RCC_ICSCR_MSIRANGE_SHIFT) /* 001: Range 1 around 131.072 kHz */ +# define RCC_ICSCR_MSIRANGE_2 (2 << RCC_ICSCR_MSIRANGE_SHIFT) /* 010: Range 2 around 262.144 kHz */ +# define RCC_ICSCR_MSIRANGE_3 (3 << RCC_ICSCR_MSIRANGE_SHIFT) /* 011: Range 3 around 524.288 kHz */ +# define RCC_ICSCR_MSIRANGE_4 (4 << RCC_ICSCR_MSIRANGE_SHIFT) /* 100: Range 4 around 1.048 MHz */ +# define RCC_ICSCR_MSIRANGE_5 (5 << RCC_ICSCR_MSIRANGE_SHIFT) /* 101: Range 5 around 2.097 MHz (reset value) */ +# define RCC_ICSCR_MSIRANGE_6 (6 << RCC_ICSCR_MSIRANGE_SHIFT) /* 110: Range 6 around 4.194 MHz */ +#define RCC_ICSCR_MSICAL_SHIFT (16) /* Bits 16-23: MSI clock calibration */ +#define RCC_ICSCR_MSICAL_MASK (0xff << RCC_ICSCR_MSICAL_SHIFT) +#define RCC_ICSCR_MSITRIM_SHIFT (24) /* Bits 24-31: MSI clock trimming */ +#define RCC_ICSCR_MSITRIM_MASK (0xff << RCC_ICSCR_MSITRIM_SHIFT) + +#define RCC_ICSR_RSTVAL 0x0000b000 + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_MSI (0 << RCC_CFGR_SW_SHIFT) /* 00: MSI selected as system clock */ +# define RCC_CFGR_SW_HSI (1 << RCC_CFGR_SW_SHIFT) /* 01: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (2 << RCC_CFGR_SW_SHIFT) /* 10: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (3 << RCC_CFGR_SW_SHIFT) /* 11: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_MSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: MSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSI (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (2 << RCC_CFGR_SWS_SHIFT) /* 10: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (3 << RCC_CFGR_SWS_SHIFT) /* 11: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 18-10: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 11-13: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ + /* Bits 14-15: Reserved */ +#define RCC_CFGR_PLLSRC (1 << 16) /* Bit 16: PLL entry clock source */ + /* Bit 17: Reserved */ +#define RCC_CFGR_PLLMUL_SHIFT (18) /* Bits 18-21: PLL Multiplication Factor */ +#define RCC_CFGR_PLLMUL_MASK (15 << RCC_CFGR_PLLMUL_SHIFT) +# define RCC_CFGR_PLLMUL_CLKx3 (0 << RCC_CFGR_PLLMUL_SHIFT) /* 0000: PLL clock entry x 3 */ +# define RCC_CFGR_PLLMUL_CLKx4 (1 << RCC_CFGR_PLLMUL_SHIFT) /* 0001: PLL clock entry x 4 */ +# define RCC_CFGR_PLLMUL_CLKx6 (2 << RCC_CFGR_PLLMUL_SHIFT) /* 0010: PLL clock entry x 6 */ +# define RCC_CFGR_PLLMUL_CLKx8 (3 << RCC_CFGR_PLLMUL_SHIFT) /* 0011: PLL clock entry x 8 */ +# define RCC_CFGR_PLLMUL_CLKx12 (4 << RCC_CFGR_PLLMUL_SHIFT) /* 0100: PLL clock entry x 12 */ +# define RCC_CFGR_PLLMUL_CLKx16 (5 << RCC_CFGR_PLLMUL_SHIFT) /* 0101: PLL clock entry x 16 */ +# define RCC_CFGR_PLLMUL_CLKx24 (6 << RCC_CFGR_PLLMUL_SHIFT) /* 0110: PLL clock entry x 24 */ +# define RCC_CFGR_PLLMUL_CLKx32 (7 << RCC_CFGR_PLLMUL_SHIFT) /* 0111: PLL clock entry x 32 */ +# define RCC_CFGR_PLLMUL_CLKx48 (8 << RCC_CFGR_PLLMUL_SHIFT) /* 1000: PLL clock entry x 48 */ +#define RCC_CFGR_PLLDIV_SHIFT (22) /* Bits 22-23: PLL output division */ +#define RCC_CFGR_PLLDIV_MASK (3 << RCC_CFGR_PLLDIV_SHIFT) +# define RCC_CFGR_PLLDIV_2 (1 << RCC_CFGR_PLLDIV_SHIFT) /* 01: PLL clock output = PLLVCO / 2 */ +# define RCC_CFGR_PLLDIV_3 (2 << RCC_CFGR_PLLDIV_SHIFT) /* 10: PLL clock output = PLLVCO / 3 */ +# define RCC_CFGR_PLLDIV_4 (3 << RCC_CFGR_PLLDIV_SHIFT) /* 11: PLL clock output = PLLVCO / 4 */ +#define RCC_CFGR_MCOSEL_SHIFT (24) /* Bits 24-26: Microcontroller clock output selection */ +#define RCC_CFGR_MCOSEL_MASK (7 << RCC_CFGR_MCOSEL_SHIFT) +# define RCC_CFGR_MCOSEL_DISABLED (0 << RCC_CFGR_MCOSEL_SHIFT) /* 000: MCO output disabled, no clock on MCO */ +# define RCC_CFGR_MCOSEL_SYSCLK (1 << RCC_CFGR_MCOSEL_SHIFT) /* 001: SYSCLK clock selected */ +# define RCC_CFGR_MCOSEL_HSICLK (2 << RCC_CFGR_MCOSEL_SHIFT) /* 010: HSI oscillator clock selected */ +# define RCC_CFGR_MCOSEL_MSICLK (3 << RCC_CFGR_MCOSEL_SHIFT) /* 011: MSI oscillator clock selected */ +# define RCC_CFGR_MCOSEL_HSECLK (4 << RCC_CFGR_MCOSEL_SHIFT) /* 100: HSE oscillator clock selected */ +# define RCC_CFGR_MCOSEL_PLLCLK (5 << RCC_CFGR_MCOSEL_SHIFT) /* 101: PLL clock selected */ +# define RCC_CFGR_MCOSEL_LSICLK (6 << RCC_CFGR_MCOSEL_SHIFT) /* 110: LSI oscillator clock selected */ +# define RCC_CFGR_MCOSEL_LSECLK (7 << RCC_CFGR_MCOSEL_SHIFT) /* 111: LSE oscillator clock selected */ + /* Bit 27: Reserved */ +#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: Microcontroller clock output selection */ +#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT) +# define RCC_CFGR_MCOPRE_DIV1 (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: MCO is divided by 1 */ +# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: MCO is divided by 2 */ +# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: MCO is divided by 4 */ +# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: MCO is divided by 8 */ +# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: MCO is divided by 16 */ + /* Bit 31: Reserved */ +#define RCC_CFGR_RESET 0x00000000 + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI ready interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE ready interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI ready interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE ready interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL ready interrupt flag */ +#define RCC_CIR_MSIRDYF (1 << 5) /* Bit 5: MSI ready interrupt flag */ +#define RCC_CIR_LSECSSF (1 << 6) /* Bit 6: LSE CSS Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock security system interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI ready interrupt enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE ready interrupt enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI ready interrupt enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE ready interrupt enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL ready interrupt enable */ +#define RCC_CIR_MSIRDYIE (1 << 13) /* Bit 13: MSI ready interrupt enable */ +#define RCC_CIR_LSECSSIE (1 << 14) /* Bit 14: LSE CSS interrupt enable */ + /* Bit 15: Reserved */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI ready interrupt clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE ready interrupt clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI ready interrupt clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE ready interrupt clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL ready interrupt clear */ +#define RCC_CIR_MSIRDYC (1 << 21) /* Bit 21: MSI ready interrupt clear */ +#define RCC_CIR_LSECSSC (1 << 22) /* Bit 22: LSE CSS interrupt clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security system interrupt clear */ + /* Bits 24-31: Reserved */ + +/* AHB peripheral clock reset register (RCC_AHBRSTR) */ + +#define RCC_AHBRSTR_GPIOPARST (1 << 0) /* Bit 0: I/O port A reset */ +#define RCC_AHBRSTR_GPIOPBRST (1 << 1) /* Bit 1: I/O port B reset */ +#define RCC_AHBRSTR_GPIOPCRST (1 << 2) /* Bit 2: I/O port C reset */ +#define RCC_AHBRSTR_GPIOPDRST (1 << 3) /* Bit 3: I/O port D reset */ +#define RCC_AHBRSTR_GPIOPERST (1 << 4) /* Bit 4: I/O port E reset */ +#define RCC_AHBRSTR_GPIOPHRST (1 << 5) /* Bit 5: I/O port H reset */ +#define RCC_AHBRSTR_GPIOPFRST (1 << 6) /* Bit 6: I/O port F reset */ +#define RCC_AHBRSTR_GPIOPGRST (1 << 7) /* Bit 7: I/O port G reset */ + /* Bits 8-11: Reserved */ +#define RCC_AHBRSTR_CRCRST (1 << 12) /* Bit 12: CRC reset */ + /* Bits 13-14: Reserved */ +#define RCC_AHBRSTR_FLITFRST (1 << 15) /* Bit 15: FLITF reset */ + /* Bits 16-23: Reserved */ +#define RCC_AHBRSTR_DMA1RST (1 << 24) /* Bit 24: DMA1 reset */ +#define RCC_AHBRSTR_DMA2RST (1 << 25) /* Bit 25: DMA2 reset */ + /* Bit 26: Reserved */ +#define RCC_AHBRSTR_AESRST (1 << 27) /* Bit 27: AES reset */ + /* Bits 28-29: Reserved */ +#define RCC_AHBRSTR_FSMCRST (1 << 30) /* Bit 30: FSMC reset */ + /* Bit 31: Reserved */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: System configuration controller reset */ + /* Bit 1: Reserved */ +#define RCC_APB2RSTR_TIM9RST (1 << 2) /* Bit 2: TIM9 timer reset */ +#define RCC_APB2RSTR_TIM10RST (1 << 3) /* Bit 3: TIM10 timer reset */ +#define RCC_APB2RSTR_TIM11RST (1 << 4) /* Bit 4: TIM11 timer reset */ + /* Bits 5-8: Reserved */ +#define RCC_APB2RSTR_ADC1RST (1 << 9) /* Bit 9: ADC1 interface reset */ + /* Bit 10: Reserved */ +#define RCC_APB2RSTR_SDIORST (1 << 11) /* Bit 11: SDIO reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ + /* Bit 13: Reserved */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ + /* Bits 15-31: Reserved */ + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: Timer 4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 3: Timer 5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: Timer 6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: Timer 7 reset */ + /* Bits 6-8: Reserved */ +#define RCC_APB1RSTR_LCDRST (1 << 9) /* Bit 9: LCD reset */ + /* Bit 10: Reserved */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window Watchdog reset */ + /* Bits 12-13: Reserved */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ + /* Bit 16: Reserved */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: UART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: UART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_USBRST (1 << 23) /* Bit 23: USB reset */ + /* Bits 24-27: Reserved */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC interface reset */ + /* Bit 30: Reserved */ +#define RCC_APB1RSTR_COMPRST (1 << 31) /* Bit 31: COMP interface reset */ + +/* AHB Peripheral Clock enable register */ + +#define RCC_AHBENR_GPIOEN(n) (1 << (n)) +#define RCC_AHBENR_GPIOPAEN (1 << 0) /* Bit 0: I/O port A clock enable */ +#define RCC_AHBENR_GPIOPBEN (1 << 1) /* Bit 1: I/O port B clock enable */ +#define RCC_AHBENR_GPIOPCEN (1 << 2) /* Bit 2: I/O port C clock enable */ +#define RCC_AHBENR_GPIOPDEN (1 << 3) /* Bit 3: I/O port D clock enable */ +#define RCC_AHBENR_GPIOPEEN (1 << 4) /* Bit 4: I/O port E clock enable */ +#define RCC_AHBENR_GPIOPHEN (1 << 5) /* Bit 5: I/O port H clock enable */ +#define RCC_AHBENR_GPIOPFEN (1 << 6) /* Bit 6: I/O port F clock enable */ +#define RCC_AHBENR_GPIOPGEN (1 << 7) /* Bit 7: I/O port G clock enable */ + /* Bits 8-11: Reserved */ +#define RCC_AHBENR_CRCEN (1 << 12) /* Bit 12: CRC clock enable */ + /* Bits 13-14: Reserved */ +#define RCC_AHBENR_FLITFEN (1 << 15) /* Bit 15: FLITF clock enable */ + /* Bits 16-23: Reserved */ +#define RCC_AHBENR_DMA1EN (1 << 24) /* Bit 24: DMA1 clock enable */ +#define RCC_AHBENR_DMA2EN (1 << 25) /* Bit 25: DMA2 clock enable */ + /* Bit 26: Reserved */ +#define RCC_AHBENR_AESEN (1 << 27) /* Bit 27: AES clock enable */ + /* Bits 28-29: Reserved */ +#define RCC_AHBENR_FSMCEN (1 << 30) /* Bit 30: FSMC clock enable */ + /* Bit 31: Reserved */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: System configuration controller clock enable */ + /* Bit 1: Reserved */ +#define RCC_APB2ENR_TIM9EN (1 << 2) /* Bit 2: TIM9 timer clock enable */ +#define RCC_APB2ENR_TIM10EN (1 << 3) /* Bit 3: TIM10 timer clock enable */ +#define RCC_APB2ENR_TIM11EN (1 << 4) /* Bit 4: TIM11 timer clock enable */ + /* Bits 5-8: Reserved */ +#define RCC_APB2ENR_ADC1EN (1 << 9) /* Bit 9: ADC1 interface clock enable */ + /* Bit 10: Reserved */ +#define RCC_APB2ENR_SDIOEN (1 << 11) /* Bit 11: SDIO clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI 1 clock enable */ + /* Bit 13: Reserved */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ + /* Bits 15-31: Reserved */ + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: Timer 4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 3: Timer 5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: Timer 6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: Timer 7 clock enable */ + /* Bits 6-8: Reserved */ +#define RCC_APB1ENR_LCDEN (1 << 9) /* Bit 9: LCD clock enable */ + /* Bit 10: Reserved */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window Watchdog clock enable */ + /* Bits 12-13: Reserved */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI 3 clock enable */ + /* Bit 16: Reserved */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART 4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART 5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C 2 clock enable */ +#define RCC_APB1ENR_USBEN (1 << 23) /* Bit 23: USB clock enable */ + /* Bits 24-27: Reserved */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ + /* Bit 30: Reserved */ +#define RCC_APB1ENR_COMPEN (1 << 31) /* Bit 31: COMP interface clock enable */ + +/* AHB peripheral clock enable in low power mode register */ + +#define RCC_AHBLPENR_GPIOPALPEN (1 << 0) /* Bit 0: I/O port A clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPBLPEN (1 << 1) /* Bit 1: I/O port B clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPCLPEN (1 << 2) /* Bit 2: I/O port C clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPDLPEN (1 << 3) /* Bit 3: I/O port D clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPELPEN (1 << 4) /* Bit 4: I/O port E clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPHLPEN (1 << 5) /* Bit 5: I/O port H clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPFLPEN (1 << 6) /* Bit 6: I/O port F clock enable during sleep mode */ +#define RCC_AHBLPENR_GPIOPGLPEN (1 << 7) /* Bit 7: I/O port G clock enable during sleep mode */ + /* Bits 8-11: Reserved */ +#define RCC_AHBLPENR_CRCLPEN (1 << 12) /* Bit 12: CRC clock enable during sleep mode */ + /* Bits 13-14: Reserved */ +#define RCC_AHBLPENR_FLITFLPEN (1 << 15) /* Bit 15: FLITF clock enable during sleep mode */ +#define RCC_AHBLPENR_SRAMLPEN (1 << 16) /* Bit 16: SRAM clock enable during sleep mode */ + /* Bits 17-23: Reserved */ +#define RCC_AHBLPENR_DMA1LPEN (1 << 24) /* Bit 24: DMA1 clock enable during sleep mode */ +#define RCC_AHBLPENR_DMA2LPEN (1 << 25) /* Bit 25: DMA2 clock enable during sleep mode */ + /* Bit 26: Reserved */ +#define RCC_AHBLPENR_AESLPEN (1 << 27) /* Bit 27: AES clock enable during sleep mode */ + /* Bits 28-29: Reserved */ +#define RCC_AHBLPENR_FSMCLPEN (1 << 30) /* Bit 30: FSMC clock enable during sleep mode */ + /* Bit 31: Reserved */ + +/* APB2 peripheral clock enable in low power mode register */ + +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 0) /* Bit 0: System configuration controller clock enable during sleep mode */ + /* Bit 1: Reserved */ +#define RCC_APB2LPENR_TIM9LPEN (1 << 2) /* Bit 2: TIM9 timer clock enable during sleep mode */ +#define RCC_APB2LPENR_TIM10LPEN (1 << 3) /* Bit 3: TIM10 timer clock enable during sleep mode */ +#define RCC_APB2LPENR_TIM11LPEN (1 << 4) /* Bit 4: TIM11 timer clock enable during sleep mode */ + /* Bits 5-8: Reserved */ +#define RCC_APB2LPENR_ADC1LPEN (1 << 9) /* Bit 9: ADC1 interface clock enable during sleep mode */ + /* Bit 10: Reserved */ +#define RCC_APB2LPENR_SDIOLPEN (1 << 11) /* Bit 11: SDIO clock enable during sleep mode */ +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) /* Bit 12: SPI 1 clock enable during sleep mode */ + /* Bit 13: Reserved */ +#define RCC_APB2LPENR_USART1LPEN (1 << 14) /* Bit 14: USART1 clock enable during sleep mode */ + /* Bits 15-31: Reserved */ + +/* APB1 peripheral clock enable in low power mode register */ + +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) /* Bit 0: Timer 2 clock enable during sleep mode */ +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) /* Bit 1: Timer 3 clock enable during sleep mode */ +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) /* Bit 2: Timer 4 clock enable during sleep mode */ +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) /* Bit 3: Timer 5 clock enable during sleep mode */ +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) /* Bit 4: Timer 6 clock enable during sleep mode */ +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) /* Bit 5: Timer 7 clock enable during sleep mode */ + /* Bits 6-8: Reserved */ +#define RCC_APB1LPENR_LCDLPEN (1 << 9) /* Bit 9: LCD clock enable during sleep mode */ + /* Bit 10: Reserved */ +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) /* Bit 11: Window Watchdog clock enable during sleep mode */ + /* Bits 12-13: Reserved */ +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) /* Bit 14: SPI 2 clock enable during sleep mode */ +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) /* Bit 15: SPI 3 clock enable during sleep mode */ + /* Bit 16: Reserved */ +#define RCC_APB1LPENR_USART2LPEN (1 << 17) /* Bit 17: USART 2 clock enable during sleep mode */ +#define RCC_APB1LPENR_USART3LPEN (1 << 18) /* Bit 18: USART 3 clock enable during sleep mode */ +#define RCC_APB1LPENR_UART4LPEN (1 << 19) /* Bit 19: UART 4 clock enable during sleep mode */ +#define RCC_APB1LPENR_UART5LPEN (1 << 20) /* Bit 20: UART 5 clock enable during sleep mode */ +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) /* Bit 21: I2C 1 clock enable during sleep mode */ +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) /* Bit 22: I2C 2 clock enable during sleep mode */ +#define RCC_APB1LPENR_USBLPEN (1 << 23) /* Bit 23: USB clock enable during sleep mode */ + /* Bits 24-27: Reserved */ +#define RCC_APB1LPENR_PWRLPEN (1 << 28) /* Bit 28: Power interface clock enable during sleep mode */ +#define RCC_APB1LPENR_DACLPEN (1 << 29) /* Bit 29: DAC interface clock enable during sleep mode */ + /* Bit 30: Reserved */ +#define RCC_APB1LPENR_COMPLPEN (1 << 31) /* Bit 31: COMP interface clock enable during sleep mode */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ + /* Bits 2-7: Reserved */ +#define RCC_CSR_LSEON (1 << 8) /* Bit 8: External Low Speed oscillator enable */ +#define RCC_CSR_LSERDY (1 << 9) /* Bit 9: External Low Speed oscillator Ready */ +#define RCC_CSR_LSEBYP (1 << 10) /* Bit 10: External low-speed oscillator bypass */ +#define RCC_CSR_LSECSSON (1 << 11) /* Bit 11: CSS on LSE enable */ +#define RCC_CSR_LSECSSD (1 << 12) /* Bit 12: CSS on LSE failure Detection */ + /* Bits 13-15: Reserved */ +#define RCC_CSR_RTCSEL_SHIFT (16) /* Bits 16-17: RTC and LCD clock source selection */ +#define RCC_CSR_RTCSEL_MASK (3 << RCC_CSR_RTCSEL_SHIFT) +# define RCC_CSR_RTCSEL_NONE (0 << RCC_CSR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_CSR_RTCSEL_LSE (1 << RCC_CSR_RTCSEL_SHIFT) /* 01: LSE oscillator clock is RTC/LCD clock */ +# define RCC_CSR_RTCSEL_LSI (2 << RCC_CSR_RTCSEL_SHIFT) /* 10: LSI oscillator clock is RTC/LCD clock */ +# define RCC_CSR_RTCSEL_HSE (3 << RCC_CSR_RTCSEL_SHIFT) /* 11: Divided HSE oscillator clock is RTC/LCD clock */ +#define RCC_CSR_RTCEN (1 << 22) /* Bit 22: RTC clock enable */ +#define RCC_CSR_RTCRST (1 << 23) /* Bit 23: RTC software reset */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_RCC_H */ + diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32l15xxx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..a4558f62502698d124be388062231be45d32c263 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_syscfg.h @@ -0,0 +1,159 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32l15xxx_syscfg.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_MEMRMP (STM32_SYSCFG_BASE+STM32_SYSCFG_MEMRMP_OFFSET) +#define STM32_SYSCFG_PMC (STM32_SYSCFG_BASE+STM32_SYSCFG_PMC_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_MEMMODE_SHIFT (0) /* Bits 0-1: Memory mapping selection */ +#define SYSCFG_MEMRMP_MEMMODE_MASK (3 << SYSCFG_MEMRMP_MEMMODE_SHIFT) +# define SYSCFG_MEMRMP_MEMMODE_FLASH (0 << SYSCFG_MEMRMP_MEMMODE_SHIFT) /* 00: Main Flash memory mapped at 0x00000000 */ +# define SYSCFG_MEMRMP_MEMMODE_SYSTEM (1 << SYSCFG_MEMRMP_MEMMODE_SHIFT) /* 01: System Flash memory mapped at 0x00000000 */ +# define SYSCFG_MEMRMP_MEMMODE_FSMC (2 << SYSCFG_MEMRMP_MEMMODE_SHIFT) /* 10: FSMC */ +# define SYSCFG_MEMRMP_MEMMODE_SRAM (3 << SYSCFG_MEMRMP_MEMMODE_SHIFT) /* 11: SRAM mapped at 0x00000000 */ + /* Bits 2-7: Reserved */ +#define SYSCFG_MEMRMP_BOOTMODE_SHIFT (0) /* Bits 8-9: Boot mode selected by the boot pins */ +#define SYSCFG_MEMRMP_BOOTMODE_MASK (3 << SYSCFG_MEMRMP_BOOTMODE_SHIFT) +# define SYSCFG_MEMRMP_BOOTMODE_FLASH (0 << SYSCFG_MEMRMP_BOOTMODE_SHIFT) /* 00: Main Flash memory boot mode */ +# define SYSCFG_MEMRMP_BOOTMODE_SYSTEM (1 << SYSCFG_MEMRMP_BOOTMODE_SHIFT) /* 01: System Flash memory boot mode */ +# define SYSCFG_MEMRMP_BOOTMODE_SRAM (3 << SYSCFG_MEMRMP_BOOTMODE_SHIFT) /* 11: Embedded SRAM boot mode */ + /* Bits 10-31: Reserved */ + +/* SYSCFG peripheral mode configuration register */ + +#define SYSCFG_PMC_USBPU (1 << 0) /* Bit 0: USB pull-up enable on DP line */ +#define SYSCFG_PMC_LCDCAPA_SHIFT (1) /* Bits 1-5: LCD decoupling capacitance connection */ +#define SYSCFG_PMC_LCDCAPA_MASK (0x1f << SYSCFG_PMC_LCDCAPA_SHIFT) +# define SYSCFG_PMC_LCDCAPA_PB2 (0x01 << SYSCFG_PMC_LCDCAPA_SHIFT) /* Bit 1: Controls VLCDrail2 on PB2/LCD_VCAP2 */ +# define SYSCFG_PMC_LCDCAPA_PB12 (0x02 << SYSCFG_PMC_LCDCAPA_SHIFT) /* Bit 2: Controls VLCDrail1 on PB12/LCD_VCAP1 */ +# define SYSCFG_PMC_LCDCAPA_PB0 (0x04 << SYSCFG_PMC_LCDCAPA_SHIFT) /* Bit 3: Controls VLCDrail3 on PB0/LCD_VCAP3 */ +# define SYSCFG_PMC_LCDCAPA_PE11 (0x08 << SYSCFG_PMC_LCDCAPA_SHIFT) /* Bit 4: Controls VLCDrail1 on PE11/LCD_VCAP1 */ +# define SYSCFG_PMC_LCDCAPA_PE12 (0x10 << SYSCFG_PMC_LCDCAPA_SHIFT) /* Bit 5: Controls VLCDrail3 on PE12/LCD_VCAP3 */ + /* Bits 6-31: Reserved */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTH (5) /* 0101: PH[x] pin */ +#define SYSCFG_EXTICR_PORTF (6) /* 0110: PF[x] pin */ +#define SYSCFG_EXTICR_PORTG (7) /* 0111: PG[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + /* Bits 16-31: Reserved */ + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + /* Bits 16-31: Reserved */ + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + /* Bits 16-31: Reserved */ + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + /* Bits 16-31: Reserved */ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32L15XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_uart.h b/arch/arm/src/stm32/chip/stm32l15xxx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..dff924493355a9f576a689a31ba6623d4f43ab84 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_uart.h @@ -0,0 +1,221 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xxx_uart.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32L15XXX_UART_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32L15XXX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_SR_OFFSET 0x0000 /* Status register (32-bits) */ +#define STM32_USART_DR_OFFSET 0x0004 /* Data register (32-bits) */ +#define STM32_USART_BRR_OFFSET 0x0008 /* Baud Rate Register (32-bits) */ +#define STM32_USART_CR1_OFFSET 0x000c /* Control register 1 (32-bits) */ +#define STM32_USART_CR2_OFFSET 0x0010 /* Control register 2 (32-bits) */ +#define STM32_USART_CR3_OFFSET 0x0014 /* Control register 3 (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0018 /* Guard time and prescaler register (32-bits) */ + +/* Register Addresses ***************************************************************/ + +#if STM32_NUSART > 0 +# define STM32_USART1_SR (STM32_USART1_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART1_DR (STM32_USART1_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_SR (STM32_USART2_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART2_DR (STM32_USART2_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_SR (STM32_USART3_BASE+STM32_USART_SR_OFFSET) +# define STM32_USART3_DR (STM32_USART3_BASE+STM32_USART_DR_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_SR (STM32_UART4_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART4_DR (STM32_UART4_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_SR (STM32_UART5_BASE+STM32_USART_SR_OFFSET) +# define STM32_UART5_DR (STM32_UART5_BASE+STM32_USART_DR_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Status register */ + +#define USART_SR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_SR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_SR_NE (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_SR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_SR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_SR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_SR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_SR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_SR_LBD (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_SR_CTS (1 << 9) /* Bit 9: CTS Flag */ + +#define USART_SR_ALLBITS (0x03ff) +#define USART_SR_CLRBITS (USART_SR_CTS|USART_SR_LBD) /* Cleared by SW write to SR */ + +/* Data register */ + +#define USART_DR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_DR_MASK (0x1ff << USART_DR_SHIFT) + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Control register 1 */ + +#define USART_CR1_SBK (1 << 0) /* Bit 0: Send Break */ +#define USART_CR1_RWU (1 << 1) /* Bit 1: Receiver wakeup */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M (1 << 12) /* Bit 12: word length */ +#define USART_CR1_UE (1 << 13) /* Bit 13: USART Enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE|USART_CR1_TCIE|USART_CR1_PEIE) + +/* Control register 2 */ + +#define USART_CR2_ADD_SHIFT (0) /* Bits 3-0: Address of the USART node */ +#define USART_CR2_ADD_MASK (0x0f << USART_CR2_ADD_SHIFT) +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */ + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Compatibility definitions ********************************************************/ +/* L15 Transmit/Read registers */ + +#define STM32_USART_RDR_OFFSET STM32_USART_DR_OFFSET /* Receive data register */ +#define STM32_USART_TDR_OFFSET STM32_USART_DR_OFFSET /* Transmit data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32L15XXX_UART_H */ diff --git a/arch/arm/src/stm32/chip/stm32l15xxx_vectors.h b/arch/arm/src/stm32/chip/stm32l15xxx_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..f6be873e822f63ae923ed186cb5b419f3ed3a77a --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32l15xxx_vectors.h @@ -0,0 +1,258 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l15xxx_vectors.h + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM-based + * 32-bit MCUs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* This file is included by stm32_vectors.S. It provides the macro VECTOR that + * supplies ach STM32F10xxx vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/stm32/stm32f10xxx_irq.h. + * stm32_vectors.S will defined the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + * + * + * Vectors for low and medium density devices + */ + +#if defined(CONFIG_STM32_LOWDENSITY) || defined(CONFIG_STM32_MEDIUMDENSITY) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 45 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 45 + +#else + VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* 0: Window Watchdog interrupt */ + VECTOR(stm32_pvd, STM32_IRQ_PVD) /* 1: PVD through EXTI Line detection interrupt */ + VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* 2: Tamper through EXTI line interrupt */ + VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* 3: RTC Wakeup through EXTI line interrupt */ + VECTOR(stm32_flash, STM32_IRQ_FLASH) /* 4: Flash global interrupt */ + VECTOR(stm32_rcc, STM32_IRQ_RCC) /* 5: RCC global interrupt */ + VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* 6: EXTI Line 0 interrupt */ + VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* 7: EXTI Line 1 interrupt */ + VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* 8: EXTI Line 2 interrupt */ + VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* 9: EXTI Line 3 interrupt */ + VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* 10: EXTI Line 4 interrupt */ + VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* 11: DMA1 channel 1 global interrupt */ + VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* 12: DMA1 channel 2 global interrupt */ + VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* 13: DMA1 channel 3 global interrupt */ + VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* 14: DMA1 channel 4 global interrupt */ + VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* 15: DMA1 channel 5 global interrupt */ + VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* 16: DMA1 channel 6 global interrupt */ + VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* 17: DMA1 channel 7 global interrupt */ + VECTOR(stm32_adc1, STM32_IRQ_ADC1) /* 18: ADC1 global interrupt */ + VECTOR(stm32_usbhp, STM32_IRQ_USBHP) /* 19: USB High Priority interrupts */ + VECTOR(stm32_usblp, STM32_IRQ_USBLP) /* 20: USB Low Priority interrupt */ + VECTOR(stm32_dac, STM32_IRQ_DAC) /* 21: DAC interrupt */ + VECTOR(stm32_comp, STM32_IRQ_COMP) /* 22: Comparator wakeup through EXTI interrupt */ + VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* 23: EXTI Line[9:5] interrupts */ + VECTOR(stm32_ldc, STM32_IRQ_LDC) /* 24: LCD global interrupt */ + VECTOR(stm32_tim9, STM32_IRQ_TIM9) /* 25: TIM9 global interrupt */ + VECTOR(stm32_tim10, STM32_IRQ_TIM10) /* 26: TIM10 global interrupt */ + VECTOR(stm32_tim11, STM32_IRQ_TIM11) /* 27: TIM11 global interrupt */ + VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* 28: TIM2 global interrupt */ + VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* 29: TIM3 global interrupt */ + VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* 30: TIM4 global interrupt */ + VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* 31: I2C1 event interrupt */ + VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* 32: I2C1 error interrupt */ + VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* 33: I2C2 event interrupt */ + VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* 34: I2C2 error interrupt */ + VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* 35: SPI1 global interrupt */ + VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* 36: SPI2 global interrupt */ + VECTOR(stm32_usart1, STM32_IRQ_USART1) /* 37: USART1 global interrupt */ + VECTOR(stm32_usart2, STM32_IRQ_USART2) /* 38: USART2 global interrupt */ + VECTOR(stm32_usart3, STM32_IRQ_USART3) /* 39: USART3 global interrupt */ + VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* 40: EXTI Line[15:10] interrupts */ + VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* 41: RTC alarm through EXTI line interrupt */ + VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP) /* 42: USB wakeup from suspend through EXTI line interrupt */ + VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* 43: TIM6 global interrupt */ + VECTOR(stm32_TIM7, STM32_IRQ_TIM7) /* 44: TIM7 global interrupt */ +#endif + +/* Vectors for medium+ density devices */ + +#elif defined(CONFIG_STM32_MEDIUMPLUSDENSITY) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 61 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 54 + +#else + VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* 0: Window Watchdog interrupt */ + VECTOR(stm32_pvd, STM32_IRQ_PVD) /* 1: PVD through EXTI Line detection interrupt */ + VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* 2: Tamper through EXTI line interrupt */ + VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* 3: RTC Wakeup through EXTI line interrupt */ + VECTOR(stm32_flash, STM32_IRQ_FLASH) /* 4: Flash global interrupt */ + VECTOR(stm32_rcc, STM32_IRQ_RCC) /* 5: RCC global interrupt */ + VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* 6: EXTI Line 0 interrupt */ + VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* 7: EXTI Line 1 interrupt */ + VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* 8: EXTI Line 2 interrupt */ + VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* 9: EXTI Line 3 interrupt */ + VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* 10: EXTI Line 4 interrupt */ + VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* 11: DMA1 channel 1 global interrupt */ + VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* 12: DMA1 channel 2 global interrupt */ + VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* 13: DMA1 channel 3 global interrupt */ + VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* 14: DMA1 channel 4 global interrupt */ + VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* 15: DMA1 channel 5 global interrupt */ + VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* 16: DMA1 channel 6 global interrupt */ + VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* 17: DMA1 channel 7 global interrupt */ + VECTOR(stm32_adc1, STM32_IRQ_ADC1) /* 18: ADC1 global interrupt */ + VECTOR(stm32_usbhp, STM32_IRQ_USBHP) /* 19: USB High Priority interrupts */ + VECTOR(stm32_usblp, STM32_IRQ_USBLP) /* 20: USB Low Priority interrupt */ + VECTOR(stm32_dac, STM32_IRQ_DAC) /* 21: DAC interrupt */ + VECTOR(stm32_comp, STM32_IRQ_COMP) /* 22: Comparator wakeup through EXTI interrupt */ + VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* 23: EXTI Line[9:5] interrupts */ + VECTOR(stm32_ldc, STM32_IRQ_LDC) /* 24: LCD global interrupt */ + VECTOR(stm32_tim9, STM32_IRQ_TIM9) /* 25: TIM9 global interrupt */ + VECTOR(stm32_tim10, STM32_IRQ_TIM10) /* 26: TIM10 global interrupt */ + VECTOR(stm32_tim11, STM32_IRQ_TIM11) /* 27: TIM11 global interrupt */ + VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* 28: TIM2 global interrupt */ + VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* 29: TIM3 global interrupt */ + VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* 30: TIM4 global interrupt */ + VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* 31: I2C1 event interrupt */ + VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* 32: I2C1 error interrupt */ + VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* 33: I2C2 event interrupt */ + VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* 34: I2C2 error interrupt */ + VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* 35: SPI1 global interrupt */ + VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* 36: SPI2 global interrupt */ + VECTOR(stm32_usart1, STM32_IRQ_USART1) /* 37: USART1 global interrupt */ + VECTOR(stm32_usart2, STM32_IRQ_USART2) /* 38: USART2 global interrupt */ + VECTOR(stm32_usart3, STM32_IRQ_USART3) /* 39: USART3 global interrupt */ + VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* 40: EXTI Line[15:10] interrupts */ + VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* 41: RTC alarm through EXTI line interrupt */ + VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP) /* 42: USB wakeup from suspend through EXTI line interrupt */ + VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* 43: TIM6 global interrupt */ + VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* 44: TIM7 global interrupt */ + VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* 45: TIM5 global interrupt */ + VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* 46: SPI3 global interrupt */ + VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* 47: DMA2 channel 1 global interrupt */ + VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* 48: DMA2 channel 2 global interrupt */ + VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* 49: DMA2 channel 3 global interrupt */ + VECTOR(stm32_dma2ch4, STM32_IRQ_DMA2CH4) /* 50: DMA2 channel 4 global interrupt */ + VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* 51: DMA2 channel 5 global interrupt */ + VECTOR(stm32_aes, STM32_IRQ_AES) /* 52: AES global interrupt */ + VECTOR(stm32_compacq, STM32_IRQ_COMPACQ) /* 53: Comparator Channel Acquisition Interrupt */ +#endif + +/* Vectors for high density devices */ + +#elif defined(CONFIG_STM32_HIGHDENSITY) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 61 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 57 + +#else + VECTOR(stm32_wwdg, STM32_IRQ_WWDG) /* 0: Window Watchdog interrupt */ + VECTOR(stm32_pvd, STM32_IRQ_PVD) /* 1: PVD through EXTI Line detection interrupt */ + VECTOR(stm32_tamper, STM32_IRQ_TAMPER) /* 2: Tamper through EXTI line interrupt */ + VECTOR(stm32_rtc_wkup, STM32_IRQ_RTC_WKUP) /* 3: RTC Wakeup through EXTI line interrupt */ + VECTOR(stm32_flash, STM32_IRQ_FLASH) /* 4: Flash global interrupt */ + VECTOR(stm32_rcc, STM32_IRQ_RCC) /* 5: RCC global interrupt */ + VECTOR(stm32_exti0, STM32_IRQ_EXTI0) /* 6: EXTI Line 0 interrupt */ + VECTOR(stm32_exti1, STM32_IRQ_EXTI1) /* 7: EXTI Line 1 interrupt */ + VECTOR(stm32_exti2, STM32_IRQ_EXTI2) /* 8: EXTI Line 2 interrupt */ + VECTOR(stm32_exti3, STM32_IRQ_EXTI3) /* 9: EXTI Line 3 interrupt */ + VECTOR(stm32_exti4, STM32_IRQ_EXTI4) /* 10: EXTI Line 4 interrupt */ + VECTOR(stm32_dma1ch1, STM32_IRQ_DMA1CH1) /* 11: DMA1 channel 1 global interrupt */ + VECTOR(stm32_dma1ch2, STM32_IRQ_DMA1CH2) /* 12: DMA1 channel 2 global interrupt */ + VECTOR(stm32_dma1ch3, STM32_IRQ_DMA1CH3) /* 13: DMA1 channel 3 global interrupt */ + VECTOR(stm32_dma1ch4, STM32_IRQ_DMA1CH4) /* 14: DMA1 channel 4 global interrupt */ + VECTOR(stm32_dma1ch5, STM32_IRQ_DMA1CH5) /* 15: DMA1 channel 5 global interrupt */ + VECTOR(stm32_dma1ch6, STM32_IRQ_DMA1CH6) /* 16: DMA1 channel 6 global interrupt */ + VECTOR(stm32_dma1ch7, STM32_IRQ_DMA1CH7) /* 17: DMA1 channel 7 global interrupt */ + VECTOR(stm32_adc1, STM32_IRQ_ADC1) /* 18: ADC1 global interrupt */ + VECTOR(stm32_usbhp, STM32_IRQ_USBHP) /* 19: USB High Priority interrupts */ + VECTOR(stm32_usblp, STM32_IRQ_USBLP) /* 20: USB Low Priority interrupt */ + VECTOR(stm32_dac, STM32_IRQ_DAC) /* 21: DAC interrupt */ + VECTOR(stm32_comp, STM32_IRQ_COMP) /* 22: Comparator wakeup through EXTI interrupt */ + VECTOR(stm32_exti95, STM32_IRQ_EXTI95) /* 23: EXTI Line[9:5] interrupts */ + VECTOR(stm32_ldc, STM32_IRQ_LDC) /* 24: LCD global interrupt */ + VECTOR(stm32_tim9, STM32_IRQ_TIM9) /* 25: TIM9 global interrupt */ + VECTOR(stm32_tim10, STM32_IRQ_TIM10) /* 26: TIM10 global interrupt */ + VECTOR(stm32_tim11, STM32_IRQ_TIM11) /* 27: TIM11 global interrupt */ + VECTOR(stm32_tim2, STM32_IRQ_TIM2) /* 28: TIM2 global interrupt */ + VECTOR(stm32_tim3, STM32_IRQ_TIM3) /* 29: TIM3 global interrupt */ + VECTOR(stm32_tim4, STM32_IRQ_TIM4) /* 30: TIM4 global interrupt */ + VECTOR(stm32_i2c1ev, STM32_IRQ_I2C1EV) /* 31: I2C1 event interrupt */ + VECTOR(stm32_i2c1er, STM32_IRQ_I2C1ER) /* 32: I2C1 error interrupt */ + VECTOR(stm32_i2c2ev, STM32_IRQ_I2C2EV) /* 33: I2C2 event interrupt */ + VECTOR(stm32_i2c2er, STM32_IRQ_I2C2ER) /* 34: I2C2 error interrupt */ + VECTOR(stm32_spi1, STM32_IRQ_SPI1) /* 35: SPI1 global interrupt */ + VECTOR(stm32_spi2, STM32_IRQ_SPI2) /* 36: SPI2 global interrupt */ + VECTOR(stm32_usart1, STM32_IRQ_USART1) /* 37: USART1 global interrupt */ + VECTOR(stm32_usart2, STM32_IRQ_USART2) /* 38: USART2 global interrupt */ + VECTOR(stm32_usart3, STM32_IRQ_USART3) /* 39: USART3 global interrupt */ + VECTOR(stm32_exti1510, STM32_IRQ_EXTI1510) /* 40: EXTI Line[15:10] interrupts */ + VECTOR(stm32_rtcalrm, STM32_IRQ_RTCALRM) /* 41: RTC alarm through EXTI line interrupt */ + VECTOR(stm32_usbwkup, STM32_IRQ_USBWKUP) /* 42: USB wakeup from suspend through EXTI line interrupt */ + VECTOR(stm32_tim6, STM32_IRQ_TIM6) /* 43: TIM6 global interrupt */ + VECTOR(stm32_tim7, STM32_IRQ_TIM7) /* 44: TIM7 global interrupt */ + VECTOR(stm32_sdio, STM32_IRQ_SDIO) /* 45: SDIO Global interrupt */ + VECTOR(stm32_tim5, STM32_IRQ_TIM5) /* 46: TIM5 global interrupt */ + VECTOR(stm32_spi3, STM32_IRQ_SPI3) /* 47: SPI3 global interrupt */ + VECTOR(stm32_usart4, STM32_IRQ_UART4) /* 48: UART4 global interrupt */ + VECTOR(stm32_usart5, STM32_IRQ_UART5) /* 49: UART5 global interrupt */ + VECTOR(stm32_dma2ch1, STM32_IRQ_DMA2CH1) /* 50: DMA2 channel 1 global interrupt */ + VECTOR(stm32_dma2ch2, STM32_IRQ_DMA2CH2) /* 51: DMA2 channel 2 global interrupt */ + VECTOR(stm32_dma2ch3, STM32_IRQ_DMA2CH3) /* 52: DMA2 channel 3 global interrupt */ + VECTOR(stm32_dma2ch4, STM32_IRQ_DMA2CH4) /* 53: DMA2 channel 4 global interrupt */ + VECTOR(stm32_dma2ch5, STM32_IRQ_DMA2CH5) /* 54: DMA2 channel 5 global interrupt */ + VECTOR(stm32_aes, STM32_IRQ_AES) /* 55: AES global interrupt */ + VECTOR(stm32_compacq, STM32_IRQ_COMPACQ) /* 56: Comparator Channel Acquisition Interrupt */ +#endif + +#else +# error "Unknown STM32L density" +#endif diff --git a/arch/arm/src/stm32/gnu/stm32_vectors.S b/arch/arm/src/stm32/gnu/stm32_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..a1a39dff2f9479b633dbb09875fb173cfc12864b --- /dev/null +++ b/arch/arm/src/stm32/gnu/stm32_vectors.S @@ -0,0 +1,523 @@ +/************************************************************************************ + * arch/arm/src/stm32/gnu/stm32_vectors.S + * + * Copyright (C) 2009-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "exc_return.h" + +/************************************************************************************ + * Configuration + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the + * MSP to the stack pointer of the interrupted thread. If the interrupted thread + * was a privileged thread, that will be the MSP otherwise it will be the PSP. If + * the PSP is used, then the value of the MSP will be invalid when the interrupt + * handler returns because it will be a pointer to an old position in the + * unprivileged stack. Then when the high priority interrupt occurs and uses this + * stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt + * handler will always set the the MSP to the interrupt stack. So when the high + * priority interrupt occurs, it will either use the MSP of the last privileged + * thread to run or, in the case of the nested interrupt, the interrupt stack if + * no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************/ +/* + * 0x0800:0000 - Beginning of FLASH. Address of vectors (if not using bootloader) + * Mapped to address 0x0000:0000 at boot time. + * 0x0800:3000 - Address of vectors if using bootloader + * 0x0803:ffff - End of flash + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap + * 0x2000:ffff - End of SRAM and end of heap + */ + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "stm32_vectors.S" + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + .globl __start + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + + .macro HANDLER, label, irqno + .thumb_func +\label: + mov r0, #\irqno + b exception_common + .endm + +/************************************************************************************ + * Vectors + ************************************************************************************/ + + .section .vectors, "ax" + .code 16 + .align 2 + .globl _vectors + .type _vectors, function + +_vectors: + +/* Processor Exceptions */ + + .word IDLE_STACK /* Vector 0: Reset stack pointer */ + .word __start /* Vector 1: Reset vector */ + .word stm32_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + .word stm32_hardfault /* Vector 3: Hard fault */ + .word stm32_mpu /* Vector 4: Memory management (MPU) */ + .word stm32_busfault /* Vector 5: Bus fault */ + .word stm32_usagefault /* Vector 6: Usage fault */ + .word stm32_reserved /* Vector 7: Reserved */ + .word stm32_reserved /* Vector 8: Reserved */ + .word stm32_reserved /* Vector 9: Reserved */ + .word stm32_reserved /* Vector 10: Reserved */ + .word stm32_svcall /* Vector 11: SVC call */ + .word stm32_dbgmonitor /* Vector 12: Debug monitor */ + .word stm32_reserved /* Vector 13: Reserved */ + .word stm32_pendsv /* Vector 14: Pendable system service request */ + .word stm32_systick /* Vector 15: System tick */ + +/* External Interrupts */ + +#if !defined(CONFIG_STM32_NOEXT_VECTORS) +#undef VECTOR +#define VECTOR(l,i) .word l + +#undef UNUSED +#define UNUSED(i) .word stm32_reserved + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_vectors.h" +#else +# error "No vectors for STM32 chip" +#endif +#endif /* CONFIG_STM32_NOEXT_VECTORS */ + .size _vectors, .-_vectors + +/************************************************************************************ + * .text + ************************************************************************************/ + + .text + .type handlers, function + .thumb_func +handlers: + HANDLER stm32_reserved, STM32_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER stm32_nmi, STM32_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER stm32_hardfault, STM32_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER stm32_mpu, STM32_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER stm32_busfault, STM32_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER stm32_usagefault, STM32_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER stm32_svcall, STM32_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER stm32_dbgmonitor, STM32_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER stm32_pendsv, STM32_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER stm32_systick, STM32_IRQ_SYSTICK /* Vector 15: System tick */ + +#if !defined(CONFIG_STM32_NOEXT_VECTORS) + +#undef VECTOR +#define VECTOR(l,i) HANDLER l, i + +#undef UNUSED +#define UNUSED(i) + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_vectors.h" +#else +# error "No handlers for STM32 chip" +#endif + +#endif /* CONFIG_STM32_NOEXT_VECTORS */ + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .globl exception_common + .type exception_common, function + +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + * + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size handlers, .-handlers + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************ + * .rodata + ************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/stm32/iar/stm32_vectors.S b/arch/arm/src/stm32/iar/stm32_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..9b2c0432ba6058885a696fc9822ac2ae04becea9 --- /dev/null +++ b/arch/arm/src/stm32/iar/stm32_vectors.S @@ -0,0 +1,691 @@ +/************************************************************************************ + * arch/arm/src/stm32/iar/stm32_vectors.S + * + * Copyright (C) 2009-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "exc_return.h" + +/************************************************************************************ + * Configuration + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the + * MSP to the stack pointer of the interrupted thread. If the interrupted thread + * was a privileged thread, that will be the MSP otherwise it will be the PSP. If + * the PSP is used, then the value of the MSP will be invalid when the interrupt + * handler returns because it will be a pointer to an old position in the + * unprivileged stack. Then when the high priority interrupt occurs and uses this + * stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt + * handler will always set the the MSP to the interrupt stack. So when the high + * priority interrupt occurs, it will either use the MSP of the last privileged + * thread to run or, in the case of the nested interrupt, the interrupt stack if + * no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************/ +/* + * 0x0800:0000 - Beginning of FLASH. Address of vectors (if not using bootloader) + * Mapped to address 0x0000:0000 at boot time. + * 0x0800:3000 - Address of vectors if using bootloader + * 0x0803:ffff - End of flash + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap + * 0x2000:ffff - End of SRAM and end of heap + */ + + MODULE stm32_vectors + + /* Forward declaration of sections. */ + SECTION CSTACK:DATA:NOROOT(3) + +IDLE_STACK EQU(sfb(CSTACK)+CONFIG_IDLETHREAD_STACKSIZE-4) +HEAP_BASE EQU(sfb(CSTACK)+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + PUBLIC __vector_table + EXTERN __start + EXTERN up_doirq + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + +HANDLER MACRO label, irqno + THUMB +label: + mov r0, #irqno + b exception_common + ENDM + +/************************************************************************************ + * Vectors + ************************************************************************************/ + + SECTION .intvec:CODE:ROOT(2) + +/* _vectors replaced on __vector_table for IAR C-SPY Simulator */ +__vector_table: + +/* Processor Exceptions */ + + DCD IDLE_STACK /* Vector 0: Reset stack pointer */ + DCD __start /* Vector 1: Reset vector */ + DCD stm32_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + DCD stm32_hardfault /* Vector 3: Hard fault */ + DCD stm32_mpu /* Vector 4: Memory management (MPU) */ + DCD stm32_busfault /* Vector 5: Bus fault */ + DCD stm32_usagefault /* Vector 6: Usage fault */ + DCD stm32_reserved /* Vector 7: Reserved */ + DCD stm32_reserved /* Vector 8: Reserved */ + DCD stm32_reserved /* Vector 9: Reserved */ + DCD stm32_reserved /* Vector 10: Reserved */ + DCD stm32_svcall /* Vector 11: SVC call */ + DCD stm32_dbgmonitor /* Vector 12: Debug monitor */ + DCD stm32_reserved /* Vector 13: Reserved */ + DCD stm32_pendsv /* Vector 14: Pendable system service request */ + DCD stm32_systick /* Vector 15: System tick */ + +/* External Interrupts */ + +#if !defined(CONFIG_STM32_NOEXT_VECTORS) +#undef VECTOR +#define VECTOR(l,i) .word l + +/* IAR Assembler: + * You must not mix assembler language and C-style preprocessor directives. + * Conceptually, they are different languages and mixing them might lead to unexpected + * behavior because an assembler directive is not necessarily accepted as a part of the C + * preprocessor language. + */ + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F20XX) + DCD stm32_wwdg /* Vector 16+0: Window Watchdog interrupt */ + DCD stm32_pvd /* Vector 16+1: PVD through EXTI Line detection interrupt */ + DCD stm32_tamper /* Vector 16+2: Tamper and time stamp interrupts */ + DCD stm32_rtc_wkup /* Vector 16+3: RTC global interrupt */ + DCD stm32_flash /* Vector 16+4: Flash global interrupt */ + DCD stm32_rcc /* Vector 16+5: RCC global interrupt */ + DCD stm32_exti0 /* Vector 16+6: EXTI Line 0 interrupt */ + DCD stm32_exti1 /* Vector 16+7: EXTI Line 1 interrupt */ + DCD stm32_exti2 /* Vector 16+8: EXTI Line 2 interrupt */ + DCD stm32_exti3 /* Vector 16+9: EXTI Line 3 interrupt */ + DCD stm32_exti4 /* Vector 16+10: EXTI Line 4 interrupt */ + DCD stm32_dma1s0 /* Vector 16+11: DMA1 Stream 0 global interrupt */ + DCD stm32_dma1s1 /* Vector 16+12: DMA1 Stream 1 global interrupt */ + DCD stm32_dma1s2 /* Vector 16+13: DMA1 Stream 2 global interrupt */ + DCD stm32_dma1s3 /* Vector 16+14: DMA1 Stream 3 global interrupt */ + DCD stm32_dma1s4 /* Vector 16+15: DMA1 Stream 4 global interrupt */ + DCD stm32_dma1s5 /* Vector 16+16: DMA1 Stream 5 global interrupt */ + DCD stm32_dma1s6 /* Vector 16+17: DMA1 Stream 6 global interrupt */ + DCD stm32_adc /* Vector 16+18: ADC1, ADC2, and ADC3 global interrupt */ + DCD stm32_can1tx /* Vector 16+19: CAN1 TX interrupts */ + DCD stm32_can1rx0 /* Vector 16+20: CAN1 RX0 interrupts */ + DCD stm32_can1rx1 /* Vector 16+21: CAN1 RX1 interrupt */ + DCD stm32_can1sce /* Vector 16+22: CAN1 SCE interrupt */ + DCD stm32_exti95 /* Vector 16+23: EXTI Line[9:5] interrupts */ + DCD stm32_tim1brk /* Vector 16+24: TIM1 Break interrupt/TIM9 global interrupt */ + DCD stm32_tim1up /* Vector 16+25: TIM1 Update interrupt/TIM10 global interrupt */ + DCD stm32_tim1trgcom /* Vector 16+26: TIM1 Trigger and Commutation interrupts/TIM11 global interrupt */ + DCD stm32_tim1cc /* Vector 16+27: TIM1 Capture Compare interrupt */ + DCD stm32_tim2 /* Vector 16+28: TIM2 global interrupt */ + DCD stm32_tim3 /* Vector 16+29: TIM3 global interrupt */ + DCD stm32_tim4 /* Vector 16+30: TIM4 global interrupt */ + DCD stm32_i2c1ev /* Vector 16+31: I2C1 event interrupt */ + DCD stm32_i2c1er /* Vector 16+32: I2C1 error interrupt */ + DCD stm32_i2c2ev /* Vector 16+33: I2C2 event interrupt */ + DCD stm32_i2c2er /* Vector 16+34: I2C2 error interrupt */ + DCD stm32_spi1 /* Vector 16+35: SPI1 global interrupt */ + DCD stm32_spi2 /* Vector 16+36: SPI2 global interrupt */ + DCD stm32_usart1 /* Vector 16+37: USART1 global interrupt */ + DCD stm32_usart2 /* Vector 16+38: USART2 global interrupt */ + DCD stm32_usart3 /* Vector 16+39: USART3 global interrupt */ + DCD stm32_exti1510 /* Vector 16+40: EXTI Line[15:10] interrupts */ + DCD stm32_rtcalrm /* Vector 16+41: RTC alarm through EXTI line interrupt */ + DCD stm32_otgfswkup /* Vector 16+42: USB On-The-Go FS Wakeup through EXTI line interrupt */ + DCD stm32_tim8brk /* Vector 16+43: TIM8 Break interrupt/TIM12 global interrupt */ + DCD stm32_tim8up /* Vector 16+44: TIM8 Update interrup/TIM13 global interrupt */ + DCD stm32_tim8trgcom /* Vector 16+45: TIM8 Trigger and Commutation interrupts/TIM14 global interrupt */ + DCD stm32_tim8cc /* Vector 16+46: TIM8 Capture Compare interrupt */ + DCD stm32_dma1s7 /* Vector 16+47: DMA1 Stream 7 global interrupt */ + DCD stm32_fsmc /* Vector 16+48: FSMC global interrupt */ + DCD stm32_sdio /* Vector 16+49: SDIO global interrupt */ + DCD stm32_tim5 /* Vector 16+50: TIM5 global interrupt */ + DCD stm32_spi3 /* Vector 16+51: SPI3 global interrupt */ + DCD stm32_uart4 /* Vector 16+52: UART4 global interrupt */ + DCD stm32_uart5 /* Vector 16+53: UART5 global interrupt */ + DCD stm32_tim6 /* Vector 16+54: TIM6 global interrupt/DAC1 and DAC2 underrun error interrupts */ + DCD stm32_tim7 /* Vector 16+55: TIM7 global interrupt */ + DCD stm32_dma2s0 /* Vector 16+56: DMA2 Stream 0 global interrupt */ + DCD stm32_dma2s1 /* Vector 16+57: DMA2 Stream 1 global interrupt */ + DCD stm32_dma2s2 /* Vector 16+58: DMA2 Stream 2 global interrupt */ + DCD stm32_dma2s3 /* Vector 16+59: DMA2 Stream 3 global interrupt */ + DCD stm32_dma2s4 /* Vector 16+60: DMA2 Stream 4 global interrupt */ + DCD stm32_eth /* Vector 16+61: Ethernet global interrupt */ + DCD stm32_ethwkup /* Vector 16+62: Ethernet Wakeup through EXTI line interrupt */ + DCD stm32_can2tx /* Vector 16+63: CAN2 TX interrupts */ + DCD stm32_can2rx0 /* Vector 16+64: CAN2 RX0 interrupts */ + DCD stm32_can2rx1 /* Vector 16+65: CAN2 RX1 interrupt */ + DCD stm32_can2sce /* Vector 16+66: CAN2 SCE interrupt */ + DCD stm32_otgfs /* Vector 16+67: USB On The Go FS global interrupt */ + DCD stm32_dma2s5 /* Vector 16+68: DMA2 Stream 5 global interrupt */ + DCD stm32_dma2s6 /* Vector 16+69: DMA2 Stream 6 global interrupt */ + DCD stm32_dma2s7 /* Vector 16+70: DMA2 Stream 7 global interrupt */ + DCD stm32_usart6 /* Vector 16+71: USART6 global interrupt */ + DCD stm32_i2c3ev /* Vector 16+72: I2C3 event interrupt */ + DCD stm32_i2c3er /* Vector 16+73: I2C3 error interrupt */ + DCD stm32_otghsep1out /* Vector 16+74: USB On The Go HS End Point 1 Out global interrupt */ + DCD stm32_otghsep1in /* Vector 16+75: USB On The Go HS End Point 1 In global interrupt */ + DCD stm32_otghswkup /* Vector 16+76: USB On The Go HS Wakeup through EXTI interrupt */ + DCD stm32_otghs /* Vector 16+77: USB On The Go HS global interrupt */ + DCD stm32_dcmi /* Vector 16+78: DCMI global interrupt */ + DCD stm32_cryp /* Vector 16+79: CRYP crypto global interrupt */ + DCD stm32_hash /* Vector 16+80: Hash and Rng global interrupt */ +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# include "chip/stm32f42xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F446) +# include "chip/stm32f44xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_vectors.h" +#else +# error "No vectors for STM32 chip" +#endif +#endif /* CONFIG_STM32_NOEXT_VECTORS */ + +/************************************************************************************ + * .text + ************************************************************************************/ + + SECTION .text:CODE:NOROOT(2) + +handlers: + HANDLER stm32_reserved, STM32_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER stm32_nmi, STM32_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER stm32_hardfault, STM32_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER stm32_mpu, STM32_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER stm32_busfault, STM32_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER stm32_usagefault, STM32_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER stm32_svcall, STM32_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER stm32_dbgmonitor, STM32_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER stm32_pendsv, STM32_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER stm32_systick, STM32_IRQ_SYSTICK /* Vector 15: System tick */ + +#if !defined(CONFIG_STM32_NOEXT_VECTORS) + +/* IAR Assembler: + * You must not mix assembler language and C-style preprocessor directives. + * Conceptually, they are different languages and mixing them might lead to unexpected + * behavior because an assembler directive is not necessarily accepted as a part of the C + * preprocessor language. + */ + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F20XX) + HANDLER stm32_wwdg, STM32_IRQ_WWDG /* Vector 16+0: Window Watchdog interrupt */ + HANDLER stm32_pvd, STM32_IRQ_PVD /* Vector 16+1: PVD through EXTI Line detection interrupt */ + HANDLER stm32_tamper, STM32_IRQ_TAMPER /* Vector 16+2: Tamper and time stamp interrupts */ + HANDLER stm32_rtc_wkup, STM32_IRQ_RTC_WKUP /* Vector 16+3: RTC global interrupt */ + HANDLER stm32_flash, STM32_IRQ_FLASH /* Vector 16+4: Flash global interrupt */ + HANDLER stm32_rcc, STM32_IRQ_RCC /* Vector 16+5: RCC global interrupt */ + HANDLER stm32_exti0, STM32_IRQ_EXTI0 /* Vector 16+6: EXTI Line 0 interrupt */ + HANDLER stm32_exti1, STM32_IRQ_EXTI1 /* Vector 16+7: EXTI Line 1 interrupt */ + HANDLER stm32_exti2, STM32_IRQ_EXTI2 /* Vector 16+8: EXTI Line 2 interrupt */ + HANDLER stm32_exti3, STM32_IRQ_EXTI3 /* Vector 16+9: EXTI Line 3 interrupt */ + HANDLER stm32_exti4, STM32_IRQ_EXTI4 /* Vector 16+10: EXTI Line 4 interrupt */ + HANDLER stm32_dma1s0, STM32_IRQ_DMA1S0 /* Vector 16+11: DMA1 Stream 0 global interrupt */ + HANDLER stm32_dma1s1, STM32_IRQ_DMA1S1 /* Vector 16+12: DMA1 Stream 1 global interrupt */ + HANDLER stm32_dma1s2, STM32_IRQ_DMA1S2 /* Vector 16+13: DMA1 Stream 2 global interrupt */ + HANDLER stm32_dma1s3, STM32_IRQ_DMA1S3 /* Vector 16+14: DMA1 Stream 3 global interrupt */ + HANDLER stm32_dma1s4, STM32_IRQ_DMA1S4 /* Vector 16+15: DMA1 Stream 4 global interrupt */ + HANDLER stm32_dma1s5, STM32_IRQ_DMA1S5 /* Vector 16+16: DMA1 Stream 5 global interrupt */ + HANDLER stm32_dma1s6, STM32_IRQ_DMA1S6 /* Vector 16+17: DMA1 Stream 6 global interrupt */ + HANDLER stm32_adc, STM32_IRQ_ADC /* Vector 16+18: ADC1, ADC2, and ADC3 global interrupt */ + HANDLER stm32_can1tx, STM32_IRQ_CAN1TX /* Vector 16+19: CAN1 TX interrupts */ + HANDLER stm32_can1rx0, STM32_IRQ_CAN1RX0 /* Vector 16+20: CAN1 RX0 interrupts */ + HANDLER stm32_can1rx1, STM32_IRQ_CAN1RX1 /* Vector 16+21: CAN1 RX1 interrupt */ + HANDLER stm32_can1sce, STM32_IRQ_CAN1SCE /* Vector 16+22: CAN1 SCE interrupt */ + HANDLER stm32_exti95, STM32_IRQ_EXTI95 /* Vector 16+23: EXTI Line[9:5] interrupts */ + HANDLER stm32_tim1brk, STM32_IRQ_TIM1BRK /* Vector 16+24: TIM1 Break interrupt/TIM9 global interrupt */ + HANDLER stm32_tim1up, STM32_IRQ_TIM1UP /* Vector 16+25: TIM1 Update interrupt/TIM10 global interrupt */ + HANDLER stm32_tim1trgcom, STM32_IRQ_TIM1TRGCOM /* Vector 16+26: TIM1 Trigger and Commutation interrupts/TIM11 global interrupt */ + HANDLER stm32_tim1cc, STM32_IRQ_TIM1CC /* Vector 16+27: TIM1 Capture Compare interrupt */ + HANDLER stm32_tim2, STM32_IRQ_TIM2 /* Vector 16+28: TIM2 global interrupt */ + HANDLER stm32_tim3, STM32_IRQ_TIM3 /* Vector 16+29: TIM3 global interrupt */ + HANDLER stm32_tim4, STM32_IRQ_TIM4 /* Vector 16+30: TIM4 global interrupt */ + HANDLER stm32_i2c1ev, STM32_IRQ_I2C1EV /* Vector 16+31: I2C1 event interrupt */ + HANDLER stm32_i2c1er, STM32_IRQ_I2C1ER /* Vector 16+32: I2C1 error interrupt */ + HANDLER stm32_i2c2ev, STM32_IRQ_I2C2EV /* Vector 16+33: I2C2 event interrupt */ + HANDLER stm32_i2c2er, STM32_IRQ_I2C2ER /* Vector 16+34: I2C2 error interrupt */ + HANDLER stm32_spi1, STM32_IRQ_SPI1 /* Vector 16+35: SPI1 global interrupt */ + HANDLER stm32_spi2, STM32_IRQ_SPI2 /* Vector 16+36: SPI2 global interrupt */ + HANDLER stm32_usart1, STM32_IRQ_USART1 /* Vector 16+37: USART1 global interrupt */ + HANDLER stm32_usart2, STM32_IRQ_USART2 /* Vector 16+38: USART2 global interrupt */ + HANDLER stm32_usart3, STM32_IRQ_USART3 /* Vector 16+39: USART3 global interrupt */ + HANDLER stm32_exti1510, STM32_IRQ_EXTI1510 /* Vector 16+40: EXTI Line[15:10] interrupts */ + HANDLER stm32_rtcalrm, STM32_IRQ_RTCALRM /* Vector 16+41: RTC alarm through EXTI line interrupt */ + HANDLER stm32_otgfswkup, STM32_IRQ_OTGFSWKUP /* Vector 16+42: USB On-The-Go FS Wakeup through EXTI line interrupt */ + HANDLER stm32_tim8brk, STM32_IRQ_TIM8BRK /* Vector 16+43: TIM8 Break interrupt/TIM12 global interrupt */ + HANDLER stm32_tim8up, STM32_IRQ_TIM8UP /* Vector 16+44: TIM8 Update interrup/TIM13 global interrupt */ + HANDLER stm32_tim8trgcom, STM32_IRQ_TIM8TRGCOM /* Vector 16+45: TIM8 Trigger and Commutation interrupts/TIM14 global interrupt */ + HANDLER stm32_tim8cc, STM32_IRQ_TIM8CC /* Vector 16+46: TIM8 Capture Compare interrupt */ + HANDLER stm32_dma1s7, STM32_IRQ_DMA1S7 /* Vector 16+47: DMA1 Stream 7 global interrupt */ + HANDLER stm32_fsmc, STM32_IRQ_FSMC /* Vector 16+48: FSMC global interrupt */ + HANDLER stm32_sdio, STM32_IRQ_SDIO /* Vector 16+49: SDIO global interrupt */ + HANDLER stm32_tim5, STM32_IRQ_TIM5 /* Vector 16+50: TIM5 global interrupt */ + HANDLER stm32_spi3, STM32_IRQ_SPI3 /* Vector 16+51: SPI3 global interrupt */ + HANDLER stm32_uart4, STM32_IRQ_UART4 /* Vector 16+52: UART4 global interrupt */ + HANDLER stm32_uart5, STM32_IRQ_UART5 /* Vector 16+53: UART5 global interrupt */ + HANDLER stm32_tim6, STM32_IRQ_TIM6 /* Vector 16+54: TIM6 global interrupt/DAC1 and DAC2 underrun error interrupts */ + HANDLER stm32_tim7, STM32_IRQ_TIM7 /* Vector 16+55: TIM7 global interrupt */ + HANDLER stm32_dma2s0, STM32_IRQ_DMA2S0 /* Vector 16+56: DMA2 Stream 0 global interrupt */ + HANDLER stm32_dma2s1, STM32_IRQ_DMA2S1 /* Vector 16+57: DMA2 Stream 1 global interrupt */ + HANDLER stm32_dma2s2, STM32_IRQ_DMA2S2 /* Vector 16+58: DMA2 Stream 2 global interrupt */ + HANDLER stm32_dma2s3, STM32_IRQ_DMA2S3 /* Vector 16+59: DMA2 Stream 3 global interrupt */ + HANDLER stm32_dma2s4, STM32_IRQ_DMA2S4 /* Vector 16+60: DMA2 Stream 4 global interrupt */ + HANDLER stm32_eth, STM32_IRQ_ETH /* Vector 16+61: Ethernet global interrupt */ + HANDLER stm32_ethwkup, STM32_IRQ_ETHWKUP /* Vector 16+62: Ethernet Wakeup through EXTI line interrupt */ + HANDLER stm32_can2tx, STM32_IRQ_CAN2TX /* Vector 16+63: CAN2 TX interrupts */ + HANDLER stm32_can2rx0, STM32_IRQ_CAN2RX0 /* Vector 16+64: CAN2 RX0 interrupts */ + HANDLER stm32_can2rx1, STM32_IRQ_CAN2RX1 /* Vector 16+65: CAN2 RX1 interrupt */ + HANDLER stm32_can2sce, STM32_IRQ_CAN2SCE /* Vector 16+66: CAN2 SCE interrupt */ + HANDLER stm32_otgfs, STM32_IRQ_OTGFS /* Vector 16+67: USB On The Go FS global interrupt */ + HANDLER stm32_dma2s5, STM32_IRQ_DMA2S5 /* Vector 16+68: DMA2 Stream 5 global interrupt */ + HANDLER stm32_dma2s6, STM32_IRQ_DMA2S6 /* Vector 16+69: DMA2 Stream 6 global interrupt */ + HANDLER stm32_dma2s7, STM32_IRQ_DMA2S7 /* Vector 16+70: DMA2 Stream 7 global interrupt */ + HANDLER stm32_usart6, STM32_IRQ_USART6 /* Vector 16+71: USART6 global interrupt */ + HANDLER stm32_i2c3ev, STM32_IRQ_I2C3EV /* Vector 16+72: I2C3 event interrupt */ + HANDLER stm32_i2c3er, STM32_IRQ_I2C3ER /* Vector 16+73: I2C3 error interrupt */ + HANDLER stm32_otghsep1out, STM32_IRQ_OTGHSEP1OUT /* Vector 16+74: USB On The Go HS End Point 1 Out global interrupt */ + HANDLER stm32_otghsep1in, STM32_IRQ_OTGHSEP1IN /* Vector 16+75: USB On The Go HS End Point 1 In global interrupt */ + HANDLER stm32_otghswkup, STM32_IRQ_OTGHSWKUP /* Vector 16+76: USB On The Go HS Wakeup through EXTI interrupt */ + HANDLER stm32_otghs, STM32_IRQ_OTGHS /* Vector 16+77: USB On The Go HS global interrupt */ + HANDLER stm32_dcmi, STM32_IRQ_DCMI /* Vector 16+78: DCMI global interrupt */ + HANDLER stm32_cryp, STM32_IRQ_CRYP /* Vector 16+79: CRYP crypto global interrupt */ + HANDLER stm32_hash, STM32_IRQ_HASH /* Vector 16+80: Hash and Rng global interrupt */ +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# include "chip/stm32f42xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F446) +# include "chip/stm32f44xxx_vectors.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_vectors.h" +#else +# error "No handlers for STM32 chip" +#endif + +#endif /* CONFIG_STM32_NOEXT_VECTORS */ + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + PUBLIC exception_common + +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq l1 /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +l1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq l2 /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + * + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b l3 /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +l2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +l3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq l4 /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b l5 +l4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +l5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif + +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************ + * .rodata + ************************************************************************************/ + + SECTION .rodata:CONST:NOROOT(2) + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + PUBLIC g_idle_topstack + +g_idle_topstack: + DCD HEAP_BASE + + END diff --git a/arch/arm/src/stm32/stm32.h b/arch/arm/src/stm32/stm32.h new file mode 100644 index 0000000000000000000000000000000000000000..ee5a6497f80424894ead8d26249269bd600409e9 --- /dev/null +++ b/arch/arm/src/stm32/stm32.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Uros Platise + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_H +#define __ARCH_ARM_SRC_STM32_STM32_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Additional Configuration *********************************************************/ +/* Custom debug settings used in the STM32 port. These are managed by STM32-specific + * logic and not the common logic in include/debug.h. NOTE: Some of these also + * depend on CONFIG_DEBUG_VERBOSE + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +# undef CONFIG_DEBUG_RTC +# undef CONFIG_DEBUG_I2C +# undef CONFIG_DEBUG_CAN +# undef CONFIG_DEBUG_PWM +# undef CONFIG_DEBUG_SENSORS +#endif + +/* Peripherals **********************************************************************/ + +#include "chip.h" +#include "stm32_adc.h" +//#include "stm32_bkp.h" +#include "stm32_can.h" +#include "stm32_dbgmcu.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_flash.h" +#include "stm32_fsmc.h" +#include "stm32_gpio.h" +#include "stm32_i2c.h" +#include "stm32_ltdc.h" +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_rtc.h" +#include "stm32_sdio.h" +#include "stm32_spi.h" +#include "stm32_tim.h" +#include "stm32_uart.h" +#include "stm32_usbdev.h" +#include "stm32_wdg.h" +#include "stm32_lowputc.h" +#include "stm32_eth.h" + +#endif /* __ARCH_ARM_SRC_STM32_STM32_H */ + diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..a2d97cf51cdb75205fbe96a88607082f6ecf06b8 --- /dev/null +++ b/arch/arm/src/stm32/stm32_adc.c @@ -0,0 +1,3012 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_adc.c + * + * Copyright (C) 2011, 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32.h" +#include "stm32_dma.h" +#include "stm32_adc.h" + +/* ADC "upper half" support must be enabled */ + +#ifdef CONFIG_ADC + +/* Some ADC peripheral must be enabled */ + +#if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) || \ + defined(CONFIG_STM32_ADC3) || defined(CONFIG_STM32_ADC4) + +/* This implementation is for the STM32 F1, F2, F4 and STM32L15XX only */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) + +/* At the moment there is no proper implementation for timers external + * trigger in STM32L15XX May be added latter + */ + +#if defined(ADC_HAVE_TIMER) && defined(CONFIG_STM32_STM32L15XX) +# warning "There is no proper implementation for TIMER TRIGGERS at the moment" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* RCC reset ****************************************************************/ + +#if defined(CONFIG_STM32_STM32F10XX) +# define STM32_RCC_RSTR STM32_RCC_APB2RSTR +# define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADC1RST +# define RCC_RSTR_ADC2RST RCC_APB2RSTR_ADC2RST +# define RCC_RSTR_ADC3RST RCC_APB2RSTR_ADC3RST +# define RCC_RSTR_ADC4RST RCC_APB2RSTR_ADC4RST +#elif defined(CONFIG_STM32_STM32F30XX) +# define STM32_RCC_RSTR STM32_RCC_AHBRSTR +# define RCC_RSTR_ADC1RST RCC_AHBRSTR_ADC12RST +# define RCC_RSTR_ADC2RST RCC_AHBRSTR_ADC12RST +# define RCC_RSTR_ADC3RST RCC_AHBRSTR_ADC34RST +# define RCC_RSTR_ADC4RST RCC_AHBRSTR_ADC34RST +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_RCC_RSTR STM32_RCC_APB2RSTR +# define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADCRST +# define RCC_RSTR_ADC2RST RCC_APB2RSTR_ADCRST +# define RCC_RSTR_ADC3RST RCC_APB2RSTR_ADCRST +# define RCC_RSTR_ADC4RST RCC_APB2RSTR_ADCRST +#elif defined(CONFIG_STM32_STM32L15XX) +# define STM32_RCC_RSTR STM32_RCC_APB2RSTR +# define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADC1RST +#endif + +/* ADC interrupts ***********************************************************/ + +#ifdef CONFIG_STM32_STM32F30XX +# define STM32_ADC_DMAREG_OFFSET STM32_ADC_CFGR_OFFSET +# define ADC_DMAREG_DMA ADC_CFGR_DMAEN +# define STM32_ADC_EXTREG_OFFSET STM32_ADC_CFGR_OFFSET +# define ADC_EXTREG_EXTSEL_MASK ADC_CFGR_EXTSEL_MASK +# define ADC_EXTREG_EXTEN_MASK ADC_CFGR_EXTEN_MASK +# define ADC_EXTREG_EXTEN_DEFAULT ADC_CFGR_EXTEN_RISING +# define ADC_ISR_EOC ADC_INT_EOC +# define ADC_IER_EOC ADC_INT_EOC +# define ADC_ISR_AWD ADC_INT_AWD1 +# define ADC_IER_AWD ADC_INT_AWD1 +# define ADC_ISR_JEOC ADC_INT_JEOC +# define ADC_IER_JEOC ADC_INT_JEOC +# define ADC_ISR_OVR ADC_INT_OVR +# define ADC_IER_OVR ADC_INT_OVR +#else +# define STM32_ADC_DMAREG_OFFSET STM32_ADC_CR2_OFFSET +# define ADC_DMAREG_DMA ADC_CR2_DMA +# define STM32_ADC_EXTREG_OFFSET STM32_ADC_CR2_OFFSET +# define ADC_EXTREG_EXTSEL_MASK ADC_CR2_EXTSEL_MASK +# define STM32_ADC_ISR_OFFSET STM32_ADC_SR_OFFSET +# define STM32_ADC_IER_OFFSET STM32_ADC_CR1_OFFSET +# define ADC_ISR_EOC ADC_SR_EOC +# define ADC_IER_EOC ADC_CR1_EOCIE +# define ADC_ISR_AWD ADC_SR_AWD +# define ADC_IER_AWD ADC_CR1_AWDIE +# define ADC_ISR_JEOC ADC_SR_JEOC +# define ADC_IER_JEOC ADC_CR1_JEOCIE +# ifdef CONFIG_STM32_STM32F10XX +# define ADC_EXTREG_EXTEN_MASK ADC_CR2_EXTTRIG +# define ADC_EXTREG_EXTEN_NONE 0 +# define ADC_EXTREG_EXTEN_DEFAULT ADC_CR2_EXTTRIG +# define ADC_ISR_OVR 0 +# define ADC_IER_OVR 0 +# else +# define ADC_EXTREG_EXTEN_MASK ADC_CR2_EXTEN_MASK +# define ADC_EXTREG_EXTEN_NONE ADC_CR2_EXTEN_NONE +# define ADC_EXTREG_EXTEN_DEFAULT ADC_CR2_EXTEN_RISING +# define ADC_ISR_OVR ADC_SR_OVR +# define ADC_IER_OVR ADC_CR1_OVRIE +# endif +#endif + +#define ADC_ISR_ALLINTS (ADC_ISR_EOC | ADC_ISR_AWD | ADC_ISR_JEOC | \ + ADC_ISR_OVR) +#define ADC_IER_ALLINTS (ADC_IER_EOC | ADC_IER_AWD | ADC_IER_JEOC | \ + ADC_IER_OVR) + +/* ADC Channels/DMA ********************************************************/ +/* The maximum number of channels that can be sampled. If DMA support is + * not enabled, then only a single channel can be sampled. Otherwise, + * data overruns would occur. + */ + +#define ADC_MAX_CHANNELS_DMA 16 +#define ADC_MAX_CHANNELS_NODMA 1 + +#ifdef ADC_HAVE_DMA +# define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_DMA +#else +# define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_NODMA +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ADC_DMA_CONTROL_WORD (DMA_SCR_MSIZE_16BITS | \ + DMA_SCR_PSIZE_16BITS | \ + DMA_SCR_MINC | \ + DMA_SCR_CIRC | \ + DMA_SCR_DIR_P2M) +#else +# define ADC_DMA_CONTROL_WORD (DMA_CCR_MSIZE_16BITS | \ + DMA_CCR_PSIZE_16BITS | \ + DMA_CCR_MINC | \ + DMA_CCR_CIRC) +#endif + +/* DMA channels and interface values differ for the F1 and F4 families */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define ADC_SMPR_DEFAULT ADC_SMPR_55p5 +# define ADC_SMPR1_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR1_SMP10_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP11_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP12_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP13_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP14_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP15_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP16_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP17_SHIFT)) +# define ADC_SMPR2_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR2_SMP0_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP1_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP2_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP3_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP4_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP5_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP6_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP7_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP8_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP9_SHIFT)) +#elif defined(CONFIG_STM32_STM32F30XX) +# define ADC_SMPR_DEFAULT ADC_SMPR_61p5 +# define ADC_SMPR1_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR1_SMP1_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP2_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP3_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP4_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP5_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP6_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP7_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP8_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP9_SHIFT)) +# define ADC_SMPR2_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR2_SMP10_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP11_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP12_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP13_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP14_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP15_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP16_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP17_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP18_SHIFT)) +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define ADC_SMPR_DEFAULT ADC_SMPR_112 +# define ADC_SMPR1_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR1_SMP10_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP11_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP12_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP13_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP14_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP15_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP16_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP17_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP18_SHIFT)) +# define ADC_SMPR2_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR2_SMP0_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP1_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP2_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP3_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP4_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP5_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP6_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP7_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP8_SHIFT) | \ + (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP9_SHIFT)) +#elif defined(CONFIG_STM32_STM32L15XX) +# define ADC_CHANNELS_NUMBER 32 +# define ADC_SMPR_DEFAULT ADC_SMPR_384 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of one ADC block */ + +struct stm32_dev_s +{ + uint8_t irq; /* Interrupt generated by this ADC block */ + uint8_t nchannels; /* Number of channels */ + uint8_t cchannels; /* Number of configured channels */ + uint8_t intf; /* ADC interface number */ + uint8_t current; /* Current ADC channel being converted */ +#ifdef ADC_HAVE_DMA + uint8_t dmachan; /* DMA channel needed by this ADC */ + bool hasdma; /* True: This channel supports DMA */ +#endif +#ifdef CONFIG_STM32_STM32L15XX + /* Sample time selection. These bits must be written only when ADON=0 */ + + uint8_t sample_rate[ADC_CHANNELS_NUMBER]; +#endif +#ifdef ADC_HAVE_TIMER + uint8_t trigger; /* Timer trigger channel: 0=CC1, 1=CC2, 2=CC3, + * 3=CC4, 4=TRGO */ +#endif + xcpt_t isr; /* Interrupt handler for this ADC block */ + uint32_t base; /* Base address of registers unique to this ADC + * block */ +#ifdef ADC_HAVE_TIMER + uint32_t tbase; /* Base address of timer used by this ADC block */ + uint32_t extsel; /* EXTSEL value used by this ADC block */ + uint32_t pclck; /* The PCLK frequency that drives this timer */ + uint32_t freq; /* The desired frequency of conversions */ +#endif +#ifdef ADC_HAVE_DMA + DMA_HANDLE dma; /* Allocated DMA channel */ + + /* DMA transfer buffer */ + + uint16_t dmabuffer[ADC_MAX_SAMPLES]; +#endif + + /* List of selected ADC channels to sample */ + + uint8_t chanlist[ADC_MAX_SAMPLES]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* ADC Register access */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, + uint32_t setbits); +#endif +static uint32_t adc_getreg(FAR struct stm32_dev_s *priv, int offset); +static void adc_putreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t value); +static void adc_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t clrbits, uint32_t setbits); +#ifdef ADC_HAVE_TIMER +static uint16_t tim_getreg(FAR struct stm32_dev_s *priv, int offset); +static void tim_putreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t value); +static void tim_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t clrbits, uint16_t setbits); +static void tim_dumpregs(FAR struct stm32_dev_s *priv, + FAR const char *msg); +#endif + +static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset); + +/* ADC Interrupt Handler */ + +static int adc_interrupt(FAR struct adc_dev_s *dev); +#ifdef CONFIG_STM32_STM32L15XX +static int adc1_interrupt(int irq, FAR void *context); +#endif +#if (defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX)) && \ + (defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2)) +static int adc12_interrupt(int irq, FAR void *context); +#endif +#if (defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX)) && defined(CONFIG_STM32_ADC3) +static int adc3_interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_STM32F30XX) && defined(CONFIG_STM32_ADC4) +static int adc4_interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static int adc123_interrupt(int irq, FAR void *context); +#endif + +/* ADC Driver Methods */ + +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); +static void adc_enable(FAR struct stm32_dev_s *priv, bool enable); + +static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first, int last, + int offset); +static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch); + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_power_down_idle(FAR struct stm32_dev_s *priv, + bool pdi_high); +static void adc_power_down_delay(FAR struct stm32_dev_s *priv, + bool pdd_high); +static void adc_dels_after_conversion(FAR struct stm32_dev_s *priv, + uint32_t delay); +static void adc_select_ch_bank(FAR struct stm32_dev_s *priv, + bool chb_selected); +static int adc_ioc_change_ints(FAR struct adc_dev_s *dev, int cmd, + bool arg); +#if STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI +static void adc_enable_hsi(bool enable); +static void adc_reset_hsi_disable(FAR struct adc_dev_s *dev); +#endif +#endif + +#ifdef ADC_HAVE_TIMER +static void adc_timstart(FAR struct stm32_dev_s *priv, bool enable); +static int adc_timinit(FAR struct stm32_dev_s *priv); +#endif + +#ifdef ADC_HAVE_DMA +static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, + FAR void *arg); +#endif + +static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ADC interface operations */ + +static const struct adc_ops_s g_adcops = +{ +#if defined(CONFIG_STM32_STM32L15XX) && \ + (STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI) + .ao_reset = adc_reset_hsi_disable, +#else + .ao_reset = adc_reset, +#endif + .ao_setup = adc_setup, + .ao_shutdown = adc_shutdown, + .ao_rxint = adc_rxint, + .ao_ioctl = adc_ioctl, +}; + +/* ADC1 state */ + +#ifdef CONFIG_STM32_ADC1 +static struct stm32_dev_s g_adcpriv1 = +{ +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + .irq = STM32_IRQ_ADC12, + .isr = adc12_interrupt, +#elif defined(CONFIG_STM32_STM32L15XX) + .irq = STM32_IRQ_ADC1, + .isr = adc1_interrupt, +#else + .irq = STM32_IRQ_ADC, + .isr = adc123_interrupt, +#endif + .intf = 1, + .base = STM32_ADC1_BASE, +#ifdef ADC1_HAVE_TIMER + .trigger = CONFIG_STM32_ADC1_TIMTRIG, + .tbase = ADC1_TIMER_BASE, + .extsel = ADC1_EXTSEL_VALUE, + .pclck = ADC1_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_ADC1_SAMPLE_FREQUENCY, +#endif +#ifdef ADC1_HAVE_DMA + .dmachan = ADC1_DMA_CHAN, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_adcdev1 = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv1, +}; +#endif + +/* ADC2 state */ + +#ifdef CONFIG_STM32_ADC2 +static struct stm32_dev_s g_adcpriv2 = +{ +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + .irq = STM32_IRQ_ADC12, + .isr = adc12_interrupt, +#else + .irq = STM32_IRQ_ADC, + .isr = adc123_interrupt, +#endif + .intf = 2, + .base = STM32_ADC2_BASE, +#ifdef ADC2_HAVE_TIMER + .trigger = CONFIG_STM32_ADC2_TIMTRIG, + .tbase = ADC2_TIMER_BASE, + .extsel = ADC2_EXTSEL_VALUE, + .pclck = ADC2_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_ADC2_SAMPLE_FREQUENCY, +#endif +#ifdef ADC2_HAVE_DMA + .dmachan = ADC2_DMA_CHAN, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_adcdev2 = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv2, +}; +#endif + +/* ADC3 state */ + +#ifdef CONFIG_STM32_ADC3 +static struct stm32_dev_s g_adcpriv3 = +{ +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + .irq = STM32_IRQ_ADC3, + .isr = adc3_interrupt, +#else + .irq = STM32_IRQ_ADC, + .isr = adc123_interrupt, +#endif + .intf = 3, + .base = STM32_ADC3_BASE, +#ifdef ADC3_HAVE_TIMER + .trigger = CONFIG_STM32_ADC3_TIMTRIG, + .tbase = ADC3_TIMER_BASE, + .extsel = ADC3_EXTSEL_VALUE, + .pclck = ADC3_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_ADC3_SAMPLE_FREQUENCY, +#endif +#ifdef ADC3_HAVE_DMA + .dmachan = ADC3_DMA_CHAN, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_adcdev3 = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv3, +}; +#endif + +/* ADC4 state */ + +#ifdef CONFIG_STM32_ADC4 +static struct stm32_dev_s g_adcpriv4 = +{ + .irq = STM32_IRQ_ADC4, + .isr = adc4_interrupt, + .intf = 4, + .base = STM32_ADC4_BASE, +#ifdef ADC4_HAVE_TIMER + .trigger = CONFIG_STM32_ADC4_TIMTRIG, + .tbase = ADC4_TIMER_BASE, + .extsel = ADC4_EXTSEL_VALUE, + .pclck = ADC4_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_ADC4_SAMPLE_FREQUENCY, +#endif +#ifdef ADC4_HAVE_DMA + .dmachan = ADC4_DMA_CHAN, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_adcdev4 = +{ + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv4, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_modifyreg32 + * + * Description: + * Modify the value of a 32-bit register (not atomic). + * + * Input Parameters: + * addr - The address of the register + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, + uint32_t setbits) +{ + putreg32((getreg32(addr) & ~clrbits) | setbits, addr); +} +#endif + +/**************************************************************************** + * Name: adc_getreg + * + * Description: + * Read the value of an ADC register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t adc_getreg(FAR struct stm32_dev_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: adc_putreg + * + * Description: + * Write a value to an ADC register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to write to + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void adc_putreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: adc_modifyreg + * + * Description: + * Modify the value of an ADC register (not atomic). + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to modify + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void adc_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t clrbits, uint32_t setbits) +{ + adc_putreg(priv, offset, (adc_getreg(priv, offset) & ~clrbits) | setbits); +} + +/**************************************************************************** + * Name: tim_getreg + * + * Description: + * Read the value of an ADC timer register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static uint16_t tim_getreg(FAR struct stm32_dev_s *priv, int offset) +{ + return getreg16(priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_putreg + * + * Description: + * Write a value to an ADC timer register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to write to + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static void tim_putreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t value) +{ + putreg16(value, priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_modifyreg + * + * Description: + * Modify the value of an ADC timer register (not atomic). + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to modify + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static void tim_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t clrbits, uint16_t setbits) +{ + tim_putreg(priv, offset, (tim_getreg(priv, offset) & ~clrbits) | setbits); +} +#endif + +/**************************************************************************** + * Name: tim_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the ADC block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static void tim_dumpregs(FAR struct stm32_dev_s *priv, FAR const char *msg) +{ + avdbg("%s:\n", msg); + avdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + tim_getreg(priv, STM32_GTIM_CR1_OFFSET), + tim_getreg(priv, STM32_GTIM_CR2_OFFSET), + tim_getreg(priv, STM32_GTIM_SMCR_OFFSET), + tim_getreg(priv, STM32_GTIM_DIER_OFFSET)); + avdbg(" SR: %04x EGR: 0000 CCMR1: %04x CCMR2: %04x\n", + tim_getreg(priv, STM32_GTIM_SR_OFFSET), + tim_getreg(priv, STM32_GTIM_CCMR1_OFFSET), + tim_getreg(priv, STM32_GTIM_CCMR2_OFFSET)); + avdbg(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", + tim_getreg(priv, STM32_GTIM_CCER_OFFSET), + tim_getreg(priv, STM32_GTIM_CNT_OFFSET), + tim_getreg(priv, STM32_GTIM_PSC_OFFSET), + tim_getreg(priv, STM32_GTIM_ARR_OFFSET)); + avdbg(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + tim_getreg(priv, STM32_GTIM_CCR1_OFFSET), + tim_getreg(priv, STM32_GTIM_CCR2_OFFSET), + tim_getreg(priv, STM32_GTIM_CCR3_OFFSET), + tim_getreg(priv, STM32_GTIM_CCR4_OFFSET)); +#ifndef CONFIG_STM32_STM32L15XX + if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE) + { + avdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + tim_getreg(priv, STM32_ATIM_RCR_OFFSET), + tim_getreg(priv, STM32_ATIM_BDTR_OFFSET), + tim_getreg(priv, STM32_ATIM_DCR_OFFSET), + tim_getreg(priv, STM32_ATIM_DMAR_OFFSET)); + } + else + { + avdbg(" DCR: %04x DMAR: %04x\n", + tim_getreg(priv, STM32_GTIM_DCR_OFFSET), + tim_getreg(priv, STM32_GTIM_DMAR_OFFSET)); + } +#endif +} +#endif + +/**************************************************************************** + * Name: adc_timstart + * + * Description: + * Start (or stop) the timer counter + * + * Input Parameters: + * priv - A reference to the ADC block status + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static void adc_timstart(FAR struct stm32_dev_s *priv, bool enable) +{ + avdbg("enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the counter */ + + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN); + } + else + { + /* Disable the counter */ + + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_timinit + * + * Description: + * Initialize the timer that drivers the ADC sampling for this channel + * using the pre-calculated timer divider definitions. + * + * Input Parameters: + * priv - A reference to the ADC block status + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static int adc_timinit(FAR struct stm32_dev_s *priv) +{ + uint32_t prescaler; + uint32_t reload; + uint32_t timclk; + + uint16_t clrbits = 0; + uint16_t setbits = 0; + uint16_t cr2; + uint16_t ccmr1; + uint16_t ccmr2; + uint16_t ocmode1; + uint16_t ocmode2; + uint16_t ccenable; + uint16_t ccer; + uint16_t egr; + + /* If the timer base address is zero, then this ADC was not configured to + * use a timer. + */ + + if (priv->tbase == 0) + { + return ERROR; + } + + /* EXTSEL selection: These bits select the external event used to trigger + * the start of conversion of a regular group. NOTE: + * + * - The position with of the EXTSEL field varies from one STM32 MCU + * to another. + * - The width of the EXTSEL field varies from one STM32 MCU to another. + * - The value in priv->extsel is already shifted into the correct bit + * position. + */ + + avdbg("Initializing timers extsel = 0x%08x\n", priv->extsel); + + adc_modifyreg(priv, STM32_ADC_EXTREG_OFFSET, + ADC_EXTREG_EXTEN_MASK | ADC_EXTREG_EXTSEL_MASK, + ADC_EXTREG_EXTEN_DEFAULT | priv->extsel); + + /* Configure the timer channel to drive the ADC */ + + /* Caculate optimal values for the timer prescaler and for the timer + * reload register. If freq is the desired frequency, then + * + * reload = timclk / freq + * reload = (pclck / prescaler) / freq + * + * There are many solutions to do this, but the best solution will be the + * one that has the largest reload value and the smallest prescaler value. + * That is the solution that should give us the most accuracy in the timer + * control. Subject to: + * + * 0 <= prescaler <= 65536 + * 1 <= reload <= 65535 + * + * So ( prescaler = pclck / 65535 / freq ) would be optimal. + */ + + prescaler = (priv->pclck / priv->freq + 65534) / 65535; + + /* We need to decrement the prescaler value by one, but only, the value + * does not underflow. + */ + + if (prescaler < 1) + { + adbg("WARNING: Prescaler underflowed.\n"); + prescaler = 1; + } + + /* Check for overflow */ + + else if (prescaler > 65536) + { + adbg("WARNING: Prescaler overflowed.\n"); + prescaler = 65536; + } + + timclk = priv->pclck / prescaler; + + reload = timclk / priv->freq; + if (reload < 1) + { + adbg("WARNING: Reload value underflowed.\n"); + reload = 1; + } + else if (reload > 65535) + { + adbg("WARNING: Reload value overflowed.\n"); + reload = 65535; + } + + /* Disable the timer until we get it configured */ + + adc_timstart(priv, false); + + /* Set up the timer CR1 register. + * + * Select the Counter Mode == count up: + * + * ATIM_CR1_EDGE: The counter counts up or down depending on the + * direction bit(DIR). + * ATIM_CR1_DIR: 0: count up, 1: count down + * + * Set the clock division to zero for all + */ + + clrbits = GTIM_CR1_DIR | GTIM_CR1_CMS_MASK | GTIM_CR1_CKD_MASK; + setbits = GTIM_CR1_EDGE; + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, clrbits, setbits); + + /* Set the reload and prescaler values */ + + tim_putreg(priv, STM32_GTIM_PSC_OFFSET, prescaler-1); + tim_putreg(priv, STM32_GTIM_ARR_OFFSET, reload); + + /* Clear the advanced timers repetition counter in TIM1 */ + +#ifndef CONFIG_STM32_STM32L15XX + if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE) + { + tim_putreg(priv, STM32_ATIM_RCR_OFFSET, 0); + tim_putreg(priv, STM32_ATIM_BDTR_OFFSET, ATIM_BDTR_MOE); /* Check me */ + } +#endif + + /* TIMx event generation: Bit 0 UG: Update generation */ + + tim_putreg(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG); + + /* Handle channel specific setup */ + + ocmode1 = 0; + ocmode2 = 0; + + switch (priv->trigger) + { + case 0: /* TimerX CC1 event */ + { + ccenable = ATIM_CCER_CC1E; + ocmode1 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) | + ATIM_CCMR1_OC1PE; + + /* Set the event CC1 */ + + egr = ATIM_EGR_CC1G; + + /* Set the duty cycle by writing to the CCR register for this + * channel + */ + + tim_putreg(priv, STM32_GTIM_CCR1_OFFSET, (uint16_t)(reload >> 1)); + } + break; + + case 1: /* TimerX CC2 event */ + { + ccenable = ATIM_CCER_CC2E; + ocmode1 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) | + ATIM_CCMR1_OC2PE; + + /* Set the event CC2 */ + + egr = ATIM_EGR_CC2G; + + /* Set the duty cycle by writing to the CCR register for this + * channel + */ + + tim_putreg(priv, STM32_GTIM_CCR2_OFFSET, (uint16_t)(reload >> 1)); + } + break; + + case 2: /* TimerX CC3 event */ + { + ccenable = ATIM_CCER_CC3E; + ocmode2 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) | + ATIM_CCMR2_OC3PE; + + /* Set the event CC3 */ + + egr = ATIM_EGR_CC3G; + + /* Set the duty cycle by writing to the CCR register for this + * channel + */ + + tim_putreg(priv, STM32_GTIM_CCR3_OFFSET, (uint16_t)(reload >> 1)); + } + break; + + case 3: /* TimerX CC4 event */ + { + ccenable = ATIM_CCER_CC4E; + ocmode2 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC4M_SHIFT) | + ATIM_CCMR2_OC4PE; + + /* Set the event CC4 */ + + egr = ATIM_EGR_CC4G; + + /* Set the duty cycle by writing to the CCR register for this + * channel + */ + + tim_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1)); + } + break; + + case 4: /* TimerX TRGO event */ + { + /* TODO: TRGO support not yet implemented */ + /* Set the event TRGO */ + + ccenable = 0; + egr = GTIM_EGR_TG; + + /* Set the duty cycle by writing to the CCR register for this + * channel + */ + + tim_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1)); + } + break; + + default: + adbg("No such trigger: %d\n", priv->trigger); + return -EINVAL; + } + + /* Disable the Channel by resetting the CCxE Bit in the CCER register */ + + ccer = tim_getreg(priv, STM32_GTIM_CCER_OFFSET); + ccer &= ~ccenable; + tim_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); + + /* Fetch the CR2, CCMR1, and CCMR2 register (already have ccer) */ + + cr2 = tim_getreg(priv, STM32_GTIM_CR2_OFFSET); + ccmr1 = tim_getreg(priv, STM32_GTIM_CCMR1_OFFSET); + ccmr2 = tim_getreg(priv, STM32_GTIM_CCMR2_OFFSET); + + /* Reset the Output Compare Mode Bits and set the select output compare + * mode + */ + + ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE | + ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE); + ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE | + ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE); + ccmr1 |= ocmode1; + ccmr2 |= ocmode2; + + /* Reset the output polarity level of all channels (selects high + * polarity) + */ + + ccer &= ~(ATIM_CCER_CC1P | ATIM_CCER_CC2P | + ATIM_CCER_CC3P | ATIM_CCER_CC4P); + + /* Enable the output state of the selected channel (only) */ + + ccer &= ~(ATIM_CCER_CC1E | ATIM_CCER_CC2E | + ATIM_CCER_CC3E | ATIM_CCER_CC4E); + ccer |= ccenable; + +#ifndef CONFIG_STM32_STM32L15XX + + if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE) + { + /* Reset output N polarity level, output N state, output compare state, + * output compare N idle state. + */ + +# if defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | + ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | + ATIM_CCER_CC3NE | ATIM_CCER_CC3NP | + ATIM_CCER_CC4NP); +# else + ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | + ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | + ATIM_CCER_CC3NE | ATIM_CCER_CC3NP); +# endif + + /* Reset the output compare and output compare N IDLE State */ + + cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N | + ATIM_CR2_OIS2 | ATIM_CR2_OIS2N | + ATIM_CR2_OIS3 | ATIM_CR2_OIS3N | + ATIM_CR2_OIS4); + } +# if defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + else + { + ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP); + } +# endif + +#else + + /* For the STM32L15XX family only these timers can be used: 2-4, 6, 7, 9, 10 + * Reset the output compare and output compare N IDLE State + */ + + if (priv->tbase >= STM32_TIM2_BASE && priv->tbase <= STM32_TIM4_BASE) + { + /* Reset output N polarity level, output N state, output compare state, + * output compare N idle state. + */ + + ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | + ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | + ATIM_CCER_CC3NE | ATIM_CCER_CC3NP | + ATIM_CCER_CC4NP); + } +#endif + + /* Save the modified register values */ + + tim_putreg(priv, STM32_GTIM_CR2_OFFSET, cr2); + tim_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + tim_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2); + tim_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); + tim_putreg(priv, STM32_GTIM_EGR_OFFSET, egr); + + /* Set the ARR Preload Bit */ + + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_ARPE); + + /* Enable the timer counter */ + + adc_timstart(priv, true); + + tim_dumpregs(priv, "After starting timers"); + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc_startconv + * + * Description: + * Start (or stop) the ADC conversion process + * + * Input Parameters: + * priv - A reference to the ADC block status + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F10XX) +static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable) +{ + avdbg("enable: %d\n", enable ? 1 : 0); + + if (!enable) + { + /* Clear ADON to stop the conversion and put the ADC in the + * power down state. + */ + + adc_enable(priv, false); + } + + /* If the ADC is already on, set ADON again to start the conversion. + * Otherwise, set ADON once to wake up the ADC from the power down state. + */ + + adc_enable(priv, true); +} +#elif defined(CONFIG_STM32_STM32F30XX) +static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + avdbg("enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the conversion of regular channels */ + + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, 0, ADC_CR_ADSTART); + } + else + { + regval = adc_getreg(priv, STM32_ADC_CR_OFFSET); + + /* Is a conversion ongoing? */ + + if ((regval & ADC_CR_ADSTART) != 0) + { + /* Stop the conversion */ + + adc_putreg(priv, STM32_ADC_CR_OFFSET, regval | ADC_CR_ADSTP); + + /* Wait for the conversion to stop */ + + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADSTP) != 0); + } + } +} +#else +static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable) +{ + avdbg("enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the conversion of regular channels */ + + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, 0, ADC_CR2_SWSTART); + } + else + { + /* Stop the conversion */ + + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, ADC_CR2_SWSTART, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_rccreset + * + * Description: + * Deinitializes the ADCx peripheral registers to their default + * reset values. It could set all the ADCs configured. + * + * Input Parameters: + * regaddr - The register to read + * reset - Condition, set or reset + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset) +{ + uint32_t adcbit; + + /* Pick the appropriate bit in the APB2 reset register. + * For the STM32 F1, there is an individual bit to reset each ADC, + * but for the STM32 F2/F4, there is one common reset for all ADCs. + * THIS will probably cause some problems! + */ + + switch (priv->intf) + { +#ifdef CONFIG_STM32_ADC1 + case 1: + adcbit = RCC_RSTR_ADC1RST; + break; +#endif +#ifdef CONFIG_STM32_ADC2 + case 2: + adcbit = RCC_RSTR_ADC2RST; + break; +#endif +#ifdef CONFIG_STM32_ADC3 + case 3: + adcbit = RCC_RSTR_ADC3RST; + break; +#endif +#ifdef CONFIG_STM32_ADC4 + case 4: + adcbit = RCC_RSTR_ADC4RST; + break; +#endif + default: + return; + } + + /* Set or clear the selected bit in the APB2 reset register. + * modifyreg32() disables interrupts. Disabling interrupts is necessary + * because the APB2RTSR register is used by several different drivers. + */ + + if (reset) + { + /* Enable ADC reset state */ + + modifyreg32(STM32_RCC_RSTR, 0, adcbit); + } + else + { + /* Release ADC from reset state */ + + modifyreg32(STM32_RCC_RSTR, adcbit, 0); + } +} + +/**************************************************************************** + * Name: adc_power_down_idle + * + * Description : Enables or disables power down during the idle phase. + * + * Input Parameters: + * + * priv - pointer to the adc device structure + * pdi_high - true: The ADC is powered down when waiting for a start event + * false: The ADC is powered up when waiting for a start event + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_power_down_idle(FAR struct stm32_dev_s *priv, bool pdi_high) +{ + uint32_t regval; + + avdbg("PDI: %d\n", pdi_high ? 1 : 0); + + regval = adc_getreg(priv, STM32_ADC_CR1_OFFSET); + + if ((STM32_ADC1_CR2 & ADC_CR2_ADON) == 0) + { + if (pdi_high) + { + regval |= ADC_CR1_PDI; + } + else + { + regval &= ~ADC_CR1_PDI; + } + + adc_putreg(priv, STM32_ADC_CR1_OFFSET, regval); + } +} +#endif + +/**************************************************************************** + * Name: adc_power_down_delay + * + * Description : Enables or disables power down during the delay phase. + * + * Input Parameters: + * + * priv - pointer to the adc device structure + * pdd_high - true: The ADC is powered down when waiting for a start event + * false: The ADC is powered up when waiting for a start event + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_power_down_delay(FAR struct stm32_dev_s *priv, bool pdd_high) +{ + uint32_t regval; + + avdbg("PDD: %d\n", pdd_high ? 1 : 0); + + regval = adc_getreg(priv, STM32_ADC_CR1_OFFSET); + + if ((STM32_ADC1_CR2 & ADC_CR2_ADON) == 0) + { + if (pdd_high) + { + regval |= ADC_CR1_PDD; + } + else + { + regval &= ~ADC_CR1_PDD; + } + + adc_putreg(priv, STM32_ADC_CR1_OFFSET, regval); + } +} +#endif + +/**************************************************************************** + * Name: adc_dels_after_conversion + * + * Description : Defines the length of the delay which is applied + * after a conversion or a sequence of conversions. + * + * Input Parameters: + * + * priv - pointer to the adc device structure + * delay - delay selection (see definition in chip/chip/stm32_adc.h + * starting from line 284) + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_dels_after_conversion(FAR struct stm32_dev_s *priv, + uint32_t delay) +{ + avdbg("Delay selected: 0x%08x\n", delay); + + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, ADC_CR2_DELS_MASK, delay); +} +#endif + +/**************************************************************************** + * Name: adc_select_ch_bank + * + * Description : Selects the bank of channels to be converted + * (! Must be modified only when no conversion is on going !) + * + * Input Parameters: + * + * priv - pointer to the adc device structure + * enable - true: bank of channels B selected + * false: bank of channels A selected + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_select_ch_bank(FAR struct stm32_dev_s *priv, + bool chb_selected) +{ + avdbg("Bank of channels selected: %c\n", chb_selected ? 'B' : 'A'); + + if (chb_selected) + { + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, 0, ADC_CR2_CFG); + } + else + { + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, ADC_CR2_CFG, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_enable + * + * Description : Enables or disables the specified ADC peripheral. + * Also, starts a conversion when the ADC is not + * triggered by timers + * + * Input Parameters: + * + * enable - true: enable ADC conversion + * false: disable ADC conversion + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32F30XX +static void adc_enable(FAR struct stm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + avdbg("enable: %d\n", enable ? 1 : 0); + + regval = adc_getreg(priv, STM32_ADC_CR_OFFSET); + + if (enable) + { + /* Enable the ADC */ + + adc_putreg(priv, STM32_ADC_CR_OFFSET, regval | ADC_CR_ADEN); + + /* Wait for the ADC to be ready */ + + while ((adc_getreg(priv, STM32_ADC_ISR_OFFSET) & ADC_INT_ARDY) == 0); + } + else if ((regval & ADC_CR_ADEN) != 0 && (regval & ADC_CR_ADDIS) == 0) + { + /* Stop ongoing conversions */ + + adc_startconv(priv, false); + + /* Disable the ADC */ + + adc_putreg(priv, STM32_ADC_CR_OFFSET, regval | ADC_CR_ADDIS); + + /* Wait for the ADC to be disabled */ + + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADEN) != 0); + } +} +#else +static void adc_enable(FAR struct stm32_dev_s *priv, bool enable) +{ +#ifdef ADC_SR_ADONS + bool enabled = (adc_getreg(priv, STM32_ADC_SR_OFFSET) & ADC_SR_ADONS) != 0; +#else + bool enabled = false; +#endif + + avdbg("enable: %d\n", enable ? 1 : 0); + + if (!enabled && enable) + { + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, 0, ADC_CR2_ADON); + } + else if (enabled && !enable) + { + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, ADC_CR2_ADON, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_write_sample_time_registers + * + * Description: + * Writes previously defined values into ADC_SMPR0, ADC_SMPR1, ADC_SMPR2 + * and ADC_SMPR3 registers + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_write_sample_time_registers(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t value = 0; + uint8_t i; + uint8_t shift; + + /* Sampling time individually for each channel + * 000: 4 cycles + * 001: 9 cycles + * 010: 16 cycles + * 011: 24 cycles + * 100: 48 cycles + * 101: 96 cycles + * 110: 192 cycles + * 111: 384 cycles - selected for all channels + */ + + for (i = 0, shift = 0; i < 32; i++) + { + value |= priv->sample_rate[i] << (shift * 3); + switch (i) + { + case 9: + adc_putreg(priv, STM32_ADC_SMPR3_OFFSET, value); + shift = 0; + value = 0; + break; + + case 19: + adc_putreg(priv, STM32_ADC_SMPR2_OFFSET, value); + shift = 0; + value = 0; + break; + + case 29: + adc_putreg(priv, STM32_ADC_SMPR1_OFFSET, value); + shift = 0; + value = 0; + break; + + case 31: + adc_putreg(priv, STM32_ADC_SMPR0_OFFSET, value); + shift = 0; + value = 0; + break; + + default: + shift++; + break; + } + } +} +#endif + +/**************************************************************************** + * Name: adc_dmacovcallback + * + * Description: + * Callback for DMA. Called from the DMA transfer complete interrupt after + * all channels have been converted and transferred with DMA. + * + * Input Parameters: + * + * handle - handle to DMA + * isr - + * arg - adc device + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef ADC_HAVE_DMA +static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) +{ + FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg; + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int i; + + for (i = 0; i < priv->nchannels; i++) + { + adc_receive(dev, priv->current, priv->dmabuffer[priv->current]); + priv->current++; + if (priv->current >= priv->nchannels) + { + /* Restart the conversion sequence from the beginning */ + + priv->current = 0; + } + } + + /* Restart DMA for the next conversion series */ + + adc_modifyreg(priv, STM32_ADC_DMAREG_OFFSET, ADC_DMAREG_DMA, 0); + adc_modifyreg(priv, STM32_ADC_DMAREG_OFFSET, 0, ADC_DMAREG_DMA); +} +#endif + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before adc_setup() and on error conditions. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_reset(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + irqstate_t flags; + uint32_t clrbits; + uint32_t setbits; +#ifdef ADC_HAVE_TIMER + int ret; +#endif + + allvdbg("intf: %d\n", priv->intf); + flags = enter_critical_section(); + +#if defined(CONFIG_STM32_STM32L15XX) && \ + (STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI) + + /* The STM32L15XX family uses HSI as an independent clock-source + * for the ADC + */ + + adc_enable_hsi(true); + +#endif + +#ifdef CONFIG_STM32_STM32F30XX + + /* Turn off the ADC so we can write the RCC bits */ + + adc_enable(priv, false); + +#endif + + /* Enable ADC reset state */ + + adc_rccreset(priv, true); + + /* Release ADC from reset state */ + + adc_rccreset(priv, false); + +#ifdef CONFIG_STM32_STM32F30XX + + /* Set voltage regular enable to intermediate state */ + + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, ADC_CR_ADVREGEN_MASK, + ADC_CR_ADVREGEN_INTER); + + /* Enable the ADC voltage regulator */ + + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, ADC_CR_ADVREGEN_MASK, + ADC_CR_ADVREGEN_ENABLED); + + /* Wait for the ADC voltage regulator to startup */ + + up_udelay(10); + +#if 0 /* Doesn't work */ + + /* Calibrate the ADC */ + + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, ADC_CR_ADCALDIF, AD_CR_ADCAL); + + /* Wait for the calibration to complete */ + + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADCAL) != 0); + +#endif + + /* Initialize the watchdog 1 threshold register */ + + adc_putreg(priv, STM32_ADC_TR1_OFFSET, 0x0fff0000); + +#else + + /* Initialize the watchdog high threshold register */ + + adc_putreg(priv, STM32_ADC_HTR_OFFSET, 0x00000fff); + + /* Initialize the watchdog low threshold register */ + + adc_putreg(priv, STM32_ADC_LTR_OFFSET, 0x00000000); + +#endif + + /* Initialize the same sample time for each ADC. + * During sample cycles channel selection bits must remain unchanged. + */ + +#ifdef CONFIG_STM32_STM32L15XX + adc_write_sample_time_registers(dev); +#else + adc_putreg(priv, STM32_ADC_SMPR1_OFFSET, ADC_SMPR1_DEFAULT); + adc_putreg(priv, STM32_ADC_SMPR2_OFFSET, ADC_SMPR2_DEFAULT); +#endif + +#ifdef CONFIG_STM32_STM32F30XX + + /* Enable the analog watchdog */ + + clrbits = ADC_CFGR_AWD1CH_MASK; + setbits = ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | + (priv->chanlist[0] << ADC_CFGR_AWD1CH_SHIFT); + + /* Set the resolution of the conversion */ + + clrbits |= ADC_CFGR_RES_MASK; + setbits |= ADC_CFGR_RES_12BIT; + +#ifdef ADC_HAVE_DMA + if (priv->hasdma) + { + /* Set DMA one shot mode */ + + clrbits |= ADC_CFGR_DMACFG; + + /* Enable DMA */ + + setbits |= ADC_CFGR_DMAEN; + } +#endif + + /* Disable continuous mode and set align to right */ + + clrbits |= ADC_CFGR_CONT | ADC_CFGR_ALIGN; + + /* Disable external trigger for regular channels */ + + clrbits |= ADC_CFGR_EXTEN_MASK; + setbits |= ADC_CFGR_EXTEN_NONE; + + /* Set CFGR configuration */ + + adc_modifyreg(priv, STM32_ADC_CFGR_OFFSET, clrbits, setbits); + + /* Enable interrupt flags, but disable overrun interrupt */ + + clrbits = ADC_IER_OVR; + setbits = ADC_IER_ALLINTS & ~ADC_IER_OVR; + + /* Set IER configuration */ + + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, clrbits, setbits); + +#else + + /* Enable the analog watchdog */ + + clrbits = ADC_CR1_AWDCH_MASK; + setbits = ADC_CR1_AWDEN | (priv->chanlist[0] << ADC_CR1_AWDCH_SHIFT); + +#ifdef CONFIG_STM32_STM32F10XX + + /* Set independent mode */ + + clrbits |= ADC_CR1_DUALMOD_MASK; + setbits |= ADC_CR1_IND; + +#else + + /* Set the resolution of the conversion */ + + clrbits |= ADC_CR1_RES_MASK; + setbits |= ADC_CR1_RES_12BIT; + +#endif + +#ifdef ADC_HAVE_DMA + if (priv->hasdma) + { + setbits |= ADC_CR1_SCAN; + } +#endif + + /* Enable interrupt flags, but disable overrun interrupt */ + + clrbits |= ADC_IER_OVR; + setbits |= ADC_IER_ALLINTS & ~ADC_IER_OVR; + + /* Set CR1 configuration */ + + adc_modifyreg(priv, STM32_ADC_CR1_OFFSET, clrbits, setbits); + +#ifdef CONFIG_STM32_STM32L15XX + + /* Disables power down during the delay phase */ + + adc_power_down_idle(priv, false); + adc_power_down_delay(priv, false); + + /* Select the bank of channels A */ + + adc_select_ch_bank(priv, false); + + /* Delay until the converted data has been read */ + + adc_dels_after_conversion(priv, ADC_CR2_DELS_TILLRD); + +#endif + + /* Disable continuous mode and set align to right */ + + clrbits = ADC_CR2_CONT | ADC_CR2_ALIGN; + setbits = 0; + + /* Disable external trigger for regular channels */ + + clrbits |= ADC_EXTREG_EXTEN_MASK; + setbits |= ADC_EXTREG_EXTEN_NONE; + +#ifdef ADC_HAVE_DMA + if (priv->hasdma) + { + setbits |= ADC_CR2_DMA; + } +#endif + + /* Set CR2 configuration */ + + adc_modifyreg(priv, STM32_ADC_CR2_OFFSET, clrbits, setbits); + +#endif + + /* Configuration of the channel conversions */ + + adc_set_ch(dev, 0); + + /* ADC CCR configuration */ + +#if defined(CONFIG_STM32_STM32F30XX) + clrbits = ADC_CCR_DUAL_MASK | ADC_CCR_DELAY_MASK | ADC_CCR_DMACFG | + ADC_CCR_MDMA_MASK | ADC_CCR_CKMODE_MASK | ADC_CCR_VREFEN | + ADC_CCR_TSEN | ADC_CCR_VBATEN; + setbits = ADC_CCR_DUAL_IND | ADC_CCR_DELAY(0) | ADC_CCR_MDMA_DISABLED | + ADC_CCR_CKMODE_ASYNCH; + + if (priv->base == STM32_ADC1_BASE || priv->base == STM32_ADC2_BASE) + { + stm32_modifyreg32(STM32_ADC12_CCR, clrbits, setbits); + } + else + { + stm32_modifyreg32(STM32_ADC34_CCR, clrbits, setbits); + } +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) + clrbits = ADC_CCR_ADCPRE_MASK | ADC_CCR_TSVREFE; + setbits = ADC_CCR_ADCPRE_DIV2; + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + clrbits |= ADC_CCR_MULTI_MASK | ADC_CCR_DELAY_MASK | ADC_CCR_DDS | + ADC_CCR_DMA_MASK | ADC_CCR_VBATE; + setbits |= ADC_CCR_MULTI_NONE | ADC_CCR_DMA_DISABLED; +#endif + + stm32_modifyreg32(STM32_ADC_CCR, clrbits, setbits); +#endif + +#ifdef ADC_HAVE_DMA + + /* Enable DMA */ + + if (priv->hasdma) + { + /* Stop and free DMA if it was started before */ + + if (priv->dma != NULL) + { + stm32_dmastop(priv->dma); + stm32_dmafree(priv->dma); + } + + priv->dma = stm32_dmachannel(priv->dmachan); + + stm32_dmasetup(priv->dma, + priv->base + STM32_ADC_DR_OFFSET, + (uint32_t)priv->dmabuffer, + priv->nchannels, + ADC_DMA_CONTROL_WORD); + + stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); + } + +#endif + + /* Set ADON to wake up the ADC from the power down state */ + + adc_enable(priv, true); + +#ifdef ADC_HAVE_TIMER + if (priv->tbase != 0) + { + ret = adc_timinit(priv); + if (ret < 0) + { + adbg("adc_timinit failed: %d\n", ret); + } + } +#ifndef CONFIG_ADC_NO_STARTUP_CONV + else +#endif +#endif +#ifndef CONFIG_ADC_NO_STARTUP_CONV + { + adc_startconv(priv, true); + } +#endif + + leave_critical_section(flags); + +#ifdef CONFIG_STM32_STM32F30XX + avdbg("ISR: 0x%08x CR: 0x%08x CFGR: 0x%08x\n", + adc_getreg(priv, STM32_ADC_ISR_OFFSET), + adc_getreg(priv, STM32_ADC_CR_OFFSET), + adc_getreg(priv, STM32_ADC_CFGR_OFFSET)); +#else + avdbg("SR: 0x%08x CR1: 0x%08x CR2: 0x%08x\n", + adc_getreg(priv, STM32_ADC_SR_OFFSET), + adc_getreg(priv, STM32_ADC_CR1_OFFSET), + adc_getreg(priv, STM32_ADC_CR2_OFFSET)); +#endif + + avdbg("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x\n", + adc_getreg(priv, STM32_ADC_SQR1_OFFSET), + adc_getreg(priv, STM32_ADC_SQR2_OFFSET), + adc_getreg(priv, STM32_ADC_SQR3_OFFSET)); + +#if defined(CONFIG_STM32_STM32F30XX) + avdbg("SQR4: 0x%08x\n", adc_getreg(priv, STM32_ADC_SQR4_OFFSET)); +#elif defined(CONFIG_STM32_STM32L15XX) + avdbg("SQR4: 0x%08x SQR5: 0x%08x\n", + adc_getreg(priv, STM32_ADC_SQR4_OFFSET) + adc_getreg(priv, STM32_ADC_SQR5_OFFSET)); +#endif + +#if defined(CONFIG_STM32_STM32F30XX) + if (priv->base == STM32_ADC1_BASE || priv->base == STM32_ADC2_BASE) + { + avdbg("CCR: 0x%08x\n", getreg32(STM32_ADC12_CCR)); + } + else + { + avdbg("CCR: 0x%08x\n", getreg32(STM32_ADC34_CCR)); + } +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) + avdbg("CCR: 0x%08x\n", getreg32(STM32_ADC_CCR)); +#endif +} + +/**************************************************************************** + * Name: adc_reset_hsi_disable + * + * Description: + * Reset the ADC device with HSI and ADC shut down. Called early to + * initialize the hardware. This is called, before adc_setup() and on + * error conditions. In STM32L15XX case sometimes HSI must be shut + * down after the first initialization + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32L15XX) && \ + (STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI) +static void adc_reset_hsi_disable(FAR struct adc_dev_s *dev) +{ + adc_reset(dev); + adc_shutdown(dev); +} +#endif + +/**************************************************************************** + * Name: adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. + * Interrupts are all disabled upon return. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_setup(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int ret; + + /* Attach the ADC interrupt */ + + ret = irq_attach(priv->irq, priv->isr); + if (ret < 0) + { + avdbg("irq_attach failed: %d\n", ret); + return ret; + } + + /* Make sure that the ADC device is in the powered up, reset state */ + + adc_reset(dev); + + /* Enable the ADC interrupt */ + + avdbg("Enable the ADC interrupt: irq=%d\n", priv->irq); + up_enable_irq(priv->irq); + + return ret; +} + +/**************************************************************************** + * Name: adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + adc_enable(priv, false); +#if defined(CONFIG_STM32_STM32L15XX) && \ + (STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI) + adc_enable_hsi(false); +#endif + + /* Disable ADC interrupts and detach the ADC interrupt handler */ + + up_disable_irq(priv->irq); + irq_detach(priv->irq); + + /* Disable and reset the ADC module */ + + adc_rccreset(priv, true); +} + +/**************************************************************************** + * Name: adc_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + avdbg("intf: %d enable: %d\n", priv->intf, enable ? 1 : 0); + + if (enable) + { + /* Enable the end-of-conversion ADC and analog watchdog interrupts */ + + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_ALLINTS); + } + else + { + /* Disable all ADC interrupts */ + + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, ADC_IER_ALLINTS, 0); + } +} + +/**************************************************************************** + * Name: adc_enable_tvref_register + * + * Description: + * Enable/disable the temperature sensor and the VREFINT channel. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * enable - true: Temperature sensor and V REFINT channel enabled + * (ch 16 and 17) + * false: Temperature sensor and V REFINT channel disabled + * (ch 16 and 17) + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_ioc_enable_tvref_register(FAR struct adc_dev_s *dev, + bool enable) +{ + if (enable) + { + stm32_modifyreg32(STM32_ADC_CCR, 0, ADC_CCR_TSVREFE); + } + else + { + stm32_modifyreg32(STM32_ADC_CCR, ADC_CCR_TSVREFE, 0); + } + + avdbg("STM32_ADC_CCR value: 0x%08x\n", getreg32(STM32_ADC_CCR)); +} +#endif + +/**************************************************************************** + * Name: adc_ioc_change_sleep_between_opers + * + * Description: + * Changes PDI and PDD bits to save battery. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * cmd - command + * arg - arguments passed with command + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static int adc_ioc_change_sleep_between_opers(FAR struct adc_dev_s *dev, + int cmd, bool arg) +{ + int ret = OK; + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + adc_enable(priv, false); + + switch (cmd) + { + case IO_ENABLE_DISABLE_PDI: + adc_power_down_idle(priv, arg); + break; + + case IO_ENABLE_DISABLE_PDD: + adc_power_down_delay(priv, arg); + break; + + case IO_ENABLE_DISABLE_PDD_PDI: + adc_power_down_idle(priv, arg); + adc_power_down_delay(priv, arg); + break; + + default: + avdbg("unknown cmd: %d\n", cmd); + break; + } + + adc_enable(priv, true); + + return ret; +} +#endif + +/**************************************************************************** + * Name: adc_ioc_enable_awd_int + * + * Description: + * Turns ON/OFF ADC analog watchdog interrupt. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * arg - true: Turn ON interrupt + * false: Turn OFF interrupt + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_ioc_enable_awd_int(FAR struct stm32_dev_s *priv, bool enable) +{ + if (enable) + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_AWD); + } + else + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, ADC_IER_AWD, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_ioc_enable_eoc_int + * + * Description: + * Turns ON/OFF ADC EOC interrupt. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * arg - true: Turn ON interrupt + * false: Turn OFF interrupt + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_ioc_enable_eoc_int(FAR struct stm32_dev_s *priv, bool enable) +{ + if (enable) + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_EOC); + } + else + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, ADC_IER_EOC, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_ioc_enable_jeoc_int + * + * Description: + * Turns ON/OFF ADC injected channels interrupt. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * arg - true: Turn ON interrupt + * false: Turn OFF interrupt + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_ioc_enable_jeoc_int(FAR struct stm32_dev_s *priv, bool enable) +{ + if (enable) + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_JEOC); + } + else + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, ADC_IER_JEOC, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_ioc_enable_ovr_int + * + * Description: + * Turns ON/OFF ADC overrun interrupt. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * arg - true: Turn ON interrupt + * false: Turn OFF interrupt + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static void adc_ioc_enable_ovr_int(FAR struct stm32_dev_s *priv, bool enable) +{ + if (enable) + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_OVR); + } + else + { + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, ADC_IER_OVR, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_ioc_change_ints + * + * Description: + * Turns ON/OFF ADC interrupts. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * cmd - command + * arg - arguments passed with command + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static int adc_ioc_change_ints(FAR struct adc_dev_s *dev, int cmd, bool arg) +{ + int ret = OK; + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + switch (cmd) + { + case IO_ENABLE_DISABLE_AWDIE: + adc_ioc_enable_awd_int(priv, arg); + break; + + case IO_ENABLE_DISABLE_EOCIE: + adc_ioc_enable_eoc_int(priv, arg); + break; + + case IO_ENABLE_DISABLE_JEOCIE: + adc_ioc_enable_jeoc_int(priv, arg); + break; + + case IO_ENABLE_DISABLE_OVRIE: + adc_ioc_enable_ovr_int(priv, arg); + break; + + case IO_ENABLE_DISABLE_ALL_INTS: + adc_ioc_enable_awd_int(priv, arg); + adc_ioc_enable_eoc_int(priv, arg); + adc_ioc_enable_jeoc_int(priv, arg); + adc_ioc_enable_ovr_int(priv, arg); + break; + + default: + avdbg("unknown cmd: %d\n", cmd); + break; + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: adc_ioc_wait_rcnr_zeroed + * + * Description: + * For the STM3215XX-family the ADC_SR_RCNR bit must be zeroed, + * before next conversion. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static int adc_ioc_wait_rcnr_zeroed(FAR struct stm32_dev_s *priv) +{ + int i; + + for (i = 0; i < 30000; i++) + { + if ((adc_getreg(priv, STM32_ADC_SR_OFFSET) & ADC_SR_RCNR) == 0) + { + return OK; + } + } + + return -ENODATA; +} +#endif + +/**************************************************************************** + * Name: adc_enable_hsi + * + * Description: + * Enable/Disable HSI clock + * + * Input Parameters: + * enable - true : HSI clock for ADC enabled + * false : HSI clock for ADC disabled + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32L15XX) && \ + (STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI) +static void adc_enable_hsi(bool enable) +{ + if (enable) + { + /* Enable the HSI */ + + stm32_modifyreg32(STM32_RCC_CR, 0, RCC_CR_HSION); + while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0); + } + else + { + /* Disable the HSI */ + + stm32_modifyreg32(STM32_RCC_CR, RCC_CR_HSION, 0); + } +} +#endif + +/**************************************************************************** + * Name: adc_sqrbits + ****************************************************************************/ + +static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first, int last, + int offset) +{ + uint32_t bits = 0; + int i; + + for (i = first - 1; + i < priv->nchannels && i < last; + i++, offset += ADC_SQ_OFFSET) + { + bits |= (uint32_t)priv->chanlist[i] << offset; + } + + return bits; +} + +/**************************************************************************** + * Name: adc_set_ch + * + * Description: + * Sets the ADC channel. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * ch - ADC channel number + 1. 0 reserved for all configured channels + * + * Returned Value: + * int - errno + * + ****************************************************************************/ + +static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t bits; + int i; + + if (ch == 0) + { + priv->current = 0; + priv->nchannels = priv->cchannels; + } + else + { + for (i = 0; i < priv->cchannels && priv->chanlist[i] != ch - 1; i++); + + if (i >= priv->cchannels) + { + return -ENODEV; + } + + priv->current = i; + priv->nchannels = 1; + } + +#ifdef STM32_ADC_SQR5_OFFSET + bits = adc_sqrbits(priv, ADC_SQR5_FIRST, ADC_SQR5_LAST, ADC_SQR5_SQ_OFFSET); + adc_modifyreg(priv, STM32_ADC_SQR5_OFFSET, ~ADC_SQR5_RESERVED, bits); +#endif + +#ifdef STM32_ADC_SQR4_OFFSET + bits = adc_sqrbits(priv, ADC_SQR4_FIRST, ADC_SQR4_LAST, ADC_SQR4_SQ_OFFSET); + adc_modifyreg(priv, STM32_ADC_SQR4_OFFSET, ~ADC_SQR4_RESERVED, bits); +#endif + + bits = adc_sqrbits(priv, ADC_SQR3_FIRST, ADC_SQR3_LAST, ADC_SQR3_SQ_OFFSET); + adc_modifyreg(priv, STM32_ADC_SQR3_OFFSET, ~ADC_SQR3_RESERVED, bits); + + bits = adc_sqrbits(priv, ADC_SQR2_FIRST, ADC_SQR2_LAST, ADC_SQR2_SQ_OFFSET); + adc_modifyreg(priv, STM32_ADC_SQR2_OFFSET, ~ADC_SQR2_RESERVED, bits); + + bits = ((uint32_t)priv->nchannels - 1) << ADC_SQR1_L_SHIFT | + adc_sqrbits(priv, ADC_SQR1_FIRST, ADC_SQR1_LAST, ADC_SQR1_SQ_OFFSET); + adc_modifyreg(priv, STM32_ADC_SQR1_OFFSET, ~ADC_SQR1_RESERVED, bits); + + return OK; +} + +/**************************************************************************** + * Name: adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * cmd - command + * arg - arguments passed with command + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int ret = OK; + + switch (cmd) + { + case ANIOC_TRIGGER: + adc_startconv(priv, true); + break; + +#ifdef CONFIG_STM32_STM32L15XX + case IO_ENABLE_TEMPER_VOLT_CH: + adc_ioc_enable_tvref_register(dev, *(bool *)arg); + break; + + case IO_ENABLE_DISABLE_PDI: + case IO_ENABLE_DISABLE_PDD: + case IO_ENABLE_DISABLE_PDD_PDI: + adc_ioc_change_sleep_between_opers(dev, cmd, *(bool *)arg); + break; + + case IO_ENABLE_DISABLE_AWDIE: + case IO_ENABLE_DISABLE_EOCIE: + case IO_ENABLE_DISABLE_JEOCIE: + case IO_ENABLE_DISABLE_OVRIE: + case IO_ENABLE_DISABLE_ALL_INTS: + adc_ioc_change_ints(dev, cmd, *(bool *)arg); + break; + + case IO_START_CONV: + { + uint8_t ch = ((uint8_t)arg); + + ret = adc_ioc_wait_rcnr_zeroed(priv); + if (ret < 0) + { + set_errno(-ret); + return ret; + } + + ret = adc_set_ch(dev, ch); + if (ret < 0) + { + set_errno(-ret); + return ret; + } + + if (ch) + { + /* Clear fifo */ + + dev->ad_recv.af_head = 0; + dev->ad_recv.af_tail = 0; + } + + adc_startconv(priv, true); + } + break; + +#if STM32_CFGR_PLLSRC != 0 || STM32_SYSCLK_SW != RCC_CFGR_SW_HSI + case IO_STOP_ADC: + adc_enable(priv, false); + adc_enable_hsi(false); + break; + + case IO_START_ADC: + adc_enable_hsi(true); + adc_enable(priv, true); + break; +#endif +#endif /* CONFIG_STM32_STM32L15XX */ + + default: + adbg("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: adc_interrupt + * + * Description: + * Common ADC interrupt handler. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int adc_interrupt(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t regval; + uint32_t pending; + int32_t data; + + regval = adc_getreg(priv, STM32_ADC_ISR_OFFSET); + pending = regval & ADC_ISR_ALLINTS; + if (pending == 0) + { + return OK; + } + + /* Identifies the interruption AWD, OVR or EOC */ + + if ((regval & ADC_ISR_AWD) != 0) + { + alldbg("WARNING: Analog Watchdog, Value converted out of range!\n"); + } + + if ((regval & ADC_ISR_OVR) != 0) + { + alldbg("WARNING: Overrun has occurred!\n"); + } + + /* EOC: End of conversion */ + + if ((regval & ADC_ISR_EOC) != 0) + { + /* Read the converted value and clear EOC bit + * (It is cleared by reading the ADC_DR) + */ + + data = adc_getreg(priv, STM32_ADC_DR_OFFSET) & ADC_DR_RDATA_MASK; + + /* Give the ADC data to the ADC driver. adc_receive() accepts 3 + * parameters: + * + * 1) The first is the ADC device instance for this ADC block. + * 2) The second is the channel number for the data, and + * 3) The third is the converted data for the channel. + */ + + adc_receive(dev, priv->chanlist[priv->current], data); + + /* Set the channel number of the next channel that will complete + * conversion. + */ + + priv->current++; + + if (priv->current >= priv->nchannels) + { + /* Restart the conversion sequence from the beginning */ + + priv->current = 0; + } + } + + regval &= ~pending; + adc_putreg(priv, STM32_ADC_ISR_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Name: adc1_interrupt + * + * Description: + * ADC interrupt handler for the STM32 L15XX family. + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt. + * context - Architecture specific register save information. + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +static int adc1_interrupt(int irq, FAR void *context) +{ + adc_interrupt(&g_adcdev1); + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc12_interrupt + * + * Description: + * ADC1/2 interrupt handler for the STM32 F1/F3 families. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if (defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX)) && \ + (defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2)) +static int adc12_interrupt(int irq, FAR void *context) +{ +#ifdef CONFIG_STM32_ADC1 + adc_interrupt(&g_adcdev1); +#endif + +#ifdef CONFIG_STM32_ADC2 + adc_interrupt(&g_adcdev2); +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc3_interrupt + * + * Description: + * ADC3 interrupt handler for the STM32 F1 family. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if (defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX)) && defined(CONFIG_STM32_ADC3) +static int adc3_interrupt(int irq, FAR void *context) +{ + adc_interrupt(&g_adcdev3); + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc4_interrupt + * + * Description: + * ADC4 interrupt handler for the STM32 F3 family. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F30XX) && defined(CONFIG_STM32_ADC4) +static int adc4_interrupt(int irq, FAR void *context) +{ +#ifdef CONFIG_STM32_ADC4 + adc_interrupt(&g_adcdev4); +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc123_interrupt + * + * Description: + * ADC1/2/3 interrupt handler for the STM32 F2/F4 families. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static int adc123_interrupt(int irq, FAR void *context) +{ +#ifdef CONFIG_STM32_ADC1 + adc_interrupt(&g_adcdev1); +#endif + +#ifdef CONFIG_STM32_ADC2 + adc_interrupt(&g_adcdev2); +#endif + +#ifdef CONFIG_STM32_ADC3 + adc_interrupt(&g_adcdev3); +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc_change_sample_time + * + * Description: + * Changes sample times for specified channels. This method + * doesn't make any register writing. So, it's only stores the information. + * Values provided by user will be written in registers only on the next + * ADC peripheral start, as it was told to do in manual. However, before + * very first start, user can call this method and override default values + * either for every channels or for only some predefined by user channel(s) + * + * Input Parameters: + * priv - pointer to the adc device structure + * pdi_high - true: The ADC is powered down when waiting for a start event + * false: The ADC is powered up when waiting for a start event + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +void stm32_adcchange_sample_time(FAR struct adc_dev_s *dev, + FAR struct adc_sample_time_s *time_samples) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint8_t ch_index; + uint8_t i; + + /* Check if user wants to assign the same value for all channels + * or just wants to change sample time values for certain channels */ + + if (time_samples->all_same) + { + memset(priv->sample_rate, time_samples->all_ch_sample_time, + ADC_CHANNELS_NUMBER); + } + else + { + for (i = 0; i < time_samples->channels_nbr; i++) + { + ch_index = time_samples->channel->channel; + if (ch_index >= ADC_CHANNELS_NUMBER) + { + break; + } + + priv->sample_rate[ch_index] = time_samples->channel->sample_time; + } + } +} +#endif + +/**************************************************************************** + * Name: stm32_adcinitialize + * + * Description: + * Initialize the ADC. + * + * The logic is, save nchannels : # of channels (conversions) in ADC_SQR1_L + * Then, take the chanlist array and store it in the SQR Regs, + * chanlist[0] -> ADC_SQR3_SQ1 + * chanlist[1] -> ADC_SQR3_SQ2 + * ... + * chanlist[15]-> ADC_SQR1_SQ16 + * + * up to + * chanlist[nchannels] + * + * Input Parameters: + * intf - Could be {1,2,3} for ADC1, ADC2, or ADC3 + * chanlist - The list of channels + * cchannels - Number of channels + * + * Returned Value: + * Valid ADC device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist, + int cchannels) +{ + FAR struct adc_dev_s *dev; + FAR struct stm32_dev_s *priv; + + avdbg("intf: %d cchannels: %d\n", intf, cchannels); + + switch (intf) + { +#ifdef CONFIG_STM32_ADC1 + case 1: + avdbg("ADC1 selected\n"); + dev = &g_adcdev1; + break; +#endif +#ifdef CONFIG_STM32_ADC2 + case 2: + avdbg("ADC2 selected\n"); + dev = &g_adcdev2; + break; +#endif +#ifdef CONFIG_STM32_ADC3 + case 3: + avdbg("ADC3 selected\n"); + dev = &g_adcdev3; + break; +#endif +#ifdef CONFIG_STM32_ADC4 + case 4: + avdbg("ADC4 selected\n"); + dev = &g_adcdev4; + break; +#endif + default: + adbg("No ADC interface defined\n"); + return NULL; + } + + /* Configure the selected ADC */ + + priv = (FAR struct stm32_dev_s *)dev->ad_priv; + +#if defined(CONFIG_STM32_STM32L15XX) + + /* Assign default values for the sample time table */ + + memset(priv->sample_rate, ADC_SMPR_DEFAULT, ADC_CHANNELS_NUMBER); + +#endif + + DEBUGASSERT(cchannels <= ADC_MAX_SAMPLES); + + priv->cchannels = cchannels; + + memcpy(priv->chanlist, chanlist, cchannels); + + return dev; +} + +#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || + * CONFIG_STM32_STM32F30XX || CONFIG_STM32_STM32F40XX || + * CONFIG_STM32_STM32L15XX + */ +#endif /* CONFIG_STM32_ADC1 || CONFIG_STM32_ADC2 || + * CONFIG_STM32_ADC3 || CONFIG_STM32_ADC4 + */ +#endif /* CONFIG_ADC */ diff --git a/arch/arm/src/stm32/stm32_adc.h b/arch/arm/src/stm32/stm32_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..25ad161b629c847de2b1f4c45504f11ef8e8a708 --- /dev/null +++ b/arch/arm/src/stm32/stm32_adc.h @@ -0,0 +1,1655 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_adc.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_ADC_H +#define __ARCH_ARM_SRC_STM32_STM32_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_adc.h" +#else +# include "chip/stm32_adc.h" +#endif + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic ADC sampling. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_ADC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +/* For the STM32 F1 line, timers 1-4 may be used. + * For the STM32 F3 line, timers 1-4, 6-8, 15, 20 may be used. + * For the STM32 F2/F4 lines, timers 1-5 and 8 may be used. + * For the STM32L15XX line, timers 2-4, 6, 7, 9, 10 may be used. + */ + +#ifdef CONFIG_STM32_STM32L15XX +# undef CONFIG_STM32_TIM1_ADC +# undef CONFIG_STM32_TIM1_ADC1 +# undef CONFIG_STM32_TIM1_ADC2 +# undef CONFIG_STM32_TIM1_ADC3 +# undef CONFIG_STM32_TIM1_ADC4 +#else +# ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_ADC +# undef CONFIG_STM32_TIM1_ADC1 +# undef CONFIG_STM32_TIM1_ADC2 +# undef CONFIG_STM32_TIM1_ADC3 +# undef CONFIG_STM32_TIM1_ADC4 +# endif +#endif + +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_ADC +# undef CONFIG_STM32_TIM2_ADC1 +# undef CONFIG_STM32_TIM2_ADC2 +# undef CONFIG_STM32_TIM2_ADC3 +# undef CONFIG_STM32_TIM2_ADC4 +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_ADC +# undef CONFIG_STM32_TIM3_ADC1 +# undef CONFIG_STM32_TIM3_ADC2 +# undef CONFIG_STM32_TIM3_ADC3 +# undef CONFIG_STM32_TIM3_ADC4 +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_ADC +# undef CONFIG_STM32_TIM4_ADC1 +# undef CONFIG_STM32_TIM4_ADC2 +# undef CONFIG_STM32_TIM4_ADC3 +# undef CONFIG_STM32_TIM4_ADC4 +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_ADC +# undef CONFIG_STM32_TIM5_ADC1 +# undef CONFIG_STM32_TIM5_ADC2 +# undef CONFIG_STM32_TIM5_ADC3 +# undef CONFIG_STM32_TIM5_ADC4 +# endif +#else +# undef CONFIG_STM32_TIM5_ADC +# undef CONFIG_STM32_TIM5_ADC1 +# undef CONFIG_STM32_TIM5_ADC2 +# undef CONFIG_STM32_TIM5_ADC3 +# undef CONFIG_STM32_TIM5_ADC4 +#endif + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_ADC +# undef CONFIG_STM32_TIM8_ADC1 +# undef CONFIG_STM32_TIM8_ADC2 +# undef CONFIG_STM32_TIM8_ADC3 +# undef CONFIG_STM32_TIM8_ADC4 +# endif +#else +# undef CONFIG_STM32_TIM8_ADC +# undef CONFIG_STM32_TIM8_ADC1 +# undef CONFIG_STM32_TIM8_ADC2 +# undef CONFIG_STM32_TIM8_ADC3 +# undef CONFIG_STM32_TIM8_ADC4 +#endif + +/* Timers 6, 7, 9, 10 used by STM32L15XX family devices. Though there is only ADC + * presented in specification and in device as well, the ADC1 is used here in code. + * See definition of the STM32_NADC + */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F30XX) +# ifndef CONFIG_STM32_TIM6 +# undef CONFIG_STM32_TIM6_ADC +# undef CONFIG_STM32_TIM6_ADC1 +# undef CONFIG_STM32_TIM6_ADC2 +# undef CONFIG_STM32_TIM6_ADC3 +# undef CONFIG_STM32_TIM6_ADC4 +# endif +# ifndef CONFIG_STM32_TIM7 +# undef CONFIG_STM32_TIM7_ADC +# undef CONFIG_STM32_TIM7_ADC1 +# undef CONFIG_STM32_TIM7_ADC2 +# undef CONFIG_STM32_TIM7_ADC3 +# undef CONFIG_STM32_TIM7_ADC4 +# endif +#else +# undef CONFIG_STM32_TIM6_ADC +# undef CONFIG_STM32_TIM6_ADC1 +# undef CONFIG_STM32_TIM6_ADC2 +# undef CONFIG_STM32_TIM6_ADC3 +# undef CONFIG_STM32_TIM6_ADC4 +# undef CONFIG_STM32_TIM7_ADC +# undef CONFIG_STM32_TIM7_ADC1 +# undef CONFIG_STM32_TIM7_ADC2 +# undef CONFIG_STM32_TIM7_ADC3 +# undef CONFIG_STM32_TIM7_ADC4 +#endif + +#if defined(CONFIG_STM32_STM32L15XX) +# ifndef CONFIG_STM32_TIM9 +# undef CONFIG_STM32_TIM9_ADC +# undef CONFIG_STM32_TIM9_ADC1 +# undef CONFIG_STM32_TIM9_ADC2 +# undef CONFIG_STM32_TIM9_ADC3 +# undef CONFIG_STM32_TIM9_ADC4 +# endif +# ifndef CONFIG_STM32_TIM10 +# undef CONFIG_STM32_TIM10_ADC +# undef CONFIG_STM32_TIM10_ADC1 +# undef CONFIG_STM32_TIM10_ADC2 +# undef CONFIG_STM32_TIM10_ADC3 +# undef CONFIG_STM32_TIM10_ADC4 +# endif +#else +# undef CONFIG_STM32_TIM9_ADC +# undef CONFIG_STM32_TIM9_ADC1 +# undef CONFIG_STM32_TIM9_ADC2 +# undef CONFIG_STM32_TIM9_ADC3 +# undef CONFIG_STM32_TIM9_ADC4 +# undef CONFIG_STM32_TIM10_ADC +# undef CONFIG_STM32_TIM10_ADC1 +# undef CONFIG_STM32_TIM10_ADC2 +# undef CONFIG_STM32_TIM10_ADC3 +# undef CONFIG_STM32_TIM10_ADC4 +#endif + +/* Timers 6, 7, and 10-14 are not used with the ADC by any supported family + */ + +#undef CONFIG_STM32_TIM11_ADC +#undef CONFIG_STM32_TIM11_ADC1 +#undef CONFIG_STM32_TIM11_ADC2 +#undef CONFIG_STM32_TIM11_ADC3 +#undef CONFIG_STM32_TIM11_ADC4 +#undef CONFIG_STM32_TIM12_ADC +#undef CONFIG_STM32_TIM12_ADC1 +#undef CONFIG_STM32_TIM12_ADC2 +#undef CONFIG_STM32_TIM12_ADC3 +#undef CONFIG_STM32_TIM12_ADC4 +#undef CONFIG_STM32_TIM13_ADC +#undef CONFIG_STM32_TIM13_ADC1 +#undef CONFIG_STM32_TIM13_ADC2 +#undef CONFIG_STM32_TIM13_ADC3 +#undef CONFIG_STM32_TIM13_ADC4 +#undef CONFIG_STM32_TIM14_ADC +#undef CONFIG_STM32_TIM14_ADC1 +#undef CONFIG_STM32_TIM14_ADC2 +#undef CONFIG_STM32_TIM14_ADC3 +#undef CONFIG_STM32_TIM14_ADC4 + +#ifdef CONFIG_STM32_STM32F30XX +# ifndef CONFIG_STM32_TIM15 +# undef CONFIG_STM32_TIM15_ADC +# undef CONFIG_STM32_TIM15_ADC1 +# undef CONFIG_STM32_TIM15_ADC2 +# undef CONFIG_STM32_TIM15_ADC3 +# undef CONFIG_STM32_TIM15_ADC4 +# endif +# ifndef CONFIG_STM32_TIM20 +# undef CONFIG_STM32_TIM20_ADC +# undef CONFIG_STM32_TIM20_ADC1 +# undef CONFIG_STM32_TIM20_ADC2 +# undef CONFIG_STM32_TIM20_ADC3 +# undef CONFIG_STM32_TIM20_ADC4 +# endif +#else +# undef CONFIG_STM32_TIM15_ADC +# undef CONFIG_STM32_TIM15_ADC1 +# undef CONFIG_STM32_TIM15_ADC2 +# undef CONFIG_STM32_TIM15_ADC3 +# undef CONFIG_STM32_TIM15_ADC4 +# undef CONFIG_STM32_TIM20_ADC +# undef CONFIG_STM32_TIM20_ADC1 +# undef CONFIG_STM32_TIM20_ADC2 +# undef CONFIG_STM32_TIM20_ADC3 +# undef CONFIG_STM32_TIM20_ADC4 +#endif + +/* Up to 4 ADC interfaces are supported */ + +#if STM32_NADC < 4 +# undef CONFIG_STM32_ADC4 +#endif + +#if STM32_NADC < 3 +# undef CONFIG_STM32_ADC3 +#endif + +#if STM32_NADC < 2 +# undef CONFIG_STM32_ADC2 +#endif + +#if STM32_NADC < 1 +# undef CONFIG_STM32_ADC1 +#endif + +#if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) || \ + defined(CONFIG_STM32_ADC3) || defined(CONFIG_STM32_ADC4) + +/* DMA support */ + +#undef ADC_HAVE_DMA +#if defined(CONFIG_STM32_ADC1_DMA) || defined(CONFIG_STM32_ADC2_DMA) || \ + defined(CONFIG_STM32_ADC3_DMA) || defined(CONFIG_STM32_ADC4_DMA) +# define ADC_HAVE_DMA 1 +#endif + +#ifdef CONFIG_STM32_ADC1_DMA +# define ADC1_HAVE_DMA 1 +#else +# undef ADC1_HAVE_DMA +#endif + +#ifdef CONFIG_STM32_ADC2_DMA +# define ADC2_HAVE_DMA 1 +#else +# undef ADC2_HAVE_DMA +#endif + +#ifdef CONFIG_STM32_ADC3_DMA +# define ADC3_HAVE_DMA 1 +#else +# undef ADC3_HAVE_DMA +#endif + +#ifdef CONFIG_STM32_ADC4_DMA +# define ADC4_HAVE_DMA 1 +#else +# undef ADC4_HAVE_DMA +#endif + +/* Timer configuration: If a timer trigger is specified, then get + * information about the timer. + * + * STM32L15XX-family has only one ADC onboard, thus there is no definition + * for other 3 ADC's + */ + +#if defined(CONFIG_STM32_TIM1_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM1_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_STM32_TIM2_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM2_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM3_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM4_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM5_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM5_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_STM32_TIM6_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM6_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM6_CLKIN +#elif defined(CONFIG_STM32_TIM7_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM7_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM7_CLKIN +#elif defined(CONFIG_STM32_TIM8_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM8_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN +#elif defined(CONFIG_STM32_TIM9_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM9_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM9_CLKIN +#elif defined(CONFIG_STM32_TIM10_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM10_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM10_CLKIN +#elif defined(CONFIG_STM32_TIM15_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_TIMER_BASE STM32_TIM15_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN +#else +# undef ADC1_HAVE_TIMER +#endif + +#ifdef ADC1_HAVE_TIMER +# ifndef CONFIG_STM32_ADC1_SAMPLE_FREQUENCY +# error "CONFIG_STM32_ADC1_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_ADC1_TIMTRIG +# error "CONFIG_STM32_ADC1_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM1_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_STM32_TIM2_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM2_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM3_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM4_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM5_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM5_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_STM32_TIM6_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM6_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM6_CLKIN +#elif defined(CONFIG_STM32_TIM8_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM8_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN +#elif defined(CONFIG_STM32_TIM15_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_TIMER_BASE STM32_TIM15_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN +#else +# undef ADC2_HAVE_TIMER +#endif + +#ifdef ADC2_HAVE_TIMER +# ifndef CONFIG_STM32_ADC2_SAMPLE_FREQUENCY +# error "CONFIG_STM32_ADC2_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_ADC2_TIMTRIG +# error "CONFIG_STM32_ADC2_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM1_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_STM32_TIM2_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM2_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM3_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM4_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM5_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM5_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_STM32_TIM7_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM7_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM7_CLKIN +#elif defined(CONFIG_STM32_TIM8_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM8_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN +#elif defined(CONFIG_STM32_TIM15_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM15_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN +#elif defined(CONFIG_STM32_TIM20_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_TIMER_BASE STM32_TIM20_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM20_CLKIN +#else +# undef ADC3_HAVE_TIMER +#endif + +#ifdef ADC3_HAVE_TIMER +# ifndef CONFIG_STM32_ADC3_SAMPLE_FREQUENCY +# error "CONFIG_STM32_ADC3_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_ADC3_TIMTRIG +# error "CONFIG_STM32_ADC3_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM1_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN +#elif defined(CONFIG_STM32_TIM2_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM2_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM3_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM4_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM5_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM5_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB1_TIM5_CLKIN +#elif defined(CONFIG_STM32_TIM7_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM7_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB1_TIM7_CLKIN +#elif defined(CONFIG_STM32_TIM8_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM8_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN +#elif defined(CONFIG_STM32_TIM15_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM15_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN +#elif defined(CONFIG_STM32_TIM20_ADC4) +# define ADC4_HAVE_TIMER 1 +# define ADC4_TIMER_BASE STM32_TIM20_BASE +# define ADC4_TIMER_PCLK_FREQUENCY STM32_APB2_TIM20_CLKIN +#else +# undef ADC4_HAVE_TIMER +#endif + +#ifdef ADC4_HAVE_TIMER +# ifndef CONFIG_STM32_ADC4_SAMPLE_FREQUENCY +# error "CONFIG_STM32_ADC4_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_ADC4_TIMTRIG +# error "CONFIG_STM32_ADC4_TIMTRIG not defined" +# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO" +# endif +#endif + +#if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || \ + defined(ADC3_HAVE_TIMER) || defined(ADC4_HAVE_TIMER) +# define ADC_HAVE_TIMER 1 +# if defined(CONFIG_STM32_STM32F10XX) && !defined(CONFIG_STM32_FORCEPOWER) +# warning "CONFIG_STM32_FORCEPOWER must be defined to enable the timer(s)" +# endif +#else +# undef ADC_HAVE_TIMER +#endif + +/* NOTE: The following assumes that all possible combinations of timers and + * values are support EXTSEL. That is not so and it varies from one STM32 + * to another. But this (wrong) assumptions keeps the logic as simple as + * possible. If unsupported combination is used, an error will show up + * later during compilation although it may be difficult to track it back + * to this simplification. + * + * STM32L15XX-family has only one ADC onboard, thus there is no definition + * for other 3 ADC's + */ + +#ifdef CONFIG_STM32_STM32F30XX +# define ADC1_EXTSEL_T1CC1 ADC12_CFGR_EXTSEL_T1CC1 +# define ADC1_EXTSEL_T1CC2 ADC12_CFGR_EXTSEL_T1CC2 +# define ADC1_EXTSEL_T1CC3 ADC12_CFGR_EXTSEL_T1CC3 +# define ADC1_EXTSEL_T1CC4 ADC12_CFGR_EXTSEL_T1CC4 +# define ADC1_EXTSEL_T1TRGO ADC12_CFGR_EXTSEL_T1TRGO +# define ADC2_EXTSEL_T1CC1 ADC12_CFGR_EXTSEL_T1CC1 +# define ADC2_EXTSEL_T1CC2 ADC12_CFGR_EXTSEL_T1CC2 +# define ADC2_EXTSEL_T1CC3 ADC12_CFGR_EXTSEL_T1CC3 +# define ADC2_EXTSEL_T1CC4 ADC12_CFGR_EXTSEL_T1CC4 +# define ADC2_EXTSEL_T1TRGO ADC12_CFGR_EXTSEL_T1TRGO +# define ADC3_EXTSEL_T1CC1 ADC34_CFGR_EXTSEL_T1CC1 +# define ADC3_EXTSEL_T1CC2 ADC34_CFGR_EXTSEL_T1CC2 +# define ADC3_EXTSEL_T1CC3 ADC34_CFGR_EXTSEL_T1CC3 +# define ADC3_EXTSEL_T1CC4 ADC34_CFGR_EXTSEL_T1CC4 +# define ADC3_EXTSEL_T1TRGO ADC34_CFGR_EXTSEL_T1TRGO +# define ADC4_EXTSEL_T1CC1 ADC34_CFGR_EXTSEL_T1CC1 +# define ADC4_EXTSEL_T1CC2 ADC34_CFGR_EXTSEL_T1CC2 +# define ADC4_EXTSEL_T1CC3 ADC34_CFGR_EXTSEL_T1CC3 +# define ADC4_EXTSEL_T1CC4 ADC34_CFGR_EXTSEL_T1CC4 +# define ADC4_EXTSEL_T1TRGO ADC34_CFGR_EXTSEL_T1TRGO +# define ADC1_EXTSEL_T2CC1 ADC12_CFGR_EXTSEL_T2CC1 +# define ADC1_EXTSEL_T2CC2 ADC12_CFGR_EXTSEL_T2CC2 +# define ADC1_EXTSEL_T2CC3 ADC12_CFGR_EXTSEL_T2CC3 +# define ADC1_EXTSEL_T2CC4 ADC12_CFGR_EXTSEL_T2CC4 +# define ADC1_EXTSEL_T2TRGO ADC12_CFGR_EXTSEL_T2TRGO +# define ADC2_EXTSEL_T2CC1 ADC12_CFGR_EXTSEL_T2CC1 +# define ADC2_EXTSEL_T2CC2 ADC12_CFGR_EXTSEL_T2CC2 +# define ADC2_EXTSEL_T2CC3 ADC12_CFGR_EXTSEL_T2CC3 +# define ADC2_EXTSEL_T2CC4 ADC12_CFGR_EXTSEL_T2CC4 +# define ADC2_EXTSEL_T2TRGO ADC12_CFGR_EXTSEL_T2TRGO +# define ADC3_EXTSEL_T2CC1 ADC34_CFGR_EXTSEL_T2CC1 +# define ADC3_EXTSEL_T2CC2 ADC34_CFGR_EXTSEL_T2CC2 +# define ADC3_EXTSEL_T2CC3 ADC34_CFGR_EXTSEL_T2CC3 +# define ADC3_EXTSEL_T2CC4 ADC34_CFGR_EXTSEL_T2CC4 +# define ADC3_EXTSEL_T2TRGO ADC34_CFGR_EXTSEL_T2TRGO +# define ADC4_EXTSEL_T2CC1 ADC34_CFGR_EXTSEL_T2CC1 +# define ADC4_EXTSEL_T2CC2 ADC34_CFGR_EXTSEL_T2CC2 +# define ADC4_EXTSEL_T2CC3 ADC34_CFGR_EXTSEL_T2CC3 +# define ADC4_EXTSEL_T2CC4 ADC34_CFGR_EXTSEL_T2CC4 +# define ADC4_EXTSEL_T2TRGO ADC34_CFGR_EXTSEL_T2TRGO +# define ADC1_EXTSEL_T3CC1 ADC12_CFGR_EXTSEL_T3CC1 +# define ADC1_EXTSEL_T3CC2 ADC12_CFGR_EXTSEL_T3CC2 +# define ADC1_EXTSEL_T3CC3 ADC12_CFGR_EXTSEL_T3CC3 +# define ADC1_EXTSEL_T3CC4 ADC12_CFGR_EXTSEL_T3CC4 +# define ADC1_EXTSEL_T3TRGO ADC12_CFGR_EXTSEL_T3TRGO +# define ADC2_EXTSEL_T3CC1 ADC12_CFGR_EXTSEL_T3CC1 +# define ADC2_EXTSEL_T3CC2 ADC12_CFGR_EXTSEL_T3CC2 +# define ADC2_EXTSEL_T3CC3 ADC12_CFGR_EXTSEL_T3CC3 +# define ADC2_EXTSEL_T3CC4 ADC12_CFGR_EXTSEL_T3CC4 +# define ADC2_EXTSEL_T3TRGO ADC12_CFGR_EXTSEL_T3TRGO +# define ADC3_EXTSEL_T3CC1 ADC34_CFGR_EXTSEL_T3CC1 +# define ADC3_EXTSEL_T3CC2 ADC34_CFGR_EXTSEL_T3CC2 +# define ADC3_EXTSEL_T3CC3 ADC34_CFGR_EXTSEL_T3CC3 +# define ADC3_EXTSEL_T3CC4 ADC34_CFGR_EXTSEL_T3CC4 +# define ADC3_EXTSEL_T3TRGO ADC34_CFGR_EXTSEL_T3TRGO +# define ADC4_EXTSEL_T3CC1 ADC34_CFGR_EXTSEL_T3CC1 +# define ADC4_EXTSEL_T3CC2 ADC34_CFGR_EXTSEL_T3CC2 +# define ADC4_EXTSEL_T3CC3 ADC34_CFGR_EXTSEL_T3CC3 +# define ADC4_EXTSEL_T3CC4 ADC34_CFGR_EXTSEL_T3CC4 +# define ADC4_EXTSEL_T3TRGO ADC34_CFGR_EXTSEL_T3TRGO +# define ADC1_EXTSEL_T4CC1 ADC12_CFGR_EXTSEL_T4CC1 +# define ADC1_EXTSEL_T4CC2 ADC12_CFGR_EXTSEL_T4CC2 +# define ADC1_EXTSEL_T4CC3 ADC12_CFGR_EXTSEL_T4CC3 +# define ADC1_EXTSEL_T4CC4 ADC12_CFGR_EXTSEL_T4CC4 +# define ADC1_EXTSEL_T4TRGO ADC12_CFGR_EXTSEL_T4TRGO +# define ADC2_EXTSEL_T4CC1 ADC12_CFGR_EXTSEL_T4CC1 +# define ADC2_EXTSEL_T4CC2 ADC12_CFGR_EXTSEL_T4CC2 +# define ADC2_EXTSEL_T4CC3 ADC12_CFGR_EXTSEL_T4CC3 +# define ADC2_EXTSEL_T4CC4 ADC12_CFGR_EXTSEL_T4CC4 +# define ADC2_EXTSEL_T4TRGO ADC12_CFGR_EXTSEL_T4TRGO +# define ADC3_EXTSEL_T4CC1 ADC34_CFGR_EXTSEL_T4CC1 +# define ADC3_EXTSEL_T4CC2 ADC34_CFGR_EXTSEL_T4CC2 +# define ADC3_EXTSEL_T4CC3 ADC34_CFGR_EXTSEL_T4CC3 +# define ADC3_EXTSEL_T4CC4 ADC34_CFGR_EXTSEL_T4CC4 +# define ADC3_EXTSEL_T4TRGO ADC34_CFGR_EXTSEL_T4TRGO +# define ADC4_EXTSEL_T4CC1 ADC34_CFGR_EXTSEL_T4CC1 +# define ADC4_EXTSEL_T4CC2 ADC34_CFGR_EXTSEL_T4CC2 +# define ADC4_EXTSEL_T4CC3 ADC34_CFGR_EXTSEL_T4CC3 +# define ADC4_EXTSEL_T4CC4 ADC34_CFGR_EXTSEL_T4CC4 +# define ADC4_EXTSEL_T4TRGO ADC34_CFGR_EXTSEL_T4TRGO +# define ADC1_EXTSEL_T5CC1 ADC12_CFGR_EXTSEL_T5CC1 +# define ADC1_EXTSEL_T5CC2 ADC12_CFGR_EXTSEL_T5CC2 +# define ADC1_EXTSEL_T5CC3 ADC12_CFGR_EXTSEL_T5CC3 +# define ADC1_EXTSEL_T5CC4 ADC12_CFGR_EXTSEL_T5CC4 +# define ADC1_EXTSEL_T5TRGO ADC12_CFGR_EXTSEL_T5TRGO +# define ADC2_EXTSEL_T5CC1 ADC12_CFGR_EXTSEL_T5CC1 +# define ADC2_EXTSEL_T5CC2 ADC12_CFGR_EXTSEL_T5CC2 +# define ADC2_EXTSEL_T5CC3 ADC12_CFGR_EXTSEL_T5CC3 +# define ADC2_EXTSEL_T5CC4 ADC12_CFGR_EXTSEL_T5CC4 +# define ADC2_EXTSEL_T5TRGO ADC12_CFGR_EXTSEL_T5TRGO +# define ADC3_EXTSEL_T5CC1 ADC34_CFGR_EXTSEL_T5CC1 +# define ADC3_EXTSEL_T5CC2 ADC34_CFGR_EXTSEL_T5CC2 +# define ADC3_EXTSEL_T5CC3 ADC34_CFGR_EXTSEL_T5CC3 +# define ADC3_EXTSEL_T5CC4 ADC34_CFGR_EXTSEL_T5CC4 +# define ADC3_EXTSEL_T5TRGO ADC34_CFGR_EXTSEL_T5TRGO +# define ADC4_EXTSEL_T5CC1 ADC34_CFGR_EXTSEL_T5CC1 +# define ADC4_EXTSEL_T5CC2 ADC34_CFGR_EXTSEL_T5CC2 +# define ADC4_EXTSEL_T5CC3 ADC34_CFGR_EXTSEL_T5CC3 +# define ADC4_EXTSEL_T5CC4 ADC34_CFGR_EXTSEL_T5CC4 +# define ADC4_EXTSEL_T5TRGO ADC34_CFGR_EXTSEL_T5TRGO +# define ADC1_EXTSEL_T6CC1 ADC12_CFGR_EXTSEL_T6CC1 +# define ADC1_EXTSEL_T6CC2 ADC12_CFGR_EXTSEL_T6CC2 +# define ADC1_EXTSEL_T6CC3 ADC12_CFGR_EXTSEL_T6CC3 +# define ADC1_EXTSEL_T6CC4 ADC12_CFGR_EXTSEL_T6CC4 +# define ADC1_EXTSEL_T6TRGO ADC12_CFGR_EXTSEL_T6TRGO +# define ADC2_EXTSEL_T6CC1 ADC12_CFGR_EXTSEL_T6CC1 +# define ADC2_EXTSEL_T6CC2 ADC12_CFGR_EXTSEL_T6CC2 +# define ADC2_EXTSEL_T6CC3 ADC12_CFGR_EXTSEL_T6CC3 +# define ADC2_EXTSEL_T6CC4 ADC12_CFGR_EXTSEL_T6CC4 +# define ADC2_EXTSEL_T6TRGO ADC12_CFGR_EXTSEL_T6TRGO +# define ADC3_EXTSEL_T6CC1 ADC34_CFGR_EXTSEL_T6CC1 +# define ADC3_EXTSEL_T6CC2 ADC34_CFGR_EXTSEL_T6CC2 +# define ADC3_EXTSEL_T6CC3 ADC34_CFGR_EXTSEL_T6CC3 +# define ADC3_EXTSEL_T6CC4 ADC34_CFGR_EXTSEL_T6CC4 +# define ADC3_EXTSEL_T6TRGO ADC34_CFGR_EXTSEL_T6TRGO +# define ADC4_EXTSEL_T6CC1 ADC34_CFGR_EXTSEL_T6CC1 +# define ADC4_EXTSEL_T6CC2 ADC34_CFGR_EXTSEL_T6CC2 +# define ADC4_EXTSEL_T6CC3 ADC34_CFGR_EXTSEL_T6CC3 +# define ADC4_EXTSEL_T6CC4 ADC34_CFGR_EXTSEL_T6CC4 +# define ADC4_EXTSEL_T6TRGO ADC34_CFGR_EXTSEL_T6TRGO +# define ADC1_EXTSEL_T7CC1 ADC12_CFGR_EXTSEL_T7CC1 +# define ADC1_EXTSEL_T7CC2 ADC12_CFGR_EXTSEL_T7CC2 +# define ADC1_EXTSEL_T7CC3 ADC12_CFGR_EXTSEL_T7CC3 +# define ADC1_EXTSEL_T7CC4 ADC12_CFGR_EXTSEL_T7CC4 +# define ADC1_EXTSEL_T7TRGO ADC12_CFGR_EXTSEL_T7TRGO +# define ADC2_EXTSEL_T7CC1 ADC12_CFGR_EXTSEL_T7CC1 +# define ADC2_EXTSEL_T7CC2 ADC12_CFGR_EXTSEL_T7CC2 +# define ADC2_EXTSEL_T7CC3 ADC12_CFGR_EXTSEL_T7CC3 +# define ADC2_EXTSEL_T7CC4 ADC12_CFGR_EXTSEL_T7CC4 +# define ADC2_EXTSEL_T7TRGO ADC12_CFGR_EXTSEL_T7TRGO +# define ADC3_EXTSEL_T7CC1 ADC34_CFGR_EXTSEL_T7CC1 +# define ADC3_EXTSEL_T7CC2 ADC34_CFGR_EXTSEL_T7CC2 +# define ADC3_EXTSEL_T7CC3 ADC34_CFGR_EXTSEL_T7CC3 +# define ADC3_EXTSEL_T7CC4 ADC34_CFGR_EXTSEL_T7CC4 +# define ADC3_EXTSEL_T7TRGO ADC34_CFGR_EXTSEL_T7TRGO +# define ADC4_EXTSEL_T7CC1 ADC34_CFGR_EXTSEL_T7CC1 +# define ADC4_EXTSEL_T7CC2 ADC34_CFGR_EXTSEL_T7CC2 +# define ADC4_EXTSEL_T7CC3 ADC34_CFGR_EXTSEL_T7CC3 +# define ADC4_EXTSEL_T7CC4 ADC34_CFGR_EXTSEL_T7CC4 +# define ADC4_EXTSEL_T7TRGO ADC34_CFGR_EXTSEL_T7TRGO +# define ADC1_EXTSEL_T8CC1 ADC12_CFGR_EXTSEL_T8CC1 +# define ADC1_EXTSEL_T8CC2 ADC12_CFGR_EXTSEL_T8CC2 +# define ADC1_EXTSEL_T8CC3 ADC12_CFGR_EXTSEL_T8CC3 +# define ADC1_EXTSEL_T8CC4 ADC12_CFGR_EXTSEL_T8CC4 +# define ADC1_EXTSEL_T8TRGO ADC12_CFGR_EXTSEL_T8TRGO +# define ADC2_EXTSEL_T8CC1 ADC12_CFGR_EXTSEL_T8CC1 +# define ADC2_EXTSEL_T8CC2 ADC12_CFGR_EXTSEL_T8CC2 +# define ADC2_EXTSEL_T8CC3 ADC12_CFGR_EXTSEL_T8CC3 +# define ADC2_EXTSEL_T8CC4 ADC12_CFGR_EXTSEL_T8CC4 +# define ADC2_EXTSEL_T8TRGO ADC12_CFGR_EXTSEL_T8TRGO +# define ADC3_EXTSEL_T8CC1 ADC34_CFGR_EXTSEL_T8CC1 +# define ADC3_EXTSEL_T8CC2 ADC34_CFGR_EXTSEL_T8CC2 +# define ADC3_EXTSEL_T8CC3 ADC34_CFGR_EXTSEL_T8CC3 +# define ADC3_EXTSEL_T8CC4 ADC34_CFGR_EXTSEL_T8CC4 +# define ADC3_EXTSEL_T8TRGO ADC34_CFGR_EXTSEL_T8TRGO +# define ADC4_EXTSEL_T8CC1 ADC34_CFGR_EXTSEL_T8CC1 +# define ADC4_EXTSEL_T8CC2 ADC34_CFGR_EXTSEL_T8CC2 +# define ADC4_EXTSEL_T8CC3 ADC34_CFGR_EXTSEL_T8CC3 +# define ADC4_EXTSEL_T8CC4 ADC34_CFGR_EXTSEL_T8CC4 +# define ADC4_EXTSEL_T8TRGO ADC34_CFGR_EXTSEL_T8TRGO +# define ADC1_EXTSEL_T9CC1 ADC12_CFGR_EXTSEL_T9CC1 +# define ADC1_EXTSEL_T9CC2 ADC12_CFGR_EXTSEL_T9CC2 +# define ADC1_EXTSEL_T9CC3 ADC12_CFGR_EXTSEL_T9CC3 +# define ADC1_EXTSEL_T9CC4 ADC12_CFGR_EXTSEL_T9CC4 +# define ADC1_EXTSEL_T9TRGO ADC12_CFGR_EXTSEL_T9TRGO +# define ADC2_EXTSEL_T9CC1 ADC12_CFGR_EXTSEL_T9CC1 +# define ADC2_EXTSEL_T9CC2 ADC12_CFGR_EXTSEL_T9CC2 +# define ADC2_EXTSEL_T9CC3 ADC12_CFGR_EXTSEL_T9CC3 +# define ADC2_EXTSEL_T9CC4 ADC12_CFGR_EXTSEL_T9CC4 +# define ADC2_EXTSEL_T9TRGO ADC12_CFGR_EXTSEL_T9TRGO +# define ADC3_EXTSEL_T9CC1 ADC34_CFGR_EXTSEL_T9CC1 +# define ADC3_EXTSEL_T9CC2 ADC34_CFGR_EXTSEL_T9CC2 +# define ADC3_EXTSEL_T9CC3 ADC34_CFGR_EXTSEL_T9CC3 +# define ADC3_EXTSEL_T9CC4 ADC34_CFGR_EXTSEL_T9CC4 +# define ADC3_EXTSEL_T9TRGO ADC34_CFGR_EXTSEL_T9TRGO +# define ADC4_EXTSEL_T9CC1 ADC34_CFGR_EXTSEL_T9CC1 +# define ADC4_EXTSEL_T9CC2 ADC34_CFGR_EXTSEL_T9CC2 +# define ADC4_EXTSEL_T9CC3 ADC34_CFGR_EXTSEL_T9CC3 +# define ADC4_EXTSEL_T9CC4 ADC34_CFGR_EXTSEL_T9CC4 +# define ADC4_EXTSEL_T9TRGO ADC34_CFGR_EXTSEL_T9TRGO +# define ADC1_EXTSEL_T10CC1 ADC12_CFGR_EXTSEL_T10CC1 +# define ADC1_EXTSEL_T10CC2 ADC12_CFGR_EXTSEL_T10CC2 +# define ADC1_EXTSEL_T10CC3 ADC12_CFGR_EXTSEL_T10CC3 +# define ADC1_EXTSEL_T10CC4 ADC12_CFGR_EXTSEL_T10CC4 +# define ADC1_EXTSEL_T10TRGO ADC12_CFGR_EXTSEL_T10TRGO +# define ADC2_EXTSEL_T10CC1 ADC12_CFGR_EXTSEL_T10CC1 +# define ADC2_EXTSEL_T10CC2 ADC12_CFGR_EXTSEL_T10CC2 +# define ADC2_EXTSEL_T10CC3 ADC12_CFGR_EXTSEL_T10CC3 +# define ADC2_EXTSEL_T10CC4 ADC12_CFGR_EXTSEL_T10CC4 +# define ADC2_EXTSEL_T10TRGO ADC12_CFGR_EXTSEL_T10TRGO +# define ADC3_EXTSEL_T10CC1 ADC34_CFGR_EXTSEL_T10CC1 +# define ADC3_EXTSEL_T10CC2 ADC34_CFGR_EXTSEL_T10CC2 +# define ADC3_EXTSEL_T10CC3 ADC34_CFGR_EXTSEL_T10CC3 +# define ADC3_EXTSEL_T10CC4 ADC34_CFGR_EXTSEL_T10CC4 +# define ADC3_EXTSEL_T10TRGO ADC34_CFGR_EXTSEL_T10TRGO +# define ADC4_EXTSEL_T10CC1 ADC34_CFGR_EXTSEL_T10CC1 +# define ADC4_EXTSEL_T10CC2 ADC34_CFGR_EXTSEL_T10CC2 +# define ADC4_EXTSEL_T10CC3 ADC34_CFGR_EXTSEL_T10CC3 +# define ADC4_EXTSEL_T10CC4 ADC34_CFGR_EXTSEL_T10CC4 +# define ADC4_EXTSEL_T10TRGO ADC34_CFGR_EXTSEL_T10TRGO +# define ADC1_EXTSEL_T15CC1 ADC12_CFGR_EXTSEL_T15CC1 +# define ADC1_EXTSEL_T15CC2 ADC12_CFGR_EXTSEL_T15CC2 +# define ADC1_EXTSEL_T15CC3 ADC12_CFGR_EXTSEL_T15CC3 +# define ADC1_EXTSEL_T15CC4 ADC12_CFGR_EXTSEL_T15CC4 +# define ADC1_EXTSEL_T15TRGO ADC12_CFGR_EXTSEL_T15TRGO +# define ADC2_EXTSEL_T15CC1 ADC12_CFGR_EXTSEL_T15CC1 +# define ADC2_EXTSEL_T15CC2 ADC12_CFGR_EXTSEL_T15CC2 +# define ADC2_EXTSEL_T15CC3 ADC12_CFGR_EXTSEL_T15CC3 +# define ADC2_EXTSEL_T15CC4 ADC12_CFGR_EXTSEL_T15CC4 +# define ADC2_EXTSEL_T15TRGO ADC12_CFGR_EXTSEL_T15TRGO +# define ADC3_EXTSEL_T15CC1 ADC34_CFGR_EXTSEL_T15CC1 +# define ADC3_EXTSEL_T15CC2 ADC34_CFGR_EXTSEL_T15CC2 +# define ADC3_EXTSEL_T15CC3 ADC34_CFGR_EXTSEL_T15CC3 +# define ADC3_EXTSEL_T15CC4 ADC34_CFGR_EXTSEL_T15CC4 +# define ADC3_EXTSEL_T15TRGO ADC34_CFGR_EXTSEL_T15TRGO +# define ADC4_EXTSEL_T15CC1 ADC34_CFGR_EXTSEL_T15CC1 +# define ADC4_EXTSEL_T15CC2 ADC34_CFGR_EXTSEL_T15CC2 +# define ADC4_EXTSEL_T15CC3 ADC34_CFGR_EXTSEL_T15CC3 +# define ADC4_EXTSEL_T15CC4 ADC34_CFGR_EXTSEL_T15CC4 +# define ADC4_EXTSEL_T15TRGO ADC34_CFGR_EXTSEL_T15TRGO +# define ADC1_EXTSEL_T20CC1 ADC12_CFGR_EXTSEL_T20CC1 +# define ADC1_EXTSEL_T20CC2 ADC12_CFGR_EXTSEL_T20CC2 +# define ADC1_EXTSEL_T20CC3 ADC12_CFGR_EXTSEL_T20CC3 +# define ADC1_EXTSEL_T20CC4 ADC12_CFGR_EXTSEL_T20CC4 +# define ADC1_EXTSEL_T20TRGO ADC12_CFGR_EXTSEL_T20TRGO +# define ADC2_EXTSEL_T20CC1 ADC12_CFGR_EXTSEL_T20CC1 +# define ADC2_EXTSEL_T20CC2 ADC12_CFGR_EXTSEL_T20CC2 +# define ADC2_EXTSEL_T20CC3 ADC12_CFGR_EXTSEL_T20CC3 +# define ADC2_EXTSEL_T20CC4 ADC12_CFGR_EXTSEL_T20CC4 +# define ADC2_EXTSEL_T20TRGO ADC12_CFGR_EXTSEL_T20TRGO +# define ADC3_EXTSEL_T20CC1 ADC34_CFGR_EXTSEL_T20CC1 +# define ADC3_EXTSEL_T20CC2 ADC34_CFGR_EXTSEL_T20CC2 +# define ADC3_EXTSEL_T20CC3 ADC34_CFGR_EXTSEL_T20CC3 +# define ADC3_EXTSEL_T20CC4 ADC34_CFGR_EXTSEL_T20CC4 +# define ADC3_EXTSEL_T20TRGO ADC34_CFGR_EXTSEL_T20TRGO +# define ADC4_EXTSEL_T20CC1 ADC34_CFGR_EXTSEL_T20CC1 +# define ADC4_EXTSEL_T20CC2 ADC34_CFGR_EXTSEL_T20CC2 +# define ADC4_EXTSEL_T20CC3 ADC34_CFGR_EXTSEL_T20CC3 +# define ADC4_EXTSEL_T20CC4 ADC34_CFGR_EXTSEL_T20CC4 +# define ADC4_EXTSEL_T20TRGO ADC34_CFGR_EXTSEL_T20TRGO +#else +# define ADC1_EXTSEL_T1CC1 ADC_CR2_EXTSEL_T1CC1 +# define ADC1_EXTSEL_T1CC2 ADC_CR2_EXTSEL_T1CC2 +# define ADC1_EXTSEL_T1CC3 ADC_CR2_EXTSEL_T1CC3 +# define ADC1_EXTSEL_T1CC4 ADC_CR2_EXTSEL_T1CC4 +# define ADC1_EXTSEL_T1TRGO ADC_CR2_EXTSEL_T1TRGO +# define ADC2_EXTSEL_T1CC1 ADC_CR2_EXTSEL_T1CC1 +# define ADC2_EXTSEL_T1CC2 ADC_CR2_EXTSEL_T1CC2 +# define ADC2_EXTSEL_T1CC3 ADC_CR2_EXTSEL_T1CC3 +# define ADC2_EXTSEL_T1CC4 ADC_CR2_EXTSEL_T1CC4 +# define ADC2_EXTSEL_T1TRGO ADC_CR2_EXTSEL_T1TRGO +# define ADC3_EXTSEL_T1CC1 ADC_CR2_EXTSEL_T1CC1 +# define ADC3_EXTSEL_T1CC2 ADC_CR2_EXTSEL_T1CC2 +# define ADC3_EXTSEL_T1CC3 ADC_CR2_EXTSEL_T1CC3 +# define ADC3_EXTSEL_T1CC4 ADC_CR2_EXTSEL_T1CC4 +# define ADC3_EXTSEL_T1TRGO ADC_CR2_EXTSEL_T1TRGO +# define ADC4_EXTSEL_T1CC1 ADC_CR2_EXTSEL_T1CC1 +# define ADC4_EXTSEL_T1CC2 ADC_CR2_EXTSEL_T1CC2 +# define ADC4_EXTSEL_T1CC3 ADC_CR2_EXTSEL_T1CC3 +# define ADC4_EXTSEL_T1CC4 ADC_CR2_EXTSEL_T1CC4 +# define ADC4_EXTSEL_T1TRGO ADC_CR2_EXTSEL_T1TRGO +# define ADC1_EXTSEL_T2CC1 ADC_CR2_EXTSEL_T2CC1 +# define ADC1_EXTSEL_T2CC2 ADC_CR2_EXTSEL_T2CC2 +# define ADC1_EXTSEL_T2CC3 ADC_CR2_EXTSEL_T2CC3 +# define ADC1_EXTSEL_T2CC4 ADC_CR2_EXTSEL_T2CC4 +# define ADC1_EXTSEL_T2TRGO ADC_CR2_EXTSEL_T2TRGO +# define ADC2_EXTSEL_T2CC1 ADC_CR2_EXTSEL_T2CC1 +# define ADC2_EXTSEL_T2CC2 ADC_CR2_EXTSEL_T2CC2 +# define ADC2_EXTSEL_T2CC3 ADC_CR2_EXTSEL_T2CC3 +# define ADC2_EXTSEL_T2CC4 ADC_CR2_EXTSEL_T2CC4 +# define ADC2_EXTSEL_T2TRGO ADC_CR2_EXTSEL_T2TRGO +# define ADC3_EXTSEL_T2CC1 ADC_CR2_EXTSEL_T2CC1 +# define ADC3_EXTSEL_T2CC2 ADC_CR2_EXTSEL_T2CC2 +# define ADC3_EXTSEL_T2CC3 ADC_CR2_EXTSEL_T2CC3 +# define ADC3_EXTSEL_T2CC4 ADC_CR2_EXTSEL_T2CC4 +# define ADC3_EXTSEL_T2TRGO ADC_CR2_EXTSEL_T2TRGO +# define ADC4_EXTSEL_T2CC1 ADC_CR2_EXTSEL_T2CC1 +# define ADC4_EXTSEL_T2CC2 ADC_CR2_EXTSEL_T2CC2 +# define ADC4_EXTSEL_T2CC3 ADC_CR2_EXTSEL_T2CC3 +# define ADC4_EXTSEL_T2CC4 ADC_CR2_EXTSEL_T2CC4 +# define ADC4_EXTSEL_T2TRGO ADC_CR2_EXTSEL_T2TRGO +# define ADC1_EXTSEL_T3CC1 ADC_CR2_EXTSEL_T3CC1 +# define ADC1_EXTSEL_T3CC2 ADC_CR2_EXTSEL_T3CC2 +# define ADC1_EXTSEL_T3CC3 ADC_CR2_EXTSEL_T3CC3 +# define ADC1_EXTSEL_T3CC4 ADC_CR2_EXTSEL_T3CC4 +# define ADC1_EXTSEL_T3TRGO ADC_CR2_EXTSEL_T3TRGO +# define ADC2_EXTSEL_T3CC1 ADC_CR2_EXTSEL_T3CC1 +# define ADC2_EXTSEL_T3CC2 ADC_CR2_EXTSEL_T3CC2 +# define ADC2_EXTSEL_T3CC3 ADC_CR2_EXTSEL_T3CC3 +# define ADC2_EXTSEL_T3CC4 ADC_CR2_EXTSEL_T3CC4 +# define ADC2_EXTSEL_T3TRGO ADC_CR2_EXTSEL_T3TRGO +# define ADC3_EXTSEL_T3CC1 ADC_CR2_EXTSEL_T3CC1 +# define ADC3_EXTSEL_T3CC2 ADC_CR2_EXTSEL_T3CC2 +# define ADC3_EXTSEL_T3CC3 ADC_CR2_EXTSEL_T3CC3 +# define ADC3_EXTSEL_T3CC4 ADC_CR2_EXTSEL_T3CC4 +# define ADC3_EXTSEL_T3TRGO ADC_CR2_EXTSEL_T3TRGO +# define ADC4_EXTSEL_T3CC1 ADC_CR2_EXTSEL_T3CC1 +# define ADC4_EXTSEL_T3CC2 ADC_CR2_EXTSEL_T3CC2 +# define ADC4_EXTSEL_T3CC3 ADC_CR2_EXTSEL_T3CC3 +# define ADC4_EXTSEL_T3CC4 ADC_CR2_EXTSEL_T3CC4 +# define ADC4_EXTSEL_T3TRGO ADC_CR2_EXTSEL_T3TRGO +# define ADC1_EXTSEL_T4CC1 ADC_CR2_EXTSEL_T4CC1 +# define ADC1_EXTSEL_T4CC2 ADC_CR2_EXTSEL_T4CC2 +# define ADC1_EXTSEL_T4CC3 ADC_CR2_EXTSEL_T4CC3 +# define ADC1_EXTSEL_T4CC4 ADC_CR2_EXTSEL_T4CC4 +# define ADC1_EXTSEL_T4TRGO ADC_CR2_EXTSEL_T4TRGO +# define ADC2_EXTSEL_T4CC1 ADC_CR2_EXTSEL_T4CC1 +# define ADC2_EXTSEL_T4CC2 ADC_CR2_EXTSEL_T4CC2 +# define ADC2_EXTSEL_T4CC3 ADC_CR2_EXTSEL_T4CC3 +# define ADC2_EXTSEL_T4CC4 ADC_CR2_EXTSEL_T4CC4 +# define ADC2_EXTSEL_T4TRGO ADC_CR2_EXTSEL_T4TRGO +# define ADC3_EXTSEL_T4CC1 ADC_CR2_EXTSEL_T4CC1 +# define ADC3_EXTSEL_T4CC2 ADC_CR2_EXTSEL_T4CC2 +# define ADC3_EXTSEL_T4CC3 ADC_CR2_EXTSEL_T4CC3 +# define ADC3_EXTSEL_T4CC4 ADC_CR2_EXTSEL_T4CC4 +# define ADC3_EXTSEL_T4TRGO ADC_CR2_EXTSEL_T4TRGO +# define ADC4_EXTSEL_T4CC1 ADC_CR2_EXTSEL_T4CC1 +# define ADC4_EXTSEL_T4CC2 ADC_CR2_EXTSEL_T4CC2 +# define ADC4_EXTSEL_T4CC3 ADC_CR2_EXTSEL_T4CC3 +# define ADC4_EXTSEL_T4CC4 ADC_CR2_EXTSEL_T4CC4 +# define ADC4_EXTSEL_T4TRGO ADC_CR2_EXTSEL_T4TRGO +# define ADC1_EXTSEL_T5CC1 ADC_CR2_EXTSEL_T5CC1 +# define ADC1_EXTSEL_T5CC2 ADC_CR2_EXTSEL_T5CC2 +# define ADC1_EXTSEL_T5CC3 ADC_CR2_EXTSEL_T5CC3 +# define ADC1_EXTSEL_T5CC4 ADC_CR2_EXTSEL_T5CC4 +# define ADC1_EXTSEL_T5TRGO ADC_CR2_EXTSEL_T5TRGO +# define ADC2_EXTSEL_T5CC1 ADC_CR2_EXTSEL_T5CC1 +# define ADC2_EXTSEL_T5CC2 ADC_CR2_EXTSEL_T5CC2 +# define ADC2_EXTSEL_T5CC3 ADC_CR2_EXTSEL_T5CC3 +# define ADC2_EXTSEL_T5CC4 ADC_CR2_EXTSEL_T5CC4 +# define ADC2_EXTSEL_T5TRGO ADC_CR2_EXTSEL_T5TRGO +# define ADC3_EXTSEL_T5CC1 ADC_CR2_EXTSEL_T5CC1 +# define ADC3_EXTSEL_T5CC2 ADC_CR2_EXTSEL_T5CC2 +# define ADC3_EXTSEL_T5CC3 ADC_CR2_EXTSEL_T5CC3 +# define ADC3_EXTSEL_T5CC4 ADC_CR2_EXTSEL_T5CC4 +# define ADC3_EXTSEL_T5TRGO ADC_CR2_EXTSEL_T5TRGO +# define ADC4_EXTSEL_T5CC1 ADC_CR2_EXTSEL_T5CC1 +# define ADC4_EXTSEL_T5CC2 ADC_CR2_EXTSEL_T5CC2 +# define ADC4_EXTSEL_T5CC3 ADC_CR2_EXTSEL_T5CC3 +# define ADC4_EXTSEL_T5CC4 ADC_CR2_EXTSEL_T5CC4 +# define ADC4_EXTSEL_T5TRGO ADC_CR2_EXTSEL_T5TRGO +# define ADC1_EXTSEL_T6CC1 ADC_CR2_EXTSEL_T6CC1 +# define ADC1_EXTSEL_T6CC2 ADC_CR2_EXTSEL_T6CC2 +# define ADC1_EXTSEL_T6CC3 ADC_CR2_EXTSEL_T6CC3 +# define ADC1_EXTSEL_T6CC4 ADC_CR2_EXTSEL_T6CC4 +# define ADC1_EXTSEL_T6TRGO ADC_CR2_EXTSEL_T6TRGO +# define ADC2_EXTSEL_T6CC1 ADC_CR2_EXTSEL_T6CC1 +# define ADC2_EXTSEL_T6CC2 ADC_CR2_EXTSEL_T6CC2 +# define ADC2_EXTSEL_T6CC3 ADC_CR2_EXTSEL_T6CC3 +# define ADC2_EXTSEL_T6CC4 ADC_CR2_EXTSEL_T6CC4 +# define ADC2_EXTSEL_T6TRGO ADC_CR2_EXTSEL_T6TRGO +# define ADC3_EXTSEL_T6CC1 ADC_CR2_EXTSEL_T6CC1 +# define ADC3_EXTSEL_T6CC2 ADC_CR2_EXTSEL_T6CC2 +# define ADC3_EXTSEL_T6CC3 ADC_CR2_EXTSEL_T6CC3 +# define ADC3_EXTSEL_T6CC4 ADC_CR2_EXTSEL_T6CC4 +# define ADC3_EXTSEL_T6TRGO ADC_CR2_EXTSEL_T6TRGO +# define ADC4_EXTSEL_T6CC1 ADC_CR2_EXTSEL_T6CC1 +# define ADC4_EXTSEL_T6CC2 ADC_CR2_EXTSEL_T6CC2 +# define ADC4_EXTSEL_T6CC3 ADC_CR2_EXTSEL_T6CC3 +# define ADC4_EXTSEL_T6CC4 ADC_CR2_EXTSEL_T6CC4 +# define ADC4_EXTSEL_T6TRGO ADC_CR2_EXTSEL_T6TRGO +# define ADC1_EXTSEL_T7CC1 ADC_CR2_EXTSEL_T7CC1 +# define ADC1_EXTSEL_T7CC2 ADC_CR2_EXTSEL_T7CC2 +# define ADC1_EXTSEL_T7CC3 ADC_CR2_EXTSEL_T7CC3 +# define ADC1_EXTSEL_T7CC4 ADC_CR2_EXTSEL_T7CC4 +# define ADC1_EXTSEL_T7TRGO ADC_CR2_EXTSEL_T7TRGO +# define ADC2_EXTSEL_T7CC1 ADC_CR2_EXTSEL_T7CC1 +# define ADC2_EXTSEL_T7CC2 ADC_CR2_EXTSEL_T7CC2 +# define ADC2_EXTSEL_T7CC3 ADC_CR2_EXTSEL_T7CC3 +# define ADC2_EXTSEL_T7CC4 ADC_CR2_EXTSEL_T7CC4 +# define ADC2_EXTSEL_T7TRGO ADC_CR2_EXTSEL_T7TRGO +# define ADC3_EXTSEL_T7CC1 ADC_CR2_EXTSEL_T7CC1 +# define ADC3_EXTSEL_T7CC2 ADC_CR2_EXTSEL_T7CC2 +# define ADC3_EXTSEL_T7CC3 ADC_CR2_EXTSEL_T7CC3 +# define ADC3_EXTSEL_T7CC4 ADC_CR2_EXTSEL_T7CC4 +# define ADC3_EXTSEL_T7TRGO ADC_CR2_EXTSEL_T7TRGO +# define ADC4_EXTSEL_T7CC1 ADC_CR2_EXTSEL_T7CC1 +# define ADC4_EXTSEL_T7CC2 ADC_CR2_EXTSEL_T7CC2 +# define ADC4_EXTSEL_T7CC3 ADC_CR2_EXTSEL_T7CC3 +# define ADC4_EXTSEL_T7CC4 ADC_CR2_EXTSEL_T7CC4 +# define ADC4_EXTSEL_T7TRGO ADC_CR2_EXTSEL_T7TRGO +# define ADC1_EXTSEL_T8CC1 ADC_CR2_EXTSEL_T8CC1 +# define ADC1_EXTSEL_T8CC2 ADC_CR2_EXTSEL_T8CC2 +# define ADC1_EXTSEL_T8CC3 ADC_CR2_EXTSEL_T8CC3 +# define ADC1_EXTSEL_T8CC4 ADC_CR2_EXTSEL_T8CC4 +# define ADC1_EXTSEL_T8TRGO ADC_CR2_EXTSEL_T8TRGO +# define ADC2_EXTSEL_T8CC1 ADC_CR2_EXTSEL_T8CC1 +# define ADC2_EXTSEL_T8CC2 ADC_CR2_EXTSEL_T8CC2 +# define ADC2_EXTSEL_T8CC3 ADC_CR2_EXTSEL_T8CC3 +# define ADC2_EXTSEL_T8CC4 ADC_CR2_EXTSEL_T8CC4 +# define ADC2_EXTSEL_T8TRGO ADC_CR2_EXTSEL_T8TRGO +# define ADC3_EXTSEL_T8CC1 ADC_CR2_EXTSEL_T8CC1 +# define ADC3_EXTSEL_T8CC2 ADC_CR2_EXTSEL_T8CC2 +# define ADC3_EXTSEL_T8CC3 ADC_CR2_EXTSEL_T8CC3 +# define ADC3_EXTSEL_T8CC4 ADC_CR2_EXTSEL_T8CC4 +# define ADC3_EXTSEL_T8TRGO ADC_CR2_EXTSEL_T8TRGO +# define ADC4_EXTSEL_T8CC1 ADC_CR2_EXTSEL_T8CC1 +# define ADC4_EXTSEL_T8CC2 ADC_CR2_EXTSEL_T8CC2 +# define ADC4_EXTSEL_T8CC3 ADC_CR2_EXTSEL_T8CC3 +# define ADC4_EXTSEL_T8CC4 ADC_CR2_EXTSEL_T8CC4 +# define ADC4_EXTSEL_T8TRGO ADC_CR2_EXTSEL_T8TRGO +# define ADC1_EXTSEL_T9CC1 ADC_CR2_EXTSEL_T9CC1 +# define ADC1_EXTSEL_T9CC2 ADC_CR2_EXTSEL_T9CC2 +# define ADC1_EXTSEL_T9CC3 ADC_CR2_EXTSEL_T9CC3 +# define ADC1_EXTSEL_T9CC4 ADC_CR2_EXTSEL_T9CC4 +# define ADC1_EXTSEL_T9TRGO ADC_CR2_EXTSEL_T9TRGO +# define ADC2_EXTSEL_T9CC1 ADC_CR2_EXTSEL_T9CC1 +# define ADC2_EXTSEL_T9CC2 ADC_CR2_EXTSEL_T9CC2 +# define ADC2_EXTSEL_T9CC3 ADC_CR2_EXTSEL_T9CC3 +# define ADC2_EXTSEL_T9CC4 ADC_CR2_EXTSEL_T9CC4 +# define ADC2_EXTSEL_T9TRGO ADC_CR2_EXTSEL_T9TRGO +# define ADC3_EXTSEL_T9CC1 ADC_CR2_EXTSEL_T9CC1 +# define ADC3_EXTSEL_T9CC2 ADC_CR2_EXTSEL_T9CC2 +# define ADC3_EXTSEL_T9CC3 ADC_CR2_EXTSEL_T9CC3 +# define ADC3_EXTSEL_T9CC4 ADC_CR2_EXTSEL_T9CC4 +# define ADC3_EXTSEL_T9TRGO ADC_CR2_EXTSEL_T9TRGO +# define ADC4_EXTSEL_T9CC1 ADC_CR2_EXTSEL_T9CC1 +# define ADC4_EXTSEL_T9CC2 ADC_CR2_EXTSEL_T9CC2 +# define ADC4_EXTSEL_T9CC3 ADC_CR2_EXTSEL_T9CC3 +# define ADC4_EXTSEL_T9CC4 ADC_CR2_EXTSEL_T9CC4 +# define ADC4_EXTSEL_T9TRGO ADC_CR2_EXTSEL_T9TRGO +# define ADC1_EXTSEL_T10CC1 ADC_CR2_EXTSEL_T10CC1 +# define ADC1_EXTSEL_T10CC2 ADC_CR2_EXTSEL_T10CC2 +# define ADC1_EXTSEL_T10CC3 ADC_CR2_EXTSEL_T10CC3 +# define ADC1_EXTSEL_T10CC4 ADC_CR2_EXTSEL_T10CC4 +# define ADC1_EXTSEL_T10TRGO ADC_CR2_EXTSEL_T10TRGO +# define ADC2_EXTSEL_T10CC1 ADC_CR2_EXTSEL_T10CC1 +# define ADC2_EXTSEL_T10CC2 ADC_CR2_EXTSEL_T10CC2 +# define ADC2_EXTSEL_T10CC3 ADC_CR2_EXTSEL_T10CC3 +# define ADC2_EXTSEL_T10CC4 ADC_CR2_EXTSEL_T10CC4 +# define ADC2_EXTSEL_T10TRGO ADC_CR2_EXTSEL_T10TRGO +# define ADC3_EXTSEL_T10CC1 ADC_CR2_EXTSEL_T10CC1 +# define ADC3_EXTSEL_T10CC2 ADC_CR2_EXTSEL_T10CC2 +# define ADC3_EXTSEL_T10CC3 ADC_CR2_EXTSEL_T10CC3 +# define ADC3_EXTSEL_T10CC4 ADC_CR2_EXTSEL_T10CC4 +# define ADC3_EXTSEL_T10TRGO ADC_CR2_EXTSEL_T10TRGO +# define ADC4_EXTSEL_T10CC1 ADC_CR2_EXTSEL_T10CC1 +# define ADC4_EXTSEL_T10CC2 ADC_CR2_EXTSEL_T10CC2 +# define ADC4_EXTSEL_T10CC3 ADC_CR2_EXTSEL_T10CC3 +# define ADC4_EXTSEL_T10CC4 ADC_CR2_EXTSEL_T10CC4 +# define ADC4_EXTSEL_T10TRGO ADC_CR2_EXTSEL_T10TRGO +# define ADC1_EXTSEL_T15CC1 ADC_CR2_EXTSEL_T15CC1 +# define ADC1_EXTSEL_T15CC2 ADC_CR2_EXTSEL_T15CC2 +# define ADC1_EXTSEL_T15CC3 ADC_CR2_EXTSEL_T15CC3 +# define ADC1_EXTSEL_T15CC4 ADC_CR2_EXTSEL_T15CC4 +# define ADC1_EXTSEL_T15TRGO ADC_CR2_EXTSEL_T15TRGO +# define ADC2_EXTSEL_T15CC1 ADC_CR2_EXTSEL_T15CC1 +# define ADC2_EXTSEL_T15CC2 ADC_CR2_EXTSEL_T15CC2 +# define ADC2_EXTSEL_T15CC3 ADC_CR2_EXTSEL_T15CC3 +# define ADC2_EXTSEL_T15CC4 ADC_CR2_EXTSEL_T15CC4 +# define ADC2_EXTSEL_T15TRGO ADC_CR2_EXTSEL_T15TRGO +# define ADC3_EXTSEL_T15CC1 ADC_CR2_EXTSEL_T15CC1 +# define ADC3_EXTSEL_T15CC2 ADC_CR2_EXTSEL_T15CC2 +# define ADC3_EXTSEL_T15CC3 ADC_CR2_EXTSEL_T15CC3 +# define ADC3_EXTSEL_T15CC4 ADC_CR2_EXTSEL_T15CC4 +# define ADC3_EXTSEL_T15TRGO ADC_CR2_EXTSEL_T15TRGO +# define ADC4_EXTSEL_T15CC1 ADC_CR2_EXTSEL_T15CC1 +# define ADC4_EXTSEL_T15CC2 ADC_CR2_EXTSEL_T15CC2 +# define ADC4_EXTSEL_T15CC3 ADC_CR2_EXTSEL_T15CC3 +# define ADC4_EXTSEL_T15CC4 ADC_CR2_EXTSEL_T15CC4 +# define ADC4_EXTSEL_T15TRGO ADC_CR2_EXTSEL_T15TRGO +# define ADC1_EXTSEL_T20CC1 ADC_CR2_EXTSEL_T20CC1 +# define ADC1_EXTSEL_T20CC2 ADC_CR2_EXTSEL_T20CC2 +# define ADC1_EXTSEL_T20CC3 ADC_CR2_EXTSEL_T20CC3 +# define ADC1_EXTSEL_T20CC4 ADC_CR2_EXTSEL_T20CC4 +# define ADC1_EXTSEL_T20TRGO ADC_CR2_EXTSEL_T20TRGO +# define ADC2_EXTSEL_T20CC1 ADC_CR2_EXTSEL_T20CC1 +# define ADC2_EXTSEL_T20CC2 ADC_CR2_EXTSEL_T20CC2 +# define ADC2_EXTSEL_T20CC3 ADC_CR2_EXTSEL_T20CC3 +# define ADC2_EXTSEL_T20CC4 ADC_CR2_EXTSEL_T20CC4 +# define ADC2_EXTSEL_T20TRGO ADC_CR2_EXTSEL_T20TRGO +# define ADC3_EXTSEL_T20CC1 ADC_CR2_EXTSEL_T20CC1 +# define ADC3_EXTSEL_T20CC2 ADC_CR2_EXTSEL_T20CC2 +# define ADC3_EXTSEL_T20CC3 ADC_CR2_EXTSEL_T20CC3 +# define ADC3_EXTSEL_T20CC4 ADC_CR2_EXTSEL_T20CC4 +# define ADC3_EXTSEL_T20TRGO ADC_CR2_EXTSEL_T20TRGO +# define ADC4_EXTSEL_T20CC1 ADC_CR2_EXTSEL_T20CC1 +# define ADC4_EXTSEL_T20CC2 ADC_CR2_EXTSEL_T20CC2 +# define ADC4_EXTSEL_T20CC3 ADC_CR2_EXTSEL_T20CC3 +# define ADC4_EXTSEL_T20CC4 ADC_CR2_EXTSEL_T20CC4 +# define ADC4_EXTSEL_T20TRGO ADC_CR2_EXTSEL_T20TRGO +#endif + +#if defined(CONFIG_STM32_TIM1_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM2_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM3_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM4_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM5_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T5CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T5CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T5CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T5CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T5TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM6_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM7_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T7CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T7CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T7CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T7CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T7TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM8_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM9_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T9CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T9CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T9CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T9CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T9TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM10_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T10CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T10CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T10CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T10CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T10TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM15_ADC1) +# if CONFIG_STM32_ADC1_TIMTRIG == 0 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15CC1 +# elif CONFIG_STM32_ADC1_TIMTRIG == 1 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15CC2 +# elif CONFIG_STM32_ADC1_TIMTRIG == 2 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15CC3 +# elif CONFIG_STM32_ADC1_TIMTRIG == 3 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15CC4 +# elif CONFIG_STM32_ADC1_TIMTRIG == 4 +# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15TRGO +# else +# error "CONFIG_STM32_ADC1_TIMTRIG is out of range" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM2_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM3_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM4_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM5_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T5CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T5CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T5CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T5CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T5TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM6_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM8_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM15_ADC2) +# if CONFIG_STM32_ADC2_TIMTRIG == 0 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15CC1 +# elif CONFIG_STM32_ADC2_TIMTRIG == 1 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15CC2 +# elif CONFIG_STM32_ADC2_TIMTRIG == 2 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15CC3 +# elif CONFIG_STM32_ADC2_TIMTRIG == 3 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15CC4 +# elif CONFIG_STM32_ADC2_TIMTRIG == 4 +# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15TRGO +# else +# error "CONFIG_STM32_ADC2_TIMTRIG is out of range" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM2_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T2CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T2CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T2CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T2CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T2TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM3_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T3CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T3CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T3CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T3CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T3TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM4_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T4CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T4CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T4CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T4CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T4TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM5_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T5CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T5CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T5CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T5CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T5TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM7_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T7CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T7CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T7CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T7CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T7TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM8_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T8CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T8CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T8CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T8CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T8TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM15_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T15CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T15CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T15CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T15CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T15TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM20_ADC3) +# if CONFIG_STM32_ADC3_TIMTRIG == 0 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T20CC1 +# elif CONFIG_STM32_ADC3_TIMTRIG == 1 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T20CC2 +# elif CONFIG_STM32_ADC3_TIMTRIG == 2 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T20CC3 +# elif CONFIG_STM32_ADC3_TIMTRIG == 3 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T20CC4 +# elif CONFIG_STM32_ADC3_TIMTRIG == 4 +# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T20TRGO +# else +# error "CONFIG_STM32_ADC3_TIMTRIG is out of range" +# endif +#endif + +#if defined(CONFIG_STM32_TIM1_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T1CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T1CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T1CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T1CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T1TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM2_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T2CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T2CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T2CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T2CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T2TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM3_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T3CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T3CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T3CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T3CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T3TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM4_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T4CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T4CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T4CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T4CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T4TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM5_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T5CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T5CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T5CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T5CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T5TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM7_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T7CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T7CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T7CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T7CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T7TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM8_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T8CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T8CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T8CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T8CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T8TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM15_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T15CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T15CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T15CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T15CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T15TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#elif defined(CONFIG_STM32_TIM20_ADC4) +# if CONFIG_STM32_ADC4_TIMTRIG == 0 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T20CC1 +# elif CONFIG_STM32_ADC4_TIMTRIG == 1 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T20CC2 +# elif CONFIG_STM32_ADC4_TIMTRIG == 2 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T20CC3 +# elif CONFIG_STM32_ADC4_TIMTRIG == 3 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T20CC4 +# elif CONFIG_STM32_ADC4_TIMTRIG == 4 +# define ADC4_EXTSEL_VALUE ADC4_EXTSEL_T20TRGO +# else +# error "CONFIG_STM32_ADC4_TIMTRIG is out of range" +# endif +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifdef CONFIG_STM32_STM32L15XX +typedef enum ADC_IO_CMDS +{ + IO_ENABLE_TEMPER_VOLT_CH = 0, + IO_ENABLE_DISABLE_PDI, + IO_ENABLE_DISABLE_PDD, + IO_ENABLE_DISABLE_PDD_PDI, + IO_ENABLE_DISABLE_AWDIE, + IO_ENABLE_DISABLE_EOCIE, + IO_ENABLE_DISABLE_JEOCIE, + IO_ENABLE_DISABLE_OVRIE = 7, + IO_ENABLE_DISABLE_ALL_INTS, + IO_START_CONV, + IO_STOP_ADC, + IO_START_ADC, +} ADC_IO_CMDS; + +/* Channel and sample time pair */ + +typedef struct adc_channel_s +{ + uint8_t channel:5; + + /* Sampling time individually for each channel + * 000: 4 cycles + * 001: 9 cycles + * 010: 16 cycles + * 011: 24 cycles + * 100: 48 cycles + * 101: 96 cycles + * 110: 192 cycles + * 111: 384 cycles - selected for all channels + */ + + uint8_t sample_time:3; +} adc_channel_t; + +/* This structure will be used while setting channels to specified by the + * "channel-sample time" pairs' values + */ + +struct adc_sample_time_s +{ + adc_channel_t *channel; /* Array of channels */ + uint8_t channels_nbr:5; /* Number of channels in array */ + bool all_same:1; /* All 32 channels will get the + * same value of the sample time */ + uint8_t all_ch_sample_time:3; /* Sample time for all 32 channels */ +}; + +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_adcinitialize + * + * Description: + * Initialize the ADC. + * + * Input Parameters: + * intf - Could be {1,2,3} for ADC1, ADC2, or ADC3 + * chanlist - The list of channels + * nchannels - Number of channels + * + * Returned Value: + * Valid can device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s; +struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist, + int nchannels); + +#ifdef CONFIG_STM32_STM32L15XX +void stm32_adcchange_sample_time(FAR struct adc_dev_s *dev, + FAR struct adc_sample_time_s *time_samples); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_STM32_ADC1 || CONFIG_STM32_ADC2 || + * CONFIG_STM32_ADC3 || CONFIG_STM32_ADC4 + */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_ADC_H */ diff --git a/arch/arm/src/stm32/stm32_aes.c b/arch/arm/src/stm32/stm32_aes.c new file mode 100644 index 0000000000000000000000000000000000000000..88e3a236c8f6ee5c7573455770d85a4791309d35 --- /dev/null +++ b/arch/arm/src/stm32/stm32_aes.c @@ -0,0 +1,320 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_aes.c + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32_aes.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AES_BLOCK_SIZE 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void aes_enable(bool on); +static void aes_ccfc(void); +static void aes_setkey(const void *key, size_t key_len); +static void aes_setiv(const void *iv); +static void aes_encryptblock(void *block_out, const void *block_in); +static int aes_setup_cr(int mode, int encrypt); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t aes_lock; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void aes_enable(bool on) +{ + uint32_t regval; + + regval = getreg32(STM32_AES_CR); + if (on) + regval |= AES_CR_EN; + else + regval &= ~AES_CR_EN; + putreg32(regval, STM32_AES_CR); +} + +/* Clear AES_SR_CCF status register bit */ + +static void aes_ccfc(void) +{ + uint32_t regval; + + regval = getreg32(STM32_AES_CR); + regval |= AES_CR_CCFC; + putreg32(regval, STM32_AES_CR); +} + +static void aes_setkey(const void *key, size_t key_len) +{ + uint32_t *in = (uint32_t *)key; + + (void)key_len; + + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR3); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR2); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR1); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR0); +} + +static void aes_setiv(const void *iv) +{ + uint32_t *in = (uint32_t *)iv; + + putreg32(__builtin_bswap32(*in), STM32_AES_IVR3); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR2); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR1); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR0); +} + +static void aes_encryptblock(void *block_out, const void *block_in) +{ + uint32_t *in = (uint32_t *)block_in; + uint32_t *out = (uint32_t *)block_out; + + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + + while (!(getreg32(STM32_AES_SR) & AES_SR_CCF)) + ; + aes_ccfc(); + + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); +} + +static int aes_setup_cr(int mode, int encrypt) +{ + uint32_t regval = 0; + + regval |= AES_CR_DATATYPE_BE; + + switch (mode) + { + case AES_MODE_ECB: + regval |= AES_CR_CHMOD_ECB; + break; + + case AES_MODE_CBC: + regval |= AES_CR_CHMOD_CBC; + break; + + case AES_MODE_CTR: + regval |= AES_CR_CHMOD_CTR; + break; + + default: + return -EINVAL; + } + + if (encrypt) + { + regval |= AES_CR_MODE_ENCRYPT; + } + else + { + if (mode == AES_MODE_CTR) + { + regval |= AES_CR_MODE_DECRYPT; + } + else + { + regval |= AES_CR_MODE_DECRYPT_KEYDERIV; + } + } + + putreg32(regval, STM32_AES_CR); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int aes_cypher(void *out, const void *in, uint32_t size, const void *iv, + const void *key, uint32_t keysize, int mode, int encrypt) +{ + int ret = OK; + + if ((size & (AES_BLOCK_SIZE-1)) != 0) + { + return -EINVAL; + } + + if (keysize != 16) + { + return -EINVAL; + } + + ret = sem_wait(&aes_lock); + if (ret < 0) + { + return ret; + } + + /* AES must be disabled before changing mode, key or IV. */ + + aes_enable(false); + ret = aes_setup_cr(mode, encrypt); + if (ret < 0) + { + goto out; + } + + aes_setkey(key, keysize); + if (iv) + { + aes_setiv(iv); + } + + aes_enable(true); + while (size) + { + aes_encryptblock(out, in); + out = (uint8_t *)out + AES_BLOCK_SIZE; + in = (uint8_t *)in + AES_BLOCK_SIZE; + size -= AES_BLOCK_SIZE; + } + + aes_enable(false); + +out: + sem_post(&aes_lock); + return ret; +} + +int up_aesreset(void) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + regval = getreg32(STM32_RCC_AHBRSTR); + regval |= RCC_AHBRSTR_AESRST; + putreg32(regval, STM32_RCC_AHBRSTR); + regval &= ~RCC_AHBRSTR_AESRST; + putreg32(regval, STM32_RCC_AHBRSTR); + + leave_critical_section(flags); + + return OK; +} + +int up_aesinitialize(void) +{ + uint32_t regval; + + sem_init(&aes_lock, 0, 1); + + regval = getreg32(STM32_RCC_AHBENR); + regval |= RCC_AHBENR_AESEN; + putreg32(regval, STM32_RCC_AHBENR); + + aes_enable(false); + + return OK; +} + +int up_aesuninitialize(void) +{ + uint32_t regval; + + aes_enable(false); + + regval = getreg32(STM32_RCC_AHBENR); + regval &= ~RCC_AHBENR_AESEN; + putreg32(regval, STM32_RCC_AHBENR); + + sem_destroy(&aes_lock); + + return OK; +} diff --git a/arch/arm/src/stm32/stm32_aes.h b/arch/arm/src/stm32/stm32_aes.h new file mode 100644 index 0000000000000000000000000000000000000000..50c0d22eab1851d51aa510ea9afa2eab091c0c8f --- /dev/null +++ b/arch/arm/src/stm32/stm32_aes.h @@ -0,0 +1,71 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_aes.h + * + * Copyright (C) 2014 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_AES_H +#define __ARCH_ARM_SRC_STM32_STM32_AES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +/* Only the STM32L162 devices have AES, but we don't bother with exact macros for + * simplicity. + */ + +#ifdef CONFIG_STM32_STM32L15XX +# include "chip/stm32l15xxx_aes.h" +#else +# error "Unknown chip for AES" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_AES_H */ diff --git a/arch/arm/src/stm32/stm32_alarm.h b/arch/arm/src/stm32/stm32_alarm.h new file mode 100644 index 0000000000000000000000000000000000000000..67bf6482080bf32652ae7f78a14864904e52347e --- /dev/null +++ b/arch/arm/src/stm32/stm32_alarm.h @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_alarm.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Uros Platise (Original for the F1) + * Gregory Nutt (On-going support and development) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_ALARM_H +#define __ARCH_ARM_SRC_STM32_STM32_ALARM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* The form of an alarm callback */ + +typedef CODE void (*alarmcb_t)(void); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +struct timespec; +int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); + +/**************************************************************************** + * Name: stm32_rtc_cancelalarm + * + * Description: + * Cancel a pending alarm alarm + * + * Input Parameters: + * none + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int stm32_rtc_cancelalarm(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_RTC_ALARM */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_ALARM_H */ diff --git a/arch/arm/src/stm32/stm32_allocateheap.c b/arch/arm/src/stm32/stm32_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..8a844b6d22d21f7fc357f921d2bbd202ef0ade2c --- /dev/null +++ b/arch/arm/src/stm32/stm32_allocateheap.c @@ -0,0 +1,631 @@ +/**************************************************************************** + * arch/arm/src/stm32/up_allocateheap.c + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Internal SRAM is available in all members of the STM32 family. The + * following definitions must be provided to specify the size and + * location of internal(system) SRAM: + * + * CONFIG_RAM_END : End address (+1) of SRAM (F1 family only, the + * : F4 family uses the a priori end of SRAM) + * + * The F4 family also contains internal CCM SRAM. This SRAM is different + * because it cannot be used for DMA. So if DMA needed, then the following + * should be defined to exclude CCM SRAM from the heap: + * + * CONFIG_STM32_CCMEXCLUDE : Exclude CCM SRAM from the HEAP + * + * In addition to internal SRAM, SRAM may also be available through the FSMC. + * In order to use FSMC SRAM, the following additional things need to be + * present in the NuttX configuration file: + * + * CONFIG_STM32_FSMC=y : Enables the FSMC + * CONFIG_STM32_FSMC_SRAM=y : Indicates that SRAM is available via the + * FSMC (as opposed to an LCD or FLASH). + * CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC + * address space + * CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC + * address space + * CONFIG_MM_REGIONS : Must be set to a large enough value to + * include the FSMC SRAM (as determined by + * the rules provided below) + */ + +#ifndef CONFIG_STM32_FSMC +# undef CONFIG_STM32_FSMC_SRAM +#endif + +/* The STM32L15xxx family has only internal SRAM. The heap is in one contiguous + * block starting at g_idle_topstack and extending through CONFIG_RAM_END. + */ + +#if defined(CONFIG_STM32_STM32L15XX) + + /* Set the end of system SRAM */ + +# define SRAM1_END CONFIG_RAM_END + + /* There is no FSMC (Other EnergyLite STM32's do have an FSMC, but not the STM32L15X */ + +# undef CONFIG_STM32_FSMC_SRAM + + /* The STM32L EnergyLite family has no CCM SRAM */ + +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 + + /* Only one memory region can be support (internal SRAM) */ + +# if CONFIG_MM_REGIONS > 1 +# error "CONFIG_MM_REGIONS > 1. The STM32L15X has only one memory region." +# endif + +/* For the STM312F10xxx family, all internal SRAM is in one contiguous block + * starting at g_idle_topstack and extending through CONFIG_RAM_END (my apologies + * for the bad naming). In addition, external FSMC SRAM may be available. + */ + +#elif defined(CONFIG_STM32_STM32F10XX) + + /* Set the end of system SRAM */ + +# define SRAM1_END CONFIG_RAM_END + + /* Check if external FSMC SRAM is provided */ + +# ifdef CONFIG_STM32_FSMC_SRAM +# if CONFIG_MM_REGIONS < 2 +# warning "FSMC SRAM not included in the heap" +# undef CONFIG_STM32_FSMC_SRAM +# elif CONFIG_MM_REGIONS > 2 +# error "CONFIG_MM_REGIONS > 2 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 2 +# endif +# elif CONFIG_MM_REGIONS > 1 +# error "CONFIG_MM_REGIONS > 1 but I don't know what the other region(s) are" +# endif + + /* The STM32 F1 has no CCM SRAM */ + +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 + +/* Members of the STM32F30xxx family has a variable amount of SRAM from 24 + * to 40Kb plus 8KB if CCM SRAM. No external RAM is supported (the F3 family + * has no FSMC). + * + * As a complication, CCM SRAM cannot be used for DMA. So, if STM32 DMA is + * enabled, CCM SRAM should probably be excluded from the heap. + */ + +#elif defined(CONFIG_STM32_STM32F30XX) + + /* Set the end of system SRAM */ + +# define SRAM1_END CONFIG_RAM_END + + /* Set the range of CCM SRAM as well (although we may not use it) */ + +# define SRAM2_START 0x10000000 +# define SRAM2_END 0x10002000 + + /* There is no FSMC */ + +# undef CONFIG_STM32_FSMC_SRAM + + /* There are 2 possible SRAM configurations: + * + * Configuration 1. System SRAM (only) + * CONFIG_MM_REGIONS == 1 + * CONFIG_STM32_CCMEXCLUDE defined + * Configuration 2. System SRAM and CCM SRAM + * CONFIG_MM_REGIONS == 2 + * CONFIG_STM32_CCMEXCLUDE NOT defined + */ + +# if CONFIG_MM_REGIONS < 2 + + /* Only one memory region. Force Configuration 1 */ + +# ifndef CONFIG_STM32_CCMEXCLUDE +# if CONFIG_STM32_HAVE_CCM +# warning "CCM SRAM excluded from the heap" +# endif +# define CONFIG_STM32_CCMEXCLUDE 1 +# endif + + /* CONFIG_MM_REGIONS may be 2 if CCM SRAM is included in the head */ + +# elif CONFIG_MM_REGIONS >= 2 +# if CONFIG_MM_REGIONS > 2 +# error "No more than two memory regions can be supported (CONFIG_MM_REGIONS)" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 2 +# endif + + /* Two memory regions is okay if CCM SRAM is not disabled. */ + +# ifdef CONFIG_STM32_CCMEXCLUDE + + /* Configuration 1: CONFIG_MM_REGIONS should have been 2 */ + +# error "CONFIG_MM_REGIONS >= 2 but but CCM SRAM is excluded (CONFIG_STM32_CCMEXCLUDE)" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 1 +# else + + /* Configuration 2: DMA should be disabled */ + +# ifdef CONFIG_ARCH_DMA +# warning "CCM SRAM is included in the heap AND DMA is enabled" +# endif +# endif +# endif + +/* All members of the STM32F37xxx families have 16-32 Kib ram in a single + * bank. No external RAM is supported (the F3 family has no FSMC). + */ +#elif defined(CONFIG_STM32_STM32F37XX) + + /* Set the end of system SRAM */ + +# define SRAM1_END CONFIG_RAM_END + + /* There is no FSMC */ + +# undef CONFIG_STM32_FSMC_SRAM + + /* The STM32 F37xx has no CCM SRAM */ + +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 + + /* Only one memory region can be support (internal SRAM) */ + +# if CONFIG_MM_REGIONS > 1 +# error "CONFIG_MM_REGIONS > 1. The STM32L15X has only one memory region." +# endif + + +/* Most members of both the STM32F20xxx and STM32F40xxx families have 128Kib + * in two banks: + * + * 1) 112KiB of System SRAM beginning at address 0x2000:0000 + * 2) 16KiB of System SRAM beginning at address 0x2001:c000 + * + * The STM32F401 family is an exception and has only 96Kib total on one bank: + * + * 3) 96KiB of System SRAM beginning at address 0x2000:0000 + * + * Members of the STM32F40xxx family have an additional 64Kib of CCM RAM + * for a total of 192KB. + * + * 4) 64Kib of CCM SRAM beginning at address 0x1000:0000 + * + * The STM32F427/437/429/439 parts have another 64KiB of System SRAM for a total + * of 256KiB. + * + * 5) 64Kib of System SRAM beginning at address 0x2002:0000 + * + * As determined by the linker script, g_heapbase lies in the 112KiB memory + * region and that extends to 0x2001:0000. But the first and second memory + * regions are contiguous and treated as one in this logic that extends to + * 0x2002:0000 (or 0x2003:0000 for the F427/F437/F429/F439). + * + * As a complication, CCM SRAM cannot be used for DMA. So, if STM32 DMA is enabled, + * CCM SRAM should probably be excluded from the heap or the application must take + * extra care to ensure that DMA buffers are not allocated in CCM SRAM. + * + * In addition, external FSMC SRAM may be available. + */ + +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + + /* The STM32 F2 and the STM32 F401/F411 have no CCM SRAM */ + +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F401) || \ + defined(CONFIG_STM32_STM32F411) +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 +# endif + + /* Set the end of system SRAM */ + +# if defined(CONFIG_STM32_STM32F401) +# define SRAM1_END 0x20018000 +# elif defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define SRAM1_END 0x20030000 +# else +# define SRAM1_END 0x20020000 +# endif + + /* Set the range of CCM SRAM as well (although we may not use it) */ + +# define SRAM2_START 0x10000000 +# define SRAM2_END 0x10010000 + + /* There are 4 possible SRAM configurations: + * + * Configuration 1. System SRAM (only) + * CONFIG_MM_REGIONS == 1 + * CONFIG_STM32_FSMC_SRAM NOT defined + * CONFIG_STM32_CCMEXCLUDE defined + * Configuration 2. System SRAM and CCM SRAM + * CONFIG_MM_REGIONS == 2 + * CONFIG_STM32_FSMC_SRAM NOT defined + * CONFIG_STM32_CCMEXCLUDE NOT defined + * Configuration 3. System SRAM and FSMC SRAM + * CONFIG_MM_REGIONS == 2 + * CONFIG_STM32_FSMC_SRAM defined + * CONFIG_STM32_CCMEXCLUDE defined + * Configuration 4. System SRAM, CCM SRAM, and FSMC SRAM + * CONFIG_MM_REGIONS == 3 + * CONFIG_STM32_FSMC_SRAM defined + * CONFIG_STM32_CCMEXCLUDE NOT defined + * + * Let's make sure that all definitions are consistent before doing + * anything else + */ + +# if defined(CONFIG_STM32_FSMC_SRAM) + + /* Configuration 3 or 4. External SRAM is available. CONFIG_MM_REGIONS + * should be at least 2. + */ + +# if CONFIG_MM_REGIONS < 2 + + /* Only one memory region. Force Configuration 1 */ + +# warning "FSMC SRAM (and CCM SRAM) excluded from the heap" +# undef CONFIG_STM32_FSMC_SRAM +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 + + /* CONFIG_MM_REGIONS may be 3 if CCM SRAM is included in the head */ + +# elif CONFIG_MM_REGIONS > 2 + + /* More than two memory regions. This is okay if CCM SRAM is not + * disabled. + */ + +# if defined(CONFIG_STM32_CCMEXCLUDE) + + /* Configuration 3: CONFIG_MM_REGIONS should have been 2 */ + +# error "CONFIG_MM_REGIONS > 2 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 2 +# else + + /* Configuration 4: DMA should be disabled and CONFIG_MM_REGIONS + * should be 3. + */ + +# ifdef CONFIG_ARCH_DMA +# warning "CCM SRAM is included in the heap AND DMA is enabled" +# endif + +# if CONFIG_MM_REGIONS != 3 +# error "CONFIG_MM_REGIONS > 3 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 3 +# endif +# endif + + /* CONFIG_MM_REGIONS is exactly 2. We cannot support both CCM SRAM and + * FSMC SRAM. + */ + +# elif !defined(CONFIG_STM32_CCMEXCLUDE) +# error "CONFIG_MM_REGIONS == 2, cannot support both CCM SRAM and FSMC SRAM" +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 +# endif + +# elif !defined(CONFIG_STM32_CCMEXCLUDE) + + /* Configuration 2: FSMC SRAM is not used, but CCM SRAM is requested. DMA + * should be disabled and CONFIG_MM_REGIONS should be 2. + */ + +# ifdef CONFIG_ARCH_DMA +# warning "CCM SRAM is included in the heap AND DMA is enabled" +# endif + +# if CONFIG_MM_REGIONS < 2 +# if CONFIG_STM32_HAVE_CCM +# error "CCM SRAM excluded from the heap because CONFIG_MM_REGIONS < 2" +# endif +# undef CONFIG_STM32_CCMEXCLUDE +# define CONFIG_STM32_CCMEXCLUDE 1 +# elif CONFIG_MM_REGIONS > 2 +# error "CONFIG_MM_REGIONS > 2 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 2 +# endif +# endif + +#else +# error "Unsupported STM32 chip" +#endif + +/* If FSMC SRAM is going to be used as heap, then verify that the starting + * address and size of the external SRAM region has been provided in the + * configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE). + */ + +#ifdef CONFIG_STM32_FSMC_SRAM +# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE) +# error "CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided" +# undef CONFIG_STM32_FSMC_SRAM +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_HEAP +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)ubase, usize); + + /* Allow user-mode access to the user heap memory */ + + stm32_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SRAM1_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#ifndef CONFIG_STM32_CCMEXCLUDE +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the STM32F20xxx/STM32F40xxx CCM SRAM heap */ + + stm32_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END-SRAM2_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + + /* Add the STM32F20xxx/STM32F40xxx CCM SRAM user heap region. */ + + kumm_addregion((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); +#endif + +#ifdef CONFIG_STM32_FSMC_SRAM +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the FSMC SRAM user heap memory */ + + stm32_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + + /* Add the external FSMC SRAM user heap region. */ + + kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/stm32/stm32_bbsram.c b/arch/arm/src/stm32/stm32_bbsram.c new file mode 100644 index 0000000000000000000000000000000000000000..507f5a4d4a22b5e136fd1f3b7b1f5980b9da843d --- /dev/null +++ b/arch/arm/src/stm32/stm32_bbsram.c @@ -0,0 +1,880 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_bbsram.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This will driver create a set of files in the STM32's Battery backed up + * SRAM. That can be used to store data retained across power cycles. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "stm32_bbsram.h" +#include "chip.h" +#include "stm32_pwr.h" +#include "stm32_rtc.h" + +#ifdef CONFIG_STM32_BBSRAM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_STM32_BKPSRAM) +#error Driver Requires CONFIG_STM32_BKPSRAM to be enabled +#endif + +#define MAX_OPENCNT (255) /* Limit of uint8_t */ + +#if defined(CONFIG_BBSRAM_DEBUG) +# define BBSRAM_DEBUG_READ() stm32_bbsram_rd() +# define BBSRAM_DUMP(p,s) stm32_bbsram_dump(p,s) +#else +# define BBSRAM_DEBUG_READ() +# define BBSRAM_DUMP(p,s) +#endif + +#define BBSRAM_HEADER_SIZE (sizeof(struct bbsramfh_s)) +#define BBSRAM_CRCED_OFFSET (sizeof(((struct bbsramfh_s *)0)->crc)) +#define BBSRAM_CRCED_SIZE(l) (BBSRAM_HEADER_SIZE-(BBSRAM_CRCED_OFFSET)+(l)) +#define BBSRAM_ALIGNMENT (sizeof(((struct bbsramfh_s *)0)->crc)) +#define BBSRAM_ALIGNMENT_MASK (BBSRAM_ALIGNMENT-1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* File Header */ + +struct bbsramfh_s +{ + uint32_t crc; /* CRC calculated over data and this struct + * starting at fileno */ + uint8_t fileno; /* The minor number */ + uint8_t dirty; /* Data has been written to the file */ + uint16_t len; /* Total Bytes in this file */ + struct timespec lastwrite; /* Last write time */ + uint8_t data[]; /* Data in the file */ +}; + +struct stm32_bbsram_s +{ + sem_t exclsem; /* For atomic accesses to this structure */ + uint8_t refs; /* Number of references */ + FAR struct bbsramfh_s *bbf; /* File in bbram */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_bbsram_open(FAR struct file *filep); +static int stm32_bbsram_close(FAR struct file *filep); +static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset, + int whence); +static ssize_t stm32_bbsram_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static ssize_t stm32_bbsram_write(FAR struct file *filep, + FAR const char *buffer, size_t len); +static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +#ifndef CONFIG_DISABLE_POLL +static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int stm32_bbsram_unlink(FAR struct inode *inode); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_BBSRAM_DEBUG) +static uint8_t debug[STM32_BBSRAM_SIZE]; +#endif + +static const struct file_operations stm32_bbsram_fops = +{ + .open = stm32_bbsram_open, + .close = stm32_bbsram_close, + .read = stm32_bbsram_read, + .write = stm32_bbsram_write, + .seek = stm32_bbsram_seek, + .ioctl = stm32_bbsram_ioctl, +#ifndef CONFIG_DISABLE_POLL + .poll = stm32_bbsram_poll, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + .unlink = stm32_bbsram_unlink, +#endif +}; + +static struct stm32_bbsram_s g_bbsram[CONFIG_STM32_BBSRAM_FILES]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_bbsram_rd + ****************************************************************************/ + +#if defined(CONFIG_BBSRAM_DEBUG) +static void stm32_bbsram_rd(void) +{ + memcpy(&debug, (uint8_t *)STM32_BKPSRAM_BASE, sizeof debug); +} +#endif + +/**************************************************************************** + * Name: stm32_bbsram_rd + ****************************************************************************/ + +#if defined(CONFIG_BBSRAM_DEBUG) +static void stm32_bbsram_dump(FAR struct bbsramfh_s *bbf, char *op) +{ + BBSRAM_DEBUG_READ(); + lldbg("%s:\n", op); + lldbg(" File Address:0x%8x\n", bbf); + lldbg(" crc:0x%8x\n", bbf->crc); + lldbg(" fileno:%d\n", (int) bbf->fileno); + lldbg(" dirty:%d\n", (int) bbf->dirty); + lldbg(" length:%d\n", (int) bbf->len); + lldbg(" time:%ld:%ld\n", bbf->lastwrite.tv_sec, bbf->lastwrite.tv_nsec); + lldbg(" data: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n", + bbf->data[0], bbf->data[1], bbf->data[2], bbf->data[3], bbf->data[4]); +} +#endif + +/************************************************************************************ + * Name: stm32_bbsram_semgive + ************************************************************************************/ + +static void stm32_bbsram_semgive(FAR struct stm32_bbsram_s *priv) +{ + sem_post(&priv->exclsem); +} + +/************************************************************************************ + * Name: stm32_bbsram_semtake + * + * Description: + * Take a semaphore handling any exceptional conditions + * + * Input Parameters: + * priv - A reference to the CAN peripheral state + * + * Returned Value: + * None + * +****************************************************************************/ + +static void stm32_bbsram_semtake(FAR struct stm32_bbsram_s *priv) +{ + int ret; + + /* Wait until we successfully get the semaphore. EINTR is the only + * expected 'failure' (meaning that the wait for the semaphore was + * interrupted by a signal. + */ + + do + { + ret = sem_wait(&priv->exclsem); + DEBUGASSERT(ret == 0 || errno == EINTR); + } + while (ret < 0); +} + +/**************************************************************************** + * Name: stm32_bbsram_ulock + * + * Description: + * Unprotects RTC registers, RTC backup data registers and backup SRAM + * against parasitic write access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_bbsram_unlock(void) +{ + (void)stm32_pwr_enablebkp(true); +} + +/**************************************************************************** + * Name: stm32_bbsram_lock + * + * Description: + * Protects RTC registers, RTC backup data registers and backup SRAM + * against parasitic write access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_bbsram_lock(void) +{ + (void)stm32_pwr_enablebkp(false); +} + +/**************************************************************************** + * Name: stm32_bbsram_crc + * + * Description: + * Calculates the CRC of the block + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static uint32_t stm32_bbsram_crc(FAR struct bbsramfh_s *pf) +{ + return crc32((uint8_t *)pf + BBSRAM_CRCED_OFFSET, BBSRAM_CRCED_SIZE(pf->len)); +} + +/**************************************************************************** + * Name: stm32_bbsram_open + * + * Description: Open the device + * + ****************************************************************************/ + +static int stm32_bbsram_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + /* Increment the reference count */ + + stm32_bbsram_semtake(bbr); + if (bbr->refs == MAX_OPENCNT) + { + return -EMFILE; + } + else + { + bbr->refs++; + } + + stm32_bbsram_semgive(bbr); + return OK; +} + +/**************************************************************************** + * Name: stm32_bbsram_internal_close + * + * Description: + * Close BBSRAM entry; Recalculate the time and crc + * + ****************************************************************************/ + +static int stm32_bbsram_internal_close(FAR struct bbsramfh_s *bbf) +{ + bbf->dirty = 0; + (void)clock_gettime(CLOCK_REALTIME, &bbf->lastwrite); + bbf->crc = stm32_bbsram_crc(bbf); + + BBSRAM_DUMP(bbf, "close done"); + return bbf->len; +} + +/**************************************************************************** + * Name: stm32_bbsram_close + * + * Description: close the device + * + ****************************************************************************/ + +static int stm32_bbsram_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + int ret = OK; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + stm32_bbsram_semtake(bbr); + + BBSRAM_DUMP(bbr->bbf, "close"); + + if (bbr->refs == 0) + { + ret = -EIO; + } + else + { + bbr->refs--; + + if (bbr->refs == 0) + { + if (bbr->bbf->dirty) + { + /* Recalculate the time and crc */ + + stm32_bbsram_unlock(); + stm32_bbsram_internal_close(bbr->bbf); + stm32_bbsram_lock(); + } + } + } + + stm32_bbsram_semgive(bbr); + return ret; +} + +/**************************************************************************** + * Name: stm32_bbsram_seek + ****************************************************************************/ + +static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset, + int whence) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + off_t newpos; + int ret; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + stm32_bbsram_semtake(bbr); + + /* Determine the new, requested file position */ + + switch (whence) + { + case SEEK_CUR: + newpos = filep->f_pos + offset; + break; + + case SEEK_SET: + newpos = offset; + break; + + case SEEK_END: + newpos = bbr->bbf->len + offset; + break; + + default: + /* Return EINVAL if the whence argument is invalid */ + + stm32_bbsram_semgive(bbr); + return -EINVAL; + } + + /* Opengroup.org: + * + * "The lseek() function shall allow the file offset to be set beyond the end + * of the existing data in the file. If data is later written at this point, + * subsequent reads of data in the gap shall return bytes with the value 0 + * until data is actually written into the gap." + * + * We can conform to the first part, but not the second. But return EINVAL if + * + * "...the resulting file offset would be negative for a regular file, block + * special file, or directory." + */ + + if (newpos >= 0) + { + filep->f_pos = newpos; + ret = newpos; + } + else + { + ret = -EINVAL; + } + + stm32_bbsram_semgive(bbr); + return ret; +} + +/**************************************************************************** + * Name: stm32_bbsram_read + ****************************************************************************/ + +static ssize_t stm32_bbsram_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + stm32_bbsram_semtake(bbr); + + /* Trim len if read would go beyond end of device */ + + if ((filep->f_pos + len) > bbr->bbf->len) + { + len = bbr->bbf->len - filep->f_pos; + } + + memcpy(buffer, &bbr->bbf->data[filep->f_pos], len); + filep->f_pos += len; + stm32_bbsram_semgive(bbr); + return len; +} + +/**************************************************************************** + * Name: stm32_bbsram_internal_write + ****************************************************************************/ + +static ssize_t stm32_bbsram_internal_write(FAR struct bbsramfh_s *bbf, + FAR const char *buffer, + off_t offset, size_t len) +{ + bbf->dirty = 1; + memcpy(&bbf->data[offset], buffer, len); + return len; +} + +/**************************************************************************** + * Name: stm32_bbsram_write + ****************************************************************************/ + +static ssize_t stm32_bbsram_write(FAR struct file *filep, FAR const char *buffer, + size_t len) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + int ret = -EFBIG; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + /* Forbid writes past the end of the device */ + + if (filep->f_pos < bbr->bbf->len) + { + /* Clamp len to avoid crossing the end of the memory */ + + if ((filep->f_pos + len) > bbr->bbf->len) + { + len = bbr->bbf->len - filep->f_pos; + } + + ret = len; /* save number of bytes written */ + + stm32_bbsram_semtake(bbr); + BBSRAM_DUMP(bbr->bbf, "write"); + stm32_bbsram_unlock(); + stm32_bbsram_internal_write(bbr->bbf, buffer, filep->f_pos, len); + stm32_bbsram_lock(); + filep->f_pos += len; + BBSRAM_DUMP(bbr->bbf, "write done"); + stm32_bbsram_semgive(bbr); + } + + BBSRAM_DEBUG_READ(); + return ret; +} + +/**************************************************************************** + * Name: stm32_bbsram_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + if (setup) + { + fds->revents |= (fds->events & (POLLIN | POLLOUT)); + if (fds->revents != 0) + { + sem_post(fds->sem); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_bbsram_ioctl + * + * Description: Return device geometry + * + ****************************************************************************/ + +static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct stm32_bbsram_s *bbr; + int ret = -ENOTTY; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + if (cmd == STM32_BBSRAM_GETDESC_IOCTL) + { + FAR struct bbsramd_s *bbrr = (FAR struct bbsramd_s *)((uintptr_t)arg); + + stm32_bbsram_semtake(bbr); + if (!bbrr) + { + ret = -EINVAL; + } + else + { + bbrr->fileno = bbr->bbf->fileno; + bbrr->lastwrite = bbr->bbf->lastwrite; + bbrr->len = bbr->bbf->len; + bbrr->flags = (bbr->bbf->crc == stm32_bbsram_crc(bbr->bbf)) ? eCRCValid : 0; + bbrr->flags = (bbr->bbf->dirty) ? eDirty : 0; + ret = OK; + } + + stm32_bbsram_semgive(bbr); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_bbsram_unlink + * + * Description: + * This function will remove the remove the file from the file system + * it will zero the contents and time stamp. It will leave the fileno + * and pointer to the BBSRAM intact. + * It should be called called on the the file used for the crash dump + * to remove it from visibility in the file system after it is created or + * read thus arming it. + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int stm32_bbsram_unlink(FAR struct inode *inode) +{ + FAR struct stm32_bbsram_s *bbr; + + DEBUGASSERT(inode && inode->i_private); + bbr = (FAR struct stm32_bbsram_s *)inode->i_private; + + stm32_bbsram_semtake(bbr); + stm32_bbsram_unlock(); + memset(bbr->bbf->data, 0, bbr->bbf->len); + bbr->bbf->lastwrite.tv_nsec = 0; + bbr->bbf->lastwrite.tv_sec = 0; + bbr->bbf->crc = stm32_bbsram_crc(bbr->bbf); + stm32_bbsram_lock(); + bbr->refs = 0; + stm32_bbsram_semgive(bbr); + sem_destroy(&bbr->exclsem); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_bbsram_probe + * + * Description: Based on the number of files defined and their sizes + * Initializes the base pointers to the file entries. + * + ****************************************************************************/ + +static int stm32_bbsram_probe(int *ent, struct stm32_bbsram_s pdev[]) +{ + int i; + int avail = STM32_BBSRAM_SIZE; + int alloc; + int size; + int ret = -EFBIG; + struct bbsramfh_s *pf = (struct bbsramfh_s *) STM32_BKPSRAM_BASE; + + for (i = 0; (i < CONFIG_STM32_BBSRAM_FILES) && ent[i] && (avail > 0); i++) + { + /* Validate the actual allocations against what is in the BBSRAM */ + + size = ent[i]; + + /* Use all that is left */ + + if (size == -1) + { + size = avail - (BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT_MASK); + } + + /* Add in header size and keep aligned */ + + alloc = size + BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT_MASK; + alloc &= ~(BBSRAM_ALIGNMENT_MASK); + + /* Does it fit? */ + + if (alloc <= avail) + { + ret = i + 1; + BBSRAM_DUMP(pf, "probe"); + + if (pf->len != size || + pf->fileno != i || + pf->crc != stm32_bbsram_crc(pf)) + { + + /* Not Valid so wipe the file in BBSRAM */ + + memset((uint8_t *)pf, 0, alloc); + pf->fileno = i; + pf->len = size; + pf->crc = stm32_bbsram_crc(pf); + BBSRAM_DUMP(pf, "probe reset"); + } + + pdev[i].bbf = pf; + pf = (struct bbsramfh_s *)((uint8_t *)pf + alloc); + sem_init(&g_bbsram[i].exclsem, 0, 1); + } + + avail -= alloc; + } + + BBSRAM_DEBUG_READ(); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_bbsraminitialize + * + * Description: + * Initialize the Battery Backed up SRAM driver. + * + * Parameters: + * devpath - the path to instantiate the files. + * sizes - Pointer to a any array of file sizes to create + * the last entry should be 0 + * A size of -1 will use all the remaining spaces + * + * If the length of sizes is greater then CONFIG_STM32_BBSRAM_FILES + * CONFIG_STM32_BBSRAM_FILES will be returned. + * + * Returned Value: + * Number of files created on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int stm32_bbsraminitialize(char *devpath, int *sizes) +{ + int i; + int fcnt; + char path[32]; + char devname[32]; + + int ret = OK; + + if (devpath == NULL) + { + return -EINVAL; + } + + i = strlen(devpath); + if (i == 0 || i > sizeof(path) + 3) + { + return -EINVAL; + } + + memset(g_bbsram, 0, sizeof(g_bbsram)); + + /* Clocking for the PWR block must be provided. However, this is done + * unconditionally in stm32f40xxx_rcc.c on power up. This done + * unconditionally because the PWR block is also needed to set the + * internal voltage regulator for maximum performance. + */ + + /* Enable backup SRAM clock is done in rcc_enableahb1() when + * CONFIG_STM32_BKPSRAM is defined. + */ + + /* Allow Access */ + + stm32_bbsram_unlock(); + + /* Enable backup regulator so that the data is retained in Standby and + * VBAT modes + */ + + stm32_pwr_enablebreg(true); + + fcnt = stm32_bbsram_probe(sizes, g_bbsram); + + strncpy(path, devpath, sizeof(path)); + strcat(path, "%d"); + + for (i = 0; i < fcnt && ret >= OK; i++) + { + snprintf(devname, sizeof(devname), path, i); + ret = register_driver(devname, &stm32_bbsram_fops, 0666, &g_bbsram[i]); + } + + /* Disallow Access */ + + stm32_bbsram_lock(); + return ret < OK ? ret : fcnt; +} + +/**************************************************************************** + * Function: stm32_bbsram_savepanic + * + * Description: + * Saves the panic context in a previously allocated BBSRAM file + * + * Parameters: + * fileno - the value returned by the ioctl STM32_BBSRAM_GETDESC_IOCTL + * context - Pointer to a any array of bytes to save + * length - The length of the data pointed to byt context + * + * Returned Value: + * Length saved or negated errno. + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_SAVE_CRASHDUMP) +int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length) +{ + FAR struct bbsramfh_s *bbf; + int fill; + int ret = -ENOSPC; + + /* On a bad day we could panic while panicking, (and we debug assert) + * this is a potential feeble attempt at only writing the first + * panic's context to the file + */ + + static bool once = false; + + if (!once) + { + once = true; + + DEBUGASSERT(fileno > 0 && fileno < CONFIG_STM32_BBSRAM_FILES); + + bbf = g_bbsram[fileno].bbf; + + DEBUGASSERT(bbf); + + /* If the g_bbsram has been nulled out we return ENXIO. + * + * As once ensures we will keep the first dump. Checking the time for + * 0 protects from over writing a previous crash dump that has not + * been saved to long term storage and erased. The dreaded reboot + * loop. + */ + + if (!bbf) + { + ret = -ENXIO; + } + else if ((bbf->lastwrite.tv_sec == 0 && bbf->lastwrite.tv_nsec == 0)) + { + /* Clamp length if too big */ + + if (length > bbf->len) + { + length = bbf->len; + } + + stm32_bbsram_unlock(); + + stm32_bbsram_internal_write(bbf, (char *) context, 0, length); + + /* Fill with 0 if data is less then file size */ + + fill = (int) bbf->len - length; + + if (fill > 0) + { + memset(&bbf->data[length], 0, fill); + } + + /* Seal the file */ + + stm32_bbsram_internal_close(bbf); + + stm32_bbsram_lock(); + ret = length; + } + } + + return ret; +} +#endif + +#endif /* CONFIG_BBSRAM_DRIVER */ diff --git a/arch/arm/src/stm32/stm32_bbsram.h b/arch/arm/src/stm32/stm32_bbsram.h new file mode 100644 index 0000000000000000000000000000000000000000..69d0046f5cfba0136aed5c1030790ba054aa380a --- /dev/null +++ b/arch/arm/src/stm32/stm32_bbsram.h @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_bbsram.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H +#define __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H + +/**************************************************************************** + * The purpose of this driver is to add battery backup file to the file + * system. There can be CONFIG_STM32_BBRSRAM_COUNT files defined. + * These files are of fixed size up to the maximum of the backing SRAM. + * In the care of the STM32F2 and STM32F4 this is a maximum of 4K Bytes. + * + * If CONFIG_SAVE_CRASHDUMP is defined The driver also supports a feature + * to save the context of a PANIC in one of these files. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_BBSRAM_SIZE 4096 +#else +# error No backup SRAM on this STM32 +#endif + +#if !defined(CONFIG_STM32_BBSRAM_FILES) +# define CONFIG_STM32_BBSRAM_FILES 4 +#endif + +/* REVISIT: What guarantees that STM32_BBSRAM_GETDESC_IOCTL has a unique + * value among all over _DIOC() values? + */ + +#define STM32_BBSRAM_GETDESC_IOCTL _DIOC(0x0010) /* Returns a bbsramd_s */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +enum bbsramdf_e +{ + eCRCValid = 1, /* The crc is valid */ + eDirty = 2, /* The file was closed */ + +}; + +struct bbsramd_s +{ + uint8_t flags; /* The crc is valid and the file was closed */ + uint8_t fileno; /* The minor number */ + uint16_t len; /* Total Bytes in this file*/ + struct timespec lastwrite; /* Last write time */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Function: stm32_bbsraminitialize + * + * Description: + * Initialize the Battery Backed up SRAM driver. + * + * Parameters: + * devpath - the path to instantiate the files. + * sizes - Pointer to a any array of file sizes to create + * the last entry should be 0 + * A size of -1 will use all the remaining spaces + * + * If the length of sizes is greater then CONFIG_STM32_BBSRAM_FILES + * CONFIG_STM32_BBSRAM_FILES will be returned. + * + * Returned Value: + * Number of files created on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int stm32_bbsraminitialize(char *devpath, int *sizes); + +/**************************************************************************** +* Function: stm32_bbsram_savepanic +* +* Description: +* Saves the panic context in a previously allocated BBSRAM file +* +* Parameters: +* fileno - the value returned by the ioctl STM32_BBSRAM_GETDESC_IOCTL +* context - Pointer to a any array of bytes to save +* length - The length of the data pointed to byt context +* +* Returned Value: +* Length saved or negated errno. +* +* Assumptions: +* +****************************************************************************/ + +#if defined(CONFIG_STM32_SAVE_CRASHDUMP) +int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H */ diff --git a/arch/arm/src/stm32/stm32_bkp.h b/arch/arm/src/stm32/stm32_bkp.h new file mode 100644 index 0000000000000000000000000000000000000000..21399c38bd291a99ca6e744ccef03f51d8f161d7 --- /dev/null +++ b/arch/arm/src/stm32/stm32_bkp.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_bkp.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_BKP_H +#define __ARCH_ARM_SRC_STM32_STM32_BKP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_bkp.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_BKP_H */ diff --git a/arch/arm/src/stm32/stm32_can.c b/arch/arm/src/stm32/stm32_can.c new file mode 100644 index 0000000000000000000000000000000000000000..8628b2fa79bdaa2c07cdf9df7c190c599bdfe396 --- /dev/null +++ b/arch/arm/src/stm32/stm32_can.c @@ -0,0 +1,1665 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_can.c + * + * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + + +#include "chip.h" +#include "stm32.h" +#include "stm32_can.h" + +#if defined(CONFIG_CAN) && (defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Delays *******************************************************************/ +/* Time out for INAK bit */ + +#define INAK_TIMEOUT 65535 + +/* Mailboxes ****************************************************************/ + +#define CAN_ALL_MAILBOXES (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2) + +/* Bit timing ***************************************************************/ + +#define CAN_BIT_QUANTA (CONFIG_CAN_TSEG1 + CONFIG_CAN_TSEG2 + 1) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing CAN */ + +#ifdef CONFIG_DEBUG_CAN +# define candbg dbg +# define canvdbg vdbg +# define canlldbg lldbg +# define canllvdbg llvdbg +#else +# define candbg(x...) +# define canvdbg(x...) +# define canlldbg(x...) +# define canllvdbg(x...) +#endif + +#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_CAN) +# undef CONFIG_CAN_REGDEBUG +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32_can_s +{ + uint8_t port; /* CAN port number (1 or 2) */ + uint8_t canrx0; /* CAN RX FIFO 0 IRQ number */ + uint8_t cantx; /* CAN TX IRQ number */ + uint8_t filter; /* Filter number */ + uint32_t base; /* Base address of the CAN control registers */ + uint32_t fbase; /* Base address of the CAN filter registers */ + uint32_t baud; /* Configured baud */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* CAN Register access */ + +static uint32_t can_getreg(struct stm32_can_s *priv, int offset); +static uint32_t can_getfreg(struct stm32_can_s *priv, int offset); +static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value); +static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value); +#ifdef CONFIG_CAN_REGDEBUG +static void can_dumpctrlregs(struct stm32_can_s *priv, FAR const char *msg); +static void can_dumpmbregs(struct stm32_can_s *priv, FAR const char *msg); +static void can_dumpfiltregs(struct stm32_can_s *priv, FAR const char *msg); +#else +# define can_dumpctrlregs(priv,msg) +# define can_dumpmbregs(priv,msg) +# define can_dumpfiltregs(priv,msg) +#endif + +/* CAN driver methods */ + +static void can_reset(FAR struct can_dev_s *dev); +static int can_setup(FAR struct can_dev_s *dev); +static void can_shutdown(FAR struct can_dev_s *dev); +static void can_rxint(FAR struct can_dev_s *dev, bool enable); +static void can_txint(FAR struct can_dev_s *dev, bool enable); +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg); +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id); +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg); +static bool can_txready(FAR struct can_dev_s *dev); +static bool can_txempty(FAR struct can_dev_s *dev); + +/* CAN interrupt handling */ + +static int can_rx0interrupt(int irq, void *context); +static int can_txinterrupt(int irq, void *context); + +/* Initialization */ + +static int can_bittiming(struct stm32_can_s *priv); +static int can_cellinit(struct stm32_can_s *priv); +static int can_filterinit(struct stm32_can_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct can_ops_s g_canops = +{ + .co_reset = can_reset, + .co_setup = can_setup, + .co_shutdown = can_shutdown, + .co_rxint = can_rxint, + .co_txint = can_txint, + .co_ioctl = can_ioctl, + .co_remoterequest = can_remoterequest, + .co_send = can_send, + .co_txready = can_txready, + .co_txempty = can_txempty, +}; + +#ifdef CONFIG_STM32_CAN1 +static struct stm32_can_s g_can1priv = +{ + .port = 1, + .canrx0 = STM32_IRQ_CAN1RX0, + .cantx = STM32_IRQ_CAN1TX, + .filter = 0, + .base = STM32_CAN1_BASE, + .fbase = STM32_CAN1_BASE, + .baud = CONFIG_CAN1_BAUD, +}; + +static struct can_dev_s g_can1dev = +{ + .cd_ops = &g_canops, + .cd_priv = &g_can1priv, +}; +#endif + +#ifdef CONFIG_STM32_CAN2 +static struct stm32_can_s g_can2priv = +{ + .port = 2, + .canrx0 = STM32_IRQ_CAN2RX0, + .cantx = STM32_IRQ_CAN2TX, + .filter = CAN_NFILTERS / 2, + .base = STM32_CAN2_BASE, + .fbase = STM32_CAN1_BASE, + .baud = CONFIG_CAN2_BAUD, +}; + +static struct can_dev_s g_can2dev = +{ + .cd_ops = &g_canops, + .cd_priv = &g_can2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: can_getreg + * Name: can_getfreg + * + * Description: + * Read the value of a CAN register or filter block register. + * + * Input Parameters: + * priv - A reference to the CAN block status + * offset - The offset to the register to read + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static uint32_t can_vgetreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} + +static uint32_t can_getreg(struct stm32_can_s *priv, int offset) +{ + return can_vgetreg(priv->base + offset); +} + +static uint32_t can_getfreg(struct stm32_can_s *priv, int offset) +{ + return can_vgetreg(priv->fbase + offset); +} + +#else +static uint32_t can_getreg(struct stm32_can_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +static uint32_t can_getfreg(struct stm32_can_s *priv, int offset) +{ + return getreg32(priv->fbase + offset); +} + +#endif + +/**************************************************************************** + * Name: can_putreg + * Name: can_putfreg + * + * Description: + * Set the value of a CAN register or filter block register. + * + * Input Parameters: + * priv - A reference to the CAN block status + * offset - The offset to the register to write + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_vputreg(uint32_t addr, uint32_t value) +{ + + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, value); + + /* Write the value */ + + putreg32(value, addr); +} + +static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value) +{ + can_vputreg(priv->base + offset, value); +} + +static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value) +{ + can_vputreg(priv->fbase + offset, value); +} + +#else +static void can_putreg(struct stm32_can_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +static void can_putfreg(struct stm32_can_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->fbase + offset); +} +#endif + +/**************************************************************************** + * Name: can_dumpctrlregs + * + * Description: + * Dump the contents of all CAN control registers + * + * Input Parameters: + * priv - A reference to the CAN block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_dumpctrlregs(struct stm32_can_s *priv, FAR const char *msg) +{ + if (msg) + { + canlldbg("Control Registers: %s\n", msg); + } + else + { + canlldbg("Control Registers:\n"); + } + + /* CAN control and status registers */ + + lldbg(" MCR: %08x MSR: %08x TSR: %08x\n", + getreg32(priv->base + STM32_CAN_MCR_OFFSET), + getreg32(priv->base + STM32_CAN_MSR_OFFSET), + getreg32(priv->base + STM32_CAN_TSR_OFFSET)); + + lldbg(" RF0R: %08x RF1R: %08x\n", + getreg32(priv->base + STM32_CAN_RF0R_OFFSET), + getreg32(priv->base + STM32_CAN_RF1R_OFFSET)); + + lldbg(" IER: %08x ESR: %08x BTR: %08x\n", + getreg32(priv->base + STM32_CAN_IER_OFFSET), + getreg32(priv->base + STM32_CAN_ESR_OFFSET), + getreg32(priv->base + STM32_CAN_BTR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: can_dumpmbregs + * + * Description: + * Dump the contents of all CAN mailbox registers + * + * Input Parameters: + * priv - A reference to the CAN block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_dumpmbregs(struct stm32_can_s *priv, FAR const char *msg) +{ + if (msg) + { + canlldbg("Mailbox Registers: %s\n", msg); + } + else + { + canlldbg("Mailbox Registers:\n"); + } + + /* CAN mailbox registers (3 TX and 2 RX) */ + + lldbg(" TI0R: %08x TDT0R: %08x TDL0R: %08x TDH0R: %08x\n", + getreg32(priv->base + STM32_CAN_TI0R_OFFSET), + getreg32(priv->base + STM32_CAN_TDT0R_OFFSET), + getreg32(priv->base + STM32_CAN_TDL0R_OFFSET), + getreg32(priv->base + STM32_CAN_TDH0R_OFFSET)); + + lldbg(" TI1R: %08x TDT1R: %08x TDL1R: %08x TDH1R: %08x\n", + getreg32(priv->base + STM32_CAN_TI1R_OFFSET), + getreg32(priv->base + STM32_CAN_TDT1R_OFFSET), + getreg32(priv->base + STM32_CAN_TDL1R_OFFSET), + getreg32(priv->base + STM32_CAN_TDH1R_OFFSET)); + + lldbg(" TI2R: %08x TDT2R: %08x TDL2R: %08x TDH2R: %08x\n", + getreg32(priv->base + STM32_CAN_TI2R_OFFSET), + getreg32(priv->base + STM32_CAN_TDT2R_OFFSET), + getreg32(priv->base + STM32_CAN_TDL2R_OFFSET), + getreg32(priv->base + STM32_CAN_TDH2R_OFFSET)); + + lldbg(" RI0R: %08x RDT0R: %08x RDL0R: %08x RDH0R: %08x\n", + getreg32(priv->base + STM32_CAN_RI0R_OFFSET), + getreg32(priv->base + STM32_CAN_RDT0R_OFFSET), + getreg32(priv->base + STM32_CAN_RDL0R_OFFSET), + getreg32(priv->base + STM32_CAN_RDH0R_OFFSET)); + + lldbg(" RI1R: %08x RDT1R: %08x RDL1R: %08x RDH1R: %08x\n", + getreg32(priv->base + STM32_CAN_RI1R_OFFSET), + getreg32(priv->base + STM32_CAN_RDT1R_OFFSET), + getreg32(priv->base + STM32_CAN_RDL1R_OFFSET), + getreg32(priv->base + STM32_CAN_RDH1R_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: can_dumpfiltregs + * + * Description: + * Dump the contents of all CAN filter registers + * + * Input Parameters: + * priv - A reference to the CAN block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_REGDEBUG +static void can_dumpfiltregs(struct stm32_can_s *priv, FAR const char *msg) +{ + int i; + + if (msg) + { + canlldbg("Filter Registers: %s\n", msg); + } + else + { + canlldbg("Filter Registers:\n"); + } + + lldbg(" FMR: %08x FM1R: %08x FS1R: %08x FFA1R: %08x FA1R: %08x\n", + getreg32(priv->base + STM32_CAN_FMR_OFFSET), + getreg32(priv->base + STM32_CAN_FM1R_OFFSET), + getreg32(priv->base + STM32_CAN_FS1R_OFFSET), + getreg32(priv->base + STM32_CAN_FFA1R_OFFSET), + getreg32(priv->base + STM32_CAN_FA1R_OFFSET)); + + for (i = 0; i < CAN_NFILTERS; i++) + { + lldbg(" F%dR1: %08x F%dR2: %08x\n", + i, getreg32(priv->base + STM32_CAN_FIR_OFFSET(i, 1)), + i, getreg32(priv->base + STM32_CAN_FIR_OFFSET(i, 2))); + } +} +#endif + +/**************************************************************************** + * Name: can_reset + * + * Description: + * Reset the CAN device. Called early to initialize the hardware. This + * function is called, before can_setup() and on error conditions. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_reset(FAR struct can_dev_s *dev) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + uint32_t regval; + uint32_t regbit = 0; + irqstate_t flags; + + canllvdbg("CAN%d\n", priv->port); + + /* Get the bits in the AHB1RSTR register needed to reset this CAN device */ + +#ifdef CONFIG_STM32_CAN1 + if (priv->port == 1) + { + regbit = RCC_APB1RSTR_CAN1RST; + } + else +#endif +#ifdef CONFIG_STM32_CAN2 + if (priv->port == 2) + { + regbit = RCC_APB1RSTR_CAN2RST; + } + else +#endif + { + canlldbg("Unsupported port %d\n", priv->port); + return; + } + + /* Disable interrupts momentary to stop any ongoing CAN event processing and + * to prevent any concurrent access to the AHB1RSTR register. + */ + + flags = enter_critical_section(); + + /* Reset the CAN */ + + regval = getreg32(STM32_RCC_APB1RSTR); + regval |= regbit; + putreg32(regval, STM32_RCC_APB1RSTR); + + regval &= ~regbit; + putreg32(regval, STM32_RCC_APB1RSTR); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: can_setup + * + * Description: + * Configure the CAN. This method is called the first time that the CAN + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching CAN interrupts. + * All CAN interrupts are disabled upon return. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_setup(FAR struct can_dev_s *dev) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + int ret; + + canllvdbg("CAN%d RX0 irq: %d TX irq: %d\n", priv->port, priv->canrx0, priv->cantx); + + /* CAN cell initialization */ + + ret = can_cellinit(priv); + if (ret < 0) + { + canlldbg("CAN%d cell initialization failed: %d\n", priv->port, ret); + return ret; + } + + can_dumpctrlregs(priv, "After cell initialization"); + can_dumpmbregs(priv, NULL); + + /* CAN filter initialization */ + + ret = can_filterinit(priv); + if (ret < 0) + { + canlldbg("CAN%d filter initialization failed: %d\n", priv->port, ret); + return ret; + } + can_dumpfiltregs(priv, "After filter initialization"); + + /* Attach the CAN RX FIFO 0 interrupt and TX interrupts. The others are not used */ + + ret = irq_attach(priv->canrx0, can_rx0interrupt); + if (ret < 0) + { + canlldbg("Failed to attach CAN%d RX0 IRQ (%d)", priv->port, priv->canrx0); + return ret; + } + + ret = irq_attach(priv->cantx, can_txinterrupt); + if (ret < 0) + { + canlldbg("Failed to attach CAN%d TX IRQ (%d)", priv->port, priv->cantx); + return ret; + } + + /* Enable the interrupts at the NVIC. Interrupts arestill disabled in + * the CAN module. Since we coming out of reset here, there should be + * no pending interrupts. + */ + + up_enable_irq(priv->canrx0); + up_enable_irq(priv->cantx); + return OK; +} + +/**************************************************************************** + * Name: can_shutdown + * + * Description: + * Disable the CAN. This method is called when the CAN device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_shutdown(FAR struct can_dev_s *dev) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + + canllvdbg("CAN%d\n", priv->port); + + /* Disable the RX FIFO 0 and TX interrupts */ + + up_disable_irq(priv->canrx0); + up_disable_irq(priv->cantx); + + /* Detach the RX FIFO 0 and TX interrupts */ + + irq_detach(priv->canrx0); + irq_detach(priv->cantx); + + /* And reset the hardware */ + + can_reset(dev); +} + +/**************************************************************************** + * Name: can_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_rxint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + uint32_t regval; + + canllvdbg("CAN%d enable: %d\n", priv->port, enable); + + /* Enable/disable the FIFO 0 message pending interrupt */ + + regval = can_getreg(priv, STM32_CAN_IER_OFFSET); + if (enable) + { + regval |= CAN_IER_FMPIE0; + } + else + { + regval &= ~CAN_IER_FMPIE0; + } + can_putreg(priv, STM32_CAN_IER_OFFSET, regval); +} + +/**************************************************************************** + * Name: can_txint + * + * Description: + * Call to enable or disable TX interrupts. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void can_txint(FAR struct can_dev_s *dev, bool enable) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + uint32_t regval; + + canllvdbg("CAN%d enable: %d\n", priv->port, enable); + + /* Support only disabling the transmit mailbox interrupt */ + + if (!enable) + { + regval = can_getreg(priv, STM32_CAN_IER_OFFSET); + regval &= ~CAN_IER_TMEIE; + can_putreg(priv, STM32_CAN_IER_OFFSET, regval); + } +} + +/**************************************************************************** + * Name: can_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) +{ + /* No CAN ioctls are supported */ + + return -ENOTTY; +} + +/**************************************************************************** + * Name: can_remoterequest + * + * Description: + * Send a remote request + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id) +{ +#warning "Remote request not implemented" + return -ENOSYS; +} + +/**************************************************************************** + * Name: can_send + * + * Description: + * Send one can message. + * + * One CAN-message consists of a maximum of 10 bytes. A message is + * composed of at least the first 2 bytes (when there are no data bytes). + * + * Byte 0: Bits 0-7: Bits 3-10 of the 11-bit CAN identifier + * Byte 1: Bits 5-7: Bits 0-2 of the 11-bit CAN identifier + * Bit 4: Remote Tranmission Request (RTR) + * Bits 0-3: Data Length Code (DLC) + * Bytes 2-10: CAN data + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + FAR uint8_t *ptr; + uint32_t regval; + uint32_t tmp; + int dlc; + int txmb; + + canllvdbg("CAN%d ID: %d DLC: %d\n", priv->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc); + + /* Select one empty transmit mailbox */ + + regval = can_getreg(priv, STM32_CAN_TSR_OFFSET); + if ((regval & CAN_TSR_TME0) != 0 && (regval & CAN_TSR_RQCP0) == 0) + { + txmb = 0; + } + else if ((regval & CAN_TSR_TME1) != 0 && (regval & CAN_TSR_RQCP1) == 0) + { + txmb = 1; + } + else if ((regval & CAN_TSR_TME2) != 0 && (regval & CAN_TSR_RQCP2) == 0) + { + txmb = 2; + } + else + { + canlldbg("ERROR: No available mailbox\n"); + return -EBUSY; + } + + /* Clear TXRQ, RTR, IDE, EXID, and STID fields */ + + regval = can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb)); + regval &= ~(CAN_TIR_TXRQ | CAN_TIR_RTR | CAN_TIR_IDE | CAN_TIR_EXID_MASK | CAN_TIR_STID_MASK); + can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval); + + /* Set up the ID, standard 11-bit or extended 29-bit. */ + +#ifdef CONFIG_CAN_EXTID + regval &= ~CAN_TIR_EXID_MASK; + if (msg->cm_hdr.ch_extid) + { + DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 29)); + regval |= (msg->cm_hdr.ch_id << CAN_TIR_EXID_SHIFT) | CAN_TIR_IDE; + } + else + { + DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 11)); + regval |= msg->cm_hdr.ch_id << CAN_TIR_STID_SHIFT; + } +#else + regval &= ~CAN_TIR_STID_MASK; + regval |= (uint32_t)msg->cm_hdr.ch_id << CAN_TIR_STID_SHIFT; +#endif + can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval); + + /* Set up the DLC */ + + dlc = msg->cm_hdr.ch_dlc; + regval = can_getreg(priv, STM32_CAN_TDTR_OFFSET(txmb)); + regval &= ~(CAN_TDTR_DLC_MASK | CAN_TDTR_TGT); + regval |= (uint32_t)dlc << CAN_TDTR_DLC_SHIFT; + can_putreg(priv, STM32_CAN_TDTR_OFFSET(txmb), regval); + + /* Set up the data fields */ + + ptr = msg->cm_data; + regval = 0; + + if (dlc > 0) + { + tmp = (uint32_t)*ptr++; + regval = tmp << CAN_TDLR_DATA0_SHIFT; + + if (dlc > 1) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDLR_DATA1_SHIFT; + + if (dlc > 2) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDLR_DATA2_SHIFT; + + if (dlc > 3) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDLR_DATA3_SHIFT; + } + } + } + } + can_putreg(priv, STM32_CAN_TDLR_OFFSET(txmb), regval); + + regval = 0; + if (dlc > 4) + { + tmp = (uint32_t)*ptr++; + regval = tmp << CAN_TDHR_DATA4_SHIFT; + + if (dlc > 5) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDHR_DATA5_SHIFT; + + if (dlc > 6) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDHR_DATA6_SHIFT; + + if (dlc > 7) + { + tmp = (uint32_t)*ptr++; + regval |= tmp << CAN_TDHR_DATA7_SHIFT; + } + } + } + } + can_putreg(priv, STM32_CAN_TDHR_OFFSET(txmb), regval); + + /* Enable the transmit mailbox empty interrupt (may already be enabled) */ + + regval = can_getreg(priv, STM32_CAN_IER_OFFSET); + regval |= CAN_IER_TMEIE; + can_putreg(priv, STM32_CAN_IER_OFFSET, regval); + + /* Request transmission */ + + regval = can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb)); + regval |= CAN_TIR_TXRQ; /* Transmit Mailbox Request */ + can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval); + + can_dumpmbregs(priv, "After send"); + return OK; +} + +/**************************************************************************** + * Name: can_txready + * + * Description: + * Return true if the CAN hardware can accept another TX message. + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if the CAN hardware is ready to accept another TX message. + * + ****************************************************************************/ + +static bool can_txready(FAR struct can_dev_s *dev) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + uint32_t regval; + + /* Return true if any mailbox is available */ + + regval = can_getreg(priv, STM32_CAN_TSR_OFFSET); + canllvdbg("CAN%d TSR: %08x\n", priv->port, regval); + + if ((regval & CAN_ALL_MAILBOXES) != 0) + { + return true; + } + return false; +} + +/**************************************************************************** + * Name: can_txempty + * + * Description: + * Return true if all message have been sent. If for example, the CAN + * hardware implements FIFOs, then this would mean the transmit FIFO is + * empty. This method is called when the driver needs to make sure that + * all characters are "drained" from the TX hardware before calling + * co_shutdown(). + * + * Input Parameters: + * dev - An instance of the "upper half" can driver state structure. + * + * Returned Value: + * True if there are no pending TX transfers in the CAN hardware. + * + ****************************************************************************/ + +static bool can_txempty(FAR struct can_dev_s *dev) +{ + FAR struct stm32_can_s *priv = dev->cd_priv; + uint32_t regval; + + /* Return true if all mailboxes are available */ + + regval = can_getreg(priv, STM32_CAN_TSR_OFFSET); + canllvdbg("CAN%d TSR: %08x\n", priv->port, regval); + + if ((regval & CAN_ALL_MAILBOXES) == CAN_ALL_MAILBOXES) + { + return true; + } + return false; +} + +/**************************************************************************** + * Name: can_rx0interrupt + * + * Description: + * CAN RX FIFO 0 interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_rx0interrupt(int irq, void *context) +{ + FAR struct can_dev_s *dev = NULL; + FAR struct stm32_can_s *priv; + struct can_hdr_s hdr; + uint8_t data[CAN_MAXDATALEN]; + uint32_t regval; + int npending; + int ret; + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) + if (g_can1priv.canrx0 == irq) + { + dev = &g_can1dev; + } + else if (g_can2priv.canrx0 == irq) + { + dev = &g_can2dev; + } + else + { + PANIC(); + } +#elif defined(CONFIG_STM32_CAN1) + dev = &g_can1dev; +#else /* defined(CONFIG_STM32_CAN2) */ + dev = &g_can2dev; +#endif + priv = dev->cd_priv; + + /* Verify that a message is pending in FIFO 0 */ + + regval = can_getreg(priv, STM32_CAN_RF0R_OFFSET); + npending = (regval & CAN_RFR_FMP_MASK) >> CAN_RFR_FMP_SHIFT; + if (npending < 1) + { + canlldbg("WARNING: No messages pending\n"); + return OK; + } + + can_dumpmbregs(priv, "RX0 interrupt"); + + /* Get the CAN identifier. */ + + regval = can_getreg(priv, STM32_CAN_RI0R_OFFSET); + +#ifdef CONFIG_CAN_EXTID + if ((regval & CAN_RIR_IDE) != 0) + { + hdr.ch_id = (regval & CAN_RIR_EXID_MASK) >> CAN_RIR_EXID_SHIFT; + hdr.ch_extid = true; + } + else + { + hdr.ch_id = (regval & CAN_RIR_STID_MASK) >> CAN_RIR_STID_SHIFT; + hdr.ch_extid = false; + } +#else + if ((regval & CAN_RIR_IDE) != 0) + { + canlldbg("ERROR: Received message with extended identifier. Dropped\n"); + ret = -ENOSYS; + goto errout; + } + + hdr.ch_id = (regval & CAN_RIR_STID_MASK) >> CAN_RIR_STID_SHIFT; +#endif + + /* Clear the error indication and unused bits */ + +#ifdef CONFIG_CAN_ERRORS + hdr.ch_error = 0; /* Error reporting not supported */ +#endif + hdr.ch_unused = 0; + + /* Extract the RTR bit */ + + hdr.ch_rtr = (regval & CAN_RIR_RTR) != 0 ? true : false; + + /* Get the DLC */ + + regval = can_getreg(priv, STM32_CAN_RDT0R_OFFSET); + hdr.ch_dlc = (regval & CAN_RDTR_DLC_MASK) >> CAN_RDTR_DLC_SHIFT; + + /* Save the message data */ + + regval = can_getreg(priv, STM32_CAN_RDL0R_OFFSET); + data[0] = (regval & CAN_RDLR_DATA0_MASK) >> CAN_RDLR_DATA0_SHIFT; + data[1] = (regval & CAN_RDLR_DATA1_MASK) >> CAN_RDLR_DATA1_SHIFT; + data[2] = (regval & CAN_RDLR_DATA2_MASK) >> CAN_RDLR_DATA2_SHIFT; + data[3] = (regval & CAN_RDLR_DATA3_MASK) >> CAN_RDLR_DATA3_SHIFT; + + regval = can_getreg(priv, STM32_CAN_RDH0R_OFFSET); + data[4] = (regval & CAN_RDHR_DATA4_MASK) >> CAN_RDHR_DATA4_SHIFT; + data[5] = (regval & CAN_RDHR_DATA5_MASK) >> CAN_RDHR_DATA5_SHIFT; + data[6] = (regval & CAN_RDHR_DATA6_MASK) >> CAN_RDHR_DATA6_SHIFT; + data[7] = (regval & CAN_RDHR_DATA7_MASK) >> CAN_RDHR_DATA7_SHIFT; + + /* Provide the data to the upper half driver */ + + ret = can_receive(dev, &hdr, data); + + /* Release the FIFO0 */ + +#ifndef CONFIG_CAN_EXTID +errout: +#endif + regval = can_getreg(priv, STM32_CAN_RF0R_OFFSET); + regval |= CAN_RFR_RFOM; + can_putreg(priv, STM32_CAN_RF0R_OFFSET, regval); + return ret; +} + +/**************************************************************************** + * Name: can_txinterrupt + * + * Description: + * CAN TX mailbox complete interrupt handler + * + * Input Parameters: + * irq - The IRQ number of the interrupt. + * context - The register state save array at the time of the interrupt. + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_txinterrupt(int irq, void *context) +{ + FAR struct can_dev_s *dev = NULL; + FAR struct stm32_can_s *priv; + uint32_t regval; + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) + if (g_can1priv.cantx == irq) + { + dev = &g_can1dev; + } + else if (g_can2priv.cantx == irq) + { + dev = &g_can2dev; + } + else + { + PANIC(); + } +#elif defined(CONFIG_STM32_CAN1) + dev = &g_can1dev; +#else /* defined(CONFIG_STM32_CAN2) */ + dev = &g_can2dev; +#endif + priv = dev->cd_priv; + + /* Get the transmit status */ + + regval = can_getreg(priv, STM32_CAN_TSR_OFFSET); + + /* Check for RQCP0: Request completed mailbox 0 */ + + if ((regval & CAN_TSR_RQCP0) != 0) + { + /* Writing '1' to RCP0 clears RCP0 and all the status bits (TXOK0, + * ALST0 and TERR0) for Mailbox 0. + */ + + can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP0); + + /* Check for errors */ + + if ((regval & CAN_TSR_TXOK0) != 0) + { + /* Tell the upper half that the tansfer is finished. */ + + (void)can_txdone(dev); + } + } + + /* Check for RQCP1: Request completed mailbox 1 */ + + if ((regval & CAN_TSR_RQCP1) != 0) + { + /* Writing '1' to RCP1 clears RCP1 and all the status bits (TXOK1, + * ALST1 and TERR1) for Mailbox 1. + */ + + can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP1); + + /* Check for errors */ + + if ((regval & CAN_TSR_TXOK1) != 0) + { + /* Tell the upper half that the tansfer is finished. */ + + (void)can_txdone(dev); + } + } + + /* Check for RQCP2: Request completed mailbox 2 */ + + if ((regval & CAN_TSR_RQCP2) != 0) + { + /* Writing '1' to RCP2 clears RCP2 and all the status bits (TXOK2, + * ALST2 and TERR2) for Mailbox 2. + */ + + can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP2); + + /* Check for errors */ + + if ((regval & CAN_TSR_TXOK2) != 0) + { + /* Tell the upper half that the tansfer is finished. */ + + (void)can_txdone(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: can_bittiming + * + * Description: + * Set the CAN bit timing register (BTR) based on the configured BAUD. + * + * "The bit timing logic monitors the serial bus-line and performs sampling + * and adjustment of the sample point by synchronizing on the start-bit edge + * and resynchronizing on the following edges. + * + * "Its operation may be explained simply by splitting nominal bit time into + * three segments as follows: + * + * 1. "Synchronization segment (SYNC_SEG): a bit change is expected to occur + * within this time segment. It has a fixed length of one time quantum + * (1 x tCAN). + * 2. "Bit segment 1 (BS1): defines the location of the sample point. It + * includes the PROP_SEG and PHASE_SEG1 of the CAN standard. Its duration + * is programmable between 1 and 16 time quanta but may be automatically + * lengthened to compensate for positive phase drifts due to differences + * in the frequency of the various nodes of the network. + * 3. "Bit segment 2 (BS2): defines the location of the transmit point. It + * represents the PHASE_SEG2 of the CAN standard. Its duration is + * programmable between 1 and 8 time quanta but may also be automatically + * shortened to compensate for negative phase drifts." + * + * Pictorially: + * + * |<----------------- NOMINAL BIT TIME ----------------->| + * |<- SYNC_SEG ->|<------ BS1 ------>|<------ BS2 ------>| + * |<---- Tq ---->|<----- Tbs1 ------>|<----- Tbs2 ------>| + * + * Where + * Tbs1 is the duration of the BS1 segment + * Tbs2 is the duration of the BS2 segment + * Tq is the "Time Quantum" + * + * Relationships: + * + * baud = 1 / bit_time + * bit_time = Tq + Tbs1 + Tbs2 + * Tbs1 = Tq * ts1 + * Tbs2 = Tq * ts2 + * Tq = brp * Tpclk1 + * + * Where: + * Tpclk1 is the period of the APB1 clock (PCLK1). + * + * Input Parameter: + * priv - A reference to the CAN block status + * + * Returned Value: + * Zero on success; a negated errno on failure + * + ****************************************************************************/ + +static int can_bittiming(struct stm32_can_s *priv) +{ + uint32_t tmp; + uint32_t brp; + uint32_t ts1; + uint32_t ts2; + + canllvdbg("CAN%d PCLK1: %d baud: %d\n", + priv->port, STM32_PCLK1_FREQUENCY, priv->baud); + + /* Try to get CAN_BIT_QUANTA quanta in one bit_time. + * + * bit_time = Tq*(ts1 + ts2 + 1) + * nquanta = bit_time / Tq + * nquanta = (ts1 + ts2 + 1) + * + * bit_time = brp * Tpclk1 * (ts1 + ts2 + 1) + * nquanta = bit_time / brp / Tpclk1 + * = PCLK1 / baud / brp + * brp = PCLK1 / baud / nquanta; + * + * Example: + * PCLK1 = 42,000,000 baud = 1,000,000 nquanta = 14 : brp = 3 + * PCLK1 = 42,000,000 baud = 700,000 nquanta = 14 : brp = 4 + */ + + tmp = STM32_PCLK1_FREQUENCY / priv->baud; + if (tmp < CAN_BIT_QUANTA) + { + /* At the smallest brp value (1), there are already too few bit times + * (PCLCK1 / baud) to meet our goal. brp must be one and we need + * make some reasonable guesses about ts1 and ts2. + */ + + brp = 1; + + /* In this case, we have to guess a good value for ts1 and ts2 */ + + ts1 = (tmp - 1) >> 1; + ts2 = tmp - ts1 - 1; + if (ts1 == ts2 && ts1 > 1 && ts2 < CAN_BTR_TSEG2_MAX) + { + ts1--; + ts2++; + } + } + + /* Otherwise, nquanta is CAN_BIT_QUANTA, ts1 is CONFIG_CAN_TSEG1, ts2 is + * CONFIG_CAN_TSEG2 and we calculate brp to achieve CAN_BIT_QUANTA quanta + * in the bit time + */ + + else + { + ts1 = CONFIG_CAN_TSEG1; + ts2 = CONFIG_CAN_TSEG2; + brp = (tmp + (CAN_BIT_QUANTA/2)) / CAN_BIT_QUANTA; + DEBUGASSERT(brp >= 1 && brp <= CAN_BTR_BRP_MAX); + } + + canllvdbg("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp); + + /* Configure bit timing. This also does the following, less obvious + * things. Unless loopback mode is enabled, it: + * + * - Disables silent mode. + * - Disables loopback mode. + * + * NOTE that for the time being, SJW is set to 1 just because I don't + * know any better. + */ + + tmp = ((brp - 1) << CAN_BTR_BRP_SHIFT) | ((ts1 - 1) << CAN_BTR_TS1_SHIFT) | + ((ts2 - 1) << CAN_BTR_TS2_SHIFT) | ((1 - 1) << CAN_BTR_SJW_SHIFT); +#ifdef CONFIG_CAN_LOOPBACK +//tmp |= (CAN_BTR_LBKM | CAN_BTR_SILM); + tmp |= CAN_BTR_LBKM; +#endif + + can_putreg(priv, STM32_CAN_BTR_OFFSET, tmp); + return OK; +} + +/**************************************************************************** + * Name: can_cellinit + * + * Description: + * CAN cell initialization + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN block + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int can_cellinit(struct stm32_can_s *priv) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + canllvdbg("CAN%d\n", priv->port); + + /* Exit from sleep mode */ + + regval = can_getreg(priv, STM32_CAN_MCR_OFFSET); + regval &= ~CAN_MCR_SLEEP; + can_putreg(priv, STM32_CAN_MCR_OFFSET, regval); + + /* Configure CAN behavior. Priority driven request order, not message ID. */ + + regval |= CAN_MCR_TXFP; + can_putreg(priv, STM32_CAN_MCR_OFFSET, regval); + + /* Enter initialization mode */ + + regval |= CAN_MCR_INRQ; + can_putreg(priv, STM32_CAN_MCR_OFFSET, regval); + + /* Wait until initialization mode is acknowledged */ + + for (timeout = INAK_TIMEOUT; timeout > 0; timeout--) + { + regval = can_getreg(priv, STM32_CAN_MSR_OFFSET); + if ((regval & CAN_MSR_INAK) != 0) + { + /* We are in initialization mode */ + + break; + } + } + + /* Check for a timeout */ + + if (timeout < 1) + { + canlldbg("ERROR: Timed out waiting to enter initialization mode\n"); + return -ETIMEDOUT; + } + + /* Disable the following modes: + * + * - Time triggered communication mode + * - Automatic bus-off management + * - Automatic wake-up mode + * - No automatic retransmission + * - Receive FIFO locked mode + * - Transmit FIFO priority + */ + + regval = can_getreg(priv, STM32_CAN_MCR_OFFSET); + regval &= ~(CAN_MCR_TXFP | CAN_MCR_RFLM | CAN_MCR_NART | CAN_MCR_AWUM | CAN_MCR_ABOM | CAN_MCR_TTCM); + can_putreg(priv, STM32_CAN_MCR_OFFSET, regval); + + /* Configure bit timing. */ + + ret = can_bittiming(priv); + if (ret < 0) + { + canlldbg("ERROR: Failed to set bit timing: %d\n", ret); + return ret; + } + + /* Exit initialization mode */ + + regval = can_getreg(priv, STM32_CAN_MCR_OFFSET); + regval &= ~CAN_MCR_INRQ; + can_putreg(priv, STM32_CAN_MCR_OFFSET, regval); + + /* Wait until the initialization mode exit is acknowledged */ + + for (timeout = INAK_TIMEOUT; timeout > 0; timeout--) + { + regval = can_getreg(priv, STM32_CAN_MSR_OFFSET); + if ((regval & CAN_MSR_INAK) == 0) + { + /* We are out of initialization mode */ + + break; + } + } + + /* Check for a timeout */ + + if (timeout < 1) + { + canlldbg("ERROR: Timed out waiting to exit initialization mode: %08x\n", regval); + return -ETIMEDOUT; + } + return OK; +} + +/**************************************************************************** + * Name: can_filterinit + * + * Description: + * CAN filter initialization. CAN filters are not currently used by this + * driver. The CAN filters can be configured in a different way: + * + * 1. As a match of specific IDs in a list (IdList mode), or as + * 2. And ID and a mask (IdMask mode). + * + * Filters can also be configured as: + * + * 3. 16- or 32-bit. The advantage of 16-bit filters is that you get + * more filters; The advantage of 32-bit filters is that you get + * finer control of the filtering. + * + * One filter is set up for each CAN. The filter resources are shared + * between the two CAN modules: CAN1 uses only filter 0 (but reserves + * 0 through CAN_NFILTERS/2-1); CAN2 uses only filter CAN_NFILTERS/2 + * (but reserves CAN_NFILTERS/2 through CAN_NFILTERS-1). + * + * 32-bit IdMask mode is configured. However, both the ID and the MASK + * are set to zero thus supressing all filtering because anything masked + * with zero matches zero. + * + * Input Parameter: + * priv - A pointer to the private data structure for this CAN block + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int can_filterinit(struct stm32_can_s *priv) +{ + uint32_t regval; + uint32_t bitmask; + + canllvdbg("CAN%d filter: %d\n", priv->port, priv->filter); + + /* Get the bitmask associated with the filter used by this CAN block */ + + bitmask = ((uint32_t)1) << priv->filter; + + /* Enter filter initialization mode */ + + regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET); + regval |= CAN_FMR_FINIT; + can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval); + + /* Disable the filter */ + + regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET); + regval &= ~bitmask; + can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval); + + /* Select the 32-bit scale for the filter */ + + regval = can_getfreg(priv, STM32_CAN_FS1R_OFFSET); + regval |= bitmask; + can_putfreg(priv, STM32_CAN_FS1R_OFFSET, regval); + + /* There are 14 or 28 filter banks (depending) on the device. Each filter bank is + * composed of two 32-bit registers, CAN_FiR: + */ + + can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 1), 0); + can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 2), 0); + + /* Set Id/Mask mode for the filter */ + + regval = can_getfreg(priv, STM32_CAN_FM1R_OFFSET); + regval &= ~bitmask; + can_putfreg(priv, STM32_CAN_FM1R_OFFSET, regval); + + /* Assign FIFO 0 for the filter */ + + regval = can_getfreg(priv, STM32_CAN_FFA1R_OFFSET); + regval &= ~bitmask; + can_putfreg(priv, STM32_CAN_FFA1R_OFFSET, regval); + + /* Enable the filter */ + + regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET); + regval |= bitmask; + can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval); + + /* Exit filter initialization mode */ + + regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET); + regval &= ~CAN_FMR_FINIT; + can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_caninitialize + * + * Description: + * Initialize the selected CAN port + * + * Input Parameter: + * Port number (for hardware that has mutiple CAN interfaces) + * + * Returned Value: + * Valid CAN device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct can_dev_s *stm32_caninitialize(int port) +{ + struct can_dev_s *dev = NULL; + + canvdbg("CAN%d\n", port); + + /* NOTE: Peripherical clocking for CAN1 and/or CAN2 was already provided + * by stm32_clockconfig() early in the reset sequence. + */ + +#ifdef CONFIG_STM32_CAN1 + if (port == 1) + { + /* Select the CAN1 device structure */ + + dev = &g_can1dev; + + /* Configure CAN1 pins. The ambiguous settings in the stm32*_pinmap.h + * file must have been disambiguated in the board.h file. + */ + + stm32_configgpio(GPIO_CAN1_RX); + stm32_configgpio(GPIO_CAN1_TX); + } + else +#endif +#ifdef CONFIG_STM32_CAN2 + if (port == 2) + { + /* Select the CAN2 device structure */ + + dev = &g_can2dev; + + /* Configure CAN2 pins. The ambiguous settings in the stm32*_pinmap.h + * file must have been disambiguated in the board.h file. + */ + + stm32_configgpio(GPIO_CAN2_RX); + stm32_configgpio(GPIO_CAN2_TX); + } + else +#endif + { + candbg("ERROR: Unsupported port %d\n", port); + return NULL; + } + + return dev; +} + +#endif /* CONFIG_CAN && (CONFIG_STM32_CAN1 || CONFIG_STM32_CAN2) */ + diff --git a/arch/arm/src/stm32/stm32_can.h b/arch/arm/src/stm32/stm32_can.h new file mode 100644 index 0000000000000000000000000000000000000000..e78b3af34f7b582264c87b8484538ff0d9542575 --- /dev/null +++ b/arch/arm/src/stm32/stm32_can.h @@ -0,0 +1,146 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_can.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_CAN_H +#define __ARCH_ARM_SRC_STM32_STM32_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_can.h" + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Up to 2 CAN interfaces are supported */ + +#if STM32_NCAN < 2 +# undef CONFIG_STM32_CAN2 +#endif + +#if STM32_NCAN < 1 +# undef CONFIG_STM32_CAN1 +#endif + +#if defined(CONFIG_CAN) && (defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2)) + +/* CAN BAUD */ + +#if defined(CONFIG_STM32_CAN1) && !defined(CONFIG_CAN1_BAUD) +# error "CONFIG_CAN1_BAUD is not defined" +#endif + +#if defined(CONFIG_STM32_CAN2) && !defined(CONFIG_CAN2_BAUD) +# error "CONFIG_CAN2_BAUD is not defined" +#endif + +/* User-defined TSEG1 and TSEG2 settings may be used. + * + * CONFIG_CAN_TSEG1 = the number of CAN time quanta in segment 1 + * CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2 + * CAN_BIT_QUANTA = The number of CAN time quanta in on bit time + */ + +#ifndef CONFIG_CAN_TSEG1 +# define CONFIG_CAN_TSEG1 6 +#endif + +#if CONFIG_CAN_TSEG1 < 1 || CONFIG_CAN_TSEG1 > CAN_BTR_TSEG1_MAX +# errror "CONFIG_CAN_TSEG1 is out of range" +#endif + +#ifndef CONFIG_CAN_TSEG2 +# define CONFIG_CAN_TSEG2 7 +#endif + +#if CONFIG_CAN_TSEG2 < 1 || CONFIG_CAN_TSEG2 > CAN_BTR_TSEG2_MAX +# errror "CONFIG_CAN_TSEG2 is out of range" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_caninitialize + * + * Description: + * Initialize the selected CAN port + * + * Input Parameter: + * Port number (for hardware that has mutiple CAN interfaces) + * + * Returned Value: + * Valid CAN device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct can_dev_s; +FAR struct can_dev_s *stm32_caninitialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_CAN && (CONFIG_STM32_CAN1 || CONFIG_STM32_CAN2) */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_CAN_H */ diff --git a/arch/arm/src/stm32/stm32_capture.c b/arch/arm/src/stm32/stm32_capture.c new file mode 100644 index 0000000000000000000000000000000000000000..55864281a9ccb17a1c1ecb9d7c0e7876bd1677c5 --- /dev/null +++ b/arch/arm/src/stm32/stm32_capture.c @@ -0,0 +1,1348 @@ +/************************************************************************************ + * arm/arm/src/stm32/stm32_capture.c + * + * Copyright (C) 2015 Bouteville Pierre-Noel. All rights reserved. + * Author: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_capture.h" + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(GPIO_TIM1_CH1IN) || defined(GPIO_TIM2_CH1IN) || defined(GPIO_TIM3_CH1IN) || \ + defined(GPIO_TIM4_CH1IN) || defined(GPIO_TIM5_CH1IN) || defined(GPIO_TIM8_CH1IN) || \ + defined(GPIO_TIM9_CH1IN) || defined(GPIO_TIM10_CH1IN) || defined(GPIO_TIM11_CH1IN) || \ + defined(GPIO_TIM12_CH1IN) || defined(GPIO_TIM13_CH1IN) || defined(GPIO_TIM14_CH1IN) +# define HAVE_CH1IN 1 +#endif + +#if defined(GPIO_TIM1_CH2IN) || defined(GPIO_TIM2_CH2IN) || defined(GPIO_TIM3_CH2IN) || \ + defined(GPIO_TIM4_CH2IN) || defined(GPIO_TIM5_CH2IN) || defined(GPIO_TIM8_CH2IN) || \ + defined(GPIO_TIM9_CH2IN) || defined(GPIO_TIM12_CH2IN) +# define HAVE_CH2IN 1 +#endif + +#if defined(GPIO_TIM1_CH3IN) || defined(GPIO_TIM2_CH3IN) || defined(GPIO_TIM3_CH3IN) || \ + defined(GPIO_TIM4_CH3IN) || defined(GPIO_TIM5_CH3IN) || defined(GPIO_TIM8_CH3IN) +# define HAVE_CH3IN 1 +#endif + +#if defined(GPIO_TIM1_CH4IN) || defined(GPIO_TIM2_CH4IN) || defined(GPIO_TIM3_CH4IN) || \ + defined(GPIO_TIM4_CH4IN) || defined(GPIO_TIM5_CH4IN) || defined(GPIO_TIM8_CH4IN) +# define HAVE_CH4IN 1 +#endif + +#if defined(CONFIG_STM32_TIM1_CAP) || defined(CONFIG_STM32_TIM1_CAP) +#define USE_ADVENCED_TIM 1 +#endif + +#if defined(GPIO_TIM1_EXT_CLK_IN) || defined(GPIO_TIM2_EXT_CLK_IN) || \ + defined(GPIO_TIM3_EXT_CLK_IN) || defined(GPIO_TIM4_EXT_CLK_IN) || \ + defined(GPIO_TIM5_EXT_CLK_IN) || defined(GPIO_TIM8_EXT_CLK_IN) || \ + defined(GPIO_TIM9_EXT_CLK_IN) || defined(GPIO_TIM12_EXT_CLK_IN) +# define USE_EXT_CLOCK 1 +#endif + +/* This module then only compiles if there are enabled timers that are not intended for + * some other purpose. + */ + +#if defined(CONFIG_STM32_TIM1_CAP) || defined(CONFIG_STM32_TIM2_CAP) || \ + defined(CONFIG_STM32_TIM3_CAP) || defined(CONFIG_STM32_TIM4_CAP) || \ + defined(CONFIG_STM32_TIM5_CAP) || defined(CONFIG_STM32_TIM8_CAP) || \ + defined(CONFIG_STM32_TIM9_CAP) || defined(CONFIG_STM32_TIM10_CAP) || \ + defined(CONFIG_STM32_TIM11_CAP) || defined(CONFIG_STM32_TIM12_CAP) || \ + defined(CONFIG_STM32_TIM13_CAP) || defined(CONFIG_STM32_TIM14_CAP) + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* TIM Device Structure */ + +struct stm32_cap_priv_s +{ + const struct stm32_cap_ops_s *ops; + const uint32_t base; /* TIMn base address */ +#ifdef USE_EXT_CLOCK + const uint32_t gpio_clk; /* TIMn base address */ +#endif + const int irq; /* irq vector */ +#ifdef USE_ADVENCED_TIM + const int irq_of; /* irq timer overflow is deferent in advanced timer */ +#endif +}; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/* Get a 16-bit register value by offset */ + +static inline uint16_t stm32_getreg16(FAR const struct stm32_cap_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->base + offset); +} + +/* Put a 16-bit register value by offset */ + +static inline void stm32_putreg16(FAR const struct stm32_cap_priv_s *priv, + uint8_t offset, uint16_t value) +{ + putreg16(value, priv->base + offset); +} + +/* Modify a 16-bit register value by offset */ + +static inline void stm32_modifyreg16(FAR const struct stm32_cap_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->base + offset, clearbits, setbits); +} + +/* Get a 32-bit register value by offset. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + */ + +static inline uint32_t stm32_getreg32(FAR const struct stm32_cap_priv_s *priv, + uint8_t offset) +{ + return getreg32(priv->base + offset); +} + +/* Put a 32-bit register value by offset. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + */ + +static inline void stm32_putreg32(FAR const struct stm32_cap_priv_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/************************************************************************************ + * gpio Functions + ************************************************************************************/ + +static inline uint32_t stm32_cap_gpio(FAR const struct stm32_cap_priv_s *priv, + int channel) +{ + switch(priv->base) + { +#ifdef CONFIG_STM32_TIM1 + case STM32_TIM1_BASE: + switch (channel) + { +#ifdef GPIO_TIM1_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM1_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM1_CH1IN + case 1: + return GPIO_TIM1_CH1IN; +#endif +#ifdef GPIO_TIM1_CH2IN + case 2: + return GPIO_TIM1_CH2IN; +#endif +#ifdef GPIO_TIM1_CH3IN + case 3: + return GPIO_TIM1_CH3IN; +#endif +#ifdef GPIO_TIM1_CH4IN + case 4: + return GPIO_TIM1_CH4IN; +#endif + } + break; +#endif +#ifdef CONFIG_STM32_TIM2 + case STM32_TIM2_BASE: + switch (channel) + { +#ifdef GPIO_TIM2_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM2_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM2_CH1IN + case 1: + return GPIO_TIM2_CH1IN; +#endif +#ifdef GPIO_TIM2_CH2IN + case 2: + return GPIO_TIM2_CH2IN; +#endif +#ifdef GPIO_TIM2_CH3IN + case 3: + return GPIO_TIM2_CH3IN; +#endif +#ifdef GPIO_TIM2_CH4IN + case 4: + return GPIO_TIM2_CH4IN; +#endif + } + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case STM32_TIM3_BASE: + switch (channel) + { +#ifdef GPIO_TIM3_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM3_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM3_CH1IN + case 1: + return GPIO_TIM3_CH1IN; +#endif +#ifdef GPIO_TIM3_CH2IN + case 2: + return GPIO_TIM3_CH2IN; +#endif +#ifdef GPIO_TIM3_CH3IN + case 3: + return GPIO_TIM3_CH3IN; +#endif +#ifdef GPIO_TIM3_CH4IN + case 4: + return GPIO_TIM3_CH4IN; +#endif + } + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case STM32_TIM4_BASE: + switch (channel) + { +#ifdef GPIO_TIM4_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM4_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM4_CH1IN + case 1: + return GPIO_TIM4_CH1IN; +#endif +#ifdef GPIO_TIM4_CH2IN + case 2: + return GPIO_TIM4_CH2IN; +#endif +#ifdef GPIO_TIM4_CH3IN + case 3: + return GPIO_TIM4_CH3IN; +#endif +#ifdef GPIO_TIM4_CH4IN + case 4: + return GPIO_TIM4_CH4IN; +#endif + } + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case STM32_TIM5_BASE: + switch (channel) + { +#ifdef GPIO_TIM5_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM5_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM5_CH1IN + case 1: + return GPIO_TIM5_CH1IN; +#endif +#ifdef GPIO_TIM5_CH2IN + case 2: + return GPIO_TIM5_CH2IN; +#endif +#ifdef GPIO_TIM5_CH3IN + case 3: + return GPIO_TIM5_CH3IN; +#endif +#ifdef GPIO_TIM5_CH4IN + case 4: + return GPIO_TIM5_CH4IN; +#endif + } + break; +#endif + +/* TIM6 and TIM7 cannot be used in capture */ + +#ifdef CONFIG_STM32_TIM8 + case STM32_TIM8_BASE: + switch (channel) + { +#ifdef GPIO_TIM8_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM8_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM8_CH1IN + case 1: + return GPIO_TIM8_CH1IN ; +#endif +#ifdef GPIO_TIM8_CH2IN + case 2: + return GPIO_TIM8_CH2IN ; +#endif +#ifdef GPIO_TIM8_CH3IN + case 3: + return GPIO_TIM8_CH3IN ; +#endif +#ifdef GPIO_TIM8_CH4IN + case 4: + return GPIO_TIM8_CH4IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM9 + case STM32_TIM9_BASE: + switch (channel) + { +#ifdef GPIO_TIM9_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM9_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM9_CH1IN + case 1: + return GPIO_TIM9_CH1IN ; +#endif +#ifdef GPIO_TIM9_CH2IN + case 2: + return GPIO_TIM9_CH2IN ; +#endif +#ifdef GPIO_TIM9_CH3IN + case 3: + return GPIO_TIM9_CH3IN ; +#endif +#ifdef GPIO_TIM9_CH4IN + case 4: + return GPIO_TIM9_CH4IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM10 + case STM32_TIM10_BASE: + switch (channel) + { +#ifdef GPIO_TIM10_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM10_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM10_CH1IN + case 1: + return GPIO_TIM10_CH1IN ; +#endif +#ifdef GPIO_TIM10_CH2IN + case 2: + return GPIO_TIM10_CH2IN ; +#endif +#ifdef GPIO_TIM10_CH4IN + case 3: + return GPIO_TIM10_CH4IN ; +#endif +#ifdef GPIO_TIM10_CH5IN + case 4: + return GPIO_TIM10_CH5IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM11 + case STM32_TIM11_BASE: + switch (channel) + { +#ifdef GPIO_TIM11_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM11_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM11_CH1IN + case 1: + return GPIO_TIM11_CH1IN ; +#endif +#ifdef GPIO_TIM11_CH2IN + case 2: + return GPIO_TIM11_CH2IN ; +#endif +#ifdef GPIO_TIM11_CH4IN + case 3: + return GPIO_TIM11_CH4IN ; +#endif +#ifdef GPIO_TIM11_CH5IN + case 4: + return GPIO_TIM11_CH5IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM12 + case STM32_TIM12_BASE: + switch (channel) + { +#ifdef GPIO_TIM12_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM12_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM12_CH1IN + case 1: + return GPIO_TIM12_CH1IN ; +#endif +#ifdef GPIO_TIM12_CH2IN + case 2: + return GPIO_TIM12_CH2IN ; +#endif +#ifdef GPIO_TIM12_CH4IN + case 3: + return GPIO_TIM12_CH4IN ; +#endif +#ifdef GPIO_TIM12_CH5IN + case 4: + return GPIO_TIM12_CH5IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM13 + case STM32_TIM13_BASE: + switch (channel) + { +#ifdef GPIO_TIM13_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM13_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM13_CH1IN + case 1: + return GPIO_TIM13_CH1IN ; +#endif +#ifdef GPIO_TIM13_CH2IN + case 2: + return GPIO_TIM13_CH2IN ; +#endif +#ifdef GPIO_TIM13_CH4IN + case 3: + return GPIO_TIM13_CH4IN ; +#endif +#ifdef GPIO_TIM13_CH5IN + case 4: + return GPIO_TIM13_CH5IN ; +#endif + } + break; +#endif + +#ifdef CONFIG_STM32_TIM14 + case STM32_TIM14_BASE: + switch (channel) + { +#ifdef GPIO_TIM14_EXT_CLK_IN + case STM32_CAP_CHANNEL_COUNTER: + return GPIO_TIM14_EXT_CLK_IN; +#endif +#ifdef GPIO_TIM14_CH1IN + case 1: + return GPIO_TIM14_CH1IN ; +#endif +#ifdef GPIO_TIM14_CH2IN + case 2: + return GPIO_TIM14_CH2IN ; +#endif +#ifdef GPIO_TIM14_CH4IN + case 3: + return GPIO_TIM14_CH4IN ; +#endif +#ifdef GPIO_TIM14_CH5IN + case 4: + return GPIO_TIM14_CH5IN ; +#endif + } + break; +#endif + } + return 0; +} + +static inline int stm32_cap_set_rcc(FAR const struct stm32_cap_priv_s *priv, + bool on) +{ + uint32_t offset = 0; + uint32_t mask = 0; + + switch (priv->base) + { +#ifdef CONFIG_STM32_TIM1_CAP + case 1: + offset = STM32_RCC_APB2ENR; + mask = RCC_APB2ENR_TIM1EN; + break; +#endif +#ifdef CONFIG_STM32_TIM2_CAP + case 2: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB1ENR_TIM2EN; + break; +#endif +#ifdef CONFIG_STM32_TIM3_CAP + case 3: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB1ENR_TIM3EN; + break; +#endif +#ifdef CONFIG_STM32_TIM4_CAP + case 4: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB1ENR_TIM4EN; + break; +#endif +#ifdef CONFIG_STM32_TIM5_CAP + case 5: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB1ENR_TIM5EN; + break; +#endif + + /* TIM6 and TIM7 cannot be used in capture */ + +#ifdef CONFIG_STM32_TIM8_CAP + case 8: + offset = STM32_RCC_APB2ENR; + mask = RCC_APB2ENR_TIM8EN; + break; +#endif +#ifdef CONFIG_STM32_TIM9_CAP + case 9: + offset = STM32_RCC_APB2ENR; + mask = RCC_APB2ENR_TIM9EN; + break; +#endif +#ifdef CONFIG_STM32_TIM10_CAP + case 10: + offset = STM32_RCC_APB2ENR; + mask = RCC_APB2ENR_TIM10EN; + break; +#endif +#ifdef CONFIG_STM32_TIM11_CAP + case 11: + offset = STM32_RCC_APB2ENR; + mask = RCC_APB2ENR_TIM11EN; + break; +#endif +#ifdef CONFIG_STM32_TIM12_CAP + case 12: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB2ENR_TIM12EN; + break; +#endif +#ifdef CONFIG_STM32_TIM13_CAP + case 13: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB2ENR_TIM13EN; + break; +#endif +#ifdef CONFIG_STM32_TIM14_CAP + case 14: + offset = STM32_RCC_APB1ENR; + mask = RCC_APB2ENR_TIM14EN; + break; +#endif + } + + if (mask == 0) + { + return ERROR; + } + + if (on) + { + modifyreg32(offset, 0, mask); + } + else + { + modifyreg32(offset, mask, 0); + } + + return OK; +} +/************************************************************************************ + * Basic Functions + ************************************************************************************/ + +static int stm32_cap_setclock(FAR struct stm32_cap_dev_s *dev, stm32_cap_clk_t clk, + uint32_t prescaler,uint32_t max) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint16_t regval = 0; + + if (prescaler == 0) + { + /* Disable Timer */ + + stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET,ATIM_CR1_CEN,0); + return 0; + } + + /* We need to decrement value for '1', but only, if we are allowed to + * not to cause underflow. Check for overflow. + */ + + if (prescaler > 0) + { + prescaler--; + } + + if (prescaler > 0xffff) + { + prescaler = 0xffff; + } + + + switch(clk) + { + case STM32_CAP_CLK_INT: + regval = GTIM_SMCR_DISAB; + break; + + case STM32_CAP_CLK_EXT: + regval = GTIM_SMCR_EXTCLK1; + break; + + /* TODO: Add other case */ + + default: + return ERROR; + } + + stm32_modifyreg16(priv, STM32_BTIM_EGR_OFFSET, GTIM_SMCR_SMS_MASK, regval); + + /* Set Maximum */ + + stm32_putreg32(priv, STM32_BTIM_ARR_OFFSET, max); + + /* Set prescaler */ + + stm32_putreg16(priv, STM32_BTIM_PSC_OFFSET, prescaler); + + /* Reset counter timer */ + + stm32_modifyreg16(priv, STM32_BTIM_EGR_OFFSET,0,BTIM_EGR_UG); + + /* Enable timer */ + + stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET,0,BTIM_CR1_CEN); + +#ifdef USE_ADVENCED_TIM + /* Advanced registers require Main Output Enable */ + + if ((priv->base == STM32_TIM1_BASE) || (priv->base == STM32_TIM8_BASE)) + { + stm32_modifyreg16(priv, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE); + } +#endif + + return prescaler; +} + +static int stm32_cap_setisr(FAR struct stm32_cap_dev_s *dev, xcpt_t handler) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + int irq; +#ifdef USE_ADVENCED_TIM + int irq_of; +#endif + + ASSERT(dev); + + irq = priv->irq; +#ifdef USE_ADVENCED_TIM + irq_of = priv->irq_of; +#endif + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(irq); + irq_detach(irq); + +#ifdef USE_ADVENCED_TIM + if (priv->irq_of) + { + up_disable_irq(irq_of); + irq_detach(irq_of); + } +#endif + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(irq, handler); + up_enable_irq(irq); + +#ifdef USE_ADVENCED_TIM + if (priv->irq_of) + { + irq_attach(priv->irq_of, handler); + up_enable_irq(priv->irq_of); + } +#endif + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(irq, NVIC_SYSH_PRIORITY_DEFAULT); + +# ifdef USE_ADVENCED_TIM + if (priv->irq_of) + { + up_prioritize_irq(irq_of, NVIC_SYSH_PRIORITY_DEFAULT); + } +# endif +#endif + + return OK; +} + + +static void stm32_cap_enableint(FAR struct stm32_cap_dev_s *dev, + stm32_cap_flags_t src, bool on) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint16_t mask = 0; + ASSERT(dev); + + if (src & STM32_CAP_FLAG_IRQ_COUNTER) + { + mask |= ATIM_DIER_UIE; + } + + if (src & STM32_CAP_FLAG_IRQ_CH_1) + { + mask |= ATIM_DIER_CC1IE; + } + + if (src & STM32_CAP_FLAG_IRQ_CH_2) + { + mask |= ATIM_DIER_CC2IE; + } + + if (src & STM32_CAP_FLAG_IRQ_CH_3) + { + mask |= ATIM_DIER_CC3IE; + } + + if (src & STM32_CAP_FLAG_IRQ_CH_4) + { + mask |= ATIM_DIER_CC4IE; + } + + /* Not IRQ on channel overflow */ + + if (on) + { + stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET,0,mask); + } + else + { + stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET,mask,0); + } +} + +static void stm32_cap_ackflags(FAR struct stm32_cap_dev_s *dev, int flags) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint16_t mask = 0; + + if (flags & STM32_CAP_FLAG_IRQ_COUNTER) + { + mask |= ATIM_SR_UIF; + } + + if (flags & STM32_CAP_FLAG_IRQ_CH_1) + { + mask |= ATIM_SR_CC1IF; + } + + if (flags & STM32_CAP_FLAG_IRQ_CH_2) + { + mask |= ATIM_SR_CC2IF; + } + + if (flags & STM32_CAP_FLAG_IRQ_CH_3) + { + mask |= ATIM_SR_CC3IF; + } + + if (flags & STM32_CAP_FLAG_IRQ_CH_4) + { + mask |= ATIM_SR_CC4IF; + } + + if (flags & STM32_CAP_FLAG_OF_CH_1) + { + mask |= ATIM_SR_CC1OF; + } + + if (flags & STM32_CAP_FLAG_OF_CH_2) + { + mask |= ATIM_SR_CC2OF; + } + + if (flags & STM32_CAP_FLAG_OF_CH_3) + { + mask |= ATIM_SR_CC3OF; + } + + if (flags & STM32_CAP_FLAG_OF_CH_4) + { + mask |= ATIM_SR_CC4OF; + } + + stm32_putreg16(priv, STM32_BTIM_SR_OFFSET, ~mask); +} + +static stm32_cap_flags_t stm32_cap_getflags(FAR struct stm32_cap_dev_s *dev) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint16_t regval = 0; + stm32_cap_flags_t flags = 0; + + regval = stm32_getreg16(priv, STM32_BTIM_SR_OFFSET); + + if (regval & ATIM_SR_UIF) + { + flags |= STM32_CAP_FLAG_IRQ_COUNTER; + } + + if (regval & ATIM_SR_CC1IF) + { + flags |= STM32_CAP_FLAG_IRQ_CH_1; + } + + if (regval & ATIM_SR_CC2IF) + { + flags |= STM32_CAP_FLAG_IRQ_CH_2; + } + + if (regval & ATIM_SR_CC3IF) + { + flags |= STM32_CAP_FLAG_IRQ_CH_3; + } + + if (regval & ATIM_SR_CC4IF) + { + flags |= STM32_CAP_FLAG_IRQ_CH_4; + } + + if (regval & ATIM_SR_CC1OF) + { + flags |= STM32_CAP_FLAG_OF_CH_1; + } + + if (regval & ATIM_SR_CC2OF) + { + flags |= STM32_CAP_FLAG_OF_CH_2; + } + + if (regval & ATIM_SR_CC3OF) + { + flags |= STM32_CAP_FLAG_OF_CH_3; + } + + if (regval & ATIM_SR_CC4OF) + { + flags |= STM32_CAP_FLAG_OF_CH_4; + } + + return flags; + +} + +/************************************************************************************ + * General Functions + ************************************************************************************/ + +static int stm32_cap_setchannel(FAR struct stm32_cap_dev_s *dev, uint8_t channel, + stm32_cap_ch_cfg_t cfg) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint32_t gpio = 0; + uint16_t mask; + uint16_t regval; + uint16_t ccer_en_bit; + + ASSERT(dev); + + gpio = stm32_cap_gpio(priv,channel); + + if (gpio == 0) + { + return ERROR; + } + + if ((cfg & STM32_CAP_MAPPED_MASK) == 0) + { + return ERROR; /* MAPPED not selected */ + } + + /* Change to zero base index */ + + channel--; + + /* Set ccer : + * + * GTIM_CCER_CCxE Is written latter to allow writing CCxS bits. + * + */ + + switch (cfg & STM32_CAP_EDGE_MASK) + { + case STM32_CAP_EDGE_DISABLED: + regval = 0; + ccer_en_bit = 0; + break; + + case STM32_CAP_EDGE_RISING: + ccer_en_bit = GTIM_CCER_CC1E; + regval = 0; + break; + + case STM32_CAP_EDGE_FALLING: + ccer_en_bit = GTIM_CCER_CC1E; + regval = GTIM_CCER_CC1P; + break; + + case STM32_CAP_EDGE_BOTH: + ccer_en_bit = GTIM_CCER_CC1E; + regval = GTIM_CCER_CC1P | GTIM_CCER_CC1NP; + break; + + default: + return ERROR; + } + + /* Shift all CCER bits to corresponding channel */ + + mask = (GTIM_CCER_CC1E | GTIM_CCER_CC1P | GTIM_CCER_CC1NP); + mask <<= (channel << 2); + regval <<= (channel << 2); + ccer_en_bit <<= (channel << 2); + + stm32_modifyreg16(priv,STM32_GTIM_CCER_OFFSET,mask,regval); + + /* Set ccmr */ + + regval = cfg; + mask = (GTIM_CCMR1_IC1F_MASK | GTIM_CCMR1_IC1PSC_MASK | GTIM_CCMR1_CC1S_MASK); + regval &= mask; + + if (channel & 1) + { + regval <<= 8; + mask <<= 8; + } + + if (channel < 2) + { + stm32_modifyreg16(priv,STM32_GTIM_CCMR1_OFFSET,mask,regval); + } + else + { + stm32_modifyreg16(priv,STM32_GTIM_CCMR2_OFFSET,mask,regval); + } + + /* Set GPIO */ + + if ((cfg & STM32_CAP_EDGE_MASK) == STM32_CAP_EDGE_DISABLED) + { + stm32_unconfiggpio(gpio); + } + else + { + stm32_configgpio(gpio); + } + + /* Enable this channel timer */ + + stm32_modifyreg16(priv, STM32_GTIM_CCER_OFFSET, 0, ccer_en_bit); + return OK; +} + +static uint32_t stm32_cap_getcapture(FAR struct stm32_cap_dev_s *dev, uint8_t channel) +{ + const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; + uint32_t offset; + ASSERT(dev); + + switch (channel) + { + case STM32_CAP_CHANNEL_COUNTER: + offset = STM32_GTIM_CNT_OFFSET; + break; +#ifdef HAVE_CH1IN + case 1: + offset = STM32_GTIM_CCR1_OFFSET; + break; +#endif +#ifdef HAVE_CH2IN + case 2: + offset = STM32_GTIM_CCR2_OFFSET; + break; +#endif +#ifdef HAVE_CH3IN + case 3: + offset = STM32_GTIM_CCR3_OFFSET; + break; +#endif +#ifdef HAVE_CH4IN + case 4: + offset = STM32_GTIM_CCR4_OFFSET; + break; +#endif + default: + return ERROR; + } + + if ((priv->base == STM32_TIM2_BASE)||(priv->base == STM32_TIM2_BASE)) + { + return stm32_getreg32(priv,offset); + } + + return stm32_getreg16(priv,offset); +} + +/************************************************************************************ + * Advanced Functions + ************************************************************************************/ + +/* TODO: Advanced functions for the STM32_ATIM */ + +/************************************************************************************ + * Device Structures, Instantiation + ************************************************************************************/ + +struct stm32_cap_ops_s stm32_cap_ops = +{ + .setclock = &stm32_cap_setclock, + .setchannel = &stm32_cap_setchannel, + .getcapture = &stm32_cap_getcapture, + .setisr = &stm32_cap_setisr, + .enableint = &stm32_cap_enableint, + .ackflags = &stm32_cap_ackflags, + .getflags = &stm32_cap_getflags +}; + +#ifdef CONFIG_STM32_TIM1_CAP +const struct stm32_cap_priv_s stm32_tim1_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM1_BASE, + .irq = STM32_IRQ_TIM1, +#ifdef USE_ADVENCED_TIM + .irg_of = STM32_IRQ_TIM1UP, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM2_CAP +const struct stm32_cap_priv_s stm32_tim2_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM2_BASE, + .irq = STM32_IRQ_TIM2, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM3_CAP +const struct stm32_cap_priv_s stm32_tim3_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM3_BASE, + .irq = STM32_IRQ_TIM3, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM4_CAP +const struct stm32_cap_priv_s stm32_tim4_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM4_BASE, + .irq = STM32_IRQ_TIM4, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM5_CAP +const struct stm32_cap_priv_s stm32_tim5_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM5_BASE, + .irq = STM32_IRQ_TIM5, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +/* TIM6 and TIM7 cannot be used in capture */ + +#ifdef CONFIG_STM32_TIM8_CAP +const struct stm32_cap_priv_s stm32_tim8_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM8_BASE, + .irq = STM32_IRQ_TIM8, +#ifdef USE_ADVENCED_TIM + .irg_of = STM32_IRQ_TIM8UP, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM9_CAP +const struct stm32_cap_priv_s stm32_tim9_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM9_BASE, + .irq = STM32_IRQ_TIM9, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM10_CAP +const struct stm32_cap_priv_s stm32_tim10_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM10_BASE, + .irq = STM32_IRQ_TIM10, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM11_CAP +const struct stm32_cap_priv_s stm32_tim11_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM11_BASE, + .irq = STM32_IRQ_TIM11, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM12_CAP +const struct stm32_cap_priv_s stm32_tim12_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM12_BASE, + .irq = STM32_IRQ_TIM12, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM13_CAP +const struct stm32_cap_priv_s stm32_tim13_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM13_BASE, + .irq = STM32_IRQ_TIM13, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +#ifdef CONFIG_STM32_TIM14_CAP +const struct stm32_cap_priv_s stm32_tim14_priv = +{ + .ops = &stm32_cap_ops, + .base = STM32_TIM14_BASE, + .irq = STM32_IRQ_TIM14, +#ifdef USE_ADVENCED_TIM + .irg_of = 0, +#endif +}; +#endif + +static inline const struct stm32_cap_priv_s * stm32_cap_get_priv(int timer) +{ + switch (timer) + { +#ifdef CONFIG_STM32_TIM1_CAP + case 1: + return &stm32_tim1_priv; +#endif +#ifdef CONFIG_STM32_TIM2_CAP + case 2: + return &stm32_tim2_priv; +#endif +#ifdef CONFIG_STM32_TIM3_CAP + case 3: + return &stm32_tim3_priv; +#endif +#ifdef CONFIG_STM32_TIM4_CAP + case 4: + return &stm32_tim4_priv; +#endif +#ifdef CONFIG_STM32_TIM5_CAP + case 5: + return &stm32_tim5_priv; +#endif + + /* TIM6 and TIM7 cannot be used in capture */ + +#ifdef CONFIG_STM32_TIM8_CAP + case 8: + return &stm32_tim8_priv; +#endif +#ifdef CONFIG_STM32_TIM9_CAP + case 9: + return &stm32_tim9_priv; +#endif +#ifdef CONFIG_STM32_TIM10_CAP + case 10: + return &stm32_tim10_priv; +#endif +#ifdef CONFIG_STM32_TIM11_CAP + case 11: + return &stm32_tim11_priv; +#endif +#ifdef CONFIG_STM32_TIM12_CAP + case 12: + return &stm32_tim12_priv; +#endif +#ifdef CONFIG_STM32_TIM13_CAP + case 13: + return &stm32_tim13_priv; +#endif +#ifdef CONFIG_STM32_TIM14_CAP + case 14: + return &stm32_tim14_priv; +#endif + } + + return NULL; +} + +/************************************************************************************ + * Public Function - Initialization + ************************************************************************************/ + +FAR struct stm32_cap_dev_s *stm32_cap_init(int timer) +{ + const struct stm32_cap_priv_s *priv = stm32_cap_get_priv(timer); + uint32_t gpio; + + if (priv) + { + stm32_cap_set_rcc(priv,true); + + gpio = stm32_cap_gpio(priv,STM32_CAP_CHANNEL_COUNTER); + if (gpio) + { + stm32_configgpio(gpio); + } + + /* Disable timer while is not configured */ + + stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0); + } + + return (struct stm32_cap_dev_s *)priv; +} + +int stm32_cap_deinit(FAR struct stm32_cap_dev_s * dev) +{ + const struct stm32_cap_priv_s *priv = (struct stm32_cap_priv_s *)dev; + uint32_t gpio; + ASSERT(dev); + + /* Disable timer while is not configured */ + + stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0); + + gpio = stm32_cap_gpio(priv,STM32_CAP_CHANNEL_COUNTER); + if (gpio) + { + stm32_unconfiggpio(gpio); + } + + stm32_cap_set_rcc(priv,false); + return OK; +} + +#endif /* defined(CONFIG_STM32_TIM1 || ... || TIM14) */ diff --git a/arch/arm/src/stm32/stm32_capture.h b/arch/arm/src/stm32/stm32_capture.h new file mode 100644 index 0000000000000000000000000000000000000000..d015c80e5622edef89c02788888c9d5bf8523464 --- /dev/null +++ b/arch/arm/src/stm32/stm32_capture.h @@ -0,0 +1,205 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_capture.h + * + * Copyright (C) 2015 Bouteville Pierre-Noel. All rights reserved. + * Author: Bouteville Pierre-Noel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_CAPTURE_H +#define __ARCH_ARM_SRC_STM32_STM32_CAPTURE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include +#include "chip/stm32_tim.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helpers **************************************************************************/ + +#define STM32_CAP_SETCLOCK(d,clk_src,psc,max) ((d)->ops->setclock(d,clk_src,psc,max)) +#define STM32_CAP_SETCHANNEL(d,ch,cfg) ((d)->ops->setchannel(d,ch,cfg)) +#define STM32_CAP_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch)) +#define STM32_CAP_SETISR(d,hnd) ((d)->ops->setisr(d,hnd)) +#define STM32_CAP_ENABLEINT(d,s,on) ((d)->ops->enableint(d,s,on)) +#define STM32_CAP_ACKFLAGS(d,f) ((d)->ops->ackflags(d,f)) +#define STM32_CAP_GETFLAGS(d) ((d)->ops->getflags(d)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Capture Device Structure */ + +struct stm32_cap_dev_s +{ + struct stm32_cap_ops_s *ops; +}; + +/* Capture input EDGE sources */ + +typedef enum +{ + /* Mapped */ + + STM32_CAP_MAPPED_MASK = (GTIM_CCMR1_CC1S_MASK), + STM32_CAP_MAPPED_TI1 = (1< + * Based on a prototype by Petteri Aimonen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stm32_ccm.h" + +#ifdef HAVE_CCM_HEAP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct mm_heap_s g_ccm_heap; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* HAVE_CCM_HEAP */ \ No newline at end of file diff --git a/arch/arm/src/stm32/stm32_ccm.h b/arch/arm/src/stm32/stm32_ccm.h new file mode 100644 index 0000000000000000000000000000000000000000..ce441ff7601880e525d076f49731e05329ee8d85 --- /dev/null +++ b/arch/arm/src/stm32/stm32_ccm.h @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/arm/src/common/stm32_ccm.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Based on a prototype by Petteri Aimonen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_CCM_H +#define __ARCH_ARM_SRC_STM32_STM32_CCM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Assume that we can support the CCM heap */ + +#define HAVE_CCM_HEAP 1 + +/* Only the STM32 F2, F3, and F4 have CCM memory */ + +#if defined(CONFIG_STM32_STM32F30XX) +# define CCM_START 0x10000000 +# define CCM_END 0x10002000 +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CCM_START 0x10000000 +# define CCM_END 0x10010000 +#else +# undef HAVE_CCM_HEAP +#endif + +/* In order to use the CCM heap, it had to have been excluded from the main + * heap. + */ + +#ifndef CONFIG_STM32_CCMEXCLUDE +# undef HAVE_CCM_HEAP +#endif + +/* Can we support the CCM heap? */ + +#ifdef HAVE_CCM_HEAP + +/* ccm_initialize must be called early in initialization in order to + * initialize the CCM heap. + */ + +#define ccm_initialize() \ + mm_initialize(&g_ccm_heap, (FAR void *)CCM_START, CCM_END-CCM_START) + +/* The ccm_addregion interface could be used if, for example, you want to + * add some other memory region to the CCM heap. I don't really know why + * you might want to do that, but the functionality is essentially free. + */ + +#define ccm_addregion(b,s) mm_addregion(&g_ccm_heap, b, s); + +/* Then, once g_ccm_heap has been setup by ccm_initialize(), these memory + * allocators can be used just like the standard memory allocators. + */ + +#define ccm_malloc(s) mm_malloc(&g_ccm_heap, s) +#define ccm_zalloc(s) mm_zalloc(&g_ccm_heap, s) +#define ccm_calloc(n,s) mm_calloc(&g_ccm_heap, n,s) +#define ccm_free(p) mm_free(&g_ccm_heap, p) +#define ccm_realloc(p,s) mm_realloc(&g_ccm_heap, p, s) +#define ccm_memalign(a,s) mm_memalign(&g_ccm_heap, a, s) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN struct mm_heap_s g_ccm_heap; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +/**************************************************************************** + * Name: ccm_procfs_register + * + * Description: + * Register the CCM procfs file system entry + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_CCM_PROCFS +int ccm_procfs_register(void); +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* HAVE_CCM_HEAP */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_CCM_H */ diff --git a/arch/arm/src/stm32/stm32_dac.c b/arch/arm/src/stm32/stm32_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..b6fb31bdcd0a38826e11f0002ade5ffff7232e3e --- /dev/null +++ b/arch/arm/src/stm32/stm32_dac.c @@ -0,0 +1,1161 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_dac.c + * + * Copyright (C) 2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32.h" +#include "stm32_dac.h" +#include "stm32_rcc.h" +#include "stm32_dma.h" + +#ifdef CONFIG_DAC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Up to 2 DAC interfaces are supported */ + +#if STM32_NDAC < 2 +# undef CONFIG_STM32_DAC2 +# undef CONFIG_STM32_DAC2_DMA +# undef CONFIG_STM32_DAC2_TIMER +# undef CONFIG_STM32_DAC2_TIMER_FREQUENCY +#endif + +#if STM32_NDAC < 1 +# undef CONFIG_STM32_DAC1 +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC1_TIMER +# undef CONFIG_STM32_DAC1_TIMER_FREQUENCY +#endif + +#if defined(CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) + +/* DMA configuration. */ + +#if defined(CONFIG_STM32_DAC1_DMA) || defined(CONFIG_STM32_DAC2_DMA) +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# ifndef CONFIG_STM32_DMA2 +# warning "STM32 F1/F3 DAC DMA support requires CONFIG_STM32_DMA2" +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC2_DMA +# endif +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# ifndef CONFIG_STM32_DMA1 +# warning "STM32 F4 DAC DMA support requires CONFIG_STM32_DMA1" +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC2_DMA +# endif +# else +# warning "No DAC DMA information for this STM32 family" +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC2_DMA +# endif +#endif + +/* If DMA is selected, then a timer and output frequency must also be + * provided to support the DMA transfer. The DMA transfer could be + * supported by and EXTI trigger, but this feature is not currently + * supported by the driver. + */ + +#ifdef CONFIG_STM32_DAC1_DMA +# if !defined(CONFIG_STM32_DAC1_TIMER) +# warning "A timer number must be specificed in CONFIG_STM32_DAC1_TIMER" +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC1_TIMER_FREQUENCY +# elif !defined(CONFIG_STM32_DAC1_TIMER_FREQUENCY) +# warning "A timer frequency must be specificed in CONFIG_STM32_DAC1_TIMER_FREQUENCY" +# undef CONFIG_STM32_DAC1_DMA +# undef CONFIG_STM32_DAC1_TIMER +# endif +#endif + +#ifdef CONFIG_STM32_DAC2_DMA +# if !defined(CONFIG_STM32_DAC2_TIMER) +# warning "A timer number must be specificed in CONFIG_STM32_DAC2_TIMER" +# undef CONFIG_STM32_DAC2_DMA +# undef CONFIG_STM32_DAC2_TIMER_FREQUENCY +# elif !defined(CONFIG_STM32_DAC2_TIMER_FREQUENCY) +# warning "A timer frequency must be specificed in CONFIG_STM32_DAC2_TIMER_FREQUENCY" +# undef CONFIG_STM32_DAC2_DMA +# undef CONFIG_STM32_DAC2_TIMER +# endif +#endif + +/* DMA *********************************************************************/ +/* DMA channels and interface values differ for the F1 and F4 families */ + +#undef HAVE_DMA +#if defined(CONFIG_STM32_DAC1_DMA) || defined(CONFIG_STM32_DAC2_DMA) +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define HAVE_DMA 1 +# define DAC_DMA 2 +# define DAC1_DMA_CHAN DMACHAN_DAC_CHAN1 +# define DAC2_DMA_CHAN DMACHAN_DAC_CHAN2 +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define HAVE_DMA 1 +# define DAC_DMA 1 +# define DAC1_DMA_CHAN DMAMAP_DAC1 +# define DAC2_DMA_CHAN DMAMAP_DAC2 +# endif +#endif + +/* Timer configuration. The STM32 supports 8 different trigger for DAC + * output: + * + * TSEL SOURCE DEVICES + * ---- ----------------------- ------------------------------------- + * 000 Timer 6 TRGO event ALL + * 001 Timer 3 TRGO event STM32 F1 Connectivity Line + * Timer 8 TRGO event Other STM32 F1 and all STM32 F4 + * 010 Timer 7 TRGO event ALL + * 011 Timer 5 TRGO event ALL + * 100 Timer 2 TRGO event ALL + * 101 Timer 4 TRGO event ALL + * 110 EXTI line9 ALL + * 111 SWTRIG Software control ALL + * + * This driver does not support the EXTI trigger. + */ + +#undef NEED_TIM6 +#undef NEED_TIM3 +#undef NEED_TIM8 +#undef NEED_TIM7 +#undef NEED_TIM5 +#undef NEED_TIM2 +#undef NEED_TIM4 + +#ifdef CONFIG_STM32_DAC1_DMA +# if CONFIG_STM32_DAC1_TIMER == 6 +# ifndef CONFIG_STM32_TIM6_DAC +# error "CONFIG_STM32_TIM6_DAC required for DAC1" +# endif +# define NEED_TIM6 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM6 +# define DAC1_TIMER_BASE STM32_TIM6_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC1_TIMER == 3 && defined(CONFIG_STM32_CONNECTIVITYLINE) +# ifndef CONFIG_STM32_TIM3_DAC +# error "CONFIG_STM32_TIM3_DAC required for DAC1" +# endif +# define NEED_TIM3 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM3 +# define DAC1_TIMER_BASE STM32_TIM3_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC1_TIMER == 8 && !defined(CONFIG_STM32_CONNECTIVITYLINE) +# ifndef CONFIG_STM32_TIM8_DAC +# error "CONFIG_STM32_TIM8_DAC required for DAC1" +# endif +# define NEED_TIM8 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM8 +# define DAC1_TIMER_BASE STM32_TIM8_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +# elif CONFIG_STM32_DAC1_TIMER == 7 +# ifndef CONFIG_STM32_TIM7_DAC +# error "CONFIG_STM32_TIM7_DAC required for DAC1" +# endif +# define NEED_TIM7 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM7 +# define DAC1_TIMER_BASE STM32_TIM7_BASE +# elif CONFIG_STM32_DAC1_TIMER == 5 +# ifndef CONFIG_STM32_TIM5_DAC +# error "CONFIG_STM32_TIM5_DAC required for DAC1" +# endif +# define NEED_TIM5 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM5 +# define DAC1_TIMER_BASE STM32_TIM5_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC1_TIMER == 2 +# ifndef CONFIG_STM32_TIM2_DAC +# error "CONFIG_STM32_TIM2_DAC required for DAC1" +# endif +# define NEED_TIM2 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM2 +# define DAC1_TIMER_BASE STM32_TIM2_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC1_TIMER == 4 +# ifndef CONFIG_STM32_TIM4_DAC +# error "CONFIG_STM32_TIM4_DAC required for DAC1" +# endif +# define NEED_TIM4 +# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM4 +# define DAC1_TIMER_BASE STM32_TIM4_BASE +# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# else +# error "Unsupported CONFIG_STM32_DAC1_TIMER" +# endif +#else +# define DAC1_TSEL_VALUE DAC_CR_TSEL_SW +#endif + +#ifdef CONFIG_STM32_DAC2_DMA +# if CONFIG_STM32_DAC2_TIMER == 6 +# ifndef CONFIG_STM32_TIM6_DAC +# error "CONFIG_STM32_TIM6_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM6 +# define DAC2_TIMER_BASE STM32_TIM6_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 3 && defined(CONFIG_STM32_CONNECTIVITYLINE) +# ifndef CONFIG_STM32_TIM3_DAC +# error "CONFIG_STM32_TIM3_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM3 +# define DAC2_TIMER_BASE STM32_TIM3_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 8 && !defined(CONFIG_STM32_CONNECTIVITYLINE) +# ifndef CONFIG_STM32_TIM8_DAC +# error "CONFIG_STM32_TIM8_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM8 +# define DAC2_TIMER_BASE STM32_TIM8_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 7 +# ifndef CONFIG_STM32_TIM7_DAC +# error "CONFIG_STM32_TIM7_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM7 +# define DAC2_TIMER_BASE STM32_TIM7_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 5 +# ifndef CONFIG_STM32_TIM5_DAC +# error "CONFIG_STM32_TIM5_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM5 +# define DAC2_TIMER_BASE STM32_TIM5_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 2 +# ifndef CONFIG_STM32_TIM2_DAC +# error "CONFIG_STM32_TIM2_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM2 +# define DAC2_TIMER_BASE STM32_TIM2_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# elif CONFIG_STM32_DAC2_TIMER == 4 +# ifndef CONFIG_STM32_TIM4_DAC +# error "CONFIG_STM32_TIM4_DAC required for DAC2" +# endif +# define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM4 +# define DAC2_TIMER_BASE STM32_TIM4_BASE +# define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +# else +# error "Unsupported CONFIG_STM32_DAC2_TIMER" +# endif +#else +# define DAC2_TSEL_VALUE DAC_CR_TSEL_SW +#endif + +#ifndef CONFIG_STM32_DAC_DMA_BUFFER_SIZE +# define CONFIG_STM32_DAC_DMA_BUFFER_SIZE 256 +#endif + +/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and + * CONFIG_STM32_DACn_TIMER_FREQUENCY. + */ + +#warning "Missing Logic" + +/* DMA stream/channel configuration */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define DAC_DMA_CONTROL_WORD (DMA_SCR_MSIZE_16BITS | \ + DMA_SCR_PSIZE_16BITS | \ + DMA_SCR_MINC | \ + DMA_SCR_CIRC | \ + DMA_SCR_DIR_M2P) +#else +# define DAC_DMA_CONTROL_WORD (DMA_CCR_MSIZE_16BITS | \ + DMA_CCR_PSIZE_16BITS | \ + DMA_CCR_MINC | \ + DMA_CCR_CIRC | \ + DMA_CCR_DIR) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the internal state of the single STM32 DAC block */ + +struct stm32_dac_s +{ + uint8_t init : 1; /* True, the DAC block has been initialized */ +}; + +/* This structure represents the internal state of one STM32 DAC channel */ + +struct stm32_chan_s +{ + uint8_t inuse : 1; /* True, the driver is in use and not available */ +#ifdef HAVE_DMA + uint8_t hasdma : 1; /* True, this channel supports DMA */ + uint8_t timer; /* Timer number 2-8 */ +#endif + uint8_t intf; /* DAC zero-based interface number (0 or 1) */ + uint32_t dro; /* Data output register */ + uint32_t tsel; /* CR trigger select value */ +#ifdef HAVE_DMA + uint16_t dmachan; /* DMA channel needed by this DAC */ + DMA_HANDLE dma; /* Allocated DMA channel */ + uint32_t tbase; /* Timer base address */ + uint32_t tfrequency; /* Timer frequency */ + uint16_t dmabuffer[CONFIG_STM32_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* DAC Register access */ + +#ifdef HAVE_DMA +static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset); +static void tim_putreg(FAR struct stm32_chan_s *chan, int offset, + uint32_t value); +#endif + +/* Interrupt handler */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static int dac_interrupt(int irq, FAR void *context); +#endif + +/* DAC methods */ + +static void dac_reset(FAR struct dac_dev_s *dev); +static int dac_setup(FAR struct dac_dev_s *dev); +static void dac_shutdown(FAR struct dac_dev_s *dev); +static void dac_txint(FAR struct dac_dev_s *dev, bool enable); +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg); +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg); + +/* Initialization */ + +#ifdef HAVE_DMA +static int dac_timinit(FAR struct stm32_chan_s *chan); +#endif +static int dac_chaninit(FAR struct stm32_chan_s *chan); +static int dac_blockinit(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct dac_ops_s g_dacops = +{ + .ao_reset = dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, +}; + +#ifdef CONFIG_STM32_DAC1 +static struct stm32_chan_s g_dac1priv = +{ + .intf = 0, + .dro = STM32_DAC_DHR12R1, +#ifdef CONFIG_STM32_DAC1_DMA + .hasdma = 1, + .dmachan = DAC1_DMA_CHAN, + .timer = CONFIG_STM32_DAC1_TIMER, + .tsel = DAC1_TSEL_VALUE, + .tbase = DAC1_TIMER_BASE, + .tfrequency = CONFIG_STM32_DAC1_TIMER_FREQUENCY, +#endif +}; + +static struct dac_dev_s g_dac1dev = +{ + .ad_ops = &g_dacops, + .ad_priv = &g_dac1priv, +}; +#endif + +#ifdef CONFIG_STM32_DAC2 +static struct stm32_chan_s g_dac2priv = +{ + .intf = 1, + .dro = STM32_DAC_DHR12R2, +#ifdef CONFIG_STM32_DAC2_DMA + .hasdma = 1, + .dmachan = DAC2_DMA_CHAN, + .timer = CONFIG_STM32_DAC2_TIMER, + .tsel = DAC2_TSEL_VALUE, + .tbase = DAC2_TIMER_BASE, + .tfrequency = CONFIG_STM32_DAC2_TIMER_FREQUENCY, +#endif +}; + +static struct dac_dev_s g_dac2dev = +{ + .ad_ops = &g_dacops, + .ad_priv = &g_dac2priv, +}; +#endif + +static struct stm32_dac_s g_dacblock; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dac_modify_cr + * + * Description: + * Modify the contents of the DAC control register. + * + * Input Parameters: + * priv - Driver state instance + * clearbits - Bits in the control register to be cleared + * setbits - Bits in the control register to be set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *chan, + uint32_t clearbits, uint32_t setbits) +{ + uint32_t shift; + + shift = chan->intf * 16; + modifyreg32(STM32_DAC_CR, clearbits << shift, setbits << shift); +} + +/**************************************************************************** + * Name: tim_getreg + * + * Description: + * Read the value of an DMA timer register. + * + * Input Parameters: + * chan - A reference to the DAC block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +#ifdef HAVE_DMA +static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset) +{ + return getreg32(chan->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_putreg + * + * Description: + * Read the value of an DMA timer register. + * + * Input Parameters: + * chan - A reference to the DAC block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef HAVE_DMA +static void tim_putreg(FAR struct stm32_chan_s *chan, int offset, + uint32_t value) +{ + putreg32(value, chan->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_modifyreg + * + * Description: + * Modify the value of an DMA timer register. + * + * Input Parameters: + * priv - Driver state instance + * offset - The timer register offset + * clearbits - Bits in the control register to be cleared + * setbits - Bits in the control register to be set + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef HAVE_DMA +static void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset, + uint32_t clearbits, uint32_t setbits) +{ + modifyreg32(chan->tbase + offset, clearbits, setbits); +} +#endif + +/**************************************************************************** + * Name: dac_interrupt + * + * Description: + * DAC interrupt handler. The STM32 F4 family supports a only a DAC + * underrun interrupt. + * + * Input Parameters: + * + * Returned Value: + * OK + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static int dac_interrupt(int irq, FAR void *context) +{ +#warning "Missing logic" + return OK; +} +#endif + +/**************************************************************************** + * Name: dac_reset + * + * Description: + * Reset the DAC channel. Called early to initialize the hardware. This + * is called, before dac_setup() and on error conditions. + * + * NOTE: DAC reset will reset both DAC channels! + * + * Input Parameters: + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dac_reset(FAR struct dac_dev_s *dev) +{ + irqstate_t flags; + + /* Reset only the selected DAC channel; the other DAC channel must remain + * functional. + */ + + flags = enter_critical_section(); + +#warning "Missing logic" + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: dac_setup + * + * Description: + * Configure the DAC. This method is called the first time that the DAC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching DAC interrupts. Interrupts + * are all disabled upon return. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_setup(FAR struct dac_dev_s *dev) +{ +#warning "Missing logic" + return OK; +} + +/**************************************************************************** + * Name: dac_shutdown + * + * Description: + * Disable the DAC. This method is called when the DAC device is closed. + * This method reverses the operation the setup method. + * + * Input Parameters: + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dac_shutdown(FAR struct dac_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: dac_txint + * + * Description: + * Call to enable or disable TX interrupts. + * + * Input Parameters: + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dac_txint(FAR struct dac_dev_s *dev, bool enable) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: dac_dmatxcallback + * + * Description: + * DMA callback function. + * + * Input Parameters: + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) +{ +} + +/**************************************************************************** + * Name: dac_send + * + * Description: + * Set the DAC output. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) +{ + FAR struct stm32_chan_s *chan = dev->ad_priv; + + /* Enable DAC Channel */ + + stm32_dac_modify_cr(chan, 0, DAC_CR_EN); + +#ifdef HAVE_DMA + if (chan->hasdma) + { + /* Configure the DMA stream/channel. + * + * - Channel number + * - Peripheral address + * - Direction: Memory to peripheral + * - Disable peripheral address increment + * - Enable memory address increment + * - Peripheral data size: half word + * - Mode: circular??? + * - Priority: ? + * - FIFO mode: disable + * - FIFO threshold: half full + * - Memory Burst: single + * - Peripheral Burst: single + */ + + stm32_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer, + CONFIG_STM32_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD); + + /* Enable DMA */ + + stm32_dmastart(chan->dma, dac_dmatxcallback, chan, false); + + /* Enable DMA for DAC Channel */ + + stm32_dac_modify_cr(chan, 0, DAC_CR_DMAEN); + } + else +#endif + { + /* Non-DMA transfer */ + + putreg16(msg->am_data, chan->dro); +#ifdef CONFIG_STM32_DAC2 + if (chan->intf) + { + dac_txdone(&g_dac2dev); + } + else +#endif + { + dac_txdone(&g_dac1dev); + } + } + + /* Reset counters (generate an update) */ + +#ifdef HAVE_DMA + tim_modifyreg(chan, STM32_BTIM_EGR_OFFSET, 0, ATIM_EGR_UG); +#endif + return OK; +} + +/**************************************************************************** + * Name: dac_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: dac_timinit + * + * Description: + * Initialize the timer that drivers the DAC DMA for this channel using + * the pre-calculated timer divider definitions. + * + * Input Parameters: + * chan - A reference to the DAC channel state data + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef HAVE_DMA +static int dac_timinit(FAR struct stm32_chan_s *chan) +{ + uint32_t pclk; + uint32_t prescaler; + uint32_t timclk; + uint32_t reload; + uint32_t regaddr; + uint32_t setbits; + + /* Configure the time base: Timer period, prescaler, clock division, + * counter mode (up). + */ + + /* Enable the timer. At most, two of the following cases (pluse the + * default) will be enabled + */ + + pclk = STM32_TIM27_FREQUENCY; + regaddr = STM32_RCC_APB1ENR; + + switch (chan->timer) + { +#ifdef NEED_TIM2 + case 2: + setbits = RCC_APB1ENR_TIM2EN; + break; +#endif +#ifdef NEED_TIM3 + case 3: + setbits = RCC_APB1ENR_TIM3EN; + break; +#endif +#ifdef NEED_TIM4 + case 4: + setbits = RCC_APB1ENR_TIM4EN; + break; +#endif +#ifdef NEED_TIM5 + case 5: + setbits = RCC_APB1ENR_TIM5EN; + break; +#endif +#ifdef NEED_TIM6 + case 6: + setbits = RCC_APB1ENR_TIM6EN; + break; +#endif +#ifdef NEED_TIM7 + case 7: + setbits = RCC_APB1ENR_TIM7EN; + break; +#endif +#ifdef NEED_TIM8 + case 8: + regaddr = STM32_RCC_APB2ENR; + setbits = RCC_APB2ENR_TIM8EN; + pclk = STM32_TIM18_FREQUENCY; + break; +#endif + default: + adbg("Could not enable timer\n"); + break; + } + + /* Enable the timer. */ + + modifyreg32(regaddr, 0, setbits); + + /* Calculate optimal values for the timer prescaler and for the timer reload + * register. If 'frequency' is the desired frequency, then + * + * reload = timclk / frequency + * timclk = pclk / presc + * + * Or, + * + * reload = pclk / presc / frequency + * + * There are many solutions to this this, but the best solution will be the + * one that has the largest reload value and the smallest prescaler value. + * That is the solution that should give us the most accuracy in the timer + * control. Subject to: + * + * 0 <= presc <= 65536 + * 1 <= reload <= 65535 + * + * So presc = pclk / 65535 / frequency would be optimal. + * + * Example: + * + * pclk = 42 MHz + * frequency = 100 Hz + * + * prescaler = 42,000,000 / 65,535 / 100 + * = 6.4 (or 7 -- taking the ceiling always) + * timclk = 42,000,000 / 7 + * = 6,000,000 + * reload = 6,000,000 / 100 + * = 60,000 + */ + + prescaler = (pclk / chan->tfrequency + 65534) / 65535; + if (prescaler < 1) + { + prescaler = 1; + } + else if (prescaler > 65536) + { + prescaler = 65536; + } + + timclk = pclk / prescaler; + + reload = timclk / chan->tfrequency; + if (reload < 1) + { + reload = 1; + } + else if (reload > 65535) + { + reload = 65535; + } + + /* Set the reload and prescaler values */ + + tim_putreg(chan, STM32_BTIM_ARR_OFFSET, (uint16_t)reload); + tim_putreg(chan, STM32_BTIM_PSC_OFFSET, (uint16_t)(prescaler - 1)); + + /* Count mode up, auto reload */ + + tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_ARPE); + + /* Selection TRGO selection: update */ + + tim_modifyreg(chan, STM32_BTIM_CR2_OFFSET, ATIM_CR2_MMS_MASK, + ATIM_CR2_MMS_UPDATE); + + /* Update DMA request enable ???? */ +#if 0 + tim_modifyreg(chan, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UDE); +#endif + + /* Enable the counter */ + + tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_CEN); + return OK; +} +#endif + +/**************************************************************************** + * Name: dac_chaninit + * + * Description: + * Initialize the DAC channel. + * + * Input Parameters: + * chan - A reference to the DAC channel state data + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_chaninit(FAR struct stm32_chan_s *chan) +{ + int ret; + uint16_t clearbits; + uint16_t setbits; + + /* Is the selected channel already in-use? */ + + if (chan->inuse) + { + /* Yes.. then return EBUSY */ + + return -EBUSY; + } + + /* Configure the DAC output pin: + * + * DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + + stm32_configgpio(chan->intf ? GPIO_DAC2_OUT : GPIO_DAC1_OUT); + + /* DAC channel configuration: + * + * - Set the trigger selection based upon the configuration. + * - Set wave generation == None. + * - Enable the output buffer. + */ + + /* Disable before change */ + + stm32_dac_modify_cr(chan, DAC_CR_EN, 0); + + clearbits = DAC_CR_TSEL_MASK | + DAC_CR_MAMP_MASK | + DAC_CR_WAVE_MASK | + DAC_CR_BOFF; + setbits = + chan->tsel | /* Set trigger source (SW or timer TRGO event) */ + DAC_CR_MAMP_AMP1 | /* Set waveform characteristics */ + DAC_CR_WAVE_DISABLED | /* Set no noise */ + DAC_CR_BOFF; /* Enable output buffer */ + stm32_dac_modify_cr(chan, clearbits, setbits); + +#ifdef HAVE_DMA + /* Determine if DMA is supported by this channel */ + + if (chan->hasdma) + { + /* Yes.. DAC trigger enable */ + + stm32_dac_modify_cr(chan, 0, DAC_CR_TEN); + + /* Allocate a DMA channel */ + + chan->dma = stm32_dmachannel(chan->dmachan); + if (!chan->dma) + { + adbg("Failed to allocate a DMA channel\n"); + return -EBUSY; + } + + /* Configure the timer that supports the DMA operation */ + + ret = dac_timinit(chan); + if (ret < 0) + { + adbg("Failed to initialize the DMA timer: %d\n", ret); + return ret; + } + } +#endif + + /* Mark the DAC channel "in-use" */ + + chan->inuse = 1; + return OK; +} + +/**************************************************************************** + * Name: dac_blockinit + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_blockinit(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Has the DMA block already been initialized? */ + + if (g_dacblock.init) + { + /* Yes.. then return success We only have to do this once */ + + return OK; + } + + /* Put the entire DAC block in reset state */ + + flags = enter_critical_section(); + regval = getreg32(STM32_RCC_APB1RSTR); + regval |= RCC_APB1RSTR_DACRST; + putreg32(regval, STM32_RCC_APB1RSTR); + + /* Take the DAC out of reset state */ + + regval &= ~RCC_APB1RSTR_DACRST; + putreg32(regval, STM32_RCC_APB1RSTR); + leave_critical_section(flags); + + /* Mark the DAC block as initialized */ + + g_dacblock.init = 1; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dacinitialize + * + * Description: + * Initialize the DAC. + * + * Input Parameters: + * intf - The DAC interface number. + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure. + * + * Assumptions: + * 1. Clock to the DAC block has enabled, + * 2. Board-specific logic has already configured + * + ****************************************************************************/ + +FAR struct dac_dev_s *stm32_dacinitialize(int intf) +{ + FAR struct dac_dev_s *dev; + FAR struct stm32_chan_s *chan; + int ret; + +#ifdef CONFIG_STM32_DAC1 + if (intf == 1) + { + avdbg("DAC1 Selected\n"); + dev = &g_dac1dev; + } + else +#endif +#ifdef CONFIG_STM32_DAC2 + if (intf == 2) + { + avdbg("DAC2 Selected\n"); + dev = &g_dac2dev; + } + else +#endif + { + adbg("No such DAC interface: %d\n", intf); + errno = ENODEV; + return NULL; + } + + /* Make sure that the DAC block has been initialized */ + + ret = dac_blockinit(); + if (ret < 0) + { + adbg("Failed to initialize the DAC block: %d\n", ret); + errno = -ret; + return NULL; + } + + /* Configure the selected DAC channel */ + + chan = dev->ad_priv; + ret = dac_chaninit(chan); + if (ret < 0) + { + adbg("Failed to initialize DAC channel %d: %d\n", intf, ret); + errno = -ret; + return NULL; + } + + return dev; +} + +#endif /* CONFIG_STM32_DAC1 || CONFIG_STM32_DAC2 */ +#endif /* CONFIG_DAC */ diff --git a/arch/arm/src/stm32/stm32_dac.h b/arch/arm/src/stm32/stm32_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..3718a245a4dce5e7dba38d9f743086e304d1f389 --- /dev/null +++ b/arch/arm/src/stm32/stm32_dac.h @@ -0,0 +1,140 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_dac.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_DAC_H +#define __ARCH_ARM_SRC_STM32_STM32_DAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_dac.h" + +#include + +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic DAC outputs. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_DAC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_DAC +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_DAC +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_DAC +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_DAC +#endif +#ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_DAC +#endif +#ifndef CONFIG_STM32_TIM6 +# undef CONFIG_STM32_TIM6_DAC +#endif +#ifndef CONFIG_STM32_TIM7 +# undef CONFIG_STM32_TIM7_DAC +#endif +#ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_DAC +#endif +#ifndef CONFIG_STM32_TIM9 +# undef CONFIG_STM32_TIM9_DAC +#endif +#ifndef CONFIG_STM32_TIM10 +# undef CONFIG_STM32_TIM10_DAC +#endif +#ifndef CONFIG_STM32_TIM11 +# undef CONFIG_STM32_TIM11_DAC +#endif +#ifndef CONFIG_STM32_TIM12 +# undef CONFIG_STM32_TIM12_DAC +#endif +#ifndef CONFIG_STM32_TIM13 +# undef CONFIG_STM32_TIM13_DAC +#endif +#ifndef CONFIG_STM32_TIM14 +# undef CONFIG_STM32_TIM14_DAC +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_dacinitialize + * + * Description: + * Initialize the DAC + * + * Input Parameters: + * intf - The DAC interface number. + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct dac_dev_s; +FAR struct dac_dev_s *stm32_dacinitialize(int intf); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_DAC_H */ + diff --git a/arch/arm/src/stm32/stm32_dbgmcu.h b/arch/arm/src/stm32/stm32_dbgmcu.h new file mode 100644 index 0000000000000000000000000000000000000000..5fb19218665bb1ebcfed347be7c335e902cf2d0c --- /dev/null +++ b/arch/arm/src/stm32/stm32_dbgmcu.h @@ -0,0 +1,64 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_dbgmcu.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_DBGMCU_H +#define __ARCH_ARM_SRC_STM32_STM32_DBGMCU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_dbgmcu.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_DBGMCU_H */ diff --git a/arch/arm/src/stm32/stm32_dma.c b/arch/arm/src/stm32/stm32_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..ff7135840e414814c0776f2bbd761fc0974c9ea0 --- /dev/null +++ b/arch/arm/src/stm32/stm32_dma.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_dma.c + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* This file is only a thin shell that includes the correct DMA implementation + * for the selected STM32 family. The correct file cannot be selected by + * the make system because it needs the intelligence that only exists in + * chip.h that can associate an STM32 part number with an STM32 family. + * + * The STM32 F4 DMA differs from the F1 DMA primarily in that it adds the + * concept of "streams" that are used to associate DMA sources with DMA + * channels. + */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) +# include "stm32f10xxx_dma.c" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "stm32f20xxx_dma.c" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "stm32f40xxx_dma.c" +#endif diff --git a/arch/arm/src/stm32/stm32_dma.h b/arch/arm/src/stm32/stm32_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..b2f968fe1f7c0e6110b1d60cf43f342c17d14d0a --- /dev/null +++ b/arch/arm/src/stm32/stm32_dma.h @@ -0,0 +1,332 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_DMA_H +#define __ARCH_ARM_SRC_STM32_STM32_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/* Include the correct DMA register definitions for this STM32 family */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f10xxx_dma.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_dma.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_dma.h" +#else +# error "Unknown STM32 DMA" +#endif + +/* These definitions provide the bit encoding of the 'status' parameter passed to the + * DMA callback function (see dma_callback_t). + */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define DMA_STATUS_FEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_DMEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_TEIF DMA_CHAN_TEIF_BIT /* Channel Transfer Error */ +# define DMA_STATUS_HTIF DMA_CHAN_HTIF_BIT /* Channel Half Transfer */ +# define DMA_STATUS_TCIF DMA_CHAN_TCIF_BIT /* Channel Transfer Complete */ +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define DMA_STATUS_FEIF 0 /* Stream FIFO error (ignored) */ +# define DMA_STATUS_DMEIF DMA_STREAM_DMEIF_BIT /* Stream direct mode error */ +# define DMA_STATUS_TEIF DMA_STREAM_TEIF_BIT /* Stream Transfer Error */ +# define DMA_STATUS_HTIF DMA_STREAM_HTIF_BIT /* Stream Half Transfer */ +# define DMA_STATUS_TCIF DMA_STREAM_TCIF_BIT /* Stream Transfer Complete */ +#endif + +#define DMA_STATUS_ERROR (DMA_STATUS_FEIF|DMA_STATUS_DMEIF|DMA_STATUS_TEIF) +#define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA + * channel (F1) or a DMA stream (F4). + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the the + * completion of the DMA. + * + * Input Parameters: + * handle - Refers tot he DMA channel or stream + * status - A bit encoded value that provides the completion status. See the + * DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when stm32_dmastart() was + * called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +#ifdef CONFIG_DEBUG_DMA +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +struct stm32_dmaregs_s +{ + uint32_t isr; + uint32_t ccr; + uint32_t cndtr; + uint32_t cpar; + uint32_t cmar; +}; +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +struct stm32_dmaregs_s +{ + uint32_t lisr; + uint32_t hisr; + uint32_t scr; + uint32_t sndtr; + uint32_t spar; + uint32_t sm0ar; + uint32_t sm1ar; + uint32_t sfcr; +}; +#else +# error "Unknown STM32 DMA" +#endif +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chan' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chan - Identifies the stream/channel resource + * For the STM32 F1, this is simply the channel number as provided by + * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h. + * For the STM32 F4, this is a bit encoded value as provided by the + * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'chan' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chan' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int chan); + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr); + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, + bool half); + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address with the given configuration. This depends on the internal + * connections in the ARM bus matrix of the processor. Note that this + * only applies to memory addresses, it will return false for any peripheral + * address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr); +#else +# define stm32_dmacapable(maddr, count, ccr) (true) +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs); +#else +# define stm32_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg); +#else +# define stm32_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_DMA_H */ diff --git a/arch/arm/src/stm32/stm32_dma2d.c b/arch/arm/src/stm32/stm32_dma2d.c new file mode 100644 index 0000000000000000000000000000000000000000..442b88c3ffc9683506119aeed144f753e71f9ea2 --- /dev/null +++ b/arch/arm/src/stm32/stm32_dma2d.c @@ -0,0 +1,2302 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_dma2d.c + * + * Copyright (C) 2014-2015 Marco Krahl. All rights reserved. + * Author: Marco Krahl + * + * References: + * STM32F429 Technical Reference Manual + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "stm32.h" +#include "chip/stm32_ltdc.h" +#include "chip/stm32_dma2d.h" +#include "chip/stm32_ccm.h" +#include "stm32_dma2d.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* output, foreground and background layer */ + +#define DMA2D_NLAYERS 3 + +/* DMA2D PFC value definitions */ + +#define DMA2D_PF_ARGB8888 0 +#define DMA2D_PF_RGB888 1 +#define DMA2D_PF_RGB565 2 +#define DMA2D_PF_ARGB1555 3 +#define DMA2D_PF_ARGB14444 4 +#define DMA2D_PF_L8 5 +#define DMA2D_PF_AL44 6 +#define DMA2D_PF_AL88 7 +#define DMA2D_PF_L4 8 +#define DMA2D_PF_A8 9 +#define DMA2D_PF_A4 10 + +/* DMA2D blender control */ + +#define STM32_DMA2D_CR_MODE_BLIT DMA2D_CR_MODE(0) +#define STM32_DMA2D_CR_MODE_BLITPFC DMA2D_CR_MODE(1) +#define STM32_DMA2D_CR_MODE_BLEND DMA2D_CR_MODE(2) +#define STM32_DMA2D_CR_MODE_COLOR DMA2D_CR_MODE(3) +#define STM32_DMA2D_CR_MODE_CLEAR STM32_DMA2D_CR_MODE_COLOR + +/* DMA2D PFC alpha mode */ + +#define STM32_DMA2D_PFCCR_AM_NONE 0 +#define STM32_DMA2D_PFCCR_AM_CONST 1 +#define STM32_DMA2D_PFCCR_AM_PIXEL 10 + +/* Only 8 bit per pixel overal supported */ + +#define DMA2D_PF_BYPP(n) ((n) / 8) + +#define DMA2D_CLUT_SIZE STM32_LTDC_NCLUT - 1 + +/* Layer argb cmap conversion */ + +#define DMA2D_CLUT_ALPHA(n) ((uint32_t)(n) << 24) +#define DMA2D_CLUT_RED(n) ((uint32_t)(n) << 16) +#define DMA2D_CLUT_GREEN(n) ((uint32_t)(n) << 8) +#define DMA2D_CLUT_BLUE(n) ((uint32_t)(n) << 0) + +#define DMA2D_CMAP_ALPHA(n) ((uint32_t)(n) >> 24) +#define DMA2D_CMAP_RED(n) ((uint32_t)(n) >> 16) +#define DMA2D_CMAP_GREEN(n) ((uint32_t)(n) >> 8) +#define DMA2D_CMAP_BLUE(n) ((uint32_t)(n) >> 0) + +/* Define shadow layer for ltdc interface */ + +#ifdef CONFIG_STM32_LTDC_INTERFACE +# ifdef CONFIG_STM32_LTDC_L2 +# define DMA2D_SHADOW_LAYER 2 +# define DMA2D_SHADOW_LAYER_L1 0 +# define DMA2D_SHADOW_LAYER_L2 1 +# else +# define DMA2D_SHADOW_LAYER 1 +# define DMA2D_SHADOW_LAYER_L1 0 +# endif +# define DMA2D_LAYER_NSIZE CONFIG_STM32_DMA2D_NLAYERS + DMA2D_SHADOW_LAYER +#else +# define DMA2D_LAYER_NSIZE CONFIG_STM32_DMA2D_NLAYERS +# define DMA2D_SHADOW_LAYER 0 +#endif + +/* Debug option */ + +#ifdef CONFIG_STM32_DMA2D_REGDEBUG +# define regdbg dbg +# define regvdbg vdbg +#else +# define regdbg(x...) +# define regvdbg(x...) +#endif + +/* check clut support */ + +#ifdef CONFIG_STM32_DMA2D_L8 +# ifndef CONFIG_FB_CMAP +# error "Enable cmap to support the configured layer formats!" +# endif +#endif + +/* check ccm heap allocation */ + +#ifndef CONFIG_STM32_CCMEXCLUDE +# error "Enable CONFIG_STM32_CCMEXCLUDE from the heap allocation" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* DMA2D General layer information */ + +struct stm32_dma2d_s +{ + struct dma2d_layer_s dma2d; /* public dma2d interface */ + + /* Fixed settings */ + + int lid; /* Layer identifier */ + struct fb_videoinfo_s vinfo; /* Layer videoinfo */ + struct fb_planeinfo_s pinfo; /* Layer planeinfo */ + + /* Blending */ + + uint32_t blendmode; /* the interface blendmode */ + uint8_t alpha; /* the alpha value */ + + /* Coloring */ + +#ifdef CONFIG_STM32_DMA2D_L8 + uint32_t *clut; /* Color lookup table */ +#endif + + /* Operation */ + uint8_t fmt; /* the controller pixel format */ + sem_t *lock; /* Ensure mutually exclusive access */ +}; + +#ifdef CONFIG_STM32_LTDC_INTERFACE + +/* This structures provides the DMA2D layer for each LTDC layer */ + +struct stm32_ltdc_dma2d_s +{ + struct stm32_dma2d_s dma2ddev; +#ifdef CONFIG_STM32_DMA2D_L8 + FAR struct ltdc_layer_s *ltdc; +#endif +}; + +struct stm32_ltdc_layer_s +{ + /* Layer state */ + + struct stm32_ltdc_dma2d_s layer[DMA2D_SHADOW_LAYER]; +}; +#endif + +/* Interrupt handling */ + +struct stm32_interrupt_s +{ + bool wait; /* Informs that the task is waiting for the irq */ + bool handled; /* Informs that an irq was handled */ + int irq; /* irq number */ + sem_t *sem; /* Semaphore for waiting for irq */ +}; + +/* This enumeration foreground and background layer supported by the dma2d + * controller + */ + +enum stm32_layer_e +{ + DMA2D_LAYER_LFORE = 0, /* Foreground Layer */ + DMA2D_LAYER_LBACK, /* Background Layer */ + DMA2D_LAYER_LOUT, /* Output Layer */ +}; + +/* DMA2D memory address register */ + +static const uintptr_t stm32_mar_layer_t[DMA2D_NLAYERS] = +{ + STM32_DMA2D_FGMAR, + STM32_DMA2D_BGMAR, + STM32_DMA2D_OMAR +}; + +/* DMA2D offset register */ + +static const uintptr_t stm32_or_layer_t[DMA2D_NLAYERS] = +{ + STM32_DMA2D_FGOR, + STM32_DMA2D_BGOR, + STM32_DMA2D_OOR +}; + +/* DMA2D pfc control register */ + +static const uintptr_t stm32_pfccr_layer_t[DMA2D_NLAYERS] = +{ + STM32_DMA2D_FGPFCCR, + STM32_DMA2D_BGPFCCR, + STM32_DMA2D_OPFCCR +}; + +/* DMA2D color register */ + +static const uintptr_t stm32_color_layer_t[DMA2D_NLAYERS] = +{ + STM32_DMA2D_FGCOLR, + STM32_DMA2D_BGCOLR, + STM32_DMA2D_OCOLR +}; + +/* DMA2D clut memory address register */ + +static const uintptr_t stm32_cmar_layer_t[DMA2D_NLAYERS - 1] = +{ + STM32_DMA2D_FGCMAR, + STM32_DMA2D_BGCMAR +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Private functions */ + +static int stm32_dma2d_pixelformat(uint8_t fmt, uint8_t *fmtmap); +static int stm32_dma2d_bpp(uint8_t fmt, uint8_t *bpp); +static void stm32_dma2d_control(uint32_t setbits, uint32_t clrbits); +static int stm32_dma2dirq(int irq, void *context); +static int stm32_dma2d_waitforirq(void); +static int stm32_dma2d_start(void); +#ifdef CONFIG_STM32_DMA2D_L8 +static int stm32_dma2d_loadclut(uintptr_t reg); +#endif +static uint32_t stm32_dma2d_memaddress(FAR const struct stm32_dma2d_s *layer, + fb_coord_t xpos, fb_coord_t ypos); +static fb_coord_t stm32_dma2d_lineoffset(FAR const struct stm32_dma2d_s *layer, + FAR const struct ltdc_area_s *area); + +static int stm32_dma2d_lfreelid(void); +static FAR struct stm32_dma2d_s * stm32_dma2d_lalloc(void); +static void stm32_dma2d_lfree(FAR struct stm32_dma2d_s *layer); +static void stm32_dma2d_llayerscleanup(void); +static bool stm32_dma2d_lvalidate(FAR const struct stm32_dma2d_s *layer); +static bool stm32_dma2d_lvalidatesize(FAR const struct stm32_dma2d_s *layer, + fb_coord_t xpos, fb_coord_t ypos, + FAR const struct ltdc_area_s *area); +static void stm32_dma2d_linit(FAR struct stm32_dma2d_s *layer, + int lid, uint8_t fmt); + +static void stm32_dma2d_lfifo(FAR const struct stm32_dma2d_s *layer, int lid, + fb_coord_t xpos, fb_coord_t ypos, + FAR const struct ltdc_area_s *area); +static void stm32_dma2d_lcolor(FAR const struct stm32_dma2d_s *layer, + int lid, uint32_t color); +static void stm32_dma2d_llnr(FAR struct stm32_dma2d_s *layer, + FAR const struct ltdc_area_s *area); +static int stm32_dma2d_loutpfc(FAR const struct stm32_dma2d_s *layer); +static void stm32_dma2d_lpfc(FAR const struct stm32_dma2d_s *layer, + int lid, uint32_t blendmode); +/* Public functions */ + +static int stm32_dma2dgetvideoinfo(FAR struct dma2d_layer_s *layer, + FAR struct fb_videoinfo_s *vinfo); +static int stm32_dma2dgetplaneinfo(FAR struct dma2d_layer_s *layer, int planeno, + FAR struct fb_planeinfo_s *pinfo); +static int stm32_dma2dgetlid(FAR struct dma2d_layer_s *layer, int *lid); +#ifdef CONFIG_STM32_DMA2D_L8 +static int stm32_dma2dsetclut(FAR struct dma2d_layer_s *layer, + const FAR struct fb_cmap_s *cmap); +static int stm32_dma2dgetclut(FAR struct dma2d_layer_s *layer, + FAR struct fb_cmap_s *cmap); +#endif +static int stm32_dma2dsetalpha(FAR struct dma2d_layer_s *layer, uint8_t alpha); +static int stm32_dma2dgetalpha(FAR struct dma2d_layer_s *layer, uint8_t *alpha); +static int stm32_dma2dsetblendmode(FAR struct dma2d_layer_s *layer, + uint32_t mode); +static int stm32_dma2dgetblendmode(FAR struct dma2d_layer_s *layer, + uint32_t *mode); +static int stm32_dma2dblit(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea); +static int stm32_dma2dblend(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea); +static int stm32_dma2dfillarea(FAR struct dma2d_layer_s *layer, + FAR const struct ltdc_area_s *area, uint32_t color); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Remember the layer references for alloc/deallocation */ + +static struct stm32_dma2d_s *g_layers[DMA2D_LAYER_NSIZE]; + +/* The DMA2D semaphore that enforces mutually exclusive access */ + +static sem_t g_lock; + +#ifdef CONFIG_STM32_LTDC_INTERFACE +/* This structure provides the DMA2D layer for each LTDC layer */ + +static struct stm32_ltdc_layer_s g_ltdc_layer; +#endif + +/* The initalized state of the driver */ + +static bool g_initialized; + +/* Semaphore for interrupt handling */ + +static sem_t g_semirq; + +/* This structure provides irq handling */ + +static struct stm32_interrupt_s g_interrupt = +{ + .wait = false, + .handled = true, + .irq = STM32_IRQ_DMA2D, + .sem = &g_semirq +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dma2d_control + * + * Description: + * Change the DMA2D control register + * + * Parameter: + * setbits - The bits to set + * clrbits - The bits to clear + * + ****************************************************************************/ + +static void stm32_dma2d_control(uint32_t setbits, uint32_t clrbits) +{ + uint32_t cr; + + gvdbg("setbits=%08x, clrbits=%08x\n", setbits, clrbits); + + cr = getreg32(STM32_DMA2D_CR); + cr &= ~clrbits; + cr |= setbits; + putreg32(cr, STM32_DMA2D_CR); +} + +/**************************************************************************** + * Name: stm32_dma2dirq + * + * Description: + * DMA2D interrupt handler + * + ****************************************************************************/ + +static int stm32_dma2dirq(int irq, void *context) +{ + uint32_t regval = getreg32(STM32_DMA2D_ISR); + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + regvdbg("irq = %d, regval = %08x\n", irq, regval); + + if (regval & DMA2D_ISR_TCIF) + { + /* Transfer complete interrupt */ + + /* Clear the interrupt status register */ + + putreg32(DMA2D_IFCR_CTCIF, STM32_DMA2D_IFCR); + } +#ifdef CONFIG_STM32_DMA2D_L8 + else if (regval & DMA2D_ISR_CTCIF) + { + /* CLUT transfer complete interrupt */ + + /* Clear the interrupt status register */ + + putreg32(DMA2D_IFCR_CCTCIF, STM32_DMA2D_IFCR); + } +#endif + else + { + /* Unknown irq, should not occur */ + + return OK; + } + + /* Update the handled flag */ + + priv->handled = true; + + /* Unlock the semaphore if locked */ + + if (priv->wait) + { + + int ret = sem_post(priv->sem); + + if (ret != OK) + { + dbg("sem_post() failed\n"); + return ret; + } + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_dma2d_waitforirq + * + * Description: + * Helper waits until the dma2d irq occurs. That means that an ongoing clut + * loading or dma transfer was completed. + * Note! The caller must use this function within a critical section. + * + * Return: + * On success OK otherwise ERROR + * + ****************************************************************************/ + +static int stm32_dma2d_waitforirq(void) +{ + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + /* Only waits if last enabled interrupt is currently not handled */ + + if (!priv->handled) + { + int ret; + + /* Inform the irq handler the task is able to wait for the irq */ + + priv->wait = true; + + ret = sem_wait(priv->sem); + + /* irq or an error occurs, reset the wait flag */ + + priv->wait = false; + + if (ret != OK) + { + dbg("sem_wait() failed\n"); + return ret; + } + } + + return OK; +} + + +#ifdef CONFIG_STM32_DMA2D_L8 +/**************************************************************************** + * Name: stm32_dma2d_loadclut + * + * Description: + * Starts clut loading but doesn't wait until loading is complete! + * + * Parameter: + * pfcreg - PFC control Register + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2d_loadclut(uintptr_t pfcreg) +{ + int ret; + uint32_t regval; + irqstate_t flags; + + flags = enter_critical_section(); + + ret = stm32_dma2d_waitforirq(); + if (ret == OK) + { + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + /* Reset the handled flag */ + + priv->handled = false; + + /* Start clut loading */ + + regval = getreg32(pfcreg); + regval |= DMA2D_xGPFCCR_START; + regvdbg("set regval=%08x\n", regval); + putreg32(regval, pfcreg); + regvdbg("configured regval=%08x\n", getreg32(pfcreg)); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_dma2d_start + * + * Description: + * Starts the dma transfer and waits until completed. + * + * Parameter: + * reg - Register to set the start + * startflag - The related flag to start the dma transfer + * irqflag - The interrupt enable flag in the DMA2D_CR register + * + ****************************************************************************/ + +static int stm32_dma2d_start(void) +{ + int ret; + irqstate_t flags; + + flags = enter_critical_section(); + + ret = stm32_dma2d_waitforirq(); + if (ret == OK) + { + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + /* Reset the handled flag */ + + priv->handled = false; + + /* Start clut loading */ + + stm32_dma2d_control(DMA2D_CR_START, 0); + + /* wait until transfer is complete */ + + ret = stm32_dma2d_waitforirq(); + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_dma2d_memaddress + * + * Description: + * Helper to calculate the layer memory address + * + * Parameter: + * layer - Reference to the common layer state structure + * + * Return: + * memory address + * + ****************************************************************************/ + +static uint32_t stm32_dma2d_memaddress(FAR const struct stm32_dma2d_s *layer, + fb_coord_t xpos, fb_coord_t ypos) +{ + FAR const struct fb_planeinfo_s *pinfo = &layer->pinfo; + uint32_t offset; + + offset = xpos * DMA2D_PF_BYPP(layer->pinfo.bpp) + layer->pinfo.stride * ypos; + + gvdbg("%p\n", ((uint32_t) pinfo->fbmem) + offset); + return ((uint32_t) pinfo->fbmem) + offset; +} + +/**************************************************************************** + * Name: stm32_dma2d_lineoffset + * + * Description: + * Helper to calculate the layer line offset + * + * Parameter: + * layer - Reference to the common layer state structure + * + * Return: + * line offset + * + ****************************************************************************/ + +static fb_coord_t stm32_dma2d_lineoffset(FAR const struct stm32_dma2d_s *layer, + FAR const struct ltdc_area_s *area) +{ + /* offset at the end of each line in the context to the area layer */ + + gvdbg("%d\n", layer->vinfo.xres - area->xres); + return layer->vinfo.xres - area->xres; +} + +/**************************************************************************** + * Name: stm32_dma2d_pixelformat + * + * Description: + * Helper to map to dma2d controller pixel format + * + * Parameter: + * layer - Reference to the common layer state structure + * fmt - Reference to the location to store the pixel format + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2d_pixelformat(uint8_t fmt, uint8_t *fmtmap) +{ + gvdbg("fmt=%d, fmtmap=%p\n", fmt, fmtmap); + + /* Map to the controller known format + * + * Not supported by NuttX: + * ARGB8888 + * ARGB1555 + * ARGB4444 + * AL44 + * AL88 + * L8 (non output layer only) + * L4 + * A8 + * A4 + */ + + switch (fmt) + { +#ifdef CONFIG_STM32_DMA2D_RGB565 + case FB_FMT_RGB16_565: + *fmtmap = DMA2D_PF_RGB565; + break; +#endif +#ifdef CONFIG_STM32_DMA2D_RGB888 + case FB_FMT_RGB24: + *fmtmap = DMA2D_PF_RGB888; + break; +#endif +#ifdef CONFIG_STM32_DMA2D_L8 + case FB_FMT_RGB8: + *fmtmap = DMA2D_PF_L8; + break; +#endif + default: + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_dma2d_bpp + * + * Description: + * Helper to get the bits per pixel + * + * Parameter: + * layer - Reference to the common layer state structure + * bpp - Reference to the location to store the pixel format + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2d_bpp(uint8_t fmt, uint8_t *bpp) +{ + gvdbg("fmt=%d, bpp=%p\n", fmt, bpp); + + switch (fmt) + { +#ifdef CONFIG_STM32_DMA2D_RGB565 + case FB_FMT_RGB16_565: + *bpp = 16; + break; +#endif +#ifdef CONFIG_STM32_DMA2D_RGB888 + case FB_FMT_RGB24: + *bpp = 24; + break; +#endif +#ifdef CONFIG_STM32_DMA2D_L8 + case FB_FMT_RGB8: + *bpp = 8; + break; +#endif + default: + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_dma2d_lfreelid + * + * Description: + * Get a free layer id + * + * Return: + * The number of the free layer + * -1 if no free layer is available + * + ****************************************************************************/ + +static int stm32_dma2d_lfreelid(void) +{ + int n; + + for (n = DMA2D_SHADOW_LAYER; n < DMA2D_LAYER_NSIZE; n++) + { + if (g_layers[n] == NULL) + { + return n; + } + } + + return -1; +} + +/**************************************************************************** + * Name: stm32_dma2d_lalloc + * + * Description: + * Allocate a new layer structure + * + * Return: + * A new allocated layer structure or NULL on error. + * + ****************************************************************************/ + +static FAR struct stm32_dma2d_s * stm32_dma2d_lalloc(void) +{ + FAR struct stm32_dma2d_s *layer; + +#ifdef HAVE_CCM_HEAP + /* First try to allocate from the ccm heap */ + + layer = ccm_malloc(sizeof(struct stm32_dma2d_s)); + + if (!layer) + { + /* Use default allocator */ + + layer = kmm_malloc(sizeof(struct stm32_dma2d_s)); + } +#else + layer = kmm_malloc(sizeof(struct stm32_dma2d_s)); +#endif + + return layer; +} + +/**************************************************************************** + * Name: stm32_dma2d_lfree + * + * Description: + * Deallocate the dynamic allocated layer structure + * + * Input Parameters: + * A previous allocated layer structure + * + ****************************************************************************/ + +static void stm32_dma2d_lfree(FAR struct stm32_dma2d_s *layer) +{ + if (layer) + { +#ifdef HAVE_CCM_HEAP + if (((uint32_t)layer & 0xf0000000) == 0x10000000) + { + ccm_free(layer); + } + else + { + kmm_free(layer); + } +#else + kmm_free(layer); +#endif + } +} + +/**************************************************************************** + * Name: stm32_dma2d_llayerscleanup + * + * Description: + * Cleanup all allocated layers + * + ****************************************************************************/ + +static void stm32_dma2d_llayerscleanup(void) +{ + int n; + + /* Do not uninitialize the ltdc related dma2d layer */ + + for (n = DMA2D_SHADOW_LAYER; n < DMA2D_LAYER_NSIZE; n++) + { + FAR struct stm32_dma2d_s *priv = g_layers[n]; + if (priv) + { + kmm_free(priv->pinfo.fbmem); + stm32_dma2d_lfree(priv); + g_layers[n] = NULL; + } + } +} + +/**************************************************************************** + * Name: stm32_dma2d_lvalidate + * + * Description: + * Helper to validate if the layer is valid + * + * Return: + * true if validates otherwise false + * + ****************************************************************************/ + +static inline bool stm32_dma2d_lvalidate(FAR const struct stm32_dma2d_s *layer) +{ + return layer && layer->lid < DMA2D_LAYER_NSIZE; +} + +/**************************************************************************** + * Name: stm32_dma2d_lvalidatesize + * + * Description: + * Helper to check if area is outside the whole layer. + * + * Parameter: + * layer - Reference to the layer control structure + * xpos - The x position inside the whole layer + * ypos - The y position inside the whole layer + * area - the area inside the whole layer + * + * Return: + * true if area is inside the whole layer otherwise false + * + ****************************************************************************/ + +static bool stm32_dma2d_lvalidatesize(FAR const struct stm32_dma2d_s *layer, + fb_coord_t xpos, fb_coord_t ypos, + FAR const struct ltdc_area_s *area) +{ + return stm32_dma2d_lvalidate(layer) && + ((layer->vinfo.xres - xpos) * (layer->vinfo.yres - ypos) >= + area->xres * area->yres); +} + +/**************************************************************************** + * Name: stm32_dma2d_linit + * + * Description: + * Initialize the internal layer structure + * + * Parameter: + * + * + ****************************************************************************/ + +static void stm32_dma2d_linit(FAR struct stm32_dma2d_s *layer, + int lid, uint8_t fmt) +{ + FAR struct dma2d_layer_s *priv = &layer->dma2d; + + gvdbg("layer=%p, lid=%d, fmt=%02x\n", layer, lid, fmt); + + /* initialize the layer interface */ + + priv->getvideoinfo = stm32_dma2dgetvideoinfo; + priv->getplaneinfo = stm32_dma2dgetplaneinfo; + priv->getlid = stm32_dma2dgetlid; +#ifdef CONFIG_STM32_DMA2D_L8 + priv->setclut = stm32_dma2dsetclut; + priv->getclut = stm32_dma2dgetclut; +#endif + priv->setalpha = stm32_dma2dsetalpha; + priv->getalpha = stm32_dma2dgetalpha; + priv->setblendmode = stm32_dma2dsetblendmode; + priv->getblendmode = stm32_dma2dgetblendmode; + priv->blit = stm32_dma2dblit; + priv->blend = stm32_dma2dblend; + priv->fillarea = stm32_dma2dfillarea; + + /* Initialize the layer structure */ + + layer->lid = lid; +#ifdef CONFIG_STM32_DMA2D_L8 + layer->clut = 0; +#endif + layer->blendmode = DMA2D_BLEND_NONE; + layer->alpha = 255; + layer->fmt = fmt; + layer->lock = &g_lock; +} + +/**************************************************************************** + * Name: stm32_dma2d_lfifo + * + * Description: + * Set the fifo for the foreground, background and output layer + * Configures the memory address register + * Configures the line offset register + * + * Parameter: + * layer - Reference to the common layer state structure + * + ****************************************************************************/ + +static void stm32_dma2d_lfifo(FAR const struct stm32_dma2d_s *layer, int lid, + fb_coord_t xpos, fb_coord_t ypos, + FAR const struct ltdc_area_s *area) +{ + gvdbg("layer=%p, lid=%d, xpos=%d, ypos=%d, area=%p\n", + layer, lid, xpos, ypos, area); + + putreg32(stm32_dma2d_memaddress(layer, xpos, ypos), stm32_mar_layer_t[lid]); + putreg32(stm32_dma2d_lineoffset(layer, area), stm32_or_layer_t[lid]); +} + +/**************************************************************************** + * Name: stm32_dma2d_lcolor + * + * Description: + * Set the color for the layer + * + * Parameter: + * layer - Reference to the common layer state structure + * + ****************************************************************************/ + +static void stm32_dma2d_lcolor(FAR const struct stm32_dma2d_s *layer, + int lid, uint32_t color) +{ + gvdbg("layer=%p, lid=%d, color=%08x\n", layer, lid, color); + putreg32(color, stm32_color_layer_t[lid]); +} + +/**************************************************************************** + * Name: stm32_dma2d_llnr + * + * Description: + * Set the number of line register + * + * Parameter: + * layer - Reference to the common layer state structure + * area - Reference to the area to copy + * + ****************************************************************************/ + +static void stm32_dma2d_llnr(FAR struct stm32_dma2d_s *layer, + FAR const struct ltdc_area_s *area) +{ + uint32_t nlrreg; + + gvdbg("pixel per line: %d, number of lines: %d\n", area->xres, area->yres); + + nlrreg = getreg32(STM32_DMA2D_NLR); + nlrreg = (DMA2D_NLR_PL(area->xres) | DMA2D_NLR_NL(area->yres)); + putreg32(nlrreg, STM32_DMA2D_NLR); +} + +/**************************************************************************** + * Name: stm32_dma2d_loutpfc + * + * Description: + * Set the output PFC control register + * + * Parameter: + * layer - Reference to the common layer state structure + * + ****************************************************************************/ + +static int stm32_dma2d_loutpfc(FAR const struct stm32_dma2d_s *layer) +{ + gvdbg("layer=%p\n", layer); + + /* CLUT format isn't supported by the dma2d controller */ + + if (layer->fmt == DMA2D_PF_L8) + { + /* Destination layer doesn't support CLUT output */ + + gdbg("ERROR: Returning ENOSYS, " + "output to layer with CLUT format not supported.\n"); + return -ENOSYS; + } + + /* Set the mapped pixel format of source layer */ + + putreg32(DMA2D_OPFCCR_CM(layer->fmt), STM32_DMA2D_OPFCCR); + + return OK; +} + +/**************************************************************************** + * Name: stm32_dma2d_lpfc + * + * Description: + * Configure foreground and background layer PFC control register + * + * Parameter: + * layer - Reference to the common layer state structure + * + ****************************************************************************/ + +static void stm32_dma2d_lpfc(FAR const struct stm32_dma2d_s *layer, + int lid, uint32_t blendmode) +{ + uint32_t pfccrreg; + + gvdbg("layer=%p, lid=%d, blendmode=%08x\n", layer, lid, blendmode); + + /* Set color format */ + + pfccrreg = DMA2D_xGPFCCR_CM(layer->fmt); + +#ifdef CONFIG_STM32_DMA2D_L8 + if (layer->fmt == DMA2D_PF_L8) + { + /* Load CLUT automatically */ + + pfccrreg |= DMA2D_xGPFCCR_START; + + /* Set the CLUT color mode */ + +#ifndef CONFIG_FB_TRANSPARENCY + pfccrreg |= DMA2D_xGPFCCR_CCM; +#endif + + /* Set CLUT size */ + + pfccrreg |= DMA2D_xGPFCCR_CS(DMA2D_CLUT_SIZE); + + /* Set the CLUT memory address */ + + putreg32((uint32_t) layer->clut, stm32_cmar_layer_t[lid]); + + /* Start async clut loading */ + + stm32_dma2d_loadclut(stm32_pfccr_layer_t[lid]); + } +#endif + + if (blendmode & DMA2D_BLEND_NONE) + { + /* No blend operation */ + + pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_NONE); + } + else + { + /* Set alpha value */ + + pfccrreg |= DMA2D_xGPFCCR_ALPHA(layer->alpha); + + /* Set alpha mode */ + + if (layer->blendmode & DMA2D_BLEND_ALPHA) + { + /* Blend with constant alpha */ + + pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_CONST); + } + else if (layer->blendmode & DMA2D_BLEND_PIXELALPHA) + { + /* Blend with pixel alpha value */ + + pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_PIXEL); + } + } + + putreg32(pfccrreg, stm32_pfccr_layer_t[lid]); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dma2dgetvideoinfo + * + * Description: + * Get video information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * vinfo - Reference to the video info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetvideoinfo(FAR struct dma2d_layer_s *layer, + FAR struct fb_videoinfo_s *vinfo) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, vinfo=%p\n", layer, vinfo); + + if (stm32_dma2d_lvalidate(priv) && vinfo) + { + sem_wait(priv->lock); + memcpy(vinfo, &priv->vinfo, sizeof(struct fb_videoinfo_s)); + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: stm32_dma2dgetplaneinfo + * + * Description: + * Get plane information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * planeno - Number of the plane + * pinfo - Reference to the plane info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetplaneinfo(FAR struct dma2d_layer_s *layer, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, planeno=%d, pinfo=%p\n", layer, planeno, pinfo); + + if (stm32_dma2d_lvalidate(priv) && pinfo && planeno == 0) + { + sem_wait(priv->lock); + memcpy(pinfo, &priv->pinfo, sizeof(struct fb_planeinfo_s)); + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_dma2dgetlid + * + * Description: + * Get a specific layer identifier. + * + * Parameter: + * layer - Reference to the layer structure + * lid - Reference to store the layer id + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetlid(FAR struct dma2d_layer_s *layer, int *lid) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, lid=%p\n", layer, lid); + + if (stm32_dma2d_lvalidate(priv) && lid) + { + sem_wait(priv->lock); + *lid = priv->lid; + sem_post(priv->lock); + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +#ifdef CONFIG_STM32_DMA2D_L8 +/**************************************************************************** + * Name: stm32_dma2dsetclut + * + * Description: + * Configure layer clut (color lookup table). + * Non clut is defined during initializing. + * + * Parameter: + * layer - Reference to the layer structure + * cmap - color lookup table with up the 256 entries + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dsetclut(FAR struct dma2d_layer_s *layer, + const FAR struct fb_cmap_s *cmap) +{ + int ret; + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, cmap=%p\n", layer, cmap); + + if (stm32_dma2d_lvalidate(priv) && cmap) + { + sem_wait(priv->lock); + +#ifdef CONFIG_STM32_LTDC_INTERFACE + if (priv->lid < DMA2D_SHADOW_LAYER) + { + /* Update the shared color lookup table. + * + * Background: + * + * We share the same memory region of the clut table with the LTDC + * driver. (see stm32_dma2dinitltdc). This is important because any + * changes to the framebuffer and color lookup table by the ltdc + * related dma2d layer should also effects to the ltdc visibility, + * except operation settings, alpha and blendmode. + * + * But we can not only update the clut memory region. The LTDC driver + * also must update they own LTDC clut register to make the changes + * visible. Using the LTDC interface to update the clut table will + * also update the clut table of the related dma2d layer. + */ + + FAR struct ltdc_layer_s *ltdc = + g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L1].ltdc; + + ret = ltdc->setclut(ltdc, cmap); + + sem_post(priv->lock); + + return ret; + } +#endif + + if (priv->fmt != DMA2D_PF_L8) + { + gdbg("Error: CLUT is not supported for the pixel format: %d\n", + priv->vinfo.fmt); + ret = -EINVAL; + } + else if (cmap->first >= STM32_DMA2D_NCLUT) + { + gdbg("Error: only %d color table entries supported\n", + STM32_DMA2D_NCLUT); + ret = -EINVAL; + } + else + { + uint32_t *clut; + int n; + + clut = priv->clut; + + for (n = cmap->first; n < cmap->len && n < STM32_DMA2D_NCLUT; n++) + { + /* Update the layer clut entry */ + +#ifndef CONFIG_FB_TRANSPARENCY + uint8_t *clut888 = (uint8_t *)clut; + uint16_t offset = 3 * n; + + clut888[offset] = cmap->blue[n]; + clut888[offset + 1] = cmap->green[n]; + clut888[offset + 2] = cmap->red[n]; + + regvdbg("n=%d, red=%02x, green=%02x, blue=%02x\n", n, + clut888[offset], clut888[offset + 1], + clut888[offset + 2]); +#else + clut[n] = (uint32_t)DMA2D_CLUT_RED(cmap->transp[n]) | + (uint32_t)DMA2D_CLUT_GREEN(cmap->red[n]) | + (uint32_t)DMA2D_CLUT_GREEN(cmap->green[n]) | + (uint32_t)DMA2D_CLUT_BLUE(cmap->blue[n]); + + regvdbg("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n, + DMA2D_CLUT_ALPHA(cmap->alpha[n]), + DMA2D_CLUT_RED(cmap->red[n]), + DMA2D_CLUT_GREEN(cmap->green[n]), + DMA2D_CLUT_BLUE(cmap->blue[n])); +#endif + } + + + ret = OK; + } + + sem_post(priv->lock); + return ret; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_dma2dgetclut + * + * Description: + * Get configured layer clut (color lookup table). + * + * Parameter: + * layer - Reference to the layer structure + * cmap - Reference to valid color lookup table accept up the 256 color + * entries + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetclut(FAR struct dma2d_layer_s *layer, + FAR struct fb_cmap_s *cmap) +{ + int ret; + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, cmap=%p\n", layer, cmap); + + if (stm32_dma2d_lvalidate(priv) && cmap) + { + sem_wait(priv->lock); + + if (priv->fmt != DMA2D_PF_L8) + { + gdbg("Error: CLUT is not supported for the pixel format: %d\n", + priv->vinfo.fmt); + ret = -EINVAL; + } + else if (cmap->first >= STM32_DMA2D_NCLUT) + { + gdbg("Error: only %d color table entries supported\n", + STM32_DMA2D_NCLUT); + ret = -EINVAL; + } + else + { + /* Copy from the layer clut */ + + uint32_t *clut; + int n; + + clut = priv->clut; + + for (n = cmap->first; n < cmap->len && n < STM32_DMA2D_NCLUT; n++) + { +#ifndef CONFIG_FB_TRANSPARENCY + uint8_t *clut888 = (uint8_t *)clut; + uint16_t offset = 3 * n; + + cmap->blue[n] = clut888[offset]; + cmap->green[n] = clut888[offset + 1]; + cmap->red[n] = clut888[offset + 2]; + + regvdbg("n=%d, red=%02x, green=%02x, blue=%02x\n", n, + clut888[offset], clut888[offset + 1], + clut888[offset + 2]); +#else + cmap->transp[n] = (uint8_t)DMA2D_CMAP_ALPHA(clut[n]); + cmap->red[n] = (uint8_t)DMA2D_CMAP_RED(clut[n]); + cmap->green[n] = (uint8_t)DMA2D_CMAP_GREEN(clut[n]); + cmap->blue[n] = (uint8_t)DMA2D_CMAP_BLUE(clut[n]); + + regvdbg("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n, + DMA2D_CMAP_ALPHA(clut[n]), DMA2D_CMAP_RED(clut[n]), + DMA2D_CMAP_GREEN(clut[n]), DMA2D_CMAP_BLUE(clut[n])); +#endif + } + + ret = OK; + } + + sem_post(priv->lock); + + return ret; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: stm32_dma2dsetalpha + * + * Description: + * Configure layer alpha value factor into blend operation. + * During the layer blend operation the source alpha value is multiplied + * with this alpha value. If the source color format doesn't support alpha + * channel (e.g. non ARGB8888) this alpha value will be used as constant + * alpha value for blend operation. + * Default value during initializing: 0xff + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dsetalpha(FAR struct dma2d_layer_s *layer, uint8_t alpha) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, alpha=%02x\n", layer, alpha); + + if (stm32_dma2d_lvalidate(priv)) + { + sem_wait(priv->lock); + priv->alpha = alpha; + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_dma2dgetalpha + * + * Description: + * Get configured layer alpha value factor for blend operation. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Reference to store the alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetalpha(FAR struct dma2d_layer_s *layer, uint8_t *alpha) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, alpha=%p\n", layer, alpha); + + if (stm32_dma2d_lvalidate(priv)) + { + sem_wait(priv->lock); + *alpha = priv->alpha; + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_dma2dsetblendmode + * + * Description: + * Configure blend mode of the layer. + * Default mode during initializing: DMA2D_BLEND_NONE + * Blendmode is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Blend mode (see DMA2D_BLEND_*) + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure information: + * DMA2D_BLEND_NONE: + * Informs the driver to disable all blend operation for the given layer. + * That means the layer is opaque. + * + * DMA2D_BLEND_ALPHA: + * Informs the driver to enable alpha blending for the given layer. + * + * DMA2D_BLEND_PIXELALPHA: + * Informs the driver to use the pixel alpha value of the layer instead + * the constant alpha value. This is only useful for ARGB8888 + * color format. + * + ****************************************************************************/ + +static int stm32_dma2dsetblendmode(FAR struct dma2d_layer_s *layer, + uint32_t mode) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, mode=%08x\n", layer, mode); + + if (stm32_dma2d_lvalidate(priv)) + { + sem_wait(priv->lock); + priv->blendmode = mode; + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getblendmode + * + * Description: + * Get configured blend mode of the layer. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Reference to store the blend mode + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_dma2dgetblendmode(FAR struct dma2d_layer_s *layer, + uint32_t *mode) +{ + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, mode=%p\n", layer, mode); + + if (stm32_dma2d_lvalidate(priv) && mode) + { + sem_wait(priv->lock); + *mode = priv->blendmode; + sem_post(priv->lock); + + return OK; + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_dma2dblit + * + * Description: + * Copy selected area from a source layer to selected position of the + * destination layer. + * + * Parameter: + * dest - Valid reference to the destination layer + * destxpos - Valid selected x position of the destination layer + * destypos - Valid selected y position of the destination layer + * src - Valid reference to the source layer + * srcarea - Valid reference to the selected area of the source layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * -ECANCELED - Operation cancelled, something goes wrong. + * + ****************************************************************************/ + +static int stm32_dma2dblit(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea) +{ + uint32_t mode; + int ret; + FAR struct stm32_dma2d_s * destlayer = (FAR struct stm32_dma2d_s *)dest; + FAR struct stm32_dma2d_s * srclayer = (FAR struct stm32_dma2d_s *)src; + + gvdbg("dest=%p, destxpos=%d, destypos=%d, src=%p, srcarea=%p\n", + dest, destxpos, destypos, src, srcarea); + + if (stm32_dma2d_lvalidatesize(destlayer, destxpos, destypos, srcarea) && + stm32_dma2d_lvalidatesize(srclayer, srcarea->xpos, + srcarea->ypos, srcarea)) + { + sem_wait(destlayer->lock); + + /* Set output pfc */ + + ret = stm32_dma2d_loutpfc(destlayer); + + if (ret == OK) + { + /* Set foreground pfc */ + + stm32_dma2d_lpfc(srclayer, DMA2D_LAYER_LFORE, DMA2D_BLEND_NONE); + + /* Set foreground fifo */ + + stm32_dma2d_lfifo(srclayer, DMA2D_LAYER_LFORE, + srcarea->xpos, srcarea->ypos, srcarea); + + /* Set output fifo */ + + stm32_dma2d_lfifo(destlayer, DMA2D_LAYER_LOUT, + destxpos, destypos, srcarea); + + /* Set number of lines and pixel per line */ + + stm32_dma2d_llnr(destlayer, srcarea); + + /* Set dma2d mode for blit operation */ + + if (destlayer->fmt == srclayer->fmt) + { + /* Blit without pfc */ + + mode = STM32_DMA2D_CR_MODE_BLIT; + } + else + { + /* Blit with pfc */ + + mode = STM32_DMA2D_CR_MODE_BLITPFC; + } + + stm32_dma2d_control(mode, STM32_DMA2D_CR_MODE_CLEAR); + + /* Start DMA2D and wait until completed */ + + ret = stm32_dma2d_start(); + + if (ret != OK) + { + ret = -ECANCELED; + gdbg("ERROR: Returning ECANCELED\n"); + } + } + + sem_post(destlayer->lock); + } + else + { + ret = -EINVAL; + gdbg("ERROR: Returning EINVAL\n"); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_dma2dblend + * + * Description: + * Blends the selected area from a background layer with selected position + * of the foreground layer. Copies the result to the selected position of + * the destination layer. Note! The content of the foreground and background + * layer keeps unchanged as long destination layer is unequal to the + * foreground and background layer. + * + * Parameter: + * dest - Reference to the destination layer + * fore - Reference to the foreground layer + * forexpos - Selected x target position of the foreground layer + * foreypos - Selected y target position of the foreground layer + * back - Reference to the background layer + * backarea - Reference to the selected area of the background layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * -ECANCELED - Operation cancelled, something goes wrong. + * + ****************************************************************************/ + +static int stm32_dma2dblend(FAR struct dma2d_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea) +{ + int ret; + FAR struct stm32_dma2d_s * destlayer = (FAR struct stm32_dma2d_s *)dest; + FAR struct stm32_dma2d_s * forelayer = (FAR struct stm32_dma2d_s *)fore; + FAR struct stm32_dma2d_s * backlayer = (FAR struct stm32_dma2d_s *)back; + + gvdbg("dest=%p, destxpos=%d, destypos=%d, " + "fore=%p, forexpos=%d, foreypos=%d, " + "back=%p, backarea=%p\n", + dest, destxpos, destypos, fore, forexpos, foreypos, back, backarea); + + if (stm32_dma2d_lvalidatesize(destlayer, destxpos, destypos, backarea) && + stm32_dma2d_lvalidatesize(forelayer, forexpos, foreypos, backarea) && + stm32_dma2d_lvalidatesize(backlayer, backarea->xpos, + backarea->ypos, backarea)) + { + + sem_wait(destlayer->lock); + + /* Set output pfc */ + + ret = stm32_dma2d_loutpfc(destlayer); + + if (ret == OK) + { + /* Set background pfc */ + + stm32_dma2d_lpfc(backlayer, DMA2D_LAYER_LBACK, backlayer->blendmode); + + /* Set foreground pfc */ + + stm32_dma2d_lpfc(forelayer, DMA2D_LAYER_LFORE, forelayer->blendmode); + + /* Set background fifo */ + + stm32_dma2d_lfifo(backlayer, DMA2D_LAYER_LBACK, + backarea->xpos, backarea->ypos, backarea); + + /* Set foreground fifo */ + + stm32_dma2d_lfifo(forelayer, DMA2D_LAYER_LFORE, + forexpos, foreypos, backarea); + + /* Set output fifo */ + + stm32_dma2d_lfifo(destlayer, DMA2D_LAYER_LOUT, + destxpos, destypos, backarea); + + /* Set number of lines and pixel per line */ + + stm32_dma2d_llnr(destlayer, backarea); + + /* Set watermark */ + + /* Enable DMA2D blender */ + + stm32_dma2d_control(STM32_DMA2D_CR_MODE_BLEND, + STM32_DMA2D_CR_MODE_CLEAR); + + /* Start DMA2D and wait until completed */ + + ret = stm32_dma2d_start(); + + if (ret != OK) + { + ret = -ECANCELED; + gdbg("ERROR: Returning ECANCELED\n"); + } + } + + sem_post(destlayer->lock); + } + else + { + ret = -EINVAL; + gdbg("ERROR: Returning EINVAL\n"); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_dma2dfillarea + * + * Description: + * Fill the selected area of the whole layer with a specific color. + * + * Parameter: + * layer - Reference to the layer structure + * area - Reference to the valid area structure select the area + * color - Color to fill the selected area. Color must be formatted + * according to the layer pixel format. + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * area outside the visible area of the layer. + * -ECANCELED - Operation cancelled, something goes wrong. + * + ****************************************************************************/ + +static int stm32_dma2dfillarea(FAR struct dma2d_layer_s *layer, + FAR const struct ltdc_area_s *area, + uint32_t color) +{ + int ret; + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + gvdbg("layer=%p, area=%p, color=%08x\n", layer, area, color); + + if (stm32_dma2d_lvalidatesize(priv, area->xpos, area->ypos, area)) + { + + sem_wait(priv->lock); + + /* Set output pfc */ + + ret = stm32_dma2d_loutpfc(priv); + + if (ret == OK) + { + /* Set output fifo */ + + stm32_dma2d_lfifo(priv, DMA2D_LAYER_LOUT, + area->xpos, area->ypos, area); + + /* Set the output color register */ + + stm32_dma2d_lcolor(priv, DMA2D_LAYER_LOUT, color); + + /* Set number of lines and pixel per line */ + + stm32_dma2d_llnr(priv, area); + + /* Set register to memory transfer */ + + stm32_dma2d_control(STM32_DMA2D_CR_MODE_COLOR, + STM32_DMA2D_CR_MODE_CLEAR); + + /* Start DMA2D and wait until completed */ + + ret = stm32_dma2d_start(); + + if (ret != OK) + { + ret = -ECANCELED; + gdbg("ERROR: Returning ECANCELED\n"); + } + } + + sem_post(priv->lock); + } + else + { + ret = -EINVAL; + gdbg("ERROR: Returning EINVAL\n"); + } + + return ret; +} + +/**************************************************************************** + * Name: up_dma2dgetlayer + * + * Description: + * Get a dma2d layer structure by the layer identifier + * + * Parameter: + * lid - Layer identifier + * + * Return: + * Reference to the dma2d layer control structure on success or Null if no + * related exist. + * + ****************************************************************************/ + +FAR struct dma2d_layer_s * up_dma2dgetlayer(int lid) +{ + if (lid < DMA2D_LAYER_NSIZE) + { + FAR struct stm32_dma2d_s *priv; + sem_wait(&g_lock); + priv = g_layers[lid]; + sem_post(&g_lock); + + return &priv->dma2d; + } + + gdbg("ERROR: EINVAL, Unknown layer identifier\n"); + errno = EINVAL; + return NULL; +} + +/**************************************************************************** + * Name: up_dma2dcreatelayer + * + * Description: + * Create a new dma2d layer object to interact with the dma2d controller + * + * Parameter: + * width - Layer width + * height - Layer height + * fmt - Pixel format of the layer + * + * Return: + * On success - A valid dma2d layer reference + * On error - NULL and errno is set to + * -EINVAL if one of the parameter is invalid + * -ENOMEM if no memory available or exceeds + * CONFIG_STM32_DMA2D_NLAYERS + * + ****************************************************************************/ + +FAR struct dma2d_layer_s *up_dma2dcreatelayer(fb_coord_t width, + fb_coord_t height, + uint8_t fmt) +{ + int ret; + int lid; + uint8_t fmtmap; + uint8_t bpp = 0; + FAR struct stm32_dma2d_s *layer = NULL; + + gvdbg("width=%d, height=%d, fmt=%02x \n", width, height, fmt); + + /* Validate if pixel format supported */ + + ret = stm32_dma2d_pixelformat(fmt, &fmtmap); + + if (ret != OK) + { + errno = -ret; + return NULL; + } + + ret = stm32_dma2d_bpp(fmt, &bpp); + + sem_wait(&g_lock); + + /* Get a free layer identifier */ + + lid = stm32_dma2d_lfreelid(); + + if (lid >= 0) + { + layer = stm32_dma2d_lalloc(); + + if (layer) + { + uint32_t fblen; + void *fbmem; + fb_coord_t stride; + + /* Stride calculation for the supported formats */ + + stride = width * bpp / 8; + + /* Calculate buffer size */ + + fblen = stride * height; + + /* Allocate 32-bit aligned memory for the layer buffer. As reported in + * mm_memalign 8-byte alignment is guaranteed by normal malloc calls. + * We have also ensure memory is allocated from the SRAM1/2/3 block. + * The CCM block is only accessible through the D-BUS but not by + * the AHB-BUS. Ensure that CONFIG_STM32_CCMEXCLUDE is set! + */ + + fbmem = kmm_zalloc(fblen); + + if (fbmem) + { + FAR struct fb_videoinfo_s *vinfo = &layer->vinfo; + FAR struct fb_planeinfo_s *pinfo = &layer->pinfo; + + /* Initialize dma2d structure */ + + stm32_dma2d_linit(layer, lid, fmtmap); + + /* Initialize the videoinfo structure */ + + vinfo->fmt = fmt; + vinfo->xres = width; + vinfo->yres = height; + vinfo->nplanes = 1; + + /* Initialize the planeinfo structure */ + + pinfo->fbmem = fbmem; + pinfo->fblen = fblen; + pinfo->stride = stride; + pinfo->bpp = bpp; + + /* Bind the layer to the identifier */ + + g_layers[lid] = layer; + } + else + { + /* free the layer struture */ + + kmm_free(layer); + gdbg("ERROR: ENOMEM, Unable to allocate layer buffer\n"); + errno = ENOMEM; + } + } + else + { + gdbg("ERROR: ENOMEM, unable to allocate layer structure\n"); + errno = ENOMEM; + } + } + else + { + gdbg("ERROR: EINVAL, no free layer available\n"); + errno = EINVAL; + } + + sem_post(&g_lock); + return (FAR struct dma2d_layer_s *)layer; +} + +/**************************************************************************** + * Name: up_dma2dremovelayer + * + * Description: + * Remove and deallocate the dma2d layer + * + * Parameter: + * layer - Reference to the layer to remove + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +int up_dma2dremovelayer(FAR struct dma2d_layer_s *layer) +{ + int ret = -EINVAL; + FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer; + + /* Check if the layer is valid and unlike a ltdc related layer */ + + if (stm32_dma2d_lvalidate(priv) && priv->lid >= DMA2D_SHADOW_LAYER) + { + sem_wait(priv->lock); + + /* Check also if the layer id is valid to the layer reference */ + + if (priv == g_layers[priv->lid]) + { + int lid = priv->lid; + + kmm_free(priv->pinfo.fbmem); + stm32_dma2d_lfree(priv); + + g_layers[lid] = NULL; + ret = OK; + } + + sem_post(priv->lock); + } + + return ret; +} + +/**************************************************************************** + * Name: up_dma2dinitialize + * + * Description: + * Initialize the dma2d controller + * + * Return: + * OK - On success + * An error if initializing failed. + * + ****************************************************************************/ + +int up_dma2dinitialize(void) +{ + dbg("Initialize DMA2D driver\n"); + + if (g_initialized == false) + { + /* Abort current dma2d data transfer */ + + up_dma2duninitialize(); + + /* Enable dma2d is done in rcc_enableahb1, see + * arch/arm/src/stm32/stm32f40xxx_rcc.c + */ + + /* Initialize the DMA2D semaphore that enforces mutually exclusive access + * to the driver + */ + + sem_init(&g_lock, 0, 1); + + /* Initialize the semaphore for interrupt handling */ + + sem_init(g_interrupt.sem, 0, 0); + +#ifdef CONFIG_STM32_DMA2D_L8 + /* Enable dma2d transfer and clut loading interrupts only */ + + stm32_dma2d_control(DMA2D_CR_TCIE | DMA2D_CR_CTCIE, DMA2D_CR_TEIE | + DMA2D_CR_TWIE | DMA2D_CR_CAEIE | DMA2D_CR_CEIE); +#else + /* Enable dma transfer interrupt only */ + + stm32_dma2d_control(DMA2D_CR_TCIE, DMA2D_CR_TEIE | DMA2D_CR_TWIE | + DMA2D_CR_CAEIE | DMA2D_CR_CTCIE | DMA2D_CR_CEIE); +#endif + + /* Attach DMA2D interrupt vector */ + + (void)irq_attach(g_interrupt.irq, stm32_dma2dirq); + + /* Enable the IRQ at the NVIC */ + + up_enable_irq(g_interrupt.irq); + + /* Initialize the dma2d layer for ltdc binding */ + +#ifdef DMA2D_SHADOW_LAYER_L1 + g_layers[DMA2D_SHADOW_LAYER_L1] = + &g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L1].dma2ddev; +#endif +#ifdef DMA2D_SHADOW_LAYER_L2 + g_layers[DMA2D_SHADOW_LAYER_L2] = + &g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L2].dma2ddev; +#endif + /* Set initialized state */ + + g_initialized = true; + } + + return OK; +} + +/**************************************************************************** + * Name: up_dma2duninitialize + * + * Description: + * Uninitialize the dma2d controller + * + ****************************************************************************/ + +void up_dma2duninitialize(void) +{ + /* Disable DMA2D interrupts */ + + up_disable_irq(g_interrupt.irq); + irq_detach(g_interrupt.irq); + + /* Cleanup all layers */ + + stm32_dma2d_llayerscleanup(); + + /* Abort current dma2d transfer */ + + stm32_dma2d_control(DMA2D_CR_ABORT, 0); + + /* Set initialized state */ + + g_initialized = false; +} + +#ifdef CONFIG_STM32_LTDC_INTERFACE +/**************************************************************************** + * Name: stm32_dma2dinitltdc + * + * Description: + * Get a reference to the dma2d layer coupled with the ltdc layer. + * It not intends to use this by user space applications. + * It resolves the following requirements: + * 1. Share the color lookup table + * 2. Share the planeinfo information + * 3. Share the videoinfo information + * + * Parameter: + * layer - a valid reference to the low level ltdc layer structure + * clut - a pointer to a valid memory region to hold 256 clut colors + * + * Return: + * On success - A valid dma2d layer reference + * On error - NULL and errno is set to + * -EINVAL if one of the parameter is invalid + * + ****************************************************************************/ + +FAR struct dma2d_layer_s * stm32_dma2dinitltdc(FAR struct stm32_ltdc_s *layer) +{ + int ret; + uint8_t fmt = 0; + FAR struct stm32_ltdc_dma2d_s *priv; + + gvdbg("layer=%p\n", layer); + DEBUGASSERT(layer && layer->lid >= 0 && layer->lid < DMA2D_SHADOW_LAYER); + + ret = stm32_dma2d_pixelformat(layer->vinfo.fmt, &fmt); + + if (ret != OK) + { + dbg("Returning -EINVAL, unsupported pixel format: %d\n", + layer->vinfo.fmt); + errno = -EINVAL; + return NULL; + } + + priv = &g_ltdc_layer.layer[layer->lid]; + + stm32_dma2d_linit(&priv->dma2ddev, layer->lid, fmt); + + memcpy(&priv->dma2ddev.vinfo, &layer->vinfo, sizeof(struct fb_videoinfo_s)); + memcpy(&priv->dma2ddev.pinfo, &layer->pinfo, sizeof(struct fb_planeinfo_s)); + +#ifdef CONFIG_STM32_DMA2D_L8 + /* Verifies that the ltdc layer has a clut. This ensures that DMA2D driver can + * support clut format but the LTDC driver does not and vice versa. + */ + + if (layer->vinfo.fmt == FB_FMT_RGB8) + { + priv->dma2ddev.clut = layer->clut; + priv->ltdc = stm32_ltdcgetlayer(layer->lid); + DEBUGASSERT(priv->ltdc != NULL); + } +#endif + + return &priv->dma2ddev.dma2d; +} +#endif /* CONFIG_STM32_LTDC_INTERFACE */ diff --git a/arch/arm/src/stm32/stm32_dma2d.h b/arch/arm/src/stm32/stm32_dma2d.h new file mode 100644 index 0000000000000000000000000000000000000000..7755ffe39d3653cc94616e0481771f8ac2b7e741 --- /dev/null +++ b/arch/arm/src/stm32/stm32_dma2d.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_dma2d.h + * + * Copyright (C) 2014-2015 Marco Krahl. All rights reserved. + * Author: Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_DMA2D_H +#define __ARCH_ARM_SRC_STM32_STM32_DMA2D_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_STM32_DMA2D +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +# ifdef CONFIG_STM32_LTDC_INTERFACE +/**************************************************************************** + * Name: stm32_dma2dinitltdc + * + * Description: + * Get a reference to the dma2d layer coupled with the ltdc layer. + * It not intends to use this function by user space applications. + * It resolves the following requirements: + * 1. Share the color lookup table + * 2. Share the planeinfo information + * 3. Share the videoinfo information + * + * Parameter: + * layer - a valid reference to the low level ltdc layer structure + * + * Return: + * On success - A valid dma2d layer reference + * On error - NULL and errno is set to + * -EINVAL if one of the parameter is invalid + * + ****************************************************************************/ + +FAR struct dma2d_layer_s * stm32_dma2dinitltdc(FAR struct stm32_ltdc_s *layer); +# endif /* CONFIG_STM32_LTDC_INTERFACE */ + +#endif /* CONFIG_STM32_DMA2D */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_DMA2D_H */ diff --git a/arch/arm/src/stm32/stm32_dumpgpio.c b/arch/arm/src/stm32/stm32_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..77d49ffa084d67a2ce431536d5ca47d79883e39d --- /dev/null +++ b/arch/arm/src/stm32/stm32_dumpgpio.c @@ -0,0 +1,241 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_gpio.c + * + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Port letters for prettier debug output */ + +#ifdef CONFIG_DEBUG +static const char g_portchar[STM32_NGPIO_PORTS] = +{ +#if STM32_NGPIO_PORTS > 11 +# error "Additional support required for this number of GPIOs" +#elif STM32_NGPIO_PORTS > 10 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' +#elif STM32_NGPIO_PORTS > 9 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' +#elif STM32_NGPIO_PORTS > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif STM32_NGPIO_PORTS > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif STM32_NGPIO_PORTS > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif STM32_NGPIO_PORTS > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif STM32_NGPIO_PORTS > 4 + 'A', 'B', 'C', 'D', 'E' +#elif STM32_NGPIO_PORTS > 3 + 'A', 'B', 'C', 'D' +#elif STM32_NGPIO_PORTS > 2 + 'A', 'B', 'C' +#elif STM32_NGPIO_PORTS > 1 + 'A', 'B' +#elif STM32_NGPIO_PORTS > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int stm32_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uint32_t base; + unsigned int port; + + /* Get the base address associated with the GPIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + +#if defined(CONFIG_STM32_STM32F10XX) + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + if ((getreg32(STM32_RCC_APB2ENR) & RCC_APB2ENR_IOPEN(port)) != 0) + { + lldbg(" CR: %08x %08x IDR: %04x ODR: %04x LCKR: %04x\n", + getreg32(base + STM32_GPIO_CRH_OFFSET), + getreg32(base + STM32_GPIO_CRL_OFFSET), + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + lldbg(" EVCR: %02x MAPR: %08x CR: %04x %04x %04x %04x\n", + getreg32(STM32_AFIO_EVCR), getreg32(STM32_AFIO_MAPR), + getreg32(STM32_AFIO_EXTICR1), + getreg32(STM32_AFIO_EXTICR2), + getreg32(STM32_AFIO_EXTICR3), + getreg32(STM32_AFIO_EXTICR4)); + } + else + { + lldbg(" GPIO%c not enabled: APB2ENR: %08x\n", + g_portchar[port], getreg32(STM32_RCC_APB2ENR)); + } + +#elif defined(CONFIG_STM32_STM32L15XX) + + DEBUGASSERT(port < STM32_NGPIO_PORTS); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + if ((getreg32(STM32_RCC_AHBENR) & RCC_AHBENR_GPIOEN(port)) != 0) + { + lldbg(" MODE: %08x OTYPE: %04x OSPEED: %08x PUPDR: %08x\n", + getreg32(base + STM32_GPIO_MODER_OFFSET), + getreg32(base + STM32_GPIO_OTYPER_OFFSET), + getreg32(base + STM32_GPIO_OSPEED_OFFSET), + getreg32(base + STM32_GPIO_PUPDR_OFFSET)); + lldbg(" IDR: %04x ODR: %04x BSRR: %08x LCKR: %04x\n", + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_BSRR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + lldbg(" AFRH: %08x AFRL: %08x\n", + getreg32(base + STM32_GPIO_AFRH_OFFSET), + getreg32(base + STM32_GPIO_AFRL_OFFSET)); + } + else + { + lldbg(" GPIO%c not enabled: AHBENR: %08x\n", + g_portchar[port], getreg32(STM32_RCC_AHBENR)); + } + +#elif defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) + + DEBUGASSERT(port < STM32_NGPIO_PORTS); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + /* GPIOs are always enabled */ + + lldbg(" MODE: %08x OTYPE: %04x OSPEED: %08x PUPDR: %08x\n", + getreg32(base + STM32_GPIO_MODER_OFFSET), + getreg32(base + STM32_GPIO_OTYPER_OFFSET), + getreg32(base + STM32_GPIO_OSPEED_OFFSET), + getreg32(base + STM32_GPIO_PUPDR_OFFSET)); + lldbg(" IDR: %04x ODR: %04x BSRR: %08x LCKR: %04x\n", + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_BSRR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + lldbg(" AFRH: %08x AFRL: %08x BRR: %04x\n", + getreg32(base + STM32_GPIO_AFRH_OFFSET), + getreg32(base + STM32_GPIO_AFRL_OFFSET), + getreg32(base + STM32_GPIO_BRR_OFFSET)); + +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + + DEBUGASSERT(port < STM32_NGPIO_PORTS); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + if ((getreg32(STM32_RCC_AHB1ENR) & RCC_AHB1ENR_GPIOEN(port)) != 0) + { + lldbg(" MODE: %08x OTYPE: %04x OSPEED: %08x PUPDR: %08x\n", + getreg32(base + STM32_GPIO_MODER_OFFSET), + getreg32(base + STM32_GPIO_OTYPER_OFFSET), + getreg32(base + STM32_GPIO_OSPEED_OFFSET), + getreg32(base + STM32_GPIO_PUPDR_OFFSET)); + lldbg(" IDR: %04x ODR: %04x BSRR: %08x LCKR: %04x\n", + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_BSRR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + lldbg(" AFRH: %08x AFRL: %08x\n", + getreg32(base + STM32_GPIO_AFRH_OFFSET), + getreg32(base + STM32_GPIO_AFRL_OFFSET)); + } + else + { + lldbg(" GPIO%c not enabled: AHB1ENR: %08x\n", + g_portchar[port], getreg32(STM32_RCC_AHB1ENR)); + } +#else +# error "Unsupported STM32 chip" +#endif + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/stm32/stm32_eth.c b/arch/arm/src/stm32/stm32_eth.c new file mode 100644 index 0000000000000000000000000000000000000000..7b06b9a3680d296a6e3d254d3aa2d02bcdf320e8 --- /dev/null +++ b/arch/arm/src/stm32/stm32_eth.c @@ -0,0 +1,4211 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_eth.c + * + * Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_STM32_ETHMAC) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#if defined(CONFIG_NET_PKT) +# include +#endif + +#include "up_internal.h" + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" +#include "stm32_syscfg.h" +#include "stm32_eth.h" + +#include + +/* STM32_NETHERNET determines the number of physical interfaces + * that will be supported. + */ + +#if STM32_NETHERNET > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* See configs/stm3240g-eval/README.txt for an explanation of the configuration + * settings. + */ + +#if STM32_NETHERNET > 1 +# error "Logic to support multiple Ethernet interfaces is incomplete" +#endif + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +#if !defined(CONFIG_STM32_SYSCFG) && !defined(CONFIG_STM32_CONNECTIVITYLINE) +# error "CONFIG_STM32_SYSCFG must be defined in the NuttX configuration" +#endif + +#ifndef CONFIG_STM32_PHYADDR +# error "CONFIG_STM32_PHYADDR must be defined in the NuttX configuration" +#endif + +#if !defined(CONFIG_STM32_MII) && !defined(CONFIG_STM32_RMII) +# warning "Neither CONFIG_STM32_MII nor CONFIG_STM32_RMII defined" +#endif + +#if defined(CONFIG_STM32_MII) && defined(CONFIG_STM32_RMII) +# error "Both CONFIG_STM32_MII and CONFIG_STM32_RMII defined" +#endif + +#ifdef CONFIG_STM32_MII +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# if !defined(CONFIG_STM32_MII_MCO1) && !defined(CONFIG_STM32_MII_MCO2) && !defined(CONFIG_STM32_MII_EXTCLK) +# warning "Neither CONFIG_STM32_MII_MCO1, CONFIG_STM32_MII_MCO2, nor CONFIG_STM32_MII_EXTCLK defined" +# endif +# if defined(CONFIG_STM32_MII_MCO1) && defined(CONFIG_STM32_MII_MCO2) +# error "Both CONFIG_STM32_MII_MCO1 and CONFIG_STM32_MII_MCO2 defined" +# endif +# elif defined(CONFIG_STM32_CONNECTIVITYLINE) +# if !defined(CONFIG_STM32_MII_MCO) && !defined(CONFIG_STM32_MII_EXTCLK) +# warning "Neither CONFIG_STM32_MII_MCO nor CONFIG_STM32_MII_EXTCLK defined" +# endif +# endif +#endif + +#ifdef CONFIG_STM32_RMII +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# if !defined(CONFIG_STM32_RMII_MCO1) && !defined(CONFIG_STM32_RMII_MCO2) && !defined(CONFIG_STM32_RMII_EXTCLK) +# warning "Neither CONFIG_STM32_RMII_MCO1, CONFIG_STM32_RMII_MCO2, nor CONFIG_STM32_RMII_EXTCLK defined" +# endif +# if defined(CONFIG_STM32_RMII_MCO1) && defined(CONFIG_STM32_RMII_MCO2) +# error "Both CONFIG_STM32_RMII_MCO1 and CONFIG_STM32_RMII_MCO2 defined" +# endif +# elif defined(CONFIG_STM32_CONNECTIVITYLINE) +# if !defined(CONFIG_STM32_RMII_MCO) && !defined(CONFIG_STM32_RMII_EXTCLK) +# warning "Neither CONFIG_STM32_RMII_MCO nor CONFIG_STM32_RMII_EXTCLK defined" +# endif +# endif +#endif + +#ifdef CONFIG_STM32_AUTONEG +# ifndef CONFIG_STM32_PHYSR +# error "CONFIG_STM32_PHYSR must be defined in the NuttX configuration" +# endif +# ifdef CONFIG_STM32_PHYSR_ALTCONFIG +# ifndef CONFIG_STM32_PHYSR_ALTMODE +# error "CONFIG_STM32_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_10HD +# error "CONFIG_STM32_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_100HD +# error "CONFIG_STM32_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_10FD +# error "CONFIG_STM32_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_100FD +# error "CONFIG_STM32_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_STM32_PHYSR_SPEED +# error "CONFIG_STM32_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_100MBPS +# error "CONFIG_STM32_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_MODE +# error "CONFIG_STM32_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32_PHYSR_FULLDUPLEX +# error "CONFIG_STM32_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +#endif + +#ifdef CONFIG_STM32_ETH_PTP +# warning "CONFIG_STM32_ETH_PTP is not yet supported" +#endif + +/* This driver does not use enhanced descriptors. Enhanced descriptors must + * be used, however, if time stamping or and/or IPv4 checksum offload is + * supported. + */ + +#undef CONFIG_STM32_ETH_ENHANCEDDESC +#undef CONFIG_STM32_ETH_HWCHECKSUM + +/* Ethernet buffer sizes, number of buffers, and number of descriptors */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER is required" +#endif + +/* Add 4 to the configured buffer size to account for the 2 byte checksum + * memory needed at the end of the maximum size packet. Buffer sizes must + * be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We + * will use the 16-byte alignment in all cases. + */ + +#define OPTIMAL_ETH_BUFSIZE ((CONFIG_NET_ETH_MTU + 4 + 15) & ~15) + +#ifndef CONFIG_STM32_ETH_BUFSIZE +# define CONFIG_STM32_ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE +#endif + +#if CONFIG_STM32_ETH_BUFSIZE > ETH_TDES1_TBS1_MASK +# error "CONFIG_STM32_ETH_BUFSIZE is too large" +#endif + +#if (CONFIG_STM32_ETH_BUFSIZE & 15) != 0 +# error "CONFIG_STM32_ETH_BUFSIZE must be aligned" +#endif + +#if CONFIG_STM32_ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE +# warning "You using an incomplete/untested configuration" +#endif + +#ifndef CONFIG_STM32_ETH_NRXDESC +# define CONFIG_STM32_ETH_NRXDESC 8 +#endif +#ifndef CONFIG_STM32_ETH_NTXDESC +# define CONFIG_STM32_ETH_NTXDESC 4 +#endif + +/* We need at least one more free buffer than transmit buffers */ + +#define STM32_ETH_NFREEBUFFERS (CONFIG_STM32_ETH_NTXDESC+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_STM32_ETHMAC_REGDEBUG +#endif + +/* Clocking *****************************************************************/ +/* Set MACMIIAR CR bits depending on HCLK setting */ + +#if STM32_HCLK_FREQUENCY >= 20000000 && STM32_HCLK_FREQUENCY < 35000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_20_35 +#elif STM32_HCLK_FREQUENCY >= 35000000 && STM32_HCLK_FREQUENCY < 60000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_35_60 +#elif STM32_HCLK_FREQUENCY >= 60000000 && STM32_HCLK_FREQUENCY < 100000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_60_100 +#elif STM32_HCLK_FREQUENCY >= 100000000 && STM32_HCLK_FREQUENCY < 150000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_100_150 +#elif STM32_HCLK_FREQUENCY >= 150000000 && STM32_HCLK_FREQUENCY <= 180000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_150_180 +#else +# error "STM32_HCLK_FREQUENCY not supportable" +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define STM32_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define STM32_TXTIMEOUT (60*CLK_TCK) + +/* PHY reset/configuration delays in milliseconds */ + +#define PHY_RESET_DELAY (65) +#define PHY_CONFIG_DELAY (1000) + +/* PHY read/write delays in loop counts */ + +#define PHY_READ_TIMEOUT (0x0004ffff) +#define PHY_WRITE_TIMEOUT (0x0004ffff) +#define PHY_RETRY_TIMEOUT (0x0004ffff) + +/* Register values **********************************************************/ + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACCR_RE Bit 2: Receiver enable + * ETH_MACCR_TE Bit 3: Transmitter enable + * ETH_MACCR_DC Bit 4: Deferral check + * ETH_MACCR_BL Bits 5-6: Back-off limit + * ETH_MACCR_APCS Bit 7: Automatic pad/CRC stripping + * ETH_MACCR_RD Bit 9: Retry disable + * ETH_MACCR_IPCO Bit 10: IPv4 checksum offload + * ETH_MACCR_DM Bit 11: Duplex mode + * ETH_MACCR_LM Bit 12: Loopback mode + * ETH_MACCR_ROD Bit 13: Receive own disable + * ETH_MACCR_FES Bit 14: Fast Ethernet speed + * ETH_MACCR_CSD Bit 16: Carrier sense disable + * ETH_MACCR_IFG Bits 17-19: Interframe gap + * ETH_MACCR_JD Bit 22: Jabber disable + * ETH_MACCR_WD Bit 23: Watchdog disable + * ETH_MACCR_CSTF Bits 25: CRC stripping for Type frames (F2/F4 only) + */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +#define MACCR_CLEAR_BITS \ + (ETH_MACCR_RE | ETH_MACCR_TE | ETH_MACCR_DC | ETH_MACCR_BL_MASK | \ + ETH_MACCR_APCS | ETH_MACCR_RD | ETH_MACCR_IPCO | ETH_MACCR_DM | \ + ETH_MACCR_LM | ETH_MACCR_ROD | ETH_MACCR_FES | ETH_MACCR_CSD | \ + ETH_MACCR_IFG_MASK | ETH_MACCR_JD | ETH_MACCR_WD | ETH_MACCR_CSTF) +#else +#define MACCR_CLEAR_BITS \ + (ETH_MACCR_RE | ETH_MACCR_TE | ETH_MACCR_DC | ETH_MACCR_BL_MASK | \ + ETH_MACCR_APCS | ETH_MACCR_RD | ETH_MACCR_IPCO | ETH_MACCR_DM | \ + ETH_MACCR_LM | ETH_MACCR_ROD | ETH_MACCR_FES | ETH_MACCR_CSD | \ + ETH_MACCR_IFG_MASK | ETH_MACCR_JD | ETH_MACCR_WD) +#endif + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACCR_RE Receiver enable 0 (disabled) + * ETH_MACCR_TE Transmitter enable 0 (disabled) + * ETH_MACCR_DC Deferral check 0 (disabled) + * ETH_MACCR_BL Back-off limit 0 (10) + * ETH_MACCR_APCS Automatic pad/CRC stripping 0 (disabled) + * ETH_MACCR_RD Retry disable 1 (disabled) + * ETH_MACCR_IPCO IPv4 checksum offload Depends on CONFIG_STM32_ETH_HWCHECKSUM + * ETH_MACCR_LM Loopback mode 0 (disabled) + * ETH_MACCR_ROD Receive own disable 0 (enabled) + * ETH_MACCR_CSD Carrier sense disable 0 (enabled) + * ETH_MACCR_IFG Interframe gap 0 (96 bits) + * ETH_MACCR_JD Jabber disable 0 (enabled) + * ETH_MACCR_WD Watchdog disable 0 (enabled) + * ETH_MACCR_CSTF CRC stripping for Type frames 0 (disabled, F2/F4 only) + * + * The following are set conditioinally based on mode and speed. + * + * ETH_MACCR_DM Duplex mode Depends on priv->fduplex + * ETH_MACCR_FES Fast Ethernet speed Depends on priv->mbps100 + */ + +#ifdef CONFIG_STM32_ETH_HWCHECKSUM +# define MACCR_SET_BITS \ + (ETH_MACCR_BL_10 | ETH_MACCR_RD | ETH_MACCR_IPCO | ETH_MACCR_IFG(96)) +#else +# define MACCR_SET_BITS \ + (ETH_MACCR_BL_10 | ETH_MACCR_RD | ETH_MACCR_IFG(96)) +#endif + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFFR_PM Bit 0: Promiscuous mode + * ETH_MACFFR_HU Bit 1: Hash unicast + * ETH_MACFFR_HM Bit 2: Hash multicast + * ETH_MACFFR_DAIF Bit 3: Destination address inverse filtering + * ETH_MACFFR_PAM Bit 4: Pass all multicast + * ETH_MACFFR_BFD Bit 5: Broadcast frames disable + * ETH_MACFFR_PCF Bits 6-7: Pass control frames + * ETH_MACFFR_SAIF Bit 8: Source address inverse filtering + * ETH_MACFFR_SAF Bit 9: Source address filter + * ETH_MACFFR_HPF Bit 10: Hash or perfect filter + * ETH_MACFFR_RA Bit 31: Receive all + */ + +#define MACFFR_CLEAR_BITS \ + (ETH_MACFFR_PM | ETH_MACFFR_HU | ETH_MACFFR_HM | ETH_MACFFR_DAIF | \ + ETH_MACFFR_PAM | ETH_MACFFR_BFD | ETH_MACFFR_PCF_MASK | ETH_MACFFR_SAIF | \ + ETH_MACFFR_SAF | ETH_MACFFR_HPF | ETH_MACFFR_RA) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFFR_PM Promiscuous mode 0 (disabled) + * ETH_MACFFR_HU Hash unicast 0 (perfect dest filtering) + * ETH_MACFFR_HM Hash multicast 0 (perfect dest filtering) + * ETH_MACFFR_DAIF Destination address inverse filtering 0 (normal) + * ETH_MACFFR_PAM Pass all multicast 0 (Depends on HM bit) + * ETH_MACFFR_BFD Broadcast frames disable 0 (enabled) + * ETH_MACFFR_PCF Pass control frames 1 (block all but PAUSE) + * ETH_MACFFR_SAIF Source address inverse filtering 0 (not used) + * ETH_MACFFR_SAF Source address filter 0 (disabled) + * ETH_MACFFR_HPF Hash or perfect filter 0 (Only matching frames passed) + * ETH_MACFFR_RA Receive all 0 (disabled) + */ + +#define MACFFR_SET_BITS (ETH_MACFFR_PCF_PAUSE) + +/* Clear the MACFCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFCR_FCB_BPA Bit 0: Flow control busy/back pressure activate + * ETH_MACFCR_TFCE Bit 1: Transmit flow control enable + * ETH_MACFCR_RFCE Bit 2: Receive flow control enable + * ETH_MACFCR_UPFD Bit 3: Unicast pause frame detect + * ETH_MACFCR_PLT Bits 4-5: Pause low threshold + * ETH_MACFCR_ZQPD Bit 7: Zero-quanta pause disable + * ETH_MACFCR_PT Bits 16-31: Pause time + */ + +#define MACFCR_CLEAR_MASK \ + (ETH_MACFCR_FCB_BPA | ETH_MACFCR_TFCE | ETH_MACFCR_RFCE | ETH_MACFCR_UPFD | \ + ETH_MACFCR_PLT_MASK | ETH_MACFCR_ZQPD | ETH_MACFCR_PT_MASK) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFCR_FCB_BPA Flow control busy/back pressure activate 0 (no pause control frame) + * ETH_MACFCR_TFCE Transmit flow control enable 0 (disabled) + * ETH_MACFCR_RFCE Receive flow control enable 0 (disabled) + * ETH_MACFCR_UPFD Unicast pause frame detect 0 (disabled) + * ETH_MACFCR_PLT Pause low threshold 0 (pause time - 4) + * ETH_MACFCR_ZQPD Zero-quanta pause disable 1 (disabled) + * ETH_MACFCR_PT Pause time 0 + */ + +#define MACFCR_SET_MASK (ETH_MACFCR_PLT_M4 | ETH_MACFCR_ZQPD) + +/* Clear the DMAOMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMAOMR_SR Bit 1: Start/stop receive + * TH_DMAOMR_OSF Bit 2: Operate on second frame + * ETH_DMAOMR_RTC Bits 3-4: Receive threshold control + * ETH_DMAOMR_FUGF Bit 6: Forward undersized good frames + * ETH_DMAOMR_FEF Bit 7: Forward error frames + * ETH_DMAOMR_ST Bit 13: Start/stop transmission + * ETH_DMAOMR_TTC Bits 14-16: Transmit threshold control + * ETH_DMAOMR_FTF Bit 20: Flush transmit FIFO + * ETH_DMAOMR_TSF Bit 21: Transmit store and forward + * ETH_DMAOMR_DFRF Bit 24: Disable flushing of received frames + * ETH_DMAOMR_RSF Bit 25: Receive store and forward + * TH_DMAOMR_DTCEFD Bit 26: Dropping of TCP/IP checksum error frames disable + */ + +#define DMAOMR_CLEAR_MASK \ + (ETH_DMAOMR_SR | ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_MASK | ETH_DMAOMR_FUGF | \ + ETH_DMAOMR_FEF | ETH_DMAOMR_ST | ETH_DMAOMR_TTC_MASK | ETH_DMAOMR_FTF | \ + ETH_DMAOMR_TSF | ETH_DMAOMR_DFRF | ETH_DMAOMR_RSF | ETH_DMAOMR_DTCEFD) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_DMAOMR_SR Start/stop receive 0 (not running) + * TH_DMAOMR_OSF Operate on second frame 1 (enabled) + * ETH_DMAOMR_RTC Receive threshold control 0 (64 bytes) + * ETH_DMAOMR_FUGF Forward undersized good frames 0 (disabled) + * ETH_DMAOMR_FEF Forward error frames 0 (disabled) + * ETH_DMAOMR_ST Start/stop transmission 0 (not running) + * ETH_DMAOMR_TTC Transmit threshold control 0 (64 bytes) + * ETH_DMAOMR_FTF Flush transmit FIFO 0 (no flush) + * ETH_DMAOMR_TSF Transmit store and forward Depends on CONFIG_STM32_ETH_HWCHECKSUM + * ETH_DMAOMR_DFRF Disable flushing of received frames 0 (enabled) + * ETH_DMAOMR_RSF Receive store and forward Depends on CONFIG_STM32_ETH_HWCHECKSUM + * TH_DMAOMR_DTCEFD Dropping of TCP/IP checksum error Depends on CONFIG_STM32_ETH_HWCHECKSUM + * frames disable + * + * When the checksum offload feature is enabled, we need to enable the Store + * and Forward mode: the store and forward guarantee that a whole frame is + * stored in the FIFO, so the MAC can insert/verify the checksum, if the + * checksum is OK the DMA can handle the frame otherwise the frame is dropped + */ + +#ifdef CONFIG_STM32_ETH_HWCHECKSUM +# define DMAOMR_SET_MASK \ + (ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_64 | ETH_DMAOMR_TTC_64 | \ + ETH_DMAOMR_TSF | ETH_DMAOMR_RSF) +#else +# define DMAOMR_SET_MASK \ + (ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_64 | ETH_DMAOMR_TTC_64 | \ + ETH_DMAOMR_DTCEFD) +#endif + +/* Clear the DMABMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMABMR_SR Bit 0: Software reset + * ETH_DMABMR_DA Bit 1: DMA Arbitration + * ETH_DMABMR_DSL Bits 2-6: Descriptor skip length + * ETH_DMABMR_EDFE Bit 7: Enhanced descriptor format enable + * ETH_DMABMR_PBL Bits 8-13: Programmable burst length + * ETH_DMABMR_RTPR Bits 14-15: RX TX priority ratio + * ETH_DMABMR_FB Bit 16: Fixed burst + * ETH_DMABMR_RDP Bits 17-22: RX DMA PBL + * ETH_DMABMR_USP Bit 23: Use separate PBL + * ETH_DMABMR_FPM Bit 24: 4xPBL mode + * ETH_DMABMR_AAB Bit 25: Address-aligned beats + * ETH_DMABMR_MB Bit 26: Mixed burst (F2/F4 only) + */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +#define DMABMR_CLEAR_MASK \ + (ETH_DMABMR_SR | ETH_DMABMR_DA | ETH_DMABMR_DSL_MASK | ETH_DMABMR_EDFE | \ + ETH_DMABMR_PBL_MASK | ETH_DMABMR_RTPR_MASK | ETH_DMABMR_FB | ETH_DMABMR_RDP_MASK | \ + ETH_DMABMR_USP | ETH_DMABMR_FPM | ETH_DMABMR_AAB | ETH_DMABMR_MB) +#else +#define DMABMR_CLEAR_MASK \ + (ETH_DMABMR_SR | ETH_DMABMR_DA | ETH_DMABMR_DSL_MASK | ETH_DMABMR_EDFE | \ + ETH_DMABMR_PBL_MASK | ETH_DMABMR_RTPR_MASK | ETH_DMABMR_FB | ETH_DMABMR_RDP_MASK | \ + ETH_DMABMR_USP | ETH_DMABMR_FPM | ETH_DMABMR_AAB) +#endif + +/* The following bits are set or left zero unconditionally in all modes. + * + * + * ETH_DMABMR_SR Software reset 0 (no reset) + * ETH_DMABMR_DA DMA Arbitration 0 (round robin) + * ETH_DMABMR_DSL Descriptor skip length 0 + * ETH_DMABMR_EDFE Enhanced descriptor format enable Depends on CONFIG_STM32_ETH_ENHANCEDDESC + * ETH_DMABMR_PBL Programmable burst length 32 beats + * ETH_DMABMR_RTPR RX TX priority ratio 2:1 + * ETH_DMABMR_FB Fixed burst 1 (enabled) + * ETH_DMABMR_RDP RX DMA PBL 32 beats + * ETH_DMABMR_USP Use separate PBL 1 (enabled) + * ETH_DMABMR_FPM 4xPBL mode 0 (disabled) + * ETH_DMABMR_AAB Address-aligned beats 1 (enabled) + * ETH_DMABMR_MB Mixed burst 0 (disabled, F2/F4 only) + */ + +#ifdef CONFIG_STM32_ETH_ENHANCEDDESC +# define DMABMR_SET_MASK \ + (ETH_DMABMR_DSL(0) | ETH_DMABMR_PBL(32) | ETH_DMABMR_EDFE | ETH_DMABMR_RTPR_2TO1 | \ + ETH_DMABMR_FB | ETH_DMABMR_RDP(32) | ETH_DMABMR_USP | ETH_DMABMR_AAB) +#else +# define DMABMR_SET_MASK \ + (ETH_DMABMR_DSL(0) | ETH_DMABMR_PBL(32) | ETH_DMABMR_RTPR_2TO1 | ETH_DMABMR_FB | \ + ETH_DMABMR_RDP(32) | ETH_DMABMR_USP | ETH_DMABMR_AAB) +#endif + +/* Interrupt bit sets *******************************************************/ +/* All interrupts in the normal and abnormal interrupt summary. Early transmit + * interrupt (ETI) is excluded from the abnormal set because it causes too + * many interrupts and is not interesting. + */ + +#define ETH_DMAINT_NORMAL \ + (ETH_DMAINT_TI | ETH_DMAINT_TBUI | ETH_DMAINT_RI | ETH_DMAINT_ERI) + +#define ETH_DMAINT_ABNORMAL \ + (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \ + ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /* ETH_DMAINT_ETI | */ \ + ETH_DMAINT_FBEI) + +/* Normal receive, transmit, error interrupt enable bit sets */ + +#define ETH_DMAINT_RECV_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_RI) +#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI) +#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI) + +#ifdef CONFIG_DEBUG_NET +# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL) +#else +# define ETH_DMAINT_ERROR_ENABLE (0) +#endif + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the Ethernet + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The stm32_ethmac_s encapsulates all state information for a single hardware + * interface + */ + +struct stm32_ethmac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */ + uint8_t fduplex : 1; /* Full (vs. half) duplex */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + struct eth_txdesc_s *txhead; /* Next available TX descriptor */ + struct eth_rxdesc_s *rxhead; /* Next available RX descriptor */ + + struct eth_txdesc_s *txtail; /* First "in_flight" TX descriptor */ + struct eth_rxdesc_s *rxcurr; /* First RX descriptor of the segment */ + uint16_t segments; /* RX segment count */ + uint16_t inflight; /* Number of TX transfers "in_flight" */ + sq_queue_t freeb; /* The free buffer list */ + + /* Descriptor allocations */ + + struct eth_rxdesc_s rxtable[CONFIG_STM32_ETH_NRXDESC]; + struct eth_txdesc_s txtable[CONFIG_STM32_ETH_NTXDESC]; + + /* Buffer allocations */ + + uint8_t rxbuffer[CONFIG_STM32_ETH_NRXDESC*CONFIG_STM32_ETH_BUFSIZE]; + uint8_t alloc[STM32_ETH_NFREEBUFFERS*CONFIG_STM32_ETH_BUFSIZE]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct stm32_ethmac_s g_stm32ethmac[STM32_NETHERNET]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_STM32_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); +static void stm32_checksetup(void); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +# define stm32_checksetup() +#endif + +/* Free buffer management */ + +static void stm32_initbuffer(FAR struct stm32_ethmac_s *priv); +static inline uint8_t *stm32_allocbuffer(FAR struct stm32_ethmac_s *priv); +static inline void stm32_freebuffer(FAR struct stm32_ethmac_s *priv, uint8_t *buffer); +static inline bool stm32_isfreebuffer(FAR struct stm32_ethmac_s *priv); + +/* Common TX logic */ + +static int stm32_transmit(FAR struct stm32_ethmac_s *priv); +static int stm32_txpoll(struct net_driver_s *dev); +static void stm32_dopoll(FAR struct stm32_ethmac_s *priv); + +/* Interrupt handling */ + +static void stm32_enableint(FAR struct stm32_ethmac_s *priv, uint32_t ierbit); +static void stm32_disableint(FAR struct stm32_ethmac_s *priv, uint32_t ierbit); + +static void stm32_freesegment(FAR struct stm32_ethmac_s *priv, + FAR struct eth_rxdesc_s *rxfirst, int segments); +static int stm32_recvframe(FAR struct stm32_ethmac_s *priv); +static void stm32_receive(FAR struct stm32_ethmac_s *priv); +static void stm32_freeframe(FAR struct stm32_ethmac_s *priv); +static void stm32_txdone(FAR struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_interrupt_work(FAR void *arg); +#endif +static int stm32_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static inline void stm32_txtimeout_process(FAR struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_txtimeout_work(FAR void *arg); +#endif +static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_poll_work(FAR void *arg); +#endif +static void stm32_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int stm32_ifup(struct net_driver_s *dev); +static int stm32_ifdown(struct net_driver_s *dev); +static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_txavail_work(FAR void *arg); +#endif +static int stm32_txavail(struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int stm32_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int stm32_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int stm32_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* Descriptor Initialization */ + +static void stm32_txdescinit(FAR struct stm32_ethmac_s *priv); +static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv); + +/* PHY Initialization */ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int stm32_phyintenable(FAR struct stm32_ethmac_s *priv); +#endif +static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value); +static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value); +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int stm32_dm9161(FAR struct stm32_ethmac_s *priv); +#endif +static int stm32_phyinit(FAR struct stm32_ethmac_s *priv); + +/* MAC/DMA Initialization */ + +#ifdef CONFIG_STM32_MII +static inline void stm32_selectmii(void); +#endif +#ifdef CONFIG_STM32_RMII +static inline void stm32_selectrmii(void); +#endif +static inline void stm32_ethgpioconfig(FAR struct stm32_ethmac_s *priv); +static void stm32_ethreset(FAR struct stm32_ethmac_s *priv); +static int stm32_macconfig(FAR struct stm32_ethmac_s *priv); +static void stm32_macaddress(FAR struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void stm32_ipv6multicast(FAR struct stm32_ethmac_s *priv); +#endif +static int stm32_macenable(FAR struct stm32_ethmac_s *priv); +static int stm32_ethconfig(FAR struct stm32_ethmac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * addr - The register address to read + * + * Returned Value: + * The value read from the register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * val - The value to write to the register + * addr - The register address to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_checksetup + * + * Description: + * Show the state of critical configuration registers. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_checksetup(void) +{ +} +#endif + +/**************************************************************************** + * Function: stm32_initbuffer + * + * Description: + * Initialize the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called during early driver initialization before Ethernet interrupts + * are enabled. + * + ****************************************************************************/ + +static void stm32_initbuffer(FAR struct stm32_ethmac_s *priv) +{ + uint8_t *buffer; + int i; + + /* Initialize the head of the free buffer list */ + + sq_init(&priv->freeb); + + /* Add all of the pre-allocated buffers to the free buffer list */ + + for (i = 0, buffer = priv->alloc; + i < STM32_ETH_NFREEBUFFERS; + i++, buffer += CONFIG_STM32_ETH_BUFSIZE) + { + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); + } +} + +/**************************************************************************** + * Function: stm32_allocbuffer + * + * Description: + * Allocate one buffer from the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * Pointer to the allocated buffer on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline uint8_t *stm32_allocbuffer(FAR struct stm32_ethmac_s *priv) +{ + /* Allocate a buffer by returning the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->freeb); +} + +/**************************************************************************** + * Function: stm32_freebuffer + * + * Description: + * Return a buffer to the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * buffer - A pointer to the buffer to be freed + * + * Returned Value: + * None + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline void stm32_freebuffer(FAR struct stm32_ethmac_s *priv, uint8_t *buffer) +{ + /* Free the buffer by adding it to to the end of the free buffer list */ + + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); +} + +/**************************************************************************** + * Function: stm32_isfreebuffer + * + * Description: + * Return TRUE if the free buffer list is not empty. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * True if there are one or more buffers in the free buffer list; + * false if the free buffer list is empty + * + * Assumptions: + * None. + * + ****************************************************************************/ + +static inline bool stm32_isfreebuffer(FAR struct stm32_ethmac_s *priv) +{ + /* Return TRUE if the free buffer list is not empty */ + + return !sq_empty(&priv->freeb); +} + +/**************************************************************************** + * Function: stm32_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_transmit(FAR struct stm32_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + struct eth_txdesc_s *txfirst; + + /* The internal (optimal) uIP buffer size may be configured to be larger + * than the Ethernet buffer size. + */ + +#if OPTIMAL_ETH_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE + uint8_t *buffer; + int bufcount; + int lastsize; + int i; +#endif + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + txdesc = priv->txhead; + txfirst = txdesc; + + nllvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n", + priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0); + + DEBUGASSERT(txdesc && (txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Is the size to be sent greater than the size of the Ethernet buffer? */ + + DEBUGASSERT(priv->dev.d_len > 0 && priv->dev.d_buf != NULL); + +#if OPTIMAL_ETH_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE + if (priv->dev.d_len > CONFIG_STM32_ETH_BUFSIZE) + { + /* Yes... how many buffers will be need to send the packet? */ + + bufcount = (priv->dev.d_len + (CONFIG_STM32_ETH_BUFSIZE-1)) / CONFIG_STM32_ETH_BUFSIZE; + lastsize = priv->dev.d_len - (bufcount - 1) * CONFIG_STM32_ETH_BUFSIZE; + + nllvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize); + + /* Set the first segment bit in the first TX descriptor */ + + txdesc->tdes0 |= ETH_TDES0_FS; + + /* Set up all but the last TX descriptor */ + + buffer = priv->dev.d_buf; + + for (i = 0; i < bufcount; i++) + { + /* This could be a normal event but the design does not handle it */ + + DEBUGASSERT((txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)buffer; + + /* Set the buffer size in all TX descriptors */ + + if (i == (bufcount-1)) + { + /* This is the last segment. Set the last segment bit in the + * last TX descriptor and ask for an interrupt when this + * segment transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_LS | ETH_TDES0_IC); + + /* This segement is, most likely, of fractional buffersize */ + + txdesc->tdes1 = lastsize; + buffer += lastsize; + } + else + { + /* This is not the last segment. We don't want an interrupt + * when this segment transfer completes. + */ + + txdesc->tdes0 &= ~ETH_TDES0_IC; + + /* The size of the transfer is the whole buffer */ + + txdesc->tdes1 = CONFIG_STM32_ETH_BUFSIZE; + buffer += CONFIG_STM32_ETH_BUFSIZE; + } + + /* Give the descriptor to DMA */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + } + else +#endif + { + /* The single descriptor is both the first and last segment. And we do + * want an interrupt when the transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_FS | ETH_TDES0_LS | ETH_TDES0_IC); + + /* Set frame size */ + + DEBUGASSERT(priv->dev.d_len <= CONFIG_NET_ETH_MTU); + txdesc->tdes1 = priv->dev.d_len; + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)priv->dev.d_buf; + + /* Set OWN bit of the TX descriptor tdes0. This gives the buffer to + * Ethernet DMA + */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + + /* Point to the next available TX descriptor */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + + /* Remember where we left off in the TX descriptor chain */ + + priv->txhead = txdesc; + + /* Detach the buffer from priv->dev structure. That buffer is now + * "in-flight". + */ + + priv->dev.d_buf = NULL; + priv->dev.d_len = 0; + + /* If there is no other TX buffer, in flight, then remember the location + * of the TX descriptor. This is the location to check for TX done events. + */ + + if (!priv->txtail) + { + DEBUGASSERT(priv->inflight == 0); + priv->txtail = txfirst; + } + + /* Increment the number of TX transfer in-flight */ + + priv->inflight++; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* If all TX descriptors are in-flight, then we have to disable receive interrupts + * too. This is because receive events can trigger more un-stoppable transmit + * events. + */ + + if (priv->inflight >= CONFIG_STM32_ETH_NTXDESC) + { + stm32_disableint(priv, ETH_DMAINT_RI); + } + + /* Check if the TX Buffer unavailable flag is set */ + + if ((stm32_getreg(STM32_ETH_DMASR) & ETH_DMAINT_TBUI) != 0) + { + /* Clear TX Buffer unavailable flag */ + + stm32_putreg(ETH_DMAINT_TBUI, STM32_ETH_DMASR); + + /* Resume DMA transmission */ + + stm32_putreg(0, STM32_ETH_DMATPDR); + } + + /* Enable TX interrupts */ + + stm32_enableint(priv, ETH_DMAINT_TI); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, STM32_TXTIMEOUT, stm32_txtimeout_expiry, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: stm32_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_txpoll(struct net_driver_s *dev) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private; + + DEBUGASSERT(priv->dev.d_buf != NULL); + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + stm32_transmit(priv); + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the TX poll if we are unable to accept another packet for + * transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) != 0 || + priv->txhead->tdes2 != 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + + /* We have the descriptor, we can continue the poll. Allocate a new + * buffer for the poll. + */ + + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't continue the poll if we have no buffers */ + + if (dev->d_buf == NULL) + { + /* Terminate the poll. */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: stm32_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (stm32_txdone), + * 2. When new TX data is available (stm32_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (stm32_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_dopoll(FAR struct stm32_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or + * CPU. We cannot perform the TX poll if we are unable to accept + * another packet for transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. + * Allocate a buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + (void)devif_poll(dev, stm32_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: stm32_enableint + * + * Description: + * Enable a "normal" interrupt + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_enableint(FAR struct stm32_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Enable the specified "normal" interrupt */ + + regval = stm32_getreg(STM32_ETH_DMAIER); + regval |= (ETH_DMAINT_NIS | ierbit); + stm32_putreg(regval, STM32_ETH_DMAIER); +} + +/**************************************************************************** + * Function: stm32_disableint + * + * Description: + * Disable a normal interrupt. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_disableint(FAR struct stm32_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Disable the "normal" interrupt */ + + regval = stm32_getreg(STM32_ETH_DMAIER); + regval &= ~ierbit; + + /* Are all "normal" interrupts now disabled? */ + + if ((regval & ETH_DMAINT_NORMAL) == 0) + { + /* Yes.. disable normal interrupts */ + + regval &= ~ETH_DMAINT_NIS; + } + + stm32_putreg(regval, STM32_ETH_DMAIER); +} + +/**************************************************************************** + * Function: stm32_freesegment + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors to the received frame. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_freesegment(FAR struct stm32_ethmac_s *priv, + FAR struct eth_rxdesc_s *rxfirst, int segments) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + nllvdbg("rxfirst: %p segments: %d\n", rxfirst, segments); + + /* Set OWN bit in RX descriptors. This gives the buffers back to DMA */ + + rxdesc = rxfirst; + for (i = 0; i < segments; i++) + { + rxdesc->rdes0 = ETH_RDES0_OWN; + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + } + + /* Reset the segment managment logic */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Check if the RX Buffer unavailable flag is set */ + + if ((stm32_getreg(STM32_ETH_DMASR) & ETH_DMAINT_RBUI) != 0) + { + /* Clear RBUS Ethernet DMA flag */ + + stm32_putreg(ETH_DMAINT_RBUI, STM32_ETH_DMASR); + + /* Resume DMA reception */ + + stm32_putreg(0, STM32_ETH_DMARPDR); + } +} + +/**************************************************************************** + * Function: stm32_recvframe + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors of the received frame. + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_recvframe(FAR struct stm32_ethmac_s *priv) +{ + struct eth_rxdesc_s *rxdesc; + struct eth_rxdesc_s *rxcurr; + uint8_t *buffer; + int i; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if there are free buffers. We cannot receive new frames in this + * design unless there is at least one free buffer. + */ + + if (!stm32_isfreebuffer(priv)) + { + nlldbg("No free buffers\n"); + return -ENOMEM; + } + + /* Scan descriptors owned by the CPU. Scan until: + * + * 1) We find a descriptor still owned by the DMA, + * 2) We have examined all of the RX descriptors, or + * 3) All of the TX descriptors are in flight. + * + * This last case is obscure. It is due to that fact that each packet + * that we receive can generate an unstoppable transmisson. So we have + * to stop receiving when we can not longer transmit. In this case, the + * transmit logic should also have disabled further RX interrupts. + */ + + rxdesc = priv->rxhead; + for (i = 0; + (rxdesc->rdes0 & ETH_RDES0_OWN) == 0 && + i < CONFIG_STM32_ETH_NRXDESC && + priv->inflight < CONFIG_STM32_ETH_NTXDESC; + i++) + { + /* Check if this is the first segment in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_FS) != 0 && + (rxdesc->rdes0 & ETH_RDES0_LS) == 0) + { + priv->rxcurr = rxdesc; + priv->segments = 1; + } + + /* Check if this is an intermediate segment in the frame */ + + else if (((rxdesc->rdes0 & ETH_RDES0_LS) == 0) && + ((rxdesc->rdes0 & ETH_RDES0_FS) == 0)) + { + priv->segments++; + } + + /* Otherwise, it is the last segment in the frame */ + + else + { + priv->segments++; + + /* Check if the there is only one segment in the frame */ + + if (priv->segments == 1) + { + rxcurr = rxdesc; + } + else + { + rxcurr = priv->rxcurr; + } + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if any errors are reported in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0) + { + struct net_driver_s *dev = &priv->dev; + + /* Get the Frame Length of the received packet: substruct 4 + * bytes of the CRC + */ + + dev->d_len = ((rxdesc->rdes0 & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_SHIFT) - 4; + + /* Get a buffer from the free list. We don't even check if + * this is successful because we already assure the free + * list is not empty above. + */ + + buffer = stm32_allocbuffer(priv); + + /* Take the buffer from the RX descriptor of the first free + * segment, put it into the uIP device structure, then replace + * the buffer in the RX descriptor with the newly allocated + * buffer. + */ + + DEBUGASSERT(dev->d_buf == NULL); + dev->d_buf = (uint8_t *)rxcurr->rdes2; + rxcurr->rdes2 = (uint32_t)buffer; + + /* Return success, remebering where we should re-start scanning + * and resetting the segment scanning logic + */ + + priv->rxhead = (struct eth_rxdesc_s *)rxdesc->rdes3; + stm32_freesegment(priv, rxcurr, priv->segments); + + nllvdbg("rxhead: %p d_buf: %p d_len: %d\n", + priv->rxhead, dev->d_buf, dev->d_len); + + return OK; + } + else + { + /* Drop the frame that contains the errors, reset the segment + * scanning logic, and continue scanning with the next frame. + */ + + nlldbg("DROPPED: RX descriptor errors: %08x\n", rxdesc->rdes0); + stm32_freesegment(priv, rxcurr, priv->segments); + } + } + + /* Try the next descriptor */ + + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + } + + /* We get here after all of the descriptors have been scanned or when rxdesc points + * to the first descriptor owned by the DMA. Remember where we left off. + */ + + priv->rxhead = rxdesc; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + return -EAGAIN; +} + +/**************************************************************************** + * Function: stm32_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_receive(FAR struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while stm32_recvframe() successfully retrieves valid + * Ethernet frames. + */ + + while (stm32_recvframe(priv) == OK) + { +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + + /* Free dropped packet buffer */ + + if (dev->d_buf) + { + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + stm32_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + stm32_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + stm32_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + + /* We are finished with the RX buffer. NOTE: If the buffer is + * re-used for transmission, the dev->d_buf field will have been + * nullified. + */ + + if (dev->d_buf) + { + /* Free the receive packet buffer */ + + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + } +} + +/**************************************************************************** + * Function: stm32_freeframe + * + * Description: + * Scans the TX descriptors and frees the buffers of completed TX transfers. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_freeframe(FAR struct stm32_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + int i; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* Scan for "in-flight" descriptors owned by the CPU */ + + txdesc = priv->txtail; + if (txdesc) + { + DEBUGASSERT(priv->inflight > 0); + + for (i = 0; (txdesc->tdes0 & ETH_TDES0_OWN) == 0; i++) + { + /* There should be a buffer assigned to all in-flight + * TX descriptors. + */ + + nllvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n", + txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3); + + DEBUGASSERT(txdesc->tdes2 != 0); + + /* Check if this is the first segment of a TX frame. */ + + if ((txdesc->tdes0 & ETH_TDES0_FS) != 0) + { + /* Yes.. Free the buffer */ + + stm32_freebuffer(priv, (uint8_t *)txdesc->tdes2); + } + + /* In any event, make sure that TDES2 is nullified. */ + + txdesc->tdes2 = 0; + + /* Check if this is the last segement of a TX frame */ + + if ((txdesc->tdes0 & ETH_TDES0_LS) != 0) + { + /* Yes.. Decrement the number of frames "in-flight". */ + + priv->inflight--; + + /* If all of the TX descriptors were in-flight, then RX interrupts + * may have been disabled... we can re-enable them now. + */ + + stm32_enableint(priv, ETH_DMAINT_RI); + + /* If there are no more frames in-flight, then bail. */ + + if (priv->inflight <= 0) + { + priv->txtail = NULL; + priv->inflight = 0; + return; + } + } + + /* Try the next descriptor in the TX chain */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + + /* We get here if (1) there are still frames "in-flight". Remember + * where we left off. + */ + + priv->txtail = txdesc; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + } +} + +/**************************************************************************** + * Function: stm32_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet + * transfer(s) are complete. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_txdone(FAR struct stm32_ethmac_s *priv) +{ + DEBUGASSERT(priv->txtail != NULL); + + /* Scan the TX descriptor change, returning buffers to free list */ + + stm32_freeframe(priv); + + /* If no further xmits are pending, then cancel the TX timeout */ + + if (priv->inflight <= 0) + { + /* Cancel the TX timeout */ + + wd_cancel(priv->txtimeout); + + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv); + + /* And disable further TX interrupts. */ + + stm32_disableint(priv, ETH_DMAINT_TI); + } + + /* Then poll uIP for new XMIT data */ + + stm32_dopoll(priv); +} + +/**************************************************************************** + * Function: stm32_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void stm32_interrupt_process(FAR struct stm32_ethmac_s *priv) +{ + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = stm32_getreg(STM32_ETH_DMASR); + + /* Mask only enabled interrupts. This depends on the fact that the interrupt + * related bits (0-16) correspond in these two registers. + */ + + dmasr &= stm32_getreg(STM32_ETH_DMAIER); + + /* Check if there are pending "normal" interrupts */ + + if ((dmasr & ETH_DMAINT_NIS) != 0) + { + /* Yes.. Check if we received an incoming packet, if so, call + * stm32_receive() + */ + + if ((dmasr & ETH_DMAINT_RI) != 0) + { + /* Clear the pending receive interrupt */ + + stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR); + + /* Handle the received package */ + + stm32_receive(priv); + } + + /* Check if a packet transmission just completed. If so, call + * stm32_txdone(). This may disable further TX interrupts if there + * are no pending transmissions. + */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* Clear the pending receive interrupt */ + + stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR); + + /* Check if there are pending transmissions */ + + stm32_txdone(priv); + } + + /* Clear the pending normal summary interrupt */ + + stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR); + } + + /* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */ + +#ifdef CONFIG_DEBUG_NET + + /* Check if there are pending "anormal" interrupts */ + + if ((dmasr & ETH_DMAINT_AIS) != 0) + { + /* Just let the user know what happened */ + + nlldbg("Abormal event(s): %08x\n", dmasr); + + /* Clear all pending abnormal events */ + + stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR); + + /* Clear the pending abnormal summary interrupt */ + + stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR); + } +#endif +} + +/**************************************************************************** + * Function: stm32_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_interrupt_work(FAR void *arg) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + stm32_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_ETH); +} +#endif + +/**************************************************************************** + * Function: stm32_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_interrupt(int irq, FAR void *context) +{ + FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0]; + +#ifdef CONFIG_NET_NOINTS + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = stm32_getreg(STM32_ETH_DMASR); + if (dmasr != 0) + { + /* Disable further Ethernet interrupts. Because Ethernet interrupts + * are also disabled if the TX timeout event occurs, there can be no + * race condition here. + */ + + up_disable_irq(STM32_IRQ_ETH); + + /* Check if a packet transmission just completed. */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_interrupt_work, priv, 0); + } + +#else + /* Process the interrupt now */ + + stm32_interrupt_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: stm32_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void stm32_txtimeout_process(FAR struct stm32_ethmac_s *priv) +{ + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + stm32_ifdown(&priv->dev); + stm32_ifup(&priv->dev); + + /* Then poll for new XMIT data */ + + stm32_dopoll(priv); +} + +/**************************************************************************** + * Function: stm32_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_txtimeout_work(FAR void *arg) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + stm32_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + + nlldbg("Timeout!\n"); + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + * + * Interrupts will be re-enabled when stm32_ifup() is called. + */ + + up_disable_irq(STM32_IRQ_ETH); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_txtimeout_work, priv, 0); + +#else + /* Process the timeout now */ + + stm32_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: stm32_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the timer poll if we are unable to accept another packet + * for transmission. Hmmm.. might be bug here. Does this mean if there is + * a transmit in progress, we will miss TCP time state updates? + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then perform the timer poll. Allocate a + * buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + /* Update TCP timing states and poll uIP for new XMIT data. + */ + + (void)devif_timer(dev, stm32_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: stm32_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_poll_work(FAR void *arg) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + stm32_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv); + } + +#else + /* Process the interrupt now */ + + stm32_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: stm32_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ifup(struct net_driver_s *dev) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the Ethernet interface for DMA operation. */ + + ret = stm32_ethconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->ifup = true; + up_enable_irq(STM32_IRQ_ETH); + + stm32_checksetup(); + return OK; +} + +/**************************************************************************** + * Function: stm32_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ifdown(struct net_driver_s *dev) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private; + irqstate_t flags; + + ndbg("Taking the network down\n"); + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(STM32_IRQ_ETH); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the stm32_ifup() always + * successfully brings the interface back up. + */ + + stm32_ethreset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: stm32_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * priv - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv) +{ + nvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + stm32_dopoll(priv); + } +} + +/**************************************************************************** + * Function: stm32_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_txavail_work(FAR void *arg) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + stm32_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int stm32_txavail(struct net_driver_s *dev) +{ + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + stm32_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Function: stm32_calcethcrc + * + * Description: + * Function to calculate the CRC used by STM32 to check an ethernet frame + * + * Parameters: + * data - the data to be checked + * length - length of the data + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t stm32_calcethcrc(const uint8_t *data, size_t length) +{ + uint32_t crc = 0xffffffff; + size_t i; + int j; + + for (i = 0; i < length; i++) + { + for (j = 0; j < 8; j++) + { + if (((crc >> 31) ^ (data[i] >> j)) & 0x01) + { + /* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ + crc = (crc << 1) ^ 0x04c11db7; + } + else + { + crc = crc << 1; + } + } + } + + return ~crc; +} +#endif + +/**************************************************************************** + * Function: stm32_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int stm32_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Add the MAC address to the hardware multicast hash table */ + + crc = stm32_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = STM32_ETH_MACHTHR; + hashindex -= 32; + } + else + { + registeraddress = STM32_ETH_MACHTLR; + } + + temp = stm32_getreg(registeraddress); + temp |= 1 << hashindex; + stm32_putreg(temp, registeraddress); + + temp = stm32_getreg(STM32_ETH_MACFFR); + temp |= (ETH_MACFFR_HM | ETH_MACFFR_HPF); + stm32_putreg(temp, STM32_ETH_MACFFR); + + return OK; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: stm32_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int stm32_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Remove the MAC address to the hardware multicast hash table */ + + crc = stm32_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = STM32_ETH_MACHTHR; + hashindex -= 32; + } + else + { + registeraddress = STM32_ETH_MACHTLR; + } + + temp = stm32_getreg(registeraddress); + temp &= ~(1 << hashindex); + stm32_putreg(temp, registeraddress); + + /* If there is no address registered any more, delete multicast filtering */ + + if (stm32_getreg(STM32_ETH_MACHTHR) == 0 && + stm32_getreg(STM32_ETH_MACHTLR) == 0) + { + temp = stm32_getreg(STM32_ETH_MACFFR); + temp &= ~(ETH_MACFFR_HM | ETH_MACFFR_HPF); + stm32_putreg(temp, STM32_ETH_MACFFR); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: stm32_txdescinit + * + * Description: + * Initializes the DMA TX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_txdescinit(FAR struct stm32_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + int i; + + /* priv->txhead will point to the first, available TX descriptor in the chain. + * Set the priv->txhead pointer to the first descriptor in the table. + */ + + priv->txhead = priv->txtable; + + /* priv->txtail will point to the first segment of the oldest pending + * "in-flight" TX transfer. NULL means that there are no active TX + * transfers. + */ + + priv->txtail = NULL; + priv->inflight = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_STM32_ETH_NTXDESC; i++) + { + txdesc = &priv->txtable[i]; + + /* Set Second Address Chained bit */ + + txdesc->tdes0 = ETH_TDES0_TCH; + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the checksum insertion for the TX frames */ + + txdesc->tdes0 |= ETH_TDES0_CIC_ALL; +#endif + + /* Clear Buffer1 address pointer (buffers will be assigned as they + * are used) + */ + + txdesc->tdes2 = 0; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_STM32_ETH_NTXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + txdesc->tdes3 = (uint32_t)&priv->txtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + txdesc->tdes3 = (uint32_t)priv->txtable; + } + } + + /* Set Transmit Desciptor List Address Register */ + + stm32_putreg((uint32_t)priv->txtable, STM32_ETH_DMATDLAR); +} + +/**************************************************************************** + * Function: stm32_rxdescinit + * + * Description: + * Initializes the DMA RX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + /* priv->rxhead will point to the first, RX descriptor in the chain. + * This will be where we receive the first incomplete frame. + */ + + priv->rxhead = priv->rxtable; + + /* If we accumulate the frame in segments, priv->rxcurr points to the + * RX descriptor of the first segment in the current TX frame. + */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_STM32_ETH_NRXDESC; i++) + { + rxdesc = &priv->rxtable[i]; + + /* Set Own bit of the RX descriptor rdes0 */ + + rxdesc->rdes0 = ETH_RDES0_OWN; + + /* Set Buffer1 size and Second Address Chained bit and enabled DMA + * RX desc receive interrupt + */ + + rxdesc->rdes1 = ETH_RDES1_RCH | (uint32_t)CONFIG_STM32_ETH_BUFSIZE; + + /* Set Buffer1 address pointer */ + + rxdesc->rdes2 = (uint32_t)&priv->rxbuffer[i*CONFIG_STM32_ETH_BUFSIZE]; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_STM32_ETH_NRXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + rxdesc->rdes3 = (uint32_t)&priv->rxtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + rxdesc->rdes3 = (uint32_t)priv->rxtable; + } + } + + /* Set Receive Descriptor List Address Register */ + + stm32_putreg((uint32_t)priv->rxtable, STM32_ETH_DMARDLAR); +} + +/**************************************************************************** + * Function: stm32_ioctl + * + * Description: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int stm32_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ +#ifdef CONFIG_ARCH_PHY_INTERRUPT + FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private; +#endif + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = stm32_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = CONFIG_STM32_PHYADDR; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = stm32_phyread(req->phy_id, req->reg_num, &req->val_out); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = stm32_phywrite(req->phy_id, req->reg_num, req->val_in); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: stm32_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int stm32_phyintenable(struct stm32_ethmac_s *priv) +{ +#warning Missing logic + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Function: stm32_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ETH_MACMIIAR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the buy bit. + * the ETH_MACMIIAR_MW is clear, indicating a read operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIAR_PA_SHIFT) & ETH_MACMIIAR_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIAR_MR_SHIFT) & ETH_MACMIIAR_MR_MASK); + regval |= ETH_MACMIIAR_MB; + + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_READ_TIMEOUT; timeout++) + { + if ((stm32_getreg(STM32_ETH_MACMIIAR) & ETH_MACMIIAR_MB) == 0) + { + *value = (uint16_t)stm32_getreg(STM32_ETH_MACMIIDR); + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x\n", + phydevaddr, phyregaddr); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: stm32_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The 16-bit value to write to the PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ETH_MACMIIAR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the busy bit. + * the ETH_MACMIIAR_MW is set, indicating a write operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIAR_PA_SHIFT) & ETH_MACMIIAR_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIAR_MR_SHIFT) & ETH_MACMIIAR_MR_MASK); + regval |= (ETH_MACMIIAR_MB | ETH_MACMIIAR_MW); + + /* Write the value into the MACIIDR register before setting the new MACMIIAR + * register value. + */ + + stm32_putreg(value, STM32_ETH_MACMIIDR); + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_WRITE_TIMEOUT; timeout++) + { + if ((stm32_getreg(STM32_ETH_MACMIIAR) & ETH_MACMIIAR_MB) == 0) + { + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x value: %04x\n", + phydevaddr, phyregaddr, value); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: stm32_dm9161 + * + * Description: + * Special workaround for the Davicom DM9161 PHY is required. On power, + * up, the PHY is not usually configured correctly but will work after + * a powered-up reset. This is really a workaround for some more + * fundamental issue with the PHY clocking initialization, but the + * root cause has not been studied (nor will it be with this workaround). + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int stm32_dm9161(FAR struct stm32_ethmac_s *priv) +{ + uint16_t phyval; + int ret; + + /* Read the PHYID1 register; A failure to read the PHY ID is one + * indication that check if the DM9161 PHY CHIP is not ready. + */ + + ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_PHYID1, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY ID1: %d\n", ret); + return ret; + } + + /* If we failed to read the PHY ID1 register, the reset the MCU to recover */ + + else if (phyval == 0xffff) + { + up_systemreset(); + } + + nvdbg("PHY ID1: 0x%04X\n", phyval); + + /* Now check the "DAVICOM Specified Configuration Register (DSCR)", Register 16 */ + + ret = stm32_phyread(CONFIG_STM32_PHYADDR, 16, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY Register 0x10: %d\n", ret); + return ret; + } + + /* Bit 8 of the DSCR register is zero, then the DM9161 has not selected RMII. + * If RMII is not selected, then reset the MCU to recover. + */ + + else if ((phyval & (1 << 8)) == 0) + { + up_systemreset(); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: stm32_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phyinit(FAR struct stm32_ethmac_s *priv) +{ + volatile uint32_t timeout; + uint32_t regval; + uint16_t phyval; + int ret; + + /* Assume 10MBps and half duplex */ + + priv->mbps100 = 0; + priv->fduplex = 0; + + /* Setup up PHY clocking by setting the SR field in the MACMIIAR register */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ~ETH_MACMIIAR_CR_MASK; + regval |= ETH_MACMIIAR_CR; + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Put the PHY in reset mode */ + + ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + ndbg("Failed to reset the PHY: %d\n", ret); + return ret; + } + up_mdelay(PHY_RESET_DELAY); + + /* Perform any necessary, board-specific PHY initialization */ + +#ifdef CONFIG_STM32_PHYINIT + ret = stm32_phy_boardinitialize(0); + if (ret < 0) + { + ndbg("Failed to initialize the PHY: %d\n", ret); + return ret; + } +#endif + + /* Special workaround for the Davicom DM9161 PHY is required. */ + +#ifdef CONFIG_ETH0_PHY_DM9161 + ret = stm32_dm9161(priv); + if (ret < 0) + { + return ret; + } +#endif + + /* Perform auto-negotion if so configured */ + +#ifdef CONFIG_STM32_AUTONEG + /* Wait for link status */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_LINKSTATUS) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for link status: %04x\n", phyval); + return -ETIMEDOUT; + } + + /* Enable auto-gegotiation */ + + ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_ANENABLE); + if (ret < 0) + { + ndbg("Failed to enable auto-negotiation: %d\n", ret); + return ret; + } + + /* Wait until auto-negotiation completes */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_ANEGCOMPLETE) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for auto-negotiation\n"); + return -ETIMEDOUT; + } + + /* Read the result of the auto-negotiation from the PHY-specific register */ + + ret = stm32_phyread(CONFIG_STM32_PHYADDR, CONFIG_STM32_PHYSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read PHY status register\n"); + return ret; + } + + /* Remember the selected speed and duplex modes */ + + nvdbg("PHYSR[%d]: %04x\n", CONFIG_STM32_PHYSR, phyval); + + /* Different PHYs present speed and mode information in different ways. IF + * This CONFIG_STM32_PHYSR_ALTCONFIG is selected, this indicates that the PHY + * represents speed and mode information are combined, for example, with + * separate bits for 10HD, 100HD, 10FD and 100FD. + */ + +#ifdef CONFIG_STM32_PHYSR_ALTCONFIG + switch (phyval & CONFIG_STM32_PHYSR_ALTMODE) + { + default: + case CONFIG_STM32_PHYSR_10HD: + priv->fduplex = 0; + priv->mbps100 = 0; + break; + + case CONFIG_STM32_PHYSR_100HD: + priv->fduplex = 0; + priv->mbps100 = 1; + break; + + case CONFIG_STM32_PHYSR_10FD: + priv->fduplex = 1; + priv->mbps100 = 0; + break; + + case CONFIG_STM32_PHYSR_100FD: + priv->fduplex = 1; + priv->mbps100 = 1; + break; + } + + /* Different PHYs present speed and mode information in different ways. Some + * will present separate information for speed and mode (this is the default). + * Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + * full/half duplex indication. + */ + +#else + if ((phyval & CONFIG_STM32_PHYSR_MODE) == CONFIG_STM32_PHYSR_FULLDUPLEX) + { + priv->fduplex = 1; + } + + if ((phyval & CONFIG_STM32_PHYSR_SPEED) == CONFIG_STM32_PHYSR_100MBPS) + { + priv->mbps100 = 1; + } +#endif + +#else /* Auto-negotion not selected */ + + phyval = 0; +#ifdef CONFIG_STM32_ETHFD + phyval |= MII_MCR_FULLDPLX; +#endif +#ifdef CONFIG_STM32_ETH100MBPS + phyval |= MII_MCR_SPEED100; +#endif + + ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, phyval); + if (ret < 0) + { + ndbg("Failed to write the PHY MCR: %d\n", ret); + return ret; + } + up_mdelay(PHY_CONFIG_DELAY); + + /* Remember the selected speed and duplex modes */ + +#ifdef CONFIG_STM32_ETHFD + priv->fduplex = 1; +#endif +#ifdef CONFIG_STM32_ETH100MBPS + priv->mbps100 = 1; +#endif +#endif + + ndbg("Duplex: %s Speed: %d MBps\n", + priv->fduplex ? "FULL" : "HALF", + priv->mbps100 ? 100 : 10); + + return OK; +} + +/************************************************************************************ + * Name: stm32_selectmii + * + * Description: + * Selects the MII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_MII +static inline void stm32_selectmii(void) +{ + uint32_t regval; + +#ifdef CONFIG_STM32_CONNECTIVITYLINE + regval = getreg32(STM32_AFIO_MAPR); + regval &= ~AFIO_MAPR_MII_RMII_SEL; + putreg32(regval, STM32_AFIO_MAPR); +#else + regval = getreg32(STM32_SYSCFG_PMC); + regval &= ~SYSCFG_PMC_MII_RMII_SEL; + putreg32(regval, STM32_SYSCFG_PMC); +#endif +} +#endif + +/************************************************************************************ + * Name: stm32_selectrmii + * + * Description: + * Selects the RMII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_selectrmii(void) +{ + uint32_t regval; + +#ifdef CONFIG_STM32_CONNECTIVITYLINE + regval = getreg32(STM32_AFIO_MAPR); + regval |= AFIO_MAPR_MII_RMII_SEL; + putreg32(regval, STM32_AFIO_MAPR); +#else + regval = getreg32(STM32_SYSCFG_PMC); + regval |= SYSCFG_PMC_MII_RMII_SEL; + putreg32(regval, STM32_SYSCFG_PMC); +#endif +} + +/**************************************************************************** + * Function: stm32_ethgpioconfig + * + * Description: + * Configure GPIOs for the Ethernet interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void stm32_ethgpioconfig(FAR struct stm32_ethmac_s *priv) +{ + /* Configure GPIO pins to support Ethernet */ + +#if defined(CONFIG_STM32_MII) || defined(CONFIG_STM32_RMII) + + /* MDC and MDIO are common to both modes */ + + stm32_configgpio(GPIO_ETH_MDC); + stm32_configgpio(GPIO_ETH_MDIO); + + /* Set up the MII interface */ + +#if defined(CONFIG_STM32_MII) + + /* Select the MII interface */ + + stm32_selectmii(); + + /* Provide clocking via MCO, MCO1 or MCO2: + * + * "MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + * clock (through a configurable prescaler) on PA8 pin." + * + * "MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or + * PLLI2S clock (through a configurable prescaler) on PC9 pin." + */ + +# if defined(CONFIG_STM32_MII_MCO1) + /* Configure MC01 to drive the PHY. Board logic must provide MC01 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO1); + stm32_mco1config(BOARD_CFGR_MC01_SOURCE, BOARD_CFGR_MC01_DIVIDER); + +# elif defined(CONFIG_STM32_MII_MCO2) + /* Configure MC02 to drive the PHY. Board logic must provide MC02 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO2); + stm32_mco2config(BOARD_CFGR_MC02_SOURCE, BOARD_CFGR_MC02_DIVIDER); + +# elif defined(CONFIG_STM32_MII_MCO) + /* Setup MCO pin for alternative usage */ + + stm32_configgpio(GPIO_MCO); + stm32_mcoconfig(BOARD_CFGR_MCO_SOURCE); +# endif + + /* MII interface pins (17): + * + * MII_TX_CLK, MII_TXD[3:0], MII_TX_EN, MII_RX_CLK, MII_RXD[3:0], MII_RX_ER, + * MII_RX_DV, MII_CRS, MII_COL, MDC, MDIO + */ + + stm32_configgpio(GPIO_ETH_MII_COL); + stm32_configgpio(GPIO_ETH_MII_CRS); + stm32_configgpio(GPIO_ETH_MII_RXD0); + stm32_configgpio(GPIO_ETH_MII_RXD1); + stm32_configgpio(GPIO_ETH_MII_RXD2); + stm32_configgpio(GPIO_ETH_MII_RXD3); + stm32_configgpio(GPIO_ETH_MII_RX_CLK); + stm32_configgpio(GPIO_ETH_MII_RX_DV); + stm32_configgpio(GPIO_ETH_MII_RX_ER); + stm32_configgpio(GPIO_ETH_MII_TXD0); + stm32_configgpio(GPIO_ETH_MII_TXD1); + stm32_configgpio(GPIO_ETH_MII_TXD2); + stm32_configgpio(GPIO_ETH_MII_TXD3); + stm32_configgpio(GPIO_ETH_MII_TX_CLK); + stm32_configgpio(GPIO_ETH_MII_TX_EN); + + /* Set up the RMII interface. */ + +#elif defined(CONFIG_STM32_RMII) + + /* Select the RMII interface */ + + stm32_selectrmii(); + + /* Provide clocking via MCO, MCO1 or MCO2: + * + * "MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + * clock (through a configurable prescaler) on PA8 pin." + * + * "MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or + * PLLI2S clock (through a configurable prescaler) on PC9 pin." + */ + +# if defined(CONFIG_STM32_RMII_MCO1) + /* Configure MC01 to drive the PHY. Board logic must provide MC01 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO1); + stm32_mco1config(BOARD_CFGR_MC01_SOURCE, BOARD_CFGR_MC01_DIVIDER); + +# elif defined(CONFIG_STM32_RMII_MCO2) + /* Configure MC02 to drive the PHY. Board logic must provide MC02 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO2); + stm32_mco2config(BOARD_CFGR_MC02_SOURCE, BOARD_CFGR_MC02_DIVIDER); + +# elif defined(CONFIG_STM32_RMII_MCO) + /* Setup MCO pin for alternative usage */ + + stm32_configgpio(GPIO_MCO); + stm32_mcoconfig(BOARD_CFGR_MCO_SOURCE); +# endif + + /* RMII interface pins (7): + * + * RMII_TXD[1:0], RMII_TX_EN, RMII_RXD[1:0], RMII_CRS_DV, MDC, MDIO, + * RMII_REF_CLK + */ + + stm32_configgpio(GPIO_ETH_RMII_CRS_DV); + stm32_configgpio(GPIO_ETH_RMII_REF_CLK); + stm32_configgpio(GPIO_ETH_RMII_RXD0); + stm32_configgpio(GPIO_ETH_RMII_RXD1); + stm32_configgpio(GPIO_ETH_RMII_TXD0); + stm32_configgpio(GPIO_ETH_RMII_TXD1); + /* stm32_configgpio(GPIO_ETH_RMII_TX_CLK); not needed? */ + stm32_configgpio(GPIO_ETH_RMII_TX_EN); + +#endif +#endif + +#ifdef CONFIG_STM32_ETH_PTP + /* Enable pulse-per-second (PPS) output signal */ + + stm32_configgpio(GPIO_ETH_PPS_OUT); +#endif +} + +/**************************************************************************** + * Function: stm32_ethreset + * + * Description: + * Reset the Ethernet block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_ethreset(FAR struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Reset the Ethernet on the AHB bus (F1 Connectivity Line) or AHB1 bus (F2 + * and F4) + */ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) + regval = stm32_getreg(STM32_RCC_AHBRSTR); + regval |= RCC_AHBRSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHBRSTR); + + regval &= ~RCC_AHBRSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHBRSTR); +#else + regval = stm32_getreg(STM32_RCC_AHB1RSTR); + regval |= RCC_AHB1RSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHB1RSTR); + + regval &= ~RCC_AHB1RSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHB1RSTR); +#endif + + /* Perform a software reset by setting the SR bit in the DMABMR register. + * This Resets all MAC subsystem internal registers and logic. After this + * reset all the registers holds their reset values. + */ + + regval = stm32_getreg(STM32_ETH_DMABMR); + regval |= ETH_DMABMR_SR; + stm32_putreg(regval, STM32_ETH_DMABMR); + + /* Wait for software reset to complete. The SR bit is cleared automatically + * after the reset operation has completed in all of the core clock domains. + */ + + while ((stm32_getreg(STM32_ETH_DMABMR) & ETH_DMABMR_SR) != 0); +} + +/**************************************************************************** + * Function: stm32_macconfig + * + * Description: + * Configure the Ethernet MAC for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_macconfig(FAR struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Set up the MACCR register */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval &= ~MACCR_CLEAR_BITS; + regval |= MACCR_SET_BITS; + + if (priv->fduplex) + { + /* Set the DM bit for full duplex support */ + + regval |= ETH_MACCR_DM; + } + + if (priv->mbps100) + { + /* Set the FES bit for 100Mbps fast ethernet support */ + + regval |= ETH_MACCR_FES; + } + + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Set up the MACFFR register */ + + regval = stm32_getreg(STM32_ETH_MACFFR); + regval &= ~MACFFR_CLEAR_BITS; + regval |= MACFFR_SET_BITS; + stm32_putreg(regval, STM32_ETH_MACFFR); + + /* Set up the MACHTHR and MACHTLR registers */ + + stm32_putreg(0, STM32_ETH_MACHTHR); + stm32_putreg(0, STM32_ETH_MACHTLR); + + /* Setup up the MACFCR register */ + + regval = stm32_getreg(STM32_ETH_MACFCR); + regval &= ~MACFCR_CLEAR_MASK; + regval |= MACFCR_SET_MASK; + stm32_putreg(regval, STM32_ETH_MACFCR); + + /* Setup up the MACVLANTR register */ + + stm32_putreg(0, STM32_ETH_MACVLANTR); + + /* DMA Configuration */ + /* Set up the DMAOMR register */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval &= ~DMAOMR_CLEAR_MASK; + regval |= DMAOMR_SET_MASK; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Set up the DMABMR register */ + + regval = stm32_getreg(STM32_ETH_DMABMR); + regval &= ~DMABMR_CLEAR_MASK; + regval |= DMABMR_SET_MASK; + stm32_putreg(regval, STM32_ETH_DMABMR); + + return OK; +} + +/**************************************************************************** + * Function: stm32_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_macaddress(FAR struct stm32_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address high register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[5] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[4]; + stm32_putreg(regval, STM32_ETH_MACA0HR); + + /* Set the MAC address low register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[3] << 24) | + ((uint32_t)dev->d_mac.ether_addr_octet[2] << 16) | + ((uint32_t)dev->d_mac.ether_addr_octet[1] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[0]; + stm32_putreg(regval, STM32_ETH_MACA0LR); +} + +/**************************************************************************** + * Function: stm32_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void stm32_ipv6multicast(FAR struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)stm32_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)stm32_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)stm32_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: stm32_macenable + * + * Description: + * Enable normal MAC operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_macenable(FAR struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Set the MAC address */ + + stm32_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + stm32_ipv6multicast(priv); +#endif + + /* Enable transmit state machine of the MAC for transmission on the MII */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval |= ETH_MACCR_TE; + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Flush Transmit FIFO */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_FTF; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Enable receive state machine of the MAC for reception from the MII */ + + /* Enables or disables the MAC reception. */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval |= ETH_MACCR_RE; + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Start DMA transmission */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_ST; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Start DMA reception */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_SR; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Enable Ethernet DMA interrupts. + * + * The STM32 hardware supports two interrupts: (1) one dedicated to normal + * Ethernet operations and the other, used only for the Ethernet wakeup + * event. The wake-up interrupt is not used by this driver. + * + * The first Ethernet vector is reserved for interrupts generated by the + * MAC and the DMA. The MAC provides PMT and time stamp trigger interrupts, + * neither of which are used by this driver. + */ + + stm32_putreg(ETH_MACIMR_ALLINTS, STM32_ETH_MACIMR); + + /* Ethernet DMA supports two classes of interrupts: Normal interrupt + * summary (NIS) and Abnormal interrupt summary (AIS) with a variety + * individual normal and abnormal interrupting events. Here only + * the normal receive event is enabled (unless DEBUG is enabled). Transmit + * events will only be enabled when a transmit interrupt is expected. + */ + + stm32_putreg((ETH_DMAINT_RECV_ENABLE | ETH_DMAINT_ERROR_ENABLE), STM32_ETH_DMAIER); + return OK; +} + +/**************************************************************************** + * Function: stm32_ethconfig + * + * Description: + * Configure the Ethernet interface for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ethconfig(FAR struct stm32_ethmac_s *priv) +{ + int ret; + + /* NOTE: The Ethernet clocks were initialized early in the boot-up + * sequence in stm32_rcc.c. + */ + + /* Reset the Ethernet block */ + + nllvdbg("Reset the Ethernet block\n"); + stm32_ethreset(priv); + + /* Initialize the PHY */ + + nllvdbg("Initialize the PHY\n"); + ret = stm32_phyinit(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the MAC and DMA */ + + nllvdbg("Initialize the MAC and DMA\n"); + ret = stm32_macconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the free buffer list */ + + stm32_initbuffer(priv); + + /* Initialize TX Descriptors list: Chain Mode */ + + stm32_txdescinit(priv); + + /* Initialize RX Descriptors list: Chain Mode */ + + stm32_rxdescinit(priv); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + return stm32_macenable(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the STM32 chip + * supports multiple Ethernet controllers, then board specific logic + * must implement up_netinitialize() and call this function to initialize + * the desired interfaces. + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if STM32_NETHERNET == 1 +static inline +#endif + +int stm32_ethinitialize(int intf) +{ + struct stm32_ethmac_s *priv; + + nvdbg("intf: %d\n", intf); + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(intf < STM32_NETHERNET); + priv = &g_stm32ethmac[intf]; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct stm32_ethmac_s)); + priv->dev.d_ifup = stm32_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = stm32_ifdown; /* I/F down callback */ + priv->dev.d_txavail = stm32_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = stm32_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = stm32_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = stm32_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)g_stm32ethmac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Configure GPIO pins to support Ethernet */ + + stm32_ethgpioconfig(priv); + + /* Attach the IRQ to the driver */ + + if (irq_attach(STM32_IRQ_ETH, stm32_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Put the interface in the down state. */ + + stm32_ifdown(&priv->dev); + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. If STM32_NETHERNET + * greater than one, then board specific logic will have to supply a + * version of up_netinitialize() that calls stm32_ethinitialize() with + * the appropriate interface number. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +#if STM32_NETHERNET == 1 +void up_netinitialize(void) +{ + (void)stm32_ethinitialize(0); +} +#endif + +#endif /* STM32_NETHERNET > 0 */ +#endif /* CONFIG_NET && CONFIG_STM32_ETHMAC */ diff --git a/arch/arm/src/stm32/stm32_eth.h b/arch/arm/src/stm32/stm32_eth.h new file mode 100644 index 0000000000000000000000000000000000000000..7b0fbf8b47faf5faf265310886721b595d45140a --- /dev/null +++ b/arch/arm/src/stm32/stm32_eth.h @@ -0,0 +1,121 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_eth.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_ETH_H +#define __ARCH_ARM_SRC_STM32_STM32_ETH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if STM32_NETHERNET > 0 + +#include "chip/stm32_eth.h" + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Function: stm32_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the STM32 chip supports + * multiple Ethernet controllers, then board specific logic must implement + * up_netinitialize() and call this function to initialize the desired interfaces. + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value identifies which + * EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#if STM32_NETHERNET > 1 +int stm32_ethinitialize(int intf); +#endif + +/************************************************************************************ + * Function: stm32_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_STM32_PHYINIT is defined in the configuration then the board specific + * logic must provide stm32_phyinitialize(); The STM32 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_PHYINIT +int stm32_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* STM32_NETHERNET > 0 */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_ETH_H */ + diff --git a/arch/arm/src/stm32/stm32_exti.h b/arch/arm/src/stm32/stm32_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..6a34582c6763f82bfa08cfa08a63218462c1214f --- /dev/null +++ b/arch/arm/src/stm32/stm32_exti.h @@ -0,0 +1,119 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_exti.h + * + * Copyright (C) 2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32_STM32_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32_exti.h" + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Name: stm32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +xcpt_t stm32_exti_alarm(bool risingedge, bool fallingedge, bool event, xcpt_t func); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32/stm32_exti_alarm.c b/arch/arm/src/stm32/stm32_exti_alarm.c new file mode 100644 index 0000000000000000000000000000000000000000..f38574f2523eb8a3e58ec9b9f6a1bb621cd8fa99 --- /dev/null +++ b/arch/arm/src/stm32/stm32_exti_alarm.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_exti_alarm.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the ALARM EXTI */ + +static xcpt_t stm32_exti_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_alarm_isr + * + * Description: + * EXTI ALARM interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32_exti_alarm_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI_RTC_ALARM, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callback) + { + ret = stm32_exti_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edget + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_callback; + stm32_exti_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32_IRQ_RTCALRM, stm32_exti_alarm_isr); + up_enable_irq(STM32_IRQ_RTCALRM); + } + else + { + up_disable_irq(STM32_IRQ_RTCALRM); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : EXTI_RTC_ALARM, + risingedge ? EXTI_RTC_ALARM : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : EXTI_RTC_ALARM, + fallingedge ? EXTI_RTC_ALARM : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : EXTI_RTC_ALARM, + event ? EXTI_RTC_ALARM : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : EXTI_RTC_ALARM, + func ? EXTI_RTC_ALARM : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32/stm32_exti_gpio.c b/arch/arm/src/stm32/stm32_exti_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..6aa2cf4be2b0900fed3f422e7f4f2ffd7f3e4dda --- /dev/null +++ b/arch/arm/src/stm32/stm32_exti_gpio.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_exti_gpio.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static xcpt_t stm32_exti_callbacks[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routines - Dispatchers + ****************************************************************************/ + +static int stm32_exti0_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0001, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[0]) + { + ret = stm32_exti_callbacks[0](irq, context); + } + + return ret; +} + +static int stm32_exti1_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0002, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[1]) + { + ret = stm32_exti_callbacks[1](irq, context); + } + + return ret; +} + +static int stm32_exti2_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0004, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[2]) + { + ret = stm32_exti_callbacks[2](irq, context); + } + + return ret; +} + +static int stm32_exti3_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0008, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[3]) + { + ret = stm32_exti_callbacks[3](irq, context); + } + + return ret; +} + +static int stm32_exti4_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0010, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[4]) + { + ret = stm32_exti_callbacks[4](irq, context); + } + + return ret; +} + +static int stm32_exti_multiisr(int irq, void *context, int first, int last) +{ + uint32_t pr; + int pin; + int ret = OK; + + /* Examine the state of each pin in the group */ + + pr = getreg32(STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + for (pin = first; pin <= last; pin++) + { + /* Is an interrupt pending on this pin? */ + + uint32_t mask = (1 << pin); + if ((pr & mask) != 0) + { + /* Clear the pending interrupt */ + + putreg32(mask, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[pin]) + { + int tmp = stm32_exti_callbacks[pin](irq, context); + if (tmp != OK) + { + ret = tmp; + } + } + } + } + + return ret; +} + +static int stm32_exti95_isr(int irq, void *context) +{ + return stm32_exti_multiisr(irq, context, 5, 9); +} + +static int stm32_exti1510_isr(int irq, void *context) +{ + return stm32_exti_multiisr(irq, context, 10, 15); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func) +{ + uint32_t pin = pinset & GPIO_PIN_MASK; + uint32_t exti = STM32_EXTI_BIT(pin); + int irq; + xcpt_t handler; + xcpt_t oldhandler = NULL; + int nshared; + xcpt_t *shared_cbs; + int i; + + /* Select the interrupt handler for this EXTI pin */ + + if (pin < 5) + { + irq = pin + STM32_IRQ_EXTI0; + nshared = 1; + shared_cbs = &stm32_exti_callbacks[pin]; + switch (pin) + { + case 0: + handler = stm32_exti0_isr; + break; + + case 1: + handler = stm32_exti1_isr; + break; + + case 2: + handler = stm32_exti2_isr; + break; + + case 3: + handler = stm32_exti3_isr; + break; + + default: + handler = stm32_exti4_isr; + break; + } + } + else if (pin < 10) + { + irq = STM32_IRQ_EXTI95; + handler = stm32_exti95_isr; + shared_cbs = &stm32_exti_callbacks[5]; + nshared = 5; + } + else + { + irq = STM32_IRQ_EXTI1510; + handler = stm32_exti1510_isr; + shared_cbs = &stm32_exti_callbacks[10]; + nshared = 6; + } + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_callbacks[pin]; + stm32_exti_callbacks[pin] = func; + + /* Install external interrupt handlers */ + + if (func) + { + irq_attach(irq, handler); + up_enable_irq(irq); + } + else + { + /* Only disable IRQ if shared handler does not have any active + * callbacks. + */ + + for (i = 0; i < nshared; i++) + { + if (shared_cbs[i] != NULL) + { + break; + } + } + + if (i == nshared) + { + up_disable_irq(irq); + } + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + if (event || func) + { + pinset |= GPIO_EXTI; + } + + stm32_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : exti, + risingedge ? exti : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : exti, + fallingedge ? exti : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : exti, + event ? exti : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : exti, + func ? exti : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32/stm32_exti_pwr.c b/arch/arm/src/stm32/stm32_exti_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..f57e85e6ca9422c7250ece3dfb0a5f2eeddff032 --- /dev/null +++ b/arch/arm/src/stm32/stm32_exti_pwr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_exti_pwr.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Gregory Nutt + * Dmitry Nikolaev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" +#include "stm32_exti_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the PVD EXTI */ + +static xcpt_t stm32_exti_pvd_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_pvd_isr + * + * Description: + * EXTI PVD interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32_exti_pvd_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI_PVD_LINE, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_pvd_callback) + { + ret = stm32_exti_pvd_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_pvd_callback; + stm32_exti_pvd_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32_IRQ_PVD, stm32_exti_pvd_isr); + up_enable_irq(STM32_IRQ_PVD); + } + else + { + up_disable_irq(STM32_IRQ_PVD); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : EXTI_PVD_LINE, + risingedge ? EXTI_PVD_LINE : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : EXTI_PVD_LINE, + fallingedge ? EXTI_PVD_LINE : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : EXTI_PVD_LINE, + event ? EXTI_PVD_LINE : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : EXTI_PVD_LINE, + func ? EXTI_PVD_LINE : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32/stm32_exti_pwr.h b/arch/arm/src/stm32/stm32_exti_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..4955045a2f19e1695a7619147f0f30017111512f --- /dev/null +++ b/arch/arm/src/stm32/stm32_exti_pwr.h @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_exti_pwr.h + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Dmitry Nikolaev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef STM32_EXTI_PWR_H_ +#define STM32_EXTI_PWR_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func); + +#endif /* STM32_EXTI_PWR_H_ */ diff --git a/arch/arm/src/stm32/stm32_flash.c b/arch/arm/src/stm32/stm32_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..56aa1f75edcee80a31cd3cda5831748b8ba8c14c --- /dev/null +++ b/arch/arm/src/stm32/stm32_flash.c @@ -0,0 +1,365 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_flash.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Provides standard flash access functions, to be used by the flash mtd driver. + * The interface is defined in the include/nuttx/progmem.h + * + * Requirements during write/erase operations on FLASH: + * - HSI must be ON. + * - Low Power Modes are not permitted during write/erase + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "stm32_flash.h" +#include "stm32_rcc.h" +#include "stm32_waste.h" + +#include "up_arch.h" + +/* Only for the STM32F[1|3|4]0xx family for now */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined (CONFIG_STM32_STM32F40XX) + +#if defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) && \ + (defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)) +# warning "Default Flash Configuration Used - See Override Flash Size Designator" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xCDEF89AB + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +#define FLASH_CR_PAGE_ERASE FLASH_CR_PER +#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPRT_ERR +#elif defined(CONFIG_STM32_STM32F40XX) +#define FLASH_CR_PAGE_ERASE FLASH_CR_SER +#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPERR +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +void stm32_flash_unlock(void) +{ + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { + up_waste(); + } + + if (getreg32(STM32_FLASH_CR) & FLASH_CR_LOCK) + { + /* Unlock sequence */ + + putreg32(FLASH_KEY1, STM32_FLASH_KEYR); + putreg32(FLASH_KEY2, STM32_FLASH_KEYR); + } +} + +void stm32_flash_lock(void) +{ + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); +} + + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + +size_t up_progmem_pagesize(size_t page) +{ + return STM32_FLASH_PAGESIZE; +} + +ssize_t up_progmem_getpage(size_t addr) +{ + if (addr >= STM32_FLASH_BASE) + { + addr -= STM32_FLASH_BASE; + } + + if (addr >= STM32_FLASH_SIZE) + { + return -EFAULT; + } + + return addr / STM32_FLASH_PAGESIZE; +} + +size_t up_progmem_getaddress(size_t page) +{ + if (page >= STM32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + return page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE; +} + +#endif /* defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) */ + +#ifdef CONFIG_STM32_STM32F40XX + +size_t up_progmem_pagesize(size_t page) +{ + static const size_t page_sizes[STM32_FLASH_NPAGES] = STM32_FLASH_SIZES; + + if (page >= sizeof(page_sizes) / sizeof(*page_sizes)) + { + return 0; + } + else + { + return page_sizes[page]; + } +} + +ssize_t up_progmem_getpage(size_t addr) +{ + size_t page_end = 0; + size_t i; + + if (addr >= STM32_FLASH_BASE) + { + addr -= STM32_FLASH_BASE; + } + + if (addr >= STM32_FLASH_SIZE) + { + return -EFAULT; + } + + for (i = 0; i < STM32_FLASH_NPAGES; ++i) + { + page_end += up_progmem_pagesize(i); + if (page_end > addr) + { + return i; + } + } + + return -EFAULT; +} + +size_t up_progmem_getaddress(size_t page) +{ + size_t base_address = STM32_FLASH_BASE; + size_t i; + + if (page >= STM32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + for (i = 0; i < page; ++i) + { + base_address += up_progmem_pagesize(i); + } + + return base_address; +} + +#endif /* def CONFIG_STM32_STM32F40XX */ + +size_t up_progmem_npages(void) +{ + return STM32_FLASH_NPAGES; +} + +bool up_progmem_isuniform(void) +{ +#ifdef STM32_FLASH_PAGESIZE + return true; +#else + return false; +#endif /* def STM32_FLASH_PAGESIZE */ +} + +ssize_t up_progmem_erasepage(size_t page) +{ +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + size_t page_address; +#endif /* defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) */ + + if (page >= STM32_FLASH_NPAGES) + { + return -EFAULT; + } + + /* Get flash ready and begin erasing single page */ + + if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) + { + return -EPERM; + } + + stm32_flash_unlock(); + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PAGE_ERASE); + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) + /* Must be valid - page index checked above */ + + page_address = up_progmem_getaddress(page); + putreg32(page_address, STM32_FLASH_AR); + +#elif defined(CONFIG_STM32_STM32F40XX) + modifyreg32(STM32_FLASH_CR, FLASH_CR_SNB_MASK, FLASH_CR_SNB(page)); +#endif + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT); + + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); + + modifyreg32(STM32_FLASH_CR, FLASH_CR_PAGE_ERASE, 0); + + /* Verify */ + if (up_progmem_ispageerased(page) == 0) + { + return up_progmem_pagesize(page); /* success */ + } + else + { + return -EIO; /* failure */ + } +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= STM32_FLASH_NPAGES) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != 0xff) + { + bwritten++; + } + } + + return bwritten; +} + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) +{ + uint16_t *hword = (uint16_t *)buf; + size_t written = count; + + /* STM32 requires half-word access */ + + if (count & 1) + { + return -EINVAL; + } + + /* Check for valid address range */ + + if (addr >= STM32_FLASH_BASE) + { + addr -= STM32_FLASH_BASE; + } + + if ((addr+count) >= STM32_FLASH_SIZE) + { + return -EFAULT; + } + + /* Get flash ready and begin flashing */ + + if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION)) + { + return -EPERM; + } + + stm32_flash_unlock(); + + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); + +#if defined(CONFIG_STM32_STM32F40XX) + /* TODO: implement up_progmem_write() to support other sizes than 16-bits */ + modifyreg32(STM32_FLASH_CR, FLASH_CR_PSIZE_MASK, FLASH_CR_PSIZE_X16); +#endif + + for (addr += STM32_FLASH_BASE; count; count -= 2, hword++, addr += 2) + { + /* Write half-word and wait to complete */ + + putreg16(*hword, addr); + + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste(); + + /* Verify */ + + if (getreg32(STM32_FLASH_SR) & FLASH_SR_WRITE_PROTECTION_ERROR) + { + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); + return -EROFS; + } + + if (getreg16(addr) != *hword) + { + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); + return -EIO; + } + } + + modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); + return written; +} + +#endif /* defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined (CONFIG_STM32_STM32F40XX) */ diff --git a/arch/arm/src/stm32/stm32_flash.h b/arch/arm/src/stm32/stm32_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..10c5cc189ed8ee159aa0d0bc5ee900867d6064b4 --- /dev/null +++ b/arch/arm/src/stm32/stm32_flash.h @@ -0,0 +1,49 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_flash.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32_STM32_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/stm32_flash.h" + +#endif /* __ARCH_ARM_SRC_STM32_STM32_FLASH_H */ diff --git a/arch/arm/src/stm32/stm32_fsmc.h b/arch/arm/src/stm32/stm32_fsmc.h new file mode 100644 index 0000000000000000000000000000000000000000..f865c00b5a7a3e1065ed9fefa5af75c144945ae1 --- /dev/null +++ b/arch/arm/src/stm32/stm32_fsmc.h @@ -0,0 +1,397 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_fsmc.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_FSMC_H +#define __ARCH_ARM_SRC_STM32_STM32_FSMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_FSMC_BCR_OFFSET(n) (8*((n)-1)) +#define STM32_FSMC_BCR1_OFFSET 0x0000 /* SRAM/NOR-Flash chip-select control registers 1 */ +#define STM32_FSMC_BCR2_OFFSET 0x0008 /* SRAM/NOR-Flash chip-select control registers 2 */ +#define STM32_FSMC_BCR3_OFFSET 0x0010 /* SRAM/NOR-Flash chip-select control registers 3 */ +#define STM32_FSMC_BCR4_OFFSET 0x0018 /* SRAM/NOR-Flash chip-select control registers 4 */ + +#define STM32_FSMC_BTR_OFFSET(n) (8*((n)-1)+0x0004) +#define STM32_FSMC_BTR1_OFFSET 0x0004 /* SRAM/NOR-Flash chip-select timing registers 1 */ +#define STM32_FSMC_BTR2_OFFSET 0x000c /* SRAM/NOR-Flash chip-select timing registers 2 */ +#define STM32_FSMC_BTR3_OFFSET 0x0014 /* SRAM/NOR-Flash chip-select timing registers 3 */ +#define STM32_FSMC_BTR4_OFFSET 0x001c /* SRAM/NOR-Flash chip-select timing registers 4 */ + +#define STM32_FSMC_BWTR_OFFSET(n) (8*((n)-1)+0x0104) +#define STM32_FSMC_BWTR1_OFFSET 0x0104 /* SRAM/NOR-Flash write timing registers 1 */ +#define STM32_FSMC_BWTR2_OFFSET 0x010c /* SRAM/NOR-Flash write timing registers 2 */ +#define STM32_FSMC_BWTR3_OFFSET 0x0114 /* SRAM/NOR-Flash write timing registers 3 */ +#define STM32_FSMC_BWTR4_OFFSET 0x011c /* SRAM/NOR-Flash write timing registers 4 */ + +#define STM32_FSMC_PCR_OFFSET(n) (0x0020*((n)-1)+0x0040) +#define STM32_FSMC_PCR2_OFFSET 0x0060 /* NAND Flash/PC Card controller register 2 */ +#define STM32_FSMC_PCR3_OFFSET 0x0080 /* NAND Flash/PC Card controller register 3 */ +#define STM32_FSMC_PCR4_OFFSET 0x00a0 /* NAND Flash/PC Card controller register 4 */ + +#define STM32_FSMC_SR_OFFSET(n) (0x0020*((n)-1)+0x0044) +#define STM32_FSMC_SR2_OFFSET 0x0064 /* NAND Flash/PC Card controller register 2 */ +#define STM32_FSMC_SR3_OFFSET 0x0084 /* NAND Flash/PC Card controller register 3 */ +#define STM32_FSMC_SR4_OFFSET 0x00a4 /* NAND Flash/PC Card controller register 4 */ + +#define STM32_FSMC_PMEM_OFFSET(n) (0x0020*((n)-1)+0x0048) +#define STM32_FSMC_PMEM2_OFFSET 0x0068 /* Common memory space timing register 2 */ +#define STM32_FSMC_PMEM3_OFFSET 0x0088 /* Common memory space timing register 3 */ +#define STM32_FSMC_PMEM4_OFFSET 0x00a8 /* Common memory space timing register 4 */ + +#define STM32_FSMC_PATT_OFFSET(n) (0x0020*((n)-1)+0x004c) +#define STM32_FSMC_PATT2_OFFSET 0x006c /* Attribute memory space timing register 2 */ +#define STM32_FSMC_PATT3_OFFSET 0x008c /* Attribute memory space timing register 3 */ +#define STM32_FSMC_PATT4_OFFSET 0x00ac /* Attribute memory space timing register 4 */ + +#define STM32_PIO4_OFFSET 0x00b0 /* I/O space timing register 4 */ + +#define STM32_FSMC_ECCR_OFFSET(n) (0x0020*((n)-1)+0x003c) +#define STM32_FSMC_ECCR2_OFFSET 0x0054 /* ECC result register 2 */ +#define STM32_FSMC_ECCR3_OFFSET 0x0074 /* ECC result register 3 */ + +#if defined(CONFIG_STM32_STM32F429) +# define STM32_FSMC_SDCR1_OFFSET 0x0140 /* SDRAM Control Register, Bank 0 */ +# define STM32_FSMC_SDCR2_OFFSET 0x0144 /* SDRAM Control Register, Bank 1 */ + +# define STM32_FSMC_SDTR1_OFFSET 0x0148 /* SDRAM Timing Register?, Bank 0 */ +# define STM32_FSMC_SDTR2_OFFSET 0x014c /* SDRAM Timing Register?, Bank 1 */ + +# define STM32_FSMC_SDCMR_OFFSET 0x0150 /* SDRAM Config register? */ +# define STM32_FSMC_SDRTR_OFFSET 0x0154 /* SDRAM Refresh Timing Register maybe? */ +# define STM32_FSMC_SDSR_OFFSET 0x0158 /* SDRAM Status Register */ +#endif + +/* Register Addresses ***************************************************************/ + +#define STM32_FSMC_BCR(n) (STM32_FSMC_BASE+STM32_FSMC_BCR_OFFSET(n)) +#define STM32_FSMC_BCR1 (STM32_FSMC_BASE+STM32_FSMC_BCR1_OFFSET ) +#define STM32_FSMC_BCR2 (STM32_FSMC_BASE+STM32_FSMC_BCR2_OFFSET ) +#define STM32_FSMC_BCR3 (STM32_FSMC_BASE+STM32_FSMC_BCR3_OFFSET ) +#define STM32_FSMC_BCR4 (STM32_FSMC_BASE+STM32_FSMC_BCR4_OFFSET ) + +#define STM32_FSMC_BTR(n) (STM32_FSMC_BASE+STM32_FSMC_BTR_OFFSET(n)) +#define STM32_FSMC_BTR1 (STM32_FSMC_BASE+STM32_FSMC_BTR1_OFFSET ) +#define STM32_FSMC_BTR2 (STM32_FSMC_BASE+STM32_FSMC_BTR2_OFFSET ) +#define STM32_FSMC_BTR3 (STM32_FSMC_BASE+STM32_FSMC_BTR3_OFFSET ) +#define STM32_FSMC_BTR4 (STM32_FSMC_BASE+STM32_FSMC_BTR4_OFFSET ) + +#define STM32_FSMC_BWTR(n) (STM32_FSMC_BASE+STM32_FSMC_BWTR_OFFSET(n)) +#define STM32_FSMC_BWTR1 (STM32_FSMC_BASE+STM32_FSMC_BWTR1_OFFSET ) +#define STM32_FSMC_BWTR2 (STM32_FSMC_BASE+STM32_FSMC_BWTR2_OFFSET ) +#define STM32_FSMC_BWTR3 (STM32_FSMC_BASE+STM32_FSMC_BWTR3_OFFSET ) +#define STM32_FSMC_BWTR4 (STM32_FSMC_BASE+STM32_FSMC_BWTR4_OFFSET ) + +#define STM32_FSMC_PCR(n) (STM32_FSMC_BASE+STM32_FSMC_PCR_OFFSET(n)) +#define STM32_FSMC_PCR2 (STM32_FSMC_BASE+STM32_FSMC_PCR2_OFFSET ) +#define STM32_FSMC_PCR3 (STM32_FSMC_BASE+STM32_FSMC_PCR3_OFFSET ) +#define STM32_FSMC_PCR4 (STM32_FSMC_BASE+STM32_FSMC_PCR4_OFFSET ) + +#define STM32_FSMC_SR(n) (STM32_FSMC_BASE+STM32_FSMC_SR_OFFSET(n)) +#define STM32_FSMC_SR2 (STM32_FSMC_BASE+STM32_FSMC_SR2_OFFSET ) +#define STM32_FSMC_SR3 (STM32_FSMC_BASE+STM32_FSMC_SR3_OFFSET ) +#define STM32_FSMC_SR4 (STM32_FSMC_BASE+STM32_FSMC_SR4_OFFSET ) + +#define STM32_FSMC_PMEM(n) (STM32_FSMC_BASE+STM32_FSMC_PMEM_OFFSET(n)) +#define STM32_FSMC_PMEM2 (STM32_FSMC_BASE+STM32_FSMC_PMEM2_OFFSET ) +#define STM32_FSMC_PMEM3 (STM32_FSMC_BASE+STM32_FSMC_PMEM3_OFFSET ) +#define STM32_FSMC_PMEM4 (STM32_FSMC_BASE+STM32_FSMC_PMEM4_OFFSET ) + +#define STM32_FSMC_PATT(n) (STM32_FSMC_BASE+STM32_FSMC_PATT_OFFSET(n)) +#define STM32_FSMC_PATT2 (STM32_FSMC_BASE+STM32_FSMC_PATT2_OFFSET ) +#define STM32_FSMC_PATT3 (STM32_FSMC_BASE+STM32_FSMC_PATT3_OFFSET ) +#define STM32_FSMC_PATT4 (STM32_FSMC_BASE+STM32_FSMC_PATT4_OFFSET ) + +#define STM32_PIO4 (STM32_FSMC_BASE+STM32_FSMC_PIO4_OFFSET ) + +#define STM32_FSMC_ECCR(n) (STM32_FSMC_BASE+STM32_FSMC_ECCR_OFFSET(n)) +#define STM32_FSMC_ECCR2 (STM32_FSMC_BASE+STM32_FSMC_ECCR2_OFFSET ) +#define STM32_FSMC_ECCR3 (STM32_FSMC_BASE+STM32_FSMC_ECCR3_OFFSET ) + +#if defined(CONFIG_STM32_STM32F429) +# define STM32_FSMC_SDCR1 (STM32_FSMC_BASE+STM32_FSMC_SDCR1_OFFSET) +# define STM32_FSMC_SDCR2 (STM32_FSMC_BASE+STM32_FSMC_SDCR2_OFFSET) + +# define STM32_FSMC_SDTR1 (STM32_FSMC_BASE+STM32_FSMC_SDTR1_OFFSET) +# define STM32_FSMC_SDTR2 (STM32_FSMC_BASE+STM32_FSMC_SDTR2_OFFSET) + +# define STM32_FSMC_SDCMR (STM32_FSMC_BASE+STM32_FSMC_SDCMR_OFFSET) +# define STM32_FSMC_SDRTR (STM32_FSMC_BASE+STM32_FSMC_SDRTR_OFFSET) +# define STM32_FSMC_SDSR (STM32_FSMC_BASE+STM32_FSMC_SDSR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +#define FSMC_BCR_MBKEN (1 << 0) /* Memory bank enable bit */ +#define FSMC_BCR_MUXEN (1 << 1) /* Address/data multiplexing enable bit */ +#define FSMC_BCR_MTYP_SHIFT (2) /* Memory type */ +#define FSMC_BCR_MTYP_MASK (3 << FSMC_BCR_MTYP_SHIFT) +# define FSMC_BCR_SRAM (0 << FSMC_BCR_MTYP_SHIFT) +# define FSMC_BCR_ROM (0 << FSMC_BCR_MTYP_SHIFT) +# define FSMC_BCR_PSRAM (1 << FSMC_BCR_MTYP_SHIFT) +# define FSMC_BCR_CRAM (1 << FSMC_BCR_MTYP_SHIFT) +# define FSMC_BCR_NOR (2 << FSMC_BCR_MTYP_SHIFT) +#define FSMC_BCR_MWID_SHIFT (4) /* Memory data bus width */ +#define FSMC_BCR_MWID_MASK (3 << FSMC_BCR_MWID_SHIFT) +# define FSMC_BCR_MWID8 (0 << FSMC_BCR_MWID_SHIFT) +# define FSMC_BCR_MWID16 (1 << FSMC_BCR_MWID_SHIFT) +#define FSMC_BCR_FACCEN (1 << 6) /* Flash access enable */ +#define FSMC_BCR_BURSTEN (1 << 8) /* Burst enable bit */ +#define FSMC_BCR_WAITPOL (1 << 9) /* Wait signal polarity bit */ +#define FSMC_BCR_WRAPMOD (1 << 10) /* Wrapped burst mode support */ +#define FSMC_BCR_WAITCFG (1 << 11) /* Wait timing configuration */ +#define FSMC_BCR_WREN (1 << 12) /* Write enable bit */ +#define FSMC_BCR_WAITEN (1 << 13) /* Wait enable bit */ +#define FSMC_BCR_EXTMOD (1 << 14) /* Extended mode enable */ +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define FSMC_BCR_ASYNCWAIT (1 << 15) /* Wait signal during asynchronous transfers */ +#endif +#define FSMC_BCR_CBURSTRW (1 << 19) /* Write burst enable */ + +#define FSMC_BCR_RSTVALUE 0x000003d2 + +#define FSMC_BTR_ADDSET_SHIFT (0) /* Address setup phase duration */ +#define FSMC_BTR_ADDSET_MASK (15 << FSMC_BTR_ADDSET_SHIFT) +# define FSMC_BTR_ADDSET(n) ((n-1) << FSMC_BTR_ADDSET_SHIFT) /* (n)xHCLK n=1..16 */ +#define FSMC_BTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ +#define FSMC_BTR_ADDHLD_MASK (15 << FSMC_BTR_ADDHLD_SHIFT) +# define FSMC_BTR_ADDHLD(n) ((n-1) << FSMC_BTR_ADDHLD_SHIFT) /* (n)xHCLK n=2..16*/ +#define FSMC_BTR_DATAST_SHIFT (8) /* Data-phase duration */ +#define FSMC_BTR_DATAST_MASK (255 << FSMC_BTR_DATAST_SHIFT) +# define FSMC_BTR_DATAST(n) ((n-1) << FSMC_BTR_DATAST_SHIFT) /* (n)xHCLK n=2..256 */ +#define FSMC_BTR_BUSTURN_SHIFT (16) /* Bus turnaround phase duration */ +#define FSMC_BTR_BUSTURN_MASK (15 << FSMC_BTR1_BUSTURN_SHIFT) +# define FSMC_BTR_BUSTURN(n) ((n-1) << FSMC_BTR_BUSTURN_SHIFT) /* (n)xHCLK n=1..16 */ +#define FSMC_BTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ +#define FSMC_BTR_CLKDIV_MASK (15 << FSMC_BTR_CLKDIV_SHIFT) +# define FSMC_BTR_CLKDIV(n) ((n-1) << FSMC_BTR_CLKDIV_SHIFT) /* (n)xHCLK n=2..16 */ +#define FSMC_BTR_DATLAT_SHIFT (24) /* Data latency */ +#define FSMC_BTR_DATLAT_MASK (15 << FSMC_BTR_DATLAT_SHIFT) +# define FSMC_BTR_DATLAT(n) ((n-2) << FSMC_BTR_DATLAT_SHIFT) /* (n)xHCLK n=2..17 */ +#define FSMC_BTR_ACCMOD_SHIFT (28) /* Access mode */ +#define FSMC_BTR_ACCMOD_MASK (3 << FSMC_BTR_ACCMOD_SHIFT) +# define FSMC_BTR_ACCMODA (0 << FSMC_BTR_ACCMOD_SHIFT) +# define FSMC_BTR_ACCMODB (1 << FSMC_BTR_ACCMOD_SHIFT) +# define FSMC_BTR_ACCMODC (2 << FSMC_BTR_ACCMOD_SHIFT) +# define FSMC_BTR_ACCMODD (3 << FSMC_BTR_ACCMOD_SHIFT) + +#define FSMC_BTR_RSTVALUE 0xffffffff + +#define FSMC_BWTR_ADDSET_SHIFT (0) /* Address setup phase duration */ +#define FSMC_BWTR_ADDSET_MASK (15 << FSMC_BWTR_ADDSET_SHIFT) +# define FSMC_BWTR_ADDSET(n) ((n-1) << FSMC_BWTR_ADDSET_SHIFT) /* (n)xHCLK n=1..16 */ +#define FSMC_BWTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ +#define FSMC_BWTR_ADDHLD_MASK (15 << FSMC_BWTR_ADDHLD_SHIFT) +# define FSMC_BWTR_ADDHLD(n) ((n-1) << FSMC_BWTR_ADDHLD_SHIFT) /* (n)xHCLK n=2..16*/ +#define FSMC_BWTR_DATAST_SHIFT (8) /* Data-phase duration */ +#define FSMC_BWTR_DATAST_MASK (255 << FSMC_BWTR_DATAST_SHIFT) +# define FSMC_BWTR_DATAST(n) ((n-1) << FSMC_BWTR_DATAST_SHIFT) /* (n)xHCLK n=2..256 */ +#define FSMC_BWTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ +#define FSMC_BWTR_CLKDIV_MASK (15 << FSMC_BWTR_CLKDIV_SHIFT) +# define FSMC_BWTR_CLKDIV(n) ((n-1) << FSMC_BWTR_CLKDIV_SHIFT) /* (n)xHCLK n=2..16 */ +#define FSMC_BWTR_DATLAT_SHIFT (24) /* Data latency */ +#define FSMC_BWTR_DATLAT_MASK (15 << FSMC_BWTR_DATLAT_SHIFT) +# define FSMC_BWTR_DATLAT(n) ((n-2) << FSMC_BWTR_DATLAT_SHIFT) /* (n)xHCLK n=2..17 */ +#define FSMC_BWTR_ACCMOD_SHIFT (28) /* Access mode */ +#define FSMC_BWTR_ACCMOD_MASK (3 << FSMC_BWTR_ACCMOD_SHIFT) +# define FSMC_BWTR_ACCMODA (0 << FSMC_BWTR_ACCMOD_SHIFT) +# define FSMC_BWTR_ACCMODB (1 << FSMC_BWTR_ACCMOD_SHIFT) +# define FSMC_BWTR_ACCMODC (2 << FSMC_BWTR_ACCMOD_SHIFT) +# define FSMC_BWTR_ACCMODD (3 << FSMC_BTR_ACCMOD_SHIFT) + +#define FSMC_PCR_PWAITEN (1 << 1) /* Wait feature enable bit */ +#define FSMC_PCR_PBKEN (1 << 2) /* PC Card/NAND Flash memory bank enable bit */ +#define FSMC_PCR_PTYP (1 << 3) /* Memory type */ +#define FSMC_PCR_PWID_SHIFT (4) /* NAND Flash databus width */ +#define FSMC_PCR_PWID_MASK (3 << FSMC_PCR_PWID_SHIFT) +# define FSMC_PCR_PWID8 (0 << FSMC_PCR_PWID_SHIFT) +# define FSMC_PCR_PWID16 (1 << FSMC_PCR_PWID_SHIFT) +#define FSMC_PCR_ECCEN (1 << 6) /* ECC computation logic enable bit */ +#define FSMC_PCR_TCLR_SHIFT (9) /* CLE to RE delay */ +#define FSMC_PCR_TCLR_MASK (15 << FSMC_PCR_TCLR_SHIFT) +# define FSMC_PCR_TCLR(n) ((n-1) << FSMC_PCR_TCLR_SHIFT) /* (n)xHCLK n=1..16 */ +#define FSMC_PCR_TAR_SHIFT (13) /* ALE to RE delay */ +#define FSMC_PCR_TAR_MASK (15 << FSMC_PCR_TAR_MASK) +# define FSMC_PCR_TAR(n) ((n-1) << FSMC_PCR_TAR_SHIFT) /* (n)xHCLK n=1..16 */ +#define FSMC_PCR_ECCPS_SHIFT (17) /* ECC page size */ +#define FSMC_PCR_ECCPS_MASK (7 << FSMC_PCR_ECCPS_SHIFT) +# define FSMC_PCR_ECCPS256 (0 << FSMC_PCR_ECCPS_SHIFT) /* 256 bytes */ +# define FSMC_PCR_ECCPS512 (1 << FSMC_PCR_ECCPS_SHIFT) /* 512 bytes */ +# define FSMC_PCR_ECCPS1024 (2 << FSMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ +# define FSMC_PCR_ECCPS2048 (3 << FSMC_PCR_ECCPS_SHIFT) /* 2048 bytes */ +# define FSMC_PCR_ECCPS4096 (4 << FSMC_PCR_ECCPS_SHIFT) /* 8192 bytes */ +# define FSMC_PCR_ECCPS8192 (5 << FSMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ + +#define FSMC_SR_IRS (1 << 0) /* Interrupt Rising Edge status */ +#define FSMC_SR_ILS (1 << 1) /* Interrupt Level status */ +#define FSMC_SR_IFS (1 << 2) /* Interrupt Falling Edge status */ +#define FSMC_SR_IREN (1 << 3) /* Interrupt Rising Edge detection Enable bit */ +#define FSMC_SR_ILEN (1 << 4) /* Interrupt Level detection Enable bit */ +#define FSMC_SR_IFEN (1 << 5) /* Interrupt Falling Edge detection Enable bit */ +#define FSMC_SR_FEMPT (1 << 6) /* FIFO empty */ + +#define FSMC_PMEM_MEMSET_SHIFT (0) /* Common memory setup time */ +#define FSMC_PMEM_MEMSET_MASK (255 << FSMC_PMEM_MEMSET_SHIFT) +# define FSMC_PMEM_MEMSET(n) ((n-1) << FSMC_PMEM_MEMSET_SHIFT) /* (n)xHCLK n=1..256 */ +#define FSMC_PMEM_MEMWAIT_SHIFT (8) /* Common memory wait time */ +#define FSMC_PMEM_MEMWAIT_MASK (255 << FSMC_PMEM_MEMWAIT_SHIFT) +# define FSMC_PMEM_MEMWAIT(n) ((n-1) << FSMC_PMEM_MEMWAIT_SHIFT) /* (n)xHCLK n=2..256 */ +#define FSMC_PMEM_MEMHOLD_SHIFT (16) /* Common memoryhold time */ +#define FSMC_PMEM_MEMHOLD_MASK (255 << FSMC_PMEM_MEMHOLD_SHIFT) +# define FSMC_PMEM_MEMHOLD(n) ((n) << FSMC_PMEM_MEMHOLD_SHIFT) /* (n)xHCLK n=1..255 */ +#define FSMC_PMEM_MEMHIZ_SHIFT (24) /* Common memory databus HiZ time */ +#define FSMC_PMEM_MEMHIZ_MASK (255 << FSMC_PMEM_MEMHIZ_SHIFT) +# define FSMC_PMEM_MEMHIZ(n) ((n) << FSMC_PMEM_MEMHIZ_SHIFT) /* (n)xHCLK n=0..255 */ + +#define FSMC_PATT_ATTSET_SHIFT (0) /* Attribute memory setup time */ +#define FSMC_PATT_ATTSET_MASK (255 << FSMC_PATT_ATTSET_SHIFT) +# define FSMC_PATT_ATTSET(n) ((n-1) << FSMC_PATT_ATTSET_SHIFT) /* (n)xHCLK n=1..256 */ +#define FSMC_PATT_ATTWAIT_SHIFT (8) /* Attribute memory wait time */ +#define FSMC_PATT_ATTWAIT_MASK (255 << FSMC_PATT_ATTWAIT_SHIFT) +# define FSMC_PATT_ATTWAIT(n) ((n-1) << FSMC_PATT_ATTWAIT_SHIFT) /* (n)xHCLK n=2..256 */ +#define FSMC_PATT_ATTHOLD_SHIFT (16) /* Attribute memory hold time */ +#define FSMC_PATT_ATTHOLD_MASK (255 << FSMC_PATT_ATTHOLD_SHIFT) +# define FSMC_PATT_ATTHOLD(n) ((n) << FSMC_PATT_ATTHOLD_SHIFT) /* (n)xHCLK n=1..255 */ +#define FSMC_PATT_ATTHIZ_SHIFT (24) /* Attribute memory databus HiZ time */ +#define FSMC_PATT_ATTHIZ_MASK (255 << FSMC_PATT_ATTHIZ_SHIFT) +# define FSMC_PATT_ATTHIZ(n) ((n) << FSMC_PATT_ATTHIZ_SHIFT) /* (n)xHCLK n=0..255 */ + +#define FSMC_PIO4_IOSET_SHIFT (0) /* IOribute memory setup time */ +#define FSMC_PIO4_IOSET_MASK (255 << FSMC_PIO4_IOSET_SHIFT) +# define FSMC_PIO4_IOSET(n) ((n-1) << FSMC_PIO4_IOSET_SHIFT) /* (n)xHCLK n=1..256 */ +#define FSMC_PIO4_IOWAIT_SHIFT (8) /* IOribute memory wait time */ +#define FSMC_PIO4_IOWAIT_MASK (255 << FSMC_PIO4_IOWAIT_SHIFT) +# define FSMC_PIO4_IOWAIT(n) ((n-1) << FSMC_PIO4_IOWAIT_SHIFT) /* (n)xHCLK n=2..256 */ +#define FSMC_PIO4_IOHOLD_SHIFT (16) /* IOribute memory hold time */ +#define FSMC_PIO4_IOHOLD_MASK (255 << FSMC_PIO4_IOHOLD_SHIFT) +# define FSMC_PIO4_IOHOLD(n) ((n) << FSMC_PIO4_IOHOLD_SHIFT) /* (n)xHCLK n=1..255 */ +#define FSMC_PIO4_IOHIZ_SHIFT (24) /* IOribute memory databus HiZ time */ +#define FSMC_PIO4_IOHIZ_MASK (255 << FSMC_PIO4_IOHIZ_SHIFT) +# define FSMC_PIO4_IOHIZ(n) ((n) << FSMC_PIO4_IOHIZ_SHIFT) /* (n)xHCLK n=0..255 */ + +#if defined(CONFIG_STM32_STM32F429) + +# define FSMC_SDRAM_CR_COLBITS_8 0x00000000 +# define FSMC_SDRAM_CR_COLBITS_9 0x00000001 +# define FSMC_SDRAM_CR_COLBITS_10 0x00000002 +# define FSMC_SDRAM_CR_COLBITS_11 0x00000003 + +# define FSMC_SDRAM_CR_ROWBITS_11 0x00000000 +# define FSMC_SDRAM_CR_ROWBITS_12 0x00000004 +# define FSMC_SDRAM_CR_ROWBITS_13 0x00000008 + +# define FSMC_SDRAM_CR_WIDTH_8 0x00000000 +# define FSMC_SDRAM_CR_WIDTH_16 0x00000010 +# define FSMC_SDRAM_CR_WIDTH_32 0x00000020 + +# define FSMC_SDRAM_CR_BANKS_2 0x00000000 +# define FSMC_SDRAM_CR_BANKS_4 0x00000040 + +# define FSMC_SDRAM_CR_CASLAT_1 0x00000080 +# define FSMC_SDRAM_CR_CASLAT_2 0x00000100 +# define FSMC_SDRAM_CR_CASLAT_3 0x00000180 + +# define FSMC_SDRAM_CR_WRITE_PROT 0x00000200 + +# define FSMC_SDRAM_CR_SDCLK_DISABLE 0x00000000 +# define FSMC_SDRAM_CR_SDCLK_2X 0x00000800 +# define FSMC_SDRAM_CR_SDCLK_3X 0x00000C00 + +# define FSMC_SDRAM_CR_BURST_READ 0x00001000 + +# define FSMC_SDRAM_CR_RPIPE_0 0x00000000 +# define FSMC_SDRAM_CR_RPIPE_1 0x00002000 +# define FSMC_SDRAM_CR_RPIPE_2 0x00004000 + +# define FSMC_SDRAM_TR_TMRD_SHIFT 0 +# define FSMC_SDRAM_TR_TXSR_SHIFT 4 +# define FSMC_SDRAM_TR_TRAS_SHIFT 8 +# define FSMC_SDRAM_TR_TRC_SHIFT 12 +# define FSMC_SDRAM_TR_TWR_SHIFT 16 +# define FSMC_SDRAM_TR_TRP_SHIFT 20 +# define FSMC_SDRAM_TR_TRCD_SHIFT 24 + +# define FSMC_SDRAM_MODE_CMD_NORMAL 0 +# define FSMC_SDRAM_MODE_CMD_CLK_ENABLE 1 +# define FSMC_SDRAM_MODE_CMD_PALL 2 +# define FSMC_SDRAM_MODE_CMD_AUTO_REFRESH 3 +# define FSMC_SDRAM_MODE_CMD_LOAD_MODE 4 +# define FSMC_SDRAM_MODE_CMD_SELF_REFRESH 5 +# define FSMC_SDRAM_MODE_CMD_POWER_DOWN 6 + +# define FSMC_SDRAM_CMD_BANK_1 0x00000010 +# define FSMC_SDRAM_CMD_BANK_2 0x00000008 + +# define FSMC_SDRAM_AUTO_REFRESH_SHIFT 5 +# define FSMC_SDRAM_MODEREG_SHIFT 9 + +# define FSMC_SDRAM_MODEREG_BURST_LENGTH_1 (0x0000 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_BURST_LENGTH_2 (0x0001 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_BURST_LENGTH_4 (0x0002 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_BURST_LENGTH_8 (0x0004 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL (0x0000 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_BURST_TYPE_INTERLEAVED (0x0008 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_CAS_LATENCY_2 (0x0020 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_CAS_LATENCY_3 (0x0030 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_OPERATING_MODE_STANDARD (0x0000 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED (0x0000 << FSMC_SDRAM_MODEREG_SHIFT) +# define FSMC_SDRAM_MODEREG_WRITEBURST_MODE_SINGLE (0x0200 << FSMC_SDRAM_MODEREG_SHIFT) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_FSMC_H */ diff --git a/arch/arm/src/stm32/stm32_gpio.c b/arch/arm/src/stm32/stm32_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..6426107b3b490130526aa6cc525e9ece4114a2d8 --- /dev/null +++ b/arch/arm/src/stm32/stm32_gpio.c @@ -0,0 +1,798 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_gpio.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "stm32_gpio.h" + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32_syscfg.h" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[STM32_NGPIO_PORTS] = +{ +#if STM32_NGPIO_PORTS > 0 + STM32_GPIOA_BASE, +#endif +#if STM32_NGPIO_PORTS > 1 + STM32_GPIOB_BASE, +#endif +#if STM32_NGPIO_PORTS > 2 + STM32_GPIOC_BASE, +#endif +#if STM32_NGPIO_PORTS > 3 + STM32_GPIOD_BASE, +#endif +#if STM32_NGPIO_PORTS > 4 + STM32_GPIOE_BASE, +#endif + +#if defined(CONFIG_STM32_STM32L15XX) + +#if STM32_NGPIO_PORTS > 5 + STM32_GPIOH_BASE, +#endif +#if STM32_NGPIO_PORTS > 6 + STM32_GPIOF_BASE, +#endif +#if STM32_NGPIO_PORTS > 7 + STM32_GPIOG_BASE, +#endif + +#else + +#if STM32_NGPIO_PORTS > 5 + STM32_GPIOF_BASE, +#endif +#if STM32_NGPIO_PORTS > 6 + STM32_GPIOG_BASE, +#endif +#if STM32_NGPIO_PORTS > 7 + STM32_GPIOH_BASE, +#endif +#if STM32_NGPIO_PORTS > 8 + STM32_GPIOI_BASE, +#endif +#if STM32_NGPIO_PORTS > 9 + STM32_GPIOJ_BASE, +#endif +#if STM32_NGPIO_PORTS > 10 + STM32_GPIOK_BASE, +#endif + +#endif /* CONFIG_STM32_STM32L15XX */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_gpioremap + * + * Description: + * + * Based on configuration within the .config file, this function will + * remaps positions of alternative functions. + * + ****************************************************************************/ + +static inline void stm32_gpioremap(void) +{ +#if defined(CONFIG_STM32_STM32F10XX) + + /* Remap according to the configuration within .config file */ + + uint32_t val = 0; + +#ifdef CONFIG_STM32_SPI1_REMAP + val |= AFIO_MAPR_SPI1_REMAP; +#endif +#ifdef CONFIG_STM32_SPI3_REMAP + val |= AFIO_MAPR_SPI3_REMAP; +#endif + +#ifdef CONFIG_STM32_I2C1_REMAP + val |= AFIO_MAPR_I2C1_REMAP; +#endif + +#ifdef CONFIG_STM32_USART1_REMAP + val |= AFIO_MAPR_USART1_REMAP; +#endif +#ifdef CONFIG_STM32_USART2_REMAP + val |= AFIO_MAPR_USART2_REMAP; +#endif +#ifdef CONFIG_STM32_USART3_FULL_REMAP + val |= AFIO_MAPR_USART3_FULLREMAP; +#endif +#ifdef CONFIG_STM32_USART3_PARTIAL_REMAP + val |= AFIO_MAPR_USART3_PARTREMAP; +#endif + +#ifdef CONFIG_STM32_TIM1_FULL_REMAP + val |= AFIO_MAPR_TIM1_FULLREMAP; +#endif +#ifdef CONFIG_STM32_TIM1_PARTIAL_REMAP + val |= AFIO_MAPR_TIM1_PARTREMAP; +#endif +#ifdef CONFIG_STM32_TIM2_FULL_REMAP + val |= AFIO_MAPR_TIM2_FULLREMAP; +#endif +#ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_1 + val |= AFIO_MAPR_TIM2_PARTREMAP1; +#endif +#ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_2 + val |= AFIO_MAPR_TIM2_PARTREMAP2; +#endif +#ifdef CONFIG_STM32_TIM3_FULL_REMAP + val |= AFIO_MAPR_TIM3_FULLREMAP; +#endif +#ifdef CONFIG_STM32_TIM3_PARTIAL_REMAP + val |= AFIO_MAPR_TIM3_PARTREMAP; +#endif +#ifdef CONFIG_STM32_TIM4_REMAP + val |= AFIO_MAPR_TIM4_REMAP; +#endif + +#ifdef CONFIG_STM32_CAN1_REMAP1 + val |= AFIO_MAPR_PB89; +#endif +#ifdef CONFIG_STM32_CAN1_REMAP2 + val |= AFIO_MAPR_PD01; +#endif +#ifdef CONFIG_STM32_CAN2_REMAP /* Connectivity line only */ + val |= AFIO_MAPR_CAN2_REMAP; +#endif + +#ifdef CONFIG_STM32_ETH_REMAP /* Connectivity line only */ + val |= AFIO_MAPR_ETH_REMAP; +#endif + +#ifdef CONFIG_STM32_JTAG_FULL_ENABLE + /* The reset default */ +#elif defined(CONFIG_STM32_JTAG_NOJNTRST_ENABLE) + val |= AFIO_MAPR_SWJ; /* enabled but without JNTRST */ +#elif defined(CONFIG_STM32_JTAG_SW_ENABLE) + val |= AFIO_MAPR_SWDP; /* set JTAG-DP disabled and SW-DP enabled */ +#else + val |= AFIO_MAPR_DISAB; /* set JTAG-DP and SW-DP Disabled */ +#endif + + putreg32(val, STM32_AFIO_MAPR); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exlusion is necessary. + * + ****************************************************************************/ + +void stm32_gpioinit(void) +{ + /* Remap according to the configuration within .config file */ + + stm32_gpioremap(); +} + +/**************************************************************************** + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * A negated errono valu on invalid port, or when pin is locked as ALT + * function. + * + * To-Do: Auto Power Enable + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_configgpio (for the STM32F10xxx family) + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F10XX) +int stm32_configgpio(uint32_t cfgset) +{ + uint32_t base; + uint32_t cr; + uint32_t regval; + uint32_t regaddr; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int modecnf; + irqstate_t flags; + bool input; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32_NGPIO_PORTS) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + if (pin < 8) + { + cr = base + STM32_GPIO_CRL_OFFSET; + pos = pin; + } + else + { + cr = base + STM32_GPIO_CRH_OFFSET; + pos = pin - 8; + } + + /* Input or output? */ + + input = ((cfgset & GPIO_INPUT) != 0); + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + /* Decode the mode and configuration */ + + regval = getreg32(cr); + + if (input) + { + /* Input.. force mode = INPUT */ + + modecnf = 0; + } + else + { + /* Output or alternate function */ + + modecnf = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT; + } + + modecnf |= ((cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT) << 2; + + /* Set the port configuration register */ + + regval &= ~(GPIO_CR_MODECNF_MASK(pos)); + regval |= (modecnf << GPIO_CR_MODECNF_SHIFT(pos)); + putreg32(regval, cr); + + /* Set or reset the corresponding BRR/BSRR bit */ + + if (!input) + { + /* It is an output or an alternate function. We have to look at the CNF + * bits to know which. + */ + + unsigned int cnf = (cfgset & GPIO_CNF_MASK); + if (cnf != GPIO_CNF_OUTPP && cnf != GPIO_CNF_OUTOD) + { + /* Its an alternate function pin... we can return early */ + + leave_critical_section(flags); + return OK; + } + } + else + { + /* It is an input pin... Should it configured as an EXTI interrupt? */ + + if ((cfgset & GPIO_EXTI) != 0) + { + int shift; + + /* Yes.. Set the bits in the EXTI CR register */ + + regaddr = STM32_AFIO_EXTICR(pin); + regval = getreg32(regaddr); + shift = AFIO_EXTICR_EXTI_SHIFT(pin); + regval &= ~(AFIO_EXTICR_PORT_MASK << shift); + regval |= (((uint32_t)port) << shift); + + putreg32(regval, regaddr); + } + + if ((cfgset & GPIO_CNF_MASK) != GPIO_CNF_INPULLUD) + { + /* Neither... we can return early */ + + leave_critical_section(flags); + return OK; + } + } + + /* If it is an output... set the pin to the correct initial state. + * If it is pull-down or pull up, then we need to set the ODR + * appropriately for that function. + */ + + if ((cfgset & GPIO_OUTPUT_SET) != 0) + { + /* Use the BSRR register to set the output */ + + regaddr = base + STM32_GPIO_BSRR_OFFSET; + } + else + { + /* Use the BRR register to clear */ + + regaddr = base + STM32_GPIO_BRR_OFFSET; + } + + regval = getreg32(regaddr); + regval |= (1 << pin); + putreg32(regval, regaddr); + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_configgpio (for the STM32L15xxx, STM32F20xxx and STM32F40xxx family) + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) +int stm32_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + unsigned int regoffset; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int pinmode; + irqstate_t flags; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32_NGPIO_PORTS) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set up the mode register (and remember whether the pin mode) */ + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input mode */ + pinmode = GPIO_MODER_INPUT; + break; + + case GPIO_OUTPUT: /* General purpose output mode */ + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + STM32_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_MODER_OFFSET); + + /* Set up the pull-up/pull-down configuration (all but analog pins) */ + + setting = GPIO_PUPDR_NONE; + if (pinmode != GPIO_MODER_ANALOG) + { + switch (cfgset & GPIO_PUPD_MASK) + { + default: + case GPIO_FLOAT: /* No pull-up, pull-down */ + break; + + case GPIO_PULLUP: /* Pull-up */ + setting = GPIO_PUPDR_PULLUP; + break; + + case GPIO_PULLDOWN: /* Pull-down */ + setting = GPIO_PUPDR_PULLDOWN; + break; + } + } + + regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET); + + /* Set the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pin < 8) + { + regoffset = STM32_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Set speed (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_SPEED_MASK) + { +#if defined(CONFIG_STM32_STM32L15XX) + default: + case GPIO_SPEED_400KHz: /* 400 kHz Very low speed ouput */ + setting = GPIO_OSPEED_400KHz; + break; + + case GPIO_SPEED_2MHz: /* 2 MHz Low speed ouput */ + setting = GPIO_OSPEED_2MHz; + break; + + case GPIO_SPEED_10MHz: /* 10 MHz Medium speed ouput */ + setting = GPIO_OSPEED_10MHz; + break; + + case GPIO_SPEED_40MHz: /* 40 MHz High speed ouput */ + setting = GPIO_OSPEED_40MHz; + break; +#else + default: + case GPIO_SPEED_2MHz: /* 2 MHz Low speed output */ + setting = GPIO_OSPEED_2MHz; + break; + + case GPIO_SPEED_25MHz: /* 25 MHz Medium speed output */ + setting = GPIO_OSPEED_25MHz; + break; + + case GPIO_SPEED_50MHz: /* 50 MHz Fast speed output */ + setting = GPIO_OSPEED_50MHz; + break; + +#if !defined(CONFIG_STM32_STM32F30XX) && !defined(CONFIG_STM32_STM32F37XX) + case GPIO_SPEED_100MHz: /* 100 MHz High speed output */ + setting = GPIO_OSPEED_100MHz; + break; +#endif +#endif + } + } + else + { + setting = 0; + } + + regval = getreg32(base + STM32_GPIO_OSPEED_OFFSET); + regval &= ~GPIO_OSPEED_MASK(pin); + regval |= (setting << GPIO_OSPEED_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_OSPEED_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + STM32_GPIO_OTYPER_OFFSET); + setting = GPIO_OTYPER_OD(pin); + + if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) && + (cfgset & GPIO_OPENDRAIN) != 0) + { + regval |= setting; + } + else + { + regval &= ~setting; + } + + putreg32(regval, base + STM32_GPIO_OTYPER_OFFSET); + + /* If it is an output... set the pin to the correct initial state. */ + + if (pinmode == GPIO_MODER_OUTPUT) + { + bool value = ((cfgset & GPIO_OUTPUT_SET) != 0); + stm32_gpiowrite(cfgset, value); + } + + /* Otherwise, it is an input pin. Should it configured as an EXTI interrupt? */ + + else if ((cfgset & GPIO_EXTI) != 0) + { + /* "In STM32 F1 the selection of the EXTI line source is performed through + * the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this + * selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers. + * + * "Only the mapping of the EXTICRx registers has been changed, without any + * changes to the meaning of the EXTIx bits. However, the range of EXTI + * bits values has been extended to 0b1000 to support the two ports added + * in F2, port H and I (in F1 series the maximum value is 0b0110)." + */ + + uint32_t regaddr; + int shift; + + /* Set the bits in the SYSCFG EXTICR register */ + + regaddr = STM32_SYSCFG_EXTICR(pin); + regval = getreg32(regaddr); + shift = SYSCFG_EXTICR_EXTI_SHIFT(pin); + regval &= ~(SYSCFG_EXTICR_PORT_MASK << shift); + regval |= (((uint32_t)port) << shift); + + putreg32(regval, regaddr); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * A negated errno value on invalid port + * + * To-Do: Auto Power Disable + ****************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset) +{ + /* Reuse port and pin number and set it to default HiZ INPUT */ + + cfgset &= GPIO_PORT_MASK | GPIO_PIN_MASK; +#if defined(CONFIG_STM32_STM32F10XX) + cfgset |= GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT; +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) + cfgset |= GPIO_INPUT | GPIO_FLOAT; +#else +# error "Unsupported STM32 chip" +#endif + + /* To-Do: Mark its unuse for automatic power saving options */ + + return stm32_configgpio(cfgset); +} + +/**************************************************************************** + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value) +{ + uint32_t base; +#if defined(CONFIG_STM32_STM32F10XX) + uint32_t offset; +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) + uint32_t bit; +#endif + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32_NGPIO_PORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + +#if defined(CONFIG_STM32_STM32F10XX) + + if (value) + { + offset = STM32_GPIO_BSRR_OFFSET; + } + else + { + offset = STM32_GPIO_BRR_OFFSET; + } + + putreg32((1 << pin), base + offset); + +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) + + if (value) + { + bit = GPIO_BSRR_SET(pin); + } + else + { + bit = GPIO_BSRR_RESET(pin); + } + + putreg32(bit, base + STM32_GPIO_BSRR_OFFSET); + +#else +# error "Unsupported STM32 chip" +#endif + } +} + +/**************************************************************************** + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32_NGPIO_PORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + STM32_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + return 0; +} diff --git a/arch/arm/src/stm32/stm32_gpio.h b/arch/arm/src/stm32/stm32_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..c1790eaaaa3f8693950edbbb1a1cc68a89bb273a --- /dev/null +++ b/arch/arm/src/stm32/stm32_gpio.h @@ -0,0 +1,538 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_gpio.h + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32_STM32_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_gpio.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_gpio.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_gpio.h" +#elif defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f30xxx_gpio.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_gpio.h" +#else +# error "Unrecognized STM32 chip" +#endif + +/************************************************************************************ + * Pre-Processor Declarations + ************************************************************************************/ + +/* Bit-encoded input to stm32_configgpio() */ + +#if defined(CONFIG_STM32_STM32F10XX) + +/* 16-bit Encoding: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * OFFS SX.. VPPP BBBB + */ + +/* Output mode: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * O... .... .... .... + */ + +#define GPIO_INPUT (1 << 15) /* Bit 15: 1=Input mode */ +#define GPIO_OUTPUT (0) /* 0=Output or alternate function */ +#define GPIO_ALT (0) + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * If the pin is an input, this bit is overloaded to provide the qualifier to\ + * distinquish input pull-up and -down: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... V... .... + */ + +#define GPIO_OUTPUT_SET (1 << 7) /* Bit 7: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* These bits set the primary function of the pin: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .FF. .... .... .... + */ + +#define GPIO_CNF_SHIFT 13 /* Bits 13-14: GPIO function */ +#define GPIO_CNF_MASK (3 << GPIO_CNF_SHIFT) + +# define GPIO_CNF_ANALOGIN (0 << GPIO_CNF_SHIFT) /* Analog input */ +# define GPIO_CNF_INFLOAT (1 << GPIO_CNF_SHIFT) /* Input floating */ +# define GPIO_CNF_INPULLUD (2 << GPIO_CNF_SHIFT) /* Input pull-up/down general bit, since up is composed of two parts */ +# define GPIO_CNF_INPULLDWN (2 << GPIO_CNF_SHIFT) /* Input pull-down */ +# define GPIO_CNF_INPULLUP ((2 << GPIO_CNF_SHIFT) | GPIO_OUTPUT_SET) /* Input pull-up */ + +# define GPIO_CNF_OUTPP (0 << GPIO_CNF_SHIFT) /* Output push-pull */ +# define GPIO_CNF_OUTOD (1 << GPIO_CNF_SHIFT) /* Output open-drain */ +# define GPIO_CNF_AFPP (2 << GPIO_CNF_SHIFT) /* Alternate function push-pull */ +# define GPIO_CNF_AFOD (3 << GPIO_CNF_SHIFT) /* Alternate function open-drain */ + +/* Maximum frequency selection: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * ...S S... .... .... + */ + +#define GPIO_MODE_SHIFT 11 /* Bits 11-12: GPIO frequency selection */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_MODE_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode (reset state) */ +# define GPIO_MODE_10MHz (1 << GPIO_MODE_SHIFT) /* Output mode, max speed 10 MHz */ +# define GPIO_MODE_2MHz (2 << GPIO_MODE_SHIFT) /* Output mode, max speed 2 MHz */ +# define GPIO_MODE_50MHz (3 << GPIO_MODE_SHIFT) /* Output mode, max speed 50 MHz */ + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .X.. .... .... + */ + +#define GPIO_EXTI (1 << 10) /* Bit 10: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... .PPP .... + */ + +#define GPIO_PORT_SHIFT 4 /* Bit 4-6: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ + +/* This identifies the bit in the port: + * + * 1111 1100 0000 0000 + * 5432 1098 7654 3210 + * ---- ---- ---- ---- + * .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually configured + * by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU .... ...X PPPP BBBB + * Outputs: MMUU .... FFOV PPPP BBBB + * Alternate Functions: MMUU AAAA FFO. PPPP BBBB + * Analog: MM.. .... .... PPPP BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ +# define GPIO_ANALOG (3 << GPIO_MODE_SHIFT) /* Analog mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (15 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) +# define GPIO_AF8 (8 << GPIO_AF_SHIFT) +# define GPIO_AF9 (9 << GPIO_AF_SHIFT) +# define GPIO_AF10 (10 << GPIO_AF_SHIFT) +# define GPIO_AF11 (11 << GPIO_AF_SHIFT) +# define GPIO_AF12 (12 << GPIO_AF_SHIFT) +# define GPIO_AF13 (13 << GPIO_AF_SHIFT) +# define GPIO_AF14 (14 << GPIO_AF_SHIFT) +# define GPIO_AF15 (15 << GPIO_AF_SHIFT) + +/* Output/Alt function frequency selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... FF.. .... .... + */ + +#define GPIO_SPEED_SHIFT (10) /* Bits 10-11: GPIO frequency selection */ +#define GPIO_SPEED_MASK (3 << GPIO_SPEED_SHIFT) +#if defined(CONFIG_STM32_STM32L15XX) +# define GPIO_SPEED_400KHz (0 << GPIO_SPEED_SHIFT) /* 400 kHz Very low speed output */ +# define GPIO_SPEED_2MHz (1 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_10MHz (2 << GPIO_SPEED_SHIFT) /* 10 MHz Medium speed output */ +# define GPIO_SPEED_40MHz (3 << GPIO_SPEED_SHIFT) /* 40 MHz High speed output */ +#else +# define GPIO_SPEED_2MHz (0 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_25MHz (1 << GPIO_SPEED_SHIFT) /* 25 MHz Medium speed output */ +# define GPIO_SPEED_50MHz (2 << GPIO_SPEED_SHIFT) /* 50 MHz Fast speed output */ +#ifndef CONFIG_STM32_STM32F30XX +# define GPIO_SPEED_100MHz (3 << GPIO_SPEED_SHIFT) /* 100 MHz High speed output */ +#endif +#endif + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ +#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */ + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * If the pin is an input, this bit is overloaded to provide the qualifier to + * distinquish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...X .... .... + */ + +#define GPIO_EXTI (1 << 8) /* Bit 8: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPPP .... + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +#if defined (CONFIG_STM32_STM32L15XX) +# define GPIO_PORTH (5 << GPIO_PORT_SHIFT) /* GPIOH */ +# define GPIO_PORTF (6 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (7 << GPIO_PORT_SHIFT) /* GPIOG */ +#else +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ +# define GPIO_PORTI (8 << GPIO_PORT_SHIFT) /* GPIOI */ +# define GPIO_PORTJ (9 << GPIO_PORT_SHIFT) /* GPIOJ */ +# define GPIO_PORTK (10 << GPIO_PORT_SHIFT) /* GPIOK */ +#endif + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +#else +# error "Unrecognized STM32 chip" +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Base addresses for each GPIO block */ + +EXTERN const uint32_t g_gpiobase[STM32_NGPIO_PORTS]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ************************************************************************************/ + +int stm32_configgpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * ERROR on invalid port + * + ************************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value); + +/************************************************************************************ + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool stm32_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG +int stm32_dumpgpio(uint32_t pinset, const char *msg); +#else +# define stm32_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + ************************************************************************************/ + +void stm32_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32/stm32_i2c.c b/arch/arm/src/stm32/stm32_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..6d06098b018b18db0785a0004d8677ac3ce499ee --- /dev/null +++ b/arch/arm/src/stm32/stm32_i2c.c @@ -0,0 +1,2054 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_i2c.c + * STM32 I2C Hardware Layer - Device Driver + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With extensions, modifications by: + * + * Copyright (C) 2011-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Supports: + * - Master operation, 100 kHz (standard) and 400 kHz (full speed) + * - Multiple instances (shared bus) + * - Interrupt based operation + * + * Structure naming: + * - Device: structure as defined by the nuttx/i2c/i2c.h + * - Instance: represents each individual access to the I2C driver, obtained by + * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; + * Instance points to OPS, to common I2C Hardware private data and contains + * its own private data, as frequency, address, mode of operation (in the + * future) + * - Private: Private data of an I2C Hardware + * + * TODO + * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW + * using the I2C_CR1_SWRST) + * - SMBus support (hardware layer timings are already supported) and add SMBA + * gpio pin + * - Slave support with multiple addresses (on multiple instances): + * - 2 x 7-bit address or + * - 1 x 10 bit addresses + 1 x 7 bit address (?) + * - plus the broadcast address (general call) + * - Multi-master support + * - DMA (to get rid of too many CPU wake-ups and interventions) + * - Be ready for IPMI + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" +#include "stm32_i2c.h" +#include "stm32_waste.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || \ + defined(CONFIG_STM32_I2C3) + +/* This implementation is for the STM32 F1, F2, and F4 only */ +/* Experimentally enabled for STM32L15XX */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_STM32_I2CTIMEOSEC) && !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOSEC 0 +# define CONFIG_STM32_I2CTIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOSEC) +# define CONFIG_STM32_I2CTIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_STM32_I2CTIMEOTICKS +# define CONFIG_STM32_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS)) +#endif + +#ifndef CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32_I2CTIMEOTICKS) +#endif + +/* On the STM32F103ZE, there is an internal conflict between I2C1 and FSMC. In that + * case, it is necessary to disable FSMC before each I2C1 access and re-enable FSMC + * when the I2C access completes. + */ + +#undef I2C1_FSMC_CONFLICT +#if defined(CONFIG_STM32_STM32F10XX) && defined(CONFIG_STM32_FSMC) && defined(CONFIG_STM32_I2C1) +# define I2C1_FSMC_CONFLICT +#endif + +/* Macros to convert a I2C pin to a GPIO output */ + +#if defined(CONFIG_STM32_STM32L15XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_OPENDRAIN | \ + GPIO_SPEED_40MHz) +#elif defined(CONFIG_STM32_STM32F10XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD | \ + GPIO_MODE_50MHz) +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_FLOAT | GPIO_OPENDRAIN |\ + GPIO_SPEED_50MHz | GPIO_OUTPUT_SET) +#endif + +#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ****************************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level + * debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define stm32_i2c_tracereset(p) +# define stm32_i2c_tracenew(p,s) +# define stm32_i2c_traceevent(p,e,a) +# define stm32_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Interrupt state */ + +enum stm32_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for completion of interrupt activity */ + INTSTATE_DONE, /* Interrupt activity complete */ +}; + +/* Trace events */ + +enum stm32_trace_e +{ + I2CEVENT_NONE = 0, /* No events have occurred with this status */ + I2CEVENT_SENDADDR, /* Start/Master bit set and address sent, param = msgc */ + I2CEVENT_SENDBYTE, /* Send byte, param = dcnt */ + I2CEVENT_ITBUFEN, /* Enable buffer interrupts, param = 0 */ + I2CEVENT_RCVBYTE, /* Read more dta, param = dcnt */ + I2CEVENT_REITBUFEN, /* Re-enable buffer interrupts, param = 0 */ + I2CEVENT_DISITBUFEN, /* Disable buffer interrupts, param = 0 */ + I2CEVENT_BTFNOSTART, /* BTF on last byte with no restart, param = msgc */ + I2CEVENT_BTFRESTART, /* Last byte sent, re-starting, param = msgc */ + I2CEVENT_BTFSTOP, /* Last byte sten, send stop, param = 0 */ + I2CEVENT_ERROR /* Error occurred, param = 0 */ +}; + +/* Trace data */ + +struct stm32_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + enum stm32_intstate_e event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + systime_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct stm32_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t reset_bit; /* Reset bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr)(int, void *); /* Interrupt handler */ + uint32_t ev_irq; /* Event IRQ */ + uint32_t er_irq; /* Error IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct stm32_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct stm32_i2c_config_s *config; /* Port configuration */ + int refs; /* Referernce count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + systime_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct stm32_trace_s trace[CONFIG_I2C_NTRACE]; +#endif + + uint32_t status; /* End of transfer SR2|SR1 status */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset); +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value); +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv); + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_STM32_I2C_DYNTIMEO */ + +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv); + +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv); +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status); +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + enum stm32_trace_e event, uint32_t parm); +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, + uint32_t frequency); +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv); +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv); + +#ifdef I2C1_FSMC_CONFLICT +static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_enablefsmc(uint32_t ahbenr); +#endif /* I2C1_FSMC_CONFLICT */ + +static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv); + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context); +#endif +#endif /* !CONFIG_I2C_POLLED */ + +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Trace events strings */ + +#ifdef CONFIG_I2C_TRACE +static const char *g_trace_names[] = +{ + "NONE ", + "SENDADDR ", + "SENDBYTE ", + "ITBUFEN ", + "RCVBYTE ", + "REITBUFEN ", + "DISITBUFEN", + "BTFNOSTART", + "BTFRESTART", + "BTFSTOP ", + "ERROR " +}; +#endif + +/* I2C interface */ + +static const struct i2c_ops_s stm32_i2c_ops = +{ + .transfer = stm32_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = stm32_i2c_reset +#endif +}; + +/* I2C device structures */ + +#ifdef CONFIG_STM32_I2C1 +static const struct stm32_i2c_config_s stm32_i2c1_config = +{ + .base = STM32_I2C1_BASE, + .clk_bit = RCC_APB1ENR_I2C1EN, + .reset_bit = RCC_APB1RSTR_I2C1RST, + .scl_pin = GPIO_I2C1_SCL, + .sda_pin = GPIO_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c1_isr, + .ev_irq = STM32_IRQ_I2C1EV, + .er_irq = STM32_IRQ_I2C1ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c1_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c1_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C2 +static const struct stm32_i2c_config_s stm32_i2c2_config = +{ + .base = STM32_I2C2_BASE, + .clk_bit = RCC_APB1ENR_I2C2EN, + .reset_bit = RCC_APB1RSTR_I2C2RST, + .scl_pin = GPIO_I2C2_SCL, + .sda_pin = GPIO_I2C2_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c2_isr, + .ev_irq = STM32_IRQ_I2C2EV, + .er_irq = STM32_IRQ_I2C2ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c2_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c2_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C3 +static const struct stm32_i2c_config_s stm32_i2c3_config = +{ + .base = STM32_I2C3_BASE, + .clk_bit = RCC_APB1ENR_I2C3EN, + .reset_bit = RCC_APB1RSTR_I2C3RST, + .scl_pin = GPIO_I2C3_SCL, + .sda_pin = GPIO_I2C3_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c3_isr, + .ev_irq = STM32_IRQ_I2C3EV, + .er_irq = STM32_IRQ_I2C3ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c3_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c3_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value) +{ + putreg16(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_modifyreg + * + * Description: + * Modify a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv) +{ + while (sem_wait(&priv->sem_excl) != 0) + { + ASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: stm32_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be processed. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + uint32_t regval; + int ret; + + flags = enter_critical_section(); + + /* Enable I2C interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN); + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_STM32_I2CTIMEOSEC > 0 + abstime.tv_sec += CONFIG_STM32_I2CTIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * stm32_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_STM32_I2CTIMEOMS > 0 + abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->sem_isr, &abstime); + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by sem_timedwait. + * NOTE that we try again if we are awakened by a signal (EINTR). + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval &= ~I2C_CR2_ALLINTS; + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); + + leave_critical_section(flags); + return ret; +} +#else +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(stm32_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + start = clock_systimer(); + + do + { + /* Poll by simply calling the timer interrupt handler until it + * reports that it is done. + */ + + stm32_i2c_isr(priv); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cvdbg("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, priv->status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_sem_waitstop + * + * Description: + * Wait for a STOP to complete + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t start; + systime_t elapsed; + systime_t timeout; + uint32_t cr1; + uint32_t sr1; + + /* Select a timeout */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Wait as stop might still be in progress; but stop might also + * be set because of a timeout error: "The [STOP] bit is set and + * cleared by software, cleared by hardware when a Stop condition is + * detected, set by hardware when a timeout error is detected." + */ + + start = clock_systimer(); + do + { + /* Check for STOP condition */ + + cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET); + if ((cr1 & I2C_CR1_STOP) == 0) + { + return; + } + + /* Check for timeout error */ + + sr1 = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET); + if ((sr1 & I2C_SR1_TIMEOUT) != 0) + { + return; + } + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the stop is complete or a timeout occurs. */ + + while (elapsed < timeout); + + /* If we get here then a timeout occurred with the STOP condition + * still pending. + */ + + i2cvdbg("Timeout with CR1: %04x SR1: %04x\n", cr1, sr1); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_post(struct stm32_i2c_priv_s *priv) +{ + sem_post(&priv->sem_excl); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) +{ + sem_init(&priv->sem_excl, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->sem_isr, 0, 0); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv) +{ + sem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->sem_isr); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_trace* + * + * Description: + * I2C trace instrumentation + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_traceclear(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systimer(); + stm32_i2c_traceclear(priv); +} + +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + stm32_i2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systimer(); + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + enum stm32_trace_e event, uint32_t parm) +{ + struct stm32_trace_s *trace; + + if (event != I2CEVENT_NONE) + { + trace = &priv->trace[priv->tndx]; + + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + stm32_i2c_traceclear(priv); + } +} + +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->start_time)); + + for (i = 0; i <= priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %3d EVENT: %s(%2d) PARM: %08x TIME: %d\n", + i+1, trace->status, trace->count, g_trace_names[trace->event], + trace->event, trace->parm, trace->time - priv->start_time); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/************************************************************************************ + * Name: stm32_i2c_setclock + * + * Description: + * Set the I2C clock + * + ************************************************************************************/ + +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequency) +{ + uint16_t cr1; + uint16_t ccr; + uint16_t trise; + uint16_t freqmhz; + uint16_t speed; + + /* Has the I2C bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Disable the selected I2C peripheral to configure TRISE */ + + cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET); + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1 & ~I2C_CR1_PE); + + /* Update timing and control registers */ + + freqmhz = (uint16_t)(STM32_PCLK1_FREQUENCY / 1000000); + ccr = 0; + + /* Configure speed in standard mode */ + + if (frequency <= 100000) + { + /* Standard mode speed calculation */ + + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency << 1)); + + /* The CCR fault must be >= 4 */ + + if (speed < 4) + { + /* Set the minimum allowed value */ + + speed = 4; + } + + ccr |= speed; + + /* Set Maximum Rise Time for standard mode */ + + trise = freqmhz + 1; + } + + /* Configure speed in fast mode */ + + else /* (frequency <= 400000) */ + { + /* Fast mode speed calculation with Tlow/Thigh = 16/9 */ + +#ifdef CONFIG_STM32_I2C_DUTY16_9 + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency * 25)); + + /* Set DUTY and fast speed bits */ + + ccr |= (I2C_CCR_DUTY | I2C_CCR_FS); +#else + /* Fast mode speed calculation with Tlow/Thigh = 2 */ + + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency * 3)); + + /* Set fast speed bit */ + + ccr |= I2C_CCR_FS; +#endif + + /* Verify that the CCR speed value is nonzero */ + + if (speed < 1) + { + /* Set the minimum allowed value */ + + speed = 1; + } + + ccr |= speed; + + /* Set Maximum Rise Time for fast mode */ + + trise = (uint16_t)(((freqmhz * 300) / 1000) + 1); + } + + /* Write the new values of the CCR and TRISE registers */ + + stm32_i2c_putreg(priv, STM32_I2C_CCR_OFFSET, ccr); + stm32_i2c_putreg(priv, STM32_I2C_TRISE_OFFSET, trise); + + /* Bit 14 of OAR1 must be configured and kept at 1 */ + + stm32_i2c_putreg(priv, STM32_I2C_OAR1_OFFSET, I2C_OAR1_ONE); + + /* Re-enable the peripheral (or not) */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1); + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/************************************************************************************ + * Name: stm32_i2c_sendstart + * + * Description: + * Send the START conditions/force Master mode + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* Disable ACK on receive by default and generate START */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_START); +} + +/************************************************************************************ + * Name: stm32_i2c_clrstart + * + * Description: + * Clear the STOP, START or PEC condition on certain error recovery steps. + * + ************************************************************************************/ + +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + * + * "The [STOP] bit is set and cleared by software, cleared by hardware + * when a Stop condition is detected, set by hardware when a timeout + * error is detected. + * + * "This [START] bit is set and cleared by software and cleared by hardware + * when start is sent or PE=0." The bit must be cleared by software if the + * START is never sent. + * + * "This [PEC] bit is set and cleared by software, and cleared by hardware + * when PEC is transferred or by a START or Stop condition or when PE=0." + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, + I2C_CR1_START | I2C_CR1_STOP | I2C_CR1_PEC, 0); +} + +/************************************************************************************ + * Name: stm32_i2c_sendstop + * + * Description: + * Send the STOP conditions + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_STOP); +} + +/************************************************************************************ + * Name: stm32_i2c_getstatus + * + * Description: + * Get 32-bit status (SR1 and SR2 combined) + * + ************************************************************************************/ + +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv) +{ + uint32_t status = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET); + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + return status; +} + +/************************************************************************************ + * Name: stm32_i2c_disablefsmc + * + * Description: + * FSMC must be disable while accessing I2C1 because it uses a common resource + * (LBAR) + * + * NOTE: This is an issue with the STM32F103ZE, but may not be an issue with other + * STM32s. You may need to experiment + * + ************************************************************************************/ + +#ifdef I2C1_FSMC_CONFLICT +static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv) +{ + uint32_t ret = 0; + uint32_t regval; + + /* Is this I2C1 */ + +#if defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) + if (priv->config->base == STM32_I2C1_BASE) +#endif + { + /* Disable FSMC unconditionally */ + + ret = getreg32(STM32_RCC_AHBENR); + regval = ret & ~RCC_AHBENR_FSMCEN; + putreg32(regval, STM32_RCC_AHBENR); + } + + return ret; +} + +/************************************************************************************ + * Name: stm32_i2c_enablefsmc + * + * Description: + * Re-enable the FSMC + * + ************************************************************************************/ + +static inline void stm32_i2c_enablefsmc(uint32_t ahbenr) +{ + uint32_t regval; + + /* Enable AHB clocking to the FSMC only if it was previously enabled. */ + + if ((ahbenr & RCC_AHBENR_FSMCEN) != 0) + { + regval = getreg32(STM32_RCC_AHBENR); + regval |= RCC_AHBENR_FSMCEN; + putreg32(regval, STM32_RCC_AHBENR); + } +} +#else +# define stm32_i2c_disablefsmc(priv) (0) +# define stm32_i2c_enablefsmc(ahbenr) +#endif /* I2C1_FSMC_CONFLICT */ + +/************************************************************************************ + * Name: stm32_i2c_isr + * + * Description: + * Common Interrupt Service Routine + * + ************************************************************************************/ + +static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) +{ + uint32_t status = stm32_i2c_getstatus(priv); + + /* Check for new trace setup */ + + stm32_i2c_tracenew(priv, status); + + /* Was start bit sent */ + + if ((status & I2C_SR1_SB) != 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc); + + /* We check for msgc > 0 here as an unexpected interrupt with + * I2C_SR1_SB set due to noise on the I2C cable can otherwise cause + * msgc to wrap causing memory overwrite + */ + + if (priv->msgc > 0 && priv->msgv != NULL) + { + /* Get run-time data */ + + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + + /* Send address byte and define addressing mode */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, + (priv->flags & I2C_M_TEN) ? + 0 : ((priv->msgv->addr << 1) | (priv->flags & I2C_M_READ))); + + /* Set ACK for receive mode */ + + if (priv->dcnt > 1 && (priv->flags & I2C_M_READ) != 0) + { + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_ACK); + } + + /* Increment to next pointer and decrement message count */ + + priv->msgv++; + priv->msgc--; + } + else + { + /* Clear ISR by writing to DR register */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, 0); + } + } + + /* In 10-bit addressing mode, was first byte sent */ + + else if ((status & I2C_SR1_ADD10) != 0) + { + /* TODO: Finish 10-bit mode addressing. + * + * For now just clear ISR by writing to DR register. As we don't do + * 10 bit addressing this must be a spurious ISR + */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, 0); + } + + /* Was address sent, continue with either sending or reading data */ + + else if ((priv->flags & I2C_M_READ) == 0 && (status & (I2C_SR1_ADDR | I2C_SR1_TXE)) != 0) + { + if (priv->dcnt > 0) + { + /* Send a byte */ + + stm32_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt); + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++); + priv->dcnt--; + } + } + + else if ((priv->flags & I2C_M_READ) != 0 && (status & I2C_SR1_ADDR) != 0) + { + /* Enable RxNE and TxE buffers in order to receive one or multiple bytes */ + +#ifndef CONFIG_I2C_POLLED + stm32_i2c_traceevent(priv, I2CEVENT_ITBUFEN, 0); + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN); +#endif + } + + /* More bytes to read */ + + else if ((status & I2C_SR1_RXNE) != 0) + { + /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */ + + if (priv->dcnt > 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); + + /* No interrupts or context switches may occur in the following + * sequence. Otherwise, additional bytes may be sent by the + * device. + */ + +#ifdef CONFIG_I2C_POLLED + irqstate_t flags = enter_critical_section(); +#endif + /* Receive a byte */ + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + + /* Disable acknowledge when last byte is to be received */ + + priv->dcnt--; + if (priv->dcnt == 1) + { + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0); + } + +#ifdef CONFIG_I2C_POLLED + leave_critical_section(flags); +#endif + } + else + { + /* Throw away the unexpected byte */ + + stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + } + } + else if (status & I2C_SR1_TXE) + { + /* This should never happen, but it does happen occasionally with lots + * of noise on the bus. It means the peripheral is expecting more data + * bytes, but we don't have any to give. + */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, 0); + } + else if (status & I2C_SR1_BTF) + { + /* We should have handled all cases where this could happen above, but + * just to ensure it gets ACKed, lets clear it here + */ + + stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + } + else if (status & I2C_SR1_STOPF) + { + /* We should never get this, as we are a master not a slave. Write CR1 + * with its current value to clear the error + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, 0); + } + + /* Do we have more bytes to send, enable/disable buffer interrupts + * (these ISRs could be replaced by DMAs) + */ + +#ifndef CONFIG_I2C_POLLED + if (priv->dcnt > 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_REITBUFEN, 0); + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN); + } + else if (priv->dcnt == 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0); + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0); + } +#endif + + /* Was last byte received or sent? Hmmm... the F2 and F4 seems to differ from + * the F1 in that BTF is not set after data is received (only RXNE). + */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) + if (priv->dcnt <= 0 && (status & (I2C_SR1_BTF | I2C_SR1_RXNE)) != 0) +#else + if (priv->dcnt <= 0 && (status & I2C_SR1_BTF) != 0) +#endif + { + stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); /* ACK ISR */ + + /* Do we need to terminate or restart after this byte? + * If there are more messages to send, then we may: + * + * - continue with repeated start + * - or just continue sending writeable part + * - or we close down by sending the stop bit + */ + + if (priv->msgc > 0 && priv->msgv != NULL) + { + if (priv->msgv->flags & I2C_M_NORESTART) + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFNOSTART, priv->msgc); + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->msgv++; + priv->msgc--; + + /* Restart this ISR! */ + +#ifndef CONFIG_I2C_POLLED + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN); +#endif + } + else + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFRESTART, priv->msgc); + stm32_i2c_sendstart(priv); + } + } + else if (priv->msgv) + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFSTOP, 0); + stm32_i2c_sendstop(priv); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + + /* Mark that we have stopped with this transaction */ + + priv->msgv = NULL; + } + } + + /* Check for errors, in which case, stop the transfer and return + * Note that in master reception mode AF becomes set on last byte + * since ACK is not returned. We should ignore this error. + */ + + if ((status & I2C_SR1_ERRORMASK) != 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_ERROR, 0); + + /* Clear interrupt flags */ + + stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + } + + priv->status = status; + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c1_isr + * + * Description: + * I2C1 interrupt service routine + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c1_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c2_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c2_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c3_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c3_priv); +} +#endif +#endif + +/************************************************************************************ + * Private Initialization and Deinitialization + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv) +{ + /* Power-up and configure GPIOs */ + + /* Enable power and reset the peripheral */ + + modifyreg32(STM32_RCC_APB1ENR, 0, priv->config->clk_bit); + modifyreg32(STM32_RCC_APB1RSTR, 0, priv->config->reset_bit); + modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0); + + /* Configure pins */ + + if (stm32_configgpio(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (stm32_configgpio(priv->config->sda_pin) < 0) + { + stm32_unconfiggpio(priv->config->scl_pin); + return ERROR; + } + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->ev_irq, priv->config->isr); + irq_attach(priv->config->er_irq, priv->config->isr); + up_enable_irq(priv->config->ev_irq); + up_enable_irq(priv->config->er_irq); +#endif + + /* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz + * or 4 MHz for 400 kHz. This also disables all I2C interrupts. + */ + + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, (STM32_PCLK1_FREQUENCY / 1000000)); + + /* Force a frequency update */ + + priv->frequency = 0; + + stm32_i2c_setclock(priv, 100000); + + /* Enable I2C */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE); + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv) +{ + /* Disable I2C */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, 0); + + /* Unconfigure GPIO pins */ + + stm32_unconfiggpio(priv->config->scl_pin); + stm32_unconfiggpio(priv->config->sda_pin); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->ev_irq); + up_disable_irq(priv->config->er_irq); + irq_detach(priv->config->ev_irq); + irq_detach(priv->config->er_irq); +#endif + + /* Disable clocking */ + + modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0); + return OK; +} + +/************************************************************************************ + * Device Driver Operations + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ************************************************************************************/ + +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count) +{ + FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; + stm32_i2c_sem_wait(priv); /* Ensure that address or flags don't change meanwhile */ + uint32_t status = 0; +#ifdef I2C1_FSMC_CONFLICT + uint32_t ahbenr; +#endif + int ret = 0; + + ASSERT(count); + +#ifdef I2C1_FSMC_CONFLICT + /* Disable FSMC that shares a pin with I2C1 (LBAR) */ + + ahbenr = stm32_i2c_disablefsmc(priv); + +#else + /* Wait for any STOP in progress. NOTE: If we have to disable the FSMC + * then we cannot do this at the top of the loop, unfortunately. The STOP + * will not complete normally if the FSMC is enabled. + */ + + stm32_i2c_sem_waitstop(priv); +#endif + + /* Clear any pending error interrupts */ + + stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." However, if the bits are + * not cleared by hardware, then we will have to do that from hardware. + */ + + stm32_i2c_clrstart(priv); + + /* Old transfers are done */ + + /* Reset ptr and dcnt to ensure an unexpected data interrupt doesn't + * overwrite stale data. + */ + + priv->dcnt = 0; + priv->ptr = NULL; + + priv->msgv = msgs; + priv->msgc = count; + + /* Reset I2C trace logic */ + + stm32_i2c_tracereset(priv); + + /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + stm32_i2c_setclock(priv, msgs->frequency); + + /* Trigger start condition, then the process moves into the ISR. I2C + * interrupts will be enabled within stm32_i2c_waitdone(). + */ + + priv->status = 0; + stm32_i2c_sendstart(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (stm32_i2c_sem_waitdone(priv) < 0) + { + status = stm32_i2c_getstatus(priv); + ret = -ETIMEDOUT; + + i2cdbg("Timed out: CR1: 0x%04x status: 0x%08x\n", + stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + */ + + stm32_i2c_clrstart(priv); + + /* Clear busy flag in case of timeout */ + + status = priv->status & 0xffff; + } + else + { + /* clear SR2 (BUSY flag) as we've done successfully */ + + status = priv->status & 0xffff; + } + + /* Check for error status conditions */ + + if ((status & I2C_SR1_ERRORMASK) != 0) + { + /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */ + + if (status & I2C_SR1_BERR) + { + /* Bus Error */ + + ret = -EIO; + } + else if (status & I2C_SR1_ARLO) + { + /* Arbitration Lost (master mode) */ + + ret = -EAGAIN; + } + else if (status & I2C_SR1_AF) + { + /* Acknowledge Failure */ + + ret = -ENXIO; + } + else if (status & I2C_SR1_OVR) + { + /* Overrun/Underrun */ + + ret = -EIO; + } + else if (status & I2C_SR1_PECERR) + { + /* PEC Error in reception */ + + ret = -EPROTO; + } + else if (status & I2C_SR1_TIMEOUT) + { + /* Timeout or Tlow Error */ + + ret = -ETIME; + } + + /* This is not an error and should never happen since SMBus is not enabled */ + + else /* if (status & I2C_SR1_SMBALERT) */ + { + /* SMBus alert is an optional signal with an interrupt line for devices + * that want to trade their ability to master for a pin. + */ + + ret = -EINTR; + } + } + + /* This is not an error, but should not happen. The BUSY signal can hang, + * however, if there are unhealthy devices on the bus that need to be reset. + * NOTE: We will only see this busy indication if stm32_i2c_sem_waitdone() + * fails above; Otherwise it is cleared. + */ + + else if ((status & (I2C_SR2_BUSY << 16)) != 0) + { + /* I2C Bus is for some reason busy */ + + ret = -EBUSY; + } + + /* Dump the trace result */ + + stm32_i2c_tracedump(priv); + +#ifdef I2C1_FSMC_CONFLICT + /* Wait for any STOP in progress. NOTE: If we have to disable the FSMC + * then we cannot do this at the top of the loop, unfortunately. The STOP + * will not complete normally if the FSMC is enabled. + */ + + stm32_i2c_sem_waitstop(priv); + + /* Re-enable the FSMC */ + + stm32_i2c_enablefsmc(ahbenr); +#endif + + /* Ensure that any ISR happening after we finish can't overwrite any user data */ + + priv->dcnt = 0; + priv->ptr = NULL; + + stm32_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: stm32_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s *dev) +{ + FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret = ERROR; + + ASSERT(dev); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + stm32_i2c_sem_wait(priv); + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + stm32_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + stm32_configgpio(scl_gpio); + stm32_configgpio(sda_gpio); + + /* Let SDA go high */ + + stm32_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!stm32_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!stm32_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + stm32_gpiowrite(sda_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + stm32_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + stm32_unconfiggpio(sda_gpio); + stm32_unconfiggpio(scl_gpio); + + /* Re-init the port */ + + stm32_i2c_init(priv); + + /* Restore the frequency */ + + stm32_i2c_setclock(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + stm32_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ************************************************************************************/ + +FAR struct i2c_master_s *stm32_i2cbus_initialize(int port) +{ + struct stm32_i2c_priv_s * priv = NULL; + irqstate_t flags; + +#if STM32_PCLK1_FREQUENCY < 4000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation. +#endif + +#if STM32_PCLK1_FREQUENCY < 2000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation. + return NULL; +#endif + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_STM32_I2C1 + case 1: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C2 + case 2: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C3 + case 3: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv; + break; +#endif + default: + return NULL; + } + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + stm32_i2c_sem_init(priv); + stm32_i2c_init(priv); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/************************************************************************************ + * Name: stm32_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ************************************************************************************/ + +int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; + irqstate_t flags; + + ASSERT(dev); + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + stm32_i2c_deinit(priv); + + /* Release unused resources */ + + stm32_i2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F40XX */ +#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */ diff --git a/arch/arm/src/stm32/stm32_i2c.h b/arch/arm/src/stm32/stm32_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..05f57ee46fbbfaed8be71d68b4141c558ae5da26 --- /dev/null +++ b/arch/arm/src/stm32/stm32_i2c.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_I2C_H +#define __ARCH_ARM_SRC_STM32_STM32_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#if defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_i2c.h" +#else +# include "chip/stm32_i2c.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If a dynamic timeout is selected, then a non-negative, non-zero micro- + * seconds per byte value must be provided as well. + */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +# if CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE < 1 +# warning "Ignoring CONFIG_STM32_I2C_DYNTIMEO because of CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE" +# undef CONFIG_STM32_I2C_DYNTIMEO +# endif +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *stm32_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: stm32_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the stm32_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_STM32_STM32_I2C_H */ diff --git a/arch/arm/src/stm32/stm32_i2c_alt.c b/arch/arm/src/stm32/stm32_i2c_alt.c new file mode 100644 index 0000000000000000000000000000000000000000..da50a9c263508f6aa96817462596fe2e88ba2c7b --- /dev/null +++ b/arch/arm/src/stm32/stm32_i2c_alt.c @@ -0,0 +1,2499 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_i2c_alt.c + * STM32 I2C Hardware Layer - Device Driver + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With extensions, modifications by: + * + * Copyright (C) 2011-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Copyright( C) 2014 Patrizio Simona. All rights reserved. + * Author: Patrizio Simona + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Supports: + * - Master operation, 100 kHz (standard) and 400 kHz (full speed) + * - Multiple instances (shared bus) + * - Interrupt based operation + * + * Structure naming: + * - Device: structure as defined by the nuttx/i2c/i2c.h + * - Instance: represents each individual access to the I2C driver, obtained by + * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; + * Instance points to OPS, to common I2C Hardware private data and contains + * its own private data, as frequency, address, mode of operation (in the + * future) + * - Private: Private data of an I2C Hardware + * + * TODO + * - Trace events in polled operation fill trace table very quickly. Events 1111 + * and 1004 get traced in an alternate fashion during polling causing multiple + * entries. + * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW + * using the I2C_CR1_SWRST) + * - SMBus support (hardware layer timings are already supported) and add SMBA + * gpio pin + * - Slave support with multiple addresses (on multiple instances): + * - 2 x 7-bit address or + * - 1 x 10 bit addresses + 1 x 7 bit address (?) + * - plus the broadcast address (general call) + * - Multi-master support + * - DMA (to get rid of too many CPU wake-ups and interventions) + * - Be ready for IPMI + * - Write trace events to keep track of ISR flow + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" +#include "stm32_i2c.h" +#include "stm32_waste.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || \ + defined(CONFIG_STM32_I2C3) + +/* This implementation is for the STM32 F1, F2, and F4 only */ +/* Experimentally enabled for STM32L15XX */ + +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_STM32_I2CTIMEOSEC) && !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOSEC 0 +# define CONFIG_STM32_I2CTIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOSEC) +# define CONFIG_STM32_I2CTIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_STM32_I2CTIMEOTICKS +# define CONFIG_STM32_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS)) +#endif + +#ifndef CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32_I2CTIMEOTICKS) +#endif + +/* On the STM32F103ZE, there is an internal conflict between I2C1 and FSMC. In that + * case, it is necessary to disable FSMC before each I2C1 access and re-enable FSMC + * when the I2C access completes. + */ + +#undef I2C1_FSMC_CONFLICT +#if defined(CONFIG_STM32_STM32F10XX) && defined(CONFIG_STM32_FSMC) && defined(CONFIG_STM32_I2C1) +# define I2C1_FSMC_CONFLICT +#endif + +/* Macros to convert a I2C pin to a GPIO output */ + +#if defined(CONFIG_STM32_STM32L15XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_OPENDRAIN | \ + GPIO_SPEED_40MHz) +#elif defined(CONFIG_STM32_STM32F10XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD | \ + GPIO_MODE_50MHz) +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define I2C_OUTPUT (GPIO_OUTPUT | GPIO_FLOAT | GPIO_OPENDRAIN |\ + GPIO_SPEED_50MHz | GPIO_OUTPUT_SET) +#endif + +#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ****************************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level + * debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define stm32_i2c_tracereset(p) +# define stm32_i2c_tracenew(p,s) +# define stm32_i2c_traceevent(p,e,a) +# define stm32_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Interrupt state */ + +enum stm32_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for completion of interrupt activity */ + INTSTATE_DONE, /* Interrupt activity complete */ +}; + +/* Trace events */ + +#ifdef CONFIG_I2C_TRACE +static const uint16_t I2CEVENT_NONE = 0; /* No events have occurred with this status */ +static const uint16_t I2CEVENT_STATE_ERROR = 1000; /* No correct state detected, diver cannot handle state */ +static const uint16_t I2CEVENT_ISR_SHUTDOWN = 1001; /* ISR gets shutdown */ +static const uint16_t I2CEVENT_ISR_EMPTY_CALL = 1002; /* ISR gets called but no I2C logic comes into play */ +static const uint16_t I2CEVENT_MSG_HANDLING = 1003; /* Message Handling 1/1: advances the msg processing param = msgc */ +static const uint16_t I2CEVENT_POLL_DEV_NOT_RDY = 1004; /* During polled operation if device is not ready yet */ +static const uint16_t I2CEVENT_ISR_CALL = 1111; /* ISR called */ + +static const uint16_t I2CEVENT_SENDADDR = 5; /* Start/Master bit set and address sent, param = priv->msgv->addr(EV5 in reference manual) */ +static const uint16_t I2CEVENT_ADDR_HDL_READ_1 = 51; /* Read of length 1 address handling, param = 0 */ +static const uint16_t I2CEVENT_ADDR_HDL_READ_2 = 52; /* Read of length 2 address handling, param = 0 */ +static const uint16_t I2CEVENT_EMPTY_MSG = 5000; /* Empty message detected, param=0 */ + +static const uint16_t I2CEVENT_ADDRESS_ACKED = 6; /* Address has been ACKed(i.e. it's a valid address) param = address */ +static const uint16_t I2CEVENT_ADDRESS_ACKED_READ_1 = 63; /* Event when reading single byte just after address is beeing ACKed, param = 0 */ +static const uint16_t I2CEVENT_ADDRESS_ACKED_READ_2 = 61; /* Event when reading two bytes just after address is beeing ACKed, param = 0 */ +static const uint16_t I2CEVENT_ADDRESS_ACKED_WRITE = 681; /* Address has been ACKed(i.e. it's a valid address) in write mode and byte has been written */ +static const uint16_t I2CEVENT_ADDRESS_NACKED = 6000; /* Address has been NACKed(i.e. it's an invalid address) param = address */ + +static const uint16_t I2CEVENT_READ = 7; /* RxNE = 1 therefore can be read, param = dcnt */ +static const uint16_t I2CEVENT_READ_3 = 72; /* EV7_2 reference manual, reading byte N-2 and N-1 when N >=3 */ +static const uint16_t I2CEVENT_READ_2 = 73; /* EV7_3 reference manual, reading byte 1 and 2 when N == 2 */ +static const uint16_t I2CEVENT_READ_SR_EMPTY = 79; /* DR is full but SR is empty, does not read DR and waits for SR to fill in next ISR */ +static const uint16_t I2CEVENT_READ_LAST_BYTE = 72; /* EV7_2 reference manual last two bytes are in SR and DR */ +static const uint16_t I2CEVENT_READ_ERROR = 7000; /* read mode error */ + +static const uint16_t I2CEVENT_WRITE_TO_DR = 8; /* EV8 reference manual, writing into the data register param = byte to send */ +static const uint16_t I2CEVENT_WRITE_STOP = 82; /* EV8_2 reference manual, set stop bit after write is finished */ +static const uint16_t I2CEVENT_WRITE_RESTART = 83; /* Re-send start bit as next packet is a read */ +static const uint16_t I2CEVENT_WRITE_NO_RESTART = 84; /* don't restart as packet flag says so */ +static const uint16_t I2CEVENT_WRITE_ERROR = 8000; /* Error in write mode, param = 0 */ +static const uint16_t I2CEVENT_WRITE_FLAG_ERROR = 8001; /* Next message has unrecognized flag, param = priv->msgv->flags */ +#endif /* CONFIG_I2C_TRACE */ + +/* Trace data */ + +struct stm32_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + uint32_t event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + systime_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct stm32_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t reset_bit; /* Reset bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr)(int, void *); /* Interrupt handler */ + uint32_t ev_irq; /* Event IRQ */ + uint32_t er_irq; /* Error IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct stm32_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct stm32_i2c_config_s *config; /* Port configuration */ + int refs; /* Referernce count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + bool check_addr_ACK; /* Flag to signal if on next interrupt address has ACKed */ + uint8_t total_msg_len; /* Flag to signal a short read sequence */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + systime_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct stm32_trace_s trace[CONFIG_I2C_NTRACE]; +#endif + + uint32_t status; /* End of transfer SR2|SR1 status */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset); +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value); +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv); + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_STM32_I2C_DYNTIMEO */ + +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv); + +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv); +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint16_t status); +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + uint16_t event, uint32_t parm); +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, + uint32_t frequency); +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv); +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv); + +#ifdef I2C1_FSMC_CONFLICT +static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_enablefsmc(uint32_t ahbenr); +#endif /* I2C1_FSMC_CONFLICT */ + +static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv); + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context); +#endif +#endif /* !CONFIG_I2C_POLLED */ + +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* I2C interface */ + +static const struct i2c_ops_s stm32_i2c_ops = +{ + .transfer = stm32_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = stm32_i2c_reset +#endif +}; + +#ifdef CONFIG_STM32_I2C1 +static const struct stm32_i2c_config_s stm32_i2c1_config = +{ + .base = STM32_I2C1_BASE, + .clk_bit = RCC_APB1ENR_I2C1EN, + .reset_bit = RCC_APB1RSTR_I2C1RST, + .scl_pin = GPIO_I2C1_SCL, + .sda_pin = GPIO_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c1_isr, + .ev_irq = STM32_IRQ_I2C1EV, + .er_irq = STM32_IRQ_I2C1ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c1_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c1_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C2 +static const struct stm32_i2c_config_s stm32_i2c2_config = +{ + .base = STM32_I2C2_BASE, + .clk_bit = RCC_APB1ENR_I2C2EN, + .reset_bit = RCC_APB1RSTR_I2C2RST, + .scl_pin = GPIO_I2C2_SCL, + .sda_pin = GPIO_I2C2_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c2_isr, + .ev_irq = STM32_IRQ_I2C2EV, + .er_irq = STM32_IRQ_I2C2ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c2_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c2_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C3 +static const struct stm32_i2c_config_s stm32_i2c3_config = +{ + .base = STM32_I2C3_BASE, + .clk_bit = RCC_APB1ENR_I2C3EN, + .reset_bit = RCC_APB1RSTR_I2C3RST, + .scl_pin = GPIO_I2C3_SCL, + .sda_pin = GPIO_I2C3_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c3_isr, + .ev_irq = STM32_IRQ_I2C3EV, + .er_irq = STM32_IRQ_I2C3ER +#endif +}; + +static struct stm32_i2c_priv_s stm32_i2c3_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c3_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value) +{ + putreg16(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_modifyreg + * + * Description: + * Modify a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv) +{ + while (sem_wait(&priv->sem_excl) != 0) + { + ASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: stm32_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be processed. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + uint32_t regval; + int ret; + + flags = enter_critical_section(); + + /* Enable I2C interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN); + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_STM32_I2CTIMEOSEC > 0 + abstime.tv_sec += CONFIG_STM32_I2CTIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * stm32_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_STM32_I2CTIMEOMS > 0 + abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->sem_isr, &abstime); + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by sem_timedwait. + * NOTE that we try again if we are awakened by a signal (EINTR). + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval &= ~I2C_CR2_ALLINTS; + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); + + leave_critical_section(flags); + return ret; +} +#else +static int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(stm32_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + start = clock_systimer(); + + do + { + /* Poll by simply calling the timer interrupt handler until it + * reports that it is done. + */ + + stm32_i2c_isr(priv); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cvdbg("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, priv->status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_sem_waitstop + * + * Description: + * Wait for a STOP to complete + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t start; + systime_t elapsed; + systime_t timeout; + uint32_t cr1; + uint32_t sr1; + + /* Select a timeout */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Wait as stop might still be in progress; but stop might also + * be set because of a timeout error: "The [STOP] bit is set and + * cleared by software, cleared by hardware when a Stop condition is + * detected, set by hardware when a timeout error is detected." + */ + + start = clock_systimer(); + do + { + /* Check for STOP condition */ + + cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET); + if ((cr1 & I2C_CR1_STOP) == 0) + { + return; + } + + /* Check for timeout error */ + + sr1 = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET); + if ((sr1 & I2C_SR1_TIMEOUT) != 0) + { + return; + } + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the stop is complete or a timeout occurs. */ + + while (elapsed < timeout); + + /* If we get here then a timeout occurred with the STOP condition + * still pending. + */ + + i2cvdbg("Timeout with CR1: %04x SR1: %04x\n", cr1, sr1); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv) +{ + sem_post(&priv->sem_excl); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) +{ + sem_init(&priv->sem_excl, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->sem_isr, 0, 0); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv) +{ + sem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->sem_isr); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_trace* + * + * Description: + * I2C trace instrumentation + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_traceclear(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systimer(); + stm32_i2c_traceclear(priv); +} + +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint16_t status) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + stm32_i2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systimer(); + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + uint16_t event, uint32_t parm) +{ + struct stm32_trace_s *trace; + + if (event != I2CEVENT_NONE || event != I2CEVENT_POLL_DEV_NOT_RDY) + { + trace = &priv->trace[priv->tndx]; + + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + stm32_i2c_traceclear(priv); + } +} + +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->start_time)); + + for (i = 0; i <= priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %4d EVENT: %4d PARM: %08x TIME: %d\n", + i+1, trace->status, trace->count, trace->event, trace->parm, + trace->time - priv->start_time); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/************************************************************************************ + * Name: stm32_i2c_setclock + * + * Description: + * Set the I2C clock + * + ************************************************************************************/ + +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequency) +{ + uint16_t cr1; + uint16_t ccr; + uint16_t trise; + uint16_t freqmhz; + uint16_t speed; + + /* Has the I2C bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Disable the selected I2C peripheral to configure TRISE */ + + cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET); + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1 & ~I2C_CR1_PE); + + /* Update timing and control registers */ + + freqmhz = (uint16_t)(STM32_PCLK1_FREQUENCY / 1000000); + ccr = 0; + + /* Configure speed in standard mode */ + + if (frequency <= 100000) + { + /* Standard mode speed calculation */ + + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency << 1)); + + /* The CCR fault must be >= 4 */ + + if (speed < 4) + { + /* Set the minimum allowed value */ + + speed = 4; + } + + ccr |= speed; + + /* Set Maximum Rise Time for standard mode */ + + trise = freqmhz + 1; + } + + /* Configure speed in fast mode */ + + else /* (frequency <= 400000) */ + { + /* Fast mode speed calculation with Tlow/Thigh = 16/9 */ + +#ifdef CONFIG_STM32_I2C_DUTY16_9 + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency * 25)); + + /* Set DUTY and fast speed bits */ + + ccr |= (I2C_CCR_DUTY | I2C_CCR_FS); +#else + /* Fast mode speed calculation with Tlow/Thigh = 2 */ + + speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency * 3)); + + /* Set fast speed bit */ + + ccr |= I2C_CCR_FS; +#endif + + /* Verify that the CCR speed value is nonzero */ + + if (speed < 1) + { + /* Set the minimum allowed value */ + + speed = 1; + } + + ccr |= speed; + + /* Set Maximum Rise Time for fast mode */ + + trise = (uint16_t)(((freqmhz * 300) / 1000) + 1); + } + + /* Write the new values of the CCR and TRISE registers */ + + stm32_i2c_putreg(priv, STM32_I2C_CCR_OFFSET, ccr); + stm32_i2c_putreg(priv, STM32_I2C_TRISE_OFFSET, trise); + + /* Bit 14 of OAR1 must be configured and kept at 1 */ + + stm32_i2c_putreg(priv, STM32_I2C_OAR1_OFFSET, I2C_OAR1_ONE); + + /* Re-enable the peripheral (or not) */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, cr1); + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/************************************************************************************ + * Name: stm32_i2c_sendstart + * + * Description: + * Send the START conditions/force Master mode + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* Disable ACK on receive by default and generate START */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_START); +} + +/************************************************************************************ + * Name: stm32_i2c_clrstart + * + * Description: + * Clear the STOP, START or PEC condition on certain error recovery steps. + * + ************************************************************************************/ + +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + * + * "The [STOP] bit is set and cleared by software, cleared by hardware + * when a Stop condition is detected, set by hardware when a timeout + * error is detected. + * + * "This [START] bit is set and cleared by software and cleared by hardware + * when start is sent or PE=0." The bit must be cleared by software if the + * START is never sent. + * + * "This [PEC] bit is set and cleared by software, and cleared by hardware + * when PEC is transferred or by a START or Stop condition or when PE=0." + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, + I2C_CR1_START | I2C_CR1_STOP | I2C_CR1_PEC, 0); +} + +/************************************************************************************ + * Name: stm32_i2c_sendstop + * + * Description: + * Send the STOP conditions + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, I2C_CR1_STOP); +} + +/************************************************************************************ + * Name: stm32_i2c_getstatus + * + * Description: + * Get 32-bit status (SR1 and SR2 combined) + * + ************************************************************************************/ + +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv) +{ + uint32_t status = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET); + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + return status; +} + +/************************************************************************************ + * Name: stm32_i2c_disablefsmc + * + * Description: + * FSMC must be disable while accessing I2C1 because it uses a common resource + * (LBAR) + * + * NOTE: This is an issue with the STM32F103ZE, but may not be an issue with other + * STM32s. You may need to experiment + * + ************************************************************************************/ + +#ifdef I2C1_FSMC_CONFLICT +static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv) +{ + uint32_t ret = 0; + uint32_t regval; + + /* Is this I2C1 */ + +#if defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) + if (priv->config->base == STM32_I2C1_BASE) +#endif + { + /* Disable FSMC unconditionally */ + + ret = getreg32(STM32_RCC_AHBENR); + regval = ret & ~RCC_AHBENR_FSMCEN; + putreg32(regval, STM32_RCC_AHBENR); + } + + return ret; +} + +/************************************************************************************ + * Name: stm32_i2c_enablefsmc + * + * Description: + * Re-enable the FSMC + * + ************************************************************************************/ + +static inline void stm32_i2c_enablefsmc(uint32_t ahbenr) +{ + uint32_t regval; + + /* Enable AHB clocking to the FSMC only if it was previously enabled. */ + + if ((ahbenr & RCC_AHBENR_FSMCEN) != 0) + { + regval = getreg32(STM32_RCC_AHBENR); + regval |= RCC_AHBENR_FSMCEN; + putreg32(regval, STM32_RCC_AHBENR); + } +} +#else +# define stm32_i2c_disablefsmc(priv) (0) +# define stm32_i2c_enablefsmc(ahbenr) +#endif /* I2C1_FSMC_CONFLICT */ + +/************************************************************************************ + * Name: stm32_i2c_isr + * + * Description: + * Common interrupt service routine (ISR) that handles I2C protocol logic. + * + * This ISR is activated and deactivated by stm32_i2c_waitdone(). Interrupt fires + * on(both ITEVFEN and ITBUFEN are set): + * + * - Start bit + * - Address sent + * - 10-bit header sent + * - Data byte transfer finished + * - Receive buffer not empty + * - Transmit buffer empty + * + * Input Parameters: + * priv - The private struct of the I2C driver. + * + * Returned Value: + * + ************************************************************************************/ + +static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) +{ + uint32_t status; + + i2cvdbg("I2C ISR called\n"); + + /* Get state of the I2C controller (register SR1 only) + * + * Get control register SR1 only as reading both SR1 and SR2 clears the ADDR + * flag(possibly others) causing the hardware to advance to the next state + * without the proper action being taken. + */ + + status = stm32_i2c_getreg(priv, STM32_I2C_SR1_OFFSET); + + /* Update private version of the state */ + + priv->status = status; + + /* Check if this is a new transmission so to set up the + * trace table accordingly. + */ + + stm32_i2c_tracenew(priv, status); + stm32_i2c_traceevent(priv, I2CEVENT_ISR_CALL, 0); + + /* Messages handling (1/2) + * + * Message handling should only operate when a message has been completely + * sent and after the ISR had the chance to run to set bits after the last + * written/read byte, i.e. priv->dcnt == -1. This is also the case in when + * the ISR is called for the first time. This can seen in stm32_i2c_transfer() + * before entering the stm32_i2c_sem_waitdone() waiting process. + * + * Message handling should only operate when: + * - A message has been completely sent and there are still messages + * to send(i.e. msgc > 0). + * - After the ISR had the chance to run to set start bit or termination + * flags after the last written/read byte(after last byte dcnt=0, msg + * handling dcnt = -1). + * + * When the ISR is called for the first time the same conditions hold. + * This can seen in stm32_i2c_transfer() before entering the + * stm32_i2c_sem_waitdone() waiting process. + */ + + if (priv->dcnt == -1 && priv->msgc > 0) + { + i2cvdbg("Switch to new message\n"); + + /* Get current message to process data and copy to private structure */ + + priv->ptr = priv->msgv->buffer; /* Copy buffer to private struct */ + priv->dcnt = priv->msgv->length; /* Set counter of current msg length */ + priv->total_msg_len = priv->msgv->length; /* Set total msg length */ + priv->flags = priv->msgv->flags; /* Copy flags to private struct */ + + i2cvdbg("Current flags %i\n", priv->flags); + + /* Decrease counter to indicate the number of messages left to process */ + + priv->msgc--; + + /* Decrease message pointer. If last message set next message vector to null */ + + if (priv->msgc == 0) + { + /* No more messages, don't need to increment msgv. This pointer will be set + * to zero when reaching the termination of the ISR calls, i.e. Messages + * handling(2/2). + */ + } + else + { + /* If not last message increment to next message to process */ + + priv->msgv++; + } + + /* Trace event */ + + stm32_i2c_traceevent(priv, I2CEVENT_MSG_HANDLING, priv->msgc); + } + + /* Note the event where we are on the last message and after the last + * byte is handled at the bottom of this function, as it terminates + * the repeated calls to the ISR. + */ + + /* I2C protocol logic + * + * I2C protocol logic follows. It's organized in an if else chain such that + * only one mode of operation is executed every time the ISR is called. + */ + + /* Address Handling + * + * Check if a start bit was set and transmit address with proper format. + * + * Note: + * On first call the start bit has been set by stm32_i2c_waitdone() + * Otherwise it will be set from this ISR. + * + * Remember that after a start bit an address has always to be sent. + */ + + if ((status & I2C_SR1_SB) != 0) + { + /* Start bit is set */ + + i2cvdbg("Entering address handling, status = %i\n", status); + + /* Check for empty message (for robustness) */ + + if (priv->dcnt > 0) + { + /* When reading messages of length 1 or 2 actions have to be taken + * during this event. The following block handles that. + */ + + if (priv->total_msg_len == 1 && (priv->flags & I2C_M_READ)) + { + i2cvdbg("short read N=1: setting NACK\n"); + + /* Set POS bit to zero (can be up from a previous 2 byte receive) */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_POS, 0); + + /* Immediately set NACK */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0); + stm32_i2c_traceevent(priv, I2CEVENT_ADDR_HDL_READ_1, 0); + } + else if (priv->total_msg_len == 2 && (priv->flags & I2C_M_READ)) + { + i2cvdbg("short read N=2: setting POS and ACK bits\n"); + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_POS); + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_ACK); + stm32_i2c_traceevent(priv, I2CEVENT_ADDR_HDL_READ_2, 0); + } + else + { + /* Enable ACK after address byte */ + + i2cvdbg("setting ACK\n"); + + /* Set POS bit to zero (can be up from a previous 2 byte receive) */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_POS, 0); + + /* ACK is the expected answer for N>=3 reads and writes */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_ACK); + } + + /* Send address byte with correct 8th bit set(for writing or reading) + * Transmission happens after having written to the data register + * STM32_I2C_DR + */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, + (priv->flags & I2C_M_TEN) ? + 0 :((priv->msgv->addr << 1) | (priv->flags & I2C_M_READ))); + + i2cvdbg("Address sent. Addr=%#02x Write/Read bit=%i\n", + priv->msgv->addr, (priv->flags & I2C_M_READ)); + + /* Flag that address has just been sent */ + + priv->check_addr_ACK = true; + + stm32_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgv->addr); + } + else + { + /* TODO: untested!! */ + + i2cdbg(" An empty message has been detected, ignoring and passing to next message.\n"); + + /* Trace event */ + + stm32_i2c_traceevent(priv, I2CEVENT_EMPTY_MSG, 0); + + /* Set condition to activate msg handling */ + + priv->dcnt = -1; + + /* Restart ISR by setting an interrupt buffer bit */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN); + } + } + + /* Address cleared event + * + * Check if the address cleared, i.e. the driver found a valid address. + * If a NACK was received the address is invalid, if an ACK was + * received the address is valid and transmission can continue. + */ + + /* Check for NACK after an address */ + +#ifndef CONFIG_I2C_POLLED + /* When polling the i2c ISR it's not possible to determine when + * an address has been ACKed(i.e. the address is valid). + * + * The mechanism to deal a NACKed address is to wait for the I2C + * call to timeout (value defined in defconfig by one of the + * following: CONFIG_STM32_I2C_DYNTIMEO, CONFIG_STM32_I2CTIMEOSEC, + * CONFIG_STM32_I2CTIMEOMS, CONFIG_STM32_I2CTIMEOTICKS). + * + * To be safe in the case of a timeout/NACKed address a stop bit + * is set on the bus to clear it. In POLLED operation it's done + * stm32_i2c_transfer() after the call to stm32_i2c_sem_waitdone(). + * + * In ISR driven operation the stop bit in case of a NACKed address + * is set in the ISR itself. + * + * Note: this commentary is found in both places. + */ + + else if ((status & I2C_SR1_ADDR) == 0 && priv->check_addr_ACK) + { + i2cvdbg("Invalid Address. Setting stop bit and clearing message\n"); + i2cvdbg("status %i\n", status); + + /* Set condition to terminate msg chain transmission as address is invalid. */ + + priv->dcnt = -1; + priv->msgc = 0; + + i2cvdbg("dcnt %i , msgc %i\n", priv->dcnt, priv->msgc); + + /* Reset flag to check for valid address */ + + priv->check_addr_ACK = false; + + /* Send stop bit to clear bus */ + + stm32_i2c_sendstop(priv); + + /* Trace event */ + + stm32_i2c_traceevent(priv, I2CEVENT_ADDRESS_NACKED, priv->msgv->addr); + } +#endif + + /* ACK in read mode, ACK in write mode is handled separately */ + + else if ((priv->flags & I2C_M_READ) != 0 && (status & I2C_SR1_ADDR) != 0 && + priv->check_addr_ACK) + { + /* Reset check addr flag as we are handling this event */ + + priv->check_addr_ACK = false; + + /* Clear ADDR flag by reading SR2 and adding it to status */ + + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + + /* Note: + * + * When reading a single byte the stop condition has to be set + * immediately after clearing the state flags, which happens + * when reading SR2(as SR1 has already been read). + * + * Similarly when reading 2 bytes the NACK bit has to be set as just + * after the clearing of the address. + */ + + if (priv->dcnt == 1 && priv->total_msg_len == 1) + { + /* this should only happen when receiving a message of length 1 */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN); + stm32_i2c_sendstop(priv); + + i2cvdbg("Address ACKed beginning data reception\n"); + i2cvdbg("short read N=1: programming stop bit\n"); + priv->dcnt--; + + /* Trace */ + + stm32_i2c_traceevent(priv, I2CEVENT_ADDRESS_ACKED_READ_1, 0); + } + else if (priv->dcnt == 2 && priv->total_msg_len == 2) + { + /* This should only happen when receiving a message of length 2 + * Set NACK + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0); + + i2cvdbg("Address ACKed beginning data reception\n"); + i2cvdbg("short read N=2: programming NACK\n"); + + /* Trace */ + + stm32_i2c_traceevent(priv, I2CEVENT_ADDRESS_ACKED_READ_2, 0); + } + else + { + i2cvdbg("Address ACKed beginning data reception\n"); + + /* Trace */ + + stm32_i2c_traceevent(priv, I2CEVENT_ADDRESS_ACKED, 0); + } + } + + /* Write mode + * + * Handles all write related I2C protocol logic. Also handles the + * ACK event after clearing the ADDR flag as the write has to + * begin immediately after. + */ + + else if ((priv->flags & (I2C_M_READ)) == 0 && + (status & (I2C_SR1_ADDR | I2C_SR1_TXE)) != 0) + { + /* The has cleared(ADDR is set, ACK was received after the address) + * or the transmit buffer is empty flag has been set(TxE) then we can + * transmit the next byte. + */ + + i2cvdbg("Entering write mode dcnt = %i msgc = %i\n", + priv->dcnt, priv->msgc); + + /* Clear ADDR flag by reading SR2 and adding it to status */ + + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + + /* Address has cleared so don't check on next call */ + + priv->check_addr_ACK = false; + + /* Check if we have transmitted the whole message or we are after + * the last byte where the stop condition or else(according to the + * msg flags) has to be set. + */ + + if (priv->dcnt >= 1) + { + /* Transmitting message. Send byte == write data into write register */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++); + + /* Decrease current message length */ + + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_TO_DR, priv->dcnt); + priv->dcnt--; + + } + else if (priv->dcnt == 0) + { + /* After last byte, check what to do based on next message flags */ + + if (priv->msgc == 0) + { + /* If last message send stop bit */ + + stm32_i2c_sendstop(priv); + i2cvdbg("Stop sent dcnt = %i msgc = %i\n", priv->dcnt, priv->msgc); + + /* Decrease counter to get to next message */ + + priv->dcnt--; + i2cvdbg("dcnt %i\n", priv->dcnt); + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_STOP, priv->dcnt); + } + + /* If there is a next message with no flags or the read flag + * a restart sequence has to be sent. + * Note msgv already points to the next message. + */ + + else if (priv->msgc > 0 && + (priv->msgv->flags == 0 || (priv->msgv[0].flags & I2C_M_READ) != 0)) + { + stm32_i2c_sendstart(priv); + + i2cvdbg("Restart detected!\n"); + i2cvdbg("Nextflag %i\n", priv->msgv[0].flags); + + /* Decrease counter to get to next message */ + + priv->dcnt--; + i2cvdbg("dcnt %i\n", priv->dcnt); + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_RESTART, priv->dcnt); + } + + /* If there is a next message with the NO_RESTART flag + * do nothing. + */ + + else if (priv->msgc > 0 && ((priv->msgv->flags & I2C_M_NORESTART) != 0)) + { + /* Set condition to get to next message */ + + priv->dcnt = -1; + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_NO_RESTART, priv->dcnt); + } + else + { + i2cdbg("Write mode: next message has an unrecognized flag.\n"); + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_FLAG_ERROR, priv->msgv->flags); + } + + } + else + { + i2cdbg("Write mode error.\n"); + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_ERROR, 0); + } + } + + /* Read mode + * + * Handles all read related I2C protocol logic. + * + * * * * * * * WARNING STM32F1xx HARDWARE ERRATA * * * * * * * + * source: https://github.com/hikob/openlab/blob/master/drivers/stm32/i2c.c + * + * RXNE-only events should not be handled since it sometimes + * fails. Only BTF & RXNE events should be handled (with the + * consequence of slowing down the transfer). + * + * It seems that when a RXNE interrupt is handled 'around' + * the end of the next byte reception, the DR register read + * is ignored by the i2c controller: it does not flush the + * DR with next byte + * + * Thus we read twice the same byte and we read effectively + * read one byte less than expected from the i2c slave point + * of view. + * + * Example: + * + we want to receive 6 bytes (B1 to B6) + * + the problem appear when reading B3 + * -> we read B1 B2 B3 B3 B4 B5(B3 twice) + * -> the i2c transfer was B1 B2 B3 B4 B5(B6 is not sent) + */ + + else if ((priv->flags & (I2C_M_READ)) != 0 && (status & I2C_SR1_RXNE) != 0) + { + /* When read flag is set and the receive buffer is not empty + * (RXNE is set) then the driver can read from the data register. + */ + + i2cvdbg("Entering read mode dcnt = %i msgc = %i, status %i\n", + priv->dcnt, priv->msgc, status); + + /* Implementation of method 2 for receiving data following + * the stm32f1xx reference manual. + */ + + /* Case total message length = 1 */ + + if (priv->dcnt == 0 && priv->total_msg_len == 1) + { + i2cvdbg("short read N=1: Read data from data register(DR)\n"); + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + priv->dcnt--; + stm32_i2c_traceevent(priv, I2CEVENT_READ, 0); + } + + /* Case total message length = 2 */ + + else if (priv->dcnt == 2 && priv->total_msg_len == 2 && !(status & I2C_SR1_BTF)) + { + i2cvdbg("short read N=2: DR full, SR empty. Waiting for more bytes.\n"); + stm32_i2c_traceevent(priv, I2CEVENT_READ_SR_EMPTY, 0); + } + else if (priv->dcnt == 2 && priv->total_msg_len == 2 && (status & I2C_SR1_BTF)) + { + i2cvdbg("short read N=2: DR and SR full setting stop bit and reading twice\n"); + + stm32_i2c_sendstop(priv); + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + priv->dcnt--; + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + priv->dcnt--; + + /* Stop request already programmed so set dcnt for next message */ + + priv->dcnt--; + + /* Set trace */ + + stm32_i2c_traceevent(priv, I2CEVENT_READ_2, 0); + } + + /* Case total message length >= 3 */ + + else if (priv->total_msg_len >= 3 && !(status & I2C_SR1_BTF)) + { + /* If the shift register is still empty (i.e. BTF is low) + * then do nothing and wait for it to fill in the next ISR. + * (should not happen in ISR mode, but if using polled mode + * this should be able to handle it). + */ + + i2cvdbg("DR full, SR empty. Waiting for more bytes.\n"); + stm32_i2c_traceevent(priv, I2CEVENT_READ_SR_EMPTY, 0); + } + else if (priv->dcnt >= 4 && priv->total_msg_len >= 3 && (status & I2C_SR1_BTF)) + { + /* Read data from data register(DR). Note this clears the + * RXNE(receive buffer not empty) flag. + */ + + i2cvdbg("Read data from data register(DR)\n"); + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + + /* Decrease current message length */ + + priv->dcnt--; + stm32_i2c_traceevent(priv, I2CEVENT_READ, 0); + } + else if (priv->dcnt == 3 && (status & I2C_SR1_BTF) && priv->total_msg_len >= 3) + { + /* This means that we are reading dcnt 3 and there is already dcnt 2 in + * the shift register. + * This coincides with EV7_2 in the reference manual. + */ + + i2cvdbg("Program NACK\n"); + i2cvdbg("Read data from data register(DR) dcnt=3\n"); + + stm32_i2c_traceevent(priv, I2CEVENT_READ_3, priv->dcnt); + + /* Program NACK */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0); + + /* Read dcnt = 3, to ensure a BTF event after having recieved + * in the shift register. + */ + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + + /* Decrease current message length */ + + priv->dcnt--; + } + else if (priv->dcnt == 2 && (status & I2C_SR1_BTF) && priv->total_msg_len >= 3) + { + i2cvdbg("Program stop\n"); + i2cvdbg("Read data from data register(DR) dcnt=2\n"); + i2cvdbg("Read data from data register(SR) dcnt=1\n"); + i2cvdbg("Setting condition to stop ISR dcnt = -1\n"); + + stm32_i2c_traceevent(priv, I2CEVENT_READ_3, priv->dcnt); + + /* Program stop */ + + stm32_i2c_sendstop(priv); + + /* read dcnt = 2 */ + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + + /* read last byte dcnt=1 */ + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + + /* Stop already sent will not get another interrupt set + * condition to stop ISR + */ + + priv->dcnt = -1; + } + + /* Error handling for read mode */ + + else + { + i2cdbg("I2C read mode no correct state detected\n"); + i2cdbg(" state %i, dcnt=%i\n", status, priv->dcnt); + + /* set condition to terminate ISR and wake waiting thread */ + + priv->dcnt = -1; + priv->msgc = 0; + stm32_i2c_traceevent(priv, I2CEVENT_READ_ERROR, 0); + } + + /* Read rest of the state */ + + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + } + + /* Empty call handler + * + * Case to handle an empty call to the ISR where it only has to + * Shutdown + */ + + else if (priv->dcnt == -1 && priv->msgc == 0) + { + /* Read rest of the state */ + + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + i2cdbg("Empty call to ISR: Stopping ISR\n"); + stm32_i2c_traceevent(priv, I2CEVENT_ISR_EMPTY_CALL, 0); + } + + /* Error handler + * + * Gets triggered if the driver does not recognize a situation(state) + * it can deal with. + * This should not happen in interrupt based operation(i.e. when + * CONFIG_I2C_POLLED is not set in the defconfig file). + * During polled operation(i.e. CONFIG_I2C_POLLED=y in defconfig) + * this case should do nothing but tracing the event that the + * device wasn't ready yet. + */ + + else + { +#ifdef CONFIG_I2C_POLLED + stm32_i2c_traceevent(priv, I2CEVENT_POLL_DEV_NOT_RDY, 0); +#else + /* Read rest of the state */ + + status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); + + i2cdbg(" No correct state detected(start bit, read or write) \n"); + i2cdbg(" state %i\n", status); + + /* set condition to terminate ISR and wake waiting thread */ + + priv->dcnt = -1; + priv->msgc = 0; + stm32_i2c_traceevent(priv, I2CEVENT_STATE_ERROR, 0); +#endif + } + + /* Messages handling(2/2) + * + * Transmission of the whole message chain has been completed. We have to + * terminate the ISR and wake up stm32_i2c_transfer() that is waiting for + * the ISR cycle to handle the sending/receiving of the messages. + */ + + if (priv->dcnt == -1 && priv->msgc == 0) + { + i2cvdbg("Shutting down I2C ISR\n"); + + stm32_i2c_traceevent(priv, I2CEVENT_ISR_SHUTDOWN, 0); + + /* Clear internal pointer to the message content. + * Good practice + done by last implementation when messages are finished + * (compatibility concerns) + */ + + priv->msgv = NULL; + +#ifdef CONFIG_I2C_POLLED + priv->intstate = INTSTATE_DONE; +#else + /* Clear all interrupts */ + + uint32_t regval; + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval &= ~I2C_CR2_ALLINTS; + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); + + /* Is there a thread waiting for this event(there should be) */ + + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#endif + } + + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c1_isr + * + * Description: + * I2C1 interrupt service routine + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c1_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c2_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c2_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c3_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c3_priv); +} +#endif +#endif + +/************************************************************************************ + * Private Initialization and Deinitialization + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv) +{ + /* Power-up and configure GPIOs */ + + /* Enable power and reset the peripheral */ + + modifyreg32(STM32_RCC_APB1ENR, 0, priv->config->clk_bit); + modifyreg32(STM32_RCC_APB1RSTR, 0, priv->config->reset_bit); + modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0); + + /* Configure pins */ + + if (stm32_configgpio(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (stm32_configgpio(priv->config->sda_pin) < 0) + { + stm32_unconfiggpio(priv->config->scl_pin); + return ERROR; + } + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->ev_irq, priv->config->isr); + irq_attach(priv->config->er_irq, priv->config->isr); + up_enable_irq(priv->config->ev_irq); + up_enable_irq(priv->config->er_irq); +#endif + + /* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz + * or 4 MHz for 400 kHz. This also disables all I2C interrupts. + */ + + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, (STM32_PCLK1_FREQUENCY / 1000000)); + + /* Force a frequency update */ + + priv->frequency = 0; + + stm32_i2c_setclock(priv, 100000); + + /* Enable I2C */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE); + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv) +{ + /* Disable I2C */ + + stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, 0); + + /* Unconfigure GPIO pins */ + + stm32_unconfiggpio(priv->config->scl_pin); + stm32_unconfiggpio(priv->config->sda_pin); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->ev_irq); + up_disable_irq(priv->config->er_irq); + irq_detach(priv->config->ev_irq); + irq_detach(priv->config->er_irq); +#endif + + /* Disable clocking */ + + modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0); + return OK; +} + +/************************************************************************************ + * Device Driver Operations + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ************************************************************************************/ + +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count) +{ + FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev; + uint32_t status = 0; +#ifdef I2C1_FSMC_CONFLICT + uint32_t ahbenr; +#endif + int ret = 0; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Ensure that address or flags don't change meanwhile */ + + stm32_i2c_sem_wait(priv); + +#ifdef I2C1_FSMC_CONFLICT + /* Disable FSMC that shares a pin with I2C1 (LBAR) */ + + ahbenr = stm32_i2c_disablefsmc(priv); + +#else + /* Wait for any STOP in progress. NOTE: If we have to disable the FSMC + * then we cannot do this at the top of the loop, unfortunately. The STOP + * will not complete normally if the FSMC is enabled. + */ + + stm32_i2c_sem_waitstop(priv); +#endif + + /* Clear any pending error interrupts */ + + stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." However, if the bits are + * not cleared by hardware, then we will have to do that from hardware. + */ + + stm32_i2c_clrstart(priv); + + /* Old transfers are done */ + + priv->msgv = msgs; + priv->msgc = count; + + /* Reset I2C trace logic */ + + stm32_i2c_tracereset(priv); + + /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + stm32_i2c_setclock(priv, msgs->frequency); + + /* Trigger start condition, then the process moves into the ISR. I2C + * interrupts will be enabled within stm32_i2c_waitdone(). + * + * Initialize current message length counter to zero. This is needed to + * process the first message(first priv->msgv entry) correctly. + */ + + priv->dcnt = -1; + priv->status = 0; + stm32_i2c_sendstart(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (stm32_i2c_sem_waitdone(priv) < 0) + { + status = stm32_i2c_getstatus(priv); + ret = -ETIMEDOUT; + + i2cdbg("Timed out: CR1: 0x%04x status: 0x%08x\n", + stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + */ + + stm32_i2c_clrstart(priv); + +#ifdef CONFIG_I2C_POLLED + /* When polling the i2c ISR it's not possible to determine when + * an address has been ACKed(i.e. the address is valid). + * + * The mechanism to deal a NACKed address is to wait for the I2C + * call to timeout(value defined in defconfig by one of the + * following: CONFIG_STM32_I2C_DYNTIMEO, CONFIG_STM32_I2CTIMEOSEC, + * CONFIG_STM32_I2CTIMEOMS, CONFIG_STM32_I2CTIMEOTICKS). + * + * To be safe in the case of a timeout/NACKed address a stop bit + * is set on the bus to clear it. In POLLED operation it's done + * stm32_i2c_transfer() after the call to stm32_i2c_sem_waitdone(). + * + * In ISR driven operation the stop bit in case of a NACKed address + * is set in the ISR itself. + * + * Note: this commentary is found in both places. + * + */ + i2cdbg("Check if the address was valid\n"); + stm32_i2c_sendstop(priv); +#endif + /* Clear busy flag in case of timeout */ + + status = priv->status & 0xffff; + } + else + { + /* clear SR2 (BUSY flag) as we've done successfully */ + + status = priv->status & 0xffff; + } + + /* Check for error status conditions */ + + if ((status & I2C_SR1_ERRORMASK) != 0) + { + /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */ + + if (status & I2C_SR1_BERR) + { + /* Bus Error */ + + ret = -EIO; + } + else if (status & I2C_SR1_ARLO) + { + /* Arbitration Lost (master mode) */ + + ret = -EAGAIN; + } + else if (status & I2C_SR1_AF) + { + /* Acknowledge Failure */ + + ret = -ENXIO; + } + else if (status & I2C_SR1_OVR) + { + /* Overrun/Underrun */ + + ret = -EIO; + } + else if (status & I2C_SR1_PECERR) + { + /* PEC Error in reception */ + + ret = -EPROTO; + } + else if (status & I2C_SR1_TIMEOUT) + { + /* Timeout or Tlow Error */ + + ret = -ETIME; + } + + /* This is not an error and should never happen since SMBus is not enabled */ + + else /* if (status & I2C_SR1_SMBALERT) */ + { + /* SMBus alert is an optional signal with an interrupt line for devices + * that want to trade their ability to master for a pin. + */ + + ret = -EINTR; + } + } + + /* This is not an error, but should not happen. The BUSY signal can hang, + * however, if there are unhealthy devices on the bus that need to be reset. + * NOTE: We will only see this busy indication if stm32_i2c_sem_waitdone() + * fails above; Otherwise it is cleared. + */ + + else if ((status & (I2C_SR2_BUSY << 16)) != 0) + { + /* I2C Bus is for some reason busy */ + + ret = -EBUSY; + } + + /* Dump the trace result */ + + stm32_i2c_tracedump(priv); + +#ifdef I2C1_FSMC_CONFLICT + /* Wait for any STOP in progress. NOTE: If we have to disable the FSMC + * then we cannot do this at the top of the loop, unfortunately. The STOP + * will not complete normally if the FSMC is enabled. + */ + + stm32_i2c_sem_waitstop(priv); + + /* Re-enable the FSMC */ + + stm32_i2c_enablefsmc(ahbenr); +#endif + + stm32_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: stm32_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s * dev) +{ + FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret = ERROR; + + ASSERT(dev); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + stm32_i2c_sem_wait(priv); + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + stm32_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + /* Let SDA go high */ + + stm32_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!stm32_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!stm32_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + stm32_gpiowrite(sda_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + stm32_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + stm32_unconfiggpio(sda_gpio); + stm32_unconfiggpio(scl_gpio); + + /* Re-init the port */ + + stm32_i2c_init(priv); + + /* Restore the frequency */ + + stm32_i2c_setclock(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + stm32_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ************************************************************************************/ + +FAR struct i2c_master_s *stm32_i2cbus_initialize(int port) +{ + struct stm32_i2c_priv_s *priv = NULL; + irqstate_t flags; + +#if STM32_PCLK1_FREQUENCY < 4000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation. +#endif + +#if STM32_PCLK1_FREQUENCY < 2000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation. + return NULL; +#endif + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_STM32_I2C1 + case 1: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C2 + case 2: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C3 + case 3: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv; + break; +#endif + default: + return NULL; + } + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + stm32_i2c_sem_init(priv); + stm32_i2c_init(priv); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/************************************************************************************ + * Name: stm32_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ************************************************************************************/ + +int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev; + irqstate_t flags; + + ASSERT(dev); + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + stm32_i2c_deinit(priv); + + /* Release unused resources */ + + stm32_i2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F40XX */ +#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */ diff --git a/arch/arm/src/stm32/stm32_idle.c b/arch/arm/src/stm32/stm32_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..0786f2ac99cb917bc10c9f6d7ee70a9545effb6f --- /dev/null +++ b/arch/arm/src/stm32/stm32_idle.c @@ -0,0 +1,212 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_idle.c + * + * Copyright (C) 2011-2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "stm32_pm.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + stm32_pmstop(true); + break; + + case PM_SLEEP: + (void)stm32_pmstandby(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. + * + * NOTE: There is an STM32F107 errata that is fixed by the following + * workaround: + * + * "2.17.11 Ethernet DMA not working after WFI/WFE instruction + * Description + * If a WFI/WFE instruction is executed to put the system in sleep mode + * while the Ethernet MAC master clock on the AHB bus matrix is ON and all + * remaining masters clocks are OFF, the Ethernet DMA will be not able to + * perform any AHB master accesses during sleep mode." + * + * Workaround + * Enable DMA1 or DMA2 clocks in the RCC_AHBENR register before + * executing the WFI/WFE instruction." + * + * Here the workaround is just to avoid SLEEP mode for the connectivity + * line parts if Ethernet is enabled. The errate recommends a more + * general solution: Enabling DMA1/2 clocking in stm32f10xx_rcc.c if the + * STM32107 Ethernet peripheral is enabled. + */ + +#if !defined(CONFIG_STM32_CONNECTIVITYLINE) || !defined(CONFIG_STM32_ETHMAC) +#if !(defined(CONFIG_DEBUG_SYMBOLS) && defined(CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG)) + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +#endif +#endif +} diff --git a/arch/arm/src/stm32/stm32_irq.c b/arch/arm/src/stm32/stm32_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..e6a347c00ac3e26e11c2571e81b2bd308a08769e --- /dev/null +++ b/arch/arm/src/stm32/stm32_irq.c @@ -0,0 +1,566 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_irq.c + * + * Copyright (C) 2009-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + + /* This is the address of the exception vector table (determined by the + * linker script). + */ + +#if defined(__ICCARM__) +/* _vectors replaced on __vector_table for IAR C-SPY Simulator */ + +extern uint32_t __vector_table[]; +#else +extern uint32_t _vectors[]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void stm32_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); + lldbg(" %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY)); + leave_critical_section(flags); +} +#else +# define stm32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32_nmi, stm32_busfault, stm32_usagefault, stm32_pendsv, + * stm32_dbgmonitor, stm32_pendsv, stm32_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int stm32_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int stm32_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void stm32_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: stm32_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int stm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= STM32_IRQ_FIRST) + { + if (irq < STM32_IRQ_FIRST + 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - STM32_IRQ_FIRST); + } + else if (irq < STM32_IRQ_FIRST + 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - STM32_IRQ_FIRST - 32); + } + else if (irq < NR_IRQS) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - STM32_IRQ_FIRST - 64); + } + else + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == STM32_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == STM32_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == STM32_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == STM32_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); + putreg32(0, NVIC_IRQ32_63_ENABLE); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* The standard location for the vector table is at the beginning of FLASH + * at address 0x0800:0000. If we are using the STMicro DFU bootloader, then + * the vector table will be offset to a different location in FLASH and we + * will need to set the NVIC vector location to this alternative location. + */ + +#if defined(__ICCARM__) + putreg32((uint32_t)__vector_table, NVIC_VECTAB); +#else + putreg32((uint32_t)_vectors, NVIC_VECTAB); +#endif + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(STM32_IRQ_SVCALL, up_svcall); + irq_attach(STM32_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, up_memfault); + up_enable_irq(STM32_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(STM32_IRQ_NMI, stm32_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault); + irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault); + irq_attach(STM32_IRQ_PENDSV, stm32_pendsv); + irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor); + irq_attach(STM32_IRQ_RESERVED, stm32_reserved); +#endif + + stm32_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + // stm32_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + // stm32_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < STM32_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= STM32_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + stm32_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/stm32/stm32_iwdg.c b/arch/arm/src/stm32/stm32_iwdg.c new file mode 100644 index 0000000000000000000000000000000000000000..80d45be7292a4a8e9c111f6dd5ac49da2f786690 --- /dev/null +++ b/arch/arm/src/stm32/stm32_iwdg.c @@ -0,0 +1,721 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_iwdg.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "stm32_rcc.h" +#include "chip/stm32_dbgmcu.h" +#include "stm32_wdg.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_STM32_IWDG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Clocking *****************************************************************/ +/* The minimum frequency of the IWDG clock is: + * + * Fmin = Flsi / 256 + * + * So the maximum delay (in milliseconds) is then: + * + * 1000 * IWDG_RLR_MAX / Fmin + * + * For example, if Flsi = 30Khz (the nominal, uncalibrated value), then the + * maximum delay is: + * + * Fmin = 117.1875 + * 1000 * 4095 / Fmin = 34,944 MSec + */ + +#define IWDG_FMIN (STM32_LSI_FREQUENCY / 256) +#define IWDG_MAXTIMEOUT (1000 * IWDG_RLR_MAX / IWDG_FMIN) + +/* Configuration ************************************************************/ + +#ifndef CONFIG_STM32_IWDG_DEFTIMOUT +# define CONFIG_STM32_IWDG_DEFTIMOUT IWDG_MAXTIMEOUT +#endif + +/* REVISIT: It appears that you can only setup the prescaler and reload + * registers once. After that, the SR register's PVU and RVU bits never go + * to zero. So we defer setting up these registers until the watchdog + * is started, then refuse any further attempts to change timeout. + */ + +#define CONFIG_STM32_IWDG_ONETIMESETUP 1 + +/* REVISIT: Another possibility is that we CAN change the prescaler and + * reload values after starting the timer. This option is untested but the + * implementation place conditioned on the following: + */ + +#undef CONFIG_STM32_IWDG_DEFERREDSETUP + +/* But you can only try one at a time */ + +#if defined(CONFIG_STM32_IWDG_ONETIMESETUP) && defined(CONFIG_STM32_IWDG_DEFERREDSETUP) +# error "Both CONFIG_STM32_IWDG_ONETIMESETUP and CONFIG_STM32_IWDG_DEFERREDSETUP are defined" +#endif + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct stm32_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ + uint32_t lsifreq; /* The calibrated frequency of the LSI oscillator */ + uint32_t timeout; /* The (actual) selected timeout */ + uint32_t lastreset; /* The last reset time */ + bool started; /* true: The watchdog timer has been started */ + uint8_t prescaler; /* Clock prescaler value */ + uint16_t reload; /* Timer reload value */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_STM32_IWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint16_t val, uint32_t addr); +#else +# define stm32_getreg(addr) getreg16(addr) +# define stm32_putreg(val,addr) putreg16(val,addr) +#endif + +static inline void stm32_setprescaler(FAR struct stm32_lowerhalf_s *priv); + +/* "Lower half" driver methods **********************************************/ + +static int stm32_start(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_stop(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int stm32_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = stm32_start, + .stop = stm32_stop, + .keepalive = stm32_keepalive, + .getstatus = stm32_getstatus, + .settimeout = stm32_settimeout, + .capture = NULL, + .ioctl = NULL, +}; + +/* "Lower half" driver state */ + +static struct stm32_lowerhalf_s g_wdgdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 IWDG register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_IWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint16_t preval = 0; + + /* Read the value from the register */ + + uint16_t val = getreg16(addr); + + /* Is this the same value that we read from the same register last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%04x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_IWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint16_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%04x\n", addr, val); + + /* Write the value */ + + putreg16(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_setprescaler + * + * Description: + * Set up the prescaler and reload values. This seems to be something + * that can only be done one time. + * + * Input Parameters: + * priv - A pointer the internal representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in milliseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline void stm32_setprescaler(FAR struct stm32_lowerhalf_s *priv) +{ + /* Enable write access to IWDG_PR and IWDG_RLR registers */ + + stm32_putreg(IWDG_KR_KEY_ENABLE, STM32_IWDG_KR); + + /* Wait for the PVU and RVU bits to be reset be hardware. These bits + * were set the last time that the PR register was written and may not + * yet be cleared. + * + * If the setup is only permitted one time, then this wait should not + * be necessary. + */ + +#ifndef CONFIG_STM32_IWDG_ONETIMESETUP + while ((stm32_getreg(STM32_IWDG_SR) & (IWDG_SR_PVU | IWDG_SR_RVU)) != 0); +#endif + + /* Set the prescaler */ + + stm32_putreg((uint16_t)priv->prescaler << IWDG_PR_SHIFT, STM32_IWDG_PR); + + /* Set the reload value */ + + stm32_putreg((uint16_t)priv->reload, STM32_IWDG_RLR); + + /* Reload the counter (and disable write access) */ + + stm32_putreg(IWDG_KR_KEY_RELOAD, STM32_IWDG_KR); +} + +/**************************************************************************** + * Name: stm32_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + irqstate_t flags; + + wdvdbg("Entry: started=%d\n"); + DEBUGASSERT(priv); + + /* Have we already been started? */ + + if (!priv->started) + { + /* REVISIT: It appears that you can only setup the prescaler and reload + * registers once. After that, the SR register's PVU and RVU bits never go + * to zero. So we defer setting up these registers until the watchdog + * is started, then refuse any further attempts to change timeout. + */ + + /* Set up prescaler and reload value for the selected timeout before + * starting the watchdog timer. + */ + +#if defined(CONFIG_STM32_IWDG_ONETIMESETUP) || defined(CONFIG_STM32_IWDG_DEFERREDSETUP) + stm32_setprescaler(priv); +#endif + + /* Enable IWDG (the LSI oscillator will be enabled by hardware). NOTE: + * If the "Hardware watchdog" feature is enabled through the device option + * bits, the watchdog is automatically enabled at power-on. + */ + + flags = enter_critical_section(); + stm32_putreg(IWDG_KR_KEY_START, STM32_IWDG_KR); + priv->lastreset = clock_systimer(); + priv->started = true; + leave_critical_section(flags); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* There is no way to disable the IDWG timer once it has been started */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: stm32_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the watchdog timer or "petting the dog". + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + irqstate_t flags; + + wdvdbg("Entry\n"); + + /* Reload the IWDG timer */ + + flags = enter_critical_section(); + stm32_putreg(IWDG_KR_KEY_RELOAD, STM32_IWDG_KR); + priv->lastreset = clock_systimer(); + leave_critical_section(flags); + + return OK; +} + +/**************************************************************************** + * Name: stm32_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint32_t ticks; + uint32_t elapsed; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + + /* Return the actual timeout in milliseconds */ + + status->timeout = priv->timeout; + + /* Get the elapsed time since the last ping */ + + ticks = clock_systimer() - priv->lastreset; + elapsed = (int32_t)TICK2MSEC(ticks); + + if (elapsed > priv->timeout) + { + elapsed = priv->timeout; + } + + /* Return the approximate time until the watchdog timer expiration */ + + status->timeleft = priv->timeout - elapsed; + + wdvdbg("Status :\n"); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: stm32_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in milliseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint32_t fiwdg; + uint64_t reload; + int prescaler; + int shift; + + wdvdbg("Entry: timeout=%d\n", timeout); + DEBUGASSERT(priv); + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > IWDG_MAXTIMEOUT) + { + wddbg("Cannot represent timeout=%d > %d\n", + timeout, IWDG_MAXTIMEOUT); + return -ERANGE; + } + + /* REVISIT: It appears that you can only setup the prescaler and reload + * registers once. After that, the SR register's PVU and RVU bits never go + * to zero. + */ + +#ifdef CONFIG_STM32_IWDG_ONETIMESETUP + if (priv->started) + { + wddbg("Timer is already started\n"); + return -EBUSY; + } +#endif + + /* Select the smallest prescaler that will result in a reload value that is + * less than the maximum. + */ + + for (prescaler = 0; ; prescaler++) + { + /* PR = 0 -> Divider = 4 = 1 << 2 + * PR = 1 -> Divider = 8 = 1 << 3 + * PR = 2 -> Divider = 16 = 1 << 4 + * PR = 3 -> Divider = 32 = 1 << 5 + * PR = 4 -> Divider = 64 = 1 << 6 + * PR = 5 -> Divider = 128 = 1 << 7 + * PR = 6 -> Divider = 256 = 1 << 8 + * PR = n -> Divider = 1 << (n+2) + */ + + shift = prescaler + 2; + + /* Get the IWDG counter frequency in Hz. For a nominal 32Khz LSI clock, + * this is value in the range of 7500 and 125. + */ + + fiwdg = priv->lsifreq >> shift; + + /* We want: + * 1000 * reload / Fiwdg = timeout + * Or: + * reload = Fiwdg * timeout / 1000 + */ + + reload = (uint64_t)fiwdg * (uint64_t)timeout / 1000; + + /* If this reload valid is less than the maximum or we are not ready + * at the prescaler value, then break out of the loop to use these + * settings. + */ + + if (reload <= IWDG_RLR_MAX || prescaler == 6) + { + /* Note that we explicitly break out of the loop rather than using + * the 'for' loop termination logic because we do not want the + * value of prescaler to be incremented. + */ + + break; + } + } + + /* Make sure that the final reload value is within range */ + + if (reload > IWDG_RLR_MAX) + { + reload = IWDG_RLR_MAX; + } + + /* Get the actual timeout value in milliseconds. + * + * We have: + * reload = Fiwdg * timeout / 1000 + * So we want: + * timeout = 1000 * reload / Fiwdg + */ + + priv->timeout = (1000 * (uint32_t)reload) / fiwdg; + + /* Save setup values for later use */ + + priv->prescaler = prescaler; + priv->reload = reload; + + /* Write the prescaler and reload values to the IWDG registers. + * + * REVISIT: It appears that you can only setup the prescaler and reload + * registers once. After that, the SR register's PVU and RVU bits never go + * to zero. + */ + +#ifndef CONFIG_STM32_IWDG_ONETIMESETUP + /* If CONFIG_STM32_IWDG_DEFERREDSETUP is selected, then perform the register + * configuration only if the timer has been started. + */ + +#ifdef CONFIG_STM32_IWDG_DEFERREDSETUP + if (priv->started) +#endif + { + stm32_setprescaler(priv); + } +#endif + + wdvdbg("prescaler=%d fiwdg=%d reload=%d\n", prescaler, fiwdg, reload); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_iwdginitialize + * + * Description: + * Initialize the IWDG watchdog time. The watchdog timer is initialized and + * registers as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * lsifreq - The calibrated LSI clock frequency + * + * Returned Values: + * None + * + ****************************************************************************/ + +void stm32_iwdginitialize(FAR const char *devpath, uint32_t lsifreq) +{ + FAR struct stm32_lowerhalf_s *priv = &g_wdgdev; + + wdvdbg("Entry: devpath=%s lsifreq=%d\n", devpath, lsifreq); + + /* NOTE we assume that clocking to the IWDG has already been provided by + * the RCC initialization logic. + */ + + /* Initialize the driver state structure. */ + + priv->ops = &g_wdgops; + priv->lsifreq = lsifreq; + priv->started = false; + + /* Make sure that the LSI oscillator is enabled. NOTE: The LSI oscillator + * is enabled here but is not disabled by this file (because this file does + * not know the global usage of the oscillator. Any clock management + * logic (say, as part of a power management scheme) needs handle other + * LSI controls outside of this file. + */ + + stm32_rcc_enablelsi(); + wdvdbg("RCC CSR: %08x\n", getreg32(STM32_RCC_CSR)); + + /* Select an arbitrary initial timeout value. But don't start the watchdog + * yet. NOTE: If the "Hardware watchdog" feature is enabled through the + * device option bits, the watchdog is automatically enabled at power-on. + */ + + stm32_settimeout((FAR struct watchdog_lowerhalf_s *)priv, CONFIG_STM32_IWDG_DEFTIMOUT); + + /* Register the watchdog driver as /dev/watchdog0 */ + + (void)watchdog_register(devpath, (FAR struct watchdog_lowerhalf_s *)priv); + + /* When the microcontroller enters debug mode (Cortex™-M4F core halted), + * the IWDG counter either continues to work normally or stops, depending + * on DBG_WIDG_STOP configuration bit in DBG module. + */ + +#if defined(CONFIG_STM32_JTAG_FULL_ENABLE) || \ + defined(CONFIG_STM32_JTAG_NOJNTRST_ENABLE) || \ + defined(CONFIG_STM32_JTAG_SW_ENABLE) + { +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + uint32_t cr = getreg32(STM32_DBGMCU_APB1_FZ); + cr |= DBGMCU_APB1_IWDGSTOP; + putreg32(cr, STM32_DBGMCU_APB1_FZ); +#else /* if defined(CONFIG_STM32_STM32F10XX) */ + uint32_t cr = getreg32(STM32_DBGMCU_CR); + cr |= DBGMCU_CR_IWDGSTOP; + putreg32(cr, STM32_DBGMCU_CR); +#endif + } +#endif +} + +#endif /* CONFIG_WATCHDOG && CONFIG_STM32_IWDG */ diff --git a/arch/arm/src/stm32/stm32_lowputc.c b/arch/arm/src/stm32/stm32_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..4307c45748e971a34502b8afd131911dbb592d5f --- /dev/null +++ b/arch/arm/src/stm32/stm32_lowputc.c @@ -0,0 +1,646 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_lowputc.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "stm32.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART1_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR +# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32_CONSOLE_TX GPIO_USART1_TX +# define STM32_CONSOLE_RX GPIO_USART1_RX +# ifdef CONFIG_USART1_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_USART2EN +# define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART2_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART2_2STOP +# define STM32_CONSOLE_TX GPIO_USART2_TX +# define STM32_CONSOLE_RX GPIO_USART2_RX +# ifdef CONFIG_USART2_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART3_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_USART3EN +# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32_CONSOLE_TX GPIO_USART3_TX +# define STM32_CONSOLE_RX GPIO_USART3_RX +# ifdef CONFIG_USART3_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART4_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART4EN +# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32_CONSOLE_TX GPIO_UART4_TX +# define STM32_CONSOLE_RX GPIO_UART4_RX +# ifdef CONFIG_UART4_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART5_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART5EN +# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32_CONSOLE_TX GPIO_UART5_TX +# define STM32_CONSOLE_RX GPIO_UART5_RX +# ifdef CONFIG_UART5_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART6_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART6_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR +# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART6EN +# define STM32_CONSOLE_BAUD CONFIG_USART6_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART6_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART6_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART6_2STOP +# define STM32_CONSOLE_TX GPIO_USART6_TX +# define STM32_CONSOLE_RX GPIO_USART6_RX +# ifdef CONFIG_USART6_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART6_RS485_DIR +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART7_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART7EN +# define STM32_CONSOLE_BAUD CONFIG_UART7_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART7_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART7_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART7_2STOP +# define STM32_CONSOLE_TX GPIO_UART7_TX +# define STM32_CONSOLE_RX GPIO_UART7_RX +# ifdef CONFIG_UART7_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART7_RS485_DIR +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART8_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART8_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART8EN +# define STM32_CONSOLE_BAUD CONFIG_UART8_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART8_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART8_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART8_2STOP +# define STM32_CONSOLE_TX GPIO_UART8_TX +# define STM32_CONSOLE_RX GPIO_UART8_RX +# ifdef CONFIG_UART8_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART8_RS485_DIR +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# endif + + /* CR1 settings */ + +# if STM32_CONSOLE_BITS == 9 +# define USART_CR1_M_VALUE USART_CR1_M +# else +# define USART_CR1_M_VALUE 0 +# endif + +# if STM32_CONSOLE_PARITY == 1 +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32_CONSOLE_PARITY == 2 +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +# else +# define USART_CR1_PARITY_VALUE 0 +# endif + +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define USART_CR1_CLRBITS\ + (USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ + USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M | USART_CR1_MME | \ + USART_CR1_OVER8 | USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK | \ + USART_CR1_ALLINTS) +# else +# define USART_CR1_CLRBITS\ + (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE | USART_CR1_ALLINTS) +# endif + +# define USART_CR1_SETBITS (USART_CR1_M_VALUE|USART_CR1_PARITY_VALUE) + + /* CR2 settings */ + +# if STM32_CONSOLE_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +# else +# define USART_CR2_STOP2_VALUE 0 +# endif + +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define USART_CR2_CLRBITS \ + (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ + USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ + USART_CR2_LINEN | USART_CR2_RXINV | USART_CR2_TXINV | USART_CR2_DATAINV | \ + USART_CR2_MSBFIRST | USART_CR2_ABREN | USART_CR2_ABRMOD_MASK | \ + USART_CR2_RTOEN | USART_CR2_ADD8_MASK) +# else +# define USART_CR2_CLRBITS \ + (USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | USART_CR2_CPHA | \ + USART_CR2_LBCL | USART_CR2_LBDIE) +# endif +# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + + /* CR3 settings */ + +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) + +# define USART_CR3_CLRBITS \ + (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ + USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ + USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR1_ONEBIT | \ + USART_CR1_OVRDIS | USART_CR1_DDRE | USART_CR1_DEM | USART_CR1_DEP | \ + USART_CR1_SCARCNT_MASK | USART_CR1_WUS_MASK | USART_CR1_WUFIE) +# else +# define USART_CR3_CLRBITS \ + (USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE) +# endif +# define USART_CR3_SETBITS 0 + + /* Only the STM32 F3 supports oversampling by 8 */ + +# undef USE_OVER8 + + /* Calculate USART BAUD rate divider */ + +# if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ + +# define STM32_USARTDIV8 \ + (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) +# define STM32_USARTDIV16 \ + ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + +# if STM32_USARTDIV8 > 100 +# define STM32_BRR_VALUE STM32_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32_BRR_VALUE \ + ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1)) +# endif + +# else /* CONFIG_STM32_STM32F30XX */ + + /* The baud rate for the receiver and transmitter (Rx and Tx) are both set + * to the same value as programmed in the Mantissa and Fraction values of + * USARTDIV. + * + * baud = fCK / (16 * usartdiv) + * usartdiv = fCK / (16 * baud) + * + * Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, + * 5 or PCLK2 for USART1). Example, fCK=72MHz baud=115200, + * usartdiv=39.0625=39 1/16th; + * + * First calculate: + * + * usartdiv32 = 32 * usartdiv = fCK / (baud/2) + * + * (NOTE: all standard baud values are even so dividing by two does not + * lose precision). Eg. (same fCK and buad), usartdiv32 = 1250 + */ + +# define STM32_USARTDIV32 (STM32_APBCLOCK / (STM32_CONSOLE_BAUD >> 1)) + + /* The mantissa is then usartdiv32 / 32: + * + * mantissa = usartdiv32 / 32/ + * + * Eg. usartdiv32=1250, mantissa = 39 + */ + +# define STM32_MANTISSA (STM32_USARTDIV32 >> 5) + + /* And the fraction: + * + * fraction = (usartdiv32 - mantissa*32 + 1) / 2 + * + * Eg., (1,250 - 39*32 + 1)/2 = 1 (or 0.0625) + */ + +# define STM32_FRACTION \ + ((STM32_USARTDIV32 - (STM32_MANTISSA << 5) + 1) >> 1) + + /* And, finally, the BRR value is: */ + +# define STM32_BRR_VALUE \ + ((STM32_MANTISSA << USART_BRR_MANT_SHIFT) | \ + (STM32_FRACTION << USART_BRR_FRAC_SHIFT)) + +# endif /* CONFIG_STM32_STM32F30XX */ +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + /* Wait until the TX data register is empty */ + + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) & USART_SR_TXE) == 0); +#ifdef STM32_CONSOLE_RS485_DIR + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Then send the character */ + + putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_TDR_OFFSET); + +#ifdef STM32_CONSOLE_RS485_DIR + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) & USART_SR_TC) == 0); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: stm32_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_STM32F10XX) + +void stm32_lowsetup(void) +{ +#if defined(HAVE_UART) + uint32_t mapr; +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + + /* Set up the pin mapping registers for the selected U[S]ARTs. + * + * NOTE: Clocking for selected U[S]ARTs was already provided in stm32_rcc.c + */ + + mapr = getreg32(STM32_AFIO_MAPR); + +#ifdef CONFIG_STM32_USART1 + /* Assume default pin mapping: + * + * Alternate USART1_REMAP USART1_REMAP + * Function = 0 = 1 + * ---------- ------------ ------------ + * USART1_TX PA9 PB6 + * USART1_RX PA10 PB7 + */ + +#ifdef CONFIG_STM32_USART1_REMAP + mapr |= AFIO_MAPR_USART1_REMAP; +#else + mapr &= ~AFIO_MAPR_USART1_REMAP; +#endif +#endif /* CONFIG_STM32_USART1 */ + +#ifdef CONFIG_STM32_USART2 + /* Assume default pin mapping: + * + * Alternate USART2_REMAP USART2_REMAP + * Function = 0 = 1 + * ---------- ------------ ------------ + * USART2_CTS PA0 PD3 + * USART2_RTS PA1 PD4 + * USART2_TX PA2 PD5 + * USART2_RX PA3 PD6 + * USART3_CK PA4 PD7 + */ + +#ifdef CONFIG_STM32_USART2_REMAP + mapr |= AFIO_MAPR_USART2_REMAP; +#else + mapr &= ~AFIO_MAPR_USART2_REMAP; +#endif +#endif /* CONFIG_STM32_USART2 */ + + /* Assume default pin mapping: + * + * Alternate USART3_REMAP[1:0] USART3_REMAP[1:0] USART3_REMAP[1:0] + * Function = “00†(no remap) = “01†(partial remap) = “11†(full remap) + * ---------_ ------------------ ---------------------- -------------------- + * USART3_TX PB10 PC10 PD8 + * USART3_RX PB11 PC11 PD9 + * USART3_CK PB12 PC12 PD10 + * USART3_CTS PB13 PB13 PD11 + * USART3_RTS PB14 PB14 PD12 + */ + + mapr &= ~AFIO_MAPR_USART3_REMAP_MASK; + +#ifdef CONFIG_STM32_USART3 +#if defined(CONFIG_STM32_USART3_PARTIAL_REMAP) + mapr |= AFIO_MAPR_USART3_PARTREMAP; +#elif defined(CONFIG_STM32_USART3_FULL_REMAP) + mapr |= AFIO_MAPR_USART3_FULLREMAP; +#endif +#endif /* CONFIG_STM32_USART3 */ + + putreg32(mapr, STM32_AFIO_MAPR); + + /* Configure GPIO pins needed for rx/tx. */ + +#ifdef STM32_CONSOLE_TX + stm32_configgpio(STM32_CONSOLE_TX); +#endif +#ifdef STM32_CONSOLE_RX + stm32_configgpio(STM32_CONSOLE_RX); +#endif + +#ifdef STM32_CONSOLE_RS485_DIR + stm32_configgpio(STM32_CONSOLE_RS485_DIR); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + /* Enable Rx, Tx, and the USART */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} + +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) + +void stm32_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + +#if defined(HAVE_CONSOLE) + /* Enable USART APB1/2 clock */ + + modifyreg32(STM32_CONSOLE_APBREG, 0, STM32_CONSOLE_APBEN); +#endif + + /* Enable the console USART and configure GPIO pins needed for rx/tx. + * + * NOTE: Clocking for selected U[S]ARTs was already provided in stm32_rcc.c + */ + +#ifdef STM32_CONSOLE_TX + stm32_configgpio(STM32_CONSOLE_TX); +#endif +#ifdef STM32_CONSOLE_RX + stm32_configgpio(STM32_CONSOLE_RX); +#endif + +#ifdef STM32_CONSOLE_RS485_DIR + stm32_configgpio(STM32_CONSOLE_RS485_DIR); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + /* Select oversampling by 8 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#endif + + /* Enable Rx, Tx, and the USART */ + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} + +#else +# error "Unsupported STM32 chip" +#endif diff --git a/arch/arm/src/stm32/stm32_lowputc.h b/arch/arm/src/stm32/stm32_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..2f95afbab027092dfcb1f60a9668c14933a39cc4 --- /dev/null +++ b/arch/arm/src/stm32/stm32_lowputc.h @@ -0,0 +1,80 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_lowputc.h + * + * Copyright (C) 2009-2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32_STM32_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: stm32_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * of serial console. + * + ************************************************************************************/ + +void stm32_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_LOWPUTC_H */ + diff --git a/arch/arm/src/stm32/stm32_lse.c b/arch/arm/src/stm32/stm32_lse.c new file mode 100644 index 0000000000000000000000000000000000000000..18334852ba21190aa56705866d4714cf7c8beb71 --- /dev/null +++ b/arch/arm/src/stm32/stm32_lse.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_lse.c + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" + +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_waste.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) oscillator. + * + * Todo: + * Check for LSE good timeout and return with -1, + * + ****************************************************************************/ + +void stm32_rcc_enablelse(void) +{ + bool bkpenabled; + + /* The LSE is in the RTC domain and write access is denied to this domain + * after reset, you have to enable write access using DBP bit in the PWR CR + * register before to configuring the LSE. + */ + + bkpenabled = stm32_pwr_enablebkp(true); + +#if defined(CONFIG_STM32_STM32L15XX) + /* Enable the External Low-Speed (LSE) oscillator by setting the LSEON bit + * the RCC CSR register. + */ + + modifyreg32(STM32_RCC_CSR, 0, RCC_CSR_LSEON); + + /* Wait for the LSE clock to be ready */ + + while ((getreg32(STM32_RCC_CSR) & RCC_CSR_LSERDY) == 0) + { + up_waste(); + } + +#else + /* Enable the External Low-Speed (LSE) oscillator by setting the LSEON bit + * the RCC BDCR register. + */ + + modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_LSEON); + + /* Wait for the LSE clock to be ready */ + + while ((getreg16(STM32_RCC_BDCR) & RCC_BDCR_LSERDY) == 0) + { + up_waste(); + } + +#endif + + /* Disable backup domain access if it was disabled on entry */ + + if (!bkpenabled) + { + (void)stm32_pwr_enablebkp(false); + } +} diff --git a/arch/arm/src/stm32/stm32_lsi.c b/arch/arm/src/stm32/stm32_lsi.c new file mode 100644 index 0000000000000000000000000000000000000000..1518cd1496116acf93305953ccaccabafeefd9c2 --- /dev/null +++ b/arch/arm/src/stm32/stm32_lsi.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_lsi.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_enablelsi(void) +{ + /* Enable the Internal Low-Speed (LSI) RC Oscillator by setting the LSION bit + * the RCC CSR register. + */ + + modifyreg32(STM32_RCC_CSR, 0, RCC_CSR_LSION); + + /* Wait for the internal RC 40 kHz oscillator to be stable. */ + + while ((getreg32(STM32_RCC_CSR) & RCC_CSR_LSIRDY) == 0); +} + +/**************************************************************************** + * Name: stm32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_disablelsi(void) +{ + /* Enable the Internal Low-Speed (LSI) RC Oscillator by setting the LSION bit + * the RCC CSR register. + */ + + modifyreg32(STM32_RCC_CSR, RCC_CSR_LSION, 0); + + /* LSIRDY should go low after 3 LSI clock cycles */ +} diff --git a/arch/arm/src/stm32/stm32_ltdc.c b/arch/arm/src/stm32/stm32_ltdc.c new file mode 100644 index 0000000000000000000000000000000000000000..2da314a79289eea0776df382b977c3e9c18f43ee --- /dev/null +++ b/arch/arm/src/stm32/stm32_ltdc.c @@ -0,0 +1,3603 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_ltdc.c + * + * Copyright (C) 2013-2015 Ken Pettit. All rights reserved. + * Authors: Ken Pettit + * Marco Krahl + * + * References: + * STM32F429 Technical Reference Manual and Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "stm32.h" +#include "chip/stm32_ltdc.h" +#include "stm32_ltdc.h" +#include "stm32_dma2d.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register definition ******************************************************/ + +#ifndef BOARD_LTDC_WIDTH +# error BOARD_LTDC_WIDTH must be defined in the board.h header file +#endif + +#ifndef BOARD_LTDC_HEIGHT +# error BOARD_LTDC_HEIGHT must be defined in the board.h header file +#endif + +#define STM32_LTDC_HEIGHT BOARD_LTDC_HEIGHT +#define STM32_LTDC_WIDTH BOARD_LTDC_WIDTH + +/* Configure LTDC register */ + +/* LTDC_LxWHPCR register */ + +#define STM32_LTDC_LxWHPCR_WHSTPOS (BOARD_LTDC_HSYNC + BOARD_LTDC_HBP - 1) +#define STM32_LTDC_LxWHPCR_WHSPPOS (BOARD_LTDC_HSYNC + BOARD_LTDC_HBP + \ + STM32_LTDC_WIDTH - 1) + +/* LTDC_LxWVPCR register */ + +#define STM32_LTDC_LxWVPCR_WVSTPOS (BOARD_LTDC_VSYNC + BOARD_LTDC_VBP - 1) +#define STM32_LTDC_LxWVPCR_WVSPPOS (BOARD_LTDC_VSYNC + BOARD_LTDC_VBP + \ + STM32_LTDC_HEIGHT - 1) + +/* LTDC_SSCR register */ + +#define STM32_LTDC_SSCR_VSH LTDC_SSCR_VSH(BOARD_LTDC_VSYNC - 1) +#define STM32_LTDC_SSCR_HSW LTDC_SSCR_HSW(BOARD_LTDC_HSYNC - 1) + +/* LTDC_BPCR register */ + +#define STM32_LTDC_BPCR_AVBP LTDC_BPCR_AVBP(STM32_LTDC_LxWVPCR_WVSTPOS) +#define STM32_LTDC_BPCR_AHBP LTDC_BPCR_AHBP(STM32_LTDC_LxWHPCR_WHSTPOS) + +/* LTDC_AWCR register */ + +#define STM32_LTDC_AWCR_AAH LTDC_AWCR_AAH(STM32_LTDC_LxWVPCR_WVSPPOS) +#define STM32_LTDC_AWCR_AAW LTDC_AWCR_AAW(STM32_LTDC_LxWHPCR_WHSPPOS) + +/* LTDC_TWCR register */ + +#define STM32_LTDC_TWCR_TOTALH LTDC_TWCR_TOTALH(BOARD_LTDC_VSYNC + \ + BOARD_LTDC_VBP + \ + STM32_LTDC_HEIGHT + BOARD_LTDC_VFP - 1) +#define STM32_LTDC_TWCR_TOTALW LTDC_TWCR_TOTALW(BOARD_LTDC_HSYNC + \ + BOARD_LTDC_HBP + \ + STM32_LTDC_WIDTH + BOARD_LTDC_HFP - 1) + +/* Global GCR register */ + +/* Synchronisation and Polarity */ + +#define STM32_LTDC_GCR_PCPOL BOARD_LTDC_GCR_PCPOL +#define STM32_LTDC_GCR_DEPOL BOARD_LTDC_GCR_DEPOL +#define STM32_LTDC_GCR_VSPOL BOARD_LTDC_GCR_VSPOL +#define STM32_LTDC_GCR_HSPOL BOARD_LTDC_GCR_HSPOL + +/* Dither */ + +#define STM32_LTDC_GCR_DEN BOARD_LTDC_GCR_DEN +#define STM32_LTDC_GCR_DBW LTDC_GCR_GBW(BOARD_LTDC_GCR_DBW) +#define STM32_LTDC_GCR_DGW LTDC_GCR_DGW(BOARD_LTDC_GCR_DGW) +#define STN32_LTDC_GCR_DRW LTDC_GCR_DBW(BOARD_LTDC_GCR_DRW) + +/* LIPCR register */ + +#define STM32_LTDC_LIPCR_LIPOS LTDC_LIPCR_LIPOS(STM32_LTDC_TWCR_TOTALW) + +/* Configuration ************************************************************/ + +#ifndef CONFIG_STM32_LTDC_DEFBACKLIGHT +# define CONFIG_STM32_LTDC_DEFBACKLIGHT 0xf0 +#endif +#define STM32_LTDC_BACKLIGHT_OFF 0x00 + +/* Color/video formats */ + +/* Layer 1 format */ + +#if defined(CONFIG_STM32_LTDC_L1_L8) +# define STM32_LTDC_L1_BPP 8 +# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB8 +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_L8) +# define STM32_LTDC_L1CMAP +#elif defined(CONFIG_STM32_LTDC_L1_AL44) +# define STM32_LTDC_L1_BPP 8 +# define STM32_LTDC_L1_COLOR_FMT ??? +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL44) +#elif defined(CONFIG_STM32_LTDC_L1_AL88) +# define STM32_LTDC_L1_BPP 16 +# define STM32_LTDC_L1_COLOR_FMT ??? +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL88) +#elif defined(CONFIG_STM32_LTDC_L1_ARGB4444) +# define STM32_LTDC_L1_BPP 16 +# define STM32_LTDC_L1_COLOR_FMT ??? +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB4444) +#elif defined(CONFIG_STM32_LTDC_L1_RGB565) +# define STM32_LTDC_L1_BPP 16 +# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB16_565 +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB565) +#elif defined(CONFIG_STM32_LTDC_L1_ARGB1555) +# define STM32_LTDC_L1_BPP 16 +# define STM32_LTDC_L1_COLOR_FMT ??? +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB1555) +#elif defined(CONFIG_STM32_LTDC_L1_RGB888) +# define STM32_LTDC_L1_BPP 24 +# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB24 +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB888) +#elif defined(CONFIG_STM32_LTDC_L1_ARGB8888) +# define STM32_LTDC_L1_BPP 32 +# define STM32_LTDC_L1_COLOR_FMT ??? +# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB8888) +#endif + +/* Layer 2 format */ + +#if defined(CONFIG_STM32_LTDC_L2_L8) +# define STM32_LTDC_L2_BPP 8 +# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB8 +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_L8) +# define STM32_LTDC_L2CMAP +#elif defined(CONFIG_STM32_LTDC_L2_AL44) +# define STM32_LTDC_L2_BPP 8 +# define STM32_LTDC_L2_COLOR_FMT ??? +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL44) +#elif defined(CONFIG_STM32_LTDC_L2_AL88) +# define STM32_LTDC_L2_BPP 16 +# define STM32_LTDC_L2_COLOR_FMT ??? +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL88) +#elif defined(CONFIG_STM32_LTDC_L2_ARGB4444) +# define STM32_LTDC_L2_BPP 16 +# define STM32_LTDC_L2_COLOR_FMT ??? +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB4444) +#elif defined(CONFIG_STM32_LTDC_L2_RGB565) +# define STM32_LTDC_L2_BPP 16 +# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB16_565 +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB565) +#elif defined(CONFIG_STM32_LTDC_L2_ARGB1555) +# define STM32_LTDC_L2_BPP 16 +# define STM32_LTDC_L2_COLOR_FMT ??? +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB1555) +#elif defined(CONFIG_STM32_LTDC_L2_RGB888) +# define STM32_LTDC_L2_BPP 24 +# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB24 +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB888) +#elif defined(CONFIG_STM32_LTDC_L2_ARGB8888) +# define STM32_LTDC_L2_BPP 32 +# define STM32_LTDC_L2_COLOR_FMT ??? +# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB8888) +#endif + +/* Framebuffer sizes in bytes */ + +#if STM32_LTDC_L1_BPP == 8 +# define STM32_L1_STRIDE (STM32_LTDC_WIDTH) +#elif STM32_LTDC_L1_BPP == 16 +# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 16 + 7) / 8) +#elif STM32_LTDC_L1_BPP == 24 +# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 24 + 7) / 8) +#elif STM32_LTDC_L1_BPP == 32 +# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 32 + 7) / 8) +#else +# error Undefined or unrecognized base resolution +#endif + +/* LTDC only supports 8 bit per pixel overal */ + +#define STM32_LTDC_Lx_BYPP(n) ((n) / 8) + +#define STM32_L1_FBSIZE (STM32_L1_STRIDE * STM32_LTDC_HEIGHT) + +#ifdef CONFIG_STM32_LTDC_L2 +# ifndef CONFIG_STM32_LTDC_L2_WIDTH +# define CONFIG_STM32_LTDC_L2_WIDTH STM32_LTDC_WIDTH +# endif + +# if CONFIG_STM32_LTDC_L2_WIDTH > STM32_LTDC_WIDTH +# error Width of Layer 2 exceeds the width of the display +# endif + +# ifndef CONFIG_STM32_LTDC_L2_HEIGHT +# define CONFIG_STM32_LTDC_L2_HEIGHT STM32_LTDC_HEIGHT +# endif + +# if CONFIG_STM32_LTDC_L2_HEIGHT > STM32_LTDC_HEIGHT +# error Height of Layer 2 exceeds the height of the display +# endif + +# if STM32_LTDC_L2_BPP == 8 +# define STM32_L2_STRIDE (CONFIG_STM32_LTDC_L2_WIDTH) +# elif STM32_LTDC_L2_BPP == 16 +# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 16 + 7) / 8) +# elif STM32_LTDC_L2_BPP == 24 +# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 24 + 7) / 8) +# elif STM32_LTDC_L2_BPP == 32 +# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 32 + 7) / 8) +# else +# error Undefined or unrecognized base resolution +# endif + +# define STM32_L2_FBSIZE (STM32_L2_STRIDE * CONFIG_STM32_LTDC_L2_HEIGHT) + +#else +# define STM32_L2_FBSIZE (0) +#endif + +/* Total memory used for framebuffers */ + +#define STM32_TOTAL_FBSIZE (STM32_L1_FBSIZE + STM32_L2_FBSIZE) + +/* Debug option */ + +#ifdef CONFIG_STM32_LTDC_REGDEBUG +# define regdbg dbg +# define regvdbg vdbg +#else +# define regdbg(x...) +# define regvdbg(x...) +#endif + +/* Preallocated LTDC framebuffers */ + +/* Position the framebuffer memory in the center of the memory set aside. We + * will use any skirts before or after the framebuffer memory as a guard against + * wild framebuffer writes. + */ + +#define STM32_LTDC_BUFFER_SIZE CONFIG_STM32_LTDC_FB_SIZE +#define STM32_LTDC_BUFFER_FREE (STM32_LTDC_BUFFER_SIZE - STM32_TOTAL_FBSIZE) +#define STM32_LTDC_BUFFER_START (CONFIG_STM32_LTDC_FB_BASE + \ + STM32_LTDC_BUFFER_FREE/2) + +#if STM32_LTDC_BUFFER_FREE < 0 +# error "STM32_LTDC_BUFFER_SIZE not large enough for frame buffers" +#endif + +/* Layer frame buffer */ + +#define STM32_LTDC_BUFFER_L1 STM32_LTDC_BUFFER_START +#define STM32_LTDC_ENDBUF_L1 (STM32_LTDC_BUFFER_L1 + STM32_L1_FBSIZE) + +#ifdef CONFIG_STM32_LTDC_L2 +# define STM32_LTDC_BUFFER_L2 STM32_LTDC_ENDBUF_L1 +# define STM32_LTDC_ENDBUF_L2 (STM32_LTDC_BUFFER_L2 + STM32_L2_FBSIZE) +#else +# define STM32_LTDC_ENDBUF_L2 STM32_LTDC_ENDBUF_L1 +#endif + +/* Layer helpers */ + +#ifdef CONFIG_STM32_LTDC_L2 +# define LTDC_NLAYERS 2 +#else +# define LTDC_NLAYERS 1 +#endif + +#define LAYER(i) g_ltdc.layer[i] +#define LAYER_L1 g_ltdc.layer[LTDC_LAYER_L1] +#define LAYER_L2 g_ltdc.layer[LTDC_LAYER_L2] + +/* Dithering */ + +#ifndef CONFIG_STM32_LTDC_DITHER_RED +# define STM32_LTDC_DITHER_RED 0 +#else +# define STM32_LTDC_DITHER_RED CONFIG_STM32_LTDC_DITHER_RED +#endif +#ifndef CONFIG_STM32_LTDC_DITHER_GREEN +# define STM32_LTDC_DITHER_GREEN 0 +#else +# define STM32_LTDC_DITHER_GREEN CONFIG_STM32_LTDC_DITHER_GREEN +#endif +#ifndef CONFIG_STM32_LTDC_DITHER_BLUE +# define STM32_LTDC_DITHER_BLUE 0 +#else +# define STM32_LTDC_DITHER_BLUE CONFIG_STM32_LTDC_DITHER_BLUE +#endif + +/* Background color */ + +#ifndef CONFIG_STM32_LTDC_BACKCOLOR +# define STM32_LTDC_BACKCOLOR 0 +#else +# define STM32_LTDC_BACKCOLOR CONFIG_STM32_LTDC_BACKCOLOR +#endif + +/* Internal operation flags */ + +#define LTDC_LAYER_SETAREA (1 << 0) /* Change visible area */ +#define LTDC_LAYER_SETALPHAVALUE (1 << 1) /* Change constant alpha value */ +#define LTDC_LAYER_SETBLENDMODE (1 << 2) /* Change blendmode */ +#define LTDC_LAYER_SETCOLORKEY (1 << 3) /* Change color key */ +#define LTDC_LAYER_ENABLECOLORKEY (1 << 4) /* Enable colorkey */ +#define LTDC_LAYER_SETCOLOR (1 << 5) /* Change default color */ +#define LTDC_LAYER_SETENABLE (1 << 6) /* Change enabled state */ +#define LTDC_LAYER_ENABLE (1 << 7) /* Enable the layer */ + +/* Layer initializing state */ + +#define LTDC_LAYER_INIT LTDC_LAYER_SETAREA | \ + LTDC_LAYER_SETALPHAVALUE | \ + LTDC_LAYER_SETBLENDMODE | \ + LTDC_LAYER_SETCOLORKEY | \ + LTDC_LAYER_SETCOLOR | \ + LTDC_LAYER_SETENABLE | \ + LTDC_LAYER_ENABLE + +/* Blendfactor reset values for flip operation */ + +#define STM32_LTDC_BF1_RESET 6 +#define STM32_LTDC_BF2_RESET 7 + +/* Check pixel format support by DMA2D driver */ + +#ifdef CONFIG_STM32_DMA2D +# if defined(CONFIG_STM32_LTDC_L1_L8) || \ + defined(CONFIG_STM32_LTDC_L2_L8) +# if !defined(CONFIG_STM32_DMA2D_L8) +# error "DMA2D must support FB_FMT_RGB8 pixel format" +# endif +# endif +# if defined(CONFIG_STM32_LTDC_L1_RGB565) || \ + defined(CONFIG_STM32_LTDC_L2_RGB565) +# if !defined(CONFIG_STM32_DMA2D_RGB565) +# error "DMA2D must support FB_FMT_RGB16_565 pixel format" +# endif +# endif +# if defined(CONFIG_STM32_LTDC_L1_RGB888) || \ + defined(CONFIG_STM32_LTDC_L2_RGB888) +# if !defined(CONFIG_STM32_DMA2D_RGB888) +# error "DMA2D must support FB_FMT_RGB24 pixel format" +# endif +# endif +#endif + +/* Calculate the size of the layers clut table */ + +#ifdef CONFIG_FB_CMAP +# if defined(CONFIG_STM32_DMA2D) && !defined(CONFIG_STM32_DMA2D_L8) +# error "DMA2D must also support L8 CLUT pixel format if supported by LTDC" +# endif +# ifdef STM32_LTDC_L1CMAP +# ifdef CONFIG_FB_TRANSPARENCY +# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * sizeof(uint32_t) +# else +# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * 3 * sizeof(uint8_t) +# endif +# endif +# ifdef STM32_LTDC_L2CMAP +# undef STM32_LAYER_CLUT_SIZE +# ifdef CONFIG_FB_TRANSPARENCY +# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * sizeof(uint32_t) * 2 +# else +# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * 3 * sizeof(uint8_t) * 2 +# endif +# endif +#endif + +#ifndef CONFIG_FB_CMAP +# if defined(STM32_LTDC_L1CMAP) || defined(STM32_LTDC_L2CMAP) +# undef STM32_LTDC_L1CMAP +# undef STM32_LTDC_L2CMAP +# error "Enable cmap to support the configured layer format!" +# endif +#endif + +/* Layer clut rgb value positioning */ + +#define LTDC_L1CLUT_REDOFFSET 0 +#define LTDC_L1CLUT_GREENOFFSET 256 +#define LTDC_L1CLUT_BLUEOFFSET 512 +#define LTDC_L2CLUT_REDOFFSET 768 +#define LTDC_L2CLUT_GREENOFFSET 1024 +#define LTDC_L2CLUT_BLUEOFFSET 1280 + +/* Layer argb clut register position */ + +#define LTDC_CLUT_ADD(n) ((uint32_t)(n) << 24) +#define LTDC_CLUT_ALPHA(n) LTDC_CLUT_ADD(n) +#define LTDC_CLUT_RED(n) ((uint32_t)(n) << 16) +#define LTDC_CLUT_GREEN(n) ((uint32_t)(n) << 8) +#define LTDC_CLUT_BLUE(n) ((uint32_t)(n) << 0) +#define LTDC_CLUT_RGB888_MASK 0xffffff + +/* Layer argb cmap conversion */ + +#define LTDC_CMAP_ALPHA(n) ((uint32_t)(n) >> 24) +#define LTDC_CMAP_RED(n) ((uint32_t)(n) >> 16) +#define LTDC_CMAP_GREEN(n) ((uint32_t)(n) >> 8) +#define LTDC_CMAP_BLUE(n) ((uint32_t)(n) >> 0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This enumeration names each layer supported by the hardware */ + +enum stm32_layer_e +{ + LTDC_LAYER_L1 = 0, /* LCD Layer 1 */ + LTDC_LAYER_L2, /* LCD Layer 2 */ +}; + +/* LTDC General layer information */ + +struct stm32_layer_s +{ +#ifdef CONFIG_STM32_LTDC_INTERFACE + /* LTDC interface */ + + struct ltdc_layer_s ltdc; /* Layer control structure */ +#endif + + struct stm32_ltdc_s state; /* Layer state structure */ + + /* Blending */ + + uint8_t opac; /* Opacity value for blending */ + uint8_t bf1; /* Blend factor 1 */ + uint8_t bf2; /* Blend factor 2 */ + + /* Operation */ + + uint8_t operation; /* Operation flags */ +#ifdef CONFIG_STM32_DMA2D + FAR struct dma2d_layer_s *dma2d; /* dma2d interface */ +#endif +}; + +/* This structure provides the state of each LTDC layer */ + +struct stm32_state_s +{ + /* Layer state */ + + struct stm32_ltdc_s state[LTDC_NLAYERS]; +}; + +/* This structure provides the overall state of the LTDC layer */ + +struct stm32_ltdcdev_s +{ + /* Layer information */ + + struct stm32_layer_s layer[LTDC_NLAYERS]; +}; + +/* Layer cmap table description */ + +#ifdef STM32_LAYER_CLUT_SIZE +enum stm32_clut_e +{ + LTDC_L1CLUT_OFFSET = 0, + LTDC_L2CLUT_OFFSET = STM32_LTDC_NCLUT * sizeof(uint32_t) +}; +#endif + +/* Interrupt handling */ + +struct stm32_interrupt_s +{ + bool wait; /* Informs that the task is waiting for the irq */ + bool handled; /* Informs that an irq was handled */ + int irq; /* irq number */ + sem_t *sem; /* Semaphore for waiting for irq */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Global register operation */ + +static void stm32_lcd_enable(bool enable); +static void stm32_ltdc_gpioconfig(void); +static void stm32_ltdc_periphconfig(void); +static void stm32_ltdc_bgcolor(uint32_t rgb); +static void stm32_ltdc_dither(bool enable, uint8_t red, + uint8_t green, uint8_t blue); +static int stm32_ltdcirq(int irq, void *context); +static int stm32_ltdc_waitforirq(void); +static int stm32_ltdc_reload(uint8_t value, bool waitvblank); + +/* Layer and layer register operation */ + +static inline void stm32_ltdc_lsetopac(FAR struct stm32_layer_s *layer); +static inline void stm32_ltdc_lunsetopac(FAR struct stm32_layer_s *layer); +static inline uint8_t stm32_ltdc_lgetopac(FAR struct stm32_layer_s *layer); +static inline bool stm32_ltdc_lvalidate(FAR const struct stm32_layer_s *layer); +#ifdef CONFIG_STM32_LTDC_INTERFACE +static int stm32_ltdc_lvalidatearea(FAR struct stm32_layer_s *layer, + fb_coord_t xpos, fb_coord_t ypos, + fb_coord_t xres, fb_coord_t yres, + fb_coord_t srcxpos, fb_coord_t srcypos); +#endif +static void stm32_ltdc_lupdate(FAR struct stm32_layer_s *layer); + +static void stm32_ltdc_lpixelformat(FAR struct stm32_layer_s *layer); +static inline void stm32_ltdc_lframebuffer(FAR struct stm32_layer_s *layer); +static void stm32_ltdc_larea(FAR struct stm32_layer_s *layer); +static void stm32_ltdc_lcolor(FAR struct stm32_layer_s *layer, uint32_t argb); +static void stm32_ltdc_lcolorkey(FAR struct stm32_layer_s *layer); +static void stm32_ltdc_lalpha(FAR struct stm32_layer_s *layer); +static void stm32_ltdc_lblendmode(FAR struct stm32_layer_s *layer, + uint8_t bf1, uint8_t bf2); + +#ifdef STM32_LAYER_CLUT_SIZE +static void stm32_ltdc_lclut(FAR struct stm32_layer_s *layer, + FAR const struct fb_cmap_s *cmap); +static void stm32_ltdc_lclutenable(FAR struct stm32_layer_s *layer, + bool enable); +#endif +static void stm32_ltdc_linit(int lid); +static void stm32_ltdc_lenable(FAR struct stm32_layer_s *layer); +static void stm32_ltdc_lclear(FAR struct stm32_layer_s *layer, + nxgl_mxpixel_t color); + +/* Generic frame buffer interface */ + +static int stm32_getvideoinfo(FAR struct fb_vtable_s *vtable, + struct fb_videoinfo_s *vinfo); +static int stm32_getplaneinfo(FAR struct fb_vtable_s *vtable, + int planeno, struct fb_planeinfo_s *pinfo); + +/* The following is provided only if the video hardware supports RGB color + * mapping + */ + +#ifdef STM32_LAYER_CLUT_SIZE +static int stm32_getcmap(struct fb_vtable_s *vtable, + struct fb_cmap_s *cmap); +static int stm32_putcmap(struct fb_vtable_s *vtable, + const struct fb_cmap_s *cmap); +#endif + +/* ltdc interface */ + +#ifdef STM32_LAYER_CLUT_SIZE +static int stm32_setclut(struct ltdc_layer_s *layer, + const struct fb_cmap_s *cmap); +static int stm32_getclut(struct ltdc_layer_s *layer, + struct fb_cmap_s *cmap); +#endif +static int stm32_lgetvideoinfo(struct ltdc_layer_s *layer, + struct fb_videoinfo_s *vinfo); +static int stm32_lgetplaneinfo(struct ltdc_layer_s *layer, int planeno, + struct fb_planeinfo_s *pinfo); + +#ifdef CONFIG_STM32_LTDC_INTERFACE +static int stm32_getlid(FAR struct ltdc_layer_s *layer, + int *lid, uint32_t flag); +static int stm32_setcolor(FAR struct ltdc_layer_s *layer, uint32_t argb); +static int stm32_getcolor(FAR struct ltdc_layer_s *layer, uint32_t *argb); +static int stm32_setcolorkey(FAR struct ltdc_layer_s *layer, uint32_t argb); +static int stm32_getcolorkey(FAR struct ltdc_layer_s *layer, uint32_t *argb); +static int stm32_setalpha(FAR struct ltdc_layer_s *layer, uint8_t alpha); +static int stm32_getalpha(FAR struct ltdc_layer_s *layer, uint8_t *alpha); +static int stm32_setblendmode(FAR struct ltdc_layer_s *layer, uint32_t mode); +static int stm32_getblendmode(FAR struct ltdc_layer_s *layer, uint32_t *mode); +static int stm32_setarea(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + fb_coord_t srcxpos, fb_coord_t srcypos); +static int stm32_getarea(FAR struct ltdc_layer_s *layer, + FAR struct ltdc_area_s *area, + fb_coord_t *srcxpos, fb_coord_t *srcypos); +static int stm32_update(FAR struct ltdc_layer_s *layer, uint32_t mode); + +#ifdef CONFIG_STM32_DMA2D +static int stm32_blit(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea); +static int stm32_blend(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea); +static int stm32_fillarea(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + uint32_t color); +#endif +#endif /* CONFIG_STM32_LTDC_INTERFACE */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* PIO pin configurations */ + +static const uint32_t g_ltdcpins[] = +{ + GPIO_LTDC_R4, GPIO_LTDC_R5, GPIO_LTDC_R6, GPIO_LTDC_R7, + GPIO_LTDC_G4, GPIO_LTDC_G5, GPIO_LTDC_G6, GPIO_LTDC_G7, + GPIO_LTDC_B4, GPIO_LTDC_B5, GPIO_LTDC_B6, GPIO_LTDC_B7, +#if BOARD_LTDC_OUTPUT_BPP > 12 + GPIO_LTDC_R3, GPIO_LTDC_G2, GPIO_LTDC_G3, GPIO_LTDC_B3, +# if BOARD_LTDC_OUTPUT_BPP > 16 + GPIO_LTDC_R2, GPIO_LTDC_B2, +# if BOARD_LTDC_OUTPUT_BPP > 18 + GPIO_LTDC_R0, GPIO_LTDC_R1, GPIO_LTDC_G0, GPIO_LTDC_G1, + GPIO_LTDC_B0, GPIO_LTDC_B1, +# endif +# endif +#endif + GPIO_LTDC_VSYNC, GPIO_LTDC_HSYNC, GPIO_LTDC_DE, GPIO_LTDC_CLK +}; + +#define STM32_LTDC_NPINCONFIGS (sizeof(g_ltdcpins) / sizeof(uint32_t)) + +/* This structure provides the base layer interface */ + +static const struct fb_vtable_s g_vtable = +{ + .getvideoinfo = stm32_getvideoinfo, + .getplaneinfo = stm32_getplaneinfo +#ifdef STM32_LAYER_CLUT_SIZE + , + .getcmap = stm32_getcmap, + .putcmap = stm32_putcmap +#endif +}; + +/* The LTDC semaphore that enforces mutually exclusive access */ + +static sem_t g_lock; + +/* The semaphore for interrupt handling */ + +static sem_t g_semirq; + +/* This structure provides irq handling */ + +static struct stm32_interrupt_s g_interrupt = +{ + .wait = false, + .handled = true, + .irq = STM32_IRQ_LTDCINT, + .sem = &g_semirq +}; + +/* The layer active state */ + +static uint8_t g_lactive; + +#ifdef STM32_LAYER_CLUT_SIZE +/* The layers clut table entries */ + +static uint32_t g_clut[STM32_LAYER_CLUT_SIZE]; +#endif + +/* The initialized state of the overall LTDC layers */ + +static struct stm32_ltdcdev_s g_ltdc = +{ + .layer[LTDC_LAYER_L1] = + { + .state = + { + .lid = LTDC_LAYER_L1, + .pinfo = + { + .fbmem = (uint8_t *)STM32_LTDC_BUFFER_L1, + .fblen = STM32_L1_FBSIZE, + .stride = STM32_L1_STRIDE, + .bpp = STM32_LTDC_L1_BPP + }, + .vinfo = + { + .fmt = STM32_LTDC_L1_COLOR_FMT, + .xres = STM32_LTDC_WIDTH, + .yres = STM32_LTDC_HEIGHT, + .nplanes = 1 + } +#ifdef STM32_LTDC_L1CMAP + , .clut = &g_clut[LTDC_L1CLUT_OFFSET] +#endif + } + } +#ifdef CONFIG_STM32_LTDC_L2 + , + .layer[LTDC_LAYER_L2] = + { + .state = + { + .lid = LTDC_LAYER_L2, + .pinfo = + { + .fbmem = (uint8_t *)STM32_LTDC_BUFFER_L2, + .fblen = STM32_L2_FBSIZE, + .stride = STM32_L2_STRIDE, + .bpp = STM32_LTDC_L2_BPP + }, + .vinfo = + { + .fmt = STM32_LTDC_L2_COLOR_FMT, + .xres = STM32_LTDC_WIDTH, + .yres = STM32_LTDC_HEIGHT, + .nplanes = 1 + } +#ifdef STM32_LTDC_L2CMAP + , .clut = &g_clut[LTDC_L2CLUT_OFFSET] +#endif + } + } +#endif +}; + +/* Pixel format lookup table */ + +static const uint32_t stm32_fmt_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1PFCR_PF +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2PFCR_PF +#endif +}; + +/* Register lookup tables */ + +/* LTDC_LxCR */ + +static const uintptr_t stm32_cr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CR +#endif +}; + +/* LTDC_LxWHPCR */ + +static const uintptr_t stm32_whpcr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1WHPCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2WHPCR +#endif +}; + +/* LTDC_LxWVPCR */ + +static const uintptr_t stm32_wvpcr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1WVPCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2WVPCR +#endif +}; + +/* LTDC_LxPFCR */ + +static const uintptr_t stm32_pfcr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1PFCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2PFCR +#endif +}; + +/* LTDC_LxDCCR */ + +static const uintptr_t stm32_dccr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1DCCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2DCCR +#endif +}; + +/* LTDC_LxCKCR */ + +static const uintptr_t stm32_ckcr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CKCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CKCR +#endif +}; + +/* LTDC_LxCACR */ + +static const uintptr_t stm32_cacr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CACR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CACR +#endif +}; + +/* LTDC_LxBFCR */ + +static const uintptr_t stm32_bfcr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1BFCR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2BFCR +#endif +}; + +/* LTDC_LxCFBAR */ + +static const uintptr_t stm32_cfbar_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CFBAR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CFBAR +#endif +}; + +/* LTDC_LxCFBLR */ + +static const uintptr_t stm32_cfblr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CFBLR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CFBLR +#endif +}; + +/* LTDC_LxCFBLNR */ + +static const uintptr_t stm32_cfblnr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CFBLNR +#ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CFBLNR +#endif +}; + +/* LTDC_LxCLUTWR */ + +#ifdef STM32_LAYER_CLUT_SIZE +static const uintptr_t stm32_clutwr_layer_t[LTDC_NLAYERS] = +{ + STM32_LTDC_L1CLUTWR +# ifdef CONFIG_STM32_LTDC_L2 + , STM32_LTDC_L2CLUTWR +# endif +}; +#endif + +/* The initialized state of the driver */ + +static bool g_initialized; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Configure global register + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ltdc_gpioconfig + * + * Description: + * Configure GPIO pins for use with the LTDC + * + ****************************************************************************/ + +static void stm32_ltdc_gpioconfig(void) +{ + int i; + + gvdbg("Configuring pins\n"); + + /* Configure each pin */ + + for (i = 0; i < STM32_LTDC_NPINCONFIGS; i++) + { + regvdbg("set gpio%d = %08x\n", i, g_ltdcpins[i]); + stm32_configgpio(g_ltdcpins[i]); + } +} + +/**************************************************************************** + * Name: stm32_ltdc_periphconfig + * + * Description: + * Configures the synchronous timings + * Configures the synchronous signals and clock polarity + * + ****************************************************************************/ + +static void stm32_ltdc_periphconfig(void) +{ + uint32_t regval; + + /* Configure GPIO's */ + + stm32_ltdc_gpioconfig(); + + /* Configure APB2 LTDC clock external */ + + regvdbg("configured RCC_APB2ENR=%08x\n", getreg32(STM32_RCC_APB2ENR)); + + /* Configure the SAI PLL external to provide the LCD_CLK */ + + regvdbg("configured RCC_PLLSAI=%08x\n", getreg32(STM32_RCC_PLLSAICFGR)); + + /* Configure dedicated clock external */ + + regvdbg("configured RCC_DCKCFGR=%08x\n", getreg32(STM32_RCC_DCKCFGR)); + + /* Configure LTDC_SSCR */ + + regval = (STM32_LTDC_SSCR_VSH | STM32_LTDC_SSCR_HSW); + regvdbg("set LTDC_SSCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_SSCR); + regvdbg("configured LTDC_SSCR=%08x\n", getreg32(STM32_LTDC_SSCR)); + + /* Configure LTDC_BPCR */ + + regval = (STM32_LTDC_BPCR_AVBP | STM32_LTDC_BPCR_AHBP); + regvdbg("set LTDC_BPCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_BPCR); + regvdbg("configured LTDC_BPCR=%08x\n", getreg32(STM32_LTDC_BPCR)); + + /* Configure LTDC_AWCR */ + + regval = (STM32_LTDC_AWCR_AAH | STM32_LTDC_AWCR_AAW); + regvdbg("set LTDC_AWCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_AWCR); + regvdbg("configured LTDC_AWCR=%08x\n", getreg32(STM32_LTDC_AWCR)); + + /* Configure LTDC_TWCR */ + + regval = (STM32_LTDC_TWCR_TOTALH | STM32_LTDC_TWCR_TOTALW); + regvdbg("set LTDC_TWCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_TWCR); + regvdbg("configured LTDC_TWCR=%08x\n", getreg32(STM32_LTDC_TWCR)); + + /* Configure LTDC_GCR */ + + regval = (STM32_LTDC_GCR_PCPOL | STM32_LTDC_GCR_DEPOL + | STM32_LTDC_GCR_VSPOL | STM32_LTDC_GCR_HSPOL); + regvdbg("set LTDC_GCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_GCR); + regvdbg("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR)); +} + +/**************************************************************************** + * Name: stm32_ltdc_bgcolor + * + * Description: + * Configures background color of the LCD controller. + * + * Parameter: + * rgb - RGB888 background color + * + ****************************************************************************/ + +static void stm32_ltdc_bgcolor(uint32_t rgb) +{ + regvdbg("set LTDC_BCCR=%08x\n", rgb); + putreg32(rgb, STM32_LTDC_BCCR); + regvdbg("configured LTDC_BCCR=%08x\n", getreg32(STM32_LTDC_BCCR)); +} + +/**************************************************************************** + * Name: stm32_ltdc_dither + * + * Description: + * Configures dither settings of the LCD controller. + * + * Parameter: + * enable - Enable dithering + * red - Red dither width + * green - Green dither width + * blue - Blue dither width + * + ****************************************************************************/ + +static void stm32_ltdc_dither(bool enable, + uint8_t red, + uint8_t green, + uint8_t blue) +{ + uint32_t regval; + + regval = getreg32(STM32_LTDC_GCR); + + if (enable == true) + { + regval |= LTDC_GCR_DEN; + } + else + { + regval &= ~LTDC_GCR_DEN; + } + + regval &= ~(!LTDC_GCR_DEN | LTDC_GCR_DRW(0) | + LTDC_GCR_DGW(0) | LTDC_GCR_DBW(0)); + regval |= (LTDC_GCR_DRW(red) | LTDC_GCR_DGW(green) | LTDC_GCR_DBW(blue)); + + regvdbg("set LTDC_GCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_GCR); + regvdbg("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR)); +} + +/**************************************************************************** + * Name: stm32_ltdc_linepos + * + * Description: + * Configures line position register + * + ****************************************************************************/ + +static void stm32_ltdc_linepos(void) +{ + /* Configure LTDC_LIPCR */ + + regvdbg("set LTDC_LIPCR=%08x\n", STM32_LTDC_LIPCR_LIPOS); + putreg32(STM32_LTDC_LIPCR_LIPOS, STM32_LTDC_LIPCR); + regvdbg("configured LTDC_LIPCR=%08x\n", getreg32(STM32_LTDC_LIPCR)); +} + +/**************************************************************************** + * Name: stm32_ltdc_irqctrl + * + * Description: + * Control interrupts generated by the ltdc controller + * + * Parameter: + * setirqs - set interrupt mask + * clrirqs - clear interrupt mask + * + ****************************************************************************/ + +static void stm32_ltdc_irqctrl(uint32_t setirqs, uint32_t clrirqs) +{ + uint32_t regval; + + regval = getreg32(STM32_LTDC_IER); + regval &= ~clrirqs; + regval |= setirqs; + regvdbg("set LTDC_IER=%08x\n", regval); + putreg32(regval, STM32_LTDC_IER); + regvdbg("configured LTDC_IER=%08x\n", getreg32(STM32_LTDC_IER)); +} + +/**************************************************************************** + * Name: stm32_ltdcirq + * + * Description: + * LTDC interrupt handler + * + ****************************************************************************/ + +static int stm32_ltdcirq(int irq, void *context) +{ + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + uint32_t regval = getreg32(STM32_LTDC_ISR); + + regvdbg("irq = %d, regval = %08x\n", irq, regval); + + if (regval & LTDC_ISR_RRIF) + { + /* Register reload interrupt */ + + /* Clear the interrupt status register */ + + putreg32(LTDC_ICR_CRRIF, STM32_LTDC_ICR); + + /* Update the handled flag */ + + priv->handled = true; + + /* Unlock the semaphore if locked */ + + if (priv->wait) + { + int ret = sem_post(priv->sem); + + if (ret != OK) + { + dbg("sem_post() failed\n"); + return ret; + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ltdc_waitforirq + * + * Description: + * Helper waits until the ltdc irq occurs. In the current design That means + * that a register reload was been completed. + * Note! The caller must use this function within a critical section. + * + * Return: + * OK - On success otherwise ERROR + * + ****************************************************************************/ + +static int stm32_ltdc_waitforirq(void) +{ + int ret = OK; + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + irqstate_t flags; + + flags = enter_critical_section(); + + /* Only waits if last enabled interrupt is currently not handled */ + + if (!priv->handled) + { + /* Inform the irq handler the task is able to wait for the irq */ + + priv->wait = true; + + ret = sem_wait(priv->sem); + + /* irq or an error occurs, reset the wait flag */ + + priv->wait = false; + + if (ret != OK) + { + dbg("sem_wait() failed\n"); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_ltdc_reload + * + * Description: + * Reload the layer shadow register and make layer changes visible. + * Note! The caller must ensure that a previous register reloading has been + * completed. + * + * Parameter: + * value - Reload flag (e.g. upon vertical blank or immediately) + * waitvblank - Wait until register reload is finished + * + ****************************************************************************/ + +static int stm32_ltdc_reload(uint8_t value, bool waitvblank) +{ + int ret = OK; + FAR struct stm32_interrupt_s *priv = &g_interrupt; + + if (value == LTDC_SRCR_VBR) + { + irqstate_t flags; + + /* Prepare shadow register reload for later detection by the task. + * At this point the last register reload must be completed. This is done + * in stm32_update before the next operation is triggered and manipulates + * the shadow register. This handling is only neccessary in the case of + * the application causes shadow register reload. + */ + + flags = enter_critical_section(); + + ASSERT(priv->handled == true); + + /* Reset the handled flag */ + + priv->handled = false; + leave_critical_section(flags); + } + + /* Reloads the shadow register. + * Note! This will not trigger an register reload interrupt if + * immediately reload is set. + */ + + regvdbg("set LTDC_SRCR=%08x\n", value); + putreg32(value, STM32_LTDC_SRCR); + regvdbg("configured LTDC_SRCR=%08x\n", getreg32(STM32_LTDC_SRCR)); + + if (waitvblank & (value == LTDC_SRCR_VBR)) + { + /* Wait upon vertical blanking period */ + + ret = stm32_ltdc_waitforirq(); + } + + /* Otherwise check if reload is completed before the next operation */ + + return ret; +} + +/**************************************************************************** + * Name: stm32_global_configure + * + * Description: + * Configure background color + * Configure interrupts + * Configure dithering + * + ****************************************************************************/ + +static void stm32_global_configure(void) +{ + /* Initialize the LTDC semaphore that enforces mutually exclusive access */ + + sem_init(&g_lock, 0, 1); + + /* Initialize the semaphore for interrupt handling */ + + sem_init(g_interrupt.sem, 0, 0); + + /* Attach LTDC interrupt vector */ + + (void)irq_attach(g_interrupt.irq, stm32_ltdcirq); + + /* Enable the IRQ at the NVIC */ + + up_enable_irq(g_interrupt.irq); + + /* Enable register reload interrupt only */ + + stm32_ltdc_irqctrl(LTDC_IER_RRIE, LTDC_IER_TERRIE | LTDC_IER_FUIE | LTDC_IER_LIE); + + /* Configure line interrupt */ + + stm32_ltdc_linepos(); + + /* Set the default active layer */ + +#ifndef CONFIG_STM32_LTDC_L2 + g_lactive = LTDC_LAYER_L1; +#else + g_lactive = LTDC_LAYER_L2; +#endif + +#ifdef STM32_LAYER_CLUT_SIZE + /* cleanup clut */ + + memset(g_clut, 0, sizeof(g_clut)); +#endif + + /* Configure dither */ + + stm32_ltdc_dither( +#ifdef CONFIG_STM32_LTDC_DITHER + true, +#else + false, +#endif + STM32_LTDC_DITHER_RED, + STM32_LTDC_DITHER_GREEN, + STM32_LTDC_DITHER_BLUE); + + /* Configure background color of the controller */ + + stm32_ltdc_bgcolor(STM32_LTDC_BACKCOLOR); +} + +/**************************************************************************** + * Name: stm32_lcd_enable + * + * Description: + * Disable the LCD peripheral + * + * Parameter: + * enable - Enable or disable + * + ****************************************************************************/ + +static void stm32_lcd_enable(bool enable) +{ + uint32_t regval; + + regval = getreg32(STM32_LTDC_GCR); + regvdbg("get LTDC_GCR=%08x\n", regval); + + if (enable == true) + { + regval |= LTDC_GCR_LTDCEN; + } + else + { + regval &= ~LTDC_GCR_LTDCEN; + } + + regvdbg("set LTDC_GCR=%08x\n", regval); + putreg32(regval, STM32_LTDC_GCR); + regvdbg("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR)); +} + +/**************************************************************************** + * Configure layer register + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ltdc_lclutenable + * + * Description: + * Disable or enable the layer clut support + * + * Parameter: + * layer - Reference to the layer control structure + * enable - Enable or disable + * + ****************************************************************************/ + +#ifdef STM32_LAYER_CLUT_SIZE +static void stm32_ltdc_lclutenable(FAR struct stm32_layer_s *layer, bool enable) +{ + uint32_t regval; + + regval = getreg32(stm32_cr_layer_t[layer->state.lid]); + regvdbg("get LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval); + + /* Disable the clut support during update the color table */ + + if (enable == true) + { + regval |= LTDC_LxCR_CLUTEN; + } + else + { + regval &= ~LTDC_LxCR_CLUTEN; + } + + regvdbg("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval); + putreg32(regval, stm32_cr_layer_t[layer->state.lid]); +} +#endif + +/**************************************************************************** + * Name: stm32_ltdc_lsetopac + * + * Description: + * Helper to set the layer to opac + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static inline void stm32_ltdc_lsetopac(FAR struct stm32_layer_s *layer) +{ + layer->opac = 0xff; +} + +/**************************************************************************** + * Name: stm32_ltdc_lunsetopac + * + * Description: + * Helper to set the layer opacity to the alpha value + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static inline void stm32_ltdc_lunsetopac(FAR struct stm32_layer_s *layer) +{ + layer->opac = 0; +} + +/**************************************************************************** + * Name: stm32_ltdc_lgetopac + * + * Description: + * Helper to get the configured layer opacity + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static inline uint8_t stm32_ltdc_lgetopac(FAR struct stm32_layer_s *layer) +{ + return layer->opac | layer->state.alpha; +} + +/**************************************************************************** + * Name: stm32_ltdc_lvalidate + * + * Description: + * Helper to check if the layer is an valid ltdc layer + * + * Parameter: + * layer - Reference to the layer control structure + * + * Return: + * true - layer valid + * false - layer invalid + * + ****************************************************************************/ + +static inline bool stm32_ltdc_lvalidate(FAR const struct stm32_layer_s *layer) +{ +#ifdef CONFIG_STM32_LTDC_L2 + return layer == &LAYER_L1 || layer == &LAYER_L2; +#else + return layer == &LAYER_L1; +#endif +} + +/**************************************************************************** + * Name: stm32_ltdc_lvalidatearea + * + * Description: + * Check if layer coordinates out of valid area. + * + * Parameter: + * layer - Reference to the layer control structure + * xpos - top left x position of the active area + * ypos - top left y position of the active area + * xres - width of the active area + * yres - height of teh active area + * srcxpos - Top left x position from where data visible in the active area + * srcypos - Top left y position from where data visible in the active area + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_LTDC_INTERFACE +static int stm32_ltdc_lvalidatearea(FAR struct stm32_layer_s *layer, + fb_coord_t xpos, fb_coord_t ypos, + fb_coord_t xres, fb_coord_t yres, + fb_coord_t srcxpos, fb_coord_t srcypos) +{ + FAR const struct fb_videoinfo_s *vinfo = &layer->state.vinfo; + + if ((xpos > vinfo->xres - 1) || + (ypos > vinfo->yres -1) || + (xres > vinfo->xres - xpos) || + (yres > vinfo->yres - ypos) || + (srcxpos > xpos + xres - 1) || + (srcypos > ypos + yres - 1)) + + { + gdbg("layer coordinates out of valid area: xpos = %d > %d, \ + ypos = %d > %d, width = %d > %d, height = %d > %d, \ + srcxpos = %d > %d, srcypos = %d > %d", + xpos, vinfo->xres - 1, + ypos, vinfo->yres - 1, + xres, vinfo->xres - xpos, + yres, vinfo->yres - ypos, + srcxpos, xpos + xres - 1, + srcypos, ypos + yres - 1); + + gdbg("Returning EINVAL\n"); + return -EINVAL; + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_ltdc_lupdate + * + * Description: + * Updates shadow register content depending on the layer operation flag. + * This made changes for the given layer visible after the next shadow + * register reload. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lupdate(FAR struct stm32_layer_s *layer) +{ + if (layer->operation & LTDC_LAYER_SETAREA) + { + /* Updates the layer horizontal and vertical position register */ + + stm32_ltdc_larea(layer); + } + + if (layer->operation & LTDC_LAYER_SETALPHAVALUE) + { + /* Updates the constant alpha register */ + + stm32_ltdc_lalpha(layer); + } + + if (layer->operation & LTDC_LAYER_SETBLENDMODE) + { + /* Update blendfactor 1 and 2 register */ + + stm32_ltdc_lblendmode(layer, layer->bf1, layer->bf2); + } + + if (layer->operation & LTDC_LAYER_SETCOLORKEY) + { + /* Update layer colorkey register */ + + stm32_ltdc_lcolorkey(layer); + } + + if (layer->operation & LTDC_LAYER_SETCOLOR) + { + /* Update layer color register */ + + stm32_ltdc_lcolor(layer, layer->state.color); + } + + if (layer->operation & LTDC_LAYER_SETENABLE) + { + /* Enable the layer */ + + stm32_ltdc_lenable(layer); + } +} + +/**************************************************************************** + * Name: stm32_ltdc_larea + * + * Description: + * Change the active area of the layer + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_larea(struct stm32_layer_s *layer) +{ + uint32_t lxpos; + uint32_t lypos; + uint32_t whpcr; + uint32_t wvpcr; + FAR struct stm32_ltdc_s *priv = &layer->state; + FAR struct ltdc_area_s *area = &priv->area; + + regvdbg("xpos = %d, ypos = %d, xres = %d, yres = %d\n", + area->xpos, area->ypos, area->xres, area->yres); + + lxpos = area->xpos + (STM32_LTDC_LxWHPCR_WHSTPOS + 1); + lypos = area->ypos + (STM32_LTDC_LxWVPCR_WVSTPOS + 1); + + /* Accumulate horizontal position */ + + whpcr = LTDC_LxWHPCR_WHSTPOS(lxpos); + whpcr |= LTDC_LxWHPCR_WHSPPOS(lxpos + area->xres - 1); + + /* Accumulate vertical position */ + + wvpcr = LTDC_LxWVPCR_WVSTPOS(lypos); + wvpcr |= LTDC_LxWVPCR_WVSPPOS(lypos + area->yres - 1); + + /* Configure LxWHPCR / LxWVPCR register */ + + regvdbg("set LTDC_L%dWHPCR=%08x\n", priv->lid + 1, whpcr); + putreg32(whpcr, stm32_whpcr_layer_t[priv->lid]); + regvdbg("set LTDC_L%dWVPCR=%08x\n", priv->lid + 1, wvpcr); + putreg32(wvpcr, stm32_wvpcr_layer_t[priv->lid]); + + /* Configure framebuffer */ + + stm32_ltdc_lframebuffer(layer); + + /* Clear area operation flag */ + + layer->operation &= ~LTDC_LAYER_SETAREA; +} + +/**************************************************************************** + * Name: stm32_ltdc_lpixelformat + * + * Description: + * Set the layer pixel format. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lpixelformat(FAR struct stm32_layer_s *layer) +{ + /* Configure PFCR register */ + + regvdbg("set LTDC_L%dPFCR=%08x\n", layer->state.lid + 1, + stm32_fmt_layer_t[layer->state.lid]); + putreg32(stm32_fmt_layer_t[layer->state.lid], + stm32_pfcr_layer_t[layer->state.lid]); +} + +/**************************************************************************** + * Name: stm32_ltdc_framebuffer + * + * Description: + * Change layer framebuffer offset. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * Reference to the layer control structure + * + ****************************************************************************/ + +static inline void stm32_ltdc_lframebuffer(FAR struct stm32_layer_s *layer) +{ + uint32_t offset; + uint32_t cfblr; + FAR struct stm32_ltdc_s *priv = &layer->state; + FAR struct ltdc_area_s *area = &priv->area; + FAR const struct fb_planeinfo_s *pinfo = &priv->pinfo; + + /* Configure LxCFBAR register */ + + /* Calculate offset position in the framebuffer */ + + offset = priv->xpos * STM32_LTDC_Lx_BYPP(pinfo->bpp) + + pinfo->stride * priv->ypos; + + regvdbg("set LTDC_L%dCFBAR=%08x\n", priv->lid + 1, pinfo->fbmem + offset); + putreg32((uint32_t)pinfo->fbmem + offset, stm32_cfbar_layer_t[priv->lid]); + + /* Configure LxCFBLR register */ + + /* Calculate line length */ + + cfblr = LTDC_LxCFBLR_CFBP(pinfo->stride) | + LTDC_LxCFBLR_CFBLL(area->xres * STM32_LTDC_Lx_BYPP(pinfo->bpp) + 3); + + regvdbg("set LTDC_L%dCFBLR=%08x\n", priv->lid + 1, cfblr); + putreg32(cfblr, stm32_cfblr_layer_t[priv->lid]); + + /* Configure LxCFBLNR register */ + + regvdbg("set LTDC_L%dCFBLNR=%08x\n", priv->lid + 1, area->yres); + putreg32(area->yres, stm32_cfblnr_layer_t[priv->lid]); +} + +/**************************************************************************** + * Name: stm32_ltdc_lalpha + * + * Description: + * Change the layer alpha value and clear the alpha operation flag. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lalpha(FAR struct stm32_layer_s *layer) +{ + uint8_t opac = stm32_ltdc_lgetopac(layer); + regvdbg("set LTDC_L%dCACR=%02x\n", layer->state.lid + 1, opac); + putreg32(opac, stm32_cacr_layer_t[layer->state.lid]); + + /* Clear the constant alpha operation flag */ + + layer->operation &= ~LTDC_LAYER_SETALPHAVALUE; +} + +/**************************************************************************** + * Name: stm32_ltdc_blendfactor + * + * Description: + * Change layer blend factors used for blend operation and clear the + * blendmode operation flag. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * layer - Reference to the laxer control structure + * bf1 - Value of blend factor 1 + * bf2 - Value of blend factor 2 + * + ****************************************************************************/ + +static void stm32_ltdc_lblendmode(FAR struct stm32_layer_s *layer, + uint8_t bf1, uint8_t bf2) +{ + regvdbg("set LTDC_L%dBFCR=%08x\n", layer->state.lid + 1, + (LTDC_LxBFCR_BF1(bf1) | LTDC_LxBFCR_BF2(bf2))); + putreg32((LTDC_LxBFCR_BF1(bf1) | LTDC_LxBFCR_BF2(bf2)), + stm32_bfcr_layer_t[layer->state.lid]); + + /* Clear the blendmode operation flag */ + + layer->operation &= ~LTDC_LAYER_SETBLENDMODE; +} + +/**************************************************************************** + * Name: stm32_ltdc_lcolor + * + * Description: + * Change layer default color and clear the color operation flag. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lcolor(FAR struct stm32_layer_s *layer, uint32_t argb) +{ + regvdbg("set LTDC_L%dDCCR=%08x\n", layer->state.lid + 1, argb); + putreg32(argb, stm32_dccr_layer_t[layer->state.lid]); + + /* Clear the color operation flag */ + + layer->operation &= ~LTDC_LAYER_SETCOLOR; +} + +/**************************************************************************** + * Name: stm32_ltdc_lcolorkey + * + * Description: + * Change layer colorkey and clear the colorkey operation flag. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lcolorkey(FAR struct stm32_layer_s *layer) +{ + uint32_t regval; + + regval = getreg32(stm32_cr_layer_t[layer->state.lid]); + + if (layer->operation & LTDC_LAYER_ENABLECOLORKEY) + { + /* Set colorkey */ + + regvdbg("set LTDC_L%dCKCR=%08x\n", + layer->state.lid + 1, layer->state.colorkey); + putreg32(layer->state.colorkey, stm32_ckcr_layer_t[layer->state.lid]); + + /* Enable colorkey */ + + regval |= LTDC_LxCR_COLKEN; + } + else + { + /* Disable colorkey */ + + regval &= ~LTDC_LxCR_COLKEN; + } + + regvdbg("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval); + putreg32(regval, stm32_cr_layer_t[layer->state.lid]); + + /* Clear the colorkey operation flag */ + + layer->operation &= ~LTDC_LAYER_SETCOLORKEY; +} + +/**************************************************************************** + * Name: stm32_ltdc_lclut + * + * Description: + * Update the clut layer register during blank period. + * Note! The clut register are no shadow register. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +#ifdef STM32_LAYER_CLUT_SIZE +static void stm32_ltdc_lclut(FAR struct stm32_layer_s *layer, + FAR const struct fb_cmap_s *cmap) +{ + int n; + uint32_t regval; + uint32_t *clut; + irqstate_t flags; + + /* Disable clut during register update */ + + stm32_ltdc_lclutenable(layer, false); + + /* Set the clut memory address */ + + clut = layer->state.clut; + + /* Reload shadow control register. + * This never changed any layer setting as long the layer register not up to + * date. This is what stm32_update does. + */ + + stm32_ltdc_reload(LTDC_SRCR_IMR, false); + + flags = enter_critical_section(); + + /* Update the clut registers */ + + for (n = cmap->first; n < cmap->len && n < STM32_LTDC_NCLUT; n++) + { + /* Update the layer clut entry */ +#ifndef CONFIG_FB_TRANSPARENCY + uint8_t *clut888 = (uint8_t *)clut; + uint16_t offset = 3 * n; + + clut888[offset] = cmap->blue[n]; + clut888[offset + 1] = cmap->green[n]; + clut888[offset + 2] = cmap->red[n]; + + regval = (uint32_t)LTDC_CLUT_BLUE(clut888[offset]) | + (uint32_t)LTDC_CLUT_GREEN(clut888[offset + 1]) | + (uint32_t)LTDC_CLUT_RED(clut888[offset + 2]) | + (uint32_t)LTDC_CLUT_ADD(n); +#else + clut[n] = (uint32_t)LTDC_CLUT_ALPHA(cmap->transp[n]) | + (uint32_t)LTDC_CLUT_RED(cmap->red[n]) | + (uint32_t)LTDC_CLUT_GREEN(cmap->green[n]) | + (uint32_t)LTDC_CLUT_BLUE(cmap->blue[n]); + regval = (uint32_t)LTDC_CLUT_ADD(n) | (clut[n] & LTDC_CLUT_RGB888_MASK); +#endif + + + regvdbg("set LTDC_L%dCLUTWR = %08x, cmap->first = %d, cmap->len = %d\n", + layer->state.lid + 1, regval, cmap->first, cmap->len); + putreg32(regval, stm32_clutwr_layer_t[layer->state.lid]); + } + + leave_critical_section(flags); + + /* Enable clut */ + + stm32_ltdc_lclutenable(layer, true); + + /* Reload shadow control register */ + + stm32_ltdc_reload(LTDC_SRCR_IMR, false); +} +#endif + +/**************************************************************************** + * Name: stm32_ltdc_lenable + * + * Description: + * Disable or enable specific layer. + * Note! This changes have no effect until the shadow register reload has + * been done. + * + * Parameter: + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_lenable(FAR struct stm32_layer_s *layer) +{ + uint32_t regval; + + /* Enable or disable layer */ + + regval = getreg32(stm32_cr_layer_t[layer->state.lid]); + + if (layer->operation & LTDC_LAYER_ENABLE) + { + regval |= LTDC_LxCR_LEN; + } + else + { + regval &= ~LTDC_LxCR_LEN; + } + + regvdbg("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval); + putreg32(regval, stm32_cr_layer_t[layer->state.lid]); + + /* Clear the enable operation flag */ + + layer->operation &= ~LTDC_LAYER_SETENABLE; +} + +/**************************************************************************** + * Name stm32_ltdc_lclear + * + * Description: + * Clear the whole layer + * + * Parameter: + * layer - Reference to the layer control structure + * color - The color to clear + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid + * + ****************************************************************************/ + +static void stm32_ltdc_lclear(FAR struct stm32_layer_s *layer, + nxgl_mxpixel_t color) +{ + FAR struct stm32_ltdc_s *priv = &layer->state; + +#if STM32_LTDC_L1_BPP == 8 || STM32_LTDC_L2_BPP == 8 + if (priv->pinfo.bpp == 8) + { + uint8_t *dest = (uint8_t *)priv->pinfo.fbmem; + int i; + + gvdbg("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n", + priv->pinfo.bpp, color, dest, priv->pinfo.fblen); + + for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint8_t)) + { + *dest++ = (uint8_t)color; + } + + return; + } +#endif + +#if STM32_LTDC_L1_BPP == 16 || STM32_LTDC_L2_BPP == 16 + if (priv->pinfo.bpp == 16) + { + uint16_t *dest = (uint16_t *)priv->pinfo.fbmem; + int i; + + gvdbg("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n", + priv->pinfo.bpp, color, dest, priv->pinfo.fblen); + + for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint16_t)) + { + *dest++ = (uint16_t)color; + } + + return; + } +#endif + +#if STM32_LTDC_L1_BPP == 24 || STM32_LTDC_L2_BPP == 24 + if (priv->pinfo.bpp == 24) + { + uint8_t *dest = (uint8_t *)priv->pinfo.fbmem; + uint8_t r; + uint8_t g; + uint8_t b; + int i; + + gvdbg("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n", + priv->pinfo.bpp, color, dest, priv->pinfo.fblen); + + r = (uint8_t) color; + g = (uint8_t) (color >> 8); + b = (uint8_t) (color >> 16); + + for (i = 0; i < priv->pinfo.fblen; i += 3*sizeof(uint8_t)) + { + *dest++ = r; + *dest++ = g; + *dest++ = b; + } + + return; + } +#endif + +#if STM32_LTDC_L1_BPP == 32 || STM32_LTDC_L2_BPP == 32 + if (priv->pinfo.bpp == 32) + { + uint32_t *dest = (uint32_t *)priv->pinfo.fbmem; + int i; + + gvdbg("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n", + priv->pinfo.bpp, color, dest, priv->pinfo.fblen); + + for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint32_t)) + { + *dest++ = (uint32_t)color; + } + } +#endif +} + +/**************************************************************************** + * Name: stm32_ltdc_linit + * + * Description: + * Initialize layer to their default states. + * + * Initialize: + * - Reset layer + * - layer fram + * - Reset layerebuffers + * - layer position + * - layer pixelformat + * - layer color + * - layer colorkey + * - layer alpha + * - layer blendmode + * - layer dma2d interface binding + * + * Parameter + * layer - Reference to the layer control structure + * + ****************************************************************************/ + +static void stm32_ltdc_linit(int lid) +{ + /* Reset layer to their default state */ + + FAR struct stm32_layer_s *layer = &LAYER(lid); + FAR struct stm32_ltdc_s *state = &layer->state; +#ifdef CONFIG_STM32_LTDC_INTERFACE + FAR struct ltdc_layer_s *ltdc = &layer->ltdc; + + /* Initialize the ltdc interface */ + + ltdc->getlid = stm32_getlid; + ltdc->getvideoinfo = stm32_lgetvideoinfo; + ltdc->getplaneinfo = stm32_lgetplaneinfo; +# ifdef STM32_LAYER_CLUT_SIZE + ltdc->setclut = stm32_setclut; + ltdc->getclut = stm32_getclut; +#endif + ltdc->setcolor = stm32_setcolor; + ltdc->getcolor = stm32_getcolor; + ltdc->setcolorkey = stm32_setcolorkey; + ltdc->getcolorkey = stm32_getcolorkey; + ltdc->setalpha = stm32_setalpha; + ltdc->getalpha = stm32_getalpha; + ltdc->setblendmode = stm32_setblendmode; + ltdc->getblendmode = stm32_getblendmode; + ltdc->setarea = stm32_setarea; + ltdc->getarea = stm32_getarea; + ltdc->update = stm32_update; +#ifdef CONFIG_STM32_DMA2D + ltdc->blit = stm32_blit; + ltdc->blend = stm32_blend; + ltdc->fillarea = stm32_fillarea; +#endif +#endif + + /* Initialize the layer state */ + + state->area.xpos = 0; + state->area.ypos = 0; + state->area.xres = STM32_LTDC_WIDTH; + state->area.yres = STM32_LTDC_HEIGHT; + state->xpos = 0; + state->ypos = 0; + state->color = 0; + state->colorkey = 0; + state->alpha = 0xff; + state->blendmode = LTDC_BLEND_NONE; + state->lock = &g_lock; + + /* Initialize driver internals */ + + layer->opac = 0xff; + layer->bf1 = LTDC_BF1_CONST_ALPHA; + layer->bf2 = LTDC_BF2_CONST_ALPHA; + layer->operation = LTDC_LAYER_INIT; + + /* Clear the layer framebuffer */ + + stm32_ltdc_lclear(layer, 0); + + /* Set Pixel input format */ + + stm32_ltdc_lpixelformat(layer); + + /* Set position, color, colorkey, blendmode, alpha */ + + stm32_ltdc_lupdate(layer); + +#ifdef STM32_LAYER_CLUT_SIZE + /* Disable clut by default */ + + if (layer->state.vinfo.fmt == FB_FMT_RGB8) + { + stm32_ltdc_lclutenable(layer, false); + } +#endif + +#ifdef CONFIG_STM32_DMA2D + /* Bind the dma2d interface */ + + layer->dma2d = stm32_dma2dinitltdc(state); + DEBUGASSERT(layer->dma2d); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getvideoinfo + * + * Description: + * Get the videoinfo for the framebuffer + * + * Parameter: + * vtable - The framebuffer driver object + * vinfo - the videoinfo object + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getvideoinfo(struct fb_vtable_s *vtable, + struct fb_videoinfo_s *vinfo) +{ + gvdbg("vtable=%p vinfo=%p\n", vtable, vinfo); + if (vtable) + { + FAR struct ltdc_layer_s *ltdc; +#ifdef CONFIG_STM32_LTDC_L2 + ltdc = (FAR struct ltdc_layer_s *)&LAYER_L2; +#else + ltdc = (FAR struct ltdc_layer_s *)&LAYER_L1; +#endif + return stm32_lgetvideoinfo(ltdc, vinfo); + } + + gdbg("ERROR: Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getplaneinfo + * + * Description: + * Get the planeinfo for the framebuffer + * + * Parameter: + * vtable - The framebuffer driver object + * pinfo - the planeinfo object + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getplaneinfo(struct fb_vtable_s *vtable, int planeno, + struct fb_planeinfo_s *pinfo) +{ + gvdbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo); + if (vtable) + { + FAR struct ltdc_layer_s *ltdc; +#ifdef CONFIG_STM32_LTDC_L2 + ltdc = (FAR struct ltdc_layer_s *)&LAYER_L2; +#else + ltdc = (FAR struct ltdc_layer_s *)&LAYER_L1; +#endif + return stm32_lgetplaneinfo(ltdc, planeno, pinfo); + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getcmap + * + * Description: + * Get a range of CLUT values for the LCD + * + * Parameter: + * vtable - The framebuffer driver object + * cmap - the color table + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +#ifdef STM32_LAYER_CLUT_SIZE +static int stm32_getcmap(struct fb_vtable_s *vtable, + struct fb_cmap_s *cmap) +{ +#ifdef CONFIG_STM32_LTDC_L2 + return stm32_getclut((FAR struct ltdc_layer_s *)&LAYER_L2, cmap); +#else + return stm32_getclut((FAR struct ltdc_layer_s *)&LAYER_L1, cmap); +#endif +} + +/**************************************************************************** + * Name: stm32_putcmap + * + * Description: + * Set a range of the CLUT values for the LCD + * + * Parameter: + * vtable - The framebuffer driver object + * cmap - the color table + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_putcmap(struct fb_vtable_s *vtable, + const struct fb_cmap_s *cmap) +{ +#ifdef CONFIG_STM32_LTDC_L2 + return stm32_setclut((FAR struct ltdc_layer_s *)&LAYER_L2, cmap); +#else + return stm32_setclut((FAR struct ltdc_layer_s *)&LAYER_L1, cmap); +#endif +} +#endif /* STM32_LAYER_CLUT_SIZE */ + +/**************************************************************************** + * Name: stm32_lgetvideoinfo + * + * Description: + * Get video information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * vinfo - Reference to the video info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_lgetvideoinfo(struct ltdc_layer_s *layer, + struct fb_videoinfo_s *vinfo) +{ + gvdbg("layer=%p vinfo=%p\n", layer, vinfo); + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + + if (stm32_ltdc_lvalidate(priv)) + { + memcpy(vinfo, &priv->state.vinfo, sizeof(struct fb_videoinfo_s)); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_lgetplaneinfo + * + * Description: + * Get plane information about the layer + * + * Parameter: + * layer - Reference to the layer control structure + * planeno - Number of the plane + * pinfo - Reference to the plane info structure + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_lgetplaneinfo(struct ltdc_layer_s *layer, int planeno, + struct fb_planeinfo_s *pinfo) +{ + gvdbg("layer=%p planeno=%d pinfo=%p\n", layer, planeno, pinfo); + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + + if (stm32_ltdc_lvalidate(priv) && planeno == 0) + { + memcpy(pinfo, &priv->state.pinfo, sizeof(struct fb_planeinfo_s)); + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_setclut + * + * Description: + * Configure layer clut (color lookup table). + * Non clut is defined during initializing. + * Clut is active during next vertical blank period. Do not need an update. + * + * Parameter: + * layer - Reference to the layer structure + * cmap - color lookup table with up the 256 entries + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +#ifdef STM32_LAYER_CLUT_SIZE +static int stm32_setclut(struct ltdc_layer_s *layer, + const struct fb_cmap_s *cmap) +{ + int ret; + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer=%p cmap=%p\n", layer, cmap); + + if (stm32_ltdc_lvalidate(priv) && cmap) + { + sem_wait(priv->state.lock); + + if (priv->state.vinfo.fmt != FB_FMT_RGB8) + { + gdbg("Error: CLUT is not supported for the pixel format: %d\n", + priv->state.vinfo.fmt); + ret = -EINVAL; + } + else if (cmap->first >= STM32_LTDC_NCLUT) + { + gdbg("Error: only %d color table entries supported\n", + STM32_LTDC_NCLUT); + ret = -EINVAL; + } + else + { + /* Update layer clut and clut register */ + + stm32_ltdc_lclut(priv, cmap); + + ret = OK; + } + + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getclut + * + * Description: + * Get configured layer clut (color lookup table). + * + * Parameter: + * layer - Reference to the layer structure + * cmap - Reference to valid color lookup table accept up the 256 color + * entries + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getclut(struct ltdc_layer_s *layer, + struct fb_cmap_s *cmap) +{ + int ret; + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer=%p cmap=%p\n", layer, cmap); + + if (priv == &LAYER_L1 || priv == &LAYER_L2) + { + sem_wait(priv->state.lock); +#ifdef CONFIG_STM32_DMA2D + /* Note! We share the same color lookup table with the dma2d driver and + * the getclut implementation works in the same way. + * To prevent redundant code we simply call the getclut function of the + * dma2d interface. + */ + + ret = priv->dma2d->getclut(priv->dma2d, cmap); +#else + if (priv->state.vinfo.fmt != FB_FMT_RGB8) + { + gdbg("Error: CLUT is not supported for the pixel format: %d\n", + priv->state.vinfo.fmt); + ret = -EINVAL; + } + else if (cmap->first >= STM32_LTDC_NCLUT) + { + gdbg("Error: only %d color table entries supported\n", + STM32_LTDC_NCLUT); + ret = -EINVAL; + } + else + { + /* Copy from the layer clut */ + + uint32_t *clut; + int n; + + clut = priv->state.clut; + + for (n = cmap->first; n < cmap->len && n < STM32_LTDC_NCLUT; n++) + { +# ifndef CONFIG_FB_TRANSPARENCY + uint8_t *clut888 = (uint8_t *)clut; + uint16_t offset = 3 * n; + + cmap->blue[n] = clut888[offset]; + cmap->green[n] = clut888[offset + 1]; + cmap->red[n] = clut888[offset + 2]; + + regvdbg("n=%d, red=%02x, green=%02x, blue=%02x\n", n, + clut888[offset], clut888[offset + 1], + clut888[offset + 2]); +# else + cmap->transp[n] = (uint8_t)LTDC_CMAP_ALPHA(clut[n]); + cmap->red[n] = (uint8_t)LTDC_CMAP_RED(clut[n]); + cmap->green[n] = (uint8_t)LTDC_CMAP_GREEN(clut[n]); + cmap->blue[n] = (uint8_t)LTDC_CMAP_BLUE(clut[n]); + + regvdbg("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n, + DMA2D_CMAP_ALPHA(clut[n]), DMA2D_CMAP_RED(clut[n]), + DMA2D_CMAP_GREEN(clut[n]), DMA2D_CMAP_BLUE(clut[n])); +# endif + } + + ret = OK; + } +#endif + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif /* STM32_LAYER_CLUT_SIZE */ + +#ifdef CONFIG_STM32_LTDC_INTERFACE +/**************************************************************************** + * Name: getlid + * + * Description: + * Get a specific layer identifier. + * + * Parameter: + * layer - Reference to the layer structure + * lid - Reference to store the layer id + * flag - Operation flag describe the layer identifier + * e.g. get the current active or inactive layer. + * See LTDC_LAYER_* for possible values + * + * Return: + * OK - On success + * Null if invalid flag + * + ****************************************************************************/ + +static int stm32_getlid(FAR struct ltdc_layer_s *layer, int *lid, + uint32_t flag) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + + gvdbg("flag = %08x\n", flag); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret = OK; + + sem_wait(priv->state.lock); + + switch (flag) + { + case LTDC_LAYER_OWN: + *lid = priv->state.lid; + break; +#ifdef CONFIG_STM32_LTDC_L2 + case LTDC_LAYER_ACTIVE: + *lid = g_lactive; + break; + case LTDC_LAYER_INACTIVE: + *lid = !g_lactive; + break; + case LTDC_LAYER_TOP: + *lid = LTDC_LAYER_L2; + break; + case LTDC_LAYER_BOTTOM: + *lid = LTDC_LAYER_L1; + break; +#else + case LTDC_LAYER_ACTIVE: + case LTDC_LAYER_INACTIVE: + case LTDC_LAYER_TOP: + case LTDC_LAYER_BOTTOM: + *lid = LTDC_LAYER_L1; + break; +#endif +#ifdef CONFIG_STM32_DMA2D + case LTDC_LAYER_DMA2D: + ret = priv->dma2d->getlid(priv->dma2d, lid); + break; +#endif + default: + ret = EINVAL; + gdbg("Returning EINVAL\n"); + break; + } + + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_setcolor + * + * Description: + * Configure layer default color value for the non active layer area. + * Default value during initializing: 0x00000000 + * Color is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * argb - ARGB8888 color value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_setcolor(FAR struct ltdc_layer_s *layer, uint32_t argb) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, argb = %08x\n", layer, argb); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + priv->state.color = argb; + priv->operation |= LTDC_LAYER_SETCOLOR; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getcolor + * + * Description: + * Get configured layer color for the non active layer area. + * + * Parameter: + * layer - Reference to the layer structure + * argb - Reference to store the ARGB8888 color value + * + * Return: + * On success - OK + * On error - -EINVAL + * +*******************************************************************************/ + +static int stm32_getcolor(FAR struct ltdc_layer_s *layer, uint32_t *argb) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, argb = %p\n", layer, argb); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + *argb = priv->state.color; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_setcolorkey + * + * Description: + * Configure layer default color key (chromakey) value for transparency. + * Layer default value during initializing: 0x00000000 + * Colorkey is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * rgb - RGB888 color value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_setcolorkey(FAR struct ltdc_layer_s *layer, uint32_t rgb) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, argb = %08x\n", layer, rgb); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + priv->state.colorkey = rgb; + priv->operation |= LTDC_LAYER_SETCOLORKEY; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getcolorkey + * + * Description: + * Get the configured layer color key (chromakey) for transparency. + * + * Parameter: + * layer - Reference to the layer structure + * rgb - Reference to store the RGB888 color key + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getcolorkey(FAR struct ltdc_layer_s *layer, uint32_t *rgb) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, argb = %p\n", layer, rgb); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + *rgb = priv->state.colorkey; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: setalpha + * + * Description: + * Configure layer alpha value factor into blend operation. + * During the layer blend operation the source alpha value is multiplied + * with this alpha value. If the source color format doesn't support alpha + * channel (e.g. non ARGB8888) this alpha value will be used as constant + * alpha value for blend operation. + * Default alpha value during initializing: 0xff + * Alpha is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_setalpha(FAR struct ltdc_layer_s *layer, uint8_t alpha) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, alpha = %02x\n", layer, alpha); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + priv->state.alpha = alpha; + priv->operation |= LTDC_LAYER_SETALPHAVALUE; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getalpha + * + * Description: + * Get configured layer alpha value factor for blend operation. + * + * Parameter: + * layer - Reference to the layer structure + * alpha - Reference to store the alpha value + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getalpha(FAR struct ltdc_layer_s *layer, uint8_t *alpha) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, alpha = %p\n", layer, alpha); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + *alpha = priv->state.alpha; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: setblendmode + * + * Description: + * Configure blend mode of the layer. + * Default mode during initializing: LTDC_BLEND_NONE + * Blendmode is active after next update. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Blend mode (see LTDC_BLEND_*) + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure information: + * LTDC_BLEND_NONE: + * Informs the driver to disable all blend operation for the given layer. + * That means the layer is opaque. Note this has no effect on the + * colorkey settings. + * + * LTDC_BLEND_ALPHA: + * Informs the driver to enable alpha blending for the given layer. + * + * LTDC_BLEND_COLORKEY: + * Informs the driver to enable colorkeying for the given layer. + * + * LTDC_BLEND_SRCPIXELALPHA: + * Informs the driver to use the pixel alpha value of the layer instead + * the constant alpha value. This is only useful for ARGB8888 + * color format. + * + * LTDC_BLEND_DESTPIXELALPHA: + * Informs the driver to use the pixel alpha value of the subjacent layer + * instead the constant alpha value. This is only useful for ARGB8888 + * color format. + * + ****************************************************************************/ + +static int stm32_setblendmode(FAR struct ltdc_layer_s *layer, uint32_t mode) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + uint32_t blendmode = mode; + gvdbg("layer = %p, mode = %08x\n", layer, mode); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret = OK; + + sem_wait(priv->state.lock); + + /* Disable colorkeying by default */ + + priv->operation &= ~LTDC_LAYER_ENABLECOLORKEY; + + if (blendmode & (LTDC_BLEND_ALPHA | LTDC_BLEND_PIXELALPHA | + LTDC_BLEND_ALPHAINV | LTDC_BLEND_PIXELALPHAINV)) + { + /* Enable any alpha blending */ + + stm32_ltdc_lunsetopac(priv); + } + else + { + /* Disable any alpha blending */ + + stm32_ltdc_lsetopac(priv); + } + + if (blendmode & LTDC_BLEND_ALPHA || blendmode == LTDC_BLEND_NONE) + { + /* alpha blending introduce LTDC_BLEND_ALPHAINV */ + + priv->bf1 = LTDC_BF1_CONST_ALPHA; + priv->bf2 = LTDC_BF2_CONST_ALPHA; + blendmode &= ~LTDC_BLEND_ALPHA; + } + + if (blendmode & LTDC_BLEND_PIXELALPHA) + { + /* pixel alpha blending introduce LTDC_BLEND_PIXELALPHAINV */ + + priv->bf1 = LTDC_BF1_PIXEL_ALPHA; + priv->bf2 = LTDC_BF2_PIXEL_ALPHA; + blendmode &= ~LTDC_BLEND_PIXELALPHA; + } + + if (blendmode & LTDC_BLEND_ALPHAINV) + { + /* alpha blending of source input */ + + priv->bf2 = LTDC_BF2_CONST_ALPHA; + blendmode &= ~LTDC_BLEND_ALPHAINV; + } + + if (blendmode & LTDC_BLEND_PIXELALPHAINV) + { + /* pixel alpha blending of source input */ + + priv->bf2 = LTDC_BF2_PIXEL_ALPHA; + blendmode &= ~LTDC_BLEND_PIXELALPHAINV; + } + + if (mode & LTDC_BLEND_COLORKEY) + { + /* Enable colorkeying */ + + priv->operation |= LTDC_LAYER_ENABLECOLORKEY; + blendmode &= ~LTDC_BLEND_COLORKEY; + } + if (blendmode) + { + gdbg("Unknown blendmode %02x\n", blendmode); + ret = -EINVAL; + } + + if (ret == OK) + { + priv->state.blendmode = mode; + priv->operation |= (LTDC_LAYER_SETBLENDMODE | + LTDC_LAYER_SETALPHAVALUE | + LTDC_LAYER_SETCOLORKEY); + } + + sem_post(priv->state.lock); + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getblendmode + * + * Description: + * Get configured blend mode of the layer. + * + * Parameter: + * layer - Reference to the layer structure + * mode - Reference to store the blend mode + * + * Return: + * On success - OK + * On error - -EINVAL + ****************************************************************************/ + +static int stm32_getblendmode(FAR struct ltdc_layer_s *layer, uint32_t *mode) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, mode = %p\n", layer, mode); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + *mode = priv->state.blendmode; + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_setarea + * + * Description: + * Configure visible layer area and the reference position of the first + * pixel of the whole layer which is the first visible top left pixel in + * the active area. + * Area is active after next update. + * + * Parameter: + * layer - Reference to the layer control structure + * area - Reference to the valid area structure for the new active area + * srcxpos - x position of the visible pixel of the whole layer + * srcypos - y position of the visible pixel of the whole layer + * + * Return: + * On success - OK + * On error - -EINVAL + * + * Procedure Information: + * If the srcxpos and srcypos unequal the the xpos and ypos of the area + * structure this acts like moving the visible area to another position on + * the screen during the next update operation. + * + ****************************************************************************/ + +static int stm32_setarea(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + fb_coord_t srcxpos, + fb_coord_t srcypos) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, area = %p, srcxpos = %d, srcypos = %d\n", + layer, area, srcxpos, srcypos); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret; + + sem_wait(priv->state.lock); + + ret = stm32_ltdc_lvalidatearea(priv, area->xpos, area->ypos, area->xres, + area->yres, srcxpos, srcypos); + + if (ret == OK) + { + priv->state.xpos = srcxpos; + priv->state.ypos = srcypos; + priv->state.area.xpos = area->xpos; + priv->state.area.ypos = area->ypos; + priv->state.area.xres = area->xres; + priv->state.area.yres = area->yres; + priv->operation |= LTDC_LAYER_SETAREA; + } + + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_getarea + * + * Description: + * Get configured visible layer area. + * + * Parameter: + * layer - Reference to the layer control structure + * area - Reference to the area structure to store the active area + * srcxpos - Reference to store the referenced x position of the whole layer + * srcypos - Reference to store the reterenced y position of the whole layer + * + * Return: + * On success - OK + * On error - -EINVAL + * + ****************************************************************************/ + +static int stm32_getarea(FAR struct ltdc_layer_s *layer, + FAR struct ltdc_area_s *area, + fb_coord_t *srcxpos, fb_coord_t *srcypos) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, area = %p, srcxpos = %p, srcypos = %p\n", + layer, area, srcxpos, srcypos); + + if (stm32_ltdc_lvalidate(priv)) + { + sem_wait(priv->state.lock); + *srcxpos = priv->state.xpos; + *srcypos = priv->state.ypos; + memcpy(area, &priv->state.area, sizeof(struct ltdc_area_s)); + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_update + * + * Description: + * Update current layer settings and make changes visible. + * + * Parameter: + * layer - Reference to the layer structure + * mode - operation mode + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid + * -ECANCELED - Operation cancelled, something goes wrong + * + * Procedure information: + * LTDC_UPDATE_SIM: + * Informs the driver to update both layers simultaneously. Otherwise update + * the given layer only. + * + * LTDC_UPDATE_FLIP: + * Informs the driver to perform a flip operation. + * This only effects the ltdc layer 1 and 2 and can be useful for double + * buffering. Each flip operation changed the active layer to the inactive + * and vice versa. In the context of the ltdc that means, the inactive layer + * is complete disabled. So the subjacent layer is the background layer + * (background color). To reactivate both layer and their current settings + * perform an update without LTDC_UPDATE_FLIP flag. + * + * LTDC_UPDATE_ACTIVATE: + * Informs the driver that the given layer should be the active layer when + * the operation is complete. + * + * LTDC_SYNC_VBLANK: + * Informs the driver to update the layer upon vertical blank. Otherwise + * immediately. + * + ****************************************************************************/ + +static int stm32_update(FAR struct ltdc_layer_s *layer, uint32_t mode) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; +#ifdef CONFIG_STM32_LTDC_L2 + FAR struct stm32_layer_s *active = &LAYER(g_lactive); + FAR struct stm32_layer_s *inactive = &LAYER(!g_lactive); +#endif + + gvdbg("layer = %p, mode = %08x\n", layer, mode); + + if (stm32_ltdc_lvalidate(priv)) + { + /* Reload immediately by default */ + + bool waitvblank = false; + uint8_t reload = LTDC_SRCR_IMR; + + sem_wait(priv->state.lock); + + if (mode & LTDC_SYNC_VBLANK) + { + reload = LTDC_SRCR_VBR; + } + + if (mode & LTDC_SYNC_WAIT) + { + waitvblank = true; + } + + /* Ensures that last register reload operation has been completed */ + + if (stm32_ltdc_waitforirq() != OK) + { + gdbg("Returning ECANCELED\n"); + return -ECANCELED; + } + + /* Update the given layer */ + + stm32_ltdc_lupdate(priv); + +#ifdef CONFIG_STM32_LTDC_L2 + /* The following operation only useful if layer 2 is supported. + * Otherwise ignore it. + */ + + if (mode & LTDC_UPDATE_SIM) + { + /* Also update the flip layer */ + + stm32_ltdc_lupdate(&LAYER(!priv->state.lid)); + } + + if (mode & LTDC_UPDATE_ACTIVATE) + { + /* Set the given layer to the next active layer */ + + g_lactive = priv->state.lid; + + /* Also change the current active layer for flip operation */ + + active = &LAYER(!g_lactive); + } + + if (mode & LTDC_UPDATE_FLIP) + { + /* Reset if manipulated by ACTIVATE flag */ + + inactive = &LAYER(!active->state.lid); + + /* Set blendfactor for current active layer to there reset value */ + + stm32_ltdc_lblendmode(active, STM32_LTDC_BF1_RESET, + STM32_LTDC_BF2_RESET); + + /* Set blendfactor for current inactive layer */ + + stm32_ltdc_lblendmode(inactive, inactive->bf1, inactive->bf2); + + /* Disable the active layer */ + + active->operation &= ~LTDC_LAYER_ENABLE; + + stm32_ltdc_lenable(active); + + /* Enable the inactive layer */ + + inactive->operation |= LTDC_LAYER_ENABLE; + + stm32_ltdc_lenable(inactive); + + /* Ensure that both layer active and the manipulated layer + * settings restored during the next update (non flip) operation + */ + + active->operation |= (LTDC_LAYER_SETBLENDMODE | + LTDC_LAYER_ENABLE | + LTDC_LAYER_SETCOLOR | + LTDC_LAYER_SETENABLE); + + /* Change layer activity */ + + g_lactive = inactive->state.lid; + } +#endif + + /* Make the changes visible */ + + stm32_ltdc_reload(reload, waitvblank); + + sem_post(priv->state.lock); + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +#ifdef CONFIG_STM32_DMA2D +/**************************************************************************** + * Name: stm32_blit + * + * Description: + * Copy selected area from a source layer to selected position of the + * destination layer. + * + * Parameter: + * dest - Reference to the destination layer + * destxpos - Selected x position of the destination layer + * destypos - Selected y position of the destination layer + * src - Reference to the source layer + * srcarea - Reference to the selected area of the source layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * + ****************************************************************************/ + +static int stm32_blit(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *src, + FAR const struct ltdc_area_s *srcarea) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)dest; + + gvdbg("dest = %p, destxpos = %d, destypos = %d, src = %p, srcarea = %p\n", + dest, destxpos, destypos, src, srcarea); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret; + + sem_wait(priv->state.lock); + priv->dma2d->blit(priv->dma2d, destxpos, destypos, src, srcarea); + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_blend + * + * Description: + * Blends the selected area from a foreground layer with selected position + * of the background layer. Copy the result to the destination layer. Note! + * The content of the foreground and background layer is not changed. + * + * Parameter: + * dest - Reference to the destination layer + * destxpos - Selected x position of the destination layer + * destypos - Selected y position of the destination layer + * fore - Reference to the foreground layer + * forexpos - Selected x position of the foreground layer + * foreypos - Selected y position of the foreground layer + * back - Reference to the background layer + * backarea - Reference to the selected area of the background layer + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * source area outside the visible area of the destination layer. + * (The visible area usually represents the display size) + * + ****************************************************************************/ + +static int stm32_blend(FAR struct ltdc_layer_s *dest, + fb_coord_t destxpos, fb_coord_t destypos, + FAR const struct dma2d_layer_s *fore, + fb_coord_t forexpos, fb_coord_t foreypos, + FAR const struct dma2d_layer_s *back, + FAR const struct ltdc_area_s *backarea) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)dest; + + gvdbg("dest=%p, destxpos=%d, destypos=%d, " + "fore=%p, forexpos=%d foreypos=%d, " + "back=%p, backarea=%p\n", + dest, destxpos, destypos, fore, forexpos, foreypos, back, backarea); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret; + + sem_wait(priv->state.lock); + priv->dma2d->blend(priv->dma2d, destxpos, destypos, + fore, forexpos, foreypos, back, backarea); + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: fillarea + * + * Description: + * Fill the selected area of the whole layer with a specific color. + * + * Parameter: + * layer - Reference to the layer structure + * area - Reference to the valid area structure select the area + * color - Color to fill the selected area. Color must be formatted + * according to the layer pixel format. + * + * Return: + * OK - On success + * -EINVAL - If one of the parameter invalid or if the size of the selected + * area outside the visible area of the layer. + * + ****************************************************************************/ + +static int stm32_fillarea(FAR struct ltdc_layer_s *layer, + FAR const struct ltdc_area_s *area, + uint32_t color) +{ + FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer; + gvdbg("layer = %p, area = %p, color = %08x\n", layer, area, color); + + if (stm32_ltdc_lvalidate(priv)) + { + int ret; + + sem_wait(priv->state.lock); + priv->dma2d->fillarea(priv->dma2d, area, color); + sem_post(priv->state.lock); + + return ret; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: stm32_ltdcgetlayer + * + * Description: + * This is a non-standard framebuffer interface. + * Get the specific layer object by the layer id to enable layer hardware + * support. + * + * Parameter: + * lid - Layer identifier + * + * Return: + * Reference to the layer control structure on success or Null if lid + * is invalid. + * + ****************************************************************************/ + +FAR struct ltdc_layer_s *stm32_ltdcgetlayer(int lid) +{ + gvdbg("lid: %d\n", lid); + if (lid == LTDC_LAYER_L1 || lid == LTDC_LAYER_L2) + { + return (FAR struct ltdc_layer_s *) &LAYER(lid); + } + + gdbg("EINVAL\n"); + errno = EINVAL; + return NULL; +} +#endif /* CONFIG_STM32_LTDC_INTERFACE */ + +/**************************************************************************** + * Name: stm32_ltdcinitialize + * + * Description: + * Initialize the ltdc controller + * + * Return: + * OK + * + ****************************************************************************/ + +int stm32_ltdcinitialize(void) +{ +#ifdef CONFIG_STM32_DMA2D + int ret; +#endif + + dbg("Initialize LTDC driver\n"); + + if (g_initialized == true) + { + return OK; + } + + /* Disable the LCD */ + + stm32_lcd_enable(false); + + gvdbg("Configuring the LCD controller\n"); + + /* Configure LCD periphery */ + + gvdbg("Configure lcd periphery\n"); + stm32_ltdc_periphconfig(); + + /* Configure global ltdc register */ + + gvdbg("Configure global register\n"); + stm32_global_configure(); + +#ifdef CONFIG_STM32_DMA2D + /* Initialize the dma2d controller */ + + ret = up_dma2dinitialize(); + + if (ret != OK) + { + return ret; + } +#endif + + /* Initialize ltdc layer */ + + gvdbg("Initialize ltdc layer\n"); + stm32_ltdc_linit(LTDC_LAYER_L1); +#ifdef CONFIG_STM32_LTDC_L2 + stm32_ltdc_linit(LTDC_LAYER_L2); +#endif + + /* Display layer 1 and 2 */ + + stm32_ltdc_lenable(&LAYER_L1); +#ifdef CONFIG_STM32_LTDC_L2 + stm32_ltdc_lenable(&LAYER_L2); +#endif + + /* Enable the backlight */ + +#ifdef CONFIG_STM32_LCD_BACKLIGHT + stm32_backlight(true); +#endif + + /* Reload shadow register */ + + gvdbg("Reload shadow register\n"); + stm32_ltdc_reload(LTDC_SRCR_IMR, false); + + /* Turn the LCD on */ + + gvdbg("Enabling the display\n"); + stm32_lcd_enable(true); + + /* Set initialized state */ + + g_initialized = true; + return OK; +} + +/**************************************************************************** + * Name: stm32_ltdcgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video + * plane. + * + * Input parameters: + * None + * + * Returned value: + * Reference to the framebuffer object (NULL on failure) + * + ****************************************************************************/ + +struct fb_vtable_s *stm32_ltdcgetvplane(int vplane) +{ + gvdbg("vplane: %d\n", vplane); + + if (vplane == 0) + { + return (struct fb_vtable_s *)&g_vtable; + } + + return NULL; +} + +/**************************************************************************** + * Name: fb_uninitialize + * + * Description: + * Uninitialize the framebuffer driver. Bad things will happen if you + * call this without first calling fb_initialize()! + * + ****************************************************************************/ + +void stm32_ltdcuninitialize(void) +{ + /* Disable all ltdc interrupts */ + + stm32_ltdc_irqctrl(0, LTDC_IER_RRIE | LTDC_IER_TERRIE | + LTDC_IER_FUIE | LTDC_IER_LIE); + + up_disable_irq(g_interrupt.irq); + irq_detach(g_interrupt.irq); + + /* Disable the LCD controller */ + + stm32_lcd_enable(false); + + /* Set initialized state */ + + g_initialized = false; +} + +/**************************************************************************** + * Name: stm32_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the STM32 LTDC. Clearing the + * display in the normal way by writing a sequences of runs that covers the + * entire display can be slow. Here the display is cleared by simply setting + * all video memory to the specified color. + * + * Parameter: + * color - The color the clear the whole framebuffer + * + ****************************************************************************/ + +void stm32_lcdclear(nxgl_mxpixel_t color) +{ +#ifdef CONFIG_STM32_LTDC_L2 + stm32_ltdc_lclear(&LAYER(LTDC_LAYER_L2), color); +#endif + stm32_ltdc_lclear(&LAYER(LTDC_LAYER_L1), color); +} + +/**************************************************************************** + * Name: stm32_lcd_backlight + * + * Description: + * Provide this interface to turn the backlight on and off. + * + * Parameter: + * blon - Enable or disable the lcd backlight + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_LCD_BACKLIGHT +void stm32_backlight(bool blon) +{ + /* Set default backlight level CONFIG_STM32_LTDC_DEFBACKLIGHT */ + + gdbg("Not supported\n"); +} +#endif diff --git a/arch/arm/src/stm32/stm32_ltdc.h b/arch/arm/src/stm32/stm32_ltdc.h new file mode 100644 index 0000000000000000000000000000000000000000..9214d83e351abb40f9a628e1738ffaf4ad1d71b2 --- /dev/null +++ b/arch/arm/src/stm32/stm32_ltdc.h @@ -0,0 +1,157 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_ltdc.h + * + * Copyright (C) 2013-2014 Ken Pettit. All rights reserved. + * Authors: Ken Pettit + * Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_LTDC_H +#define __ARCH_ARM_SRC_STM32_STM32_LTDC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include + +#ifdef CONFIG_STM32_LTDC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Common layer state structure for the LTDC and DMA2D controller */ + +struct stm32_ltdc_s +{ + /* Fixed settings */ + + int lid; /* Layer identifier */ + struct fb_videoinfo_s vinfo; /* Layer videoinfo */ + struct fb_planeinfo_s pinfo; /* Layer planeinfo */ + + /* Positioning */ + + struct ltdc_area_s area; /* Active layer area */ + fb_coord_t xpos; /* Reference x position */ + fb_coord_t ypos; /* Reference y position */ + + /* Coloring */ + + uint32_t color; /* Layer color definition */ +#ifdef CONFIG_FB_CMAP + uint32_t *clut; /* 32-bit aligned clut color table */ +#endif + + /* Blending */ + + uint8_t alpha; /* Layer constant alpha value */ + uint32_t colorkey; /* Layer colorkey */ + uint32_t blendmode; /* Layer blend factor */ + + /* Operation */ + + sem_t *lock; /* Ensure mutually exclusive access */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/* The STM32 LTDC driver uses the common framebuffer interfaces declared in + * include/nuttx/video/fb.h. + */ + +int stm32_ltdcinitialize(void); +FAR struct fb_vtable_s *stm32_ltdcgetvplane(int vplane); +void stm32_ltdcuninitialize(void); + +/************************************************************************************ + * Name: stm32_ltdcgetlayer + * + * Description: + * Get the ltdc layer structure to perform hardware layer operation + * + * Parameter: + * lid - Layer identifier + * + * Return: + * Reference to the layer control structure on success or Null if parameter + * invalid. + * + ************************************************************************************/ + +FAR struct ltdc_layer_s *stm32_ltdcgetlayer(int lid); + +/************************************************************************************ + * Name: stm32_lcdclear + * + * Description: + * This is a non-standard LCD interface just for the STM32 LTDC. Clearing the + * display in the normal way by writing a sequences of runs that covers the + * entire display can be slow. Here the display is cleared by simply setting + * all video memory to the specified color. + * + ************************************************************************************/ + +void stm32_lcdclear(nxgl_mxpixel_t color); + +/************************************************************************************ + * Name: stm32_lcd_backlight + * + * Description: + * If CONFIG_STM32_LCD_BACKLIGHT is defined, then the board-specific logic must + * provide this interface to turn the backlight on and off. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_LCD_BACKLIGHT +void stm32_backlight(bool blon); +#endif + +#endif /* CONFIG_STM32_LTDC */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_LTDC_H */ diff --git a/arch/arm/src/stm32/stm32_mpuinit.c b/arch/arm/src/stm32/stm32_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..552e75d1fd992f46fc363ba97b23370dd92fc512 --- /dev/null +++ b/arch/arm/src/stm32/stm32_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_mpuinit.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "stm32_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void stm32_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void stm32_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/stm32/stm32_mpuinit.h b/arch/arm/src/stm32/stm32_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..6d76db47ee54a48b452f0ba87be9aef300e787aa --- /dev/null +++ b/arch/arm/src/stm32/stm32_mpuinit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_mpuinit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_MPUINIT_H +#define __ARCH_ARM_SRC_STM32_STM32_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpuinitialize(void); +#else +# define stm32_mpuinitialize() +#endif + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpu_uheap(uintptr_t start, size_t size); +#else +# define stm32_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_STM32_STM32_MPUINIT_H */ diff --git a/arch/arm/src/stm32/stm32_otgfs.h b/arch/arm/src/stm32/stm32_otgfs.h new file mode 100644 index 0000000000000000000000000000000000000000..ba3549379c1e075a24c087873f0fd61b47872ab6 --- /dev/null +++ b/arch/arm/src/stm32/stm32_otgfs.h @@ -0,0 +1,128 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_otgfs.h + * + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_OTGFS_H +#define __ARCH_ARM_SRC_STM32_STM32_OTGFS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "stm32.h" + +#include "chip/stm32fxxxxx_otgfs.h" + +#if defined(CONFIG_STM32_OTGFS) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifndef CONFIG_OTGFS_PRI +# define CONFIG_OTGFS_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_otgfshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller); +#endif + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the OTG FS device driver + * is used. This function is called whenever the USB enters or leaves suspend + * mode. This is an opportunity for the board logic to shutdown clocks, power, + * etc. while the USB is suspended. + * + ************************************************************************************/ + +void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32_OTGFS */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_OTGFS_H */ + diff --git a/arch/arm/src/stm32/stm32_otgfsdev.c b/arch/arm/src/stm32/stm32_otgfsdev.c new file mode 100644 index 0000000000000000000000000000000000000000..81fb004fbce49ee81cbc050ead8cbdfba63fad59 --- /dev/null +++ b/arch/arm/src/stm32/stm32_otgfsdev.c @@ -0,0 +1,5671 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_otgfsdev.c + * + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32_otgfs.h" + +#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32_OTGFS)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* There is 1.25Kb of FIFO memory. The default partitions this memory + * so that there is a TxFIFO allocated for each endpoint and with more + * memory provided for the common RxFIFO. A more knowledge-able + * configuration would not allocate any TxFIFO space to OUT endpoints. + */ + +#ifndef CONFIG_USBDEV_RXFIFO_SIZE +# define CONFIG_USBDEV_RXFIFO_SIZE 512 +#endif + +#ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 192 +#endif + +#if (CONFIG_USBDEV_RXFIFO_SIZE + CONFIG_USBDEV_EP0_TXFIFO_SIZE + \ + CONFIG_USBDEV_EP2_TXFIFO_SIZE + CONFIG_USBDEV_EP3_TXFIFO_SIZE) > 1280 +# error "FIFO allocations exceed FIFO memory size" +#endif + +/* The actual FIFO addresses that we use must be aligned to 4-byte boundaries; + * FIFO sizes must be provided in units of 32-bit words. + */ + +#define STM32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3) +#define STM32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2) + +#define STM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP0_TXFIFO_WORDS < 16 || STM32_EP0_TXFIFO_WORDS > 256 +# error "CONFIG_USBDEV_EP0_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP1_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP1_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP2_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP2_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP3_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range" +#endif + +/* Debug ***********************************************************************/ +/* Trace error codes */ + +#define STM32_TRACEERR_ALLOCFAIL 0x01 +#define STM32_TRACEERR_BADCLEARFEATURE 0x02 +#define STM32_TRACEERR_BADDEVGETSTATUS 0x03 +#define STM32_TRACEERR_BADEPNO 0x04 +#define STM32_TRACEERR_BADEPGETSTATUS 0x05 +#define STM32_TRACEERR_BADGETCONFIG 0x06 +#define STM32_TRACEERR_BADGETSETDESC 0x07 +#define STM32_TRACEERR_BADGETSTATUS 0x08 +#define STM32_TRACEERR_BADSETADDRESS 0x09 +#define STM32_TRACEERR_BADSETCONFIG 0x0a +#define STM32_TRACEERR_BADSETFEATURE 0x0b +#define STM32_TRACEERR_BADTESTMODE 0x0c +#define STM32_TRACEERR_BINDFAILED 0x0d +#define STM32_TRACEERR_DISPATCHSTALL 0x0e +#define STM32_TRACEERR_DRIVER 0x0f +#define STM32_TRACEERR_DRIVERREGISTERED 0x10 +#define STM32_TRACEERR_EP0NOSETUP 0x11 +#define STM32_TRACEERR_EP0SETUPSTALLED 0x12 +#define STM32_TRACEERR_EPINNULLPACKET 0x13 +#define STM32_TRACEERR_EPINUNEXPECTED 0x14 +#define STM32_TRACEERR_EPOUTNULLPACKET 0x15 +#define STM32_TRACEERR_EPOUTUNEXPECTED 0x16 +#define STM32_TRACEERR_INVALIDCTRLREQ 0x17 +#define STM32_TRACEERR_INVALIDPARMS 0x18 +#define STM32_TRACEERR_IRQREGISTRATION 0x19 +#define STM32_TRACEERR_NOEP 0x1a +#define STM32_TRACEERR_NOTCONFIGURED 0x1b +#define STM32_TRACEERR_EPOUTQEMPTY 0x1c +#define STM32_TRACEERR_EPINREQEMPTY 0x1d +#define STM32_TRACEERR_NOOUTSETUP 0x1e +#define STM32_TRACEERR_POLLTIMEOUT 0x1f + +/* Trace interrupt codes */ + +#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */ +#define STM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */ + +#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */ +#define STM32_TRACEINTID_EPIN (10 + 1) +#define STM32_TRACEINTID_MISMATCH (10 + 2) +#define STM32_TRACEINTID_WAKEUP (10 + 3) +#define STM32_TRACEINTID_SUSPEND (10 + 4) +#define STM32_TRACEINTID_SOF (10 + 5) +#define STM32_TRACEINTID_RXFIFO (10 + 6) +#define STM32_TRACEINTID_DEVRESET (10 + 7) +#define STM32_TRACEINTID_ENUMDNE (10 + 8) +#define STM32_TRACEINTID_IISOIXFR (10 + 9) +#define STM32_TRACEINTID_IISOOXFR (10 + 10) +#define STM32_TRACEINTID_SRQ (10 + 11) +#define STM32_TRACEINTID_OTG (10 + 12) + +#define STM32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */ +#define STM32_TRACEINTID_EPOUT_EPDISD (40 + 1) +#define STM32_TRACEINTID_EPOUT_SETUP (40 + 2) +#define STM32_TRACEINTID_DISPATCH (40 + 3) + +#define STM32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */ +#define STM32_TRACEINTID_EPGETSTATUS (50 + 1) +#define STM32_TRACEINTID_DEVGETSTATUS (50 + 2) +#define STM32_TRACEINTID_IFGETSTATUS (50 + 3) +#define STM32_TRACEINTID_CLEARFEATURE (50 + 4) +#define STM32_TRACEINTID_SETFEATURE (50 + 5) +#define STM32_TRACEINTID_SETADDRESS (50 + 6) +#define STM32_TRACEINTID_GETSETDESC (50 + 7) +#define STM32_TRACEINTID_GETCONFIG (50 + 8) +#define STM32_TRACEINTID_SETCONFIG (50 + 9) +#define STM32_TRACEINTID_GETSETIF (50 + 10) +#define STM32_TRACEINTID_SYNCHFRAME (50 + 11) + +#define STM32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */ +#define STM32_TRACEINTID_EPIN_TOC (70 + 1) +#define STM32_TRACEINTID_EPIN_ITTXFE (70 + 2) +#define STM32_TRACEINTID_EPIN_EPDISD (70 + 3) +#define STM32_TRACEINTID_EPIN_TXFE (70 + 4) + +#define STM32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */ + +#define STM32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */ +#define STM32_TRACEINTID_OUTRECVD (90 + 1) +#define STM32_TRACEINTID_OUTDONE (90 + 2) +#define STM32_TRACEINTID_SETUPDONE (90 + 3) +#define STM32_TRACEINTID_SETUPRECVD (90 + 4) + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define STM32_NENDPOINTS (4) /* ep0-3 x 2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define STM32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN) +#define STM32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT) + +/* Endpoint 0 */ + +#define EP0 (0) + +/* The set of all enpoints available to the class implementation (1-3) */ + +#define STM32_EP_AVAILABLE (0x0e) /* All available endpoints */ + +/* Maximum packet sizes for full speed endpoints */ + +#define STM32_MAXPACKET (64) /* Max packet size (1-64) */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 +#define STM32_FLUSH_DELAY 200000 + +/* Request queue operations ****************************************************/ + +#define stm32_rqempty(ep) ((ep)->head == NULL) +#define stm32_rqpeek(ep) ((ep)->head) + +/* Standard stuff **************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Overall device state */ + +enum stm32_devstate_e +{ + DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply + * means that the device is not yet been given an + * address. + * SET: At initialization, uninitialization, + * reset, and whenever the device address + * is set to zero + * TESTED: Never + */ + DEVSTATE_ADDRESSED, /* Device address has been assigned, not no + * configuration has yet been selected. + * SET: When either a non-zero device address + * is first assigned or when the device + * is unconfigured (with configuration == 0) + * TESTED: never + */ + DEVSTATE_CONFIGURED, /* Address assigned and configured: + * SET: When the device has been addressed and + * an non-zero configuration has been selected. + * TESTED: In many places to assure that the USB device + * has been properly configured by the host. + */ +}; + +/* Endpoint 0 states */ + +enum stm32_ep0state_e +{ + EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or + * epsubmit: + * SET: In stm32_epin() and stm32_epout() when + * we revert from request processing to + * SETUP processing. + * TESTED: Never + */ + EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA + * OUT phase of SETUP Packet to complete before + * processing a SETUP command (without a USB request): + * SET: Set in stm32_rxinterrupt() when SETUP OUT + * packet is received. + * TESTED: In stm32_ep0out_receive() + */ + EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and + * accompanying data have been received. Processing + * of SETUP command will happen soon. + * SET: (1) stm32_ep0out_receive() when the OUT + * SETUP data phase completes, or (2) + * stm32_rxinterrupt() when an IN SETUP is + * packet received. + * TESTED: Tested in stm32_epout_interrupt() when + * SETUP phase is done to see if the SETUP + * command is ready to be processed. Also + * tested in stm32_ep0out_setup() just to + * double-check that we have a SETUP request + * and any accompanying data. + */ + EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by stm32_ep0out_setup(): + * SET: When SETUP packet received in EP0 OUT + * TESTED: Never + */ + EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request): + * SET: When SETUP response is sent by + * stm32_ep0in_setupresponse() + * TESTED: Never + */ + EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request): + * SET: In stm32_epin_request() when a write + * request is processed on EP0. + * TESTED: In stm32_epin() to see if we should + * revert to SETUP processing. + */ + EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a + * USB request) + * SET: In stm32_epout_request() when a read + * request is processed on EP0. + * TESTED: In stm32_epout() to see if we should + * revert to SETUP processing + */ +}; + +/* Parsed control request */ + +struct stm32_ctrlreq_s +{ + uint8_t type; + uint8_t req; + uint16_t value; + uint16_t index; + uint16_t len; +}; + +/* A container for a request so that the request may be retained in a list */ + +struct stm32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct stm32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct stm32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct stm32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* STM32-specific fields */ + + struct stm32_usbdev_s *dev; /* Reference to private driver data */ + struct stm32_req_s *head; /* Request list for this endpoint */ + struct stm32_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t eptype:2; /* Endpoint type */ + uint8_t active:1; /* 1: A request is being processed */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t isin:1; /* 1: IN Endpoint */ + uint8_t odd:1; /* 1: Odd frame */ + uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */ +}; + +/* This structure retains the state of the USB device controller */ + +struct stm32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct stm32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* STM32-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t addressed:1; /* 1: Peripheral address has been set */ + uint8_t configured:1; /* 1: Class driver has been configured */ + uint8_t wakeup:1; /* 1: Device remote wake-up */ + uint8_t dotest:1; /* 1: Test mode selected */ + + uint8_t devstate:4; /* See enum stm32_devstate_e */ + uint8_t ep0state:4; /* See enum stm32_ep0state_e */ + uint8_t testmode:4; /* Selected test mode */ + uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */ + + /* E0 SETUP data buffering. + * + * ctrlreq: + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The pack receipt logic will save + * the accompanying EP0 IN data in ep0data[] before the SETUP command is + * processed. + * + * For IN SETUP requests, the DATA phase will occur AFTER the SETUP + * control request is processed. In that case, ep0data[] may be used as + * the response buffer. + * + * ep0datlen + * Length of OUT DATA received in ep0data[] (Not used with OUT data) + */ + + struct usb_ctrlreq_s ctrlreq; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint lists */ + + struct stm32_ep_s epin[STM32_NENDPOINTS]; + struct stm32_ep_s epout[STM32_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations ****************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep); +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req); + +/* Low level data transfers and request operations *****************************/ +/* Special endpoint 0 data transfer logic */ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *data, uint32_t nbytes); +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv); +static void stm32_ep0in_activate(void); + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv); + +/* IN request and TxFIFO handling */ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* OUT request and RxFIFO handling */ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len); +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len); +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt); +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt); +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* General request handling */ + +static void stm32_ep_flush(FAR struct stm32_ep_s *privep); +static void stm32_req_complete(FAR struct stm32_ep_s *privep, + int16_t result); +static void stm32_req_cancel(FAR struct stm32_ep_s *privep, + int16_t status); + +/* Interrupt handling **********************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog); +static int stm32_req_dispatch(FAR struct stm32_usbdev_s *priv, + FAR const struct usb_ctrlreq_s *ctrl); +static void stm32_usbreset(FAR struct stm32_usbdev_s *priv); + +/* Second level OUT endpoint interrupt processing */ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index); +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq); +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv); +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, + uint8_t epno); +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Second level IN endpoint interrupt processing */ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv); +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno); +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno); +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Other second level interrupt processing */ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv); +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv); +#endif +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv); +#endif + +/* First level interrupt processing */ + +static int stm32_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ +/* Global OUT NAK controls */ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep); +static void stm32_disablegonak(FAR struct stm32_ep_s *privep); + +/* Endpoint configuration */ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, bool last); +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv); + +/* Endpoint disable */ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep); +static void stm32_epin_disable(FAR struct stm32_ep_s *privep); +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep); + +/* Endpoint request management */ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep); +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); + +/* Endpoint buffer management */ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif + +/* Endpoint request submission */ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Endpoint request cancellation */ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Stall handling */ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep); +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume); +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv); + +/* Endpoint allocation */ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void stm32_ep_free(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep); + +/* USB device controller operations ********************************************/ + +static int stm32_getframe(struct usbdev_s *dev); +static int stm32_wakeup(struct usbdev_s *dev); +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int stm32_pullup(struct usbdev_s *dev, bool enable); +static void stm32_setaddress(struct stm32_usbdev_s *priv, + uint16_t address); +static int stm32_txfifo_flush(uint32_t txfnum); +static int stm32_rxfifo_flush(void); + +/* Initialization **************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv); +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct stm32_usbdev_s g_otgfsdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = stm32_ep_configure, + .disable = stm32_ep_disable, + .allocreq = stm32_ep_allocreq, + .freereq = stm32_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = stm32_ep_allocbuffer, + .freebuffer = stm32_ep_freebuffer, +#endif + .submit = stm32_ep_submit, + .cancel = stm32_ep_cancel, + .stall = stm32_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = stm32_ep_alloc, + .freeep = stm32_ep_free, + .getframe = stm32_getframe, + .wakeup = stm32_wakeup, + .selfpowered = stm32_selfpowered, + .pullup = stm32_pullup, +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(STM32_TRACEERR_ALLOCFAIL ), + TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ), + TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADEPNO ), + TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADGETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADGETSETDESC ), + TRACE_STR(STM32_TRACEERR_BADGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADSETADDRESS ), + TRACE_STR(STM32_TRACEERR_BADSETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADSETFEATURE ), + TRACE_STR(STM32_TRACEERR_BADTESTMODE ), + TRACE_STR(STM32_TRACEERR_BINDFAILED ), + TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ), + TRACE_STR(STM32_TRACEERR_DRIVER ), + TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED), + TRACE_STR(STM32_TRACEERR_EP0NOSETUP ), + TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ), + TRACE_STR(STM32_TRACEERR_EPINNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPINUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPOUTUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ), + TRACE_STR(STM32_TRACEERR_INVALIDPARMS ), + TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ), + TRACE_STR(STM32_TRACEERR_NOEP ), + TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ), + TRACE_STR(STM32_TRACEERR_EPOUTQEMPTY ), + TRACE_STR(STM32_TRACEERR_EPINREQEMPTY ), + TRACE_STR(STM32_TRACEERR_NOOUTSETUP ), + TRACE_STR(STM32_TRACEERR_POLLTIMEOUT ), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(STM32_TRACEINTID_USB ), + TRACE_STR(STM32_TRACEINTID_INTPENDING ), + TRACE_STR(STM32_TRACEINTID_EPOUT ), + TRACE_STR(STM32_TRACEINTID_EPIN ), + TRACE_STR(STM32_TRACEINTID_MISMATCH ), + TRACE_STR(STM32_TRACEINTID_WAKEUP ), + TRACE_STR(STM32_TRACEINTID_SUSPEND ), + TRACE_STR(STM32_TRACEINTID_SOF ), + TRACE_STR(STM32_TRACEINTID_RXFIFO ), + TRACE_STR(STM32_TRACEINTID_DEVRESET ), + TRACE_STR(STM32_TRACEINTID_ENUMDNE ), + TRACE_STR(STM32_TRACEINTID_IISOIXFR ), + TRACE_STR(STM32_TRACEINTID_IISOOXFR ), + TRACE_STR(STM32_TRACEINTID_SRQ ), + TRACE_STR(STM32_TRACEINTID_OTG ), + TRACE_STR(STM32_TRACEINTID_EPOUT_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPOUT_EPDISD), + TRACE_STR(STM32_TRACEINTID_EPOUT_SETUP ), + TRACE_STR(STM32_TRACEINTID_DISPATCH ), + TRACE_STR(STM32_TRACEINTID_GETSTATUS ), + TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS), + TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_CLEARFEATURE), + TRACE_STR(STM32_TRACEINTID_SETFEATURE ), + TRACE_STR(STM32_TRACEINTID_SETADDRESS ), + TRACE_STR(STM32_TRACEINTID_GETSETDESC ), + TRACE_STR(STM32_TRACEINTID_GETCONFIG ), + TRACE_STR(STM32_TRACEINTID_SETCONFIG ), + TRACE_STR(STM32_TRACEINTID_GETSETIF ), + TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ), + TRACE_STR(STM32_TRACEINTID_EPIN_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPIN_TOC ), + TRACE_STR(STM32_TRACEINTID_EPIN_ITTXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EPDISD ), + TRACE_STR(STM32_TRACEINTID_EPIN_TXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EMPWAIT), + TRACE_STR(STM32_TRACEINTID_OUTNAK ), + TRACE_STR(STM32_TRACEINTID_OUTRECVD ), + TRACE_STR(STM32_TRACEINTID_OUTDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPRECVD ), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_req_remfirst + * + * Description: + * Remove a request from the head of an endpoint request queue + * + ****************************************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep) +{ + FAR struct stm32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_req_addlast + * + * Description: + * Add a request to the end of an endpoint request queue + * + ****************************************************************************/ + +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + return is_empty; +} + +/**************************************************************************** + * Name: stm32_ep0in_setupresponse + * + * Description: + * Schedule a short transfer on Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *buf, uint32_t nbytes) +{ + stm32_epin_transfer(&priv->epin[EP0], buf, nbytes); + priv->ep0state = EP0STATE_SETUPRESPONSE; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0in_transmitzlp + * + * Description: + * Send a zero length packet (ZLP) on endpoint 0 IN + * + ****************************************************************************/ + +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv) +{ + stm32_ep0in_setupresponse(priv, NULL, 0); +} + +/**************************************************************************** + * Name: stm32_ep0in_activate + * + * Description: + * Activate the endpoint 0 IN endpoint. + * + ****************************************************************************/ + +static void stm32_ep0in_activate(void) +{ + uint32_t regval; + + /* Set the max packet size of the IN EP. */ + + regval = stm32_getreg(STM32_OTGFS_DIEPCTL0); + regval &= ~OTGFS_DIEPCTL0_MPSIZ_MASK; + +#if CONFIG_USBDEV_EP0_MAXSIZE == 8 + regval |= OTGFS_DIEPCTL0_MPSIZ_8; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 16 + regval |= OTGFS_DIEPCTL0_MPSIZ_16; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 32 + regval |= OTGFS_DIEPCTL0_MPSIZ_32; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 64 + regval |= OTGFS_DIEPCTL0_MPSIZ_64; +#else +# error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE" +#endif + + stm32_putreg(regval, STM32_OTGFS_DIEPCTL0); + + /* Clear global IN NAK */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval |= OTGFS_DCTL_CGINAK; + stm32_putreg(regval, STM32_OTGFS_DCTL); +} + +/**************************************************************************** + * Name: stm32_ep0out_ctrlsetup + * + * Description: + * Setup to receive a SETUP packet. + * + ****************************************************************************/ + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Setup the hardware to perform the SETUP transfer */ + + regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) | + (OTGFS_DOEPTSIZ0_PKTCNT) | + (3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DOEPTSIZ0); + + /* Then clear NAKing and enable the transfer */ + + regval = stm32_getreg(STM32_OTGFS_DOEPCTL0); + regval |= (OTGFS_DOEPCTL0_CNAK | OTGFS_DOEPCTL0_EPENA); + stm32_putreg(regval, STM32_OTGFS_DOEPCTL0); +} + +/**************************************************************************** + * Name: stm32_txfifo_write + * + * Description: + * Send data to the endpoint's TxFIFO. + * + ****************************************************************************/ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t regaddr; + uint32_t regval; + int nwords; + int i; + + /* Convert the number of bytes to words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the TxFIFO for this endpoint (same as the endpoint number) */ + + regaddr = STM32_OTGFS_DFIFO_DEP(privep->epphy); + + /* Then transfer each word to the TxFIFO */ + + for (i = 0; i < nwords; i++) + { + /* Read four bytes from the source buffer (to avoid unaligned accesses) + * and pack these into one 32-bit word (little endian). + */ + + regval = (uint32_t)*buf++; + regval |= ((uint32_t)*buf++) << 8; + regval |= ((uint32_t)*buf++) << 16; + regval |= ((uint32_t)*buf++) << 24; + + /* Then write the packet data to the TxFIFO */ + + stm32_putreg(regval, regaddr); + } +} + +/**************************************************************************** + * Name: stm32_epin_transfer + * + * Description: + * Start the Tx data transfer + * + ****************************************************************************/ + +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t pktcnt; + uint32_t regval; + + /* Read the DIEPSIZx register */ + + regval = stm32_getreg(STM32_OTGFS_DIEPTSIZ(privep->epphy)); + + /* Clear the XFRSIZ, PKTCNT, and MCNT field of the DIEPSIZx register */ + + regval &= ~(OTGFS_DIEPTSIZ_XFRSIZ_MASK | OTGFS_DIEPTSIZ_PKTCNT_MASK | + OTGFS_DIEPTSIZ_MCNT_MASK); + + /* Are we sending a zero length packet (ZLP) */ + + if (nbytes == 0) + { + /* Yes.. leave the transfer size at zero and set the packet count to 1 */ + + pktcnt = 1; + } + else + { + /* No.. Program the transfer size and packet count . First calculate: + * + * xfrsize = The total number of bytes to be sent. + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + */ + + pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + } + + /* Set the XFRSIZ and PKTCNT */ + + regval |= (pktcnt << OTGFS_DIEPTSIZ_PKTCNT_SHIFT); + regval |= ((uint32_t)nbytes << OTGFS_DIEPTSIZ_XFRSIZ_SHIFT); + + /* If this is an isochronous endpoint, then set the multi-count field to + * the PKTCNT as well. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + regval |= (pktcnt << OTGFS_DIEPTSIZ_MCNT_SHIFT); + } + + /* Save DIEPSIZx register value */ + + stm32_putreg(regval, STM32_OTGFS_DIEPTSIZ(privep->epphy)); + + /* Read the DIEPCTLx register */ + + regval = stm32_getreg(STM32_OTGFS_DIEPCTL(privep->epphy)); + + /* If this is an isochronous endpoint, then set the even/odd frame bit + * the DIEPCTLx register. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + /* Check bit 0 of the frame number of the received SOF and set the + * even/odd frame to match. + */ + + uint32_t status = stm32_getreg(STM32_OTGFS_DSTS); + if ((status & OTGFS_DSTS_SOFFN0) == OTGFS_DSTS_SOFFN_EVEN) + { + regval |= OTGFS_DIEPCTL_SEVNFRM; + } + else + { + regval |= OTGFS_DIEPCTL_SODDFRM; + } + } + + /* EP enable, IN data in FIFO */ + + regval &= ~OTGFS_DIEPCTL_EPDIS; + regval |= (OTGFS_DIEPCTL_CNAK | OTGFS_DIEPCTL_EPENA); + stm32_putreg(regval, STM32_OTGFS_DIEPCTL(privep->epphy)); + + /* Transfer the data to the TxFIFO. At this point, the caller has already + * assured that there is sufficient space in the TxFIFO to hold the transfer + * we can just blindly continue. + */ + + stm32_txfifo_write(privep, buf, nbytes); +} + +/**************************************************************************** + * Name: stm32_epin_request + * + * Description: + * Begin or continue write request processing. + * + ****************************************************************************/ + +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint8_t *buf; + int nbytes; + int nwords; + int bytesleft; + + /* We get here in one of four possible ways. From three interrupting + * events: + * + * 1. From stm32_epin as part of the transfer complete interrupt processing + * This interrupt indicates that the last transfer has completed. + * 2. As part of the ITTXFE interrupt processing. That interrupt indicates + * that an IN token was received when the associated TxFIFO was empty. + * 3. From stm32_epin_txfifoempty as part of the TXFE interrupt processing. + * The TXFE interrupt is only enabled when the TxFIFO is full and the + * software must wait for space to become available in the TxFIFO. + * + * And this function may be called immediately when the write request is + * queue to start up the next transaction. + * + * 4. From stm32_ep_submit when a new write request is received WHILE the + * endpoint is not active (privep->active == false). + */ + + /* Check the request from the head of the endpoint request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINREQEMPTY), privep->epphy); + + /* There is no TX transfer in progress and no new pending TX + * requests to send. To stop transmitting any data on a particular + * IN endpoint, the application must set the IN NAK bit. To set this + * bit, the following field must be programmed. + */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGFS_DIEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer active */ + + privep->active = false; + return; + } + + ullvdbg("EP%d req=%p: len=%d xfrd=%d zlp=%d\n", + privep->epphy, privreq, privreq->req.len, + privreq->req.xfrd, privep->zlp); + + /* Check for a special case: If we are just starting a request (xfrd==0) and + * the class driver is trying to send a zero-length packet (len==0). Then set + * the ZLP flag so that the packet will be sent. + */ + + if (privreq->req.len == 0) + { + /* The ZLP flag is set TRUE whenever we want to force the driver to + * send a zero-length-packet on the next pass through the loop (below). + * The flag is cleared whenever a packet is sent in the loop below. + */ + + privep->zlp = true; + } + + /* Add one more packet to the TxFIFO. We will wait for the transfer + * complete event before we add the next packet (or part of a packet + * to the TxFIFO). + * + * The documentation says that we can can multiple packets to the TxFIFO, + * but it seems that we need to get the transfer complete event before + * we can add the next (or maybe I have got something wrong?) + */ + +#if 0 + while (privreq->req.xfrd < privreq->req.len || privep->zlp) +#else + if (privreq->req.xfrd < privreq->req.len || privep->zlp) +#endif + { + /* Get the number of bytes left to be sent in the request */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + + /* Assume no zero-length-packet on the next pass through this loop */ + + privep->zlp = false; + + /* Limit the size of the transfer to one full packet and handle + * zero-length packets (ZLPs). + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* The ZLP flag is set TRUE whenever we want to force + * the driver to send a zero-length-packet on the next + * pass through this loop. The flag is cleared (above) + * whenever we are committed to sending any packet and + * set here when we want to force one more pass through + * the loop. + */ + + privep->zlp = true; + } + } + } + + /* Get the transfer size in 32-bit words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the number of 32-bit words available in the TxFIFO. The + * DXTFSTS indicates the amount of free space available in the + * endpoint TxFIFO. Values are in terms of 32-bit words: + * + * 0: Endpoint TxFIFO is full + * 1: 1 word available + * 2: 2 words available + * n: n words available + */ + + regaddr = STM32_OTGFS_DTXFSTS(privep->epphy); + + /* Check for space in the TxFIFO. If space in the TxFIFO is not + * available, then set up an interrupt to resume the transfer when + * the TxFIFO is empty. + */ + + regval = stm32_getreg(regaddr); + if ((int)(regval & OTGFS_DTXFSTS_MASK) < nwords) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval); + + /* There is insufficient space in the TxFIFO. Wait for a TxFIFO + * empty interrupt and try again. + */ + + uint32_t empmsk = stm32_getreg(STM32_OTGFS_DIEPEMPMSK); + empmsk |= OTGFS_DIEPEMPMSK(privep->epphy); + stm32_putreg(empmsk, STM32_OTGFS_DIEPEMPMSK); + + /* Terminate the transfer. We will try again when the TxFIFO empty + * interrupt is received. + */ + + return; + } + + /* Transfer data to the TxFIFO */ + + buf = privreq->req.buf + privreq->req.xfrd; + stm32_epin_transfer(privep, buf, nbytes); + + /* If it was not before, the OUT endpoint is now actively transferring + * data. + */ + + privep->active = true; + + /* EP0 is a special case */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_IN; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* Note that the ZLP, if any, must be sent as a separate transfer. The need + * for a ZLP is indicated by privep->zlp. If all of the bytes were sent + * (including any final null packet) then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->zlp) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + + /* We are finished with the request (although the transfer has not + * yet completed). + */ + + stm32_req_complete(privep, OK); + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_read + * + * Description: + * Read packet from the RxFIFO into a read request. + * + ****************************************************************************/ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len) +{ + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO. Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTGFS_DFIFO_DEP(EP0); + + /* Read 32-bits and write 4 x 8-bits at time (to avoid unaligned accesses) */ + + for (i = 0; i < len; i += 4) + { + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Read 1 x 32-bits of EP0 packet data */ + + data.w = stm32_getreg(regaddr); + + /* Write 4 x 8-bits of EP0 packet data */ + + *dest++ = data.b[0]; + *dest++ = data.b[1]; + *dest++ = data.b[2]; + *dest++ = data.b[3]; + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_discard + * + * Description: + * Discard packet data from the RxFIFO. + * + ****************************************************************************/ + +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len) +{ + if (len > 0) + { + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTGFS_DFIFO_DEP(EP0); + + /* Read 32-bits at time */ + + for (i = 0; i < len; i += 4) + { + volatile uint32_t data = stm32_getreg(regaddr); + (void)data; + } + } +} + +/**************************************************************************** + * Name: stm32_epout_complete + * + * Description: + * This function is called when an OUT transfer complete interrupt is + * received. It completes the read request at the head of the endpoint's + * request queue. + * + ****************************************************************************/ + +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + + /* Since a transfer just completed, there must be a read request at the head of + * the endpoint request queue. + */ + + privreq = stm32_rqpeek(privep); + DEBUGASSERT(privreq); + + if (!privreq) + { + /* An OUT transfer completed, but no packet to receive the data. This + * should not happen. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + privep->epphy, privreq->req.len, privreq->req.xfrd); + + /* Return the completed read request to the class driver and mark the state + * IDLE. + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + stm32_req_complete(privep, OK); + privep->active = false; + + /* Now set up the next read request (if any) */ + + stm32_epout_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_ep0out_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + FAR struct stm32_usbdev_s *priv; + + /* Sanity Checking */ + + DEBUGASSERT(privep && privep->ep.priv); + priv = (FAR struct stm32_usbdev_s *)privep->ep.priv; + + ullvdbg("EP0: bcnt=%d\n", bcnt); + usbtrace(TRACE_READ(EP0), bcnt); + + /* Verify that an OUT SETUP request as received before this data was + * received in the RxFIFO. + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Read the data into our special buffer for SETUP data */ + + int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt); + stm32_rxfifo_read(privep, priv->ep0data, readlen); + + /* Do we have to discard any excess bytes? */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Now we can process the setup command */ + + privep->active = false; + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + + stm32_ep0out_setup(priv); + } + else + { + /* This is an error. We don't have any idea what to do with the EP0 + * data in this case. Just read and discard it so that the RxFIFO + * does not become constipated. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOOUTSETUP), priv->ep0state); + stm32_rxfifo_discard(privep, bcnt); + privep->active = false; + } +} + +/**************************************************************************** + * Name: stm32_epout_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + struct stm32_req_s *privreq; + uint8_t *dest; + int buflen; + int readlen; + + /* Get a reference to the request at the head of the endpoint's request + * queue. + */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* Incoming data is available in the RxFIFO, but there is no read setup + * to receive the receive the data. This should not happen for data + * endpoints; those endpoints should have been NAKing any OUT data tokens. + * + * We should get here normally on OUT data phase following an OUT + * SETUP command. EP0 data will still receive data in this case and it + * should not be NAKing. + */ + + if (privep->epphy == 0) + { + stm32_ep0out_receive(privep, bcnt); + } + else + { + /* Otherwise, the data is lost. This really should not happen if + * NAKing is working as expected. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* Discard the data in the RxFIFO */ + + stm32_rxfifo_discard(privep, bcnt); + } + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", privep->epphy, privreq->req.len, privreq->req.xfrd); + usbtrace(TRACE_READ(privep->epphy), bcnt); + + /* Get the number of bytes to transfer from the RxFIFO */ + + buflen = privreq->req.len - privreq->req.xfrd; + DEBUGASSERT(buflen > 0 && buflen >= bcnt); + readlen = MIN(buflen, bcnt); + + /* Get the destination of the data transfer */ + + dest = privreq->req.buf + privreq->req.xfrd; + + /* Transfer the data from the RxFIFO to the request's data buffer */ + + stm32_rxfifo_read(privep, dest, readlen); + + /* If there were more bytes in the RxFIFO than could be held in the read + * request, then we will have to discard those. + */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Update the number of bytes transferred */ + + privreq->req.xfrd += readlen; +} + +/**************************************************************************** + * Name: stm32_epout_request + * + * Description: + * This function is called when either (1) new read request is received, or + * (2) a pending receive request completes. If there is no read in pending, + * then this function will initiate the next OUT (read) operation. + * + ****************************************************************************/ + +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; + + /* Make sure that there is not already a pending request request. If there is, + * just return, leaving the newly received request in the request queue. + */ + + if (!privep->active) + { + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an invalid + * read request is encountered. + */ + + for (; ; ) + { + /* Get a reference to the request at the head of the endpoint's request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* There are no read requests to be setup. Configure the hardware to + * NAK any incoming packets. (This should already be the case. I + * think that the hardware will automatically NAK after a transfer is + * completed until SNAK is cleared). + */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGFS_DOEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* This endpoint is no longer actively transferring */ + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d\n", privep->epphy, privreq->req.len); + + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ + + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); + stm32_req_complete(privep, OK); + } + + /* Otherwise, we have a usable read request... break out of the loop */ + + else + { + break; + } + } + + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ + + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = STM32_OTGFS_DOEPTSIZ(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~(OTGFS_DOEPTSIZ_XFRSIZ_MASK | OTGFS_DOEPTSIZ_PKTCNT_MASK); + regval |= (xfrsize << OTGFS_DOEPTSIZ_XFRSIZ_SHIFT); + regval |= (pktcnt << OTGFS_DOEPTSIZ_PKTCNT_SHIFT); + stm32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* When an isochronous transfer is enabled the Even/Odd frame bit must + * also be set appropriately. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + if (privep->odd) + { + regval |= OTGFS_DOEPCTL_SODDFRM; + } + else + { + regval |= OTGFS_DOEPCTL_SEVNFRM; + } + } +#endif + + /* Clearing NAKing and enable the transfer. */ + + regval |= (OTGFS_DOEPCTL_CNAK | OTGFS_DOEPCTL_EPENA); + stm32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + + /* EP0 is a special case. We need to know when to switch back to + * normal SETUP processing. + */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_OUT; + } + } +} + +/**************************************************************************** + * Name: stm32_ep_flush + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void stm32_ep_flush(struct stm32_ep_s *privep) +{ + if (privep->isin) + { + stm32_txfifo_flush(OTGFS_GRSTCTL_TXFNUM_D(privep->epphy)); + } + else + { + stm32_rxfifo_flush(); + } +} + +/**************************************************************************** + * Name: stm32_req_complete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void stm32_req_complete(struct stm32_ep_s *privep, int16_t result) +{ + FAR struct stm32_req_s *privreq; + + /* Remove the request at the head of the request list */ + + privreq = stm32_req_remfirst(privep); + DEBUGASSERT(privreq != NULL); + + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == EP0) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: stm32_req_cancel + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void stm32_req_cancel(struct stm32_ep_s *privep, int16_t status) +{ + if (!stm32_rqempty(privep)) + { + stm32_ep_flush(privep); + } + + while (!stm32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (stm32_rqpeek(privep))->req.xfrd); + stm32_req_complete(privep, status); + } +} + +/**************************************************************************** + * Name: stm32_ep_findbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog) +{ + struct stm32_ep_s *privep; + uint8_t epphy = USB_EPNO(eplog); + + if (epphy >= STM32_NENDPOINTS) + { + return NULL; + } + + /* Is this an IN or an OUT endpoint? */ + + if (USB_ISEPIN(eplog)) + { + privep = &priv->epin[epphy]; + } + else + { + privep = &priv->epout[epphy]; + } + + /* Return endpoint reference */ + + DEBUGASSERT(privep->epphy == epphy); + return privep; +} + +/**************************************************************************** + * Name: stm32_req_dispatch + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static int stm32_req_dispatch(struct stm32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, + priv->ep0data, priv->ep0datlen); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_usbreset(struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int i; + + /* Clear the Remote Wake-up Signaling */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval &= ~OTGFS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGFS_DCTL); + + /* Flush the EP0 Tx FIFO */ + + stm32_txfifo_flush(OTGFS_GRSTCTL_TXFNUM_D(EP0)); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Mark all endpoints as available */ + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + /* Disable all end point interrupts */ + + for (i = 0; i < STM32_NENDPOINTS ; i++) + { + /* Disable endpoint interrupts */ + + stm32_putreg(0xff, STM32_OTGFS_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTGFS_DOEPINT(i)); + + /* Return write requests to the class implementation */ + + privep = &priv->epin[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset IN endpoint status */ + + privep->stalled = false; + + /* Return read requests to the class implementation */ + + privep = &priv->epout[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + stm32_putreg(0xffffffff, STM32_OTGFS_DAINT); + + /* Mask all device endpoint interrupts except EP0 */ + + regval = (OTGFS_DAINT_IEP(EP0) | OTGFS_DAINT_OEP(EP0)); + stm32_putreg(regval, STM32_OTGFS_DAINTMSK); + + /* Unmask OUT interrupts */ + + regval = (OTGFS_DOEPMSK_XFRCM | OTGFS_DOEPMSK_STUPM | OTGFS_DOEPMSK_EPDM); + stm32_putreg(regval, STM32_OTGFS_DOEPMSK); + + /* Unmask IN interrupts */ + + regval = (OTGFS_DIEPMSK_XFRCM | OTGFS_DIEPMSK_EPDM | OTGFS_DIEPMSK_TOM); + stm32_putreg(regval, STM32_OTGFS_DIEPMSK); + + /* Reset device address to 0 */ + + stm32_setaddress(priv, 0); + priv->devstate = DEVSTATE_DEFAULT; + priv->usbdev.speed = USB_SPEED_FULL; + + /* Re-configure EP0 */ + + stm32_ep0_configure(priv); + + /* Setup EP0 to receive SETUP packets */ + + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_testmode + * + * Description: + * Select test mode + * + ****************************************************************************/ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index) +{ + uint8_t testmode; + + testmode = index >> 8; + switch (testmode) + { + case 1: + priv->testmode = OTGFS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGFS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGFS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGFS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGFS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGFS_TESTMODE_DISABLED; + priv->stalled = true; + } + + priv->dotest = true; + stm32_ep0in_transmitzlp(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_stdrequest + * + * Description: + * Handle a stanard request on EP0. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver. + * + ****************************************************************************/ + +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq) +{ + FAR struct stm32_ep_s *privep; + + /* Handle standard request */ + + switch (ctrlreq->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ + + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); + + /* If the class driver accepted the configuration, then mark the + * device state as configured (or not, depending on the + * configuration). + */ + + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } +} + +/**************************************************************************** + * Name: stm32_ep0out_setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv) +{ + struct stm32_ctrlreq_s ctrlreq; + + /* Verify that a SETUP was received */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + + /* Terminate any pending requests */ + + stm32_req_cancel(&priv->epout[EP0], -EPROTO); + stm32_req_cancel(&priv->epin[EP0], -EPROTO); + + /* Assume NOT stalled */ + + priv->epout[EP0].stalled = false; + priv->epin[EP0].stalled = false; + priv->stalled = false; + + /* Starting to process a control request - update state */ + + priv->ep0state = EP0STATE_SETUP_PROCESS; + + /* And extract the little-endian 16-bit values to host order */ + + ctrlreq.type = priv->ctrlreq.type; + ctrlreq.req = priv->ctrlreq.req; + ctrlreq.value = GETUINT16(priv->ctrlreq.value); + ctrlreq.index = GETUINT16(priv->ctrlreq.index); + ctrlreq.len = GETUINT16(priv->ctrlreq.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrlreq.type, ctrlreq.req, ctrlreq.value, ctrlreq.index, ctrlreq.len); + + /* Check for a standard request */ + + if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + /* Dispatch any non-standard requests */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + /* Handle standard requests. */ + + stm32_ep0out_stdrequest(priv, &ctrlreq); + } + + /* Check if the setup processing resulted in a STALL */ + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + stm32_ep0_stall(priv); + } + + /* Reset state/data associated with thie SETUP request */ + + priv->ep0datlen = 0; +} + +/**************************************************************************** + * Name: stm32_epout + * + * Description: + * This is part of the OUT endpoint interrupt processing. This function + * handles the OUT event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + privep = &priv->epout[EP0]; + + /* In the EP0STATE_DATA_OUT state, we are receiving data into the + * request buffer. In that case, we must continue the request + * processing. + */ + + if (priv->ep0state == EP0STATE_DATA_OUT) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epout_complete(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an OUT request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + stm32_epout_complete(priv, &priv->epout[epno]); + } +} + +/**************************************************************************** + * Name: stm32_epout_interrupt + * + * Description: + * USB OUT endpoint interrupt handler. The core generates this interrupt when + * there is an interrupt is pending on one of the OUT endpoints of the core. + * The driver must read the OTGFS DAINT register to determine the exact number + * of the OUT endpoint on which the interrupt occurred, and then read the + * corresponding OTGFS DOEPINTx register to determine the exact cause of the + * interrupt. + * + ****************************************************************************/ + +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t daint; + uint32_t regval; + uint32_t doepint; + int epno; + + /* Get the pending, enabled interrupts for the OUT endpoint from the endpoint + * interrupt status register. + */ + + regval = stm32_getreg(STM32_OTGFS_DAINT); + regval &= stm32_getreg(STM32_OTGFS_DAINTMSK); + daint = (regval & OTGFS_DAINT_OEP_MASK) >> OTGFS_DAINT_OEP_SHIFT; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + regval = stm32_getreg(STM32_OTGFS_DAINT); + daint = (regval & OTGFS_DAINT_OEP_MASK) >> OTGFS_DAINT_OEP_SHIFT; + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTUNEXPECTED), + (uint16_t)regval); + + epno = 0; + while (daint) + { + if ((daint & 1) != 0) + { + regval = stm32_getreg(STM32_OTGFS_DOEPINT(epno)); + ulldbg("DOEPINT(%d) = %08x\n", epno, regval); + stm32_putreg(0xFF, STM32_OTGFS_DOEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an OUT interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Yes.. get the OUT endpoint interrupt status */ + + doepint = stm32_getreg(STM32_OTGFS_DOEPINT(epno)); + doepint &= stm32_getreg(STM32_OTGFS_DOEPMSK); + + /* Transfer completed interrupt. This interrupt is trigged when + * stm32_rxinterrupt() removes the last packet data from the RxFIFO. + * In this case, core internally sets the NAK bit for this endpoint to + * prevent it from receiving any more packets. + */ + + if ((doepint & OTGFS_DOEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_XFRC), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTGFS_DOEPINT_XFRC, STM32_OTGFS_DOEPINT(epno)); + + /* Handle the RX transfer data ready event */ + + stm32_epout(priv, epno); + } + + /* Endpoint disabled interrupt (ignored because this interrupt is + * used in polled mode by the endpoint disable logic). + */ +#if 1 + /* REVISIT: */ + if ((doepint & OTGFS_DOEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTGFS_DOEPINT_EPDISD, STM32_OTGFS_DOEPINT(epno)); + } +#endif + /* Setup Phase Done (control EPs) */ + + if ((doepint & OTGFS_DOEPINT_SETUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_SETUP), priv->ep0state); + + /* Handle the receipt of the IN SETUP packets now (OUT setup + * packet processing may be delayed until the accompanying + * OUT DATA is received) + */ + + if (priv->ep0state == EP0STATE_SETUP_READY) + { + stm32_ep0out_setup(priv); + } + stm32_putreg(OTGFS_DOEPINT_SETUP, STM32_OTGFS_DOEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_epin_runtestmode + * + * Description: + * Execute the test mode setup by the SET FEATURE request + * + ****************************************************************************/ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval = stm32_getreg(STM32_OTGFS_DCTL); + regval &= OTGFS_DCTL_TCTL_MASK; + regval |= (uint32_t)priv->testmode << OTGFS_DCTL_TCTL_SHIFT; + stm32_putreg(regval , STM32_OTGFS_DCTL); + + priv->dotest = 0; + priv->testmode = OTGFS_TESTMODE_DISABLED; +} + +/**************************************************************************** + * Name: stm32_epin + * + * Description: + * This is part of the IN endpoint interrupt processing. This function + * handles the IN event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + /* In the EP0STATE_DATA_IN state, we are sending data from request + * buffer. In that case, we must continue the request processing. + */ + + if (priv->ep0state == EP0STATE_DATA_IN) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epin_request(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + + /* Test mode is another special case */ + + if (priv->dotest) + { + stm32_epin_runtestmode(priv); + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an IN request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + /* Continue processing data from the endpoint write request queue */ + + stm32_epin_request(priv, privep); + } +} + +/**************************************************************************** + * Name: stm32_epin_txfifoempty + * + * Description: + * TxFIFO empty interrupt handling + * + ****************************************************************************/ + +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Continue processing the write request queue. This may mean sending + * more data from the existing request or terminating the current requests + * and (perhaps) starting the IN transfer from the next write request. + */ + + stm32_epin_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_epin_interrupt + * + * Description: + * USB IN endpoint interrupt handler. The core generates this interrupt when + * an interrupt is pending on one of the IN endpoints of the core. The driver + * must read the OTGFS DAINT register to determine the exact number of the IN + * endpoint on which the interrupt occurred, and then read the corresponding + * OTGFS DIEPINTx register to determine the exact cause of the interrupt. + * + ****************************************************************************/ + +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t diepint; + uint32_t daint; + uint32_t mask; + uint32_t empty; + int epno; + + /* Get the pending, enabled interrupts for the IN endpoint from the endpoint + * interrupt status register. + */ + + daint = stm32_getreg(STM32_OTGFS_DAINT); + daint &= stm32_getreg(STM32_OTGFS_DAINTMSK); + daint &= OTGFS_DAINT_IEP_MASK; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + daint = stm32_getreg(STM32_OTGFS_DAINT); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINUNEXPECTED), + (uint16_t)daint); + + daint &= OTGFS_DAINT_IEP_MASK; + epno = 0; + + while (daint) + { + if ((daint & 1) != 0) + { + ulldbg("DIEPINT(%d) = %08x\n", + epno, stm32_getreg(STM32_OTGFS_DIEPINT(epno))); + stm32_putreg(0xFF, STM32_OTGFS_DIEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an IN interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Get IN interrupt mask register. Bits 0-6 correspond to enabled + * interrupts as will be found in the DIEPINT interrupt status + * register. + */ + + mask = stm32_getreg(STM32_OTGFS_DIEPMSK); + + /* Check if the TxFIFO not empty interrupt is enabled for this + * endpoint in the DIEPMSK register. Bits n corresponds to + * endpoint n in the register. That condition corresponds to + * bit 7 of the DIEPINT interrupt status register. There is + * no TXFE bit in the mask register, so we fake one here. + */ + + empty = stm32_getreg(STM32_OTGFS_DIEPEMPMSK); + if ((empty & OTGFS_DIEPEMPMSK(epno)) != 0) + { + mask |= OTGFS_DIEPINT_TXFE; + } + + /* Now, read the interrupt status and mask out all disabled + * interrupts. + */ + + diepint = stm32_getreg(STM32_OTGFS_DIEPINT(epno)) & mask; + + /* Decode and process the enabled, pending interrupts */ + /* Transfer completed interrupt */ + + if ((diepint & OTGFS_DIEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC), + (uint16_t)diepint); + + /* It is possible that logic may be waiting for a the + * TxFIFO to become empty. We disable the TxFIFO empty + * interrupt here; it will be re-enabled if there is still + * insufficient space in the TxFIFO. + */ + + empty &= ~OTGFS_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTGFS_DIEPEMPMSK); + stm32_putreg(OTGFS_DIEPINT_XFRC, STM32_OTGFS_DIEPINT(epno)); + + /* IN transfer complete */ + + stm32_epin(priv, epno); + } + + /* Timeout condition */ + + if ((diepint & OTGFS_DIEPINT_TOC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TOC), (uint16_t)diepint); + stm32_putreg(OTGFS_DIEPINT_TOC, STM32_OTGFS_DIEPINT(epno)); + } + + /* IN token received when TxFIFO is empty. Applies to non-periodic IN + * endpoints only. This interrupt indicates that an IN token was received + * when the associated TxFIFO (periodic/non-periodic) was empty. This + * interrupt is asserted on the endpoint for which the IN token was + * received. + */ + + if ((diepint & OTGFS_DIEPINT_ITTXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_ITTXFE), (uint16_t)diepint); + stm32_epin_request(priv, &priv->epin[epno]); + stm32_putreg(OTGFS_DIEPINT_ITTXFE, STM32_OTGFS_DIEPINT(epno)); + } + + /* IN endpoint NAK effective (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTGFS_DIEPINT_INEPNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_INEPNE), (uint16_t)diepint); + stm32_putreg(OTGFS_DIEPINT_INEPNE, STM32_OTGFS_DIEPINT(epno)); + } +#endif + /* Endpoint disabled interrupt (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTGFS_DIEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EPDISD), (uint16_t)diepint); + stm32_putreg(OTGFS_DIEPINT_EPDISD, STM32_OTGFS_DIEPINT(epno)); + } +#endif + /* Transmit FIFO empty */ + + if ((diepint & OTGFS_DIEPINT_TXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint); + + /* If we were waiting for TxFIFO to become empty, the we might have both + * XFRC and TXFE interrupts pending. Since we do the same thing for both + * cases, ignore the TXFE if we have already processed the XFRC. + */ + + if ((diepint & OTGFS_DIEPINT_XFRC) == 0) + { + /* Mask further FIFO empty interrupts. This will be re-enabled + * whenever we need to wait for a FIFO event. + */ + + empty &= ~OTGFS_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTGFS_DIEPEMPMSK); + + /* Handle TxFIFO empty */ + + stm32_epin_txfifoempty(priv, epno); + } + + /* Clear the pending TxFIFO empty interrupt */ + + stm32_putreg(OTGFS_DIEPINT_TXFE, STM32_OTGFS_DIEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_resumeinterrupt + * + * Description: + * Resume/remote wakeup detected interrupt + * + ****************************************************************************/ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Restart the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTGFS_PCGCCTL); + regval &= ~(OTGFS_PCGCCTL_STPPCLK | OTGFS_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTGFS_PCGCCTL); +#endif + + /* Clear remote wake-up signaling */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval &= ~OTGFS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGFS_DCTL); + + /* Restore full power -- whatever that means for this particular board */ + + stm32_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: stm32_suspendinterrupt + * + * Description: + * USB suspend interrupt + * + ****************************************************************************/ + +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv) +{ +#ifdef CONFIG_USBDEV_LOWPOWER + uint32_t regval; +#endif + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + +#ifdef CONFIG_USBDEV_LOWPOWER + /* OTGFS_DSTS_SUSPSTS is set as long as the suspend condition is detected + * on USB. Check if we are still have the suspend condition, that we are + * connected to the host, and that we have been configured. + */ + + regval = stm32_getreg(STM32_OTGFS_DSTS); + + if ((regval & OTGFS_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED) + { + /* Switch off OTG FS clocking. Setting OTGFS_PCGCCTL_STPPCLK stops the + * PHY clock. + */ + + regval = stm32_getreg(STM32_OTGFS_PCGCCTL); + regval |= OTGFS_PCGCCTL_STPPCLK; + stm32_putreg(regval, STM32_OTGFS_PCGCCTL); + + /* Setting OTGFS_PCGCCTL_GATEHCLK gate HCLK to modules other than + * the AHB Slave and Master and wakeup logic. + */ + + regval |= OTGFS_PCGCCTL_GATEHCLK; + stm32_putreg(regval, STM32_OTGFS_PCGCCTL); + } +#endif + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + stm32_usbsuspend((FAR struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: stm32_rxinterrupt + * + * Description: + * RxFIFO non-empty interrupt. This interrupt indicates that there is at + * least one packet pending to be read from the RxFIFO. + * + ****************************************************************************/ + +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int bcnt; + int epphy; + + /* Disable the Rx status queue level interrupt */ + + regval = stm32_getreg(STM32_OTGFS_GINTMSK); + regval &= ~OTGFS_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTGFS_GINTMSK); + + /* Get the status from the top of the FIFO */ + + regval = stm32_getreg(STM32_OTGFS_GRXSTSP); + + /* Decode status fields */ + + epphy = (regval & OTGFS_GRXSTSD_EPNUM_MASK) >> OTGFS_GRXSTSD_EPNUM_SHIFT; + + if (epphy < STM32_NENDPOINTS) + { + privep = &priv->epout[epphy]; + + /* Handle the RX event according to the packet status field */ + + switch (regval & OTGFS_GRXSTSD_PKTSTS_MASK) + { + /* Global OUT NAK. This indicate that the global OUT NAK bit has taken + * effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't + * Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, DPID = Actual Data PID. + */ + + case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> OTGFS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. This indicates that an OUT data transfer for + * the specified OUT endpoint has completed. After this entry is popped + * from the receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup stage for + * the specified endpoint has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core asserts a + * Setup interrupt on the specified control OUT endpoint (triggers an + * interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + } + break; + + /* SETUP data packet received. This indicates that a SETUP packet for the + * specified endpoint is now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ + + stm32_rxfifo_read(&priv->epout[EP0], (FAR uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero length, + * then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = stm32_getreg(STM32_OTGFS_DOEPCTL0); + regval |= OTGFS_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTGFS_DOEPCTL0); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word is + * popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> OTGFS_GRXSTSD_PKTSTS_SHIFT); + } + break; + } + } + + /* Enable the Rx Status Queue Level interrupt */ + + regval = stm32_getreg(STM32_OTGFS_GINTMSK); + regval |= OTGFS_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTGFS_GINTMSK); +} + +/**************************************************************************** + * Name: stm32_enuminterrupt + * + * Description: + * Enumeration done interrupt + * + ****************************************************************************/ + +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Activate EP0 */ + + stm32_ep0in_activate(); + + /* Set USB turn-around time for the full speed device with internal PHY interface. */ + + regval = stm32_getreg(STM32_OTGFS_GUSBCFG); + regval &= ~OTGFS_GUSBCFG_TRDT_MASK; + regval |= OTGFS_GUSBCFG_TRDT(5); + stm32_putreg(regval, STM32_OTGFS_GUSBCFG); +} + +/**************************************************************************** + * Name: stm32_isocininterrupt + * + * Description: + * Incomplete isochronous IN transfer interrupt. Assertion of the incomplete + * isochronous IN transfer interrupt indicates an incomplete isochronous IN + * transfer on at least one of the isochronous IN endpoints. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv) +{ + int i; + + /* The application must read the endpoint control register for all isochronous + * IN endpoints to detect endpoints with incomplete IN data transfers. + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous IN endpoint? */ + + privep = &priv->epin[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTGFS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTGFS_DIEPCTL_EONUM) != 0); + soffn = ((dsts & OTGFS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous IN endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTGFS_DIEPCTL_USBAEP too" + stm32_epin_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_isocoutinterrupt + * + * Description: + * Incomplete periodic transfer interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + FAR struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t doepctl; + uint32_t dsts; + bool eonum; + bool soffn; + + /* When it receives an IISOOXFR interrupt, the application must read the + * control registers of all isochronous OUT endpoints to determine which + * endpoints had an incomplete transfer in the current microframe. An + * endpoint transfer is incomplete if both the following conditions are true: + * + * DOEPCTLx:EONUM = DSTS:SOFFN[0], and + * DOEPCTLx:EPENA = 1 + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous OUT endpoint? */ + + privep = &priv->epout[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTGFS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTGFS_DOEPCTL_EONUM) != 0); + soffn = ((dsts & OTGFS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous OUT endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTGFS_DOEPCTL_USBAEP too" + stm32_epout_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_sessioninterrupt + * + * Description: + * Session request/new session detected interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv) +{ +#warning "Missing logic" +} +#endif + +/**************************************************************************** + * Name: stm32_otginterrupt + * + * Description: + * OTG interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Check for session end detected */ + + regval = stm32_getreg(STM32_OTGFS_GOTGINT); + if ((regval & OTGFS_GOTGINT_SEDET) != 0) + { +#warning "Missing logic" + } + + /* Clear OTG interrupt */ + + stm32_putreg(retval, STM32_OTGFS_GOTGINT); +} +#endif + +/**************************************************************************** + * Name: stm32_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int stm32_usbinterrupt(int irq, FAR void *context) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otgfsdev; + uint32_t regval; + + usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0); + + /* Assure that we are in device mode */ + + DEBUGASSERT((stm32_getreg(STM32_OTGFS_GINTSTS) & OTGFS_GINTSTS_CMOD) == OTGFS_GINTSTS_DEVMODE); + + /* Get the state of all enabled interrupts. We will do this repeatedly + * some interrupts (like RXFLVL) will generate additional interrupting + * events. + */ + + for (; ; ) + { + /* Get the set of pending, un-masked interrupts */ + + regval = stm32_getreg(STM32_OTGFS_GINTSTS); + regval &= stm32_getreg(STM32_OTGFS_GINTMSK); + + /* Break out of the loop when there are no further pending (and + * unmasked) interrupts to be processes. + */ + + if (regval == 0) + { + break; + } + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_INTPENDING), (uint16_t)regval); + + /* OUT endpoint interrupt. The core sets this bit to indicate that an + * interrupt is pending on one of the OUT endpoints of the core. + */ + + if ((regval & OTGFS_GINT_OEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT), (uint16_t)regval); + stm32_epout_interrupt(priv); + stm32_putreg(OTGFS_GINT_OEP, STM32_OTGFS_GINTSTS); + } + + /* IN endpoint interrupt. The core sets this bit to indicate that + * an interrupt is pending on one of the IN endpoints of the core. + */ + + if ((regval & OTGFS_GINT_IEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN), (uint16_t)regval); + stm32_epin_interrupt(priv); + stm32_putreg(OTGFS_GINT_IEP, STM32_OTGFS_GINTSTS); + } + + /* Host/device mode mismatch error interrupt */ + +#ifdef CONFIG_DEBUG_USB + if ((regval & OTGFS_GINT_MMIS) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_MISMATCH), (uint16_t)regval); + stm32_putreg(OTGFS_GINT_MMIS, STM32_OTGFS_GINTSTS); + } +#endif + + /* Resume/remote wakeup detected interrupt */ + + if ((regval & OTGFS_GINT_WKUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_WAKEUP), (uint16_t)regval); + stm32_resumeinterrupt(priv); + stm32_putreg(OTGFS_GINT_WKUP, STM32_OTGFS_GINTSTS); + } + + /* USB suspend interrupt */ + + if ((regval & OTGFS_GINT_USBSUSP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSPEND), (uint16_t)regval); + stm32_suspendinterrupt(priv); + stm32_putreg(OTGFS_GINT_USBSUSP, STM32_OTGFS_GINTSTS); + } + + /* Start of frame interrupt */ + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + if ((regval & OTGFS_GINT_SOF) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SOF), (uint16_t)regval); + stm32_putreg(OTGFS_GINT_SOF, STM32_OTGFS_GINTSTS); + } +#endif + + /* RxFIFO non-empty interrupt. Indicates that there is at least one + * packet pending to be read from the RxFIFO. + */ + + if ((regval & OTGFS_GINT_RXFLVL) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RXFIFO), (uint16_t)regval); + stm32_rxinterrupt(priv); + stm32_putreg(OTGFS_GINT_RXFLVL, STM32_OTGFS_GINTSTS); + } + + /* USB reset interrupt */ + + if ((regval & OTGFS_GINT_USBRST) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVRESET), (uint16_t)regval); + + /* Perform the device reset */ + + stm32_usbreset(priv); + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + stm32_putreg(OTGFS_GINT_USBRST, STM32_OTGFS_GINTSTS); + return OK; + } + + /* Enumeration done interrupt */ + + if ((regval & OTGFS_GINT_ENUMDNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_ENUMDNE), (uint16_t)regval); + stm32_enuminterrupt(priv); + stm32_putreg(OTGFS_GINT_ENUMDNE, STM32_OTGFS_GINTSTS); + } + + /* Incomplete isochronous IN transfer interrupt. When the core finds + * non-empty any of the isochronous IN endpoint FIFOs scheduled for + * the current frame non-empty, the core generates an IISOIXFR + * interrupt. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if ((regval & OTGFS_GINT_IISOIXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOIXFR), (uint16_t)regval); + stm32_isocininterrupt(priv); + stm32_putreg(OTGFS_GINT_IISOIXFR, STM32_OTGFS_GINTSTS); + } + + /* Incomplete isochronous OUT transfer. For isochronous OUT + * endpoints, the XFRC interrupt may not always be asserted. If the + * core drops isochronous OUT data packets, the application could fail + * to detect the XFRC interrupt. The incomplete Isochronous OUT data + * interrupt indicates that an XFRC interrupt was not asserted on at + * least one of the isochronous OUT endpoints. At this point, the + * endpoint with the incomplete transfer remains enabled, but no active + * transfers remain in progress on this endpoint on the USB. + */ + + if ((regval & OTGFS_GINT_IISOOXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOOXFR), (uint16_t)regval); + stm32_isocoutinterrupt(priv); + stm32_putreg(OTGFS_GINT_IISOOXFR, STM32_OTGFS_GINTSTS); + } +#endif + + /* Session request/new session detected interrupt */ + +#ifdef CONFIG_USBDEV_VBUSSENSING + if ((regval & OTGFS_GINT_SRQ) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SRQ), (uint16_t)regval); + stm32_sessioninterrupt(priv); + stm32_putreg(OTGFS_GINT_SRQ, STM32_OTGFS_GINTSTS); + } + + /* OTG interrupt */ + + if ((regval & OTGFS_GINT_OTG) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OTG), (uint16_t)regval); + stm32_otginterrupt(priv); + stm32_putreg(OTGFS_GINT_OTG, STM32_OTGFS_GINTSTS); + } +#endif + } + + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_enablegonak + * + * Description: + * Enable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* First, make sure that there is no GNOAKEFF interrupt pending. */ + +#if 0 + stm32_putreg(OTGFS_GINT_GONAKEFF, STM32_OTGFS_GINTSTS); +#endif + + /* Enable Global OUT NAK mode in the core. */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval |= OTGFS_DCTL_SGONAK; + stm32_putreg(regval, STM32_OTGFS_DCTL); + +#if 0 + /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK + * mode is in effect. When the interrupt handler pops the OUTNAK word + * from the RxFIFO, the core sets the GONAKEFF interrupt. + */ + + while ((stm32_getreg(STM32_OTGFS_GINTSTS) & OTGFS_GINT_GONAKEFF) == 0); + stm32_putreg(OTGFS_GINT_GONAKEFF, STM32_OTGFS_GINTSTS); + +#else + /* Since we are in the interrupt handler, we cannot wait inline for the + * GONAKEFF because it cannot occur until service the RXFLVL global interrupt + * and pop the OUTNAK word from the RxFIFO. + * + * Perhaps it is sufficient to wait for Global OUT NAK status to be reported + * in OTGFS DCTL register? + */ + + while ((stm32_getreg(STM32_OTGFS_DCTL) & OTGFS_DCTL_GONSTS) == 0); +#endif +} + +/**************************************************************************** + * Name: stm32_disablegonak + * + * Description: + * Disable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_disablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval |= OTGFS_DCTL_CGONAK; + stm32_putreg(regval, STM32_OTGFS_DCTL); +} + +/**************************************************************************** + * Name: stm32_epout_configure + * + * Description: + * Configure an OUT endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTGFS_DOEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTGFS_DOEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTGFS_DOEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTGFS_DOEPCTL0_MPSIZ_64; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTGFS_DOEPCTL_MPSIZ_SHIFT); + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGFS_DOEPCTL_USBAEP) == 0) + { + if (regval & OTGFS_DOEPCTL_NAKSTS) + { + regval |= OTGFS_DOEPCTL_CNAK; + } + + regval &= ~(OTGFS_DOEPCTL_MPSIZ_MASK | OTGFS_DOEPCTL_EPTYP_MASK); + regval |= mpsiz; + regval |= (eptype << OTGFS_DOEPCTL_EPTYP_SHIFT); + regval |= (OTGFS_DOEPCTL_SD0PID | OTGFS_DOEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTGFS_DAINTMSK); + regval |= OTGFS_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTGFS_DAINTMSK); + return OK; +} + +/**************************************************************************** + * Name: stm32_epin_configure + * + * Description: + * Configure an IN endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTGFS_DIEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTGFS_DIEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTGFS_DIEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTGFS_DIEPCTL0_MPSIZ_64; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTGFS_DIEPCTL_MPSIZ_SHIFT); + } + + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGFS_DIEPCTL_USBAEP) == 0) + { + if (regval & OTGFS_DIEPCTL_NAKSTS) + { + regval |= OTGFS_DIEPCTL_CNAK; + } + + regval &= ~(OTGFS_DIEPCTL_MPSIZ_MASK | OTGFS_DIEPCTL_EPTYP_MASK | OTGFS_DIEPCTL_TXFNUM_MASK); + regval |= mpsiz; + regval |= (eptype << OTGFS_DIEPCTL_EPTYP_SHIFT); + regval |= (eptype << OTGFS_DIEPCTL_TXFNUM_SHIFT); + regval |= (OTGFS_DIEPCTL_SD0PID | OTGFS_DIEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTGFS_DAINTMSK); + regval |= OTGFS_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTGFS_DAINTMSK); + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_configure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + uint16_t maxpacket; + uint8_t eptype; + int ret; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialize EP capabilities */ + + maxpacket = GETUINT16(desc->mxpacketsize); + eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK; + + /* Setup Endpoint Control Register */ + + if (privep->isin) + { + ret = stm32_epin_configure(privep, eptype, maxpacket); + } + else + { + ret = stm32_epout_configure(privep, eptype, maxpacket); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv) +{ + /* Enable EP0 IN and OUT */ + + (void)stm32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); + (void)stm32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); +} + +/**************************************************************************** + * Name: stm32_epout_disable + * + * Description: + * Diable an OUT endpoint will no longer be used + * + ****************************************************************************/ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + /* Before disabling any OUT endpoint, the application must enable + * Global OUT NAK mode in the core. + */ + + flags = enter_critical_section(); + stm32_enablegonak(privep); + + /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits + * int DOECPTL register. + */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGFS_DOEPCTL_USBAEP; + regval |= (OTGFS_DOEPCTL_EPDIS | OTGFS_DOEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTGFS_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGFS_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTGFS_DOEPINT_EPDISD, STM32_OTGFS_DOEPINT(privep->epphy)); + + /* Then disable the Global OUT NAK mode to continue receiving data + * from other non-disabled OUT endpoints. + */ + + stm32_disablegonak(privep); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTGFS_DAINTMSK); + regval &= ~OTGFS_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTGFS_DAINTMSK); + + /* Cancel any queued read requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_epin_disable + * + * Description: + * Disable an IN endpoint when it will no longer be used + * + ****************************************************************************/ + +static void stm32_epin_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* After USB reset, the endpoint will already be deactivated by the + * hardware. Trying to disable again will just hang in the wait. + */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGFS_DIEPCTL_USBAEP) == 0) + { + return; + } + + /* This INEPNE wait logic is suggested by reference manual, but seems + * to get stuck to infinite loop. + */ + +#if 0 + /* Make sure that there is no pending IPEPNE interrupt (because we are + * to poll this bit below). + */ + + stm32_putreg(OTGFS_DIEPINT_INEPNE, STM32_OTGFS_DIEPINT(privep->epphy)); + + /* Set the endpoint in NAK mode */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGFS_DIEPCTL_USBAEP; + regval |= (OTGFS_DIEPCTL_EPDIS | OTGFS_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the INEPNE interrupt that indicates that we are now in NAK mode */ + + regaddr = STM32_OTGFS_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGFS_DIEPINT_INEPNE) == 0); + + /* Clear the INEPNE interrupt indication */ + + stm32_putreg(OTGFS_DIEPINT_INEPNE, regaddr); +#endif + + /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits + * the DIEPCTLx register. + */ + + flags = enter_critical_section(); + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGFS_DIEPCTL_USBAEP; + regval |= (OTGFS_DIEPCTL_EPDIS | OTGFS_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the IN + * endpoint is completely disabled. + */ + + regaddr = STM32_OTGFS_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGFS_DIEPINT_EPDISD) == 0); + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTGFS_DIEPINT_EPDISD, stm32_getreg(regaddr)); + + /* Flush any data remaining in the TxFIFO */ + + stm32_txfifo_flush(OTGFS_GRSTCTL_TXFNUM_D(privep->epphy)); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTGFS_DAINTMSK); + regval &= ~OTGFS_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTGFS_DAINTMSK); + + /* Cancel any queued write requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_ep_disable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + if (privep->isin) + { + /* Disable the IN endpoint */ + + stm32_epin_disable(privep); + } + else + { + /* Disable the OUT endpoint */ + + stm32_epout_disable(privep); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_allocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + + privreq = (FAR struct stm32_req_s *)kmm_malloc(sizeof(struct stm32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct stm32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: stm32_ep_freereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: stm32_ep_allocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_freebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_submit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + FAR struct stm32_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + + /* Some sanity checking */ + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint. */ + + if (stm32_req_addlast(privep, privreq) && !privep->active) + { + /* If a request was added to an IN endpoint, then attempt to send + * the request data buffer now. + */ + + if (privep->isin) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the endpoint is not busy with another write request, + * then process the newly received write request now. + */ + + if (!privep->active) + { + stm32_epin_request(priv, privep); + } + } + + /* If the request was added to an OUT endpoint, then attempt to + * setup a read into the request data buffer now (this will, of + * course, fail if there is already a read in place). + */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + stm32_epout_request(priv, privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_ep_cancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_epout_setstall + * + * Description: + * Stall an OUT endpoint + * + ****************************************************************************/ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep) +{ +#if 1 + /* This implementation follows the requirements from the STM32 F4 reference + * manual. + */ + + uint32_t regaddr; + uint32_t regval; + + /* Put the core in the Global OUT NAK mode */ + + stm32_enablegonak(privep); + + /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits + * in the DOECPTL register. + */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= (OTGFS_DOEPCTL_EPDIS | OTGFS_DOEPCTL_STALL); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTGFS_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGFS_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Disable Global OUT NAK mode */ + + stm32_disablegonak(privep); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#else + /* This implementation follows the STMicro code example. */ + /* REVISIT: */ + + uint32_t regaddr; + uint32_t regval; + + /* Stall the OUT endpoint by setting the STALL bit in the DOECPTL register. */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGFS_DOEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#endif +} + +/**************************************************************************** + * Name: stm32_epin_setstall + * + * Description: + * Stall an IN endpoint + * + ****************************************************************************/ + +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + + /* Get the IN endpoint device control register */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* Then stall the endpoint */ + + regval |= OTGFS_DIEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_setstall + * + * Description: + * Stall an endpoint + * + ****************************************************************************/ + +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep) +{ + usbtrace(TRACE_EPSTALL, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + return stm32_epin_setstall(privep); + } + else + { + return stm32_epout_setstall(privep); + } +} + +/**************************************************************************** + * Name: stm32_ep_clrstall + * + * Description: + * Resume a stalled endpoint + * + ****************************************************************************/ + +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t stallbit; + uint32_t data0bit; + + usbtrace(TRACE_EPRESUME, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTGFS_DIEPCTL(privep->epphy); + stallbit = OTGFS_DIEPCTL_STALL; + data0bit = OTGFS_DIEPCTL_SD0PID; + } + else + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + stallbit = OTGFS_DOEPCTL_STALL; + data0bit = OTGFS_DOEPCTL_SD0PID; + } + + /* Clear the stall bit */ + + regval = stm32_getreg(regaddr); + regval &= ~stallbit; + + /* Set the DATA0 pid for interrupt and bulk endpoints */ + + if (privep->eptype == USB_EP_ATTR_XFER_INT || + privep->eptype == USB_EP_ATTR_XFER_BULK) + { + /* Writing this bit sets the DATA0 PID */ + + regval |= data0bit; + } + + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer stalled */ + + privep->stalled = false; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_stall + * + * Description: + * Stall or resume an endpoint + * + ****************************************************************************/ + +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + int ret; + + /* Set or clear the stall condition as requested */ + + flags = enter_critical_section(); + if (resume) + { + ret = stm32_ep_clrstall(privep); + } + else + { + ret = stm32_ep_setstall(privep); + } + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_stall + * + * Description: + * Stall endpoint 0 + * + ****************************************************************************/ + +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv) +{ + stm32_epin_setstall(&priv->epin[EP0]); + stm32_epout_setstall(&priv->epout[EP0]); + priv->stalled = true; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ep_alloc + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t eplog, bool in, + uint8_t eptype) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint8_t epavail; + irqstate_t flags; + int epphy; + int epno = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + epphy = USB_EPNO(eplog); + + /* Get the set of available endpoints depending on the direction */ + + flags = enter_critical_section(); + epavail = priv->epavail[in]; + + /* A physical address of 0 means that any endpoint will do */ + + if (epphy > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epphy >= STM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPNO), (uint16_t)epphy); + return NULL; + } + + /* Remove all of the candidate endpoints from the bitset except for the + * this physical endpoint number. + */ + + epavail &= (1 << epphy); + } + + /* Is there an available endpoint? */ + + if (epavail) + { + /* Yes.. Select the lowest numbered endpoint in the set of available + * endpoints. + */ + + for (epno = 1; epno < STM32_NENDPOINTS; epno++) + { + uint8_t bit = 1 << epno; + if ((epavail & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail[in] &= ~(1 << epno); + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return in ? &priv->epin[epno].ep : &priv->epout[epno].ep; + } + } + + /* We should not get here */ + } + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOEP), (uint16_t)eplog); + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: stm32_ep_free + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void stm32_ep_free(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail[privep->isin] |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int stm32_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* Return the last frame number of the last SOF detected by the hardware */ + + regval = stm32_getreg(STM32_OTGFS_DSTS); + return (int)((regval & OTGFS_DSTS_SOFFN_MASK) >> OTGFS_DSTS_SOFFN_SHIFT); +} + +/**************************************************************************** + * Name: stm32_wakeup + * + * Description: + * Exit suspend mode. + * + ****************************************************************************/ + +static int stm32_wakeup(struct usbdev_s *dev) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + /* Is wakeup enabled? */ + + flags = enter_critical_section(); + if (priv->wakeup) + { + /* Yes... is the core suspended? */ + + regval = stm32_getreg(STM32_OTGFS_DSTS); + if ((regval & OTGFS_DSTS_SUSPSTS) != 0) + { + /* Re-start the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTGFS_PCGCCTL); + regval &= ~(OTGFS_PCGCCTL_STPPCLK | OTGFS_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTGFS_PCGCCTL); +#endif + /* Activate Remote wakeup signaling */ + + regval = stm32_getreg(STM32_OTGFS_DCTL); + regval |= OTGFS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGFS_DCTL); + up_mdelay(5); + regval &= ~OTGFS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGFS_DCTL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_selfpowered + * + * Description: + * Sets/clears the device self-powered feature + * + ****************************************************************************/ + +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: stm32_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int stm32_pullup(struct usbdev_s *dev, bool enable) +{ + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + regval = stm32_getreg(STM32_OTGFS_DCTL); + if (enable) + { + /* Connect the device by clearing the soft disconnect bit in the DCTL + * register + */ + + regval &= ~OTGFS_DCTL_SDIS; + } + else + { + /* Connect the device by setting the soft disconnect bit in the DCTL + * register + */ + + regval |= OTGFS_DCTL_SDIS; + } + + stm32_putreg(regval, STM32_OTGFS_DCTL); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static void stm32_setaddress(struct stm32_usbdev_s *priv, uint16_t address) +{ + uint32_t regval; + + /* Set the device address in the DCFG register */ + + regval = stm32_getreg(STM32_OTGFS_DCFG); + regval &= ~OTGFS_DCFG_DAD_MASK; + regval |= ((uint32_t)address << OTGFS_DCFG_DAD_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DCFG); + + /* Are we now addressed? (i.e., do we have a non-NULL device + * address?) + */ + + if (address != 0) + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->addressed = true; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + priv->addressed = false; + } +} + +/**************************************************************************** + * Name: stm32_txfifo_flush + * + * Description: + * Flush the specific TX fifo. + * + ****************************************************************************/ + +static int stm32_txfifo_flush(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTGFS_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(regval, STM32_OTGFS_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_rxfifo_flush + * + * Description: + * Flush the RX fifo. + * + ****************************************************************************/ + +static int stm32_rxfifo_flush(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(OTGFS_GRSTCTL_RXFFLSH, STM32_OTGFS_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_swinitialize + * + * Description: + * Initialize all driver data structures. + * + ****************************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + int i; + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct stm32_usbdev_s)); + + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->epin[EP0].ep; + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + priv->epin[EP0].ep.priv = priv; + priv->epout[EP0].ep.priv = priv; + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epin[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->isin = 1; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYIN2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epout[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYOUT2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } +} + +/**************************************************************************** + * Name: stm32_hwinitialize + * + * Description: + * Configure the OTG FS core for operation. + * + ****************************************************************************/ + +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + uint32_t timeout; + uint32_t address; + int i; + + /* At start-up the core is in FS mode. */ + + /* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG + * register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO + * interrupts will occur when the TxFIFO is truly empty (not just half full). + */ + + stm32_putreg(OTGFS_GAHBCFG_TXFELVL, STM32_OTGFS_GAHBCFG); + + /* Common USB OTG core initialization */ + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(OTGFS_GRSTCTL_CSRST, STM32_OTGFS_GRSTCTL); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + +#if defined(CONFIG_STM32_STM32F446) + /* In the case of the STM32F446 the meaning of the bit has changed to VBUS + * Detection Enable when set + */ + + regval = OTGFS_GCCFG_PWRDWN; + +# ifdef CONFIG_USBDEV_VBUSSENSING + regval |= OTGFS_GCCFG_VBDEN; +# endif + +#else + /* In the case of the the all others the meaning of the bit is No VBUS + * Sense when Set + */ + + regval = (OTGFS_GCCFG_PWRDWN | OTGFS_GCCFG_VBUSASEN | OTGFS_GCCFG_VBUSBSEN); +# ifndef CONFIG_USBDEV_VBUSSENSING + regval |= OTGFS_GCCFG_NOVBUSSENS; +# endif +# ifdef CONFIG_STM32_OTGFS_SOFOUTPUT + regval |= OTGFS_GCCFG_SOFOUTEN; +# endif +#endif + stm32_putreg(regval, STM32_OTGFS_GCCFG); + up_mdelay(20); + + /* For the new OTG controller in the F446 when VBUS sensing is not used we + * need to force the B session valid + */ + +#if defined(CONFIG_STM32_STM32F446) +# ifndef CONFIG_USBDEV_VBUSSENSING + regval = stm32_getreg(STM32_OTGFS_GOTGCTL); + regval |= (OTGFS_GOTGCTL_BVALOEN | OTGFS_GOTGCTL_BVALOVAL); + stm32_putreg(regval, STM32_OTGFS_GOTGCTL); +# endif +#endif + + /* Force Device Mode */ + + regval = stm32_getreg(STM32_OTGFS_GUSBCFG); + regval &= ~OTGFS_GUSBCFG_FHMOD; + regval |= OTGFS_GUSBCFG_FDMOD; + stm32_putreg(regval, STM32_OTGFS_GUSBCFG); + up_mdelay(50); + + /* Initialize device mode */ + /* Restart the PHY Clock */ + + stm32_putreg(0, STM32_OTGFS_PCGCCTL); + + /* Device configuration register */ + + regval = stm32_getreg(STM32_OTGFS_DCFG); + regval &= ~OTGFS_DCFG_PFIVL_MASK; + regval |= OTGFS_DCFG_PFIVL_80PCT; + stm32_putreg(regval, STM32_OTGFS_DCFG); + + /* Set full speed PHY */ + + regval = stm32_getreg(STM32_OTGFS_DCFG); + regval &= ~OTGFS_DCFG_DSPD_MASK; + regval |= OTGFS_DCFG_DSPD_FS; + stm32_putreg(regval, STM32_OTGFS_DCFG); + + /* Set Rx FIFO size */ + + stm32_putreg(STM32_RXFIFO_WORDS, STM32_OTGFS_GRXFSIZ); + + /* EP0 TX */ + + address = STM32_RXFIFO_WORDS; + regval = (address << OTGFS_DIEPTXF0_TX0FD_SHIFT) | + (STM32_EP0_TXFIFO_WORDS << OTGFS_DIEPTXF0_TX0FSA_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DIEPTXF0); + + /* EP1 TX */ + + address += STM32_EP0_TXFIFO_WORDS; + regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP1_TXFIFO_WORDS << OTGFS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DIEPTXF1); + + /* EP2 TX */ + + address += STM32_EP1_TXFIFO_WORDS; + regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP2_TXFIFO_WORDS << OTGFS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DIEPTXF2); + + /* EP3 TX */ + + address += STM32_EP2_TXFIFO_WORDS; + regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP3_TXFIFO_WORDS << OTGFS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DIEPTXF3); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTGFS_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* Clear all pending Device Interrupts */ + + stm32_putreg(0, STM32_OTGFS_DIEPMSK); + stm32_putreg(0, STM32_OTGFS_DOEPMSK); + stm32_putreg(0, STM32_OTGFS_DIEPEMPMSK); + stm32_putreg(0xffffffff, STM32_OTGFS_DAINT); + stm32_putreg(0, STM32_OTGFS_DAINTMSK); + + /* Configure all IN endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTGFS_DIEPCTL(i)); + if ((regval & OTGFS_DIEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTGFS_DIEPCTL_EPENA | OTGFS_DIEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTGFS_DIEPCTL(i)); + stm32_putreg(0, STM32_OTGFS_DIEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTGFS_DIEPINT(i)); + } + + /* Configure all OUT endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTGFS_DOEPCTL(i)); + if ((regval & OTGFS_DOEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTGFS_DOEPCTL_EPENA | OTGFS_DOEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTGFS_DOEPCTL(i)); + stm32_putreg(0, STM32_OTGFS_DOEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTGFS_DOEPINT(i)); + } + + /* Disable all interrupts. */ + + stm32_putreg(0, STM32_OTGFS_GINTMSK); + + /* Clear any pending USB_OTG Interrupts */ + + stm32_putreg(0xffffffff, STM32_OTGFS_GOTGINT); + + /* Clear any pending interrupts */ + + stm32_putreg(0xbfffffff, STM32_OTGFS_GINTSTS); + + /* Enable the interrupts in the INTMSK */ + + regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_ENUMDNE | + OTGFS_GINT_IEP | OTGFS_GINT_OEP | OTGFS_GINT_USBRST); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + regval |= (OTGFS_GINT_IISOIXFR | OTGFS_GINT_IISOOXFR); +#endif + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + regval |= OTGFS_GINT_SOF; +#endif + +#ifdef CONFIG_USBDEV_VBUSSENSING + regval |= (OTGFS_GINT_OTG | OTGFS_GINT_SRQ); +#endif + +#ifdef CONFIG_DEBUG_USB + regval |= OTGFS_GINT_MMIS; +#endif + + stm32_putreg(regval, STM32_OTGFS_GINTMSK); + + /* Enable the USB global interrupt by setting GINTMSK in the global OTG + * FS AHB configuration register; Set the TXFELVL bit in the GAHBCFG + * register so that TxFIFO interrupts will occur when the TxFIFO is truly + * empty (not just half full). + */ + + stm32_putreg(OTGFS_GAHBCFG_GINTMSK | OTGFS_GAHBCFG_TXFELVL, + STM32_OTGFS_GAHBCFG); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otgfsdev; + int ret; + + usbtrace(TRACE_DEVINIT, 0); + + /* Here we assume that: + * + * 1. GPIOA and OTG FS peripheral clocking has already been enabled as part + * of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG FS alternate function pins + * + * PIN* SIGNAL DIRECTION + * ---- ----------- ---------- + * PA8 OTG_FS_SOF SOF clock output + * PA9 OTG_FS_VBUS VBUS input for device, Driven by external regulator by + * host (not an alternate function) + * PA10 OTG_FS_ID OTG ID pin (only needed in Dual mode) + * PA11 OTG_FS_DM D- I/O + * PA12 OTG_FS_DP D+ I/O + * + * *Pins may vary from device-to-device. + */ + + stm32_configgpio(GPIO_OTGFS_DM); + stm32_configgpio(GPIO_OTGFS_DP); + stm32_configgpio(GPIO_OTGFS_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable. */ + +#ifdef CONFIG_STM32_OTGFS_SOFOUTPUT + stm32_configgpio(GPIO_OTGFS_SOF); +#endif + + /* Uninitialize the hardware so that we know that we are starting from a + * known state. */ + + up_usbuninitialize(); + + /* Initialie the driver data structure */ + + stm32_swinitialize(priv); + + /* Attach the OTG FS interrupt handler */ + + ret = irq_attach(STM32_IRQ_OTGFS, stm32_usbinterrupt); + if (ret < 0) + { + udbg("irq_attach failed\n", ret); + goto errout; + } + + /* Initialize the USB OTG core */ + + stm32_hwinitialize(priv); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + stm32_usbreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_OTGFS); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_OTGFS, CONFIG_OTGFS_PRI); +#endif + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otgfsdev; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + stm32_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(STM32_IRQ_OTGFS); + irq_detach(STM32_IRQ_OTGFS); + + /* Disable all endpoint interrupts */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + stm32_putreg(0xff, STM32_OTGFS_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTGFS_DOEPINT(i)); + } + + stm32_putreg(0, STM32_OTGFS_DIEPMSK); + stm32_putreg(0, STM32_OTGFS_DOEPMSK); + stm32_putreg(0, STM32_OTGFS_DIEPEMPMSK); + stm32_putreg(0, STM32_OTGFS_DAINTMSK); + stm32_putreg(0xffffffff, STM32_OTGFS_DAINT); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTGFS_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* TODO: Turn off USB power and clocking */ + + priv->devstate = DEVSTATE_DEFAULT; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otgfsdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(STM32_IRQ_OTGFS); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + stm32_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG FS device support. Hence it is + * pre-allocated as g_otgfsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otgfsdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + stm32_usbreset(priv); + leave_critical_section(flags); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts */ + + flags = enter_critical_section(); + up_disable_irq(STM32_IRQ_OTGFS); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_STM32_OTGFSDEV */ diff --git a/arch/arm/src/stm32/stm32_otgfshost.c b/arch/arm/src/stm32/stm32_otgfshost.c new file mode 100644 index 0000000000000000000000000000000000000000..81f6ded2697d4c576038b7bc699d319771118fb8 --- /dev/null +++ b/arch/arm/src/stm32/stm32_otgfshost.c @@ -0,0 +1,5306 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_otgfshost.c + * + * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" /* Includes default GPIO settings */ +#include /* May redefine GPIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32_usbhost.h" + +#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32_OTGFS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* STM32 USB OTG FS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_STM32_OTGFS - Enable the STM32 USB OTG FS block + * CONFIG_STM32_SYSCFG - Needed + * + * Options: + * + * CONFIG_STM32_OTGFS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_STM32_OTGFS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_STM32_OTGFS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_STM32_OTGFS_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_STM32_OTGFS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * CONFIG_STM32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG. + * CONFIG_STM32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * packets. Depends on CONFIG_DEBUG. + */ + +/* Pre-requisites (partial) */ + +#ifndef CONFIG_STM32_SYSCFG +# error "CONFIG_STM32_SYSCFG is required" +#endif + +/* Default RxFIFO size */ + +#ifndef CONFIG_STM32_OTGFS_RXFIFO_SIZE +# define CONFIG_STM32_OTGFS_RXFIFO_SIZE 128 +#endif + +/* Default host non-periodic Tx FIFO size */ + +#ifndef CONFIG_STM32_OTGFS_NPTXFIFO_SIZE +# define CONFIG_STM32_OTGFS_NPTXFIFO_SIZE 96 +#endif + +/* Default host periodic Tx fifo size register */ + +#ifndef CONFIG_STM32_OTGFS_PTXFIFO_SIZE +# define CONFIG_STM32_OTGFS_PTXFIFO_SIZE 96 +#endif + +/* Maximum size of a descriptor */ + +#ifndef CONFIG_STM32_OTGFS_DESCSIZE +# define CONFIG_STM32_OTGFS_DESCSIZE 128 +#endif + +/* Register/packet debug depends on CONFIG_DEBUG */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_STM32_USBHOST_REGDEBUG +# undef CONFIG_STM32_USBHOST_PKTDUMP +#endif + +/* HCD Setup *******************************************************************/ +/* Hardware capabilities */ + +#define STM32_NHOST_CHANNELS 8 /* Number of host channels */ +#define STM32_MAX_PACKET_SIZE 64 /* Full speed max packet size */ +#define STM32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */ +#define STM32_EP0_MAX_PACKET_SIZE 64 /* EP0 FS max packet size */ +#define STM32_MAX_TX_FIFOS 15 /* Max number of TX FIFOs */ +#define STM32_MAX_PKTCOUNT 256 /* Max packet count */ +#define STM32_RETRY_COUNT 3 /* Number of ctrl transfer retries */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 /* In loop counts */ +#define STM32_FLUSH_DELAY 200000 /* In loop counts */ +#define STM32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ +#define STM32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ + +/* Ever-present MIN/MAX macros */ + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The following enumeration represents the various states of the USB host + * state machine (for debug purposes only) + */ + +enum stm32_smstate_e +{ + SMSTATE_DETACHED = 0, /* Not attached to a device */ + SMSTATE_ATTACHED, /* Attached to a device */ + SMSTATE_ENUM, /* Attached, enumerating */ + SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */ +}; + +/* This enumeration provides the reason for the channel halt. */ + +enum stm32_chreason_e +{ + CHREASON_IDLE = 0, /* Inactive (initial state) */ + CHREASON_FREED, /* Channel is no longer in use */ + CHREASON_XFRC, /* Transfer complete */ + CHREASON_NAK, /* NAK received */ + CHREASON_NYET, /* NotYet received */ + CHREASON_STALL, /* Endpoint stalled */ + CHREASON_TXERR, /* Transfer error received */ + CHREASON_DTERR, /* Data toggle error received */ + CHREASON_FRMOR, /* Frame overrun */ + CHREASON_CANCELLED /* Transfer cancelled */ +}; + +/* This structure retains the state of one host channel. NOTE: Since there + * is only one channel operation active at a time, some of the fields in + * in the structure could be moved in struct stm32_ubhost_s to achieve + * some memory savings. + */ + +struct stm32_chan_s +{ + sem_t waitsem; /* Channel wait semaphore */ + volatile uint8_t result; /* The result of the transfer */ + volatile uint8_t chreason; /* Channel halt reason. See enum stm32_chreason_e */ + uint8_t chidx; /* Channel index */ + uint8_t epno; /* Device endpoint number (0-127) */ + uint8_t eptype; /* See OTGFS_EPTYPE_* definitions */ + uint8_t funcaddr; /* Device function address */ + uint8_t speed; /* Device speed */ + uint8_t pid; /* Data PID */ + uint8_t npackets; /* Number of packets (for data toggle) */ + bool inuse; /* True: This channel is "in use" */ + volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */ + volatile bool outdata1; /* OUT data toggle. True: DATA01 */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + uint16_t maxpacket; /* Max packet size */ + uint16_t buflen; /* Buffer length (at start of transfer) */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ + volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */ + FAR uint8_t *buffer; /* Transfer buffer pointer */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + FAR void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* A channel represents on uni-directional endpoint. So, in the case of the + * bi-directional, control endpoint, there must be two channels to represent + * the endpoint. + */ + +struct stm32_ctrlinfo_s +{ + uint8_t inndx; /* EP0 IN control channel index */ + uint8_t outndx; /* EP0 OUT control channel index */ +}; + +/* This structure retains the state of the USB host controller */ + +struct stm32_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to structstm32_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Overall driver status */ + + volatile uint8_t smstate; /* The state of the USB host state machine */ + uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */ + volatile bool connected; /* Connected to device */ + volatile bool change; /* Connection change */ + volatile bool pscwait; /* True: Thread is waiting for a port event */ + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for a port event */ + struct stm32_ctrlinfo_s ep0; /* Root hub port EP0 description */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* The state of each host channel */ + + struct stm32_chan_s chan[STM32_MAX_TX_FIFOS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t addr, uint32_t value); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(addr,val) putreg32(val,addr) +#endif + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits); + +#ifdef CONFIG_STM32_USBHOST_PKTDUMP +# define stm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) +#else +# define stm32_pktdump(m,b,n) +#endif + +/* Semaphores ******************************************************************/ + +static void stm32_takesem(sem_t *sem); +#define stm32_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val); + +/* Channel management **********************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv); +static inline void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx); +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv); +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx); +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason); +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep); +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); + +/* Control/data transfer logic *************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx); +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void); +#endif +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req); +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif + +/* Interrupt handling **********************************************************/ +/* Lower level interrupt handlers */ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen); +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv); +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv); + +/* Second level interrupt handlers */ + +#ifdef CONFIG_STM32_OTGFS_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv); +#endif +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv); + +/* First level, global interrupt handler */ + +static int stm32_gint_isr(int irq, FAR void *context); + +/* Interrupt controls */ + +static void stm32_gint_enable(void); +static void stm32_gint_disable(void); +static inline void stm32_hostinit_enable(void); +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx); + +/* USB host controller operations **********************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const FAR struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer); +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer); +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected); +#endif +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv); +static void stm32_flush_txfifos(uint32_t txfnum); +static void stm32_flush_rxfifo(void); +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state); +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv); + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv); +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct stm32_usbhost_s g_usbhost; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = stm32_wait, + .enumerate = stm32_enumerate, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_printreg + * + * Description: + * Print the contents of an STM32xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: stm32_checkreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + stm32_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + stm32_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static uint32_t stm32_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_putreg(uint32_t addr, uint32_t val) +{ + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_modifyreg + * + * Description: + * Modify selected bits of an STM32 register. + * + ****************************************************************************/ + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, uint32_t setbits) +{ + stm32_putreg(addr, (((stm32_getreg(addr)) & ~clrbits) | setbits)); +} + +/**************************************************************************** + * Name: stm32_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void stm32_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: stm32_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: stm32_chan_alloc + * + * Description: + * Allocate a channel. + * + ****************************************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv) +{ + int chidx; + + /* Search the table of channels */ + + for (chidx = 0; chidx < STM32_NHOST_CHANNELS; chidx++) + { + /* Is this channel available? */ + + if (!priv->chan[chidx].inuse) + { + /* Yes... make it "in use" and return the index */ + + priv->chan[chidx].inuse = true; + return chidx; + } + } + + /* All of the channels are "in-use" */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_chan_free + * + * Description: + * Free a previoiusly allocated channel. + * + ****************************************************************************/ + +static void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx) +{ + DEBUGASSERT((unsigned)chidx < STM32_NHOST_CHANNELS); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_FREED); + + /* Mark the channel available */ + + priv->chan[chidx].inuse = false; +} + +/**************************************************************************** + * Name: stm32_chan_freeall + * + * Description: + * Free all channels. + * + ****************************************************************************/ + +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv) +{ + uint8_t chidx; + + /* Free all host channels */ + + for (chidx = 2; chidx < STM32_NHOST_CHANNELS; chidx ++) + { + stm32_chan_free(priv, chidx); + } +} + +/**************************************************************************** + * Name: stm32_chan_configure + * + * Description: + * Configure or re-configure a host channel. Host channels are configured + * when endpoint is allocated and EP0 (only) is re-configured with the + * max packet size or device address changes. + * + ****************************************************************************/ + +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + + /* Clear any old pending interrupts for this host channel. */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), 0xffffffff); + + /* Enable channel interrupts required for transfers on this channel. */ + + regval = 0; + + switch (chan->eptype) + { + case OTGFS_EPTYPE_CTRL: + case OTGFS_EPTYPE_BULK: + { +#ifdef HAVE_USBHOST_TRACE_VERBOSE + uint16_t intrace; + uint16_t outtrace; + + /* Determine the definitive trace ID to use below */ + + if (chan->eptype == OTGFS_EPTYPE_CTRL) + { + intrace = OTGFS_VTRACE2_CHANCONF_CTRL_IN; + outtrace = OTGFS_VTRACE2_CHANCONF_CTRL_OUT; + } + else + { + intrace = OTGFS_VTRACE2_CHANCONF_BULK_IN; + outtrace = OTGFS_VTRACE2_CHANCONF_BULK_OUT; + } +#endif + + /* Interrupts required for CTRL and BULK endpoints */ + + regval |= (OTGFS_HCINT_XFRC | OTGFS_HCINT_STALL | OTGFS_HCINT_NAK | + OTGFS_HCINT_TXERR | OTGFS_HCINT_DTERR); + + /* Additional setting for IN/OUT endpoints */ + + if (chan->in) + { + usbhost_vtrace2(intrace, chidx, chan->epno); + regval |= OTGFS_HCINT_BBERR; + } + else + { + usbhost_vtrace2(outtrace, chidx, chan->epno); + regval |= OTGFS_HCINT_NYET; + } + } + break; + + case OTGFS_EPTYPE_INTR: + { + /* Interrupts required for INTR endpoints */ + + regval |= (OTGFS_HCINT_XFRC | OTGFS_HCINT_STALL | OTGFS_HCINT_NAK | + OTGFS_HCINT_TXERR | OTGFS_HCINT_FRMOR | OTGFS_HCINT_DTERR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTGFS_VTRACE2_CHANCONF_INTR_IN, chidx, + chan->epno); + regval |= OTGFS_HCINT_BBERR; + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTGFS_VTRACE2_CHANCONF_INTR_OUT, chidx, + chan->epno); + } +#endif + } + break; + + case OTGFS_EPTYPE_ISOC: + { + /* Interrupts required for ISOC endpoints */ + + regval |= (OTGFS_HCINT_XFRC | OTGFS_HCINT_ACK | OTGFS_HCINT_FRMOR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTGFS_VTRACE2_CHANCONF_ISOC_IN, chidx, + chan->epno); + regval |= (OTGFS_HCINT_TXERR | OTGFS_HCINT_BBERR); + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTGFS_VTRACE2_CHANCONF_ISOC_OUT, chidx, + chan->epno); + } +#endif + } + break; + } + + stm32_putreg(STM32_OTGFS_HCINTMSK(chidx), regval); + + /* Enable the top level host channel interrupt. */ + + stm32_modifyreg(STM32_OTGFS_HAINTMSK, 0, OTGFS_HAINT(chidx)); + + /* Make sure host channel interrupts are enabled. */ + + stm32_modifyreg(STM32_OTGFS_GINTMSK, 0, OTGFS_GINT_HC); + + /* Program the HCCHAR register */ + + regval = ((uint32_t)chan->maxpacket << OTGFS_HCCHAR_MPSIZ_SHIFT) | + ((uint32_t)chan->epno << OTGFS_HCCHAR_EPNUM_SHIFT) | + ((uint32_t)chan->eptype << OTGFS_HCCHAR_EPTYP_SHIFT) | + ((uint32_t)chan->funcaddr << OTGFS_HCCHAR_DAD_SHIFT); + + /* Special case settings for low speed devices */ + + if (chan->speed == USB_SPEED_LOW) + { + regval |= OTGFS_HCCHAR_LSDEV; + } + + /* Special case settings for IN endpoints */ + + if (chan->in) + { + regval |= OTGFS_HCCHAR_EPDIR_IN; + } + + /* Special case settings for INTR endpoints */ + + if (chan->eptype == OTGFS_EPTYPE_INTR) + { + regval |= OTGFS_HCCHAR_ODDFRM; + } + + /* Write the channel configuration */ + + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), regval); +} + +/**************************************************************************** + * Name: stm32_chan_halt + * + * Description: + * Halt the channel associated with 'chidx' by setting the CHannel DISable + * (CHDIS) bit in in the HCCHAR register. + * + ****************************************************************************/ + +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason) +{ + uint32_t hcchar; + uint32_t intmsk; + uint32_t eptype; + unsigned int avail; + + /* Save the reason for the halt. We need this in the channel halt interrupt + * handling logic to know what to do next. + */ + + usbhost_vtrace2(OTGFS_VTRACE2_CHANHALT, chidx, chreason); + + priv->chan[chidx].chreason = (uint8_t)chreason; + + /* "The application can disable any channel by programming the OTG_FS_HCCHARx + * register with the CHDIS and CHENA bits set to 1. This enables the OTG_FS + * host to flush the posted requests (if any) and generates a channel halted + * interrupt. The application must wait for the CHH interrupt in OTG_FS_HCINTx + * before reallocating the channel for other transactions. The OTG_FS host + * does not interrupt the transaction that has already been started on the + * USB." + */ + + hcchar = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + hcchar |= (OTGFS_HCCHAR_CHDIS | OTGFS_HCCHAR_CHENA); + + /* Get the endpoint type from the HCCHAR register */ + + eptype = hcchar & OTGFS_HCCHAR_EPTYP_MASK; + + /* Check for space in the Tx FIFO to issue the halt. + * + * "Before disabling a channel, the application must ensure that there is at + * least one free space available in the non-periodic request queue (when + * disabling a non-periodic channel) or the periodic request queue (when + * disabling a periodic channel). The application can simply flush the + * posted requests when the Request queue is full (before disabling the + * channel), by programming the OTG_FS_HCCHARx register with the CHDIS bit + * set to 1, and the CHENA bit cleared to 0. + */ + + if (eptype == OTGFS_HCCHAR_EPTYP_CTRL || eptype == OTGFS_HCCHAR_EPTYP_BULK) + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTGFS_HNPTXSTS) & OTGFS_HNPTXSTS_NPTXFSAV_MASK; + } + else /* if (eptype == OTGFS_HCCHAR_EPTYP_ISOC || eptype == OTGFS_HCCHAR_EPTYP_INTR) */ + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTGFS_HPTXSTS) & OTGFS_HPTXSTS_PTXFSAVL_MASK; + } + + /* Check if there is any space available in the Tx FIFO. */ + + if (avail == 0) + { + /* The Tx FIFO is full... disable the channel to flush the requests */ + + hcchar &= ~OTGFS_HCCHAR_CHENA; + } + + /* Unmask the CHannel Halted (CHH) interrupt */ + + intmsk = stm32_getreg(STM32_OTGFS_HCINTMSK(chidx)); + intmsk |= OTGFS_HCINT_CHH; + stm32_putreg(STM32_OTGFS_HCINTMSK(chidx), intmsk); + + /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */ + + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), hcchar); +} + +/**************************************************************************** + * Name: stm32_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been started. + * + ****************************************************************************/ + +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags; + int ret; + + /* Disable interrupts so that the following operations will be atomic. On + * the OTG FS global interrupt needs to be disabled. However, here we disable + * all interrupts to exploit that fact that interrupts will be re-enabled + * while we wait. + */ + + flags = enter_critical_section(); + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; 'waiter' + * will be set to false and 'result' will be set appropriately when the + * transfer is completed. + */ + + do + { + /* Wait for the transfer to complete. NOTE the transfer may already + * completed before we get here or the transfer may complete while we + * wait here. + */ + + ret = sem_wait(&chan->waitsem); + + /* sem_wait should succeed. But it is possible that we could be + * awakened by a signal too. + */ + + DEBUGASSERT(ret == OK || get_errno() == EINTR); + } + while (chan->waiter); + + /* The transfer is complete re-enable interrupts and return the result */ + + ret = -(int)chan->result; + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + /* Is the transfer complete? */ + + if (chan->result != EBUSY) + { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + /* Wake'em up! */ + + usbhost_vtrace2(chan->in ? OTGFS_VTRACE2_CHANWAKEUP_IN : + OTGFS_VTRACE2_CHANWAKEUP_OUT, + chan->epno, chan->result); + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + /* Handle continuation of IN/OUT pipes */ + + if (chan->in) + { + stm32_in_next(priv, chan); + } + else + { + stm32_out_next(priv, chan); + } + } +#endif + } +} + +/**************************************************************************** + * Name: stm32_ctrlchan_alloc + * + * Description: + * Allocate and configured channels for a control pipe. + * + ****************************************************************************/ + +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep) +{ + FAR struct stm32_chan_s *chan; + int inndx; + int outndx; + + outndx = stm32_chan_alloc(priv); + if (outndx < 0) + { + return -ENOMEM; + } + + ctrlep->outndx = outndx; + chan = &priv->chan[outndx]; + chan->epno = epno; + chan->in = false; + chan->eptype = OTGFS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control OUT channels */ + + stm32_chan_configure(priv, outndx); + + /* Allocate and initialize the control IN channel */ + + inndx = stm32_chan_alloc(priv); + if (inndx < 0) + { + stm32_chan_free(priv, outndx); + return -ENOMEM; + } + + ctrlep->inndx = inndx; + chan = &priv->chan[inndx]; + chan->epno = epno; + chan->in = true; + chan->eptype = OTGFS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control IN channels */ + + stm32_chan_configure(priv, inndx); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlep_alloc + * + * Description: + * Allocate a container and channels for control pipe. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct usbhost_hubport_s *hport; + FAR struct stm32_ctrlinfo_s *ctrlep; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a container for the control endpoint */ + + ctrlep = (FAR struct stm32_ctrlinfo_s *)kmm_malloc(sizeof(struct stm32_ctrlinfo_s)); + if (ctrlep == NULL) + { + udbg("ERROR: Failed to allocate control endpoint container\n"); + return -ENOMEM; + } + + /* Then allocate and configure the IN/OUT channnels */ + + ret = stm32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK, + hport->funcaddr, hport->speed, ctrlep); + if (ret < 0) + { + udbg("ERROR: stm32_ctrlchan_alloc failed: %d\n", ret); + kmm_free(ctrlep); + return ret; + } + + /* Return a pointer to the control pipe container as the pipe "handle" */ + + *ep = (usbhost_ep_t)ctrlep; + return OK; +} + +/************************************************************************************ + * Name: stm32_xfrep_alloc + * + * Description: + * Allocate and configure one unidirectional endpoint. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + FAR struct stm32_chan_s *chan; + int chidx; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a host channel for the endpoint */ + + chidx = stm32_chan_alloc(priv); + if (chidx < 0) + { + udbg("ERROR: Failed to allocate a host channel\n"); + return -ENOMEM; + } + + /* Decode the endpoint descriptor to initialize the channel data structures. + * Note: Here we depend on the fact that the endpoint point type is + * encoded in the same way in the endpoint descriptor as it is in the OTG + * HS hardware. + */ + + chan = &priv->chan[chidx]; + chan->epno = epdesc->addr & USB_EPNO_MASK; + chan->in = epdesc->in; + chan->eptype = epdesc->xfrtype; + chan->funcaddr = hport->funcaddr; + chan->speed = hport->speed; + chan->maxpacket = epdesc->mxpacketsize; + chan->indata1 = false; + chan->outdata1 = false; + + /* Then configure the endpoint */ + + stm32_chan_configure(priv, chidx); + + /* Return the index to the allocated channel as the endpoint "handle" */ + + *ep = (usbhost_ep_t)chidx; + return OK; +} + +/**************************************************************************** + * Name: stm32_transfer_start + * + * Description: + * Start at transfer on the select IN or OUT channel. + * + ****************************************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int npackets; + unsigned int maxpacket; + unsigned int avail; + unsigned int wrsize; + unsigned int minsize; + + /* Set up the initial state of the transfer */ + + chan = &priv->chan[chidx]; + + usbhost_vtrace2(OTGFS_VTRACE2_STARTTRANSFER, chidx, chan->buflen); + + chan->result = EBUSY; + chan->inflight = 0; + chan->xfrd = 0; + priv->chidx = chidx; + + /* Compute the expected number of packets associated to the transfer. + * If the transfer length is zero (or less than the size of one maximum + * size packet), then one packet is expected. + */ + + /* If the transfer size is greater than one packet, then calculate the + * number of packets that will be received/sent, including any partial + * final packet. + */ + + maxpacket = chan->maxpacket; + + if (chan->buflen > maxpacket) + { + npackets = (chan->buflen + maxpacket - 1) / maxpacket; + + /* Clip if the buffer length if it exceeds the maximum number of + * packets that can be transferred (this should not happen). + */ + + if (npackets > STM32_MAX_PKTCOUNT) + { + npackets = STM32_MAX_PKTCOUNT; + chan->buflen = STM32_MAX_PKTCOUNT * maxpacket; + usbhost_trace2(OTGFS_TRACE2_CLIP, chidx, chan->buflen); + } + } + else + { + /* One packet will be sent/received (might be a zero length packet) */ + + npackets = 1; + } + + /* If it is an IN transfer, then adjust the size of the buffer UP to + * a full number of packets. Hmmm... couldn't this cause an overrun + * into unallocated memory? + */ + +#if 0 /* Think about this */ + if (chan->in) + { + /* Force the buffer length to an even multiple of maxpacket */ + + chan->buflen = npackets * maxpacket; + } +#endif + + /* Save the number of packets in the transfer. We will need this in + * order to set the next data toggle correctly when the transfer + * completes. + */ + + chan->npackets = (uint8_t)npackets; + + /* Setup the HCTSIZn register */ + + regval = ((uint32_t)chan->buflen << OTGFS_HCTSIZ_XFRSIZ_SHIFT) | + ((uint32_t)npackets << OTGFS_HCTSIZ_PKTCNT_SHIFT) | + ((uint32_t)chan->pid << OTGFS_HCTSIZ_DPID_SHIFT); + stm32_putreg(STM32_OTGFS_HCTSIZ(chidx), regval); + + /* Setup the HCCHAR register: Frame oddness and host channel enable */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + + /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd + * Frame. This field is applicable for only periodic (isochronous and + * interrupt) channels. + */ + + if ((stm32_getreg(STM32_OTGFS_HFNUM) & 1) == 0) + { + regval |= OTGFS_HCCHAR_ODDFRM; + } + else + { + regval &= ~OTGFS_HCCHAR_ODDFRM; + } + + regval &= ~OTGFS_HCCHAR_CHDIS; + regval |= OTGFS_HCCHAR_CHENA; + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), regval); + + /* If this is an out transfer, then we need to do more.. we need to copy + * the outgoing data into the correct TxFIFO. + */ + + if (!chan->in && chan->buflen > 0) + { + /* Handle non-periodic (CTRL and BULK) OUT transfers differently than + * periodic (INTR and ISOC) OUT transfers. + */ + + minsize = MIN(chan->buflen, chan->maxpacket); + + switch (chan->eptype) + { + case OTGFS_EPTYPE_CTRL: /* Non periodic transfer */ + case OTGFS_EPTYPE_BULK: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTGFS_HNPTXSTS); + avail = ((regval & OTGFS_HNPTXSTS_NPTXFSAV_MASK) >> OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + } + break; + + /* Periodic transfer */ + + case OTGFS_EPTYPE_INTR: + case OTGFS_EPTYPE_ISOC: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTGFS_HPTXSTS); + avail = ((regval & OTGFS_HPTXSTS_PTXFSAVL_MASK) >> OTGFS_HPTXSTS_PTXFSAVL_SHIFT) << 2; + } + break; + + default: + DEBUGASSERT(false); + return; + } + + /* Is there space in the TxFIFO to hold the minimum size packet? */ + + if (minsize <= avail) + { + /* Yes.. Get the size of the biggest thing that we can put in the Tx FIFO now */ + + wrsize = chan->buflen; + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Write packet into the Tx FIFO. */ + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); + } + + /* Did we put the entire buffer into the Tx FIFO? */ + + if (chan->buflen > avail) + { + /* No, there was insufficient space to hold the entire transfer ... + * Enable the Tx FIFO interrupt to handle the transfer when the Tx + * FIFO becomes empty. + */ + + stm32_txfe_enable(priv, chidx); + } + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Get the current frame number. The frame number (FRNUM) field increments + * when a new SOF is transmitted on the USB, and is cleared to 0 when it + * reaches 0x3fff. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void) +{ + return (uint16_t)(stm32_getreg(STM32_OTGFS_HFNUM) & OTGFS_HFNUM_FRNUM_MASK); +} +#endif + +/**************************************************************************** + * Name: stm32_ctrl_sendsetup + * + * Description: + * Send an IN/OUT SETUP packet. + * + ****************************************************************************/ + +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop while the device reports NAK (and a timeout is not exceeded */ + + chan = &priv->chan[ep0->outndx]; + start = clock_systimer(); + + do + { + /* Send the SETUP packet */ + + chan->pid = OTGFS_PID_SETUP; + chan->buffer = (FAR uint8_t *)req; + chan->buflen = USB_SIZEOF_CTRLREQ; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete */ + + ret = stm32_chan_wait(priv, chan); + + /* Return on success and for all failures other than EAGAIN. EAGAIN + * means that the device NAKed the SETUP command and that we should + * try a few more times. + */ + + if (ret != -EAGAIN) + { + /* Output some debug information if the transfer failed */ + + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_TRNSFRFAILED, ret); + } + + /* Return the result in any event */ + + return ret; + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_SETUP_DELAY); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_ctrl_senddata + * + * Description: + * Send data in the data phase of an OUT control transfer. Or send status + * in the status phase of an IN control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->outndx]; + int ret; + + /* Save buffer information */ + + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set the DATA PID */ + + if (buflen == 0) + { + /* For status OUT stage with buflen == 0, set PID DATA1 */ + + chan->outdata1 = true; + } + + /* Set the Data PID as per the outdata1 boolean */ + + chan->pid = chan->outdata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_ctrl_recvdata + * + * Description: + * Receive data in the data phase of an IN control transfer. Or receive status + * in the status phase of an OUT control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->inndx]; + int ret; + + /* Save buffer information */ + + chan->pid = OTGFS_PID_DATA1; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->inndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_in_setup + * + * Description: + * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTGFS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTGFS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the IN data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_ISOCIN, chidx, chan->buflen); + chan->pid = OTGFS_PID_DATA0; + } + break; + + case OTGFS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_BULKIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0; + } + break; + + case OTGFS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_INTRIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_in_transfer + * + * Description: + * Transfer 'buflen' bytes into 'buffer' from an IN channel. + * + ****************************************************************************/ + +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + start = clock_systimer(); + while (chan->xfrd < chan->buflen) + { + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* EAGAIN indicates that the device NAKed the transfer and we need + * do try again. Anything else (success or other errors) will + * cause use to return + */ + + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + } + } + + return (ssize_t)chan->xfrd; +} + +/**************************************************************************** + * Name: stm32_in_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_in_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_in_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_out_setup + * + * Description: + * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTGFS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTGFS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the OUT data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_ISOCOUT, chidx, chan->buflen); + chan->pid = OTGFS_PID_DATA0; + } + break; + + case OTGFS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_BULKOUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0; + } + break; + + case OTGFS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTGFS_VTRACE2_INTROUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTGFS_PID_DATA1 : OTGFS_PID_DATA0; + + /* Toggle the OUT data PID for the next transfer */ + + chan->outdata1 ^= true; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_out_transfer + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' through an OUT channel. + * + ****************************************************************************/ + +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + size_t xfrlen; + ssize_t xfrd; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + start = clock_systimer(); + xfrd = 0; + + while (buflen > 0) + { + /* Transfer one packet at a time. The hardware is capable of queueing + * multiple OUT packets, but I just haven't figured out how to handle + * the case where a single OUT packet in the group is NAKed. + */ + + xfrlen = MIN(chan->maxpacket, buflen); + chan->buffer = buffer; + chan->buflen = xfrlen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* Handle transfer failures */ + + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Is this flush really necessary? What does the hardware do with the + * data in the FIFO when the NAK occurs? Does it discard it? + */ + + stm32_flush_txfifos(OTGFS_GRSTCTL_TXFNUM_HALL); + + /* Get the device a little time to catch up. Then retry the transfer + * using the same buffer pointer and length. + */ + + usleep(20*1000); + } + else + { + /* Successfully transferred. Update the buffer pointer and length */ + + buffer += xfrlen; + buflen -= xfrlen; + xfrd += chan->xfrd; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: stm32_out_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_out_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_out_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_gint_wrpacket + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with + * 'chidx' (non-DMA). + * + ****************************************************************************/ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen) +{ + FAR uint32_t *src; + uint32_t fifo; + int buflen32; + + stm32_pktdump("Sending", buffer, buflen); + + /* Get the number of 32-byte words associated with this byte size */ + + buflen32 = (buflen + 3) >> 2; + + /* Get the address of the Tx FIFO associated with this channel */ + + fifo = STM32_OTGFS_DFIFO_HCH(chidx); + + /* Transfer all of the data into the Tx FIFO */ + + src = (FAR uint32_t *)buffer; + for (; buflen32 > 0; buflen32--) + { + uint32_t data = *src++; + stm32_putreg(fifo, data); + } + + /* Increment the count of bytes "in-flight" in the Tx FIFO */ + + priv->chan[chidx].inflight += buflen; +} + +/**************************************************************************** + * Name: stm32_gint_hcinisr + * + * Description: + * USB OTG FS host IN channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTGFS_HCINT(chidx)); + regval = stm32_getreg(STM32_OTGFS_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTGFS_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_ACK); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTGFS_HCINT_STALL) != 0) + { + /* Clear the NAK and STALL Conditions. */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), (OTGFS_HCINT_NAK | OTGFS_HCINT_STALL)); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + + /* When there is a STALL, clear any pending NAK so that it is not + * processed below. + */ + + pending &= ~OTGFS_HCINT_NAK; + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if ((pending & OTGFS_HCINT_DTERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the NAK and data toggle error conditions */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), (OTGFS_HCINT_NAK | OTGFS_HCINT_DTERR)); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + if ((pending & OTGFS_HCINT_FRMOR) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the FRaMe OverRun (FRMOR) condition */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTGFS_HCINT_XFRC) != 0) + { + /* Clear the TransFeR Completed (XFRC) condition */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_XFRC); + + /* Then handle the transfer completion event based on the endpoint type */ + + if (chan->eptype == OTGFS_EPTYPE_CTRL || chan->eptype == OTGFS_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear any pending NAK condition. The 'indata1' data toggle + * should have been appropriately updated by the RxFIFO + * logic as each packet was received. + */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_NAK); + } + else if (chan->eptype == OTGFS_EPTYPE_INTR) + { + /* Force the next transfer on an ODD frame */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + regval |= OTGFS_HCCHAR_ODDFRM; + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), regval); + + /* Set the request done state */ + + chan->result = OK; + } + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTGFS_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTGFS_HCINTMSK(chidx)); + regval &= ~OTGFS_HCINT_CHH; + stm32_putreg(STM32_OTGFS_HCINTMSK(chidx), regval); + + /* Update the request state based on the host state machine state */ + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the request I/O error result */ + + chan->result = EIO; + } + else if (chan->chreason == CHREASON_NAK) + { + /* Halt on NAK only happens on an INTR channel. Fetch the HCCHAR register + * and check for an interrupt endpoint. + */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + if ((regval & OTGFS_HCCHAR_EPTYP_MASK) == OTGFS_HCCHAR_EPTYP_INTR) + { + /* Toggle the IN data toggle (Used by Bulk and INTR only) */ + + chan->indata1 ^= true; + } + + /* Set the NAK error result */ + + chan->result = EAGAIN; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame overrun error result */ + + chan->result = EPIPE; + } + + /* Clear the CHannel Halted (CHH) condition */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_CHH); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTGFS_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the Transaction ERror (TXERR) condition */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_TXERR); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTGFS_HCINT_NAK) != 0) + { + /* For a BULK transfer, the hardware is capable of retrying + * automatically on a NAK. However, this is not always + * what we need to do. So we always halt the transfer and + * return control to high level logic in the event of a NAK. + */ + +#if 1 + /* Halt the interrupt channel */ + + if (chan->eptype == OTGFS_EPTYPE_INTR) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + } + + /* Re-activate CTRL and BULK channels. + * REVISIT: This can cause a lot of interrupts! + */ + + else if (chan->eptype == OTGFS_EPTYPE_CTRL || + chan->eptype == OTGFS_EPTYPE_BULK) + { + /* Re-activate the channel by clearing CHDIS and assuring that + * CHENA is set + */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + regval |= OTGFS_HCCHAR_CHENA; + regval &= ~OTGFS_HCCHAR_CHDIS; + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), regval); + } +#else + /* Halt all transfers on the NAK -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); +#endif + + /* Clear the NAK condition */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_NAK); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_hcoutisr + * + * Description: + * USB OTG FS host OUT channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTGFS_HCINT(chidx)); + regval = stm32_getreg(STM32_OTGFS_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTGFS_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_ACK); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + else if ((pending & OTGFS_HCINT_FRMOR) != 0) + { + /* Halt the channel (probably not necessary for FRMOR) */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTGFS_HCINT_XFRC) != 0) + { + /* Decrement the number of bytes remaining by the number of + * bytes that were "in-flight". + */ + + priv->chan[chidx].buffer += priv->chan[chidx].inflight; + priv->chan[chidx].xfrd += priv->chan[chidx].inflight; + priv->chan[chidx].inflight = 0; + + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear the pending the TransFeR Completed (XFRC) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_XFRC); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTGFS_HCINT_STALL) != 0) + { + /* Clear the pending the STALL response receiv (STALL) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_STALL); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTGFS_HCINT_NAK) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + + /* Clear the pending the NAK response received (NAK) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_NAK); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTGFS_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the pending the Transaction ERror (TXERR) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_TXERR); + } + + /* Check for a NYET interrupt */ + +#if 0 /* NYET is a reserved bit in the HCINT register */ + else if ((pending & OTGFS_HCINT_NYET) != 0) + { + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_NYET); + + /* Clear the pending the NYET interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_NYET); + } +#endif + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if (pending & OTGFS_HCINT_DTERR) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), (OTGFS_HCINT_DTERR | OTGFS_HCINT_NAK)); + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTGFS_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTGFS_HCINTMSK(chidx)); + regval &= ~OTGFS_HCINT_CHH; + stm32_putreg(STM32_OTGFS_HCINTMSK(chidx), regval); + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + + /* Read the HCCHAR register to get the HCCHAR register to get + * the endpoint type. + */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + + /* Is it a bulk endpoint? Were an odd number of packets + * transferred? + */ + + if ((regval & OTGFS_HCCHAR_EPTYP_MASK) == OTGFS_HCCHAR_EPTYP_BULK && + (chan->npackets & 1) != 0) + { + /* Yes to both... toggle the data out PID */ + + chan->outdata1 ^= true; + } + } + else if (chan->chreason == CHREASON_NAK || + chan->chreason == CHREASON_NYET) + { + /* Set the try again later result */ + + chan->result = EAGAIN; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the I/O failure result */ + + chan->result = EIO; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame error result */ + + chan->result = EPIPE; + } + + /* Clear the pending the CHannel Halted (CHH) interrupt */ + + stm32_putreg(STM32_OTGFS_HCINT(chidx), OTGFS_HCINT_CHH); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_connected + * + * Description: + * Handle a connection event. + * + ****************************************************************************/ + +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv) +{ + /* We we previously disconnected? */ + + if (!priv->connected) + { + /* Yes.. then now we are connected */ + + usbhost_vtrace1(OTGFS_VTRACE1_CONNECTED, 0); + priv->connected = true; + priv->change = true; + DEBUGASSERT(priv->smstate == SMSTATE_DETACHED); + + /* Notify any waiters */ + + priv->smstate = SMSTATE_ATTACHED; + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_disconnected + * + * Description: + * Handle a disconnection event. + * + ****************************************************************************/ + +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv) +{ + /* Were we previously connected? */ + + if (priv->connected) + { + /* Yes.. then we no longer connected */ + + usbhost_vtrace1(OTGFS_VTRACE1_DISCONNECTED, 0); + + /* Are we bound to a class driver? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class driver */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Re-Initialize Host for new Enumeration */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = true; + stm32_chan_freeall(priv); + + priv->rhport.hport.speed = USB_SPEED_FULL; + + /* Notify any waiters that there is a change in the connection state */ + + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_sofisr + * + * Description: + * USB OTG FS start-of-frame interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_OTGFS_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle SOF interrupt */ +#warning "Do what?" + + /* Clear pending SOF interrupt */ + + stm32_putreg(STM32_OTGFS_GINTSTS, OTGFS_GINT_SOF); +} +#endif + +/**************************************************************************** + * Name: stm32_gint_rxflvlisr + * + * Description: + * USB OTG FS RxFIFO non-empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv) +{ + FAR uint32_t *dest; + uint32_t grxsts; + uint32_t intmsk; + uint32_t hcchar; + uint32_t hctsiz; + uint32_t fifo; + int bcnt; + int bcnt32; + int chidx; + int i; + + /* Disable the RxFIFO non-empty interrupt */ + + intmsk = stm32_getreg(STM32_OTGFS_GINTMSK); + intmsk &= ~OTGFS_GINT_RXFLVL; + stm32_putreg(STM32_OTGFS_GINTMSK, intmsk); + + /* Read and pop the next status from the Rx FIFO */ + + grxsts = stm32_getreg(STM32_OTGFS_GRXSTSP); + ullvdbg("GRXSTS: %08x\n", grxsts); + + /* Isolate the channel number/index in the status word */ + + chidx = (grxsts & OTGFS_GRXSTSH_CHNUM_MASK) >> OTGFS_GRXSTSH_CHNUM_SHIFT; + + /* Get the host channel characteristics register (HCCHAR) for this channel */ + + hcchar = stm32_getreg(STM32_OTGFS_HCCHAR(chidx)); + + /* Then process the interrupt according to the packet status */ + + switch (grxsts & OTGFS_GRXSTSH_PKTSTS_MASK) + { + case OTGFS_GRXSTSH_PKTSTS_INRECVD: /* IN data packet received */ + { + /* Read the data into the host buffer. */ + + bcnt = (grxsts & OTGFS_GRXSTSH_BCNT_MASK) >> OTGFS_GRXSTSH_BCNT_SHIFT; + if (bcnt > 0 && priv->chan[chidx].buffer != NULL) + { + /* Transfer the packet from the Rx FIFO into the user buffer */ + + dest = (FAR uint32_t *)priv->chan[chidx].buffer; + fifo = STM32_OTGFS_DFIFO_HCH(0); + bcnt32 = (bcnt + 3) >> 2; + + for (i = 0; i < bcnt32; i++) + { + *dest++ = stm32_getreg(fifo); + } + + stm32_pktdump("Received", priv->chan[chidx].buffer, bcnt); + + /* Toggle the IN data pid (Used by Bulk and INTR only) */ + + priv->chan[chidx].indata1 ^= true; + + /* Manage multiple packet transfers */ + + priv->chan[chidx].buffer += bcnt; + priv->chan[chidx].xfrd += bcnt; + + /* Check if more packets are expected */ + + hctsiz = stm32_getreg(STM32_OTGFS_HCTSIZ(chidx)); + if ((hctsiz & OTGFS_HCTSIZ_PKTCNT_MASK) != 0) + { + /* Re-activate the channel when more packets are expected */ + + hcchar |= OTGFS_HCCHAR_CHENA; + hcchar &= ~OTGFS_HCCHAR_CHDIS; + stm32_putreg(STM32_OTGFS_HCCHAR(chidx), hcchar); + } + } + } + break; + + case OTGFS_GRXSTSH_PKTSTS_INDONE: /* IN transfer completed */ + case OTGFS_GRXSTSH_PKTSTS_DTOGERR: /* Data toggle error */ + case OTGFS_GRXSTSH_PKTSTS_HALTED: /* Channel halted */ + default: + break; + } + + /* Re-enable the RxFIFO non-empty interrupt */ + + intmsk |= OTGFS_GINT_RXFLVL; + stm32_putreg(STM32_OTGFS_GINTMSK, intmsk); +} + +/**************************************************************************** + * Name: stm32_gint_nptxfeisr + * + * Description: + * USB OTG FS non-periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the NPTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTGFS_GINTMSK, OTGFS_GINT_NPTXFE, 0); + return; + } + + /* Read the status from the top of the non-periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTGFS_HNPTXSTS); + + /* Extract the number of bytes available in the non-periodic Tx FIFO. */ + + avail = ((regval & OTGFS_HNPTXSTS_NPTXFSAV_MASK) >> OTGFS_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further NPTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTGFS_GINTMSK, OTGFS_GINT_NPTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HNPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_ptxfeisr + * + * Description: + * USB OTG FS periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transfered the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the PTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTGFS_GINTMSK, OTGFS_GINT_PTXFE, 0); + return; + } + + /* Read the status from the top of the periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTGFS_HPTXSTS); + + /* Extract the number of bytes available in the periodic Tx FIFO. */ + + avail = ((regval & OTGFS_HPTXSTS_PTXFSAVL_MASK) >> OTGFS_HPTXSTS_PTXFSAVL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further PTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTGFS_GINTMSK, OTGFS_GINT_PTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_hcisr + * + * Description: + * USB OTG FS host channels interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t haint; + uint32_t hcchar; + int i = 0; + + /* Read the Host all channels interrupt register and test each bit in the + * register. Each bit i, i=0...(STM32_NHOST_CHANNELS-1), corresponds to + * a pending interrupt on channel i. + */ + + haint = stm32_getreg(STM32_OTGFS_HAINT); + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + /* Is an interrupt pending on this channel? */ + + if ((haint & OTGFS_HAINT(i)) != 0) + { + /* Yes... read the HCCHAR register to get the direction bit */ + + hcchar = stm32_getreg(STM32_OTGFS_HCCHAR(i)); + + /* Was this an interrupt on an IN or an OUT channel? */ + + if ((hcchar & OTGFS_HCCHAR_EPDIR) != 0) + { + /* Handle the HC IN channel interrupt */ + + stm32_gint_hcinisr(priv, i); + } + else + { + /* Handle the HC OUT channel interrupt */ + + stm32_gint_hcoutisr(priv, i); + } + } + } +} + +/**************************************************************************** + * Name: stm32_gint_hprtisr + * + * Description: + * USB OTG FS host port interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t hprt; + uint32_t newhprt; + uint32_t hcfg; + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT, 0); + /* Read the port status and control register (HPRT) */ + + hprt = stm32_getreg(STM32_OTGFS_HPRT); + + /* Setup to clear the interrupt bits in GINTSTS by setting the corresponding + * bits in the HPRT. The HCINT interrupt bit is cleared when the appropriate + * status bits in the HPRT register are cleared. + */ + + newhprt = hprt & ~(OTGFS_HPRT_PENA | OTGFS_HPRT_PCDET | + OTGFS_HPRT_PENCHNG | OTGFS_HPRT_POCCHNG); + + /* Check for Port Overcurrent CHaNGe (POCCHNG) */ + + if ((hprt & OTGFS_HPRT_POCCHNG) != 0) + { + /* Set up to clear the POCCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_POCCHNG, 0); + newhprt |= OTGFS_HPRT_POCCHNG; + } + + /* Check for Port Connect DETected (PCDET). The core sets this bit when a + * device connection is detected. + */ + + if ((hprt & OTGFS_HPRT_PCDET) != 0) + { + /* Set up to clear the PCDET status in the new HPRT contents. Then + * process the new connection event. + */ + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_PCDET, 0); + newhprt |= OTGFS_HPRT_PCDET; + stm32_portreset(priv); + stm32_gint_connected(priv); + } + + /* Check for Port Enable CHaNGed (PENCHNG) */ + + if ((hprt & OTGFS_HPRT_PENCHNG) != 0) + { + /* Set up to clear the PENCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_PENCHNG, 0); + newhprt |= OTGFS_HPRT_PENCHNG; + + /* Was the port enabled? */ + + if ((hprt & OTGFS_HPRT_PENA) != 0) + { + /* Yes.. handle the new connection event */ + + stm32_gint_connected(priv); + + /* Check the Host ConFiGuration register (HCFG) */ + + hcfg = stm32_getreg(STM32_OTGFS_HCFG); + + /* Is this a low speed or full speed connection (OTG FS does not + * support high speed) + */ + + if ((hprt & OTGFS_HPRT_PSPD_MASK) == OTGFS_HPRT_PSPD_LS) + { + /* Set the Host Frame Interval Register for the 6KHz speed */ + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_LSDEV, 0); + stm32_putreg(STM32_OTGFS_HFIR, 6000); + + /* Are we switching from FS to LS? */ + + if ((hcfg & OTGFS_HCFG_FSLSPCS_MASK) != OTGFS_HCFG_FSLSPCS_LS6MHz) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_FSLSSW, 0); + + /* Yes... configure for LS */ + + hcfg &= ~OTGFS_HCFG_FSLSPCS_MASK; + hcfg |= OTGFS_HCFG_FSLSPCS_LS6MHz; + stm32_putreg(STM32_OTGFS_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + else /* if ((hprt & OTGFS_HPRT_PSPD_MASK) == OTGFS_HPRT_PSPD_FS) */ + { + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_FSDEV, 0); + stm32_putreg(STM32_OTGFS_HFIR, 48000); + + /* Are we switching from LS to FS? */ + + if ((hcfg & OTGFS_HCFG_FSLSPCS_MASK) != OTGFS_HCFG_FSLSPCS_FS48MHz) + { + + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HPRT_LSFSSW, 0); + /* Yes... configure for FS */ + + hcfg &= ~OTGFS_HCFG_FSLSPCS_MASK; + hcfg |= OTGFS_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTGFS_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + } + } + + /* Clear port interrupts by setting bits in the HPRT */ + + stm32_putreg(STM32_OTGFS_HPRT, newhprt); +} + +/**************************************************************************** + * Name: stm32_gint_discisr + * + * Description: + * USB OTG FS disconnect detected interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle the disconnection event */ + + stm32_gint_disconnected(priv); + + /* Clear the dicsonnect interrupt */ + + stm32_putreg(STM32_OTGFS_GINTSTS, OTGFS_GINT_DISC); +} + +/**************************************************************************** + * Name: stm32_gint_ipxfrisr + * + * Description: + * USB OTG FS incomplete periodic interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + /* CHENA : Set to enable the channel + * CHDIS : Set to stop transmitting/receiving data on a channel + */ + + regval = stm32_getreg(STM32_OTGFS_HCCHAR(0)); + regval |= (OTGFS_HCCHAR_CHDIS | OTGFS_HCCHAR_CHENA); + stm32_putreg(STM32_OTGFS_HCCHAR(0), regval); + + /* Clear the incomplete isochronous OUT interrupt */ + + stm32_putreg(STM32_OTGFS_GINTSTS, OTGFS_GINT_IPXFR); +} + +/**************************************************************************** + * Name: stm32_gint_isr + * + * Description: + * USB OTG FS global interrupt handler + * + ****************************************************************************/ + +static int stm32_gint_isr(int irq, FAR void *context) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + uint32_t pending; + + /* If OTG were supported, we would need to check if we are in host or + * device mode when the global interrupt occurs. Here we support only + * host mode + */ + + /* Loop while there are pending interrupts to process. This loop may save a + * little interrupt handling overhead. + */ + + for (; ; ) + { + /* Get the unmasked bits in the GINT status */ + + pending = stm32_getreg(STM32_OTGFS_GINTSTS); + pending &= stm32_getreg(STM32_OTGFS_GINTMSK); + + /* Return from the interrupt when there are no further pending + * interrupts. + */ + + if (pending == 0) + { + return OK; + } + + /* Otherwise, process each pending, unmasked GINT interrupts */ + + /* Handle the start of frame interrupt */ + +#ifdef CONFIG_STM32_OTGFS_SOFINTR + if ((pending & OTGFS_GINT_SOF) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_SOF, 0); + stm32_gint_sofisr(priv); + } +#endif + + /* Handle the RxFIFO non-empty interrupt */ + + if ((pending & OTGFS_GINT_RXFLVL) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_RXFLVL, 0); + stm32_gint_rxflvlisr(priv); + } + + /* Handle the non-periodic TxFIFO empty interrupt */ + + if ((pending & OTGFS_GINT_NPTXFE) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_NPTXFE, 0); + stm32_gint_nptxfeisr(priv); + } + + /* Handle the periodic TxFIFO empty interrupt */ + + if ((pending & OTGFS_GINT_PTXFE) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_PTXFE, 0); + stm32_gint_ptxfeisr(priv); + } + + /* Handle the host channels interrupt */ + + if ((pending & OTGFS_GINT_HC) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_HC, 0); + stm32_gint_hcisr(priv); + } + + /* Handle the host port interrupt */ + + if ((pending & OTGFS_GINT_HPRT) != 0) + { + stm32_gint_hprtisr(priv); + } + + /* Handle the disconnect detected interrupt */ + + if ((pending & OTGFS_GINT_DISC) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_DISC, 0); + stm32_gint_discisr(priv); + } + + /* Handle the incomplete periodic transfer */ + + if ((pending & OTGFS_GINT_IPXFR) != 0) + { + usbhost_vtrace1(OTGFS_VTRACE1_GINT_IPXFR, 0); + stm32_gint_ipxfrisr(priv); + } + } + + /* We won't get here */ + + return OK; +} + +/**************************************************************************** + * Name: stm32_gint_enable and stm32_gint_disable + * + * Description: + * Respectively enable or disable the global OTG FS interrupt. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_gint_enable(void) +{ + uint32_t regval; + + /* Set the GINTMSK bit to unmask the interrupt */ + + regval = stm32_getreg(STM32_OTGFS_GAHBCFG); + regval |= OTGFS_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTGFS_GAHBCFG, regval); +} + +static void stm32_gint_disable(void) +{ + uint32_t regval; + + /* Clear the GINTMSK bit to mask the interrupt */ + + regval = stm32_getreg(STM32_OTGFS_GAHBCFG); + regval &= ~OTGFS_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTGFS_GAHBCFG, regval); +} + +/**************************************************************************** + * Name: stm32_hostinit_enable + * + * Description: + * Enable host interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_hostinit_enable(void) +{ + uint32_t regval; + + /* Disable all interrupts. */ + + stm32_putreg(STM32_OTGFS_GINTMSK, 0); + + /* Clear any pending interrupts. */ + + stm32_putreg(STM32_OTGFS_GINTSTS, 0xffffffff); + + /* Clear any pending USB OTG Interrupts (should be done elsewhere if OTG is supported) */ + + stm32_putreg(STM32_OTGFS_GOTGINT, 0xffffffff); + + /* Clear any pending USB OTG interrupts */ + + stm32_putreg(STM32_OTGFS_GINTSTS, 0xbfffffff); + + /* Enable the host interrupts */ + /* Common interrupts: + * + * OTGFS_GINT_WKUP : Resume/remote wakeup detected interrupt + * OTGFS_GINT_USBSUSP : USB suspend + */ + + regval = (OTGFS_GINT_WKUP | OTGFS_GINT_USBSUSP); + + /* If OTG were supported, we would need to enable the following as well: + * + * OTGFS_GINT_OTG : OTG interrupt + * OTGFS_GINT_SRQ : Session request/new session detected interrupt + * OTGFS_GINT_CIDSCHG : Connector ID status change + */ + + /* Host-specific interrupts + * + * OTGFS_GINT_SOF : Start of frame + * OTGFS_GINT_RXFLVL : RxFIFO non-empty + * OTGFS_GINT_IISOOXFR : Incomplete isochronous OUT transfer + * OTGFS_GINT_HPRT : Host port interrupt + * OTGFS_GINT_HC : Host channels interrupt + * OTGFS_GINT_DISC : Disconnect detected interrupt + */ + +#ifdef CONFIG_STM32_OTGFS_SOFINTR + regval |= (OTGFS_GINT_SOF | OTGFS_GINT_RXFLVL | OTGFS_GINT_IISOOXFR | + OTGFS_GINT_HPRT | OTGFS_GINT_HC | OTGFS_GINT_DISC); +#else + regval |= (OTGFS_GINT_RXFLVL | OTGFS_GINT_IPXFR | OTGFS_GINT_HPRT | + OTGFS_GINT_HC | OTGFS_GINT_DISC); +#endif + stm32_putreg(STM32_OTGFS_GINTMSK, regval); +} + +/**************************************************************************** + * Name: stm32_txfe_enable + * + * Description: + * Enable Tx FIFO empty interrupts. This is necessary when the entire + * transfer will not fit into Tx FIFO. The transfer will then be completed + * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled + * the fifo empty interrupt handler when the transfer is complete. + * + * Input Parameters: + * priv - Driver state structure reference + * chidx - The channel that requires the Tx FIFO empty interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Called from user task context. Interrupts must be disabled to assure + * exclusive access to the GINTMSK register. + * + ****************************************************************************/ + +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + irqstate_t flags; + uint32_t regval; + + /* Disable all interrupts so that we have exclusive access to the GINTMSK + * (it would be sufficent just to disable the GINT interrupt). + */ + + flags = enter_critical_section(); + + /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */ + + regval = stm32_getreg(STM32_OTGFS_GINTMSK); + switch (chan->eptype) + { + default: + case OTGFS_EPTYPE_CTRL: /* Non periodic transfer */ + case OTGFS_EPTYPE_BULK: + regval |= OTGFS_GINT_NPTXFE; + break; + + case OTGFS_EPTYPE_INTR: /* Periodic transfer */ + case OTGFS_EPTYPE_ISOC: + regval |= OTGFS_GINT_PTXFE; + break; + } + + /* Enable interrupts */ + + stm32_putreg(STM32_OTGFS_GINTMSK, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + + /* Loop until a change in connection state is detected */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + + /* Yes. Remember the new state */ + + connport->connected = priv->connected; + priv->change = false; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + uvdbg("RHport Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + uvdbg("Hub port Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + stm32_takesem(&priv->pscsem); + } +} + +/**************************************************************************** + * Name: stm32_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + uint32_t regval; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + usbhost_trace1(OTGFS_TRACE1_DEVDISCONN, 0); + return -ENODEV; + } + + DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED); + + /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */ + + usleep(100*1000); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Get the current device speed */ + + regval = stm32_getreg(STM32_OTGFS_HPRT); + if ((regval & OTGFS_HPRT_PSPD_MASK) == OTGFS_HPRT_PSPD_LS) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + /* Allocate and initialize the root hub port EP0 channels */ + + ret = stm32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, &priv->ep0); + if (ret < 0) + { + udbg("ERROR: Failed to allocate a control endpoint: %d\n", ret); + } + + return ret; +} + +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = stm32_rh_enumerate(priv, conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uvdbg("Enumerate the device\n"); + priv->smstate = SMSTATE_ENUM; + ret = usbhost_enumerate(hport, &hport->devclass); + + /* The enumeration may fail either because of some HCD interfaces failure + * or because the device class is not supported. In either case, we just + * need to perform the disconnection operation and make ready for a new + * enumeration. + */ + + if (ret < 0) + { + /* Return to the disconnected state */ + + udbg("ERROR: Enumeration failed: %d\n", ret); + stm32_gint_disconnected(priv); + } + + return ret; +} + +/************************************************************************************ + * Name: stm32_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support an + * external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + FAR struct stm32_chan_s *chan; + + DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 && + maxpacketsize <= 64); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Configure the EP0 OUT channel */ + + chan = &priv->chan[ep0info->outndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->outndx); + + /* Configure the EP0 IN channel */ + + chan = &priv->chan[ep0info->inndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->inndx); + + stm32_givesem(&priv->exclsem); + return OK; +} + +/************************************************************************************ + * Name: stm32_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handler control pipes differently from other endpoint types. This is + * because the normal, "transfer" endpoints are unidirectional an require + * only a single channel. Control endpoints, however, are bi-diretional + * and require two channels, one for the IN and one for the OUT direction. + */ + + if (epdesc->xfrtype == OTGFS_EPTYPE_CTRL) + { + ret = stm32_ctrlep_alloc(priv, epdesc, ep); + } + else + { + ret = stm32_xfrep_alloc(priv, epdesc, ep); + } + + stm32_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: stm32_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpoint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + + DEBUGASSERT(priv); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* A single channel is represent by an index in the range of 0 to STM32_MAX_TX_FIFOS. + * Otherwise, the ep must be a pointer to an allocated control endpoint structure. + */ + + if ((uintptr_t)ep < STM32_MAX_TX_FIFOS) + { + /* Halt the channel and mark the channel available */ + + stm32_chan_free(priv, (int)ep); + } + else + { + /* Halt both control channel and mark the channels available */ + + FAR struct stm32_ctrlinfo_s *ctrlep = (FAR struct stm32_ctrlinfo_s *)ep; + stm32_chan_free(priv, ctrlep->inndx); + stm32_chan_free(priv, ctrlep->outndx); + + /* And free the control endpoint container */ + + kmm_free(ctrlep); + } + + stm32_givesem(&priv->exclsem); + return OK; +} + +/**************************************************************************** + * Name: stm32_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special memory requirement for the STM32. */ + + alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32_OTGFS_DESCSIZE); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated address and size of the descriptor buffer */ + + *buffer = alloc; + *maxlen = CONFIG_STM32_OTGFS_DESCSIZE; + return OK; +} + +/**************************************************************************** + * Name: stm32_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to free that + * request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: stm32_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* There is no special memory requirement */ + + alloc = (FAR uint8_t *)kmm_malloc(buflen); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated buffer */ + + *buffer = alloc; + return OK; +} + +/************************************************************************************ + * Name: stm32_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlin and stm32_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTGFS_VTRACE2_CTRLIN, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the IN data phase (if any) */ + + if (buflen > 0) + { + ret = stm32_ctrl_recvdata(priv, ep0info, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_RECVDATA, -ret); + } + } + + /* Handle the status OUT phase */ + + if (ret == OK) + { + priv->chan[ep0info->outndx].outdata1 ^= true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactions exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTGFS_TRACE1_SENDDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTGFS_VTRACE2_CTRLOUT, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the data OUT phase (if any) */ + + if (buflen > 0) + { + /* Start DATA out transfer (only one DATA packet) */ + + priv->chan[ep0info->outndx].outdata1 = true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret < 0) + { + usbhost_trace1(OTGFS_TRACE1_SENDDATA, -ret); + } + } + + /* Handle the status IN phase */ + + if (ret == OK) + { + ret = stm32_ctrl_recvdata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactins exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTGFS_TRACE1_RECVDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + ssize_t nbytes; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + nbytes = stm32_in_transfer(priv, chidx, buffer, buflen); + } + else + { + nbytes = stm32_out_transfer(priv, chidx, buffer, buflen); + } + + stm32_givesem(&priv->exclsem); + return nbytes; +} + +/**************************************************************************** + * Name: stm32_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + int ret; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + ret = stm32_in_asynch(priv, chidx, buffer, buflen, callback, arg); + } + else + { + ret = stm32_out_asynch(priv, chidx, buffer, buflen, callback, arg); + } + + stm32_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: stm32_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_chan_s *chan; + unsigned int chidx = (unsigned int)ep; + irqstate_t flags; + + uvdbg("chidx: %u: %d\n", chidx); + + DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS); + chan = &priv->chan[chidx]; + + /* We need to disable interrupts to avoid race conditions with the asynchronous + * completion of the transfer being cancelled. + */ + + flags = enter_critical_section(); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_CANCELLED); + chan->result = -ESHUTDOWN; + + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + + /* Wake'em up! */ + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + usbhost_asynch_t callback; + FAR void *arg; + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + callback(arg, -ESHUTDOWN); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: stm32_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && hport != NULL); + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + stm32_givesem(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_portreset + * + * Description: + * Reset the USB host port. + * + * NOTE: "Before starting to drive a USB reset, the application waits for the + * OTG interrupt triggered by the debounce done bit (DBCDNE bit in + * OTG_FS_GOTGINT), which indicates that the bus is stable again after the + * electrical debounce caused by the attachment of a pull-up resistor on DP + * (FS) or DM (LS). + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + regval = stm32_getreg(STM32_OTGFS_HPRT); + regval &= ~(OTGFS_HPRT_PENA | OTGFS_HPRT_PCDET | OTGFS_HPRT_PENCHNG | + OTGFS_HPRT_POCCHNG); + regval |= OTGFS_HPRT_PRST; + stm32_putreg(STM32_OTGFS_HPRT, regval); + + up_mdelay(20); + + regval &= ~OTGFS_HPRT_PRST; + stm32_putreg(STM32_OTGFS_HPRT, regval); + + up_mdelay(20); +} + +/**************************************************************************** + * Name: stm32_flush_txfifos + * + * Description: + * Flush the selected Tx FIFO. + * + * Input Parameters: + * txfnum -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_txfifos(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTGFS_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(STM32_OTGFS_GRSTCTL, regval); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_flush_rxfifo + * + * Description: + * Flush the Rx FIFO. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_rxfifo(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(STM32_OTGFS_GRSTCTL, OTGFS_GRSTCTL_RXFFLSH); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_vbusdrive + * + * Description: + * Drive the Vbus +5V. + * + * Input Parameters: + * priv - USB host driver private data structure. + * state - True: Drive, False: Don't drive + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state) +{ + uint32_t regval; + + /* Enable/disable the external charge pump */ + + stm32_usbhost_vbusdrive(0, state); + + /* Turn on the Host port power. */ + + regval = stm32_getreg(STM32_OTGFS_HPRT); + regval &= ~(OTGFS_HPRT_PENA | OTGFS_HPRT_PCDET | OTGFS_HPRT_PENCHNG | + OTGFS_HPRT_POCCHNG); + + if (((regval & OTGFS_HPRT_PPWR) == 0) && state) + { + regval |= OTGFS_HPRT_PPWR; + stm32_putreg(STM32_OTGFS_HPRT, regval); + } + + if (((regval & OTGFS_HPRT_PPWR) != 0) && !state) + { + regval &= ~OTGFS_HPRT_PPWR; + stm32_putreg(STM32_OTGFS_HPRT, regval); + } + + up_mdelay(200); +} + +/**************************************************************************** + * Name: stm32_host_initialize + * + * Description: + * Initialize/re-initialize hardware for host mode operation. At present, + * this function is called only from stm32_hw_initialize(). But if OTG mode + * were supported, this function would also be called to swtich between + * host and device modes on a connector ID change interrupt. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + uint32_t offset; + int i; + + /* Restart the PHY Clock */ + + stm32_putreg(STM32_OTGFS_PCGCCTL, 0); + + /* Initialize Host Configuration (HCFG) register */ + + regval = stm32_getreg(STM32_OTGFS_HCFG); + regval &= ~OTGFS_HCFG_FSLSPCS_MASK; + regval |= OTGFS_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTGFS_HCFG, regval); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Clear the FS-/LS-only support bit in the HCFG register */ + + regval = stm32_getreg(STM32_OTGFS_HCFG); + regval &= ~OTGFS_HCFG_FSLSS; + stm32_putreg(STM32_OTGFS_HCFG, regval); + + /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */ + /* Configure Rx FIFO size (GRXFSIZ) */ + + stm32_putreg(STM32_OTGFS_GRXFSIZ, CONFIG_STM32_OTGFS_RXFIFO_SIZE); + offset = CONFIG_STM32_OTGFS_RXFIFO_SIZE; + + /* Setup the host non-periodic Tx FIFO size (HNPTXFSIZ) */ + + regval = (offset | (CONFIG_STM32_OTGFS_NPTXFIFO_SIZE << OTGFS_HNPTXFSIZ_NPTXFD_SHIFT)); + stm32_putreg(STM32_OTGFS_HNPTXFSIZ, regval); + offset += CONFIG_STM32_OTGFS_NPTXFIFO_SIZE; + + /* Set up the host periodic Tx fifo size register (HPTXFSIZ) */ + + regval = (offset | (CONFIG_STM32_OTGFS_PTXFIFO_SIZE << OTGFS_HPTXFSIZ_PTXFD_SHIFT)); + stm32_putreg(STM32_OTGFS_HPTXFSIZ, regval); + + /* If OTG were supported, we sould need to clear HNP enable bit in the + * USB_OTG control register about here. + */ + + /* Flush all FIFOs */ + + stm32_flush_txfifos(OTGFS_GRSTCTL_TXFNUM_HALL); + stm32_flush_rxfifo(); + + /* Clear all pending HC Interrupts */ + + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + stm32_putreg(STM32_OTGFS_HCINT(i), 0xffffffff); + stm32_putreg(STM32_OTGFS_HCINTMSK(i), 0); + } + + /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + stm32_vbusdrive(priv, true); + + /* Enable host interrupts */ + + stm32_hostinit_enable(); +} + +/**************************************************************************** + * Name: stm32_sw_initialize + * + * Description: + * One-time setup of the host driver state structure. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) +{ + FAR struct usbhost_driver_s *drvr; + FAR struct usbhost_hubport_s *hport; + int i; + + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = stm32_ep0configure; + drvr->epalloc = stm32_epalloc; + drvr->epfree = stm32_epfree; + drvr->alloc = stm32_alloc; + drvr->free = stm32_free; + drvr->ioalloc = stm32_ioalloc; + drvr->iofree = stm32_iofree; + drvr->ctrlin = stm32_ctrlin; + drvr->ctrlout = stm32_ctrlout; + drvr->transfer = stm32_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = stm32_asynch; +#endif + drvr->cancel = stm32_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = stm32_connect; +#endif + drvr->disconnect = stm32_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = (usbhost_ep_t)&priv->ep0; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->rhport); + + /* Initialize semaphores */ + + sem_init(&priv->pscsem, 0, 0); + sem_init(&priv->exclsem, 0, 1); + + /* Initialize the driver state data */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = false; + + /* Put all of the channels back in their initial, allocated state */ + + memset(priv->chan, 0, STM32_MAX_TX_FIFOS * sizeof(struct stm32_chan_s)); + + /* Initialize each channel */ + + for (i = 0; i < STM32_MAX_TX_FIFOS; i++) + { + FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + sem_init(&chan->waitsem, 0, 0); + } +} + +/**************************************************************************** + * Name: stm32_hw_initialize + * + * Description: + * One-time setup of the host controller harware for normal operations. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + unsigned long timeout; + + /* Set the PHYSEL bit in the GUSBCFG register to select the OTG FS serial + * transceiver: "This bit is always 1 with write-only access" + */ + + regval = stm32_getreg(STM32_OTGFS_GUSBCFG); + regval |= OTGFS_GUSBCFG_PHYSEL; + stm32_putreg(STM32_OTGFS_GUSBCFG, regval); + + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(STM32_OTGFS_GRSTCTL, OTGFS_GRSTCTL_CSRST); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGFS_GRSTCTL); + if ((regval & OTGFS_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + + regval = (OTGFS_GCCFG_PWRDWN | OTGFS_GCCFG_VBUSASEN | OTGFS_GCCFG_VBUSBSEN); +#ifndef CONFIG_USBDEV_VBUSSENSING + regval |= OTGFS_GCCFG_NOVBUSSENS; +#endif +#ifdef CONFIG_STM32_OTGFS_SOFOUTPUT + regval |= OTGFS_GCCFG_SOFOUTEN; +#endif + stm32_putreg(STM32_OTGFS_GCCFG, regval); + up_mdelay(20); + + /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + * bits would need to be set in the GUSBCFG register about here. + */ + + /* Force Host Mode */ + + regval = stm32_getreg(STM32_OTGFS_GUSBCFG); + regval &= ~OTGFS_GUSBCFG_FDMOD; + regval |= OTGFS_GUSBCFG_FHMOD; + stm32_putreg(STM32_OTGFS_GUSBCFG, regval); + up_mdelay(50); + + /* Initialize host mode and return success */ + + stm32_host_initialize(priv); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_otgfshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + + /* Make sure that interrupts from the OTG FS core are disabled */ + + stm32_gint_disable(); + + /* Reset the state of the host driver */ + + stm32_sw_initialize(priv); + + /* Alternate function pin configuration. Here we assume that: + * + * 1. GPIOA, SYSCFG, and OTG FS peripheral clocking have already been\ + * enabled as part of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG FS alternate function pins for DM, DP, ID, and SOF. + * + * PIN* SIGNAL DIRECTION + * ---- ----------- ---------- + * PA8 OTG_FS_SOF SOF clock output + * PA9 OTG_FS_VBUS VBUS input for device, Driven by external regulator by + * host (not an alternate function) + * PA10 OTG_FS_ID OTG ID pin (only needed in Dual mode) + * PA11 OTG_FS_DM D- I/O + * PA12 OTG_FS_DP D+ I/O + * + * *Pins may vary from device-to-device. + */ + + stm32_configgpio(GPIO_OTGFS_DM); + stm32_configgpio(GPIO_OTGFS_DP); + stm32_configgpio(GPIO_OTGFS_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable */ + +#ifdef CONFIG_STM32_OTGFS_SOFOUTPUT + stm32_configgpio(GPIO_OTGFS_SOF); +#endif + + /* Initialize the USB OTG FS core */ + + stm32_hw_initialize(priv); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(STM32_IRQ_OTGFS, stm32_gint_isr) != 0) + { + usbhost_trace1(OTGFS_TRACE1_IRQATTACH, 0); + return NULL; + } + + /* Enable USB OTG FS global interrupts */ + + stm32_gint_enable(); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(STM32_IRQ_OTGFS); + return &g_usbconn; +} + +#endif /* CONFIG_USBHOST && CONFIG_STM32_OTGFS */ diff --git a/arch/arm/src/stm32/stm32_otghs.h b/arch/arm/src/stm32/stm32_otghs.h new file mode 100644 index 0000000000000000000000000000000000000000..2c36cb801fc3a55c6fd5c02ec6f74d7f21d4ff3e --- /dev/null +++ b/arch/arm/src/stm32/stm32_otghs.h @@ -0,0 +1,127 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_otghs.h + * + * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_OTGHS_H +#define __ARCH_ARM_SRC_STM32_STM32_OTGHS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "stm32.h" +#include "chip/stm32_otghs.h" + +#if defined(CONFIG_STM32_OTGHS) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifndef CONFIG_OTGHS_PRI +# define CONFIG_OTGHS_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_otgfshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +FAR struct usbhost_connection_s *stm32_otghshost_initialize(int controller); +#endif + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the OTG FS device driver + * is used. This function is called whenever the USB enters or leaves suspend + * mode. This is an opportunity for the board logic to shutdown clocks, power, + * etc. while the USB is suspended. + * + ************************************************************************************/ + +void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32_OTGFS */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_OTGHS_H */ + diff --git a/arch/arm/src/stm32/stm32_otghsdev.c b/arch/arm/src/stm32/stm32_otghsdev.c new file mode 100644 index 0000000000000000000000000000000000000000..07e9f0af1ca694661d14f28d6947f6dde2ce3628 --- /dev/null +++ b/arch/arm/src/stm32/stm32_otghsdev.c @@ -0,0 +1,5660 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_otghsdev.c + * + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32_otghs.h" + +#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32_OTGHS)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* There is 1.25Kb of FIFO memory. The default partitions this memory + * so that there is a TxFIFO allocated for each endpoint and with more + * memory provided for the common RxFIFO. A more knowledge-able + * configuration would not allocate any TxFIFO space to OUT endpoints. + */ + +#ifndef CONFIG_USBDEV_RXFIFO_SIZE +# define CONFIG_USBDEV_RXFIFO_SIZE 512 +#endif + +#ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 192 +#endif + +#if (CONFIG_USBDEV_RXFIFO_SIZE + CONFIG_USBDEV_EP0_TXFIFO_SIZE + \ + CONFIG_USBDEV_EP2_TXFIFO_SIZE + CONFIG_USBDEV_EP3_TXFIFO_SIZE) > 1280 +# error "FIFO allocations exceed FIFO memory size" +#endif + +/* The actual FIFO addresses that we use must be aligned to 4-byte boundaries; + * FIFO sizes must be provided in units of 32-bit words. + */ + +#define STM32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3) +#define STM32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2) + +#define STM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP0_TXFIFO_WORDS < 16 || STM32_EP0_TXFIFO_WORDS > 256 +# error "CONFIG_USBDEV_EP0_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP1_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP1_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP2_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP2_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP3_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range" +#endif + +/* Debug ***********************************************************************/ +/* Trace error codes */ + +#define STM32_TRACEERR_ALLOCFAIL 0x01 +#define STM32_TRACEERR_BADCLEARFEATURE 0x02 +#define STM32_TRACEERR_BADDEVGETSTATUS 0x03 +#define STM32_TRACEERR_BADEPNO 0x04 +#define STM32_TRACEERR_BADEPGETSTATUS 0x05 +#define STM32_TRACEERR_BADGETCONFIG 0x06 +#define STM32_TRACEERR_BADGETSETDESC 0x07 +#define STM32_TRACEERR_BADGETSTATUS 0x08 +#define STM32_TRACEERR_BADSETADDRESS 0x09 +#define STM32_TRACEERR_BADSETCONFIG 0x0a +#define STM32_TRACEERR_BADSETFEATURE 0x0b +#define STM32_TRACEERR_BADTESTMODE 0x0c +#define STM32_TRACEERR_BINDFAILED 0x0d +#define STM32_TRACEERR_DISPATCHSTALL 0x0e +#define STM32_TRACEERR_DRIVER 0x0f +#define STM32_TRACEERR_DRIVERREGISTERED 0x10 +#define STM32_TRACEERR_EP0NOSETUP 0x11 +#define STM32_TRACEERR_EP0SETUPSTALLED 0x12 +#define STM32_TRACEERR_EPINNULLPACKET 0x13 +#define STM32_TRACEERR_EPINUNEXPECTED 0x14 +#define STM32_TRACEERR_EPOUTNULLPACKET 0x15 +#define STM32_TRACEERR_EPOUTUNEXPECTED 0x16 +#define STM32_TRACEERR_INVALIDCTRLREQ 0x17 +#define STM32_TRACEERR_INVALIDPARMS 0x18 +#define STM32_TRACEERR_IRQREGISTRATION 0x19 +#define STM32_TRACEERR_NOEP 0x1a +#define STM32_TRACEERR_NOTCONFIGURED 0x1b +#define STM32_TRACEERR_EPOUTQEMPTY 0x1c +#define STM32_TRACEERR_EPINREQEMPTY 0x1d +#define STM32_TRACEERR_NOOUTSETUP 0x1e +#define STM32_TRACEERR_POLLTIMEOUT 0x1f + +/* Trace interrupt codes */ + +#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */ +#define STM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */ + +#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */ +#define STM32_TRACEINTID_EPIN (10 + 1) +#define STM32_TRACEINTID_MISMATCH (10 + 2) +#define STM32_TRACEINTID_WAKEUP (10 + 3) +#define STM32_TRACEINTID_SUSPEND (10 + 4) +#define STM32_TRACEINTID_SOF (10 + 5) +#define STM32_TRACEINTID_RXFIFO (10 + 6) +#define STM32_TRACEINTID_DEVRESET (10 + 7) +#define STM32_TRACEINTID_ENUMDNE (10 + 8) +#define STM32_TRACEINTID_IISOIXFR (10 + 9) +#define STM32_TRACEINTID_IISOOXFR (10 + 10) +#define STM32_TRACEINTID_SRQ (10 + 11) +#define STM32_TRACEINTID_OTG (10 + 12) + +#define STM32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */ +#define STM32_TRACEINTID_EPOUT_EPDISD (40 + 1) +#define STM32_TRACEINTID_EPOUT_SETUP (40 + 2) +#define STM32_TRACEINTID_DISPATCH (40 + 3) + +#define STM32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */ +#define STM32_TRACEINTID_EPGETSTATUS (50 + 1) +#define STM32_TRACEINTID_DEVGETSTATUS (50 + 2) +#define STM32_TRACEINTID_IFGETSTATUS (50 + 3) +#define STM32_TRACEINTID_CLEARFEATURE (50 + 4) +#define STM32_TRACEINTID_SETFEATURE (50 + 5) +#define STM32_TRACEINTID_SETADDRESS (50 + 6) +#define STM32_TRACEINTID_GETSETDESC (50 + 7) +#define STM32_TRACEINTID_GETCONFIG (50 + 8) +#define STM32_TRACEINTID_SETCONFIG (50 + 9) +#define STM32_TRACEINTID_GETSETIF (50 + 10) +#define STM32_TRACEINTID_SYNCHFRAME (50 + 11) + +#define STM32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */ +#define STM32_TRACEINTID_EPIN_TOC (70 + 1) +#define STM32_TRACEINTID_EPIN_ITTXFE (70 + 2) +#define STM32_TRACEINTID_EPIN_EPDISD (70 + 3) +#define STM32_TRACEINTID_EPIN_TXFE (70 + 4) + +#define STM32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */ + +#define STM32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */ +#define STM32_TRACEINTID_OUTRECVD (90 + 1) +#define STM32_TRACEINTID_OUTDONE (90 + 2) +#define STM32_TRACEINTID_SETUPDONE (90 + 3) +#define STM32_TRACEINTID_SETUPRECVD (90 + 4) + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define STM32_NENDPOINTS (4) /* ep0-3 x 2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define STM32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN) +#define STM32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT) + +/* Endpoint 0 */ + +#define EP0 (0) + +/* The set of all enpoints available to the class implementation (1-3) */ + +#define STM32_EP_AVAILABLE (0x0e) /* All available endpoints */ + +/* Maximum packet sizes for full speed endpoints */ + +#define STM32_MAXPACKET (64) /* Max packet size (1-64) */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 +#define STM32_FLUSH_DELAY 200000 + +/* Request queue operations ****************************************************/ + +#define stm32_rqempty(ep) ((ep)->head == NULL) +#define stm32_rqpeek(ep) ((ep)->head) + +/* Standard stuff **************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Overall device state */ + +enum stm32_devstate_e +{ + DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply + * means that the device is not yet been given an + * address. + * SET: At initialization, uninitialization, + * reset, and whenever the device address + * is set to zero + * TESTED: Never + */ + DEVSTATE_ADDRESSED, /* Device address has been assigned, not no + * configuration has yet been selected. + * SET: When either a non-zero device address + * is first assigned or when the device + * is unconfigured (with configuration == 0) + * TESTED: never + */ + DEVSTATE_CONFIGURED, /* Address assigned and configured: + * SET: When the device has been addressed and + * an non-zero configuration has been selected. + * TESTED: In many places to assure that the USB device + * has been properly configured by the host. + */ +}; + +/* Endpoint 0 states */ + +enum stm32_ep0state_e +{ + EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or + * epsubmit: + * SET: In stm32_epin() and stm32_epout() when + * we revert from request processing to + * SETUP processing. + * TESTED: Never + */ + EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA + * OUT phase of SETUP Packet to complete before + * processing a SETUP command (without a USB request): + * SET: Set in stm32_rxinterrupt() when SETUP OUT + * packet is received. + * TESTED: In stm32_ep0out_receive() + */ + EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and + * accompanying data have been received. Processing + * of SETUP command will happen soon. + * SET: (1) stm32_ep0out_receive() when the OUT + * SETUP data phase completes, or (2) + * stm32_rxinterrupt() when an IN SETUP is + * packet received. + * TESTED: Tested in stm32_epout_interrupt() when + * SETUP phase is done to see if the SETUP + * command is ready to be processed. Also + * tested in stm32_ep0out_setup() just to + * double-check that we have a SETUP request + * and any accompanying data. + */ + EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by stm32_ep0out_setup(): + * SET: When SETUP packet received in EP0 OUT + * TESTED: Never + */ + EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request): + * SET: When SETUP response is sent by + * stm32_ep0in_setupresponse() + * TESTED: Never + */ + EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request): + * SET: In stm32_epin_request() when a write + * request is processed on EP0. + * TESTED: In stm32_epin() to see if we should + * revert to SETUP processing. + */ + EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a + * USB request) + * SET: In stm32_epout_request() when a read + * request is processed on EP0. + * TESTED: In stm32_epout() to see if we should + * revert to SETUP processing + */ +}; + +/* Parsed control request */ + +struct stm32_ctrlreq_s +{ + uint8_t type; + uint8_t req; + uint16_t value; + uint16_t index; + uint16_t len; +}; + +/* A container for a request so that the request may be retained in a list */ + +struct stm32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct stm32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct stm32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct stm32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* STM32-specific fields */ + + struct stm32_usbdev_s *dev; /* Reference to private driver data */ + struct stm32_req_s *head; /* Request list for this endpoint */ + struct stm32_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t eptype:2; /* Endpoint type */ + uint8_t active:1; /* 1: A request is being processed */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t isin:1; /* 1: IN Endpoint */ + uint8_t odd:1; /* 1: Odd frame */ + uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */ +}; + +/* This structure retains the state of the USB device controller */ + +struct stm32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct stm32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* STM32-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t addressed:1; /* 1: Peripheral address has been set */ + uint8_t configured:1; /* 1: Class driver has been configured */ + uint8_t wakeup:1; /* 1: Device remote wake-up */ + uint8_t dotest:1; /* 1: Test mode selected */ + + uint8_t devstate:4; /* See enum stm32_devstate_e */ + uint8_t ep0state:4; /* See enum stm32_ep0state_e */ + uint8_t testmode:4; /* Selected test mode */ + uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */ + + /* E0 SETUP data buffering. + * + * ctrlreq: + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The pack receipt logic will save + * the accompanying EP0 IN data in ep0data[] before the SETUP command is + * processed. + * + * For IN SETUP requests, the DATA phase will occur AFTER the SETUP + * control request is processed. In that case, ep0data[] may be used as + * the response buffer. + * + * ep0datlen + * Length of OUT DATA received in ep0data[] (Not used with OUT data) + */ + + struct usb_ctrlreq_s ctrlreq; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint lists */ + + struct stm32_ep_s epin[STM32_NENDPOINTS]; + struct stm32_ep_s epout[STM32_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations ****************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep); +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req); + +/* Low level data transfers and request operations *****************************/ +/* Special endpoint 0 data transfer logic */ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *data, uint32_t nbytes); +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv); +static void stm32_ep0in_activate(void); + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv); + +/* IN request and TxFIFO handling */ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* OUT request and RxFIFO handling */ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len); +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len); +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt); +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt); +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* General request handling */ + +static void stm32_ep_flush(FAR struct stm32_ep_s *privep); +static void stm32_req_complete(FAR struct stm32_ep_s *privep, + int16_t result); +static void stm32_req_cancel(FAR struct stm32_ep_s *privep, + int16_t status); + +/* Interrupt handling **********************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog); +static int stm32_req_dispatch(FAR struct stm32_usbdev_s *priv, + FAR const struct usb_ctrlreq_s *ctrl); +static void stm32_usbreset(FAR struct stm32_usbdev_s *priv); + +/* Second level OUT endpoint interrupt processing */ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index); +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq); +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv); +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, + uint8_t epno); +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Second level IN endpoint interrupt processing */ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv); +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno); +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno); +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Other second level interrupt processing */ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv); +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv); +#endif +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv); +#endif + +/* First level interrupt processing */ + +static int stm32_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ +/* Global OUT NAK controls */ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep); +static void stm32_disablegonak(FAR struct stm32_ep_s *privep); + +/* Endpoint configuration */ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, bool last); +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv); + +/* Endpoint disable */ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep); +static void stm32_epin_disable(FAR struct stm32_ep_s *privep); +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep); + +/* Endpoint request management */ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep); +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); + +/* Endpoint buffer management */ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif + +/* Endpoint request submission */ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Endpoint request cancellation */ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Stall handling */ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep); +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume); +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv); + +/* Endpoint allocation */ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void stm32_ep_free(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep); + +/* USB device controller operations ********************************************/ + +static int stm32_getframe(struct usbdev_s *dev); +static int stm32_wakeup(struct usbdev_s *dev); +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int stm32_pullup(struct usbdev_s *dev, bool enable); +static void stm32_setaddress(struct stm32_usbdev_s *priv, + uint16_t address); +static int stm32_txfifo_flush(uint32_t txfnum); +static int stm32_rxfifo_flush(void); + +/* Initialization **************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv); +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct stm32_usbdev_s g_otghsdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = stm32_ep_configure, + .disable = stm32_ep_disable, + .allocreq = stm32_ep_allocreq, + .freereq = stm32_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = stm32_ep_allocbuffer, + .freebuffer = stm32_ep_freebuffer, +#endif + .submit = stm32_ep_submit, + .cancel = stm32_ep_cancel, + .stall = stm32_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = stm32_ep_alloc, + .freeep = stm32_ep_free, + .getframe = stm32_getframe, + .wakeup = stm32_wakeup, + .selfpowered = stm32_selfpowered, + .pullup = stm32_pullup, +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(STM32_TRACEERR_ALLOCFAIL ), + TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ), + TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADEPNO ), + TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADGETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADGETSETDESC ), + TRACE_STR(STM32_TRACEERR_BADGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADSETADDRESS ), + TRACE_STR(STM32_TRACEERR_BADSETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADSETFEATURE ), + TRACE_STR(STM32_TRACEERR_BADTESTMODE ), + TRACE_STR(STM32_TRACEERR_BINDFAILED ), + TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ), + TRACE_STR(STM32_TRACEERR_DRIVER ), + TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED), + TRACE_STR(STM32_TRACEERR_EP0NOSETUP ), + TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ), + TRACE_STR(STM32_TRACEERR_EPINNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPINUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPOUTUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ), + TRACE_STR(STM32_TRACEERR_INVALIDPARMS ), + TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ), + TRACE_STR(STM32_TRACEERR_NOEP ), + TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ), + TRACE_STR(STM32_TRACEERR_EPOUTQEMPTY ), + TRACE_STR(STM32_TRACEERR_EPINREQEMPTY ), + TRACE_STR(STM32_TRACEERR_NOOUTSETUP ), + TRACE_STR(STM32_TRACEERR_POLLTIMEOUT ), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(STM32_TRACEINTID_USB ), + TRACE_STR(STM32_TRACEINTID_INTPENDING ), + TRACE_STR(STM32_TRACEINTID_EPOUT ), + TRACE_STR(STM32_TRACEINTID_EPIN ), + TRACE_STR(STM32_TRACEINTID_MISMATCH ), + TRACE_STR(STM32_TRACEINTID_WAKEUP ), + TRACE_STR(STM32_TRACEINTID_SUSPEND ), + TRACE_STR(STM32_TRACEINTID_SOF ), + TRACE_STR(STM32_TRACEINTID_RXFIFO ), + TRACE_STR(STM32_TRACEINTID_DEVRESET ), + TRACE_STR(STM32_TRACEINTID_ENUMDNE ), + TRACE_STR(STM32_TRACEINTID_IISOIXFR ), + TRACE_STR(STM32_TRACEINTID_IISOOXFR ), + TRACE_STR(STM32_TRACEINTID_SRQ ), + TRACE_STR(STM32_TRACEINTID_OTG ), + TRACE_STR(STM32_TRACEINTID_EPOUT_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPOUT_EPDISD), + TRACE_STR(STM32_TRACEINTID_EPOUT_SETUP ), + TRACE_STR(STM32_TRACEINTID_DISPATCH ), + TRACE_STR(STM32_TRACEINTID_GETSTATUS ), + TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS), + TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_CLEARFEATURE), + TRACE_STR(STM32_TRACEINTID_SETFEATURE ), + TRACE_STR(STM32_TRACEINTID_SETADDRESS ), + TRACE_STR(STM32_TRACEINTID_GETSETDESC ), + TRACE_STR(STM32_TRACEINTID_GETCONFIG ), + TRACE_STR(STM32_TRACEINTID_SETCONFIG ), + TRACE_STR(STM32_TRACEINTID_GETSETIF ), + TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ), + TRACE_STR(STM32_TRACEINTID_EPIN_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPIN_TOC ), + TRACE_STR(STM32_TRACEINTID_EPIN_ITTXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EPDISD ), + TRACE_STR(STM32_TRACEINTID_EPIN_TXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EMPWAIT), + TRACE_STR(STM32_TRACEINTID_OUTNAK ), + TRACE_STR(STM32_TRACEINTID_OUTRECVD ), + TRACE_STR(STM32_TRACEINTID_OUTDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPRECVD ), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_req_remfirst + * + * Description: + * Remove a request from the head of an endpoint request queue + * + ****************************************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep) +{ + FAR struct stm32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_req_addlast + * + * Description: + * Add a request to the end of an endpoint request queue + * + ****************************************************************************/ + +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + return is_empty; +} + +/**************************************************************************** + * Name: stm32_ep0in_setupresponse + * + * Description: + * Schedule a short transfer on Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *buf, uint32_t nbytes) +{ + stm32_epin_transfer(&priv->epin[EP0], buf, nbytes); + priv->ep0state = EP0STATE_SETUPRESPONSE; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0in_transmitzlp + * + * Description: + * Send a zero length packet (ZLP) on endpoint 0 IN + * + ****************************************************************************/ + +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv) +{ + stm32_ep0in_setupresponse(priv, NULL, 0); +} + +/**************************************************************************** + * Name: stm32_ep0in_activate + * + * Description: + * Activate the endpoint 0 IN endpoint. + * + ****************************************************************************/ + +static void stm32_ep0in_activate(void) +{ + uint32_t regval; + + /* Set the max packet size of the IN EP. */ + + regval = stm32_getreg(STM32_OTGHS_DIEPCTL0); + regval &= ~OTGHS_DIEPCTL0_MPSIZ_MASK; + +#if CONFIG_USBDEV_EP0_MAXSIZE == 8 + regval |= OTGHS_DIEPCTL0_MPSIZ_8; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 16 + regval |= OTGHS_DIEPCTL0_MPSIZ_16; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 32 + regval |= OTGHS_DIEPCTL0_MPSIZ_32; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 64 + regval |= OTGHS_DIEPCTL0_MPSIZ_64; +#else +# error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE" +#endif + + stm32_putreg(regval, STM32_OTGHS_DIEPCTL0); + + /* Clear global IN NAK */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval |= OTGHS_DCTL_CGINAK; + stm32_putreg(regval, STM32_OTGHS_DCTL); +} + +/**************************************************************************** + * Name: stm32_ep0out_ctrlsetup + * + * Description: + * Setup to receive a SETUP packet. + * + ****************************************************************************/ + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Setup the hardware to perform the SETUP transfer */ + + regval = (USB_SIZEOF_CTRLREQ * 3 << OTGHS_DOEPTSIZ0_XFRSIZ_SHIFT) | + (OTGHS_DOEPTSIZ0_PKTCNT) | + (3 << OTGHS_DOEPTSIZ0_STUPCNT_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DOEPTSIZ0); + + /* Then clear NAKing and enable the transfer */ + + regval = stm32_getreg(STM32_OTGHS_DOEPCTL0); + regval |= (OTGHS_DOEPCTL0_CNAK | OTGHS_DOEPCTL0_EPENA); + stm32_putreg(regval, STM32_OTGHS_DOEPCTL0); +} + +/**************************************************************************** + * Name: stm32_txfifo_write + * + * Description: + * Send data to the endpoint's TxFIFO. + * + ****************************************************************************/ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t regaddr; + uint32_t regval; + int nwords; + int i; + + /* Convert the number of bytes to words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the TxFIFO for this endpoint (same as the endpoint number) */ + + regaddr = STM32_OTGHS_DFIFO_DEP(privep->epphy); + + /* Then transfer each word to the TxFIFO */ + + for (i = 0; i < nwords; i++) + { + /* Read four bytes from the source buffer (to avoid unaligned accesses) + * and pack these into one 32-bit word (little endian). + */ + + regval = (uint32_t)*buf++; + regval |= ((uint32_t)*buf++) << 8; + regval |= ((uint32_t)*buf++) << 16; + regval |= ((uint32_t)*buf++) << 24; + + /* Then write the packet data to the TxFIFO */ + + stm32_putreg(regval, regaddr); + } +} + +/**************************************************************************** + * Name: stm32_epin_transfer + * + * Description: + * Start the Tx data transfer + * + ****************************************************************************/ + +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t pktcnt; + uint32_t regval; + + /* Read the DIEPSIZx register */ + + regval = stm32_getreg(STM32_OTGHS_DIEPTSIZ(privep->epphy)); + + /* Clear the XFRSIZ, PKTCNT, and MCNT field of the DIEPSIZx register */ + + regval &= ~(OTGHS_DIEPTSIZ_XFRSIZ_MASK | OTGHS_DIEPTSIZ_PKTCNT_MASK | + OTGHS_DIEPTSIZ_MCNT_MASK); + + /* Are we sending a zero length packet (ZLP) */ + + if (nbytes == 0) + { + /* Yes.. leave the transfer size at zero and set the packet count to 1 */ + + pktcnt = 1; + } + else + { + /* No.. Program the transfer size and packet count . First calculate: + * + * xfrsize = The total number of bytes to be sent. + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + */ + + pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + } + + /* Set the XFRSIZ and PKTCNT */ + + regval |= (pktcnt << OTGHS_DIEPTSIZ_PKTCNT_SHIFT); + regval |= ((uint32_t)nbytes << OTGHS_DIEPTSIZ_XFRSIZ_SHIFT); + + /* If this is an isochronous endpoint, then set the multi-count field to + * the PKTCNT as well. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + regval |= (pktcnt << OTGHS_DIEPTSIZ_MCNT_SHIFT); + } + + /* Save DIEPSIZx register value */ + + stm32_putreg(regval, STM32_OTGHS_DIEPTSIZ(privep->epphy)); + + /* Read the DIEPCTLx register */ + + regval = stm32_getreg(STM32_OTGHS_DIEPCTL(privep->epphy)); + + /* If this is an isochronous endpoint, then set the even/odd frame bit + * the DIEPCTLx register. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + /* Check bit 0 of the frame number of the received SOF and set the + * even/odd frame to match. + */ + + uint32_t status = stm32_getreg(STM32_OTGHS_DSTS); + if ((status & OTGHS_DSTS_SOFFN0) == OTGHS_DSTS_SOFFN_EVEN) + { + regval |= OTGHS_DIEPCTL_SEVNFRM; + } + else + { + regval |= OTGHS_DIEPCTL_SODDFRM; + } + } + + /* EP enable, IN data in FIFO */ + + regval &= ~OTGHS_DIEPCTL_EPDIS; + regval |= (OTGHS_DIEPCTL_CNAK | OTGHS_DIEPCTL_EPENA); + stm32_putreg(regval, STM32_OTGHS_DIEPCTL(privep->epphy)); + + /* Transfer the data to the TxFIFO. At this point, the caller has already + * assured that there is sufficient space in the TxFIFO to hold the transfer + * we can just blindly continue. + */ + + stm32_txfifo_write(privep, buf, nbytes); +} + +/**************************************************************************** + * Name: stm32_epin_request + * + * Description: + * Begin or continue write request processing. + * + ****************************************************************************/ + +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint8_t *buf; + int nbytes; + int nwords; + int bytesleft; + + /* We get here in one of four possible ways. From three interrupting + * events: + * + * 1. From stm32_epin as part of the transfer complete interrupt processing + * This interrupt indicates that the last transfer has completed. + * 2. As part of the ITTXFE interrupt processing. That interrupt indicates + * that an IN token was received when the associated TxFIFO was empty. + * 3. From stm32_epin_txfifoempty as part of the TXFE interrupt processing. + * The TXFE interrupt is only enabled when the TxFIFO is full and the + * software must wait for space to become available in the TxFIFO. + * + * And this function may be called immediately when the write request is + * queue to start up the next transaction. + * + * 4. From stm32_ep_submit when a new write request is received WHILE the + * endpoint is not active (privep->active == false). + */ + + /* Check the request from the head of the endpoint request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINREQEMPTY), privep->epphy); + + /* There is no TX transfer in progress and no new pending TX + * requests to send. To stop transmitting any data on a particular + * IN endpoint, the application must set the IN NAK bit. To set this + * bit, the following field must be programmed. + */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGHS_DIEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer active */ + + privep->active = false; + return; + } + + ullvdbg("EP%d req=%p: len=%d xfrd=%d zlp=%d\n", + privep->epphy, privreq, privreq->req.len, + privreq->req.xfrd, privep->zlp); + + /* Check for a special case: If we are just starting a request (xfrd==0) and + * the class driver is trying to send a zero-length packet (len==0). Then set + * the ZLP flag so that the packet will be sent. + */ + + if (privreq->req.len == 0) + { + /* The ZLP flag is set TRUE whenever we want to force the driver to + * send a zero-length-packet on the next pass through the loop (below). + * The flag is cleared whenever a packet is sent in the loop below. + */ + + privep->zlp = true; + } + + /* Add one more packet to the TxFIFO. We will wait for the transfer + * complete event before we add the next packet (or part of a packet + * to the TxFIFO). + * + * The documentation says that we can can multiple packets to the TxFIFO, + * but it seems that we need to get the transfer complete event before + * we can add the next (or maybe I have got something wrong?) + */ + +#if 0 + while (privreq->req.xfrd < privreq->req.len || privep->zlp) +#else + if (privreq->req.xfrd < privreq->req.len || privep->zlp) +#endif + { + /* Get the number of bytes left to be sent in the request */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + + /* Assume no zero-length-packet on the next pass through this loop */ + + privep->zlp = false; + + /* Limit the size of the transfer to one full packet and handle + * zero-length packets (ZLPs). + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* The ZLP flag is set TRUE whenever we want to force + * the driver to send a zero-length-packet on the next + * pass through this loop. The flag is cleared (above) + * whenever we are committed to sending any packet and + * set here when we want to force one more pass through + * the loop. + */ + + privep->zlp = true; + } + } + } + + /* Get the transfer size in 32-bit words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the number of 32-bit words available in the TxFIFO. The + * DXTHSTS indicates the amount of free space available in the + * endpoint TxFIFO. Values are in terms of 32-bit words: + * + * 0: Endpoint TxFIFO is full + * 1: 1 word available + * 2: 2 words available + * n: n words available + */ + + regaddr = STM32_OTGHS_DTXFSTS(privep->epphy); + + /* Check for space in the TxFIFO. If space in the TxFIFO is not + * available, then set up an interrupt to resume the transfer when + * the TxFIFO is empty. + */ + + regval = stm32_getreg(regaddr); + if ((int)(regval & OTGHS_DTXFSTS_MASK) < nwords) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval); + + /* There is insufficient space in the TxFIFO. Wait for a TxFIFO + * empty interrupt and try again. + */ + + uint32_t empmsk = stm32_getreg(STM32_OTGHS_DIEPEMPMSK); + empmsk |= OTGHS_DIEPEMPMSK(privep->epphy); + stm32_putreg(empmsk, STM32_OTGHS_DIEPEMPMSK); + + /* Terminate the transfer. We will try again when the TxFIFO empty + * interrupt is received. + */ + + return; + } + + /* Transfer data to the TxFIFO */ + + buf = privreq->req.buf + privreq->req.xfrd; + stm32_epin_transfer(privep, buf, nbytes); + + /* If it was not before, the OUT endpoint is now actively transferring + * data. + */ + + privep->active = true; + + /* EP0 is a special case */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_IN; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* Note that the ZLP, if any, must be sent as a separate transfer. The need + * for a ZLP is indicated by privep->zlp. If all of the bytes were sent + * (including any final null packet) then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->zlp) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + + /* We are finished with the request (although the transfer has not + * yet completed). + */ + + stm32_req_complete(privep, OK); + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_read + * + * Description: + * Read packet from the RxFIFO into a read request. + * + ****************************************************************************/ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len) +{ + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO. Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTGHS_DFIFO_DEP(EP0); + + /* Read 32-bits and write 4 x 8-bits at time (to avoid unaligned accesses) */ + + for (i = 0; i < len; i += 4) + { + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Read 1 x 32-bits of EP0 packet data */ + + data.w = stm32_getreg(regaddr); + + /* Write 4 x 8-bits of EP0 packet data */ + + *dest++ = data.b[0]; + *dest++ = data.b[1]; + *dest++ = data.b[2]; + *dest++ = data.b[3]; + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_discard + * + * Description: + * Discard packet data from the RxFIFO. + * + ****************************************************************************/ + +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len) +{ + if (len > 0) + { + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTGHS_DFIFO_DEP(EP0); + + /* Read 32-bits at time */ + + for (i = 0; i < len; i += 4) + { + volatile uint32_t data = stm32_getreg(regaddr); + (void)data; + } + } +} + +/**************************************************************************** + * Name: stm32_epout_complete + * + * Description: + * This function is called when an OUT transfer complete interrupt is + * received. It completes the read request at the head of the endpoint's + * request queue. + * + ****************************************************************************/ + +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + + /* Since a transfer just completed, there must be a read request at the head of + * the endpoint request queue. + */ + + privreq = stm32_rqpeek(privep); + DEBUGASSERT(privreq); + + if (!privreq) + { + /* An OUT transfer completed, but no packet to receive the data. This + * should not happen. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", + privep->epphy, privreq->req.len, privreq->req.xfrd); + + /* Return the completed read request to the class driver and mark the state + * IDLE. + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + stm32_req_complete(privep, OK); + privep->active = false; + + /* Now set up the next read request (if any) */ + + stm32_epout_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_ep0out_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + FAR struct stm32_usbdev_s *priv; + + /* Sanity Checking */ + + DEBUGASSERT(privep && privep->ep.priv); + priv = (FAR struct stm32_usbdev_s *)privep->ep.priv; + + ullvdbg("EP0: bcnt=%d\n", bcnt); + usbtrace(TRACE_READ(EP0), bcnt); + + /* Verify that an OUT SETUP request as received before this data was + * received in the RxFIFO. + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Read the data into our special buffer for SETUP data */ + + int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt); + stm32_rxfifo_read(privep, priv->ep0data, readlen); + + /* Do we have to discard any excess bytes? */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Now we can process the setup command */ + + privep->active = false; + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + + stm32_ep0out_setup(priv); + } + else + { + /* This is an error. We don't have any idea what to do with the EP0 + * data in this case. Just read and discard it so that the RxFIFO + * does not become constipated. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOOUTSETUP), priv->ep0state); + stm32_rxfifo_discard(privep, bcnt); + privep->active = false; + } +} + +/**************************************************************************** + * Name: stm32_epout_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + struct stm32_req_s *privreq; + uint8_t *dest; + int buflen; + int readlen; + + /* Get a reference to the request at the head of the endpoint's request + * queue. + */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* Incoming data is available in the RxFIFO, but there is no read setup + * to receive the receive the data. This should not happen for data + * endpoints; those endpoints should have been NAKing any OUT data tokens. + * + * We should get here normally on OUT data phase following an OUT + * SETUP command. EP0 data will still receive data in this case and it + * should not be NAKing. + */ + + if (privep->epphy == 0) + { + stm32_ep0out_receive(privep, bcnt); + } + else + { + /* Otherwise, the data is lost. This really should not happen if + * NAKing is working as expected. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* Discard the data in the RxFIFO */ + + stm32_rxfifo_discard(privep, bcnt); + } + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", privep->epphy, privreq->req.len, privreq->req.xfrd); + usbtrace(TRACE_READ(privep->epphy), bcnt); + + /* Get the number of bytes to transfer from the RxFIFO */ + + buflen = privreq->req.len - privreq->req.xfrd; + DEBUGASSERT(buflen > 0 && buflen >= bcnt); + readlen = MIN(buflen, bcnt); + + /* Get the destination of the data transfer */ + + dest = privreq->req.buf + privreq->req.xfrd; + + /* Transfer the data from the RxFIFO to the request's data buffer */ + + stm32_rxfifo_read(privep, dest, readlen); + + /* If there were more bytes in the RxFIFO than could be held in the read + * request, then we will have to discard those. + */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Update the number of bytes transferred */ + + privreq->req.xfrd += readlen; +} + +/**************************************************************************** + * Name: stm32_epout_request + * + * Description: + * This function is called when either (1) new read request is received, or + * (2) a pending receive request completes. If there is no read in pending, + * then this function will initiate the next OUT (read) operation. + * + ****************************************************************************/ + +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; + + /* Make sure that there is not already a pending request request. If there is, + * just return, leaving the newly received request in the request queue. + */ + + if (!privep->active) + { + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an invalid + * read request is encountered. + */ + + for (; ; ) + { + /* Get a reference to the request at the head of the endpoint's request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* There are no read requests to be setup. Configure the hardware to + * NAK any incoming packets. (This should already be the case. I + * think that the hardware will automatically NAK after a transfer is + * completed until SNAK is cleared). + */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGHS_DOEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* This endpoint is no longer actively transferring */ + + privep->active = false; + return; + } + + ullvdbg("EP%d: len=%d\n", privep->epphy, privreq->req.len); + + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ + + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); + stm32_req_complete(privep, OK); + } + + /* Otherwise, we have a usable read request... break out of the loop */ + + else + { + break; + } + } + + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ + + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = STM32_OTGHS_DOEPTSIZ(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~(OTGHS_DOEPTSIZ_XFRSIZ_MASK | OTGHS_DOEPTSIZ_PKTCNT_MASK); + regval |= (xfrsize << OTGHS_DOEPTSIZ_XFRSIZ_SHIFT); + regval |= (pktcnt << OTGHS_DOEPTSIZ_PKTCNT_SHIFT); + stm32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* When an isochronous transfer is enabled the Even/Odd frame bit must + * also be set appropriately. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + if (privep->odd) + { + regval |= OTGHS_DOEPCTL_SODDFRM; + } + else + { + regval |= OTGHS_DOEPCTL_SEVNFRM; + } + } +#endif + + /* Clearing NAKing and enable the transfer. */ + + regval |= (OTGHS_DOEPCTL_CNAK | OTGHS_DOEPCTL_EPENA); + stm32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + + /* EP0 is a special case. We need to know when to switch back to + * normal SETUP processing. + */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_OUT; + } + } +} + +/**************************************************************************** + * Name: stm32_ep_flush + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void stm32_ep_flush(struct stm32_ep_s *privep) +{ + if (privep->isin) + { + stm32_txfifo_flush(OTGHS_GRSTCTL_TXFNUM_D(privep->epphy)); + } + else + { + stm32_rxfifo_flush(); + } +} + +/**************************************************************************** + * Name: stm32_req_complete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void stm32_req_complete(struct stm32_ep_s *privep, int16_t result) +{ + FAR struct stm32_req_s *privreq; + + /* Remove the request at the head of the request list */ + + privreq = stm32_req_remfirst(privep); + DEBUGASSERT(privreq != NULL); + + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == EP0) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: stm32_req_cancel + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void stm32_req_cancel(struct stm32_ep_s *privep, int16_t status) +{ + if (!stm32_rqempty(privep)) + { + stm32_ep_flush(privep); + } + + while (!stm32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (stm32_rqpeek(privep))->req.xfrd); + stm32_req_complete(privep, status); + } +} + +/**************************************************************************** + * Name: stm32_ep_findbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog) +{ + struct stm32_ep_s *privep; + uint8_t epphy = USB_EPNO(eplog); + + if (epphy >= STM32_NENDPOINTS) + { + return NULL; + } + + /* Is this an IN or an OUT endpoint? */ + + if (USB_ISEPIN(eplog)) + { + privep = &priv->epin[epphy]; + } + else + { + privep = &priv->epout[epphy]; + } + + /* Return endpoint reference */ + + DEBUGASSERT(privep->epphy == epphy); + return privep; +} + +/**************************************************************************** + * Name: stm32_req_dispatch + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static int stm32_req_dispatch(struct stm32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, + priv->ep0data, priv->ep0datlen); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_usbreset(struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int i; + + /* Clear the Remote Wake-up Signaling */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval &= ~OTGHS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGHS_DCTL); + + /* Flush the EP0 Tx FIFO */ + + stm32_txfifo_flush(OTGHS_GRSTCTL_TXFNUM_D(EP0)); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Mark all endpoints as available */ + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + /* Disable all end point interrupts */ + + for (i = 0; i < STM32_NENDPOINTS ; i++) + { + /* Disable endpoint interrupts */ + + stm32_putreg(0xff, STM32_OTGHS_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTGHS_DOEPINT(i)); + + /* Return write requests to the class implementation */ + + privep = &priv->epin[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset IN endpoint status */ + + privep->stalled = false; + + /* Return read requests to the class implementation */ + + privep = &priv->epout[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + stm32_putreg(0xffffffff, STM32_OTGHS_DAINT); + + /* Mask all device endpoint interrupts except EP0 */ + + regval = (OTGHS_DAINT_IEP(EP0) | OTGHS_DAINT_OEP(EP0)); + stm32_putreg(regval, STM32_OTGHS_DAINTMSK); + + /* Unmask OUT interrupts */ + + regval = (OTGHS_DOEPMSK_XFRCM | OTGHS_DOEPMSK_STUPM | OTGHS_DOEPMSK_EPDM); + stm32_putreg(regval, STM32_OTGHS_DOEPMSK); + + /* Unmask IN interrupts */ + + regval = (OTGHS_DIEPMSK_XFRCM | OTGHS_DIEPMSK_EPDM | OTGHS_DIEPMSK_TOM); + stm32_putreg(regval, STM32_OTGHS_DIEPMSK); + + /* Reset device address to 0 */ + + stm32_setaddress(priv, 0); + priv->devstate = DEVSTATE_DEFAULT; + priv->usbdev.speed = USB_SPEED_FULL; + + /* Re-configure EP0 */ + + stm32_ep0_configure(priv); + + /* Setup EP0 to receive SETUP packets */ + + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_testmode + * + * Description: + * Select test mode + * + ****************************************************************************/ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index) +{ + uint8_t testmode; + + testmode = index >> 8; + switch (testmode) + { + case 1: + priv->testmode = OTGHS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGHS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGHS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGHS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGHS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGHS_TESTMODE_DISABLED; + priv->stalled = true; + } + + priv->dotest = true; + stm32_ep0in_transmitzlp(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_stdrequest + * + * Description: + * Handle a stanard request on EP0. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver. + * + ****************************************************************************/ + +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq) +{ + FAR struct stm32_ep_s *privep; + + /* Handle standard request */ + + switch (ctrlreq->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ + + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); + + /* If the class driver accepted the configuration, then mark the + * device state as configured (or not, depending on the + * configuration). + */ + + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } +} + +/**************************************************************************** + * Name: stm32_ep0out_setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv) +{ + struct stm32_ctrlreq_s ctrlreq; + + /* Verify that a SETUP was received */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + + /* Terminate any pending requests */ + + stm32_req_cancel(&priv->epout[EP0], -EPROTO); + stm32_req_cancel(&priv->epin[EP0], -EPROTO); + + /* Assume NOT stalled */ + + priv->epout[EP0].stalled = false; + priv->epin[EP0].stalled = false; + priv->stalled = false; + + /* Starting to process a control request - update state */ + + priv->ep0state = EP0STATE_SETUP_PROCESS; + + /* And extract the little-endian 16-bit values to host order */ + + ctrlreq.type = priv->ctrlreq.type; + ctrlreq.req = priv->ctrlreq.req; + ctrlreq.value = GETUINT16(priv->ctrlreq.value); + ctrlreq.index = GETUINT16(priv->ctrlreq.index); + ctrlreq.len = GETUINT16(priv->ctrlreq.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrlreq.type, ctrlreq.req, ctrlreq.value, ctrlreq.index, ctrlreq.len); + + /* Check for a standard request */ + + if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + /* Dispatch any non-standard requests */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + /* Handle standard requests. */ + + stm32_ep0out_stdrequest(priv, &ctrlreq); + } + + /* Check if the setup processing resulted in a STALL */ + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + stm32_ep0_stall(priv); + } + + /* Reset state/data associated with thie SETUP request */ + + priv->ep0datlen = 0; +} + +/**************************************************************************** + * Name: stm32_epout + * + * Description: + * This is part of the OUT endpoint interrupt processing. This function + * handles the OUT event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + privep = &priv->epout[EP0]; + + /* In the EP0STATE_DATA_OUT state, we are receiving data into the + * request buffer. In that case, we must continue the request + * processing. + */ + + if (priv->ep0state == EP0STATE_DATA_OUT) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epout_complete(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an OUT request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + stm32_epout_complete(priv, &priv->epout[epno]); + } +} + +/**************************************************************************** + * Name: stm32_epout_interrupt + * + * Description: + * USB OUT endpoint interrupt handler. The core generates this interrupt when + * there is an interrupt is pending on one of the OUT endpoints of the core. + * The driver must read the OTGHS DAINT register to determine the exact number + * of the OUT endpoint on which the interrupt occurred, and then read the + * corresponding OTGHS DOEPINTx register to determine the exact cause of the + * interrupt. + * + ****************************************************************************/ + +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t daint; + uint32_t regval; + uint32_t doepint; + int epno; + + /* Get the pending, enabled interrupts for the OUT endpoint from the endpoint + * interrupt status register. + */ + + regval = stm32_getreg(STM32_OTGHS_DAINT); + regval &= stm32_getreg(STM32_OTGHS_DAINTMSK); + daint = (regval & OTGHS_DAINT_OEP_MASK) >> OTGHS_DAINT_OEP_SHIFT; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + regval = stm32_getreg(STM32_OTGHS_DAINT); + daint = (regval & OTGHS_DAINT_OEP_MASK) >> OTGHS_DAINT_OEP_SHIFT; + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTUNEXPECTED), + (uint16_t)regval); + + epno = 0; + while (daint) + { + if ((daint & 1) != 0) + { + regval = stm32_getreg(STM32_OTGHS_DOEPINT(epno)); + ulldbg("DOEPINT(%d) = %08x\n", epno, regval); + stm32_putreg(0xFF, STM32_OTGHS_DOEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an OUT interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Yes.. get the OUT endpoint interrupt status */ + + doepint = stm32_getreg(STM32_OTGHS_DOEPINT(epno)); + doepint &= stm32_getreg(STM32_OTGHS_DOEPMSK); + + /* Transfer completed interrupt. This interrupt is trigged when + * stm32_rxinterrupt() removes the last packet data from the RxFIFO. + * In this case, core internally sets the NAK bit for this endpoint to + * prevent it from receiving any more packets. + */ + + if ((doepint & OTGHS_DOEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_XFRC), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTGHS_DOEPINT_XFRC, STM32_OTGHS_DOEPINT(epno)); + + /* Handle the RX transfer data ready event */ + + stm32_epout(priv, epno); + } + + /* Endpoint disabled interrupt (ignored because this interrupt is + * used in polled mode by the endpoint disable logic). + */ +#if 1 + /* REVISIT: */ + if ((doepint & OTGHS_DOEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTGHS_DOEPINT_EPDISD, STM32_OTGHS_DOEPINT(epno)); + } +#endif + /* Setup Phase Done (control EPs) */ + + if ((doepint & OTGHS_DOEPINT_SETUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_SETUP), priv->ep0state); + + /* Handle the receipt of the IN SETUP packets now (OUT setup + * packet processing may be delayed until the accompanying + * OUT DATA is received) + */ + + if (priv->ep0state == EP0STATE_SETUP_READY) + { + stm32_ep0out_setup(priv); + } + stm32_putreg(OTGHS_DOEPINT_SETUP, STM32_OTGHS_DOEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_epin_runtestmode + * + * Description: + * Execute the test mode setup by the SET FEATURE request + * + ****************************************************************************/ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval = stm32_getreg(STM32_OTGHS_DCTL); + regval &= OTGHS_DCTL_TCTL_MASK; + regval |= (uint32_t)priv->testmode << OTGHS_DCTL_TCTL_SHIFT; + stm32_putreg(regval , STM32_OTGHS_DCTL); + + priv->dotest = 0; + priv->testmode = OTGHS_TESTMODE_DISABLED; +} + +/**************************************************************************** + * Name: stm32_epin + * + * Description: + * This is part of the IN endpoint interrupt processing. This function + * handles the IN event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + /* In the EP0STATE_DATA_IN state, we are sending data from request + * buffer. In that case, we must continue the request processing. + */ + + if (priv->ep0state == EP0STATE_DATA_IN) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epin_request(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + + /* Test mode is another special case */ + + if (priv->dotest) + { + stm32_epin_runtestmode(priv); + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an IN request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + /* Continue processing data from the endpoint write request queue */ + + stm32_epin_request(priv, privep); + } +} + +/**************************************************************************** + * Name: stm32_epin_txfifoempty + * + * Description: + * TxFIFO empty interrupt handling + * + ****************************************************************************/ + +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Continue processing the write request queue. This may mean sending + * more data from the existing request or terminating the current requests + * and (perhaps) starting the IN transfer from the next write request. + */ + + stm32_epin_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_epin_interrupt + * + * Description: + * USB IN endpoint interrupt handler. The core generates this interrupt when + * an interrupt is pending on one of the IN endpoints of the core. The driver + * must read the OTGHS DAINT register to determine the exact number of the IN + * endpoint on which the interrupt occurred, and then read the corresponding + * OTGHS DIEPINTx register to determine the exact cause of the interrupt. + * + ****************************************************************************/ + +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t diepint; + uint32_t daint; + uint32_t mask; + uint32_t empty; + int epno; + + /* Get the pending, enabled interrupts for the IN endpoint from the endpoint + * interrupt status register. + */ + + daint = stm32_getreg(STM32_OTGHS_DAINT); + daint &= stm32_getreg(STM32_OTGHS_DAINTMSK); + daint &= OTGHS_DAINT_IEP_MASK; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + daint = stm32_getreg(STM32_OTGHS_DAINT); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINUNEXPECTED), + (uint16_t)daint); + + daint &= OTGHS_DAINT_IEP_MASK; + epno = 0; + + while (daint) + { + if ((daint & 1) != 0) + { + ulldbg("DIEPINT(%d) = %08x\n", + epno, stm32_getreg(STM32_OTGHS_DIEPINT(epno))); + stm32_putreg(0xFF, STM32_OTGHS_DIEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an IN interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Get IN interrupt mask register. Bits 0-6 correspond to enabled + * interrupts as will be found in the DIEPINT interrupt status + * register. + */ + + mask = stm32_getreg(STM32_OTGHS_DIEPMSK); + + /* Check if the TxFIFO not empty interrupt is enabled for this + * endpoint in the DIEPMSK register. Bits n corresponds to + * endpoint n in the register. That condition corresponds to + * bit 7 of the DIEPINT interrupt status register. There is + * no TXFE bit in the mask register, so we fake one here. + */ + + empty = stm32_getreg(STM32_OTGHS_DIEPEMPMSK); + if ((empty & OTGHS_DIEPEMPMSK(epno)) != 0) + { + mask |= OTGHS_DIEPINT_TXFE; + } + + /* Now, read the interrupt status and mask out all disabled + * interrupts. + */ + + diepint = stm32_getreg(STM32_OTGHS_DIEPINT(epno)) & mask; + + /* Decode and process the enabled, pending interrupts */ + /* Transfer completed interrupt */ + + if ((diepint & OTGHS_DIEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC), + (uint16_t)diepint); + + /* It is possible that logic may be waiting for a the + * TxFIFO to become empty. We disable the TxFIFO empty + * interrupt here; it will be re-enabled if there is still + * insufficient space in the TxFIFO. + */ + + empty &= ~OTGHS_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTGHS_DIEPEMPMSK); + stm32_putreg(OTGHS_DIEPINT_XFRC, STM32_OTGHS_DIEPINT(epno)); + + /* IN transfer complete */ + + stm32_epin(priv, epno); + } + + /* Timeout condition */ + + if ((diepint & OTGHS_DIEPINT_TOC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TOC), (uint16_t)diepint); + stm32_putreg(OTGHS_DIEPINT_TOC, STM32_OTGHS_DIEPINT(epno)); + } + + /* IN token received when TxFIFO is empty. Applies to non-periodic IN + * endpoints only. This interrupt indicates that an IN token was received + * when the associated TxFIFO (periodic/non-periodic) was empty. This + * interrupt is asserted on the endpoint for which the IN token was + * received. + */ + + if ((diepint & OTGHS_DIEPINT_ITTXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_ITTXFE), (uint16_t)diepint); + stm32_epin_request(priv, &priv->epin[epno]); + stm32_putreg(OTGHS_DIEPINT_ITTXFE, STM32_OTGHS_DIEPINT(epno)); + } + + /* IN endpoint NAK effective (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTGHS_DIEPINT_INEPNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_INEPNE), (uint16_t)diepint); + stm32_putreg(OTGHS_DIEPINT_INEPNE, STM32_OTGHS_DIEPINT(epno)); + } +#endif + /* Endpoint disabled interrupt (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTGHS_DIEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EPDISD), (uint16_t)diepint); + stm32_putreg(OTGHS_DIEPINT_EPDISD, STM32_OTGHS_DIEPINT(epno)); + } +#endif + /* Transmit FIFO empty */ + + if ((diepint & OTGHS_DIEPINT_TXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint); + + /* If we were waiting for TxFIFO to become empty, the we might have both + * XFRC and TXFE interrupts pending. Since we do the same thing for both + * cases, ignore the TXFE if we have already processed the XFRC. + */ + + if ((diepint & OTGHS_DIEPINT_XFRC) == 0) + { + /* Mask further FIFO empty interrupts. This will be re-enabled + * whenever we need to wait for a FIFO event. + */ + + empty &= ~OTGHS_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTGHS_DIEPEMPMSK); + + /* Handle TxFIFO empty */ + + stm32_epin_txfifoempty(priv, epno); + } + + /* Clear the pending TxFIFO empty interrupt */ + + stm32_putreg(OTGHS_DIEPINT_TXFE, STM32_OTGHS_DIEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_resumeinterrupt + * + * Description: + * Resume/remote wakeup detected interrupt + * + ****************************************************************************/ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Restart the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTGHS_PCGCCTL); + regval &= ~(OTGHS_PCGCCTL_STPPCLK | OTGHS_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTGHS_PCGCCTL); +#endif + + /* Clear remote wake-up signaling */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval &= ~OTGHS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGHS_DCTL); + + /* Restore full power -- whatever that means for this particular board */ + + stm32_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: stm32_suspendinterrupt + * + * Description: + * USB suspend interrupt + * + ****************************************************************************/ + +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv) +{ +#ifdef CONFIG_USBDEV_LOWPOWER + uint32_t regval; +#endif + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + +#ifdef CONFIG_USBDEV_LOWPOWER + /* OTGHS_DSTS_SUSPSTS is set as long as the suspend condition is detected + * on USB. Check if we are still have the suspend condition, that we are + * connected to the host, and that we have been configured. + */ + + regval = stm32_getreg(STM32_OTGHS_DSTS); + + if ((regval & OTGHS_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED) + { + /* Switch off OTG HS clocking. Setting OTGHS_PCGCCTL_STPPCLK stops the + * PHY clock. + */ + + regval = stm32_getreg(STM32_OTGHS_PCGCCTL); + regval |= OTGHS_PCGCCTL_STPPCLK; + stm32_putreg(regval, STM32_OTGHS_PCGCCTL); + + /* Setting OTGHS_PCGCCTL_GATEHCLK gate HCLK to modules other than + * the AHB Slave and Master and wakeup logic. + */ + + regval |= OTGHS_PCGCCTL_GATEHCLK; + stm32_putreg(regval, STM32_OTGHS_PCGCCTL); + } +#endif + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + stm32_usbsuspend((FAR struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: stm32_rxinterrupt + * + * Description: + * RxFIFO non-empty interrupt. This interrupt indicates that there is at + * least one packet pending to be read from the RxFIFO. + * + ****************************************************************************/ + +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int bcnt; + int epphy; + + /* Disable the Rx status queue level interrupt */ + + regval = stm32_getreg(STM32_OTGHS_GINTMSK); + regval &= ~OTGHS_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTGHS_GINTMSK); + + /* Get the status from the top of the FIFO */ + + regval = stm32_getreg(STM32_OTGHS_GRXSTSP); + + /* Decode status fields */ + + epphy = (regval & OTGHS_GRXSTSD_EPNUM_MASK) >> OTGHS_GRXSTSD_EPNUM_SHIFT; + + if (epphy < STM32_NENDPOINTS) + { + privep = &priv->epout[epphy]; + + /* Handle the RX event according to the packet status field */ + + switch (regval & OTGHS_GRXSTSD_PKTSTS_MASK) + { + /* Global OUT NAK. This indicate that the global OUT NAK bit has taken + * effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't + * Care. + */ + + case OTGHS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, DPID = Actual Data PID. + */ + + case OTGHS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTGHS_GRXSTSD_BCNT_MASK) >> OTGHS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. This indicates that an OUT data transfer for + * the specified OUT endpoint has completed. After this entry is popped + * from the receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ + + case OTGHS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup stage for + * the specified endpoint has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core asserts a + * Setup interrupt on the specified control OUT endpoint (triggers an + * interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTGHS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + } + break; + + /* SETUP data packet received. This indicates that a SETUP packet for the + * specified endpoint is now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case OTGHS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ + + stm32_rxfifo_read(&priv->epout[EP0], (FAR uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero length, + * then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = stm32_getreg(STM32_OTGHS_DOEPCTL0); + regval |= OTGHS_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTGHS_DOEPCTL0); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word is + * popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTGHS_GRXSTSD_PKTSTS_MASK) >> OTGHS_GRXSTSD_PKTSTS_SHIFT); + } + break; + } + } + + /* Enable the Rx Status Queue Level interrupt */ + + regval = stm32_getreg(STM32_OTGHS_GINTMSK); + regval |= OTGHS_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTGHS_GINTMSK); +} + +/**************************************************************************** + * Name: stm32_enuminterrupt + * + * Description: + * Enumeration done interrupt + * + ****************************************************************************/ + +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Activate EP0 */ + + stm32_ep0in_activate(); + + /* Set USB turn-around time for the full speed device with internal PHY interface. */ + + regval = stm32_getreg(STM32_OTGHS_GUSBCFG); + regval &= ~OTGHS_GUSBCFG_TRDT_MASK; + regval |= OTGHS_GUSBCFG_TRDT(5); + stm32_putreg(regval, STM32_OTGHS_GUSBCFG); +} + +/**************************************************************************** + * Name: stm32_isocininterrupt + * + * Description: + * Incomplete isochronous IN transfer interrupt. Assertion of the incomplete + * isochronous IN transfer interrupt indicates an incomplete isochronous IN + * transfer on at least one of the isochronous IN endpoints. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv) +{ + int i; + + /* The application must read the endpoint control register for all isochronous + * IN endpoints to detect endpoints with incomplete IN data transfers. + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous IN endpoint? */ + + privep = &priv->epin[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTGHS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTGHS_DIEPCTL_EONUM) != 0); + soffn = ((dsts & OTGHS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous IN endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTGHS_DIEPCTL_USBAEP too" + stm32_epin_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_isocoutinterrupt + * + * Description: + * Incomplete periodic transfer interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + FAR struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t doepctl; + uint32_t dsts; + bool eonum; + bool soffn; + + /* When it receives an IISOOXFR interrupt, the application must read the + * control registers of all isochronous OUT endpoints to determine which + * endpoints had an incomplete transfer in the current microframe. An + * endpoint transfer is incomplete if both the following conditions are true: + * + * DOEPCTLx:EONUM = DSTS:SOFFN[0], and + * DOEPCTLx:EPENA = 1 + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous OUT endpoint? */ + + privep = &priv->epout[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTGHS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTGHS_DOEPCTL_EONUM) != 0); + soffn = ((dsts & OTGHS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous OUT endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTGHS_DOEPCTL_USBAEP too" + stm32_epout_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_sessioninterrupt + * + * Description: + * Session request/new session detected interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv) +{ +#warning "Missing logic" +} +#endif + +/**************************************************************************** + * Name: stm32_otginterrupt + * + * Description: + * OTG interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Check for session end detected */ + + regval = stm32_getreg(STM32_OTGHS_GOTGINT); + if ((regval & OTGHS_GOTGINT_SEDET) != 0) + { +#warning "Missing logic" + } + + /* Clear OTG interrupt */ + + stm32_putreg(retval, STM32_OTGHS_GOTGINT); +} +#endif + +/**************************************************************************** + * Name: stm32_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int stm32_usbinterrupt(int irq, FAR void *context) +{ + /* At present, there is only a single OTG HS device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + uint32_t regval; + + usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0); + + /* Assure that we are in device mode */ + + DEBUGASSERT((stm32_getreg(STM32_OTGHS_GINTSTS) & OTGHS_GINTSTS_CMOD) == OTGHS_GINTSTS_DEVMODE); + + /* Get the state of all enabled interrupts. We will do this repeatedly + * some interrupts (like RXFLVL) will generate additional interrupting + * events. + */ + + for (; ; ) + { + /* Get the set of pending, un-masked interrupts */ + + regval = stm32_getreg(STM32_OTGHS_GINTSTS); + regval &= stm32_getreg(STM32_OTGHS_GINTMSK); + + /* Break out of the loop when there are no further pending (and + * unmasked) interrupts to be processes. + */ + + if (regval == 0) + { + break; + } + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_INTPENDING), (uint16_t)regval); + + /* OUT endpoint interrupt. The core sets this bit to indicate that an + * interrupt is pending on one of the OUT endpoints of the core. + */ + + if ((regval & OTGHS_GINT_OEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT), (uint16_t)regval); + stm32_epout_interrupt(priv); + stm32_putreg(OTGHS_GINT_OEP, STM32_OTGHS_GINTSTS); + } + + /* IN endpoint interrupt. The core sets this bit to indicate that + * an interrupt is pending on one of the IN endpoints of the core. + */ + + if ((regval & OTGHS_GINT_IEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN), (uint16_t)regval); + stm32_epin_interrupt(priv); + stm32_putreg(OTGHS_GINT_IEP, STM32_OTGHS_GINTSTS); + } + + /* Host/device mode mismatch error interrupt */ + +#ifdef CONFIG_DEBUG_USB + if ((regval & OTGHS_GINT_MMIS) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_MISMATCH), (uint16_t)regval); + stm32_putreg(OTGHS_GINT_MMIS, STM32_OTGHS_GINTSTS); + } +#endif + + /* Resume/remote wakeup detected interrupt */ + + if ((regval & OTGHS_GINT_WKUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_WAKEUP), (uint16_t)regval); + stm32_resumeinterrupt(priv); + stm32_putreg(OTGHS_GINT_WKUP, STM32_OTGHS_GINTSTS); + } + + /* USB suspend interrupt */ + + if ((regval & OTGHS_GINT_USBSUSP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSPEND), (uint16_t)regval); + stm32_suspendinterrupt(priv); + stm32_putreg(OTGHS_GINT_USBSUSP, STM32_OTGHS_GINTSTS); + } + + /* Start of frame interrupt */ + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + if ((regval & OTGHS_GINT_SOF) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SOF), (uint16_t)regval); + stm32_putreg(OTGHS_GINT_SOF, STM32_OTGHS_GINTSTS); + } +#endif + + /* RxFIFO non-empty interrupt. Indicates that there is at least one + * packet pending to be read from the RxFIFO. + */ + + if ((regval & OTGHS_GINT_RXFLVL) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RXFIFO), (uint16_t)regval); + stm32_rxinterrupt(priv); + stm32_putreg(OTGHS_GINT_RXFLVL, STM32_OTGHS_GINTSTS); + } + + /* USB reset interrupt */ + + if ((regval & OTGHS_GINT_USBRST) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVRESET), (uint16_t)regval); + + /* Perform the device reset */ + + stm32_usbreset(priv); + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + stm32_putreg(OTGHS_GINT_USBRST, STM32_OTGHS_GINTSTS); + return OK; + } + + /* Enumeration done interrupt */ + + if ((regval & OTGHS_GINT_ENUMDNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_ENUMDNE), (uint16_t)regval); + stm32_enuminterrupt(priv); + stm32_putreg(OTGHS_GINT_ENUMDNE, STM32_OTGHS_GINTSTS); + } + + /* Incomplete isochronous IN transfer interrupt. When the core finds + * non-empty any of the isochronous IN endpoint FIFOs scheduled for + * the current frame non-empty, the core generates an IISOIXFR + * interrupt. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if ((regval & OTGHS_GINT_IISOIXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOIXFR), (uint16_t)regval); + stm32_isocininterrupt(priv); + stm32_putreg(OTGHS_GINT_IISOIXFR, STM32_OTGHS_GINTSTS); + } + + /* Incomplete isochronous OUT transfer. For isochronous OUT + * endpoints, the XFRC interrupt may not always be asserted. If the + * core drops isochronous OUT data packets, the application could fail + * to detect the XFRC interrupt. The incomplete Isochronous OUT data + * interrupt indicates that an XFRC interrupt was not asserted on at + * least one of the isochronous OUT endpoints. At this point, the + * endpoint with the incomplete transfer remains enabled, but no active + * transfers remain in progress on this endpoint on the USB. + */ + + if ((regval & OTGHS_GINT_IISOOXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOOXFR), (uint16_t)regval); + stm32_isocoutinterrupt(priv); + stm32_putreg(OTGHS_GINT_IISOOXFR, STM32_OTGHS_GINTSTS); + } +#endif + + /* Session request/new session detected interrupt */ + +#ifdef CONFIG_USBDEV_VBUSSENSING + if ((regval & OTGHS_GINT_SRQ) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SRQ), (uint16_t)regval); + stm32_sessioninterrupt(priv); + stm32_putreg(OTGHS_GINT_SRQ, STM32_OTGHS_GINTSTS); + } + + /* OTG interrupt */ + + if ((regval & OTGHS_GINT_OTG) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OTG), (uint16_t)regval); + stm32_otginterrupt(priv); + stm32_putreg(OTGHS_GINT_OTG, STM32_OTGHS_GINTSTS); + } +#endif + } + + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_enablegonak + * + * Description: + * Enable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* First, make sure that there is no GNOAKEFF interrupt pending. */ + +#if 0 + stm32_putreg(OTGHS_GINT_GONAKEFF, STM32_OTGHS_GINTSTS); +#endif + + /* Enable Global OUT NAK mode in the core. */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval |= OTGHS_DCTL_SGONAK; + stm32_putreg(regval, STM32_OTGHS_DCTL); + +#if 0 + /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK + * mode is in effect. When the interrupt handler pops the OUTNAK word + * from the RxFIFO, the core sets the GONAKEFF interrupt. + */ + + while ((stm32_getreg(STM32_OTGHS_GINTSTS) & OTGHS_GINT_GONAKEFF) == 0); + stm32_putreg(OTGHS_GINT_GONAKEFF, STM32_OTGHS_GINTSTS); + +#else + /* Since we are in the interrupt handler, we cannot wait inline for the + * GONAKEFF because it cannot occur until service the RXFLVL global interrupt + * and pop the OUTNAK word from the RxFIFO. + * + * Perhaps it is sufficient to wait for Global OUT NAK status to be reported + * in OTGHS DCTL register? + */ + + while ((stm32_getreg(STM32_OTGHS_DCTL) & OTGHS_DCTL_GONSTS) == 0); +#endif +} + +/**************************************************************************** + * Name: stm32_disablegonak + * + * Description: + * Disable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_disablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval |= OTGHS_DCTL_CGONAK; + stm32_putreg(regval, STM32_OTGHS_DCTL); +} + +/**************************************************************************** + * Name: stm32_epout_configure + * + * Description: + * Configure an OUT endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTGHS_DOEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTGHS_DOEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTGHS_DOEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTGHS_DOEPCTL0_MPSIZ_64; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTGHS_DOEPCTL_MPSIZ_SHIFT); + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGHS_DOEPCTL_USBAEP) == 0) + { + if (regval & OTGHS_DOEPCTL_NAKSTS) + { + regval |= OTGHS_DOEPCTL_CNAK; + } + + regval &= ~(OTGHS_DOEPCTL_MPSIZ_MASK | OTGHS_DOEPCTL_EPTYP_MASK); + regval |= mpsiz; + regval |= (eptype << OTGHS_DOEPCTL_EPTYP_SHIFT); + regval |= (OTGHS_DOEPCTL_SD0PID | OTGHS_DOEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTGHS_DAINTMSK); + regval |= OTGHS_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTGHS_DAINTMSK); + return OK; +} + +/**************************************************************************** + * Name: stm32_epin_configure + * + * Description: + * Configure an IN endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTGHS_DIEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTGHS_DIEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTGHS_DIEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTGHS_DIEPCTL0_MPSIZ_64; + break; + + default: + udbg("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTGHS_DIEPCTL_MPSIZ_SHIFT); + } + + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGHS_DIEPCTL_USBAEP) == 0) + { + if (regval & OTGHS_DIEPCTL_NAKSTS) + { + regval |= OTGHS_DIEPCTL_CNAK; + } + + regval &= ~(OTGHS_DIEPCTL_MPSIZ_MASK | OTGHS_DIEPCTL_EPTYP_MASK | OTGHS_DIEPCTL_TXFNUM_MASK); + regval |= mpsiz; + regval |= (eptype << OTGHS_DIEPCTL_EPTYP_SHIFT); + regval |= (eptype << OTGHS_DIEPCTL_TXFNUM_SHIFT); + regval |= (OTGHS_DIEPCTL_SD0PID | OTGHS_DIEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTGHS_DAINTMSK); + regval |= OTGHS_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTGHS_DAINTMSK); + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_configure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + uint16_t maxpacket; + uint8_t eptype; + int ret; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialize EP capabilities */ + + maxpacket = GETUINT16(desc->mxpacketsize); + eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK; + + /* Setup Endpoint Control Register */ + + if (privep->isin) + { + ret = stm32_epin_configure(privep, eptype, maxpacket); + } + else + { + ret = stm32_epout_configure(privep, eptype, maxpacket); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv) +{ + /* Enable EP0 IN and OUT */ + + (void)stm32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); + (void)stm32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); +} + +/**************************************************************************** + * Name: stm32_epout_disable + * + * Description: + * Diable an OUT endpoint will no longer be used + * + ****************************************************************************/ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + /* Before disabling any OUT endpoint, the application must enable + * Global OUT NAK mode in the core. + */ + + flags = enter_critical_section(); + stm32_enablegonak(privep); + + /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits + * int DOECPTL register. + */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGHS_DOEPCTL_USBAEP; + regval |= (OTGHS_DOEPCTL_EPDIS | OTGHS_DOEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTGHS_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGHS_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTGHS_DOEPINT_EPDISD, STM32_OTGHS_DOEPINT(privep->epphy)); + + /* Then disable the Global OUT NAK mode to continue receiving data + * from other non-disabled OUT endpoints. + */ + + stm32_disablegonak(privep); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTGHS_DAINTMSK); + regval &= ~OTGHS_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTGHS_DAINTMSK); + + /* Cancel any queued read requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_epin_disable + * + * Description: + * Disable an IN endpoint when it will no longer be used + * + ****************************************************************************/ + +static void stm32_epin_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* After USB reset, the endpoint will already be deactivated by the + * hardware. Trying to disable again will just hang in the wait. + */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTGHS_DIEPCTL_USBAEP) == 0) + { + return; + } + + /* This INEPNE wait logic is suggested by reference manual, but seems + * to get stuck to infinite loop. + */ + +#if 0 + /* Make sure that there is no pending IPEPNE interrupt (because we are + * to poll this bit below). + */ + + stm32_putreg(OTGHS_DIEPINT_INEPNE, STM32_OTGHS_DIEPINT(privep->epphy)); + + /* Set the endpoint in NAK mode */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGHS_DIEPCTL_USBAEP; + regval |= (OTGHS_DIEPCTL_EPDIS | OTGHS_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the INEPNE interrupt that indicates that we are now in NAK mode */ + + regaddr = STM32_OTGHS_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGHS_DIEPINT_INEPNE) == 0); + + /* Clear the INEPNE interrupt indication */ + + stm32_putreg(OTGHS_DIEPINT_INEPNE, regaddr); +#endif + + /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits + * the DIEPCTLx register. + */ + + flags = enter_critical_section(); + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTGHS_DIEPCTL_USBAEP; + regval |= (OTGHS_DIEPCTL_EPDIS | OTGHS_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the IN + * endpoint is completely disabled. + */ + + regaddr = STM32_OTGHS_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGHS_DIEPINT_EPDISD) == 0); + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTGHS_DIEPINT_EPDISD, stm32_getreg(regaddr)); + + /* Flush any data remaining in the TxFIFO */ + + stm32_txfifo_flush(OTGHS_GRSTCTL_TXFNUM_D(privep->epphy)); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTGHS_DAINTMSK); + regval &= ~OTGHS_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTGHS_DAINTMSK); + + /* Cancel any queued write requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_ep_disable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + if (privep->isin) + { + /* Disable the IN endpoint */ + + stm32_epin_disable(privep); + } + else + { + /* Disable the OUT endpoint */ + + stm32_epout_disable(privep); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_allocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + + privreq = (FAR struct stm32_req_s *)kmm_malloc(sizeof(struct stm32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct stm32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: stm32_ep_freereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: stm32_ep_allocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_freebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_submit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + FAR struct stm32_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + + /* Some sanity checking */ + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint. */ + + if (stm32_req_addlast(privep, privreq) && !privep->active) + { + /* If a request was added to an IN endpoint, then attempt to send + * the request data buffer now. + */ + + if (privep->isin) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the endpoint is not busy with another write request, + * then process the newly received write request now. + */ + + if (!privep->active) + { + stm32_epin_request(priv, privep); + } + } + + /* If the request was added to an OUT endpoint, then attempt to + * setup a read into the request data buffer now (this will, of + * course, fail if there is already a read in place). + */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + stm32_epout_request(priv, privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_ep_cancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_epout_setstall + * + * Description: + * Stall an OUT endpoint + * + ****************************************************************************/ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep) +{ +#if 1 + /* This implementation follows the requirements from the STM32 F4 reference + * manual. + */ + + uint32_t regaddr; + uint32_t regval; + + /* Put the core in the Global OUT NAK mode */ + + stm32_enablegonak(privep); + + /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits + * in the DOECPTL register. + */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= (OTGHS_DOEPCTL_EPDIS | OTGHS_DOEPCTL_STALL); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTGHS_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTGHS_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Disable Global OUT NAK mode */ + + stm32_disablegonak(privep); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#else + /* This implementation follows the STMicro code example. */ + /* REVISIT: */ + + uint32_t regaddr; + uint32_t regval; + + /* Stall the OUT endpoint by setting the STALL bit in the DOECPTL register. */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTGHS_DOEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#endif +} + +/**************************************************************************** + * Name: stm32_epin_setstall + * + * Description: + * Stall an IN endpoint + * + ****************************************************************************/ + +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + + /* Get the IN endpoint device control register */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* Then stall the endpoint */ + + regval |= OTGHS_DIEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_setstall + * + * Description: + * Stall an endpoint + * + ****************************************************************************/ + +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep) +{ + usbtrace(TRACE_EPSTALL, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + return stm32_epin_setstall(privep); + } + else + { + return stm32_epout_setstall(privep); + } +} + +/**************************************************************************** + * Name: stm32_ep_clrstall + * + * Description: + * Resume a stalled endpoint + * + ****************************************************************************/ + +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t stallbit; + uint32_t data0bit; + + usbtrace(TRACE_EPRESUME, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTGHS_DIEPCTL(privep->epphy); + stallbit = OTGHS_DIEPCTL_STALL; + data0bit = OTGHS_DIEPCTL_SD0PID; + } + else + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTGHS_DOEPCTL(privep->epphy); + stallbit = OTGHS_DOEPCTL_STALL; + data0bit = OTGHS_DOEPCTL_SD0PID; + } + + /* Clear the stall bit */ + + regval = stm32_getreg(regaddr); + regval &= ~stallbit; + + /* Set the DATA0 pid for interrupt and bulk endpoints */ + + if (privep->eptype == USB_EP_ATTR_XFER_INT || + privep->eptype == USB_EP_ATTR_XFER_BULK) + { + /* Writing this bit sets the DATA0 PID */ + + regval |= data0bit; + } + + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer stalled */ + + privep->stalled = false; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_stall + * + * Description: + * Stall or resume an endpoint + * + ****************************************************************************/ + +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + int ret; + + /* Set or clear the stall condition as requested */ + + flags = enter_critical_section(); + if (resume) + { + ret = stm32_ep_clrstall(privep); + } + else + { + ret = stm32_ep_setstall(privep); + } + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_stall + * + * Description: + * Stall endpoint 0 + * + ****************************************************************************/ + +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv) +{ + stm32_epin_setstall(&priv->epin[EP0]); + stm32_epout_setstall(&priv->epout[EP0]); + priv->stalled = true; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ep_alloc + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t eplog, bool in, + uint8_t eptype) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint8_t epavail; + irqstate_t flags; + int epphy; + int epno = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + epphy = USB_EPNO(eplog); + + /* Get the set of available endpoints depending on the direction */ + + flags = enter_critical_section(); + epavail = priv->epavail[in]; + + /* A physical address of 0 means that any endpoint will do */ + + if (epphy > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epphy >= STM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPNO), (uint16_t)epphy); + return NULL; + } + + /* Remove all of the candidate endpoints from the bitset except for the + * this physical endpoint number. + */ + + epavail &= (1 << epphy); + } + + /* Is there an available endpoint? */ + + if (epavail) + { + /* Yes.. Select the lowest numbered endpoint in the set of available + * endpoints. + */ + + for (epno = 1; epno < STM32_NENDPOINTS; epno++) + { + uint8_t bit = 1 << epno; + if ((epavail & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail[in] &= ~(1 << epno); + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return in ? &priv->epin[epno].ep : &priv->epout[epno].ep; + } + } + + /* We should not get here */ + } + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOEP), (uint16_t)eplog); + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: stm32_ep_free + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void stm32_ep_free(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail[privep->isin] |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int stm32_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* Return the last frame number of the last SOF detected by the hardware */ + + regval = stm32_getreg(STM32_OTGHS_DSTS); + return (int)((regval & OTGHS_DSTS_SOFFN_MASK) >> OTGHS_DSTS_SOFFN_SHIFT); +} + +/**************************************************************************** + * Name: stm32_wakeup + * + * Description: + * Exit suspend mode. + * + ****************************************************************************/ + +static int stm32_wakeup(struct usbdev_s *dev) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + /* Is wakeup enabled? */ + + flags = enter_critical_section(); + if (priv->wakeup) + { + /* Yes... is the core suspended? */ + + regval = stm32_getreg(STM32_OTGHS_DSTS); + if ((regval & OTGHS_DSTS_SUSPSTS) != 0) + { + /* Re-start the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTGHS_PCGCCTL); + regval &= ~(OTGHS_PCGCCTL_STPPCLK | OTGHS_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTGHS_PCGCCTL); +#endif + /* Activate Remote wakeup signaling */ + + regval = stm32_getreg(STM32_OTGHS_DCTL); + regval |= OTGHS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGHS_DCTL); + up_mdelay(5); + regval &= ~OTGHS_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTGHS_DCTL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_selfpowered + * + * Description: + * Sets/clears the device self-powered feature + * + ****************************************************************************/ + +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: stm32_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int stm32_pullup(struct usbdev_s *dev, bool enable) +{ + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + regval = stm32_getreg(STM32_OTGHS_DCTL); + if (enable) + { + /* Connect the device by clearing the soft disconnect bit in the DCTL + * register + */ + + regval &= ~OTGHS_DCTL_SDIS; + } + else + { + /* Connect the device by setting the soft disconnect bit in the DCTL + * register + */ + + regval |= OTGHS_DCTL_SDIS; + } + + stm32_putreg(regval, STM32_OTGHS_DCTL); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static void stm32_setaddress(struct stm32_usbdev_s *priv, uint16_t address) +{ + uint32_t regval; + + /* Set the device address in the DCFG register */ + + regval = stm32_getreg(STM32_OTGHS_DCFG); + regval &= ~OTGHS_DCFG_DAD_MASK; + regval |= ((uint32_t)address << OTGHS_DCFG_DAD_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DCFG); + + /* Are we now addressed? (i.e., do we have a non-NULL device + * address?) + */ + + if (address != 0) + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->addressed = true; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + priv->addressed = false; + } +} + +/**************************************************************************** + * Name: stm32_txfifo_flush + * + * Description: + * Flush the specific TX fifo. + * + ****************************************************************************/ + +static int stm32_txfifo_flush(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTGHS_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(regval, STM32_OTGHS_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_rxfifo_flush + * + * Description: + * Flush the RX fifo. + * + ****************************************************************************/ + +static int stm32_rxfifo_flush(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(OTGHS_GRSTCTL_RXFFLSH, STM32_OTGHS_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_swinitialize + * + * Description: + * Initialize all driver data structures. + * + ****************************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + int i; + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct stm32_usbdev_s)); + + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->epin[EP0].ep; + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + priv->epin[EP0].ep.priv = priv; + priv->epout[EP0].ep.priv = priv; + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epin[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->isin = 1; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYIN2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epout[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYOUT2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } +} + +/**************************************************************************** + * Name: stm32_hwinitialize + * + * Description: + * Configure the OTG HS core for operation. + * + ****************************************************************************/ + +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + uint32_t timeout; + uint32_t address; + int i; + + /* At start-up the core is in HS mode. */ + + /* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG + * register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO + * interrupts will occur when the TxFIFO is truly empty (not just half full). + */ + + stm32_putreg(OTGHS_GAHBCFG_TXFELVL, STM32_OTGHS_GAHBCFG); + + /* Set the PHYSEL bit in the GUSBCFG register to select the OTG HS serial + * transceiver: "This bit is always 1 with write-only access" + */ + + regval = stm32_getreg(STM32_OTGHS_GUSBCFG); + regval |= OTGHS_GUSBCFG_PHYSEL; + stm32_putreg(regval, STM32_OTGHS_GUSBCFG); + + /* Common USB OTG core initialization */ + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(OTGHS_GRSTCTL_CSRST, STM32_OTGHS_GRSTCTL); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + + regval = (OTGHS_GCCFG_PWRDWN | OTGHS_GCCFG_VBUSASEN | OTGHS_GCCFG_VBUSBSEN); +#ifndef CONFIG_USBDEV_VBUSSENSING + regval |= OTGHS_GCCFG_NOVBUSSENS; +#endif +#ifdef CONFIG_STM32_OTGHS_SOFOUTPUT + regval |= OTGHS_GCCFG_SOFOUTEN; +#endif + stm32_putreg(regval, STM32_OTGHS_GCCFG); + up_mdelay(20); + + /* Force Device Mode */ + + regval = stm32_getreg(STM32_OTGHS_GUSBCFG); + regval &= ~OTGHS_GUSBCFG_FHMOD; + regval |= OTGHS_GUSBCFG_FDMOD; + stm32_putreg(regval, STM32_OTGHS_GUSBCFG); + up_mdelay(50); + + /* Initialize device mode */ + /* Restart the PHY Clock */ + + stm32_putreg(0, STM32_OTGHS_PCGCCTL); + + /* Device configuration register */ + + regval = stm32_getreg(STM32_OTGHS_DCFG); + regval &= ~OTGHS_DCFG_PFIVL_MASK; + regval |= OTGHS_DCFG_PFIVL_80PCT; + stm32_putreg(regval, STM32_OTGHS_DCFG); + + /* Set full speed PHY */ + + regval = stm32_getreg(STM32_OTGHS_DCFG); + regval &= ~OTGHS_DCFG_DSPD_MASK; + regval |= OTGHS_DCFG_DSPD_FS; + stm32_putreg(regval, STM32_OTGHS_DCFG); + + /* Set Rx FIFO size */ + + stm32_putreg(STM32_RXFIFO_WORDS, STM32_OTGHS_GRXFSIZ); + + /* EP0 TX */ + + address = STM32_RXFIFO_WORDS; + regval = (address << OTGHS_DIEPTXF0_TX0FD_SHIFT) | + (STM32_EP0_TXFIFO_WORDS << OTGHS_DIEPTXF0_TX0FSA_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DIEPTXF0); + + /* EP1 TX */ + + address += STM32_EP0_TXFIFO_WORDS; + regval = (address << OTGHS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP1_TXFIFO_WORDS << OTGHS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DIEPTXF1); + + /* EP2 TX */ + + address += STM32_EP1_TXFIFO_WORDS; + regval = (address << OTGHS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP2_TXFIFO_WORDS << OTGHS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DIEPTXF2); + + /* EP3 TX */ + + address += STM32_EP2_TXFIFO_WORDS; + regval = (address << OTGHS_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP3_TXFIFO_WORDS << OTGHS_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTGHS_DIEPTXF3); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTGHS_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* Clear all pending Device Interrupts */ + + stm32_putreg(0, STM32_OTGHS_DIEPMSK); + stm32_putreg(0, STM32_OTGHS_DOEPMSK); + stm32_putreg(0, STM32_OTGHS_DIEPEMPMSK); + stm32_putreg(0xffffffff, STM32_OTGHS_DAINT); + stm32_putreg(0, STM32_OTGHS_DAINTMSK); + + /* Configure all IN endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTGHS_DIEPCTL(i)); + if ((regval & OTGHS_DIEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTGHS_DIEPCTL_EPENA | OTGHS_DIEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTGHS_DIEPCTL(i)); + stm32_putreg(0, STM32_OTGHS_DIEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTGHS_DIEPINT(i)); + } + + /* Configure all OUT endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTGHS_DOEPCTL(i)); + if ((regval & OTGHS_DOEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTGHS_DOEPCTL_EPENA | OTGHS_DOEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTGHS_DOEPCTL(i)); + stm32_putreg(0, STM32_OTGHS_DOEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTGHS_DOEPINT(i)); + } + + /* Disable all interrupts. */ + + stm32_putreg(0, STM32_OTGHS_GINTMSK); + + /* Clear any pending USB_OTG Interrupts */ + + stm32_putreg(0xffffffff, STM32_OTGHS_GOTGINT); + + /* Clear any pending interrupts */ + + stm32_putreg(0xbfffffff, STM32_OTGHS_GINTSTS); + + /* Disable the ULPI Clock enable in RCC AHB1 Register. This must + * be done because if both the ULPI and the FS PHY clock enable bits + * are set at the same time, the ARM never awakens from WFI due to + * some bug / errata in the chip. + */ + + regval = stm32_getreg(STM32_RCC_AHB1LPENR); + regval &= ~RCC_AHB1ENR_OTGHSULPIEN; + stm32_putreg(regval, STM32_RCC_AHB1LPENR); + + /* Enable the interrupts in the INTMSK */ + + regval = (OTGHS_GINT_RXFLVL | OTGHS_GINT_USBSUSP | OTGHS_GINT_ENUMDNE | + OTGHS_GINT_IEP | OTGHS_GINT_OEP | OTGHS_GINT_USBRST); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + regval |= (OTGHS_GINT_IISOIXFR | OTGHS_GINT_IISOOXFR); +#endif + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + regval |= OTGHS_GINT_SOF; +#endif + +#ifdef CONFIG_USBDEV_VBUSSENSING + regval |= (OTGHS_GINT_OTG | OTGHS_GINT_SRQ); +#endif + +#ifdef CONFIG_DEBUG_USB + regval |= OTGHS_GINT_MMIS; +#endif + + stm32_putreg(regval, STM32_OTGHS_GINTMSK); + + /* Enable the USB global interrupt by setting GINTMSK in the global OTG + * HS AHB configuration register; Set the TXFELVL bit in the GAHBCFG + * register so that TxFIFO interrupts will occur when the TxFIFO is truly + * empty (not just half full). + */ + + stm32_putreg(OTGHS_GAHBCFG_GINTMSK | OTGHS_GAHBCFG_TXFELVL, + STM32_OTGHS_GAHBCFG); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* At present, there is only a single OTG HS device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + int ret; + + usbtrace(TRACE_DEVINIT, 0); + + /* Here we assume that: + * + * 1. GPIOA and OTG HS peripheral clocking has already been enabled as part + * of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG HS alternate function pins + * + * PIN* SIGNAL DIRECTION + * ---- ----------- ---------- + * PA8 OTG_HS_SOF SOF clock output + * PA9 OTG_HS_VBUS VBUS input for device, Driven by external regulator by + * host (not an alternate function) + * PA10 OTG_HS_ID OTG ID pin (only needed in Dual mode) + * PA11 OTG_HS_DM D- I/O + * PA12 OTG_HS_DP D+ I/O + * + * *Pins may vary from device-to-device. + */ + + stm32_configgpio(GPIO_OTGHS_DM); + stm32_configgpio(GPIO_OTGHS_DP); + stm32_configgpio(GPIO_OTGHS_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable. */ + +#ifdef CONFIG_STM32_OTGHS_SOFOUTPUT + stm32_configgpio(GPIO_OTGHS_SOF); +#endif + + /* Uninitialize the hardware so that we know that we are starting from a + * known state. */ + + up_usbuninitialize(); + + /* Initialie the driver data structure */ + + stm32_swinitialize(priv); + + /* Attach the OTG HS interrupt handler */ + + ret = irq_attach(STM32_IRQ_OTGHS, stm32_usbinterrupt); + if (ret < 0) + { + udbg("irq_attach failed\n", ret); + goto errout; + } + + /* Initialize the USB OTG core */ + + stm32_hwinitialize(priv); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + stm32_usbreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_OTGHS); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_OTGHS, CONFIG_OTGHS_PRI); +#endif + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbhsuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* At present, there is only a single OTG HS device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + stm32_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(STM32_IRQ_OTGHS); + irq_detach(STM32_IRQ_OTGHS); + + /* Disable all endpoint interrupts */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + stm32_putreg(0xff, STM32_OTGHS_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTGHS_DOEPINT(i)); + } + + stm32_putreg(0, STM32_OTGHS_DIEPMSK); + stm32_putreg(0, STM32_OTGHS_DOEPMSK); + stm32_putreg(0, STM32_OTGHS_DIEPEMPMSK); + stm32_putreg(0, STM32_OTGHS_DAINTMSK); + stm32_putreg(0xffffffff, STM32_OTGHS_DAINT); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTGHS_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* TODO: Turn off USB power and clocking */ + + priv->devstate = DEVSTATE_DEFAULT; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG HS device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(STM32_IRQ_OTGHS); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + stm32_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG HS device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + stm32_usbreset(priv); + leave_critical_section(flags); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts */ + + flags = enter_critical_section(); + up_disable_irq(STM32_IRQ_OTGHS); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_STM32_OTGHSDEV */ diff --git a/arch/arm/src/stm32/stm32_otghshost.c b/arch/arm/src/stm32/stm32_otghshost.c new file mode 100644 index 0000000000000000000000000000000000000000..4c6252a0291e9d5b05404c052bbaca26b15e2862 --- /dev/null +++ b/arch/arm/src/stm32/stm32_otghshost.c @@ -0,0 +1,5306 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_otghshost.c + * + * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" /* Includes default GPIO settings */ +#include /* May redefine GPIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32_usbhost.h" + +#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32_OTGHS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* STM32 USB OTG HS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_STM32_OTGHS - Enable the STM32 USB OTG HS block + * CONFIG_STM32_SYSCFG - Needed + * + * Options: + * + * CONFIG_STM32_OTGHS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_STM32_OTGHS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_STM32_OTGHS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_STM32_OTGHS_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_STM32_OTGHS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * CONFIG_STM32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG. + * CONFIG_STM32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * packets. Depends on CONFIG_DEBUG. + */ + +/* Pre-requisites (partial) */ + +#ifndef CONFIG_STM32_SYSCFG +# error "CONFIG_STM32_SYSCFG is required" +#endif + +/* Default RxFIFO size */ + +#ifndef CONFIG_STM32_OTGHS_RXFIFO_SIZE +# define CONFIG_STM32_OTGHS_RXFIFO_SIZE 128 +#endif + +/* Default host non-periodic Tx FIFO size */ + +#ifndef CONFIG_STM32_OTGHS_NPTXFIFO_SIZE +# define CONFIG_STM32_OTGHS_NPTXFIFO_SIZE 96 +#endif + +/* Default host periodic Tx fifo size register */ + +#ifndef CONFIG_STM32_OTGHS_PTXFIFO_SIZE +# define CONFIG_STM32_OTGHS_PTXFIFO_SIZE 96 +#endif + +/* Maximum size of a descriptor */ + +#ifndef CONFIG_STM32_OTGHS_DESCSIZE +# define CONFIG_STM32_OTGHS_DESCSIZE 128 +#endif + +/* Register/packet debug depends on CONFIG_DEBUG */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_STM32_USBHOST_REGDEBUG +# undef CONFIG_STM32_USBHOST_PKTDUMP +#endif + +/* HCD Setup *******************************************************************/ +/* Hardware capabilities */ + +#define STM32_NHOST_CHANNELS 12 /* Number of host channels */ +#define STM32_MAX_PACKET_SIZE 64 /* Full speed max packet size */ +#define STM32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */ +#define STM32_EP0_MAX_PACKET_SIZE 64 /* EP0 HS max packet size */ +#define STM32_MAX_TX_FIFOS 12 /* Max number of TX FIFOs */ +#define STM32_MAX_PKTCOUNT 256 /* Max packet count */ +#define STM32_RETRY_COUNT 3 /* Number of ctrl transfer retries */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 /* In loop counts */ +#define STM32_FLUSH_DELAY 200000 /* In loop counts */ +#define STM32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ +#define STM32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ + +/* Ever-present MIN/MAX macros */ + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The following enumeration represents the various states of the USB host + * state machine (for debug purposes only) + */ + +enum stm32_smstate_e +{ + SMSTATE_DETACHED = 0, /* Not attached to a device */ + SMSTATE_ATTACHED, /* Attached to a device */ + SMSTATE_ENUM, /* Attached, enumerating */ + SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */ +}; + +/* This enumeration provides the reason for the channel halt. */ + +enum stm32_chreason_e +{ + CHREASON_IDLE = 0, /* Inactive (initial state) */ + CHREASON_FREED, /* Channel is no longer in use */ + CHREASON_XFRC, /* Transfer complete */ + CHREASON_NAK, /* NAK received */ + CHREASON_NYET, /* NotYet received */ + CHREASON_STALL, /* Endpoint stalled */ + CHREASON_TXERR, /* Transfer error received */ + CHREASON_DTERR, /* Data toggle error received */ + CHREASON_FRMOR, /* Frame overrun */ + CHREASON_CANCELLED /* Transfer cancelled */ +}; + +/* This structure retains the state of one host channel. NOTE: Since there + * is only one channel operation active at a time, some of the fields in + * in the structure could be moved in struct stm32_ubhost_s to achieve + * some memory savings. + */ + +struct stm32_chan_s +{ + sem_t waitsem; /* Channel wait semaphore */ + volatile uint8_t result; /* The result of the transfer */ + volatile uint8_t chreason; /* Channel halt reason. See enum stm32_chreason_e */ + uint8_t chidx; /* Channel index */ + uint8_t epno; /* Device endpoint number (0-127) */ + uint8_t eptype; /* See OTGHS_EPTYPE_* definitions */ + uint8_t funcaddr; /* Device function address */ + uint8_t speed; /* Device speed */ + uint8_t pid; /* Data PID */ + uint8_t npackets; /* Number of packets (for data toggle) */ + bool inuse; /* True: This channel is "in use" */ + volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */ + volatile bool outdata1; /* OUT data toggle. True: DATA01 */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + uint16_t maxpacket; /* Max packet size */ + uint16_t buflen; /* Buffer length (at start of transfer) */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ + volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */ + FAR uint8_t *buffer; /* Transfer buffer pointer */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + FAR void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* A channel represents on uni-directional endpoint. So, in the case of the + * bi-directional, control endpoint, there must be two channels to represent + * the endpoint. + */ + +struct stm32_ctrlinfo_s +{ + uint8_t inndx; /* EP0 IN control channel index */ + uint8_t outndx; /* EP0 OUT control channel index */ +}; + +/* This structure retains the state of the USB host controller */ + +struct stm32_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to structstm32_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Overall driver status */ + + volatile uint8_t smstate; /* The state of the USB host state machine */ + uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */ + volatile bool connected; /* Connected to device */ + volatile bool change; /* Connection change */ + volatile bool pscwait; /* True: Thread is waiting for a port event */ + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for a port event */ + struct stm32_ctrlinfo_s ep0; /* Root hub port EP0 description */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* The state of each host channel */ + + struct stm32_chan_s chan[STM32_MAX_TX_FIFOS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t addr, uint32_t value); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(addr,val) putreg32(val,addr) +#endif + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits); + +#ifdef CONFIG_STM32_USBHOST_PKTDUMP +# define stm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) +#else +# define stm32_pktdump(m,b,n) +#endif + +/* Semaphores ******************************************************************/ + +static void stm32_takesem(sem_t *sem); +#define stm32_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val); + +/* Channel management **********************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv); +static inline void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx); +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv); +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx); +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason); +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep); +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); + +/* Control/data transfer logic *************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx); +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void); +#endif +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req); +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif + +/* Interrupt handling **********************************************************/ +/* Lower level interrupt handlers */ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen); +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv); +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv); + +/* Second level interrupt handlers */ + +#ifdef CONFIG_STM32_OTGHS_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv); +#endif +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv); + +/* First level, global interrupt handler */ + +static int stm32_gint_isr(int irq, FAR void *context); + +/* Interrupt controls */ + +static void stm32_gint_enable(void); +static void stm32_gint_disable(void); +static inline void stm32_hostinit_enable(void); +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx); + +/* USB host controller operations **********************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const FAR struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer); +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer); +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected); +#endif +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv); +static void stm32_flush_txfifos(uint32_t txfnum); +static void stm32_flush_rxfifo(void); +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state); +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv); + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv); +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct stm32_usbhost_s g_usbhost; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = stm32_wait, + .enumerate = stm32_enumerate, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_printreg + * + * Description: + * Print the contents of an STM32xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: stm32_checkreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + stm32_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + stm32_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static uint32_t stm32_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_putreg(uint32_t addr, uint32_t val) +{ + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_modifyreg + * + * Description: + * Modify selected bits of an STM32 register. + * + ****************************************************************************/ + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, uint32_t setbits) +{ + stm32_putreg(addr, (((stm32_getreg(addr)) & ~clrbits) | setbits)); +} + +/**************************************************************************** + * Name: stm32_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void stm32_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: stm32_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: stm32_chan_alloc + * + * Description: + * Allocate a channel. + * + ****************************************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv) +{ + int chidx; + + /* Search the table of channels */ + + for (chidx = 0; chidx < STM32_NHOST_CHANNELS; chidx++) + { + /* Is this channel available? */ + + if (!priv->chan[chidx].inuse) + { + /* Yes... make it "in use" and return the index */ + + priv->chan[chidx].inuse = true; + return chidx; + } + } + + /* All of the channels are "in-use" */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_chan_free + * + * Description: + * Free a previoiusly allocated channel. + * + ****************************************************************************/ + +static void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx) +{ + DEBUGASSERT((unsigned)chidx < STM32_NHOST_CHANNELS); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_FREED); + + /* Mark the channel available */ + + priv->chan[chidx].inuse = false; +} + +/**************************************************************************** + * Name: stm32_chan_freeall + * + * Description: + * Free all channels. + * + ****************************************************************************/ + +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv) +{ + uint8_t chidx; + + /* Free all host channels */ + + for (chidx = 2; chidx < STM32_NHOST_CHANNELS; chidx ++) + { + stm32_chan_free(priv, chidx); + } +} + +/**************************************************************************** + * Name: stm32_chan_configure + * + * Description: + * Configure or re-configure a host channel. Host channels are configured + * when endpoint is allocated and EP0 (only) is re-configured with the + * max packet size or device address changes. + * + ****************************************************************************/ + +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + + /* Clear any old pending interrupts for this host channel. */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), 0xffffffff); + + /* Enable channel interrupts required for transfers on this channel. */ + + regval = 0; + + switch (chan->eptype) + { + case OTGHS_EPTYPE_CTRL: + case OTGHS_EPTYPE_BULK: + { +#ifdef HAVE_USBHOST_TRACE_VERBOSE + uint16_t intrace; + uint16_t outtrace; + + /* Determine the definitive trace ID to use below */ + + if (chan->eptype == OTGHS_EPTYPE_CTRL) + { + intrace = OTGHS_VTRACE2_CHANCONF_CTRL_IN; + outtrace = OTGHS_VTRACE2_CHANCONF_CTRL_OUT; + } + else + { + intrace = OTGHS_VTRACE2_CHANCONF_BULK_IN; + outtrace = OTGHS_VTRACE2_CHANCONF_BULK_OUT; + } +#endif + + /* Interrupts required for CTRL and BULK endpoints */ + + regval |= (OTGHS_HCINT_XFRC | OTGHS_HCINT_STALL | OTGHS_HCINT_NAK | + OTGHS_HCINT_TXERR | OTGHS_HCINT_DTERR); + + /* Additional setting for IN/OUT endpoints */ + + if (chan->in) + { + usbhost_vtrace2(intrace, chidx, chan->epno); + regval |= OTGHS_HCINT_BBERR; + } + else + { + usbhost_vtrace2(outtrace, chidx, chan->epno); + regval |= OTGHS_HCINT_NYET; + } + } + break; + + case OTGHS_EPTYPE_INTR: + { + /* Interrupts required for INTR endpoints */ + + regval |= (OTGHS_HCINT_XFRC | OTGHS_HCINT_STALL | OTGHS_HCINT_NAK | + OTGHS_HCINT_TXERR | OTGHS_HCINT_FRMOR | OTGHS_HCINT_DTERR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTGHS_VTRACE2_CHANCONF_INTR_IN, chidx, + chan->epno); + regval |= OTGHS_HCINT_BBERR; + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTGHS_VTRACE2_CHANCONF_INTR_OUT, chidx, + chan->epno); + } +#endif + } + break; + + case OTGHS_EPTYPE_ISOC: + { + /* Interrupts required for ISOC endpoints */ + + regval |= (OTGHS_HCINT_XFRC | OTGHS_HCINT_ACK | OTGHS_HCINT_FRMOR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTGHS_VTRACE2_CHANCONF_ISOC_IN, chidx, + chan->epno); + regval |= (OTGHS_HCINT_TXERR | OTGHS_HCINT_BBERR); + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTGHS_VTRACE2_CHANCONF_ISOC_OUT, chidx, + chan->epno); + } +#endif + } + break; + } + + stm32_putreg(STM32_OTGHS_HCINTMSK(chidx), regval); + + /* Enable the top level host channel interrupt. */ + + stm32_modifyreg(STM32_OTGHS_HAINTMSK, 0, OTGHS_HAINT(chidx)); + + /* Make sure host channel interrupts are enabled. */ + + stm32_modifyreg(STM32_OTGHS_GINTMSK, 0, OTGHS_GINT_HC); + + /* Program the HCCHAR register */ + + regval = ((uint32_t)chan->maxpacket << OTGHS_HCCHAR_MPSIZ_SHIFT) | + ((uint32_t)chan->epno << OTGHS_HCCHAR_EPNUM_SHIFT) | + ((uint32_t)chan->eptype << OTGHS_HCCHAR_EPTYP_SHIFT) | + ((uint32_t)chan->funcaddr << OTGHS_HCCHAR_DAD_SHIFT); + + /* Special case settings for low speed devices */ + + if (chan->speed == USB_SPEED_LOW) + { + regval |= OTGHS_HCCHAR_LSDEV; + } + + /* Special case settings for IN endpoints */ + + if (chan->in) + { + regval |= OTGHS_HCCHAR_EPDIR_IN; + } + + /* Special case settings for INTR endpoints */ + + if (chan->eptype == OTGHS_EPTYPE_INTR) + { + regval |= OTGHS_HCCHAR_ODDFRM; + } + + /* Write the channel configuration */ + + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), regval); +} + +/**************************************************************************** + * Name: stm32_chan_halt + * + * Description: + * Halt the channel associated with 'chidx' by setting the CHannel DISable + * (CHDIS) bit in in the HCCHAR register. + * + ****************************************************************************/ + +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason) +{ + uint32_t hcchar; + uint32_t intmsk; + uint32_t eptype; + unsigned int avail; + + /* Save the reason for the halt. We need this in the channel halt interrupt + * handling logic to know what to do next. + */ + + usbhost_vtrace2(OTGHS_VTRACE2_CHANHALT, chidx, chreason); + + priv->chan[chidx].chreason = (uint8_t)chreason; + + /* "The application can disable any channel by programming the OTG_HS_HCCHARx + * register with the CHDIS and CHENA bits set to 1. This enables the OTG_HS + * host to flush the posted requests (if any) and generates a channel halted + * interrupt. The application must wait for the CHH interrupt in OTG_HS_HCINTx + * before reallocating the channel for other transactions. The OTG_HS host + * does not interrupt the transaction that has already been started on the + * USB." + */ + + hcchar = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + hcchar |= (OTGHS_HCCHAR_CHDIS | OTGHS_HCCHAR_CHENA); + + /* Get the endpoint type from the HCCHAR register */ + + eptype = hcchar & OTGHS_HCCHAR_EPTYP_MASK; + + /* Check for space in the Tx FIFO to issue the halt. + * + * "Before disabling a channel, the application must ensure that there is at + * least one free space available in the non-periodic request queue (when + * disabling a non-periodic channel) or the periodic request queue (when + * disabling a periodic channel). The application can simply flush the + * posted requests when the Request queue is full (before disabling the + * channel), by programming the OTG_HS_HCCHARx register with the CHDIS bit + * set to 1, and the CHENA bit cleared to 0. + */ + + if (eptype == OTGHS_HCCHAR_EPTYP_CTRL || eptype == OTGHS_HCCHAR_EPTYP_BULK) + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTGHS_HNPTXSTS) & OTGHS_HNPTXSTS_NPTXFSAV_MASK; + } + else /* if (eptype == OTGHS_HCCHAR_EPTYP_ISOC || eptype == OTGHS_HCCHAR_EPTYP_INTR) */ + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTGHS_HPTXSTS) & OTGHS_HPTXSTS_PTXFSAVL_MASK; + } + + /* Check if there is any space available in the Tx FIFO. */ + + if (avail == 0) + { + /* The Tx FIFO is full... disable the channel to flush the requests */ + + hcchar &= ~OTGHS_HCCHAR_CHENA; + } + + /* Unmask the CHannel Halted (CHH) interrupt */ + + intmsk = stm32_getreg(STM32_OTGHS_HCINTMSK(chidx)); + intmsk |= OTGHS_HCINT_CHH; + stm32_putreg(STM32_OTGHS_HCINTMSK(chidx), intmsk); + + /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */ + + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), hcchar); +} + +/**************************************************************************** + * Name: stm32_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been started. + * + ****************************************************************************/ + +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags; + int ret; + + /* Disable interrupts so that the following operations will be atomic. On + * the OTG HS global interrupt needs to be disabled. However, here we disable + * all interrupts to exploit that fact that interrupts will be re-enabled + * while we wait. + */ + + flags = enter_critical_section(); + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; 'waiter' + * will be set to false and 'result' will be set appropriately when the + * transfer is completed. + */ + + do + { + /* Wait for the transfer to complete. NOTE the transfer may already + * completed before we get here or the transfer may complete while we + * wait here. + */ + + ret = sem_wait(&chan->waitsem); + + /* sem_wait should succeed. But it is possible that we could be + * awakened by a signal too. + */ + + DEBUGASSERT(ret == OK || get_errno() == EINTR); + } + while (chan->waiter); + + /* The transfer is complete re-enable interrupts and return the result */ + + ret = -(int)chan->result; + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + /* Is the transfer complete? */ + + if (chan->result != EBUSY) + { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + /* Wake'em up! */ + + usbhost_vtrace2(chan->in ? OTGHS_VTRACE2_CHANWAKEUP_IN : + OTGHS_VTRACE2_CHANWAKEUP_OUT, + chan->epno, chan->result); + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + /* Handle continuation of IN/OUT pipes */ + + if (chan->in) + { + stm32_in_next(priv, chan); + } + else + { + stm32_out_next(priv, chan); + } + } +#endif + } +} + +/**************************************************************************** + * Name: stm32_ctrlchan_alloc + * + * Description: + * Allocate and configured channels for a control pipe. + * + ****************************************************************************/ + +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep) +{ + FAR struct stm32_chan_s *chan; + int inndx; + int outndx; + + outndx = stm32_chan_alloc(priv); + if (outndx < 0) + { + return -ENOMEM; + } + + ctrlep->outndx = outndx; + chan = &priv->chan[outndx]; + chan->epno = epno; + chan->in = false; + chan->eptype = OTGHS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control OUT channels */ + + stm32_chan_configure(priv, outndx); + + /* Allocate and initialize the control IN channel */ + + inndx = stm32_chan_alloc(priv); + if (inndx < 0) + { + stm32_chan_free(priv, outndx); + return -ENOMEM; + } + + ctrlep->inndx = inndx; + chan = &priv->chan[inndx]; + chan->epno = epno; + chan->in = true; + chan->eptype = OTGHS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control IN channels */ + + stm32_chan_configure(priv, inndx); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlep_alloc + * + * Description: + * Allocate a container and channels for control pipe. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct usbhost_hubport_s *hport; + FAR struct stm32_ctrlinfo_s *ctrlep; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a container for the control endpoint */ + + ctrlep = (FAR struct stm32_ctrlinfo_s *)kmm_malloc(sizeof(struct stm32_ctrlinfo_s)); + if (ctrlep == NULL) + { + udbg("ERROR: Failed to allocate control endpoint container\n"); + return -ENOMEM; + } + + /* Then allocate and configure the IN/OUT channnels */ + + ret = stm32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK, + hport->funcaddr, hport->speed, ctrlep); + if (ret < 0) + { + udbg("ERROR: stm32_ctrlchan_alloc failed: %d\n", ret); + kmm_free(ctrlep); + return ret; + } + + /* Return a pointer to the control pipe container as the pipe "handle" */ + + *ep = (usbhost_ep_t)ctrlep; + return OK; +} + +/************************************************************************************ + * Name: stm32_xfrep_alloc + * + * Description: + * Allocate and configure one unidirectional endpoint. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + FAR struct stm32_chan_s *chan; + int chidx; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a host channel for the endpoint */ + + chidx = stm32_chan_alloc(priv); + if (chidx < 0) + { + udbg("ERROR: Failed to allocate a host channel\n"); + return -ENOMEM; + } + + /* Decode the endpoint descriptor to initialize the channel data structures. + * Note: Here we depend on the fact that the endpoint point type is + * encoded in the same way in the endpoint descriptor as it is in the OTG + * HS hardware. + */ + + chan = &priv->chan[chidx]; + chan->epno = epdesc->addr & USB_EPNO_MASK; + chan->in = epdesc->in; + chan->eptype = epdesc->xfrtype; + chan->funcaddr = hport->funcaddr; + chan->speed = hport->speed; + chan->maxpacket = epdesc->mxpacketsize; + chan->indata1 = false; + chan->outdata1 = false; + + /* Then configure the endpoint */ + + stm32_chan_configure(priv, chidx); + + /* Return the index to the allocated channel as the endpoint "handle" */ + + *ep = (usbhost_ep_t)chidx; + return OK; +} + +/**************************************************************************** + * Name: stm32_transfer_start + * + * Description: + * Start at transfer on the select IN or OUT channel. + * + ****************************************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int npackets; + unsigned int maxpacket; + unsigned int avail; + unsigned int wrsize; + unsigned int minsize; + + /* Set up the initial state of the transfer */ + + chan = &priv->chan[chidx]; + + usbhost_vtrace2(OTGHS_VTRACE2_STARTTRANSFER, chidx, chan->buflen); + + chan->result = EBUSY; + chan->inflight = 0; + chan->xfrd = 0; + priv->chidx = chidx; + + /* Compute the expected number of packets associated to the transfer. + * If the transfer length is zero (or less than the size of one maximum + * size packet), then one packet is expected. + */ + + /* If the transfer size is greater than one packet, then calculate the + * number of packets that will be received/sent, including any partial + * final packet. + */ + + maxpacket = chan->maxpacket; + + if (chan->buflen > maxpacket) + { + npackets = (chan->buflen + maxpacket - 1) / maxpacket; + + /* Clip if the buffer length if it exceeds the maximum number of + * packets that can be transferred (this should not happen). + */ + + if (npackets > STM32_MAX_PKTCOUNT) + { + npackets = STM32_MAX_PKTCOUNT; + chan->buflen = STM32_MAX_PKTCOUNT * maxpacket; + usbhost_trace2(OTGHS_TRACE2_CLIP, chidx, chan->buflen); + } + } + else + { + /* One packet will be sent/received (might be a zero length packet) */ + + npackets = 1; + } + + /* If it is an IN transfer, then adjust the size of the buffer UP to + * a full number of packets. Hmmm... couldn't this cause an overrun + * into unallocated memory? + */ + +#if 0 /* Think about this */ + if (chan->in) + { + /* Force the buffer length to an even multiple of maxpacket */ + + chan->buflen = npackets * maxpacket; + } +#endif + + /* Save the number of packets in the transfer. We will need this in + * order to set the next data toggle correctly when the transfer + * completes. + */ + + chan->npackets = (uint8_t)npackets; + + /* Setup the HCTSIZn register */ + + regval = ((uint32_t)chan->buflen << OTGHS_HCTSIZ_XFRSIZ_SHIFT) | + ((uint32_t)npackets << OTGHS_HCTSIZ_PKTCNT_SHIFT) | + ((uint32_t)chan->pid << OTGHS_HCTSIZ_DPID_SHIFT); + stm32_putreg(STM32_OTGHS_HCTSIZ(chidx), regval); + + /* Setup the HCCHAR register: Frame oddness and host channel enable */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + + /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd + * Frame. This field is applicable for only periodic (isochronous and + * interrupt) channels. + */ + + if ((stm32_getreg(STM32_OTGHS_HFNUM) & 1) == 0) + { + regval |= OTGHS_HCCHAR_ODDFRM; + } + else + { + regval &= ~OTGHS_HCCHAR_ODDFRM; + } + + regval &= ~OTGHS_HCCHAR_CHDIS; + regval |= OTGHS_HCCHAR_CHENA; + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), regval); + + /* If this is an out transfer, then we need to do more.. we need to copy + * the outgoing data into the correct TxFIFO. + */ + + if (!chan->in && chan->buflen > 0) + { + /* Handle non-periodic (CTRL and BULK) OUT transfers differently than + * periodic (INTR and ISOC) OUT transfers. + */ + + minsize = MIN(chan->buflen, chan->maxpacket); + + switch (chan->eptype) + { + case OTGHS_EPTYPE_CTRL: /* Non periodic transfer */ + case OTGHS_EPTYPE_BULK: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTGHS_HNPTXSTS); + avail = ((regval & OTGHS_HNPTXSTS_NPTXFSAV_MASK) >> OTGHS_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + } + break; + + /* Periodic transfer */ + + case OTGHS_EPTYPE_INTR: + case OTGHS_EPTYPE_ISOC: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTGHS_HPTXSTS); + avail = ((regval & OTGHS_HPTXSTS_PTXFSAVL_MASK) >> OTGHS_HPTXSTS_PTXFSAVL_SHIFT) << 2; + } + break; + + default: + DEBUGASSERT(false); + return; + } + + /* Is there space in the TxFIFO to hold the minimum size packet? */ + + if (minsize <= avail) + { + /* Yes.. Get the size of the biggest thing that we can put in the Tx FIFO now */ + + wrsize = chan->buflen; + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Write packet into the Tx FIFO. */ + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); + } + + /* Did we put the entire buffer into the Tx FIFO? */ + + if (chan->buflen > avail) + { + /* No, there was insufficient space to hold the entire transfer ... + * Enable the Tx FIFO interrupt to handle the transfer when the Tx + * FIFO becomes empty. + */ + + stm32_txfe_enable(priv, chidx); + } + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Get the current frame number. The frame number (FRNUM) field increments + * when a new SOF is transmitted on the USB, and is cleared to 0 when it + * reaches 0x3fff. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void) +{ + return (uint16_t)(stm32_getreg(STM32_OTGHS_HFNUM) & OTGHS_HFNUM_FRNUM_MASK); +} +#endif + +/**************************************************************************** + * Name: stm32_ctrl_sendsetup + * + * Description: + * Send an IN/OUT SETUP packet. + * + ****************************************************************************/ + +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop while the device reports NAK (and a timeout is not exceeded */ + + chan = &priv->chan[ep0->outndx]; + start = clock_systimer(); + + do + { + /* Send the SETUP packet */ + + chan->pid = OTGHS_PID_SETUP; + chan->buffer = (FAR uint8_t *)req; + chan->buflen = USB_SIZEOF_CTRLREQ; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete */ + + ret = stm32_chan_wait(priv, chan); + + /* Return on success and for all failures other than EAGAIN. EAGAIN + * means that the device NAKed the SETUP command and that we should + * try a few more times. + */ + + if (ret != -EAGAIN) + { + /* Output some debug information if the transfer failed */ + + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_TRNSFRFAILED, ret); + } + + /* Return the result in any event */ + + return ret; + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_SETUP_DELAY); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_ctrl_senddata + * + * Description: + * Send data in the data phase of an OUT control transfer. Or send status + * in the status phase of an IN control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->outndx]; + int ret; + + /* Save buffer information */ + + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set the DATA PID */ + + if (buflen == 0) + { + /* For status OUT stage with buflen == 0, set PID DATA1 */ + + chan->outdata1 = true; + } + + /* Set the Data PID as per the outdata1 boolean */ + + chan->pid = chan->outdata1 ? OTGHS_PID_DATA1 : OTGHS_PID_DATA0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_ctrl_recvdata + * + * Description: + * Receive data in the data phase of an IN control transfer. Or receive status + * in the status phase of an OUT control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->inndx]; + int ret; + + /* Save buffer information */ + + chan->pid = OTGHS_PID_DATA1; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->inndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_in_setup + * + * Description: + * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTGHS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTGHS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the IN data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_ISOCIN, chidx, chan->buflen); + chan->pid = OTGHS_PID_DATA0; + } + break; + + case OTGHS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_BULKIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTGHS_PID_DATA1 : OTGHS_PID_DATA0; + } + break; + + case OTGHS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_INTRIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTGHS_PID_DATA1 : OTGHS_PID_DATA0; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_in_transfer + * + * Description: + * Transfer 'buflen' bytes into 'buffer' from an IN channel. + * + ****************************************************************************/ + +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + start = clock_systimer(); + while (chan->xfrd < chan->buflen) + { + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* EAGAIN indicates that the device NAKed the transfer and we need + * do try again. Anything else (success or other errors) will + * cause use to return + */ + + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + } + } + + return (ssize_t)chan->xfrd; +} + +/**************************************************************************** + * Name: stm32_in_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_in_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_in_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_in_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_out_setup + * + * Description: + * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTGHS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTGHS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the OUT data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_ISOCOUT, chidx, chan->buflen); + chan->pid = OTGHS_PID_DATA0; + } + break; + + case OTGHS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_BULKOUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTGHS_PID_DATA1 : OTGHS_PID_DATA0; + } + break; + + case OTGHS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTGHS_VTRACE2_INTROUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTGHS_PID_DATA1 : OTGHS_PID_DATA0; + + /* Toggle the OUT data PID for the next transfer */ + + chan->outdata1 ^= true; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_out_transfer + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' through an OUT channel. + * + ****************************************************************************/ + +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + size_t xfrlen; + ssize_t xfrd; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + start = clock_systimer(); + xfrd = 0; + + while (buflen > 0) + { + /* Transfer one packet at a time. The hardware is capable of queueing + * multiple OUT packets, but I just haven't figured out how to handle + * the case where a single OUT packet in the group is NAKed. + */ + + xfrlen = MIN(chan->maxpacket, buflen); + chan->buffer = buffer; + chan->buflen = xfrlen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* Handle transfer failures */ + + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + udbg("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Is this flush really necessary? What does the hardware do with the + * data in the FIFO when the NAK occurs? Does it discard it? + */ + + stm32_flush_txfifos(OTGHS_GRSTCTL_TXFNUM_HALL); + + /* Get the device a little time to catch up. Then retry the transfer + * using the same buffer pointer and length. + */ + + usleep(20*1000); + } + else + { + /* Successfully transferred. Update the buffer pointer and length */ + + buffer += xfrlen; + buflen -= xfrlen; + xfrd += chan->xfrd; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: stm32_out_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_out_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uvdbg("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_out_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + udbg("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + udbg("ERROR: stm32_out_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_gint_wrpacket + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with + * 'chidx' (non-DMA). + * + ****************************************************************************/ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen) +{ + FAR uint32_t *src; + uint32_t fifo; + int buflen32; + + stm32_pktdump("Sending", buffer, buflen); + + /* Get the number of 32-byte words associated with this byte size */ + + buflen32 = (buflen + 3) >> 2; + + /* Get the address of the Tx FIFO associated with this channel */ + + fifo = STM32_OTGHS_DFIFO_HCH(chidx); + + /* Transfer all of the data into the Tx FIFO */ + + src = (FAR uint32_t *)buffer; + for (; buflen32 > 0; buflen32--) + { + uint32_t data = *src++; + stm32_putreg(fifo, data); + } + + /* Increment the count of bytes "in-flight" in the Tx FIFO */ + + priv->chan[chidx].inflight += buflen; +} + +/**************************************************************************** + * Name: stm32_gint_hcinisr + * + * Description: + * USB OTG HS host IN channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTGHS_HCINT(chidx)); + regval = stm32_getreg(STM32_OTGHS_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTGHS_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_ACK); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTGHS_HCINT_STALL) != 0) + { + /* Clear the NAK and STALL Conditions. */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), (OTGHS_HCINT_NAK | OTGHS_HCINT_STALL)); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + + /* When there is a STALL, clear any pending NAK so that it is not + * processed below. + */ + + pending &= ~OTGHS_HCINT_NAK; + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if ((pending & OTGHS_HCINT_DTERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the NAK and data toggle error conditions */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), (OTGHS_HCINT_NAK | OTGHS_HCINT_DTERR)); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + if ((pending & OTGHS_HCINT_FRMOR) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the FRaMe OverRun (FRMOR) condition */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTGHS_HCINT_XFRC) != 0) + { + /* Clear the TransFeR Completed (XFRC) condition */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_XFRC); + + /* Then handle the transfer completion event based on the endpoint type */ + + if (chan->eptype == OTGHS_EPTYPE_CTRL || chan->eptype == OTGHS_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear any pending NAK condition. The 'indata1' data toggle + * should have been appropriately updated by the RxFIFO + * logic as each packet was received. + */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_NAK); + } + else if (chan->eptype == OTGHS_EPTYPE_INTR) + { + /* Force the next transfer on an ODD frame */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + regval |= OTGHS_HCCHAR_ODDFRM; + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), regval); + + /* Set the request done state */ + + chan->result = OK; + } + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTGHS_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTGHS_HCINTMSK(chidx)); + regval &= ~OTGHS_HCINT_CHH; + stm32_putreg(STM32_OTGHS_HCINTMSK(chidx), regval); + + /* Update the request state based on the host state machine state */ + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the request I/O error result */ + + chan->result = EIO; + } + else if (chan->chreason == CHREASON_NAK) + { + /* Halt on NAK only happens on an INTR channel. Fetch the HCCHAR register + * and check for an interrupt endpoint. + */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + if ((regval & OTGHS_HCCHAR_EPTYP_MASK) == OTGHS_HCCHAR_EPTYP_INTR) + { + /* Toggle the IN data toggle (Used by Bulk and INTR only) */ + + chan->indata1 ^= true; + } + + /* Set the NAK error result */ + + chan->result = EAGAIN; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame overrun error result */ + + chan->result = EPIPE; + } + + /* Clear the CHannel Halted (CHH) condition */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_CHH); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTGHS_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the Transaction ERror (TXERR) condition */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_TXERR); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTGHS_HCINT_NAK) != 0) + { + /* For a BULK transfer, the hardware is capable of retrying + * automatically on a NAK. However, this is not always + * what we need to do. So we always halt the transfer and + * return control to high level logic in the event of a NAK. + */ + +#if 1 + /* Halt the interrupt channel */ + + if (chan->eptype == OTGHS_EPTYPE_INTR) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + } + + /* Re-activate CTRL and BULK channels. + * REVISIT: This can cause a lot of interrupts! + */ + + else if (chan->eptype == OTGHS_EPTYPE_CTRL || + chan->eptype == OTGHS_EPTYPE_BULK) + { + /* Re-activate the channel by clearing CHDIS and assuring that + * CHENA is set + */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + regval |= OTGHS_HCCHAR_CHENA; + regval &= ~OTGHS_HCCHAR_CHDIS; + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), regval); + } +#else + /* Halt all transfers on the NAK -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); +#endif + + /* Clear the NAK condition */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_NAK); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_hcoutisr + * + * Description: + * USB OTG HS host OUT channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTGHS_HCINT(chidx)); + regval = stm32_getreg(STM32_OTGHS_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullvdbg("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTGHS_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_ACK); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + else if ((pending & OTGHS_HCINT_FRMOR) != 0) + { + /* Halt the channel (probably not necessary for FRMOR) */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTGHS_HCINT_XFRC) != 0) + { + /* Decrement the number of bytes remaining by the number of + * bytes that were "in-flight". + */ + + priv->chan[chidx].buffer += priv->chan[chidx].inflight; + priv->chan[chidx].xfrd += priv->chan[chidx].inflight; + priv->chan[chidx].inflight = 0; + + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear the pending the TransFeR Completed (XFRC) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_XFRC); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTGHS_HCINT_STALL) != 0) + { + /* Clear the pending the STALL response receiv (STALL) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_STALL); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTGHS_HCINT_NAK) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + + /* Clear the pending the NAK response received (NAK) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_NAK); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTGHS_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the pending the Transaction ERror (TXERR) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_TXERR); + } + + /* Check for a NYET interrupt */ + +#if 0 /* NYET is a reserved bit in the HCINT register */ + else if ((pending & OTGHS_HCINT_NYET) != 0) + { + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_NYET); + + /* Clear the pending the NYET interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_NYET); + } +#endif + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if (pending & OTGHS_HCINT_DTERR) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), (OTGHS_HCINT_DTERR | OTGHS_HCINT_NAK)); + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTGHS_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTGHS_HCINTMSK(chidx)); + regval &= ~OTGHS_HCINT_CHH; + stm32_putreg(STM32_OTGHS_HCINTMSK(chidx), regval); + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + + /* Read the HCCHAR register to get the HCCHAR register to get + * the endpoint type. + */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + + /* Is it a bulk endpoint? Were an odd number of packets + * transferred? + */ + + if ((regval & OTGHS_HCCHAR_EPTYP_MASK) == OTGHS_HCCHAR_EPTYP_BULK && + (chan->npackets & 1) != 0) + { + /* Yes to both... toggle the data out PID */ + + chan->outdata1 ^= true; + } + } + else if (chan->chreason == CHREASON_NAK || + chan->chreason == CHREASON_NYET) + { + /* Set the try again later result */ + + chan->result = EAGAIN; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the I/O failure result */ + + chan->result = EIO; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame error result */ + + chan->result = EPIPE; + } + + /* Clear the pending the CHannel Halted (CHH) interrupt */ + + stm32_putreg(STM32_OTGHS_HCINT(chidx), OTGHS_HCINT_CHH); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_connected + * + * Description: + * Handle a connection event. + * + ****************************************************************************/ + +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv) +{ + /* We we previously disconnected? */ + + if (!priv->connected) + { + /* Yes.. then now we are connected */ + + usbhost_vtrace1(OTGHS_VTRACE1_CONNECTED, 0); + priv->connected = true; + priv->change = true; + DEBUGASSERT(priv->smstate == SMSTATE_DETACHED); + + /* Notify any waiters */ + + priv->smstate = SMSTATE_ATTACHED; + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_disconnected + * + * Description: + * Handle a disconnection event. + * + ****************************************************************************/ + +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv) +{ + /* Were we previously connected? */ + + if (priv->connected) + { + /* Yes.. then we no longer connected */ + + usbhost_vtrace1(OTGHS_VTRACE1_DISCONNECTED, 0); + + /* Are we bound to a class driver? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class driver */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Re-Initialize Host for new Enumeration */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = true; + stm32_chan_freeall(priv); + + priv->rhport.hport.speed = USB_SPEED_FULL; + + /* Notify any waiters that there is a change in the connection state */ + + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_sofisr + * + * Description: + * USB OTG HS start-of-frame interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_OTGHS_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle SOF interrupt */ +#warning "Do what?" + + /* Clear pending SOF interrupt */ + + stm32_putreg(STM32_OTGHS_GINTSTS, OTGHS_GINT_SOF); +} +#endif + +/**************************************************************************** + * Name: stm32_gint_rxflvlisr + * + * Description: + * USB OTG HS RxFIFO non-empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv) +{ + FAR uint32_t *dest; + uint32_t grxsts; + uint32_t intmsk; + uint32_t hcchar; + uint32_t hctsiz; + uint32_t fifo; + int bcnt; + int bcnt32; + int chidx; + int i; + + /* Disable the RxFIFO non-empty interrupt */ + + intmsk = stm32_getreg(STM32_OTGHS_GINTMSK); + intmsk &= ~OTGHS_GINT_RXFLVL; + stm32_putreg(STM32_OTGHS_GINTMSK, intmsk); + + /* Read and pop the next status from the Rx FIFO */ + + grxsts = stm32_getreg(STM32_OTGHS_GRXSTSP); + ullvdbg("GRXSTS: %08x\n", grxsts); + + /* Isolate the channel number/index in the status word */ + + chidx = (grxsts & OTGHS_GRXSTSH_CHNUM_MASK) >> OTGHS_GRXSTSH_CHNUM_SHIFT; + + /* Get the host channel characteristics register (HCCHAR) for this channel */ + + hcchar = stm32_getreg(STM32_OTGHS_HCCHAR(chidx)); + + /* Then process the interrupt according to the packet status */ + + switch (grxsts & OTGHS_GRXSTSH_PKTSTS_MASK) + { + case OTGHS_GRXSTSH_PKTSTS_INRECVD: /* IN data packet received */ + { + /* Read the data into the host buffer. */ + + bcnt = (grxsts & OTGHS_GRXSTSH_BCNT_MASK) >> OTGHS_GRXSTSH_BCNT_SHIFT; + if (bcnt > 0 && priv->chan[chidx].buffer != NULL) + { + /* Transfer the packet from the Rx FIFO into the user buffer */ + + dest = (FAR uint32_t *)priv->chan[chidx].buffer; + fifo = STM32_OTGHS_DFIFO_HCH(0); + bcnt32 = (bcnt + 3) >> 2; + + for (i = 0; i < bcnt32; i++) + { + *dest++ = stm32_getreg(fifo); + } + + stm32_pktdump("Received", priv->chan[chidx].buffer, bcnt); + + /* Toggle the IN data pid (Used by Bulk and INTR only) */ + + priv->chan[chidx].indata1 ^= true; + + /* Manage multiple packet transfers */ + + priv->chan[chidx].buffer += bcnt; + priv->chan[chidx].xfrd += bcnt; + + /* Check if more packets are expected */ + + hctsiz = stm32_getreg(STM32_OTGHS_HCTSIZ(chidx)); + if ((hctsiz & OTGHS_HCTSIZ_PKTCNT_MASK) != 0) + { + /* Re-activate the channel when more packets are expected */ + + hcchar |= OTGHS_HCCHAR_CHENA; + hcchar &= ~OTGHS_HCCHAR_CHDIS; + stm32_putreg(STM32_OTGHS_HCCHAR(chidx), hcchar); + } + } + } + break; + + case OTGHS_GRXSTSH_PKTSTS_INDONE: /* IN transfer completed */ + case OTGHS_GRXSTSH_PKTSTS_DTOGERR: /* Data toggle error */ + case OTGHS_GRXSTSH_PKTSTS_HALTED: /* Channel halted */ + default: + break; + } + + /* Re-enable the RxFIFO non-empty interrupt */ + + intmsk |= OTGHS_GINT_RXFLVL; + stm32_putreg(STM32_OTGHS_GINTMSK, intmsk); +} + +/**************************************************************************** + * Name: stm32_gint_nptxfeisr + * + * Description: + * USB OTG HS non-periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the NPTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTGHS_GINTMSK, OTGHS_GINT_NPTXFE, 0); + return; + } + + /* Read the status from the top of the non-periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTGHS_HNPTXSTS); + + /* Extract the number of bytes available in the non-periodic Tx FIFO. */ + + avail = ((regval & OTGHS_HNPTXSTS_NPTXFSAV_MASK) >> OTGHS_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further NPTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTGHS_GINTMSK, OTGHS_GINT_NPTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HNPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %dwrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_ptxfeisr + * + * Description: + * USB OTG HS periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transfered the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the PTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTGHS_GINTMSK, OTGHS_GINT_PTXFE, 0); + return; + } + + /* Read the status from the top of the periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTGHS_HPTXSTS); + + /* Extract the number of bytes available in the periodic Tx FIFO. */ + + avail = ((regval & OTGHS_HPTXSTS_PTXFSAVL_MASK) >> OTGHS_HPTXSTS_PTXFSAVL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further PTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTGHS_GINTMSK, OTGHS_GINT_PTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullvdbg("HPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_hcisr + * + * Description: + * USB OTG HS host channels interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t haint; + uint32_t hcchar; + int i = 0; + + /* Read the Host all channels interrupt register and test each bit in the + * register. Each bit i, i=0...(STM32_NHOST_CHANNELS-1), corresponds to + * a pending interrupt on channel i. + */ + + haint = stm32_getreg(STM32_OTGHS_HAINT); + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + /* Is an interrupt pending on this channel? */ + + if ((haint & OTGHS_HAINT(i)) != 0) + { + /* Yes... read the HCCHAR register to get the direction bit */ + + hcchar = stm32_getreg(STM32_OTGHS_HCCHAR(i)); + + /* Was this an interrupt on an IN or an OUT channel? */ + + if ((hcchar & OTGHS_HCCHAR_EPDIR) != 0) + { + /* Handle the HC IN channel interrupt */ + + stm32_gint_hcinisr(priv, i); + } + else + { + /* Handle the HC OUT channel interrupt */ + + stm32_gint_hcoutisr(priv, i); + } + } + } +} + +/**************************************************************************** + * Name: stm32_gint_hprtisr + * + * Description: + * USB OTG HS host port interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t hprt; + uint32_t newhprt; + uint32_t hcfg; + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT, 0); + /* Read the port status and control register (HPRT) */ + + hprt = stm32_getreg(STM32_OTGHS_HPRT); + + /* Setup to clear the interrupt bits in GINTSTS by setting the corresponding + * bits in the HPRT. The HCINT interrupt bit is cleared when the appropriate + * status bits in the HPRT register are cleared. + */ + + newhprt = hprt & ~(OTGHS_HPRT_PENA | OTGHS_HPRT_PCDET | + OTGHS_HPRT_PENCHNG | OTGHS_HPRT_POCCHNG); + + /* Check for Port Overcurrent CHaNGe (POCCHNG) */ + + if ((hprt & OTGHS_HPRT_POCCHNG) != 0) + { + /* Set up to clear the POCCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_POCCHNG, 0); + newhprt |= OTGHS_HPRT_POCCHNG; + } + + /* Check for Port Connect DETected (PCDET). The core sets this bit when a + * device connection is detected. + */ + + if ((hprt & OTGHS_HPRT_PCDET) != 0) + { + /* Set up to clear the PCDET status in the new HPRT contents. Then + * process the new connection event. + */ + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_PCDET, 0); + newhprt |= OTGHS_HPRT_PCDET; + stm32_portreset(priv); + stm32_gint_connected(priv); + } + + /* Check for Port Enable CHaNGed (PENCHNG) */ + + if ((hprt & OTGHS_HPRT_PENCHNG) != 0) + { + /* Set up to clear the PENCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_PENCHNG, 0); + newhprt |= OTGHS_HPRT_PENCHNG; + + /* Was the port enabled? */ + + if ((hprt & OTGHS_HPRT_PENA) != 0) + { + /* Yes.. handle the new connection event */ + + stm32_gint_connected(priv); + + /* Check the Host ConFiGuration register (HCFG) */ + + hcfg = stm32_getreg(STM32_OTGHS_HCFG); + + /* Is this a low speed or full speed connection (OTG HS does not + * support high speed) + */ + + if ((hprt & OTGHS_HPRT_PSPD_MASK) == OTGHS_HPRT_PSPD_LS) + { + /* Set the Host Frame Interval Register for the 6KHz speed */ + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_LSDEV, 0); + stm32_putreg(STM32_OTGHS_HFIR, 6000); + + /* Are we switching from HS to LS? */ + + if ((hcfg & OTGHS_HCFG_FSLSPCS_MASK) != OTGHS_HCFG_FSLSPCS_LS6MHz) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_FSLSSW, 0); + + /* Yes... configure for LS */ + + hcfg &= ~OTGHS_HCFG_FSLSPCS_MASK; + hcfg |= OTGHS_HCFG_FSLSPCS_LS6MHz; + stm32_putreg(STM32_OTGHS_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + else /* if ((hprt & OTGHS_HPRT_PSPD_MASK) == OTGHS_HPRT_PSPD_HS) */ + { + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_FSDEV, 0); + stm32_putreg(STM32_OTGHS_HFIR, 48000); + + /* Are we switching from LS to HS? */ + + if ((hcfg & OTGHS_HCFG_FSLSPCS_MASK) != OTGHS_HCFG_FSLSPCS_FS48MHz) + { + + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HPRT_LSFSSW, 0); + /* Yes... configure for HS */ + + hcfg &= ~OTGHS_HCFG_FSLSPCS_MASK; + hcfg |= OTGHS_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTGHS_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + } + } + + /* Clear port interrupts by setting bits in the HPRT */ + + stm32_putreg(STM32_OTGHS_HPRT, newhprt); +} + +/**************************************************************************** + * Name: stm32_gint_discisr + * + * Description: + * USB OTG HS disconnect detected interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle the disconnection event */ + + stm32_gint_disconnected(priv); + + /* Clear the dicsonnect interrupt */ + + stm32_putreg(STM32_OTGHS_GINTSTS, OTGHS_GINT_DISC); +} + +/**************************************************************************** + * Name: stm32_gint_ipxfrisr + * + * Description: + * USB OTG HS incomplete periodic interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + /* CHENA : Set to enable the channel + * CHDIS : Set to stop transmitting/receiving data on a channel + */ + + regval = stm32_getreg(STM32_OTGHS_HCCHAR(0)); + regval |= (OTGHS_HCCHAR_CHDIS | OTGHS_HCCHAR_CHENA); + stm32_putreg(STM32_OTGHS_HCCHAR(0), regval); + + /* Clear the incomplete isochronous OUT interrupt */ + + stm32_putreg(STM32_OTGHS_GINTSTS, OTGHS_GINT_IPXFR); +} + +/**************************************************************************** + * Name: stm32_gint_isr + * + * Description: + * USB OTG HS global interrupt handler + * + ****************************************************************************/ + +static int stm32_gint_isr(int irq, FAR void *context) +{ + /* At present, there is only support for a single OTG HS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + uint32_t pending; + + /* If OTG were supported, we would need to check if we are in host or + * device mode when the global interrupt occurs. Here we support only + * host mode + */ + + /* Loop while there are pending interrupts to process. This loop may save a + * little interrupt handling overhead. + */ + + for (; ; ) + { + /* Get the unmasked bits in the GINT status */ + + pending = stm32_getreg(STM32_OTGHS_GINTSTS); + pending &= stm32_getreg(STM32_OTGHS_GINTMSK); + + /* Return from the interrupt when there are no further pending + * interrupts. + */ + + if (pending == 0) + { + return OK; + } + + /* Otherwise, process each pending, unmasked GINT interrupts */ + + /* Handle the start of frame interrupt */ + +#ifdef CONFIG_STM32_OTGHS_SOFINTR + if ((pending & OTGHS_GINT_SOF) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_SOF, 0); + stm32_gint_sofisr(priv); + } +#endif + + /* Handle the RxFIFO non-empty interrupt */ + + if ((pending & OTGHS_GINT_RXFLVL) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_RXFLVL, 0); + stm32_gint_rxflvlisr(priv); + } + + /* Handle the non-periodic TxFIFO empty interrupt */ + + if ((pending & OTGHS_GINT_NPTXFE) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_NPTXFE, 0); + stm32_gint_nptxfeisr(priv); + } + + /* Handle the periodic TxFIFO empty interrupt */ + + if ((pending & OTGHS_GINT_PTXFE) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_PTXFE, 0); + stm32_gint_ptxfeisr(priv); + } + + /* Handle the host channels interrupt */ + + if ((pending & OTGHS_GINT_HC) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_HC, 0); + stm32_gint_hcisr(priv); + } + + /* Handle the host port interrupt */ + + if ((pending & OTGHS_GINT_HPRT) != 0) + { + stm32_gint_hprtisr(priv); + } + + /* Handle the disconnect detected interrupt */ + + if ((pending & OTGHS_GINT_DISC) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_DISC, 0); + stm32_gint_discisr(priv); + } + + /* Handle the incomplete periodic transfer */ + + if ((pending & OTGHS_GINT_IPXFR) != 0) + { + usbhost_vtrace1(OTGHS_VTRACE1_GINT_IPXFR, 0); + stm32_gint_ipxfrisr(priv); + } + } + + /* We won't get here */ + + return OK; +} + +/**************************************************************************** + * Name: stm32_gint_enable and stm32_gint_disable + * + * Description: + * Respectively enable or disable the global OTG HS interrupt. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_gint_enable(void) +{ + uint32_t regval; + + /* Set the GINTMSK bit to unmask the interrupt */ + + regval = stm32_getreg(STM32_OTGHS_GAHBCFG); + regval |= OTGHS_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTGHS_GAHBCFG, regval); +} + +static void stm32_gint_disable(void) +{ + uint32_t regval; + + /* Clear the GINTMSK bit to mask the interrupt */ + + regval = stm32_getreg(STM32_OTGHS_GAHBCFG); + regval &= ~OTGHS_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTGHS_GAHBCFG, regval); +} + +/**************************************************************************** + * Name: stm32_hostinit_enable + * + * Description: + * Enable host interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_hostinit_enable(void) +{ + uint32_t regval; + + /* Disable all interrupts. */ + + stm32_putreg(STM32_OTGHS_GINTMSK, 0); + + /* Clear any pending interrupts. */ + + stm32_putreg(STM32_OTGHS_GINTSTS, 0xffffffff); + + /* Clear any pending USB OTG Interrupts (should be done elsewhere if OTG is supported) */ + + stm32_putreg(STM32_OTGHS_GOTGINT, 0xffffffff); + + /* Clear any pending USB OTG interrupts */ + + stm32_putreg(STM32_OTGHS_GINTSTS, 0xbfffffff); + + /* Enable the host interrupts */ + /* Common interrupts: + * + * OTGHS_GINT_WKUP : Resume/remote wakeup detected interrupt + * OTGHS_GINT_USBSUSP : USB suspend + */ + + regval = (OTGHS_GINT_WKUP | OTGHS_GINT_USBSUSP); + + /* If OTG were supported, we would need to enable the following as well: + * + * OTGHS_GINT_OTG : OTG interrupt + * OTGHS_GINT_SRQ : Session request/new session detected interrupt + * OTGHS_GINT_CIDSCHG : Connector ID status change + */ + + /* Host-specific interrupts + * + * OTGHS_GINT_SOF : Start of frame + * OTGHS_GINT_RXFLVL : RxFIFO non-empty + * OTGHS_GINT_IISOOXFR : Incomplete isochronous OUT transfer + * OTGHS_GINT_HPRT : Host port interrupt + * OTGHS_GINT_HC : Host channels interrupt + * OTGHS_GINT_DISC : Disconnect detected interrupt + */ + +#ifdef CONFIG_STM32_OTGHS_SOFINTR + regval |= (OTGHS_GINT_SOF | OTGHS_GINT_RXFLVL | OTGHS_GINT_IISOOXFR | + OTGHS_GINT_HPRT | OTGHS_GINT_HC | OTGHS_GINT_DISC); +#else + regval |= (OTGHS_GINT_RXFLVL | OTGHS_GINT_IPXFR | OTGHS_GINT_HPRT | + OTGHS_GINT_HC | OTGHS_GINT_DISC); +#endif + stm32_putreg(STM32_OTGHS_GINTMSK, regval); +} + +/**************************************************************************** + * Name: stm32_txfe_enable + * + * Description: + * Enable Tx FIFO empty interrupts. This is necessary when the entire + * transfer will not fit into Tx FIFO. The transfer will then be completed + * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled + * the fifo empty interrupt handler when the transfer is complete. + * + * Input Parameters: + * priv - Driver state structure reference + * chidx - The channel that requires the Tx FIFO empty interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Called from user task context. Interrupts must be disabled to assure + * exclusive access to the GINTMSK register. + * + ****************************************************************************/ + +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + irqstate_t flags; + uint32_t regval; + + /* Disable all interrupts so that we have exclusive access to the GINTMSK + * (it would be sufficent just to disable the GINT interrupt). + */ + + flags = enter_critical_section(); + + /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */ + + regval = stm32_getreg(STM32_OTGHS_GINTMSK); + switch (chan->eptype) + { + default: + case OTGHS_EPTYPE_CTRL: /* Non periodic transfer */ + case OTGHS_EPTYPE_BULK: + regval |= OTGHS_GINT_NPTXFE; + break; + + case OTGHS_EPTYPE_INTR: /* Periodic transfer */ + case OTGHS_EPTYPE_ISOC: + regval |= OTGHS_GINT_PTXFE; + break; + } + + /* Enable interrupts */ + + stm32_putreg(STM32_OTGHS_GINTMSK, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + + /* Loop until a change in connection state is detected */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + + /* Yes. Remember the new state */ + + connport->connected = priv->connected; + priv->change = false; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + uvdbg("RHport Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + uvdbg("Hub port Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + stm32_takesem(&priv->pscsem); + } +} + +/**************************************************************************** + * Name: stm32_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + uint32_t regval; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + usbhost_trace1(OTGHS_TRACE1_DEVDISCONN, 0); + return -ENODEV; + } + + DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED); + + /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */ + + usleep(100*1000); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Get the current device speed */ + + regval = stm32_getreg(STM32_OTGHS_HPRT); + if ((regval & OTGHS_HPRT_PSPD_MASK) == OTGHS_HPRT_PSPD_LS) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + /* Allocate and initialize the root hub port EP0 channels */ + + ret = stm32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, &priv->ep0); + if (ret < 0) + { + udbg("ERROR: Failed to allocate a control endpoint: %d\n", ret); + } + + return ret; +} + +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = stm32_rh_enumerate(priv, conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uvdbg("Enumerate the device\n"); + priv->smstate = SMSTATE_ENUM; + ret = usbhost_enumerate(hport, &hport->devclass); + + /* The enumeration may fail either because of some HCD interfaces failure + * or because the device class is not supported. In either case, we just + * need to perform the disconnection operation and make ready for a new + * enumeration. + */ + + if (ret < 0) + { + /* Return to the disconnected state */ + + udbg("ERROR: Enumeration failed: %d\n", ret); + stm32_gint_disconnected(priv); + } + + return ret; +} + +/************************************************************************************ + * Name: stm32_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support an + * external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + FAR struct stm32_chan_s *chan; + + DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 && + maxpacketsize <= 64); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Configure the EP0 OUT channel */ + + chan = &priv->chan[ep0info->outndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->outndx); + + /* Configure the EP0 IN channel */ + + chan = &priv->chan[ep0info->inndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->inndx); + + stm32_givesem(&priv->exclsem); + return OK; +} + +/************************************************************************************ + * Name: stm32_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handler control pipes differently from other endpoint types. This is + * because the normal, "transfer" endpoints are unidirectional an require + * only a single channel. Control endpoints, however, are bi-diretional + * and require two channels, one for the IN and one for the OUT direction. + */ + + if (epdesc->xfrtype == OTGHS_EPTYPE_CTRL) + { + ret = stm32_ctrlep_alloc(priv, epdesc, ep); + } + else + { + ret = stm32_xfrep_alloc(priv, epdesc, ep); + } + + stm32_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: stm32_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpoint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + + DEBUGASSERT(priv); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* A single channel is represent by an index in the range of 0 to STM32_MAX_TX_FIFOS. + * Otherwise, the ep must be a pointer to an allocated control endpoint structure. + */ + + if ((uintptr_t)ep < STM32_MAX_TX_FIFOS) + { + /* Halt the channel and mark the channel available */ + + stm32_chan_free(priv, (int)ep); + } + else + { + /* Halt both control channel and mark the channels available */ + + FAR struct stm32_ctrlinfo_s *ctrlep = (FAR struct stm32_ctrlinfo_s *)ep; + stm32_chan_free(priv, ctrlep->inndx); + stm32_chan_free(priv, ctrlep->outndx); + + /* And free the control endpoint container */ + + kmm_free(ctrlep); + } + + stm32_givesem(&priv->exclsem); + return OK; +} + +/**************************************************************************** + * Name: stm32_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special memory requirement for the STM32. */ + + alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32_OTGHS_DESCSIZE); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated address and size of the descriptor buffer */ + + *buffer = alloc; + *maxlen = CONFIG_STM32_OTGHS_DESCSIZE; + return OK; +} + +/**************************************************************************** + * Name: stm32_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to free that + * request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: stm32_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* There is no special memory requirement */ + + alloc = (FAR uint8_t *)kmm_malloc(buflen); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated buffer */ + + *buffer = alloc; + return OK; +} + +/************************************************************************************ + * Name: stm32_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlin and stm32_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTGHS_VTRACE2_CTRLIN, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the IN data phase (if any) */ + + if (buflen > 0) + { + ret = stm32_ctrl_recvdata(priv, ep0info, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_RECVDATA, -ret); + } + } + + /* Handle the status OUT phase */ + + if (ret == OK) + { + priv->chan[ep0info->outndx].outdata1 ^= true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactions exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTGHS_TRACE1_SENDDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTGHS_VTRACE2_CTRLOUT, req->type, req->req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the data OUT phase (if any) */ + + if (buflen > 0) + { + /* Start DATA out transfer (only one DATA packet) */ + + priv->chan[ep0info->outndx].outdata1 = true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret < 0) + { + usbhost_trace1(OTGHS_TRACE1_SENDDATA, -ret); + } + } + + /* Handle the status IN phase */ + + if (ret == OK) + { + ret = stm32_ctrl_recvdata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactins exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTGHS_TRACE1_RECVDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + ssize_t nbytes; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + nbytes = stm32_in_transfer(priv, chidx, buffer, buflen); + } + else + { + nbytes = stm32_out_transfer(priv, chidx, buffer, buflen); + } + + stm32_givesem(&priv->exclsem); + return nbytes; +} + +/**************************************************************************** + * Name: stm32_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + int ret; + + uvdbg("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + ret = stm32_in_asynch(priv, chidx, buffer, buflen, callback, arg); + } + else + { + ret = stm32_out_asynch(priv, chidx, buffer, buflen, callback, arg); + } + + stm32_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: stm32_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_chan_s *chan; + unsigned int chidx = (unsigned int)ep; + irqstate_t flags; + + uvdbg("chidx: %u: %d\n", chidx); + + DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS); + chan = &priv->chan[chidx]; + + /* We need to disable interrupts to avoid race conditions with the asynchronous + * completion of the transfer being cancelled. + */ + + flags = enter_critical_section(); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_CANCELLED); + chan->result = -ESHUTDOWN; + + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + + /* Wake'em up! */ + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + usbhost_asynch_t callback; + FAR void *arg; + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + callback(arg, -ESHUTDOWN); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: stm32_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && hport != NULL); + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + stm32_givesem(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_portreset + * + * Description: + * Reset the USB host port. + * + * NOTE: "Before starting to drive a USB reset, the application waits for the + * OTG interrupt triggered by the debounce done bit (DBCDNE bit in + * OTG_HS_GOTGINT), which indicates that the bus is stable again after the + * electrical debounce caused by the attachment of a pull-up resistor on DP + * (HS) or DM (LS). + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + regval = stm32_getreg(STM32_OTGHS_HPRT); + regval &= ~(OTGHS_HPRT_PENA | OTGHS_HPRT_PCDET | OTGHS_HPRT_PENCHNG | + OTGHS_HPRT_POCCHNG); + regval |= OTGHS_HPRT_PRST; + stm32_putreg(STM32_OTGHS_HPRT, regval); + + up_mdelay(20); + + regval &= ~OTGHS_HPRT_PRST; + stm32_putreg(STM32_OTGHS_HPRT, regval); + + up_mdelay(20); +} + +/**************************************************************************** + * Name: stm32_flush_txfifos + * + * Description: + * Flush the selected Tx FIFO. + * + * Input Parameters: + * txfnum -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_txfifos(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTGHS_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(STM32_OTGHS_GRSTCTL, regval); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_flush_rxfifo + * + * Description: + * Flush the Rx FIFO. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_rxfifo(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(STM32_OTGHS_GRSTCTL, OTGHS_GRSTCTL_RXFFLSH); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_vbusdrive + * + * Description: + * Drive the Vbus +5V. + * + * Input Parameters: + * priv - USB host driver private data structure. + * state - True: Drive, False: Don't drive + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state) +{ + uint32_t regval; + + /* Enable/disable the external charge pump */ + + stm32_usbhost_vbusdrive(0, state); + + /* Turn on the Host port power. */ + + regval = stm32_getreg(STM32_OTGHS_HPRT); + regval &= ~(OTGHS_HPRT_PENA | OTGHS_HPRT_PCDET | OTGHS_HPRT_PENCHNG | + OTGHS_HPRT_POCCHNG); + + if (((regval & OTGHS_HPRT_PPWR) == 0) && state) + { + regval |= OTGHS_HPRT_PPWR; + stm32_putreg(STM32_OTGHS_HPRT, regval); + } + + if (((regval & OTGHS_HPRT_PPWR) != 0) && !state) + { + regval &= ~OTGHS_HPRT_PPWR; + stm32_putreg(STM32_OTGHS_HPRT, regval); + } + + up_mdelay(200); +} + +/**************************************************************************** + * Name: stm32_host_initialize + * + * Description: + * Initialize/re-initialize hardware for host mode operation. At present, + * this function is called only from stm32_hw_initialize(). But if OTG mode + * were supported, this function would also be called to swtich between + * host and device modes on a connector ID change interrupt. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + uint32_t offset; + int i; + + /* Restart the PHY Clock */ + + stm32_putreg(STM32_OTGHS_PCGCCTL, 0); + + /* Initialize Host Configuration (HCFG) register */ + + regval = stm32_getreg(STM32_OTGHS_HCFG); + regval &= ~OTGHS_HCFG_FSLSPCS_MASK; + regval |= OTGHS_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTGHS_HCFG, regval); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Clear the HS-/LS-only support bit in the HCFG register */ + + regval = stm32_getreg(STM32_OTGHS_HCFG); + regval &= ~OTGHS_HCFG_FSLSS; + stm32_putreg(STM32_OTGHS_HCFG, regval); + + /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */ + /* Configure Rx FIFO size (GRXHSIZ) */ + + stm32_putreg(STM32_OTGHS_GRXFSIZ, CONFIG_STM32_OTGHS_RXFIFO_SIZE); + offset = CONFIG_STM32_OTGHS_RXFIFO_SIZE; + + /* Setup the host non-periodic Tx FIFO size (HNPTXHSIZ) */ + + regval = (offset | (CONFIG_STM32_OTGHS_NPTXFIFO_SIZE << OTGHS_HNPTXFSIZ_NPTXFD_SHIFT)); + stm32_putreg(STM32_OTGHS_HNPTXFSIZ, regval); + offset += CONFIG_STM32_OTGHS_NPTXFIFO_SIZE; + + /* Set up the host periodic Tx fifo size register (HPTXHSIZ) */ + + regval = (offset | (CONFIG_STM32_OTGHS_PTXFIFO_SIZE << OTGHS_HPTXFSIZ_PTXFD_SHIFT)); + stm32_putreg(STM32_OTGHS_HPTXFSIZ, regval); + + /* If OTG were supported, we sould need to clear HNP enable bit in the + * USB_OTG control register about here. + */ + + /* Flush all FIFOs */ + + stm32_flush_txfifos(OTGHS_GRSTCTL_TXFNUM_HALL); + stm32_flush_rxfifo(); + + /* Clear all pending HC Interrupts */ + + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + stm32_putreg(STM32_OTGHS_HCINT(i), 0xffffffff); + stm32_putreg(STM32_OTGHS_HCINTMSK(i), 0); + } + + /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + stm32_vbusdrive(priv, true); + + /* Enable host interrupts */ + + stm32_hostinit_enable(); +} + +/**************************************************************************** + * Name: stm32_sw_initialize + * + * Description: + * One-time setup of the host driver state structure. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) +{ + FAR struct usbhost_driver_s *drvr; + FAR struct usbhost_hubport_s *hport; + int i; + + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = stm32_ep0configure; + drvr->epalloc = stm32_epalloc; + drvr->epfree = stm32_epfree; + drvr->alloc = stm32_alloc; + drvr->free = stm32_free; + drvr->ioalloc = stm32_ioalloc; + drvr->iofree = stm32_iofree; + drvr->ctrlin = stm32_ctrlin; + drvr->ctrlout = stm32_ctrlout; + drvr->transfer = stm32_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = stm32_asynch; +#endif + drvr->cancel = stm32_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = stm32_connect; +#endif + drvr->disconnect = stm32_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = (usbhost_ep_t)&priv->ep0; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->rhport); + + /* Initialize semaphores */ + + sem_init(&priv->pscsem, 0, 0); + sem_init(&priv->exclsem, 0, 1); + + /* Initialize the driver state data */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = false; + + /* Put all of the channels back in their initial, allocated state */ + + memset(priv->chan, 0, STM32_MAX_TX_FIFOS * sizeof(struct stm32_chan_s)); + + /* Initialize each channel */ + + for (i = 0; i < STM32_MAX_TX_FIFOS; i++) + { + FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + sem_init(&chan->waitsem, 0, 0); + } +} + +/**************************************************************************** + * Name: stm32_hw_initialize + * + * Description: + * One-time setup of the host controller harware for normal operations. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + unsigned long timeout; + + /* Set the PHYSEL bit in the GUSBCFG register to select the OTG HS serial + * transceiver: "This bit is always 1 with write-only access" + */ + + regval = stm32_getreg(STM32_OTGHS_GUSBCFG); + regval |= OTGHS_GUSBCFG_PHYSEL; + stm32_putreg(STM32_OTGHS_GUSBCFG, regval); + + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(STM32_OTGHS_GRSTCTL, OTGHS_GRSTCTL_CSRST); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTGHS_GRSTCTL); + if ((regval & OTGHS_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + + regval = (OTGHS_GCCFG_PWRDWN | OTGHS_GCCFG_VBUSASEN | OTGHS_GCCFG_VBUSBSEN); +#ifndef CONFIG_USBDEV_VBUSSENSING + regval |= OTGHS_GCCFG_NOVBUSSENS; +#endif +#ifdef CONFIG_STM32_OTGHS_SOFOUTPUT + regval |= OTGHS_GCCFG_SOFOUTEN; +#endif + stm32_putreg(STM32_OTGHS_GCCFG, regval); + up_mdelay(20); + + /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + * bits would need to be set in the GUSBCFG register about here. + */ + + /* Force Host Mode */ + + regval = stm32_getreg(STM32_OTGHS_GUSBCFG); + regval &= ~OTGHS_GUSBCFG_FDMOD; + regval |= OTGHS_GUSBCFG_FHMOD; + stm32_putreg(STM32_OTGHS_GUSBCFG, regval); + up_mdelay(50); + + /* Initialize host mode and return success */ + + stm32_host_initialize(priv); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_otghshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *stm32_otghshost_initialize(int controller) +{ + /* At present, there is only support for a single OTG HS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + + /* Make sure that interrupts from the OTG HS core are disabled */ + + stm32_gint_disable(); + + /* Reset the state of the host driver */ + + stm32_sw_initialize(priv); + + /* Alternate function pin configuration. Here we assume that: + * + * 1. GPIOA, SYSCFG, and OTG HS peripheral clocking have already been\ + * enabled as part of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG HS alternate function pins for DM, DP, ID, and SOF. + * + * PIN* SIGNAL DIRECTION + * ---- ----------- ---------- + * PA8 OTG_HS_SOF SOF clock output + * PA9 OTG_HS_VBUS VBUS input for device, Driven by external regulator by + * host (not an alternate function) + * PA10 OTG_HS_ID OTG ID pin (only needed in Dual mode) + * PA11 OTG_HS_DM D- I/O + * PA12 OTG_HS_DP D+ I/O + * + * *Pins may vary from device-to-device. + */ + + stm32_configgpio(GPIO_OTGHSFS_DM); + stm32_configgpio(GPIO_OTGHSFS_DP); +// stm32_configgpio(GPIO_OTGHSFS_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable */ + +#ifdef CONFIG_STM32_OTGHS_SOFOUTPUT + stm32_configgpio(GPIO_OTGHSFS_SOF); +#endif + + /* Initialize the USB OTG HS core */ + + stm32_hw_initialize(priv); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(STM32_IRQ_OTGHS, stm32_gint_isr) != 0) + { + usbhost_trace1(OTGHS_TRACE1_IRQATTACH, 0); + return NULL; + } + + /* Enable USB OTG HS global interrupts */ + + stm32_gint_enable(); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(STM32_IRQ_OTGHS); + return &g_usbconn; +} + +#endif /* CONFIG_USBHOST && CONFIG_STM32_OTGHS */ diff --git a/arch/arm/src/stm32/stm32_pm.h b/arch/arm/src/stm32/stm32_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..7fc93ba688f9d324dfc550b647f217c550ffcb0d --- /dev/null +++ b/arch/arm/src/stm32/stm32_pm.h @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_pm.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_PM_H +#define __ARCH_ARM_SRC_STM32_STM32_PM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pmstop + * + * Description: + * Enter STOP mode. + * + * Input Parameters: + * lpds - true: To further reduce power consumption in Stop mode, put the + * internal voltage regulator in low-power mode using the LPDS bit + * of the Power control register (PWR_CR). + * + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +int stm32_pmstop(bool lpds); + +/**************************************************************************** + * Name: stm32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * Input Parameters: + * None + * + * Returned Value. + * On success, this function will not return (STANDBY mode can only be + * terminated with a reset event). Otherwise, STANDBY mode did not occur + * and a negated errno value is returned to indicate the cause of the + * failure. + * + ****************************************************************************/ + +int stm32_pmstandby(void); + +/**************************************************************************** + * Name: stm32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep mode + * as soon as WFI or WFE instruction is executed. + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +void stm32_pmsleep(bool sleeponexit); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_PM_H */ diff --git a/arch/arm/src/stm32/stm32_pminitialize.c b/arch/arm/src/stm32/stm32_pminitialize.c new file mode 100644 index 0000000000000000000000000000000000000000..e9b6d4780cb43c27cead52ed1293ac5866134e4d --- /dev/null +++ b/arch/arm/src/stm32/stm32_pminitialize.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pminitialize.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_internal.h" +#include "stm32_pm.h" + +#ifdef CONFIG_PM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_pminitialize + * + * Description: + * This function is called by MCU-specific logic at power-on reset in + * order to provide one-time initialization the power management subystem. + * This function must be called *very* early in the initialization sequence + * *before* any other device drivers are initialized (since they may + * attempt to register with the power management subsystem). + * + * Input parameters: + * None. + * + * Returned value: + * None. + * + ****************************************************************************/ + +void up_pminitialize(void) +{ + /* Then initialize the NuttX power management subsystem proper */ + + pm_initialize(); +} + +#endif /* CONFIG_PM */ diff --git a/arch/arm/src/stm32/stm32_pmsleep.c b/arch/arm/src/stm32/stm32_pmsleep.c new file mode 100644 index 0000000000000000000000000000000000000000..49ebf1ce75a748d6386a90c412a2768dda5ff44c --- /dev/null +++ b/arch/arm/src/stm32/stm32_pmsleep.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pmsleep.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "nvic.h" +#include "stm32_pwr.h" +#include "stm32_pm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep mode + * as soon as WFI or WFE instruction is executed. + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal volatage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +void stm32_pmsleep(bool sleeponexit) +{ + uint32_t regval; + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval &= ~NVIC_SYSCON_SLEEPDEEP; + if (sleeponexit) + { + regval |= NVIC_SYSCON_SLEEPONEXIT; + } + else + { + regval &= ~NVIC_SYSCON_SLEEPONEXIT; + } + + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup interrupt or event occurs */ + +#ifdef CONFIG_PM_WFE + /* Mode: SLEEP + Entry with WFE */ + + asm("wfe"); +#else + /* Mode: SLEEP + Entry with WFI */ + + asm("wfi"); +#endif +} diff --git a/arch/arm/src/stm32/stm32_pmstandby.c b/arch/arm/src/stm32/stm32_pmstandby.c new file mode 100644 index 0000000000000000000000000000000000000000..2b4de6a6f0ec407160bd8f8761b1e2da06c4f00a --- /dev/null +++ b/arch/arm/src/stm32/stm32_pmstandby.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pmstandby.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "nvic.h" +#include "stm32_pwr.h" +#include "stm32_pm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * Input Parameters: + * None + * + * Returned Value. + * On success, this function will not return (STANDBY mode can only be + * terminated with a reset event). Otherwise, STANDBY mode did not occur + * and a negated errno value is returned to indicate the cause of the + * failure. + * + ****************************************************************************/ + +int stm32_pmstandby(void) +{ + uint32_t regval; + + /* Clear the Wake-Up Flag by setting the CWUF bit in the power control + * register. + */ + + regval = getreg32(STM32_PWR_CR); + regval |= PWR_CR_CWUF; + putreg32(regval, STM32_PWR_CR); + + /* Set the Power Down Deep Sleep (PDDS) bit in the power control register. */ + + regval |= PWR_CR_PDDS; + putreg32(regval, STM32_PWR_CR); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval |= NVIC_SYSCON_SLEEPDEEP; + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup reset occurs */ + + asm("wfi"); + return OK; /* Won't get here */ +} diff --git a/arch/arm/src/stm32/stm32_pmstop.c b/arch/arm/src/stm32/stm32_pmstop.c new file mode 100644 index 0000000000000000000000000000000000000000..bde0334ec4a4d254fd6d1d6245e3d0fb2a1cc1ef --- /dev/null +++ b/arch/arm/src/stm32/stm32_pmstop.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pmstop.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" +#include "nvic.h" +#include "stm32_pwr.h" +#include "stm32_pm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pmstop + * + * Description: + * Enter STOP mode. + * + * Input Parameters: + * lpds - true: To further reduce power consumption in Stop mode, put the + * internal voltage regulator in low-power mode using the LPDS bit + * of the Power control register (PWR_CR). + * + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal volatage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +int stm32_pmstop(bool lpds) +{ + uint32_t regval; + + /* Clear the Power Down Deep Sleep (PDDS) and the Low Power Deep Sleep + * (LPDS)) bits in the power control register. + */ + + regval = getreg32(STM32_PWR_CR); + regval &= ~(PWR_CR_LPDS | PWR_CR_PDDS); + + /* Set the Low Power Deep Sleep (LPDS) bit if so requested */ + + if (lpds) + { + regval |= PWR_CR_LPDS; + } + + putreg32(regval, STM32_PWR_CR); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval |= NVIC_SYSCON_SLEEPDEEP; + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup interrupt or event occurs */ + +#ifdef CONFIG_PM_WFE + /* Mode: SLEEP + Entry with WFE */ + + asm("wfe"); +#else + /* Mode: SLEEP + Entry with WFI */ + + asm("wfi"); +#endif + return OK; +} diff --git a/arch/arm/src/stm32/stm32_procfs_ccm.c b/arch/arm/src/stm32/stm32_procfs_ccm.c new file mode 100644 index 0000000000000000000000000000000000000000..231f37dd9c4c7fe7c9108edf9d3e3cfd364f1089 --- /dev/null +++ b/arch/arm/src/stm32/stm32_procfs_ccm.c @@ -0,0 +1,336 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_procfs_ccm.c + * + * Copyright (C) 2014 Pelle Windestam. All rights reserved. + * Author: Pelle Windestam (pelle@windestam.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "stm32_ccm.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ + defined(CONFIG_FS_PROCFS_REGISTER) && defined(CONFIG_STM32_CCM_PROCFS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CCM_LINELEN 64 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct ccm_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + unsigned int linesize; /* Number of valid characters in line[] */ + char line[CCM_LINELEN]; /* Pre-allocated buffer for formatted lines */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* File system methods */ + +static int ccm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int ccm_close(FAR struct file *filep); +static ssize_t ccm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int ccm_dup(FAR const struct file *oldp, + FAR struct file *newp); +static int ccm_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* See include/nutts/fs/procfs.h + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +static const struct procfs_operations ccm_procfsoperations = +{ + ccm_open, /* open */ + ccm_close, /* close */ + ccm_read, /* read */ + NULL, /* write */ + ccm_dup, /* dup */ + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + ccm_stat /* stat */ +}; + +static const struct procfs_entry_s g_procfs_ccm = +{ + "ccm", + &ccm_procfsoperations +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ccm_open + ****************************************************************************/ + +static int ccm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct ccm_file_s *priv; + + fvdbg("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) + { + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "cpuload" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "ccm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* Allocate a container to hold the task and attribute selection */ + + priv = (FAR struct ccm_file_s *)kmm_zalloc(sizeof(struct ccm_file_s)); + if (!priv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the index as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)priv; + return OK; +} + +/**************************************************************************** + * Name: ccm_close + ****************************************************************************/ + +static int ccm_close(FAR struct file *filep) +{ + FAR struct ccm_file_s *priv; + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct ccm_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + /* Release the file attributes structure */ + + kmm_free(priv); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: ccm_read + ****************************************************************************/ + +static ssize_t ccm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct ccm_file_s *priv; + size_t linesize; + size_t copysize; + size_t remaining; + size_t totalsize; + struct mallinfo mem; + off_t offset = filep->f_pos; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct ccm_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + + mm_mallinfo(&g_ccm_heap, &mem); + + remaining = buflen; + totalsize = 0; + + linesize = snprintf(priv->line, + CCM_LINELEN, + " total used free largest\n"); + copysize = procfs_memcpy(priv->line, linesize, buffer, remaining, &offset); + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + + if (totalsize >= buflen) + { + return totalsize; + } + + linesize = snprintf(priv->line, + CCM_LINELEN, + "Mem: %11d%11d%11d%11d\n", + mem.arena, + mem.uordblks, + mem.fordblks, + mem.mxordblk); + copysize = procfs_memcpy(priv->line, linesize, buffer, remaining, &offset); + totalsize += copysize; + + /* Update the file offset */ + + if (totalsize > 0) + { + filep->f_pos += totalsize; + } + + return totalsize; +} + +/**************************************************************************** + * Name: ccm_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int ccm_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct ccm_file_s *oldpriv; + FAR struct ccm_file_s *newpriv; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldpriv = (FAR struct ccm_file_s *)oldp->f_priv; + DEBUGASSERT(oldpriv); + + /* Allocate a new container to hold the task and attribute selection */ + + newpriv = (FAR struct ccm_file_s *)kmm_zalloc(sizeof(struct ccm_file_s)); + if (!newpriv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attributes from the old attributes to the new */ + + memcpy(newpriv, oldpriv, sizeof(struct ccm_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newpriv; + return OK; +} + +static int ccm_stat(const char *relpath, struct stat *buf) +{ + if (strcmp(relpath, "ccm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + buf->st_size = 0; + buf->st_blksize = 0; + buf->st_blocks = 0; + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ccm_procfs_register + * + * Description: + * Register the CCM procfs file system entry + * + ****************************************************************************/ + +int ccm_procfs_register(void) +{ + return procfs_register(&g_procfs_ccm); +} + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && + * CONFIG_FS_PROCFS_REGISTER && CONFIG_STM32_CCM_PROCFS */ diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..8779d18692fa9108f2cb09ee314747d513463951 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -0,0 +1,2401 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pwm.c + * + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32_pwm.h" +#include "stm32.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ + defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ + defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ + defined(CONFIG_STM32_TIM9_PWM) || defined(CONFIG_STM32_TIM10_PWM) || \ + defined(CONFIG_STM32_TIM11_PWM) || defined(CONFIG_STM32_TIM12_PWM) || \ + defined(CONFIG_STM32_TIM13_PWM) || defined(CONFIG_STM32_TIM14_PWM) || \ + defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ + defined(CONFIG_STM32_TIM17_PWM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* PWM/Timer Definitions ****************************************************/ +/* The following definitions are used to identify the various time types */ + +#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4, TIM15-17 on F3 */ +#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ +#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ + +#define TIMTYPE_TIM1 TIMTYPE_ADVANCED +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) +# define TIMTYPE_TIM2 TIMTYPE_GENERAL16 +#else +# define TIMTYPE_TIM2 TIMTYPE_GENERAL32 +#endif +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define TIMTYPE_TIM3 TIMTYPE_GENERAL32 +# define TIMTYPE_TIM4 TIMTYPE_GENERAL32 +#else +# define TIMTYPE_TIM3 TIMTYPE_GENERAL16 +# define TIMTYPE_TIM4 TIMTYPE_GENERAL16 +#endif +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define TIMTYPE_TIM5 TIMTYPE_GENERAL16 +#else +# define TIMTYPE_TIM5 TIMTYPE_GENERAL32 +#endif +#define TIMTYPE_TIM6 TIMTYPE_BASIC +#define TIMTYPE_TIM7 TIMTYPE_BASIC +#define TIMTYPE_TIM8 TIMTYPE_ADVANCED +#define TIMTYPE_TIM9 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM10 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM11 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM12 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM13 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM14 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM15 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM16 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM17 TIMTYPE_COUNTUP16 + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_PWM +#endif + +#ifdef CONFIG_DEBUG_PWM +# define pwmdbg dbg +# define pwmlldbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define pwmvdbg vdbg +# define pwmllvdbg llvdbg +# define pwm_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +# endif +#else +# define pwmdbg(x...) +# define pwmlldbg(x...) +# define pwmvdbg(x...) +# define pwmllvdbg(x...) +# define pwm_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum stm32_timmode_e +{ + STM32_TIMMODE_COUNTUP = 0, + STM32_TIMMODE_COUNTDOWN = 1, + STM32_TIMMODE_CENTER1 = 2, + STM32_TIMMODE_CENTER2 = 3, + STM32_TIMMODE_CENTER3 = 4, +}; + +enum stm32_chanmode_e +{ + STM32_CHANMODE_PWM1 = 0, + STM32_CHANMODE_PWM2 = 1, + STM32_CHANMODE_COMBINED1 = 2, + STM32_CHANMODE_COMBINED2 = 3, + STM32_CHANMODE_ASYMMETRIC1 = 4, + STM32_CHANMODE_ASYMMETRIC2 = 5, +}; + +struct stm32_pwmchan_s +{ + uint8_t channel; /* Timer output channel: {1,..4} */ + uint32_t pincfg; /* Output pin configuration */ + enum stm32_chanmode_e mode; +}; + +/* This structure represents the state of one PWM timer */ + +struct stm32_pwmtimer_s +{ + FAR const struct pwm_ops_s *ops; /* PWM operations */ + uint8_t timid; /* Timer ID {1,...,17} */ + struct stm32_pwmchan_s channels[PWM_NCHANNELS]; + uint8_t timtype; /* See the TIMTYPE_* definitions */ + enum stm32_timmode_e mode; +#ifdef CONFIG_PWM_PULSECOUNT + uint8_t irq; /* Timer update IRQ */ + uint8_t prev; /* The previous value of the RCR (pre-loaded) */ + uint8_t curr; /* The current value of the RCR (pre-loaded) */ + uint32_t count; /* Remaining pluse count */ +#endif + uint32_t base; /* The base address of the timer */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. */ +#ifdef CONFIG_PWM_PULSECOUNT + FAR void *handle; /* Handle used for upper-half callback */ +#endif +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ +/* Register access */ + +static uint16_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset); +static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint16_t value); + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg); +#else +# define pwm_dumpregs(priv,msg) +#endif + +/* Timer management */ + +static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, + FAR const struct pwm_info_s *info); + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) +static int pwm_interrupt(struct stm32_pwmtimer_s *priv); +#if defined(CONFIG_STM32_TIM1_PWM) +static int pwm_tim1interrupt(int irq, void *context); +#endif +#if defined(CONFIG_STM32_TIM8_PWM) +static int pwm_tim8interrupt(int irq, void *context); +#endif +static uint8_t pwm_pulsecount(uint32_t count); +#endif + +/* PWM driver methods */ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + +#ifdef CONFIG_PWM_PULSECOUNT +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info, + FAR void *handle); +#else +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); +#endif + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +#ifdef CONFIG_STM32_TIM1_PWM +static struct stm32_pwmtimer_s g_pwm1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channels = + { +#ifdef CONFIG_STM32_TIM1_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM1_CH1CFG, + .mode = CONFIG_STM32_TIM1_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM1_CH2CFG, + .mode = CONFIG_STM32_TIM1_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM1_CH3CFG, + .mode = CONFIG_STM32_TIM1_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM1_CH4CFG, + .mode = CONFIG_STM32_TIM1_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM1, + .mode = CONFIG_STM32_TIM1_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM1UP, +#endif + .base = STM32_TIM1_BASE, + .pclk = STM32_APB2_TIM1_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM2_PWM +static struct stm32_pwmtimer_s g_pwm2dev = +{ + .ops = &g_pwmops, + .timid = 2, + .channels = + { +#ifdef CONFIG_STM32_TIM2_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM2_CH1CFG, + .mode = CONFIG_STM32_TIM2_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM2_CH2CFG, + .mode = CONFIG_STM32_TIM2_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM2_CH3CFG, + .mode = CONFIG_STM32_TIM2_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM2_CH4CFG, + .mode = CONFIG_STM32_TIM2_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM2, + .mode = CONFIG_STM32_TIM2_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM2, +#endif + .base = STM32_TIM2_BASE, + .pclk = STM32_APB1_TIM2_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM3_PWM +static struct stm32_pwmtimer_s g_pwm3dev = +{ + .ops = &g_pwmops, + .timid = 3, + .channels = + { +#ifdef CONFIG_STM32_TIM3_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM3_CH1CFG, + .mode = CONFIG_STM32_TIM3_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM3_CH2CFG, + .mode = CONFIG_STM32_TIM3_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM3_CH3CFG, + .mode = CONFIG_STM32_TIM3_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM3_CH4CFG, + .mode = CONFIG_STM32_TIM3_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM3, + .mode = CONFIG_STM32_TIM3_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM3, +#endif + .base = STM32_TIM3_BASE, + .pclk = STM32_APB1_TIM3_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM4_PWM +static struct stm32_pwmtimer_s g_pwm4dev = +{ + .ops = &g_pwmops, + .timid = 4, + .channels = + { +#ifdef CONFIG_STM32_TIM4_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM4_CH1CFG, + .mode = CONFIG_STM32_TIM4_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM4_CH2CFG, + .mode = CONFIG_STM32_TIM4_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM4_CH3CFG, + .mode = CONFIG_STM32_TIM4_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM4_CH4CFG, + .mode = CONFIG_STM32_TIM4_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM4, + .mode = CONFIG_STM32_TIM4_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM4, +#endif + .base = STM32_TIM4_BASE, + .pclk = STM32_APB1_TIM4_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM5_PWM +static struct stm32_pwmtimer_s g_pwm5dev = +{ + .ops = &g_pwmops, + .timid = 5, + .channels = + { +#ifdef CONFIG_STM32_TIM5_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM5_CH1CFG, + .mode = CONFIG_STM32_TIM5_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM5_CH2CFG, + .mode = CONFIG_STM32_TIM5_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM5_CH3CFG, + .mode = CONFIG_STM32_TIM5_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM5_CH4CFG, + .mode = CONFIG_STM32_TIM5_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM5, + .mode = CONFIG_STM32_TIM5_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM5, +#endif + .base = STM32_TIM5_BASE, + .pclk = STM32_APB1_TIM5_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM8_PWM +static struct stm32_pwmtimer_s g_pwm8dev = +{ + .ops = &g_pwmops, + .timid = 8, + .channels = + { +#ifdef CONFIG_STM32_TIM8_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM8_CH1CFG, + .mode = CONFIG_STM32_TIM8_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM8_CH2CFG, + .mode = CONFIG_STM32_TIM8_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM8_CH3CFG, + .mode = CONFIG_STM32_TIM8_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM8_CH4CFG, + .mode = CONFIG_STM32_TIM8_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM8, + .mode = CONFIG_STM32_TIM8_MODE, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM8UP, +#endif + .base = STM32_TIM8_BASE, + .pclk = STM32_APB2_TIM8_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM9_PWM +static struct stm32_pwmtimer_s g_pwm9dev = +{ + .ops = &g_pwmops, + .timid = 9, + .channels = + { +#ifdef CONFIG_STM32_TIM9_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM9_CH1CFG, + .mode = CONFIG_STM32_TIM9_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM9_CH2CFG, + .mode = CONFIG_STM32_TIM9_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM9_CH3CFG, + .mode = CONFIG_STM32_TIM9_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM9_CH4CFG, + .mode = CONFIG_STM32_TIM9_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM9, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM9, +#endif + .base = STM32_TIM9_BASE, + .pclk = STM32_APB2_TIM9_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM10_PWM +static struct stm32_pwmtimer_s g_pwm10dev = +{ + .ops = &g_pwmops, + .timid = 10, + .channels = + { +#ifdef CONFIG_STM32_TIM10_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM10_CH1CFG, + .mode = CONFIG_STM32_TIM10_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM10_CH2CFG, + .mode = CONFIG_STM32_TIM10_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM10_CH3CFG, + .mode = CONFIG_STM32_TIM10_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM10_CH4CFG, + .mode = CONFIG_STM32_TIM10_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM10, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM10, +#endif + .base = STM32_TIM10_BASE, + .pclk = STM32_APB2_TIM10_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM11_PWM +static struct stm32_pwmtimer_s g_pwm11dev = +{ + .ops = &g_pwmops, + .timid = 11, + .channels = + { +#ifdef CONFIG_STM32_TIM11_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM11_CH1CFG, + .mode = CONFIG_STM32_TIM11_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM11_CH2CFG, + .mode = CONFIG_STM32_TIM11_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM11_CH3CFG, + .mode = CONFIG_STM32_TIM11_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM11_CH4CFG, + .mode = CONFIG_STM32_TIM11_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM11, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM11, +#endif + .base = STM32_TIM11_BASE, + .pclk = STM32_APB2_TIM11_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM12_PWM +static struct stm32_pwmtimer_s g_pwm12dev = +{ + .ops = &g_pwmops, + .timid = 12, + .channels = + { +#ifdef CONFIG_STM32_TIM12_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM12_CH1CFG, + .mode = CONFIG_STM32_TIM12_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM12_CH2CFG, + .mode = CONFIG_STM32_TIM12_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM12_CH3CFG, + .mode = CONFIG_STM32_TIM12_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM12_CH4CFG, + .mode = CONFIG_STM32_TIM12_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM12, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM12, +#endif + .base = STM32_TIM12_BASE, + .pclk = STM32_APB1_TIM12_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM13_PWM +static struct stm32_pwmtimer_s g_pwm13dev = +{ + .ops = &g_pwmops, + .timid = 13, + .channels = + { +#ifdef CONFIG_STM32_TIM13_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM13_CH1CFG, + .mode = CONFIG_STM32_TIM13_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM13_CH2CFG, + .mode = CONFIG_STM32_TIM13_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM13_CH3CFG, + .mode = CONFIG_STM32_TIM13_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM13_CH4CFG, + .mode = CONFIG_STM32_TIM13_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM13, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM13, +#endif + .base = STM32_TIM13_BASE, + .pclk = STM32_APB1_TIM13_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM14_PWM +static struct stm32_pwmtimer_s g_pwm14dev = +{ + .ops = &g_pwmops, + .timid = 14, + .channels = + { +#ifdef CONFIG_STM32_TIM14_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM14_CH1CFG, + .mode = CONFIG_STM32_TIM14_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM14_CH2CFG, + .mode = CONFIG_STM32_TIM14_CH2MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL3 + { + .channel = 3, + .pincfg = PWM_TIM14_CH3CFG, + .mode = CONFIG_STM32_TIM14_CH3MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL4 + { + .channel = 4, + .pincfg = PWM_TIM14_CH4CFG, + .mode = CONFIG_STM32_TIM14_CH4MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM14, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM14, +#endif + .base = STM32_TIM14_BASE, + .pclk = STM32_APB1_TIM14_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM15_PWM +static struct stm32_pwmtimer_s g_pwm15dev = +{ + .ops = &g_pwmops, + .timid = 15, + .channels = + { +#ifdef CONFIG_STM32_TIM15_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM15_CH1CFG, + .mode = CONFIG_STM32_TIM15_CH1MODE, + }, +#endif +#ifdef CONFIG_STM32_TIM15_CHANNEL2 + { + .channel = 2, + .pincfg = PWM_TIM15_CH2CFG, + .mode = CONFIG_STM32_TIM15_CH2MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM15, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM15, +#endif + .base = STM32_TIM15_BASE, + .pclk = STM32_APB1_TIM15_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM16_PWM +static struct stm32_pwmtimer_s g_pwm16dev = +{ + .ops = &g_pwmops, + .timid = 16, + .channels = + { +#ifdef CONFIG_STM32_TIM16_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM16_CH1CFG, + .mode = CONFIG_STM32_TIM16_CH1MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM16, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM16, +#endif + .base = STM32_TIM16_BASE, + .pclk = STM32_APB1_TIM16_CLKIN, +}; +#endif + +#ifdef CONFIG_STM32_TIM17_PWM +static struct stm32_pwmtimer_s g_pwm17dev = +{ + .ops = &g_pwmops, + .timid = 17, + .channels = + { +#ifdef CONFIG_STM32_TIM17_CHANNEL1 + { + .channel = 1, + .pincfg = PWM_TIM17_CH1CFG, + .mode = CONFIG_STM32_TIM17_CH1MODE, + }, +#endif + }, + .timtype = TIMTYPE_TIM17, + .mode = STM32_TIMMODE_COUNTUP, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = STM32_IRQ_TIM17, +#endif + .base = STM32_TIM17_BASE, + .pclk = STM32_APB1_TIM17_CLKIN, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_getreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint16_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset) +{ + return getreg16(priv->base + offset); +} + +/**************************************************************************** + * Name: pwm_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint16_t value) +{ + if (priv->timtype == TIMTYPE_GENERAL32 && + (offset == STM32_GTIM_CNT_OFFSET || + offset == STM32_GTIM_ARR_OFFSET || + offset == STM32_GTIM_CCR1_OFFSET || + offset == STM32_GTIM_CCR2_OFFSET || + offset == STM32_GTIM_CCR3_OFFSET || + offset == STM32_GTIM_CCR4_OFFSET)) + { + /* a 32 bit access is required for a 32 bit register: + * if only a 16 bit write would be performed, then the + * upper 16 bits of the 32 bit register will be a copy of + * the lower 16 bits. + */ + + putreg32(value, priv->base + offset); + } + else + { + putreg16(value, priv->base + offset); + } +} + +/**************************************************************************** + * Name: pwm_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the PWM block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_PWM) && defined(CONFIG_DEBUG_VERBOSE) +static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) +{ + pwmvdbg("%s:\n", msg); + pwmvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + pwm_getreg(priv, STM32_GTIM_CR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_SMCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); + pwmvdbg(" SR: %04x EGR: %04x CCMR1: %04x CCMR2: %04x\n", + pwm_getreg(priv, STM32_GTIM_SR_OFFSET), + pwm_getreg(priv, STM32_GTIM_EGR_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET)); + pwmvdbg(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCER_OFFSET), + pwm_getreg(priv, STM32_GTIM_CNT_OFFSET), + pwm_getreg(priv, STM32_GTIM_PSC_OFFSET), + pwm_getreg(priv, STM32_GTIM_ARR_OFFSET)); + pwmvdbg(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR3_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR4_OFFSET)); +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) + if (priv->timtype == TIMTYPE_ADVANCED) + { + pwmvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, STM32_ATIM_RCR_OFFSET), + pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET), + pwm_getreg(priv, STM32_ATIM_DCR_OFFSET), + pwm_getreg(priv, STM32_ATIM_DMAR_OFFSET)); + } + else +#endif + { + pwmvdbg(" DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, STM32_GTIM_DCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DMAR_OFFSET)); + } +} +#endif + +/**************************************************************************** + * Name: pwm_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, + FAR const struct pwm_info_s *info) +{ +#ifdef CONFIG_PWM_MULTICHAN + int i; +#endif + + /* Calculated values */ + + uint32_t prescaler; + uint32_t timclk; + uint32_t reload; + uint32_t ccr; + + /* Register contents */ + + uint16_t cr1; + uint16_t ccer; + uint16_t cr2; +#ifdef CONFIG_STM32_STM32F30XX + uint32_t ccmr1; + uint32_t ccmr2; +#else + uint16_t ccmr1; + uint16_t ccmr2; +#endif + + /* New timer regiser bit settings */ + + uint16_t ccenable; +#ifdef CONFIG_STM32_STM32F30XX + uint32_t ocmode1; + uint32_t ocmode2; +#else + uint16_t ocmode1; + uint16_t ocmode2; +#endif + + DEBUGASSERT(priv != NULL && info != NULL); + +#if defined(CONFIG_PWM_MULTICHAN) + pwmvdbg("TIM%d frequency: %d\n", + priv->timid, info->frequency); +#elif defined(CONFIG_PWM_PULSECOUNT) + pwmvdbg("TIM%d channel: %d frequency: %d duty: %08x count: %d\n", + priv->timid, priv->channel, info->frequency, + info->duty, info->count); +#else + pwmvdbg("TIM%d channel: %d frequency: %d duty: %08x\n", + priv->timid, priv->channel, info->frequency, info->duty); +#endif + + DEBUGASSERT(info->frequency > 0); +#ifndef CONFIG_PWM_MULTICHAN + DEBUGASSERT(info->duty >= 0 && info->duty < uitoub16(100)); +#endif + + /* Disable all interrupts and DMA requests, clear all pending status */ + +#ifdef CONFIG_PWM_PULSECOUNT + pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, 0); + pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); +#endif + + /* Calculate optimal values for the timer prescaler and for the timer reload + * register. If 'frequency' is the desired frequency, then + * + * reload = timclk / frequency + * timclk = pclk / presc + * + * Or, + * + * reload = pclk / presc / frequency + * + * There are many solutions to this this, but the best solution will be the + * one that has the largest reload value and the smallest prescaler value. + * That is the solution that should give us the most accuracy in the timer + * control. Subject to: + * + * 0 <= presc <= 65536 + * 1 <= reload <= 65535 + * + * So presc = pclk / 65535 / frequency would be optimal. + * + * Example: + * + * pclk = 42 MHz + * frequency = 100 Hz + * + * prescaler = 42,000,000 / 65,535 / 100 + * = 6.4 (or 7 -- taking the ceiling always) + * timclk = 42,000,000 / 7 + * = 6,000,000 + * reload = 6,000,000 / 100 + * = 60,000 + */ + + prescaler = (priv->pclk / info->frequency + 65534) / 65535; + if (prescaler < 1) + { + prescaler = 1; + } + else if (prescaler > 65536) + { + prescaler = 65536; + } + + timclk = priv->pclk / prescaler; + + reload = timclk / info->frequency; + if (reload < 1) + { + reload = 1; + } + else if (reload > 65535) + { + reload = 65535; + } + + pwmvdbg("TIM%d PCLK: %d frequency: %d TIMCLK: %d prescaler: %d reload: %d\n", + priv->timid, priv->pclk, info->frequency, timclk, prescaler, reload); + + /* Set up the timer CR1 register: + * + * 1,8 CKD[1:0] ARPE CMS[1:0] DIR OPM URS UDIS CEN + * 2-5 CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN + * 6-7 ARPE OPM URS UDIS CEN + * 9-14 CKD[1:0] ARPE URS UDIS CEN + * 15-17 CKD[1:0] ARPE OPM URS UDIS CEN + */ + + cr1 = pwm_getreg(priv, STM32_GTIM_CR1_OFFSET); + + /* Disable the timer until we get it configured */ + + cr1 &= ~GTIM_CR1_CEN; + + /* Set the counter mode for the advanced timers (1,8) and most general + * purpose timers (all 2-5, but not 9-17), i.e., all but TIMTYPE_COUNTUP16 + * and TIMTYPE_BASIC + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ + defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ + defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) + + if (priv->timtype != TIMTYPE_BASIC && priv->timtype != TIMTYPE_COUNTUP16) + { + /* Select the Counter Mode: + * + * GTIM_CR1_EDGE: The counter counts up or down depending on the + * direction bit (DIR). + * GTIM_CR1_CENTER1, GTIM_CR1_CENTER2, GTIM_CR1_CENTER3: The counter + * counts up then down. + * GTIM_CR1_DIR: 0: count up, 1: count down + */ + + cr1 &= ~(GTIM_CR1_DIR | GTIM_CR1_CMS_MASK); + + switch (priv->mode) + { + case STM32_TIMMODE_COUNTUP: + cr1 |= GTIM_CR1_EDGE; + break; + + case STM32_TIMMODE_COUNTDOWN: + cr1 |= GTIM_CR1_EDGE | GTIM_CR1_DIR; + break; + + case STM32_TIMMODE_CENTER1: + cr1 |= GTIM_CR1_CENTER1; + break; + + case STM32_TIMMODE_CENTER2: + cr1 |= GTIM_CR1_CENTER2; + break; + + case STM32_TIMMODE_CENTER3: + cr1 |= GTIM_CR1_CENTER3; + break; + + default: + pwmdbg("No such timer mode: %d\n", (int)priv->mode); + return -EINVAL; + } + } +#endif + + /* Set the clock division to zero for all (but the basic timers, but there + * should be no basic timers in this context + */ + + cr1 &= ~GTIM_CR1_CKD_MASK; + pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* Set the reload and prescaler values */ + + pwm_putreg(priv, STM32_GTIM_ARR_OFFSET, (uint16_t)reload); + pwm_putreg(priv, STM32_GTIM_PSC_OFFSET, (uint16_t)(prescaler - 1)); + + /* Set the advanced timer's repetition counter */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) + if (priv->timtype == TIMTYPE_ADVANCED) + { + /* If a non-zero repetition count has been selected, then set the + * repitition counter to the count-1 (pwm_start() has already + * assured us that the count value is within range). + */ + +#ifdef CONFIG_PWM_PULSECOUNT + if (info->count > 0) + { + /* Save the remaining count and the number of counts that will have + * elapsed on the first interrupt. + */ + + /* If the first interrupt occurs at the end end of the first + * repetition count, then the count will be the same as the RCR + * value. + */ + + priv->prev = pwm_pulsecount(info->count); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->prev - 1); + + /* Generate an update event to reload the prescaler. This should + * preload the RCR into active repetition counter. + */ + + pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + + /* Now set the value of the RCR that will be loaded on the next + * update event. + */ + + priv->count = info->count; + priv->curr = pwm_pulsecount(info->count - priv->prev); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1); + } + + /* Otherwise, just clear the repetition counter */ + + else +#endif + { + /* Set the repetition counter to zero */ + + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0); + + /* Generate an update event to reload the prescaler */ + + pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + } + } + else +#endif + { + /* Generate an update event to reload the prescaler (all timers) */ + + pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + } + + /* Handle channel specific setup */ + + ccenable = 0; + ocmode1 = 0; + ocmode2 = 0; + +#ifdef CONFIG_PWM_MULTICHAN + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) +#endif + { + ub16_t duty; +#ifdef CONFIG_STM32_STM32F30XX + uint32_t chanmode; + bool ocmbit = false; +#else + uint16_t chanmode; +#endif + uint8_t channel; +#ifdef CONFIG_PWM_MULTICHAN + int j; +#endif + enum stm32_chanmode_e mode; + +#ifdef CONFIG_PWM_MULTICHAN + duty = info->channels[i].duty; + channel = info->channels[i].channel; + + for (j = 0; j < PWM_NCHANNELS; j++) + { + if (priv->channels[j].channel == channel) + { + mode = priv->channels[j].mode; + break; + } + } + + if (j >= PWM_NCHANNELS) + { + pwmdbg("No such channel: %d\n", channel); + return -EINVAL; + } +#else + duty = info->duty; + channel = priv->channels[0].channel; + mode = priv->channels[0].mode; +#endif + + /* Duty cycle: + * + * duty cycle = ccr / reload (fractional value) + */ + + ccr = b16toi(duty * reload + b16HALF); + + pwmvdbg("ccr: %d\n", ccr); + + switch (mode) + { + case STM32_CHANMODE_PWM1: + chanmode = ATIM_CCMR_MODE_PWM1; + break; + + case STM32_CHANMODE_PWM2: + chanmode = ATIM_CCMR_MODE_PWM2; + break; + +#ifdef CONFIG_STM32_STM32F30XX + case STM32_CHANMODE_COMBINED1: + chanmode = ATIM_CCMR_MODE_COMBINED1; + ocmbit = true; + break; + + case STM32_CHANMODE_COMBINED2: + chanmode = ATIM_CCMR_MODE_COMBINED2; + ocmbit = true; + break; + + case STM32_CHANMODE_ASYMMETRIC1: + chanmode = ATIM_CCMR_MODE_ASYMMETRIC1; + ocmbit = true; + break; + + case STM32_CHANMODE_ASYMMETRIC2: + chanmode = ATIM_CCMR_MODE_ASYMMETRIC2; + ocmbit = true; + break; +#endif + + default: + pwmdbg("No such mode: %d\n", (int)mode); + return -EINVAL; + } + + switch (channel) + { + case 1: /* PWM Mode configuration: Channel 1 */ + { + /* Select the CCER enable bit for this channel */ + + ccenable |= ATIM_CCER_CC1E; + + /* Set the CCMR1 mode values (leave CCMR2 zero) */ + + ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) | + (chanmode << ATIM_CCMR1_OC1M_SHIFT) | + ATIM_CCMR1_OC1PE; + +#ifdef CONFIG_STM32_STM32F30XX + if (ocmbit) + { + ocmode1 |= ATIM_CCMR1_OC1M; + } +#endif + + /* Set the duty cycle by writing to the CCR register for this channel */ + + pwm_putreg(priv, STM32_GTIM_CCR1_OFFSET, (uint16_t)ccr); + } + break; + + case 2: /* PWM Mode configuration: Channel 2 */ + { + /* Select the CCER enable bit for this channel */ + + ccenable |= ATIM_CCER_CC2E; + + /* Set the CCMR1 mode values (leave CCMR2 zero) */ + + ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) | + (chanmode << ATIM_CCMR1_OC2M_SHIFT) | + ATIM_CCMR1_OC2PE; + +#ifdef CONFIG_STM32_STM32F30XX + if (ocmbit) + { + ocmode1 |= ATIM_CCMR1_OC2M; + } +#endif + + /* Set the duty cycle by writing to the CCR register for this channel */ + + pwm_putreg(priv, STM32_GTIM_CCR2_OFFSET, (uint16_t)ccr); + } + break; + + case 3: /* PWM Mode configuration: Channel 3 */ + { + /* Select the CCER enable bit for this channel */ + + ccenable |= ATIM_CCER_CC3E; + + /* Set the CCMR2 mode values (leave CCMR1 zero) */ + + ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) | + (chanmode << ATIM_CCMR2_OC3M_SHIFT) | + ATIM_CCMR2_OC3PE; + +#ifdef CONFIG_STM32_STM32F30XX + if (ocmbit) + { + ocmode2 |= ATIM_CCMR2_OC3M; + } +#endif + + /* Set the duty cycle by writing to the CCR register for this channel */ + + pwm_putreg(priv, STM32_GTIM_CCR3_OFFSET, (uint16_t)ccr); + } + break; + + case 4: /* PWM Mode configuration: Channel 4 */ + { + /* Select the CCER enable bit for this channel */ + + ccenable |= ATIM_CCER_CC4E; + + /* Set the CCMR2 mode values (leave CCMR1 zero) */ + + ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) | + (chanmode << ATIM_CCMR2_OC4M_SHIFT) | + ATIM_CCMR2_OC4PE; + +#ifdef CONFIG_STM32_STM32F30XX + if (ocmbit) + { + ocmode2 |= ATIM_CCMR2_OC4M; + } +#endif + + /* Set the duty cycle by writing to the CCR register for this channel */ + + pwm_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)ccr); + } + break; + + default: + pwmdbg("No such channel: %d\n", channel); + return -EINVAL; + } + } + + /* Disable the Channel by resetting the CCxE Bit in the CCER register */ + + ccer = pwm_getreg(priv, STM32_GTIM_CCER_OFFSET); + ccer &= ~ccenable; + pwm_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); + + /* Fetch the CR2, CCMR1, and CCMR2 register (already have cr1 and ccer) */ + + cr2 = pwm_getreg(priv, STM32_GTIM_CR2_OFFSET); + ccmr1 = pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET); + ccmr2 = pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET); + + /* Reset the Output Compare Mode Bits and set the select output compare mode */ + + ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE | + ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE +#ifdef CONFIG_STM32_STM32F30XX + | ATIM_CCMR1_OC1M | ATIM_CCMR1_OC2M +#endif + ); + ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE | + ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE +#ifdef CONFIG_STM32_STM32F30XX + | ATIM_CCMR2_OC3M | ATIM_CCMR2_OC4M +#endif + ); + ccmr1 |= ocmode1; + ccmr2 |= ocmode2; + + /* Reset the output polarity level of all channels (selects high polarity)*/ + + ccer &= ~(ATIM_CCER_CC1P | ATIM_CCER_CC2P | ATIM_CCER_CC3P | ATIM_CCER_CC4P); + + /* Enable the output state of the selected channels */ + + ccer &= ~(ATIM_CCER_CC1E | ATIM_CCER_CC2E | ATIM_CCER_CC3E | ATIM_CCER_CC4E); + ccer |= ccenable; + + /* Some special setup for advanced timers */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) + if (priv->timtype == TIMTYPE_ADVANCED) + { + uint16_t bdtr; + + /* Reset output N polarity level, output N state, output compare state, + * output compare N idle state. + */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | + ATIM_CCER_CC3NE | ATIM_CCER_CC3NP | ATIM_CCER_CC4NP); +#else + ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | + ATIM_CCER_CC3NE | ATIM_CCER_CC3NP); +#endif + + /* Reset the output compare and output compare N IDLE State */ + + cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N | ATIM_CR2_OIS2 | ATIM_CR2_OIS2N | + ATIM_CR2_OIS3 | ATIM_CR2_OIS3N | ATIM_CR2_OIS4); + + /* Set the main output enable (MOE) bit and clear the OSSI and OSSR + * bits in the BDTR register. + */ + + bdtr = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + bdtr &= ~(ATIM_BDTR_OSSI | ATIM_BDTR_OSSR); + bdtr |= ATIM_BDTR_MOE; + pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, bdtr); + } +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + else +#endif +#endif +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + { + ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP); + } +#endif + + /* Save the modified register values */ + + pwm_putreg(priv, STM32_GTIM_CR2_OFFSET, cr2); +#ifdef CONFIG_STM32_STM32F30XX + putreg32(ccmr1, priv->base + STM32_GTIM_CCMR1_OFFSET); + putreg32(ccmr2, priv->base + STM32_GTIM_CCMR2_OFFSET); +#else + pwm_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + pwm_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2); +#endif + pwm_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); + + /* Set the ARR Preload Bit */ + + cr1 = pwm_getreg(priv, STM32_GTIM_CR1_OFFSET); + cr1 |= GTIM_CR1_ARPE; + pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* Setup update interrupt. If info->count is > 0, then we can be + * assured that pwm_start() has already verified: (1) that this is an + * advanced timer, and that (2) the repetition count is within range. + */ + +#ifdef CONFIG_PWM_PULSECOUNT + if (info->count > 0) + { + /* Clear all pending interrupts and enable the update interrupt. */ + + pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); + pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, ATIM_DIER_UIE); + + /* Enable the timer */ + + cr1 |= GTIM_CR1_CEN; + pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* And enable timer interrupts at the NVIC */ + + up_enable_irq(priv->irq); + } + else +#endif + { + /* Just enable the timer, leaving all interrupts disabled */ + + cr1 |= GTIM_CR1_CEN; + pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + } + + pwm_dumpregs(priv, "After starting"); + return OK; +} + +/**************************************************************************** + * Name: pwm_interrupt + * + * Description: + * Handle timer interrupts. + * + * Input parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) +static int pwm_interrupt(struct stm32_pwmtimer_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = pwm_getreg(priv, STM32_ATIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + pwm_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + + /* Calculate the new count by subtracting the number of pulses + * since the last interrupt. + */ + + if (priv->count <= priv->prev) + { + /* We are finished. Turn off the mast output to stop the output as + * quickly as possible. + */ + + regval = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + regval &= ~ATIM_BDTR_MOE; + pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, regval); + + /* Disable first interrtups, stop and reset the timer */ + + (void)pwm_stop((FAR struct pwm_lowerhalf_s *)priv); + + /* Then perform the callback into the upper half driver */ + + pwm_expired(priv->handle); + + priv->handle = NULL; + priv->count = 0; + priv->prev = 0; + priv->curr = 0; + } + else + { + /* Decrement the count of pulses remaining using the number of + * pulses generated since the last interrupt. + */ + + priv->count -= priv->prev; + + /* Set up the next RCR. Set 'prev' to the value of the RCR that + * was loaded when the update occurred (just before this interrupt) + * and set 'curr' to the current value of the RCR register (which + * will bet loaded on the next update event). + */ + + priv->prev = priv->curr; + priv->curr = pwm_pulsecount(priv->count - priv->prev); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1); + } + + /* Now all of the time critical stuff is done so we can do some debug output */ + + pwmllvdbg("Update interrupt SR: %04x prev: %d curr: %d count: %d\n", + regval, priv->prev, priv->curr, priv->count); + + return OK; +} +#endif + +/**************************************************************************** + * Name: pwm_tim1/8interrupt + * + * Description: + * Handle timer 1 and 8 interrupts. + * + * Input parameters: + * Standard NuttX interrupt inputs + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_STM32_TIM1_PWM) +static int pwm_tim1interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm1dev); +} +#endif + +#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_STM32_TIM8_PWM) +static int pwm_tim8interrupt(int irq, void *context) +{ + return pwm_interrupt(&g_pwm8dev); +} +#endif + +/**************************************************************************** + * Name: pwm_pulsecount + * + * Description: + * Pick an optimal pulse count to program the RCR. + * + * Input parameters: + * count - The total count remaining + * + * Returned Value: + * The recommended pulse count + * + ****************************************************************************/ + +#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) +static uint8_t pwm_pulsecount(uint32_t count) +{ + /* The the remaining pulse count is less than or equal to the maximum, the + * just return the count. + */ + + if (count <= ATIM_RCR_REP_MAX) + { + return count; + } + + /* Otherwise, we have to be careful. We do not want a small number of + * counts at the end because we might have trouble responding fast enough. + * If the remaining count is less than 150% of the maximum, then return + * half of the maximum. In this case the final sequence will be between 64 + * and 128. + */ + + else if (count < (3 * ATIM_RCR_REP_MAX / 2)) + { + return (ATIM_RCR_REP_MAX + 1) >> 1; + } + + /* Otherwise, return the maximum. The final count will be 64 or more */ + + else + { + return ATIM_RCR_REP_MAX; + } +} +#endif + +/**************************************************************************** + * Name: pwm_set_apb_clock + * + * Description: + * Enable or disable APB clock for the timer peripheral + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) +{ + uint32_t en_bit; + uint32_t regaddr; + + /* Determine which timer to configure */ + + switch (priv->timid) + { +#ifdef CONFIG_STM32_TIM1_PWM + case 1: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM1EN; + break; +#endif +#ifdef CONFIG_STM32_TIM2_PWM + case 2: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM2EN; + break; +#endif +#ifdef CONFIG_STM32_TIM3_PWM + case 3: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM3EN; + break; +#endif +#ifdef CONFIG_STM32_TIM4_PWM + case 4: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM4EN; + break; +#endif +#ifdef CONFIG_STM32_TIM5_PWM + case 5: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM5EN; + break; +#endif +#ifdef CONFIG_STM32_TIM8_PWM + case 8: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM8EN; + break; +#endif +#ifdef CONFIG_STM32_TIM9_PWM + case 9: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM9EN; + break; +#endif +#ifdef CONFIG_STM32_TIM10_PWM + case 10: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM10EN; + break; +#endif +#ifdef CONFIG_STM32_TIM11_PWM + case 11: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM11EN; + break; +#endif +#ifdef CONFIG_STM32_TIM12_PWM + case 12: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM12EN; + break; +#endif +#ifdef CONFIG_STM32_TIM13_PWM + case 13: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM13EN; + break; +#endif +#ifdef CONFIG_STM32_TIM14_PWM + case 14: + regaddr = STM32_RCC_APB1ENR; + en_bit = RCC_APB1ENR_TIM14EN; + break; +#endif +#ifdef CONFIG_STM32_TIM15_PWM + case 15: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM15EN; + break; +#endif +#ifdef CONFIG_STM32_TIM16_PWM + case 16: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM16EN; + break; +#endif +#ifdef CONFIG_STM32_TIM17_PWM + case 17: + regaddr = STM32_RCC_APB2ENR; + en_bit = RCC_APB2ENR_TIM17EN; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for timer */ + + if (on) + { + modifyreg32(regaddr, 0, en_bit); + } + else + { + modifyreg32(regaddr, en_bit, 0); + } +} + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * APB1 or 2 clocking for the GPIOs has already been configured by the RCC + * logic at power up. + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t pincfg; + int i; + + pwmvdbg("TIM%d\n", priv->timid); + pwm_dumpregs(priv, "Initially"); + + /* Enable APB1/2 clocking for timer. */ + + pwm_set_apb_clock(priv, true); + + /* Configure the PWM output pins, but do not start the timer yet */ + + for (i = 0; i < PWM_NCHANNELS; i++) + { + pincfg = priv->channels[i].pincfg; + if (pincfg == 0) + { + continue; + } + + pwmvdbg("pincfg: %08x\n", pincfg); + + stm32_configgpio(pincfg); + pwm_dumpgpio(pincfg, "PWM setup"); + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t pincfg; + int i; + + pwmvdbg("TIM%d\n", priv->timid); + + /* Make sure that the output has been stopped */ + + pwm_stop(dev); + + /* Disable APB1/2 clocking for timer. */ + + pwm_set_apb_clock(priv, false); + + /* Then put the GPIO pins back to the default state */ + + for (i = 0; i < PWM_NCHANNELS; i++) + { + pincfg = priv->channels[i].pincfg; + if (pincfg == 0) + { + continue; + } + + pwmvdbg("pincfg: %08x\n", pincfg); + + pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK); + +#if defined(CONFIG_STM32_STM32F10XX) + pincfg |= GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT; +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) + pincfg |= GPIO_INPUT | GPIO_FLOAT; +#else +# error "Unrecognized STM32 chip" +#endif + + stm32_configgpio(pincfg); + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef CONFIG_PWM_PULSECOUNT +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info, + FAR void *handle) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + /* Check if a pulsecount has been selected */ + + if (info->count > 0) + { + /* Only the advanced timers (TIM1,8 can support the pulse counting) */ + + if (priv->timtype != TIMTYPE_ADVANCED) + { + pwmdbg("ERROR: TIM%d cannot support pulse count: %d\n", + priv->timid, info->count); + return -EPERM; + } + } + + /* Save the handle */ + + priv->handle = handle; + + /* Start the time */ + + return pwm_timer(priv, info); +} +#else +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + return pwm_timer(priv, info); +} +#endif + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t resetbit; + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + pwmvdbg("TIM%d\n", priv->timid); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + flags = enter_critical_section(); + + /* Disable further interrupts and stop the timer */ + + pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, 0); + pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); + + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_STM32_TIM1_PWM + case 1: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM1RST; + break; +#endif +#ifdef CONFIG_STM32_TIM2_PWM + case 2: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM2RST; + break; +#endif +#ifdef CONFIG_STM32_TIM3_PWM + case 3: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM3RST; + break; +#endif +#ifdef CONFIG_STM32_TIM4_PWM + case 4: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM4RST; + break; +#endif +#ifdef CONFIG_STM32_TIM5_PWM + case 5: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM5RST; + break; +#endif +#ifdef CONFIG_STM32_TIM8_PWM + case 8: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM8RST; + break; +#endif +#ifdef CONFIG_STM32_TIM9_PWM + case 9: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM9RST; + break; +#endif +#ifdef CONFIG_STM32_TIM10_PWM + case 10: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM10RST; + break; +#endif +#ifdef CONFIG_STM32_TIM11_PWM + case 11: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM11RST; + break; +#endif +#ifdef CONFIG_STM32_TIM12_PWM + case 12: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM12RST; + break; +#endif +#ifdef CONFIG_STM32_TIM13_PWM + case 13: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM13RST; + break; +#endif +#ifdef CONFIG_STM32_TIM14_PWM + case 14: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM14RST; + break; +#endif +#ifdef CONFIG_STM32_TIM15_PWM + case 15: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM15RST; + break; +#endif +#ifdef CONFIG_STM32_TIM16_PWM + case 16: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM16RST; + break; +#endif +#ifdef CONFIG_STM32_TIM17_PWM + case 17: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM17RST; + break; +#endif + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where pwm_start() can be called. + */ + + regval = getreg32(regaddr); + regval |= resetbit; + putreg32(regval, regaddr); + + regval &= ~resetbit; + putreg32(regval, regaddr); + leave_critical_section(flags); + + pwmvdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + pwm_dumpregs(priv, "After stop"); + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ +#ifdef CONFIG_DEBUG_PWM + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + /* There are no platform-specific ioctl commands */ + + pwmvdbg("TIM%d\n", priv->timid); +#endif + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,17}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer) +{ + FAR struct stm32_pwmtimer_s *lower; + + pwmvdbg("TIM%d\n", timer); + + switch (timer) + { +#ifdef CONFIG_STM32_TIM1_PWM + case 1: + lower = &g_pwm1dev; + + /* Attach but disable the TIM1 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_tim1interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif + +#ifdef CONFIG_STM32_TIM2_PWM + case 2: + lower = &g_pwm2dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM3_PWM + case 3: + lower = &g_pwm3dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM4_PWM + case 4: + lower = &g_pwm4dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM5_PWM + case 5: + lower = &g_pwm5dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM8_PWM + case 8: + lower = &g_pwm8dev; + + /* Attach but disable the TIM8 update interrupt */ + +#ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_tim8interrupt); + up_disable_irq(lower->irq); +#endif + break; +#endif + +#ifdef CONFIG_STM32_TIM9_PWM + case 9: + lower = &g_pwm9dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM10_PWM + case 10: + lower = &g_pwm10dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM11_PWM + case 11: + lower = &g_pwm11dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM12_PWM + case 12: + lower = &g_pwm12dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM13_PWM + case 13: + lower = &g_pwm13dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM14_PWM + case 14: + lower = &g_pwm14dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM15_PWM + case 15: + lower = &g_pwm15dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM16_PWM + case 16: + lower = &g_pwm16dev; + break; +#endif + +#ifdef CONFIG_STM32_TIM17_PWM + case 17: + lower = &g_pwm17dev; + break; +#endif + + default: + pwmdbg("No such timer configured\n"); + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,17 */ diff --git a/arch/arm/src/stm32/stm32_pwm.h b/arch/arm/src/stm32/stm32_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..e636ead3a37b447e5864845ce7ca3581976ad6f2 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwm.h @@ -0,0 +1,1108 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_pwm.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_PWM_H +#define __ARCH_ARM_SRC_STM32_STM32_PWM_H + +/* The STM32 does not have dedicated PWM hardware. Rather, pulsed output control + * is a capabilitiy of the STM32 timers. The logic in this file implements the + * lower half of the standard, NuttX PWM interface using the STM32 timers. That + * interface is described in include/nuttx/pwm.h. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is + * to generate modulated outputs for such things as motor control. If CONFIG_STM32_TIMn + * is defined then the CONFIG_STM32_TIMn_PWM must also be defined to indicate that + * timer "n" is intended to be used for pulsed output signal generation. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_PWM +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_PWM +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_PWM +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_PWM +#endif +#ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_PWM +#endif +#ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_PWM +#endif +#ifndef CONFIG_STM32_TIM9 +# undef CONFIG_STM32_TIM9_PWM +#endif +#ifndef CONFIG_STM32_TIM10 +# undef CONFIG_STM32_TIM10_PWM +#endif +#ifndef CONFIG_STM32_TIM11 +# undef CONFIG_STM32_TIM11_PWM +#endif +#ifndef CONFIG_STM32_TIM12 +# undef CONFIG_STM32_TIM12_PWM +#endif +#ifndef CONFIG_STM32_TIM13 +# undef CONFIG_STM32_TIM13_PWM +#endif +#ifndef CONFIG_STM32_TIM14 +# undef CONFIG_STM32_TIM14_PWM +#endif +#ifndef CONFIG_STM32_TIM15 +# undef CONFIG_STM32_TIM15_PWM +#endif +#ifndef CONFIG_STM32_TIM16 +# undef CONFIG_STM32_TIM16_PWM +#endif +#ifndef CONFIG_STM32_TIM17 +# undef CONFIG_STM32_TIM17_PWM +#endif + +/* The basic timers (timer 6 and 7) are not capable of generating output pulses */ + +#undef CONFIG_STM32_TIM6_PWM +#undef CONFIG_STM32_TIM7_PWM + +/* Check if PWM support for any channel is enabled. */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ + defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ + defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ + defined(CONFIG_STM32_TIM9_PWM) || defined(CONFIG_STM32_TIM10_PWM) || \ + defined(CONFIG_STM32_TIM11_PWM) || defined(CONFIG_STM32_TIM12_PWM) || \ + defined(CONFIG_STM32_TIM13_PWM) || defined(CONFIG_STM32_TIM14_PWM) || \ + defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ + defined(CONFIG_STM32_TIM17_PWM) + +#include +#include "chip/stm32_tim.h" + +#ifdef CONFIG_PWM_MULTICHAN + +#ifdef CONFIG_STM32_TIM1_CHANNEL1 +# ifdef CONFIG_STM32_TIM1_CH1OUT +# define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT +# else +# define PWM_TIM1_CH1CFG 0 +# endif +# define PWM_TIM1_CHANNEL1 1 +#else +# define PWM_TIM1_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL2 +# ifdef CONFIG_STM32_TIM1_CH2OUT +# define PWM_TIM1_CH2CFG GPIO_TIM1_CH2OUT +# else +# define PWM_TIM1_CH2CFG 0 +# endif +# define PWM_TIM1_CHANNEL2 1 +#else +# define PWM_TIM1_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL3 +# ifdef CONFIG_STM32_TIM1_CH3OUT +# define PWM_TIM1_CH3CFG GPIO_TIM1_CH3OUT +# else +# define PWM_TIM1_CH3CFG 0 +# endif +# define PWM_TIM1_CHANNEL3 1 +#else +# define PWM_TIM1_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL4 +# ifdef CONFIG_STM32_TIM1_CH4OUT +# define PWM_TIM1_CH4CFG GPIO_TIM1_CH4OUT +# else +# define PWM_TIM1_CH4CFG 0 +# endif +# define PWM_TIM1_CHANNEL4 1 +#else +# define PWM_TIM1_CHANNEL4 0 +#endif +#define PWM_TIM1_NCHANNELS (PWM_TIM1_CHANNEL1 + PWM_TIM1_CHANNEL2 + \ + PWM_TIM1_CHANNEL3 + PWM_TIM1_CHANNEL4) + +#ifdef CONFIG_STM32_TIM2_CHANNEL1 +# ifdef CONFIG_STM32_TIM2_CH1OUT +# define PWM_TIM2_CH1CFG GPIO_TIM2_CH1OUT +# else +# define PWM_TIM2_CH1CFG 0 +# endif +# define PWM_TIM2_CHANNEL1 1 +#else +# define PWM_TIM2_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL2 +# ifdef CONFIG_STM32_TIM2_CH2OUT +# define PWM_TIM2_CH2CFG GPIO_TIM2_CH2OUT +# else +# define PWM_TIM2_CH2CFG 0 +# endif +# define PWM_TIM2_CHANNEL2 1 +#else +# define PWM_TIM2_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL3 +# ifdef CONFIG_STM32_TIM2_CH3OUT +# define PWM_TIM2_CH3CFG GPIO_TIM2_CH3OUT +# else +# define PWM_TIM2_CH3CFG 0 +# endif +# define PWM_TIM2_CHANNEL3 1 +#else +# define PWM_TIM2_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL4 +# ifdef CONFIG_STM32_TIM2_CH4OUT +# define PWM_TIM2_CH4CFG GPIO_TIM2_CH4OUT +# else +# define PWM_TIM2_CH4CFG 0 +# endif +# define PWM_TIM2_CHANNEL4 1 +#else +# define PWM_TIM2_CHANNEL4 0 +#endif +#define PWM_TIM2_NCHANNELS (PWM_TIM2_CHANNEL1 + PWM_TIM2_CHANNEL2 + \ + PWM_TIM2_CHANNEL3 + PWM_TIM2_CHANNEL4) + +#ifdef CONFIG_STM32_TIM3_CHANNEL1 +# ifdef CONFIG_STM32_TIM3_CH1OUT +# define PWM_TIM3_CH1CFG GPIO_TIM3_CH1OUT +# else +# define PWM_TIM3_CH1CFG 0 +# endif +# define PWM_TIM3_CHANNEL1 1 +#else +# define PWM_TIM3_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL2 +# ifdef CONFIG_STM32_TIM3_CH2OUT +# define PWM_TIM3_CH2CFG GPIO_TIM3_CH2OUT +# else +# define PWM_TIM3_CH2CFG 0 +# endif +# define PWM_TIM3_CHANNEL2 1 +#else +# define PWM_TIM3_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL3 +# ifdef CONFIG_STM32_TIM3_CH3OUT +# define PWM_TIM3_CH3CFG GPIO_TIM3_CH3OUT +# else +# define PWM_TIM3_CH3CFG 0 +# endif +# define PWM_TIM3_CHANNEL3 1 +#else +# define PWM_TIM3_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL4 +# ifdef CONFIG_STM32_TIM3_CH4OUT +# define PWM_TIM3_CH4CFG GPIO_TIM3_CH4OUT +# else +# define PWM_TIM3_CH4CFG 0 +# endif +# define PWM_TIM3_CHANNEL4 1 +#else +# define PWM_TIM3_CHANNEL4 0 +#endif +#define PWM_TIM3_NCHANNELS (PWM_TIM3_CHANNEL1 + PWM_TIM3_CHANNEL2 + \ + PWM_TIM3_CHANNEL3 + PWM_TIM3_CHANNEL4) + +#ifdef CONFIG_STM32_TIM4_CHANNEL1 +# ifdef CONFIG_STM32_TIM4_CH1OUT +# define PWM_TIM4_CH1CFG GPIO_TIM4_CH1OUT +# else +# define PWM_TIM4_CH1CFG 0 +# endif +# define PWM_TIM4_CHANNEL1 1 +#else +# define PWM_TIM4_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL2 +# ifdef CONFIG_STM32_TIM4_CH2OUT +# define PWM_TIM4_CH2CFG GPIO_TIM4_CH2OUT +# else +# define PWM_TIM4_CH2CFG 0 +# endif +# define PWM_TIM4_CHANNEL2 1 +#else +# define PWM_TIM4_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL3 +# ifdef CONFIG_STM32_TIM4_CH3OUT +# define PWM_TIM4_CH3CFG GPIO_TIM4_CH3OUT +# else +# define PWM_TIM4_CH3CFG 0 +# endif +# define PWM_TIM4_CHANNEL3 1 +#else +# define PWM_TIM4_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL4 +# ifdef CONFIG_STM32_TIM4_CH4OUT +# define PWM_TIM4_CH4CFG GPIO_TIM4_CH4OUT +# else +# define PWM_TIM4_CH4CFG 0 +# endif +# define PWM_TIM4_CHANNEL4 1 +#else +# define PWM_TIM4_CHANNEL4 0 +#endif +#define PWM_TIM4_NCHANNELS (PWM_TIM4_CHANNEL1 + PWM_TIM4_CHANNEL2 + \ + PWM_TIM4_CHANNEL3 + PWM_TIM4_CHANNEL4) + +#ifdef CONFIG_STM32_TIM5_CHANNEL1 +# ifdef CONFIG_STM32_TIM5_CH1OUT +# define PWM_TIM5_CH1CFG GPIO_TIM5_CH1OUT +# else +# define PWM_TIM5_CH1CFG 0 +# endif +# define PWM_TIM5_CHANNEL1 1 +#else +# define PWM_TIM5_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL2 +# ifdef CONFIG_STM32_TIM5_CH2OUT +# define PWM_TIM5_CH2CFG GPIO_TIM5_CH2OUT +# else +# define PWM_TIM5_CH2CFG 0 +# endif +# define PWM_TIM5_CHANNEL2 1 +#else +# define PWM_TIM5_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL3 +# ifdef CONFIG_STM32_TIM5_CH3OUT +# define PWM_TIM5_CH3CFG GPIO_TIM5_CH3OUT +# else +# define PWM_TIM5_CH3CFG 0 +# endif +# define PWM_TIM5_CHANNEL3 1 +#else +# define PWM_TIM5_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL4 +# ifdef CONFIG_STM32_TIM5_CH4OUT +# define PWM_TIM5_CH4CFG GPIO_TIM5_CH4OUT +# else +# define PWM_TIM5_CH4CFG 0 +# endif +# define PWM_TIM5_CHANNEL4 1 +#else +# define PWM_TIM5_CHANNEL4 0 +#endif +#define PWM_TIM5_NCHANNELS (PWM_TIM5_CHANNEL1 + PWM_TIM5_CHANNEL2 + \ + PWM_TIM5_CHANNEL3 + PWM_TIM5_CHANNEL4) + +#ifdef CONFIG_STM32_TIM8_CHANNEL1 +# ifdef CONFIG_STM32_TIM8_CH1OUT +# define PWM_TIM8_CH1CFG GPIO_TIM8_CH1OUT +# else +# define PWM_TIM8_CH1CFG 0 +# endif +# define PWM_TIM8_CHANNEL1 1 +#else +# define PWM_TIM8_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL2 +# ifdef CONFIG_STM32_TIM8_CH2OUT +# define PWM_TIM8_CH2CFG GPIO_TIM8_CH2OUT +# else +# define PWM_TIM8_CH2CFG 0 +# endif +# define PWM_TIM8_CHANNEL2 1 +#else +# define PWM_TIM8_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL3 +# ifdef CONFIG_STM32_TIM8_CH3OUT +# define PWM_TIM8_CH3CFG GPIO_TIM8_CH3OUT +# else +# define PWM_TIM8_CH3CFG 0 +# endif +# define PWM_TIM8_CHANNEL3 1 +#else +# define PWM_TIM8_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL4 +# ifdef CONFIG_STM32_TIM8_CH4OUT +# define PWM_TIM8_CH4CFG GPIO_TIM8_CH4OUT +# else +# define PWM_TIM8_CH4CFG 0 +# endif +# define PWM_TIM8_CHANNEL4 1 +#else +# define PWM_TIM8_CHANNEL4 0 +#endif +#define PWM_TIM8_NCHANNELS (PWM_TIM8_CHANNEL1 + PWM_TIM8_CHANNEL2 + \ + PWM_TIM8_CHANNEL3 + PWM_TIM8_CHANNEL4) + +#ifdef CONFIG_STM32_TIM9_CHANNEL1 +# ifdef CONFIG_STM32_TIM9_CH1OUT +# define PWM_TIM9_CH1CFG GPIO_TIM9_CH1OUT +# else +# define PWM_TIM9_CH1CFG 0 +# endif +# define PWM_TIM9_CHANNEL1 1 +#else +# define PWM_TIM9_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL2 +# ifdef CONFIG_STM32_TIM9_CH2OUT +# define PWM_TIM9_CH2CFG GPIO_TIM9_CH2OUT +# else +# define PWM_TIM9_CH2CFG 0 +# endif +# define PWM_TIM9_CHANNEL2 1 +#else +# define PWM_TIM9_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL3 +# ifdef CONFIG_STM32_TIM9_CH3OUT +# define PWM_TIM9_CH3CFG GPIO_TIM9_CH3OUT +# else +# define PWM_TIM9_CH3CFG 0 +# endif +# define PWM_TIM9_CHANNEL3 1 +#else +# define PWM_TIM9_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL4 +# ifdef CONFIG_STM32_TIM9_CH4OUT +# define PWM_TIM9_CH4CFG GPIO_TIM9_CH4OUT +# else +# define PWM_TIM9_CH4CFG 0 +# endif +# define PWM_TIM9_CHANNEL4 1 +#else +# define PWM_TIM9_CHANNEL4 0 +#endif +#define PWM_TIM9_NCHANNELS (PWM_TIM9_CHANNEL1 + PWM_TIM9_CHANNEL2 + \ + PWM_TIM9_CHANNEL3 + PWM_TIM9_CHANNEL4) + +#ifdef CONFIG_STM32_TIM10_CHANNEL1 +# ifdef CONFIG_STM32_TIM10_CH1OUT +# define PWM_TIM10_CH1CFG GPIO_TIM10_CH1OUT +# else +# define PWM_TIM10_CH1CFG 0 +# endif +# define PWM_TIM10_CHANNEL1 1 +#else +# define PWM_TIM10_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL2 +# ifdef CONFIG_STM32_TIM10_CH2OUT +# define PWM_TIM10_CH2CFG GPIO_TIM10_CH2OUT +# else +# define PWM_TIM10_CH2CFG 0 +# endif +# define PWM_TIM10_CHANNEL2 1 +#else +# define PWM_TIM10_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL3 +# ifdef CONFIG_STM32_TIM10_CH3OUT +# define PWM_TIM10_CH3CFG GPIO_TIM10_CH3OUT +# else +# define PWM_TIM10_CH3CFG 0 +# endif +# define PWM_TIM10_CHANNEL3 1 +#else +# define PWM_TIM10_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM10_CHANNEL4 +# ifdef CONFIG_STM32_TIM10_CH4OUT +# define PWM_TIM10_CH4CFG GPIO_TIM10_CH4OUT +# else +# define PWM_TIM10_CH4CFG 0 +# endif +# define PWM_TIM10_CHANNEL4 1 +#else +# define PWM_TIM10_CHANNEL4 0 +#endif +#define PWM_TIM10_NCHANNELS (PWM_TIM10_CHANNEL1 + PWM_TIM10_CHANNEL2 + \ + PWM_TIM10_CHANNEL3 + PWM_TIM10_CHANNEL4) + +#ifdef CONFIG_STM32_TIM11_CHANNEL1 +# ifdef CONFIG_STM32_TIM11_CH1OUT +# define PWM_TIM11_CH1CFG GPIO_TIM11_CH1OUT +# else +# define PWM_TIM11_CH1CFG 0 +# endif +# define PWM_TIM11_CHANNEL1 1 +#else +# define PWM_TIM11_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL2 +# ifdef CONFIG_STM32_TIM11_CH2OUT +# define PWM_TIM11_CH2CFG GPIO_TIM11_CH2OUT +# else +# define PWM_TIM11_CH2CFG 0 +# endif +# define PWM_TIM11_CHANNEL2 1 +#else +# define PWM_TIM11_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL3 +# ifdef CONFIG_STM32_TIM11_CH3OUT +# define PWM_TIM11_CH3CFG GPIO_TIM11_CH3OUT +# else +# define PWM_TIM11_CH3CFG 0 +# endif +# define PWM_TIM11_CHANNEL3 1 +#else +# define PWM_TIM11_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM11_CHANNEL4 +# ifdef CONFIG_STM32_TIM11_CH4OUT +# define PWM_TIM11_CH4CFG GPIO_TIM11_CH4OUT +# else +# define PWM_TIM11_CH4CFG 0 +# endif +# define PWM_TIM11_CHANNEL4 1 +#else +# define PWM_TIM11_CHANNEL4 0 +#endif +#define PWM_TIM11_NCHANNELS (PWM_TIM11_CHANNEL1 + PWM_TIM11_CHANNEL2 + \ + PWM_TIM11_CHANNEL3 + PWM_TIM11_CHANNEL4) + +#ifdef CONFIG_STM32_TIM12_CHANNEL1 +# ifdef CONFIG_STM32_TIM12_CH1OUT +# define PWM_TIM12_CH1CFG GPIO_TIM12_CH1OUT +# else +# define PWM_TIM12_CH1CFG 0 +# endif +# define PWM_TIM12_CHANNEL1 1 +#else +# define PWM_TIM12_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL2 +# ifdef CONFIG_STM32_TIM12_CH2OUT +# define PWM_TIM12_CH2CFG GPIO_TIM12_CH2OUT +# else +# define PWM_TIM12_CH2CFG 0 +# endif +# define PWM_TIM12_CHANNEL2 1 +#else +# define PWM_TIM12_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL3 +# ifdef CONFIG_STM32_TIM12_CH3OUT +# define PWM_TIM12_CH3CFG GPIO_TIM12_CH3OUT +# else +# define PWM_TIM12_CH3CFG 0 +# endif +# define PWM_TIM12_CHANNEL3 1 +#else +# define PWM_TIM12_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL4 +# ifdef CONFIG_STM32_TIM12_CH4OUT +# define PWM_TIM12_CH4CFG GPIO_TIM12_CH4OUT +# else +# define PWM_TIM12_CH4CFG 0 +# endif +# define PWM_TIM12_CHANNEL4 1 +#else +# define PWM_TIM12_CHANNEL4 0 +#endif +#define PWM_TIM12_NCHANNELS (PWM_TIM12_CHANNEL1 + PWM_TIM12_CHANNEL2 + \ + PWM_TIM12_CHANNEL3 + PWM_TIM12_CHANNEL4) + +#ifdef CONFIG_STM32_TIM13_CHANNEL1 +# ifdef CONFIG_STM32_TIM13_CH1OUT +# define PWM_TIM13_CH1CFG GPIO_TIM13_CH1OUT +# else +# define PWM_TIM13_CH1CFG 0 +# endif +# define PWM_TIM13_CHANNEL1 1 +#else +# define PWM_TIM13_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL2 +# ifdef CONFIG_STM32_TIM13_CH2OUT +# define PWM_TIM13_CH2CFG GPIO_TIM13_CH2OUT +# else +# define PWM_TIM13_CH2CFG 0 +# endif +# define PWM_TIM13_CHANNEL2 1 +#else +# define PWM_TIM13_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL3 +# ifdef CONFIG_STM32_TIM13_CH3OUT +# define PWM_TIM13_CH3CFG GPIO_TIM13_CH3OUT +# else +# define PWM_TIM13_CH3CFG 0 +# endif +# define PWM_TIM13_CHANNEL3 1 +#else +# define PWM_TIM13_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM13_CHANNEL4 +# ifdef CONFIG_STM32_TIM13_CH4OUT +# define PWM_TIM13_CH4CFG GPIO_TIM13_CH4OUT +# else +# define PWM_TIM13_CH4CFG 0 +# endif +# define PWM_TIM13_CHANNEL4 1 +#else +# define PWM_TIM13_CHANNEL4 0 +#endif +#define PWM_TIM13_NCHANNELS (PWM_TIM13_CHANNEL1 + PWM_TIM13_CHANNEL2 + \ + PWM_TIM13_CHANNEL3 + PWM_TIM13_CHANNEL4) + +#ifdef CONFIG_STM32_TIM14_CHANNEL1 +# ifdef CONFIG_STM32_TIM14_CH1OUT +# define PWM_TIM14_CH1CFG GPIO_TIM14_CH1OUT +# else +# define PWM_TIM14_CH1CFG 0 +# endif +# define PWM_TIM14_CHANNEL1 1 +#else +# define PWM_TIM14_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL2 +# ifdef CONFIG_STM32_TIM14_CH2OUT +# define PWM_TIM14_CH2CFG GPIO_TIM14_CH2OUT +# else +# define PWM_TIM14_CH2CFG 0 +# endif +# define PWM_TIM14_CHANNEL2 1 +#else +# define PWM_TIM14_CHANNEL2 0 +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL3 +# ifdef CONFIG_STM32_TIM14_CH3OUT +# define PWM_TIM14_CH3CFG GPIO_TIM14_CH3OUT +# else +# define PWM_TIM14_CH3CFG 0 +# endif +# define PWM_TIM14_CHANNEL3 1 +#else +# define PWM_TIM14_CHANNEL3 0 +#endif +#ifdef CONFIG_STM32_TIM14_CHANNEL4 +# ifdef CONFIG_STM32_TIM14_CH4OUT +# define PWM_TIM14_CH4CFG GPIO_TIM14_CH4OUT +# else +# define PWM_TIM14_CH4CFG 0 +# endif +# define PWM_TIM14_CHANNEL4 1 +#else +# define PWM_TIM14_CHANNEL4 0 +#endif +#define PWM_TIM14_NCHANNELS (PWM_TIM14_CHANNEL1 + PWM_TIM14_CHANNEL2 + \ + PWM_TIM14_CHANNEL3 + PWM_TIM14_CHANNEL4) + +#ifdef CONFIG_STM32_TIM15_CHANNEL1 +# ifdef CONFIG_STM32_TIM15_CH1OUT +# define PWM_TIM15_CH1CFG GPIO_TIM15_CH1OUT +# else +# define PWM_TIM15_CH1CFG 0 +# endif +# define PWM_TIM15_CHANNEL1 1 +#else +# define PWM_TIM15_CHANNEL1 0 +#endif +#ifdef CONFIG_STM32_TIM15_CHANNEL2 +# ifdef CONFIG_STM32_TIM15_CH2OUT +# define PWM_TIM15_CH2CFG GPIO_TIM15_CH2OUT +# else +# define PWM_TIM15_CH2CFG 0 +# endif +# define PWM_TIM15_CHANNEL2 1 +#else +# define PWM_TIM15_CHANNEL2 0 +#endif +#define PWM_TIM15_NCHANNELS (PWM_TIM15_CHANNEL1 + PWM_TIM15_CHANNEL2) + +#ifdef CONFIG_STM32_TIM16_CHANNEL1 +# ifdef CONFIG_STM32_TIM16_CH1OUT +# define PWM_TIM16_CH1CFG GPIO_TIM16_CH1OUT +# else +# define PWM_TIM16_CH1CFG 0 +# endif +# define PWM_TIM16_CHANNEL1 1 +#else +# define PWM_TIM16_CHANNEL1 0 +#endif +#define PWM_TIM16_NCHANNELS PWM_TIM16_CHANNEL1 + +#ifdef CONFIG_STM32_TIM17_CHANNEL1 +# ifdef CONFIG_STM32_TIM17_CH1OUT +# define PWM_TIM17_CH1CFG GPIO_TIM17_CH1OUT +# else +# define PWM_TIM17_CH1CFG 0 +# endif +# define PWM_TIM17_CHANNEL1 1 +#else +# define PWM_TIM17_CHANNEL1 0 +#endif +#define PWM_TIM17_NCHANNELS PWM_TIM17_CHANNEL1 + +#define PWM_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define PWM_NCHANNELS PWM_MAX(PWM_TIM1_NCHANNELS, \ + PWM_MAX(PWM_TIM2_NCHANNELS, \ + PWM_MAX(PWM_TIM3_NCHANNELS, \ + PWM_MAX(PWM_TIM4_NCHANNELS, \ + PWM_MAX(PWM_TIM5_NCHANNELS, \ + PWM_MAX(PWM_TIM8_NCHANNELS, \ + PWM_MAX(PWM_TIM9_NCHANNELS, \ + PWM_MAX(PWM_TIM10_NCHANNELS, \ + PWM_MAX(PWM_TIM11_NCHANNELS, \ + PWM_MAX(PWM_TIM12_NCHANNELS, \ + PWM_MAX(PWM_TIM13_NCHANNELS, \ + PWM_MAX(PWM_TIM14_NCHANNELS, \ + PWM_MAX(PWM_TIM15_NCHANNELS, \ + PWM_MAX(PWM_TIM16_NCHANNELS, \ + PWM_TIM17_NCHANNELS)))))))))))))) + +#else + +/* For each timer that is enabled for PWM usage, we need the following additional + * configuration settings: + * + * CONFIG_STM32_TIMx_CHANNEL - Specifies the timer output channel {1,..,4} + * PWM_TIMx_CHn - One of the values defined in chip/stm32*_pinmap.h. In the case + * where there are multiple pin selections, the correct setting must be provided + * in the arch/board/board.h file. + * + * NOTE: The STM32 timers are each capable of generating different signals on + * each of the four channels with different duty cycles. That capability is + * not supported by this driver: Only one output channel per timer. + */ + +#ifdef CONFIG_STM32_TIM1_PWM +# if !defined(CONFIG_STM32_TIM1_CHANNEL) +# error "CONFIG_STM32_TIM1_CHANNEL must be provided" +# elif CONFIG_STM32_TIM1_CHANNEL == 1 +# define CONFIG_STM32_TIM1_CHANNEL1 1 +# define CONFIG_STM32_TIM1_CH1MODE CONFIG_STM32_TIM1_CHMODE +# define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT +# elif CONFIG_STM32_TIM1_CHANNEL == 2 +# define CONFIG_STM32_TIM1_CHANNEL2 1 +# define CONFIG_STM32_TIM1_CH2MODE CONFIG_STM32_TIM1_CHMODE +# define PWM_TIM1_CH2CFG GPIO_TIM1_CH2OUT +# elif CONFIG_STM32_TIM1_CHANNEL == 3 +# define CONFIG_STM32_TIM1_CHANNEL3 1 +# define CONFIG_STM32_TIM1_CH3MODE CONFIG_STM32_TIM1_CHMODE +# define PWM_TIM1_CH3CFG GPIO_TIM1_CH3OUT +# elif CONFIG_STM32_TIM1_CHANNEL == 4 +# define CONFIG_STM32_TIM1_CHANNEL4 1 +# define CONFIG_STM32_TIM1_CH4MODE CONFIG_STM32_TIM1_CHMODE +# define PWM_TIM1_CH4CFG GPIO_TIM1_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM1_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM2_PWM +# if !defined(CONFIG_STM32_TIM2_CHANNEL) +# error "CONFIG_STM32_TIM2_CHANNEL must be provided" +# elif CONFIG_STM32_TIM2_CHANNEL == 1 +# define CONFIG_STM32_TIM2_CHANNEL1 1 +# define CONFIG_STM32_TIM2_CH1MODE CONFIG_STM32_TIM2_CHMODE +# define PWM_TIM2_CH1CFG GPIO_TIM2_CH1OUT +# elif CONFIG_STM32_TIM2_CHANNEL == 2 +# define CONFIG_STM32_TIM2_CHANNEL2 1 +# define CONFIG_STM32_TIM2_CH2MODE CONFIG_STM32_TIM2_CHMODE +# define PWM_TIM2_CH2CFG GPIO_TIM2_CH2OUT +# elif CONFIG_STM32_TIM2_CHANNEL == 3 +# define CONFIG_STM32_TIM2_CHANNEL3 1 +# define CONFIG_STM32_TIM2_CH3MODE CONFIG_STM32_TIM2_CHMODE +# define PWM_TIM2_CH3CFG GPIO_TIM2_CH3OUT +# elif CONFIG_STM32_TIM2_CHANNEL == 4 +# define CONFIG_STM32_TIM2_CHANNEL4 1 +# define CONFIG_STM32_TIM2_CH4MODE CONFIG_STM32_TIM2_CHMODE +# define PWM_TIM2_CH4CFG GPIO_TIM2_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM2_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM3_PWM +# if !defined(CONFIG_STM32_TIM3_CHANNEL) +# error "CONFIG_STM32_TIM3_CHANNEL must be provided" +# elif CONFIG_STM32_TIM3_CHANNEL == 1 +# define CONFIG_STM32_TIM3_CHANNEL1 1 +# define CONFIG_STM32_TIM3_CH1MODE CONFIG_STM32_TIM3_CHMODE +# define PWM_TIM3_CH1CFG GPIO_TIM3_CH1OUT +# elif CONFIG_STM32_TIM3_CHANNEL == 2 +# define CONFIG_STM32_TIM3_CHANNEL2 1 +# define CONFIG_STM32_TIM3_CH2MODE CONFIG_STM32_TIM3_CHMODE +# define PWM_TIM3_CH2CFG GPIO_TIM3_CH2OUT +# elif CONFIG_STM32_TIM3_CHANNEL == 3 +# define CONFIG_STM32_TIM3_CHANNEL3 1 +# define CONFIG_STM32_TIM3_CH3MODE CONFIG_STM32_TIM3_CHMODE +# define PWM_TIM3_CH3CFG GPIO_TIM3_CH3OUT +# elif CONFIG_STM32_TIM3_CHANNEL == 4 +# define CONFIG_STM32_TIM3_CHANNEL4 1 +# define CONFIG_STM32_TIM3_CH4MODE CONFIG_STM32_TIM3_CHMODE +# define PWM_TIM3_CH4CFG GPIO_TIM3_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM3_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM4_PWM +# if !defined(CONFIG_STM32_TIM4_CHANNEL) +# error "CONFIG_STM32_TIM4_CHANNEL must be provided" +# elif CONFIG_STM32_TIM4_CHANNEL == 1 +# define CONFIG_STM32_TIM4_CHANNEL1 1 +# define CONFIG_STM32_TIM4_CH1MODE CONFIG_STM32_TIM4_CHMODE +# define PWM_TIM4_CH1CFG GPIO_TIM4_CH1OUT +# elif CONFIG_STM32_TIM4_CHANNEL == 2 +# define CONFIG_STM32_TIM4_CHANNEL2 1 +# define CONFIG_STM32_TIM4_CH2MODE CONFIG_STM32_TIM4_CHMODE +# define PWM_TIM4_CH2CFG GPIO_TIM4_CH2OUT +# elif CONFIG_STM32_TIM4_CHANNEL == 3 +# define CONFIG_STM32_TIM4_CHANNEL3 1 +# define CONFIG_STM32_TIM4_CH3MODE CONFIG_STM32_TIM4_CHMODE +# define PWM_TIM4_CH3CFG GPIO_TIM4_CH3OUT +# elif CONFIG_STM32_TIM4_CHANNEL == 4 +# define CONFIG_STM32_TIM4_CHANNEL4 1 +# define CONFIG_STM32_TIM4_CH4MODE CONFIG_STM32_TIM4_CHMODE +# define PWM_TIM4_CH4CFG GPIO_TIM4_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM4_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM5_PWM +# if !defined(CONFIG_STM32_TIM5_CHANNEL) +# error "CONFIG_STM32_TIM5_CHANNEL must be provided" +# elif CONFIG_STM32_TIM5_CHANNEL == 1 +# define CONFIG_STM32_TIM5_CHANNEL1 1 +# define CONFIG_STM32_TIM5_CH1MODE CONFIG_STM32_TIM5_CHMODE +# define PWM_TIM5_CH1CFG GPIO_TIM5_CH1OUT +# elif CONFIG_STM32_TIM5_CHANNEL == 2 +# define CONFIG_STM32_TIM5_CHANNEL2 1 +# define CONFIG_STM32_TIM5_CH2MODE CONFIG_STM32_TIM5_CHMODE +# define PWM_TIM5_CH2CFG GPIO_TIM5_CH2OUT +# elif CONFIG_STM32_TIM5_CHANNEL == 3 +# define CONFIG_STM32_TIM5_CHANNEL3 1 +# define CONFIG_STM32_TIM5_CH3MODE CONFIG_STM32_TIM5_CHMODE +# define PWM_TIM5_CH3CFG GPIO_TIM5_CH3OUT +# elif CONFIG_STM32_TIM5_CHANNEL == 4 +# define CONFIG_STM32_TIM5_CHANNEL4 1 +# define CONFIG_STM32_TIM5_CH4MODE CONFIG_STM32_TIM5_CHMODE +# define PWM_TIM5_CH4CFG GPIO_TIM5_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM5_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM8_PWM +# if !defined(CONFIG_STM32_TIM8_CHANNEL) +# error "CONFIG_STM32_TIM8_CHANNEL must be provided" +# elif CONFIG_STM32_TIM8_CHANNEL == 1 +# define CONFIG_STM32_TIM8_CHANNEL1 1 +# define CONFIG_STM32_TIM8_CH1MODE CONFIG_STM32_TIM8_CHMODE +# define PWM_TIM8_CH1CFG GPIO_TIM8_CH1OUT +# elif CONFIG_STM32_TIM8_CHANNEL == 2 +# define CONFIG_STM32_TIM8_CHANNEL2 1 +# define CONFIG_STM32_TIM8_CH2MODE CONFIG_STM32_TIM8_CHMODE +# define PWM_TIM8_CH2CFG GPIO_TIM8_CH2OUT +# elif CONFIG_STM32_TIM8_CHANNEL == 3 +# define CONFIG_STM32_TIM8_CHANNEL3 1 +# define CONFIG_STM32_TIM8_CH3MODE CONFIG_STM32_TIM8_CHMODE +# define PWM_TIM8_CH3CFG GPIO_TIM8_CH3OUT +# elif CONFIG_STM32_TIM8_CHANNEL == 4 +# define CONFIG_STM32_TIM8_CHANNEL4 1 +# define CONFIG_STM32_TIM8_CH4MODE CONFIG_STM32_TIM8_CHMODE +# define PWM_TIM8_CH4CFG GPIO_TIM8_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM8_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM9_PWM +# if !defined(CONFIG_STM32_TIM9_CHANNEL) +# error "CONFIG_STM32_TIM9_CHANNEL must be provided" +# elif CONFIG_STM32_TIM9_CHANNEL == 1 +# define CONFIG_STM32_TIM9_CHANNEL1 1 +# define CONFIG_STM32_TIM9_CH1MODE CONFIG_STM32_TIM9_CHMODE +# define PWM_TIM9_CH1CFG GPIO_TIM9_CH1OUT +# elif CONFIG_STM32_TIM9_CHANNEL == 2 +# define CONFIG_STM32_TIM9_CHANNEL2 1 +# define CONFIG_STM32_TIM9_CH2MODE CONFIG_STM32_TIM9_CHMODE +# define PWM_TIM9_CH2CFG GPIO_TIM9_CH2OUT +# elif CONFIG_STM32_TIM9_CHANNEL == 3 +# define CONFIG_STM32_TIM9_CHANNEL3 1 +# define CONFIG_STM32_TIM9_CH3MODE CONFIG_STM32_TIM9_CHMODE +# define PWM_TIM9_CH3CFG GPIO_TIM9_CH3OUT +# elif CONFIG_STM32_TIM9_CHANNEL == 4 +# define CONFIG_STM32_TIM9_CHANNEL4 1 +# define CONFIG_STM32_TIM9_CH4MODE CONFIG_STM32_TIM9_CHMODE +# define PWM_TIM9_CH4CFG GPIO_TIM9_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM9_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM10_PWM +# if !defined(CONFIG_STM32_TIM10_CHANNEL) +# error "CONFIG_STM32_TIM10_CHANNEL must be provided" +# elif CONFIG_STM32_TIM10_CHANNEL == 1 +# define CONFIG_STM32_TIM10_CHANNEL1 1 +# define CONFIG_STM32_TIM10_CH1MODE CONFIG_STM32_TIM10_CHMODE +# define PWM_TIM10_CH1CFG GPIO_TIM10_CH1OUT +# elif CONFIG_STM32_TIM10_CHANNEL == 2 +# define CONFIG_STM32_TIM10_CHANNEL2 1 +# define CONFIG_STM32_TIM10_CH2MODE CONFIG_STM32_TIM10_CHMODE +# define PWM_TIM10_CH2CFG GPIO_TIM10_CH2OUT +# elif CONFIG_STM32_TIM10_CHANNEL == 3 +# define CONFIG_STM32_TIM10_CHANNEL3 1 +# define CONFIG_STM32_TIM10_CH3MODE CONFIG_STM32_TIM10_CHMODE +# define PWM_TIM10_CH3CFG GPIO_TIM10_CH3OUT +# elif CONFIG_STM32_TIM10_CHANNEL == 4 +# define CONFIG_STM32_TIM10_CHANNEL4 1 +# define CONFIG_STM32_TIM10_CH4MODE CONFIG_STM32_TIM10_CHMODE +# define PWM_TIM10_CH4CFG GPIO_TIM10_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM10_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM11_PWM +# if !defined(CONFIG_STM32_TIM11_CHANNEL) +# error "CONFIG_STM32_TIM11_CHANNEL must be provided" +# elif CONFIG_STM32_TIM11_CHANNEL == 1 +# define CONFIG_STM32_TIM11_CHANNEL1 1 +# define CONFIG_STM32_TIM11_CH1MODE CONFIG_STM32_TIM11_CHMODE +# define PWM_TIM11_CH1CFG GPIO_TIM11_CH1OUT +# elif CONFIG_STM32_TIM11_CHANNEL == 2 +# define CONFIG_STM32_TIM11_CHANNEL2 1 +# define CONFIG_STM32_TIM11_CH2MODE CONFIG_STM32_TIM11_CHMODE +# define PWM_TIM11_CH2CFG GPIO_TIM11_CH2OUT +# elif CONFIG_STM32_TIM11_CHANNEL == 3 +# define CONFIG_STM32_TIM11_CHANNEL3 1 +# define CONFIG_STM32_TIM11_CH3MODE CONFIG_STM32_TIM11_CHMODE +# define PWM_TIM11_CH3CFG GPIO_TIM11_CH3OUT +# elif CONFIG_STM32_TIM11_CHANNEL == 4 +# define CONFIG_STM32_TIM11_CHANNEL4 1 +# define CONFIG_STM32_TIM11_CH4MODE CONFIG_STM32_TIM11_CHMODE +# define PWM_TIM11_CH4CFG GPIO_TIM11_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM11_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM12_PWM +# if !defined(CONFIG_STM32_TIM12_CHANNEL) +# error "CONFIG_STM32_TIM12_CHANNEL must be provided" +# elif CONFIG_STM32_TIM12_CHANNEL == 1 +# define CONFIG_STM32_TIM12_CHANNEL1 1 +# define CONFIG_STM32_TIM12_CH1MODE CONFIG_STM32_TIM12_CHMODE +# define PWM_TIM12_CH1CFG GPIO_TIM12_CH1OUT +# elif CONFIG_STM32_TIM12_CHANNEL == 2 +# define CONFIG_STM32_TIM12_CHANNEL2 1 +# define CONFIG_STM32_TIM12_CH2MODE CONFIG_STM32_TIM12_CHMODE +# define PWM_TIM12_CH2CFG GPIO_TIM12_CH2OUT +# elif CONFIG_STM32_TIM12_CHANNEL == 3 +# define CONFIG_STM32_TIM12_CHANNEL3 1 +# define CONFIG_STM32_TIM12_CH3MODE CONFIG_STM32_TIM12_CHMODE +# define PWM_TIM12_CH3CFG GPIO_TIM12_CH3OUT +# elif CONFIG_STM32_TIM12_CHANNEL == 4 +# define CONFIG_STM32_TIM12_CHANNEL4 1 +# define CONFIG_STM32_TIM12_CH4MODE CONFIG_STM32_TIM12_CHMODE +# define PWM_TIM12_CH4CFG GPIO_TIM12_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM12_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM13_PWM +# if !defined(CONFIG_STM32_TIM13_CHANNEL) +# error "CONFIG_STM32_TIM13_CHANNEL must be provided" +# elif CONFIG_STM32_TIM13_CHANNEL == 1 +# define CONFIG_STM32_TIM13_CHANNEL1 1 +# define CONFIG_STM32_TIM13_CH1MODE CONFIG_STM32_TIM13_CHMODE +# define PWM_TIM13_CH1CFG GPIO_TIM13_CH1OUT +# elif CONFIG_STM32_TIM13_CHANNEL == 2 +# define CONFIG_STM32_TIM13_CHANNEL2 1 +# define CONFIG_STM32_TIM13_CH2MODE CONFIG_STM32_TIM13_CHMODE +# define PWM_TIM13_CH2CFG GPIO_TIM13_CH2OUT +# elif CONFIG_STM32_TIM13_CHANNEL == 3 +# define CONFIG_STM32_TIM13_CHANNEL3 1 +# define CONFIG_STM32_TIM13_CH3MODE CONFIG_STM32_TIM13_CHMODE +# define PWM_TIM13_CH3CFG GPIO_TIM13_CH3OUT +# elif CONFIG_STM32_TIM13_CHANNEL == 4 +# define CONFIG_STM32_TIM13_CHANNEL4 1 +# define CONFIG_STM32_TIM13_CH4MODE CONFIG_STM32_TIM13_CHMODE +# define PWM_TIM13_CH4CFG GPIO_TIM13_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM13_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM14_PWM +# if !defined(CONFIG_STM32_TIM14_CHANNEL) +# error "CONFIG_STM32_TIM14_CHANNEL must be provided" +# elif CONFIG_STM32_TIM14_CHANNEL == 1 +# define CONFIG_STM32_TIM14_CHANNEL1 1 +# define CONFIG_STM32_TIM14_CH1MODE CONFIG_STM32_TIM14_CHMODE +# define PWM_TIM14_CH1CFG GPIO_TIM14_CH1OUT +# elif CONFIG_STM32_TIM14_CHANNEL == 2 +# define CONFIG_STM32_TIM14_CHANNEL2 1 +# define CONFIG_STM32_TIM14_CH2MODE CONFIG_STM32_TIM14_CHMODE +# define PWM_TIM14_CH2CFG GPIO_TIM14_CH2OUT +# elif CONFIG_STM32_TIM14_CHANNEL == 3 +# define CONFIG_STM32_TIM14_CHANNEL3 1 +# define CONFIG_STM32_TIM14_CH3MODE CONFIG_STM32_TIM14_CHMODE +# define PWM_TIM14_CH3CFG GPIO_TIM14_CH3OUT +# elif CONFIG_STM32_TIM14_CHANNEL == 4 +# define CONFIG_STM32_TIM14_CHANNEL4 1 +# define CONFIG_STM32_TIM14_CH4MODE CONFIG_STM32_TIM14_CHMODE +# define PWM_TIM14_CH4CFG GPIO_TIM14_CH4OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM14_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM15_PWM +# if !defined(CONFIG_STM32_TIM15_CHANNEL) +# error "CONFIG_STM32_TIM15_CHANNEL must be provided" +# elif CONFIG_STM32_TIM15_CHANNEL == 1 +# define CONFIG_STM32_TIM15_CHANNEL1 1 +# define CONFIG_STM32_TIM15_CH1MODE CONFIG_STM32_TIM15_CHMODE +# define PWM_TIM15_CH1CFG GPIO_TIM15_CH1OUT +# elif CONFIG_STM32_TIM15_CHANNEL == 2 +# define CONFIG_STM32_TIM15_CHANNEL2 1 +# define CONFIG_STM32_TIM15_CH2MODE CONFIG_STM32_TIM15_CHMODE +# define PWM_TIM15_CH2CFG GPIO_TIM15_CH2OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM15_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM16_PWM +# if !defined(CONFIG_STM32_TIM16_CHANNEL) +# error "CONFIG_STM32_TIM16_CHANNEL must be provided" +# elif CONFIG_STM32_TIM16_CHANNEL == 1 +# define CONFIG_STM32_TIM16_CHANNEL1 1 +# define CONFIG_STM32_TIM16_CH1MODE CONFIG_STM32_TIM16_CHMODE +# define PWM_TIM16_CH1CFG GPIO_TIM16_CH1OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM16_CHANNEL" +# endif +#endif + +#ifdef CONFIG_STM32_TIM17_PWM +# if !defined(CONFIG_STM32_TIM17_CHANNEL) +# error "CONFIG_STM32_TIM17_CHANNEL must be provided" +# elif CONFIG_STM32_TIM17_CHANNEL == 1 +# define CONFIG_STM32_TIM17_CHANNEL1 1 +# define CONFIG_STM32_TIM17_CH1MODE CONFIG_STM32_TIM17_CHMODE +# define PWM_TIM17_CH1CFG GPIO_TIM17_CH1OUT +# else +# error "Unsupported value of CONFIG_STM32_TIM17_CHANNEL" +# endif +#endif + +#define PWM_NCHANNELS 1 + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,17}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32_TIMx_PWM */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_PWM_H */ diff --git a/arch/arm/src/stm32/stm32_pwr.c b/arch/arm/src/stm32/stm32_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..a32caaea517529f63c486b208e37ac3ffa638186 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwr.c @@ -0,0 +1,274 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_pwr.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Authors: Uros Platise + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "stm32_pwr.h" + +#if defined(CONFIG_STM32_PWR) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +static inline uint16_t stm32_pwr_getreg(uint8_t offset) +{ + return (uint16_t)getreg32(STM32_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value) +{ + putreg32((uint32_t)value, STM32_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits) +{ + modifyreg32(STM32_PWR_BASE + (uint32_t)offset, (uint32_t)clearbits, (uint32_t)setbits); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables access to the backup domain (RTC registers, RTC backup data registers + * and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ************************************************************************************/ + +bool stm32_pwr_enablebkp(bool writable) +{ + uint16_t regval; + bool waswritable; + + /* Get the current state of the STM32 PWR control register */ + + regval = stm32_pwr_getreg(STM32_PWR_CR_OFFSET); + waswritable = ((regval & PWR_CR_DBP) != 0); + + /* Enable or disable the ability to write */ + + if (waswritable && !writable) + { + /* Disable backup domain access */ + + regval &= ~PWR_CR_DBP; + stm32_pwr_putreg(STM32_PWR_CR_OFFSET, regval); + } + else if (!waswritable && writable) + { + /* Enable backup domain access */ + + regval |= PWR_CR_DBP; + stm32_pwr_putreg(STM32_PWR_CR_OFFSET, regval); + + /* Enable does not happen right away */ + + up_udelay(4); + } + + return waswritable; +} + +/************************************************************************************ + * Name: stm32_pwr_enablebreg + * + * Description: + * Enables the Backup regulator, the Backup regulator (used to maintain backup + * SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup + * regulator is switched off. The backup SRAM can still be used but its content will + * be lost in the Standby and VBAT modes. Once set, the application must wait that + * the Backup Regulator Ready flag (BRR) is set to indicate that the data written + * into the RAM will be maintained in the Standby and VBAT modes. + * + * Input Parameters: + * regon - state to set it to + * + * Returned Values: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +void stm32_pwr_enablebreg(bool regon) +{ + uint16_t regval; + + regval = stm32_pwr_getreg(STM32_PWR_CSR_OFFSET); + regval &= ~PWR_CSR_BRE; + regval |= regon ? PWR_CSR_BRE : 0; + stm32_pwr_putreg(STM32_PWR_CSR_OFFSET, regval); + + if (regon) + { + while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_BRR) == 0); + } +} +#endif + +/************************************************************************************ + * Name: stm32_pwr_setvos + * + * Description: + * Set voltage scaling for EnergyLite devices. + * + * Input Parameters: + * vos - Properly aligned voltage scaling select bits for the PWR_CR register. + * + * Returned Values: + * None + * + * Assumptions: + * At present, this function is called only from initialization logic. If used + * for any other purpose that protection to assure that its operation is atomic + * will be required. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_ENERGYLITE +void stm32_pwr_setvos(uint16_t vos) +{ + uint16_t regval; + + /* The following sequence is required to program the voltage regulator ranges: + * 1. Check VDD to identify which ranges are allowed... + * 2. Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0. + * 3. Configure the voltage scaling range by setting the VOS bits in the PWR_CR + * register. + * 4. Poll VOSF bit of in PWR_CSR register. Wait until it is reset to 0. + */ + + while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_VOSF) != 0); + + regval = stm32_pwr_getreg(STM32_PWR_CR_OFFSET); + regval &= ~PWR_CR_VOS_MASK; + regval |= (vos & PWR_CR_VOS_MASK); + stm32_pwr_putreg(STM32_PWR_CR_OFFSET, regval); + + while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_VOSF) != 0); +} + +/************************************************************************************ + * Name: stm32_pwr_setpvd + * + * Description: + * Sets power voltage detector + * + * Input Parameters: + * pls - PVD level + * + * Returned Values: + * None + * + * Assumptions: + * At present, this function is called only from initialization logic. If used + * for any other purpose that protection to assure that its operation is atomic + * will be required. + * + ************************************************************************************/ + +void stm32_pwr_setpvd(uint16_t pls) +{ + uint16_t regval; + + /* Set PLS */ + + regval = stm32_pwr_getreg(STM32_PWR_CR_OFFSET); + regval &= ~PWR_CR_PLS_MASK; + regval |= (pls & PWR_CR_PLS_MASK); + + /* Write value to register */ + + stm32_pwr_putreg(STM32_PWR_CR_OFFSET, regval); +} + +/************************************************************************************ + * Name: stm32_pwr_enablepvd + * + * Description: + * Enable the Programmable Voltage Detector + * + ************************************************************************************/ + +void stm32_pwr_enablepvd(void) +{ + /* Enable PVD by setting the PVDE bit in PWR_CR register. */ + + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_PVDE); +} + +/************************************************************************************ + * Name: stm32_pwr_disablepvd + * + * Description: + * Disable the Programmable Voltage Detector + * + ************************************************************************************/ + +void stm32_pwr_disablepvd(void) +{ + /* Disable PVD by clearing the PVDE bit in PWR_CR register. */ + + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, PWR_CR_PVDE, 0); +} + +#endif /* CONFIG_STM32_ENERGYLITE */ + +#endif /* CONFIG_STM32_PWR */ diff --git a/arch/arm/src/stm32/stm32_pwr.h b/arch/arm/src/stm32/stm32_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..49e0657f552b68a1085d1576fb714b592d491592 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwr.h @@ -0,0 +1,180 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_pwr.h + * + * Copyright (C) 2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32_STM32_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32_pwr.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables access to the backup domain (RTC registers, RTC backup data registers + * and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ************************************************************************************/ + +bool stm32_pwr_enablebkp(bool writable); + +/************************************************************************************ + * Name: stm32_pwr_enablebreg + * + * Description: + * Enables the Backup regulator, the Backup regulator (used to maintain backup + * SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup + * regulator is switched off. The backup SRAM can still be used but its content will + * be lost in the Standby and VBAT modes. Once set, the application must wait that + * the Backup Regulator Ready flag (BRR) is set to indicate that the data written + * into the RAM will be maintained in the Standby and VBAT modes. + * + * Input Parameters: + * regon - state to set it to + * + * Returned Values: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +void stm32_pwr_enablebreg(bool regon); +#else +# define stm32_pwr_enablebreg(regon) +#endif + +/************************************************************************************ + * Name: stm32_pwr_setvos + * + * Description: + * Set voltage scaling for EnergyLite devices. + * + * Input Parameters: + * vos - Properly aligned voltage scaling select bits for the PWR_CR register. + * + * Returned Values: + * None + * + * Assumptions: + * At present, this function is called only from initialization logic. If used + * for any other purpose that protection to assure that its operation is atomic + * will be required. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_ENERGYLITE +void stm32_pwr_setvos(uint16_t vos); + +/************************************************************************************ + * Name: stm32_pwr_setpvd + * + * Description: + * Sets power voltage detector for EnergyLite devices. + * + * Input Parameters: + * pls - PVD level + * + * Returned Values: + * None + * + * Assumptions: + * At present, this function is called only from initialization logic. + * + ************************************************************************************/ + +void stm32_pwr_setpvd(uint16_t pls); + +/************************************************************************************ + * Name: stm32_pwr_enablepvd + * + * Description: + * Enable the Programmable Voltage Detector + * + ************************************************************************************/ + +void stm32_pwr_enablepvd(void); + +/************************************************************************************ + * Name: stm32_pwr_disablepvd + * + * Description: + * Disable the Programmable Voltage Detector + * + ************************************************************************************/ + +void stm32_pwr_disablepvd(void); + +#endif /* CONFIG_STM32_ENERGYLITE */ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_PWR_H */ diff --git a/arch/arm/src/stm32/stm32_qencoder.c b/arch/arm/src/stm32/stm32_qencoder.c new file mode 100644 index 0000000000000000000000000000000000000000..5cec5e0874d2fdac8bb23999a7173059e3197853 --- /dev/null +++ b/arch/arm/src/stm32/stm32_qencoder.c @@ -0,0 +1,1304 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_qencoder.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_tim.h" +#include "stm32_qencoder.h" + +#ifdef CONFIG_QENCODER + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Clocking *************************************************************************/ +/* The CLKOUT value should not exceed the CLKIN value */ + +#if defined(CONFIG_STM32_TIM1_QE) && CONFIG_STM32_TIM1_QECLKOUT > STM32_APB2_TIM1_CLKIN +# warning "CONFIG_STM32_TIM1_QECLKOUT exceeds STM32_APB2_TIM1_CLKIN" +#endif + +#if defined(CONFIG_STM32_TIM2_QE) && CONFIG_STM32_TIM2_QECLKOUT > STM32_APB1_TIM2_CLKIN +# warning "CONFIG_STM32_TIM2_QECLKOUT exceeds STM32_APB2_TIM2_CLKIN" +#endif + +#if defined(CONFIG_STM32_TIM3_QE) && CONFIG_STM32_TIM3_QECLKOUT > STM32_APB1_TIM3_CLKIN +# warning "CONFIG_STM32_TIM3_QECLKOUT exceeds STM32_APB2_TIM3_CLKIN" +#endif + +#if defined(CONFIG_STM32_TIM4_QE) && CONFIG_STM32_TIM4_QECLKOUT > STM32_APB1_TIM4_CLKIN +# warning "CONFIG_STM32_TIM4_QECLKOUT exceeds STM32_APB2_TIM4_CLKIN" +#endif + +#if defined(CONFIG_STM32_TIM5_QE) && CONFIG_STM32_TIM5_QECLKOUT > STM32_APB1_TIM5_CLKIN +# warning "CONFIG_STM32_TIM5_QECLKOUT exceeds STM32_APB2_TIM5_CLKIN" +#endif + +#if defined(CONFIG_STM32_TIM8_QE) && CONFIG_STM32_TIM8_QECLKOUT > STM32_APB2_TIM8_CLKIN +# warning "CONFIG_STM32_TIM8_QECLKOUT exceeds STM32_APB2_TIM8_CLKIN" +#endif + +/* Timers ***************************************************************************/ + +#undef HAVE_32BIT_TIMERS +#undef HAVE_16BIT_TIMERS + +/* On the F1 series, all timers are 16-bit. */ + +#if defined(CONFIG_STM32_STM32F10XX) + +# define HAVE_16BIT_TIMERS 1 + + /* The width in bits of each timer */ + +# define TIM1_BITWIDTH 16 +# define TIM2_BITWIDTH 16 +# define TIM3_BITWIDTH 16 +# define TIM4_BITWIDTH 16 +# define TIM5_BITWIDTH 16 +# define TIM8_BITWIDTH 16 + +/* On the F3 series, TIM5 is 32-bit. All of the rest are 16-bit */ + +#elif defined(CONFIG_STM32_STM32F30XX) + + /* If TIM5 is enabled, then we have 32-bit timers */ + +# if defined(CONFIG_STM32_TIM5_QE) +# define HAVE_32BIT_TIMERS 1 +# endif + + /* If TIM1,2,3,4, or 8 are enabled, then we have 16-bit timers */ + +# if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM2_QE) || \ + defined(CONFIG_STM32_TIM3_QE) || defined(CONFIG_STM32_TIM4_QE) || \ + defined(CONFIG_STM32_TIM8_QE) +# define HAVE_16BIT_TIMERS 1 +# endif + + /* The width in bits of each timer */ + +# define TIM1_BITWIDTH 16 +# define TIM2_BITWIDTH 16 +# define TIM3_BITWIDTH 16 +# define TIM4_BITWIDTH 16 +# define TIM5_BITWIDTH 32 +# define TIM8_BITWIDTH 16 + +/* On the F4 series, TIM2 and TIM5 are 32-bit. All of the rest are 16-bit */ + +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) + + /* If TIM2 or TIM5 are enabled, then we have 32-bit timers */ + +# if defined(CONFIG_STM32_TIM2_QE) || defined(CONFIG_STM32_TIM5_QE) +# define HAVE_32BIT_TIMERS 1 +# endif + + /* If TIM1,3,4, or 8 are enabled, then we have 16-bit timers */ + +# if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM3_QE) || \ + defined(CONFIG_STM32_TIM4_QE) || defined(CONFIG_STM32_TIM8_QE) +# define HAVE_16BIT_TIMERS 1 +# endif + + /* The width in bits of each timer */ + +# define TIM1_BITWIDTH 16 +# define TIM2_BITWIDTH 32 +# define TIM3_BITWIDTH 16 +# define TIM4_BITWIDTH 16 +# define TIM5_BITWIDTH 32 +# define TIM8_BITWIDTH 16 +#endif + +/* Do we need to support mixed 16- and 32-bit timers */ + +#undef HAVE_MIXEDWIDTH_TIMERS +#if defined(HAVE_16BIT_TIMERS) && defined(HAVE_32BIT_TIMERS) +# define HAVE_MIXEDWIDTH_TIMERS 1 +#endif + +/* Input filter *********************************************************************/ + +#ifdef CONFIG_STM32_QENCODER_FILTER +# if defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_1) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_NOFILT +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_CKINT) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_2) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FCKINT2 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_4) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FCKINT4 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FCKINT8 +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS_2) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_6) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd26 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd28 +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS_4) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_6) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd46 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd48 +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS_8) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_6) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd86 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd88 +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS_16) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_5) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd165 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_6) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd166 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd168 +# endif +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_FDTS_32) +# if defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_5) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd325 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_6) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd326 +# elif defined(CONFIG_STM32_QENCODER_SAMPLE_EVENT_8) +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_FDTSd328 +# endif +# endif + +# ifndef STM32_QENCODER_ICF +# warning "Invalid encoder filter combination, filter disabled" +# endif +#endif + +#ifndef STM32_QENCODER_ICF +# define STM32_QENCODER_ICF GTIM_CCMR_ICF_NOFILT +#endif + +#if defined(CONFIG_STM32_STM32F10XX) +# define STM32_GPIO_INPUT_FLOAT (GPIO_INPUT | GPIO_CNF_INFLOAT | \ + GPIO_MODE_INPUT) +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# define STM32_GPIO_INPUT_FLOAT (GPIO_INPUT | GPIO_FLOAT) +#else +# error "Unrecognized STM32 chip" +#endif + +/* Debug ****************************************************************************/ +/* Non-standard debug that may be enabled just for testing the quadrature encoder */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_SENSORS +#endif + +#ifdef CONFIG_DEBUG_SENSORS +# ifdef CONFIG_DEBUG_VERBOSE +# define qe_dumpgpio(p,m) stm32_dumpgpio(p,m) +# else +# define qe_dumpgpio(p,m) +# endif +#else +# define qe_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* Constant configuration structure that is retained in FLASH */ + +struct stm32_qeconfig_s +{ + uint8_t timid; /* Timer ID {1,2,3,4,5,8} */ + uint8_t irq; /* Timer update IRQ */ +#ifdef HAVE_MIXEDWIDTH_TIMERS + uint8_t width; /* Timer width (16- or 32-bits) */ +#endif +#ifdef CONFIG_STM32_STM32F10XX + uint16_t ti1cfg; /* TI1 input pin configuration (16-bit encoding) */ + uint16_t ti2cfg; /* TI2 input pin configuration (16-bit encoding) */ +#else + uint32_t ti1cfg; /* TI1 input pin configuration (20-bit encoding) */ + uint32_t ti2cfg; /* TI2 input pin configuration (20-bit encoding) */ +#endif + uint32_t base; /* Register base address */ + uint32_t psc; /* Timer input clock prescaler */ + xcpt_t handler; /* Interrupt handler for this IRQ */ +}; + +/* Overall, RAM-based state structure */ + +struct stm32_lowerhalf_s +{ + /* The first field of this state structure must be a pointer to the lower- + * half callback structure: + */ + + FAR const struct qe_ops_s *ops; /* Lower half callback structure */ + + /* STM32 driver-specific fields: */ + + FAR const struct stm32_qeconfig_s *config; /* static onfiguration */ + + bool inuse; /* True: The lower-half driver is in-use */ + +#ifdef HAVE_16BIT_TIMERS + volatile int32_t position; /* The current position offset */ +#endif +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ +/* Helper functions */ + +static uint16_t stm32_getreg16(FAR struct stm32_lowerhalf_s *priv, int offset); +static void stm32_putreg16(FAR struct stm32_lowerhalf_s *priv, int offset, uint16_t value); +static uint32_t stm32_getreg32(FAR struct stm32_lowerhalf_s *priv, int offset); +static void stm32_putreg32(FAR struct stm32_lowerhalf_s *priv, int offset, uint32_t value); + +#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_VERBOSE) +static void stm32_dumpregs(FAR struct stm32_lowerhalf_s *priv, FAR const char *msg); +#else +# define stm32_dumpregs(priv,msg) +#endif + +static FAR struct stm32_lowerhalf_s *stm32_tim2lower(int tim); + +/* Interrupt handling */ + +#ifdef HAVE_16BIT_TIMERS +static int stm32_interrupt(FAR struct stm32_lowerhalf_s *priv); +#if defined(CONFIG_STM32_TIM1_QE) && TIM1_BITWIDTH == 16 +static int stm32_tim1interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_TIM2_QE) && TIM2_BITWIDTH == 16 +static int stm32_tim2interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_TIM3_QE) && TIM3_BITWIDTH == 16 +static int stm32_tim3interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_TIM4_QE) && TIM4_BITWIDTH == 16 +static int stm32_tim4interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_TIM5_QE) && TIM5_BITWIDTH == 16 +static int stm32_tim5interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_TIM8_QE) && TIM8_BITWIDTH == 16 +static int stm32_tim8interrupt(int irq, FAR void *context); +#endif +#endif + +/* Lower-half Quadrature Encoder Driver Methods */ + +static int stm32_setup(FAR struct qe_lowerhalf_s *lower); +static int stm32_shutdown(FAR struct qe_lowerhalf_s *lower); +static int stm32_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos); +static int stm32_reset(FAR struct qe_lowerhalf_s *lower); +static int stm32_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long arg); + +/************************************************************************************ + * Private Data + ************************************************************************************/ +/* The lower half callback structure */ + +static const struct qe_ops_s g_qecallbacks = +{ + .setup = stm32_setup, + .shutdown = stm32_shutdown, + .position = stm32_position, + .reset = stm32_reset, + .ioctl = stm32_ioctl, +}; + +/* Per-timer state structures */ + +#ifdef CONFIG_STM32_TIM1_QE +static const struct stm32_qeconfig_s g_tim1config = +{ + .timid = 1, + .irq = STM32_IRQ_TIM1UP, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM1_BITWIDTH, +#endif + .base = STM32_TIM1_BASE, + .psc = (STM32_APB2_TIM1_CLKIN / CONFIG_STM32_TIM1_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM1_CH1IN, + .ti2cfg = GPIO_TIM1_CH2IN, +#if TIM1_BITWIDTH == 16 + .handler = stm32_tim1interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim1lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim1config, + .inuse = false, +}; + +#endif + +#ifdef CONFIG_STM32_TIM2_QE +static const struct stm32_qeconfig_s g_tim2config = +{ + .timid = 2, + .irq = STM32_IRQ_TIM2, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM2_BITWIDTH, +#endif + .base = STM32_TIM2_BASE, + .psc = (STM32_APB1_TIM2_CLKIN / CONFIG_STM32_TIM2_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM2_CH1IN, + .ti2cfg = GPIO_TIM2_CH2IN, +#if TIM2_BITWIDTH == 16 + .handler = stm32_tim2interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim2lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim2config, + .inuse = false, +}; + +#endif + +#ifdef CONFIG_STM32_TIM3_QE +static const struct stm32_qeconfig_s g_tim3config = +{ + .timid = 3, + .irq = STM32_IRQ_TIM3, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM3_BITWIDTH, +#endif + .base = STM32_TIM3_BASE, + .psc = (STM32_APB1_TIM3_CLKIN / CONFIG_STM32_TIM3_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM3_CH1IN, + .ti2cfg = GPIO_TIM3_CH2IN, +#if TIM3_BITWIDTH == 16 + .handler = stm32_tim3interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim3lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim3config, + .inuse = false, +}; + +#endif + +#ifdef CONFIG_STM32_TIM4_QE +static const struct stm32_qeconfig_s g_tim4config = +{ + .timid = 4, + .irq = STM32_IRQ_TIM4, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM4_BITWIDTH, +#endif + .base = STM32_TIM4_BASE, + .psc = (STM32_APB1_TIM4_CLKIN / CONFIG_STM32_TIM4_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM4_CH1IN, + .ti2cfg = GPIO_TIM4_CH2IN, +#if TIM4_BITWIDTH == 16 + .handler = stm32_tim4interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim4lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim4config, + .inuse = false, +}; + +#endif + +#ifdef CONFIG_STM32_TIM5_QE +static const struct stm32_qeconfig_s g_tim5config = +{ + .timid = 5, + .irq = STM32_IRQ_TIM5, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM5_BITWIDTH, +#endif + .base = STM32_TIM5_BASE, + .psc = (STM32_APB1_TIM5_CLKIN / CONFIG_STM32_TIM5_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM5_CH1IN, + .ti2cfg = GPIO_TIM5_CH2IN, +#if TIM5_BITWIDTH == 16 + .handler = stm32_tim5interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim5lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim5config, + .inuse = false, +}; + +#endif + +#ifdef CONFIG_STM32_TIM8_QE +static const struct stm32_qeconfig_s g_tim8config = +{ + .timid = 8, + .irq = STM32_IRQ_TIM8UP, +#ifdef HAVE_MIXEDWIDTH_TIMERS + .width = TIM8_BITWIDTH, +#endif + .base = STM32_TIM8_BASE, + .psc = (STM32_APB2_TIM8_CLKIN / CONFIG_STM32_TIM8_QECLKOUT) - 1, + .ti1cfg = GPIO_TIM8_CH1IN, + .ti2cfg = GPIO_TIM8_CH2IN, +#if TIM8_BITWIDTH == 16 + .handler = stm32_tim8interrupt, +#endif +}; + +static struct stm32_lowerhalf_s g_tim8lower = +{ + .ops = &g_qecallbacks, + .config = &g_tim8config, + .inuse = false, +}; + +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_getreg16 + * + * Description: + * Read the value of a 16-bit timer register. + * + * Input Parameters: + * priv - A reference to the lower half status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ************************************************************************************/ + +static uint16_t stm32_getreg16(struct stm32_lowerhalf_s *priv, int offset) +{ + return getreg16(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_putreg16 + * + * Description: + * Write a value to a 16-bit timer register. + * + * Input Parameters: + * priv - A reference to the lower half status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void stm32_putreg16(FAR struct stm32_lowerhalf_s *priv, int offset, uint16_t value) +{ + putreg16(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_getreg32 + * + * Description: + * Read the value of a 32-bit timer register. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5 (but works OK + * with the 16-bit TIM1,8 and F1 registers as well). + * + * Input Parameters: + * priv - A reference to the lower half status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ************************************************************************************/ + +static uint32_t stm32_getreg32(FAR struct stm32_lowerhalf_s *priv, int offset) +{ + return getreg32(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_putreg16 + * + * Description: + * Write a value to a 32-bit timer register. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5 (but works OK + * with the 16-bit TIM1,8 and F1 registers). + * + * Input Parameters: + * priv - A reference to the lower half status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void stm32_putreg32(FAR struct stm32_lowerhalf_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->config->base + offset); +} + +/**************************************************************************** + * Name: stm32_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the QENCODER block status + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_VERBOSE) +static void stm32_dumpregs(FAR struct stm32_lowerhalf_s *priv, FAR const char *msg) +{ + snvdbg("%s:\n", msg); + snvdbg(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CR2_OFFSET), + stm32_getreg16(priv, STM32_GTIM_SMCR_OFFSET), + stm32_getreg16(priv, STM32_GTIM_DIER_OFFSET)); + snvdbg(" SR: %04x EGR: %04x CCMR1: %04x CCMR2: %04x\n", + stm32_getreg16(priv, STM32_GTIM_SR_OFFSET), + stm32_getreg16(priv, STM32_GTIM_EGR_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CCMR1_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CCMR2_OFFSET)); + snvdbg(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", + stm32_getreg16(priv, STM32_GTIM_CCER_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CNT_OFFSET), + stm32_getreg16(priv, STM32_GTIM_PSC_OFFSET), + stm32_getreg16(priv, STM32_GTIM_ARR_OFFSET)); + snvdbg(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + stm32_getreg16(priv, STM32_GTIM_CCR1_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CCR2_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CCR3_OFFSET), + stm32_getreg16(priv, STM32_GTIM_CCR4_OFFSET)); +#if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM8_QE) + if (priv->config->timid == 1 || priv->config->timid == 8) + { + snvdbg(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + stm32_getreg16(priv, STM32_ATIM_RCR_OFFSET), + stm32_getreg16(priv, STM32_ATIM_BDTR_OFFSET), + stm32_getreg16(priv, STM32_ATIM_DCR_OFFSET), + stm32_getreg16(priv, STM32_ATIM_DMAR_OFFSET)); + } + else +#endif + { + snvdbg(" DCR: %04x DMAR: %04x\n", + stm32_getreg16(priv, STM32_GTIM_DCR_OFFSET), + stm32_getreg16(priv, STM32_GTIM_DMAR_OFFSET)); + } +} +#endif + +/************************************************************************************ + * Name: stm32_tim2lower + * + * Description: + * Map a timer number to a device structure + * + ************************************************************************************/ + +static FAR struct stm32_lowerhalf_s *stm32_tim2lower(int tim) +{ + switch (tim) + { +#ifdef CONFIG_STM32_TIM1_QE + case 1: + return &g_tim1lower; +#endif +#ifdef CONFIG_STM32_TIM2_QE + case 2: + return &g_tim2lower; +#endif +#ifdef CONFIG_STM32_TIM3_QE + case 3: + return &g_tim3lower; +#endif +#ifdef CONFIG_STM32_TIM4_QE + case 4: + return &g_tim4lower; +#endif +#ifdef CONFIG_STM32_TIM5_QE + case 5: + return &g_tim5lower; +#endif +#ifdef CONFIG_STM32_TIM8_QE + case 8: + return &g_tim8lower; +#endif + default: + return NULL; + } +} + +/************************************************************************************ + * Name: stm32_interrupt + * + * Description: + * Common timer interrupt handling. NOTE: Only 16-bit timers require timer + * interrupts. + * + ************************************************************************************/ + +#ifdef HAVE_16BIT_TIMERS +static int stm32_interrupt(FAR struct stm32_lowerhalf_s *priv) +{ + uint16_t regval; + + /* Verify that this is an update interrupt. Nothing else is expected. */ + + regval = stm32_getreg16(priv, STM32_GTIM_SR_OFFSET); + DEBUGASSERT((regval & ATIM_SR_UIF) != 0); + + /* Clear the UIF interrupt bit */ + + stm32_putreg16(priv, STM32_GTIM_SR_OFFSET, regval & ~GTIM_SR_UIF); + + /* Check the direction bit in the CR1 register and add or subtract the + * maximum value, as appropriate. + */ + + regval = stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET); + if ((regval & ATIM_CR1_DIR) != 0) + { + priv->position -= (int32_t)0x0000ffff; + } + else + { + priv->position += (int32_t)0x0000ffff; + } + + return OK; +} +#endif + +/************************************************************************************ + * Name: stm32_intNinterrupt + * + * Description: + * TIMN interrupt handler + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_TIM1_QE) && TIM1_BITWIDTH == 16 +static int stm32_tim1interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim1lower); +} +#endif + +#if defined(CONFIG_STM32_TIM2_QE) && TIM2_BITWIDTH == 16 +static int stm32_tim2interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim2lower); +} +#endif + +#if defined(CONFIG_STM32_TIM3_QE) && TIM3_BITWIDTH == 16 +static int stm32_tim3interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim3lower); +} +#endif + +#if defined(CONFIG_STM32_TIM4_QE) && TIM4_BITWIDTH == 16 +static int stm32_tim4interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim4lower); +} +#endif + +#if defined(CONFIG_STM32_TIM5_QE) && TIM5_BITWIDTH == 16 +static int stm32_tim5interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim5lower); +} +#endif + +#if defined(CONFIG_STM32_TIM8_QE) && TIM8_BITWIDTH == 16 +static int stm32_tim8interrupt(int irq, FAR void *context) +{ + return stm32_interrupt(&g_tim8lower); +} +#endif + +/************************************************************************************ + * Name: stm32_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * The initial position value should be zero. * + * + ************************************************************************************/ + +static int stm32_setup(FAR struct qe_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint16_t dier; + uint16_t smcr; + uint16_t ccmr1; + uint16_t ccer; + uint16_t cr1; +#ifdef HAVE_16BIT_TIMERS + uint16_t regval; + int ret; +#endif + + /* NOTE: Clocking should have been enabled in the low-level RCC logic at boot-up */ + + /* Timer base configuration */ + + cr1 = stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET); + + /* Clear the direction bit (0=count up) and select the Counter Mode (0=Edge aligned) + * (Timers 2-5 and 1-8 only) + */ + + cr1 &= ~(GTIM_CR1_DIR | GTIM_CR1_CMS_MASK); + stm32_putreg16(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* Set the Autoreload value */ + +#if defined(HAVE_MIXEDWIDTH_TIMERS) + if (priv->config->width == 32) + { + stm32_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffffffff); + } + else + { + stm32_putreg16(priv, STM32_GTIM_ARR_OFFSET, 0xffff); + } +#elif defined(HAVE_32BIT_TIMERS) + stm32_putreg32(priv, STM32_GTIM_ARR_OFFSET, 0xffffffff); +#else + stm32_putreg16(priv, STM32_GTIM_ARR_OFFSET, 0xffff); +#endif + + /* Set the timer prescaler value. The clock input value (CLKIN) is based on the + * peripheral clock (PCLK) and a multiplier. These CLKIN values are provided in + * the board.h file. The prescaler value is then that CLKIN value divided by the + * configured CLKOUT value (minus one) + */ + + stm32_putreg16(priv, STM32_GTIM_PSC_OFFSET, (uint16_t)priv->config->psc); + +#if defined(CONFIG_STM32_TIM1_QE) || defined(CONFIG_STM32_TIM8_QE) + if (priv->config->timid == 1 || priv->config->timid == 8) + { + /* Clear the Repetition Counter value */ + + stm32_putreg16(priv, STM32_ATIM_RCR_OFFSET, 0); + } +#endif + + /* Generate an update event to reload the Prescaler + * and the repetition counter (only for TIM1 and TIM8) value immediately + */ + + stm32_putreg16(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG); + + /* GPIO pin configuration */ + + stm32_configgpio(priv->config->ti1cfg); + stm32_configgpio(priv->config->ti2cfg); + + /* Set the encoder Mode 3 */ + + smcr = stm32_getreg16(priv, STM32_GTIM_SMCR_OFFSET); + smcr &= ~GTIM_SMCR_SMS_MASK; + smcr |= GTIM_SMCR_ENCMD3; + stm32_putreg16(priv, STM32_GTIM_SMCR_OFFSET, smcr); + + /* TI1 Channel Configuration */ + /* Disable the Channel 1: Reset the CC1E Bit */ + + ccer = stm32_getreg16(priv, STM32_GTIM_CCER_OFFSET); + ccer &= ~GTIM_CCER_CC1E; + stm32_putreg16(priv, STM32_GTIM_CCER_OFFSET, ccer); + + ccmr1 = stm32_getreg16(priv, STM32_GTIM_CCMR1_OFFSET); + ccer = stm32_getreg16(priv, STM32_GTIM_CCER_OFFSET); + + /* Select the Input IC1=TI1 and set the filter fSAMPLING=fDTS/4, N=6 */ + + ccmr1 &= ~(GTIM_CCMR1_CC1S_MASK | GTIM_CCMR1_IC1F_MASK); + ccmr1 |= GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC1S_SHIFT; + ccmr1 |= STM32_QENCODER_ICF << GTIM_CCMR1_IC1F_SHIFT; + + /* Select the Polarity=rising and set the CC1E Bit */ + + ccer &= ~(GTIM_CCER_CC1P | GTIM_CCER_CC1NP); + ccer |= GTIM_CCER_CC1E; + + /* Write to TIM CCMR1 and CCER registers */ + + stm32_putreg16(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + stm32_putreg16(priv, STM32_GTIM_CCER_OFFSET, ccer); + + /* Set the Input Capture Prescaler value: Capture performed each time an + * edge is detected on the capture input. + */ + + ccmr1 = stm32_getreg16(priv, STM32_GTIM_CCMR1_OFFSET); + ccmr1 &= ~GTIM_CCMR1_IC1PSC_MASK; + ccmr1 |= (GTIM_CCMR_ICPSC_NOPSC << GTIM_CCMR1_IC1PSC_SHIFT); + stm32_putreg16(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + + /* TI2 Channel Configuration */ + /* Disable the Channel 2: Reset the CC2E Bit */ + + ccer = stm32_getreg16(priv, STM32_GTIM_CCER_OFFSET); + ccer &= ~GTIM_CCER_CC2E; + stm32_putreg16(priv, STM32_GTIM_CCER_OFFSET, ccer); + + ccmr1 = stm32_getreg16(priv, STM32_GTIM_CCMR1_OFFSET); + ccer = stm32_getreg16(priv, STM32_GTIM_CCER_OFFSET); + + /* Select the Input IC2=TI2 and set the filter fSAMPLING=fDTS/4, N=6 */ + + ccmr1 &= ~(GTIM_CCMR1_CC2S_MASK | GTIM_CCMR1_IC2F_MASK); + ccmr1 |= GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC2S_SHIFT; + ccmr1 |= STM32_QENCODER_ICF << GTIM_CCMR1_IC2F_SHIFT; + + /* Select the Polarity=rising and set the CC2E Bit */ + + ccer &= ~(GTIM_CCER_CC2P | GTIM_CCER_CC2NP); + ccer |= GTIM_CCER_CC2E; + + /* Write to TIM CCMR1 and CCER registers */ + + stm32_putreg16(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + stm32_putreg16(priv, STM32_GTIM_CCER_OFFSET, ccer); + + /* Set the Input Capture Prescaler value: Capture performed each time an + * edge is detected on the capture input. + */ + + ccmr1 = stm32_getreg16(priv, STM32_GTIM_CCMR1_OFFSET); + ccmr1 &= ~GTIM_CCMR1_IC2PSC_MASK; + ccmr1 |= (GTIM_CCMR_ICPSC_NOPSC << GTIM_CCMR1_IC2PSC_SHIFT); + stm32_putreg16(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + + /* Disable the update interrupt */ + + dier = stm32_getreg16(priv, STM32_GTIM_DIER_OFFSET); + dier &= ~GTIM_DIER_UIE; + stm32_putreg16(priv, STM32_GTIM_DIER_OFFSET, dier); + + /* There is no need for interrupts with 32-bit timers */ + +#ifdef HAVE_16BIT_TIMERS +#ifdef HAVE_MIXEDWIDTH_TIMERS + if (priv->config->width != 32) +#endif + { + /* Attach the interrupt handler */ + + ret = irq_attach(priv->config->irq, priv->config->handler); + if (ret < 0) + { + stm32_shutdown(lower); + return ret; + } + + /* Enable the update/global interrupt at the NVIC */ + + up_enable_irq(priv->config->irq); + } +#endif + + /* Reset the Update Disable Bit */ + + cr1 = stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET); + cr1 &= ~GTIM_CR1_UDIS; + stm32_putreg16(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* Reset the URS Bit */ + + cr1 &= ~GTIM_CR1_URS; + stm32_putreg16(priv, STM32_GTIM_CR1_OFFSET, cr1); + + /* There is no need for interrupts with 32-bit timers */ + +#ifdef HAVE_16BIT_TIMERS +#ifdef HAVE_MIXEDWIDTH_TIMERS + if (priv->config->width != 32) +#endif + { + /* Clear any pending update interrupts */ + + regval = stm32_getreg16(priv, STM32_GTIM_SR_OFFSET); + stm32_putreg16(priv, STM32_GTIM_SR_OFFSET, regval & ~GTIM_SR_UIF); + + /* Then enable the update interrupt */ + + dier = stm32_getreg16(priv, STM32_GTIM_DIER_OFFSET); + dier |= GTIM_DIER_UIE; + stm32_putreg16(priv, STM32_GTIM_DIER_OFFSET, dier); + } +#endif + + /* Enable the TIM Counter */ + + cr1 = stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET); + cr1 |= GTIM_CR1_CEN; + stm32_putreg16(priv, STM32_GTIM_CR1_OFFSET, cr1); + + return OK; +} + +/************************************************************************************ + * Name: stm32_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * should stop data collection, free any resources, disable timer hardware, and + * put the system into the lowest possible power usage state * + * + ************************************************************************************/ + +static int stm32_shutdown(FAR struct qe_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + irqstate_t flags; + uint32_t regaddr; + uint32_t regval; + uint32_t resetbit; + uint32_t pincfg; + + /* Disable the update/global interrupt at the NVIC */ + + flags = enter_critical_section(); + up_disable_irq(priv->config->irq); + + /* Detach the interrupt handler */ + + (void)irq_detach(priv->config->irq); + + /* Disable interrupts momentary to stop any ongoing timer processing and + * to prevent any concurrent access to the reset register. + */ + + /* Disable further interrupts and stop the timer */ + + stm32_putreg16(priv, STM32_GTIM_DIER_OFFSET, 0); + stm32_putreg16(priv, STM32_GTIM_SR_OFFSET, 0); + + /* Determine which timer to reset */ + + switch (priv->config->timid) + { +#ifdef CONFIG_STM32_TIM1_QE + case 1: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM1RST; + break; +#endif +#ifdef CONFIG_STM32_TIM2_QE + case 2: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM2RST; + break; +#endif +#ifdef CONFIG_STM32_TIM3_QE + case 3: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM3RST; + break; +#endif +#ifdef CONFIG_STM32_TIM4_QE + case 4: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM4RST; + break; +#endif +#ifdef CONFIG_STM32_TIM5_QE + case 5: + regaddr = STM32_RCC_APB1RSTR; + resetbit = RCC_APB1RSTR_TIM5RST; + break; +#endif +#ifdef CONFIG_STM32_TIM8_QE + case 8: + regaddr = STM32_RCC_APB2RSTR; + resetbit = RCC_APB2RSTR_TIM8RST; + break; +#endif + default: + return -EINVAL; + } + + /* Reset the timer - stopping the output and putting the timer back + * into a state where stm32_start() can be called. + */ + + regval = getreg32(regaddr); + regval |= resetbit; + putreg32(regval, regaddr); + + regval &= ~resetbit; + putreg32(regval, regaddr); + leave_critical_section(flags); + + snvdbg("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + stm32_dumpregs(priv, "After stop"); + + /* Put the TI1 GPIO pin back to its default state */ + + pincfg = priv->config->ti1cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= STM32_GPIO_INPUT_FLOAT; + + stm32_configgpio(pincfg); + + /* Put the TI2 GPIO pin back to its default state */ + + pincfg = priv->config->ti2cfg & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= STM32_GPIO_INPUT_FLOAT; + + stm32_configgpio(pincfg); + return OK; +} + +/************************************************************************************ + * Name: stm32_position + * + * Description: + * Return the current position measurement. + * + ************************************************************************************/ + +static int stm32_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; +#ifdef HAVE_16BIT_TIMERS + int32_t position; + int32_t verify; + uint32_t count; + + DEBUGASSERT(lower && priv->inuse); + + /* Loop until we are certain that no interrupt occurred between samples */ + + do + { + /* Don't let another task pre-empt us until we get the measurement. The timer + * interrupt may still be processed + */ + + sched_lock(); + position = priv->position; + count = stm32_getreg32(priv, STM32_GTIM_CNT_OFFSET); + verify = priv->position; + sched_unlock(); + } + while (position != verify); + + /* Return the position measurement */ + + *pos = position + (int32_t)count; +#else + /* Return the counter value */ + + *pos = (int32_t)stm32_getreg32(priv, STM32_GTIM_CNT_OFFSET); +#endif + return OK; +} + +/************************************************************************************ + * Name: stm32_reset + * + * Description: + * Reset the position measurement to zero. + * + ************************************************************************************/ + +static int stm32_reset(FAR struct qe_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; +#ifdef HAVE_16BIT_TIMERS + irqstate_t flags; + + snvdbg("Resetting position to zero\n"); + DEBUGASSERT(lower && priv->inuse); + + /* Reset the timer and the counter. Interrupts are disabled to make this atomic + * (if possible) + */ + + flags = enter_critical_section(); + stm32_putreg32(priv, STM32_GTIM_CNT_OFFSET, 0); + priv->position = 0; + leave_critical_section(flags); +#else + snvdbg("Resetting position to zero\n"); + DEBUGASSERT(lower && priv->inuse); + + /* Reset the counter to zero */ + + stm32_putreg32(priv, STM32_GTIM_CNT_OFFSET, 0); +#endif + return OK; +} + +/************************************************************************************ + * Name: stm32_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + ************************************************************************************/ + +static int stm32_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long arg) +{ + /* No ioctl commands supported */ + + return -ENOTTY; +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_qeinitialize + * + * Description: + * Initialize a quadrature encoder interface. This function must be called from + * board-specific logic. + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/qe0" + * tim - The timer number to used. 'tim' must be an element of {1,2,3,4,5,8} + * + * Returned Values: + * Zero on success; A negated errno value is returned on failure. + * + ************************************************************************************/ + +int stm32_qeinitialize(FAR const char *devpath, int tim) +{ + FAR struct stm32_lowerhalf_s *priv; + int ret; + + /* Find the pre-allocated timer state structure corresponding to this timer */ + + priv = stm32_tim2lower(tim); + if (!priv) + { + sndbg("TIM%d support not configured\n", tim); + return -ENXIO; + } + + /* Make sure that it is available */ + + if (priv->inuse) + { + sndbg("TIM%d is in-used\n", tim); + return -EBUSY; + } + + /* Register the priv-half driver */ + + ret = qe_register(devpath, (FAR struct qe_lowerhalf_s *)priv); + if (ret < 0) + { + sndbg("qe_register failed: %d\n", ret); + return ret; + } + + /* Make sure that the timer is in the shutdown state */ + + stm32_shutdown((FAR struct qe_lowerhalf_s *)priv); + + /* The driver is now in-use */ + + priv->inuse = true; + return OK; +} + +#endif /* CONFIG_QENCODER */ diff --git a/arch/arm/src/stm32/stm32_qencoder.h b/arch/arm/src/stm32/stm32_qencoder.h new file mode 100644 index 0000000000000000000000000000000000000000..5effa7163d78138aa1234c707958d7fd9b7fec26 --- /dev/null +++ b/arch/arm/src/stm32/stm32_qencoder.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_qencoder.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_QENCODER_H +#define __ARCH_ARM_SRC_STM32_STM32_QENCODER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_QENCODER + +/************************************************************************************ + * Included Files + ************************************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is as + * a quadrature encoder input device. If CONFIG_STM32_TIMn is defined then the + * CONFIG_STM32_TIMn_QE must also be defined to indicate that timer "n" is intended + * to be used for as a quadrature encoder. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_QE +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_QE +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_QE +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_QE +#endif +#ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_QE +#endif +#ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_QE +#endif + +/* Only timers 2-5, and 1 & 8 can be used as a quadrature encoder (at least for the + * STM32 F4) + */ + +#undef CONFIG_STM32_TIM6_QE +#undef CONFIG_STM32_TIM7_QE +#undef CONFIG_STM32_TIM9_QE +#undef CONFIG_STM32_TIM10_QE +#undef CONFIG_STM32_TIM11_QE +#undef CONFIG_STM32_TIM12_QE +#undef CONFIG_STM32_TIM13_QE +#undef CONFIG_STM32_TIM14_QE + +/* Clock out frequency. This value is used to calculation the timer CLKIN in + * prescaler value. + */ + +#ifndef CONFIG_STM32_TIM1_QECLKOUT +# define CONFIG_STM32_TIM1_QECLKOUT 28000000 +#endif + +#ifndef CONFIG_STM32_TIM2_QECLKOUT +# define CONFIG_STM32_TIM2_QECLKOUT 28000000 +#endif + +#ifndef CONFIG_STM32_TIM3_QECLKOUT +# define CONFIG_STM32_TIM3_QECLKOUT 28000000 +#endif + +#ifndef CONFIG_STM32_TIM4_QECLKOUT +# define CONFIG_STM32_TIM4_QECLKOUT 28000000 +#endif + +#ifndef CONFIG_STM32_TIM5_QECLKOUT +# define CONFIG_STM32_TIM5_QECLKOUT 28000000 +#endif + +#ifndef CONFIG_STM32_TIM8_QECLKOUT +# define CONFIG_STM32_TIM8_QECLKOUT 28000000 +#endif + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_qeinitialize + * + * Description: + * Initialize a quadrature encoder interface. This function must be called from + * board-specific logic.. + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/qe0" + * tim - The timer number to used. 'tim' must be an element of {1,2,3,4,5,8} + * + * Returned Values: + * Zero on success; A negated errno value is returned on failure. + * + ************************************************************************************/ + +int stm32_qeinitialize(FAR const char *devpath, int tim); + +#endif /* CONFIG_QENCODER */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_QENCODER_H */ + diff --git a/arch/arm/src/stm32/stm32_rcc.c b/arch/arm/src/stm32/stm32_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..8040af9e1e6b0b1ff04a19637ce2f888c31d66cc --- /dev/null +++ b/arch/arm/src/stm32/stm32_rcc.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rcc.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32_flash.h" +#include "stm32.h" +#include "stm32_waste.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_STM32_STM32L15XX) +# include "stm32l15xxx_rcc.c" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "stm32f10xxx_rcc.c" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "stm32f20xxx_rcc.c" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "stm32f30xxx_rcc.c" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "stm32f37xxx_rcc.c" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "stm32f40xxx_rcc.c" +#else +# error "Unsupported STM32 chip" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_clockconfig(void) +{ + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + +#if defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); +} + +/************************************************************************************ + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void) +{ +#if defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif +} +#endif + diff --git a/arch/arm/src/stm32/stm32_rcc.h b/arch/arm/src/stm32/stm32_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..a4939221e8f2e1c2a138e1be4792c40f1df1f38a --- /dev/null +++ b/arch/arm/src/stm32/stm32_rcc.h @@ -0,0 +1,341 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_rcc.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_RRC_H +#define __ARCH_ARM_SRC_STM32_STM32_RRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_rcc.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_rcc.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_rcc.h" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_rcc.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_rcc.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_rcc.h" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* This symbol references the Cortex-M3 vector table (as positioned by the linker + * script, ld.script or ld.script.dfu. The standard location for the vector table is + * at the beginning of FLASH at address 0x0800:0000. If we are using the STMicro DFU + * bootloader, then the vector table will be offset to a different location in FLASH + * and we will need to set the NVIC vector location to this alternative location. + */ + +extern uint32_t _vectors[]; /* See stm32_vectors.S */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_mco1config + * + * Description: + * Selects the clock source to output on MCO1 pin (PA8). PA8 should be configured in + * alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO1 definitions from + * chip/stm32f4xxxx_rcc.h {RCC_CFGR_MCO1_HSI, RCC_CFGR_MCO1_LSE, + * RCC_CFGR_MCO1_HSE, RCC_CFGR_MCO1_PLL} + * div - One of the definitions for the RCC_CFGR_MCO1PRE definitions from + * chip/stm32f4xxxx_rcc.h {RCC_CFGR_MCO1PRE_NONE, RCC_CFGR_MCO1PRE_DIV2, + * RCC_CFGR_MCO1PRE_DIV3, RCC_CFGR_MCO1PRE_DIV4, RCC_CFGR_MCO1PRE_DIV5} + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static inline void stm32_mco1config(uint32_t source, uint32_t div) +{ + uint32_t regval; + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO1_MASK|RCC_CFGR_MCO1PRE_MASK); + regval |= (source | div); + putreg32(regval, STM32_RCC_CFGR); +} +#endif + +/************************************************************************************ + * Name: stm32_mcoconfig + * + * Description: + * Selects the clock source to output on MC pin (PA8) for stm32f10xxx. + * PA8 should be configured in alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO definitions from + * chip/stm32f10xxx_rcc.h {RCC_CFGR_SYSCLK, RCC_CFGR_INTCLK, RCC_CFGR_EXTCLK, + * RCC_CFGR_PLLCLKd2, RCC_CFGR_PLL2CLK, RCC_CFGR_PLL3CLKd2, RCC_CFGR_XT1, + * RCC_CFGR_PLL3CLK} + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) +static inline void stm32_mcoconfig(uint32_t source) +{ + uint32_t regval; + + /* Set MCO source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO_MASK); + regval |= (source & RCC_CFGR_MCO_MASK); + putreg32(regval, STM32_RCC_CFGR); +} +#endif + +/************************************************************************************ + * Name: stm32_mcodivconfig + * + * Description: + * Selects the clock source to output and clock divider on MC pin (PA4) for + * stm32l1xxx. PA4 should be configured in alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCOSEL definitions from + * chip/stm32l15xxx_rcc.h {RCC_CFGR_MCOSEL_DISABLED, RCC_CFGR_MCOSEL_SYSCLK, + * RCC_CFGR_MCOSEL_HSICLK, RCC_CFGR_MCOSEL_MSICLK, RCC_CFGR_MCOSEL_HSECLK, + * RCC_CFGR_MCOSEL_PLLCLK, RCC_CFGR_MCOSEL_LSICLK, RCC_CFGR_MCOSEL_LSECLK} + * divider - One of the definitions for the RCC_CFGR_MCOPRE definitions from + * chip/stm32l15xxx_rcc.h {RCC_CFGR_MCOPRE_DIV1, RCC_CFGR_MCOPRE_DIV2, + * RCC_CFGR_MCOPRE_DIV4, RCC_CFGR_MCOPRE_DIV8, RCC_CFGR_MCOPRE_DIV16} + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32L15XX) +static inline void stm32_mcodivconfig(uint32_t source, uint32_t divider) +{ + uint32_t regval; + + /* Set MCO source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCOSEL_MASK); + regval |= (source & RCC_CFGR_MCOSEL_MASK); + regval &= ~(RCC_CFGR_MCOPRE_MASK); + regval |= (divider & RCC_CFGR_MCOPRE_MASK); + putreg32(regval, STM32_RCC_CFGR); +} +#endif + +/************************************************************************************ + * Name: stm32_mco2config + * + * Description: + * Selects the clock source to output on MCO2 pin (PC9). PC9 should be configured in + * alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO2 definitions from + * chip/stm32f4xxxx_rcc.h {RCC_CFGR_MCO2_SYSCLK, RCC_CFGR_MCO2_PLLI2S, + * RCC_CFGR_MCO2_HSE, RCC_CFGR_MCO2_PLL} + * div - One of the definitions for the RCC_CFGR_MCO2PRE definitions from + * chip/stm32f4xxxx_rcc.h {RCC_CFGR_MCO2PRE_NONE, RCC_CFGR_MCO2PRE_DIV2, + * RCC_CFGR_MCO2PRE_DIV3, RCC_CFGR_MCO2PRE_DIV4, RCC_CFGR_MCO2PRE_DIV5} + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +static inline void stm32_mco2config(uint32_t source, uint32_t div) +{ + uint32_t regval; + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO2_MASK|RCC_CFGR_MCO2PRE_MASK); + regval |= (source | div); + putreg32(regval, STM32_RCC_CFGR); +} +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_clockconfig(void); + +/************************************************************************************ + * Name: stm32_board_clockconfig + * + * Description: + * Any STM32 board may replace the "standard" board clock configuration logic with + * its own, custom clock cofiguration logic. + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG +void stm32_board_clockconfig(void); +#endif + +/************************************************************************************ + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void); +#endif + +/************************************************************************************ + * Name: stm32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator and, if the RTC is + * configured, setup the LSE as the RTC clock source, and enable the RTC. + * + * For the STM32L15X family, this will also select the LSE as the clock source of + * the LCD. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_rcc_enablelse(void); + +/**************************************************************************** + * Name: stm32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_enablelsi(void); + +/**************************************************************************** + * Name: stm32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_disablelsi(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_RRC_H */ diff --git a/arch/arm/src/stm32/stm32_rng.c b/arch/arm/src/stm32/stm32_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..5726f43ef9c83dd3b0e10dd886e92ae40518e369 --- /dev/null +++ b/arch/arm/src/stm32/stm32_rng.c @@ -0,0 +1,265 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rng.c + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/stm32_rng.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_rnginitialize(void); +static int stm32_interrupt(int irq, void *context); +static void stm32_enable(void); +static void stm32_disable(void); +static ssize_t stm32_read(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rng_dev_s +{ + sem_t rd_devsem; /* Threads can only exclusively access the RNG */ + sem_t rd_readsem; /* To block until the buffer is filled */ + char *rd_buf; + size_t rd_buflen; + uint32_t rd_lastval; + bool rd_first; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rng_dev_s g_rngdev; + +static const struct file_operations g_rngops = +{ + 0, /* open */ + 0, /* close */ + stm32_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +static int stm32_rnginitialize() +{ + uint32_t regval; + + vdbg("Initializing RNG\n"); + + memset(&g_rngdev, 0, sizeof(struct rng_dev_s)); + + sem_init(&g_rngdev.rd_devsem, 0, 1); + + if (irq_attach(STM32_IRQ_RNG, stm32_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + vdbg("Could not attach IRQ.\n"); + + return -EAGAIN; + } + + /* Enable interrupts */ + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_IE; + putreg32(regval, STM32_RNG_CR); + + up_enable_irq(STM32_IRQ_RNG); + + return OK; +} + +static void stm32_enable() +{ + uint32_t regval; + + g_rngdev.rd_first = true; + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +static void stm32_disable() +{ + uint32_t regval; + regval = getreg32(STM32_RNG_CR); + regval &= ~RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +static int stm32_interrupt(int irq, void *context) +{ + uint32_t rngsr; + uint32_t data; + + rngsr = getreg32(STM32_RNG_SR); + + if ((rngsr & (RNG_SR_SEIS | RNG_SR_CEIS)) /* Check for error bits */ + || !(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + { + /* This random value is not valid, we will try again. */ + + return OK; + } + + data = getreg32(STM32_RNG_DR); + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting the + * RNGEN bit should not be used, but saved for comparison with the next + * generated random number. Each subsequent generated random number has to be + * compared with the previously generated number. The test fails if any two + * compared numbers are equal (continuous random number generator test). + */ + + if (g_rngdev.rd_first) + { + g_rngdev.rd_first = false; + g_rngdev.rd_lastval = data; + return OK; + } + + if (g_rngdev.rd_lastval == data) + { + /* Two subsequent same numbers, we will try again. */ + + return OK; + } + + /* If we get here, the random number is valid. */ + + g_rngdev.rd_lastval = data; + + if (g_rngdev.rd_buflen >= 4) + { + g_rngdev.rd_buflen -= 4; + *(uint32_t *)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; + } + else + { + while (g_rngdev.rd_buflen > 0) + { + g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; + data >>= 8; + } + } + + if (g_rngdev.rd_buflen == 0) + { + /* Buffer filled, stop further interrupts. */ + + stm32_disable(); + sem_post(&g_rngdev.rd_readsem); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_read + ****************************************************************************/ + +static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen) +{ + if (sem_wait(&g_rngdev.rd_devsem) != OK) + { + return -errno; + } + else + { + /* We've got the semaphore. */ + + /* Initialize semaphore with 0 for blocking until the buffer is filled from + * interrupts. + */ + + sem_init(&g_rngdev.rd_readsem, 0, 1); + + g_rngdev.rd_buflen = buflen; + g_rngdev.rd_buf = buffer; + + /* Enable RNG with interrupts */ + + stm32_enable(); + + /* Wait until the buffer is filled */ + + sem_wait(&g_rngdev.rd_readsem); + + /* Free RNG for next use */ + + sem_post(&g_rngdev.rd_devsem); + + return buflen; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_rnginitialize() +{ + stm32_rnginitialize(); + register_driver("/dev/random", &g_rngops, 0444, NULL); +} diff --git a/arch/arm/src/stm32/stm32_rtc.c b/arch/arm/src/stm32/stm32_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..0080b78cd24e869bce115ee4ddb3e590c5d7d989 --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtc.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rtc.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* This file is only a thin shell that includes the correct RTC implementation + * for the selected STM32 family. The correct file cannot be selected by + * the make system because it needs the intelligence that only exists in + * chip.h that can associate an STM32 part number with an STM32 family. + */ + +/* The STM32 F1 has a simple battery-backed counter for its RTC and has a + * separate block for the BKP registers. + */ + +#if defined(CONFIG_STM32_STM32F10XX) +# include "stm32_rtcounter.c" + +/* The other families use a more traditional Realtime Clock/Calendar (RTCC) with + * broken-out data/time in BCD format. The backup registers are integrated into + * the RTCC in these families. + */ + +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) +# include "stm32_rtcc.c" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "stm32f40xxx_rtcc.c" +#endif diff --git a/arch/arm/src/stm32/stm32_rtc.h b/arch/arm/src/stm32/stm32_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..731cc2d3b8410b33b1bb67ccf664139535696456 --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtc.h @@ -0,0 +1,184 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rtc.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Uros Platise (Original for the F1) + * Gregory Nutt (On-going support and development) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_RTC_H +#define __ARCH_ARM_SRC_STM32_STM32_RTC_H + +#include + +#include "chip.h" + +/* The STM32 F1 has a simple battery-backed counter for its RTC and has a separate + * block for the BKP registers. + */ + +#if defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32_rtc.h" +# include "chip/stm32_bkp.h" + +/* The other families use a more traditional Realtime Clock/Calendar (RTCC) with + * broken-out data/time in BCD format. The backup registers are integrated into + * the RTCC in these families. + */ + +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32_rtcc.h" +#endif + +/* Alarm function differs from part to part */ + +#ifdef CONFIG_STM32_STM32F40XX +# include "stm32f40xxx_alarm.h" +#else +# include "stm32_alarm.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_RTC_PRESCALER_SECOND 32767 /* Default prescaler to get a second base */ +#define STM32_RTC_PRESCALER_MIN 1 /* Maximum speed of 16384 Hz */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS + * during initialization to set up the system time when CONFIG_RTC and + * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. + * Thatsub-second accuracy is returned through 'nsec'. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec); +#endif + +/**************************************************************************** + * Name: stm32_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide + * this function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DATETIME +struct tm; +int stm32_rtc_setdatetime(FAR const struct tm *tp); +#endif + +/**************************************************************************** + * Name: stm32_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32. General usage: + * + * #include + * #include "stm32_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DRIVER +struct rtc_lowerhalf_s; +FAR struct rtc_lowerhalf_s *stm32_rtc_lowerhalf(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_RTC_H */ diff --git a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c new file mode 100644 index 0000000000000000000000000000000000000000..20275ee92169f720a5b4e554940f9f1e0586be3c --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c @@ -0,0 +1,697 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rtc_lowerhalf.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* REVISIT: This driver is *not* thread-safe! */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "stm32_rtc.h" + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_STM32_STM32F40XX +# define STM32_NALARMS 2 +#else +# define STM32_NALARMS 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct stm32_cbinfo_s +{ + volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */ + volatile FAR void *priv; /* Private argurment to accompany callback */ +#ifdef CONFIG_STM32_STM32F40XX + uint8_t id; /* Identifies the alarm */ +#endif +}; +#endif + +/* This is the private type for the RTC state. It must be cast compatible + * with struct rtc_lowerhalf_s. + */ + +struct stm32_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half + * operations vtable (which may lie in FLASH or ROM) + */ + + FAR const struct rtc_ops_s *ops; + + /* Data following is private to this driver and not visible outside of + * this file. + */ + +#ifdef CONFIG_RTC_ALARM + /* Alarm callback information */ + + struct stm32_cbinfo_s cbinfo[STM32_NALARMS]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Prototypes for static methods in struct rtc_ops_s */ + +static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime); +static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime); + +#ifdef CONFIG_RTC_ALARM +static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo); +static int stm32_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo); +static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, + int alarmid); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* STM32 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = stm32_rdtime, + .settime = stm32_settime, +#ifdef CONFIG_RTC_ALARM + .setalarm = stm32_setalarm, + .setrelative = stm32_setrelative, + .cancelalarm = stm32_cancelalarm, +#endif +#ifdef CONFIG_RTC_IOCTL + .ioctl = NULL, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + .destroy = NULL, +#endif +}; + +/* STM32 RTC device state */ + +static struct stm32_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_alarm_callback + * + * Description: + * This is the function that is called from the RTC driver when the alarm + * goes off. It just invokes the upper half drivers callback. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +#ifdef CONFIG_STM32_STM32F40XX +static void stm32_alarm_callback(FAR void *arg, unsigned int alarmid) +{ + FAR struct stm32_lowerhalf_s *lower; + FAR struct stm32_cbinfo_s *cbinfo; + rtc_alarm_callback_t cb; + FAR void *priv; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB); + + lower = (struct stm32_lowerhalf_s *)arg; + cbinfo = &lower->cbinfo[alarmid]; + + /* Sample and clear the callback information to minimize the window in + * time in which race conditions can occur. + */ + + cb = (rtc_alarm_callback_t)cbinfo->cb; + priv = (FAR void *)cbinfo->priv; + + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Perform the callback */ + + if (cb != NULL) + { + cb(priv, alarmid); + } +} + +#else +static void stm32_alarm_callback(void) +{ + FAR struct stm32_cbinfo_s *cbinfo = &g_rtc_lowerhalf.cbinfo[0]; + + /* Sample and clear the callback information to minimize the window in + * time in which race conditions can occur. + */ + + rtc_alarm_callback_t cb = (rtc_alarm_callback_t)cbinfo->cb; + FAR void *arg = (FAR void *)cbinfo->priv; + + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Perform the callback */ + + if (cb != NULL) + { + cb(arg, 0); + } +} + +#endif /* CONFIG_STM32_STM32F40XX */ +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: stm32_rdtime + * + * Description: + * Implements the rdtime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The location in which to return the current RTC time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime) +{ +#if defined(CONFIG_RTC_DATETIME) + /* This operation depends on the fact that struct rtc_time is cast + * compatible with struct tm. + */ + + return up_rtc_getdatetime((FAR struct tm *)rtctime); + +#elif defined(CONFIG_RTC_HIRES) + FAR struct timespec ts; + int ret; + + /* Get the higher resolution time */ + + ret = up_rtc_gettime(&ts); + if (ret < 0) + { + goto errout_with_errno; + } + + /* Convert the one second epoch time to a struct tm. This operation + * depends on the fact that struct rtc_time and struct tm are cast + * compatible. + */ + + if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime)) + { + goto errout_with_errno; + } + + return OK; + +errout_with_errno: + ret = get_errno(); + DEBUGASSERT(ret > 0); + return -ret; + +#else + time_t timer; + + /* The resolution of time is only 1 second */ + + timer = up_rtc_time(); + + /* Convert the one second epoch time to a struct tm */ + + if (!gmtime_r(&timer, (FAR struct tm *)rtctime)) + { + int errcode = get_errno(); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + return OK; +#endif +} + +/**************************************************************************** + * Name: stm32_settime + * + * Description: + * Implements the settime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The new time to set + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime) +{ +#ifdef CONFIG_RTC_DATETIME + /* This operation depends on the fact that struct rtc_time is cast + * compatible with struct tm. + */ + + return stm32_rtc_setdatetime((FAR const struct tm *)rtctime); + +#else + struct timespec ts; + + /* Convert the struct rtc_time to a time_t. Here we assume that struct + * rtc_time is cast compatible with struct tm. + */ + + ts.tv_sec = mktime((FAR struct tm *)rtctime); + ts.tv_nsec = 0; + + /* Now set the time (to one second accuracy) */ + + return up_rtc_settime(&ts); +#endif +} + +/**************************************************************************** + * Name: stm32_setalarm + * + * Description: + * Set a new alarm. This function implements the setalarm() method of the + * RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo) +{ +#ifdef CONFIG_STM32_STM32F40XX + FAR struct stm32_lowerhalf_s *priv; + FAR struct stm32_cbinfo_s *cbinfo; + struct alm_setalarm_s lowerinfo; + int ret = -EINVAL; + + /* ID0-> Alarm A; ID1 -> Alarm B */ + + DEBUGASSERT(lower != NULL && alarminfo != NULL); + DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB); + priv = (FAR struct stm32_lowerhalf_s *)lower; + + if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB) + { + /* Remember the callback information */ + + cbinfo = &priv->cbinfo[alarminfo->id]; + cbinfo->cb = alarminfo->cb; + cbinfo->priv = alarminfo->priv; + cbinfo->id = alarminfo->id; + + /* Set the alarm */ + + lowerinfo.as_id = alarminfo->id; + lowerinfo.as_cb = stm32_alarm_callback; + lowerinfo.as_arg = priv; + memcpy(&lowerinfo.as_time, &alarminfo->time, sizeof(struct tm)); + + /* And set the alarm */ + + ret = stm32_rtc_setalarm(&lowerinfo); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + } + + return ret; + +#else + FAR struct stm32_lowerhalf_s *priv; + FAR struct stm32_cbinfo_s *cbinfo; + int ret = -EINVAL; + + DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0); + priv = (FAR struct stm32_lowerhalf_s *)lower; + + if (alarminfo->id == 0) + { + struct timespec ts; + + /* Convert the RTC time to a timespec (1 second accuracy) */ + + ts.tv_sec = mktime((FAR struct tm *)&alarminfo->time); + ts.tv_nsec = 0; + + /* Remember the callback information */ + + cbinfo = &priv->cbinfo[0]; + cbinfo->cb = alarminfo->cb; + cbinfo->priv = alarminfo->priv; + + /* And set the alarm */ + + ret = stm32_rtc_setalarm(&ts, stm32_alarm_callback); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + } + + return ret; +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_setrelative + * + * Description: + * Set a new alarm relative to the current time. This function implements + * the setrelative() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int stm32_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo) +{ +#ifdef CONFIG_STM32_STM32F40XX + struct lower_setalarm_s setalarm; + struct tm time; + time_t seconds; + int ret = -EINVAL; + + ASSERT(lower != NULL && alarminfo != NULL); + DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB); + + if ((alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB) && + alarminfo->reltime > 0) + { + /* Disable pre-emption while we do this so that we don't have to worry + * about being suspended and working on an old time. + */ + + sched_lock(); + + /* Get the current time in broken out format */ + + ret = up_rtc_getdatetime(&time); + if (ret >= 0) + { + /* Convert to seconds since the epoch */ + + seconds = mktime(&time); + + /* Add the seconds offset. Add one to the number of seconds + * because we are unsure of the phase of the timer. + */ + + seconds += (alarminfo->reltime + 1); + + /* And convert the time back to broken out format */ + + (void)gmtime_r(&seconds, (FAR struct tm *)&setalarm.time); + + /* The set the alarm using this absolute time */ + + setalarm.id = alarminfo->id; + setalarm.cb = alarminfo->cb; + setalarm.priv = alarminfo->priv; + + ret = stm32_setalarm(lower, &setalarm); + } + + sched_unlock(); + } + + return ret; + +#else + FAR struct stm32_lowerhalf_s *priv; + FAR struct stm32_cbinfo_s *cbinfo; +#if defined(CONFIG_RTC_DATETIME) + struct tm time; +#endif + FAR struct timespec ts; + int ret = -EINVAL; + + DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0); + priv = (FAR struct stm32_lowerhalf_s *)lower; + + if (alarminfo->id == 0 && alarminfo->reltime > 0) + { + /* Disable pre-emption while we do this so that we don't have to worry + * about being suspended and working on an old time. + */ + + sched_lock(); + + /* Get the current time in seconds */ + +#if defined(CONFIG_RTC_DATETIME) + /* Get the broken out time and convert to seconds */ + + ret = up_rtc_getdatetime(&time); + if (ret < 0) + { + sched_unlock(); + return ret; + } + + ts.tv_sec = mktime(&time); + ts.tv_nsec = 0; + +#elif defined(CONFIG_RTC_HIRES) + /* Get the higher resolution time */ + + ret = up_rtc_gettime(&ts); + if (ret < 0) + { + sched_unlock(); + return ret; + } +#else + /* The resolution of time is only 1 second */ + + ts.tv_sec = up_rtc_time(); + ts.tv_nsec = 0; +#endif + + /* Add the seconds offset. Add one to the number of seconds because + * we are unsure of the phase of the timer. + */ + + ts.tv_sec += (alarminfo->reltime + 1); + + /* Remember the callback information */ + + cbinfo = &priv->cbinfo[0]; + cbinfo->cb = alarminfo->cb; + cbinfo->priv = alarminfo->priv; + + /* And set the alarm */ + + ret = stm32_rtc_setalarm(&ts, stm32_alarm_callback); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + + sched_unlock(); + } + + return ret; +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_cancelalarm + * + * Description: + * Cancel the current alarm. This function implements the cancelalarm() + * method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid) +{ +#ifdef CONFIG_STM32_STM32F40XX + FAR struct stm32_lowerhalf_s *priv; + FAR struct stm32_cbinfo_s *cbinfo; + int ret = -EINVAL; + + DEBUGASSERT(lower != NULL); + DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB); + priv = (FAR struct stm32_lowerhalf_s *)lower; + + /* ID0-> Alarm A; ID1 -> Alarm B */ + + if (alarmid == RTC_ALARMA || alarmid == RTC_ALARMB) + { + /* Nullify callback information to reduce window for race conditions */ + + cbinfo = &priv->cbinfo[alarmid]; + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Then cancel the alarm */ + + ret = stm32_rtc_cancelalarm((enum alm_id_e)alarmid); + } + + return ret; + +#else + FAR struct stm32_lowerhalf_s *priv; + FAR struct stm32_cbinfo_s *cbinfo; + + DEBUGASSERT(lower != NULL); + DEBUGASSERT(alarmid == 0); + priv = (FAR struct stm32_lowerhalf_s *)lower; + + /* Nullify callback information to reduce window for race conditions */ + + cbinfo = &priv->cbinfo[0]; + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Then cancel the alarm */ + + return stm32_rtc_cancelalarm(); +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32. General usage: + * + * #include + * #include "stm32_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +FAR struct rtc_lowerhalf_s *stm32_rtc_lowerhalf(void) +{ + return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf; +} + +#endif /* CONFIG_RTC_DRIVER */ diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c new file mode 100644 index 0000000000000000000000000000000000000000..7d403ba50415f10e1c1081030fabb645b5558372 --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -0,0 +1,1119 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_rtcc.c + * + * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" +#include "stm32_pwr.h" +#include "stm32_exti.h" +#include "stm32_rtc.h" + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error "CONFIG_RTC_DATETIME must be set to use this driver" +#endif + +#ifdef CONFIG_RTC_HIRES +# error "CONFIG_RTC_HIRES must NOT be set with this driver" +#endif + +#ifndef CONFIG_STM32_PWR +# error "CONFIG_STM32_PWR must selected to use this driver" +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +#ifdef CONFIG_STM32_STM32L15XX +# if defined(CONFIG_RTC_HSECLOCK) +# error "RTC with HSE clock not yet implemented for STM32L15XXX" +# elif defined(CONFIG_RTC_LSICLOCK) +# error "RTC with LSI clock not yet implemented for STM32L15XXX" +# endif +#endif + +#if !defined(CONFIG_RTC_MAGIC) +# define CONFIG_RTC_MAGIC (0xfacefeee) +#endif + +#if !defined(CONFIG_RTC_MAGIC_REG) +# define CONFIG_RTC_MAGIC_REG (0) +#endif + +/* Constants ************************************************************************/ + +#define SYNCHRO_TIMEOUT (0x00020000) +#define INITMODE_TIMEOUT (0x00010000) +#define RTC_MAGIC CONFIG_RTC_MAGIC +#define RTC_MAGIC_REG STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG) + +/* Proxy definitions to make the same code work for all the STM32 series ************/ + +#if defined(CONFIG_STM32_STM32L15XX) +# define STM32_RCC_XXX STM32_RCC_CSR +# define RCC_XXX_YYYRST RCC_CSR_RTCRST +# define RCC_XXX_RTCEN RCC_CSR_RTCEN +# define RCC_XXX_RTCSEL_MASK RCC_CSR_RTCSEL_MASK +# define RCC_XXX_RTCSEL_LSE RCC_CSR_RTCSEL_LSE +# define RCC_XXX_RTCSEL_LSI RCC_CSR_RTCSEL_LSI +# define RCC_XXX_RTCSEL_HSE RCC_CSR_RTCSEL_HSE +#else +# define STM32_RCC_XXX STM32_RCC_BDCR +# define RCC_XXX_YYYRST RCC_BDCR_BDRST +# define RCC_XXX_RTCEN RCC_BDCR_RTCEN +# define RCC_XXX_RTCSEL_MASK RCC_BDCR_RTCSEL_MASK +# define RCC_XXX_RTCSEL_LSE RCC_BDCR_RTCSEL_LSE +# define RCC_XXX_RTCSEL_LSI RCC_BDCR_RTCSEL_LSI +# define RCC_XXX_RTCSEL_HSE RCC_BDCR_RTCSEL_HSE +#endif + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" TR: %08x\n", getreg32(STM32_RTC_TR)); + rtclldbg(" DR: %08x\n", getreg32(STM32_RTC_DR)); + rtclldbg(" CR: %08x\n", getreg32(STM32_RTC_CR)); + rtclldbg(" ISR: %08x\n", getreg32(STM32_RTC_ISR)); + rtclldbg(" PRER: %08x\n", getreg32(STM32_RTC_PRER)); + rtclldbg(" WUTR: %08x\n", getreg32(STM32_RTC_WUTR)); +#ifndef CONFIG_STM32_STM32F30XX + rtclldbg(" CALIBR: %08x\n", getreg32(STM32_RTC_CALIBR)); +#endif + rtclldbg(" ALRMAR: %08x\n", getreg32(STM32_RTC_ALRMAR)); + rtclldbg(" ALRMBR: %08x\n", getreg32(STM32_RTC_ALRMBR)); + rtclldbg(" SHIFTR: %08x\n", getreg32(STM32_RTC_SHIFTR)); + rtclldbg(" TSTR: %08x\n", getreg32(STM32_RTC_TSTR)); + rtclldbg(" TSDR: %08x\n", getreg32(STM32_RTC_TSDR)); + rtclldbg(" TSSSR: %08x\n", getreg32(STM32_RTC_TSSSR)); + rtclldbg(" CALR: %08x\n", getreg32(STM32_RTC_CALR)); + rtclldbg(" TAFCR: %08x\n", getreg32(STM32_RTC_TAFCR)); + rtclldbg("ALRMASSR: %08x\n", getreg32(STM32_RTC_ALRMASSR)); + rtclldbg("ALRMBSSR: %08x\n", getreg32(STM32_RTC_ALRMBSSR)); + rtclldbg("MAGICREG: %08x\n", getreg32(RTC_MAGIC_REG)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_wprunlock + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void rtc_wprunlock(void) +{ + /* Enable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* The following steps are required to unlock the write protection on all the + * RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR). + * + * 1. Write 0xCA into the RTC_WPR register. + * 2. Write 0x53 into the RTC_WPR register. + * + * Writing a wrong key re-activates the write protection. + */ + + putreg32(0xca, STM32_RTC_WPR); + putreg32(0x53, STM32_RTC_WPR); +} + +/************************************************************************************ + * Name: rtc_wprlock + * + * Description: + * Enable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void rtc_wprlock(void) +{ + /* Writing any wrong key re-activates the write protection. */ + + putreg32(0xff, STM32_RTC_WPR); + + /* Disable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(false); +} + +/************************************************************************************ + * Name: rtc_synchwait + * + * Description: + * Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_synchwait(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Clear Registers synchronization flag (RSF) */ + + regval = getreg32(STM32_RTC_ISR); + regval &= ~RTC_ISR_RSF; + putreg32(regval, STM32_RTC_ISR); + + /* Now wait the registers to become synchronised */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_RSF) != 0) + { + /* Synchronized */ + + ret = OK; + break; + } + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + return ret; +} + +/************************************************************************************ + * Name: rtc_enterinit + * + * Description: + * Enter RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_enterinit(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Check if the Initialization mode is already set */ + + regval = getreg32(STM32_RTC_ISR); + + ret = OK; + if ((regval & RTC_ISR_INITF) == 0) + { + /* Set the Initialization mode */ + + putreg32(RTC_ISR_INIT, STM32_RTC_ISR); + + /* Wait until the RTC is in the INIT state (or a timeout occurs) */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_INITF) != 0) + { + ret = OK; + break; + } + } + } + + return ret; +} + +/************************************************************************************ + * Name: rtc_exitinit + * + * Description: + * Exit RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_exitinit(void) +{ + uint32_t regval; + + regval = getreg32(STM32_RTC_ISR); + regval &= ~(RTC_ISR_INIT); + putreg32(regval, STM32_RTC_ISR); +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint32_t rtc_bin2bcd(int value) +{ + uint32_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint32_t value) +{ + uint32_t tens = (value >> 4) * 10; + return (int)(tens + (value & 0x0f)); +} + +/************************************************************************************ + * Name: rtc_setup + * + * Description: + * Performs first time configuration of the RTC. A special value written into + * back-up register 0 will prevent this function from being called on sub-sequent + * resets or power up. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_setup(void) +{ + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the 24 hour format by clearing the FMT bit in the RTC + * control register + */ + + regval = getreg32(STM32_RTC_CR); + regval &= ~RTC_CR_FMT; + putreg32(regval, STM32_RTC_CR); + + /* Configure RTC pre-scaler with the required values */ + +#ifdef CONFIG_RTC_HSECLOCK + /* For a 1 MHz clock this yields 0.9999360041 Hz on the second + * timer - which is pretty close. + */ + + putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32_RTC_PRER); +#else + /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ + + putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32_RTC_PRER); +#endif + + /* Exit RTC initialization mode */ + + rtc_exitinit(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + + return ret; +} + +/************************************************************************************ + * Name: rtc_resume + * + * Description: + * Called when the RTC was already initialized on a previous power cycle. This + * just brings the RTC back into full operation. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_resume(void) +{ +#ifdef CONFIG_RTC_ALARM + uint32_t regval; + + /* Clear the RTC alarm flags */ + + regval = getreg32(STM32_RTC_ISR); + regval &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF); + putreg32(regval, STM32_RTC_ISR); + + /* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */ + + putreg32((1 << 17), STM32_EXTI_PR); +#endif +} + +/************************************************************************************ + * Name: rtc_wkup_interrupt + * + * Description: + * RTC WKUP interrupt service routine through the EXTI line + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_wkup_interrupt(int irq, void *context) +{ +#warning "Missing logic" + return OK; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + uint32_t regval; + uint32_t tr_bkp; + uint32_t dr_bkp; + int ret; + int maxretry = 10; + int nretry = 0; + + /* Clocking for the PWR block must be provided. However, this is done + * unconditionally in stm32f40xxx_rcc.c on power up. This done unconditionally + * because the PWR block is also needed to set the internal voltage regulator for + * maximum performance. + */ + + rtc_dumpregs("On reset"); + + /* Select the clock source */ + /* Save the token before losing it when resetting */ + + regval = getreg32(RTC_MAGIC_REG); + + (void)stm32_pwr_enablebkp(true); + + if (regval != RTC_MAGIC) + { + /* We might be changing RTCSEL - to ensure such changes work, we must reset the + * backup domain (having backed up the RTC_MAGIC token) + */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_YYYRST); + modifyreg32(STM32_RCC_XXX, RCC_XXX_YYYRST, 0); + + /* Some boards do not have the external 32khz oscillator installed, for those + * boards we must fallback to the crummy internal RC clock or the external high + * rate clock + */ + +#ifdef CONFIG_RTC_HSECLOCK + /* Use the HSE clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_HSE); + +#elif defined(CONFIG_RTC_LSICLOCK) + /* Use the LSI clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSI); + +#elif defined(CONFIG_RTC_LSECLOCK) + /* Use the LSE clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSE); + +#endif + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_RTCEN); + } + else /* The RTC is already in use: check if the clock source is changed */ + { +#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_RTC_LSICLOCK) || \ + defined(CONFIG_RTC_LSECLOCK) + + uint32_t clksrc = getreg32(STM32_RCC_XXX); + +#if defined(CONFIG_RTC_HSECLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_HSE) +#elif defined(CONFIG_RTC_LSICLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_LSI) +#elif defined(CONFIG_RTC_LSECLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_LSE) +#endif +#endif + { + tr_bkp = getreg32(STM32_RTC_TR); + dr_bkp = getreg32(STM32_RTC_DR); + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_YYYRST); + modifyreg32(STM32_RCC_XXX, RCC_XXX_YYYRST, 0); + +#if defined(CONFIG_RTC_HSECLOCK) + /* Change to the new clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_HSE); + +#elif defined(CONFIG_RTC_LSICLOCK) + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSI); + +#elif defined(CONFIG_RTC_LSECLOCK) + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSE); +#endif + + putreg32(tr_bkp, STM32_RTC_TR); + putreg32(dr_bkp, STM32_RTC_DR); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_RTCEN); + } + } + + (void)stm32_pwr_enablebkp(false); + + /* Loop, attempting to initialize/resume the RTC. This loop is necessary + * because it seems that occasionally it takes longer to initialize the RTC + * (the actual failure is in rtc_synchwait()). + */ + + do + { + /* Wait for the RTC Time and Date registers to be synchronized with RTC APB + * clock. + */ + + ret = rtc_synchwait(); + + /* Check that rtc_syncwait() returned successfully */ + + switch (ret) + { + case OK: + { + rtclldbg("rtc_syncwait() okay\n"); + break; + } + + default: + { + rtclldbg("rtc_syncwait() failed (%d)\n", ret); + break; + } + } + } + while (ret != OK && ++nretry < maxretry); + + /* Check if the one-time initialization of the RTC has already been + * performed. We can determine this by checking if the magic number + * has been writing to to back-up date register DR0. + */ + + if (regval != RTC_MAGIC) + { + rtclldbg("Do setup\n"); + + /* Perform the one-time setup of the LSE clocking to the RTC */ + + ret = rtc_setup(); + + /* Enable write access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + } + else + { + rtclldbg("Do resume\n"); + + /* RTC already set-up, just resume normal operation */ + + rtc_resume(); + rtc_dumpregs("Did resume"); + } + + /* Disable write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(false); + + if (ret != OK && nretry > 0) + { + rtclldbg("setup/resume ran %d times and failed with %d\n", + nretry, ret); + return -ETIMEDOUT; + } + + /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are + * connected to the EXTI controller. To enable the RTC Alarm interrupt, the + * following sequence is required: + * + * 1. Configure and enable the EXTI Line 17 in interrupt mode and select the + * rising edge sensitivity. + * 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC. + * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B). + */ + +#ifdef CONFIG_RTC_ALARM +# warning "Missing EXTI setup logic" + + /* Then attach the ALARM interrupt handler */ + + irq_attach(STM32_IRQ_RTC_WKUP, rtc_interrupt); + up_enable_irq(STM32_IRQ_RTC_WKUP); +#endif + + g_rtc_enabled = true; + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: stm32_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is returned through 'nsec'. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec) +#else +int up_rtc_getdatetime(FAR struct tm *tp) +#endif +{ +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + uint32_t ssr; +#endif + uint32_t dr; + uint32_t tr; + uint32_t tmp; + + /* Sample the data time registers. There is a race condition here... If we sample + * the time just before midnight on December 31, the date could be wrong because + * the day rolled over while were sampling. + */ + + do + { + dr = getreg32(STM32_RTC_DR); + tr = getreg32(STM32_RTC_TR); +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + ssr = getreg32(STM32_RTC_SSR); +#endif + tmp = getreg32(STM32_RTC_DR); + } + while (tmp != dr); + + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time to fields in struct tm format. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tmp = (tr & (RTC_TR_SU_MASK | RTC_TR_ST_MASK)) >> RTC_TR_SU_SHIFT; + tp->tm_sec = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_MNU_MASK | RTC_TR_MNT_MASK)) >> RTC_TR_MNU_SHIFT; + tp->tm_min = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_HU_MASK | RTC_TR_HT_MASK)) >> RTC_TR_HU_SHIFT; + tp->tm_hour = rtc_bcd2bin(tmp); + + /* Now convert the RTC date to fields in struct tm format: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + tmp = (dr & (RTC_DR_DU_MASK | RTC_DR_DT_MASK)) >> RTC_DR_DU_SHIFT; + tp->tm_mday = rtc_bcd2bin(tmp); + + tmp = (dr & (RTC_DR_MU_MASK | RTC_DR_MT)) >> RTC_DR_MU_SHIFT; + tp->tm_mon = rtc_bcd2bin(tmp) - 1; + + tmp = (dr & (RTC_DR_YU_MASK | RTC_DR_YT_MASK)) >> RTC_DR_YU_SHIFT; + tp->tm_year = rtc_bcd2bin(tmp) + 100; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + tmp = (dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT; + tp->tm_wday = tmp % 7; + tp->tm_yday = tp->tm_mday + clock_daysbeforemonth(tp->tm_mon, clock_isleapyear(tp->tm_year + 1900)); + tp->tm_isdst = 0 +#endif + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + /* Return RTC sub-seconds if no configured and if a non-NULL value + * of nsec has been provided to receive the sub-second value. + */ + + if (nsec) + { + uint32_t prediv_s; + uint32_t usecs; + + prediv_s = getreg32(STM32_RTC_PRER) & RTC_PRER_PREDIV_S_MASK; + prediv_s >>= RTC_PRER_PREDIV_S_SHIFT; + + ssr &= RTC_SSR_MASK; + + /* Maximum prediv_s is 0x7fff, thus we can multiply by 100000 and + * still fit 32-bit unsigned integer. + */ + + usecs = (((prediv_s - ssr) * 100000) / (prediv_s + 1)) * 10; + *nsec = usecs * 1000; + } +#endif /* CONFIG_STM32_HAVE_RTC_SUBSECONDS */ + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int up_rtc_getdatetime(FAR struct tm *tp) +{ + return stm32_rtc_getdatetime_with_subseconds(tp, NULL); +} +#endif + +/************************************************************************************ + * Name: stm32_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this + * function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int stm32_rtc_setdatetime(FAR const struct tm *tp) +{ + uint32_t tr; + uint32_t dr; + int ret; + + rtc_dumptime(tp, "Setting time"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tr = (rtc_bin2bcd(tp->tm_sec) << RTC_TR_SU_SHIFT) | + (rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) | + (rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT); + tr &= ~RTC_TR_RESERVED_BITS; + + /* Now convert the fields in struct tm format to the RTC date register fields: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) | + ((rtc_bin2bcd(tp->tm_mon + 1)) << RTC_DR_MU_SHIFT) | +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + ((tp->tm_wday == 0 ? 7 : (tp->tm_wday & 7)) << RTC_DR_WDU_SHIFT) | +#endif + ((rtc_bin2bcd(tp->tm_year - 100)) << RTC_DR_YU_SHIFT); + + dr &= ~RTC_DR_RESERVED_BITS; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the RTC TR and DR registers */ + + putreg32(tr, STM32_RTC_TR); + putreg32(dr, STM32_RTC_DR); + + /* Exit Initialization mode and wait for the RTC Time and Date + * registers to be synchronized with RTC APB clock. + */ + + rtc_exitinit(); + ret = rtc_synchwait(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + rtc_dumpregs("New time setting"); + return ret; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + + /* Break out the time values (not that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + return stm32_rtc_setdatetime(&newtime); +} + +/************************************************************************************ + * Name: stm32_rtc_setalarm + * + * Description: + * Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B). + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Break out the time values */ +#warning "Missing logic" + + /* The set the alarm */ +#warning "Missing logic" + + ret = OK; + } + + return ret; +} +#endif + +#endif /* CONFIG_RTC */ diff --git a/arch/arm/src/stm32/stm32_rtcounter.c b/arch/arm/src/stm32/stm32_rtcounter.c new file mode 100644 index 0000000000000000000000000000000000000000..8156de0a6041fdc32623c7d0347a584a8dc3acd7 --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtcounter.c @@ -0,0 +1,730 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_rtcounter.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With extensions, modifications by: + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregroy Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* The STM32 RTC Driver offers standard precision of 1 Hz or High Resolution + * operating at rate up to 16384 Hz. It provides UTC time and alarm interface + * with external output pin (for wake-up). + * + * RTC is based on hardware RTC module which is located in a separate power + * domain. The 32-bit counter is extended by 16-bit registers in BKP domain + * STM32_BKP_DR1 to provide system equiv. function to the: time_t time(time_t *). + * + * Notation: + * - clock refers to 32-bit hardware counter + * - time is a combination of clock and upper bits stored in backuped domain + * with unit of 1 [s] + * + * TODO: Error Handling in case LSE fails during start-up or during operation. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" + +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_rtc.h" +#include "stm32_waste.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* In hi-res mode, the RTC operates at 16384Hz. Overflow interrupts are handled + * when the 32-bit RTC counter overflows every 3 days and 43 minutes. A BKP register + * is incremented on each overflow interrupt creating, effectively, a 48-bit RTC + * counter. + * + * In the lo-res mode, the RTC operates at 1Hz. Overflow interrupts are not handled + * (because the next overflow is not expected until the year 2106. + * + * WARNING: Overflow interrupts are lost whenever the STM32 is powered down. The + * overflow interrupt may be lost even if the STM32 is powered down only momentarily. + * Therefor hi-res solution is only useful in systems where the power is always on. + */ + +#ifdef CONFIG_RTC_HIRES +# ifndef CONFIG_RTC_FREQUENCY +# error "CONFIG_RTC_FREQUENCY is required for CONFIG_RTC_HIRES" +# elif CONFIG_RTC_FREQUENCY != 16384 +# error "Only hi-res CONFIG_RTC_FREQUENCY of 16384Hz is supported" +# endif +#else +# ifndef CONFIG_RTC_FREQUENCY +# define CONFIG_RTC_FREQUENCY 1 +# endif +# if CONFIG_RTC_FREQUENCY != 1 +# error "Only lo-res CONFIG_RTC_FREQUENCY of 1Hz is supported" +# endif +#endif + +#ifndef CONFIG_STM32_BKP +# error "CONFIG_STM32_BKP is required for CONFIG_RTC" +#endif + +#ifndef CONFIG_STM32_PWR +# error "CONFIG_STM32_PWR is required for CONFIG_RTC" +#endif + +#ifdef CONFIG_STM32_STM32F10XX +# if defined(CONFIG_RTC_HSECLOCK) +# error "RTC with HSE clock not yet implemented for STM32F10XXX" +# elif defined(CONFIG_RTC_LSICLOCK) +# error "RTC with LSI clock not yet implemented for STM32F10XXX" +# endif +#endif + +/* RTC/BKP Definitions *************************************************************/ +/* STM32_RTC_PRESCALAR_VALUE + * RTC pre-scalar value. The RTC is driven by a 32,768Hz input clock. This input + * value is divided by this value (plus one) to generate the RTC frequency. + * RTC_TIMEMSB_REG + * The BKP module register used to hold the RTC overflow value. Overflows are + * only handled in hi-res mode. + * RTC_CLOCKS_SHIFT + * The shift used to convert the hi-res timer LSB to one second. Not used with + * the lo-res timer. + */ + +#ifdef CONFIG_RTC_HIRES +# define STM32_RTC_PRESCALAR_VALUE STM32_RTC_PRESCALER_MIN +# define RTC_TIMEMSB_REG STM32_BKP_DR1 +# define RTC_CLOCKS_SHIFT 14 +#else +# define STM32_RTC_PRESCALAR_VALUE STM32_RTC_PRESCALER_SECOND +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct rtc_regvals_s +{ + uint16_t cntl; + uint16_t cnth; +#ifdef CONFIG_RTC_HIRES + uint16_t ovf; +#endif +}; + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* Variable determines the state of the LSE oscillator. + * Possible errors: + * - on start-up + * - during operation, reported by LSE interrupt + */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_rtc_beginwr + * + * Description: + * Enter configuration mode + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_rtc_beginwr(void) +{ + /* Previous write is done? */ + + while ((getreg16(STM32_RTC_CRL) & RTC_CRL_RTOFF) == 0) + { + up_waste(); + } + + /* Enter Config mode, Set Value and Exit */ + + modifyreg16(STM32_RTC_CRL, 0, RTC_CRL_CNF); +} + +/************************************************************************************ + * Name: stm32_rtc_endwr + * + * Description: + * Exit configuration mode + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_rtc_endwr(void) +{ + modifyreg16(STM32_RTC_CRL, RTC_CRL_CNF, 0); + + /* Wait for the write to actually reach RTC registers */ + + while ((getreg16(STM32_RTC_CRL) & RTC_CRL_RTOFF) == 0) + { + up_waste(); + } +} + +/************************************************************************************ + * Name: stm32_rtc_wait4rsf + * + * Description: + * Wait for registers to synchronise with RTC module, call after power-up only + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_rtc_wait4rsf(void) +{ + modifyreg16(STM32_RTC_CRL, RTC_CRL_RSF, 0); + while ((getreg16(STM32_RTC_CRL) & RTC_CRL_RSF) == 0) + { + up_waste(); + } +} + +/************************************************************************************ + * Name: stm32_rtc_breakout + * + * Description: + * Set the RTC to the provided time. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_HIRES +static void stm32_rtc_breakout(FAR const struct timespec *tp, + FAR struct rtc_regvals_s *regvals) +{ + uint64_t frac; + uint32_t cnt; + uint16_t ovf; + + /* Break up the time in seconds + milleconds into the correct values for our use */ + + frac = ((uint64_t)tp->tv_nsec * CONFIG_RTC_FREQUENCY) / 1000000000; + cnt = (tp->tv_sec << RTC_CLOCKS_SHIFT) | ((uint32_t)frac & (CONFIG_RTC_FREQUENCY-1)); + ovf = (tp->tv_sec >> (32 - RTC_CLOCKS_SHIFT)); + + /* Then return the broken out time */ + + regvals->cnth = cnt >> 16; + regvals->cntl = cnt & 0xffff; + regvals->ovf = ovf; +} +#else +static inline void stm32_rtc_breakout(FAR const struct timespec *tp, + FAR struct rtc_regvals_s *regvals) +{ + /* The low-res timer is easy... tv_sec holds exactly the value needed by the + * CNTH/CNTL registers. + */ + + regvals->cnth = (uint16_t)((uint32_t)tp->tv_sec >> 16); + regvals->cntl = (uint16_t)((uint32_t)tp->tv_sec & 0xffff); +} +#endif + +/************************************************************************************ + * Name: stm32_rtc_interrupt + * + * Description: + * RTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#if defined(CONFIG_RTC_HIRES) || defined(CONFIG_RTC_ALARM) +static int stm32_rtc_interrupt(int irq, void *context) +{ + uint16_t source = getreg16(STM32_RTC_CRL); + +#ifdef CONFIG_RTC_HIRES + if ((source & RTC_CRL_OWF) != 0) + { + putreg16(getreg16(RTC_TIMEMSB_REG) + 1, RTC_TIMEMSB_REG); + } +#endif + +#ifdef CONFIG_RTC_ALARM + if ((source & RTC_CRL_ALRF) != 0 && g_alarmcb != NULL) + { + /* Alarm callback */ + + g_alarmcb(); + g_alarmcb = NULL; + } +#endif + + /* Clear pending flags, leave RSF high */ + + putreg16(RTC_CRL_RSF, STM32_RTC_CRL); + return 0; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + /* Enable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* Set access to the peripheral, enable the backup domain (BKP) and the lower + * power external 32,768Hz (Low-Speed External, LSE) oscillator. Configure the + * LSE to drive the RTC. + */ + + stm32_rcc_enablelse(); + + /* TODO: Get state from this function, if everything is + * okay and whether it is already enabled (if it was disabled + * reset upper time register) + */ + + g_rtc_enabled = true; + + /* TODO: Possible stall? should we set the timeout period? and return with -1 */ + + stm32_rtc_wait4rsf(); + + /* Configure prescaler, note that these are write-only registers */ + + stm32_rtc_beginwr(); + putreg16(STM32_RTC_PRESCALAR_VALUE >> 16, STM32_RTC_PRLH); + putreg16(STM32_RTC_PRESCALAR_VALUE & 0xffff, STM32_RTC_PRLL); + stm32_rtc_endwr(); + + /* Configure RTC interrupt to catch overflow and alarm interrupts. */ + +#if defined(CONFIG_RTC_HIRES) || defined(CONFIG_RTC_ALARM) + irq_attach(STM32_IRQ_RTC, stm32_rtc_interrupt); + up_enable_irq(STM32_IRQ_RTC); +#endif + + /* Previous write is done? This is required prior writing into CRH */ + + while ((getreg16(STM32_RTC_CRL) & RTC_CRL_RTOFF) == 0) + { + up_waste(); + } + + modifyreg16(STM32_RTC_CRH, 0, RTC_CRH_OWIE); + + /* Alarm Int via EXTI Line */ + + /* STM32_IRQ_RTCALRM 41: RTC alarm through EXTI line interrupt */ + + /* Disable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(false); + + return OK; +} + +/************************************************************************************ + * Name: up_rtc_time + * + * Description: + * Get the current time in seconds. This is similar to the standard time() + * function. This interface is only required if the low-resolution RTC/counter + * hardware implementation selected. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC is set but neither + * CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set. + * + * Input Parameters: + * None + * + * Returned Value: + * The current time in seconds + * + ************************************************************************************/ + +#ifndef CONFIG_RTC_HIRES +time_t up_rtc_time(void) +{ + irqstate_t flags; + uint16_t cnth; + uint16_t cntl; + uint16_t tmp; + + /* The RTC counter is read from two 16-bit registers to form one 32-bit + * value. Because these are non-atomic operations, many things can happen + * between the two reads: This thread could get suspended or interrupted + * or the lower 16-bit counter could rollover between reads. Disabling + * interrupts will prevent suspensions and interruptions: + */ + + flags = enter_critical_section(); + + /* And the following loop will handle any clock rollover events that may + * happen between samples. Most of the time (like 99.9%), the following + * loop will execute only once. In the rare rollover case, it should + * execute no more than 2 times. + */ + + do + { + tmp = getreg16(STM32_RTC_CNTL); + cnth = getreg16(STM32_RTC_CNTH); + cntl = getreg16(STM32_RTC_CNTL); + } + + /* The second sample of CNTL could be less than the first sample of CNTL + * only if rollover occurred. In that case, CNTH may or may not be out + * of sync. The best thing to do is try again until we know that no + * rollover occurred. + */ + + while (cntl < tmp); + leave_critical_section(flags); + + /* Okay.. the samples should be as close together in time as possible and + * we can be assured that no clock rollover occurred between the samples. + * + * Return the time in seconds. + */ + + return (time_t)cnth << 16 | (time_t)cntl; +} +#endif + +/************************************************************************************ + * Name: up_rtc_gettime + * + * Description: + * Get the current time from the high resolution RTC clock/counter. This interface + * is only supported by the high-resolution RTC/counter hardware implementation. + * It is used to replace the system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_HIRES +int up_rtc_gettime(FAR struct timespec *tp) +{ + irqstate_t flags; + uint32_t ls; + uint32_t ms; + uint16_t ovf; + uint16_t cnth; + uint16_t cntl; + uint16_t tmp; + + /* The RTC counter is read from two 16-bit registers to form one 32-bit + * value. Because these are non-atomic operations, many things can happen + * between the two reads: This thread could get suspended or interrupted + * or the lower 16-bit counter could rollover between reads. Disabling + * interrupts will prevent suspensions and interruptions: + */ + + flags = enter_critical_section(); + + /* And the following loop will handle any clock rollover events that may + * happen between samples. Most of the time (like 99.9%), the following + * loop will execute only once. In the rare rollover case, it should + * execute no more than 2 times. + */ + + do + { + tmp = getreg16(STM32_RTC_CNTL); + cnth = getreg16(STM32_RTC_CNTH); + ovf = getreg16(RTC_TIMEMSB_REG); + cntl = getreg16(STM32_RTC_CNTL); + } + + /* The second sample of CNTL could be less than the first sample of CNTL + * only if rollover occurred. In that case, CNTH may or may not be out + * of sync. The best thing to do is try again until we know that no + * rollover occurred. + */ + + while (cntl < tmp); + leave_critical_section(flags); + + /* Okay.. the samples should be as close together in time as possible and + * we can be assured that no clock rollover occurred between the samples. + * + * Create a 32-bit value from the LS and MS 16-bit RTC counter values and + * from the MS and overflow 16-bit counter values. + */ + + ls = (uint32_t)cnth << 16 | (uint32_t)cntl; + ms = (uint32_t)ovf << 16 | (uint32_t)cnth; + + /* Then we can save the time in seconds and fractional seconds. */ + + tp->tv_sec = (ms << (32-RTC_CLOCKS_SHIFT-16)) | (ls >> (RTC_CLOCKS_SHIFT+16)); + tp->tv_nsec = (ls & (CONFIG_RTC_FREQUENCY-1)) * (1000000000/CONFIG_RTC_FREQUENCY); + return OK; +} +#endif + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + struct rtc_regvals_s regvals; + irqstate_t flags; + uint16_t cntl; + + /* Break out the time values */ + + stm32_rtc_breakout(tp, ®vals); + + /* Enable write access to the backup domain */ + + flags = enter_critical_section(); + (void)stm32_pwr_enablebkp(true); + + /* Then write the broken out values to the RTC counter and BKP overflow register + * (hi-res mode only) + */ + + do + { + stm32_rtc_beginwr(); + putreg16(regvals.cnth, STM32_RTC_CNTH); + putreg16(regvals.cntl, STM32_RTC_CNTL); + cntl = getreg16(STM32_RTC_CNTL); + stm32_rtc_endwr(); + } + while (cntl != regvals.cntl); + +#ifdef CONFIG_RTC_HIRES + putreg16(regvals.ovf, RTC_TIMEMSB_REG); +#endif + + (void)stm32_pwr_enablebkp(false); + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: stm32_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + struct rtc_regvals_s regvals; + irqstate_t flags; + uint16_t cr; + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Break out the time values */ + + stm32_rtc_breakout(tp, ®vals); + + /* Enable RTC alarm */ + + cr = getreg16(STM32_RTC_CRH); + cr |= RTC_CRH_ALRIE; + putreg16(cr, STM32_RTC_CRH); + + /* The set the alarm */ + + flags = enter_critical_section(); + stm32_rtc_beginwr(); + putreg16(regvals.cnth, STM32_RTC_ALRH); + putreg16(regvals.cntl, STM32_RTC_ALRL); + stm32_rtc_endwr(); + leave_critical_section(flags); + + ret = OK; + } + + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32_rtc_cancelalarm + * + * Description: + * Cancel a pending alarm alarm + * + * Input Parameters: + * none + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_rtc_cancelalarm(void) +{ + irqstate_t flags; + int ret = -ENODATA; + + if (g_alarmcb != NULL) + { + /* Cancel the global callback function */ + + g_alarmcb = NULL; + + /* Unset the alarm */ + + flags = enter_critical_section(); + stm32_rtc_beginwr(); + putreg16(0xffff, STM32_RTC_ALRH); + putreg16(0xffff, STM32_RTC_ALRL); + stm32_rtc_endwr(); + leave_critical_section(flags); + + ret = OK; + } + + return ret; +} +#endif diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c new file mode 100644 index 0000000000000000000000000000000000000000..b9bea99351fb203f29aae8544a454fcc3434a7fa --- /dev/null +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -0,0 +1,2973 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_sdio.c + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" + +#include "stm32.h" +#include "stm32_dma.h" +#include "stm32_sdio.h" + +#ifdef CONFIG_STM32_SDIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* Required system configuration options: + * + * CONFIG_ARCH_DMA - Enable architecture-specific DMA subsystem + * initialization. Required if CONFIG_SDIO_DMA is enabled. + * CONFIG_STM32_DMA2 - Enable STM32 DMA2 support. Required if + * CONFIG_SDIO_DMA is enabled + * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. + * + * Driver-specific configuration options: + * + * CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking + * APIs to manage concurrent accesses on the SDIO bus. This is not + * needed for the simple case of a single SD card, for example. + * CONFIG_SDIO_DMA - Enable SDIO. This is a marginally optional. For + * most usages, SDIO will cause data overruns if used without DMA. + * NOTE the above system DMA configuration options. + * CONFIG_SDIO_WIDTH_D1_ONLY - This may be selected to force the driver + * operate with only a single data line (the default is to use all + * 4 SD data lines). + * CONFIG_SDIO_PRI - SDIO interrupt priority. This setting is not very + * important since interrupt nesting is not currently supported. + * CONFIG_SDM_DMAPRIO - SDIO DMA priority. This can be selecte if + * CONFIG_SDIO_DMA is enabled. + * CONFIG_SDIO_XFRDEBUG - Enables some very low-level debug output + * This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_VERBOSE + */ + +#if defined(CONFIG_SDIO_DMA) && !defined(CONFIG_STM32_DMA2) +# warning "CONFIG_SDIO_DMA support requires CONFIG_STM32_DMA2" +#endif + +#ifndef CONFIG_SDIO_DMA +# warning "Large Non-DMA transfer may result in RX overrun failures" +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_SDIO_PRI +# define CONFIG_SDIO_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +#ifdef CONFIG_SDIO_DMA +# ifndef CONFIG_SDIO_DMAPRIO +# if defined(CONFIG_STM32_STM32F10XX) +# define CONFIG_SDIO_DMAPRIO DMA_CCR_PRIMED +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CONFIG_SDIO_DMAPRIO DMA_SCR_PRIVERYHI +# else +# error "Unknown STM32 DMA" +# endif +# endif +# if defined(CONFIG_STM32_STM32F10XX) +# if (CONFIG_SDIO_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SDIO_DMAPRIO" +# endif +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# if (CONFIG_SDIO_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SDIO_DMAPRIO" +# endif +# else +# error "Unknown STM32 DMA" +# endif +#else +# undef CONFIG_SDIO_DMAPRIO +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG) +# undef CONFIG_SDIO_XFRDEBUG +#endif + +/* Friendly CLKCR bit re-definitions ****************************************/ + +#define SDIO_CLKCR_RISINGEDGE (0) +#define SDIO_CLKCR_FALLINGEDGE SDIO_CLKCR_NEGEDGE + +/* Mode dependent settings. These depend on clock devisor settings that must + * be defined in the board-specific board.h header file: SDIO_INIT_CLKDIV, + * SDIO_MMCXFR_CLKDIV, and SDIO_SDXFR_CLKDIV. + */ + +#define STM32_CLCKCR_INIT (SDIO_INIT_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLKCR_MMCXFR (SDIO_MMCXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLCKR_SDXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLCKR_SDWIDEXFR (SDIO_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D4) + +/* Timing */ + +#define SDIO_CMDTIMEOUT (100000) +#define SDIO_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define SDIO_DTIMER_DATATIMEOUT (0x000fffff) + +/* DMA channel/stream configuration register settings. The following + * must be selected. The DMA driver will select the remaining fields. + * + * - 32-bit DMA + * - Memory increment + * - Direction (memory-to-peripheral, peripheral-to-memory) + * - Memory burst size (F4 only) + */ + +/* STM32 F1 channel configuration register (CCR) settings */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define SDIO_RXDMA32_CONFIG (CONFIG_SDIO_DMAPRIO | DMA_CCR_MSIZE_32BITS | \ + DMA_CCR_PSIZE_32BITS | DMA_CCR_MINC) +# define SDIO_TXDMA32_CONFIG (CONFIG_SDIO_DMAPRIO | DMA_CCR_MSIZE_32BITS | \ + DMA_CCR_PSIZE_32BITS | DMA_CCR_MINC | DMA_CCR_DIR) + +/* STM32 F4 stream configuration register (SCR) settings. */ + +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define SDIO_RXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_P2M|DMA_SCR_MINC | \ + DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ + CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ + DMA_SCR_MBURST_INCR4) +# define SDIO_TXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_M2P | DMA_SCR_MINC | \ + DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ + CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ + DMA_SCR_MBURST_INCR4) +#else +# error "Unknown STM32 DMA" +#endif + +/* SDIO DMA Channel/Stream selection. For the case of the STM32 F4, there + * are multiple DMA stream options that must be dis-ambiguated in the board.h + * file. + */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define SDIO_DMACHAN DMACHAN_SDIO +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define SDIO_DMACHAN DMAMAP_SDIO +#else +# error "Unknown STM32 DMA" +#endif + +/* FIFO sizes */ + +#define SDIO_HALFFIFO_WORDS (8) +#define SDIO_HALFFIFO_BYTES (8*4) + +/* Data transfer interrupt mask bits */ + +#define SDIO_RECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ + SDIO_MASK_RXFIFOHFIE | SDIO_MASK_STBITERRIE) +#define SDIO_SEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ + SDIO_MASK_TXFIFOHEIE | SDIO_MASK_STBITERRIE) +#define SDIO_DMARECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ + SDIO_MASK_STBITERRIE) +#define SDIO_DMASEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ + SDIO_MASK_STBITERRIE) + +/* Event waiting interrupt mask bits */ + +#define SDIO_CMDDONE_STA (SDIO_STA_CMDSENT) +#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL | \ + SDIO_STA_CMDREND) +#define SDIO_XFRDONE_STA (0) + +#define SDIO_CMDDONE_MASK (SDIO_MASK_CMDSENTIE) +#define SDIO_RESPDONE_MASK (SDIO_MASK_CCRCFAILIE | SDIO_MASK_CTIMEOUTIE | \ + SDIO_MASK_CMDRENDIE) +#define SDIO_XFRDONE_MASK (0) + +#define SDIO_CMDDONE_ICR (SDIO_ICR_CMDSENTC | SDIO_ICR_DBCKENDC) +#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC | \ + SDIO_ICR_CMDRENDC | SDIO_ICR_DBCKENDC) +#define SDIO_XFRDONE_ICR (SDIO_ICR_DATAENDC | SDIO_ICR_DCRCFAILC | \ + SDIO_ICR_DTIMEOUTC | SDIO_ICR_RXOVERRC | \ + SDIO_ICR_TXUNDERRC | SDIO_ICR_STBITERRC | \ + SDIO_ICR_DBCKENDC) + +#define SDIO_WAITALL_ICR (SDIO_CMDDONE_ICR | SDIO_RESPDONE_ICR | \ + SDIO_XFRDONE_ICR | SDIO_ICR_DBCKENDC) + +/* Let's wait until we have both SDIO transfer complete and DMA complete. */ + +#define SDIO_XFRDONE_FLAG (1) +#define SDIO_DMADONE_FLAG (2) +#define SDIO_ALLDONE (3) + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +# ifdef CONFIG_SDIO_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define DEBUG_NSAMPLES 5 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define DEBUG_NSAMPLES 3 +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure defines the state of the STM32 SDIO interface */ + +struct stm32_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* STM32-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + size_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */ + bool dmamode; /* true: DMA mode transfer */ + DMA_HANDLE dma; /* Handle for DMA channel */ +#endif +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +struct stm32_sdioregs_s +{ + uint8_t power; + uint16_t clkcr; + uint16_t dctrl; + uint32_t dtimer; + uint32_t dlen; + uint32_t dcount; + uint32_t sta; + uint32_t mask; + uint32_t fifocnt; +}; + +struct stm32_sampleregs_s +{ + struct stm32_sdioregs_s sdio; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + struct stm32_dmaregs_s dma; +#endif +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void stm32_takesem(struct stm32_dev_s *priv); +#define stm32_givesem(priv) (sem_post(&priv->waitsem)) +static inline void stm32_setclkcr(uint32_t clkcr); +static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask); +static void stm32_setpwrctrl(uint32_t pwrctrl); +static inline uint32_t stm32_getpwrctrl(void); + +/* DMA Helpers **************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sampleinit(void); +static void stm32_sdiosample(struct stm32_sdioregs_s *regs); +static void stm32_sample(struct stm32_dev_s *priv, int index); +static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg); +static void stm32_dumpsample(struct stm32_dev_s *priv, + struct stm32_sampleregs_s *regs, const char *msg); +static void stm32_dumpsamples(struct stm32_dev_s *priv); +#else +# define stm32_sampleinit() +# define stm32_sample(priv,index) +# define stm32_dumpsamples(priv) +#endif + +#ifdef CONFIG_SDIO_DMA +static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +/* Data Transfer Helpers ****************************************************/ + +static uint8_t stm32_log2(uint16_t value); +static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl); +static void stm32_datadisable(void); +static void stm32_sendfifo(struct stm32_dev_s *priv); +static void stm32_recvfifo(struct stm32_dev_s *priv); +static void stm32_eventtimeout(int argc, uint32_t arg); +static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent); +static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupevent); + +/* Interrupt Handling *******************************************************/ + +static int stm32_interrupt(int irq, void *context); +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int stm32_rdyinterrupt(int irq, void *context); +#endif + +/* SDIO interface methods ***************************************************/ + +/* Mutual exclusion */ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock); +#endif + +/* Initialization/setup */ + +static void stm32_reset(FAR struct sdio_dev_s *dev); +static uint8_t stm32_status(FAR struct sdio_dev_s *dev); +static void stm32_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void stm32_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int stm32_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, uint32_t nbytes); +static int stm32_cancel(FAR struct sdio_dev_s *dev); + +static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void stm32_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void stm32_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int stm32_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool stm32_dmasupported(FAR struct sdio_dev_s *dev); +#ifdef CONFIG_SDIO_PREFLIGHT +static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif +static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void stm32_callback(void *arg); +static void stm32_default(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct stm32_dev_s g_sdiodev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = stm32_lock, +#endif + .reset = stm32_reset, + .status = stm32_status, + .widebus = stm32_widebus, + .clock = stm32_clock, + .attach = stm32_attach, + .sendcmd = stm32_sendcmd, +#ifdef CONFIG_SDIO_BLOCKSETUP + .blocksetup = stm32_blocksetup, /* Not implemented yet */ +#endif + .recvsetup = stm32_recvsetup, + .sendsetup = stm32_sendsetup, + .cancel = stm32_cancel, + .waitresponse = stm32_waitresponse, + .recvR1 = stm32_recvshortcrc, + .recvR2 = stm32_recvlong, + .recvR3 = stm32_recvshort, + .recvR4 = stm32_recvnotimpl, + .recvR5 = stm32_recvnotimpl, + .recvR6 = stm32_recvshortcrc, + .recvR7 = stm32_recvshort, + .waitenable = stm32_waitenable, + .eventwait = stm32_eventwait, + .callbackenable = stm32_callbackenable, + .registercallback = stm32_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = stm32_dmasupported, +#ifdef CONFIG_SDIO_PREFLIGHT + .dmapreflight = stm32_dmapreflight, +#endif + .dmarecvsetup = stm32_dmarecvsetup, + .dmasendsetup = stm32_dmasendsetup, +#endif + }, +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_takesem(struct stm32_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: stm32_setclkcr + * + * Description: + * Modify oft-changed bits in the CLKCR register. Only the following bit- + * fields are changed: + * + * CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, and HWFC_EN + * + * Input Parameters: + * clkcr - A new CLKCR setting for the above mentions bits (other bits + * are ignored. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_setclkcr(uint32_t clkcr) +{ + uint32_t regval = getreg32(STM32_SDIO_CLKCR); + + /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ + + regval &= ~(SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | + SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | + SDIO_CLKCR_CLKEN); + + /* Replace with user provided settings */ + + clkcr &= (SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | + SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | + SDIO_CLKCR_CLKEN); + + regval |= clkcr; + putreg32(regval, STM32_SDIO_CLKCR); + + fvdbg("CLKCR: %08x PWR: %08x\n", + getreg32(STM32_SDIO_CLKCR), getreg32(STM32_SDIO_POWER)); +} + +/**************************************************************************** + * Name: stm32_configwaitints + * + * Description: + * Enable/disable SDIO interrupts needed to suport the wait function + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * waitmask - The set of bits in the SDIO MASK register to set + * waitevents - Waited for events + * wkupevent - Wake-up events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + int pinset; +#endif + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + flags = enter_critical_section(); + +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + if ((waitmask & SDIOWAIT_WRCOMPLETE) != 0) + { + /* Do not use this in STM32_SDIO_MASK register */ + + waitmask &= !SDIOWAIT_WRCOMPLETE; + + pinset = GPIO_SDIO_D0 & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pinset |= (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI); + + /* Arm the SDIO_D Ready and install Isr */ + + stm32_gpiosetevent(pinset, true, false, false, stm32_rdyinterrupt); + } + + /* Disarm SDIO_D ready */ + + if ((wkupevent & SDIOWAIT_WRCOMPLETE) != 0) + { + stm32_gpiosetevent(GPIO_SDIO_D0, false, false, false , NULL); + stm32_configgpio(GPIO_SDIO_D0); + } +#endif + + priv->waitevents = waitevents; + priv->wkupevent = wkupevent; + priv->waitmask = waitmask; +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_configxfrints + * + * Description: + * Enable SDIO interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * xfrmask - The set of bits in the SDIO MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask) +{ + irqstate_t flags; + flags = enter_critical_section(); + priv->xfrmask = xfrmask; + putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_setpwrctrl + * + * Description: + * Change the PWRCTRL field of the SDIO POWER register to turn the SDIO + * ON or OFF + * + * Input Parameters: + * clkcr - A new PWRCTRL setting + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_setpwrctrl(uint32_t pwrctrl) +{ + uint32_t regval; + + regval = getreg32(STM32_SDIO_POWER); + regval &= ~SDIO_POWER_PWRCTRL_MASK; + regval |= pwrctrl; + putreg32(regval, STM32_SDIO_POWER); +} + +/**************************************************************************** + * Name: stm32_getpwrctrl + * + * Description: + * Return the current value of the the PWRCTRL field of the SDIO POWER + * register. This function can be used to see if the SDIO is powered ON + * or OFF + * + * Input Parameters: + * None + * + * Returned Value: + * The current value of the the PWRCTRL field of the SDIO POWER register. + * + ****************************************************************************/ + +static inline uint32_t stm32_getpwrctrl(void) +{ + return getreg32(STM32_SDIO_POWER) & SDIO_POWER_PWRCTRL_MASK; +} + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sampleinit + * + * Description: + * Setup prior to collecting DMA samples + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sampleinit(void) +{ + memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct stm32_sampleregs_s)); +} +#endif + +/**************************************************************************** + * Name: stm32_sdiosample + * + * Description: + * Sample SDIO registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sdiosample(struct stm32_sdioregs_s *regs) +{ + regs->power = (uint8_t)getreg32(STM32_SDIO_POWER); + regs->clkcr = (uint16_t)getreg32(STM32_SDIO_CLKCR); + regs->dctrl = (uint16_t)getreg32(STM32_SDIO_DCTRL); + regs->dtimer = getreg32(STM32_SDIO_DTIMER); + regs->dlen = getreg32(STM32_SDIO_DLEN); + regs->dcount = getreg32(STM32_SDIO_DCOUNT); + regs->sta = getreg32(STM32_SDIO_STA); + regs->mask = getreg32(STM32_SDIO_MASK); + regs->fifocnt = getreg32(STM32_SDIO_FIFOCNT); +} +#endif + +/**************************************************************************** + * Name: stm32_sample + * + * Description: + * Sample SDIO/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sample(struct stm32_dev_s *priv, int index) +{ + struct stm32_sampleregs_s *regs = &g_sampleregs[index]; +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dmasample(priv->dma, ®s->dma); + } +#endif + stm32_sdiosample(®s->sdio); +} +#endif + +/**************************************************************************** + * Name: stm32_sdiodump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg) +{ + fdbg("SDIO Registers: %s\n", msg); + fdbg(" POWER[%08x]: %08x\n", STM32_SDIO_POWER, regs->power); + fdbg(" CLKCR[%08x]: %08x\n", STM32_SDIO_CLKCR, regs->clkcr); + fdbg(" DCTRL[%08x]: %08x\n", STM32_SDIO_DCTRL, regs->dctrl); + fdbg(" DTIMER[%08x]: %08x\n", STM32_SDIO_DTIMER, regs->dtimer); + fdbg(" DLEN[%08x]: %08x\n", STM32_SDIO_DLEN, regs->dlen); + fdbg(" DCOUNT[%08x]: %08x\n", STM32_SDIO_DCOUNT, regs->dcount); + fdbg(" STA[%08x]: %08x\n", STM32_SDIO_STA, regs->sta); + fdbg(" MASK[%08x]: %08x\n", STM32_SDIO_MASK, regs->mask); + fdbg("FIFOCNT[%08x]: %08x\n", STM32_SDIO_FIFOCNT, regs->fifocnt); +} +#endif + +/**************************************************************************** + * Name: stm32_dumpsample + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_dumpsample(struct stm32_dev_s *priv, + struct stm32_sampleregs_s *regs, const char *msg) +{ +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dmadump(priv->dma, ®s->dma, msg); + } +#endif + stm32_sdiodump(®s->sdio, msg); +} +#endif + +/**************************************************************************** + * Name: stm32_dumpsamples + * + * Description: + * Dump all sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_dumpsamples(struct stm32_dev_s *priv) +{ + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); + } +#endif + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup"); + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer"); +#if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); + } +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_dmacallback + * + * Description: + * Called when SDIO DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)arg; + DEBUGASSERT(priv->dmamode); + sdio_eventset_t result; + + /* In the normal case, SDIO appears to handle the End-Of-Transfer interrupt + * first with the End-Of-DMA event occurring significantly later. On + * transfer errors, however, the DMA error will occur before the End-of- + * Transfer. + */ + + stm32_sample((struct stm32_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); + + /* Get the result of the DMA transfer */ + + if ((status & DMA_STATUS_ERROR) != 0) + { + flldbg("DMA error %02x, remaining: %d\n", status, priv->remaining); + result = SDIOWAIT_ERROR; + } + else + { + result = SDIOWAIT_TRANSFERDONE; + } + + /* Then terminate the transfer if this completes all of the steps in the + * transfer OR if a DMA error occurred. In the non-error case, we should + * already have the SDIO transfer done interrupt. If not, the transfer + * will appropriately time out. + */ + + priv->xfrflags |= SDIO_DMADONE_FLAG; + if (priv->xfrflags == SDIO_ALLDONE || result == SDIOWAIT_ERROR) + { + stm32_endtransfer(priv, result); + } +} +#endif + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_log2 + * + * Description: + * Take (approximate) log base 2 of the provided number (Only works if the + * provided number is a power of 2). + * + ****************************************************************************/ + +static uint8_t stm32_log2(uint16_t value) +{ + uint8_t log2 = 0; + + /* 0000 0000 0000 0001 -> return 0, + * 0000 0000 0000 001x -> return 1, + * 0000 0000 0000 01xx -> return 2, + * 0000 0000 0000 1xxx -> return 3, + * ... + * 1xxx xxxx xxxx xxxx -> return 15, + */ + + DEBUGASSERT(value > 0); + while (value != 1) + { + value >>= 1; + log2++; + } + + return log2; +} + +/**************************************************************************** + * Name: stm32_dataconfig + * + * Description: + * Configure the SDIO data path for the next data transfer + * + ****************************************************************************/ + +static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) +{ + uint32_t regval = 0; + + /* Enable data path */ + + putreg32(timeout, STM32_SDIO_DTIMER); /* Set DTIMER */ + putreg32(dlen, STM32_SDIO_DLEN); /* Set DLEN */ + + /* Configure DCTRL DTDIR, DTMODE, and DBLOCKSIZE fields and set the DTEN + * field + */ + + regval = getreg32(STM32_SDIO_DCTRL); + regval &= ~(SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); + dctrl &= (SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); + regval |= (dctrl | SDIO_DCTRL_DTEN); + putreg32(regval, STM32_SDIO_DCTRL); +} + +/**************************************************************************** + * Name: stm32_datadisable + * + * Description: + * Disable the SDIO data path setup by stm32_dataconfig() and + * disable DMA. + * + ****************************************************************************/ + +static void stm32_datadisable(void) +{ + uint32_t regval; + + /* Disable the data path */ + + putreg32(SDIO_DTIMER_DATATIMEOUT, STM32_SDIO_DTIMER); /* Reset DTIMER */ + putreg32(0, STM32_SDIO_DLEN); /* Reset DLEN */ + + /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */ + + regval = getreg32(STM32_SDIO_DCTRL); + regval &= ~(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | + SDIO_DCTRL_DMAEN | SDIO_DCTRL_DBLOCKSIZE_MASK); + putreg32(regval, STM32_SDIO_DCTRL); +} + +/**************************************************************************** + * Name: stm32_sendfifo + * + * Description: + * Send SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_sendfifo(struct stm32_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is more data to be sent and the RX FIFO is not full */ + + while (priv->remaining > 0 && + (getreg32(STM32_SDIO_STA) & SDIO_STA_TXFIFOF) == 0) + { + /* Is there a full word remaining in the user buffer? */ + + if (priv->remaining >= sizeof(uint32_t)) + { + /* Yes, transfer the word to the TX FIFO */ + + data.w = *priv->buffer++; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer just the bytes remaining in the user buffer, + * padding with zero as necessary to extend to a full word. + */ + + uint8_t *ptr = (uint8_t *)priv->remaining; + int i; + + data.w = 0; + for (i = 0; i < (int)priv->remaining; i++) + { + data.b[i] = *ptr++; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + + /* Put the word in the FIFO */ + + putreg32(data.w, STM32_SDIO_FIFO); + } +} + +/**************************************************************************** + * Name: stm32_recvfifo + * + * Description: + * Receive SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_recvfifo(struct stm32_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is space to store the data and there is more + * data available in the RX FIFO. + */ + + while (priv->remaining > 0 && + (getreg32(STM32_SDIO_STA) & SDIO_STA_RXDAVL) != 0) + { + /* Read the next word from the RX FIFO */ + + data.w = getreg32(STM32_SDIO_FIFO); + if (priv->remaining >= sizeof(uint32_t)) + { + /* Transfer the whole word to the user buffer */ + + *priv->buffer++ = data.w; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* Transfer any trailing fractional word */ + + uint8_t *ptr = (uint8_t *)priv->buffer; + int i; + + for (i = 0; i < (int)priv->remaining; i++) + { + *ptr++ = data.b[i]; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + } +} + +/**************************************************************************** + * Name: stm32_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_eventtimeout(int argc, uint32_t arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)arg; + + /* There is always race conditions with timer expirations. */ + + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + + /* Is a data transfer complete event expected? */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + stm32_endwait(priv, SDIOWAIT_TIMEOUT); + flldbg("Timeout: remaining: %d\n", priv->remaining); + } +} + +/**************************************************************************** + * Name: stm32_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, wkupevent); + + /* Wake up the waiting thread */ + + stm32_givesem(priv); +} + +/**************************************************************************** + * Name: stm32_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the SDIO interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + stm32_configxfrints(priv, 0); + + /* Clearing pending interrupt status on all transfer related interrupts */ + + putreg32(SDIO_XFRDONE_ICR, STM32_SDIO_ICR); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* DMA debug instrumentation */ + + stm32_sample(priv, SAMPLENDX_END_TRANSFER); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + stm32_dmastop(priv->dma); + } +#endif + + /* Mark the transfer finished */ + + priv->remaining = 0; + + /* Is a thread wait for these data transfer complete events? */ + + if ((priv->waitevents & wkupevent) != 0) + { + /* Yes.. wake up any waiting threads */ + + stm32_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rdyinterrupt + * + * Description: + * SDIO ready interrupt handler + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int stm32_rdyinterrupt(int irq, void *context) +{ + struct stm32_dev_s *priv = &g_sdiodev; + stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_interrupt + * + * Description: + * SDIO interrupt handler + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int stm32_interrupt(int irq, void *context) +{ + struct stm32_dev_s *priv = &g_sdiodev; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. Check the SDIO status + * register. Mask out all bits that don't correspond to enabled + * interrupts. (This depends on the fact that bits are ordered + * the same in both the STA and MASK register). If there are non-zero + * bits remaining, then we have work to do here. + */ + + while ((enabled = getreg32(STM32_SDIO_STA) & getreg32(STM32_SDIO_MASK)) != 0) + { + /* Handle in progress, interrupt driven data transfers ****************/ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { +#ifdef CONFIG_SDIO_DMA + if (!priv->dmamode) +#endif + { + /* Is the RX FIFO half full or more? Is so then we must be + * processing a receive transaction. + */ + + if ((pending & SDIO_STA_RXFIFOHF) != 0) + { + /* Receive data from the RX FIFO */ + + stm32_recvfifo(priv); + } + + /* Otherwise, Is the transmit FIFO half empty or less? If so we must + * be processing a send transaction. NOTE: We can't be processing + * both! + */ + + else if ((pending & SDIO_STA_TXFIFOHE) != 0) + { + /* Send data via the TX FIFO */ + + stm32_sendfifo(priv); + } + } + + /* Handle data end events */ + + if ((pending & SDIO_STA_DATAEND) != 0) + { + /* Handle any data remaining the RX FIFO. If the RX FIFO is + * less than half full at the end of the transfer, then no + * half-full interrupt will be received. + */ + + /* Was this transfer performed in DMA mode? */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Yes.. Terminate the transfers only if the DMA has also + * finished. + */ + + priv->xfrflags |= SDIO_XFRDONE_FLAG; + if (priv->xfrflags == SDIO_ALLDONE) + { + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + + /* Otherwise, just disable futher transfer interrupts and + * wait for the DMA complete event. + */ + + else + { + stm32_configxfrints(priv, 0); + } + } + else +#endif + { + /* Receive data from the RX FIFO */ + + stm32_recvfifo(priv); + + /* Then terminate the transfer */ + + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle data block send/receive CRC failure */ + + else if ((pending & SDIO_STA_DCRCFAIL) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle data timeout error */ + + else if ((pending & SDIO_STA_DTIMEOUT) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Data timeout, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + + /* Handle RX FIFO overrun error */ + + else if ((pending & SDIO_STA_RXOVERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle TX FIFO underrun error */ + + else if ((pending & SDIO_STA_TXUNDERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle start bit error */ + + else if ((pending & SDIO_STA_STBITERR) != 0) + { + /* Terminate the transfer with an error */ + + flldbg("ERROR: Start bit, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + + /* Handle wait events *************************************************/ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + /* Is this a response completion event? */ + + if ((pending & SDIO_RESPDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for response done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + stm32_endwait(priv, SDIOWAIT_RESPONSEDONE); + } + } + + /* Is this a command completion event? */ + + if ((pending & SDIO_CMDDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for command done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + stm32_endwait(priv, SDIOWAIT_CMDDONE); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_lock + * + * Description: + * Locks the bus. Function calls low-level multiplexed bus routines to + * resolve bus requests and acknowledgment issues. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * lock - TRUE to lock, FALSE to unlock. + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock) +{ + /* Single SDIO instance so there is only one possibility. The multiplex + * bus is part of board support package. + */ + + stm32_muxbus_sdio_lock(lock); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_reset + * + * Description: + * Reset the SDIO controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + irqstate_t flags; + + /* Disable clocking */ + + flags = enter_critical_section(); + putreg32(0, SDIO_CLKCR_CLKEN_BB); + stm32_setpwrctrl(SDIO_POWER_PWRCTRL_OFF); + + /* Put SDIO registers in their default, reset state */ + + stm32_default(); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; /* Used to synchronize SDIO and DMA completion events */ +#endif + + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->buffer = 0; /* Address of current R/W buffer */ + priv->remaining = 0; /* Number of bytes remaining in the transfer */ + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; /* true: DMA mode transfer */ +#endif + + /* Configure the SDIO peripheral */ + + stm32_setclkcr(STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); + stm32_setpwrctrl(SDIO_POWER_PWRCTRL_ON); + leave_critical_section(flags); + + fvdbg("CLCKR: %08x POWER: %08x\n", + getreg32(STM32_SDIO_CLKCR), getreg32(STM32_SDIO_POWER)); +} + +/**************************************************************************** + * Name: stm32_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see stm32_status_* defines) + * + ****************************************************************************/ + +static uint8_t stm32_status(FAR struct sdio_dev_s *dev) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: stm32_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + priv->widebus = wide; +} + +/**************************************************************************** + * Name: stm32_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t clckr; + + switch (rate) + { + /* Disable clocking (with default ID mode divisor) */ + + default: + case CLOCK_SDIO_DISABLED: + clckr = STM32_CLCKCR_INIT; + return; + + /* Enable in initial ID mode clocking (<400KHz) */ + + case CLOCK_IDMODE: + clckr = (STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); + break; + + /* Enable in MMC normal operation clocking */ + + case CLOCK_MMC_TRANSFER: + clckr = (SDIO_CLKCR_MMCXFR | SDIO_CLKCR_CLKEN); + break; + + /* SD normal operation clocking (wide 4-bit mode) */ + + case CLOCK_SD_TRANSFER_4BIT: +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + clckr = (SDIO_CLCKR_SDWIDEXFR | SDIO_CLKCR_CLKEN); + break; +#endif + + /* SD normal operation clocking (narrow 1-bit mode) */ + + case CLOCK_SD_TRANSFER_1BIT: + clckr = (SDIO_CLCKR_SDXFR | SDIO_CLKCR_CLKEN); + break; + } + + /* Set the new clock frequency along with the clock enable/disable bit */ + + stm32_setclkcr(clckr); +} + +/**************************************************************************** + * Name: stm32_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int stm32_attach(FAR struct sdio_dev_s *dev) +{ + int ret; + + /* Attach the SDIO interrupt handler */ + + ret = irq_attach(STM32_IRQ_SDIO, stm32_interrupt); + if (ret == OK) + { + + /* Disable all interrupts at the SDIO controller and clear static + * interrupt flags + */ + + putreg32(SDIO_MASK_RESET, STM32_SDIO_MASK); + putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR); + + /* Enable SDIO interrupts at the NVIC. They can now be enabled at + * the SDIO controller as needed. + */ + + up_enable_irq(STM32_IRQ_SDIO); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_SDIO, CONFIG_SDIO_PRI); +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) +{ + uint32_t regval; + uint32_t cmdidx; + + /* Set the SDIO Argument value */ + + putreg32(arg, STM32_SDIO_ARG); + + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, and CPSMEN bits */ + + regval = getreg32(STM32_SDIO_CMD); + regval &= ~(SDIO_CMD_CMDINDEX_MASK | SDIO_CMD_WAITRESP_MASK | + SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND | SDIO_CMD_CPSMEN); + + /* Set WAITRESP bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + regval |= SDIO_CMD_NORESPONSE; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= SDIO_CMD_SHORTRESPONSE; + break; + + case MMCSD_R2_RESPONSE: + regval |= SDIO_CMD_LONGRESPONSE; + break; + } + + /* Set CPSMEN and the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval |= cmdidx | SDIO_CMD_CPSMEN; + + fvdbg("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + + /* Write the SDIO CMD */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + putreg32(regval, STM32_SDIO_CMD); + return OK; +} + +/**************************************************************************** + * Name: stm32_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer in which to receive the data + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize | SDIO_DCTRL_DTDIR); + + /* And enable interrupts */ + + stm32_configxfrints(priv, SDIO_RECV_MASK); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: stm32_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer containing the data to send + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize); + + /* Enable TX interrupts */ + + stm32_configxfrints(priv, SDIO_SEND_MASK); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: stm32_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_cancel(FAR struct sdio_dev_s *dev) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + stm32_configxfrints(priv, 0); + stm32_configwaitints(priv, 0, 0, 0); + + /* Clearing pending interrupt status on all transfer- and event- related + * interrupts + */ + + putreg32(SDIO_WAITALL_ICR, STM32_SDIO_ICR); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + */ + + stm32_dmastop(priv->dma); + } +#endif + + /* Mark no transfer in progress */ + + priv->remaining = 0; + return OK; +} + +/**************************************************************************** + * Name: stm32_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + int32_t timeout; + uint32_t events; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + events = SDIO_CMDDONE_STA; + timeout = SDIO_CMDTIMEOUT; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + events = SDIO_RESPDONE_STA; + timeout = SDIO_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + events = SDIO_RESPDONE_STA; + timeout = SDIO_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + while ((getreg32(STM32_SDIO_STA) & events) == 0) + { + if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n", + cmd, events, getreg32(STM32_SDIO_STA)); + + return -ETIMEDOUT; + } + } + + putreg32(SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + return OK; +} + +/**************************************************************************** + * Name: stm32_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a faiure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intacta and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ +#ifdef CONFIG_DEBUG + uint32_t respcmd; +#endif + uint32_t regval; + int ret = OK; + + /* R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + */ + + +#ifdef CONFIG_DEBUG + if (!rshort) + { + fdbg("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(STM32_SDIO_STA); + if ((regval & SDIO_STA_CTIMEOUT) != 0) + { + fdbg("ERROR: Command timeout: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if ((regval & SDIO_STA_CCRCFAIL) != 0) + { + fdbg("ERROR: CRC failure: %08x\n", regval); + ret = -EIO; + } +#ifdef CONFIG_DEBUG + else + { + /* Check response received is of desired command */ + + respcmd = getreg32(STM32_SDIO_RESPCMD); + if ((uint8_t)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK)) + { + fdbg("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd); + ret = -EINVAL; + } + } +#endif + } + + /* Clear all pending message completion events and return the R1/R6 response */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + *rshort = getreg32(STM32_SDIO_RESP1); + return ret; +} + +static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + uint32_t regval; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(STM32_SDIO_STA); + if (regval & SDIO_STA_CTIMEOUT) + { + fdbg("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if (regval & SDIO_STA_CCRCFAIL) + { + fdbg("ERROR: CRC fail STA: %08x\n", regval); + ret = -EIO; + } + } + + /* Return the long response */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + if (rlong) + { + rlong[0] = getreg32(STM32_SDIO_RESP1); + rlong[1] = getreg32(STM32_SDIO_RESP2); + rlong[2] = getreg32(STM32_SDIO_RESP3); + rlong[3] = getreg32(STM32_SDIO_RESP4); + } + return ret; +} + +static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ + uint32_t regval; + int ret = OK; + + /* R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + + /* Check that this is the correct response to this command */ + +#ifdef CONFIG_DEBUG + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + fdbg("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout occurred (Apparently a CRC error can terminate + * a good response) + */ + + regval = getreg32(STM32_SDIO_STA); + if (regval & SDIO_STA_CTIMEOUT) + { + fdbg("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + } + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + if (rshort) + { + *rshort = getreg32(STM32_SDIO_RESP1); + } + return ret; +} + +/* MMC responses not supported */ + +static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl) +{ + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDIO_ICR); + return -ENOSYS; +} + +/**************************************************************************** + * Name: stm32_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling stm32_eventwait. This is done in this way + * to help the driver to eliminate race conditions between the command + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + +#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) + if ((eventset & SDIOWAIT_WRCOMPLETE) != 0) + { + waitmask = SDIOWAIT_WRCOMPLETE; + } + else +#endif + { + waitmask = 0; + if ((eventset & SDIOWAIT_CMDDONE) != 0) + { + waitmask |= SDIO_CMDDONE_MASK; + } + + if ((eventset & SDIOWAIT_RESPONSEDONE) != 0) + { + waitmask |= SDIO_RESPDONE_MASK; + } + + if ((eventset & SDIOWAIT_TRANSFERDONE) != 0) + { + waitmask |= SDIO_XFRDONE_MASK; + } + + /* Enable event-related interrupts */ + + putreg32(SDIO_WAITALL_ICR, STM32_SDIO_ICR); + } + + stm32_configwaitints(priv, waitmask, eventset, 0); +} + +/**************************************************************************** + * Name: stm32_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when stm32_eventwait + * returns. SDIO_WAITEVENTS must be called again before stm32_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + irqstate_t flags; + int ret; + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevents will + * be non-zero (and, hopefully, the semaphore count will also be non-zero. + */ + + flags = enter_critical_section(); + DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + /* Then just tell the caller that we already timed out */ + + wkupevent = SDIOWAIT_TIMEOUT; + goto errout; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)stm32_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + fdbg("ERROR: wd_start failed: %d\n", ret); + } + } + +#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) + if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) + { + /* Atomically read pin to see if ready (true) and determine if ISR fired + * If Pin is ready and if ISR did NOT fire end the wait here + */ + + if (stm32_gpioread(GPIO_SDIO_D0) && + (priv->wkupevent & SDIOWAIT_WRCOMPLETE) == 0) + { + stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); + } + } +#endif + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling stm32_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + stm32_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, 0); +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + +errout: + leave_critical_section(flags); + stm32_dumpsamples(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: stm32_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in stm32_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methos. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + fvdbg("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + stm32_callback(priv); +} + +/**************************************************************************** + * Name: stm32_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int stm32_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + fvdbg("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: stm32_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool stm32_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: stm32_dmapreflight + * + * Description: + * Preflight an SDIO DMA operation. If the buffer is not well-formed for + * SDIO DMA transfer (alignment, size, etc.) returns an error. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA to/from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + ****************************************************************************/ + +#if defined(CONFIG_SDIO_DMA) && defined(CONFIG_SDIO_PREFLIGHT) +static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + + /* Wide bus operation is required for DMA */ + + if (!priv->widebus) + { + return -EINVAL; + } + + /* DMA must be possible to the buffer */ + + if (!stm32_dmacapable((uintptr_t)buffer, (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG)) + { + return -EFAULT; + } + + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); +#ifdef CONFIG_SDIO_PREFLIGHT + DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); +#endif + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + + /* Initialize register sampling */ + + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize | SDIO_DCTRL_DTDIR); + + /* Configure the RX DMA */ + + stm32_configxfrints(priv, SDIO_DMARECV_MASK); + + putreg32(1, SDIO_DCTRL_DMAEN_BB); + stm32_dmasetup(priv->dma, STM32_SDIO_FIFO, (uint32_t)buffer, + (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG); + + /* Start the DMA */ + + stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); + stm32_dmastart(priv->dma, stm32_dmacallback, priv, false); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); +#ifdef CONFIG_SDIO_PREFLIGHT + DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); +#endif + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + + /* Initialize register sampling */ + + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize); + + /* Configure the TX DMA */ + + stm32_dmasetup(priv->dma, STM32_SDIO_FIFO, (uint32_t)buffer, + (buflen + 3) >> 2, SDIO_TXDMA32_CONFIG); + + stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); + putreg32(1, SDIO_DCTRL_DMAEN_BB); + + /* Start the DMA */ + + stm32_dmastart(priv->dma, stm32_dmacallback, priv, false); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + + /* Enable TX interrupts */ + + stm32_configxfrints(priv, SDIO_DMASEND_MASK); + + return OK; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void stm32_callback(void *arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)arg; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + fvdbg("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* Callbacks cannot be performed in the context of an interrupt handler. + * If we are in an interrupt handler, then queue the callback to be + * performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + fvdbg("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + } + else + { + /* No.. then just call the callback here */ + + fvdbg("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } + } +} + +/**************************************************************************** + * Name: stm32_default + * + * Description: + * Restore SDIO registers to their default, reset values + * + ****************************************************************************/ + +static void stm32_default(void) +{ + putreg32(SDIO_POWER_RESET, STM32_SDIO_POWER); + putreg32(SDIO_CLKCR_RESET, STM32_SDIO_CLKCR); + putreg32(SDIO_ARG_RESET, STM32_SDIO_ARG); + putreg32(SDIO_CMD_RESET, STM32_SDIO_CMD); + putreg32(SDIO_DTIMER_RESET, STM32_SDIO_DTIMER); + putreg32(SDIO_DLEN_RESET, STM32_SDIO_DLEN); + putreg32(SDIO_DCTRL_RESET, STM32_SDIO_DCTRL); + putreg32(SDIO_ICR_RESET, STM32_SDIO_ICR); + putreg32(SDIO_MASK_RESET, STM32_SDIO_MASK); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + /* There is only one slot */ + + struct stm32_dev_s *priv = &g_sdiodev; + + /* Initialize the SDIO slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + + /* Allocate a DMA channel */ + +#ifdef CONFIG_SDIO_DMA + priv->dma = stm32_dmachannel(SDIO_DMACHAN); + DEBUGASSERT(priv->dma); +#endif + + /* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of + * 8-bit wide bus operation but D4-D7 are not configured). + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. + */ + +#ifndef CONFIG_SDIO_MUXBUS + stm32_configgpio(GPIO_SDIO_D0); +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + stm32_configgpio(GPIO_SDIO_D1); + stm32_configgpio(GPIO_SDIO_D2); + stm32_configgpio(GPIO_SDIO_D3); +#endif + stm32_configgpio(GPIO_SDIO_CK); + stm32_configgpio(GPIO_SDIO_CMD); +#endif + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + stm32_reset(&priv->dev); + return &g_sdiodev.dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + leave_critical_section(flags); + + fvdbg("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + stm32_callback(priv); + } +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + fvdbg("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} +#endif /* CONFIG_STM32_SDIO */ diff --git a/arch/arm/src/stm32/stm32_sdio.h b/arch/arm/src/stm32/stm32_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..04c65ba00f975b35761ef391016503ecb9e5c22d --- /dev/null +++ b/arch/arm/src/stm32/stm32_sdio.h @@ -0,0 +1,128 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_sdio.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_SDIO_H +#define __ARCH_ARM_SRC_STM32_STM32_SDIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/stm32_sdio.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_SDIO_H */ + diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..2e11d5260942cd815fd1dd96bfcfb7cb7fbaf02d --- /dev/null +++ b/arch/arm/src/stm32/stm32_serial.c @@ -0,0 +1,2959 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_serial.c + * + * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include + +#include "chip.h" +#include "stm32_uart.h" +#include "stm32_dma.h" +#include "stm32_rcc.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* DMA configuration */ + +/* If DMA is enabled on any USART, then very that other pre-requisites + * have also been selected. + */ + +#ifdef SERIAL_HAVE_DMA + +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +/* Verify that DMA has been enabled and the DMA channel has been defined. + */ + +# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA) +# ifndef CONFIG_STM32_DMA2 +# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2 +# endif +# endif + +# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \ + defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) || \ + defined(CONFIG_UART7_RXDMA) || defined(CONFIG_UART8_RXDMA) +# ifndef CONFIG_STM32_DMA1 +# error STM32 USART2/3/4/5/7/8 receive DMA requires CONFIG_STM32_DMA1 +# endif +# endif + +/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack + * of testing - RS-485 support was developed on STM32F1x + */ + +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ + (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ + (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ + (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ + (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) || \ + (defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_RS485)) || \ + (defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_RS485)) || \ + (defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_RS485)) +# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" +# endif + +/* For the F4, there are alternate DMA channels for USART1 and 6. + * Logic in the board.h file make the DMA channel selection by defining + * the following in the board.h file. + */ + +# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) +# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" +# endif + +# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX) +# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)" +# endif + +# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX) +# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)" +# endif + +# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX) +# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)" +# endif + +# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX) +# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)" +# endif + +# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX) +# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)" +# endif + +# if defined(CONFIG_UART7_RXDMA) && !defined(DMAMAP_UART7_RX) +# error "UART7 DMA channel not defined (DMAMAP_UART7_RX)" +# endif + +# if defined(CONFIG_UART8_RXDMA) && !defined(DMAMAP_UART8_RX) +# error "UART8 DMA channel not defined (DMAMAP_UART8_RX)" +# endif + +# elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F30XX) + +# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) +# ifndef CONFIG_STM32_DMA1 +# error STM32 USART1/2/3 receive DMA requires CONFIG_STM32_DMA1 +# endif +# endif + +# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) +# ifndef CONFIG_STM32_DMA2 +# error STM32 UART4/5 receive DMA requires CONFIG_STM32_DMA2 +# endif +# endif + +/* There are no optional DMA channel assignments for the F1 */ + +# define DMAMAP_USART1_RX DMACHAN_USART1_RX +# define DMAMAP_USART2_RX DMACHAN_USART2_RX +# define DMAMAP_USART3_RX DMACHAN_USART3_RX +# define DMAMAP_UART4_RX DMACHAN_UART4_RX +# define DMAMAP_UART5_RX DMACHAN_UART5_RX + +# endif + +/* The DMA buffer size when using RX DMA to emulate a FIFO. + * + * When streaming data, the generic serial layer will be called + * every time the FIFO receives half this number of bytes. + */ + +# define RXDMA_BUFFER_SIZE 32 + +/* DMA priority */ + +# ifndef CONFIG_USART_DMAPRIO +# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED +# else +# error "Unknown STM32 DMA" +# endif +# endif +# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \ + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# else +# error "Unknown STM32 DMA" +# endif + +/* DMA control words */ + +# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_CIRC | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# endif +# else +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_CCR_CIRC | \ + DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# endif +# endif + +#endif + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_PM_SERIAL_ACTIVITY) +# define CONFIG_PM_SERIAL_ACTIVITY 10 +# define PM_IDLE_DOMAIN 0 /* Revisit */ +#endif + +#ifdef USE_SERIALDRIVER +#ifdef HAVE_UART + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt mask bits value */ + uint16_t sr; /* Saved status bits */ + + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif + uint32_t baud; /* Configured baud */ +#else + const uint8_t parity; /* 0=none, 1=odd, 2=even */ + const uint8_t bits; /* Number of bits (7 or 8) */ + const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif + const uint32_t baud; /* Configured baud */ +#endif + + const uint8_t irq; /* IRQ associated with this USART */ + const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t usartbase; /* Base address of USART registers */ + const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif + +#ifdef SERIAL_HAVE_DMA + const unsigned int rxdma_channel; /* DMA channel assigned */ +#endif + + int (*const vector)(int irq, void *context); /* Interrupt handler */ + + /* RX DMA state */ + +#ifdef SERIAL_HAVE_DMA + DMA_HANDLE rxdma; /* currently-open receive DMA stream */ + bool rxenable; /* DMA-based reception en/disable */ + uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ + char *const rxfifo; /* Receive DMA buffer */ +#endif + +#ifdef HAVE_RS485 + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void up_set_format(struct uart_dev_s *dev); +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt_common(struct up_dev_s *dev); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, + bool upper); +#endif +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev); +static void up_dma_shutdown(struct uart_dev_s *dev); +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_dma_rxint(struct uart_dev_s *dev, bool enable); +static bool up_dma_rxavailable(struct uart_dev_s *dev); + +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int dowmin, + enum pm_state_e pmstate); +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +#ifdef CONFIG_STM32_USART1 +static int up_interrupt_usart1(int irq, void *context); +#endif +#ifdef CONFIG_STM32_USART2 +static int up_interrupt_usart2(int irq, void *context); +#endif +#ifdef CONFIG_STM32_USART3 +static int up_interrupt_usart3(int irq, void *context); +#endif +#ifdef CONFIG_STM32_UART4 +static int up_interrupt_uart4(int irq, void *context); +#endif +#ifdef CONFIG_STM32_UART5 +static int up_interrupt_uart5(int irq, void *context); +#endif +#ifdef CONFIG_STM32_USART6 +static int up_interrupt_usart6(int irq, void *context); +#endif +#ifdef CONFIG_STM32_UART7 +static int up_interrupt_uart7(int irq, void *context); +#endif +#ifdef CONFIG_STM32_UART8 +static int up_interrupt_uart8(int irq, void *context); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +#ifdef SERIAL_HAVE_DMA +static const struct uart_ops_s g_uart_dma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_dma_receive, + .rxint = up_dma_rxint, + .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +/* I/O buffers */ + +#ifdef CONFIG_STM32_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +# ifdef CONFIG_USART1_RXDMA +static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +# ifdef CONFIG_USART2_RXDMA +static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +# ifdef CONFIG_USART3_RXDMA +static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +# ifdef CONFIG_UART4_RXDMA +static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +# ifdef CONFIG_UART5_RXDMA +static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_USART6 +static char g_usart6rxbuffer[CONFIG_USART6_RXBUFSIZE]; +static char g_usart6txbuffer[CONFIG_USART6_TXBUFSIZE]; +# ifdef CONFIG_USART6_RXDMA +static char g_usart6rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART7 +static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; +static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; +# ifdef CONFIG_UART7_RXDMA +static char g_uart7rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART8 +static char g_uart8rxbuffer[CONFIG_UART8_RXBUFSIZE]; +static char g_uart8txbuffer[CONFIG_UART8_TXBUFSIZE]; +# ifdef CONFIG_UART8_RXDMA +static char g_uart8rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +/* This describes the state of the STM32 USART1 ports. */ + +#ifdef CONFIG_STM32_USART1 +static struct up_dev_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, +#ifdef CONFIG_USART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart1priv, + }, + + .irq = STM32_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = STM32_PCLK2_FREQUENCY, + .usartbase = STM32_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +#endif +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, + .rxfifo = g_usart1rxfifo, +#endif + .vector = up_interrupt_usart1, + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_USART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART2 port. */ + +#ifdef CONFIG_STM32_USART2 +static struct up_dev_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, +#ifdef CONFIG_USART2_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart2priv, + }, + + .irq = STM32_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, + .rxfifo = g_usart2rxfifo, +#endif + .vector = up_interrupt_usart2, + +#ifdef CONFIG_USART2_RS485 + .rs485_dir_gpio = GPIO_USART2_RS485_DIR, +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART3 port. */ + +#ifdef CONFIG_STM32_USART3 +static struct up_dev_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, +#ifdef CONFIG_USART3_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart3priv, + }, + + .irq = STM32_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, + .rxfifo = g_usart3rxfifo, +#endif + .vector = up_interrupt_usart3, + +#ifdef CONFIG_USART3_RS485 + .rs485_dir_gpio = GPIO_USART3_RS485_DIR, +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART4 port. */ + +#ifdef CONFIG_STM32_UART4 +static struct up_dev_s g_uart4priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, +#ifdef CONFIG_UART4_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart4priv, + }, + + .irq = STM32_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART4_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART4_BASE, + .tx_gpio = GPIO_UART4_TX, + .rx_gpio = GPIO_UART4_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART4_RXDMA + .rxdma_channel = DMAMAP_UART4_RX, + .rxfifo = g_uart4rxfifo, +#endif + .vector = up_interrupt_uart4, + +#ifdef CONFIG_UART4_RS485 + .rs485_dir_gpio = GPIO_UART4_RS485_DIR, +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART5 port. */ + +#ifdef CONFIG_STM32_UART5 +static struct up_dev_s g_uart5priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, +#ifdef CONFIG_UART5_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart5priv, + }, + + .irq = STM32_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART5_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART5_BASE, + .tx_gpio = GPIO_UART5_TX, + .rx_gpio = GPIO_UART5_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART5_RXDMA + .rxdma_channel = DMAMAP_UART5_RX, + .rxfifo = g_uart5rxfifo, +#endif + .vector = up_interrupt_uart5, + +#ifdef CONFIG_UART5_RS485 + .rs485_dir_gpio = GPIO_UART5_RS485_DIR, +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART6 port. */ + +#ifdef CONFIG_STM32_USART6 +static struct up_dev_s g_usart6priv = +{ + .dev = + { +#if CONSOLE_UART == 6 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART6_RXBUFSIZE, + .buffer = g_usart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART6_TXBUFSIZE, + .buffer = g_usart6txbuffer, + }, +#ifdef CONFIG_USART6_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart6priv, + }, + + .irq = STM32_IRQ_USART6, + .parity = CONFIG_USART6_PARITY, + .bits = CONFIG_USART6_BITS, + .stopbits2 = CONFIG_USART6_2STOP, + .baud = CONFIG_USART6_BAUD, + .apbclock = STM32_PCLK2_FREQUENCY, + .usartbase = STM32_USART6_BASE, + .tx_gpio = GPIO_USART6_TX, + .rx_gpio = GPIO_USART6_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART6_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART6_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART6_RTS, +#endif +#ifdef CONFIG_USART6_RXDMA + .rxdma_channel = DMAMAP_USART6_RX, + .rxfifo = g_usart6rxfifo, +#endif + .vector = up_interrupt_usart6, + +#ifdef CONFIG_USART6_RS485 + .rs485_dir_gpio = GPIO_USART6_RS485_DIR, +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART7 port. */ + +#ifdef CONFIG_STM32_UART7 +static struct up_dev_s g_uart7priv = +{ + .dev = + { +#if CONSOLE_UART == 7 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART7_RXBUFSIZE, + .buffer = g_uart7rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART7_TXBUFSIZE, + .buffer = g_uart7txbuffer, + }, +#ifdef CONFIG_UART7_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart7priv, + }, + + .irq = STM32_IRQ_UART7, + .parity = CONFIG_UART7_PARITY, + .bits = CONFIG_UART7_BITS, + .stopbits2 = CONFIG_UART7_2STOP, + .baud = CONFIG_UART7_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART7_BASE, + .tx_gpio = GPIO_UART7_TX, + .rx_gpio = GPIO_UART7_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART7_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART7_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART7_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART7_RTS, +#endif +#ifdef CONFIG_UART7_RXDMA + .rxdma_channel = DMAMAP_UART7_RX, + .rxfifo = g_uart7rxfifo, +#endif + .vector = up_interrupt_uart7, + +#ifdef CONFIG_UART7_RS485 + .rs485_dir_gpio = GPIO_UART7_RS485_DIR, +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART8 port. */ + +#ifdef CONFIG_STM32_UART8 +static struct up_dev_s g_uart8priv = +{ + .dev = + { +#if CONSOLE_UART == 8 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART8_RXBUFSIZE, + .buffer = g_uart8rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART8_TXBUFSIZE, + .buffer = g_uart8txbuffer, + }, +#ifdef CONFIG_UART8_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart8priv, + }, + + .irq = STM32_IRQ_UART8, + .parity = CONFIG_UART8_PARITY, + .bits = CONFIG_UART8_BITS, + .stopbits2 = CONFIG_UART8_2STOP, + .baud = CONFIG_UART8_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART8_BASE, + .tx_gpio = GPIO_UART8_TX, + .rx_gpio = GPIO_UART8_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART8_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART8_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART8_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART8_RTS, +#endif +#ifdef CONFIG_UART8_RXDMA + .rxdma_channel = DMAMAP_UART8_RX, + .rxfifo = g_uart8rxfifo, +#endif + .vector = up_interrupt_uart8, + +#ifdef CONFIG_UART8_RS485 + .rs485_dir_gpio = GPIO_UART8_RS485_DIR, +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +static struct up_dev_s * const uart_devs[STM32_NUSART] = +{ +#ifdef CONFIG_STM32_USART1 + [0] = &g_usart1priv, +#endif +#ifdef CONFIG_STM32_USART2 + [1] = &g_usart2priv, +#endif +#ifdef CONFIG_STM32_USART3 + [2] = &g_usart3priv, +#endif +#ifdef CONFIG_STM32_UART4 + [3] = &g_uart4priv, +#endif +#ifdef CONFIG_STM32_UART5 + [4] = &g_uart5priv, +#endif +#ifdef CONFIG_STM32_USART6 + [5] = &g_usart6priv, +#endif +#ifdef CONFIG_STM32_UART7 + [6] = &g_uart7priv, +#endif +#ifdef CONFIG_STM32_UART8 + [7] = &g_uart8priv, +#endif +}; + +#ifdef CONFIG_PM +static struct pm_callback_s g_serialcb = +{ + .notify = up_pm_notify, + .prepare = up_pm_prepare, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) +{ + uint32_t cr; + + /* Save the interrupt mask */ + + priv->ie = ie; + + /* And restore the interrupt state (see the interrupt enable/usage table above) */ + + cr = up_serialin(priv, STM32_USART_CR1_OFFSET); + cr &= ~(USART_CR1_USED_INTS); + cr |= (ie & (USART_CR1_USED_INTS)); + up_serialout(priv, STM32_USART_CR1_OFFSET, cr); + + cr = up_serialin(priv, STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_EIE; + cr |= (ie & USART_CR3_EIE); + up_serialout(priv, STM32_USART_CR3_OFFSET, cr); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) +{ + if (ie) + { + uint32_t cr1; + uint32_t cr3; + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------ ---------- + * USART_CR1_IDLEIE USART_SR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_SR_RXNE Received Data Ready to be Read + * " " USART_SR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_SR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_SR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_SR_PE Parity Error + * + * USART_CR2_LBDIE USART_SR_LBD Break Flag (not used) + * USART_CR3_EIE USART_SR_FE Framing Error + * " " USART_SR_NE Noise Error + * " " USART_SR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_SR_CTS CTS flag (not used) + */ + + cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); + cr3 = up_serialin(priv, STM32_USART_CR3_OFFSET); + + /* Return the current interrupt mask value for the used interrupts. Notice + * that this depends on the fact that none of the used interrupt enable bits + * overlap. This logic would fail if we needed the break interrupt! + */ + + *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); + } + + /* Disable all interrupts */ + + up_restoreusartint(priv, 0); +} + +/**************************************************************************** + * Name: up_dma_nextrx + * + * Description: + * Returns the index into the RX FIFO where the DMA will place the next + * byte that it receives. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_nextrx(struct up_dev_s *priv) +{ + size_t dmaresidual; + + dmaresidual = stm32_dmaresidual(priv->rxdma); + + return (RXDMA_BUFFER_SIZE - (int)dmaresidual); +} +#endif + +/**************************************************************************** + * Name: up_set_format + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void up_set_format(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + +#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) + /* This first implementation is for U[S]ARTs that support oversampling + * by 8 in additional to the standard oversampling by 16. + */ + + uint32_t usartdiv8; + uint32_t cr1; + uint32_t brr; + + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ + + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = 2 * usartdiv8 + */ + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + + cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); + if (usartdiv8 > 100) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); + up_serialout(priv, STM32_USART_BRR_OFFSET, brr); + +#else + + /* This second implementation is for U[S]ARTs that support fractional + * dividers. + */ + + uint32_t usartdiv32; + uint32_t mantissa; + uint32_t fraction; + uint32_t brr; + + /* Configure the USART Baud Rate. The baud rate for the receiver and + * transmitter (Rx and Tx) are both set to the same value as programmed + * in the Mantissa and Fraction values of USARTDIV. + * + * baud = fCK / (16 * usartdiv) + * usartdiv = fCK / (16 * baud) + * + * Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, 5 + * or PCLK2 for USART1) + * + * First calculate (NOTE: all stand baud values are even so dividing by two + * does not lose precision): + * + * usartdiv32 = 32 * usartdiv = fCK / (baud/2) + */ + + usartdiv32 = priv->apbclock / (priv->baud >> 1); + + /* The mantissa part is then */ + + mantissa = usartdiv32 >> 5; + brr = mantissa << USART_BRR_MANT_SHIFT; + + /* The fractional remainder (with rounding) */ + + fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; + brr |= fraction << USART_BRR_FRAC_SHIFT; + up_serialout(priv, STM32_USART_BRR_OFFSET, brr); +#endif + + /* Configure parity mode */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + /* Configure word length (parity uses one of configured bits) + * + * Default: 1 start, 8 data (no parity), n stop, OR + * 1 start, 7 data + parity, n stop + */ + + if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) + { + /* Select: 1 start, 8 data + parity, n stop, OR + * 1 start, 9 data (no parity), n stop. + */ + + regval |= USART_CR1_M; + } + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = up_serialin(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); +} +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Name: up_set_apb_clock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void up_set_apb_clock(struct uart_dev_s *dev, bool on) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32_USART1 + case STM32_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32_USART2 + case STM32_USART2_BASE: + rcc_en = RCC_APB1ENR_USART2EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_USART3 + case STM32_USART3_BASE: + rcc_en = RCC_APB1ENR_USART3EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART4 + case STM32_UART4_BASE: + rcc_en = RCC_APB1ENR_UART4EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART5 + case STM32_UART5_BASE: + rcc_en = RCC_APB1ENR_UART5EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_USART6 + case STM32_USART6_BASE: + rcc_en = RCC_APB2ENR_USART6EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32_UART7 + case STM32_UART7_BASE: + rcc_en = RCC_APB1ENR_UART7EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART8 + case STM32_UART8_BASE: + rcc_en = RCC_APB1ENR_UART8EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled in stm32_lowsetup(). + */ + + /* Enable USART APB1/2 clock */ + + up_set_apb_clock(dev, true); + + /* Configure pins for USART use */ + + stm32_configgpio(priv->tx_gpio); + stm32_configgpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_configgpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32_configgpio(config); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_configgpio(priv->rs485_dir_gpio); + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + } +#endif + + /* Configure CR2 */ + /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + + /* Configure STOP bits */ + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure CR1 */ + /* Clear TE, REm and all interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure CR3 */ + /* Clear CTSE, RTSE, and all interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE); + + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); + + /* Configure the USART line format and speed. */ + + up_set_format(dev); + + /* Enable Rx, Tx, and the USART */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + + /* Set up the cached interrupt enables value */ + + priv->ie = 0; + return OK; +} + +/**************************************************************************** + * Name: up_dma_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int result; + uint32_t regval; + + /* Do the basic UART setup first, unless we are the console */ + + if (!dev->isconsole) + { + result = up_setup(dev); + if (result != OK) + { + return result; + } + } + + /* Acquire the DMA channel. This should always succeed. */ + + priv->rxdma = stm32_dmachannel(priv->rxdma_channel); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Enable receive DMA for the UART */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval |= USART_CR3_DMAR; + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Disable all interrupts */ + + up_disableusartint(priv, NULL); + + /* Disable USART APB1/2 clock */ + + up_set_apb_clock(dev, false); + + /* Disable Rx, Tx, and the UART */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Release pins. "If the serial-attached device is powered down, the TX + * pin causes back-powering, potentially confusing the device to the point + * of complete lock-up." + * + * REVISIT: Is unconfiguring the pins appropriate for all device? If not, + * then this may need to be a configuration option. + */ + + stm32_unconfiggpio(priv->tx_gpio); + stm32_unconfiggpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_unconfiggpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + stm32_unconfiggpio(priv->rts_gpio); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_unconfiggpio(priv->rs485_dir_gpio); + } +#endif +} + +/**************************************************************************** + * Name: up_dma_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Perform the normal UART shutdown */ + + up_shutdown(dev); + + /* Stop the DMA channel */ + + stm32_dmastop(priv->rxdma); + + /* Release the DMA channel */ + + stm32_dmafree(priv->rxdma); + priv->rxdma = NULL; +} +#endif + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->vector); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt_common + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt_common(struct up_dev_s *priv) +{ + int passes; + bool handled; + + /* Report serial activity to the power management logic */ + +#if defined(CONFIG_PM) && CONFIG_PM_SERIAL_ACTIVITY > 0 + pm_activity(PM_IDLE_DOMAIN, CONFIG_PM_SERIAL_ACTIVITY); +#endif + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked USART status word. */ + + priv->sr = up_serialin(priv, STM32_USART_SR_OFFSET); + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_SR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_SR_RXNE Received Data Ready to be Read + * " " USART_SR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_SR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_SR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_SR_PE Parity Error + * + * USART_CR2_LBDIE USART_SR_LBD Break Flag (not used) + * USART_CR3_EIE USART_SR_FE Framing Error + * " " USART_SR_NE Noise Error + * " " USART_SR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_SR_CTS CTS flag (not used) + * + * NOTE: Some of these status bits must be cleared by explicity writing zero + * to the SR register: USART_SR_CTS, USART_SR_LBD. Note of those are currently + * being used. + */ + +#ifdef HAVE_RS485 + /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. + * Note - this should be first, to have the most recent TC bit value from + * SR register - sending data affects TC, but without refresh we will not + * know that... + */ + + if ((priv->sr & USART_SR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && + (priv->ie & USART_CR1_TXEIE) == 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); + } +#endif + + /* Handle incoming, receive bytes. */ + + if ((priv->sr & USART_SR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0) + { + /* Received data ready... process incoming bytes. NOTE the check for + * RXNEIE: We cannot call uart_recvchards of RX interrupts are disabled. + */ + + uart_recvchars(&priv->dev); + handled = true; + } + + /* We may still have to read from the DR register to clear any pending + * error conditions. + */ + + else if ((priv->sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE)) != 0) + { +#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) + /* These errors are cleared by writing the corresponding bit to the + * interrupt clear register (ICR). + */ + + up_serialout(priv, STM32_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF)); +#else + /* If an error occurs, read from DR to clear the error (data has + * been lost). If ORE is set along with RXNE then it tells you + * that the byte *after* the one in the data register has been + * lost, but the data register value is correct. That case will + * be handled above if interrupts are enabled. Otherwise, that + * good byte will be lost. + */ + + (void)up_serialin(priv, STM32_USART_RDR_OFFSET); +#endif + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & USART_SR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(&priv->dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif +#ifdef CONFIG_SERIAL_TERMIOS + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_STM32_USART_SINGLEWIRE + case TIOCSSINGLEWIRE: + { + /* Change the TX port to be open-drain/push-pull and enable/disable + * half-duplex mode. + */ + + uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); + +#if defined(CONFIG_STM32_STM32F10XX) + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD); + cr |= USART_CR3_HDSEL; + } + else + { + stm32_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFPP); + cr &= ~USART_CR3_HDSEL; + } +#else + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + cr |= USART_CR3_HDSEL; + } + else + { + stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + cr &= ~USART_CR3_HDSEL; + } +#endif + + up_serialout(priv, STM32_USART_CR3_OFFSET, cr); + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + up_set_format(dev); + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + +#ifdef CONFIG_USART_BREAKS + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + uint32_t cr2 = up_serialin(priv, STM32_USART_CR2_OFFSET); + up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + uint32_t cr1 = up_serialin(priv, STM32_USART_CR2_OFFSET); + up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rdr; + + /* Get the Rx byte */ + + rdr = up_serialin(priv, STM32_USART_RDR_OFFSET); + + /* Get the Rx byte plux error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint16_t ie; + + /* USART receive interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_SR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_SR_RXNE Received Data Ready to be Read + * " " USART_SR_ORE Overrun Error Detected + * USART_CR1_PEIE USART_SR_PE Parity Error + * + * USART_CR2_LBDIE USART_SR_LBD Break Flag (not used) + * USART_CR3_EIE USART_SR_FE Framing Error + * " " USART_SR_NE Noise Error + * " " USART_SR_ORE Overrun Error Detected + */ + + flags = enter_critical_section(); + ie = priv->ie; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_USART_ERRINTS + ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); +#else + ie |= USART_CR1_RXNEIE; +#endif +#endif + } + else + { + ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); + } + + /* Then set the new interrupt state */ + + up_restoreusartint(priv, ie); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_RXNE) != 0); +} +#endif + +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32_gpiowrite(priv->rts_gpio, upper); + return upper; + } + +#else + if (priv->iflow) + { + /* Is the RX buffer full? */ + + if (upper) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral. When hardware RTS is enabled, this will + * prevent more data from coming in. + * + * This function is only called when UART recv buffer is full, + * that is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts + * when buffer is read empty and thus we do not have to re- + * enable Rx interrupts. + */ + + uart_disablerxint(dev); + return true; + } + + /* No.. The RX buffer is empty */ + + else + { + /* We might leave Rx interrupt disabled if full recv buffer was + * read empty. Enable Rx interrupt to make sure that more input is + * received. + */ + + uart_enablerxint(dev); + } + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: up_dma_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int c = 0; + + if (up_dma_nextrx(priv) != priv->rxdmanext) + { + c = priv->rxfifo[priv->rxdmanext]; + + priv->rxdmanext++; + if (priv->rxdmanext == RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* RX DMA buffer full. RX paused, RTS line pulled up to prevent + * more input data from other end. + */ + } + else +#endif + { + priv->rxdmanext = 0; + } + } + } + + return c; +} +#endif + +/**************************************************************************** + * Name: up_dma_reenable + * + * Description: + * Call to re-enable RX DMA. + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) +static void up_dma_reenable(struct up_dev_s *priv) +{ + /* Configure for non-circular DMA reception into the RX fifo */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Start the DMA channel, and arrange for callbacks at the full point in + * the FIFO. After buffer gets full, hardware flow-control kicks in and + * DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* En/disable DMA reception. + * + * Note that it is not safe to check for available bytes and immediately + * pass them to uart_recvchars as that could potentially recurse back + * to us again. Instead, bytes must wait until the next up_dma_poll or + * DMA event. + */ + + priv->rxenable = enable; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif +} +#endif + +/**************************************************************************** + * Name: up_dma_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static bool up_dma_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Compare our receive pointer to the current DMA pointer, if they + * do not match, then there are bytes to be received. + */ + + return (up_dma_nextrx(priv) != priv->rxdmanext); +} +#endif + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + } +#endif + + up_serialout(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ---------------------------- ---------- + * USART_CR1_TCIE USART_SR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_SR_TXE Transmit Data Register Empty + * USART_CR3_CTSIE USART_SR_CTS CTS flag (not used) + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uint16_t ie = priv->ie | USART_CR1_TXEIE; + + /* If RS-485 is supported on this U[S]ART, then also enable the + * transmission complete interrupt. + */ + +# ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + ie |= USART_CR1_TCIE; + } +# endif + + up_restoreusartint(priv, ie); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_TXE) != 0); +} + +/**************************************************************************** + * Name: up_interrupt_u[s]art[n] + * + * Description: + * Interrupt handlers for U[S]ART[n] where n=1,..,6. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USART1 +static int up_interrupt_usart1(int irq, void *context) +{ + return up_interrupt_common(&g_usart1priv); +} +#endif + +#ifdef CONFIG_STM32_USART2 +static int up_interrupt_usart2(int irq, void *context) +{ + return up_interrupt_common(&g_usart2priv); +} +#endif + +#ifdef CONFIG_STM32_USART3 +static int up_interrupt_usart3(int irq, void *context) +{ + return up_interrupt_common(&g_usart3priv); +} +#endif + +#ifdef CONFIG_STM32_UART4 +static int up_interrupt_uart4(int irq, void *context) +{ + return up_interrupt_common(&g_uart4priv); +} +#endif + +#ifdef CONFIG_STM32_UART5 +static int up_interrupt_uart5(int irq, void *context) +{ + return up_interrupt_common(&g_uart5priv); +} +#endif + +#ifdef CONFIG_STM32_USART6 +static int up_interrupt_usart6(int irq, void *context) +{ + return up_interrupt_common(&g_usart6priv); +} +#endif + +#ifdef CONFIG_STM32_UART7 +static int up_interrupt_uart7(int irq, void *context) +{ + return up_interrupt_common(&g_uart7priv); +} +#endif + +#ifdef CONFIG_STM32_UART8 +static int up_interrupt_uart8(int irq, void *context) +{ + return up_interrupt_common(&g_uart8priv); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxcallback + * + * Description: + * This function checks the current DMA state and calls the generic + * serial stack when bytes appear to be available. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = (struct up_dev_s *)arg; + + if (priv->rxenable && up_dma_rxavailable(&priv->dev)) + { + uart_recvchars(&priv->dev); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && + (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif + } +} +#endif + +/**************************************************************************** + * Name: up_pm_notify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * None - The driver already agreed to transition to the low power + * consumption state when when it returned OK to the prepare() call. + * + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + switch (pmstate) + { + case(PM_NORMAL): + { + /* Logic for PM_NORMAL goes here */ + + } + break; + + case(PM_IDLE): + { + /* Logic for PM_IDLE goes here */ + + } + break; + + case(PM_STANDBY): + { + /* Logic for PM_STANDBY goes here */ + + } + break; + + case(PM_SLEEP): + { + /* Logic for PM_SLEEP goes here */ + + } + break; + + default: + /* Should not get here */ + break; + } +} +#endif + +/**************************************************************************** + * Name: up_pm_prepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * Zero - (OK) means the event was successfully processed and that the + * driver is prepared for the PM state change. + * + * Non-zero - means that the driver is not prepared to perform the tasks + * needed achieve this power setting and will cause the state + * change to be aborted. NOTE: The prepare() method will also + * be called when reverting from lower back to higher power + * consumption modes (say because another driver refused a + * lower power state change). Drivers are not permitted to + * return non-zero values when reverting back to higher power + * consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + /* Logic to prepare for a reduced power state goes here. */ + + return OK; +} +#endif +#endif /* HAVE_UART */ +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ +#ifdef HAVE_UART + unsigned i; + + /* Disable all USART interrupts */ + + for (i = 0; i < STM32_NUSART; i++) + { + if (uart_devs[i]) + { + up_disableusartint(uart_devs[i], NULL); + } + } + + /* Configure whichever one is the console */ + +#if CONSOLE_UART > 0 + up_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* HAVE UART */ +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef HAVE_UART + char devname[16]; + unsigned i; + unsigned minor = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Register to receive power management callbacks */ + +#ifdef CONFIG_PM + ret = pm_register(&g_serialcb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + /* Register the console */ + +#if CONSOLE_UART > 0 + (void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + (void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#ifdef SERIAL_HAVE_CONSOLE_DMA + /* If we need to re-initialise the console to enable DMA do that here. */ + + up_dma_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strcpy(devname, "/dev/ttySx"); + + for (i = 0; i < STM32_NUSART; i++) + { + /* Don't create a device for non-configured ports. */ + + if (uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* Don't create a device for the console - we did that above */ + + if (uart_devs[i]->dev.isconsole) + { + continue; + } +#endif + + /* Register USARTs as devices in increasing order */ + + devname[9] = '0' + minor++; + (void)uart_register(devname, &uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: stm32_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_USART1_RXDMA + if (g_usart1priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); + } +#endif + +#ifdef CONFIG_USART2_RXDMA + if (g_usart2priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); + } +#endif + +#ifdef CONFIG_USART3_RXDMA + if (g_usart3priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); + } +#endif + +#ifdef CONFIG_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); + } +#endif + +#ifdef CONFIG_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); + } +#endif + +#ifdef CONFIG_USART6_RXDMA + if (g_usart6priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart6priv.rxdma, 0, &g_usart6priv); + } +#endif + +#ifdef CONFIG_UART7_RXDMA + if (g_uart7priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart7priv.rxdma, 0, &g_uart7priv); + } +#endif + +#ifdef CONFIG_UART8_RXDMA + if (g_uart8priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart8priv.rxdma, 0, &g_uart8priv); + } +#endif + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct up_dev_s *priv = uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + up_disableusartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreusartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..eed9ea9845b58d849bee1db75454ebed984b1e52 --- /dev/null +++ b/arch/arm/src/stm32/stm32_spi.c @@ -0,0 +1,1703 @@ +/************************************************************************************ + * arm/arm/src/stm32/stm32_spi.c + * + * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status must be + * provided by board-specific logic. They are implementations of the select + * and status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including stm32_spibus_initialize()) + * are provided by common STM32 logic. To use this common SPI logic on your + * board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. Add a calls to stm32_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by stm32_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************c********************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_dma.h" +#include "stm32_spi.h" + +#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3) || \ + defined(CONFIG_STM32_SPI4) || defined(CONFIG_STM32_SPI5) || defined(CONFIG_STM32_SPI6) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* SPI interrupts */ + +#ifdef CONFIG_STM32_SPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_STM32_SPI_INTERRUPTS) && defined(CONFIG_STM32_SPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/* SPI DMA priority */ + +#ifdef CONFIG_STM32_SPI_DMA + +# if defined(CONFIG_SPI_DMAPRIO) +# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO +# elif defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32L15XX) +# define SPI_DMA_PRIO DMA_CCR_PRIMED +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define SPI_DMA_PRIO DMA_SCR_PRIMED +# else +# error "Unknown STM32 DMA" +# endif + +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32L15XX) +# if (SPI_DMA_PRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# if (SPI_DMA_PRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif +# else +# error "Unknown STM32 DMA" +# endif + +#endif + +/* DMA channel configuration */ + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32L15XX) +# define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC ) +# define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC ) +# define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS ) +# define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS ) +# define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR) +# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR) +# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR) +# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR) +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_P2M) +# define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_P2M) +# define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_P2M) +# define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_P2M) +# define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_M2P) +# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P) +# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_M2P) +# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P) +#else +# error "Unknown STM32 DMA" +#endif + + +/* Debug ****************************************************************************/ +/* Check if (non-standard) SPI debug is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct stm32_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ + uint32_t spiclock; /* Clocking for the SPI module */ +#ifdef CONFIG_STM32_SPI_INTERRUPTS + uint8_t spiirq; /* SPI IRQ number */ +#endif +#ifdef CONFIG_STM32_SPI_DMA + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the RX DMA */ + uint8_t rxch; /* The RX DMA channel number */ + uint8_t txch; /* The TX DMA channel number */ + DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */ + DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ + sem_t rxsem; /* Wait for RX DMA to complete */ + sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + int8_t nbits; /* Width of word in bits (8 or 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* Helpers */ + +static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv, uint8_t offset); +static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint8_t offset, + uint16_t value); +static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv); +static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t byte); +static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv); + +/* DMA support */ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmarxwait(FAR struct stm32_spidev_s *priv); +static void spi_dmatxwait(FAR struct stm32_spidev_s *priv); +static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv); +static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv); +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, + FAR void *rxbuffer, FAR void *rxdummy, size_t nwords); +static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, + FAR const void *txbuffer, FAR const void *txdummy, size_t nwords); +static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv); +static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); +#endif + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + +/* Initialization */ + +static void spi_bus_initialize(FAR struct stm32_spidev_s *priv); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI1 +static const struct spi_ops_s g_sp1iops = +{ + .lock = spi_lock, + .select = stm32_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = stm32_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi1dev = +{ + .spidev = { &g_sp1iops }, + .spibase = STM32_SPI1_BASE, + .spiclock = STM32_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI1, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI1_RX, + .txch = DMACHAN_SPI1_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32_SPI2 +static const struct spi_ops_s g_sp2iops = +{ + .lock = spi_lock, + .select = stm32_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi2register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi2dev = +{ + .spidev = { &g_sp2iops }, + .spibase = STM32_SPI2_BASE, + .spiclock = STM32_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI2, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI2_RX, + .txch = DMACHAN_SPI2_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32_SPI3 +static const struct spi_ops_s g_sp3iops = +{ + .lock = spi_lock, + .select = stm32_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi3register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi3dev = +{ + .spidev = { &g_sp3iops }, + .spibase = STM32_SPI3_BASE, + .spiclock = STM32_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI3, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI3_RX, + .txch = DMACHAN_SPI3_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32_SPI4 +static const struct spi_ops_s g_sp4iops = +{ + .lock = spi_lock, + .select = stm32_spi4select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32_spi4status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi4cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi4register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi4dev = +{ + .spidev = { &g_sp4iops }, + .spibase = STM32_SPI4_BASE, + .spiclock = STM32_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI4, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI4_RX, + .txch = DMACHAN_SPI4_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32_SPI5 +static const struct spi_ops_s g_sp5iops = +{ + .lock = spi_lock, + .select = stm32_spi5select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32_spi5status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi5cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi5register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi5dev = +{ + .spidev = { &g_sp5iops }, + .spibase = STM32_SPI5_BASE, + .spiclock = STM32_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI5, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI5_RX, + .txch = DMACHAN_SPI5_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32_SPI6 +static const struct spi_ops_s g_sp6iops = +{ + .lock = spi_lock, + .select = stm32_spi6select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32_spi6status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi6register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32_spidev_s g_spi6dev = +{ + .spidev = { &g_sp6iops }, + .spibase = STM32_SPI6_BASE, + .spiclock = STM32_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32_SPI_INTERRUPTS + .spiirq = STM32_IRQ_SPI6, +#endif +#ifdef CONFIG_STM32_SPI_DMA + .rxch = DMACHAN_SPI6_RX, + .txch = DMACHAN_SPI6_TX, +#endif +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv, uint8_t offset) +{ + return getreg16(priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint8_t offset, uint16_t value) +{ + putreg16(value, priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_readword + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ************************************************************************************/ + +static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0); + + /* Then return the received byte */ + + return spi_getreg(priv, STM32_SPI_DR_OFFSET); +} + +/************************************************************************************ + * Name: spi_writeword + * + * Description: + * Write one byte to SPI + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word) +{ + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_TXE) == 0); + + /* Then send the byte */ + + spi_putreg(priv, STM32_SPI_DR_OFFSET, word); +} + +/************************************************************************************ + * Name: spi_16bitmode + * + * Description: + * Check if the SPI is operating in 16-bit mode + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: 16-bit mode, false: 8-bit mode + * + ************************************************************************************/ + +static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv) +{ + return ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_DFF) != 0); +} + +/************************************************************************************ + * Name: spi_dmarxwait + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmarxwait(FAR struct stm32_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->rxsem) != 0 || priv->rxresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwait + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmatxwait(FAR struct stm32_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->txsem) != 0 || priv->txresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmarxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv) +{ + (void)sem_post(&priv->rxsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv) +{ + (void)sem_post(&priv->txsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->rxresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmarxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->txresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmatxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxsetup + * + * Description: + * Setup to perform RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, + FAR void *rxdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA16_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA8_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA8NULL_CONFIG; + } + } + + /* Configure the RX DMA */ + + stm32_dmasetup(priv->rxdma, priv->spibase + STM32_SPI_DR_OFFSET, + (uint32_t)rxbuffer, nwords, priv->rxccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxsetup + * + * Description: + * Setup to perform TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer, + FAR const void *txdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA16_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA8_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA8NULL_CONFIG; + } + } + + /* Setup the TX DMA */ + + stm32_dmasetup(priv->txdma, priv->spibase + STM32_SPI_DR_OFFSET, + (uint32_t)txbuffer, nwords, priv->txccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxstart + * + * Description: + * Start RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv) +{ + priv->rxresult = 0; + stm32_dmastart(priv->rxdma, spi_dmarxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxstart + * + * Description: + * Start TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv) +{ + priv->txresult = 0; + stm32_dmastart(priv->txdma, spi_dmatxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_modifycr1 + * + * Description: + * Clear and set bits in the CR1 register + * + * Input Parameters: + * priv - Device-specific state data + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits, uint16_t clrbits) +{ + uint16_t cr1; + cr1 = spi_getreg(priv, STM32_SPI_CR1_OFFSET); + cr1 &= ~clrbits; + cr1 |= setbits; + spi_putreg(priv, STM32_SPI_CR1_OFFSET, cr1); +} + +/************************************************************************************ + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ************************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/************************************************************************************ + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint16_t setbits; + uint32_t actual; + + /* Limit to max possible (if STM32_SPI_CLK_MAX is defined in board.h) */ + + if (frequency > STM32_SPI_CLK_MAX) + { + frequency = STM32_SPI_CLK_MAX; + } + + /* Has the frequency changed? */ + + if (frequency != priv->frequency) + { + /* Choices are limited by PCLK frequency with a set of divisors */ + + if (frequency >= priv->spiclock >> 1) + { + /* More than fPCLK/2. This is as fast as we can go */ + + setbits = SPI_CR1_FPCLCKd2; /* 000: fPCLK/2 */ + actual = priv->spiclock >> 1; + } + else if (frequency >= priv->spiclock >> 2) + { + /* Between fPCLCK/2 and fPCLCK/4, pick the slower */ + + setbits = SPI_CR1_FPCLCKd4; /* 001: fPCLK/4 */ + actual = priv->spiclock >> 2; + } + else if (frequency >= priv->spiclock >> 3) + { + /* Between fPCLCK/4 and fPCLCK/8, pick the slower */ + + setbits = SPI_CR1_FPCLCKd8; /* 010: fPCLK/8 */ + actual = priv->spiclock >> 3; + } + else if (frequency >= priv->spiclock >> 4) + { + /* Between fPCLCK/8 and fPCLCK/16, pick the slower */ + + setbits = SPI_CR1_FPCLCKd16; /* 011: fPCLK/16 */ + actual = priv->spiclock >> 4; + } + else if (frequency >= priv->spiclock >> 5) + { + /* Between fPCLCK/16 and fPCLCK/32, pick the slower */ + + setbits = SPI_CR1_FPCLCKd32; /* 100: fPCLK/32 */ + actual = priv->spiclock >> 5; + } + else if (frequency >= priv->spiclock >> 6) + { + /* Between fPCLCK/32 and fPCLCK/64, pick the slower */ + + setbits = SPI_CR1_FPCLCKd64; /* 101: fPCLK/64 */ + actual = priv->spiclock >> 6; + } + else if (frequency >= priv->spiclock >> 7) + { + /* Between fPCLCK/64 and fPCLCK/128, pick the slower */ + + setbits = SPI_CR1_FPCLCKd128; /* 110: fPCLK/128 */ + actual = priv->spiclock >> 7; + } + else + { + /* Less than fPCLK/128. This is as slow as we can go */ + + setbits = SPI_CR1_FPCLCKd256; /* 111: fPCLK/256 */ + actual = priv->spiclock >> 8; + } + + spi_modifycr1(priv, 0, SPI_CR1_SPE); + spi_modifycr1(priv, setbits, SPI_CR1_BR_MASK); + spi_modifycr1(priv, SPI_CR1_SPE, 0); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + + spivdbg("Frequency %d->%d\n", frequency, actual); + + priv->frequency = frequency; + priv->actual = actual; + } + + return priv->actual; +} + +/************************************************************************************ + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint16_t setbits; + uint16_t clrbits; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR1 appropriately */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setbits = 0; + clrbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setbits = SPI_CR1_CPHA; + clrbits = SPI_CR1_CPOL; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setbits = SPI_CR1_CPOL; + clrbits = SPI_CR1_CPHA; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + clrbits = 0; + break; + + default: + return; + } + + spi_modifycr1(priv, 0, SPI_CR1_SPE); + spi_modifycr1(priv, setbits, clrbits); + spi_modifycr1(priv, SPI_CR1_SPE, 0); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/************************************************************************************ + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint16_t setbits; + uint16_t clrbits; + + spivdbg("nbits=%d\n", nbits); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set CR1 appropriately */ + + switch (nbits) + { + case -8: + setbits = SPI_CR1_LSBFIRST; + clrbits = SPI_CR1_DFF; + break; + + case 8: + setbits = 0; + clrbits = SPI_CR1_DFF | SPI_CR1_LSBFIRST; + break; + + case -16: + setbits = SPI_CR1_DFF | SPI_CR1_LSBFIRST; + clrbits = 0; + break; + + case 16: + setbits = SPI_CR1_DFF; + clrbits = SPI_CR1_LSBFIRST; + break; + + default: + return; + } + + spi_modifycr1(priv, 0, SPI_CR1_SPE); + spi_modifycr1(priv, setbits, clrbits); + spi_modifycr1(priv, SPI_CR1_SPE, 0); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/************************************************************************************ + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t regval; + uint16_t ret; + + DEBUGASSERT(priv && priv->spibase); + + spi_writeword(priv, wd); + ret = spi_readword(priv); + + /* Check and clear any error flags (Reading from the SR clears the error flags) */ + + regval = spi_getreg(priv, STM32_SPI_SR_OFFSET); + + spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval); + UNUSED(regval); + + return ret; +} + +/************************************************************************************ + * Name: spi_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchaned in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if !defined(CONFIG_STM32_SPI_DMA) || defined(CONFIG_STM32_DMACAPABLE) +#if !defined(CONFIG_STM32_SPI_DMA) +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#else +static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#endif +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + DEBUGASSERT(priv && priv->spibase); + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Exchange one word */ + + word = spi_send(dev, word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t)spi_send(dev, (uint16_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } +} +#endif /* !CONFIG_STM32_SPI_DMA || CONFIG_STM32_DMACAPABLE */ + +/**************************************************************************** + * Name: spi_exchange (with DMA capability) + * + * Description: + * Exchange a block of data on SPI using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI_DMA +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + +#ifdef CONFIG_STM32_DMACAPABLE + if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) || + (rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr))) + { + /* Unsupported memory region, fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + } + else +#endif + { + static uint16_t rxdummy = 0xffff; + static const uint16_t txdummy = 0xffff; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + DEBUGASSERT(priv && priv->spibase); + + /* Setup DMAs */ + + spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords); + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords); + + /* Start the DMAs */ + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + + /* Then wait for each to complete */ + + spi_dmarxwait(priv); + spi_dmatxwait(priv); + } +} +#endif /* CONFIG_STM32_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_bus_initialize + * + * Description: + * Initialize the selected SPI bus in its default state (Master, 8-bit, mode 0, etc.) + * + * Input Parameter: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_bus_initialize(FAR struct stm32_spidev_s *priv) +{ + uint16_t setbits; + uint16_t clrbits; + + /* Configure CR1. Default configuration: + * Mode 0: CPHA=0 and CPOL=0 + * Master: MSTR=1 + * 8-bit: DFF=0 + * MSB tranmitted first: LSBFIRST=0 + * Replace NSS with SSI & SSI=1: SSI=1 SSM=1 (prevents MODF error) + * Two lines full duplex: BIDIMODE=0 BIDIOIE=(Don't care) and RXONLY=0 + */ + + clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST | + SPI_CR1_RXONLY | SPI_CR1_DFF | SPI_CR1_BIDIOE | SPI_CR1_BIDIMODE; + setbits = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM; + spi_modifycr1(priv, setbits, clrbits); + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* CRCPOLY configuration */ + + spi_putreg(priv, STM32_SPI_CRCPR_OFFSET, 7); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + /* Initialize the SPI semaphores that is used to wait for DMA completion */ + +#ifdef CONFIG_STM32_SPI_DMA + sem_init(&priv->rxsem, 0, 0); + sem_init(&priv->txsem, 0, 0); + + /* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel. + * if the channel is not available, then stm32_dmachannel() will block and wait + * until the channel becomes available. WARNING: If you have another device sharing + * a DMA channel with SPI and the code never releases that channel, then the call + * to stm32_dmachannel() will hang forever in this function! Don't let your + * design do that! + */ + + priv->rxdma = stm32_dmachannel(priv->rxch); + priv->txdma = stm32_dmachannel(priv->txch); + DEBUGASSERT(priv->rxdma && priv->txdma); + + spi_putreg(priv, STM32_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); +#endif + + /* Enable spi */ + + spi_modifycr1(priv, SPI_CR1_SPE, 0); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32_spibus_initialize(int bus) +{ + FAR struct stm32_spidev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); + +#ifdef CONFIG_STM32_SPI1 + if (bus == 1) + { + /* Select SPI1 */ + + priv = &g_spi1dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI1 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI1_SCK); + stm32_configgpio(GPIO_SPI1_MISO); + stm32_configgpio(GPIO_SPI1_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32_SPI2 + if (bus == 2) + { + /* Select SPI2 */ + + priv = &g_spi2dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI2 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI2_SCK); + stm32_configgpio(GPIO_SPI2_MISO); + stm32_configgpio(GPIO_SPI2_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32_SPI3 + if (bus == 3) + { + /* Select SPI3 */ + + priv = &g_spi3dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI3 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI3_SCK); + stm32_configgpio(GPIO_SPI3_MISO); + stm32_configgpio(GPIO_SPI3_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32_SPI4 + if (bus == 4) + { + /* Select SPI4 */ + + priv = &g_spi4dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI4 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI4_SCK); + stm32_configgpio(GPIO_SPI4_MISO); + stm32_configgpio(GPIO_SPI4_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32_SPI5 + if (bus == 5) + { + /* Select SPI5 */ + + priv = &g_spi5dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI5 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI5_SCK); + stm32_configgpio(GPIO_SPI5_MISO); + stm32_configgpio(GPIO_SPI5_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32_SPI6 + if (bus == 6) + { + /* Select SPI6 */ + + priv = &g_spi6dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI6 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI6_SCK); + stm32_configgpio(GPIO_SPI6_MISO); + stm32_configgpio(GPIO_SPI6_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif + { + spidbg("ERROR: Unsupbused SPI bus: %d\n", bus); + return NULL; + } + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 || CONFIG_STM32_SPI4 || CONFIG_STM32_SPI5 || CONFIG_STM32_SPI6 */ diff --git a/arch/arm/src/stm32/stm32_spi.h b/arch/arm/src/stm32/stm32_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..a9d336cb8607317fd3115ae07a18fd77687e5c6a --- /dev/null +++ b/arch/arm/src/stm32/stm32_spi.h @@ -0,0 +1,214 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_spi.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_STM32_SPI_H +#define __ARCH_ARM_STC_STM32_STM32_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * bus number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32_spibus_initialize(int bus); + +/************************************************************************************ + * Name: stm32_spi1/2/...select and stm32_spi1/2/...status + * + * Description: + * The external functions, stm32_spi1/2/...select, stm32_spi1/2/...status, and + * stm32_spi1/2/...cmddata must be provided by board-specific logic. These are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * (including stm32_spibus_initialize()) are provided by common STM32 logic. To use this + * common SPI logic on your board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2/...select() and stm32_spi1/2/...status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, then + * provide stm32_spi1/2/...cmddata() functions in your board-specific logic. + * These functions will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Add a calls to stm32_spibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by stm32_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_SPI1 +void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32_SPI2 +void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32_SPI3 +void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32_SPI4 +void stm32_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi4cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32_SPI5 +void stm32_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi5status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi5cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32_SPI6 +void stm32_spi6select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32_spi6status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32_spi6cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: stm32_spi1/2/...register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based MMC/SD + * driver when an SD card is inserted or removed, then CONFIG_SPI_CALLBACK should + * be defined and the following function(s) must be implemented. These functions + * implements the registercallback method of the SPI interface (see + * include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_STM32_SPI1 +int stm32_spi1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32_SPI2 +int stm32_spi2register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32_SPI3 +int stm32_spi3register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32_SPI4 +int stm32_spi4register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32_SPI5 +int stm32_spi5register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32_SPI6 +int stm32_spi6register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32_STM32_SPI_H */ + diff --git a/arch/arm/src/stm32/stm32_start.c b/arch/arm/src/stm32/stm32_start.c new file mode 100644 index 0000000000000000000000000000000000000000..8e58e862a9ed94ad48523be4c9cf8cbfa5ca0b96 --- /dev/null +++ b/arch/arm/src/stm32/stm32_start.c @@ -0,0 +1,326 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_start.c + * + * Copyright (C) 2009, 2011-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void stm32_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: stm32_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define stm32_fpuconfig() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + stm32_clockconfig(); + stm32_fpuconfig(); + stm32_lowsetup(); + stm32_gpioinit(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = _START_BSS; dest < _END_BSS; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = _DATA_INIT, dest = _START_DATA; dest < _END_DATA; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stm32_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + stm32_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/stm32/stm32_syscfg.h b/arch/arm/src/stm32/stm32_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..8098779f2a6dcc8b61141584f25d789f50a04548 --- /dev/null +++ b/arch/arm/src/stm32/stm32_syscfg.h @@ -0,0 +1,62 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/stm32_syscfg.h + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_SYSCFG_H +#define __ARCH_ARM_SRC_STM32_STM32_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_syscfg.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_syscfg.h" +#elif defined(CONFIG_STM32_STM32F30XX) +# include "chip/stm32f30xxx_syscfg.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_syscfg.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_syscfg.h" +#endif + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_STM32_SYSCFG_H */ diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c new file mode 100644 index 0000000000000000000000000000000000000000..c7d3b8350ce72557e389c92dc0261e174331830f --- /dev/null +++ b/arch/arm/src/stm32/stm32_tim.c @@ -0,0 +1,1093 @@ +/************************************************************************************ + * arm/arm/src/stm32/stm32_tim.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With modifications and updates by: + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_tim.h" + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. Such special purposes include: + * + * - To generate modulated outputs for such things as motor control. If CONFIG_STM32_TIMn + * is defined then the CONFIG_STM32_TIMn_PWM may also be defined to indicate that + * the timer is intended to be used for pulsed output modulation. + * + * - To control periodic ADC input sampling. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_ADC may also be defined to indicate that timer "n" is intended + * to be used for that purpose. + * + * - To control periodic DAC outputs. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_DAC may also be defined to indicate that timer "n" is intended + * to be used for that purpose. + * + * - To use a Quadrature Encoder. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_QE may also be defined to indicate that timer "n" is intended + * to be used for that purpose. + * + * In any of these cases, the timer will not be used by this timer module. + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined (CONFIG_STM32_TIM1_ADC) || \ + defined(CONFIG_STM32_TIM1_DAC) || defined(CONFIG_STM32_TIM1_QE) +# undef CONFIG_STM32_TIM1 +#endif +#if defined(CONFIG_STM32_TIM2_PWM) || defined (CONFIG_STM32_TIM2_ADC) || \ + defined(CONFIG_STM32_TIM2_DAC) || defined(CONFIG_STM32_TIM2_QE) +# undef CONFIG_STM32_TIM2 +#endif +#if defined(CONFIG_STM32_TIM3_PWM) || defined (CONFIG_STM32_TIM3_ADC) || \ + defined(CONFIG_STM32_TIM3_DAC) || defined(CONFIG_STM32_TIM3_QE) +# undef CONFIG_STM32_TIM3 +#endif +#if defined(CONFIG_STM32_TIM4_PWM) || defined (CONFIG_STM32_TIM4_ADC) || \ + defined(CONFIG_STM32_TIM4_DAC) || defined(CONFIG_STM32_TIM4_QE) +# undef CONFIG_STM32_TIM4 +#endif +#if defined(CONFIG_STM32_TIM5_PWM) || defined (CONFIG_STM32_TIM5_ADC) || \ + defined(CONFIG_STM32_TIM5_DAC) || defined(CONFIG_STM32_TIM5_QE) +# undef CONFIG_STM32_TIM5 +#endif +#if defined(CONFIG_STM32_TIM6_PWM) || defined (CONFIG_STM32_TIM6_ADC) || \ + defined(CONFIG_STM32_TIM6_DAC) || defined(CONFIG_STM32_TIM6_QE) +# undef CONFIG_STM32_TIM6 +#endif +#if defined(CONFIG_STM32_TIM7_PWM) || defined (CONFIG_STM32_TIM7_ADC) || \ + defined(CONFIG_STM32_TIM7_DAC) || defined(CONFIG_STM32_TIM7_QE) +# undef CONFIG_STM32_TIM7 +#endif +#if defined(CONFIG_STM32_TIM8_PWM) || defined (CONFIG_STM32_TIM8_ADC) || \ + defined(CONFIG_STM32_TIM8_DAC) || defined(CONFIG_STM32_TIM8_QE) +# undef CONFIG_STM32_TIM8 +#endif +#if defined(CONFIG_STM32_TIM9_PWM) || defined (CONFIG_STM32_TIM9_ADC) || \ + defined(CONFIG_STM32_TIM9_DAC) || defined(CONFIG_STM32_TIM9_QE) +# undef CONFIG_STM32_TIM9 +#endif +#if defined(CONFIG_STM32_TIM10_PWM) || defined (CONFIG_STM32_TIM10_ADC) || \ + defined(CONFIG_STM32_TIM10_DAC) || defined(CONFIG_STM32_TIM10_QE) +# undef CONFIG_STM32_TIM10 +#endif +#if defined(CONFIG_STM32_TIM11_PWM) || defined (CONFIG_STM32_TIM11_ADC) || \ + defined(CONFIG_STM32_TIM11_DAC) || defined(CONFIG_STM32_TIM11_QE) +# undef CONFIG_STM32_TIM11 +#endif +#if defined(CONFIG_STM32_TIM12_PWM) || defined (CONFIG_STM32_TIM12_ADC) || \ + defined(CONFIG_STM32_TIM12_DAC) || defined(CONFIG_STM32_TIM12_QE) +# undef CONFIG_STM32_TIM12 +#endif +#if defined(CONFIG_STM32_TIM13_PWM) || defined (CONFIG_STM32_TIM13_ADC) || \ + defined(CONFIG_STM32_TIM13_DAC) || defined(CONFIG_STM32_TIM13_QE) +# undef CONFIG_STM32_TIM13 +#endif +#if defined(CONFIG_STM32_TIM14_PWM) || defined (CONFIG_STM32_TIM14_ADC) || \ + defined(CONFIG_STM32_TIM14_DAC) || defined(CONFIG_STM32_TIM14_QE) +# undef CONFIG_STM32_TIM14 +#endif + +#if defined(CONFIG_STM32_TIM1) +# if defined(GPIO_TIM1_CH1OUT) ||defined(GPIO_TIM1_CH2OUT)||\ + defined(GPIO_TIM1_CH3OUT) ||defined(GPIO_TIM1_CH4OUT) +# define HAVE_TIM1_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32_TIM2) +# if defined(GPIO_TIM2_CH1OUT) ||defined(GPIO_TIM2_CH2OUT)||\ + defined(GPIO_TIM2_CH3OUT) ||defined(GPIO_TIM2_CH4OUT) +# define HAVE_TIM2_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32_TIM3) +# if defined(GPIO_TIM3_CH1OUT) ||defined(GPIO_TIM3_CH2OUT)||\ + defined(GPIO_TIM3_CH3OUT) ||defined(GPIO_TIM3_CH4OUT) +# define HAVE_TIM3_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32_TIM4) +# if defined(GPIO_TIM4_CH1OUT) ||defined(GPIO_TIM4_CH2OUT)||\ + defined(GPIO_TIM4_CH3OUT) ||defined(GPIO_TIM4_CH4OUT) +# define HAVE_TIM4_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32_TIM5) +# if defined(GPIO_TIM5_CH1OUT) ||defined(GPIO_TIM5_CH2OUT)||\ + defined(GPIO_TIM5_CH3OUT) ||defined(GPIO_TIM5_CH4OUT) +# define HAVE_TIM5_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32_TIM8) +# if defined(GPIO_TIM8_CH1OUT) ||defined(GPIO_TIM8_CH2OUT)||\ + defined(GPIO_TIM8_CH3OUT) ||defined(GPIO_TIM8_CH4OUT) +# define HAVE_TIM8_GPIOCONFIG 1 +#endif +#endif + + +/* This module then only compiles if there are enabled timers that are not intended for + * some other purpose. + */ + +#if defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || defined(CONFIG_STM32_TIM3) || \ + defined(CONFIG_STM32_TIM4) || defined(CONFIG_STM32_TIM5) || defined(CONFIG_STM32_TIM6) || \ + defined(CONFIG_STM32_TIM7) || defined(CONFIG_STM32_TIM8) + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* TIM Device Structure */ + +struct stm32_tim_priv_s +{ + struct stm32_tim_ops_s *ops; + stm32_tim_mode_t mode; + uint32_t base; /* TIMn base address */ +}; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/* Get a 16-bit register value by offset */ + +static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg16(((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/* Put a 16-bit register value by offset */ + +static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset, + uint16_t value) +{ + putreg16(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/* Modify a 16-bit register value by offset */ + +static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(((struct stm32_tim_priv_s *)dev)->base + offset, clearbits, setbits); +} + +/* Get a 32-bit register value by offset. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + */ + +static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg32(((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/* Put a 32-bit register value by offset. This applies only for the STM32 F4 + * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + */ + +static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset, + uint32_t value) +{ + putreg32(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_BTIM_EGR_OFFSET); + val |= ATIM_EGR_UG; + stm32_putreg16(dev, STM32_BTIM_EGR_OFFSET, val); +} + +static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET); + val |= ATIM_CR1_CEN; + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val); +} + +static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET); + val &= ~ATIM_CR1_CEN; + stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val); +} + +/* Reset timer into system default state, but do not affect output/input pins */ + +static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev) +{ + ((struct stm32_tim_priv_s *)dev)->mode = STM32_TIM_MODE_DISABLED; + stm32_tim_disable(dev); +} + +#if defined(HAVE_TIM1_GPIOCONFIG)||defined(HAVE_TIM2_GPIOCONFIG)||\ + defined(HAVE_TIM3_GPIOCONFIG)||defined(HAVE_TIM4_GPIOCONFIG)||\ + defined(HAVE_TIM5_GPIOCONFIG)||defined(HAVE_TIM8_GPIOCONFIG) +static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode) +{ + /* TODO: Add support for input capture and bipolar dual outputs for TIM8 */ + + if (mode & STM32_TIM_CH_MODE_MASK) + { + stm32_configgpio(cfg); + } + else + { + stm32_unconfiggpio(cfg); + } +} +#endif + +/************************************************************************************ + * Basic Functions + ************************************************************************************/ + +static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq) +{ + int prescaler; + + ASSERT(dev); + + /* Disable Timer? */ + + if (freq == 0) + { + stm32_tim_disable(dev); + return 0; + } + +#if STM32_NATIM > 0 + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE || + ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE) + { + prescaler = STM32_TIM18_FREQUENCY / freq; + } + else +#endif + { + prescaler = STM32_TIM27_FREQUENCY / freq; + } + + /* We need to decrement value for '1', but only, if we are allowed to + * not to cause underflow. Check for overflow. + */ + + if (prescaler > 0) + { + prescaler--; + } + + if (prescaler > 0xffff) + { + prescaler = 0xffff; + } + + stm32_putreg16(dev, STM32_BTIM_PSC_OFFSET, prescaler); + stm32_tim_enable(dev); + + return prescaler; +} + +static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, + uint32_t period) +{ + ASSERT(dev); + stm32_putreg32(dev, STM32_BTIM_ARR_OFFSET, period); +} + +static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, + int (*handler)(int irq, void *context), + int source) +{ + int vectorno; + + ASSERT(dev); + ASSERT(source == 0); + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32_TIM2 + case STM32_TIM2_BASE: + vectorno = STM32_IRQ_TIM2; + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case STM32_TIM3_BASE: + vectorno = STM32_IRQ_TIM3; + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case STM32_TIM4_BASE: + vectorno = STM32_IRQ_TIM4; + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case STM32_TIM5_BASE: + vectorno = STM32_IRQ_TIM5; + break; +#endif +#if STM32_NBTIM > 0 +#ifdef CONFIG_STM32_TIM6 + case STM32_TIM6_BASE: + vectorno = STM32_IRQ_TIM6; + break; +#endif +#endif +#if STM32_NBTIM > 1 +#ifdef CONFIG_STM32_TIM7 + case STM32_TIM7_BASE: + vectorno = STM32_IRQ_TIM7; + break; +#endif +#endif +#if STM32_NATIM > 0 + /* TODO: add support for multiple sources and callbacks */ + +#ifdef CONFIG_STM32_TIM1 + case STM32_TIM1_BASE: + vectorno = STM32_IRQ_TIM1UP; + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case STM32_TIM8_BASE: + vectorno = STM32_IRQ_TIM8UP; + break; +#endif +#endif + default: + return ERROR; + } + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(vectorno); + irq_detach(vectorno); + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(vectorno, handler); + up_enable_irq(vectorno); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); +#endif + + return OK; +} + +static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source) +{ + ASSERT(dev); + stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UIE); +} + +static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source) +{ + ASSERT(dev); + stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, ATIM_DIER_UIE, 0); +} + +static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source) +{ + stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~ATIM_SR_UIF); +} + +/************************************************************************************ + * General Functions + ************************************************************************************/ + +static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode) +{ + uint16_t val = ATIM_CR1_CEN | ATIM_CR1_ARPE; + + ASSERT(dev); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + +#if STM32_NBTIM > 0 + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE +#endif +#if STM32_NBTIM > 1 + || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE +#endif +#if STM32_NBTIM > 0 + ) + { + return ERROR; + } +#endif + + /* Decode operational modes */ + + switch (mode & STM32_TIM_MODE_MASK) + { + case STM32_TIM_MODE_DISABLED: + val = 0; + break; + + case STM32_TIM_MODE_DOWN: + val |= ATIM_CR1_DIR; + + case STM32_TIM_MODE_UP: + break; + + case STM32_TIM_MODE_UPDOWN: + val |= ATIM_CR1_CENTER1; + // Our default: Interrupts are generated on compare, when counting down + break; + + case STM32_TIM_MODE_PULSE: + val |= ATIM_CR1_OPM; + break; + + default: return ERROR; + } + + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val); + +#if STM32_NATIM > 0 + /* Advanced registers require Main Output Enable */ + + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE || + ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE) + { + stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE); + } +#endif + + return OK; +} + +static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel, + stm32_tim_channel_t mode) +{ + uint16_t ccmr_orig = 0; + uint16_t ccmr_val = 0; + uint16_t ccmr_mask = 0xff; + uint16_t ccer_val = stm32_getreg16(dev, STM32_GTIM_CCER_OFFSET); + uint8_t ccmr_offset = STM32_GTIM_CCMR1_OFFSET; + + ASSERT(dev); + + /* Further we use range as 0..3; if channel=0 it will also overflow here */ + + if (--channel > 4) return ERROR; + + /* Assume that channel is disabled and polarity is active high */ + + ccer_val &= ~(3 << (channel << 2)); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + +#if STM32_NBTIM > 0 + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE +#endif +#if STM32_NBTIM > 1 + || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE +#endif +#if STM32_NBTIM > 0 + ) + { + return ERROR; + } +#endif + + /* Decode configuration */ + + switch (mode & STM32_TIM_CH_MODE_MASK) + { + case STM32_TIM_CH_DISABLED: + break; + + case STM32_TIM_CH_OUTPWM: + ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) + ATIM_CCMR1_OC1PE; + ccer_val |= ATIM_CCER_CC1E << (channel << 2); + break; + + default: + return ERROR; + } + + /* Set polarity */ + + if (mode & STM32_TIM_CH_POLARITY_NEG) + { + ccer_val |= ATIM_CCER_CC1P << (channel << 2); + } + + /* Define its position (shift) and get register offset */ + + if (channel & 1) + { + ccmr_val <<= 8; + ccmr_mask <<= 8; + } + + if (channel > 1) + { + ccmr_offset = STM32_GTIM_CCMR2_OFFSET; + } + + ccmr_orig = stm32_getreg16(dev, ccmr_offset); + ccmr_orig &= ~ccmr_mask; + ccmr_orig |= ccmr_val; + stm32_putreg16(dev, ccmr_offset, ccmr_orig); + stm32_putreg16(dev, STM32_GTIM_CCER_OFFSET, ccer_val); + + /* set GPIO */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32_TIM2 + case STM32_TIM2_BASE: + switch (channel) + { +#if defined(GPIO_TIM2_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM2_CH1OUT, mode); + break; +#endif +#if defined(GPIO_TIM2_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM2_CH2OUT, mode); + break; +#endif +#if defined(GPIO_TIM2_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM2_CH3OUT, mode); + break; +#endif +#if defined(GPIO_TIM2_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM2_CH4OUT, mode); + break; +#endif + default: + return ERROR; + } + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case STM32_TIM3_BASE: + switch (channel) + { +#if defined(GPIO_TIM3_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM3_CH1OUT, mode); + break; +#endif +#if defined(GPIO_TIM3_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM3_CH2OUT, mode); + break; +#endif +#if defined(GPIO_TIM3_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM3_CH3OUT, mode); + break; +#endif +#if defined(GPIO_TIM3_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM3_CH4OUT, mode); + break; +#endif + default: + return ERROR; + } + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case STM32_TIM4_BASE: + switch (channel) + { +#if defined(GPIO_TIM4_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM4_CH1OUT, mode); + break; +#endif +#if defined(GPIO_TIM4_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM4_CH2OUT, mode); + break; +#endif +#if defined(GPIO_TIM4_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM4_CH3OUT, mode); + break; +#endif +#if defined(GPIO_TIM4_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM4_CH4OUT, mode); + break; +#endif + default: return ERROR; + } + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case STM32_TIM5_BASE: + switch (channel) + { +#if defined(GPIO_TIM5_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM5_CH1OUT, mode); + break; +#endif +#if defined(GPIO_TIM5_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM5_CH2OUT, mode); + break; +#endif +#if defined(GPIO_TIM5_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM5_CH3OUT, mode); + break; +#endif +#if defined(GPIO_TIM5_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM5_CH4OUT, mode); + break; +#endif + default: return ERROR; + } + break; +#endif + +#if STM32_NATIM > 0 +#ifdef CONFIG_STM32_TIM1 + case STM32_TIM1_BASE: + switch (channel) + { +#if defined(GPIO_TIM1_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM1_CH1OUT, mode); break; +#endif +#if defined(GPIO_TIM1_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM1_CH2OUT, mode); break; +#endif +#if defined(GPIO_TIM1_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM1_CH3OUT, mode); break; +#endif +#if defined(GPIO_TIM1_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM1_CH4OUT, mode); break; +#endif + default: return ERROR; + } + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case STM32_TIM8_BASE: + switch (channel) + { +#if defined(GPIO_TIM8_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM8_CH1OUT, mode); break; +#endif +#if defined(GPIO_TIM8_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM8_CH2OUT, mode); break; +#endif +#if defined(GPIO_TIM8_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM8_CH3OUT, mode); break; +#endif +#if defined(GPIO_TIM8_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM8_CH4OUT, mode); break; +#endif + default: + return ERROR; + } + break; +#endif +#endif + default: + return ERROR; + } + + return OK; +} + +static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel, + uint32_t compare) +{ + ASSERT(dev); + + switch (channel) + { + case 1: + stm32_putreg32(dev, STM32_GTIM_CCR1_OFFSET, compare); + break; + case 2: + stm32_putreg32(dev, STM32_GTIM_CCR2_OFFSET, compare); + break; + case 3: + stm32_putreg32(dev, STM32_GTIM_CCR3_OFFSET, compare); + break; + case 4: + stm32_putreg32(dev, STM32_GTIM_CCR4_OFFSET, compare); + break; + default: + return ERROR; + } + return OK; +} + +static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel) +{ + ASSERT(dev); + + switch (channel) + { + case 1: + return stm32_getreg32(dev, STM32_GTIM_CCR1_OFFSET); + case 2: + return stm32_getreg32(dev, STM32_GTIM_CCR2_OFFSET); + case 3: + return stm32_getreg32(dev, STM32_GTIM_CCR3_OFFSET); + case 4: + return stm32_getreg32(dev, STM32_GTIM_CCR4_OFFSET); + } + + return ERROR; +} + +/************************************************************************************ + * Advanced Functions + ************************************************************************************/ + +/* TODO: Advanced functions for the STM32_ATIM */ + +/************************************************************************************ + * Device Structures, Instantiation + ************************************************************************************/ + +struct stm32_tim_ops_s stm32_tim_ops = +{ + .setmode = &stm32_tim_setmode, + .setclock = &stm32_tim_setclock, + .setperiod = &stm32_tim_setperiod, + .setchannel = &stm32_tim_setchannel, + .setcompare = &stm32_tim_setcompare, + .getcapture = &stm32_tim_getcapture, + .setisr = &stm32_tim_setisr, + .enableint = &stm32_tim_enableint, + .disableint = &stm32_tim_disableint, + .ackint = &stm32_tim_ackint +}; + +#ifdef CONFIG_STM32_TIM2 +struct stm32_tim_priv_s stm32_tim2_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM2_BASE, +}; +#endif + +#ifdef CONFIG_STM32_TIM3 +struct stm32_tim_priv_s stm32_tim3_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM3_BASE, +}; +#endif + +#ifdef CONFIG_STM32_TIM4 +struct stm32_tim_priv_s stm32_tim4_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM4_BASE, +}; +#endif + +#ifdef CONFIG_STM32_TIM5 +struct stm32_tim_priv_s stm32_tim5_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM5_BASE, +}; +#endif + +#if STM32_NBTIM > 0 +#ifdef CONFIG_STM32_TIM6 +struct stm32_tim_priv_s stm32_tim6_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM6_BASE, +}; +#endif +#endif + +#if STM32_NBTIM > 1 +#ifdef CONFIG_STM32_TIM7 +struct stm32_tim_priv_s stm32_tim7_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM7_BASE, +}; +#endif +#endif + +#if STM32_NATIM > 0 + +#ifdef CONFIG_STM32_TIM1 +struct stm32_tim_priv_s stm32_tim1_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM1_BASE, +}; +#endif + +#ifdef CONFIG_STM32_TIM8 +struct stm32_tim_priv_s stm32_tim8_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM8_BASE, +}; +#endif + +#endif + +/************************************************************************************ + * Public Function - Initialization + ************************************************************************************/ + +FAR struct stm32_tim_dev_s *stm32_tim_init(int timer) +{ + struct stm32_tim_dev_s *dev = NULL; + + /* Get structure and enable power */ + + switch (timer) + { +#ifdef CONFIG_STM32_TIM2 + case 2: + dev = (struct stm32_tim_dev_s *)&stm32_tim2_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM2EN); + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case 3: + dev = (struct stm32_tim_dev_s *)&stm32_tim3_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM3EN); + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case 4: + dev = (struct stm32_tim_dev_s *)&stm32_tim4_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM4EN); + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case 5: + dev = (struct stm32_tim_dev_s *)&stm32_tim5_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM5EN); + break; +#endif + +#if STM32_NBTIM > 0 +#ifdef CONFIG_STM32_TIM6 + case 6: + dev = (struct stm32_tim_dev_s *)&stm32_tim6_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM6EN); + break; +#endif +#endif +#if STM32_NBTIM > 1 +#ifdef CONFIG_STM32_TIM7 + case 7: + dev = (struct stm32_tim_dev_s *)&stm32_tim7_priv; + modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_TIM7EN); + break; +#endif +#endif + +#if STM32_NATIM > 0 +#ifdef CONFIG_STM32_TIM1 + case 1: + dev = (struct stm32_tim_dev_s *)&stm32_tim1_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case 8: + dev = (struct stm32_tim_dev_s *)&stm32_tim8_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM8EN); + break; +#endif +#endif + default: + return NULL; + } + + /* Is device already allocated */ + + if (((struct stm32_tim_priv_s *)dev)->mode != STM32_TIM_MODE_UNUSED) + { + return NULL; + } + + stm32_tim_reset(dev); + + return dev; +} + +/* TODO: Detach interrupts, and close down all TIM Channels */ + +int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev) +{ + ASSERT(dev); + + /* Disable power */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32_TIM2 + case STM32_TIM2_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM2EN, 0); + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case STM32_TIM3_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM3EN, 0); + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case STM32_TIM4_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM4EN, 0); + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case STM32_TIM5_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM5EN, 0); + break; +#endif +#if STM32_NBTIM > 0 +#ifdef CONFIG_STM32_TIM6 + case STM32_TIM6_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM6EN, 0); + break; +#endif +#endif +#if STM32_NBTIM > 1 +#ifdef CONFIG_STM32_TIM7 + case STM32_TIM7_BASE: + modifyreg32(STM32_RCC_APB1ENR, RCC_APB1ENR_TIM7EN, 0); + break; +#endif +#endif + +#if STM32_NATIM > 0 +#ifdef CONFIG_STM32_TIM1 + case STM32_TIM1_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM1EN, 0); + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case STM32_TIM8_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM8EN, 0); + break; +#endif +#endif + default: + return ERROR; + } + + /* Mark it as free */ + + ((struct stm32_tim_priv_s *)dev)->mode = STM32_TIM_MODE_UNUSED; + + return OK; +} + +#endif /* defined(CONFIG_STM32_TIM1 || ... || TIM8) */ diff --git a/arch/arm/src/stm32/stm32_tim.h b/arch/arm/src/stm32/stm32_tim.h new file mode 100644 index 0000000000000000000000000000000000000000..2d3b01a683b71c835641b858bbed7006151e1ebe --- /dev/null +++ b/arch/arm/src/stm32/stm32_tim.h @@ -0,0 +1,215 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_tim.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With modifications and updates by: + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_TIM_H +#define __ARCH_ARM_SRC_STM32_STM32_TIM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_tim.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Helpers **************************************************************************/ + +#define STM32_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) +#define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq)) +#define STM32_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period)) +#define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode)) +#define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp)) +#define STM32_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch)) +#define STM32_TIM_SETISR(d,hnd,s) ((d)->ops->setisr(d,hnd,s)) +#define STM32_TIM_ENABLEINT(d,s) ((d)->ops->enableint(d,s)) +#define STM32_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s)) +#define STM32_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* TIM Device Structure */ + +struct stm32_tim_dev_s +{ + struct stm32_tim_ops_s *ops; +}; + +/* TIM Modes of Operation */ + +typedef enum +{ + STM32_TIM_MODE_UNUSED = -1, + + /* One of the following */ + + STM32_TIM_MODE_MASK = 0x0310, + STM32_TIM_MODE_DISABLED = 0x0000, + STM32_TIM_MODE_UP = 0x0100, + STM32_TIM_MODE_DOWN = 0x0110, + STM32_TIM_MODE_UPDOWN = 0x0200, + STM32_TIM_MODE_PULSE = 0x0300, + + /* One of the following */ + + STM32_TIM_MODE_CK_INT = 0x0000, +//STM32_TIM_MODE_CK_INT_TRIG = 0x0400, +//STM32_TIM_MODE_CK_EXT = 0x0800, +//STM32_TIM_MODE_CK_EXT_TRIG = 0x0C00, + + /* Clock sources, OR'ed with CK_EXT */ + +//STM32_TIM_MODE_CK_CHINVALID = 0x0000, +//STM32_TIM_MODE_CK_CH1 = 0x0001, +//STM32_TIM_MODE_CK_CH2 = 0x0002, +//STM32_TIM_MODE_CK_CH3 = 0x0003, +//STM32_TIM_MODE_CK_CH4 = 0x0004 + + /* Todo: external trigger block */ + +} stm32_tim_mode_t; + +/* TIM Channel Modes */ + +typedef enum +{ + STM32_TIM_CH_DISABLED = 0x00, + + /* Common configuration */ + + STM32_TIM_CH_POLARITY_POS = 0x00, + STM32_TIM_CH_POLARITY_NEG = 0x01, + + /* MODES: */ + + STM32_TIM_CH_MODE_MASK = 0x06, + + /* Output Compare Modes */ + + STM32_TIM_CH_OUTPWM = 0x04, /** Enable standard PWM mode, active high when counter < compare */ +//STM32_TIM_CH_OUTCOMPARE = 0x06, + + // TODO other modes ... as PWM capture, ENCODER and Hall Sensor +//STM32_TIM_CH_INCAPTURE = 0x10, +//STM32_TIM_CH_INPWM = 0x20 +//STM32_TIM_CH_DRIVE_OC -- open collector mode + +} stm32_tim_channel_t; + +/* TIM Operations */ + +struct stm32_tim_ops_s +{ + /* Basic Timers */ + + int (*setmode)(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode); + int (*setclock)(FAR struct stm32_tim_dev_s *dev, uint32_t freq); + void (*setperiod)(FAR struct stm32_tim_dev_s *dev, uint32_t period); + + /* General and Advanced Timers Adds */ + + int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, stm32_tim_channel_t mode); + int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, uint32_t compare); + int (*getcapture)(FAR struct stm32_tim_dev_s *dev, uint8_t channel); + + /* Timer interrupts */ + + int (*setisr)(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source); + void (*enableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*disableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*ackint)(FAR struct stm32_tim_dev_s *dev, int source); +}; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/* Power-up timer and get its structure */ + +FAR struct stm32_tim_dev_s *stm32_tim_init(int timer); + +/* Power-down timer, mark it as unused */ + +int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev); + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the form /dev/timer0 + * timer - the timer number. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIMER +int stm32_timer_initialize(FAR const char *devpath, int timer); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_TIM_H */ diff --git a/arch/arm/src/stm32/stm32_tim_lowerhalf.c b/arch/arm/src/stm32/stm32_tim_lowerhalf.c new file mode 100644 index 0000000000000000000000000000000000000000..5de8549c71d65d2535323875ce337329026f618f --- /dev/null +++ b/arch/arm/src/stm32/stm32_tim_lowerhalf.c @@ -0,0 +1,756 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_tim_lowerhalf.c + * + * Copyright (C) 2015 Wail Khemir. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Wail Khemir + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include "stm32_tim.h" + +#if defined(CONFIG_TIMER) && \ + (defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || \ + defined(CONFIG_STM32_TIM3) || defined(CONFIG_STM32_TIM4) || \ + defined(CONFIG_STM32_TIM5) || defined(CONFIG_STM32_TIM6) || \ + defined(CONFIG_STM32_TIM7) || defined(CONFIG_STM32_TIM8) || \ + defined(CONFIG_STM32_TIM9) || defined(CONFIG_STM32_TIM10) || \ + defined(CONFIG_STM32_TIM11) || defined(CONFIG_STM32_TIM12) || \ + defined(CONFIG_STM32_TIM13) || defined(CONFIG_STM32_TIM14)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_TIM1_RES 16 +#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) +# define STM32_TIM2_RES 16 +#else +# define STM32_TIM2_RES 32 +#endif +#if defined(CONFIG_STM32_STM32L20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_TIM3_RES 32 +# define STM32_TIM4_RES 32 +#else +# define STM32_TIM3_RES 16 +# define STM32_TIM4_RES 16 +#endif +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +# define STM32_TIM5_RES 16 +#else +# define STM32_TIM5_RES 32 +#endif +#define STM32_TIM6_RES 16 +#define STM32_TIM7_RES 16 +#define STM32_TIM8_RES 16 +#define STM32_TIM9_RES 16 +#define STM32_TIM10_RES 16 +#define STM32_TIM11_RES 16 +#define STM32_TIM12_RES 16 +#define STM32_TIM13_RES 16 +#define STM32_TIM14_RES 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct stm32_lowerhalf_s +{ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + FAR struct stm32_tim_dev_s *tim; /* stm32 timer driver */ + tccb_t usrhandler; /* Current user interrupt handler */ + const xcpt_t timhandler; /* Current timer interrupt handler */ + bool started; /* True: Timer has been started */ + const uint8_t resolution; /* Number of bits in the timer (16 or 32 bits) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Interrupt handling *******************************************************/ + +#ifdef CONFIG_STM32_TIM1 +static int stm32_tim1_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM2 +static int stm32_tim2_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM3 +static int stm32_tim3_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM4 +static int stm32_tim4_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM5 +static int stm32_tim5_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM6 +static int stm32_tim6_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM7 +static int stm32_tim7_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM8 +static int stm32_tim8_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM9 +static int stm32_tim9_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM10 +static int stm32_tim10_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM11 +static int stm32_tim11_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM12 +static int stm32_tim12_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM13 +static int stm32_tim13_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_STM32_TIM14 +static int stm32_tim14_interrupt(int irq, FAR void *context); +#endif + +static int stm32_timer_handler(FAR struct stm32_lowerhalf_s *lower); + +/* "Lower half" driver methods **********************************************/ + +static int stm32_start(FAR struct timer_lowerhalf_s *lower); +static int stm32_stop(FAR struct timer_lowerhalf_s *lower); +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout); +static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t handler); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_timer_ops = +{ + .start = stm32_start, + .stop = stm32_stop, + .getstatus = NULL, + .settimeout = stm32_settimeout, + .sethandler = stm32_sethandler, + .ioctl = NULL, +}; + +#ifdef CONFIG_STM32_TIM1 +static struct stm32_lowerhalf_s g_tim1_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim1_interrupt, + .resolution = STM32_TIM1_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM2 +static struct stm32_lowerhalf_s g_tim2_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim2_interrupt, + .resolution = STM32_TIM2_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM3 +static struct stm32_lowerhalf_s g_tim3_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim3_interrupt, + .resolution = STM32_TIM3_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM4 +static struct stm32_lowerhalf_s g_tim4_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim4_interrupt, + .resolution = STM32_TIM4_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM5 +static struct stm32_lowerhalf_s g_tim5_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim5_interrupt, + .resolution = STM32_TIM5_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM6 +static struct stm32_lowerhalf_s g_tim6_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim6_interrupt, + .resolution = STM32_TIM6_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM7 +static struct stm32_lowerhalf_s g_tim7_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim7_interrupt, + .resolution = STM32_TIM7_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM8 +static struct stm32_lowerhalf_s g_tim8_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim8_interrupt, + .resolution = STM32_TIM8_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM9 +static struct stm32_lowerhalf_s g_tim9_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim9_interrupt, + .resolution = STM32_TIM9_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM10 +static struct stm32_lowerhalf_s g_tim10_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim10_interrupt, + .resolution = STM32_TIM10_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM11 +static struct stm32_lowerhalf_s g_tim11_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim11_interrupt, + .resolution = STM32_TIM11_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM12 +static struct stm32_lowerhalf_s g_tim12_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim12_interrupt, + .resolution = STM32_TIM12_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM13 +static struct stm32_lowerhalf_s g_tim13_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim13_interrupt, + .resolution = STM32_TIM13_RES, +}; +#endif + +#ifdef CONFIG_STM32_TIM14 +static struct stm32_lowerhalf_s g_tim14_lowerhalf = +{ + .ops = &g_timer_ops, + .timhandler = stm32_tim14_interrupt, + .resolution = STM32_TIM14_RES, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timN_interrupt, N=1..14 + * + * Description: + * Individual interrupt handlers for each timer + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_TIM1 +static int stm32_tim1_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim1_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM2 +static int stm32_tim2_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim2_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM3 +static int stm32_tim3_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim3_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM4 +static int stm32_tim4_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim4_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM5 +static int stm32_tim5_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim5_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM6 +static int stm32_tim6_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim6_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM7 +static int stm32_tim7_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim7_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM8 +static int stm32_tim8_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim8_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM9 +static int stm32_tim9_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim9_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM10 +static int stm32_tim10_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim10_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM11 +static int stm32_tim11_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim11_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM12 +static int stm32_tim12_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim12_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM13 +static int stm32_tim13_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim13_lowerhalf); +} +#endif + +#ifdef CONFIG_STM32_TIM14 +static int stm32_tim14_interrupt(int irq, FAR void *context) +{ + return stm32_timer_handler(&g_tim14_lowerhalf); +} +#endif + +/**************************************************************************** + * Name: stm32_timer_handler + * + * Description: + * timer interrupt handler + * + * Input Parameters: + * + * Returned Values: + * + ****************************************************************************/ + +static int stm32_timer_handler(FAR struct stm32_lowerhalf_s *lower) +{ + uint32_t next_interval_us = 0; + + STM32_TIM_ACKINT(lower->tim, 0); + + if (lower->usrhandler(&next_interval_us)) + { + if (next_interval_us > 0) + { + STM32_TIM_SETPERIOD(lower->tim, next_interval_us); + } + } + else + { + stm32_stop((struct timer_lowerhalf_s *)lower); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_start(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + + if (!priv->started) + { + STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_UP); + + if (priv->usrhandler != NULL) + { + STM32_TIM_SETISR(priv->tim, priv->timhandler, 0); + STM32_TIM_ENABLEINT(priv->tim, 0); + } + + priv->started = true; + return OK; + } + + /* Return EBUSY to indicate that the timer was already running */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_stop(struct timer_lowerhalf_s *lower) +{ + struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + + if (priv->started) + { + STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_DISABLED); + STM32_TIM_DISABLEINT(priv->tim, 0); + STM32_TIM_SETISR(priv->tim, 0, 0); + priv->started = false; + return OK; + } + + /* Return ENODEV to indicate that the timer was not running */ + + return -ENODEV; +} + +/**************************************************************************** + * Name: stm32_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeout) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint64_t maxtimeout; + + if (priv->started) + { + return -EPERM; + } + + maxtimeout = (1 << priv->resolution) - 1; + if (timeout > maxtimeout) + { + uint64_t freq = (maxtimeout * 1000000) / timeout; + STM32_TIM_SETCLOCK(priv->tim, freq); + STM32_TIM_SETPERIOD(priv->tim, maxtimeout); + } + else + { + STM32_TIM_SETCLOCK(priv->tim, 1000000); + STM32_TIM_SETPERIOD(priv->tim, timeout); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_sethandler + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower, + tccb_t newhandler) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + + irqstate_t flags = enter_critical_section(); + + /* Get the old handler return value */ + + tccb_t oldhandler = priv->usrhandler; + + /* Save the new handler */ + + priv->usrhandler = newhandler; + + if (newhandler != NULL && priv->started) + { + STM32_TIM_SETISR(priv->tim, priv->timhandler, 0); + STM32_TIM_ENABLEINT(priv->tim, 0); + } + else + { + STM32_TIM_DISABLEINT(priv->tim, 0); + STM32_TIM_SETISR(priv->tim, 0, 0); + } + + leave_critical_section(flags); + return oldhandler; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer's number. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int stm32_timer_initialize(FAR const char *devpath, int timer) +{ + FAR struct stm32_lowerhalf_s *lower; + + switch (timer) + { +#ifdef CONFIG_STM32_TIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM3 + case 3: + lower = &g_tim3_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM4 + case 4: + lower = &g_tim4_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM5 + case 5: + lower = &g_tim5_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM6 + case 6: + lower = &g_tim6_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM7 + case 7: + lower = &g_tim7_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM8 + case 8: + lower = &g_tim8_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM9 + case 9: + lower = &g_tim9_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM10 + case 10: + lower = &g_tim10_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM11 + case 11: + lower = &g_tim11_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM12 + case 12: + lower = &g_tim12_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM13 + case 13: + lower = &g_tim13_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32_TIM14 + case 14: + lower = &g_tim14_lowerhalf; + break; +#endif + default: + return -ENODEV; + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->usrhandler = NULL; + lower->tim = stm32_tim_init(timer); + + if (lower->tim == NULL) + { + return -EINVAL; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be used with timer_unregister(). + * REVISIT: The returned handle is discard here. + */ + + FAR void *drvr = timer_register(devpath, + (FAR struct timer_lowerhalf_s *)lower); + if (drvr == NULL) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'depath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + + return -EEXIST; + } + + return OK; +} + +#endif /* CONFIG_TIMER */ diff --git a/arch/arm/src/stm32/stm32_timerisr.c b/arch/arm/src/stm32/stm32_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..b9c3fa1ab3eda55e2a960282ff364a1a978b5676 --- /dev/null +++ b/arch/arm/src/stm32/stm32_timerisr.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +#undef CONFIG_STM32_SYSTICK_HCLKd8 /* Power up default is HCLK, not HCLK/8 */ + /* And I don't know now to re-configure it yet */ + +#ifdef CONFIG_STM32_SYSTICK_HCLKd8 +# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / 8 / CLK_TCK) - 1) +#else +# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / CLK_TCK) - 1) +#endif + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set correctly */ + +#if 0 /* Does not work. Comes up with HCLK source and I can't change it */ + regval = getreg32(NVIC_SYSTICK_CTRL); +#ifdef CONFIG_STM32_SYSTICK_HCLKd8 + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STM32_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(STM32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/stm32/stm32_uart.h b/arch/arm/src/stm32/stm32_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..56ae3035439a47bdfe321d081ecf871361ddba85 --- /dev/null +++ b/arch/arm/src/stm32/stm32_uart.h @@ -0,0 +1,358 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_uart.h + * + * Copyright (C) 2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_STM32_UART_H +#define __ARCH_ARM_STC_STM32_STM32_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32_STM32L15XX) +# include "chip/stm32l15xxx_uart.h" +#elif defined(CONFIG_STM32_STM32F10XX) +# include "chip/stm32f10xxx_uart.h" +#elif defined(CONFIG_STM32_STM32F20XX) +# include "chip/stm32f20xxx_uart.h" +#elif defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f30xxx_uart.h" +#elif defined(CONFIG_STM32_STM32F40XX) +# include "chip/stm32f40xxx_uart.h" +#else +# error "Unsupported STM32 UART" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Make sure that we have not enabled more U[S]ARTs than are supported by the + * device. + */ + +#if STM32_NUSART < 8 || !defined(CONFIG_STM32_HAVE_UART8) +# undef CONFIG_STM32_UART8 +#endif +#if STM32_NUSART < 7 || !defined(CONFIG_STM32_HAVE_UART7) +# undef CONFIG_STM32_UART7 +#endif +#if STM32_NUSART < 6 || !defined(CONFIG_STM32_HAVE_USART6) +# undef CONFIG_STM32_USART6 +#endif +#if STM32_NUSART < 5 || !defined(CONFIG_STM32_HAVE_UART5) +# undef CONFIG_STM32_UART5 +#endif +#if STM32_NUSART < 4 || !defined(CONFIG_STM32_HAVE_UART4) +# undef CONFIG_STM32_UART4 +#endif +#if STM32_NUSART < 3 || !defined(CONFIG_STM32_HAVE_USART3) +# undef CONFIG_STM32_USART3 +#endif +#if STM32_NUSART < 2 +# undef CONFIG_STM32_USART2 +#endif +#if STM32_NUSART < 1 +# undef CONFIG_STM32_USART1 +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32_USART1) || defined(CONFIG_STM32_USART2) || \ + defined(CONFIG_STM32_USART3) || defined(CONFIG_STM32_UART4) || \ + defined(CONFIG_STM32_UART5) || defined(CONFIG_STM32_USART6) || \ + defined(CONFIG_STM32_UART7) || defined(CONFIG_STM32_UART8) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART1) +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART2) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART3) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART4) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART5) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART6) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 6 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART7) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 7 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART8) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define CONSOLE_UART 8 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration */ + +#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_UART4_RXDMA +# undef CONFIG_UART5_RXDMA +# undef CONFIG_USART6_RXDMA +# undef CONFIG_UART7_RXDMA +# undef CONFIG_UART8_RXDMA +#endif + +/* Disable the DMA configuration on all unused USARTs */ + +#ifndef CONFIG_STM32_USART1 +# undef CONFIG_USART1_RXDMA +#endif + +#ifndef CONFIG_STM32_USART2 +# undef CONFIG_USART2_RXDMA +#endif + +#ifndef CONFIG_STM32_USART3 +# undef CONFIG_USART3_RXDMA +#endif + +#ifndef CONFIG_STM32_UART4 +# undef CONFIG_UART4_RXDMA +#endif + +#ifndef CONFIG_STM32_UART5 +# undef CONFIG_UART5_RXDMA +#endif + +#ifndef CONFIG_STM32_USART6 +# undef CONFIG_USART6_RXDMA +#endif + +#ifndef CONFIG_STM32_UART7 +# undef CONFIG_UART7_RXDMA +#endif + +#ifndef CONFIG_STM32_UART8 +# undef CONFIG_UART8_RXDMA +#endif + +/* Is DMA available on any (enabled) USART? */ + +#undef SERIAL_HAVE_DMA +#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) || defined(CONFIG_UART4_RXDMA) || \ + defined(CONFIG_UART5_RXDMA) || defined(CONFIG_USART6_RXDMA) || \ + defined(CONFIG_UART7_RXDMA) || defined(CONFIG_UART8_RXDMA) +# define SERIAL_HAVE_DMA 1 +#endif + +/* Is DMA used on the console UART? */ + +#undef SERIAL_HAVE_CONSOLE_DMA +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#endif + +/* Is DMA used on all (enabled) USARTs */ + +#define SERIAL_HAVE_ONLY_DMA 1 +#if defined(CONFIG_STM32_USART1) && !defined(CONFIG_USART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART2) && !defined(CONFIG_USART2_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART3) && !defined(CONFIG_USART3_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART4) && !defined(CONFIG_UART4_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART5) && !defined(CONFIG_UART5_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART6) && !defined(CONFIG_USART6_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART7) && !defined(CONFIG_UART7_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART8) && !defined(CONFIG_UART8_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#endif + +/* Is RS-485 used? */ + +#if defined(CONFIG_USART1_RS485) || defined(CONFIG_USART2_RS485) || \ + defined(CONFIG_USART3_RS485) || defined(CONFIG_UART4_RS485) || \ + defined(CONFIG_UART5_RS485) || defined(CONFIG_USART6_RS485) || \ + defined(CONFIG_UART7_RS485) || defined(CONFIG_UART8_RS485) +# define HAVE_RS485 1 +#endif + +#ifdef HAVE_RS485 +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) +#else +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_serial_dma_poll + * + * Description: + * Must be called periodically if any STM32 UART is configured for DMA. The DMA + * callback is triggered for each fifo size/2 bytes, but this can result in some + * bytes being transferred but not collected if the incoming data is not a whole + * multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ************************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32_STM32_UART_H */ diff --git a/arch/arm/src/stm32/stm32_uid.c b/arch/arm/src/stm32/stm32_uid.c new file mode 100644 index 0000000000000000000000000000000000000000..5456b2027d6c02c32b3b17d56256621fa134ff06 --- /dev/null +++ b/arch/arm/src/stm32/stm32_uid.c @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_uid.c + * + * Copyright (C) 2015 Marawan Ragab. All rights reserved. + * Author: Marawan Ragab + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "stm32_uid.h" + +#ifdef STM32_SYSMEM_UID /* Not defined for the STM32L */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void stm32_get_uniqueid(uint8_t uniqueid[12]) +{ + int i; + + for (i = 0; i < 12; i++) + { + uniqueid[i] = *((uint8_t*)(STM32_SYSMEM_UID)+i); + } +} + +#endif /* STM32_SYSMEM_UID */ + diff --git a/arch/arm/src/stm32/stm32_uid.h b/arch/arm/src/stm32/stm32_uid.h new file mode 100644 index 0000000000000000000000000000000000000000..cfa044611082911c47f50df65d248ab57b2fbf9a --- /dev/null +++ b/arch/arm/src/stm32/stm32_uid.h @@ -0,0 +1,51 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_uid.h + * + * Copyright (C) 2015 Marawan Ragab. All rights reserved. + * Author: Marawan Ragab + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_UID_H +#define __ARCH_ARM_SRC_STM32_UID_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +void stm32_get_uniqueid(uint8_t uniqueid[12]); + +#endif /* __ARCH_ARM_SRC_STM32_UID_H */ diff --git a/arch/arm/src/stm32/stm32_usbdev.c b/arch/arm/src/stm32/stm32_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..27f75be899a0c0deba68a77eb30a55a2c33e37cb --- /dev/null +++ b/arch/arm/src/stm32/stm32_usbdev.c @@ -0,0 +1,3954 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_usbdev.c + * + * Copyright (C) 2009-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * - RM0008 Reference manual, STMicro document ID 13902 + * - STM32F10xxx USB development kit, UM0424, STMicro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "stm32.h" +#include "stm32_syscfg.h" +#include "stm32_gpio.h" +#include "stm32_usbdev.h" + +#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_USB) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USB_PRI +# define CONFIG_USB_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* USB Interrupts. Should be re-mapped if CAN is used. */ + +#ifdef CONFIG_STM32_STM32F30XX +# ifdef CONFIG_STM32_USB_ITRMP +# define STM32_IRQ_USBHP STM32_IRQ_USBHP_2 +# define STM32_IRQ_USBLP STM32_IRQ_USBLP_2 +# define STM32_IRQ_USBWKUP STM32_IRQ_USBWKUP_2 +# else +# define STM32_IRQ_USBHP STM32_IRQ_USBHP_1 +# define STM32_IRQ_USBLP STM32_IRQ_USBLP_1 +# define STM32_IRQ_USBWKUP STM32_IRQ_USBWKUP_1 +# endif +#endif + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_STM32_USBDEV_REGDEBUG +#endif + +/* Initial interrupt mask: Reset + Suspend + Correct Transfer */ + +#define STM32_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_CTRM) + +/* Endpoint identifiers. The STM32 supports up to 16 mono-directional or 8 + * bidirectional endpoints. However, when you take into account PMA buffer + * usage (see below) and the fact that EP0 is bidirectional, then there is + * a functional limitation of EP0 + 5 mono-directional endpoints = 6. We'll + * define STM32_NENDPOINTS to be 8, however, because that is how many + * endpoint register sets there are. + */ + +#define STM32_NENDPOINTS (8) +#define EP0 (0) +#define EP1 (1) +#define EP2 (2) +#define EP3 (3) +#define EP4 (4) +#define EP5 (5) +#define EP6 (6) +#define EP7 (7) + +#define STM32_ENDP_BIT(ep) (1 << (ep)) +#define STM32_ENDP_ALLSET 0xff + +/* Packet sizes. We us a fixed 64 max packet size for all endpoint types */ + +#define STM32_MAXPACKET_SHIFT (6) +#define STM32_MAXPACKET_SIZE (1 << (STM32_MAXPACKET_SHIFT)) +#define STM32_MAXPACKET_MASK (STM32_MAXPACKET_SIZE-1) + +#define STM32_EP0MAXPACKET STM32_MAXPACKET_SIZE + +/* Buffer descriptor table. We assume that USB has exclusive use of CAN/USB + * memory. The buffer table is positioned at the beginning of the 512-byte + * CAN/USB memory. We will use the first STM32_NENDPOINTS*4 words for the buffer + * table. That is exactly 64 bytes, leaving 7*64 bytes for endpoint buffers. + */ + +#define STM32_BTABLE_ADDRESS (0x00) /* Start at the beginning of USB/CAN RAM */ +#define STM32_DESC_SIZE (8) /* Each descriptor is 4*2=8 bytes in size */ +#define STM32_BTABLE_SIZE (STM32_NENDPOINTS*STM32_DESC_SIZE) + +/* Buffer layout. Assume that all buffers are 64-bytes (maxpacketsize), then + * we have space for only 7 buffers; endpoint 0 will require two buffers, leaving + * 5 for other endpoints. + */ + +#define STM32_BUFFER_START STM32_BTABLE_SIZE +#define STM32_EP0_RXADDR STM32_BUFFER_START +#define STM32_EP0_TXADDR (STM32_EP0_RXADDR+STM32_EP0MAXPACKET) + +#define STM32_BUFFER_EP0 0x03 +#define STM32_NBUFFERS 7 +#define STM32_BUFFER_BIT(bn) (1 << (bn)) +#define STM32_BUFFER_ALLSET 0x7f +#define STM32_BUFNO2BUF(bn) (STM32_BUFFER_START+((bn)<head == NULL) +#define stm32_rqpeek(ep) ((ep)->head) + +/* USB trace ****************************************************************/ +/* Trace error codes */ + +#define STM32_TRACEERR_ALLOCFAIL 0x0001 +#define STM32_TRACEERR_BADCLEARFEATURE 0x0002 +#define STM32_TRACEERR_BADDEVGETSTATUS 0x0003 +#define STM32_TRACEERR_BADEPGETSTATUS 0x0004 +#define STM32_TRACEERR_BADEPNO 0x0005 +#define STM32_TRACEERR_BADEPTYPE 0x0006 +#define STM32_TRACEERR_BADGETCONFIG 0x0007 +#define STM32_TRACEERR_BADGETSETDESC 0x0008 +#define STM32_TRACEERR_BADGETSTATUS 0x0009 +#define STM32_TRACEERR_BADSETADDRESS 0x000a +#define STM32_TRACEERR_BADSETCONFIG 0x000b +#define STM32_TRACEERR_BADSETFEATURE 0x000c +#define STM32_TRACEERR_BINDFAILED 0x000d +#define STM32_TRACEERR_DISPATCHSTALL 0x000e +#define STM32_TRACEERR_DRIVER 0x000f +#define STM32_TRACEERR_DRIVERREGISTERED 0x0010 +#define STM32_TRACEERR_EP0BADCTR 0x0011 +#define STM32_TRACEERR_EP0SETUPSTALLED 0x0012 +#define STM32_TRACEERR_EPBUFFER 0x0013 +#define STM32_TRACEERR_EPDISABLED 0x0014 +#define STM32_TRACEERR_EPOUTNULLPACKET 0x0015 +#define STM32_TRACEERR_EPRESERVE 0x0016 +#define STM32_TRACEERR_INVALIDCTRLREQ 0x0017 +#define STM32_TRACEERR_INVALIDPARMS 0x0018 +#define STM32_TRACEERR_IRQREGISTRATION 0x0019 +#define STM32_TRACEERR_NOTCONFIGURED 0x001a +#define STM32_TRACEERR_REQABORTED 0x001b + +/* Trace interrupt codes */ + +#define STM32_TRACEINTID_CLEARFEATURE 0x0001 +#define STM32_TRACEINTID_DEVGETSTATUS 0x0002 +#define STM32_TRACEINTID_DISPATCH 0x0003 +#define STM32_TRACEINTID_EP0IN 0x0004 +#define STM32_TRACEINTID_EP0INDONE 0x0005 +#define STM32_TRACEINTID_EP0OUTDONE 0x0006 +#define STM32_TRACEINTID_EP0SETUPDONE 0x0007 +#define STM32_TRACEINTID_EP0SETUPSETADDRESS 0x0008 +#define STM32_TRACEINTID_EPGETSTATUS 0x0009 +#define STM32_TRACEINTID_EPINDONE 0x000a +#define STM32_TRACEINTID_EPINQEMPTY 0x000b +#define STM32_TRACEINTID_EPOUTDONE 0x000c +#define STM32_TRACEINTID_EPOUTPENDING 0x000d +#define STM32_TRACEINTID_EPOUTQEMPTY 0x000e +#define STM32_TRACEINTID_ESOF 0x000f +#define STM32_TRACEINTID_GETCONFIG 0x0010 +#define STM32_TRACEINTID_GETSETDESC 0x0011 +#define STM32_TRACEINTID_GETSETIF 0x0012 +#define STM32_TRACEINTID_GETSTATUS 0x0013 +#define STM32_TRACEINTID_HPINTERRUPT 0x0014 +#define STM32_TRACEINTID_IFGETSTATUS 0x0015 +#define STM32_TRACEINTID_LPCTR 0x0016 +#define STM32_TRACEINTID_LPINTERRUPT 0x0017 +#define STM32_TRACEINTID_NOSTDREQ 0x0018 +#define STM32_TRACEINTID_RESET 0x0019 +#define STM32_TRACEINTID_SETCONFIG 0x001a +#define STM32_TRACEINTID_SETFEATURE 0x001b +#define STM32_TRACEINTID_SUSP 0x001c +#define STM32_TRACEINTID_SYNCHFRAME 0x001d +#define STM32_TRACEINTID_WKUP 0x001e +#define STM32_TRACEINTID_EP0SETUPOUT 0x001f +#define STM32_TRACEINTID_EP0SETUPOUTDATA 0x0020 + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/* Byte ordering in host-based values */ + +#ifdef CONFIG_ENDIAN_BIG +# define LSB 1 +# define MSB 0 +#else +# define LSB 0 +# define MSB 1 +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* The various states of a control pipe */ + +enum stm32_ep0state_e +{ + EP0STATE_IDLE = 0, /* No request in progress */ + EP0STATE_SETUP_OUT, /* Set up recived with data for device OUT in progress */ + EP0STATE_SETUP_READY, /* Set up was recived prior and is in ctrl, + * now the data has arrived */ + EP0STATE_WRREQUEST, /* Write request in progress */ + EP0STATE_RDREQUEST, /* Read request in progress */ + EP0STATE_STALLED /* We are stalled */ +}; + +/* Resume states */ + +enum stm32_rsmstate_e +{ + RSMSTATE_IDLE = 0, /* Device is either fully suspended or running */ + RSMSTATE_STARTED, /* Resume sequence has been started */ + RSMSTATE_WAITING /* Waiting (on ESOFs) for end of sequence */ +}; + +union wb_u +{ + uint16_t w; + uint8_t b[2]; +}; + +/* A container for a request so that the request make be retained in a list */ + +struct stm32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct stm32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct stm32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct stm32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* STR71X-specific fields */ + + struct stm32_usbdev_s *dev; /* Reference to private driver data */ + struct stm32_req_s *head; /* Request list for this endpoint */ + struct stm32_req_s *tail; + uint8_t bufno; /* Allocated buffer number */ + uint8_t stalled:1; /* true: Endpoint is stalled */ + uint8_t halted:1; /* true: Endpoint feature halted */ + uint8_t txbusy:1; /* true: TX endpoint FIFO full */ + uint8_t txnullpkt:1; /* Null packet needed at end of transfer */ +}; + +struct stm32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structstm32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* STM32-specific fields */ + + uint8_t ep0state; /* State of EP0 (see enum stm32_ep0state_e) */ + uint8_t rsmstate; /* Resume state (see enum stm32_rsmstate_e) */ + uint8_t nesofs; /* ESOF counter (for resume support) */ + uint8_t rxpending:1; /* 1: OUT data in PMA, but no read requests */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t epavail; /* Bitset of available endpoints */ + uint8_t bufavail; /* Bitset of available buffers */ + uint16_t rxstatus; /* Saved during interrupt processing */ + uint16_t txstatus; /* " " " " " " " " */ + uint16_t imask; /* Current interrupt mask */ + + /* E0 SETUP data buffering. + * + * ctrl + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The ep0 packet receipt logic + * stm32_ep0_rdrequest will save the accompanying EP0 OUT data in + * ep0data[] before the SETUP command is re-processed. + * + * ep0datlen + * Lenght of OUT DATA received in ep0data[] + */ + + struct usb_ctrlreq_s ctrl; /* Last EP0 request */ + + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint list */ + + struct stm32_ep_s eplist[STM32_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint16_t val, uint32_t addr); +static void stm32_checksetup(void); +static void stm32_dumpep(int epno); +#else +# define stm32_getreg(addr) getreg16(addr) +# define stm32_putreg(val,addr) putreg16(val,addr) +# define stm32_checksetup() +# define stm32_dumpep(epno) +#endif + +/* Low-Level Helpers ********************************************************/ + +static inline void + stm32_seteptxcount(uint8_t epno, uint16_t count); +static inline void + stm32_seteptxaddr(uint8_t epno, uint16_t addr); +static inline uint16_t + stm32_geteptxaddr(uint8_t epno); +static void stm32_seteprxcount(uint8_t epno, uint16_t count); +static inline uint16_t + stm32_geteprxcount(uint8_t epno); +static inline void + stm32_seteprxaddr(uint8_t epno, uint16_t addr); +static inline uint16_t + stm32_geteprxaddr(uint8_t epno); +static inline void + stm32_setepaddress(uint8_t epno, uint16_t addr); +static inline void + stm32_seteptype(uint8_t epno, uint16_t type); +static inline void + stm32_seteptxaddr(uint8_t epno, uint16_t addr); +static inline void + stm32_setstatusout(uint8_t epno); +static inline void + stm32_clrstatusout(uint8_t epno); +static void stm32_clrrxdtog(uint8_t epno); +static void stm32_clrtxdtog(uint8_t epno); +static void stm32_clrepctrrx(uint8_t epno); +static void stm32_clrepctrtx(uint8_t epno); +static void stm32_seteptxstatus(uint8_t epno, uint16_t state); +static void stm32_seteprxstatus(uint8_t epno, uint16_t state); +static inline uint16_t + stm32_geteptxstatus(uint8_t epno); +static inline uint16_t + stm32_geteprxstatus(uint8_t epno); +static bool stm32_eptxstalled(uint8_t epno); +static bool stm32_eprxstalled(uint8_t epno); +static void stm32_setimask(struct stm32_usbdev_s *priv, uint16_t setbits, + uint16_t clrbits); + +/* Suspend/Resume Helpers ***************************************************/ + +static void stm32_suspend(struct stm32_usbdev_s *priv); +static void stm32_initresume(struct stm32_usbdev_s *priv); +static void stm32_esofpoll(struct stm32_usbdev_s *priv) ; + +/* Request Helpers **********************************************************/ + +static void stm32_copytopma(const uint8_t *buffer, uint16_t pma, + uint16_t nbytes); +static inline void + stm32_copyfrompma(uint8_t *buffer, uint16_t pma, uint16_t nbytes); +static struct stm32_req_s * + stm32_rqdequeue(struct stm32_ep_s *privep); +static void stm32_rqenqueue(struct stm32_ep_s *privep, + struct stm32_req_s *req); +static inline void + stm32_abortrequest(struct stm32_ep_s *privep, + struct stm32_req_s *privreq, int16_t result); +static void stm32_reqcomplete(struct stm32_ep_s *privep, int16_t result); +static void stm32_epwrite(struct stm32_usbdev_s *buf, + struct stm32_ep_s *privep, const uint8_t *data, uint32_t nbytes); +static int stm32_wrrequest(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep); +inline static int + stm32_wrrequest_ep0(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep); +static inline int + stm32_ep0_rdrequest(struct stm32_usbdev_s *priv); +static int stm32_rdrequest(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep); +static void stm32_cancelrequests(struct stm32_ep_s *privep); + +/* Interrupt level processing ***********************************************/ + +static void stm32_dispatchrequest(struct stm32_usbdev_s *priv); +static void stm32_epdone(struct stm32_usbdev_s *priv, uint8_t epno); +static void stm32_setdevaddr(struct stm32_usbdev_s *priv, uint8_t value); +static void stm32_ep0setup(struct stm32_usbdev_s *priv); +static void stm32_ep0out(struct stm32_usbdev_s *priv); +static void stm32_ep0in(struct stm32_usbdev_s *priv); +static inline void + stm32_ep0done(struct stm32_usbdev_s *priv, uint16_t istr); +static void stm32_lptransfer(struct stm32_usbdev_s *priv); +static int stm32_hpinterrupt(int irq, void *context); +static int stm32_lpinterrupt(int irq, void *context); + +/* Endpoint helpers *********************************************************/ + +static inline struct stm32_ep_s * + stm32_epreserve(struct stm32_usbdev_s *priv, uint8_t epset); +static inline void + stm32_epunreserve(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep); +static inline bool + stm32_epreserved(struct stm32_usbdev_s *priv, int epno); +static int stm32_epallocpma(struct stm32_usbdev_s *priv); +static inline void + stm32_epfreepma(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep); + +/* Endpoint operations ******************************************************/ + +static int stm32_epconfigure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int stm32_epdisable(struct usbdev_ep_s *ep); +static struct usbdev_req_s * + stm32_epallocreq(struct usbdev_ep_s *ep); +static void stm32_epfreereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); +static int stm32_epsubmit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int stm32_epcancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int stm32_epstall(struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations *****************************************/ + +static struct usbdev_ep_s * + stm32_allocep(struct usbdev_s *dev, uint8_t epno, bool in, + uint8_t eptype); +static void stm32_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep); +static int stm32_getframe(struct usbdev_s *dev); +static int stm32_wakeup(struct usbdev_s *dev); +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered); + +/* Initialization/Reset *****************************************************/ + +static void stm32_reset(struct stm32_usbdev_s *priv); +static void stm32_hwreset(struct stm32_usbdev_s *priv); +static void stm32_hwsetup(struct stm32_usbdev_s *priv); +static void stm32_hwshutdown(struct stm32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct stm32_usbdev_s g_usbdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = stm32_epconfigure, + .disable = stm32_epdisable, + .allocreq = stm32_epallocreq, + .freereq = stm32_epfreereq, + .submit = stm32_epsubmit, + .cancel = stm32_epcancel, + .stall = stm32_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = stm32_allocep, + .freeep = stm32_freeep, + .getframe = stm32_getframe, + .wakeup = stm32_wakeup, + .selfpowered = stm32_selfpowered, + .pullup = stm32_usbpullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(STM32_TRACEINTID_CLEARFEATURE ), + TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_DISPATCH ), + TRACE_STR(STM32_TRACEINTID_EP0IN ), + TRACE_STR(STM32_TRACEINTID_EP0INDONE ), + TRACE_STR(STM32_TRACEINTID_EP0OUTDONE ), + TRACE_STR(STM32_TRACEINTID_EP0SETUPDONE ), + TRACE_STR(STM32_TRACEINTID_EP0SETUPSETADDRESS ), + TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_EPINDONE ), + TRACE_STR(STM32_TRACEINTID_EPINQEMPTY ), + TRACE_STR(STM32_TRACEINTID_EPOUTDONE ), + TRACE_STR(STM32_TRACEINTID_EPOUTPENDING ), + TRACE_STR(STM32_TRACEINTID_EPOUTQEMPTY ), + TRACE_STR(STM32_TRACEINTID_ESOF ), + TRACE_STR(STM32_TRACEINTID_GETCONFIG ), + TRACE_STR(STM32_TRACEINTID_GETSETDESC ), + TRACE_STR(STM32_TRACEINTID_GETSETIF ), + TRACE_STR(STM32_TRACEINTID_GETSTATUS ), + TRACE_STR(STM32_TRACEINTID_HPINTERRUPT ), + TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_LPCTR ), + TRACE_STR(STM32_TRACEINTID_LPINTERRUPT ), + TRACE_STR(STM32_TRACEINTID_NOSTDREQ ), + TRACE_STR(STM32_TRACEINTID_RESET ), + TRACE_STR(STM32_TRACEINTID_SETCONFIG ), + TRACE_STR(STM32_TRACEINTID_SETFEATURE ), + TRACE_STR(STM32_TRACEINTID_SUSP ), + TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ), + TRACE_STR(STM32_TRACEINTID_WKUP ), + TRACE_STR(STM32_TRACEINTID_EP0SETUPOUT ), + TRACE_STR(STM32_TRACEINTID_EP0SETUPOUTDATA ), + TRACE_STR_END +}; +#endif + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(STM32_TRACEERR_ALLOCFAIL ), + TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ), + TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADEPNO ), + TRACE_STR(STM32_TRACEERR_BADEPTYPE ), + TRACE_STR(STM32_TRACEERR_BADGETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADGETSETDESC ), + TRACE_STR(STM32_TRACEERR_BADGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADSETADDRESS ), + TRACE_STR(STM32_TRACEERR_BADSETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADSETFEATURE ), + TRACE_STR(STM32_TRACEERR_BINDFAILED ), + TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ), + TRACE_STR(STM32_TRACEERR_DRIVER ), + TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED ), + TRACE_STR(STM32_TRACEERR_EP0BADCTR ), + TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ), + TRACE_STR(STM32_TRACEERR_EPBUFFER ), + TRACE_STR(STM32_TRACEERR_EPDISABLED ), + TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPRESERVE ), + TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ), + TRACE_STR(STM32_TRACEERR_INVALIDPARMS ), + TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ), + TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ), + TRACE_STR(STM32_TRACEERR_REQABORTED ), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Private Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_getreg + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint16_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint16_t val = getreg16(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%04x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint16_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%04x\n", addr, val); + + /* Write the value */ + + putreg16(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_dumpep + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_dumpep(int epno) +{ + uint32_t addr; + + /* Common registers */ + + lldbg("CNTR: %04x\n", getreg16(STM32_USB_CNTR)); + lldbg("ISTR: %04x\n", getreg16(STM32_USB_ISTR)); + lldbg("FNR: %04x\n", getreg16(STM32_USB_FNR)); + lldbg("DADDR: %04x\n", getreg16(STM32_USB_DADDR)); + lldbg("BTABLE: %04x\n", getreg16(STM32_USB_BTABLE)); + + /* Endpoint register */ + + addr = STM32_USB_EPR(epno); + lldbg("EPR%d: [%08x] %04x\n", epno, addr, getreg16(addr)); + + /* Endpoint descriptor */ + + addr = STM32_USB_BTABLE_ADDR(epno, 0); + lldbg("DESC: %08x\n", addr); + + /* Endpoint buffer descriptor */ + + addr = STM32_USB_ADDR_TX(epno); + lldbg(" TX ADDR: [%08x] %04x\n", addr, getreg16(addr)); + + addr = STM32_USB_COUNT_TX(epno); + lldbg(" COUNT: [%08x] %04x\n", addr, getreg16(addr)); + + addr = STM32_USB_ADDR_RX(epno); + lldbg(" RX ADDR: [%08x] %04x\n", addr, getreg16(addr)); + + addr = STM32_USB_COUNT_RX(epno); + lldbg(" COUNT: [%08x] %04x\n", addr, getreg16(addr)); +} +#endif + +/**************************************************************************** + * Name: stm32_checksetup + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_checksetup(void) +{ + uint32_t cfgr = getreg32(STM32_RCC_CFGR); + uint32_t apb1rstr = getreg32(STM32_RCC_APB1RSTR); + uint32_t apb1enr = getreg32(STM32_RCC_APB1ENR); + + lldbg("CFGR: %08x APB1RSTR: %08x APB1ENR: %08x\n", cfgr, apb1rstr, apb1enr); + + if ((apb1rstr & RCC_APB1RSTR_USBRST) != 0 || + (apb1enr & RCC_APB1ENR_USBEN) == 0) + { + lldbg("ERROR: USB is NOT setup correctly\n"); + } +} +#endif + +/**************************************************************************** + * Low-Level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_seteptxcount + ****************************************************************************/ + +static inline void stm32_seteptxcount(uint8_t epno, uint16_t count) +{ + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_COUNT_TX(epno); + *epaddr = count; +} + +/**************************************************************************** + * Name: stm32_seteptxaddr + ****************************************************************************/ + +static inline void stm32_seteptxaddr(uint8_t epno, uint16_t addr) +{ + volatile uint32_t *txaddr = (uint32_t *)STM32_USB_ADDR_TX(epno); + *txaddr = addr; +} + +/**************************************************************************** + * Name: stm32_geteptxaddr + ****************************************************************************/ + +static inline uint16_t stm32_geteptxaddr(uint8_t epno) +{ + volatile uint32_t *txaddr = (uint32_t *)STM32_USB_ADDR_TX(epno); + return (uint16_t)*txaddr; +} + +/**************************************************************************** + * Name: stm32_seteprxcount + ****************************************************************************/ + +static void stm32_seteprxcount(uint8_t epno, uint16_t count) +{ + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_COUNT_RX(epno); + uint32_t rxcount = 0; + uint16_t nblocks; + + /* The upper bits of the RX COUNT value contain the size of allocated + * RX buffer. This is based on a block size of 2 or 32: + * + * USB_COUNT_RX_BL_SIZE not set: + * nblocks is in units of 2 bytes. + * 00000 - not allowed + * 00001 - 2 bytes + * .... + * 11111 - 62 bytes + * + * USB_COUNT_RX_BL_SIZE set: + * 00000 - 32 bytes + * 00001 - 64 bytes + * ... + * 01111 - 512 bytes + * 1xxxx - Not allowed + */ + + if (count > 62) + { + /* Blocks of 32 (with 0 meaning one block of 32) */ + + nblocks = (count >> 5) - 1 ; + DEBUGASSERT(nblocks <= 0x0f); + rxcount = (uint32_t)((nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT) | USB_COUNT_RX_BL_SIZE); + } + else if (count > 0) + { + /* Blocks of 2 (with 1 meaning one block of 2) */ + + nblocks = (count + 1) >> 1; + DEBUGASSERT(nblocks > 0 && nblocks < 0x1f); + rxcount = (uint32_t)(nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT); + } + *epaddr = rxcount; +} + +/**************************************************************************** + * Name: stm32_geteprxcount + ****************************************************************************/ + +static inline uint16_t stm32_geteprxcount(uint8_t epno) +{ + volatile uint32_t *epaddr = (uint32_t *)STM32_USB_COUNT_RX(epno); + return (*epaddr) & USB_COUNT_RX_MASK; +} + +/**************************************************************************** + * Name: stm32_seteprxaddr + ****************************************************************************/ + +static inline void stm32_seteprxaddr(uint8_t epno, uint16_t addr) +{ + volatile uint32_t *rxaddr = (uint32_t *)STM32_USB_ADDR_RX(epno); + *rxaddr = addr; +} + +/**************************************************************************** + * Name: stm32_seteprxaddr + ****************************************************************************/ + +static inline uint16_t stm32_geteprxaddr(uint8_t epno) +{ + volatile uint32_t *rxaddr = (uint32_t *)STM32_USB_ADDR_RX(epno); + return (uint16_t)*rxaddr; +} + +/**************************************************************************** + * Name: stm32_setepaddress + ****************************************************************************/ + +static inline void stm32_setepaddress(uint8_t epno, uint16_t addr) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval &= ~USB_EPR_EA_MASK; + regval |= (addr << USB_EPR_EA_SHIFT); + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_seteptype + ****************************************************************************/ + +static inline void stm32_seteptype(uint8_t epno, uint16_t type) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval &= ~USB_EPR_EPTYPE_MASK; + regval |= type; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_setstatusout + ****************************************************************************/ + +static inline void stm32_setstatusout(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + /* For a BULK endpoint the EP_KIND bit is used to enabled double buffering; + * for a CONTROL endpoint, it is set to indicate that a status OUT + * transaction is expected. The bit is not used with out endpoint types. + */ + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval |= USB_EPR_EP_KIND; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_clrstatusout + ****************************************************************************/ + +static inline void stm32_clrstatusout(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + /* For a BULK endpoint the EP_KIND bit is used to enabled double buffering; + * for a CONTROL endpoint, it is set to indicate that a status OUT + * transaction is expected. The bit is not used with out endpoint types. + */ + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval &= ~USB_EPR_EP_KIND; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_clrrxdtog + ****************************************************************************/ + +static void stm32_clrrxdtog(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + if ((regval & USB_EPR_DTOG_RX) != 0) + { + regval &= EPR_NOTOG_MASK; + regval |= USB_EPR_DTOG_RX; + stm32_putreg(regval, epaddr); + } +} + +/**************************************************************************** + * Name: stm32_clrtxdtog + ****************************************************************************/ + +static void stm32_clrtxdtog(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + if ((regval & USB_EPR_DTOG_TX) != 0) + { + regval &= EPR_NOTOG_MASK; + regval |= USB_EPR_DTOG_TX; + stm32_putreg(regval, epaddr); + } +} + +/**************************************************************************** + * Name: stm32_clrepctrrx + ****************************************************************************/ + +static void stm32_clrepctrrx(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval &= ~USB_EPR_CTR_RX; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_clrepctrtx + ****************************************************************************/ + +static void stm32_clrepctrtx(uint8_t epno) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + regval = stm32_getreg(epaddr); + regval &= EPR_NOTOG_MASK; + regval &= ~USB_EPR_CTR_TX; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_geteptxstatus + ****************************************************************************/ + +static inline uint16_t stm32_geteptxstatus(uint8_t epno) +{ + return (uint16_t)(stm32_getreg(STM32_USB_EPR(epno)) & USB_EPR_STATTX_MASK); +} + +/**************************************************************************** + * Name: stm32_geteprxstatus + ****************************************************************************/ + +static inline uint16_t stm32_geteprxstatus(uint8_t epno) +{ + return (stm32_getreg(STM32_USB_EPR(epno)) & USB_EPR_STATRX_MASK); +} + +/**************************************************************************** + * Name: stm32_seteptxstatus + ****************************************************************************/ + +static void stm32_seteptxstatus(uint8_t epno, uint16_t state) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + /* The bits in the STAT_TX field can be toggled by software to set their + * value. When set to 0, the value remains unchanged; when set to one, + * value toggles. + */ + + regval = stm32_getreg(epaddr); + + /* The exclusive OR will set STAT_TX bits to 1 if there value is different + * from the bits requested in 'state' + */ + + regval ^= state; + regval &= EPR_TXDTOG_MASK; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_seteprxstatus + ****************************************************************************/ + +static void stm32_seteprxstatus(uint8_t epno, uint16_t state) +{ + uint32_t epaddr = STM32_USB_EPR(epno); + uint16_t regval; + + /* The bits in the STAT_RX field can be toggled by software to set their + * value. When set to 0, the value remains unchanged; when set to one, + * value toggles. + */ + + regval = stm32_getreg(epaddr); + + /* The exclusive OR will set STAT_RX bits to 1 if there value is different + * from the bits requested in 'state' + */ + + regval ^= state; + regval &= EPR_RXDTOG_MASK; + stm32_putreg(regval, epaddr); +} + +/**************************************************************************** + * Name: stm32_eptxstalled + ****************************************************************************/ + +static inline bool stm32_eptxstalled(uint8_t epno) +{ + return (stm32_geteptxstatus(epno) == USB_EPR_STATTX_STALL); +} + +/**************************************************************************** + * Name: stm32_eprxstalled + ****************************************************************************/ + +static inline bool stm32_eprxstalled(uint8_t epno) +{ + return (stm32_geteprxstatus(epno) == USB_EPR_STATRX_STALL); +} + +/**************************************************************************** + * Request Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_copytopma + ****************************************************************************/ + +static void stm32_copytopma(const uint8_t *buffer, uint16_t pma, uint16_t nbytes) +{ + uint16_t *dest; + uint16_t ms; + uint16_t ls; + int nwords = (nbytes + 1) >> 1; + int i; + + /* Copy loop. Source=user buffer, Dest=packet memory */ + + dest = (uint16_t *)(STM32_USBRAM_BASE + ((uint32_t)pma << 1)); + for (i = nwords; i != 0; i--) + { + /* Read two bytes and pack into on 16-bit word */ + + ls = (uint16_t)(*buffer++); + ms = (uint16_t)(*buffer++); + *dest = ms << 8 | ls; + + /* Source address increments by 2*sizeof(uint8_t) = 2; Dest address + * increments by 2*sizeof(uint16_t) = 4. + */ + + dest += 2; + } +} + +/**************************************************************************** + * Name: stm32_copyfrompma + ****************************************************************************/ + +static inline void +stm32_copyfrompma(uint8_t *buffer, uint16_t pma, uint16_t nbytes) +{ + uint32_t *src; + int nwords = (nbytes + 1) >> 1; + int i; + + /* Copy loop. Source=packet memory, Dest=user buffer */ + + src = (uint32_t *)(STM32_USBRAM_BASE + ((uint32_t)pma << 1)); + for (i = nwords; i != 0; i--) + { + /* Copy 16-bits from packet memory to user buffer. */ + + *(uint16_t *)buffer = *src++; + + /* Source address increments by 1*sizeof(uint32_t) = 4; Dest address + * increments by 2*sizeof(uint8_t) = 2. + */ + + buffer += 2; + } +} + +/**************************************************************************** + * Name: stm32_rqdequeue + ****************************************************************************/ + +static struct stm32_req_s *stm32_rqdequeue(struct stm32_ep_s *privep) +{ + struct stm32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_rqenqueue + ****************************************************************************/ + +static void stm32_rqenqueue(struct stm32_ep_s *privep, struct stm32_req_s *req) +{ + req->flink = NULL; + if (!privep->head) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } +} + +/**************************************************************************** + * Name: stm32_abortrequest + ****************************************************************************/ + +static inline void +stm32_abortrequest(struct stm32_ep_s *privep, struct stm32_req_s *privreq, int16_t result) +{ + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_REQABORTED), (uint16_t)USB_EPNO(privep->ep.eplog)); + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); +} + +/**************************************************************************** + * Name: stm32_reqcomplete + ****************************************************************************/ + +static void stm32_reqcomplete(struct stm32_ep_s *privep, int16_t result) +{ + struct stm32_req_s *privreq; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint request list */ + + flags = enter_critical_section(); + privreq = stm32_rqdequeue(privep); + leave_critical_section(flags); + + if (privreq) + { + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (USB_EPNO(privep->ep.eplog) == EP0) + { + privep->stalled = (privep->dev->ep0state == EP0STATE_STALLED); + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; + } +} + +/**************************************************************************** + * Name: tm32_epwrite + ****************************************************************************/ + +static void stm32_epwrite(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep, + const uint8_t *buf, uint32_t nbytes) +{ + uint8_t epno = USB_EPNO(privep->ep.eplog); + usbtrace(TRACE_WRITE(epno), nbytes); + + /* Check for a zero-length packet */ + + if (nbytes > 0) + { + /* Copy the data from the user buffer into packet memory for this + * endpoint + */ + + stm32_copytopma(buf, stm32_geteptxaddr(epno), nbytes); + } + + /* Send the packet (might be a null packet nbytes == 0) */ + + stm32_seteptxcount(epno, nbytes); + priv->txstatus = USB_EPR_STATTX_VALID; + + /* Indicate that there is data in the TX packet memory. This will be cleared + * when the next data out interrupt is received. + */ + + privep->txbusy = true; +} + +/**************************************************************************** + * Name: stm32_wrrequest_ep0 + * + * Description: + * Handle the ep0 state on writes. + * + ****************************************************************************/ + +inline static int stm32_wrrequest_ep0(struct stm32_usbdev_s *priv, + struct stm32_ep_s *privep) +{ + int ret; + ret = stm32_wrrequest(priv, privep); + priv->ep0state = ((ret == OK) ? EP0STATE_WRREQUEST : EP0STATE_IDLE); + return ret; +} + +/**************************************************************************** + * Name: stm32_wrrequest + ****************************************************************************/ + +static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint8_t *buf; + uint8_t epno; + int nbytes; + int bytesleft; + + /* We get here when an IN endpoint interrupt occurs. So now we know that + * there is no TX transfer in progress. + */ + + privep->txbusy = false; + + /* Check the request from the head of the endpoint request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* There is no TX transfer in progress and no new pending TX + * requests to send. + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPINQEMPTY), 0); + return -ENOENT; + } + + epno = USB_EPNO(privep->ep.eplog); + ullvdbg("epno=%d req=%p: len=%d xfrd=%d nullpkt=%d\n", + epno, privreq, privreq->req.len, privreq->req.xfrd, privep->txnullpkt); + UNUSED(epno); + + /* Get the number of bytes left to be sent in the packet */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + +#warning "REVISIT: If the EP supports double buffering, then we can do better" + + /* Either (1) we are committed to sending the null packet (because txnullpkt == 1 + * && nbytes == 0), or (2) we have not yet send the last packet (nbytes > 0). + * In either case, it is appropriate to clearn txnullpkt now. + */ + + privep->txnullpkt = 0; + + /* If we are not sending a NULL packet, then clip the size to maxpacket + * and check if we need to send a following NULL packet. + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + privep->txnullpkt = 1; + } + } + } + + /* Send the packet (might be a null packet nbytes == 0) */ + + buf = privreq->req.buf + privreq->req.xfrd; + stm32_epwrite(priv, privep, buf, nbytes); + + /* Update for the next data IN interrupt */ + + privreq->req.xfrd += nbytes; + bytesleft = privreq->req.len - privreq->req.xfrd; + + /* If all of the bytes were sent (including any final null packet) + * then we are finished with the request buffer). + */ + + if (bytesleft == 0 && !privep->txnullpkt) + { + /* Return the write request to the class driver */ + + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + privep->txnullpkt = 0; + stm32_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep0_rdrequest + * + * Description: + * This function is called from the stm32_ep0out handler when the ep0state + * is EP0STATE_SETUP_OUT and uppon new incoming data is available in the endpoint + * 0's buffer. This function will simply copy the OUT data into ep0data. + * + ****************************************************************************/ + +static inline int stm32_ep0_rdrequest(struct stm32_usbdev_s *priv) +{ + uint32_t src; + int pmalen; + int readlen; + + /* Get the number of bytes to read from packet memory */ + + pmalen = stm32_geteprxcount(EP0); + + ullvdbg("EP0: pmalen=%d\n", pmalen); + usbtrace(TRACE_READ(EP0), pmalen); + + /* Read the data into our special buffer for SETUP data */ + + readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, pmalen); + src = stm32_geteprxaddr(EP0); + + /* Receive the next packet */ + + stm32_copyfrompma(&priv->ep0data[0], src, readlen); + + /* Now we can process the setup command */ + + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPOUTDATA), readlen); + + stm32_ep0setup(priv); + priv->ep0datlen = 0; /* mark the date consumed */ + + return OK; +} + +/**************************************************************************** + * Name: stm32_rdrequest + ****************************************************************************/ + +static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t src; + uint8_t *dest; + uint8_t epno; + int pmalen; + int readlen; + + /* Check the request from the head of the endpoint request queue */ + + epno = USB_EPNO(privep->ep.eplog); + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* Incoming data available in PMA, but no packet to receive the data. + * Mark that the RX data is pending and hope that a packet is returned + * soon. + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUTQEMPTY), epno); + return -ENOENT; + } + + ullvdbg("EP%d: len=%d xfrd=%d\n", epno, privreq->req.len, privreq->req.xfrd); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); + stm32_reqcomplete(privep, OK); + return OK; + } + + usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + + /* Get the source and destination transfer addresses */ + + dest = privreq->req.buf + privreq->req.xfrd; + src = stm32_geteprxaddr(epno); + + /* Get the number of bytes to read from packet memory */ + + pmalen = stm32_geteprxcount(epno); + readlen = MIN(privreq->req.len, pmalen); + + /* Receive the next packet */ + + stm32_copyfrompma(dest, src, readlen); + + /* If the receive buffer is full or this is a partial packet, + * then we are finished with the request buffer). + */ + + privreq->req.xfrd += readlen; + if (pmalen < privep->ep.maxpacket || privreq->req.xfrd >= privreq->req.len) + { + /* Return the read request to the class driver. */ + + usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd); + stm32_reqcomplete(privep, OK); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_cancelrequests + ****************************************************************************/ + +static void stm32_cancelrequests(struct stm32_ep_s *privep) +{ + while (!stm32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), + (stm32_rqpeek(privep))->req.xfrd); + stm32_reqcomplete(privep, -ESHUTDOWN); + } +} + +/**************************************************************************** + * Interrupt Level Processing + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_dispatchrequest + ****************************************************************************/ + +static void stm32_dispatchrequest(struct stm32_usbdev_s *priv) +{ + int ret; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, + priv->ep0data, priv->ep0datlen); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0); + priv->ep0state = EP0STATE_STALLED; + } + } +} + +/**************************************************************************** + * Name: stm32_epdone + ****************************************************************************/ + +static void stm32_epdone(struct stm32_usbdev_s *priv, uint8_t epno) +{ + struct stm32_ep_s *privep; + uint16_t epr; + + /* Decode and service non control endpoints interrupt */ + + epr = stm32_getreg(STM32_USB_EPR(epno)); + privep = &priv->eplist[epno]; + + /* OUT: host-to-device + * CTR_RX is set by the hardware when an OUT/SETUP transaction + * successfully completed on this endpoint. + */ + + if ((epr & USB_EPR_CTR_RX) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUTDONE), epr); + + /* Handle read requests. First check if a read request is available to + * accept the host data. + */ + + if (!stm32_rqempty(privep)) + { + /* Read host data into the current read request */ + + (void)stm32_rdrequest(priv, privep); + + /* "After the received data is processed, the application software + * should set the STAT_RX bits to '11' (Valid) in the USB_EPnR, + * enabling further transactions. " + */ + + priv->rxstatus = USB_EPR_STATRX_VALID; + } + + /* NAK further OUT packets if there there no more read requests */ + + if (stm32_rqempty(privep)) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUTPENDING), (uint16_t)epno); + + /* Mark the RX processing as pending and NAK any OUT actions + * on this endpoint. "While the STAT_RX bits are equal to '10' + * (NAK), any OUT request addressed to that endpoint is NAKed, + * indicating a flow control condition: the USB host will retry + * the transaction until it succeeds." + */ + + priv->rxstatus = USB_EPR_STATRX_NAK; + priv->rxpending = true; + } + + /* Clear the interrupt status and set the new RX status */ + + stm32_clrepctrrx(epno); + stm32_seteprxstatus(epno, priv->rxstatus); + } + + /* IN: device-to-host + * CTR_TX is set when an IN transaction successfully completes on + * an endpoint + */ + + else if ((epr & USB_EPR_CTR_TX) != 0) + { + /* Clear interrupt status */ + + stm32_clrepctrtx(epno); + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPINDONE), epr); + + /* Handle write requests */ + + priv->txstatus = USB_EPR_STATTX_NAK; + if (epno == EP0) + { + (void)stm32_wrrequest_ep0(priv, privep); + } + else + { + (void)stm32_wrrequest(priv, privep); + } + + /* Set the new TX status */ + + stm32_seteptxstatus(epno, priv->txstatus); + } +} + +/**************************************************************************** + * Name: stm32_setdevaddr + ****************************************************************************/ + +static void stm32_setdevaddr(struct stm32_usbdev_s *priv, uint8_t value) +{ + int epno; + + /* Set address in every allocated endpoint */ + + for (epno = 0; epno < STM32_NENDPOINTS; epno++) + { + if (stm32_epreserved(priv, epno)) + { + stm32_setepaddress((uint8_t)epno, (uint8_t)epno); + } + } + + /* Set the device address and enable function */ + + stm32_putreg(value | USB_DADDR_EF, STM32_USB_DADDR); +} + +/**************************************************************************** + * Name: stm32_ep0setup + ****************************************************************************/ + +static void stm32_ep0setup(struct stm32_usbdev_s *priv) +{ + struct stm32_ep_s *ep0 = &priv->eplist[EP0]; + struct stm32_req_s *privreq = stm32_rqpeek(ep0); + struct stm32_ep_s *privep; + union wb_u value; + union wb_u index; + union wb_u len; + union wb_u response; + bool handled = false; + uint8_t epno; + int nbytes = 0; /* Assume zero-length packet */ + + /* Terminate any pending requests (doesn't work if the pending request + * was a zero-length transfer!) + */ + + while (!stm32_rqempty(ep0)) + { + int16_t result = OK; + if (privreq->req.xfrd != privreq->req.len) + { + result = -EPROTO; + } + + usbtrace(TRACE_COMPLETE(ep0->ep.eplog), privreq->req.xfrd); + stm32_reqcomplete(ep0, result); + } + + /* Assume NOT stalled; no TX in progress */ + + ep0->stalled = 0; + ep0->txbusy = 0; + + /* Check to see if called from the DATA phase of a SETUP Transfer */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + /* Not the data phase */ + /* Get a 32-bit PMA address and use that to get the 8-byte setup + * request + */ + + stm32_copyfrompma((uint8_t *)&priv->ctrl, stm32_geteprxaddr(EP0), + USB_SIZEOF_CTRLREQ); + + /* And extract the little-endian 16-bit values to host order */ + + value.w = GETUINT16(priv->ctrl.value); + index.w = GETUINT16(priv->ctrl.index); + len.w = GETUINT16(priv->ctrl.len); + + ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + + /* Is this an setup with OUT and data of length > 0 */ + + if (USB_REQ_ISOUT(priv->ctrl.type) && len.w > 0) + { + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPOUT), len.w); + + /* At this point priv->ctrl is the setup packet. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + return; + } + else + { + priv->ep0state = EP0STATE_SETUP_READY; + } + } + + /* Dispatch any non-standard requests */ + + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standar requests */ + + stm32_dispatchrequest(priv); + return; + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->ep0state = EP0STATE_STALLED; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), epno); + if (epno >= STM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), epno); + priv->ep0state = EP0STATE_STALLED; + } + else + { + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ + + if (USB_ISEPIN(index.b[LSB])) + { + /* IN endpoint */ + + if (stm32_eptxstalled(epno)) + { + /* IN Endpoint stalled */ + + response.b[LSB] = 1; /* Stalled */ + } + } + else + { + /* OUT endpoint */ + + if (stm32_eprxstalled(epno)) + { + /* OUT Endpoint stalled */ + + response.b[LSB] = 1; /* Stalled */ + } + } + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + priv->ep0state = EP0STATE_STALLED; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* Let the class implementation handle all recipients (except for the + * endpoint recipient) + */ + + stm32_dispatchrequest(priv); + handled = true; + } + else + { + /* Endpoint recipient */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < STM32_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 0; + (void)stm32_epstall(&privep->ep, true); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), priv->ctrl.type); + if (((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && + value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + ullvdbg("test mode: %d\n", index.w); + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) + { + /* The class driver handles all recipients except recipient=endpoint */ + + stm32_dispatchrequest(priv); + handled = true; + } + else + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < STM32_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = 1; + (void)stm32_epstall(&privep->ep, false); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPSETADDRESS), value.w); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->ep0state = EP0STATE_STALLED; + } + + /* Note that setting of the device address will be deferred. A zero-length + * packet will be sent and the device address will be set when the zero- + * length packet transfer completes. + */ + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + stm32_dispatchrequest(priv); + handled = true; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + stm32_dispatchrequest(priv); + handled = true; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index.w == 0 && len.w == 0) + { + /* The request seems valid... let the class implementation handle it */ + + stm32_dispatchrequest(priv); + handled = true; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->ep0state = EP0STATE_STALLED; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), priv->ctrl.type); + stm32_dispatchrequest(priv); + handled = true; + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); + priv->ep0state = EP0STATE_STALLED; + } + break; + } + + /* At this point, the request has been handled and there are three possible + * outcomes: + * + * 1. The setup request was successfully handled above and a response packet + * must be sent (may be a zero length packet). + * 2. The request was successfully handled by the class implementation. In + * case, the EP0 IN response has already been queued and the local variable + * 'handled' will be set to true and ep0state != EP0STATE_STALLED; + * 3. An error was detected in either the above logic or by the class implementation + * logic. In either case, priv->state will be set EP0STATE_STALLED + * to indicate this case. + * + * NOTE: Non-standard requests are a special case. They are handled by the + * class implementation and this function returned early above, skipping this + * logic altogether. + */ + + if (priv->ep0state != EP0STATE_STALLED && !handled) + { + /* We will response. First, restrict the data length to the length + * requested in the setup packet + */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* Send the response (might be a zero-length packet) */ + + stm32_epwrite(priv, ep0, response.b, nbytes); + priv->ep0state = EP0STATE_IDLE; + } +} + +/**************************************************************************** + * Name: stm32_ep0in + ****************************************************************************/ + +static void stm32_ep0in(struct stm32_usbdev_s *priv) +{ + /* There is no longer anything in the EP0 TX packet memory */ + + priv->eplist[EP0].txbusy = false; + + /* Are we processing the completion of one packet of an outgoing request + * from the class driver? + */ + + if (priv->ep0state == EP0STATE_WRREQUEST) + { + stm32_wrrequest_ep0(priv, &priv->eplist[EP0]); + } + + /* No.. Are we processing the completion of a status response? */ + + else if (priv->ep0state == EP0STATE_IDLE) + { + /* Look at the saved SETUP command. Was it a SET ADDRESS request? + * If so, then now is the time to set the address. + */ + + if (priv->ctrl.req == USB_REQ_SETADDRESS && + (priv->ctrl.type & REQRECIPIENT_MASK) == + (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_DEVICE)) + { + union wb_u value; + value.w = GETUINT16(priv->ctrl.value); + stm32_setdevaddr(priv, value.b[LSB]); + } + } + else + { + priv->ep0state = EP0STATE_STALLED; + } +} + +/**************************************************************************** + * Name: stm32_ep0out + ****************************************************************************/ + +static void stm32_ep0out(struct stm32_usbdev_s *priv) +{ + int ret; + + struct stm32_ep_s *privep = &priv->eplist[EP0]; + switch (priv->ep0state) + { + case EP0STATE_RDREQUEST: /* Read request in progress */ + case EP0STATE_IDLE: /* No transfer in progress */ + ret = stm32_rdrequest(priv, privep); + priv->ep0state = ((ret == OK) ? EP0STATE_RDREQUEST : EP0STATE_IDLE); + break; + + case EP0STATE_SETUP_OUT: /* SETUP was waiting for data */ + ret = stm32_ep0_rdrequest(priv); /* Off load the data and run the + * last set up command with the OUT + * data + */ + priv->ep0state = EP0STATE_IDLE; /* There is no notion of reciving OUT + * data greater then the length of + * CONFIG_USBDEV_SETUP_MAXDATASIZE + * so we are done + */ + break; + + default: + /* Unexpected state OR host aborted the OUT transfer before it + * completed, STALL the endpoint in either case + */ + + priv->ep0state = EP0STATE_STALLED; + break; + } +} + +/**************************************************************************** + * Name: stm32_ep0done + ****************************************************************************/ + +static inline void stm32_ep0done(struct stm32_usbdev_s *priv, uint16_t istr) +{ + uint16_t epr; + + /* Initialize RX and TX status. We shouldn't have to actually look at the + * status because the hardware is supposed to set the both RX and TX status + * to NAK when an EP0 SETUP occurs (of course, this might not be a setup) + */ + + priv->rxstatus = USB_EPR_STATRX_NAK; + priv->txstatus = USB_EPR_STATTX_NAK; + + /* Set both RX and TX status to NAK */ + + stm32_seteprxstatus(EP0, USB_EPR_STATRX_NAK); + stm32_seteptxstatus(EP0, USB_EPR_STATTX_NAK); + + /* Check the direction bit to determine if this the completion of an EP0 + * packet sent to or received from the host PC. + */ + + if ((istr & USB_ISTR_DIR) == 0) + { + /* EP0 IN: device-to-host (DIR=0) */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0IN), istr); + stm32_clrepctrtx(EP0); + stm32_ep0in(priv); + } + else + { + /* EP0 OUT: host-to-device (DIR=1) */ + + epr = stm32_getreg(STM32_USB_EPR(EP0)); + + /* CTR_TX is set when an IN transaction successfully + * completes on an endpoint + */ + + if ((epr & USB_EPR_CTR_TX) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0INDONE), epr); + stm32_clrepctrtx(EP0); + stm32_ep0in(priv); + } + + /* SETUP is set by the hardware when the last completed + * transaction was a control endpoint SETUP + */ + + else if ((epr & USB_EPR_SETUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPDONE), epr); + stm32_clrepctrrx(EP0); + stm32_ep0setup(priv); + } + + /* Set by the hardware when an OUT/SETUP transaction successfully + * completed on this endpoint. + */ + + else if ((epr & USB_EPR_CTR_RX) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0OUTDONE), epr); + stm32_clrepctrrx(EP0); + stm32_ep0out(priv); + } + + /* None of the above */ + + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0BADCTR), epr); + return; /* Does this ever happen? */ + } + } + + /* Make sure that the EP0 packet size is still OK (superstitious?) */ + + stm32_seteprxcount(EP0, STM32_EP0MAXPACKET); + + /* Now figure out the new RX/TX status. Here are all possible + * consequences of the above EP0 operations: + * + * rxstatus txstatus ep0state MEANING + * -------- -------- --------- --------------------------------- + * NAK NAK IDLE Nothing happened + * NAK VALID IDLE EP0 response sent from USBDEV driver + * NAK VALID WRREQUEST EP0 response sent from class driver + * NAK --- STALL Some protocol error occurred + * + * First handle the STALL condition: + */ + + if (priv->ep0state == EP0STATE_STALLED) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + priv->rxstatus = USB_EPR_STATRX_STALL; + priv->txstatus = USB_EPR_STATTX_STALL; + } + + /* Was a transmission started? If so, txstatus will be VALID. The + * only special case to handle is when both are set to NAK. In that + * case, we need to set RX status to VALID in order to accept the next + * SETUP request. + */ + + else if (priv->rxstatus == USB_EPR_STATRX_NAK && + priv->txstatus == USB_EPR_STATTX_NAK) + { + priv->rxstatus = USB_EPR_STATRX_VALID; + } + + /* Now set the new TX and RX status */ + + stm32_seteprxstatus(EP0, priv->rxstatus); + stm32_seteptxstatus(EP0, priv->txstatus); +} + +/**************************************************************************** + * Name: stm32_lptransfer + ****************************************************************************/ + +static void stm32_lptransfer(struct stm32_usbdev_s *priv) +{ + uint8_t epno; + uint16_t istr; + + /* Stay in loop while LP interrupts are pending */ + + while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0) + { + stm32_putreg((uint16_t)~USB_ISTR_CTR, STM32_USB_ISTR); + + /* Extract highest priority endpoint number */ + + epno = (uint8_t)(istr & USB_ISTR_EPID_MASK); + + /* Handle EP0 completion events */ + + if (epno == 0) + { + stm32_ep0done(priv, istr); + } + + /* Handle other endpoint completion events */ + + else + { + stm32_epdone(priv, epno); + } + } +} + +/**************************************************************************** + * Name: stm32_hpinterrupt + ****************************************************************************/ + +static int stm32_hpinterrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + uint16_t istr; + uint8_t epno; + + /* High priority interrupts are only triggered by a correct transfer event + * for isochronous and double-buffer bulk transfers. + */ + + istr = stm32_getreg(STM32_USB_ISTR); + usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_HPINTERRUPT), istr); + while ((istr & USB_ISTR_CTR) != 0) + { + stm32_putreg((uint16_t)~USB_ISTR_CTR, STM32_USB_ISTR); + + /* Extract highest priority endpoint number */ + + epno = (uint8_t)(istr & USB_ISTR_EPID_MASK); + + /* And handle the completion event */ + + stm32_epdone(priv, epno); + + /* Fetch the status again for the next time through the loop */ + + istr = stm32_getreg(STM32_USB_ISTR); + } + + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_HPINTERRUPT), 0); + return OK; +} + +/**************************************************************************** + * Name: stm32_lpinterrupt + ****************************************************************************/ + +static int stm32_lpinterrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + uint16_t istr = stm32_getreg(STM32_USB_ISTR); + + usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_LPINTERRUPT), istr); + + /* Handle Reset interrupts. When this event occurs, the peripheral is left + * in the same conditions it is left by the system reset (but with the + * USB controller enabled). + */ + + if ((istr & USB_ISTR_RESET) != 0) + { + /* Reset interrupt received. Clear the RESET interrupt status. */ + + stm32_putreg(~USB_ISTR_RESET, STM32_USB_ISTR); + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RESET), istr); + + /* Restore our power-up state and exit now because istr is no longer + * valid. + */ + + stm32_reset(priv); + goto exit_lpinterrupt; + } + + /* Handle Wakeup interrupts. This interrupt is only enable while the USB is + * suspended. + */ + + if ((istr & USB_ISTR_WKUP & priv->imask) != 0) + { + /* Wakeup interrupt received. Clear the WKUP interrupt status. The + * cause of the resume is indicated in the FNR register + */ + + stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR); + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_WKUP), stm32_getreg(STM32_USB_FNR)); + + /* Perform the wakeup action */ + + stm32_initresume(priv); + priv->rsmstate = RSMSTATE_IDLE; + + /* Disable ESOF polling, disable the wakeup interrupt, and + * re-enable the suspend interrupt. Clear any pending SUSP + * interrupts. + */ + + stm32_setimask(priv, USB_CNTR_SUSPM, USB_CNTR_ESOFM | USB_CNTR_WKUPM); + stm32_putreg(~USB_CNTR_SUSPM, STM32_USB_ISTR); + } + + if ((istr & USB_ISTR_SUSP & priv->imask) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSP), 0); + stm32_suspend(priv); + + /* Clear of the ISTR bit must be done after setting of USB_CNTR_FSUSP */ + + stm32_putreg(~USB_ISTR_SUSP, STM32_USB_ISTR); + } + + if ((istr & USB_ISTR_ESOF & priv->imask) != 0) + { + stm32_putreg(~USB_ISTR_ESOF, STM32_USB_ISTR); + + /* Resume handling timing is made with ESOFs */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_ESOF), 0); + stm32_esofpoll(priv); + } + + if ((istr & USB_ISTR_CTR & priv->imask) != 0) + { + /* Low priority endpoint correct transfer interrupt */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_LPCTR), istr); + stm32_lptransfer(priv); + } + +exit_lpinterrupt: + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_LPINTERRUPT), stm32_getreg(STM32_USB_EP0R)); + return OK; +} + +/**************************************************************************** + * Name: stm32_setimask + ****************************************************************************/ + +static void +stm32_setimask(struct stm32_usbdev_s *priv, uint16_t setbits, uint16_t clrbits) +{ + uint16_t regval; + + /* Adjust the interrupt mask bits in the shadow copy first */ + + priv->imask &= ~clrbits; + priv->imask |= setbits; + + /* Then make the interrupt mask bits in the CNTR register match the shadow + * register (Hmmm... who is shadowing whom?) + */ + + regval = stm32_getreg(STM32_USB_CNTR); + regval &= ~USB_CNTR_ALLINTS; + regval |= priv->imask; + stm32_putreg(regval, STM32_USB_CNTR); +} + +/**************************************************************************** + * Suspend/Resume Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_suspend + ****************************************************************************/ + +static void stm32_suspend(struct stm32_usbdev_s *priv) +{ + uint16_t regval; + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* Disable ESOF polling, disable the SUSP interrupt, and enable the WKUP + * interrupt. Clear any pending WKUP interrupt. + */ + + stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM | USB_CNTR_SUSPM); + stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR); + + /* Set the FSUSP bit in the CNTR register. This activates suspend mode + * within the USB peripheral and disables further SUSP interrupts. + */ + + regval = stm32_getreg(STM32_USB_CNTR); + regval |= USB_CNTR_FSUSP; + stm32_putreg(regval, STM32_USB_CNTR); + + /* If we are not a self-powered device, the got to low-power mode */ + + if (!priv->selfpowered) + { + /* Setting LPMODE in the CNTR register removes static power + * consumption in the USB analog transceivers but keeps them + * able to detect resume activity + */ + + regval = stm32_getreg(STM32_USB_CNTR); + regval |= USB_CNTR_LPMODE; + stm32_putreg(regval, STM32_USB_CNTR); + } + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + stm32_usbsuspend((struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: stm32_initresume + ****************************************************************************/ + +static void stm32_initresume(struct stm32_usbdev_s *priv) +{ + uint16_t regval; + + /* This function is called when either (1) a WKUP interrupt is received from + * the host PC, or (2) the class device implementation calls the wakeup() + * method. + */ + + /* Clear the USB low power mode (lower power mode was not set if this is + * a self-powered device. Also, low power mode is automatically cleared by + * hardware when a WKUP interrupt event occurs). + */ + + regval = stm32_getreg(STM32_USB_CNTR); + regval &= (~USB_CNTR_LPMODE); + stm32_putreg(regval, STM32_USB_CNTR); + + /* Restore full power -- whatever that means for this particular board */ + + stm32_usbsuspend((struct usbdev_s *)priv, true); + + /* Reset FSUSP bit and enable normal interrupt handling */ + + stm32_putreg(STM32_CNTR_SETUP, STM32_USB_CNTR); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: stm32_esofpoll + ****************************************************************************/ + +static void stm32_esofpoll(struct stm32_usbdev_s *priv) +{ + uint16_t regval; + + /* Called periodically from ESOF interrupt after RSMSTATE_STARTED */ + + switch (priv->rsmstate) + { + /* One ESOF after internal resume requested */ + + case RSMSTATE_STARTED: + regval = stm32_getreg(STM32_USB_CNTR); + regval |= USB_CNTR_RESUME; + stm32_putreg(regval, STM32_USB_CNTR); + priv->rsmstate = RSMSTATE_WAITING; + priv->nesofs = 10; + break; + + /* Countdown before completing the operation */ + + case RSMSTATE_WAITING: + priv->nesofs--; + if (priv->nesofs == 0) + { + /* Okay.. we are ready to resume normal operation */ + + regval = stm32_getreg(STM32_USB_CNTR); + regval &= (~USB_CNTR_RESUME); + stm32_putreg(regval, STM32_USB_CNTR); + priv->rsmstate = RSMSTATE_IDLE; + + /* Disable ESOF polling, disable the SUSP interrupt, and enable + * the WKUP interrupt. Clear any pending WKUP interrupt. + */ + + stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM | USB_CNTR_SUSPM); + stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR); + } + break; + + case RSMSTATE_IDLE: + default: + priv->rsmstate = RSMSTATE_IDLE; + break; + } +} + +/**************************************************************************** + * Endpoint Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_epreserve + ****************************************************************************/ + +static inline struct stm32_ep_s * +stm32_epreserve(struct stm32_usbdev_s *priv, uint8_t epset) +{ + struct stm32_ep_s *privep = NULL; + irqstate_t flags; + int epndx = 0; + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints + * (skipping EP0) + */ + + for (epndx = 1; epndx < STM32_NENDPOINTS; epndx++) + { + uint8_t bit = STM32_ENDP_BIT(epndx); + if ((epset & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail &= ~bit; + + /* And return the pointer to the standard endpoint structure */ + + privep = &priv->eplist[epndx]; + break; + } + } + } + + leave_critical_section(flags); + return privep; +} + +/**************************************************************************** + * Name: stm32_epunreserve + ****************************************************************************/ + +static inline void +stm32_epunreserve(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= STM32_ENDP_BIT(USB_EPNO(privep->ep.eplog)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_epreserved + ****************************************************************************/ + +static inline bool +stm32_epreserved(struct stm32_usbdev_s *priv, int epno) +{ + return ((priv->epavail & STM32_ENDP_BIT(epno)) == 0); +} + +/**************************************************************************** + * Name: stm32_epallocpma + ****************************************************************************/ + +static int stm32_epallocpma(struct stm32_usbdev_s *priv) +{ + irqstate_t flags; + int bufno = ERROR; + int bufndx; + + flags = enter_critical_section(); + for (bufndx = 2; bufndx < STM32_NBUFFERS; bufndx++) + { + /* Check if this buffer is available */ + + uint8_t bit = STM32_BUFFER_BIT(bufndx); + if ((priv->bufavail & bit) != 0) + { + /* Yes.. Mark the endpoint no longer available */ + + priv->bufavail &= ~bit; + + /* And return the index of the allocated buffer */ + + bufno = bufndx; + break; + } + } + + leave_critical_section(flags); + return bufno; +} + +/**************************************************************************** + * Name: stm32_epfreepma + ****************************************************************************/ + +static inline void +stm32_epfreepma(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= STM32_ENDP_BIT(privep->bufno); + leave_critical_section(flags); +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_epconfigure + ****************************************************************************/ + +static int stm32_epconfigure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct stm32_ep_s *privep = (struct stm32_ep_s *)ep; + uint16_t pma; + uint16_t setting; + uint16_t maxpacket; + uint8_t epno; + +#ifdef CONFIG_DEBUG + if (!ep || !desc) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p desc=%p\n"); + return -EINVAL; + } +#endif + + /* Get the unadorned endpoint address */ + + epno = USB_EPNO(desc->addr); + usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno); + DEBUGASSERT(epno == USB_EPNO(ep->eplog)); + + /* Set the requested type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + setting = USB_EPR_EPTYPE_INTERRUPT; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + setting = USB_EPR_EPTYPE_BULK; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ +#warning "REVISIT: Need to review isochronous EP setup" + setting = USB_EPR_EPTYPE_ISOC; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint */ + setting = USB_EPR_EPTYPE_CONTROL; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPTYPE), (uint16_t)desc->type); + return -EINVAL; + } + + stm32_seteptype(epno, setting); + + /* Get the address of the PMA buffer allocated for this endpoint */ + +#warning "REVISIT: Should configure BULK EPs using double buffer feature" + pma = STM32_BUFNO2BUF(privep->bufno); + + /* Get the maxpacket size of the endpoint. */ + + maxpacket = GETUINT16(desc->mxpacketsize); + DEBUGASSERT(maxpacket <= STM32_MAXPACKET_SIZE); + ep->maxpacket = maxpacket; + + /* Get the subset matching the requested direction */ + + if (USB_ISEPIN(desc->addr)) + { + /* The full, logical EP number includes direction */ + + ep->eplog = USB_EPIN(epno); + + /* Set up TX; disable RX */ + + stm32_seteptxaddr(epno, pma); + stm32_seteptxstatus(epno, USB_EPR_STATTX_NAK); + stm32_seteprxstatus(epno, USB_EPR_STATRX_DIS); + } + else + { + /* The full, logical EP number includes direction */ + + ep->eplog = USB_EPOUT(epno); + + /* Set up RX; disable TX */ + + stm32_seteprxaddr(epno, pma); + stm32_seteprxcount(epno, maxpacket); + stm32_seteprxstatus(epno, USB_EPR_STATRX_VALID); + stm32_seteptxstatus(epno, USB_EPR_STATTX_DIS); + } + + stm32_dumpep(epno); + return OK; +} + +/**************************************************************************** + * Name: stm32_epdisable + ****************************************************************************/ + +static int stm32_epdisable(struct usbdev_ep_s *ep) +{ + struct stm32_ep_s *privep = (struct stm32_ep_s *)ep; + irqstate_t flags; + uint8_t epno; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p\n", ep); + return -EINVAL; + } +#endif + + epno = USB_EPNO(ep->eplog); + usbtrace(TRACE_EPDISABLE, epno); + + /* Cancel any ongoing activity */ + + flags = enter_critical_section(); + stm32_cancelrequests(privep); + + /* Disable TX; disable RX */ + + stm32_seteprxcount(epno, 0); + stm32_seteprxstatus(epno, USB_EPR_STATRX_DIS); + stm32_seteptxstatus(epno, USB_EPR_STATTX_DIS); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_epallocreq + ****************************************************************************/ + +static struct usbdev_req_s *stm32_epallocreq(struct usbdev_ep_s *ep) +{ + struct stm32_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, USB_EPNO(ep->eplog)); + + privreq = (struct stm32_req_s *)kmm_malloc(sizeof(struct stm32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct stm32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: stm32_epfreereq + ****************************************************************************/ + +static void stm32_epfreereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct stm32_req_s *privreq = (struct stm32_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, USB_EPNO(ep->eplog)); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: stm32_epsubmit + ****************************************************************************/ + +static int stm32_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct stm32_req_s *privreq = (struct stm32_req_s *)req; + struct stm32_ep_s *privep = (struct stm32_ep_s *)ep; + struct stm32_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + ulldbg("ERROR: driver=%p\n", priv->driver); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + epno = USB_EPNO(ep->eplog); + req->result = -EINPROGRESS; + req->xfrd = 0; + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + stm32_abortrequest(privep, privreq, -EBUSY); + ulldbg("ERROR: stalled\n"); + ret = -EBUSY; + } + + /* Handle IN (device-to-host) requests. NOTE: If the class device is + * using the bi-directional EP0, then we assume that they intend the EP0 + * IN functionality. + */ + + else if (USB_ISEPIN(ep->eplog) || epno == EP0) + { + /* Add the new request to the request queue for the IN endpoint */ + + stm32_rqenqueue(privep, privreq); + usbtrace(TRACE_INREQQUEUED(epno), req->len); + + /* If the IN endpoint FIFO is available, then transfer the data now */ + + if (!privep->txbusy) + { + priv->txstatus = USB_EPR_STATTX_NAK; + if (epno == EP0) + { + ret = stm32_wrrequest_ep0(priv, privep); + } + else + { + ret = stm32_wrrequest(priv, privep); + } + + /* Set the new TX status */ + + stm32_seteptxstatus(epno, priv->txstatus); + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + /* Add the new request to the request queue for the OUT endpoint */ + + privep->txnullpkt = 0; + stm32_rqenqueue(privep, privreq); + usbtrace(TRACE_OUTREQQUEUED(epno), req->len); + + /* This there a incoming data pending the availability of a request? */ + + if (priv->rxpending) + { + /* Set STAT_RX bits to '11' in the USB_EPnR, enabling further + * transactions. "While the STAT_RX bits are equal to '10' + * (NAK), any OUT request addressed to that endpoint is NAKed, + * indicating a flow control condition: the USB host will retry + * the transaction until it succeeds." + */ + + priv->rxstatus = USB_EPR_STATRX_VALID; + stm32_seteprxstatus(epno, priv->rxstatus); + + /* Data is no longer pending */ + + priv->rxpending = false; + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_epcancel + ****************************************************************************/ + +static int stm32_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct stm32_ep_s *privep = (struct stm32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); + + flags = enter_critical_section(); + stm32_cancelrequests(privep); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_epstall + ****************************************************************************/ + +static int stm32_epstall(struct usbdev_ep_s *ep, bool resume) +{ + struct stm32_ep_s *privep; + struct stm32_usbdev_s *priv; + uint8_t epno; + uint16_t status; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + privep = (struct stm32_ep_s *)ep; + priv = (struct stm32_usbdev_s *)privep->dev; + epno = USB_EPNO(ep->eplog); + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, USB_EPNO(ep->eplog)); + + /* Get status of the endpoint; stall the request if the endpoint is + * disabled + */ + + if (USB_ISEPIN(ep->eplog)) + { + status = stm32_geteptxstatus(epno); + } + else + { + status = stm32_geteprxstatus(epno); + } + + if (status == 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPDISABLED), 0); + + if (epno == 0) + { + priv->ep0state = EP0STATE_STALLED; + } + + return -ENODEV; + } + + /* Handle the resume condition */ + + if (resume) + { + /* Resuming a stalled endpoint */ + + usbtrace(TRACE_EPRESUME, epno); + privep->stalled = false; + + if (USB_ISEPIN(ep->eplog)) + { + /* IN endpoint */ + + if (stm32_eptxstalled(epno)) + { + stm32_clrtxdtog(epno); + + /* Restart any queued write requests */ + + priv->txstatus = USB_EPR_STATTX_NAK; + if (epno == EP0) + { + (void)stm32_wrrequest_ep0(priv, privep); + } + else + { + (void)stm32_wrrequest(priv, privep); + } + + /* Set the new TX status */ + + stm32_seteptxstatus(epno, priv->txstatus); + } + } + else + { + /* OUT endpoint */ + + if (stm32_eprxstalled(epno)) + { + if (epno == EP0) + { + /* After clear the STALL, enable the default endpoint receiver */ + + stm32_seteprxcount(epno, ep->maxpacket); + } + else + { + stm32_clrrxdtog(epno); + } + + priv->rxstatus = USB_EPR_STATRX_VALID; + stm32_seteprxstatus(epno, USB_EPR_STATRX_VALID); + } + } + } + + /* Handle the stall condition */ + + else + { + usbtrace(TRACE_EPSTALL, epno); + privep->stalled = true; + + if (USB_ISEPIN(ep->eplog)) + { + /* IN endpoint */ + + priv->txstatus = USB_EPR_STATTX_STALL; + stm32_seteptxstatus(epno, USB_EPR_STATTX_STALL); + } + else + { + /* OUT endpoint */ + + priv->rxstatus = USB_EPR_STATRX_STALL; + stm32_seteprxstatus(epno, USB_EPR_STATRX_STALL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_allocep + ****************************************************************************/ + +static struct usbdev_ep_s *stm32_allocep(struct usbdev_s *dev, uint8_t epno, + bool in, uint8_t eptype) +{ + struct stm32_usbdev_s *priv = (struct stm32_usbdev_s *)dev; + struct stm32_ep_s *privep = NULL; + uint8_t epset = STM32_ENDP_ALLSET; + int bufno; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epno >= STM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset = STM32_ENDP_BIT(epno); + } + + /* Check if the selected endpoint number is available */ + + privep = stm32_epreserve(priv, epset); + if (!privep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPRESERVE), (uint16_t)epset); + goto errout; + } + + /* Allocate a PMA buffer for this endpoint */ + +#warning "REVISIT: Should configure BULK EPs using double buffer feature" + bufno = stm32_epallocpma(priv); + if (bufno < 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPBUFFER), 0); + goto errout_with_ep; + } + + privep->bufno = (uint8_t)bufno; + return &privep->ep; + +errout_with_ep: + stm32_epunreserve(priv, privep); +errout: + return NULL; +} + +/**************************************************************************** + * Name: stm32_freeep + ****************************************************************************/ + +static void stm32_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) +{ + struct stm32_usbdev_s *priv; + struct stm32_ep_s *privep; + +#ifdef CONFIG_DEBUG + if (!dev || !ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + priv = (struct stm32_usbdev_s *)dev; + privep = (struct stm32_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)USB_EPNO(ep->eplog)); + + if (priv && privep) + { + /* Free the PMA buffer assigned to this endpoint */ + + stm32_epfreepma(priv, privep); + + /* Mark the endpoint as available */ + + stm32_epunreserve(priv, privep); + } +} + +/**************************************************************************** + * Name: stm32_getframe + ****************************************************************************/ + +static int stm32_getframe(struct usbdev_s *dev) +{ + uint16_t fnr; + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Return the last frame number detected by the hardware */ + + fnr = stm32_getreg(STM32_USB_FNR); + usbtrace(TRACE_DEVGETFRAME, fnr); + return (fnr & USB_FNR_FN_MASK); +} + +/**************************************************************************** + * Name: stm32_wakeup + ****************************************************************************/ + +static int stm32_wakeup(struct usbdev_s *dev) +{ + struct stm32_usbdev_s *priv = (struct stm32_usbdev_s *)dev; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Start the resume sequence. The actual resume steps will be driven + * by the ESOF interrupt. + */ + + flags = enter_critical_section(); + stm32_initresume(priv); + priv->rsmstate = RSMSTATE_STARTED; + + /* Disable the SUSP interrupt (until we are fully resumed), disable + * the WKUP interrupt (we are already waking up), and enable the + * ESOF interrupt that will drive the resume operations. Clear any + * pending ESOF interrupt. + */ + + stm32_setimask(priv, USB_CNTR_ESOFM, USB_CNTR_WKUPM | USB_CNTR_SUSPM); + stm32_putreg(~USB_ISTR_ESOF, STM32_USB_ISTR); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_selfpowered + ****************************************************************************/ + +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct stm32_usbdev_s *priv = (struct stm32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Initialization/Reset + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_reset + ****************************************************************************/ + +static void stm32_reset(struct stm32_usbdev_s *priv) +{ + int epno; + + /* Put the USB controller in reset, disable all interrupts */ + + stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR); + + /* Tell the class driver that we are disconnected. The class driver + * should then accept any new configurations. + */ + + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + + /* Reset the device state structure */ + + priv->ep0state = EP0STATE_IDLE; + priv->rsmstate = RSMSTATE_IDLE; + priv->rxpending = false; + + /* Reset endpoints */ + + for (epno = 0; epno < STM32_NENDPOINTS; epno++) + { + struct stm32_ep_s *privep = &priv->eplist[epno]; + + /* Cancel any queued requests. Since they are canceled + * with status -ESHUTDOWN, then will not be requeued + * until the configuration is reset. NOTE: This should + * not be necessary... the CLASS_DISCONNECT above should + * result in the class implementation calling stm32_epdisable + * for each of its configured endpoints. + */ + + stm32_cancelrequests(privep); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->halted = false; + privep->txbusy = false; + privep->txnullpkt = false; + } + + /* Re-configure the USB controller in its initial, unconnected state */ + + stm32_hwreset(priv); + priv->usbdev.speed = USB_SPEED_FULL; +} + +/**************************************************************************** + * Name: stm32_hwreset + ****************************************************************************/ + +static void stm32_hwreset(struct stm32_usbdev_s *priv) +{ + /* Put the USB controller into reset, clear all interrupt enables */ + + stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR); + + /* Disable interrupts (and perhaps take the USB controller out of reset) */ + + priv->imask = 0; + stm32_putreg(priv->imask, STM32_USB_CNTR); + + /* Set the STM32 BTABLE address */ + + stm32_putreg(STM32_BTABLE_ADDRESS & 0xfff8, STM32_USB_BTABLE); + + /* Initialize EP0 */ + + stm32_seteptype(EP0, USB_EPR_EPTYPE_CONTROL); + stm32_seteptxstatus(EP0, USB_EPR_STATTX_NAK); + stm32_seteprxaddr(EP0, STM32_EP0_RXADDR); + stm32_seteprxcount(EP0, STM32_EP0MAXPACKET); + stm32_seteptxaddr(EP0, STM32_EP0_TXADDR); + stm32_clrstatusout(EP0); + stm32_seteprxstatus(EP0, USB_EPR_STATRX_VALID); + + /* Set the device to respond on default address */ + + stm32_setdevaddr(priv, 0); + + /* Clear any pending interrupts */ + + stm32_putreg(0, STM32_USB_ISTR); + + /* Enable interrupts at the USB controller */ + + stm32_setimask(priv, STM32_CNTR_SETUP, (USB_CNTR_ALLINTS & ~STM32_CNTR_SETUP)); + stm32_dumpep(EP0); +} + +/**************************************************************************** + * Name: stm32_hwsetup + ****************************************************************************/ + +static void stm32_hwsetup(struct stm32_usbdev_s *priv) +{ + int epno; + + /* Power the USB controller, put the USB controller into reset, disable + * all USB interrupts + */ + + stm32_putreg(USB_CNTR_FRES|USB_CNTR_PDWN, STM32_USB_CNTR); + + /* Disconnect the device / disable the pull-up. We don't want the + * host to enumerate us until the class driver is registered. + */ + + stm32_usbpullup(&priv->usbdev, false); + + /* Initialize the device state structure. NOTE: many fields + * have the initial value of zero and, hence, are not explicitly + * initialized here. + */ + + memset(priv, 0, sizeof(struct stm32_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[EP0].ep; + priv->epavail = STM32_ENDP_ALLSET & ~STM32_ENDP_BIT(EP0); + priv->bufavail = STM32_BUFFER_ALLSET & ~STM32_BUFFER_EP0; + + /* Initialize the endpoint list */ + + for (epno = 0; epno < STM32_NENDPOINTS; epno++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the (physical) endpoint number which is just the index to the + * endpoint. + */ + + priv->eplist[epno].ep.ops = &g_epops; + priv->eplist[epno].dev = priv; + priv->eplist[epno].ep.eplog = epno; + + /* We will use a fixed maxpacket size for all endpoints (perhaps + * ISOC endpoints could have larger maxpacket???). A smaller + * packet size can be selected when the endpoint is configured. + */ + + priv->eplist[epno].ep.maxpacket = STM32_MAXPACKET_SIZE; + } + + /* Select a smaller endpoint size for EP0 */ + +#if STM32_EP0MAXPACKET < STM32_MAXPACKET_SIZE + priv->eplist[EP0].ep.maxpacket = STM32_EP0MAXPACKET; +#endif + + /* Configure the USB controller. USB uses the following GPIO pins: + * + * PA9 - VBUS + * PA10 - ID + * PA11 - DM + * PA12 - DP + * + * "As soon as the USB is enabled, these pins [DM and DP] are connected to + * the USB internal transceiver automatically." + */ + + /* Power up the USB controller, holding it in reset. There is a delay of + * about 1uS after applying power before the USB will behave predictably. + * A 5MS delay is more than enough. NOTE that we leave the USB controller + * in the reset state; the hardware will not be initialized until the + * class driver has been bound. + */ + + stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR); + up_mdelay(5); +} + +/**************************************************************************** + * Name: stm32_hwshutdown + ****************************************************************************/ + +static void stm32_hwshutdown(struct stm32_usbdev_s *priv) +{ + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable all interrupts and force the USB controller into reset */ + + stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR); + + /* Clear any pending interrupts */ + + stm32_putreg(0, STM32_USB_ISTR); + + /* Disconnect the device / disable the pull-up */ + + stm32_usbpullup(&priv->usbdev, false); + + /* Power down the USB controller */ + + stm32_putreg(USB_CNTR_FRES | USB_CNTR_PDWN, STM32_USB_CNTR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_usbinitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + + usbtrace(TRACE_DEVINIT, 0); + stm32_checksetup(); + + /* Configure USB GPIO alternate function pins */ + +#ifdef CONFIG_STM32_STM32F30XX + (void)stm32_configgpio(GPIO_USB_DM); + (void)stm32_configgpio(GPIO_USB_DP); +#endif + + /* Power up the USB controller, but leave it in the reset state */ + + stm32_hwsetup(priv); + + /* Remap the USB interrupt as needed (Only supported by the STM32 F3 family) */ + +#ifdef CONFIG_STM32_STM32F30XX +# ifdef CONFIG_STM32_USB_ITRMP + /* Clear the ITRMP bit to use the legacy, shared USB/CAN interrupts */ + + modifyreg32(STM32_RCC_APB1ENR, SYSCFG_CFGR1_USB_ITRMP, 0); +# else + /* Set the ITRMP bit to use the STM32 F3's dedicated USB interrupts */ + + modifyreg32(STM32_RCC_APB1ENR, 0, SYSCFG_CFGR1_USB_ITRMP); +# endif +#endif + + /* Attach USB controller interrupt handlers. The hardware will not be + * initialized and interrupts will not be enabled until the class device + * driver is bound. Getting the IRQs here only makes sure that we have + * them when we need them later. + */ + + if (irq_attach(STM32_IRQ_USBHP, stm32_hpinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_IRQREGISTRATION), + (uint16_t)STM32_IRQ_USBHP); + goto errout; + } + + if (irq_attach(STM32_IRQ_USBLP, stm32_lpinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_IRQREGISTRATION), + (uint16_t)STM32_IRQ_USBLP); + goto errout; + } + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + flags = enter_critical_section(); + usbtrace(TRACE_DEVUNINIT, 0); + + /* Disable and detach the USB IRQs */ + + up_disable_irq(STM32_IRQ_USBHP); + up_disable_irq(STM32_IRQ_USBLP); + irq_detach(STM32_IRQ_USBHP); + irq_detach(STM32_IRQ_USBLP); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Put the hardware in an inactive state */ + + stm32_hwshutdown(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BINDFAILED), (uint16_t)-ret); + } + else + { + /* Setup the USB controller -- enabling interrupts at the USB controller */ + + stm32_hwreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_USBHP); + up_enable_irq(STM32_IRQ_USBLP); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_USBHP, CONFIG_USB_PRI); + up_prioritize_irq(STM32_IRQ_USBLP, CONFIG_USB_PRI); +#endif + + /* Enable pull-up to connect the device. The host should enumerate us + * some time after this + */ + + stm32_usbpullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver. If the USB device is connected to a + * USB host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct stm32_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + stm32_reset(priv); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts (but keep them attached) */ + + up_disable_irq(STM32_IRQ_USBHP); + up_disable_irq(STM32_IRQ_USBLP); + + /* Put the hardware in an inactive state. Then bring the hardware back up + * in the reset state (this is probably not necessary, the stm32_reset() + * call above was probably sufficient). + */ + + stm32_hwshutdown(priv); + stm32_hwsetup(priv); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_STM32_USB */ diff --git a/arch/arm/src/stm32/stm32_usbdev.h b/arch/arm/src/stm32/stm32_usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..3ed55d01fdfe37cb70594a32d41f2ddff0054b4b --- /dev/null +++ b/arch/arm/src/stm32/stm32_usbdev.h @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_usbdev.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_USBDEV_H +#define __ARCH_ARM_SRC_STM32_STM32_USBDEV_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include "chip.h" +#include "chip/stm32_usbdev.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: stm32_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide stm32_pullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * + ************************************************************************************/ + +int stm32_usbpullup(FAR struct usbdev_s *dev, bool enable); + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_USBDEV_H */ + diff --git a/arch/arm/src/stm32/stm32_usbhost.c b/arch/arm/src/stm32/stm32_usbhost.c new file mode 100644 index 0000000000000000000000000000000000000000..0c3ff5a37ff059d5edf9a8788aa4ba44e3035693 --- /dev/null +++ b/arch/arm/src/stm32/stm32_usbhost.c @@ -0,0 +1,257 @@ +/******************************************************************************************** + * arch/arm/src/stm32/stm32_usbhost.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include +#include +#include + +#include "stm32_usbhost.h" + +#ifdef HAVE_USBHOST_TRACE + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +#define TR_FMT1 false +#define TR_FMT2 true + +#define TRENTRY(id,fmt1,string) {string} + +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + +/******************************************************************************************** + * Private Types + ********************************************************************************************/ + +struct stm32_usbhost_trace_s +{ +#if 0 + uint16_t id; + bool fmt2; +#endif + FAR const char *string; +}; + +/******************************************************************************************** + * Private Data + ********************************************************************************************/ + +static const struct stm32_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] = +{ +#ifdef CONFIG_STM32_OTGFS + + TRENTRY(OTGFS_TRACE1_DEVDISCONN, TR_FMT1, "OTGFS ERROR: Host Port %d. Device disconnected\n"), + TRENTRY(OTGFS_TRACE1_IRQATTACH, TR_FMT1, "OTGFS ERROR: Failed to attach IRQ\n"), + TRENTRY(OTGFS_TRACE1_TRNSFRFAILED, TR_FMT1, "OTGFS ERROR: Transfer Failed. ret=%d\n"), + TRENTRY(OTGFS_TRACE1_SENDSETUP, TR_FMT1, "OTGFS ERROR: ctrl_sendsetup() failed with: %d\n"), + TRENTRY(OTGFS_TRACE1_SENDDATA, TR_FMT1, "OTGFS ERROR: ctrl_senddata() failed with: %d\n"), + TRENTRY(OTGFS_TRACE1_RECVDATA, TR_FMT1, "OTGFS ERROR: ctrl_recvdata() failed with: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTGFS_VTRACE1_CONNECTED, TR_FMT1, "OTGFS Host Port %d connected.\n"), + TRENTRY(OTGFS_VTRACE1_DISCONNECTED, TR_FMT1, "OTGFS Host Port %d disconnected.\n"), + TRENTRY(OTGFS_VTRACE1_GINT, TR_FMT1, "OTGFS Handling Interrupt. Entry Point.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_SOF, TR_FMT1, "OTGFS Handle the start of frame interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_RXFLVL, TR_FMT1, "OTGFS Handle the RxFIFO non-empty interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_NPTXFE, TR_FMT1, "OTGFS Handle the non-periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_PTXFE, TR_FMT1, "OTGFS Handle the periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HC, TR_FMT1, "OTGFS Handle the host channels interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT, TR_FMT1, "OTGFS Handle the host port interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_POCCHNG, TR_FMT1, "OTGFS HPRT: Port Over-Current Change.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_PCDET, TR_FMT1, "OTGFS HPRT: Port Connect Detect.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_PENCHNG, TR_FMT1, "OTGFS HPRT: Port Enable Changed.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_LSDEV, TR_FMT1, "OTGFS HPRT: Low Speed Device Connected.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_FSDEV, TR_FMT1, "OTGFS HPRT: Full Speed Device Connected.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_LSFSSW, TR_FMT1, "OTGFS HPRT: Host Switch: LS -> FS.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_HPRT_FSLSSW, TR_FMT1, "OTGFS HPRT: Host Switch: FS -> LS.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_DISC, TR_FMT1, "OTGFS Handle the disconnect detected interrupt.\n"), + TRENTRY(OTGFS_VTRACE1_GINT_IPXFR, TR_FMT1, "OTGFS Handle the incomplete periodic transfer.\n"), + +# endif +#endif + +#ifdef CONFIG_STM32_OTGHS + + TRENTRY(OTGHS_TRACE1_DEVDISCONN, TR_FMT1, "OTGHS ERROR: Host Port %d. Device disconnected\n"), + TRENTRY(OTGHS_TRACE1_IRQATTACH, TR_FMT1, "OTGHS ERROR: Failed to attach IRQ\n"), + TRENTRY(OTGHS_TRACE1_TRNSFRFAILED, TR_FMT1, "OTGHS ERROR: Transfer Failed. ret=%d\n"), + TRENTRY(OTGHS_TRACE1_SENDSETUP, TR_FMT1, "OTGHS ERROR: ctrl_sendsetup() failed with: %d\n"), + TRENTRY(OTGHS_TRACE1_SENDDATA, TR_FMT1, "OTGHS ERROR: ctrl_senddata() failed with: %d\n"), + TRENTRY(OTGHS_TRACE1_RECVDATA, TR_FMT1, "OTGHS ERROR: ctrl_recvdata() failed with: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTGHS_VTRACE1_CONNECTED, TR_FMT1, "OTGHS Host Port %d connected.\n"), + TRENTRY(OTGHS_VTRACE1_DISCONNECTED, TR_FMT1, "OTGHS Host Port %d disconnected.\n"), + TRENTRY(OTGHS_VTRACE1_GINT, TR_FMT1, "OTGHS Handling Interrupt. Entry Point.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_SOF, TR_FMT1, "OTGHS Handle the start of frame interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_RXFLVL, TR_FMT1, "OTGHS Handle the RxFIFO non-empty interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_NPTXFE, TR_FMT1, "OTGHS Handle the non-periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_PTXFE, TR_FMT1, "OTGHS Handle the periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HC, TR_FMT1, "OTGHS Handle the host channels interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT, TR_FMT1, "OTGHS Handle the host port interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_POCCHNG, TR_FMT1, "OTGHS HPRT: Port Over-Current Change.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_PCDET, TR_FMT1, "OTGHS HPRT: Port Connect Detect.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_PENCHNG, TR_FMT1, "OTGHS HPRT: Port Enable Changed.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_LSDEV, TR_FMT1, "OTGHS HPRT: Low Speed Device Connected.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_HSDEV, TR_FMT1, "OTGHS HPRT: Full Speed Device Connected.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_LSHSSW, TR_FMT1, "OTGHS HPRT: Host Switch: LS -> HS.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_HPRT_HSLSSW, TR_FMT1, "OTGHS HPRT: Host Switch: HS -> LS.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_DISC, TR_FMT1, "OTGHS Handle the disconnect detected interrupt.\n"), + TRENTRY(OTGHS_VTRACE1_GINT_IPXFR, TR_FMT1, "OTGHS Handle the incomplete periodic transfer.\n"), + +# endif +#endif + +}; + +static const struct stm32_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] = +{ +#ifdef CONFIG_STM32_OTGFS + + TRENTRY(OTGFS_TRACE2_CLIP, TR_FMT2, "OTGFS CLIP: chidx: %d buflen: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTGFS_VTRACE2_CHANWAKEUP_IN, TR_FMT2, "OTGFS EP%d(IN) wake up with result: %d\n"), + TRENTRY(OTGFS_VTRACE2_CHANWAKEUP_OUT, TR_FMT2, "OTGFS EP%d(OUT) wake up with result: %d\n"), + TRENTRY(OTGFS_VTRACE2_CTRLIN, TR_FMT2, "OTGFS CTRL_IN type: %02x req: %02x\n"), + TRENTRY(OTGFS_VTRACE2_CTRLOUT, TR_FMT2, "OTGFS CTRL_OUT type: %02x req: %02x\n"), + TRENTRY(OTGFS_VTRACE2_INTRIN, TR_FMT2, "OTGFS INTR_IN chidx: %02x len: %02x\n"), + TRENTRY(OTGFS_VTRACE2_INTROUT, TR_FMT2, "OTGFS INTR_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTGFS_VTRACE2_BULKIN, TR_FMT2, "OTGFS BULK_IN chidx: %02x len: %02x\n"), + TRENTRY(OTGFS_VTRACE2_BULKOUT, TR_FMT2, "OTGFS BULK_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTGFS_VTRACE2_ISOCIN, TR_FMT2, "OTGFS ISOC_IN chidx: %02x len: %04d\n"), + TRENTRY(OTGFS_VTRACE2_ISOCOUT, TR_FMT2, "OTGFS ISOC_OUT chidx: %02x req: %02x\n"), + TRENTRY(OTGFS_VTRACE2_STARTTRANSFER, TR_FMT2, "OTGFS Transfer chidx: %d buflen: %d\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_CTRL_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,CTRL)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_CTRL_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,CTRL)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_INTR_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,INTR)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_INTR_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,INTR)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_BULK_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,BULK)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_BULK_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,BULK)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_ISOC_IN, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,IN ,ISOC)\n"), + TRENTRY(OTGFS_VTRACE2_CHANCONF_ISOC_OUT, TR_FMT2, "OTGFS Channel configured. chidx: %d: (EP%d,OUT,ISOC)\n"), + TRENTRY(OTGFS_VTRACE2_CHANHALT, TR_FMT2, "OTGFS Channel halted. chidx: %d, reason: %d\n"), + +# endif +#endif +#ifdef CONFIG_STM32_OTGHS + + TRENTRY(OTGHS_TRACE2_CLIP, TR_FMT2, "OTGHS CLIP: chidx: %d buflen: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTGHS_VTRACE2_CHANWAKEUP_IN, TR_FMT2, "OTGHS EP%d(IN) wake up with result: %d\n"), + TRENTRY(OTGHS_VTRACE2_CHANWAKEUP_OUT, TR_FMT2, "OTGHS EP%d(OUT) wake up with result: %d\n"), + TRENTRY(OTGHS_VTRACE2_CTRLIN, TR_FMT2, "OTGHS CTRL_IN type: %02x req: %02x\n"), + TRENTRY(OTGHS_VTRACE2_CTRLOUT, TR_FMT2, "OTGHS CTRL_OUT type: %02x req: %02x\n"), + TRENTRY(OTGHS_VTRACE2_INTRIN, TR_FMT2, "OTGHS INTR_IN chidx: %02x len: %02x\n"), + TRENTRY(OTGHS_VTRACE2_INTROUT, TR_FMT2, "OTGHS INTR_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTGHS_VTRACE2_BULKIN, TR_FMT2, "OTGHS BULK_IN chidx: %02x len: %02x\n"), + TRENTRY(OTGHS_VTRACE2_BULKOUT, TR_FMT2, "OTGHS BULK_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTGHS_VTRACE2_ISOCIN, TR_FMT2, "OTGHS ISOC_IN chidx: %02x len: %04d\n"), + TRENTRY(OTGHS_VTRACE2_ISOCOUT, TR_FMT2, "OTGHS ISOC_OUT chidx: %02x req: %02x\n"), + TRENTRY(OTGHS_VTRACE2_STARTTRANSFER, TR_FMT2, "OTGHS Transfer chidx: %d buflen: %d\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_CTRL_IN, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,IN ,CTRL)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_CTRL_OUT, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,OUT,CTRL)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_INTR_IN, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,IN ,INTR)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_INTR_OUT, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,OUT,INTR)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_BULK_IN, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,IN ,BULK)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_BULK_OUT, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,OUT,BULK)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_ISOC_IN, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,IN ,ISOC)\n"), + TRENTRY(OTGHS_VTRACE2_CHANCONF_ISOC_OUT, TR_FMT2, "OTGHS Channel configured. chidx: %d: (EP%d,OUT,ISOC)\n"), + TRENTRY(OTGHS_VTRACE2_CHANHALT, TR_FMT2, "OTGHS Channel halted. chidx: %d, reason: %d\n"), + +# endif +#endif +}; + +/******************************************************************************************** + * Private Function Prototypes + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ********************************************************************************************/ + +FAR const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +FAR const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} + +#endif /* HAVE_USBHOST_TRACE */ diff --git a/arch/arm/src/stm32/stm32_usbhost.h b/arch/arm/src/stm32/stm32_usbhost.h new file mode 100644 index 0000000000000000000000000000000000000000..2a6a7335446fe83bcd1ecd59f0952667f3cc6fed --- /dev/null +++ b/arch/arm/src/stm32/stm32_usbhost.h @@ -0,0 +1,292 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_usbhost.h + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_USBHOST_H +#define __ARCH_ARM_SRC_STM32_STM32_USBHOST_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +#include "chip.h" +#include "chip/stm32_otgfs.h" +#include "chip/stm32_otghs.h" + +#if (defined(CONFIG_STM32_OTGFS) || defined(CONFIG_STM32_OTGHS)) && defined(CONFIG_USBHOST) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + +#ifdef CONFIG_STM32_OTGFS + + OTGFS_TRACE1_DEVDISCONN, /* OTGFS ERROR: Host Port Device disconnected */ + OTGFS_TRACE1_IRQATTACH, /* OTGFS ERROR: Failed to attach IRQ */ + OTGFS_TRACE1_TRNSFRFAILED, /* OTGFS ERROR: Host Port Transfer Failed */ + OTGFS_TRACE1_SENDSETUP, /* OTGFS ERROR: sendsetup() failed with: */ + OTGFS_TRACE1_SENDDATA, /* OTGFS ERROR: senddata() failed with: */ + OTGFS_TRACE1_RECVDATA, /* OTGFS ERROR: recvdata() failed with: */ + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTGFS_VTRACE1_CONNECTED, /* OTGFS Host Port connected */ + OTGFS_VTRACE1_DISCONNECTED, /* OTGFS Host Port disconnected */ + OTGFS_VTRACE1_GINT, /* OTGFS Handling Interrupt. Entry Point */ + OTGFS_VTRACE1_GINT_SOF, /* OTGFS Handle the start of frame interrupt */ + OTGFS_VTRACE1_GINT_RXFLVL, /* OTGFS Handle the RxFIFO non-empty interrupt */ + OTGFS_VTRACE1_GINT_NPTXFE, /* OTGFS Handle the non-periodic TxFIFO empty interrupt */ + OTGFS_VTRACE1_GINT_PTXFE, /* OTGFS Handle the periodic TxFIFO empty interrupt */ + OTGFS_VTRACE1_GINT_HC, /* OTGFS Handle the host channels interrupt */ + OTGFS_VTRACE1_GINT_HPRT, /* OTGFS Handle the host port interrupt */ + OTGFS_VTRACE1_GINT_HPRT_POCCHNG, /* OTGFS HPRT: Port Over-Current Change*/ + OTGFS_VTRACE1_GINT_HPRT_PCDET, /* OTGFS HPRT: Port Connect Detect */ + OTGFS_VTRACE1_GINT_HPRT_PENCHNG, /* OTGFS HPRT: Port Enable Changed */ + OTGFS_VTRACE1_GINT_HPRT_LSDEV, /* OTGFS HPRT: Low Speed Device Connected */ + OTGFS_VTRACE1_GINT_HPRT_FSDEV, /* OTGFS HPRT: Full Speed Device Connected */ + OTGFS_VTRACE1_GINT_HPRT_LSFSSW, /* OTGFS HPRT: Host Switch: LS -> FS */ + OTGFS_VTRACE1_GINT_HPRT_FSLSSW, /* OTGFS HPRT: Host Switch: FS -> LS */ + OTGFS_VTRACE1_GINT_DISC, /* OTGFS Handle the disconnect detected interrupt */ + OTGFS_VTRACE1_GINT_IPXFR, /* OTGFS Handle the incomplete periodic transfer */ + +# endif +#endif + +#ifdef CONFIG_STM32_OTGHS + + OTGHS_TRACE1_DEVDISCONN, /* OTGHS ERROR: Host Port Device disconnected */ + OTGHS_TRACE1_IRQATTACH, /* OTGHS ERROR: Failed to attach IRQ */ + OTGHS_TRACE1_TRNSFRFAILED, /* OTGHS ERROR: Host Port Transfer Failed */ + OTGHS_TRACE1_SENDSETUP, /* OTGHS ERROR: sendsetup() failed with: */ + OTGHS_TRACE1_SENDDATA, /* OTGHS ERROR: senddata() failed with: */ + OTGHS_TRACE1_RECVDATA, /* OTGHS ERROR: recvdata() failed with: */ + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTGHS_VTRACE1_CONNECTED, /* OTGHS Host Port connected */ + OTGHS_VTRACE1_DISCONNECTED, /* OTGHS Host Port disconnected */ + OTGHS_VTRACE1_GINT, /* OTGHS Handling Interrupt. Entry Point */ + OTGHS_VTRACE1_GINT_SOF, /* OTGHS Handle the start of frame interrupt */ + OTGHS_VTRACE1_GINT_RXFLVL, /* OTGHS Handle the RxFIFO non-empty interrupt */ + OTGHS_VTRACE1_GINT_NPTXFE, /* OTGHS Handle the non-periodic TxFIFO empty interrupt */ + OTGHS_VTRACE1_GINT_PTXFE, /* OTGHS Handle the periodic TxFIFO empty interrupt */ + OTGHS_VTRACE1_GINT_HC, /* OTGHS Handle the host channels interrupt */ + OTGHS_VTRACE1_GINT_HPRT, /* OTGHS Handle the host port interrupt */ + OTGHS_VTRACE1_GINT_HPRT_POCCHNG, /* OTGHS HPRT: Port Over-Current Change*/ + OTGHS_VTRACE1_GINT_HPRT_PCDET, /* OTGHS HPRT: Port Connect Detect */ + OTGHS_VTRACE1_GINT_HPRT_PENCHNG, /* OTGHS HPRT: Port Enable Changed */ + OTGHS_VTRACE1_GINT_HPRT_LSDEV, /* OTGHS HPRT: Low Speed Device Connected */ + OTGHS_VTRACE1_GINT_HPRT_FSDEV, /* OTGHS HPRT: Full Speed Device Connected */ + OTGHS_VTRACE1_GINT_HPRT_LSFSSW, /* OTGHS HPRT: Host Switch: LS -> FS */ + OTGHS_VTRACE1_GINT_HPRT_FSLSSW, /* OTGHS HPRT: Host Switch: FS -> LS */ + OTGHS_VTRACE1_GINT_DISC, /* OTGHS Handle the disconnect detected interrupt */ + OTGHS_VTRACE1_GINT_IPXFR, /* OTGHS Handle the incomplete periodic transfer */ + +# endif +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + +#ifdef CONFIG_STM32_OTGFS + + OTGFS_TRACE2_CLIP, /* OTGFS CLIP: chidx: buflen: */ + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTGFS_VTRACE2_CHANWAKEUP_IN, /* OTGFS IN Channel wake up with result */ + OTGFS_VTRACE2_CHANWAKEUP_OUT, /* OTGFS OUT Channel wake up with result */ + OTGFS_VTRACE2_CTRLIN, /* OTGFS CTRLIN */ + OTGFS_VTRACE2_CTRLOUT, /* OTGFS CTRLOUT */ + OTGFS_VTRACE2_INTRIN, /* OTGFS INTRIN */ + OTGFS_VTRACE2_INTROUT, /* OTGFS INTROUT */ + OTGFS_VTRACE2_BULKIN, /* OTGFS BULKIN */ + OTGFS_VTRACE2_BULKOUT, /* OTGFS BULKOUT */ + OTGFS_VTRACE2_ISOCIN, /* OTGFS ISOCIN */ + OTGFS_VTRACE2_ISOCOUT, /* OTGFS ISOCOUT */ + OTGFS_VTRACE2_STARTTRANSFER, /* OTGFS EP buflen */ + OTGFS_VTRACE2_CHANCONF_CTRL_IN, + OTGFS_VTRACE2_CHANCONF_CTRL_OUT, + OTGFS_VTRACE2_CHANCONF_INTR_IN, + OTGFS_VTRACE2_CHANCONF_INTR_OUT, + OTGFS_VTRACE2_CHANCONF_BULK_IN, + OTGFS_VTRACE2_CHANCONF_BULK_OUT, + OTGFS_VTRACE2_CHANCONF_ISOC_IN, + OTGFS_VTRACE2_CHANCONF_ISOC_OUT, + OTGFS_VTRACE2_CHANHALT, /* Channel halted. chidx: , reason: */ + +# endif +#endif + +#ifdef CONFIG_STM32_OTGHS + + OTGHS_TRACE2_CLIP, /* OTGHS CLIP: chidx: buflen: */ + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTGHS_VTRACE2_CHANWAKEUP_IN, /* OTGHS IN Channel wake up with result */ + OTGHS_VTRACE2_CHANWAKEUP_OUT, /* OTGHS OUT Channel wake up with result */ + OTGHS_VTRACE2_CTRLIN, /* OTGHS CTRLIN */ + OTGHS_VTRACE2_CTRLOUT, /* OTGHS CTRLOUT */ + OTGHS_VTRACE2_INTRIN, /* OTGHS INTRIN */ + OTGHS_VTRACE2_INTROUT, /* OTGHS INTROUT */ + OTGHS_VTRACE2_BULKIN, /* OTGHS BULKIN */ + OTGHS_VTRACE2_BULKOUT, /* OTGHS BULKOUT */ + OTGHS_VTRACE2_ISOCIN, /* OTGHS ISOCIN */ + OTGHS_VTRACE2_ISOCOUT, /* OTGHS ISOCOUT */ + OTGHS_VTRACE2_STARTTRANSFER, /* OTGHS EP buflen */ + OTGHS_VTRACE2_CHANCONF_CTRL_IN, + OTGHS_VTRACE2_CHANCONF_CTRL_OUT, + OTGHS_VTRACE2_CHANCONF_INTR_IN, + OTGHS_VTRACE2_CHANCONF_INTR_OUT, + OTGHS_VTRACE2_CHANCONF_BULK_IN, + OTGHS_VTRACE2_CHANCONF_BULK_OUT, + OTGHS_VTRACE2_CHANCONF_ISOC_IN, + OTGHS_VTRACE2_CHANCONF_ISOC_OUT, + OTGHS_VTRACE2_CHANHALT, /* Channel halted. chidx: , reason: */ + +# endif +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) + +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +/* + * STM32 USB OTG FS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_STM32_OTGFS - Enable the STM32 USB OTG FS block + * or + * CONFIG_STM32_OTGHS - Enable the STM32 USB OTG HS block + * CONFIG_STM32_SYSCFG - Needed + * + * Options: + * + * CONFIG_STM32_OTGFS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_STM32_OTGFS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_STM32_OTGFS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_STM32_OTGFS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * + * CONFIG_STM32_OTGHS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_STM32_OTGHS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_STM32_OTGHS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_STM32_OTGHS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * + * CONFIG_STM32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG. + */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/*********************************************************************************** + * Name: stm32_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be provided be + * each platform that implements the STM32 OTG FS host interface + * + * "On-chip 5 V VBUS generation is not supported. For this reason, a charge pump + * or, if 5 V are available on the application board, a basic power switch, must + * be added externally to drive the 5 V VBUS line. The external charge pump can + * be driven by any GPIO output. When the application decides to power on VBUS + * using the chosen GPIO, it must also set the port power bit in the host port + * control and status register (PPWR bit in OTG_FS_HPRT). + * + * "The application uses this field to control power to this port, and the core + * clears this bit on an overcurrent condition." + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interface. Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ***********************************************************************************/ + +void stm32_usbhost_vbusdrive(int iface, bool enable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32_OTGFS && CONFIG_USBHOST */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_USBHOST_H */ diff --git a/arch/arm/src/stm32/stm32_userspace.c b/arch/arm/src/stm32/stm32_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..9e3a537d08932fb9758c6f0cc5ae8c0a64d7c341 --- /dev/null +++ b/arch/arm/src/stm32/stm32_userspace.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "stm32_mpuinit.h" +#include "stm32_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void stm32_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + stm32_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/stm32/stm32_userspace.h b/arch/arm/src/stm32/stm32_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..70614552d2d0cc369905f3379167a5be904d4583 --- /dev/null +++ b/arch/arm/src/stm32/stm32_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_userspace.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_USERSPACE_H +#define __ARCH_ARM_SRC_STM32_STM32_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_STM32_STM32_USERSPACE_H */ diff --git a/arch/arm/src/stm32/stm32_waste.c b/arch/arm/src/stm32/stm32_waste.c new file mode 100644 index 0000000000000000000000000000000000000000..a680b8b0f3db448dafa04105c1e10c24c1f7930e --- /dev/null +++ b/arch/arm/src/stm32/stm32_waste.c @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_waste.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "stm32_waste.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t idle_wastecounter = 0; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_waste(void) +{ + idle_wastecounter++; +} diff --git a/arch/arm/src/stm32/stm32_waste.h b/arch/arm/src/stm32/stm32_waste.h new file mode 100644 index 0000000000000000000000000000000000000000..4d13700ea2c78efc855c9af4ab7dcc21a79c01c4 --- /dev/null +++ b/arch/arm/src/stm32/stm32_waste.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_waste.h + * + * Copyright (C) 2011, 2015 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_WASTE_H +#define __ARCH_ARM_SRC_STM32_STM32_WASTE_H + +/* Waste CPU Time */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/** Waste CPU Time + * + * up_waste() is the logic that will be executed when portions of kernel + * or user-app is polling some register or similar, waiting for desired + * status. This time is wasted away. This function offers a measure of + * badly written piece of software or some undesired behavior. + * + * At the same time this function adds to some IDLE time which portion + * cannot be used for other purposes (yet). + **/ + +void up_waste(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_RRC_H */ diff --git a/arch/arm/src/stm32/stm32_wdg.h b/arch/arm/src/stm32/stm32_wdg.h new file mode 100644 index 0000000000000000000000000000000000000000..64815bfe908dc66576aa95528550a7406d05a07e --- /dev/null +++ b/arch/arm/src/stm32/stm32_wdg.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_wdg.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_WDG_H +#define __ARCH_ARM_SRC_STM32_STM32_WDG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_wdg.h" + +#ifdef CONFIG_WATCHDOG + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_iwdginitialize + * + * Description: + * Initialize the IWDG watchdog time. The watchdog timer is initialized + * and registers as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * lsifreq - The calibrated LSI clock frequency + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_IWDG +void stm32_iwdginitialize(FAR const char *devpath, uint32_t lsifreq); +#endif + +/**************************************************************************** + * Name: stm32_wwdginitialize + * + * Description: + * Initialize the WWDG watchdog time. The watchdog timer is initializeed and + * registers as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_WWDG +void stm32_wwdginitialize(FAR const char *devpath); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_WATCHDOG */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_WDG_H */ diff --git a/arch/arm/src/stm32/stm32_wwdg.c b/arch/arm/src/stm32/stm32_wwdg.c new file mode 100644 index 0000000000000000000000000000000000000000..5cab6ce92b6db5030869ce6ef0cb5e6010fcb4ec --- /dev/null +++ b/arch/arm/src/stm32/stm32_wwdg.c @@ -0,0 +1,816 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_wwdg.c + * + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "chip/stm32_dbgmcu.h" +#include "stm32_wdg.h" + +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_STM32_WWDG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Clocking *****************************************************************/ +/* The minimum frequency of the WWDG clock is: + * + * Fmin = PCLK1 / 4096 / 8 + * + * So the maximum delay (in milliseconds) is then: + * + * 1000 * (WWDG_CR_T_MAX+1) / Fmin + * + * For example, if PCLK1 = 42MHz, then the maximum delay is: + * + * Fmin = 1281.74 + * 1000 * 64 / Fmin = 49.93 msec + */ + +#define WWDG_FMIN (STM32_PCLK1_FREQUENCY / 4096 / 8) +#define WWDG_MAXTIMEOUT (1000 * (WWDG_CR_T_MAX+1) / WWDG_FMIN) + +/* Configuration ************************************************************/ + +#ifndef CONFIG_STM32_WWDG_DEFTIMOUT +# define CONFIG_STM32_WWDG_DEFTIMOUT WWDG_MAXTIMEOUT +#endif + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the watchdog + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_WATCHDOG +# define wddbg lldbg +# define wdvdbg llvdbg +#else +# define wddbg(x...) +# define wdvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct stm32_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ + xcpt_t handler; /* Current EWI interrupt handler */ + uint32_t timeout; /* The actual timeout value */ + uint32_t fwwdg; /* WWDG clock frequency */ + bool started; /* The timer has been started */ + uint8_t reload; /* The 7-bit reload field reset value */ + uint8_t window; /* The 7-bit window (W) field value */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_STM32_WWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint16_t val, uint32_t addr); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +#endif +static void stm32_setwindow(FAR struct stm32_lowerhalf_s *priv, + uint8_t window); + +/* Interrupt hanlding *******************************************************/ + +static int stm32_interrupt(int irq, FAR void *context); + +/* "Lower half" driver methods **********************************************/ + +static int stm32_start(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_stop(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int stm32_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int stm32_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); +static xcpt_t stm32_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler); +static int stm32_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = stm32_start, + .stop = stm32_stop, + .keepalive = stm32_keepalive, + .getstatus = stm32_getstatus, + .settimeout = stm32_settimeout, + .capture = stm32_capture, + .ioctl = stm32_ioctl, +}; + +/* "Lower half" driver state */ + +static struct stm32_lowerhalf_s g_wdgdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_WWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static uint16_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t count = 0; + static uint16_t preval = 0; + + /* Read the value from the register */ + + uint16_t val = getreg16(addr); + + /* Is this the same value that we read from the same registe last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%04x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_WWDG_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint16_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%04x\n", addr, val); + + /* Write the value */ + + putreg16(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_setwindow + * + * Description: + * Set the CFR window value. The window value is compared to the down- + * counter when the counter is updated. The WWDG counter should be updated + * only when the counter is below this window value (and greater than 64) + * otherwise a reset will be generated + * + ****************************************************************************/ + +static void stm32_setwindow(FAR struct stm32_lowerhalf_s *priv, uint8_t window) +{ + uint16_t regval; + + /* Set W[6:0] bits according to selected window value */ + + regval = stm32_getreg(STM32_WWDG_CFR); + regval &= ~WWDG_CFR_W_MASK; + regval |= window << WWDG_CFR_W_SHIFT; + stm32_putreg(regval, STM32_WWDG_CFR); + + /* Remember the window setting */ + + priv->window = window; +} + +/**************************************************************************** + * Name: stm32_interrupt + * + * Description: + * WWDG early warning interrupt + * + * Input Parameters: + * Usual interrupt handler arguments. + * + * Returned Values: + * Always returns OK. + * + ****************************************************************************/ + +static int stm32_interrupt(int irq, FAR void *context) +{ + FAR struct stm32_lowerhalf_s *priv = &g_wdgdev; + uint16_t regval; + + /* Check if the EWI interrupt is really pending */ + + regval = stm32_getreg(STM32_WWDG_SR); + if ((regval & WWDG_SR_EWIF) != 0) + { + /* Is there a registered handler? */ + + if (priv->handler) + { + /* Yes... NOTE: This interrupt service routine (ISR) must reload + * the WWDG counter to prevent the reset. Otherwise, we will reset + * upon return. + */ + + priv->handler(irq, context); + } + + /* The EWI interrupt is cleared by writing '0' to the EWIF bit in the + * WWDG_SR register. + */ + + regval &= ~WWDG_SR_EWIF; + stm32_putreg(regval, STM32_WWDG_SR); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* The watchdog is always disabled after a reset. It is enabled by setting + * the WDGA bit in the WWDG_CR register, then it cannot be disabled again + * except by a reset. + */ + + stm32_putreg(WWDG_CR_WDGA | WWDG_CR_T_RESET | priv->reload, STM32_WWDG_CR); + priv->started = true; + return OK; +} + +/**************************************************************************** + * Name: stm32_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + /* The watchdog is always disabled after a reset. It is enabled by setting + * the WDGA bit in the WWDG_CR register, then it cannot be disabled again + * except by a reset. + */ + + wdvdbg("Entry\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: stm32_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the watchdog timer or "petting the dog". + * + * The application program must write in the WWDG_CR register at regular + * intervals during normal operation to prevent an MCU reset. This operation + * must occur only when the counter value is lower than the window register + * value. The value to be stored in the WWDG_CR register must be between + * 0xff and 0xC0: + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Write to T[6:0] bits to configure the counter value, no need to do + * a read-modify-write; writing a 0 to WDGA bit does nothing. + */ + + stm32_putreg((WWDG_CR_T_RESET | priv->reload), STM32_WWDG_CR); + return OK; +} + +/**************************************************************************** + * Name: stm32_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the watchdog status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint32_t elapsed; + uint16_t reload; + + wdvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + + if (priv->handler) + { + status->flags |= WDFLAGS_CAPTURE; + } + + /* Return the actual timeout is milliseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the watchdog expires (in milliseconds) */ + + reload = (stm32_getreg(STM32_WWDG_CR) >> WWDG_CR_T_SHIFT) & 0x7f; + elapsed = priv->reload - reload; + status->timeleft = (priv->timeout * elapsed) / (priv->reload + 1); + + wdvdbg("Status :\n"); + wdvdbg(" flags : %08x\n", status->flags); + wdvdbg(" timeout : %d\n", status->timeout); + wdvdbg(" timeleft : %d\n", status->flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * timeout - The new timeout value in milliseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + uint32_t fwwdg; + uint32_t reload; + uint16_t regval; + int wdgtb; + + DEBUGASSERT(priv); + wdvdbg("Entry: timeout=%d\n", timeout); + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > WWDG_MAXTIMEOUT) + { + wddbg("Cannot represent timeout=%d > %d\n", + timeout, WWDG_MAXTIMEOUT); + return -ERANGE; + } + + /* Determine prescaler value. + * + * Fwwdg = PCLK1/4096/prescaler. + * + * Where + * Fwwwdg is the frequency of the WWDG clock + * wdgtb is one of {1, 2, 4, or 8} + */ + + /* Select the smallest prescaler that will result in a reload field value that is + * less than the maximum. + */ + + for (wdgtb = 0; ; wdgtb++) + { + /* WDGTB = 0 -> Divider = 1 = 1 << 0 + * WDGTB = 1 -> Divider = 2 = 1 << 1 + * WDGTB = 2 -> Divider = 4 = 1 << 2 + * WDGTB = 3 -> Divider = 8 = 1 << 3 + */ + + /* Get the WWDG counter frequency in Hz. */ + + fwwdg = (STM32_PCLK1_FREQUENCY/4096) >> wdgtb; + + /* The formula to calculate the timeout value is given by: + * + * timeout = 1000 * (reload + 1) / Fwwdg, OR + * reload = timeout * Fwwdg / 1000 - 1 + * + * Where + * timeout is the desired timout in milliseconds + * reload is the contents of T{5:0] + * Fwwdg is the frequency of the WWDG clock + */ + + reload = timeout * fwwdg / 1000 - 1; + + /* If this reload valid is less than the maximum or we are not ready + * at the prescaler value, then break out of the loop to use these + * settings. + */ + +#if 0 + wdvdbg("wdgtb=%d fwwdg=%d reload=%d timout=%d\n", + wdgtb, fwwdg, reload, 1000 * (reload + 1) / fwwdg); +#endif + if (reload <= WWDG_CR_T_MAX || wdgtb == 3) + { + /* Note that we explicitly break out of the loop rather than using + * the 'for' loop termination logic because we do not want the + * value of wdgtb to be incremented. + */ + + break; + } + } + + /* Make sure that the final reload value is within range */ + + if (reload > WWDG_CR_T_MAX) + { + reload = WWDG_CR_T_MAX; + } + + /* Calculate and save the actual timeout value in milliseconds: + * + * timeout = 1000 * (reload + 1) / Fwwdg + */ + + priv->timeout = 1000 * (reload + 1) / fwwdg; + + /* Remember the selected values */ + + priv->fwwdg = fwwdg; + priv->reload = reload; + + wdvdbg("wdgtb=%d fwwdg=%d reload=%d timout=%d\n", + wdgtb, fwwdg, reload, priv->timeout); + + /* Set WDGTB[1:0] bits according to calculated value */ + + regval = stm32_getreg(STM32_WWDG_CFR); + regval &= ~WWDG_CFR_WDGTB_MASK; + regval |= (uint16_t)wdgtb << WWDG_CFR_WDGTB_SHIFT; + stm32_putreg(regval, STM32_WWDG_CFR); + + /* Reset the 7-bit window value to the maximum value.. essentially disabling + * the lower limit of the watchdog reset time. + */ + + stm32_setwindow(priv, 0x7f); + return OK; +} + +/**************************************************************************** + * Name: stm32_capture + * + * Description: + * Don't reset on watchdog timer timeout; instead, call this user provider + * timeout handler. NOTE: Providing handler==NULL will restore the reset + * behavior. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new watchdog expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous watchdog expiration function pointer or NULL is there was + * no previous function pointer, i.e., if the previous behavior was + * reset-on-expiration (NULL is also returned if an error occurs). + * + ****************************************************************************/ + +static xcpt_t stm32_capture(FAR struct watchdog_lowerhalf_s *lower, + xcpt_t handler) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + irqstate_t flags; + xcpt_t oldhandler; + uint16_t regval; + + DEBUGASSERT(priv); + wdvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + flags = enter_critical_section(); + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + /* Are we attaching or detaching the handler? */ + + regval = stm32_getreg(STM32_WWDG_CFR); + if (handler) + { + /* Attaching... Enable the EWI interrupt */ + + regval |= WWDG_CFR_EWI; + stm32_putreg(regval, STM32_WWDG_CFR); + + up_enable_irq(STM32_IRQ_WWDG); + } + else + { + /* Detaching... Disable the EWI interrupt */ + + regval &= ~WWDG_CFR_EWI; + stm32_putreg(regval, STM32_WWDG_CFR); + + up_disable_irq(STM32_IRQ_WWDG); + } + + leave_critical_section(flags); + return oldhandler; +} + +/**************************************************************************** + * Name: stm32_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctl command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower; + int ret = -ENOTTY; + + DEBUGASSERT(priv); + wdvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg); + + /* WDIOC_MINTIME: Set the minimum ping time. If two keepalive ioctls + * are received within this time, a reset event will be generated. + * Argument: A 32-bit time value in milliseconds. + */ + + if (cmd == WDIOC_MINTIME) + { + uint32_t mintime = (uint32_t)arg; + + /* The minimum time should be strictly less than the total delay + * which, in turn, will be less than or equal to WWDG_CR_T_MAX + */ + + ret = -EINVAL; + if (mintime < priv->timeout) + { + uint32_t window = (priv->timeout - mintime) * priv->fwwdg / 1000 - 1; + DEBUGASSERT(window < priv->reload); + stm32_setwindow(priv, window | WWDG_CR_T_RESET); + ret = OK; + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_wwdginitialize + * + * Description: + * Initialize the WWDG watchdog time. The watchdog timer is initialized and + * registers as 'devpath. The initial state of the watchdog time is + * disabled. + * + * Input Parameters: + * devpath - The full path to the watchdog. This should be of the form + * /dev/watchdog0 + * + * Returned Values: + * None + * + ****************************************************************************/ + +void stm32_wwdginitialize(FAR const char *devpath) +{ + FAR struct stm32_lowerhalf_s *priv = &g_wdgdev; + + wdvdbg("Entry: devpath=%s\n", devpath); + + /* NOTE we assume that clocking to the IWDG has already been provided by + * the RCC initialization logic. + */ + + /* Initialize the driver state structure. Here we assume: (1) the state + * structure lies in .bss and was zeroed at reset time. (2) This function + * is only called once so it is never necessary to re-zero the structure. + */ + + priv->ops = &g_wdgops; + + /* Attach our EWI interrupt handler (But don't enable it yet) */ + + (void)irq_attach(STM32_IRQ_WWDG, stm32_interrupt); + + /* Select an arbitrary initial timeout value. But don't start the watchdog + * yet. NOTE: If the "Hardware watchdog" feature is enabled through the + * device option bits, the watchdog is automatically enabled at power-on. + */ + + stm32_settimeout((FAR struct watchdog_lowerhalf_s *)priv, + CONFIG_STM32_WWDG_DEFTIMOUT); + + /* Register the watchdog driver as /dev/watchdog0 */ + + (void)watchdog_register(devpath, (FAR struct watchdog_lowerhalf_s *)priv); + + /* When the microcontroller enters debug mode (Cortex™-M4F core halted), + * the WWDG counter either continues to work normally or stops, depending + * on DBG_WWDG_STOP configuration bit in DBG module. + */ + +#if defined(CONFIG_STM32_JTAG_FULL_ENABLE) || \ + defined(CONFIG_STM32_JTAG_NOJNTRST_ENABLE) || \ + defined(CONFIG_STM32_JTAG_SW_ENABLE) + { +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F40XX) + uint32_t cr = getreg32(STM32_DBGMCU_APB1_FZ); + cr |= DBGMCU_APB1_WWDGSTOP; + putreg32(cr, STM32_DBGMCU_APB1_FZ); +#else /* if defined(CONFIG_STM32_STM32F10XX) */ + uint32_t cr = getreg32(STM32_DBGMCU_CR); + cr |= DBGMCU_CR_WWDGSTOP; + putreg32(cr, STM32_DBGMCU_CR); +#endif + } +#endif +} + +#endif /* CONFIG_WATCHDOG && CONFIG_STM32_WWDG */ diff --git a/arch/arm/src/stm32/stm32f10xxx_dma.c b/arch/arm/src/stm32/stm32f10xxx_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..8c5bf161e6ae4fcd734e9d19dc38e93e7f05b17a --- /dev/null +++ b/arch/arm/src/stm32/stm32f10xxx_dma.c @@ -0,0 +1,753 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f10xxx_dma.c + * + * Copyright (C) 2009, 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" +#include "stm32_dma.h" +#include "stm32.h" + + +#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32L15XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NCHANNELS 7 +#if STM32_NDMA > 1 +# define DMA2_NCHANNELS 5 +# define DMA_NCHANNELS (DMA1_NCHANNELS+DMA2_NCHANNELS) +#else +# define DMA_NCHANNELS DMA1_NCHANNELS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA channel base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes one DMA channel */ + +struct stm32_dma_s +{ + uint8_t chan; /* DMA channel number (0-6) */ + uint8_t irq; /* DMA channel IRQ number */ + sem_t sem; /* Used to wait for DMA channel to become available */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32_dma_s g_dma[DMA_NCHANNELS] = +{ + { + .chan = 0, + .irq = STM32_IRQ_DMA1CH1, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32_IRQ_DMA1CH2, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32_IRQ_DMA1CH3, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2), + }, + { + .chan = 3, + .irq = STM32_IRQ_DMA1CH4, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3), + }, + { + .chan = 4, + .irq = STM32_IRQ_DMA1CH5, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4), + }, + { + .chan = 5, + .irq = STM32_IRQ_DMA1CH6, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5), + }, + { + .chan = 6, + .irq = STM32_IRQ_DMA1CH7, + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6), + }, +#if STM32_NDMA > 1 + { + .chan = 0, + .irq = STM32_IRQ_DMA2CH1, + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32_IRQ_DMA2CH2, + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32_IRQ_DMA2CH3, + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(2), + }, + { + .chan = 3, +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32L15XX) + .irq = STM32_IRQ_DMA2CH4, +#else + .irq = STM32_IRQ_DMA2CH45, +#endif + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3), + }, + { + .chan = 4, +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32L15XX) + .irq = STM32_IRQ_DMA2CH5, +#else + .irq = STM32_IRQ_DMA2CH45, +#endif + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(4), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32_dma_s *dmach, uint32_t offset) +{ + return getreg32(DMA_BASE(dmach->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmach->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmachan_getreg(struct stm32_dma_s *dmach, uint32_t offset) +{ + return getreg32(dmach->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmachan_putreg(struct stm32_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, dmach->base + offset); +} + +/************************************************************************************ + * Name: stm32_dmatake() and stm32_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32_dmatake(FAR struct stm32_dma_s *dmach) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmach->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32_dmagive(FAR struct stm32_dma_s *dmach) +{ + (void)sem_post(&dmach->sem); +} + +/************************************************************************************ + * Name: stm32_dmachandisable + * + * Description: + * Disable the DMA channel + * + ************************************************************************************/ + +static void stm32_dmachandisable(struct stm32_dma_s *dmach) +{ + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET); + regval &= ~DMA_CCR_ALLINTS; + + /* Disable the DMA channel */ + + regval &= ~DMA_CCR_EN; + dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval); + + /* Clear pending channel interrupts */ + + dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, DMA_ISR_CHAN_MASK(dmach->chan)); +} + +/************************************************************************************ + * Name: stm32_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32_dmainterrupt(int irq, void *context) +{ + struct stm32_dma_s *dmach; + uint32_t isr; + int chndx = 0; + + /* Get the channel structure from the interrupt number */ + + if (irq >= STM32_IRQ_DMA1CH1 && irq <= STM32_IRQ_DMA1CH7) + { + chndx = irq - STM32_IRQ_DMA1CH1; + } + else +#if STM32_NDMA > 1 +#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32L15XX) + if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH5) +#else + if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH45) +#endif + { + chndx = irq - STM32_IRQ_DMA2CH1 + DMA1_NCHANNELS; + } + else +#endif + { + PANIC(); + } + dmach = &g_dma[chndx]; + + /* Get the interrupt status (for this channel only) */ + + isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan); + + /* Clear the interrupts we are handling */ + + dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr); + + /* Invoke the callback */ + + if (dmach->callback) + { + dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(dmach->chan), dmach->arg); + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32_dma_s *dmach; + int chndx; + + /* Initialize each DMA channel */ + + for (chndx = 0; chndx < DMA_NCHANNELS; chndx++) + { + dmach = &g_dma[chndx]; + sem_init(&dmach->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmach->irq, stm32_dmainterrupt); + + /* Disable the DMA channel */ + + stm32_dmachandisable(dmach); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmach->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmach->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chndx' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chndx - Identifies the stream/channel resource. For the STM32 F1, this + * is simply the channel number as provided by the DMACHAN_* definitions + * in chip/stm32f10xxx_dma.h. + * + * Returned Value: + * Provided that 'chndx' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chndx' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int chndx) +{ + struct stm32_dma_s *dmach = &g_dma[chndx]; + + DEBUGASSERT(chndx < DMA_NCHANNELS); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32_dmatake(dmach); + + /* The caller now has exclusive use of the DMA channel */ + + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32_dmagive(dmach); +} + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + uint32_t regval; + + /* Then DMA_CNDTRx register can only be modified if the DMA channel is + * disabled. + */ + + regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_EN); + dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval); + + /* Set the peripheral register address in the DMA_CPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmachan_putreg(dmach, STM32_DMACHAN_CPAR_OFFSET, paddr); + + /* Set the memory address in the DMA_CMARx register. The data will be + * written to or read from this memory after the peripheral event. + */ + + dmachan_putreg(dmach, STM32_DMACHAN_CMAR_OFFSET, maddr); + + /* Configure the total number of data to be transferred in the DMA_CNDTRx + * register. After each peripheral event, this value will be decremented. + */ + + dmachan_putreg(dmach, STM32_DMACHAN_CNDTR_OFFSET, ntransfers); + + /* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx + * register. Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register. + */ + + regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + ccr &= (DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + regval |= ccr; + dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval); +} + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + uint32_t ccr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked whent the DMA commpletes */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Activate the channel by setting the ENABLE bit in the DMA_CCRx register. + * As soon as the channel is enabled, it can serve any DMA request from the + * peripheral connected on the channel. + */ + + ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET); + ccr |= DMA_CCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular mode, + * always interrupt on buffer wrap, and optionally interrupt at the halfway point. + */ + + if ((ccr & DMA_CCR_CIRC) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + ccr |= (half ? (DMA_CCR_HTIE | DMA_CCR_TEIE) : (DMA_CCR_TCIE | DMA_CCR_TEIE)); + } + else + { + /* In nonstop mode, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE; + } + + dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, ccr); +} + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + stm32_dmachandisable(dmach); +} + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + + return dmachan_getreg(dmach, STM32_DMACHAN_CNDTR_OFFSET); +} + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size; + uint32_t mend; + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_CCR_MSIZE_MASK) + { + case DMA_CCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_CCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_CCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default: + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + return false; + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK)) + { + return false; + } + + switch (maddr & STM32_REGION_MASK) + { +#if defined(CONFIG_STM32_STM32F10XX) + case STM32_FSMC_BANK1: + case STM32_FSMC_BANK2: + case STM32_FSMC_BANK3: + case STM32_FSMC_BANK4: +#endif + case STM32_SRAM_BASE: + case STM32_CODE_BASE: + /* All RAM and flash is supported */ + + return true; + + default: + /* Everything else is unsupported by DMA */ + + return false; + } +} +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + irqstate_t flags; + + flags = enter_critical_section(); + regs->isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET); + regs->ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET); + regs->cndtr = dmachan_getreg(dmach, STM32_DMACHAN_CNDTR_OFFSET); + regs->cpar = dmachan_getreg(dmach, STM32_DMACHAN_CPAR_OFFSET); + regs->cmar = dmachan_getreg(dmach, STM32_DMACHAN_CMAR_OFFSET); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg) +{ + struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmach->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" ISRC[%08x]: %08x\n", dmabase + STM32_DMA_ISR_OFFSET, regs->isr); + dmadbg(" CCR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CCR_OFFSET, regs->ccr); + dmadbg(" CNDTR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CNDTR_OFFSET, regs->cndtr); + dmadbg(" CPAR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CPAR_OFFSET, regs->cpar); + dmadbg(" CMAR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CMAR_OFFSET, regs->cmar); +} +#endif + +#endif /* CONFIG_STM32_STM32F10XX */ diff --git a/arch/arm/src/stm32/stm32f10xxx_rcc.c b/arch/arm/src/stm32/stm32f10xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..736b3ee7ef80a29b221461b6c87e2bf19b60fd34 --- /dev/null +++ b/arch/arm/src/stm32/stm32f10xxx_rcc.c @@ -0,0 +1,781 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f10xxx_rcc.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Put all RCC registers in reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ + putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ + putreg32(RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN, STM32_RCC_AHBENR); /* FLITF and SRAM Clock ON */ + putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ + putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ + + regval = getreg32(STM32_RCC_CR); /* Set the HSION bit */ + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ + regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | + RCC_CFGR_PPRE2_MASK | RCC_CFGR_ADCPRE_MASK | RCC_CFGR_MCO_MASK); + putreg32(regval, STM32_RCC_CFGR); + + regval = getreg32(STM32_RCC_CR); /* Reset HSEON, CSSON and PLLON bits */ + regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */ + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK +#ifndef CONFIG_STM32_VALUELINE + | RCC_CFGR_USBPRE +#endif + ); + putreg32(regval, STM32_RCC_CFGR); + + putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ +} + +/**************************************************************************** + * Name: rcc_enableahb + * + * Description: + * Enable selected AHB peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb(void) +{ + uint32_t regval; + +#if defined(CONFIG_STM32_CONNECTIVITYLINE) && defined(CONFIG_STM32_OTGFS) + /* USB clock divider for USB OTG FS. This bit must be valid before + * enabling the USB clock in the RCC_AHBENR register. This bit can't be + * reset if the USB clock is enabled. + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_OTGFSPRE; + regval |= STM32_CFGR_OTGFSPRE; + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Always enable FLITF clock and SRAM clock */ + + regval = RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN; + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHBENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHBENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHBENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_FSMC + /* FSMC clock enable */ + + regval |= RCC_AHBENR_FSMCEN; +#endif + +#ifdef CONFIG_STM32_SDIO + /* SDIO clock enable */ + + regval |= RCC_AHBENR_SDIOEN; +#endif + +#ifdef CONFIG_STM32_CONNECTIVITYLINE +#ifdef CONFIG_STM32_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHBENR_OTGFSEN; +#endif + +#ifdef CONFIG_STM32_ETHMAC + /* Ethernet clock enable */ + + regval |= (RCC_AHBENR_ETHMACEN | RCC_AHBENR_ETHMACTXEN | RCC_AHBENR_ETHMACRXEN); +#endif +#endif + + putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + +#ifdef CONFIG_STM32_USB + /* USB clock divider for USB FS device. This bit must be valid before + * enabling the USB clock in the RCC_APB1ENR register. This bit can't be + * reset if the USB clock is enabled. + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_USBPRE; + regval |= STM32_CFGR_USBPRE; + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); +#ifdef CONFIG_STM32_TIM2 + /* Timer 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM2EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM3 + /* Timer 3 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM3EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM4 + /* Timer 4 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM4EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM5 + /* Timer 5 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM5EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM6 + /* Timer 6 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM6EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM7 + /* Timer 7 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM7EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM12 + /* Timer 12 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM12EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM13 + /* Timer 13 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM13EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM14 + /* Timer 14 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM14EN; +#endif +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window Watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI 2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI 3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART 3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32_UART4 + /* UART 4 clock enable */ + + regval |= RCC_APB1ENR_UART4EN; +#endif + +#ifdef CONFIG_STM32_UART5 + /* UART 5 clock enable */ + + regval |= RCC_APB1ENR_UART5EN; +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C 1 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C1EN; +#endif +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C2EN; +#endif +#endif + +#ifdef CONFIG_STM32_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + +#ifdef CONFIG_STM32_CAN1 + /* CAN1 clock enable */ + + regval |= RCC_APB1ENR_CAN1EN; +#endif + +#ifdef CONFIG_STM32_CAN2 + /* CAN2 clock enable. NOTE: CAN2 needs CAN1 clock as well. */ + + regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN); +#endif + +#ifdef CONFIG_STM32_BKP + /* Backup interface clock enable */ + + regval |= RCC_APB1ENR_BKPEN; +#endif + +#ifdef CONFIG_STM32_PWR + /* Power interface clock enable */ + + regval |= RCC_APB1ENR_PWREN; +#endif + +#if defined(CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + +#ifdef CONFIG_STM32_CEC + /* CEC clock enable */ + + regval |= RCC_APB1ENR_CECEN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + /* Enable GPIOA, GPIOB, ... and AFIO clocks */ + + regval = getreg32(STM32_RCC_APB2ENR); + regval |= (RCC_APB2ENR_AFIOEN +#if STM32_NGPIO > 0 + | RCC_APB2ENR_IOPAEN +#endif +#if STM32_NGPIO > 16 + | RCC_APB2ENR_IOPBEN +#endif +#if STM32_NGPIO > 32 + | RCC_APB2ENR_IOPCEN +#endif +#if STM32_NGPIO > 48 + | RCC_APB2ENR_IOPDEN +#endif +#if STM32_NGPIO > 64 + | RCC_APB2ENR_IOPEEN +#endif +#if STM32_NGPIO > 80 + | RCC_APB2ENR_IOPFEN +#endif +#if STM32_NGPIO > 96 + | RCC_APB2ENR_IOPGEN +#endif + ); + +#ifdef CONFIG_STM32_ADC1 + /* ADC 1 interface clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + +#ifdef CONFIG_STM32_ADC2 + /* ADC 2 interface clock enable */ + + regval |= RCC_APB2ENR_ADC2EN; +#endif + +#ifdef CONFIG_STM32_TIM1 + /* TIM1 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM1EN; +#endif +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI 1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_TIM8 + /* TIM8 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM8EN; +#endif +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32_ADC3 + /* ADC3 interface clock enable */ + + regval |= RCC_APB2ENR_ADC3EN; +#endif + +#ifdef CONFIG_STM32_TIM15 + /* TIM15 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM15EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM16 + /* TIM16 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM16EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM17 + /* TIM17 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM17EN; +#endif +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. This + * version is for the Connectivity Line parts. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && \ + defined(CONFIG_STM32_CONNECTIVITYLINE) +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + + /* Enable HSE */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Set flash wait states + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); + putreg32(regval, STM32_FLASH_ACR); + + /* Set up PLL input scaling (with source = PLL2) */ + + regval = getreg32(STM32_RCC_CFGR2); + regval &= ~(RCC_CFGR2_PREDIV2_MASK | RCC_CFGR2_PLL2MUL_MASK | + RCC_CFGR2_PREDIV1SRC_MASK | RCC_CFGR2_PREDIV1_MASK); + regval |= (STM32_PLL_PREDIV2 | STM32_PLL_PLL2MUL | + RCC_CFGR2_PREDIV1SRC_PLL2 | STM32_PLL_PREDIV1); + putreg32(regval, STM32_RCC_CFGR2); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PPRE2_MASK | RCC_CFGR_HPRE_MASK); + regval |= STM32_RCC_CFGR_PPRE2; + regval |= RCC_CFGR_HPRE_SYSCLK; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + + /* Enable PLL2 */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLL2ON; + putreg32(regval, STM32_RCC_CR); + + /* Wait for PLL2 ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL2RDY) == 0); + +#if defined(CONFIG_STM32_MII_MCO) || defined(CONFIG_STM32_RMII_MCO) + /* Setup PLL3 for MII/RMII clock on MCO */ + + regval = getreg32(STM32_RCC_CFGR2); + regval &= ~(RCC_CFGR2_PLL3MUL_MASK); + regval |= STM32_PLL_PLL3MUL; + putreg32(regval, STM32_RCC_CFGR2); + + /* Switch PLL3 on */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLL3ON; + putreg32(regval, STM32_RCC_CR); + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL3RDY) == 0); +#endif + + /* Set main PLL source and multiplier */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK); + regval |= (RCC_CFGR_PLLSRC | STM32_PLL_PLLMUL); + putreg32(regval, STM32_RCC_CFGR); + + /* Switch main PLL on */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + + /* Select PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until PLL is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_PLL) == 0); +} +#endif + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. This + * version is for the non-Connectivity Line parts. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && \ + !defined(CONFIG_STM32_CONNECTIVITYLINE) +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + + /* If the PLL is using the HSE, or the HSE is the system clock */ + +#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) + { + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + + if (timeout == 0) + { + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or misconfiguration. + */ + + return; + } + } + + /* If this is a value-line part and we are using the HSE as the PLL */ + +# if defined(CONFIG_STM32_VALUELINE) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) + +# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) +# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 +# endif + + /* Set the HSE prescaler */ + + regval = STM32_CFGR2_PREDIV1; + putreg32(regval, STM32_RCC_CFGR2); + +# endif +#endif + + /* Value-line devices don't implement flash prefetch/waitstates */ + +#ifndef CONFIG_STM32_VALUELINE + + /* Enable FLASH prefetch buffer and 2 wait states */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); + putreg32(regval, STM32_FLASH_ACR); + +#endif + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + + /* If we are using the PLL, configure and start it */ + +#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL + + /* Set the PLL divider and multiplier */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK); + regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLXTPRE | STM32_CFGR_PLLMUL); + putreg32(regval, STM32_RCC_CFGR); + + /* Enable the PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + +#endif + + /* Select the system clock source (probably the PLL) */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= STM32_SYSCLK_SW; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the selected source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); + +#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE */ + + stm32_rcc_enablelse(); +#endif +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb(); + rcc_enableapb2(); + rcc_enableapb1(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f20xxx_dma.c b/arch/arm/src/stm32/stm32f20xxx_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..39c40f59f65115ae6cb37b36d1bbfc04359eb0a0 --- /dev/null +++ b/arch/arm/src/stm32/stm32f20xxx_dma.c @@ -0,0 +1,1025 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f20xxx_dma.c + * + * Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" +#include "stm32_dma.h" +#include "stm32.h" + +/* This file supports only the STM32 F2 family (although it is identical to + * the corresponding F4 file). + */ + +#if defined(CONFIG_STM32_STM32F20XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NSTREAMS 8 +#if STM32_NDMA > 1 +# define DMA2_NSTREAMS 8 +# define DMA_NSTREAMS (DMA1_NSTREAMS+DMA2_NSTREAMS) +#else +# define DMA_NSTREAMS DMA1_NSTREAMS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA stream base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes one DMA channel */ + +struct stm32_dma_s +{ + uint8_t stream; /* DMA stream number (0-7) */ + uint8_t irq; /* DMA stream IRQ number */ + uint8_t shift; /* ISR/IFCR bit shift value */ + uint8_t channel; /* DMA channel number (0-7) */ + bool nonstop; /* Stream is configured in a non-stopping mode. */ + sem_t sem; /* Used to wait for DMA channel to become available */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32_dma_s g_dma[DMA_NSTREAMS] = +{ + { + .stream = 0, + .irq = STM32_IRQ_DMA1S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA1S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA1S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA1S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA1S4, + .shift = DMA_INT_STREAM4_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA1S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA1S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA1S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(7), + }, +#if STM32_NDMA > 1 + { + .stream = 0, + .irq = STM32_IRQ_DMA2S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA2S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA2S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA2S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA2S4, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA2S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA2S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA2S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(7), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(DMA_BASE(dmast->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmast->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmast_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(dmast->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmast_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, dmast->base + offset); +} + +/************************************************************************************ + * Name: stm32_dmatake() and stm32_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32_dmatake(FAR struct stm32_dma_s *dmast) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmast->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32_dmagive(FAR struct stm32_dma_s *dmast) +{ + (void)sem_post(&dmast->sem); +} + +/************************************************************************************ + * Name: stm32_dmastream + * + * Description: + * Get the g_dma table entry associated with a DMA controller and a stream number + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmastream(unsigned int stream, + unsigned int controller) +{ + int index; + + DEBUGASSERT(stream < DMA_NSTREAMS && controller < STM32_NDMA); + + /* Convert the controller + stream based on the fact that there are 8 streams + * per controller. + */ + +#if STM32_NDMA > 1 + index = controller << 3 | stream; +#else + index = stream; +#endif + + /* Then return the stream structure associated with the stream index */ + + return &g_dma[index]; +} + +/************************************************************************************ + * Name: stm32_dmamap + * + * Description: + * Get the g_dma table entry associated with a bit-encoded DMA selection + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmamap(unsigned long dmamap) +{ + /* Extract the DMA controller number from the bit encoded value */ + + unsigned int controller = STM32_DMA_CONTROLLER(dmamap); + + /* Extact the stream number from the bit encoded value */ + + unsigned int stream = STM32_DMA_STREAM(dmamap); + + /* Return the table entry associated with the controller + stream */ + + return stm32_dmastream(stream, controller); +} + +/************************************************************************************ + * Name: stm32_dmastreamdisable + * + * Description: + * Disable the DMA stream + * + ************************************************************************************/ + +static void stm32_dmastreamdisable(struct stm32_dma_s *dmast) +{ + uint32_t regoffset; + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~DMA_SCR_ALLINTS; + + /* Disable the DMA stream */ + + regval &= ~DMA_SCR_EN; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); +} + +/************************************************************************************ + * Name: stm32_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32_dmainterrupt(int irq, void *context) +{ + struct stm32_dma_s *dmast; + uint32_t status; + uint32_t regoffset = 0; + unsigned int stream = 0; + unsigned int controller = 0; + + /* Get the stream and the controller that generated the interrupt */ + + if (irq >= STM32_IRQ_DMA1S0 && irq <= STM32_IRQ_DMA1S6) + { + stream = irq - STM32_IRQ_DMA1S0; + controller = DMA1; + } + else if (irq == STM32_IRQ_DMA1S7) + { + stream = 7; + controller = DMA1; + } + else +#if STM32_NDMA > 1 + if (irq >= STM32_IRQ_DMA2S0 && irq <= STM32_IRQ_DMA2S4) + { + stream = irq - STM32_IRQ_DMA2S0; + controller = DMA2; + } + else if (irq >= STM32_IRQ_DMA2S5 && irq <= STM32_IRQ_DMA2S7) + { + stream = irq - STM32_IRQ_DMA2S5 + 5; + controller = DMA2; + } + else +#endif + { + PANIC(); + } + + /* Get the stream structure from the stream and controller numbers */ + + dmast = stm32_dmastream(stream, controller); + + /* Select the interrupt status register (either the LISR or HISR) + * based on the stream number that caused the interrupt. + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LISR_OFFSET; + } + else + { + regoffset = STM32_DMA_HISR_OFFSET; + } + + /* Get the interrupt status for this stream */ + + status = (dmabase_getreg(dmast, regoffset) >> dmast->shift) & DMA_STREAM_MASK; + + /* Clear fetched stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (status << dmast->shift)); + + /* Invoke the callback */ + + if (dmast->callback) + { + dmast->callback(dmast, status, dmast->arg); + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32_dma_s *dmast; + int stream; + + /* Initialize each DMA stream */ + + for (stream = 0; stream < DMA_NSTREAMS; stream++) + { + dmast = &g_dma[stream]; + sem_init(&dmast->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmast->irq, stm32_dmainterrupt); + + /* Disable the DMA stream */ + + stm32_dmastreamdisable(dmast); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmast->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmast->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * dmamap - Identifies the stream/channel resource. For the STM32 F2, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in chip/stm32f20xxx_dma.h + * + * Returned Value: + * Provided that 'dmamap' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'dmamap' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int dmamap) +{ + FAR struct stm32_dma_s *dmast; + + /* Get the stream index from the bit-encoded channel value */ + + dmast = stm32_dmamap(dmamap); + DEBUGASSERT(dmast != NULL); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32_dmatake(dmast); + + /* The caller now has exclusive use of the DMA channel. Assign the + * channel to the stream and return an opaque reference to the stream + * structure. + */ + + dmast->channel = STM32_DMA_CHANNEL(dmamap); + return (DMA_HANDLE)dmast; +} + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32_dmagive(dmast); +} + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t scr) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t regoffset; + uint32_t regval; + + dmadbg("paddr: %08x maddr: %08x ntransfers: %d scr: %08x\n", + paddr, maddr, ntransfers, scr); + + /* "If the stream is enabled, disable it by resetting the EN bit in the + * DMA_SxCR register, then read this bit in order to confirm that there is no + * ongoing stream operation. Writing this bit to 0 is not immediately + * effective since it is actually written to 0 once all the current transfers + * have finished. When the EN bit is read as 0, this means that the stream is + * ready to be configured. It is therefore necessary to wait for the EN bit + * to be cleared before starting any stream configuration. ..." + */ + + while ((dmast_getreg(dmast, STM32_DMA_SCR_OFFSET) & DMA_SCR_EN) != 0); + + /* "... All the stream dedicated bits set in the status register (DMA_LISR + * and DMA_HISR) from the previous data block DMA transfer should be cleared + * before the stream can be re-enabled." + * + * Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); + + /* "Set the peripheral register address in the DMA_SPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmast_putreg(dmast, STM32_DMA_SPAR_OFFSET, paddr); + + /* "Set the memory address in the DMA_SM0ARx ... register. The data will be + * written to or read from this memory after the peripheral event." + * + * Note that in double-buffered mode it is explicitly assumed that the second + * buffer immediately follows the first. + */ + + dmast_putreg(dmast, STM32_DMA_SM0AR_OFFSET, maddr); + if (scr & DMA_SCR_DBM) + { + dmast_putreg(dmast, STM32_DMA_SM1AR_OFFSET, maddr + ntransfers); + } + + /* "Configure the total number of data items to be transferred in the + * DMA_SNDTRx register. After each peripheral event, this value will be + * decremented." + * + * "When the peripheral flow controller is used for a given stream, the value + * written into the DMA_SxNDTR has no effect on the DMA transfer. Actually, + * whatever the value written, it will be forced by hardware to 0xFFFF as soon + * as the stream is enabled..." + */ + + dmast_putreg(dmast, STM32_DMA_SNDTR_OFFSET, ntransfers); + + /* "Select the DMA channel (request) using CHSEL[2:0] in the DMA_SxCR register." + * + * "Configure the stream priority using the PL[1:0] bits in the DMA_SCRx" + * register." + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PL_MASK | DMA_SCR_CHSEL_MASK); + regval |= scr & DMA_SCR_PL_MASK; + regval |= (uint32_t)dmast->channel << DMA_SCR_CHSEL_SHIFT; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* "Configure the FIFO usage (enable or disable, threshold in transmission and + * reception)" + * + * "Caution is required when choosing the FIFO threshold (bits FTH[1:0] of the + * DMA_SxFCR register) and the size of the memory burst (MBURST[1:0] of the + * DMA_SxCR register): The content pointed by the FIFO threshold must exactly + * match to an integer number of memory burst transfers. If this is not in the + * case, a FIFO error (flag FEIFx of the DMA_HISR or DMA_LISR register) will be + * generated when the stream is enabled, then the stream will be automatically + * disabled." + * + * The FIFO is disabled in circular mode when transferring data from a + * peripheral to memory, as in this case it is usually desirable to know that + * every byte from the peripheral is transferred immediately to memory. It is + * not practical to flush the DMA FIFO, as this requires disabling the channel + * which triggers the transfer-complete interrupt. + * + * NOTE: The FEIFx error interrupt is not enabled because the FEIFx seems to + * be reported spuriously causing good transfers to be marked as failures. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + regval &= ~(DMA_SFCR_FTH_MASK | DMA_SFCR_FS_MASK | DMA_SFCR_FEIE); + if (!((scr & (DMA_SCR_CIRC | DMA_SCR_DIR_MASK)) == (DMA_SCR_CIRC | DMA_SCR_DIR_P2M))) + { + regval |= (DMA_SFCR_FTH_FULL | DMA_SFCR_DMDIS); + } + dmast_putreg(dmast, STM32_DMA_SFCR_OFFSET, regval); + + /* "Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register." + * + * Note: The CT bit is always reset. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_CIRC | DMA_SCR_DBM | DMA_SCR_CT | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + scr &= (DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_DBM | DMA_SCR_CIRC | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + regval |= scr; + dmast->nonstop = (scr & (DMA_SCR_DBM | DMA_SCR_CIRC)) != 0; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); +} + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t scr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked whent the DMA commpletes */ + + dmast->callback = callback; + dmast->arg = arg; + + /* Activate the stream by setting the ENABLE bit in the DMA_SCRx register. + * As soon as the stream is enabled, it can serve any DMA request from the + * peripheral connected on the stream. + */ + + scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + scr |= DMA_SCR_EN; + + if (!dmast->nonstop) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + scr |= (half ? (DMA_SCR_HTIE | DMA_SCR_TEIE) : (DMA_SCR_TCIE | DMA_SCR_TEIE)); + } + else + { + /* In nonstop mode, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + scr |= (half ? DMA_SCR_HTIE : 0) | DMA_SCR_TCIE | DMA_SCR_TEIE; + } + + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, scr); +} + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + stm32_dmastreamdisable(dmast); +} + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Read the DMA bytes-remaining register. + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t residual; + + /* Fetch the count of bytes remaining to be transferred. + * + * If the FIFO is enabled, this count may be inaccurate. ST don't + * appear to document whether this counts the peripheral or the memory + * side of the channel, and they don't make the memory pointer + * available either. + * + * For reception in circular mode the FIFO is disabled in order that + * this value can be useful. + */ + + residual = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + + return (size_t)residual; +} + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size, burst_length; + uint32_t mend; + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & STM32_DMA_SCR_MSIZE_MASK) + { + case DMA_SCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_SCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_SCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + return false; + } + + /* Verify that burst transfers do not cross a 1KiB boundary. */ + + if ((maddr / 1024) != (mend / 1024)) + { + /* The transfer as a whole crosses a 1KiB boundary. + * Verify that no burst does by asserting that the address + * is aligned to the burst length. + */ + + switch (ccr & STM32_DMA_SCR_MBURST_MASK) + { + case DMA_SCR_MBURST_SINGLE: + burst_length = transfer_size; + break; + + case DMA_SCR_MBURST_INCR4: + burst_length = transfer_size << 2; + break; + + case DMA_SCR_MBURST_INCR8: + burst_length = transfer_size << 3; + break; + + case DMA_SCR_MBURST_INCR16: + burst_length = transfer_size << 4; + break; + + default: + return false; + } + + if ((maddr & (burst_length - 1)) != 0) + { + return false; + } + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK)) + { + return false; + } + + switch (maddr & STM32_REGION_MASK) + { + case STM32_FSMC_BANK1: + case STM32_FSMC_BANK2: + case STM32_FSMC_BANK3: + case STM32_FSMC_BANK4: + case STM32_SRAM_BASE: + case STM32_CODE_BASE: + /* All RAM and flash is supported */ + + return true; + + default: + /* Everything else is unsupported by DMA */ + + return false; + } +} +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + irqstate_t flags; + + flags = enter_critical_section(); + regs->lisr = dmabase_getreg(dmast, STM32_DMA_LISR_OFFSET); + regs->hisr = dmabase_getreg(dmast, STM32_DMA_HISR_OFFSET); + regs->scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regs->sndtr = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + regs->spar = dmast_getreg(dmast, STM32_DMA_SPAR_OFFSET); + regs->sm0ar = dmast_getreg(dmast, STM32_DMA_SM0AR_OFFSET); + regs->sm1ar = dmast_getreg(dmast, STM32_DMA_SM1AR_OFFSET); + regs->sfcr = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmast->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" LISR[%08x]: %08x\n", dmabase + STM32_DMA_LISR_OFFSET, regs->lisr); + dmadbg(" HISR[%08x]: %08x\n", dmabase + STM32_DMA_HISR_OFFSET, regs->hisr); + dmadbg(" SCR[%08x]: %08x\n", dmast->base + STM32_DMA_SCR_OFFSET, regs->scr); + dmadbg(" SNDTR[%08x]: %08x\n", dmast->base + STM32_DMA_SNDTR_OFFSET, regs->sndtr); + dmadbg(" SPAR[%08x]: %08x\n", dmast->base + STM32_DMA_SPAR_OFFSET, regs->spar); + dmadbg(" SM0AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM0AR_OFFSET, regs->sm0ar); + dmadbg(" SM1AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM1AR_OFFSET, regs->sm1ar); + dmadbg(" SFCR[%08x]: %08x\n", dmast->base + STM32_DMA_SFCR_OFFSET, regs->sfcr); +} +#endif + +#endif /* CONFIG_STM32_STM32F20XX */ diff --git a/arch/arm/src/stm32/stm32f20xxx_rcc.c b/arch/arm/src/stm32/stm32f20xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..a45241ed85b0d09e6ccdf47a5feb8a9741139f91 --- /dev/null +++ b/arch/arm/src/stm32/stm32f20xxx_rcc.c @@ -0,0 +1,695 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f20xxx_rcc.c + * + * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "stm32_pwr.h" + +/* This file supports only the STM32 F2 family (although it is identical to + * the corresponding F4 file). + */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Reset the RCC clock configuration to the default reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Enable the Internal High Speed clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + /* Reset CFGR register */ + + putreg32(0x00000000, STM32_RCC_CFGR); + + /* Reset HSEON, CSSON and PLLON bits */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + /* Reset PLLCFGR register to reset default */ + + putreg32(RCC_PLLCFG_RESET, STM32_RCC_PLLCFG); + + /* Reset HSEBYP bit */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + /* Disable all interrupts */ + + putreg32(0x00000000, STM32_RCC_CIR); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB1ENR); + + /* Enable GPIOA, GPIOB, .... GPIOI */ + +#if STM32_NGPIO > 0 + regval |= (RCC_AHB1ENR_GPIOAEN +#if STM32_NGPIO > 16 + | RCC_AHB1ENR_GPIOBEN +#endif +#if STM32_NGPIO > 32 + | RCC_AHB1ENR_GPIOCEN +#endif +#if STM32_NGPIO > 48 + | RCC_AHB1ENR_GPIODEN +#endif +#if STM32_NGPIO > 64 + | RCC_AHB1ENR_GPIOEEN +#endif +#if STM32_NGPIO > 80 + | RCC_AHB1ENR_GPIOFEN +#endif +#if STM32_NGPIO > 96 + | RCC_AHB1ENR_GPIOGEN +#endif +#if STM32_NGPIO > 112 + | RCC_AHB1ENR_GPIOHEN +#endif +#if STM32_NGPIO > 128 + | RCC_AHB1ENR_GPIOIEN +#endif + ); +#endif + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_BKPSRAM + /* Backup SRAM clock enable */ + + regval |= RCC_AHB1ENR_BKPSRAMEN; +#endif + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHB1ENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHB1ENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_ETHMAC + /* Ethernet MAC clocking */ + + regval |= (RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN); + +#ifdef CONFIG_STM32_ETH_PTP + /* Precision Time Protocol (PTP) */ + + regval |= RCC_AHB1ENR_ETHMACPTPEN; + +#endif +#endif + +#ifdef CONFIG_STM32_OTGHS + /* USB OTG HS */ + + regval |= (RCC_AHB1ENR_OTGHSEN | RCC_AHB1ENR_OTGHSULPIEN); +#endif + + putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR register to enabled the + * selected AHB2 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB2ENR); + +#ifdef CONFIG_STM32_DCMI + /* Camera interface enable */ + + regval |= RCC_AHB2ENR_DCMIEN; +#endif + +#ifdef CONFIG_STM32_CRYP + /* Cryptographic modules clock enable */ + + regval |= RCC_AHB2ENR_CRYPEN; +#endif + +#ifdef CONFIG_STM32_HASH + /* Hash modules clock enable */ + + regval |= RCC_AHB2ENR_HASHEN; +#endif + +#ifdef CONFIG_STM32_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHB2ENR_RNGEN; +#endif + +#ifdef CONFIG_STM32_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHB2ENR_OTGFSEN; +#endif + + putreg32(regval, STM32_RCC_AHB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ +#ifdef CONFIG_STM32_FSMC + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the + * selected AHB3 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB3ENR); + + /* Flexible static memory controller module clock enable */ + + regval |= RCC_AHB3ENR_FSMCEN; + + putreg32(regval, STM32_RCC_AHB3ENR); /* Enable peripherals */ +#endif +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32_TIM2 + /* TIM2 clock enable */ + + regval |= RCC_APB1ENR_TIM2EN; +#endif + +#ifdef CONFIG_STM32_TIM3 + /* TIM3 clock enable */ + + regval |= RCC_APB1ENR_TIM3EN; +#endif + +#ifdef CONFIG_STM32_TIM4 + /* TIM4 clock enable */ + + regval |= RCC_APB1ENR_TIM4EN; +#endif + +#ifdef CONFIG_STM32_TIM5 + /* TIM5 clock enable */ + + regval |= RCC_APB1ENR_TIM5EN; +#endif + +#ifdef CONFIG_STM32_TIM6 + /* TIM6 clock enable */ + + regval |= RCC_APB1ENR_TIM6EN; +#endif + +#ifdef CONFIG_STM32_TIM7 + /* TIM7 clock enable */ + + regval |= RCC_APB1ENR_TIM7EN; +#endif + +#ifdef CONFIG_STM32_TIM12 + /* TIM12 clock enable */ + + regval |= RCC_APB1ENR_TIM12EN; +#endif + +#ifdef CONFIG_STM32_TIM13 + /* TIM13 clock enable */ + + regval |= RCC_APB1ENR_TIM13EN; +#endif + +#ifdef CONFIG_STM32_TIM14 + /* TIM14 clock enable */ + + regval |= RCC_APB1ENR_TIM14EN; +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32_UART4 + /* UART4 clock enable */ + + regval |= RCC_APB1ENR_UART4EN; +#endif + +#ifdef CONFIG_STM32_UART5 + /* UART5 clock enable */ + + regval |= RCC_APB1ENR_UART5EN; +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1ENR_I2C1EN; +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1ENR_I2C2EN; +#endif + +#ifdef CONFIG_STM32_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1ENR_I2C3EN; +#endif + +#ifdef CONFIG_STM32_CAN1 + /* CAN 1 clock enable */ + + regval |= RCC_APB1ENR_CAN1EN; +#endif + +#ifdef CONFIG_STM32_CAN2 + /* CAN2 clock enable. NOTE: CAN2 needs CAN1 clock as well. */ + + regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN); +#endif + + /* Power interface clock enable. The PWR block is always enabled so that + * we can set the internal voltage regulator for maximum performance. + */ + + regval |= RCC_APB1ENR_PWREN; + +#if defined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32_TIM1 + /* TIM1 clock enable */ + + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32_TIM8 + /* TIM8 clock enable */ + + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32_USART6 + /* USART6 clock enable */ + + regval |= RCC_APB2ENR_USART6EN; +#endif + +#ifdef CONFIG_STM32_ADC1 + /* ADC1 clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + +#ifdef CONFIG_STM32_ADC2 + /* ADC2 clock enable */ + + regval |= RCC_APB2ENR_ADC2EN; +#endif + +#ifdef CONFIG_STM32_ADC3 + /* ADC3 clock enable */ + + regval |= RCC_APB2ENR_ADC3EN; +#endif + +#ifdef CONFIG_STM32_SDIO + /* SDIO clock enable */ + + regval |= RCC_APB2ENR_SDIOEN; +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_SYSCFG + /* System configuration controller clock enable */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32_TIM9 + /* TIM9 clock enable */ + + regval |= RCC_APB2ENR_TIM9EN; +#endif + +#ifdef CONFIG_STM32_TIM10 + /* TIM10 clock enable */ + + regval |= RCC_APB2ENR_TIM10EN; +#endif + +#ifdef CONFIG_STM32_TIM11 + /* TIM11 clock enable */ + + regval |= RCC_APB2ENR_TIM11EN; +#endif + + putreg32(regval, STM32_RCC_APB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + + /* Check for a timeout. If this timeout occurs, then we are hosed. We + * have no real back-up plan, although the following logic makes it look + * as though we do. + */ + + if (timeout > 0) + { + /* Select regulator voltage output Scale 1 mode to support system + * frequencies up to 168 MHz. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32_RCC_APB1ENR); + + regval = getreg32(STM32_PWR_CR); + regval |= PWR_CR_VOS; + putreg32(regval, STM32_PWR_CR); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#ifdef CONFIG_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the PLL dividers and multipliers to configure the main PLL */ + + regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN | STM32_PLLCFG_PLLP | + RCC_PLLCFG_PLLSRC_HSE | STM32_PLLCFG_PLLQ); + putreg32(regval, STM32_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + + /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */ + +#ifdef CONFIG_STM32_FLASH_PREFETCH + regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN); +#else + regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); +#endif + putreg32(regval, STM32_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL); + +#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + */ + + stm32_rcc_enablelse(); +#endif + } +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f30xxx_i2c.c b/arch/arm/src/stm32/stm32f30xxx_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..15b0cb63bb4f65700ac46def29585f5e6d011aaf --- /dev/null +++ b/arch/arm/src/stm32/stm32f30xxx_i2c.c @@ -0,0 +1,2054 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32f3xx_i2c.c + * STM32 F3 I2C Hardware Layer - Device Driver + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With extensions and modifications for the F1, F2, and F4 by: + * + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregroy Nutt + * + * And this version for the STM32 F3 by + * + * Author: John Wharington + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Supports: + * - Master operation, 100 kHz (standard) and 400 kHz (full speed) + * - Multiple instances (shared bus) + * - Interrupt based operation + * + * Structure naming: + * - Device: structure as defined by the nuttx/i2c/i2c.h + * - Instance: represents each individual access to the I2C driver, obtained by + * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; + * Instance points to OPS, to common I2C Hardware private data and contains + * its own private data, as frequency, address, mode of operation (in the future) + * - Private: Private data of an I2C Hardware + * + * TODO + * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST) + * - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin + * - Slave support with multiple addresses (on multiple instances): + * - 2 x 7-bit address or + * - 1 x 10 bit adresses + 1 x 7 bit address (?) + * - plus the broadcast address (general call) + * - Multi-master support + * - DMA (to get rid of too many CPU wake-ups and interventions) + * - Be ready for IPMI + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" +#include "stm32_i2c.h" +#include "stm32_waste.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) +/* This implementation is for the STM32 F1, F2, and F4 only */ + +#if defined(CONFIG_STM32_STM32F30XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_STM32_I2CTIMEOSEC) && !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOSEC 0 +# define CONFIG_STM32_I2CTIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOSEC) +# define CONFIG_STM32_I2CTIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_STM32_I2CTIMEOMS) +# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_STM32_I2CTIMEOTICKS +# define CONFIG_STM32_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_STM32_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32_I2CTIMEOMS)) +#endif + +#ifndef CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32_I2CTIMEOTICKS) +#endif + +#define I2C_OUTPUT \ + (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD | GPIO_MODE_50MHz) +#define MKI2C_OUTPUT(p) \ + (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Register setting unique to the STM32F30xx */ + +#define I2C_CR1_TXRX \ + (I2C_CR1_RXIE | I2C_CR1_TXIE) +#define I2C_CR1_ALLINTS \ + (I2C_CR1_TXRX | I2C_CR1_TCIE | I2C_CR1_ADDRIE | I2C_CR1_ERRIE) + +#define STATUS_NACK(status) (status & I2C_INT_NACK) +#define STATUS_ADDR(status) (status & I2C_INT_ADDR) +#define STATUS_ADDR_TX(status) (status & (I2C_INT_ADDR | I2C_ISR_TXIS)) +#define STATUS_ADD10(status) (0) +#define STATUS_RXNE(status) (status & I2C_ISR_RXNE) +#define STATUS_TC(status) (status & I2C_ISR_TC) +#define STATUS_BUSY(status) (status & I2C_ISR_BUSY) + +/* Debug ****************************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level + * debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define stm32_i2c_tracereset(p) +# define stm32_i2c_tracenew(p,s) +# define stm32_i2c_traceevent(p,e,a) +# define stm32_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Interrupt state */ + +enum stm32_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for completion of interrupt activity */ + INTSTATE_DONE, /* Interrupt activity complete */ +}; + +/* Trace events */ + +enum stm32_trace_e +{ + I2CEVENT_NONE = 0, /* No events have occurred with this status */ + I2CEVENT_SENDADDR, /* Start/Master bit set and address sent, param = msgc */ + I2CEVENT_SENDBYTE, /* Send byte, param = dcnt */ + I2CEVENT_ITBUFEN, /* Enable buffer interrupts, param = 0 */ + I2CEVENT_RCVBYTE, /* Read more dta, param = dcnt */ + I2CEVENT_REITBUFEN, /* Re-enable buffer interrupts, param = 0 */ + I2CEVENT_DISITBUFEN, /* Disable buffer interrupts, param = 0 */ + I2CEVENT_BTFNOSTART, /* BTF on last byte with no restart, param = msgc */ + I2CEVENT_BTFRESTART, /* Last byte sent, re-starting, param = msgc */ + I2CEVENT_BTFSTOP, /* Last byte sten, send stop, param = 0 */ + I2CEVENT_ERROR /* Error occurred, param = 0 */ +}; + +/* Trace data */ + +struct stm32_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + enum stm32_intstate_e event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + systime_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct stm32_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t reset_bit; /* Reset bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr)(int, void *); /* Interrupt handler */ + uint32_t ev_irq; /* Event IRQ */ + uint32_t er_irq; /* Error IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct stm32_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct stm32_i2c_config_s *config; /* Port configuration */ + int refs; /* Referernce count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + bool astart; /* START sent */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + systime_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct stm32_trace_s trace[CONFIG_I2C_NTRACE]; +#endif + + uint32_t status; /* End of transfer SR2|SR1 status */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset); +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value); +static inline void stm32_i2c_putreg32(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint32_t value); +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline void stm32_i2c_modifyreg32(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits); +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv); +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_STM32_I2C_DYNTIMEO */ +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv); +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv); +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status); +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + enum stm32_trace_e event, uint32_t parm); +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, + uint32_t frequency); +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv); +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv); +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv); +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context); +#endif +#endif +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv); +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Device Structures, Instantiation */ + +const struct i2c_ops_s stm32_i2c_ops = +{ + .transfer = stm32_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = stm32_i2c_reset +#endif +}; + +#ifdef CONFIG_STM32_I2C1 +static const struct stm32_i2c_config_s stm32_i2c1_config = +{ + .base = STM32_I2C1_BASE, + .clk_bit = RCC_APB1ENR_I2C1EN, + .reset_bit = RCC_APB1RSTR_I2C1RST, + .scl_pin = GPIO_I2C1_SCL, + .sda_pin = GPIO_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c1_isr, + .ev_irq = STM32_IRQ_I2C1EV, + .er_irq = STM32_IRQ_I2C1ER +#endif +}; + +struct stm32_i2c_priv_s stm32_i2c1_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c1_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C2 +static const struct stm32_i2c_config_s stm32_i2c2_config = +{ + .base = STM32_I2C2_BASE, + .clk_bit = RCC_APB1ENR_I2C2EN, + .reset_bit = RCC_APB1RSTR_I2C2RST, + .scl_pin = GPIO_I2C2_SCL, + .sda_pin = GPIO_I2C2_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c2_isr, + .ev_irq = STM32_IRQ_I2C2EV, + .er_irq = STM32_IRQ_I2C2ER +#endif +}; + +struct stm32_i2c_priv_s stm32_i2c2_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c2_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32_I2C3 +static const struct stm32_i2c_config_s stm32_i2c3_config = +{ + .base = STM32_I2C3_BASE, + .clk_bit = RCC_APB1ENR_I2C3EN, + .reset_bit = RCC_APB1RSTR_I2C3RST, + .scl_pin = GPIO_I2C3_SCL, + .sda_pin = GPIO_I2C3_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32_i2c3_isr, + .ev_irq = STM32_IRQ_I2C3EV, + .er_irq = STM32_IRQ_I2C3ER +#endif +}; + +struct stm32_i2c_priv_s stm32_i2c3_priv = +{ + .ops = &stm32_i2c_ops, + .config = &stm32_i2c3_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ************************************************************************************/ + +static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_getreg32 + * + * Description: + * Get a 32-bit register value by offset + * + ************************************************************************************/ + +static inline uint32_t stm32_i2c_getreg32(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg32(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t offset, + uint16_t value) +{ + putreg16(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_putreg32 + * + * Description: + * Put a 32-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_putreg32(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32_i2c_modifyreg + * + * Description: + * Modify a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32_i2c_modifyreg32 + * + * Description: + * Modify a 32-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32_i2c_modifyreg32(FAR struct stm32_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv) +{ + while (sem_wait(&priv->sem_excl) != 0) + { + ASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: stm32_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be processed. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO +static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_enableinterrupts + * + * Description: + * Enable I2C interrupts + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline void stm32_i2c_enableinterrupts(struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_TXRX); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_disableinterrupts + * + * Description: + * Enable I2C interrupts + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline void stm32_i2c_disableinterrupts(struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_TXRX, 0); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + uint32_t regval; + int ret; + + flags = enter_critical_section(); + + /* Enable I2C interrupts */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, 0, + (I2C_CR1_ALLINTS & ~I2C_CR1_TXRX)); + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_STM32_I2CTIMEOSEC > 0 + abstime.tv_sec += CONFIG_STM32_I2CTIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * stm32_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_STM32_I2CTIMEOMS > 0 + abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->sem_isr, &abstime); + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by sem_timedwait. + * NOTE that we try again if we are awakened by a signal (EINTR). + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ALLINTS, 0); + + leave_critical_section(flags); + return ret; +} +#else +static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(stm32_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + start = clock_systimer(); + + do + { + /* Poll by simply calling the timer interrupt handler until it + * reports that it is done. + */ + + stm32_i2c_isr(priv); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cvdbg("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, priv->status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32_i2c_set_7bit_address + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_set_7bit_address(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_SADD7_MASK, + ((priv->msgv->addr & 0x7F) << I2C_CR2_SADD7_SHIFT)); +} + +/************************************************************************************ + * Name: stm32_i2c_set_bytes_to_transfer + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_set_bytes_to_transfer(FAR struct stm32_i2c_priv_s *priv, + uint8_t n_bytes) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_NBYTES_MASK, + (n_bytes << I2C_CR2_NBYTES_SHIFT)); +} + +/************************************************************************************ + * Name: stm32_i2c_set_write_transfer_dir + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_set_write_transfer_dir(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_RD_WRN, 0); +} + +/************************************************************************************ + * Name: stm32_i2c_set_read_transfer_dir + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_set_read_transfer_dir(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_RD_WRN); +} + +/************************************************************************************ + * Name: stm32_i2c_enable_autoend + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_enable_autoend(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_AUTOEND); +} + +/************************************************************************************ + * Name: stm32_i2c_disable_autoend + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32_i2c_disable_autoend(FAR struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_AUTOEND, 0); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_waitstop + * + * Description: + * Wait for a STOP to complete + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv) +{ + systime_t start; + systime_t elapsed; + systime_t timeout; + uint32_t cr; + uint32_t sr; + + /* Select a timeout */ + +#ifdef CONFIG_STM32_I2C_DYNTIMEO + timeout = USEC2TICK(CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP); +#else + timeout = CONFIG_STM32_I2CTIMEOTICKS; +#endif + + /* Wait as stop might still be in progress; but stop might also + * be set because of a timeout error: "The [STOP] bit is set and + * cleared by software, cleared by hardware when a Stop condition is + * detected, set by hardware when a timeout error is detected." + */ + + start = clock_systimer(); + do + { + /* Check for STOP condition */ + + cr = stm32_i2c_getreg32(priv, STM32_I2C_CR2_OFFSET); + if ((cr & I2C_CR2_STOP) == 0) + { + return; + } + + /* Check for timeout error */ + + sr = stm32_i2c_getreg(priv, STM32_I2C_ISR_OFFSET); + if ((sr & I2C_INT_TIMEOUT) != 0) + { + return; + } + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the stop is complete or a timeout occurs. */ + + while (elapsed < timeout); + + /* If we get here then a timeout occurred with the STOP condition + * still pending. + */ + + i2cvdbg("Timeout with CR: %04x SR: %04x\n", cr, sr); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv) +{ + sem_post(&priv->sem_excl); +} + +/************************************************************************************ + * Name: stm32_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) +{ + sem_init(&priv->sem_excl, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->sem_isr, 0, 0); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv) +{ + sem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->sem_isr); +#endif +} + +/************************************************************************************ + * Name: stm32_i2c_trace* + * + * Description: + * I2C trace instrumentation + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void stm32_i2c_traceclear(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systimer(); + stm32_i2c_traceclear(priv); +} + +static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, + uint32_t status) +{ + struct stm32_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + stm32_i2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systimer(); + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv, + enum stm32_trace_e event, uint32_t parm) +{ + struct stm32_trace_s *trace; + + if (event != I2CEVENT_NONE) + { + trace = &priv->trace[priv->tndx]; + + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + stm32_i2c_traceclear(priv); + } +} + +static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv) +{ + struct stm32_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->start_time)); + + for (i = 0; i <= priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %3d EVENT: %2d PARM: %08x TIME: %d\n", + i+1, trace->status, trace->count, trace->event, trace->parm, + trace->time - priv->start_time); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/************************************************************************************ + * Name: stm32_i2c_setclock + * + * Description: + * Set the I2C clock + * + ************************************************************************************/ + +static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequency) +{ + uint32_t pe; + uint8_t presc; + uint8_t s_time; + uint8_t h_time; + uint8_t scl_h_period; + uint8_t scl_l_period; + + /* Has the I2C bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Disable the selected I2C peripheral to configure TRISE */ + + pe = (stm32_i2c_getreg32(priv, STM32_I2C_CR1_OFFSET) & I2C_CR1_PE); + if (pe) + { + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE, 0); + } + + /* Update timing and control registers */ + + /* TODO: speed/timing calcs */ +#warning "check set filters before timing, see RM0316" + + /* values from 100khz at 8mhz i2c clock */ + + /* prescaler */ + /* t_presc= (presc+1)*t_i2cclk */ + /* RM0316 */ + + if (frequency == 10000) + { + presc = 0x01; + scl_l_period = 0xc7; + scl_h_period = 0xc3; + h_time = 0x02; + s_time = 0x04; + } + else if (frequency == 100000) + { + /* values from datasheet with clock 8mhz */ + + presc = 0x01; + scl_l_period = 0x13; + scl_h_period = 0x0f; + h_time = 0x02; + s_time = 0x04; + } + else + { + presc = 0x00; + scl_l_period = 0x09; + scl_h_period = 0x03; + h_time = 0x01; + s_time = 0x03; + } + + uint32_t timingr = + (presc << I2C_TIMINGR_PRESC_SHIFT) | + (s_time << I2C_TIMINGR_SCLDEL_SHIFT) | + (h_time << I2C_TIMINGR_SDADEL_SHIFT) | + (scl_h_period << I2C_TIMINGR_SCLH_SHIFT) | + (scl_l_period << I2C_TIMINGR_SCLL_SHIFT); + + stm32_i2c_putreg32(priv, STM32_I2C_TIMINGR_OFFSET, timingr); + + /* Bit 14 of OAR1 must be configured and kept at 1 */ + + stm32_i2c_putreg(priv, STM32_I2C_OAR1_OFFSET, I2C_OAR1_ONE); + + /* Re-enable the peripheral (or not) */ + + if (pe) + { + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_PE); + } + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/************************************************************************************ + * Name: stm32_i2c_sendstart + * + * Description: + * Send the START conditions/force Master mode + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* Get run-time data */ + + priv->astart = true; + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + + /* Disable ACK on receive by default and generate START */ + + stm32_i2c_set_bytes_to_transfer(priv, priv->dcnt); + stm32_i2c_set_7bit_address(priv); + if (priv->flags & I2C_M_READ) + { + stm32_i2c_set_read_transfer_dir(priv); + } + else + { + stm32_i2c_set_write_transfer_dir(priv); + } + + if (priv->msgc == 1) + { + /* stm32_i2c_enable_autoend(priv); */ + } + else + { + /* stm32_i2c_disable_autoend(priv); */ + } + + /* TODO check NACK */ + /* TODO handle NACKR? */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_START); +} + +/************************************************************************************ + * Name: stm32_i2c_clrstart + * + * Description: + * Clear the STOP, START or PEC condition on certain error recovery steps. + * + ************************************************************************************/ + +static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv) +{ + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + * + * "The [STOP] bit is set and cleared by software, cleared by hardware + * when a Stop condition is detected, set by hardware when a timeout + * error is detected. + * + * "This [START] bit is set and cleared by software and cleared by hardware + * when start is sent or PE=0." The bit must be cleared by software if the + * START is never sent. + * + * "This [PEC] bit is set and cleared by software, and cleared by hardware + * when PEC is transferred or by a START or Stop condition or when PE=0." + */ + + /* TODO check PEC (32 bit separate reg) */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, + I2C_CR2_START | I2C_CR2_STOP, 0); +} + +/************************************************************************************ + * Name: stm32_i2c_sendstop + * + * Description: + * Send the STOP conditions + * + ************************************************************************************/ + +static inline void stm32_i2c_sendstop(FAR struct stm32_i2c_priv_s *priv) +{ + /* TODO check NACK */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_STOP); +} + +/************************************************************************************ + * Name: stm32_i2c_getstatus + * + * Description: + * Get 32-bit status (SR1 and SR2 combined) + * + ************************************************************************************/ + +static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv) +{ + return getreg32(priv->config->base + STM32_I2C_ISR_OFFSET); +} + +/************************************************************************************ + * Name: stm32_i2c_isr + * + * Description: + * Common logic when a message is started. Just adds the even to the trace buffer + * if enabled and adjusts the message pointer and count. + * + ************************************************************************************/ + +static inline void stm32_i2c_isr_startmessage(struct stm32_i2c_priv_s *priv) +{ + stm32_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc); + + /* Increment to next pointer and decrement message count */ + + priv->msgv++; + priv->msgc--; +} + +/************************************************************************************ + * Name: stm32_i2c_clearinterrupts + * + * Description: + * Clear all interrupts + * + ************************************************************************************/ + +static inline void stm32_i2c_clearinterrupts(struct stm32_i2c_priv_s *priv) +{ +#warning "check this clears interrupts?" + stm32_i2c_modifyreg32(priv, STM32_I2C_ICR_OFFSET, 0, I2C_ICR_CLEARMASK); +} + +/************************************************************************************ + * Name: stm32_i2c_isr + * + * Description: + * Common Interrupt Service Routine + * + ************************************************************************************/ + +static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) +{ + uint32_t status = stm32_i2c_getstatus(priv); + + /* Check for new trace setup */ + + stm32_i2c_tracenew(priv, status); + +#warning "TODO: check clear interrupts after all actions" + + if (STATUS_NACK(status)) + { + /* wait, reset this? */ + } + else if (priv->astart) + { + stm32_i2c_isr_startmessage(priv); + priv->astart = false; + } + + /* Was address sent, continue with either sending or reading data */ + + if ((priv->flags & I2C_M_READ) == 0 && STATUS_ADDR_TX(status)) + { +#warning "TODO: ADDRCF clear address interrupt flag" + if (priv->dcnt > 0) + { + /* Send a byte */ + + stm32_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt); + stm32_i2c_putreg(priv, STM32_I2C_TXDR_OFFSET, *priv->ptr++); + priv->dcnt--; + } + } + + else if ((priv->flags & I2C_M_READ) != 0 && STATUS_ADDR(status)) + { + /* Enable RxNE and TxE buffers in order to receive one or multiple bytes */ + +#warning "TODO: ADDRCF clear address interrupt flag" + +#ifndef CONFIG_I2C_POLLED + stm32_i2c_traceevent(priv, I2CEVENT_ITBUFEN, 0); + stm32_i2c_enableinterrupts(priv); +#endif + } + + /* More bytes to read */ + else if (STATUS_RXNE(status)) + { + /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */ + + if (priv->dcnt > 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); + + /* No interrupts or context switches may occur in the following + * sequence. Otherwise, additional bytes may be sent by the + * device. + */ + +#ifdef CONFIG_I2C_POLLED + irqstate_t flags = enter_critical_section(); +#endif + /* Receive a byte */ + + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_RXDR_OFFSET); + + /* Disable acknowledge when last byte is to be received */ + + priv->dcnt--; + if (priv->dcnt == 1) + { + /* autoend? */ + } + +#ifdef CONFIG_I2C_POLLED + leave_critical_section(flags); +#endif + } + } + + /* Do we have more bytes to send, enable/disable buffer interrupts + * (these ISRs could be replaced by DMAs) + */ + +#ifndef CONFIG_I2C_POLLED + if (priv->dcnt > 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_REITBUFEN, 0); + stm32_i2c_enableinterrupts(priv); + } + else if ((priv->dcnt == 0) && (priv->msgc == 0)) + { + stm32_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0); + stm32_i2c_disableinterrupts(priv); + } +#endif + + /* Was last byte received or sent? Hmmm... the F2 and F4 seems to differ from + * the F1 in that BTF is not set after data is received (only RXNE). + */ + + if (priv->dcnt <= 0 && STATUS_TC(status)) + { + /* ??? */ + + /* Do we need to terminate or restart after this byte? + * If there are more messages to send, then we may: + * + * - continue with repeated start + * - or just continue sending writeable part + * - or we close down by sending the stop bit + */ + + if (priv->msgc > 0) + { + if (priv->msgv->flags & I2C_M_NORESTART) + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFNOSTART, priv->msgc); + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->msgv++; + priv->msgc--; + + /* Restart this ISR! */ + +#ifndef CONFIG_I2C_POLLED + stm32_i2c_enableinterrupts(priv); +#endif + } + else + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFRESTART, priv->msgc); + /* ??? */ + stm32_i2c_sendstart(priv); + } + } + else if (priv->msgv) + { + stm32_i2c_traceevent(priv, I2CEVENT_BTFSTOP, 0); + + stm32_i2c_sendstop(priv); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + + /* Mark that we have stopped with this transaction */ + + priv->msgv = NULL; + } + } + + /* Check for errors, in which case, stop the transfer and return + * Note that in master reception mode AF becomes set on last byte + * since ACK is not returned. We should ignore this error. + */ + + if ((status & I2C_ISR_ERRORMASK) != 0) + { + stm32_i2c_traceevent(priv, I2CEVENT_ERROR, 0); + + /* Clear interrupt flags */ + + stm32_i2c_clearinterrupts(priv); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + } + + priv->status = status; + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c1_isr + * + * Description: + * I2C1 interrupt service routine + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32_I2C1 +static int stm32_i2c1_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c1_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c2_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C2 +static int stm32_i2c2_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c2_priv); +} +#endif + +/************************************************************************************ + * Name: stm32_i2c3_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_I2C3 +static int stm32_i2c3_isr(int irq, void *context) +{ + return stm32_i2c_isr(&stm32_i2c3_priv); +} +#endif +#endif + +/************************************************************************************ + * Private Initialization and Deinitialization + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv) +{ + /* Power-up and configure GPIOs */ + + /* Enable power and reset the peripheral */ + + modifyreg32(STM32_RCC_APB1ENR, 0, priv->config->clk_bit); + modifyreg32(STM32_RCC_APB1RSTR, 0, priv->config->reset_bit); + modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0); + + /* Configure pins */ + + if (stm32_configgpio(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (stm32_configgpio(priv->config->sda_pin) < 0) + { + stm32_unconfiggpio(priv->config->scl_pin); + return ERROR; + } + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->ev_irq, priv->config->isr); + irq_attach(priv->config->er_irq, priv->config->isr); + up_enable_irq(priv->config->ev_irq); + up_enable_irq(priv->config->er_irq); +#endif + + /* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz + * or 4 MHz for 400 kHz. This also disables all I2C interrupts. + */ + + /* Force a frequency update */ + + priv->frequency = 0; + + /* TODO: f303 i2c clock source RCC_CFGR3 */ + /* RCC_CFGR3_I2C1SW (default is HSI clock) */ + + stm32_i2c_setclock(priv, 100000); + + /* Enable I2C */ + + stm32_i2c_modifyreg32(priv, STM32_I2C_CR1_OFFSET, 0, I2C_CR1_PE); + return OK; +} + +/************************************************************************************ + * Name: stm32_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv) +{ + /* Disable I2C */ + + stm32_i2c_putreg32(priv, STM32_I2C_CR1_OFFSET, 0); + + /* Unconfigure GPIO pins */ + + stm32_unconfiggpio(priv->config->scl_pin); + stm32_unconfiggpio(priv->config->sda_pin); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->ev_irq); + up_disable_irq(priv->config->er_irq); + irq_detach(priv->config->ev_irq); + irq_detach(priv->config->er_irq); +#endif + + /* Disable clocking */ + + modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0); + return OK; +} + +/************************************************************************************ + * Device Driver Operations + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ************************************************************************************/ + +static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count) +{ + FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; + uint32_t status = 0; + int ret = OK; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Ensure that address or flags don't change meanwhile */ + + stm32_i2c_sem_wait(priv); + + /* Wait for any STOP in progress. */ + + stm32_i2c_sem_waitstop(priv); + + /* Clear any pending error interrupts */ + + stm32_i2c_clearinterrupts(priv); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." However, if the bits are + * not cleared by hardware, then we will have to do that from hardware. + */ + + stm32_i2c_clrstart(priv); + + /* Old transfers are done */ + + priv->msgv = msgs; + priv->msgc = count; + + /* Reset I2C trace logic */ + + stm32_i2c_tracereset(priv); + + /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + stm32_i2c_setclock(priv, msgs->frequency); + + /* Trigger start condition, then the process moves into the ISR. I2C + * interrupts will be enabled within stm32_i2c_waitdone(). + */ + + priv->status = 0; + +#ifndef CONFIG_I2C_POLLED + stm32_i2c_enableinterrupts(priv); +#endif + + stm32_i2c_sendstart(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (stm32_i2c_sem_waitdone(priv) < 0) + { + status = stm32_i2c_getstatus(priv); + ret = -ETIMEDOUT; + + i2cdbg("Timed out: CR1: %04x status: %08x\n", + stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + */ + + stm32_i2c_clrstart(priv); + + /* Clear busy flag in case of timeout */ + + status = priv->status & 0xffff; + } + else + { + /* clear SR2 (BUSY flag) as we've done successfully */ + + status = priv->status & 0xffff; + } + + status &= ~I2C_ISR_BUSY; +#if 0 + /* Refresh status */ + do + { + status = stm32_i2c_getstatus(priv); + } + while (STATUS_BUSY(status)); +#endif + + /* Check for error status conditions */ + + if ((status & I2C_ISR_ERRORMASK) != 0) + { + /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */ + + if (status & I2C_INT_BERR) + { + /* Bus Error */ + + ret = -EIO; + } + else if (status & I2C_INT_ARLO) + { + /* Arbitration Lost (master mode) */ + + ret = -EAGAIN; + } + + /* TODO Acknowledge failure */ + + else if (status & I2C_INT_OVR) + { + /* Overrun/Underrun */ + + ret = -EIO; + } + else if (status & I2C_INT_PECERR) + { + /* PEC Error in reception */ + + ret = -EPROTO; + } + else if (status & I2C_INT_TIMEOUT) + { + /* Timeout or Tlow Error */ + + ret = -ETIME; + } + + /* This is not an error and should never happen since SMBus is not + * enabled + */ + + else /* if (status & I2C_INT_ALERT) */ + { + /* SMBus alert is an optional signal with an interrupt line for devices + * that want to trade their ability to master for a pin. + */ + + ret = -EINTR; + } + } + + /* This is not an error, but should not happen. The BUSY signal can hang, + * however, if there are unhealthy devices on the bus that need to be reset. + * NOTE: We will only see this buy indication if stm32_i2c_sem_waitdone() + * fails above; Otherwise it is cleared. + */ + + else if ((status & I2C_ISR_BUSY) != 0) + { + /* I2C Bus is for some reason busy */ + + ret = -EBUSY; + } + + /* Dump the trace result */ + + stm32_i2c_tracedump(priv); + stm32_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: stm32_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int stm32_i2c_reset(FAR struct i2c_master_s * dev) +{ + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret = ERROR; + + ASSERT(dev); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + stm32_i2c_sem_wait(priv); + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + stm32_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + /* Let SDA go high */ + + stm32_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!stm32_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!stm32_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + stm32_gpiowrite(sda_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 0); + up_udelay(10); + stm32_gpiowrite(scl_gpio, 1); + up_udelay(10); + stm32_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + stm32_unconfiggpio(sda_gpio); + stm32_unconfiggpio(scl_gpio); + + /* Re-init the port */ + + stm32_i2c_init(priv); + + /* Restore the frequency */ + + stm32_i2c_setclock(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + stm32_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ************************************************************************************/ + +FAR struct i2c_master_s *stm32_i2cbus_initialize(int port) +{ + struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */ + irqtate_t flags; + +#if STM32_PCLK1_FREQUENCY < 4000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation. +#endif + +#if STM32_PCLK1_FREQUENCY < 2000000 +# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation. + return NULL; +#endif + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_STM32_I2C1 + case 1: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C2 + case 2: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv; + break; +#endif +#ifdef CONFIG_STM32_I2C3 + case 3: + priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv; + break; +#endif + default: + return NULL; + } + + /* Init private data for the first time, increment refs count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + stm32_i2c_sem_init(priv); + stm32_i2c_init(priv); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/************************************************************************************ + * Name: stm32_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ************************************************************************************/ + +int stm32_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; + irqstate_t flags; + + ASSERT(dev); + + /* Decrement refs and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + stm32_i2c_deinit(priv); + + /* Release unused resources */ + + stm32_i2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_STM32_STM32F30XX */ +#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */ diff --git a/arch/arm/src/stm32/stm32f30xxx_rcc.c b/arch/arm/src/stm32/stm32f30xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..6da5b9c03b0c254460c3fb3764d4df7b3a3b770b --- /dev/null +++ b/arch/arm/src/stm32/stm32f30xxx_rcc.c @@ -0,0 +1,690 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f30xxx_rcc.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Put all RCC registers in reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ + putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ + putreg32(RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN, STM32_RCC_AHBENR); /* FLITF and SRAM Clock ON */ + putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ + putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ + + regval = getreg32(STM32_RCC_CR); /* Set the HSION bit */ + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, USBPRE, I2SSRC, and MCO bits */ + regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | + RCC_CFGR_PPRE2_MASK | RCC_CFGR_USBPRE | RCC_CFGR_I2SSRC | + RCC_CFGR_MCO_MASK); + putreg32(regval, STM32_RCC_CFGR); + + regval = getreg32(STM32_RCC_CFGR2); /* Reset PREDIV, ADC12PRE, and ADC23PRE bits */ + regval &= ~(RCC_CFGR2_PREDIV_MASK | RCC_CFGR2_ADC12PRES_MASK | + RCC_CFGR2_ADC34PRES_MASK); + putreg32(regval, STM32_RCC_CFGR2); + + putreg32(0, STM32_RCC_CFGR2); /* Reset fCK source for all U[S]ARTs to PCLK */ + + regval = getreg32(STM32_RCC_CR); /* Reset HSEON, CSSON and PLLON bits */ + regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */ + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK | + RCC_CFGR_USBPRE); + putreg32(regval, STM32_RCC_CFGR); + + putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ +} + +/**************************************************************************** + * Name: rcc_enableahb + * + * Description: + * Enable selected AHB peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb(void) +{ + uint32_t regval; + + /* Always enable FLITF clock and SRAM clock */ + + regval = RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN; + + /* Enable GPIO PORTA, PORTB, ... PORTF */ + + regval |= (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPBEN | RCC_AHBENR_IOPCEN | + RCC_AHBENR_IOPDEN | RCC_AHBENR_IOPEEN | RCC_AHBENR_IOPFEN); + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHBENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHBENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHBENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_TSC + /* CRC clock enable */ + + regval |= RCC_AHBENR_TSCEN; +#endif + +#if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) + /* ADC1/ADC2 interface clock enable */ + + regval |= RCC_AHBENR_ADC12EN; +#endif + +#if defined(CONFIG_STM32_ADC3) || defined(CONFIG_STM32_ADC4) + /* ADC3/ADC4 interface clock enable */ + + regval |= RCC_AHBENR_ADC34EN; +#endif + + putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + +#ifdef CONFIG_STM32_USB + /* USB clock divider. This bit must be valid before enabling the USB + * clock in the RCC_APB1ENR register. This bit can’t be reset if the USB + * clock is enabled. + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_USBPRE; + regval |= STM32_CFGR_USBPRE; + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32_TIM2 + /* Timer 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM2EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM3 + /* Timer 3 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM3EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM4 + /* Timer 4 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM4EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM6 + /* Timer 6 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM6EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM7 + /* Timer 7 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM7EN; +#endif +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window Watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI 2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI 3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART 3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32_UART4 + /* UART 4 clock enable */ + + regval |= RCC_APB1ENR_UART4EN; +#endif + +#ifdef CONFIG_STM32_UART5 + /* UART 5 clock enable */ + + regval |= RCC_APB1ENR_UART5EN; +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C 1 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C1EN; +#endif +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C2EN; +#endif +#endif + +#ifdef CONFIG_STM32_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + +#ifdef CONFIG_STM32_CAN1 + /* CAN1 clock enable */ + + regval |= RCC_APB1ENR_CAN1EN; +#endif + +#ifdef CONFIG_STM32_PWR + /* Power interface clock enable */ + + regval |= RCC_APB1ENR_PWREN; +#endif + +#ifdef CONFIG_STM32_DAC + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32_SYSCFG + /* SYSCFG clock */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32_TIM1 + /* TIM1 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM1EN; +#endif +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI 1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_TIM8 + /* TIM8 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM8EN; +#endif +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32_TIM15 + /* TIM15 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM15EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM16 + /* TIM16 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM16EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM17 + /* TIM17 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM17EN; +#endif +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. This + * version is for the Connectivity Line parts. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && defined(CONFIG_STM32_CONNECTIVITYLINE) +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + + /* Enable HSE */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Set flash wait states + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); + putreg32(regval, STM32_FLASH_ACR); + + /* Set up PLL input scaling (with source = PLL2) */ + + regval = getreg32(STM32_RCC_CFGR2); + regval &= ~(RCC_CFGR2_PREDIV2_MASK | RCC_CFGR2_PLL2MUL_MASK | + RCC_CFGR2_PREDIV1SRC_MASK | RCC_CFGR2_PREDIV1_MASK); + regval |= (STM32_PLL_PREDIV2 | STM32_PLL_PLL2MUL | + RCC_CFGR2_PREDIV1SRC_PLL2 | STM32_PLL_PREDIV1); + putreg32(regval, STM32_RCC_CFGR2); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PPRE2_MASK | RCC_CFGR_HPRE_MASK); + regval |= STM32_RCC_CFGR_PPRE2; + regval |= RCC_CFGR_HPRE_SYSCLK; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + + /* Enable PLL2 */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLL2ON; + putreg32(regval, STM32_RCC_CR); + + /* Wait for PLL2 ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL2RDY) == 0); + + /* Setup PLL3 for MII/RMII clock on MCO */ + +#if defined(CONFIG_STM32_MII_MCO) || defined(CONFIG_STM32_RMII_MCO) + regval = getreg32(STM32_RCC_CFGR2); + regval &= ~(RCC_CFGR2_PLL3MUL_MASK); + regval |= STM32_PLL_PLL3MUL; + putreg32(regval, STM32_RCC_CFGR2); + + /* Switch PLL3 on */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLL3ON; + putreg32(regval, STM32_RCC_CR); + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL3RDY) == 0); +#endif + + /* Set main PLL source and multiplier */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK); + regval |= (RCC_CFGR_PLLSRC | STM32_PLL_PLLMUL); + putreg32(regval, STM32_RCC_CFGR); + + /* Switch main PLL on */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + + /* Select PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until PLL is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_PLL) == 0); +} +#endif + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. This + * version is for the non-Connectivity Line parts. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && \ + !defined(CONFIG_STM32_CONNECTIVITYLINE) +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + + /* If the PLL is using the HSE, or the HSE is the system clock */ + +#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) + { + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + + if (timeout == 0) + { + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or + * misconfiguration. + */ + + return; + } + } + +# if defined(CONFIG_STM32_VALUELINE) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) + /* If this is a value-line part and we are using the HSE as the PLL */ + +# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) +# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 +# endif + + /* Set the HSE prescaler */ + + regval = STM32_CFGR2_PREDIV1; + putreg32(regval, STM32_RCC_CFGR2); + +# endif +#endif + +#ifndef CONFIG_STM32_VALUELINE + /* Value-line devices don't implement flash prefetch/waitstates */ + /* Enable FLASH prefetch buffer and 2 wait states */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); + putreg32(regval, STM32_FLASH_ACR); +#endif + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL + /* If we are using the PLL, configure and start it */ + /* Set the PLL divider and multiplier */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK); + regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLXTPRE | STM32_CFGR_PLLMUL); + putreg32(regval, STM32_RCC_CFGR); + + /* Enable the PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + +#endif + + /* Select the system clock source (probably the PLL) */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= STM32_SYSCLK_SW; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the selected source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); + +#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI + * + * TODO: There is another case where the LSI needs to + * be enabled: if the MCO pin selects LSI as source. + */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO pin selects LSE as source. + * + * TODO: There is another case where the LSE needs to + * be enabled: if USARTx selects LSE as source. + */ + + stm32_rcc_enablelse(); +#endif +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb(); + rcc_enableapb2(); + rcc_enableapb1(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f37xxx_rcc.c b/arch/arm/src/stm32/stm32f37xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..02fa9fd930d3c5fe799f9c73347a44ed2b79e4ba --- /dev/null +++ b/arch/arm/src/stm32/stm32f37xxx_rcc.c @@ -0,0 +1,584 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f37xxx_rcc.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified for STM32F373 by Marten Svanfeldt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Put all RCC registers in reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ + putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ + putreg32(RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN, STM32_RCC_AHBENR); /* FLITF and SRAM Clock ON */ + putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ + putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ + + regval = getreg32(STM32_RCC_CR); /* Set the HSION bit */ + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, USBPRE, and MCO bits */ + regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | + RCC_CFGR_PPRE2_MASK | RCC_CFGR_USBPRE | RCC_CFGR_MCO_MASK); + putreg32(regval, STM32_RCC_CFGR); + + regval = getreg32(STM32_RCC_CFGR2); /* Reset PREDIV bits */ + regval &= ~(RCC_CFGR2_PREDIV_MASK); + putreg32(regval, STM32_RCC_CFGR2); + + putreg32(0, STM32_RCC_CFGR2); /* Reset fCK source for all U[S]ARTs to PCLK */ + + regval = getreg32(STM32_RCC_CR); /* Reset HSEON, CSSON and PLLON bits */ + regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */ + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK | + RCC_CFGR_USBPRE); + putreg32(regval, STM32_RCC_CFGR); + + putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ +} + +/**************************************************************************** + * Name: rcc_enableahb + * + * Description: + * Enable selected AHB peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb(void) +{ + uint32_t regval; + + /* Always enable FLITF clock and SRAM clock */ + + regval = RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN; + + /* Enable GPIO PORTA, PORTB, ... PORTF */ + + regval |= (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPBEN | RCC_AHBENR_IOPCEN | + RCC_AHBENR_IOPDEN | RCC_AHBENR_IOPEEN | RCC_AHBENR_IOPFEN); + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHBENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHBENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHBENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_TSC + /* TSC clock enable */ + + regval |= RCC_AHBENR_TSCEN; +#endif + + putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + +#ifdef CONFIG_STM32_USB + /* USB clock divider. This bit must be valid before enabling the USB + * clock in the RCC_APB1ENR register. This bit can’t be reset if the USB + * clock is enabled. + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_USBPRE; + regval |= STM32_CFGR_USBPRE; + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32_TIM2 + /* Timer 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM2EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM3 + /* Timer 3 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM3EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM4 + /* Timer 4 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM4EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM5 + /* Timer 5 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM4EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM6 + /* Timer 6 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM6EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM7 + /* Timer 7 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM7EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM12 + /* Timer 12 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM12EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM13 + /* Timer 13 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM13EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM14 + /* Timer 14 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM14EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM18 + /* Timer 7 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM18EN; +#endif +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window Watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI 2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI 3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART 3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C 1 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C1EN; +#endif +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C2EN; +#endif +#endif + +#ifdef CONFIG_STM32_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + +#ifdef CONFIG_STM32_CAN1 + /* CAN1 clock enable */ + + regval |= RCC_APB1ENR_CANEN; +#endif + +#ifdef CONFIG_STM32_DAC2 + /* DAC 2 interface clock enable */ + + regval |= RCC_APB1ENR_DAC2EN; +#endif + +#ifdef CONFIG_STM32_PWR + /* Power interface clock enable */ + + regval |= RCC_APB1ENR_PWREN; +#endif + +#ifdef CONFIG_STM32_DAC1 + /* DAC 1 interface clock enable */ + + regval |= RCC_APB1ENR_DAC1EN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32_SYSCFG + /* SYSCFG clock */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI 1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32_TIM15 + /* TIM15 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM15EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM16 + /* TIM16 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM16EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM17 + /* TIM17 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM17EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM19 + /* TIM17 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM17EN; +#endif +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + + /* If the PLL is using the HSE, or the HSE is the system clock */ + +#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) + { + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + + if (timeout == 0) + { + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or misconfiguration. + */ + + return; + } + } + + /* If this is a value-line part and we are using the HSE as the PLL */ + +# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) +# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 +# endif + + /* Set the HSE prescaler */ + + regval = STM32_CFGR2_PREDIV1; + putreg32(regval, STM32_RCC_CFGR2); + +# endif + + /* Enable FLASH prefetch buffer and 2 wait states */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); + putreg32(regval, STM32_FLASH_ACR); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL + /* If we are using the PLL, configure and start it */ + /* Set the PLL divider and multiplier */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK); + regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLXTPRE | STM32_CFGR_PLLMUL); + putreg32(regval, STM32_RCC_CFGR); + + /* Enable the PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + +#endif + + /* Select the system clock source (probably the PLL) */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= STM32_SYSCLK_SW; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the selected source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); + +#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI + * + * TODO: There is another case where the LSI needs to + * be enabled: if the MCO pin selects LSI as source. + */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO pin selects LSE as source. + * + * TODO: There is another case where the LSE needs to + * be enabled: if USART1-2-3 selects LSE as source. + * + * TODO: There is another case where the LSE needs to + * be enabled: if CEC selects LSE as source. + */ + + stm32_rcc_enablelse(); +#endif +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb(); + rcc_enableapb2(); + rcc_enableapb1(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f40xxx_alarm.h b/arch/arm/src/stm32/stm32f40xxx_alarm.h new file mode 100644 index 0000000000000000000000000000000000000000..5d8d94a197561f10c74625b95326624400463554 --- /dev/null +++ b/arch/arm/src/stm32/stm32f40xxx_alarm.h @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/arm/src/include/stm32/stm32f0xxx_alarm.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Neil hancock - delegated to Gregory Nutt Mar 30, 2016 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32F40XXX_ALARM_H +#define __ARCH_ARM_SRC_STM32_STM32F40XXX_ALARM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid); + +/* These features are known to map to STM32 RTC from stm32F4xx and appear to + * map to beyond stm32F4xx and stm32L0xx there appears to be a small variant + * with stm32F3 but do not map to stm32F0, F1, F2 + */ + +enum alm_id_e +{ + RTC_ALARMA = 0, /* RTC ALARM A */ + RTC_ALARMB, /* RTC ALARM B */ + RTC_ALARM_LAST +}; + +/* Structure used to pass parmaters to set an alarm */ + +struct alm_setalarm_s +{ + int as_id; /* enum alm_id_e */ + struct tm as_time; /* Alarm expiration time */ + alm_callback_t as_cb; /* Callback (if non-NULL) */ + FAR void *as_arg; /* Argument for callback */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rtc_setalarm + * + * Description: + * Set an alarm to an asbolute time using associated hardware. + * + * Input Parameters: + * alminfo - Information about the alarm configuration. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo); + +/**************************************************************************** + * Name: stm32_rtc_cancelalarm + * + * Description: + * Cancel an alaram. + * + * Input Parameters: + * alarmid - Identifies the alarm to be cancelled + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int stm32_rtc_cancelalarm(enum alm_id_e alarmid); + +#endif /* CONFIG_RTC_ALARM */ +#endif /* __ARCH_ARM_SRC_STM32_STM32F40XXX_ALARM_H */ diff --git a/arch/arm/src/stm32/stm32f40xxx_dma.c b/arch/arm/src/stm32/stm32f40xxx_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..41d243685957832fc2581aa9c62c13174fb33e07 --- /dev/null +++ b/arch/arm/src/stm32/stm32f40xxx_dma.c @@ -0,0 +1,1053 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f40xxx_dma.c + * + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" +#include "stm32_dma.h" +#include "stm32.h" + +/* This file supports only the STM32 F4 family (an probably the F2 family + * as well?) + */ + +#if defined(CONFIG_STM32_STM32F40XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NSTREAMS 8 +#if STM32_NDMA > 1 +# define DMA2_NSTREAMS 8 +# define DMA_NSTREAMS (DMA1_NSTREAMS+DMA2_NSTREAMS) +#else +# define DMA_NSTREAMS DMA1_NSTREAMS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA stream base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes one DMA channel */ + +struct stm32_dma_s +{ + uint8_t stream; /* DMA stream number (0-7) */ + uint8_t irq; /* DMA stream IRQ number */ + uint8_t shift; /* ISR/IFCR bit shift value */ + uint8_t channel; /* DMA channel number (0-7) */ + sem_t sem; /* Used to wait for DMA channel to become available */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32_dma_s g_dma[DMA_NSTREAMS] = +{ + { + .stream = 0, + .irq = STM32_IRQ_DMA1S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA1S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA1S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA1S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA1S4, + .shift = DMA_INT_STREAM4_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA1S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA1S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA1S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(7), + }, +#if STM32_NDMA > 1 + { + .stream = 0, + .irq = STM32_IRQ_DMA2S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA2S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA2S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA2S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA2S4, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA2S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA2S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA2S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(7), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(DMA_BASE(dmast->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmast->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmast_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(dmast->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmast_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, dmast->base + offset); +} + +/************************************************************************************ + * Name: stm32_dmatake() and stm32_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32_dmatake(FAR struct stm32_dma_s *dmast) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmast->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32_dmagive(FAR struct stm32_dma_s *dmast) +{ + (void)sem_post(&dmast->sem); +} + +/************************************************************************************ + * Name: stm32_dmastream + * + * Description: + * Get the g_dma table entry associated with a DMA controller and a stream number + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmastream(unsigned int stream, + unsigned int controller) +{ + int index; + + DEBUGASSERT(stream < DMA_NSTREAMS && controller < STM32_NDMA); + + /* Convert the controller + stream based on the fact that there are 8 streams + * per controller. + */ + +#if STM32_NDMA > 1 + index = controller << 3 | stream; +#else + index = stream; +#endif + + /* Then return the stream structure associated with the stream index */ + + return &g_dma[index]; +} + +/************************************************************************************ + * Name: stm32_dmamap + * + * Description: + * Get the g_dma table entry associated with a bit-encoded DMA selection + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmamap(unsigned long dmamap) +{ + /* Extract the DMA controller number from the bit encoded value */ + + unsigned int controller = STM32_DMA_CONTROLLER(dmamap); + + /* Extact the stream number from the bit encoded value */ + + unsigned int stream = STM32_DMA_STREAM(dmamap); + + /* Return the table entry associated with the controller + stream */ + + return stm32_dmastream(stream, controller); +} + +/************************************************************************************ + * Name: stm32_dmastreamdisable + * + * Description: + * Disable the DMA stream + * + ************************************************************************************/ + +static void stm32_dmastreamdisable(struct stm32_dma_s *dmast) +{ + uint32_t regoffset; + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~DMA_SCR_ALLINTS; + + /* Disable the DMA stream */ + + regval &= ~DMA_SCR_EN; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); +} + +/************************************************************************************ + * Name: stm32_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32_dmainterrupt(int irq, void *context) +{ + struct stm32_dma_s *dmast; + uint32_t status; + uint32_t regoffset = 0; + unsigned int stream = 0; + unsigned int controller = 0; + + /* Get the stream and the controller that generated the interrupt */ + + if (irq >= STM32_IRQ_DMA1S0 && irq <= STM32_IRQ_DMA1S6) + { + stream = irq - STM32_IRQ_DMA1S0; + controller = DMA1; + } + else if (irq == STM32_IRQ_DMA1S7) + { + stream = 7; + controller = DMA1; + } + else +#if STM32_NDMA > 1 + if (irq >= STM32_IRQ_DMA2S0 && irq <= STM32_IRQ_DMA2S4) + { + stream = irq - STM32_IRQ_DMA2S0; + controller = DMA2; + } + else if (irq >= STM32_IRQ_DMA2S5 && irq <= STM32_IRQ_DMA2S7) + { + stream = irq - STM32_IRQ_DMA2S5 + 5; + controller = DMA2; + } + else +#endif + { + PANIC(); + } + + /* Get the stream structure from the stream and controller numbers */ + + dmast = stm32_dmastream(stream, controller); + + /* Select the interrupt status register (either the LISR or HISR) + * based on the stream number that caused the interrupt. + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LISR_OFFSET; + } + else + { + regoffset = STM32_DMA_HISR_OFFSET; + } + + /* Get the interrupt status for this stream */ + + status = (dmabase_getreg(dmast, regoffset) >> dmast->shift) & DMA_STREAM_MASK; + + /* Clear fetched stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (status << dmast->shift)); + + /* Invoke the callback */ + + if (dmast->callback) + { + dmast->callback(dmast, status, dmast->arg); + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32_dma_s *dmast; + int stream; + + /* Initialize each DMA stream */ + + for (stream = 0; stream < DMA_NSTREAMS; stream++) + { + dmast = &g_dma[stream]; + sem_init(&dmast->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmast->irq, stm32_dmainterrupt); + + /* Disable the DMA stream */ + + stm32_dmastreamdisable(dmast); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmast->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmast->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * dmamap - Identifies the stream/channel resource. For the STM32 F4, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'dmamap' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'dmamap' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int dmamap) +{ + FAR struct stm32_dma_s *dmast; + + /* Get the stream index from the bit-encoded channel value */ + + dmast = stm32_dmamap(dmamap); + DEBUGASSERT(dmast != NULL); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32_dmatake(dmast); + + /* The caller now has exclusive use of the DMA channel. Assign the + * channel to the stream and return an opaque reference to the stream + * structure. + */ + + dmast->channel = STM32_DMA_CHANNEL(dmamap); + return (DMA_HANDLE)dmast; +} + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32_dmagive(dmast); +} + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t scr) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t regoffset; + uint32_t regval; + + dmadbg("paddr: %08x maddr: %08x ntransfers: %d scr: %08x\n", + paddr, maddr, ntransfers, scr); + +#ifdef CONFIG_STM32_DMACAPABLE + DEBUGASSERT(stm32_dmacapable(maddr, ntransfers, scr)); +#endif + + /* "If the stream is enabled, disable it by resetting the EN bit in the + * DMA_SxCR register, then read this bit in order to confirm that there is no + * ongoing stream operation. Writing this bit to 0 is not immediately + * effective since it is actually written to 0 once all the current transfers + * have finished. When the EN bit is read as 0, this means that the stream is + * ready to be configured. It is therefore necessary to wait for the EN bit + * to be cleared before starting any stream configuration. ..." + */ + + while ((dmast_getreg(dmast, STM32_DMA_SCR_OFFSET) & DMA_SCR_EN) != 0); + + /* "... All the stream dedicated bits set in the status register (DMA_LISR + * and DMA_HISR) from the previous data block DMA transfer should be cleared + * before the stream can be re-enabled." + * + * Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); + + /* "Set the peripheral register address in the DMA_SPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmast_putreg(dmast, STM32_DMA_SPAR_OFFSET, paddr); + + /* "Set the memory address in the DMA_SM0ARx ... register. The data will be + * written to or read from this memory after the peripheral event." + * + * Note that in double-buffered mode it is explicitly assumed that the second + * buffer immediately follows the first. + */ + + dmast_putreg(dmast, STM32_DMA_SM0AR_OFFSET, maddr); + if (scr & DMA_SCR_DBM) + { + dmast_putreg(dmast, STM32_DMA_SM1AR_OFFSET, maddr + ntransfers); + } + + /* "Configure the total number of data items to be transferred in the + * DMA_SNDTRx register. After each peripheral event, this value will be + * decremented." + * + * "When the peripheral flow controller is used for a given stream, the value + * written into the DMA_SxNDTR has no effect on the DMA transfer. Actually, + * whatever the value written, it will be forced by hardware to 0xFFFF as soon + * as the stream is enabled..." + */ + + dmast_putreg(dmast, STM32_DMA_SNDTR_OFFSET, ntransfers); + + /* "Select the DMA channel (request) using CHSEL[2:0] in the DMA_SxCR register." + * + * "Configure the stream priority using the PL[1:0] bits in the DMA_SCRx" + * register." + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PL_MASK | DMA_SCR_CHSEL_MASK); + regval |= scr & DMA_SCR_PL_MASK; + regval |= (uint32_t)dmast->channel << DMA_SCR_CHSEL_SHIFT; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* "Configure the FIFO usage (enable or disable, threshold in transmission and + * reception)" + * + * "Caution is required when choosing the FIFO threshold (bits FTH[1:0] of the + * DMA_SxFCR register) and the size of the memory burst (MBURST[1:0] of the + * DMA_SxCR register): The content pointed by the FIFO threshold must exactly + * match to an integer number of memory burst transfers. If this is not in the + * case, a FIFO error (flag FEIFx of the DMA_HISR or DMA_LISR register) will be + * generated when the stream is enabled, then the stream will be automatically + * disabled." + * + * The FIFO is disabled in circular mode when transferring data from a + * peripheral to memory, as in this case it is usually desirable to know that + * every byte from the peripheral is transferred immediately to memory. It is + * not practical to flush the DMA FIFO, as this requires disabling the channel + * which triggers the transfer-complete interrupt. + * + * NOTE: The FEIFx error interrupt is not enabled because the FEIFx seems to + * be reported spuriously causing good transfers to be marked as failures. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + regval &= ~(DMA_SFCR_FTH_MASK | DMA_SFCR_FS_MASK | DMA_SFCR_FEIE); + if (!((scr & (DMA_SCR_CIRC | DMA_SCR_DIR_MASK)) == (DMA_SCR_CIRC | DMA_SCR_DIR_P2M))) + { + regval |= (DMA_SFCR_FTH_FULL | DMA_SFCR_DMDIS); + } + dmast_putreg(dmast, STM32_DMA_SFCR_OFFSET, regval); + + /* "Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register." + * + * Note: The CT bit is always reset. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_CIRC | DMA_SCR_DBM | DMA_SCR_CT | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + scr &= (DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_DBM | DMA_SCR_CIRC | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + regval |= scr; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); +} + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t scr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked whent the DMA commpletes */ + + dmast->callback = callback; + dmast->arg = arg; + + /* Activate the stream by setting the ENABLE bit in the DMA_SCRx register. + * As soon as the stream is enabled, it can serve any DMA request from the + * peripheral connected on the stream. + */ + + scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + scr |= DMA_SCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular + * and double-buffered modes, always interrupt on buffer wrap, and optionally + * interrupt at the halfway point. + */ + + if ((scr & (DMA_SCR_DBM | DMA_SCR_CIRC)) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + scr |= (half ? (DMA_SCR_HTIE | DMA_SCR_TEIE) : (DMA_SCR_TCIE | DMA_SCR_TEIE)); + } + else + { + /* In non-stop modes, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + scr |= (half ? DMA_SCR_HTIE : 0) | DMA_SCR_TCIE | DMA_SCR_TEIE; + } + + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, scr); +} + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + stm32_dmastreamdisable(dmast); +} + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Read the DMA bytes-remaining register. + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t residual; + + /* Fetch the count of bytes remaining to be transferred. + * + * If the FIFO is enabled, this count may be inaccurate. ST don't + * appear to document whether this counts the peripheral or the memory + * side of the channel, and they don't make the memory pointer + * available either. + * + * For reception in circular mode the FIFO is disabled in order that + * this value can be useful. + */ + + residual = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + + return (size_t)residual; +} + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size, burst_length; + uint32_t mend; + + dmavdbg("stm32_dmacapable: 0x%08x/%u 0x%08x\n", maddr, count, ccr); + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_SCR_MSIZE_MASK) + { + case DMA_SCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_SCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_SCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default: + dmavdbg("stm32_dmacapable: bad transfer size in CCR\n"); + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + dmavdbg("stm32_dmacapable: transfer unaligned\n"); + return false; + } + + /* Verify that burst transfers do not cross a 1KiB boundary. */ + + if ((maddr / 1024) != (mend / 1024)) + { + /* The transfer as a whole crosses a 1KiB boundary. + * Verify that no burst does by asserting that the address + * is aligned to the burst length. + */ + + switch (ccr & DMA_SCR_MBURST_MASK) + { + case DMA_SCR_MBURST_SINGLE: + burst_length = transfer_size; + break; + + case DMA_SCR_MBURST_INCR4: + burst_length = transfer_size << 2; + break; + + case DMA_SCR_MBURST_INCR8: + burst_length = transfer_size << 3; + break; + + case DMA_SCR_MBURST_INCR16: + burst_length = transfer_size << 4; + break; + + default: + dmavdbg("stm32_dmacapable: bad burst size in CCR\n"); + return false; + } + + if ((maddr & (burst_length - 1)) != 0) + { + dmavdbg("stm32_dmacapable: burst crosses 1KiB\n"); + return false; + } + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK)) + { + dmavdbg("stm32_dmacapable: transfer crosses memory region\n"); + return false; + } + + switch (maddr & STM32_REGION_MASK) + { + case STM32_FSMC_BANK1: + case STM32_FSMC_BANK2: + case STM32_FSMC_BANK3: + case STM32_FSMC_BANK4: + case STM32_SRAM_BASE: + /* All RAM is supported */ + + break; + + case STM32_CODE_BASE: + /* Everything except the CCM ram is supported */ + + if (maddr >= STM32_CCMRAM_BASE && + (maddr - STM32_CCMRAM_BASE) < 65536) + { + dmavdbg("stm32_dmacapable: transfer targets CCMRAM\n"); + return false; + } + break; + + default: + /* Everything else is unsupported by DMA */ + + dmavdbg("stm32_dmacapable: transfer targets unknown/unsupported region\n"); + return false; + } + + dmavdbg("stm32_dmacapable: transfer OK\n"); + return true; +} +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + irqstate_t flags; + + flags = enter_critical_section(); + regs->lisr = dmabase_getreg(dmast, STM32_DMA_LISR_OFFSET); + regs->hisr = dmabase_getreg(dmast, STM32_DMA_HISR_OFFSET); + regs->scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regs->sndtr = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + regs->spar = dmast_getreg(dmast, STM32_DMA_SPAR_OFFSET); + regs->sm0ar = dmast_getreg(dmast, STM32_DMA_SM0AR_OFFSET); + regs->sm1ar = dmast_getreg(dmast, STM32_DMA_SM1AR_OFFSET); + regs->sfcr = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmast->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" LISR[%08x]: %08x\n", dmabase + STM32_DMA_LISR_OFFSET, regs->lisr); + dmadbg(" HISR[%08x]: %08x\n", dmabase + STM32_DMA_HISR_OFFSET, regs->hisr); + dmadbg(" SCR[%08x]: %08x\n", dmast->base + STM32_DMA_SCR_OFFSET, regs->scr); + dmadbg(" SNDTR[%08x]: %08x\n", dmast->base + STM32_DMA_SNDTR_OFFSET, regs->sndtr); + dmadbg(" SPAR[%08x]: %08x\n", dmast->base + STM32_DMA_SPAR_OFFSET, regs->spar); + dmadbg(" SM0AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM0AR_OFFSET, regs->sm0ar); + dmadbg(" SM1AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM1AR_OFFSET, regs->sm1ar); + dmadbg(" SFCR[%08x]: %08x\n", dmast->base + STM32_DMA_SFCR_OFFSET, regs->sfcr); +} +#endif + +#endif /* CONFIG_STM32_STM32F40XX */ diff --git a/arch/arm/src/stm32/stm32f40xxx_rcc.c b/arch/arm/src/stm32/stm32f40xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..d431ce6df7a886fb4465328d22b185fe6cd2642b --- /dev/null +++ b/arch/arm/src/stm32/stm32f40xxx_rcc.c @@ -0,0 +1,944 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32f40xxx_rcc.c + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "stm32_pwr.h" +#include "itm_syslog.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/* Same for HSI */ + +#define HSIRDY_TIMEOUT HSERDY_TIMEOUT + +/* HSE divisor to yield ~1MHz RTC clock */ + +#define HSE_DIVISOR (STM32_HSE_FREQUENCY + 500000) / 1000000 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Reset the RCC clock configuration to the default reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Enable the Internal High Speed clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + /* Reset CFGR register */ + + putreg32(0x00000000, STM32_RCC_CFGR); + + /* Reset HSION, HSEON, CSSON and PLLON bits */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + /* Reset PLLCFGR register to reset default */ + + putreg32(RCC_PLLCFG_RESET, STM32_RCC_PLLCFG); + + /* Reset HSEBYP bit */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + /* Disable all interrupts */ + + putreg32(0x00000000, STM32_RCC_CIR); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB1ENR); + + /* Enable GPIOA, GPIOB, .... GPIOI */ + +#if STM32_NGPIO_PORTS > 0 + regval |= (RCC_AHB1ENR_GPIOAEN +#if STM32_NGPIO_PORTS > 1 + | RCC_AHB1ENR_GPIOBEN +#endif +#if STM32_NGPIO_PORTS > 2 + | RCC_AHB1ENR_GPIOCEN +#endif +#if STM32_NGPIO_PORTS > 3 + | RCC_AHB1ENR_GPIODEN +#endif +#if STM32_NGPIO_PORTS > 4 + | RCC_AHB1ENR_GPIOEEN +#endif +#if STM32_NGPIO_PORTS > 5 + | RCC_AHB1ENR_GPIOFEN +#endif +#if STM32_NGPIO_PORTS > 6 + | RCC_AHB1ENR_GPIOGEN +#endif +#if STM32_NGPIO_PORTS > 7 + | RCC_AHB1ENR_GPIOHEN +#endif +#if STM32_NGPIO_PORTS > 8 + | RCC_AHB1ENR_GPIOIEN +#endif +#if STM32_NGPIO_PORTS > 9 + | RCC_AHB1ENR_GPIOJEN +#endif +#if STM32_NGPIO_PORTS > 10 + | RCC_AHB1ENR_GPIOKEN +#endif + ); +#endif + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_BKPSRAM + /* Backup SRAM clock enable */ + + regval |= RCC_AHB1ENR_BKPSRAMEN; +#endif + +#ifdef CONFIG_STM32_CCMDATARAM + /* CCM data RAM clock enable */ + + regval |= RCC_AHB1ENR_CCMDATARAMEN; +#endif + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHB1ENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHB1ENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_ETHMAC + /* Ethernet MAC clocking */ + + regval |= (RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN); + +#ifdef CONFIG_STM32_ETH_PTP + /* Precision Time Protocol (PTP) */ + + regval |= RCC_AHB1ENR_ETHMACPTPEN; + +#endif +#endif + +#ifdef CONFIG_STM32_OTGHS + /* USB OTG HS */ + + regval |= RCC_AHB1ENR_OTGHSEN; + +#endif /* CONFIG_STM32_OTGHS */ + +#ifdef CONFIG_STM32_DMA2D + /* DMA2D clock */ + + regval |= RCC_AHB1ENR_DMA2DEN; +#endif + + putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR register to enabled the + * selected AHB2 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB2ENR); + +#ifdef CONFIG_STM32_DCMI + /* Camera interface enable */ + + regval |= RCC_AHB2ENR_DCMIEN; +#endif + +#ifdef CONFIG_STM32_CRYP + /* Cryptographic modules clock enable */ + + regval |= RCC_AHB2ENR_CRYPEN; +#endif + +#ifdef CONFIG_STM32_HASH + /* Hash modules clock enable */ + + regval |= RCC_AHB2ENR_HASHEN; +#endif + +#ifdef CONFIG_STM32_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHB2ENR_RNGEN; +#endif + +#ifdef CONFIG_STM32_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHB2ENR_OTGFSEN; +#endif + + putreg32(regval, STM32_RCC_AHB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ +#ifdef CONFIG_STM32_FSMC + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the + * selected AHB3 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB3ENR); + + /* Flexible static memory controller module clock enable */ + + regval |= RCC_AHB3ENR_FSMCEN; + + putreg32(regval, STM32_RCC_AHB3ENR); /* Enable peripherals */ +#endif +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32_TIM2 + /* TIM2 clock enable */ + + regval |= RCC_APB1ENR_TIM2EN; +#endif + +#ifdef CONFIG_STM32_TIM3 + /* TIM3 clock enable */ + + regval |= RCC_APB1ENR_TIM3EN; +#endif + +#ifdef CONFIG_STM32_TIM4 + /* TIM4 clock enable */ + + regval |= RCC_APB1ENR_TIM4EN; +#endif + +#ifdef CONFIG_STM32_TIM5 + /* TIM5 clock enable */ + + regval |= RCC_APB1ENR_TIM5EN; +#endif + +#ifdef CONFIG_STM32_TIM6 + /* TIM6 clock enable */ + + regval |= RCC_APB1ENR_TIM6EN; +#endif + +#ifdef CONFIG_STM32_TIM7 + /* TIM7 clock enable */ + + regval |= RCC_APB1ENR_TIM7EN; +#endif + +#ifdef CONFIG_STM32_TIM12 + /* TIM12 clock enable */ + + regval |= RCC_APB1ENR_TIM12EN; +#endif + +#ifdef CONFIG_STM32_TIM13 + /* TIM13 clock enable */ + + regval |= RCC_APB1ENR_TIM13EN; +#endif + +#ifdef CONFIG_STM32_TIM14 + /* TIM14 clock enable */ + + regval |= RCC_APB1ENR_TIM14EN; +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32_UART4 + /* UART4 clock enable */ + + regval |= RCC_APB1ENR_UART4EN; +#endif + +#ifdef CONFIG_STM32_UART5 + /* UART5 clock enable */ + + regval |= RCC_APB1ENR_UART5EN; +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1ENR_I2C1EN; +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1ENR_I2C2EN; +#endif + +#ifdef CONFIG_STM32_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1ENR_I2C3EN; +#endif + +#ifdef CONFIG_STM32_CAN1 + /* CAN 1 clock enable */ + + regval |= RCC_APB1ENR_CAN1EN; +#endif + +#ifdef CONFIG_STM32_CAN2 + /* CAN2 clock enable. NOTE: CAN2 needs CAN1 clock as well. */ + + regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN); +#endif + + /* Power interface clock enable. The PWR block is always enabled so that + * we can set the internal voltage regulator for maximum performance. + */ + + regval |= RCC_APB1ENR_PWREN; + +#if defined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + +#ifdef CONFIG_STM32_UART7 + /* UART7 clock enable */ + + regval |= RCC_APB1ENR_UART7EN; +#endif + +#ifdef CONFIG_STM32_UART8 + /* UART8 clock enable */ + + regval |= RCC_APB1ENR_UART8EN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32_TIM1 + /* TIM1 clock enable */ + + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32_TIM8 + /* TIM8 clock enable */ + + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32_USART6 + /* USART6 clock enable */ + + regval |= RCC_APB2ENR_USART6EN; +#endif + +#ifdef CONFIG_STM32_ADC1 + /* ADC1 clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + +#ifdef CONFIG_STM32_ADC2 + /* ADC2 clock enable */ + + regval |= RCC_APB2ENR_ADC2EN; +#endif + +#ifdef CONFIG_STM32_ADC3 + /* ADC3 clock enable */ + + regval |= RCC_APB2ENR_ADC3EN; +#endif + +#ifdef CONFIG_STM32_SDIO + /* SDIO clock enable */ + + regval |= RCC_APB2ENR_SDIOEN; +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_SPI4 + /* SPI4 clock enable */ + + regval |= RCC_APB2ENR_SPI4EN; +#endif + +#ifdef CONFIG_STM32_SYSCFG + /* System configuration controller clock enable */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32_TIM9 + /* TIM9 clock enable */ + + regval |= RCC_APB2ENR_TIM9EN; +#endif + +#ifdef CONFIG_STM32_TIM10 + /* TIM10 clock enable */ + + regval |= RCC_APB2ENR_TIM10EN; +#endif + +#ifdef CONFIG_STM32_TIM11 + /* TIM11 clock enable */ + + regval |= RCC_APB2ENR_TIM11EN; +#endif + +#ifdef CONFIG_STM32_SPI5 + /* SPI5 clock enable */ + + regval |= RCC_APB2ENR_SPI5EN; +#endif + +#ifdef CONFIG_STM32_SPI6 + /* SPI6 clock enable */ + + regval |= RCC_APB2ENR_SPI6EN; +#endif + +#ifdef CONFIG_STM32_LTDC + /* LTDC clock enable */ + + regval |= RCC_APB2ENR_LTDCEN; +#endif + + putreg32(regval, STM32_RCC_APB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + +#ifdef STM32_BOARD_USEHSI + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; /* Enable HSI */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#else /* if STM32_BOARD_USEHSE */ + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#endif + + /* Check for a timeout. If this timeout occurs, then we are hosed. We + * have no real back-up plan, although the following logic makes it look + * as though we do. + */ + + if (timeout > 0) + { + /* Select regulator voltage output Scale 1 mode to support system + * frequencies up to 168 MHz. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32_RCC_APB1ENR); + + regval = getreg32(STM32_PWR_CR); +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) + regval &= ~PWR_CR_VOS_MASK; + regval |= PWR_CR_VOS_SCALE_1; +#else + regval |= PWR_CR_VOS; +#endif + putreg32(regval, STM32_PWR_CR); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#ifdef CONFIG_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the PLL dividers and multipliers to configure the main PLL */ + + regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN | STM32_PLLCFG_PLLP + | STM32_PLLCFG_PLLQ +#ifdef STM32_BOARD_USEHSI + | RCC_PLLCFG_PLLSRC_HSI +#else /* if STM32_BOARD_USEHSE */ + | RCC_PLLCFG_PLLSRC_HSE +#endif +#if defined(CONFIG_STM32_STM32F446) + | STM32_PLLCFG_PLLR +#endif + ); + putreg32(regval, STM32_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0) + { + } + +#if defined(CONFIG_STM32_STM32F429) || defined(CONFIG_STM32_STM32F446) + /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ + + regval = getreg32(STM32_PWR_CR); + regval |= PWR_CR_ODEN; + putreg32(regval, STM32_PWR_CR); + while ((getreg32(STM32_PWR_CSR) & PWR_CSR_ODRDY) == 0) + { + } + + regval = getreg32(STM32_PWR_CR); + regval |= PWR_CR_ODSWEN; + putreg32(regval, STM32_PWR_CR); + while ((getreg32(STM32_PWR_CSR) & PWR_CSR_ODSWRDY) == 0) + { + } +#endif + + /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */ + + regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN +#ifdef CONFIG_STM32_FLASH_PREFETCH + | FLASH_ACR_PRFTEN +#endif + ); + putreg32(regval, STM32_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) + { + } + +#if defined(CONFIG_STM32_LTDC) || \ + (defined(CONFIG_STM32_STM32F446) && defined(CONFIG_STM32_SAIPLL)) + /* Configure PLLSAI */ + + regval = getreg32(STM32_RCC_PLLSAICFGR); +#if defined(CONFIG_STM32_STM32F446) + regval &= ~(RCC_PLLSAICFGR_PLLSAIM_MASK + | RCC_PLLSAICFGR_PLLSAIN_MASK + | RCC_PLLSAICFGR_PLLSAIP_MASK + | RCC_PLLSAICFGR_PLLSAIQ_MASK); + regval |= (STM32_RCC_PLLSAICFGR_PLLSAIM + | STM32_RCC_PLLSAICFGR_PLLSAIN + | STM32_RCC_PLLSAICFGR_PLLSAIP + | STM32_RCC_PLLSAICFGR_PLLSAIQ); +#else + regval &= ~(RCC_PLLSAICFGR_PLLSAIN_MASK + | RCC_PLLSAICFGR_PLLSAIR_MASK + | RCC_PLLSAICFGR_PLLSAIQ_MASK); + regval |= (STM32_RCC_PLLSAICFGR_PLLSAIN + | STM32_RCC_PLLSAICFGR_PLLSAIR + | STM32_RCC_PLLSAICFGR_PLLSAIQ); +#endif + putreg32(regval, STM32_RCC_PLLSAICFGR); + + regval = getreg32(STM32_RCC_DCKCFGR); +#if defined(CONFIG_STM32_STM32F446) + regval &= ~(RCC_DCKCFGR_PLLI2SDIVQ_MASK + | RCC_DCKCFGR_PLLSAIDIVQ_MASK + | RCC_DCKCFGR_SAI1SRC_MASK + | RCC_DCKCFGR_SAI2SRC_MASK + | RCC_DCKCFGR_I2S1SRC_MASK + | RCC_DCKCFGR_I2S2SRC_MASK); + regval |= (STM32_RCC_DCKCFGR_PLLI2SDIVQ + | STM32_RCC_DCKCFGR_PLLSAIDIVQ + | STM32_RCC_DCKCFGR_SAI1SRC + | STM32_RCC_DCKCFGR_SAI2SRC + | STM32_RCC_DCKCFGR_TIMPRE + | STM32_RCC_DCKCFGR_I2S1SRC + | STM32_RCC_DCKCFGR_I2S2SRC); +#else + regval &= ~RCC_DCKCFGR_PLLSAIDIVR_MASK; + regval |= STM32_RCC_DCKCFGR_PLLSAIDIVR; +#endif + putreg32(regval, STM32_RCC_DCKCFGR); + + /* Enable PLLSAI */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLSAION; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLLSAI is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLSAIRDY) == 0) + { + } +#endif + +#if defined(CONFIG_STM32_STM32F446) && defined(CONFIG_STM32_I2SPLL) + /* Configure PLLI2S */ + + regval = getreg32(STM32_RCC_PLLI2SCFGR); + regval &= ~(RCC_PLLI2SCFGR_PLLI2SM_MASK + | RCC_PLLI2SCFGR_PLLI2SN_MASK + | RCC_PLLI2SCFGR_PLLI2SP_MASK + | RCC_PLLI2SCFGR_PLLI2SQ_MASK); + regval |= (STM32_RCC_PLLI2SCFGR_PLLI2SM + | STM32_RCC_PLLI2SCFGR_PLLI2SN + | STM32_RCC_PLLI2SCFGR_PLLI2SP + | STM32_RCC_PLLI2SCFGR_PLLI2SQ + | STM32_RCC_PLLI2SCFGR_PLLI2SR); + putreg32(regval, STM32_RCC_PLLI2SCFGR); + + regval = getreg32(STM32_RCC_DCKCFGR2); + regval &= ~(RCC_DCKCFGR2_FMPI2C1SEL_MASK + | RCC_DCKCFGR2_CECSEL_MASK + | RCC_DCKCFGR2_CK48MSEL_MASK + | RCC_DCKCFGR2_SDIOSEL_MASK + | RCC_DCKCFGR2_SPDIFRXSEL_MASK); + regval |= (STM32_RCC_DCKCFGR2_FMPI2C1SEL + | STM32_RCC_DCKCFGR2_CECSEL + | STM32_RCC_DCKCFGR2_CK48MSEL + | STM32_RCC_DCKCFGR2_SDIOSEL + | STM32_RCC_DCKCFGR2_SPDIFRXSEL); + + putreg32(regval, STM32_RCC_DCKCFGR2); + + /* Enable PLLI2S */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLI2SON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLLI2S is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLI2SRDY) == 0) + { + } +#endif + +#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + */ + + stm32_rcc_enablelse(); +#endif + } +} +#endif + +/**************************************************************************** + * Name: efm32_itm_syslog + * + * Description: + * Enable Serial wire output pin, configure debug clocking, and enable + * ITM syslog support. + * + ****************************************************************************/ + +#if defined(CONFIG_SYSLOG) && defined(CONFIG_ARMV7M_ITMSYSLOG) +static inline void rcc_itm_syslog(void) +{ + /* Enable SWO output */ + + modifyreg32(STM32_DBGMCU_CR, DBGMCU_CR_TRACEMODE_MASK, DBGMCU_CR_ASYNCH | + DBGMCU_CR_TRACEIOEN); + + itm_syslog_initialize(); +} +#else +# define rcc_itm_syslog() +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); + rcc_itm_syslog(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c new file mode 100644 index 0000000000000000000000000000000000000000..ece81269c6698513f1c9ef42cf7d9b3d1f494c4f --- /dev/null +++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c @@ -0,0 +1,1501 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32f40xxx_rtcc.c + * + * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Modified: Neil Hancock + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "stm32_rcc.h" +#include "stm32_pwr.h" +#include "stm32_exti.h" +#include "stm32_rtc.h" + +#include + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports + * - date/time RTC hardware + * - extended functions Alarm A and B for STM32F4xx and onwards + * */ + +#ifndef CONFIG_RTC_DATETIME +# error "CONFIG_RTC_DATETIME must be set to use this driver" +#endif + +#ifdef CONFIG_RTC_HIRES +# error "CONFIG_RTC_HIRES must NOT be set with this driver" +#endif + +#ifndef CONFIG_STM32_PWR +# error "CONFIG_STM32_PWR must selected to use this driver" +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +#if !defined(CONFIG_RTC_MAGIC) +# define CONFIG_RTC_MAGIC (0xfacefeee) +#endif + +#if !defined(CONFIG_RTC_MAGIC_REG) +# define CONFIG_RTC_MAGIC_REG (0) +#endif + +/* Constants ************************************************************************/ + +#define SYNCHRO_TIMEOUT (0x00020000) +#define INITMODE_TIMEOUT (0x00010000) +#define RTC_MAGIC CONFIG_RTC_MAGIC +#define RTC_MAGIC_REG STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG) + +/* Proxy definitions to make the same code work for all the STM32 series ************/ + +# define STM32_RCC_XXX STM32_RCC_BDCR +# define RCC_XXX_YYYRST RCC_BDCR_BDRST +# define RCC_XXX_RTCEN RCC_BDCR_RTCEN +# define RCC_XXX_RTCSEL_MASK RCC_BDCR_RTCSEL_MASK +# define RCC_XXX_RTCSEL_LSE RCC_BDCR_RTCSEL_LSE +# define RCC_XXX_RTCSEL_LSI RCC_BDCR_RTCSEL_LSI +# define RCC_XXX_RTCSEL_HSE RCC_BDCR_RTCSEL_HSE + +/* BCD conversions */ + +#define rtc_reg_tr_bin2bcd(tp) \ + ((rtc_bin2bcd((tp)->tm_sec) << RTC_TR_SU_SHIFT) | \ + (rtc_bin2bcd((tp)->tm_min) << RTC_TR_MNU_SHIFT) | \ + (rtc_bin2bcd((tp)->tm_hour) << RTC_TR_HU_SHIFT)) + +#define rtc_reg_alrmr_bin2bcd(tm) \ + ((rtc_bin2bcd((tm)->tm_sec) << RTC_ALRMR_SU_SHIFT) | \ + (rtc_bin2bcd((tm)->tm_min) << RTC_ALRMR_MNU_SHIFT) | \ + (rtc_bin2bcd((tm)->tm_hour) << RTC_ALRMR_HU_SHIFT)) + +/* Time conversions */ + +#define MINUTES_IN_HOUR 60 +#define HOURS_IN_DAY 24 + +/* Can't exceed 24hours-2min without providing extra logic for carry over for day. */ + +#define MAX_RTC_ALARM_REL_MINUTES (24*MINUTES_IN_HOUR)-2 + +#define hours_add(parm_hrs) \ + time->tm_hour += parm_hrs;\ + if ((HOURS_IN_DAY-1) < (time->tm_hour))\ + {\ + time->tm_hour = (parm_hrs - HOURS_IN_DAY);\ + } + +#define RTC_ALRMR_DIS_MASK (RTC_ALRMR_MSK4 | RTC_ALRMR_MSK3 | \ + RTC_ALRMR_MSK2 | RTC_ALRMR_MSK1) +#define RTC_ALRMR_DIS_DATE_MASK (RTC_ALRMR_MSK4) +#define RTC_ALRMR_ENABLE (0) + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +typedef unsigned int rtc_alarmreg_t; + +struct alm_cbinfo_s +{ + volatile alm_callback_t ac_cb; /* Client callback function */ + volatile FAR void *ac_arg; /* Argument to pass with the callback function */ +}; +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +/* Callback to use when an EXTI is activated */ + +static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST]; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtchw_check_alrawf(void); +static int rtchw_check_alrbwf(void); +static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg); +static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg); +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" TR: %08x\n", getreg32(STM32_RTC_TR)); + rtclldbg(" DR: %08x\n", getreg32(STM32_RTC_DR)); + rtclldbg(" CR: %08x\n", getreg32(STM32_RTC_CR)); + rtclldbg(" ISR: %08x\n", getreg32(STM32_RTC_ISR)); + rtclldbg(" PRER: %08x\n", getreg32(STM32_RTC_PRER)); + rtclldbg(" WUTR: %08x\n", getreg32(STM32_RTC_WUTR)); +#ifndef CONFIG_STM32_STM32F30XX + rtclldbg(" CALIBR: %08x\n", getreg32(STM32_RTC_CALIBR)); +#endif + rtclldbg(" ALRMAR: %08x\n", getreg32(STM32_RTC_ALRMAR)); + rtclldbg(" ALRMBR: %08x\n", getreg32(STM32_RTC_ALRMBR)); + rtclldbg(" SHIFTR: %08x\n", getreg32(STM32_RTC_SHIFTR)); + rtclldbg(" TSTR: %08x\n", getreg32(STM32_RTC_TSTR)); + rtclldbg(" TSDR: %08x\n", getreg32(STM32_RTC_TSDR)); + rtclldbg(" TSSSR: %08x\n", getreg32(STM32_RTC_TSSSR)); + rtclldbg(" CALR: %08x\n", getreg32(STM32_RTC_CALR)); + rtclldbg(" TAFCR: %08x\n", getreg32(STM32_RTC_TAFCR)); + rtclldbg("ALRMASSR: %08x\n", getreg32(STM32_RTC_ALRMASSR)); + rtclldbg("ALRMBSSR: %08x\n", getreg32(STM32_RTC_ALRMBSSR)); + rtclldbg("MAGICREG: %08x\n", getreg32(RTC_MAGIC_REG)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_wprunlock + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void rtc_wprunlock(void) +{ + /* Enable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* The following steps are required to unlock the write protection on all the + * RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR). + * + * 1. Write 0xCA into the RTC_WPR register. + * 2. Write 0x53 into the RTC_WPR register. + * + * Writing a wrong key re-activates the write protection. + */ + + putreg32(0xca, STM32_RTC_WPR); + putreg32(0x53, STM32_RTC_WPR); +} + +/************************************************************************************ + * Name: rtc_wprlock + * + * Description: + * Enable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void rtc_wprlock(void) +{ + /* Writing any wrong key re-activates the write protection. */ + + putreg32(0xff, STM32_RTC_WPR); + + /* Disable write access to the backup domain (RTC registers, RTC backup data + * registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(false); +} + +/************************************************************************************ + * Name: rtc_synchwait + * + * Description: + * Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_synchwait(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Clear Registers synchronization flag (RSF) */ + + regval = getreg32(STM32_RTC_ISR); + regval &= ~RTC_ISR_RSF; + putreg32(regval, STM32_RTC_ISR); + + /* Now wait the registers to become synchronised */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_RSF) != 0) + { + /* Synchronized */ + + ret = OK; + break; + } + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + return ret; +} + +/************************************************************************************ + * Name: rtc_enterinit + * + * Description: + * Enter RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_enterinit(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Check if the Initialization mode is already set */ + + regval = getreg32(STM32_RTC_ISR); + + ret = OK; + if ((regval & RTC_ISR_INITF) == 0) + { + /* Set the Initialization mode */ + + putreg32(RTC_ISR_INIT, STM32_RTC_ISR); + + /* Wait until the RTC is in the INIT state (or a timeout occurs) */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_INITF) != 0) + { + ret = OK; + break; + } + } + } + + return ret; +} + +/************************************************************************************ + * Name: rtc_exitinit + * + * Description: + * Exit RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_exitinit(void) +{ + uint32_t regval; + + regval = getreg32(STM32_RTC_ISR); + regval &= ~(RTC_ISR_INIT); + putreg32(regval, STM32_RTC_ISR); +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint32_t rtc_bin2bcd(int value) +{ + uint32_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint32_t value) +{ + uint32_t tens = (value >> 4) * 10; + return (int)(tens + (value & 0x0f)); +} + +/************************************************************************************ + * Name: rtc_setup + * + * Description: + * Performs first time configuration of the RTC. A special value written into + * back-up register 0 will prevent this function from being called on sub-sequent + * resets or power up. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_setup(void) +{ + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the 24 hour format by clearing the FMT bit in the RTC + * control register + */ + + regval = getreg32(STM32_RTC_CR); + regval &= ~RTC_CR_FMT; + putreg32(regval, STM32_RTC_CR); + + /* Configure RTC pre-scaler with the required values */ + +#ifdef CONFIG_RTC_HSECLOCK + /* For a 1 MHz clock this yields 0.9999360041 Hz on the second + * timer - which is pretty close. + */ + + putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32_RTC_PRER); +#else + /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ + + putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32_RTC_PRER); +#endif + + /* Exit RTC initialization mode */ + + rtc_exitinit(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + + return ret; +} + +/************************************************************************************ + * Name: rtc_resume + * + * Description: + * Called when the RTC was already initialized on a previous power cycle. This + * just brings the RTC back into full operation. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_resume(void) +{ +#ifdef CONFIG_RTC_ALARM + uint32_t regval; + + /* Clear the RTC alarm flags */ + + regval = getreg32(STM32_RTC_ISR); + regval &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF); + putreg32(regval, STM32_RTC_ISR); + + /* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */ + + putreg32((1 << 17), STM32_EXTI_PR); +#endif +} + +/************************************************************************************ + * Name: stm32_rtc_alarm_handler + * + * Description: + * RTC ALARM interrupt service routine through the EXTI line + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int stm32_rtc_alarm_handler(int irq, void *context) +{ + FAR struct alm_cbinfo_s *cbinfo; + alm_callback_t cb; + FAR void *arg; + uint32_t isr; + uint32_t cr; + int ret = OK; + + isr = getreg32(STM32_RTC_ISR); + + /* Check for EXTI from Alarm A or B and handle according */ + + if ((isr & RTC_ISR_ALRAF) != 0) + { + cr = getreg32(STM32_RTC_CR); + if ((cr & RTC_CR_ALRAIE) != 0) + { + cbinfo = &g_alarmcb[RTC_ALARMA]; + if (cbinfo->ac_cb != NULL) + { + /* Alarm A callback */ + + cb = cbinfo->ac_cb; + arg = (FAR void *)cbinfo->ac_arg; + + cbinfo->ac_cb = NULL; + cbinfo->ac_arg = NULL; + + cb(arg, RTC_ALARMA); + } + + isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRAF; + putreg32(isr, STM32_RTC_CR); + } + } + + if ((isr & RTC_ISR_ALRBF) != 0) + { + cr = getreg32(STM32_RTC_CR); + if ((cr & RTC_CR_ALRBIE) != 0) + { + cbinfo = &g_alarmcb[RTC_ALARMB]; + if (cbinfo->ac_cb != NULL) + { + /* Alarm B callback */ + + cb = cbinfo->ac_cb; + arg = (FAR void *)cbinfo->ac_arg; + + cbinfo->ac_cb = NULL; + cbinfo->ac_arg = NULL; + + cb(arg, RTC_ALARMB); + } + + isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRBF; + putreg32(isr, STM32_RTC_CR); + } + } + + return ret; +} +#endif + +/************************************************************************************ + * Name: rtchw_check_alrXwf X= a or B + * + * Description: + * Check registers + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtchw_check_alrawf(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret = -ETIMEDOUT; + + /* Check RTC_ISR ALRAWF for access to alarm register, + * Can take 2 RTCCLK cycles or timeout + * CubeMX use GetTick. + */ + + for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_ALRAWF) != 0) + { + ret = OK; + break; + } + } + + return ret; +} +#endif + +#ifdef CONFIG_RTC_ALARM +static int rtchw_check_alrbwf(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret = -ETIMEDOUT; + + /* Check RTC_ISR ALRAWF for access to alarm register, + * can take 2 RTCCLK cycles or timeout + * CubeMX use GetTick. + */ + + for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++) + { + regval = getreg32(STM32_RTC_ISR); + if ((regval & RTC_ISR_ALRBWF) != 0) + { + ret = OK; + break; + } + } + + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32_rtchw_set_alrmXr X is a or b + * + * Description: + * Set the alarm (A or B) hardware registers, using the required hardware access + * protocol + * + * Input Parameters: + * alarmreg - the register + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg) +{ + int ret = -EBUSY; + + /* Need to follow RTC register wrote protection + * Disable the write protection for RTC registers + */ + + rtc_wprunlock(); + + /* Disable RTC alarm & Interrupt */ + + modifyreg32(STM32_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0); + + ret = rtchw_check_alrawf(); + if (ret != OK) + { + goto errout_with_wprunlock; + } + + /* Set the RTC Alarm register */ + + putreg32(alarmreg, STM32_RTC_ALRMAR); + rtcvdbg(" TR: %08x ALRMAR: %08x\n", + getreg32(STM32_RTC_TR), getreg32(STM32_RTC_ALRMAR)); + + /* Enable RTC alarm */ + + modifyreg32(STM32_RTC_CR, 0, (RTC_CR_ALRAE | RTC_CR_ALRAIE)); + +errout_with_wprunlock: + rtc_wprlock(); + return ret; +} +#endif + +#ifdef CONFIG_RTC_ALARM +static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg) +{ + int ret = -EBUSY; + + /* Need to follow RTC register wrote protection + * Disable the write protection for RTC registers + */ + + rtc_wprunlock(); + + /* Disable RTC alarm B & Interrupt B */ + + modifyreg32(STM32_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0); + + ret = rtchw_check_alrbwf(); + if (ret != OK) + { + goto rtchw_set_alrmbr_exit; + } + + /* Set the RTC Alarm register */ + + putreg32(alarmreg, STM32_RTC_ALRMBR); + rtcvdbg(" TR: %08x ALRMBR: %08x\n", + getreg32(STM32_RTC_TR), getreg32(STM32_RTC_ALRMBR)); + + /* Enable RTC alarm B */ + + modifyreg32(STM32_RTC_CR, 0, (RTC_CR_ALRBE | RTC_CR_ALRBIE)); + +rtchw_set_alrmbr_exit: + rtc_wprlock(); + return ret; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + uint32_t regval; + uint32_t tr_bkp; + uint32_t dr_bkp; + int ret; + int maxretry = 10; + int nretry = 0; + + /* Clocking for the PWR block must be provided. However, this is done + * unconditionally in stm32f40xxx_rcc.c on power up. This done unconditionally + * because the PWR block is also needed to set the internal voltage regulator for + * maximum performance. + */ + + rtc_dumpregs("On reset"); + + /* Select the clock source */ + /* Save the token before losing it when resetting */ + + regval = getreg32(RTC_MAGIC_REG); + + (void)stm32_pwr_enablebkp(true); + + if (regval != RTC_MAGIC) + { + /* We might be changing RTCSEL - to ensure such changes work, we must reset the + * backup domain (having backed up the RTC_MAGIC token) + */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_YYYRST); + modifyreg32(STM32_RCC_XXX, RCC_XXX_YYYRST, 0); + + /* Some boards do not have the external 32khz oscillator installed, for those + * boards we must fallback to the crummy internal RC clock or the external high + * rate clock + */ + +#ifdef CONFIG_RTC_HSECLOCK + /* Use the HSE clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_HSE); + +#elif defined(CONFIG_RTC_LSICLOCK) + /* Use the LSI clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSI); + +#elif defined(CONFIG_RTC_LSECLOCK) + /* Use the LSE clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSE); + +#endif + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_RTCEN); + } + else /* The RTC is already in use: check if the clock source is changed */ + { +#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_RTC_LSICLOCK) || \ + defined(CONFIG_RTC_LSECLOCK) + + uint32_t clksrc = getreg32(STM32_RCC_XXX); + +#if defined(CONFIG_RTC_HSECLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_HSE) +#elif defined(CONFIG_RTC_LSICLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_LSI) +#elif defined(CONFIG_RTC_LSECLOCK) + if ((clksrc & RCC_XXX_RTCSEL_MASK) != RCC_XXX_RTCSEL_LSE) +#endif +#endif + { + tr_bkp = getreg32(STM32_RTC_TR); + dr_bkp = getreg32(STM32_RTC_DR); + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_YYYRST); + modifyreg32(STM32_RCC_XXX, RCC_XXX_YYYRST, 0); + +#if defined(CONFIG_RTC_HSECLOCK) + /* Change to the new clock as the input to the RTC block */ + + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_HSE); + +#elif defined(CONFIG_RTC_LSICLOCK) + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSI); + +#elif defined(CONFIG_RTC_LSECLOCK) + modifyreg32(STM32_RCC_XXX, RCC_XXX_RTCSEL_MASK, RCC_XXX_RTCSEL_LSE); +#endif + + putreg32(tr_bkp, STM32_RTC_TR); + putreg32(dr_bkp, STM32_RTC_DR); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32_RCC_XXX, 0, RCC_XXX_RTCEN); + } + } + + (void)stm32_pwr_enablebkp(false); + + /* Loop, attempting to initialize/resume the RTC. This loop is necessary + * because it seems that occasionally it takes longer to initialize the RTC + * (the actual failure is in rtc_synchwait()). + */ + + do + { + /* Wait for the RTC Time and Date registers to be synchronized with RTC APB + * clock. + */ + + ret = rtc_synchwait(); + + /* Check that rtc_syncwait() returned successfully */ + + switch (ret) + { + case OK: + { + rtclldbg("rtc_syncwait() okay\n"); + break; + } + + default: + { + rtclldbg("rtc_syncwait() failed (%d)\n", ret); + break; + } + } + } + while (ret != OK && ++nretry < maxretry); + + /* Check if the one-time initialization of the RTC has already been + * performed. We can determine this by checking if the magic number + * has been writing to to back-up date register DR0. + */ + + if (regval != RTC_MAGIC) + { + rtclldbg("Do setup\n"); + + /* Perform the one-time setup of the LSE clocking to the RTC */ + + ret = rtc_setup(); + + /* Enable write access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + } + else + { + rtclldbg("Do resume\n"); + + /* RTC already set-up, just resume normal operation */ + + rtc_resume(); + rtc_dumpregs("Did resume"); + } + + /* Disable write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(false); + + if (ret != OK && nretry > 0) + { + rtclldbg("setup/resume ran %d times and failed with %d\n", + nretry, ret); + return -ETIMEDOUT; + } + +#ifdef CONFIG_RTC_ALARM + /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are + * connected to the EXTI controller. To enable the RTC Alarm interrupt, the + * following sequence is required: + * + * 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt mode and select the + * rising edge sensitivity. + * For STM32F4xx + * EXTI line 21 RTC Tamper & Timestamp + * EXTI line 22 RTC Wakeup + * 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC. + * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B). + */ + + stm32_exti_alarm(true, false, true, stm32_rtc_alarm_handler); +#endif + + g_rtc_enabled = true; + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: stm32_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is returned through 'nsec'. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec) +#else +int up_rtc_getdatetime(FAR struct tm *tp) +#endif +{ +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + uint32_t ssr; +#endif + uint32_t dr; + uint32_t tr; + uint32_t tmp; + + /* Sample the data time registers. There is a race condition here... If we sample + * the time just before midnight on December 31, the date could be wrong because + * the day rolled over while were sampling. + */ + + do + { + dr = getreg32(STM32_RTC_DR); + tr = getreg32(STM32_RTC_TR); +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + ssr = getreg32(STM32_RTC_SSR); +#endif + tmp = getreg32(STM32_RTC_DR); + } + while (tmp != dr); + + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time to fields in struct tm format. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tmp = (tr & (RTC_TR_SU_MASK | RTC_TR_ST_MASK)) >> RTC_TR_SU_SHIFT; + tp->tm_sec = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_MNU_MASK | RTC_TR_MNT_MASK)) >> RTC_TR_MNU_SHIFT; + tp->tm_min = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_HU_MASK | RTC_TR_HT_MASK)) >> RTC_TR_HU_SHIFT; + tp->tm_hour = rtc_bcd2bin(tmp); + + /* Now convert the RTC date to fields in struct tm format: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + tmp = (dr & (RTC_DR_DU_MASK | RTC_DR_DT_MASK)) >> RTC_DR_DU_SHIFT; + tp->tm_mday = rtc_bcd2bin(tmp); + + tmp = (dr & (RTC_DR_MU_MASK | RTC_DR_MT)) >> RTC_DR_MU_SHIFT; + tp->tm_mon = rtc_bcd2bin(tmp) - 1; + + tmp = (dr & (RTC_DR_YU_MASK | RTC_DR_YT_MASK)) >> RTC_DR_YU_SHIFT; + tp->tm_year = rtc_bcd2bin(tmp) + 100; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + tmp = (dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT; + tp->tm_wday = tmp % 7; + tp->tm_yday = tp->tm_mday + clock_daysbeforemonth(tp->tm_mon, clock_isleapyear(tp->tm_year + 1900)); + tp->tm_isdst = 0 +#endif + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS + /* Return RTC sub-seconds if no configured and if a non-NULL value + * of nsec has been provided to receive the sub-second value. + */ + + if (nsec) + { + uint32_t prediv_s; + uint32_t usecs; + + prediv_s = getreg32(STM32_RTC_PRER) & RTC_PRER_PREDIV_S_MASK; + prediv_s >>= RTC_PRER_PREDIV_S_SHIFT; + + ssr &= RTC_SSR_MASK; + + /* Maximum prediv_s is 0x7fff, thus we can multiply by 100000 and + * still fit 32-bit unsigned integer. + */ + + usecs = (((prediv_s - ssr) * 100000) / (prediv_s + 1)) * 10; + *nsec = usecs * 1000; + } +#endif /* CONFIG_STM32_HAVE_RTC_SUBSECONDS */ + + rtc_dumptime((FAR const struct tm *)tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int up_rtc_getdatetime(FAR struct tm *tp) +{ + return stm32_rtc_getdatetime_with_subseconds(tp, NULL); +} +#endif + +/************************************************************************************ + * Name: stm32_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this + * function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int stm32_rtc_setdatetime(FAR const struct tm *tp) +{ + uint32_t tr; + uint32_t dr; + int ret; + + rtc_dumptime(tp, "Setting time"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tr = (rtc_reg_tr_bin2bcd(tp) & ~RTC_TR_RESERVED_BITS); + + /* Now convert the fields in struct tm format to the RTC date register fields: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) | + ((rtc_bin2bcd(tp->tm_mon + 1)) << RTC_DR_MU_SHIFT) | +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + ((tp->tm_wday == 0 ? 7 : (tp->tm_wday & 7)) << RTC_DR_WDU_SHIFT) | +#endif + ((rtc_bin2bcd(tp->tm_year - 100)) << RTC_DR_YU_SHIFT); + + dr &= ~RTC_DR_RESERVED_BITS; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the RTC TR and DR registers */ + + putreg32(tr, STM32_RTC_TR); + putreg32(dr, STM32_RTC_DR); + + /* Exit Initialization mode and wait for the RTC Time and Date + * registers to be synchronized with RTC APB clock. + */ + + rtc_exitinit(); + ret = rtc_synchwait(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + rtc_dumpregs("New time setting"); + return ret; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + + /* Break out the time values (not that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + return stm32_rtc_setdatetime(&newtime); +} + +/**************************************************************************** + * Name: stm32_rtc_setalarm + * + * Description: + * Set an alarm to an asbolute time using associated hardware. + * + * Input Parameters: + * alminfo - Information about the alarm configuration. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo) +{ + FAR struct alm_cbinfo_s *cbinfo; + rtc_alarmreg_t alarmreg; + int ret = -EINVAL; + + ASSERT(alminfo != NULL); + DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id); + + /* REVISIT: Should test that the time is in the future */ + + rtc_dumptime(&alminfo->as_time, "New alarm time"); + + /* Break out the values to the HW alarm register format */ + + alarmreg = rtc_reg_alrmr_bin2bcd(&alminfo->as_time); + + /* Set the alarm in hardware and enable interrupts */ + + switch (alminfo->as_id) + { + case RTC_ALARMA: + { + cbinfo = &g_alarmcb[RTC_ALARMA]; + cbinfo->ac_cb = alminfo->as_cb; + cbinfo->ac_arg = alminfo->as_arg; + + ret = rtchw_set_alrmar(alarmreg | RTC_ALRMR_ENABLE); + if (ret < 0) + { + cbinfo->ac_cb = NULL; + cbinfo->ac_arg = NULL; + } + } + break; + + case RTC_ALARMB: + { + cbinfo = &g_alarmcb[RTC_ALARMB]; + cbinfo->ac_cb = alminfo->as_cb; + cbinfo->ac_arg = alminfo->as_arg; + + ret = rtchw_set_alrmbr(alarmreg | RTC_ALRMR_ENABLE); + if (ret < 0) + { + cbinfo->ac_cb = NULL; + cbinfo->ac_arg = NULL; + } + } + break; + + default: + rtcvdbg("ERROR: Invalid ALARM%d\n", alminfo->as_id); + break; + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_rtc_cancelalarm + * + * Description: + * Cancel an alaram. + * + * Input Parameters: + * alarmid - Identifies the alarm to be cancelled + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_rtc_cancelalarm(enum alm_id_e alarmid) +{ + int ret = -EINVAL; + + DEBUGASSERT(RTC_ALARM_LAST > alarmid); + + /* Cancel the alarm in hardware and disable interrupts */ + + switch (alarmid) + { + case RTC_ALARMA: + { + /* Cancel the global callback function */ + + g_alarmcb[alarmid].ac_cb = NULL; + g_alarmcb[alarmid].ac_arg = NULL; + + /* Need to follow RTC register wrote protection. + * Disable the write protection for RTC registers + */ + + rtc_wprunlock(); + + /* Disable RTC alarm and interrupt */ + + modifyreg32(STM32_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0); + + ret = rtchw_check_alrawf(); + if (ret < 0) + { + goto errout_with_wprunlock; + } + + /* Unset the alarm */ + + putreg32(-1, STM32_RTC_ALRMAR); + rtc_wprlock(); + ret = OK; + } + break; + + case RTC_ALARMB: + { + /* Cancel the global callback function */ + + g_alarmcb[alarmid].ac_cb = NULL; + g_alarmcb[alarmid].ac_arg = NULL; + + /* Need to follow RTC register wrote protection. + * Disable the write protection for RTC registers + */ + + rtc_wprunlock(); + + /* Disable RTC alarm and interrupt */ + + modifyreg32(STM32_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0); + + ret = rtchw_check_alrbwf(); + if (ret < 0) + { + goto errout_with_wprunlock; + } + + /* Unset the alarm */ + + putreg32(-1, STM32_RTC_ALRMBR); + rtc_wprlock(); + ret = OK; + } + break; + + default: + rtcvdbg("ERROR: Invalid ALARM%d\n", alminfo->as_id); + break; + } + + return ret; + +errout_with_wprunlock: + rtc_wprlock(); + return ret; +} +#endif + +#endif /* CONFIG_RTC */ diff --git a/arch/arm/src/stm32/stm32l15xxx_rcc.c b/arch/arm/src/stm32/stm32l15xxx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..51a163d99a1a4a9f712b702eb65821a49a1e613d --- /dev/null +++ b/arch/arm/src/stm32/stm32l15xxx_rcc.c @@ -0,0 +1,756 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32l15xxx_rcc.c + * For STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM- + * based 32-bit MCUs + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/* HSE divisor to yield ~1MHz RTC clock (valid for HSE = 8MHz) */ + +#define HSE_DIVISOR RCC_CR_RTCPRE_HSEd8 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Put all RCC registers in reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ +#if 0 /* None of this is necessary if only called from power up */ + uint32_t regval; + + /* Make sure that all devices are out of reset */ + + putreg32(0, STM32_RCC_AHBRSTR); /* Disable AHB Peripheral Reset */ + putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ + putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ + + /* Disable all clocking (other than to FLASH) */ + + putreg32(RCC_AHBENR_FLITFEN, STM32_RCC_AHBENR); /* FLITF Clock ON */ + putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ + putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ + + /* Set the Internal clock sources calibration register to its reset value. + * MSI to the default frequency (nominally 2.097MHz), MSITRIM=0, HSITRIM=0x10. + * Preserve the factory HSICAL and MSICAL settings. + */ + + regval = getreg32(STM32_RCC_ICSCR); + regval &= (RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK); + regval |= (RCC_ICSR_RSTVAL & ~(RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK)); + putreg32(regval, STM32_RCC_ICSCR); + + /* Enable the internal MSI */ + + regval = getreg32(STM32_RCC_CR); /* Enable the MSI */ + regval |= RCC_CR_MSION; + putreg32(regval, STM32_RCC_CR); + + /* Set the CFGR register to its reset value: Reset SW, HPRE, PPRE1, PPRE2, + * and MCO bits. Resetting SW selects the MSI clock as the system clock + * source. We do not clear PLL values yet because the PLL may be providing + * the SYSCLK and we want the PLL to be stable through the transition. + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | + RCC_CFGR_PPRE2_MASK | RCC_CFGR_MCOSEL_MASK | RCC_CFGR_MCOPRE_MASK); + putreg32(regval, STM32_RCC_CFGR); + + /* Make sure that the selected MSI source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_MSI); + + /* Now we can disable the alternative clock sources: HSE, HSI, PLL, CSS and RTCPRE. Also, + * reset the HSE bypass. This restores the RCC CR to its reset state. + */ + + regval = getreg32(STM32_RCC_CR); /* Disable the HSE and the PLL */ + regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_RTCPRE_MASK); + putreg32(regval, STM32_RCC_CR); + + regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + /* Now we can reset the CFGR PLL fields to their reset value */ + + regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLMUL, and PLLDIV bits */ + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK); + putreg32(regval, STM32_RCC_CFGR); + + /* Make sure that all interrupts are disabled */ + + putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ + + /* Go to the (default) voltage range 2 */ + + stm32_pwr_setvos(PWR_CR_VOS_SCALE_2); + + /* Reset the FLASH controller to 32-bit mode, no wait states. + * + * First, program the new number of WS to the LATENCY bit in Flash access + * control register (FLASH_ACR) + */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY; /* No wait states */ + putreg32(regval, STM32_FLASH_ACR); + + /* Check that the new number of WS is taken into account by reading FLASH_ACR */ + + /* Program the 32-bit access by clearing ACC64 in FLASH_ACR */ + + regval &= ~FLASH_ACR_ACC64; /* 32-bit access mode */ + putreg32(regval, STM32_FLASH_ACR); + + /* Check that 32-bit access is taken into account by reading FLASH_ACR */ +#endif +} + +/**************************************************************************** + * Name: rcc_enableahb + * + * Description: + * Enable selected AHB peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb(void) +{ + uint32_t regval; + + /* Always enable FLITF clock clock */ + + regval = RCC_AHBENR_FLITFEN; + + /* Enable GPIOA-E, H, F-G (not all parts have all ports) */ + + regval |= (RCC_AHBENR_GPIOPAEN | RCC_AHBENR_GPIOPBEN | RCC_AHBENR_GPIOPCEN | + RCC_AHBENR_GPIOPDEN | RCC_AHBENR_GPIOPEEN | RCC_AHBENR_GPIOPHEN | + RCC_AHBENR_GPIOPFEN | RCC_AHBENR_GPIOPGEN); + +#ifdef CONFIG_STM32_CRC + /* CRC clock enable */ + + regval |= RCC_AHBENR_CRCEN; +#endif + +#ifdef CONFIG_STM32_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHBENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHBENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32_AES + /* AES clock enable */ + + regval |= RCC_AHBENR_AESEN; +#endif + +#ifdef CONFIG_STM32_FSMC + /* FSMC clock enable */ + + regval |= RCC_AHBENR_FSMCEN; +#endif + + putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32_TIM2 + /* Timer 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM2EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM3 + /* Timer 3 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM3EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM4 + /* Timer 4 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM4EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM5 + /* Timer 5 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM5EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM6 + /* Timer 6 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM6EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM7 + /* Timer 7 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_TIM7EN; +#endif +#endif + +#ifdef CONFIG_STM32_LCD + /* LCD clock enable */ + + regval |= RCC_APB1ENR_LCDEN; +#endif + +#ifdef CONFIG_STM32_WWDG + /* Window Watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32_SPI2 + /* SPI 2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32_SPI3 + /* SPI 3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32_USART2 + /* USART 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_USART2EN; +#endif +#endif + +#ifdef CONFIG_STM32_USART3 + /* USART 3 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_USART3EN; +#endif +#endif + +#ifdef CONFIG_STM32_UART4 + /* USART 4 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_UART4EN; +#endif +#endif + +#ifdef CONFIG_STM32_UART5 + /* USART 5 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_UART5EN; +#endif +#endif + +#ifdef CONFIG_STM32_I2C1 + /* I2C 1 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C1EN; +#endif +#endif + +#ifdef CONFIG_STM32_I2C2 + /* I2C 2 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB1ENR_I2C2EN; +#endif +#endif + +#ifdef CONFIG_STM32_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + +#ifdef CONFIG_STM32_PWR + /* Power interface clock enable */ + + regval |= RCC_APB1ENR_PWREN; +#endif + +#ifdef CONFIG_STM32_DAC + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + +#ifdef CONFIG_STM32_COMP + /* COMP interface clock enable */ + + regval |= RCC_APB1ENR_COMPEN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32_SYSCFG + /* SYSCFG clock */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32_TIM9 + /* TIM9 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM9EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM10 + /* TIM10 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM10EN; +#endif +#endif + +#ifdef CONFIG_STM32_TIM11 + /* TIM11 Timer clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_TIM11EN; +#endif +#endif + +#ifdef CONFIG_STM32_ADC1 + /* ADC 1 clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + +#ifdef CONFIG_STM32_SDIO + /* SDIO clock enable */ + + regval |= RCC_APB2ENR_SDIOEN; +#endif + +#ifdef CONFIG_STM32_SPI1 + /* SPI 1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32_USART1 + /* USART1 clock enable */ + +#ifdef CONFIG_STM32_FORCEPOWER + regval |= RCC_APB2ENR_USART1EN; +#endif +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: stm32_rcc_enablehse + * + * Description: + * Enable the External High-Speed (HSE) Oscillator. + * + ****************************************************************************/ + +#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) +static inline bool stm32_rcc_enablehse(void) +{ + uint32_t regval; + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then return TRUE */ + + return true; + } + } + + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or misconfiguration. + */ + + return false; +} +#endif + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes or any clocking other than PLL driven by the HSE. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG +static void stm32_stdclockconfig(void) +{ + uint32_t regval; +#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK) + uint16_t pwrcr; +#endif + + /* Enable PWR clock from APB1 to give access to PWR_CR register */ + + regval = getreg32(STM32_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32_RCC_APB1ENR); + + /* Go to the high performance voltage range 1 if necessary. In this mode, + * the PLL VCO frequency can be up to 96MHz. USB and SDIO can be supported. + * + * Range 1: PLLVCO up to 96MHz in range 1 (1.8V) + * Range 2: PLLVCO up to 48MHz in range 2 (1.5V) (default) + * Range 3: PLLVCO up to 24MHz in range 3 (1.2V) + */ + +#if STM32_PLL_FREQUENCY > 48000000 + stm32_pwr_setvos(PWR_CR_VOS_SCALE_1); +#endif + +#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK) + /* If RTC / LCD selects HSE as clock source, the RTC prescaler + * needs to be set before HSEON bit is set. + */ + + /* The RTC domain has write access denied after reset, + * you have to enable write access using DBP bit in the PWR CR + * register before to selecting the clock source ( and the PWR + * peripheral must be enabled) + */ + + regval = getreg32(STM32_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32_RCC_APB1ENR); + + pwrcr = getreg16(STM32_PWR_CR); + putreg16(pwrcr | PWR_CR_DBP, STM32_PWR_CR); + + /* Set the RTC clock divisor */ + + regval = getreg32(STM32_RCC_CSR); + regval &= ~RCC_CSR_RTCSEL_MASK; + regval |= RCC_CSR_RTCSEL_HSE; + putreg32(regval, STM32_RCC_CSR); + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_RTCPRE_MASK; + regval |= HSE_DIVISOR; + putreg32(regval, STM32_RCC_CR); + + /* Restore the previous state of the DBP bit */ + + putreg32(regval, STM32_PWR_CR); + +#endif + + /* Enable the source clock for the PLL (via HSE or HSI), HSE, and HSI. + * NOTE that only PLL, HSE, or HSI are supported for the system clock + * in this implementation + */ + +#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) + /* The PLL is using the HSE, or the HSE is the system clock. In either + * case, we need to enable HSE clocking. + */ + + if (!stm32_rcc_enablehse()) + { + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or + * misconfiguration (for example, if no crystal is fitted on the board. + */ + + return; + } + +#elif (STM32_CFGR_PLLSRC == 0) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSI) + /* The PLL is using the HSI, or the HSI is the system clock. In either + * case, we need to enable HSI clocking. + */ + + regval = getreg32(STM32_RCC_CR); /* Enable the HSI */ + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSI clock is ready. Since this is an internal clock, no + * timeout is expected + */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0); + +#endif + + /* Increasing the CPU frequency (in the same voltage range): + * + * After reset, the used clock is the MSI (2 MHz) with 0 WS configured in the + * FLASH_ACR register. 32-bit access is enabled and prefetch is disabled. + * ST strongly recommends to use the following software sequences to tune the + * number of wait states needed to access the Flash memory with the CPU + * frequency. + * + * - Program the 64-bit access by setting the ACC64 bit in Flash access + * control register (FLASH_ACR) + * - Check that 64-bit access is taken into account by reading FLASH_ACR + * - Program 1 WS to the LATENCY bit in FLASH_ACR + * - Check that the new number of WS is taken into account by reading FLASH_ACR + * - Modify the CPU clock source by writing to the SW bits in the Clock + * configuration register (RCC_CFGR) + * - If needed, modify the CPU clock prescaler by writing to the HPRE bits in + * RCC_CFGR + * - Check that the new CPU clock source or/and the new CPU clock prescaler + * value is/are taken into account by reading the clock source status (SWS + * bits) or/and the AHB prescaler value (HPRE bits), respectively, in the + * RCC_CFGR register + */ + + regval = getreg32(STM32_FLASH_ACR); + regval |= FLASH_ACR_ACC64; /* 64-bit access mode */ + putreg32(regval, STM32_FLASH_ACR); + + regval |= FLASH_ACR_LATENCY; /* One wait state */ + putreg32(regval, STM32_FLASH_ACR); + + /* Enable FLASH prefetch */ + + regval |= FLASH_ACR_PRFTEN; + putreg32(regval, STM32_FLASH_ACR); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + + /* If we are using the PLL, configure and start it */ + +#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL + + /* Set the PLL divider and multiplier. NOTE: The PLL needs to be disabled + * to do these operation. We know this is the case here because pll_reset() + * was previously called by stm32_clockconfig(). + */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK); + regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLMUL | STM32_CFGR_PLLDIV); + putreg32(regval, STM32_RCC_CFGR); + + /* Enable the PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); + +#endif + + /* Select the system clock source (probably the PLL) */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= STM32_SYSCLK_SW; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the selected source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); + +#if defined(CONFIG_STM32_IWDG) || \ + defined(CONFIG_RTC_LSICLOCK) || defined(CONFIG_LCD_LSICLOCK) + /* Low speed internal clock source LSI + * + * TODO: There is another case where the LSI needs to + * be enabled: if the MCO pin selects LSI as source. + */ + + stm32_rcc_enablelsi(); + +#endif + +#if defined(CONFIG_RTC_LSECLOCK) || defined(CONFIG_LCD_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO pin selects LSE as source. + * + * TODO: There is another case where the LSE needs to + * be enabled: if TIM9-10 Channel 1 selects LSE as input. + * + * TODO: There is another case where the LSE needs to + * be enabled: if TIM10-11 selects LSE as ETR Input. + * + */ + + stm32_rcc_enablelse(); +#endif +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb(); + rcc_enableapb2(); + rcc_enableapb1(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d31b3a6ea54eab643222bde174335e17dcf48254 --- /dev/null +++ b/arch/arm/src/stm32f7/Kconfig @@ -0,0 +1,647 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_STM32F7 + +comment "STM32 F7 Configuration Options" + +choice + prompt "STM32 F7 Chip Selection" + default ARCH_CHIP_STM32F746 + depends on ARCH_CHIP_STM32F7 + +config ARCH_CHIP_STM32F745 + bool "STM32F745xx" + select STM32F7_STM32F74XX + ---help--- + STM32 F7 Cortex M7, 512 or 1024Kb FLASH, 335 (240++16+54) Kb SRAM + +config ARCH_CHIP_STM32F746 + bool "STM32F746xx" + select STM32F7_STM32F74XX + select STM32F7_HAVE_LTDC + ---help--- + STM32 F7 Cortex M7, 512 or 1024Kb FLASH, 335 (240++16+54) Kb SRAM + +config ARCH_CHIP_STM32F756 + bool "STM32F756xx" + select STM32F7_STM32F75XX + select STM32F7_HAVE_LTDC + ---help--- + STM32 F7 Cortex M7, 512 or 1024Kb FLASH, 335 (240++16+54) Kb SRAM + +endchoice # STM32 F7 Chip Selection + +config STM32F7_STM32F74XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +config STM32F7_STM32F75XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +choice + prompt "Embedded FLASH size" + default STM32F7_FLASH_1024KB + +config STM32F7_FLASH_512KB + bool "512 KB" + +config STM32F7_FLASH_1024KB + bool "1024 KB" + +endchoice # Embedded FLASH size + +menu "STM32 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config STM32F7_HAVE_LTDC + bool + default n + +# These "hidden" settings are the OR of individual peripheral selections +# indicating that the general capabilitiy is required. + +config STM32F7_ADC + bool + default n + +config STM32F7_CAN + bool + default n + +config STM32F7_DAC + bool + default n + +config STM32F7_DMA + bool + default n + +config STM32F7_I2C + bool + default n + +config STM32F7_SAI + bool + default n + +config STM32F7_SPI + bool + default n + +config STM32F7_USART + bool + default n + +# These are the peripheral selections proper + +config STM32F7_ADC1 + bool "ADC1" + default n + select STM32F7_ADC + +config STM32F7_ADC2 + bool "ADC2" + default n + select STM32F7_ADC + +config STM32F7_ADC3 + bool "ADC3" + default n + select STM32F7_ADC + +config STM32F7_BKPSRAM + bool "Enable BKP RAM Domain" + default n + +config STM32F7_CAN1 + bool "CAN1" + default n + select CAN + select STM32F7_CAN + +config STM32F7_CAN2 + bool "CAN2" + default n + select CAN + select STM32F7_CAN + +config STM32F7_CEC + bool "CEC" + default n + depends on STM32F7_VALUELINE + +config STM32F7_CRC + bool "CRC" + default n + +config STM32F7_CRYP + bool "CRYP" + default n + +config STM32F7_DMA1 + bool "DMA1" + default n + select STM32F7_DMA + select ARCH_DMA + +config STM32F7_DMA2 + bool "DMA2" + default n + select STM32F7_DMA + select ARCH_DMA + +config STM32F7_DAC1 + bool "DAC1" + default n + select STM32F7_DAC + +config STM32F7_DAC2 + bool "DAC2" + default n + select STM32F7_DAC + +config STM32F7_DCMI + bool "DCMI" + default n + +config STM32F7_ETHMAC + bool "Ethernet MAC" + default n + select NETDEVICES + select ARCH_HAVE_PHY + +config STM32F7_FSMC + bool "FSMC" + default n + +config STM32F7_I2C1 + bool "I2C1" + default n + select STM32F7_I2C + +config STM32F7_CEC + bool "HDMI-CEC" + default n + +config STM32F7_I2C2 + bool "I2C2" + default n + select STM32F7_I2C + +config STM32F7_I2C3 + bool "I2C3" + default n + select STM32F7_I2C + +config STM32F7_LPTIM1 + bool "Low-power timer 1" + default n + +config STM32F7_LTDC + bool "LTDC" + default n + depends on STM32F7_HAVE_LTDC + ---help--- + The STM32 LTDC is an LCD-TFT Display Controller available on + the STM32F429 and STM32F439 devices. It is a standard parallel + video interface (HSYNC, VSYNC, etc.) for controlling TFT + LCD displays. + +config STM32F7_DMA2D + bool "DMA2D" + default n + ---help--- + The STM32 DMA2D is an Chrom-Art Accelerator for image manipulation + available on the STM32 F7 devices. + +config STM32F7_OTGFS + bool "OTG FS" + default n + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32F7_OTGHS + bool "OTG HS" + default n + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32F7_QUADSPI + bool "QuadSPI" + default n + +config STM32F7_SAI1 +config STM32F7_RNG + bool "RNG" + default n + select ARCH_HAVE_RNG + +config STM32F7_SAI1 + bool "SAI1" + default n + select STM32F7_SAI + +config STM32F7_SAI2 + bool "SAI2" + default n + select STM32F7_SAI + +config STM32F7_SDMMC1 + bool "SDMMC1" + default n + select ARCH_HAVE_SDIO + +config STM32F7_SPDIFRX + bool "SPDIFRX" + default n + +config STM32F7_SPI1 + bool "SPI1" + default n + select SPI + select STM32F7_SPI + +config STM32F7_SPI2 + bool "SPI2" + default n + select SPI + select STM32F7_SPI + +config STM32F7_SPI3 + bool "SPI3" + default n + select SPI + select STM32F7_SPI + +config STM32F7_SPI4 + bool "SPI4" + default n + select SPI + select STM32F7_SPI + +config STM32F7_SPI5 + bool "SPI5" + default n + select SPI + select STM32F7_SPI + +config STM32F7_SPI6 + bool "SPI6" + default n + select SPI + select STM32F7_SPI + +config STM32F7_TIM1 + bool "TIM1" + default n + +config STM32F7_TIM2 + bool "TIM2" + default n + +config STM32F7_TIM3 + bool "TIM3" + default n + +config STM32F7_TIM4 + bool "TIM4" + default n + +config STM32F7_TIM5 + bool "TIM5" + default n + +config STM32F7_TIM6 + bool "TIM6" + default n + +config STM32F7_TIM7 + bool "TIM7" + default n + +config STM32F7_TIM8 + bool "TIM8" + default n + +config STM32F7_TIM9 + bool "TIM9" + default n + +config STM32F7_TIM10 + bool "TIM10" + default n + +config STM32F7_TIM11 + bool "TIM11" + default n + +config STM32F7_TIM12 + bool "TIM12" + default n + +config STM32F7_TIM13 + bool "TIM13" + default n + +config STM32F7_TIM14 + bool "TIM14" + default n + +config STM32F7_TIM15 + bool "TIM15" + default n + +config STM32F7_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32F7_USART + +config STM32F7_USART2 + bool "USART2" + default n + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32F7_USART + +config STM32F7_USART3 + bool "USART3" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART3 + select STM32F7_USART + +config STM32F7_UART4 + bool "UART4" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART4 + select STM32F7_USART + +config STM32F7_UART5 + bool "UART5" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART5 + select STM32F7_USART + +config STM32F7_USART6 + bool "USART6" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART6 + select STM32F7_USART + +config STM32F7_UART7 + bool "UART7" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART7 + select STM32F7_USART + +config STM32F7_UART8 + bool "UART8" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART8 + select STM32F7_USART + +config STM32F7_IWDG + bool "IWDG" + default n + select WATCHDOG + +config STM32F7_WWDG + bool "WWDG" + default n + select WATCHDOG + +endmenu + +config STM32F7_CUSTOM_CLOCKCONFIG + bool "Custom clock configuration" + default n + ---help--- + Enables special, board-specific STM32 clock configuration. + +config STM32F7_DTCM_PROCFS + bool "DTCM SRAM PROCFS support" + default n + depends on ARMV7M_DTCM && FS_PROCFS + ---help--- + Select to build in support for /proc/dtcm. Reading from /proc/dtcm + will provide statistics about DTCM memory use similar to what you + would get from mallinfo() for the user heap. + +if STM32F7_ETHMAC +menu "Ethernet MAC configuration" + +config STM32F7_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +config STM32F7_PHYINIT + bool "Board-specific PHY Initialization" + default n + ---help--- + Some boards require specialized initialization of the PHY before it can be used. + This may include such things as configuring GPIOs, resetting the PHY, etc. If + STM32F7_PHYINIT is defined in the configuration then the board specific logic must + provide stm32_phyinitialize(); The STM32 Ethernet driver will call this function + one time before it first uses the PHY. + +config STM32F7_MII + bool "Use MII interface" + default n + ---help--- + Support Ethernet MII interface. + +choice + prompt "MII clock configuration" + default STM32F7_MII_EXTCLK + depends on STM32F7_MII + +config STM32F7_MII_MCO1 + bool "Use MC01 as MII clock" + ---help--- + Use MCO1 to clock the MII interface. + +config STM32F7_MII_MCO2 + bool "Use MC02 as MII clock" + ---help--- + Use MCO2 to clock the MII interface. + +config STM32F7_MII_EXTCLK + bool "External MII clock" + ---help--- + Clocking is provided by external logic. + +endchoice + +config STM32F7_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +config STM32F7_ETHFD + bool "Full duplex" + default n + depends on !STM32F7_AUTONEG + ---help--- + If STM32F7_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config STM32F7_ETH100MBPS + bool "100 Mbps" + default n + depends on !STM32F7_AUTONEG + ---help--- + If STM32F7_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +config STM32F7_PHYSR + int "PHY Status Register Address (decimal)" + depends on STM32F7_AUTONEG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config STM32F7_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + depends on STM32F7_AUTONEG + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +config STM32F7_PHYSR_SPEED + hex "PHY Speed Mask" + depends on STM32F7_AUTONEG && !STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config STM32F7_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + depends on STM32F7_AUTONEG && !STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config STM32F7_PHYSR_MODE + hex "PHY Mode Mask" + depends on STM32F7_AUTONEG && !STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config STM32F7_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + depends on STM32F7_AUTONEG && !STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +config STM32F7_PHYSR_ALTMODE + hex "PHY Mode Mask" + depends on STM32F7_AUTONEG && STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config STM32F7_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + depends on STM32F7_AUTONEG && STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config STM32F7_PHYSR_100HD + hex "100Base-T Half Duplex Value" + depends on STM32F7_AUTONEG && STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config STM32F7_PHYSR_10FD + hex "10Base-T Full Duplex Value" + depends on STM32F7_AUTONEG && STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config STM32F7_PHYSR_100FD + hex "100Base-T Full Duplex Value" + depends on STM32F7_AUTONEG && STM32F7_PHYSR_ALTCONFIG + ---help--- + This must be provided if STM32F7_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +config STM32F7_ETH_PTP + bool "Precision Time Protocol (PTP)" + default n + ---help--- + Precision Time Protocol (PTP). Not supported but some hooks are indicated + with this condition. + +config STM32F7_RMII + bool + default y if !STM32F7_MII + +choice + prompt "RMII clock configuration" + default STM32F7_RMII_EXTCLK + depends on STM32F7_RMII + +config STM32F7_RMII_MCO1 + bool "Use MC01 as RMII clock" + ---help--- + Use MCO1 to clock the RMII interface. + +config STM32F7_RMII_MCO2 + bool "Use MC02 as RMII clock" + ---help--- + Use MCO2 to clock the RMII interface. + +config STM32F7_RMII_EXTCLK + bool "External RMII clock" + ---help--- + Clocking is provided by external logic. + +endchoice + +config STM32F7_ETHMAC_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu +endif # STM32F7_ETHMAC +endif # ARCH_CHIP_STM32F7 diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..2f4b7b251346b339b59bece843d3292169b8f3e7 --- /dev/null +++ b/arch/arm/src/stm32f7/Make.defs @@ -0,0 +1,154 @@ +############################################################################ +# arch/arm/src/stm32f7/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file. Only common vectors are support so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M7 files + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_memfault.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_vfork.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARMV7M_DCACHE),y) +CMN_CSRCS += arch_enable_dcache.c arch_disable_dcache.c +CMN_CSRCS += arch_invalidate_dcache.c arch_invalidate_dcache_all.c +ifneq ($(CONFIG_ARMV7M_DCACHE_WRITETHROUGH),y) +CMN_CSRCS += arch_clean_dcache.c arch_clean_dcache_all.c +CMN_CSRCS += arch_flush_dcache.c arch_flush_dcache_all.c +endif +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Required STM32F7 files + +CHIP_ASRCS = +CHIP_CSRCS = stm32_allocateheap.c stm32_exti_gpio.c stm32_gpio.c +CHIP_CSRCS += stm32_irq.c stm32_lowputc.c stm32_rcc.c stm32_serial.c +CHIP_CSRCS += stm32_start.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += stm32_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c +endif + +ifeq ($(CONFIG_ARMV7M_DTCM),y) +CHIP_CSRCS += stm32_dtcm.c +ifeq ($(CONFIG_STM32F7_DTCM_PROCFS),y) +CHIP_CSRCS += stm32_procfs_dtcm.c +endif +endif + +ifeq ($(CONFIG_STM32F7_DMA),y) +CHIP_CSRCS += stm32_dma.c +endif + +ifeq ($(CONFIG_STM32_PWR),y) +CHIP_CSRCS += stm32_exti_pwr.c +endif + +ifeq ($(CONFIG_RTC),y) +ifeq ($(CONFIG_RTC_ALARM),y) +CHIP_CSRCS += stm32_exti_alarm.c +endif +endif + +ifeq ($(CONFIG_STM32F7_ETHMAC),y) +CHIP_CSRCS += stm32_ethernet.c +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += stm32_dumpgpio.c +endif diff --git a/arch/arm/src/stm32f7/chip.h b/arch/arm/src/stm32f7/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..536b8e001071e25e8cbe4654faa9eac4baabfbef --- /dev/null +++ b/arch/arm/src/stm32f7/chip.h @@ -0,0 +1,82 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include +#include "chip/stm32_memorymap.h" + +/* If the common ARMv7-M vector handling logic is used, then it expects the + * following definition in this file that provides the number of supported external + * interrupts which, for this architecture, is provided in the arch/stm32f7/chip.h + * header file. + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS NR_INTERRUPTS + +/* Cache line sizes (in bytes)for the STM32F7 */ + +#define ARMV7M_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7M_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_dma.h b/arch/arm/src/stm32f7/chip/stm32_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..63db15ec9f3e32119711fb5586788ee74ec6e134 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_dma.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_dma.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DMA_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_dma.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DMA_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_ethernet.h b/arch/arm/src/stm32f7/chip/stm32_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..e5fc6982d2859f9ada3083f35f53fcc484e11962 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_ethernet.h @@ -0,0 +1,810 @@ +/**************************************************************************************************** + * arch/arm/src/stm32f7/chip/stm32_ethernet.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_ETHERNET_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_ETHERNET_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ +/* MAC Registers */ + +#define STM32_ETH_MACCR_OFFSET 0x0000 /* Ethernet MAC configuration register */ +#define STM32_ETH_MACFFR_OFFSET 0x0004 /* Ethernet MAC frame filter register */ +#define STM32_ETH_MACHTHR_OFFSET 0x0008 /* Ethernet MAC hash table high register */ +#define STM32_ETH_MACHTLR_OFFSET 0x000c /* Ethernet MAC hash table low register */ +#define STM32_ETH_MACMIIAR_OFFSET 0x0010 /* Ethernet MAC MII address register */ +#define STM32_ETH_MACMIIDR_OFFSET 0x0014 /* Ethernet MAC MII data register */ +#define STM32_ETH_MACFCR_OFFSET 0x0018 /* Ethernet MAC flow control register */ +#define STM32_ETH_MACVLANTR_OFFSET 0x001c /* Ethernet MAC VLAN tag register */ +#define STM32_ETH_MACRWUFFR_OFFSET 0x0028 /* Ethernet MAC remote wakeup frame filter reg */ +#define STM32_ETH_MACPMTCSR_OFFSET 0x002c /* Ethernet MAC PMT control and status register */ +#define STM32_ETH_MACDBGR_OFFSET 0x0034 /* Ethernet MAC debug register */ +#define STM32_ETH_MACSR_OFFSET 0x0038 /* Ethernet MAC interrupt status register */ +#define STM32_ETH_MACIMR_OFFSET 0x003c /* Ethernet MAC interrupt mask register */ +#define STM32_ETH_MACA0HR_OFFSET 0x0040 /* Ethernet MAC address 0 high register */ +#define STM32_ETH_MACA0LR_OFFSET 0x0044 /* Ethernet MAC address 0 low register */ +#define STM32_ETH_MACA1HR_OFFSET 0x0048 /* Ethernet MAC address 1 high register */ +#define STM32_ETH_MACA1LR_OFFSET 0x004c /* Ethernet MAC address1 low register */ +#define STM32_ETH_MACA2HR_OFFSET 0x0050 /* Ethernet MAC address 2 high register */ +#define STM32_ETH_MACA2LR_OFFSET 0x0054 /* Ethernet MAC address 2 low register */ +#define STM32_ETH_MACA3HR_OFFSET 0x0058 /* Ethernet MAC address 3 high register */ +#define STM32_ETH_MACA3LR_OFFSET 0x005c /* Ethernet MAC address 3 low register */ + +/* MMC Registers */ + +#define STM32_ETH_MMCCR_OFFSET 0x0100 /* Ethernet MMC control register */ +#define STM32_ETH_MMCRIR_OFFSET 0x0104 /* Ethernet MMC receive interrupt register */ +#define STM32_ETH_MMCTIR_OFFSET 0x0108 /* Ethernet MMC transmit interrupt register */ +#define STM32_ETH_MMCRIMR_OFFSET 0x010c /* Ethernet MMC receive interrupt mask register */ +#define STM32_ETH_MMCTIMR_OFFSET 0x0110 /* Ethernet MMC transmit interrupt mask register */ +#define STM32_ETH_MMCTGFSCCR_OFFSET 0x014c /* Ethernet MMC transmitted good frames counter register (single collision) */ +#define STM32_ETH_MMCTGFMSCCR_OFFSET 0x0150 /* Ethernet MMC transmitted good frames counter register (multiple-collision) */ +#define STM32_ETH_MMCTGFCR_OFFSET 0x0168 /* Ethernet MMC transmitted good frames counter register */ +#define STM32_ETH_MMCRFCECR_OFFSET 0x0194 /* Ethernet MMC received frames with CRC error counter register */ +#define STM32_ETH_MMCRFAECR_OFFSET 0x0198 /* Ethernet MMC received frames with alignment error counter */ +#define STM32_ETH_MMCRGUFCR_OFFSET 0x01c4 /* MMC received good unicast frames counter register */ + +/* IEEE 1588 time stamp registers */ + +#define STM32_ETH_PTPTSCR_OFFSET 0x0700 /* Ethernet PTP time stamp control register */ +#define STM32_ETH_PTPSSIR_OFFSET 0x0704 /* Ethernet PTP subsecond increment register */ +#define STM32_ETH_PTPTSHR_OFFSET 0x0708 /* Ethernet PTP time stamp high register */ +#define STM32_ETH_PTPTSLR_OFFSET 0x070c /* Ethernet PTP time stamp low register */ +#define STM32_ETH_PTPTSHUR_OFFSET 0x0710 /* Ethernet PTP time stamp high update register */ +#define STM32_ETH_PTPTSLUR_OFFSET 0x0714 /* Ethernet PTP time stamp low update register */ +#define STM32_ETH_PTPTSAR_OFFSET 0x0718 /* Ethernet PTP time stamp addend register */ +#define STM32_ETH_PTPTTHR_OFFSET 0x071c /* Ethernet PTP target time high register */ +#define STM32_ETH_PTPTTLR_OFFSET 0x0720 /* Ethernet PTP target time low register */ +#define STM32_ETH_PTPTSSR_OFFSET 0x0728 /* Ethernet PTP time stamp status register */ + +/* DMA Registers */ + +#define STM32_ETH_DMABMR_OFFSET 0x1000 /* Ethernet DMA bus mode register */ +#define STM32_ETH_DMATPDR_OFFSET 0x1004 /* Ethernet DMA transmit poll demand register */ +#define STM32_ETH_DMARPDR_OFFSET 0x1008 /* Ethernet DMA receive poll demand register */ +#define STM32_ETH_DMARDLAR_OFFSET 0x100c /* Ethernet DMA receive descriptor list address register */ +#define STM32_ETH_DMATDLAR_OFFSET 0x1010 /* Ethernet DMA transmit descriptor list address register */ +#define STM32_ETH_DMASR_OFFSET 0x1014 /* Ethernet DMA status register */ +#define STM32_ETH_DMAOMR_OFFSET 0x1018 /* Ethernet DMA operation mode register */ +#define STM32_ETH_DMAIER_OFFSET 0x101c /* Ethernet DMA interrupt enable register */ +#define STM32_ETH_DMAMFBOC_OFFSET 0x1020 /* Ethernet DMA missed frame and buffer overflow counter register */ +#define STM32_ETH_DMARSWTR_OFFSET 0x1024 /* Ethernet DMA receive status watchdog timer register */ +#define STM32_ETH_DMACHTDR_OFFSET 0x1048 /* Ethernet DMA current host transmit descriptor register */ +#define STM32_ETH_DMACHRDR_OFFSET 0x104c /* Ethernet DMA current host receive descriptor register */ +#define STM32_ETH_DMACHTBAR_OFFSET 0x1050 /* Ethernet DMA current host transmit buffer address register */ +#define STM32_ETH_DMACHRBAR_OFFSET 0x1054 /* Ethernet DMA current host receive buffer address register */ + +/* Register Base Addresses **************************************************************************/ +/* MAC Registers */ + +#define STM32_ETH_MACCR (STM32_ETHMAC_BASE+STM32_ETH_MACCR_OFFSET) +#define STM32_ETH_MACFFR (STM32_ETHMAC_BASE+STM32_ETH_MACFFR_OFFSET) +#define STM32_ETH_MACHTHR (STM32_ETHMAC_BASE+STM32_ETH_MACHTHR_OFFSET) +#define STM32_ETH_MACHTLR (STM32_ETHMAC_BASE+STM32_ETH_MACHTLR_OFFSET) +#define STM32_ETH_MACMIIAR (STM32_ETHMAC_BASE+STM32_ETH_MACMIIAR_OFFSET) +#define STM32_ETH_MACMIIDR (STM32_ETHMAC_BASE+STM32_ETH_MACMIIDR_OFFSET) +#define STM32_ETH_MACFCR (STM32_ETHMAC_BASE+STM32_ETH_MACFCR_OFFSET) +#define STM32_ETH_MACVLANTR (STM32_ETHMAC_BASE+STM32_ETH_MACVLANTR_OFFSET) +#define STM32_ETH_MACRWUFFR (STM32_ETHMAC_BASE+STM32_ETH_MACRWUFFR_OFFSET) +#define STM32_ETH_MACPMTCSR (STM32_ETHMAC_BASE+STM32_ETH_MACPMTCSR_OFFSET) +#define STM32_ETH_MACDBGR (STM32_ETHMAC_BASE+STM32_ETH_MACDBGR_OFFSET) +#define STM32_ETH_MACSR (STM32_ETHMAC_BASE+STM32_ETH_MACSR_OFFSET) +#define STM32_ETH_MACIMR (STM32_ETHMAC_BASE+STM32_ETH_MACIMR_OFFSET) +#define STM32_ETH_MACA0HR (STM32_ETHMAC_BASE+STM32_ETH_MACA0HR_OFFSET) +#define STM32_ETH_MACA0LR (STM32_ETHMAC_BASE+STM32_ETH_MACA0LR_OFFSET) +#define STM32_ETH_MACA1HR (STM32_ETHMAC_BASE+STM32_ETH_MACA1HR_OFFSET) +#define STM32_ETH_MACA1LR (STM32_ETHMAC_BASE+STM32_ETH_MACA1LR_OFFSET) +#define STM32_ETH_MACA2HR (STM32_ETHMAC_BASE+STM32_ETH_MACA2HR_OFFSET) +#define STM32_ETH_MACA2LR (STM32_ETHMAC_BASE+STM32_ETH_MACA2LR_OFFSET) +#define STM32_ETH_MACA3HR (STM32_ETHMAC_BASE+STM32_ETH_MACA3HR_OFFSET) +#define STM32_ETH_MACA3LR (STM32_ETHMAC_BASE+STM32_ETH_MACA3LR_OFFSET) + +/* MMC Registers */ + +#define STM32_ETH_MMCC (STM32_ETHMAC_BASE+STM32_ETH_MMCCR_OFFSET) +#define STM32_ETH_MMCRIR (STM32_ETHMAC_BASE+STM32_ETH_MMCRIR_OFFSET) +#define STM32_ETH_MMCTIR (STM32_ETHMAC_BASE+STM32_ETH_MMCTIR_OFFSET) +#define STM32_ETH_MMCRIMR (STM32_ETHMAC_BASE+STM32_ETH_MMCRIMR_OFFSET) +#define STM32_ETH_MMCTIMR (STM32_ETHMAC_BASE+STM32_ETH_MMCTIMR_OFFSET) +#define STM32_ETH_MMCTGFSCCR (STM32_ETHMAC_BASE+STM32_ETH_MMCTGFSCCR_OFFSET) +#define STM32_ETH_MMCTGFMSCCR (STM32_ETHMAC_BASE+STM32_ETH_MMCTGFMSCCR_OFFSET) +#define STM32_ETH_MMCTGFCR (STM32_ETHMAC_BASE+STM32_ETH_MMCTGFCR_OFFSET) +#define STM32_ETH_MMCRFCECR (STM32_ETHMAC_BASE+STM32_ETH_MMCRFCECR_OFFSET) +#define STM32_ETH_MMCRFAECR (STM32_ETHMAC_BASE+STM32_ETH_MMCRFAECR_OFFSET) +#define STM32_ETH_MMCRGUFCR (STM32_ETHMAC_BASE+STM32_ETH_MMCRGUFCR_OFFSET) + +/* IEEE 1588 time stamp registers */ + +#define STM32_ETH_PTPTSCR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSCR_OFFSET) +#define STM32_ETH_PTPSSIR (STM32_ETHMAC_BASE+STM32_ETH_PTPSSIR_OFFSET) +#define STM32_ETH_PTPTSHR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSHR_OFFSET) +#define STM32_ETH_PTPTSLR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSLR_OFFSET) +#define STM32_ETH_PTPTSHUR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSHUR_OFFSET) +#define STM32_ETH_PTPTSLUR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSLUR_OFFSET) +#define STM32_ETH_PTPTSAR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSAR_OFFSET) +#define STM32_ETH_PTPTTHR (STM32_ETHMAC_BASE+STM32_ETH_PTPTTHR_OFFSET) +#define STM32_ETH_PTPTTLR (STM32_ETHMAC_BASE+STM32_ETH_PTPTTLR_OFFSET) +#define STM32_ETH_PTPTSSR (STM32_ETHMAC_BASE+STM32_ETH_PTPTSSR_OFFSET) + +/* DMA Registers */ + +#define STM32_ETH_DMABMR (STM32_ETHMAC_BASE+STM32_ETH_DMABMR_OFFSET) +#define STM32_ETH_DMATPDR (STM32_ETHMAC_BASE+STM32_ETH_DMATPDR_OFFSET) +#define STM32_ETH_DMARPDR (STM32_ETHMAC_BASE+STM32_ETH_DMARPDR_OFFSET) +#define STM32_ETH_DMARDLAR (STM32_ETHMAC_BASE+STM32_ETH_DMARDLAR_OFFSET) +#define STM32_ETH_DMATDLAR (STM32_ETHMAC_BASE+STM32_ETH_DMATDLAR_OFFSET) +#define STM32_ETH_DMASR (STM32_ETHMAC_BASE+STM32_ETH_DMASR_OFFSET) +#define STM32_ETH_DMAOMR (STM32_ETHMAC_BASE+STM32_ETH_DMAOMR_OFFSET) +#define STM32_ETH_DMAIER (STM32_ETHMAC_BASE+STM32_ETH_DMAIER_OFFSET) +#define STM32_ETH_DMAMFBOC (STM32_ETHMAC_BASE+STM32_ETH_DMAMFBOC_OFFSET) +#define STM32_ETH_DMARSWTR (STM32_ETHMAC_BASE+STM32_ETH_DMARSWTR_OFFSET) +#define STM32_ETH_DMACHTDR (STM32_ETHMAC_BASE+STM32_ETH_DMACHTDR_OFFSET) +#define STM32_ETH_DMACHRDR (STM32_ETHMAC_BASE+STM32_ETH_DMACHRDR_OFFSET) +#define STM32_ETH_DMACHTBAR (STM32_ETHMAC_BASE+STM32_ETH_DMACHTBAR_OFFSET) +#define STM32_ETH_DMACHRBAR (STM32_ETHMAC_BASE+STM32_ETH_DMACHRBAR_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ +/* MAC Registers */ + +/* Ethernet MAC configuration register */ + +#define ETH_MACCR_RE (1 << 2) /* Bit 2: Receiver enable */ +#define ETH_MACCR_TE (1 << 3) /* Bit 3: Transmitter enable */ +#define ETH_MACCR_DC (1 << 4) /* Bit 4: Deferral check */ +#define ETH_MACCR_BL_SHIFT (5) /* Bits 5-6: Back-off limit */ +#define ETH_MACCR_BL_MASK (3 << ETH_MACCR_BL_SHIFT) +# define ETH_MACCR_BL_10 (0 << ETH_MACCR_BL_SHIFT) /* 00: k = min (n, 10) */ +# define ETH_MACCR_BL_8 (1 << ETH_MACCR_BL_SHIFT) /* 01: k = min (n, 8) */ +# define ETH_MACCR_BL_4 (2 << ETH_MACCR_BL_SHIFT) /* 10: k = min (n, 4) */ +# define ETH_MACCR_BL_1 (3 << ETH_MACCR_BL_SHIFT) /* 11: k = min (n, 1) */ +#define ETH_MACCR_APCS (1 << 7) /* Bit 7: Automatic pad/CRC stripping */ +#define ETH_MACCR_RD (1 << 9) /* Bit 9: Retry disable */ +#define ETH_MACCR_IPCO (1 << 10) /* Bit 10: IPv4 checksum offload */ +#define ETH_MACCR_DM (1 << 11) /* Bit 11: Duplex mode */ +#define ETH_MACCR_LM (1 << 12) /* Bit 12: Loopback mode */ +#define ETH_MACCR_ROD (1 << 13) /* Bit 13: Receive own disable */ +#define ETH_MACCR_FES (1 << 14) /* Bit 14: Fast Ethernet speed */ +#define ETH_MACCR_CSD (1 << 16) /* Bit 16: Carrier sense disable */ +#define ETH_MACCR_IFG_SHIFT (17) /* Bits 17-19: Interframe gap */ +#define ETH_MACCR_IFG_MASK (7 << ETH_MACCR_IFG_SHIFT) +# define ETH_MACCR_IFG(n) ((12-((n) >> 3)) << ETH_MACCR_IFG_SHIFT) /* n bit times, n=40,48,..96 */ +#define ETH_MACCR_JD (1 << 22) /* Bit 22: Jabber disable */ +#define ETH_MACCR_WD (1 << 23) /* Bit 23: Watchdog disable */ +#define ETH_MACCR_CSTF (1 << 25) /* Bits 25: CRC stripping for Type frames */ + +/* Ethernet MAC frame filter register */ + +#define ETH_MACFFR_PM (1 << 0) /* Bit 0: Promiscuous mode */ +#define ETH_MACFFR_HU (1 << 1) /* Bit 1: Hash unicast */ +#define ETH_MACFFR_HM (1 << 2) /* Bit 2: Hash multicast */ +#define ETH_MACFFR_DAIF (1 << 3) /* Bit 3: Destination address inverse filtering */ +#define ETH_MACFFR_PAM (1 << 4) /* Bit 4: Pass all multicast */ +#define ETH_MACFFR_BFD (1 << 5) /* Bit 5: Broadcast frames disable */ +#define ETH_MACFFR_PCF_SHIFT (6) /* Bits 6-7: Pass control frames */ +#define ETH_MACFFR_PCF_MASK (3 << ETH_MACFFR_PCF_SHIFT) +# define ETH_MACFFR_PCF_NONE (0 << ETH_MACFFR_PCF_SHIFT) /* Prevents all control frames */ +# define ETH_MACFFR_PCF_PAUSE (1 << ETH_MACFFR_PCF_SHIFT) /* Prevents all except Pause control frames */ +# define ETH_MACFFR_PCF_ALL (2 << ETH_MACFFR_PCF_SHIFT) /* Forwards all control frames */ +# define ETH_MACFFR_PCF_FILTER (3 << ETH_MACFFR_PCF_SHIFT) /* Forwards all that pass address filter */ +#define ETH_MACFFR_SAIF (1 << 8) /* Bit 8: Source address inverse filtering */ +#define ETH_MACFFR_SAF (1 << 9) /* Bit 9: Source address filter */ +#define ETH_MACFFR_HPF (1 << 10) /* Bit 10: Hash or perfect filter */ +#define ETH_MACFFR_RA (1 << 31) /* Bit 31: Receive all */ + +/* Ethernet MAC hash table high/low registers (32-bit values) */ + +/* Ethernet MAC MII address register */ + +#define ETH_MACMIIAR_MB (1 << 0) /* Bit 0: MII busy */ +#define ETH_MACMIIAR_MW (1 << 1) /* Bit 1: MII write */ +#define ETH_MACMIIAR_CR_SHIFT (2) /* Bits 2-4: Clock range */ +#define ETH_MACMIIAR_CR_MASK (7 << ETH_MACMIIAR_CR_SHIFT) +# define ETH_MACMIIAR_CR_DIV42 (0 << ETH_MACMIIAR_CR_SHIFT) /* 60-100 MHz HCLK/42 */ +# define ETH_MACMIIAR_CR_DIV62 (1 << ETH_MACMIIAR_CR_SHIFT) /* 100-150 MHz HCLK/62 */ +# define ETH_MACMIIAR_CR_DIV16 (2 << ETH_MACMIIAR_CR_SHIFT) /* 20-35 MHz HCLK/16 */ +# define ETH_MACMIIAR_CR_DIV26 (3 << ETH_MACMIIAR_CR_SHIFT) /* 35-60 MHz HCLK/26 */ +# define ETH_MACMIIAR_CR_DIV102 (4 << ETH_MACMIIAR_CR_SHIFT) /* 150-216 MHz HCLK/102 */ +#define ETH_MACMIIAR_MR_SHIFT (6) /* Bits 6-10: MII register */ +#define ETH_MACMIIAR_MR_MASK (31 << ETH_MACMIIAR_MR_SHIFT) +# define ETH_MACMIIAR_MR(n) ((uint32_t)(n) << ETH_MACMIIAR_MR_SHIFT) +#define ETH_MACMIIAR_PA_SHIFT (11) /* Bits 11-15: PHY address */ +#define ETH_MACMIIAR_PA_MASK (31 << ETH_MACMIIAR_PA_SHIFT) +# define ETH_MACMIIAR_PA(n) ((uint32_t)(n) << ETH_MACMIIAR_PA_SHIFT) + +/* Ethernet MAC MII data register */ + +#define ETH_MACMIIDR_MASK (0xffff) + +/* Ethernet MAC flow control register */ + +#define ETH_MACFCR_FCB_BPA (1 << 0) /* Bit 0: Flow control busy/back pressure activate */ +#define ETH_MACFCR_TFCE (1 << 1) /* Bit 1: Transmit flow control enable */ +#define ETH_MACFCR_RFCE (1 << 2) /* Bit 2: Receive flow control enable */ +#define ETH_MACFCR_UPFD (1 << 3) /* Bit 3: Unicast pause frame detect */ +#define ETH_MACFCR_PLT_SHIFT (4) /* Bits 4-5: Pause low threshold */ +#define ETH_MACFCR_PLT_MASK (3 << ETH_MACFCR_PLT_SHIFT) +# define ETH_MACFCR_PLT_M4 (0 << ETH_MACFCR_PLT_SHIFT) /* 00 Pause - 4 slot times */ +# define ETH_MACFCR_PLT_M28 (1 << ETH_MACFCR_PLT_SHIFT) /* 01 Pause - 28 slot times */ +# define ETH_MACFCR_PLT_M144 (2 << ETH_MACFCR_PLT_SHIFT) /* 10 Pause - 144 slot times */ +# define ETH_MACFCR_PLT_M256 (3 << ETH_MACFCR_PLT_SHIFT) /* 11 Pause -s 256 slot times */ +#define ETH_MACFCR_ZQPD (1 << 7) /* Bit 7: Zero-quanta pause disable */ +#define ETH_MACFCR_PT_SHIFT (16) /* Bits 16-31: Pause time */ +#define ETH_MACFCR_PT_MASK (0xffff << ETH_MACFCR_PT_SHIFT) + +/* Ethernet MAC VLAN tag register */ + +#define ETH_MACVLANTR_VLANTI_SHIFT (0) /* Bits 0-15: VLAN tag identifier (for receive frames) */ +#define ETH_MACVLANTR_VLANTI_MASK (0xffff << ETH_MACVLANTR_VLANTI_SHIFT) +# define ETH_MACVLANTR_VLANTI(n) ((uint32_t)(n) << ETH_MACVLANTR_VLANTI_SHIFT) +#define ETH_MACVLANTR_VLANTC (1 << 16) /* Bit 16: 12-bit VLAN tag comparison */ + +/* Ethernet MAC remote wakeup frame filter reg. Provides 32-bit access to remote + * remote wake-up filters. + */ + +/* Ethernet MAC PMT control and status register */ + +#define ETH_MACPMTCSR_PD (1 << 0) /* Bit 0: Power down */ +#define ETH_MACPMTCSR_MPE (1 << 1) /* Bit 1: Magic Packet enable */ +#define ETH_MACPMTCSR_WFE (1 << 2) /* Bit 2: Wakeup frame enable */ +#define ETH_MACPMTCSR_MPR (1 << 5) /* Bit 5: Magic packet received */ +#define ETH_MACPMTCSR_WFR (1 << 6) /* Bit 6: Wakeup frame received */ +#define ETH_MACPMTCSR_GU (1 << 9) /* Bit 9: Global unicast */ + +/* Ethernet MAC debug register */ + +#define ETH_MACDBGR_MMRPEA (1 << 0) /* Bit 0: MAC MII receive protocol engine active */ +#define ETH_MACDBGR_MSFRWCS_SHIFT (1) /* Bits 1-2: MAC small FIFO read / write controllers status */ +#define ETH_MACDBGR_MSFRWCS_MASK (3 << ETH_MACDBGR_MSFRWCS_SHIFT) +# define ETH_MACDBGR_MSFRWCS(n) ((uint32_t)(n) << ETH_MACDBGR_MSFRWCS_SHIFT) +#define ETH_MACDBGR_RFWRA (1 << 4) /* Bit 4: Rx FIFO write controller active */ +#define ETH_MACDBGR_RFRCS_SHIFT (5) /* Bits 5-6: Rx FIFO read controller status */ +#define ETH_MACDBGR_RFRCS_MASK (3 << ETH_MACDBGR_RFRCS_SHIFT) +# define ETH_MACDBGR_RFRCS_IDLE (0 << ETH_MACDBGR_RFRCS_SHIFT) /* 00: IDLE state */ +# define ETH_MACDBGR_RFRCS_RFRAME (1 << ETH_MACDBGR_RFRCS_SHIFT) /* 01: Reading frame data */ +# define ETH_MACDBGR_RFRCS_RSTATUS (2 << ETH_MACDBGR_RFRCS_SHIFT) /* 10: Reading frame status (or time-stamp) */ +# define ETH_MACDBGR_RFRCS_FLUSHING (3 << ETH_MACDBGR_RFRCS_SHIFT) /* 11: Flushing the frame data and status */ +#define ETH_MACDBGR_RFFL_SHIFT (8) /* Bits 8-9: Rx FIFO fill level */ +#define ETH_MACDBGR_RFFL_MASK (3 << ETH_MACDBGR_RFFL_SHIFT) +# define ETH_MACDBGR_RFFL_EMPTY (0 << ETH_MACDBGR_RFFL_SHIFT) /* 00: RxFIFO empty */ +# define ETH_MACDBGR_RFFL_DEACT (1 << ETH_MACDBGR_RFFL_SHIFT) /* 01: RxFIFO fill-level below flow-control de-activate threshold */ +# define ETH_MACDBGR_RFFL_ACTIV (2 << ETH_MACDBGR_RFFL_SHIFT) /* 10: RxFIFO fill-level above flow-control activate threshold */ +# define ETH_MACDBGR_RFFL_FULL (3 << ETH_MACDBGR_RFFL_SHIFT) /* 11: RxFIFO full */ +#define ETH_MACDBGR_MMTEA (1 << 16) /* Bit 16: MAC MII transmit engine active */ +#define ETH_MACDBGR_MTFCS_SHIFT (17) /* Bits 17-18: MAC transmit frame controller status */ +#define ETH_MACDBGR_MTFCS_MASK (3 << ETH_MACDBGR_MTFCS_SHIFT) +# define ETH_MACDBGR_MTFCS_IDLE (0 << ETH_MACDBGR_MTFCS_SHIFT) /* 00: Idle */ +# define ETH_MACDBGR_MTFCS_WAITING (1 << ETH_MACDBGR_MTFCS_SHIFT) /* 01: Waiting for Status of previous frame or IFG/backoff period to be over */ +# define ETH_MACDBGR_MTFCS_PAUSE (2 << ETH_MACDBGR_MTFCS_SHIFT) /* 10: Generating and transmitting a Pause control frame */ +# define ETH_MACDBGR_MTFCS_FRAME (3 << ETH_MACDBGR_MTFCS_SHIFT) /* 11: Transferring input frame for transmission */ +#define ETH_MACDBGR_MTP (1 << 19) /* Bit 19: MAC transmitter in pause */ +#define ETH_MACDBGR_TFRS_SHIFT (20) /* Bits 20-21: Tx FIFO read status */ +#define ETH_MACDBGR_TFRS_MASK (3 << ETH_MACDBGR_TFRS_SHIFT) +# define ETH_MACDBGR_TFRS_IDLE (0 << ETH_MACDBGR_TFRS_SHIFT) /* 00: Idle state */ +# define ETH_MACDBGR_TFRS_READ (1 << ETH_MACDBGR_TFRS_SHIFT) /* 01: Read state */ +# define ETH_MACDBGR_TFRS_WAITING (2 << ETH_MACDBGR_TFRS_SHIFT) /* 10: Waiting for TxStatus from MAC transmitter */ +# define ETH_MACDBGR_TFRS_WRITING (3 << ETH_MACDBGR_TFRS_SHIFT) /* 11: Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MACDBGR_TFWA (1 << 22) /* Bit 22: Tx FIFO write active */ +#define ETH_MACDBGR_TFNE (1 << 24) /* Bit 24: Tx FIFO not empty */ +#define ETH_MACDBGR_TFF (1 << 25) /* Bit 25: Tx FIFO full */ + +/* Ethernet MAC interrupt status register */ + +#define ETH_MACSR_PMTS (1 << 3) /* Bit 3: PMT status */ +#define ETH_MACSR_MMCS (1 << 4) /* Bit 4: MMC status */ +#define ETH_MACSR_MMCRS (1 << 5) /* Bit 5: MMC receive status */ +#define ETH_MACSR_MMCTS (1 << 6) /* Bit 6: MMC transmit status */ +#define ETH_MACSR_TSTS (1 << 9) /* Bit 9: Time stamp trigger status */ + +/* Ethernet MAC interrupt mask register */ + +#define ETH_MACIMR_PMTIM (1 << 3) /* Bit 3: PMT interrupt mask */ +#define ETH_MACIMR_TSTIM (1 << 9) /* Bit 9: Time stamp trigger interrupt mask */ +#define ETH_MACIMR_ALLINTS (ETH_MACIMR_PMTIM|ETH_MACIMR_TSTIM) + +/* Ethernet MAC address 0 high register */ + +#define ETH_MACA0HR_MACA0H_SHIFT (0) /* Bits 0-15: MAC address0 high [47:32] */ +#define ETH_MACA0HR_MACA0H_MASK (0xffff << ETH_MACA0HR_MACA0H_SHIFT) +# define ETH_MACA0HR_MACA0H(n) ((uint32_t)(n) << ETH_MACA0HR_MACA0H_SHIFT) +#define ETH_MACA0HR_MO (1 << 31) /* Bit 31: Always 1 */ + +/* Ethernet MAC address 0 low register (MAC address0 low [31:0]) */ + +/* Ethernet MAC address 1 high register */ + +#define ETH_MACA1HR_MACA1H_SHIFT (0) /* Bits 0-15: MAC address1 high [47:32] */ +#define ETH_MACA1HR_MACA1H_MASK (0xffff << ETH_MACA1HR_MACA1H_SHIFT) +# define ETH_MACA1HR_MACA1H(n) ((uint32_t)(n) << ETH_MACA1HR_MACA1H_SHIFT) +#define ETH_MACA1HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA1HR_MBC_MASK (0x3f << ETH_MACA1HR_MBC_SHIFT) +# define ETH_MACA1HR_MBC_40_47 (0x20 << ETH_MACA1HR_MBC_SHIFT) /* Bit 29: ETH_MACA1HR [8-15] */ +# define ETH_MACA1HR_MBC_32_39 (0x10 << ETH_MACA1HR_MBC_SHIFT) /* Bit 28: ETH_MACA1HR [0-7] */ +# define ETH_MACA1HR_MBC_24_31 (0x08 << ETH_MACA1HR_MBC_SHIFT) /* Bit 27: ETH_MACA1LR [24-31] */ +# define ETH_MACA1HR_MBC_16_23 (0x04 << ETH_MACA1HR_MBC_SHIFT) /* Bit 26: ETH_MACA1LR [16-23] */ +# define ETH_MACA1HR_MBC_8_15 (0x02 << ETH_MACA1HR_MBC_SHIFT) /* Bit 25: ETH_MACA1LR [8-15] */ +# define ETH_MACA1HR_MBC_0_7 (0x01 << ETH_MACA1HR_MBC_SHIFT) /* Bit 24: ETH_MACA1LR [0-7] */ +#define ETH_MACA1HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA1HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address1 low register (MAC address1 low [31:0]) */ + +/* Ethernet MAC address 2 high register */ + +#define ETH_MACA2HR_MACA2H_SHIFT (0) /* Bits 0-15: MAC address2 high [47:32] */ +#define ETH_MACA2HR_MACA2H_MASK (0xffff << ETH_MACA2HR_MACA2H_SHIFT) +# define ETH_MACA2HR_MACA2H(n) ((uint32_t)(n) << ETH_MACA2HR_MACA2H_SHIFT) +#define ETH_MACA2HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA2HR_MBC_MASK (0x3f << ETH_MACA2HR_MBC_SHIFT) +# define ETH_MACA2HR_MBC_40_47 (0x20 << ETH_MACA2HR_MBC_SHIFT) /* Bit 29: ETH_MACA2HR [8-15] */ +# define ETH_MACA2HR_MBC_32_39 (0x10 << ETH_MACA2HR_MBC_SHIFT) /* Bit 28: ETH_MACA2HR [0-7] */ +# define ETH_MACA2HR_MBC_24_31 (0x08 << ETH_MACA2HR_MBC_SHIFT) /* Bit 27: ETH_MACA2LR [24-31] */ +# define ETH_MACA2HR_MBC_16_23 (0x04 << ETH_MACA2HR_MBC_SHIFT) /* Bit 26: ETH_MACA2LR [16-23] */ +# define ETH_MACA2HR_MBC_8_15 (0x02 << ETH_MACA2HR_MBC_SHIFT) /* Bit 25: ETH_MACA2LR [8-15] */ +# define ETH_MACA2HR_MBC_0_7 (0x01 << ETH_MACA2HR_MBC_SHIFT) /* Bit 24: ETH_MACA2LR [0-7] */ +#define ETH_MACA2HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA2HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address 2 low register (MAC address2 low [31:0]) */ + +/* Ethernet MAC address 3 high register */ + +#define ETH_MACA3HR_MACA3H_SHIFT (0) /* Bits 0-15: MAC address3 high [47:32] */ +#define ETH_MACA3HR_MACA3H_MASK (0xffff << ETH_MACA3HR_MACA3H_SHIFT) +# define ETH_MACA3HR_MACA3H(n) ((uint32_t)(n) << ETH_MACA3HR_MACA3H_SHIFT) +#define ETH_MACA3HR_MBC_SHIFT (24) /* Bits 24-29: Mask byte control */ +#define ETH_MACA3HR_MBC_MASK (0x3f << ETH_MACA3HR_MBC_SHIFT) +# define ETH_MACA3HR_MBC_40_47 (0x20 << ETH_MACA3HR_MBC_SHIFT) /* Bit 29: ETH_MACA3HR [8-15] */ +# define ETH_MACA3HR_MBC_32_39 (0x10 << ETH_MACA3HR_MBC_SHIFT) /* Bit 28: ETH_MACA3HR [0-7] */ +# define ETH_MACA3HR_MBC_24_31 (0x08 << ETH_MACA3HR_MBC_SHIFT) /* Bit 27: ETH_MACA3LR [24-31] */ +# define ETH_MACA3HR_MBC_16_23 (0x04 << ETH_MACA3HR_MBC_SHIFT) /* Bit 26: ETH_MACA3LR [16-23] */ +# define ETH_MACA3HR_MBC_8_15 (0x02 << ETH_MACA3HR_MBC_SHIFT) /* Bit 25: ETH_MACA3LR [8-15] */ +# define ETH_MACA3HR_MBC_0_7 (0x01 << ETH_MACA3HR_MBC_SHIFT) /* Bit 24: ETH_MACA3LR [0-7] */ +#define ETH_MACA3HR_SA (1 << 30) /* Bit 30: Source address */ +#define ETH_MACA3HR_AE (1 << 31) /* Bit 31: Address enable */ + +/* Ethernet MAC address 3 low register (MAC address3 low [31:0]) */ + +/* MMC Registers */ + +/* Ethernet MMC control register */ + +#define ETH_MMCCR_CR (1 << 0) /* Bit 0: Counter reset */ +#define ETH_MMCCR_CSR (1 << 1) /* Bit 1: Counter stop rollover */ +#define ETH_MMCCR_ROR (1 << 2) /* Bit 2: Reset on read */ +#define ETH_MMCCR_MCF (1 << 3) /* Bit 3: MMC counter freeze */ +#define ETH_MMCCR_MCP (1 << 4) /* Bit 4: MMC counter preset */ +#define ETH_MMCCR_MCFHP (1 << 5) /* Bit 5: MMC counter Full-Half preset */ + +/* Ethernet MMC receive interrupt and interrupt mask registers */ + +#define ETH_MMCRI_RFCE (1 << 5) /* Bit 5: Received frame CRC error */ +#define ETH_MMCRI_RFAE (1 << 6) /* Bit 6: Received frames alignment error */ +#define ETH_MMCRI_RGUF (1 << 17) /* Bit 17: Received good unicast frames */ + +/* Ethernet MMC transmit interrupt and interrupt mask register */ + +#define ETH_MMCTI_TGFSC (1 << 14) /* Bit 14: Transmitted good frames single collision */ +#define ETH_MMCTI_TGFMSC (1 << 15) /* Bit 15: Transmitted good frames more single collision */ +#define ETH_MMCTI_TGF (1 << 21) /* Bit 21: Transmitted good frames */ + +/* 32-bit counters: + * + * Ethernet MMC transmitted good frames counter register (single collision) + * Ethernet MMC transmitted good frames counter register (multiple-collision) + * Ethernet MMC transmitted good frames counter register + * Ethernet MMC received frames with CRC error counter register + * Ethernet MMC received frames with alignment error counter + * MMC received good unicast frames counter register + */ + +/* IEEE 1588 time stamp registers */ + +/* Ethernet PTP time stamp control register */ + +#define ETH_PTPTSCR_TSE (1 << 0) /* Bit 0: Time stamp enable */ +#define ETH_PTPTSCR_TSFCU (1 << 1) /* Bit 1: Time stamp fine or coarse update */ +#define ETH_PTPTSCR_TSSTI (1 << 2) /* Bit 2: Time stamp system time initialize */ +#define ETH_PTPTSCR_TSSTU (1 << 3) /* Bit 3: Time stamp system time update */ +#define ETH_PTPTSCR_TSITE (1 << 4) /* Bit 4: Time stamp interrupt trigger enable */ +#define ETH_PTPTSCR_TSARU (1 << 5) /* Bit 5: Time stamp addend register update */ +#define ETH_PTPTSCR_TSSARFE (1 << 8) /* Bit 8: Time stamp snapshot for all received frames enable */ +#define ETH_PTPTSCR_TSSSR (1 << 9) /* Bit 9: Time stamp subsecond rollover: digital or binary rollover control */ +#define ETH_PTPTSCR_TSPTPPSV2E (1 << 10) /* Bit 10: Time stamp PTP packet snooping for version2 format enable */ +#define ETH_PTPTSCR_TSSPTPOEFE (1 << 11) /* Bit 11: Time stamp snapshot for PTP over ethernet frames enable */ +#define ETH_PTPTSCR_TSSIPV6FE (1 << 12) /* Bit 12: Time stamp snapshot for IPv6 frames enable */ +#define ETH_PTPTSCR_TSSIPV4FE (1 << 13) /* Bit 13: Time stamp snapshot for IPv4 frames enable */ +#define ETH_PTPTSCR_TSSEME (1 << 14) /* Bit 14: Time stamp snapshot for event message enable */ +#define ETH_PTPTSCR_TSSMRME (1 << 15) /* Bit 15: Time stamp snapshot for message relevant to master enable */ +#define ETH_PTPTSCR_TSCNT_SHIFT (16) /* Bits 16-17: Time stamp clock node type */ +#define ETH_PTPTSCR_TSCNT_MASK (3 << ETH_PTPTSCR_TSCNT_SHIFT) +# define ETH_PTPTSCR_TSCNT_ORDINARY (0 << ETH_PTPTSCR_TSCNT_SHIFT) /* 00: Ordinary clock */ +# define ETH_PTPTSCR_TSCNT_BOUNDARY (1 << ETH_PTPTSCR_TSCNT_SHIFT) /* 01: Boundary clock */ +# define ETH_PTPTSCR_TSCNT_E2E (2 << ETH_PTPTSCR_TSCNT_SHIFT) /* 10: End-to-end transparent clock */ +# define ETH_PTPTSCR_TSCNT_P2P (3 << ETH_PTPTSCR_TSCNT_SHIFT) /* 11: Peer-to-peer transparent clock */ +#define ETH_PTPTSCR_TSPFFMAE (1 << 18) /* Bit 18: Time stamp PTP frame filtering MAC address enable */ + +/* Ethernet PTP subsecond increment register */ + +#define ETH_PTPSSIR_MASK (0xff) + +/* Ethernet PTP time stamp high register (32-bit) */ + +/* Ethernet PTP time stamp low register */ + +#define ETH_PTPTSLR_STPNS (1 << 31) /* Bit 31: System time positive or negative sign */ +#define ETH_PTPTSLR_MASK (0x7fffffff) /* Bits 0-30: System time subseconds */ + +/* Ethernet PTP time stamp high update register (32-bit) */ + +/* Ethernet PTP time stamp low update register */ + +#define ETH_PTPTSLU_TSUPNS (1 << 31) /* Bit 31: System time positive or negative sign */ +#define ETH_PTPTSLU_MASK (0x7fffffff) /* Bits 0-30: Time stamp update subsecond */ + +/* Ethernet PTP time stamp addend register (32-bit) */ +/* Ethernet PTP target time high register (32-bit) */ +/* Ethernet PTP target time low register (32-bit) */ + +/* Ethernet PTP time stamp status register */ + +#define ETH_PTPTSSR_TSSO (1 << 0) /* Bit 0: Time stamp second overflow */ +#define ETH_PTPTSSR_TSTTR (1 << 1) /* Bit 1: Time stamp target time reached */ + +/* DMA Registers */ + +/* Ethernet DMA bus mode register */ + +#define ETH_DMABMR_SR (1 << 0) /* Bit 0: Software reset */ +#define ETH_DMABMR_DA (1 << 1) /* Bit 1: DMA Arbitration */ +#define ETH_DMABMR_DSL_SHIFT (2) /* Bits 2-6: Descriptor skip length */ +#define ETH_DMABMR_DSL_MASK (31 << ETH_DMABMR_DSL_SHIFT) +# define ETH_DMABMR_DSL(n) ((n) << ETH_DMABMR_DSL_SHIFT) +#define ETH_DMABMR_EDFE (1 << 7) /* Bit 7: Enhanced descriptor format enable */ +#define ETH_DMABMR_PBL_SHIFT (8) /* Bits 8-13: Programmable burst length */ +#define ETH_DMABMR_PBL_MASK (0x3f << ETH_DMABMR_PBL_SHIFT) +# define ETH_DMABMR_PBL(n) ((n) << ETH_DMABMR_PBL_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMR_PM_SHIFT (14) /* Bits 14-15: Rx Tx priority ratio */ +#define ETH_DMABMR_PM_MASK (3 << ETH_DMABMR_PM_SHIFT) +# define ETH_DMABMR_RTPR_1TO1 (0 << ETH_DMABMR_PM_SHIFT) /* 00: 1:1 */ +# define ETH_DMABMR_RTPR_2TO1 (1 << ETH_DMABMR_PM_SHIFT) /* 01: 2:1 */ +# define ETH_DMABMR_RTPR_3TO1 (2 << ETH_DMABMR_PM_SHIFT) /* 10: 3:1 */ +# define ETH_DMABMR_RTPR_4TO1 (3 << ETH_DMABMR_PM_SHIFT) /* 11: 4:1 */ +#define ETH_DMABMR_FB (1 << 16) /* Bit 16: Fixed burst */ +#define ETH_DMABMR_RDP_SHIFT (17) /* Bits 17-22: Rx DMA PBL */ +#define ETH_DMABMR_RDP_MASK (0x3f << ETH_DMABMR_RDP_SHIFT) +# define ETH_DMABMR_RDP(n) ((n) << ETH_DMABMR_RDP_SHIFT) /* n=1, 2, 4, 8, 16, 32 */ +#define ETH_DMABMR_USP (1 << 23) /* Bit 23: Use separate PBL */ +#define ETH_DMABMR_FPM (1 << 24) /* Bit 24: 4xPBL mode */ +#define ETH_DMABMR_AAB (1 << 25) /* Bit 25: Address-aligned beats */ +#define ETH_DMABMR_MB (1 << 26) /* Bit 26: Mixed burst */ + +/* Ethernet DMA transmit poll demand register (32-bit) */ +/* Ethernet DMA receive poll demand register (32-bit) */ +/* Ethernet DMA receive descriptor list address register (32-bit address) */ +/* Ethernet DMA transmit descriptor list address register (32-bit address) */ + +/* Interrupt bit definitions common between the DMA status register (DMASR) and + * the DMA interrupt enable register (DMAIER). + */ + +#define ETH_DMAINT_TI (1 << 0) /* Bit 0: Transmit interrupt */ +#define ETH_DMAINT_TPSI (1 << 1) /* Bit 1: Transmit process stopped interrupt */ +#define ETH_DMAINT_TBUI (1 << 2) /* Bit 2: Transmit buffer unavailable interrupt */ +#define ETH_DMAINT_TJTI (1 << 3) /* Bit 3: Transmit jabber timeout interrupt */ +#define ETH_DMAINT_ROI (1 << 4) /* Bit 4: Overflow interrupt */ +#define ETH_DMAINT_TUI (1 << 5) /* Bit 5: Underflow interrupt */ +#define ETH_DMAINT_RI (1 << 6) /* Bit 6: Receive interrupt */ +#define ETH_DMAINT_RBUI (1 << 7) /* Bit 7: Receive buffer unavailable interrupt */ +#define ETH_DMAINT_RPSI (1 << 8) /* Bit 8: Receive process stopped interrupt */ +#define ETH_DMAINT_RWTI (1 << 9) /* Bit 9: Receive watchdog timeout interrupt */ +#define ETH_DMAINT_ETI (1 << 10) /* Bit 10: Early transmit interrupt */ +#define ETH_DMAINT_FBEI (1 << 13) /* Bit 13: Fatal bus error interrupt */ +#define ETH_DMAINT_ERI (1 << 14) /* Bit 14: Early receive interrupt */ +#define ETH_DMAINT_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */ +#define ETH_DMAINT_NIS (1 << 16) /* Bit 16: Normal interrupt summary */ + +/* Ethernet DMA status register (in addition to the interrupt bits above */ + +#define ETH_DMASR_RPS_SHIFT (17) /* Bits 17-19: Receive process state */ +#define ETH_DMASR_RPS_MASK (7 << ETH_DMASR_RPS_SHIFT) +# define ETH_DMASR_RPS_STOPPED (0 << ETH_DMASR_RPS_SHIFT) /* 000: Stopped: Reset or Stop Receive Command issued */ +# define ETH_DMASR_RPS_RXDESC (1 << ETH_DMASR_RPS_SHIFT) /* 001: Running: Fetching receive transfer descriptor */ +# define ETH_DMASR_RPS_WAITING (3 << ETH_DMASR_RPS_SHIFT) /* 011: Running: Waiting for receive packet */ +# define ETH_DMASR_RPS_SUSPENDED (4 << ETH_DMASR_RPS_SHIFT) /* 100: Suspended: Receive descriptor unavailable */ +# define ETH_DMASR_RPS_CLOSING (5 << ETH_DMASR_RPS_SHIFT) /* 101: Running: Closing receive descriptor */ +# define ETH_DMASR_RPS_TRANSFER (7 << ETH_DMASR_RPS_SHIFT) /* 111: Running: Transferring the receive data to memory */ +#define ETH_DMASR_TPS_SHIFT (20) /* Bits 20-22: Transmit process state */ +#define ETH_DMASR_TPS_MASK (7 << ETH_DMASR_TPS_SHIFT) +# define ETH_DMASR_TPS_STOPPED (0 << ETH_DMASR_TPS_SHIFT) /* 000: Stopped; Reset or Stop Transmit Command issued */ +# define ETH_DMASR_TPS_TXDESC (1 << ETH_DMASR_TPS_SHIFT) /* 001: Running; Fetching transmit transfer descriptor */ +# define ETH_DMASR_TPS_WAITING (2 << ETH_DMASR_TPS_SHIFT) /* 010: Running; Waiting for status */ +# define ETH_DMASR_TPS_TRANSFER (3 << ETH_DMASR_TPS_SHIFT) /* 011: Running; Reading data and queuing to transmit (TxFIFO) */ +# define ETH_DMASR_TPS_SUSPENDED (6 << ETH_DMASR_TPS_SHIFT) /* 110: Suspended; Transmit descriptor unavailable or buffer underflow */ +# define ETH_DMASR_TPS_CLOSING (7 << ETH_DMASR_TPS_SHIFT) /* 111: Running; Closing transmit descriptor */ +#define ETH_DMASR_EBS_SHIFT (23) /* Bits 23-25: Error bits status */ +#define ETH_DMASR_EBS_MASK (7 << ETH_DMASR_EBS_SHIFT) +# define ETH_DMASR_EBS_TXDMS (1 << ETH_DMASR_EBS_SHIFT) /* Bit 23 1 Error during data transfer by TxDMA */ +# define ETH_DMASR_EBS_READ (2 << ETH_DMASR_EBS_SHIFT) /* Bit 24 1 Error during read transfer */ +# define ETH_DMASR_EBS_DESC (4 << ETH_DMASR_EBS_SHIFT) /* Bit 25 1 Error during descriptor access */ +#define ETH_DMASR_MMCS (1 << 27) /* Bit 27: MMC status */ +#define ETH_DMASR_PMTS (1 << 28) /* Bit 28: PMT status */ +#define ETH_DMASR_TSTS (1 << 29) /* Bit 29: Time stamp trigger status */ + +/* Ethernet DMA operation mode register */ + +#define ETH_DMAOMR_SR (1 << 1) /* Bit 1: Start/stop receive */ +#define ETH_DMAOMR_OSF (1 << 2) /* Bit 2: Operate on second frame */ +#define ETH_DMAOMR_RTC_SHIFT (3) /* Bits 3-4: Receive threshold control */ +#define ETH_DMAOMR_RTC_MASK (3 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_64 (0 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_32 (1 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_96 (2 << ETH_DMAOMR_RTC_SHIFT) +# define ETH_DMAOMR_RTC_128 (3 << ETH_DMAOMR_RTC_SHIFT) +#define ETH_DMAOMR_FUGF (1 << 6) /* Bit 6: Forward undersized good frames */ +#define ETH_DMAOMR_FEF (1 << 7) /* Bit 7: Forward error frames */ +#define ETH_DMAOMR_ST (1 << 13) /* Bit 13: Start/stop transmission */ +#define ETH_DMAOMR_TTC_SHIFT (14) /* Bits 14-16: Transmit threshold control */ +#define ETH_DMAOMR_TTC_MASK (7 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_64 (0 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_128 (1 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_192 (2 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_256 (3 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_40 (4 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_32 (5 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_24 (6 << ETH_DMAOMR_TTC_SHIFT) +# define ETH_DMAOMR_TTC_16 (7 << ETH_DMAOMR_TTC_SHIFT) +#define ETH_DMAOMR_FTF (1 << 20) /* Bit 20: Flush transmit FIFO */ +#define ETH_DMAOMR_TSF (1 << 21) /* Bit 21: Transmit store and forward */ +#define ETH_DMAOMR_DFRF (1 << 24) /* Bit 24: Disable flushing of received frames */ +#define ETH_DMAOMR_RSF (1 << 25) /* Bit 25: Receive store and forward */ +#define ETH_DMAOMR_DTCEFD (1 << 26) /* Bit 26: Dropping of TCP/IP checksum error frames disable */ + +/* Ethernet DMA missed frame and buffer overflow counter register */ + +#define ETH_DMAMFBOC_MFC_SHIFT (0) /* Bits 0-15: Missed frames by the controller */ +#define ETH_DMAMFBOC_MFC_MASK (0xffff << ETH_DMAMFBOC_MFC_SHIFT) +# define ETH_DMAMFBOC_MFC(n) ((uint32_t)(n) << ETH_DMAMFBOC_MFC_SHIFT) +#define ETH_DMAMFBOC_OMFC (1 << 16) /* Bit 16: Overflow bit for missed frame counter */ +#define ETH_DMAMFBOC_MFA_SHIFT (17) /* Bits 17-27: Missed frames by the application */ +#define ETH_DMAMFBOC_MFA_MASK (0x7ff << ETH_DMAMFBOC_MFA_SHIFT) +# define ETH_DMAMFBOC_MFA(n) ((uint32_t)(n) << ETH_DMAMFBOC_MFA_SHIFT) +#define ETH_DMAMFBOC_OFOC (1 << 28) /* Bit 28: Overflow bit for FIFO overflow counter */ + +/* Ethernet DMA receive status watchdog timer register */ + +#define ETH_DMARSWTR_MASK (0xff) + +/* Ethernet DMA current host transmit descriptor register (32-bit address) */ +/* Ethernet DMA current host receive descriptor register (32-bit address) */ +/* Ethernet DMA current host transmit buffer address register (32-bit address) */ +/* Ethernet DMA current host receive buffer address register (32-bit address) */ + +/* DMA Descriptors **********************************************************************************/ +/* TDES0: Transmit descriptor Word0 */ + +#define ETH_TDES0_DB (1 << 0) /* Bit 0: Deferred bit */ +#define ETH_TDES0_UF (1 << 1) /* Bit 1: Underflow error */ +#define ETH_TDES0_ED (1 << 2) /* Bit 2: Excessive deferral */ +#define ETH_TDES0_CC_SHIFT (3) /* Bits 3-6: Collision count */ +#define ETH_TDES0_CC_MASK (15 << ETH_TDES0_CC_SHIFT) +# define ETH_TDES0_CC(n) ((uint32_t)(n) << ETH_TDES0_CC_SHIFT) +#define ETH_TDES0_VF (1 << 7) /* Bit 7: VLAN frame */ +#define ETH_TDES0_EC (1 << 8) /* Bit 8: Excessive collision */ +#define ETH_TDES0_LCO (1 << 9) /* Bit 9: Late collision */ +#define ETH_TDES0_NC (1 << 10) /* Bit 10: No carrier */ +#define ETH_TDES0_LCA (1 << 11) /* Bit 11: Loss of carrier */ +#define ETH_TDES0_IPE (1 << 12) /* Bit 12: IP payload error */ +#define ETH_TDES0_FF (1 << 13) /* Bit 13: Frame flushed */ +#define ETH_TDES0_JT (1 << 14) /* Bit 14: Jabber timeout */ +#define ETH_TDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_TDES0_IHE (1 << 16) /* Bit 16: IP header error */ +#define ETH_TDES0_TTSS (1 << 17) /* Bit 17: Transmit time stamp status */ +#define ETH_TDES0_TCH (1 << 20) /* Bit 20: Second address chained */ +#define ETH_TDES0_TER (1 << 21) /* Bit 21: Transmit end of ring */ +#define ETH_TDES0_CIC_SHIFT (22) /* Bits 22-23: Checksum insertion control */ +#define ETH_TDES0_CIC_MASK (3 << ETH_TDES0_CIC_SHIFT) +# define ETH_TDES0_CIC_DISABLED (0 << ETH_TDES0_CIC_SHIFT) /* Checksum disabled */ +# define ETH_TDES0_CIC_IH (1 << ETH_TDES0_CIC_SHIFT) /* IP header checksum enabled */ +# define ETH_TDES0_CIC_IHPL (2 << ETH_TDES0_CIC_SHIFT) /* IP header and payload checksum enabled */ +# define ETH_TDES0_CIC_ALL (3 << ETH_TDES0_CIC_SHIFT) /* IP Header, payload, and pseudo-header checksum enabled */ +#define ETH_TDES0_TTSE (1 << 25) /* Bit 25: Transmit time stamp enable */ +#define ETH_TDES0_DP (1 << 26) /* Bit 26: Disable pad */ +#define ETH_TDES0_DC (1 << 27) /* Bit 27: Disable CRC */ +#define ETH_TDES0_FS (1 << 28) /* Bit 28: First segment */ +#define ETH_TDES0_LS (1 << 29) /* Bit 29: Last segment */ +#define ETH_TDES0_IC (1 << 30) /* Bit 30: Interrupt on completion */ +#define ETH_TDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* TDES1: Transmit descriptor Word1 */ + +#define ETH_TDES1_TBS1_SHIFT (0) /* Bits 0-12: Transmit buffer 1 size */ +#define ETH_TDES1_TBS1_MASK (0x1fff << ETH_TDES1_TBS1_SHIFT) +# define ETH_TDES1_TBS1(n) ((uint32_t)(n) << ETH_TDES1_TBS1_SHIFT) +#define ETH_TDES1_TBS2_SHIFT (16) /* Bits 16-28: Transmit buffer 2 size */ +#define ETH_TDES1_TBS2_MASK (0x1fff << ETH_TDES1_TBS2_SHIFT) +# define ETH_TDES1_TBS2(n) ((uint32_t)(n) << ETH_TDES1_TBS2_SHIFT) + +/* TDES2: Transmit descriptor Word2 (32-bit address) */ +/* TDES3: Transmit descriptor Word3 (32-bit address) */ +/* TDES6: Transmit descriptor Word6 (32-bit time stamp) */ +/* TDES7: Transmit descriptor Word7 (32-bit time stamp) */ + +/* RDES0: Receive descriptor Word0 */ + +#define ETH_RDES0_PCE (1 << 0) /* Bit 0: Payload checksum error */ +#define ETH_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#define ETH_RDES0_CE (1 << 1) /* Bit 1: CRC error */ +#define ETH_RDES0_DBE (1 << 2) /* Bit 2: Dribble bit error */ +#define ETH_RDES0_RE (1 << 3) /* Bit 3: Receive error */ +#define ETH_RDES0_RWT (1 << 4) /* Bit 4: Receive watchdog timeout */ +#define ETH_RDES0_FT (1 << 5) /* Bit 5: Frame type */ +#define ETH_RDES0_LCO (1 << 6) /* Bit 6: Late collision */ +#define ETH_RDES0_TSV (1 << 7) /* Bit 7: Time stamp valid */ +#define ETH_RDES0_IPHCE (1 << 7) /* Bit 7: IPv header checksum error */ +#define ETH_RDES0_LS (1 << 8) /* Bit 8: Last descriptor */ +#define ETH_RDES0_FS (1 << 9) /* Bit 9: First descriptor */ +#define ETH_RDES0_VLAN (1 << 10) /* Bit 10: VLAN tag */ +#define ETH_RDES0_OE (1 << 11) /* Bit 11: Overflow error */ +#define ETH_RDES0_LE (1 << 12) /* Bit 12: Length error */ +#define ETH_RDES0_SAF (1 << 13) /* Bit 13: Source address filter fail */ +#define ETH_RDES0_DE (1 << 14) /* Bit 14: Descriptor error */ +#define ETH_RDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define ETH_RDES0_FL_SHIFT (16) /* Bits 16-29: Frame length */ +#define ETH_RDES0_FL_MASK (0x3fff << ETH_RDES0_FL_SHIFT) +# define ETH_RDES0_FL(n) ((uint32_t)(n) << ETH_RDES0_FL_SHIFT) +#define ETH_RDES0_AFM (1 << 30) /* Bit 30: Destination address filter fail */ +#define ETH_RDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* RDES1: Receive descriptor Word1 */ + +#define ETH_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ +#define ETH_RDES1_RBS1_MASK (0x1fff << ETH_RDES1_RBS1_SHIFT) +# define ETH_RDES1_RBS1(n) ((uint32_t)(n) << ETH_RDES1_RBS1_SHIFT) +#define ETH_RDES1_RCH (1 << 14) /* Bit 14: Second address chained */ +#define ETH_RDES1_RER (1 << 15) /* Bit 15: Receive end of ring */ +#define ETH_RDES1_RBS2_SHIFT (16) /* Bits 16-28: Receive buffer 2 size */ +#define ETH_RDES1_RBS2_MASK (0x1fff << ETH_RDES1_RBS2_SHIFT) +# define ETH_RDES1_RBS2(n) ((uint32_t)(n) << ETH_RDES1_RBS2_SHIFT) +#define ETH_RDES1_DIC (1 << 31) /* Bit 31: Disable interrupt on completion */ + +/* RDES2: Receive descriptor Word2 (32-bit address) */ +/* RDES3: Receive descriptor Word3 (32-bit address) */ + +/* RDES4: Receive descriptor Word4 */ + +#define ETH_RDES4_IPPT_SHIFT (0) /* Bits 0-2: IP payload type */ +#define ETH_RDES4_IPPT_MASK (7 << ETH_RDES4_IPPT_SHIFT) +# define ETH_RDES4_IPPT_UNKNOWN (0 << ETH_RDES4_IPPT_SHIFT) /* Unknown or did not process IP payload */ +# define ETH_RDES4_IPPT_UDP (1 << ETH_RDES4_IPPT_SHIFT) /* UDP payload in IP datagram */ +# define ETH_RDES4_IPPT_TCP (2 << ETH_RDES4_IPPT_SHIFT) /* TCP payload in IP datagram */ +# define ETH_RDES4_IPPT_ICMP (3 << ETH_RDES4_IPPT_SHIFT) /* ICMP payload in IP datagram */ +#define ETH_RDES4_IPHE (1 << 3) /* Bit 3: IP header error */ +#define ETH_RDES4_IPPE (1 << 4) /* Bit 4: IP payload error */ +#define ETH_RDES4_IPCB (1 << 5) /* Bit 5: IP checksum bypassed */ +#define ETH_RDES4_IPV4PR (1 << 6) /* Bit 6: IPv4 packet received */ +#define ETH_RDES4_IPV6PR (1 << 7) /* Bit 7: IPv6 packet received */ +#define ETH_RDES4_PMT_SHIFT (8) /* Bits 8-11: PTP message type */ +#define ETH_RDES4_PMT_MASK (15 << ETH_RDES4_PMT_SHIFT) +# define ETH_RDES4_PMT_NONE (0 << ETH_RDES4_PMT_SHIFT) /* No PTP message received */ +# define ETH_RDES4_PMT_SYNC (1 << ETH_RDES4_PMT_SHIFT) /* SYNC (all clock types) */ +# define ETH_RDES4_PMT_FOLLOWUP (2 << ETH_RDES4_PMT_SHIFT) /* Follow_Up (all clock types) */ +# define ETH_RDES4_PMT_DELAYREQ (3 << ETH_RDES4_PMT_SHIFT) /* Delay_Req (all clock types) */ +# define ETH_RDES4_PMT_DELAYRESP (4 << ETH_RDES4_PMT_SHIFT) /* Delay_Resp (all clock types) */ +# define ETH_RDES4_PMT_PDELREQAM (5 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Req (in peer-to-peer + * transparent clock) or Announce (in + * ordinary or boundary clock) */ +# define ETH_RDES4_PMT_PDELREQMM (6 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Resp (in peer-to-peer + * transparent clock) or Management (in + * ordinary or boundary clock) */ +# define ETH_RDES4_PMT_PDELREQFUS (7 << ETH_RDES4_PMT_SHIFT) /* Pdelay_Resp_Follow_Up (in + * peer-to-peer transparent clock) or + * Signaling (for ordinary or boundary + * clock) */ +#define ETH_RDES4_PFT (1 << 12) /* Bit 12: PTP frame type */ +#define ETH_RDES4_PV (1 << 13) /* Bit 13: PTP version */ + +/* RDES5: Receive descriptor Word5 - Reserved */ +/* RDES6: Receive descriptor Word6 (32-bit time stamp) */ +/* RDES7: Receive descriptor Word7 (32-bit time stamp) */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Ethernet TX DMA Descriptor */ + +struct eth_txdesc_s +{ + /* Normal DMA descriptor words */ + + volatile uint32_t tdes0; /* Status */ + volatile uint32_t tdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t tdes2; /* Buffer1 address pointer */ + volatile uint32_t tdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp */ + +#ifdef CONFIG_STM32F7_ETH_ENHANCEDDESC + volatile uint32_t tdes4; /* Reserved */ + volatile uint32_t tdes5; /* Reserved */ + volatile uint32_t tdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t tdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/* Ethernet RX DMA Descriptor */ + +struct eth_rxdesc_s +{ + volatile uint32_t rdes0; /* Status */ + volatile uint32_t rdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t rdes2; /* Buffer1 address pointer */ + volatile uint32_t rdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp and PTP support */ + +#ifdef CONFIG_STM32F7_ETH_ENHANCEDDESC + volatile uint32_t rdes4; /* Extended status for PTP receive descriptor */ + volatile uint32_t rdes5; /* Reserved */ + volatile uint32_t rdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t rdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_ETHERNET_H */ + diff --git a/arch/arm/src/stm32f7/chip/stm32_exti.h b/arch/arm/src/stm32f7/chip/stm32_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..1bf43de7931ea7eb3c4604533d51b2ac0ed60970 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_exti.h @@ -0,0 +1,131 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_exti.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32_NEXTI 24 +#define STM32_EXTI_MASK 0x00ffffff +#define STM32_EXTI_BIT(n) (1 << (n)) + +/* Register Offsets *****************************************************************/ + +#define STM32_EXTI_IMR_OFFSET 0x0000 /* Interrupt mask register */ +#define STM32_EXTI_EMR_OFFSET 0x0004 /* Event mask register */ +#define STM32_EXTI_RTSR_OFFSET 0x0008 /* Rising Trigger selection register */ +#define STM32_EXTI_FTSR_OFFSET 0x000c /* Falling Trigger selection register */ +#define STM32_EXTI_SWIER_OFFSET 0x0010 /* Software interrupt event register */ +#define STM32_EXTI_PR_OFFSET 0x0014 /* Pending register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_EXTI_IMR (STM32_EXTI_BASE+STM32_EXTI_IMR_OFFSET) +#define STM32_EXTI_EMR (STM32_EXTI_BASE+STM32_EXTI_EMR_OFFSET) +#define STM32_EXTI_RTSR (STM32_EXTI_BASE+STM32_EXTI_RTSR_OFFSET) +#define STM32_EXTI_FTSR (STM32_EXTI_BASE+STM32_EXTI_FTSR_OFFSET) +#define STM32_EXTI_SWIER (STM32_EXTI_BASE+STM32_EXTI_SWIER_OFFSET) +#define STM32_EXTI_PR (STM32_EXTI_BASE+STM32_EXTI_PR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* EXTI linex < 16 are associated with GPIO pins 0-15. + * EXTI lines > 15 are associated with internal devices: + */ + +#define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 = PVD output */ +#define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 = RTC Alarm event */ +#define EXTI_OTGFS_WAKEUP (1 << 18) /* EXTI line 18 = USB OTG FS Wakeup event */ +#define EXTI_ETH_WAKEUP (1 << 19) /* EXTI line 19 = Ethernet Wakeup event */ +#define EXTI_OTGHS_WAKEUP (1 << 20) /* EXTI line 20 = USB OTG HS (FS mode) Wakeup eventt */ +#define EXTI_RTC_TAMPER (1 << 21) /* EXTI line 21 = RTC Tamper and TimeStamp events */ +#define EXTI_RTC_TIMESTAMP (1 << 21) /* EXTI line 21 = RTC Tamper and TimeStamp events */ +#define EXTI_RTC_WAKEUP (1 << 22) /* EXTI line 22 = RTC Wakeup event */ +#define EXTI_LPTIM1_WAKEUP (1 << 23) /* EXTI line 23 = LPTIM1 asynchronous event */ + +/* Interrupt mask register */ + +#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR_MASK STM32_EXTI_MASK + +/* Event mask register */ + +#define EXTI_EMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR_MASK STM32_EXTI_MASK + +/* Rising Trigger selection register */ + +#define EXTI_RTSR_BIT(n) STM32_EXTI_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR_MASK STM32_EXTI_MASK + +/* Falling Trigger selection register */ + +#define EXTI_FTSR_BIT(n) STM32_EXTI_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR_MASK STM32_EXTI_MASK + +/* Software interrupt event register */ + +#define EXTI_SWIER_BIT(n) STM32_EXTI_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER_MASK STM32_EXTI_MASK + +/* Pending register */ + +#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR_MASK STM32_EXTI_MASK + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_flash.h b/arch/arm/src/stm32f7/chip/stm32_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..965191bdcfbb70b94ca73f0b7776931a2b0972a8 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_flash.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_flash.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_flash.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_FLASH_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_gpio.h b/arch/arm/src/stm32f7/chip/stm32_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..5b89574b0f29130da07c0bc8093a635f7edc666d --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_gpio.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_gpio.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_memorymap.h b/arch/arm/src/stm32f7/chip/stm32_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..f3ef8a1d53b83e38b989b9d342e45977440751fa --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_memorymap.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_memorymap.h" +#else +# error "Unsupported STM32 F7 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_pinmap.h b/arch/arm/src/stm32f7/chip/stm32_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..59903d8d03e21ebf156de17b75476bc3dad7b5e2 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_pinmap.h @@ -0,0 +1,53 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_pinmap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PINMAP_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_pinmap.h" +#else +# error "Unsupported STM32 F7 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PINMAP_H */ + diff --git a/arch/arm/src/stm32f7/chip/stm32_pwr.h b/arch/arm/src/stm32f7/chip/stm32_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..427fab1f3fcfdfcd3364469c3c92a3180033773e --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_pwr.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_pwr.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_pwr.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_PWR_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_rcc.h b/arch/arm/src/stm32f7/chip/stm32_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..13468a55601d8427c96c4a5f020c417b3eb35923 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_rcc.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_rcc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RCC_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RCC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_rcc.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RCC_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_syscfg.h b/arch/arm/src/stm32f7/chip/stm32_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..37c82ec50cf4b6c87316f352cc8cacb4d33759d9 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_syscfg.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_syscfg.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SYSCFG_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SYSCFG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_syscfg.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SYSCFG_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32_uart.h b/arch/arm/src/stm32f7/chip/stm32_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..0d48eaa399a94ae741256cb8cd20327af9624fdc --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_uart.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_uart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_UART_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "chip/stm32f74xx75xx_uart.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_UART_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dma.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..a9acb05787178b750c099a549fb0845602706c7c --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dma.h @@ -0,0 +1,551 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32f74xx75xx_dma.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XX_DMA_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XX_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* 2 DMA controllers */ + +#define DMA1 (0) +#define DMA2 (1) + +/* 8 DMA streams */ + +#define DMA_STREAM0 (0) +#define DMA_STREAM1 (1) +#define DMA_STREAM2 (2) +#define DMA_STREAM3 (3) +#define DMA_STREAM4 (4) +#define DMA_STREAM5 (5) +#define DMA_STREAM6 (6) +#define DMA_STREAM7 (7) + +/* 8 DMA channels */ + +#define DMA_CHAN0 (0) +#define DMA_CHAN1 (1) +#define DMA_CHAN2 (2) +#define DMA_CHAN3 (3) +#define DMA_CHAN4 (4) +#define DMA_CHAN5 (5) +#define DMA_CHAN6 (6) +#define DMA_CHAN7 (7) + +/* Register Offsets *****************************************************************/ + +#define STM32_DMA_LISR_OFFSET 0x0000 /* DMA low interrupt status register */ +#define STM32_DMA_HISR_OFFSET 0x0004 /* DMA high interrupt status register */ +#define STM32_DMA_LIFCR_OFFSET 0x0008 /* DMA low interrupt flag clear register */ +#define STM32_DMA_HIFCR_OFFSET 0x000c /* DMA high interrupt flag clear register */ + +#define STM32_DMA_OFFSET(n) (0x0010+0x0018*(n)) +#define STM32_DMA_SCR_OFFSET 0x0000 /* DMA stream n configuration register */ +#define STM32_DMA_SNDTR_OFFSET 0x0004 /* DMA stream n number of data register */ +#define STM32_DMA_SPAR_OFFSET 0x0008 /* DMA stream n peripheral address register */ +#define STM32_DMA_SM0AR_OFFSET 0x000c /* DMA stream n memory 0 address register */ +#define STM32_DMA_SM1AR_OFFSET 0x0010 /* DMA stream n memory 1 address register */ +#define STM32_DMA_SFCR_OFFSET 0x0014 /* DMA stream n FIFO control register */ + +#define STM32_DMA_S0CR_OFFSET 0x0010 /* DMA stream 0 configuration register */ +#define STM32_DMA_S1CR_OFFSET 0x0028 /* DMA stream 1 configuration register */ +#define STM32_DMA_S2CR_OFFSET 0x0040 /* DMA stream 2 configuration register */ +#define STM32_DMA_S3CR_OFFSET 0x0058 /* DMA stream 3 configuration register */ +#define STM32_DMA_S4CR_OFFSET 0x0070 /* DMA stream 4 configuration register */ +#define STM32_DMA_S5CR_OFFSET 0x0088 /* DMA stream 5 configuration register */ +#define STM32_DMA_S6CR_OFFSET 0x00a0 /* DMA stream 6 configuration register */ +#define STM32_DMA_S7CR_OFFSET 0x00b8 /* DMA stream 7 configuration register */ + +#define STM32_DMA_S0NDTR_OFFSET 0x0014 /* DMA stream 0 number of data register */ +#define STM32_DMA_S1NDTR_OFFSET 0x002c /* DMA stream 1 number of data register */ +#define STM32_DMA_S2NDTR_OFFSET 0x0044 /* DMA stream 2 number of data register */ +#define STM32_DMA_S3NDTR_OFFSET 0x005c /* DMA stream 3 number of data register */ +#define STM32_DMA_S4NDTR_OFFSET 0x0074 /* DMA stream 4 number of data register */ +#define STM32_DMA_S5NDTR_OFFSET 0x008c /* DMA stream 5 number of data register */ +#define STM32_DMA_S6NDTR_OFFSET 0x00a4 /* DMA stream 6 number of data register */ +#define STM32_DMA_S7NDTR_OFFSET 0x00bc /* DMA stream 7 number of data register */ + +#define STM32_DMA_S0PAR_OFFSET 0x0018 /* DMA stream 0 peripheral address register */ +#define STM32_DMA_S1PAR_OFFSET 0x0030 /* DMA stream 1 peripheral address register */ +#define STM32_DMA_S2PAR_OFFSET 0x0048 /* DMA stream 2 peripheral address register */ +#define STM32_DMA_S3PAR_OFFSET 0x0060 /* DMA stream 3 peripheral address register */ +#define STM32_DMA_S4PAR_OFFSET 0x0078 /* DMA stream 4 peripheral address register */ +#define STM32_DMA_S5PAR_OFFSET 0x0090 /* DMA stream 5 peripheral address register */ +#define STM32_DMA_S6PAR_OFFSET 0x00a8 /* DMA stream 6 peripheral address register */ +#define STM32_DMA_S7PAR_OFFSET 0x00c0 /* DMA stream 7 peripheral address register */ + +#define STM32_DMA_S0M0AR_OFFSET 0x001c /* DMA stream 0 memory 0 address register */ +#define STM32_DMA_S1M0AR_OFFSET 0x0034 /* DMA stream 1 memory 0 address register */ +#define STM32_DMA_S2M0AR_OFFSET 0x004c /* DMA stream 2 memory 0 address register */ +#define STM32_DMA_S3M0AR_OFFSET 0x0064 /* DMA stream 3 memory 0 address register */ +#define STM32_DMA_S4M0AR_OFFSET 0x007c /* DMA stream 4 memory 0 address register */ +#define STM32_DMA_S5M0AR_OFFSET 0x0094 /* DMA stream 5 memory 0 address register */ +#define STM32_DMA_S6M0AR_OFFSET 0x00ac /* DMA stream 6 memory 0 address register */ +#define STM32_DMA_S7M0AR_OFFSET 0x00c4 /* DMA stream 7 memory 0 address register */ + +#define STM32_DMA_S0M1AR_OFFSET 0x0020 /* DMA stream 0 memory 1 address register */ +#define STM32_DMA_S1M1AR_OFFSET 0x0038 /* DMA stream 1 memory 1 address register */ +#define STM32_DMA_S2M1AR_OFFSET 0x0050 /* DMA stream 2 memory 1 address register */ +#define STM32_DMA_S3M1AR_OFFSET 0x0068 /* DMA stream 3 memory 1 address register */ +#define STM32_DMA_S4M1AR_OFFSET 0x0080 /* DMA stream 4 memory 1 address register */ +#define STM32_DMA_S5M1AR_OFFSET 0x0098 /* DMA stream 5 memory 1 address register */ +#define STM32_DMA_S6M1AR_OFFSET 0x00b0 /* DMA stream 6 memory 1 address register */ +#define STM32_DMA_S7M1AR_OFFSET 0x00c8 /* DMA stream 7 memory 1 address register */ + +#define STM32_DMA_S0FCR_OFFSET 0x0024 /* DMA stream 0 FIFO control register */ +#define STM32_DMA_S1FCR_OFFSET 0x003c /* DMA stream 1 FIFO control register */ +#define STM32_DMA_S2FCR_OFFSET 0x0054 /* DMA stream 2 FIFO control register */ +#define STM32_DMA_S3FCR_OFFSET 0x006c /* DMA stream 3 FIFO control register */ +#define STM32_DMA_S4FCR_OFFSET 0x0084 /* DMA stream 4 FIFO control register */ +#define STM32_DMA_S5FCR_OFFSET 0x009c /* DMA stream 5 FIFO control register */ +#define STM32_DMA_S6FCR_OFFSET 0x00b4 /* DMA stream 6 FIFO control register */ +#define STM32_DMA_S7FCR_OFFSET 0x00cc /* DMA stream 7 FIFO control register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_DMA1_LISRC (STM32_DMA1_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA1_HISRC (STM32_DMA1_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA1_LIFCR (STM32_DMA1_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA1_HIFCR (STM32_DMA1_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA1_SCR(n) (STM32_DMA1_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0CR (STM32_DMA1_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA1_S1CR (STM32_DMA1_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA1_S2CR (STM32_DMA1_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA1_S3CR (STM32_DMA1_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA1_S4CR (STM32_DMA1_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA1_S5CR (STM32_DMA1_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA1_S6CR (STM32_DMA1_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA1_S7CR (STM32_DMA1_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA1_SNDTR(n) (STM32_DMA1_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0NDTR (STM32_DMA1_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA1_S1NDTR (STM32_DMA1_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA1_S2NDTR (STM32_DMA1_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA1_S3NDTR (STM32_DMA1_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA1_S4NDTR (STM32_DMA1_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA1_S5NDTR (STM32_DMA1_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA1_S6NDTR (STM32_DMA1_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA1_S7NDTR (STM32_DMA1_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA1_SPAR(n) (STM32_DMA1_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0PAR (STM32_DMA1_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA1_S1PAR (STM32_DMA1_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA1_S2PAR (STM32_DMA1_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA1_S3PAR (STM32_DMA1_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA1_S4PAR (STM32_DMA1_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA1_S5PAR (STM32_DMA1_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA1_S6PAR (STM32_DMA1_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA1_S7PAR (STM32_DMA1_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA1_SM0AR(n) (STM32_DMA1_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M0AR (STM32_DMA1_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA1_S1M0AR (STM32_DMA1_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA1_S2M0AR (STM32_DMA1_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA1_S3M0AR (STM32_DMA1_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA1_S4M0AR (STM32_DMA1_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA1_S5M0AR (STM32_DMA1_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA1_S6M0AR (STM32_DMA1_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA1_S7M0AR (STM32_DMA1_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA1_SM1AR(n) (STM32_DMA1_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0M1AR (STM32_DMA1_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA1_S1M1AR (STM32_DMA1_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA1_S2M1AR (STM32_DMA1_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA1_S3M1AR (STM32_DMA1_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA1_S4M1AR (STM32_DMA1_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA1_S5M1AR (STM32_DMA1_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA1_S6M1AR (STM32_DMA1_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA1_S7M1AR (STM32_DMA1_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA1_SFCR(n) (STM32_DMA1_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA1_S0FCR (STM32_DMA1_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA1_S1FCR (STM32_DMA1_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA1_S2FCR (STM32_DMA1_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA1_S3FCR (STM32_DMA1_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA1_S4FCR (STM32_DMA1_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA1_S5FCR (STM32_DMA1_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA1_S6FCR (STM32_DMA1_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA1_S7FCR (STM32_DMA1_BASE+STM32_DMA_S7FCR_OFFSET) + +#define STM32_DMA2_LISRC (STM32_DMA2_BASE+STM32_DMA_LISR_OFFSET) +#define STM32_DMA2_HISRC (STM32_DMA2_BASE+STM32_DMA_HISR_OFFSET) +#define STM32_DMA2_LIFCR (STM32_DMA2_BASE+STM32_DMA_LIFCR_OFFSET) +#define STM32_DMA2_HIFCR (STM32_DMA2_BASE+STM32_DMA_HIFCR_OFFSET) + +#define STM32_DMA2_SCR(n) (STM32_DMA2_BASE+STM32_DMA_SCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0CR (STM32_DMA2_BASE+STM32_DMA_S0CR_OFFSET) +#define STM32_DMA2_S1CR (STM32_DMA2_BASE+STM32_DMA_S1CR_OFFSET) +#define STM32_DMA2_S2CR (STM32_DMA2_BASE+STM32_DMA_S2CR_OFFSET) +#define STM32_DMA2_S3CR (STM32_DMA2_BASE+STM32_DMA_S3CR_OFFSET) +#define STM32_DMA2_S4CR (STM32_DMA2_BASE+STM32_DMA_S4CR_OFFSET) +#define STM32_DMA2_S5CR (STM32_DMA2_BASE+STM32_DMA_S5CR_OFFSET) +#define STM32_DMA2_S6CR (STM32_DMA2_BASE+STM32_DMA_S6CR_OFFSET) +#define STM32_DMA2_S7CR (STM32_DMA2_BASE+STM32_DMA_S7CR_OFFSET) + +#define STM32_DMA2_SNDTR(n) (STM32_DMA2_BASE+STM32_DMA_SNDTR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0NDTR (STM32_DMA2_BASE+STM32_DMA_S0NDTR_OFFSET) +#define STM32_DMA2_S1NDTR (STM32_DMA2_BASE+STM32_DMA_S1NDTR_OFFSET) +#define STM32_DMA2_S2NDTR (STM32_DMA2_BASE+STM32_DMA_S2NDTR_OFFSET) +#define STM32_DMA2_S3NDTR (STM32_DMA2_BASE+STM32_DMA_S3NDTR_OFFSET) +#define STM32_DMA2_S4NDTR (STM32_DMA2_BASE+STM32_DMA_S4NDTR_OFFSET) +#define STM32_DMA2_S5NDTR (STM32_DMA2_BASE+STM32_DMA_S5NDTR_OFFSET) +#define STM32_DMA2_S6NDTR (STM32_DMA2_BASE+STM32_DMA_S6NDTR_OFFSET) +#define STM32_DMA2_S7NDTR (STM32_DMA2_BASE+STM32_DMA_S7NDTR_OFFSET) + +#define STM32_DMA2_SPAR(n) (STM32_DMA2_BASE+STM32_DMA_SPAR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0PAR (STM32_DMA2_BASE+STM32_DMA_S0PAR_OFFSET) +#define STM32_DMA2_S1PAR (STM32_DMA2_BASE+STM32_DMA_S1PAR_OFFSET) +#define STM32_DMA2_S2PAR (STM32_DMA2_BASE+STM32_DMA_S2PAR_OFFSET) +#define STM32_DMA2_S3PAR (STM32_DMA2_BASE+STM32_DMA_S3PAR_OFFSET) +#define STM32_DMA2_S4PAR (STM32_DMA2_BASE+STM32_DMA_S4PAR_OFFSET) +#define STM32_DMA2_S5PAR (STM32_DMA2_BASE+STM32_DMA_S5PAR_OFFSET) +#define STM32_DMA2_S6PAR (STM32_DMA2_BASE+STM32_DMA_S6PAR_OFFSET) +#define STM32_DMA2_S7PAR (STM32_DMA2_BASE+STM32_DMA_S7PAR_OFFSET) + +#define STM32_DMA2_SM0AR(n) (STM32_DMA2_BASE+STM32_DMA_SM0AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M0AR (STM32_DMA2_BASE+STM32_DMA_S0M0AR_OFFSET) +#define STM32_DMA2_S1M0AR (STM32_DMA2_BASE+STM32_DMA_S1M0AR_OFFSET) +#define STM32_DMA2_S2M0AR (STM32_DMA2_BASE+STM32_DMA_S2M0AR_OFFSET) +#define STM32_DMA2_S3M0AR (STM32_DMA2_BASE+STM32_DMA_S3M0AR_OFFSET) +#define STM32_DMA2_S4M0AR (STM32_DMA2_BASE+STM32_DMA_S4M0AR_OFFSET) +#define STM32_DMA2_S5M0AR (STM32_DMA2_BASE+STM32_DMA_S5M0AR_OFFSET) +#define STM32_DMA2_S6M0AR (STM32_DMA2_BASE+STM32_DMA_S6M0AR_OFFSET) +#define STM32_DMA2_S7M0AR (STM32_DMA2_BASE+STM32_DMA_S7M0AR_OFFSET) + +#define STM32_DMA2_SM1AR(n) (STM32_DMA2_BASE+STM32_DMA_SM1AR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0M1AR (STM32_DMA2_BASE+STM32_DMA_S0M1AR_OFFSET) +#define STM32_DMA2_S1M1AR (STM32_DMA2_BASE+STM32_DMA_S1M1AR_OFFSET) +#define STM32_DMA2_S2M1AR (STM32_DMA2_BASE+STM32_DMA_S2M1AR_OFFSET) +#define STM32_DMA2_S3M1AR (STM32_DMA2_BASE+STM32_DMA_S3M1AR_OFFSET) +#define STM32_DMA2_S4M1AR (STM32_DMA2_BASE+STM32_DMA_S4M1AR_OFFSET) +#define STM32_DMA2_S5M1AR (STM32_DMA2_BASE+STM32_DMA_S5M1AR_OFFSET) +#define STM32_DMA2_S6M1AR (STM32_DMA2_BASE+STM32_DMA_S6M1AR_OFFSET) +#define STM32_DMA2_S7M1AR (STM32_DMA2_BASE+STM32_DMA_S7M1AR_OFFSET) + +#define STM32_DMA2_SFCR(n) (STM32_DMA2_BASE+STM32_DMA_SFCR_OFFSET+STM32_DMA_OFFSET(n)) +#define STM32_DMA2_S0FCR (STM32_DMA2_BASE+STM32_DMA_S0FCR_OFFSET) +#define STM32_DMA2_S1FCR (STM32_DMA2_BASE+STM32_DMA_S1FCR_OFFSET) +#define STM32_DMA2_S2FCR (STM32_DMA2_BASE+STM32_DMA_S2FCR_OFFSET) +#define STM32_DMA2_S3FCR (STM32_DMA2_BASE+STM32_DMA_S3FCR_OFFSET) +#define STM32_DMA2_S4FCR (STM32_DMA2_BASE+STM32_DMA_S4FCR_OFFSET) +#define STM32_DMA2_S5FCR (STM32_DMA2_BASE+STM32_DMA_S5FCR_OFFSET) +#define STM32_DMA2_S6FCR (STM32_DMA2_BASE+STM32_DMA_S6FCR_OFFSET) +#define STM32_DMA2_S7FCR (STM32_DMA2_BASE+STM32_DMA_S7FCR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_STREAM_MASK 0x3f +#define DMA_STREAM_FEIF_BIT (1 << 0) /* Bit 0: Stream FIFO error interrupt flag */ +#define DMA_STREAM_DMEIF_BIT (1 << 2) /* Bit 2: Stream direct mode error interrupt flag */ +#define DMA_STREAM_TEIF_BIT (1 << 3) /* Bit 3: Stream Transfer Error flag */ +#define DMA_STREAM_HTIF_BIT (1 << 4) /* Bit 4: Stream Half Transfer flag */ +#define DMA_STREAM_TCIF_BIT (1 << 5) /* Bit 5: Stream Transfer Complete flag */ + +/* DMA interrupt status register and interrupt flag clear register field definitions */ + +#define DMA_INT_STREAM0_SHIFT (0) /* Bits 0-5: DMA Stream 0 interrupt */ +#define DMA_INT_STREAM0_MASK (DMA_STREAM_MASK << DMA_INT_STREAM0_SHIFT) +#define DMA_INT_STREAM1_SHIFT (6) /* Bits 6-11: DMA Stream 1 interrupt */ +#define DMA_INT_STREAM1_MASK (DMA_STREAM_MASK << DMA_INT_STREAM1_SHIFT) +#define DMA_INT_STREAM2_SHIFT (16) /* Bits 16-21: DMA Stream 2 interrupt */ +#define DMA_INT_STREAM2_MASK (DMA_STREAM_MASK << DMA_INT_STREAM2_SHIFT) +#define DMA_INT_STREAM3_SHIFT (22) /* Bits 22-27: DMA Stream 3 interrupt */ +#define DMA_INT_STREAM3_MASK (DMA_STREAM_MASK << DMA_INT_STREAM3_SHIFT) + +#define DMA_INT_STREAM4_SHIFT (0) /* Bits 0-5: DMA Stream 4 interrupt */ +#define DMA_INT_STREAM4_MASK (DMA_STREAM_MASK << DMA_INT_STREAM4_SHIFT) +#define DMA_INT_STREAM5_SHIFT (6) /* Bits 6-11: DMA Stream 5 interrupt */ +#define DMA_INT_STREAM5_MASK (DMA_STREAM_MASK << DMA_INT_STREAM5_SHIFT) +#define DMA_INT_STREAM6_SHIFT (16) /* Bits 16-21: DMA Stream 6 interrupt */ +#define DMA_INT_STREAM6_MASK (DMA_STREAM_MASK << DMA_INT_STREAM6_SHIFT) +#define DMA_INT_STREAM7_SHIFT (22) /* Bits 22-27: DMA Stream 7 interrupt */ +#define DMA_INT_STREAM7_MASK (DMA_STREAM_MASK << DMA_INT_STREAM7_SHIFT) + +/* DMA stream configuration register */ + +#define DMA_SCR_EN (1 << 0) /* Bit 0: Stream enable */ +#define DMA_SCR_DMEIE (1 << 1) /* Bit 1: Direct mode error interrupt enable */ +#define DMA_SCR_TEIE (1 << 2) /* Bit 2: Transfer error interrupt enable */ +#define DMA_SCR_HTIE (1 << 3) /* Bit 3: Half Transfer interrupt enable */ +#define DMA_SCR_TCIE (1 << 4) /* Bit 4: Transfer complete interrupt enable */ +#define DMA_SCR_PFCTRL (1 << 5) /* Bit 5: Peripheral flow controller */ +#define DMA_SCR_DIR_SHIFT (6) /* Bits 6-7: Data transfer direction */ +#define DMA_SCR_DIR_MASK (3 << DMA_SCR_DIR_SHIFT) +# define DMA_SCR_DIR_P2M (0 << DMA_SCR_DIR_SHIFT) /* 00: Peripheral-to-memory */ +# define DMA_SCR_DIR_M2P (1 << DMA_SCR_DIR_SHIFT) /* 01: Memory-to-peripheral */ +# define DMA_SCR_DIR_M2M (2 << DMA_SCR_DIR_SHIFT) /* 10: Memory-to-memory */ +#define DMA_SCR_CIRC (1 << 8) /* Bit 8: Circular mode */ +#define DMA_SCR_PINC (1 << 9) /* Bit 9: Peripheral increment mode */ +#define DMA_SCR_MINC (1 << 10) /* Bit 10: Memory increment mode */ +#define DMA_SCR_PSIZE_SHIFT (11) /* Bits 11-12: Peripheral size */ +#define DMA_SCR_PSIZE_MASK (3 << DMA_SCR_PSIZE_SHIFT) +# define DMA_SCR_PSIZE_8BITS (0 << DMA_SCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_PSIZE_16BITS (1 << DMA_SCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_PSIZE_32BITS (2 << DMA_SCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_MSIZE_SHIFT (13) /* Bits 13-14: Memory size */ +#define DMA_SCR_MSIZE_MASK (3 << DMA_SCR_MSIZE_SHIFT) +# define DMA_SCR_MSIZE_8BITS (0 << DMA_SCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_SCR_MSIZE_16BITS (1 << DMA_SCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_SCR_MSIZE_32BITS (2 << DMA_SCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_SCR_PINCOS (1 << 15) /* Bit 15: Peripheral increment offset size */ +#define DMA_SCR_PL_SHIFT (16) /* Bits 16-17: Stream Priority level */ +#define DMA_SCR_PL_MASK (3 << DMA_SCR_PL_SHIFT) +# define DMA_SCR_PRILO (0 << DMA_SCR_PL_SHIFT) /* 00: Low */ +# define DMA_SCR_PRIMED (1 << DMA_SCR_PL_SHIFT) /* 01: Medium */ +# define DMA_SCR_PRIHI (2 << DMA_SCR_PL_SHIFT) /* 10: High */ +# define DMA_SCR_PRIVERYHI (3 << DMA_SCR_PL_SHIFT) /* 11: Very high */ +#define DMA_SCR_DBM (1 << 18) /* Bit 15: Double buffer mode */ +#define DMA_SCR_CT (1 << 19) /* Bit 19: Current target */ +#define DMA_SCR_PBURST_SHIFT (21) /* Bits 21-22: Peripheral burst transfer configuration */ +#define DMA_SCR_PBURST_MASK (3 << DMA_SCR_PBURST_SHIFT) +# define DMA_SCR_PBURST_SINGLE (0 << DMA_SCR_PBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_PBURST_INCR4 (1 << DMA_SCR_PBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_PBURST_INCR8 (2 << DMA_SCR_PBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_PBURST_INCR16 (3 << DMA_SCR_PBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_MBURST_SHIFT (23) /* Bits 23-24: Memory burst transfer configuration */ +#define DMA_SCR_MBURST_MASK (3 << DMA_SCR_MBURST_SHIFT) +# define DMA_SCR_MBURST_SINGLE (0 << DMA_SCR_MBURST_SHIFT) /* 00: Single transfer */ +# define DMA_SCR_MBURST_INCR4 (1 << DMA_SCR_MBURST_SHIFT) /* 01: Incremental burst of 4 beats */ +# define DMA_SCR_MBURST_INCR8 (2 << DMA_SCR_MBURST_SHIFT) /* 10: Incremental burst of 8 beats */ +# define DMA_SCR_MBURST_INCR16 (3 << DMA_SCR_MBURST_SHIFT) /* 11: Incremental burst of 16 beats */ +#define DMA_SCR_CHSEL_SHIFT (25) /* Bits 25-27: Channel selection */ +#define DMA_SCR_CHSEL_MASK (7 << DMA_SCR_CHSEL_SHIFT) +# define DMA_SCR_CHSEL(n) ((n) << DMA_SCR_CHSEL_SHIFT) + +#define DMA_SCR_ALLINTS (DMA_SCR_DMEIE|DMA_SCR_TEIE|DMA_SCR_HTIE|DMA_SCR_TCIE) + +/* DMA stream number of data register */ + +#define DMA_SNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_SNDTR_NDT_MASK (0xffff << DMA_SNDTR_NDT_SHIFT) + +/* DMA stream n FIFO control register */ + +#define DMA_SFCR_FTH_SHIFT (0) /* Bits 0-1: FIFO threshold selection */ +#define DMA_SFCR_FTH_MASK (3 << DMA_SFCR_FTH_SHIFT) +# define DMA_SFCR_FTH_QUARTER (0 << DMA_SFCR_FTH_SHIFT) /* 1/4 full FIFO */ +# define DMA_SFCR_FTH_HALF (1 << DMA_SFCR_FTH_SHIFT) /* 1/2 full FIFO */ +# define DMA_SFCR_FTH_3QUARTER (2 << DMA_SFCR_FTH_SHIFT) /* 3/4 full FIFO */ +# define DMA_SFCR_FTH_FULL (3 << DMA_SFCR_FTH_SHIFT) /* full FIFO */ +#define DMA_SFCR_DMDIS (1 << 2) /* Bit 2: Direct mode disable */ +#define DMA_SFCR_FS_SHIFT (3) /* Bits 3-5: FIFO status */ +#define DMA_SFCR_FS_MASK (7 << DMA_SFCR_FS_SHIFT) +# define DMA_SFCR_FS_QUARTER (0 << DMA_SFCR_FS_SHIFT) /* 0 < fifo_level < 1/4 */ +# define DMA_SFCR_FS_HALF (1 << DMA_SFCR_FS_SHIFT) /* 1/4 = fifo_level < 1/2 */ +# define DMA_SFCR_FS_3QUARTER (2 << DMA_SFCR_FS_SHIFT) /* 1/2 = fifo_level < 3/4 */ +# define DMA_SFCR_FS_ALMOSTFULL (3 << DMA_SFCR_FS_SHIFT) /* 3/4 = fifo_level < full */ +# define DMA_SFCR_FS_EMPTY (4 << DMA_SFCR_FS_SHIFT) /* FIFO is empty */ +# define DMA_SFCR_FS_FULL (5 << DMA_SFCR_FS_SHIFT) /* FIFO is full */ + /* Bit 6: Reserved */ +#define DMA_SFCR_FEIE (1 << 7) /* Bit 7: FIFO error interrupt enable */ + /* Bits 8-31: Reserved */ + +/* DMA Stream mapping. Each DMA stream has a mapping to several possible + * sources/sinks of data. The requests from peripherals assigned to a stream + * are simply OR'ed together before entering the DMA block. This means that only + * one request on a given stream can be enabled at once. + * + * Alternative stream selections are provided with a numeric suffix like _1, _2, etc. + * The DMA driver, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * SPI3_RX connects via DMA STREAM0, then following should be application-specific + * mapping should be used: + * + * #define DMAMAP_SPI3_RX DMAMAP_SPI3_RX_1 + */ + +#define STM32_DMA_MAP(d,s,c) ((d) << 6 | (s) << 3 | (c)) +#define STM32_DMA_CONTROLLER(m) (((m) >> 6) & 1) +#define STM32_DMA_STREAM(m) (((m) >> 3) & 7) +#define STM32_DMA_CHANNEL(m) ((m) & 7) + +#define DMAMAP_SPI3_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_SPDIFRX_DT STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN0) +#define DMAMAP_SPI3_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_SPI2_RX STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN0) +#define DMAMAP_SPI2_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_SPI3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN0) +#define DMAMAP_SPDIFRX_CS STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_SPI3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN0) + +#define DMAMAP_I2C1_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN1) +#define DMAMAP_I2C3_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN1) +#define DMAMAP_TIM7_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_TIM7_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN1) +#define DMAMAP_I2C1_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN1) +#define DMAMAP_I2C1_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN1) +#define DMAMAP_I2C1_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_TIM4_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_I2C_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN2) +#define DMAMAP_TIM4_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN2) +#define DMAMAP_I2C4_TX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_TIM4_UP STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_TIM4_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_TIM2_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN3) +#define DMAMAP_TIM2_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN3) +#define DMAMAP_I2C3_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_I2C3_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN3) +#define DMAMAP_TIM2_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN3) +#define DMAMAP_TIM2_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_TIM2_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) +#define DMAMAP_TIM2_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN3) + +#define DMAMAP_UART5_RX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN4) +#define DMAMAP_USART3_RX STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN4) +#define DMAMAP_UART4_RX STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_USART3_TX_1 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_UART4_TX STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN4) +#define DMAMAP_USART2_RX STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_USART2_TX STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_UART5_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN4) + +#define DMAMAP_UART8_TX STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN5) +#define DMAMAP_UART7_TX STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN5) +#define DMAMAP_TIM3_CH4 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_TIM3_UP STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_UART7_RX STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN5) +#define DMAMAP_TIM3_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_TRIG STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_TIM3_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN5) +#define DMAMAP_UART8_RX STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN5) +#define DMAMAP_TIM3_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM5_CH3 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_UP_1 STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_1 STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM5_CH1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM5_CH4_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_TRIG_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM5_CH2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM5_UP_2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM6_UP STM32_DMA_MAP(DMA1,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_I2C2_RX_1 STM32_DMA_MAP(DMA1,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_I2C2_RX_2 STM32_DMA_MAP(DMA1,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_USART3_TX_2 STM32_DMA_MAP(DMA1,DMA_STREAM4,DMA_CHAN7) +#define DMAMAP_DAC1 STM32_DMA_MAP(DMA1,DMA_STREAM5,DMA_CHAN7) +#define DMAMAP_DAC2 STM32_DMA_MAP(DMA1,DMA_STREAM6,DMA_CHAN7) +#define DMAMAP_I2C2_TX STM32_DMA_MAP(DMA1,DMA_STREAM7,DMA_CHAN7) + +#define DMAMAP_ADC1_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN0) +#define DMAMAP_SAI1_A_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN0) +#define DMAMAP_TIM8_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_TIM8_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN0) +#define DMAMAP_SAI1_A_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN0) +#define DMAMAP_ADC1_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN0) +#define DMAMAP_SAI1_B_1 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN0) +#define DMAMAP_TIM1_CH1_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH2_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_TIM1_CH3_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN0) +#define DMAMAP_SAI1_B_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN0) + +#define DMAMAP_DCMI_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN1) +#define DMAMAP_ADC2_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN1) +#define DMAMAP_ADC2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN1) +#define DMAMAP_SAI1_B STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN1) +#define DMAMAP_SPI6_TX STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN1) +#define DMAMAP_SPI6_RX STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN1) +#define DMAMAP_DCMI_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN1) + +#define DMAMAP_ADC3_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN2) +#define DMAMAP_ADC3_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN2) +#define DMAMAP_SPI5_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN2) +#define DMAMAP_SPI5_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN2) +#define DMAMAP_CRYP_OUT STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN2) +#define DMAMAP_CRYP_IN STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN2) +#define DMAMAP_HASH_IN STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN2) + +#define DMAMAP_SPI1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN3) +#define DMAMAP_SPI1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN3) +#define DMAMAP_SPI1_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN3) +#define DMAMAP_SAI2_A STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN3) +#define DMAMAP_SPI1_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN3) +#define DMAMAP_SAI2_B STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN3) +#define DMAMAP_QUADSPI STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN3) + +#define DMAMAP_SPI4_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN4) +#define DMAMAP_SPI4_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN4) +#define DMAMAP_USART1_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN4) +#define DMAMAP_SDMMC1_1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN4) +#define DMAMAP_USART1_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN4) +#define DMAMAP_SDMMC1_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN4) +#define DMAMAP_USART1_TX STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN4) + +#define DMAMAP_USART6_RX_1 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN5) +#define DMAMAP_USART6_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN5) +#define DMAMAP_SPI4_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN5) +#define DMAMAP_SPI4_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN5) +#define DMAMAP_USART6_TX_1 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN5) +#define DMAMAP_USART6_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN5) + +#define DMAMAP_TIM1_TRIG_1 STM32_DMA_MAP(DMA2,DMA_STREAM0,DMA_CHAN6) +#define DMAMAP_TIM1_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN6) +#define DMAMAP_TIM1_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN6) +#define DMAMAP_TIM1_CH1 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN6) +#define DMAMAP_TIM1_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_TRIG_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_COM STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN6) +#define DMAMAP_TIM1_UP STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN6) +#define DMAMAP_TIM1_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN6) + +#define DMAMAP_TIM8_UP STM32_DMA_MAP(DMA2,DMA_STREAM1,DMA_CHAN7) +#define DMAMAP_TIM8_CH1_2 STM32_DMA_MAP(DMA2,DMA_STREAM2,DMA_CHAN7) +#define DMAMAP_TIM8_CH2_2 STM32_DMA_MAP(DMA2,DMA_STREAM3,DMA_CHAN7) +#define DMAMAP_TIM8_CH3_2 STM32_DMA_MAP(DMA2,DMA_STREAM4,DMA_CHAN7) +#define DMAMAP_SPI5_RX_2 STM32_DMA_MAP(DMA2,DMA_STREAM5,DMA_CHAN7) +#define DMAMAP_SPI5_TX_2 STM32_DMA_MAP(DMA2,DMA_STREAM6,DMA_CHAN7) +#define DMAMAP_TIM8_CH4 STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_TRIG STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) +#define DMAMAP_TIM8_COM STM32_DMA_MAP(DMA2,DMA_STREAM7,DMA_CHAN7) + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XX_DMA_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_flash.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..69f4e217fca1a7d573cc9fc5da53acaca69eb7b1 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_flash.h @@ -0,0 +1,184 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32f74xx75xx_flash.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM327_CHIP_STM32F74XX75XX_FLASH_H +#define __ARCH_ARM_SRC_STM327_CHIP_STM32F74XX75XX_FLASH_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Flash size is not known from the chip configuration: + * + * Parts STM32F74xxE have 512Kb of FLASH + * Parts STM32F74xxG have 1024Kb of FLASH + * + * The user has to tell us the FLASH size by setting CONFIG_STM32F7_FLASH_SIZE + */ + +#if defined(CONFIG_STM32F7_FLASH_512KB) + +# define STM32_FLASH_NPAGES 2 +# define STM32_FLASH_SIZE (512*1024) + +#elif defined(CONFIG_STM32F7_FLASH_1024KB) + +# define STM32_FLASH_NPAGES 4 +# define STM32_FLASH_SIZE (1024*1024) + +#else +# warning Assuming FLASH size 1024KB + +# define STM32_FLASH_NPAGES 4 +# define STM32_FLASH_SIZE (1024*1024) + +#endif + +/* The STM32F745xx/46xx have mixed page sizes: + * + * Sectors: 0-3: 32 KB + * Sector 4 128 KB + * Sectors: 5-7: 256 KB + * + * We use the largest page size and set the number of pages equal to the + * FLASH size assuming that fixed, largest pages size. + */ + +#define STM32_FLASH_PAGESIZE (256*1024) + + +/* Register Offsets *****************************************************************/ + +#define STM32_FLASH_ACR_OFFSET 0x0000 +#define STM32_FLASH_KEYR_OFFSET 0x0004 +#define STM32_FLASH_OPTKEYR_OFFSET 0x0008 +#define STM32_FLASH_SR_OFFSET 0x000c +#define STM32_FLASH_CR_OFFSET 0x0010 +#define STM32_FLASH_OPTCR_OFFSET 0x0014 +#define STM32_FLASH_OPTCR1_OFFSET 0x0018 + +/* Register Addresses ***************************************************************/ + +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE+STM32_FLASH_ACR_OFFSET) +#define STM32_FLASH_KEYR (STM32_FLASHIF_BASE+STM32_FLASH_KEYR_OFFSET) +#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) +#define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) +#define STM32_FLASH_CR (STM32_FLASHIF_BASE+STM32_FLASH_CR_OFFSET) +#define STM32_FLASH_OPTCR (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR_OFFSET) +#define STM32_FLASH_OPTCR1 (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR1_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ +/* Flash Access Control Register (ACR) */ + +#define FLASH_ACR_LATENCY_SHIFT (0) /* Bits 0-1: Latency */ +#define FLASH_ACR_LATENCY_MASK (7 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* n wait states */ +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 000: Zero wait states */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 001: One wait state */ +# define FLASH_ACR_LATENCY_2 (2 << FLASH_ACR_LATENCY_SHIFT) /* 010: Two wait states */ +# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 011: Three wait states */ +# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 100: Four wait states */ +# define FLASH_ACR_LATENCY_5 (5 << FLASH_ACR_LATENCY_SHIFT) /* 101: Five wait states */ +# define FLASH_ACR_LATENCY_6 (6 << FLASH_ACR_LATENCY_SHIFT) /* 110: Six wait states */ +# define FLASH_ACR_LATENCY_7 (7 << FLASH_ACR_LATENCY_SHIFT) /* 111: Seven wait states */ +#define FLASH_ACR_PRFTEN (1 << 8) /* FLASH prefetch enable */ +#define FLASH_ACR_ARTEN (1 << 9) /* Bit 9: ART Accelerator Enable */ +#define FLASH_ACR_ARTRST (1 << 11) /* Bit 11: ART Accelerator reset */ + +/* Flash Status Register (SR) */ + +#define FLASH_SR_EOP (1 << 0) /* Bit 0: End of operation */ +#define FLASH_SR_OPERR (1 << 1) /* Bit 1: Operation error */ +#define FLASH_SR_WRPERR (1 << 4) /* Bit 4: Write protection error */ +#define FLASH_SR_PGAERR (1 << 5) /* Bit 5: Programming alignment error */ +#define FLASH_SR_PGPERR (1 << 6) /* Bit 6: Programming parallelism error */ +#define FLASH_SR_PGSERR (1 << 7) /* Bit 7: Programming sequence error */ +#define FLASH_SR_BSY (1 << 16) /* Bit 16: Busy */ + +/* Flash Control Register (CR) */ + +#define FLASH_CR_PG (1 << 0) /* Bit 0: Programming */ +#define FLASH_CR_SER (1 << 1) /* Bit 1: Sector Erase */ +#define FLASH_CR_MER (1 << 2) /* Bit 2: Mass Erase sectors 0..11 */ +#define FLASH_CR_SNB_SHIFT (3) /* Bits 3-6: Sector number */ +#define FLASH_CR_SNB_MASK (15 << FLASH_CR_SNB_SHIFT) +# define FLASH_CR_SNB(n) ((uint32_t)(n) << FLASH_CR_SNB_SHIFT) | ((n / 12) << 7)) /* Sector n, n=0..23 */ +#define FLASH_CR_PSIZE_SHIFT (8) /* Bits 8-9: Program size */ +#define FLASH_CR_PSIZE_MASK (3 << FLASH_CR_PSIZE_SHIFT) +# define FLASH_CR_PSIZE_X8 (0 << FLASH_CR_PSIZE_SHIFT) /* Program x8 */ +# define FLASH_CR_PSIZE_X16 (1 << FLASH_CR_PSIZE_SHIFT) /* Program x16 */ +# define FLASH_CR_PSIZE_X32 (2 << FLASH_CR_PSIZE_SHIFT) /* Program x32 */ +# define FLASH_CR_PSIZE_X64 (3 << FLASH_CR_PSIZE_SHIFT) /* Program x64 */ +#define FLASH_CR_STRT (1 << 16) /* Bit 16: Start Erase */ +#define FLASH_CR_EOPIE (1 << 24) /* Bit 24: End of operation interrupt enable */ +#define FLASH_CR_ERRIE (1 << 25) /* Bit 25: Error interrupt enable */ +#define FLASH_CR_LOCK (1 << 31) /* Bit 31: Lock */ +#define FLASH_CR_MER1 (1 << 15) /* Bit 15: Mass Erase sectors 12..23 */ + +/* Flash Option Control Register (OPTCR) */ + +#define FLASH_OPTCR_OPTLOCK (1 << 0) /* Bit 0: Option lock */ +#define FLASH_OPTCR_OPTSTRT (1 << 1) /* Bit 1: Option start */ +#define FLASH_OPTCR_BORLEV_SHIFT (2) /* Bits 2-3: BOR reset Level */ +#define FLASH_OPTCR_BORLEV_MASK (3 << FLASH_OPTCR_BORLEV_SHIFT) +# define FLASH_OPTCR_VBOR3 (0 << FLASH_OPTCR_BORLEV_SHIFT) /* BOR Level 3 */ +# define FLASH_OPTCR_VBOR2 (1 << FLASH_OPTCR_BORLEV_SHIFT) /* BOR Level 2 */ +# define FLASH_OPTCR_VBOR1 (2 << FLASH_OPTCR_BORLEV_SHIFT) /* BOR Level 1 */ +# define FLASH_OPTCR_VBOR0 (3 << FLASH_OPTCR_BORLEV_SHIFT) /* BOR off */ +#define FLASH_OPTCR_USER_SHIFT (4) /* Bits 5-7: User option bytes */ +#define FLASH_OPTCR_USER_MASK (15 << FLASH_OPTCR_USER_SHIFT) +# define FLASH_OPTCR_WWDG_SW (1 << 4) /* Bit 5: WWDG_SW */ +# define FLASH_OPTCR_IWDG_SW (1 << 5) /* Bit 5: IWDG_SW */ +# define FLASH_OPTCR_NRST_STOP (1 << 6) /* Bit 6: nRST_STOP */ +# define FLASH_OPTCR_NRST_STDBY (1 << 7) /* Bit 7: nRST_STDBY */ +#define FLASH_OPTCR_RDP_SHIFT (8) /* Bits 8-15: Read protect */ +#define FLASH_OPTCR_RDP_MASK (0xff << FLASH_OPTCR_RDP_SHIFT) +# define FLASH_OPTCR_RDP(n) ((uint32_t)(n) << FLASH_OPTCR_RDP_SHIFT) +#define FLASH_OPTCR_NWRP_SHIFT (16) /* Bits 16-27: Not write protect */ +#define FLASH_OPTCR_NWRP_MASK (0xfff << FLASH_OPTCR_NWRP_SHIFT) +# define FLASH_OPTCR_NWRP(n) ((uint32_t)(n) << FLASH_OPTCR_NWRP_SHIFT) +#define FLASH_OPTCR_IWDG_STDBY (1 << 30) /* Bit 30: IWDG freeze in stop mode */ +#define FLASH_OPTCR_IWDG_STOP (1 << 31) /* Bit 31: IWDG freeze in standby mode */ + +/* Flash Option Control Register (OPTCR1) */ + +#define FLASH_OPTCR1_BOOTADD0_SHIFT (0) /* Bits 0-15: Boot base address when Boot pin=0 */ +#define FLASH_OPTCR1_BOOTADD0_MASK (0xffff << FLASH_OPTCR1_BOOTADD0_SHIFT) +# define FLASH_OPTCR1_BOOTADD0(n) ((uint32_t)(n) << FLASH_OPTCR1_BOOTADD0_SHIFT) +#define FLASH_OPTCR1_BOOTADD1_SHIFT (16) /* Bits 16-31:Boot base address when Boot pin=1 */ +#define FLASH_OPTCR1_BOOTADD1_MASK (0xffff << FLASH_OPTCR1_BOOTADD1_SHIFT) +# define FLASH_OPTCR1_BOOTADD1(n) ((uint32_t)(n) << FLASH_OPTCR1_BOOTADD1_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM327_CHIP_STM32F74XX75XX_FLASH_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_gpio.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..c996f7d1052226b065fc39140333050598ae890d --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_gpio.h @@ -0,0 +1,419 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32f74xxx75xx_gpio.h + * + * Copyright (C) 2005 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_GPIO_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ +#define STM32_GPIO_BRR_OFFSET 0x0028 /* GPIO port bit reset register */ + +/* Register Addresses ***************************************************************/ + +#if STM32F7_NGPIO > 0 +# define STM32_GPIOA_MODER (STM32_GPIOA_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOA_IDR (STM32_GPIOA_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOA_ODR (STM32_GPIOA_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOA_BSRR (STM32_GPIOA_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOA_LCKR (STM32_GPIOA_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOA_AFRL (STM32_GPIOA_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOA_AFRH (STM32_GPIOA_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOA_BRR (STM32_GPIOA_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 1 +# define STM32_GPIOB_MODER (STM32_GPIOB_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOB_IDR (STM32_GPIOB_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOB_ODR (STM32_GPIOB_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOB_BSRR (STM32_GPIOB_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOB_LCKR (STM32_GPIOB_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOB_AFRL (STM32_GPIOB_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOB_AFRH (STM32_GPIOB_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOB_BRR (STM32_GPIOB_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 2 +# define STM32_GPIOC_MODER (STM32_GPIOC_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOC_IDR (STM32_GPIOC_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOC_ODR (STM32_GPIOC_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOC_BSRR (STM32_GPIOC_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOC_LCKR (STM32_GPIOC_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOC_AFRL (STM32_GPIOC_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOC_AFRH (STM32_GPIOC_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOC_BRR (STM32_GPIOC_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 3 +# define STM32_GPIOD_MODER (STM32_GPIOD_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOD_IDR (STM32_GPIOD_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOD_ODR (STM32_GPIOD_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOD_BSRR (STM32_GPIOD_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOD_LCKR (STM32_GPIOD_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOD_AFRL (STM32_GPIOD_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOD_AFRH (STM32_GPIOD_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOD_BRR (STM32_GPIOD_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 4 +# define STM32_GPIOE_MODER (STM32_GPIOE_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOE_IDR (STM32_GPIOE_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOE_ODR (STM32_GPIOE_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOE_BSRR (STM32_GPIOE_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOE_LCKR (STM32_GPIOE_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOE_AFRL (STM32_GPIOE_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOE_AFRH (STM32_GPIOE_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOE_BRR (STM32_GPIOE_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 5 +# define STM32_GPIOF_MODER (STM32_GPIOF_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOF_IDR (STM32_GPIOF_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOF_ODR (STM32_GPIOF_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOF_BSRR (STM32_GPIOF_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOF_LCKR (STM32_GPIOF_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOF_AFRL (STM32_GPIOF_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOF_AFRH (STM32_GPIOF_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOF_BRR (STM32_GPIOF_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 6 +# define STM32_GPIOG_MODER (STM32_GPIOG_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOG_OTYPER (STM32_GPIOG_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOG_OSPEED (STM32_GPIOG_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOG_PUPDR (STM32_GPIOG_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOG_IDR (STM32_GPIOG_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOG_ODR (STM32_GPIOG_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOG_BSRR (STM32_GPIOG_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOG_LCKR (STM32_GPIOG_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOG_AFRL (STM32_GPIOG_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOG_AFRH (STM32_GPIOG_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOG_BRR (STM32_GPIOG_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 7 +# define STM32_GPIOH_MODER (STM32_GPIOH_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOH_OTYPER (STM32_GPIOH_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOH_OSPEED (STM32_GPIOH_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOH_PUPDR (STM32_GPIOH_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOH_IDR (STM32_GPIOH_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOH_ODR (STM32_GPIOH_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOH_BSRR (STM32_GPIOH_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOH_LCKR (STM32_GPIOH_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOH_AFRL (STM32_GPIOH_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOH_AFRH (STM32_GPIOH_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOH_BRR (STM32_GPIOH_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 8 +# define STM32_GPIOI_MODER (STM32_GPIOI_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOI_OTYPER (STM32_GPIOI_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOI_OSPEED (STM32_GPIOI_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOI_PUPDR (STM32_GPIOI_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOI_IDR (STM32_GPIOI_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOI_ODR (STM32_GPIOI_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOI_BSRR (STM32_GPIOI_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOI_LCKR (STM32_GPIOI_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOI_AFRL (STM32_GPIOI_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOI_AFRH (STM32_GPIOI_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOI_BRR (STM32_GPIOI_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 9 +# define STM32_GPIOJ_MODER (STM32_GPIOJ_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOJ_OTYPER (STM32_GPIOJ_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOJ_OSPEED (STM32_GPIOJ_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOJ_PUPDR (STM32_GPIOJ_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOJ_IDR (STM32_GPIOJ_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOJ_ODR (STM32_GPIOJ_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOJ_BSRR (STM32_GPIOJ_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOJ_LCKR (STM32_GPIOJ_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOJ_AFRL (STM32_GPIOJ_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOJ_AFRH (STM32_GPIOJ_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOJ_BRR (STM32_GPIOJ_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +#if STM32F7_NGPIO > 10 +# define STM32_GPIOK_MODER (STM32_GPIOK_BASE+STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOK_OTYPER (STM32_GPIOK_BASE+STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOK_OSPEED (STM32_GPIOK_BASE+STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOK_PUPDR (STM32_GPIOK_BASE+STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOK_IDR (STM32_GPIOK_BASE+STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOK_ODR (STM32_GPIOK_BASE+STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOK_BSRR (STM32_GPIOK_BASE+STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOK_LCKR (STM32_GPIOK_BASE+STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOK_AFRL (STM32_GPIOK_BASE+STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOK_AFRH (STM32_GPIOK_BASE+STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOK_BRR (STM32_GPIOK_BASE+STM32_GPIO_BRR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (2) /* 50 MHz Fast speed */ +#define GPIO_OSPEED_100MHz (3) /* 100 MHz High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +/* GPIO port bit reset register */ + +#define GPIO_BRR(n) (1 << (n)) + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_GPIO_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..82a5d2242bc036c54485630992d9c2dc3745a972 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/stm3fr2/chip/stm32f74xxx75xxx_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XXX_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb AHB1-2 peripheral blocks */ +#define STM32_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +# define STM32_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3&4 block */ +# define STM32_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32_FSMC_BANK4 0x90000000 /* 0x90000000-0x9fffffff: 256Mb PC CARD */ +#define STM32_AHB3_BASE 0xa0000000 /* 0xa0000000-0xa0001fff: 256Mb AHB3 peripheral block */ +#define STM32_FSMC_BASE5 0xc0000000 /* 0xc0000000-0xcfffffff: 256Mb FSMC */ +#define STM32_FSMC_BASE6 0xc0000000 /* 0xd0000000-0xdfffffff: 256Mb FSMC */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M7 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) +#define STM32_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_FSMC_BANK1) + +/* Code Base Addresses **************************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ +#define STM32_INSTRAM_BASE 0x00000000 /* 0x00000000-0x00003fff: Instruction RAM (ITCM-RAM) */ +#define STM32_SYSMEM_ICTM 0x00100000 /* 0x00100000-0x0010edbf: System memory (ITCM) */ +#define STM32_FLASH_ITCM 0x00200000 /* 0x00200000-0x002fffff: FLASH memory (ITCM) */ +#define STM32_LOADER_BASE 0x01000000 /* 0x01000000- Bootloader */ +#define STM32_FLASH_AXIM 0x08000000 /* 0x08000000-0x080fffff: FLASH memory (AXIM) */ +#define STM32_OPTIONS_BASE 0x1fff0000 /* 0x1ff00000-0x1fff001f: OTP (AXIM) */ + +/* Information Addresses ************************************************************/ + + +#define STM32_SYSMEM_AXIM 0x1ff00000 /* 0x1ff00000-0x1ff0edbf: System memory (AXIM) */ +#define STM32_OTP_ICTM 0x0010f000 /* 0x0010f000-0x0010edbf: OTP (ITCM) */ +#define STM32_OTP_AXIM 0x1ff0f000 /* 0x1ff00000-0x1ff0f41f: OTP (AXIM) */ + +/* SRAM Base Addresses **************************************************************/ + +#define STM32_DTCRAM_BASE 0x20000000 /* 0x20000000-0x2000ffff: DTCM-RAM on TCM interface */ +#define STM32_SRAM1_BASE 0x20010000 /* 0x20010000-0x2004bfff: System SRAM1 */ +#define STM32_SRAM2_BASE 0x2004c000 /* 0x2004c000-0x2004ffff: System SRAM2 */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x40007fff: APB1 */ +#define STM32_APB2_BASE 0x40010000 /* 0x40010000-0x40016bff: APB2 */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x4007ffff: APB1 */ +#define STM32_AHB2_BASE 0x50000000 /* 0x50000000-0x5003ffff: AHB2 */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff: TIM2 */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff: TIM3 */ +#define STM32_TIM4_BASE 0x40000800 /* 0x40000800-0x40000bff: TIM4 */ +#define STM32_TIM5_BASE 0x40000c00 /* 0x40000c00-0x40000fff: TIM5 */ +#define STM32_TIM6_BASE 0x40001000 /* 0x40001000-0x400013ff: TIM6 */ +#define STM32_TIM7_BASE 0x40001400 /* 0x40001400-0x400017ff: TIM7 */ +#define STM32_TIM12_BASE 0x40001800 /* 0x40001800-0x40001bff: TIM12 */ +#define STM32_TIM13_BASE 0x40001c00 /* 0x40001c00-0x40001fff: TIM13 */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000-0x400023ff: TIM14 */ +#define STM32_LPTIM1_BASE 0x40002400 /* 0x40002400-0x400027ff: LPTIM1 */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff: RTC & BKP Registers */ +#define STM32_BKP_BASE 0x40002800 /* 0x40002800-0x40002bff: RTC & BKP Registers */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff: WWDG */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff: IWDG */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff: SPI2 / I2S2 */ +#define STM32_I2S2_BASE 0x40003800 /* 0x40003800-0x40003bff: SPI2 / I2S2 */ +#define STM32_SPI3_BASE 0x40003c00 /* 0x40003c00-0x40003fff: SPI3 / I2S3 */ +#define STM32_I2S3_BASE 0x40003c00 /* 0x40003c00-0x40003fff: SPI3 / I2S3 */ +#define STM32_SPDIFRX_BASE 0x40004000 /* 0x40004000-0x400043ff: SPDIFRX */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff: USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff: USART3 */ +#define STM32_UART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff: UART4 */ +#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff: UART5 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff: I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff: I2C2 */ +#define STM32_I2C3_BASE 0x40005c00 /* 0x40005c00-0x40005fff: I2C3 */ +#define STM32_I2C4_BASE 0x40006000 /* 0x40006000-0x400063ff: I2C4 */ +#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff: CAN1 */ +#define STM32_CAN2_BASE 0x40006800 /* 0x40006800-0x40006bff: CAN2 */ +#define STM32_HDMICEC_BASE 0x40006c00 /* 0x40006c00-0x40006fff: HDMI-CEC */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff: PWR */ +#define STM32_DAC_BASE 0x40007400 /* 0x40007400-0x400077ff: DAC */ +#define STM32_UART7_BASE 0x40007800 /* 0x40007800-0x40007bff: UART7 */ +#define STM32_UART8_BASE 0x40007c00 /* 0x40007c00-0x40007fff: UART8 */ + +/* APB2 Base Addresses **************************************************************/ + +#define STM32_TIM1_BASE 0x40010000 /* 0x40010000-0x400103ff: TIM1 */ +#define STM32_TIM8_BASE 0x40010400 /* 0x40010400-0x400107ff: TIM8 */ +#define STM32_USART1_BASE 0x40011000 /* 0x40011000-0x400113ff: USART1 */ +#define STM32_USART6_BASE 0x40011400 /* 0x40011400-0x400117ff: USART6 */ +#define STM32_ADC_BASE 0x40012000 /* 0x40012000-0x400123ff: ADC1 - ADC2 - ADC3 */ +#define STM32_SDMMC1_BASE 0x40012c00 /* 0x40012c00-0x40012fff: SDMMC1 */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff: SPI1 */ +#define STM32_SPI4_BASE 0x40013400 /* 0x40013400-0x400137ff: SPI4 */ +#define STM32_SYSCFG_BASE 0x40013800 /* 0x40013800-0x40013bff: SYSCFG */ +#define STM32_EXTI_BASE 0x40013c00 /* 0x40013c00-0x40013fff: EXTI */ +#define STM32_TIM9_BASE 0x40014000 /* 0x40014000-0x400143ff: TIM9 */ +#define STM32_TIM10_BASE 0x40014400 /* 0x40014400-0x400147ff: TIM10 */ +#define STM32_TIM11_BASE 0x40014800 /* 0x40014800-0x40014bff: TIM11 */ +#define STM32_SPI5_BASE 0x40015000 /* 0x40015000-0x400153ff: SPI5 */ +#define STM32_SPI6_BASE 0x40015400 /* 0x40015400-0x400157ff: SPI6 */ +#define STM32_SAI1_BASE 0x40015800 /* 0x40015800-0x40015bff: SAI1 */ +#define STM32_SAI2_BASE 0x40015c00 /* 0x40015c00-0x40015fff: SAI2 */ +#define STM32_LCDTFT_BASE 0x40016800 /* 0x40016800-0x40016bff: LCD-TFT */ + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32_GPIOA_BASE 0x40020000 /* 0x40020000-0x400203ff: GPIOA */ +#define STM32_GPIOB_BASE 0x40020400 /* 0x40020400-0x400207ff: GPIOB */ +#define STM32_GPIOC_BASE 0x40020800 /* 0x40020800-0x40020bff: GPIOC */ +#define STM32_GPIOD_BASE 0x40020c00 /* 0x40020c00-0x40020fff: GPIOD */ +#define STM32_GPIOE_BASE 0x40021000 /* 0x40021000-0x400213ff: GPIOE */ +#define STM32_GPIOF_BASE 0x40021400 /* 0x40021400-0x400217ff: GPIOF */ +#define STM32_GPIOG_BASE 0x40021800 /* 0x40021800-0x40021bff: GPIOG */ +#define STM32_GPIOH_BASE 0x40021c00 /* 0x40021c00-0x40021fff: GPIOH */ +#define STM32_GPIOI_BASE 0x40022000 /* 0x40022000-0x400223ff: GPIOI */ +#define STM32_GPIOJ_BASE 0x40022400 /* 0x40022400-0x400227ff: GPIOJ */ +#define STM32_GPIOK_BASE 0x40022800 /* 0x40022800-0x40022bff: GPIOK */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ +#define STM32_RCC_BASE 0x40023800 /* 0x40023800-0x40023bff: RCC */ +#define STM32_FLASHIF_BASE 0x40023c00 /* 0x40023c00-0x40023fff: Flash interface */ +#define STM32_BKPSRAM_BASE 0x40024000 /* 0x40024000-0x40024fff: BKPSRAM */ +#define STM32_DMA1_BASE 0x40026000 /* 0x40026000-0x400263ff: DMA1 */ +#define STM32_DMA2_BASE 0x40026400 /* 0x40026400-0x400267ff: DMA2 */ +#define STM32_ETHMAC_BASE 0x40028000 /* 0x40028000-0x400293ff: ETHERNET MAC */ +#define STM32_DMA2D_BASE 0x4002b000 /* 0x4002b000-0x4002Bbff: Chrom-ART (DMA2D) */ +#define STM32_USBOTGHS_BASE 0x40040000 /* 0x40040000-0x4007ffff: USB OTG HS */ + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32_USBOTGFS_BASE 0x50000000 /* 0x50000000-0x5003ffff: USB OTG FS */ +#define STM32_DCMI_BASE 0x50050000 /* 0x50050000-0x500503ff: DCMI */ +#define STM32_CRYP_BASE 0x50060000 /* 0x50060000-0x500603ff: CRYP */ +#define STM32_HASH_BASE 0x50060400 /* 0x50060400-0x500607ff: HASH */ +#define STM32_RNG_BASE 0x50060800 /* 0x50060800-0x50060bff: RNG */ + +/* AHB3 Base Addresses **************************************************************/ + +#define STM32_FMCBANK1_BASE 0x60000000 /* 0x60000000-0x6fffffff: FMC bank 1 */ +#define STM32_FMCBANK2_BASE 0x70000000 /* 0x70000000-0x7fffffff: FMC bank 2 */ +#define STM32_FMCBANK3_BASE 0x80000000 /* 0x80000000-0x8fffffff: FMC bank 3 */ +#define STM32_FMCBANK4_BASE 0x90000000 /* 0x90000000-0x9fffffff: FMC bank 4 */ +#define STM32_FSMC_BASE 0xa0000000 /* 0xa0000000-0xa0000fff: FMC control registers */ +#define STM32_QUADSPI_BASE 0xa0001000 /* 0xa0001000-0xa0001fff: QuadSPI Control */ +#define STM32_FMCBANK5_BASE 0xc0000000 /* 0xc0000000-0xcfffffff: FMC bank 5 */ +#define STM32_FMCBANK6_BASE 0xd0000000 /* 0xd0000000-0xdfffffff: FMC bank 6 */ + +/* Cortex-M7 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XXX75XXX_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..64b68653d188a853236f8107287e0e6c4b904f98 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h @@ -0,0 +1,1182 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_PINMAP_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32_gpio.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32F40xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN8 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN10) + +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN14 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN15 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) + +/* CAN */ + +#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN1_RX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) + +#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_CAN1_TX_4 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) + +#define GPIO_CAN2_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_CAN2_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_CAN2_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN2_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +/* DAC -" Once the DAC channel is enabled, the corresponding GPIO pin + * (PA4 or PA5) is automatically connected to the analog converter output + * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin + * should first be configured to analog (AIN)". + */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* Digital Camera Interface (DCMI) */ + +#define GPIO_DCMI_D0_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN9) +#define GPIO_DCMI_D0_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_DCMI_D0_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN9) +#define GPIO_DCMI_D1_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN10) +#define GPIO_DCMI_D1_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_DCMI_D1_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN10) +#define GPIO_DCMI_D2_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN8) +#define GPIO_DCMI_D2_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN0) +#define GPIO_DCMI_D2_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN10) +#define GPIO_DCMI_D2_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN11) +#define GPIO_DCMI_D3_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN9) +#define GPIO_DCMI_D3_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN1) +#define GPIO_DCMI_D3_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN11) +#define GPIO_DCMI_D3_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN12) +#define GPIO_DCMI_D4_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_DCMI_D4_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_DCMI_D4_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN14) +#define GPIO_DCMI_D5_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_DCMI_D5_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN3) +#define GPIO_DCMI_D5_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN4) +#define GPIO_DCMI_D6_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_DCMI_D6_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_DCMI_D6_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN6) +#define GPIO_DCMI_D7_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_DCMI_D7_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_DCMI_D7_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN7) +#define GPIO_DCMI_D8_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_DCMI_D8_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN6) +#define GPIO_DCMI_D8_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN1) +#define GPIO_DCMI_D9_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_DCMI_D9_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN7) +#define GPIO_DCMI_D9_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN2) +#define GPIO_DCMI_D10_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_DCMI_D10_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6) +#define GPIO_DCMI_D10_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN3) +#define GPIO_DCMI_D11_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN2) +#define GPIO_DCMI_D11_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN10) +#define GPIO_DCMI_D11_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN15) +#define GPIO_DCMI_D12_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN11) +#define GPIO_DCMI_D12_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN6) +#define GPIO_DCMI_D13_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN15) +#define GPIO_DCMI_D13_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN7) +#define GPIO_DCMI_D13_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN0) +#define GPIO_DCMI_HSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DCMI_HSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTH|GPIO_PIN8) +#define GPIO_DCMI_PIXCK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_DCMI_VSYNC_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN7) +#define GPIO_DCMI_VSYNC_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN9) +#define GPIO_DCMI_VSYNC_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTI|GPIO_PIN5) + +/* Ethernet MAC */ + +#define GPIO_ETH_MDC (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ETH_MDIO (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ETH_MII_COL_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ETH_MII_COL_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_ETH_MII_CRS_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ETH_MII_CRS_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_ETH_MII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH_MII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH_MII_RXD2_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ETH_MII_RXD2_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_ETH_MII_RXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ETH_MII_RXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN7) +#define GPIO_ETH_MII_RX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH_MII_RX_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH_MII_RX_ER_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_ETH_MII_RX_ER_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_ETH_MII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_MII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_ETH_MII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_MII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_ETH_MII_TXD2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ETH_MII_TXD3_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_ETH_MII_TXD3_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN2) +#define GPIO_ETH_MII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_MII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_MII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#define GPIO_ETH_PPS_OUT_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_ETH_PPS_OUT_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN8) + +#define GPIO_ETH_RMII_CRS_DV (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH_RMII_REF_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH_RMII_RXD0 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH_RMII_RXD1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH_RMII_TXD0_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH_RMII_TXD0_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_ETH_RMII_TXD1_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH_RMII_TXD1_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_ETH_RMII_TX_CLK (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH_RMII_TX_EN_1 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH_RMII_TX_EN_2 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) + +/* Event outputs */ + +#define GPIO_PA0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN1) +#define GPIO_PA2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN2) +#define GPIO_PA3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN3) +#define GPIO_PA4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN4) +#define GPIO_PA5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN5) +#define GPIO_PA6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN6) +#define GPIO_PA7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN7) +#define GPIO_PA8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN8) +#define GPIO_PA9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN9) +#define GPIO_PA10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN10) +#define GPIO_PA11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN11) +#define GPIO_PA12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN12) +#define GPIO_PA13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_PB0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN0) +#define GPIO_PB1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN1) +#define GPIO_PB2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN2) +#define GPIO_PB3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN4) +#define GPIO_PB5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN5) +#define GPIO_PB6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN6) +#define GPIO_PB7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN7) +#define GPIO_PB8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN8) +#define GPIO_PB9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN9) +#define GPIO_PB10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN10) +#define GPIO_PB11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN11) +#define GPIO_PB12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN12) +#define GPIO_PB13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN13) +#define GPIO_PB14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN14) +#define GPIO_PB15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN15) + +#define GPIO_PC0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN0) +#define GPIO_PC1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN1) +#define GPIO_PC2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN2) +#define GPIO_PC3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN3) +#define GPIO_PC4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN4) +#define GPIO_PC5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN5) +#define GPIO_PC6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN6) +#define GPIO_PC7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN7) +#define GPIO_PC8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN8) +#define GPIO_PC9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN9) +#define GPIO_PC10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN10) +#define GPIO_PC11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PC12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN12) +#define GPIO_PC13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN13) +#define GPIO_PC14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN14) +#define GPIO_PC15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN15) + +#define GPIO_PD0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN0) +#define GPIO_PD1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN1) +#define GPIO_PD2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN2) +#define GPIO_PD3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN3) +#define GPIO_PD4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN4) +#define GPIO_PD5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN5) +#define GPIO_PD6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PD7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN7) +#define GPIO_PD8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN8) +#define GPIO_PD9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN9) +#define GPIO_PD10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN10) +#define GPIO_PD11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN11) +#define GPIO_PD12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN12) +#define GPIO_PD13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN13) +#define GPIO_PD14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN14) +#define GPIO_PD15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN15) + +#define GPIO_PE0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN0) +#define GPIO_PE1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN1) +#define GPIO_PE2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN2) +#define GPIO_PE3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN3) +#define GPIO_PE4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN4) +#define GPIO_PE5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN5) +#define GPIO_PE6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN6) +#define GPIO_PE7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN7) +#define GPIO_PE8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN8) +#define GPIO_PE9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN9) +#define GPIO_PE10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN10) +#define GPIO_PE11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN11) +#define GPIO_PE12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN12) +#define GPIO_PE13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN13) +#define GPIO_PE14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN14) +#define GPIO_PE15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN15) + +#define GPIO_PF0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN0) +#define GPIO_PF1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN1) +#define GPIO_PF2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN2) +#define GPIO_PF3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN3) +#define GPIO_PF4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN4) +#define GPIO_PF5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN5) +#define GPIO_PF6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN6) +#define GPIO_PF7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN7) +#define GPIO_PF8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN8) +#define GPIO_PF9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN9) +#define GPIO_PF10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN10) +#define GPIO_PF11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN11) +#define GPIO_PF12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN12) +#define GPIO_PF13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN13) +#define GPIO_PF14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN14) +#define GPIO_PF15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN15) + +#define GPIO_PG0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN0) +#define GPIO_PG1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN1) +#define GPIO_PG2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN2) +#define GPIO_PG3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN3) +#define GPIO_PG4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN4) +#define GPIO_PG5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN5) +#define GPIO_PG6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN6) +#define GPIO_PG7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN7) +#define GPIO_PG8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN8) +#define GPIO_PG9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN9) +#define GPIO_PG10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN10) +#define GPIO_PG11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN11) +#define GPIO_PG12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN12) +#define GPIO_PG13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN13) +#define GPIO_PG14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN14) +#define GPIO_PG15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN15) + +#define GPIO_PH0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN0) +#define GPIO_PH1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN1) +#define GPIO_PH2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN2) +#define GPIO_PH3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN3) +#define GPIO_PH4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN4) +#define GPIO_PH5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN5) +#define GPIO_PH6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN6) +#define GPIO_PH7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN7) +#define GPIO_PH8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN8) +#define GPIO_PH9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN9) +#define GPIO_PH10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN10) +#define GPIO_PH11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN11) +#define GPIO_PH12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN12) +#define GPIO_PH13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN13) +#define GPIO_PH14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN14) +#define GPIO_PH15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN15) + +#define GPIO_PI0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN0) +#define GPIO_PI1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN1) +#define GPIO_PI2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN2) +#define GPIO_PI3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN3) +#define GPIO_PI4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN4) +#define GPIO_PI5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN5) +#define GPIO_PI6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN6) +#define GPIO_PI7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN7) +#define GPIO_PI8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN8) +#define GPIO_PI9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN9) +#define GPIO_PI10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN10) +#define GPIO_PI11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN11) +#define GPIO_PI12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN12) +#define GPIO_PI13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN13) +#define GPIO_PI14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN14) +#define GPIO_PI15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN15) + +#define GPIO_PJ0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN0) +#define GPIO_PJ1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN1) +#define GPIO_PJ2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN2) +#define GPIO_PJ3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN3) +#define GPIO_PJ4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN4) +#define GPIO_PJ5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN5) +#define GPIO_PJ6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN6) +#define GPIO_PJ7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN7) +#define GPIO_PJ8_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN8) +#define GPIO_PJ9_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN9) +#define GPIO_PJ10_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN10) +#define GPIO_PJ11_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN11) +#define GPIO_PJ12_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN12) +#define GPIO_PJ13_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN13) +#define GPIO_PJ14_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN14) +#define GPIO_PJ15_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTJ|GPIO_PIN15) + +#define GPIO_PK0_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN0) +#define GPIO_PK1_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN1) +#define GPIO_PK2_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN2) +#define GPIO_PK3_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN3) +#define GPIO_PK4_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN4) +#define GPIO_PK5_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN5) +#define GPIO_PK6_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN6) +#define GPIO_PK7_EVENTOUT (GPIO_ALT|GPIO_AF15|GPIO_PORTK|GPIO_PIN7) + +/* Flexible Static Memory Controller (FSMC) */ + +#define GPIO_FSMC_A0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FSMC_A1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FSMC_A2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FSMC_A3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FSMC_A4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FSMC_A5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FSMC_A6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FSMC_A7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FSMC_A8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FSMC_A9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FSMC_A10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FSMC_A11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FSMC_A12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FSMC_A13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FSMC_A14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FSMC_A15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FSMC_A16 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FSMC_A17 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FSMC_A18 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FSMC_A19 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FSMC_A20 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FSMC_A21 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FSMC_A22 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FSMC_A23 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FSMC_A24 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FSMC_A25 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_FSMC_ALE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FSMC_BA0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FSMC_BA1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FSMC_CLE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FSMC_CLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FSMC_D0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FSMC_D1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FSMC_D2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FSMC_D3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FSMC_D4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FSMC_D5 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FSMC_D6 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FSMC_D7 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FSMC_D8 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FSMC_D9 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FSMC_D10 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FSMC_D11 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FSMC_D12 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FSMC_D13 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FSMC_D14 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FSMC_D15 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN10) +#define GPIO_FSMC_D16 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN8) +#define GPIO_FSMC_D17 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN9) +#define GPIO_FSMC_D18 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN10) +#define GPIO_FSMC_D19 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN11) +#define GPIO_FSMC_D20 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN12) +#define GPIO_FSMC_D21 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN13) +#define GPIO_FSMC_D22 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN14) +#define GPIO_FSMC_D23 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN15) +#define GPIO_FSMC_D24 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN0) +#define GPIO_FSMC_D25 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN1) +#define GPIO_FSMC_D26 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN2) +#define GPIO_FSMC_D27 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN3) +#define GPIO_FSMC_D28 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN6) +#define GPIO_FSMC_D29 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN7) +#define GPIO_FSMC_D30 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN9) +#define GPIO_FSMC_D31 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN10) +#define GPIO_FSMC_INT (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FSMC_NBL0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FSMC_NBL1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FSMC_NBL2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN4) +#define GPIO_FSMC_NBL3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTI|GPIO_PIN5) +#define GPIO_FSMC_NCE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FSMC_NE1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FSMC_NE2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FSMC_NE3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FSMC_NE4 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FSMC_NL (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FSMC_NOE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FSMC_NWAIT (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FSMC_NWE (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN5) +#define GPIO_FSMC_SDCKE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_FSMC_SDCKE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN5) +#define GPIO_FSMC_SDCKE0_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN2) +#define GPIO_FSMC_SDCKE1_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_FSMC_SDCKE1_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN7) +#define GPIO_FSMC_SDCLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN8) +#define GPIO_FSMC_SDNCAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN15) +#define GPIO_FSMC_SDNE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_FSMC_SDNE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN4) +#define GPIO_FSMC_SDNE0_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN3) +#define GPIO_FSMC_SDNE1_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN6) +#define GPIO_FSMC_SDNE1_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN6) +#define GPIO_FSMC_SDNRAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN11) +#define GPIO_FSMC_SDNWE_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_FSMC_SDNWE_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN0) +#define GPIO_FSMC_SDNWE_3 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN5) + +/* HDMI-CEC Controller */ + +#define GPIO_HDMICEC_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN6) +#define GPIO_HDMICEC_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN15) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN4) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN5) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C2_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) + +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN8) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) + +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11) +#define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) + +/* I2S */ + +#define GPIO_I2S1_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +#define GPIO_I2S1_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S1_MCK (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN4) +#define GPIO_I2S1_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2S1_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S1_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2S1_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_I2S2_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2S2_CK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2S2_CK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_CK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN3) +#define GPIO_I2S2_CK_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN1) +#define GPIO_I2S2_MCK (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_I2S2_SD_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2S2_SD_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN3) +#define GPIO_I2S2_SD_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2S2_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2S2_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN0) +#define GPIO_I2S2_WS_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) + +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_MCK (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SD_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN6) +#define GPIO_I2S3_SD_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SD_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_SD_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN2) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2S3_WS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_I2S_CKIN (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) + +/* JTAG */ + +#define GPIO_JTCK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_JTMS (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_NJTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) + +#define GPIO_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_SWDIO (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) + +/* LCD-TFT Display Controller (LTDC) */ + +#define GPIO_LTDC_R0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_LTDC_R0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_LTDC_R0_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN15) +#define GPIO_LTDC_R1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LTDC_R1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_LTDC_R1_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN0) +#define GPIO_LTDC_R2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LTDC_R2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LTDC_R2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN8) +#define GPIO_LTDC_R2_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN1) +#define GPIO_LTDC_R3_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_LTDC_R3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN2) +#define GPIO_LTDC_R3_1 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LTDC_R4_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_LTDC_R4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_LTDC_R4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_LTDC_R4_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN3) +#define GPIO_LTDC_R5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_LTDC_R5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LTDC_R5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_LTDC_R5_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN4) +#define GPIO_LTDC_R6_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LTDC_R6_2 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LTDC_R6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_LTDC_R6_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN5) +#define GPIO_LTDC_R7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN15) +#define GPIO_LTDC_R7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +#define GPIO_LTDC_R7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN6) + +#define GPIO_LTDC_B0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN4) +#define GPIO_LTDC_B0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_LTDC_B0_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN12) +#define GPIO_LTDC_B1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +#define GPIO_LTDC_B1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN13) +#define GPIO_LTDC_B2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +#define GPIO_LTDC_B2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +#define GPIO_LTDC_B2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN14) +#define GPIO_LTDC_B3_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) +#define GPIO_LTDC_B3_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#define GPIO_LTDC_B3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN15) +#define GPIO_LTDC_B4_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN12) +#define GPIO_LTDC_B4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN4) +#define GPIO_LTDC_B4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN3) +#define GPIO_LTDC_B4_4 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +#define GPIO_LTDC_B5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LTDC_B5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_LTDC_B5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN4) +#define GPIO_LTDC_B6_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_LTDC_B6_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_LTDC_B6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN5) +#define GPIO_LTDC_B7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_LTDC_B7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_LTDC_B7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN6) + +#define GPIO_LTDC_G0_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +#define GPIO_LTDC_G0_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN7) +#define GPIO_LTDC_G1_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) +#define GPIO_LTDC_G1_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN8) +#define GPIO_LTDC_G2_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LTDC_G2_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) +#define GPIO_LTDC_G2_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN9) +#define GPIO_LTDC_G3_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +#define GPIO_LTDC_G3_2 (GPIO_ALT|GPIO_AF9 |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +#define GPIO_LTDC_G3_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN14) +#define GPIO_LTDC_G3_4 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN10) +#define GPIO_LTDC_G4_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LTDC_G4_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN15) +#define GPIO_LTDC_G4_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTJ|GPIO_PIN11) +#define GPIO_LTDC_G5_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LTDC_G5_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) +#define GPIO_LTDC_G5_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN0) +#define GPIO_LTDC_G6_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_LTDC_G6_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN1) +#define GPIO_LTDC_G6_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN1) +#define GPIO_LTDC_G7_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN3) +#define GPIO_LTDC_G7_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_LTDC_G7_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN2) + +#define GPIO_LTDC_HSYNC_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_LTDC_HSYNC_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_LTDC_HSYNC_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN12) +#define GPIO_LTDC_VSYNC_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) +#define GPIO_LTDC_VSYNC_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_LTDC_VSYNC_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN13) +#define GPIO_LTDC_CLK_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_LTDC_CLK_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN7) +#define GPIO_LTDC_CLK_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN14) +#define GPIO_LTDC_DE_1 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_LTDC_DE_2 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN10) +#define GPIO_LTDC_DE_3 (GPIO_ALT|GPIO_AF14|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTK|GPIO_PIN7) + +/* Low Power Timer */ + +#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LPTIM1_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN14) +#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM1_IN1_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN12) +#define GPIO_LPTIM1_IN2_3 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN1) +#define GPIO_LPTIM1_IN2_4 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN2) +#define GPIO_LPTIM1_OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPTIM1_OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) + +/* Clocks outputs */ + +#define GPIO_MCO1 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO2 (GPIO_ALT|GPIO_AF0|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) + +/* OTG FS/HS (VBUS PA9 is not an alternate configuration) */ + +#define GPIO_OTGFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTGFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTGFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTGFS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) + +#define GPIO_OTGHSFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_OTGHSFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_OTGHSFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_OTGHS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_OTGHS_ULPI_CK (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_D0 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_D1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_OTGHS_ULPI_D2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OTGHS_ULPI_D3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OTGHS_ULPI_D4 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#define GPIO_OTGHS_ULPI_D5 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTGHS_ULPI_D6 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN13) +#define GPIO_OTGHS_ULPI_D7 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN5) +#define GPIO_OTGHS_ULPI_DIR_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN2) +#define GPIO_OTGHS_ULPI_DIR_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN11) +#define GPIO_OTGHS_ULPI_NXT_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN3) +#define GPIO_OTGHS_ULPI_NXT_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN4) +#define GPIO_OTGHS_ULPI_STP (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN0) + +/* QuadSPI */ + +#define GPIO_QUADSPI_BK1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN8) +#define GPIO_QUADSPI_BK1_IO0_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN9) +#define GPIO_QUADSPI_BK1_IO0_3 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN11) +#define GPIO_QUADSPI_BK1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN9) +#define GPIO_QUADSPI_BK1_IO1_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN10) +#define GPIO_QUADSPI_BK1_IO1_3 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN12) +#define GPIO_QUADSPI_BK1_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN2) +#define GPIO_QUADSPI_BK1_IO2_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN7) +#define GPIO_QUADSPI_BK1_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTA|GPIO_PIN1) +#define GPIO_QUADSPI_BK1_IO3_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN13) +#define GPIO_QUADSPI_BK1_IO3_3 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN6) +#define GPIO_QUADSPI_BK1_NCS (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_QUADSPI_BK2_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN7) +#define GPIO_QUADSPI_BK2_IO0_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTH|GPIO_PIN2) +#define GPIO_QUADSPI_BK2_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN8) +#define GPIO_QUADSPI_BK2_IO1_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTH|GPIO_PIN3) +#define GPIO_QUADSPI_BK2_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN9) +#define GPIO_QUADSPI_BK2_IO2_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN9) +#define GPIO_QUADSPI_BK2_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10) +#define GPIO_QUADSPI_BK2_IO3_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN14) +#define GPIO_QUADSPI_BK2_NCS (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN11) + +#define GPIO_QUADSPI_CLK (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN2) + +/* RTC */ + +#define GPIO_RTC_REFIN (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN15) + +/* Serial Audio Interface */ + +#define GPIO_SAI1_FS_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SAI1_FS_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SAI1_MCLK_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN2) +#define GPIO_SAI1_MCLK_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN7) +#define GPIO_SAI1_SCK_A (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SAI1_SCK_B (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SAI1_SD_A_4 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN3) +#define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SAI2_FS_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN12) +#define GPIO_SAI2_FS_A_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN7) +#define GPIO_SAI2_FS_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SAI2_FS_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SAI2_FS_B_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +#define GPIO_SAI2_FS_B_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN0) +#define GPIO_SAI2_MCLK_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN0) +#define GPIO_SAI2_MCLK_A_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN4) +#define GPIO_SAI2_MCLK_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN1) +#define GPIO_SAI2_MCLK_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14) +#define GPIO_SAI2_MCLK_B_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI2_MCLK_B_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN3) +#define GPIO_SAI2_SCK_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN13) +#define GPIO_SAI2_SCK_A_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN5) +#define GPIO_SAI2_SCK_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SAI2_SCK_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN2) +#define GPIO_SAI2_SCK_B_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN2) +#define GPIO_SAI2_SD_A_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SAI2_SD_A_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN6) +#define GPIO_SAI2_SD_B_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN0) +#define GPIO_SAI2_SD_B_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SAI2_SD_B_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN11) +#define GPIO_SAI2_SD_B_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN10) + +/* SD/MMC */ + +#define GPIO_SDMMC1_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDMMC1_CMD (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDMMC1_D0 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDMMC1_D1 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDMMC1_D2 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDMMC1_D3 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDMMC1_D4 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_D5 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D6 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D7 (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) + +/* SPDIFRX */ + +#define GPIO_SPDIFRX_IN0_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN11) +#define GPIO_SPDIFRX_IN0_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SPDIFRX_IN1_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPDIFRX_IN1_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN8) +#define GPIO_SPDIFRX_IN2_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN8) +#define GPIO_SPDIFRX_IN2_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN4) +#define GPIO_SPDIFRX_IN3_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SPDIFRX_IN3_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN5) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN2) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN3) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN0) +#define GPIO_SPI2_NSS_4 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTI|GPIO_PIN1) + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_SPI4_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SPI4_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SPI4_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SPI4_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN14) +#define GPIO_SPI4_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SPI4_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SPI4_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN2) +#define GPIO_SPI4_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTE|GPIO_PIN12) + +#define GPIO_SPI5_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SPI5_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN7) +#define GPIO_SPI5_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SPI5_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN11) +#define GPIO_SPI5_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SPI5_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN5) +#define GPIO_SPI5_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTF|GPIO_PIN7) +#define GPIO_SPI5_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTH|GPIO_PIN6) + +#define GPIO_SPI6_MISO (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPI6_MOSI (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN14) +#define GPIO_SPI6_NSS (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN8) +#define GPIO_SPI6_SCK (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTG|GPIO_PIN13) + +/* Timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) + +#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) + +#define GPIO_TIM5_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) + +#define GPIO_TIM5_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) + +#define GPIO_TIM5_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) + +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4) +#define GPIO_TIM8_BKIN2_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM8_BKIN2_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN1) +#define GPIO_TIM8_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13) +#define GPIO_TIM8_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH2N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN14) +#define GPIO_TIM8_CH3IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15) +#define GPIO_TIM8_CH4IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3) + +#define GPIO_TIM9_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM9_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM9_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM9_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM9_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) + +#define GPIO_TIM10_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM10_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM10_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) + +#define GPIO_TIM11_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM11_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM11_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_TIM12_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6) +#define GPIO_TIM12_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM12_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) + +#define GPIO_TIM12_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM12_CH2IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9) +#define GPIO_TIM12_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM12_CH2OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) + +#define GPIO_TIM13_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM13_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM13_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) + +#define GPIO_TIM14_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM14_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM14_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) + +/* Trace */ + +#define GPIO_TRACECLK (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN1) +#define GPIO_TRACED0_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED0_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN13) +#define GPIO_TRACED1_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TRACED1_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED1_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN14) +#define GPIO_TRACED2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN2) +#define GPIO_TRACED2_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN12) +#define GPIO_TRACED3_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +#define GPIO_TRACESWO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) + +/* UARTs/USARTs */ + +#define GPIO_USART1_CK (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN5) + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) + +#define GPIO_UART4_CTS (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN0) +#define GPIO_UART4_RTS (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN15) +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) + +#define GPIO_UART5_CTS (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN9) +#define GPIO_UART5_RTS (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN8) +#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) + +#define GPIO_USART6_CK_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN8) +#define GPIO_USART6_CK_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN7) +#define GPIO_USART6_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART6_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN15) +#define GPIO_USART6_RTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN12) +#define GPIO_USART6_RTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN8) +#define GPIO_USART6_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_USART6_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART6_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_USART6_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) + +#define GPIO_UART7_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTE|GPIO_PIN10) +#define GPIO_UART7_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTF|GPIO_PIN9) +#define GPIO_UART7_RTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTE|GPIO_PIN9) +#define GPIO_UART7_RTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTF|GPIO_PIN8) +#define GPIO_UART7_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN7) +#define GPIO_UART7_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_UART7_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN8) +#define GPIO_UART7_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_UART8_CTS (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN14) +#define GPIO_UART8_RTS (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN15) +#define GPIO_UART8_RX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN0) +#define GPIO_UART8_TX (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN1) + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_PINMAP_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pwr.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..e7c58b19ff57c720cad80b2dc006a79df8750aaa --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pwr.h @@ -0,0 +1,158 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_pwr.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_PWR_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_PWR_CR1_OFFSET 0x0000 /* Power control register 1 */ +#define STM32_PWR_CSR1_OFFSET 0x0004 /* Power control/status register 1 */ +#define STM32_PWR_CR2_OFFSET 0x0008 /* Power control register 1 */ +#define STM32_PWR_CSR2_OFFSET 0x000c /* Power control/status register 1 */ + +/* Register Addresses ***************************************************************/ + +#define STM32_PWR_CR1 (STM32_PWR_BASE+STM32_PWR_CR1_OFFSET) +#define STM32_PWR_CSR1 (STM32_PWR_BASE+STM32_PWR_CSR1_OFFSET) +#define STM32_PWR_CR2 (STM32_PWR_BASE+STM32_PWR_CR2_OFFSET) +#define STM32_PWR_CSR2 (STM32_PWR_BASE+STM32_PWR_CSR2_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Power control register 1 */ + +#define PWR_CR1_LPDS (1 << 0) /* Bit 0: Low-Power Deepsleep/sleep; low power run */ +#define PWR_CR1_PDDS (1 << 1) /* Bit 1: Power Down Deepsleep */ +#define PWR_CR1_CSBF (1 << 3) /* Bit 3: Clear Standby Flag */ +#define PWR_CR1_PVDE (1 << 4) /* Bit 4: Power Voltage Detector Enable */ +#define PWR_CR1_PLS_SHIFT (5) /* Bits 7-5: PVD Level Selection */ +#define PWR_CR1_PLS_MASK (7 << PWR_CR1_PLS_SHIFT) +# define PWR_CR1_2p0V (0 << PWR_CR1_PLS_SHIFT) /* 000: 2.0V */ +# define PWR_CR1_2p1V (1 << PWR_CR1_PLS_SHIFT) /* 001: 2.1V */ +# define PWR_CR1_2p3V (2 << PWR_CR1_PLS_SHIFT) /* 010: 2.3V */ +# define PWR_CR1_2p5V (3 << PWR_CR1_PLS_SHIFT) /* 011: 2.5V */ +# define PWR_CR1_2p6V (4 << PWR_CR1_PLS_SHIFT) /* 100: 2.6V */ +# define PWR_CR1_2p7V (5 << PWR_CR1_PLS_SHIFT) /* 101: 2.7V */ +# define PWR_CR1_2p8V (6 << PWR_CR1_PLS_SHIFT) /* 110: 2.8V */ +# define PWR_CR1_2p9V (7 << PWR_CR1_PLS_SHIFT) /* 111: 2.9V */ +#define PWR_CR1_DBP (1 << 8) /* Bit 8: Disable Backup Domain write protection */ +#define PWR_CR1_FPDS (1 << 9) /* Bit 9: Flash power down in Stop mode */ +#define PWR_CR1_LPUDS (1 << 10) /* Bit 10: Low-power regulator in deepsleep under-drive mode */ +#define PWR_CR1_MRUDS (1 << 11) /* Bit 11: Main regulator in deepsleep under-drive mode */ +#define PWR_CR1_ADCDC1 (1 << 13) /* Bit 13: see AN4073 for details */ +#define PWR_CR1_VOS_SHIFT (14) /* Bits 14-15: Regulator voltage scaling output selection */ +#define PWR_CR1_VOS_MASK (3 << PWR_CR1_VOS_SHIFT) +# define PWR_CR1_VOS_SCALE_3 (1 << PWR_CR1_VOS_SHIFT) /* Fmax = 144MHz */ +# define PWR_CR1_VOS_SCALE_2 (2 << PWR_CR1_VOS_SHIFT) /* Fmax = 168/180MHz */ +# define PWR_CR1_VOS_SCALE_1 (3 << PWR_CR1_VOS_SHIFT) /* Fmax = 180/216MHz */ +#define PWR_CR1_ODEN (1 << 16) /* Bit 16: Over Drive enable */ +#define PWR_CR1_ODSWEN (1 << 17) /* Bit 17: Over Drive switch enabled */ +#define PWR_CR1_UDEN_SHIFT (18) /* Bits 18-19: Under-drive enable in stop mode */ +#define PWR_CR1_UDEN_MASK (3 << PWR_CR1_UDEN_SHIFT) +# define PWR_CR1_UDEN_DISABLE (0 << PWR_CR1_UDEN_SHIFT) /* Under-drive disable */ +# define PWR_CR1_UDEN_ENABLE (3 << PWR_CR1_UDEN_SHIFT) /* Under-drive enable */ + +/* Power control/status register 1 */ + +#define PWR_CSR1_WUIF (1 << 0) /* Bit 0: Wakeup internal flag */ +#define PWR_CSR1_SBF (1 << 1) /* Bit 1: Standby flag */ +#define PWR_CSR1_PVDO (1 << 2) /* Bit 2: PVD Output */ +#define PWR_CSR1_BRR (1 << 3) /* Bit 3: Backup regulator ready */ +#define PWR_CSR1_BRE (1 << 9) /* Bit 9: Backup regulator enable */ +#define PWR_CSR1_VOSRDY (1 << 14) /* Bit 14: Regulator voltage scaling output selection ready bite */ +#define PWR_CSR1_ODRDY (1 << 16) /* Bit 16: Over Drive generator ready */ +#define PWR_CSR1_ODSWRDY (1 << 17) /* Bit 17: Over Drive Switch ready */ +#define PWR_CSR1_UDSRDY_SHIFT (18) /* Bits 18-19: Under-drive ready flag */ +#define PWR_CSR1_UDSRDY_MASK (3 << PWR_CSR1_UDSRDY_SHIFT) +# define PWR_CSR1_UDSRDY_DISAB (0 << PWR_CSR1_UDSRDY_SHIFT) /* Under-drive is disabled */ +# define PWR_CSR1_UDSRDY_STOP (3 << PWR_CSR1_UDSRDY_SHIFT) /* Under-drive mode is activated in Stop mode */ + +/* Power control register 2 */ + +#define PWR_CR2_CWUPF1 (1 << 0) /* Bit 0: Clear Wakeup Pin flag for PA0 */ +#define PWR_CR2_CWUPF2 (1 << 1) /* Bit 1: Clear Wakeup Pin flag for PA2 */ +#define PWR_CR2_CWUPF3 (1 << 2) /* Bit 2: Clear Wakeup Pin flag for PC1 */ +#define PWR_CR2_CWUPF4 (1 << 3) /* Bit 3: Clear Wakeup Pin flag for PC13 */ +#define PWR_CR2_CWUPF5 (1 << 4) /* Bit 4: Clear Wakeup Pin flag for PI8 */ +#define PWR_CR2_CWUPF6 (1 << 5) /* Bit 5: Clear Wakeup Pin flag for PI11 */ +#define PWR_CR2_WUPP1 (1 << 8) /* Bit 8: Wakeup pin polarity bit for PA0 */ +# define PWR_CR2_WUPP1_RISING (0 << 8) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP1_FALLING (1 << 8) /* 1= Detection on falling edge */ +#define PWR_CR2_WUPP2 (1 << 9) /* Bit 9: Wakeup pin polarity bit for PA2 */ +# define PWR_CR2_WUPP2_RISING (0 << 9) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP2_FALLING (1 << 9) /* 1= Detection on falling edge */ +#define PWR_CR2_WUPP3 (1 << 10) /* Bit 10: Wakeup pin polarity bit for PC1 */ +# define PWR_CR2_WUPP3_RISING (0 << 10) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP3_FALLING (1 << 10) /* 1= Detection on falling edge */ +#define PWR_CR2_WUPP4 (1 << 11) /* Bit 11: Wakeup pin polarity bit for PC13 */ +# define PWR_CR2_WUPP4_RISING (0 << 11) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP4_FALLING (1 << 11) /* 1= Detection on falling edge */ +#define PWR_CR2_WUPP5 (1 << 12) /* Bit 12: Wakeup pin polarity bit for PI8 */ +# define PWR_CR2_WUPP5_RISING (0 << 12) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP5_FALLING (1 << 12) /* 1= Detection on falling edge */ +#define PWR_CR2_WUPP6 (1 << 13) /* Bits 13: Wakeup pin polarity bit for PI11 */ +# define PWR_CR2_WUPP6_RISING (0 << 13) /* 0=Detection on rising edge */ +# define PWR_CR2_WUPP6_FALLING (1 << 13) /* 1= Detection on falling edge */ + +/* Power control/status register 2 */ + +#define PWR_CSR2_WUPF1 (1 << 0) /* Bit 0: Wakeup Pin flag for PA0 */ +#define PWR_CSR2_WUPF2 (1 << 1) /* Bit 1: Wakeup Pin flag for PA2 */ +#define PWR_CSR2_WUPF3 (1 << 2) /* Bit 2: Wakeup Pin flag for PC1 */ +#define PWR_CSR2_WUPF4 (1 << 3) /* Bit 3: Wakeup Pin flag for PC13 */ +#define PWR_CSR2_WUPF5 (1 << 4) /* Bit 4: Wakeup Pin flag for PI8 */ +#define PWR_CSR2_WUPF6 (1 << 5) /* Bit 5: Wakeup Pin flag for PI11 */ +#define PWR_CSR2_EWUP1 (1 << 8) /* Bit 8: Enable wakeup pin for PA0 */ +#define PWR_CSR2_EWUP2 (1 << 9) /* Bit 9: Enable wakeup pin for PA2 */ +#define PWR_CSR2_EWUP3 (1 << 10) /* Bit 10: Enable wakeup pin for PC1 */ +#define PWR_CSR2_EWUP4 (1 << 11) /* Bit 11: Enable wakeup pin for PC13 */ +#define PWR_CSR2_EWUP5 (1 << 12) /* Bit 12: Enable wakeup pin for PI8 */ +#define PWR_CSR2_EWUP6 (1 << 13) /* Bit 13: Enable wakeup pin for PI11 */ + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_PWR_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..0cdc92c7276b5aa3a080d3aea0bbfaeab91a26a1 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h @@ -0,0 +1,705 @@ +/**************************************************************************************************** + * arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_RCC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_RCC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_PLLCFG_OFFSET 0x0004 /* PLL configuration register */ +#define STM32_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32_RCC_CIR_OFFSET 0x000c /* Clock interrupt register */ +#define STM32_RCC_AHB1RSTR_OFFSET 0x0010 /* AHB1 peripheral reset register */ +#define STM32_RCC_AHB2RSTR_OFFSET 0x0014 /* AHB2 peripheral reset register */ +#define STM32_RCC_AHB3RSTR_OFFSET 0x0018 /* AHB3 peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x0020 /* APB1 Peripheral reset register */ +#define STM32_RCC_APB2RSTR_OFFSET 0x0024 /* APB2 Peripheral reset register */ +#define STM32_RCC_AHB1ENR_OFFSET 0x0030 /* AHB1 Peripheral Clock enable register */ +#define STM32_RCC_AHB2ENR_OFFSET 0x0034 /* AHB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB3ENR_OFFSET 0x0038 /* AHB3 Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x0040 /* APB1 Peripheral Clock enable register */ +#define STM32_RCC_APB2ENR_OFFSET 0x0044 /* APB2 Peripheral Clock enable register */ +#define STM32_RCC_AHB1LPENR_OFFSET 0x0050 /* RCC AHB1 low power mode peripheral clock enable register */ +#define STM32_RCC_AHB2LPENR_OFFSET 0x0054 /* RCC AHB2 low power mode peripheral clock enable register */ +#define STM32_RCC_AHB3LPENR_OFFSET 0x0058 /* RCC AHB3 low power mode peripheral clock enable register */ +#define STM32_RCC_APB1LPENR_OFFSET 0x0060 /* RCC APB1 low power mode peripheral clock enable register */ +#define STM32_RCC_APB2LPENR_OFFSET 0x0064 /* RCC APB2 low power mode peripheral clock enable register */ +#define STM32_RCC_BDCR_OFFSET 0x0070 /* Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x0074 /* Control/status register */ +#define STM32_RCC_SSCGR_OFFSET 0x0080 /* Spread spectrum clock generation register */ +#define STM32_RCC_PLLI2SCFGR_OFFSET 0x0084 /* PLLI2S configuration register */ +#define STM32_RCC_PLLSAICFGR_OFFSET 0x0088 /* PLLSAI configuration register */ +#define STM32_RCC_DCKCFGR1_OFFSET 0x008c /* Dedicated clocks configuration register 1 */ +#define STM32_RCC_DCKCFGR2_OFFSET 0x0090 /* Dedicated clocks configuration register 2 */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_PLLCFG (STM32_RCC_BASE+STM32_RCC_PLLCFG_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CIR (STM32_RCC_BASE+STM32_RCC_CIR_OFFSET) +#define STM32_RCC_AHB1RSTR (STM32_RCC_BASE+STM32_RCC_AHB1RSTR_OFFSET) +#define STM32_RCC_AHB2RSTR (STM32_RCC_BASE+STM32_RCC_AHB2RSTR_OFFSET) +#define STM32_RCC_AHB3RSTR (STM32_RCC_BASE+STM32_RCC_AHB3RSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_AHB1ENR (STM32_RCC_BASE+STM32_RCC_AHB1ENR_OFFSET) +#define STM32_RCC_AHB2ENR (STM32_RCC_BASE+STM32_RCC_AHB2ENR_OFFSET) +#define STM32_RCC_AHB3ENR (STM32_RCC_BASE+STM32_RCC_AHB3ENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_AHB1LPENR (STM32_RCC_BASE+STM32_RCC_AHB1LPENR_OFFSET) +#define STM32_RCC_AHB2LPENR (STM32_RCC_BASE+STM32_RCC_AHB2LPENR) +#define STM32_RCC_AHB3LPENR (STM32_RCC_BASE+STM32_RCC_AHB3LPENR_OFFSET) +#define STM32_RCC_APB1LPENR (STM32_RCC_BASE+STM32_RCC_APB1LPENR_OFFSET) +#define STM32_RCC_APB2LPENR (STM32_RCC_BASE+STM32_RCC_APB2LPENR_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE+STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE+STM32_RCC_CSR_OFFSET) +#define STM32_RCC_SSCGR (STM32_RCC_BASE+STM32_RCC_SSCGR_OFFSET) +#define STM32_RCC_PLLI2SCFGR (STM32_RCC_BASE+STM32_RCC_PLLI2SCFGR_OFFSET) +#define STM32_RCC_PLLSAICFGR (STM32_RCC_BASE+STM32_RCC_PLLSAICFGR_OFFSET) +#define STM32_RCC_DCKCFGR1 (STM32_RCC_BASE+STM32_RCC_DCKCFGR1_OFFSET) +#define STM32_RCC_DCKCFGR2 (STM32_RCC_BASE+STM32_RCC_DCKCFGR2_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* Clock control register */ + +#define RCC_CR_HSION (1 << 0) /* Bit 0: Internal High Speed clock enable */ +#define RCC_CR_HSIRDY (1 << 1) /* Bit 1: Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM_SHIFT (3) /* Bits 7-3: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (8) /* Bits 15-8: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#define RCC_CR_PLLI2SON (1 << 26) /* Bit 26: PLLI2S enable */ +#define RCC_CR_PLLI2SRDY (1 << 27) /* Bit 27: PLLI2S clock ready flag */ +#define RCC_CR_PLLSAION (1 << 28) /* Bit 28: PLLSAI enable */ +#define RCC_CR_PLLSAIRDY (1 << 29) /* Bit 29: PLLSAI clock ready flag */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLM_SHIFT (0) /* Bits 0-5: Main PLL (PLL) and audio PLL (PLLI2S) + * input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x3f << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n) << RCC_PLLCFG_PLLM_SHIFT) /* n = 2..63 */ +#define RCC_PLLCFG_PLLN_SHIFT (6) /* Bits 6-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x1ff << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 2..432 */ +#define RCC_PLLCFG_PLLP_SHIFT (16) /* Bits 16-17: Main PLL (PLL) main system clock divider */ +#define RCC_PLLCFG_PLLP_MASK (3 << RCC_PLLCFG_PLLP_SHIFT) +# define RCC_PLLCFG_PLLP(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLP_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLP_2 (0 << RCC_PLLCFG_PLLP_SHIFT) /* 00: PLLP = 2 */ +# define RCC_PLLCFG_PLLP_4 (1 << RCC_PLLCFG_PLLP_SHIFT) /* 01: PLLP = 4 */ +# define RCC_PLLCFG_PLLP_6 (2 << RCC_PLLCFG_PLLP_SHIFT) /* 10: PLLP = 6 */ +# define RCC_PLLCFG_PLLP_8 (3 << RCC_PLLCFG_PLLP_SHIFT) /* 11: PLLP = 8 */ +#define RCC_PLLCFG_PLLSRC (1 << 22) /* Bit 22: Main PLL(PLL) and audio PLL (PLLI2S) + * entry clock source */ +# define RCC_PLLCFG_PLLSRC_HSI (0) +# define RCC_PLLCFG_PLLSRC_HSE RCC_PLLCFG_PLLSRC +#define RCC_PLLCFG_PLLQ_SHIFT (24) /* Bits 24-27: Main PLL (PLL) divider + * (USB OTG FS, SDIO and RNG clocks) */ +#define RCC_PLLCFG_PLLQ_MASK (15 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((n) << RCC_PLLCFG_PLLQ_SHIFT) /* n=2..15 */ + +#define RCC_PLLCFG_RESET (0x24003010) /* PLLCFG reset value */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ +#define RCC_CFGR_PPRE1_SHIFT (10) /* Bits 10-12: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_PPRE2_SHIFT (13) /* Bits 13-15: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_RTCPRE_SHIFT (16) /* Bits 16-20: APB High speed prescaler (APB2) */ +#define RCC_CFGR_RTCPRE_MASK (31 << RCC_CFGR_RTCPRE_SHIFT) +# define RCC_CFGR_RTCPRE(n) ((n) << RCC_CFGR_RTCPRE_SHIFT) /* HSE/n, n=1..31 */ +#define RCC_CFGR_MCO1_SHIFT (21) /* Bits 21-22: Microcontroller Clock Output */ +#define RCC_CFGR_MCO1_MASK (3 << RCC_CFGR_MCO1_SHIFT) +# define RCC_CFGR_MCO1_HSI (0 << RCC_CFGR_MCO1_SHIFT) /* 00: HSI clock selected */ +# define RCC_CFGR_MCO1_LSE (1 << RCC_CFGR_MCO1_SHIFT) /* 01: LSE oscillator selected */ +# define RCC_CFGR_MCO1_HSE (2 << RCC_CFGR_MCO1_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO1_PLL (3 << RCC_CFGR_MCO1_SHIFT) /* 11: PLL clock selected */ +#define RCC_CFGR_I2SSRC (1 << 23) /* Bit 23: I2S clock selection */ +#define RCC_CFGR_MCO1PRE_SHIFT (24) /* Bits 24-26: MCO1 prescaler */ +#define RCC_CFGR_MCO1PRE_MASK (7 << RCC_CFGR_MCO1PRE_SHIFT) +# define RCC_CFGR_MCO1PRE_NONE (0 << RCC_CFGR_MCO1PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO1PRE_DIV2 (4 << RCC_CFGR_MCO1PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO1PRE_DIV3 (5 << RCC_CFGR_MCO1PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO1PRE_DIV4 (6 << RCC_CFGR_MCO1PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO1PRE_DIV5 (7 << RCC_CFGR_MCO1PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2PRE_SHIFT (27) /* Bits 27-29: MCO2 prescaler */ +#define RCC_CFGR_MCO2PRE_MASK (7 << RCC_CFGR_MCO2PRE_SHIFT) +# define RCC_CFGR_MCO2PRE_NONE (0 << RCC_CFGR_MCO2PRE_SHIFT) /* 0xx: no division */ +# define RCC_CFGR_MCO2PRE_DIV2 (4 << RCC_CFGR_MCO2PRE_SHIFT) /* 100: division by 2 */ +# define RCC_CFGR_MCO2PRE_DIV3 (5 << RCC_CFGR_MCO2PRE_SHIFT) /* 101: division by 3 */ +# define RCC_CFGR_MCO2PRE_DIV4 (6 << RCC_CFGR_MCO2PRE_SHIFT) /* 110: division by 4 */ +# define RCC_CFGR_MCO2PRE_DIV5 (7 << RCC_CFGR_MCO2PRE_SHIFT) /* 111: division by 5 */ +#define RCC_CFGR_MCO2_SHIFT (30) /* Bits 30-31: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_MASK (3 << RCC_CFGR_MCO2_SHIFT) +# define RCC_CFGR_MCO2_SYSCLK (0 << RCC_CFGR_MCO2_SHIFT) /* 00: System clock (SYSCLK) selected */ +# define RCC_CFGR_MCO2_PLLI2S (1 << RCC_CFGR_MCO2_SHIFT) /* 01: PLLI2S clock selected */ +# define RCC_CFGR_MCO2_HSE (2 << RCC_CFGR_MCO2_SHIFT) /* 10: HSE oscillator clock selected */ +# define RCC_CFGR_MCO2_PLL (3 << RCC_CFGR_MCO2_SHIFT) /* 11: PLL clock selected */ + +/* Clock interrupt register */ + +#define RCC_CIR_LSIRDYF (1 << 0) /* Bit 0: LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF (1 << 1) /* Bit 1: LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF (1 << 2) /* Bit 2: HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF (1 << 3) /* Bit 3: HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF (1 << 4) /* Bit 4: PLL Ready Interrupt flag */ +#define RCC_CIR_PLLI2SRDYF (1 << 5) /* Bit 5: PLLI2S Ready Interrupt flag */ +#define RCC_CIR_PLLSAIRDYF (1 << 6) /* Bit 6: PLLSAI Ready Interrupt flag */ +#define RCC_CIR_CSSF (1 << 7) /* Bit 7: Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE (1 << 8) /* Bit 8: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 9) /* Bit 9: LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 10) /* Bit 10: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 11) /* Bit 11: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 12) /* Bit 12: PLL Ready Interrupt Enable */ +#define RCC_CIR_PLLI2SRDYIE (1 << 13) /* Bit 13: PLLI2S Ready Interrupt enable */ +#define RCC_CIR_PLLSAIRDYIE (1 << 14) /* Bit 14: PLLSAI Ready Interrupt enable */ +#define RCC_CIR_LSIRDYC (1 << 16) /* Bit 16: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC (1 << 17) /* Bit 17: LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC (1 << 18) /* Bit 18: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC (1 << 19) /* Bit 19: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC (1 << 20) /* Bit 20: PLL Ready Interrupt Clear */ +#define RCC_CIR_PLLI2SRDYC (1 << 21) /* Bit 21: PLLI2S Ready Interrupt clear */ +#define RCC_CIR_PLLSAIRDYC (1 << 22) /* Bit 22: PLLSAI Ready Interrupt clear */ +#define RCC_CIR_CSSC (1 << 23) /* Bit 23: Clock Security System Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB1RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB1RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB1RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB1RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB1RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB1RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB1RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#define RCC_AHB1RSTR_GPIOIRST (1 << 8) /* Bit 8: IO port I reset */ +#define RCC_AHB1RSTR_GPIOJRST (1 << 9) /* Bit 9: IO port J reset */ +#define RCC_AHB1RSTR_GPIOKRST (1 << 10) /* Bit 10: IO port K reset */ +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12 CRC reset */ +#define RCC_AHB1RSTR_DMA1RST (1 << 21) /* Bit 21: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 22) /* Bit 22: DMA2 reset */ +#define RCC_AHB1RSTR_DMA2DRST (1 << 23) /* Bit 23: DMA2D reset */ +#define RCC_AHB1RSTR_ETHMACRST (1 << 25) /* Bit 25: Ethernet MAC reset */ +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) /* Bit 29: USB OTG HS module reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_DCMIRST (1 << 0) /* Bit 0: Camera interface reset */ +#define RCC_AHB2RSTR_CRYPRST (1 << 4) /* Bit 4: Cryptographic module reset */ +#define RCC_AHB2RSTR_HASHRST (1 << 5) /* Bit 5: Hash module reset */ +#define RCC_AHB2RSTR_RNGRST (1 << 6) /* Bit 6: Random number generator module reset */ +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) /* Bit 7: USB OTG FS module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */ +#define RCC_AHB3RSTR_QSPIRST (1 << 1) /* Bit 1: Quad SPI memory controller reset */ + +/* APB1 Peripheral reset register */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR_TIM12RST (1 << 6) /* Bit 6: TIM12 reset */ +#define RCC_APB1RSTR_TIM13RST (1 << 7) /* Bit 7: TIM13 reset */ +#define RCC_APB1RSTR_TIM14RST (1 << 8) /* Bit 8: TIM14 reset */ +#define RCC_APB1RSTR_LPTIM1RST (1 << 9) /* Bit 9: LPTIM1 reset */ +#define RCC_APB1RSTR_WWDGRST (1 << 11) /* Bit 11: Window watchdog reset */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_SPI3RST (1 << 15) /* Bit 15: SPI 3 reset */ +#define RCC_APB1RSTR_SPDIFRXRST (1 << 16) /* Bit 16: SPDIFRX reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_UART4RST (1 << 19) /* Bit 19: USART 4 reset */ +#define RCC_APB1RSTR_UART5RST (1 << 20) /* Bit 20: USART 5 reset */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) /* Bit 22: I2C 2 reset */ +#define RCC_APB1RSTR_I2C3RST (1 << 23) /* Bit 23: I2C 3 reset */ +#define RCC_APB1RSTR_I2C4RST (1 << 24) /* Bit 24: I2C 4 reset */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR_CAN2RST (1 << 26) /* Bit 26: CAN2 reset */ +#define RCC_APB1RSTR_CECRST (1 << 27) /* Bit 27: CEC reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR_DACRST (1 << 29) /* Bit 29: DAC reset */ +#define RCC_APB1RSTR_UART7RST (1 << 30) /* Bit 30: USART 7 reset */ +#define RCC_APB1RSTR_UART8RST (1 << 31) /* Bit 31: USART 8 reset */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_TIM1RST (1 << 0) /* Bit 0: TIM1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 1) /* Bit 1: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 4) /* Bit 4: USART1 reset */ +#define RCC_APB2RSTR_USART6RST (1 << 5) /* Bit 5: USART6 reset */ +#define RCC_APB2RSTR_ADCRST (1 << 8) /* Bit 8: ADC interface reset (common to all ADCs) */ +#define RCC_APB2RSTR_SDMMC1RST (1 << 11) /* Bit 11: SDMMC1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#define RCC_APB2RSTR_SPI4RST (1 << 13) /* Bit 13: SPI4 reset */ +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) /* Bit 14: System configuration controller reset */ +#define RCC_APB2RSTR_TIM9RST (1 << 16) /* Bit 16: TIM9 reset */ +#define RCC_APB2RSTR_TIM10RST (1 << 17) /* Bit 17: TIM10 reset */ +#define RCC_APB2RSTR_TIM11RST (1 << 18) /* Bit 18: TIM11 reset */ +#define RCC_APB2RSTR_SPI5RST (1 << 20) /* Bit 20: SPI 5 reset */ +#define RCC_APB2RSTR_SPI6RST (1 << 21) /* Bit 21: SPI 6 reset */ +#define RCC_APB2RSTR_SAI1RST (1 << 22) /* Bit 22: SAI 1 reset */ +#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 23: SAI 2 reset */ +#define RCC_APB2RSTR_LTDCRST (1 << 26) /* Bit 26: LTDC reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_GPIOEN(n) (1 << (n)) +#define RCC_AHB1ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A clock enable */ +#define RCC_AHB1ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B clock enable */ +#define RCC_AHB1ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C clock enable */ +#define RCC_AHB1ENR_GPIODEN (1 << 3) /* Bit 3: IO port D clock enable */ +#define RCC_AHB1ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E clock enable */ +#define RCC_AHB1ENR_GPIOFEN (1 << 5) /* Bit 5: IO port F clock enable */ +#define RCC_AHB1ENR_GPIOGEN (1 << 6) /* Bit 6: IO port G clock enable */ +#define RCC_AHB1ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H clock enable */ +#define RCC_AHB1ENR_GPIOIEN (1 << 8) /* Bit 8: IO port I clock enable */ +#define RCC_AHB1ENR_GPIOJEN (1 << 9) /* Bit 9: IO port J clock enable */ +#define RCC_AHB1ENR_GPIOKEN (1 << 10) /* Bit 10: IO port K clock enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC clock enable */ +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable */ +#define RCC_AHB1ENR_DTCMRAMEN (1 << 20) /* Bit 20: DTCM RAM clock enable */ +#define RCC_AHB1ENR_DMA1EN (1 << 21) /* Bit 21: DMA1 clock enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 22) /* Bit 22: DMA2 clock enable */ +#define RCC_AHB1ENR_DMA2DEN (1 << 23) /* Bit 23: DMA2D clock enable */ +#define RCC_AHB1ENR_ETHMACEN (1 << 25) /* Bit 25: Ethernet MAC clock enable */ +#define RCC_AHB1ENR_ETHMACTXEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable */ +#define RCC_AHB1ENR_ETHMACRXEN (1 << 27) /* Bit 27: Ethernet Reception clock enable */ +#define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable */ +#define RCC_AHB1ENR_OTGHSEN (1 << 29) /* Bit 29: USB OTG HS clock enable */ +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable */ + +/* AHB2 Peripheral Clock enable register */ + +#define RCC_AHB2ENR_DCMIEN (1 << 0) /* Bit 0: Camera interface enable */ +#define RCC_AHB2ENR_CRYPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable */ +#define RCC_AHB2ENR_HASHEN (1 << 5) /* Bit 5: Hash modules clock enable */ +#define RCC_AHB2ENR_RNGEN (1 << 6) /* Bit 6: Random number generator clock enable */ +#define RCC_AHB2ENR_OTGFSEN (1 << 7) /* Bit 7: USB OTG FS clock enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module clock enable */ +#define RCC_AHB3ENR_QSPIEN (1 << 1) /* Bit 1: Quad SPI memory controller clock enable */ + +/* APB1 Peripheral Clock enable register */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: TIM 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: TIM 3 clock enable */ +#define RCC_APB1ENR_TIM4EN (1 << 2) /* Bit 2: TIM 4 clock enable */ +#define RCC_APB1ENR_TIM5EN (1 << 3) /* Bit 3: TIM 5 clock enable */ +#define RCC_APB1ENR_TIM6EN (1 << 4) /* Bit 4: TIM 6 clock enable */ +#define RCC_APB1ENR_TIM7EN (1 << 5) /* Bit 5: TIM 7 clock enable */ +#define RCC_APB1ENR_TIM12EN (1 << 6) /* Bit 6: TIM 12 clock enable */ +#define RCC_APB1ENR_TIM13EN (1 << 7) /* Bit 7: TIM 13 clock enable */ +#define RCC_APB1ENR_TIM14EN (1 << 8) /* Bit 8: TIM 14 clock enable */ +#define RCC_APB1ENR_LPTIM1EN (1 << 9) /* Bit 9: LPTIM 1 clock enable */ +#define RCC_APB1ENR_WWDGEN (1 << 11) /* Bit 11: Window watchdog clock enable */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_SPI3EN (1 << 15) /* Bit 15: SPI 3 clock enable */ +#define RCC_APB1ENR_SPDIFRXEN (1 << 16) /* Bit 16: SPDIFRX clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_UART4EN (1 << 19) /* Bit 19: UART 4 clock enable */ +#define RCC_APB1ENR_UART5EN (1 << 20) /* Bit 20: UART 5 clock enable */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ +#define RCC_APB1ENR_I2C2EN (1 << 22) /* Bit 22: I2C 2 clock enable */ +#define RCC_APB1ENR_I2C3EN (1 << 23) /* Bit 23: I2C 3 clock enable */ +#define RCC_APB1ENR_I2C4EN (1 << 24) /* Bit 24: I2C 4 clock enable */ +#define RCC_APB1ENR_CAN1EN (1 << 25) /* Bit 25: CAN 1 clock enable */ +#define RCC_APB1ENR_CAN2EN (1 << 26) /* Bit 26: CAN 2 clock enable */ +#define RCC_APB1ENR_CECEN (1 << 27) /* Bit 27: CEC clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ +#define RCC_APB1ENR_DACEN (1 << 29) /* Bit 29: DAC interface clock enable */ +#define RCC_APB1ENR_UART7EN (1 << 30) /* Bit 30: UART7 clock enable */ +#define RCC_APB1ENR_UART8EN (1 << 31) /* Bit 31: UART8 clock enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_TIM1EN (1 << 0) /* Bit 0: TIM 1 clock enable */ +#define RCC_APB2ENR_TIM8EN (1 << 1) /* Bit 1: TIM 8 clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 4) /* Bit 4: USART 1 clock enable */ +#define RCC_APB2ENR_USART6EN (1 << 5) /* Bit 5: USART 6 clock enable */ +#define RCC_APB2ENR_ADC1EN (1 << 8) /* Bit 8: ADC 1 clock enable */ +#define RCC_APB2ENR_ADC2EN (1 << 9) /* Bit 9: ADC 2 clock enable */ +#define RCC_APB2ENR_ADC3EN (1 << 10) /* Bit 10: ADC 3 clock enable */ +#define RCC_APB2ENR_SDMMC1EN (1 << 11) /* Bit 11: SDMMC 1 clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI 1 clock enable */ +#define RCC_APB2ENR_SPI4EN (1 << 13) /* Bit 13: SPI 4 clock enable */ +#define RCC_APB2ENR_SYSCFGEN (1 << 14) /* Bit 14: System configuration controller clock enable */ +#define RCC_APB2ENR_TIM9EN (1 << 16) /* Bit 16: TIM 9 clock enable */ +#define RCC_APB2ENR_TIM10EN (1 << 17) /* Bit 17: TIM1 0 clock enable */ +#define RCC_APB2ENR_TIM11EN (1 << 18) /* Bit 18: TIM 11 clock enable */ +#define RCC_APB2ENR_SPI5EN (1 << 20) /* Bit 20: SPI 5 clock enable */ +#define RCC_APB2ENR_SPI6EN (1 << 21) /* Bit 21: SPI 6 clock enable */ +#define RCC_APB2ENR_SAI1EN (1 << 22) /* Bit 22: SAI 1 clock enable */ +#define RCC_APB2ENR_SAI2EN (1 << 23) /* Bit 23: SAI 2 clock enable */ +#define RCC_APB2ENR_LTDCEN (1 << 26) /* Bit 26: LTDC clock enable */ + +/* RCC AHB1 low power mode peripheral clock enable register */ + +#define RCC_AHB1LPENR_GPIOLPEN(n) (1 << (n)) +#define RCC_AHB1LPENR_GPIOALPEN (1 << 0) /* Bit 0: IO port A clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOBLPEN (1 << 1) /* Bit 1: IO port B clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOCLPEN (1 << 2) /* Bit 2: IO port C clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIODLPEN (1 << 3) /* Bit 3: IO port D clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOELPEN (1 << 4) /* Bit 4: IO port E clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOFLPEN (1 << 5) /* Bit 5: IO port F clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOGLPEN (1 << 6) /* Bit 6: IO port G clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOHLPEN (1 << 7) /* Bit 7: IO port H clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOILPEN (1 << 8) /* Bit 8: IO port I clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOJLPEN (1 << 9) /* Bit 8: IO port J clock enable during Sleep mode */ +#define RCC_AHB1LPENR_GPIOKLPEN (1 << 10) /* Bit 10: IO port K clock enable during Sleep mode */ +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) /* Bit 12: CRC clock enable during Sleep mode */ +#define RCC_AHB1LPENR_AXILPEN (1 << 13) /* Bit 12: AXI to AHB bridge clock enable during Sleep mode */ +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) /* Bit 15: Flash interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) /* Bit 16: SRAM 1 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) /* Bit 17: SRAM 2 interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) /* Bit 18: Backup SRAM interface clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DTCMLPEN (1 << 20) /* Bit 20: DTCM RAM clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) /* Bit 21: DMA1 clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) /* Bit 22: DMA2 clock enable during Sleep mode */ +#define RCC_AHB1LPENR_DMA2DLPEN (1 << 23) /* Bit 23: DMA2D clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) /* Bit 25: Ethernet MAC clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHTXLPEN (1 << 26) /* Bit 26: Ethernet Transmission clock enable during Sleep mode */ +#define RCC_AHB1LPENR_ETHRXLPEN (1 << 27) /* Bit 27: Ethernet Reception clock enable during Sleep mode */ + +#define RCC_AHB1LPENR_ETHPTPLPEN (1 << 28) /* Bit 28: Ethernet PTP clock enable during Sleep mode */ +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) /* Bit 29: USB OTG HS clock enable during Sleep mode */ +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) /* Bit 30: USB OTG HSULPI clock enable during Sleep mode */ + +/* RCC AHB2 low power mode peripheral clock enable register */ + +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) /* Bit 0: Camera interface enable during Sleep mode */ +#define RCC_AHB2LPENR_CRYPLPEN (1 << 4) /* Bit 4: Cryptographic modules clock enable during Sleep mode */ +#define RCC_AHB2LPENR_HASHLPEN (1 << 5) /* Bit 5: Hash modules clock enable during Sleep mode */ +#define RCC_AHB2LPENR_RNGLPEN (1 << 6) /* Bit 6: Random number generator clock enable during Sleep mode */ +#define RCC_AHB2LPENR_OTGFLPSEN (1 << 7) /* Bit 7: USB OTG FS clock enable during Sleep mode */ + +/* RCC AHB3 low power mode peripheral clock enable register */ + +#define RCC_AHB3LPENR_FSMLPEN (1 << 0) /* Bit 0: Flexible static memory controller module clock + * enable during Sleep mode */ +#define RCC_AHB3LPENR_QSPILPEN (1 << 1) /* Bit 1: Quad SPI memory controller clock + * enable during Sleep mode */ + +/* RCC APB1 low power mode peripheral clock enable register */ + +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) /* Bit 0: TIM 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) /* Bit 1: TIM 3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) /* Bit 2: TIM 4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) /* Bit 3: TIM 5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) /* Bit 4: TIM 6 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) /* Bit 5: TIM 7 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) /* Bit 6: TIM 12 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) /* Bit 7: TIM 13 clock enable during Sleep mode */ +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) /* Bit 8: TIM 14 clock enable during Sleep mode */ +#define RCC_APB1LPENR_LPTIM1LPEN (1 << 9) /* Bit 9: LPTIM 1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) /* Bit 11: Window watchdog clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) /* Bit 14: SPI 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) /* Bit 15: SPI 3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_SPDIFRXLPEN (1 << 16) /* Bit 16: SPDIFRX clock enable during Sleep mode */ +#define RCC_APB1LPENR_USART2LPEN (1 << 17) /* Bit 17: USART 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_USART3LPEN (1 << 18) /* Bit 18: USART 3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART4LPEN (1 << 19) /* Bit 19: UART 4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART5LPEN (1 << 20) /* Bit 20: UART 5 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) /* Bit 21: I2C 1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) /* Bit 22: I2C 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) /* Bit 23: I2C 3 clock enable during Sleep mode */ +#define RCC_APB1LPENR_I2C4LPEN (1 << 24) /* Bit 24: I2C 4 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) /* Bit 25: CAN 1 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) /* Bit 26: CAN 2 clock enable during Sleep mode */ +#define RCC_APB1LPENR_CECLPEN (1 << 27) /* Bit 27: CEC clock enable during Sleep mode */ +#define RCC_APB1LPENR_PWRLPEN (1 << 28) /* Bit 28: Power interface clock enable during Sleep mode */ +#define RCC_APB1LPENR_DACLPEN (1 << 29) /* Bit 29: DAC interface clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART7LPEN (1 << 30) /* Bit 30: UART 7 clock enable during Sleep mode */ +#define RCC_APB1LPENR_UART8LPEN (1 << 31) /* Bit 31: UART 8 clock enable during Sleep mode */ + +/* RCC APB2 low power mode peripheral clock enable register */ + +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) /* Bit 0: TIM 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) /* Bit 1: TIM 8 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART1LPEN (1 << 4) /* Bit 4: USART 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_USART6LPEN (1 << 5) /* Bit 5: USART 6 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) /* Bit 8: ADC 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) /* Bit 9: ADC 2 clock enable during Sleep mode */ +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) /* Bit 10: ADC 3 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SDMMC1LPEN (1 << 11) /* Bit 11: SDMMC 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) /* Bit 12: SPI 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI4LPEN (1 << 13) /* Bit 13: SPI 4 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) /* Bit 14: System configuration controller clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) /* Bit 16: TIM 9 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) /* Bit 17: TIM 10 clock enable during Sleep mode */ +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) /* Bit 18: TIM 11 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI5LPEN (1 << 20) /* Bit 20: SPI 5 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SPI6LPEN (1 << 21) /* Bit 21: SPI 6 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SAI1LPEN (1 << 22) /* Bit 22: SAI 1 clock enable during Sleep mode */ +#define RCC_APB2LPENR_SAI2LPEN (1 << 23) /* Bit 23: SAI 2 clock enable during Sleep mode */ +#define RCC_APB2LPENR_LTDCLPEN (1 << 26) /* Bit 26: LTDC clock enable during Sleep mode */ + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 128 used as RTC clock */ +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF (1 << 24) /* Bit 24: Remove reset flag */ +#define RCC_CSR_BORRSTF (1 << 25) /* Bit 25: BOR reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* Spread spectrum clock generation register */ + +#define RCC_SSCGR_MODPER_SHIFT (0) /* Bit 0-12: Modulation period */ +#define RCC_SSCGR_MODPER_MASK (0x1fff << RCC_SSCGR_MODPER_SHIFT) +# define RCC_SSCGR_MODPER(n) ((n) << RCC_SSCGR_MODPER_SHIFT) +#define RCC_SSCGR_INCSTEP_SHIFT (13) /* Bit 13-27: Incrementation step */ +#define RCC_SSCGR_INCSTEP_MASK (0x7fff << RCC_SSCGR_INCSTEP_SHIFT) +# define RCC_SSCGR_INCSTEP(n) ((n) << RCC_SSCGR_INCSTEP_SHIFT) +#define RCC_SSCGR_SPREADSEL (1 << 30) /* Bit 30: Spread Select */ +#define RCC_SSCGR_SSCGEN (1 << 31) /* Bit 31: Spread spectrum modulation enable */ + +/* PLLI2S configuration register */ + +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT (6) /* Bits 6-14: PLLI2S multiplication factor for VCO */ +#define RCC_PLLI2SCFGR_PLLI2SN_MASK (0x1ff << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SN(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) +#define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIFRX clock */ +#define RCC_PLLI2SCFGR_PLLI2SP_MASK (3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SP(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) +#define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAIs clock */ +#define RCC_PLLI2SCFGR_PLLI2SQ_MASK (15 << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) +#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT (28) /* Bits 28-30: PLLI2S division factor for I2S clocks */ +#define RCC_PLLI2SCFGR_PLLI2SR_MASK (7 << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SR(n) (uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) + +/* PLLSAI configuration register */ + +#define RCC_PLLSAICFGR_PLLSAIN_SHIFT (6) /* Bits 6-14: PLLSAI divider (N) for VCO */ +#define RCC_PLLSAICFGR_PLLSAIN_MASK (0x1ff << RCC_PLLSAICFGR_PLLSAIN_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT) +#define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48MHz clock */ +#define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIP(n) ((n) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) +#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */ +#define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) +#define RCC_PLLSAICFGR_PLLSAIR_SHIFT (28) /* Bits 28-30: PLLSAI division factor for LCD clock */ +#define RCC_PLLSAICFGR_PLLSAIR_MASK (7 << RCC_PLLSAICFGR_PLLSAIR_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIR(n) ((n) << RCC_PLLSAICFGR_PLLSAIR_SHIFT) + +/* Dedicated clocks configuration register 1 */ + +#define RCC_DCKCFGR1_PLLI2SDIVQ_SHIFT (0) /* Bits 0-4: PLLI2S division factor for I2S clock */ +#define RCC_DCKCFGR1_PLLI2SDIVQ_MASK (0x1F << RCC_DCKCFGR1_PLLI2SDIVQ_SHIFT) +# define RCC_DCKCFGR1_PLLI2SDIVQ(n) ((n) << RCC_DCKCFGR1_PLLI2SDIVQ_SHIFT) +#define RCC_DCKCFGR1_PLLSAIDIVQ_SHIFT (8) /* Bits 8-12: PLLSAI division factor for SAI clock */ +#define RCC_DCKCFGR1_PLLSAIDIVQ_MASK (0x1F << RCC_DCKCFGR1_PLLSAIDIVQ_SHIFT) +# define RCC_DCKCFGR1_PLLSAIDIVQ(n) ((n) << RCC_DCKCFGR1_PLLSAIDIVQ_SHIFT) + +#define RCC_DCKCFGR1_PLLSAIDIVR_SHIFT (16) /* Bits 16-17: PLLSAI division factor for LCD_CLK clock */ +#define RCC_DCKCFGR1_PLLSAIDIVR_MASK (0x3 << RCC_DCKCFGR1_PLLSAIDIVR_SHIFT) +# define RCC_DCKCFGR1_PLLSAIDIVR(n) ((n) << RCC_DCKCFGR1_PLLSAIDIVR_SHIFT) + +#define RCC_DCKCFGR1_SAI1SEL_SHIFT (20) /* Bits 20-21: SAI 1 clock source selection */ +#define RCC_DCKCFGR1_SAI1SEL_MASK (0x3 << RCC_DCKCFGR1_SAI1SEL_SHIFT) +# define RCC_DCKCFGR1_SAI1SEL(n) ((n) << RCC_DCKCFGR1_SAI1SEL_SHIFT) + +#define RCC_DCKCFGR1_SAI2SEL_SHIFT (22) /* Bits 22-23: SAI 2 clock source selection */ +#define RCC_DCKCFGR1_SAI2SEL_MASK (0x3 << RCC_DCKCFGR1_SAI2SEL_SHIFT) +# define RCC_DCKCFGR1_SAI2SEL(n) ((n) << RCC_DCKCFGR1_SAI2SEL_SHIFT) +#define RCC_DCKCFGR1_TIMPRE (1 << 24) /* Bit 24: Timer clock prescaler selection */ + +/* Dedicated clocks configuration register 2 */ + +#define RCC_DCKCFGR2_USART1SEL_SHIFT (0) /* Bits 0-1: USART 1 clock source selection */ +#define RCC_DCKCFGR2_USART1SEL_MASK (3 << RCC_DCKCFGR2_USART1SEL_SHIFT) +# define RCC_DCKCFGR2_USART1SEL_APB (0 << RCC_DCKCFGR2_USART1SEL_SHIFT) /* APB2 clock (PCLK2) is selected as USART 1 clock */ +# define RCC_DCKCFGR2_USART1SEL_SYSCLK (1 << RCC_DCKCFGR2_USART1SEL_SHIFT) /* System clock is selected as USART 1 clock */ +# define RCC_DCKCFGR2_USART1SEL_HSI (2 << RCC_DCKCFGR2_USART1SEL_SHIFT) /* HSI clock is selected as USART 1 clock */ +# define RCC_DCKCFGR2_USART1SEL_LSE (3 << RCC_DCKCFGR2_USART1SEL_SHIFT) /* LSE clock is selected as USART 1 clock */ +#define RCC_DCKCFGR2_USART2SEL_SHIFT (2) /* Bits 2-3: USART 2 clock source selection */ +#define RCC_DCKCFGR2_USART2SEL_MASK (3 << RCC_DCKCFGR2_USART2SEL_SHIFT) +# define RCC_DCKCFGR2_USART2SEL_APB (0 << RCC_DCKCFGR2_USART2SEL_SHIFT) /* APB1 clock (PCLK1) is selected as USART 2 clock */ +# define RCC_DCKCFGR2_USART2SEL_SYSCLK (1 << RCC_DCKCFGR2_USART2SEL_SHIFT) /* System clock is selected as USART 2 clock */ +# define RCC_DCKCFGR2_USART2SEL_HSI (2 << RCC_DCKCFGR2_USART2SEL_SHIFT) /* HSI clock is selected as USART 2 clock */ +# define RCC_DCKCFGR2_USART2SEL_LSE (3 << RCC_DCKCFGR2_USART2SEL_SHIFT) /* LSE clock is selected as USART 2 clock */ +#define RCC_DCKCFGR2_UART4SEL_SHIFT (6) /* Bits 6-7: UART 4 clock source selection */ +#define RCC_DCKCFGR2_UART4SEL_MASK (3 << RCC_DCKCFGR2_UART4SEL_SHIFT) +# define RCC_DCKCFGR2_UART4SEL_APB (0 << RCC_DCKCFGR2_UART4SEL_SHIFT) /* APB1 clock (PCLK1) is selected as UART 4 clock */ +# define RCC_DCKCFGR2_UART4SEL_SYSCLK (1 << RCC_DCKCFGR2_UART4SEL_SHIFT) /* System clock is selected as UART 4 clock */ +# define RCC_DCKCFGR2_UART4SEL_HSI (2 << RCC_DCKCFGR2_UART4SEL_SHIFT) /* HSI clock is selected as UART 4 clock */ +# define RCC_DCKCFGR2_UART4SEL_LSE (3 << RCC_DCKCFGR2_UART4SEL_SHIFT) /* LSE clock is selected as UART 4 clock */ +#define RCC_DCKCFGR2_UART5SEL_SHIFT (8) /* Bits 8-9: UART 5 clock source selection */ +#define RCC_DCKCFGR2_UART5SEL_MASK (3 << RCC_DCKCFGR2_UART5SEL_SHIFT) +# define RCC_DCKCFGR2_UART5SEL_APB (0 << RCC_DCKCFGR2_UART5SEL_SHIFT) /* APB1 clock (PCLK1) is selected as UART 5 clock */ +# define RCC_DCKCFGR2_UART5SEL_SYSCLK (1 << RCC_DCKCFGR2_UART5SEL_SHIFT) /* System clock is selected as UART 5 clock */ +# define RCC_DCKCFGR2_UART5SEL_HSI (2 << RCC_DCKCFGR2_UART5SEL_SHIFT) /* HSI clock is selected as UART 5 clock */ +# define RCC_DCKCFGR2_UART5SEL_LSE (3 << RCC_DCKCFGR2_UART5SEL_SHIFT) /* LSE clock is selected as UART 5 clock */ +#define RCC_DCKCFGR2_USART6SEL_SHIFT (10) /* Bits 10-11: USART 6 clock source selection */ +#define RCC_DCKCFGR2_USART6SEL_MASK (3 << RCC_DCKCFGR2_USART6SEL_SHIFT) +# define RCC_DCKCFGR2_USART6SEL_APB (0 << RCC_DCKCFGR2_USART6SEL_SHIFT) /* APB2 clock (PCLK2) is selected as USART 6 clock */ +# define RCC_DCKCFGR2_USART6SEL_SYSCLK (1 << RCC_DCKCFGR2_USART6SEL_SHIFT) /* System clock is selected as USART 6 clock */ +# define RCC_DCKCFGR2_USART6SEL_HSI (2 << RCC_DCKCFGR2_USART6SEL_SHIFT) /* HSI clock is selected as USART 6 clock */ +# define RCC_DCKCFGR2_USART6SEL_LSE (3 << RCC_DCKCFGR2_USART6SEL_SHIFT) /* LSE clock is selected as USART 6 clock */ +#define RCC_DCKCFGR2_UART7SEL_SHIFT (12) /* Bits 12-13: UART 7 clock source selection */ +#define RCC_DCKCFGR2_UART7SEL_MASK (3 << RCC_DCKCFGR2_UART7SEL_SHIFT) +# define RCC_DCKCFGR2_UART7SEL_APB (0 << RCC_DCKCFGR2_UART7SEL_SHIFT) /* APB1 clock (PCLK1) is selected as UART 7 clock */ +# define RCC_DCKCFGR2_UART7SEL_SYSCLK (1 << RCC_DCKCFGR2_UART7SEL_SHIFT) /* System clock is selected as UART 7 clock */ +# define RCC_DCKCFGR2_UART7SEL_HSI (2 << RCC_DCKCFGR2_UART7SEL_SHIFT) /* HSI clock is selected as UART 7 clock */ +# define RCC_DCKCFGR2_UART7SEL_LSE (3 << RCC_DCKCFGR2_UART7SEL_SHIFT) /* LSE clock is selected as UART 7 clock */ +#define RCC_DCKCFGR2_UART8SEL_SHIFT (14) /* Bits 14-15: UART 8 clock source selection */ +#define RCC_DCKCFGR2_UART8SEL_MASK (3 << RCC_DCKCFGR2_UART8SEL_SHIFT) +# define RCC_DCKCFGR2_UART8SEL_APB (0 << RCC_DCKCFGR2_UART8SEL_SHIFT) /* APB1 clock (PCLK1) is selected as UART 8 clock */ +# define RCC_DCKCFGR2_UART8SEL_SYSCLK (1 << RCC_DCKCFGR2_UART8SEL_SHIFT) /* System clock is selected as UART 8 clock */ +# define RCC_DCKCFGR2_UART8SEL_HSI (2 << RCC_DCKCFGR2_UART8SEL_SHIFT) /* HSI clock is selected as UART 8 clock */ +# define RCC_DCKCFGR2_UART8SEL_LSE (3 << RCC_DCKCFGR2_UART8SEL_SHIFT) /* LSE clock is selected as UART 8 clock */ +#define RCC_DCKCFGR2_I2C1SEL_SHIFT (16) /* Bits 16-17: I2C1 clock source selection */ +#define RCC_DCKCFGR2_I2C1SEL_MASK (3 << RCC_DCKCFGR2_I2C1SEL_SHIFT) +# define RCC_DCKCFGR2_I2C1SEL_APB (0 << RCC_DCKCFGR2_I2C1SEL_SHIFT) /* APB1 clock (PCLK1) is selected as I2C 1 clock */ +# define RCC_DCKCFGR2_I2C1SEL_SYSCLK (1 << RCC_DCKCFGR2_I2C1SEL_SHIFT) /* System clock is selected as I2C 1 clock */ +# define RCC_DCKCFGR2_I2C1SEL_HSI (2 << RCC_DCKCFGR2_I2C1SEL_SHIFT) /* HSI clock is selected as I2C 1 clock */ +#define RCC_DCKCFGR2_I2C2SEL_SHIFT (18) /* Bits 18-19: I2C2 clock source selection */ +#define RCC_DCKCFGR2_I2C2SEL_MASK (3 << RCC_DCKCFGR2_I2C2SEL_SHIFT) +# define RCC_DCKCFGR2_I2C2SEL_APB (0 << RCC_DCKCFGR2_I2C2SEL_SHIFT) /* APB1 clock (PCLK1) is selected as I2C 2 clock */ +# define RCC_DCKCFGR2_I2C2SEL_SYSCLK (1 << RCC_DCKCFGR2_I2C2SEL_SHIFT) /* System clock is selected as I2C 2 clock */ +# define RCC_DCKCFGR2_I2C2SEL_HSI (2 << RCC_DCKCFGR2_I2C2SEL_SHIFT) /* HSI clock is selected as I2C 2 clock */ +#define RCC_DCKCFGR2_I2C3SEL_SHIFT (20) /* Bits 20-21: I2C3 clock source selection */ +#define RCC_DCKCFGR2_I2C3SEL_MASK (3 << RCC_DCKCFGR2_I2C3SEL_SHIFT) +# define RCC_DCKCFGR2_I2C3SEL_APB (0 << RCC_DCKCFGR2_I2C3SEL_SHIFT) /* APB1 clock (PCLK1) is selected as I2C 3 clock */ +# define RCC_DCKCFGR2_I2C3SEL_SYSCLK (1 << RCC_DCKCFGR2_I2C3SEL_SHIFT) /* System clock is selected as I2C 3 clock */ +# define RCC_DCKCFGR2_I2C3SEL_HSI (2 << RCC_DCKCFGR2_I2C3SEL_SHIFT) /* HSI clock is selected as I2C 3 clock */ +#define RCC_DCKCFGR2_I2C4SEL_SHIFT (22) /* Bits 22-23: I2C4 clock source selection */ +#define RCC_DCKCFGR2_I2C4SEL_MASK (3 << RCC_DCKCFGR2_I2C4SEL_SHIFT) +# define RCC_DCKCFGR2_I2C4SEL_APB (0 << RCC_DCKCFGR2_I2C4SEL_SHIFT) /* APB1 clock (PCLK1) is selected as I2C 4 clock */ +# define RCC_DCKCFGR2_I2C4SEL_SYSCLK (1 << RCC_DCKCFGR2_I2C4SEL_SHIFT) /* System clock is selected as I2C 4 clock */ +# define RCC_DCKCFGR2_I2C4SEL_HSI (2 << RCC_DCKCFGR2_I2C4SEL_SHIFT) /* HSI clock is selected as I2C 4 clock */ +#define RCC_DCKCFGR2_LPTIM1SEL_SHIFT (24) /* Bits 24-25: Low power timer 1 clock source selection */ +#define RCC_DCKCFGR2_LPTIM1SEL_MASK (3 << RCC_DCKCFGR2_LPTIM1SEL_SHIFT) +# define RCC_DCKCFGR2_LPTIM1SEL_APB (0 << RCC_DCKCFGR2_LPTIM1SEL_SHIFT) /* APB1 clock (PCLK1) is selected as LPTIM 1 clock */ +# define RCC_DCKCFGR2_LPTIM1SEL_SYSCLK (1 << RCC_DCKCFGR2_LPTIM1SEL_SHIFT) /* System clock is selected as LPTIM 1 clock */ +# define RCC_DCKCFGR2_LPTIM1SEL_HSI (2 << RCC_DCKCFGR2_LPTIM1SEL_SHIFT) /* HSI clock is selected as LPTIM 1 clock */ +# define RCC_DCKCFGR2_LPTIM1SEL_LSE (3 << RCC_DCKCFGR2_LPTIM1SEL_SHIFT) /* LSE clock is selected as LPTIM 1 clock */ +#define RCC_DCKCFGR2_CECSEL_SHIFT (26) /* Bit 26: HDMI-CEC clock source selection */ +#define RCC_DCKCFGR2_CECSEL_MASK (1 << RCC_DCKCFGR2_CECSEL_SHIFT) +# define RCC_DCKCFGR2_CECSEL_LSE (0 << RCC_DCKCFGR2_CECSEL_SHIFT) /* LSE clock is selected as HDMI-CEC clock */ +# define RCC_DCKCFGR2_CECSEL_HSI (1 << RCC_DCKCFGR2_CECSEL_SHIFT) /* HSI clock is selected as HDMI-CEC clock */ +#define RCC_DCKCFGR2_CK48MSEL_SHIFT (27) /* Bit 27: 48MHz clock source selection */ +#define RCC_DCKCFGR2_CK48MSEL_MASK (1 << RCC_DCKCFGR2_CK48MSEL_SHIFT) +# define RCC_DCKCFGR2_CK48MSEL_PLL (0 << RCC_DCKCFGR2_CK48MSEL_SHIFT) /* 48MHz clock from PLL is selected */ +# define RCC_DCKCFGR2_CK48MSEL_PLLSAI (1 << RCC_DCKCFGR2_CK48MSEL_SHIFT) /*48MHz clock from PLLSAI is selected */ +#define RCC_DCKCFGR2_SDMMCSEL_SHIFT (28) /* Bit 28: SDMMC clock source selection */ +#define RCC_DCKCFGR2_SDMMCSEL_MASK (1 << RCC_DCKCFGR2_SDMMCSEL_SHIFT) +# define RCC_DCKCFGR2_SDMMCSEL_48MHZ (0 << RCC_DCKCFGR2_SDMMCSEL_SHIFT) /* 48 MHz clock is selected as SDMMC clock */ +# define RCC_DCKCFGR2_SDMMCSEL_SYSCLK (1 << RCC_DCKCFGR2_SDMMCSEL_SHIFT) /* System clock is selected as SDMMC clock */ + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F74XX75XX_RCC_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_syscfg.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..55f90c562762e639e9b5a3fbc92fb680de7a1854 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_syscfg.h @@ -0,0 +1,159 @@ +/**************************************************************************************************** + * arch/arm/src/stm32f7/chip/stm32f74xx75xx_syscfg.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */ + +#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ + +#define STM32_SYSCFG_CMPCR_OFFSET 0x0020 /* Compensation cell control register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_SYSCFG_MEMRMP (STM32_SYSCFG_BASE+STM32_SYSCFG_MEMRMP_OFFSET) +#define STM32_SYSCFG_PMC (STM32_SYSCFG_BASE+STM32_SYSCFG_PMC_OFFSET) + +#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) +#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) +#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET) +#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET) +#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET) + +#define STM32_SYSCFG_CMPCR (STM32_SYSCFG_BASE+STM32_SYSCFG_CMPCR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_MEMBOOT (1 << 0) /* Bit 0: Memory boot mapping */ +#define SYSCFG_MEMRMP_MEMBOOT_ADD0 (0 << 0) /* 0=BOOT_ADD0 defines */ +#define SYSCFG_MEMRMP_MEMBOOT_ADD1 (1 << 0) /* 1=BOOT_ADD1 defines */ +#define SYSCFG_MEMRMP_SWPFMC_SHIFT (10) /* Bits 10-11: FMC memory mapping swap */ +#define SYSCFG_MEMRMP_SWPFMC_MASK (3 << SYSCFG_MEMRMP_SWPFMC_SHIFT) +# define SYSCFG_MEMRMP_SWPFMC_NONE (0 << SYSCFG_MEMRMP_SWPFMC_SHIFT) /* No FMC memory mapping swapping */ +# define SYSCFG_MEMRMP_SWPFMC_NORRAM (1 << SYSCFG_MEMRMP_SWPFMC_SHIFT) /* NOR/RAM and SDRAM memory mapping swapped */ + +/* SYSCFG peripheral mode configuration register */ + +#define SYSCFG_PMC_ADC1DC2 (1 << 16) /* Bit 16: See AN4073 */ +#define SYSCFG_PMC_ADC2DC2 (1 << 17) /* Bit 17: See AN4073 */ +#define SYSCFG_PMC_ADC3DC2 (1 << 18) /* Bit 18: See AN4073 */ +#define SYSCFG_PMC_MII_RMII_SEL (1 << 23) /* Bit 23: Ethernet PHY interface selection */ +# define SYSCFG_PMC_MII_SEL (0 << 23) /* 0 selects MII */ +# define SYSCFG_PMC_RMII_SEL (1 << 23) /* 1 selects RMII */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ +#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */ +#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin */ +#define SYSCFG_EXTICR_PORTJ (9) /* 1001: PJ[x] pin */ +#define SYSCFG_EXTICR_PORTK (10) /* 1010: PK[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (15) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* Compensation cell control register */ + +#define SYSCFG_CMPCR_CMPPD (1 << 0) /* Bit 0: Compensation cell power-down */ +#define SYSCFG_CMPCR_READY (1 << 8) /* Bit 8: Compensation cell ready flag */ + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SYSCFG_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_uart.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..50d5f949f5fe62ce6bce527a90e82e2882287035 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_uart.h @@ -0,0 +1,369 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32f74xxf75xx_uart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32F7_CHIP_STM32F74XX75XX_UART_H +#define __ARCH_ARM_STC_STM32F7_CHIP_STM32F74XX75XX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_USART_CR1_OFFSET 0x0000 /* Control register 1 */ +#define STM32_USART_CR2_OFFSET 0x0004 /* Control register 2 */ +#define STM32_USART_CR3_OFFSET 0x0008 /* Control register 3 */ +#define STM32_USART_BRR_OFFSET 0x000c /* Baud Rate Register (32-bits) */ +#define STM32_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ +#define STM32_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ +#define STM32_USART_RQR_OFFSET 0x0018 /* Request register */ +#define STM32_USART_ISR_OFFSET 0x001c /* Interrupt & status register */ +#define STM32_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ +#define STM32_USART_RDR_OFFSET 0x0024 /* Receive data register */ +#define STM32_USART_TDR_OFFSET 0x0028 /* Transmit data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32F7_NUSART > 0 +# define STM32_USART1_CR1 (STM32_USART1_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART1_CR2 (STM32_USART1_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART1_CR3 (STM32_USART1_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART1_BRR (STM32_USART1_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART1_RTOR (STM32_USART1_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART1_RQR (STM32_USART1_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART1_GTPR (STM32_USART1_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART1_ISR (STM32_USART1_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART1_ICR (STM32_USART1_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART1_RDR (STM32_USART1_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART1_TDR (STM32_USART1_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUSART > 1 +# define STM32_USART2_CR1 (STM32_USART2_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART2_RTOR (STM32_USART2_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART2_RQR (STM32_USART2_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART2_ISR (STM32_USART2_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART2_ICR (STM32_USART2_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART2_RDR (STM32_USART2_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART2_TDR (STM32_USART2_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUSART > 2 +# define STM32_USART3_CR1 (STM32_USART3_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART3_RTOR (STM32_USART3_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART3_RQR (STM32_USART3_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART3_ISR (STM32_USART3_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART3_ICR (STM32_USART3_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART3_RDR (STM32_USART3_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART3_TDR (STM32_USART3_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUSART > 3 +# define STM32_USART6_CR1 (STM32_USART6_BASE+STM32_USART_CR1_OFFSET) +# define STM32_USART6_CR2 (STM32_USART6_BASE+STM32_USART_CR2_OFFSET) +# define STM32_USART6_CR3 (STM32_USART6_BASE+STM32_USART_CR3_OFFSET) +# define STM32_USART6_BRR (STM32_USART6_BASE+STM32_USART_BRR_OFFSET) +# define STM32_USART6_GTPR (STM32_USART6_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART6_RTOR (STM32_USART6_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_USART6_RQR (STM32_USART6_BASE+STM32_USART_RQR_OFFSET) +# define STM32_USART6_GTPR (STM32_USART6_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_USART6_ISR (STM32_USART6_BASE+STM32_USART_ISR_OFFSET) +# define STM32_USART6_ICR (STM32_USART6_BASE+STM32_USART_ICR_OFFSET) +# define STM32_USART6_RDR (STM32_USART6_BASE+STM32_USART_RDR_OFFSET) +# define STM32_USART6_TDR (STM32_USART6_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUART > 0 +# define STM32_UART4_CR1 (STM32_UART4_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART4_GTPR (STM32_UART4_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART4_RTOR (STM32_UART4_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART4_RQR (STM32_UART4_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART4_GTPR (STM32_UART4_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART4_ISR (STM32_UART4_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART4_ICR (STM32_UART4_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART4_RDR (STM32_UART4_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART4_TDR (STM32_UART4_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUART > 1 +# define STM32_UART5_CR1 (STM32_UART5_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART5_GTPR (STM32_UART5_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART5_RTOR (STM32_UART5_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART5_RQR (STM32_UART5_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART5_GTPR (STM32_UART5_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART5_ISR (STM32_UART5_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART5_ICR (STM32_UART5_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART5_RDR (STM32_UART5_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART5_TDR (STM32_UART5_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUART > 2 +# define STM32_UART7_CR1 (STM32_UART7_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART7_CR2 (STM32_UART7_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART7_CR3 (STM32_UART7_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART7_BRR (STM32_UART7_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART7_GTPR (STM32_UART7_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART7_RTOR (STM32_UART7_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART7_RQR (STM32_UART7_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART7_GTPR (STM32_UART7_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART7_ISR (STM32_UART7_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART7_ICR (STM32_UART7_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART7_RDR (STM32_UART7_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART7_TDR (STM32_UART7_BASE+STM32_USART_TDR_OFFSET) +#endif + +#if STM32F7_NUART > 3 +# define STM32_UART8_CR1 (STM32_UART8_BASE+STM32_USART_CR1_OFFSET) +# define STM32_UART8_CR2 (STM32_UART8_BASE+STM32_USART_CR2_OFFSET) +# define STM32_UART8_CR3 (STM32_UART8_BASE+STM32_USART_CR3_OFFSET) +# define STM32_UART8_BRR (STM32_UART8_BASE+STM32_USART_BRR_OFFSET) +# define STM32_UART8_GTPR (STM32_UART8_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART8_RTOR (STM32_UART8_BASE+STM32_USART_RTOR_OFFSET) +# define STM32_UART8_RQR (STM32_UART8_BASE+STM32_USART_RQR_OFFSET) +# define STM32_UART8_GTPR (STM32_UART8_BASE+STM32_USART_GTPR_OFFSET) +# define STM32_UART8_ISR (STM32_UART8_BASE+STM32_USART_ISR_OFFSET) +# define STM32_UART8_ICR (STM32_UART8_BASE+STM32_USART_ICR_OFFSET) +# define STM32_UART8_RDR (STM32_UART8_BASE+STM32_USART_RDR_OFFSET) +# define STM32_UART8_TDR (STM32_UART8_BASE+STM32_USART_TDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define USART_CR1_UE (1 << 0) /* Bit 0: USART enable */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Receiver wakeup method */ +#define USART_CR1_M0 (1 << 12) /* Bit 12: Word length, bit 0 */ +#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ +#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ +#define USART_CR1_DEDT_SHIFT (16) /* Bits 16-20: Driver Enable deassertion time */ +#define USART_CR1_DEDT_MASK (31 << USART_CR1_DEDT_SHIFT) +# define USART_CR1_DEDT(n) ((uint32_t)(n) << USART_CR1_DEDT_SHIFT) +#define USART_CR1_DEAT_SHIFT (21) /* Bits 21-25: Driver Enable assertion time */ +#define USART_CR1_DEAT_MASK (31 << USART_CR1_DEAT_SHIFT) +# define USART_CR1_DEAT(n) ((uint32_t)(n) << USART_CR1_DEAT_SHIFT) +#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of Block interrupt enable */ +#define USART_CR1_M1 (1 << 28) /* Bit 31: Word length, bit 1 */ + +#define USART_CR1_ALLINTS \ + (USART_CR1_IDLEIE | USART_CR1_RXNEIE | USART_CR1_TCIE | USART_CR1_TXEIE |\ + USART_CR1_PEIE | USART_CR1_CMIE |USART_CR1_RTOIE | USART_CR1_EOBIE) + +/* Control register 2 */ + +#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: :7-/4-bit Address Detection */ +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ +#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ +#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ +#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ +#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ +#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto baud rate enable */ +#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Auto baud rate mode */ +#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) +# define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* Start bit */ +# define USART_CR2_ABRMOD_FALL (1 << USART_CR2_ABRMOD_SHIFT) /* Falling edge measurement */ +# define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 0x7F frame detection */ +# define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 0x55 frame detection */ +#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ +#define USART_CR2_ADD4L_SHIFT (24) /* Bits 24-27: Address[3:0]:of the USART node */ +#define USART_CR2_ADD4L_MASK (15 << USART_CR2_ADD4L_SHIFT) +# define USART_CR2_ADD4L(n) ((uint32_t)(n) << USART_CR2_ADD4L_SHIFT) +#define USART_CR2_ADD4H_SHIFT (28) /* Bits 28-31: Address[4:0] of the USART node */ +#define USART_CR2_ADD4H_MASK (15 << USART_CR2_ADD4H_SHIFT) +# define USART_CR2_ADD4H(n) ((uint32_t)(n) << USART_CR2_ADD4H_SHIFT) +#define USART_CR2_ADD8_SHIFT (24) /* Bits 24-31: Address[7:0] of the USART node */ +#define USART_CR2_ADD8_MASK (255 << USART_CR2_ADD8_SHIFT) +# define USART_CR2_ADD8(n) ((uint32_t)(n) << USART_CR2_ADD8_SHIFT) + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR1_ONEBIT (1 << 11) /* Bit 11: One sample bit method enable */ +#define USART_CR1_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ +#define USART_CR1_DDRE (1 << 13) /* Bit 13: DMA Disable on Reception Error */ +#define USART_CR1_DEM (1 << 14) /* Bit 14: Driver enable mode */ +#define USART_CR1_DEP (1 << 15) /* Bit 15: Driver enable polarity selection */ +#define USART_CR1_SCARCNT_SHIFT (17) /* Bit 17-19: Smartcard auto-retry count */ +#define USART_CR1_SCARCNT_MASK (7 << USART_CR1_SCARCNT_SHIFT) +# define USART_CR1_SCARCNT(n) ((uint32_t)(n) << USART_CR1_SCARCNT_SHIFT) + +/* Baud Rate Register */ + +#define USART_BRR_SHIFT (0) /* Bits 0-15: USARTDIV[15:0] OVER8=0*/ +#define USART_BRR_MASK (0xffff << USART_BRR_SHIFT) +# define USART_BRR(n) ((uint32_t)(n) << USART_BRR_SHIFT) +#define USART_BRR_0_3_SHIFT (0) /* Bits 0-2: USARTDIV[3:0] OVER8=1 */ +#define USART_BRR_0_3_MASK (0x0fff << USART_BRR_0_3_SHIFT) +# define USART_BRR_0_3(n) ((uint32_t)(n) << USART_BRR_0_3_SHIFT) +#define USART_BRR_4_7_SHIFT (0) /* Bits 4-15: USARTDIV[15:4] OVER8=1*/ +#define USART_BRR_4_7_MASK (0xffff << USART_BRR_4_7_SHIFT) +# define USART_BRR_4_7(n) ((uint32_t)(n) << USART_BRR_4_7_SHIFT) + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +# define USART_GTPR_PSC(n) ((uint32_t)(n) << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) +# define USART_GTPR_GT(n) ((uint32_t)(n) << USART_GTPR_GT_SHIFT) + +/* Receiver timeout register */ + +#define USART_RTOR_RTO_SHIFT (0) /* Bits 0-23: Receiver timeout value */ +#define USART_RTOR_RTO_MASK (0xffffff << USART_RTOR_RTO_SHIFT) +# define USART_RTOR_RTO(n) ((uint32_t)(n) << USART_RTOR_RTO_SHIFT) +#define USART_RTOR_BLEN_SHIFT (24) /* Bits 24-31: Block Length */ +#define USART_RTOR_BLEN_MASK (0xff << USART_RTOR_BLEN_SHIFT) +# define USART_RTOR_BLEN(n) ((uint32_t)(n) << USART_RTOR_BLEN_SHIFT) + +/* Request register */ + +#define USART_RQR_ABRRQ (1 << 0) /* Bit 0: Auto baud rate request */ +#define USART_RQR_SBKRQ (1 << 1) /* Bit 1: Send break request */ +#define USART_RQR_MMRQ (1 << 2) /* Bit 2: Mute mode request */ +#define USART_RQR_RXFRQ (1 << 3) /* Bit 3: Receive data flush request */ +#define USART_RQR_TXFRQ (1 << 4) /* Bit 4: Transmit data flush request */ + +/* Interrupt & status register */ + +#define USART_ISR_PE (1 << 0) /* Bit 0: Parity error */ +#define USART_ISR_FE (1 << 1) /* Bit 1: Framing error */ +#define USART_ISR_NF (1 << 2) /* Bit 2: Noise detected flag */ +#define USART_ISR_ORE (1 << 3) /* Bit 3: Overrun error */ +#define USART_ISR_IDLE (1 << 4) /* Bit 4: Idle line detected */ +#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read data register not empty */ +#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission complete */ +#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit data register empty */ +#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN break detection flag */ +#define USART_ISR_CTSIF (1 << 9) /* Bit 9: CTS interrupt flag */ +#define USART_ISR_CTS (1 << 10) /* Bit 10: CTS flag */ +#define USART_ISR_RTOF (1 << 11) /* Bit 11: Receiver timeout */ +#define USART_ISR_EOBF (1 << 12) /* Bit 12: End of block flag */ +#define USART_ISR_ABRE (1 << 14) /* Bit 14: Auto baud rate error */ +#define USART_ISR_ABRF (1 << 15) /* Bit 15: Auto baud rate flag */ +#define USART_ISR_BUSY (1 << 16) /* Bit 16: Busy flag */ +#define USART_ISR_CMF (1 << 17) /* Bit 17: Character match flag */ +#define USART_ISR_SBKF (1 << 18) /* Bit 18: Send break flag */ +#define USART_ISR_TEACK (1 << 21) /* Bit 21: Transmit enable acknowledge flag */ + +#define USART_ISR_ALLBITS (0x0027dfff) + +/* Interrupt flag clear register */ + +#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ +#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ +#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected flag *clear flag */ +#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ +#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ +#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete */ +#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ +#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS interrupt clear flag */ +#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ +#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ + +#define USART_ICR_ALLBITS (0x00021b5f) + +/* Receive data register */ + +#define USART_RDR_SHIFT (0) /* Bits 8:0: Receive data value */ +#define USART_RDR_MASK (0x1ff << USART_RDR_SHIFT) + +/* Transmit data register */ + +#define USART_TDR_SHIFT (0) /* Bits 8:0: Transmit data value */ +#define USART_TDR_MASK (0x1ff << USART_TDR_SHIFT) + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* __ARCH_ARM_STC_STM32F7_CHIP_STM32F74XX75XX_UART_H */ diff --git a/arch/arm/src/stm32f7/stm32_allocateheap.c b/arch/arm/src/stm32f7/stm32_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..919890b83343e00298d30f92735610845e72348d --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_allocateheap.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/up_allocateheap.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Internal SRAM is available in all members of the STM32 family. The + * following definitions must be provided to specify the size and + * location of internal(system) SRAM: + * + * CONFIG_RAM_END : End address (+1) of SRAM (F1 family only, the + * : F4 family uses the a priori end of SRAM) + * + * In addition to internal SRAM, SRAM may also be available through the FSMC. + * In order to use FSMC SRAM, the following additional things need to be + * present in the NuttX configuration file: + * + * CONFIG_STM32F7_FSMC=y : Enables the FSMC + * CONFIG_STM32F7_FSMC_SRAM=y : Indicates that SRAM is available via the + * FSMC (as opposed to an LCD or FLASH). + * CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC + * address space + * CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC + * address space + * CONFIG_MM_REGIONS : Must be set to a large enough value to + * include the FSMC SRAM (as determined by + * the rules provided below) + */ + +/* Set the start and end of SRAM1 and SRAM2 */ + +#define SRAM1_START STM32_SRAM1_BASE +#define SRAM1_END (SRAM1_START + STM32F7_SRAM1_SIZE) + +#define SRAM2_START STM32_SRAM2_BASE +#define SRAM2_END (SRAM2_START + STM32F7_SRAM2_SIZE) + +/* We can't possibly have FSMC SRAM if the FSMC is not enabled */ + +#ifndef CONFIG_STM32F7_FSMC +# undef CONFIG_STM32F7_FSMC_SRAM +#endif + +/* If FSMC SRAM is going to be used as heap, then verify that the starting + * address and size of the external SRAM region has been provided in the + * configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE). + */ + +#ifdef CONFIG_STM32F7_FSMC_SRAM +# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE) +# error CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided +# undef CONFIG_STM32F7_FSMC_SRAM +# endif +#endif + +/* There are 3 possible heap configurations: + * + * Configuration 1. System SRAM1 (only) + * CONFIG_MM_REGIONS == 1 + * CONFIG_STM32F7_FSMC_SRAM NOT defined + * Configuration 2. System SRAM1 and SRAM2 + * CONFIG_MM_REGIONS == 2 + * CONFIG_STM32F7_FSMC_SRAM NOT defined + * Configuration 3. System SRAM1 and SRAM2 and FSMC SRAM + * CONFIG_MM_REGIONS == 3 + * CONFIG_STM32F7_FSMC_SRAM defined + * + * Let's make sure that all definitions are consistent before doing + * anything else + */ + +#if CONFIG_MM_REGIONS < 2 +# ifdef CONFIG_STM32F7_FSMC_SRAM +# warning FSMC SRAM and SRAM2 excluded from the heap +# else +# warning "SRAM2 excluded from the heap" +# endif +#elif CONFIG_MM_REGIONS < 3 +# ifdef CONFIG_STM32F7_FSMC_SRAM +# warning FSMC SRAM excluded from the heap +# endif +#elif CONFIG_MM_REGIONS < 4 +# ifndef CONFIG_STM32F7_FSMC_SRAM +# error CONFIG_MM_REGIONS > 2 but I do not know what some of the region(s) are +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 2 +# endif +#else +# error CONFIG_MM_REGIONS > 3 but I do not know what some of the region(s) are +# undef CONFIG_MM_REGIONS +# ifdef CONFIG_STM32F7_FSMC_SRAM +# define CONFIG_MM_REGIONS 3 +# else +# define CONFIG_MM_REGIONS 2 +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_HEAP +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)ubase, usize); + + /* Allow user-mode access to the user heap memory */ + + stm32_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SRAM1_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the STM32F20xxx/STM32F40xxx SRAM2 heap */ + + stm32_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END-SRAM2_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + + /* Add the STM32F20xxx/STM32F40xxx SRAM2 user heap region. */ + + kumm_addregion((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + +#ifdef CONFIG_STM32F7_FSMC_SRAM +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the FSMC SRAM user heap memory */ + + stm32_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + + /* Add the external FSMC SRAM user heap region. */ + + kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/stm32f7/stm32_config.h b/arch/arm/src/stm32f7/stm32_config.h new file mode 100644 index 0000000000000000000000000000000000000000..09762b9c6b6b8a5ce7043297703d3cffbebf23a1 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_config.h @@ -0,0 +1,292 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_CONFIG_H +#define __ARCH_ARM_SRC_STM32F7_STM32_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* GPIO IRQs ****************************************************************/ + +#ifndef CONFIG_STM32F7_GPIO_IRQ +# undef CONFIG_STM32F7_GPIOA_IRQ +# undef CONFIG_STM32F7_GPIOB_IRQ +# undef CONFIG_STM32F7_GPIOC_IRQ +# undef CONFIG_STM32F7_GPIOD_IRQ +# undef CONFIG_STM32F7_GPIOE_IRQ +#endif + +#if STM32F7_NPORTS < 1 +# undef CONFIG_STM32F7_GPIOA_IRQ +#endif +#if STM32F7_NPORTS < 2 +# undef CONFIG_STM32F7_GPIOB_IRQ +#endif +#if STM32F7_NPORTS < 3 +# undef CONFIG_STM32F7_GPIOC_IRQ +#endif +#if STM32F7_NPORTS < 4 +# undef CONFIG_STM32F7_GPIOD_IRQ +#endif +#if STM32F7_NPORTS < 5 +# undef CONFIG_STM32F7_GPIOE_IRQ +#endif + +/* UARTs ********************************************************************/ +/* Don't enable UARTs not supported by the chip. */ + +#if STM32F7_NUART < 1 +# undef CONFIG_STM32F7_UART0 +# undef CONFIG_STM32F7_UART1 +# undef CONFIG_STM32F7_UART2 +# undef CONFIG_STM32F7_UART3 +# undef CONFIG_STM32F7_UART4 +#elif STM32F7_NUART < 2 +# undef CONFIG_STM32F7_UART1 +# undef CONFIG_STM32F7_UART2 +# undef CONFIG_STM32F7_UART3 +# undef CONFIG_STM32F7_UART4 +#elif STM32F7_NUART < 3 +# undef CONFIG_STM32F7_UART2 +# undef CONFIG_STM32F7_UART3 +# undef CONFIG_STM32F7_UART4 +#elif STM32F7_NUART < 4 +# undef CONFIG_STM32F7_UART3 +# undef CONFIG_STM32F7_UART4 +#elif STM32F7_NUART < 5 +# undef CONFIG_STM32F7_UART4 +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_STM32F7_UART0) || defined(CONFIG_STM32F7_UART1) || \ + defined(CONFIG_STM32F7_UART2) || defined(CONFIG_STM32F7_UART3) || \ + defined(CONFIG_STM32F7_UART4) +# define HAVE_UART_DEVICE 1 +#endif + +/* USARTs *******************************************************************/ +/* If the USART is not being used as a UART, then it really isn't enabled + * for our purposes. + */ + +#ifndef CONFIG_USART0_ISUART +# undef CONFIG_STM32F7_USART0 +#endif +#ifndef CONFIG_USART1_ISUART +# undef CONFIG_STM32F7_USART1 +#endif +#ifndef CONFIG_USART2_ISUART +# undef CONFIG_STM32F7_USART2 +#endif + +/* Don't enable USARTs not supported by the chip. */ + +#if STM32F7_NUSART < 1 +# undef CONFIG_STM32F7_USART0 +# undef CONFIG_STM32F7_USART1 +# undef CONFIG_STM32F7_USART2 +#elif STM32F7_NUSART < 2 +# undef CONFIG_STM32F7_USART1 +# undef CONFIG_STM32F7_USART2 +#elif STM32F7_NUSART < 3 +# undef CONFIG_STM32F7_USART2 +#endif + +/* Are any USARTs enabled? */ + +#if defined(CONFIG_STM32F7_USART0) || defined(CONFIG_STM32F7_USART1) || \ + defined(CONFIG_STM32F7_USART2) +# undef HAVE_UART_DEVICE +# define HAVE_UART_DEVICE 1 +#endif + +/* UART Flow Control ********************************************************/ +/* UARTs do not support flow control */ + +#undef CONFIG_UART0_IFLOWCONTROL +#undef CONFIG_UART1_IFLOWCONTROL +#undef CONFIG_UART2_IFLOWCONTROL +#undef CONFIG_UART3_IFLOWCONTROL +#undef CONFIG_UART4_IFLOWCONTROL + +/* Hardware flow control requires using DMAC channel (not yet supported) */ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +# warning PDC or DMAC support is required for RTS hardware flow control +# undef CONFIG_SERIAL_IFLOWCONTROL +# undef CONFIG_USART0_IFLOWCONTROL +# undef CONFIG_USART1_IFLOWCONTROL +# undef CONFIG_USART2_IFLOWCONTROL +#endif + +/* Serial Console ***********************************************************/ +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,..,STM32F7_NUART, or USARTn, n=1,.., STM32F7_NUSART + */ + +#undef HAVE_SERIAL_CONSOLE +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART4) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART0) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +#endif + +/* SPI ******************************************************************************/ +/* Don't enable SPI peripherals not supported by the chip. */ + +#if CHIP_NSPI < 1 +# undef CONFIG_STM32F7_SPI0 +# undef CONFIG_STM32F7_SPI1 +#elif CHIP_NSPI < 2 +# undef CONFIG_STM32F7_SPI1 +#endif + +#ifndef CONFIG_STM32F7_HAVE_SPI +# undef CONFIG_STM32F7_SPI0 +# undef CONFIG_STM32F7_SPI1 +#endif + +/* Are any SPI peripherals enabled? */ + +#if !defined(CONFIG_STM32F7_SPI0) && !defined(CONFIG_STM32F7_SPI0) +# undef CONFIG_STM32F7_HAVE_SPI +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_CONFIG_H */ diff --git a/arch/arm/src/stm32f7/stm32_dma.c b/arch/arm/src/stm32f7/stm32_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..ff904c1d6b0100a3d980e00a5fd32ba70fc046bf --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_dma.c @@ -0,0 +1,1054 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_dma.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "up_internal.h" +#include "sched/sched.h" +#include "stm32_dma.h" + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NSTREAMS 8 +#if STM32F7_NDMA > 1 +# define DMA2_NSTREAMS 8 +# define DMA_NSTREAMS (DMA1_NSTREAMS+DMA2_NSTREAMS) +#else +# define DMA_NSTREAMS DMA1_NSTREAMS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA stream base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes one DMA channel */ + +struct stm32_dma_s +{ + uint8_t stream; /* DMA stream number (0-7) */ + uint8_t irq; /* DMA stream IRQ number */ + uint8_t shift; /* ISR/IFCR bit shift value */ + uint8_t channel; /* DMA channel number (0-7) */ + sem_t sem; /* Used to wait for DMA channel to become available */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32_dma_s g_dma[DMA_NSTREAMS] = +{ + { + .stream = 0, + .irq = STM32_IRQ_DMA1S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA1S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA1S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA1S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA1S4, + .shift = DMA_INT_STREAM4_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA1S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA1S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA1S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA1_BASE + STM32_DMA_OFFSET(7), + }, +#if STM32F7_NDMA > 1 + { + .stream = 0, + .irq = STM32_IRQ_DMA2S0, + .shift = DMA_INT_STREAM0_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(0), + }, + { + .stream = 1, + .irq = STM32_IRQ_DMA2S1, + .shift = DMA_INT_STREAM1_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(1), + }, + { + .stream = 2, + .irq = STM32_IRQ_DMA2S2, + .shift = DMA_INT_STREAM2_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(2), + }, + { + .stream = 3, + .irq = STM32_IRQ_DMA2S3, + .shift = DMA_INT_STREAM3_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(3), + }, + { + .stream = 4, + .irq = STM32_IRQ_DMA2S4, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(4), + }, + { + .stream = 5, + .irq = STM32_IRQ_DMA2S5, + .shift = DMA_INT_STREAM5_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(5), + }, + { + .stream = 6, + .irq = STM32_IRQ_DMA2S6, + .shift = DMA_INT_STREAM6_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(6), + }, + { + .stream = 7, + .irq = STM32_IRQ_DMA2S7, + .shift = DMA_INT_STREAM7_SHIFT, + .base = STM32_DMA2_BASE + STM32_DMA_OFFSET(7), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(DMA_BASE(dmast->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmast->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmast_getreg(struct stm32_dma_s *dmast, uint32_t offset) +{ + return getreg32(dmast->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmast_putreg(struct stm32_dma_s *dmast, uint32_t offset, uint32_t value) +{ + putreg32(value, dmast->base + offset); +} + +/************************************************************************************ + * Name: stm32_dmatake() and stm32_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32_dmatake(FAR struct stm32_dma_s *dmast) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmast->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32_dmagive(FAR struct stm32_dma_s *dmast) +{ + (void)sem_post(&dmast->sem); +} + +/************************************************************************************ + * Name: stm32_dmastream + * + * Description: + * Get the g_dma table entry associated with a DMA controller and a stream number + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmastream(unsigned int stream, + unsigned int controller) +{ + int index; + + DEBUGASSERT(stream < DMA_NSTREAMS && controller < STM32F7_NDMA); + + /* Convert the controller + stream based on the fact that there are 8 streams + * per controller. + */ + +#if STM32F7_NDMA > 1 + index = controller << 3 | stream; +#else + index = stream; +#endif + + /* Then return the stream structure associated with the stream index */ + + return &g_dma[index]; +} + +/************************************************************************************ + * Name: stm32_dmamap + * + * Description: + * Get the g_dma table entry associated with a bit-encoded DMA selection + * + ************************************************************************************/ + +static inline FAR struct stm32_dma_s *stm32_dmamap(unsigned long dmamap) +{ + /* Extract the DMA controller number from the bit encoded value */ + + unsigned int controller = STM32_DMA_CONTROLLER(dmamap); + + /* Extact the stream number from the bit encoded value */ + + unsigned int stream = STM32_DMA_STREAM(dmamap); + + /* Return the table entry associated with the controller + stream */ + + return stm32_dmastream(stream, controller); +} + +/************************************************************************************ + * Name: stm32_dmastreamdisable + * + * Description: + * Disable the DMA stream + * + ************************************************************************************/ + +static void stm32_dmastreamdisable(struct stm32_dma_s *dmast) +{ + uint32_t regoffset; + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~DMA_SCR_ALLINTS; + + /* Disable the DMA stream */ + + regval &= ~DMA_SCR_EN; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); +} + +/************************************************************************************ + * Name: stm32_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32_dmainterrupt(int irq, void *context) +{ + struct stm32_dma_s *dmast; + uint32_t status; + uint32_t regoffset = 0; + unsigned int stream = 0; + unsigned int controller = 0; + + /* Get the stream and the controller that generated the interrupt */ + + if (irq >= STM32_IRQ_DMA1S0 && irq <= STM32_IRQ_DMA1S6) + { + stream = irq - STM32_IRQ_DMA1S0; + controller = DMA1; + } + else if (irq == STM32_IRQ_DMA1S7) + { + stream = 7; + controller = DMA1; + } + else +#if STM32F7_NDMA > 1 + if (irq >= STM32_IRQ_DMA2S0 && irq <= STM32_IRQ_DMA2S4) + { + stream = irq - STM32_IRQ_DMA2S0; + controller = DMA2; + } + else if (irq >= STM32_IRQ_DMA2S5 && irq <= STM32_IRQ_DMA2S7) + { + stream = irq - STM32_IRQ_DMA2S5 + 5; + controller = DMA2; + } + else +#endif + { + PANIC(); + } + + /* Get the stream structure from the stream and controller numbers */ + + dmast = stm32_dmastream(stream, controller); + + /* Select the interrupt status register (either the LISR or HISR) + * based on the stream number that caused the interrupt. + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LISR_OFFSET; + } + else + { + regoffset = STM32_DMA_HISR_OFFSET; + } + + /* Get the interrupt status for this stream */ + + status = (dmabase_getreg(dmast, regoffset) >> dmast->shift) & DMA_STREAM_MASK; + + /* Clear fetched stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (status << dmast->shift)); + + /* Invoke the callback */ + + if (dmast->callback) + { + dmast->callback(dmast, status, dmast->arg); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32_dma_s *dmast; + int stream; + + /* Initialize each DMA stream */ + + for (stream = 0; stream < DMA_NSTREAMS; stream++) + { + dmast = &g_dma[stream]; + sem_init(&dmast->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmast->irq, stm32_dmainterrupt); + + /* Disable the DMA stream */ + + stm32_dmastreamdisable(dmast); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmast->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmast->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * dmamap - Identifies the stream/channel resource. For the STM32 F4, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'dmamap' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'dmamap' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int dmamap) +{ + FAR struct stm32_dma_s *dmast; + + /* Get the stream index from the bit-encoded channel value */ + + dmast = stm32_dmamap(dmamap); + DEBUGASSERT(dmast != NULL); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32_dmatake(dmast); + + /* The caller now has exclusive use of the DMA channel. Assign the + * channel to the stream and return an opaque reference to the stream + * structure. + */ + + dmast->channel = STM32_DMA_CHANNEL(dmamap); + return (DMA_HANDLE)dmast; +} + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32_dmagive(dmast); +} + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t scr) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t regoffset; + uint32_t regval; + + dmadbg("paddr: %08x maddr: %08x ntransfers: %d scr: %08x\n", + paddr, maddr, ntransfers, scr); + +#ifdef CONFIG_STM32_DMACAPABLE + DEBUGASSERT(stm32_dmacapable(maddr, ntransfers, scr)); +#endif + + /* "If the stream is enabled, disable it by resetting the EN bit in the + * DMA_SxCR register, then read this bit in order to confirm that there is no + * ongoing stream operation. Writing this bit to 0 is not immediately + * effective since it is actually written to 0 once all the current transfers + * have finished. When the EN bit is read as 0, this means that the stream is + * ready to be configured. It is therefore necessary to wait for the EN bit + * to be cleared before starting any stream configuration. ..." + */ + + while ((dmast_getreg(dmast, STM32_DMA_SCR_OFFSET) & DMA_SCR_EN) != 0); + + /* "... All the stream dedicated bits set in the status register (DMA_LISR + * and DMA_HISR) from the previous data block DMA transfer should be cleared + * before the stream can be re-enabled." + * + * Clear pending stream interrupts by setting bits in the upper or lower IFCR + * register + */ + + if (dmast->stream < 4) + { + regoffset = STM32_DMA_LIFCR_OFFSET; + } + else + { + regoffset = STM32_DMA_HIFCR_OFFSET; + } + + dmabase_putreg(dmast, regoffset, (DMA_STREAM_MASK << dmast->shift)); + + /* "Set the peripheral register address in the DMA_SPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmast_putreg(dmast, STM32_DMA_SPAR_OFFSET, paddr); + + /* "Set the memory address in the DMA_SM0ARx ... register. The data will be + * written to or read from this memory after the peripheral event." + * + * Note that in double-buffered mode it is explicitly assumed that the second + * buffer immediately follows the first. + */ + + dmast_putreg(dmast, STM32_DMA_SM0AR_OFFSET, maddr); + if (scr & DMA_SCR_DBM) + { + dmast_putreg(dmast, STM32_DMA_SM1AR_OFFSET, maddr + ntransfers); + } + + /* "Configure the total number of data items to be transferred in the + * DMA_SNDTRx register. After each peripheral event, this value will be + * decremented." + * + * "When the peripheral flow controller is used for a given stream, the value + * written into the DMA_SxNDTR has no effect on the DMA transfer. Actually, + * whatever the value written, it will be forced by hardware to 0xFFFF as soon + * as the stream is enabled..." + */ + + dmast_putreg(dmast, STM32_DMA_SNDTR_OFFSET, ntransfers); + + /* "Select the DMA channel (request) using CHSEL[2:0] in the DMA_SxCR register." + * + * "Configure the stream priority using the PL[1:0] bits in the DMA_SCRx" + * register." + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PL_MASK | DMA_SCR_CHSEL_MASK); + regval |= scr & DMA_SCR_PL_MASK; + regval |= (uint32_t)dmast->channel << DMA_SCR_CHSEL_SHIFT; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); + + /* "Configure the FIFO usage (enable or disable, threshold in transmission and + * reception)" + * + * "Caution is required when choosing the FIFO threshold (bits FTH[1:0] of the + * DMA_SxFCR register) and the size of the memory burst (MBURST[1:0] of the + * DMA_SxCR register): The content pointed by the FIFO threshold must exactly + * match to an integer number of memory burst transfers. If this is not in the + * case, a FIFO error (flag FEIFx of the DMA_HISR or DMA_LISR register) will be + * generated when the stream is enabled, then the stream will be automatically + * disabled." + * + * The FIFO is disabled in circular mode when transferring data from a + * peripheral to memory, as in this case it is usually desirable to know that + * every byte from the peripheral is transferred immediately to memory. It is + * not practical to flush the DMA FIFO, as this requires disabling the channel + * which triggers the transfer-complete interrupt. + * + * NOTE: The FEIFx error interrupt is not enabled because the FEIFx seems to + * be reported spuriously causing good transfers to be marked as failures. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + regval &= ~(DMA_SFCR_FTH_MASK | DMA_SFCR_FS_MASK | DMA_SFCR_FEIE); + if (!((scr & (DMA_SCR_CIRC | DMA_SCR_DIR_MASK)) == (DMA_SCR_CIRC | DMA_SCR_DIR_P2M))) + { + regval |= (DMA_SFCR_FTH_FULL | DMA_SFCR_DMDIS); + } + + dmast_putreg(dmast, STM32_DMA_SFCR_OFFSET, regval); + + /* "Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register." + * + * Note: The CT bit is always reset. + */ + + regval = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regval &= ~(DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_CIRC | DMA_SCR_DBM | DMA_SCR_CT | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + scr &= (DMA_SCR_PFCTRL | DMA_SCR_DIR_MASK | DMA_SCR_PINC | DMA_SCR_MINC | + DMA_SCR_PSIZE_MASK | DMA_SCR_MSIZE_MASK | DMA_SCR_PINCOS | + DMA_SCR_DBM | DMA_SCR_CIRC | + DMA_SCR_PBURST_MASK | DMA_SCR_MBURST_MASK); + regval |= scr; + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, regval); +} + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t scr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked when the DMA completes */ + + dmast->callback = callback; + dmast->arg = arg; + + /* Activate the stream by setting the ENABLE bit in the DMA_SCRx register. + * As soon as the stream is enabled, it can serve any DMA request from the + * peripheral connected on the stream. + */ + + scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + scr |= DMA_SCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular + * and double-buffered modes, always interrupt on buffer wrap, and optionally + * interrupt at the halfway point. + */ + + if ((scr & (DMA_SCR_DBM | DMA_SCR_CIRC)) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + scr |= (half ? (DMA_SCR_HTIE | DMA_SCR_TEIE) : (DMA_SCR_TCIE | DMA_SCR_TEIE)); + } + else + { + /* In non-stop modes, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + scr |= (half ? DMA_SCR_HTIE : 0) | DMA_SCR_TCIE | DMA_SCR_TEIE; + } + + dmast_putreg(dmast, STM32_DMA_SCR_OFFSET, scr); +} + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + stm32_dmastreamdisable(dmast); +} + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Read the DMA bytes-remaining register. + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t residual; + + /* Fetch the count of bytes remaining to be transferred. + * + * If the FIFO is enabled, this count may be inaccurate. ST don't + * appear to document whether this counts the peripheral or the memory + * side of the channel, and they don't make the memory pointer + * available either. + * + * For reception in circular mode the FIFO is disabled in order that + * this value can be useful. + */ + + residual = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + + return (size_t)residual; +} + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size, burst_length; + uint32_t mend; + + dmavdbg("stm32_dmacapable: 0x%08x/%u 0x%08x\n", maddr, count, ccr); + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_SCR_MSIZE_MASK) + { + case DMA_SCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_SCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_SCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default: + dmavdbg("stm32_dmacapable: bad transfer size in CCR\n"); + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + dmavdbg("stm32_dmacapable: transfer unaligned\n"); + return false; + } + + /* Verify that burst transfers do not cross a 1KiB boundary. */ + + if ((maddr / 1024) != (mend / 1024)) + { + /* The transfer as a whole crosses a 1KiB boundary. + * Verify that no burst does by asserting that the address + * is aligned to the burst length. + */ + + switch (ccr & DMA_SCR_MBURST_MASK) + { + case DMA_SCR_MBURST_SINGLE: + burst_length = transfer_size; + break; + + case DMA_SCR_MBURST_INCR4: + burst_length = transfer_size << 2; + break; + + case DMA_SCR_MBURST_INCR8: + burst_length = transfer_size << 3; + break; + + case DMA_SCR_MBURST_INCR16: + burst_length = transfer_size << 4; + break; + + default: + dmavdbg("stm32_dmacapable: bad burst size in CCR\n"); + return false; + } + + if ((maddr & (burst_length - 1)) != 0) + { + dmavdbg("stm32_dmacapable: burst crosses 1KiB\n"); + return false; + } + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK)) + { + dmavdbg("stm32_dmacapable: transfer crosses memory region\n"); + return false; + } + + switch (maddr & STM32_REGION_MASK) + { + case STM32_FSMC_BANK1: + case STM32_FSMC_BANK2: + case STM32_FSMC_BANK3: + case STM32_FSMC_BANK4: + case STM32_SRAM_BASE: + /* All RAM is supported */ + + break; + + case STM32_CODE_BASE: + /* Everything except the CCM ram is supported */ + + if (maddr >= STM32_CCMRAM_BASE && + (maddr - STM32_CCMRAM_BASE) < 65536) + { + dmavdbg("stm32_dmacapable: transfer targets CCMRAM\n"); + return false; + } + break; + + default: + /* Everything else is unsupported by DMA */ + + dmavdbg("stm32_dmacapable: transfer targets unknown/unsupported region\n"); + return false; + } + + dmavdbg("stm32_dmacapable: transfer OK\n"); + return true; +} +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + irqstate_t flags; + + flags = enter_critical_section(); + regs->lisr = dmabase_getreg(dmast, STM32_DMA_LISR_OFFSET); + regs->hisr = dmabase_getreg(dmast, STM32_DMA_HISR_OFFSET); + regs->scr = dmast_getreg(dmast, STM32_DMA_SCR_OFFSET); + regs->sndtr = dmast_getreg(dmast, STM32_DMA_SNDTR_OFFSET); + regs->spar = dmast_getreg(dmast, STM32_DMA_SPAR_OFFSET); + regs->sm0ar = dmast_getreg(dmast, STM32_DMA_SM0AR_OFFSET); + regs->sm1ar = dmast_getreg(dmast, STM32_DMA_SM1AR_OFFSET); + regs->sfcr = dmast_getreg(dmast, STM32_DMA_SFCR_OFFSET); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg) +{ + struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmast->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" LISR[%08x]: %08x\n", dmabase + STM32_DMA_LISR_OFFSET, regs->lisr); + dmadbg(" HISR[%08x]: %08x\n", dmabase + STM32_DMA_HISR_OFFSET, regs->hisr); + dmadbg(" SCR[%08x]: %08x\n", dmast->base + STM32_DMA_SCR_OFFSET, regs->scr); + dmadbg(" SNDTR[%08x]: %08x\n", dmast->base + STM32_DMA_SNDTR_OFFSET, regs->sndtr); + dmadbg(" SPAR[%08x]: %08x\n", dmast->base + STM32_DMA_SPAR_OFFSET, regs->spar); + dmadbg(" SM0AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM0AR_OFFSET, regs->sm0ar); + dmadbg(" SM1AR[%08x]: %08x\n", dmast->base + STM32_DMA_SM1AR_OFFSET, regs->sm1ar); + dmadbg(" SFCR[%08x]: %08x\n", dmast->base + STM32_DMA_SFCR_OFFSET, regs->sfcr); +} +#endif + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ diff --git a/arch/arm/src/stm32f7/stm32_dma.h b/arch/arm/src/stm32f7/stm32_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..67c9cbf4c83c46f14557aba5153942b5859b6627 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_dma.h @@ -0,0 +1,298 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_dma.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_DMA_H +#define __ARCH_ARM_SRC_STM32F7_STM32_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/stm32_dma.h" + +/* These definitions provide the bit encoding of the 'status' parameter passed to the + * DMA callback function (see dma_callback_t). + */ + +#define DMA_STATUS_FEIF 0 /* Stream FIFO error (ignored) */ +#define DMA_STATUS_DMEIF DMA_STREAM_DMEIF_BIT /* Stream direct mode error */ +#define DMA_STATUS_TEIF DMA_STREAM_TEIF_BIT /* Stream Transfer Error */ +#define DMA_STATUS_HTIF DMA_STREAM_HTIF_BIT /* Stream Half Transfer */ +#define DMA_STATUS_TCIF DMA_STREAM_TCIF_BIT /* Stream Transfer Complete */ + +#define DMA_STATUS_ERROR (DMA_STATUS_FEIF|DMA_STATUS_DMEIF|DMA_STATUS_TEIF) +#define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA + * channel (F1) or a DMA stream (F4). + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the the + * completion of the DMA. NOTE: The DMA module does *NOT* perform any cache + * operations. It is the responsibility of the DMA client to invalidate DMA + * buffers after completion of the DMA RX operations. + * + * Input Parameters: + * handle - Refers tot he DMA channel or stream + * status - A bit encoded value that provides the completion status. See the + * DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when stm32_dmastart() was + * called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +struct stm32_dmaregs_s +{ + uint32_t lisr; + uint32_t hisr; + uint32_t scr; + uint32_t sndtr; + uint32_t spar; + uint32_t sm0ar; + uint32_t sm1ar; + uint32_t sfcr; +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chan' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32_dma.h. + * + * If the DMA channel is not available, then stm32_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chan - Identifies the stream/channel resource + * For the STM32 F1, this is simply the channel number as provided by + * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h. + * For the STM32 F4, this is a bit encoded value as provided by the + * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'chan' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chan' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int chan); + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr); + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer. NOTE: The DMA module does *NOT* perform any + * cache operations. It is the responsibility of the DMA client to clean + * DMA buffers after staring of the DMA TX operations. + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, + bool half); + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address with the given configuration. This depends on the internal + * connections in the ARM bus matrix of the processor. Note that this + * only applies to memory addresses, it will return false for any peripheral + * address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_DMACAPABLE +bool stm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr); +#else +# define stm32_dmacapable(maddr, count, ccr) (true) +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs); +#else +# define stm32_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg); +#else +# define stm32_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_DMA_H */ diff --git a/arch/arm/src/stm32f7/stm32_dtcm.c b/arch/arm/src/stm32f7/stm32_dtcm.c new file mode 100644 index 0000000000000000000000000000000000000000..07dc04e319a021d67349ad21b587b354821ad3b4 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_dtcm.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_dtcm.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stm32_dtcm.h" + +#ifdef HAVE_DTCM_HEAP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct mm_heap_s g_dtcm_heap; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* HAVE_DTCM_HEAP */ \ No newline at end of file diff --git a/arch/arm/src/stm32f7/stm32_dtcm.h b/arch/arm/src/stm32f7/stm32_dtcm.h new file mode 100644 index 0000000000000000000000000000000000000000..a3e76330e917e10d0c68bf8aacdefc7ee1c0293d --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_dtcm.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_dtcm.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_DTCM_H +#define __ARCH_ARM_SRC_STM32F7_STM32_DTCM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* Assume that we can support the DTCM heap */ + +#define HAVE_DTCM_HEAP 1 + +/* Only the STM32 F2, F3, and F4 have DTCM memory */ + +#if defined(CONFIG_STM32_STM32F30XX) +# define DTCM_START 0x10000000 +# define DTCM_END 0x10002000 +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define DTCM_START 0x10000000 +# define DTCM_END 0x10010000 +#else +# undef HAVE_DTCM_HEAP +#endif + +/* In order to use the DTCM heap, it had to have been excluded from the main + * heap. + */ + +#ifndef CONFIG_STM32_DTCMEXCLUDE +# undef HAVE_DTCM_HEAP +#endif + +/* Can we support the DTCM heap? */ + +#ifdef HAVE_DTCM_HEAP + +/* dtcm_initialize must be called early in initialization in order to + * initialize the DTCM heap. + */ + +#define dtcm_initialize() \ + mm_initialize(&g_dtcm_heap, (FAR void *)DTCM_START, DTCM_END-DTCM_START) + +/* The dtcm_addregion interface could be used if, for example, you want to + * add some other memory region to the DTCM heap. I don't really know why + * you might want to do that, but the functionality is essentially free. + */ + +#define dtcm_addregion(b,s) mm_addregion(&g_dtcm_heap, b, s); + +/* Then, once g_dtcm_heap has been setup by dtcm_initialize(), these memory + * allocators can be used just like the standard memory allocators. + */ + +#define dtcm_malloc(s) mm_malloc(&g_dtcm_heap, s) +#define dtcm_zalloc(s) mm_zalloc(&g_dtcm_heap, s) +#define dtcm_calloc(n,s) mm_calloc(&g_dtcm_heap, n,s) +#define dtcm_free(p) mm_free(&g_dtcm_heap, p) +#define dtcm_realloc(p,s) mm_realloc(&g_dtcm_heap, p, s) +#define dtcm_memalign(a,s) mm_memalign(&g_dtcm_heap, a, s) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN struct mm_heap_s g_dtcm_heap; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* HAVE_DTCM_HEAP */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_DTCM_H */ diff --git a/arch/arm/src/stm32f7/stm32_dumpgpio.c b/arch/arm/src/stm32f7/stm32_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..e1772e89cd10fb809224b416cb9ebb7539fef43c --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_dumpgpio.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_gpio.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" + +#ifdef CONFIG_DEBUG + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Port letters for prettier debug output */ + +#ifdef CONFIG_DEBUG +static const char g_portchar[STM32F7_NGPIO] = +{ +#if STM32F7_NGPIO > 11 +# error "Additional support required for this number of GPIOs" +#elif STM32F7_NGPIO > 10 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' +#elif STM32F7_NGPIO > 9 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' +#elif STM32F7_NGPIO > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif STM32F7_NGPIO > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif STM32F7_NGPIO > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif STM32F7_NGPIO > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif STM32F7_NGPIO > 4 + 'A', 'B', 'C', 'D', 'E' +#elif STM32F7_NGPIO > 3 + 'A', 'B', 'C', 'D' +#elif STM32F7_NGPIO > 2 + 'A', 'B', 'C' +#elif STM32F7_NGPIO > 1 + 'A', 'B' +#elif STM32F7_NGPIO > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin configuration + * + ****************************************************************************/ + +int stm32_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uint32_t base; + unsigned int port; + + /* Get the base address associated with the GPIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + + DEBUGASSERT(port < STM32F7_NGPIO); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + if ((getreg32(STM32_RCC_AHB1ENR) & RCC_AHB1ENR_GPIOEN(port)) != 0) + { + lldbg(" MODE: %08x OTYPE: %04x OSPEED: %08x PUPDR: %08x\n", + getreg32(base + STM32_GPIO_MODER_OFFSET), + getreg32(base + STM32_GPIO_OTYPER_OFFSET), + getreg32(base + STM32_GPIO_OSPEED_OFFSET), + getreg32(base + STM32_GPIO_PUPDR_OFFSET)); + lldbg(" IDR: %04x ODR: %04x LCKR: %05x\n", + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + lldbg(" AFRH: %08x AFRL: %08x\n", + getreg32(base + STM32_GPIO_AFRH_OFFSET), + getreg32(base + STM32_GPIO_AFRL_OFFSET)); + } + else + { + lldbg(" GPIO%c not enabled: AHB1ENR: %08x\n", + g_portchar[port], getreg32(STM32_RCC_AHB1ENR)); + } + + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/stm32f7/stm32_ethernet.c b/arch/arm/src/stm32f7/stm32_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..4cf496a4eb9c996156a27c6ace0b3bdd8bfc6208 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_ethernet.c @@ -0,0 +1,4334 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_ethernet.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include +#if defined(CONFIG_NET_PKT) +# include +#endif + +#include "cache.h" +#include "up_internal.h" + +#include "chip/stm32_syscfg.h" +#include "chip/stm32_pinmap.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" +#include "stm32_ethernet.h" + +#include + +/* STM32F7_NETHERNET determines the number of physical interfaces that can + * be supported by the hardware. CONFIG_STM32F7_ETHMAC will defined if + * any STM32F7 Ethernet support is enabled in the configuration. + */ + +#if STM32F7_NETHERNET > 0 && defined(CONFIG_STM32F7_ETHMAC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* See configs/stm3240g-eval/README.txt for an explanation of the configuration + * settings. + */ + +#if STM32F7_NETHERNET > 1 +# error "Logic to support multiple Ethernet interfaces is incomplete" +#endif + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +#ifndef CONFIG_STM32F7_PHYADDR +# error "CONFIG_STM32F7_PHYADDR must be defined in the NuttX configuration" +#endif + +#if !defined(CONFIG_STM32F7_MII) && !defined(CONFIG_STM32F7_RMII) +# warning "Neither CONFIG_STM32F7_MII nor CONFIG_STM32F7_RMII defined" +#endif + +#if defined(CONFIG_STM32F7_MII) && defined(CONFIG_STM32F7_RMII) +# error "Both CONFIG_STM32F7_MII and CONFIG_STM32F7_RMII defined" +#endif + +#ifdef CONFIG_STM32F7_MII +# if !defined(CONFIG_STM32F7_MII_MCO1) && !defined(CONFIG_STM32F7_MII_MCO2) && \ + !defined(CONFIG_STM32F7_MII_EXTCLK) +# warning "Neither CONFIG_STM32F7_MII_MCO1, CONFIG_STM32F7_MII_MCO2, nor CONFIG_STM32F7_MII_EXTCLK defined" +# endif +# if defined(CONFIG_STM32F7_MII_MCO1) && defined(CONFIG_STM32F7_MII_MCO2) +# error "Both CONFIG_STM32F7_MII_MCO1 and CONFIG_STM32F7_MII_MCO2 defined" +# endif +#endif + +#ifdef CONFIG_STM32F7_RMII +# if !defined(CONFIG_STM32F7_RMII_MCO1) && !defined(CONFIG_STM32F7_RMII_MCO2) && \ + !defined(CONFIG_STM32F7_RMII_EXTCLK) +# warning "Neither CONFIG_STM32F7_RMII_MCO1, CONFIG_STM32F7_RMII_MCO2, nor CONFIG_STM32F7_RMII_EXTCLK defined" +# endif +# if defined(CONFIG_STM32F7_RMII_MCO1) && defined(CONFIG_STM32F7_RMII_MCO2) +# error "Both CONFIG_STM32F7_RMII_MCO1 and CONFIG_STM32F7_RMII_MCO2 defined" +# endif +#endif + +#ifdef CONFIG_STM32F7_AUTONEG +# ifndef CONFIG_STM32F7_PHYSR +# error "CONFIG_STM32F7_PHYSR must be defined in the NuttX configuration" +# endif +# ifdef CONFIG_STM32F7_PHYSR_ALTCONFIG +# ifndef CONFIG_STM32F7_PHYSR_ALTMODE +# error "CONFIG_STM32F7_PHYSR_ALTMODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_10HD +# error "CONFIG_STM32F7_PHYSR_10HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_100HD +# error "CONFIG_STM32F7_PHYSR_100HD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_10FD +# error "CONFIG_STM32F7_PHYSR_10FD must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_100FD +# error "CONFIG_STM32F7_PHYSR_100FD must be defined in the NuttX configuration" +# endif +# else +# ifndef CONFIG_STM32F7_PHYSR_SPEED +# error "CONFIG_STM32F7_PHYSR_SPEED must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_100MBPS +# error "CONFIG_STM32F7_PHYSR_100MBPS must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_MODE +# error "CONFIG_STM32F7_PHYSR_MODE must be defined in the NuttX configuration" +# endif +# ifndef CONFIG_STM32F7_PHYSR_FULLDUPLEX +# error "CONFIG_STM32F7_PHYSR_FULLDUPLEX must be defined in the NuttX configuration" +# endif +# endif +#endif + +#ifdef CONFIG_STM32F7_ETH_PTP +# warning "CONFIG_STM32F7_ETH_PTP is not yet supported" +#endif + +/* This driver does not use enhanced descriptors. Enhanced descriptors must + * be used, however, if time stamping or and/or IPv4 checksum offload is + * supported. + */ + +#undef CONFIG_STM32F7_ETH_ENHANCEDDESC +#undef CONFIG_STM32F7_ETH_HWCHECKSUM + +/* Ethernet buffer sizes, number of buffers, and number of descriptors */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER is required" +#endif + +/* Add 4 to the configured buffer size to account for the 2 byte checksum + * memory needed at the end of the maximum size packet. Buffer sizes must + * be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We + * will use the 16-byte alignment in all cases. + */ + +#define OPTIMAL_ETH_BUFSIZE ((CONFIG_NET_ETH_MTU + 4 + 15) & ~15) + +#ifdef CONFIG_STM32F7_ETH_BUFSIZE +# define ETH_BUFSIZE CONFIG_STM32F7_ETH_BUFSIZE +#else +# define ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE +#endif + +#if ETH_BUFSIZE > ETH_TDES1_TBS1_MASK +# error "ETH_BUFSIZE is too large" +#endif + +#if (ETH_BUFSIZE & 15) != 0 +# error "ETH_BUFSIZE must be aligned" +#endif + +#if ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE +# warning "You using an incomplete/untested configuration" +#endif + +#ifndef CONFIG_STM32F7_ETH_NRXDESC +# define CONFIG_STM32F7_ETH_NRXDESC 8 +#endif +#ifndef CONFIG_STM32F7_ETH_NTXDESC +# define CONFIG_STM32F7_ETH_NTXDESC 4 +#endif + +/* We need at least one more free buffer than transmit buffers */ + +#define STM32_ETH_NFREEBUFFERS (CONFIG_STM32F7_ETH_NTXDESC+1) + +/* Buffers use fro DMA access must begin on an address aligned with the + * D-Cache line and must be an even multiple of the D-Cache line size. + * These size/alignment requirements are necessary so that D-Cache flush + * and invalidate operations will not have any additional effects. + * + * The TX and RX descriptors are normally 16 bytes in size but could be + * 32 bytes in size if the enhanced descriptor format is used (it is not). + */ + +#define DMA_BUFFER_MASK (ARMV7M_DCACHE_LINESIZE - 1) +#define DMA_ALIGN_UP(n) (((n) + DMA_BUFFER_MASK) & ~DMA_BUFFER_MASK) +#define DMA_ALIGN_DOWN(n) ((n) & ~DMA_BUFFER_MASK) + +#ifndef CONFIG_STM32F7_ETH_ENHANCEDDESC +# define RXDESC_SIZE 16 +# define TXDESC_SIZE 16 +#else +# define RXDESC_SIZE 32 +# define TXDESC_SIZE 32 +#endif + +#define RXDESC_PADSIZE DMA_ALIGN_UP(RXDESC_SIZE) +#define TXDESC_PADSIZE DMA_ALIGN_UP(TXDESC_SIZE) +#define ALIGNED_BUFSIZE DMA_ALIGN_UP(ETH_BUFSIZE) + +#define RXTABLE_SIZE (STM32F7_NETHERNET * CONFIG_STM32F7_ETH_NRXDESC) +#define TXTABLE_SIZE (STM32F7_NETHERNET * CONFIG_STM32F7_ETH_NTXDESC) + +#define RXBUFFER_SIZE (CONFIG_STM32F7_ETH_NRXDESC * ALIGNED_BUFSIZE) +#define RXBUFFER_ALLOC (STM32F7_NETHERNET * RXBUFFER_SIZE) + +#define TXBUFFER_SIZE (STM32_ETH_NFREEBUFFERS * ALIGNED_BUFSIZE) +#define TXBUFFER_ALLOC (STM32F7_NETHERNET * TXBUFFER_SIZE) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_STM32F7_ETHMAC_REGDEBUG +#endif + +/* Clocking *****************************************************************/ +/* Set MACMIIAR CR bits depending on HCLK setting */ + +#if STM32_HCLK_FREQUENCY >= 20000000 && STM32_HCLK_FREQUENCY < 35000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_DIV16 +#elif STM32_HCLK_FREQUENCY >= 35000000 && STM32_HCLK_FREQUENCY < 60000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_DIV26 +#elif STM32_HCLK_FREQUENCY >= 60000000 && STM32_HCLK_FREQUENCY < 100000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_DIV42 +#elif STM32_HCLK_FREQUENCY >= 100000000 && STM32_HCLK_FREQUENCY < 150000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_DIV62 +#elif STM32_HCLK_FREQUENCY >= 150000000 && STM32_HCLK_FREQUENCY <= 216000000 +# define ETH_MACMIIAR_CR ETH_MACMIIAR_CR_DIV102 +#else +# error "STM32_HCLK_FREQUENCY not supportable" +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define STM32_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define STM32_TXTIMEOUT (60*CLK_TCK) + +/* PHY reset/configuration delays in milliseconds */ + +#define PHY_RESET_DELAY (65) +#define PHY_CONFIG_DELAY (1000) + +/* PHY read/write delays in loop counts */ + +#define PHY_READ_TIMEOUT (0x0004ffff) +#define PHY_WRITE_TIMEOUT (0x0004ffff) +#define PHY_RETRY_TIMEOUT (0x0004ffff) + +/* Register values **********************************************************/ + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACCR_RE Bit 2: Receiver enable + * ETH_MACCR_TE Bit 3: Transmitter enable + * ETH_MACCR_DC Bit 4: Deferral check + * ETH_MACCR_BL Bits 5-6: Back-off limit + * ETH_MACCR_APCS Bit 7: Automatic pad/CRC stripping + * ETH_MACCR_RD Bit 9: Retry disable + * ETH_MACCR_IPCO Bit 10: IPv4 checksum offload + * ETH_MACCR_DM Bit 11: Duplex mode + * ETH_MACCR_LM Bit 12: Loopback mode + * ETH_MACCR_ROD Bit 13: Receive own disable + * ETH_MACCR_FES Bit 14: Fast Ethernet speed + * ETH_MACCR_CSD Bit 16: Carrier sense disable + * ETH_MACCR_IFG Bits 17-19: Interframe gap + * ETH_MACCR_JD Bit 22: Jabber disable + * ETH_MACCR_WD Bit 23: Watchdog disable + * ETH_MACCR_CSTF Bits 25: CRC stripping for Type frames (F2/F4 only) + */ + +#define MACCR_CLEAR_BITS \ + (ETH_MACCR_RE | ETH_MACCR_TE | ETH_MACCR_DC | ETH_MACCR_BL_MASK | \ + ETH_MACCR_APCS | ETH_MACCR_RD | ETH_MACCR_IPCO | ETH_MACCR_DM | \ + ETH_MACCR_LM | ETH_MACCR_ROD | ETH_MACCR_FES | ETH_MACCR_CSD | \ + ETH_MACCR_IFG_MASK | ETH_MACCR_JD | ETH_MACCR_WD | ETH_MACCR_CSTF) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACCR_RE Receiver enable 0 (disabled) + * ETH_MACCR_TE Transmitter enable 0 (disabled) + * ETH_MACCR_DC Deferral check 0 (disabled) + * ETH_MACCR_BL Back-off limit 0 (10) + * ETH_MACCR_APCS Automatic pad/CRC stripping 0 (disabled) + * ETH_MACCR_RD Retry disable 1 (disabled) + * ETH_MACCR_IPCO IPv4 checksum offload Depends on CONFIG_STM32F7_ETH_HWCHECKSUM + * ETH_MACCR_LM Loopback mode 0 (disabled) + * ETH_MACCR_ROD Receive own disable 0 (enabled) + * ETH_MACCR_CSD Carrier sense disable 0 (enabled) + * ETH_MACCR_IFG Interframe gap 0 (96 bits) + * ETH_MACCR_JD Jabber disable 0 (enabled) + * ETH_MACCR_WD Watchdog disable 0 (enabled) + * ETH_MACCR_CSTF CRC stripping for Type frames 0 (disabled, F2/F4 only) + * + * The following are set conditionally based on mode and speed. + * + * ETH_MACCR_DM Duplex mode Depends on priv->fduplex + * ETH_MACCR_FES Fast Ethernet speed Depends on priv->mbps100 + */ + +#ifdef CONFIG_STM32F7_ETH_HWCHECKSUM +# define MACCR_SET_BITS \ + (ETH_MACCR_BL_10 | ETH_MACCR_RD | ETH_MACCR_IPCO | ETH_MACCR_IFG(96)) +#else +# define MACCR_SET_BITS \ + (ETH_MACCR_BL_10 | ETH_MACCR_RD | ETH_MACCR_IFG(96)) +#endif + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFFR_PM Bit 0: Promiscuous mode + * ETH_MACFFR_HU Bit 1: Hash unicast + * ETH_MACFFR_HM Bit 2: Hash multicast + * ETH_MACFFR_DAIF Bit 3: Destination address inverse filtering + * ETH_MACFFR_PAM Bit 4: Pass all multicast + * ETH_MACFFR_BFD Bit 5: Broadcast frames disable + * ETH_MACFFR_PCF Bits 6-7: Pass control frames + * ETH_MACFFR_SAIF Bit 8: Source address inverse filtering + * ETH_MACFFR_SAF Bit 9: Source address filter + * ETH_MACFFR_HPF Bit 10: Hash or perfect filter + * ETH_MACFFR_RA Bit 31: Receive all + */ + +#define MACFFR_CLEAR_BITS \ + (ETH_MACFFR_PM | ETH_MACFFR_HU | ETH_MACFFR_HM | ETH_MACFFR_DAIF | \ + ETH_MACFFR_PAM | ETH_MACFFR_BFD | ETH_MACFFR_PCF_MASK | ETH_MACFFR_SAIF | \ + ETH_MACFFR_SAF | ETH_MACFFR_HPF | ETH_MACFFR_RA) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFFR_PM Promiscuous mode 0 (disabled) + * ETH_MACFFR_HU Hash unicast 0 (perfect dest filtering) + * ETH_MACFFR_HM Hash multicast 0 (perfect dest filtering) + * ETH_MACFFR_DAIF Destination address inverse filtering 0 (normal) + * ETH_MACFFR_PAM Pass all multicast 0 (Depends on HM bit) + * ETH_MACFFR_BFD Broadcast frames disable 0 (enabled) + * ETH_MACFFR_PCF Pass control frames 1 (block all but PAUSE) + * ETH_MACFFR_SAIF Source address inverse filtering 0 (not used) + * ETH_MACFFR_SAF Source address filter 0 (disabled) + * ETH_MACFFR_HPF Hash or perfect filter 0 (Only matching frames passed) + * ETH_MACFFR_RA Receive all 0 (disabled) + */ + +#define MACFFR_SET_BITS (ETH_MACFFR_PCF_PAUSE) + +/* Clear the MACFCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_MACFCR_FCB_BPA Bit 0: Flow control busy/back pressure activate + * ETH_MACFCR_TFCE Bit 1: Transmit flow control enable + * ETH_MACFCR_RFCE Bit 2: Receive flow control enable + * ETH_MACFCR_UPFD Bit 3: Unicast pause frame detect + * ETH_MACFCR_PLT Bits 4-5: Pause low threshold + * ETH_MACFCR_ZQPD Bit 7: Zero-quanta pause disable + * ETH_MACFCR_PT Bits 16-31: Pause time + */ + +#define MACFCR_CLEAR_MASK \ + (ETH_MACFCR_FCB_BPA | ETH_MACFCR_TFCE | ETH_MACFCR_RFCE | ETH_MACFCR_UPFD | \ + ETH_MACFCR_PLT_MASK | ETH_MACFCR_ZQPD | ETH_MACFCR_PT_MASK) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_MACFCR_FCB_BPA Flow control busy/back pressure activate 0 (no pause control frame) + * ETH_MACFCR_TFCE Transmit flow control enable 0 (disabled) + * ETH_MACFCR_RFCE Receive flow control enable 0 (disabled) + * ETH_MACFCR_UPFD Unicast pause frame detect 0 (disabled) + * ETH_MACFCR_PLT Pause low threshold 0 (pause time - 4) + * ETH_MACFCR_ZQPD Zero-quanta pause disable 1 (disabled) + * ETH_MACFCR_PT Pause time 0 + */ + +#define MACFCR_SET_MASK (ETH_MACFCR_PLT_M4 | ETH_MACFCR_ZQPD) + +/* Clear the DMAOMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMAOMR_SR Bit 1: Start/stop receive + * TH_DMAOMR_OSF Bit 2: Operate on second frame + * ETH_DMAOMR_RTC Bits 3-4: Receive threshold control + * ETH_DMAOMR_FUGF Bit 6: Forward undersized good frames + * ETH_DMAOMR_FEF Bit 7: Forward error frames + * ETH_DMAOMR_ST Bit 13: Start/stop transmission + * ETH_DMAOMR_TTC Bits 14-16: Transmit threshold control + * ETH_DMAOMR_FTF Bit 20: Flush transmit FIFO + * ETH_DMAOMR_TSF Bit 21: Transmit store and forward + * ETH_DMAOMR_DFRF Bit 24: Disable flushing of received frames + * ETH_DMAOMR_RSF Bit 25: Receive store and forward + * TH_DMAOMR_DTCEFD Bit 26: Dropping of TCP/IP checksum error frames disable + */ + +#define DMAOMR_CLEAR_MASK \ + (ETH_DMAOMR_SR | ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_MASK | ETH_DMAOMR_FUGF | \ + ETH_DMAOMR_FEF | ETH_DMAOMR_ST | ETH_DMAOMR_TTC_MASK | ETH_DMAOMR_FTF | \ + ETH_DMAOMR_TSF | ETH_DMAOMR_DFRF | ETH_DMAOMR_RSF | ETH_DMAOMR_DTCEFD) + +/* The following bits are set or left zero unconditionally in all modes. + * + * ETH_DMAOMR_SR Start/stop receive 0 (not running) + * TH_DMAOMR_OSF Operate on second frame 1 (enabled) + * ETH_DMAOMR_RTC Receive threshold control 0 (64 bytes) + * ETH_DMAOMR_FUGF Forward undersized good frames 0 (disabled) + * ETH_DMAOMR_FEF Forward error frames 0 (disabled) + * ETH_DMAOMR_ST Start/stop transmission 0 (not running) + * ETH_DMAOMR_TTC Transmit threshold control 0 (64 bytes) + * ETH_DMAOMR_FTF Flush transmit FIFO 0 (no flush) + * ETH_DMAOMR_TSF Transmit store and forward Depends on CONFIG_STM32F7_ETH_HWCHECKSUM + * ETH_DMAOMR_DFRF Disable flushing of received frames 0 (enabled) + * ETH_DMAOMR_RSF Receive store and forward Depends on CONFIG_STM32F7_ETH_HWCHECKSUM + * TH_DMAOMR_DTCEFD Dropping of TCP/IP checksum error Depends on CONFIG_STM32F7_ETH_HWCHECKSUM + * frames disable + * + * When the checksum offload feature is enabled, we need to enable the Store + * and Forward mode: the store and forward guarantee that a whole frame is + * stored in the FIFO, so the MAC can insert/verify the checksum, if the + * checksum is OK the DMA can handle the frame otherwise the frame is dropped + */ + +#ifdef CONFIG_STM32F7_ETH_HWCHECKSUM +# define DMAOMR_SET_MASK \ + (ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_64 | ETH_DMAOMR_TTC_64 | \ + ETH_DMAOMR_TSF | ETH_DMAOMR_RSF) +#else +# define DMAOMR_SET_MASK \ + (ETH_DMAOMR_OSF | ETH_DMAOMR_RTC_64 | ETH_DMAOMR_TTC_64 | \ + ETH_DMAOMR_DTCEFD) +#endif + +/* Clear the DMABMR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * ETH_DMABMR_SR Bit 0: Software reset + * ETH_DMABMR_DA Bit 1: DMA Arbitration + * ETH_DMABMR_DSL Bits 2-6: Descriptor skip length + * ETH_DMABMR_EDFE Bit 7: Enhanced descriptor format enable + * ETH_DMABMR_PBL Bits 8-13: Programmable burst length + * ETH_DMABMR_RTPR Bits 14-15: RX TX priority ratio + * ETH_DMABMR_FB Bit 16: Fixed burst + * ETH_DMABMR_RDP Bits 17-22: RX DMA PBL + * ETH_DMABMR_USP Bit 23: Use separate PBL + * ETH_DMABMR_FPM Bit 24: 4xPBL mode + * ETH_DMABMR_AAB Bit 25: Address-aligned beats + * ETH_DMABMR_MB Bit 26: Mixed burst (F2/F4 only) + */ + +#define DMABMR_CLEAR_MASK \ + (ETH_DMABMR_SR | ETH_DMABMR_DA | ETH_DMABMR_DSL_MASK | ETH_DMABMR_EDFE | \ + ETH_DMABMR_PBL_MASK | ETH_DMABMR_PM_MASK | ETH_DMABMR_FB | ETH_DMABMR_RDP_MASK | \ + ETH_DMABMR_USP | ETH_DMABMR_FPM | ETH_DMABMR_AAB | ETH_DMABMR_MB) + +/* The following bits are set or left zero unconditionally in all modes. + * + * + * ETH_DMABMR_SR Software reset 0 (no reset) + * ETH_DMABMR_DA DMA Arbitration 0 (round robin) + * ETH_DMABMR_DSL Descriptor skip length 0 + * ETH_DMABMR_EDFE Enhanced descriptor format enable Depends on CONFIG_STM32F7_ETH_ENHANCEDDESC + * ETH_DMABMR_PBL Programmable burst length 32 beats + * ETH_DMABMR_RTPR RX TX priority ratio 2:1 + * ETH_DMABMR_FB Fixed burst 1 (enabled) + * ETH_DMABMR_RDP RX DMA PBL 32 beats + * ETH_DMABMR_USP Use separate PBL 1 (enabled) + * ETH_DMABMR_FPM 4xPBL mode 0 (disabled) + * ETH_DMABMR_AAB Address-aligned beats 1 (enabled) + * ETH_DMABMR_MB Mixed burst 0 (disabled, F2/F4 only) + */ + +#ifdef CONFIG_STM32F7_ETH_ENHANCEDDESC +# define DMABMR_SET_MASK \ + (ETH_DMABMR_DSL(0) | ETH_DMABMR_PBL(32) | ETH_DMABMR_EDFE | ETH_DMABMR_RTPR_2TO1 | \ + ETH_DMABMR_FB | ETH_DMABMR_RDP(32) | ETH_DMABMR_USP | ETH_DMABMR_AAB) +#else +# define DMABMR_SET_MASK \ + (ETH_DMABMR_DSL(0) | ETH_DMABMR_PBL(32) | ETH_DMABMR_RTPR_2TO1 | ETH_DMABMR_FB | \ + ETH_DMABMR_RDP(32) | ETH_DMABMR_USP | ETH_DMABMR_AAB) +#endif + +/* Interrupt bit sets *******************************************************/ +/* All interrupts in the normal and abnormal interrupt summary. Early transmit + * interrupt (ETI) is excluded from the abnormal set because it causes too + * many interrupts and is not interesting. + */ + +#define ETH_DMAINT_NORMAL \ + (ETH_DMAINT_TI | ETH_DMAINT_TBUI | ETH_DMAINT_RI | ETH_DMAINT_ERI) + +#define ETH_DMAINT_ABNORMAL \ + (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \ + ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /* ETH_DMAINT_ETI | */ \ + ETH_DMAINT_FBEI) + +/* Normal receive, transmit, error interrupt enable bit sets */ + +#define ETH_DMAINT_RECV_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_RI) +#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI) +#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI) + +#ifdef CONFIG_DEBUG_NET +# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL) +#else +# define ETH_DMAINT_ERROR_ENABLE (0) +#endif + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the Ethernet + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This union type forces the allocated size of RX descriptors to be the + * padded to a exact multiple of the Cortex-M7 D-Cache line size. + */ + +union stm32_txdesc_u +{ + uint8_t pad[TXDESC_PADSIZE]; + struct eth_txdesc_s txdesc; +}; + +union stm32_rxdesc_u +{ + uint8_t pad[RXDESC_PADSIZE]; + struct eth_rxdesc_s rxdesc; +}; + +/* The stm32_ethmac_s encapsulates all state information for a single hardware + * interface + */ + +struct stm32_ethmac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */ + uint8_t fduplex : 1; /* Full (vs. half) duplex */ + uint8_t intf; /* Ethernet interface number */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ + + /* Used to track transmit and receive descriptors */ + + struct eth_txdesc_s *txhead; /* Next available TX descriptor */ + struct eth_rxdesc_s *rxhead; /* Next available RX descriptor */ + + struct eth_txdesc_s *txtail; /* First "in_flight" TX descriptor */ + struct eth_rxdesc_s *rxcurr; /* First RX descriptor of the segment */ + uint16_t segments; /* RX segment count */ + uint16_t inflight; /* Number of TX transfers "in_flight" */ + sq_queue_t freeb; /* The free buffer list */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* DMA buffers. DMA buffers must: + * + * 1. Be a multiple of the D-Cache line size. This requirement is assured + * by the definition of RXDMA buffer size above. + * 2. Be aligned a D-Cache line boundaries, and + * 3. Be positioned in DMA-able memory (*NOT* DTCM memory). This must + * be managed by logic in the linker script file. + * + * These DMA buffers are defined sequentially here to best assure optimal + * packing of the buffers. + */ + +/* Descriptor allocations */ + +static union stm32_rxdesc_u g_rxtable[RXTABLE_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +static union stm32_txdesc_u g_txtable[TXTABLE_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); + +/* Buffer allocations */ + +static uint8_t g_rxbuffer[RXBUFFER_ALLOC] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +static uint8_t g_txbuffer[TXBUFFER_ALLOC] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); + +/* These are the pre-allocated Ethernet device structures */ + +static struct stm32_ethmac_s g_stm32ethmac[STM32F7_NETHERNET]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_STM32F7_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); +static void stm32_checksetup(void); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +# define stm32_checksetup() +#endif + +/* Free buffer management */ + +static void stm32_initbuffer(struct stm32_ethmac_s *priv, + uint8_t *txbuffer); +static inline uint8_t *stm32_allocbuffer(struct stm32_ethmac_s *priv); +static inline void stm32_freebuffer(struct stm32_ethmac_s *priv, uint8_t *buffer); +static inline bool stm32_isfreebuffer(struct stm32_ethmac_s *priv); + +/* Common TX logic */ + +static int stm32_transmit(struct stm32_ethmac_s *priv); +static int stm32_txpoll(struct net_driver_s *dev); +static void stm32_dopoll(struct stm32_ethmac_s *priv); + +/* Interrupt handling */ + +static void stm32_enableint(struct stm32_ethmac_s *priv, uint32_t ierbit); +static void stm32_disableint(struct stm32_ethmac_s *priv, uint32_t ierbit); + +static void stm32_freesegment(struct stm32_ethmac_s *priv, + struct eth_rxdesc_s *rxfirst, int segments); +static int stm32_recvframe(struct stm32_ethmac_s *priv); +static void stm32_receive(struct stm32_ethmac_s *priv); +static void stm32_freeframe(struct stm32_ethmac_s *priv); +static void stm32_txdone(struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_interrupt_work(void *arg); +#endif +static int stm32_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static inline void stm32_txtimeout_process(struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_txtimeout_work(void *arg); +#endif +static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void stm32_poll_process(struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_poll_work(void *arg); +#endif +static void stm32_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int stm32_ifup(struct net_driver_s *dev); +static int stm32_ifdown(struct net_driver_s *dev); +static int stm32_ifdown(struct net_driver_s *dev); +static inline void stm32_txavail_process(struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void stm32_txavail_work(void *arg); +#endif +static int stm32_txavail(struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int stm32_addmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int stm32_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int stm32_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* Descriptor Initialization */ + +static void stm32_txdescinit(struct stm32_ethmac_s *priv, + union stm32_txdesc_u *txtable); +static void stm32_rxdescinit(struct stm32_ethmac_s *priv, + union stm32_rxdesc_u *rxtable, + uint8_t *rxbuffer); + +/* PHY Initialization */ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int stm32_phyintenable(struct stm32_ethmac_s *priv); +#endif +static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value); +static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value); +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int stm32_dm9161(struct stm32_ethmac_s *priv); +#endif +static int stm32_phyinit(struct stm32_ethmac_s *priv); + +/* MAC/DMA Initialization */ + +#ifdef CONFIG_STM32F7_MII +static inline void stm32_selectmii(void); +#endif +#ifdef CONFIG_STM32F7_RMII +static inline void stm32_selectrmii(void); +#endif +static inline void stm32_ethgpioconfig(struct stm32_ethmac_s *priv); +static void stm32_ethreset(struct stm32_ethmac_s *priv); +static int stm32_macconfig(struct stm32_ethmac_s *priv); +static void stm32_macaddress(struct stm32_ethmac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void stm32_ipv6multicast(struct stm32_ethmac_s *priv); +#endif +static int stm32_macenable(struct stm32_ethmac_s *priv); +static int stm32_ethconfig(struct stm32_ethmac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * addr - The register address to read + * + * Returned Value: + * The value read from the register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32F7_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * val - The value to write to the register + * addr - The register address to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32F7_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_checksetup + * + * Description: + * Show the state of critical configuration registers. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32F7_ETHMAC_REGDEBUG) && defined(CONFIG_DEBUG) +static void stm32_checksetup(void) +{ +} +#endif + +/**************************************************************************** + * Function: stm32_initbuffer + * + * Description: + * Initialize the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * txbuffer - DMA memory allocated for TX buffers. + * + * Returned Value: + * None + * + * Assumptions: + * Called during early driver initialization before Ethernet interrupts + * are enabled. + * + ****************************************************************************/ + +static void stm32_initbuffer(struct stm32_ethmac_s *priv, uint8_t *txbuffer) +{ + uint8_t *buffer; + int i; + + /* Initialize the head of the free buffer list */ + + sq_init(&priv->freeb); + + /* Add all of the pre-allocated buffers to the free buffer list */ + + for (i = 0, buffer = txbuffer; + i < STM32_ETH_NFREEBUFFERS; + i++, buffer += ALIGNED_BUFSIZE) + { + sq_addlast((sq_entry_t *)buffer, &priv->freeb); + } +} + +/**************************************************************************** + * Function: stm32_allocbuffer + * + * Description: + * Allocate one buffer from the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * Pointer to the allocated buffer on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline uint8_t *stm32_allocbuffer(struct stm32_ethmac_s *priv) +{ + /* Allocate a buffer by returning the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->freeb); +} + +/**************************************************************************** + * Function: stm32_freebuffer + * + * Description: + * Return a buffer to the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * buffer - A pointer to the buffer to be freed + * + * Returned Value: + * None + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline void stm32_freebuffer(struct stm32_ethmac_s *priv, uint8_t *buffer) +{ + /* Free the buffer by adding it to to the end of the free buffer list */ + + sq_addlast((sq_entry_t *)buffer, &priv->freeb); +} + +/**************************************************************************** + * Function: stm32_isfreebuffer + * + * Description: + * Return TRUE if the free buffer list is not empty. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * True if there are one or more buffers in the free buffer list; + * false if the free buffer list is empty + * + * Assumptions: + * None. + * + ****************************************************************************/ + +static inline bool stm32_isfreebuffer(struct stm32_ethmac_s *priv) +{ + /* Return TRUE if the free buffer list is not empty */ + + return !sq_empty(&priv->freeb); +} + +/**************************************************************************** + * Function: stm32_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_transmit(struct stm32_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + struct eth_txdesc_s *txfirst; + + /* The internal (optimal) uIP buffer size may be configured to be larger + * than the Ethernet buffer size. + */ + +#if OPTIMAL_ETH_BUFSIZE > ALIGNED_BUFSIZE + uint8_t *buffer; + int bufcount; + int lastsize; + int i; +#endif + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + txdesc = priv->txhead; + txfirst = txdesc; + + nllvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n", + priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0); + + DEBUGASSERT(txdesc && (txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Flush the contents of the TX buffer into physical memory */ + + arch_clean_dcache((uintptr_t)priv->dev.d_buf, + (uintptr_t)priv->dev.d_buf + priv->dev.d_len); + + /* Is the size to be sent greater than the size of the Ethernet buffer? */ + + DEBUGASSERT(priv->dev.d_len > 0 && priv->dev.d_buf != NULL); + +#if OPTIMAL_ETH_BUFSIZE > ALIGNED_BUFSIZE + if (priv->dev.d_len > ALIGNED_BUFSIZE) + { + /* Yes... how many buffers will be need to send the packet? */ + + bufcount = (priv->dev.d_len + (ALIGNED_BUFSIZE-1)) / ALIGNED_BUFSIZE; + lastsize = priv->dev.d_len - (bufcount - 1) * ALIGNED_BUFSIZE; + + nllvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize); + + /* Set the first segment bit in the first TX descriptor */ + + txdesc->tdes0 |= ETH_TDES0_FS; + + /* Set up all but the last TX descriptor */ + + buffer = priv->dev.d_buf; + + for (i = 0; i < bufcount; i++) + { + /* This could be a normal event but the design does not handle it */ + + DEBUGASSERT((txdesc->tdes0 & ETH_TDES0_OWN) == 0); + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)buffer; + + /* Set the buffer size in all TX descriptors */ + + if (i == (bufcount-1)) + { + /* This is the last segment. Set the last segment bit in the + * last TX descriptor and ask for an interrupt when this + * segment transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_LS | ETH_TDES0_IC); + + /* This segement is, most likely, of fractional buffersize */ + + txdesc->tdes1 = lastsize; + buffer += lastsize; + } + else + { + /* This is not the last segment. We don't want an interrupt + * when this segment transfer completes. + */ + + txdesc->tdes0 &= ~ETH_TDES0_IC; + + /* The size of the transfer is the whole buffer */ + + txdesc->tdes1 = ALIGNED_BUFSIZE; + buffer += ALIGNED_BUFSIZE; + } + + /* Give the descriptor to DMA */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + + /* Flush the contents of the modified TX descriptor into physical + * memory. + */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct eth_txdesc_s)); + + /* Get the next descriptor in the link list */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + } + else +#endif + { + /* The single descriptor is both the first and last segment. And we do + * want an interrupt when the transfer completes. + */ + + txdesc->tdes0 |= (ETH_TDES0_FS | ETH_TDES0_LS | ETH_TDES0_IC); + + /* Set frame size */ + + DEBUGASSERT(priv->dev.d_len <= CONFIG_NET_ETH_MTU); + txdesc->tdes1 = priv->dev.d_len; + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)priv->dev.d_buf; + + /* Set OWN bit of the TX descriptor tdes0. This gives the buffer to + * Ethernet DMA + */ + + txdesc->tdes0 |= ETH_TDES0_OWN; + + /* Flush the contents of the modified TX descriptor into physical + * memory. + */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct eth_txdesc_s)); + + /* Point to the next available TX descriptor */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + } + + /* Remember where we left off in the TX descriptor chain */ + + priv->txhead = txdesc; + + /* Detach the buffer from priv->dev structure. That buffer is now + * "in-flight". + */ + + priv->dev.d_buf = NULL; + priv->dev.d_len = 0; + + /* If there is no other TX buffer, in flight, then remember the location + * of the TX descriptor. This is the location to check for TX done events. + */ + + if (!priv->txtail) + { + DEBUGASSERT(priv->inflight == 0); + priv->txtail = txfirst; + } + + /* Increment the number of TX transfer in-flight */ + + priv->inflight++; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* If all TX descriptors are in-flight, then we have to disable receive interrupts + * too. This is because receive events can trigger more un-stoppable transmit + * events. + */ + + if (priv->inflight >= CONFIG_STM32F7_ETH_NTXDESC) + { + stm32_disableint(priv, ETH_DMAINT_RI); + } + + /* Check if the TX Buffer unavailable flag is set */ + + if ((stm32_getreg(STM32_ETH_DMASR) & ETH_DMAINT_TBUI) != 0) + { + /* Clear TX Buffer unavailable flag */ + + stm32_putreg(ETH_DMAINT_TBUI, STM32_ETH_DMASR); + + /* Resume DMA transmission */ + + stm32_putreg(0, STM32_ETH_DMATPDR); + } + + /* Enable TX interrupts */ + + stm32_enableint(priv, ETH_DMAINT_TI); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, STM32_TXTIMEOUT, stm32_txtimeout_expiry, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: stm32_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_txpoll(struct net_driver_s *dev) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; + + DEBUGASSERT(priv->dev.d_buf != NULL); + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + stm32_transmit(priv); + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the TX poll if we are unable to accept another packet for + * transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32F7_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) != 0 || + priv->txhead->tdes2 != 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + + /* We have the descriptor, we can continue the poll. Allocate a new + * buffer for the poll. + */ + + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't continue the poll if we have no buffers */ + + if (dev->d_buf == NULL) + { + /* Terminate the poll. */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: stm32_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (stm32_txdone), + * 2. When new TX data is available (stm32_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (stm32_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_dopoll(struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or + * CPU. We cannot perform the TX poll if we are unable to accept + * another packet for transmission. + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32F7_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. + * Allocate a buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + (void)devif_poll(dev, stm32_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: stm32_enableint + * + * Description: + * Enable a "normal" interrupt + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_enableint(struct stm32_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Enable the specified "normal" interrupt */ + + regval = stm32_getreg(STM32_ETH_DMAIER); + regval |= (ETH_DMAINT_NIS | ierbit); + stm32_putreg(regval, STM32_ETH_DMAIER); +} + +/**************************************************************************** + * Function: stm32_disableint + * + * Description: + * Disable a normal interrupt. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_disableint(struct stm32_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Disable the "normal" interrupt */ + + regval = stm32_getreg(STM32_ETH_DMAIER); + regval &= ~ierbit; + + /* Are all "normal" interrupts now disabled? */ + + if ((regval & ETH_DMAINT_NORMAL) == 0) + { + /* Yes.. disable normal interrupts */ + + regval &= ~ETH_DMAINT_NIS; + } + + stm32_putreg(regval, STM32_ETH_DMAIER); +} + +/**************************************************************************** + * Function: stm32_freesegment + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors to the received frame. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_freesegment(struct stm32_ethmac_s *priv, + struct eth_rxdesc_s *rxfirst, int segments) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + nllvdbg("rxfirst: %p segments: %d\n", rxfirst, segments); + + /* Give the freed RX buffers back to the Ethernet MAC to be refilled */ + + rxdesc = rxfirst; + for (i = 0; i < segments; i++) + { + /* Set OWN bit in RX descriptors. This gives the buffers back to DMA */ + + rxdesc->rdes0 = ETH_RDES0_OWN; + + /* Make sure that the modified RX descriptor is written to physical + * memory. + */ + + arch_clean_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct eth_rxdesc_s)); + + /* Get the next RX descriptor in the chain (cache coherency should not + * be an issue because the link address is constant. + */ + + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + } + + /* Reset the segment management logic */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Check if the RX Buffer unavailable flag is set */ + + if ((stm32_getreg(STM32_ETH_DMASR) & ETH_DMAINT_RBUI) != 0) + { + /* Clear RBUS Ethernet DMA flag */ + + stm32_putreg(ETH_DMAINT_RBUI, STM32_ETH_DMASR); + + /* Resume DMA reception */ + + stm32_putreg(0, STM32_ETH_DMARPDR); + } +} + +/**************************************************************************** + * Function: stm32_recvframe + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors of the received frame. + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static int stm32_recvframe(struct stm32_ethmac_s *priv) +{ + struct eth_rxdesc_s *rxdesc; + struct eth_rxdesc_s *rxcurr; + uint8_t *buffer; + int i; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if there are free buffers. We cannot receive new frames in this + * design unless there is at least one free buffer. + */ + + if (!stm32_isfreebuffer(priv)) + { + nlldbg("No free buffers\n"); + return -ENOMEM; + } + + /* Scan descriptors owned by the CPU. Scan until: + * + * 1) We find a descriptor still owned by the DMA, + * 2) We have examined all of the RX descriptors, or + * 3) All of the TX descriptors are in flight. + * + * This last case is obscure. It is due to that fact that each packet + * that we receive can generate an unstoppable transmisson. So we have + * to stop receiving when we can not longer transmit. In this case, the + * transmit logic should also have disabled further RX interrupts. + */ + + rxdesc = priv->rxhead; + + /* Forces the first RX descriptor to be re-read from physical memory */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct eth_rxdesc_s)); + + for (i = 0; + (rxdesc->rdes0 & ETH_RDES0_OWN) == 0 && + i < CONFIG_STM32F7_ETH_NRXDESC && + priv->inflight < CONFIG_STM32F7_ETH_NTXDESC; + i++) + { + /* Check if this is the first segment in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_FS) != 0 && + (rxdesc->rdes0 & ETH_RDES0_LS) == 0) + { + priv->rxcurr = rxdesc; + priv->segments = 1; + } + + /* Check if this is an intermediate segment in the frame */ + + else if (((rxdesc->rdes0 & ETH_RDES0_LS) == 0) && + ((rxdesc->rdes0 & ETH_RDES0_FS) == 0)) + { + priv->segments++; + } + + /* Otherwise, it is the last segment in the frame */ + + else + { + priv->segments++; + + /* Check if the there is only one segment in the frame */ + + if (priv->segments == 1) + { + rxcurr = rxdesc; + } + else + { + rxcurr = priv->rxcurr; + } + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if any errors are reported in the frame */ + + if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0) + { + struct net_driver_s *dev = &priv->dev; + + /* Get the Frame Length of the received packet: subtract 4 + * bytes of the CRC + */ + + dev->d_len = ((rxdesc->rdes0 & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_SHIFT) - 4; + + /* Get a buffer from the free list. We don't even check if + * this is successful because we already assure the free + * list is not empty above. + */ + + buffer = stm32_allocbuffer(priv); + + /* Take the buffer from the RX descriptor of the first free + * segment, put it into the uIP device structure, then replace + * the buffer in the RX descriptor with the newly allocated + * buffer. + */ + + DEBUGASSERT(dev->d_buf == NULL); + dev->d_buf = (uint8_t *)rxcurr->rdes2; + rxcurr->rdes2 = (uint32_t)buffer; + + /* Make sure that the modified RX descriptor is written to + * physical memory. + */ + + arch_clean_dcache((uintptr_t)rxcurr, + (uintptr_t)rxdesc + sizeof(struct eth_rxdesc_s)); + + /* Remember where we should re-start scanning and reset the segment + * scanning logic + */ + + priv->rxhead = (struct eth_rxdesc_s *)rxdesc->rdes3; + stm32_freesegment(priv, rxcurr, priv->segments); + + /* Force the completed RX DMA buffer to be re-read from + * physical memory. + */ + + arch_invalidate_dcache((uintptr_t)dev->d_buf, + (uintptr_t)dev->d_buf + dev->d_len); + + nllvdbg("rxhead: %p d_buf: %p d_len: %d\n", + priv->rxhead, dev->d_buf, dev->d_len); + + /* Return success */ + + return OK; + } + else + { + /* Drop the frame that contains the errors, reset the segment + * scanning logic, and continue scanning with the next frame. + */ + + nlldbg("DROPPED: RX descriptor errors: %08x\n", rxdesc->rdes0); + stm32_freesegment(priv, rxcurr, priv->segments); + } + } + + /* Try the next descriptor */ + + rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3; + + /* Force the next RX descriptor to be re-read from physical memory */ + + arch_invalidate_dcache((uintptr_t)rxdesc, + (uintptr_t)rxdesc + sizeof(struct eth_rxdesc_s)); + } + + /* We get here after all of the descriptors have been scanned or when rxdesc points + * to the first descriptor owned by the DMA. Remember where we left off. + */ + + priv->rxhead = rxdesc; + + nllvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + return -EAGAIN; +} + +/**************************************************************************** + * Function: stm32_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_receive(struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while stm32_recvframe() successfully retrieves valid + * Ethernet frames. + */ + + while (stm32_recvframe(priv) == OK) + { +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + continue; + } + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + stm32_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + stm32_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + stm32_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + + /* We are finished with the RX buffer. NOTE: If the buffer is + * re-used for transmission, the dev->d_buf field will have been + * nullified. + */ + + if (dev->d_buf) + { + /* Free the receive packet buffer */ + + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + } +} + +/**************************************************************************** + * Function: stm32_freeframe + * + * Description: + * Scans the TX descriptors and frees the buffers of completed TX transfers. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void stm32_freeframe(struct stm32_ethmac_s *priv) +{ + struct eth_txdesc_s *txdesc; + int i; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* Scan for "in-flight" descriptors owned by the CPU */ + + txdesc = priv->txtail; + if (txdesc) + { + DEBUGASSERT(priv->inflight > 0); + + /* Force re-reading of the TX descriptor for physical memory */ + + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct eth_txdesc_s)); + + for (i = 0; (txdesc->tdes0 & ETH_TDES0_OWN) == 0; i++) + { + /* There should be a buffer assigned to all in-flight + * TX descriptors. + */ + + nllvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n", + txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3); + + DEBUGASSERT(txdesc->tdes2 != 0); + + /* Check if this is the first segment of a TX frame. */ + + if ((txdesc->tdes0 & ETH_TDES0_FS) != 0) + { + /* Yes.. Free the buffer */ + + stm32_freebuffer(priv, (uint8_t *)txdesc->tdes2); + } + + /* In any event, make sure that TDES2 is nullified. */ + + txdesc->tdes2 = 0; + + /* Flush the contents of the modified TX descriptor into + * physical memory. + */ + + arch_clean_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct eth_txdesc_s)); + + /* Check if this is the last segment of a TX frame */ + + if ((txdesc->tdes0 & ETH_TDES0_LS) != 0) + { + /* Yes.. Decrement the number of frames "in-flight". */ + + priv->inflight--; + + /* If all of the TX descriptors were in-flight, then RX interrupts + * may have been disabled... we can re-enable them now. + */ + + stm32_enableint(priv, ETH_DMAINT_RI); + + /* If there are no more frames in-flight, then bail. */ + + if (priv->inflight <= 0) + { + priv->txtail = NULL; + priv->inflight = 0; + return; + } + } + + /* Try the next descriptor in the TX chain */ + + txdesc = (struct eth_txdesc_s *)txdesc->tdes3; + + /* Force re-reading of the TX descriptor for physical memory */ + + arch_invalidate_dcache((uintptr_t)txdesc, + (uintptr_t)txdesc + sizeof(struct eth_txdesc_s)); + } + + /* We get here if (1) there are still frames "in-flight". Remember + * where we left off. + */ + + priv->txtail = txdesc; + + nllvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + } +} + +/**************************************************************************** + * Function: stm32_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_txdone(struct stm32_ethmac_s *priv) +{ + DEBUGASSERT(priv->txtail != NULL); + + /* Scan the TX descriptor change, returning buffers to free list */ + + stm32_freeframe(priv); + + /* If no further xmits are pending, then cancel the TX timeout */ + + if (priv->inflight <= 0) + { + /* Cancel the TX timeout */ + + wd_cancel(priv->txtimeout); + + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv); + + /* And disable further TX interrupts. */ + + stm32_disableint(priv, ETH_DMAINT_TI); + } + + /* Then poll uIP for new XMIT data */ + + stm32_dopoll(priv); +} + +/**************************************************************************** + * Function: stm32_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void stm32_interrupt_process(struct stm32_ethmac_s *priv) +{ + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = stm32_getreg(STM32_ETH_DMASR); + + /* Mask only enabled interrupts. This depends on the fact that the interrupt + * related bits (0-16) correspond in these two registers. + */ + + dmasr &= stm32_getreg(STM32_ETH_DMAIER); + + /* Check if there are pending "normal" interrupts */ + + if ((dmasr & ETH_DMAINT_NIS) != 0) + { + /* Yes.. Check if we received an incoming packet, if so, call + * stm32_receive() + */ + + if ((dmasr & ETH_DMAINT_RI) != 0) + { + /* Clear the pending receive interrupt */ + + stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR); + + /* Handle the received package */ + + stm32_receive(priv); + } + + /* Check if a packet transmission just completed. If so, call + * stm32_txdone(). This may disable further TX interrupts if there + * are no pending transmissions. + */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* Clear the pending receive interrupt */ + + stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR); + + /* Check if there are pending transmissions */ + + stm32_txdone(priv); + } + + /* Clear the pending normal summary interrupt */ + + stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR); + } + + /* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */ + +#ifdef CONFIG_DEBUG_NET + /* Check if there are pending "abnormal" interrupts */ + + if ((dmasr & ETH_DMAINT_AIS) != 0) + { + /* Just let the user know what happened */ + + nlldbg("Abormal event(s): %08x\n", dmasr); + + /* Clear all pending abnormal events */ + + stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR); + + /* Clear the pending abnormal summary interrupt */ + + stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR); + } +#endif +} + +/**************************************************************************** + * Function: stm32_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_interrupt_work(void *arg) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + stm32_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_ETH); +} +#endif + +/**************************************************************************** + * Function: stm32_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_interrupt(int irq, void *context) +{ + struct stm32_ethmac_s *priv = &g_stm32ethmac[0]; + +#ifdef CONFIG_NET_NOINTS + uint32_t dmasr; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmasr = stm32_getreg(STM32_ETH_DMASR); + if (dmasr != 0) + { + /* Disable further Ethernet interrupts. Because Ethernet interrupts + * are also disabled if the TX timeout event occurs, there can be no + * race condition here. + */ + + up_disable_irq(STM32_IRQ_ETH); + + /* Check if a packet transmission just completed. */ + + if ((dmasr & ETH_DMAINT_TI) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_interrupt_work, priv, 0); + } + +#else + /* Process the interrupt now */ + + stm32_interrupt_process(priv); +#endif + + return OK; +} + +/**************************************************************************** + * Function: stm32_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void stm32_txtimeout_process(struct stm32_ethmac_s *priv) +{ + /* Then reset the hardware. Just take the interface down, then back + * up again. + */ + + stm32_ifdown(&priv->dev); + stm32_ifup(&priv->dev); + + /* Then poll for new XMIT data */ + + stm32_dopoll(priv); +} + +/**************************************************************************** + * Function: stm32_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_txtimeout_work(void *arg) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + stm32_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + + nlldbg("Timeout!\n"); + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + * + * Interrupts will be re-enabled when stm32_ifup() is called. + */ + + up_disable_irq(STM32_IRQ_ETH); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_txtimeout_work, priv, 0); + +#else + /* Process the timeout now */ + + stm32_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: stm32_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void stm32_poll_process(struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the timer poll if we are unable to accept another packet + * for transmission. Hmmm.. might be bug here. Does this mean if there is + * a transmit in progress, we will miss TCP time state updates? + * + * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available + * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_STM32F7_ETH_NTXDESC). + */ + + if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then perform the timer poll. Allocate a + * buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = stm32_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + /* Update TCP timing states and poll uIP for new XMIT data. + */ + + (void)devif_timer(dev, stm32_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + stm32_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv); +} + +/**************************************************************************** + * Function: stm32_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_poll_work(void *arg) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + stm32_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void stm32_poll_expiry(int argc, uint32_t arg, ...) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv); + } + +#else + /* Process the interrupt now */ + + stm32_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: stm32_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ifup(struct net_driver_s *dev) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + nvdbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + nvdbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the Ethernet interface for DMA operation. */ + + ret = stm32_ethconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->ifup = true; + up_enable_irq(STM32_IRQ_ETH); + + stm32_checksetup(); + return OK; +} + +/**************************************************************************** + * Function: stm32_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ifdown(struct net_driver_s *dev) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; + irqstate_t flags; + + nvdbg("Taking the network down\n"); + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(STM32_IRQ_ETH); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the stm32_ifup() always + * successfully brings the interface back up. + */ + + stm32_ethreset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: stm32_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * priv - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void stm32_txavail_process(struct stm32_ethmac_s *priv) +{ + nvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + stm32_dopoll(priv); + } + +} + +/**************************************************************************** + * Function: stm32_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void stm32_txavail_work(void *arg) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + stm32_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: stm32_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int stm32_txavail(struct net_driver_s *dev) +{ + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, stm32_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + stm32_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Function: stm32_calcethcrc + * + * Description: + * Function to calculate the CRC used by STM32 to check an ethernet frame + * + * Parameters: + * data - the data to be checked + * length - length of the data + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t stm32_calcethcrc(const uint8_t *data, size_t length) +{ + uint32_t crc = 0xffffffff; + size_t i; + int j; + + for (i = 0; i < length; i++) + { + for (j = 0; j < 8; j++) + { + if (((crc >> 31) ^ (data[i] >> j)) & 0x01) + { + /* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ + crc = (crc << 1) ^ 0x04c11db7; + } + else + { + crc = crc << 1; + } + } + } + + return ~crc; +} +#endif + +/**************************************************************************** + * Function: stm32_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int stm32_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Add the MAC address to the hardware multicast hash table */ + + crc = stm32_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = STM32_ETH_MACHTHR; + hashindex -= 32; + } + else + { + registeraddress = STM32_ETH_MACHTLR; + } + + temp = stm32_getreg(registeraddress); + temp |= 1 << hashindex; + stm32_putreg(temp, registeraddress); + + temp = stm32_getreg(STM32_ETH_MACFFR); + temp |= (ETH_MACFFR_HM | ETH_MACFFR_HPF); + stm32_putreg(temp, STM32_ETH_MACFFR); + + return OK; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: stm32_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int stm32_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Remove the MAC address to the hardware multicast hash table */ + + crc = stm32_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = STM32_ETH_MACHTHR; + hashindex -= 32; + } + else + { + registeraddress = STM32_ETH_MACHTLR; + } + + temp = stm32_getreg(registeraddress); + temp &= ~(1 << hashindex); + stm32_putreg(temp, registeraddress); + + /* If there is no address registered any more, delete multicast filtering */ + + if (stm32_getreg(STM32_ETH_MACHTHR) == 0 && + stm32_getreg(STM32_ETH_MACHTLR) == 0) + { + temp = stm32_getreg(STM32_ETH_MACFFR); + temp &= ~(ETH_MACFFR_HM | ETH_MACFFR_HPF); + stm32_putreg(temp, STM32_ETH_MACFFR); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: stm32_txdescinit + * + * Description: + * Initializes the DMA TX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * txtable - List of pre-allocated TX descriptors for the Ethernet + * interface + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_txdescinit(struct stm32_ethmac_s *priv, + union stm32_txdesc_u *txtable) + +{ + struct eth_txdesc_s *txdesc; + int i; + + /* priv->txhead will point to the first, available TX descriptor in the chain. + * Set the priv->txhead pointer to the first descriptor in the table. + */ + + priv->txhead = &txtable[0].txdesc; + + /* priv->txtail will point to the first segment of the oldest pending + * "in-flight" TX transfer. NULL means that there are no active TX + * transfers. + */ + + priv->txtail = NULL; + priv->inflight = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_STM32F7_ETH_NTXDESC; i++) + { + txdesc = &txtable[i].txdesc; + + /* Set Second Address Chained bit */ + + txdesc->tdes0 = ETH_TDES0_TCH; + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the checksum insertion for the TX frames */ + + txdesc->tdes0 |= ETH_TDES0_CIC_ALL; +#endif + + /* Clear Buffer1 address pointer (buffers will be assigned as they + * are used) + */ + + txdesc->tdes2 = 0; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_STM32F7_ETH_NTXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + txdesc->tdes3 = (uint32_t)&txtable[i+1].txdesc; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + txdesc->tdes3 = (uint32_t)&txtable[0].txdesc; + } + } + + /* Flush all of the initialized TX descriptors to physical memory */ + + arch_clean_dcache((uintptr_t)txtable, + (uintptr_t)txtable + + TXTABLE_SIZE * sizeof(union stm32_txdesc_u)); + + /* Set Transmit Descriptor List Address Register */ + + stm32_putreg((uint32_t)&txtable[0].txdesc, STM32_ETH_DMATDLAR); +} + +/**************************************************************************** + * Function: stm32_rxdescinit + * + * Description: + * Initializes the DMA RX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * rxtable - List of pre-allocated RX descriptors for the Ethernet + * interface + * txbuffer - List of pre-allocated DMA buffers for the Ethernet interface + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_rxdescinit(struct stm32_ethmac_s *priv, + union stm32_rxdesc_u *rxtable, + uint8_t *rxbuffer) +{ + struct eth_rxdesc_s *rxdesc; + int i; + + /* priv->rxhead will point to the first, RX descriptor in the chain. + * This will be where we receive the first incomplete frame. + */ + + priv->rxhead = &rxtable[0].rxdesc; + + /* If we accumulate the frame in segments, priv->rxcurr points to the + * RX descriptor of the first segment in the current TX frame. + */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Initialize each RX descriptor */ + + for (i = 0; i < CONFIG_STM32F7_ETH_NRXDESC; i++) + { + rxdesc = &rxtable[i].rxdesc; + + /* Set Own bit of the RX descriptor rdes0 */ + + rxdesc->rdes0 = ETH_RDES0_OWN; + + /* Set Buffer1 size and Second Address Chained bit and enabled DMA + * RX desc receive interrupt + */ + + rxdesc->rdes1 = ETH_RDES1_RCH | (uint32_t)ALIGNED_BUFSIZE; + + /* Set Buffer1 address pointer */ + + rxdesc->rdes2 = (uint32_t)&rxbuffer[i * ALIGNED_BUFSIZE]; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_STM32F7_ETH_NRXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + rxdesc->rdes3 = (uint32_t)&rxtable[i+1].rxdesc; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + rxdesc->rdes3 = (uint32_t)&rxtable[0].rxdesc; + } + } + + /* Flush all of the initialized RX descriptors to physical memory */ + + arch_clean_dcache((uintptr_t)rxtable, + (uintptr_t)rxtable + + RXTABLE_SIZE * sizeof(union stm32_rxdesc_u)); + + /* Set Receive Descriptor List Address Register */ + + stm32_putreg((uint32_t)&rxtable[0].rxdesc, STM32_ETH_DMARDLAR); +} + +/**************************************************************************** + * Function: stm32_ioctl + * + * Description: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int stm32_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ +#ifdef CONFIG_ARCH_PHY_INTERRUPT + struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private; +#endif + int ret; + + switch (cmd) + { +#ifdef CONFIG_ARCH_PHY_INTERRUPT + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + ret = stm32_phyintenable(priv); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = CONFIG_STM32F7_PHYADDR; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = stm32_phyread(req->phy_id, req->reg_num, &req->val_out); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = stm32_phywrite(req->phy_id, req->reg_num, req->val_in); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: stm32_phyintenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) +static int stm32_phyintenable(struct stm32_ethmac_s *priv) +{ +#warning Missing logic + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Function: stm32_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ETH_MACMIIAR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the buy bit. + * the ETH_MACMIIAR_MW is clear, indicating a read operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIAR_PA_SHIFT) & ETH_MACMIIAR_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIAR_MR_SHIFT) & ETH_MACMIIAR_MR_MASK); + regval |= ETH_MACMIIAR_MB; + + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_READ_TIMEOUT; timeout++) + { + if ((stm32_getreg(STM32_ETH_MACMIIAR) & ETH_MACMIIAR_MB) == 0) + { + *value = (uint16_t)stm32_getreg(STM32_ETH_MACMIIDR); + return OK; + } + } + + nvdbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x\n", + phydevaddr, phyregaddr); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: stm32_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The 16-bit value to write to the PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MACMIIAR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ETH_MACMIIAR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the busy bit. + * the ETH_MACMIIAR_MW is set, indicating a write operation. + */ + + regval |= (((uint32_t)phydevaddr << ETH_MACMIIAR_PA_SHIFT) & ETH_MACMIIAR_PA_MASK); + regval |= (((uint32_t)phyregaddr << ETH_MACMIIAR_MR_SHIFT) & ETH_MACMIIAR_MR_MASK); + regval |= (ETH_MACMIIAR_MB | ETH_MACMIIAR_MW); + + /* Write the value into the MACIIDR register before setting the new MACMIIAR + * register value. + */ + + stm32_putreg(value, STM32_ETH_MACMIIDR); + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_WRITE_TIMEOUT; timeout++) + { + if ((stm32_getreg(STM32_ETH_MACMIIAR) & ETH_MACMIIAR_MB) == 0) + { + return OK; + } + } + + nvdbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x value: %04x\n", + phydevaddr, phyregaddr, value); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: stm32_dm9161 + * + * Description: + * Special workaround for the Davicom DM9161 PHY is required. On power, + * up, the PHY is not usually configured correctly but will work after + * a powered-up reset. This is really a workaround for some more + * fundamental issue with the PHY clocking initialization, but the + * root cause has not been studied (nor will it be with this workaround). + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ETH0_PHY_DM9161 +static inline int stm32_dm9161(struct stm32_ethmac_s *priv) +{ + uint16_t phyval; + int ret; + + /* Read the PHYID1 register; A failure to read the PHY ID is one + * indication that check if the DM9161 PHY CHIP is not ready. + */ + + ret = stm32_phyread(CONFIG_STM32F7_PHYADDR, MII_PHYID1, &phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to read the PHY ID1: %d\n", ret); + return ret; + } + + /* If we failed to read the PHY ID1 register, the reset the MCU to recover */ + + else if (phyval == 0xffff) + { + up_systemreset(); + } + + nvdbg("PHY ID1: 0x%04X\n", phyval); + + /* Now check the "DAVICOM Specified Configuration Register (DSCR)", Register 16 */ + + ret = stm32_phyread(CONFIG_STM32F7_PHYADDR, 16, &phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to read the PHY Register 0x10: %d\n", ret); + return ret; + } + + /* Bit 8 of the DSCR register is zero, then the DM9161 has not selected RMII. + * If RMII is not selected, then reset the MCU to recover. + */ + + else if ((phyval & (1 << 8)) == 0) + { + up_systemreset(); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: stm32_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_phyinit(struct stm32_ethmac_s *priv) +{ + volatile uint32_t timeout; + uint32_t regval; + uint16_t phyval; + int ret; + + /* Assume 10MBps and half duplex */ + + priv->mbps100 = 0; + priv->fduplex = 0; + + /* Setup up PHY clocking by setting the SR field in the MACMIIAR register */ + + regval = stm32_getreg(STM32_ETH_MACMIIAR); + regval &= ~ETH_MACMIIAR_CR_MASK; + regval |= ETH_MACMIIAR_CR; + stm32_putreg(regval, STM32_ETH_MACMIIAR); + + /* Put the PHY in reset mode */ + + ret = stm32_phywrite(CONFIG_STM32F7_PHYADDR, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + ndbg("ERROR: Failed to reset the PHY: %d\n", ret); + return ret; + } + up_mdelay(PHY_RESET_DELAY); + + /* Perform any necessary, board-specific PHY initialization */ + +#ifdef CONFIG_STM32F7_PHYINIT + ret = stm32_phy_boardinitialize(0); + if (ret < 0) + { + ndbg("ERROR: Failed to initialize the PHY: %d\n", ret); + return ret; + } +#endif + + /* Special workaround for the Davicom DM9161 PHY is required. */ + +#ifdef CONFIG_ETH0_PHY_DM9161 + ret = stm32_dm9161(priv); + if (ret < 0) + { + return ret; + } +#endif + + /* Perform auto-negotiation if so configured */ + +#ifdef CONFIG_STM32F7_AUTONEG + /* Wait for link status */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = stm32_phyread(CONFIG_STM32F7_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_LINKSTATUS) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("ERROR: Timed out waiting for link status: %04x\n", phyval); + return -ETIMEDOUT; + } + + /* Enable auto-negotiation */ + + ret = stm32_phywrite(CONFIG_STM32F7_PHYADDR, MII_MCR, MII_MCR_ANENABLE); + if (ret < 0) + { + ndbg("ERROR: Failed to enable auto-negotiation: %d\n", ret); + return ret; + } + + /* Wait until auto-negotiation completes */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = stm32_phyread(CONFIG_STM32F7_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_ANEGCOMPLETE) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("ERROR: Timed out waiting for auto-negotiation\n"); + return -ETIMEDOUT; + } + + /* Read the result of the auto-negotiation from the PHY-specific register */ + + ret = stm32_phyread(CONFIG_STM32F7_PHYADDR, CONFIG_STM32F7_PHYSR, &phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to read PHY status register\n"); + return ret; + } + + /* Remember the selected speed and duplex modes */ + + nvdbg("PHYSR[%d]: %04x\n", CONFIG_STM32F7_PHYSR, phyval); + + /* Different PHYs present speed and mode information in different ways. IF + * This CONFIG_STM32F7_PHYSR_ALTCONFIG is selected, this indicates that the PHY + * represents speed and mode information are combined, for example, with + * separate bits for 10HD, 100HD, 10FD and 100FD. + */ + +#ifdef CONFIG_STM32F7_PHYSR_ALTCONFIG + switch (phyval & CONFIG_STM32F7_PHYSR_ALTMODE) + { + default: + ndbg("ERROR: Unrecognized PHY status setting\n"); + + case CONFIG_STM32F7_PHYSR_10HD: + priv->fduplex = 0; + priv->mbps100 = 0; + break; + + case CONFIG_STM32F7_PHYSR_100HD: + priv->fduplex = 0; + priv->mbps100 = 1; + break; + + case CONFIG_STM32F7_PHYSR_10FD: + priv->fduplex = 1; + priv->mbps100 = 0; + break; + + case CONFIG_STM32F7_PHYSR_100FD: + priv->fduplex = 1; + priv->mbps100 = 1; + break; + } + + /* Different PHYs present speed and mode information in different ways. Some + * will present separate information for speed and mode (this is the default). + * Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + * full/half duplex indication. + */ + +#else + if ((phyval & CONFIG_STM32F7_PHYSR_MODE) == CONFIG_STM32F7_PHYSR_FULLDUPLEX) + { + priv->fduplex = 1; + } + + if ((phyval & CONFIG_STM32F7_PHYSR_SPEED) == CONFIG_STM32F7_PHYSR_100MBPS) + { + priv->mbps100 = 1; + } +#endif + +#else /* Auto-negotion not selected */ + + phyval = 0; +#ifdef CONFIG_STM32F7_ETHFD + phyval |= MII_MCR_FULLDPLX; +#endif +#ifdef CONFIG_STM32F7_ETH100MBPS + phyval |= MII_MCR_SPEED100; +#endif + + ret = stm32_phywrite(CONFIG_STM32F7_PHYADDR, MII_MCR, phyval); + if (ret < 0) + { + ndbg("ERROR: Failed to write the PHY MCR: %d\n", ret); + return ret; + } + + up_mdelay(PHY_CONFIG_DELAY); + + /* Remember the selected speed and duplex modes */ + +#ifdef CONFIG_STM32F7_ETHFD + priv->fduplex = 1; +#endif +#ifdef CONFIG_STM32F7_ETH100MBPS + priv->mbps100 = 1; +#endif +#endif + + nvdbg("Duplex: %s Speed: %d MBps\n", + priv->fduplex ? "FULL" : "HALF", + priv->mbps100 ? 100 : 10); + + return OK; +} + +/************************************************************************************ + * Name: stm32_selectmii + * + * Description: + * Selects the MII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_STM32F7_MII +static inline void stm32_selectmii(void) +{ + uint32_t regval; + + regval = getreg32(STM32_SYSCFG_PMC); + regval &= ~SYSCFG_PMC_MII_RMII_SEL; + putreg32(regval, STM32_SYSCFG_PMC); +} +#endif + +/************************************************************************************ + * Name: stm32_selectrmii + * + * Description: + * Selects the RMII inteface. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_selectrmii(void) +{ + uint32_t regval; + + regval = getreg32(STM32_SYSCFG_PMC); + regval |= SYSCFG_PMC_MII_RMII_SEL; + putreg32(regval, STM32_SYSCFG_PMC); +} + +/**************************************************************************** + * Function: stm32_ethgpioconfig + * + * Description: + * Configure GPIOs for the Ethernet interface. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void stm32_ethgpioconfig(struct stm32_ethmac_s *priv) +{ + /* Configure GPIO pins to support Ethernet */ + +#if defined(CONFIG_STM32F7_MII) || defined(CONFIG_STM32F7_RMII) + + /* MDC and MDIO are common to both modes */ + + stm32_configgpio(GPIO_ETH_MDC); + stm32_configgpio(GPIO_ETH_MDIO); + + /* Set up the MII interface */ + +#if defined(CONFIG_STM32F7_MII) + + /* Select the MII interface */ + + stm32_selectmii(); + + /* Provide clocking via MCO, MCO1 or MCO2: + * + * "MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + * clock (through a configurable prescaler) on PA8 pin." + * + * "MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or + * PLLI2S clock (through a configurable prescaler) on PC9 pin." + */ + +# if defined(CONFIG_STM32F7_MII_MCO1) + /* Configure MC01 to drive the PHY. Board logic must provide MC01 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO1); + stm32_mco1config(BOARD_CFGR_MC01_SOURCE, BOARD_CFGR_MC01_DIVIDER); + +# elif defined(CONFIG_STM32F7_MII_MCO2) + /* Configure MC02 to drive the PHY. Board logic must provide MC02 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO2); + stm32_mco2config(BOARD_CFGR_MC02_SOURCE, BOARD_CFGR_MC02_DIVIDER); + +# elif defined(CONFIG_STM32F7_MII_MCO) + /* Setup MCO pin for alternative usage */ + + stm32_configgpio(GPIO_MCO); + stm32_mcoconfig(BOARD_CFGR_MCO_SOURCE); +# endif + + /* MII interface pins (17): + * + * MII_TX_CLK, MII_TXD[3:0], MII_TX_EN, MII_RX_CLK, MII_RXD[3:0], MII_RX_ER, + * MII_RX_DV, MII_CRS, MII_COL, MDC, MDIO + */ + + stm32_configgpio(GPIO_ETH_MII_COL); + stm32_configgpio(GPIO_ETH_MII_CRS); + stm32_configgpio(GPIO_ETH_MII_RXD0); + stm32_configgpio(GPIO_ETH_MII_RXD1); + stm32_configgpio(GPIO_ETH_MII_RXD2); + stm32_configgpio(GPIO_ETH_MII_RXD3); + stm32_configgpio(GPIO_ETH_MII_RX_CLK); + stm32_configgpio(GPIO_ETH_MII_RX_DV); + stm32_configgpio(GPIO_ETH_MII_RX_ER); + stm32_configgpio(GPIO_ETH_MII_TXD0); + stm32_configgpio(GPIO_ETH_MII_TXD1); + stm32_configgpio(GPIO_ETH_MII_TXD2); + stm32_configgpio(GPIO_ETH_MII_TXD3); + stm32_configgpio(GPIO_ETH_MII_TX_CLK); + stm32_configgpio(GPIO_ETH_MII_TX_EN); + + /* Set up the RMII interface. */ + +#elif defined(CONFIG_STM32F7_RMII) + + /* Select the RMII interface */ + + stm32_selectrmii(); + + /* Provide clocking via MCO, MCO1 or MCO2: + * + * "MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + * clock (through a configurable prescaler) on PA8 pin." + * + * "MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or + * PLLI2S clock (through a configurable prescaler) on PC9 pin." + */ + +# if defined(CONFIG_STM32F7_RMII_MCO1) + /* Configure MC01 to drive the PHY. Board logic must provide MC01 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO1); + stm32_mco1config(BOARD_CFGR_MC01_SOURCE, BOARD_CFGR_MC01_DIVIDER); + +# elif defined(CONFIG_STM32F7_RMII_MCO2) + /* Configure MC02 to drive the PHY. Board logic must provide MC02 clocking + * info. + */ + + stm32_configgpio(GPIO_MCO2); + stm32_mco2config(BOARD_CFGR_MC02_SOURCE, BOARD_CFGR_MC02_DIVIDER); + +# elif defined(CONFIG_STM32F7_RMII_MCO) + /* Setup MCO pin for alternative usage */ + + stm32_configgpio(GPIO_MCO); + stm32_mcoconfig(BOARD_CFGR_MCO_SOURCE); +# endif + + /* RMII interface pins (7): + * + * RMII_TXD[1:0], RMII_TX_EN, RMII_RXD[1:0], RMII_CRS_DV, MDC, MDIO, + * RMII_REF_CLK + */ + + stm32_configgpio(GPIO_ETH_RMII_CRS_DV); + stm32_configgpio(GPIO_ETH_RMII_REF_CLK); + stm32_configgpio(GPIO_ETH_RMII_RXD0); + stm32_configgpio(GPIO_ETH_RMII_RXD1); + stm32_configgpio(GPIO_ETH_RMII_TXD0); + stm32_configgpio(GPIO_ETH_RMII_TXD1); + /* stm32_configgpio(GPIO_ETH_RMII_TX_CLK); not needed? */ + stm32_configgpio(GPIO_ETH_RMII_TX_EN); + +#endif +#endif + +#ifdef CONFIG_STM32F7_ETH_PTP + /* Enable pulse-per-second (PPS) output signal */ + + stm32_configgpio(GPIO_ETH_PPS_OUT); +#endif +} + +/**************************************************************************** + * Function: stm32_ethreset + * + * Description: + * Reset the Ethernet block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_ethreset(struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Reset the Ethernet on the AHB bus (F1 Connectivity Line) or AHB1 bus (F2 + * and F4) + */ + + regval = stm32_getreg(STM32_RCC_AHB1RSTR); + regval |= RCC_AHB1RSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHB1RSTR); + + regval &= ~RCC_AHB1RSTR_ETHMACRST; + stm32_putreg(regval, STM32_RCC_AHB1RSTR); + + /* Perform a software reset by setting the SR bit in the DMABMR register. + * This Resets all MAC subsystem internal registers and logic. After this + * reset all the registers holds their reset values. + */ + + regval = stm32_getreg(STM32_ETH_DMABMR); + regval |= ETH_DMABMR_SR; + stm32_putreg(regval, STM32_ETH_DMABMR); + + /* Wait for software reset to complete. The SR bit is cleared automatically + * after the reset operation has completed in all of the core clock domains. + */ + + while ((stm32_getreg(STM32_ETH_DMABMR) & ETH_DMABMR_SR) != 0); +} + +/**************************************************************************** + * Function: stm32_macconfig + * + * Description: + * Configure the Ethernet MAC for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_macconfig(struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Set up the MACCR register */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval &= ~MACCR_CLEAR_BITS; + regval |= MACCR_SET_BITS; + + if (priv->fduplex) + { + /* Set the DM bit for full duplex support */ + + regval |= ETH_MACCR_DM; + } + + if (priv->mbps100) + { + /* Set the FES bit for 100Mbps fast ethernet support */ + + regval |= ETH_MACCR_FES; + } + + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Set up the MACFFR register */ + + regval = stm32_getreg(STM32_ETH_MACFFR); + regval &= ~MACFFR_CLEAR_BITS; + regval |= MACFFR_SET_BITS; + stm32_putreg(regval, STM32_ETH_MACFFR); + + /* Set up the MACHTHR and MACHTLR registers */ + + stm32_putreg(0, STM32_ETH_MACHTHR); + stm32_putreg(0, STM32_ETH_MACHTLR); + + /* Setup up the MACFCR register */ + + regval = stm32_getreg(STM32_ETH_MACFCR); + regval &= ~MACFCR_CLEAR_MASK; + regval |= MACFCR_SET_MASK; + stm32_putreg(regval, STM32_ETH_MACFCR); + + /* Setup up the MACVLANTR register */ + + stm32_putreg(0, STM32_ETH_MACVLANTR); + + /* DMA Configuration */ + /* Set up the DMAOMR register */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval &= ~DMAOMR_CLEAR_MASK; + regval |= DMAOMR_SET_MASK; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Set up the DMABMR register */ + + regval = stm32_getreg(STM32_ETH_DMABMR); + regval &= ~DMABMR_CLEAR_MASK; + regval |= DMABMR_SET_MASK; + stm32_putreg(regval, STM32_ETH_DMABMR); + + return OK; +} + +/**************************************************************************** + * Function: stm32_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void stm32_macaddress(struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address high register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[5] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[4]; + stm32_putreg(regval, STM32_ETH_MACA0HR); + + /* Set the MAC address low register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[3] << 24) | + ((uint32_t)dev->d_mac.ether_addr_octet[2] << 16) | + ((uint32_t)dev->d_mac.ether_addr_octet[1] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[0]; + stm32_putreg(regval, STM32_ETH_MACA0LR); +} + +/**************************************************************************** + * Function: stm32_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void stm32_ipv6multicast(struct stm32_ethmac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)stm32_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)stm32_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)stm32_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: stm32_macenable + * + * Description: + * Enable normal MAC operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_macenable(struct stm32_ethmac_s *priv) +{ + uint32_t regval; + + /* Set the MAC address */ + + stm32_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + stm32_ipv6multicast(priv); +#endif + + /* Enable transmit state machine of the MAC for transmission on the MII */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval |= ETH_MACCR_TE; + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Flush Transmit FIFO */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_FTF; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Enable receive state machine of the MAC for reception from the MII */ + + /* Enables or disables the MAC reception. */ + + regval = stm32_getreg(STM32_ETH_MACCR); + regval |= ETH_MACCR_RE; + stm32_putreg(regval, STM32_ETH_MACCR); + + /* Start DMA transmission */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_ST; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Start DMA reception */ + + regval = stm32_getreg(STM32_ETH_DMAOMR); + regval |= ETH_DMAOMR_SR; + stm32_putreg(regval, STM32_ETH_DMAOMR); + + /* Enable Ethernet DMA interrupts. + * + * The STM32 hardware supports two interrupts: (1) one dedicated to normal + * Ethernet operations and the other, used only for the Ethernet wakeup + * event. The wake-up interrupt is not used by this driver. + * + * The first Ethernet vector is reserved for interrupts generated by the + * MAC and the DMA. The MAC provides PMT and time stamp trigger interrupts, + * neither of which are used by this driver. + */ + + stm32_putreg(ETH_MACIMR_ALLINTS, STM32_ETH_MACIMR); + + /* Ethernet DMA supports two classes of interrupts: Normal interrupt + * summary (NIS) and Abnormal interrupt summary (AIS) with a variety + * individual normal and abnormal interrupting events. Here only + * the normal receive event is enabled (unless DEBUG is enabled). Transmit + * events will only be enabled when a transmit interrupt is expected. + */ + + stm32_putreg((ETH_DMAINT_RECV_ENABLE | ETH_DMAINT_ERROR_ENABLE), STM32_ETH_DMAIER); + return OK; +} + +/**************************************************************************** + * Function: stm32_ethconfig + * + * Description: + * Configure the Ethernet interface for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int stm32_ethconfig(struct stm32_ethmac_s *priv) +{ + int ret; + + /* NOTE: The Ethernet clocks were initialized early in the boot-up + * sequence in stm32_rcc.c. + */ + + /* Reset the Ethernet block */ + + nllvdbg("Reset the Ethernet block\n"); + stm32_ethreset(priv); + + /* Initialize the PHY */ + + nllvdbg("Initialize the PHY\n"); + ret = stm32_phyinit(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the MAC and DMA */ + + nllvdbg("Initialize the MAC and DMA\n"); + ret = stm32_macconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the free buffer list */ + + stm32_initbuffer(priv, &g_txbuffer[priv->intf * TXBUFFER_SIZE]); + + /* Initialize TX Descriptors list: Chain Mode */ + + stm32_txdescinit(priv, + &g_txtable[priv->intf * CONFIG_STM32F7_ETH_NTXDESC]); + + /* Initialize RX Descriptors list: Chain Mode */ + + stm32_rxdescinit(priv, + &g_rxtable[priv->intf * CONFIG_STM32F7_ETH_NRXDESC], + &g_rxbuffer[priv->intf * RXBUFFER_SIZE]); + + /* Enable normal MAC operation */ + + nllvdbg("Enable normal operation\n"); + return stm32_macenable(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the STM32 chip + * supports multiple Ethernet controllers, then board specific logic + * must implement up_netinitialize() and call this function to initialize + * the desired interfaces. + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if STM32F7_NETHERNET == 1 +static inline +#endif + +int stm32_ethinitialize(int intf) +{ + struct stm32_ethmac_s *priv; + + nvdbg("intf: %d\n", intf); + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(intf < STM32F7_NETHERNET); + priv = &g_stm32ethmac[intf]; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct stm32_ethmac_s)); + priv->dev.d_ifup = stm32_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = stm32_ifdown; /* I/F down callback */ + priv->dev.d_txavail = stm32_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = stm32_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = stm32_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = stm32_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)g_stm32ethmac; /* Used to recover private state from dev */ + priv->intf = intf; /* Remember the interface number */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Configure GPIO pins to support Ethernet */ + + stm32_ethgpioconfig(priv); + + /* Attach the IRQ to the driver */ + + if (irq_attach(STM32_IRQ_ETH, stm32_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Put the interface in the down state. */ + + stm32_ifdown(&priv->dev); + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. If STM32F7_NETHERNET + * greater than one, then board specific logic will have to supply a + * version of up_netinitialize() that calls stm32_ethinitialize() with + * the appropriate interface number. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +#if STM32F7_NETHERNET == 1 +void up_netinitialize(void) +{ + (void)stm32_ethinitialize(0); +} +#endif + +#endif /* STM32F7_NETHERNET > 0 && CONFIG_STM32F7_ETHMAC */ diff --git a/arch/arm/src/stm32f7/stm32_ethernet.h b/arch/arm/src/stm32f7/stm32_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..00f489e5a3a4dd26cb87a3632c818a3f6d016e13 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_ethernet.h @@ -0,0 +1,118 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_ethernet.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_ETHERNET_H +#define __ARCH_ARM_SRC_STM32F7_STM32_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip/stm32_ethernet.h" + +#if STM32F7_NETHERNET > 0 +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Function: stm32_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the STM32 chip supports + * multiple Ethernet controllers, then board specific logic must implement + * up_netinitialize() and call this function to initialize the desired interfaces. + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value identifies which + * EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#if STM32F7_NETHERNET > 1 +int stm32_ethinitialize(int intf); +#endif + +/************************************************************************************ + * Function: stm32_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can be used. + * This may include such things as configuring GPIOs, resetting the PHY, etc. If + * CONFIG_STM32F7_PHYINIT is defined in the configuration then the board specific + * logic must provide stm32_phyinitialize(); The STM32 Ethernet driver will call + * this function one time before it first uses the PHY. + * + * Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#ifdef CONFIG_STM32F7_PHYINIT +int stm32_phy_boardinitialize(int intf); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* STM32F7_NETHERNET > 0 */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_ETHERNET_H */ + diff --git a/arch/arm/src/stm32f7/stm32_exti.h b/arch/arm/src/stm32f7/stm32_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..38ed8a1d6ed78bdcfdd45c6ab17eefe73da0756a --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_exti.h @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_exti.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32F7_STM32_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32_exti.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/**************************************************************************** + * Name: stm32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +xcpt_t stm32_exti_alarm(bool risingedge, bool fallingedge, bool event, xcpt_t func); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32f7/stm32_exti_alarm.c b/arch/arm/src/stm32f7/stm32_exti_alarm.c new file mode 100644 index 0000000000000000000000000000000000000000..ff53915178a1a4d9ebf41a96484bd1f76f44df1a --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_exti_alarm.c @@ -0,0 +1,171 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_exti_alarm.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file derives from similar logic for the STM32 F1: + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Diego Sanchez + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the ALARM EXTI */ + +static xcpt_t stm32_exti_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_alarm_isr + * + * Description: + * EXTI ALARM interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32_exti_alarm_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI_RTC_ALARM, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callback) + { + ret = stm32_exti_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edget + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_callback; + stm32_exti_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32_IRQ_RTCALRM, stm32_exti_alarm_isr); + up_enable_irq(STM32_IRQ_RTCALRM); + } + else + { + up_disable_irq(STM32_IRQ_RTCALRM); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : EXTI_RTC_ALARM, + risingedge ? EXTI_RTC_ALARM : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : EXTI_RTC_ALARM, + fallingedge ? EXTI_RTC_ALARM : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : EXTI_RTC_ALARM, + event ? EXTI_RTC_ALARM : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : EXTI_RTC_ALARM, + func ? EXTI_RTC_ALARM : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32f7/stm32_exti_gpio.c b/arch/arm/src/stm32f7/stm32_exti_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..7c150275635df00eae0cac6d81dc0a656892162d --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_exti_gpio.c @@ -0,0 +1,372 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_exti_gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on EXTI GPIO logic from the Cortex-M3/4 which includes contributions + * from Uros Patise: + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static xcpt_t stm32_exti_callbacks[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routines - Dispatchers + ****************************************************************************/ + +static int stm32_exti0_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0001, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[0]) + { + ret = stm32_exti_callbacks[0](irq, context); + } + + return ret; +} + +static int stm32_exti1_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0002, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[1]) + { + ret = stm32_exti_callbacks[1](irq, context); + } + + return ret; +} + +static int stm32_exti2_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0004, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[2]) + { + ret = stm32_exti_callbacks[2](irq, context); + } + + return ret; +} + +static int stm32_exti3_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0008, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[3]) + { + ret = stm32_exti_callbacks[3](irq, context); + } + + return ret; +} + +static int stm32_exti4_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0010, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[4]) + { + ret = stm32_exti_callbacks[4](irq, context); + } + + return ret; +} + +static int stm32_exti_multiisr(int irq, void *context, int first, int last) +{ + uint32_t pr; + int pin; + int ret = OK; + + /* Examine the state of each pin in the group */ + + pr = getreg32(STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + for (pin = first; pin <= last; pin++) + { + /* Is an interrupt pending on this pin? */ + + uint32_t mask = (1 << pin); + if ((pr & mask) != 0) + { + /* Clear the pending interrupt */ + + putreg32(mask, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_callbacks[pin]) + { + int tmp = stm32_exti_callbacks[pin](irq, context); + if (tmp != OK) + { + ret = tmp; + } + } + } + } + + return ret; +} + +static int stm32_exti95_isr(int irq, void *context) +{ + return stm32_exti_multiisr(irq, context, 5, 9); +} + +static int stm32_exti1510_isr(int irq, void *context) +{ + return stm32_exti_multiisr(irq, context, 10, 15); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func) +{ + uint32_t pin = pinset & GPIO_PIN_MASK; + uint32_t exti = STM32_EXTI_BIT(pin); + int irq; + xcpt_t handler; + xcpt_t oldhandler = NULL; + int nshared; + xcpt_t *shared_cbs; + int i; + + /* Select the interrupt handler for this EXTI pin */ + + if (pin < 5) + { + irq = pin + STM32_IRQ_EXTI0; + nshared = 1; + shared_cbs = &stm32_exti_callbacks[pin]; + switch (pin) + { + case 0: + handler = stm32_exti0_isr; + break; + + case 1: + handler = stm32_exti1_isr; + break; + + case 2: + handler = stm32_exti2_isr; + break; + + case 3: + handler = stm32_exti3_isr; + break; + + default: + handler = stm32_exti4_isr; + break; + } + } + else if (pin < 10) + { + irq = STM32_IRQ_EXTI95; + handler = stm32_exti95_isr; + shared_cbs = &stm32_exti_callbacks[5]; + nshared = 5; + } + else + { + irq = STM32_IRQ_EXTI1510; + handler = stm32_exti1510_isr; + shared_cbs = &stm32_exti_callbacks[10]; + nshared = 6; + } + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_callbacks[pin]; + stm32_exti_callbacks[pin] = func; + + /* Install external interrupt handlers */ + + if (func) + { + irq_attach(irq, handler); + up_enable_irq(irq); + } + else + { + /* Only disable IRQ if shared handler does not have any active + * callbacks. + */ + + for (i = 0; i < nshared; i++) + { + if (shared_cbs[i] != NULL) + { + break; + } + } + + if (i == nshared) + { + up_disable_irq(irq); + } + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + if (event || func) + { + pinset |= GPIO_EXTI; + } + + stm32_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : exti, + risingedge ? exti : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : exti, + fallingedge ? exti : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : exti, + event ? exti : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : exti, + func ? exti : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ diff --git a/arch/arm/src/stm32f7/stm32_exti_pwr.c b/arch/arm/src/stm32f7/stm32_exti_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..104dbff01055da91010d43b23fb5002cd30b64be --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_exti_pwr.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/arm/src/stm32v7/stm32_exti_pwr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file derives from similar logic for the STM32 F1: + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Gregory Nutt + * Dmitry Nikolaev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" +#include "stm32_exti_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the PVD EXTI */ + +static xcpt_t stm32_exti_pvd_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_pvd_isr + * + * Description: + * EXTI PVD interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32_exti_pvd_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI_PVD_LINE, STM32_EXTI_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32_exti_pvd_callback) + { + ret = stm32_exti_pvd_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32_exti_pvd_callback; + stm32_exti_pvd_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32_IRQ_PVD, stm32_exti_pvd_isr); + up_enable_irq(STM32_IRQ_PVD); + } + else + { + up_disable_irq(STM32_IRQ_PVD); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR, + risingedge ? 0 : EXTI_PVD_LINE, + risingedge ? EXTI_PVD_LINE : 0); + modifyreg32(STM32_EXTI_FTSR, + fallingedge ? 0 : EXTI_PVD_LINE, + fallingedge ? EXTI_PVD_LINE : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR, + event ? 0 : EXTI_PVD_LINE, + event ? EXTI_PVD_LINE : 0); + modifyreg32(STM32_EXTI_IMR, + func ? 0 : EXTI_PVD_LINE, + func ? EXTI_PVD_LINE : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32f7/stm32_gpio.c b/arch/arm/src/stm32f7/stm32_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..ee4e0f819bbf3abd2ddbe3e39d09c9409bbb4e62 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_gpio.c @@ -0,0 +1,455 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/stm32_syscfg.h" +#include "stm32_gpio.h" + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[STM32F7_NGPIO] = +{ +#if STM32F7_NGPIO > 0 + STM32_GPIOA_BASE, +#endif +#if STM32F7_NGPIO > 1 + STM32_GPIOB_BASE, +#endif +#if STM32F7_NGPIO > 2 + STM32_GPIOC_BASE, +#endif +#if STM32F7_NGPIO > 3 + STM32_GPIOD_BASE, +#endif +#if STM32F7_NGPIO > 4 + STM32_GPIOE_BASE, +#endif +#if STM32F7_NGPIO > 5 + STM32_GPIOF_BASE, +#endif +#if STM32F7_NGPIO > 6 + STM32_GPIOG_BASE, +#endif +#if STM32F7_NGPIO > 7 + STM32_GPIOH_BASE, +#endif +#if STM32F7_NGPIO > 8 + STM32_GPIOI_BASE, +#endif +#if STM32F7_NGPIO > 9 + STM32_GPIOJ_BASE, +#endif +#if STM32F7_NGPIO > 10 + STM32_GPIOK_BASE, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exclusion is necessary. + * + ****************************************************************************/ + +void stm32_gpioinit(void) +{ +} + +/**************************************************************************** + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * A negated errono value on invalid port, or when pin is locked as ALT + * function. + * + * To-Do: Auto Power Enable + ****************************************************************************/ + +int stm32_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + unsigned int regoffset; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int pinmode; + irqstate_t flags; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32F7_NGPIO) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set up the mode register (and remember whether the pin mode) */ + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input mode */ + pinmode = GPIO_MODER_INPUT; + break; + + case GPIO_OUTPUT: /* General purpose output mode */ + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + STM32_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_MODER_OFFSET); + + /* Set up the pull-up/pull-down configuration (all but analog pins) */ + + setting = GPIO_PUPDR_NONE; + if (pinmode != GPIO_MODER_ANALOG) + { + switch (cfgset & GPIO_PUPD_MASK) + { + default: + case GPIO_FLOAT: /* No pull-up, pull-down */ + break; + + case GPIO_PULLUP: /* Pull-up */ + setting = GPIO_PUPDR_PULLUP; + break; + + case GPIO_PULLDOWN: /* Pull-down */ + setting = GPIO_PUPDR_PULLDOWN; + break; + } + } + + regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET); + + /* Set the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pin < 8) + { + regoffset = STM32_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Set speed (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_SPEED_MASK) + { + default: + case GPIO_SPEED_2MHz: /* 2 MHz Low speed output */ + setting = GPIO_OSPEED_2MHz; + break; + + case GPIO_SPEED_25MHz: /* 25 MHz Medium speed output */ + setting = GPIO_OSPEED_25MHz; + break; + + case GPIO_SPEED_50MHz: /* 50 MHz Fast speed output */ + setting = GPIO_OSPEED_50MHz; + break; + + case GPIO_SPEED_100MHz: /* 100 MHz High speed output */ + setting = GPIO_OSPEED_100MHz; + break; + } + } + else + { + setting = 0; + } + + regval = getreg32(base + STM32_GPIO_OSPEED_OFFSET); + regval &= ~GPIO_OSPEED_MASK(pin); + regval |= (setting << GPIO_OSPEED_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_OSPEED_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + STM32_GPIO_OTYPER_OFFSET); + setting = GPIO_OTYPER_OD(pin); + + if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) && + (cfgset & GPIO_OPENDRAIN) != 0) + { + regval |= setting; + } + else + { + regval &= ~setting; + } + + putreg32(regval, base + STM32_GPIO_OTYPER_OFFSET); + + /* If it is an output... set the pin to the correct initial state. */ + + if (pinmode == GPIO_MODER_OUTPUT) + { + bool value = ((cfgset & GPIO_OUTPUT_SET) != 0); + stm32_gpiowrite(cfgset, value); + } + + /* Otherwise, it is an input pin. Should it configured as an EXTI interrupt? */ + + else if ((cfgset & GPIO_EXTI) != 0) + { + /* "In STM32 F1 the selection of the EXTI line source is performed through + * the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this + * selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers. + * + * "Only the mapping of the EXTICRx registers has been changed, without any + * changes to the meaning of the EXTIx bits. However, the range of EXTI + * bits values has been extended to 0b1000 to support the two ports added + * in F2, port H and I (in F1 series the maximum value is 0b0110)." + */ + + uint32_t regaddr; + int shift; + + /* Set the bits in the SYSCFG EXTICR register */ + + regaddr = STM32_SYSCFG_EXTICR(pin); + regval = getreg32(regaddr); + shift = SYSCFG_EXTICR_EXTI_SHIFT(pin); + regval &= ~(SYSCFG_EXTICR_PORT_MASK << shift); + regval |= (((uint32_t)port) << shift); + + putreg32(regval, regaddr); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previously selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * A negated errno value on invalid port + * + * To-Do: Auto Power Disable + ****************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset) +{ + /* Reuse port and pin number and set it to default HiZ INPUT */ + + cfgset &= GPIO_PORT_MASK | GPIO_PIN_MASK; + cfgset |= GPIO_INPUT | GPIO_FLOAT; + + /* To-Do: Mark its unuse for automatic power saving options */ + + return stm32_configgpio(cfgset); +} + +/**************************************************************************** + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value) +{ + uint32_t base; + uint32_t bit; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32F7_NGPIO) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + bit = GPIO_BSRR_SET(pin); + } + else + { + bit = GPIO_BSRR_RESET(pin); + } + + putreg32(bit, base + STM32_GPIO_BSRR_OFFSET); + } +} + +/**************************************************************************** + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32F7_NGPIO) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + STM32_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + return 0; +} + +#endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX */ diff --git a/arch/arm/src/stm32f7/stm32_gpio.h b/arch/arm/src/stm32f7/stm32_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..7fff5e249984d0598908d038e8d1c72e1f29a77f --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_gpio.h @@ -0,0 +1,373 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32F7_STM32_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" +#include "chip/stm32_gpio.h" + +/************************************************************************************ + * Pre-Processor Declarations + ************************************************************************************/ + +/* Bit-encoded input to stm32_configgpio() */ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually configured + * by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU .... ...X PPPP BBBB + * Outputs: MMUU .... FFOV PPPP BBBB + * Alternate Functions: MMUU AAAA FFO. PPPP BBBB + * Analog: MM.. .... .... PPPP BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ +# define GPIO_ANALOG (3 << GPIO_MODE_SHIFT) /* Analog mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (15 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) +# define GPIO_AF8 (8 << GPIO_AF_SHIFT) +# define GPIO_AF9 (9 << GPIO_AF_SHIFT) +# define GPIO_AF10 (10 << GPIO_AF_SHIFT) +# define GPIO_AF11 (11 << GPIO_AF_SHIFT) +# define GPIO_AF12 (12 << GPIO_AF_SHIFT) +# define GPIO_AF13 (13 << GPIO_AF_SHIFT) +# define GPIO_AF14 (14 << GPIO_AF_SHIFT) +# define GPIO_AF15 (15 << GPIO_AF_SHIFT) + +/* Output/Alt function frequency selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... FF.. .... .... + */ + +#define GPIO_SPEED_SHIFT (10) /* Bits 10-11: GPIO frequency selection */ +#define GPIO_SPEED_MASK (3 << GPIO_SPEED_SHIFT) +# define GPIO_SPEED_2MHz (0 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_25MHz (1 << GPIO_SPEED_SHIFT) /* 25 MHz Medium speed output */ +# define GPIO_SPEED_50MHz (2 << GPIO_SPEED_SHIFT) /* 50 MHz Fast speed output */ +# define GPIO_SPEED_100MHz (3 << GPIO_SPEED_SHIFT) /* 100 MHz High speed output */ + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ +#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */ + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * If the pin is an input, this bit is overloaded to provide the qualifier to + * distinquish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...X .... .... + */ + +#define GPIO_EXTI (1 << 8) /* Bit 8: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPPP .... + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ +# define GPIO_PORTI (8 << GPIO_PORT_SHIFT) /* GPIOI */ +# define GPIO_PORTJ (9 << GPIO_PORT_SHIFT) /* GPIOJ */ +# define GPIO_PORTK (10 << GPIO_PORT_SHIFT) /* GPIOK */ + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Base addresses for each GPIO block */ + +EXTERN const uint32_t g_gpiobase[STM32F7_NGPIO]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ************************************************************************************/ + +int stm32_configgpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previously selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * ERROR on invalid port + * + ************************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value); + +/************************************************************************************ + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool stm32_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG +int stm32_dumpgpio(uint32_t pinset, const char *msg); +#else +# define stm32_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + ************************************************************************************/ + +void stm32_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32f7/stm32_irq.c b/arch/arm/src/stm32f7/stm32_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..a52e3e56d934e02eb24a8b92f79d32bb1960e1b4 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_irq.c @@ -0,0 +1,686 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_irq.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#ifdef CONFIG_STM32F7_GPIO_IRQ +# include "stm32_gpio.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void stm32_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); +#if NR_INTERRUPTS > 15 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); +#endif +#if NR_INTERRUPTS > 31 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); +#endif +#if NR_INTERRUPTS > 47 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); +#endif +#if NR_INTERRUPTS > 63 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); +#endif +#if NR_INTERRUPTS > 79 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), getreg32(NVIC_IRQ92_95_PRIORITY)); +#endif +#if NR_INTERRUPTS > 95 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), getreg32(NVIC_IRQ108_111_PRIORITY)); +#endif +#if NR_INTERRUPTS > 111 +# warning Missing logic +#endif + leave_critical_section(flags); +} +#else +# define stm32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32_nmi, stm32_busfault, stm32_usagefault, stm32_pendsv, stm32_dbgmonitor, + * stm32_pendsv, stm32_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int stm32_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int stm32_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void stm32_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: stm32_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int stm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + unsigned int extint = irq - STM32_IRQ_FIRST; + + DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= STM32_IRQ_FIRST) + { +#if NR_INTERRUPTS <= 32 + if (extint < NR_INTERRUPTS) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else +#elif NR_INTERRUPTS <= 64 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < NR_INTERRUPTS) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else +#elif NR_INTERRUPTS <= 96 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < NR_INTERRUPTS) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else +#elif NR_INTERRUPTS <= 128 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < NR_INTERRUPTS) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else +#else +# warning Missing logic +#endif + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == STM32_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == STM32_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == STM32_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == STM32_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + uint32_t regval; +#endif + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(STM32_IRQ_SVCALL, up_svcall); + irq_attach(STM32_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, up_memfault); + up_enable_irq(STM32_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(STM32_IRQ_NMI, stm32_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault); + irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault); + irq_attach(STM32_IRQ_PENDSV, stm32_pendsv); + irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor); + irq_attach(STM32_IRQ_RESERVED, stm32_reserved); +#endif + + stm32_dumpnvic("initial", STM32_IRQ_NIRQS); + + /* If a debugger is connected, try to prevent it from catching hardfaults. + * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal + * operation. + */ + +#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI) + regval = getreg32(NVIC_DEMCR); + regval &= ~NVIC_DEMCR_VCHARDERR; + putreg32(regval, NVIC_DEMCR); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_STM32F7_GPIO_IRQ + stm32_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_STM32F7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + stm32_gpioirqdisable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + stm32_dumpnvic("disable", irq); +#endif +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_STM32F7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + stm32_gpioirqenable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + stm32_dumpnvic("enable", irq); +#endif +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < STM32_IRQ_NIRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < STM32_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= STM32_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + stm32_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/stm32f7/stm32_lowputc.c b/arch/arm/src/stm32f7/stm32_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..d642c862a69f0c58174aa47cc259628dba5bd57b --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_lowputc.c @@ -0,0 +1,440 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_lowputc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "chip/stm32_pinmap.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART1_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR +# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32_CONSOLE_TX GPIO_USART1_TX +# define STM32_CONSOLE_RX GPIO_USART1_RX +# ifdef CONFIG_USART1_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_USART2EN +# define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART2_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART2_2STOP +# define STM32_CONSOLE_TX GPIO_USART2_TX +# define STM32_CONSOLE_RX GPIO_USART2_RX +# ifdef CONFIG_USART2_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART3_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_USART3EN +# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32_CONSOLE_TX GPIO_USART3_TX +# define STM32_CONSOLE_RX GPIO_USART3_RX +# ifdef CONFIG_USART3_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART4_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART4EN +# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32_CONSOLE_TX GPIO_UART4_TX +# define STM32_CONSOLE_RX GPIO_UART4_RX +# ifdef CONFIG_UART4_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART5_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART5EN +# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32_CONSOLE_TX GPIO_UART5_TX +# define STM32_CONSOLE_RX GPIO_UART5_RX +# ifdef CONFIG_UART5_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART6_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART6_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR +# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART6EN +# define STM32_CONSOLE_BAUD CONFIG_USART6_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART6_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART6_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART6_2STOP +# define STM32_CONSOLE_TX GPIO_USART6_TX +# define STM32_CONSOLE_RX GPIO_USART6_RX +# ifdef CONFIG_USART6_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART6_RS485_DIR +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART7_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART7EN +# define STM32_CONSOLE_BAUD CONFIG_UART7_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART7_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART7_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART7_2STOP +# define STM32_CONSOLE_TX GPIO_UART7_TX +# define STM32_CONSOLE_RX GPIO_UART7_RX +# ifdef CONFIG_UART7_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART7_RS485_DIR +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART8_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART8_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR +# define STM32_CONSOLE_APBEN RCC_APB1ENR_UART8EN +# define STM32_CONSOLE_BAUD CONFIG_UART8_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART8_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART8_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART8_2STOP +# define STM32_CONSOLE_TX GPIO_UART8_TX +# define STM32_CONSOLE_RX GPIO_UART8_RX +# ifdef CONFIG_UART8_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART8_RS485_DIR +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# endif + + /* CR1 settings */ + +# if STM32_CONSOLE_BITS == 7 +# define USART_CR_M01_VALUE USART_CR1_M1 +# elif STM32_CONSOLE_BITS == 9 +# define USART_CR_M01_VALUE USART_CR1_M0 +# else /* STM32_CONSOLE_BITS == 8 */ +# define USART_CR_M01_VALUE 0 +# endif + +# if STM32_CONSOLE_PARITY == 1 +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32_CONSOLE_PARITY == 2 +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +# else +# define USART_CR1_PARITY_VALUE 0 +# endif + +# define USART_CR1_CLRBITS \ + (USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | USART_CR1_PCE | \ + USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_MME | USART_CR1_OVER8 | \ + USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) + +# define USART_CR1_SETBITS (USART_CR_M01_VALUE | USART_CR1_PARITY_VALUE) + + /* CR2 settings */ + +# if STM32_CONSOLE_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +# else +# define USART_CR2_STOP2_VALUE 0 +# endif + +# define USART_CR2_CLRBITS \ + (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ + USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ + USART_CR2_LINEN | USART_CR2_RXINV | USART_CR2_TXINV | USART_CR2_DATAINV | \ + USART_CR2_MSBFIRST | USART_CR2_ABREN | USART_CR2_ABRMOD_MASK | \ + USART_CR2_RTOEN | USART_CR2_ADD8_MASK) + +# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + + /* CR3 settings */ + +# define USART_CR3_CLRBITS \ + (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ + USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ + USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR1_ONEBIT | \ + USART_CR1_OVRDIS | USART_CR1_DDRE | USART_CR1_DEM | USART_CR1_DEP | \ + USART_CR1_SCARCNT_MASK) + +# define USART_CR3_SETBITS 0 + + /* Only the STM32 F3 supports oversampling by 8 */ + +# undef USE_OVER8 + + /* Calculate USART BAUD rate divider */ + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ + +# define STM32_USARTDIV8 \ + (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) +# define STM32_USARTDIV16 \ + ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) + + /* Use oversampling by 8 only if the divisor is small. But what is small? */ + +# if STM32_USARTDIV8 > 100 +# define STM32_BRR_VALUE STM32_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32_BRR_VALUE \ + ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1)) +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + /* Wait until the TX data register is empty */ + + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & USART_ISR_TXE) == 0); +#ifdef STM32_CONSOLE_RS485_DIR + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Then send the character */ + + putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_TDR_OFFSET); + +#ifdef STM32_CONSOLE_RS485_DIR + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & USART_ISR_TC) == 0); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: stm32_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void stm32_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + +#if defined(HAVE_CONSOLE) + /* Enable USART APB1/2 clock */ + + modifyreg32(STM32_CONSOLE_APBREG, 0, STM32_CONSOLE_APBEN); +#endif + + /* Enable the console USART and configure GPIO pins needed for rx/tx. + * + * NOTE: Clocking for selected U[S]ARTs was already provided in stm32_rcc.c + */ + +#ifdef STM32_CONSOLE_TX + stm32_configgpio(STM32_CONSOLE_TX); +#endif +#ifdef STM32_CONSOLE_RX + stm32_configgpio(STM32_CONSOLE_RX); +#endif + +#ifdef STM32_CONSOLE_RS485_DIR + stm32_configgpio(STM32_CONSOLE_RS485_DIR); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + /* Select oversampling by 8 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#endif + + /* Enable Rx, Tx, and the USART */ + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/arm/src/stm32f7/stm32_lowputc.h b/arch/arm/src/stm32f7/stm32_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..a848277a185a982fce0eb7b6f7bb7b59437b3253 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_lowputc.h @@ -0,0 +1,78 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_lowputc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32F7_STM32_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: stm32_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * of serial console. + * + ************************************************************************************/ + +void stm32_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_LOWPUTC_H */ + diff --git a/arch/arm/src/stm32f7/stm32_mpuinit.c b/arch/arm/src/stm32f7/stm32_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..096742a0ecc2854fd46946fa230b9a650f598bf7 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_mpuinit.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_mpuinit.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "stm32_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void stm32_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void stm32_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/stm32f7/stm32_mpuinit.h b/arch/arm/src/stm32f7/stm32_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..5e2d613e123a2fa8d54076627fd241cfae906d19 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_mpuinit.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * Name: stm32_mpuinitialize + * arch/arm/src/stm32f7/stm32_mpuinit.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_MPUINIT_H +#define __ARCH_ARM_SRC_STM32F7_STM32_MPUINIT_H + +/**************************************************************************** + * Name: stm32_mpuinitialize + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Name: stm32_mpuinitialize + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted + * STM32F7 resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpuinitialize(void); +#else +# define stm32_mpuinitialize() +#endif + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpu_uheap(uintptr_t start, size_t size); +#else +# define stm32_mpu_uheap(start,size) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_MPUINIT_H */ diff --git a/arch/arm/src/stm32f7/stm32_procfs_dtcm.c b/arch/arm/src/stm32f7/stm32_procfs_dtcm.c new file mode 100644 index 0000000000000000000000000000000000000000..af6f467fef5cba94bea1fc75d50833e4a0249b80 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_procfs_dtcm.c @@ -0,0 +1,323 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_procfs_dtcm.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on STM32 CCM code contributed by Pelle Windestam: + * + * Copyright (C) 2014 Pelle Windestam. All rights reserved. + * Author: Pelle Windestam (pelle@windestam.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "stm32_dtcm.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DTCM_LINELEN 64 + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This enumeration identifies all of the thread attributes that can be + * accessed via the procfs file system. + */ + +/* This structure describes one open "file" */ + +struct dtcm_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + unsigned int linesize; /* Number of valid characters in line[] */ + char line[DTCM_LINELEN]; /* Pre-allocated buffer for formatted lines */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* File system methods */ + +static int dtcm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int dtcm_close(FAR struct file *filep); +static ssize_t dtcm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int dtcm_dup(FAR const struct file *oldp, + FAR struct file *newp); +static int dtcm_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* See include/nutts/fs/procfs.h + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct procfs_operations dtcm_procfsoperations = +{ + dtcm_open, /* open */ + dtcm_close, /* close */ + dtcm_read, /* read */ + NULL, /* write */ + dtcm_dup, /* dup */ + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + dtcm_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dtcm_open + ****************************************************************************/ + +static int dtcm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct dtcm_file_s *priv; + + fvdbg("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) + { + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "cpuload" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "dtcm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* Allocate a container to hold the task and attribute selection */ + + priv = (FAR struct dtcm_file_s *)kmm_zalloc(sizeof(struct dtcm_file_s)); + if (!priv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the index as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)priv; + return OK; +} + +/**************************************************************************** + * Name: dtcm_close + ****************************************************************************/ + +static int dtcm_close(FAR struct file *filep) +{ + FAR struct dtcm_file_s *priv; + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct dtcm_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + /* Release the file attributes structure */ + + kmm_free(priv); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: dtcm_read + ****************************************************************************/ + +static ssize_t dtcm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct dtcm_file_s *priv; + size_t linesize; + size_t copysize; + size_t remaining; + size_t totalsize; + struct mallinfo mem; + off_t offset = filep->f_pos; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct dtcm_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + + mm_mallinfo(&g_dtcm_heap, &mem); + + remaining = buflen; + totalsize = 0; + + linesize = snprintf(priv->line, + DTCM_LINELEN, + " total used free largest\n"); + copysize = procfs_memcpy(priv->line, linesize, buffer, remaining, &offset); + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + + if (totalsize >= buflen) + { + return totalsize; + } + + linesize = snprintf(priv->line, + DTCM_LINELEN, + "Mem: %11d%11d%11d%11d\n", + mem.arena, + mem.uordblks, + mem.fordblks, + mem.mxordblk); + copysize = procfs_memcpy(priv->line, linesize, buffer, remaining, &offset); + totalsize += copysize; + + /* Update the file offset */ + + if (totalsize > 0) + { + filep->f_pos += totalsize; + } + + return totalsize; +} + +/**************************************************************************** + * Name: dtcm_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int dtcm_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct dtcm_file_s *oldpriv; + FAR struct dtcm_file_s *newpriv; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldpriv = (FAR struct dtcm_file_s *)oldp->f_priv; + DEBUGASSERT(oldpriv); + + /* Allocate a new container to hold the task and attribute selection */ + + newpriv = (FAR struct dtcm_file_s *)kmm_zalloc(sizeof(struct dtcm_file_s)); + if (!newpriv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attributes from the old attributes to the new */ + + memcpy(newpriv, oldpriv, sizeof(struct dtcm_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newpriv; + return OK; +} + +static int dtcm_stat(const char *relpath, struct stat *buf) +{ + if (strcmp(relpath, "dtcm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + buf->st_size = 0; + buf->st_blksize = 0; + buf->st_blocks = 0; + + return OK; +} + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */ diff --git a/arch/arm/src/stm32f7/stm32_pwr.h b/arch/arm/src/stm32f7/stm32_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..3c5a30f96738676775413bc07942eb930ffd28d7 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_pwr.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_pwr.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32F7_STM32_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32_pwr.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables access to the backup domain (RTC registers, RTC backup data registers + * and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writeable. + * + ************************************************************************************/ + +bool stm32_pwr_enablebkp(bool writable); + +/************************************************************************************ + * Name: stm32_pwr_enablebreg + * + * Description: + * Enables the Backup regulator, the Backup regulator (used to maintain backup + * SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup + * regulator is switched off. The backup SRAM can still be used but its content will + * be lost in the Standby and VBAT modes. Once set, the application must wait that + * the Backup Regulator Ready flag (BRR) is set to indicate that the data written + * into the RAM will be maintained in the Standby and VBAT modes. + * + * Input Parameters: + * regon - state to set it to + * + * Returned Values: + * None + * + ************************************************************************************/ + +void stm32_pwr_enablebreg(bool regon); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_PWR_H */ diff --git a/arch/arm/src/stm32f7/stm32_rcc.c b/arch/arm/src/stm32f7/stm32_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..bd1d1e7bcab3645b87538e183038cdb56ae31e45 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_rcc.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_rcc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/stm32_flash.h" +#include "stm32_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "stm32f74xx75xx_rcc.c" +#else +# error "Unsupported STM32 F7 chip" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all peripherals enabled in the NuttX + * configurationfile. + * + * If CONFIG_STM32F7_CUSTOM_CLOCKCONFIG is defined, then clocking + * will be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_clockconfig(void) +{ + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + +#if defined(CONFIG_STM32F7_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); +} + +/************************************************************************************ + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_STM32F7_CUSTOM_CLOCKCONFIG is defined, then clocking will be enabled + * by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void) +{ +#if defined(CONFIG_STM32F7_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif +} +#endif diff --git a/arch/arm/src/stm32f7/stm32_rcc.h b/arch/arm/src/stm32f7/stm32_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..40f3155ccadd919f6a0c76e374f72f7a56be08e0 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_rcc.h @@ -0,0 +1,255 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_rcc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_RRC_H +#define __ARCH_ARM_SRC_STM32F7_STM32_RRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" + +#include "chip/stm32_rcc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* This symbol references the Cortex-M7 vector table (as positioned by the linker + * script, ld.script or ld.script.dfu. The standard location for the vector table is + * at the beginning of FLASH at address 0x0800:0000. If we are using the STMicro DFU + * bootloader, then the vector table will be offset to a different location in FLASH + * and we will need to set the NVIC vector location to this alternative location. + */ + +extern uint32_t _vectors[]; /* See stm32_vectors.S */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_mco1config + * + * Description: + * Selects the clock source to output on MCO1 pin (PA8). PA8 should be configured in + * alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO1 definitions from + * chip/stm32f7xxxx_rcc.h {RCC_CFGR_MCO1_HSI, RCC_CFGR_MCO1_LSE, + * RCC_CFGR_MCO1_HSE, RCC_CFGR_MCO1_PLL} + * div - One of the definitions for the RCC_CFGR_MCO1PRE definitions from + * chip/stm32f7xxxx_rcc.h {RCC_CFGR_MCO1PRE_NONE, RCC_CFGR_MCO1PRE_DIV2, + * RCC_CFGR_MCO1PRE_DIV3, RCC_CFGR_MCO1PRE_DIV4, RCC_CFGR_MCO1PRE_DIV5} + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_mco1config(uint32_t source, uint32_t div) +{ + uint32_t regval; + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO1_MASK|RCC_CFGR_MCO1PRE_MASK); + regval |= (source | div); + putreg32(regval, STM32_RCC_CFGR); +} + +/************************************************************************************ + * Name: stm32_mco2config + * + * Description: + * Selects the clock source to output on MCO2 pin (PC9). PC9 should be configured in + * alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO2 definitions from + * chip/stn32f7xxxx_rcc.h {RCC_CFGR_MCO2_SYSCLK, RCC_CFGR_MCO2_PLLI2S, + * RCC_CFGR_MCO2_HSE, RCC_CFGR_MCO2_PLL} + * div - One of the definitions for the RCC_CFGR_MCO2PRE definitions from + * chip/stn32f7xxxx_rcc.h {RCC_CFGR_MCO2PRE_NONE, RCC_CFGR_MCO2PRE_DIV2, + * RCC_CFGR_MCO2PRE_DIV3, RCC_CFGR_MCO2PRE_DIV4, RCC_CFGR_MCO2PRE_DIV5} + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32_mco2config(uint32_t source, uint32_t div) +{ + uint32_t regval; + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO2_MASK|RCC_CFGR_MCO2PRE_MASK); + regval |= (source | div); + putreg32(regval, STM32_RCC_CFGR); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all peripherals enabled in the NuttX configuration + * file. + * + * If CONFIG_STM32F7_CUSTOM_CLOCKCONFIG is defined, then clocking will be enabled + * by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_clockconfig(void); + +/************************************************************************************ + * Name: stm32_board_clockconfig + * + * Description: + * Any STM32 board may replace the "standard" board clock configuration logic with + * its own, custom clock configuration logic. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32F7_CUSTOM_CLOCKCONFIG +void stm32_board_clockconfig(void); +#endif + +/************************************************************************************ + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not reset the + * currently enabled peripheral clocks. + * + * If CONFIG_STM32F7_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void); +#endif + +/************************************************************************************ + * Name: stm32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator and, if the RTC is + * configured, setup the LSE as the RTC clock source, and enable the RTC. + * + * For the STM32L15X family, this will also select the LSE as the clock source of + * the LCD. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32_rcc_enablelse(void); + +/**************************************************************************** + * Name: stm32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_enablelsi(void); + +/**************************************************************************** + * Name: stm32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_disablelsi(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_RRC_H */ diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..d62b78fd6ed4e247d377e36d393b1f4b965df6b6 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -0,0 +1,2889 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_serial.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "cache.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "stm32_gpio.h" +#include "chip/stm32_pinmap.h" +#include "stm32_dma.h" +#include "stm32_rcc.h" +#include "stm32_uart.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Total number of possible serial devices */ + +#define STM32_NSERIAL (STM32F7_NUSART + STM32F7_NUART) + +/* DMA configuration */ + +/* If DMA is enabled on any USART, then very that other pre-requisites + * have also been selected. + */ + +#ifdef SERIAL_HAVE_DMA + +/* Verify that DMA has been enabled and the DMA channel has been defined. + */ + +# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA) +# ifndef CONFIG_STM32F7_DMA2 +# error STM32 USART1/6 receive DMA requires CONFIG_STM32F7_DMA2 +# endif +# endif + +# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \ + defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) || \ + defined(CONFIG_UART7_RXDMA) || defined(CONFIG_UART8_RXDMA) +# ifndef CONFIG_STM32F7_DMA1 +# error STM32 USART2/3/4/5/7/8 receive DMA requires CONFIG_STM32F7_DMA1 +# endif +# endif + +/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack + * of testing - RS-485 support was developed on STM32F1x + */ + +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ + (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ + (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ + (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ + (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) || \ + (defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_RS485)) || \ + (defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_RS485)) || \ + (defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_RS485)) +# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" +# endif + +/* There may be alternate DMA channels for each U[S]ART. Logic in the + * board.h file should provide definitions to select among the alternatives. + */ + +# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) +# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" +# endif + +# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX) +# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)" +# endif + +# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX) +# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)" +# endif + +# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX) +# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)" +# endif + +# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX) +# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)" +# endif + +# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX) +# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)" +# endif + +# if defined(CONFIG_UART7_RXDMA) && !defined(DMAMAP_UART7_RX) +# error "UART7 DMA channel not defined (DMAMAP_UART7_RX)" +# endif + +# if defined(CONFIG_UART8_RXDMA) && !defined(DMAMAP_UART8_RX) +# error "UART8 DMA channel not defined (DMAMAP_UART8_RX)" +# endif + +/* The DMA buffer size when using RX DMA to emulate a FIFO. + * + * When streaming data, the generic serial layer will be called + * every time the FIFO receives half this number of bytes. + * + * This buffer size should be an even multiple of the Cortex-M7 + * D-Cache line size so that it can be individually invalidated. + */ + +# define RXDMA_BUFFER_MASK (ARMV7M_DCACHE_LINESIZE - 1) +# define RXDMA_BUFFER_SIZE ((32 + RXDMA_BUFFER_MASK) & ~RXDMA_BUFFER_MASK) + +/* DMA priority */ + +# ifndef CONFIG_USART_DMAPRIO +# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED +# endif + +# if (CONFIG_USART_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif + +/* DMA control words */ + +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_CIRC | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# endif +#endif /* SERIAL_HAVE_DMA */ + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_PM_SERIAL_ACTIVITY) +# define CONFIG_PM_SERIAL_ACTIVITY 10 +# define PM_IDLE_DOMAIN 0 /* Revisit */ +#endif + +#ifdef USE_SERIALDRIVER +#ifdef HAVE_UART + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt mask bits value */ + uint16_t sr; /* Saved status bits */ + + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif + uint32_t baud; /* Configured baud */ +#else + const uint8_t parity; /* 0=none, 1=odd, 2=even */ + const uint8_t bits; /* Number of bits (7 or 8) */ + const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif + const uint32_t baud; /* Configured baud */ +#endif + + const uint8_t irq; /* IRQ associated with this USART */ + const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t usartbase; /* Base address of USART registers */ + const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif + +#ifdef SERIAL_HAVE_DMA + const unsigned int rxdma_channel; /* DMA channel assigned */ +#endif + + int (*const vector)(int irq, void *context); /* Interrupt handler */ + + /* RX DMA state */ + +#ifdef SERIAL_HAVE_DMA + DMA_HANDLE rxdma; /* currently-open receive DMA stream */ + bool rxenable; /* DMA-based reception en/disable */ + uint16_t rxdmain; /* Next byte in the DMA where hardware will write */ + uint16_t rxdmaout; /* Next byte in the DMA buffer to be read */ + VAR char * const rxfifo; /* Receive DMA buffer */ +#endif + +#ifdef HAVE_RS485 + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void up_set_format(struct uart_dev_s *dev); +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt_common(struct up_dev_s *dev); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, + bool upper); +#endif +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev); +static void up_dma_shutdown(struct uart_dev_s *dev); +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_dma_rxint(struct uart_dev_s *dev, bool enable); +static bool up_dma_rxavailable(struct uart_dev_s *dev); + +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +#ifdef CONFIG_STM32F7_USART1 +static int up_interrupt_usart1(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_USART2 +static int up_interrupt_usart2(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_USART3 +static int up_interrupt_usart3(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_UART4 +static int up_interrupt_uart4(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_UART5 +static int up_interrupt_uart5(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_USART6 +static int up_interrupt_usart6(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_UART7 +static int up_interrupt_uart7(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_UART8 +static int up_interrupt_uart8(int irq, void *context); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +#ifdef SERIAL_HAVE_DMA +static const struct uart_ops_s g_uart_dma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_dma_receive, + .rxint = up_dma_rxint, + .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +/* DMA buffers. DMA buffers must: + * + * 1. Be a multiple of the D-Cache line size. This requirement is assured + * by the definition of RXDMA buffer size above. + * 2. Be aligned a D-Cache line boundaries, and + * 3. Be positioned in DMA-able memory (*NOT* DTCM memory). This must + * be managed by logic in the linker script file. + * + * These DMA buffers are defined sequentially here to best assure optimal + * packing of the buffers. + */ + +#ifdef CONFIG_USART1_RXDMA +static char g_usart1rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +# ifdef CONFIG_USART2_RXDMA +static char g_usart2rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_USART3_RXDMA +static char g_usart3rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_UART4_RXDMA +static char g_uart4rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_UART5_RXDMA +static char g_uart5rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_USART6_RXDMA +static char g_usart6rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_UART7_RXDMA +static char g_uart7rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +#ifdef CONFIG_UART8_RXDMA +static char g_uart8rxfifo[RXDMA_BUFFER_SIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); +#endif + +/* Receive/Transmit buffers */ + +#ifdef CONFIG_STM32F7_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_USART6 +static char g_usart6rxbuffer[CONFIG_USART6_RXBUFSIZE]; +static char g_usart6txbuffer[CONFIG_USART6_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_UART7 +static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; +static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; +#endif + +#ifdef CONFIG_STM32F7_UART8 +static char g_uart8rxbuffer[CONFIG_UART8_RXBUFSIZE]; +static char g_uart8txbuffer[CONFIG_UART8_TXBUFSIZE]; +#endif + +/* This describes the state of the STM32 USART1 ports. */ + +#ifdef CONFIG_STM32F7_USART1 +static struct up_dev_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, +#ifdef CONFIG_USART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart1priv, + }, + + .irq = STM32_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = STM32_PCLK2_FREQUENCY, + .usartbase = STM32_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +#endif +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, + .rxfifo = g_usart1rxfifo, +#endif + .vector = up_interrupt_usart1, + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_USART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART2 port. */ + +#ifdef CONFIG_STM32F7_USART2 +static struct up_dev_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, +#ifdef CONFIG_USART2_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart2priv, + }, + + .irq = STM32_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, + .rxfifo = g_usart2rxfifo, +#endif + .vector = up_interrupt_usart2, + +#ifdef CONFIG_USART2_RS485 + .rs485_dir_gpio = GPIO_USART2_RS485_DIR, +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART3 port. */ + +#ifdef CONFIG_STM32F7_USART3 +static struct up_dev_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, +#ifdef CONFIG_USART3_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart3priv, + }, + + .irq = STM32_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, + .rxfifo = g_usart3rxfifo, +#endif + .vector = up_interrupt_usart3, + +#ifdef CONFIG_USART3_RS485 + .rs485_dir_gpio = GPIO_USART3_RS485_DIR, +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART4 port. */ + +#ifdef CONFIG_STM32F7_UART4 +static struct up_dev_s g_uart4priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, +#ifdef CONFIG_UART4_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart4priv, + }, + + .irq = STM32_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART4_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART4_BASE, + .tx_gpio = GPIO_UART4_TX, + .rx_gpio = GPIO_UART4_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART4_RXDMA + .rxdma_channel = DMAMAP_UART4_RX, + .rxfifo = g_uart4rxfifo, +#endif + .vector = up_interrupt_uart4, + +#ifdef CONFIG_UART4_RS485 + .rs485_dir_gpio = GPIO_UART4_RS485_DIR, +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART5 port. */ + +#ifdef CONFIG_STM32F7_UART5 +static struct up_dev_s g_uart5priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, +#ifdef CONFIG_UART5_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart5priv, + }, + + .irq = STM32_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART5_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART5_BASE, + .tx_gpio = GPIO_UART5_TX, + .rx_gpio = GPIO_UART5_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART5_RXDMA + .rxdma_channel = DMAMAP_UART5_RX, + .rxfifo = g_uart5rxfifo, +#endif + .vector = up_interrupt_uart5, + +#ifdef CONFIG_UART5_RS485 + .rs485_dir_gpio = GPIO_UART5_RS485_DIR, +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART6 port. */ + +#ifdef CONFIG_STM32F7_USART6 +static struct up_dev_s g_usart6priv = +{ + .dev = + { +#if CONSOLE_UART == 6 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART6_RXBUFSIZE, + .buffer = g_usart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART6_TXBUFSIZE, + .buffer = g_usart6txbuffer, + }, +#ifdef CONFIG_USART6_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart6priv, + }, + + .irq = STM32_IRQ_USART6, + .parity = CONFIG_USART6_PARITY, + .bits = CONFIG_USART6_BITS, + .stopbits2 = CONFIG_USART6_2STOP, + .baud = CONFIG_USART6_BAUD, + .apbclock = STM32_PCLK2_FREQUENCY, + .usartbase = STM32_USART6_BASE, + .tx_gpio = GPIO_USART6_TX, + .rx_gpio = GPIO_USART6_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART6_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART6_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART6_RTS, +#endif +#ifdef CONFIG_USART6_RXDMA + .rxdma_channel = DMAMAP_USART6_RX, + .rxfifo = g_usart6rxfifo, +#endif + .vector = up_interrupt_usart6, + +#ifdef CONFIG_USART6_RS485 + .rs485_dir_gpio = GPIO_USART6_RS485_DIR, +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART7 port. */ + +#ifdef CONFIG_STM32F7_UART7 +static struct up_dev_s g_uart7priv = +{ + .dev = + { +#if CONSOLE_UART == 7 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART7_RXBUFSIZE, + .buffer = g_uart7rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART7_TXBUFSIZE, + .buffer = g_uart7txbuffer, + }, +#ifdef CONFIG_UART7_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart7priv, + }, + + .irq = STM32_IRQ_UART7, + .parity = CONFIG_UART7_PARITY, + .bits = CONFIG_UART7_BITS, + .stopbits2 = CONFIG_UART7_2STOP, + .baud = CONFIG_UART7_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART7_BASE, + .tx_gpio = GPIO_UART7_TX, + .rx_gpio = GPIO_UART7_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART7_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART7_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART7_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART7_RTS, +#endif +#ifdef CONFIG_UART7_RXDMA + .rxdma_channel = DMAMAP_UART7_RX, + .rxfifo = g_uart7rxfifo, +#endif + .vector = up_interrupt_uart7, + +#ifdef CONFIG_UART7_RS485 + .rs485_dir_gpio = GPIO_UART7_RS485_DIR, +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART8 port. */ + +#ifdef CONFIG_STM32F7_UART8 +static struct up_dev_s g_uart8priv = +{ + .dev = + { +#if CONSOLE_UART == 8 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART8_RXBUFSIZE, + .buffer = g_uart8rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART8_TXBUFSIZE, + .buffer = g_uart8txbuffer, + }, +#ifdef CONFIG_UART8_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart8priv, + }, + + .irq = STM32_IRQ_UART8, + .parity = CONFIG_UART8_PARITY, + .bits = CONFIG_UART8_BITS, + .stopbits2 = CONFIG_UART8_2STOP, + .baud = CONFIG_UART8_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART8_BASE, + .tx_gpio = GPIO_UART8_TX, + .rx_gpio = GPIO_UART8_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART8_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART8_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART8_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART8_RTS, +#endif +#ifdef CONFIG_UART8_RXDMA + .rxdma_channel = DMAMAP_UART8_RX, + .rxfifo = g_uart8rxfifo, +#endif + .vector = up_interrupt_uart8, + +#ifdef CONFIG_UART8_RS485 + .rs485_dir_gpio = GPIO_UART8_RS485_DIR, +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +static struct up_dev_s * const uart_devs[STM32_NSERIAL] = +{ +#ifdef CONFIG_STM32F7_USART1 + [0] = &g_usart1priv, +#endif +#ifdef CONFIG_STM32F7_USART2 + [1] = &g_usart2priv, +#endif +#ifdef CONFIG_STM32F7_USART3 + [2] = &g_usart3priv, +#endif +#ifdef CONFIG_STM32F7_UART4 + [3] = &g_uart4priv, +#endif +#ifdef CONFIG_STM32F7_UART5 + [4] = &g_uart5priv, +#endif +#ifdef CONFIG_STM32F7_USART6 + [5] = &g_usart6priv, +#endif +#ifdef CONFIG_STM32F7_UART7 + [6] = &g_uart7priv, +#endif +#ifdef CONFIG_STM32F7_UART8 + [7] = &g_uart8priv, +#endif +}; + +#ifdef CONFIG_PM +static struct pm_callback_s g_serialcb = +{ + .notify = up_pm_notify, + .prepare = up_pm_prepare, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) +{ + uint32_t cr; + + /* Save the interrupt mask */ + + priv->ie = ie; + + /* And restore the interrupt state (see the interrupt enable/usage table above) */ + + cr = up_serialin(priv, STM32_USART_CR1_OFFSET); + cr &= ~(USART_CR1_USED_INTS); + cr |= (ie & (USART_CR1_USED_INTS)); + up_serialout(priv, STM32_USART_CR1_OFFSET, cr); + + cr = up_serialin(priv, STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_EIE; + cr |= (ie & USART_CR3_EIE); + up_serialout(priv, STM32_USART_CR3_OFFSET, cr); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) +{ + if (ie) + { + uint32_t cr1; + uint32_t cr3; + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------ ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Error + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); + cr3 = up_serialin(priv, STM32_USART_CR3_OFFSET); + + /* Return the current interrupt mask value for the used interrupts. Notice + * that this depends on the fact that none of the used interrupt enable bits + * overlap. This logic would fail if we needed the break interrupt! + */ + + *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); + } + + /* Disable all interrupts */ + + up_restoreusartint(priv, 0); +} + +/**************************************************************************** + * Name: up_dma_nextrx + * + * Description: + * Returns the index into the RX FIFO where the DMA will place the next + * byte that it receives. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_nextrx(struct up_dev_s *priv) +{ + size_t dmaresidual; + + dmaresidual = stm32_dmaresidual(priv->rxdma); + + return (RXDMA_BUFFER_SIZE - (int)dmaresidual); +} +#endif + +/**************************************************************************** + * Name: up_set_format + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void up_set_format(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + uint32_t usartdiv8; + uint32_t cr1; + uint32_t brr; + + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ + + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = 2 * usartdiv8 + */ + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + + cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); + if (usartdiv8 > 100) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); + up_serialout(priv, STM32_USART_BRR_OFFSET, brr); + + /* Configure parity mode */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + /* Configure word length (Default: 8-bits) */ + + if (priv->bits == 7) + { + regval |= USART_CR1_M1; + } + else if (priv->bits == 9) + { + regval |= USART_CR1_M0; + } + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = up_serialin(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32F7_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); +} +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Name: up_set_apb_clock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void up_set_apb_clock(struct uart_dev_s *dev, bool on) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32F7_USART1 + case STM32_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32F7_USART2 + case STM32_USART2_BASE: + rcc_en = RCC_APB1ENR_USART2EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32F7_USART3 + case STM32_USART3_BASE: + rcc_en = RCC_APB1ENR_USART3EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32F7_UART4 + case STM32_UART4_BASE: + rcc_en = RCC_APB1ENR_UART4EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32F7_UART5 + case STM32_UART5_BASE: + rcc_en = RCC_APB1ENR_UART5EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32F7_USART6 + case STM32_USART6_BASE: + rcc_en = RCC_APB2ENR_USART6EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32F7_UART7 + case STM32_UART7_BASE: + rcc_en = RCC_APB1ENR_UART7EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32F7_UART8 + case STM32_UART8_BASE: + rcc_en = RCC_APB1ENR_UART8EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled in stm32_lowsetup(). + */ + + /* Enable USART APB1/2 clock */ + + up_set_apb_clock(dev, true); + + /* Configure pins for USART use */ + + stm32_configgpio(priv->tx_gpio); + stm32_configgpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_configgpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32F7_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32_configgpio(config); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_configgpio(priv->rs485_dir_gpio); + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + } +#endif + + /* Configure CR2 */ + /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + + /* Configure STOP bits */ + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure CR1 */ + /* Clear TE, REm and all interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure CR3 */ + /* Clear CTSE, RTSE, and all interrupt enable bits */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE); + + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); + + /* Configure the USART line format and speed. */ + + up_set_format(dev); + + /* Enable Rx, Tx, and the USART */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + + /* Set up the cached interrupt enables value */ + + priv->ie = 0; + return OK; +} + +/**************************************************************************** + * Name: up_dma_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int result; + uint32_t regval; + + /* Do the basic UART setup first, unless we are the console */ + + if (!dev->isconsole) + { + result = up_setup(dev); + if (result != OK) + { + return result; + } + } + + /* Acquire the DMA channel. This should always succeed. */ + + priv->rxdma = stm32_dmachannel(priv->rxdma_channel); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmaout = 0; + priv->rxdmain = 0; + + /* Enable receive DMA for the UART */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval |= USART_CR3_DMAR; + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Disable all interrupts */ + + up_disableusartint(priv, NULL); + + /* Disable USART APB1/2 clock */ + + up_set_apb_clock(dev, false); + + /* Disable Rx, Tx, and the UART */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Release pins. "If the serial-attached device is powered down, the TX + * pin causes back-powering, potentially confusing the device to the point + * of complete lock-up." + * + * REVISIT: Is unconfiguring the pins appropriate for all device? If not, + * then this may need to be a configuration option. + */ + + stm32_unconfiggpio(priv->tx_gpio); + stm32_unconfiggpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_unconfiggpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + stm32_unconfiggpio(priv->rts_gpio); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_unconfiggpio(priv->rs485_dir_gpio); + } +#endif +} + +/**************************************************************************** + * Name: up_dma_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Perform the normal UART shutdown */ + + up_shutdown(dev); + + /* Stop the DMA channel */ + + stm32_dmastop(priv->rxdma); + + /* Release the DMA channel */ + + stm32_dmafree(priv->rxdma); + priv->rxdma = NULL; +} +#endif + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->vector); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt_common + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt_common(struct up_dev_s *priv) +{ + int passes; + bool handled; + + /* Report serial activity to the power management logic */ + +#if defined(CONFIG_PM) && CONFIG_PM_SERIAL_ACTIVITY > 0 + pm_activity(PM_IDLE_DOMAIN, CONFIG_PM_SERIAL_ACTIVITY); +#endif + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked USART status word. */ + + priv->sr = up_serialin(priv, STM32_USART_ISR_OFFSET); + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Error + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + * + * NOTE: Some of these status bits must be cleared by explicitly writing zero + * to the SR register: USART_ISR_CTS, USART_ISR_LBD. Note of those are currently + * being used. + */ + +#ifdef HAVE_RS485 + /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. + * Note - this should be first, to have the most recent TC bit value from + * SR register - sending data affects TC, but without refresh we will not + * know that... + */ + + if ((priv->sr & USART_ISR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && + (priv->ie & USART_CR1_TXEIE) == 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); + } +#endif + + /* Handle incoming, receive bytes. */ + + if ((priv->sr & USART_ISR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0) + { + /* Received data ready... process incoming bytes. NOTE the check for + * RXNEIE: We cannot call uart_recvchards of RX interrupts are disabled. + */ + + uart_recvchars(&priv->dev); + handled = true; + } + + /* We may still have to read from the DR register to clear any pending + * error conditions. + */ + + else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) + { + /* These errors are cleared by writing the corresponding bit to the + * interrupt clear register (ICR). + */ + + up_serialout(priv, STM32_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF)); + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & USART_ISR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(&priv->dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif +#ifdef CONFIG_SERIAL_TERMIOS + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_STM32F7_USART_SINGLEWIRE + case TIOCSSINGLEWIRE: + { + /* Change the TX port to be open-drain/push-pull and enable/disable + * half-duplex mode. + */ + + uint32_t cr = up_serialin(priv, STM32_USART_CR3_OFFSET); + + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + cr |= USART_CR3_HDSEL; + } + else + { + stm32_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + cr &= ~USART_CR3_HDSEL; + } + + up_serialout(priv, STM32_USART_CR3_OFFSET, cr); + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + up_set_format(dev); + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + +#ifdef CONFIG_USART_BREAKS + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + uint32_t cr2 = up_serialin(priv, STM32_USART_CR2_OFFSET); + up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + uint32_t cr1 = up_serialin(priv, STM32_USART_CR2_OFFSET); + up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rdr; + + /* Get the Rx byte */ + + rdr = up_serialin(priv, STM32_USART_RDR_OFFSET); + + /* Get the Rx byte plux error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint16_t ie; + + /* USART receive interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Error + * " " USART_ISR_ORE Overrun Error Detected + */ + + flags = enter_critical_section(); + ie = priv->ie; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_USART_ERRINTS + ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); +#else + ie |= USART_CR1_RXNEIE; +#endif +#endif + } + else + { + ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); + } + + /* Then set the new interrupt state */ + + up_restoreusartint(priv, ie); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32_USART_ISR_OFFSET) & USART_ISR_RXNE) != 0); +} +#endif + +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32F7_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32_gpiowrite(priv->rts_gpio, upper); + return upper; + } + +#else + if (priv->iflow) + { + /* Is the RX buffer full? */ + + if (upper) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral. When hardware RTS is enabled, this will + * prevent more data from coming in. + * + * This function is only called when UART recv buffer is full, + * that is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts + * when buffer is read empty and thus we do not have to re- + * enable Rx interrupts. + */ + + uart_disablerxint(dev); + return true; + } + + /* No.. The RX buffer is empty */ + + else + { + /* We might leave Rx interrupt disabled if full recv buffer was + * read empty. Enable Rx interrupt to make sure that more input is + * received. + */ + + uart_enablerxint(dev); + } + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: up_dma_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rxdmain; + int c = 0; + + /* If additional bytes have been added to the DMA buffer, then we will need + * to invalidate the DMA buffer before reading the byte. + */ + + rxdmain = up_dma_nextrx(priv); + if (rxdmain != priv->rxdmain) + { + /* Invalidate the DMA buffer */ + + arch_invalidate_dcache((uintptr_t)priv->rxfifo, + (uintptr_t)priv->rxfifo + RXDMA_BUFFER_SIZE - 1); + + /* Since DMA is ongoing, there are lots of race conditions here. We + * just have to hope that the rxdmaout stays well ahead of rxdmain. + */ + + priv->rxdmain = rxdmain; + } + + /* Now check if there are any bytes to read from the DMA buffer */ + + if (rxdmain != priv->rxdmaout) + { + c = priv->rxfifo[priv->rxdmaout]; + + priv->rxdmaout++; + if (priv->rxdmaout == RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* RX DMA buffer full. RX paused, RTS line pulled up to prevent + * more input data from other end. + */ + } + else +#endif + { + priv->rxdmaout = 0; + } + } + } + + return c; +} +#endif + +/**************************************************************************** + * Name: up_dma_reenable + * + * Description: + * Call to re-enable RX DMA. + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) +static void up_dma_reenable(struct up_dev_s *priv) +{ + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + + /* Reset our DMA shadow pointer to match the address just programmed + * above. + */ + + priv->rxdmaout = 0; + priv->rxdmain = 0; + + /* Start the DMA channel, and arrange for callbacks at the full point in + * the FIFO. After buffer gets full, hardware flow-control kicks in and + * DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* En/disable DMA reception. + * + * Note that it is not safe to check for available bytes and immediately + * pass them to uart_recvchars as that could potentially recurse back + * to us again. Instead, bytes must wait until the next up_dma_poll or + * DMA event. + */ + + priv->rxenable = enable; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && (priv->rxdmaout == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif +} +#endif + +/**************************************************************************** + * Name: up_dma_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static bool up_dma_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Compare our receive pointer to the current DMA pointer, if they + * do not match, then there are bytes to be received. + */ + + return (up_dma_nextrx(priv) != priv->rxdmaout); +} +#endif + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + } +#endif + + up_serialout(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ---------------------------- ---------- + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uint16_t ie = priv->ie | USART_CR1_TXEIE; + + /* If RS-485 is supported on this U[S]ART, then also enable the + * transmission complete interrupt. + */ + +# ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + ie |= USART_CR1_TCIE; + } +# endif + + up_restoreusartint(priv, ie); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32_USART_ISR_OFFSET) & USART_ISR_TXE) != 0); +} + +/**************************************************************************** + * Name: up_interrupt_u[s]art[n] + * + * Description: + * Interrupt handlers for U[S]ART[n] where n=1,..,6. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32F7_USART1 +static int up_interrupt_usart1(int irq, void *context) +{ + return up_interrupt_common(&g_usart1priv); +} +#endif + +#ifdef CONFIG_STM32F7_USART2 +static int up_interrupt_usart2(int irq, void *context) +{ + return up_interrupt_common(&g_usart2priv); +} +#endif + +#ifdef CONFIG_STM32F7_USART3 +static int up_interrupt_usart3(int irq, void *context) +{ + return up_interrupt_common(&g_usart3priv); +} +#endif + +#ifdef CONFIG_STM32F7_UART4 +static int up_interrupt_uart4(int irq, void *context) +{ + return up_interrupt_common(&g_uart4priv); +} +#endif + +#ifdef CONFIG_STM32F7_UART5 +static int up_interrupt_uart5(int irq, void *context) +{ + return up_interrupt_common(&g_uart5priv); +} +#endif + +#ifdef CONFIG_STM32F7_USART6 +static int up_interrupt_usart6(int irq, void *context) +{ + return up_interrupt_common(&g_usart6priv); +} +#endif + +#ifdef CONFIG_STM32F7_UART7 +static int up_interrupt_uart7(int irq, void *context) +{ + return up_interrupt_common(&g_uart7priv); +} +#endif + +#ifdef CONFIG_STM32F7_UART8 +static int up_interrupt_uart8(int irq, void *context) +{ + return up_interrupt_common(&g_uart8priv); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxcallback + * + * Description: + * This function checks the current DMA state and calls the generic + * serial stack when bytes appear to be available. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = (struct up_dev_s *)arg; + + if (priv->rxenable && up_dma_rxavailable(&priv->dev)) + { + uart_recvchars(&priv->dev); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && + (priv->rxdmaout == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif + } +} +#endif + +/**************************************************************************** + * Name: up_pm_notify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * None - The driver already agreed to transition to the low power + * consumption state when when it returned OK to the prepare() call. + * + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + switch (pmstate) + { + case(PM_NORMAL): + { + /* Logic for PM_NORMAL goes here */ + + } + break; + + case(PM_IDLE): + { + /* Logic for PM_IDLE goes here */ + + } + break; + + case(PM_STANDBY): + { + /* Logic for PM_STANDBY goes here */ + + } + break; + + case(PM_SLEEP): + { + /* Logic for PM_SLEEP goes here */ + + } + break; + + default: + /* Should not get here */ + break; + } +} +#endif + +/**************************************************************************** + * Name: up_pm_prepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * Zero - (OK) means the event was successfully processed and that the + * driver is prepared for the PM state change. + * + * Non-zero - means that the driver is not prepared to perform the tasks + * needed achieve this power setting and will cause the state + * change to be aborted. NOTE: The prepare() method will also + * be called when reverting from lower back to higher power + * consumption modes (say because another driver refused a + * lower power state change). Drivers are not permitted to + * return non-zero values when reverting back to higher power + * consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + /* Logic to prepare for a reduced power state goes here. */ + + return OK; +} +#endif +#endif /* HAVE_UART */ +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ +#ifdef HAVE_UART + unsigned i; + + /* Disable all USART interrupts */ + + for (i = 0; i < STM32_NSERIAL; i++) + { + if (uart_devs[i]) + { + up_disableusartint(uart_devs[i], NULL); + } + } + + /* Configure whichever one is the console */ + +#if CONSOLE_UART > 0 + up_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* HAVE UART */ +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef HAVE_UART + char devname[16]; + unsigned i; + unsigned minor = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Register to receive power management callbacks */ + +#ifdef CONFIG_PM + ret = pm_register(&g_serialcb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + /* Register the console */ + +#if CONSOLE_UART > 0 + (void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + (void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#ifdef SERIAL_HAVE_CONSOLE_DMA + /* If we need to re-initialise the console to enable DMA do that here. */ + + up_dma_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strcpy(devname, "/dev/ttySx"); + + for (i = 0; i < STM32_NSERIAL; i++) + { + /* Don't create a device for non-configured ports. */ + + if (uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* Don't create a device for the console - we did that above */ + + if (uart_devs[i]->dev.isconsole) + { + continue; + } +#endif + + /* Register USARTs as devices in increasing order */ + + devname[9] = '0' + minor++; + (void)uart_register(devname, &uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: stm32_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_USART1_RXDMA + if (g_usart1priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); + } +#endif + +#ifdef CONFIG_USART2_RXDMA + if (g_usart2priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); + } +#endif + +#ifdef CONFIG_USART3_RXDMA + if (g_usart3priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); + } +#endif + +#ifdef CONFIG_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); + } +#endif + +#ifdef CONFIG_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); + } +#endif + +#ifdef CONFIG_USART6_RXDMA + if (g_usart6priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart6priv.rxdma, 0, &g_usart6priv); + } +#endif + +#ifdef CONFIG_UART7_RXDMA + if (g_uart7priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart7priv.rxdma, 0, &g_uart7priv); + } +#endif + +#ifdef CONFIG_UART8_RXDMA + if (g_uart8priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart8priv.rxdma, 0, &g_uart8priv); + } +#endif + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct up_dev_s *priv = uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + up_disableusartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreusartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32f7/stm32_start.c b/arch/arm/src/stm32f7/stm32_start.c new file mode 100644 index 0000000000000000000000000000000000000000..b4f935a3978350f108ce23e8cabd0fed79811a5d --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_start.c @@ -0,0 +1,405 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_start.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "cache.h" +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +#include "stm32_rcc.h" +#include "stm32_userspace.h" +#include "stm32_lowputc.h" +#include "stm32_start.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Memory Map ***************************************************************/ +/* + * 0x0400:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x041f:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x2000:0000 - Start of internal SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2005:ffff - End of internal SRAM and end of heap (a + */ + +#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void stm32_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: stm32_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define stm32_fpuconfig() +#endif + +/**************************************************************************** + * Name: stm32_tcmenable + * + * Description: + * Enable/disable tightly coupled memories. Size of tightly coupled + * memory regions is controlled by GPNVM Bits 7-8. + * + ****************************************************************************/ + +static inline void stm32_tcmenable(void) +{ + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Enabled/disabled ITCM */ + +#ifdef CONFIG_ARMV7M_ITCM + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_ITCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_ITCMCR); + + /* Enabled/disabled DTCM */ + +#ifdef CONFIG_ARMV7M_DTCM + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_DTCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_DTCMCR); + + ARM_DSB(); + ARM_ISB(); + +#ifdef CONFIG_ARMV7M_ITCM + /* Copy TCM code from flash to ITCM */ + +#warning Missing logic +#endif +} + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is geive by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs. This should be done before stm32_clockconfig() is + * called (in case it has some dependency on initialized C variables). + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + stm32_clockconfig(); + stm32_fpuconfig(); + stm32_lowsetup(); + + /* Enable/disable tightly coupled memories */ + + stm32_tcmenable(); + + /* Initialize onboard resources */ + + stm32_boardinitialize(); + + /* Enable I- and D-Caches */ + + arch_dcache_writethrough(); + arch_enable_icache(); + arch_enable_dcache(); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segements. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stm32_userspace(); +#endif + + /* Then start NuttX */ + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/stm32f7/stm32_start.h b/arch/arm/src/stm32f7/stm32_start.h new file mode 100644 index 0000000000000000000000000000000000000000..fb401968387924ecf0522a28403becea223bec5f --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_start.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_start.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMV7_SAM_START_H +#define __ARCH_ARM_SRC_SAMV7_SAM_START_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the linker + * script. _ebss lies at the end of the BSS region. The idle task stack starts at + * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is + * the thread that the system boots on and, eventually, becomes the IDLE, do + * nothing task that runs only when there is nothing else to run. The heap + * continues from there until the end of memory. g_idle_topstack is a read-only + * variable the provides this computed address. + */ + +EXTERN const uintptr_t g_idle_topstack; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All SAMV7 architectures must provide the following entry point. This entry + * point is called early in the initialization -- after clocking and memory have + * been configured but before caches have been enabled and before any devices have + * been initialized. + * + ************************************************************************************/ + +void stm32_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMV7_SAM_START_H */ diff --git a/arch/arm/src/stm32f7/stm32_timerisr.c b/arch/arm/src/stm32f7/stm32_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..db9c685cdf4be9d9bb2889cdd0f1550459270626 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_timerisr.c @@ -0,0 +1,160 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select MCU-specific settings + * + * The RCC feeds the external clock of the Cortex System Timer (SysTick) with + * the AHB clock (HCLK) divided by 8. The SysTick can work either with this + * clock or with the Cortex clock (HCLK), configurable in the SysTick control + * and status register. + * + * The SysTick calibration value is fixed to 18750, which gives a reference + * time base of 1 ms with the SysTick clock set to 18.75 MHz (HCLK/8, with + * HCLK set to 150 MHz). + */ + +#define STM32_SYSTICK_CLOCK (STM32_BOARD_HCLK / 8) + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * For example, suppose HCLK = 216 MHz and CLK_TCK = 100, then: + * + * STM32_SYSTICK_CLOCK = 216 MHz / 8 = 27 MHz + * SYSTICK_RELOAD = (27,000,000 / 100) - 1 = 269,999 + */ + +#define SYSTICK_RELOAD ((STM32_SYSTICK_CLOCK / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + putreg32(0, NVIC_SYSTICK_CURRENT); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STM32_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts: + * + * NVIC_SYSTICK_CTRL_CLKSOURCE=0 : Use the implementation defined clock + * source which, for the STM32F7, will be + * HCLK/8 + * NVIC_SYSTICK_CTRL_TICKINT=1 : Generate interrupts + * NVIC_SYSTICK_CTRL_ENABLE : Enable the counter + */ + + regval = (NVIC_SYSTICK_CTRL_TICKINT | NVIC_SYSTICK_CTRL_ENABLE); + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(STM32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/stm32f7/stm32_uart.h b/arch/arm/src/stm32f7/stm32_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..9b1bce0b4e6d8761eb3c493cc4c1ebc9928642e8 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_uart.h @@ -0,0 +1,345 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_uart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32F7_STM32_UART_H +#define __ARCH_ARM_STC_STM32F7_STM32_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip/stm32_uart.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Make sure that we have not enabled more U[S]ARTs than are supported by the + * device. + */ + +#if STM32F7_NUART < 4 +# undef CONFIG_STM32F7_UART8 +#endif +#if STM32F7_NUART < 3 +# undef CONFIG_STM32F7_UART7 +#endif +#if STM32F7_NUART < 2 +# undef CONFIG_STM32F7_UART5 +#endif +#if STM32F7_NUART < 1 +# undef CONFIG_STM32F7_UART4 +#endif + +#if STM32F7_NUSART < 4 +# undef CONFIG_STM32F7_USART6 +#endif +#if STM32F7_NUSART < 3 +# undef CONFIG_STM32F7_USART3 +#endif +#if STM32F7_NUSART < 2 +# undef CONFIG_STM32F7_USART2 +#endif +#if STM32F7_NUSART < 1 +# undef CONFIG_STM32F7_USART1 +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32F7_USART1) || defined(CONFIG_STM32F7_USART2) || \ + defined(CONFIG_STM32F7_USART3) || defined(CONFIG_STM32F7_UART4) || \ + defined(CONFIG_STM32F7_UART5) || defined(CONFIG_STM32F7_USART6) || \ + defined(CONFIG_STM32F7_UART7) || defined(CONFIG_STM32F7_UART8) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART1) +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART2) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART3) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART4) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART5) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_USART6) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 6 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART7) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 7 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_STM32F7_UART8) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define CONSOLE_UART 8 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration */ + +#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_UART4_RXDMA +# undef CONFIG_UART5_RXDMA +# undef CONFIG_USART6_RXDMA +# undef CONFIG_UART7_RXDMA +# undef CONFIG_UART8_RXDMA +#endif + +/* Disable the DMA configuration on all unused USARTs */ + +#ifndef CONFIG_STM32F7_USART1 +# undef CONFIG_USART1_RXDMA +#endif + +#ifndef CONFIG_STM32F7_USART2 +# undef CONFIG_USART2_RXDMA +#endif + +#ifndef CONFIG_STM32F7_USART3 +# undef CONFIG_USART3_RXDMA +#endif + +#ifndef CONFIG_STM32F7_UART4 +# undef CONFIG_UART4_RXDMA +#endif + +#ifndef CONFIG_STM32F7_UART5 +# undef CONFIG_UART5_RXDMA +#endif + +#ifndef CONFIG_STM32F7_USART6 +# undef CONFIG_USART6_RXDMA +#endif + +#ifndef CONFIG_STM32F7_UART7 +# undef CONFIG_UART7_RXDMA +#endif + +#ifndef CONFIG_STM32F7_UART8 +# undef CONFIG_UART8_RXDMA +#endif + +/* Is DMA available on any (enabled) USART? */ + +#undef SERIAL_HAVE_DMA +#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) || defined(CONFIG_UART4_RXDMA) || \ + defined(CONFIG_UART5_RXDMA) || defined(CONFIG_USART6_RXDMA) || \ + defined(CONFIG_UART7_RXDMA) || defined(CONFIG_UART8_RXDMA) +# define SERIAL_HAVE_DMA 1 +#endif + +/* Is DMA used on the console UART? */ + +#undef SERIAL_HAVE_CONSOLE_DMA +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#endif + +/* Is DMA used on all (enabled) USARTs */ + +#define SERIAL_HAVE_ONLY_DMA 1 +#if defined(CONFIG_STM32F7_USART1) && !defined(CONFIG_USART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_USART2) && !defined(CONFIG_USART2_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_USART3) && !defined(CONFIG_USART3_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_UART4) && !defined(CONFIG_UART4_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_UART5) && !defined(CONFIG_UART5_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_USART6) && !defined(CONFIG_USART6_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_UART7) && !defined(CONFIG_UART7_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32F7_UART8) && !defined(CONFIG_UART8_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#endif + +/* Is RS-485 used? */ + +#if defined(CONFIG_USART1_RS485) || defined(CONFIG_USART2_RS485) || \ + defined(CONFIG_USART3_RS485) || defined(CONFIG_UART4_RS485) || \ + defined(CONFIG_UART5_RS485) || defined(CONFIG_USART6_RS485) || \ + defined(CONFIG_UART7_RS485) || defined(CONFIG_UART8_RS485) +# define HAVE_RS485 1 +#endif + +#ifdef HAVE_RS485 +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) +#else +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_serial_dma_poll + * + * Description: + * Must be called periodically if any STM32 UART is configured for DMA. The DMA + * callback is triggered for each FIFO size/2 bytes, but this can result in some + * bytes being transferred but not collected if the incoming data is not a whole + * multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ************************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32F7_STM32_UART_H */ diff --git a/arch/arm/src/stm32f7/stm32_userspace.c b/arch/arm/src/stm32f7/stm32_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..8185db83b5199aa6492d3d7a825f1f5d8b7adba0 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_userspace.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_userspace.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "stm32_mpuinit.h" +#include "stm32_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void stm32_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + stm32_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/stm32f7/stm32_userspace.h b/arch/arm/src/stm32f7/stm32_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..c331a408ed5f61b261661c6ed0a7d940dc1abb28 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_userspace.h @@ -0,0 +1,105 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_userspace.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_USERSPACE_H +#define __ARCH_ARM_SRC_STM32F7_STM32_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_userspace(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_USERSPACE_H */ diff --git a/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c b/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..1db43d255132f7e258e8c20db5607bc91235c175 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c @@ -0,0 +1,890 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32f74xxx75xx_rcc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "stm32_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/* Same for HSI */ + +#define HSIRDY_TIMEOUT HSERDY_TIMEOUT + +/* HSE divisor to yield ~1MHz RTC clock */ + +#define HSE_DIVISOR (STM32_HSE_FREQUENCY + 500000) / 1000000 + +/* FLASH wait states */ + +#if !defined(BOARD_FLASH_WAITSTATES) +# error BOARD_FLASH_WAITSTATES not defined +#elif BOARD_FLASH_WAITSTATES < 0 || BOARD_FLASH_WAITSTATES > 15 +# error BOARD_FLASH_WAITSTATES is out of range +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Reset the RCC clock configuration to the default reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Enable the Internal High Speed clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; + putreg32(regval, STM32_RCC_CR); + + /* Reset CFGR register */ + + putreg32(0x00000000, STM32_RCC_CFGR); + + /* Reset HSION, HSEON, CSSON and PLLON bits */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32_RCC_CR); + + /* Reset PLLCFGR register to reset default */ + + putreg32(RCC_PLLCFG_RESET, STM32_RCC_PLLCFG); + + /* Reset HSEBYP bit */ + + regval = getreg32(STM32_RCC_CR); + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32_RCC_CR); + + /* Disable all interrupts */ + + putreg32(0x00000000, STM32_RCC_CIR); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB1ENR); + + /* Enable GPIOA, GPIOB, .... GPIOI */ + +#if STM32F7_NGPIO > 0 + regval |= (RCC_AHB1ENR_GPIOAEN +#if STM32F7_NGPIO > 1 + | RCC_AHB1ENR_GPIOBEN +#endif +#if STM32F7_NGPIO > 2 + | RCC_AHB1ENR_GPIOCEN +#endif +#if STM32F7_NGPIO > 3 + | RCC_AHB1ENR_GPIODEN +#endif +#if STM32F7_NGPIO > 4 + | RCC_AHB1ENR_GPIOEEN +#endif +#if STM32F7_NGPIO > 5 + | RCC_AHB1ENR_GPIOFEN +#endif +#if STM32F7_NGPIO > 6 + | RCC_AHB1ENR_GPIOGEN +#endif +#if STM32F7_NGPIO > 7 + | RCC_AHB1ENR_GPIOHEN +#endif +#if STM32F7_NGPIO > 8 + | RCC_AHB1ENR_GPIOIEN +#endif +#if STM32F7_NGPIO > 9 + | RCC_AHB1ENR_GPIOJEN +#endif +#if STM32F7_NGPIO > 10 + | RCC_AHB1ENR_GPIOKEN +#endif + ); +#endif + +#ifdef CONFIG_STM32F7_CRC + /* CRC clock enable */ + + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32F7_BKPSRAM + /* Backup SRAM clock enable */ + + regval |= RCC_AHB1ENR_BKPSRAMEN; +#endif + +#ifdef CONFIG_ARMV7M_DTCM + /* DTCM data RAM clock enable */ + + regval |= RCC_AHB1ENR_DTCMRAMEN; +#endif + +#ifdef CONFIG_STM32F7_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHB1ENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32F7_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHB1ENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32F7_DMA2D + /* DMA2D clock */ + + regval |= RCC_AHB1ENR_DMA2DEN; +#endif + +#ifdef CONFIG_STM32F7_ETHMAC + /* Ethernet MAC clocking */ + + regval |= (RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | \ + RCC_AHB1ENR_ETHMACRXEN); + +#ifdef CONFIG_STM32F7_ETH_PTP + /* Precision Time Protocol (PTP) */ + + regval |= RCC_AHB1ENR_ETHMACPTPEN; + +#endif +#endif + +#ifdef CONFIG_STM32F7_OTGHS + /* USB OTG HS */ + + regval |= RCC_AHB1ENR_OTGHSEN; + +#endif /* CONFIG_STM32F7_OTGHS */ + + putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR register to enabled the + * selected AHB2 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB2ENR); + +#ifdef CONFIG_STM32F7_DCMI + /* Camera interface enable */ + + regval |= RCC_AHB2ENR_DCMIEN; +#endif + +#ifdef CONFIG_STM32F7_CRYP + /* Cryptographic modules clock enable */ + + regval |= RCC_AHB2ENR_CRYPEN; +#endif + +#ifdef CONFIG_STM32F7_HASH + /* Hash modules clock enable */ + + regval |= RCC_AHB2ENR_HASHEN; +#endif + +#ifdef CONFIG_STM32F7_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHB2ENR_RNGEN; +#endif + +#ifdef CONFIG_STM32F7_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHB2ENR_OTGFSEN; +#endif + + putreg32(regval, STM32_RCC_AHB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the + * selected AHB3 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB3ENR); + +#ifdef CONFIG_STM32F7_FSMC + /* Flexible static memory controller module clock enable */ + + regval |= RCC_AHB3ENR_FSMCEN; +#endif + +#ifdef CONFIG_STM32F7_QUADSPI + /* FQuad SPI memory controller clock enable */ + + regval |= RCC_AHB3ENR_QSPIEN; +#endif + + putreg32(regval, STM32_RCC_AHB3ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32F7_TIM2 + /* TIM2 clock enable */ + + regval |= RCC_APB1ENR_TIM2EN; +#endif + +#ifdef CONFIG_STM32F7_TIM3 + /* TIM3 clock enable */ + + regval |= RCC_APB1ENR_TIM3EN; +#endif + +#ifdef CONFIG_STM32F7_TIM4 + /* TIM4 clock enable */ + + regval |= RCC_APB1ENR_TIM4EN; +#endif + +#ifdef CONFIG_STM32F7_TIM5 + /* TIM5 clock enable */ + + regval |= RCC_APB1ENR_TIM5EN; +#endif + +#ifdef CONFIG_STM32F7_TIM6 + /* TIM6 clock enable */ + + regval |= RCC_APB1ENR_TIM6EN; +#endif + +#ifdef CONFIG_STM32F7_TIM7 + /* TIM7 clock enable */ + + regval |= RCC_APB1ENR_TIM7EN; +#endif + +#ifdef CONFIG_STM32F7_TIM12 + /* TIM12 clock enable */ + + regval |= RCC_APB1ENR_TIM12EN; +#endif + +#ifdef CONFIG_STM32F7_TIM13 + /* TIM13 clock enable */ + + regval |= RCC_APB1ENR_TIM13EN; +#endif + +#ifdef CONFIG_STM32F7_TIM14 + /* TIM14 clock enable */ + + regval |= RCC_APB1ENR_TIM14EN; +#endif + +#ifdef CONFIG_STM32F7_LPTIM1 + /* Low-power timer 1 clock enable */ + + regval |= RCC_APB1ENR_LPTIM1EN; +#endif + +#ifdef CONFIG_STM32F7_WWDG + /* Window watchdog clock enable */ + + regval |= RCC_APB1ENR_WWDGEN; +#endif + +#ifdef CONFIG_STM32F7_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32F7_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32F7_SPDIFRX + /* SPDIFRX clock enable */ + + regval |= RCC_APB1ENR_SPDIFRXEN; +#endif + +#ifdef CONFIG_STM32F7_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR_USART2EN; +#endif + +#ifdef CONFIG_STM32F7_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1ENR_USART3EN; +#endif + +#ifdef CONFIG_STM32F7_UART4 + /* UART4 clock enable */ + + regval |= RCC_APB1ENR_UART4EN; +#endif + +#ifdef CONFIG_STM32F7_UART5 + /* UART5 clock enable */ + + regval |= RCC_APB1ENR_UART5EN; +#endif + +#ifdef CONFIG_STM32F7_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1ENR_I2C1EN; +#endif + +#ifdef CONFIG_STM32F7_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1ENR_I2C2EN; +#endif + +#ifdef CONFIG_STM32F7_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1ENR_I2C3EN; +#endif + +#ifdef CONFIG_STM32F7_I2C4 + /* I2C4 clock enable */ + + regval |= RCC_APB1ENR_I2C4EN; +#endif + +#ifdef CONFIG_STM32F7_CAN1 + /* CAN 1 clock enable */ + + regval |= RCC_APB1ENR_CAN1EN; +#endif + +#ifdef CONFIG_STM32F7_CAN2 + /* CAN2 clock enable. NOTE: CAN2 needs CAN1 clock as well. */ + + regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN); +#endif + +#ifdef CONFIG_STM32F7_CEC + /* CEC clock enable. */ + + regval |= RCC_APB1ENR_CECEN; +#endif + + /* Power interface clock enable. The PWR block is always enabled so that + * we can set the internal voltage regulator for maximum performance. + */ + + regval |= RCC_APB1ENR_PWREN; + +#if defined (CONFIG_STM32F7_DAC1) || defined(CONFIG_STM32F7_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR_DACEN; +#endif + +#ifdef CONFIG_STM32F7_UART7 + /* UART7 clock enable */ + + regval |= RCC_APB1ENR_UART7EN; +#endif + +#ifdef CONFIG_STM32F7_UART8 + /* UART8 clock enable */ + + regval |= RCC_APB1ENR_UART8EN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32F7_TIM1 + /* TIM1 clock enable */ + + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32F7_TIM8 + /* TIM8 clock enable */ + + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32F7_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32F7_USART6 + /* USART6 clock enable */ + + regval |= RCC_APB2ENR_USART6EN; +#endif + +#ifdef CONFIG_STM32F7_ADC1 + /* ADC1 clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + +#ifdef CONFIG_STM32F7_ADC2 + /* ADC2 clock enable */ + + regval |= RCC_APB2ENR_ADC2EN; +#endif + +#ifdef CONFIG_STM32F7_ADC3 + /* ADC3 clock enable */ + + regval |= RCC_APB2ENR_ADC3EN; +#endif + +#ifdef CONFIG_STM32F7_SDMMC1 + /* SDIO clock enable */ + + regval |= RCC_APB2ENR_SDMMC1EN; +#endif + +#ifdef CONFIG_STM32F7_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32F7_SPI4 + /* SPI4 clock enable */ + + regval |= RCC_APB2ENR_SPI4EN; +#endif + + /* System configuration controller clock enable */ + + regval |= RCC_APB2ENR_SYSCFGEN; + +#ifdef CONFIG_STM32F7_TIM9 + /* TIM9 clock enable */ + + regval |= RCC_APB2ENR_TIM9EN; +#endif + +#ifdef CONFIG_STM32F7_TIM10 + /* TIM10 clock enable */ + + regval |= RCC_APB2ENR_TIM10EN; +#endif + +#ifdef CONFIG_STM32F7_TIM11 + /* TIM11 clock enable */ + + regval |= RCC_APB2ENR_TIM11EN; +#endif + +#ifdef CONFIG_STM32F7_SPI5 + /* SPI5 clock enable */ + + regval |= RCC_APB2ENR_SPI5EN; +#endif + +#ifdef CONFIG_STM32F7_SPI6 + /* SPI6 clock enable */ + + regval |= RCC_APB2ENR_SPI6EN; +#endif + +#ifdef CONFIG_STM32F7_SAI1 + /* SPI6 clock enable */ + + regval |= RCC_APB2ENR_SAI1EN; +#endif + +#ifdef CONFIG_STM32F7_SAI2 + /* SPI6 clock enable */ + + regval |= RCC_APB2ENR_SAI2EN; +#endif + +#ifdef CONFIG_STM32F7_LTDC + /* LTDC clock enable */ + + regval |= RCC_APB2ENR_LTDCEN; +#endif + + putreg32(regval, STM32_RCC_APB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_STM32F7_CUSTOM_CLOCKCONFIG +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + +#ifdef STM32_BOARD_USEHSI + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; /* Enable HSI */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#else /* if STM32_BOARD_USEHSE */ + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#endif + + /* Check for a timeout. If this timeout occurs, then we are hosed. We + * have no real back-up plan, although the following logic makes it look + * as though we do. + */ + + if (timeout > 0) + { + /* Select regulator voltage output Scale 1 mode to support system + * frequencies up to 216 MHz. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32_RCC_APB1ENR); + + regval = getreg32(STM32_PWR_CR1); + regval &= ~PWR_CR1_VOS_MASK; + regval |= PWR_CR1_VOS_SCALE_1; + putreg32(regval, STM32_PWR_CR1); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#ifdef CONFIG_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the PLL dividers and multipliers to configure the main PLL */ + +#ifdef STM32_BOARD_USEHSI + regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN | STM32_PLLCFG_PLLP | + RCC_PLLCFG_PLLSRC_HSI | STM32_PLLCFG_PLLQ); +#else /* if STM32_BOARD_USEHSE */ + regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN | STM32_PLLCFG_PLLP | + RCC_PLLCFG_PLLSRC_HSE | STM32_PLLCFG_PLLQ); +#endif + putreg32(regval, STM32_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0) + { + } + + /* Enable the Over-drive to extend the clock frequency to 216 Mhz */ + + regval = getreg32(STM32_PWR_CR1); + regval |= PWR_CR1_ODEN; + putreg32(regval, STM32_PWR_CR1); + while ((getreg32(STM32_PWR_CSR1) & PWR_CSR1_ODRDY) == 0) + { + } + + regval = getreg32(STM32_PWR_CR1); + regval |= PWR_CR1_ODSWEN; + putreg32(regval, STM32_PWR_CR1); + while ((getreg32(STM32_PWR_CSR1) & PWR_CSR1_ODSWRDY) == 0) + { + } + + /* Configure FLASH wait states */ + + regval = FLASH_ACR_LATENCY(BOARD_FLASH_WAITSTATES); + +#ifdef CONFIG_STM32F7_FLASH_PREFETCH + /* Enable FLASH prefetch */ + + regval |= FLASH_ACR_PRFTEN; +#endif + +#ifdef CONFIG_ARMV7M_ITCM + /* The Flash memory interface accelerates code execution with a system of + * instruction prefetch and cache lines on ITCM interface (ART + * Acceleratorâ„¢). + */ + + regval |= FLASH_ACR_ARTEN; +#endif + + putreg32(regval, STM32_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) + { + } + +#ifdef CONFIG_STM32F7_LTDC + /* Configure PLLSAI */ + + regval = getreg32(STM32_RCC_PLLSAICFGR); + regval |= (STM32_RCC_PLLSAICFGR_PLLSAIN + | STM32_RCC_PLLSAICFGR_PLLSAIR + | STM32_RCC_PLLSAICFGR_PLLSAIQ); + putreg32(regval, STM32_RCC_PLLSAICFGR); + + regval = getreg32(STM32_RCC_DCKCFGR); + regval |= STM32_RCC_DCKCFGR_PLLSAIDIVR; + putreg32(regval, STM32_RCC_DCKCFGR); + + /* Enable PLLSAI */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLSAION; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLLSAI is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLSAIRDY) == 0) + { + } +#endif + +#if defined(CONFIG_STM32F7_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + */ + + stm32_rcc_enablelse(); +#endif + } +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..92e6209014a21d303869e01cd617a28685bf1f1c --- /dev/null +++ b/arch/arm/src/stm32l4/Kconfig @@ -0,0 +1,678 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_STM32L4 + +comment "STM32L4 Configuration Options" + +choice + prompt "STM32 L4 Chip Selection" + default ARCH_CHIP_STM32L476RG + depends on ARCH_CHIP_STM32L4 + +config ARCH_CHIP_STM32L476RG + bool "STM32L476RG" + select STM32L4_STM32L476XX + select STM32L4_FLASH_1024KB + ---help--- + STM32 L4 Cortex M4, 1024Kb FLASH, 96+32 Kb SRAM + +config ARCH_CHIP_STM32L476RE + bool "STM32L476RE" + select STM32L4_STM32L476XX + select STM32L4_FLASH_512KB + ---help--- + STM32 L4 Cortex M4, 512 FLASH, 96+32 Kb SRAM + +config ARCH_CHIP_STM32L486 + bool "STM32L486xx" + select STM32L4_STM32L486XX + select STM32L4_HAVE_AES + ---help--- + STM32 L4 Cortex M4, AES, 1024Kb FLASH, 96+32 Kb SRAM + +endchoice # STM32 L4 Chip Selection + +# Chip families + +config STM32L4_STM32L476XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +config STM32L4_STM32L486XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + select STM32L4_FLASH_1024KB + +choice + prompt "Embedded FLASH size" + default STM32L4_FLASH_1024KB + +config STM32L4_FLASH_256KB + bool "256 KB" + +config STM32L4_FLASH_512KB + bool "512 KB" + +config STM32L4_FLASH_1024KB + bool "1024 KB" + +endchoice # Embedded FLASH size + +menu "STM32L4 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config STM32L4_HAVE_LTDC + bool + default n + +# These "hidden" settings are the OR of individual peripheral selections +# indicating that the general capabilitiy is required. + +config STM32L4_ADC + bool + default n + +config STM32L4_CAN + bool + default n + +config STM32L4_DAC + bool + default n + +config STM32L4_DMA + bool + default n + +config STM32L4_I2C + bool + default n + +config STM32L4_SAI + bool + default n + +config STM32L4_SPI + bool + default n + +config STM32L4_USART + bool + default n + +config STM32L4_LPTIM + bool + default n + +# These are the peripheral selections proper + +comment "AHB1 Peripherals" + +config STM32L4_DMA1 + bool "DMA1" + default n + select STM32L4_DMA + select ARCH_DMA + +config STM32L4_DMA2 + bool "DMA2" + default n + select STM32L4_DMA + select ARCH_DMA + + +config STM32L4_CRC + bool "CRC" + default n + +config STM32L4_TSC + bool "TSC" + default n + +comment "AHB2 Peripherals" + +config STM32L4_OTGFS + bool "OTG FS" + default n + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32L4_ADC1 + bool "ADC1" + default n + select STM32L4_ADC + +config STM32L4_ADC2 + bool "ADC2" + default n + select STM32L4_ADC + +config STM32L4_ADC3 + bool "ADC3" + default n + select STM32L4_ADC + +config STM32L4_AES + bool "AES" + default n + +config STM32L4_RNG + bool "RNG" + default n + select ARCH_HAVE_RNG + +comment "AHB3 Peripherals" + +config STM32L4_FMC + bool "FMC" + default n + +config STM32L4_QUADSPI + bool "QuadSPI" + default n + +comment "APB1 Peripherals" + +config STM32L4_PWR + bool "PWR" + default n + +config STM32L4_TIM2 + bool "TIM2" + default n + +config STM32L4_TIM3 + bool "TIM3" + default n + +config STM32L4_TIM4 + bool "TIM4" + default n + +config STM32L4_TIM5 + bool "TIM5" + default n + +config STM32L4_TIM6 + bool "TIM6" + default n + +config STM32L4_TIM7 + bool "TIM7" + default n + +config STM32L4_LCD + bool "LCD" + default n + +config STM32L4_SPI2 + bool "SPI2" + default n + select SPI + select STM32L4_SPI + +config STM32L4_SPI3 + bool "SPI3" + default n + select SPI + select STM32L4_SPI + +config STM32L4_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_USART2 + bool "USART2" + default n + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_USART3 + bool "USART3" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART3 + select STM32L4_USART + +config STM32L4_UART4 + bool "UART4" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART4 + select STM32L4_USART + +config STM32L4_UART5 + bool "UART5" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART5 + select STM32L4_USART + +config STM32L4_I2C1 + bool "I2C1" + default n + select STM32L4_I2C + +config STM32L4_I2C2 + bool "I2C2" + default n + select STM32L4_I2C + +config STM32L4_I2C3 + bool "I2C3" + default n + select STM32L4_I2C + +config STM32L4_CAN1 + bool "CAN1" + default n + select CAN + select STM32L4_CAN + +config STM32L4_DAC1 + bool "DAC1" + default n + select STM32L4_DAC + +config STM32L4_DAC2 + bool "DAC2" + default n + select STM32L4_DAC + +config STM32L4_OPAMP + bool "OPAMP" + default n + +config STM32L4_LPTIM1 + bool "LPTIM1" + default n + select STM32L4_LPTIM + +config STM32L4_LPUART1 + bool "LPUART1" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_LPUART1 + +config STM32L4_SWPMI + bool "SWPMI" + default n + +config STM32L4_LPTIM2 + bool "LPTIM2" + default n + select STM32L4_LPTIM + +comment "APB2 Peripherals" + +config STM32L4_SYSCFG + bool "SYSCFG" + default y + +config STM32L4_FIREWALL + bool "FIREWALL" + default y + depends on STM32L4_SYSCFG + +config STM32L4_SDMMC1 + bool "SDMMC1" + default n + select ARCH_HAVE_SDIO + +config STM32L4_TIM1 + bool "TIM1" + default n + +config STM32L4_SPI1 + bool "SPI1" + default n + select SPI + select STM32L4_SPI + +config STM32L4_TIM8 + bool "TIM8" + default n + +config STM32L4_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_TIM15 + bool "TIM15" + default n + +config STM32L4_TIM16 + bool "TIM16" + default n + +config STM32L4_TIM17 + bool "TIM17" + default n + +config STM32L4_SAI1 + bool "SAI1" + default n + select STM32L4_SAI + +config STM32L4_SAI2 + bool "SAI2" + default n + select STM32L4_SAI + +config STM32L4_DFSDM + bool "DFSDM" + default n + +comment "Other Peripherals" + +config STM32L4_BKPSRAM + bool "Enable BKP RAM Domain" + default n + +config STM32L4_IWDG + bool "IWDG" + default n + select WATCHDOG + +config STM32L4_WWDG + bool "WWDG" + default n + select WATCHDOG + +endmenu + +config STM32L4_FLASH_PREFETCH + bool "Enable FLASH Pre-fetch" + default y + ---help--- + Enable FLASH prefetch + +config STM32L4_DISABLE_IDLE_SLEEP_DURING_DEBUG + bool "Disable IDLE Sleep (WFI) in debug mode" + default n + ---help--- + In debug configuration, disables the WFI instruction in the IDLE loop + to prevent the JTAG from disconnecting. With some JTAG debuggers, such + as the ST-LINK2 with OpenOCD, if the ARM is put to sleep via the WFI + instruction, the debugger will disconnect, terminating the debug session. + +config ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG + bool "Custom clock configuration" + default n + ---help--- + Enables special, board-specific STM32 clock configuration. + +choice + prompt "RTC clock source" + default STM32L4_RTC_LSECLOCK + depends on RTC + +config STM32L4_RTC_LSECLOCK + bool "LSE clock" + ---help--- + Drive the RTC with the LSE clock + +config STM32L4_RTC_LSICLOCK + bool "LSI clock" + ---help--- + Drive the RTC with the LSI clock + +config STM32L4_RTC_HSECLOCK + bool "HSE clock" + ---help--- + Drive the RTC with the HSE clock, divided down to 1MHz. + +endchoice + +config STM32L4_SAI1PLL + bool "SAI1PLL" + default n + ---help--- + The STM32L476 has a separate PLL for the SAI1 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32L4_SAI2PLL + bool "SAI2PLL" + default n + ---help--- + The STM32L476 has a separate PLL for the SAI2 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32L4_USART + bool + +menu "U[S]ART Configuration" + depends on STM32L4_USART + +config USART1_RS485 + bool "RS-485 on USART1" + default n + depends on STM32L4_USART1 + ---help--- + Enable RS-485 interface on USART1. Your board config will have to + provide GPIO_USART1_RS485_DIR pin definition. Currently it cannot be + used with USART1_RXDMA. + +config USART1_RS485_DIR_POLARITY + int "USART1 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART1_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART1. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART1_RXDMA + bool "USART1 Rx DMA" + default n + depends on STM32L4_USART1 && ( STM32L4_DMA1 || STM32L4_DMA2 ) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART2_RS485 + bool "RS-485 on USART2" + default n + depends on STM32L4_USART2 + ---help--- + Enable RS-485 interface on USART2. Your board config will have to + provide GPIO_USART2_RS485_DIR pin definition. Currently it cannot be + used with USART2_RXDMA. + +config USART2_RS485_DIR_POLARITY + int "USART2 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART2_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART2. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART2_RXDMA + bool "USART2 Rx DMA" + default n + depends on STM32L4_USART2 && STM32L4_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART3_RS485 + bool "RS-485 on USART3" + default n + depends on STM32L4_USART3 + ---help--- + Enable RS-485 interface on USART3. Your board config will have to + provide GPIO_USART3_RS485_DIR pin definition. Currently it cannot be + used with USART3_RXDMA. + +config USART3_RS485_DIR_POLARITY + int "USART3 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART3_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART3. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART3_RXDMA + bool "USART3 Rx DMA" + default n + depends on STM32L4_USART3 && STM32L4_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART4_RS485 + bool "RS-485 on UART4" + default n + depends on STM32L4_UART4 + ---help--- + Enable RS-485 interface on UART4. Your board config will have to + provide GPIO_UART4_RS485_DIR pin definition. Currently it cannot be + used with UART4_RXDMA. + +config UART4_RS485_DIR_POLARITY + int "UART4 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART4_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART4. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART4_RXDMA + bool "UART4 Rx DMA" + default n + depends on STM32L4_UART4 && STM32L4_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART5_RS485 + bool "RS-485 on UART5" + default n + depends on STM32L4_UART5 + ---help--- + Enable RS-485 interface on UART5. Your board config will have to + provide GPIO_UART5_RS485_DIR pin definition. Currently it cannot be + used with UART5_RXDMA. + +config UART5_RS485_DIR_POLARITY + int "UART5 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART5_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART5. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART5_RXDMA + bool "UART5 Rx DMA" + default n + depends on STM32L4_UART5 && STM32L4_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + depends on STM32L4_USART1 || STM32L4_USART2 || STM32L4_USART3 || STM32L4_UART4 || STM32L4_UART5 + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + console is always on /dev/ttyS0. If more than one UART is in use this + can, however, have the side-effect that all port mappings + (hardware USART1 -> /dev/ttyS0) change if the console is moved to another + UART. This is in particular relevant if a project uses the USB console + in some configs and a serial console in other configs, but does not + want the side effect of having all serial port names change when just + the console is moved from serial to USB. + +config STM32L4_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + depends on STM32L4_USART + default n + ---help--- + Enable UART RTS flow control using Software. Because STM + Current STM32 have broken HW based RTS behavior (they assert + nRTS after every byte received) Enable this setting workaround + this issue by useing software based management of RTS + +endmenu + +menu "SPI Configuration" + depends on STM32L4_SPI + +config STM32L4_SPI_INTERRUPTS + bool "Interrupt driver SPI" + default n + ---help--- + Select to enable interrupt driven SPI support. Non-interrupt-driven, + poll-waiting is recommended if the interrupt rate would be to high in + the interrupt driven case. + +config STM32L4_SPI_DMA + bool "SPI DMA" + default n + ---help--- + Use DMA to improve SPI transfer performance. Cannot be used with STM32L4_SPI_INTERRUPT. + +endmenu + +menu "I2C Configuration" + depends on STM32L4_I2C + +config STM32L4_I2C_DYNTIMEO + bool "Use dynamic timeouts" + default n + depends on STM32L4_I2C + +config STM32L4_I2C_DYNTIMEO_USECPERBYTE + int "Timeout Microseconds per Byte" + default 500 + depends on STM32L4_I2C_DYNTIMEO + +config STM32L4_I2C_DYNTIMEO_STARTSTOP + int "Timeout for Start/Stop (Milliseconds)" + default 1000 + depends on STM32L4_I2C_DYNTIMEO + +config STM32L4_I2CTIMEOSEC + int "Timeout seconds" + default 0 + depends on STM32L4_I2C + +config STM32L4_I2CTIMEOMS + int "Timeout Milliseconds" + default 500 + depends on STM32L4_I2C && !STM32L4_I2C_DYNTIMEO + +config STM32L4_I2CTIMEOTICKS + int "Timeout for Done and Stop (ticks)" + default 500 + depends on STM32L4_I2C && !STM32L4_I2C_DYNTIMEO + +config STM32L4_I2C_DUTY16_9 + bool "Frequency with Tlow/Thigh = 16/9 " + default n + depends on STM32L4_I2C + +endmenu + +endif # ARCH_CHIP_STM32L4 diff --git a/arch/arm/src/stm32l4/Make.defs b/arch/arm/src/stm32l4/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..9353e81c99d2871934ee48f41caeb7f8197b3ee9 --- /dev/null +++ b/arch/arm/src/stm32l4/Make.defs @@ -0,0 +1,159 @@ +############################################################################ +# arch/arm/src/stm32l4/Make.defs +# +# Copyright (C) 2015 Sebastien Lorquet. All rights reserved. +# Author: Sebastien Lorquet +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file. Only common vectors are support so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M4 files (copied from stm32/Make.defs) + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vfork.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Required STM32L4 files + +CHIP_ASRCS = +CHIP_CSRCS = stm32l4_allocateheap.c stm32l4_exti_gpio.c stm32l4_gpio.c +CHIP_CSRCS += stm32l4_idle.c stm32l4_irq.c stm32l4_lowputc.c stm32l4_rcc.c +CHIP_CSRCS += stm32l4_serial.c stm32l4_start.c stm32l4_waste.c +CHIP_CSRCS += stm32l4_spi.c stm32l4_i2c.c stm32l4_lse.c stm32l4_pwr.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += stm32l4_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += stm32l4_userspace.c stm32l4_mpuinit.c +endif + +ifeq ($(CONFIG_ARMV7M_DTCM),y) +CHIP_CSRCS += stm32l4_dtcm.c +ifeq ($(CONFIG_STM32L4_DTCM_PROCFS),y) +CHIP_CSRCS += stm32l4_procfs_dtcm.c +endif +endif + +ifeq ($(CONFIG_STM32L4_DMA),y) +CHIP_CSRCS += stm32l4_dma.c +endif + +ifeq ($(CONFIG_STM32L4_PWR),y) +CHIP_CSRCS += stm32l4_exti_pwr.c +endif + +ifeq ($(CONFIG_RTC),y) +CHIP_CSRCS += stm32l4_rtcc.c +ifeq ($(CONFIG_RTC_ALARM),y) +CHIP_CSRCS += stm32l4_exti_alarm.c +endif +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += stm32l4_rtc_lowerhalf.c +endif +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += stm32l4_dumpgpio.c +endif + +ifeq ($(CONFIG_STM32L4_RNG),y) +CHIP_CSRCS += stm32l4_rng.c +endif diff --git a/arch/arm/src/stm32l4/README.txt b/arch/arm/src/stm32l4/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..bf38fb80ae18dec5ea1963bc4aa337d15b999162 --- /dev/null +++ b/arch/arm/src/stm32l4/README.txt @@ -0,0 +1,60 @@ +This is a port of NuttX to the STM32L4 Family +Used development board is the Nucleo L476RG + +The status is HIGHLY EXPERIMENTAL. + +OSTEST application works, but drivers are not complete. + +Most code is copied and adapted from the STM32 Port. + +TODO list +--------- + +Peripherals with equivalent implementation in STM32 port + +IRQs : OK +GPIO : OK +EXTI : OK, to be tested. +HSI : OK +HSE : To be tested +PLL : Works @ 80 MHz +MSI : TODO +LSE : works, but TODO autotrim of MSI, etc +RCC : All registers defined, peripherals enabled, basic clock working +SYSCTL : All registers defined +USART : Working in normal mode (no DMA, to be tested, code is written) +DMA : Ported from STM32, code written, to be tested +SRAM2 : Should work with enough MM regions +FIREWALL : Code written, to be tested, requires support from ldscript +SPI : Code written, to be tested, including DMA +I2C : Registers defined +RTC : works +QSPI : TODO (port from stm32f7) +CAN : TODO +OTGFS : TODO +Timers : TODO +PM : TODO, PWR registers defined +FSMC : TODO +AES : TODO +RNG : works +CRC : TODO (configurable polynomial) +WWDG : TODO +IWDG : TODO +MMCSD : TODO +ADC : TODO +DAC : TODO + +New peripherals with implementation to be written from scratch +These are Low Priority TODO items, unless someone requests or contributes it. + +TSC : TODO (Touch Screen Controller) +SWP : TODO (Single wire protocol master, to connect with NFC enabled SIM cards) +LPUART : TODO (Low power UART working with LSE at low baud rates) +LPTIMER : TODO (Low power TIMER) +OPAMP : TODO (Analog operational amplifier) +COMP : TODO (Analog comparators) +DFSDM : TODO (Digital Filter and Sigma-Delta Modulator) +LCD : TODO (Segment LCD controller) +SAIPLL : works (PLL For Digital Audio interfaces, and other things) +SAI : TODO (Digital Audio interfaces, I2S, SPDIF, etc) + diff --git a/arch/arm/src/stm32l4/chip.h b/arch/arm/src/stm32l4/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..b4caa13eaca13e9093f8379f3b664fe0bca1bf5c --- /dev/null +++ b/arch/arm/src/stm32l4/chip.h @@ -0,0 +1,83 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include +#include "chip/stm32l4_pinmap.h" +#include "chip/stm32l4_memorymap.h" + +/* If the common ARMv7-M vector handling logic is used, then it expects the + * following definition in this file that provides the number of supported external + * interrupts which, for this architecture, is provided in the arch/stm32f7/chip.h + * header file. + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS NR_INTERRUPTS + +/* Cache line sizes (in bytes)for the STM32L4 */ + +#define ARMV7M_DCACHE_LINESIZE 0 /* no cache */ +#define ARMV7M_ICACHE_LINESIZE 0 /* no cache */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_exti.h b/arch/arm/src/stm32l4/chip/stm32l4_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..1fb1628a7a916b29826e6b6ff4da72d6b1406c0b --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_exti.h @@ -0,0 +1,179 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_exti.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32L4_NEXTI1 31 +#define STM32L4_EXTI1_MASK 0xffffffff +#define STM32L4_NEXTI2 8 +#define STM32L4_EXTI2_MASK 0x000000ff + +#define STM32L4_EXTI1_BIT(n) (1 << (n)) +#define STM32L4_EXTI2_BIT(n) (1 << (n)) + +/* Register Offsets *****************************************************************/ + +#define STM32L4_EXTI1_OFFSET 0x0000 /* Offset to EXTI1 registers */ +#define STM32L4_EXTI2_OFFSET 0x0020 /* Offset to EXTI2 registers */ + +#define STM32L4_EXTI_IMR_OFFSET 0x0000 /* Interrupt mask register */ +#define STM32L4_EXTI_EMR_OFFSET 0x0004 /* Event mask register */ +#define STM32L4_EXTI_RTSR_OFFSET 0x0008 /* Rising Trigger selection register */ +#define STM32L4_EXTI_FTSR_OFFSET 0x000c /* Falling Trigger selection register */ +#define STM32L4_EXTI_SWIER_OFFSET 0x0010 /* Software interrupt event register */ +#define STM32L4_EXTI_PR_OFFSET 0x0014 /* Pending register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_EXTI1_BASE (STM32L4_EXTI_BASE+STM32L4_EXTI1_OFFSET) +#define STM32L4_EXTI2_BASE (STM32L4_EXTI_BASE+STM32L4_EXTI2_OFFSET) + +#define STM32L4_EXTI1_IMR (STM32L4_EXTI1_BASE+STM32L4_EXTI_IMR_OFFSET) +#define STM32L4_EXTI1_EMR (STM32L4_EXTI1_BASE+STM32L4_EXTI_EMR_OFFSET) +#define STM32L4_EXTI1_RTSR (STM32L4_EXTI1_BASE+STM32L4_EXTI_RTSR_OFFSET) +#define STM32L4_EXTI1_FTSR (STM32L4_EXTI1_BASE+STM32L4_EXTI_FTSR_OFFSET) +#define STM32L4_EXTI1_SWIER (STM32L4_EXTI1_BASE+STM32L4_EXTI_SWIER_OFFSET) +#define STM32L4_EXTI1_PR (STM32L4_EXTI1_BASE+STM32L4_EXTI_PR_OFFSET) + +#define STM32L4_EXTI2_IMR (STM32L4_EXTI2_BASE+STM32L4_EXTI_IMR_OFFSET) +#define STM32L4_EXTI2_EMR (STM32L4_EXTI2_BASE+STM32L4_EXTI_EMR_OFFSET) +#define STM32L4_EXTI2_RTSR (STM32L4_EXTI2_BASE+STM32L4_EXTI_RTSR_OFFSET) +#define STM32L4_EXTI2_FTSR (STM32L4_EXTI2_BASE+STM32L4_EXTI_FTSR_OFFSET) +#define STM32L4_EXTI2_SWIER (STM32L4_EXTI2_BASE+STM32L4_EXTI_SWIER_OFFSET) +#define STM32L4_EXTI2_PR (STM32L4_EXTI2_BASE+STM32L4_EXTI_PR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* EXTI lines > 15 are associated with internal devices: */ + +#define EXTI1_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +#define EXTI1_OTGFS_WAKEUP (1 << 17) /* EXTI line 17 is connected to the USB OTG FS Wakeup event */ +#define EXTI1_RTC_ALARM (1 << 18) /* EXTI line 18 is connected to the RTC Alarm event */ +#define EXTI1_RTC_TAMPER (1 << 19) /* EXTI line 19 is connected to the RTC Tamper and TimeStamp events */ +#define EXTI1_RTC_WAKEUP (1 << 20) /* EXTI line 20 is connected to the RTC Wakeup event */ +#define EXTI1_COMP1 (1 << 21) /* EXTI line 21 is connected to the COMP1 (comparator) output */ +#define EXTI1_COMP2 (1 << 22) /* EXTI line 22 is connected to the COMP2 (comparator) output */ +#define EXTI1_I2C1 (1 << 23) /* EXTI line 23 is connected to the I2C1 wakeup */ +#define EXTI1_I2C2 (1 << 24) /* EXTI line 24 is connected to the I2C2 wakeup */ +#define EXTI1_I2C3 (1 << 25) /* EXTI line 25 is connected to the I2C3 wakeup */ +#define EXTI1_USART1 (1 << 26) /* EXTI line 26 is connected to the USART1 wakeup */ +#define EXTI1_USART2 (1 << 27) /* EXTI line 27 is connected to the USART2 wakeup */ +#define EXTI1_USART3 (1 << 28) /* EXTI line 28 is connected to the USART3 wakeup */ +#define EXTI1_UART4 (1 << 29) /* EXTI line 29 is connected to the UART4 wakeup */ +#define EXTI1_UART5 (1 << 30) /* EXTI line 30 is connected to the UART5 wakeup */ +#define EXTI1_LPUART1 (1 << 31) /* EXTI line 31 is connected to the LPUART1 wakeup */ +#define EXTI2_LPTIM1 (1 << 0) /* EXTI line 32 is connected to LPTIM1 */ +#define EXTI2_LPTIM2 (1 << 1) /* EXTI line 33 is connected to LPTIM2 */ +#define EXTI2_SWPMI1 (1 << 2) /* EXTI line 34 is connected to the SWPMI1 wakeup */ +#define EXTI2_PVM1 (1 << 3) /* EXTI line 35 is connected to the PVM1 wakeup */ +#define EXTI2_PVM2 (1 << 4) /* EXTI line 36 is connected to the PVM2 wakeup */ +#define EXTI2_PVM3 (1 << 5) /* EXTI line 37 is connected to the PVM3 wakeup */ +#define EXTI2_PVM4 (1 << 6) /* EXTI line 38 is connected to the PVM4 wakeup */ +#define EXTI2_LCD (1 << 7) /* EXTI line 39 is connected to the LCD wakeup */ + +/* Interrupt mask register */ + +#define EXTI_IMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR1_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_IMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR2_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR2_MASK STM32L4_EXTI2_MASK + +/* Event mask register */ + +#define EXTI_EMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR1_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_EMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR2_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR2_MASK STM32L4_EXTI2_MASK + +/* Rising Trigger selection register */ + +#define EXTI_RTSR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR1_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_RTSR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR2_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR2_MASK STM32L4_EXTI2_MASK + +/* Falling Trigger selection register */ + +#define EXTI_FTSR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR1_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_FTSR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR2_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR2_MASK STM32L4_EXTI2_MASK + +/* Software interrupt event register */ + +#define EXTI_SWIER1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER1_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER1_MASK STM32L4_EXTI1_MASK + +#define EXTI_SWIER2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER2_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER2_MASK STM32L4_EXTI2_MASK + +/* Pending register */ + +#define EXTI_IMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR1_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_IMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR2_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR2_MASK STM32L4_EXTI2_MASK + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_i2c.h b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..02927801fd3ff5685fbbf16b50f8c653ef4111d9 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h @@ -0,0 +1,249 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_I2C_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_I2C_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_I2C_CR1_OFFSET 0x0000 /* Control register 1 (32-bit) */ +#define STM32L4_I2C_CR2_OFFSET 0x0004 /* Control register 2 (32-bit) */ +#define STM32L4_I2C_OAR1_OFFSET 0x0008 /* Own address register 1 (16-bit) */ +#define STM32L4_I2C_OAR2_OFFSET 0x000c /* Own address register 2 (16-bit) */ +#define STM32L4_I2C_TIMINGR_OFFSET 0x0010 /* Timing register */ +#define STM32L4_I2C_TIMEOUTR_OFFSET 0x0014 /* Timeout register */ +#define STM32L4_I2C_ISR_OFFSET 0x0018 /* Interrupt and Status register */ +#define STM32L4_I2C_ICR_OFFSET 0x001c /* Interrupt clear register */ +#define STM32L4_I2C_PECR_OFFSET 0x0020 /* Packet error checking register */ +#define STM32L4_I2C_RXDR_OFFSET 0x0024 /* Receive data register */ +#define STM32L4_I2C_TXDR_OFFSET 0x0028 /* Transmit data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NI2C > 0 +# define STM32L4_I2C1_CR1 (STM32L4_I2C1_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C1_CR2 (STM32L4_I2C1_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C1_OAR1 (STM32L4_I2C1_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C1_OAR2 (STM32L4_I2C1_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C1_TIMINGR (STM32L4_I2C1_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C1_TIMEOUTR (STM32L4_I2C1_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C1_ISR (STM32L4_I2C1_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C1_ICR (STM32L4_I2C1_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C1_PECR (STM32L4_I2C1_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C1_RXDR (STM32L4_I2C1_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C1_TXDR (STM32L4_I2C1_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +#if STM32L4_NI2C > 1 +# define STM32L4_I2C2_CR1 (STM32L4_I2C2_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C2_CR2 (STM32L4_I2C2_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C2_OAR1 (STM32L4_I2C2_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C2_OAR2 (STM32L4_I2C2_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C2_TIMINGR (STM32L4_I2C2_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C2_TIMEOUTR (STM32L4_I2C2_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C2_ISR (STM32L4_I2C2_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C2_ICR (STM32L4_I2C2_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C2_PECR (STM32L4_I2C2_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C2_RXDR (STM32L4_I2C2_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C2_TXDR (STM32L4_I2C2_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +#if STM32L4_NI2C > 2 +# define STM32L4_I2C3_CR1 (STM32L4_I2C3_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C3_CR2 (STM32L4_I2C3_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C3_OAR1 (STM32L4_I2C3_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C3_OAR2 (STM32L4_I2C3_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C3_TIMINGR (STM32L4_I2C3_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C3_TIMEOUTR (STM32L4_I2C3_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C3_ISR (STM32L4_I2C3_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C3_ICR (STM32L4_I2C3_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C3_PECR (STM32L4_I2C3_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C3_RXDR (STM32L4_I2C3_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C3_TXDR (STM32L4_I2C3_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define I2C_CR1_PE (1 << 0) /* Bit 0: Peripheral Enable */ +#define I2C_CR1_TXIE (1 << 1) /* Bit 1: TX Interrupt enable */ +#define I2C_CR1_RXIE (1 << 2) /* Bit 2: RX Interrupt enable */ +#define I2C_CR1_ADDRIE (1 << 3) /* Bit 3: Address match interrupt enable (slave) */ +#define I2C_CR1_NACKIE (1 << 4) /* Bit 4: Not acknowledge received interrupt enable */ +#define I2C_CR1_STOPIE (1 << 5) /* Bit 5: STOP detection interrupt enable */ +#define I2C_CR1_TCIE (1 << 6) /* Bit 6: Transfer Complete interrupt enable */ +#define I2C_CR1_ERRIE (1 << 7) /* Bit 7: Error interrupts enable */ +#define I2C_CR1_DNF_SHIFT (8) /* Bits 8-11: Digital noise filter */ +#define I2C_CR1_DNF_MASK (15 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF_DISABLE (0 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF(n) ((n) << I2C_CR1_DNF_SHIFT) /* Up to n * Ti2cclk, n=1..15 */ +#define I2C_CR1_ANFOFF (1 << 12) /* Bit 12: Analog noise filter OFF */ +#define I2C_CR1_TXDMAEN (1 << 14) /* Bit 14: DMA transmission requests enable */ +#define I2C_CR1_RXDMAEN (1 << 15) /* Bit 15: DMA reception requests enable */ +#define I2C_CR1_SBC (1 << 16) /* Bit 16: Slave byte control */ +#define I2C_CR1_NOSTRETCH (1 << 17) /* Bit 17: Clock stretching disable */ +#define I2C_CR1_WUPEN (1 << 18) /* Bit 18: Wakeup from STOP enable */ +#define I2C_CR1_GCEN (1 << 19) /* Bit 19: General call enable */ +#define I2C_CR1_SMBHEN (1 << 20) /* Bit 20: SMBus Host address enable */ +#define I2C_CR1_SMBDEN (1 << 21) /* Bit 21: SMBus Device Default address enable */ +#define I2C_CR1_ALERTEN (1 << 22) /* Bit 22: SMBus alert enable */ +#define I2C_CR1_PECEN (1 << 23) /* Bit 23: PEC enable */ + +/* Control register 2 */ + +#define I2C_CR2_SADD10_SHIFT (0) /* Bits 0-9: Slave 10-bit address (master) */ +#define I2C_CR2_SADD10_MASK (0x3ff << I2C_CR2_SADD10_SHIFT) +#define I2C_CR2_SADD7_SHIFT (1) /* Bits 1-7: Slave 7-bit address (master) */ +#define I2C_CR2_SADD7_MASK (0x7f << I2C_CR2_SADD7_SHIFT) +#define I2C_CR2_RD_WRN (1 << 10) /* Bit 10: Transfer direction (master) */ +#define I2C_CR2_ADD10 (1 << 11) /* Bit 11: 10-bit addressing mode (master) */ +#define I2C_CR2_HEAD10R (1 << 12) /* Bit 12: 10-bit address header only read direction (master) */ +#define I2C_CR2_START (1 << 13) /* Bit 13: Start generation */ +#define I2C_CR2_STOP (1 << 14) /* Bit 14: Stop generation (master) */ +#define I2C_CR2_NACK (1 << 15) /* Bit 15: NACK generation (slave) */ +#define I2C_CR2_NBYTES_SHIFT (16) /* Bits 16-23: Number of bytes */ +#define I2C_CR2_NBYTES_MASK (0xff << I2C_CR2_NBYTES_SHIFT) +#define I2C_CR2_RELOAD (1 << 24) /* Bit 24: NBYTES reload mode */ +#define I2C_CR2_AUTOEND (1 << 25) /* Bit 25: Automatic end mode (master) */ +#define I2C_CR2_PECBYTE (1 << 26) /* Bit 26: Packet error checking byte */ + +/* Own address register 1 */ + +#define I2C_OAR1_OA1_10_SHIFT (0) /* Bits 0-9: 10-bit interface address */ +#define I2C_OAR1_OA1_10_MASK (0x3ff << I2C_OAR1_OA1_10_SHIFT) +#define I2C_OAR1_OA1_7_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR1_OA1_7_MASK (0x7f << I2C_OAR1_OA1_7_SHIFT) +#define I2C_OAR1_OA1MODE (1 << 10) /* Bit 10: Own Address 1 10-bit mode */ +#define I2C_OAR1_OA1EN (1 << 15) /* Bit 15: Own Address 1 enable */ + +/* Own address register 2 */ + +#define I2C_OAR2_OA2_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR2_OA2_MASK (0x7f << I2C_OAR2_OA2_SHIFT) +#define I2C_OAR2_OA2MSK_SHIFT (8) /* Bits 8-10: Own Address 2 masks */ +#define I2C_OAR2_OA2MSK_MASK (7 << I2C_OAR2_OA2MSK_SHIFT) +# define I2C_OAR2_OA2MSK_NONE (0 << I2C_OAR2_OA2MSK_SHIFT) /* No mask */ +# define I2C_OAR2_OA2MSK_2_7 (1 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:2] are compared */ +# define I2C_OAR2_OA2MSK_3_7 (2 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:3] are compared */ +# define I2C_OAR2_OA2MSK_4_7 (3 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:4] are compared */ +# define I2C_OAR2_OA2MSK_5_7 (4 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:5] are compared */ +# define I2C_OAR2_OA2MSK_6_7 (5 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:6] are compared */ +# define I2C_OAR2_OA2MSK_7 (6 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7] is compared */ +# define I2C_OAR2_OA2MSK_ALL (7 << I2C_OAR2_OA2MSK_SHIFT) /* All 7-bit addresses acknowledged */ +#define I2C_OAR2_OA2EN (1 << 15) /* Bit 15: Own Address 2 enable */ + +/* Timing register */ + +#define I2C_TIMINGR_SCLL_SHIFT (0) /* Bits 0-7: SCL low period (master) */ +#define I2C_TIMINGR_SCLL_MASK (0xff << I2C_TIMINGR_SCLL_SHIFT) +# define I2C_TIMINGR_SCLL(n) (((n)-1) << I2C_TIMINGR_SCLL_SHIFT) /* tSCLL = n x tPRESC */ + +#define I2C_TIMINGR_SCLH_SHIFT (8) /* Bits 8-15: SCL high period (master) */ +#define I2C_TIMINGR_SCLH_MASK (0xff << I2C_TIMINGR_SCLH_SHIFT) +# define I2C_TIMINGR_SCLH(n) (((n)-1) << I2C_TIMINGR_SCLH_SHIFT) /* tSCLH = n x tPRESC */ + +#define I2C_TIMINGR_SDADEL_SHIFT (16) /* Bits 16-19: Data hold time */ +#define I2C_TIMINGR_SDADEL_MASK (15 << I2C_TIMINGR_SDADEL_SHIFT) +# define I2C_TIMINGR_SDADEL(n) ((n) << I2C_TIMINGR_SDADEL_SHIFT) /* tSDADEL= n x tPRESC */ + +#define I2C_TIMINGR_SCLDEL_SHIFT (20) /* Bits 20-23: Data setup time */ +#define I2C_TIMINGR_SCLDEL_MASK (15 << I2C_TIMINGR_SCLDEL_SHIFT) +# define I2C_TIMINGR_SCLDEL(n) (((n)-1) << I2C_TIMINGR_SCLDEL_SHIFT) /* tSCLDEL = n x tPRESC */ + +#define I2C_TIMINGR_PRESC_SHIFT (28) /* Bits 28-31: Timing prescaler */ +#define I2C_TIMINGR_PRESC_MASK (15 << I2C_TIMINGR_PRESC_SHIFT) +# define I2C_TIMINGR_PRESC(n) (((n)-1) << I2C_TIMINGR_PRESC_SHIFT) /* tPRESC = n x tI2CCLK */ + +/* Timeout register */ + +#define I2C_TIMEOUTR_A_SHIFT (0) /* Bits 0-11: Bus Timeout A */ +#define I2C_TIMEOUTR_A_MASK (0x0fff << I2C_TIMEOUTR_A_SHIFT) +# define I2C_TIMEOUTR_A(n) ((n) << I2C_TIMEOUTR_A_SHIFT) +#define I2C_TIMEOUTR_TIDLE (1 << 12) /* Bit 12: Idle clock timeout detection */ +#define I2C_TIMEOUTR_TIMOUTEN (1 << 15) /* Bit 15: Clock timeout enable */ +#define I2C_TIMEOUTR_B_SHIFT (16) /* Bits 16-27: Bus Timeout B */ +#define I2C_TIMEOUTR_B_MASK (0x0fff << I2C_TIMEOUTR_B_SHIFT) +# define I2C_TIMEOUTR_B(n) ((n) << I2C_TIMEOUTR_B_SHIFT) +#define I2C_TIMEOUTR_TEXTEN (1 << 31) /* Bits 31: Extended clock timeout enable */ + +/* Interrupt and Status register and interrupt clear register */ +/* Common interrupt bits */ + +#define I2C_INT_ADDR (1 << 3) /* Bit 3: Address matched (slave) */ +#define I2C_INT_NACK (1 << 4) /* Bit 4: Not Acknowledge received flag */ +#define I2C_INT_STOP (1 << 5) /* Bit 5: Stop detection flag */ +#define I2C_INT_BERR (1 << 8) /* Bit 8: Bus error */ +#define I2C_INT_ARLO (1 << 9) /* Bit 9: Arbitration lost */ +#define I2C_INT_OVR (1 << 10) /* Bit 10: Overrun/Underrun (slave) */ +#define I2C_INT_PECERR (1 << 11) /* Bit 11: PEC Error in reception */ +#define I2C_INT_TIMEOUT (1 << 12) /* Bit 12: Timeout or tLOW detection flag */ +#define I2C_INT_ALERT (1 << 13) /* Bit 13: SMBus alert */ + +/* Fields unique to the Interrupt and Status register */ + +#define I2C_ISR_TXE (1 << 0) /* Bit 0: Transmit data register empty (transmitters) */ +#define I2C_ISR_TXIS (1 << 1) /* Bit 1: Transmit interrupt status (transmitters) */ +#define I2C_ISR_RXNE (1 << 2) /* Bit 2: Receive data register not empty (receivers) */ +#define I2C_ISR_TC (1 << 6) /* Bit 6: Transfer Complete (master) */ +#define I2C_ISR_TCR (1 << 7) /* Bit 7: Transfer Complete Reload */ +#define I2C_ISR_BUSY (1 << 15) /* Bit 15: Bus busy */ +#define I2C_ISR_DIR (1 << 16) /* Bit 16: Transfer direction (slave) */ +#define I2C_ISR_ADDCODE_SHIFT (17) /* Bits 17-23: Address match code (slave) */ +#define I2C_ISR_ADDCODE_MASK (0x7f << I2C_ISR_ADDCODE_SHIFT) + +#define I2C_ISR_ERRORMASK (I2C_INT_BERR | I2C_INT_ARLO | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT) + +#define I2C_ICR_CLEARMASK (I2C_INT_ADDR | I2C_INT_NACK | I2C_INT_STOP | I2C_INT_BERR | I2C_INT_ARLO \ + | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT | I2C_INT_ALERT) + +/* Packet error checking register */ + +#define I2C_PECR_MASK (0xff) + +/* Receive data register */ + +#define I2C_RXDR_MASK (0xff) + +/* Transmit data register */ + +#define I2C_TXDR_MASK (0xff) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32F30XXX_I2C_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..0dd79ff8de84528afb142bfbff83b3380c10e413 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h @@ -0,0 +1,197 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_memorymap.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32L4_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32L4_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block (96k) */ +#define STM32L4_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32L4_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32L4_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +# define STM32L4_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32L4_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3 / QSPI block */ +# define STM32L4_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32L4_QSPI_BANK 0x90000000 /* 0x90000000-0x9fffffff: 256Mb QUADSPI*/ +#define STM32L4_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: FSMC register block */ +#define STM32L4_QSPI_BASE 0xa0001000 /* 0xa0000000-0xbfffffff: QSPI register block */ + /* 0xc0000000-0xdfffffff: 512Mb (not used) */ +#define STM32L4_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32L4_REGION_MASK 0xf0000000 +#define STM32L4_IS_SRAM(a) ((((uint32_t)(a)) & STM32L4_REGION_MASK) == STM32L4_SRAM_BASE) +#define STM32L4_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32L4_REGION_MASK) == STM32L4_FSMC_BANK1) + +/* Code Base Addresses **************************************************************/ + +#define STM32L4_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32L4_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x0fffffff: Reserved */ +#define STM32L4_SRAM2_BASE 0x10000000 /* 0x10000000-0x1000ffff: 32Kb SRAM2 */ + /* 0x10010000-0x1ffeffff: Reserved */ +#define STM32L4_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32L4_OPTION_BASE 0x1fffc000 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32L4_SYSMEM_UID 0x1fff7590 /* The 96-bit unique device identifier */ +#define STM32L4_SYSMEM_FSIZE 0x1fff75E0 /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x0400 corresponds + * to 1024 Kbytes. + */ +#define STM32L4_SYSMEM_PACKAGE 0x1fff7500 /* This bitfield indicates the package + * type. + * 0: LQFP64 + * 2: LQFP100 + * 3: BGA132 + * 4: LQFP144, WLCSP81 or WLCSP72 + */ + +/* SRAM Base Addresses **************************************************************/ + + /* 0x20000000-0x2000ffff: 64k aliased by bit-banding */ + /* 0x2001c000-0x2001ffff: 16Kb aliased by bit-banding */ +#define STM32L4_SRAMBB_BASE 0x22000000 /* 0x22000000- : SRAM bit-band region */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32L4_APB1_BASE 0x40000000 /* 0x40000000-0x400097ff: APB1 */ + /* 0x40009800-0x4000ffff: Reserved */ +#define STM32L4_APB2_BASE 0x40010000 /* 0x40010000-0x400163ff: APB2 */ + /* 0x40016400-0x4001ffff: Reserved */ +#define STM32L4_AHB1_BASE 0x40020000 /* 0x40020000-0x400243ff: APB1 */ + /* 0x40024400-0x47ffffff: Reserved */ +#define STM32L4_AHB2_BASE 0x48000000 /* 0x48000000-0x50060bff: AHB2 */ + /* 0x50060c00-0x5fffffff: Reserved */ + +/* FSMC/QSPI Base Addresses **************************************************************/ + +#define STM32L4_AHB3_BASE 0x60000000 /* 0x60000000-0xa0000fff: AHB3 */ + +/* in datasheet order */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32L4_LPTIM2_BASE 0x40009400 +#define STM32L4_SWPMI1_BASE 0x40008800 +#define STM32L4_LPUART1_BASE 0x40008000 +#define STM32L4_LPTIM1_BASE 0x40007c00 +#define STM32L4_OPAMP_BASE 0x40007800 +#define STM32L4_DAC_BASE 0x40007400 +#define STM32L4_PWR_BASE 0x40007000 +#define STM32L4_CAN1_BASE 0x40006400 +#define STM32L4_I2C3_BASE 0x40005c00 +#define STM32L4_I2C2_BASE 0x40005800 +#define STM32L4_I2C1_BASE 0x40005400 +#define STM32L4_UART5_BASE 0x40005000 +#define STM32L4_UART4_BASE 0x40004c00 +#define STM32L4_USART3_BASE 0x40004800 +#define STM32L4_USART2_BASE 0x40004400 +#define STM32L4_SPI3_BASE 0x40003c00 +#define STM32L4_SPI2_BASE 0x40003800 +#define STM32L4_IWDG_BASE 0x40003000 +#define STM32L4_WWDG_BASE 0x40002c00 +#define STM32L4_RTC_BASE 0x40002800 +#define STM32L4_LCD_BASE 0x40002400 +#define STM32L4_TIM7_BASE 0x40001400 +#define STM32L4_TIM6_BASE 0x40001000 +#define STM32L4_TIM5_BASE 0x40000c00 +#define STM32L4_TIM4_BASE 0x40000800 +#define STM32L4_TIM3_BASE 0x40000400 +#define STM32L4_TIM2_BASE 0x40000000 + +/* APB2 Base Addresses **************************************************************/ + +#define STM32L4_DFSDM_BASE 0x40016000 +#define STM32L4_SAI2_BASE 0x40015800 +#define STM32L4_SAI1_BASE 0x40015400 +#define STM32L4_TIM17_BASE 0x40014800 +#define STM32L4_TIM16_BASE 0x40014400 +#define STM32L4_TIM15_BASE 0x40014000 +#define STM32L4_USART1_BASE 0x40013800 +#define STM32L4_TIM8_BASE 0x40013400 +#define STM32L4_SPI1_BASE 0x40013000 +#define STM32L4_TIM1_BASE 0x40012c00 +#define STM32L4_SDMMC1_BASE 0x40012800 +#define STM32L4_FIREWALL_BASE 0x40011c00 +#define STM32L4_EXTI_BASE 0x40010400 +#define STM32L4_COMP_BASE 0x40010200 +#define STM32L4_VREFBUF_BASE 0x40010030 +#define STM32L4_SYSCFG_BASE 0x40010000 + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32L4_TSC_BASE 0x40024000 +#define STM32L4_CRC_BASE 0x40023000 +#define STM32L4_FLASHIF_BASE 0x40022000 +#define STM32L4_RCC_BASE 0x40021000 +#define STM32L4_DMA2_BASE 0x40020400 +#define STM32L4_DMA1_BASE 0x40020000 + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32L4_RNG_BASE 0x50060800 +#define STM32L4_AES_BASE 0x50060000 +#define STM32L4_ADC_BASE 0x50040000 +#define STM32L4_OTG_FS_BASE 0x50000000 +#define STM32L4_GPIOH_BASE 0x50001c00 +#define STM32L4_GPIOG_BASE 0x48001800 +#define STM32L4_GPIOF_BASE 0x48001400 +#define STM32L4_GPIOE_BASE 0x48001000 +#define STM32L4_GPIOD_BASE 0x48000c00 +#define STM32L4_GPIOC_BASE 0x48000800 +#define STM32L4_GPIOB_BASE 0x48000400 +#define STM32L4_GPIOA_BASE 0x48000000 + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32L4_SCS_BASE 0xe000e000 +#define STM32L4_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..16bbdec7ab14b30993635d9d20419aa04ce35c2d --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h @@ -0,0 +1,53 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32_pinmap.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32_PINMAP_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_pinmap.h" +#else +# error "Unsupported STM32 L4 pin map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32_PINMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_pwr.h b/arch/arm/src/stm32l4/chip/stm32l4_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..2e771551f8ea23e2faad53ae83f3446ef3b65645 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_pwr.h @@ -0,0 +1,195 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_pwr.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_PWR_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_PWR_CR1_OFFSET 0x0000 /* Power control register 1 */ +#define STM32L4_PWR_CR2_OFFSET 0x0004 /* Power control register 2 */ +#define STM32L4_PWR_CR3_OFFSET 0x0008 /* Power control register 3 */ +#define STM32L4_PWR_CR4_OFFSET 0x000C /* Power control register 4 */ +#define STM32L4_PWR_SR1_OFFSET 0x0010 /* Power status register 1 */ +#define STM32L4_PWR_SR2_OFFSET 0x0014 /* Power status register 2 */ +#define STM32L4_PWR_SCR_OFFSET 0x0018 /* Power status clear register */ +#define STM32L4_PWR_PUCRA_OFFSET 0x0020 /* Power Port A pull-up control register */ +#define STM32L4_PWR_PDCRA_OFFSET 0x0024 /* Power Port A pull-down control register */ +#define STM32L4_PWR_PUCRB_OFFSET 0x0028 /* Power Port B pull-up control register */ +#define STM32L4_PWR_PDCRB_OFFSET 0x002C /* Power Port B pull-down control register */ +#define STM32L4_PWR_PUCRC_OFFSET 0x0030 /* Power Port C pull-up control register */ +#define STM32L4_PWR_PDCRC_OFFSET 0x0034 /* Power Port C pull-down control register */ +#define STM32L4_PWR_PUCRD_OFFSET 0x0038 /* Power Port D pull-up control register */ +#define STM32L4_PWR_PDCRD_OFFSET 0x003C /* Power Port D pull-down control register */ +#define STM32L4_PWR_PUCRE_OFFSET 0x0040 /* Power Port E pull-up control register */ +#define STM32L4_PWR_PDCRE_OFFSET 0x0044 /* Power Port E pull-down control register */ +#define STM32L4_PWR_PUCRF_OFFSET 0x0048 /* Power Port F pull-up control register */ +#define STM32L4_PWR_PDCRF_OFFSET 0x004C /* Power Port F pull-down control register */ +#define STM32L4_PWR_PUCRG_OFFSET 0x0050 /* Power Port G pull-up control register */ +#define STM32L4_PWR_PDCRG_OFFSET 0x0054 /* Power Port G pull-down control register */ +#define STM32L4_PWR_PUCRH_OFFSET 0x0058 /* Power Port H pull-up control register */ +#define STM32L4_PWR_PDCRH_OFFSET 0x005C /* Power Port H pull-down control register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_PWR_CR1 (STM32L4_PWR_BASE+STM32L4_PWR_CR1_OFFSET) +#define STM32L4_PWR_CR2 (STM32L4_PWR_BASE+STM32L4_PWR_CR2_OFFSET) +#define STM32L4_PWR_CR3 (STM32L4_PWR_BASE+STM32L4_PWR_CR3_OFFSET) +#define STM32L4_PWR_CR4 (STM32L4_PWR_BASE+STM32L4_PWR_CR4_OFFSET) +#define STM32L4_PWR_SR1 (STM32L4_PWR_BASE+STM32L4_PWR_SR1_OFFSET) +#define STM32L4_PWR_SR2 (STM32L4_PWR_BASE+STM32L4_PWR_SR2_OFFSET) +#define STM32L4_PWR_SCR (STM32L4_PWR_BASE+STM32L4_PWR_SCR_OFFSET) +#define STM32L4_PWR_PUCRA (STM32L4_PWR_BASE+STM32L4_PWR_PUCRA_OFFSET) +#define STM32L4_PWR_PDCRA (STM32L4_PWR_BASE+STM32L4_PWR_PDCRA_OFFSET) +#define STM32L4_PWR_PUCRB (STM32L4_PWR_BASE+STM32L4_PWR_PUCRB_OFFSET) +#define STM32L4_PWR_PDCRB (STM32L4_PWR_BASE+STM32L4_PWR_PDCRB_OFFSET) +#define STM32L4_PWR_PUCRC (STM32L4_PWR_BASE+STM32L4_PWR_PUCRC_OFFSET) +#define STM32L4_PWR_PDCRC (STM32L4_PWR_BASE+STM32L4_PWR_PDCRC_OFFSET) +#define STM32L4_PWR_PUCRD (STM32L4_PWR_BASE+STM32L4_PWR_PUCRD_OFFSET) +#define STM32L4_PWR_PDCRD (STM32L4_PWR_BASE+STM32L4_PWR_PDCRD_OFFSET) +#define STM32L4_PWR_PUCRE (STM32L4_PWR_BASE+STM32L4_PWR_PUCRE_OFFSET) +#define STM32L4_PWR_PDCRE (STM32L4_PWR_BASE+STM32L4_PWR_PDCRE_OFFSET) +#define STM32L4_PWR_PUCRF (STM32L4_PWR_BASE+STM32L4_PWR_PUCRF_OFFSET) +#define STM32L4_PWR_PDCRF (STM32L4_PWR_BASE+STM32L4_PWR_PDCRF_OFFSET) +#define STM32L4_PWR_PUCRG (STM32L4_PWR_BASE+STM32L4_PWR_PUCRG_OFFSET) +#define STM32L4_PWR_PDCRG (STM32L4_PWR_BASE+STM32L4_PWR_PDCRG_OFFSET) +#define STM32L4_PWR_PUCRH (STM32L4_PWR_BASE+STM32L4_PWR_PUCRH_OFFSET) +#define STM32L4_PWR_PDCRH (STM32L4_PWR_BASE+STM32L4_PWR_PDCRH_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Power control register 1 */ + +#define PWR_CR1_LPMS_SHIFT 0 +#define PWR_CR1_LPMS_MASK (7 << PWR_CR1_LPMS_SHIFT) /* Bits 0-2: Low-power mode selection */ +# define PWR_CR1_LPMS_STOP0 (0 << PWR_CR1_LPMS_SHIFT) /* 000: Stop 0 mode */ +# define PWR_CR1_LPMS_STOP1 (1 << PWR_CR1_LPMS_SHIFT) /* 001: Stpp 1 mode */ +# define PWR_CR1_LPMS_STOP2 (2 << PWR_CR1_LPMS_SHIFT) /* 010: Stop 2 mode*/ +# define PWR_CR1_LPMS_STANDBY (3 << PWR_CR1_LPMS_SHIFT) /* 011: Standby mode */ +# define PWR_CR1_LPMS_SHUTDOWN (4 << PWR_CR1_LPMS_SHIFT) /* 1xx: Shutdown node */ +#define PWR_CR1_DBP (1 << 8) /* Bit 8: Disable Backup domain write protection */ +#define PWR_CR1_VOS_SHIFT 9 +#define PWR_CR1_VOS_MASK (3 << PWR_CR1_VOS_SHIFT) /* Bits 9-10: Voltage scaling range selection */ +#define PWR_CR1_VOS_RANGE1 (1 << PWR_CR1_VOS_SHIFT) /* 01: Range 1 */ +#define PWR_CR1_VOS_RANGE2 (2 << PWR_CR1_VOS_SHIFT) /* 10: Range 2 */ +#define PWR_CR1_LPR (1 << 14) /* Bit 14: Low-power run */ + +/* Power control register 2 */ + +#define PWR_CR2_PVDE (1 << 0) /* Bit 0: Power voltage detector enable */ +#define PWR_CR2_PLS_SHIFT 1 +#define PWR_CR2_PLS_MASK (7 << PWR_CR2_PLS_SHIFT) /* Bits 1-3: Power voltage detector level selection */ +# define PWR_CR2_PLS_2000mv (0 << PWR_CR2_PLS_SHIFT) /* 000: VPVD0 around 2.0V */ +# define PWR_CR2_PLS_2200mv (1 << PWR_CR2_PLS_SHIFT) /* 001: VPVD1 around 2.2V */ +# define PWR_CR2_PLS_2400mv (2 << PWR_CR2_PLS_SHIFT) /* 010: VPVD2 around 2.4V */ +# define PWR_CR2_PLS_2500mv (3 << PWR_CR2_PLS_SHIFT) /* 011: VPVD3 around 2.5V */ +# define PWR_CR2_PLS_2600mv (4 << PWR_CR2_PLS_SHIFT) /* 100: VPVD4 around 2.6V */ +# define PWR_CR2_PLS_2800mv (5 << PWR_CR2_PLS_SHIFT) /* 101: VPVD5 around 2.8V */ +# define PWR_CR2_PLS_2900mv (6 << PWR_CR2_PLS_SHIFT) /* 110: VPVD6 around 2.9V */ +# define PWR_CR2_PLS_EXT (7 << PWR_CR2_PLS_SHIFT) /* 111: External input analog voltage PVD_IN */ +#define PWR_CR2_PVME1 (1 << 4) /* Bit 4: Peripheral voltage monitoring 1 enable (VDDUSB vs 1.2V) */ +#define PWR_CR2_PVME2 (1 << 5) /* Bit 5: Peripheral voltage monitoring 2 enable (VDDIO2 vs 0.9V) */ +#define PWR_CR2_PVME3 (1 << 6) /* Bit 6: Peripheral voltage monitoring 3 enable (VDDA vs 1.62V) */ +#define PWR_CR2_PVME4 (1 << 7) /* Bit 7: Peripheral voltage monitoring 4 enable (VDDA vs 2.2V) */ +#define PWR_CR2_IOSV (1 << 9) /* Bit 9: VDDIO2 Independent I/Os supply valid */ +#define PWR_CR2_USV (1 << 10) /* Bit 10: VDDUSB USB supply valid */ + +/* Power control register 3 */ + +#define PWR_CR3_EWUP1 (1 << 0) /* Bit 0: Enable Wakeup pin WKUP1 */ +#define PWR_CR3_EWUP2 (1 << 1) /* Bit 1: Enable Wakeup pin WKUP2 */ +#define PWR_CR3_EWUP3 (1 << 2) /* Bit 2: Enable Wakeup pin WKUP3 */ +#define PWR_CR3_EWUP4 (1 << 3) /* Bit 3: Enable Wakeup pin WKUP4 */ +#define PWR_CR3_EWUP5 (1 << 4) /* Bit 4: Enable Wakeup pin WKUP5 */ +#define PWR_CR3_RRS (1 << 8) /* Bit 8: SRAM2 retention in Standby mode */ +#define PWR_CR3_APC (1 << 10) /* Bit 10: Apply pull-up and pull-down configuration */ +#define PWR_CR3_EIWUL (1 << 15) /* Bit 15: Enable internal wakeup line */ + +/* Power control register 4 */ + +#define PWR_CR4_WP1 (1 << 0) /* Bit 0: Wakeup pin WKUP1 polarity */ +#define PWR_CR4_WP2 (1 << 1) /* Bit 1: Wakeup pin WKUP2 polarity */ +#define PWR_CR4_WP3 (1 << 2) /* Bit 2: Wakeup pin WKUP3 polarity */ +#define PWR_CR4_WP4 (1 << 3) /* Bit 3: Wakeup pin WKUP4 polarity */ +#define PWR_CR4_WP5 (1 << 4) /* Bit 4: Wakeup pin WKUP5 polarity */ +#define PWR_CR4_VBE (1 << 8) /* Bit 8: Vbat battery charging enable */ +#define PWR_CR4_VBRS (1 << 9) /* Bit 9: Vbat barrery charging resistor selection */ +# define PWR_CR4_VBRS_5k 0 /* 0: 5k resistor */ +# define PWR_CR4_VBRS_1k5 PWR_CR4_VBRS /* 1: 1k5 resistor */ + +/* Power status register 1 */ + +#define PWR_SR1_WUF1 (1 << 0) /* Bit 0: Wakeup flag 1 */ +#define PWR_SR1_WUF2 (1 << 1) /* Bit 1: Wakeup flag 2 */ +#define PWR_SR1_WUF3 (1 << 2) /* Bit 2: Wakeup flag 3 */ +#define PWR_SR1_WUF4 (1 << 3) /* Bit 3: Wakeup flag 4 */ +#define PWR_SR1_WUF5 (1 << 4) /* Bit 4: Wakeup flag 5 */ +#define PWR_SR1_SBF (1 << 8) /* Bit 8: Standby flag */ +#define PWR_SR1_WUFI (1 << 15) /* Bit 15: Wakeup internal flag */ + +/* Power status register 2 */ + +#define PWR_SR2_REGLPS (1 << 0) /* Bit 0: Low power regulator started */ +#define PWR_SR2_REGLPF (1 << 1) /* Bit 1: Low power regulator flag */ +#define PWR_SR2_VOSF (1 << 10) /* Bit 10: Voltage scaling flag */ +#define PWR_SR2_PVDO (1 << 11) /* Bit 11: Power voltage detector output */ +#define PWR_SR2_PVMO1 (1 << 12) /* Bit 12: Peripheral voltage monitoring output 1 (VDDUSB vs 1.2V) */ +#define PWR_SR2_PVMO2 (1 << 13) /* Bit 13: Peripheral voltage monitoring output 2 (VDDIO2 vs 0.9V) */ +#define PWR_SR2_PVMO3 (1 << 14) /* Bit 14: Peripheral voltage monitoring output 3 (VDDA vs 1.62V) */ +#define PWR_SR2_PVMO4 (1 << 15) /* Bit 15: Peripheral voltage monitoring output 4 (VDDA vs 2.2V) */ + +/* Power status clear register */ + +#define PWR_SCR_CWUF1 (1 << 0) /* Bit 0: Clear wakeup flag 1 */ +#define PWR_SCR_CWUF2 (1 << 1) /* Bit 1: Clear wakeup flag 2 */ +#define PWR_SCR_CWUF3 (1 << 2) /* Bit 2: Clear wakeup flag 3 */ +#define PWR_SCR_CWUF4 (1 << 3) /* Bit 3: Clear wakeup flag 4 */ +#define PWR_SCR_CWUF5 (1 << 4) /* Bit 4: Clear wakeup flag 5 */ +#define PWR_SCR_CSBF (1 << 8) /* Bit 8: Clear standby flag */ + +/* Port X pull-up/down registers have one bit per port line, with a few exceptions */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_PWR_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_rng.h b/arch/arm/src/stm32l4/chip/stm32l4_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..434b77c1c265c93b2706f0c85c0a351804a8aea6 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_rng.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32l4_rng.h + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32L4_RNG_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32L4_RNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_RNG_CR_OFFSET 0x0000 /* RNG Control Register */ +#define STM32L4_RNG_SR_OFFSET 0x0004 /* RNG Status Register */ +#define STM32L4_RNG_DR_OFFSET 0x0008 /* RNG Data Register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_RNG_CR (STM32L4_RNG_BASE+STM32L4_RNG_CR_OFFSET) +#define STM32L4_RNG_SR (STM32L4_RNG_BASE+STM32L4_RNG_SR_OFFSET) +#define STM32L4_RNG_DR (STM32L4_RNG_BASE+STM32L4_RNG_DR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RNG Control Register */ + +#define RNG_CR_RNGEN (1 << 2) /* Bit 2: RNG enable */ +#define RNG_CR_IE (1 << 3) /* Bit 3: Interrupt enable */ + +/* RNG Status Register */ + +#define RNG_SR_DRDY (1 << 0) /* Bit 0: Data ready */ +#define RNG_SR_CECS (1 << 1) /* Bit 1: Clock error current status */ +#define RNG_SR_SECS (1 << 2) /* Bit 2: Seed error current status */ +#define RNG_SR_CEIS (1 << 5) /* Bit 5: Clock error interrupt status */ +#define RNG_SR_SEIS (1 << 6) /* Bit 6: Seed error interrupt status */ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32L4_RNG_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_rtcc.h b/arch/arm/src/stm32l4/chip/stm32l4_rtcc.h new file mode 100644 index 0000000000000000000000000000000000000000..1bc7c7bfd7f66228755766ddd4166d1857ab9e31 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_rtcc.h @@ -0,0 +1,401 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_rtcc.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_RTCC_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_RTCC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_RTC_TR_OFFSET 0x0000 /* RTC time register */ +#define STM32L4_RTC_DR_OFFSET 0x0004 /* RTC date register */ +#define STM32L4_RTC_CR_OFFSET 0x0008 /* RTC control register */ +#define STM32L4_RTC_ISR_OFFSET 0x000c /* RTC initialization and status register */ +#define STM32L4_RTC_PRER_OFFSET 0x0010 /* RTC prescaler register */ +#define STM32L4_RTC_WUTR_OFFSET 0x0014 /* RTC wakeup timer register */ +#define STM32L4_RTC_ALRMAR_OFFSET 0x001c /* RTC alarm A register */ +#define STM32L4_RTC_ALRMBR_OFFSET 0x0020 /* RTC alarm B register */ +#define STM32L4_RTC_WPR_OFFSET 0x0024 /* RTC write protection register */ +#define STM32L4_RTC_SSR_OFFSET 0x0028 /* RTC sub second register */ +#define STM32L4_RTC_SHIFTR_OFFSET 0x002c /* RTC shift control register */ +#define STM32L4_RTC_TSTR_OFFSET 0x0030 /* RTC time stamp time register */ +#define STM32L4_RTC_TSDR_OFFSET 0x0034 /* RTC time stamp date register */ +#define STM32L4_RTC_TSSSR_OFFSET 0x0038 /* RTC timestamp sub second register */ +#define STM32L4_RTC_CALR_OFFSET 0x003c /* RTC calibration register */ +#define STM32L4_RTC_TAMPCR_OFFSET 0x0040 /* RTC tamper configuration register */ +#define STM32L4_RTC_ALRMASSR_OFFSET 0x0044 /* RTC alarm A sub second register */ +#define STM32L4_RTC_ALRMBSSR_OFFSET 0x0048 /* RTC alarm B sub second register */ +#define STM32L4_RTC_OR_OFFSET 0x004c /* RTC option register */ + +#define STM32L4_RTC_BKR_OFFSET(n) (0x0050+((n)<<2)) +#define STM32L4_RTC_BK0R_OFFSET 0x0050 /* RTC backup register 0 */ +#define STM32L4_RTC_BK1R_OFFSET 0x0054 /* RTC backup register 1 */ +#define STM32L4_RTC_BK2R_OFFSET 0x0058 /* RTC backup register 2 */ +#define STM32L4_RTC_BK3R_OFFSET 0x005c /* RTC backup register 3 */ +#define STM32L4_RTC_BK4R_OFFSET 0x0060 /* RTC backup register 4 */ +#define STM32L4_RTC_BK5R_OFFSET 0x0064 /* RTC backup register 5 */ +#define STM32L4_RTC_BK6R_OFFSET 0x0068 /* RTC backup register 6 */ +#define STM32L4_RTC_BK7R_OFFSET 0x006c /* RTC backup register 7 */ +#define STM32L4_RTC_BK8R_OFFSET 0x0070 /* RTC backup register 8 */ +#define STM32L4_RTC_BK9R_OFFSET 0x0074 /* RTC backup register 9 */ +#define STM32L4_RTC_BK10R_OFFSET 0x0078 /* RTC backup register 10 */ +#define STM32L4_RTC_BK11R_OFFSET 0x007c /* RTC backup register 11 */ +#define STM32L4_RTC_BK12R_OFFSET 0x0080 /* RTC backup register 12 */ +#define STM32L4_RTC_BK13R_OFFSET 0x0084 /* RTC backup register 13 */ +#define STM32L4_RTC_BK14R_OFFSET 0x0088 /* RTC backup register 14 */ +#define STM32L4_RTC_BK15R_OFFSET 0x008c /* RTC backup register 15 */ +#define STM32L4_RTC_BK16R_OFFSET 0x0090 /* RTC backup register 16 */ +#define STM32L4_RTC_BK17R_OFFSET 0x0094 /* RTC backup register 17 */ +#define STM32L4_RTC_BK18R_OFFSET 0x0098 /* RTC backup register 18 */ +#define STM32L4_RTC_BK19R_OFFSET 0x009c /* RTC backup register 19 */ +#define STM32L4_RTC_BK20R_OFFSET 0x00a0 /* RTC backup register 20 */ +#define STM32L4_RTC_BK21R_OFFSET 0x00a4 /* RTC backup register 21 */ +#define STM32L4_RTC_BK22R_OFFSET 0x00a8 /* RTC backup register 22 */ +#define STM32L4_RTC_BK23R_OFFSET 0x00ac /* RTC backup register 23 */ +#define STM32L4_RTC_BK24R_OFFSET 0x00b0 /* RTC backup register 24 */ +#define STM32L4_RTC_BK25R_OFFSET 0x00b4 /* RTC backup register 25 */ +#define STM32L4_RTC_BK26R_OFFSET 0x00b8 /* RTC backup register 26 */ +#define STM32L4_RTC_BK27R_OFFSET 0x00bc /* RTC backup register 27 */ +#define STM32L4_RTC_BK28R_OFFSET 0x00c0 /* RTC backup register 28 */ +#define STM32L4_RTC_BK29R_OFFSET 0x00c4 /* RTC backup register 29 */ +#define STM32L4_RTC_BK30R_OFFSET 0x00c8 /* RTC backup register 30 */ +#define STM32L4_RTC_BK31R_OFFSET 0x00cc /* RTC backup register 31 */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_RTC_TR (STM32L4_RTC_BASE+STM32L4_RTC_TR_OFFSET) +#define STM32L4_RTC_DR (STM32L4_RTC_BASE+STM32L4_RTC_DR_OFFSET) +#define STM32L4_RTC_CR (STM32L4_RTC_BASE+STM32L4_RTC_CR_OFFSET) +#define STM32L4_RTC_ISR (STM32L4_RTC_BASE+STM32L4_RTC_ISR_OFFSET) +#define STM32L4_RTC_PRER (STM32L4_RTC_BASE+STM32L4_RTC_PRER_OFFSET) +#define STM32L4_RTC_WUTR (STM32L4_RTC_BASE+STM32L4_RTC_WUTR_OFFSET) +#define STM32L4_RTC_ALRMAR (STM32L4_RTC_BASE+STM32L4_RTC_ALRMAR_OFFSET) +#define STM32L4_RTC_ALRMBR (STM32L4_RTC_BASE+STM32L4_RTC_ALRMBR_OFFSET) +#define STM32L4_RTC_WPR (STM32L4_RTC_BASE+STM32L4_RTC_WPR_OFFSET) +#define STM32L4_RTC_SSR (STM32L4_RTC_BASE+STM32L4_RTC_SSR_OFFSET) +#define STM32L4_RTC_SHIFTR (STM32L4_RTC_BASE+STM32L4_RTC_SHIFTR_OFFSET) +#define STM32L4_RTC_TSTR (STM32L4_RTC_BASE+STM32L4_RTC_TSTR_OFFSET) +#define STM32L4_RTC_TSDR (STM32L4_RTC_BASE+STM32L4_RTC_TSDR_OFFSET) +#define STM32L4_RTC_TSSSR (STM32L4_RTC_BASE+STM32L4_RTC_TSSSR_OFFSET) +#define STM32L4_RTC_CALR (STM32L4_RTC_BASE+STM32L4_RTC_CALR_OFFSET) +#define STM32L4_RTC_TAMPCR (STM32L4_RTC_BASE+STM32L4_RTC_TAMPCR_OFFSET) +#define STM32L4_RTC_ALRMASSR (STM32L4_RTC_BASE+STM32L4_RTC_ALRMASSR_OFFSET) +#define STM32L4_RTC_ALRMBSSR (STM32L4_RTC_BASE+STM32L4_RTC_ALRMBSSR_OFFSET) +#define STM32L4_RTC_OR (STM32L4_RTC_BASE+STM32L4_RTC_OR_OFFSET) + +#define STM32L4_RTC_BKR(n) (STM32L4_RTC_BASE+STM32L4_RTC_BKR_OFFSET(n)) +#define STM32L4_RTC_BK0R (STM32L4_RTC_BASE+STM32L4_RTC_BK0R_OFFSET) +#define STM32L4_RTC_BK1R (STM32L4_RTC_BASE+STM32L4_RTC_BK1R_OFFSET) +#define STM32L4_RTC_BK2R (STM32L4_RTC_BASE+STM32L4_RTC_BK2R_OFFSET) +#define STM32L4_RTC_BK3R (STM32L4_RTC_BASE+STM32L4_RTC_BK3R_OFFSET) +#define STM32L4_RTC_BK4R (STM32L4_RTC_BASE+STM32L4_RTC_BK4R_OFFSET) +#define STM32L4_RTC_BK5R (STM32L4_RTC_BASE+STM32L4_RTC_BK5R_OFFSET) +#define STM32L4_RTC_BK6R (STM32L4_RTC_BASE+STM32L4_RTC_BK6R_OFFSET) +#define STM32L4_RTC_BK7R (STM32L4_RTC_BASE+STM32L4_RTC_BK7R_OFFSET) +#define STM32L4_RTC_BK8R (STM32L4_RTC_BASE+STM32L4_RTC_BK8R_OFFSET) +#define STM32L4_RTC_BK9R (STM32L4_RTC_BASE+STM32L4_RTC_BK9R_OFFSET) +#define STM32L4_RTC_BK10R (STM32L4_RTC_BASE+STM32L4_RTC_BK10R_OFFSET) +#define STM32L4_RTC_BK11R (STM32L4_RTC_BASE+STM32L4_RTC_BK11R_OFFSET) +#define STM32L4_RTC_BK12R (STM32L4_RTC_BASE+STM32L4_RTC_BK12R_OFFSET) +#define STM32L4_RTC_BK13R (STM32L4_RTC_BASE+STM32L4_RTC_BK13R_OFFSET) +#define STM32L4_RTC_BK14R (STM32L4_RTC_BASE+STM32L4_RTC_BK14R_OFFSET) +#define STM32L4_RTC_BK15R (STM32L4_RTC_BASE+STM32L4_RTC_BK15R_OFFSET) +#define STM32L4_RTC_BK16R (STM32L4_RTC_BASE+STM32L4_RTC_BK16R_OFFSET) +#define STM32L4_RTC_BK17R (STM32L4_RTC_BASE+STM32L4_RTC_BK17R_OFFSET) +#define STM32L4_RTC_BK18R (STM32L4_RTC_BASE+STM32L4_RTC_BK18R_OFFSET) +#define STM32L4_RTC_BK19R (STM32L4_RTC_BASE+STM32L4_RTC_BK19R_OFFSET) +#define STM32L4_RTC_BK20R (STM32L4_RTC_BASE+STM32L4_RTC_BK20R_OFFSET) +#define STM32L4_RTC_BK21R (STM32L4_RTC_BASE+STM32L4_RTC_BK21R_OFFSET) +#define STM32L4_RTC_BK22R (STM32L4_RTC_BASE+STM32L4_RTC_BK22R_OFFSET) +#define STM32L4_RTC_BK23R (STM32L4_RTC_BASE+STM32L4_RTC_BK23R_OFFSET) +#define STM32L4_RTC_BK24R (STM32L4_RTC_BASE+STM32L4_RTC_BK24R_OFFSET) +#define STM32L4_RTC_BK25R (STM32L4_RTC_BASE+STM32L4_RTC_BK25R_OFFSET) +#define STM32L4_RTC_BK26R (STM32L4_RTC_BASE+STM32L4_RTC_BK26R_OFFSET) +#define STM32L4_RTC_BK27R (STM32L4_RTC_BASE+STM32L4_RTC_BK27R_OFFSET) +#define STM32L4_RTC_BK28R (STM32L4_RTC_BASE+STM32L4_RTC_BK28R_OFFSET) +#define STM32L4_RTC_BK29R (STM32L4_RTC_BASE+STM32L4_RTC_BK29R_OFFSET) +#define STM32L4_RTC_BK30R (STM32L4_RTC_BASE+STM32L4_RTC_BK30R_OFFSET) +#define STM32L4_RTC_BK31R (STM32L4_RTC_BASE+STM32L4_RTC_BK31R_OFFSET) + +# define STM32L4_RTC_BKCOUNT 32 + +/* Register Bitfield Definitions ****************************************************/ + +/* RTC time register */ + +#define RTC_TR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format */ +#define RTC_TR_SU_MASK (15 << RTC_TR_SU_SHIFT) +#define RTC_TR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format */ +#define RTC_TR_ST_MASK (7 << RTC_TR_ST_SHIFT) +#define RTC_TR_MNU_SHIFT (8) /* Bit 8-11: Minute units in BCD format */ +#define RTC_TR_MNU_MASK (15 << RTC_TR_MNU_SHIFT) +#define RTC_TR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format */ +#define RTC_TR_MNT_MASK (7 << RTC_TR_MNT_SHIFT) +#define RTC_TR_HU_SHIFT (16) /* Bit 16-19: Hour units in BCD format */ +#define RTC_TR_HU_MASK (15 << RTC_TR_HU_SHIFT) +#define RTC_TR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format */ +#define RTC_TR_HT_MASK (3 << RTC_TR_HT_SHIFT) +#define RTC_TR_PM (1 << 22) /* Bit 22: AM/PM notation */ +#define RTC_TR_RESERVED_BITS (0xff808080) + +/* RTC date register */ + +#define RTC_DR_DU_SHIFT (0) /* Bits 0-3: Date units in BCD format */ +#define RTC_DR_DU_MASK (15 << RTC_DR_DU_SHIFT) +#define RTC_DR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */ +#define RTC_DR_DT_MASK (3 << RTC_DR_DT_SHIFT) +#define RTC_DR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */ +#define RTC_DR_MU_MASK (15 << RTC_DR_MU_SHIFT) +#define RTC_DR_MT (1 << 12) /* Bit 12: Month tens in BCD format */ +#define RTC_DR_WDU_SHIFT (13) /* Bits 13-15: Week day units */ +#define RTC_DR_WDU_MASK (7 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_MONDAY (1 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_TUESDAY (2 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_WEDNESDAY (3 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_THURSDAY (4 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_FRIDAY (5 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_SATURDAY (6 << RTC_DR_WDU_SHIFT) +# define RTC_DR_WDU_SUNDAY (7 << RTC_DR_WDU_SHIFT) +#define RTC_DR_YU_SHIFT (16) /* Bits 16-19: Year units in BCD format */ +#define RTC_DR_YU_MASK (15 << RTC_DR_YU_SHIFT) +#define RTC_DR_YT_SHIFT (20) /* Bits 20-23: Year tens in BCD format */ +#define RTC_DR_YT_MASK (15 << RTC_DR_YT_SHIFT) +#define RTC_DR_RESERVED_BITS (0xff0000c0) + +/* RTC control register */ + +#define RTC_CR_WUCKSEL_SHIFT (0) /* Bits 0-2: Wakeup clock selection */ +#define RTC_CR_WUCKSEL_MASK (7 << RTC_CR_WUCKSEL_SHIFT) +# define RTC_CR_WUCKSEL_RTCDIV16 (0 << RTC_CR_WUCKSEL_SHIFT) /* 000: RTC/16 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV8 (1 << RTC_CR_WUCKSEL_SHIFT) /* 001: RTC/8 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV4 (2 << RTC_CR_WUCKSEL_SHIFT) /* 010: RTC/4 clock is selected */ +# define RTC_CR_WUCKSEL_RTCDIV2 (3 << RTC_CR_WUCKSEL_SHIFT) /* 011: RTC/2 clock is selected */ +# define RTC_CR_WUCKSEL_CKSPRE (4 << RTC_CR_WUCKSEL_SHIFT) /* 10x: ck_spre clock is selected */ +# define RTC_CR_WUCKSEL_CKSPREADD (6 << RTC_CR_WUCKSEL_SHIFT) /* 11x: ck_spr clock and 216 added WUT counter */ +#define RTC_CR_TSEDGE (1 << 3) /* Bit 3: Timestamp event active edge */ +#define RTC_CR_REFCKON (1 << 4) /* Bit 4: Reference clock detection enable (50 or 60 Hz) */ +#define RTC_CR_BYPSHAD (1 << 5) /* Bit 5: Bypass the shadow registers */ +#define RTC_CR_FMT (1 << 6) /* Bit 6: Hour format */ + /* Bit 7: reserved */ +#define RTC_CR_ALRAE (1 << 8) /* Bit 8: Alarm A enable */ +#define RTC_CR_ALRBE (1 << 9) /* Bit 9: Alarm B enable */ +#define RTC_CR_WUTE (1 << 10) /* Bit 10: Wakeup timer enable */ +#define RTC_CR_TSE (1 << 11) /* Bit 11: Time stamp enable */ +#define RTC_CR_ALRAIE (1 << 12) /* Bit 12: Alarm A interrupt enable */ +#define RTC_CR_ALRBIE (1 << 13) /* Bit 13: Alarm B interrupt enable */ +#define RTC_CR_WUTIE (1 << 14) /* Bit 14: Wakeup timer interrupt enable */ +#define RTC_CR_TSIE (1 << 15) /* Bit 15: Timestamp interrupt enable */ +#define RTC_CR_ADD1H (1 << 16) /* Bit 16: Add 1 hour (summer time change) */ +#define RTC_CR_SUB1H (1 << 17) /* Bit 17: Subtract 1 hour (winter time change) */ +#define RTC_CR_BKP (1 << 18) /* Bit 18: Backup */ +#define RTC_CR_COSEL (1 << 19) /* Bit 19: Calibration output selection */ +#define RTC_CR_POL (1 << 20) /* Bit 20: Output polarity */ +#define RTC_CR_OSEL_SHIFT (21) /* Bits 21-22: Output selection */ +#define RTC_CR_OSEL_MASK (3 << RTC_CR_OSEL_SHIFT) +# define RTC_CR_OSEL_DISABLED (0 << RTC_CR_OSEL_SHIFT) /* 00: Output disabled */ +# define RTC_CR_OSEL_ALRMA (1 << RTC_CR_OSEL_SHIFT) /* 01: Alarm A output enabled */ +# define RTC_CR_OSEL_ALRMB (2 << RTC_CR_OSEL_SHIFT) /* 10: Alarm B output enabled */ +# define RTC_CR_OSEL_WUT (3 << RTC_CR_OSEL_SHIFT) /* 11: Wakeup output enabled */ +#define RTC_CR_COE (1 << 23) /* Bit 23: Calibration output enable */ +#define RTC_CR_ITSE (1 << 24) /* Bit 24: Timestamp on internal event enable */ + +/* RTC initialization and status register */ + +#define RTC_ISR_ALRAWF (1 << 0) /* Bit 0: Alarm A write flag */ +#define RTC_ISR_ALRBWF (1 << 1) /* Bit 1: Alarm B write flag */ +#define RTC_ISR_WUTWF (1 << 2) /* Bit 2: Wakeup timer write flag */ +#define RTC_ISR_SHPF (1 << 3) /* Bit 3: Shift operation pending */ +#define RTC_ISR_INITS (1 << 4) /* Bit 4: Initialization status flag */ +#define RTC_ISR_RSF (1 << 5) /* Bit 5: Registers synchronization flag */ +#define RTC_ISR_INITF (1 << 6) /* Bit 6: Initialization flag */ +#define RTC_ISR_INIT (1 << 7) /* Bit 7: Initialization mode */ +#define RTC_ISR_ALRAF (1 << 8) /* Bit 8: Alarm A flag */ +#define RTC_ISR_ALRBF (1 << 9) /* Bit 9: Alarm B flag */ +#define RTC_ISR_WUTF (1 << 10) /* Bit 10: Wakeup timer flag */ +#define RTC_ISR_TSF (1 << 11) /* Bit 11: Timestamp flag */ +#define RTC_ISR_TSOVF (1 << 12) /* Bit 12: Timestamp overflow flag */ +#define RTC_ISR_TAMP1F (1 << 13) /* Bit 13: Tamper detection flag */ +#define RTC_ISR_TAMP2F (1 << 14) /* Bit 14: TAMPER2 detection flag */ +#define RTC_ISR_TAMP3F (1 << 15) /* Bit 15: TAMPER3 detection flag */ +#define RTC_ISR_RECALPF (1 << 16) /* Bit 16: Recalibration pending Flag */ +#define RTC_ISR_ITSF (1 << 17) /* Bit 17: Recalibration pending Flag */ +#define RTC_ISR_ALLFLAGS (0x0003ffff) + +/* RTC prescaler register */ + +#define RTC_PRER_PREDIV_S_SHIFT (0) /* Bits 0-14: Synchronous prescaler factor */ +#define RTC_PRER_PREDIV_S_MASK (0x7fff << RTC_PRER_PREDIV_S_SHIFT) +#define RTC_PRER_PREDIV_A_SHIFT (16) /* Bits 16-22: Asynchronous prescaler factor */ +#define RTC_PRER_PREDIV_A_MASK (0x7f << RTC_PRER_PREDIV_A_SHIFT) + +/* RTC wakeup timer register */ + +#define RTC_WUTR_MASK (0xffff) /* Bits 15:0 Wakeup auto-reload value bits */ + +/* RTC alarm A/B registers */ + +#define RTC_ALRMR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */ +#define RTC_ALRMR_SU_MASK (15 << RTC_ALRMR_SU_SHIFT) +#define RTC_ALRMR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */ +#define RTC_ALRMR_ST_MASK (7 << RTC_ALRMR_ST_SHIFT) +#define RTC_ALRMR_MSK1 (1 << 7) /* Bit 7 : Alarm A seconds mask */ +#define RTC_ALRMR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */ +#define RTC_ALRMR_MNU_MASK (15 << RTC_ALRMR_MNU_SHIFT) +#define RTC_ALRMR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */ +#define RTC_ALRMR_MNT_MASK (7 << RTC_ALRMR_MNT_SHIFT) +#define RTC_ALRMR_MSK2 (1 << 15) /* Bit 15 : Alarm A minutes mask */ +#define RTC_ALRMR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */ +#define RTC_ALRMR_HU_MASK (15 << RTC_ALRMR_HU_SHIFT) +#define RTC_ALRMR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */ +#define RTC_ALRMR_HT_MASK (3 << RTC_ALRMR_HT_SHIFT) +#define RTC_ALRMR_PM (1 << 22) /* Bit 22 : AM/PM notation */ +#define RTC_ALRMR_MSK3 (1 << 23) /* Bit 23 : Alarm A hours mask */ +#define RTC_ALRMR_DU_SHIFT (24) /* Bits 24-27: Date units or day in BCD format. */ +#define RTC_ALRMR_DU_MASK (15 << RTC_ALRMR_DU_SHIFT) +#define RTC_ALRMR_DT_SHIFT (28) /* Bits 28-29: Date tens in BCD format. */ +#define RTC_ALRMR_DT_MASK (3 << RTC_ALRMR_DT_SHIFT) +#define RTC_ALRMR_WDSEL (1 << 30) /* Bit 30: Week day selection */ +#define RTC_ALRMR_MSK4 (1 << 31) /* Bit 31: Alarm A date mask */ + +/* RTC write protection register */ + +#define RTC_WPR_MASK (0xff) /* Bits 0-7: Write protection key */ + +/* RTC sub second register */ + +#define RTC_SSR_MASK (0xffff) /* Bits 0-15: Sub second value */ + +/* RTC shift control register */ + +#define RTC_SHIFTR_SUBFS_SHIFT (0) /* Bits 0-14: Subtract a fraction of a second */ +#define RTC_SHIFTR_SUBFS_MASK (0x7ffff << RTC_SHIFTR_SUBFS_SHIFT) +#define RTC_SHIFTR_ADD1S (1 << 31) /* Bit 31: Add one second */ + +/* RTC time stamp time register */ + +#define RTC_TSTR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */ +#define RTC_TSTR_SU_MASK (15 << RTC_TSTR_SU_SHIFT) +#define RTC_TSTR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */ +#define RTC_TSTR_ST_MASK (7 << RTC_TSTR_ST_SHIFT) +#define RTC_TSTR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */ +#define RTC_TSTR_MNU_MASK (15 << RTC_TSTR_MNU_SHIFT) +#define RTC_TSTR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */ +#define RTC_TSTR_MNT_MASK (7 << RTC_TSTR_MNT_SHIFT) +#define RTC_TSTR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */ +#define RTC_TSTR_HU_MASK (15 << RTC_TSTR_HU_SHIFT) +#define RTC_TSTR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */ +#define RTC_TSTR_HT_MASK (3 << RTC_TSTR_HT_SHIFT) +#define RTC_TSTR_PM (1 << 22) /* Bit 22: AM/PM notation */ + +/* RTC time stamp date register */ + +#define RTC_TSDR_DU_SHIFT (0) /* Bit 0-3: Date units in BCD format */ +#define RTC_TSDR_DU_MASK (15 << RTC_TSDR_DU_SHIFT) */ +#define RTC_TSDR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */ +#define RTC_TSDR_DT_MASK (3 << RTC_TSDR_DT_SHIFT) +#define RTC_TSDR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */ +#define RTC_TSDR_MU_MASK (xx << RTC_TSDR_MU_SHIFT) +#define RTC_TSDR_MT (1 << 12) /* Bit 12: Month tens in BCD format */ +#define RTC_TSDR_WDU_SHIFT (13) /* Bits 13-15: Week day units */ +#define RTC_TSDR_WDU_MASK (7 << RTC_TSDR_WDU_SHIFT) + +/* RTC timestamp sub second register */ + +#define RTC_TSSSR_MASK (0xffff) /* Bits 0-15: Sub second value */ + +/* RTC calibration register */ + +#define RTC_CALR_CALM_SHIFT (0) /* Bits 0-8: Calibration minus */ +#define RTC_CALR_CALM_MASK (0x1ff << RTC_CALR_CALM_SHIFT) +#define RTC_CALR_CALW16 (1 << 13) /* Bit 13: Use a 16-second calibration cycle period */ +#define RTC_CALR_CALW8 (1 << 14) /* Bit 14: Use an 8-second calibration cycle period */ +#define RTC_CALR_CALP (1 << 15) /* Bit 15: Increase frequency of RTC by 488.5 ppm */ + +/* RTC tamper configuration register */ + +#define RTC_TAMPCR_TAMP1E (1 << 0) /* Bit 0: RTC_TAMP1 input detection enable */ +#define RTC_TAMPCR_TAMP1TRG (1 << 1) /* Bit 1: Active level for RTC_TAMP1 input */ +#define RTC_TAMPCR_TAMPIE (1 << 2) /* Bit 2: Tamper interrupt enable */ +#define RTC_TAMPCR_TAMP2E (1 << 3) /* Bit 3: RTC_TAMP2 detection enable */ +#define RTC_TAMPCR_TAMP2TRG (1 << 4) /* Bit 4: Active level for RTC_TAMP2 input */ +#define RTC_TAMPCR_TAMP3E (1 << 5) /* Bit 5: RTC_TAMP3 detection enable */ +#define RTC_TAMPCR_TAMP3TRG (1 << 6) /* Bit 6: Active level for RTC_TAMP3 input */ +#define RTC_TAMPCR_TAMPTS (1 << 7) /* Bit 7: Activate timestamp on tamper detection event */ +#define RTC_TAMPCR_TAMPFREQ_SHIFT (8) /* Bits 8-10: Tamper sampling frequency */ +#define RTC_TAMPCR_TAMPFREQ_MASK (7 << RTC_TAMPCR_TAMPFREQ_SHIFT) +# define RTC_TAMPCR_TAMPFREQ_DIV32768 (0 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 32768 (1 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV16384 (1 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 16384 (2 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV8192 (2 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 8192 (4 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV4096 (3 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 4096 (8 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV2048 (4 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 2048 (16 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV1024 (5 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 1024 (32 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV512 (6 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 512 (64 Hz) */ +# define RTC_TAMPCR_TAMPFREQ_DIV256 (7 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 256 (128 Hz) */ +#define RTC_TAMPCR_TAMPFLT_SHIFT (11) /* Bits 11-12: RTC_TAMPx filter count */ +#define RTC_TAMPCR_TAMPFLT_MASK (3 << RTC_TAMPCR_TAMPFLT_SHIFT) +#define RTC_TAMPCR_TAMPPRCH_SHIFT (13) /* Bits 13-14: RTC_TAMPx precharge duration */ +#define RTC_TAMPCR_TAMPPRCH_MASK (3 << RTC_TAMPCR_TAMPPRCH_SHIFT) +# define RTC_TAMPCR_TAMPPRCH_1CYCLE (0 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 1 RTCCLK cycle */ +# define RTC_TAMPCR_TAMPPRCH_2CYCLES (1 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 2 RTCCLK cycles */ +# define RTC_TAMPCR_TAMPPRCH_4CYCLES (2 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 4 RTCCLK cycles */ +# define RTC_TAMPCR_TAMPPRCH_5CYCLES (3 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 8 RTCCLK cycles */ +#define RTC_TAMPCR_TAMPPUDIS (1 << 15) /* Bit 15: RTC_TAMPx pull-up disable */ +#define RTC_TAMPCR_TAMP1IE (1 << 16) /* Bit 16: RTC_TAMP1 interrupt enable */ +#define RTC_TAMPCR_TAMP1NOERASE (1 << 17) /* Bit 17: RTC_TAMP1 no erase */ +#define RTC_TAMPCR_TAMP1F (1 << 18) /* Bit 18: RTC_TAMP1 mask flag */ +#define RTC_TAMPCR_TAMP2IE (1 << 19) /* Bit 19: RTC_TAMP2 interrupt enable */ +#define RTC_TAMPCR_TAMP2NOERASE (1 << 20) /* Bit 20: RTC_TAMP2 no erase */ +#define RTC_TAMPCR_TAMP2MF (1 << 21) /* Bit 21: RTC_TAMP2 mask flag */ +#define RTC_TAMPCR_TAMP3IE (1 << 22) /* Bit 22: RTC_TAMP3 interrupt enable */ +#define RTC_TAMPCR_TAMP3NOERASE (1 << 23) /* Bit 23: RTC_TAMP3 no erase */ +#define RTC_TAMPCR_TAMP3MF (1 << 24) /* Bit 24: RTC_TAMP3 mask flag */ + +/* RTC alarm A/B sub second register */ + +#define RTC_ALRMSSR_SS_SHIFT (0) /* Bits 0-14: Sub second value */ +#define RTC_ALRMSSR_SS_MASK (0x7fff << RTC_ALRMSSR_SS_SHIFT) +#define RTC_ALRMSSR_MASKSS_SHIFT (24) /* Bits 24-27: Mask the most-significant bits starting at this bit */ +#define RTC_ALRMSSR_MASKSS_MASK (0xf << RTC_ALRMSSR_MASKSS_SHIFT) + +/* RTC option register */ + +#define RTC_OR_ALARMTYPE (1 << 0) /* Bit 0: RTC alarm type on PC13/PB14, pushpull/OD */ +#define RTC_OR_OUTRMP (1 << 1) /* Bit 1: remap output to PB14 */ + + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_RTCC_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_spi.h b/arch/arm/src/stm32l4/chip/stm32l4_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..c9a1a03ef287c9f1c0eb58a9707b01af3f763ba4 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_spi.h @@ -0,0 +1,181 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_spi.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SPI_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Maximum allowed speed as per specifications for all SPIs */ + +#if defined(CONFIG_STM32L4_STM32F40XX) +# define STM32L4_SPI_CLK_MAX 37500000UL +#else +# define STM32L4_SPI_CLK_MAX 18000000UL +#endif + +/* Register Offsets *****************************************************************/ + +#define STM32L4_SPI_CR1_OFFSET 0x0000 /* SPI Control Register 1 (16-bit) */ +#define STM32L4_SPI_CR2_OFFSET 0x0004 /* SPI control register 2 (16-bit) */ +#define STM32L4_SPI_SR_OFFSET 0x0008 /* SPI status register (16-bit) */ +#define STM32L4_SPI_DR_OFFSET 0x000c /* SPI data register (16-bit) */ +#define STM32L4_SPI_CRCPR_OFFSET 0x0010 /* SPI CRC polynomial register (16-bit) */ +#define STM32L4_SPI_RXCRCR_OFFSET 0x0014 /* SPI Rx CRC register (16-bit) */ +#define STM32L4_SPI_TXCRCR_OFFSET 0x0018 /* SPI Tx CRC register (16-bit) */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NSPI > 0 +# define STM32L4_SPI1_CR1 (STM32L4_SPI1_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI1_CR2 (STM32L4_SPI1_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI1_SR (STM32L4_SPI1_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI1_DR (STM32L4_SPI1_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI1_CRCPR (STM32L4_SPI1_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI1_RXCRCR (STM32L4_SPI1_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI1_TXCRCR (STM32L4_SPI1_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +#if STM32L4_NSPI > 1 +# define STM32L4_SPI2_CR1 (STM32L4_SPI2_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI2_CR2 (STM32L4_SPI2_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI2_SR (STM32L4_SPI2_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI2_DR (STM32L4_SPI2_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI2_CRCPR (STM32L4_SPI2_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI2_RXCRCR (STM32L4_SPI2_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI2_TXCRCR (STM32L4_SPI2_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +#if STM32L4_NSPI > 2 +# define STM32L4_SPI3_CR1 (STM32L4_SPI3_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI3_CR2 (STM32L4_SPI3_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI3_SR (STM32L4_SPI3_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI3_DR (STM32L4_SPI3_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI3_CRCPR (STM32L4_SPI3_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI3_RXCRCR (STM32L4_SPI3_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI3_TXCRCR (STM32L4_SPI3_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* SPI Control Register 1 */ + +#define SPI_CR1_CPHA (1 << 0) /* Bit 0: Clock Phase */ +#define SPI_CR1_CPOL (1 << 1) /* Bit 1: Clock Polarity */ +#define SPI_CR1_MSTR (1 << 2) /* Bit 2: Master Selection */ +#define SPI_CR1_BR_SHIFT (3) /* Bits 5:3 Baud Rate Control */ +#define SPI_CR1_BR_MASK (7 << SPI_CR1_BR_SHIFT) +# define SPI_CR1_FPCLCKd2 (0 << SPI_CR1_BR_SHIFT) /* 000: fPCLK/2 */ +# define SPI_CR1_FPCLCKd4 (1 << SPI_CR1_BR_SHIFT) /* 001: fPCLK/4 */ +# define SPI_CR1_FPCLCKd8 (2 << SPI_CR1_BR_SHIFT) /* 010: fPCLK/8 */ +# define SPI_CR1_FPCLCKd16 (3 << SPI_CR1_BR_SHIFT) /* 011: fPCLK/16 */ +# define SPI_CR1_FPCLCKd32 (4 << SPI_CR1_BR_SHIFT) /* 100: fPCLK/32 */ +# define SPI_CR1_FPCLCKd64 (5 << SPI_CR1_BR_SHIFT) /* 101: fPCLK/64 */ +# define SPI_CR1_FPCLCKd128 (6 << SPI_CR1_BR_SHIFT) /* 110: fPCLK/128 */ +# define SPI_CR1_FPCLCKd256 (7 << SPI_CR1_BR_SHIFT) /* 111: fPCLK/256 */ +#define SPI_CR1_SPE (1 << 6) /* Bit 6: SPI Enable */ +#define SPI_CR1_LSBFIRST (1 << 7) /* Bit 7: Frame Format */ +#define SPI_CR1_SSI (1 << 8) /* Bit 8: Internal slave select */ +#define SPI_CR1_SSM (1 << 9) /* Bit 9: Software slave management */ +#define SPI_CR1_RXONLY (1 << 10) /* Bit 10: Receive only */ +#define SPI_CR1_CRCL (1 << 11) /* Bit 11: CRC length */ +#define SPI_CR1_CRCNEXT (1 << 12) /* Bit 12: Transmit CRC next */ +#define SPI_CR1_CRCEN (1 << 13) /* Bit 13: Hardware CRC calculation enable */ +#define SPI_CR1_BIDIOE (1 << 14) /* Bit 14: Output enable in bidirectional mode */ +#define SPI_CR1_BIDIMODE (1 << 15) /* Bit 15: Bidirectional data mode enable */ + +/* SPI Control Register 2 */ + +#define SPI_CR2_RXDMAEN (1 << 0) /* Bit 0: Rx Buffer DMA Enable */ +#define SPI_CR2_TXDMAEN (1 << 1) /* Bit 1: Tx Buffer DMA Enable */ +#define SPI_CR2_SSOE (1 << 2) /* Bit 2: SS Output Enable */ +#define SPI_CR2_NSSP (1 << 3) /* Bit 3: NSS pulse management */ +#define SPI_CR2_FRF (1 << 4) /* Bit 4: Frame format */ +#define SPI_CR2_ERRIE (1 << 5) /* Bit 5: Error interrupt enable */ +#define SPI_CR2_RXNEIE (1 << 6) /* Bit 6: RX buffer not empty interrupt enable */ +#define SPI_CR2_TXEIE (1 << 7) /* Bit 7: Tx buffer empty interrupt enable */ +#define SPI_CR2_DS_SHIFT (8) /* Bits 8-11: Data size */ +#define SPI_CR2_DS_MASK (15 << SPI_CR2_DS_SHIFT) +# define SPI_CR2_DS_VAL(bits) ( ((bits)-1) << SPI_CR2_DS_SHIFT) +# define SPI_CR2_DS_4BIT SPI_CR2_DS_VAL( 4) +# define SPI_CR2_DS_5BIT SPI_CR2_DS_VAL( 5) +# define SPI_CR2_DS_6BIT SPI_CR2_DS_VAL( 6) +# define SPI_CR2_DS_7BIT SPI_CR2_DS_VAL( 7) +# define SPI_CR2_DS_8BIT SPI_CR2_DS_VAL( 8) +# define SPI_CR2_DS_9BIT SPI_CR2_DS_VAL( 9) +# define SPI_CR2_DS_10BIT SPI_CR2_DS_VAL(10) +# define SPI_CR2_DS_11BIT SPI_CR2_DS_VAL(11) +# define SPI_CR2_DS_12BIT SPI_CR2_DS_VAL(12) +# define SPI_CR2_DS_13BIT SPI_CR2_DS_VAL(13) +# define SPI_CR2_DS_14BIT SPI_CR2_DS_VAL(14) +# define SPI_CR2_DS_15BIT SPI_CR2_DS_VAL(15) +# define SPI_CR2_DS_16BIT SPI_CR2_DS_VAL(16) +#define SPI_CR2_FRXTH (1 << 12) /* Bit 12: FIFO reception threshold */ +#define SPI_CR2_LDMARX (1 << 13) /* Bit 13: Last DMA transfer for receptione */ +#define SPI_CR2_LDMATX (1 << 14) /* Bit 14: Last DMA transfer for transmission */ + +/* SPI status register */ + +#define SPI_SR_RXNE (1 << 0) /* Bit 0: Receive buffer not empty */ +#define SPI_SR_TXE (1 << 1) /* Bit 1: Transmit buffer empty */ +#define SPI_SR_CRCERR (1 << 4) /* Bit 4: CRC error flag */ +#define SPI_SR_MODF (1 << 5) /* Bit 5: Mode fault */ +#define SPI_SR_OVR (1 << 6) /* Bit 6: Overrun flag */ +#define SPI_SR_BSY (1 << 7) /* Bit 7: Busy flag */ +#define SPI_SR_FRE (1 << 8) /* Bit 8: Frame format error */ +#define SPI_SR_FRLVL_SHIFT (9) /* Bits 9-10: FIFO reception level */ +#define SPI_SR_FRLVL_MASK (3 << SPI_SR_FRLVL_SHIFT) +# define SPI_SR_FRLVL_EMPTY (0 << SPI_SR_FRLVL_SHIFT) /* FIFO empty */ +# define SPI_SR_FRLVL_QUARTER (1 << SPI_SR_FRLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_SR_FRLVL_HALF (2 << SPI_SR_FRLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_SR_FRLVL_FULL (3 << SPI_SR_FRLVL_SHIFT) /* FIFO full */ +#define SPI_SR_FTLVL_SHIFT (11) /* Bits 11-12: FIFO transmission level */ +#define SPI_SR_FTLVL_MASK (3 << SPI_SR_FTLVL_SHIFT) +# define SPI_SR_FTLVL_EMPTY (0 << SPI_SR_FTLVL_SHIFT) /* FIFO empty */ +# define SPI_SR_FTLVL_QUARTER (1 << SPI_SR_FTLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_SR_FTLVL_HALF (2 << SPI_SR_FTLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_SR_FTLVL_FULL (3 << SPI_SR_FTLVL_SHIFT) /* FIFO full */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SPI_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..2e34974769cf260f364654379be48c3ff55bd234 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h @@ -0,0 +1,184 @@ +/**************************************************************************************************** + * arch/arm/src/stm32l4/chip/stm32l4_syscfg.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32L4_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32L4_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */ +#define STM32L4_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32L4_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32L4_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32L4_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32L4_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ +#define STM32L4_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */ +#define STM32L4_SYSCFG_CFGR2_OFFSET 0x001c /* SYSCFG configuration register 2 */ +#define STM32L4_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */ +#define STM32L4_SYSCFG_SKR_OFFSET 0x0024 /* SYSCFG SRAM2 key register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32L4_SYSCFG_MEMRMP (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_MEMRMP_OFFSET) +#define STM32L4_SYSCFG_CFGR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR1_OFFSET) +#define STM32L4_SYSCFG_EXTICR(p) (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR_OFFSET(p)) +#define STM32L4_SYSCFG_EXTICR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR1_OFFSET) +#define STM32L4_SYSCFG_EXTICR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR2_OFFSET) +#define STM32L4_SYSCFG_EXTICR3 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR3_OFFSET) +#define STM32L4_SYSCFG_EXTICR4 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR4_OFFSET) +#define STM32L4_SYSCFG_SCSR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SCSR_OFFSET) +#define STM32L4_SYSCFG_CFGR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR2_OFFSET) +#define STM32L4_SYSCFG_SWPR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR_OFFSET) +#define STM32L4_SYSCFG_SKR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SKR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 2:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_MEMRMP_MASK (7 << SYSCFG_MEMRMP_SHIFT) +# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 000: Main Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 001: System Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_FMC (2 << SYSCFG_MEMRMP_SHIFT) /* 010: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 011: SRAM1 (112kB) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_QSPI (6 << SYSCFG_MEMRMP_SHIFT) /* 110: QUADSPI mapped at 0x0000 0000 */ +#define SYSCFG_FBMODE (1 << 8) /* Bit 8: Flash Bank mode selection */ + +/* SYSCFG configuration register 1 */ + +#define SYSCFG_CFGR1_FWDIS (1 << 0) /* Bit 0: Firewall disable */ +#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */ +#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */ +#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */ +#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */ +#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */ +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_FPU_IE0 (1 << 26) /* Bit 26: FPU Invalid operation interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE1 (1 << 27) /* Bit 27: FPU Divide-by-zero interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE2 (1 << 28) /* Bit 28: FPU Underflow interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE3 (1 << 29) /* Bit 29: FPU Overflow interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE4 (1 << 30) /* Bit 30: FPU Input denormal interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE5 (1 << 31) /* Bit 31: FPU Inexact interrupt enable */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (7) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-2: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-6: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-10: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-14: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-2: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-6: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-10: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-14: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-2: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-6: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-10: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-14: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-2: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-6: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-10: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-14: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* SYSCFG SRAM2 control and status register */ + +#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */ +#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */ + +/* SYSCFG configuration register 2 */ + +#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M4 LOCKUP (Hardfault) output enable (TIMx break enable, see refman) */ +#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock enable (same) */ +#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable (same) */ +#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock enable (same) */ +#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */ + +/* SYSCFG SRAM2 write protection register */ +/* There is one bit per SRAM2 page */ + +/* SYSCFG SRAM2 key register */ + +#define SYSCFG_SKR_SHIFT 0 +#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT) + +#endif /* CONFIG_STM32L4_STM32L476XX || CONFIG_STM32L4_STM32L486XX */ +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..c0d136150fac799cc7b3b19aad1c40991f2a972a --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h @@ -0,0 +1,480 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_DMA_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_DMA_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* These definitions apply to both the STM32 F1 and F3 families */ +/* 12 Channels Total: 7 DMA1 Channels(1-7) and 5 DMA2 channels (1-5) */ + +#define DMA1 0 +#define DMA2 1 +#define DMA3 2 +#define DMA4 3 +#define DMA5 4 +#define DMA6 5 +#define DMA7 6 + +/* Register Offsets *****************************************************************/ + +#define STM32L4_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */ +#define STM32L4_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */ + +#define STM32L4_DMACHAN_OFFSET(n) (0x0014*(n)) +#define STM32L4_DMACHAN1_OFFSET 0x0000 +#define STM32L4_DMACHAN2_OFFSET 0x0014 +#define STM32L4_DMACHAN3_OFFSET 0x0028 +#define STM32L4_DMACHAN4_OFFSET 0x003c +#define STM32L4_DMACHAN5_OFFSET 0x0050 +#define STM32L4_DMACHAN6_OFFSET 0x0064 +#define STM32L4_DMACHAN7_OFFSET 0x0078 + +#define STM32L4_DMACHAN_CCR_OFFSET 0x0008 /* DMA channel configuration register */ +#define STM32L4_DMACHAN_CNDTR_OFFSET 0x000c /* DMA channel number of data register */ +#define STM32L4_DMACHAN_CPAR_OFFSET 0x0010 /* DMA channel peripheral address register */ +#define STM32L4_DMACHAN_CMAR_OFFSET 0x0014 /* DMA channel memory address register */ + +#define STM32L4_DMA_CCR_OFFSET(n) (STM32L4_DMACHAN_CCR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CNDTR_OFFSET(n) (STM32L4_DMACHAN_CNDTR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CPAR_OFFSET(n) (STM32L4_DMACHAN_CPAR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CMAR_OFFSET(n) (STM32L4_DMACHAN_CMAR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) + +#define STM32L4_DMA_CCR1_OFFSET 0x0008 /* DMA channel 1 configuration register */ +#define STM32L4_DMA_CCR2_OFFSET 0x001c /* DMA channel 2 configuration register */ +#define STM32L4_DMA_CCR3_OFFSET 0x0030 /* DMA channel 3 configuration register */ +#define STM32L4_DMA_CCR4_OFFSET 0x0044 /* DMA channel 4 configuration register */ +#define STM32L4_DMA_CCR5_OFFSET 0x0058 /* DMA channel 5 configuration register */ +#define STM32L4_DMA_CCR6_OFFSET 0x006c /* DMA channel 6 configuration register */ +#define STM32L4_DMA_CCR7_OFFSET 0x0080 /* DMA channel 7 configuration register */ + +#define STM32L4_DMA_CNDTR1_OFFSET 0x000c /* DMA channel 1 number of data register */ +#define STM32L4_DMA_CNDTR2_OFFSET 0x0020 /* DMA channel 2 number of data register */ +#define STM32L4_DMA_CNDTR3_OFFSET 0x0034 /* DMA channel 3 number of data register */ +#define STM32L4_DMA_CNDTR4_OFFSET 0x0048 /* DMA channel 4 number of data register */ +#define STM32L4_DMA_CNDTR5_OFFSET 0x005c /* DMA channel 5 number of data register */ +#define STM32L4_DMA_CNDTR6_OFFSET 0x0070 /* DMA channel 6 number of data register */ +#define STM32L4_DMA_CNDTR7_OFFSET 0x0084 /* DMA channel 7 number of data register */ + +#define STM32L4_DMA_CPAR1_OFFSET 0x0010 /* DMA channel 1 peripheral address register */ +#define STM32L4_DMA_CPAR2_OFFSET 0x0024 /* DMA channel 2 peripheral address register */ +#define STM32L4_DMA_CPAR3_OFFSET 0x0038 /* DMA channel 3 peripheral address register */ +#define STM32L4_DMA_CPAR4_OFFSET 0x004c /* DMA channel 4 peripheral address register */ +#define STM32L4_DMA_CPAR5_OFFSET 0x0060 /* DMA channel 5 peripheral address register */ +#define STM32L4_DMA_CPAR6_OFFSET 0x0074 /* DMA channel 6 peripheral address register */ +#define STM32L4_DMA_CPAR7_OFFSET 0x0088 /* DMA channel 7 peripheral address register */ + +#define STM32L4_DMA_CMAR1_OFFSET 0x0014 /* DMA channel 1 memory address register */ +#define STM32L4_DMA_CMAR2_OFFSET 0x0028 /* DMA channel 2 memory address register */ +#define STM32L4_DMA_CMAR3_OFFSET 0x003c /* DMA channel 3 memory address register */ +#define STM32L4_DMA_CMAR4_OFFSET 0x0050 /* DMA channel 4 memory address register */ +#define STM32L4_DMA_CMAR5_OFFSET 0x0064 /* DMA channel 5 memory address register */ +#define STM32L4_DMA_CMAR6_OFFSET 0x0078 /* DMA channel 6 memory address register */ +#define STM32L4_DMA_CMAR7_OFFSET 0x008c /* DMA channel 7 memory address register */ + +#define STM32L4_DMA_CSELR_OFFSET 0x00a8 /* DMA channel selection register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_DMA1_ISRC (STM32L4_DMA1_BASE+STM32L4_DMA_ISR_OFFSET) +#define STM32L4_DMA1_IFCR (STM32L4_DMA1_BASE+STM32L4_DMA_IFCR_OFFSET) + +#define STM32L4_DMA1_CCR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CCR_OFFSET(n)) +#define STM32L4_DMA1_CCR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR1_OFFSET) +#define STM32L4_DMA1_CCR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR2_OFFSET) +#define STM32L4_DMA1_CCR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR3_OFFSET) +#define STM32L4_DMA1_CCR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR4_OFFSET) +#define STM32L4_DMA1_CCR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR5_OFFSET) +#define STM32L4_DMA1_CCR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR6_OFFSET) +#define STM32L4_DMA1_CCR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR7_OFFSET) + +#define STM32L4_DMA1_CNDTR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR_OFFSET(n)) +#define STM32L4_DMA1_CNDTR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR1_OFFSET) +#define STM32L4_DMA1_CNDTR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR2_OFFSET) +#define STM32L4_DMA1_CNDTR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR3_OFFSET) +#define STM32L4_DMA1_CNDTR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR4_OFFSET) +#define STM32L4_DMA1_CNDTR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR5_OFFSET) +#define STM32L4_DMA1_CNDTR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR6_OFFSET) +#define STM32L4_DMA1_CNDTR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR7_OFFSET) + +#define STM32L4_DMA1_CPAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR_OFFSET(n)) +#define STM32L4_DMA1_CPAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR1_OFFSET) +#define STM32L4_DMA1_CPAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR2_OFFSET) +#define STM32L4_DMA1_CPAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR3_OFFSET) +#define STM32L4_DMA1_CPAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR4_OFFSET) +#define STM32L4_DMA1_CPAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR5_OFFSET) +#define STM32L4_DMA1_CPAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR6_OFFSET) +#define STM32L4_DMA1_CPAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR7_OFFSET) + +#define STM32L4_DMA1_CMAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR_OFFSET(n)) +#define STM32L4_DMA1_CMAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR1_OFFSET) +#define STM32L4_DMA1_CMAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR2_OFFSET) +#define STM32L4_DMA1_CMAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR3_OFFSET) +#define STM32L4_DMA1_CMAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR4_OFFSET) +#define STM32L4_DMA1_CMAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR5_OFFSET) +#define STM32L4_DMA1_CMAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR6_OFFSET) +#define STM32L4_DMA1_CMAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR7_OFFSET) + +#define STM32L4_DMA2_ISRC (STM32L4_DMA2_BASE+STM32L4_DMA_ISR_OFFSET) +#define STM32L4_DMA2_IFCR (STM32L4_DMA2_BASE+STM32L4_DMA_IFCR_OFFSET) + +#define STM32L4_DMA2_CCR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CCR_OFFSET(n)) +#define STM32L4_DMA2_CCR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR1_OFFSET) +#define STM32L4_DMA2_CCR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR2_OFFSET) +#define STM32L4_DMA2_CCR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR3_OFFSET) +#define STM32L4_DMA2_CCR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR4_OFFSET) +#define STM32L4_DMA2_CCR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR5_OFFSET) + +#define STM32L4_DMA2_CNDTR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR_OFFSET(n)) +#define STM32L4_DMA2_CNDTR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR1_OFFSET) +#define STM32L4_DMA2_CNDTR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR2_OFFSET) +#define STM32L4_DMA2_CNDTR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR3_OFFSET) +#define STM32L4_DMA2_CNDTR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR4_OFFSET) +#define STM32L4_DMA2_CNDTR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR5_OFFSET) + +#define STM32L4_DMA2_CPAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR_OFFSET(n)) +#define STM32L4_DMA2_CPAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR1_OFFSET) +#define STM32L4_DMA2_CPAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR2_OFFSET) +#define STM32L4_DMA2_CPAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR3_OFFSET) +#define STM32L4_DMA2_CPAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR4_OFFSET) +#define STM32L4_DMA2_CPAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR5_OFFSET) + +#define STM32L4_DMA2_CMAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR_OFFSET(n)) +#define STM32L4_DMA2_CMAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR1_OFFSET) +#define STM32L4_DMA2_CMAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR2_OFFSET) +#define STM32L4_DMA2_CMAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR3_OFFSET) +#define STM32L4_DMA2_CMAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR4_OFFSET) +#define STM32L4_DMA2_CMAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR5_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_CHAN_SHIFT(n) ((n) << 2) +#define DMA_CHAN_MASK 0x0f +#define DMA_CHAN_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */ +#define DMA_CHAN_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */ +#define DMA_CHAN_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */ +#define DMA_CHAN_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */ + +/* DMA interrupt status register */ + +#define DMA_ISR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_ISR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */ +#define DMA_ISR_CHAN1_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN1_SHIFT) +#define DMA_ISR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */ +#define DMA_ISR_CHAN2_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN2_SHIFT) +#define DMA_ISR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */ +#define DMA_ISR_CHAN3_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN3_SHIFT) +#define DMA_ISR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */ +#define DMA_ISR_CHAN4_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN4_SHIFT) +#define DMA_ISR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */ +#define DMA_ISR_CHAN5_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN5_SHIFT) +#define DMA_ISR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */ +#define DMA_ISR_CHAN6_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN6_SHIFT) +#define DMA_ISR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */ +#define DMA_ISR_CHAN7_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN7_SHIFT) + +#define DMA_ISR_GIF(n) (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TCIF(n) (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_HTIF(n) (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TEIF(n) (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n)) + +/* DMA interrupt flag clear register */ + +#define DMA_IFCR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_IFCR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt flag clear */ +#define DMA_IFCR_CHAN1_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN1_SHIFT) +#define DMA_IFCR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt flag clear */ +#define DMA_IFCR_CHAN2_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN2_SHIFT) +#define DMA_IFCR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt flag clear */ +#define DMA_IFCR_CHAN3_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN3_SHIFT) +#define DMA_IFCR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt flag clear */ +#define DMA_IFCR_CHAN4_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN4_SHIFT) +#define DMA_IFCR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt flag clear */ +#define DMA_IFCR_CHAN5_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN5_SHIFT) +#define DMA_IFCR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt flag clear */ +#define DMA_IFCR_CHAN6_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN6_SHIFT) +#define DMA_IFCR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt flag clear */ +#define DMA_IFCR_CHAN7_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN7_SHIFT) +#define DMA_IFCR_ALLCHANNELS (0x0fffffff) + +#define DMA_IFCR_CGIF(n) (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTCIF(n) (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHTIF(n) (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTEIF(n) (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) + +/* DMA channel configuration register */ + +#define DMA_CCR_EN (1 << 0) /* Bit 0: Channel enable */ +#define DMA_CCR_TCIE (1 << 1) /* Bit 1: Transfer complete interrupt enable */ +#define DMA_CCR_HTIE (1 << 2) /* Bit 2: Half Transfer interrupt enable */ +#define DMA_CCR_TEIE (1 << 3) /* Bit 3: Transfer error interrupt enable */ +#define DMA_CCR_DIR (1 << 4) /* Bit 4: Data transfer direction */ +#define DMA_CCR_CIRC (1 << 5) /* Bit 5: Circular mode */ +#define DMA_CCR_PINC (1 << 6) /* Bit 6: Peripheral increment mode */ +#define DMA_CCR_MINC (1 << 7) /* Bit 7: Memory increment mode */ +#define DMA_CCR_PSIZE_SHIFT (8) /* Bits 8-9: Peripheral size */ +#define DMA_CCR_PSIZE_MASK (3 << DMA_CCR_PSIZE_SHIFT) +# define DMA_CCR_PSIZE_8BITS (0 << DMA_CCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_PSIZE_16BITS (1 << DMA_CCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_PSIZE_32BITS (2 << DMA_CCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_MSIZE_SHIFT (10) /* Bits 10-11: Memory size */ +#define DMA_CCR_MSIZE_MASK (3 << DMA_CCR_MSIZE_SHIFT) +# define DMA_CCR_MSIZE_8BITS (0 << DMA_CCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_MSIZE_16BITS (1 << DMA_CCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_MSIZE_32BITS (2 << DMA_CCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_PL_SHIFT (12) /* Bits 12-13: Channel Priority level */ +#define DMA_CCR_PL_MASK (3 << DMA_CCR_PL_SHIFT) +# define DMA_CCR_PRILO (0 << DMA_CCR_PL_SHIFT) /* 00: Low */ +# define DMA_CCR_PRIMED (1 << DMA_CCR_PL_SHIFT) /* 01: Medium */ +# define DMA_CCR_PRIHI (2 << DMA_CCR_PL_SHIFT) /* 10: High */ +# define DMA_CCR_PRIVERYHI (3 << DMA_CCR_PL_SHIFT) /* 11: Very high */ +#define DMA_CCR_MEM2MEM (1 << 14) /* Bit 14: Memory to memory mode */ + +#define DMA_CCR_ALLINTS (DMA_CCR_TEIE|DMA_CCR_HTIE|DMA_CCR_TCIE) + +/* DMA channel number of data register */ + +#define DMA_CNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_CNDTR_NDT_MASK (0xffff << DMA_CNDTR_NDT_SHIFT) + +/* DMA Channel mapping. Each DMA channel has a mapping to one of several + * possible sources/sinks of data. The requests from peripherals assigned to a + * channel are multiplexed together before entering the DMA block. This means + * that only one request on a given channel can be enabled at once. + * + * Alternative DMA channel selections are provided with a numeric suffix like _1, + * _2, etc. Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. + */ + +#define STM32L4_DMA1_CHAN1 (0) +#define STM32L4_DMA1_CHAN2 (1) +#define STM32L4_DMA1_CHAN3 (2) +#define STM32L4_DMA1_CHAN4 (3) +#define STM32L4_DMA1_CHAN5 (4) +#define STM32L4_DMA1_CHAN6 (5) +#define STM32L4_DMA1_CHAN7 (6) + +#define STM32L4_DMA2_CHAN1 (7) +#define STM32L4_DMA2_CHAN2 (8) +#define STM32L4_DMA2_CHAN3 (9) +#define STM32L4_DMA2_CHAN4 (10) +#define STM32L4_DMA2_CHAN5 (11) +#define STM32L4_DMA2_CHAN6 (12) +#define STM32L4_DMA2_CHAN7 (13) + +#define DMACHAN_SETTING(chan, sel) ( ( ( (sel) & 0xff) << 8) | ( (chan) & 0xff) ) +#define DMACHAN_SETTING_CHANNEL_MASK 0x00FF +#define DMACHAN_SETTING_CHANNEL_SHIFT (0) +#define DMACHAN_SETTING_FUNCTION_MASK 0xFF00 +#define DMACHAN_SETTING_FUNCTION_SHIFT (8) + +/* ADC */ + +#define DMACHAN_ADC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_ADC1_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 0) + +#define DMACHAN_ADC2_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_ADC2_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 0) + +#define DMACHAN_ADC3_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_ADC3_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 0) + +/* AES */ + +#define DMACHAN_AES_IN_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 6) +#define DMACHAN_AES_IN_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 6) +#define DMACHAN_AES_OUT_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 6) +#define DMACHAN_AES_OUT_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 6) + +/* DAC */ + +#define DMACHAN_DAC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6) +#define DMACHAN_DAC1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5) +#define DMACHAN_DAC1_3 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3) + +#define DMACHAN_DAC2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 3) + +/* DFSDM */ + +#define DMACHAN_DFSDM0 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 0) +#define DMACHAN_DFSDM1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 0) +#define DMACHAN_DFSDM2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 0) +#define DMACHAN_DFSDM3 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 0) + +/* I2C */ + +#define DMACHAN_I2C1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 3) +#define DMACHAN_I2C1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 5) +#define DMACHAN_I2C1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 3) +#define DMACHAN_I2C1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 5) + +#define DMACHAN_I2C2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 3) +#define DMACHAN_I2C2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 3) + +#define DMACHAN_I2C3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 2) +#define DMACHAN_I2C3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 3) + +/* QUADSPI */ + +#define DMACHAN_QUADSPI_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 5) +#define DMACHAN_QUADSPI_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 3) + +/* SAI */ + +#define DMACHAN_SAI1_A_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 1) +#define DMACHAN_SAI1_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 1) +#define DMACHAN_SAI1_B_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 1) +#define DMACHAN_SAI1_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 1) + +#define DMACHAN_SAI2_A_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 1) +#define DMACHAN_SAI2_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 1) +#define DMACHAN_SAI2_B_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 1) +#define DMACHAN_SAI2_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 1) + +/* SDMMC */ + +#define DMACHAN_SDMMC_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 7) +#define DMACHAN_SDMMC_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 7) + +/* SPI */ + +#define DMACHAN_SPI1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 1) +#define DMACHAN_SPI1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 4) +#define DMACHAN_SPI1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 0) +#define DMACHAN_SPI1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 4) + +#define DMACHAN_SPI2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 1) +#define DMACHAN_SPI2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 1) + +#define DMACHAN_SPI3_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 3) +#define DMACHAN_SPI3_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 3) + +/* SWPMI */ + +#define DMACHAN_SWPMI_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 4) +#define DMACHAN_SWPMI_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 4) + +/* TIM */ + +#define DMACHAN_TIM1_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 7) +#define DMACHAN_TIM1_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 7) +#define DMACHAN_TIM1_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 7) +#define DMACHAN_TIM1_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) +#define DMACHAN_TIM1_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) +#define DMACHAN_TIM1_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) +#define DMACHAN_TIM1_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 7) + +#define DMACHAN_TIM2_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 4) +#define DMACHAN_TIM2_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4) +#define DMACHAN_TIM2_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 4) +#define DMACHAN_TIM2_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4) +#define DMACHAN_TIM2_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 4) + +#define DMACHAN_TIM3_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5) +#define DMACHAN_TIM3_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 5) +#define DMACHAN_TIM3_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5) +#define DMACHAN_TIM3_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5) +#define DMACHAN_TIM3_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5) + +#define DMACHAN_TIM4_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 6) +#define DMACHAN_TIM4_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 6) +#define DMACHAN_TIM4_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 6) +#define DMACHAN_TIM4_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 6) + +#define DMACHAN_TIM5_CH1 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 5) +#define DMACHAN_TIM5_CH2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 5) +#define DMACHAN_TIM5_CH3 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 5) +#define DMACHAN_TIM5_CH4 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_TIM5_COM DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_TIM5_TRIG DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_TIM5_UP DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 5) + +#define DMACHAN_TIM6_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6) +#define DMACHAN_TIM6_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3) + +#define DMACHAN_TIM7_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5) +#define DMACHAN_TIM7_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 3) + +#define DMACHAN_TIM8_CH1 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 7) +#define DMACHAN_TIM8_CH2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 7) +#define DMACHAN_TIM8_CH3 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 7) +#define DMACHAN_TIM8_CH4 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) +#define DMACHAN_TIM8_COM DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) +#define DMACHAN_TIM8_TRIG DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) +#define DMACHAN_TIM8_UP DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 7) + +#define DMACHAN_TIM15_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) + +#define DMACHAN_TIM16_CH1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4) +#define DMACHAN_TIM16_CH1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4) +#define DMACHAN_TIM16_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4) +#define DMACHAN_TIM16_UP_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4) + +#define DMACHAN_TIM17_CH1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 5) +#define DMACHAN_TIM17_CH1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 5) +#define DMACHAN_TIM17_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 5) +#define DMACHAN_TIM17_UP_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 5) + +/* UART */ + +#define DMACHAN_USART1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 2) +#define DMACHAN_USART1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 2) +#define DMACHAN_USART1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 2) +#define DMACHAN_USART1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 2) + +#define DMACHAN_USART2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 2) +#define DMACHAN_USART2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 2) + +#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1) +#define DMACHAN_USART3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 2) + +#define DMACHAN_UART5_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 2) +#define DMACHAN_UART5_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 2) + +#define DMACHAN_UART4_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 2) +#define DMACHAN_UART4_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 2) + +#define DMACHAN_LPUART_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 4) +#define DMACHAN_LPUART_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 4) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_DMA_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h new file mode 100644 index 0000000000000000000000000000000000000000..e0471567fec6ac6c73edd4ddb75aa1d3f03f7a96 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h @@ -0,0 +1,104 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_FIREWALL_CSSA_OFFSET 0x0000 +#define STM32L4_FIREWALL_CSL_OFFSET 0x0004 +#define STM32L4_FIREWALL_NVDSSA_OFFSET 0x0008 +#define STM32L4_FIREWALL_NVDSL_OFFSET 0x000C +#define STM32L4_FIREWALL_VDSSA_OFFSET 0x0010 +#define STM32L4_FIREWALL_VDSL_OFFSET 0x0014 +#define STM32L4_FIREWALL_CR_OFFSET 0x0020 + +/* Register Addresses ***************************************************************/ + +#define STM32L4_FIREWALL_CSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSSA_OFFSET) +#define STM32L4_FIREWALL_CSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSL_OFFSET) +#define STM32L4_FIREWALL_NVDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSSA_OFFSET) +#define STM32L4_FIREWALL_NVDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSL_OFFSET) +#define STM32L4_FIREWALL_VDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSSA_OFFSET) +#define STM32L4_FIREWALL_VDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSL_OFFSET) +#define STM32L4_FIREWALL_CR (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Code Segment Start Address */ +#define FIREWALL_CSSADD_SHIFT 8 +#define FIREWALL_CSSADD_MASK (0xFFFF << FIREWALL_CSSADD_SHIFT) + +/* Code Segment Length */ +#define FIREWALL_CSSLENG_SHIFT 8 +#define FIREWALL_CSSLENG_MASK (0x3FFF << FIREWALL_CSSLENG_SHIFT) + +/* Non-volatile Data Segment Start Address */ +#define FIREWALL_NVDSADD_SHIFT 8 +#define FIREWALL_NVDSADD_MASK (0xFFFF << FIREWALL_NVDSADD_SHIFT) + +/* Non-volatile Data Segment Length */ +#define FIREWALL_NVDSLENG_SHIFT 8 +#define FIREWALL_NVDSLENG_MASK (0x3FFF << FIREWALL_NVDSLENG_SHIFT) + +/* Volatile Data Segment Start Address */ +#define FIREWALL_VDSADD_SHIFT 6 +#define FIREWALL_VDSADD_MASK (0x07FF << FIREWALL_VDSADD_SHIFT) + +/* Volatile Data Segment Length */ +#define FIREWALL_VDSLENG_SHIFT 6 +#define FIREWALL_VDSLENG_MASK (0x07FF << FIREWALL_VDSLENG_SHIFT) + +/* Configuration Register */ +#define FIREWALL_CR_FPA (1 << 0) /* Bit 0: Firewall prearm */ +#define FIREWALL_CR_VDS (1 << 1) /* Bit 1: Volatile data shared */ +#define FIREWALL_CR_VDE (1 << 2) /* Bit 2: Volatile data execution */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..2e72915e82b8b8d9e73a7b934739c793e5773d07 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h @@ -0,0 +1,362 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h + * + * Copyright (C) 2016, Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32L4_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32L4_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32L4_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32L4_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32L4_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32L4_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32L4_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32L4_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32L4_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NPORTS > 0 +# define STM32L4_GPIOA_MODER (STM32L4_GPIOA_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOA_OTYPER (STM32L4_GPIOA_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOA_OSPEED (STM32L4_GPIOA_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOA_PUPDR (STM32L4_GPIOA_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOA_IDR (STM32L4_GPIOA_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOA_ODR (STM32L4_GPIOA_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOA_BSRR (STM32L4_GPIOA_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOA_LCKR (STM32L4_GPIOA_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOA_AFRL (STM32L4_GPIOA_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOA_AFRH (STM32L4_GPIOA_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 1 +# define STM32L4_GPIOB_MODER (STM32L4_GPIOB_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOB_OTYPER (STM32L4_GPIOB_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOB_OSPEED (STM32L4_GPIOB_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOB_PUPDR (STM32L4_GPIOB_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOB_IDR (STM32L4_GPIOB_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOB_ODR (STM32L4_GPIOB_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOB_BSRR (STM32L4_GPIOB_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOB_LCKR (STM32L4_GPIOB_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOB_AFRL (STM32L4_GPIOB_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOB_AFRH (STM32L4_GPIOB_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 2 +# define STM32L4_GPIOC_MODER (STM32L4_GPIOC_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOC_OTYPER (STM32L4_GPIOC_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOC_OSPEED (STM32L4_GPIOC_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOC_PUPDR (STM32L4_GPIOC_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOC_IDR (STM32L4_GPIOC_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOC_ODR (STM32L4_GPIOC_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOC_BSRR (STM32L4_GPIOC_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOC_LCKR (STM32L4_GPIOC_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOC_AFRL (STM32L4_GPIOC_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOC_AFRH (STM32L4_GPIOC_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 3 +# define STM32L4_GPIOD_MODER (STM32L4_GPIOD_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOD_OTYPER (STM32L4_GPIOD_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOD_OSPEED (STM32L4_GPIOD_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOD_PUPDR (STM32L4_GPIOD_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOD_IDR (STM32L4_GPIOD_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOD_ODR (STM32L4_GPIOD_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOD_BSRR (STM32L4_GPIOD_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOD_LCKR (STM32L4_GPIOD_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOD_AFRL (STM32L4_GPIOD_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOD_AFRH (STM32L4_GPIOD_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 4 +# define STM32L4_GPIOE_MODER (STM32L4_GPIOE_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOE_OTYPER (STM32L4_GPIOE_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOE_OSPEED (STM32L4_GPIOE_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOE_PUPDR (STM32L4_GPIOE_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOE_IDR (STM32L4_GPIOE_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOE_ODR (STM32L4_GPIOE_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOE_BSRR (STM32L4_GPIOE_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOE_LCKR (STM32L4_GPIOE_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOE_AFRL (STM32L4_GPIOE_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOE_AFRH (STM32L4_GPIOE_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 5 +# define STM32L4_GPIOF_MODER (STM32L4_GPIOF_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOF_OTYPER (STM32L4_GPIOF_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOF_OSPEED (STM32L4_GPIOF_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOF_PUPDR (STM32L4_GPIOF_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOF_IDR (STM32L4_GPIOF_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOF_ODR (STM32L4_GPIOF_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOF_BSRR (STM32L4_GPIOF_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOF_LCKR (STM32L4_GPIOF_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOF_AFRL (STM32L4_GPIOF_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOF_AFRH (STM32L4_GPIOF_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 6 +# define STM32L4_GPIOG_MODER (STM32L4_GPIOG_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOG_OTYPER (STM32L4_GPIOG_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOG_OSPEED (STM32L4_GPIOG_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOG_PUPDR (STM32L4_GPIOG_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOG_IDR (STM32L4_GPIOG_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOG_ODR (STM32L4_GPIOG_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOG_BSRR (STM32L4_GPIOG_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOG_LCKR (STM32L4_GPIOG_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOG_AFRL (STM32L4_GPIOG_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOG_AFRH (STM32L4_GPIOG_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NPORTS > 7 +# define STM32L4_GPIOH_MODER (STM32L4_GPIOH_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOH_OTYPER (STM32L4_GPIOH_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOH_OSPEED (STM32L4_GPIOH_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOH_PUPDR (STM32L4_GPIOH_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOH_IDR (STM32L4_GPIOH_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOH_ODR (STM32L4_GPIOH_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOH_BSRR (STM32L4_GPIOH_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOH_LCKR (STM32L4_GPIOH_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOH_AFRL (STM32L4_GPIOH_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOH_AFRH (STM32L4_GPIOH_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (2) /* 50 MHz High speed */ +#define GPIO_OSPEED_100MHz (3) /* 100 MHz Very High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..d711f730bffe62b8f0b4608df00c338704e47150 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h @@ -0,0 +1,783 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h + * + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_PINMAP_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32l4_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32L4xxx family share the same + * pin multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN16 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) + +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN16 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) + +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN8 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN10) + +/* CAN */ + +#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN1) + +/* Clocks outputs */ + +#define GPIO_MCO (GPIO_ALT|GPIO_AF0 |GPIO_PORTA|GPIO_PIN8) + +/* Comparators */ + +#define GPIO_COMP1_INM_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_COMP1_INM_2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_COMP1_INP_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2) +#define GPIO_COMP1_INP_2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN0) +#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN10) + +#define GPIO_COMP2_INM_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN3) +#define GPIO_COMP2_INM_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN7) +#define GPIO_COMP2_INP_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN4) +#define GPIO_COMP2_INP_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN6) +#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN5) +#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN11) + +/* DAC */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* Digital Filter for Sigma-Delta Modulators (DFSDM) */ + +#define GPIO_DFSDM_DATIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_DFSDM_DATIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN3) +#define GPIO_DFSDM_DATIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_DFSDM_DATIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN6) +#define GPIO_DFSDM_DATIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_DFSDM_DATIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN7) +#define GPIO_DFSDM_DATIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_DFSDM_DATIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_DFSDM_DATIN4_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_DFSDM_DATIN4_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_DFSDM_DATIN5_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_DFSDM_DATIN5_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_DFSDM_DATIN6_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_DFSDM_DATIN6_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTF|GPIO_PIN13) +#define GPIO_DFSDM_DATIN7_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_DFSDM_DATIN7_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN0) + +#define GPIO_DFSDM_CKIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_DFSDM_CKIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN4) +#define GPIO_DFSDM_CKIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_DFSDM_CKIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN7) +#define GPIO_DFSDM_CKIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_DFSDM_CKIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN8) +#define GPIO_DFSDM_CKIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_DFSDM_CKIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_DFSDM_CKIN4_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_DFSDM_CKIN4_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_DFSDM_CKIN5_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_DFSDM_CKIN5_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_DFSDM_CKIN6_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_DFSDM_CKIN6_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTF|GPIO_PIN14) +#define GPIO_DFSDM_CKIN7_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_DFSDM_CKIN7_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN1) + +#define GPIO_DFSDM_CKOUT_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_DFSDM_CKOUT_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN9) + + +/* Flexible Static Memory Controller (FSMC) */ + +#define GPIO_FMC_NL (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FMC_NBL0 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FMC_NBL1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FMC_CLK (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FMC_NOE (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FMC_NWE (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN5) +#define GPIO_FMC_NWAIT (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FMC_NE1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FMC_NE2 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FMC_NE3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FMC_NE4 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FMC_INT3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FMC_NCE3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) + +#define GPIO_FMC_A0 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FMC_A1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FMC_A2 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FMC_A3 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FMC_A4 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FMC_A5 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FMC_A6 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FMC_A7 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FMC_A8 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FMC_A9 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FMC_A10 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FMC_A11 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FMC_A12 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FMC_A13 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FMC_A14 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FMC_A15 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FMC_A16 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FMC_A17 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FMC_A18 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FMC_A19 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FMC_A20 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FMC_A21 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FMC_A22 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FMC_A23 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FMC_A24 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FMC_A25 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN14) + +#define GPIO_FMC_D0 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FMC_D1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FMC_D2 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FMC_D3 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FMC_D4 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FMC_D5 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FMC_D6 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FMC_D7 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FMC_D8 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FMC_D9 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FMC_D10 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FMC_D11 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FMC_D12 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FMC_D13 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FMC_D14 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FMC_D15 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN10) + +/* I2C */ + +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN15) + +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN2) + +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN6) + +/* JTAG */ + +#define GPIO_JTCK_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_JTMS_SWDIO (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_JTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) + +/* LCD Segment Controller */ + +#define GPIO_LCD_VLCD (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN3) + +#define GPIO_LCD_SEG0 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LCD_SEG1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LCD_SEG2 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LCD_SEG3 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LCD_SEG4 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN7) +#define GPIO_LCD_SEG5 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LCD_SEG6 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LCD_SEG7 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN3) +#define GPIO_LCD_SEG8 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN4) +#define GPIO_LCD_SEG9 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN5) +#define GPIO_LCD_SEG10 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LCD_SEG11 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LCD_SEG12 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN12) +#define GPIO_LCD_SEG13 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LCD_SEG14 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN14) +#define GPIO_LCD_SEG15 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN15) +#define GPIO_LCD_SEG16 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN8) +#define GPIO_LCD_SEG17 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN15) +#define GPIO_LCD_SEG18 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LCD_SEG19 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN1) +#define GPIO_LCD_SEG20 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN2) +#define GPIO_LCD_SEG21 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN7) +#define GPIO_LCD_SEG22 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN4) +#define GPIO_LCD_SEG23 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN5) +#define GPIO_LCD_SEG24 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN6) +#define GPIO_LCD_SEG25 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN7) +#define GPIO_LCD_SEG26 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN8) +#define GPIO_LCD_SEG27 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN9) +#define GPIO_LCD_SEG28_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_SEG28_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN8) +#define GPIO_LCD_SEG29_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_SEG29_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN9) +#define GPIO_LCD_SEG30_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_SEG30_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN10) +#define GPIO_LCD_SEG31_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) +#define GPIO_LCD_SEG31_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN11) +#define GPIO_LCD_SEG32 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LCD_SEG33 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LCD_SEG34 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN14) +#define GPIO_LCD_SEG35 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN15) +#define GPIO_LCD_SEG36 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LCD_SEG37 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN1) +#define GPIO_LCD_SEG38 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN2) +#define GPIO_LCD_SEG39 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN3) +#define GPIO_LCD_SEG40 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_SEG41 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_SEG42 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_SEG43 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_LCD_COM0 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LCD_COM1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN9) +#define GPIO_LCD_COM2 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN10) +#define GPIO_LCD_COM3 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN9) +#define GPIO_LCD_COM4 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_COM5 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_COM6 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_COM7 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) + +/* OTG FS */ + +#define GPIO_OTG_FS_SOF (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN8) +#define GPIO_OTG_FS_ID (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTG_FS_DM (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTG_FS_DP (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTG_FS_NOE_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN13) +#define GPIO_OTG_FS_NOE_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN9) + +/* QUADSPI */ + +#define GPIO_QUADSPI_NCS_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#define GPIO_QUADSPI_NCS_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11) +#define GPIO_QUADSPI_CLK_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_QUADSPI_CLK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10) +#define GPIO_QUADSPI_BK1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_QUADSPI_BK1_IO0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12) +#define GPIO_QUADSPI_BK1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_QUADSPI_BK1_IO1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13) +#define GPIO_QUADSPI_BK1_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN7) +#define GPIO_QUADSPI_BK1_IO2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14) +#define GPIO_QUADSPI_BK1_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN6) +#define GPIO_QUADSPI_BK1_IO3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN15) + +/* RTC */ + +#define GPIO_RTC_OUT (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_RTC_REFIN (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN15) + +/* SAI */ + +#define GPIO_SAI1_EXTCLK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN0) + +#define GPIO_SAI1_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SAI1_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SAI1_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SAI1_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI1_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SAI1_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN2) + +#define GPIO_SAI1_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SAI1_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_SAI1_FS_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SAI1_FS_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SAI1_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SAI1_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SAI1_SCK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN3) +#define GPIO_SAI1_SD_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SAI1_SD_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SAI1_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SAI1_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN10) +#define GPIO_SAI1_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_SAI2_EXTCLK_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN2) +#define GPIO_SAI2_EXTCLK_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN9) + +#define GPIO_SAI2_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SAI2_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN12) +#define GPIO_SAI2_FS_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SAI2_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SAI2_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN10) +#define GPIO_SAI2_SCK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SAI2_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SAI2_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SAI2_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SAI2_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SAI2_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SAI2_MCLK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SAI2_MCLK_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN11) + +#define GPIO_SAI2_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SAI2_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN3) +#define GPIO_SAI2_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SAI2_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN2) +#define GPIO_SAI2_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SAI2_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SAI2_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SAI2_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SAI2_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN4) + +/* SDIO */ + +#define GPIO_SDMMC1_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDMMC1_CMD (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDMMC1_D0 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDMMC1_D1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDMMC1_D2 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDMMC1_D3 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDMMC1_D4 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_D5 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D6 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D7 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN7) + +/* Single Wire Protocol Interface */ + +#define GPIO_SWPMI1_IO (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SWPMI1_TX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SWPMI1_RX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SWPMI1_SUSPEND (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN15) + +/* SPI */ + +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_SPI1_NSS_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN5) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI1_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_SPI1_SCK_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN2) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_SPI1_MOSI_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN4) +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_SPI1_MISO_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN3) + +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN0) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN1) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN4) +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN3) + +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_SPI3_SCK_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN9) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MISO_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN10) + +/* Timers */ + +#define GPIO_TIM1_CH1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH3_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH4_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN_COMP1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN_COMP2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_COMP2_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_COMP1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_COMP2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_BKIN (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN15) + +#define GPIO_TIM3_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1_4 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TIM3_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2_4 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TIM3_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM3_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM3_ETR_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_TIM3_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN2) + +#define GPIO_TIM4_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM5_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM5_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM5_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM5_ETR (GPIO_ALT|GPIO_AF1 |GPIO_PORTF|GPIO_PIN6) + +#define GPIO_TIM8_CH1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH3 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH4 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_COMP1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_COMP2 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN2_COMP1 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN2_COMP2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_ETR (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN0) + +#define GPIO_TIM15_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN10) +#define GPIO_TIM15_CH2_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM15_CH2_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN11) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM15_CH1N_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN9) +#define GPIO_TIM15_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_TIM16_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1N (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM16_BKIN (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_TIM17_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1N (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM17_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN4) + +#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_LPTIM1_IN1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM1_IN1_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN10) +#define GPIO_LPTIM1_IN2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_LPTIM1_IN2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_LPTIM1_IN2_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_LPTIM1_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_LPTIM1_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPTIM1_OUT_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN15) +#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_LPTIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM1_ETR_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN12) + +#define GPIO_LPTIM2_IN1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPTIM2_IN1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM2_IN1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM2_OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN4) +#define GPIO_LPTIM2_OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LPTIM2_OUT_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPTIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN5) +#define GPIO_LPTIM2_ETR_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM2_ETR_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN11) + +/* Touch Screen Controller */ + +#define GPIO_TSC_SYNC (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TSC_G1_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TSC_G1_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_TSC_G1_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TSC_G1_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN15) + +#define GPIO_TSC_G2_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_TSC_G2_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_TSC_G2_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TSC_G2_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN7) + +#define GPIO_TSC_G3_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_TSC_G3_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_TSC_G3_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_TSC_G3_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN12) + +#define GPIO_TSC_G4_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TSC_G4_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TSC_G4_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TSC_G4_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN9) + +#define GPIO_TSC_G5_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_TSC_G5_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_TSC_G5_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_TSC_G5_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN13) + +#define GPIO_TSC_G6_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN10) +#define GPIO_TSC_G6_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN11) +#define GPIO_TSC_G6_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN12) +#define GPIO_TSC_G6_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN13) + +#define GPIO_TSC_G7_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN2) +#define GPIO_TSC_G7_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TSC_G7_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TSC_G7_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN5) + +#define GPIO_TSC_G8_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN14) +#define GPIO_TSC_G8_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN15) +#define GPIO_TSC_G8_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN0) +#define GPIO_TSC_G8_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN1) + +/* IR interface (with timers 16 and 17) */ + +#define GPIO_IR_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN13) +#define GPIO_IR_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN9) + +/* Trace */ + +#define GPIO_TRACECK (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN6) + +/* UARTs/USARTs */ + +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN10) +#define GPIO_USART1_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_USART1_CK_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART1_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART1_CTS_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_USART1_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART1_RTS_DE_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN12) + +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN5) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN4) + +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN4) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN8) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN5) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_USART3_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_DE_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_USART3_RTS_DE_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN12) + +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_UART4_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN15) + +#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_UART5_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN4) + +#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_LPUART1_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPUART1_TX_3 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPUART1_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPUART1_RX_3 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN8) +#define GPIO_LPUART1_CTS_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPUART1_CTS_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN5) +#define GPIO_LPUART1_RTS_DE_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_LPUART1_RTS_DE_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN6) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_PINMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..134ee2844cdfa93a7ffc5acc5f3596d42397b7ab --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h @@ -0,0 +1,763 @@ +/**************************************************************************************************** + * arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32F42XXX_RCC_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32F42XXX_RCC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32L4_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32L4_RCC_ICSCR_OFFSET 0x0004 /* Internal clock sources calibration register */ +#define STM32L4_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32L4_RCC_PLLCFG_OFFSET 0x000c /* PLL configuration register */ +#define STM32L4_RCC_PLLSAI1CFG_OFFSET 0x0010 /* PLLSAI1 configuration register */ +#define STM32L4_RCC_PLLSAI2CFG_OFFSET 0x0014 /* PLLSAI2 configuration register */ +#define STM32L4_RCC_CIER_OFFSET 0x0018 /* Clock interrupt enable register */ +#define STM32L4_RCC_CIFR_OFFSET 0x001c /* Clock interrupt flag register */ +#define STM32L4_RCC_CICR_OFFSET 0x0020 /* Clock interrupt clear register */ +#define STM32L4_RCC_AHB1RSTR_OFFSET 0x0028 /* AHB1 peripheral reset register */ +#define STM32L4_RCC_AHB2RSTR_OFFSET 0x002c /* AHB2 peripheral reset register */ +#define STM32L4_RCC_AHB3RSTR_OFFSET 0x0030 /* AHB3 peripheral reset register */ +#define STM32L4_RCC_APB1RSTR1_OFFSET 0x0038 /* APB1 Peripheral reset register 1 */ +#define STM32L4_RCC_APB1RSTR2_OFFSET 0x003c /* APB1 Peripheral reset register 2 */ +#define STM32L4_RCC_APB2RSTR_OFFSET 0x0040 /* APB2 Peripheral reset register */ +#define STM32L4_RCC_AHB1ENR_OFFSET 0x0048 /* AHB1 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB2ENR_OFFSET 0x004c /* AHB2 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB3ENR_OFFSET 0x0050 /* AHB3 Peripheral Clock enable register */ +#define STM32L4_RCC_APB1ENR1_OFFSET 0x0058 /* APB1 Peripheral Clock enable register 1 */ +#define STM32L4_RCC_APB1ENR2_OFFSET 0x005c /* APB1 Peripheral Clock enable register 2 */ +#define STM32L4_RCC_APB2ENR_OFFSET 0x0060 /* APB2 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB1SMENR_OFFSET 0x0068 /* RCC AHB1 low power mode peripheral clock enable register */ +#define STM32L4_RCC_AHB2SMENR_OFFSET 0x006c /* RCC AHB2 low power mode peripheral clock enable register */ +#define STM32L4_RCC_AHB3SMENR_OFFSET 0x0070 /* RCC AHB3 low power mode peripheral clock enable register */ +#define STM32L4_RCC_APB1SMENR1_OFFSET 0x0078 /* RCC APB1 low power mode peripheral clock enable register 1 */ +#define STM32L4_RCC_APB1SMENR2_OFFSET 0x007c /* RCC APB1 low power mode peripheral clock enable register 2 */ +#define STM32L4_RCC_APB2SMENR_OFFSET 0x0080 /* RCC APB2 low power mode peripheral clock enable register */ +#define STM32L4_RCC_CCIPR_OFFSET 0x0088 /* Peripherals independ clock configuration register */ +#define STM32L4_RCC_BDCR_OFFSET 0x0090 /* Backup domain control register */ +#define STM32L4_RCC_CSR_OFFSET 0x0094 /* Control/status register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32L4_RCC_CR (STM32L4_RCC_BASE+STM32L4_RCC_CR_OFFSET) +#define STM32L4_RCC_ICSCR (STM32L4_RCC_BASE+STM32L4_RCC_ICSCR_OFFSET) +#define STM32L4_RCC_CFGR (STM32L4_RCC_BASE+STM32L4_RCC_CFGR_OFFSET) +#define STM32L4_RCC_PLLCFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLCFG_OFFSET) +#define STM32L4_RCC_PLLSAI1CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI1CFG_OFFSET) +#define STM32L4_RCC_PLLSAI2CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI2CFG_OFFSET) +#define STM32L4_RCC_CIER (STM32L4_RCC_BASE+STM32L4_RCC_CIER_OFFSET) +#define STM32L4_RCC_CIFR (STM32L4_RCC_BASE+STM32L4_RCC_CIFR_OFFSET) +#define STM32L4_RCC_CICR (STM32L4_RCC_BASE+STM32L4_RCC_CICR_OFFSET) +#define STM32L4_RCC_AHB1RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1RSTR_OFFSET) +#define STM32L4_RCC_AHB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2RSTR_OFFSET) +#define STM32L4_RCC_AHB3RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3RSTR_OFFSET) +#define STM32L4_RCC_APB1RSTR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR1_OFFSET) +#define STM32L4_RCC_APB1RSTR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR2_OFFSET) +#define STM32L4_RCC_APB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_APB2RSTR_OFFSET) +#define STM32L4_RCC_AHB1ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1ENR_OFFSET) +#define STM32L4_RCC_AHB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2ENR_OFFSET) +#define STM32L4_RCC_AHB3ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3ENR_OFFSET) +#define STM32L4_RCC_APB1ENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR1_OFFSET) +#define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET) +#define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET) +#define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET) +#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR) +#define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET) +#define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET) +#define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET) +#define STM32L4_RCC_APB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2SMENR_OFFSET) +#define STM32L4_RCC_CCIPR (STM32L4_RCC_BASE+STM32L4_RCC_CCIPR_OFFSET) +#define STM32L4_RCC_BDCR (STM32L4_RCC_BASE+STM32L4_RCC_BDCR_OFFSET) +#define STM32L4_RCC_CSR (STM32L4_RCC_BASE+STM32L4_RCC_CSR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* Clock control register */ + +#define RCC_CR_MSION (1 << 0) /* Bit 0: Internal Medium Speed clock enable */ +#define RCC_CR_MSIRDY (1 << 1) /* Bit 1: Internal Medium Speed clock ready flag */ +#define RCC_CR_MSIPLLEN (1 << 2) /* Bit 2: MSI clock PLL enable */ +#define RCC_CR_MSIRGSEL (1 << 3) /* Bit 2: MSI clock range selection */ +#define RCC_CR_MSIRANGE_SHIFT (4) /* Bits 7-4: MSI clock range */ +#define RCC_CR_MSIRANGE_MASK (0x0f << RCC_CR_MSIRANGE_SHIFT) +# define RCC_CR_MSIRANGE_100K (0 << RCC_CR_MSIRANGE_SHIFT) /* 0000: around 100 kHz */ +# define RCC_CR_MSIRANGE_200K (1 << RCC_CR_MSIRANGE_SHIFT) /* 0001: around 200 kHz */ +# define RCC_CR_MSIRANGE_400K (2 << RCC_CR_MSIRANGE_SHIFT) /* 0010: around 400 kHz */ +# define RCC_CR_MSIRANGE_800K (3 << RCC_CR_MSIRANGE_SHIFT) /* 0011: around 800 kHz */ +# define RCC_CR_MSIRANGE_1M (4 << RCC_CR_MSIRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CR_MSIRANGE_2M (5 << RCC_CR_MSIRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CR_MSIRANGE_4M (6 << RCC_CR_MSIRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CR_MSIRANGE_8M (7 << RCC_CR_MSIRANGE_SHIFT) /* 0111: around 8 MHz */ +# define RCC_CR_MSIRANGE_16M (8 << RCC_CR_MSIRANGE_SHIFT) /* 1000: around 16 MHz */ +# define RCC_CR_MSIRANGE_24M (9 << RCC_CR_MSIRANGE_SHIFT) /* 1001: around 24 MHz */ +# define RCC_CR_MSIRANGE_32M (10 << RCC_CR_MSIRANGE_SHIFT) /* 1010: around 32 MHz */ +# define RCC_CR_MSIRANGE_48M (11 << RCC_CR_MSIRANGE_SHIFT) /* 1011: around 48 MHz */ + +#define RCC_CR_HSION (1 << 8) /* Bit 8: Internal High Speed clock enable */ +#define RCC_CR_HSIKERON (1 << 9) /* Bit 9: HSI16 always enable for peripheral kernels */ +#define RCC_CR_HSIRDY (1 << 10) /* Bit 10: Internal High Speed clock ready flag */ +#define RCC_CR_HSIASFS (1 << 11) /* Bit 11: HSI automatic start from stop */ + +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#define RCC_CR_PLLSAI1ON (1 << 26) /* Bit 26: PLLSAI1 enable */ +#define RCC_CR_PLLSAI1RDY (1 << 27) /* Bit 27: PLLSAI1 clock ready flag */ +#define RCC_CR_PLLSAI2ON (1 << 28) /* Bit 28: PLLSAI2 enable */ +#define RCC_CR_PLLSAI2RDY (1 << 29) /* Bit 29: PLLSAI2 clock ready flag */ + +/* Internal Clock Sources Calibration */ + +#define RCC_CR_HSITRIM_SHIFT (24) /* Bits 28-24: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (16) /* Bits 23-16: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_MSITRIM_SHIFT (8) /* Bits 15-8: Internal Medium Speed clock trimming */ +#define RCC_CR_MSITRIM_MASK (0xff << RCC_CR_MSITRIM_SHIFT) +#define RCC_CR_MSICAL_SHIFT (0) /* Bits 7-0: Internal Menium Speed clock Calibration */ +#define RCC_CR_MSICAL_MASK (0xff << RCC_CR_MSICAL_SHIFT) + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_MSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSI (1 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (2 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (3 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ + +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_MSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSI (1 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (2 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (3 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ + +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ + +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 8-10: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ + +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 11-13: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ + +#define RCC_CFGR_STOPWUCK (1 << 15) /* Bit 15: Wakeup from Stop and CSS backup clock selection */ +# define RCC_CFGR_STOPWUCK_MSI (0 << 15) /* 0: MSI */ +# define RCC_CFGR_STOPWUCK_HSI (1 << 15) /* 0: HSI */ + +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 24-26: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (7 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_MCO_NONE (0 << RCC_CFGR_MCO_SHIFT) /* 000: Disabled */ +# define RCC_CFGR_MCO_SYSCLK (1 << RCC_CFGR_MCO_SHIFT) /* 001: SYSCLK system clock selected */ +# define RCC_CFGR_MCO_MSI (2 << RCC_CFGR_MCO_SHIFT) /* 010: MSI clock selected */ +# define RCC_CFGR_MCO_HSI (3 << RCC_CFGR_MCO_SHIFT) /* 011: HSI clock selected */ +# define RCC_CFGR_MCO_HSE (4 << RCC_CFGR_MCO_SHIFT) /* 100: HSE clock selected */ +# define RCC_CFGR_MCO_PLL (5 << RCC_CFGR_MCO_SHIFT) /* 101: Main PLL selected */ +# define RCC_CFGR_MCO_LSI (6 << RCC_CFGR_MCO_SHIFT) /* 110: LSI clock selected */ +# define RCC_CFGR_MCO_LSE (7 << RCC_CFGR_MCO_SHIFT) /* 111: LSE clock selected */ + +#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ +#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT) +# define RCC_CFGR_MCOPRE_NONE (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: no division */ +# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: division by 2 */ +# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: division by 4 */ +# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: division by 8 */ +# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: division by 16 */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLL(PLL) and audio PLLs (PLLSAIx) + * entry clock source */ +#define RCC_PLLCFG_PLLSRC_MASK (3 << RCC_PLLCFG_PLLSRC_SHIFT) +# define RCC_PLLCFG_PLLSRC_NONE (0 << RCC_PLLCFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */ +# define RCC_PLLCFG_PLLSRC_MSI (1 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSI (2 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSI selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSE (3 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSE selected as PLL source */ + +#define RCC_PLLCFG_PLLM_SHIFT (4) /* Bits 4-6: Main PLL (PLL) input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x07 << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n-1) << RCC_PLLCFG_PLLM_SHIFT) /* m = 1..8 */ + +#define RCC_PLLCFG_PLLN_SHIFT (8) /* Bits 6-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x7f << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLCFG_PLLPEN (1 << 16) /* Bit 16: Main PLL PLLSAI3CLK output enable */ + +#define RCC_PLLCFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI3CLK */ +# define RCC_PLLCFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLCFG_PLLP_17 RCC_PLLCFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLCFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M1CLK output enable */ + +#define RCC_PLLCFG_PLLQ_SHIFT (21) +#define RCC_PLLCFG_PLLQ_MASK (3 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLQ_2 (0 << RCC_PLLCFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLCFG_PLLQ_4 (1 << RCC_PLLCFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLCFG_PLLQ_6 (2 << RCC_PLLCFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLCFG_PLLQ_8 (3 << RCC_PLLCFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLCFG_PLLREN (1 << 24) /* Bit 24: Main PLL PLLCLK output enable */ + +#define RCC_PLLCFG_PLLR_SHIFT (25) +#define RCC_PLLCFG_PLLR_MASK (3 << RCC_PLLCFG_PLLR_SHIFT) +# define RCC_PLLCFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLR_2 (0 << RCC_PLLCFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLCFG_PLLR_4 (1 << RCC_PLLCFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLCFG_PLLR_6 (2 << RCC_PLLCFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLCFG_PLLR_8 (3 << RCC_PLLCFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +#define RCC_PLLCFG_RESET (0x00001000) /* PLLCFG reset value */ + +/* PLLSAI1 Configuration register */ + +#define RCC_PLLSAI1CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI1 PLL (PLLSAI1) VCO multiplier */ +#define RCC_PLLSAI1CFG_PLLN_MASK (0x7f << RCC_PLLSAI1CFG_PLLN_SHIFT) +# define RCC_PLLSAI1CFG_PLLN(n) ((n) << RCC_PLLSAI1CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI1CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI1CLK */ +# define RCC_PLLSAI1CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI1CFG_PLLP_17 RCC_PLLSAI1CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI1CFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M2CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLQ_SHIFT (21) +#define RCC_PLLSAI1CFG_PLLQ_MASK (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) +# define RCC_PLLSAI1CFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLQ_2 (0 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLSAI1CFG_PLLQ_4 (1 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLSAI1CFG_PLLQ_6 (2 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLSAI1CFG_PLLQ_8 (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLSAI1CFG_PLLREN (1 << 24) /* Bit 24: SAI1 PLL PLLADC1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLR_SHIFT (25) +#define RCC_PLLSAI1CFG_PLLR_MASK (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) +# define RCC_PLLSAI1CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLR_2 (0 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLSAI1CFG_PLLR_4 (1 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLSAI1CFG_PLLR_6 (2 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLSAI1CFG_PLLR_8 (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +/* PLLSAI2 Configuration register */ + +#define RCC_PLLSAI2CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI2 PLL (PLLSAI2) VCO multiplier */ +#define RCC_PLLSAI2CFG_PLLN_MASK (0x7f << RCC_PLLSAI2CFG_PLLN_SHIFT) +# define RCC_PLLSAI2CFG_PLLN(n) ((n) << RCC_PLLSAI2CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI2CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI2CLK output enable */ + +#define RCC_PLLSAI2CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI2CLK */ +# define RCC_PLLSAI2CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI2CFG_PLLP_17 RCC_PLLSAI2CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI2CFG_PLLREN (1 << 24) /* Bit 24: SAI2 PLL PLLADC2CLK output enable */ + +#define RCC_PLLSAI2CFG_PLLR_SHIFT (25) +#define RCC_PLLSAI2CFG_PLLR_MASK (3 << RCC_PLLSAI2CFG_PLLR_SHIFT) +# define RCC_PLLSAI2CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI2CFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI2CFG_PLLR_2 (0 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLSAI2CFG_PLLR_4 (1 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLSAI2CFG_PLLR_6 (2 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLSAI2CFG_PLLR_8 (3 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +/* Clock interrupt enable register */ + +#define RCC_CIR_LSIRDYIE (1 << 0) /* Bit 0: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 1) /* Bit 1: LSE Ready Interrupt Enable */ +#define RCC_CIR_MSIRDYIE (1 << 2) /* Bit 2: MSI Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 3) /* Bit 3: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 4) /* Bit 4: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 5) /* Bit 5: PLL Ready Interrupt Enable */ +#define RCC_CIR_PLLSAI1RDYIE (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt enable */ +#define RCC_CIR_PLLSAI2RDYIE (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt enable */ +#define RCC_CIR_LSECSSIE (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Enable */ + +/* Clock interrupt flag register */ + +#define RCC_CIR_LSIRDYIF (1 << 0) /* Bit 0: LSI Ready Interrupt Flag */ +#define RCC_CIR_LSERDYIF (1 << 1) /* Bit 1: LSE Ready Interrupt Flag */ +#define RCC_CIR_MSIRDYIF (1 << 2) /* Bit 2: MSI Ready Interrupt Flag */ +#define RCC_CIR_HSIRDYIF (1 << 3) /* Bit 3: HSI Ready Interrupt Flag */ +#define RCC_CIR_HSERDYIF (1 << 4) /* Bit 4: HSE Ready Interrupt Flag */ +#define RCC_CIR_PLLRDYIF (1 << 5) /* Bit 5: PLL Ready Interrupt Flag */ +#define RCC_CIR_PLLSAI1RDYIF (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Flag */ +#define RCC_CIR_PLLSAI2RDYIF (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Flag */ +#define RCC_CIR_CSSF (1 << 8) /* Bit 8: Clock Security System Interrupt Flag */ +#define RCC_CIR_LSECSSIF (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Flag */ + +/* Clock interrupt clear register */ + +#define RCC_CIR_LSIRDYIC (1 << 0) /* Bit 0: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYIC (1 << 1) /* Bit 1: LSE Ready Interrupt Clear */ +#define RCC_CIR_MSIRDYIC (1 << 2) /* Bit 2: MSI Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYIC (1 << 3) /* Bit 3: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYIC (1 << 4) /* Bit 4: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYIC (1 << 5) /* Bit 5: PLL Ready Interrupt Clear */ +#define RCC_CIR_PLLSAI1RDYIC (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Clear */ +#define RCC_CIR_PLLSAI2RDYIC (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Clear */ +#define RCC_CIR_CSSC (1 << 8) /* Bit 8: Clock Security System Interrupt Clear */ +#define RCC_CIR_LSECSSIC (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_DMA1RST (1 << 0) /* Bit 0: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 1) /* Bit 1: DMA2 reset */ +#define RCC_AHB1RSTR_FLASHRST (1 << 8) /* Bit 8: Flash memory interface reset */ +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12: CRC reset */ +#define RCC_AHB1RSTR_TSCRST (1 << 16) /* Bit 16: Touch Sensing Controller reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB2RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB2RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB2RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB2RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB2RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB2RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB2RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#define RCC_AHB2RSTR_OTGFSRST (1 << 12) /* Bit 12: USB OTG FS module reset */ +#define RCC_AHB2RSTR_ADCRST (1 << 13) /* Bit 13: ADC interface reset (common to all ADCs) */ +#define RCC_AHB2RSTR_AESRST (1 << 16) /* Bit 16: AES Cryptographic module reset */ +#define RCC_AHB2RSTR_RNGRST (1 << 18) /* Bit 6: Random number generator module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */ +#define RCC_AHB3RSTR_QSPIRST (1 << 8) /* Bit 8: Quad SPI module reset */ + +/* APB1 Peripheral reset register 1 */ + +#define RCC_APB1RSTR1_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR1_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR1_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR1_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR1_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR1_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR1_LCDRST (1 << 9) /* Bit 9: LCD controller reset */ +#define RCC_APB1RSTR1_SPI2RST (1 << 14) /* Bit 14: SPI2 reset */ +#define RCC_APB1RSTR1_SPI3RST (1 << 15) /* Bit 15: SPI3 reset */ +#define RCC_APB1RSTR1_USART2RST (1 << 17) /* Bit 17: USART2 reset */ +#define RCC_APB1RSTR1_USART3RST (1 << 18) /* Bit 18: USART3 reset */ +#define RCC_APB1RSTR1_UART4RST (1 << 19) /* Bit 19: USART4 reset */ +#define RCC_APB1RSTR1_UART5RST (1 << 20) /* Bit 20: USART5 reset */ +#define RCC_APB1RSTR1_I2C1RST (1 << 21) /* Bit 21: I2C1 reset */ +#define RCC_APB1RSTR1_I2C2RST (1 << 22) /* Bit 22: I2C2 reset */ +#define RCC_APB1RSTR1_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */ +#define RCC_APB1RSTR1_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR1_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR1_DAC1RST (1 << 29) /* Bit 29: DAC1 reset */ +#define RCC_APB1RSTR1_OPAMPRST (1 << 30) /* Bit 30: OPAMP reset */ +#define RCC_APB1RSTR1_LPTIM1RST (1 << 31) /* Bit 31: Low-power Timer 1 reset */ + +/* APB1 Peripheral reset register 2 */ + +#define RCC_APB1RSTR2_LPUART1RST (1 << 0) /* Bit 0: Low-power UART 1 reset */ +#define RCC_APB1RSTR2_SWPMI1RST (1 << 2) /* Bit 2: Single Wire Protocol reset */ +#define RCC_APB1RSTR2_LPTIM2RST (1 << 5) /* Bit 5: Low-power Timer 2 reset */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: System configuration controller reset */ +#define RCC_APB2RSTR_SDMMCRST (1 << 10) /* Bit 10: SDMMC reset */ +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#define RCC_APB2RSTR_SAI1RST (1 << 21) /* Bit 21: SAI1 reset */ +#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 22: SAI2 reset */ +#define RCC_APB2RSTR_DFSDMRST (1 << 24) /* Bit 24: DFSDM reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_DMA1EN (1 << 0) /* Bit 0: DMA1 enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 1) /* Bit 1: DMA2 enable */ +#define RCC_AHB1ENR_FLASHEN (1 << 8) /* Bit 8: Flash memory interface enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC enable */ +#define RCC_AHB1ENR_TSCEN (1 << 16) /* Bit 16: Touch Sensing Controller enable */ + +/* AHB2 Peripheral Clock enable register */ + +#define RCC_AHB2ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A enable */ +#define RCC_AHB2ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B enable */ +#define RCC_AHB2ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C enable */ +#define RCC_AHB2ENR_GPIODEN (1 << 3) /* Bit 3: IO port D enable */ +#define RCC_AHB2ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E enable */ +#define RCC_AHB2ENR_GPIOFEN (1 << 5) /* Bit 5: IO port F enable */ +#define RCC_AHB2ENR_GPIOGEN (1 << 6) /* Bit 6: IO port G enable */ +#define RCC_AHB2ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H enable */ +#define RCC_AHB2ENR_OTGFSEN (1 << 12) /* Bit 12: USB OTG FS module enable */ +#define RCC_AHB2ENR_ADCEN (1 << 13) /* Bit 13: ADC interface enable (common to all ADCs) */ +#define RCC_AHB2ENR_AESEN (1 << 16) /* Bit 16: AES Cryptographic module enable */ +#define RCC_AHB2ENR_RNGEN (1 << 18) /* Bit 18: Random number generator module enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module enable */ +#define RCC_AHB3ENR_QSPIEN (1 << 8) /* Bit 8: Quad SPI module enable */ + +/* APB1 Peripheral Clock enable register 1*/ + +#define RCC_APB1ENR1_TIM2EN (1 << 0) /* Bit 0: TIM2 enable */ +#define RCC_APB1ENR1_TIM3EN (1 << 1) /* Bit 1: TIM3 enable */ +#define RCC_APB1ENR1_TIM4EN (1 << 2) /* Bit 2: TIM4 enable */ +#define RCC_APB1ENR1_TIM5EN (1 << 3) /* Bit 3: TIM5 enable */ +#define RCC_APB1ENR1_TIM6EN (1 << 4) /* Bit 4: TIM6 enable */ +#define RCC_APB1ENR1_TIM7EN (1 << 5) /* Bit 5: TIM7 enable */ +#define RCC_APB1ENR1_LCDEN (1 << 9) /* Bit 9: LCD controller enable */ +#define RCC_APB1ENR1_WWDGEN (1 << 11) /* Bit 11: Windowed Watchdog enable */ +#define RCC_APB1ENR1_SPI2EN (1 << 14) /* Bit 14: SPI2 enable */ +#define RCC_APB1ENR1_SPI3EN (1 << 15) /* Bit 15: SPI3 enable */ +#define RCC_APB1ENR1_USART2EN (1 << 17) /* Bit 17: USART2 enable */ +#define RCC_APB1ENR1_USART3EN (1 << 18) /* Bit 18: USART3 enable */ +#define RCC_APB1ENR1_UART4EN (1 << 19) /* Bit 19: USART4 enable */ +#define RCC_APB1ENR1_UART5EN (1 << 20) /* Bit 20: USART5 enable */ +#define RCC_APB1ENR1_I2C1EN (1 << 21) /* Bit 21: I2C1 enable */ +#define RCC_APB1ENR1_I2C2EN (1 << 22) /* Bit 22: I2C2 enable */ +#define RCC_APB1ENR1_I2C3EN (1 << 23) /* Bit 23: I2C3 enable */ +#define RCC_APB1ENR1_CAN1EN (1 << 25) /* Bit 25: CAN1 enable */ +#define RCC_APB1ENR1_PWREN (1 << 28) /* Bit 28: Power interface enable */ +#define RCC_APB1ENR1_DAC1EN (1 << 29) /* Bit 29: DAC1 enable */ +#define RCC_APB1ENR1_OPAMPEN (1 << 30) /* Bit 30: OPAMP enable */ +#define RCC_APB1ENR1_LPTIM1EN (1 << 31) /* Bit 31: Low-power Timer 1 enable */ + +/* APB1 Peripheral Clock enable register 2*/ + +#define RCC_APB1ENR2_LPUART1EN (1 << 0) /* Bit 0: Low-power UART 1 enable */ +#define RCC_APB1ENR2_SWPMI1EN (1 << 2) /* Bit 2: Single Wire Protocol enable */ +#define RCC_APB1ENR2_LPTIM2EN (1 << 5) /* Bit 5: Low-power Timer 2 enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: System configuration controller enable */ +#define RCC_APB2ENR_FWEN (1 << 7) /* Bit 7: Firewall enable */ +#define RCC_APB2ENR_SDMMCEN (1 << 10) /* Bit 10: SDMMC enable */ +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 enable */ +#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 enable */ +#define RCC_APB2ENR_SAI1EN (1 << 21) /* Bit 21: SAI1 enable */ +#define RCC_APB2ENR_SAI2EN (1 << 22) /* Bit 22: SAI2 enable */ +#define RCC_APB2ENR_DFSDMEN (1 << 24) /* Bit 24: DFSDM enable */ + +/* RCC AHB1 low power mode peripheral clock enable register */ + +#define RCC_AHB1SMENR_DMA1LPSMEN (1 << 0) /* Bit 0: DMA1 enable during Sleep mode */ +#define RCC_AHB1SMENR_DMA2LPSMEN (1 << 1) /* Bit 1: DMA2 enable during Sleep mode */ +#define RCC_AHB1SMENR_FLASHLPSMEN (1 << 8) /* Bit 8: Flash memory interface enable during Sleep mode */ +#define RCC_AHB1SMENR_SRAM1SMEN (1 << 9) /* Bit 9: SRAM1 enable during Sleep mode */ +#define RCC_AHB1SMENR_CRCLPSMEN (1 << 12) /* Bit 12: CRC enable during Sleep mode */ +#define RCC_AHB1SMENR_TSCLPSMEN (1 << 16) /* Bit 16: Touch Sensing Controller enable during Sleep mode */ + +/* RCC AHB2 low power mode peripheral clock enable register */ + +#define RCC_AHB2SMENR_GPIOASMEN (1 << 0) /* Bit 0: IO port A enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOBSMEN (1 << 1) /* Bit 1: IO port B enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOCSMEN (1 << 2) /* Bit 2: IO port C enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIODSMEN (1 << 3) /* Bit 3: IO port D enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOESMEN (1 << 4) /* Bit 4: IO port E enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOFSMEN (1 << 5) /* Bit 5: IO port F enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOGSMEN (1 << 6) /* Bit 6: IO port G enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOHSMEN (1 << 7) /* Bit 7: IO port H enable during Sleep mode */ +#define RCC_AHB2SMENR_SRAM2SMEN (1 << 9) /* Bit 9: SRAM2 enable during Sleep mode */ +#define RCC_AHB2SMENR_OTGFSSMEN (1 << 12) /* Bit 12: USB OTG FS module enable during Sleep mode */ +#define RCC_AHB2SMENR_ADCSMEN (1 << 13) /* Bit 13: ADC interface enable during Sleep mode (common to all ADCs) */ +#define RCC_AHB2SMENR_AESSMEN (1 << 16) /* Bit 16: AES Cryptographic module enable during Sleep mode */ +#define RCC_AHB2SMENR_RNGSMEN (1 << 18) /* Bit 6: Random number generator module enable during Sleep mode */ + +/* RCC AHB3 low power mode peripheral clock enable register */ + +#define RCC_AHB3SMENR_FSMCSMEN (1 << 0) /* Bit 0: Flexible static memory controller module enable during Sleep mode */ +#define RCC_AHB3SMENR_QSPISMEN (1 << 8) /* Bit 8: Quad SPI module enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register 1 */ + +#define RCC_APB1SMENR1_TIM2SMEN (1 << 0) /* Bit 0: TIM2 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM3SMEN (1 << 1) /* Bit 1: TIM3 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM4SMEN (1 << 2) /* Bit 2: TIM4 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM5SMEN (1 << 3) /* Bit 3: TIM5 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM6SMEN (1 << 4) /* Bit 4: TIM6 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM7SMEN (1 << 5) /* Bit 5: TIM7 enable during Sleep mode */ +#define RCC_APB1SMENR1_LCDSMEN (1 << 9) /* Bit 9: LCD controller enable during Sleep mode */ +#define RCC_APB1SMENR1_WWDGSMEN (1 << 11) /* Bit 11: Windowed Watchdog enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI2SMEN (1 << 14) /* Bit 14: SPI2 enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI3SMEN (1 << 15) /* Bit 15: SPI3 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART2SMEN (1 << 17) /* Bit 17: USART2 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART3SMEN (1 << 18) /* Bit 18: USART3 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART4SMEN (1 << 19) /* Bit 19: USART4 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART5SMEN (1 << 20) /* Bit 20: USART5 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C1SMEN (1 << 21) /* Bit 21: I2C1 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C2SMEN (1 << 22) /* Bit 22: I2C2 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C3SMEN (1 << 23) /* Bit 23: I2C3 enable during Sleep mode */ +#define RCC_APB1SMENR1_CAN1SMEN (1 << 25) /* Bit 25: CAN1 enable during Sleep mode */ +#define RCC_APB1SMENR1_PWRSMEN (1 << 28) /* Bit 28: Power interface enable during Sleep mode */ +#define RCC_APB1SMENR1_DAC1SMEN (1 << 29) /* Bit 29: DAC1 enable during Sleep mode */ +#define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) /* Bit 30: OPAMP enable during Sleep mode */ +#define RCC_APB1SMENR1_LPTIM1SMEN (1 << 31) /* Bit 31: Low-power Timer 1 enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register 2 */ + +#define RCC_APB1SMENR2_LPUART1SMEN (1 << 0) /* Bit 0: Low-power UART 1 enable during Sleep mode */ +#define RCC_APB1SMENR2_SWPMI1SMEN (1 << 2) /* Bit 2: Single Wire Protocol enable during Sleep mode */ +#define RCC_APB1SMENR2_LPTIM2SMEN (1 << 5) /* Bit 5: Low-power Timer 2 enable during Sleep mode */ + +/* RCC APB2 low power mode peripheral clock enable register */ + +#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) /* Bit 0: System configuration controller enable during Sleep mode */ +#define RCC_APB2SMENR_SDMMCSMEN (1 << 10) /* Bit 10: SDMMC enable during Sleep mode */ +#define RCC_APB2SMENR_TIM1SMEN (1 << 11) /* Bit 11: TIM1 enable during Sleep mode */ +#define RCC_APB2SMENR_SPI1SMEN (1 << 12) /* Bit 12: SPI1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM8SMEN (1 << 13) /* Bit 13: TIM8 enable during Sleep mode */ +#define RCC_APB2SMENR_USART1SMEN (1 << 14) /* Bit 14: USART1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM15SMEN (1 << 16) /* Bit 16: TIM15 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM16SMEN (1 << 17) /* Bit 17: TIM16 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM17SMEN (1 << 18) /* Bit 18: TIM17 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI1SMEN (1 << 21) /* Bit 21: SAI1 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI2SMEN (1 << 22) /* Bit 22: SAI2 enable during Sleep mode */ +#define RCC_APB2SMENR_DFSDMSMEN (1 << 24) /* Bit 24: DFSDM enable during Sleep mode */ + +/* Peripheral Independent Clock Configuration register */ + +#define RCC_CCIPR_USART1SEL_SHIFT (0) +#define RCC_CCIPR_USART1SEL_MASK (3 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_PCLK (0 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_SYSCLK (1 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_HSI (2 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_LSE (3 << RCC_CCIPR_USART1SEL_SHIFT) + +#define RCC_CCIPR_USART2SEL_SHIFT (2) +#define RCC_CCIPR_USART2SEL_MASK (3 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_PCLK (0 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_SYSCLK (1 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_HSI (2 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_LSE (3 << RCC_CCIPR_USART2SEL_SHIFT) + +#define RCC_CCIPR_USART3SEL_SHIFT (4) +#define RCC_CCIPR_USART3SEL_MASK (3 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_PCLK (0 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_SYSCLK (1 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_HSI (2 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_LSE (3 << RCC_CCIPR_USART3SEL_SHIFT) + +#define RCC_CCIPR_UART4SEL_SHIFT (6) +#define RCC_CCIPR_UART4SEL_MASK (3 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_PCLK (0 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_SYSCLK (1 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_HSI (2 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_LSE (3 << RCC_CCIPR_UART4SEL_SHIFT) + +#define RCC_CCIPR_UART5SEL_SHIFT (8) +#define RCC_CCIPR_UART5SEL_MASK (3 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_PCLK (0 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_SYSCLK (1 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_HSI (2 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_LSE (3 << RCC_CCIPR_UART5SEL_SHIFT) + +#define RCC_CCIPR_LPUART1SEL_SHIFT (10) +#define RCC_CCIPR_LPUART1SEL_MASK (3 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_PCLK (0 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_SYSCLK (1 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_HSI (2 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_LSE (3 << RCC_CCIPR_LPUART1SEL_SHIFT) + +#define RCC_CCIPR_I2C1SEL_SHIFT (12) +#define RCC_CCIPR_I2C1SEL_MASK (3 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_PCLK (0 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_SYSCLK (1 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_HSI (2 << RCC_CCIPR_I2C1SEL_SHIFT) + +#define RCC_CCIPR_I2C2SEL_SHIFT (14) +#define RCC_CCIPR_I2C2SEL_MASK (3 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_PCLK (0 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_SYSCLK (1 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_HSI (2 << RCC_CCIPR_I2C2SEL_SHIFT) + +#define RCC_CCIPR_I2C3SEL_SHIFT (16) +#define RCC_CCIPR_I2C3SEL_MASK (3 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_PCLK (0 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_SYSCLK (1 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_HSI (2 << RCC_CCIPR_I2C3SEL_SHIFT) + +#define RCC_CCIPR_LPTIM1SEL_SHIFT (18) +#define RCC_CCIPR_LPTIM1SEL_MASK (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_PCLK (0 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSI (1 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_HSI (2 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSE (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) + +#define RCC_CCIPR_LPTIM2SEL_SHIFT (20) +#define RCC_CCIPR_LPTIM2SEL_MASK (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_PCLK (0 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSI (1 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_HSI (2 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSE (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) + +#define RCC_CCIPR_SAI1SEL_SHIFT (22) +#define RCC_CCIPR_SAI1SEL_MASK (3 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLSAI1 (0 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLSAI2 (1 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLMAIN (2 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_EXTCLK (3 << RCC_CCIPR_SAI1SEL_SHIFT) + +#define RCC_CCIPR_SAI2SEL_SHIFT (24) +#define RCC_CCIPR_SAI2SEL_MASK (3 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLSAI1 (0 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLSAI2 (1 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLMAIN (2 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_EXTCLK (3 << RCC_CCIPR_SAI2SEL_SHIFT) + +#define RCC_CCIPR_CLK48SEL_SHIFT (26) +#define RCC_CCIPR_CLK48SEL_MASK (3 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_NONE (0 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_PLLSAI1 (1 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_PLLMAIN (2 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_MSI (3 << RCC_CCIPR_CLK48SEL_SHIFT) + +#define RCC_CCIPR_ADCSEL_SHIFT (28) +#define RCC_CCIPR_ADCSEL_MASK (3 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_NONE (0 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_PLLSAI1 (1 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_PLLSAI2 (2 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_SYSCLK (3 << RCC_CCIPR_ADCSEL_SHIFT) + +#define RCC_CCIPR_SWPMI1SEL (1 << 30) +# define RCC_CCIPR_SWPMI1SEL_PCLK 0 +# define RCC_CCIPR_SWPMI1SEL_HSI RCC_CCIPR_SWPMI1SEL + +#define RCC_CCIPR_DFSDMSEL (1 << 31) +# define RCC_CCIPR_DFSDMSEL_PCLK 0 +# define RCC_CCIPR_DFSDMSEL_SYSCLK RCC_CCIPR_DFSDMSEL + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ + +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 3-4: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOWER (0 << RCC_BDCR_LSEDRV_SHIFT) /* 00: Lower driving capability */ +# define RCC_BDCR_LSEDRV_MIDLOW (1 << RCC_BDCR_LSEDRV_SHIFT) /* 01: Medium Low driving capability */ +# define RCC_BDCR_LSEDRV_MIDHI (2 << RCC_BDCR_LSEDRV_SHIFT) /* 10: Medium High driving capability*/ +# define RCC_BDCR_LSEDRV_HIGER (3 << RCC_BDCR_LSEDRV_SHIFT) /* 11: Higher driving capability */ + +#define RCC_BDCR_LSECSSON (1 << 5) /* Bit 5: CSS on LSE enable */ +#define RCC_BDCR_LSECSSD (1 << 6) /* Bit 6: CSS on LSE failure Detection */ + +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 32 used as RTC clock */ + +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ +#define RCC_BDCR_LSCOEN (1 << 24) /* Bit 24: Low speed clock output enable */ +#define RCC_BDCR_LSCOSEL (1 << 25) /* Bit 25: Low speed clock output selection */ +# define RCC_BCDR_LSCOSEL_LSI 0 /* LSI selected */ +# define RCC_BDCR_LSCOSEL_LSE RCC_BDCR_LSCOSEL /* LSE selected */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ + +#define RCC_CSR_MSISRANGE_SHIFT 8 +# define RCC_CSR_MSISRANGE_MASK (0x0F << RCC_CSR_MSISRANGE_SHIFT) /* MSI range after Standby mode */ +# define RCC_CSR_MSISRANGE_1M (4 << RCC_CSR_MSISRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CSR_MSISRANGE_2M (5 << RCC_CSR_MSISRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CSR_MSISRANGE_4M (6 << RCC_CSR_MSISRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CSR_MSISRANGE_8M (7 << RCC_CSR_MSISRANGE_SHIFT) /* 0111: around 8 MHz */ + +#define RCC_CSR_RMVF (1 << 23) /* Bit 23: Remove reset flag */ +#define RCC_CSR_FWRSTF (1 << 24) /* Bit 24: Firewall reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_BORRSTF (1 << 27) /* Bit 27: BOR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +#endif /* CONFIG_STM32L4_STM32F427 || CONFIG_STM32L4_STM32F429 */ +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32F42XXX_RCC_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..7e1855061d56814a044137cb7ef989e249723d23 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h @@ -0,0 +1,318 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_UART_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_USART_CR1_OFFSET 0x0000 /* Control register 1 */ +#define STM32L4_USART_CR2_OFFSET 0x0004 /* Control register 2 */ +#define STM32L4_USART_CR3_OFFSET 0x0008 /* Control register 3 */ +#define STM32L4_USART_BRR_OFFSET 0x000c /* Baud Rate register */ +#define STM32L4_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ +#define STM32L4_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ +#define STM32L4_USART_RQR_OFFSET 0x0018 /* Request register */ +#define STM32L4_USART_ISR_OFFSET 0x001c /* Interrupot and status register */ +#define STM32L4_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ +#define STM32L4_USART_RDR_OFFSET 0x0024 /* Receive Data register */ +#define STM32L4_USART_TDR_OFFSET 0x0028 /* Transmit Data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NUSART > 0 +# define STM32L4_USART1_CR1 (STM32L4_USART1_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART1_CR2 (STM32L4_USART1_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART1_CR3 (STM32L4_USART1_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART1_BRR (STM32L4_USART1_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART1_GTPR (STM32L4_USART1_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART1_RTOR (STM32L4_USART1_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART1_RQR (STM32L4_USART1_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART1_ISR (STM32L4_USART1_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART1_ICR (STM32L4_USART1_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART1_RDR (STM32L4_USART1_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART1_TDR (STM32L4_USART1_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 1 +# define STM32L4_USART2_CR1 (STM32L4_USART2_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART2_CR2 (STM32L4_USART2_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART2_CR3 (STM32L4_USART2_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART2_BRR (STM32L4_USART2_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART2_GTPR (STM32L4_USART2_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART2_RTOR (STM32L4_USART2_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART2_RQR (STM32L4_USART2_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART2_ISR (STM32L4_USART2_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART2_ICR (STM32L4_USART2_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART2_RDR (STM32L4_USART2_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART2_TDR (STM32L4_USART2_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 2 +# define STM32L4_USART3_CR1 (STM32L4_USART3_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART3_CR2 (STM32L4_USART3_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART3_CR3 (STM32L4_USART3_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART3_BRR (STM32L4_USART3_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART3_GTPR (STM32L4_USART3_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART3_RTOR (STM32L4_USART3_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART3_RQR (STM32L4_USART3_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART3_ISR (STM32L4_USART3_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART3_ICR (STM32L4_USART3_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART3_RDR (STM32L4_USART3_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART3_TDR (STM32L4_USART3_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 3 +# define STM32L4_UART4_CR1 (STM32L4_UART4_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_UART4_CR2 (STM32L4_UART4_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_UART4_CR3 (STM32L4_UART4_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_UART4_BRR (STM32L4_UART4_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_UART4_GTPR (STM32L4_UART4_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_UART4_RTOR (STM32L4_UART4_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_UART4_RQR (STM32L4_UART4_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_UART4_ISR (STM32L4_UART4_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_UART4_ICR (STM32L4_UART4_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_UART4_RDR (STM32L4_UART4_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_UART4_TDR (STM32L4_UART4_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 4 +# define STM32L4_UART5_CR1 (STM32L4_UART5_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_UART5_CR2 (STM32L4_UART5_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_UART5_CR3 (STM32L4_UART5_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_UART5_BRR (STM32L4_UART5_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_UART5_GTPR (STM32L4_UART5_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_UART5_RTOR (STM32L4_UART5_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_UART5_RQR (STM32L4_UART5_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_UART5_ISR (STM32L4_UART5_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_UART5_ICR (STM32L4_UART5_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_UART5_RDR (STM32L4_UART5_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_UART5_TDR (STM32L4_UART5_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */ +#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode*/ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M0 (1 << 12) /* Bit 12: word length */ +#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ +#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_DEDT_SHIFT (16) /* Bits 16..20 DE deactivation delay */ +#define USART_CR1_DEDT_MASK (0x1f << USART_CR1_DEDT_SHIFT) + +#define USART_CR1_DEAT_SHIFT (21) /* Bits 21..25 DE activation delay */ +#define USART_CR1_DEAT_MASK (0x1f << USART_CR1_DEAT_SHIFT) + +#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */ +#define USART_CR1_M1 (1 << 28) /* Bit 12: word length */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \ + USART_CR1_TCIE|USART_CR1_TXEIE|USART_CR1_PEIE|USART_CR1_CMIE| \ + USART_CR1_RTOIE|USART_CR1_EOBIE) + +/* Control register 2 */ + +#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: */ +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ + +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ + +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ +#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ +#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ +#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ +#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ +#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto Baud rate enable */ + +#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Autobaud rate mode*/ +#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) +#define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* 00: Start bit */ +#define USART_CR2_ABRMOD_EDGES (1 << USART_CR2_ABRMOD_SHIFT) /* 01: Falling-to-falling edge -> frame must start with 10xxxxxx */ +#define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 10: 0x7F */ +#define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 11: 0x55 */ + +#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ + +#define USART_CR2_ADD_SHIFT (24) /* Bits 24-31: Address of the USART node */ +#define USART_CR2_ADD_MASK (0xff << USART_CR2_ADD_SHIFT) + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR3_ONEBIT (1 << 11) /* Bit 11: One sample bit method Enable */ +#define USART_CR3_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ +#define USART_CR3_DDRE (1 << 13) /* Bit 13: DMA disable on Reception error */ +#define USART_CR3_DEM (1 << 14) /* Bit 14: Driver Enable mode */ +#define USART_CR3_DEP (1 << 15) /* Bit 15: Driver Enable polarity selection */ +#define USART_CR3_SCARCNT2_SHIFT (17) /* Bits 17-19: Smart card auto retry count */ +#define USART_CR3_SCARCNT2_MASK (7 << USART_CR3_SCARCNT2_SHIFT) +#define USART_CR3_WUS_SHIFT (20) /* Bits 20-21: Wakeup from Stop mode interrupt flag selection */ +#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) /* 00: WUF active on address match */ +#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) /* 10: WUF active on Start bit detection */ +#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) /* 11: WUF active on RXNE */ +#define USART_CR3_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Receiver timeout register */ + +/* Request Register */ + +#define USART_CR1_SBRKQ (1 << 1) /* Bit 0: Send Break */ + +/* Interrupt and Status register */ + +#define USART_ISR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_ISR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_ISR_NF (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_ISR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_ISR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_ISR_CTS (1 << 9) /* Bit 9: CTS Flag */ +#define USART_ISR_RTOF (1 << 10) /* Bit 10: Receiver timeout Flag */ +#define USART_ISR_EOBF (1 << 11) /* Bit 11: End of block Flag */ +#define USART_ISR_ABRE (1 << 12) /* Bit 12: Auto baud rate Error */ +#define USART_ISR_ABRF (1 << 14) /* Bit 14: Auto baud rate Flag */ +#define USART_ISR_BUSY (1 << 15) /* Bit 15: Busy Flag */ +#define USART_ISR_CMF (1 << 16) /* Bit 16: Character match Flag */ +#define USART_ISR_SBKF (1 << 17) /* Bit 17: Send break Flag */ +#define USART_ISR_RWU (1 << 18) /* Bit 18: Receiver wakeup from Mute mode */ +#define USART_ISR_WUF (1 << 19) /* Bit 19: Wakeup from Stop mode Flag */ +#define USART_ISR_TEACK (1 << 20) /* Bit 20: Transmit enable acknowledge Flag */ +#define USART_ISR_REACK (1 << 21) /* Bit 21: Receive enable acknowledge Flag */ + +/* ICR */ + +#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ +#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ +#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected clear flag */ +#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ +#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ +#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete clear flag */ +#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ +#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS clear flag */ +#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ +#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ +#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ + +/* Receive Data register */ + +#define USART_RDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_RDR_MASK (0xff << USART_RDR_SHIFT) + +/* Transmit Data register */ + +#define USART_TDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_TDR_MASK (0xff << USART_TDR_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32L4_CHIP_STM32L4X6XX_UART_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4.h b/arch/arm/src/stm32l4/stm32l4.h new file mode 100644 index 0000000000000000000000000000000000000000..c78865577d2c10811dbfa3abdbd60e9ee38b75d6 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4.h @@ -0,0 +1,96 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Uros Platise + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Additional Configuration *********************************************************/ +/* Custom debug settings used in the STM32L4 port. These are managed by + * STM32L4-specific logic and not the common logic in include/debug.h. + * NOTE: Some of these also depend on CONFIG_DEBUG_VERBOSE + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +# undef CONFIG_DEBUG_RTC +# undef CONFIG_DEBUG_I2C +# undef CONFIG_DEBUG_CAN +# undef CONFIG_DEBUG_PWM +# undef CONFIG_DEBUG_SENSORS +#endif + +/* Peripherals **********************************************************************/ + +#include "chip.h" +#include "stm32l4_adc.h" +//#include "stm32_bkp.h" +#include "stm32l4_can.h" +#include "stm32l4_dbgmcu.h" +#include "stm32l4_dma.h" +#include "stm32l4_exti.h" +#include "stm32l4_flash.h" +#include "stm32l4_fsmc.h" +#include "stm32l4_gpio.h" +#include "stm32l4_i2c.h" +#include "stm32l4_lcd.h" +#include "stm32l4_pwr.h" +#include "stm32l4_rcc.h" +#include "stm32l4_rtc.h" +#include "stm32l4_sdio.h" +#include "stm32l4_spi.h" +#include "stm32l4_tim.h" +#include "stm32l4_uart.h" +#include "stm32l4_usbdev.h" +#include "stm32l4_wdg.h" +#include "stm32l4_lowputc.h" + +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_adc.h b/arch/arm/src/stm32l4/stm32l4_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_allocateheap.c b/arch/arm/src/stm32l4/stm32l4_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..e1c2e1acafcba8020e3532f174dfe26aa0ca23f3 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_allocateheap.c @@ -0,0 +1,375 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/up_allocateheap.c + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32l4_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Internal SRAM is available in all members of the STM32L4 family. The + * following definitions must be provided to specify the size and + * location of internal(system) SRAM: + * + * SRAM1_END 0x20018000 + * SRAM2_START 0x10000000 + * SRAM2_END 0x10008000 + * + * In addition to internal SRAM, SRAM may also be available through the FSMC. + * In order to use FSMC SRAM, the following additional things need to be + * present in the NuttX configuration file: + * + * CONFIG_STM32L4_FSMC=y : Enables the FSMC + * CONFIG_STM32L4_FSMC_SRAM=y : Indicates that SRAM is available via the + * FSMC (as opposed to an LCD or FLASH). + * CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC + * address space + * CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC + * address space + * CONFIG_MM_REGIONS : Must be set to a large enough value to + * include the FSMC SRAM (as determined by + * the rules provided below) + */ + +#ifndef CONFIG_STM32L4_FSMC +# undef CONFIG_STM32L4_FSMC_SRAM +#endif + +/* MSTM32L4x6xx have 128Kib in two banks, both accessible to DMA: + * + * 1) 96KiB of System SRAM beginning at address 0x2000:0000 - 0x2001:8000 + * 2) 32KiB of System SRAM beginning at address 0x1000:0000 - 0x1000:8000 + * + * In addition, external FSMC SRAM may be available. + */ + +/* Set the end of system SRAM */ + +#define SRAM1_END 0x20018000 + +/* Set the range of SRAM2 as well, requires a second memory region */ + +#define SRAM2_START 0x10000000 +#define SRAM2_END 0x10008000 + +/* Allocations according to the number of memory regions: + * + * 1 region available: + * - map it to SRAM1 + * - warn that SRAM2 is not available for heap + * - if FMC is enabled, warn that it is not available for heap + * + * 2 regions available: map them to SRAM1 and SRAM2 + * - map region 1 to SRAM1 + * - map region 2 to SRAM2 + * - if FMC is enabled, warn that it is not available for heap + * + * 3 or more regions + * + * - map them to SRAM1, SRAM2, FMC + */ + +#if CONFIG_MM_REGIONS < 1 +# warning heap is not usable + +#elif CONFIG_MM_REGIONS < 2 + +# warning SRAM2 (32k) is NOT available for heap, only SRAM1 (96k) : not enough MM regions +# undef SRAM2_START +# undef SRAM2_END + +# if defined(CONFIG_STM32L4_FSMC_SRAM) +# warning FMC SRAM is NOT available for heap : not enough MM regions (1) +# undef CONFIG_STM32L4_FSMC_SRAM +# endif + +#elif CONFIG_MM_REGIONS < 3 + +# if defined(CONFIG_STM32L4_FSMC_SRAM) +# warning FMC SRAM is NOT available for heap : not enough MM regions (2) +# undef CONFIG_STM32L4_FSMC_SRAM +# endif + +#elif CONFIG_MM_REGIONS > 3 + +/*Everything can be mapped but some entries wont be used -> warn and correct*/ +# warning "CONFIG_MM_REGIONS > 3 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 3 + +#else +/*Everything can be mapped*/ +#endif + + +/* If FSMC SRAM is going to be used as heap, then verify that the starting + * address and size of the external SRAM region has been provided in the + * configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE). + */ + +#ifdef CONFIG_STM32L4_FSMC_SRAM +# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE) +# error "CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided" +# undef CONFIG_STM32L4_FSMC_SRAM +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_HEAP +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)ubase, usize); + + /* Allow user-mode access to the user heap memory */ + + stm32l4_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SRAM1_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the SRAM2 heap */ + + stm32l4_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END-SRAM2_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + + /* Add the SRAM2 user heap region. */ + + kumm_addregion((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + +#ifdef CONFIG_STM32L4_FSMC_SRAM +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the FSMC SRAM user heap memory */ + + stm32l4_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + + /* Add the external FSMC SRAM user heap region. */ + + kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/stm32l4/stm32l4_can.h b/arch/arm/src/stm32l4/stm32l4_can.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_dbgmcu.h b/arch/arm/src/stm32l4/stm32l4_dbgmcu.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_dma.c b/arch/arm/src/stm32l4/stm32l4_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..c1b25e64dee075344bddc46c99ae6a2aaf7d9293 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_dma.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_dma.c + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* This file is only a thin shell that includes the correct DMA implementation + * for the selected STM32 family. The correct file cannot be selected by + * the make system because it needs the intelligence that only exists in + * chip.h that can associate an STM32 part number with an STM32 family. + */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +#include "stm32l4x6xx_dma.c" +#else +# error "Unsupported STM32L4 chip" +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4_dma.h b/arch/arm/src/stm32l4/stm32l4_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..9fd36a6337350fa29a05e5363c2f514c556fe63b --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_dma.h @@ -0,0 +1,301 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_DMA_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/* Include the correct DMA register definitions for this STM32 family */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_dma.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/* These definitions provide the bit encoding of the 'status' parameter passed to the + * DMA callback function (see dma_callback_t). + */ + +# define DMA_STATUS_FEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_DMEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_TEIF DMA_CHAN_TEIF_BIT /* Channel Transfer Error */ +# define DMA_STATUS_HTIF DMA_CHAN_HTIF_BIT /* Channel Half Transfer */ +# define DMA_STATUS_TCIF DMA_CHAN_TCIF_BIT /* Channel Transfer Complete */ + +#define DMA_STATUS_ERROR (DMA_STATUS_FEIF|DMA_STATUS_DMEIF|DMA_STATUS_TEIF) +#define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA + * channel (F1) or a DMA stream (F4). + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the the + * completion of the DMA. + * + * Input Parameters: + * handle - Refers tot he DMA channel or stream + * status - A bit encoded value that provides the completion status. See the + * DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when stm32l4_dmastart() was + * called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +#ifdef CONFIG_DEBUG_DMA +struct stm32l4_dmaregs_s +{ + uint32_t isr; + uint32_t ccr; + uint32_t cndtr; + uint32_t cpar; + uint32_t cmar; +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chan' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32l4_dma.h. + * + * If the DMA channel is not available, then stm32l4_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32l4_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32l4_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chan - Identifies the stream/channel resource + * For the STM32 F1, this is simply the channel number as provided by + * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h. + * For the STM32 F4, this is a bit encoded value as provided by the + * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'chan' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chan' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32l4_dmachannel(unsigned int chan); + +/**************************************************************************** + * Name: stm32l4_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32l4_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32l4_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr); + +/**************************************************************************** + * Name: stm32l4_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, + bool half); + +/**************************************************************************** + * Name: stm32l4_dmastop + * + * Description: + * Cancel the DMA. After stm32l4_dmastop() is called, the DMA channel is + * reset and stm32l4_dmasetup() must be called before stm32l4_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +void stm32l4_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +size_t stm32l4_dmaresidual(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address with the given configuration. This depends on the internal + * connections in the ARM bus matrix of the processor. Note that this + * only applies to memory addresses, it will return false for any peripheral + * address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_DMACAPABLE +bool stm32l4_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr); +#else +# define stm32l4_dmacapable(maddr, count, ccr) (true) +#endif + +/**************************************************************************** + * Name: stm32l4_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmasample(DMA_HANDLE handle, struct stm32l4_dmaregs_s *regs); +#else +# define stm32l4_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: stm32l4_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmadump(DMA_HANDLE handle, const struct stm32l4_dmaregs_s *regs, + const char *msg); +#else +# define stm32l4_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_DMA_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_dtcm.c b/arch/arm/src/stm32l4/stm32l4_dtcm.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_dumpgpio.c b/arch/arm/src/stm32l4/stm32l4_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_exti.h b/arch/arm/src/stm32l4/stm32l4_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..87dbd78c25506963cf1e2830bb347ed2cd513c01 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti.h @@ -0,0 +1,119 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_exti.h + * + * Copyright (C) 2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_EXTI_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32l4_exti.h" + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Name: stm32l4_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +xcpt_t stm32l4_exti_alarm(bool risingedge, bool fallingedge, bool event, xcpt_t func); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_EXTI_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_exti_alarm.c b/arch/arm/src/stm32l4/stm32l4_exti_alarm.c new file mode 100644 index 0000000000000000000000000000000000000000..8f145ccd4fd44802814624235cb82fe31f3a39cf --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_alarm.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_alarm.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Diego Sanchez + * dev@ziggurat29.com (adaptation to stm32l4) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the ALARM EXTI */ + +static xcpt_t stm32l4_exti_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_alarm_isr + * + * Description: + * EXTI ALARM interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32l4_exti_alarm_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI1_RTC_ALARM, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callback) + { + ret = stm32l4_exti_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edget + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_callback; + stm32l4_exti_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32L4_IRQ_RTCALRM, stm32l4_exti_alarm_isr); + up_enable_irq(STM32L4_IRQ_RTCALRM); + } + else + { + up_disable_irq(STM32L4_IRQ_RTCALRM); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : EXTI1_RTC_ALARM, + risingedge ? EXTI1_RTC_ALARM : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : EXTI1_RTC_ALARM, + fallingedge ? EXTI1_RTC_ALARM : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : EXTI1_RTC_ALARM, + event ? EXTI1_RTC_ALARM : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : EXTI1_RTC_ALARM, + func ? EXTI1_RTC_ALARM : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_gpio.c b/arch/arm/src/stm32l4/stm32l4_exti_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..ede05e83221963110e1e4bb108b51e2a3e54c2ff --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_gpio.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_gpio.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static xcpt_t stm32l4_exti_callbacks[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routines - Dispatchers + ****************************************************************************/ + +static int stm32l4_exti0_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0001, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[0]) + { + ret = stm32l4_exti_callbacks[0](irq, context); + } + + return ret; +} + +static int stm32l4_exti1_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0002, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[1]) + { + ret = stm32l4_exti_callbacks[1](irq, context); + } + + return ret; +} + +static int stm32l4_exti2_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0004, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[2]) + { + ret = stm32l4_exti_callbacks[2](irq, context); + } + + return ret; +} + +static int stm32l4_exti3_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0008, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[3]) + { + ret = stm32l4_exti_callbacks[3](irq, context); + } + + return ret; +} + +static int stm32l4_exti4_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0010, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[4]) + { + ret = stm32l4_exti_callbacks[4](irq, context); + } + + return ret; +} + +static int stm32l4_exti_multiisr(int irq, void *context, int first, int last) +{ + uint32_t pr; + int pin; + int ret = OK; + + /* Examine the state of each pin in the group */ + + pr = getreg32(STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + for (pin = first; pin <= last; pin++) + { + /* Is an interrupt pending on this pin? */ + + uint32_t mask = (1 << pin); + if ((pr & mask) != 0) + { + /* Clear the pending interrupt */ + + putreg32(mask, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[pin]) + { + int tmp = stm32l4_exti_callbacks[pin](irq, context); + if (tmp != OK) + { + ret = tmp; + } + } + } + } + + return ret; +} + +static int stm32l4_exti95_isr(int irq, void *context) +{ + return stm32l4_exti_multiisr(irq, context, 5, 9); +} + +static int stm32l4_exti1510_isr(int irq, void *context) +{ + return stm32l4_exti_multiisr(irq, context, 10, 15); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func) +{ + uint32_t pin = pinset & GPIO_PIN_MASK; + uint32_t exti = STM32L4_EXTI1_BIT(pin); + int irq; + xcpt_t handler; + xcpt_t oldhandler = NULL; + int nshared; + xcpt_t *shared_cbs; + int i; + + /* Select the interrupt handler for this EXTI pin */ + + if (pin < 5) + { + irq = pin + STM32L4_IRQ_EXTI0; + nshared = 1; + shared_cbs = &stm32l4_exti_callbacks[pin]; + switch (pin) + { + case 0: + handler = stm32l4_exti0_isr; + break; + + case 1: + handler = stm32l4_exti1_isr; + break; + + case 2: + handler = stm32l4_exti2_isr; + break; + + case 3: + handler = stm32l4_exti3_isr; + break; + + default: + handler = stm32l4_exti4_isr; + break; + } + } + else if (pin < 10) + { + irq = STM32L4_IRQ_EXTI95; + handler = stm32l4_exti95_isr; + shared_cbs = &stm32l4_exti_callbacks[5]; + nshared = 5; + } + else + { + irq = STM32L4_IRQ_EXTI1510; + handler = stm32l4_exti1510_isr; + shared_cbs = &stm32l4_exti_callbacks[10]; + nshared = 6; + } + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_callbacks[pin]; + stm32l4_exti_callbacks[pin] = func; + + /* Install external interrupt handlers */ + + if (func) + { + irq_attach(irq, handler); + up_enable_irq(irq); + } + else + { + /* Only disable IRQ if shared handler does not have any active + * callbacks. + */ + + for (i = 0; i < nshared; i++) + { + if (shared_cbs[i] != NULL) + { + break; + } + } + + if (i == nshared) + { + up_disable_irq(irq); + } + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + if (event || func) + { + pinset |= GPIO_EXTI; + } + + stm32l4_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : exti, + risingedge ? exti : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : exti, + fallingedge ? exti : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : exti, + event ? exti : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : exti, + func ? exti : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_pwr.c b/arch/arm/src/stm32l4/stm32l4_exti_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..f037936c649934f1002fa4d01cedd2707e61185b --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_pwr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_pwr.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Gregory Nutt + * Dmitry Nikolaev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" +#include "stm32l4_exti_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the PVD EXTI */ + +static xcpt_t stm32l4_exti_pvd_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd_isr + * + * Description: + * EXTI PVD interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32l4_exti_pvd_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI1_PVD_LINE, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_pvd_callback) + { + ret = stm32l4_exti_pvd_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_pvd_callback; + stm32l4_exti_pvd_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32L4_IRQ_PVD, stm32l4_exti_pvd_isr); + up_enable_irq(STM32L4_IRQ_PVD); + } + else + { + up_disable_irq(STM32L4_IRQ_PVD); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : EXTI1_PVD_LINE, + risingedge ? EXTI1_PVD_LINE : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : EXTI1_PVD_LINE, + fallingedge ? EXTI1_PVD_LINE : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : EXTI1_PVD_LINE, + event ? EXTI1_PVD_LINE : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : EXTI1_PVD_LINE, + func ? EXTI1_PVD_LINE : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_pwr.h b/arch/arm/src/stm32l4/stm32l4_exti_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..5789e37076489ba45d4ea522e8e7316bf057eba7 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_pwr.h @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_pwr.h + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Dmitry Nikolaev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef STM32L4_EXTI_PWR_H_ +#define STM32L4_EXTI_PWR_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func); + +#endif /* STM32L4_EXTI_PWR_H_ */ diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.c b/arch/arm/src/stm32l4/stm32l4_firewall.c new file mode 100644 index 0000000000000000000000000000000000000000..46cc3ff62de8ee00d7067cb835dc477dc826e5f2 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_firewall.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_firewall.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stm32l4_firewall.h" + +int stm32l4_firewallsetup(FAR struct stm32l4_firewall_t *setup) + { + uint32_t reg; + + /* code and nvdata must be aligned to 256 bytes + * data must be aligned to 64 bytes + */ + if( (setup->codestart & 0xFF) || (setup->nvdatastart & 0xFF) || (setup->datastart & 0x3F) ) + { + return -1; + } + + /* code and nvdata length must be a multiple of 256 bytes + * data length must be a multiple of 64 bytes + */ + if( (setup->codelen & 0xFF) || (setup->nvdatalen & 0xFF) || (setup->datalen & 0x3F) ) + { + return -1; + } + + /* + * code and nvdata must be in flash + * data must be in SRAM1 + */ + if( (setup->codestart & STM32L4_REGION_MASK) != STM32L4_FLASH_BASE) + { + return -1; + } + + if( (setup->nvdatastart & STM32L4_REGION_MASK) != STM32L4_FLASH_BASE) + { + return -1; + } + + /* Define address and length registers */ + modifyreg32(STM32L4_FIREWALL_CSSA , FIREWALL_CSSADD_MASK , setup->codestart ); + modifyreg32(STM32L4_FIREWALL_CSL , FIREWALL_CSSLENG_MASK , setup->codelen ); + modifyreg32(STM32L4_FIREWALL_NVDSSA, FIREWALL_NVDSADD_MASK , setup->nvdatastart); + modifyreg32(STM32L4_FIREWALL_NVDSL , FIREWALL_NVDSLENG_MASK, setup->nvdatalen ); + modifyreg32(STM32L4_FIREWALL_VDSSA , FIREWALL_VDSADD_MASK , setup->datastart ); + modifyreg32(STM32L4_FIREWALL_VDSL , FIREWALL_VDSLENG_MASK , setup->datalen ); + + /* Define access options */ + reg = getreg32(STM32L4_FIREWALL_CR); + if(setup->datashared) + { + reg |= FIREWALL_CR_VDS; + } + if(setup->dataexec) + { + reg |= FIREWALL_CR_VDE; + } + + putreg32(reg, STM32L4_FIREWALL_CR); + + /* Enable firewall */ + reg = getreg32(STM32L4_SYSCFG_CFGR1); + reg &= ~SYSCFG_CFGR1_FWDIS; + putreg32(reg, STM32L4_SYSCFG_CFGR1); + + /* Now protected code can only be accessed by jumping to the FW gate */ + return 0; + } + diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.h b/arch/arm/src/stm32l4/stm32l4_firewall.h new file mode 100644 index 0000000000000000000000000000000000000000..989e7e3c302f84248e08f8101f6d29f0f9acc49d --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_firewall.h @@ -0,0 +1,111 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_firewall.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_FIREWALL_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_FIREWALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/* Include the correct firewall register definitions for this STM32L4 family */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_firewall.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +struct stm32l4_firewall_t + { + uintptr_t *codestart; + size_t codelen; + uintptr_t *nvdatastart; + size_t nvdatalen; + uintptr_t *datastart; + size_t datalen; + uint8_t datashared:1; + uint8_t dataexec :1; + }; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_firewallsetup + * + * Description: + * Configure the STM32L4 firewall. After this, protected code will only + * be accessible via the "entry gate". + * Once enabled, the firewall cannot be enabled until the next reset. + * Returns 0 when OK, -1 when addresses and length are not properly aligned. + * + ****************************************************************************/ + +int stm32l4_firewallsetup(FAR struct stm32l4_firewall_t *setup); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_FIREWALL_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_flash.h b/arch/arm/src/stm32l4/stm32l4_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..ecb6fccb0a9dba169d512e7a9eda3cffdb6b44ac --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_flash.h @@ -0,0 +1,218 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_flash.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_FLASH_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_FLASH_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define _K(x) ((x)*1024) + +#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_C) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_E) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_G) +# define CONFIG_STM32L4_FLASH_CONFIG_DEFAULT +#endif + +#if defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) +# define STM32L4_FLASH_NPAGES 512 +# define STM32L4_FLASH_PAGESIZE 2048 +#endif /* CONFIG_STM32L4_FLASH_CONFIG_DEFAULT */ + +/* Override of the Flash Has been Chosen */ + +#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) + +/* Define the Valid Configuration the F1 and F3 */ + +# if defined(CONFIG_STM32L4_FLASH_CONFIG_C) /* 256 kB */ +# define STM32L4_FLASH_NPAGES 128 +# define STM32L4_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32L4_FLASH_CONFIG_E) /* 512 kB */ +# define STM32L4_FLASH_NPAGES 256 +# define STM32L4_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32L4_FLASH_CONFIG_G) /* 1 MB */ +# define STM32L4_FLASH_NPAGES 512 +# define STM32L4_FLASH_PAGESIZE 2048 +# else +# endif +#endif + +#ifdef STM32L4_FLASH_PAGESIZE +# define STM32L4_FLASH_SIZE (STM32L4_FLASH_NPAGES * STM32L4_FLASH_PAGESIZE) +#endif /* def STM32L4_FLASH_PAGESIZE */ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_FLASH_ACR_OFFSET 0x0000 +#define STM32L4_FLASH_PDKEYR_OFFSET 0x0004 +#define STM32L4_FLASH_KEYR_OFFSET 0x0008 +#define STM32L4_FLASH_OPTKEYR_OFFSET 0x000c +#define STM32L4_FLASH_SR_OFFSET 0x0010 +#define STM32L4_FLASH_CR_OFFSET 0x0014 +#define STM32L4_FLASH_ECCR_OFFSET 0x0018 +#define STM32L4_FLASH_OPTR_OFFSET 0x0020 +#define STM32L4_FLASH_PCROP1SR_OFFSET 0x0024 +#define STM32L4_FLASH_PCROP1ER_OFFSET 0x0028 +#define STM32L4_FLASH_WRP1AR_OFFSET 0x002c +#define STM32L4_FLASH_WRP1BR_OFFSET 0x0030 +#define STM32L4_FLASH_PCROP2SR_OFFSET 0x0044 +#define STM32L4_FLASH_PCROP2ER_OFFSET 0x0048 +#define STM32L4_FLASH_WRP2AR_OFFSET 0x004c +#define STM32L4_FLASH_WRP2BR_OFFSET 0x0050 + +/* Register Addresses ***************************************************************/ + +#define STM32L4_FLASH_ACR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_ACR_OFFSET) +#define STM32L4_FLASH_PDKEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PDKEYR_OFFSET) +#define STM32L4_FLASH_KEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_KEYR_OFFSET) +#define STM32L4_FLASH_OPTKEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_OPTKEYR_OFFSET) +#define STM32L4_FLASH_SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_SR_OFFSET) +#define STM32L4_FLASH_CR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_CR_OFFSET) +#define STM32L4_FLASH_ECCR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_ECCR_OFFSET) +#define STM32L4_FLASH_OPTR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_OPTR_OFFSET) +#define STM32L4_FLASH_PCROP1SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP1SR_OFFSET) +#define STM32L4_FLASH_PCROP1ER (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP1ER_OFFSET) +#define STM32L4_FLASH_WRP1AR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP1AR_OFFSET) +#define STM32L4_FLASH_WRP1BR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP1BR_OFFSET) +#define STM32L4_FLASH_PCROP2SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP2SR_OFFSET) +#define STM32L4_FLASH_PCROP2ER (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP2ER_OFFSET) +#define STM32L4_FLASH_WRP2AR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP2AR_OFFSET) +#define STM32L4_FLASH_WRP2BR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP2BR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ +/* Flash Access Control Register (ACR) */ + +#define FLASH_ACR_LATENCY_SHIFT (0) +#define FLASH_ACR_LATENCY_MASK (7 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* n wait states , for Vcore range 1 2 */ +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 000: Zero wait states <=16 <=6 */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 001: One wait state <=32 <=12 */ +# define FLASH_ACR_LATENCY_2 (2 << FLASH_ACR_LATENCY_SHIFT) /* 010: Two wait states <=48 <=18 */ +# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 011: Three wait states <=64 <=26 */ +# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 100: Four wait states <=80 <=26 */ + +#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Pprefetch enable */ +#define FLASH_ACR_ICEN (1 << 9) /* Bit 9: Instruction cache enable */ +#define FLASH_ACR_DCEN (1 << 10) /* Bit 10: Data cache enable */ +#define FLASH_ACR_ICRST (1 << 11) /* Bit 11: Instruction cache reset */ +#define FLASH_ACR_DCRST (1 << 12) /* Bit 12: Data cache reset */ +#define FLASH_ACR_RUN_PD (1 << 13) /* Bit 13: Flash mode during Run */ +#define FLASH_ACR_SLEEP_PD (1 << 14) /* Bit 14: Flash mode during Sleep */ + +/* Flash Status Register (SR) */ + +#define FLASH_SR_EOP (1 << 0) /* Bit 0: End of operation */ +#define FLASH_SR_OPERR (1 << 1) /* Bit 1: Operation error */ +#define FLASH_SR_WRPERR (1 << 4) /* Bit 4: Write protection error */ +#define FLASH_SR_PGAERR (1 << 5) /* Bit 5: Programming alignment error */ +#define FLASH_SR_SIZERR (1 << 6) /* Bit 6: Size error */ +#define FLASH_SR_PGSERR (1 << 7) /* Bit 7: Programming sequence error */ +#define FLASH_SR_MISERR (1 << 8) /* Bit 8: Fast programming data miss error */ +#define FLASH_SR_FASTERR (1 << 9) /* Bit 9: Fast programming error */ +#define FLASH_SR_RDERR (1 << 14) /* Bit 14: PCROP read error */ +#define FLASH_SR_OPTVERR (1 << 15) /* Bit 15: Option validity error */ +#define FLASH_SR_BSY (1 << 16) /* Bit 16: Busy */ + +/* Flash Control Register (CR) */ + +#define FLASH_CR_PG (1 << 0) /* Bit 0 : Program Page */ +#define FLASH_CR_PER (1 << 1) /* Bit 1 : Page Erase */ +#define FLASH_CR_MER1 (1 << 2) /* Bit 2 : Mass Erase Bank 1 */ + +#define FLASH_CR_PNB_SHIFT (3) /* Bits 3-10: Page number */ +#define FLASH_CR_PNB_MASK (0xFF << FLASH_CR_PNB_SHIFT) +#define FLASH_CR_PNB(n) ((n) << FLASH_CR_PNB_SHIFT) /* Page n (if BKER=0) or n+256 (if BKER=1), n=0..255 */ + +#define FLASH_CR_BKER (1 << 11) /* Bit 11: Page number MSB (Bank selection) */ +#define FLASH_CR_MER2 (1 << 15) /* Bit 15: Mass Erase Bank 2 */ +#define FLASH_CR_START (1 << 16) /* Bit 16: Start Erase */ +#define FLASH_CR_OPTSTRT (1 << 17) /* Bit 17: Options modification Start */ +#define FLASH_CR_FSTPG (1 << 23) /* Bit 23: Fast programming */ +#define FLASH_CR_EOPIE (1 << 24) /* Bit 24: End of operation interrupt enable */ +#define FLASH_CR_ERRIE (1 << 25) /* Bit 25: Error interrupt enable */ +#define FLASH_CR_RDERRIE (1 << 26) /* Bit 26: PCROP read error interrupt enable */ +#define FLASH_CR_OBL_LAUNCH (1 << 27) /* Bit 27: Option Byte Loading */ +#define FLASH_CR_OPTLOCK (1 << 30) /* Bit 30: Option Lock */ +#define FLASH_CR_LOCK (1 << 31) /* Bit 31: Lock */ + +/* Flash ECC Register (ECCR) */ + +#define FLASH_ECCR_ADDR_ECC_SHIFT (0) /* Bits 8-15: Read protect */ +#define FLASH_ECCR_ADDR_ECC_MASK (0x07ffff << FLASH_ECCR_ADDR_ECC_SHIFT) +#define FLASH_ECCR_BK_ECC (1 << 19) /* Bit 19: ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC (1 << 20) /* Bit 20: System Flash ECC fail */ +#define FLASH_ECCR_ECCCIE (1 << 24) /* Bit 24: ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC (1 << 30) /* Bit 30: ECC correction */ +#define FLASH_ECCR_ECCD (1 << 31) /* Bit 31: ECC detection */ + +/* Flash Option Control Register (OPTCR) */ + +#define FLASH_OPTCR_NRST_STOP (1 << 12) /* Bit 12: Generate reset when entering the Stop mode */ +#define FLASH_OPTCR_NRST_STDBY (1 << 13) /* Bit 13: Generate reset when entering the Standby mode */ +#define FLASH_OPTCR_NRST_SHDW (1 << 14) /* Bit 14: Generate reset when entering the Shutdown mode */ +#define FLASH_OPTCR_IWDG_SW (1 << 16) /* Bit 16: Independent watchdog selection */ +#define FLASH_OPTCR_IWDG_STOP (1 << 17) /* Bit 17: Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTCR_IWDG_STDBY (1 << 18) /* Bit 18: Independent watchdog counter freeze in Standby mode*/ +#define FLASH_OPTCR_WWDG_SW (1 << 19) /* Bit 19: Window watchdog selection */ +#define FLASH_OPTCR_BFB2 (1 << 20) /* Bit 20: Dual bank boot */ +#define FLASH_OPTCR_DUALBANK (1 << 21) /* Bit 21: Dual bank enable */ +#define FLASH_OPTCR_NBOOT1 (1 << 23) /* Bit 23: Boot configuration */ +#define FLASH_OPTCR_SRAM2_PE (1 << 24) /* Bit 24: SRAM2 parity check enable */ +#define FLASH_OPTCR_SRAM2_RST (1 << 25) /* Bit 24: SRAM2 Erase when system reset */ +#define FLASH_OPTCR_BORLEV_SHIFT (8) /* Bits 8-10: BOR reset Level */ +#define FLASH_OPTCR_BORLEV_MASK (7 << FLASH_OPTCR_BORLEV_SHIFT) +#define FLASH_OPTCR_VBOR0 (0 << FLASH_OPTCR_BORLEV_SHIFT) /* 000: BOR Level 0 (1.7 V) */ +#define FLASH_OPTCR_VBOR1 (1 << FLASH_OPTCR_BORLEV_SHIFT) /* 001: BOR Level 1 (2.0 V) */ +#define FLASH_OPTCR_VBOR2 (2 << FLASH_OPTCR_BORLEV_SHIFT) /* 010: BOR Level 2 (2.2 V) */ +#define FLASH_OPTCR_VBOR3 (3 << FLASH_OPTCR_BORLEV_SHIFT) /* 011: BOR Level 3 (2.5 V) */ +#define FLASH_OPTCR_VBOR4 (4 << FLASH_OPTCR_BORLEV_SHIFT) /* 100: BOR Level 4 (2.8 V) */ +#define FLASH_OPTCR_RDP_SHIFT (0) /* Bits 0-7: Read Protection Level */ +#define FLASH_OPTCR_RDP_MASK (0xFF << FLASH_OPTCR_RDP_SHIFT) +#define FLASH_OPTCR_RDP_NONE (0xAA << FLASH_OPTCR_RDP_SHIFT) +#define FLASH_OPTCR_RDP_CHIP (0xCC << FLASH_OPTCR_RDP_SHIFT) /* WARNING, CANNOT BE REVERSED !! */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void STM32L4_flash_lock(void); +void STM32L4_flash_unlock(void); + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_FLASH_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_fsmc.h b/arch/arm/src/stm32l4/stm32l4_fsmc.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_gpio.c b/arch/arm/src/stm32l4/stm32l4_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..8ae6efdb11857001c0cbc7709d2601792d243248 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_gpio.c @@ -0,0 +1,451 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_gpio.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4_gpio.h" + +#if defined(CONFIG_STM32L4_STM32L478XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4_syscfg.h" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[STM32L4_NPORTS] = +{ +#if STM32L4_NPORTS > 0 + STM32L4_GPIOA_BASE, +#endif +#if STM32L4_NPORTS > 1 + STM32L4_GPIOB_BASE, +#endif +#if STM32L4_NPORTS > 2 + STM32L4_GPIOC_BASE, +#endif +#if STM32L4_NPORTS > 3 + STM32L4_GPIOD_BASE, +#endif +#if STM32L4_NPORTS > 4 + STM32L4_GPIOE_BASE, +#endif +#if STM32L4_NPORTS > 5 + STM32L4_GPIOF_BASE, +#endif +#if STM32L4_NPORTS > 6 + STM32L4_GPIOG_BASE, +#endif +#if STM32L4_NPORTS > 7 + STM32L4_GPIOH_BASE, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32l4_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32l4_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exlusion is necessary. + * + ****************************************************************************/ + +void stm32l4_gpioinit(void) +{ +} + +/**************************************************************************** + * Name: stm32l4_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32l4_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * A negated errono valu on invalid port, or when pin is locked as ALT + * function. + * + * To-Do: Auto Power Enable + ****************************************************************************/ + +int stm32l4_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + unsigned int regoffset; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int pinmode; + irqstate_t flags; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32L4_NPORTS) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set up the mode register (and remember whether the pin mode) */ + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input mode */ + pinmode = GPIO_MODER_INPUT; + break; + + case GPIO_OUTPUT: /* General purpose output mode */ + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + STM32L4_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + STM32L4_GPIO_MODER_OFFSET); + + /* Set up the pull-up/pull-down configuration (all but analog pins) */ + + setting = GPIO_PUPDR_NONE; + if (pinmode != GPIO_MODER_ANALOG) + { + switch (cfgset & GPIO_PUPD_MASK) + { + default: + case GPIO_FLOAT: /* No pull-up, pull-down */ + break; + + case GPIO_PULLUP: /* Pull-up */ + setting = GPIO_PUPDR_PULLUP; + break; + + case GPIO_PULLDOWN: /* Pull-down */ + setting = GPIO_PUPDR_PULLDOWN; + break; + } + } + + regval = getreg32(base + STM32L4_GPIO_PUPDR_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + STM32L4_GPIO_PUPDR_OFFSET); + + /* Set the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pin < 8) + { + regoffset = STM32L4_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32L4_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Set speed (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_SPEED_MASK) + { + default: + case GPIO_SPEED_2MHz: /* 2 MHz Low speed output */ + setting = GPIO_OSPEED_2MHz; + break; + + case GPIO_SPEED_25MHz: /* 25 MHz Medium speed output */ + setting = GPIO_OSPEED_25MHz; + break; + + case GPIO_SPEED_50MHz: /* 50 MHz High speed output */ + setting = GPIO_OSPEED_50MHz; + break; + + case GPIO_SPEED_100MHz: /* 100 MHz Very High speed output */ + setting = GPIO_OSPEED_100MHz; + break; + } + } + else + { + setting = 0; + } + + regval = getreg32(base + STM32L4_GPIO_OSPEED_OFFSET); + regval &= ~GPIO_OSPEED_MASK(pin); + regval |= (setting << GPIO_OSPEED_SHIFT(pin)); + putreg32(regval, base + STM32L4_GPIO_OSPEED_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + STM32L4_GPIO_OTYPER_OFFSET); + setting = GPIO_OTYPER_OD(pin); + + if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) && + (cfgset & GPIO_OPENDRAIN) != 0) + { + regval |= setting; + } + else + { + regval &= ~setting; + } + + putreg32(regval, base + STM32L4_GPIO_OTYPER_OFFSET); + + /* If it is an output... set the pin to the correct initial state. */ + + if (pinmode == GPIO_MODER_OUTPUT) + { + bool value = ((cfgset & GPIO_OUTPUT_SET) != 0); + stm32l4_gpiowrite(cfgset, value); + } + + /* Otherwise, it is an input pin. Should it configured as an EXTI interrupt? */ + + else if ((cfgset & GPIO_EXTI) != 0) + { +#if 0 + /* "In STM32 F1 the selection of the EXTI line source is performed through + * the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this + * selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers. + * + * "Only the mapping of the EXTICRx registers has been changed, without any + * changes to the meaning of the EXTIx bits. However, the range of EXTI + * bits values has been extended to 0b1000 to support the two ports added + * in F2, port H and I (in F1 series the maximum value is 0b0110)." + */ + + uint32_t regaddr; + int shift; + + /* Set the bits in the SYSCFG EXTICR register */ + + regaddr = STM32L4_SYSCFG_EXTICR(pin); + regval = getreg32(regaddr); + shift = SYSCFG_EXTICR_EXTI_SHIFT(pin); + regval &= ~(SYSCFG_EXTICR_PORT_MASK << shift); + regval |= (((uint32_t)port) << shift); + + putreg32(regval, regaddr); +#endif + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32l4_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * A negated errno value on invalid port + * + * To-Do: Auto Power Disable + ****************************************************************************/ + +int stm32l4_unconfiggpio(uint32_t cfgset) +{ + /* Reuse port and pin number and set it to default HiZ INPUT */ + + cfgset &= GPIO_PORT_MASK | GPIO_PIN_MASK; + cfgset |= GPIO_INPUT | GPIO_FLOAT; + + /* To-Do: Mark its unuse for automatic power saving options */ + + return stm32l4_configgpio(cfgset); +} + +/**************************************************************************** + * Name: stm32l4_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32l4_gpiowrite(uint32_t pinset, bool value) +{ + uint32_t base; + uint32_t bit; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32L4_NPORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + bit = GPIO_BSRR_SET(pin); + } + else + { + bit = GPIO_BSRR_RESET(pin); + } + + putreg32(bit, base + STM32L4_GPIO_BSRR_OFFSET); + + } +} + +/**************************************************************************** + * Name: stm32l4_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32l4_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32L4_NPORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + STM32L4_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + return 0; +} diff --git a/arch/arm/src/stm32l4/stm32l4_gpio.h b/arch/arm/src/stm32l4/stm32l4_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..185af4810fb0739ca3b612488e25f883c94bbf68 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_gpio.h @@ -0,0 +1,378 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_gpio.h + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_GPIO_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include +#include + +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_gpio.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-Processor Declarations + ************************************************************************************/ + +/* Bit-encoded input to stm32l4_configgpio() */ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually configured + * by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU .... ...X PPPP BBBB + * Outputs: MMUU .... FFOV PPPP BBBB + * Alternate Functions: MMUU AAAA FFO. PPPP BBBB + * Analog: MM.. .... .... PPPP BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ +# define GPIO_ANALOG (3 << GPIO_MODE_SHIFT) /* Analog mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (15 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) +# define GPIO_AF8 (8 << GPIO_AF_SHIFT) +# define GPIO_AF9 (9 << GPIO_AF_SHIFT) +# define GPIO_AF10 (10 << GPIO_AF_SHIFT) +# define GPIO_AF11 (11 << GPIO_AF_SHIFT) +# define GPIO_AF12 (12 << GPIO_AF_SHIFT) +# define GPIO_AF13 (13 << GPIO_AF_SHIFT) +# define GPIO_AF14 (14 << GPIO_AF_SHIFT) +# define GPIO_AF15 (15 << GPIO_AF_SHIFT) + +/* Output/Alt function frequency selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... FF.. .... .... + */ + +#define GPIO_SPEED_SHIFT (10) /* Bits 10-11: GPIO frequency selection */ +#define GPIO_SPEED_MASK (3 << GPIO_SPEED_SHIFT) +# define GPIO_SPEED_2MHz (0 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_25MHz (1 << GPIO_SPEED_SHIFT) /* 25 MHz Medium speed output */ +# define GPIO_SPEED_50MHz (2 << GPIO_SPEED_SHIFT) /* 50 MHz High speed output */ +# define GPIO_SPEED_100MHz (3 << GPIO_SPEED_SHIFT) /* 100 MHz Very High speed output */ + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ +#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */ + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * If the pin is an input, this bit is overloaded to provide the qualifier to + * distinquish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...X .... .... + */ + +#define GPIO_EXTI (1 << 8) /* Bit 8: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPPP .... + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Base addresses for each GPIO block */ + +EXTERN const uint32_t g_gpiobase[STM32L4_NPORTS]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ************************************************************************************/ + +int stm32l4_configgpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32l4_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set it + * into default HiZ state (and possibly mark it's unused) and unlock it whether + * it was previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, as unexpected + * write to the Timer Channel Output GPIO to fixed '1' or '0' while it should + * operate in PWM mode could produce excessive on-board currents and trigger + * over-current/alarm function. + * + * Returns: + * OK on success + * ERROR on invalid port + * + ************************************************************************************/ + +int stm32l4_unconfiggpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32l4_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void stm32l4_gpiowrite(uint32_t pinset, bool value); + +/************************************************************************************ + * Name: stm32l4_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool stm32l4_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Function: stm32l4_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG +int stm32l4_dumpgpio(uint32_t pinset, const char *msg); +#else +# define stm32l4_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Function: stm32l4_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32l4_start(). + * + ************************************************************************************/ + +void stm32l4_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_GPIO_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.c b/arch/arm/src/stm32l4/stm32l4_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..3a394cda7504a597d3b88b2398f7ee8c552a5f2e --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_i2c.c @@ -0,0 +1,2059 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32f3xx_i2c.c + * STM32L4 I2C driver - based on STM32F3 I2C Hardware Layer - Device Driver + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * With extensions and modifications for the F1, F2, and F4 by: + * + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregroy Nutt + * + * And this version for the STM32 F3 by + * + * Author: John Wharington + * + * Modified for STM32L4 by + * + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* Supports: + * - Master operation, 100 kHz (standard) and 400 kHz (full speed) + * - Multiple instances (shared bus) + * - Interrupt based operation + * + * Structure naming: + * - Device: structure as defined by the nuttx/i2c/i2c.h + * - Instance: represents each individual access to the I2C driver, obtained by + * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; + * Instance points to OPS, to common I2C Hardware private data and contains + * its own private data, as frequency, address, mode of operation (in the future) + * - Private: Private data of an I2C Hardware + * + * TODO + * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST) + * - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin + * - Slave support with multiple addresses (on multiple instances): + * - 2 x 7-bit address or + * - 1 x 10 bit adresses + 1 x 7 bit address (?) + * - plus the broadcast address (general call) + * - Multi-master support + * - DMA (to get rid of too many CPU wake-ups and interventions) + * - Be ready for IPMI + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32l4_rcc.h" +#include "stm32l4_i2c.h" +#include "stm32l4_waste.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_STM32L4_I2C1) || defined(CONFIG_STM32L4_I2C2) || defined(CONFIG_STM32L4_I2C3) +/* This implementation is for the STM32 F1, F2, and F4 only */ + +#if defined(CONFIG_STM32L4_STM32F30XX) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_STM32L4_I2CTIMEOSEC) && !defined(CONFIG_STM32L4_I2CTIMEOMS) +# define CONFIG_STM32L4_I2CTIMEOSEC 0 +# define CONFIG_STM32L4_I2CTIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_STM32L4_I2CTIMEOSEC) +# define CONFIG_STM32L4_I2CTIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_STM32L4_I2CTIMEOMS) +# define CONFIG_STM32L4_I2CTIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_STM32L4_I2CTIMEOTICKS +# define CONFIG_STM32L4_I2CTIMEOTICKS \ + (SEC2TICK(CONFIG_STM32L4_I2CTIMEOSEC) + MSEC2TICK(CONFIG_STM32L4_I2CTIMEOMS)) +#endif + +#ifndef CONFIG_STM32L4_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_STM32L4_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_STM32L4_I2CTIMEOTICKS) +#endif + +#define I2C_OUTPUT \ + (GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD | GPIO_MODE_50MHz) +#define MKI2C_OUTPUT(p) \ + (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Register setting unique to the STM32F30xx */ + +#define I2C_CR1_TXRX \ + (I2C_CR1_RXIE | I2C_CR1_TXIE) +#define I2C_CR1_ALLINTS \ + (I2C_CR1_TXRX | I2C_CR1_TCIE | I2C_CR1_ADDRIE | I2C_CR1_ERRIE) + +#define STATUS_NACK(status) (status & I2C_INT_NACK) +#define STATUS_ADDR(status) (status & I2C_INT_ADDR) +#define STATUS_ADDR_TX(status) (status & (I2C_INT_ADDR | I2C_ISR_TXIS)) +#define STATUS_ADD10(status) (0) +#define STATUS_RXNE(status) (status & I2C_ISR_RXNE) +#define STATUS_TC(status) (status & I2C_ISR_TC) +#define STATUS_BUSY(status) (status & I2C_ISR_BUSY) + +/* Debug ****************************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level + * debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define stm32l4_i2c_tracereset(p) +# define stm32l4_i2c_tracenew(p,s) +# define stm32l4_i2c_traceevent(p,e,a) +# define stm32l4_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Interrupt state */ + +enum stm32l4_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for completion of interrupt activity */ + INTSTATE_DONE, /* Interrupt activity complete */ +}; + +/* Trace events */ + +enum stm32l4_trace_e +{ + I2CEVENT_NONE = 0, /* No events have occurred with this status */ + I2CEVENT_SENDADDR, /* Start/Master bit set and address sent, param = msgc */ + I2CEVENT_SENDBYTE, /* Send byte, param = dcnt */ + I2CEVENT_ITBUFEN, /* Enable buffer interrupts, param = 0 */ + I2CEVENT_RCVBYTE, /* Read more dta, param = dcnt */ + I2CEVENT_REITBUFEN, /* Re-enable buffer interrupts, param = 0 */ + I2CEVENT_DISITBUFEN, /* Disable buffer interrupts, param = 0 */ + I2CEVENT_BTFNOSTART, /* BTF on last byte with no restart, param = msgc */ + I2CEVENT_BTFRESTART, /* Last byte sent, re-starting, param = msgc */ + I2CEVENT_BTFSTOP, /* Last byte sten, send stop, param = 0 */ + I2CEVENT_ERROR /* Error occurred, param = 0 */ +}; + +/* Trace data */ + +struct stm32l4_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + enum stm32l4_intstate_e event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + systime_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct stm32l4_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t reset_bit; /* Reset bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr)(int, void *); /* Interrupt handler */ + uint32_t ev_irq; /* Event IRQ */ + uint32_t er_irq; /* Error IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct stm32l4_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct stm32l4_i2c_config_s *config; /* Port configuration */ + int refs; /* Referernce count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + volatile uint8_t intstate; /* Interrupt handshake (see enum stm32l4_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + bool astart; /* START sent */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + systime_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct stm32l4_trace_s trace[CONFIG_I2C_NTRACE]; +#endif + + uint32_t status; /* End of transfer SR2|SR1 status */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +static inline uint16_t stm32l4_i2c_getreg(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset); +static inline void stm32l4_i2c_putreg(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset, + uint16_t value); +static inline void stm32l4_i2c_putreg32(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset, + uint32_t value); +static inline void stm32l4_i2c_modifyreg(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline void stm32l4_i2c_modifyreg32(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits); +static inline void stm32l4_i2c_sem_wait(FAR struct stm32l4_i2c_priv_s *priv); +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO +static useconds_t stm32l4_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_STM32L4_I2C_DYNTIMEO */ +static inline int stm32l4_i2c_sem_waitdone(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_sem_waitstop(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_sem_post(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_sem_init(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_sem_destroy(FAR struct stm32l4_i2c_priv_s *priv); +#ifdef CONFIG_I2C_TRACE +static void stm32l4_i2c_tracereset(FAR struct stm32l4_i2c_priv_s *priv); +static void stm32l4_i2c_tracenew(FAR struct stm32l4_i2c_priv_s *priv, uint32_t status); +static void stm32l4_i2c_traceevent(FAR struct stm32l4_i2c_priv_s *priv, + enum stm32l4_trace_e event, uint32_t parm); +static void stm32l4_i2c_tracedump(FAR struct stm32l4_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ +static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, + uint32_t frequency); +static inline void stm32l4_i2c_sendstart(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_clrstart(FAR struct stm32l4_i2c_priv_s *priv); +static inline void stm32l4_i2c_sendstop(FAR struct stm32l4_i2c_priv_s *priv); +static inline uint32_t stm32l4_i2c_getstatus(FAR struct stm32l4_i2c_priv_s *priv); +static int stm32l4_i2c_isr(struct stm32l4_i2c_priv_s * priv); +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32L4_I2C1 +static int stm32l4_i2c1_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_I2C2 +static int stm32l4_i2c2_isr(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_I2C3 +static int stm32l4_i2c3_isr(int irq, void *context); +#endif +#endif +static int stm32l4_i2c_init(FAR struct stm32l4_i2c_priv_s *priv); +static int stm32l4_i2c_deinit(FAR struct stm32l4_i2c_priv_s *priv); +static int stm32l4_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET +static int stm32l4_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Device Structures, Instantiation */ + +const struct i2c_ops_s stm32l4_i2c_ops = +{ + .transfer = stm32l4_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = stm32l4_i2c_reset +#endif +}; + +#ifdef CONFIG_STM32L4_I2C1 +static const struct stm32l4_i2c_config_s stm32l4_i2c1_config = +{ + .base = STM32L4_I2C1_BASE, + .clk_bit = RCC_APB1ENR_I2C1EN, + .reset_bit = RCC_APB1RSTR_I2C1RST, + .scl_pin = GPIO_I2C1_SCL, + .sda_pin = GPIO_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32l4_i2c1_isr, + .ev_irq = STM32L4_IRQ_I2C1EV, + .er_irq = STM32L4_IRQ_I2C1ER +#endif +}; + +struct stm32l4_i2c_priv_s stm32l4_i2c1_priv = +{ + .ops = &stm32l4_i2c_ops, + .config = &stm32l4_i2c1_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32L4_I2C2 +static const struct stm32l4_i2c_config_s stm32l4_i2c2_config = +{ + .base = STM32L4_I2C2_BASE, + .clk_bit = RCC_APB1ENR_I2C2EN, + .reset_bit = RCC_APB1RSTR_I2C2RST, + .scl_pin = GPIO_I2C2_SCL, + .sda_pin = GPIO_I2C2_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32l4_i2c2_isr, + .ev_irq = STM32L4_IRQ_I2C2EV, + .er_irq = STM32L4_IRQ_I2C2ER +#endif +}; + +struct stm32l4_i2c_priv_s stm32l4_i2c2_priv = +{ + .ops = &stm32l4_i2c_ops, + .config = &stm32l4_i2c2_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_STM32L4_I2C3 +static const struct stm32l4_i2c_config_s stm32l4_i2c3_config = +{ + .base = STM32L4_I2C3_BASE, + .clk_bit = RCC_APB1ENR_I2C3EN, + .reset_bit = RCC_APB1RSTR_I2C3RST, + .scl_pin = GPIO_I2C3_SCL, + .sda_pin = GPIO_I2C3_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = stm32l4_i2c3_isr, + .ev_irq = STM32L4_IRQ_I2C3EV, + .er_irq = STM32L4_IRQ_I2C3ER +#endif +}; + +struct stm32l4_i2c_priv_s stm32l4_i2c3_priv = +{ + .ops = &stm32l4_i2c_ops, + .config = &stm32l4_i2c3_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ************************************************************************************/ + +static inline uint16_t stm32l4_i2c_getreg(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_i2c_getreg32 + * + * Description: + * Get a 32-bit register value by offset + * + ************************************************************************************/ + +static inline uint32_t stm32l4_i2c_getreg32(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset) +{ + return getreg32(priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32l4_i2c_putreg(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset, + uint16_t value) +{ + putreg16(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_i2c_putreg32 + * + * Description: + * Put a 32-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32l4_i2c_putreg32(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_i2c_modifyreg + * + * Description: + * Modify a 16-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32l4_i2c_modifyreg(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32l4_i2c_modifyreg32 + * + * Description: + * Modify a 32-bit register value by offset + * + ************************************************************************************/ + +static inline void stm32l4_i2c_modifyreg32(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->config->base + offset, clearbits, setbits); +} + +/************************************************************************************ + * Name: stm32l4_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sem_wait(FAR struct stm32l4_i2c_priv_s *priv) +{ + while (sem_wait(&priv->sem_excl) != 0) + { + ASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: stm32l4_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be processed. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO +static useconds_t stm32l4_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_STM32L4_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c_enableinterrupts + * + * Description: + * Enable I2C interrupts + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline void stm32l4_i2c_enableinterrupts(struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, 0, I2C_CR1_TXRX); +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c_disableinterrupts + * + * Description: + * Enable I2C interrupts + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline void stm32l4_i2c_disableinterrupts(struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, I2C_CR1_TXRX, 0); +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int stm32l4_i2c_sem_waitdone(FAR struct stm32l4_i2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + uint32_t regval; + int ret; + + flags = enter_critical_section(); + + /* Enable I2C interrupts */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, 0, + (I2C_CR1_ALLINTS & ~I2C_CR1_TXRX)); + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_STM32L4_I2CTIMEOSEC > 0 + abstime.tv_sec += CONFIG_STM32L4_I2CTIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * stm32l4_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_STM32L4_I2CTIMEOMS > 0 + abstime.tv_nsec += CONFIG_STM32L4_I2CTIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->sem_isr, &abstime); + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by sem_timedwait. + * NOTE that we try again if we are awakened by a signal (EINTR). + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, I2C_CR1_ALLINTS, 0); + + leave_critical_section(flags); + return ret; +} +#else +static inline int stm32l4_i2c_sem_waitdone(FAR struct stm32l4_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO + timeout = USEC2TICK(stm32l4_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_STM32L4_I2CTIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + start = clock_systimer(); + + do + { + /* Poll by simply calling the timer interrupt handler until it + * reports that it is done. + */ + + stm32l4_i2c_isr(priv); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cvdbg("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, priv->status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c_set_7bit_address + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_set_7bit_address(FAR struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, I2C_CR2_SADD7_MASK, + ((priv->msgv->addr & 0x7F) << I2C_CR2_SADD7_SHIFT)); +} + +/************************************************************************************ + * Name: stm32l4_i2c_set_bytes_to_transfer + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_set_bytes_to_transfer(FAR struct stm32l4_i2c_priv_s *priv, + uint8_t n_bytes) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, I2C_CR2_NBYTES_MASK, + (n_bytes << I2C_CR2_NBYTES_SHIFT)); +} + +/************************************************************************************ + * Name: stm32l4_i2c_set_write_transfer_dir + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_set_write_transfer_dir(FAR struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, I2C_CR2_RD_WRN, 0); +} + +/************************************************************************************ + * Name: stm32l4_i2c_set_read_transfer_dir + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_set_read_transfer_dir(FAR struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, 0, I2C_CR2_RD_WRN); +} + +/************************************************************************************ + * Name: stm32l4_i2c_enable_autoend + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_enable_autoend(FAR struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, 0, I2C_CR2_AUTOEND); +} + +/************************************************************************************ + * Name: stm32l4_i2c_disable_autoend + * + * Description: + * + ************************************************************************************/ + +static inline void +stm32l4_i2c_disable_autoend(FAR struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, I2C_CR2_AUTOEND, 0); +} + +/************************************************************************************ + * Name: stm32l4_i2c_sem_waitstop + * + * Description: + * Wait for a STOP to complete + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sem_waitstop(FAR struct stm32l4_i2c_priv_s *priv) +{ + systime_t start; + systime_t elapsed; + systime_t timeout; + uint32_t cr; + uint32_t sr; + + /* Select a timeout */ + +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO + timeout = USEC2TICK(CONFIG_STM32L4_I2C_DYNTIMEO_STARTSTOP); +#else + timeout = CONFIG_STM32L4_I2CTIMEOTICKS; +#endif + + /* Wait as stop might still be in progress; but stop might also + * be set because of a timeout error: "The [STOP] bit is set and + * cleared by software, cleared by hardware when a Stop condition is + * detected, set by hardware when a timeout error is detected." + */ + + start = clock_systimer(); + do + { + /* Check for STOP condition */ + + cr = stm32l4_i2c_getreg32(priv, STM32L4_I2C_CR2_OFFSET); + if ((cr & I2C_CR2_STOP) == 0) + { + return; + } + + /* Check for timeout error */ + + sr = stm32l4_i2c_getreg(priv, STM32L4_I2C_ISR_OFFSET); + if ((sr & I2C_INT_TIMEOUT) != 0) + { + return; + } + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the stop is complete or a timeout occurs. */ + + while (elapsed < timeout); + + /* If we get here then a timeout occurred with the STOP condition + * still pending. + */ + + i2cvdbg("Timeout with CR: %04x SR: %04x\n", cr, sr); +} + +/************************************************************************************ + * Name: stm32l4_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sem_post(FAR struct stm32l4_i2c_priv_s *priv) +{ + sem_post(&priv->sem_excl); +} + +/************************************************************************************ + * Name: stm32l4_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sem_init(FAR struct stm32l4_i2c_priv_s *priv) +{ + sem_init(&priv->sem_excl, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->sem_isr, 0, 0); +#endif +} + +/************************************************************************************ + * Name: stm32l4_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sem_destroy(FAR struct stm32l4_i2c_priv_s *priv) +{ + sem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->sem_isr); +#endif +} + +/************************************************************************************ + * Name: stm32l4_i2c_trace* + * + * Description: + * I2C trace instrumentation + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void stm32l4_i2c_traceclear(FAR struct stm32l4_i2c_priv_s *priv) +{ + struct stm32l4_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void stm32l4_i2c_tracereset(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systimer(); + stm32l4_i2c_traceclear(priv); +} + +static void stm32l4_i2c_tracenew(FAR struct stm32l4_i2c_priv_s *priv, + uint32_t status) +{ + struct stm32l4_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + stm32l4_i2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systimer(); + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void stm32l4_i2c_traceevent(FAR struct stm32l4_i2c_priv_s *priv, + enum stm32l4_trace_e event, uint32_t parm) +{ + struct stm32l4_trace_s *trace; + + if (event != I2CEVENT_NONE) + { + trace = &priv->trace[priv->tndx]; + + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("Trace table overflow\n"); + return; + } + + priv->tndx++; + stm32l4_i2c_traceclear(priv); + } +} + +static void stm32l4_i2c_tracedump(FAR struct stm32l4_i2c_priv_s *priv) +{ + struct stm32l4_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->start_time)); + + for (i = 0; i <= priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %3d EVENT: %2d PARM: %08x TIME: %d\n", + i+1, trace->status, trace->count, trace->event, trace->parm, + trace->time - priv->start_time); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/************************************************************************************ + * Name: stm32l4_i2c_setclock + * + * Description: + * Set the I2C clock + * + ************************************************************************************/ + +static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, uint32_t frequency) +{ + uint32_t pe; + uint8_t presc; + uint8_t s_time; + uint8_t h_time; + uint8_t scl_h_period; + uint8_t scl_l_period; + + /* Has the I2C bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Disable the selected I2C peripheral to configure TRISE */ + + pe = (stm32l4_i2c_getreg32(priv, STM32L4_I2C_CR1_OFFSET) & I2C_CR1_PE); + if (pe) + { + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, I2C_CR1_PE, 0); + } + + /* Update timing and control registers */ + + /* TODO: speed/timing calcs */ +#warning "check set filters before timing, see RM0316" + + /* values from 100khz at 8mhz i2c clock */ + + /* prescaler */ + /* t_presc= (presc+1)*t_i2cclk */ + /* RM0316 */ + + if (frequency == 10000) + { + presc = 0x01; + scl_l_period = 0xc7; + scl_h_period = 0xc3; + h_time = 0x02; + s_time = 0x04; + } + else if (frequency == 100000) + { + /* values from datasheet with clock 8mhz */ + + presc = 0x01; + scl_l_period = 0x13; + scl_h_period = 0x0f; + h_time = 0x02; + s_time = 0x04; + } + else + { + presc = 0x00; + scl_l_period = 0x09; + scl_h_period = 0x03; + h_time = 0x01; + s_time = 0x03; + } + + uint32_t timingr = + (presc << I2C_TIMINGR_PRESC_SHIFT) | + (s_time << I2C_TIMINGR_SCLDEL_SHIFT) | + (h_time << I2C_TIMINGR_SDADEL_SHIFT) | + (scl_h_period << I2C_TIMINGR_SCLH_SHIFT) | + (scl_l_period << I2C_TIMINGR_SCLL_SHIFT); + + stm32l4_i2c_putreg32(priv, STM32L4_I2C_TIMINGR_OFFSET, timingr); + + /* Bit 14 of OAR1 must be configured and kept at 1 */ + + stm32l4_i2c_putreg(priv, STM32L4_I2C_OAR1_OFFSET, I2C_OAR1_ONE); + + /* Re-enable the peripheral (or not) */ + + if (pe) + { + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, 0, I2C_CR1_PE); + } + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/************************************************************************************ + * Name: stm32l4_i2c_sendstart + * + * Description: + * Send the START conditions/force Master mode + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sendstart(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* Get run-time data */ + + priv->astart = true; + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + + /* Disable ACK on receive by default and generate START */ + + stm32l4_i2c_set_bytes_to_transfer(priv, priv->dcnt); + stm32l4_i2c_set_7bit_address(priv); + if (priv->flags & I2C_M_READ) + { + stm32l4_i2c_set_read_transfer_dir(priv); + } + else + { + stm32l4_i2c_set_write_transfer_dir(priv); + } + + if (priv->msgc == 1) + { + /* stm32l4_i2c_enable_autoend(priv); */ + } + else + { + /* stm32l4_i2c_disable_autoend(priv); */ + } + + /* TODO check NACK */ + /* TODO handle NACKR? */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, 0, I2C_CR2_START); +} + +/************************************************************************************ + * Name: stm32l4_i2c_clrstart + * + * Description: + * Clear the STOP, START or PEC condition on certain error recovery steps. + * + ************************************************************************************/ + +static inline void stm32l4_i2c_clrstart(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + * + * "The [STOP] bit is set and cleared by software, cleared by hardware + * when a Stop condition is detected, set by hardware when a timeout + * error is detected. + * + * "This [START] bit is set and cleared by software and cleared by hardware + * when start is sent or PE=0." The bit must be cleared by software if the + * START is never sent. + * + * "This [PEC] bit is set and cleared by software, and cleared by hardware + * when PEC is transferred or by a START or Stop condition or when PE=0." + */ + + /* TODO check PEC (32 bit separate reg) */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, + I2C_CR2_START | I2C_CR2_STOP, 0); +} + +/************************************************************************************ + * Name: stm32l4_i2c_sendstop + * + * Description: + * Send the STOP conditions + * + ************************************************************************************/ + +static inline void stm32l4_i2c_sendstop(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* TODO check NACK */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR2_OFFSET, 0, I2C_CR2_STOP); +} + +/************************************************************************************ + * Name: stm32l4_i2c_getstatus + * + * Description: + * Get 32-bit status (SR1 and SR2 combined) + * + ************************************************************************************/ + +static inline uint32_t stm32l4_i2c_getstatus(FAR struct stm32l4_i2c_priv_s *priv) +{ + return getreg32(priv->config->base + STM32L4_I2C_ISR_OFFSET); +} + +/************************************************************************************ + * Name: stm32l4_i2c_isr + * + * Description: + * Common logic when a message is started. Just adds the even to the trace buffer + * if enabled and adjusts the message pointer and count. + * + ************************************************************************************/ + +static inline void stm32l4_i2c_isr_startmessage(struct stm32l4_i2c_priv_s *priv) +{ + stm32l4_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc); + + /* Increment to next pointer and decrement message count */ + + priv->msgv++; + priv->msgc--; +} + +/************************************************************************************ + * Name: stm32l4_i2c_clearinterrupts + * + * Description: + * Clear all interrupts + * + ************************************************************************************/ + +static inline void stm32l4_i2c_clearinterrupts(struct stm32l4_i2c_priv_s *priv) +{ +#warning "check this clears interrupts?" + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_ICR_OFFSET, 0, I2C_ICR_CLEARMASK); +} + +/************************************************************************************ + * Name: stm32l4_i2c_isr + * + * Description: + * Common Interrupt Service Routine + * + ************************************************************************************/ + +static int stm32l4_i2c_isr(struct stm32l4_i2c_priv_s *priv) +{ + uint32_t status = stm32l4_i2c_getstatus(priv); + + /* Check for new trace setup */ + + stm32l4_i2c_tracenew(priv, status); + +#warning "TODO: check clear interrupts after all actions" + + if (STATUS_NACK(status)) + { + /* wait, reset this? */ + } + else if (priv->astart) + { + stm32l4_i2c_isr_startmessage(priv); + priv->astart = false; + } + + /* Was address sent, continue with either sending or reading data */ + + if ((priv->flags & I2C_M_READ) == 0 && STATUS_ADDR_TX(status)) + { +#warning "TODO: ADDRCF clear address interrupt flag" + if (priv->dcnt > 0) + { + /* Send a byte */ + + stm32l4_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt); + stm32l4_i2c_putreg(priv, STM32L4_I2C_TXDR_OFFSET, *priv->ptr++); + priv->dcnt--; + } + } + + else if ((priv->flags & I2C_M_READ) != 0 && STATUS_ADDR(status)) + { + /* Enable RxNE and TxE buffers in order to receive one or multiple bytes */ + +#warning "TODO: ADDRCF clear address interrupt flag" + +#ifndef CONFIG_I2C_POLLED + stm32l4_i2c_traceevent(priv, I2CEVENT_ITBUFEN, 0); + stm32l4_i2c_enableinterrupts(priv); +#endif + } + + /* More bytes to read */ + else if (STATUS_RXNE(status)) + { + /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */ + + if (priv->dcnt > 0) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); + + /* No interrupts or context switches may occur in the following + * sequence. Otherwise, additional bytes may be sent by the + * device. + */ + +#ifdef CONFIG_I2C_POLLED + irqstate_t flags = enter_critical_section(); +#endif + /* Receive a byte */ + + *priv->ptr++ = stm32l4_i2c_getreg(priv, STM32L4_I2C_RXDR_OFFSET); + + /* Disable acknowledge when last byte is to be received */ + + priv->dcnt--; + if (priv->dcnt == 1) + { + /* autoend? */ + } + +#ifdef CONFIG_I2C_POLLED + leave_critical_section(flags); +#endif + } + } + + /* Do we have more bytes to send, enable/disable buffer interrupts + * (these ISRs could be replaced by DMAs) + */ + +#ifndef CONFIG_I2C_POLLED + if (priv->dcnt > 0) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_REITBUFEN, 0); + stm32l4_i2c_enableinterrupts(priv); + } + else if ((priv->dcnt == 0) && (priv->msgc == 0)) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0); + stm32l4_i2c_disableinterrupts(priv); + } +#endif + + /* Was last byte received or sent? Hmmm... the F2 and F4 seems to differ from + * the F1 in that BTF is not set after data is received (only RXNE). + */ + + if (priv->dcnt <= 0 && STATUS_TC(status)) + { + /* ??? */ + + /* Do we need to terminate or restart after this byte? + * If there are more messages to send, then we may: + * + * - continue with repeated start + * - or just continue sending writeable part + * - or we close down by sending the stop bit + */ + + if (priv->msgc > 0) + { + if (priv->msgv->flags & I2C_M_NORESTART) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_BTFNOSTART, priv->msgc); + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->msgv++; + priv->msgc--; + + /* Restart this ISR! */ + +#ifndef CONFIG_I2C_POLLED + stm32l4_i2c_enableinterrupts(priv); +#endif + } + else + { + stm32l4_i2c_traceevent(priv, I2CEVENT_BTFRESTART, priv->msgc); + /* ??? */ + stm32l4_i2c_sendstart(priv); + } + } + else if (priv->msgv) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_BTFSTOP, 0); + + stm32l4_i2c_sendstop(priv); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + + /* Mark that we have stopped with this transaction */ + + priv->msgv = NULL; + } + } + + /* Check for errors, in which case, stop the transfer and return + * Note that in master reception mode AF becomes set on last byte + * since ACK is not returned. We should ignore this error. + */ + + if ((status & I2C_ISR_ERRORMASK) != 0) + { + stm32l4_i2c_traceevent(priv, I2CEVENT_ERROR, 0); + + /* Clear interrupt flags */ + + stm32l4_i2c_clearinterrupts(priv); + + /* Is there a thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->intstate = INTSTATE_DONE; +#endif + } + + priv->status = status; + return OK; +} + +/************************************************************************************ + * Name: stm32l4_i2c1_isr + * + * Description: + * I2C1 interrupt service routine + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_STM32L4_I2C1 +static int stm32l4_i2c1_isr(int irq, void *context) +{ + return stm32l4_i2c_isr(&stm32l4_i2c1_priv); +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c2_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_I2C2 +static int stm32l4_i2c2_isr(int irq, void *context) +{ + return stm32l4_i2c_isr(&stm32l4_i2c2_priv); +} +#endif + +/************************************************************************************ + * Name: stm32l4_i2c3_isr + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_I2C3 +static int stm32l4_i2c3_isr(int irq, void *context) +{ + return stm32l4_i2c_isr(&stm32l4_i2c3_priv); +} +#endif +#endif + +/************************************************************************************ + * Private Initialization and Deinitialization + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int stm32l4_i2c_init(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* Power-up and configure GPIOs */ + + /* Enable power and reset the peripheral */ + + modifyreg32(STM32L4_RCC_APB1ENR, 0, priv->config->clk_bit); + modifyreg32(STM32L4_RCC_APB1RSTR, 0, priv->config->reset_bit); + modifyreg32(STM32L4_RCC_APB1RSTR, priv->config->reset_bit, 0); + + /* Configure pins */ + + if (stm32l4_configgpio(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (stm32l4_configgpio(priv->config->sda_pin) < 0) + { + stm32l4_unconfiggpio(priv->config->scl_pin); + return ERROR; + } + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->ev_irq, priv->config->isr); + irq_attach(priv->config->er_irq, priv->config->isr); + up_enable_irq(priv->config->ev_irq); + up_enable_irq(priv->config->er_irq); +#endif + + /* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz + * or 4 MHz for 400 kHz. This also disables all I2C interrupts. + */ + + /* Force a frequency update */ + + priv->frequency = 0; + + /* TODO: f303 i2c clock source RCC_CFGR3 */ + /* RCC_CFGR3_I2C1SW (default is HSI clock) */ + + stm32l4_i2c_setclock(priv, 100000); + + /* Enable I2C */ + + stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, 0, I2C_CR1_PE); + return OK; +} + +/************************************************************************************ + * Name: stm32l4_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int stm32l4_i2c_deinit(FAR struct stm32l4_i2c_priv_s *priv) +{ + /* Disable I2C */ + + stm32l4_i2c_putreg32(priv, STM32L4_I2C_CR1_OFFSET, 0); + + /* Unconfigure GPIO pins */ + + stm32l4_unconfiggpio(priv->config->scl_pin); + stm32l4_unconfiggpio(priv->config->sda_pin); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->ev_irq); + up_disable_irq(priv->config->er_irq); + irq_detach(priv->config->ev_irq); + irq_detach(priv->config->er_irq); +#endif + + /* Disable clocking */ + + modifyreg32(STM32L4_RCC_APB1ENR, priv->config->clk_bit, 0); + return OK; +} + +/************************************************************************************ + * Device Driver Operations + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ************************************************************************************/ + +static int stm32l4_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count) +{ + FAR struct stm32l4_i2c_priv_s *priv = (struct stm32l4_i2c_priv_s *)dev; + uint32_t status = 0; + int ret = OK; + + DEBUGASSERT(dev != NULL && msgs != NULL && count > 0); + + /* Ensure that address or flags don't change meanwhile */ + + stm32l4_i2c_sem_wait(priv); + + /* Wait for any STOP in progress. */ + + stm32l4_i2c_sem_waitstop(priv); + + /* Clear any pending error interrupts */ + + stm32l4_i2c_clearinterrupts(priv); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." However, if the bits are + * not cleared by hardware, then we will have to do that from hardware. + */ + + stm32l4_i2c_clrstart(priv); + + /* Old transfers are done */ + + priv->msgv = msgs; + priv->msgc = count; + + /* Reset I2C trace logic */ + + stm32l4_i2c_tracereset(priv); + + /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + stm32l4_i2c_setclock(priv, msgs->frequency); + + /* Trigger start condition, then the process moves into the ISR. I2C + * interrupts will be enabled within stm32l4_i2c_waitdone(). + */ + + priv->status = 0; + +#ifndef CONFIG_I2C_POLLED + stm32l4_i2c_enableinterrupts(priv); +#endif + + stm32l4_i2c_sendstart(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (stm32l4_i2c_sem_waitdone(priv) < 0) + { + status = stm32l4_i2c_getstatus(priv); + ret = -ETIMEDOUT; + + i2cdbg("Timed out: CR1: %04x status: %08x\n", + stm32l4_i2c_getreg(priv, STM32L4_I2C_CR1_OFFSET), status); + + /* "Note: When the STOP, START or PEC bit is set, the software must + * not perform any write access to I2C_CR1 before this bit is + * cleared by hardware. Otherwise there is a risk of setting a + * second STOP, START or PEC request." + */ + + stm32l4_i2c_clrstart(priv); + + /* Clear busy flag in case of timeout */ + + status = priv->status & 0xffff; + } + else + { + /* clear SR2 (BUSY flag) as we've done successfully */ + + status = priv->status & 0xffff; + } + + status &= ~I2C_ISR_BUSY; +#if 0 + /* Refresh status */ + do + { + status = stm32l4_i2c_getstatus(priv); + } + while (STATUS_BUSY(status)); +#endif + + /* Check for error status conditions */ + + if ((status & I2C_ISR_ERRORMASK) != 0) + { + /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */ + + if (status & I2C_INT_BERR) + { + /* Bus Error */ + + ret = -EIO; + } + else if (status & I2C_INT_ARLO) + { + /* Arbitration Lost (master mode) */ + + ret = -EAGAIN; + } + + /* TODO Acknowledge failure */ + + else if (status & I2C_INT_OVR) + { + /* Overrun/Underrun */ + + ret = -EIO; + } + else if (status & I2C_INT_PECERR) + { + /* PEC Error in reception */ + + ret = -EPROTO; + } + else if (status & I2C_INT_TIMEOUT) + { + /* Timeout or Tlow Error */ + + ret = -ETIME; + } + + /* This is not an error and should never happen since SMBus is not + * enabled + */ + + else /* if (status & I2C_INT_ALERT) */ + { + /* SMBus alert is an optional signal with an interrupt line for devices + * that want to trade their ability to master for a pin. + */ + + ret = -EINTR; + } + } + + /* This is not an error, but should not happen. The BUSY signal can hang, + * however, if there are unhealthy devices on the bus that need to be reset. + * NOTE: We will only see this buy indication if stm32l4_i2c_sem_waitdone() + * fails above; Otherwise it is cleared. + */ + + else if ((status & I2C_ISR_BUSY) != 0) + { + /* I2C Bus is for some reason busy */ + + ret = -EBUSY; + } + + /* Dump the trace result */ + + stm32l4_i2c_tracedump(priv); + stm32l4_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: stm32l4_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int stm32l4_i2c_reset(FAR struct i2c_master_s * dev) +{ + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret = ERROR; + + ASSERT(dev); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + stm32l4_i2c_sem_wait(priv); + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + stm32l4_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + /* Let SDA go high */ + + stm32l4_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!stm32l4_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!stm32l4_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + stm32l4_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + stm32l4_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + stm32l4_gpiowrite(sda_gpio, 0); + up_udelay(10); + stm32l4_gpiowrite(scl_gpio, 0); + up_udelay(10); + stm32l4_gpiowrite(scl_gpio, 1); + up_udelay(10); + stm32l4_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + stm32l4_unconfiggpio(sda_gpio); + stm32l4_unconfiggpio(scl_gpio); + + /* Re-init the port */ + + stm32l4_i2c_init(priv); + + /* Restore the frequency */ + + stm32l4_i2c_setclock(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + stm32l4_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ************************************************************************************/ + +FAR struct i2c_master_s *stm32l4_i2cbus_initialize(int port) +{ + struct stm32l4_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */ + irqtate_t flags; + +#if STM32L4_PCLK1_FREQUENCY < 4000000 +# warning STM32L4_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation. +#endif + +#if STM32L4_PCLK1_FREQUENCY < 2000000 +# warning STM32L4_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation. + return NULL; +#endif + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_STM32L4_I2C1 + case 1: + priv = (struct stm32l4_i2c_priv_s *)&stm32l4_i2c1_priv; + break; +#endif +#ifdef CONFIG_STM32L4_I2C2 + case 2: + priv = (struct stm32l4_i2c_priv_s *)&stm32l4_i2c2_priv; + break; +#endif +#ifdef CONFIG_STM32L4_I2C3 + case 3: + priv = (struct stm32l4_i2c_priv_s *)&stm32l4_i2c3_priv; + break; +#endif + default: + return NULL; + } + + /* Init private data for the first time, increment refs count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + stm32l4_i2c_sem_init(priv); + stm32l4_i2c_init(priv); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/************************************************************************************ + * Name: stm32l4_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ************************************************************************************/ + +int stm32l4_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + FAR struct stm32l4_i2c_priv_s *priv = (struct stm32l4_i2c_priv_s *)dev; + irqstate_t flags; + + ASSERT(dev); + + /* Decrement refs and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + stm32l4_i2c_deinit(priv); + + /* Release unused resources */ + + stm32l4_i2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_STM32L4_STM32F30XX */ +#endif /* CONFIG_STM32L4_I2C1 || CONFIG_STM32L4_I2C2 || CONFIG_STM32L4_I2C3 */ + diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.h b/arch/arm/src/stm32l4/stm32l4_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..267ee1d6640509d57d63137356fdaabf784306fb --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_i2c.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_I2C_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/stm32l4_i2c.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If a dynamic timeout is selected, then a non-negative, non-zero micro- + * seconds per byte value must be provided as well. + */ + +#ifdef CONFIG_STM32L4_I2C_DYNTIMEO +# if CONFIG_STM32L4_I2C_DYNTIMEO_USECPERBYTE < 1 +# warning "Ignoring CONFIG_STM32L4_I2C_DYNTIMEO because of CONFIG_STM32L4_I2C_DYNTIMEO_USECPERBYTE" +# undef CONFIG_STM32L4_I2C_DYNTIMEO +# endif +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *stm32l4_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: stm32l4_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the stm32l4_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int stm32l4_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_I2C_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_idle.c b/arch/arm/src/stm32l4/stm32l4_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..7cf0734c22d1b88ca12b91ce3bb62b75b4139aa1 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_idle.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_idle.c + * + * Copyright (C) 2011-2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "stm32l4_pm.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = irqsave(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + stm32l4_pmstop(true); + break; + + case PM_SLEEP: + (void)stm32l4_pmstandby(); + break; + + default: + break; + } + + irqrestore(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + +#if !(defined(CONFIG_DEBUG_SYMBOLS) && defined(CONFIG_STM32L4_DISABLE_IDLE_SLEEP_DURING_DEBUG)) + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif + +#endif +} diff --git a/arch/arm/src/stm32l4/stm32l4_irq.c b/arch/arm/src/stm32l4/stm32l4_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..e0e963c66df118d575182ab6d4f51e361a7a64ea --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_irq.c @@ -0,0 +1,561 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_irq.c + * arch/arm/src/chip/stm32l4_irq.c + * + * Copyright (C) 2009-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void stm32l4_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); + lldbg(" %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY)); + leave_critical_section(flags); +} +#else +# define stm32l4_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32l4_nmi, stm32l4_busfault, stm32l4_usagefault, stm32l4_pendsv, + * stm32l4_dbgmonitor, stm32l4_pendsv, stm32l4_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int stm32l4_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32l4_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32l4_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32l4_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32l4_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int stm32l4_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32l4_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void stm32l4_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: stm32l4_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int stm32l4_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= STM32L4_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= STM32L4_IRQ_FIRST) + { + if (irq < STM32L4_IRQ_FIRST + 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST); + } + else if (irq < STM32L4_IRQ_FIRST + 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST - 32); + } + else if (irq < NR_IRQS) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST - 64); + } + else + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == STM32L4_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == STM32L4_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == STM32L4_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == STM32L4_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); + putreg32(0, NVIC_IRQ32_63_ENABLE); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* The standard location for the vector table is at the beginning of FLASH + * at address 0x0800:0000. If we are using the STMicro DFU bootloader, then + * the vector table will be offset to a different location in FLASH and we + * will need to set the NVIC vector location to this alternative location. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(STM32L4_IRQ_SVCALL, up_svcall); + irq_attach(STM32L4_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(STM32L4_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + stm32l4_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(STM32L4_IRQ_MEMFAULT, up_memfault); + up_enable_irq(STM32L4_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(STM32L4_IRQ_NMI, stm32l4_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(STM32L4_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(STM32L4_IRQ_BUSFAULT, stm32l4_busfault); + irq_attach(STM32L4_IRQ_USAGEFAULT, stm32l4_usagefault); + irq_attach(STM32L4_IRQ_PENDSV, stm32l4_pendsv); + irq_attach(STM32L4_IRQ_DBGMONITOR, stm32l4_dbgmonitor); + irq_attach(STM32L4_IRQ_RESERVED, stm32l4_reserved); +#endif + + stm32l4_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32l4_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32L4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + // stm32l4_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32l4_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32L4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + // stm32l4_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= STM32L4_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < STM32L4_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= STM32L4_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + stm32l4_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/stm32l4/stm32l4_lcd.h b/arch/arm/src/stm32l4/stm32l4_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_lowputc.c b/arch/arm/src/stm32l4/stm32l4_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..4d6ff2601859692d8b053ccb8e4293ac8ca4c4e1 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_lowputc.c @@ -0,0 +1,388 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_lowputc.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "stm32l4.h" +#include "stm32l4_rcc.h" +#include "stm32l4_gpio.h" +#include "stm32l4_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART1_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK2_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB2ENR +# define STM32L4_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART1_TX +# define STM32L4_CONSOLE_RX GPIO_USART1_RX +# ifdef CONFIG_USART1_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART2_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_USART2EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART2_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART2_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART2_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART2_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART2_TX +# define STM32L4_CONSOLE_RX GPIO_USART2_RX +# ifdef CONFIG_USART2_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART3_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_USART3EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART3_TX +# define STM32L4_CONSOLE_RX GPIO_USART3_RX +# ifdef CONFIG_USART3_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_UART4_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_UART4EN +# define STM32L4_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32L4_CONSOLE_TX GPIO_UART4_TX +# define STM32L4_CONSOLE_RX GPIO_UART4_RX +# ifdef CONFIG_UART4_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_UART5_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_UART5EN +# define STM32L4_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32L4_CONSOLE_TX GPIO_UART5_TX +# define STM32L4_CONSOLE_RX GPIO_UART5_RX +# ifdef CONFIG_UART5_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# endif + + /* CR1 settings */ + +# if STM32L4_CONSOLE_BITS == 9 +# define USART_CR1_M0_VALUE USART_CR1_M0 +# define USART_CR1_M1_VALUE 0 +# elif STM32L4_CONSOLE_BITS == 7 +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE USART_CR1_M1 +# else /* 8 bits */ +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE 0 +# endif + +# if STM32L4_CONSOLE_PARITY == 1 /* odd parity */ +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32L4_CONSOLE_PARITY == 2 /* even parity */ +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +# else /* no parity */ +# define USART_CR1_PARITY_VALUE 0 +# endif + +# define USART_CR1_CLRBITS \ + (USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ + USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ + USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ + USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) + +# define USART_CR1_SETBITS (USART_CR1_M0_VALUE|USART_CR1_M1_VALUE|USART_CR1_PARITY_VALUE) + + /* CR2 settings */ + +# if STM32L4_CONSOLE_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +# else +# define USART_CR2_STOP2_VALUE 0 +# endif + +# define USART_CR2_CLRBITS \ + (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ + USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ + USART_CR2_LINEN | USART_CR2_SWAP | USART_CR2_RXINV | USART_CR2_TXINV | \ + USART_CR2_DATAINV | USART_CR2_MSBFIRST | USART_CR2_ABREN | \ + USART_CR2_ABRMOD_MASK | USART_CR2_RTOEN | USART_CR2_ADD_MASK) + +# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + + /* CR3 settings */ + +# define USART_CR3_CLRBITS \ + (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ + USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ + USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ + USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | USART_CR3_DEP | \ + USART_CR3_SCARCNT2_MASK | USART_CR3_WUS_MASK | USART_CR3_WUFIE) + +# define USART_CR3_SETBITS 0 + +# undef USE_OVER8 + + /* Calculate USART BAUD rate divider */ + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ + +# define STM32L4_USARTDIV8 \ + (((STM32L4_APBCLOCK << 1) + (STM32L4_CONSOLE_BAUD >> 1)) / STM32L4_CONSOLE_BAUD) +# define STM32L4_USARTDIV16 \ + ((STM32L4_APBCLOCK + (STM32L4_CONSOLE_BAUD >> 1)) / STM32L4_CONSOLE_BAUD) + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + +# if STM32L4_USARTDIV8 > 100 +# define STM32L4_BRR_VALUE STM32L4_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32L4_BRR_VALUE \ + ((STM32L4_USARTDIV8 & 0xfff0) | ((STM32L4_USARTDIV8 & 0x000f) >> 1)) +# endif + +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + /* Wait until the TX data register is empty */ + + while ((getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_ISR_OFFSET) & USART_ISR_TXE) == 0); +#ifdef STM32L4_CONSOLE_RS485_DIR + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Then send the character */ + + putreg32((uint32_t)ch, STM32L4_CONSOLE_BASE + STM32L4_USART_TDR_OFFSET); + +#ifdef STM32L4_CONSOLE_RS485_DIR + while ((getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_ISR_OFFSET) & USART_ISR_TC) == 0); + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, !STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: stm32l4_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void stm32l4_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + +#if defined(HAVE_CONSOLE) + /* Enable USART APB1/2 clock */ + + modifyreg32(STM32L4_CONSOLE_APBREG, 0, STM32L4_CONSOLE_APBEN); +#endif + + /* Enable the console USART and configure GPIO pins needed for rx/tx. + * + * NOTE: Clocking for selected U[S]ARTs was already provided in stm32l4_rcc.c + */ + +#ifdef STM32L4_CONSOLE_TX + stm32l4_configgpio(STM32L4_CONSOLE_TX); +#endif +#ifdef STM32L4_CONSOLE_RX + stm32l4_configgpio(STM32L4_CONSOLE_RX); +#endif + +#ifdef STM32L4_CONSOLE_RS485_DIR + stm32l4_configgpio(STM32L4_CONSOLE_RS485_DIR); + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, !STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32L4_BRR_VALUE, STM32L4_CONSOLE_BASE + STM32L4_USART_BRR_OFFSET); + + /* Select oversampling by 8 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); +#endif + + /* Enable Rx, Tx, and the USART */ + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} + diff --git a/arch/arm/src/stm32l4/stm32l4_lowputc.h b/arch/arm/src/stm32l4/stm32l4_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..e00820f2adb0899e85277aa417251363215f9311 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_lowputc.h @@ -0,0 +1,80 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_lowputc.h + * + * Copyright (C) 2009-2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: stm32l4_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * of serial console. + * + ************************************************************************************/ + +void stm32l4_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_LOWPUTC_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_lse.c b/arch/arm/src/stm32l4/stm32l4_lse.c new file mode 100644 index 0000000000000000000000000000000000000000..1cadc4abe187a181d54b505084d959bf13908063 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_lse.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_lse.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" + +#include "stm32l4_pwr.h" +#include "stm32l4_rcc.h" +#include "stm32l4_waste.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) oscillator. + * + * Todo: + * Check for LSE good timeout and return with -1, + * + ****************************************************************************/ + +void stm32l4_rcc_enablelse(void) +{ + bool writable; + uint32_t regval; + + /* The LSE is in the RTC domain and write access is denied to this domain + * after reset, you have to enable write access using DBP bit in the PWR CR + * register before to configuring the LSE. + */ + + writable = stm32l4_pwr_enablebkp(true); + + /* Enable the External Low-Speed (LSE) oscillator by setting the LSEON bit + * the RCC BDCR register. + */ + + regval = getreg32(STM32L4_RCC_BDCR); + regval |= RCC_BDCR_LSEON; + putreg32(regval,STM32L4_RCC_BDCR); + + /* Wait for the LSE clock to be ready */ + + while (((regval = getreg32(STM32L4_RCC_BDCR)) & RCC_BDCR_LSERDY) == 0) + { + up_waste(); + } + + /* Disable backup domain access if it was disabled on entry */ + + (void)stm32l4_pwr_enablebkp(writable); +} diff --git a/arch/arm/src/stm32l4/stm32l4_mpuinit.c b/arch/arm/src/stm32l4/stm32l4_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_mpuinit.h b/arch/arm/src/stm32l4/stm32l4_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_pm.h b/arch/arm/src/stm32l4/stm32l4_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_procfs_dtcm.c b/arch/arm/src/stm32l4/stm32l4_procfs_dtcm.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_pwr.c b/arch/arm/src/stm32l4/stm32l4_pwr.c new file mode 100644 index 0000000000000000000000000000000000000000..7659f73147046ad3bcc9aee9da5f0eccb17ae96c --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_pwr.c @@ -0,0 +1,168 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_pwr.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Authors: Uros Platise + * Gregory Nutt + * dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "stm32l4_pwr.h" +#include "stm32l4_rcc.h" + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +static inline uint16_t stm32l4_pwr_getreg(uint8_t offset) +{ + return (uint16_t)getreg32(STM32L4_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32l4_pwr_putreg(uint8_t offset, uint16_t value) +{ + putreg32((uint32_t)value, STM32L4_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32l4_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits) +{ + modifyreg32(STM32L4_PWR_BASE + (uint32_t)offset, (uint32_t)clearbits, (uint32_t)setbits); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: enableclk + * + * Description: + * Enable/disable the clock to the power control peripheral. Enabling must be done + * after the APB1 clock is validly configured, and prior to using any functionality + * controlled by the PWR block (i.e. much of anything else provided by this module). + * + * Input Parameters: + * enable - True: enable the clock to the Power control (PWR) block. + * + * Returned Value: + * True: the PWR block was previously enabled. + * + ************************************************************************************/ + +bool stm32l4_pwr_enableclk(bool enable) +{ + uint32_t regval; + bool wasenabled; + + regval = getreg32(STM32L4_RCC_APB1ENR1); + wasenabled = ((regval & RCC_APB1ENR1_PWREN) != 0); + + /* Power interface clock enable. */ + + if (wasenabled && !enable) + { + /* Disable power interface clock */ + + regval &= ~RCC_APB1ENR1_PWREN; + putreg32(regval, STM32L4_RCC_APB1ENR1); + } + else if (!wasenabled && enable) + { + /* Enable power interface clock */ + + regval |= RCC_APB1ENR1_PWREN; + putreg32(regval, STM32L4_RCC_APB1ENR1); + } + + return wasenabled; +} + +/************************************************************************************ + * Name: stm32l4_pwr_enablebkp + * + * Description: + * Enables access to the backup domain (RTC registers, RTC backup data registers + * and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ************************************************************************************/ + +bool stm32l4_pwr_enablebkp(bool writable) +{ + uint16_t regval; + bool waswritable; + + /* Get the current state of the STM32 PWR control register */ + + regval = stm32l4_pwr_getreg(STM32L4_PWR_CR1_OFFSET); + waswritable = ((regval & PWR_CR1_DBP) != 0); + + /* Enable or disable the ability to write */ + + if (waswritable && !writable) + { + /* Disable backup domain access */ + + regval &= ~PWR_CR1_DBP; + stm32l4_pwr_putreg(STM32L4_PWR_CR1_OFFSET, regval); + } + else if (!waswritable && writable) + { + /* Enable backup domain access */ + + regval |= PWR_CR1_DBP; + stm32l4_pwr_putreg(STM32L4_PWR_CR1_OFFSET, regval); + + /* Enable does not happen right away */ + + up_udelay(4); + } + + return waswritable; +} diff --git a/arch/arm/src/stm32l4/stm32l4_pwr.h b/arch/arm/src/stm32l4/stm32l4_pwr.h new file mode 100644 index 0000000000000000000000000000000000000000..6c065f3d4429a0d91bae697ad7b1e62e2de4eff1 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_pwr.h @@ -0,0 +1,110 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_pwr.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_PWR_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32l4_pwr.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: enableclk + * + * Description: + * Enable/disable the clock to the power control peripheral. Enabling must be done + * after the APB1 clock is validly configured, and prior to using any functionality + * controlled by the PWR block (i.e. much of anything else provided by this module). + * + * Input Parameters: + * enable - True: enable the clock to the Power control (PWR) block. + * + * Returned Value: + * True: the PWR block was previously enabled. + * + ************************************************************************************/ + +bool stm32l4_pwr_enableclk(bool enable); + +/************************************************************************************ + * Name: stm32l4_pwr_enablebkp + * + * Description: + * Enables access to the backup domain (RTC registers, RTC backup data registers + * and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ************************************************************************************/ + +bool stm32l4_pwr_enablebkp(bool writable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_PWR_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.c b/arch/arm/src/stm32l4/stm32l4_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..0d51d7afd16a25cd3a1678ba96da8cab4f358bda --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rcc.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_rcc.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Author: Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4_rcc.h" +#include "stm32l4_flash.h" +#include "stm32l4.h" +#include "stm32l4_waste.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "stm32l4x6xx_rcc.c" +#else +# error "Unsupported STM32L4 chip" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_clockconfig(void) +{ + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + +#if defined(CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32l4_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32l4_stdclockconfig(); + +#endif + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); +} + +/************************************************************************************ + * Name: stm32l4_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32l4_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32l4_clockenable(void) +{ +#if defined(CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32l4_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32l4_stdclockconfig(); + +#endif +} +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.h b/arch/arm/src/stm32l4/stm32l4_rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..3dae842de86254c6740a26dede8ae20ae4a193a8 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rcc.h @@ -0,0 +1,230 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_rcc.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_RRC_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_RRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_rcc.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* This symbol references the Cortex-M4 vector table (as positioned by the linker + * script, ld.script or ld.script.dfu. The standard location for the vector table is + * at the beginning of FLASH at address 0x0800:0000. If we are using the STMicro DFU + * bootloader, then the vector table will be offset to a different location in FLASH + * and we will need to set the NVIC vector location to this alternative location. + */ + +extern uint32_t _vectors[]; /* See stm32l4_vectors.S */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_mcoconfig + * + * Description: + * Selects the clock source to output on MC pin (PA8) for stm32f10xxx. + * PA8 should be configured in alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO definitions from + * chip/stm32f10xxx_rcc.h {RCC_CFGR_SYSCLK, RCC_CFGR_INTCLK, RCC_CFGR_EXTCLK, + * RCC_CFGR_PLLCLKd2, RCC_CFGR_PLL2CLK, RCC_CFGR_PLL3CLKd2, RCC_CFGR_XT1, + * RCC_CFGR_PLL3CLK} + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32l4_mcoconfig(uint32_t source) +{ + uint32_t regval; + + /* Set MCO source */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO_MASK); + regval |= (source & RCC_CFGR_MCO_MASK); + putreg32(regval, STM32L4_RCC_CFGR); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_clockconfig(void); + +/************************************************************************************ + * Name: stm32l4_board_clockconfig + * + * Description: + * Any STM32L4 board may replace the "standard" board clock configuration logic with + * its own, custom clock cofiguration logic. + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG +void stm32l4_board_clockconfig(void); +#endif + +/************************************************************************************ + * Name: stm32l4_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32l4_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32l4_clockenable(void); +#endif + +/************************************************************************************ + * Name: stm32l4_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator and, if the RTC is + * configured, setup the LSE as the RTC clock source, and enable the RTC. + * + * For the STM32L15X family, this will also select the LSE as the clock source of + * the LCD. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_rcc_enablelse(void); + +/**************************************************************************** + * Name: stm32l4_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32l4_rcc_enablelsi(void); + +/**************************************************************************** + * Name: stm32l4_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32l4_rcc_disablelsi(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_RCC_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_rng.c b/arch/arm/src/stm32l4/stm32l4_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..b82c42fdc20a96b8dfdd3563c15f21a1d3ac9611 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rng.c @@ -0,0 +1,298 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32l4_rng.c + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * mods for STL32L4 port by dev@ziggurat29.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip/stm32l4_rng.h" +#include "up_internal.h" + +#ifdef CONFIG_STM32L4_RNG + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32l4_rnginitialize(void); +static int stm32l4_rnginterrupt(int irq, void *context); +static void stm32l4_rngenable(void); +static void stm32l4_rngdisable(void); +static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rng_dev_s +{ + sem_t rd_devsem; /* Threads can only exclusively access the RNG */ + sem_t rd_readsem; /* To block until the buffer is filled */ + char *rd_buf; + size_t rd_buflen; + uint32_t rd_lastval; + bool rd_first; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rng_dev_s g_rngdev; + +static const struct file_operations g_rngops = +{ + 0, /* open */ + 0, /* close */ + stm32l4_rngread, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif + +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +static int stm32l4_rnginitialize(void) +{ + vdbg("Initializing RNG\n"); + + memset(&g_rngdev, 0, sizeof(struct rng_dev_s)); + + sem_init(&g_rngdev.rd_devsem, 0, 1); + + if (irq_attach(STM32L4_IRQ_RNG, stm32l4_rnginterrupt)) + { + /* We could not attach the ISR to the interrupt */ + + vdbg("Could not attach IRQ.\n"); + + return -EAGAIN; + } + + return OK; +} + +static void stm32l4_rngenable(void) +{ + uint32_t regval; + + g_rngdev.rd_first = true; + + /* Enable generation and interrupts */ + + regval = getreg32(STM32L4_RNG_CR); + regval |= RNG_CR_RNGEN; + regval |= RNG_CR_IE; + putreg32(regval, STM32L4_RNG_CR); + + up_enable_irq(STM32L4_IRQ_RNG); +} + +static void stm32l4_rngdisable() +{ + uint32_t regval; + + up_disable_irq(STM32L4_IRQ_RNG); + + regval = getreg32(STM32L4_RNG_CR); + regval &= ~RNG_CR_IE; + regval &= ~RNG_CR_RNGEN; + putreg32(regval, STM32L4_RNG_CR); +} + +static int stm32l4_rnginterrupt(int irq, void *context) +{ + uint32_t rngsr; + uint32_t data; + + rngsr = getreg32(STM32L4_RNG_SR); + if (rngsr & RNG_SR_CEIS) /* Check for clock error int stat */ + { + /* Clear it, we will try again. */ + + putreg32(rngsr & ~RNG_SR_CEIS, STM32L4_RNG_SR); + return OK; + } + + if (rngsr & RNG_SR_SEIS) /* Check for seed error in int stat */ + { + uint32_t crval; + + /* Clear seed error, then disable/enable the rng and try again. */ + + putreg32(rngsr & ~RNG_SR_SEIS, STM32L4_RNG_SR); + crval = getreg32(STM32L4_RNG_CR); + crval &= ~RNG_CR_RNGEN; + putreg32(crval, STM32L4_RNG_CR); + crval |= RNG_CR_RNGEN; + putreg32(crval, STM32L4_RNG_CR); + return OK; + } + + if (!(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + { + /* This random value is not valid, we will try again. */ + + return OK; + } + + data = getreg32(STM32L4_RNG_DR); + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting the + * RNGEN bit should not be used, but saved for comparison with the next + * generated random number. Each subsequent generated random number has to be + * compared with the previously generated number. The test fails if any two + * compared numbers are equal (continuous random number generator test). + */ + + if (g_rngdev.rd_first) + { + g_rngdev.rd_first = false; + g_rngdev.rd_lastval = data; + return OK; + } + + if (g_rngdev.rd_lastval == data) + { + /* Two subsequent same numbers, we will try again. */ + + return OK; + } + + /* If we get here, the random number is valid. */ + + g_rngdev.rd_lastval = data; + + if (g_rngdev.rd_buflen >= 4) + { + g_rngdev.rd_buflen -= 4; + *(uint32_t *)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; + } + else + { + while (g_rngdev.rd_buflen > 0) + { + g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; + data >>= 8; + } + } + + if (g_rngdev.rd_buflen == 0) + { + /* Buffer filled, stop further interrupts. */ + + stm32l4_rngdisable(); + sem_post(&g_rngdev.rd_readsem); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32l4_rngread + ****************************************************************************/ + +static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t buflen) +{ + if (sem_wait(&g_rngdev.rd_devsem) != OK) + { + return -errno; + } + else + { + /* We've got the device semaphore, proceed with reading */ + + /* Initialize the operation semaphore with 0 for blocking until + * the buffer is filled from interrupts. + */ + + sem_init(&g_rngdev.rd_readsem, 0, 0); + + g_rngdev.rd_buflen = buflen; + g_rngdev.rd_buf = buffer; + + /* Enable RNG with interrupts */ + + stm32l4_rngenable(); + + /* Wait until the buffer is filled */ + + sem_wait(&g_rngdev.rd_readsem); + + /* Done with the operation semaphore */ + + sem_destroy(&g_rngdev.rd_readsem); + + /* Free RNG via the device semaphore for next use */ + + sem_post(&g_rngdev.rd_devsem); + + return buflen; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_rnginitialize(void) +{ + stm32l4_rnginitialize(); + register_driver("/dev/random", &g_rngops, 0444, NULL); +} + +#endif /* CONFIG_STM32L4_RNG */ diff --git a/arch/arm/src/stm32l4/stm32l4_rtc.h b/arch/arm/src/stm32l4/stm32l4_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..5292f6f4eb937352a3aa499f7611f4424b685c1b --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rtc.h @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_rtc.h + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Uros Platise (Original for the F1) + * Gregory Nutt (On-going support and development) + * dev@ziggurat29.com (adaptations for STM32L4) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_RTC_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_RTC_H + +#include + +#include "chip.h" + +#include "chip/stm32l4_rtcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_RTC_PRESCALER_SECOND 32767 /* Default prescaler to get a second base */ +#define STM32_RTC_PRESCALER_MIN 1 /* Maximum speed of 16384 Hz */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* The form of an alarm callback */ + +typedef CODE void (*alarmcb_t)(void); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS + * during initialization to set up the system time when CONFIG_RTC and + * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. + * That sub-second accuracy is returned through 'nsec'. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS +int stm32l4_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec); +#endif + +/**************************************************************************** + * Name: stm32l4_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide + * this function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DATETIME +struct tm; +int stm32l4_rtc_setdatetime(FAR const struct tm *tp); +#endif + +/**************************************************************************** + * Name: stm32l4_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct timespec; +int stm32l4_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); +#endif + +/**************************************************************************** + * Name: stm32l4_rtc_cancelalarm + * + * Description: + * Cancel a pending alarm alarm + * + * Input Parameters: + * none + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32l4_rtc_cancelalarm(void); +#endif + +/**************************************************************************** + * Name: stm32l4_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32L4. General usage: + * + * #include + * #include "stm32l4_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32l4_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DRIVER +struct rtc_lowerhalf_s; +FAR struct rtc_lowerhalf_s *stm32l4_rtc_lowerhalf(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_RTC_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c b/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c new file mode 100644 index 0000000000000000000000000000000000000000..033a191e41194d282b237e84ee33dbfb10f22760 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * dev@ziggurat29.com (adaptations for stm32l4) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* REVISIT: This driver is *not* thread-safe! */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "stm32l4_rtc.h" + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This is the private type for the RTC state. It must be cast compatible + * with struct rtc_lowerhalf_s. + */ + +struct stm32l4_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half + * operations vtable (which may lie in FLASH or ROM) + */ + + FAR const struct rtc_ops_s *ops; + + /* Data following is private to this driver and not visible outside of + * this file. + */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Prototypes for static methods in struct rtc_ops_s */ + +static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime); +static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* STM32 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = stm32l4_rdtime, + .settime = stm32l4_settime, +#ifdef CONFIG_RTC_ALARM + .setalarm = NULL, + .setrelative = NULL, + .cancelalarm = NULL, +#endif +#ifdef CONFIG_RTC_IOCTL + .ioctl = NULL, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + .destroy = NULL, +#endif +}; + +/* STM32L4 RTC device state */ + +static struct stm32l4_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_rdtime + * + * Description: + * Implements the rdtime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The location in which to return the current RTC time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime) +{ + /* This operation depends on the fact that struct rtc_time is cast + * compatible with struct tm. + */ + + return up_rtc_getdatetime((FAR struct tm *)rtctime); +} + +/**************************************************************************** + * Name: stm32l4_settime + * + * Description: + * Implements the settime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The new time to set + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime) +{ + /* This operation depends on the fact that struct rtc_time is cast + * compatible with struct tm. + */ + + return stm32l4_rtc_setdatetime((FAR const struct tm *)rtctime); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32. General usage: + * + * #include + * #include "stm32l4_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32l4_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +FAR struct rtc_lowerhalf_s *stm32l4_rtc_lowerhalf(void) +{ + return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf; +} + +#endif /* CONFIG_RTC_DRIVER */ diff --git a/arch/arm/src/stm32l4/stm32l4_rtcc.c b/arch/arm/src/stm32l4/stm32l4_rtcc.c new file mode 100644 index 0000000000000000000000000000000000000000..1b7bb5f12ade2996abd4f102ce4ecc09ceb5ad58 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rtcc.c @@ -0,0 +1,1069 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_rtcc.c + * + * Copyright (C) 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * dev@ziggurat29.com (adaptations to stm32l4) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" + +#include "stm32l4_rcc.h" +#include "stm32l4_pwr.h" +#include "stm32l4_exti.h" +#include "stm32l4_rtc.h" + +#ifdef CONFIG_RTC + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error "CONFIG_RTC_DATETIME must be set to use this driver" +#endif + +#ifdef CONFIG_RTC_HIRES +# error "CONFIG_RTC_HIRES must NOT be set with this driver" +#endif + +#ifndef CONFIG_STM32L4_PWR +# error "CONFIG_STM32L4_PWR must selected to use this driver" +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +#if !defined(CONFIG_RTC_MAGIC) +# define CONFIG_RTC_MAGIC (0xfacefeee) +#endif + +#if !defined(CONFIG_RTC_MAGIC_REG) +# define CONFIG_RTC_MAGIC_REG (0) +#endif + +/* Constants ************************************************************************/ + +#define SYNCHRO_TIMEOUT (0x00020000) +#define INITMODE_TIMEOUT (0x00010000) +#define RTC_MAGIC CONFIG_RTC_MAGIC +#define RTC_MAGIC_REG STM32L4_RTC_BKR(CONFIG_RTC_MAGIC_REG) + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static alarmcb_t g_alarmcb; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: rtc_dumpregs + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumpregs(FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" TR: %08x\n", getreg32(STM32L4_RTC_TR)); + rtclldbg(" DR: %08x\n", getreg32(STM32L4_RTC_DR)); + rtclldbg(" CR: %08x\n", getreg32(STM32L4_RTC_CR)); + rtclldbg(" ISR: %08x\n", getreg32(STM32L4_RTC_ISR)); + rtclldbg(" PRER: %08x\n", getreg32(STM32L4_RTC_PRER)); + rtclldbg(" WUTR: %08x\n", getreg32(STM32L4_RTC_WUTR)); + + rtclldbg(" ALRMAR: %08x\n", getreg32(STM32L4_RTC_ALRMAR)); + rtclldbg(" ALRMBR: %08x\n", getreg32(STM32L4_RTC_ALRMBR)); + rtclldbg(" SHIFTR: %08x\n", getreg32(STM32L4_RTC_SHIFTR)); + rtclldbg(" TSTR: %08x\n", getreg32(STM32L4_RTC_TSTR)); + rtclldbg(" TSDR: %08x\n", getreg32(STM32L4_RTC_TSDR)); + rtclldbg(" TSSSR: %08x\n", getreg32(STM32L4_RTC_TSSSR)); + rtclldbg(" CALR: %08x\n", getreg32(STM32L4_RTC_CALR)); + rtclldbg(" TAFCR: %08x\n", getreg32(STM32L4_RTC_TAMPCR_OFFSET)); + rtclldbg("ALRMASSR: %08x\n", getreg32(STM32L4_RTC_ALRMASSR)); + rtclldbg("ALRMBSSR: %08x\n", getreg32(STM32L4_RTC_ALRMBSSR)); + rtclldbg("MAGICREG: %08x\n", getreg32(RTC_MAGIC_REG)); +} +#else +# define rtc_dumpregs(msg) +#endif + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_wprunlock + * + * Description: + * Disable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void rtc_wprunlock(void) +{ + /* Enable write access to the backup domain. */ + + (void)stm32l4_pwr_enablebkp(true); + + /* The following steps are required to unlock the write protection on all the + * RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR). + * + * 1. Write 0xCA into the RTC_WPR register. + * 2. Write 0x53 into the RTC_WPR register. + * + * Writing a wrong key re-activates the write protection. + */ + + putreg32(0xca, STM32L4_RTC_WPR); + putreg32(0x53, STM32L4_RTC_WPR); +} + +/************************************************************************************ + * Name: rtc_wprlock + * + * Description: + * Enable RTC write protection + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void rtc_wprlock(void) +{ + /* Writing any wrong key re-activates the write protection. */ + + putreg32(0xff, STM32L4_RTC_WPR); + + /* Disable write access to the backup domain. */ + + (void)stm32l4_pwr_enablebkp(false); +} + +/************************************************************************************ + * Name: rtc_synchwait + * + * Description: + * Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_synchwait(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Clear Registers synchronization flag (RSF) */ + + regval = getreg32(STM32L4_RTC_ISR); + regval &= ~RTC_ISR_RSF; + putreg32(regval, STM32L4_RTC_ISR); + + /* Now wait the registers to become synchronised */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++) + { + regval = getreg32(STM32L4_RTC_ISR); + if ((regval & RTC_ISR_RSF) != 0) + { + /* Synchronized */ + + ret = OK; + break; + } + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + return ret; +} + +/************************************************************************************ + * Name: rtc_enterinit + * + * Description: + * Enter RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_enterinit(void) +{ + volatile uint32_t timeout; + uint32_t regval; + int ret; + + /* Check if the Initialization mode is already set */ + + regval = getreg32(STM32L4_RTC_ISR); + + ret = OK; + if ((regval & RTC_ISR_INITF) == 0) + { + /* Set the Initialization mode */ + + putreg32(RTC_ISR_INIT, STM32L4_RTC_ISR); + + /* Wait until the RTC is in the INIT state (or a timeout occurs) */ + + ret = -ETIMEDOUT; + for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++) + { + regval = getreg32(STM32L4_RTC_ISR); + if ((regval & RTC_ISR_INITF) != 0) + { + ret = OK; + break; + } + } + } + + return ret; +} + +/************************************************************************************ + * Name: rtc_exitinit + * + * Description: + * Exit RTC initialization mode. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_exitinit(void) +{ + uint32_t regval; + + regval = getreg32(STM32L4_RTC_ISR); + regval &= ~(RTC_ISR_INIT); + putreg32(regval, STM32L4_RTC_ISR); +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint32_t rtc_bin2bcd(int value) +{ + uint32_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint32_t value) +{ + uint32_t tens = (value >> 4) * 10; + return (int)(tens + (value & 0x0f)); +} + +/************************************************************************************ + * Name: rtc_setup + * + * Description: + * Performs first time configuration of the RTC. A special value written into + * back-up register 0 will prevent this function from being called on sub-sequent + * resets or power up. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static int rtc_setup(void) +{ + uint32_t regval; + int ret; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the 24 hour format by clearing the FMT bit in the RTC + * control register + */ + + regval = getreg32(STM32L4_RTC_CR); + regval &= ~RTC_CR_FMT; + putreg32(regval, STM32L4_RTC_CR); + + /* Configure RTC pre-scaler with the required values */ + +#ifdef CONFIG_STM32L4_RTC_HSECLOCK + /* For a 1 MHz clock this yields 0.9999360041 Hz on the second + * timer - which is pretty close. + */ + + putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32L4_RTC_PRER); +#else + /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */ + + putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32L4_RTC_PRER); +#endif + + /* Exit RTC initialization mode */ + + rtc_exitinit(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + + return ret; +} + +/************************************************************************************ + * Name: rtc_resume + * + * Description: + * Called when the RTC was already initialized on a previous power cycle. This + * just brings the RTC back into full operation. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +static void rtc_resume(void) +{ +#ifdef CONFIG_RTC_ALARM + uint32_t regval; + + /* Clear the RTC alarm flags */ + + regval = getreg32(STM32L4_RTC_ISR); + regval &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF); + putreg32(regval, STM32L4_RTC_ISR); + + /* Clear the EXTI Line 18 Pending bit (Connected internally to RTC Alarm) */ + + putreg32((1 << 18), STM32L4_EXTI1_PR); +#endif +} + +/************************************************************************************ + * Name: rtc_interrupt + * + * Description: + * RTC interrupt service routine + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt + * context - Architecture specific register save information. + * + * Returned Value: + * Zero (OK) on success; A negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_interrupt(int irq, void *context) +{ +#warning "Missing logic" + return OK; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_initialize(void) +{ + uint32_t regval; + uint32_t tr_bkp; + uint32_t dr_bkp; + int ret; + int maxretry = 10; + int nretry = 0; + + /* Clocking for the PWR block must be provided. + */ + + rtc_dumpregs("On reset"); + + /* Select the clock source */ + /* Save the token before losing it when resetting */ + + regval = getreg32(RTC_MAGIC_REG); + + (void)stm32l4_pwr_enablebkp(true); + + if (regval != RTC_MAGIC) + { + /* We might be changing RTCSEL - to ensure such changes work, we must reset the + * backup domain (having backed up the RTC_MAGIC token) + */ + + modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_BDRST); + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_BDRST, 0); + + /* Some boards do not have the external 32khz oscillator installed, for those + * boards we must fallback to the crummy internal RC clock or the external high + * rate clock + */ + +#ifdef CONFIG_STM32L4_RTC_HSECLOCK + /* Use the HSE clock as the input to the RTC block */ + + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE); + +#elif defined(CONFIG_STM32L4_RTC_LSICLOCK) + /* Use the LSI clock as the input to the RTC block */ + + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI); + +#elif defined(CONFIG_STM32L4_RTC_LSECLOCK) + /* Use the LSE clock as the input to the RTC block */ + + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE); + +#endif + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_RTCEN); + } + else /* The RTC is already in use: check if the clock source is changed */ + { +#if defined(CONFIG_STM32L4_RTC_HSECLOCK) || defined(CONFIG_STM32L4_RTC_LSICLOCK) || \ + defined(CONFIG_STM32L4_RTC_LSECLOCK) + + uint32_t clksrc = getreg32(STM32L4_RCC_BDCR); + +#if defined(CONFIG_STM32L4_RTC_HSECLOCK) + if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_HSE) +#elif defined(CONFIG_STM32L4_RTC_LSICLOCK) + if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_LSI) +#elif defined(CONFIG_STM32L4_RTC_LSECLOCK) + if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_LSE) +#endif +#endif + { + tr_bkp = getreg32(STM32L4_RTC_TR); + dr_bkp = getreg32(STM32L4_RTC_DR); + modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_BDRST); + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_BDRST, 0); + +#if defined(CONFIG_STM32L4_RTC_HSECLOCK) + /* Change to the new clock as the input to the RTC block */ + + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE); + +#elif defined(CONFIG_STM32L4_RTC_LSICLOCK) + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI); + +#elif defined(CONFIG_STM32L4_RTC_LSECLOCK) + modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE); +#endif + + putreg32(tr_bkp, STM32L4_RTC_TR); + putreg32(dr_bkp, STM32L4_RTC_DR); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + + /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */ + + modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_RTCEN); + } + } + + (void)stm32l4_pwr_enablebkp(false); + + /* Loop, attempting to initialize/resume the RTC. This loop is necessary + * because it seems that occasionally it takes longer to initialize the RTC + * (the actual failure is in rtc_synchwait()). + */ + + do + { + /* Wait for the RTC Time and Date registers to be synchronized with RTC APB + * clock. + */ + + ret = rtc_synchwait(); + + /* Check that rtc_syncwait() returned successfully */ + + switch (ret) + { + case OK: + { + rtclldbg("rtc_syncwait() okay\n"); + break; + } + + default: + { + rtclldbg("rtc_syncwait() failed (%d)\n", ret); + break; + } + } + } + while (ret != OK && ++nretry < maxretry); + + /* Check if the one-time initialization of the RTC has already been + * performed. We can determine this by checking if the magic number + * has been writing to to back-up date register DR0. + */ + + if (regval != RTC_MAGIC) + { + rtclldbg("Do setup\n"); + + /* Perform the one-time setup of the LSE clocking to the RTC */ + + ret = rtc_setup(); + + /* Enable write access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + */ + + (void)stm32l4_pwr_enablebkp(true); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, RTC_MAGIC_REG); + } + else + { + rtclldbg("Do resume\n"); + + /* RTC already set-up, just resume normal operation */ + + rtc_resume(); + rtc_dumpregs("Did resume"); + } + + /* Disable write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). + */ + + (void)stm32l4_pwr_enablebkp(false); + + if (ret != OK && nretry > 0) + { + rtclldbg("setup/resume ran %d times and failed with %d\n", + nretry, ret); + return -ETIMEDOUT; + } + + /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are + * connected to the EXTI controller. To enable the RTC Alarm interrupt, the + * following sequence is required: + * + * 1. Configure and enable the EXTI Line 18 in interrupt mode and select the + * rising edge sensitivity. + * 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC. + * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B). + */ + +#ifdef CONFIG_RTC_ALARM +# warning "Missing EXTI setup logic" + + /* Then attach the ALARM interrupt handler */ + + irq_attach(STM32L4_IRQ_RTC_WKUP, rtc_interrupt); + up_enable_irq(STM32L4_IRQ_RTC_WKUP); +#endif + + g_rtc_enabled = true; + rtc_dumpregs("After Initialization"); + return OK; +} + +/************************************************************************************ + * Name: stm32l4_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected. + * + * Sub-second accuracy is returned through 'nsec'. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int stm32l4_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec) +{ + uint32_t ssr; + uint32_t dr; + uint32_t tr; + uint32_t tmp; + + /* Sample the data time registers. There is a race condition here... If we sample + * the time just before midnight on December 31, the date could be wrong because + * the day rolled over while were sampling. + */ + + do + { + dr = getreg32(STM32L4_RTC_DR); + tr = getreg32(STM32L4_RTC_TR); + ssr = getreg32(STM32L4_RTC_SSR); + tmp = getreg32(STM32L4_RTC_DR); + } + while (tmp != dr); + + rtc_dumpregs("Reading Time"); + + /* Convert the RTC time to fields in struct tm format. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tmp = (tr & (RTC_TR_SU_MASK | RTC_TR_ST_MASK)) >> RTC_TR_SU_SHIFT; + tp->tm_sec = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_MNU_MASK | RTC_TR_MNT_MASK)) >> RTC_TR_MNU_SHIFT; + tp->tm_min = rtc_bcd2bin(tmp); + + tmp = (tr & (RTC_TR_HU_MASK | RTC_TR_HT_MASK)) >> RTC_TR_HU_SHIFT; + tp->tm_hour = rtc_bcd2bin(tmp); + + /* Now convert the RTC date to fields in struct tm format: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + tmp = (dr & (RTC_DR_DU_MASK | RTC_DR_DT_MASK)) >> RTC_DR_DU_SHIFT; + tp->tm_mday = rtc_bcd2bin(tmp); + + tmp = (dr & (RTC_DR_MU_MASK | RTC_DR_MT)) >> RTC_DR_MU_SHIFT; + tp->tm_mon = rtc_bcd2bin(tmp) - 1; + + tmp = (dr & (RTC_DR_YU_MASK | RTC_DR_YT_MASK)) >> RTC_DR_YU_SHIFT; + tp->tm_year = rtc_bcd2bin(tmp) + 100; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + tmp = (dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT; + tp->tm_wday = tmp % 7; + tp->tm_yday = tp->tm_mday + clock_daysbeforemonth(tp->tm_mon, clock_isleapyear(tp->tm_year + 1900)); + tp->tm_isdst = 0 +#endif + + /* Return RTC sub-seconds if a non-NULL value + * of nsec has been provided to receive the sub-second value. + */ + + if (nsec) + { + uint32_t prediv_s; + uint32_t usecs; + + prediv_s = getreg32(STM32L4_RTC_PRER) & RTC_PRER_PREDIV_S_MASK; + prediv_s >>= RTC_PRER_PREDIV_S_SHIFT; + + ssr &= RTC_SSR_MASK; + + /* Maximum prediv_s is 0x7fff, thus we can multiply by 100000 and + * still fit 32-bit unsigned integer. + */ + + usecs = (((prediv_s - ssr) * 100000) / (prediv_s + 1)) * 10; + *nsec = usecs * 1000; + } + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected. + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + return stm32l4_rtc_getdatetime_with_subseconds(tp, NULL); +} + +/************************************************************************************ + * Name: stm32l4_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this + * function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int stm32l4_rtc_setdatetime(FAR const struct tm *tp) +{ + uint32_t tr; + uint32_t dr; + int ret; + + rtc_dumptime(tp, "Setting time"); + + /* Then write the broken out values to the RTC */ + + /* Convert the struct tm format to RTC time register fields. All of the STM32 + * All of the ranges of values correspond between struct tm and the time + * register. + */ + + tr = (rtc_bin2bcd(tp->tm_sec) << RTC_TR_SU_SHIFT) | + (rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) | + (rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT); + tr &= ~RTC_TR_RESERVED_BITS; + + /* Now convert the fields in struct tm format to the RTC date register fields: + * Days: 1-31 match in both cases. + * Month: STM32 is 1-12, struct tm is 0-11. + * Years: STM32 is 00-99, struct tm is years since 1900. + * WeekDay: STM32 is 1 = Mon - 7 = Sun + * Issue: I am not sure what the STM32 years mean. Are these the + * years 2000-2099? I'll assume so. + */ + + dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) | + ((rtc_bin2bcd(tp->tm_mon + 1)) << RTC_DR_MU_SHIFT) | +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + ((tp->tm_wday == 0 ? 7 : (tp->tm_wday & 7)) << RTC_DR_WDU_SHIFT) | +#endif + ((rtc_bin2bcd(tp->tm_year - 100)) << RTC_DR_YU_SHIFT); + + dr &= ~RTC_DR_RESERVED_BITS; + + /* Disable the write protection for RTC registers */ + + rtc_wprunlock(); + + /* Set Initialization mode */ + + ret = rtc_enterinit(); + if (ret == OK) + { + /* Set the RTC TR and DR registers */ + + putreg32(tr, STM32L4_RTC_TR); + putreg32(dr, STM32L4_RTC_DR); + + /* Exit Initialization mode and wait for the RTC Time and Date + * registers to be synchronized with RTC APB clock. + */ + + rtc_exitinit(); + ret = rtc_synchwait(); + } + + /* Re-enable the write protection for RTC registers */ + + rtc_wprlock(); + rtc_dumpregs("New time setting"); + return ret; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + + /* Break out the time values (not that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + return stm32l4_rtc_setdatetime(&newtime); +} + +/************************************************************************************ + * Name: stm32l4_rtc_setalarm + * + * Description: + * Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B). + * + * Input Parameters: + * tp - the time to set the alarm + * callback - the function to call when the alarm expires. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32l4_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) +{ + int ret = -EBUSY; + + /* Is there already something waiting on the ALARM? */ + + if (g_alarmcb == NULL) + { + /* No.. Save the callback function pointer */ + + g_alarmcb = callback; + + /* Break out the time values */ +#warning "Missing logic" + + /* The set the alarm */ +#warning "Missing logic" + + ret = OK; + } + + return ret; +} +#endif + +#endif /* CONFIG_RTC */ diff --git a/arch/arm/src/stm32l4/stm32l4_sdio.h b/arch/arm/src/stm32l4/stm32l4_sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c b/arch/arm/src/stm32l4/stm32l4_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..68e9e7524579ee895686f61d6f29a3e2edc0d696 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_serial.c @@ -0,0 +1,2580 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_serial.c + * + * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include + +#include "chip.h" +#include "stm32l4_uart.h" +#include "stm32l4_dma.h" +#include "stm32l4_rcc.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* DMA configuration */ + +/* If DMA is enabled on any USART, then very that other pre-requisites + * have also been selected. + * UART DMA1 DMA2 + * 1 X X + * 2 X + * 3 X + * 4 X + * 5 X + */ + +#ifdef SERIAL_HAVE_DMA + +/* Verify that DMA has been enabled and the DMA channel has been defined. + */ + +# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) +# ifndef CONFIG_STM32L4_DMA1 +# error STM32 USART2/3 receive DMA requires CONFIG_STM32L4_DMA1 +# endif +# endif + +# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) +# ifndef CONFIG_STM32L4_DMA2 +# error STM32 USART4/5 receive DMA requires CONFIG_STM32L4_DMA2 +# endif +# endif + +/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack + * of testing - RS-485 support was developed on STM32F1x + */ + +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ + (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ + (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ + (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ + (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) +# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" +# endif + +/* For the L4, there are alternate DMA channels for USART1. + * Logic in the board.h file make the DMA channel selection by defining + * the following in the board.h file. + */ + +# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) +# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" +# endif + +/* UART2-5 have no alternate channels */ + +# define DMAMAP_USART2_RX DMACHAN_USART2_RX +# define DMAMAP_USART3_RX DMACHAN_USART3_RX +# define DMAMAP_UART4_RX DMACHAN_UART4_RX +# define DMAMAP_UART5_RX DMACHAN_UART5_RX + +/* The DMA buffer size when using RX DMA to emulate a FIFO. + * + * When streaming data, the generic serial layer will be called + * every time the FIFO receives half this number of bytes. + */ + +# define RXDMA_BUFFER_SIZE 32 + +/* DMA priority */ + +# ifndef CONFIG_USART_DMAPRIO +# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \ + defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX) +# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED +# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED +# else +# error "Unknown STM32 DMA" +# endif +# endif +# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \ + defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# else +# error "Unknown STM32 DMA" +# endif + +/* DMA control words */ + +# if defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_CIRC | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# endif +# else +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_CCR_CIRC | \ + DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# endif +# endif + +#endif + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_PM_SERIAL_ACTIVITY) +# define CONFIG_PM_SERIAL_ACTIVITY 10 +# define PM_IDLE_DOMAIN 0 /* Revisit */ +#endif + +#ifdef USE_SERIALDRIVER +#ifdef HAVE_UART + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt mask bits value */ + uint16_t sr; /* Saved status bits */ + + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif + uint32_t baud; /* Configured baud */ +#else + const uint8_t parity; /* 0=none, 1=odd, 2=even */ + const uint8_t bits; /* Number of bits (7 or 8) */ + const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif + const uint32_t baud; /* Configured baud */ +#endif + + const uint8_t irq; /* IRQ associated with this USART */ + const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t usartbase; /* Base address of USART registers */ + const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif + +#ifdef SERIAL_HAVE_DMA + const unsigned int rxdma_channel; /* DMA channel assigned */ +#endif + + int (*const vector)(int irq, void *context); /* Interrupt handler */ + + /* RX DMA state */ + +#ifdef SERIAL_HAVE_DMA + DMA_HANDLE rxdma; /* currently-open receive DMA stream */ + bool rxenable; /* DMA-based reception en/disable */ + uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ + char *const rxfifo; /* Receive DMA buffer */ +#endif + +#ifdef HAVE_RS485 + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void up_set_format(struct uart_dev_s *dev); +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt_common(struct up_dev_s *dev); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, + bool upper); +#endif +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev); +static void up_dma_shutdown(struct uart_dev_s *dev); +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_dma_rxint(struct uart_dev_s *dev, bool enable); +static bool up_dma_rxavailable(struct uart_dev_s *dev); + +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +#ifdef CONFIG_STM32L4_USART1 +static int up_interrupt_usart1(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_USART2 +static int up_interrupt_usart2(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_USART3 +static int up_interrupt_usart3(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_UART4 +static int up_interrupt_uart4(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_UART5 +static int up_interrupt_uart5(int irq, void *context); +#endif + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +#ifdef SERIAL_HAVE_DMA +static const struct uart_ops_s g_uart_dma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_dma_receive, + .rxint = up_dma_rxint, + .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; +#endif + +/* I/O buffers */ + +#ifdef CONFIG_STM32L4_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +# ifdef CONFIG_USART1_RXDMA +static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +# ifdef CONFIG_USART2_RXDMA +static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +# ifdef CONFIG_USART3_RXDMA +static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +# ifdef CONFIG_UART4_RXDMA +static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +# ifdef CONFIG_UART5_RXDMA +static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +/* This describes the state of the STM32 USART1 ports. */ + +#ifdef CONFIG_STM32L4_USART1 +static struct up_dev_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, +#ifdef CONFIG_USART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart1priv, + }, + + .irq = STM32L4_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = STM32L4_PCLK2_FREQUENCY, + .usartbase = STM32L4_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +#endif +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, + .rxfifo = g_usart1rxfifo, +#endif + .vector = up_interrupt_usart1, + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_USART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART2 port. */ + +#ifdef CONFIG_STM32L4_USART2 +static struct up_dev_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, +#ifdef CONFIG_USART2_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart2priv, + }, + + .irq = STM32L4_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, + .rxfifo = g_usart2rxfifo, +#endif + .vector = up_interrupt_usart2, + +#ifdef CONFIG_USART2_RS485 + .rs485_dir_gpio = GPIO_USART2_RS485_DIR, +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART3 port. */ + +#ifdef CONFIG_STM32L4_USART3 +static struct up_dev_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, +#ifdef CONFIG_USART3_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart3priv, + }, + + .irq = STM32L4_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, + .rxfifo = g_usart3rxfifo, +#endif + .vector = up_interrupt_usart3, + +#ifdef CONFIG_USART3_RS485 + .rs485_dir_gpio = GPIO_USART3_RS485_DIR, +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART4 port. */ + +#ifdef CONFIG_STM32L4_UART4 +static struct up_dev_s g_uart4priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, +#ifdef CONFIG_UART4_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart4priv, + }, + + .irq = STM32L4_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART4_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_UART4_BASE, + .tx_gpio = GPIO_UART4_TX, + .rx_gpio = GPIO_UART4_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART4_RXDMA + .rxdma_channel = DMAMAP_UART4_RX, + .rxfifo = g_uart4rxfifo, +#endif + .vector = up_interrupt_uart4, + +#ifdef CONFIG_UART4_RS485 + .rs485_dir_gpio = GPIO_UART4_RS485_DIR, +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART5 port. */ + +#ifdef CONFIG_STM32L4_UART5 +static struct up_dev_s g_uart5priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, +#ifdef CONFIG_UART5_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart5priv, + }, + + .irq = STM32L4_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART5_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_UART5_BASE, + .tx_gpio = GPIO_UART5_TX, + .rx_gpio = GPIO_UART5_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART5_RXDMA + .rxdma_channel = DMAMAP_UART5_RX, + .rxfifo = g_uart5rxfifo, +#endif + .vector = up_interrupt_uart5, + +#ifdef CONFIG_UART5_RS485 + .rs485_dir_gpio = GPIO_UART5_RS485_DIR, +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +static struct up_dev_s * const uart_devs[STM32L4_NUSART] = +{ +#ifdef CONFIG_STM32L4_USART1 + [0] = &g_usart1priv, +#endif +#ifdef CONFIG_STM32L4_USART2 + [1] = &g_usart2priv, +#endif +#ifdef CONFIG_STM32L4_USART3 + [2] = &g_usart3priv, +#endif +#ifdef CONFIG_STM32L4_UART4 + [3] = &g_uart4priv, +#endif +#ifdef CONFIG_STM32L4_UART5 + [4] = &g_uart5priv, +#endif +}; + +#ifdef CONFIG_PM +static struct pm_callback_s g_serialcb = +{ + .notify = up_pm_notify, + .prepare = up_pm_prepare, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) +{ + uint32_t cr; + + /* Save the interrupt mask */ + + priv->ie = ie; + + /* And restore the interrupt state (see the interrupt enable/usage table above) */ + + cr = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + cr &= ~(USART_CR1_USED_INTS); + cr |= (ie & (USART_CR1_USED_INTS)); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, cr); + + cr = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + cr &= ~USART_CR3_EIE; + cr |= (ie & USART_CR3_EIE); + up_serialout(priv, STM32L4_USART_CR3_OFFSET, cr); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) +{ + if (ie) + { + uint32_t cr1; + uint32_t cr3; + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------ ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Flag + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + cr1 = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + cr3 = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + + /* Return the current interrupt mask value for the used interrupts. Notice + * that this depends on the fact that none of the used interrupt enable bits + * overlap. This logic would fail if we needed the break interrupt! + */ + + *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); + } + + /* Disable all interrupts */ + + up_restoreusartint(priv, 0); +} + +/**************************************************************************** + * Name: up_dma_nextrx + * + * Description: + * Returns the index into the RX FIFO where the DMA will place the next + * byte that it receives. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_nextrx(struct up_dev_s *priv) +{ + size_t dmaresidual; + + dmaresidual = stm32l4_dmaresidual(priv->rxdma); + + return (RXDMA_BUFFER_SIZE - (int)dmaresidual); +} +#endif + +/**************************************************************************** + * Name: up_set_format + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void up_set_format(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* This first implementation is for U[S]ARTs that support oversampling + * by 8 in additional to the standard oversampling by 16. + */ + + uint32_t usartdiv8; + uint32_t cr1; + uint32_t brr; + + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ + + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = 2 * usartdiv8 + */ + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + + cr1 = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + if (usartdiv8 > 100) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, cr1); + up_serialout(priv, STM32L4_USART_BRR_OFFSET, brr); + + /* Configure parity mode */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + /* Configure word length (parity uses one of configured bits) + * + * Default: 1 start, 8 data (no parity), n stop, OR + * 1 start, 7 data + parity, n stop + */ + + if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) + { + /* Select: 1 start, 8 data + parity, n stop, OR + * 1 start, 9 data (no parity), n stop. + */ + + regval |= USART_CR1_M0; + } + else if (priv->bits == 7 && priv->parity == 0) + { + /* Select: 1 start, 7 data (no parity), n stop, OR + */ + + regval |= USART_CR1_M1; + } + /* Else Select: 1 start, 7 data + parity, n stop, OR + * 1 start, 8 data (no parity), n stop. + */ + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32L4_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32L4_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); +} +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Name: up_set_apb_clock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void up_set_apb_clock(struct uart_dev_s *dev, bool on) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32L4_USART1 + case STM32L4_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32L4_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32L4_USART2 + case STM32L4_USART2_BASE: + rcc_en = RCC_APB1ENR1_USART2EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_USART3 + case STM32L4_USART3_BASE: + rcc_en = RCC_APB1ENR1_USART3EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_UART4 + case STM32L4_UART4_BASE: + rcc_en = RCC_APB1ENR1_UART4EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_UART5 + case STM32L4_UART5_BASE: + rcc_en = RCC_APB1ENR1_UART5EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled in stm32l4_lowsetup(). + */ + + /* Enable USART APB1/2 clock */ + + up_set_apb_clock(dev, true); + + /* Configure pins for USART use */ + + stm32l4_configgpio(priv->tx_gpio); + stm32l4_configgpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32l4_configgpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32L4_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32l4_configgpio(config); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_configgpio(priv->rs485_dir_gpio); + stm32l4_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + } +#endif + + /* Configure CR2 */ + /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + + /* Configure STOP bits */ + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32L4_USART_CR2_OFFSET, regval); + + /* Configure CR1 */ + /* Clear TE, REm and all interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Configure CR3 */ + /* Clear CTSE, RTSE, and all interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE); + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); + + /* Configure the USART line format and speed. */ + + up_set_format(dev); + + /* Enable Rx, Tx, and the USART */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + + /* Set up the cached interrupt enables value */ + + priv->ie = 0; + return OK; +} + +/**************************************************************************** + * Name: up_dma_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int result; + uint32_t regval; + + /* Do the basic UART setup first, unless we are the console */ + + if (!dev->isconsole) + { + result = up_setup(dev); + if (result != OK) + { + return result; + } + } + + /* Acquire the DMA channel. This should always succeed. */ + + priv->rxdma = stm32l4_dmachannel(priv->rxdma_channel); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Enable receive DMA for the UART */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval |= USART_CR3_DMAR; + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Disable all interrupts */ + + up_disableusartint(priv, NULL); + + /* Disable USART APB1/2 clock */ + + up_set_apb_clock(dev, false); + + /* Disable Rx, Tx, and the UART */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Release pins. "If the serial-attached device is powered down, the TX + * pin causes back-powering, potentially confusing the device to the point + * of complete lock-up." + * + * REVISIT: Is unconfiguring the pins appropriate for all device? If not, + * then this may need to be a configuration option. + */ + + stm32l4_unconfiggpio(priv->tx_gpio); + stm32l4_unconfiggpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32l4_unconfiggpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + stm32l4_unconfiggpio(priv->rts_gpio); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_unconfiggpio(priv->rs485_dir_gpio); + } +#endif +} + +/**************************************************************************** + * Name: up_dma_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Perform the normal UART shutdown */ + + up_shutdown(dev); + + /* Stop the DMA channel */ + + stm32l4_dmastop(priv->rxdma); + + /* Release the DMA channel */ + + stm32l4_dmafree(priv->rxdma); + priv->rxdma = NULL; +} +#endif + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->vector); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt_common + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt_common(struct up_dev_s *priv) +{ + int passes; + bool handled; + + /* Report serial activity to the power management logic */ + +#if defined(CONFIG_PM) && CONFIG_PM_SERIAL_ACTIVITY > 0 + pm_activity(PM_IDLE_DOMAIN, CONFIG_PM_SERIAL_ACTIVITY); +#endif + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked USART status word. */ + + priv->sr = up_serialin(priv, STM32L4_USART_ISR_OFFSET); + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NE Noise Error + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + * + * NOTE: Some of these status bits must be cleared by explicity writing zero + * to the SR register: USART_ISR_CTS, USART_ISR_LBD. Note of those are currently + * being used. + */ + +#ifdef HAVE_RS485 + /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. + * Note - this should be first, to have the most recent TC bit value from + * SR register - sending data affects TC, but without refresh we will not + * know that... + */ + + if ((priv->sr & USART_ISR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && + (priv->ie & USART_CR1_TXEIE) == 0) + { + stm32l4_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); + } +#endif + + /* Handle incoming, receive bytes. */ + + if ((priv->sr & USART_ISR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0) + { + /* Received data ready... process incoming bytes. NOTE the check for + * RXNEIE: We cannot call uart_recvchards of RX interrupts are disabled. + */ + + uart_recvchars(&priv->dev); + handled = true; + } + + /* We may still have to read from the DR register to clear any pending + * error conditions. + */ + + else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) + { + /* These errors are cleared by writing the corresponding bit to the + * interrupt clear register (ICR). + */ + + up_serialout(priv, STM32L4_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF)); + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & USART_ISR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(&priv->dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif +#ifdef CONFIG_SERIAL_TERMIOS + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_STM32L4_USART_SINGLEWIRE + case TIOCSSINGLEWIRE: + { + /* Change the TX port to be open-drain/push-pull and enable/disable + * half-duplex mode. + */ + + uint32_t cr = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + +#if defined(CONFIG_STM32L4_STM32F10XX) + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD); + cr |= USART_CR3_HDSEL; + } + else + { + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFPP); + cr &= ~USART_CR3_HDSEL; + } +#else + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32l4_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + cr |= USART_CR3_HDSEL; + } + else + { + stm32l4_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + cr &= ~USART_CR3_HDSEL; + } +#endif + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, cr); + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + up_set_format(dev); + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + +#ifdef CONFIG_USART_BREAKS + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + uint32_t cr2 = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + up_serialout(priv, STM32L4_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + uint32_t cr1 = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + up_serialout(priv, STM32L4_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rdr; + + /* Get the Rx byte */ + + rdr = up_serialin(priv, STM32L4_USART_RDR_OFFSET); + + /* Get the Rx byte plux error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint16_t ie; + + /* USART receive interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Flag + * " " USART_ISR_ORE Overrun Error Detected + */ + + flags = enter_critical_section(); + ie = priv->ie; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_USART_ERRINTS + ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); +#else + ie |= USART_CR1_RXNEIE; +#endif +#endif + } + else + { + ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); + } + + /* Then set the new interrupt state */ + + up_restoreusartint(priv, ie); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32L4_USART_ISR_OFFSET) & USART_ISR_RXNE) != 0); +} +#endif + +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32L4_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32l4_gpiowrite(priv->rts_gpio, upper); + return upper; + } + +#else + if (priv->iflow) + { + /* Is the RX buffer full? */ + + if (upper) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral. When hardware RTS is enabled, this will + * prevent more data from coming in. + * + * This function is only called when UART recv buffer is full, + * that is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts + * when buffer is read empty and thus we do not have to re- + * enable Rx interrupts. + */ + + uart_disablerxint(dev); + return true; + } + + /* No.. The RX buffer is empty */ + + else + { + /* We might leave Rx interrupt disabled if full recv buffer was + * read empty. Enable Rx interrupt to make sure that more input is + * received. + */ + + uart_enablerxint(dev); + } + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: up_dma_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int c = 0; + + if (up_dma_nextrx(priv) != priv->rxdmanext) + { + c = priv->rxfifo[priv->rxdmanext]; + + priv->rxdmanext++; + if (priv->rxdmanext == RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* RX DMA buffer full. RX paused, RTS line pulled up to prevent + * more input data from other end. + */ + } + else +#endif + { + priv->rxdmanext = 0; + } + } + } + + return c; +} +#endif + +/**************************************************************************** + * Name: up_dma_reenable + * + * Description: + * Call to re-enable RX DMA. + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) +static void up_dma_reenable(struct up_dev_s *priv) +{ + /* Configure for non-circular DMA reception into the RX fifo */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Start the DMA channel, and arrange for callbacks at the full point in + * the FIFO. After buffer gets full, hardware flow-control kicks in and + * DMA transfer is stopped. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* En/disable DMA reception. + * + * Note that it is not safe to check for available bytes and immediately + * pass them to uart_recvchars as that could potentially recurse back + * to us again. Instead, bytes must wait until the next up_dma_poll or + * DMA event. + */ + + priv->rxenable = enable; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif +} +#endif + +/**************************************************************************** + * Name: up_dma_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static bool up_dma_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Compare our receive pointer to the current DMA pointer, if they + * do not match, then there are bytes to be received. + */ + + return (up_dma_nextrx(priv) != priv->rxdmanext); +} +#endif + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + } +#endif + + up_serialout(priv, STM32L4_USART_TDR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ---------------------------- ---------- + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uint16_t ie = priv->ie | USART_CR1_TXEIE; + + /* If RS-485 is supported on this U[S]ART, then also enable the + * transmission complete interrupt. + */ + +# ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + ie |= USART_CR1_TCIE; + } +# endif + + up_restoreusartint(priv, ie); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32L4_USART_ISR_OFFSET) & USART_ISR_TXE) != 0); +} + +/**************************************************************************** + * Name: up_interrupt_u[s]art[n] + * + * Description: + * Interrupt handlers for U[S]ART[n] where n=1,..,6. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_USART1 +static int up_interrupt_usart1(int irq, void *context) +{ + return up_interrupt_common(&g_usart1priv); +} +#endif + +#ifdef CONFIG_STM32L4_USART2 +static int up_interrupt_usart2(int irq, void *context) +{ + return up_interrupt_common(&g_usart2priv); +} +#endif + +#ifdef CONFIG_STM32L4_USART3 +static int up_interrupt_usart3(int irq, void *context) +{ + return up_interrupt_common(&g_usart3priv); +} +#endif + +#ifdef CONFIG_STM32L4_UART4 +static int up_interrupt_uart4(int irq, void *context) +{ + return up_interrupt_common(&g_uart4priv); +} +#endif + +#ifdef CONFIG_STM32L4_UART5 +static int up_interrupt_uart5(int irq, void *context) +{ + return up_interrupt_common(&g_uart5priv); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxcallback + * + * Description: + * This function checks the current DMA state and calls the generic + * serial stack when bytes appear to be available. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = (struct up_dev_s *)arg; + + if (priv->rxenable && up_dma_rxavailable(&priv->dev)) + { + uart_recvchars(&priv->dev); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && + (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif + } +} +#endif + +/**************************************************************************** + * Name: up_pm_notify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * None - The driver already agreed to transition to the low power + * consumption state when when it returned OK to the prepare() call. + * + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + switch (pmstate) + { + case(PM_NORMAL): + { + /* Logic for PM_NORMAL goes here */ + + } + break; + + case(PM_IDLE): + { + /* Logic for PM_IDLE goes here */ + + } + break; + + case(PM_STANDBY): + { + /* Logic for PM_STANDBY goes here */ + + } + break; + + case(PM_SLEEP): + { + /* Logic for PM_SLEEP goes here */ + + } + break; + + default: + /* Should not get here */ + break; + } +} +#endif + +/**************************************************************************** + * Name: up_pm_prepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * Zero - (OK) means the event was successfully processed and that the + * driver is prepared for the PM state change. + * + * Non-zero - means that the driver is not prepared to perform the tasks + * needed achieve this power setting and will cause the state + * change to be aborted. NOTE: The prepare() method will also + * be called when reverting from lower back to higher power + * consumption modes (say because another driver refused a + * lower power state change). Drivers are not permitted to + * return non-zero values when reverting back to higher power + * consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + /* Logic to prepare for a reduced power state goes here. */ + + return OK; +} +#endif +#endif /* HAVE_UART */ +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ +#ifdef HAVE_UART + unsigned i; + + /* Disable all USART interrupts */ + + for (i = 0; i < STM32L4_NUSART; i++) + { + if (uart_devs[i]) + { + up_disableusartint(uart_devs[i], NULL); + } + } + + /* Configure whichever one is the console */ + +#if CONSOLE_UART > 0 + up_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* HAVE UART */ +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef HAVE_UART + char devname[16]; + unsigned i; + unsigned minor = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Register to receive power management callbacks */ + +#ifdef CONFIG_PM + ret = pm_register(&g_serialcb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + /* Register the console */ + +#if CONSOLE_UART > 0 + (void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + (void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#ifdef SERIAL_HAVE_CONSOLE_DMA + /* If we need to re-initialise the console to enable DMA do that here. */ + + up_dma_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strcpy(devname, "/dev/ttySx"); + + for (i = 0; i < STM32L4_NUSART; i++) + { + /* Don't create a device for non-configured ports. */ + + if (uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* Don't create a device for the console - we did that above */ + + if (uart_devs[i]->dev.isconsole) + { + continue; + } +#endif + + /* Register USARTs as devices in increasing order */ + + devname[9] = '0' + minor++; + (void)uart_register(devname, &uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: stm32l4_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32l4_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_USART1_RXDMA + if (g_usart1priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); + } +#endif + +#ifdef CONFIG_USART2_RXDMA + if (g_usart2priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); + } +#endif + +#ifdef CONFIG_USART3_RXDMA + if (g_usart3priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); + } +#endif + +#ifdef CONFIG_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); + } +#endif + +#ifdef CONFIG_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); + } +#endif + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct up_dev_s *priv = uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + up_disableusartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreusartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..86c7ddbc54a7ddb0a54086408d8e4ed9abe8efde --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_spi.c @@ -0,0 +1,1495 @@ +/************************************************************************************ + * arm/arm/src/stm32l4/stm32l4_spi.c + * + * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status must be + * provided by board-specific logic. They are implementations of the select + * and status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including stm32l4_spibus_initialize()) + * are provided by common STM32 logic. To use this common SPI logic on your + * board: + * + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. Add a calls to stm32l4_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by stm32l4_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************c********************************/ + +/* + * This driver is ported from the stm32 one, which only supports 8 and 16 bits + * transfers. The STM32L4 family supports frame size from 4 to 16 bits, but we do not + * support that yet. For the moment, we replace uses of the CR1_DFF bit with a check + * of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits, else 8 bits. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4.h" +#include "stm32l4_gpio.h" +#include "stm32l4_dma.h" +#include "stm32l4_spi.h" + +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* SPI interrupts */ + +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_STM32L4_SPI_INTERRUPTS) && defined(CONFIG_STM32L4_SPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/* SPI DMA priority */ + +#ifdef CONFIG_STM32L4_SPI_DMA + +# if defined(CONFIG_SPI_DMAPRIO) +# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO +# else +# define SPI_DMA_PRIO DMA_CCR_PRIMED +# endif + +# if (SPI_DMA_PRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif + +#endif + +/* DMA channel configuration */ + +#define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC ) +#define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC ) +#define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS ) +#define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS ) +#define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR) +#define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR) +#define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR) +#define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR) + + +/* Debug ****************************************************************************/ +/* Check if (non-standard) SPI debug is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct stm32l4_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ + uint32_t spiclock; /* Clocking for the SPI module */ +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + uint8_t spiirq; /* SPI IRQ number */ +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the RX DMA */ + uint16_t rxch; /* The RX DMA channel number */ + uint16_t txch; /* The TX DMA channel number */ + DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */ + DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ + sem_t rxsem; /* Wait for RX DMA to complete */ + sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + int8_t nbits; /* Width of word in bits (8 or 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* Helpers */ + +static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset); +static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset, + uint16_t value); +static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv); +static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t byte); +static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv); + +/* DMA support */ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv); +static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv); +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, + FAR void *rxbuffer, FAR void *rxdummy, size_t nwords); +static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv, + FAR const void *txbuffer, FAR const void *txdummy, size_t nwords); +static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv); +#endif + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + +/* Initialization */ + +static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = stm32l4_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = stm32l4_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi1dev = +{ + .spidev = { &g_spi1ops }, + .spibase = STM32L4_SPI1_BASE, + .spiclock = STM32L4_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI1, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + /* lines must be configured in board.h */ + .rxch = DMACHAN_SPI1_RX, + .txch = DMACHAN_SPI1_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32L4_SPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = stm32l4_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32l4_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi2register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi2dev = +{ + .spidev = { &g_spi2ops }, + .spibase = STM32L4_SPI2_BASE, + .spiclock = STM32L4_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI2, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + .rxch = DMACHAN_SPI2_RX, + .txch = DMACHAN_SPI2_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32L4_SPI3 +static const struct spi_ops_s g_spi3ops = +{ + .lock = spi_lock, + .select = stm32l4_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32l4_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi3register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi3dev = +{ + .spidev = { &g_spi3ops }, + .spibase = STM32L4_SPI3_BASE, + .spiclock = STM32L4_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI3, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + .rxch = DMACHAN_SPI3_RX, + .txch = DMACHAN_SPI3_TX, +#endif +}; +#endif + +/*endif?*/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset) +{ + return getreg16(priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset, uint16_t value) +{ + putreg16(value, priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_readword + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ************************************************************************************/ + +static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0); + + /* Then return the received byte */ + + return spi_getreg(priv, STM32L4_SPI_DR_OFFSET); +} + +/************************************************************************************ + * Name: spi_writeword + * + * Description: + * Write one byte to SPI + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t word) +{ + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_TXE) == 0); + + /* Then send the byte */ + + spi_putreg(priv, STM32L4_SPI_DR_OFFSET, word); +} + +/************************************************************************************ + * Name: spi_16bitmode + * + * Description: + * Check if the SPI is operating in 16-bit mode + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: 16-bit mode, false: 8-bit mode + * + ************************************************************************************/ + +static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv) +{ + return ((spi_getreg(priv, STM32L4_SPI_CR2_OFFSET) & SPI_CR2_DS_MASK) == SPI_CR2_DS_16BIT); +} + +/************************************************************************************ + * Name: spi_dmarxwaitw + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->rxsem) != 0 || priv->rxresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwait + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->txsem) != 0 || priv->txresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmarxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv) +{ + (void)sem_post(&priv->rxsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv) +{ + (void)sem_post(&priv->txsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->rxresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmarxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->txresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmatxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxsetup + * + * Description: + * Setup to perform RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, FAR void *rxbuffer, + FAR void *rxdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA16_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA8_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA8NULL_CONFIG; + } + } + + /* Configure the RX DMA */ + + stm32l4_dmasetup(priv->rxdma, priv->spibase + STM32L4_SPI_DR_OFFSET, + (uint32_t)rxbuffer, nwords, priv->rxccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxsetup + * + * Description: + * Setup to perform TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv, FAR const void *txbuffer, + FAR const void *txdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA16_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA8_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA8NULL_CONFIG; + } + } + + /* Setup the TX DMA */ + + stm32l4_dmasetup(priv->txdma, priv->spibase + STM32L4_SPI_DR_OFFSET, + (uint32_t)txbuffer, nwords, priv->txccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxstart + * + * Description: + * Start RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv) +{ + priv->rxresult = 0; + stm32l4_dmastart(priv->rxdma, spi_dmarxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxstart + * + * Description: + * Start TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv) +{ + priv->txresult = 0; + stm32l4_dmastart(priv->txdma, spi_dmatxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_modifycr + * + * Description: + * Clear and set bits in the CR1 or CR2 register + * + * Input Parameters: + * priv - Device-specific state data + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv, uint16_t setbits, uint16_t clrbits) +{ + uint16_t cr1; + cr1 = spi_getreg(priv, addr); + cr1 &= ~clrbits; + cr1 |= setbits; + spi_putreg(priv, addr, cr1); +} + +/************************************************************************************ + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ************************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/************************************************************************************ + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits; + uint32_t actual; + + /* Limit to max possible (if STM32L4_SPI_CLK_MAX is defined in board.h) */ + + if (frequency > STM32L4_SPI_CLK_MAX) + { + frequency = STM32L4_SPI_CLK_MAX; + } + + /* Has the frequency changed? */ + + if (frequency != priv->frequency) + { + /* Choices are limited by PCLK frequency with a set of divisors */ + + if (frequency >= priv->spiclock >> 1) + { + /* More than fPCLK/2. This is as fast as we can go */ + + setbits = SPI_CR1_FPCLCKd2; /* 000: fPCLK/2 */ + actual = priv->spiclock >> 1; + } + else if (frequency >= priv->spiclock >> 2) + { + /* Between fPCLCK/2 and fPCLCK/4, pick the slower */ + + setbits = SPI_CR1_FPCLCKd4; /* 001: fPCLK/4 */ + actual = priv->spiclock >> 2; + } + else if (frequency >= priv->spiclock >> 3) + { + /* Between fPCLCK/4 and fPCLCK/8, pick the slower */ + + setbits = SPI_CR1_FPCLCKd8; /* 010: fPCLK/8 */ + actual = priv->spiclock >> 3; + } + else if (frequency >= priv->spiclock >> 4) + { + /* Between fPCLCK/8 and fPCLCK/16, pick the slower */ + + setbits = SPI_CR1_FPCLCKd16; /* 011: fPCLK/16 */ + actual = priv->spiclock >> 4; + } + else if (frequency >= priv->spiclock >> 5) + { + /* Between fPCLCK/16 and fPCLCK/32, pick the slower */ + + setbits = SPI_CR1_FPCLCKd32; /* 100: fPCLK/32 */ + actual = priv->spiclock >> 5; + } + else if (frequency >= priv->spiclock >> 6) + { + /* Between fPCLCK/32 and fPCLCK/64, pick the slower */ + + setbits = SPI_CR1_FPCLCKd64; /* 101: fPCLK/64 */ + actual = priv->spiclock >> 6; + } + else if (frequency >= priv->spiclock >> 7) + { + /* Between fPCLCK/64 and fPCLCK/128, pick the slower */ + + setbits = SPI_CR1_FPCLCKd128; /* 110: fPCLK/128 */ + actual = priv->spiclock >> 7; + } + else + { + /* Less than fPCLK/128. This is as slow as we can go */ + + setbits = SPI_CR1_FPCLCKd256; /* 111: fPCLK/256 */ + actual = priv->spiclock >> 8; + } + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, SPI_CR1_BR_MASK); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + + spivdbg("Frequency %d->%d\n", frequency, actual); + + priv->frequency = frequency; + priv->actual = actual; + } + + return priv->actual; +} + +/************************************************************************************ + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits; + uint16_t clrbits; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR1 appropriately */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setbits = 0; + clrbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setbits = SPI_CR1_CPHA; + clrbits = SPI_CR1_CPOL; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setbits = SPI_CR1_CPOL; + clrbits = SPI_CR1_CPHA; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + clrbits = 0; + break; + + default: + return; + } + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/************************************************************************************ + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. With STM32L4, this is not restricted to 8 or 16, + * but can be any value between 4 and 16. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested, negative value means LSB first. + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits1, setbits2; + uint16_t clrbits1, clrbits2; + + spivdbg("nbits=%d\n", nbits); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + + /* Yes... Set CR1/2 appropriately */ + + /* negative sign means LSBFIRST, set this in CR1*/ + if(nbits<0) + { + setbits1 = SPI_CR1_LSBFIRST; + clrbits1 = 0; + nbits = -nbits; + } + else + { + setbits1 = 0; + clrbits1 = SPI_CR1_LSBFIRST; + } + + /* set the number of bits (valid range 4-16) */ + if(nbits<4 || nbits>16) + { + return; + } + + clrbits2 = SPI_CR2_DS_MASK; + setbits2 = SPI_CR2_DS_VAL(nbits); + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits1, clrbits1); + spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits2, clrbits2); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/************************************************************************************ + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint32_t regval; + uint16_t ret; + + DEBUGASSERT(priv && priv->spibase); + + spi_writeword(priv, wd); + ret = spi_readword(priv); + + /* Check and clear any error flags (Reading from the SR clears the error flags) */ + + regval = spi_getreg(priv, STM32L4_SPI_SR_OFFSET); + + spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval); + UNUSED(regval); + + return ret; +} + +/************************************************************************************ + * Name: spi_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchaned in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if !defined(CONFIG_STM32L4_SPI_DMA) || defined(CONFIG_STM32L4_DMACAPABLE) +#if !defined(CONFIG_STM32L4_SPI_DMA) +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#else +static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#endif +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + DEBUGASSERT(priv && priv->spibase); + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Exchange one word */ + + word = spi_send(dev, word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t)spi_send(dev, (uint16_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } +} +#endif /* !CONFIG_STM32L4_SPI_DMA || CONFIG_STM32L4_DMACAPABLE */ + +/**************************************************************************** + * Name: spi_exchange (with DMA capability) + * + * Description: + * Exchange a block of data on SPI using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + +#ifdef CONFIG_STM32L4_DMACAPABLE + if ((txbuffer && !stm32l4_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) || + (rxbuffer && !stm32l4_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr))) + { + /* Unsupported memory region, fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + } + else +#endif + { + static uint16_t rxdummy = 0xffff; + static const uint16_t txdummy = 0xffff; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + DEBUGASSERT(priv && priv->spibase); + + /* Setup DMAs */ + + spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords); + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords); + + /* Start the DMAs */ + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + + /* Then wait for each to complete */ + + spi_dmarxwait(priv); + spi_dmatxwait(priv); + } +} +#endif /* CONFIG_STM32L4_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_bus_initialize + * + * Description: + * Initialize the selected SPI bus in its default state (Master, 8-bit, mode 0, etc.) + * + * Input Parameter: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv) +{ + uint16_t setbits; + uint16_t clrbits; + + /* Configure CR1 and CR2. Default configuration: + * Mode 0: CR1.CPHA=0 and CR1.CPOL=0 + * Master: CR1.MSTR=1 + * 8-bit: CR2.DS=7 + * MSB tranmitted first: CR1.LSBFIRST=0 + * Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error) + * Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care) and CR1.RXONLY=0 + */ + + clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST | + SPI_CR1_RXONLY | SPI_CR1_BIDIOE | SPI_CR1_BIDIMODE; + setbits = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM; + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits); + + clrbits = SPI_CR2_DS_MASK; + setbits = SPI_CR2_DS_8BIT; + spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits, clrbits); + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* CRCPOLY configuration */ + + spi_putreg(priv, STM32L4_SPI_CRCPR_OFFSET, 7); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_STM32L4_SPI_DMA + /* Initialize the SPI semaphores that is used to wait for DMA completion */ + + sem_init(&priv->rxsem, 0, 0); + sem_init(&priv->txsem, 0, 0); + + /* Get DMA channels. NOTE: stm32l4_dmachannel() will always assign the DMA channel. + * if the channel is not available, then stm32l4_dmachannel() will block and wait + * until the channel becomes available. WARNING: If you have another device sharing + * a DMA channel with SPI and the code never releases that channel, then the call + * to stm32l4_dmachannel() will hang forever in this function! Don't let your + * design do that! + */ + + priv->rxdma = stm32l4_dmachannel(priv->rxch); + priv->txdma = stm32l4_dmachannel(priv->txch); + DEBUGASSERT(priv->rxdma && priv->txdma); + + spi_putreg(priv, STM32L4_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); +#endif + + /* Enable spi */ + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32l4_spibus_initialize(int bus) +{ + FAR struct stm32l4_spidev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); + +#ifdef CONFIG_STM32L4_SPI1 + if (bus == 1) + { + /* Select SPI1 */ + + priv = &g_spi1dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI1 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI1_SCK); + stm32l4_configgpio(GPIO_SPI1_MISO); + stm32l4_configgpio(GPIO_SPI1_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32L4_SPI2 + if (bus == 2) + { + /* Select SPI2 */ + + priv = &g_spi2dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI2 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI2_SCK); + stm32l4_configgpio(GPIO_SPI2_MISO); + stm32l4_configgpio(GPIO_SPI2_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32L4_SPI3 + if (bus == 3) + { + /* Select SPI3 */ + + priv = &g_spi3dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI3 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI3_SCK); + stm32l4_configgpio(GPIO_SPI3_MISO); + stm32l4_configgpio(GPIO_SPI3_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif + { + spidbg("ERROR: Unsupbused SPI bus: %d\n", bus); + return NULL; + } + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_STM32L4_SPI1 || CONFIG_STM32L4_SPI2 || CONFIG_STM32L4_SPI3 */ + diff --git a/arch/arm/src/stm32l4/stm32l4_spi.h b/arch/arm/src/stm32l4/stm32l4_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..242a81f184b6ef150307cafe14e78b9ee65b5d00 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_spi.h @@ -0,0 +1,181 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_spi.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_SPI_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32l4_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * bus number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32l4_spibus_initialize(int bus); + +/************************************************************************************ + * Name: stm32l4_spi1/2/...select and stm32l4_spi1/2/...status + * + * Description: + * The external functions, stm32l4_spi1/2/...select, stm32l4_spi1/2/...status, and + * stm32l4_spi1/2/...cmddata must be provided by board-specific logic. These are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * (including stm32l4_spibus_initialize()) are provided by common STM32 logic. To use this + * common SPI logic on your board: + * + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32l4_spi1/2/...select() and stm32l4_spi1/2/...status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, then + * provide stm32l4_spi1/2/...cmddata() functions in your board-specific logic. + * These functions will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Add a calls to stm32l4_spibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by stm32l4_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI1 +void stm32l4_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32L4_SPI2 +void stm32l4_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32L4_SPI3 +void stm32l4_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: stm32l4_spi1/2/...register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based MMC/SD + * driver when an SD card is inserted or removed, then CONFIG_SPI_CALLBACK should + * be defined and the following function(s) must be implemented. These functions + * implements the registercallback method of the SPI interface (see + * include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_STM32L4_SPI1 +int stm32l4_spi1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32L4_SPI2 +int stm32l4_spi2register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32L4_SPI3 +int stm32l4_spi3register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_SPI_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_start.c b/arch/arm/src/stm32l4/stm32l4_start.c new file mode 100644 index 0000000000000000000000000000000000000000..ee1f894d8d34b19a3cea3cd270521e33664b40ba --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_start.c @@ -0,0 +1,363 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_start.c + * arch/arm/src/chip/stm32l4_start.c + * + * Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32l4.h" +#include "stm32l4_gpio.h" +#include "stm32l4_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map ***************************************************************/ +/* + * 0x0800:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x080f:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x1000:0000 - Start of internal SRAM2 + * 0x1000:7fff - End of internal SRAM2 + * 0x2000:0000 - Start of internal SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2001:7fff - End of internal SRAM and end of heap + */ + +#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void stm32l4_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: stm32l4_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void stm32l4_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void stm32l4_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define stm32l4_fpuconfig() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + stm32l4_clockconfig(); + stm32l4_fpuconfig(); + stm32l4_lowsetup(); + stm32l4_gpioinit(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stm32l4_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + stm32l4_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/stm32l4/stm32l4_tim.h b/arch/arm/src/stm32l4/stm32l4_tim.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_timerisr.c b/arch/arm/src/stm32l4/stm32l4_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..ee02fc01fa6861deab43476fe526196d80147d4d --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_timerisr.c @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +#undef CONFIG_STM32L4_SYSTICK_HCLKd8 /* Power up default is HCLK, not HCLK/8 */ + /* And I don't know now to re-configure it yet */ + +#ifdef CONFIG_STM32L4_SYSTICK_HCLKd8 +# define SYSTICK_RELOAD ((STM32L4_HCLK_FREQUENCY / 8 / CLK_TCK) - 1) +#else +# define SYSTICK_RELOAD ((STM32L4_HCLK_FREQUENCY / CLK_TCK) - 1) +#endif + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set correctly */ + +#if 0 /* Does not work. Comes up with HCLK source and I can't change it */ + regval = getreg32(NVIC_SYSTICK_CTRL); +#ifdef CONFIG_STM32L4_SYSTICK_HCLKd8 + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STM32L4_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(STM32L4_IRQ_SYSTICK); +} + diff --git a/arch/arm/src/stm32l4/stm32l4_uart.h b/arch/arm/src/stm32l4/stm32l4_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..24fc9bd31367ad7243dd20cd29f363784c1a58a2 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_uart.h @@ -0,0 +1,263 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_uart.h + * + * Copyright (C) 2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32L4_STM32L4_UART_H +#define __ARCH_ARM_STC_STM32L4_STM32L4_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_uart.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Make sure that we have not enabled more U[S]ARTs than are supported by the + * device. + */ + +#if STM32L4_NUSART < 5 || !defined(CONFIG_STM32L4_HAVE_UART5) +# undef CONFIG_STM32L4_UART5 +#endif +#if STM32L4_NUSART < 4 || !defined(CONFIG_STM32L4_HAVE_UART4) +# undef CONFIG_STM32L4_UART4 +#endif +#if STM32L4_NUSART < 3 || !defined(CONFIG_STM32L4_HAVE_USART3) +# undef CONFIG_STM32L4_USART3 +#endif +#if STM32L4_NUSART < 2 +# undef CONFIG_STM32L4_USART2 +#endif +#if STM32L4_NUSART < 1 +# undef CONFIG_STM32L4_USART1 +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32L4_USART1) || defined(CONFIG_STM32L4_USART2) || \ + defined(CONFIG_STM32L4_USART3) || defined(CONFIG_STM32L4_UART4) || \ + defined(CONFIG_STM32L4_UART5) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART1) +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART2) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART3) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART4) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART5) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration */ + +#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_UART4_RXDMA +# undef CONFIG_UART5_RXDMA +#endif + +/* Disable the DMA configuration on all unused USARTs */ + +#ifndef CONFIG_STM32L4_USART1 +# undef CONFIG_USART1_RXDMA +#endif + +#ifndef CONFIG_STM32L4_USART2 +# undef CONFIG_USART2_RXDMA +#endif + +#ifndef CONFIG_STM32L4_USART3 +# undef CONFIG_USART3_RXDMA +#endif + +#ifndef CONFIG_STM32L4_UART4 +# undef CONFIG_UART4_RXDMA +#endif + +#ifndef CONFIG_STM32L4_UART5 +# undef CONFIG_UART5_RXDMA +#endif + +/* Is DMA available on any (enabled) USART? */ + +#undef SERIAL_HAVE_DMA +#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) || defined(CONFIG_UART4_RXDMA) || \ + defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_DMA 1 +#endif + +/* Is DMA used on the console UART? */ + +#undef SERIAL_HAVE_CONSOLE_DMA +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#endif + +/* Is DMA used on all (enabled) USARTs */ + +#define SERIAL_HAVE_ONLY_DMA 1 +#if defined(CONFIG_STM32L4_USART1) && !defined(CONFIG_USART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_USART2) && !defined(CONFIG_USART2_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_USART3) && !defined(CONFIG_USART3_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_UART4) && !defined(CONFIG_UART4_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_UART5) && !defined(CONFIG_UART5_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#endif + +/* Is RS-485 used? */ + +#if defined(CONFIG_USART1_RS485) || defined(CONFIG_USART2_RS485) || \ + defined(CONFIG_USART3_RS485) || defined(CONFIG_UART4_RS485) || \ + defined(CONFIG_UART5_RS485) +# define HAVE_RS485 1 +#endif + +#ifdef HAVE_RS485 +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) +#else +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_serial_dma_poll + * + * Description: + * Must be called periodically if any STM32 UART is configured for DMA. The DMA + * callback is triggered for each fifo size/2 bytes, but this can result in some + * bytes being transferred but not collected if the incoming data is not a whole + * multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ************************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32l4_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32L4_STM32L4_UART_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_usbdev.h b/arch/arm/src/stm32l4/stm32l4_usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_userspace.c b/arch/arm/src/stm32l4/stm32l4_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_userspace.h b/arch/arm/src/stm32l4/stm32l4_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4_waste.c b/arch/arm/src/stm32l4/stm32l4_waste.c new file mode 100644 index 0000000000000000000000000000000000000000..cb710380ea5d3877757186cd828fb8e24a9ba217 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_waste.c @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_waste.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "stm32l4_waste.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t idle_wastecounter = 0; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_waste(void) +{ + idle_wastecounter++; +} diff --git a/arch/arm/src/stm32l4/stm32l4_waste.h b/arch/arm/src/stm32l4/stm32l4_waste.h new file mode 100644 index 0000000000000000000000000000000000000000..e14459c045eb22ea97b9f08c55d6099f5b456c83 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_waste.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_waste.h + * + * Copyright (C) 2011, 2015 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_WASTE_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_WASTE_H + +/* Waste CPU Time */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/** Waste CPU Time + * + * up_waste() is the logic that will be executed when portions of kernel + * or user-app is polling some register or similar, waiting for desired + * status. This time is wasted away. This function offers a measure of + * badly written piece of software or some undesired behavior. + * + * At the same time this function adds to some IDLE time which portion + * cannot be used for other purposes (yet). + **/ + +void up_waste(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_WASTE_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_wdg.h b/arch/arm/src/stm32l4/stm32l4_wdg.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_dma.c b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..2e6afa2b3b606aab48a82b07ae1fdda3bf0c28f7 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c @@ -0,0 +1,758 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4x6xx_dma.c + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" +#include "stm32l4_dma.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NCHANNELS 7 +#if STM32L4_NDMA > 1 +# define DMA2_NCHANNELS 7 +# define DMA_NCHANNELS (DMA1_NCHANNELS+DMA2_NCHANNELS) +#else +# define DMA_NCHANNELS DMA1_NCHANNELS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA channel base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes one DMA channel */ + +struct stm32l4_dma_s +{ + uint8_t chan; /* DMA channel number (0-6) */ + uint8_t function; /* DMA peripheral connected to this channel (0-7) */ + uint8_t irq; /* DMA channel IRQ number */ + sem_t sem; /* Used to wait for DMA channel to become available */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32l4_dma_s g_dma[DMA_NCHANNELS] = +{ + { + .chan = 0, + .irq = STM32L4_IRQ_DMA1CH1, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32L4_IRQ_DMA1CH2, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32L4_IRQ_DMA1CH3, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(2), + }, + { + .chan = 3, + .irq = STM32L4_IRQ_DMA1CH4, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(3), + }, + { + .chan = 4, + .irq = STM32L4_IRQ_DMA1CH5, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(4), + }, + { + .chan = 5, + .irq = STM32L4_IRQ_DMA1CH6, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(5), + }, + { + .chan = 6, + .irq = STM32L4_IRQ_DMA1CH7, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(6), + }, +#if STM32L4_NDMA > 1 + { + .chan = 0, + .irq = STM32L4_IRQ_DMA2CH1, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32L4_IRQ_DMA2CH2, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32L4_IRQ_DMA2CH3, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(2), + }, + { + .chan = 3, + .irq = STM32L4_IRQ_DMA2CH4, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(3), + }, + { + .chan = 4, + .irq = STM32L4_IRQ_DMA2CH5, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(4), + }, + { + .chan = 5, + .irq = STM32L4_IRQ_DMA2CH6, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(5), + }, + { + .chan = 6, + .irq = STM32L4_IRQ_DMA2CH7, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(6), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32l4_dma_s *dmach, uint32_t offset) +{ + return getreg32(DMA_BASE(dmach->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32l4_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmach->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmachan_getreg(struct stm32l4_dma_s *dmach, uint32_t offset) +{ + return getreg32(dmach->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmachan_putreg(struct stm32l4_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, dmach->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_dmatake() and stm32l4_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32l4_dmatake(FAR struct stm32l4_dma_s *dmach) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmach->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32l4_dmagive(FAR struct stm32l4_dma_s *dmach) +{ + (void)sem_post(&dmach->sem); +} + +/************************************************************************************ + * Name: stm32l4_dmachandisable + * + * Description: + * Disable the DMA channel + * + ************************************************************************************/ + +static void stm32l4_dmachandisable(struct stm32l4_dma_s *dmach) +{ + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~DMA_CCR_ALLINTS; + + /* Disable the DMA channel */ + + regval &= ~DMA_CCR_EN; + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + + /* Clear pending channel interrupts */ + + dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, DMA_ISR_CHAN_MASK(dmach->chan)); +} + +/************************************************************************************ + * Name: stm32l4_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32l4_dmainterrupt(int irq, void *context) +{ + struct stm32l4_dma_s *dmach; + uint32_t isr; + int chndx = 0; + + /* Get the channel structure from the interrupt number */ + + if (irq >= STM32L4_IRQ_DMA1CH1 && irq <= STM32L4_IRQ_DMA1CH7) + { + chndx = irq - STM32L4_IRQ_DMA1CH1; + } + else +#if STM32L4_NDMA > 1 + if (irq >= STM32L4_IRQ_DMA2CH1 && irq <= STM32L4_IRQ_DMA2CH5) + { + chndx = irq - STM32L4_IRQ_DMA2CH1 + DMA1_NCHANNELS; + } + else if (irq >= STM32L4_IRQ_DMA2CH6 && irq <= STM32L4_IRQ_DMA2CH7) + { + chndx = irq - STM32L4_IRQ_DMA2CH6 + DMA1_NCHANNELS + 5; + } +#endif + else + { + PANIC(); + } + dmach = &g_dma[chndx]; + + /* Get the interrupt status (for this channel only) */ + + isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan); + + /* Clear the interrupts we are handling */ + + dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, isr); + + /* Invoke the callback */ + + if (dmach->callback) + { + dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(dmach->chan), dmach->arg); + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32l4_dma_s *dmach; + int chndx; + + /* Initialize each DMA channel */ + + for (chndx = 0; chndx < DMA_NCHANNELS; chndx++) + { + dmach = &g_dma[chndx]; + sem_init(&dmach->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmach->irq, stm32l4_dmainterrupt); + + /* Disable the DMA channel */ + + stm32l4_dmachandisable(dmach); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmach->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmach->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32l4_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chndx' argument. + * DMA channels are shared on the STM32L4: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32l4_dma.h. + * + * If the DMA channel is not available, then stm32l4_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32l4_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32l4_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chndx - Identifies the stream/channel resource. For the STM32 F1, this + * is simply the channel number as provided by the DMACHAN_* definitions + * in chip/stm32f10xxx_dma.h. + * + * Returned Value: + * Provided that 'chndx' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chndx' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32l4_dmachannel(unsigned int chndef) +{ + int chndx = (chndef & DMACHAN_SETTING_CHANNEL_MASK) >> DMACHAN_SETTING_CHANNEL_SHIFT; + + struct stm32l4_dma_s *dmach = &g_dma[chndx]; + + DEBUGASSERT(chndx < DMA_NCHANNELS); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32l4_dmatake(dmach); + + /* The caller now has exclusive use of the DMA channel */ + + /* Define the peripheral that will use the channel. This is stored until + * dmasetup is called. + */ + dmach->function = (chndef & DMACHAN_SETTING_FUNCTION_MASK) >> DMACHAN_SETTING_FUNCTION_SHIFT; + + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: stm32l4_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32l4_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32l4_dmachannel() is + * called again to re-gain access to the channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmafree(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32l4_dmagive(dmach); +} + +/**************************************************************************** + * Name: stm32l4_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t regval; + + /* Then DMA_CNDTRx register can only be modified if the DMA channel is + * disabled. + */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_EN); + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + + /* Set the peripheral register address in the DMA_CPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CPAR_OFFSET, paddr); + + /* Set the memory address in the DMA_CMARx register. The data will be + * written to or read from this memory after the peripheral event. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CMAR_OFFSET, maddr); + + /* Configure the total number of data to be transferred in the DMA_CNDTRx + * register. After each peripheral event, this value will be decremented. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET, ntransfers); + + /* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx + * register. Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register. + */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + ccr &= (DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + regval |= ccr; + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + +#warning TODO define peripheral by using dmach->function +} + +/**************************************************************************** + * Name: stm32l4_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmastart(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t ccr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked when the DMA commpletes */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Activate the channel by setting the ENABLE bit in the DMA_CCRx register. + * As soon as the channel is enabled, it can serve any DMA request from the + * peripheral connected on the channel. + */ + + ccr = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + ccr |= DMA_CCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular mode, + * always interrupt on buffer wrap, and optionally interrupt at the halfway point. + */ + + if ((ccr & DMA_CCR_CIRC) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + ccr |= (half ? (DMA_CCR_HTIE | DMA_CCR_TEIE) : (DMA_CCR_TCIE | DMA_CCR_TEIE)); + } + else + { + /* In nonstop mode, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE; + } + + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, ccr); +} + +/**************************************************************************** + * Name: stm32l4_dmastop + * + * Description: + * Cancel the DMA. After stm32l4_dmastop() is called, the DMA channel is + * reset and stm32l4_dmasetup() must be called before stm32l4_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +void stm32l4_dmastop(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + stm32l4_dmachandisable(dmach); +} + +/**************************************************************************** + * Name: stm32l4_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +size_t stm32l4_dmaresidual(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + + return dmachan_getreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET); +} + +/**************************************************************************** + * Name: stm32l4_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_DMACAPABLE +bool stm32l4_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size; + uint32_t mend; + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_CCR_MSIZE_MASK) + { + case DMA_CCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_CCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_CCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default: + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + return false; + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32L4_REGION_MASK) != (mend & STM32L4_REGION_MASK)) + { + return false; + } + + switch (maddr & STM32L4_REGION_MASK) + { +#if defined(CONFIG_STM32L4_STM32F10XX) + case STM32L4_FSMC_BANK1: + case STM32L4_FSMC_BANK2: + case STM32L4_FSMC_BANK3: + case STM32L4_FSMC_BANK4: +#endif + case STM32L4_SRAM_BASE: + case STM32L4_CODE_BASE: + /* All RAM and flash is supported */ + + return true; + + default: + /* Everything else is unsupported by DMA */ + + return false; + } +} +#endif + +/**************************************************************************** + * Name: stm32l4_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmasample(DMA_HANDLE handle, struct stm32l4_dmaregs_s *regs) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + irqstate_t flags; + + flags = irqsave(); + regs->isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET); + regs->ccr = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regs->cndtr = dmachan_getreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET); + regs->cpar = dmachan_getreg(dmach, STM32L4_DMACHAN_CPAR_OFFSET); + regs->cmar = dmachan_getreg(dmach, STM32L4_DMACHAN_CMAR_OFFSET); + irqrestore(flags); +} +#endif + +/**************************************************************************** + * Name: stm32l4_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmadump(DMA_HANDLE handle, const struct stm32l4_dmaregs_s *regs, + const char *msg) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmach->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" ISRC[%08x]: %08x\n", dmabase + STM32L4_DMA_ISR_OFFSET, regs->isr); + dmadbg(" CCR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CCR_OFFSET, regs->ccr); + dmadbg(" CNDTR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CNDTR_OFFSET, regs->cndtr); + dmadbg(" CPAR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CPAR_OFFSET, regs->cpar); + dmadbg(" CMAR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CMAR_OFFSET, regs->cmar); +} +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c new file mode 100644 index 0000000000000000000000000000000000000000..8e4cbe624cf0d56ad1347a02df6ddce923a6c99e --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c @@ -0,0 +1,871 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4x6xx_rcc.c + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Sebastien Lorquet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "stm32l4_pwr.h" +#include "stm32l4_flash.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/* Same for HSI */ + +#define HSIRDY_TIMEOUT HSERDY_TIMEOUT + +/* HSE divisor to yield ~1MHz RTC clock */ + +#define HSE_DIVISOR (STM32L4_HSE_FREQUENCY + 500000) / 1000000 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Reset the RCC clock configuration to the default reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Enable the Internal High Speed clock (HSI) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSION; + putreg32(regval, STM32L4_RCC_CR); + + /* Reset CFGR register */ + + putreg32(0x00000000, STM32L4_RCC_CFGR); + + /* Reset HSION, HSEON, CSSON and PLLON bits */ + + regval = getreg32(STM32L4_RCC_CR); + regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32L4_RCC_CR); + + /* Reset PLLCFGR register to reset default */ + + putreg32(RCC_PLLCFG_RESET, STM32L4_RCC_PLLCFG); + + /* Reset HSEBYP bit */ + + regval = getreg32(STM32L4_RCC_CR); + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32L4_RCC_CR); + + /* Disable all interrupts */ + + putreg32(0x00000000, STM32L4_RCC_CIER); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB1ENR); + +#ifdef CONFIG_STM32L4_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHB1ENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32L4_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHB1ENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32L4_CRC + /* CRC clock enable */ + + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32L4_TSC + /* TSC clock enable */ + + regval |= RCC_AHB1ENR_TSCEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR register to enabled the + * selected AHB2 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB2ENR); + + /* Enable GPIOA, GPIOB, .... GPIOI */ + +#if STM32L4_NPORTS > 0 + regval |= (RCC_AHB2ENR_GPIOAEN +#if STM32L4_NPORTS > 1 + | RCC_AHB2ENR_GPIOBEN +#endif +#if STM32L4_NPORTS > 2 + | RCC_AHB2ENR_GPIOCEN +#endif +#if STM32L4_NPORTS > 3 + | RCC_AHB2ENR_GPIODEN +#endif +#if STM32L4_NPORTS > 4 + | RCC_AHB2ENR_GPIOEEN +#endif +#if STM32L4_NPORTS > 5 + | RCC_AHB2ENR_GPIOFEN +#endif +#if STM32L4_NPORTS > 6 + | RCC_AHB2ENR_GPIOGEN +#endif +#if STM32L4_NPORTS > 7 + | RCC_AHB2ENR_GPIOHEN +#endif + ); +#endif + +#ifdef CONFIG_STM32L4_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHB2ENR_OTGFSEN; +#endif + +#if defined(CONFIG_STM32L4_ADC1) || defined(CONFIG_STM32L4_ADC2) || defined(CONFIG_STM32L4_ADC3) + /* ADC clock enable */ + + regval |= RCC_AHB2ENR_ADCEN; +#endif + +#ifdef CONFIG_STM32L4_AES + /* Cryptographic modules clock enable */ + + regval |= RCC_AHB2ENR_AESEN; +#endif + +#ifdef CONFIG_STM32L4_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHB2ENR_RNGEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the + * selected AHB3 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB3ENR); + +#ifdef CONFIG_STM32L4_FSMC + /* Flexible static memory controller module clock enable */ + + regval |= RCC_AHB3ENR_FMCEN; +#endif + + +#ifdef CONFIG_STM32L4_QUADSPI + /* QuadSPI module clock enable */ + + regval |= RCC_AHB3ENR_QSPIEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB3ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32L4_RCC_APB1ENR1); + +#ifdef CONFIG_STM32L4_TIM2 + /* TIM2 clock enable */ + + regval |= RCC_APB1ENR1_TIM2EN; +#endif + +#ifdef CONFIG_STM32L4_TIM3 + /* TIM3 clock enable */ + + regval |= RCC_APB1ENR1_TIM3EN; +#endif + +#ifdef CONFIG_STM32L4_TIM4 + /* TIM4 clock enable */ + + regval |= RCC_APB1ENR1_TIM4EN; +#endif + +#ifdef CONFIG_STM32L4_TIM5 + /* TIM5 clock enable */ + + regval |= RCC_APB1ENR1_TIM5EN; +#endif + +#ifdef CONFIG_STM32L4_TIM6 + /* TIM6 clock enable */ + + regval |= RCC_APB1ENR1_TIM6EN; +#endif + +#ifdef CONFIG_STM32L4_TIM7 + /* TIM7 clock enable */ + + regval |= RCC_APB1ENR1_TIM7EN; +#endif + +#ifdef CONFIG_STM32L4_LCD + /* LCD clock enable */ + + regval |= RCC_APB1ENR1_LCDEN; +#endif + +#ifdef CONFIG_STM32L4_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB1ENR1_SPI2EN; +#endif + +#ifdef CONFIG_STM32L4_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1ENR1_SPI3EN; +#endif + +#ifdef CONFIG_STM32L4_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR1_USART2EN; +#endif + +#ifdef CONFIG_STM32L4_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1ENR1_USART3EN; +#endif + +#ifdef CONFIG_STM32L4_UART4 + /* UART4 clock enable */ + + regval |= RCC_APB1ENR1_UART4EN; +#endif + +#ifdef CONFIG_STM32L4_UART5 + /* UART5 clock enable */ + + regval |= RCC_APB1ENR1_UART5EN; +#endif + +#ifdef CONFIG_STM32L4_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1ENR1_I2C1EN; +#endif + +#ifdef CONFIG_STM32L4_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1ENR1_I2C2EN; +#endif + +#ifdef CONFIG_STM32L4_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1ENR1_I2C3EN; +#endif + +#ifdef CONFIG_STM32L4_CAN1 + /* CAN 1 clock enable */ + + regval |= RCC_APB1ENR1_CAN1EN; +#endif + + /* Power interface clock enable. The PWR block is always enabled so that + * we can set the internal voltage regulator as required. + */ + + regval |= RCC_APB1ENR1_PWREN; + +#if defined (CONFIG_STM32L4_DAC1) || defined(CONFIG_STM32L4_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR1_DACEN; +#endif + +#ifdef CONFIG_STM32L4_OPAMP + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR1_OPAMPEN; +#endif + + putreg32(regval, STM32L4_RCC_APB1ENR1); /* Enable peripherals */ + + /* Second APB1 register */ + + regval = getreg32(STM32L4_RCC_APB1ENR2); + +#ifdef CONFIG_STM32L4_LPTIM1 + /* Low power timer 1 clock enable */ + + regval |= RCC_APB1ENR2_LPTIM1EN; +#endif + +#ifdef CONFIG_STM32L4_LPUART1 + /* Low power uart clock enable */ + + regval |= RCC_APB1ENR2_LPUART1EN; +#endif + +#ifdef CONFIG_STM32L4_SWPMI + /* Single-wire protocol master clock enable */ + + regval |= RCC_APB1ENR2_SWPMI1EN; +#endif + +#ifdef CONFIG_STM32L4_LPTIM2 + /* Low power timer 2 clock enable */ + + regval |= RCC_APB1ENR2_LPTIM2EN; +#endif + + putreg32(regval, STM32L4_RCC_APB1ENR2); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32L4_RCC_APB2ENR); + +#ifdef CONFIG_STM32L4_SYSCFG + /* System configuration controller clock enable */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32L4_FIREWALL + /* Firewall clock enable */ + + regval |= RCC_APB2ENR_FWEN; +#endif + +#ifdef CONFIG_STM32L4_SDMMC + /* SDMMC clock enable */ + + regval |= RCC_APB2ENR_SDMMCEN; +#endif + +#ifdef CONFIG_STM32L4_TIM1 + /* TIM1 clock enable */ + + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32L4_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32L4_TIM8 + /* TIM8 clock enable */ + + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32L4_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32L4_TIM15 + /* TIM15 clock enable */ + + regval |= RCC_APB2ENR_TIM15EN; +#endif + +#ifdef CONFIG_STM32L4_TIM16 + /* TIM16 clock enable */ + + regval |= RCC_APB2ENR_TIM16EN; +#endif + +#ifdef CONFIG_STM32L4_TIM17 + /* TIM17 clock enable */ + + regval |= RCC_APB2ENR_TIM17EN; +#endif + +#ifdef CONFIG_STM32L4_SAI1 + /* SAI1 clock enable */ + + regval |= RCC_APB2ENR_SAI1EN; +#endif + +#ifdef CONFIG_STM32L4_SAI2 + /* SAI2 clock enable */ + + regval |= RCC_APB2ENR_SAI2EN; +#endif + +#ifdef CONFIG_STM32L4_DFSDM + /* DFSDM clock enable */ + + regval |= RCC_APB2ENR_DFSDMEN; +#endif + + putreg32(regval, STM32L4_RCC_APB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: stm32l4_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG +static void stm32l4_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + +#ifdef STM32L4_BOARD_USEHSI + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSION; /* Enable HSI */ + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDY flag is the set in the CR */ + + if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#elif defined(STM32L4_BOARD_USEMSI) + /* Enable Internal Multi-Speed Clock (MSI) */ + +# error STM32L4_BOARD_USEMSI not yet implemented in arch/arm/src/stm32l4/stm32l4x6xx_rcc.c + /* setting MSIRANGE */ + /* setting MSIPLLEN */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_MSION; /* Enable MSI */ + putreg32(regval, STM32L4_RCC_CR); + +#elif defined(STM32L4_BOARD_USEHSE) + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#else + +# error stm32l4_stdclockconfig(), must have one of STM32L4_BOARD_USEHSI, STM32L4_BOARD_USEMSI, STM32L4_BOARD_USEHSE defined + +#endif + + /* Check for a timeout. If this timeout occurs, then we are hosed. We + * have no real back-up plan, although the following logic makes it look + * as though we do. + */ + + if (timeout > 0) + { +#warning todo: regulator voltage according to clock freq +#if 0 + /* Ensure Power control is enabled before modifying it. */ + + regval = getreg32(STM32L4_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32L4_RCC_APB1ENR); + + /* Select regulator voltage output Scale 1 mode to support system + * frequencies up to 168 MHz. + */ + + regval = getreg32(STM32L4_PWR_CR); + regval &= ~PWR_CR_VOS_MASK; + regval |= PWR_CR_VOS_SCALE_1; + putreg32(regval, STM32L4_PWR_CR); +#endif + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32L4_RCC_CFGR_HPRE; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32L4_RCC_CFGR_PPRE2; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32L4_RCC_CFGR_PPRE1; + putreg32(regval, STM32L4_RCC_CFGR); + +#ifdef CONFIG_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32L4_RCC_CFGR); +#endif + + /* Set the PLL source and main divider */ + + regval = getreg32(STM32L4_RCC_PLLCFG); + + /* Configure Main PLL */ + + /* Set the PLL dividers and multipliers to configure the main PLL */ + + regval = (STM32L4_PLLCFG_PLLM | STM32L4_PLLCFG_PLLN | STM32L4_PLLCFG_PLLP + | STM32L4_PLLCFG_PLLQ | STM32L4_PLLCFG_PLLR); + +#ifdef STM32L4_PLLCFG_PLLP_ENABLED + regval |= RCC_PLLCFG_PLLPEN; +#endif +#ifdef STM32L4_PLLCFG_PLLQ_ENABLED + regval |= RCC_PLLCFG_PLLQEN; +#endif +#ifdef STM32L4_PLLCFG_PLLR_ENABLED + regval |= RCC_PLLCFG_PLLREN; +#endif + + /* XXX The choice of clock source to PLL (all three) is independent + * of the sys clock source choice, review the STM32L4_BOARD_USEHSI + * name; probably split it into two, one for PLL source and one + * for sys clock source. + */ + +#ifdef STM32L4_BOARD_USEHSI + regval |= RCC_PLLCFG_PLLSRC_HSI; +#else /* if STM32L4_BOARD_USEHSE */ + regval |= RCC_PLLCFG_PLLSRC_HSE; +#endif + + putreg32(regval, STM32L4_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLRDY) == 0) + { + } + +#ifdef CONFIG_STM32L4_SAI1PLL + /* Configure SAI1 PLL */ + + regval = getreg32(STM32L4_RCC_PLLSAI1CFG); + + /* Set the PLL dividers and multipliers to configure the SAI1 PLL */ + + regval = (STM32L4_PLLSAI1CFG_PLLN | STM32L4_PLLSAI1CFG_PLLP + | STM32L4_PLLSAI1CFG_PLLQ | STM32L4_PLLSAI1CFG_PLLR); + +#ifdef STM32L4_PLLSAI1CFG_PLLP_ENABLED + regval |= RCC_PLLSAI1CFG_PLLPEN; +#endif +#ifdef STM32L4_PLLSAI1CFG_PLLQ_ENABLED + regval |= RCC_PLLSAI1CFG_PLLQEN; +#endif +#ifdef STM32L4_PLLSAI1CFG_PLLR_ENABLED + regval |= RCC_PLLSAI1CFG_PLLREN; +#endif + + putreg32(regval, STM32L4_RCC_PLLSAI1CFG); + + /* Enable the SAI1 PLL */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_PLLSAI1ON; + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLSAI1RDY) == 0) + { + } +#endif + +#ifdef CONFIG_STM32L4_SAI2PLL + /* Configure SAI2 PLL */ + + regval = getreg32(STM32L4_RCC_PLLSAI2CFG); + + /* Enable the SAI2 PLL */ + /* Set the PLL dividers and multipliers to configure the SAI2 PLL */ + + regval = (STM32L4_PLLSAI2CFG_PLLN | STM32L4_PLLSAI2CFG_PLLP | + STM32L4_PLLSAI2CFG_PLLR); + +#ifdef STM32L4_PLLSAI2CFG_PLLP_ENABLED + regval |= RCC_PLLSAI2CFG_PLLPEN; +#endif +#ifdef STM32L4_PLLSAI2CFG_PLLR_ENABLED + regval |= RCC_PLLSAI2CFG_PLLREN; +#endif + + putreg32(regval, STM32L4_RCC_PLLSAI2CFG); + + /* Enable the SAI1 PLL */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_PLLSAI2ON; + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLSAI2RDY) == 0) + { + } +#endif + + /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */ + +#ifdef CONFIG_STM32L4_FLASH_PREFETCH + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN); +#else + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); +#endif + putreg32(regval, STM32L4_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32L4_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) + { + } + +#if defined(CONFIG_STM32L4_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32l4_rcc_enablelsi(); +#endif + +#if defined(STM32L4_USE_LSE) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + * XXX and other cases, like automatic trimming of MSI for USB use + */ + + /* ensure Power control is enabled since it is indirectly required + * to alter the LSE parameters. + */ + stm32l4_pwr_enableclk(true); + + /* XXX other LSE settings must be made before turning on the oscillator + * and we need to ensure it is first off before doing so. + */ + + /* turn on the LSE oscillator + * XXX this will almost surely get moved since we also want to use + * this for automatically trimming MSI, etc. + */ + + stm32l4_rcc_enablelse(); +#endif + +#if defined(STM32L4_USE_CLK48) + /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source + * and then we can also do away with STM32L4_USE_CLK48, and give better + * warning messages + * + * XXX sanity if our STM32L4_CLK48_SEL is YYY then we need to have already + * enabled ZZZ + */ + + regval = getreg32(STM32L4_RCC_CCIPR); + regval &= RCC_CCIPR_CLK48SEL_MASK; + regval |= STM32L4_CLK48_SEL; + putreg32(regval, STM32L4_RCC_CCIPR); +#endif + } +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/str71x/Kconfig b/arch/arm/src/str71x/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2b8bc7278ffce228c6991a4c05aef5ad3234620f --- /dev/null +++ b/arch/arm/src/str71x/Kconfig @@ -0,0 +1,210 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "STR71x Configuration Options" + +menu "STR71x Peripheral Selections" + +config STR71X_ADC12 + bool "ADC12" + default n + select ADC + +config STR71X_BSPI0 + bool "BSPI0" + default n + select STR71X_GPIO0 + select SPI + +config STR71X_BSPI1 + bool "BSPI1" + default n + select STR71X_GPIO0 + select SPI + +config STR71X_CAN + bool "CAN" + default n + select CAN + +config STR71X_CKOUT + bool "CKOUT" + default n + +config STR71X_GPIO0 + bool "GPIO0" + default y + +config STR71X_GPIO1 + bool "GPIO1" + default n + +config STR71X_GPIO2 + bool "GPIO2" + default n + +config STR71X_HDLC + bool "HDLC" + default n + +config STR71X_I2C0 + bool "I2C0" + default n + select I2C + +config STR71X_I2C1 + bool "I2C1" + default n + select I2C + +config STR71X_RTC + bool "RTC" + default n + select RTC + +config STR71X_TIM1 + bool "TIM1" + default n + +config STR71X_TIM2 + bool "TIM2" + default n + +config STR71X_TIM3 + bool "TIM3" + default n + +config STR71X_UART0 + bool "UART0" + default n + select STR71X_GPIO0 + select ARCH_HAVE_UART0 + +config STR71X_UART1 + bool "UART1" + default n + select STR71X_GPIO0 + select ARCH_HAVE_UART1 + +config STR71X_UART2 + bool "UART2" + default n + select STR71X_GPIO0 + select ARCH_HAVE_UART2 + +config STR71X_UART3 + bool "UART3" + default n + select STR71X_GPIO0 + select ARCH_HAVE_UART3 + +config STR71X_USB + bool "USB" + default n + select USBDEV + +config STR71X_XTI + bool "XTI" + +endmenu #STR71x Peripheral Selections + +config STR71X_DISABLE_PERIPHINIT + bool "Disable peripheral interrupts" + default n + +menu "STR71x EMI Configuration" + +config STR71X_BANK0 + bool "Bank 0" + default n + select STR71X_HAVE_EXTMEM + +if STR71X_BANK0 + +config STR71X_BANK0_SIZE + int "Bank 0 size" + default 16 + ---help--- + The only valid options are 8 and 16 + +config STR71X_BANK0_WAITSTATES + int "Bank 0 wait states" + default 0 + range 0 15 + +endif # STR71X_BANK0 + +config STR71X_BANK1 + bool "Bank 1" + default n + select STR71X_HAVE_EXTMEM + +if STR71X_BANK1 + +config STR71X_BANK1_SIZE + int "Bank 1 size" + default 16 + ---help--- + The only valid options are 8 and 16 + +config STR71X_BANK1_WAITSTATES + int "Bank 1 wait states" + default 0 + range 0 15 + +endif # STR71X_BANK1 + +config STR71X_BANK2 + bool "Bank 2" + default n + select STR71X_HAVE_EXTMEM + +if STR71X_BANK2 + +config STR71X_BANK2_SIZE + int "Bank 2 size" + default 16 + ---help--- + The only valid options are 8 and 16 + +config STR71X_BANK2_WAITSTATES + int "Bank 2 wait states" + default 0 + range 0 15 + +endif # STR71X_BANK2 + +config STR71X_BANK3 + bool "Bank 3" + default n + select STR71X_HAVE_EXTMEM + +if STR71X_BANK3 + +config STR71X_BANK3_SIZE + int "Bank 3 size" + default 16 + ---help--- + The only valid options are 8 and 16 + +config STR71X_BANK3_WAITSTATES + int "Bank 3 wait states" + default 0 + range 0 15 + +endif # STR71X_BANK3 + +config STR71X_HAVE_EXTMEM + bool + default n + +config STR71X_BIGEXTMEM + bool "Big external memory" + default n + depends on STR71X_HAVE_EXTMEM + ---help--- + Needed if the address space is > 1MB + +endmenu # STR71x EMI Configuration diff --git a/arch/arm/src/str71x/Make.defs b/arch/arm/src/str71x/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..00db6c3b8f040171a9eeb4e3d377ecaeef015d32 --- /dev/null +++ b/arch/arm/src/str71x/Make.defs @@ -0,0 +1,78 @@ +############################################################################## +# arch/arm/src/str71x/Make.defs +# +# Copyright (C) 2008, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +HEAD_ASRC = str71x_head.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S +CMN_ASRCS += vfork.S + +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c +CMN_CSRCS += up_exit.c up_idle.c up_initialize.c up_initialstate.c +CMN_CSRCS += up_interruptcontext.c up_prefetchabort.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_stackframe.c +CMN_CSRCS += up_syscall.c up_unblocktask.c up_undefinedinsn.c up_usestack.c +CMN_CSRCS += up_lowputs.c up_vfork.c + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = str71x_prccu.c str71x_lowputc.c str71x_decodeirq.c str71x_irq.c +CHIP_CSRCS += str71x_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += str71x_timerisr.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS+= str71x_usbdev.c +endif + +ifeq ($(CONFIG_STR71X_XTI),y) +CHIP_CSRCS+= str71x_xti.c +endif + diff --git a/arch/arm/src/str71x/chip.h b/arch/arm/src/str71x/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..af1da9ea861790d2a509a23fec879b1fdabf9b49 --- /dev/null +++ b/arch/arm/src/str71x/chip.h @@ -0,0 +1,80 @@ +/************************************************************************************ + * arch/arm/src/str71x/chip.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_CHIP_H +#define __ARCH_ARM_SRC_STR71X_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" /* Memory map */ +#include "str71x_emi.h" /* External memory interface */ +#include "str71x_rccu.h" /* Reset and clock control unit */ +#include "str71x_pcu.h" /* Power control unit */ +#include "str71x_gpio.h" /* I/O ports */ +#include "str71x_eic.h" /* Enhanced interrupt controller */ +#include "str71x_xti.h" /* External interrupts (XTI) */ +#include "str71x_rtc.h" /* Real Time Clock (RTC) */ +#include "str71x_wdog.h" /* Watchdog timer */ +#include "str71x_timer.h" /* Timers */ +#include "str71x_can.h" /* Controller Area Network (CAN) */ +#include "str71x_i2c.h" /* I2C */ +#include "str71x_bspi.h" /* Buffered SPI (BSPI) */ +#include "str71x_uart.h" /* UART */ +#include "str71x_usb.h" /* USB */ +#include "str71x_adc12.h" /* ADC */ +#include "str71x_apb.h" /* USB */ +#include "str71x_flash.h" /* Flash */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_CHIP_H */ diff --git a/arch/arm/src/str71x/str71x.h b/arch/arm/src/str71x/str71x.h new file mode 100644 index 0000000000000000000000000000000000000000..7b3bedf1df34e28e851cdd6044d976859cf4d7af --- /dev/null +++ b/arch/arm/src/str71x/str71x.h @@ -0,0 +1,175 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x.h + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_H +#define __ARCH_ARM_SRC_STR71X_STR71X_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Calculate the values of PCLK1 and PCLK2 from settings in board.h. + * + * Example: + * STR71X_RCCU_MAIN_OSC = 4MHz (not divided by 2) + * STR71X_CLK2 = 4MHz + * STR71X_PLL1OUT = 16 * STR71X_CLK2 / 2 = 32MHz + * CLK3 = 32MHz + * RCLK = 32MHz + * PCLK1 = 32MHz / 1 = 32MHz + */ + +/* PLL1OUT derives from Main OSC->CLK2 */ + +#ifdef STR71X_PLL1IN_DIV2 /* CLK2 is input to PLL1 */ +# define STR71X_CLK2 (STR71X_RCCU_MAIN_OSC/2) /* CLK2 is OSC/2 */ +#else +# define STR71X_CLK2 STR71X_RCCU_MAIN_OSC /* CLK2 is OSC */ +#endif + +#define STR71X_PLL1OUT ((STR71X_PLL1OUT_MUL * STR71X_CLK2) / STR71X_PLL1OUT_DIV) + +/* PLL2 OUT derives from HCLK */ + +#define STR71X_PLL2OUT ((STR71X_PLL2OUT_MUL * STR71X_HCLK) / STR71X_PLL2OUT_DIV) + +/* Peripheral clocks derive from PLL1OUT->CLK3->RCLK->PCLK1/2 */ + +#define STR71X_CLK3 STR71X_PLL1OUT /* CLK3 hard coded to be PLL1OUT */ +#define STR71X_RCLK STR71X_CLK3 /* RCLK hard coded to be CLK3 */ +#define STR71X_PCLK1 (STR71X_RCLK / STR71X_APB1_DIV) /* PCLK1 derives from RCLK */ +#define STR71X_PCLK2 (STR71X_RCLK / STR71X_APB2_DIV) /* PCLK2 derives from RCLK */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/******************************************************************************** + * Name: str7x_xtiinitialize + * + * Description: + * Configure XTI for operation. Note that the lines are not used as wake-up + * sources in this implementation. Some extensions would be required for that + * capability. + * + ********************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +int str71x_xtiinitialize(void); +#else +# define str71x_xtiinitialize() +#endif /* CONFIG_STR71X_XTI */ + +/******************************************************************************** + * Name: str7x_xticonfig + * + * Description: + * Configure an external line to provide interrupts. Interrupt is configured, + * but disabled on return. + * + ********************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +int str71x_xticonfig(int irq, bool rising); +#else +# define str71x_xticonfig(irq,rising) +#endif /* CONFIG_STR71X_XTI */ + +/**************************************************************************** + * Name: str71x_enable_xtiirq + * + * Description: + * Enable an external interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +void str71x_enable_xtiirq(int irq); +#else +# define str71x_enable_xtiirq(irq) +#endif /* CONFIG_STR71X_XTI */ + +/**************************************************************************** + * Name: str71x_disable_xtiirq + * + * Description: + * Disable an external interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_STR71X_XTI +void str71x_disable_xtiirq(int irq); +#else +# define str71x_disable_xtiirq(irq) +#endif /* CONFIG_STR71X_XTI */ + +struct spi_dev_s; /* Forward reference */ + +/**************************************************************************** + * Name: str71_spibus_initialize + * + * Description: + * Initialize the selected SPI port. This function could get called + * multiple times for each STR7 devices that needs an SPI reference. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *str71_spibus_initialize(int port); + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_H */ diff --git a/arch/arm/src/str71x/str71x_adc12.h b/arch/arm/src/str71x/str71x_adc12.h new file mode 100644 index 0000000000000000000000000000000000000000..ec8631252bc99c70987838b414478035b95ac8d8 --- /dev/null +++ b/arch/arm/src/str71x/str71x_adc12.h @@ -0,0 +1,109 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_adc12.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_ADC12_H +#define __ARCH_ARM_SRC_STR71X_STR71X_ADC12_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* ADC12 registers ******************************************************************/ + +#define STR71X_ADC12_DATA0 (STR71X_ADC12_BASE + 0x0000) /* 16-bits wide */ +#define STR71X_ADC12_DATA1 (STR71X_ADC12_BASE + 0x0008) /* 16-bits wide */ +#define STR71X_ADC12_DATA2 (STR71X_ADC12_BASE + 0x0010) /* 16-bits wide */ +#define STR71X_ADC12_DATA3 (STR71X_ADC12_BASE + 0x0018) /* 16-bits wide */ +#define STR71X_ADC12_CSR (STR71X_ADC12_BASE + 0x0020) /* 16-bits wide */ +#define STR71X_ADC12_CPR (STR71X_ADC12_BASE + 0x0030) /* 16-bits wide */ + +/* Register bit settings ************************************************************/ +/* ADC12 Conversion modes */ + +#define STR71X_ADC12_SINGLE (0) +#define STR71X_ADC12_ROUND (1) + +/* ADC12 Channels */ + +#define STR71X_ADC12_CHANNEL0 (0x00) +#define STR71X_ADC12_CHANNEL1 (0x10) +#define STR71X_ADC12_CHANNEL2 (0x20) +#define STR71X_ADC12_CHANNEL3 (0x30) + +/* ADC12 control status register */ + +#define STR71X_ADC12_DA0 (0x0001) +#define STR71X_ADC12_DA1 (0x0002) +#define STR71X_ADC12_DA2 (0x0004) +#define STR71X_ADC12_DA3 (0x0008) +#define STR71X_ADC12_OR (0x2000) + +/* Interrupt bits for channel n */ + +#define STR71X_ADC12_IT0 (0x0100) +#define STR71X_ADC12_IT1 (0x0200) +#define STR71X_ADC12_IT2 (0x0400) +#define STR71X_ADC12_IT3 (0x0800) +#define STR71X_ADC12_ITALL (0x0f00) + +/* Mode selection */ + +#define STR71X_ADC12_MODE (0x0040) + +/* Converter configuration */ + +#define STR71X_ADC12_START (0x0020) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_ADC12_H */ diff --git a/arch/arm/src/str71x/str71x_apb.h b/arch/arm/src/str71x/str71x_apb.h new file mode 100644 index 0000000000000000000000000000000000000000..e12c46a62a14a437c504db68500d947e2be3dac5 --- /dev/null +++ b/arch/arm/src/str71x/str71x_apb.h @@ -0,0 +1,109 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_apb.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_APB_H +#define __ARCH_ARM_SRC_STR71X_STR71X_APB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* APB register offsets *************************************************************/ + +#define STR71X_APB_CKDIS_OFFSET (0x0010) /* 32-bits wide */ +#define STR71X_APB_SWRES_OFFSET (0x0014) /* 32-bits wide */ + +/* APB register addresses ***********************************************************/ + +#define STR71X_APB1_CKDIS (STR71X_APB1_BASE + STR71X_APB_CKDIS_OFFSET) +#define STR71X_APB1_SWRES (STR71X_APB1_BASE + STR71X_APB_SWRES_OFFSET) + +#define STR71X_APB2_CKDIS (STR71X_APB2_BASE + STR71X_APB_CKDIS_OFFSET) +#define STR71X_APB2_SWRES (STR71X_APB2_BASE + STR71X_APB_SWRES_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* APB1 periperals */ + +#define STR71X_APB1_I2C0 (0x0001) /* Bit 0: I2C0 */ +#define STR71X_APB1_I2C1 (0x0002) /* Bit 1: I2C1 */ +#define STR71X_APB1_UART0 (0x0008) /* Bit 3: UART0 */ +#define STR71X_APB1_UART1 (0x0010) /* Bit 4: UART1 */ +#define STR71X_APB1_UART2 (0x0020) /* Bit 5: UART2 */ +#define STR71X_APB1_UART3 (0x0040) /* Bit 6: UART3 */ +#define STR71X_APB1_USB (0x0080) /* Bit 7: USB */ +#define STR71X_APB1_CAN (0x0100) /* Bit 8: CAN */ +#define STR71X_APB1_BSPI0 (0x0200) /* Bit 9: BSPI0 */ +#define STR71X_APB1_BSPI1 (0x0400) /* Bit 10: BSPI1 */ +#define STR71X_APB1_HDLC (0x2000) /* Bit 13: HDLC */ +#define STR71X_APB1_APB1ALL (0x27fb) + +/* APB2 Peripherals */ + +#define STR71X_APB2_XTI (0x0001) /* Bit 0: XTI */ +#define STR71X_APB2_GPIO0 (0x0004) /* Bit 2: IOPORT0 */ +#define STR71X_APB2_GPIO1 (0x0008) /* Bit 3: IOPORT1 */ +#define STR71X_APB2_GPIO2 (0x0010) /* Bit 4: IOPORT2 */ +#define STR71X_APB2_ADC12 (0x0040) /* Bit 6: ADC */ +#define STR71X_APB2_CKOUT (0x0080) /* Bit 7: CKOUT */ +#define STR71X_APB2_TIM0 (0x0100) /* Bit 8: TIMER0 */ +#define STR71X_APB2_TIM1 (0x0200) /* Bit 9: TIMER1 */ +#define STR71X_APB2_TIM2 (0x0400) /* Bit 10: TIMER2 */ +#define STR71X_APB2_TIM3 (0x0800) /* Bit 11: TIMER3 */ +#define STR71X_APB2_RTC (0x1000) /* Bit 12: RTC */ +#define STR71X_APB2_EIC (0x4000) /* Bit 14: EIC */ +#define STR71X_APB2_APB2ALL (0x5fdd) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_APB_H */ diff --git a/arch/arm/src/str71x/str71x_bspi.h b/arch/arm/src/str71x/str71x_bspi.h new file mode 100644 index 0000000000000000000000000000000000000000..0a1c7864f71e52df7b9024f4c00cc56b5f342dcd --- /dev/null +++ b/arch/arm/src/str71x/str71x_bspi.h @@ -0,0 +1,153 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_bspi.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_BSPI_H +#define __ARCH_ARM_SRC_STR71X_STR71X_BSPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STR71X_BSPI_RXR_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_BSPI_TXR_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_BSPI_CSR1_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_BSPI_CSR2_OFFSET (0x000c) /* 16-bits wide */ +#define STR71X_BSPI_CLK_OFFSET (0x0010) /* 16-bits wide */ + +/* Registers ************************************************************************/ + +#define STR71X_BSPI_RXR(b) ((b) + STR71X_BSPI_RXR_OFFSET) +#define STR71X_BSPI_TXR(b) ((b) + STR71X_BSPI_TXR_OFFSET) +#define STR71X_BSPI_CSR1(b) ((b) + STR71X_BSPI_CSR1_OFFSET) +#define STR71X_BSPI_CSR2(b) ((b) + STR71X_BSPI_CSR2_OFFSET) +#define STR71X_BSPI_CLK(b) ((b) + STR71X_BSPI_CLK_OFFSET) + +#define STR71X_BSPI0_RXR (STR71X_BSPI0_BASE + STR71X_BSPI_RXR_OFFSET) +#define STR71X_BSPI0_TXR (STR71X_BSPI0_BASE + STR71X_BSPI_TXR_OFFSET) +#define STR71X_BSPI0_CSR1 (STR71X_BSPI0_BASE + STR71X_BSPI_CSR1_OFFSET) +#define STR71X_BSPI0_CSR2 (STR71X_BSPI0_BASE + STR71X_BSPI_CSR2_OFFSET) +#define STR71X_BSPI0_CLK (STR71X_BSPI0_BASE + STR71X_BSPI_CLK_OFFSET) + +#define STR71X_BSPI1_RXR (STR71X_BSPI1_BASE + STR71X_BSPI_RXR_OFFSET) +#define STR71X_BSPI1_TXR (STR71X_BSPI1_BASE + STR71X_BSPI_TXR_OFFSET) +#define STR71X_BSPI1_CSR1 (STR71X_BSPI1_BASE + STR71X_BSPI_CSR1_OFFSET) +#define STR71X_BSPI1_CSR2 (STR71X_BSPI1_BASE + STR71X_BSPI_CSR2_OFFSET) +#define STR71X_BSPI1_CLK (STR71X_BSPI1_BASE + STR71X_BSPI_CLK_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* BSPI control/status register 1 */ + +#define STR71X_BSPICSR1_BSPE (1 << 0) /* Bit 0: BSPI enable */ +#define STR71X_BSPICSR1_MSTR (1 << 1) /* Bit 1: Master/Slave select */ +#define STR71X_BSPICSR1_RIESHIFT 2 /* Bit 2-3: BSPI receive interrupt enable */ +#define STR71X_BSPICSR1_RIEMASK (3 << STR71X_BSPICSR1_RIESHIFT) +#define STR71X_BSPICSR1_RIEDISABLED (0 << STR71X_BSPICSR1_RIESHIFT) /* Disabled */ +#define STR71X_BSPICSR1_RIERFNE (1 << STR71X_BSPICSR1_RIESHIFT) /* Receive FIFO not empty */ +#define STR71X_BSPICSR1_RIERFF (3 << STR71X_BSPICSR1_RIESHIFT) /* Receive FIFO full */ +#define STR71X_BSPICSR1_REIE (1 << 4) /* Bit 4: Receive error interrupt enable */ +#define STR71X_BSPICSR1_BEIE (1 << 7) /* Bit 7: Bus error interrupt enable */ +#define STR71X_BSPICSR1_CPOL (1 << 8) /* Bit 8: Clock polarity select */ +#define STR71X_BSPICSR1_CPHA (1 << 9) /* Bit 9: Clock phase select */ +#define STR71X_BSPICSR1_WLSHIFT 10 /* Bits 10-11: Word length */ +#define STR71X_BSPICSR1_WLMASK (3 << STR71X_BSPICSR1_WLSHIFT) +#define STR71X_BSPICSR1_WL8BIT (0 << STR71X_BSPICSR1_WLSHIFT) /* 8-bits */ +#define STR71X_BSPICSR1_WL16BIT (1 << STR71X_BSPICSR1_WLSHIFT) /* 16-bits */ +#define STR71X_BSPICSR1_RFESHIFT 12 /* Bits 12-15: Receive FIFO enable */ +#define STR71X_BSPICSR1_RFEMASK (15 << STR71X_BSPICSR1_RFESHIFT) +#define STR71X_BSPICSR1_RFE1 (0 << STR71X_BSPICSR1_RFESHIFT) /* Word 1 enabled */ +#define STR71X_BSPICSR1_RFE12 (1 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-2 enabled */ +#define STR71X_BSPICSR1_RFE13 (2 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-3 enabled */ +#define STR71X_BSPICSR1_RFE14 (3 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-4 enabled */ +#define STR71X_BSPICSR1_RFE15 (4 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-5 enabled */ +#define STR71X_BSPICSR1_RFE16 (5 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-6 enabled */ +#define STR71X_BSPICSR1_RFE17 (6 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-7 enabled */ +#define STR71X_BSPICSR1_RFE18 (7 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-8 enabled */ +#define STR71X_BSPICSR1_RFE19 (8 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-9 enabled */ +#define STR71X_BSPICSR1_RFE110 (9 << STR71X_BSPICSR1_RFESHIFT) /* Word 1-10 enabled */ + +/* BSPI control/status register 2 */ + +#define STR71X_BSPICSR2_DFIFO (1 << 0) /* Bit 0: FIFO disable */ +#define STR71X_BSPICSR2_BERR (1 << 2) /* Bit 2: Bus error */ +#define STR71X_BSPICSR2_RFNE (1 << 3) /* Bit 3: Receiver FIFO not empty */ +#define STR71X_BSPICSR2_RFF (1 << 4) /* Bit 4: Receiver FIFO full */ +#define STR71X_BSPICSR2_ROFL (1 << 5) /* Bit 5: Receiver overflow */ +#define STR71X_BSPICSR2_TFE (1 << 6) /* Bit 6: Transmit FIFO empty */ +#define STR71X_BSPICSR2_TUFL (1 << 7) /* Bit 7: Transmit FIFO underflow */ +#define STR71X_BSPICSR2_TFF (1 << 8) /* Bit 8: Transmit FIFO full */ +#define STR71X_BSPICSR2_TFNE (1 << 9) /* Bit 9: Transmit FIFO not empty */ +#define STR71X_BSPICSR2_TFESHIFT 10 /* Bits 10-13: Transmit FIFO enable*/ +#define STR71X_BSPICSR2_TFEMASK (15 << STR71X_BSPICSR2_TFESHIFT) +#define STR71X_BSPICSR2_TFE1 (0 << STR71X_BSPICSR2_TFESHIFT) /* Word 1 enabled */ +#define STR71X_BSPICSR2_TFE12 (1 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-2 enabled */ +#define STR71X_BSPICSR2_TFE13 (2 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-3 enabled */ +#define STR71X_BSPICSR2_TFE14 (3 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-4 enabled */ +#define STR71X_BSPICSR2_TFE15 (4 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-5 enabled */ +#define STR71X_BSPICSR2_TFE16 (5 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-6 enabled */ +#define STR71X_BSPICSR2_TFE17 (6 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-7 enabled */ +#define STR71X_BSPICSR2_TFE18 (7 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-8 enabled */ +#define STR71X_BSPICSR2_TFE19 (8 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-9 enabled */ +#define STR71X_BSPICSR2_TFE110 (9 << STR71X_BSPICSR2_TFESHIFT) /* Word 1-10 enabled */ +#define STR71X_BSPICSR2_TIESHIFT 14 /* Bit 14-15: BSPI transmit interrupt enable */ +#define STR71X_BSPICSR2_TIEMASK (3 << STR71X_BSPICSR2_TIESHIFT) +#define STR71X_BSPICSR2_TIEDISABLED (0 << STR71X_BSPICSR2_TIESHIFT) /* Disabled */ +#define STR71X_BSPICSR2_TIETFE (1 << STR71X_BSPICSR2_TIESHIFT) /* Interrupt on transmit FIFO empty */ +#define STR71X_BSPICSR2_TIETUFL (2 << STR71X_BSPICSR2_TIESHIFT) /* Interrupt on transmit underlow */ +#define STR71X_BSPICSR2_TIETFF (3 << STR71X_BSPICSR2_TIESHIFT) /* Interrupt on transmit FIFO full */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_BSPI_H */ diff --git a/arch/arm/src/str71x/str71x_can.h b/arch/arm/src/str71x/str71x_can.h new file mode 100644 index 0000000000000000000000000000000000000000..3bd0f3cea1886641e0166361a8a58ff42a9c5e18 --- /dev/null +++ b/arch/arm/src/str71x/str71x_can.h @@ -0,0 +1,207 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_can.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_CAN_H +#define __ARCH_ARM_SRC_STR71X_STR71X_CAN_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Registers ************************************************************************/ + +#define STR71X_CAN_CR (STR71X_CAN_BASE + 0x0000) /* 16-bits wide */ +#define STR71X_CAN_SR (STR71X_CAN_BASE + 0x0004) /* 16-bits wide */ +#define STR71X_CAN_ERR (STR71X_CAN_BASE + 0x0008) /* 16-bits wide */ +#define STR71X_CAN_BTR (STR71X_CAN_BASE + 0x000c) /* 16-bits wide */ +#define STR71X_CAN_IDR (STR71X_CAN_BASE + 0x0010) /* 16-bits wide */ +#define STR71X_CAN_TESTR (STR71X_CAN_BASE + 0x0014) /* 16-bits wide */ +#define STR71X_CAN_BRPR (STR71X_CAN_BASE + 0x0018) /* 16-bits wide */ + +#define STR71X_CAN_IF1BASE (STR71X_CAN_BASE + 0x0020) +#define STR71X_CAN_IF2BASE (STR71X_CAN_BASE + 0x0080) + +#define STR71X_CAN_CRR_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_CAN_CMR_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_CAN_M1R_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_CAN_M2R_OFFSET (0x000c) /* 16-bits wide */ +#define STR71X_CAN_A1R_OFFSET (0x0010) /* 16-bits wide */ +#define STR71X_CAN_A2R_OFFSET (0x0014) /* 16-bits wide */ +#define STR71X_CAN_MCR_OFFSET (0x0018) /* 16-bits wide */ +#define STR71X_CAN_DA1R_OFFSET (0x001c) /* 16-bits wide */ +#define STR71X_CAN_DA2R_OFFSET (0x0020) /* 16-bits wide */ +#define STR71X_CAN_DB1R_OFFSET (0x0024) /* 16-bits wide */ +#define STR71X_CAN_DB2R_OFFSET (0x0028) /* 16-bits wide */ + +#define STR71X_CAN_CRR(b) ((b) + STR71X_CAN_CRR_OFFSET) +#define STR71X_CAN_CMR(b) ((b) + STR71X_CAN_CMR_OFFSET) +#define STR71X_CAN_M1R(b) ((b) + STR71X_CAN_M1R_OFFSET) +#define STR71X_CAN_M2R(b) ((b) + STR71X_CAN_M2R_OFFSET) +#define STR71X_CAN_A1R(b) ((b) + STR71X_CAN_A1R_OFFSET) +#define STR71X_CAN_A2R(b) ((b) + STR71X_CAN_A2R_OFFSET) +#define STR71X_CAN_MCR(b) ((b) + STR71X_CAN_MCR_OFFSET) +#define STR71X_CAN_DA1R(b) ((b) + STR71X_CAN_DA1R_OFFSET) +#define STR71X_CAN_DA2R(b) ((b) + STR71X_CAN_DA2R_OFFSET) +#define STR71X_CAN_DB1R(b) ((b) + STR71X_CAN_DB1R_OFFSET) +#define STR71X_CAN_DB2R(b) ((b) + STR71X_CAN_DB2R_OFFSET) + +#define STR71X_CAN_IF1CRR (STR71X_CAN_IF1BASE + STR71X_CAN_CRR_OFFSET) +#define STR71X_CAN_IF1CMR (STR71X_CAN_IF1BASE + STR71X_CAN_CMR_OFFSET) +#define STR71X_CAN_IF1M1R (STR71X_CAN_IF1BASE + STR71X_CAN_M1R_OFFSET) +#define STR71X_CAN_IF1M2R (STR71X_CAN_IF1BASE + STR71X_CAN_M2R_OFFSET) +#define STR71X_CAN_IF1A1R (STR71X_CAN_IF1BASE + STR71X_CAN_A1R_OFFSET) +#define STR71X_CAN_IF1A2R (STR71X_CAN_IF1BASE + STR71X_CAN_A2R_OFFSET) +#define STR71X_CAN_IF1MCR (STR71X_CAN_IF1BASE + STR71X_CAN_MCR_OFFSET) +#define STR71X_CAN_IF1DA1R (STR71X_CAN_IF1BASE + STR71X_CAN_DA1R_OFFSET) +#define STR71X_CAN_IF1DA2R (STR71X_CAN_IF1BASE + STR71X_CAN_DA2R_OFFSET) +#define STR71X_CAN_IF1DB1R (STR71X_CAN_IF1BASE + STR71X_CAN_DB1R_OFFSET) +#define STR71X_CAN_IF1DB2R (STR71X_CAN_IF1BASE + STR71X_CAN_DB2R_OFFSET) + +#define STR71X_CAN_IF2CRR (STR71X_CAN_IF2BASE + STR71X_CAN_CRR_OFFSET) +#define STR71X_CAN_IF2CMR (STR71X_CAN_IF2BASE + STR71X_CAN_CMR_OFFSET) +#define STR71X_CAN_IF2M1R (STR71X_CAN_IF2BASE + STR71X_CAN_M1R_OFFSET) +#define STR71X_CAN_IF2M2R (STR71X_CAN_IF2BASE + STR71X_CAN_M2R_OFFSET) +#define STR71X_CAN_IF2A1R (STR71X_CAN_IF2BASE + STR71X_CAN_A1R_OFFSET) +#define STR71X_CAN_IF2A2R (STR71X_CAN_IF2BASE + STR71X_CAN_A2R_OFFSET) +#define STR71X_CAN_IF2MCR (STR71X_CAN_IF2BASE + STR71X_CAN_MCR_OFFSET) +#define STR71X_CAN_IF2DA1R (STR71X_CAN_IF2BASE + STR71X_CAN_DA1R_OFFSET) +#define STR71X_CAN_IF2DA2R (STR71X_CAN_IF2BASE + STR71X_CAN_DA2R_OFFSET) +#define STR71X_CAN_IF2DB1R (STR71X_CAN_IF2BASE + STR71X_CAN_DB1R_OFFSET) +#define STR71X_CAN_IF2DB2R (STR71X_CAN_IF2BASE + STR71X_CAN_DB2R_OFFSET) + +#define STR71X_CAN_TR1R (STR71X_CAN_BASE + 0x0100) /* 16-bits wide */ +#define STR71X_CAN_TR2R (STR71X_CAN_BASE + 0x0104) /* 16-bits wide */ +#define STR71X_CAN_ND1R (STR71X_CAN_BASE + 0x0120) /* 16-bits wide */ +#define STR71X_CAN_ND2R (STR71X_CAN_BASE + 0x0124) /* 16-bits wide */ +#define STR71X_CAN_IP1R (STR71X_CAN_BASE + 0x0140) /* 16-bits wide */ +#define STR71X_CAN_IP2R (STR71X_CAN_BASE + 0x0144) /* 16-bits wide */ +#define STR71X_CAN_MV1R (STR71X_CAN_BASE + 0x0160) /* 16-bits wide */ +#define STR71X_CAN_MV2R (STR71X_CAN_BASE + 0x0164) /* 16-bits wide */ + +/* Register bit settings ***********************************************************/ + +/* Control register */ + +#define STR41X_CANCR_INIT (0x0001) +#define STR41X_CANCR_IE (0x0002) +#define STR41X_CANCR_SIE (0x0004) +#define STR41X_CANCR_EIE (0x0008) +#define STR41X_CANCR_DAR (0x0020) +#define STR41X_CANCR_CCE (0x0040) +#define STR41X_CANCR_TEST (0x0080) + +/* Status register */ + +#define STR41X_CANSR_LEC (0x0007) +#define STR41X_CANSR_TXOK (0x0008) +#define STR41X_CANSR_RXOK (0x0010) +#define STR41X_CANSR_EPASS (0x0020) +#define STR41X_CANSR_EWARN (0x0040) +#define STR41X_CANSR_BOFF (0x0080) + +/* Test register */ + +#define STR41X_CANTESTR_BASIC (0x0004) +#define STR41X_CANTESTR_SILENT (0x0008) +#define STR41X_CANTESTR_LBACK (0x0010) +#define STR41X_CANTESTR_TX0 (0x0020) +#define STR41X_CANTESTR_TX1 (0x0040) +#define STR41X_CANTESTR_RX (0x0080) + +/* IFn / Command Request register */ + +#define STR41X_CANCRR_BUSY (0x8000) + +/* IFn / Command Mask register */ + +#define STR41X_CANCMR_DATAB (0x0001) +#define STR41X_CANCMR_DATAA (0x0002) +#define STR41X_CANCMR_TXRQST (0x0004) +#define STR41X_CANCMR_CLRINTPND (0x0008) +#define STR41X_CANCMR_CONTROL (0x0010) +#define STR41X_CANCMR_ARB (0x0020) +#define STR41X_CANCMR_MASK (0x0040) +#define STR41X_CANCMR_WRRD (0x0080) + +/* IFn / Mask 2 register */ + +#define STR41X_CANM2R_MXTD (0x8000) +#define STR41X_CANM2R_MDIR (0x4000) + +/* IFn / Arbitration 2 register */ + +#define STR41X_CANA2R_DIR (0x2000) +#define STR41X_CANA2R_XTD (0x4000) +#define STR41X_CANA2R_MSGVAL (0x8000) + +/* IFn / Message Control register */ + +#define STR41X_CANMCR_EOB (0x0080) +#define STR41X_CANMCR_TXRQST (0x0100) +#define STR41X_CANMCR_RMTEN (0x0200) +#define STR41X_CANMCR_RXIE (0x0400) +#define STR41X_CANMCR_TXIE (0x0800) +#define STR41X_CANMCR_UMASK (0x1000) +#define STR41X_CANMCR_INTPND (0x2000) +#define STR41X_CANMCR_MSGLST (0x4000) +#define STR41X_CANMCR_NEWDAT (0x8000) + +/* Message ID limits */ + +#define STR41X_CAN_LASTSTDID ((1 << 11) - 1) +#define STR41X_CAN_LASTEXTID ((1 << 29) - 1) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_CAN_H */ + diff --git a/arch/arm/src/str71x/str71x_decodeirq.c b/arch/arm/src/str71x/str71x_decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..c908ae9e3a10110eb97cdf37f4b2db391325ac4f --- /dev/null +++ b/arch/arm/src/str71x/str71x_decodeirq.c @@ -0,0 +1,143 @@ +/******************************************************************************** + * arch/arm/src/str71x/str71x_decodeirq.c + * + * Copyright (C) 2008-2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Private Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Funstions + ********************************************************************************/ + +/******************************************************************************** + * up_decodeirq() + * + * Description: + * Read the IRQ number from the IVR register. During initialization, the IVR + * register was set to zero. Each SIR[n] register was programmed to contain + * the IRQ number. At IRQ processing time (when this function run), the IVR + * should contain the desired IRQ number. + * + ********************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + board_autoled_on(LED_INIRQ); + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + CURRENT_REGS = regs; + PANIC(); +#else + unsigned int irq; + + /* Read the IRQ number from the IVR register (Could probably get the same + * info from CIC register without the setup). + */ + + board_autoled_on(LED_INIRQ); + irq = getreg32(STR71X_EIC_IVR); + + /* Verify that the resulting IRQ number is valid */ + + if (irq < NR_IRQS) + { + uint32_t *savestate; + + /* Current regs non-zero indicates that we are processing an interrupt; + * CURRENT_REGS is also used to manage interrupt level context switches. + */ + + savestate = (uint32_t *)CURRENT_REGS; + CURRENT_REGS = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* Restore the previous value of CURRENT_REGS. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + CURRENT_REGS = savestate; + } +#ifdef CONFIG_DEBUG + else + { + PANIC(); /* Normally never happens */ + } +#endif + board_autoled_off(LED_INIRQ); +#endif +} diff --git a/arch/arm/src/str71x/str71x_eic.h b/arch/arm/src/str71x/str71x_eic.h new file mode 100644 index 0000000000000000000000000000000000000000..8e4f1cd0b80c5679ca99104d4725d3db0e603563 --- /dev/null +++ b/arch/arm/src/str71x/str71x_eic.h @@ -0,0 +1,176 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_eic.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_EIC_H +#define __ARCH_ARM_SRC_STR71X_STR71X_EIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Enhanced Interupt Controller (EIC) register offsets ******************************/ + +#define STR71X_EIC_ICR_OFFSET (0x0000) /* 32-bits wide */ +#define STR71X_EIC_CICR_OFFSET (0x0004) /* 32-bits wide */ +#define STR71X_EIC_CIPR_OFFSET (0x0008) /* 32-bits wide */ +#define STR71X_EIC_IVR_OFFSET (0x0018) /* 32-bits wide */ +#define STR71X_EIC_FIR_OFFSET (0x001c) /* 32-bits wide */ +#define STR71X_EIC_IER_OFFSET (0x0020) /* 32-bits wide */ +#define STR71X_EIC_IPR_OFFSET (0x0040) /* 32-bits wide */ + +#define STR71X_EIC_SIR_OFFSET (0x0060) /* 32 x 32-bits */ +#define STR71X_EIC_SIR0_OFFSET (0x0060) /* 32-bits wide */ +#define STR71X_EIC_SIR1_OFFSET (0x0064) /* 32-bits wide */ +#define STR71X_EIC_SIR2_OFFSET (0x0068) /* 32-bits wide */ +#define STR71X_EIC_SIR3_OFFSET (0x006c) /* 32-bits wide */ +#define STR71X_EIC_SIR4_OFFSET (0x0070) /* 32-bits wide */ +#define STR71X_EIC_SIR5_OFFSET (0x0074) /* 32-bits wide */ +#define STR71X_EIC_SIR6_OFFSET (0x0078) /* 32-bits wide */ +#define STR71X_EIC_SIR7_OFFSET (0x007c) /* 32-bits wide */ +#define STR71X_EIC_SIR8_OFFSET (0x0080) /* 32-bits wide */ +#define STR71X_EIC_SIR9_OFFSET (0x0084) /* 32-bits wide */ +#define STR71X_EIC_SIR10_OFFSET (0x0088) /* 32-bits wide */ +#define STR71X_EIC_SIR11_OFFSET (0x008c) /* 32-bits wide */ +#define STR71X_EIC_SIR12_OFFSET (0x0090) /* 32-bits wide */ +#define STR71X_EIC_SIR13_OFFSET (0x0094) /* 32-bits wide */ +#define STR71X_EIC_SIR14_OFFSET (0x0098) /* 32-bits wide */ +#define STR71X_EIC_SIR15_OFFSET (0x009c) /* 32-bits wide */ +#define STR71X_EIC_SIR16_OFFSET (0x00a0) /* 32-bits wide */ +#define STR71X_EIC_SIR17_OFFSET (0x00a4) /* 32-bits wide */ +#define STR71X_EIC_SIR18_OFFSET (0x00a8) /* 32-bits wide */ +#define STR71X_EIC_SIR19_OFFSET (0x00ac) /* 32-bits wide */ +#define STR71X_EIC_SIR20_OFFSET (0x00b0) /* 32-bits wide */ +#define STR71X_EIC_SIR21_OFFSET (0x00b4) /* 32-bits wide */ +#define STR71X_EIC_SIR22_OFFSET (0x00b8) /* 32-bits wide */ +#define STR71X_EIC_SIR23_OFFSET (0x00bc) /* 32-bits wide */ +#define STR71X_EIC_SIR24_OFFSET (0x00c0) /* 32-bits wide */ +#define STR71X_EIC_SIR25_OFFSET (0x00c4) /* 32-bits wide */ +#define STR71X_EIC_SIR26_OFFSET (0x00c8) /* 32-bits wide */ +#define STR71X_EIC_SIR27_OFFSET (0x00cc) /* 32-bits wide */ +#define STR71X_EIC_SIR28_OFFSET (0x00d0) /* 32-bits wide */ +#define STR71X_EIC_SIR29_OFFSET (0x00d4) /* 32-bits wide */ +#define STR71X_EIC_SIR30_OFFSET (0x00d8) /* 32-bits wide */ +#define STR71X_EIC_SIR31_OFFSET (0x00dc) /* 32-bits wide */ + +#define STR71X_EIC_NCHANNELS (32) +#define STR71X_EIC_SIR_BASE (STR71X_EIC_BASE + STR71X_EIC_SIR_OFFSET) + +/* Enhanced Interupt Controller (EIC) registers *************************************/ + +#define STR71X_EIC_ICR (STR71X_EIC_BASE + STR71X_EIC_ICR_OFFSET) +#define STR71X_EIC_CICR (STR71X_EIC_BASE + STR71X_EIC_CICR_OFFSET) +#define STR71X_EIC_CIPR (STR71X_EIC_BASE + STR71X_EIC_CIPR_OFFSET) +#define STR71X_EIC_IVR (STR71X_EIC_BASE + STR71X_EIC_IVR_OFFSET) +#define STR71X_EIC_FIR (STR71X_EIC_BASE + STR71X_EIC_FIR_OFFSET) +#define STR71X_EIC_IER (STR71X_EIC_BASE + STR71X_EIC_IER_OFFSET) +#define STR71X_EIC_IPR (STR71X_EIC_BASE + STR71X_EIC_IPR_OFFSET) + +#define STR71X_EIC_SIR(n) (STR71X_EIC_SIR_BASE + ((n) << 2)) + +#define STR71X_EIC_SIR0 (STR71X_EIC_BASE + STR71X_EIC_SIR0_OFFSET) +#define STR71X_EIC_SIR1 (STR71X_EIC_BASE + STR71X_EIC_SIR1_OFFSET) +#define STR71X_EIC_SIR2 (STR71X_EIC_BASE + STR71X_EIC_SIR2_OFFSET) +#define STR71X_EIC_SIR3 (STR71X_EIC_BASE + STR71X_EIC_SIR3_OFFSET) +#define STR71X_EIC_SIR4 (STR71X_EIC_BASE + STR71X_EIC_SIR4_OFFSET) +#define STR71X_EIC_SIR5 (STR71X_EIC_BASE + STR71X_EIC_SIR5_OFFSET) +#define STR71X_EIC_SIR6 (STR71X_EIC_BASE + STR71X_EIC_SIR6_OFFSET) +#define STR71X_EIC_SIR7 (STR71X_EIC_BASE + STR71X_EIC_SIR7_OFFSET) +#define STR71X_EIC_SIR8 (STR71X_EIC_BASE + STR71X_EIC_SIR8_OFFSET) +#define STR71X_EIC_SIR9 (STR71X_EIC_BASE + STR71X_EIC_SIR9_OFFSET) +#define STR71X_EIC_SIR10 (STR71X_EIC_BASE + STR71X_EIC_SIR10_OFFSET) +#define STR71X_EIC_SIR11 (STR71X_EIC_BASE + STR71X_EIC_SIR11_OFFSET) +#define STR71X_EIC_SIR12 (STR71X_EIC_BASE + STR71X_EIC_SIR12_OFFSET) +#define STR71X_EIC_SIR13 (STR71X_EIC_BASE + STR71X_EIC_SIR13_OFFSET) +#define STR71X_EIC_SIR14 (STR71X_EIC_BASE + STR71X_EIC_SIR14_OFFSET) +#define STR71X_EIC_SIR15 (STR71X_EIC_BASE + STR71X_EIC_SIR15_OFFSET) +#define STR71X_EIC_SIR16 (STR71X_EIC_BASE + STR71X_EIC_SIR16_OFFSET) +#define STR71X_EIC_SIR17 (STR71X_EIC_BASE + STR71X_EIC_SIR17_OFFSET) +#define STR71X_EIC_SIR18 (STR71X_EIC_BASE + STR71X_EIC_SIR18_OFFSET) +#define STR71X_EIC_SIR19 (STR71X_EIC_BASE + STR71X_EIC_SIR19_OFFSET) +#define STR71X_EIC_SIR20 (STR71X_EIC_BASE + STR71X_EIC_SIR20_OFFSET) +#define STR71X_EIC_SIR21 (STR71X_EIC_BASE + STR71X_EIC_SIR21_OFFSET) +#define STR71X_EIC_SIR22 (STR71X_EIC_BASE + STR71X_EIC_SIR22_OFFSET) +#define STR71X_EIC_SIR23 (STR71X_EIC_BASE + STR71X_EIC_SIR23_OFFSET) +#define STR71X_EIC_SIR24 (STR71X_EIC_BASE + STR71X_EIC_SIR24_OFFSET) +#define STR71X_EIC_SIR25 (STR71X_EIC_BASE + STR71X_EIC_SIR25_OFFSET) +#define STR71X_EIC_SIR26 (STR71X_EIC_BASE + STR71X_EIC_SIR26_OFFSET) +#define STR71X_EIC_SIR27 (STR71X_EIC_BASE + STR71X_EIC_SIR27_OFFSET) +#define STR71X_EIC_SIR28 (STR71X_EIC_BASE + STR71X_EIC_SIR28_OFFSET) +#define STR71X_EIC_SIR29 (STR71X_EIC_BASE + STR71X_EIC_SIR29_OFFSET) +#define STR71X_EIC_SIR30 (STR71X_EIC_BASE + STR71X_EIC_SIR30_OFFSET) +#define STR71X_EIC_SIR31 (STR71X_EIC_BASE + STR71X_EIC_SIR31_OFFSET) + +/* Register bit settings ************************************************************/ + +/* Interrupt control register (ICR) bit definitions */ + +#define STR71X_EICICR_IRQEN (0x00000001) /* Bit 0: IRQ output enable */ +#define STR71X_EICICR_FIQEN (0x00000002) /* Bit 1: FIQ output enable */ + +/* Current interrupt channel register (CICR) bit definitions */ + +#define STR71X_EICCICR_MASK 0x1f /* Bits: 0-4: CIC */ + +/* Fast interrupt register (FIR) bit definitions */ + +#define STR71X_EICFIR_FIE (0x00000001) /* Bit 0: FIQ channel 1/0 enable */ +#define STR71X_EICFIR_FIP (0x00000002) /* Bit 1: channel 1/0 FIQ pending */ + +/* Source interrupt register definitions */ + +#define STR71X_EICSIR_SIPLMASK (0x0000000f) /* Bits 0-3: Source interrupt priority level */ +#define STR71X_EICSIR_SIVMASK (0xffff0000) /* Bits 16-31: Source interrupt vector */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_EIC_H */ diff --git a/arch/arm/src/str71x/str71x_emi.h b/arch/arm/src/str71x/str71x_emi.h new file mode 100644 index 0000000000000000000000000000000000000000..7c135d937edee8ddf6b606d04f9f9fbbf0312987 --- /dev/null +++ b/arch/arm/src/str71x/str71x_emi.h @@ -0,0 +1,103 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_emi.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_EMI_H +#define __ARCH_ARM_SRC_STR71X_STR71X_EMI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* External Memory Interfac (EMI) register offset ***********************************/ + +#define STR71X_EMI_BCON0_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_EMI_BCON1_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_EMI_BCON2_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_EMI_BCON3_OFFSET (0x000c) /* 16-bits wide */ + +/* External Memory Interfac (EMI) register addresses ********************************/ + +#define STR71X_EMI_BCON0 (STR71X_EMI_BASE + STR71X_EMI_BCON0_OFFSET) +#define STR71X_EMI_BCON1 (STR71X_EMI_BASE + STR71X_EMI_BCON1_OFFSET) +#define STR71X_EMI_BCON2 (STR71X_EMI_BASE + STR71X_EMI_BCON2_OFFSET) +#define STR71X_EMI_BCON3 (STR71X_EMI_BASE + STR71X_EMI_BCON3_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* Bank-N configuration register (BCONn) bit definitions */ + +#define STR71X_EMIBCON_BSIZEMASK (0x0003) /* Bits 0-1: Bank size */ +#define STR71X_EMIBCON_BSIZE8 (0x0000) /* 8-bit */ +#define STR71X_EMIBCON_BSIZE16 (0x0001) /* 16-bit */ +#define STR71X_EMIBCON_WSMASK (0x003c) /* Bits 2-5: Wait states */ +#define STR71X_EMIBCON_WS0 (0x0000) /* 0 waitstates */ +#define STR71X_EMIBCON_WS1 (0x0004) /* 1 waitstates */ +#define STR71X_EMIBCON_WS2 (0x0008) /* 2 waitstates */ +#define STR71X_EMIBCON_WS3 (0x000c) /* 3 waitstates */ +#define STR71X_EMIBCON_WS4 (0x0010) /* 4 waitstates */ +#define STR71X_EMIBCON_WS5 (0x0014) /* 5 waitstates */ +#define STR71X_EMIBCON_WS6 (0x0018) /* 6 waitstates */ +#define STR71X_EMIBCON_WS7 (0x001c) /* 7 waitstates */ +#define STR71X_EMIBCON_WS8 (0x0020) /* 8 waitstates */ +#define STR71X_EMIBCON_WS9 (0x0024) /* 9 waitstates */ +#define STR71X_EMIBCON_WS10 (0x0028) /* 10 waitstates */ +#define STR71X_EMIBCON_WS11 (0x002c) /* 11 waitstates */ +#define STR71X_EMIBCON_WS12 (0x0030) /* 12 waitstates */ +#define STR71X_EMIBCON_WS13 (0x0034) /* 13 waitstates */ +#define STR71X_EMIBCON_WS14 (0x0038) /* 14 waitstates */ +#define STR71X_EMIBCON_WS15 (0x003c) /* 15 waitstates */ +#define STR71X_EMIBCON_ENABLE (0x8000) /* Bit 15: Bank enable */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_EMI_H */ diff --git a/arch/arm/src/str71x/str71x_flash.h b/arch/arm/src/str71x/str71x_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..b7e0f5a820dca6c7456d9a99b622cf8fb329812e --- /dev/null +++ b/arch/arm/src/str71x/str71x_flash.h @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_flash.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_FLASH_H +#define __ARCH_ARM_SRC_STR71X_STR71X_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Flash registers ******************************************************************/ + +#define STR71X_FLASH_CR0 (STR71X_FLASHREG_BASE + 0x0000) /* 32-bits wide */ +#define STR71X_FLASH_CR1 (STR71X_FLASHREG_BASE + 0x0004) /* 32-bits wide */ +#define STR71X_FLASH_DR0 (STR71X_FLASHREG_BASE + 0x0008) /* 32-bits wide */ +#define STR71X_FLASH_DR1 (STR71X_FLASHREG_BASE + 0x000c) /* 32-bits wide */ +#define STR71X_FLASH_AR (STR71X_FLASHREG_BASE + 0x0010) /* 32-bits wide */ +#define STR71X_FLASH_ER (STR71X_FLASHREG_BASE + 0x0014) /* 32-bits wide */ + +/* Register bit settings ************************************************************/ + +#define STR71X_FLASH_B0F0 (0x00000001) +#define STR71X_FLASH_B0F1 (0x00000002) +#define STR71X_FLASH_B0F2 (0x00000004) +#define STR71X_FLASH_B0F3 (0x00000008) +#define STR71X_FLASH_B0F4 (0x00000010) +#define STR71X_FLASH_B0F5 (0x00000020) +#define STR71X_FLASH_B0F6 (0x00000040) +#define STR71X_FLASH_B0F7 (0x00000080) + +#define STR71X_FLASH_B1F0 (0x00010000) +#define STR71X_FLASH_B1F1 (0x00020000) + +#define STR71X_FLASH_B0 (STR71X_FLASH_B0F0|STR71X_FLASH_B0F1|\ + STR71X_FLASH_B0F2|STR71X_FLASH_B0F3|\ + STR71X_FLASH_B0F4|STR71X_FLASH_B0F5|\ + STR71X_FLASH_B0F6| STR71X_FLASH_B0F7) +#define STR71X_FLASH_B1 (STR71X_FLASH_B1F0|STR71X_FLASH_B1F1) + +#define STR71X_FLASH_BANK0 (0x1000000) +#define STR71X_FLASH_BANK1 (0x2000000) + +#define STR71X_FLASH_BSYA0 (0x01) /* 000-00001 (0000 0001 (0x01 */ /* STR71X_FLASH_CR0.1 */ +#define STR71X_FLASH_BSYA1 (0x02) /* 000-00010 (0000 0010 (0x02 */ /* STR71X_FLASH_CR0.2 */ +#define STR71X_FLASH_LOCK (0x04) /* 000-00100 (0000 0100 (0x04 */ /* STR71X_FLASH_CR0.4 */ +#define STR71X_FLASH_INTP (0x14) /* 000-10100 (0001 0100 (0x14 */ /* STR71X_FLASH_CR0.20 */ +#define STR71X_FLASH_B0S (0x38) /* 001-11000 (0011 1000 (0x38 */ /* STR71X_FLASH_CR1.24 */ +#define STR71X_FLASH_B1S (0x39) /* 001-11001 (0011 1001 (0x39 */ /* STR71X_FLASH_CR1.25 */ +#define STR71X_FLASH_ERR (0xa0) /* 101-00000 (1010 0000 (0xA0 */ /* STR71X_FLASH_ER.0 */ +#define STR71X_FLASH_ERER (0xa1) /* 101-00001 (1010 0001 (0xA1 */ /* STR71X_FLASH_ER.1 */ +#define STR71X_FLASH_PGER (0xa2) /* 101-00010 (1010 0010 (0xA2 */ /* STR71X_FLASH_ER.2 */ +#define STR71X_FLASH_10ER (0xa3) /* 101-00011 (1010 0011 (0xA3 */ /* STR71X_FLASH_ER.3 */ +#define STR71X_FLASH_SEQER (0xa6) /* 101-00110 (1010 0110 (0xA6 */ /* STR71X_FLASH_ER.6 */ +#define STR71X_FLASH_RESER (0xa7) /* 101-00111 (1010 0111 (0xA7 */ /* STR71X_FLASH_ER.7 */ +#define STR71X_FLASH_WPF (0xa8) /* 101-01000 (1010 1000 (0xA8 */ /* STR71X_FLASH_ER.8 */ + +#define STR71X_FLASH_WMS_MASK (0x80000000) +#define STR71X_FLASH_SUSP_MASK (0x40000000) +#define STR71X_FLASH_WPG_MASK (0x20000000) +#define STR71X_FLASH_DWPG_MASK (0x10000000) +#define STR71X_FLASH_SER_MASK (0x08000000) +#define STR71X_FLASH_SPR_MASK (0x01000000) +#define STR71X_FLASH_DBGP_MASK (0x00000002) +#define STR71X_FLASH_ACCP_MASK (0x00000001) + +#define STR71X_FLASH_Reg_Mask (0xe0) +#define STR71X_FLASH_Flag_Mask (0x1f) + +#define STR71X_FLASH_INTM_Mask (0x00200000) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_FLASH_H */ diff --git a/arch/arm/src/str71x/str71x_gpio.h b/arch/arm/src/str71x/str71x_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..f53f16f5d61537f5b9a07bea24bb7d2f0f78b50a --- /dev/null +++ b/arch/arm/src/str71x/str71x_gpio.h @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_gpio.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_GPIO_H +#define __ARCH_ARM_SRC_STR71X_STR71X_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO register offsets ************************************************************/ + +#define STR71X_GPIO_PC0_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_GPIO_PC1_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_GPIO_PC2_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_GPIO_PD_OFFSET (0x000c) /* 16-bits wide */ + +/* GPIO register addresses **********************************************************/ + +#define STR71X_GPIO_PC0(b) ((b) + STR71X_GPIO_PC0_OFFSET) +#define STR71X_GPIO_PC1(b) ((b) + STR71X_GPIO_PC1_OFFSET) +#define STR71X_GPIO_PC2(b) ((b) + STR71X_GPIO_PC2_OFFSET) +#define STR71X_GPIO_PD(b) ((b) + STR71X_GPIO_PD_OFFSET) + +#define STR71X_GPIO0_PC0 (STR71X_GPIO0_BASE + STR71X_GPIO_PC0_OFFSET) +#define STR71X_GPIO0_PC1 (STR71X_GPIO0_BASE + STR71X_GPIO_PC1_OFFSET) +#define STR71X_GPIO0_PC2 (STR71X_GPIO0_BASE + STR71X_GPIO_PC2_OFFSET) +#define STR71X_GPIO0_PD (STR71X_GPIO0_BASE + STR71X_GPIO_PD_OFFSET) + +#define STR71X_GPIO1_PC0 (STR71X_GPIO1_BASE + STR71X_GPIO_PC0_OFFSET) +#define STR71X_GPIO1_PC1 (STR71X_GPIO1_BASE + STR71X_GPIO_PC1_OFFSET) +#define STR71X_GPIO1_PC2 (STR71X_GPIO1_BASE + STR71X_GPIO_PC2_OFFSET) +#define STR71X_GPIO1_PD (STR71X_GPIO1_BASE + STR71X_GPIO_PD_OFFSET) + +#define STR71X_GPIO2_PC0 (STR71X_GPIO2_BASE + STR71X_GPIO_PC0_OFFSET) +#define STR71X_GPIO2_PC1 (STR71X_GPIO2_BASE + STR71X_GPIO_PC1_OFFSET) +#define STR71X_GPIO2_PC2 (STR71X_GPIO2_BASE + STR71X_GPIO_PC2_OFFSET) +#define STR71X_GPIO2_PD (STR71X_GPIO2_BASE + STR71X_GPIO_PD_OFFSET) + +/* Register bit settings ************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_GPIO_H */ diff --git a/arch/arm/src/str71x/str71x_head.S b/arch/arm/src/str71x/str71x_head.S new file mode 100644 index 0000000000000000000000000000000000000000..6a299e8911bb182a95247a80e5447fbc2f9e077a --- /dev/null +++ b/arch/arm/src/str71x/str71x_head.S @@ -0,0 +1,630 @@ +/***************************************************************************** + * arch/arm/src/str71x/str71x_head.S + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include /* NuttX configuration settings */ +#include /* Board-specific settings */ + +#include "arm.h" /* ARM-specific settings */ +#include "chip.h" /* Chip-specific settings */ +#include "up_internal.h" +#include "up_arch.h" + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +/* This file holds the NuttX start logic that runs when the STR711 + * is reset. This logic must be located at address 0x4000:0000 in + * flash. It will also be mapped to address zero when the STR711 is + * reset. + */ + +/***************************************************************************** + * External references + *****************************************************************************/ + + .globl str71x_prccuinit /* Clock initialization */ + .globl up_lowsetup /* Early initialization of UART */ +#ifdef USE_EARLYSERIALINIT + .globl up_earlyserialinit /* Early initialization of serial driver */ +#endif +#ifdef CONFIG_ARCH_LEDS + .globl board_autoled_initialize /* Boot LED setup */ +#endif +#ifdef CONFIG_DEBUG + .globl up_lowputc /* Low-level debug output */ +#endif + .globl os_start /* NuttX entry point */ + +/***************************************************************************** + * Macros + *****************************************************************************/ + +/***************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. This macro will + * modify r0, r1, r2 and r14 + * + *****************************************************************************/ + + .macro showprogress, code +#ifdef CONFIG_DEBUG + mov r0, #\code + bl up_lowputc +#endif + .endm + +/***************************************************************************** + * Name: emiinit + * + * Description: + * Initialize external memory banks 0-3 as configured + * + *****************************************************************************/ + + .macro emiinit, base, value +#if defined(CONFIG_STR71X_BANK0) || defined(CONFIG_STR71X_BANK1) || \ + defined(CONFIG_STR71X_BANK2) || defined(CONFIG_STR71X_BANK3) + + /* In order to use the external memory, certain GPIO pins must be + * configured in the alternate function: + * + * GPIO ALT Description + * P2.0-3 CS.0-3 External memory chip select for banks 0,1,3,4 + * P2.4-7 A.20-23 External memory extended address bus (needed for + * address space > 1Mb) + */ + +#ifdef CONFIG_STR71X_BIGEXTMEM +# define EXTMEM_GPIO_BITSET 0x000000ff /* P2.0-7 */ +#else +# define EXTMEM_GPIO_BITSET 0x0000000f /* P2.0-3 */ +#endif + + ldr \base, =STR71X_GPIO_BASE ; Configure P2.0 to P2.3/7 in AF_PP mode + ldr \value, [\base, #STR71X_GPIO_PC0_OFFSET] + orr \value, \value, #EXTMEM_GPIO_BITSET + str \value, [\base, #STR71X_GPIO_PC0_OFFSET] + ldr \value, [\base, #STR71X_GPIO_PC1_OFFSET] + orr \value, \value, #EXTMEM_GPIO_BITSET + str \value, [\base, #STR71X_GPIO_PC1_OFFSET] + ldr \value, [\base, #STR71X_GPIO_PC2_OFFSET] + orr \value, \value, #EXTMEM_GPIO_BITSET + str \value, [\base, #STR71X_GPIO_PC2_OFFSET] + + /* Enable bank 0 */ + + ldr \base, =STR71X_EMI_BASE + +#ifdef CONFIG_STR71X_BANK0 + + /* Get the bank 0 size */ + +# if CONFIG_STR71X_BANK0_SIZE == 8 +# define EXTMEM_BANK0_SIZE STR71X_EMIBCON_BSIZE8 +# elif CONFIG_STR71X_BANK0_SIZE == 16 +# define EXTMEM_BANK0_SIZE STR71X_EMIBCON_BSIZE16 +# else +# error "CONFIG_STR71X_BANK0_SIZE invalid" +# endif + + /* Get the bank 0 waitstates */ + +# if !defined(CONFIG_STR71X_BANK0_WAITSTATES) || \ + CONFIG_STR71X_BANK0_WAITSTATES < 0 || CONFIG_STR71X_BANK0_WAITSTATES > 15 +# error "CONFIG_STR71X_BANK0_WAITSTATES invalid" +# else + /* Bits 2-5: wait states */ +# define EXTMEM_BANK0_WAITSTATES (CONFIG_STR71X_BANK0_WAITSTATES << 2) +# endif + + ldr \value, =(STR71X_EMIBCON_ENABLE|EXTMEM_BANK0_WAITSTATES|EXTMEM_BANK0_SIZE) +#else + mov \value, #0 +#endif + str \value, [\base, #STR71X_EMI_BCON0_OFFSET] + + /* Enable bank 1 */ + +#ifdef CONFIG_STR71X_BANK1 + + /* Get the bank 1 size */ + +# if CONFIG_STR71X_BANK1_SIZE == 8 +# define EXTMEM_BANK1_SIZE STR71X_EMIBCON_BSIZE8 +# elif CONFIG_STR71X_BANK1_SIZE == 16 +# define EXTMEM_BANK1_SIZE STR71X_EMIBCON_BSIZE16 +# else +# error "CONFIG_STR71X_BANK1_SIZE invalid" +# endif + + /* Get the bank 1 waitstates */ + +# if !defined(CONFIG_STR71X_BANK1_WAITSTATES) || \ + CONFIG_STR71X_BANK1_WAITSTATES < 0 || CONFIG_STR71X_BANK1_WAITSTATES > 15 +# error "CONFIG_STR71X_BANK1_WAITSTATES invalid" +# else + /* Bits 2-5: wait states */ +# define EXTMEM_BANK1_WAITSTATES (CONFIG_STR71X_BANK1_WAITSTATES << 2) +# endif + + ldr \value, =(STR71X_EMIBCON_ENABLE|EXTMEM_BANK1_WAITSTATES|EXTMEM_BANK1_SIZE) +#else + mov \value, #0 +#endif + str \value, [\base, #STR71X_EMI_BCON1_OFFSET] + + /* Enable bank 2 */ + +#ifdef CONFIG_STR71X_BANK2 + + /* Get the bank 2 size */ + +# if CONFIG_STR71X_BANK2_SIZE == 8 +# define EXTMEM_BANK2_SIZE STR71X_EMIBCON_BSIZE8 +# elif CONFIG_STR71X_BANK2_SIZE == 16 +# define EXTMEM_BANK2_SIZE STR71X_EMIBCON_BSIZE16 +# else +# error "CONFIG_STR71X_BANK2_SIZE invalid" +# endif + + /* Get the bank 2 waitstates */ + +# if !defined(CONFIG_STR71X_BANK2_WAITSTATES) || \ + CONFIG_STR71X_BANK2_WAITSTATES < 2 || CONFIG_STR71X_BANK2_WAITSTATES > 15 +# error "CONFIG_STR71X_BANK2_WAITSTATES invalid" +# else + /* Bits 2-5: wait states */ +# define EXTMEM_BANK2_WAITSTATES (CONFIG_STR71X_BANK2_WAITSTATES << 2) +# endif + + ldr \value, =(STR71X_EMIBCON_ENABLE|EXTMEM_BANK2_WAITSTATES|EXTMEM_BANK2_SIZE) +#else + mov \value, #0 +#endif + str \value, [\base, #STR71X_EMI_BCON2_OFFSET] + + /* Enable bank 3 */ + +#ifdef CONFIG_STR71X_BANK3 + + /* Get the bank 3 size */ + +# if CONFIG_STR71X_BANK3_SIZE == 8 +# define EXTMEM_BANK3_SIZE STR71X_EMIBCON_BSIZE8 +# elif CONFIG_STR71X_BANK3_SIZE == 16 +# define EXTMEM_BANK3_SIZE STR71X_EMIBCON_BSIZE16 +# else +# error "CONFIG_STR71X_BANK3_SIZE invalid" +# endif + + /* Get the bank 3 waitstates */ + +# if !defined(CONFIG_STR71X_BANK3_WAITSTATES) || \ + CONFIG_STR71X_BANK3_WAITSTATES < 3 || CONFIG_STR71X_BANK3_WAITSTATES > 15 +# error "CONFIG_STR71X_BANK3_WAITSTATES invalid" +# else + /* Bits 2-5: wait states */ +# define EXTMEM_BANK3_WAITSTATES (CONFIG_STR71X_BANK3_WAITSTATES << 2) +# endif + + ldr \value, =(STR71X_EMIBCON_ENABLE|EXTMEM_BANK3_WAITSTATES|EXTMEM_BANK3_SIZE) +#else + mov \value, #0 +#endif + str \value, [\base, #STR71X_EMI_BCON3_OFFSET] +#endif + .endm + +/***************************************************************************** + * Name: eicinit + * + * Description: + * The EIC is initialized for use with NuttX. This initialization does not + * take advantage of the high performance capabilities of the EIC. Instead, + * The EIC is only used to to provide NuttX IRQ numbers. Here is what is + * done: + * + * IRQs and FIQs are disabled + * IVR set to zero + * All channels are disabled + * Channels set to priority 0 + * All SIR[n] registers contain the NuttX IRQ number in the MS 16-bits + * + * At the time of IRQ processing, the IVR will contain the decoded IRQ + * number needed by NuttX. + * + *****************************************************************************/ + + .macro eicinit, eicbase, value, irqno, offset + /* Disable and clear all interrupts */ + + ldr \eicbase, =STR71X_EIC_BASE + + /* Disable FIQ and IRQ */ + + mov \value, #0 + str \value, [\eicbase, #STR71X_EIC_ICR_OFFSET] + + /* Disable all channel interrupts */ + + str \value, [\eicbase, #STR71X_EIC_IER_OFFSET] + + /* Clear all pending IRQs */ + + ldr \value, =0xffffffff + str \value, [\eicbase, #STR71X_EIC_IPR_OFFSET] + + /* Disable FIQ channels/clear pending FIQs */ + + mov \value, #0x0c + str \value, [\eicbase, #STR71X_EIC_FIR_OFFSET] + + /* Reset the current priority register */ + + mov \value, #0 + str \value, [\eicbase, #STR71X_EIC_CIPR_OFFSET] + + /* Zero IVR 31:16 */ + + str \value, [\eicbase, #STR71X_EIC_IVR_OFFSET] + + /* Set up the loop to initialize each SIR register. Start + * with IRQ number 0 and SIR0 + */ + + mov \irqno, #0 + ldr \offset, =STR71X_EIC_SIR_OFFSET + + /* Then loop for each EIC channel */ +eicloop: + /* Shift the IRQ number to bits 16-31 and save the shifted IRQ + * number as SIR[irqno]. This will appear as bits 0:15 in the + * IVR during IRQ processing. + * + * NOTE that the initial priority is set to zero -- the current + * interrupt priority (CIP) is always zero, so these interrupts + * are all disabled. + */ + + mov \value, \irqno, lsl #16 + str \value, [\eicbase, \offset] + + /* Increment the offset to the next SIR register and inrement + * the IRQ number. + */ + + add \offset, \offset, #4 + add \irqno, \irqno, #1 + + /* Continue to loop until all of the SIR registers have been + * initializeed. + */ + + cmp \irqno, #STR71X_EIC_NCHANNELS + blt eicloop + .endm + +/***************************************************************************** + * Name: periphinit + * + * Description" + * Disable all perfipherals (except EIC) + * + *****************************************************************************/ + + .macro periphinit, value, base1, base2 +#ifndef CONFIG_STR71X_DISABLE_PERIPHINIT + /* Set up APB1 and APB2 addresses */ + + ldr \base1, =STR71X_APB1_BASE + ldr \base2, =STR71X_APB2_BASE + + /* Disable all APB1 peripherals */ + + ldr \value, =STR71X_APB1_APB1ALL + strh \value, [\base1, #STR71X_APB_CKDIS_OFFSET] + + /* Disable all(or most) APB2 peripherals */ + + ldr \value, =(STR71X_APB2_APB2ALL & ~STR71X_APB2_EIC) + strh \value, [\base2, #STR71X_APB_CKDIS_OFFSET] + + /* Allow EMI and USB */ + + ldr \base1, =STR71X_RCCU_BASE +#ifdef CONFIG_STR71X_USB + ldr \value, =(STR71X_RCCUPER_EMI|STR71X_RCCUPER_USBKERNEL) +#else + ldr \value, =STR71X_RCCUPER_EMI +#endif + strh \value, [\base1, #STR71X_RCCU_PER_OFFSET] +#endif + .endm + +/***************************************************************************** + * Name: remap + * + * Description: + * Remap memory at address 0x0000000 to either FLASH. The system always + * boots at Bank0, sector 0 of FLASH. Part of the initial setup will be to + * map the memory appropriately for the execution configuration. Various + * options are possible, but only boot from FLASH is currently supported. + * + *****************************************************************************/ + + .macro remap, base, value + + /* Read the PCU BOOTCR register */ + + ldr \base, =STR71X_PCU_BASE + ldrh \value, [\base, #STR71X_PCU_BOOTCR_OFFSET] + + /* Mask out the old boot mode bits and set the boot mode to FLASH */ + + bic \value, \value, #STR71X_PCUBOOTCR_BOOTMASK + orr \value, \value, #STR71X_PCUBOOTCR_BMFLASH + + /* Save the modified BOOTCR register */ + + strh \value, [\base, #STR71X_PCU_BOOTCR_OFFSET] + .endm + +/***************************************************************************** + * Text + *****************************************************************************/ + + .text + +/***************************************************************************** + * Name: _vector_table + * + * Description: + * Interrrupt vector table. This must be located at the beginning + * of the memory space (at the beginning FLASH which will be mapped to + * address 0x00000000). The first entry in the vector table is the reset + * vector and this is the code that will execute whn the processor is reset. + * + *****************************************************************************/ + + .globl _vector_table + .type _vector_table, %function +_vector_table: + ldr pc, .Lresethandler /* 0x00: Reset */ + ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ + ldr pc, .Lswihandler /* 0x08: Software interrupt */ + ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ + ldr pc, .Ldataaborthandler /* 0x10: Data abort */ + .long 0 /* 0x14: Reserved vector */ + ldr pc, .Lirqhandler /* 0x18: IRQ */ + ldr pc, .Lfiqhandler /* 0x1c: FIQ */ + + .globl __start + .globl up_vectorundefinsn + .globl up_vectorswi + .globl up_vectorprefetch + .globl up_vectordata + .globl up_vectorirq + .globl up_vectorfiq + +.Lresethandler: + .long __start +.Lundefinedhandler: + .long up_vectorundefinsn +.Lswihandler: + .long up_vectorswi +.Lprefetchaborthandler: + .long up_vectorprefetch +.Ldataaborthandler: + .long up_vectordata +.Lirqhandler: + .long up_vectorirq +.Lfiqhandler: + .long up_vectorfiq + .size _vector_table, . - _vector_table + +/***************************************************************************** + * Name: __start + * + * Description: + * Reset entry point. This is the first function to execute when + * the processor is reset. It initializes hardware and then gives + * control to NuttX. + * + *****************************************************************************/ + + .global __start + .type __start, #function + +__start: + /* On reset, an aliased copy of FLASH is mapped to address 0x00000000. + * Continue execution in the 'real' FLASH address space rather than + * the aliased copy + */ + + ldr pc, =__flashstart +__flashstart: + .rept 9 + nop /* Wait for OSC stabilization */ + .endr + + /* Setup the initial processor mode */ + + mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT ) + msr cpsr, r0 + + /* Initialize the external memory interface (EMI) */ + + emiinit r0, r1 + + /* Initialize the enhanced interrupt controller (EIC) */ + + eicinit r0, r1, r2, r3 + + /* Disable all peripherals except EIC */ + + periphinit r0, r1, r2 + + /* Map memory appropriately for configuration */ + + remap r0, r1 + + /* Setup system stack (and get the BSS range) */ + + adr r0, LC0 + ldmia r0, {r4, r5, sp} + + /* Clear system BSS section */ + + mov r0, #0 +1: cmp r4, r5 + strcc r0, [r4], #4 + bcc 1b + + /* Copy system .data sections from FLASH to new home in RAM. */ + + adr r3, LC2 + ldmia r3, {r0, r1, r2} + +2: ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 2b + + /* Initialize clocking */ + + bl str71x_prccuinit + + /* Configure the uart so that we can get debug output as soon + * as possible. + */ + + bl up_lowsetup + showprogress 'A' + + /* Perform early serial initialization */ + + mov fp, #0 +#ifdef USE_EARLYSERIALINIT + bl up_earlyserialinit +#endif + + showprogress 'B' + + /* Call C++ constructors */ + +#ifdef CONFIG_CPLUSPLUS + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ +ctor_loop: + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + mov pc, r2 + ldmfd sp!, {r0-r1} + b ctor_loop +ctor_end: + + showprogress 'C' +#endif + showprogress '\n' + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + bl board_autoled_initialize +#endif + + /* Then jump to OS entry */ + + b os_start + + /* Call destructors -- never get here */ + +#if 0 /* CONFIG_CPLUSPLUS */ + ldr r0, =__dtors_start__ + ldr r1, =__dtors_end__ +dtor_loop: + cmp r0, r1 + beq dtor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + mov pc, r2 + ldmfd sp!, {r0-r1} + b dtor_loop +dtor_end: +#endif + + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_IDLETHREAD_STACKSIZE. The heap continues + * from there until the end of memory. See g_idle_topstack + * below. + */ + +LC0: .long _sbss + .long _ebss + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +LC2: .long _eronly /* Where .data defaults are stored in FLASH */ + .long _sdata /* Where .data needs to reside in SDRAM */ + .long _edata + .size __start, .-__start + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to LCO + * above. + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/str71x/str71x_i2c.h b/arch/arm/src/str71x/str71x_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..39fb03b1a29f532287b829f51a97839dd462bacb --- /dev/null +++ b/arch/arm/src/str71x/str71x_i2c.h @@ -0,0 +1,153 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_i2c.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_I2C_H +#define __ARCH_ARM_SRC_STR71X_STR71X_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offets ******************************************************************/ + +#define STR71X_I2C_CR_OFFSET (0x0000) /* 8-bits wide */ +#define STR71X_I2C_SR1_OFFSET (0x0004) /* 8-bits wide */ +#define STR71X_I2C_SR2_OFFSET (0x0008) /* 8-bits wide */ +#define STR71X_I2C_CCR_OFFSET (0x000c) /* 8-bits wide */ +#define STR71X_I2C_OAR1_OFFSET (0x0010) /* 8-bits wide */ +#define STR71X_I2C_OAR2_OFFSET (0x0014) /* 8-bits wide */ +#define STR71X_I2C_DR_OFFSET (0x0018) /* 8-bits wide */ +#define STR71X_I2C_ECCR_OFFSET (0x001c) /* 8-bits wide */ + +/* Registers ************************************************************************/ + +#define STR71X_I2C_CR(b) ((b) + STR71X_I2C_SR_OFFSET) +#define STR71X_I2C_SR1(b) ((b) + STR71X_I2C_SR1_OFFSET) +#define STR71X_I2C_SR2(b) ((b) + STR71X_I2C_SR2_OFFSET) +#define STR71X_I2C_CCR(b) ((b) + STR71X_I2C_CCR_OFFSET) +#define STR71X_I2C_OAR1(b) ((b) + STR71X_I2C_OAR1_OFFSET) +#define STR71X_I2C_OAR2(b) ((b) + STR71X_I2C_OAR2_OFFSET) +#define STR71X_I2C_DR(b) ((b) + STR71X_I2C_DR_OFFSET) +#define STR71X_I2C_ECCR(b) ((b) + STR71X_I2C_ECCR_OFFSET) + +#define STR71X_I2C0_CR (STR71X_I2C0_BASE + STR71X_I2C_SR_OFFSET) +#define STR71X_I2C0_SR1 (STR71X_I2C0_BASE + STR71X_I2C_SR1_OFFSET) +#define STR71X_I2C0_SR2 (STR71X_I2C0_BASE + STR71X_I2C_SR2_OFFSET) +#define STR71X_I2C0_CCR (STR71X_I2C0_BASE + STR71X_I2C_CCR_OFFSET) +#define STR71X_I2C0_OAR1 (STR71X_I2C0_BASE + STR71X_I2C_OAR1_OFFSET) +#define STR71X_I2C0_OAR2 (STR71X_I2C0_BASE + STR71X_I2C_OAR2_OFFSET) +#define STR71X_I2C0_DR (STR71X_I2C0_BASE + STR71X_I2C_DR_OFFSET) +#define STR71X_I2C0_ECCR (STR71X_I2C0_BASE + STR71X_I2C_ECCR_OFFSET) + +#define STR71X_I2C1_CR (STR71X_I2C1_BASE + STR71X_I2C_SR_OFFSET) +#define STR71X_I2C1_SR1 (STR71X_I2C1_BASE + STR71X_I2C_SR1_OFFSET) +#define STR71X_I2C1_SR2 (STR71X_I2C1_BASE + STR71X_I2C_SR2_OFFSET) +#define STR71X_I2C1_CCR (STR71X_I2C1_BASE + STR71X_I2C_CCR_OFFSET) +#define STR71X_I2C1_OAR1 (STR71X_I2C1_BASE + STR71X_I2C_OAR1_OFFSET) +#define STR71X_I2C1_OAR2 (STR71X_I2C1_BASE + STR71X_I2C_OAR2_OFFSET) +#define STR71X_I2C1_DR (STR71X_I2C1_BASE + STR71X_I2C_DR_OFFSET) +#define STR71X_I2C1_ECCR (STR71X_I2C1_BASE + STR71X_I2C_ECCR_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* I2C Control Register (CR) */ + +#define STR71X_I2CCR_ITE (0x01) /* Bit 0: Interrupt enable */ +#define STR71X_I2CCR_STOP (0x02) /* Bit 1: Generation of a stop condition */ +#define STR71X_I2CCR_ACK (0x04) /* Bit 2: Acknowledge enable */ +#define STR71X_I2CCR_START (0x08) /* Bit 3: Generation of a start condition */ +#define STR71X_I2CCR_ENGC (0x10) /* Bit 4: Enable general call */ +#define STR71X_I2CCR_PE (0x20) /* Bit 5: Peripheral enable */ + +/* I2C Status Register 1 (SR1) */ + +#define STR71X_I2CSR1_SB (0x01) /* Bit 0: Start bit (master mode) */ +#define STR71X_I2CSR1_MSL (0x02) /* Bit 1: Master/slave */ +#define STR71X_I2CSR1_ADSL (0x04) /* Bit 2: Address matched */ +#define STR71X_I2CSR1_BTF (0x08) /* Bit 3: Byte transfer finished */ +#define STR71X_I2CSR1_BUSY (0x10) /* Bit 4: Bus busy */ +#define STR71X_I2CSR1_TRA (0x20) /* Bit 5: Transmitter/receiver */ +#define STR71X_I2CSR1_ADD10 (0x40) /* Bit 6: 10-bit addressing in master mode */ +#define STR71X_I2CSR1_EVF (0x80) /* Bit 7: Event flag */ + +/* I2C Status Register 2 (SR2) */ + +#define STR71X_I2CSR2_GCAL (0x01) /* Bit 0: General call (slave mode) */ +#define STR71X_I2CSR2_BERR (0x02) /* Bit 1: Bus error */ +#define STR71X_I2CSR2_ARLO (0x04) /* Bit 2: Arbitration lost */ +#define STR71X_I2CSR2_STOPF (0x08) /* Bit 3: Stop detection (slave mode) */ +#define STR71X_I2CSR2_AF (0x10) /* Bit 4: Acknowledge failure */ +#define STR71X_I2CSR2_ENDAD (0x20) /* Bit 5: End of address transmission */ + +/* I2C Clock Control Register (CCR) */ + +#define STR71X_I2CCCR_DIVMASK (0x7f) /* Bits 0-6: 7 bits of the 12-bit clock divider */ +#define STR71X_I2CCCR_FMSM (0x80) /* Bit 7: Fast/standard I2C mode */ + +/* I2C Extended Clock Control Register (ECCR) */ + +#define STR71X_I2CECCR_DIVMASK (0x1f) /* Bits 0-5: 5 bits of the 12-bit clock divider */ + +/* I2C Own Address Register 2 (OAR2) */ + +#define STR71X_I2COAR2_ADDRMASK (0x06) /* Bits 1-2: 2 bits of the 10-bit interface address */ +#define STR71X_I2COAR2_FREQMASK (0xe0) /* Bits 5-7: Frequency */ +#define STR71X_I2COAR2_5_10 (0x00) /* FPCLK1 = 5 to 10 */ +#define STR71X_I2COAR2_10_16 (0x20) /* FPCLK1 = 10 to 16.67 */ +#define STR71X_I2COAR2_16_26 (0x40) /* FPCLK1 = 16.67 to 26.67 */ +#define STR71X_I2COAR2_26_40 (0x60) /* FPCLK1 = 26.67 to 40 */ +#define STR71X_I2COAR2_40_53 (0x80) /* FPCLK1 = 40 to 53.33 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_I2C_H */ diff --git a/arch/arm/src/str71x/str71x_irq.c b/arch/arm/src/str71x/str71x_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..314ea525950e84aeca2944dc8a62c9c82494cd1a --- /dev/null +++ b/arch/arm/src/str71x/str71x_irq.c @@ -0,0 +1,223 @@ +/**************************************************************************** + * arch/arm/src/st71x/st71x_irq.c + * + * Copyright (C) 2008-2009, 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "arm.h" +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "str71x.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* The bulk of IRQ initialization if performed in str71x_head.S, so we + * have very little to do here -- basically just enabling interrupts; + * + * Enable IRQs (but not FIQs -- they aren't used) + */ + + putreg32(STR71X_EICICR_IRQEN, STR71X_EIC_ICR); + + /* This shouldn't be necessary, but it appears that something is needed + * here to prevent spurious interrupts when the ARM interrupts are enabled + * (Needs more investigation). + */ + + up_mdelay(50); /* Wait a bit */ +#if 0 + putreg32(0, STR71X_EIC_IER); /* Make sure that all interrupts are disabled */ + putreg32(0xffffffff, STR71X_EIC_IPR); /* And that no interrupts are pending */ +#endif + + /* Initialize external interrupts */ + + str71x_xtiinitialize(); + + /* Enable global ARM interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uint32_t reg32; + + if ((unsigned)irq < STR71X_NBASEIRQS) + { + /* Mask the IRQ by clearing the associated bit in the IER register */ + + reg32 = getreg32(STR71X_EIC_IER); + reg32 &= ~(1 << irq); + putreg32(reg32, STR71X_EIC_IER); + } +#ifdef CONFIG_STR71X_XTI + else if ((unsigned)irq < NR_IRQS) + { + str71x_disable_xtiirq(irq); + } +#endif /* CONFIG_STR71X_XTI */ +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uint32_t reg32; + + if ((unsigned)irq < STR71X_NBASEIRQS) + { + /* Enable the IRQ by setting the associated bit in the IER register */ + + reg32 = getreg32(STR71X_EIC_IER); + reg32 |= (1 << irq); + putreg32(reg32, STR71X_EIC_IER); + } +#ifdef CONFIG_STR71X_XTI + else if ((unsigned)irq < NR_IRQS) + { + str71x_enable_xtiirq(irq); + } +#endif /* CONFIG_STR71X_XTI */ +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt. No XTI support.. only used in interrupt + * handling logic. + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + uint32_t reg32; + + if ((unsigned)irq < STR71X_NBASEIRQS) + { + /* Clear the interrupt by writing a one to the corresponding bit in the + * IPR register. + */ + + reg32 = getreg32(STR71X_EIC_IPR); + reg32 |= (1 << irq); + putreg32(reg32, STR71X_EIC_IPR); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set interrupt priority. Note, there is no way to prioritize + * individual XTI interrupts. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t addr; + uint32_t reg32; + + /* The current interrupt priority (CIP) is always zero, so a minimum prioriy + * of one is enforced to prevent disabling the interrupt. + */ + + if ((unsigned)irq < STR71X_NBASEIRQS && priority > 0 && priority < 16) + { + addr = STR71X_EIC_SIR(irq); + reg32 = getreg32(addr); + reg32 &= ~STR71X_EICSIR_SIPLMASK; + reg32 |= priority; + putreg32(reg32, addr); + return OK; + } + + return -EINVAL; +} +#endif + diff --git a/arch/arm/src/str71x/str71x_lowputc.c b/arch/arm/src/str71x/str71x_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..aa569d7fd9cfe007175a11c4b1e02a7122753b0c --- /dev/null +++ b/arch/arm/src/str71x/str71x_lowputc.c @@ -0,0 +1,324 @@ +/**************************************************************************** + * arch/arm/src/str71x/str71x_lowputc.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "str71x.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* Is there a UART enabled? */ + +#if defined(CONFIG_STR71X_UART0) || defined(CONFIG_STR71X_UART1) || \ + defined(CONFIG_STR71X_UART2) || defined(CONFIG_STR71X_UART3) +# define HAVE_UART 1 + +/* Is there a serial console? */ + +# if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE) ||\ + defined(CONFIG_UART2_SERIAL_CONSOLE) || defined(CONFIG_UART3_SERIAL_CONSOLE) +# define HAVE_CONSOLE +# else +# undef HAVE_CONSOLE +# endif + +#else +# undef HAVE_UART +# undef HAVE_CONSOLE +#endif + +/* GPIO0 UART configuration bits. For each enabled UART: + * + * TX needs to be configured for alternate function, push-pull {1, 1, 1} + * RX needs to be configured for input, tristate, cmos {0, 1, 0} + */ + +#ifdef CONFIG_STR71X_UART0 +# define STR71X_UART0_GPIO0_MASK (0x0300) /* P0.8->U0.TX, B0.9->U0.RX */ +# define STR71X_UART0_GPIO0_PC0BITS (0x0200) +# define STR71X_UART0_GPIO0_PC1BITS (0x0300) +# define STR71X_UART0_GPIO0_PC2BITS (0x0200) +#else +# define STR71X_UART0_GPIO0_MASK (0) +# define STR71X_UART0_GPIO0_PC0BITS (0) +# define STR71X_UART0_GPIO0_PC1BITS (0) +# define STR71X_UART0_GPIO0_PC2BITS (0) +#endif + +#ifdef CONFIG_STR71X_UART1 +# define STR71X_UART1_GPIO0_MASK (0x0c00) /* P0,10->U1.RX, P0.11->U1.TX */ +# define STR71X_UART1_GPIO0_PC0BITS (0x0800) +# define STR71X_UART1_GPIO0_PC1BITS (0x0c00) +# define STR71X_UART1_GPIO0_PC2BITS (0x0800) +#else +# define STR71X_UART1_GPIO0_MASK (0) +# define STR71X_UART1_GPIO0_PC0BITS (0) +# define STR71X_UART1_GPIO0_PC1BITS (0) +# define STR71X_UART1_GPIO0_PC2BITS (0) +#endif + +#ifdef CONFIG_STR71X_UART2 +# define STR71X_UART2_GPIO0_MASK (0x6000) /* P0.13->U2.RX, P0.14>U2.TX */ +# define STR71X_UART2_GPIO0_PC0BITS (0x4000) +# define STR71X_UART2_GPIO0_PC1BITS (0x6000) +# define STR71X_UART2_GPIO0_PC2BITS (0x4000) +#else +# define STR71X_UART2_GPIO0_MASK (0) +# define STR71X_UART2_GPIO0_PC0BITS (0) +# define STR71X_UART2_GPIO0_PC1BITS (0) +# define STR71X_UART2_GPIO0_PC2BITS (0) +#endif + +#ifdef CONFIG_STR71X_UART3 +# define STR71X_UART3_GPIO0_MASK (0x0003) /* P0.0->U3.TX, P0.1->U3.RX */ +# define STR71X_UART3_GPIO0_PC0BITS (0x0001) +# define STR71X_UART3_GPIO0_PC1BITS (0x0003) +# define STR71X_UART3_GPIO0_PC2BITS (0x0001) +#else +# define STR71X_UART3_GPIO0_MASK (0) +# define STR71X_UART3_GPIO0_PC0BITS (0) +# define STR71X_UART3_GPIO0_PC1BITS (0) +# define STR71X_UART3_GPIO0_PC2BITS (0) +#endif + +#define STR71X_UART_GPIO0_MASK \ + (STR71X_UART0_GPIO0_MASK | STR71X_UART1_GPIO0_MASK | \ + STR71X_UART2_GPIO0_MASK | STR71X_UART3_GPIO0_MASK) +#define STR71X_UART_GPIO0_PC0BITS \ + (STR71X_UART0_GPIO0_PC0BITS | STR71X_UART1_GPIO0_PC0BITS | \ + STR71X_UART2_GPIO0_PC0BITS | STR71X_UART3_GPIO0_PC0BITS) +#define STR71X_UART_GPIO0_PC1BITS \ + (STR71X_UART0_GPIO0_PC1BITS | STR71X_UART1_GPIO0_PC1BITS | \ + STR71X_UART2_GPIO0_PC1BITS | STR71X_UART3_GPIO0_PC1BITS) +#define STR71X_UART_GPIO0_PC2BITS \ + (STR71X_UART0_GPIO0_PC2BITS | STR71X_UART1_GPIO0_PC2BITS | \ + STR71X_UART2_GPIO0_PC2BITS | STR71X_UART3_GPIO0_PC2BITS) + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define STR71X_UART_BASE STR71X_UART0_BASE +# define STR71X_UART_BAUD CONFIG_UART0_BAUD +# define STR71X_UART_BITS CONFIG_UART0_BITS +# define STR71X_UART_PARITY CONFIG_UART0_PARITY +# define STR71X_UART_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define STR71X_UART_BASE STR71X_UART1_BASE +# define STR71X_UART_BAUD CONFIG_UART1_BAUD +# define STR71X_UART_BITS CONFIG_UART1_BITS +# define STR71X_UART_PARITY CONFIG_UART1_PARITY +# define STR71X_UART_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define STR71X_UART_BASE STR71X_UART2_BASE +# define STR71X_UART_BAUD CONFIG_UART2_BAUD +# define STR71X_UART_BITS CONFIG_UART2_BITS +# define STR71X_UART_PARITY CONFIG_UART2_PARITY +# define STR71X_UART_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define STR71X_UART_BASE STR71X_UART3_BASE +# define STR71X_UART_BAUD CONFIG_UART3_BAUD +# define STR71X_UART_BITS CONFIG_UART3_BITS +# define STR71X_UART_PARITY CONFIG_UART3_PARITY +# define STR71X_UART_2STOP CONFIG_UART3_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get mode setting */ + +#if STR71X_UART_BITS == 7 +# if STR71X_UART_PARITY == 0 +# error "7-bits, no parity mode not supported" +# else +# define STR71X_UARTCR_MODE STR71X_UARTCR_MODE7BITP +# endif +#elif STR71X_UART_BITS == 8 +# if STR71X_UART_PARITY == 0 +# define STR71X_UARTCR_MODE STR71X_UARTCR_MODE8BIT +# else +# define STR71X_UARTCR_MODE STR71X_UARTCR_MODE8BITP +# endif +#elif STR71X_UART_BITS == 9 +# if STR71X_UART_PARITY == 0 +# define STR71X_UARTCR_MODE STR71X_UARTCR_MODE9BIT +# else +# error "9-bits with parity not supported" +# endif +#else +# error "Number of bits not supported" +#endif + +#if STR71X_UART_PARITY == 0 || STR71X_UART_PARITY == 2 +# define STR71X_UARTCR_PARITY (0) +#elif STR71X_UART_PARITY == 1 +# define STR71X_UARTCR_PARITY STR71X_UARTCR_PARITYODD +#else +# error "Invalid parity selection" +#endif + +#if STR71X_UART_2STOP != 0 +# define STR71X_UARTCR_STOP STR71X_UARTCR_STOPBIT20 +#else +# define STR71X_UARTCR_STOP STR71X_UARTCR_STOPBIT10 +#endif + +#define STR71X_UARTCR_VALUE \ + (STR71X_UARTCR_MODE | STR71X_UARTCR_PARITY | STR71X_UARTCR_STOP | \ + STR71X_UARTCR_RUN | STR71X_UARTCR_RXENABLE | STR71X_UARTCR_FIFOENABLE) + +/* Calculate BAUD rate from PCLK1: + * + * Example: + * PCLK1 = 32MHz + * STR71X_UART_BAUD = 38,400 + * UART_BAUDRATE_DIVISOR = 614,400 + * UART_BAUDRATE = 52.583 (exact) or 52 truncated (1.1% error) + */ + +#define UART_BAUDDIVISOR (16 * STR71X_UART_BAUD) +#define UART_BAUDRATE ((STR71X_PCLK1 + (UART_BAUDDIVISOR/2)) / UART_BAUDDIVISOR) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + /* Wait until the TX FIFO is not full */ + + while ((getreg16(STR71X_UART_SR(STR71X_UART_BASE)) & STR71X_UARTSR_TF) != 0); + + /* Then send the character */ + + putreg16((uint16_t)ch, STR71X_UART_TXBUFR(STR71X_UART_BASE)); +#endif +} + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowsetup(void) +{ +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + + uint16_t reg16; + + /* Enable the selected console device */ + /* Set the UART baud rate */ + + putreg16((uint16_t)UART_BAUDRATE, STR71X_UART_BR(STR71X_UART_BASE)); + + /* Configure the UART control registers */ + + putreg16(STR71X_UARTCR_VALUE, STR71X_UART_CR(STR71X_UART_BASE)); + + /* Clear FIFOs */ + + putreg16(0, STR71X_UART_TXRSTR(STR71X_UART_BASE)); + putreg16(0, STR71X_UART_RXRSTR(STR71X_UART_BASE)); +#endif + + /* Configure GPIO0 pins to enable all UARTs in the configuration + * (the serial driver later depends on this configuration) + */ + +#ifdef HAVE_UART + reg16 = getreg16(STR71X_GPIO0_PC0); + reg16 &= ~STR71X_UART_GPIO0_MASK; + reg16 |= STR71X_UART_GPIO0_PC0BITS; + putreg16(reg16, STR71X_GPIO0_PC0); + + reg16 = getreg16(STR71X_GPIO0_PC1); + reg16 &= ~STR71X_UART_GPIO0_MASK; + reg16 |= STR71X_UART_GPIO0_PC1BITS; + putreg16(reg16, STR71X_GPIO0_PC1); + + reg16 = getreg16(STR71X_GPIO0_PC2); + reg16 &= ~STR71X_UART_GPIO0_MASK; + reg16 |= STR71X_UART_GPIO0_PC2BITS; + putreg16(reg16, STR71X_GPIO0_PC2); +#endif +} + + diff --git a/arch/arm/src/str71x/str71x_map.h b/arch/arm/src/str71x/str71x_map.h new file mode 100644 index 0000000000000000000000000000000000000000..bc832e75858a318bb15eb7defaa6b6e0ade58a20 --- /dev/null +++ b/arch/arm/src/str71x/str71x_map.h @@ -0,0 +1,99 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_map.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_MAP_H +#define __ARCH_ARM_SRC_STR71X_STR71X_MAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ + +#define STR71X_FLASHRAMEMI_BASE (0x00000000) /* Flash alias for booting */ +#define STR71X_RAM_BASE (0x20000000) +#define STR71X_FLASH_BASE (0x40000000) +#define STR71X_FLASHREG_BASE (0x40100000) +#define STR71X_EXTMEM_BASE (0x60000000) +#define STR71X_EMI_BASE (STR71X_EXTMEM_BASE + 0x0c000000) +#define STR71X_RCCU_BASE (0xa0000000) +#define STR71X_PCU_BASE (0xa0000040) +#define STR71X_APB1_BASE (0xc0000000) +#define STR71X_I2C0_BASE (STR71X_APB1_BASE + 0x1000) +#define STR71X_I2C1_BASE (STR71X_APB1_BASE + 0x2000) +#define STR71X_UART0_BASE (STR71X_APB1_BASE + 0x4000) +#define STR71X_UART1_BASE (STR71X_APB1_BASE + 0x5000) +#define STR71X_UART2_BASE (STR71X_APB1_BASE + 0x6000) +#define STR71X_UART3_BASE (STR71X_APB1_BASE + 0x7000) +#define STR71X_USBRAM_BASE (STR71X_APB1_BASE + 0x8000) +#define STR71X_USB_BASE (STR71X_APB1_BASE + 0x8800) +#define STR71X_CAN_BASE (STR71X_APB1_BASE + 0x9000) +#define STR71X_BSPI0_BASE (STR71X_APB1_BASE + 0xa000) +#define STR71X_BSPI1_BASE (STR71X_APB1_BASE + 0xb000) +#define STR71X_HDLCRAM_BASE (STR71X_APB1_BASE + 0xe000) +#define STR71X_APB2_BASE (0xe0000000) +#define STR71X_XTI_BASE (STR71X_APB2_BASE + 0x1000) +#define STR71X_GPIO0_BASE (STR71X_APB2_BASE + 0x3000) +#define STR71X_GPIO1_BASE (STR71X_APB2_BASE + 0x4000) +#define STR71X_GPIO2_BASE (STR71X_APB2_BASE + 0x5000) +#define STR71X_ADC12_BASE (STR71X_APB2_BASE + 0x7000) +#define STR71X_CLKOUT_BASE (STR71X_APB2_BASE + 0x8000) +#define STR71X_TIMER0_BASE (STR71X_APB2_BASE + 0x9000) +#define STR71X_TIMER1_BASE (STR71X_APB2_BASE + 0xa000) +#define STR71X_TIMER2_BASE (STR71X_APB2_BASE + 0xb000) +#define STR71X_TIMER3_BASE (STR71X_APB2_BASE + 0xc000) +#define STR71X_RTC_BASE (STR71X_APB2_BASE + 0xd000) +#define STR71X_WDOG_BASE (STR71X_APB2_BASE + 0xe000) +#define STR71X_EIC_BASE (0xfffff800) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif // __ARCH_ARM_SRC_STR71X_STR71X_MAP_H diff --git a/arch/arm/src/str71x/str71x_pcu.h b/arch/arm/src/str71x/str71x_pcu.h new file mode 100644 index 0000000000000000000000000000000000000000..526805017c331906e1161f319149e6f282901496 --- /dev/null +++ b/arch/arm/src/str71x/str71x_pcu.h @@ -0,0 +1,159 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_pcu.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_PCU_H +#define __ARCH_ARM_SRC_STR71X_STR71X_PCU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Power Control Unit (PCU) register offsets ****************************************/ + +#define STR71X_PCU_MDIVR_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_PCU_PDIVR_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_PCU_RSTR_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_PCU_PLL2CR_OFFSET (0x000c) /* 16-bits wide */ +#define STR71X_PCU_BOOTCR_OFFSET (0x0010) /* 16-bits wide */ +#define STR71X_PCU_PWRCR_OFFSET (0x0014) /* 16-bits wide */ + +/* Power Control Unit (PCU) register addresses **************************************/ + +#define STR71X_PCU_MDIVR (STR71X_PCU_BASE + STR71X_PCU_MDIVR_OFFSET) +#define STR71X_PCU_PDIVR (STR71X_PCU_BASE + STR71X_PCU_PDIVR_OFFSET) +#define STR71X_PCU_RSTR (STR71X_PCU_BASE + STR71X_PCU_RSTR_OFFSET) +#define STR71X_PCU_PLL2CR (STR71X_PCU_BASE + STR71X_PCU_PLL2CR_OFFSET) +#define STR71X_PCU_BOOTCR (STR71X_PCU_BASE + STR71X_PCU_BOOTCR_OFFSET) +#define STR71X_PCU_PWRCR (STR71X_PCU_BASE + STR71X_PCU_PWRCR_OFFSET) + +/* Register bit settings ************************************************************/ + +/* PCU MDIVR register bit definitions */ + +#define STR71X_PCUMDIVR_FACTMASK (0x0003) /* Bits 0-1: Division factor for main system clock */ +#define STR71X_PCUMDIVR_DIV1 (0x0000) /* MCLK = RCLK */ +#define STR71X_PCUMDIVR_DIV2 (0x0001) /* MCLK = RCLK / 2 */ +#define STR71X_PCUMDIVR_DIV4 (0x0002) /* MCLK = RCLK / 4 */ +#define STR71X_PCUMDIVR_DIV8 (0x0003) /* MCLK = RCLK / 8 */ + +/* PCU PDIVR register bit definitions */ + +#define STR71X_PCUPDIVR_FACT1MASK (0x0003) /* Bits 0-1: Division factor for APB1 peripherals */ +#define STR71X_PCUPDIVR_APB1DIV1 (0x0000) /* PCLK1 = RCLK */ +#define STR71X_PCUPDIVR_APB1DIV2 (0x0001) /* PCLK1 = RCLK / 2 */ +#define STR71X_PCUPDIVR_APB1DIV4 (0x0002) /* PCLK1 = RCLK / 4 */ +#define STR71X_PCUPDIVR_APB1DIV8 (0x0003) /* PCLK1 = RCLK / 8 */ +#define STR71X_PCUPDIVR_FACT2MASK (0x0300) /* Bits 8-9: Division factor for APB2 peripherals */ +#define STR71X_PCUPDIVR_APB2DIV1 (0x0000) /* PCLK2 = RCLK */ +#define STR71X_PCUPDIVR_APB2DIV2 (0x0100) /* PCLK2 = RCLK / 2 */ +#define STR71X_PCUPDIVR_APB2DIV4 (0x0200) /* PCLK2 = RCLK / 4 */ +#define STR71X_PCUPDIVR_APB2DIV8 (0x0300) /* PCLK2 = RCLK / 8 */ + +/* PCU RSTR register bit definitions */ + +#define STR71X_PCURSTR_EMIRESET (0x0004) /* Bit 2: EMI reset */ + +/* PCU PLL2CR register bit definitions */ + +#define STR71X_PCUPPL2CR_DXMASK (0x0007) /* Bits 0-2: PLL2 output clock divider */ +#define STR71X_PCUPPL2CR_DIV1 (0x0000) /* PLL2 / 1 */ +#define STR71X_PCUPPL2CR_DIV2 (0x0001) /* PLL2 / 2 */ +#define STR71X_PCUPPL2CR_DIV3 (0x0002) /* PLL2 / 3 */ +#define STR71X_PCUPPL2CR_DIV4 (0x0003) /* PLL2 / 4 */ +#define STR71X_PCUPPL2CR_DIV5 (0x0004) /* PLL2 / 5 */ +#define STR71X_PCUPPL2CR_DIV6 (0x0005) /* PLL2 / 6 */ +#define STR71X_PCUPPL2CR_DIV7 (0x0006) /* PLL2 / 7 */ +#define STR71X_PCUPPL2CR_OFF (0x0007) /* PLL2 OFF */ +#define STR71X_PCUPPL2CR_MXMASK (0x0030) /* Bits 4-5: PLL2 multiplier */ +#define STR71X_PCUPPL2CR_MUL20 (0x0000) /* CLK2 * 20 */ +#define STR71X_PCUPPL2CR_MUL12 (0x0010) /* CLK2 * 12 */ +#define STR71X_PCUPPL2CR_MUL28 (0x0020) /* CLK2 * 28 */ +#define STR71X_PCUPPL2CR_MUL16 (0x0030) /* CLK2 * 16 */ +#define STR71X_PCUPPL2CR_FRQRNG (0x0040) /* Bit 6: PLL2 frequency range selection */ +#define STR71X_PCUPPL2CR_PLLEN (0x0080) /* Bit 7: PLL2 enable */ +#define STR71X_PCUPPL2CR_USBEN (0x0100) /* Bit 8: Enable PLL clock to USB */ +#define STR71X_PCUPPL2CR_IRQMASK (0x0200) /* Bit 9: Enable interrupt request CPU on lock transition */ +#define STR71X_PCUPPL2CR_IRQPEND (0x0400) /* Bit 10: Interrtup request to CPU on lock transition pending */ +#define STR71X_PCUPPL2CR_LOCK (0x8000) /* Bit 15: PLL2 locked */ + +/* PCU BOOTCR register bit definitions */ + +#define STR71X_PCUBOOTCR_BOOTMASK (0x0003) /* Bits 0-1: Boot mode */ +#define STR71X_PCUBOOTCR_BMFLASH (0x0000) /* FLASH */ +#define STR71X_PCUBOOTCR_BMRAM (0x0002) /* RAM */ +#define STR71X_PCUBOOTCR_BMEXTMEM (0x0003) /* FLASH */ +#define STR71X_PCUBOOTCR_BSPIOEN (0x0004) /* Bit 2: Enable BSPI0 */ +#define STR71X_PCUBOOTCR_USBFILTEN (0x0008) /* Bit 3: Enable USB standby filtering */ +#define STR71X_PCUBOOTCR_LPOWDBGEN (0x0010) /* Bit 4: Enable reserved features for STOP mode */ +#define STR71X_PCUBOOTCR_ACDEN (0x0020) /* Bit 5: Enable ADC */ +#define STR71X_PCUBOOTCR_CANACTIVE (0x0040) /* Bit 6: CAN active */ +#define STR71X_PCUBOOTCR_HDLCACTIVE (0x0080) /* Bit 7: HDLC active */ +#define STR71X_PCUBOOTCR_PKG64 (0x0200) /* Bit 9: Die is hosted in 64-pin package */ + +/* PCU PWRCR register bit definitions */ + +#define STR71X_PCUPWRCR_VRBYP (0x0008) /* Bit 3: Main regulator bypass */ +#define STR71X_PCUPWRCR_LPRWFI (0x0010) /* Bit 4: Low power regulator in wait-for-interrupt mode */ +#define STR71X_PCUPWRCR_LPRBYP (0x0020) /* Bit 5: Low power regulator bypass */ +#define STR71X_PCUPWRCR_PWRDWN (0x0040) /* Bit 6: Activate standby mode */ +#define STR71X_PCUPWRCR_OSCBYP (0x0080) /* Bit 7: 32KHz oscillator bypass */ +#define STR71X_PCUPWRCR_LVDDIS (0x0100) /* Bit 8: Low voltage detector disable */ +#define STR71X_PCUPWRCR_FLASHLP (0x0200) /* Bit 9: FLASH low speed (low power) select */ +#define STR71X_PCUPWRCR_VROK (0x1000) /* Bit 12: Voltage regulator OK */ +#define STR71X_PCUPWRCR_WKUPALRM (0x2000) /* Bit 13: Wakeup or alarm active */ +#define STR71X_PCUPWRCR_BUSY (0x4000) /* Bit 14: PCU register backup logic busy */ +#define STR71X_PCUPWRCR_WREN (0x8000) /* Bit 15: PCU register write enable */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_PCU_H */ diff --git a/arch/arm/src/str71x/str71x_prccu.c b/arch/arm/src/str71x/str71x_prccu.c new file mode 100644 index 0000000000000000000000000000000000000000..0d9184cc2540ae052c11ff082b298882e93a3813 --- /dev/null +++ b/arch/arm/src/str71x/str71x_prccu.c @@ -0,0 +1,476 @@ +/******************************************************************************** + * arch/arm/src/str71x/str71x_prccu.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "str71x.h" + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/* Select set of peripherals to be enabled */ + +/* APB1 periperals */ + +#ifndef CONFIG_STR71X_I2C0 +# define APB1EN_I2C0 STR71X_APB1_I2C0 +#else +# define APB1EN_I2C0 (0) +#endif + +#ifndef CONFIG_STR71X_I2C1 +# define APB1EN_I2C1 STR71X_APB1_I2C1 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "I2C1 requires GPIO0" +# endif +# ifdef CONFIG_STR71X_BSPI0 +# error "I2C1 is incompatible with BSPI0" +# endif +# define APB1EN_I2C1 (0) +#endif + +#ifndef CONFIG_STR71X_UART0 +# define APB1EN_UART0 STR71X_APB1_UART0 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "CONFIG_STR71X_UART0 requires CONFIG_STR71X_GPIO0" +# endif +# define APB1EN_UART0 (0) +#endif + +#ifndef CONFIG_STR71X_UART1 +# define APB1EN_UART1 STR71X_APB1_UART1 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "CONFIG_STR71X_UART1 requires CONFIG_STR71X_GPIO0" +# endif +# define APB1EN_UART1 (0) +#endif + +#ifndef CONFIG_STR71X_UART2 +# define APB1EN_UART2 STR71X_APB1_UART2 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "CONFIG_STR71X_UART2 requires CONFIG_STR71X_GPIO0" +# endif +# define APB1EN_UART2 (0) +#endif + +#ifndef CONFIG_STR71X_UART3 +# define APB1EN_UART3 STR71X_APB1_UART3 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "UART3 requires GPIO0" +# endif +# ifdef CONFIG_STR71X_BSPI0 +# error "UART3 is incompatible with BSPI0" +# endif +# define APB1EN_UART3 (0) +#endif + +#ifndef CONFIG_STR71X_USB +# define APB1EN_USB STR71X_APB1_USB +#else +# define APB1EN_USB (0) +#endif + +#ifndef CONFIG_STR71X_CAN +# define APB1EN_CAN STR71X_APB1_CAN +#else +# define APB1EN_CAN (0) +#endif + +#ifndef CONFIG_STR71X_BSPI0 +# define APB1EN_BSPI0 STR71X_APB1_BSPI0 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "BSPI0 requires GPIO0" +# endif +# ifdef CONFIG_STR71X_UART3 +# error "BSPI0 is incompatible with UART3" +# endif +# ifdef CONFIG_STR71X_I2C1 +# error "BSPI0 is incompatible with I2C1" +# endif +# define APB1EN_BSPI0 (0) +#endif + +#ifndef CONFIG_STR71X_BSPI1 +# define APB1EN_BSPI1 STR71X_APB1_BSPI1 +#else +# ifndef CONFIG_STR71X_GPIO0 +# error "BSPI1 requires GPIO0" +# endif +# define APB1EN_BSPI1 (0) +#endif + +#ifndef CONFIG_STR71X_HDLC +# define APB1EN_HDLC STR71X_APB1_HDLC +#else +# define APB1EN_HDLC (0) +#endif + +#define APB1EN_ALL \ + (APB1EN_I2C0 | APB1EN_I2C1 | APB1EN_UART0 | APB1EN_UART1 | \ + APB1EN_UART2 | APB1EN_UART3 | APB1EN_USB | APB1EN_CAN | \ + APB1EN_BSPI0 | APB1EN_BSPI1 | APB1EN_HDLC) + +/* APB2 Peripherals */ + +#ifndef CONFIG_STR71X_XTI +# define APB2EN_XTI STR71X_APB2_XTI +#else +# define APB2EN_XTI (0) +#endif + +#ifndef CONFIG_STR71X_GPIO0 +# define APB2EN_GPIO0 STR71X_APB2_GPIO0 +#else +# define APB2EN_GPIO0 (0) +#endif + +#ifndef CONFIG_STR71X_GPIO1 +# define APB2EN_GPIO1 STR71X_APB2_GPIO1 +#else +# define APB2EN_GPIO1 (0) +#endif + +#ifndef CONFIG_STR71X_GPIO2 +# define APB2EN_GPIO2 STR71X_APB2_GPIO2 +#else +# define APB2EN_GPIO2 (0) +#endif + +#ifndef CONFIG_STR71X_ADC12 +# define APB2EN_ADC12 STR71X_APB2_ADC12 +#else +# define APB2EN_ADC12 (0) +#endif + +#ifndef CONFIG_STR71X_CKOUT +# define APB2EN_CKOUT STR71X_APB2_CKOUT +#else +# define APB2EN_CKOUT (0) +#endif + +#define APB2EN_TIM0 (0) /* System timer -- always enabled */ + +#ifndef CONFIG_STR71X_TIM1 +# define APB2EN_TIM1 STR71X_APB2_TIM1 +#else +# define APB2EN_TIM1 (0) +#endif + +#ifndef CONFIG_STR71X_TIM2 +# define APB2EN_TIM2 STR71X_APB2_TIM2 +#else +# define APB2EN_TIM2 (0) +#endif + +#ifndef CONFIG_STR71X_TIM3 +# define APB2EN_TIM3 STR71X_APB2_TIM3 +#else +# define APB2EN_TIM3 (0) +#endif + +#ifndef CONFIG_STR71X_RTC +# define APB2EN_RTC STR71X_APB2_RTC +#else +# define APB2EN_RTC (0) +#endif + +#define APB2EN_EIC (0) /* Interrupt controller always enabled */ + +#define APB2EN_ALL \ + (APB2EN_XTI | APB2EN_GPIO0 | APB2EN_GPIO1 | APB2EN_GPIO2 | \ + APB2EN_ADC12 | APB2EN_CKOUT | APB2EN_TIM0 | APB2EN_TIM1 | \ + APB2EN_TIM2 | APB2EN_TIM3 | APB2EN_RTC | APB2EN_EIC) + + +#if STR71X_PLL1OUT_MUL == 12 +# define PLL1MUL STR71X_RCCUPLL1CR_MUL12 +#elif STR71X_PLL1OUT_MUL == 16 +# define PLL1MUL STR71X_RCCUPLL1CR_MUL16 +#elif STR71X_PLL1OUT_MUL == 20 +# define PLL1MUL STR71X_RCCUPLL1CR_MUL20 +#elif STR71X_PLL1OUT_MUL == 24 +# define PLL1MUL STR71X_RCCUPLL1CR_MUL24 +#else +# error "Unsupporetd value for STR71X_PLL1OUT_MUL" +#endif + +#if STR71X_PLL1OUT_DIV == 1 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV1 +#elif STR71X_PLL1OUT_DIV == 2 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV2 +#elif STR71X_PLL1OUT_DIV == 3 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV3 +#elif STR71X_PLL1OUT_DIV == 4 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV4 +#elif STR71X_PLL1OUT_DIV == 5 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV5 +#elif STR71X_PLL1OUT_DIV == 6 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV6 +#elif STR71X_PLL1OUT_DIV == 7 +# define PLL1DIV STR71X_RCCUPLL1CR_DIV7 +#else +# error "Unsupported value for STR71X_PLL1OUT_DIV" +#endif + +#if STR71X_APB1_DIV == 1 +# define APB1DIV STR71X_PCUPDIVR_APB1DIV1 +#elif STR71X_APB1_DIV == 2 +# define APB1DIV STR71X_PCUPDIVR_APB1DIV2 +#elif STR71X_APB1_DIV == 4 +# define APB1DIV STR71X_PCUPDIVR_APB1DIV4 +#elif STR71X_APB1_DIV == 8 +# define APB1DIV STR71X_PCUPDIVR_APB1DIV8 +#else +# error "Unsupported value for STR71X_APB1_DIV" +#endif + +#if STR71X_APB2_DIV == 1 +# define APB2DIV STR71X_PCUPDIVR_APB2DIV1 +#elif STR71X_APB2_DIV == 2 +# define APB2DIV STR71X_PCUPDIVR_APB2DIV2 +#elif STR71X_APB2_DIV == 4 +# define APB2DIV STR71X_PCUPDIVR_APB2DIV4 +#elif STR71X_APB2_DIV == 8 +# define APB2DIV STR71X_PCUPDIVR_APB2DIV8 +#else +# error "Unsupported value for STR71X_APB2_DIV" +#endif + +#if STR71X_MCLK_DIV == 1 +# define MCLKDIV STR71X_PCUMDIVR_DIV1 +#elif STR71X_MCLK_DIV == 2 +# define MCLKDIV STR71X_PCUMDIVR_DIV2 +#elif STR71X_MCLK_DIV == 4 +# define MCLKDIV STR71X_PCUMDIVR_DIV4 +#elif STR71X_MCLK_DIV == 8 +# define MCLKDIV STR71X_PCUMDIVR_DIV8 +#else +# error "Unsupported value for STR71X_MCLK_DIV" +#endif + +#if STR71X_PLL2OUT_MUL == 12 +# define PLL2MUL STR71X_PCUPPL2CR_MUL12 +#elif STR71X_PLL2OUT_MUL == 16 +# define PLL2MUL STR71X_PCUPPL2CR_MUL16 +#elif STR71X_PLL2OUT_MUL == 20 +# define PLL2MUL STR71X_PCUPPL2CR_MUL20 +#elif STR71X_PLL2OUT_MUL == 28 +# define PLL2MUL STR71X_PCUPPL2CR_MUL28 +#else +# error "Unsupporetd value for STR71X_PLL2OUT_MUL" +#endif + +#if STR71X_PLL2OUT_DIV == 1 +# define PLL2DIV STR71X_PCUPPL2CR_DIV1 +#elif STR71X_PLL2OUT_DIV == 2 +# define PLL2DIV STR71X_PCUPPL2CR_DIV2 +#elif STR71X_PLL2OUT_DIV == 3 +# define PLL2DIV STR71X_PCUPPL2CR_DIV3 +#elif STR71X_PLL2OUT_DIV == 4 +# define PLL2DIV STR71X_PCUPPL2CR_DIV4 +#elif STR71X_PLL2OUT_DIV == 5 +# define PLL2DIV STR71X_PCUPPL2CR_DIV5 +#elif STR71X_PLL2OUT_DIV == 6 +# define PLL2DIV STR71X_PCUPPL2CR_DIV6 +#elif STR71X_PLL2OUT_DIV == 7 +# define PLL2DIV STR71X_PCUPPL2CR_DIV7 +#else +# error "Unsupported value for STR71X_PLL2OUT_DIV" +#endif + +/******************************************************************************** + * Private Types + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Public Funstions + ********************************************************************************/ + +/******************************************************************************** + * Name: str71x_prccuinit + * + * Description: + * Initialize the PCU/RCCU based on the NuttX configuration and the board-specific + * settings in board.h + * + ********************************************************************************/ + +void str71x_prccuinit(void) +{ + uint32_t reg32; + uint16_t reg16; + + /* Divide RCLK to obtain PCLK1 & 2 clock for the APB1 & 2 peripherals. The divider + * values are provided in board.h + */ + + reg16 = getreg16(STR71X_PCU_PDIVR); + reg16 &= ~(STR71X_PCUPDIVR_FACT1MASK | STR71X_PCUPDIVR_FACT2MASK); + reg16 |= (APB1DIV | APB2DIV); + putreg16(reg16, STR71X_PCU_PDIVR); + + /* Configure the main system clock (MCLK) divider with value from board.h */ + + reg16 = getreg16(STR71X_PCU_MDIVR); + reg16 &= ~STR71X_PCUMDIVR_FACTMASK; + reg16 |= MCLKDIV; + putreg16(reg16 , STR71X_PCU_MDIVR); + + /* Turn off the PLL1 by setting bits DX[2:0] */ + + putreg32(STR71X_RCCUPLL1CR_CLK2, STR71X_RCCU_PLL1CR); + + /* Configure the PLL1CR register using the provided multiplier and + * divider. The FREF_RANGE bit is also set if the input frequency + * (CLK2) is greater than 3MHz. + */ + +#if STR71X_CLK2 > 3000000 + putreg32(PLL1MUL | PLL1DIV, STR71X_RCCU_PLL1CR); +#else + putreg32(PLL1MUL | PLL1DIV | STR71X_RCCUPLL1CR_FREFRANGE, + STR71X_RCCU_PLL1CR); +#endif + + /* Wait for the PLL to lock */ + + while ((getreg16(STR71X_RCCU_CFR) & STR71X_RCCUCFR_LOCK) == 0); + + /* Set the CK2_16 Bit in the CFR to use CLK2/PLL1OUT as CLK3 */ + + reg32 = getreg32(STR71X_RCCU_CFR); + reg32 |= STR71X_RCCUCFR_CK216; + + /* Should the main oscillator divided down by 2? */ + +#ifdef STR71X_PLL1IN_DIV2 + reg32 |= STR71X_RCCUCFR_DIV2; +#else + reg32 &= ~STR71X_RCCUCFR_DIV2; +#endif + putreg32(reg32, STR71X_RCCU_CFR); + + /* Wait for the PLL to lock */ + + while ((getreg16(STR71X_RCCU_CFR) & STR71X_RCCUCFR_LOCK) == 0); + + /* Select CLK3 (vs the alternative source) for RCLK in the clock + * control register (CCR) + */ + + reg16 = getreg16(STR71X_RCCU_CCR); + reg16 &= ~STR71X_RCCUCCR_CKAFSEL; + putreg16(reg16, STR71X_RCCU_CCR); + + /* Select PLL1OUT as the CLK3 */ + + reg32 = getreg32(STR71X_RCCU_CFR); + putreg32(reg32 | STR71X_RCCUCFR_CSUCKSEL, STR71X_RCCU_CFR); + + /* Enable clocking on selected periperals */ + + putreg32(APB1EN_ALL, STR71X_APB1_CKDIS); + putreg32(APB2EN_ALL, STR71X_APB2_CKDIS); + + /* Configure PLL2 */ + +#if defined(CONFIG_STR71X_HDLC) || (defined(CONFIG_STR71X_USB) && defined(STR71X_USBIN_PLL2)) + reg16 = getreg16(STR71X_PCU_PLL2CR); + reg16 &= ~(STR71X_PCUPPL2CR_MXMASK | STR71X_PCUPPL2CR_DXMASK); + reg16 |= (PLL2MUL | PLL2DIV); + + /* Set the PLL2 FRQRNG bit according to the PLL2 input frequency */ + +#if STR71X_PCU_HCLK_OSC < 3000000 + reg16 &= ~STR71X_PCUPPL2CR_FRQRNG; +#else + reg16 |= STR71X_PCUPPL2CR_FRQRNG; +#endif + putreg16(reg16, STR71X_PCU_PLL2CR); + + /* Wait for PLL2 to lock in */ + // while ((getreg16(STR71X_PCU_PLL2CR) & STR71X_PCUPPL2CR_LOCK) == 0); +#endif + + /* Select the USB clock source */ + +#ifdef CONFIG_STR71X_USB + reg16 = getreg16(STR71X_PCU_PLL2CR); +#ifdef STR71X_USBIN_PLL2 + /* PLL2 is the clock source to the USB */ + + reg16 |= STR71X_PCUPPL2CR_USBEN; +#else + /* USBCLK pin is the clock source to the USB */ + + reg16 &= ~STR71X_PCUPPL2CR_USBEN; +#endif + putreg16(reg16, STR71X_PCU_PLL2CR); +#endif +} + + diff --git a/arch/arm/src/str71x/str71x_rccu.h b/arch/arm/src/str71x/str71x_rccu.h new file mode 100644 index 0000000000000000000000000000000000000000..4d2235cf34b223337b17b141f889b7dc97c2d81b --- /dev/null +++ b/arch/arm/src/str71x/str71x_rccu.h @@ -0,0 +1,143 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_rccu.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_RCCU_H +#define __ARCH_ARM_SRC_STR71X_STR71X_RCCU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Reset and Clock Control Unit (RCCU) register offsets *****************************/ + +/* All registers are 32-bits wide, but with the top 16 bits "reserved" */ + +#define STR71X_RCCU_CCR_OFFSET (0x0000) /* 32-bits wide */ +#define STR71X_RCCU_CFR_OFFSET (0x0008) /* 32-bits wide */ +#define STR71X_RCCU_PLL1CR_OFFSET (0x0018) /* 32-bits wide */ +#define STR71X_RCCU_PER_OFFSET (0x001c) /* 32-bits wide */ +#define STR71X_RCCU_SMR_OFFSET (0x0020) /* 32-bits wide */ + +/* Reset and Clock Control Unit (RCCU) register addresses ***************************/ + +#define STR71X_RCCU_CCR (STR71X_RCCU_BASE + STR71X_RCCU_CCR_OFFSET) +#define STR71X_RCCU_CFR (STR71X_RCCU_BASE + STR71X_RCCU_CFR_OFFSET) +#define STR71X_RCCU_PLL1CR (STR71X_RCCU_BASE + STR71X_RCCU_PLL1CR_OFFSET) +#define STR71X_RCCU_PER (STR71X_RCCU_BASE + STR71X_RCCU_PER_OFFSET) +#define STR71X_RCCU_SMR (STR71X_RCCU_BASE + STR71X_RCCU_SMR_OFFSET) + +/* Register bit settings ************************************************************/ + +/* RCCU CCR register bit definitions */ + +#define STR71X_RCCUCCR_LPOWFI (0x00000001) /* Bit 0: Low power mode in wait-for-interrupt mode */ +#define STR71X_RCCUCCR_WFICLKSEL (0x00000002) /* Bit 1: WFI clock select */ +#define STR71X_RCCUCCR_CKAFSEL (0x00000004) /* Bit 2: Alternate function clock select */ +#define STR71X_RCCUCCR_SRESEN (0x00000008) /* Bit 3: Software reset enable */ +#define STR71X_RCCUCCR_ENCLOCK (0x00000080) /* Bit 7: Lock interrupt enable */ +#define STR71X_RCCUCCR_ENCKAF (0x00000100) /* Bit 8: CKAF interrupt enable */ +#define STR71X_RCCUCCR_ENCK216 (0x00000200) /* Bit 9: CK2_16 interrupt enable */ +#define STR71X_RCCUCCR_ENSTOP (0x00000400) /* Bit 10: Stop interrupt enable */ +#define STR71X_RCCUCCR_ENHALT (0x00000800) /* Bit 11: Enable halt */ + +/* RCCU CFR register bit definitions */ + +#define STR71X_RCCUCFR_CSUCKSEL (0x00000001) /* Bit 0: CSU clock select */ +#define STR71X_RCCUCFR_LOCK (0x00000002) /* Bit 1: PLL locked-in */ +#define STR71X_RCCUCFR_CKAFST (0x00000004) /* Bit 2: CK_AF status */ +#define STR71X_RCCUCFR_CK216 (0x00000008) /* Bit 3: CLK2/16 selection */ +#define STR71X_RCCUCFR_CKSTOPEN (0x00000010) /* Bit 4: Clock stop enable */ +#define STR71X_RCCUCFR_SOFTRES (0x00000020) /* Bit 5: Software reset */ +#define STR71X_RCCUCFR_WDGRES (0x00000040) /* Bit 6: Watchdog reset */ +#define STR71X_RCCUCFR_RTCALARM (0x00000080) /* Bit 7: RTC alarm reset */ +#define STR71X_RCCUCFR_LVDRES (0x00000200) /* Bit 9: Voltage regulator low voltage detector reset */ +#define STR71X_RCCUCFR_WKPRES (0x00000400) /* Bit 10: External wakeup */ +#define STR71X_RCCUCFR_LOCKI (0x00000800) /* Bit 11: Lock interrupt pending */ +#define STR71X_RCCUCFR_CKAFI (0x00001000) /* Bit 12: CK_AF switching interrupt pending */ +#define STR71X_RCCUCFR_CK216I (0x00002000) /* Bit 13: CK2_16 switching interrupt pending */ +#define STR71X_RCCUCFR_STOPI (0x00004000) /* Bit 14: Stop interrupt pending */ +#define STR71X_RCCUCFR_DIV2 (0x00008000) /* Bit 15: OSCIN divided by 2 */ + +/* RCCU PPL1CR register bit definitions */ + +#define STR71X_RCCUPLL1CR_DXMASK (0x00000003) /* Bit 0-2: PLL1 clock divisor */ +#define STR71X_RCCUPLL1CR_DIV1 (0x00000000) /* PLLCK / 1 */ +#define STR71X_RCCUPLL1CR_DIV2 (0x00000001) /* PLLCK / 2 */ +#define STR71X_RCCUPLL1CR_DIV3 (0x00000002) /* PLLCK / 3 */ +#define STR71X_RCCUPLL1CR_DIV4 (0x00000003) /* PLLCK / 4 */ +#define STR71X_RCCUPLL1CR_DIV5 (0x00000004) /* PLLCK / 5 */ +#define STR71X_RCCUPLL1CR_DIV6 (0x00000005) /* PLLCK / 6 */ +#define STR71X_RCCUPLL1CR_DIV7 (0x00000006) /* PLLCK / 7 */ +#define STR71X_RCCUPLL1CR_CLK2 (0x00000007) /* FREEN==0: CLK2 */ +#define STR71X_RCCUPLL1CR_FREERM (0x00000007) /* FREEN==1: PLL1 in free running mode */ +#define STR71X_RCCUPLL1CR_MXMASK (0x00000030) /* Bit 4-5: PLL1 clock multiplier */ +#define STR71X_RCCUPLL1CR_MUL20 (0x00000000) /* CLK2 * 20 */ +#define STR71X_RCCUPLL1CR_MUL12 (0x00000010) /* CLK2 * 12 */ +#define STR71X_RCCUPLL1CR_MUL24 (0x00000020) /* CLK2 * 24 */ +#define STR71X_RCCUPLL1CR_MUL16 (0x00000030) /* CLK2 * 16 */ +#define STR71X_RCCUPLL1CR_FREFRANGE (0x00000040) /* Bit 6: Reference frequency range select */ +#define STR71X_RCCUPLL1CR_FREEN (0x00000080) /* Bit 7: PKL free running mode */ + +/* RCCU PER register bit definitions */ + +#define STR71X_RCCUPER_EMI (0x00000004) /* Bit 2: EMI */ +#define STR71X_RCCUPER_USBKERNEL (0x00000010) /* Bit 4: USB Kernel */ + +/* RCCU SMR register bit definitions */ + +#define STR71X_RCCUSMR_WFI (0x00000001) /* Bit 0: Wait for interrupt */ +#define STR71X_RCCUSMR_HALT (0x00000000) /* Bit 1: Halt */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_RCCU_H */ diff --git a/arch/arm/src/str71x/str71x_rtc.h b/arch/arm/src/str71x/str71x_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..05f6bfb7e6e5840373da51323243897a88ee9924 --- /dev/null +++ b/arch/arm/src/str71x/str71x_rtc.h @@ -0,0 +1,92 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_rtc.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_RTC_H +#define __ARCH_ARM_SRC_STR71X_STR71X_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* RTC Registers ********************************************************************/ + +#define STR71X_RTC_CRH (STR71X_RTC_BASE + 0x0000) /* 16-bits wide */ +#define STR71X_RTC_CRL (STR71X_RTC_BASE + 0x0004) /* 16-bits wide */ +#define STR71X_RTC_PRLH (STR71X_RTC_BASE + 0x0008) /* 16-bits wide */ +#define STR71X_RTC_PRLL (STR71X_RTC_BASE + 0x000c) /* 16-bits wide */ +#define STR71X_RTC_DIVH (STR71X_RTC_BASE + 0x0010) /* 16-bits wide */ +#define STR71X_RTC_DIVL (STR71X_RTC_BASE + 0x0014) /* 16-bits wide */ +#define STR71X_RTC_CNTH (STR71X_RTC_BASE + 0x0018) /* 16-bits wide */ +#define STR71X_RTC_CNTL (STR71X_RTC_BASE + 0x001c) /* 16-bits wide */ +#define STR71X_RTC_ALRH (STR71X_RTC_BASE + 0x0020) /* 16-bits wide */ +#define STR71X_RTC_ALRL (STR71X_RTC_BASE + 0x0024) /* 16-bits wide */ + +/* Register bit settings ***********************************************************/ + +/* RTC control register */ + +#define STR71X_RTCCRH_SEN (0x0001) /* Bit 0: Second interrupt enable */ +#define STR71X_RTCCRH_AEN (0x0002) /* Bit 1: Alarm interrupt enable */ +#define STR71X_RTCCRH_OWEN (0x0004) /* Bit 2: Overflow interrupt enable */ +#define STR71X_RTCCRH_GEN (0x0008) /* Bit 3: Global interrupt enable */ + +#define STR71X_RTCCRL_SIR (0x0001) /* Bit 0: Second interrupt request */ +#define STR71X_RTCCRL_AIR (0x0002) /* Bit 1: Alarm interrupt request */ +#define STR71X_RTCCRL_OWIR (0x0004) /* Bit 2: Overflow interrupt request */ +#define STR71X_RTCCRL_GIR (0x0008) /* Bit 3: Global interrupt request */ +#define STR71X_RTCCRL_CNF (0x0010) /* Bit 4: Enter configuration mode */ +#define STR71X_RTCCRL_RTOFF (0x0020) /* Bit 5: RTC Operation Off */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_RTC_H */ diff --git a/arch/arm/src/str71x/str71x_serial.c b/arch/arm/src/str71x/str71x_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..fe98f543aa7f0ea559bbc7c851f6b703ddfabe24 --- /dev/null +++ b/arch/arm/src/str71x/str71x_serial.c @@ -0,0 +1,1058 @@ +/**************************************************************************** + * arch/arm/src/str71x/str71x_serial.c + * + * Copyright (C) 2008-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "str71x.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Is there a UART enabled? */ + +#if !defined(CONFIG_STR71X_UART0) && !defined(CONFIG_STR71X_UART1) && \ + !defined(CONFIG_STR71X_UART2) && !defined(CONFIG_STR71X_UART3) +# error "No UARTs enabled" +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE) ||\ + defined(CONFIG_UART2_SERIAL_CONSOLE) || defined(CONFIG_UART3_SERIAL_CONSOLE) +# define HAVE_CONSOLE 1 +#else +# undef HAVE_CONSOLE +#endif + +/* Did the user select a priority? */ + +#ifndef CONFIG_UART_PRI +# define CONFIG_UART_PRI 1 +#elif CONFIG_UART_PRI <= 1 || CONFIG_UART_PRI > 15 +# error "CONFIG_UART_PRI is out of range" +#endif + +/* If we are not using the serial driver for the console, then we + * still must provide some minimal implementation of up_putc(). + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? tty2? tty3? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) || !defined(HAVE_CONSOLE) +# ifdef HAVE_CONSOLE +# ifndef CONFIG_STR71X_UART0 +# error "UART0 not selected, cannot be console" +# endif +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# endif +# define TTYS0_DEV g_uart0port /* UART0 is tty0 */ +# if defined(CONFIG_STR71X_UART1) +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# if defined(CONFIG_STR71X_UART2) +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS3_DEV g_uart3port /* UART3 is tty3 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART2) +# define TTYS1_DEV g_uart2port /* UART2 is tty1 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is tty1 */ +# endif +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# ifndef CONFIG_STR71X_UART1 +# error "UART1 not selected, cannot be console" +# endif +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is tty0 */ +# if CONFIG_STR71X_UART0 +# define TTYS1_DEV g_uart0port /* UART0 is tty1 */ +# if CONFIG_STR71X_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS3_DEV g_uart3port /* UART3 is tty3 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif CONFIG_STR71X_UART2 +# define TTYS1_DEV g_uart2port /* UART2 is tty1 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is tty1 */ +# endif +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# ifndef CONFIG_STR71X_UART2 +# error "UART2 not selected, cannot be console" +# endif +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is tty0 */ +# if CONFIG_STR71X_UART0 +# define TTYS1_DEV g_uart0port /* UART0 is tty1 */ +# if defined(CONFIG_STR71X_UART1) +# define TTYS2_DEV g_uart1port /* UART1 is tty2 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS3_DEV g_uart3port /* UART3 is tty3 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART1) +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# if defined(CONFIG_STR71X_UART3) +# define TTYS2_DEV g_uart3port /* UART3 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART3) +# define TTYS1_DEV g_uart3port /* UART3 is tty1 */ +# endif +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# ifndef CONFIG_STR71X_UART3 +# error "UART3 not selected, cannot be console" +# endif +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is tty0 */ +# if CONFIG_STR71X_UART0 +# define TTYS1_DEV g_uart0port /* UART0 is tty1 */ +# if defined(CONFIG_STR71X_UART1) +# define TTYS2_DEV g_uart1port /* UART1 is tty2 */ +# if defined(CONFIG_STR71X_UART2) +# define TTYS3_DEV g_uart2port /* UART2 is tty3 */ +# endif +# elif defined(CONFIG_STR71X_UART2) +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART1) +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# if defined(CONFIG_STR71X_UART2) +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# endif +# elif defined(CONFIG_STR71X_UART2) +# define TTYS1_DEV g_uart2port /* UART2 is tty1 */ +# endif +#else +# warning "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Select RX interrupt enable bits. There are two models: (1) We interrupt + * when each character is received. Or, (2) we interrupt when either the Rx + * FIFO is half full, OR a timeout occurs with data in the RX FIFO. The + * later does not work because there seems to be a disconnect -- we can get + * the FIFO half full interrupt with no data in the RX buffer. + */ + +#if 1 +# define RXENABLE_BITS (STR71X_UARTIER_RHF|STR71X_UARTIER_TIMEOUTNE) +#else +# define RXENABLE_BITS STR71X_UARTIER_RNE +#endif + +/* Which ever model is used, there seems to be some timing disconnects between + * Rx FIFO not full and Rx FIFO half full indications. Best bet is to use + * both. + */ + +#define RXAVAILABLE_BITS (STR71X_UARTSR_RNE|STR71X_UARTSR_RHF) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint16_t ier; /* Saved IER value */ + uint16_t sr; /* Saved SR value (only used during interrupt processing) */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Internal Helpers */ + +static inline uint16_t up_serialin(struct up_dev_s *priv, int offset); +static inline void up_serialout(struct up_dev_s *priv, int offset, uint16_t value); +static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier); +static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier); +#ifdef HAVE_CONSOLE +static inline void up_waittxnotfull(struct up_dev_s *priv); +#endif + +/* Serial Driver Methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_STR71X_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_STR71X_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_STR71X_UART2 +static char g_uart2rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_STR71X_UART3 +static char g_uart3rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +/* This describes the state of the STR71X uart0 port. */ + +#ifdef CONFIG_STR71X_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = STR71X_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = STR71X_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the STR71X uart1 port. */ + +#ifdef CONFIG_STR71X_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = STR71X_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = STR71X_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the STR71X uart2 port. */ + +#ifdef CONFIG_STR71X_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = STR71X_UART2_BASE, + .baud = CONFIG_UART2_BAUD, + .irq = STR71X_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the STR71X uart3 port. */ + +#ifdef CONFIG_STR71X_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = STR71X_UART3_BASE, + .baud = CONFIG_UART3_BAUD, + .irq = STR71X_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint16_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg16(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint16_t value) +{ + putreg16(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier) +{ + if (ier) + { + *ier = priv->ier; + } + + priv->ier = 0; + up_serialout(priv, STR71X_UART_IER_OFFSET, 0); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier) +{ + priv->ier = ier; + up_serialout(priv, STR71X_UART_IER_OFFSET, ier); +} + +/**************************************************************************** + * Name: up_waittxnotfull + ****************************************************************************/ + +#ifdef HAVE_CONSOLE +static inline void up_waittxnotfull(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TX available condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check TX FIFO is full */ + + if ((up_serialin(priv, STR71X_UART_SR_OFFSET) & STR71X_UARTSR_TF) == 0) + { + /* The TX FIFO is not full... return */ + break; + } + } +} +#endif + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t divisor; + uint32_t baud; + uint16_t cr; + + /* Set the BAUD rate */ + + divisor = 16 * priv->baud; + baud = (STR71X_PCLK1 + divisor/2) / divisor; + up_serialout(priv, STR71X_UART_BR_OFFSET, baud); + + /* Get mode setting */ + + cr = STR71X_UARTCR_RUN | STR71X_UARTCR_RXENABLE | STR71X_UARTCR_FIFOENABLE; + + if (priv->bits == 7) + { + DEBUGASSERT(priv->parity != 0); + cr |= STR71X_UARTCR_MODE7BITP; + } + else if (priv->bits == 8) + { + if (priv->parity) + { + cr |= STR71X_UARTCR_MODE8BITP; + } + else + { + cr |= STR71X_UARTCR_MODE8BIT; + } + } + else + { + DEBUGASSERT(priv->bits == 9 && priv->parity == 0); + cr |= STR71X_UARTCR_MODE9BIT; + } + + if (priv->parity == 1) + { + cr |= STR71X_UARTCR_PARITYODD; + } + + if (priv->stopbits2) + { + cr |= STR71X_UARTCR_STOPBIT20; + } + else + { + cr |= STR71X_UARTCR_STOPBIT10; + } + + up_serialout(priv, STR71X_UART_CR_OFFSET, cr); + + /* Clear FIFOs */ + + up_serialout(priv, STR71X_UART_TXRSTR_OFFSET, 0xffff); + up_serialout(priv, STR71X_UART_RXRSTR_OFFSET, 0xffff); + + /* We will take RX interrupts on either the FIFO half full or upon + * a timeout. The timeout is based upon BAUD rate ticks + */ + + up_serialout(priv, STR71X_UART_TOR_OFFSET, 50); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, STR71X_UART_IER_OFFSET); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the uart interrupt priority (the default value is one) */ + + up_prioritize_irq(priv->irq, CONFIG_UART_PRI); +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + int passes; + bool handled; + +#ifdef CONFIG_STR71X_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_STR71X_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_STR71X_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_STR71X_UART3 + if (g_uart3priv.irq == irq) + { + dev = &g_uart3port; + } + else +#endif + { + PANIC(); + } + + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv && dev); + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the current UART status */ + + priv->sr = up_serialin(priv, STR71X_UART_SR_OFFSET); + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((priv->sr & RXAVAILABLE_BITS) != 0 && /* Data available in Rx FIFO */ + (priv->ier & RXENABLE_BITS) != 0) /* Rx FIFO interrupts enabled */ + { + /* Rx buffer not empty ... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & STR71X_UARTSR_TF) == 0 && /* Tx FIFO not full */ + (priv->ier & STR71X_UARTIER_THE) != 0) /* Tx Half empty interrupt enabled */ + { + /* Tx FIFO not full ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint16_t rxbufr; + + rxbufr = up_serialin(priv, STR71X_UART_RXBUFR_OFFSET); + *status = (uint32_t)priv->sr << 16 | rxbufr; + return rxbufr & 0xff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { + /* Receive an interrupt when the Rx FIFO is half full (or if a timeout + * occurs while the Rx FIFO is not empty). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= RXENABLE_BITS; +#endif + } + else + { + priv->ier &= ~RXENABLE_BITS; + } + up_serialout(priv, STR71X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STR71X_UART_SR_OFFSET) & RXAVAILABLE_BITS) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, STR71X_UART_TXBUFR_OFFSET, (uint16_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { + /* Set to receive an interrupt when the TX fifo is half emptied */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= STR71X_UARTSR_THE; +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ier &= ~STR71X_UARTSR_THE; + } + up_serialout(priv, STR71X_UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STR71X_UART_SR_OFFSET) & STR71X_UARTSR_TF) == 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STR71X_UART_SR_OFFSET) & STR71X_UARTSR_TE) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* NOTE: All GPIO configuration for the UARTs was performed in + * up_lowsetup + */ + + /* Disable all UARTS */ + + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + up_disableuartint(TTYS2_DEV.priv, NULL); +#endif +#ifdef TTYS3_DEV + up_disableuartint(TTYS3_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint16_t ier; + + up_disableuartint(priv, &ier); + up_waittxnotfull(priv); + up_serialout(priv, STR71X_UART_TXBUFR_OFFSET, (uint16_t)ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxnotfull(priv); + up_serialout(priv, STR71X_UART_TXBUFR_OFFSET, (uint16_t)'\r'); + } + + up_waittxnotfull(priv); + up_restoreuartint(priv, ier); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/str71x/str71x_timer.h b/arch/arm/src/str71x/str71x_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..fc27f4eb4796aff7be91750a9386623170a67ca2 --- /dev/null +++ b/arch/arm/src/str71x/str71x_timer.h @@ -0,0 +1,155 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_timer.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_TIMER_H +#define __ARCH_ARM_SRC_STR71X_STR71X_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define STR71X_TIMER_ICAR_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_TIMER_ICBR_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_TIMER_OCAR_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_TIMER_OCBR_OFFSET (0x000c) /* 16-bits wide */ +#define STR71X_TIMER_CNTR_OFFSET (0x0010) /* 16-bits wide */ +#define STR71X_TIMER_CR1_OFFSET (0x0014) /* 16-bits wide */ +#define STR71X_TIMER_CR2_OFFSET (0x0018) /* 16-bits wide */ +#define STR71X_TIMER_SR_OFFSET (0x001c) /* 16-bits wide */ + +/* Register Addresses ***************************************************************/ + +#define STR71X_TIMER_ICAR(b) ((b) + STR71X_TIMER_ICAR_OFFSET) +#define STR71X_TIMER_ICBR(b) ((b) + STR71X_TIMER_ICBR_OFFSET) +#define STR71X_TIMER_OCAR(b) ((b) + STR71X_TIMER_OCAR_OFFSET) +#define STR71X_TIMER_OCBR(b) ((b) + STR71X_TIMER_OCBR_OFFSET) +#define STR71X_TIMER_CNTR(b) ((b) + STR71X_TIMER_CNTR_OFFSET) +#define STR71X_TIMER_CR1(b) ((b) + STR71X_TIMER_CR1_OFFSET) +#define STR71X_TIMER_CR2(b) ((b) + STR71X_TIMER_CR2_OFFSET) +#define STR71X_TIMER_SR(b) ((b) + STR71X_TIMER_SR_OFFSET) + +#define STR71X_TIMER0_ICAR (STR71X_TIMER0_BASE + STR71X_TIMER_ICAR_OFFSET) +#define STR71X_TIMER0_ICBR (STR71X_TIMER0_BASE + STR71X_TIMER_ICBR_OFFSET) +#define STR71X_TIMER0_OCAR (STR71X_TIMER0_BASE + STR71X_TIMER_OCAR_OFFSET) +#define STR71X_TIMER0_OCBR (STR71X_TIMER0_BASE + STR71X_TIMER_OCBR_OFFSET) +#define STR71X_TIMER0_CNTR (STR71X_TIMER0_BASE + STR71X_TIMER_CNTR_OFFSET) +#define STR71X_TIMER0_CR1 (STR71X_TIMER0_BASE + STR71X_TIMER_CR1_OFFSET) +#define STR71X_TIMER0_CR2 (STR71X_TIMER0_BASE + STR71X_TIMER_CR2_OFFSET) +#define STR71X_TIMER0_SR (STR71X_TIMER0_BASE + STR71X_TIMER_SR_OFFSET) + +#define STR71X_TIMER1_ICAR (STR71X_TIMER1_BASE + STR71X_TIMER_ICAR_OFFSET) +#define STR71X_TIMER1_ICBR (STR71X_TIMER1_BASE + STR71X_TIMER_ICBR_OFFSET) +#define STR71X_TIMER1_OCAR (STR71X_TIMER1_BASE + STR71X_TIMER_OCAR_OFFSET) +#define STR71X_TIMER1_OCBR (STR71X_TIMER1_BASE + STR71X_TIMER_OCBR_OFFSET) +#define STR71X_TIMER1_CNTR (STR71X_TIMER1_BASE + STR71X_TIMER_CNTR_OFFSET) +#define STR71X_TIMER1_CR1 (STR71X_TIMER1_BASE + STR71X_TIMER_CR1_OFFSET) +#define STR71X_TIMER1_CR2 (STR71X_TIMER1_BASE + STR71X_TIMER_CR2_OFFSET) +#define STR71X_TIMER1_SR (STR71X_TIMER1_BASE + STR71X_TIMER_SR_OFFSET) + +#define STR71X_TIMER2_ICAR (STR71X_TIMER2_BASE + STR71X_TIMER_ICAR_OFFSET) +#define STR71X_TIMER2_ICBR (STR71X_TIMER2_BASE + STR71X_TIMER_ICBR_OFFSET) +#define STR71X_TIMER2_OCAR (STR71X_TIMER2_BASE + STR71X_TIMER_OCAR_OFFSET) +#define STR71X_TIMER2_OCBR (STR71X_TIMER2_BASE + STR71X_TIMER_OCBR_OFFSET) +#define STR71X_TIMER2_CNTR (STR71X_TIMER2_BASE + STR71X_TIMER_CNTR_OFFSET) +#define STR71X_TIMER2_CR1 (STR71X_TIMER2_BASE + STR71X_TIMER_CR1_OFFSET) +#define STR71X_TIMER2_CR2 (STR71X_TIMER2_BASE + STR71X_TIMER_CR2_OFFSET) +#define STR71X_TIMER2_SR (STR71X_TIMER2_BASE + STR71X_TIMER_SR_OFFSET) + +#define STR71X_TIMER3_ICAR (STR71X_TIMER3_BASE + STR71X_TIMER_ICAR_OFFSET) +#define STR71X_TIMER3_ICBR (STR71X_TIMER3_BASE + STR71X_TIMER_ICBR_OFFSET) +#define STR71X_TIMER3_OCAR (STR71X_TIMER3_BASE + STR71X_TIMER_OCAR_OFFSET) +#define STR71X_TIMER3_OCBR (STR71X_TIMER3_BASE + STR71X_TIMER_OCBR_OFFSET) +#define STR71X_TIMER3_CNTR (STR71X_TIMER3_BASE + STR71X_TIMER_CNTR_OFFSET) +#define STR71X_TIMER3_CR1 (STR71X_TIMER3_BASE + STR71X_TIMER_CR1_OFFSET) +#define STR71X_TIMER3_CR2 (STR71X_TIMER3_BASE + STR71X_TIMER_CR2_OFFSET) +#define STR71X_TIMER3_SR (STR71X_TIMER3_BASE + STR71X_TIMER_SR_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* Timer control register (CR1 and CR2) */ + +#define STR71X_TIMERCR1_ECKEN (0x0001) /* Bit 0: External clock enable */ +#define STR71X_TIMERCR1_EXEDG (0x0002) /* Bit 1: External clock edge */ +#define STR71X_TIMERCR1_IEDGA (0x0004) /* Bit 2: Input edge A */ +#define STR71X_TIMERCR1_IEDGB (0x0008) /* Bit 3: Input edge B */ +#define STR71X_TIMERCR1_PWM (0x0010) /* Bit 4: Pulse width modulation */ +#define STR71X_TIMERCR1_OPM (0x0020) /* Bit 5: One pulse mode */ +#define STR71X_TIMERCR1_OCAE (0x0040) /* Bit 6: Output compare A enable */ +#define STR71X_TIMERCR1_OCBE (0x0080) /* Bit 7: Output compare B enable */ +#define STR71X_TIMERCR1_OLVLA (0x0100) /* Bit 8: Output level A */ +#define STR71X_TIMERCR1_OLVLB (0x0200) /* Bit 9: Output level B */ +#define STR71X_TIMERCR1_FOLVA (0x0400) /* Bit 10: Forced output compare A */ +#define STR71X_TIMERCR1_FOLVB (0x0800) /* Bit 11: Forced output compare B */ +#define STR71X_TIMERCR1_PWMI (0x4000) /* Bit 14: Pulse width modulation input */ +#define STR71X_TIMERCR1_EN (0x8000) /* Bit 15: Timer count enable */ + +#define STR71X_TIMERCR2_DIVMASK (0x00ff) /* Bits 0-7: Timer prescaler value */ +#define STR71X_TIMERCR2_OCBIE (0x0800) /* Bit 11: Output capture B enable */ +#define STR71X_TIMERCR2_ICBIE (0x1000) /* Bit 12: Input capture B enable */ +#define STR71X_TIMERCR2_TOIE (0x2000) /* Bit 13: Timer overflow enable */ +#define STR71X_TIMERCR2_OCAIE (0x4000) /* Bit 14: Output capture A enable */ +#define STR71X_TIMERCR2_ICAIE (0x8000) /* Bit 15: Input capture B enable */ + +/* Timer status register (SR) */ + +#define STR71X_TIMERSR_OCFB (0x0800) /* Bit 11: Output capture flag B */ +#define STR71X_TIMERSR_ICFB (0x1000) /* Bit 12: Input capture flag B */ +#define STR71X_TIMERSR_TOF (0x2000) /* Bit 13: Timer overflow */ +#define STR71X_TIMERSR_OCFA (0x4000) /* Bit 14: Output capture flag A */ +#define STR71X_TIMERSR_ICFA (0x8000) /* Bit 15: Input capture flag A */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_TIMER_H */ diff --git a/arch/arm/src/str71x/str71x_timerisr.c b/arch/arm/src/str71x/str71x_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..3604e6aa73c95181714b160976893de74073e7e1 --- /dev/null +++ b/arch/arm/src/str71x/str71x_timerisr.c @@ -0,0 +1,217 @@ +/**************************************************************************** + * arch/arm/src/str71x/str71x_timerisr.c + * + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "clock/clock.h" +#include "up_internal.h" + +#include "str71x.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration */ + +#ifndef CONFIG_TIM_PRI +# define CONFIG_TIM_PRI 1 +#elif CONFIG_TIM_PRI <= 1 || CONFIG_TIM_PRI > 15 +# error "CONFIG_TIM_PRI is out of range" +#endif + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The best accuracy would be obtained by using the largest value in the + * the output compare register (OCAR), i.e., 0xffff = 65,535: + */ + +#define MAX_OCAR 65535 + +/* In this case, the desired, maximum clocking would be MAX_TIM0CLK. For + * example if CLK_TCK is the default of 100Hz, then the ideal clocking for + * timer0 would be 6,553,500 */ + +#define MAX_TIM0CLK (MAX_OCAR * CLK_TCK) + +/* The best divider then would be the one that reduces PCLK2 to MAX_TIM0CLK. + * Note that the following calculation forces an integer divisor to the next + * integer above the optimal. So, for example, if MAX_TIM0CLK is 6,553,500 + * and PCLK2 is 32MHz, then ideal PCLK2_DIVIDER would be 4.88 but 5 is used + * instead. The value 5 would give an actual TIM0CLK of 6,400,000, less + * than the maximum. + */ + +#if STR71X_PCLK2 > MAX_TIM0CLK +# define PCLK2_DIVIDER (((STR71X_PCLK2) + (MAX_TIM0CLK+1)) / MAX_TIM0CLK) +#else +# define PCLK2_DIVIDER (1) +#endif + +#if PCLK2_DIVIDER > 255 +# error "PCLK2 is too fast for any divisor" +#endif + +/* Then we can get the actual OCAR value from the selected divider value. + * For example, if PCLK2 is 32MHz and PCLK2_DIVIDER is 5, then the actual + * TIM0CLK would 6,4000,000 and the final OCAR_VALUE would be 64,000. + */ + +#define ACTUAL_TIM0CLK (STR71X_PCLK2 / PCLK2_DIVIDER) +#define OCAR_VALUE (ACTUAL_TIM0CLK / CLK_TCK) + +#if OCAR_VALUE > 65535 +# error "PCLK2 is too fast for the configured CLK_TCK" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + uint16_t ocar; + + /* Clear all the output compare A interrupt status bit */ + + putreg16(~STR71X_TIMERSR_OCFA, STR71X_TIMER0_SR); + + /* Set up for the next compare match. We could either reset + * the OCAR and CNTR to restart, or simply update the OCAR as + * follows to that the match occurs later without resetting: + */ + + ocar = getreg16(STR71X_TIMER0_OCAR); + ocar += OCAR_VALUE; + putreg16(ocar, STR71X_TIMER0_OCAR); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + irqstate_t flags; + + /* Make sure that timer0 is disabled */ + + flags = enter_critical_section(); + putreg16(0x0000, STR71X_TIMER0_CR1); + putreg16(0x0000, STR71X_TIMER0_CR2); + putreg16(0x0000, STR71X_TIMER0_SR); + + /* Configure TIM0 so that it is clocked by the internal APB2 frequency (PCLK2) + * divided by the above prescaler value (1) -- versus an external Clock. + * -- Nothing to do because STR71X_TIMERCR1_ECKEN is already cleared. + * + * Select a divisor to reduce the frequency of clocking. This must be + * done so that the entire timer interval can fit in the 16-bit OCAR register. + * (see the discussion above). + */ + + putreg16(STR71X_TIMERCR2_OCAIE | (PCLK2_DIVIDER - 1), STR71X_TIMER0_CR2); + + /* Start The TIM0 Counter and enable the output comparison A */ + + putreg16(STR71X_TIMERCR1_EN | STR71X_TIMERCR1_OCAE, STR71X_TIMER0_CR1); + + /* Setup output compare A for desired interrupt frequency. Note that + * the OCAE and OCBE bits are cleared and the pins are available for other + * functions. + */ + + putreg16(OCAR_VALUE, STR71X_TIMER0_OCAR); + putreg16(0xfffc, STR71X_TIMER0_CNTR); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the timer interrupt priority */ + + up_prioritize_irq(STR71X_IRQ_SYSTIMER, CONFIG_TIM_PRI); +#endif + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STR71X_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + + /* And enable the timer interrupt */ + + up_enable_irq(STR71X_IRQ_SYSTIMER); + leave_critical_section(flags); +} diff --git a/arch/arm/src/str71x/str71x_uart.h b/arch/arm/src/str71x/str71x_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..fb70153722e0a487093982a08295e2a0263c0b40 --- /dev/null +++ b/arch/arm/src/str71x/str71x_uart.h @@ -0,0 +1,181 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_uart.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_UART_H +#define __ARCH_ARM_SRC_STR71X_STR71X_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Registers offsets ****************************************************************/ + +#define STR71X_UART_BR_OFFSET (0x0000) /* 16-bits wide */ +#define STR71X_UART_TXBUFR_OFFSET (0x0004) /* 16-bits wide */ +#define STR71X_UART_RXBUFR_OFFSET (0x0008) /* 16-bits wide */ +#define STR71X_UART_CR_OFFSET (0x000c) /* 16-bits wide */ +#define STR71X_UART_IER_OFFSET (0x0010) /* 16-bits wide */ +#define STR71X_UART_SR_OFFSET (0x0014) /* 16-bits wide */ +#define STR71X_UART_GTR_OFFSET (0x0018) /* 16-bits wide */ +#define STR71X_UART_TOR_OFFSET (0x001c) /* 16-bits wide */ +#define STR71X_UART_TXRSTR_OFFSET (0x0020) /* 16-bits wide */ +#define STR71X_UART_RXRSTR_OFFSET (0x0024) /* 16-bits wide */ + +/* Registers addresses **************************************************************/ + +#define STR71X_UART_BR(b) ((b) + STR71X_UART_BR_OFFSET) +#define STR71X_UART_TXBUFR(b) ((b) + STR71X_UART_TXBUFR_OFFSET) +#define STR71X_UART_RXBUFR(b) ((b) + STR71X_UART_RXBUFR_OFFSET) +#define STR71X_UART_CR(b) ((b) + STR71X_UART_CR_OFFSET) +#define STR71X_UART_IER(b) ((b) + STR71X_UART_IER_OFFSET) +#define STR71X_UART_SR(b) ((b) + STR71X_UART_SR_OFFSET) +#define STR71X_UART_GTR(b) ((b) + STR71X_UART_GTR_OFFSET) +#define STR71X_UART_TOR(b) ((b) + STR71X_UART_TOR_OFFSET) +#define STR71X_UART_TXRSTR(b) ((b) + STR71X_UART_TXRSTR_OFFSET) +#define STR71X_UART_RXRSTR(b) ((b) + STR71X_UART_RXRSTR_OFFSET) + +#define STR71X_UART0_BR (STR71X_UART0_BASE + STR71X_UART_BR_OFFSET) +#define STR71X_UART0_TXBUFR (STR71X_UART0_BASE + STR71X_UART_TXBUFR_OFFSET) +#define STR71X_UART0_RXBUFR (STR71X_UART0_BASE + STR71X_UART_RXBUFR_OFFSET) +#define STR71X_UART0_CR (STR71X_UART0_BASE + STR71X_UART_CR_OFFSET) +#define STR71X_UART0_IER (STR71X_UART0_BASE + STR71X_UART_IER_OFFSET) +#define STR71X_UART0_SR (STR71X_UART0_BASE + STR71X_UART_SR_OFFSET) +#define STR71X_UART0_GTR (STR71X_UART0_BASE + STR71X_UART_GTR_OFFSET) +#define STR71X_UART0_TOR (STR71X_UART0_BASE + STR71X_UART_TOR_OFFSET) +#define STR71X_UART0_TXRSTR (STR71X_UART0_BASE + STR71X_UART_TXRSTR_OFFSET) +#define STR71X_UART0_RXRSTR (STR71X_UART0_BASE + STR71X_UART_RXRSTR_OFFSET) + +#define STR71X_UART1_BR (STR71X_UART1_BASE + STR71X_UART_BR_OFFSET) +#define STR71X_UART1_TXBUFR (STR71X_UART1_BASE + STR71X_UART_TXBUFR_OFFSET) +#define STR71X_UART1_RXBUFR (STR71X_UART1_BASE + STR71X_UART_RXBUFR_OFFSET) +#define STR71X_UART1_CR (STR71X_UART1_BASE + STR71X_UART_CR_OFFSET) +#define STR71X_UART1_IER (STR71X_UART1_BASE + STR71X_UART_IER_OFFSET) +#define STR71X_UART1_SR (STR71X_UART1_BASE + STR71X_UART_SR_OFFSET) +#define STR71X_UART1_GTR (STR71X_UART1_BASE + STR71X_UART_GTR_OFFSET) +#define STR71X_UART1_TOR (STR71X_UART1_BASE + STR71X_UART_TOR_OFFSET) +#define STR71X_UART1_TXRSTR (STR71X_UART1_BASE + STR71X_UART_TXRSTR_OFFSET) +#define STR71X_UART1_RXRSTR (STR71X_UART1_BASE + STR71X_UART_RXRSTR_OFFSET) + +#define STR71X_UART2_BR (STR71X_UART2_BASE + STR71X_UART_BR_OFFSET) +#define STR71X_UART2_TXBUFR (STR71X_UART2_BASE + STR71X_UART_TXBUFR_OFFSET) +#define STR71X_UART2_RXBUFR (STR71X_UART2_BASE + STR71X_UART_RXBUFR_OFFSET) +#define STR71X_UART2_CR (STR71X_UART2_BASE + STR71X_UART_CR_OFFSET) +#define STR71X_UART2_IER (STR71X_UART2_BASE + STR71X_UART_IER_OFFSET) +#define STR71X_UART2_SR (STR71X_UART2_BASE + STR71X_UART_SR_OFFSET) +#define STR71X_UART2_GTR (STR71X_UART2_BASE + STR71X_UART_GTR_OFFSET) +#define STR71X_UART2_TOR (STR71X_UART2_BASE + STR71X_UART_TOR_OFFSET) +#define STR71X_UART2_TXRSTR (STR71X_UART2_BASE + STR71X_UART_TXRSTR_OFFSET) +#define STR71X_UART2_RXRSTR (STR71X_UART2_BASE + STR71X_UART_RXRSTR_OFFSET) + +#define STR71X_UART3_BR (STR71X_UART3_BASE + STR71X_UART_BR_OFFSET) +#define STR71X_UART3_TXBUFR (STR71X_UART3_BASE + STR71X_UART_TXBUFR_OFFSET) +#define STR71X_UART3_RXBUFR (STR71X_UART3_BASE + STR71X_UART_RXBUFR_OFFSET) +#define STR71X_UART3_CR (STR71X_UART3_BASE + STR71X_UART_CR_OFFSET) +#define STR71X_UART3_IER (STR71X_UART3_BASE + STR71X_UART_IER_OFFSET) +#define STR71X_UART3_SR (STR71X_UART3_BASE + STR71X_UART_SR_OFFSET) +#define STR71X_UART3_GTR (STR71X_UART3_BASE + STR71X_UART_GTR_OFFSET) +#define STR71X_UART3_TOR (STR71X_UART3_BASE + STR71X_UART_TOR_OFFSET) +#define STR71X_UART3_TXRSTR (STR71X_UART3_BASE + STR71X_UART_TXRSTR_OFFSET) +#define STR71X_UART3_RXRSTR (STR71X_UART3_BASE + STR71X_UART_RXRSTR_OFFSET) + +/* Register bit settings ***********************************************************/ + +/* UART control register (CR) */ + +#define STR71X_UARTCR_MODEMASK (0x0007) /* Bits 0-2: Mode */ +#define STR71X_UARTCR_MODE8BIT (0x0001) /* 8-bit */ +#define STR71X_UARTCR_MODE7BITP (0x0003) /* 7-bit with parity bit */ +#define STR71X_UARTCR_MODE9BIT (0x0004) /* 9-bit */ +#define STR71X_UARTCR_MODE8BITWU (0x0005) /* 8-bit with wakeup bit */ +#define STR71X_UARTCR_MODE8BITP (0x0007) /* 8-bit with parity bit */ +#define STR71X_UARTCR_STOPBITSMASK (0x0018) /* Bits 3-4: Stop bits */ +#define STR71X_UARTCR_STOPBIT05 (0x0000) /* 0.5 stop bits */ +#define STR71X_UARTCR_STOPBIT10 (0x0008) /* 1.0 stop bit */ +#define STR71X_UARTCR_STOPBIT15 (0x0010) /* 1.5 stop bits */ +#define STR71X_UARTCR_STOPBIT20 (0x0018) /* 2.0 stop bits */ +#define STR71X_UARTCR_PARITYODD (0x0020) /* Bit 5: Parity selection */ +#define STR71X_UARTCR_LOOPBACK (0x0040) /* Bit 6: Loopback mode enable */ +#define STR71X_UARTCR_RUN (0x0080) /* Bit 7: Baudrate generator run bit */ +#define STR71X_UARTCR_RXENABLE (0x0100) /* Bit 8: Receiver enable */ +#define STR71X_UARTCR_SCENABLE (0x0200) /* Bit 9: SmartCard mode enable */ +#define STR71X_UARTCR_FIFOENABLE (0x0400) /* Bit 10: FIFO enable */ + +/* UART interrupt enable (IER) register */ + +#define STR71X_UARTIER_RNE (0x0001) /* Bit 0: Rx buffer not empty */ +#define STR71X_UARTIER_TE (0x0002) /* Bit 1: Tx empty */ +#define STR71X_UARTIER_THE (0x0004) /* Bit 2: Tx half empty */ +#define STR71X_UARTIER_PERROR (0x0008) /* Bit 3: Parity error */ +#define STR71X_UARTIER_FRERROR (0x0010) /* Bit 4: Frame error */ +#define STR71X_UARTIER_OVERRUN (0x0020) /* Bit 5: Overrun error */ +#define STR71X_UARTIER_TIMEOUTNE (0x0040) /* Bit 6: Time out not empty*/ +#define STR71X_UARTIER_TIMEOUTIDLE (0x0080) /* Bit 7: Timeout out idle */ +#define STR71X_UARTIER_RHF (0x0100) /* Bit 8: Rx half full */ +#define STR71X_UARTIER_ALL (0x01ff) /* All interrupt bits */ + +/* UART status register (SR) */ + +#define STR71X_UARTSR_RNE (0x0001) /* Bit 0: Rx buffer not empty */ +#define STR71X_UARTSR_TE (0x0002) /* Bit 1: Tx empty */ +#define STR71X_UARTSR_THE (0x0004) /* Bit 2: Tx half empty */ +#define STR71X_UARTSR_PERR (0x0008) /* Bit 3: Parity error */ +#define STR71X_UARTSR_FRERROR (0x0010) /* Bit 4: Frame error */ +#define STR71X_UARTSR_OVERRUN (0x0020) /* Bit 5: Overrun error */ +#define STR71X_UARTSR_TIMEOUTNE (0x0040) /* Bit 6: Time out not empty */ +#define STR71X_UARTSR_TIMEOUTIDLE (0x0080) /* Bit 7: Timeout out idle */ +#define STR71X_UARTSR_RHF (0x0100) /* Bit 8: Rx half full */ +#define STR71X_UARTSR_TF (0x0200) /* Bit 9: Tx full */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_UART_H */ diff --git a/arch/arm/src/str71x/str71x_usb.h b/arch/arm/src/str71x/str71x_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..cebba716f1116ed70545725b2fa173d0708554f2 --- /dev/null +++ b/arch/arm/src/str71x/str71x_usb.h @@ -0,0 +1,180 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_usb.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_USB_H +#define __ARCH_ARM_SRC_STR71X_STR71X_USB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* USB registers ********************************************************************/ + +#define STR71X_USB_NENDPNTS (16) +#define STR71X_USB_EPR(ep) (STR71X_USB_BASE + ((ep) << 4)) +#define STR71X_USB_EP0R (STR71X_USB_BASE + 0x0000) /* Endpoint 0 */ +#define STR71X_USB_EP1R (STR71X_USB_BASE + 0x0004) /* Endpoint 1 */ +#define STR71X_USB_EP2R (STR71X_USB_BASE + 0x0008) /* Endpoint 2 */ +#define STR71X_USB_EP3R (STR71X_USB_BASE + 0x000c) /* Endpoint 3 */ +#define STR71X_USB_EP4R (STR71X_USB_BASE + 0x0010) /* Endpoint 4 */ +#define STR71X_USB_EP5R (STR71X_USB_BASE + 0x0014) /* Endpoint 5 */ +#define STR71X_USB_EP6R (STR71X_USB_BASE + 0x0018) /* Endpoint 6 */ +#define STR71X_USB_EP7R (STR71X_USB_BASE + 0x001c) /* Endpoint 7 */ +#define STR71X_USB_EP8R (STR71X_USB_BASE + 0x0020) /* Endpoint 8 */ +#define STR71X_USB_EP9R (STR71X_USB_BASE + 0x0024) /* Endpoint 9 */ +#define STR71X_USB_EP10R (STR71X_USB_BASE + 0x0028) /* Endpoint 10 */ +#define STR71X_USB_EP11R (STR71X_USB_BASE + 0x002c) /* Endpoint 11 */ +#define STR71X_USB_EP12R (STR71X_USB_BASE + 0x0030) /* Endpoint 12 */ +#define STR71X_USB_EP13R (STR71X_USB_BASE + 0x0034) /* Endpoint 13 */ +#define STR71X_USB_EP14R (STR71X_USB_BASE + 0x0038) /* Endpoint 14 */ +#define STR71X_USB_EP15R (STR71X_USB_BASE + 0x003c) /* Endpoint 15 */ +#define STR71X_USB_CNTR (STR71X_USB_BASE + 0x0040) /* Control register */ +#define STR71X_USB_ISTR (STR71X_USB_BASE + 0x0044) /* Interrupt status register */ +#define STR71X_USB_FNR (STR71X_USB_BASE + 0x0048) /* Frame number register */ +#define STR71X_USB_DADDR (STR71X_USB_BASE + 0x004C) /* Device address register */ +#define STR71X_USB_BTABLE (STR71X_USB_BASE + 0x0050) /* Buffer Table address register */ + +/* Register bit settings ***********************************************************/ + +/* Control Register (CNTR) */ + +#define USB_CNTR_FRES (1 << 0) /* Bit 0: Force usb reset */ +#define USB_CNTR_PDWN (1 << 1) /* Bit 1: Power down */ +#define USB_CNTR_LPMODE (1 << 2) /* Bit 2: Low-power mode */ +#define USB_CNTR_FSUSP (1 << 3) /* Bit 3: Force suspend */ +#define USB_CNTR_RESUME (1 << 4) /* Bit 4: Resume request */ +#define USB_CNTR_ESOFM (1 << 8) /* Bit 8: Expected start of frame */ +#define USB_CNTR_SOFM (1 << 9) /* Bit 9: Start of frame */ +#define USB_CNTR_RESETM (1 << 10) /* Bit 10: Reset */ +#define USB_CNTR_SUSPM (1 << 11) /* Bit 11: Suspend */ +#define USB_CNTR_WKUPM (1 << 12) /* Bit 12: Wake up */ +#define USB_CNTR_ERRM (1 << 13) /* Bit 13: Error */ +#define USB_CNTR_DOVRM (1 << 14) /* Bit 14: DMA over/underrun */ +#define USB_CNTR_CTRM (1 << 15) /* Bit 15: Correct transfer */ + +/* Interrupt status register (ISTR) */ + +#define USB_ISTR_EPID_SHIFT 0 /* Bits 0-3: Endpoint Identifier */ +#define USB_ISTR_EPID_MASK (0x0f << USB_ISTR_EPID_SHIFT) +#define USB_ISTR_DIR (1 << 4) /* Bit 4: DIRection of transaction */ +#define USB_ISTR_ESOF (1 << 8) /* Bit 8: Expected start of frame */ +#define USB_ISTR_SOF (1 << 9) /* Bit 9: Start of frame */ +#define USB_ISTR_RESET (1 << 10) /* Bit 10: Reset */ +#define USB_ISTR_SUSP (1 << 11) /* Bit 11: Suspend */ +#define USB_ISTR_WKUP (1 << 12) /* Bit 12: Wakeup */ +#define USB_ISTR_ERR (1 << 13) /* Bit 13: Error */ +#define USB_ISTR_DOVR (1 << 14) /* Bit 14: DMA Over/underrun */ +#define USB_ISTR_CTR (1 << 15) /* Bit 15: Correct Transfer */ + +/* Frame number register (FNR) */ + +#define USB_FNR_FN_SHIFT 0 /* Bit 0-10: Frame number */ +#define USB_FNR_LSOF_SHIFT 11 /* Bits 11-12 : Lost SOF */ +#define USB_FNR_LSOF_MASK (3 << USB_FNR_LSOF_SHIFT) +#define USB_FNR_FN_MASK (0x07ff << USB_FNR_FN_SHIFT) +#define USB_FNR_LCK (1 << 13) /* Bit 13: Locked */ +#define USB_FNR_RXDM (1 << 14) /* Bit 14: Status of D- data line */ +#define USB_FNR_RXDP (1 << 15) /* Bit 15: Status of D+ data line */ + +/* Device address register (DADDR) */ + +#define USB_DADDR_ADD_SHIFT 0 /* Bits 0-7: Device address */ +#define USB_DADDR_ADD_MASK (0x7f << USB_DADDR_ADD_SHIFT) +#define USB_DADDR_EF (1 << 7) /* Bit 8: Enable function */ + +/* Endpoint registers (EPR) */ + +#define USB_EPR_ADDRFIELD_SHIFT 0 /* Bits 0-3: Endpoint address */ +#define USB_EPR_ADDRFIELD_MASK (0x0f << USB_EPR_ADDRFIELD_SHIFT) +#define USB_EPR_TXSTAT_SHIFT 4 /* Bits 4-5: Endpoint TX status bit */ +#define USB_EPR_TXSTAT_MASK (3 << USB_EPR_TXSTAT_SHIFT) +# define USB_EPR_TXDIS (0 << USB_EPR_TXSTAT_SHIFT) /* Endpoint TX disabled */ +# define USB_EPR_TXSTALL (1 << USB_EPR_TXSTAT_SHIFT) /* Endpoint TX stalled */ +# define USB_EPR_TXNAK (2 << USB_EPR_TXSTAT_SHIFT) /* Endpoint TX NAKed */ +# define USB_EPR_TXVALID (3 << USB_EPR_TXSTAT_SHIFT) /* Endpoint TX valid */ +# define USB_EPR_TXDTOG1 (1 << USB_EPR_TXSTAT_SHIFT) /* Bit : Endpoint TX data toggle bit1 */ +# define USB_EPR_TXDTOG2 (2 << USB_EPR_TXSTAT_SHIFT) /* Bit : Endpoint TX data toggle bit2 */ +#define USB_EPR_DTOGTX (1 << 6) /* Bit 6: Endpoint data toggle TX */ +#define USB_EPR_CTRTX (1 << 7) /* Bit 7: Endpoint correct transfer TX */ +#define USB_EPR_KIND (1 << 8) /* Bit 8: Endpoint kind */ +#define USB_EPR_EPTYPE_SHIFT 9 /* Bits 9-10: Endpoint type */ +#define USB_EPR_EPTYPE_MASK (3 << USB_EPR_EPTYPE_SHIFT) +# define USB_EPR_BULK (0 << USB_EPR_EPTYPE_SHIFT) /* Endpoint BULK */ +# define USB_EPR_CONTROL (1 << USB_EPR_EPTYPE_SHIFT) /* Endpoint CONTROL */ +# define USB_EPR_ISOC (2 << USB_EPR_EPTYPE_SHIFT)) /* Endpoint ISOCHRONOUS */ +# define USB_EPR_INTERRUPT (3 << USB_EPR_EPTYPE_SHIFT) /* Endpoint INTERRUPT */ +#define USB_EPR_SETUP (1 << 11) /* Bit 11: Endpoint setup */ +#define USB_EPR_RXSTAT_SHIFT 12 /* Bits 12-13: Endpoint RX status bit */ +#define USB_EPR_RXSTAT_MASK (3 << USB_EPR_RXSTAT_SHIFT) +# define USB_EPR_RXDIS (0 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX disabled */ +# define USB_EPR_RXSTALL (1 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX stalled */ +# define USB_EPR_RXNAK (2 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX NAKed */ +# define USB_EPR_RXVALID (3 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX valid */ +# define USB_EPR_RXDTOG1 (1 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX data toggle bit1 */ +# define USB_EPR_RXDTOG2 (2 << USB_EPR_RXSTAT_SHIFT) /* Endpoint RX data toggle bit2 */ +#define USB_EPR_DTOGRX (1 << 14) /* Bit 14: Endpoint data toggle RX */ +#define USB_EPR_CTRRX (1 << 15) /* Bit 15: Endpoint correct transfer RX */ + +/* Endpoint register mask (no toggle fields) */ + +#define USB_EPR_NOTOGGLE_MASK (USB_EPR_CTRRX|USB_EPR_SETUP|USB_EPR_TFIELD|\ + USB_EPR_KIND|USB_EPR_CTRTX|USB_EPR_ADDRFIELD) + +/* Toggles only */ + +#define USB_EPR_TXDTOG_MASK (USB_EPR_TXSTAT_MASK|USB_EPR_NOTOGGLE_MASK) +#define USB_EPR_RXDTOG_MASK (USB_EPR_RXSTAT_MASK|USB_EPR_NOTOGGLE_MASK) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_USB_H */ diff --git a/arch/arm/src/str71x/str71x_wdog.h b/arch/arm/src/str71x/str71x_wdog.h new file mode 100644 index 0000000000000000000000000000000000000000..3e7640482e44b984ae8e0b5cbd59c33cd73dde05 --- /dev/null +++ b/arch/arm/src/str71x/str71x_wdog.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_wdog.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_WDOG_H +#define __ARCH_ARM_SRC_STR71X_STR71X_WDOG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Registers ************************************************************************/ + +#define STR71X_WDOG_CR (STR71X_WDOG_BASE + 0x0000) /* 16-bits wide */ +#define STR71X_WDOG_PR (STR71X_WDOG_BASE + 0x0004) /* 16-bits wide */ +#define STR71X_WDOG_VR (STR71X_WDOG_BASE + 0x0008) /* 16-bits wide */ +#define STR71X_WDOG_CNT (STR71X_WDOG_BASE + 0x000c) /* 16-bits wide */ +#define STR71X_WDOG_SR (STR71X_WDOG_BASE + 0x0010) /* 16-bits wide */ +#define STR71X_WDOG_MR (STR71X_WDOG_BASE + 0x0014) /* 16-bits wide */ +#define STR71X_WDOG_KR (STR71X_WDOG_BASE + 0x00018 /* 16-bits wide */ + +/* Register bit settings ***********************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STR71X_STR71X_WDOG_H */ diff --git a/arch/arm/src/str71x/str71x_xti.c b/arch/arm/src/str71x/str71x_xti.c new file mode 100644 index 0000000000000000000000000000000000000000..1bb42e656b9d22e11b571e5a143fe244d040dc58 --- /dev/null +++ b/arch/arm/src/str71x/str71x_xti.c @@ -0,0 +1,320 @@ +/******************************************************************************** + * arch/arm/src/str71x/str71x_xti.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************/ + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "str71x.h" + +#ifdef CONFIG_STR71X_XTI + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Private Types + ********************************************************************************/ + +struct xtiregs_s +{ + uint32_t mr; /* Mask register */ + uint32_t tr; /* Trigger polarity register */ +}; + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +static const struct xtiregs_s g_xtiregs[2] = +{ + { STR71X_XTI_MRL, STR71X_XTI_TRL }, + { STR71X_XTI_MRH, STR71X_XTI_TRH } +}; + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: str71x_xtiinterrupt + * + * Description: + * Dispatch an XTI interrupt. + * + ********************************************************************************/ + +static int str71x_xtiinterrupt(int irq, FAR void *context) +{ + uint16_t enabled = (uint16_t)getreg8(STR71X_XTI_MRH) << 8 | + (uint16_t)getreg8(STR71X_XTI_MRL); + uint16_t pending = (uint16_t)getreg8(STR71X_XTI_PRH) << 8 | + (uint16_t)getreg8(STR71X_XTI_PRL); + uint16_t mask; + + /* Dispatch the interrupts, the actions performed by the interrupt + * handlers should clear the interrupt at the external source of the + * interrupt. We need to clear the interrupts at the source before + * clearing the pending interrupts (see below). + */ + + pending &= enabled; + + for (irq = STR71X_IRQ_FIRSTXTI, mask = 0x0001; + irq < NR_IRQS && pending != 0; + irq++, mask <<= 1) + { + /* Is this interrupt pending? */ + + if ((pending & mask) != 0) + { + /* Deliver the IRQ */ + + irq_dispatch(irq, context); + pending &= ~mask; + } + } + + /* Clear the pending interrupts. This should be safe: "it is necessary to + * clear at least one pending bit: this operation allows a rising edge to be + * generated on the internal line (if there is at least one more pending bit + * set and not masked) and so to set the interrupt controller pending bit + * again. + */ + + putreg8(0, STR71X_XTI_PRH); + putreg8(0, STR71X_XTI_PRL); + return OK; +} + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: str71x_xtiinitialize + * + * Description: + * Configure XTI for operation. Note that the lines are not used as wake-up + * sources in this implementation. Some extensions would be required for that + * capability. + * + ********************************************************************************/ + +int str71x_xtiinitialize(void) +{ + int ret; + + /* Mask all interrupts by setting XTI MRH/L to zero */ + + putreg8(0, STR71X_XTI_MRH); + putreg8(0, STR71X_XTI_MRL); + + /* Clear any pending interrupts by setting XTI PRH/L to zero */ + + putreg8(0, STR71X_XTI_PRH); + putreg8(0, STR71X_XTI_PRL); + + /* Attach the XTI interrupt */ + + ret = irq_attach(STR71X_IRQ_XTI, str71x_xtiinterrupt); + if (ret == OK) + { + /* Enable the XTI interrupt at the XTI */ + + putreg8(STR71X_XTICTRL_ID1S, STR71X_XTI_CTRL); + + /* And enable the XTI interrupt at the interrupt controller */ + + up_enable_irq(STR71X_IRQ_XTI); + } + return ret; +} + +/******************************************************************************** + * Name: str71x_xticonfig + * + * Description: + * Configure an external line to provide interrupts. + * + ********************************************************************************/ + +int str71x_xticonfig(int irq, bool rising) +{ + uint8_t regval; + int bit; + int ndx; + int ret = -EINVAL; + + /* Configure one of the 16 lines as an interrupt source */ + + if (irq >= STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) + { + /* Make sure that the interrupt is disabled */ + + str71x_disable_xtiirq(irq); + + /* Decide if we use the lower or upper regiser */ + + bit = irq - STR71X_IRQ_FIRSTXTI; + ndx = 0; + if (bit > 7) + { + /* Select the high register */ + + bit -= 8; + ndx = 1; + } + + /* Set the rising or trailing edge */ + + regval = getreg8(g_xtiregs[ndx].tr); + if (rising) + { + regval |= (1 << bit); + } + else + { + regval &= ~(1 << bit); + } + putreg8(regval, g_xtiregs[ndx].tr); + + /* Return success */ + + ret = OK; + } + return ret; +} + +/**************************************************************************** + * Name: str71x_enable_xtiirq + * + * Description: + * Enable an external interrupt. + * + ****************************************************************************/ + +void str71x_enable_xtiirq(int irq) +{ + uint8_t regval; + int bit; + int ndx; + + /* Enable the external interrupt */ + + if (irq >= STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) + { + /* Decide if we use the lower or upper regiser */ + + bit = irq - STR71X_IRQ_FIRSTXTI; + ndx = 0; + if (bit > 7) + { + /* Select the high register */ + + bit -= 8; + ndx = 1; + } + + /* Enable the interrupt be setting the corresponding mask bit + * the XTI_MRL/H register. + */ + + regval = getreg8(g_xtiregs[ndx].mr); + regval |= (1 << bit); + putreg8(regval, g_xtiregs[ndx].mr); + } +} + +/**************************************************************************** + * Name: str71x_disable_xtiirq + * + * Description: + * Disable an external interrupt. + * + ****************************************************************************/ + +void str71x_disable_xtiirq(int irq) +{ + uint8_t regval; + int bit; + int ndx; + + /* Disable the external interrupt */ + + if (irq >= STR71X_IRQ_FIRSTXTI && irq <= NR_IRQS) + { + /* Decide if we use the lower or upper regiser */ + + bit = irq - STR71X_IRQ_FIRSTXTI; + ndx = 0; + if (bit > 7) + { + /* Select the high register */ + + bit -= 8; + ndx = 1; + } + + /* Disable the interrupt be clearing the corresponding mask bit + * the XTI_MRL/H register. + */ + + regval = getreg8(g_xtiregs[ndx].mr); + regval &= ~(1 << bit); + putreg8(regval, g_xtiregs[ndx].mr); + } +} + +#endif /* CONFIG_STR71X_XTI */ diff --git a/arch/arm/src/str71x/str71x_xti.h b/arch/arm/src/str71x/str71x_xti.h new file mode 100644 index 0000000000000000000000000000000000000000..1bb2ef6791b63b6fce92ba5a722adaa9ca4fee7a --- /dev/null +++ b/arch/arm/src/str71x/str71x_xti.h @@ -0,0 +1,105 @@ +/************************************************************************************ + * arch/arm/src/str71x/str71x_xti.h + * + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STR71X_STR71X_XTI_H +#define __ARCH_ARM_SRC_STR71X_STR71X_XTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "str71x_map.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* External Interupt Controller (XTI) registers *************************************/ + +#define STR71X_XTI_SR (STR71X_XTI_BASE + 0x001c) /* 8-bits wide */ +#define STR71X_XTI_CTRL (STR71X_XTI_BASE + 0x0024) /* 8-bits wide */ +#define STR71X_XTI_MRH (STR71X_XTI_BASE + 0x0028) /* 8-bits wide */ +#define STR71X_XTI_MRL (STR71X_XTI_BASE + 0x002c) /* 8-bits wide */ +#define STR71X_XTI_TRH (STR71X_XTI_BASE + 0x0030) /* 8-bits wide */ +#define STR71X_XTI_TRL (STR71X_XTI_BASE + 0x0034) /* 8-bits wide */ +#define STR71X_XTI_PRH (STR71X_XTI_BASE + 0x0038) /* 8-bits wide */ +#define STR71X_XTI_PRL (STR71X_XTI_BASE + 0x003c) /* 8-bits wide */ + +/* Register bit settings ************************************************************/ + +/* Control register (CTRL) */ + +#define STR71X_XTICTRL_WKUPINT (0x01) +#define STR71X_XTICTRL_ID1S (0x02) +#define STR71X_XTICTRL_STOP (0x04) + +/* Most registers are address by external interrupt line in two 8-bit high and low + * registers + */ + +#define STR71X_XTI_LINE(n) (1 << (n)) +#define STR71X_XTI_LINE0 STR71X_XTI_LINE(0) /* Low register */ +#define STR71X_XTI_LINE1 STR71X_XTI_LINE(1) +#define STR71X_XTI_LINE2 STR71X_XTI_LINE(2) +#define STR71X_XTI_LINE3 STR71X_XTI_LINE(3) +#define STR71X_XTI_LINE4 STR71X_XTI_LINE(4) +#define STR71X_XTI_LINE5 STR71X_XTI_LINE(5) +#define STR71X_XTI_LINE6 STR71X_XTI_LINE(6) +#define STR71X_XTI_LINE7 STR71X_XTI_LINE(7) + +#define STR71X_XTI_LINE8 STR71X_XTI_LINE(8) /* High register */ +#define STR71X_XTI_LINE9 STR71X_XTI_LINE(9) +#define STR71X_XTI_LINE10 STR71X_XTI_LINE(10) +#define STR71X_XTI_LINE11 STR71X_XTI_LINE(11) +#define STR71X_XTI_LINE12 STR71X_XTI_LINE(12) +#define STR71X_XTI_LINE13 STR71X_XTI_LINE(13) +#define STR71X_XTI_LINE14 STR71X_XTI_LINE(14) +#define STR71X_XTI_LINE15 STR71X_XTI_LINE(15) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* _ARCH_ARM_SRC_STR71X_STR71X_XTI_H */ diff --git a/arch/arm/src/tiva/Kconfig b/arch/arm/src/tiva/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..96b82a469136d0c6cd829c8659f799a9f76beefd --- /dev/null +++ b/arch/arm/src/tiva/Kconfig @@ -0,0 +1,1148 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Tiva/Stellaris Configuration Options" + +choice + prompt "Tiva/Stellaris Chip Selection" + default ARCH_CHIP_LM3S6965 + depends on ARCH_CHIP_LM || ARCH_CHIP_TIVA + +config ARCH_CHIP_LM3S6918 + bool "LM3S6918" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM3 + select ARCH_CHIP_LM3S + select TIVA_HAVE_I2C1 + select TIVA_HAVE_SSI1 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_ETHERNET + +config ARCH_CHIP_LM3S9B96 + bool "LM3S9B96" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM3 + select ARCH_CHIP_LM3S + select TIVA_HAVE_UART3 + select TIVA_HAVE_I2C1 + select TIVA_HAVE_SSI1 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_ETHERNET + select TIVA_HAVE_GPIOH_IRQS + +config ARCH_CHIP_LM3S6432 + bool "LM3S6432" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM3 + select ARCH_CHIP_LM3S + select TIVA_HAVE_ETHERNET + +config ARCH_CHIP_LM3S6965 + bool "LM3S6965" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM3 + select ARCH_CHIP_LM3S + select TIVA_HAVE_UART3 + select TIVA_HAVE_I2C1 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_ETHERNET + select TIVA_HAVE_GPIOH_IRQS + +config ARCH_CHIP_LM3S8962 + bool "LM3S8962" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM3 + select ARCH_CHIP_LM3S + select TIVA_HAVE_UART3 + select TIVA_HAVE_I2C1 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_TIMER4 + select TIVA_HAVE_TIMER5 + select TIVA_HAVE_ETHERNET + select TIVA_HAVE_GPIOH_IRQS + +config ARCH_CHIP_LM4F120 + bool "LM4F120" + depends on ARCH_CHIP_LM + select ARCH_CORTEXM4 + select ARCH_CHIP_LM4F + select ARCH_HAVE_FPU + +config ARCH_CHIP_TM4C123GH6ZRB + bool "TM4C123GH6ZRB" + depends on ARCH_CHIP_TIVA + select ARCH_CHIP_TM4C + select ARCH_CHIP_TM4C123 + select TIVA_HAVE_GPIOP_IRQS + select TIVA_HAVE_GPIOQ_IRQS + select TIVA_HAVE_I2C4 + select TIVA_HAVE_I2C5 + +config ARCH_CHIP_TM4C123GH6PMI + bool "TM4C123GH6PMI" + depends on ARCH_CHIP_TIVA + select ARCH_CHIP_TM4C + select ARCH_CHIP_TM4C123 + select TIVA_HAVE_GPIOA_IRQS + select TIVA_HAVE_GPIOB_IRQS + select TIVA_HAVE_GPIOC_IRQS + select TIVA_HAVE_GPIOD_IRQS + select TIVA_HAVE_GPIOE_IRQS + select TIVA_HAVE_GPIOF_IRQS + select TIVA_HAVE_ADC0 + select TIVA_HAVE_ADC1 + +config ARCH_CHIP_TM4C1294NC + bool "TM4C1294NC" + depends on ARCH_CHIP_TIVA + select ARCH_CHIP_TM4C + select ARCH_CHIP_TM4C129 + select TIVA_HAVE_ETHERNET + +config ARCH_CHIP_TM4C129XNC + bool "TM4C129XNC" + depends on ARCH_CHIP_TIVA + select ARCH_CHIP_TM4C + select ARCH_CHIP_TM4C129 + select TIVA_HAVE_ETHERNET + +config ARCH_CHIP_CC3200 + bool "CC3200" + depends on ARCH_CHIP_TIVA + select ARCH_CORTEXM4 + select TIVA_HAVE_I2C1 + +endchoice + +# Chip families + +config ARCH_CHIP_LM3S + bool + select TIVA_HAVE_GPIOA_IRQS + select TIVA_HAVE_GPIOB_IRQS + select TIVA_HAVE_GPIOC_IRQS + select TIVA_HAVE_GPIOD_IRQS + select TIVA_HAVE_GPIOE_IRQS + select TIVA_HAVE_GPIOF_IRQS + select TIVA_HAVE_GPIOG_IRQS + select TIVA_HAVE_SSI0 + +config ARCH_CHIP_LM4F + bool + select TIVA_HAVE_GPIOA_IRQS + select TIVA_HAVE_GPIOB_IRQS + select TIVA_HAVE_GPIOC_IRQS + select TIVA_HAVE_GPIOD_IRQS + select TIVA_HAVE_GPIOE_IRQS + select TIVA_HAVE_GPIOF_IRQS + select TIVA_HAVE_GPIOG_IRQS + select TIVA_HAVE_GPIOH_IRQS + select TIVA_HAVE_I2C1 + select TIVA_HAVE_I2C2 + select TIVA_HAVE_I2C3 + select TIVA_HAVE_UART3 + select TIVA_HAVE_UART4 + select TIVA_HAVE_UART5 + select TIVA_HAVE_UART6 + select TIVA_HAVE_UART7 + select TIVA_HAVE_SSI0 + select TIVA_HAVE_SSI1 + select TIVA_HAVE_SSI2 + select TIVA_HAVE_SSI3 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_TIMER4 + select TIVA_HAVE_TIMER5 + +config ARCH_CHIP_TM4C123 + bool + +config ARCH_CHIP_TM4C129 + bool + select TIVA_HAVE_GPIOP_IRQS + select TIVA_HAVE_GPIOQ_IRQS + select TIVA_HAVE_I2C4 + select TIVA_HAVE_I2C5 + select TIVA_HAVE_I2C6 + select TIVA_HAVE_I2C7 + select TIVA_HAVE_I2C8 + select TIVA_HAVE_I2C9 + select TIVA_HAVE_TIMER6 + select TIVA_HAVE_TIMER7 + +config ARCH_CHIP_TM4C + bool + select ARCH_CORTEXM4 + select ARCH_HAVE_FPU + select TIVA_HAVE_ADC0 + select TIVA_HAVE_ADC1 + select TIVA_HAVE_GPIOP_IRQS + select TIVA_HAVE_I2C1 + select TIVA_HAVE_I2C2 + select TIVA_HAVE_I2C3 + select TIVA_HAVE_UART3 + select TIVA_HAVE_UART4 + select TIVA_HAVE_UART5 + select TIVA_HAVE_UART6 + select TIVA_HAVE_UART7 + select TIVA_HAVE_SSI0 + select TIVA_HAVE_SSI1 + select TIVA_HAVE_SSI2 + select TIVA_HAVE_SSI3 + select TIVA_HAVE_TIMER0 + select TIVA_HAVE_TIMER1 + select TIVA_HAVE_TIMER2 + select TIVA_HAVE_TIMER3 + select TIVA_HAVE_TIMER4 + select TIVA_HAVE_TIMER5 + +config LM_REVA2 + bool "Rev A2" + default n + depends on ARCH_CHIP_LM + ---help--- + Some early silicon returned an increase LDO voltage or 2.75V to work + around a PLL bug + +config TIVA_BOARD_EARLYINIT + bool + default n + +menu "Tiva/Stellaris Peripheral Support" + +config TIVA_ADC + bool + default n + +config TIVA_HAVE_ADC0 + bool + default n + +config TIVA_HAVE_ADC1 + bool + default n + +config TIVA_I2C + bool + default n + +config TIVA_HAVE_I2C1 + bool + default n + +config TIVA_HAVE_I2C2 + bool + default n + +config TIVA_HAVE_I2C3 + bool + default n + +config TIVA_HAVE_I2C4 + bool + default n + +config TIVA_HAVE_I2C5 + bool + default n + +config TIVA_HAVE_I2C6 + bool + default n + +config TIVA_HAVE_I2C7 + bool + default n + +config TIVA_HAVE_I2C8 + bool + default n + +config TIVA_HAVE_I2C9 + bool + default n + +config TIVA_HAVE_UART3 + bool + default n + +config TIVA_HAVE_UART4 + bool + default n + +config TIVA_HAVE_UART5 + bool + default n + +config TIVA_HAVE_UART6 + bool + default n + +config TIVA_HAVE_UART7 + bool + default n + +config TIVA_HAVE_SSI0 + bool + default n + +config TIVA_HAVE_SSI1 + bool + default n + +config TIVA_HAVE_SSI2 + bool + default n + +config TIVA_HAVE_SSI3 + bool + default n + +config TIVA_HAVE_ETHERNET + bool + default n + +config TIVA_SSI + bool + default n + +config TIVA_TIMER + bool + default n + +config TIVA_HAVE_TIMER0 + bool + default n + +config TIVA_HAVE_TIMER1 + bool + default n + +config TIVA_HAVE_TIMER2 + bool + default n + +config TIVA_HAVE_TIMER3 + bool + default n + +config TIVA_HAVE_TIMER4 + bool + default n + +config TIVA_HAVE_TIMER5 + bool + default n + +config TIVA_HAVE_TIMER6 + bool + default n + +config TIVA_HAVE_TIMER7 + bool + default n + +config TIVA_ADC0 + bool "ADC0" + default n + select TIVA_ADC + +config TIVA_ADC1 + bool "ADC1" + default n + depends on TIVA_HAVE_ADC0 + select TIVA_ADC + +config TIVA_I2C0 + bool "I2C0" + default n + select TIVA_I2C + +config TIVA_I2C1 + bool "I2C1" + default n + select TIVA_I2C + +config TIVA_I2C2 + bool "I2C2" + default n + depends on TIVA_HAVE_I2C2 + select TIVA_I2C + +config TIVA_I2C3 + bool "I2C3" + default n + depends on TIVA_HAVE_I2C3 + select TIVA_I2C + +config TIVA_I2C4 + bool "I2C4" + default n + depends on TIVA_HAVE_I2C4 + select TIVA_I2C + +config TIVA_I2C5 + bool "I2C5" + default n + depends on TIVA_HAVE_I2C5 + select TIVA_I2C + +config TIVA_I2C6 + bool "I2C6" + default n + depends on TIVA_HAVE_I2C6 + select TIVA_I2C + +config TIVA_I2C7 + bool "I2C7" + default n + depends on TIVA_HAVE_I2C7 + select TIVA_I2C + +config TIVA_I2C8 + bool "I2C8" + default n + depends on TIVA_HAVE_I2C8 + select TIVA_I2C + +config TIVA_I2C9 + bool "I2C9" + default n + depends on TIVA_HAVE_I2C9 + select TIVA_I2C + +config TIVA_UART0 + bool "UART0" + select ARCH_HAVE_UART0 + default n + +config TIVA_UART1 + bool "UART1" + select ARCH_HAVE_UART1 + default n + +config TIVA_UART2 + bool "UART2" + select ARCH_HAVE_UART2 + default n + +config TIVA_UART3 + bool "UART3" + default n + depends on TIVA_HAVE_UART3 + select ARCH_HAVE_UART3 + +config TIVA_UART4 + bool "UART4" + default n + depends on TIVA_HAVE_UART4 + select ARCH_HAVE_UART4 + +config TIVA_UART5 + bool "UART5" + default n + depends on TIVA_HAVE_UART5 + select ARCH_HAVE_UART5 + +config TIVA_UART6 + bool "UART6" + default n + depends on TIVA_HAVE_UART6 + select ARCH_HAVE_UART6 + +config TIVA_UART7 + bool "UART7" + default n + depends on TIVA_HAVE_UART7 + select ARCH_HAVE_UART7 + +config TIVA_SSI0 + bool "SSI0" + default n + depends on TIVA_HAVE_SSI0 + select TIVA_SSI + +config TIVA_SSI1 + bool "SSI1" + default n + depends on TIVA_HAVE_SSI1 + select TIVA_SSI + +config TIVA_SSI2 + bool "SSI2" + default n + depends on TIVA_HAVE_SSI2 + select TIVA_SSI + +config TIVA_SSI3 + bool "SSI3" + default n + depends on TIVA_HAVE_SSI3 + select TIVA_SSI + +config TIVA_TIMER0 + bool "16-/32-bit Timer 0" + default n + depends on TIVA_HAVE_TIMER0 + select TIVA_TIMER + +config TIVA_TIMER1 + bool "16-/32-bit Timer 1" + default n + depends on TIVA_HAVE_TIMER1 + select TIVA_TIMER + +config TIVA_TIMER2 + bool "16-/32-bit Timer 2" + default n + depends on TIVA_HAVE_TIMER2 + select TIVA_TIMER + +config TIVA_TIMER3 + bool "16-/32-bit Timer 3" + default n + depends on TIVA_HAVE_TIMER3 + select TIVA_TIMER + +config TIVA_TIMER4 + bool "16-/32-bit Timer 4" + default n + depends on TIVA_HAVE_TIMER4 + select TIVA_TIMER + +config TIVA_TIMER5 + bool "16-/32-bit Timer 5" + default n + depends on TIVA_HAVE_TIMER5 + select TIVA_TIMER + +config TIVA_TIMER6 + bool "16-/32-bit Timer 6" + default n + depends on TIVA_HAVE_TIMER6 + select TIVA_TIMER + +config TIVA_TIMER7 + bool "16-/32-bit Timer 7" + default n + depends on TIVA_HAVE_TIMER7 + select TIVA_TIMER + +config TIVA_ETHERNET + bool "Ethernet" + default n + depends on TIVA_HAVE_ETHERNET + select NETDEVICES + select ARCH_HAVE_NETDEV_STATISTICS if ARCH_CHIP_LM3S || ARCH_CHIP_LM4F + ---help--- + This must be set (along with NET) to build the Stellaris Ethernet driver. + +config TIVA_FLASH + bool "Internal FLASH driver" + default n + ---help--- + Enable MTD driver support for internal FLASH. + +endmenu + +menu "Enable GPIO Interrupts" + +config TIVA_GPIO_IRQS + bool + default n + +config TIVA_HAVE_GPIOA_IRQS + bool + default n + +config TIVA_HAVE_GPIOB_IRQS + bool + default n + +config TIVA_HAVE_GPIOC_IRQS + bool + default n + +config TIVA_HAVE_GPIOD_IRQS + bool + default n + +config TIVA_HAVE_GPIOE_IRQS + bool + default n + +config TIVA_HAVE_GPIOF_IRQS + bool + default n + +config TIVA_HAVE_GPIOG_IRQS + bool + default n + +config TIVA_HAVE_GPIOH_IRQS + bool + default n + +config TIVA_HAVE_GPIOJ_IRQS + bool + default n + +config TIVA_HAVE_GPIOK_IRQS + bool + default n + +config TIVA_HAVE_GPIOL_IRQS + bool + default n + +config TIVA_HAVE_GPIOM_IRQS + bool + default n + +config TIVA_HAVE_GPION_IRQS + bool + default n + +config TIVA_HAVE_GPIOP_IRQS + bool + default n + +config TIVA_HAVE_GPIOQ_IRQS + bool + default n + +config TIVA_HAVE_GPIOR_IRQS + bool + default n + +config TIVA_HAVE_GPIOS_IRQS + bool + default n + +config TIVA_HAVE_GPIOT_IRQS + bool + default n + +config TIVA_GPIOA_IRQS + bool "Enable GPIOA IRQs" + default n + depends on TIVA_HAVE_GPIOA_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOB_IRQS + bool "Enable GPIOB IRQs" + default n + depends on TIVA_HAVE_GPIOB_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOC_IRQS + bool "Enable GPIOC IRQs" + default n + depends on TIVA_HAVE_GPIOC_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOD_IRQS + bool "Enable GPIOD IRQs" + default n + depends on TIVA_HAVE_GPIOD_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOE_IRQS + bool "Enable GPIOE IRQs" + default n + depends on TIVA_HAVE_GPIOE_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOF_IRQS + bool "Enable GPIOF IRQs" + default n + depends on TIVA_HAVE_GPIOF_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOG_IRQS + bool "Enable GPIOG IRQs" + default n + depends on TIVA_HAVE_GPIOG_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOH_IRQS + bool "Enable GPIOH IRQs" + default n + depends on TIVA_HAVE_GPIOH_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOJ_IRQS + bool "Enable GPIOJ IRQs" + default n + depends on TIVA_HAVE_GPIOJ_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOK_IRQS + bool "Enable GPIOK IRQs" + default n + depends on TIVA_HAVE_GPIOK_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOL_IRQS + bool "Enable GPIOL IRQs" + default n + depends on TIVA_HAVE_GPIOL_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOM_IRQS + bool "Enable GPIOM IRQs" + default n + depends on TIVA_HAVE_GPIOM_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPION_IRQS + bool "Enable GPION IRQs" + default n + depends on TIVA_HAVE_GPION_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOP_IRQS + bool "Enable GPIOP IRQs" + default n + depends on TIVA_HAVE_GPIOP_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOQ_IRQS + bool "Enable GPIOQ IRQs" + default n + depends on TIVA_HAVE_GPIOQ_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOR_IRQS + bool "Enable GPIOR IRQs" + default n + depends on TIVA_HAVE_GPIOR_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOS_IRQS + bool "Enable GPIOS IRQs" + default n + depends on TIVA_HAVE_GPIOS_IRQS + select TIVA_GPIO_IRQS + +config TIVA_GPIOT_IRQS + bool "Enable GPIOT IRQs" + default n + depends on TIVA_HAVE_GPIOT_IRQS + select TIVA_GPIO_IRQS + +endmenu + +if TIVA_I2C + +menu "I2C Configuration" + +config TIVA_I2C_DYNTIMEO + bool "Use dynamic timeouts" + default n + +if TIVA_I2C_DYNTIMEO + +config TIVA_I2C_DYNTIMEO_USECPERBYTE + int "Timeout Microseconds per Byte" + default 500 + +config TIVA_I2C_DYNTIMEO_STARTSTOP + int "Timeout for Start/Stop (Milliseconds)" + default 1000 + +endif # TIVA_I2C_DYNTIMEO + +config TIVA_I2C_TIMEOSEC + int "Timeout seconds" + default 0 + +if !TIVA_I2C_DYNTIMEO + +config TIVA_I2C_TIMEOMS + int "Timeout Milliseconds" + default 500 + depends on !TIVA_I2C_DYNTIMEO + +config TIVA_I2C_TIMEOTICKS + int "Timeout for Done and Stop (ticks)" + default 500 + depends on !TIVA_I2C_DYNTIMEO + +endif # !TIVA_I2C_DYNTIMEO + +config TIVA_I2C_HIGHSPEED + bool "High speed support" + default n + depends on ARCH_CHIP_TM4C && EXPERIMENTAL + ---help--- + Enable support for high speed I2C transfers. + Only partially implemented and completely untested. + +config TIVA_I2C_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enables extremely detailed register access debug output. + +endmenu # I2C Configuration +endif # TIVA_I2C + +if TIVA_TIMER + +menu "Timer Configuration" + +config TIVA_TIMER_32BIT + bool "32-bit timer support" + default n + +if TIVA_TIMER_32BIT + +config TIVA_TIMER32_PERIODIC + bool "32-bit one-shot/periodic timer support" + default n + +config TIVA_TIMER32_RTC + bool "32-bit RTC (needs 32.768-KHz input)" + default n + +endif # TIVA_TIMER_32BIT + +config TIVA_TIMER_16BIT + bool "16-bit timer support" + default n + +if TIVA_TIMER_16BIT + +config TIVA_TIMER16_PERIODIC + bool "16-bit one-shot/periodic timer support" + default n + +config TIVA_TIMER16_EDGECOUNT + bool "16-bit input edge-count capture support" + default n + depends on EXPERIMENTAL + +config TIVA_TIMER16_TIMECAP + bool "16-bit input time capture support" + default n + depends on EXPERIMENTAL + +config TIVA_TIMER16_PWM + bool "16-bit PWM output support" + default n + depends on EXPERIMENTAL + +endif # TIVA_TIMER_16BIT + +config TIVA_TIMER_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enables extremely detailed register access debug output. + +endmenu # Tiva Timer Configuration +endif # TIVA_TIMER + +if TIVA_ADC +menu "ADC Configuration" + +config TIVA_ADC_REGDEBUG + bool "Register level debug" + default n + depends on DEBUG + ---help--- + Enables extremely detailed register access debug output. + +endmenu # Tiva ADC Configuration +endif # TIVA_ADC + +if TIVA_ETHERNET + +menu "Stellaris Ethernet Configuration" + depends on ARCH_CHIP_LM3S + +config TIVA_ETHLEDS + bool "Ethernet LEDs" + default n + ---help--- + Enable to use Ethernet LEDs on the board. + +config TIVA_ETHHDUPLEX + bool "Force Half Duplex" + default n + ---help--- + Set to force half duplex operation + +config TIVA_ETHNOAUTOCRC + bool "Disable auto-CRC" + default n + ---help--- + Set to suppress auto-CRC generation + +config TIVA_ETHNOPAD + bool "Disable Tx Padding" + default n + ---help--- + Set to suppress Tx padding + +config TIVA_MULTICAST + bool "Enable Multicast" + default n + ---help--- + Set to enable multicast frames + +config TIVA_PROMISCUOUS + bool "Enable Promiscuous Mode" + default n + ---help--- + Set to enable promiscuous mode + +config TIVA_TIMESTAMP + bool "Enable Timestamping" + default n + +config TIVA_BADCRC + bool "Enable Bad CRC Rejection" + default n + ---help--- + Set to enable bad CRC rejection. + +config TIVA_DUMPPACKET + bool "Dump Packets" + default n + ---help--- + Dump each packet received/sent to the console. + +endmenu # Stellaris Ethernet Configuration + +menu "Ethernet Configuration" + depends on ARCH_CHIP_TM4C + +choice + prompt "PHY selection" + default TIVA_PHY_INTERNAL + +config TIVA_PHY_INTERNAL + bool "Internal PHY" + ---help--- + Use the built-in, internal Tiva PHY + +config TIVA_PHY_MII + bool "External MII interface" + depends on EXPERIMENTAL + ---help--- + Support external PHY MII interface. + +config TIVA_PHY_RMII + bool "External RMII interface" + depends on EXPERIMENTAL + ---help--- + Support external PHY RMII interface. + +endchoice # PHY selection + +config TIVA_AUTONEG + bool "Use autonegotiation" + default y + ---help--- + Use PHY autonegotiation to determine speed and mode + +if !TIVA_PHY_INTERNAL + +config TIVA_PHYADDR + int "PHY address" + default 1 + ---help--- + The 5-bit address of the PHY on the board. Default: 1 + +if !TIVA_AUTONEG +config TIVA_ETHFD + bool "Full duplex" + default n + ---help--- + If TIVA_AUTONEG is not defined, then this may be defined to select full duplex + mode. Default: half-duplex + +config TIVA_ETH100MBPS + bool "100 Mbps" + default n + ---help--- + If TIVA_AUTONEG is not defined, then this may be defined to select 100 MBps + speed. Default: 10 Mbps + +endif # !TIVA_AUTONEG +if TIVA_AUTONEG + +config TIVA_PHYSR + int "PHY Status Register Address (decimal)" + ---help--- + This must be provided if TIVA_AUTONEG is defined. The PHY status register + address may diff from PHY to PHY. This configuration sets the address of + the PHY status register. + +config TIVA_PHYSR_ALTCONFIG + bool "PHY Status Alternate Bit Layout" + default n + ---help--- + Different PHYs present speed and mode information in different ways. Some + will present separate information for speed and mode (this is the default). + Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + full/half duplex indication. This options selects an alternative representation + where speed and mode information are combined. This might mean, for example, + separate bits for 10HD, 100HD, 10FD and 100FD. + +if !TIVA_PHYSR_ALTCONFIG + +config TIVA_PHYSR_SPEED + hex "PHY Speed Mask" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This provides bit mask + for isolating the 10 or 100MBps speed indication. + +config TIVA_PHYSR_100MBPS + hex "PHY 100Mbps Speed Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This provides the value + of the speed bit(s) indicating 100MBps speed. + +config TIVA_PHYSR_MODE + hex "PHY Mode Mask" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This provide bit mask + for isolating the full or half duplex mode bits. + +config TIVA_PHYSR_FULLDUPLEX + hex "PHY Full Duplex Mode Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This provides the + value of the mode bits indicating full duplex mode. + +endif # !TIVA_PHYSR_ALTCONFIG +if TIVA_PHYSR_ALTCONFIG + +config TIVA_PHYSR_ALTMODE + hex "PHY Mode Mask" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This provide bit mask + for isolating the speed and full/half duplex mode bits. + +config TIVA_PHYSR_10HD + hex "10MBase-T Half Duplex Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, half duplex setting. + +config TIVA_PHYSR_100HD + hex "100Base-T Half Duplex Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, half duplex setting. + +config TIVA_PHYSR_10FD + hex "10Base-T Full Duplex Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This is the value + under the bit mask that represents the 10Mbps, full duplex setting. + +config TIVA_PHYSR_100FD + hex "100Base-T Full Duplex Value" + ---help--- + This must be provided if TIVA_AUTONEG is defined. This is the value + under the bit mask that represents the 100Mbps, full duplex setting. + +endif # TIVA_PHYSR_ALTCONFIG +endif # TIVA_AUTONEG +endif # !TIVA_PHY_INTERNAL + +config TIVA_PHY_INTERRUPTS + bool "PHY interrupt support" + select ARCH_PHY_INTERRUPT + select NETDEV_PHY_IOCTL + default n + ---help--- + Enable logic to signal user tasks when a PHY interrupt occurs. The + PHY interrupt may indicate a change in the link status such as, for + example, when a cable is plugged in or unplugged. + +config TIVA_EMAC_NRXDESC + int "Number of RX descriptors" + default 8 + ---help--- + Number of RX DMA descriptors to use. + +config TIVA_EMAC_NTXDESC + int "Number of TX descriptors" + default 4 + ---help--- + Number of TX DMA descriptors to use. + +config TIVA_EMAC_ENHANCEDDESC + bool + default n + +config TIVA_EMAC_PTP + bool "Precision Time Protocol (PTP)" + default n + depends on EXPERIMENTAL + select TIVA_EMAC_ENHANCEDDESC + ---help--- + Precision Time Protocol (PTP). Not supported but some hooks are indicated + with this condition. + +config TIVA_EMAC_HWCHECKSUM + bool "Use hardware checksums" + default n + depends on EXPERIMENTAL + ---help--- + Use the hardware checksum capabilities of the Tiva chip + +config TIVA_ETHERNET_REGDEBUG + bool "Register-Level Debug" + default n + depends on DEBUG + ---help--- + Enable very low-level register access debug. Depends on DEBUG. + +endmenu # Tiva Ethernet Configuration + +config TIVA_BOARDMAC + bool "Board MAC" + default n + ---help--- + If the board-specific logic can provide a MAC address (via + tiva_ethernetmac()), then this should be selected. + +endif # TIVA_ETHERNET + +if TIVA_SSI +menu "Tiva/Stellaris SSI Configuration" + +config SSI_POLLWAIT + bool "Poll Wait (No-Interrupt) Mode" + default y + +config SSI_TXLIMIT + int "Tx Limit" + default 4 + ---help--- + Default of 4 assumes half of the 8 entry FIFO + +endmenu +endif + +if TIVA_FLASH +menu "Tiva/Stellaris Internal Flash Driver Configuration" + +config TIVA_FLASH_STARTPAGE + int "First page accessible by the MTD driver" + default 250 + ---help--- + To prevent accessing FLASH sections where code is stored. + +endmenu +endif + diff --git a/arch/arm/src/tiva/Make.defs b/arch/arm/src/tiva/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..cb5648817586721f50db0450af0946503e54a8a2 --- /dev/null +++ b/arch/arm/src/tiva/Make.defs @@ -0,0 +1,124 @@ +############################################################################ +# arch/arm/src/tiva/Make.defs +# +# Copyright (C) 2009-2011, 2013-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = tiva_vectors.S + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_memfault.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c +CMN_CSRCS += up_svcall.c up_vfork.c + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +else +CMN_CSRCS += up_allocateheap.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c +endif + +CHIP_ASRCS = +CHIP_CSRCS = tiva_allocateheap.c tiva_start.c tiva_irq.c tiva_gpio.c +CHIP_CSRCS += tiva_gpioirq.c tiva_lowputc.c tiva_serial.c tiva_ssi.c +CHIP_CSRCS += tiva_dumpgpio.c + +ifeq ($(CONFIG_ARCH_CHIP_TM4C129),y) +CHIP_CSRCS += tm4c129_syscontrol.c +else +CHIP_CSRCS += tiva_syscontrol.c +endif + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += tiva_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += tiva_userspace.c tiva_mpuinit.c +endif + +ifeq ($(CONFIG_TIVA_I2C),y) +CHIP_CSRCS += tiva_i2c.c +endif + +ifeq ($(CONFIG_TIVA_TIMER),y) +CHIP_CSRCS += tiva_timerlib.c +ifeq ($(CONFIG_TIVA_TIMER32_PERIODIC),y) +CHIP_CSRCS += tiva_timerlow32.c +endif +endif + +ifeq ($(CONFIG_TIVA_ADC),y) +CHIP_CSRCS += tiva_adclow.c +CHIP_CSRCS += tiva_adclib.c +endif + +ifeq ($(CONFIG_TIVA_ETHERNET),y) +ifeq ($(CONFIG_ARCH_CHIP_LM3S),y) +CHIP_CSRCS += lm3s_ethernet.c +endif +ifeq ($(CONFIG_ARCH_CHIP_TM4C),y) +CHIP_CSRCS += tm4c_ethernet.c +endif +endif + +ifeq ($(CONFIG_TIVA_FLASH),y) +CHIP_CSRCS += tiva_flash.c +endif diff --git a/arch/arm/src/tiva/chip.h b/arch/arm/src/tiva/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..622ac3c1384da6dc20082868232d34c87555bddf --- /dev/null +++ b/arch/arm/src/tiva/chip.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/* Then get all of the register definitions */ + +#include "chip/tiva_memorymap.h" /* Memory map */ +#include "chip/tiva_syscontrol.h" /* System control module */ +#include "chip/tiva_gpio.h" /* GPIO modules */ +#include "chip/tiva_uart.h" /* UART modules */ +#include "chip/tiva_i2c.h" /* I2C modules */ +#include "chip/tiva_ssi.h" /* SSI modules */ +#include "chip/tiva_ethernet.h" /* Ethernet MAC and PHY */ +#include "chip/tiva_flash.h" /* FLASH */ +#include "chip/tiva_timer.h" /* Timer */ +#include "chip/tiva_adc.h" /* ADC */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_H */ diff --git a/arch/arm/src/tiva/chip/cc3200_memorymap.h b/arch/arm/src/tiva/chip/cc3200_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..437dc646708af216fc65ddaadbaf1952022d554d --- /dev/null +++ b/arch/arm/src/tiva/chip/cc3200_memorymap.h @@ -0,0 +1,156 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/cc3200_memorymap.h + * + * Copyright (C) 2014 Droidifi LLC. All rights reserved. + * Jim Ewing + * + * Adapted for the cc3200 from code: + * + * Copyright (C) Gregory Nutt. + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Droidifi 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_CC3200_MEMORYMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_CC3200_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory map ***********************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_CC3200) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0007ffff: On-chip FLASH */ + /* -0x00ffffff: Reserved */ +# define TIVA_ROM_BASE 0x01000000 /* -0x1fffffff: Reserved for ROM */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x2003ffff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x23ffffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000- */ + +# define TIVA_CRYPTO_BASE 0x44030000 /* -0x44039fff: Crypto HW base 44030000- */ + /* -0xdfffffff: Reserved */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ +# define TIVA_ETM_BASE 0xe0041000 /* -0xe0041fff: Embedded Trace Macrocell */ + /* -0xffffffff: Reserved */ +#else +# error "Memory map not specified for this TM4C chip" +#endif + +/* Peripheral base addresses ********************************************************/ + +#if defined(CONFIG_ARCH_CHIP_CC3200) + +# define TIVA_WDOG0_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ + +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ + +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x207ff: I2C0 */ + +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ + +// NOTE: ADC memory location not listed in CC3200 DS +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ + +# define TIVA_CONF_REG (TIVA_PERIPH_BASE + 0xf7000) /* -0xf7fff: Configuration registers */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ + +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ +# define TIVA_ASP_A0 (TIVA_PERIPH_BASE + 0x401c000)/* -0x401efff: McASP A0 */ +# define TIVA_SPI_A0 (TIVA_PERIPH_BASE + 0x4020000)/* -0x4020fff: McSPI A0 */ +# define TIVA_SPI_A1 (TIVA_PERIPH_BASE + 0x4021000)/* -0x4022fff: McSPI A1 */ + +# define TIVA_APP_CLK_BASE (TIVA_PERIPH_BASE + 0x4025000)/* -0x4025fff: App Clk */ +# define TIVA_APP_CFG_BASE (TIVA_PERIPH_BASE + 0x4026000)/* -0x4026fff: App config */ +# define TIVA_OCP_GPRCM_BASE (TIVA_PERIPH_BASE + 0x402d000)/* -0x402dfff: global reset, pwr, clk */ +# define TIVA_OCP_SHR_BASE (TIVA_PERIPH_BASE + 0x402e000)/* -0x402efff: OCP shared config */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0x402f000)/* -0x402ffff: Hibernation Controller */ + +/* Crypto Base Addresses */ + +# define TIVA_TCP_DTHE_BASE (TIVA_CRYPTO_BASE + 0x0000) /* -0x0fff: TCP Checksum & DTHE regs */ +# define TIVA_CCM_BASE TIVA_TCP_DTHE_BASE +# define TIVA_SHA_BASE (TIVA_CRYPTO_BASE + 0x5000) /* -0x5fff: MD5/SHA */ +# define TIVA_AES_BASE (TIVA_CRYPTO_BASE + 0x7000) /* -0x7fff: AES */ +# define TIVA_DES_BASE (TIVA_CRYPTO_BASE + 0x9000) /* -0x9fff: DES */ + +// NOTE: the following locations are not listed in CC3200 DS +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ + +# define TIVA_EPI0_BASE (TIVA_PERIPH_BASE + 0xd0000) /* -0xd0fff: EPI 0 */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ + +#else +# error "Peripheral base addresses not specified for this Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_CC3200_MEMORYMAP_H */ diff --git a/arch/arm/src/tiva/chip/cc3200_pinmap.h b/arch/arm/src/tiva/chip/cc3200_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..b05b2a49d9444674350bf1793d3962fe1074587e --- /dev/null +++ b/arch/arm/src/tiva/chip/cc3200_pinmap.h @@ -0,0 +1,136 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/cc3200_pinmap.h + * + * Copyright (C) 2014 Droidifi LLC. All rights reserved. + * Author: Jim Ewing + * + * Adapted for the cc3200 from code: + * + * Copyright (C) Gregory Nutt. + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Droidifi 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_CC3200_PINMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_CC3200_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_CC3200) + +# define GPIO_ADC_IN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_IN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_IN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_IN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_IN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_IN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_IN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_IN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_IN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_IN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_IN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_IN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) + +# define GPIO_CORE_TRCLK (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PADTYPE_ODWPU | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_CORE_TRD0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PADTYPE_ODWPU | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_CORE_TRD1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PADTYPE_ODWPU | GPIO_PORTF | GPIO_PIN_1) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_I2C2_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_I2C2_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_I2C3_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_I2C3_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_1) + +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TMS (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_SYSCON_NMI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_SYSCON_NMI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_0) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_TIM2_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM3_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM4_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_5) + +#else +# error "Unknown TIVA chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_CC3200_PINMAP_H */ diff --git a/arch/arm/src/tiva/chip/cc3200_syscontrol.h b/arch/arm/src/tiva/chip/cc3200_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..424332eb8704045e6203ffa730735b66adb4db73 --- /dev/null +++ b/arch/arm/src/tiva/chip/cc3200_syscontrol.h @@ -0,0 +1,1865 @@ +/******************************************************************************************** + * arch/arm/src/tiva/chip/cc3200_syscontrol.h + * + * Copyright (C) 2014 Droidifi LLC. All rights reserved. + * Author: Jim Ewing + * + * Adapted for the cc3200 from code: + * + * Copyright (C) Gregory Nutt. + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Droidifi 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_CC3200_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_CC3200_SYSCONTROL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* System Control Register Offsets **********************************************************/ + +#define TIVA_SYSCON_DID0_OFFSET 0x000 /* Device Identification 0 */ +#define TIVA_SYSCON_DID1_OFFSET 0x004 /* Device Identification 1 */ +#define TIVA_SYSCON_PBORCTL_OFFSET 0x030 /* Brown-Out Reset Control */ +#define TIVA_SYSCON_RIS_OFFSET 0x050 /* Raw Interrupt Status */ +#define TIVA_SYSCON_IMC_OFFSET 0x054 /* Interrupt Mask Control */ +#define TIVA_SYSCON_MISC_OFFSET 0x058 /* Masked Interrupt Status and Clear */ +#define TIVA_SYSCON_RESC_OFFSET 0x05c /* Reset Cause */ +#define TIVA_SYSCON_RCC_OFFSET 0x060 /* Run-Mode Clock Configuration */ +#define TIVA_SYSCON_GPIOHBCTL_OFFSET 0x06c /* GPIO High-Performance Bus Control */ +#define TIVA_SYSCON_RCC2_OFFSET 0x070 /* Run-Mode Clock Configuration 2 */ +#define TIVA_SYSCON_MOSCCTL_OFFSET 0x07c /* Main Oscillator Control */ +#define TIVA_SYSCON_DSLPCLKCFG_OFFSET 0x144 /* Deep Sleep Clock Configuration */ +#define TIVA_SYSCON_SYSPROP_OFFSET 0x14c /* System Properties */ +#define TIVA_SYSCON_PIOSCCAL_OFFSET 0x150 /* Precision Internal Oscillator Calibration */ +#define TIVA_SYSCON_PIOSCSTAT_OFFSET 0x154 /* Precision Internal Oscillator Statistics */ +#define TIVA_SYSCON_PLLFREQ0_OFFSET 0x160 /* PLL 0 Frequency */ +#define TIVA_SYSCON_PLLFREQ1_OFFSET 0x164 /* PLL 1 Frequency */ +#define TIVA_SYSCON_PLLSTAT_OFFSET 0x168 /* PLL Status */ +#define TIVA_SYSCON_SLPPWRCFG_OFFSET 0x188 /* Sleep Power Configuration */ +#define TIVA_SYSCON_DSLPPWRCFG_OFFSET 0x18c /* Deep-Sleep Power Configuration */ +#define TIVA_SYSCON_LDOSPCTL_OFFSET 0x1b4 /* LDO Sleep Power Control */ +#define TIVA_SYSCON_LDOSPCAL_OFFSET 0x1b8 /* LDO Sleep Power Calibration */ +#define TIVA_SYSCON_LDODPCTL_OFFSET 0x1bc /* LDO Deep-Sleep Power Control */ +#define TIVA_SYSCON_LDODPCAL_OFFSET 0x1c0 /* LDO Deep-Sleep Power Calibration */ +#define TIVA_SYSCON_SDPMST_OFFSET 0x1cc /* Sleep / Deep-Sleep Power Mode Status */ + +#define TIVA_SYSCON_PPWD_OFFSET 0x300 /* Watchdog Timer Peripheral Present */ +#define TIVA_SYSCON_PPTIMER_OFFSET 0x304 /* 16/32-Bit Timer Peripheral Present */ +#define TIVA_SYSCON_PPGPIO_OFFSET 0x308 /* GPIO Peripheral Present */ +#define TIVA_SYSCON_PPDMA_OFFSET 0x30c /* uDMA Peripheral Present */ +#define TIVA_SYSCON_PPHIB_OFFSET 0x314 /* Hibernation Peripheral Present */ +#define TIVA_SYSCON_PPUART_OFFSET 0x318 /* UART Present */ +#define TIVA_SYSCON_PPSSI_OFFSET 0x31c /* SSI Peripheral Present */ +#define TIVA_SYSCON_PPI2C_OFFSET 0x320 /* I2C Peripheral Present */ +#define TIVA_SYSCON_PPUSB_OFFSET 0x328 /* USB Peripheral Present */ +#define TIVA_SYSCON_PPCAN_OFFSET 0x334 /* CAN Peripheral Present */ +#define TIVA_SYSCON_PPADC_OFFSET 0x338 /* ADC Peripheral Present */ +#define TIVA_SYSCON_PPACMP_OFFSET 0x33c /* Analog Comparator Peripheral Present */ +#define TIVA_SYSCON_PPPWM_OFFSET 0x340 /* Pulse Width Modulator Peripheral Present */ +#define TIVA_SYSCON_PPQEI_OFFSET 0x344 /* Quadrature Encoder Peripheral Present */ +#define TIVA_SYSCON_PPEEPROM_OFFSET 0x358 /* EEPROM Peripheral Present */ +#define TIVA_SYSCON_PPWTIMER_OFFSET 0x35c /* 32/64-Bit Wide Timer Peripheral Present */ + +#define TIVA_SYSCON_SRWD_OFFSET 0x500 /* Watchdog Timer Software Reset */ +#define TIVA_SYSCON_SRTIMER_OFFSET 0x504 /* 16/32-Bit Timer Software Reset */ +#define TIVA_SYSCON_SRGPIO_OFFSET 0x508 /* GPIO Software Reset */ +#define TIVA_SYSCON_SRDMA_OFFSET 0x50c /* uDMA Software Reset */ +#define TIVA_SYSCON_SRHIB_OFFSET 0x514 /* Hibernation Software Reset */ +#define TIVA_SYSCON_SRUART_OFFSET 0x518 /* UART Software Reset*/ +#define TIVA_SYSCON_SRSSI_OFFSET 0x51c /* SSI Software Reset */ +#define TIVA_SYSCON_SRI2C_OFFSET 0x520 /* I2C Software Reset */ +#define TIVA_SYSCON_SRUSB_OFFSET 0x528 /* USB Software Reset */ +#define TIVA_SYSCON_SRCAN_OFFSET 0x534 /* CAN Software Reset */ +#define TIVA_SYSCON_SRADC_OFFSET 0x538 /* ADC Software Reset */ +#define TIVA_SYSCON_SRACMP_OFFSET 0x53c /* Analog Comparator Software Reset */ +#define TIVA_SYSCON_SRPWM_OFFSET 0x540 /* Pulse Width Modulator Software Reset */ +#define TIVA_SYSCON_SRQEI_OFFSET 0x544 /* Quadrature Encoder Interface Software Reset */ +#define TIVA_SYSCON_SREEPROM_OFFSET 0x558 /* EEPROM Software Reset */ +#define TIVA_SYSCON_SRWTIMER_OFFSET 0x55c /* 32/64-Bit Wide Timer Software Reset */ + +#define TIVA_SYSCON_RCGCWD_OFFSET 0x600 /* Watchdog Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCTIMER_OFFSET 0x604 /* 16/32-Bit Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCGPIO_OFFSET 0x608 /* GPIO Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCDMA_OFFSET 0x60c /* uDMA Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCHIB_OFFSET 0x614 /* Hibernation Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUART_OFFSET 0x618 /* UART Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCSSI_OFFSET 0x61c /* SSI Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCI2C_OFFSET 0x620 /* I2C Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUSB_OFFSET 0x628 /* USB Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCCAN_OFFSET 0x634 /* CAN Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCADC_OFFSET 0x638 /* ADC Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCACMP_OFFSET 0x63c /* Analog Comparator Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCPWM_OFFSET 0x640 /* Pulse Width Modulator Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCQEI_OFFSET 0x644 /* Quadrature Encoder Interface Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEEPROM_OFFSET 0x658 /* EEPROM Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCWTIMER_OFFSET 0x65c /* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define TIVA_SYSCON_SCGCWD_OFFSET 0x700 /* Watchdog Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCTIMER_OFFSET 0x704 /* 16/32-Bit Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCGPIO_OFFSET 0x708 /* GPIO Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCDMA_OFFSET 0x70c /* uDMA Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCHIB_OFFSET 0x714 /* Hibernation Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUART_OFFSET 0x718 /* UART Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCSSI_OFFSET 0x71c /* SSI Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCI2C_OFFSET 0x720 /* I2C Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUSB_OFFSET 0x728 /* USB Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCCAN_OFFSET 0x734 /* CAN Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCADC_OFFSET 0x738 /* ADC Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCACMP_OFFSET 0x73c /* Analog Comparator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCPWM_OFFSET 0x740 /* PulseWidthModulator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCQEI_OFFSET 0x744 /* Quadrature Encoder Interface Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEEPROM_OFFSET 0x758 /* EEPROM Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCWTIMER_OFFSET 0x75c /* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_DCGCWD_OFFSET 0x800 /* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCTIMER_OFFSET 0x804 /* Clock Gating Control */ +#define TIVA_SYSCON_DCGCGPIO_OFFSET 0x808 /* GPIO Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCDMA_OFFSET 0x80c /* uDMA Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCHIB_OFFSET 0x814 /* Hibernation Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUART_OFFSET 0x818 /* UART Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCSSI_OFFSET 0x81c /* SSI Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCI2C_OFFSET 0x820 /* I2C Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUSB_OFFSET 0x828 /* USB Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCCAN_OFFSET 0x834 /* CAN Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCADC_OFFSET 0x838 /* ADC Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCACMP_OFFSET 0x83c /* Analog Comparator Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCPWM_OFFSET 0x840 /* Pulse Width Modulator Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCQEI_OFFSET 0x844 /* Quadrature Encoder Interface Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEEPROM_OFFSET 0x858 /* EEPROM Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCWTIMER_OFFSET 0x85c /* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_PRWD_OFFSET 0xa00 /* Watchdog Timer Peripheral Ready */ +#define TIVA_SYSCON_PRTIMER_OFFSET 0xa04 /* 16/32-Bit Timer Peripheral Ready */ +#define TIVA_SYSCON_PRGPIO_OFFSET 0xa08 /* GPIO Peripheral Ready */ +#define TIVA_SYSCON_PRDMA_OFFSET 0xa0c /* uDMA Peripheral Ready */ +#define TIVA_SYSCON_PRHIB_OFFSET 0xa14 /* Hibernation Peripheral Ready */ +#define TIVA_SYSCON_PRUART_OFFSET 0xa18 /* UART Peripheral Ready */ +#define TIVA_SYSCON_PRSSI_OFFSET 0xa1c /* SSI Peripheral Ready */ +#define TIVA_SYSCON_PRI2C_OFFSET 0xa20 /* I2C Peripheral Ready */ +#define TIVA_SYSCON_PRUSB_OFFSET 0xa28 /* USB Peripheral Ready */ +#define TIVA_SYSCON_PRCAN_OFFSET 0xa34 /* CAN Peripheral Ready */ +#define TIVA_SYSCON_PRADC_OFFSET 0xa38 /* ADC Peripheral Ready */ +#define TIVA_SYSCON_PRACMP_OFFSET 0xa3c /* Analog Comparator Peripheral Ready */ +#define TIVA_SYSCON_PRPWM_OFFSET 0xa40 /* Pulse Width Modulator Peripheral Ready */ +#define TIVA_SYSCON_PRQEI_OFFSET 0xa44 /* Quadrature Encoder Interface Peripheral Ready */ +#define TIVA_SYSCON_PREEPROM_OFFSET 0xa58 /* EEPROM Peripheral Ready */ +#define TIVA_SYSCON_PRWTIMER_OFFSET 0xa5c /* 2/64-BitWide Timer Peripheral Ready */ + +/* System Control Legacy Register Offsets ***************************************************/ + +#define TIVA_SYSCON_DC0_OFFSET 0x008 /* Device Capabilities 0 */ +#define TIVA_SYSCON_DC1_OFFSET 0x010 /* Device Capabilities 1 */ +#define TIVA_SYSCON_DC2_OFFSET 0x014 /* Device Capabilities 2 */ +#define TIVA_SYSCON_DC3_OFFSET 0x018 /* Device Capabilities 3 */ +#define TIVA_SYSCON_DC4_OFFSET 0x01c /* Device Capabilities 4 */ +#define TIVA_SYSCON_DC5_OFFSET 0x020 /* Device Capabilities 5 */ +#define TIVA_SYSCON_DC6_OFFSET 0x024 /* Device Capabilities 6 */ +#define TIVA_SYSCON_DC7_OFFSET 0x028 /* Device Capabilities 7 */ +#define TIVA_SYSCON_DC8_OFFSET 0x02c /* Device Capabilities 8 */ + +#define TIVA_SYSCON_SRCR0_OFFSET 0x040 /* Software Reset Control 0 */ +#define TIVA_SYSCON_SRCR1_OFFSET 0x044 /* Software Reset Control 1 */ +#define TIVA_SYSCON_SRCR2_OFFSET 0x048 /* Software Reset Control 2 */ + +#define TIVA_SYSCON_RCGC0_OFFSET 0x100 /* Run Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_RCGC1_OFFSET 0x104 /* Run Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_RCGC2_OFFSET 0x108 /* Run Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_SCGC0_OFFSET 0x110 /* Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_SCGC1_OFFSET 0x114 /* Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_SCGC2_OFFSET 0x118 /* Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DCGC0_OFFSET 0x120 /* Deep Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_DCGC1_OFFSET 0x124 /* Deep Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_DCGC2_OFFSET 0x128 /* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DC9_OFFSET 0x190 /* Device Capabilities */ +#define TIVA_SYSCON_NVMSTAT_OFFSET 0x1a0 /* Non-Volatile Memory Information */ + +/* System Control Register Addresses ********************************************************/ + +#define TIVA_SYSCON_DID0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID0_OFFSET) +#define TIVA_SYSCON_DID1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID1_OFFSET) +#define TIVA_SYSCON_PBORCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_PBORCTL_OFFSET) +#define TIVA_SYSCON_RIS (TIVA_SYSCON_BASE + TIVA_SYSCON_RIS_OFFSET) +#define TIVA_SYSCON_IMC (TIVA_SYSCON_BASE + TIVA_SYSCON_IMC_OFFSET) +#define TIVA_SYSCON_MISC (TIVA_SYSCON_BASE + TIVA_SYSCON_MISC_OFFSET) +#define TIVA_SYSCON_RESC (TIVA_SYSCON_BASE + TIVA_SYSCON_RESC_OFFSET) +#define TIVA_SYSCON_RCC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC_OFFSET) +#define TIVA_SYSCON_GPIOHBCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_GPIOHBCTL_OFFSET) +#define TIVA_SYSCON_RCC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC2_OFFSET) +#define TIVA_SYSCON_MOSCCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_MOSCCTL_OFFSET) +#define TIVA_SYSCON_DSLPCLKCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPCLKCFG_OFFSET) +#define TIVA_SYSCON_SYSPROP (TIVA_SYSCON_BASE + TIVA_SYSCON_SYSPROP_OFFSET) +#define TIVA_SYSCON_PIOSCCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCCAL_OFFSET) +#define TIVA_SYSCON_PIOSCSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCSTAT_OFFSET) +#define TIVA_SYSCON_PLLFREQ0 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ0_OFFSET) +#define TIVA_SYSCON_PLLFREQ1 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ1_OFFSET) +#define TIVA_SYSCON_PLLSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLSTAT_OFFSET) +#define TIVA_SYSCON_SLPPWRCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_SLPPWRCFG_OFFSET) +#define TIVA_SYSCON_DSLPPWRCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPPWRCFG_OFFSET) +#define TIVA_SYSCON_LDOSPCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDOSPCTL_OFFSET) +#define TIVA_SYSCON_LDOSPCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDOSPCAL_OFFSET) +#define TIVA_SYSCON_LDODPCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDODPCTL_OFFSET) +#define TIVA_SYSCON_LDODPCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDODPCAL_OFFSET) +#define TIVA_SYSCON_SDPMST (TIVA_SYSCON_BASE + TIVA_SYSCON_SDPMST_OFFSET) + +#define TIVA_SYSCON_PPWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWD_OFFSET) +#define TIVA_SYSCON_PPTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPTIMER_OFFSET) +#define TIVA_SYSCON_PPGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PPGPIO_OFFSET) +#define TIVA_SYSCON_PPDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PPDMA_OFFSET) +#define TIVA_SYSCON_PPHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPHIB_OFFSET) +#define TIVA_SYSCON_PPUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUART_OFFSET) +#define TIVA_SYSCON_PPSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPSSI_OFFSET) +#define TIVA_SYSCON_PPI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PPI2C_OFFSET) +#define TIVA_SYSCON_PPUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUSB_OFFSET) +#define TIVA_SYSCON_PPCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PPCAN_OFFSET) +#define TIVA_SYSCON_PPADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PPADC_OFFSET) +#define TIVA_SYSCON_PPACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PPACMP_OFFSET) +#define TIVA_SYSCON_PPPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPPWM_OFFSET) +#define TIVA_SYSCON_PPQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPQEI_OFFSET) +#define TIVA_SYSCON_PPEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPEEPROM_OFFSET) +#define TIVA_SYSCON_PPWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWTIMER_OFFSET) + +#define TIVA_SYSCON_SRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWD_OFFSET) +#define TIVA_SYSCON_SRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRTIMER_OFFSET) +#define TIVA_SYSCON_SRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SRGPIO_OFFSET) +#define TIVA_SYSCON_SRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SRDMA_OFFSET) +#define TIVA_SYSCON_SRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRHIB_OFFSET) +#define TIVA_SYSCON_SRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUART_OFFSET) +#define TIVA_SYSCON_SRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SRSSI_OFFSET) +#define TIVA_SYSCON_SRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SRI2C_OFFSET) +#define TIVA_SYSCON_SRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUSB_OFFSET) +#define TIVA_SYSCON_SRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCAN_OFFSET) +#define TIVA_SYSCON_SRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SRADC_OFFSET) +#define TIVA_SYSCON_SRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SRACMP_OFFSET) +#define TIVA_SYSCON_SRPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_SRPWM_OFFSET) +#define TIVA_SYSCON_SRQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_SRQEI_OFFSET) +#define TIVA_SYSCON_SREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SREEPROM_OFFSET) +#define TIVA_SYSCON_SRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWTIMER_OFFSET) + +#define TIVA_SYSCON_RCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWD_OFFSET) +#define TIVA_SYSCON_RCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCTIMER_OFFSET) +#define TIVA_SYSCON_RCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCGPIO_OFFSET) +#define TIVA_SYSCON_RCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCDMA_OFFSET) +#define TIVA_SYSCON_RCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCHIB_OFFSET) +#define TIVA_SYSCON_RCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUART_OFFSET) +#define TIVA_SYSCON_RCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCSSI_OFFSET) +#define TIVA_SYSCON_RCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCI2C_OFFSET) +#define TIVA_SYSCON_RCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUSB_OFFSET) +#define TIVA_SYSCON_RCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCCAN_OFFSET) +#define TIVA_SYSCON_RCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCADC_OFFSET) +#define TIVA_SYSCON_RCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCACMP_OFFSET) +#define TIVA_SYSCON_RCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCPWM_OFFSET) +#define TIVA_SYSCON_RCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCQEI_OFFSET) +#define TIVA_SYSCON_RCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCEEPROM_OFFSET) +#define TIVA_SYSCON_RCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_SCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWD_OFFSET) +#define TIVA_SYSCON_SCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCTIMER_OFFSET) +#define TIVA_SYSCON_SCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCGPIO_OFFSET) +#define TIVA_SYSCON_SCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCDMA_OFFSET) +#define TIVA_SYSCON_SCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCHIB_OFFSET) +#define TIVA_SYSCON_SCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUART_OFFSET) +#define TIVA_SYSCON_SCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCSSI_OFFSET) +#define TIVA_SYSCON_SCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCI2C_OFFSET) +#define TIVA_SYSCON_SCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUSB_OFFSET) +#define TIVA_SYSCON_SCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCCAN_OFFSET) +#define TIVA_SYSCON_SCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCADC_OFFSET) +#define TIVA_SYSCON_SCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCACMP_OFFSET) +#define TIVA_SYSCON_SCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCPWM_OFFSET +#define TIVA_SYSCON_SCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCQEI_OFFSET +#define TIVA_SYSCON_SCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCEEPROM_OFFSET) +#define TIVA_SYSCON_SCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_DCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWD_OFFSET) +#define TIVA_SYSCON_DCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCTIMER_OFFSET) +#define TIVA_SYSCON_DCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCGPIO_OFFSET) +#define TIVA_SYSCON_DCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCDMA_OFFSET) +#define TIVA_SYSCON_DCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCHIB_OFFSET) +#define TIVA_SYSCON_DCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUART_OFFSET) +#define TIVA_SYSCON_DCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCSSI_OFFSET) +#define TIVA_SYSCON_DCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCI2C_OFFSET) +#define TIVA_SYSCON_DCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUSB_OFFSET) +#define TIVA_SYSCON_DCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCCAN_OFFSET) +#define TIVA_SYSCON_DCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCADC_OFFSET) +#define TIVA_SYSCON_DCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCACMP_OFFSET) +#define TIVA_SYSCON_DCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCPWM_OFFSET) +#define TIVA_SYSCON_DCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCQEI_OFFSET) +#define TIVA_SYSCON_DCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCEEPROM_OFFSET) +#define TIVA_SYSCON_DCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_PRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWD_OFFSET) +#define TIVA_SYSCON_PRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRTIMER_OFFSET) +#define TIVA_SYSCON_PRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PRGPIO_OFFSET) +#define TIVA_SYSCON_PRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PRDMA_OFFSET) +#define TIVA_SYSCON_PRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRHIB_OFFSET) +#define TIVA_SYSCON_PRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUART_OFFSET) +#define TIVA_SYSCON_PRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PRSSI_OFFSET) +#define TIVA_SYSCON_PRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PRI2C_OFFSET) +#define TIVA_SYSCON_PRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUSB_OFFSET) +#define TIVA_SYSCON_PRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PRCAN_OFFSET) +#define TIVA_SYSCON_PRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PRADC_OFFSET) +#define TIVA_SYSCON_PRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PRACMP_OFFSET) +#define TIVA_SYSCON_PRPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_PRPWM_OFFSET) +#define TIVA_SYSCON_PRQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_PRQEI_OFFSET) +#define TIVA_SYSCON_PREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PREEPROM_OFFSET) +#define TIVA_SYSCON_PRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWTIMER_OFFSET) + +/* System Control Legacy Register Addresses *************************************************/ + +#define TIVA_SYSCON_DC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC0_OFFSET) +#define TIVA_SYSCON_DC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC1_OFFSET) +#define TIVA_SYSCON_DC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC2_OFFSET) +#define TIVA_SYSCON_DC3 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC3_OFFSET) +#define TIVA_SYSCON_DC4 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC4_OFFSET) +#define TIVA_SYSCON_DC5 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC5_OFFSET) +#define TIVA_SYSCON_DC6 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC6_OFFSET) +#define TIVA_SYSCON_DC7 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC7_OFFSET) +#define TIVA_SYSCON_DC8 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC8_OFFSET) + +#define TIVA_SYSCON_SRCR0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR0_OFFSET) +#define TIVA_SYSCON_SRCR1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR1_OFFSET) +#define TIVA_SYSCON_SRCR2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR2_OFFSET) + +#define TIVA_SYSCON_RCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC0_OFFSET) +#define TIVA_SYSCON_RCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC1_OFFSET) +#define TIVA_SYSCON_RCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC2_OFFSET) + +#define TIVA_SYSCON_SCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC0_OFFSET) +#define TIVA_SYSCON_SCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC1_OFFSET) +#define TIVA_SYSCON_SCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC2_OFFSET) + +#define TIVA_SYSCON_DCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC0_OFFSET) +#define TIVA_SYSCON_DCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC1_OFFSET) +#define TIVA_SYSCON_DCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC2_OFFSET) + +#define TIVA_SYSCON_DC9 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC9_OFFSET) +#define TIVA_SYSCON_NVMSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_NVMSTAT_OFFSET) + +/* System Control Register Bit Definitions **************************************************/ + +/* Device Identification 0 */ + +#define SYSCON_DID0_MINOR_SHIFT 0 /* Bits 7-0: Minor Revision of the device */ +#define SYSCON_DID0_MINOR_MASK (0xff << SYSCON_DID0_MINOR_SHIFT) +#define SYSCON_DID0_MAJOR_SHIFT 8 /* Bits 15-8: Major Revision of the device */ +#define SYSCON_DID0_MAJOR_MASK (0xff << SYSCON_DID0_MAJOR_SHIFT) +#define SYSCON_DID0_CLASS_SHIFT 16 /* Bits 23-16: Device Class */ +#define SYSCON_DID0_CLASS_MASK (0xff << SYSCON_DID0_CLASS_SHIFT) +#define SYSCON_DID0_VER_SHIFT 28 /* Bits 30-28: DID0 Version */ +#define SYSCON_DID0_VER_MASK (7 << SYSCON_DID0_VER_SHIFT) + +/* Device Identification 1 */ + +#define SYSCON_DID1_QUAL_SHIFT 0 /* Bits 1-0: Qualification Status */ +#define SYSCON_DID1_QUAL_MASK (0x03 << SYSCON_DID1_QUAL_SHIFT) +#define SYSCON_DID1_ROHS (1 << 2) /* Bit 2: RoHS-Compliance */ +#define SYSCON_DID1_PKG_SHIFT 3 /* Bits 4-3: Package Type */ +#define SYSCON_DID1_PKG_MASK (0x03 << SYSCON_DID1_PKG_SHIFT) +#define SYSCON_DID1_TEMP_SHIFT 5 /* Bits 7-5: Temperature Range */ +#define SYSCON_DID1_TEMP_MASK (0x07 << SYSCON_DID1_TEMP_SHIFT) +#define SYSCON_DID1_PINCOUNT_SHIFT 13 /* Bits 15-13: Package Pin Count */ +#define SYSCON_DID1_PINCOUNT_MASK (0x07 << SYSCON_DID1_PINCOUNT_SHIFT) +#define SYSCON_DID1_PARTNO_SHIFT 16 /* Bits 23-16: Part Number */ +#define SYSCON_DID1_PARTNO_MASK (0xff << SYSCON_DID1_PARTNO_SHIFT) +#define SYSCON_DID1_FAM_SHIFT 24 /* Bits 27-24: Family */ +#define SYSCON_DID1_FAM_MASK (0x0f << SYSCON_DID1_FAM_SHIFT) +#define SYSCON_DID1_VER_SHIFT 28 /* Bits 31-28: DID1 Version */ +#define SYSCON_DID1_VER_MASK (0x0f << SYSCON_DID1_VER_SHIFT) + +/* Brown-Out Reset Control */ + +#define SYSCON_PBORCTL_BORI1 (1 << 1) /* Bit 1: VDD under BOR1 Event Action */ +#define SYSCON_PBORCTL_BORI0 (1 << 2) /* Bit 2: VDD under BOR0 Event Action */ + +/* Raw Interrupt Status */ + +#define SYSCON_RIS_BORR1RIS (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Status */ +#define SYSCON_RIS_MOFRIS (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Status */ +#define SYSCON_RIS_PLLLRIS (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_USBPLLLRIS (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_MOSCPUPRIS (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Status */ +#define SYSCON_RIS_VDDARIS (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Status */ +#define SYSCON_RIS_BOR0RIS (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Status */ + +/* Interrupt Mask Control */ + +#define SYSCON_IMC_BORR1RIM (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Mask */ +#define SYSCON_IMC_MOFRIM (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Mask */ +#define SYSCON_IMC_PLLLRIM (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Mask */ +#define SYSCON_IMC_USBPLLLRIM (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Mask */ +#define SYSCON_IMC_MOSCPUPRIM (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Mask */ +#define SYSCON_IMC_VDDARIM (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Mask */ +#define SYSCON_IMC_BOR0RIM (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Mask */ + +/* Masked Interrupt Status and Clear */ + +#define SYSCON_MISC_BORR1MIS (1 << 1) /* Bit 1: VDD under BOR1 Masked Interrupt Status */ +#define SYSCON_MISC_MOFMIS (1 << 3) /* Bit 3: Main Oscillator Failure Masked Interrupt Status */ +#define SYSCON_MISC_PLLLMIS (1 << 6) /* Bit 6: PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_USBPLLLMIS (1 << 7) /* Bit 7: USB PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_MOSCPUPMIS (1 << 8) /* Bit 8: MOSC Power Up Masked Interrupt Status */ +#define SYSCON_MISC_VDDAMIS (1 << 10) /* Bit 10: VDDA Power OK Event Masked Interrupt Status */ +#define SYSCON_MISC_BOR0MIS (1 << 11) /* Bit 11: VDD under BOR0 Masked Interrupt Status */ + +/* Reset Cause */ + +#define SYSCON_RESC_EXT (1 << 0) /* Bit 0: External Reset */ +#define SYSCON_RESC_POR (1 << 1) /* Bit 1: Power-On Reset */ +#define SYSCON_RESC_BOR (1 << 2) /* Bit 2: Brown-Out Reset */ +#define SYSCON_RESC_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset */ +#define SYSCON_RESC_SW (1 << 4) /* Bit 4: Software Reset */ +#define SYSCON_RESC_WDT1 (1 << 5) /* Bit 5: Watchdog Timer 1 Reset */ +#define SYSCON_RESC_MOSCFAIL (1 << 16) /* Bit 16: MOSC Failure Reset */ + +/* Run-Mode Clock Configuration */ + +#define SYSCON_RCC_MOSCDIS (1 << 0) /* Bit 0: Main Oscillator Disable */ +#define SYSCON_RCC_OSCSRC_SHIFT 4 /* Bits 5-4: Oscillator Source */ +#define SYSCON_RCC_OSCSRC_MASK (0x03 << SYSCON_RCC_OSCSRC_SHIFT) +# define SYSCON_RCC_OSCSRC_MOSC (0 << SYSCON_RCC_OSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_RCC_OSCSRC_PIOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC_OSCSRC_PIOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC_OSCSRC_LFIOSC (3 << SYSCON_RCC_OSCSRC_SHIFT) /* Low-frequency internal oscillator */ +#define SYSCON_RCC_XTAL_SHIFT 6 /* Bits 10-6: Crystal Value */ +#define SYSCON_RCC_XTAL_MASK (31 << SYSCON_RCC_XTAL_SHIFT) +# define SYSCON_RCC_XTAL4000KHZ (6 << SYSCON_RCC_XTAL_SHIFT) /* 4 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4096KHZ (7 << SYSCON_RCC_XTAL_SHIFT) /* 4.096 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4915p2KHZ (8 << SYSCON_RCC_XTAL_SHIFT) /* 4.9152 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL5000KHZ (9 << SYSCON_RCC_XTAL_SHIFT) /* 5 MHz (USB) */ +# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.12 MHz */ +# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6 MHz (USB) */ +# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.144 MHz */ +# define SYSCON_RCC_XTAL7372p8KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728 MHz */ +# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8 MHz (USB) */ +# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.192 MHz */ +# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12288KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */ +# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */ +# define SYSCON_RCC_XTAL14318p18KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */ +# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */ +# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */ +# define SYSCON_RCC_XTAL18000KHZ (23 << SYSCON_RCC_XTAL_SHIFT) /* 18.0 MHz (USB) */ +# define SYSCON_RCC_XTAL20000KHZ (24 << SYSCON_RCC_XTAL_SHIFT) /* 20.0 MHz (USB) */ +# define SYSCON_RCC_XTAL24000KHZ (25 << SYSCON_RCC_XTAL_SHIFT) /* 24.0 MHz (USB) */ +# define SYSCON_RCC_XTAL25000KHZ (26 << SYSCON_RCC_XTAL_SHIFT) /* 25.0 MHz (USB) */ +# define SYSCON_RCC_XTAL40000KHZ (27 << SYSCON_RCC_XTAL_SHIFT) /* 40.0 MHz */ +#define SYSCON_RCC_BYPASS (1 << 11) /* Bit 11: PLL Bypass */ +#define SYSCON_RCC_PWRDN (1 << 13) /* Bit 13: PLL Power Down */ +#define SYSCON_RCC_PWMDIV_SHIFT 17 /* Bits 19-17: PWM Unit Clock Divisor */ +#define SYSCON_RCC_PWMDIV_MASK (7 << SYSCON_RCC_PWMDIV_SHIFT) +# define SYSCON_RCC_PWMDIV_2 (0 << SYSCON_RCC_PWMDIV_SHIFT) /* /2 */ +# define SYSCON_RCC_PWMDIV_4 (1 << SYSCON_RCC_PWMDIV_SHIFT) /* /4 */ +# define SYSCON_RCC_PWMDIV_8 (2 << SYSCON_RCC_PWMDIV_SHIFT) /* /8 */ +# define SYSCON_RCC_PWMDIV_16 (3 << SYSCON_RCC_PWMDIV_SHIFT) /* /16 */ +# define SYSCON_RCC_PWMDIV_32 (4 << SYSCON_RCC_PWMDIV_SHIFT) /* /32 */ +# define SYSCON_RCC_PWMDIV_64 (7 << SYSCON_RCC_PWMDIV_SHIFT) /* /64 (default) */ +#define SYSCON_RCC_USEPWMDIV (1 << 20) /* Bit 20: Enable PWM Clock Divisor */ +#define SYSCON_RCC_USESYSDIV (1 << 22) /* Bit 22: Enable System Clock Divider */ +#define SYSCON_RCC_SYSDIV_SHIFT 23 /* Bits 26-23: System Clock Divisor */ +#define SYSCON_RCC_SYSDIV_MASK (0x0f << SYSCON_RCC_SYSDIV_SHIFT) +# define SYSCON_RCC_SYSDIV(n) (((n)-1) << SYSCON_RCC_SYSDIV_SHIFT) +#define SYSCON_RCC_ACG (1 << 27) /* Bit 27: Auto Clock Gating */ + +/* GPIO High-Performance Bus Control */ + +#define SYSCON_GPIOHBCTL_PORT(n) (1 << (n)) +# define SYSCON_GPIOHBCTL_PORTA (1 << 0) /* Bit 0: Port A Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTB (1 << 1) /* Bit 1: Port B Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTC (1 << 2) /* Bit 2: Port C Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTD (1 << 3) /* Bit 3: Port D Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTE (1 << 4) /* Bit 4: Port E Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTF (1 << 5) /* Bit 5: Port F Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTG (1 << 6) /* Bit 6: Port G Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTH (1 << 7) /* Bit 7: Port H Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTJ (1 << 8) /* Bit 8: Port J Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTK (1 << 9) /* Bit 9: Port K Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTL (1 << 10) /* Bit 10: Port L Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTM (1 << 11) /* Bit 11: Port M Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTN (1 << 12) /* Bit 12: Port N Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTP (1 << 13) /* Bit 13: Port P Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTQ (1 << 14) /* Bit 14: Port Q Advanced High-Performance Bus */ + +/* Run-Mode Clock Configuration 2 */ + +#define SYSCON_RCC2_OSCSRC2_SHIFT 4 /* Bits 6-4: Oscillator Source */ +#define SYSCON_RCC2_OSCSRC2_MASK (7 << SYSCON_RCC2_OSCSRC2_SHIFT) +# define SYSCON_RCC2_OSCSRC2_MOSC (0 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Main oscillator */ +# define SYSCON_RCC2_OSCSRC2_PIOSC (1 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC2_OSCSRC2_PIOSC4 (2 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC2_OSCSRC2_LFIOSC (4 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_RCC2_OSCSRC2_32768HZ (7 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_RCC2_BYPASS2 (1 << 11) /* Bit 11: Bypass PLL */ +#define SYSCON_RCC2_PWRDN2 (1 << 13) /* Bit 13: Power-Down PLL */ +#define SYSCON_RCC2_USBPWRDN (1 << 14) /* Bit 14: Power-Down USB PLL */ +#define SYSCON_RCC2_SYSDIV2LSB (1 << 22) /* Bit 22: Additional LSB for SYSDIV2 */ +#define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */ +#define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV_DIV400(n) (((n-1) >> 1) << SYSCON_RCC2_SYSDIV2_SHIFT) +#define SYSCON_RCC2_DIV400 (1 << 30) /* Bit 30: Divide PLL as 400 MHz vs. 200 MHz */ +#define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */ + +/* Main Oscillator Control */ + +#define SYSCON_MOSCCTL_CVAL (1 << 0) /* Bit 0: Clock Validation for MOSC */ +#define SYSCON_MOSCCTL_MOSCIM (1 << 1) /* Bit 1: MOSC Failure Action */ +#define SYSCON_MOSCCTL_NOXTAL (1 << 2) /* Bit 2: No Crystal Connected */ + +/* Deep Sleep Clock Configuration */ + +#define SYSCON_DSLPCLKCFG_PIOSCPD (1 << 1) /* Bit 1: PIOSC Power Down Request */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT 4 /* Bits 6-4: Clock Source */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_MASK (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) +# define SYSCON_DSLPCLKCFG_DSOSCSRC_MOSC (0 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC (1 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC4 (2 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_LFIOSC (4 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_32768KHZ (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT 23 /* Bits 28-23: Divider Field Override */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_MASK (0x3f << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) +# define SYSCON_DSLPCLKCFG_DSDIVORIDE(b) (((n)-1) << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) + +/* System Properties */ + +#define SYSCON_SYSPROP_FPU (1 << 0) /* Bit 0: FPU Present */ +#define SYSCON_SYSPROP_FLASHLPM (1 << 8) /* Bit 8: Flash Memory Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMLPM (1 << 10) /* Bit 10: SRAM Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMSM (1 << 11) /* Bit 11: SRAM Sleep/Deep-Sleep Standby Mode Present */ +#define SYSCON_SYSPROP_PIOSCPDE (1 << 12) /* Bit 12: PIOSC Power Down Present */ + +/* Precision Internal Oscillator Calibration */ + +#define SYSCON_PIOSCCAL_UT_SHIFT (0) /* Bits 0-6: User Trim Value */ +#define SYSCON_PIOSCCAL_UT_MASK (0x7f << SYSCON_PIOSCCAL_UT_SHIFT) +# define SYSCON_PIOSCCAL_UT(n) ((uint32_t)(n) << SYSCON_PIOSCCAL_UT_SHIFT) +#define SYSCON_PIOSCCAL_UPDATE (1 << 8) /* Bit 8: Update Trim */ +#define SYSCON_PIOSCCAL_CAL (1 << 9) /* Bit 9: Start Calibration */ +#define SYSCON_PIOSCCAL_UTEN (1 << 31) /* Bit 31: Use User Trim Value */ + +/* Precision Internal Oscillator Statistics */ + +#define SYSCON_PIOSCSTAT_CT_SHIFT (0) /* Bits 0-6: Calibration Trim Value */ +#define SYSCON_PIOSCSTAT_CT_MASK (0x7f << SYSCON_PIOSCSTAT_CT_SHIFT) +# define SYSCON_PIOSCSTAT_CT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_CT_SHIFT) +#define SYSCON_PIOSCSTAT_RESULT_SHIFT (8) /* Bits 8-9: Calibration Result */ +#define SYSCON_PIOSCSTAT_RESULT_MASK (3 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_RESULT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_RESULT_SHIFT) +#define SYSCON_PIOSCSTAT_DT_SHIFT (16) /* Bits 16-22: Default Trim Value */ +#define SYSCON_PIOSCSTAT_DT_MASK (0x7f << SYSCON_PIOSCSTAT_DT_SHIFT) +# define SYSCON_PIOSCSTAT_DT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_DT_SHIFT) + +/* PLL0 Frequency */ + +#define SYSCON_PLLFREQ0_MINT_SHIFT (0) /* Bits 0-9: PLL M Integer Value */ +#define SYSCON_PLLFREQ0_MINT_MASK (0x3ff << SYSCON_PLLFREQ0_MINT_SHIFT) +# define SYSCON_PLLFREQ0_MINT(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MINT_SHIFT) +#define SYSCON_PLLFREQ0_MFRAC_SHIFT (10) /* Bits 10-19: PLL M Fractional Value */ +#define SYSCON_PLLFREQ0_MFRAC_MASK (0x3ff << SYSCON_PLLFREQ0_MFRAC_SHIFT) +# define SYSCON_PLLFREQ0_MFRAC(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MFRAC_SHIFT) + +/* PLL1 Frequency */ + +#define SYSCON_PLLFREQ1_N_SHIFT (0) /* Bits 0-4: PLL N Value */ +#define SYSCON_PLLFREQ1_N_MASK (31 << SYSCON_PLLFREQ1_N_SHIFT) +# define SYSCON_PLLFREQ1_N(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_N_SHIFT) +#define SYSCON_PLLFREQ1_Q_SHIFT (8) /* Bits 8-12: PLL Q Value */ +#define SYSCON_PLLFREQ1_Q_MASK (31 << SYSCON_PLLFREQ1_Q_SHIFT) +# define SYSCON_PLLFREQ1_Q(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_Q_SHIFT) + +/* PLL Status */ + +#define SYSCON_PLLSTAT_LOCK (1 << 0) /* Bit 0: PLL Lock */ + +/* Sleep Power Configuration */ + +#define SYSCON_SLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_SLPPWRCFG_SRAMPM_MASK (3 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_SLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_LOWPWR (2 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_SLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_SLPPWRCFG_FLASHPM_MASK (3 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_SLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_FLASHPM_LOWPWRR (2 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ + +/* Deep-Sleep Power Configuration */ + +#define SYSCON_DSLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_DSLPPWRCFG_SRAMPM_MASK (3 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_DSLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_LOWPWR (2 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_DSLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_DSLPPWRCFG_FLASHPM_MASK (3 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_DSLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_FLASHPM_LOWPWR (2 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ + +/* LDO Sleep Power Control */ + +#define SYSCON_LDOSPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDOSPCTL_VLDO_MASK (0xff << SYSCON_LDOSPCTL_VLDO_SHIFT) +# define SYSCON_LDOSPCTL_VLDO_0p90V (0x12 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCTL_VLDO_0p95V (0x13 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCTL_VLDO_1p00V (0x14 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCTL_VLDO_1p05V (0x15 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCTL_VLDO_1p10V (0x16 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCTL_VLDO_1p15V (0x17 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCTL_VLDO_1p20V (0x18 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Sleep Power Calibration */ + +#define SYSCON_LDOSPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Sleep without PLL */ +#define SYSCON_LDOSPCAL_NOPLL_MASK (0xff << SYSCON_LDOSPCAL_NOPLL_SHIFT) +# define SYSCON_LDOSPCAL_NOPLL_0p90V (0x12 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_NOPLL_0p95V (0x13 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p00V (0x14 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p05V (0x15 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p10V (0x16 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p15V (0x17 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p20V (0x18 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCAL_WITHPLL_SHIFT (8) /* Bits 15-8: Sleep with PLL */ +#define SYSCON_LDOSPCAL_WITHPLL_MASK (0xff << SYSCON_LDOSPCAL_WITHPLL_SHIFT) +# define SYSCON_LDOSPCAL_WITHPLL_0p90V (0x12 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_WITHPLL_0p95V (0x13 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p00V (0x14 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p05V (0x15 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p10V (0x16 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p15V (0x17 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p20V (0x18 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.20 V */ + +/* LDO Deep-Sleep Power Control */ + +#define SYSCON_LDODPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDODPCTL_VLDO_MASK (0xff << SYSCON_LDODPCTL_VLDO_SHIFT) +# define SYSCON_LDODPCTL_VLDO_0p90V (0x12 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCTL_VLDO_0p95V (0x13 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCTL_VLDO_1p00V (0x14 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCTL_VLDO_1p05V (0x15 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCTL_VLDO_1p10V (0x16 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCTL_VLDO_1p15V (0x17 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCTL_VLDO_1p20V (0x18 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Deep-Sleep Power Calibration */ + +#define SYSCON_LDODPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Deep-Sleep without PLL */ +#define SYSCON_LDODPCAL_NOPLL_MASK (0xff << SYSCON_LDODPCAL_NOPLL_SHIFT) +# define SYSCON_LDODPCAL_NOPLL_0p90V (0x12 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_NOPLL_0p95V (0x13 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_NOPLL_1p00V (0x14 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_NOPLL_1p05V (0x15 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_NOPLL_1p10V (0x16 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_NOPLL_1p15V (0x17 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_NOPLL_1p20V (0x18 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCAL_30KHZ_SHIFT (8) /* Bits 15-8: Deep-Sleep with IOSC */ +#define SYSCON_LDODPCAL_30KHZ_MASK (0xff << SYSCON_LDODPCAL_30KHZ_SHIFT) +# define SYSCON_LDODPCAL_30KHZ_0p90V (0x12 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_30KHZ_0p95V (0x13 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_30KHZ_1p00V (0x14 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_30KHZ_1p05V (0x15 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_30KHZ_1p10V (0x16 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_30KHZ_1p15V (0x17 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_30KHZ_1p20V (0x18 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.20 V */ + +/* Sleep / Deep-Sleep Power Mode Status */ + +#define SYSCON_SDPMST_SPDERR (1 << 0) /* Bit 0: SRAM Power Down Request Error */ +#define SYSCON_SDPMST_FPDERR (1 << 1) /* Bit 1: Flash Memory Power Down Request Error */ +#define SYSCON_SDPMST_PPDERR (1 << 2) /* Bit 2: PIOSC Power Down Request Error */ +#define SYSCON_SDPMST_LDMINERR (1 << 3) /* Bit 3: VLDO Value Below Minimum Error in Deep-Sleep Mode */ +#define SYSCON_SDPMST_LSMINERR (1 << 4) /* Bit 4: VLDO Value Below Minimum Error in Sleep Mode */ +#define SYSCON_SDPMST_LMAXERR (1 << 6) /* Bit 6: VLDO Value Above Maximum Error */ +#define SYSCON_SDPMST_PPDW (1 << 7) /* Bit 7: PIOSC Power Down Request Warning */ +#define SYSCON_SDPMST_PRACT (1 << 16) /* Bit 16: Sleep or Deep-Sleep Power Request Active */ +#define SYSCON_SDPMST_LOWPWR (1 << 17) /* Bit 17: Sleep or Deep-Sleep Mode */ +#define SYSCON_SDPMST_FLASHLP (1 << 18) /* Bit 18: Flash Memory in Low Power State */ +#define SYSCON_SDPMST_LDOUA (1 << 19) /* Bit 19: LDO Update Active */ + +/* Watchdog Timer Peripheral Present */ + +#define SYSCON_PPWD(n) (1 << (n)) /* Bit n: WDTn present */ +# define SYSCON_PPWD_P0 (1 << 0) /* Bit 0: WDT0 present */ +# define SYSCON_PPWD_P1 (1 << 1) /* Bit 1: WDT1 present */ + +/* 16/32-Bit Timer Peripheral Present */ + +#define SYSCON_PPTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Present */ +# define SYSCON_PPTIMER_P0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 0 Present */ + +/* GPIO Peripheral Present */ + +#define SYSCON_PPGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Present */ +# define SYSCON_PPGPIO_P0 (1 << 0) /* Bit 0: GPIO Port A Present */ +# define SYSCON_PPGPIO_P1 (1 << 1) /* Bit 1: GPIO Port B Present */ +# define SYSCON_PPGPIO_P2 (1 << 2) /* Bit 2: GPIO Port C Present */ +# define SYSCON_PPGPIO_P3 (1 << 3) /* Bit 3: GPIO Port D Present */ +# define SYSCON_PPGPIO_P4 (1 << 4) /* Bit 4: GPIO Port E Present */ +# define SYSCON_PPGPIO_P5 (1 << 5) /* Bit 5: GPIO Port F Present */ +# define SYSCON_PPGPIO_P6 (1 << 6) /* Bit 6: GPIO Port G Present */ +# define SYSCON_PPGPIO_P7 (1 << 7) /* Bit 7: GPIO Port H Present */ +# define SYSCON_PPGPIO_P8 (1 << 8) /* Bit 8: GPIO Port J Present */ +# define SYSCON_PPGPIO_P9 (1 << 9) /* Bit 9: GPIO Port K Present */ +# define SYSCON_PPGPIO_P10 (1 << 10) /* Bit 10: GPIO Port L Present */ +# define SYSCON_PPGPIO_P11 (1 << 11) /* Bit 11: GPIO Port M Present */ +# define SYSCON_PPGPIO_P12 (1 << 12) /* Bit 12: GPIO Port N Present */ +# define SYSCON_PPGPIO_P13 (1 << 13) /* Bit 13: GPIO Port P Present */ +# define SYSCON_PPGPIO_P14 (1 << 14) /* Bit 14: GPIO Port Q Present */ + +/* uDMA Peripheral Present */ + +#define SYSCON_PPDMA_P0 (1 << 0) /* Bit 0: μDMA Module Present */ + +/* Hibernation Peripheral Present */ + +#define SYSCON_PPHIB_P0 (1 << 0) /* Bit 0: Hibernation Module Present */ + +/* UART Present */ + +#define SYSCON_PPUART(n) (1 << (n)) /* Bit n: UART Module n Present */ +# define SYSCON_PPUART_P0 (1 << 0) /* Bit 0: UART Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: UART Module 1 Present */ +# define SYSCON_PPUART_P2 (1 << 2) /* Bit 2: UART Module 2 Present */ +# define SYSCON_PPUART_P3 (1 << 3) /* Bit 3: UART Module 3 Present */ +# define SYSCON_PPUART_P4 (1 << 4) /* Bit 4: UART Module 4 Present */ +# define SYSCON_PPUART_P5 (1 << 5) /* Bit 5: UART Module 5 Present */ +# define SYSCON_PPUART_P6 (1 << 6) /* Bit 6: UART Module 6 Present */ +# define SYSCON_PPUART_P7 (1 << 7) /* Bit 7: UART Module 7 Present */ + +/* SSI Peripheral Present */ + +#define SYSCON_PPSSI(n) (1 << (n)) /* Bit n: SSI Module n Present */ +# define SYSCON_PPSSI_P0 (1 << 0) /* Bit 0: SSI Module 0 Present */ +# define SYSCON_PPSSI_P1 (1 << 1) /* Bit 1: SSI Module 1 Present */ +# define SYSCON_PPSSI_P2 (1 << 2) /* Bit 2: SSI Module 2 Present */ +# define SYSCON_PPSSI_P3 (1 << 3) /* Bit 3: SSI Module 3 Present */ + +/* I2C Peripheral Present */ + +#define SYSCON_PPI2C(n) (1 << (n)) /* Bit n: I2C Module n Present */ +# define SYSCON_PPI2C_P0 (1 << 0) /* Bit 0: I2C Module 0 Present */ +# define SYSCON_PPI2C_P1 (1 << 1) /* Bit 1: I2C Module 1 Present */ +# define SYSCON_PPI2C_P2 (1 << 2) /* Bit 2: I2C Module 2 Present */ +# define SYSCON_PPI2C_P3 (1 << 3) /* Bit 3: I2C Module 3 Present */ +# define SYSCON_PPI2C_P4 (1 << 4) /* Bit 4: I2C Module 4 Present */ +# define SYSCON_PPI2C_P5 (1 << 5) /* Bit 5: I2C Module 5 Present */ + +/* USB Peripheral Present */ + +#define SYSCON_PPUSB_P0 (1 << 0) /* USB Module Present */ + +/* CAN Peripheral Present */ + +#define SYSCON_PPCAN(n) (1 << (n)) /* Bit n: CAN Module n Present */ +# define SYSCON_PPCAN_P0 (1 << 0) /* Bit 0: CAN Module 0 Present */ +# define SYSCON_PPCAN_P1 (1 << 1) /* Bit 1: CAN Module 1 Present */ + +/* ADC Peripheral Present */ + +#define SYSCON_PPADC(n) (1 << (n)) /* Bit n: ADC Module n Present */ +# define SYSCON_PPADC_P0 (1 << 0) /* Bit 0: ADC Module 0 Present */ +# define SYSCON_PPADC_P1 (1 << 1) /* Bit 1: ADC Module 1 Present */ + +/* Analog Comparator Peripheral Present */ + +#define SYSCON_PPACMP_P0 (1 << 0) /* Bit 0: Analog Comparator Module Present */ + +/* Pulse Width Modulator Peripheral Present */ + +#define SYSCON_PPWM(n) (1 << (n)) /* Bit n: PWM Module n Present */ +# define SYSCON_PPWM_P0 (1 << 0) /* Bit 0: PWM Module 0 Present */ +# define SYSCON_PPWM_P1 (1 << 1) /* Bit 1: PWM Module 1 Present */ + +/* Quadrature Encoder Peripheral Present */ + +#define SYSCON_PPQEI(n) (1 << (n)) /* Bit n: QEI Module n Present */ +# define SYSCON_PPQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: QEI Module 1 Present */ + +/* EEPROM Peripheral Present */ + +#define SYSCON_PPEEPROM_P0 (1 << 0) /* Bit 0: EEPROM Module Present */ + +/* 32/64-Bit Wide Timer Peripheral Present */ + +#define SYSCON_PPWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Present */ +# define SYSCON_PPWTIMER_P0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Present */ +# define SYSCON_PPWTIMER_P1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Present */ +# define SYSCON_PPWTIMER_P2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Present */ +# define SYSCON_PPWTIMER_P3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Present */ +# define SYSCON_PPWTIMER_P4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Present */ +# define SYSCON_PPWTIMER_P5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Present */ + +/* Watchdog Timer Software Reset */ + +#define SYSCON_SRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Software Reset */ +# define SYSCON_SRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Software Reset */ +# define SYSCON_SRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Software Reset */ + +/* 16/32-Bit Timer Software Reset */ + +#define SYSCON_SRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Software Reset */ +# define SYSCON_SRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Software Reset */ + +/* GPIO Software Reset */ + +#define SYSCON_SRGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Software Reset */ +# define SYSCON_SRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Software Reset */ +# define SYSCON_SRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Software Reset */ +# define SYSCON_SRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Software Reset */ +# define SYSCON_SRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Software Reset */ +# define SYSCON_SRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Software Reset */ +# define SYSCON_SRPGIO_R5 (1 << 5) /* Bit 5: GPIO Port F Software Reset */ +# define SYSCON_SRPGIO_R6 (1 << 6) /* Bit 6: GPIO Port G Software Reset */ +# define SYSCON_SRPGIO_R7 (1 << 7) /* Bit 7: GPIO Port H Software Reset */ +# define SYSCON_SRPGIO_R8 (1 << 8) /* Bit 8: GPIO Port J Software Reset */ +# define SYSCON_SRPGIO_R9 (1 << 9) /* Bit 9: GPIO Port K Software Reset */ +# define SYSCON_SRPGIO_R10 (1 << 0) /* Bit 0: GPIO Port L Software Reset */ +# define SYSCON_SRPGIO_R11 (1 << 1) /* Bit 1: GPIO Port M Software Reset */ +# define SYSCON_SRPGIO_R12 (1 << 2) /* Bit 2: GPIO Port N Software Reset */ +# define SYSCON_SRPGIO_R13 (1 << 3) /* Bit 3: GPIO Port P Software Reset */ +# define SYSCON_SRPGIO_R14 (1 << 4) /* Bit 4: GPIO Port Q Software Reset */ + +/* uDMA Software Reset */ + +#define SYSCON_SRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Software Reset */ + +/* Hibernation Software Reset */ + +#define SYSCON_SRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Software Reset */ + +/* UART Software Reset*/ + +#define SYSCON_SRUARTR(n) (1 << (n)) /* Bit n: UART Module n Software Reset */ +# define SYSCON_SRUARTR_R0 (1 << 0) /* Bit 0: UART Module 0 Software Reset */ +# define SYSCON_SRUARTR_R1 (1 << 1) /* Bit 1: UART Module 1 Software Reset */ +# define SYSCON_SRUARTR_R2 (1 << 2) /* Bit 2: UART Module 2 Software Reset */ +# define SYSCON_SRUARTR_R3 (1 << 3) /* Bit 3: UART Module 3 Software Reset */ +# define SYSCON_SRUARTR_R4 (1 << 4) /* Bit 4: UART Module 4 Software Reset */ +# define SYSCON_SRUARTR_R5 (1 << 5) /* Bit 5: UART Module 5 Software Reset */ +# define SYSCON_SRUARTR_R6 (1 << 6) /* Bit 6: UART Module 6 Software Reset */ +# define SYSCON_SRUARTR_R7 (1 << 7) /* Bit 7: UART Module 7 Software Reset */ + +/* SSI Software Reset */ + +#define SYSCON_SRSSI(n) (1 << (n)) /* Bit n: SSI Module n Software Reset */ +# define SYSCON_SRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Software Reset */ +# define SYSCON_SRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Software Reset */ +# define SYSCON_SRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Software Reset */ +# define SYSCON_SRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Software Reset */ + +/* I2C Software Reset */ + +#define SYSCON_SRI2C(n) (1 << (n)) /* Bit n: I2C Module n Software Reset */ +# define SYSCON_SRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Software Reset */ +# define SYSCON_SRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Software Reset */ +# define SYSCON_SRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Software Reset */ +# define SYSCON_SRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Software Reset */ +# define SYSCON_SRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Software Reset */ +# define SYSCON_SRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Software Reset */ + +/* USB Software Reset */ + +#define SYSCON_SRUSB_R0 (1 << 0) /* Bit 0: USB Module Software Reset */ + +/* CAN Software Reset */ + +#define SYSCON_SRCAN(n) (1 << (n)) /* Bit n: CAN Module n Software Reset */ +# define SYSCON_SRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Software Reset */ +# define SYSCON_SRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Software Reset*/ + +/* ADC Software Reset */ + +#define SYSCON_SRADC(n) (1 << (n)) /* Bit n: ADC Module n Software Reset */ +# define SYSCON_SRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Software Reset */ +# define SYSCON_SRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Software Reset */ + +/* Analog Comparator Software Reset */ + +#define SYSCON_SRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Software Reset */ + +/* Pulse Width Modulator Software Reset */ + +#define SYSCON_SRPWM(n) (1 << (n)) /* Bit n: PWM Module n Software Reset */ +# define SYSCON_SRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Software Reset */ +# define SYSCON_SRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Software Reset */ + +/* Quadrature Encoder Interface Software Reset */ +#define SYSCON_SRQEI_ +#define SYSCON_SRQEI(n) (1 << (n)) /* Bit n: QEI Module n Software Reset */ +# define SYSCON_SRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Software Reset */ +# define SYSCON_SRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Software Reset */ + +/* EEPROM Software Reset */ + +#define SYSCON_SREEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Software Reset */ + +/* 32/64-Bit Wide Timer Software Reset */ + +#define SYSCON_SRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Software Reset */ +# define SYSCON_SRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Software Reset */ + +/* Watchdog Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Run Mode Clock Gating Control */ + +/* 16/32-Bit Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* GPIO Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCGPIO(n) (1 << (n)) /* Bit n: 16/32-Bit GPIO Port n Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R0 (1 << 0) /* Bit 0: 16/32-Bit GPIO Port A Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R1 (1 << 1) /* Bit 1: 16/32-Bit GPIO Port B Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R2 (1 << 2) /* Bit 2: 16/32-Bit GPIO Port C Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R3 (1 << 3) /* Bit 3: 16/32-Bit GPIO Port D Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R4 (1 << 4) /* Bit 4: 16/32-Bit GPIO Port E Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R5 (1 << 5) /* Bit 5: 16/32-Bit GPIO Port F Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R6 (1 << 6) /* Bit 6: 16/32-Bit GPIO Port G Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R7 (1 << 7) /* Bit 7: 16/32-Bit GPIO Port H Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R8 (1 << 8) /* Bit 8: 16/32-Bit GPIO Port J Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R9 (1 << 9) /* Bit 9: 16/32-Bit GPIO Port K Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R10 (1 << 10) /* Bit 10: 16/32-Bit GPIO Port L Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R11 (1 << 11) /* Bit 11: 16/32-Bit GPIO Port M Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R12 (1 << 12) /* Bit 12: 16/32-Bit GPIO Port N Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R13 (1 << 13) /* Bit 13: 16/32-Bit GPIO Port P Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R14 (1 << 14) /* Bit 14: 16/32-Bit GPIO Port Q Run Mode Clock Gating Control */ + +/* uDMA Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCDMA_R0 (1 << 0) /* Bit 0: μDMA Module Run Mode Clock Gating Control */ + +/* Hibernation Run Mode Clock Gating Control */ + +#define SYSCON_RCGCHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Run Mode Clock Gating Control */ + +/* UART Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCUART(n) (1 << (n)) /* Bit n: UART Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R0 (1 << 0) /* Bit 0: UART Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R1 (1 << 1) /* Bit 1: UART Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R2 (1 << 2) /* Bit 2: UART Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R3 (1 << 3) /* Bit 3: UART Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R4 (1 << 4) /* Bit 4: UART Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R5 (1 << 5) /* Bit 5: UART Module 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R6 (1 << 6) /* Bit 6: UART Module 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R7 (1 << 7) /* Bit 7: UART Module 7 Run Mode Clock Gating Control */ + +/* SSI Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Run Mode Clock Gating Control */ + +/* I2C Run Mode Clock Gating Control */ + +#define SYSCON_RCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Run Mode Clock Gating Control */ + +/* USB Run Mode Clock Gating Control */ + +#define SYSCON_RCGCUSB_R0 (1 << 0) /* Bit 0: USB Module Run Mode Clock Gating Control */ + +/* CAN Run Mode Clock Gating Control */ + +#define SYSCON_RCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Run Mode Clock Gating Control */ + +/* ADC Run Mode Clock Gating Control */ + +#define SYSCON_RCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Run Mode Clock Gating Control */ + +/* Analog Comparator Run Mode Clock Gating Control */ + +#define SYSCON_RCGCACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Run Mode Clock Gating Control */ + +/* Pulse Width Modulator Run Mode Clock Gating Control */ + +#define SYSCON_RCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Run Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Run Mode Clock Gating Control */ + +#define SYSCON_RCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Run Mode Clock Gating Control */ + +/* EEPROM Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Run Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* Watchdog Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: Watchdog Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: Watchdog Timer 1 Sleep Mode Clock Gating Control */ + +/* 16/32-Bit Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* GPIO Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S0 (1 << 0) /* Bit 0: GPIO Port A Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S1 (1 << 1) /* Bit 1: GPIO Port B Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S2 (1 << 2) /* Bit 2: GPIO Port C Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S3 (1 << 3) /* Bit 3: GPIO Port D Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S4 (1 << 4) /* Bit 4: GPIO Port E Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S5 (1 << 5) /* Bit 5: GPIO Port F Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S6 (1 << 6) /* Bit 6: GPIO Port G Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S7 (1 << 7) /* Bit 7: GPIO Port H Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S8 (1 << 8) /* Bit 8: GPIO Port J Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S9 (1 << 9) /* Bit 9: GPIO Port K Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S10 (1 << 10) /* Bit 10: GPIO Port L Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S11 (1 << 11) /* Bit 11: GPIO Port M Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S12 (1 << 12) /* Bit 12: GPIO Port N Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S13 (1 << 13) /* Bit 13: GPIO Port P Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S14 (1 << 14) /* Bit 14: GPIO Port Q Sleep Mode Clock Gating Control */ + +/* uDMA Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCDMA_S0 (1 << 0) /* Bit 0: μDMA Module Sleep Mode Clock Gating Control */ + +/* Hibernation Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCHIB_S0 (1 << 0) /* Bit 0: Hibernation Module Sleep Mode Clock Gating Control */ + +/* UART Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUART(n) (1 << (n)) /* Bit n: UART Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S0 (1 << 0) /* Bit 0: UART Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S1 (1 << 1) /* Bit 1: UART Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S2 (1 << 2) /* Bit 2: UART Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S3 (1 << 3) /* Bit 3: UART Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S4 (1 << 4) /* Bit 4: UART Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S5 (1 << 5) /* Bit 5: UART Module 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S6 (1 << 6) /* Bit 6: UART Module 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S7 (1 << 7) /* Bit 7: UART Module 7 Sleep Mode Clock Gating Control */ + +/* SSI Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S0 (1 << 0) /* Bit 0: SSI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S1 (1 << 1) /* Bit 1: SSI Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S2 (1 << 2) /* Bit 2: SSI Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S3 (1 << 3) /* Bit 3: SSI Module 3 Sleep Mode Clock Gating Control */ + +/* I2C Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S0 (1 << 0) /* Bit 0: I2C Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S1 (1 << 1) /* Bit 1: I2C Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S2 (1 << 2) /* Bit 2: I2C Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S3 (1 << 3) /* Bit 3: I2C Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S4 (1 << 4) /* Bit 4: I2C Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S5 (1 << 5) /* Bit 5: I2C Module 5 Sleep Mode Clock Gating Control */ + +/* USB Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUSB_S0 (1 << 0) /* Bit 0: USB Module Sleep Mode Clock Gating Control */ + +/* CAN Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S0 (1 << 0) /* Bit 0: CAN Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S1 (1 << 1) /* Bit 1: CAN Module 1 Sleep Mode Clock Gating Control */ + +/* ADC Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S0 (1 << 0) /* Bit 0: ADC Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S1 (1 << 1) /* Bit 1: ADC Module 1 Sleep Mode Clock Gating Control */ + +/* Analog Comparator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCACMP_S0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Sleep Mode Clock Gating Control */ + +/* PulseWidthModulator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S0 (1 << 0) /* Bit 0: PWM Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S1 (1 << 1) /* Bit 1: PWM Module 1 Sleep Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S0 (1 << 0) /* Bit 0: QEI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S1 (1 << 1) /* Bit 1: QEI Module 1 Sleep Mode Clock Gating Control */ + +/* EEPROM Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEEPROM_S0 (1 << 0) /* Bit 0: EEPROM Module Sleep Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D0 (1 << 0) /* Bit 0: Watchdog Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D1 (1 << 1) /* Bit 1: Watchdog Timer 1 Deep-Sleep Mode Clock Gating Control */ + +/* Clock Gating Control */ + +#define SYSCON_DCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Deep-Sleep Mode Clock Gating Control */ + +/* GPIO Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D0 (1 << 0) /* Bit 0: GPIO Port A Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D1 (1 << 1) /* Bit 1: GPIO Port B Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D2 (1 << 2) /* Bit 2: GPIO Port C Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D3 (1 << 3) /* Bit 3: GPIO Port D Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D4 (1 << 4) /* Bit 4: GPIO Port E Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D5 (1 << 5) /* Bit 5: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D6 (1 << 6) /* Bit 6: GPIO Port G Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D7 (1 << 7) /* Bit 7: GPIO Port H Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D8 (1 << 8) /* Bit 8: GPIO Port J Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D9 (1 << 9) /* Bit 9: GPIO Port K Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D10 (1 << 10) /* Bit 10: GPIO Port L Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D11 (1 << 11) /* Bit 11: GPIO Port M Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D12 (1 << 12) /* Bit 12: GPIO Port N Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D13 (1 << 13) /* Bit 13: GPIO Port P Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D14 (1 << 14) /* Bit 14: GPIO Port Q Deep-Sleep Mode Clock Gating Control */ + +/* uDMA Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCDMA_D0 (1 << 0) /* Bit 0: μDMA Module Deep-Sleep Mode Clock Gating Control */ + +/* Hibernation Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCHIB_D0 (1 << 0) /* Bit 0: Hibernation Module Deep-Sleep Mode Clock Gating Control */ + +/* UART Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUART(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D6 (1 << 6) /* Bit 6: UART Module 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D7 (1 << 7) /* Bit 7: UART Module 7 Deep-Sleep Mode Clock Gating Control */ + +/* SSI Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D0 (1 << 0) /* Bit 0: SSI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D1 (1 << 1) /* Bit 1: SSI Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D2 (1 << 2) /* Bit 2: SSI Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D3 (1 << 3) /* Bit 3: SSI Module 3 Deep-Sleep Mode Clock Gating Control */ + +/* I2C Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D0 (1 << 0) /* Bit 0: I2C Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D1 (1 << 1) /* Bit 1: I2C Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D2 (1 << 2) /* Bit 2: I2C Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D3 (1 << 3) /* Bit 3: I2C Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D4 (1 << 4) /* Bit 4: I2C Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D5 (1 << 5) /* Bit 5: I2C Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* USB Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUSB_D0 (1 << 0) /* Bit 0: USB Module Deep-Sleep Mode Clock Gating Control */ + +/* CAN Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D0 (1 << 0) /* Bit 0: CAN Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D1 (1 << 1) /* Bit 1: CAN Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* ADC Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D0 (1 << 0) /* Bit 0: ADC Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D1 (1 << 1) /* Bit 1: ADC Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* Analog Comparator Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCACMP_D0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* Pulse Width Modulator Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D0 (1 << 0) /* Bit 0: PWM Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D1 (1 << 1) /* Bit 1: PWM Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D0 (1 << 0) /* Bit 0: QEI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D1 (1 << 1) /* Bit 1: QEI Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* EEPROM Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEEPROM_D0 (1 << 0) /* Bit 0: EEPROM Module Deep-Sleep Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWTIMER(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Peripheral Ready */ + +#define SYSCON_PRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Peripheral Ready */ +# define SYSCON_PRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Peripheral Ready */ +# define SYSCON_PRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Peripheral Ready */ + +/* 16/32-Bit Timer Peripheral Ready */ + +#define SYSCON_PRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Peripheral Ready */ + +/* GPIO Peripheral Ready */ + +#define SYSCON_PRGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Peripheral Ready */ +# define SYSCON_PRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Peripheral Ready */ +# define SYSCON_PRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Peripheral Ready */ +# define SYSCON_PRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Peripheral Ready */ +# define SYSCON_PRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Peripheral Ready */ +# define SYSCON_PRGPIO_R5 (1 << 5) /* Bit 5: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R6 (1 << 6) /* Bit 6: GPIO Port G Peripheral Ready */ +# define SYSCON_PRGPIO_R7 (1 << 7) /* Bit 7: GPIO Port H Peripheral Ready */ +# define SYSCON_PRGPIO_R8 (1 << 8) /* Bit 8: GPIO Port J Peripheral Ready */ +# define SYSCON_PRGPIO_R9 (1 << 9) /* Bit 9: GPIO Port K Peripheral Ready */ +# define SYSCON_PRGPIO_R10 (1 << 10) /* Bit 10: GPIO Port L Peripheral Ready */ +# define SYSCON_PRGPIO_R11 (1 << 11) /* Bit 11: GPIO Port M Peripheral Ready */ +# define SYSCON_PRGPIO_R12 (1 << 12) /* Bit 12: GPIO Port N Peripheral Ready */ +# define SYSCON_PRGPIO_R13 (1 << 13) /* Bit 13: GPIO Port P Peripheral Ready */ +# define SYSCON_PRGPIO_R14 (1 << 14) /* Bit 14: GPIO Port Q Peripheral Ready */ + +/* uDMA Peripheral Ready */ + +#define SYSCON_PRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Peripheral Ready */ + +/* Hibernation Peripheral Ready */ + +#define SYSCON_PRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Peripheral Ready */ + +/* UART Peripheral Ready */ + +#define SYSCON_PRUART(n) (1 << (n)) /* Bit n: UART Module n Peripheral Ready */ +# define SYSCON_PRUART_R0 (1 << 0) /* Bit 0: UART Module 0 Peripheral Ready */ +# define SYSCON_PRUART_R1 (1 << 1) /* Bit 1: UART Module 1 Peripheral Ready */ +# define SYSCON_PRUART_R2 (1 << 2) /* Bit 2: UART Module 2 Peripheral Ready */ +# define SYSCON_PRUART_R3 (1 << 3) /* Bit 3: UART Module 3 Peripheral Ready */ +# define SYSCON_PRUART_R4 (1 << 4) /* Bit 4: UART Module 4 Peripheral Ready */ +# define SYSCON_PRUART_R5 (1 << 5) /* Bit 5: UART Module 5 Peripheral Ready */ +# define SYSCON_PRUART_R6 (1 << 6) /* Bit 6: UART Module 6 Peripheral Ready */ +# define SYSCON_PRUART_R7 (1 << 7) /* Bit 7: UART Module 7 Peripheral Ready */ + +/* SSI Peripheral Ready */ + +#define SYSCON_PRSSI(n) (1 << (n)) /* Bit n: SSI Module n Peripheral Ready */ +# define SYSCON_PRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Peripheral Ready */ +# define SYSCON_PRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Peripheral Ready */ +# define SYSCON_PRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Peripheral Ready */ +# define SYSCON_PRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Peripheral Ready */ + +/* I2C Peripheral Ready */ + +#define SYSCON_PRI2C(n) (1 << (n)) /* Bit n: I2C Module n Peripheral Ready */ +# define SYSCON_PRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Peripheral Ready */ +# define SYSCON_PRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Peripheral Ready */ +# define SYSCON_PRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Peripheral Ready */ +# define SYSCON_PRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Peripheral Ready */ +# define SYSCON_PRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Peripheral Ready */ +# define SYSCON_PRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Peripheral Ready */ + +/* USB Peripheral Ready */ + +#define SYSCON_PRUSB_R0 (1 << 0) /* Bit 0: USB Module Peripheral Ready */ + +/* CAN Peripheral Ready */ + +#define SYSCON_PRCAN(n) (1 << (n)) /* Bit n: CAN Module n Peripheral Ready */ +# define SYSCON_PRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Peripheral Ready */ +# define SYSCON_PRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Peripheral Ready */ + +/* ADC Peripheral Ready */ + +#define SYSCON_PRADC(n) (1 << (n)) /* Bit n: ADC Module n Peripheral Ready */ +# define SYSCON_PRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Peripheral Ready */ +# define SYSCON_PRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Peripheral Ready */ + +/* Analog Comparator Peripheral Ready */ + +#define SYSCON_PRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Peripheral Ready */ + +/* Pulse Width Modulator Peripheral Ready */ + +#define SYSCON_PRPWM(n) (1 << (n)) /* Bit n: PWM Module n Peripheral Ready */ +# define SYSCON_PRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Peripheral Ready */ +# define SYSCON_PRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Peripheral Ready */ + +/* Quadrature Encoder Interface Peripheral Ready */ + +#define SYSCON_PRQEI(n) (1 << (n)) /* Bit n: QEI Module n Peripheral Ready */ +# define SYSCON_PRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Peripheral Ready */ +# define SYSCON_PRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Peripheral Ready */ + +/* EEPROM Peripheral Ready */ + +#define SYSCON_PREEPROM_0 (1 << 0) /* Bit 0: EEPROM Module Peripheral Ready */ + +/* 2/64-BitWide Timer Peripheral Ready */ + +#define SYSCON_PRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Peripheral Ready */ + +/* System Control Legacy Register Bit Definitions *******************************************/ +/* Device Capabilities 0 */ + +#define SYSCON_DC0_FLASHSZ_SHIFT 0 /* Bits 15-0: FLASH Size */ +#define SYSCON_DC0_FLASHSZ_MASK (0xffff << SYSCON_DC0_FLASHSZ_SHIFT) +#define SYSCON_DC0_SRAMSZ_SHIFT 16 /* Bits 31-16: SRAM Size */ +#define SYSCON_DC0_SRAMSZ_MASK (0xffff << SYSCON_DC0_SRAMSZ_SHIFT) + +/* Device Capabilities 1 */ + +#define SYSCON_DC1_JTAG (1 << 0) /* Bit 0: JTAG Present */ +#define SYSCON_DC1_SWD (1 << 1) /* Bit 1: SWD Present */ +#define SYSCON_DC1_SWO (1 << 2) /* Bit 2: SWO Trace Port Present */ +#define SYSCON_DC1_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Present */ +#define SYSCON_DC1_PLL (1 << 4) /* Bit 4: PLL Present */ +#define SYSCON_DC1_TEMPSNS (1 << 5) /* Bit 5: Temp Sensor Present */ +#define SYSCON_DC1_HIB (1 << 6) /* Bit 6: Hibernation Module Present */ +#define SYSCON_DC1_MPU (1 << 7) /* Bit 7: MPU Present */ +#define SYSCON_DC1_MAXADC0SPD_SHIFT (8) /* Bits 9-8: Max ADC Speed */ +#define SYSCON_DC1_MAXADC0SPD_MASK (3 << SYSCON_DC1_MAXADC0SPD_SHIFT) +#define SYSCON_DC1_MAXADC1SPD_SHIFT (10) /* Bits 10-11: Max ADC Speed */ +#define SYSCON_DC1_MAXADC1SPD_MASK (3 << SYSCON_DC1_MAXADC1SPD_SHIFT) +#define SYSCON_DC1_MINSYSDIV_SHIFT 12 /* Bits 12-15: System Clock Divider Minimum */ +#define SYSCON_DC1_MINSYSDIV_MASK (15 << SYSCON_DC1_MINSYSDIV_SHIFT) +#define SYSCON_DC1_ADC0 (1 << 16) /* Bit 16: ADC0 Module Present */ +#define SYSCON_DC1_ADC1 (1 << 17) /* Bit 17: ADC1 Module Present */ +#define SYSCON_DC1_PWM0 (1 << 20) /* Bit 20: PWM0 Module Present */ +#define SYSCON_DC1_PWM1 (1 << 21) /* Bit 21: PWM1 Module Present */ +#define SYSCON_DC1_CAN0 (1 << 24) /* Bit 24: CAN0 Module Present */ +#define SYSCON_DC1_CAN1 (1 << 25) /* Bit 25: CAN1 Module Present */ +#define SYSCON_DC1_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Present */ + +/* Device Capabilities 2 */ + +#define SYSCON_DC2_UART0 (1 << 0) /* Bit 0: UART0 Module Present */ +#define SYSCON_DC2_UART1 (1 << 1) /* Bit 1: UART1 Module Present */ +#define SYSCON_DC2_UART2 (1 << 2) /* Bit 2: UART2 Module Present */ +#define SYSCON_DC2_SSI0 (1 << 4) /* Bit 4: SSI0 Module Present */ +#define SYSCON_DC2_SSI1 (1 << 5) /* Bit 5: SSI1 Module Present */ +#define SYSCON_DC2_QEI0 (1 << 8) /* Bit 8: QEI0 Module Present */ +#define SYSCON_DC2_QEI1 (1 << 9) /* Bit 9: QEI1 Module Present */ +#define SYSCON_DC2_I2C0 (1 << 12) /* Bit 12: I2C Module 0 Present */ +#define SYSCON_DC2_I2C0HS (1 << 13) /* Bit 13: I2C Module 0 Speed */ +#define SYSCON_DC2_I2C1 (1 << 14) /* Bit 14: I2C Module 1 Present */ +#define SYSCON_DC2_I2C1HS (1 << 15) /* Bit 15: I2C Module 1 Speed */ +#define SYSCON_DC2_TIMER0 (1 << 16) /* Bit 16: Timer 0 Present */ +#define SYSCON_DC2_TIMER1 (1 << 17) /* Bit 17: Timer 1 Present */ +#define SYSCON_DC2_TIMER2 (1 << 18) /* Bit 18: Timer 2 Present */ +#define SYSCON_DC2_TIMER3 (1 << 19) /* Bit 19: Timer 3 Present */ +#define SYSCON_DC2_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Present */ +#define SYSCON_DC2_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Present */ +#define SYSCON_DC2_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Present */ +#define SYSCON_DC2_I2S0 (1 << 28) /* Bit 28: I2S Module 0 Present */ +#define SYSCON_DC2_EPI0 (1 << 30) /* Bit 30: EPI Module 0 Present */ + +/* Device Capabilities 3 */ + +#define SYSCON_DC3_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define SYSCON_DC3_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define SYSCON_DC3_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define SYSCON_DC3_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define SYSCON_DC3_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define SYSCON_DC3_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define SYSCON_DC3_C0MINUS (1 << 6) /* Bit 6: C0- Pin Present */ +#define SYSCON_DC3_C0PLUS (1 << 7) /* Bit 7: C0+ Pin Present */ +#define SYSCON_DC3_C0O (1 << 8) /* Bit 8: C0o Pin Present */ +#define SYSCON_DC3_C1MINUS (1 << 9) /* Bit 9: C1- Pin Present */ +#define SYSCON_DC3_C1PLUS (1 << 10) /* Bit 10: C1+ Pin Present */ +#define SYSCON_DC3_C1O (1 << 11) /* Bit 11: C1o Pin Present */ +#define SYSCON_DC3_C2MINUS (1 << 12) /* Bit 12: C2- Pin Present */ +#define SYSCON_DC3_C2PLUS (1 << 13) /* Bit 13: C2+ Pin Present */ +#define SYSCON_DC3_C2O (1 << 14) /* Bit 14: C2o Pin Present */ +#define SYSCON_DC3_PWMFAULT (1 << 15) /* Bit 15: PWM Fault Pin Pre */ +#define SYSCON_DC3_ADC0AIN0 (1 << 16) /* Bit 16: ADC Module 0 AIN0 Pin Present */ +#define SYSCON_DC3_ADC0AIN1 (1 << 17) /* Bit 17: ADC Module 0 AIN1 Pin Present */ +#define SYSCON_DC3_ADC0AIN2 (1 << 18) /* Bit 18: ADC Module 0 AIN2 Pin Present */ +#define SYSCON_DC3_ADC0AIN3 (1 << 19) /* Bit 19: ADC Module 0 AIN3 Pin Present */ +#define SYSCON_DC3_ADC0AIN4 (1 << 20) /* Bit 20: ADC Module 0 AIN4 Pin Present */ +#define SYSCON_DC3_ADC0AIN5 (1 << 21) /* Bit 21: ADC Module 0 AIN5 Pin Present */ +#define SYSCON_DC3_ADC0AIN6 (1 << 22) /* Bit 22: ADC Module 0 AIN6 Pin Present */ +#define SYSCON_DC3_ADC0AIN7 (1 << 23) /* Bit 23: ADC Module 0 AIN7 Pin Present */ +#define SYSCON_DC3_CCP0 (1 << 24) /* Bit 24: T0CCP0 Pin Present */ +#define SYSCON_DC3_CCP1 (1 << 25) /* Bit 25: T0CCP1 Pin Present */ +#define SYSCON_DC3_CCP2 (1 << 26) /* Bit 26: T1CCP0 Pin Present */ +#define SYSCON_DC3_CCP3 (1 << 27) /* Bit 27: T1CCP1 Pin Present */ +#define SYSCON_DC3_CCP4 (1 << 28) /* Bit 28: T2CCP0 Pin Present */ +#define SYSCON_DC3_CCP5 (1 << 29) /* Bit 29: T2CCP1 Pin Present */ +#define SYSCON_DC3_32KHZ (1 << 31) /* Bit 31: 32KHz Input Clock Available */ + +/* Device Capabilities 4 */ + +#define SYSCON_DC4_GPIO(n) (1 << (n)) +#define SYSCON_DC4_GPIOA (1 << 0) /* Bit 0: GPIO Port A Present */ +#define SYSCON_DC4_GPIOB (1 << 1) /* Bit 1: GPIO Port B Present */ +#define SYSCON_DC4_GPIOC (1 << 2) /* Bit 2: GPIO Port C Present */ +#define SYSCON_DC4_GPIOD (1 << 3) /* Bit 3: GPIO Port D Present */ +#define SYSCON_DC4_GPIOE (1 << 4) /* Bit 4: GPIO Port E Present */ +#define SYSCON_DC4_GPIOF (1 << 5) /* Bit 5: GPIO Port F Present */ +#define SYSCON_DC4_GPIOG (1 << 6) /* Bit 6: GPIO Port G Present */ +#define SYSCON_DC4_GPIOH (1 << 7) /* Bit 7: GPIO Port H Present */ +#define SYSCON_DC4_GPIOJ (1 << 8) /* Bit 8: GPIO Port J Present */ + +#define SYSCON_DC4_ROM (1 << 12) /* Bit 12: Internal Code ROM Present */ +#define SYSCON_DC4_UDMA (1 << 13) /* Bit 13: Micro-DMA Module Present */ +#define SYSCON_DC4_CCP6 (1 << 14) /* Bit 14: T3CCP0 Pin Present */ +#define SYSCON_DC4_CCP7 (1 << 15) /* Bit 15: T3CCP1 Pin Present */ +#define SYSCON_DC4_PICAL (1 << 18) /* Bit 18: PIOSC Calibrate */ +#define SYSCON_DC4_E1588 (1 << 24) /* Bit 24: 1588 Capable */ +#define SYSCON_DC4_EMAC0 (1 << 28) /* Bit 28: Ethernet MAC0 Present */ +#define SYSCON_DC4_EPHY0 (1 << 30) /* Bit 30: Ethernet PHY0 Present */ + +/* Device Capabilities 5 */ + +#define TIVA_SYSCON_DC5_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define TIVA_SYSCON_DC5_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define TIVA_SYSCON_DC5_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define TIVA_SYSCON_DC5_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define TIVA_SYSCON_DC5_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define TIVA_SYSCON_DC5_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define TIVA_SYSCON_DC5_PWM6 (1 << 6) /* Bit 6: PWM6 Pin Present */ +#define TIVA_SYSCON_DC5_PWM7 (1 << 7) /* Bit 7: PWM7 Pin Present */ +#define TIVA_SYSCON_DC5_PWMESYNC (1 << 20) /* Bit 20: PWM Extended SYNC Active */ +#define TIVA_SYSCON_DC5_PWMEFLT (1 << 21) /* Bit 21: PWM Extended Fault Active */ +#define TIVA_SYSCON_DC5_PWMFAULT0 (1 << 24) /* Bit 24: PWM Fault 0 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT1 (1 << 25) /* Bit 25: PWM Fault 1 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT2 (1 << 26) /* Bit 26: PWM Fault 2 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT3 (1 << 27) /* Bit 27: PWM Fault 3 Pin Present */ + +/* Device Capabilities 6 */ + +#define TIVA_SYSCON_DC6_USB0_SHIFT (0) /* Bits 0-1: USB Module 0 Present */ +#define TIVA_SYSCON_DC6_USB0_MASK (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_NONE (1 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_DEVICE (2 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_HOST (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_OTG (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +#define TIVA_SYSCON_DC6_USB0PHY (1 << 4) /* Bit 4: USB Module 0 PHY Present */ + +/* Device Capabilities 7 */ + +#define TIVA_SYSCON_DC7_DMACH0 (1 << 0) /* Bit 0: DMA Channel 0 */ +#define TIVA_SYSCON_DC7_DMACH1 (1 << 1) /* Bit 1: DMA Channel 1 */ +#define TIVA_SYSCON_DC7_DMACH2 (1 << 2) /* Bit 2: DMA Channel 2 */ +#define TIVA_SYSCON_DC7_DMACH3 (1 << 3) /* Bit 3: DMA Channel 3 */ +#define TIVA_SYSCON_DC7_DMACH4 (1 << 4) /* Bit 4: DMA Channel 4 */ +#define TIVA_SYSCON_DC7_DMACH5 (1 << 5) /* Bit 5: DMA Channel 5 */ +#define TIVA_SYSCON_DC7_DMACH6 (1 << 6) /* Bit 6: DMA Channel 6 */ +#define TIVA_SYSCON_DC7_DMACH7 (1 << 7) /* Bit 7: DMA Channel 7 */ +#define TIVA_SYSCON_DC7_DMACH8 (1 << 8) /* Bit 8: DMA Channel 8 */ +#define TIVA_SYSCON_DC7_DMACH9 (1 << 9) /* Bit 9: DMA Channel 9 */ +#define TIVA_SYSCON_DC7_DMACH10 (1 << 10) /* Bit 10: DMA Channel 10 */ +#define TIVA_SYSCON_DC7_DMACH11 (1 << 11) /* Bit 11: DMA Channel 11 */ +#define TIVA_SYSCON_DC7_DMACH12 (1 << 12) /* Bit 12: DMA Channel 12 */ +#define TIVA_SYSCON_DC7_DMACH13 (1 << 13) /* Bit 13: DMA Channel 13 */ +#define TIVA_SYSCON_DC7_DMACH14 (1 << 14) /* Bit 14: DMA Channel 14 */ +#define TIVA_SYSCON_DC7_DMACH15 (1 << 15) /* Bit 15: DMA Channel 15 */ +#define TIVA_SYSCON_DC7_DMACH16 (1 << 16) /* Bit 16: DMA Channel 16 */ +#define TIVA_SYSCON_DC7_DMACH17 (1 << 17) /* Bit 17: DMA Channel 17 */ +#define TIVA_SYSCON_DC7_DMACH18 (1 << 18) /* Bit 18: DMA Channel 18 */ +#define TIVA_SYSCON_DC7_DMACH19 (1 << 19) /* Bit 19: DMA Channel 19 */ +#define TIVA_SYSCON_DC7_DMACH20 (1 << 20) /* Bit 20: DMA Channel 20 */ +#define TIVA_SYSCON_DC7_DMACH21 (1 << 21) /* Bit 21: DMA Channel 21 */ +#define TIVA_SYSCON_DC7_DMACH22 (1 << 22) /* Bit 22: DMA Channel 22 */ +#define TIVA_SYSCON_DC7_DMACH23 (1 << 23) /* Bit 23: DMA Channel 23 */ +#define TIVA_SYSCON_DC7_DMACH24 (1 << 24) /* Bit 24: DMA Channel 24 */ +#define TIVA_SYSCON_DC7_DMACH25 (1 << 25) /* Bit 25: DMA Channel 25 */ +#define TIVA_SYSCON_DC7_DMACH26 (1 << 26) /* Bit 26: DMA Channel 26 */ +#define TIVA_SYSCON_DC7_DMACH27 (1 << 27) /* Bit 27: DMA Channel 27 */ +#define TIVA_SYSCON_DC7_DMACH28 (1 << 28) /* Bit 28: DMA Channel 28 */ +#define TIVA_SYSCON_DC7_DMACH29 (1 << 29) /* Bit 29: DMA Channel 29 */ +#define TIVA_SYSCON_DC7_DMACH30 (1 << 30) /* Bit 30: DMA Channel 30 */ + +/* Device Capabilities 8 */ + +#define TIVA_SYSCON_DC8_ADC0AIN0 (1 << 0) /* Bit 0: ADC Module 0 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN1 (1 << 1) /* Bit 1: ADC Module 0 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN2 (1 << 2) /* Bit 2: ADC Module 0 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN3 (1 << 3) /* Bit 3: ADC Module 0 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN4 (1 << 4) /* Bit 4: ADC Module 0 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN5 (1 << 5) /* Bit 5: ADC Module 0 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN6 (1 << 6) /* Bit 6: ADC Module 0 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN7 (1 << 7) /* Bit 7: ADC Module 0 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN8 (1 << 8) /* Bit 8: ADC Module 0 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN9 (1 << 9) /* Bit 9: ADC Module 0 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN10 (1 << 10) /* Bit 10: ADC Module 0 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN11 (1 << 11) /* Bit 11: ADC Module 0 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN12 (1 << 12) /* Bit 12: ADC Module 0 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN13 (1 << 13) /* Bit 13: ADC Module 0 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN14 (1 << 14) /* Bit 14: ADC Module 0 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN15 (1 << 15) /* Bit 15: ADC Module 0 AIN15 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN0 (1 << 16) /* Bit 16: ADC Module 1 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN1 (1 << 17) /* Bit 17: ADC Module 1 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN2 (1 << 18) /* Bit 18: ADC Module 1 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN3 (1 << 19) /* Bit 19: ADC Module 1 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN4 (1 << 20) /* Bit 20: ADC Module 1 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN5 (1 << 21) /* Bit 21: ADC Module 1 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN6 (1 << 22) /* Bit 22: ADC Module 1 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN7 (1 << 23) /* Bit 23: ADC Module 1 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN8 (1 << 24) /* Bit 24: ADC Module 1 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN9 (1 << 25) /* Bit 25: ADC Module 1 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN10 (1 << 26) /* Bit 26: ADC Module 1 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN11 (1 << 27) /* Bit 27: ADC Module 1 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN12 (1 << 28) /* Bit 28: ADC Module 1 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN13 (1 << 29) /* Bit 29: ADC Module 1 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN14 (1 << 30) /* Bit 30: ADC Module 1 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN15 (1 << 31) /* Bit 31: ADC Module 1 AIN15 Pin Present */ + +/* Software Reset Control 0 */ + +#define SYSCON_SRCR0_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset Control */ +#define SYSCON_SRCR0_HIB (1 << 6) /* Bit 6: Hibernation Module Reset Control */ +#define SYSCON_SRCR0_ADC0 (1 << 16) /* Bit 16: ADC0 Reset Control */ +#define SYSCON_SRCR0_ADC1 (1 << 17) /* Bit 17: ADC1 Reset Control */ +#define SYSCON_SRCR0_CAN0 (1 << 24) /* Bit 24: CAN0 Reset Control */ +#define SYSCON_SRCR0_CAN1 (1 << 25) /* Bit 24: CAN1 Reset Control */ +#define SYSCON_SRCR0_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Reset Control */ + +/* Software Reset Control 1 */ + +#define SYSCON_SRCR1_UART0 (1 << 0) /* Bit 0: UART0 Reset Control */ +#define SYSCON_SRCR1_UART1 (1 << 1) /* Bit 1: UART1 Reset Control */ +#define SYSCON_SRCR1_UART2 (1 << 2) /* Bit 2: UART2 Reset Control */ +#define SYSCON_SRCR1_SSI0 (1 << 4) /* Bit 4: SSI0 Reset Control */ +#define SYSCON_SRCR1_SSI1 (1 << 5) /* Bit 5: SSI1 Reset Control */ +#define SYSCON_SRCR1_QEI0 (1 << 8) /* Bit 8: QEI0 Reset Control */ +#define SYSCON_SRCR1_QEI1 (1 << 9) /* Bit 9: QEI1 Reset Control */ +#define SYSCON_SRCR1_I2C0 (1 << 12) /* Bit 12: I2C 0 Reset Control */ +#define SYSCON_SRCR1_I2C1 (1 << 14) /* Bit 14: I2C 1 Reset Control */ +#define SYSCON_SRCR1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Reset Control */ +#define SYSCON_SRCR1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Reset Control */ +#define SYSCON_SRCR1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Reset Control */ +#define SYSCON_SRCR1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Reset Control */ +#define SYSCON_SRCR1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Reset Control */ +#define SYSCON_SRCR1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Reset Control */ +#define SYSCON_SRCR1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Reset Control */ + +/* Software Reset Control 2 */ + +#define SYSCON_SRCR2_GPIO(n) (1 << (n)) +#define SYSCON_SRCR2_GPIOA (1 << 0) /* Bit 0: Port A Reset Control */ +#define SYSCON_SRCR2_GPIOB (1 << 1) /* Bit 1: Port B Reset Control */ +#define SYSCON_SRCR2_GPIOC (1 << 2) /* Bit 2: Port C Reset Control */ +#define SYSCON_SRCR2_GPIOD (1 << 3) /* Bit 3: Port D Reset Control */ +#define SYSCON_SRCR2_GPIOE (1 << 4) /* Bit 4: Port E Reset Control */ +#define SYSCON_SRCR2_GPIOF (1 << 5) /* Bit 5: Port F Reset Control */ +#define SYSCON_SRCR2_GPIOG (1 << 6) /* Bit 6: Port G Reset Control */ +#define SYSCON_SRCR2_GPIOH (1 << 7) /* Bit 7: Port H Reset Control */ +#define SYSCON_SRCR2_GPIOJ (1 << 8) /* Bit 8: Port J Reset Control */ +#define SYSCON_SRCR2_UDMA (1 << 13) /* Bit 13: Micro-DMA Reset Control */ +#define SYSCON_SRCR2_USB0 (1 << 16) /* Bit 16: USB0 Reset Control */ + +/* Run Mode Clock Gating Control Register 0 */ + +#define SYSCON_RCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_RCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_RCGC0_MAXADC0SPD_SHIFT (8) /* Bits 8-9: ADC0 Sample Speed */ +#define SYSCON_RCGC0_MAXADC0SPD_MASK (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_125KSPS (0 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_250KSPS (1 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_500KSPS (2 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_1MSPS (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +#define SYSCON_RCGC0_MAXADC1SPD_SHIFT (8) /* Bits 10-11: ADC1 Sample Speed */ +#define SYSCON_RCGC0_MAXADC1SPD_MASK (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_125KSPS (0 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_250KSPS (1 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_500KSPS (2 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_1MSPS (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +#define SYSCON_RCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_RCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_RCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_RCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_RCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_RCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Run Mode Clock Gating Control Register 1 */ + +#define SYSCON_RCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_RCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_RCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_RCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_RCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_RCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_RCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_RCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_RCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_RCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_RCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_RCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Clock Gating */ + +/* Run Mode Clock Gating Control Register 2 */ + +#define SYSCON_RCGC2_GPIO(n) (1 << (n)) +#define SYSCON_RCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_RCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_RCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_RCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_RCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_RCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_RCGC2_GPIOG (1 << 6) /* Bit 6: Port GClock Gating Control */ +#define SYSCON_RCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_RCGC2_GPIOJ (1 << 8) /* Bit 8: Port J Clock Gating Control */ +#define SYSCON_RCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_RCGC2_USB0 (1 << 16) /* Bit 16: USB0 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_SCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_SCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_SCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_SCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_SCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_SCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_SCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_SCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_SCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_SCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_SCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_SCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_SCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_SCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_SCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_SCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_SCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_SCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_SCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_SCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Clock Gating */ + +/* Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_SCGC2_GPIO(n) (1 << (n)) +#define SYSCON_SCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_SCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_SCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_SCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_SCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_SCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_SCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_SCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_SCGC2_GPIOI (1 << 8) /* Bit 8: Port I Clock Gating Control */ +#define SYSCON_SCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_SCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_DCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_DCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_DCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_DCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_DCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_DCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_DCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_DCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_DCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_DCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_DCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_DCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_DCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_DCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_DCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_DCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_DCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_DCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_DCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_DCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 6 Clock Gating */ + +/* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_DCGC2_GPIO(n) (1 << (n)) +#define SYSCON_DCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_DCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_DCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_DCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_DCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_DCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_DCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_DCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_DCGC2_GPIOI (1 << 8) /* Bit 8: Port I Clock Gating Control */ +#define SYSCON_DCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_DCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Device Capabilities */ + +#define TIVA_SYSCON_DC9_ADC0DC0 (1 << 0) /* Bit 0: ADC0 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC0DC1 (1 << 1) /* Bit 1: ADC0 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC0DC2 (1 << 2) /* Bit 2: ADC0 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC0DC3 (1 << 3) /* Bit 3: ADC0 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC0DC4 (1 << 4) /* Bit 4: ADC0 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC0DC5 (1 << 5) /* Bit 5: ADC0 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC0DC6 (1 << 6) /* Bit 6: ADC0 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC0DC7 (1 << 7) /* Bit 7: ADC0 DC7 Present */ +#define TIVA_SYSCON_DC9_ADC1DC0 (1 << 16) /* Bit 16: ADC1 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC1DC1 (1 << 17) /* Bit 17: ADC1 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC1DC2 (1 << 18) /* Bit 18: ADC1 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC1DC3 (1 << 19) /* Bit 19: ADC1 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC1DC4 (1 << 20) /* Bit 20: ADC1 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC1DC5 (1 << 21) /* Bit 21: ADC1 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC1DC6 (1 << 22) /* Bit 22: ADC1 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC1DC7 (1 << 23) /* Bit 23: ADC1 DC7 Present */ + +/* Non-Volatile Memory Information */ + +#define TIVA_SYSCON_NVMSTAT_FWB (1 << 0) /* Bit 0: 32 Word Flash Write Buffer Available */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_CC3200_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/cc3200_vectors.h b/arch/arm/src/tiva/chip/cc3200_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..9c4b04d33689bd11a4307b4732ff9597ab578a7d --- /dev/null +++ b/arch/arm/src/tiva/chip/cc3200_vectors.h @@ -0,0 +1,267 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/cc3200_vectors.h + * + * Copyright (C) 2014 Droidifi LLC. All rights reserved. + * Author: Jim Ewing + * + * Adapted for the cc3200 from code: + * + * Copyright (C) Gregory Nutt. + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Droidifi 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Vectors + ************************************************************************************/ + +/* This file is included by tiva_vectors.S. It provides the macro VECTOR that + * supplies each Tiva vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/tiva/tm4c_irq.h. + * tiva_vectors.S will define the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +#if defined(CONFIG_ARCH_CHIP_CC3200) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 155 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 155 + +# else +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ +UNUSED(TIVA_RESERVED_20) /* Vector 20: Reserved */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +UNUSED(TIVA_RESERVED_23) /* Vector 23: Reserved */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +UNUSED(TIVA_RESERVED_25) /* Vector 25: Reserved */ +UNUSED(TIVA_RESERVED_26) /* Vector 26: Reserved */ +UNUSED(TIVA_RESERVED_27) /* Vector 27: Reserved */ +UNUSED(TIVA_RESERVED_28) /* Vector 28: Reserved */ +UNUSED(TIVA_RESERVED_29) /* Vector 29: Reserved */ +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +UNUSED(TIVA_RESERVED_41) /* Vector 41: Reserved */ +UNUSED(TIVA_RESERVED_42) /* Vector 42: Reserved */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +UNUSED(TIVA_RESERVED_46) /* Vector 46: Reserved */ +UNUSED(TIVA_RESERVED_47) /* Vector 47: Reserved */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: Reserved */ +UNUSED(TIVA_RESERVED_49) /* Vector 49: Reserved */ + +UNUSED(TIVA_RESERVED_50) /* Vector 50: Reserved */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +UNUSED(TIVA_RESERVED_53) /* Vector 53: Reserved */ +UNUSED(TIVA_RESERVED_54) /* Vector 54: Reserved */ +UNUSED(TIVA_RESERVED_55) /* Vector 55: Reserved */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +UNUSED(TIVA_RESERVED_58) /* Vector 58: Reserved */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +UNUSED(TIVA_RESERVED_60) /* Vector 60: Reserved */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 62: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR)/* Vector 63: uDMA Error */ +UNUSED(TIVA_RESERVED_64) /* Vector 64: Reserved */ +UNUSED(TIVA_RESERVED_65) /* Vector 65: Reserved */ +UNUSED(TIVA_RESERVED_66) /* Vector 66: Reserved */ +UNUSED(TIVA_RESERVED_67) /* Vector 67: Reserved */ +VECTOR(tiva_i2s0, TIVA_IRQ_I2S0) /* Vector 68: I2S 0 */ +VECTOR(tiva_epi, TIVA_IRQ_EPI) /* Vector 69: EPI */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +UNUSED(TIVA_RESERVED_71) /* Vector 71: Reserved */ +UNUSED(TIVA_RESERVED_72) /* Vector 72: Reserved */ +UNUSED(TIVA_RESERVED_73) /* Vector 73: Reserved */ +UNUSED(TIVA_RESERVED_74) /* Vector 74: Reserved */ +UNUSED(TIVA_RESERVED_75) /* Vector 75: Reserved */ +UNUSED(TIVA_RESERVED_76) /* Vector 76: Reserved */ +UNUSED(TIVA_RESERVED_77) /* Vector 77: Reserved */ +UNUSED(TIVA_RESERVED_78) /* Vector 78: Reserved */ +UNUSED(TIVA_RESERVED_79) /* Vector 79: Reserved */ + +UNUSED(TIVA_RESERVED_80) /* Vector 80: Reserved */ +UNUSED(TIVA_RESERVED_81) /* Vector 81: Reserved */ +UNUSED(TIVA_RESERVED_82) /* Vector 82: Reserved */ +UNUSED(TIVA_RESERVED_83) /* Vector 83: Reserved */ +UNUSED(TIVA_RESERVED_84) /* Vector 84: Reserved */ +UNUSED(TIVA_RESERVED_85) /* Vector 85: Reserved */ +UNUSED(TIVA_RESERVED_86) /* Vector 86: Reserved */ +UNUSED(TIVA_RESERVED_87) /* Vector 87: Reserved */ +UNUSED(TIVA_RESERVED_88) /* Vector 88: Reserved */ +UNUSED(TIVA_RESERVED_89) /* Vector 89: Reserved */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +UNUSED(TIVA_RESERVED_91) /* Vector 91: Reserved */ +UNUSED(TIVA_RESERVED_92) /* Vector 92: Reserved */ +UNUSED(TIVA_RESERVED_93) /* Vector 93: Reserved */ +UNUSED(TIVA_RESERVED_94) /* Vector 94: Reserved */ +UNUSED(TIVA_RESERVED_95) /* Vector 95: Reserved */ +UNUSED(TIVA_RESERVED_96) /* Vector 96: Reserved */ +UNUSED(TIVA_RESERVED_97) /* Vector 97: Reserved */ +UNUSED(TIVA_RESERVED_98) /* Vector 98: Reserved */ +UNUSED(TIVA_RESERVED_99) /* Vector 99: Reserved */ +UNUSED(TIVA_RESERVED_100) /* Vector 100: Reserved */ +UNUSED(TIVA_RESERVED_101) /* Vector 101: Reserved */ +UNUSED(TIVA_RESERVED_102) /* Vector 102: Reserved */ +UNUSED(TIVA_RESERVED_103) /* Vector 103: Reserved */ +UNUSED(TIVA_RESERVED_104) /* Vector 104: Reserved */ +UNUSED(TIVA_RESERVED_105) /* Vector 105: Reserved */ +UNUSED(TIVA_RESERVED_106) /* Vector 106: Reserved */ +UNUSED(TIVA_RESERVED_107) /* Vector 107: Reserved */ +UNUSED(TIVA_RESERVED_108) /* Vector 108: Reserved */ +UNUSED(TIVA_RESERVED_109) /* Vector 109: Reserved */ + +UNUSED(TIVA_RESERVED_110) /* Vector 110: Reserved */ +UNUSED(TIVA_RESERVED_111) /* Vector 111: Reserved */ +UNUSED(TIVA_RESERVED_112) /* Vector 112: Reserved */ +UNUSED(TIVA_RESERVED_113) /* Vector 113: Reserved */ +UNUSED(TIVA_RESERVED_114) /* Vector 114: Reserved */ +UNUSED(TIVA_RESERVED_115) /* Vector 115: Reserved */ +UNUSED(TIVA_RESERVED_116) /* Vector 116: Reserved */ +UNUSED(TIVA_RESERVED_117) /* Vector 117: Reserved */ +UNUSED(TIVA_RESERVED_118) /* Vector 118: Reserved */ +UNUSED(TIVA_RESERVED_119) /* Vector 119: Reserved */ + +UNUSED(TIVA_RESERVED_120) /* Vector 120: Reserved */ +UNUSED(TIVA_RESERVED_121) /* Vector 121: Reserved */ +VECTOR(tiva_system, TIVA_IRQ_SYSTEM) /* Vector 122: System Exception (imprecise) */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +UNUSED(TIVA_RESERVED_125) /* Vector 125: Reserved */ +UNUSED(TIVA_RESERVED_126) /* Vector 126: Reserved */ +UNUSED(TIVA_RESERVED_127) /* Vector 127: Reserved */ +UNUSED(TIVA_RESERVED_128) /* Vector 128: Reserved */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +UNUSED(TIVA_RESERVED_130) /* Vector 130: Reserved */ +UNUSED(TIVA_RESERVED_131) /* Vector 131: Reserved */ +UNUSED(TIVA_RESERVED_132) /* Vector 132: Reserved */ +UNUSED(TIVA_RESERVED_133) /* Vector 133: Reserved */ +UNUSED(TIVA_RESERVED_134) /* Vector 134: Reserved */ +UNUSED(TIVA_RESERVED_135) /* Vector 135: Reserved */ +UNUSED(TIVA_RESERVED_136) /* Vector 136: Reserved */ +UNUSED(TIVA_RESERVED_137) /* Vector 137: Reserved */ +UNUSED(TIVA_RESERVED_138) /* Vector 138: Reserved */ +UNUSED(TIVA_RESERVED_139) /* Vector 139: Reserved */ + +UNUSED(TIVA_RESERVED_140) /* Vector 140: Reserved */ +UNUSED(TIVA_RESERVED_141) /* Vector 141: Reserved */ +UNUSED(TIVA_RESERVED_142) /* Vector 142: Reserved */ +UNUSED(TIVA_RESERVED_143) /* Vector 143: Reserved */ +UNUSED(TIVA_RESERVED_144) /* Vector 144: Reserved */ +UNUSED(TIVA_RESERVED_145) /* Vector 145: Reserved */ +UNUSED(TIVA_RESERVED_146) /* Vector 146: Reserved */ +UNUSED(TIVA_RESERVED_147) /* Vector 147: Reserved */ +UNUSED(TIVA_RESERVED_148) /* Vector 148: Reserved */ +UNUSED(TIVA_RESERVED_149) /* Vector 149: Reserved */ + +UNUSED(TIVA_RESERVED_150) /* Vector 150: Reserved */ +UNUSED(TIVA_RESERVED_151) /* Vector 151: Reserved */ +UNUSED(TIVA_RESERVED_152) /* Vector 152: Reserved */ +UNUSED(TIVA_RESERVED_153) /* Vector 153: Reserved */ +UNUSED(TIVA_RESERVED_154) /* Vector 154: Reserved */ +UNUSED(TIVA_RESERVED_155) /* Vector 155: Reserved */ +UNUSED(TIVA_RESERVED_156) /* Vector 156: Reserved */ +UNUSED(TIVA_RESERVED_157) /* Vector 157: Reserved */ +UNUSED(TIVA_RESERVED_158) /* Vector 158: Reserved */ +UNUSED(TIVA_RESERVED_159) /* Vector 159: Reserved */ + +UNUSED(TIVA_RESERVED_160) /* Vector 160: Reserved */ +UNUSED(TIVA_RESERVED_161) /* Vector 161: Reserved */ +UNUSED(TIVA_RESERVED_162) /* Vector 162: Reserved */ +UNUSED(TIVA_RESERVED_163) /* Vector 163: Reserved */ +UNUSED(TIVA_RESERVED_164) /* Vector 164: SHA HW */ +UNUSED(TIVA_RESERVED_165) /* Vector 165: Reserved */ +UNUSED(TIVA_RESERVED_166) /* Vector 166: Reserved */ +UNUSED(TIVA_RESERVED_167) /* Vector 167: AES HW */ +UNUSED(TIVA_RESERVED_168) /* Vector 168: Reserved */ +UNUSED(TIVA_RESERVED_169) /* Vector 169: DES HW */ +UNUSED(TIVA_RESERVED_170) /* Vector 170: Reserved */ +UNUSED(TIVA_RESERVED_171) /* Vector 171: Reserved */ +UNUSED(TIVA_RESERVED_172) /* Vector 172: Reserved */ +UNUSED(TIVA_RESERVED_173) /* Vector 173: Reserved */ +UNUSED(TIVA_RESERVED_174) /* Vector 174: Reserved */ +UNUSED(TIVA_RESERVED_175) /* Vector 175: SDIO */ +UNUSED(TIVA_RESERVED_176) /* Vector 176: Reserved */ +UNUSED(TIVA_RESERVED_177) /* Vector 177: McASP 0 */ +UNUSED(TIVA_RESERVED_178) /* Vector 178: Reserved */ +UNUSED(TIVA_RESERVED_179) /* Vector 179: Camera A0 */ + +UNUSED(TIVA_RESERVED_180) /* Vector 180: Reserved */ +UNUSED(TIVA_RESERVED_181) /* Vector 181: Reserved */ +UNUSED(TIVA_RESERVED_182) /* Vector 182: Reserved */ +UNUSED(TIVA_RESERVED_183) /* Vector 183: Reserved */ +UNUSED(TIVA_RESERVED_184) /* Vector 184: RAM Err */ +UNUSED(TIVA_RESERVED_185) /* Vector 185: Reserved */ +UNUSED(TIVA_RESERVED_186) /* Vector 186: Reserved */ +UNUSED(TIVA_RESERVED_187) /* Vector 187: NWP IC interocessor comm */ +UNUSED(TIVA_RESERVED_188) /* Vector 188: Pwr, Rst, Clk */ +UNUSED(TIVA_RESERVED_189) /* Vector 189: From Top Die */ + +UNUSED(TIVA_RESERVED_190) /* Vector 190: Reserved */ +UNUSED(TIVA_RESERVED_191) /* Vector 191: SPI S0 */ +UNUSED(TIVA_RESERVED_192) /* Vector 192: SPI A0 */ +UNUSED(TIVA_RESERVED_193) /* Vector 193: SPI A1 */ +UNUSED(TIVA_RESERVED_194) /* Vector 194: Reserved */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#else +# error "Vectors not known for this Tiva chip" +#endif /* defined(CONFIG_ARCH_CHIP_CC3200) */ diff --git a/arch/arm/src/tiva/chip/lm3s_ethernet.h b/arch/arm/src/tiva/chip/lm3s_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..785f10bbcaaa8ac9f324e8afba56a6087e9961a0 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_ethernet.h @@ -0,0 +1,203 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_ethernet.h + * + * Copyright (C) 2009-2010, 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM3S_ETHERNET_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM3S_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Ethernet Controller Register Offsets *********************************************/ + +/* Ethernet MAC Register Offsets */ + +#define TIVA_MAC_RIS_OFFSET 0x000 /* Ethernet MAC Raw Interrupt Status */ +#define TIVA_MAC_IACK_OFFSET 0x000 /* Ethernet MAC Acknowledge */ +#define TIVA_MAC_IM_OFFSET 0x004 /* Ethernet MAC Interrupt Mask */ +#define TIVA_MAC_RCTL_OFFSET 0x008 /* Ethernet MAC Receive Control */ +#define TIVA_MAC_TCTL_OFFSET 0x00c /* Ethernet MAC Transmit Control */ +#define TIVA_MAC_DATA_OFFSET 0x010 /* Ethernet MAC Data */ +#define TIVA_MAC_IA0_OFFSET 0x014 /* Ethernet MAC Individual Address 0 */ +#define TIVA_MAC_IA1_OFFSET 0x018 /* Ethernet MAC Individual Address 1 */ +#define TIVA_MAC_THR_OFFSET 0x01c /* Ethernet MAC Threshold */ +#define TIVA_MAC_MCTL_OFFSET 0x020 /* Ethernet MAC Management Control */ +#define TIVA_MAC_MDV_OFFSET 0x024 /* Ethernet MAC Management Divider */ +#define TIVA_MAC_MTXD_OFFSET 0x02c /* Ethernet MAC Management Transmit Data */ +#define TIVA_MAC_MRXD_OFFSET 0x030 /* Ethernet MAC Management Receive Data */ +#define TIVA_MAC_NP_OFFSET 0x034 /* Ethernet MAC Number of Packets */ +#define TIVA_MAC_TR_OFFSET 0x038 /* Ethernet MAC Transmission Request */ +#ifdef TIVA_ETHTS +# define TIVA_MAC_TS_OFFSET 0x03c /* Ethernet MAC Time Stamp Configuration */ +#endif + +/* MII Management Register Offsets (see include/nuttx/net/mii.h) */ + +/* Ethernet Controller Register Addresses *******************************************/ + +#define TIVA_MAC_RIS (TIVA_ETHCON_BASE + TIVA_MAC_RIS_OFFSET) +#define TIVA_MAC_IACK (TIVA_ETHCON_BASE + TIVA_MAC_IACK_OFFSET) +#define TIVA_MAC_IM (TIVA_ETHCON_BASE + TIVA_MAC_IM_OFFSET) +#define TIVA_MAC_RCTL (TIVA_ETHCON_BASE + TIVA_MAC_RCTL_OFFSET) +#define TIVA_MAC_TCTL (TIVA_ETHCON_BASE + TIVA_MAC_TCTL_OFFSET) +#define TIVA_MAC_DATA (TIVA_ETHCON_BASE + TIVA_MAC_DATA_OFFSET) +#define TIVA_MAC_IA0 (TIVA_ETHCON_BASE + TIVA_MAC_IA0_OFFSET) +#define TIVA_MAC_IA1 (TIVA_ETHCON_BASE + TIVA_MAC_IA1_OFFSET) +#define TIVA_MAC_THR (TIVA_ETHCON_BASE + TIVA_MAC_THR_OFFSET) +#define TIVA_MAC_MCTL (TIVA_ETHCON_BASE + TIVA_MAC_MCTL_OFFSET) +#define TIVA_MAC_MDV (TIVA_ETHCON_BASE + TIVA_MAC_MDV_OFFSET) +#define TIVA_MAC_MTXD (TIVA_ETHCON_BASE + TIVA_MAC_MTXD_OFFSET) +#define TIVA_MAC_MRXD (TIVA_ETHCON_BASE + TIVA_MAC_MRXD_OFFSET) +#define TIVA_MAC_NP (TIVA_ETHCON_BASE + TIVA_MAC_NP_OFFSET) +#define TIVA_MAC_TR (TIVA_ETHCON_BASE + TIVA_MAC_TR_OFFSET) +#ifdef TIVA_ETHTS +# define TIVA_MAC_TS (TIVA_ETHCON_BASE + TIVA_MAC_TS_OFFSET) +#endif + +/* Memory Mapped MII Management Registers */ + +#define MAC_MII_MCR (TIVA_ETHCON_BASE + MII_MCR) +#define MAC_MII_MSR (TIVA_ETHCON_BASE + MII_MSR) +#define MAC_MII_PHYID1 (TIVA_ETHCON_BASE + MII_PHYID1) +#define MAC_MII_PHYID2 (TIVA_ETHCON_BASE + MII_PHYID2) +#define MAC_MII_ADVERTISE (TIVA_ETHCON_BASE + MII_ADVERTISE) +#define MAC_MII_LPA (TIVA_ETHCON_BASE + MII_LPA) +#define MAC_MII_EXPANSION (TIVA_ETHCON_BASE + MII_EXPANSION) +#define MAC_MII_VSPECIFIC (TIVA_ETHCON_BASE + MII_TIVA_VSPECIFIC) +#define MAC_MII_INTCS (TIVA_ETHCON_BASE + MII_TIVA_INTCS) +#define MAC_MII_DIAGNOSTIC (TIVA_ETHCON_BASE + MII_TIVA_DIAGNOSTIC) +#define MAC_MII_XCVRCONTROL (TIVA_ETHCON_BASE + MII_TIVA_XCVRCONTROL) +#define MAC_MII_LEDCONFIG (TIVA_ETHCON_BASE + MII_TIVA_LEDCONFIG) +#define MAC_MII_MDICONTROL (TIVA_ETHCON_BASE + MII_TIVA_MDICONTROL) + +/* Ethernet Controller Register Bit Definitions *************************************/ + +/* Ethernet MAC Raw Interrupt Status/Acknowledge (MACRIS/MACIACK), offset 0x000 */ + +#define MAC_RIS_RXINT (1 << 0) /* Bit 0: Packet Received */ +#define MAC_RIS_TXER (1 << 1) /* Bit 1: Transmit Error */ +#define MAC_RIS_TXEMP (1 << 2) /* Bit 2: Transmit FIFO Empty */ +#define MAC_RIS_FOV (1 << 3) /* Bit 3: FIFO Overrun */ +#define MAC_RIS_RXER (1 << 4) /* Bit 4: Receive Error */ +#define MAC_RIS_MDINT (1 << 5) /* Bit 5: MII Transaction Complete */ +#define MAC_RIS_PHYINT (1 << 6) /* Bit 6: PHY Interrupt */ + +#define MAC_IACK_RXINT (1 << 0) /* Bit 0: Clear Packet Received */ +#define MAC_IACK_TXER (1 << 1) /* Bit 1: Clear Transmit Error */ +#define MAC_IACK_TXEMP (1 << 2) /* Bit 2: Clear Transmit FIFO Empty */ +#define MAC_IACK_FOV (1 << 3) /* Bit 3: Clear FIFO Overrun */ +#define MAC_IACK_RXER (1 << 4) /* Bit 4: Clear Receive Error */ +#define MAC_IACK_MDINT (1 << 5) /* Bit 5: Clear MII Transaction Complete */ +#define MAC_IACK_PHYINT (1 << 6) /* Bit 6: Clear PHY Interrupt */ + +/* Ethernet MAC Interrupt Mask (MACIM), offset 0x004 */ + +#define MAC_IM_RXINTM (1 << 0) /* Bit 0: Mask Packet Received */ +#define MAC_IM_TXERM (1 << 1) /* Bit 1: Mask Transmit Error */ +#define MAC_IM_TXEMPM (1 << 2) /* Bit 2: Mask Transmit FIFO Empty */ +#define MAC_IM_FOVM (1 << 3) /* Bit 3: Mask FIFO Overrun */ +#define MAC_IM_RXERM (1 << 4) /* Bit 4: Mask Receive Error */ +#define MAC_IM_MDINTM (1 << 5) /* Bit 5: Mask MII Transaction Complete */ +#define MAC_IM_PHYINTM (1 << 6) /* Bit 6: Mask PHY Interrupt */ +#define MAC_IM_ALLINTS 0x7f + +/* Ethernet MAC Receive Control (MACRCTL), offset 0x008 */ + +#define MAC_RCTL_RXEN (1 << 0) /* Bit 0: Enable Receiver */ +#define MAC_RCTL_AMUL (1 << 1) /* Bit 1: Enable Multicast Frames */ +#define MAC_RCTL_PRMS (1 << 2) /* Bit 2: Enable Promiscuous Mode */ +#define MAC_RCTL_BADCRC (1 << 3) /* Bit 3: Enable Reject Bad CRC */ +#define MAC_RCTL_RSTFIFO (1 << 4) /* Bit 4: Clear Receive FIFO */ + +/* Ethernet MAC Transmit Control (MACTCTL), offset 0x00c */ + +#define MAC_TCTL_TXEN (1 << 0) /* Bit 0: Enable Transmitter */ +#define MAC_TCTL_PADEN (1 << 1) /* Bit 1: Enable Packet Padding */ +#define MAC_TCTL_CRC (1 << 2) /* Bit 2: Enable CRC Generation */ +#define MAC_TCTL_DUPLEX (1 << 4) /* Bit 4: Enable Duplex Mode */ + +/* Ethernet MAC Threshold (MACTHR), offset 0x01c */ + +#define MAC_THR_MASK 0x3f /* Bits 5-0: Threshold Value */ + +/* Ethernet MAC Management Control (MACMCTL), offset 0x020 */ + +#define MAC_MCTL_START (1 << 0) /* Bit 0: MII Register Transaction Enable */ +#define MAC_MCTL_WRITE (1 << 1) /* Bit 1: MII Register Transaction Type */ +#define MAC_MCTL_REGADR_SHIFT 3 /* Bits 7-3: MII Register Address */ +#define MAC_MCTL_REGADR_MASK (0x1f << MAC_MCTL_REGADR_SHIFT) + +/* Ethernet MAC Management Divider (MACMDV), offset 0x024 */ + +#define MAC_MDV_MASK 0xff /* Bits 7-0: Clock Divider */ + +/* Ethernet MAC Management Transmit Data (MACTXD), offset 0x02c */ + +#define MAC_MTXD_MASK 0xffff /* Bits 15-0: MII Register Transmit Data */ + +/* Ethernet MAC Management Receive Data (MACRXD), offset 0x030 */ + +#define MAC_MTRD_MASK 0xffff /* Bits 15-0: MII Register Receive Data */ + +/* Ethernet MAC Number of Packets (MACNP), offset 0x034 */ + +#define MAC_NP_MASK 0x3f /* Bits 5-0: Number of Packets in Receive FIFO */ + +/* Ethernet MAC Transmission Request (MACTR), offset 0x038 */ + +#define MAC_TR_NEWTX (1 << 0) /* Bit 0: New Transmission */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM3S_ETHERNET_H */ diff --git a/arch/arm/src/tiva/chip/lm3s_flash.h b/arch/arm/src/tiva/chip/lm3s_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..fb75e53ed731da4ddbb48f88f2634bc63744e6a0 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_flash.h @@ -0,0 +1,164 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_flash.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM3S_FLASH_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM3S_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* FLASH dimensions ****************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LM3S6965) || defined(CONFIG_ARCH_CHIP_LM4F120) || \ + defined(CONFIG_ARCH_CHIP_LM3S8962) || defined(CONFIG_ARCH_CHIP_LM3S9B96) || \ + defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) || defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) || \ + defined(CONFIG_ARCH_CHIP_CC3200) + +/* These parts all support a 1KiB erase page size and a total FLASH memory size + * of 256Kib or 256 pages. + */ + +# define TIVA_FLASH_NPAGES 256 +# define TIVA_FLASH_PAGESIZE 1024 + +#else +# warning "No flash dimensions defined for selected chip." +#endif + +#define TIVA_FLASH_SIZE (TIVA_FLASH_NPAGES * TIVA_FLASH_PAGESIZE) + +/* FLASH register offsets ***********************************************************/ + +/* The FMA, FMD, FMC, FCRIS, FCIM, and FCMISC registers are relative to the Flash + * control base address of TIVA_FLASHCON_BASE. + */ + +#define TIVA_FLASH_FMA_OFFSET 0x000 /* Flash memory address */ +#define TIVA_FLASH_FMD_OFFSET 0x004 /* Flash memory data */ +#define TIVA_FLASH_FMC_OFFSET 0x008 /* Flash memory control */ +#define TIVA_FLASH_FCRIS_OFFSET 0x00c /* Flash controller raw interrupt status */ +#define TIVA_FLASH_FCIM_OFFSET 0x010 /* Flash controller interrupt mask */ +#define TIVA_FLASH_FCMISC_OFFSET 0x014 /* Flash controller masked interrupt status and clear */ + +/* The FMPREn, FMPPEn, USECRL, USER_DBG, and USER_REGn registers are relative to the + * System Control base address of TIVA_SYSCON_BASE + */ + +#define TIVA_FLASH_FMPRE_OFFSET 0x130 /* Flash memory protection read enable */ +#define TIVA_FLASH_FMPPE_OFFSET 0x134 /* Flash memory protection program enable */ +#define TIVA_FLASH_USECRL_OFFSET 0x140 /* USec Reload */ +#define TIVA_FLASH_USERDBG_OFFSET 0x1d0 /* User Debug */ +#define TIVA_FLASH_USERREG0_OFFSET 0x1e0 /* User Register 0 */ +#define TIVA_FLASH_USERREG1_OFFSET 0x1e4 /* User Register 1 */ +#define TIVA_FLASH_FMPRE0_OFFSET 0x200 /* Flash Memory Protection Read Enable 0 */ +#define TIVA_FLASH_FMPRE1_OFFSET 0x204 /* Flash Memory Protection Read Enable 1 */ +#define TIVA_FLASH_FMPRE2_OFFSET 0x208 /* Flash Memory Protection Read Enable 2 */ +#define TIVA_FLASH_FMPRE3_OFFSET 0x20c /* Flash Memory Protection Read Enable 3 */ +#define TIVA_FLASH_FMPPE0_OFFSET 0x400 /* Flash Memory Protection Program Enable 0 */ +#define TIVA_FLASH_FMPPE1_OFFSET 0x404 /* Flash Memory Protection Program Enable 1 */ +#define TIVA_FLASH_FMPPE2_OFFSET 0x408 /* Flash Memory Protection Program Enable 2 */ +#define TIVA_FLASH_FMPPE3_OFFSET 0x40c /* Flash Memory Protection Program Enable 3 */ + +/* FLASH register addresses *********************************************************/ + +/* The FMA, FMD, FMC, FCRIS, FCIM, and FCMISC registers are relative to the Flash + * control base address of TIVA_FLASHCON_BASE. + */ + +#define TIVA_FLASH_FMA (TIVA_FLASHCON_BASE + TIVA_FLASH_FMA_OFFSET) +#define TIVA_FLASH_FMD (TIVA_FLASHCON_BASE + TIVA_FLASH_FMD_OFFSET) +#define TIVA_FLASH_FMC (TIVA_FLASHCON_BASE + TIVA_FLASH_FMC_OFFSET) +#define TIVA_FLASH_FCRIS (TIVA_FLASHCON_BASE + TIVA_FLASH_FCRIS_OFFSET) +#define TIVA_FLASH_FCIM (TIVA_FLASHCON_BASE + TIVA_FLASH_FCIM_OFFSET) +#define TIVA_FLASH_FCMISC (TIVA_FLASHCON_BASE + TIVA_FLASH_FCMISC_OFFSET) + +/* The FMPREn, FMPPEn, USECRL, USER_DBG, and USER_REGn registers are relative to the + * System Control base address of TIVA_SYSCON_BASE + */ + +#define TIVA_FLASH_FMPRE (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE_OFFSET) +#define TIVA_FLASH_FMPPE (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE_OFFSET) +#define TIVA_FLASH_USECRL (TIVA_SYSCON_BASE + TIVA_FLASH_USECRL_OFFSET) +#define TIVA_FLASH_USERDBG (TIVA_SYSCON_BASE + TIVA_FLASH_USERDBG_OFFSET) +#define TIVA_FLASH_USERREG0 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG0_OFFSET) +#define TIVA_FLASH_USERREG1 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG1_OFFSET) +#define TIVA_FLASH_FMPRE0 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE0_OFFSET) +#define TIVA_FLASH_FMPRE1 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE1_OFFSET) +#define TIVA_FLASH_FMPRE2 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE2_OFFSET) +#define TIVA_FLASH_FMPRE3 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE3_OFFSET) +#define TIVA_FLASH_FMPPE0 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE0_OFFSET) +#define TIVA_FLASH_FMPPE1 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE1_OFFSET) +#define TIVA_FLASH_FMPPE2 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE2_OFFSET) +#define TIVA_FLASH_FMPPE3 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE3_OFFSET) + +/* FLASH register bit definitions ***************************************************/ + +#define FLASH_FMA_OFFSET_SHIFT 0 /* Bits 17-0: Address Offset */ +#define FLASH_FMA_OFFSET_MASK (0x0003ffff << FLASH_FMA_OFFSET_SHIFT) + +#define FLASH_FMC_WRITE (1 << 0) /* Write a Word into Flash Memory */ +#define FLASH_FMC_ERASE (1 << 1) /* Erase a Page of Flash Memory */ +#define FLASH_FMC_MERASE (1 << 2) /* Mass Erase Flash Memory */ +#define FLASH_FMC_COMT (1 << 3) /* Commit Register Value */ + +/* This field contains a write key, which is used to minimize the incidence + * of accidental flash writes. The value 0xA442 must be written into this + * field for a write to occur. Writes to the FMC register without this WRKEY + * value are ignored. A read of this field returns the value 0 + */ +#define FLASH_FMC_WRKEY_SHIFT 16 /* Bits 16-31: Flash Write Key */ +#define FLASH_FMC_WRKEY_MASK (0xffff << FLASH_FMC_WRKEY_SHIFT) +#define FLASH_FMC_WRKEY (0xa442 << FLASH_FMC_WRKEY_SHIFT) /* Magic write key */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM3S_FLASH_H */ diff --git a/arch/arm/src/tiva/chip/lm3s_memorymap.h b/arch/arm/src/tiva/chip/lm3s_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..71ad565c1c10c8453a1b018cb7cdde873045b387 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_memorymap.h @@ -0,0 +1,352 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_memorymap.h + * + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM3S_MEMORYMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM3S_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory map ***********************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LM3S6918) || defined(CONFIG_ARCH_CHIP_LM3S6432) || \ + defined(CONFIG_ARCH_CHIP_LM3S6965) || defined(CONFIG_ARCH_CHIP_LM3S8962) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */ + /* -0x1fffffff: Reserved */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x2000ffff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x221fffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000- */ + /* -0xdfffffff: Reserved */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ + /* -0xffffffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */ + /* -0x1fffffff: Reserved */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x2000ffff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x221fffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alise of 40000000- */ + /* -0x5fffffff: Reserved */ +# define TIVA_EPI0RAM_BASE 0x60000000 /* -0xdfffffff: EPI0 mapped peripheral and RAM */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ + /* -0xffffffff: Reserved */ +#else +# error "Memory map not specified for this LM3S chip" +#endif + +/* Peripheral base addresses ********************************************************/ +/* The LM3S6918 and LM3S6965 differ by only the presence or absence of a few differnt + * peripheral modules. They could probably be combined into one peripheral memory + * map. However, keeping them separate does also provide so early, compile-time + * error detection that makes the duplication worthwhile. + */ + +#if defined(CONFIG_ARCH_CHIP_LM3S6918) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */ + /* -0x0bfff: Reserved */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ + /* -0x23fff: Reserved */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ +# define TIVA_GPIOH_BASE (TIVA_PERIPH_BASE + 0x27000) /* -0x27fff: GPIO Port H */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x47fff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */ + /* -0xfcfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ + /* -0x1ffffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_LM3S6432) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ + /* -0x0bfff: Reserved */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ + /* -0x23fff: Reserved */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ + /* -0x27fff: Reserved */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x47fff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */ + /* -0xfcfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ + /* -0x1ffffff: Reserved */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S6965) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ + /* -0x0bfff: Reserved */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0dfff: UART2 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ + /* -0x23fff: Reserved */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ + /* -0x27fff: Reserved */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */ + /* -0x2bfff: Reserved */ +# define TIVA_QEI0_BASE (TIVA_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */ +# define TIVA_QEI1_BASE (TIVA_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x47fff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */ + /* -0xfcfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ + /* -0x1ffffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_LM3S8962) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ + /* -0x0bfff: Reserved */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ + /* -0x23fff: Reserved */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ + /* -0x27fff: Reserved */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */ + /* -0x2bfff: Reserved */ +# define TIVA_QEI0_BASE (TIVA_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */ +# define TIVA_QEI1_BASE (TIVA_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x3fffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller */ + /* -0x47fff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */ + /* -0xfcfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ + /* -0x1ffffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI0 */ + /* -0x0bfff: Reserved */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0dfff: UART2 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x207ff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x217ff: I2C1 */ + /* -0x23fff: Reserved */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ +# define TIVA_GPIOH_BASE (TIVA_PERIPH_BASE + 0x27000) /* -0x27fff: GPIO Port H */ + +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM */ + /* -0x2bfff: Reserved */ +# define TIVA_QEI0_BASE (TIVA_PERIPH_BASE + 0x2c000) /* -0x2cfff: QEI0 */ +# define TIVA_QEI1_BASE (TIVA_PERIPH_BASE + 0x2d000) /* -0x2dfff: QEI1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: Timer 3 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ +# define TIVA_GPIOJ_BASE (TIVA_PERIPH_BASE + 0x3d000) /* -0x3dfff: GPIO Port J */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH_BASE + 0x41000) /* -0x41fff: CAN 1 */ + /* -0x47fff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH_BASE + 0x48000) /* -0x48fff: Ethernet Controller */ + /* -0x49fff: Reserved */ +# define TIVA_USB_BASE (TIVA_PERIPH_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x53fff: Reserved */ +# define TIVA_I2S0_BASE (TIVA_PERIPH_BASE + 0x54000) /* -0x54fff: I2S 0 */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ +# define TIVA_GPIOGAHB_BASE (TIVA_PERIPH_BASE + 0x5e000) /* -0x5efff: GPIO Port G (AHB aperture) */ +# define TIVA_GPIOHAHB_BASE (TIVA_PERIPH_BASE + 0x5f000) /* -0x5ffff: GPIO Port H (AHB aperture) */ +# define TIVA_GPIOJAHB_BASE (TIVA_PERIPH_BASE + 0x60000) /* -0x60fff: GPIO Port J (AHB aperture) */ + /* -0xcffff: Reserved */ +# define TIVA_EPI0_BASE (TIVA_PERIPH_BASE + 0xd0000) /* -0xd0fff: EPI 0 */ + /* -0xfcfff: Reserved */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + /* -0x1ffffff: Reserved */ +#else +# error "Peripheral base addresses not specified for this Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM3S_MEMORYMAP_H */ diff --git a/arch/arm/src/tiva/chip/lm3s_pinmap.h b/arch/arm/src/tiva/chip/lm3s_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..0e4a26c74cebd190a66e3827bdeaab9ff1ee00b0 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_pinmap.h @@ -0,0 +1,281 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_pinmap.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM3S_PINMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM3S_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* The following lists the input value to tiva_configgpio to setup the alternate, + * hardware function for each pin. + */ + +#if defined(CONFIG_ARCH_CHIP_LM3S6918) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 0) /* PA0: UART 0 receive (U0Rx) */ +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 1) /* PA1: UART 0 transmit (U0Tx) */ +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_PORTA | 2) /* PA2: SSI0 clock (SSI0Clk) */ +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_PORTA | 3) /* PA3: SSI0 frame (SSI0Fss) */ +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 4) /* PA4: SSI0 receive (SSI0Rx) */ +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 5) /* PA5: SSI0 transmit (SSI0Tx) */ +# define GPIO_TMR1_CCP (GPIO_FUNC_PFIO | GPIO_PORTA | 6) /* PA6: Capture/Compare/PWM1 (CCP1) */ +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_PORTA | 7) /* PA7: I2C1 data (I2C1SDA) */ +# define GPIO_TMR0_CCP (GPIO_FUNC_PFIO | GPIO_PORTB | 0) /* PB0: Capture/Compare/PWM0 (CCP0) */ +# define GPIO_TMR2_CCP (GPIO_FUNC_PFIO | GPIO_PORTB | 1) /* PB1: Capture/Compare/PWM2 (CCP2) */ +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 2) /* PB2: I2C0 clock (I2C0SCL) */ +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_PORTB | 3) /* PB3: I2C0 data (I2C0SDA) */ +# define GPIO_CMP0_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 4) /* PB4: Analog comparator 0 negative input (C0-) */ +# define GPIO_CMP1_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 5) /* PB5: Analog comparator 1 negative input (C1-) */ +# define GPIO_CMP0_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 6) /* PB6: Analog comparator 0 positive input (C0+) */ +# define GPIO_JTAG_TRST (GPIO_FUNC_PFINPUT | GPIO_PORTB | 7) /* PB7: JTAG ~TRST */ +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_TMS (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG TMS */ +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG SWDIO */ +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_PORTC | 2) /* PC2: JTAG TDI */ +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG TDO */ +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG SWO */ +# define GPIO_TMR5_CCP (GPIO_FUNC_PFIO | GPIO_PORTC | 4) /* PC4: Capture/Compare/PWM5 (CCP5) */ +# define GPIO_CMP1_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 1 positive input (C1+) */ +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 0 output (C0o) */ +# define GPIO_TMR3_CCP (GPIO_FUNC_PFIO | GPIO_PORTC | 6) /* PC6: Capture/Compare/PWM3 (CCP3) */ +# define GPIO_TMR4_CCP (GPIO_FUNC_PFIO | GPIO_PORTC | 7) /* PC7: Capture/Compare/PWM4 (CCP4) */ +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 2) /* PD2: UART 1 receive (U1Rx) */ +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 3) /* PD3: UART 1 transmit (U1Tx) */ +# define GPIO_SSI1_CLK (GPIO_FUNC_PFIO | GPIO_PORTE | 0) /* PE0: SSI1 clock (SSI1Clk) */ +# define GPIO_SSI1_FSS (GPIO_FUNC_PFIO | GPIO_PORTE | 1) /* PE1: SSI1 frame (SSI1Fss) */ +# define GPIO_SSI1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: SSI1 receive (SSI1Rx) */ +# define GPIO_SSI1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 3) /* PE3: SSI1 transmit (SSI1Tx) */ +# define GPIO_ETHPHY_LED1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 2) /* PF2: LED1 */ +# define GPIO_ETHPHY_LED0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 3) /* PF3: LED0 */ +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTG | 0) /* PG0: I2C1 clock (I2C1SCL) */ +#elif defined(CONFIG_ARCH_CHIP_LM3S6432) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 0) /* PA0: UART 0 receive (U0Rx) */ +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 1) /* PA1: UART 0 transmit (U0Tx) */ +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_PORTA | 2) /* PA2: SSI0 clock (SSI0Clk) */ +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_PORTA | 3) /* PA3: SSI0 frame (SSI0Fss) */ +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 4) /* PA4: SSI0 receive (SSI0Rx) */ +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 5) /* PA5: SSI0 transmit (SSI0Tx) */ +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 2) /* PB2: I2C0 clock (I2C0SCL) */ +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_PORTB | 3) /* PB3: I2C0 data (I2C0SDA) */ +# define GPIO_CMP0_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 4) /* PB4: Analog comparator 0 negative input (C0-) */ +# define GPIO_CMP1_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 5) /* PB5: Analog comparator 1 negative input (C1-) */ +# define GPIO_CMP0_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 6) /* PB6: Analog comparator 0 positive input (C0+) */ +# define GPIO_JTAG_TRST (GPIO_FUNC_PFINPUT | GPIO_PORTB | 7) /* PB7: JTAG ~TRST */ +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_TMS (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG TMS */ +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG SWDIO */ +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_PORTC | 2) /* PC2: JTAG TDI */ +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG TDO */ +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG SWO */ +# define GPIO_CMP1_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 1 positive input (C1+) */ +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 0 output (C0o) */ +# define GPIO_PWM0_0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 0) /* PD0: PWM Generator 0, PWM0 */ +# define GPIO_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 1) /* PD1: PWM Generator 0, PWM1 */ +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 2) /* PD2: UART 1 receive (U1Rx) */ +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 3) /* PD3: UART 1 transmit (U1Tx) */ +# define GPIO_PWM_FAULT (GPIO_FUNC_PFINPUT | GPIO_PORTD | 6) /* PD6: PWM Fault */ +# define GPIO_TMR1_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 7) /* PD7: Capture/Compare/TMR1 (CCP1) */ +# define GPIO_ETHPHY_LED1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 2) /* PF2: LED1 */ +# define GPIO_ETHPHY_LED0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 3) /* PF3: LED0 */ +#elif defined(CONFIG_ARCH_CHIP_LM3S6965) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 0) /* PA0: UART 0 receive (U0Rx) */ +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 1) /* PA1: UART 0 transmit (U0Tx) */ +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_PORTA | 2) /* PA2: SSI0 clock (SSI0Clk) */ +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_PORTA | 3) /* PA3: SSI0 frame (SSI0Fss) */ +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 4) /* PA4: SSI0 receive (SSI0Rx) */ +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 5) /* PA5: SSI0 transmit (SSI0Tx) */ +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 6) /* PA6: I2C1 clock (I2C1SCL) */ +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_PORTA | 7) /* PA7: I2C1 data (I2C1SDA) */ +# define GPIO_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 0) /* PB0: PWM Generator 1, PWM2 */ +# define GPIO_PWM1_3 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 1) /* PB1: PWM Generator 1, PWM3 */ +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 2) /* PB2: I2C0 clock (I2C0SCL) */ +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_PORTB | 3) /* PB3: I2C0 data (I2C0SDA) */ +# define GPIO_CMP0_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 4) /* PB4: Analog comparator 0 negative input (C0-) */ +# define GPIO_CMP1_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 5) /* PB5: Analog comparator 1 negative input (C1-) */ +# define GPIO_CMP0_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 6) /* PB6: Analog comparator 0 positive input (C0+) */ +# define GPIO_JTAG_TRST (GPIO_FUNC_PFINPUT | GPIO_PORTB | 7) /* PB7: JTAG ~TRST */ +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_TMS (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG TMS */ +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG SWDIO */ +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_PORTC | 2) /* PC2: JTAG TDI */ +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG TDO */ +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG SWO */ +# define GPIO_QEI0_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTC | 4) /* PC4: QEI module 0 phase A. */ +# define GPIO_CMP1_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 1 positive input (C1+) */ +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 0 output (C0o) */ +# define GPIO_TMR3_CCP (GPIO_FUNC_PFIO | GPIO_PORTC | 6) /* PC6: Capture/Compare/PWM3 (CCP3) */ +# define GPIO_QEI0_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTC | 7) /* PC7: QEI module 0 phase B. */ +# define GPIO_QEI0_IDX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 1) /* PD0: QEI module 0 index. ) */ +# define GPIO_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 1) /* PD1: PWM Generator 0, PWM1 */ +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 2) /* PD2: UART 1 receive (U1Rx) */ +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 3) /* PD3: UART 1 transmit (U1Tx) */ +# define GPIO_TMR0_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 4) /* PC4: Capture/Compare/PWM0 (CCP0) */ +# define GPIO_TMR2_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 5) /* PC5: Capture/Compare/PWM2 (CCP2) */ +# define GPIO_PWM_FAULT (GPIO_FUNC_PFINPUT | GPIO_PORTD | 6) /* PC5: PWM Fault */ +# define GPIO_TMR1_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 7) /* PC5: Capture/Compare/TMR1 (CCP1) */ +# define GPIO_SSI1_CLK (GPIO_FUNC_PFIO | GPIO_PORTE | 0) /* PE0: SSI1 clock (SSI1Clk) */ +# define GPIO_SSI1_FSS (GPIO_FUNC_PFIO | GPIO_PORTE | 1) /* PE1: SSI1 frame (SSI1Fss) */ +# define GPIO_SSI1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: SSI1 receive (SSI1Rx) */ +# define GPIO_SSI1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 3) /* PE3: SSI1 transmit (SSI1Tx) */ +# define GPIO_PWM2_4 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 0) /* PE0: PWM Generator 2, PWM4 */ +# define GPIO_PWM2_5 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 1) /* PE1: PWM Generator 1, PWM5 */ +# define GPIO_QEI1_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: QEI module 1 phase B. */ +# define GPIO_QEI1_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTE | 3) /* PE3: QEI module 1 phase A. */ +# define GPIO_PWM0_0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 0) /* PE4: PWM Generator 0, PWM0 */ +# define GPIO_QEI1_IDX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 1) /* PD0: QEI module 1 index. ) */ +# define GPIO_ETHPHY_LED1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 2) /* PF2: LED1 */ +# define GPIO_ETHPHY_LED0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 3) /* PF3: LED0 */ +# define GPIO_UART2_RX (GPIO_FUNC_PFINPUT | GPIO_PORTG | 0) /* PA0: UART 0 receive (UGRx) */ +# define GPIO_UART2_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTG | 1) /* PA1: UART 0 transmit (UGTx) */ +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 0) /* PA0: UART 0 receive (U0Rx) */ +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 1) /* PA1: UART 0 transmit (U0Tx) */ +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_PORTA | 2) /* PA2: SSI0 clock (SSI0Clk) */ +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_PORTA | 3) /* PA3: SSI0 frame (SSI0Fss) */ +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 4) /* PA4: SSI0 receive (SSI0Rx) */ +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 5) /* PA5: SSI0 transmit (SSI0Tx) */ +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 6) /* PA6: I2C1 clock (I2C1SCL) */ +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_PORTA | 7) /* PA7: I2C1 data (I2C1SDA) */ +# define GPIO_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 0) /* PB0: PWM Generator 1, PWM2 */ +# define GPIO_PWM1_3 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 1) /* PB1: PWM Generator 1, PWM3 */ +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 2) /* PB2: I2C0 clock (I2C0SCL) */ +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_PORTB | 3) /* PB3: I2C0 data (I2C0SDA) */ +# define GPIO_CMP0_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 4) /* PB4: Analog comparator 0 negative input (C0-) */ +# define GPIO_CMP1_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 5) /* PB5: Analog comparator 1 negative input (C1-) */ +# define GPIO_CMP0_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 6) /* PB6: Analog comparator 0 positive input (C0+) */ +# define GPIO_JTAG_TRST (GPIO_FUNC_PFINPUT | GPIO_PORTB | 7) /* PB7: JTAG ~TRST */ +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_TMS (GPIO_FUNC_PFINPUT | GPIO_PORTC | 1) /* PC1: JTAG TMS */ +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG SWDIO */ +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_PORTC | 2) /* PC2: JTAG TDI */ +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG TDO */ +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG SWO */ +# define GPIO_QEI0_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTC | 4) /* PC4: QEI module 0 phase A. */ +# define GPIO_CMP1_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 1 positive input (C1+) */ +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 5) /* PC5: Analog comparator 0 output (C0o) */ +# define GPIO_TMR3_CCP (GPIO_FUNC_PFIO | GPIO_PORTC | 6) /* PC6: Capture/Compare/PWM3 (CCP3) */ +# define GPIO_QEI0_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTC | 7) /* PC7: QEI module 0 phase B. */ +# define GPIO_QEI0_IDX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 1) /* PD0: QEI module 0 index. ) */ +# define GPIO_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 1) /* PD1: PWM Generator 0, PWM1 */ +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 2) /* PD2: UART 1 receive (U1Rx) */ +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 3) /* PD3: UART 1 transmit (U1Tx) */ +# define GPIO_TMR0_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 4) /* PC4: Capture/Compare/PWM0 (CCP0) */ +# define GPIO_TMR2_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 5) /* PC5: Capture/Compare/PWM2 (CCP2) */ +# define GPIO_PWM_FAULT (GPIO_FUNC_PFINPUT | GPIO_PORTD | 6) /* PC5: PWM Fault */ +# define GPIO_TMR1_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 7) /* PC5: Capture/Compare/TMR1 (CCP1) */ +# define GPIO_SSI1_CLK (GPIO_FUNC_PFIO | GPIO_PORTE | 0) /* PE0: SSI1 clock (SSI1Clk) */ +# define GPIO_SSI1_FSS (GPIO_FUNC_PFIO | GPIO_PORTE | 1) /* PE1: SSI1 frame (SSI1Fss) */ +# define GPIO_SSI1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: SSI1 receive (SSI1Rx) */ +# define GPIO_SSI1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 3) /* PE3: SSI1 transmit (SSI1Tx) */ +# define GPIO_PWM2_4 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 0) /* PE0: PWM Generator 2, PWM4 */ +# define GPIO_PWM2_5 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 1) /* PE1: PWM Generator 1, PWM5 */ +# define GPIO_QEI1_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: QEI module 1 phase B. */ +# define GPIO_QEI1_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTE | 3) /* PE3: QEI module 1 phase A. */ +# define GPIO_PWM0_0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 0) /* PE4: PWM Generator 0, PWM0 */ +# define GPIO_QEI1_IDX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 1) /* PD0: QEI module 1 index. ) */ +# define GPIO_ETHPHY_LED1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 2) /* PF2: LED1 */ +# define GPIO_ETHPHY_LED0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 3) /* PF3: LED0 */ +# define GPIO_UART2_RX (GPIO_FUNC_PFINPUT | GPIO_PORTG | 0) /* PA0: UART 0 receive (UGRx) */ +# define GPIO_UART2_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTG | 1) /* PA1: UART 0 transmit (UGTx) */ + +#elif defined(CONFIG_ARCH_CHIP_LM3S8962) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 0) /* PA0: UART 0 receive (U0Rx) */ +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 1) /* PA1: UART 0 transmit (U0Tx) */ +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_PORTA | 2) /* PA2: SSI0 clock (SSI0Clk) */ +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_PORTA | 3) /* PA3: SSI0 frame (SSI0Fss) */ +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTA | 4) /* PA4: SSI0 receive (SSI0Rx) */ +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTA | 5) /* PA5: SSI0 transmit (SSI0Tx) */ +# define GPIO_TMR1_CCP (GPIO_FUNC_PFIO | GPIO_PORTA | 6) /* PA6: Capture/Compare/PWM0 (CCP1) */ +# define GPIO_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 0) /* PB0: PWM Generator 1, PWM2 */ +# define GPIO_PWM1_3 (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 1) /* PB1: PWM Generator 1, PWM3 */ +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 2) /* PB2: I2C0 clock (I2C0SCL) */ +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_PORTB | 3) /* PB3: I2C0 data (I2C0SDA) */ +# define GPIO_CMP0_NIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 4) /* PB4: Analog comparator 0 negative input (C0-) */ +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_PORTB | 5) /* PB5: Analog comparator 0 output (C0o) (differs) */ +# define GPIO_CMP0_PIN (GPIO_FUNC_PFINPUT | GPIO_PORTB | 6) /* PB6: Analog comparator 0 positive input (C0+) */ +# define GPIO_JTAG_TRST (GPIO_FUNC_PFINPUT | GPIO_PORTB | 7) /* PB7: JTAG ~TRST */ +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_PORTC | 0) /* PC0: JTAG/SWD CLK */ +# define GPIO_JTAG_TMS (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG TMS */ +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_PORTC | 1) /* PC1: JTAG SWDIO */ +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_PORTC | 2) /* PC2: JTAG TDI */ +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG TDO */ +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_PORTC | 3) /* PC3: JTAG SWO */ +# define GPIO_QEI0_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTC | 4) /* PC4: QEI module 0 phase A. */ +# define GPIO_QEI0_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTC | 6) /* PC6: QEI module 0 phase B. */ +# define GPIO_CAN0_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 0) /* PD0: CAN module RX */ +# define GPIO_CAN0_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 1) /* PD1: CAN module TX */ +# define GPIO_UART1_RX (GPIO_FUNC_PFINPUT | GPIO_PORTD | 2) /* PD2: UART 1 receive (U1Rx) */ +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_PORTD | 3) /* PD3: UART 1 transmit (U1Tx) */ +# define GPIO_TMR0_CCP (GPIO_FUNC_PFIO | GPIO_PORTD | 4) /* PD4: Capture/Compare/PWM0 (CCP0) */ +# define GPIO_PWM_FAULT (GPIO_FUNC_PFINPUT | GPIO_PORTD | 6) /* PD6: PWM Fault */ +# define GPIO_QEI0_IDX (GPIO_FUNC_PFIO | GPIO_PORTD | 7) /* PC7: QEI module 0 index */ +# define GPIO_PWM2_4 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 0) /* PE0: PWM Generator 2, PWM4 */ +# define GPIO_PWM2_5 (GPIO_FUNC_PFOUTPUT | GPIO_PORTE | 1) /* PE1: PWM Generator 1, PWM5 */ +# define GPIO_QEI1_PHB (GPIO_FUNC_PFINPUT | GPIO_PORTE | 2) /* PE2: QEI module 1 phase B. */ +# define GPIO_QEI1_PHA (GPIO_FUNC_PFINPUT | GPIO_PORTE | 3) /* PE3: QEI module 1 phase A. */ +# define GPIO_PWM0_0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 0) /* PF0: PWM Generator 0, PWM0 */ +# define GPIO_QEI1_IDX (GPIO_FUNC_PFINPUT | GPIO_PORTE | 1) /* PF1: QEI module 1 index. ) */ +# define GPIO_ETHPHY_LED1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 2) /* PF2: LED1 */ +# define GPIO_ETHPHY_LED0 (GPIO_FUNC_PFOUTPUT | GPIO_PORTF | 3) /* PF3: LED0 */ +# define GPIO_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_PORTG | 1) /* PG1:PWM Generator 0, PWM1 */ +#else +# error "Unknown Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM3S_PINMAP_H */ diff --git a/arch/arm/src/tiva/chip/lm3s_syscontrol.h b/arch/arm/src/tiva/chip/lm3s_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..5097b9bd7a567e09939ebda82fd472afc953b815 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_syscontrol.h @@ -0,0 +1,495 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_syscontrol.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM3S_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM3S_SYSCONTROL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* System Control Register Offsets **************************************************/ + +#define TIVA_SYSCON_DID0_OFFSET 0x000 /* Device Identification 0 */ +#define TIVA_SYSCON_DID1_OFFSET 0x004 /* Device Identification 1 */ +#define TIVA_SYSCON_DC0_OFFSET 0x008 /* Device Capabilities 0 */ +#define TIVA_SYSCON_DC1_OFFSET 0x010 /* Device Capabilities 1 */ +#define TIVA_SYSCON_DC2_OFFSET 0x014 /* Device Capabilities 2 */ +#define TIVA_SYSCON_DC3_OFFSET 0x018 /* Device Capabilities 3 */ +#define TIVA_SYSCON_DC4_OFFSET 0x01c /* Device Capabilities 4 */ +#define TIVA_SYSCON_PBORCTL_OFFSET 0x030 /* Brown-Out Reset Control */ +#define TIVA_SYSCON_LDOPCTL_OFFSET 0x034 /* LDO Power Control */ +#define TIVA_SYSCON_SRCR0_OFFSET 0x040 /* Software Reset Control 0 */ +#define TIVA_SYSCON_SRCR1_OFFSET 0x044 /* Software Reset Control 1 */ +#define TIVA_SYSCON_SRCR2_OFFSET 0x048 /* Software Reset Control 2*/ +#define TIVA_SYSCON_RIS_OFFSET 0x050 /* Raw Interrupt Status */ +#define TIVA_SYSCON_IMC_OFFSET 0x054 /* Interrupt Mask Control */ +#define TIVA_SYSCON_MISC_OFFSET 0x058 /* Masked Interrupt Status and Clear */ +#define TIVA_SYSCON_RESC_OFFSET 0x05c /* Reset Cause */ +#define TIVA_SYSCON_RCC_OFFSET 0x060 /* Run-Mode Clock Configuration */ +#define TIVA_SYSCON_PLLCFG_OFFSET 0x064 /* XTAL to PLL Translation */ +#define TIVA_SYSCON_RCC2_OFFSET 0x070 /* Run-Mode Clock Configuration 2 */ +#define TIVA_SYSCON_RCGC0_OFFSET 0x100 /* Run Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_RCGC1_OFFSET 0x104 /* Run Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_RCGC2_OFFSET 0x108 /* Run Mode Clock Gating Control Register 2 */ +#define TIVA_SYSCON_SCGC0_OFFSET 0x110 /* Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_SCGC1_OFFSET 0x114 /* Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_SCGC2_OFFSET 0x118 /* Sleep Mode Clock Gating Control Register 2 */ +#define TIVA_SYSCON_DCGC0_OFFSET 0x120 /* Deep Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_DCGC1_OFFSET 0x124 /* Deep Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_DCGC2_OFFSET 0x128 /* Deep Sleep Mode Clock Gating Control Register 2 */ +#define TIVA_SYSCON_DSLPCLKCFG_OFFSET 0x144 /* Deep Sleep Clock Configuration*/ + +/* System Control Register Addresses ************************************************/ + +#define TIVA_SYSCON_DID0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID0_OFFSET) +#define TIVA_SYSCON_DID1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID1_OFFSET) +#define TIVA_SYSCON_DC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC0_OFFSET) +#define TIVA_SYSCON_DC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC1_OFFSET) +#define TIVA_SYSCON_DC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC2_OFFSET) +#define TIVA_SYSCON_DC3 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC3_OFFSET) +#define TIVA_SYSCON_DC4 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC4_OFFSET) +#define TIVA_SYSCON_PBORCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_PBORCTL_OFFSET) +#define TIVA_SYSCON_LDOPCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDOPCTL_OFFSET) +#define TIVA_SYSCON_SRCR0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR0_OFFSET) +#define TIVA_SYSCON_SRCR1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR1_OFFSET) +#define TIVA_SYSCON_SRCR2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR2_OFFSET) +#define TIVA_SYSCON_RIS (TIVA_SYSCON_BASE + TIVA_SYSCON_RIS_OFFSET) +#define TIVA_SYSCON_IMC (TIVA_SYSCON_BASE + TIVA_SYSCON_IMC_OFFSET) +#define TIVA_SYSCON_MISC (TIVA_SYSCON_BASE + TIVA_SYSCON_MISC_OFFSET) +#define TIVA_SYSCON_RESC (TIVA_SYSCON_BASE + TIVA_SYSCON_RESC_OFFSET) +#define TIVA_SYSCON_RCC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC_OFFSET) +#define TIVA_SYSCON_PLLCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLCFG_OFFSET) +#define TIVA_SYSCON_RCC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC2_OFFSET) +#define TIVA_SYSCON_RCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC0_OFFSET) +#define TIVA_SYSCON_RCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC1_OFFSET) +#define TIVA_SYSCON_RCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC2_OFFSET) +#define TIVA_SYSCON_SCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC0_OFFSET) +#define TIVA_SYSCON_SCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC1_OFFSET) +#define TIVA_SYSCON_SCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC2_OFFSET) +#define TIVA_SYSCON_DCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC0_OFFSET) +#define TIVA_SYSCON_DCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC1_OFFSET) +#define TIVA_SYSCON_DCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC2_OFFSET) +#define TIVA_SYSCON_DSLPCLKCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPCLKCFG_OFFSET) + +/* System Control Register Bit Definitions ******************************************/ + +/* Device Identification 0 (DID0), offset 0x000 */ + +#define SYSCON_DID0_MINOR_SHIFT 0 /* Bits 7-0: Minor Revision of the device */ +#define SYSCON_DID0_MINOR_MASK (0xff << SYSCON_DID0_MINOR_SHIFT) +#define SYSCON_DID0_MAJOR_SHIFT 8 /* Bits 15-8: Major Revision of the device */ +#define SYSCON_DID0_MAJOR_MASK (0xff << SYSCON_DID0_MAJOR_SHIFT) +#define SYSCON_DID0_CLASS_SHIFT 16 /* Bits 23-16: Device Class */ +#define SYSCON_DID0_CLASS_MASK (0xff << SYSCON_DID0_CLASS_SHIFT) +#define SYSCON_DID0_VER_SHIFT 28 /* Bits 30-28: DID0 Version */ +#define SYSCON_DID0_VER_MASK (7 << SYSCON_DID0_VER_SHIFT) + +/* Device Identification 1 (DID1), offset 0x004 */ + +#define SYSCON_DID1_QUAL_SHIFT 0 /* Bits 1-0: Qualification Status */ +#define SYSCON_DID1_QUAL_MASK (0x03 << SYSCON_DID1_QUAL_SHIFT) +#define SYSCON_DID1_ROHS (1 << 2) /* Bit 2: RoHS-Compliance */ +#define SYSCON_DID1_PKG_SHIFT 3 /* Bits 4-3: Package Type */ +#define SYSCON_DID1_PKG_MASK (0x03 << SYSCON_DID1_PKG_SHIFT) +#define SYSCON_DID1_TEMP_SHIFT 5 /* Bits 7-5: Temperature Range */ +#define SYSCON_DID1_TEMP_MASK (0x07 << SYSCON_DID1_TEMP_SHIFT) +#define SYSCON_DID1_PINCOUNT_SHIFT 13 /* Bits 15-13: Package Pin Count */ +#define SYSCON_DID1_PINCOUNT_MASK (0x07 << SYSCON_DID1_PINCOUNT_SHIFT) +#define SYSCON_DID1_PARTNO_SHIFT 16 /* Bits 23-16: Part Number */ +#define SYSCON_DID1_PARTNO_MASK (0xff << SYSCON_DID1_PARTNO_SHIFT) +#define SYSCON_DID1_FAM_SHIFT 24 /* Bits 27-24: Family */ +#define SYSCON_DID1_FAM_MASK (0x0f << SYSCON_DID1_FAM_SHIFT) +#define SYSCON_DID1_VER_SHIFT 28 /* Bits 31-28: DID1 Version */ +#define SYSCON_DID1_VER_MASK (0x0f << SYSCON_DID1_VER_SHIFT) + +/* Device Capabilities 0 (DC0), offset 0x008 */ + +#define SYSCON_DC0_FLASHSZ_SHIFT 0 /* Bits 15-0: FLASH Size */ +#define SYSCON_DC0_FLASHSZ_MASK (0xffff << SYSCON_DC0_FLASHSZ_SHIFT) +#define SYSCON_DC0_SRAMSZ_SHIFT 16 /* Bits 31-16: SRAM Size */ +#define SYSCON_DC0_SRAMSZ_MASK (0xffff << SYSCON_DC0_SRAMSZ_SHIFT) + +/* Device Capabilities 1 (DC1), offset 0x010 */ + +#define SYSCON_DC1_JTAG (1 << 0) /* Bit 0: JTAG Present */ +#define SYSCON_DC1_SWD (1 << 1) /* Bit 1: SWD Present */ +#define SYSCON_DC1_SWO (1 << 2) /* Bit 2: SWO Trace Port Present */ +#define SYSCON_DC1_WDT (1 << 3) /* Bit 3: Watchdog Timer Present */ +#define SYSCON_DC1_PLL (1 << 4) /* Bit 4: PLL Present */ +#define SYSCON_DC1_TEMPSNS (1 << 5) /* Bit 5: Temp Sensor Present */ +#define SYSCON_DC1_HIB (1 << 6) /* Bit 6: Hibernation Module Present */ +#define SYSCON_DC1_MPU (1 << 7) /* Bit 7: MPU Present */ +#define SYSCON_DC1_MAXADCSPD_SHIFT 8 /* Bits 9-8: Max ADC Speed */ +#define SYSCON_DC1_MAXADCSPD_MASK (0x03 << SYSCON_DC1_MAXADCSPD_SHIFT) +#define SYSCON_DC1_ADC (1 << 16) /* Bit 16: ADC Module Present */ +#define SYSCON_DC1_MINSYSDIV_SHIFT 12 /* Bits 15-12: System Clock Divider Minimum */ +#define SYSCON_DC1_MINSYSDIV_MASK (0x0f << SYSCON_DC1_MINSYSDIV_SHIFT) + +/* Device Capabilities 2 (DC2), offset 0x014 */ + +#define SYSCON_DC2_UART0 (1 << 0) /* Bit 0: UART0 Present */ +#define SYSCON_DC2_UART1 (1 << 1) /* Bit 1: UART1 Present */ +#define SYSCON_DC2_SSI0 (1 << 4) /* Bit 4: SSI0 Present */ +#define SYSCON_DC2_SSI1 (1 << 5) /* Bit 5: SSI1 Present */ +#define SYSCON_DC2_I2C0 (1 << 12) /* Bit 12: I2C Module 0 Present */ +#define SYSCON_DC2_I2C1 (1 << 14) /* Bit 14: I2C Module 1 Present */ +#define SYSCON_DC2_TIMER0 (1 << 16) /* Bit 16: Timer 0 Present */ +#define SYSCON_DC2_TIMER1 (1 << 17) /* Bit 17: Timer 1 Present */ +#define SYSCON_DC2_TIMER2 (1 << 18) /* Bit 18: Timer 2 Present */ +#define SYSCON_DC2_TIMER3 (1 << 19) /* Bit 19: Timer 3 Present */ +#define SYSCON_DC2_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Present */ +#define SYSCON_DC2_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Present */ + +/* Device Capabilities 3 (DC3), offset 0x018 */ + +#define SYSCON_DC3_C0MINUS (1 << 6) /* Bit 6: C0- Pin Present */ +#define SYSCON_DC3_C0PLUS (1 << 7) /* Bit 7: C0+ Pin Present */ +#define SYSCON_DC3_C0O (1 << 8) /* Bit 8: C0o Pin Present */ +#define SYSCON_DC3_C1MINUS (1 << 9) /* Bit 9: C1- Pin Present */ +#define SYSCON_DC3_C1PLUS (1 << 10) /* Bit 10: C1+ Pin Present */ +#define SYSCON_DC3_ADC0 (1 << 16) /* Bit 16: ADC0 Pin Present */ +#define SYSCON_DC3_ADC1 (1 << 17) /* Bit 17: ADC1 Pin Present */ +#define SYSCON_DC3_ADC2 (1 << 18) /* Bit 18: ADC2 Pin Present */ +#define SYSCON_DC3_ADC3 (1 << 19) /* Bit 19: ADC3 Pin Present */ +#define SYSCON_DC3_ADC4 (1 << 20) /* Bit 20: ADC4 Pin Present */ +#define SYSCON_DC3_ADC5 (1 << 21) /* Bit 21: ADC5 Pin Present */ +#define SYSCON_DC3_ADC6 (1 << 22) /* Bit 22: ADC6 Pin Present */ +#define SYSCON_DC3_ADC7 (1 << 23) /* Bit 23: ADC7 Pin Present */ +#define SYSCON_DC3_CCP0 (1 << 24) /* Bit 24: CCP0 Pin Present */ +#define SYSCON_DC3_CCP1 (1 << 25) /* Bit 25: CCP1 Pin Present */ +#define SYSCON_DC3_CCP2 (1 << 26) /* Bit 26: CCP2 Pin Present */ +#define SYSCON_DC3_CCP3 (1 << 27) /* Bit 27: CCP3 Pin Present */ +#define SYSCON_DC3_CCP4 (1 << 28) /* Bit 28: CCP4 Pin Present */ +#define SYSCON_DC3_CCP5 (1 << 29) /* Bit 29: CCP5 Pin Present */ +#define SYSCON_DC3_32KHZ (1 << 31) /* Bit 31: 32KHz Input Clock Available */ + +/* Device Capabilities 4 (DC4), offset 0x01c */ + +#define SYSCON_DC4_GPIO(n) (1 << (n)) +#define SYSCON_DC4_GPIOA (1 << 0) /* Bit 0: GPIO Port A Present */ +#define SYSCON_DC4_GPIOB (1 << 1) /* Bit 1: GPIO Port B Present */ +#define SYSCON_DC4_GPIOC (1 << 2) /* Bit 2: GPIO Port C Present */ +#define SYSCON_DC4_GPIOD (1 << 3) /* Bit 3: GPIO Port D Present */ +#define SYSCON_DC4_GPIOE (1 << 4) /* Bit 4: GPIO Port E Present */ +#define SYSCON_DC4_GPIOF (1 << 5) /* Bit 5: GPIO Port F Present */ +#define SYSCON_DC4_GPIOG (1 << 6) /* Bit 6: GPIO Port G Present */ +#define SYSCON_DC4_GPIOH (1 << 7) /* Bit 7: GPIO Port H Present */ +#define SYSCON_DC4_EMAC0 (1 << 28) /* Bit 28: Ethernet MAC0 Present */ +#define SYSCON_DC4_EPHY0 (1 << 30) /* Bit 30: Ethernet PHY0 Present */ + +/* Brown-Out Reset Control (PBORCTL), offset 0x030 */ + +#define SYSCON_PBORCTL_BORIOR (1 << 1) /* Bit 1: BOR Interrupt or Reset */ + +/* LDO Power Control (LDOPCTL), offset 0x034 */ + +#define SYSCON_LDOPCTL_VADJ_SHIFT 0 /* Bits 5-0: LDO Output Voltage */ +#define SYSCON_LDOPCTL_VADJ_MASK (0x3f << SYSCON_LDOPCTL_VADJ_SHIFT) +# define SYSCON_LPDOPCTL_2500MV (0x00 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.5V (reset)*/ +# define SYSCON_LPDOPCTL_2450MV (0x01 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.45V */ +# define SYSCON_LPDOPCTL_2400MV (0x02 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.4V */ +# define SYSCON_LPDOPCTL_2350MV (0x03 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.35V */ +# define SYSCON_LPDOPCTL_2300MV (0x04 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.3V */ +# define SYSCON_LPDOPCTL_2250MV (0x05 << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.25V */ +# define SYSCON_LPDOPCTL_2750MV (0x1b << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.75V */ +# define SYSCON_LPDOPCTL_2700MV (0x1c << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.7V */ +# define SYSCON_LPDOPCTL_2650MV (0x1d << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.65V */ +# define SYSCON_LPDOPCTL_2600MV (0x1e << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.6V */ +# define SYSCON_LPDOPCTL_2550MV (0x1f << SYSCON_LDOPCTL_VADJ_SHIFT) /* 2.55V */ + +/* Software Reset Control 0 (SRCR0), offset 0x040 */ + +#define SYSCON_SRCR0_WDT (1 << 3) /* Bit 3: WDT Reset Control */ +#define SYSCON_SRCR0_HIB (1 << 6) /* Bit 6: HIB Reset Control */ +#define SYSCON_SRCR0_ADC (1 << 16) /* Bit 16: ADC0 Reset Control */ + +/* Software Reset Control 1 (SRCR1), offset 0x044 */ + +#define SYSCON_SRCR1_UART0 (1 << 0) /* Bit 0: UART0 Reset Control */ +#define SYSCON_SRCR1_UART1 (1 << 1) /* Bit 1: UART1 Reset Control */ +#define SYSCON_SRCR1_SSI0 (1 << 4) /* Bit 4: SSI0 Reset Control1 */ +#define SYSCON_SRCR1_SSI1 (1 << 5) /* Bit 5: SSI1 Reset Control */ +#define SYSCON_SRCR1_I2C0 (1 << 12) /* Bit 12: I2C0 Reset Control */ +#define SYSCON_SRCR1_I2C1 (1 << 14) /* Bit 14: I2C1 Reset Control */ +#define SYSCON_SRCR1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Reset Control */ +#define SYSCON_SRCR1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Reset Control */ +#define SYSCON_SRCR1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Reset Control */ +#define SYSCON_SRCR1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Reset Control */ +#define SYSCON_SRCR1_COMP0 (1 << 24) /* Bit 24: Analog Comp 0 Reset Control */ +#define SYSCON_SRCR1_COMP1 (1 << 25) /* Bit 25: Analog Comp 1 Reset Control */ + +/* Software Reset Control 2 (SRCR2), offset 0x048 */ + +#define SYSCON_SRCR2_GPIO(n) (1 << (n)) +#define SYSCON_SRCR2_GPIOA (1 << 0) /* Bit 0: Port A Reset Control */ +#define SYSCON_SRCR2_GPIOB (1 << 1) /* Bit 1: Port B Reset Control */ +#define SYSCON_SRCR2_GPIOC (1 << 2) /* Bit 2: Port C Reset Control */ +#define SYSCON_SRCR2_GPIOD (1 << 3) /* Bit 3: Port D Reset Control */ +#define SYSCON_SRCR2_GPIOE (1 << 4) /* Bit 4: Port E Reset Control */ +#define SYSCON_SRCR2_GPIOF (1 << 5) /* Bit 5: Port F Reset Control */ +#define SYSCON_SRCR2_GPIOG (1 << 6) /* Bit 6: Port G Reset Control */ +#define SYSCON_SRCR2_GPIOH (1 << 7) /* Bit 7: Port H Reset Control */ +#define SYSCON_SRCR2_EMAC0 (1 << 28) /* Bit 28: MAC0 Reset Control */ +#define SYSCON_SRCR2_EPHY0 (1 << 30) /* Bit 30: PHY0 Reset Control */ + +/* Raw Interrupt Status (RIS), offset 0x050 */ + +#define SYSCON_RIS_BORRIS (1 << 1) /* Bit 1: Brown-Out Reset Raw Interrupt Status */ +#define SYSCON_RIS_PLLLRIS (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Status */ + +/* Interrupt Mask Control (IMC), offset 0x054 */ + +#define SYSCON_IMC_BORIM (1 << 1) /* Bit 1: Brown-Out Reset Interrupt Mask */ +#define SYSCON_IMC_PLLLIM (1 << 6) /* Bit 6: PLL Lock Interrupt Mask */ + +/* Masked Interrupt Status and Clear (MISC), offset 0x058 */ + +#define SYSCON_MISC_BORMIS (1 << 1) /* Bit 1: BOR Masked Interrupt Status */ +#define SYSCON_MISC_PLLLMIS (1 << 6) /* Bit 6: PLL Lock Masked Interrupt Status */ + +/* Reset Cause (RESC), offset 0x05C */ + +#define SYSCON_RESC_EXT (1 << 0) /* Bit 0: External Reset */ +#define SYSCON_RESC_POR (1 << 1) /* Bit 1: Power-On Reset */ +#define SYSCON_RESC_BOR (1 << 2) /* Bit 2: Brown-Out Reset */ +#define SYSCON_RESC_WDT (1 << 3) /* Bit 3: Watchdog Timer Reset */ +#define SYSCON_RESC_SW (1 << 4) /* Bit 4: Software Reset */ + +/* Run-Mode Clock Configuration (RCC), offset 0x060 */ + +#define SYSCON_RCC_MOSCDIS (1 << 0) /* Bit 0: Main Oscillator Disable */ +#define SYSCON_RCC_IOSCDIS (1 << 1) /* Bit 1: Internal Oscillator Disable */ +#define SYSCON_RCC_OSCSRC_SHIFT 4 /* Bits 5-4: Oscillator Source */ +#define SYSCON_RCC_OSCSRC_MASK (0x03 << SYSCON_RCC_OSCSRC_SHIFT) +# define SYSCON_RCC_OSCSRC_MOSC (0 << SYSCON_RCC_OSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_RCC_OSCSRC_PIOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Internal oscillator (reset) */ +# define SYSCON_RCC_OSCSRC_PIOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Internal oscillator / 4 */ +# define SYSCON_RCC_OSCSRC_LFIOSC (3 << SYSCON_RCC_OSCSRC_SHIFT) /* 30KHz internal oscillator */ +#define SYSCON_RCC_XTAL_SHIFT 6 /* Bits 10-6: Crystal Value */ +#define SYSCON_RCC_XTAL_MASK (0x1f << SYSCON_RCC_XTAL_SHIFT) +# define SYSCON_RCC_XTAL1000KHZ ( 0 << SYSCON_RCC_XTAL_SHIFT) /* 1.0000MHz (NO PLL) */ +# define SYSCON_RCC_XTAL1843KHZ ( 1 << SYSCON_RCC_XTAL_SHIFT) /* 1.8432MHz (NO PLL) */ +# define SYSCON_RCC_XTAL2000KHZ ( 2 << SYSCON_RCC_XTAL_SHIFT) /* 2.0000MHz (NO PLL) */ +# define SYSCON_RCC_XTAL2580KHZ ( 3 << SYSCON_RCC_XTAL_SHIFT) /* 2.4576MHz (NO PLL) */ +# define SYSCON_RCC_XTAL3580KHZ ( 4 << SYSCON_RCC_XTAL_SHIFT) /* 3.5795MHz */ +# define SYSCON_RCC_XTAL3686KHZ ( 5 << SYSCON_RCC_XTAL_SHIFT) /* 3.6864MHz */ +# define SYSCON_RCC_XTAL4000KHZ ( 6 << SYSCON_RCC_XTAL_SHIFT) /* 4.0000MHz */ +# define SYSCON_RCC_XTAL4096KHZ ( 7 << SYSCON_RCC_XTAL_SHIFT) /* 4.0960MHz */ +# define SYSCON_RCC_XTAL4915KHZ ( 8 << SYSCON_RCC_XTAL_SHIFT) /* 4.9152MHz */ +# define SYSCON_RCC_XTAL5000KHZ ( 9 << SYSCON_RCC_XTAL_SHIFT) /* 5.0000MHz */ +# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.1200MHz */ +# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6.0000MHz (reset value) */ +# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.1440MHz */ +# define SYSCON_RCC_XTAL7373KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728MHz */ +# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8.0000MHz */ +# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.1920MHz */ +#ifdef CONFIG_ARCH_CHIP_LM3S9B96 +# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12888KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */ +# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */ +# define SYSCON_RCC_XTAL14318KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */ +# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */ +# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */ +#endif +#define SYSCON_RCC_BYPASS (1 << 11) /* Bit 11: PLL Bypass */ +#define SYSCON_RCC_PWRDN (1 << 13) /* Bit 13: PLL Power Down */ +#define SYSCON_RCC_USESYSDIV (1 << 22) /* Bit 22: Enable System Clock Divider */ +#define SYSCON_RCC_SYSDIV_SHIFT 23 /* Bits 26-23: System Clock Divisor */ +#define SYSCON_RCC_SYSDIV_MASK (0x0f << SYSCON_RCC_SYSDIV_SHIFT) +# define SYSCON_RCC_SYSDIV(n) (((n)-1) << SYSCON_RCC_SYSDIV_SHIFT) +#define SYSCON_RCC_ACG (1 << 27) /* Bit 27: Auto Clock Gating */ + +/* XTAL to PLL Translation (PLLCFG), offset 0x064 */ + +#define SYSCON_PLLCFG_F_SHIFT 5 /* Bits 13-5: PLL F Value */ +#define SYSCON_PLLCFG_F_MASK (0x1ff << SYSCON_PLLCFG_F_SHIFT) +#define SYSCON_PLLCFG_R_SHIFT 0 /* Bits 4-0: PLL R Value */ +#define SYSCON_PLLCFG_R_MASK (0x1f << SYSCON_PLLCFG_R_SHIFT) + +/* Run-Mode Clock Configuration 2 (RCC2), offset 0x070 */ + +#define SYSCON_RCC2_OSCSRC2_SHIFT 4 /* Bits 6-4: Oscillator Source */ +#define SYSCON_RCC2_OSCSRC2_MASK (0x07 << SYSCON_RCC2_OSCSRC2_SHIFT) +# define SYSCON_RCC2_OSCSRC2_MOSC (0 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Main oscillator */ +# define SYSCON_RCC2_OSCSRC2_PIOSC (1 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Internal oscillator (reset) */ +# define SYSCON_RCC2_OSCSRC2_PIOSC4 (2 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Internal oscillator / 4 */ +# define SYSCON_RCC2_OSCSRC2_LFIOSC (3 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 30KHz internal oscillator */ +# define SYSCON_RCC2_OSCSRC2_32768HZ (7 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_RCC2_BYPASS2 (1 << 11) /* Bit 11: Bypass PLL */ +#define SYSCON_RCC2_PWRDN2 (1 << 13) /* Bit 13: Power-Down PLL */ +#define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */ +#define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT) +#define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */ + +/* Run Mode Clock Gating Control Register 0 (RCGC0), offset 0x100 */ + +#define SYSCON_RCGC0_WDT (1 << 3) /* Bit 3: WDT Clock Gating Control */ +#define SYSCON_RCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_RCGC0_MAXADCSPD_SHIFT 8 /* Bits 9-8: ADC Sample Speed */ +#define SYSCON_RCGC0_MAXADCSPD_MASK (0x03 << SYSCON_RCGC0_MAXADCSPD_SHIFT) +#define SYSCON_RCGC0_ADC (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ + +/* Run Mode Clock Gating Control Register 1 (RCGC1), offset 0x104 */ + +#define SYSCON_RCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_RCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_RCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_RCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_RCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_RCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_RCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_RCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Run Mode Clock Gating Control Register 2 (RCGC2), offset 0x108 */ + +#define SYSCON_RCGC2_GPIO(n) (1 << (n)) +#define SYSCON_RCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_RCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_RCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_RCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_RCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_RCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_RCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_RCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_RCGC2_EMAC0 (1 << 28) /* Bit 28: MAC0 Clock Gating Control */ +#define SYSCON_RCGC2_EPHY0 (1 << 30) /* Bit 30: PHY0 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 0 (SCGC0), offset 0x110 */ + +#define SYSCON_SCGC0_WDT (1 << 3) /* Bit 3: WDT Clock Gating Control */ +#define SYSCON_SCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_SCGC0_MAXADCSPD_SHIFT 8 /* Bits 9-8: ADC Sample Speed */ +#define SYSCON_SCGC0_MAXADCSPD_MASK (0x03 << SYSCON_SCGC0_MAXADCSPD_SHIFT) +#define SYSCON_SCGC0_ADC (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 1 (SCGC1), offset 0x114 */ + +#define SYSCON_SCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_SCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_SCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_SCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_SCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_SCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_SCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_SCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Sleep Mode Clock Gating Control Register 2 (SCGC2), offset 0x118 */ + +#define SYSCON_SCGC2_GPIO(n) (1 << (n)) +#define SYSCON_SCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_SCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_SCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_SCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_SCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_SCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_SCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_SCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_SCGC2_EMAC0 (1 << 28) /* Bit 28: MAC0 Clock Gating Control */ +#define SYSCON_SCGC2_EPHY0 (1 << 30) /* Bit 30: PHY0 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 0 (DCGC0), offset 0x120 */ + +#define SYSCON_DCGC0_WDT (1 << 3) /* Bit 3: WDT Clock Gating Control */ +#define SYSCON_DCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_DCGC0_MAXADCSPD_SHIFT 8 /* Bits 9-8: ADC Sample Speed */ +#define SYSCON_DCGC0_MAXADCSPD_MASK (0x03 << SYSCON_DCGC0_MAXADCSPD_SHIFT) +#define SYSCON_DCGC0_ADC (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 1 (DCGC1), offset 0x124 */ + +#define SYSCON_DCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_DCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_DCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_DCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_DCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_DCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_DCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_DCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Deep Sleep Mode Clock Gating Control Register 2 (DCGC2), offset 0x128 */ + +#define SYSCON_DCGC2_GPIO(n) (1 << (n)) +#define SYSCON_DCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_DCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_DCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_DCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_DCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_DCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_DCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_DCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_DCGC2_EMAC0 (1 << 28) /* Bit 28: MAC0 Clock Gating Control */ +#define SYSCON_DCGC2_EPHY0 (1 << 30) /* Bit 30: PHY0 Clock Gating Control */ + +/* Deep Sleep Clock Configuration (DSLPCLKCFG), offset 0x144 */ + +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT 23 /* Bits 28-23: Divider Field Override */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_MASK (0x3f << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) +#define SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT 4 /* Bits 6-4: Clock Source */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_MASK (0x07 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM3S_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/lm3s_vectors.h b/arch/arm/src/tiva/chip/lm3s_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..8b8c26cc361338dd080a1d403a6a6043c986cf81 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm3s_vectors.h @@ -0,0 +1,439 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm3s_vectors.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Vectors + ************************************************************************************/ + +/* This file is included by tiva_vectors.S. It provides the macro VECTOR that + * supplies ach Stellaris vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/tiva/lm3s_irq.h. + * tiva_vectors.S will define the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +#if defined(CONFIG_ARCH_CHIP_LM3S6918) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 71 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 71 + +#else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +UNUSED(TIVA_RESERVED_25) /* Vector 25: Reserved */ +UNUSED(TIVA_RESERVED_26) /* Vector 26: Reserved */ +UNUSED(TIVA_RESERVED_27) /* Vector 27: Reserved */ +UNUSED(TIVA_RESERVED_28) /* Vector 28: Reserved */ +UNUSED(TIVA_RESERVED_29) /* Vector 29: Reserved */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timer */ +VECTOR(tiva_tmr0a, TIVA_IRQ_TIMER0A) /* Vector 35: Timer 0 A */ +VECTOR(tiva_tmr0b, TIVA_IRQ_TIMER0B) /* Vector 36: Timer 0 B */ +VECTOR(tiva_tmr1a, TIVA_IRQ_TIMER1A) /* Vector 37: Timer 1 A */ +VECTOR(tiva_tmr1b, TIVA_IRQ_TIMER1B) /* Vector 38: Timer 1 B */ +VECTOR(tiva_tmr2a, TIVA_IRQ_TIMER2A) /* Vector 39: Timer 2 A */ + +VECTOR(tiva_tmr2b, TIVA_IRQ_TIMER2B) /* Vector 40: Timer 3 B */ +VECTOR(tiva_cmp0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_cmp1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +VECTOR(tiva_gpioh, TIVA_IRQ_GPIOH) /* Vector 48: GPIO Port H */ +UNUSED(TIVA_RESERVED_49) /* Vector 49: Reserved */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_tmr3a, TIVA_IRQ_TIMER3A) /* Vector 51: Timer 3 A */ +VECTOR(tiva_tmr3b, TIVA_IRQ_TIMER3B) /* Vector 52: Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +UNUSED(TIVA_RESERVED_54) /* Vector 54: Reserved */ +UNUSED(TIVA_RESERVED_55) /* Vector 55: Reserved */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +VECTOR(tiva_eth, TIVA_IRQ_ETHCON) /* Vector 58: Ethernet Controller */ +VECTOR(tiva_hib, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +UNUSED(TIVA_RESERVED_60) /* Vector 60: Reserved */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +UNUSED(TIVA_RESERVED_62) /* Vector 62: Reserved */ +UNUSED(TIVA_RESERVED_63) /* Vector 63: Reserved */ +UNUSED(TIVA_RESERVED_64) /* Vector 64: Reserved */ +UNUSED(TIVA_RESERVED_65) /* Vector 65: Reserved */ +UNUSED(TIVA_RESERVED_66) /* Vector 66: Reserved */ +UNUSED(TIVA_RESERVED_67) /* Vector 67: Reserved */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +#endif + +#elif defined(CONFIG_ARCH_CHIP_LM3S6432) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 71 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 71 + +#else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +UNUSED(TIVA_RESERVED_25) /* Vector 25: Reserved */ +VECTOR(tiva_pwm0, TIVA_IRQ_PWM0) /* Vector 26: PWM Generator 0 */ +UNUSED(TIVA_RESERVED_27) /* Vector 27: Reserved */ +UNUSED(TIVA_RESERVED_28) /* Vector 28: Reserved */ +UNUSED(TIVA_RESERVED_29) /* Vector 29: Reserved */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timer */ +VECTOR(tiva_tmr0a, TIVA_IRQ_TIMER0A) /* Vector 35: Timer 0 A */ +VECTOR(tiva_tmr0b, TIVA_IRQ_TIMER0B) /* Vector 36: Timer 0 B */ +VECTOR(tiva_tmr1a, TIVA_IRQ_TIMER1A) /* Vector 37: Timer 1 A */ +VECTOR(tiva_tmr1b, TIVA_IRQ_TIMER1B) /* Vector 38: Timer 1 B */ +VECTOR(tiva_tmr2a, TIVA_IRQ_TIMER2A) /* Vector 39: Timer 2 A */ + +VECTOR(tiva_tmr2b, TIVA_IRQ_TIMER2B) /* Vector 40: Timer 3 B */ +VECTOR(tiva_cmp0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_cmp1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: Reserved */ +UNUSED(TIVA_RESERVED_49) /* Vector 49: Reserved */ + +UNUSED(TIVA_RESERVED_50) /* Vector 50: Reserved */ +UNUSED(TIVA_RESERVED_51) /* Vector 51: Reserved */ +UNUSED(TIVA_RESERVED_52) /* Vector 52: Reserved */ +UNUSED(TIVA_RESERVED_53) /* Vector 53: Reserved */ +UNUSED(TIVA_RESERVED_54) /* Vector 54: Reserved */ +UNUSED(TIVA_RESERVED_55) /* Vector 55: Reserved */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +VECTOR(tiva_eth, TIVA_IRQ_ETHCON) /* Vector 58: Ethernet Controller */ +UNUSED(TIVA_RESERVED_59) /* Vector 59: Reserved */ + +UNUSED(TIVA_RESERVED_60) /* Vector 60: Reserved */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +UNUSED(TIVA_RESERVED_62) /* Vector 62: Reserved */ +UNUSED(TIVA_RESERVED_63) /* Vector 63: Reserved */ +UNUSED(TIVA_RESERVED_64) /* Vector 64: Reserved */ +UNUSED(TIVA_RESERVED_65) /* Vector 65: Reserved */ +UNUSED(TIVA_RESERVED_66) /* Vector 66: Reserved */ +UNUSED(TIVA_RESERVED_67) /* Vector 67: Reserved */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +#endif + +#elif defined(CONFIG_ARCH_CHIP_LM3S6965) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 71 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 71 + +#else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwmfault, TIVA_IRQ_PWMFAULT) /* Vector 25: PWM Fault */ +VECTOR(tiva_pwm0, TIVA_IRQ_PWM0) /* Vector 26: PWM Generator 0 */ +VECTOR(tiva_pwm1, TIVA_IRQ_PWM1) /* Vector 27: PWM Generator 1 */ +VECTOR(tiva_pwm2, TIVA_IRQ_PWM2) /* Vector 28: PWM Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI 0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timer */ +VECTOR(tiva_tmr0a, TIVA_IRQ_TIMER0A) /* Vector 35: Timer 0 A */ +VECTOR(tiva_tmr0b, TIVA_IRQ_TIMER0B) /* Vector 36: Timer 0 B */ +VECTOR(tiva_tmr1a, TIVA_IRQ_TIMER1A) /* Vector 37: Timer 1 A */ +VECTOR(tiva_tmr1b, TIVA_IRQ_TIMER1B) /* Vector 38: Timer 1 B */ +VECTOR(tiva_tmr2a, TIVA_IRQ_TIMER2A) /* Vector 39: Timer 2 A */ + +VECTOR(tiva_tmr2b, TIVA_IRQ_TIMER2B) /* Vector 40: Timer 3 B */ +VECTOR(tiva_cmp0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_cmp1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: Reserved */ +VECTOR(tiva_uart2, TIVA_IRQ_UART1) /* Vector 49: UART 1 */ + +UNUSED(TIVA_RESERVED_50) /* Vector 50: Reserved */ +VECTOR(tiva_tmr3a, TIVA_IRQ_TIMER3A) /* Vector 51: Timer 3 A */ +VECTOR(tiva_tmr3b, TIVA_IRQ_TIMER3B) /* Vector 52: Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_qei1, TIVA_IRQ_QEI1) /* Vector 54: QEI 1 */ +UNUSED(TIVA_RESERVED_55) /* Vector 55: Reserved */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +VECTOR(tiva_eth, TIVA_IRQ_ETHCON) /* Vector 58: Ethernet Controller */ +VECTOR(tiva_hib, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +UNUSED(TIVA_RESERVED_60) /* Vector 60: Reserved */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +UNUSED(TIVA_RESERVED_62) /* Vector 62: Reserved */ +UNUSED(TIVA_RESERVED_63) /* Vector 63: Reserved */ +UNUSED(TIVA_RESERVED_64) /* Vector 64: Reserved */ +UNUSED(TIVA_RESERVED_65) /* Vector 65: Reserved */ +UNUSED(TIVA_RESERVED_66) /* Vector 66: Reserved */ +UNUSED(TIVA_RESERVED_67) /* Vector 67: Reserved */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +#endif + +#elif defined(CONFIG_ARCH_CHIP_LM3S8962) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 71 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 71 + +#else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwmfault, TIVA_IRQ_PWMFAULT) /* Vector 25: PWM Fault */ +VECTOR(tiva_pwm0, TIVA_IRQ_PWM0) /* Vector 26: PWM Generator 0 */ +VECTOR(tiva_pwm1, TIVA_IRQ_PWM1) /* Vector 27: PWM Generator 1 */ +VECTOR(tiva_pwm2, TIVA_IRQ_PWM2) /* Vector 28: PWM Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI 0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timer */ +VECTOR(tiva_tmr0a, TIVA_IRQ_TIMER0A) /* Vector 35: Timer 0 A */ +VECTOR(tiva_tmr0b, TIVA_IRQ_TIMER0B) /* Vector 36: Timer 0 B */ +VECTOR(tiva_tmr1a, TIVA_IRQ_TIMER1A) /* Vector 37: Timer 1 A */ +VECTOR(tiva_tmr1b, TIVA_IRQ_TIMER1B) /* Vector 38: Timer 1 B */ +VECTOR(tiva_tmr2a, TIVA_IRQ_TIMER2A) /* Vector 39: Timer 2 A */ + +VECTOR(tiva_tmr2b, TIVA_IRQ_TIMER2B) /* Vector 40: Timer 3 B */ +VECTOR(tiva_cmp0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +UNUSED(TIVA_RESERVED_42) /* Vector 42: Reserved */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: Reserved */ +UNUSED(TIVA_RESERVED_49) /* Vector 49: Reserved */ + +UNUSED(TIVA_RESERVED_50) /* Vector 50: Reserved */ +VECTOR(tiva_tmr3a, TIVA_IRQ_TIMER3A) /* Vector 51: Timer 3 A */ +VECTOR(tiva_tmr3b, TIVA_IRQ_TIMER3B) /* Vector 52: Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_qei1, TIVA_IRQ_QEI1) /* Vector 54: QEI 1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 55: CAN 0 */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +VECTOR(tiva_eth, TIVA_IRQ_ETHCON) /* Vector 58: Ethernet Controller */ +VECTOR(tiva_hib, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +UNUSED(TIVA_RESERVED_60) /* Vector 60: Reserved */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +UNUSED(TIVA_RESERVED_62) /* Vector 62: Reserved */ +UNUSED(TIVA_RESERVED_63) /* Vector 63: Reserved */ +UNUSED(TIVA_RESERVED_64) /* Vector 64: Reserved */ +UNUSED(TIVA_RESERVED_65) /* Vector 65: Reserved */ +UNUSED(TIVA_RESERVED_66) /* Vector 66: Reserved */ +UNUSED(TIVA_RESERVED_67) /* Vector 67: Reserved */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +#endif + +#elif defined(CONFIG_ARCH_CHIP_LM3S9B96) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +#ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 72 interrupt table entries for I/O interrupts. */ + +# define ARMV7M_PERIPHERAL_INTERRUPTS 72 + +#else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ + +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwmfault, TIVA_IRQ_PWMFAULT) /* Vector 25: PWM Fault */ +VECTOR(tiva_pwm0, TIVA_IRQ_PWM0) /* Vector 26: PWM Generator 0 */ +VECTOR(tiva_pwm1, TIVA_IRQ_PWM1) /* Vector 27: PWM Generator 1 */ +VECTOR(tiva_pwm2, TIVA_IRQ_PWM2) /* Vector 28: PWM Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI 0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timer */ +VECTOR(tiva_tmr0a, TIVA_IRQ_TIMER0A) /* Vector 35: Timer 0 A */ +VECTOR(tiva_tmr0b, TIVA_IRQ_TIMER0B) /* Vector 36: Timer 0 B */ +VECTOR(tiva_tmr1a, TIVA_IRQ_TIMER1A) /* Vector 37: Timer 1 A */ +VECTOR(tiva_tmr1b, TIVA_IRQ_TIMER1B) /* Vector 38: Timer 1 B */ +VECTOR(tiva_tmr2a, TIVA_IRQ_TIMER2A) /* Vector 39: Timer 2 A */ + +VECTOR(tiva_tmr2b, TIVA_IRQ_TIMER2B) /* Vector 40: Timer 3 B */ +VECTOR(tiva_cmp0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_cmp1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +VECTOR(tiva_cmp2, TIVA_IRQ_COMPARE2) /* Vector 43: Analog Comparator 2 */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +VECTOR(tiva_gpioh, TIVA_IRQ_GPIOH) /* Vector 48: GPIO Port H */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 49: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: GPIO Port H */ +VECTOR(tiva_tmr3a, TIVA_IRQ_TIMER3A) /* Vector 51: Timer 3 A */ +VECTOR(tiva_tmr3b, TIVA_IRQ_TIMER3B) /* Vector 52: Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_qei1, TIVA_IRQ_QEI1) /* Vector 54: QEI 1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 55: CAN 0 */ +VECTOR(tiva_can1, TIVA_IRQ_CAN1) /* Vector 56: CAN 1 */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +VECTOR(tiva_eth, TIVA_IRQ_ETHCON) /* Vector 58: Ethernet Controller */ +UNUSED(TIVA_RESERVED_59) /* Vector 59: Reserved */ + +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 60: USB */ +VECTOR(tiva_pwm3, TIVA_IRQ_PWM3) /* Vector 61: PWM 3 */ +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 62: uDMA Software */ +VECTOR(tiva_udmaerror, TIVA_IRQ_UDMAERROR) /* Vector 63: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 64: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 65: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 66: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 67: ADC1 Sequence 3 */ +VECTOR(tiva_i2s0, TIVA_IRQ_I2S0) /* Vector 68: I2S 0 */ +VECTOR(tiva_epi, TIVA_IRQ_EPI) /* Vector 69: EPI */ + +VECTOR(tiva_gpioj, TIVA_IRQ_GPIOJ) /* Vector 70: GPIO Port J */ +UNUSED(TIVA_RESERVED_71) /* Vector 71: Reserved */ +#endif + +#else +# error "Vectors not specified for this Stellaris chip" +#endif diff --git a/arch/arm/src/tiva/chip/lm4f_memorymap.h b/arch/arm/src/tiva/chip/lm4f_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..4ec56359cfe609c5eba9c2061b63cba39cbf2eeb --- /dev/null +++ b/arch/arm/src/tiva/chip/lm4f_memorymap.h @@ -0,0 +1,163 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm4f_memorymap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Jose Pablo Carballo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM4F_MEMORYMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM4F_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory map ***********************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LM4F120) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */ + /* -0x00ffffff: Reserved */ +# define TIVA_ROM_BASE 0x01000000 /* -0x1fffffff: Reserved for ROM */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x20007fff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x220fffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000- */ + /* -0xdfffffff: Reserved */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ +# define TIVA_ETM_BASE 0xe0041000 /* -0xe0041fff: Embedded Trace Macrocell */ + /* -0xffffffff: Reserved */ +#else +# error "Memory map not specified for this LM4F chip" +#endif + +/* Peripheral base addresses ********************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LM4F120) +/* FiRM Peripheral Base Addresses */ + +# define TIVA_WDOG0_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +/* Peripheral Base Addresses */ + +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ +# define TIVA_WTIMER0_BASE (TIVA_PERIPH_BASE + 0x36000) /* -0x36fff: 32/64 Wide Timer 0 */ +# define TIVA_WTIMER1_BASE (TIVA_PERIPH_BASE + 0x37000) /* -0x37fff: 32/64 Wide Timer 1 */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x43fff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller */ + /* -0x4bfff: Reserved */ +# define TIVA_WTIMER2_BASE (TIVA_PERIPH_BASE + 0x4c000) /* -0x4cfff: 32/64 Wide Timer 2 */ +# define TIVA_WTIMER3_BASE (TIVA_PERIPH_BASE + 0x4d000) /* -0x4dfff: 32/64 Wide Timer 3 */ +# define TIVA_WTIMER4_BASE (TIVA_PERIPH_BASE + 0x4e000) /* -0x4efff: 32/64 Wide Timer 4 */ +# define TIVA_WTIMER5_BASE (TIVA_PERIPH_BASE + 0x4f000) /* -0x4ffff: 32/64 Wide Timer 5 */ +# define TIVA_USB_BASE (TIVA_PERIPH_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ +#else +# error "Peripheral base addresses not specified for this Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM4F_MEMORYMAP_H */ diff --git a/arch/arm/src/tiva/chip/lm4f_pinmap.h b/arch/arm/src/tiva/chip/lm4f_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..ec8ad402a30fcc40e6e03de3da52e4d259f49381 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm4f_pinmap.h @@ -0,0 +1,215 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm4f_pinmap.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM4F_PINMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM4F_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alternate Pin Functions. All members of the LM4F family share the same pin + * multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +#if defined(CONFIG_ARCH_CHIP_LM4F120) + +# define GPIO_ADC_IN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_IN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_IN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_IN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_IN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_IN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_IN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_IN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_IN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_IN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_IN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_IN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) + +# define GPIO_CAN0_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CAN0_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_CAN0_RX_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_CAN0_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_CAN0_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_CAN0_TX_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_5) + +# define GPIO_CMP0_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_CMP0_OUT (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CMP0_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_CMP1_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_CMP1_OUT (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_CMP1_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_5) + +# define GPIO_CORE_TRCLK (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_CORE_TRD0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_CORE_TRD1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PADTYPE_ODWPU | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PADTYPE_ODWPU | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_I2C2_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_I2C2_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PADTYPE_ODWPU | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_I2C3_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_I2C3_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PADTYPE_ODWPU | GPIO_PORTD | GPIO_PIN_1) + +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TMS (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_SSI0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI1_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI1_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_SSI1_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI1_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_SSI1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI2_CLK (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_SSI2_FSS (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_SSI2_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_SSI2_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_SSI3_CLK (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI3_FSS (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI3_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI3_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_3) + +# define GPIO_SYSCON_NMI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_SYSCON_NMI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_0) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_TIM2_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM3_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM3_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_TIM4_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_TIM4_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_TIM5_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_TIM5_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_3) + +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART2_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_UART2_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_UART3_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_UART3_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_UART4_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART4_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART5_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_UART5_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_UART6_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_UART6_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_UART7_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_UART7_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_1) + +# define GPIO_USB0_DM (GPIO_FUNC_ANIO | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_USB0_DP (GPIO_FUNC_ANIO | GPIO_PORTD | GPIO_PIN_5) + +# define GPIO_WTIM0_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_WTIM0_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_WTIM1_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_WTIM1_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_WTIM2_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_WTIM2_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_WTIM3_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_WTIM3_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_WTIM4_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_WTIM4_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_WTIM5_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_WTIM5_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_7) + +#else +# error "Unknown Stellaris chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM4F_PINMAP_H */ diff --git a/arch/arm/src/tiva/chip/lm4f_syscontrol.h b/arch/arm/src/tiva/chip/lm4f_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..fe315a2c4451f2a31184700ea827b5966c82af69 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm4f_syscontrol.h @@ -0,0 +1,1532 @@ +/******************************************************************************************** + * arch/arm/src/tiva/chip/lm4f_syscontrol.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_LM4F_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_LM4F_SYSCONTROL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* System Control Register Offsets **********************************************************/ + +#define TIVA_SYSCON_DID0_OFFSET 0x000 /* Device Identification 0 */ +#define TIVA_SYSCON_DID1_OFFSET 0x004 /* Device Identification 1 */ +#define TIVA_SYSCON_PBORCTL_OFFSET 0x030 /* Brown-Out Reset Control */ +#define TIVA_SYSCON_RIS_OFFSET 0x050 /* Raw Interrupt Status */ +#define TIVA_SYSCON_IMC_OFFSET 0x054 /* Interrupt Mask Control */ +#define TIVA_SYSCON_MISC_OFFSET 0x058 /* Masked Interrupt Status and Clear */ +#define TIVA_SYSCON_RESC_OFFSET 0x05c /* Reset Cause */ +#define TIVA_SYSCON_RCC_OFFSET 0x060 /* Run-Mode Clock Configuration */ +#define TIVA_SYSCON_GPIOHBCTL_OFFSET 0x06c /* GPIO High-Performance Bus Control */ +#define TIVA_SYSCON_RCC2_OFFSET 0x070 /* Run-Mode Clock Configuration 2 */ +#define TIVA_SYSCON_MOSCCTL_OFFSET 0x07c /* Main Oscillator Control */ +#define TIVA_SYSCON_DSLPCLKCFG_OFFSET 0x144 /* Deep Sleep Clock Configuration */ +#define TIVA_SYSCON_SYSPROP_OFFSET 0x14c /* System Properties */ +#define TIVA_SYSCON_PIOSCCAL_OFFSET 0x150 /* Precision Internal Oscillator Calibration */ +#define TIVA_SYSCON_PIOSCSTAT_OFFSET 0x154 /* Precision Internal Oscillator Statistics */ +#define TIVA_SYSCON_PLLFREQ0_OFFSET 0x160 /* PLL 0 Frequency */ +#define TIVA_SYSCON_PLLFREQ1_OFFSET 0x164 /* PLL 1 Frequency */ +#define TIVA_SYSCON_PLLSTAT_OFFSET 0x168 /* PLL Status */ + +#define TIVA_SYSCON_PPWD_OFFSET 0x300 /* Watchdog Timer Peripheral Present */ +#define TIVA_SYSCON_PPTIMER_OFFSET 0x304 /* 16/32-Bit Timer Peripheral Present */ +#define TIVA_SYSCON_PPGPIO_OFFSET 0x308 /* GPIO Peripheral Present */ +#define TIVA_SYSCON_PPDMA_OFFSET 0x30c /* uDMA Peripheral Present */ +#define TIVA_SYSCON_PPHIB_OFFSET 0x314 /* Hibernation Peripheral Present */ +#define TIVA_SYSCON_PPUART_OFFSET 0x318 /* UART Present */ +#define TIVA_SYSCON_PPSSI_OFFSET 0x31c /* SSI Peripheral Present */ +#define TIVA_SYSCON_PPI2C_OFFSET 0x320 /* I2C Peripheral Present */ +#define TIVA_SYSCON_PPUSB_OFFSET 0x328 /* USB Peripheral Present */ +#define TIVA_SYSCON_PPCAN_OFFSET 0x334 /* CAN Peripheral Present */ +#define TIVA_SYSCON_PPADC_OFFSET 0x338 /* ADC Peripheral Present */ +#define TIVA_SYSCON_PPACMP_OFFSET 0x33c /* Analog Comparator Peripheral Present */ +#define TIVA_SYSCON_PPPWM_OFFSET 0x340 /* Pulse Width Modulator Peripheral Present */ +#define TIVA_SYSCON_PPQEI_OFFSET 0x344 /* Quadrature Encoder Peripheral Present */ +#define TIVA_SYSCON_PPEEPROM_OFFSET 0x358 /* EEPROM Peripheral Present */ +#define TIVA_SYSCON_PPWTIMER_OFFSET 0x35c /* 32/64-Bit Wide Timer Peripheral Present */ + +#define TIVA_SYSCON_SRWD_OFFSET 0x500 /* Watchdog Timer Software Reset */ +#define TIVA_SYSCON_SRTIMER_OFFSET 0x504 /* 16/32-Bit Timer Software Reset */ +#define TIVA_SYSCON_SRGPIO_OFFSET 0x508 /* GPIO Software Reset */ +#define TIVA_SYSCON_SRDMA_OFFSET 0x50c /* uDMA Software Reset */ +#define TIVA_SYSCON_SRHIB_OFFSET 0x514 /* Hibernation Software Reset */ +#define TIVA_SYSCON_SRUART_OFFSET 0x518 /* UART Software Reset*/ +#define TIVA_SYSCON_SRSSI_OFFSET 0x51c /* SSI Software Reset */ +#define TIVA_SYSCON_SRI2C_OFFSET 0x520 /* I2C Software Reset */ +#define TIVA_SYSCON_SRUSB_OFFSET 0x528 /* USB Software Reset */ +#define TIVA_SYSCON_SRCAN_OFFSET 0x534 /* CAN Software Reset */ +#define TIVA_SYSCON_SRADC_OFFSET 0x538 /* ADC Software Reset */ +#define TIVA_SYSCON_SRACMP_OFFSET 0x53c /* Analog Comparator Software Reset */ +#define TIVA_SYSCON_SREEPROM_OFFSET 0x558 /* EEPROM Software Reset */ +#define TIVA_SYSCON_SRWTIMER_OFFSET 0x55c /* 32/64-Bit Wide Timer Software Reset */ + +#define TIVA_SYSCON_RCGCWD_OFFSET 0x600 /* Watchdog Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCTIMER_OFFSET 0x604 /* 16/32-Bit Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCGPIO_OFFSET 0x608 /* GPIO Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCDMA_OFFSET 0x60c /* uDMA Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCHIB_OFFSET 0x614 /* Hibernation Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUART_OFFSET 0x618 /* UART Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCSSI_OFFSET 0x61c /* SSI Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCI2C_OFFSET 0x620 /* I2C Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUSB_OFFSET 0x628 /* USB Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCCAN_OFFSET 0x634 /* CAN Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCADC_OFFSET 0x638 /* ADC Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCACMP_OFFSET 0x63c /* Analog Comparator Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEEPROM_OFFSET 0x658 /* EEPROM Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCWTIMER_OFFSET 0x65c /* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define TIVA_SYSCON_SCGCWD_OFFSET 0x700 /* Watchdog Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCTIMER_OFFSET 0x704 /* 16/32-Bit Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCGPIO_OFFSET 0x708 /* GPIO Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCDMA_OFFSET 0x70c /* uDMA Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCHIB_OFFSET 0x714 /* Hibernation Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUART_OFFSET 0x718 /* UART Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCSSI_OFFSET 0x71c /* SSI Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCI2C_OFFSET 0x720 /* I2C Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUSB_OFFSET 0x728 /* USB Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCCAN_OFFSET 0x734 /* CAN Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCADC_OFFSET 0x738 /* ADC Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCACMP_OFFSET 0x73c /* Analog Comparator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEEPROM_OFFSET 0x758 /* EEPROM Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCWTIMER_OFFSET 0x75c /* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_DCGCWD_OFFSET 0x800 /* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCTIMER_OFFSET 0x804 /* Clock Gating Control */ +#define TIVA_SYSCON_DCGCGPIO_OFFSET 0x808 /* GPIO Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCDMA_OFFSET 0x80c /* uDMA Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCHIB_OFFSET 0x814 /* Hibernation Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUART_OFFSET 0x818 /* UART Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCSSI_OFFSET 0x81c /* SSI Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCI2C_OFFSET 0x820 /* I2C Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUSB_OFFSET 0x828 /* USB Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCCAN_OFFSET 0x834 /* CAN Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCADC_OFFSET 0x838 /* ADC Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCACMP_OFFSET 0x83c /* Analog Comparator Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEEPROM_OFFSET 0x858 /* EEPROM Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCWTIMER_OFFSET 0x85c /* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_PRWD_OFFSET 0xa00 /* Watchdog Timer Peripheral Ready */ +#define TIVA_SYSCON_PRTIMER_OFFSET 0xa04 /* 16/32-Bit Timer Peripheral Ready */ +#define TIVA_SYSCON_PRGPIO_OFFSET 0xa08 /* GPIO Peripheral Ready */ +#define TIVA_SYSCON_PRDMA_OFFSET 0xa0c /* uDMA Peripheral Ready */ +#define TIVA_SYSCON_PRHIB_OFFSET 0xa14 /* Hibernation Peripheral Ready */ +#define TIVA_SYSCON_PRUART_OFFSET 0xa18 /* UART Peripheral Ready */ +#define TIVA_SYSCON_PRSSI_OFFSET 0xa1c /* SSI Peripheral Ready */ +#define TIVA_SYSCON_PRI2C_OFFSET 0xa20 /* I2C Peripheral Ready */ +#define TIVA_SYSCON_PRUSB_OFFSET 0xa28 /* USB Peripheral Ready */ +#define TIVA_SYSCON_PRCAN_OFFSET 0xa34 /* CAN Peripheral Ready */ +#define TIVA_SYSCON_PRADC_OFFSET 0xa38 /* ADC Peripheral Ready */ +#define TIVA_SYSCON_PRACMP_OFFSET 0xa3c /* Analog Comparator Peripheral Ready */ +#define TIVA_SYSCON_PREEPROM_OFFSET 0xa58 /* EEPROM Peripheral Ready */ +#define TIVA_SYSCON_PRWTIMER_OFFSET 0xa5c /* 2/64-BitWide Timer Peripheral Ready */ + +/* System Control Legacy Register Offsets ***************************************************/ + +#define TIVA_SYSCON_DC0_OFFSET 0x008 /* Device Capabilities 0 */ +#define TIVA_SYSCON_DC1_OFFSET 0x010 /* Device Capabilities 1 */ +#define TIVA_SYSCON_DC2_OFFSET 0x014 /* Device Capabilities 2 */ +#define TIVA_SYSCON_DC3_OFFSET 0x018 /* Device Capabilities 3 */ +#define TIVA_SYSCON_DC4_OFFSET 0x01c /* Device Capabilities 4 */ +#define TIVA_SYSCON_DC5_OFFSET 0x020 /* Device Capabilities 5 */ +#define TIVA_SYSCON_DC6_OFFSET 0x024 /* Device Capabilities 6 */ +#define TIVA_SYSCON_DC7_OFFSET 0x028 /* Device Capabilities 7 */ +#define TIVA_SYSCON_DC8_OFFSET 0x02c /* Device Capabilities 8 */ + +#define TIVA_SYSCON_SRCR0_OFFSET 0x040 /* Software Reset Control 0 */ +#define TIVA_SYSCON_SRCR1_OFFSET 0x044 /* Software Reset Control 1 */ +#define TIVA_SYSCON_SRCR2_OFFSET 0x048 /* Software Reset Control 2 */ + +#define TIVA_SYSCON_RCGC0_OFFSET 0x100 /* Run Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_RCGC1_OFFSET 0x104 /* Run Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_RCGC2_OFFSET 0x108 /* Run Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_SCGC0_OFFSET 0x110 /* Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_SCGC1_OFFSET 0x114 /* Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_SCGC2_OFFSET 0x118 /* Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DCGC0_OFFSET 0x120 /* Deep Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_DCGC1_OFFSET 0x124 /* Deep Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_DCGC2_OFFSET 0x128 /* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DC9_OFFSET 0x190 /* Device Capabilities */ +#define TIVA_SYSCON_NVMSTAT_OFFSET 0x1a0 /* Non-Volatile Memory Information */ + +/* System Control Register Addresses ********************************************************/ + +#define TIVA_SYSCON_DID0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID0_OFFSET) +#define TIVA_SYSCON_DID1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID1_OFFSET) +#define TIVA_SYSCON_PBORCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_PBORCTL_OFFSET) +#define TIVA_SYSCON_RIS (TIVA_SYSCON_BASE + TIVA_SYSCON_RIS_OFFSET) +#define TIVA_SYSCON_IMC (TIVA_SYSCON_BASE + TIVA_SYSCON_IMC_OFFSET) +#define TIVA_SYSCON_MISC (TIVA_SYSCON_BASE + TIVA_SYSCON_MISC_OFFSET) +#define TIVA_SYSCON_RESC (TIVA_SYSCON_BASE + TIVA_SYSCON_RESC_OFFSET) +#define TIVA_SYSCON_RCC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC_OFFSET) +#define TIVA_SYSCON_GPIOHBCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_GPIOHBCTL_OFFSET) +#define TIVA_SYSCON_RCC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC2_OFFSET) +#define TIVA_SYSCON_MOSCCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_MOSCCTL_OFFSET) +#define TIVA_SYSCON_DSLPCLKCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPCLKCFG_OFFSET) +#define TIVA_SYSCON_SYSPROP (TIVA_SYSCON_BASE + TIVA_SYSCON_SYSPROP_OFFSET) +#define TIVA_SYSCON_PIOSCCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCCAL_OFFSET) +#define TIVA_SYSCON_PIOSCSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCSTAT_OFFSET) +#define TIVA_SYSCON_PLLFREQ0 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ0_OFFSET) +#define TIVA_SYSCON_PLLFREQ1 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ1_OFFSET) +#define TIVA_SYSCON_PLLSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLSTAT_OFFSET) + +#define TIVA_SYSCON_PPWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWD_OFFSET) +#define TIVA_SYSCON_PPTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPTIMER_OFFSET) +#define TIVA_SYSCON_PPGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PPGPIO_OFFSET) +#define TIVA_SYSCON_PPDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PPDMA_OFFSET) +#define TIVA_SYSCON_PPHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPHIB_OFFSET) +#define TIVA_SYSCON_PPUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUART_OFFSET) +#define TIVA_SYSCON_PPSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPSSI_OFFSET) +#define TIVA_SYSCON_PPI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PPI2C_OFFSET) +#define TIVA_SYSCON_PPUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUSB_OFFSET) +#define TIVA_SYSCON_PPCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PPCAN_OFFSET) +#define TIVA_SYSCON_PPADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PPADC_OFFSET) +#define TIVA_SYSCON_PPACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PPACMP_OFFSET) +#define TIVA_SYSCON_PPPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPPWM_OFFSET) +#define TIVA_SYSCON_PPQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPQEI_OFFSET) +#define TIVA_SYSCON_PPEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPEEPROM_OFFSET) +#define TIVA_SYSCON_PPWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWTIMER_OFFSET) + +#define TIVA_SYSCON_SRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWD_OFFSET) +#define TIVA_SYSCON_SRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRTIMER_OFFSET) +#define TIVA_SYSCON_SRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SRGPIO_OFFSET) +#define TIVA_SYSCON_SRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SRDMA_OFFSET) +#define TIVA_SYSCON_SRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRHIB_OFFSET) +#define TIVA_SYSCON_SRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUART_OFFSET) +#define TIVA_SYSCON_SRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SRSSI_OFFSET) +#define TIVA_SYSCON_SRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SRI2C_OFFSET) +#define TIVA_SYSCON_SRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUSB_OFFSET) +#define TIVA_SYSCON_SRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCAN_OFFSET) +#define TIVA_SYSCON_SRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SRADC_OFFSET) +#define TIVA_SYSCON_SRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SRACMP_OFFSET) +#define TIVA_SYSCON_SREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SREEPROM_OFFSET) +#define TIVA_SYSCON_SRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWTIMER_OFFSET) + +#define TIVA_SYSCON_RCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWD_OFFSET) +#define TIVA_SYSCON_RCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCTIMER_OFFSET) +#define TIVA_SYSCON_RCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCGPIO_OFFSET) +#define TIVA_SYSCON_RCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCDMA_OFFSET) +#define TIVA_SYSCON_RCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCHIB_OFFSET) +#define TIVA_SYSCON_RCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUART_OFFSET) +#define TIVA_SYSCON_RCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCSSI_OFFSET) +#define TIVA_SYSCON_RCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCI2C_OFFSET) +#define TIVA_SYSCON_RCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUSB_OFFSET) +#define TIVA_SYSCON_RCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCCAN_OFFSET) +#define TIVA_SYSCON_RCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCADC_OFFSET) +#define TIVA_SYSCON_RCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCACMP_OFFSET) +#define TIVA_SYSCON_RCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCEEPROM_OFFSET) +#define TIVA_SYSCON_RCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_SCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWD_OFFSET) +#define TIVA_SYSCON_SCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCTIMER_OFFSET) +#define TIVA_SYSCON_SCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCGPIO_OFFSET) +#define TIVA_SYSCON_SCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCDMA_OFFSET) +#define TIVA_SYSCON_SCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCHIB_OFFSET) +#define TIVA_SYSCON_SCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUART_OFFSET) +#define TIVA_SYSCON_SCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCSSI_OFFSET) +#define TIVA_SYSCON_SCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCI2C_OFFSET) +#define TIVA_SYSCON_SCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUSB_OFFSET) +#define TIVA_SYSCON_SCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCCAN_OFFSET) +#define TIVA_SYSCON_SCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCADC_OFFSET) +#define TIVA_SYSCON_SCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCACMP_OFFSET) +#define TIVA_SYSCON_SCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCEEPROM_OFFSET) +#define TIVA_SYSCON_SCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_DCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWD_OFFSET) +#define TIVA_SYSCON_DCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCTIMER_OFFSET) +#define TIVA_SYSCON_DCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCGPIO_OFFSET) +#define TIVA_SYSCON_DCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCDMA_OFFSET) +#define TIVA_SYSCON_DCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCHIB_OFFSET) +#define TIVA_SYSCON_DCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUART_OFFSET) +#define TIVA_SYSCON_DCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCSSI_OFFSET) +#define TIVA_SYSCON_DCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCI2C_OFFSET) +#define TIVA_SYSCON_DCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUSB_OFFSET) +#define TIVA_SYSCON_DCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCCAN_OFFSET) +#define TIVA_SYSCON_DCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCADC_OFFSET) +#define TIVA_SYSCON_DCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCACMP_OFFSET) +#define TIVA_SYSCON_DCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCEEPROM_OFFSET) +#define TIVA_SYSCON_DCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_PRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWD_OFFSET) +#define TIVA_SYSCON_PRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRTIMER_OFFSET) +#define TIVA_SYSCON_PRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PRGPIO_OFFSET) +#define TIVA_SYSCON_PRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PRDMA_OFFSET) +#define TIVA_SYSCON_PRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRHIB_OFFSET) +#define TIVA_SYSCON_PRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUART_OFFSET) +#define TIVA_SYSCON_PRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PRSSI_OFFSET) +#define TIVA_SYSCON_PRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PRI2C_OFFSET) +#define TIVA_SYSCON_PRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUSB_OFFSET) +#define TIVA_SYSCON_PRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PRCAN_OFFSET) +#define TIVA_SYSCON_PRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PRADC_OFFSET) +#define TIVA_SYSCON_PRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PRACMP_OFFSET) +#define TIVA_SYSCON_PREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PREEPROM_OFFSET) +#define TIVA_SYSCON_PRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWTIMER_OFFSET) + +/* System Control Legacy Register Addresses *************************************************/ + +#define TIVA_SYSCON_DC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC0_OFFSET) +#define TIVA_SYSCON_DC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC1_OFFSET) +#define TIVA_SYSCON_DC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC2_OFFSET) +#define TIVA_SYSCON_DC3 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC3_OFFSET) +#define TIVA_SYSCON_DC4 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC4_OFFSET) +#define TIVA_SYSCON_DC5 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC5_OFFSET) +#define TIVA_SYSCON_DC6 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC6_OFFSET) +#define TIVA_SYSCON_DC7 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC7_OFFSET) +#define TIVA_SYSCON_DC8 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC8_OFFSET) + +#define TIVA_SYSCON_SRCR0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR0_OFFSET) +#define TIVA_SYSCON_SRCR1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR1_OFFSET) +#define TIVA_SYSCON_SRCR2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR2_OFFSET) + +#define TIVA_SYSCON_RCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC0_OFFSET) +#define TIVA_SYSCON_RCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC1_OFFSET) +#define TIVA_SYSCON_RCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC2_OFFSET) + +#define TIVA_SYSCON_SCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC0_OFFSET) +#define TIVA_SYSCON_SCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC1_OFFSET) +#define TIVA_SYSCON_SCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC2_OFFSET) + +#define TIVA_SYSCON_DCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC0_OFFSET) +#define TIVA_SYSCON_DCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC1_OFFSET) +#define TIVA_SYSCON_DCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC2_OFFSET) + +#define TIVA_SYSCON_DC9 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC9_OFFSET) +#define TIVA_SYSCON_NVMSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_NVMSTAT_OFFSET) + +/* System Control Register Bit Definitions **************************************************/ + +/* Device Identification 0 */ + +#define SYSCON_DID0_MINOR_SHIFT 0 /* Bits 7-0: Minor Revision of the device */ +#define SYSCON_DID0_MINOR_MASK (0xff << SYSCON_DID0_MINOR_SHIFT) +#define SYSCON_DID0_MAJOR_SHIFT 8 /* Bits 15-8: Major Revision of the device */ +#define SYSCON_DID0_MAJOR_MASK (0xff << SYSCON_DID0_MAJOR_SHIFT) +#define SYSCON_DID0_CLASS_SHIFT 16 /* Bits 23-16: Device Class */ +#define SYSCON_DID0_CLASS_MASK (0xff << SYSCON_DID0_CLASS_SHIFT) +#define SYSCON_DID0_VER_SHIFT 28 /* Bits 30-28: DID0 Version */ +#define SYSCON_DID0_VER_MASK (7 << SYSCON_DID0_VER_SHIFT) + +/* Device Identification 1 */ + +#define SYSCON_DID1_QUAL_SHIFT 0 /* Bits 1-0: Qualification Status */ +#define SYSCON_DID1_QUAL_MASK (0x03 << SYSCON_DID1_QUAL_SHIFT) +#define SYSCON_DID1_ROHS (1 << 2) /* Bit 2: RoHS-Compliance */ +#define SYSCON_DID1_PKG_SHIFT 3 /* Bits 4-3: Package Type */ +#define SYSCON_DID1_PKG_MASK (0x03 << SYSCON_DID1_PKG_SHIFT) +#define SYSCON_DID1_TEMP_SHIFT 5 /* Bits 7-5: Temperature Range */ +#define SYSCON_DID1_TEMP_MASK (0x07 << SYSCON_DID1_TEMP_SHIFT) +#define SYSCON_DID1_PINCOUNT_SHIFT 13 /* Bits 15-13: Package Pin Count */ +#define SYSCON_DID1_PINCOUNT_MASK (0x07 << SYSCON_DID1_PINCOUNT_SHIFT) +#define SYSCON_DID1_PARTNO_SHIFT 16 /* Bits 23-16: Part Number */ +#define SYSCON_DID1_PARTNO_MASK (0xff << SYSCON_DID1_PARTNO_SHIFT) +#define SYSCON_DID1_FAM_SHIFT 24 /* Bits 27-24: Family */ +#define SYSCON_DID1_FAM_MASK (0x0f << SYSCON_DID1_FAM_SHIFT) +#define SYSCON_DID1_VER_SHIFT 28 /* Bits 31-28: DID1 Version */ +#define SYSCON_DID1_VER_MASK (0x0f << SYSCON_DID1_VER_SHIFT) + +/* Brown-Out Reset Control */ + +#define SYSCON_PBORCTL_BORI1 (1 << 1) /* Bit 1: VDD under BOR1 Event Action */ +#define SYSCON_PBORCTL_BORI0 (1 << 2) /* Bit 2: VDD under BOR0 Event Action */ + +/* Raw Interrupt Status */ + +#define SYSCON_RIS_BORR1RIS (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Status */ +#define SYSCON_RIS_MOFRIS (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Status */ +#define SYSCON_RIS_PLLLRIS (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_USBPLLLRIS (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_MOSCPUPRIS (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Status */ +#define SYSCON_RIS_VDDARIS (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Status */ +#define SYSCON_RIS_BOR0RIS (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Status */ + +/* Interrupt Mask Control */ + +#define SYSCON_IMC_BORR1RIM (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Mask */ +#define SYSCON_IMC_MOFRIM (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Mask */ +#define SYSCON_IMC_PLLLRIM (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Mask */ +#define SYSCON_IMC_USBPLLLRIM (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Mask */ +#define SYSCON_IMC_MOSCPUPRIM (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Mask */ +#define SYSCON_IMC_VDDARIM (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Mask */ +#define SYSCON_IMC_BOR0RIM (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Mask */ + +/* Masked Interrupt Status and Clear */ + +#define SYSCON_MISC_BORR1MIS (1 << 1) /* Bit 1: VDD under BOR1 Masked Interrupt Status */ +#define SYSCON_MISC_MOFMIS (1 << 3) /* Bit 3: Main Oscillator Failure Masked Interrupt Status */ +#define SYSCON_MISC_PLLLMIS (1 << 6) /* Bit 6: PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_USBPLLLMIS (1 << 7) /* Bit 7: USB PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_MOSCPUPMIS (1 << 8) /* Bit 8: MOSC Power Up Masked Interrupt Status */ +#define SYSCON_MISC_VDDAMIS (1 << 10) /* Bit 10: VDDA Power OK Event Masked Interrupt Status */ +#define SYSCON_MISC_BOR0MIS (1 << 11) /* Bit 11: VDD under BOR0 Masked Interrupt Status */ + +/* Reset Cause */ + +#define SYSCON_RESC_EXT (1 << 0) /* Bit 0: External Reset */ +#define SYSCON_RESC_POR (1 << 1) /* Bit 1: Power-On Reset */ +#define SYSCON_RESC_BOR (1 << 2) /* Bit 2: Brown-Out Reset */ +#define SYSCON_RESC_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset */ +#define SYSCON_RESC_SW (1 << 4) /* Bit 4: Software Reset */ +#define SYSCON_RESC_WDT1 (1 << 5) /* Bit 5: Watchdog Timer 1 Reset */ +#define SYSCON_RESC_MOSCFAIL (1 << 16) /* Bit 16: MOSC Failure Reset */ + +/* Run-Mode Clock Configuration */ + +#define SYSCON_RCC_MOSCDIS (1 << 0) /* Bit 0: Main Oscillator Disable */ +#define SYSCON_RCC_OSCSRC_SHIFT 4 /* Bits 5-4: Oscillator Source */ +#define SYSCON_RCC_OSCSRC_MASK (0x03 << SYSCON_RCC_OSCSRC_SHIFT) +# define SYSCON_RCC_OSCSRC_MOSC (0 << SYSCON_RCC_OSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_RCC_OSCSRC_PIOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC_OSCSRC_PIOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC_OSCSRC_LFIOSC (3 << SYSCON_RCC_OSCSRC_SHIFT) /* Low-frequency internal oscillator */ +#define SYSCON_RCC_XTAL_SHIFT 6 /* Bits 10-6: Crystal Value */ +#define SYSCON_RCC_XTAL_MASK (31 << SYSCON_RCC_XTAL_SHIFT) +# define SYSCON_RCC_XTAL4000KHZ (6 << SYSCON_RCC_XTAL_SHIFT) /* 4 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4096KHZ (7 << SYSCON_RCC_XTAL_SHIFT) /* 4.096 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4915p2KHZ (8 << SYSCON_RCC_XTAL_SHIFT) /* 4.9152 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL5000KHZ (9 << SYSCON_RCC_XTAL_SHIFT) /* 5 MHz (USB) */ +# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.12 MHz */ +# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6 MHz (USB) */ +# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.144 MHz */ +# define SYSCON_RCC_XTAL7372p8KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728 MHz */ +# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8 MHz (USB) */ +# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.192 MHz */ +# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12288KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */ +# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */ +# define SYSCON_RCC_XTAL14318p18KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */ +# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */ +# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */ +# define SYSCON_RCC_XTAL18000KHZ (23 << SYSCON_RCC_XTAL_SHIFT) /* 18.0 MHz (USB) */ +# define SYSCON_RCC_XTAL20000KHZ (24 << SYSCON_RCC_XTAL_SHIFT) /* 20.0 MHz (USB) */ +# define SYSCON_RCC_XTAL24000KHZ (25 << SYSCON_RCC_XTAL_SHIFT) /* 24.0 MHz (USB) */ +# define SYSCON_RCC_XTAL25000KHZ (26 << SYSCON_RCC_XTAL_SHIFT) /* 25.0 MHz (USB) */ +#define SYSCON_RCC_BYPASS (1 << 11) /* Bit 11: PLL Bypass */ +#define SYSCON_RCC_PWRDN (1 << 13) /* Bit 13: PLL Power Down */ +#define SYSCON_RCC_USESYSDIV (1 << 22) /* Bit 22: Enable System Clock Divider */ +#define SYSCON_RCC_SYSDIV_SHIFT 23 /* Bits 26-23: System Clock Divisor */ +#define SYSCON_RCC_SYSDIV_MASK (0x0f << SYSCON_RCC_SYSDIV_SHIFT) +# define SYSCON_RCC_SYSDIV(n) (((n)-1) << SYSCON_RCC_SYSDIV_SHIFT) +#define SYSCON_RCC_ACG (1 << 27) /* Bit 27: Auto Clock Gating */ + +/* GPIO High-Performance Bus Control */ + +#define SYSCON_GPIOHBCTL_PORTA (1 << 0) /* Bit 0: Port A Advanced High-Performance Bus */ +#define SYSCON_GPIOHBCTL_PORTB (1 << 1) /* Bit 1: Port B Advanced High-Performance Bus */ +#define SYSCON_GPIOHBCTL_PORTC (1 << 2) /* Bit 2: Port C Advanced High-Performance Bus */ +#define SYSCON_GPIOHBCTL_PORTD (1 << 3) /* Bit 3: Port D Advanced High-Performance Bus */ +#define SYSCON_GPIOHBCTL_PORTE (1 << 4) /* Bit 4: Port E Advanced High-Performance Bus */ +#define SYSCON_GPIOHBCTL_PORTF (1 << 5) /* Bit 5: Port F Advanced High-Performance Bus */ + +/* Run-Mode Clock Configuration 2 */ + +#define SYSCON_RCC2_OSCSRC2_SHIFT 4 /* Bits 6-4: Oscillator Source */ +#define SYSCON_RCC2_OSCSRC2_MASK (7 << SYSCON_RCC2_OSCSRC2_SHIFT) +# define SYSCON_RCC2_OSCSRC2_MOSC (0 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Main oscillator */ +# define SYSCON_RCC2_OSCSRC2_PIOSC (1 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC2_OSCSRC2_PIOSC4 (2 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC2_OSCSRC2_LFIOSC (4 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_RCC2_OSCSRC2_32768HZ (7 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_RCC2_BYPASS2 (1 << 11) /* Bit 11: Bypass PLL */ +#define SYSCON_RCC2_PWRDN2 (1 << 13) /* Bit 13: Power-Down PLL */ +#define SYSCON_RCC2_USBPWRDN (1 << 14) /* Bit 14: Power-Down USB PLL */ +#define SYSCON_RCC2_SYSDIV2LSB (1 << 22) /* Bit 22: Additional LSB for SYSDIV2 */ +#define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */ +#define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV_DIV400(n) (((n-1) >> 1) << SYSCON_RCC2_SYSDIV2_SHIFT) +#define SYSCON_RCC2_DIV400 (1 << 30) /* Bit 30: Divide PLL as 400 MHz vs. 200 MHz */ +#define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */ + +/* Main Oscillator Control */ + +#define SYSCON_MOSCCTL_CVAL (1 << 0) /* Bit 0: Clock Validation for MOSC */ +#define SYSCON_MOSCCTL_MOSCIM (1 << 1) /* Bit 1: MOSC Failure Action */ +#define SYSCON_MOSCCTL_NOXTAL (1 << 2) /* Bit 2: No Crystal Connected */ + +/* Deep Sleep Clock Configuration */ + +#define SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT 4 /* Bits 6-4: Clock Source */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_MASK (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) +# define SYSCON_DSLPCLKCFG_DSOSCSRC_MOSC (0 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC (1 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC4 (2 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_LFIOSC (4 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_32768KHZ (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT 23 /* Bits 28-23: Divider Field Override */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_MASK (0x3f << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) +# define SYSCON_DSLPCLKCFG_DSDIVORIDE(b) (((n)-1) << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) + +/* System Properties */ + +#define SYSCON_SYSPROP_FPU (1 << 0) /* Bit 0: FPU Present */ + +/* Precision Internal Oscillator Calibration */ + +#define SYSCON_PIOSCCAL_UT_SHIFT (0) /* Bits 0-6: User Trim Value */ +#define SYSCON_PIOSCCAL_UT_MASK (0x7f << SYSCON_PIOSCCAL_UT_SHIFT) +#define SYSCON_PIOSCCAL_UPDATE (1 << 8) /* Bit 8: Update Trim */ +#define SYSCON_PIOSCCAL_CAL (1 << 9) /* Bit 9: Start Calibration */ +#define SYSCON_PIOSCCAL_UTEN (1 << 31) /* Bit 31: Use User Trim Value */ + +/* Precision Internal Oscillator Statistics */ + +#define SYSCON_PIOSCSTAT_CT_SHIFT (0) /* Bits 0-6: Calibration Trim Value */ +#define SYSCON_PIOSCSTAT_CT_MASK (0x7f << SYSCON_PIOSCSTAT_CT_SHIFT) +#define SYSCON_PIOSCSTAT_RESULT_SHIFT (8) /* Bits 8-9: Calibration Result */ +#define SYSCON_PIOSCSTAT_RESULT_MASK (3 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +#define SYSCON_PIOSCSTAT_DT_SHIFT (16) /* Bits 16-22: Default Trim Value */ +#define SYSCON_PIOSCSTAT_DT_MASK (0x7f << SYSCON_PIOSCSTAT_DT_SHIFT) + +/* PLL0 Frequency */ + +#define SYSCON_PLLFREQ0_MINT_SHIFT (0) /* Bits 0-9: PLL M Integer Value */ +#define SYSCON_PLLFREQ0_MINT_MASK (0x3ff << SYSCON_PLLFREQ0_MINT_SHIFT) +#define SYSCON_PLLFREQ0_MFRAC_SHIFT (10) /* Bits 10-19: PLL M Fractional Value */ +#define SYSCON_PLLFREQ0_MFRAC_MASK (0x3ff << SYSCON_PLLFREQ0_MFRAC_SHIFT) + +/* PLL1 Frequency */ + +#define SYSCON_PLLFREQ1_N_SHIFT (0) /* Bits 0-4: PLL N Value */ +#define SYSCON_PLLFREQ1_N_MASK (31 << SYSCON_PLLFREQ1_N_SHIFT) +#define SYSCON_PLLFREQ1_Q_SHIFT (8) /* Bits 8-12: PLL Q Value */ +#define SYSCON_PLLFREQ1_Q_MASK (31 << SYSCON_PLLFREQ1_Q_SHIFT) + +/* PLL Status */ + +#define SYSCON_PLLSTAT_LOCK (1 << 0) /* Bit 0: PLL Lock */ + +/* Watchdog Timer Peripheral Present */ + +#define SYSCON_PPWD(n) (1 << (n)) /* Bit n: WDTn present */ +# define SYSCON_PPWD_P0 (1 << 0) /* Bit 0: WDT0 present */ +# define SYSCON_PPWD_P1 (1 << 1) /* Bit 1: WDT1 present */ + +/* 16/32-Bit Timer Peripheral Present */ + +#define SYSCON_PPTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Present */ +# define SYSCON_PPTIMER_P0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 0 Present */ + +/* GPIO Peripheral Present */ + +#define SYSCON_PPGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Present */ +# define SYSCON_PPGPIO_P0 (1 << 0) /* Bit 0: GPIO Port A Present */ +# define SYSCON_PPGPIO_P1 (1 << 1) /* Bit 1: GPIO Port B Present */ +# define SYSCON_PPGPIO_P2 (1 << 2) /* Bit 2: GPIO Port C Present */ +# define SYSCON_PPGPIO_P3 (1 << 3) /* Bit 3: GPIO Port D Present */ +# define SYSCON_PPGPIO_P4 (1 << 4) /* Bit 4: GPIO Port E Present */ +# define SYSCON_PPGPIO_P5 (1 << 5) /* Bit 5: GPIO Port F Present */ +# define SYSCON_PPGPIO_P6 (1 << 6) /* Bit 6: GPIO Port G Present */ +# define SYSCON_PPGPIO_P7 (1 << 7) /* Bit 7: GPIO Port H Present */ +# define SYSCON_PPGPIO_P8 (1 << 8) /* Bit 8: GPIO Port J Present */ +# define SYSCON_PPGPIO_P9 (1 << 9) /* Bit 9: GPIO Port K Present */ +# define SYSCON_PPGPIO_P10 (1 << 10) /* Bit 10: GPIO Port L Present */ +# define SYSCON_PPGPIO_P11 (1 << 11) /* Bit 11: GPIO Port M Present */ +# define SYSCON_PPGPIO_P12 (1 << 12) /* Bit 12: GPIO Port N Present */ +# define SYSCON_PPGPIO_P13 (1 << 13) /* Bit 13: GPIO Port P Present */ +# define SYSCON_PPGPIO_P14 (1 << 14) /* Bit 14: GPIO Port Q Present */ + +/* uDMA Peripheral Present */ + +#define SYSCON_PPDMA_P0 (1 << 0) /* Bit 0: μDMA Module Present */ + +/* Hibernation Peripheral Present */ + +#define SYSCON_PPHIB_P0 (1 << 0) /* Bit 0: Hibernation Module Present */ + +/* UART Present */ + +#define SYSCON_PPUART(n) (1 << (n)) /* Bit n: UART Module n Present */ +# define SYSCON_PPUART_P0 (1 << 0) /* Bit 0: UART Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: UART Module 1 Present */ +# define SYSCON_PPUART_P2 (1 << 2) /* Bit 2: UART Module 2 Present */ +# define SYSCON_PPUART_P3 (1 << 3) /* Bit 3: UART Module 3 Present */ +# define SYSCON_PPUART_P4 (1 << 4) /* Bit 4: UART Module 4 Present */ +# define SYSCON_PPUART_P5 (1 << 5) /* Bit 5: UART Module 5 Present */ +# define SYSCON_PPUART_P6 (1 << 6) /* Bit 6: UART Module 6 Present */ +# define SYSCON_PPUART_P7 (1 << 7) /* Bit 7: UART Module 7 Present */ + +/* SSI Peripheral Present */ + +#define SYSCON_PPSSI(n) (1 << (n)) /* Bit n: SSI Module n Present */ +# define SYSCON_PPSSI_P0 (1 << 0) /* Bit 0: SSI Module 0 Present */ +# define SYSCON_PPSSI_P1 (1 << 1) /* Bit 1: SSI Module 1 Present */ +# define SYSCON_PPSSI_P2 (1 << 2) /* Bit 2: SSI Module 2 Present */ +# define SYSCON_PPSSI_P3 (1 << 3) /* Bit 3: SSI Module 3 Present */ + +/* I2C Peripheral Present */ + +#define SYSCON_PPI2C(n) (1 << (n)) /* Bit n: I2C Module n Present */ +# define SYSCON_PPI2C_P0 (1 << 0) /* Bit 0: I2C Module 0 Present */ +# define SYSCON_PPI2C_P1 (1 << 1) /* Bit 1: I2C Module 1 Present */ +# define SYSCON_PPI2C_P2 (1 << 2) /* Bit 2: I2C Module 2 Present */ +# define SYSCON_PPI2C_P3 (1 << 3) /* Bit 3: I2C Module 3 Present */ +# define SYSCON_PPI2C_P4 (1 << 4) /* Bit 4: I2C Module 4 Present */ +# define SYSCON_PPI2C_P5 (1 << 5) /* Bit 5: I2C Module 5 Present */ + +/* USB Peripheral Present */ + +#define SYSCON_PPUSB_P0 (1 << 0) /* USB Module Present */ + +/* CAN Peripheral Present */ + +#define SYSCON_PPCAN(n) (1 << (n)) /* Bit n: CAN Module n Present */ +# define SYSCON_PPCAN_P0 (1 << 0) /* Bit 0: CAN Module 0 Present */ +# define SYSCON_PPCAN_P1 (1 << 1) /* Bit 1: CAN Module 1 Present */ + +/* ADC Peripheral Present */ + +#define SYSCON_PPADC(n) (1 << (n)) /* Bit n: ADC Module n Present */ +# define SYSCON_PPADC_P0 (1 << 0) /* Bit 0: ADC Module 0 Present */ +# define SYSCON_PPADC_P1 (1 << 1) /* Bit 1: ADC Module 1 Present */ + +/* Analog Comparator Peripheral Present */ + +#define SYSCON_PPACMP_P0 (1 << 0) /* Bit 0: Analog Comparator Module Present */ + +/* Pulse Width Modulator Peripheral Present */ + +#define SYSCON_PPWM(n) (1 << (n)) /* Bit n: PWM Module n Present */ +# define SYSCON_PPWM_P0 (1 << 0) /* Bit 0: PWM Module 0 Present */ +# define SYSCON_PPWM_P1 (1 << 1) /* Bit 1: PWM Module 1 Present */ + +/* Quadrature Encoder Peripheral Present */ + +#define SYSCON_PPQEI(n) (1 << (n)) /* Bit n: QEI Module n Present */ +# define SYSCON_PPQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: QEI Module 1 Present */ + +/* EEPROM Peripheral Present */ + +#define SYSCON_PPEEPROM_P0 (1 << 0) /* Bit 0: EEPROM Module Present */ + +/* 32/64-Bit Wide Timer Peripheral Present */ + +#define SYSCON_PPWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Present */ +# define SYSCON_PPWTIMER_P0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Present */ +# define SYSCON_PPWTIMER_P1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Present */ +# define SYSCON_PPWTIMER_P2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Present */ +# define SYSCON_PPWTIMER_P3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Present */ +# define SYSCON_PPWTIMER_P4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Present */ +# define SYSCON_PPWTIMER_P5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Present */ + +/* Watchdog Timer Software Reset */ + +#define SYSCON_SPWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Software Reset */ +# define SYSCON_SPWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Software Reset */ +# define SYSCON_SPWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Software Reset */ + +/* 16/32-Bit Timer Software Reset */ + +#define SYSCON_SRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Software Reset */ +# define SYSCON_SRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Software Reset */ + +/* GPIO Software Reset */ + +#define SYSCON_SRGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Software Reset */ +# define SYSCON_SRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Software Reset */ +# define SYSCON_SRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Software Reset */ +# define SYSCON_SRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Software Reset */ +# define SYSCON_SRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Software Reset */ +# define SYSCON_SRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Software Reset */ +# define SYSCON_SRPGIO_R5 (1 << 5) /* Bit 5: GPIO Port F Software Reset */ + +/* uDMA Software Reset */ + +#define SYSCON_SRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Software Reset */ + +/* Hibernation Software Reset */ + +#define SYSCON_SRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Software Reset */ + +/* UART Software Reset*/ + +#define SYSCON_SRUARTR(n) (1 << (n)) /* Bit n: UART Module n Software Reset */ +# define SYSCON_SRUARTR_R0 (1 << 0) /* Bit 0: UART Module 0 Software Reset */ +# define SYSCON_SRUARTR_R1 (1 << 1) /* Bit 1: UART Module 1 Software Reset */ +# define SYSCON_SRUARTR_R2 (1 << 2) /* Bit 2: UART Module 2 Software Reset */ +# define SYSCON_SRUARTR_R3 (1 << 3) /* Bit 3: UART Module 3 Software Reset */ +# define SYSCON_SRUARTR_R4 (1 << 4) /* Bit 4: UART Module 4 Software Reset */ +# define SYSCON_SRUARTR_R5 (1 << 5) /* Bit 5: UART Module 5 Software Reset */ +# define SYSCON_SRUARTR_R6 (1 << 6) /* Bit 6: UART Module 6 Software Reset */ +# define SYSCON_SRUARTR_R7 (1 << 7) /* Bit 7: UART Module 7 Software Reset */ + +/* SSI Software Reset */ + +#define SYSCON_SRSSI(n) (1 << (n)) /* Bit n: SSI Module n Software Reset */ +# define SYSCON_SRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Software Reset */ +# define SYSCON_SRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Software Reset */ +# define SYSCON_SRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Software Reset */ +# define SYSCON_SRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Software Reset */ + +/* I2C Software Reset */ + +#define SYSCON_SRI2C(n) (1 << (n)) /* Bit n: I2C Module n Software Reset */ +# define SYSCON_SRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Software Reset */ +# define SYSCON_SRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Software Reset */ +# define SYSCON_SRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Software Reset */ +# define SYSCON_SRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Software Reset */ + +/* USB Software Reset */ + +#define SYSCON_SRUSB_R0 (1 << 0) /* Bit 0: USB Module Software Reset */ + +/* CAN Software Reset */ + +#define SYSCON_SRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Software Reset */ + +/* ADC Software Reset */ + +#define SYSCON_SRADC(n) (1 << (n)) /* Bit n: ADC Module n Software Reset */ +# define SYSCON_SRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Software Reset */ +# define SYSCON_SRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Software Reset */ + +/* Analog Comparator Software Reset */ + +#define SYSCON_SRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Software Reset */ + +/* EEPROM Software Reset */ + +#define SYSCON_SREEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Software Reset */ + +/* 32/64-Bit Wide Timer Software Reset */ + +#define SYSCON_SRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Software Reset */ +# define SYSCON_SRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Software Reset */ +# define SYSCON_SRWTIMER_R6 (1 << 6) /* Bit 6: 32/64-Bit Wide General-Purpose Timer 6 Software Reset */ + +/* Watchdog Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Run Mode Clock Gating Control */ + +/* 16/32-Bit Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* GPIO Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCGPIO(n) (1 << (n)) /* Bit n: 16/32-Bit GPIO Port n Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R0 (1 << 0) /* Bit 0: 16/32-Bit GPIO Port A Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R1 (1 << 1) /* Bit 1: 16/32-Bit GPIO Port B Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R2 (1 << 2) /* Bit 2: 16/32-Bit GPIO Port C Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R3 (1 << 3) /* Bit 3: 16/32-Bit GPIO Port D Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R4 (1 << 4) /* Bit 4: 16/32-Bit GPIO Port E Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R5 (1 << 5) /* Bit 5: 16/32-Bit GPIO Port F Run Mode Clock Gating Control */ + +/* uDMA Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCDMA_R0 (1 << 0) /* Bit 0: μDMA Module Run Mode Clock Gating Control */ + +/* Hibernation Run Mode Clock Gating Control */ + +#define SYSCON_RCGCHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Run Mode Clock Gating Control */ + +/* UART Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCUART(n) (1 << (n)) /* Bit n: UART Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R0 (1 << 0) /* Bit 0: UART Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R1 (1 << 1) /* Bit 1: UART Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R2 (1 << 2) /* Bit 2: UART Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R3 (1 << 3) /* Bit 3: UART Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R4 (1 << 4) /* Bit 4: UART Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R5 (1 << 5) /* Bit 5: UART Module 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R6 (1 << 6) /* Bit 6: UART Module 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R7 (1 << 7) /* Bit 7: UART Module 7 Run Mode Clock Gating Control */ + +/* SSI Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Run Mode Clock Gating Control */ + +/* I2C Run Mode Clock Gating Control */ + +#define SYSCON_RCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Run Mode Clock Gating Control */ + +/* USB Run Mode Clock Gating Control */ + +#define SYSCON_RCGCUSB_R0 (1 << 0) /* Bit 0: USB Module Run Mode Clock Gating Control */ + +/* CAN Run Mode Clock Gating Control */ + +#define SYSCON_RCGCCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Run Mode Clock Gating Control */ + +/* ADC Run Mode Clock Gating Control */ + +#define SYSCON_RCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Run Mode Clock Gating Control */ + +/* Analog Comparator Run Mode Clock Gating Control */ + +#define SYSCON_RCGCACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Run Mode Clock Gating Control */ + +/* EEPROM Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Run Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* Watchdog Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: Watchdog Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: Watchdog Timer 1 Sleep Mode Clock Gating Control */ + +/* 16/32-Bit Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* GPIO Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S0 (1 << 0) /* Bit 0: GPIO Port A Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S1 (1 << 1) /* Bit 1: GPIO Port B Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S2 (1 << 2) /* Bit 2: GPIO Port C Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S3 (1 << 3) /* Bit 3: GPIO Port D Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S4 (1 << 4) /* Bit 4: GPIO Port E Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S5 (1 << 5) /* Bit 5: GPIO Port F Sleep Mode Clock Gating Control */ + +/* uDMA Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCDMA_S0 (1 << 0) /* Bit 0: μDMA Module Sleep Mode Clock Gating Control */ + +/* Hibernation Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCHIB_S0 (1 << 0) /* Bit 0: Hibernation Module Sleep Mode Clock Gating Control */ + +/* UART Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUART(n) (1 << (n)) /* Bit n: UART Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S0 (1 << 0) /* Bit 0: UART Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S1 (1 << 1) /* Bit 1: UART Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S2 (1 << 2) /* Bit 2: UART Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S3 (1 << 3) /* Bit 3: UART Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S4 (1 << 4) /* Bit 4: UART Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S5 (1 << 5) /* Bit 5: UART Module 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S6 (1 << 6) /* Bit 6: UART Module 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S7 (1 << 7) /* Bit 7: UART Module 7 Sleep Mode Clock Gating Control */ + +/* SSI Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S0 (1 << 0) /* Bit 0: SSI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S1 (1 << 1) /* Bit 1: SSI Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S2 (1 << 2) /* Bit 2: SSI Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S3 (1 << 3) /* Bit 3: SSI Module 3 Sleep Mode Clock Gating Control */ + +/* I2C Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S0 (1 << 0) /* Bit 0: I2C Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S1 (1 << 1) /* Bit 1: I2C Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S2 (1 << 2) /* Bit 2: I2C Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S3 (1 << 3) /* Bit 3: I2C Module 3 Sleep Mode Clock Gating Control */ + +/* USB Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUSB_S0 (1 << 0) /* Bit 0: USB Module Sleep Mode Clock Gating Control */ + +/* CAN Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCCAN_S0 (1 << 0) /* Bit 0: CAN Module 0 Sleep Mode Clock Gating Control */ + +/* ADC Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S0 (1 << 0) /* Bit 0: ADC Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S1 (1 << 1) /* Bit 1: ADC Module 1 Sleep Mode Clock Gating Control */ + +/* Analog Comparator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCACMP_S0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Sleep Mode Clock Gating Control */ + +/* EEPROM Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEEPROM_S0 (1 << 0) /* Bit 0: EEPROM Module Sleep Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D0 (1 << 0) /* Bit 0: Watchdog Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D1 (1 << 1) /* Bit 1: Watchdog Timer 1 Deep-Sleep Mode Clock Gating Control */ + +/* Clock Gating Control */ + +#define SYSCON_DCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Deep-Sleep Mode Clock Gating Control */ + +/* GPIO Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D0 (1 << 0) /* Bit 0: GPIO Port A Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D1 (1 << 1) /* Bit 1: GPIO Port B Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D2 (1 << 2) /* Bit 2: GPIO Port C Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D3 (1 << 3) /* Bit 3: GPIO Port D Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D4 (1 << 4) /* Bit 4: GPIO Port E Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D5 (1 << 5) /* Bit 5: GPIO Port F Deep-Sleep Mode Clock Gating Control */ + +/* uDMA Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCDMA_D0 (1 << 0) /* Bit 0: μDMA Module Deep-Sleep Mode Clock Gating Control */ + +/* Hibernation Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCHIB_D0 (1 << 0) /* Bit 0: Hibernation Module Deep-Sleep Mode Clock Gating Control */ + +/* UART Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUART(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D6 (1 << 6) /* Bit 6: UART Module 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D7 (1 << 7) /* Bit 7: UART Module 7 Deep-Sleep Mode Clock Gating Control */ + +/* SSI Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D0 (1 << 0) /* Bit 0: SSI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D1 (1 << 1) /* Bit 1: SSI Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D2 (1 << 2) /* Bit 2: SSI Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D3 (1 << 3) /* Bit 3: SSI Module 3 Deep-Sleep Mode Clock Gating Control */ + +/* I2C Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D0 (1 << 0) /* Bit 0: I2C Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D1 (1 << 1) /* Bit 1: I2C Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D2 (1 << 2) /* Bit 2: I2C Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D3 (1 << 3) /* Bit 3: I2C Module 3 Deep-Sleep Mode Clock Gating Control */ + +/* USB Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUSB_D0 (1 << 0) /* Bit 0: USB Module Deep-Sleep Mode Clock Gating Control */ + +/* CAN Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCCAN_D0 (1 << 0) /* Bit 0: CAN Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* ADC Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D0 (1 << 0) /* Bit 0: ADC Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D1 (1 << 1) /* Bit 1: ADC Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* Analog Comparator Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCACMP_D0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* EEPROM Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEEPROM_D0 (1 << 0) /* Bit 0: EEPROM Module Deep-Sleep Mode Clock Gating Control */ + + +/* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWTIMER(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Peripheral Ready */ + +#define SYSCON_PRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Peripheral Ready */ +# define SYSCON_PRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Peripheral Ready */ +# define SYSCON_PRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Peripheral Ready */ + +/* 16/32-Bit Timer Peripheral Ready */ + +#define SYSCON_PRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Peripheral Ready */ + +/* GPIO Peripheral Ready */ + +#define SYSCON_PRGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Peripheral Ready */ +# define SYSCON_PRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Peripheral Ready */ +# define SYSCON_PRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Peripheral Ready */ +# define SYSCON_PRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Peripheral Ready */ +# define SYSCON_PRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Peripheral Ready */ +# define SYSCON_PRGPIO_R5 (1 << 5) /* Bit 5: GPIO Port F Peripheral Ready */ + +/* uDMA Peripheral Ready */ + +#define SYSCON_PRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Peripheral Ready */ + +/* Hibernation Peripheral Ready */ + +#define SYSCON_PRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Peripheral Ready */ + +/* UART Peripheral Ready */ + +#define SYSCON_PRUART(n) (1 << (n)) /* Bit n: UART Module n Peripheral Ready */ +# define SYSCON_PRUART_R0 (1 << 0) /* Bit 0: UART Module 0 Peripheral Ready */ +# define SYSCON_PRUART_R1 (1 << 1) /* Bit 1: UART Module 1 Peripheral Ready */ +# define SYSCON_PRUART_R2 (1 << 2) /* Bit 2: UART Module 2 Peripheral Ready */ +# define SYSCON_PRUART_R3 (1 << 3) /* Bit 3: UART Module 3 Peripheral Ready */ +# define SYSCON_PRUART_R4 (1 << 4) /* Bit 4: UART Module 4 Peripheral Ready */ +# define SYSCON_PRUART_R5 (1 << 5) /* Bit 5: UART Module 5 Peripheral Ready */ +# define SYSCON_PRUART_R6 (1 << 6) /* Bit 6: UART Module 6 Peripheral Ready */ +# define SYSCON_PRUART_R7 (1 << 7) /* Bit 7: UART Module 7 Peripheral Ready */ + +/* SSI Peripheral Ready */ + +#define SYSCON_PRSSI(n) (1 << (n)) /* Bit n: SSI Module n Peripheral Ready */ +# define SYSCON_PRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Peripheral Ready */ +# define SYSCON_PRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Peripheral Ready */ +# define SYSCON_PRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Peripheral Ready */ +# define SYSCON_PRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Peripheral Ready */ + +/* I2C Peripheral Ready */ + +#define SYSCON_PRI2C(n) (1 << (n)) /* Bit n: I2C Module n Peripheral Ready */ +# define SYSCON_PRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Peripheral Ready */ +# define SYSCON_PRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Peripheral Ready */ +# define SYSCON_PRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Peripheral Ready */ +# define SYSCON_PRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Peripheral Ready */ + +/* USB Peripheral Ready */ + +#define SYSCON_PRUSB_R0 (1 << 0) /* Bit 0: USB Module Peripheral Ready */ + +/* CAN Peripheral Ready */ + +#define SYSCON_PRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Peripheral Ready */ + +/* ADC Peripheral Ready */ + +#define SYSCON_PRADC(n) (1 << (n)) /* Bit n: ADC Module n Peripheral Ready */ +# define SYSCON_PRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Peripheral Ready */ +# define SYSCON_PRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Peripheral Ready */ + +/* Analog Comparator Peripheral Ready */ + +#define SYSCON_PRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Peripheral Ready */ + +/* EEPROM Peripheral Ready */ + +#define SYSCON_PREEPROM_0 (1 << 0) /* Bit 0: EEPROM Module Peripheral Ready */ + +/* 2/64-BitWide Timer Peripheral Ready */ + +#define SYSCON_PRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Peripheral Ready */ + +/* System Control Legacy Register Bit Definitions *******************************************/ +/* Device Capabilities 0 */ + +#define SYSCON_DC0_FLASHSZ_SHIFT 0 /* Bits 15-0: FLASH Size */ +#define SYSCON_DC0_FLASHSZ_MASK (0xffff << SYSCON_DC0_FLASHSZ_SHIFT) +#define SYSCON_DC0_SRAMSZ_SHIFT 16 /* Bits 31-16: SRAM Size */ +#define SYSCON_DC0_SRAMSZ_MASK (0xffff << SYSCON_DC0_SRAMSZ_SHIFT) + +/* Device Capabilities 1 */ + +#define SYSCON_DC1_JTAG (1 << 0) /* Bit 0: JTAG Present */ +#define SYSCON_DC1_SWD (1 << 1) /* Bit 1: SWD Present */ +#define SYSCON_DC1_SWO (1 << 2) /* Bit 2: SWO Trace Port Present */ +#define SYSCON_DC1_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Present */ +#define SYSCON_DC1_PLL (1 << 4) /* Bit 4: PLL Present */ +#define SYSCON_DC1_TEMPSNS (1 << 5) /* Bit 5: Temp Sensor Present */ +#define SYSCON_DC1_HIB (1 << 6) /* Bit 6: Hibernation Module Present */ +#define SYSCON_DC1_MPU (1 << 7) /* Bit 7: MPU Present */ +#define SYSCON_DC1_MAXADC0SPD_SHIFT (8) /* Bits 9-8: Max ADC Speed */ +#define SYSCON_DC1_MAXADC0SPD_MASK (3 << SYSCON_DC1_MAXADC0SPD_SHIFT) +#define SYSCON_DC1_MAXADC1SPD_SHIFT (10) /* Bits 10-11: Max ADC Speed */ +#define SYSCON_DC1_MAXADC1SPD_MASK (3 << SYSCON_DC1_MAXADC1SPD_SHIFT) +#define SYSCON_DC1_MINSYSDIV_SHIFT 12 /* Bits 12-15: System Clock Divider Minimum */ +#define SYSCON_DC1_MINSYSDIV_MASK (15 << SYSCON_DC1_MINSYSDIV_SHIFT) +#define SYSCON_DC1_ADC0 (1 << 16) /* Bit 16: ADC0 Module Present */ +#define SYSCON_DC1_ADC1 (1 << 17) /* Bit 17: ADC1 Module Present */ +#define SYSCON_DC1_PWM0 (1 << 20) /* Bit 20: PWM0 Module Present */ +#define SYSCON_DC1_PWM1 (1 << 21) /* Bit 21: PWM1 Module Present */ +#define SYSCON_DC1_CAN0 (1 << 24) /* Bit 24: CAN0 Module Present */ +#define SYSCON_DC1_CAN1 (1 << 25) /* Bit 25: CAN1 Module Present */ +#define SYSCON_DC1_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Present */ + +/* Device Capabilities 2 */ + +#define SYSCON_DC2_UART0 (1 << 0) /* Bit 0: UART0 Module Present */ +#define SYSCON_DC2_UART1 (1 << 1) /* Bit 1: UART1 Module Present */ +#define SYSCON_DC2_UART2 (1 << 2) /* Bit 2: UART2 Module Present */ +#define SYSCON_DC2_SSI0 (1 << 4) /* Bit 4: SSI0 Module Present */ +#define SYSCON_DC2_SSI1 (1 << 5) /* Bit 5: SSI1 Module Present */ +#define SYSCON_DC2_QEI0 (1 << 8) /* Bit 8: QEI0 Module Present */ +#define SYSCON_DC2_QEI1 (1 << 9) /* Bit 9: QEI1 Module Present */ +#define SYSCON_DC2_I2C0 (1 << 12) /* Bit 12: I2C Module 0 Present */ +#define SYSCON_DC2_I2C0HS (1 << 13) /* Bit 13: I2C Module 0 Speed */ +#define SYSCON_DC2_I2C1 (1 << 14) /* Bit 14: I2C Module 1 Present */ +#define SYSCON_DC2_I2C1HS (1 << 15) /* Bit 15: I2C Module 1 Speed */ +#define SYSCON_DC2_TIMER0 (1 << 16) /* Bit 16: Timer 0 Present */ +#define SYSCON_DC2_TIMER1 (1 << 17) /* Bit 17: Timer 1 Present */ +#define SYSCON_DC2_TIMER2 (1 << 18) /* Bit 18: Timer 2 Present */ +#define SYSCON_DC2_TIMER3 (1 << 19) /* Bit 19: Timer 3 Present */ +#define SYSCON_DC2_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Present */ +#define SYSCON_DC2_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Present */ +#define SYSCON_DC2_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Present */ +#define SYSCON_DC2_I2S0 (1 << 28) /* Bit 28: I2S Module 0 Present */ +#define SYSCON_DC2_EPI0 (1 << 30) /* Bit 30: EPI Module 0 Present */ + +/* Device Capabilities 3 */ + +#define SYSCON_DC3_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define SYSCON_DC3_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define SYSCON_DC3_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define SYSCON_DC3_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define SYSCON_DC3_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define SYSCON_DC3_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define SYSCON_DC3_C0MINUS (1 << 6) /* Bit 6: C0- Pin Present */ +#define SYSCON_DC3_C0PLUS (1 << 7) /* Bit 7: C0+ Pin Present */ +#define SYSCON_DC3_C0O (1 << 8) /* Bit 8: C0o Pin Present */ +#define SYSCON_DC3_C1MINUS (1 << 9) /* Bit 9: C1- Pin Present */ +#define SYSCON_DC3_C1PLUS (1 << 10) /* Bit 10: C1+ Pin Present */ +#define SYSCON_DC3_C1O (1 << 11) /* Bit 11: C1o Pin Present */ +#define SYSCON_DC3_C2MINUS (1 << 12) /* Bit 12: C2- Pin Present */ +#define SYSCON_DC3_C2PLUS (1 << 13) /* Bit 13: C2+ Pin Present */ +#define SYSCON_DC3_C2O (1 << 14) /* Bit 14: C2o Pin Present */ +#define SYSCON_DC3_PWMFAULT (1 << 15) /* Bit 15: PWM Fault Pin Pre */ +#define SYSCON_DC3_ADC0AIN0 (1 << 16) /* Bit 16: ADC Module 0 AIN0 Pin Present */ +#define SYSCON_DC3_ADC0AIN1 (1 << 17) /* Bit 17: ADC Module 0 AIN1 Pin Present */ +#define SYSCON_DC3_ADC0AIN2 (1 << 18) /* Bit 18: ADC Module 0 AIN2 Pin Present */ +#define SYSCON_DC3_ADC0AIN3 (1 << 19) /* Bit 19: ADC Module 0 AIN3 Pin Present */ +#define SYSCON_DC3_ADC0AIN4 (1 << 20) /* Bit 20: ADC Module 0 AIN4 Pin Present */ +#define SYSCON_DC3_ADC0AIN5 (1 << 21) /* Bit 21: ADC Module 0 AIN5 Pin Present */ +#define SYSCON_DC3_ADC0AIN6 (1 << 22) /* Bit 22: ADC Module 0 AIN6 Pin Present */ +#define SYSCON_DC3_ADC0AIN7 (1 << 23) /* Bit 23: ADC Module 0 AIN7 Pin Present */ +#define SYSCON_DC3_CCP0 (1 << 24) /* Bit 24: T0CCP0 Pin Present */ +#define SYSCON_DC3_CCP1 (1 << 25) /* Bit 25: T0CCP1 Pin Present */ +#define SYSCON_DC3_CCP2 (1 << 26) /* Bit 26: T1CCP0 Pin Present */ +#define SYSCON_DC3_CCP3 (1 << 27) /* Bit 27: T1CCP1 Pin Present */ +#define SYSCON_DC3_CCP4 (1 << 28) /* Bit 28: T2CCP0 Pin Present */ +#define SYSCON_DC3_CCP5 (1 << 29) /* Bit 29: T2CCP1 Pin Present */ +#define SYSCON_DC3_32KHZ (1 << 31) /* Bit 31: 32KHz Input Clock Available */ + +/* Device Capabilities 4 */ + +#define SYSCON_DC4_GPIO(n) (1 << (n)) +#define SYSCON_DC4_GPIOA (1 << 0) /* Bit 0: GPIO Port A Present */ +#define SYSCON_DC4_GPIOB (1 << 1) /* Bit 1: GPIO Port B Present */ +#define SYSCON_DC4_GPIOC (1 << 2) /* Bit 2: GPIO Port C Present */ +#define SYSCON_DC4_GPIOD (1 << 3) /* Bit 3: GPIO Port D Present */ +#define SYSCON_DC4_GPIOE (1 << 4) /* Bit 4: GPIO Port E Present */ +#define SYSCON_DC4_GPIOF (1 << 5) /* Bit 5: GPIO Port F Present */ +#define SYSCON_DC4_GPIOG (1 << 6) /* Bit 6: GPIO Port G Present */ +#define SYSCON_DC4_GPIOH (1 << 7) /* Bit 7: GPIO Port H Present */ +#define SYSCON_DC4_GPIOJ (1 << 8) /* Bit 8: GPIO Port J Present */ + +#define SYSCON_DC4_ROM (1 << 12) /* Bit 12: Internal Code ROM Present */ +#define SYSCON_DC4_UDMA (1 << 13) /* Bit 13: Micro-DMA Module Present */ +#define SYSCON_DC4_CCP6 (1 << 14) /* Bit 14: T3CCP0 Pin Present */ +#define SYSCON_DC4_CCP7 (1 << 15) /* Bit 15: T3CCP1 Pin Present */ +#define SYSCON_DC4_PICAL (1 << 18) /* Bit 18: PIOSC Calibrate */ +#define SYSCON_DC4_E1588 (1 << 24) /* Bit 24: 1588 Capable */ +#define SYSCON_DC4_EMAC0 (1 << 28) /* Bit 28: Ethernet MAC0 Present */ +#define SYSCON_DC4_EPHY0 (1 << 30) /* Bit 30: Ethernet PHY0 Present */ + +/* Device Capabilities 5 */ + +#define TIVA_SYSCON_DC5_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define TIVA_SYSCON_DC5_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define TIVA_SYSCON_DC5_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define TIVA_SYSCON_DC5_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define TIVA_SYSCON_DC5_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define TIVA_SYSCON_DC5_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define TIVA_SYSCON_DC5_PWM6 (1 << 6) /* Bit 6: PWM6 Pin Present */ +#define TIVA_SYSCON_DC5_PWM7 (1 << 7) /* Bit 7: PWM7 Pin Present */ +#define TIVA_SYSCON_DC5_PWMESYNC (1 << 20) /* Bit 20: PWM Extended SYNC Active */ +#define TIVA_SYSCON_DC5_PWMEFLT (1 << 21) /* Bit 21: PWM Extended Fault Active */ +#define TIVA_SYSCON_DC5_PWMFAULT0 (1 << 24) /* Bit 24: PWM Fault 0 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT1 (1 << 25) /* Bit 25: PWM Fault 1 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT2 (1 << 26) /* Bit 26: PWM Fault 2 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT3 (1 << 27) /* Bit 27: PWM Fault 3 Pin Present */ + +/* Device Capabilities 6 */ + +#define TIVA_SYSCON_DC6_USB0_SHIFT (0) /* Bits 0-1: USB Module 0 Present */ +#define TIVA_SYSCON_DC6_USB0_MASK (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_NONE (1 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_DEVICE (2 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_HOST (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_OTG (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +#define TIVA_SYSCON_DC6_USB0PHY (1 << 4) /* Bit 4: USB Module 0 PHY Present */ + +/* Device Capabilities 7 */ + +#define TIVA_SYSCON_DC7_DMACH0 (1 << 0) /* Bit 0: DMA Channel 0 */ +#define TIVA_SYSCON_DC7_DMACH1 (1 << 1) /* Bit 1: DMA Channel 1 */ +#define TIVA_SYSCON_DC7_DMACH2 (1 << 2) /* Bit 2: DMA Channel 2 */ +#define TIVA_SYSCON_DC7_DMACH3 (1 << 3) /* Bit 3: DMA Channel 3 */ +#define TIVA_SYSCON_DC7_DMACH4 (1 << 4) /* Bit 4: DMA Channel 4 */ +#define TIVA_SYSCON_DC7_DMACH5 (1 << 5) /* Bit 5: DMA Channel 5 */ +#define TIVA_SYSCON_DC7_DMACH6 (1 << 6) /* Bit 6: DMA Channel 6 */ +#define TIVA_SYSCON_DC7_DMACH7 (1 << 7) /* Bit 7: DMA Channel 7 */ +#define TIVA_SYSCON_DC7_DMACH8 (1 << 8) /* Bit 8: DMA Channel 8 */ +#define TIVA_SYSCON_DC7_DMACH9 (1 << 9) /* Bit 9: DMA Channel 9 */ +#define TIVA_SYSCON_DC7_DMACH10 (1 << 10) /* Bit 10: DMA Channel 10 */ +#define TIVA_SYSCON_DC7_DMACH11 (1 << 11) /* Bit 11: DMA Channel 11 */ +#define TIVA_SYSCON_DC7_DMACH12 (1 << 12) /* Bit 12: DMA Channel 12 */ +#define TIVA_SYSCON_DC7_DMACH13 (1 << 13) /* Bit 13: DMA Channel 13 */ +#define TIVA_SYSCON_DC7_DMACH14 (1 << 14) /* Bit 14: DMA Channel 14 */ +#define TIVA_SYSCON_DC7_DMACH15 (1 << 15) /* Bit 15: DMA Channel 15 */ +#define TIVA_SYSCON_DC7_DMACH16 (1 << 16) /* Bit 16: DMA Channel 16 */ +#define TIVA_SYSCON_DC7_DMACH17 (1 << 17) /* Bit 17: DMA Channel 17 */ +#define TIVA_SYSCON_DC7_DMACH18 (1 << 18) /* Bit 18: DMA Channel 18 */ +#define TIVA_SYSCON_DC7_DMACH19 (1 << 19) /* Bit 19: DMA Channel 19 */ +#define TIVA_SYSCON_DC7_DMACH20 (1 << 20) /* Bit 20: DMA Channel 20 */ +#define TIVA_SYSCON_DC7_DMACH21 (1 << 21) /* Bit 21: DMA Channel 21 */ +#define TIVA_SYSCON_DC7_DMACH22 (1 << 22) /* Bit 22: DMA Channel 22 */ +#define TIVA_SYSCON_DC7_DMACH23 (1 << 23) /* Bit 23: DMA Channel 23 */ +#define TIVA_SYSCON_DC7_DMACH24 (1 << 24) /* Bit 24: DMA Channel 24 */ +#define TIVA_SYSCON_DC7_DMACH25 (1 << 25) /* Bit 25: DMA Channel 25 */ +#define TIVA_SYSCON_DC7_DMACH26 (1 << 26) /* Bit 26: DMA Channel 26 */ +#define TIVA_SYSCON_DC7_DMACH27 (1 << 27) /* Bit 27: DMA Channel 27 */ +#define TIVA_SYSCON_DC7_DMACH28 (1 << 28) /* Bit 28: DMA Channel 28 */ +#define TIVA_SYSCON_DC7_DMACH29 (1 << 29) /* Bit 29: DMA Channel 29 */ +#define TIVA_SYSCON_DC7_DMACH30 (1 << 30) /* Bit 30: DMA Channel 30 */ + +/* Device Capabilities 8 */ + +#define TIVA_SYSCON_DC8_ADC0AIN0 (1 << 0) /* Bit 0: ADC Module 0 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN1 (1 << 1) /* Bit 1: ADC Module 0 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN2 (1 << 2) /* Bit 2: ADC Module 0 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN3 (1 << 3) /* Bit 3: ADC Module 0 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN4 (1 << 4) /* Bit 4: ADC Module 0 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN5 (1 << 5) /* Bit 5: ADC Module 0 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN6 (1 << 6) /* Bit 6: ADC Module 0 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN7 (1 << 7) /* Bit 7: ADC Module 0 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN8 (1 << 8) /* Bit 8: ADC Module 0 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN9 (1 << 9) /* Bit 9: ADC Module 0 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN10 (1 << 10) /* Bit 10: ADC Module 0 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN11 (1 << 11) /* Bit 11: ADC Module 0 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN12 (1 << 12) /* Bit 12: ADC Module 0 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN13 (1 << 13) /* Bit 13: ADC Module 0 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN14 (1 << 14) /* Bit 14: ADC Module 0 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN15 (1 << 15) /* Bit 15: ADC Module 0 AIN15 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN0 (1 << 16) /* Bit 16: ADC Module 1 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN1 (1 << 17) /* Bit 17: ADC Module 1 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN2 (1 << 18) /* Bit 18: ADC Module 1 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN3 (1 << 19) /* Bit 19: ADC Module 1 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN4 (1 << 20) /* Bit 20: ADC Module 1 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN5 (1 << 21) /* Bit 21: ADC Module 1 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN6 (1 << 22) /* Bit 22: ADC Module 1 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN7 (1 << 23) /* Bit 23: ADC Module 1 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN8 (1 << 24) /* Bit 24: ADC Module 1 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN9 (1 << 25) /* Bit 25: ADC Module 1 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN10 (1 << 26) /* Bit 26: ADC Module 1 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN11 (1 << 27) /* Bit 27: ADC Module 1 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN12 (1 << 28) /* Bit 28: ADC Module 1 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN13 (1 << 29) /* Bit 29: ADC Module 1 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN14 (1 << 30) /* Bit 30: ADC Module 1 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN15 (1 << 31) /* Bit 31: ADC Module 1 AIN15 Pin Present */ + +/* Software Reset Control 0 */ + +#define SYSCON_SRCR0_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset Control */ +#define SYSCON_SRCR0_HIB (1 << 6) /* Bit 6: Hibernation Module Reset Control */ +#define SYSCON_SRCR0_ADC0 (1 << 16) /* Bit 16: ADC0 Reset Control */ +#define SYSCON_SRCR0_ADC1 (1 << 17) /* Bit 17: ADC1 Reset Control */ +#define SYSCON_SRCR0_CAN0 (1 << 24) /* Bit 24: CAN0 Reset Control */ +#define SYSCON_SRCR0_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Reset Control */ + +/* Software Reset Control 1 */ + +#define SYSCON_SRCR1_UART0 (1 << 0) /* Bit 0: UART0 Reset Control */ +#define SYSCON_SRCR1_UART1 (1 << 1) /* Bit 1: UART1 Reset Control */ +#define SYSCON_SRCR1_UART2 (1 << 2) /* Bit 2: UART2 Reset Control */ +#define SYSCON_SRCR1_SSI0 (1 << 4) /* Bit 4: SSI0 Reset Control */ +#define SYSCON_SRCR1_SSI1 (1 << 5) /* Bit 5: SSI1 Reset Control */ +#define SYSCON_SRCR1_I2C0 (1 << 12) /* Bit 12: I2C 0 Reset Control */ +#define SYSCON_SRCR1_I2C1 (1 << 14) /* Bit 14: I2C 1 Reset Control */ +#define SYSCON_SRCR1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Reset Control */ +#define SYSCON_SRCR1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Reset Control */ +#define SYSCON_SRCR1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Reset Control */ +#define SYSCON_SRCR1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Reset Control */ +#define SYSCON_SRCR1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Reset Control */ +#define SYSCON_SRCR1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Reset Control */ + +/* Software Reset Control 2 */ + +#define SYSCON_SRCR2_GPIO(n) (1 << (n)) +#define SYSCON_SRCR2_GPIOA (1 << 0) /* Bit 0: Port A Reset Control */ +#define SYSCON_SRCR2_GPIOB (1 << 1) /* Bit 1: Port B Reset Control */ +#define SYSCON_SRCR2_GPIOC (1 << 2) /* Bit 2: Port C Reset Control */ +#define SYSCON_SRCR2_GPIOD (1 << 3) /* Bit 3: Port D Reset Control */ +#define SYSCON_SRCR2_GPIOE (1 << 4) /* Bit 4: Port E Reset Control */ +#define SYSCON_SRCR2_GPIOF (1 << 5) /* Bit 5: Port F Reset Control */ +#define SYSCON_SRCR2_UDMA (1 << 13) /* Bit 13: Micro-DMA Reset Control */ +#define SYSCON_SRCR2_USB0 (1 << 16) /* Bit 16: USB0 Reset Control */ + +/* Run Mode Clock Gating Control Register 0 */ + +#define SYSCON_RCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_RCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_RCGC0_MAXADC0SPD_SHIFT (8) /* Bits 8-9: ADC0 Sample Speed */ +#define SYSCON_RCGC0_MAXADC0SPD_MASK (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_125KSPS (0 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_250KSPS (1 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_500KSPS (2 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_1MSPS (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +#define SYSCON_RCGC0_MAXADC1SPD_SHIFT (8) /* Bits 10-11: ADC1 Sample Speed */ +#define SYSCON_RCGC0_MAXADC1SPD_MASK (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_125KSPS (0 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_250KSPS (1 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_500KSPS (2 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_1MSPS (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +#define SYSCON_RCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_RCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_RCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Run Mode Clock Gating Control Register 1 */ + +#define SYSCON_RCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_RCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_RCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_RCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_RCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_RCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_RCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_RCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_RCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Run Mode Clock Gating Control Register 2 */ + +#define SYSCON_RCGC2_GPIO(n) (1 << (n)) +#define SYSCON_RCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_RCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_RCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_RCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_RCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_RCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_RCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_RCGC2_USB0 (1 << 16) /* Bit 16: USB0 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_SCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_SCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_SCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_SCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_SCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_SCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_SCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_SCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_SCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_SCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_SCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_SCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_SCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_SCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_SCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_SCGC2_GPIO(n) (1 << (n)) +#define SYSCON_SCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_SCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_SCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_SCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_SCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_SCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_SCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_SCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_DCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_DCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_DCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_DCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_DCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_DCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_DCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_DCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_DCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_DCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_DCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_DCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_DCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_DCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_DCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ + +/* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_DCGC2_GPIO(n) (1 << (n)) +#define SYSCON_DCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_DCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_DCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_DCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_DCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_DCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_DCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_DCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Device Capabilities */ + +#define TIVA_SYSCON_DC9_ADC0DC0 (1 << 0) /* Bit 0: ADC0 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC0DC1 (1 << 1) /* Bit 1: ADC0 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC0DC2 (1 << 2) /* Bit 2: ADC0 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC0DC3 (1 << 3) /* Bit 3: ADC0 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC0DC4 (1 << 4) /* Bit 4: ADC0 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC0DC5 (1 << 5) /* Bit 5: ADC0 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC0DC6 (1 << 6) /* Bit 6: ADC0 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC0DC7 (1 << 7) /* Bit 7: ADC0 DC7 Present */ +#define TIVA_SYSCON_DC9_ADC1DC0 (1 << 16) /* Bit 16: ADC1 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC1DC1 (1 << 17) /* Bit 17: ADC1 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC1DC2 (1 << 18) /* Bit 18: ADC1 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC1DC3 (1 << 19) /* Bit 19: ADC1 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC1DC4 (1 << 20) /* Bit 20: ADC1 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC1DC5 (1 << 21) /* Bit 21: ADC1 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC1DC6 (1 << 22) /* Bit 22: ADC1 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC1DC7 (1 << 23) /* Bit 23: ADC1 DC7 Present */ + +/* Non-Volatile Memory Information */ + +#define TIVA_SYSCON_NVMSTAT_FWB (1 << 0) /* Bit 0: 32 Word Flash Write Buffer Available */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_LM4F_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/lm4f_vectors.h b/arch/arm/src/tiva/chip/lm4f_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..7d8928fd65f1176339248ebf6cdfcd3ebf8c7311 --- /dev/null +++ b/arch/arm/src/tiva/chip/lm4f_vectors.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/lm4f_vectors.f + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Vectors + ************************************************************************************/ + +/* This file is included by tiva_vectors.S. It provides the macro VECTOR that + * supplies ach Stellaris vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/tiva/lm4f_irq.h. + * tiva_vectors.S will define the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +#if defined(CONFIG_ARCH_CHIP_LM4F120) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 155 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 155 + +# else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +UNUSED(TIVA_RESERVED_25) /* Vector 25: Reserved */ +UNUSED(TIVA_RESERVED_26) /* Vector 26: Reserved */ +UNUSED(TIVA_RESERVED_27) /* Vector 27: Reserved */ +UNUSED(TIVA_RESERVED_28) /* Vector 28: Reserved */ +UNUSED(TIVA_RESERVED_29) /* Vector 29: Reserved */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +VECTOR(tiva_compare0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_compare1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +UNUSED(TIVA_RESERVED_43) /* Vector 43: Reserved */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +UNUSED(TIVA_RESERVED_47) /* Vector 47: Reserved */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: Reserved */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 22: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +UNUSED(TIVA_RESERVED_54) /* Vector 54: Reserved */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 55: CAN 0 */ +UNUSED(TIVA_RESERVED_56) /* Vector 56: Reserved */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +UNUSED(TIVA_RESERVED_58) /* Vector 58: Reserved */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 60: USB */ +UNUSED(TIVA_RESERVED_61) /* Vector 61: Reserved */ +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 62: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR) /* Vector 63: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 64: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 65: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 66: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 67: ADC1 Sequence 3 */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: Reserved */ +UNUSED(TIVA_RESERVED_71) /* Vector 71: Reserved */ +UNUSED(TIVA_RESERVED_72) /* Vector 72: Reserved */ +VECTOR(tiva_ssi2, TIVA_IRQ_SSI2) /* Vector 73: SSI 2 */ +VECTOR(tiva_ssi3, TIVA_IRQ_SSI3) /* Vector 74: SSI 3 */ +VECTOR(tiva_uart3, TIVA_IRQ_UART3) /* Vector 75: UART 3 */ +VECTOR(tiva_uart4, TIVA_IRQ_UART4) /* Vector 76: UART 4 */ +VECTOR(tiva_uart5, TIVA_IRQ_UART5) /* Vector 77: UART 5 */ +VECTOR(tiva_uart6, TIVA_IRQ_UART6) /* Vector 78: UART 6 */ +VECTOR(tiva_uart7, TIVA_IRQ_UART7) /* Vector 79: UART 7 */ + +UNUSED(TIVA_RESERVED_80) /* Vector 80: Reserved */ +UNUSED(TIVA_RESERVED_81) /* Vector 81: Reserved */ +UNUSED(TIVA_RESERVED_82) /* Vector 82: Reserved */ +UNUSED(TIVA_RESERVED_83) /* Vector 83: Reserved */ +VECTOR(tiva_i2c2, TIVA_IRQ_I2C2) /* Vector 84: I2C 2 */ +VECTOR(tiva_i2c3, TIVA_IRQ_I2C3) /* Vector 85: I2C 3 */ +VECTOR(tiva_timer4a, TIVA_IRQ_TIMER4A) /* Vector 86: 16/32-Bit Timer 4 A */ +VECTOR(tiva_timer4b, TIVA_IRQ_TIMER4B) /* Vector 87: 16/32-Bit Timer 4 B */ +UNUSED(TIVA_RESERVED_88) /* Vector 88: Reserved */ +UNUSED(TIVA_RESERVED_89) /* Vector 89: Reserved */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +UNUSED(TIVA_RESERVED_91) /* Vector 91: Reserved */ +UNUSED(TIVA_RESERVED_92) /* Vector 92: Reserved */ +UNUSED(TIVA_RESERVED_93) /* Vector 93: Reserved */ +UNUSED(TIVA_RESERVED_94) /* Vector 94: Reserved */ +UNUSED(TIVA_RESERVED_95) /* Vector 95: Reserved */ +UNUSED(TIVA_RESERVED_96) /* Vector 96: Reserved */ +UNUSED(TIVA_RESERVED_97) /* Vector 97: Reserved */ +UNUSED(TIVA_RESERVED_98) /* Vector 98: Reserved */ +UNUSED(TIVA_RESERVED_99) /* Vector 99: Reserved */ + +UNUSED(TIVA_RESERVED_100) /* Vector 100: Reserved */ +UNUSED(TIVA_RESERVED_101) /* Vector 101: Reserved */ +UNUSED(TIVA_RESERVED_102) /* Vector 102: Reserved */ +UNUSED(TIVA_RESERVED_103) /* Vector 103: Reserved */ +UNUSED(TIVA_RESERVED_104) /* Vector 104: Reserved */ +UNUSED(TIVA_RESERVED_105) /* Vector 105: Reserved */ +UNUSED(TIVA_RESERVED_106) /* Vector 106: Reserved */ +UNUSED(TIVA_RESERVED_107) /* Vector 107: Reserved */ +VECTOR(tiva_timer5a, TIVA_IRQ_TIMER5A) /* Vector 108: 16/32-Bit Timer 5 A */ +VECTOR(tiva_timer5b, TIVA_IRQ_TIMER5B) /* Vector 109: 16/32-Bit Timer 5 B */ + +VECTOR(tiva_wtimer0a, TIVA_IRQ_WTIMER0A) /* Vector 110: 32/64-Bit Timer 0 A */ +VECTOR(tiva_wtimer0b, TIVA_IRQ_WTIMER0B) /* Vector 111: 32/64-Bit Timer 0 B */ +VECTOR(tiva_wtimer1a, TIVA_IRQ_WTIMER1A) /* Vector 112: 32/64-Bit Timer 1 A */ +VECTOR(tiva_wtimer1b, TIVA_IRQ_WTIMER1B) /* Vector 113: 32/64-Bit Timer 1 B */ +VECTOR(tiva_wtimer2a, TIVA_IRQ_WTIMER2A) /* Vector 114: 32/64-Bit Timer 2 A */ +VECTOR(tiva_wtimer2b, TIVA_IRQ_WTIMER2B) /* Vector 115: 32/64-Bit Timer 2 B */ +VECTOR(tiva_wtimer3a, TIVA_IRQ_WTIMER3A) /* Vector 116: 32/64-Bit Timer 3 A */ +VECTOR(tiva_wtimer3b, TIVA_IRQ_WTIMER3B) /* Vector 117: 32/64-Bit Timer 3 B */ +VECTOR(tiva_wtimer4a, TIVA_IRQ_WTIMER4A) /* Vector 118: 32/64-Bit Timer 4 A */ +VECTOR(tiva_WTIMER4B, TIVA_IRQ_WTIMER4B) /* Vector 119: 32/64-Bit Timer 4 B */ + +VECTOR(tiva_wtimer5a, TIVA_IRQ_WTIMER5A) /* Vector 120: 32/64-Bit Timer 5 A */ +VECTOR(tiva_wtimer5b, TIVA_IRQ_WTIMER5B) /* Vector 121: 32/64-Bit Timer 5 B */ +VECTOR(tiva_system, TIVA_IRQ_SYSTEM) /* Vector 122: System Exception (imprecise) */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +UNUSED(TIVA_RESERVED_125) /* Vector 125: Reserved */ +UNUSED(TIVA_RESERVED_126) /* Vector 126: Reserved */ +UNUSED(TIVA_RESERVED_127) /* Vector 127: Reserved */ +UNUSED(TIVA_RESERVED_128) /* Vector 128: Reserved */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +UNUSED(TIVA_RESERVED_130) /* Vector 130: Reserved */ +UNUSED(TIVA_RESERVED_131) /* Vector 131: Reserved */ +UNUSED(TIVA_RESERVED_132) /* Vector 132: Reserved */ +UNUSED(TIVA_RESERVED_133) /* Vector 133: Reserved */ +UNUSED(TIVA_RESERVED_134) /* Vector 134: Reserved */ +UNUSED(TIVA_RESERVED_135) /* Vector 135: Reserved */ +UNUSED(TIVA_RESERVED_136) /* Vector 136: Reserved */ +UNUSED(TIVA_RESERVED_137) /* Vector 137: Reserved */ +UNUSED(TIVA_RESERVED_138) /* Vector 138: Reserved */ +UNUSED(TIVA_RESERVED_139) /* Vector 139: Reserved */ + +UNUSED(TIVA_RESERVED_140) /* Vector 140: Reserved */ +UNUSED(TIVA_RESERVED_141) /* Vector 141: Reserved */ +UNUSED(TIVA_RESERVED_142) /* Vector 142: Reserved */ +UNUSED(TIVA_RESERVED_143) /* Vector 143: Reserved */ +UNUSED(TIVA_RESERVED_144) /* Vector 144: Reserved */ +UNUSED(TIVA_RESERVED_145) /* Vector 145: Reserved */ +UNUSED(TIVA_RESERVED_146) /* Vector 146: Reserved */ +UNUSED(TIVA_RESERVED_147) /* Vector 147: Reserved */ +UNUSED(TIVA_RESERVED_148) /* Vector 148: Reserved */ +UNUSED(TIVA_RESERVED_149) /* Vector 149: Reserved */ + +UNUSED(TIVA_RESERVED_150) /* Vector 150: Reserved */ +UNUSED(TIVA_RESERVED_151) /* Vector 151: Reserved */ +UNUSED(TIVA_RESERVED_152) /* Vector 152: Reserved */ +UNUSED(TIVA_RESERVED_153) /* Vector 153: Reserved */ +UNUSED(TIVA_RESERVED_154) /* Vector 154: Reserved */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#else +# error "Vectors not known for this Stellaris chip" +#endif diff --git a/arch/arm/src/tiva/chip/tiva_adc.h b/arch/arm/src/tiva/chip/tiva_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..2b2dd131d2c50fd47e003bcd04c36ff88125c03e --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_adc.h @@ -0,0 +1,946 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_adc.h + * + * Copyright (C) 2015 Calvin Maguranis. All rights reserved. + * Author: Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ADC_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* ADC register offsets *************************************************************/ + +#define TIVA_ADC_ACTSS_OFFSET 0x000 /* ADC Active Sample Sequencer */ +#define TIVA_ADC_RIS_OFFSET 0x004 /* ADC Raw Interrupt Status */ +#define TIVA_ADC_IM_OFFSET 0x008 /* ADC Interrupt Mask */ +#define TIVA_ADC_ISC_OFFSET 0x00c /* ADC Interrupt Status and Clear */ +#define TIVA_ADC_OSTAT_OFFSET 0x010 /* ADC Overflow Status */ +#define TIVA_ADC_EMUX_OFFSET 0x014 /* ADC Event Multiplexer Select */ +#define TIVA_ADC_USTAT_OFFSET 0x018 /* ADC Underflow Status */ +#define TIVA_ADC_TSSEL_OFFSET 0x01c /* ADC Trigger Source Select */ +#define TIVA_ADC_SSPRI_OFFSET 0x020 /* ADC Sample Sequencer Priority */ +#define TIVA_ADC_SPC_OFFSET 0x024 /* ADC Sample Phase Control */ +#define TIVA_ADC_PSSI_OFFSET 0x028 /* ADC Processor Sample Sequence Initiate */ +#define TIVA_ADC_SAC_OFFSET 0x030 /* ADC Sample Averaging Control */ +#define TIVA_ADC_DCISC_OFFSET 0x034 /* ADC Digital Comparator Interrupt Status and Clear */ +#define TIVA_ADC_CTL_OFFSET 0x038 /* ADC Control */ + +#define TIVA_ADC_SS_BASE 0x040 /* ADC Sample Sequence base address */ +#define TIVA_ADC_SSMUX_OFFSET 0x020 /* ADC Sample Sequence Input Multiplexer Select */ +#define TIVA_ADC_SSCTL_OFFSET 0x004 /* ADC Sample Sequence Control */ +#define TIVA_ADC_SSFIFO_OFFSET 0x008 /* ADC Sample Sequence Result FIFO */ +#define TIVA_ADC_SSFSTAT_OFFSET 0x00c /* ADC Sample Sequence FIFO Status */ +#define TIVA_ADC_SSOP_OFFSET 0x010 /* ADC Sample Sequence Operation */ +#define TIVA_ADC_SSDC_OFFSET 0x014 /* ADC Sample Sequence Digital Comparator Select */ +#define TIVA_ADC_SSEMUX_OFFSET 0x018 /* ADC Sample Sequence Extended Input Multiplexer Select */ +#define TIVA_ADC_SSTSH_OFFSET 0x01c /* ADC Sample Sequence Sample and Hold Time */ + +#define TIVA_ADC_DCRIC_OFFSET 0xd00 /* ADC Digital Comparator Reset Initial Conditions */ +#define TIVA_ADC_DCCTL0_OFFSET 0xe00 /* ADC Digital Comparator Control 0 */ +#define TIVA_ADC_DCCTL1_OFFSET 0xe04 /* ADC Digital Comparator Control 1 */ +#define TIVA_ADC_DCCTL2_OFFSET 0xe08 /* ADC Digital Comparator Control 2 */ +#define TIVA_ADC_DCCTL3_OFFSET 0xe0c /* ADC Digital Comparator Control 3 */ +#define TIVA_ADC_DCCTL4_OFFSET 0xe10 /* ADC Digital Comparator Control 4 */ +#define TIVA_ADC_DCCTL5_OFFSET 0xe14 /* ADC Digital Comparator Control 5 */ +#define TIVA_ADC_DCCTL6_OFFSET 0xe18 /* ADC Digital Comparator Control 6 */ +#define TIVA_ADC_DCCTL7_OFFSET 0xe1c /* ADC Digital Comparator Control 7 */ + +#define TIVA_ADC_DCCMP0_OFFSET 0xe40 /* ADC Digital Comparator Range 0 */ +#define TIVA_ADC_DCCMP1_OFFSET 0xe44 /* ADC Digital Comparator Range 1 */ +#define TIVA_ADC_DCCMP2_OFFSET 0xe48 /* ADC Digital Comparator Range 2 */ +#define TIVA_ADC_DCCMP3_OFFSET 0xe4c /* ADC Digital Comparator Range 3 */ +#define TIVA_ADC_DCCMP4_OFFSET 0xe50 /* ADC Digital Comparator Range 4 */ +#define TIVA_ADC_DCCMP5_OFFSET 0xe54 /* ADC Digital Comparator Range 5 */ +#define TIVA_ADC_DCCMP6_OFFSET 0xe58 /* ADC Digital Comparator Range 6 */ +#define TIVA_ADC_DCCMP7_OFFSET 0xe5c /* ADC Digital Comparator Range 7 */ + +#define TIVA_ADC_PP_OFFSET 0xfc0 /* ADC Peripheral Properties */ +#define TIVA_ADC_PC_OFFSET 0xfc4 /* ADC Peripheral Configuration */ +#define TIVA_ADC_CC_OFFSET 0xfc8 /* ADC Clock Configuration */ + +/* ADC register addresses ***********************************************************/ + +#define TIVA_ADC_BASE(n) (TIVA_ADC0_BASE + (n)*0x01000) +#define TIVA_ADC_SS(n) (TIVA_ADC_SS_BASE + ((n)*TIVA_ADC_SSMUX_OFFSET)) + +#define TIVA_ADC_ACTSS(n) (TIVA_ADC_BASE(n)+TIVA_ADC_ACTSS_OFFSET) /* ADC Active Sample Sequencer */ +#define TIVA_ADC_RIS(n) (TIVA_ADC_BASE(n)+TIVA_ADC_RIS_OFFSET) /* ADC Raw Interrupt Status */ +#define TIVA_ADC_IM(n) (TIVA_ADC_BASE(n)+TIVA_ADC_IM_OFFSET) /* ADC Interrupt Mask */ +#define TIVA_ADC_ISC(n) (TIVA_ADC_BASE(n)+TIVA_ADC_ISC_OFFSET) /* ADC Interrupt Status and Clear */ +#define TIVA_ADC_OSTAT(n) (TIVA_ADC_BASE(n)+TIVA_ADC_OSTAT_OFFSET) /* ADC Overflow Status */ +#define TIVA_ADC_EMUX(n) (TIVA_ADC_BASE(n)+TIVA_ADC_EMUX_OFFSET) /* ADC Event Multiplexer Select */ +#define TIVA_ADC_USTAT(n) (TIVA_ADC_BASE(n)+TIVA_ADC_USTAT_OFFSET) /* ADC Underflow Status */ +#define TIVA_ADC_TSSEL(n) (TIVA_ADC_BASE(n)+TIVA_ADC_TSSEL_OFFSET) /* ADC Trigger Source Select */ +#define TIVA_ADC_SSPRI(n) (TIVA_ADC_BASE(n)+TIVA_ADC_SSPRI_OFFSET) /* ADC Sample Sequencer Priority */ +#define TIVA_ADC_SPC(n) (TIVA_ADC_BASE(n)+TIVA_ADC_SPC_OFFSET) /* ADC Sample Phase Control */ +#define TIVA_ADC_PSSI(n) (TIVA_ADC_BASE(n)+TIVA_ADC_PSSI_OFFSET) /* ADC Processor Sample Sequence Initiate */ +#define TIVA_ADC_SAC(n) (TIVA_ADC_BASE(n)+TIVA_ADC_SAC_OFFSET) /* ADC Sample Averaging Control */ +#define TIVA_ADC_DCISC(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCISC_OFFSET) /* ADC Digital Comparator Interrupt Status and Clear */ +#define TIVA_ADC_CTL(n) (TIVA_ADC_BASE(n)+TIVA_ADC_CTL_OFFSET) /* ADC Control */ + +#define TIVA_ADC_SSMUX(n) TIVA_ADC_SS(n) /* ADC Sample Sequence Input Multiplexer Select */ +#define TIVA_ADC_SSCTL(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSCTL_OFFSET) /* ADC Sample Sequence Control */ +#define TIVA_ADC_SSFIFO(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSFIFO_OFFSET) /* ADC Sample Sequence Result FIFO */ +#define TIVA_ADC_SSFSTAT(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSFSTAT_OFFSET) /* ADC Sample Sequence FIFO Status */ +#define TIVA_ADC_SSOP(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSOP_OFFSET) /* ADC Sample Sequence Operation */ +#define TIVA_ADC_SSDC(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSDC_OFFSET) /* ADC Sample Sequence Digital Comparator Select */ +#define TIVA_ADC_SSEMUX(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSEMUX_OFFSET) /* ADC Sample Sequence Extended Input Multiplexer Select */ +#define TIVA_ADC_SSTSH(n) (TIVA_ADC_SS(n)+TIVA_ADC_SSTSH_OFFSET) /* ADC Sample Sequence Sample and Hold Time */ + +#define TIVA_ADC_DCRIC(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCRIC_OFFSET) /* ADC Digital Comparator Reset Initial Conditions */ +#define TIVA_ADC_DCCTL0(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL0_OFFSET) /* ADC Digital Comparator Control 0 */ +#define TIVA_ADC_DCCTL1(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL1_OFFSET) /* ADC Digital Comparator Control 1 */ +#define TIVA_ADC_DCCTL2(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL2_OFFSET) /* ADC Digital Comparator Control 2 */ +#define TIVA_ADC_DCCTL3(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL3_OFFSET) /* ADC Digital Comparator Control 3 */ +#define TIVA_ADC_DCCTL4(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL4_OFFSET) /* ADC Digital Comparator Control 4 */ +#define TIVA_ADC_DCCTL5(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL5_OFFSET) /* ADC Digital Comparator Control 5 */ +#define TIVA_ADC_DCCTL6(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL6_OFFSET) /* ADC Digital Comparator Control 6 */ +#define TIVA_ADC_DCCTL7(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCTL7_OFFSET) /* ADC Digital Comparator Control 7 */ + +#define TIVA_ADC_DCCMP0(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP0_OFFSET) /* ADC Digital Comparator Range 0 */ +#define TIVA_ADC_DCCMP1(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP1_OFFSET) /* ADC Digital Comparator Range 1 */ +#define TIVA_ADC_DCCMP2(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP2_OFFSET) /* ADC Digital Comparator Range 2 */ +#define TIVA_ADC_DCCMP3(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP3_OFFSET) /* ADC Digital Comparator Range 3 */ +#define TIVA_ADC_DCCMP4(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP4_OFFSET) /* ADC Digital Comparator Range 4 */ +#define TIVA_ADC_DCCMP5(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP5_OFFSET) /* ADC Digital Comparator Range 5 */ +#define TIVA_ADC_DCCMP6(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP6_OFFSET) /* ADC Digital Comparator Range 6 */ +#define TIVA_ADC_DCCMP7(n) (TIVA_ADC_BASE(n)+TIVA_ADC_DCCMP7_OFFSET) /* ADC Digital Comparator Range 7 */ + +/* ADC register address expansion ***************************************************/ + +#define TIVA_ADC0_ACTSS (TIVA_ADC_BASE(0) + TIVA_ADC_ACTSS_OFFSET) /* ADC Active Sample Sequencer */ +#define TIVA_ADC0_RIS (TIVA_ADC_BASE(0) + TIVA_ADC_RIS_OFFSET) /* ADC Raw Interrupt Status */ +#define TIVA_ADC0_IM (TIVA_ADC_BASE(0) + TIVA_ADC_IM_OFFSET) /* ADC Interrupt Mask */ +#define TIVA_ADC0_ISC (TIVA_ADC_BASE(0) + TIVA_ADC_ISC_OFFSET) /* ADC Interrupt Status and Clear */ +#define TIVA_ADC0_OSTAT (TIVA_ADC_BASE(0) + TIVA_ADC_OSTAT_OFFSET) /* ADC Overflow Status */ +#define TIVA_ADC0_EMUX (TIVA_ADC_BASE(0) + TIVA_ADC_EMUX_OFFSET) /* ADC Event Multiplexer Select */ +#define TIVA_ADC0_USTAT (TIVA_ADC_BASE(0) + TIVA_ADC_USTAT_OFFSET) /* ADC Underflow Status */ +#define TIVA_ADC0_TSSEL (TIVA_ADC_BASE(0) + TIVA_ADC_TSSEL_OFFSET) /* ADC Trigger Source Select */ +#define TIVA_ADC0_SSPRI (TIVA_ADC_BASE(0) + TIVA_ADC_SSPRI_OFFSET) /* ADC Sample Sequencer Priority */ +#define TIVA_ADC0_SPC (TIVA_ADC_BASE(0) + TIVA_ADC_SPC_OFFSET) /* ADC Sample Phase Control */ +#define TIVA_ADC0_PSSI (TIVA_ADC_BASE(0) + TIVA_ADC_PSSI_OFFSET) /* ADC Processor Sample Sequence Initiate */ +#define TIVA_ADC0_SAC (TIVA_ADC_BASE(0) + TIVA_ADC_SAC_OFFSET) /* ADC Sample Averaging Control */ +#define TIVA_ADC0_DCISC (TIVA_ADC_BASE(0) + TIVA_ADC_DCISC_OFFSET) /* ADC Digital Comparator Interrupt Status and Clear */ +#define TIVA_ADC0_CTL (TIVA_ADC_BASE(0) + TIVA_ADC_CTL_OFFSET) /* ADC Control */ + +#define TIVA_ADC0_SSMUX0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSMUX(0)) /* ADC Sample Sequence Input Multiplexer Select 0 */ +#define TIVA_ADC0_SSCTL0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSCTL(0)) /* ADC Sample Sequence Control 0 */ +#define TIVA_ADC0_SSFIFO0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFIFO(0)) /* ADC Sample Sequence Result FIFO 0 */ +#define TIVA_ADC0_SSFSTAT0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFSTAT(0)) /* ADC Sample Sequence FIFO 0 Status */ +#define TIVA_ADC0_SSOP0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSOP(0)) /* ADC Sample Sequence 0 Operation */ +#define TIVA_ADC0_SSDC0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSDC(0)) /* ADC Sample Sequence 0 Digital Comparator Select */ +#define TIVA_ADC0_SSEMUX0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSEMUX(0)) /* ADC Sample Sequence Extended Input Multiplexer Select 0 */ +#define TIVA_ADC0_SSTSH0 (TIVA_ADC_BASE(0) + TIVA_ADC_SSTSH(0)) /* ADC Sample Sequence 0 Sample and Hold Time */ + +#define TIVA_ADC0_SSMUX1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSMUX(1)) /* ADC Sample Sequence Input Multiplexer Select 1 */ +#define TIVA_ADC0_SSCTL1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSCTL(1)) /* ADC Sample Sequence Control 1 */ +#define TIVA_ADC0_SSFIFO1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFIFO(1)) /* ADC Sample Sequence Result FIFO 1 */ +#define TIVA_ADC0_SSFSTAT1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFSTAT(1)) /* ADC Sample Sequence FIFO 1 Status */ +#define TIVA_ADC0_SSOP1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSOP(1)) /* ADC Sample Sequence 1 Operation */ +#define TIVA_ADC0_SSDC1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSDC(1)) /* ADC Sample Sequence 1 Digital Comparator Select */ +#define TIVA_ADC0_SSEMUX1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSEMUX(1)) /* ADC Sample Sequence Extended Input Multiplexer Select 1 */ +#define TIVA_ADC0_SSTSH1 (TIVA_ADC_BASE(0) + TIVA_ADC_SSTSH(1)) /* ADC Sample Sequence 1 Sample and Hold Time */ + +#define TIVA_ADC0_SSMUX2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSMUX(2)) /* ADC Sample Sequence Input Multiplexer Select 2 */ +#define TIVA_ADC0_SSCTL2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSCTL(2)) /* ADC Sample Sequence Control 2 */ +#define TIVA_ADC0_SSFIFO2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFIFO(2)) /* ADC Sample Sequence Result FIFO 2 */ +#define TIVA_ADC0_SSFSTAT2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFSTAT(2)) /* ADC Sample Sequence FIFO 2 Status */ +#define TIVA_ADC0_SSOP2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSOP(2)) /* ADC Sample Sequence 2 Operation */ +#define TIVA_ADC0_SSDC2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSDC(2)) /* ADC Sample Sequence 2 Digital Comparator Select */ +#define TIVA_ADC0_SSEMUX2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSEMUX(2)) /* ADC Sample Sequence Extended Input Multiplexer Select 2 */ +#define TIVA_ADC0_SSTSH2 (TIVA_ADC_BASE(0) + TIVA_ADC_SSTSH(2)) /* ADC Sample Sequence 2 Sample and Hold Time */ + +#define TIVA_ADC0_SSMUX3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSMUX(3)) /* ADC Sample Sequence Input Multiplexer Select 3 */ +#define TIVA_ADC0_SSCTL3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSCTL(3)) /* ADC Sample Sequence Control 3 */ +#define TIVA_ADC0_SSFIFO3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFIFO(3)) /* ADC Sample Sequence Result FIFO 3 */ +#define TIVA_ADC0_SSFSTAT3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSFSTAT(3)) /* ADC Sample Sequence FIFO 3 Status */ +#define TIVA_ADC0_SSOP3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSOP(3)) /* ADC Sample Sequence 3 Operation */ +#define TIVA_ADC0_SSDC3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSDC(3)) /* ADC Sample Sequence 3 Digital Comparator Select */ +#define TIVA_ADC0_SSEMUX3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSEMUX(3)) /* ADC Sample Sequence Extended Input Multiplexer Select 3 */ +#define TIVA_ADC0_SSTSH3 (TIVA_ADC_BASE(0) + TIVA_ADC_SSTSH(3)) /* ADC Sample Sequence 3 Sample and Hold Time */ + +#define TIVA_ADC0_DCRIC (TIVA_ADC_BASE(0) + TIVA_ADC_DCRIC_OFFSET) /* ADC Digital Comparator Reset Initial Conditions */ +#define TIVA_ADC0_DCCTL0 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL0_OFFSET) /* ADC Digital Comparator Control 0 */ +#define TIVA_ADC0_DCCTL1 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL1_OFFSET) /* ADC Digital Comparator Control 1 */ +#define TIVA_ADC0_DCCTL2 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL2_OFFSET) /* ADC Digital Comparator Control 2 */ +#define TIVA_ADC0_DCCTL3 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL3_OFFSET) /* ADC Digital Comparator Control 3 */ +#define TIVA_ADC0_DCCTL4 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL4_OFFSET) /* ADC Digital Comparator Control 4 */ +#define TIVA_ADC0_DCCTL5 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL5_OFFSET) /* ADC Digital Comparator Control 5 */ +#define TIVA_ADC0_DCCTL6 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL6_OFFSET) /* ADC Digital Comparator Control 6 */ +#define TIVA_ADC0_DCCTL7 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCTL7_OFFSET) /* ADC Digital Comparator Control 7 */ + +#define TIVA_ADC0_DCCMP0 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP0_OFFSET) /* ADC Digital Comparator Range 0 */ +#define TIVA_ADC0_DCCMP1 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP1_OFFSET) /* ADC Digital Comparator Range 1 */ +#define TIVA_ADC0_DCCMP2 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP2_OFFSET) /* ADC Digital Comparator Range 2 */ +#define TIVA_ADC0_DCCMP3 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP3_OFFSET) /* ADC Digital Comparator Range 3 */ +#define TIVA_ADC0_DCCMP4 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP4_OFFSET) /* ADC Digital Comparator Range 4 */ +#define TIVA_ADC0_DCCMP5 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP5_OFFSET) /* ADC Digital Comparator Range 5 */ +#define TIVA_ADC0_DCCMP6 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP6_OFFSET) /* ADC Digital Comparator Range 6 */ +#define TIVA_ADC0_DCCMP7 (TIVA_ADC_BASE(0) + TIVA_ADC_DCCMP7_OFFSET) /* ADC Digital Comparator Range 7 */ + +#define TIVA_ADC1_ACTSS (TIVA_ADC_BASE(1) + TIVA_ADC_ACTSS_OFFSET) /* ADC Active Sample Sequencer */ +#define TIVA_ADC1_RIS (TIVA_ADC_BASE(1) + TIVA_ADC_RIS_OFFSET) /* ADC Raw Interrupt Status */ +#define TIVA_ADC1_IM (TIVA_ADC_BASE(1) + TIVA_ADC_IM_OFFSET) /* ADC Interrupt Mask */ +#define TIVA_ADC1_ISC (TIVA_ADC_BASE(1) + TIVA_ADC_ISC_OFFSET) /* ADC Interrupt Status and Clear */ +#define TIVA_ADC1_OSTAT (TIVA_ADC_BASE(1) + TIVA_ADC_OSTAT_OFFSET) /* ADC Overflow Status */ +#define TIVA_ADC1_EMUX (TIVA_ADC_BASE(1) + TIVA_ADC_EMUX_OFFSET) /* ADC Event Multiplexer Select */ +#define TIVA_ADC1_USTAT (TIVA_ADC_BASE(1) + TIVA_ADC_USTAT_OFFSET) /* ADC Underflow Status */ +#define TIVA_ADC1_TSSEL (TIVA_ADC_BASE(1) + TIVA_ADC_TSSEL_OFFSET) /* ADC Trigger Source Select */ +#define TIVA_ADC1_SSPRI (TIVA_ADC_BASE(1) + TIVA_ADC_SSPRI_OFFSET) /* ADC Sample Sequencer Priority */ +#define TIVA_ADC1_SPC (TIVA_ADC_BASE(1) + TIVA_ADC_SPC_OFFSET) /* ADC Sample Phase Control */ +#define TIVA_ADC1_PSSI (TIVA_ADC_BASE(1) + TIVA_ADC_PSSI_OFFSET) /* ADC Processor Sample Sequence Initiate */ +#define TIVA_ADC1_SAC (TIVA_ADC_BASE(1) + TIVA_ADC_SAC_OFFSET) /* ADC Sample Averaging Control */ +#define TIVA_ADC1_DCISC (TIVA_ADC_BASE(1) + TIVA_ADC_DCISC_OFFSET) /* ADC Digital Comparator Interrupt Status and Clear */ +#define TIVA_ADC1_CTL (TIVA_ADC_BASE(1) + TIVA_ADC_CTL_OFFSET) /* ADC Control */ + +#define TIVA_ADC1_SSMUX0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSMUX(0)) /* ADC Sample Sequence Input Multiplexer Select 0 */ +#define TIVA_ADC1_SSCTL0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSCTL(0)) /* ADC Sample Sequence Control 0 */ +#define TIVA_ADC1_SSFIFO0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFIFO(0)) /* ADC Sample Sequence Result FIFO 0 */ +#define TIVA_ADC1_SSFSTAT0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFSTAT(0)) /* ADC Sample Sequence FIFO 0 Status */ +#define TIVA_ADC1_SSOP0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSOP(0)) /* ADC Sample Sequence 0 Operation */ +#define TIVA_ADC1_SSDC0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSDC(0)) /* ADC Sample Sequence 0 Digital Comparator Select */ +#define TIVA_ADC1_SSEMUX0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSEMUX(0)) /* ADC Sample Sequence Extended Input Multiplexer Select 0 */ +#define TIVA_ADC1_SSTSH0 (TIVA_ADC_BASE(1) + TIVA_ADC_SSTSH(0)) /* ADC Sample Sequence 0 Sample and Hold Time */ + +#define TIVA_ADC1_SSMUX1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSMUX(1)) /* ADC Sample Sequence Input Multiplexer Select 1 */ +#define TIVA_ADC1_SSCTL1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSCTL(1)) /* ADC Sample Sequence Control 1 */ +#define TIVA_ADC1_SSFIFO1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFIFO(1)) /* ADC Sample Sequence Result FIFO 1 */ +#define TIVA_ADC1_SSFSTAT1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFSTAT(1)) /* ADC Sample Sequence FIFO 1 Status */ +#define TIVA_ADC1_SSOP1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSOP(1)) /* ADC Sample Sequence 1 Operation */ +#define TIVA_ADC1_SSDC1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSDC(1)) /* ADC Sample Sequence 1 Digital Comparator Select */ +#define TIVA_ADC1_SSEMUX1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSEMUX(1)) /* ADC Sample Sequence Extended Input Multiplexer Select 1 */ +#define TIVA_ADC1_SSTSH1 (TIVA_ADC_BASE(1) + TIVA_ADC_SSTSH(1)) /* ADC Sample Sequence 1 Sample and Hold Time */ + +#define TIVA_ADC1_SSMUX2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSMUX(2)) /* ADC Sample Sequence Input Multiplexer Select 2 */ +#define TIVA_ADC1_SSCTL2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSCTL(2)) /* ADC Sample Sequence Control 2 */ +#define TIVA_ADC1_SSFIFO2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFIFO(2)) /* ADC Sample Sequence Result FIFO 2 */ +#define TIVA_ADC1_SSFSTAT2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFSTAT(2)) /* ADC Sample Sequence FIFO 2 Status */ +#define TIVA_ADC1_SSOP2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSOP(2)) /* ADC Sample Sequence 2 Operation */ +#define TIVA_ADC1_SSDC2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSDC(2)) /* ADC Sample Sequence 2 Digital Comparator Select */ +#define TIVA_ADC1_SSEMUX2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSEMUX(2)) /* ADC Sample Sequence Extended Input Multiplexer Select 2 */ +#define TIVA_ADC1_SSTSH2 (TIVA_ADC_BASE(1) + TIVA_ADC_SSTSH(2)) /* ADC Sample Sequence 2 Sample and Hold Time */ + +#define TIVA_ADC1_SSMUX3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSMUX(3)) /* ADC Sample Sequence Input Multiplexer Select 3 */ +#define TIVA_ADC1_SSCTL3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSCTL(3)) /* ADC Sample Sequence Control 3 */ +#define TIVA_ADC1_SSFIFO3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFIFO(3)) /* ADC Sample Sequence Result FIFO 3 */ +#define TIVA_ADC1_SSFSTAT3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSFSTAT(3)) /* ADC Sample Sequence FIFO 3 Status */ +#define TIVA_ADC1_SSOP3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSOP(3)) /* ADC Sample Sequence 3 Operation */ +#define TIVA_ADC1_SSDC3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSDC(3)) /* ADC Sample Sequence 3 Digital Comparator Select */ +#define TIVA_ADC1_SSEMUX3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSEMUX(3)) /* ADC Sample Sequence Extended Input Multiplexer Select 3 */ +#define TIVA_ADC1_SSTSH3 (TIVA_ADC_BASE(1) + TIVA_ADC_SSTSH(3)) /* ADC Sample Sequence 3 Sample and Hold Time */ + +#define TIVA_ADC1_DCRIC (TIVA_ADC_BASE(1) + TIVA_ADC_DCRIC_OFFSET) /* ADC Digital Comparator Reset Initial Conditions */ +#define TIVA_ADC1_DCCTL0 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL0_OFFSET) /* ADC Digital Comparator Control 0 */ +#define TIVA_ADC1_DCCTL1 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL1_OFFSET) /* ADC Digital Comparator Control 1 */ +#define TIVA_ADC1_DCCTL2 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL2_OFFSET) /* ADC Digital Comparator Control 2 */ +#define TIVA_ADC1_DCCTL3 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL3_OFFSET) /* ADC Digital Comparator Control 3 */ +#define TIVA_ADC1_DCCTL4 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL4_OFFSET) /* ADC Digital Comparator Control 4 */ +#define TIVA_ADC1_DCCTL5 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL5_OFFSET) /* ADC Digital Comparator Control 5 */ +#define TIVA_ADC1_DCCTL6 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL6_OFFSET) /* ADC Digital Comparator Control 6 */ +#define TIVA_ADC1_DCCTL7 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCTL7_OFFSET) /* ADC Digital Comparator Control 7 */ + +#define TIVA_ADC1_DCCMP0 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP0_OFFSET) /* ADC Digital Comparator Range 0 */ +#define TIVA_ADC1_DCCMP1 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP1_OFFSET) /* ADC Digital Comparator Range 1 */ +#define TIVA_ADC1_DCCMP2 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP2_OFFSET) /* ADC Digital Comparator Range 2 */ +#define TIVA_ADC1_DCCMP3 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP3_OFFSET) /* ADC Digital Comparator Range 3 */ +#define TIVA_ADC1_DCCMP4 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP4_OFFSET) /* ADC Digital Comparator Range 4 */ +#define TIVA_ADC1_DCCMP5 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP5_OFFSET) /* ADC Digital Comparator Range 5 */ +#define TIVA_ADC1_DCCMP6 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP6_OFFSET) /* ADC Digital Comparator Range 6 */ +#define TIVA_ADC1_DCCMP7 (TIVA_ADC_BASE(1) + TIVA_ADC_DCCMP7_OFFSET) /* ADC Digital Comparator Range 7 */ + +/* ADC register bit settings ********************************************************/ + +/* Bit fields in the TIVA_ADC_ACTSS register. */ + +#define ADC_ACTSS_BUSY 0x00010000 /* ADC Busy */ +#define ADC_ACTSS_ADEN3 0x00000800 /* ADC SS3 DMA Enable */ +#define ADC_ACTSS_ADEN2 0x00000400 /* ADC SS2 DMA Enable */ +#define ADC_ACTSS_ADEN1 0x00000200 /* ADC SS1 DMA Enable */ +#define ADC_ACTSS_ADEN0 0x00000100 /* ADC SS1 DMA Enable */ +#define ADC_ACTSS_ASEN3 0x00000008 /* ADC SS3 Enable */ +#define ADC_ACTSS_ASEN2 0x00000004 /* ADC SS2 Enable */ +#define ADC_ACTSS_ASEN1 0x00000002 /* ADC SS1 Enable */ +#define ADC_ACTSS_ASEN0 0x00000001 /* ADC SS0 Enable */ + +/* Bit fields in the TIVA_ADC_RIS register. */ + +#define ADC_RIS_INRDC 0x00010000 /* Digital Comparator Raw Interrupt Status */ +#define ADC_RIS_DMAINR3 0x00000800 /* SS3 DMA Raw Interrupt Status */ +#define ADC_RIS_DMAINR2 0x00000400 /* SS2 DMA Raw Interrupt Status */ +#define ADC_RIS_DMAINR1 0x00000200 /* SS1 DMA Raw Interrupt Status */ +#define ADC_RIS_DMAINR0 0x00000100 /* SS0 DMA Raw Interrupt Status */ +#define ADC_RIS_INR3 0x00000008 /* SS3 Raw Interrupt Status */ +#define ADC_RIS_INR2 0x00000004 /* SS2 Raw Interrupt Status */ +#define ADC_RIS_INR1 0x00000002 /* SS1 Raw Interrupt Status */ +#define ADC_RIS_INR0 0x00000001 /* SS0 Raw Interrupt Status */ + +/* Bit fields in the TIVA_ADC_IM register. */ + +#define ADC_IM_DCONSS3 0x00080000 /* Digital Comparator Interrupt on SS3 */ +#define ADC_IM_DCONSS2 0x00040000 /* Digital Comparator Interrupt on SS2 */ +#define ADC_IM_DCONSS1 0x00020000 /* Digital Comparator Interrupt on SS1 */ +#define ADC_IM_DCONSS0 0x00010000 /* Digital Comparator Interrupt on SS0 */ +#define ADC_IM_DMAMASK3 0x00000800 /* SS3 DMA Interrupt Mask */ +#define ADC_IM_DMAMASK2 0x00000400 /* SS2 DMA Interrupt Mask */ +#define ADC_IM_DMAMASK1 0x00000200 /* SS1 DMA Interrupt Mask */ +#define ADC_IM_DMAMASK0 0x00000100 /* SS0 DMA Interrupt Mask */ +#define ADC_IM_MASK3 0x00000008 /* SS3 Interrupt Mask */ +#define ADC_IM_MASK2 0x00000004 /* SS2 Interrupt Mask */ +#define ADC_IM_MASK1 0x00000002 /* SS1 Interrupt Mask */ +#define ADC_IM_MASK0 0x00000001 /* SS0 Interrupt Mask */ + +/* Bit fields in the TIVA_ADC_ISC register. */ + +#define ADC_ISC_SSE(n) (1 << ((n)*4)) +#define ADC_ISC_DCIN_SHIFT 20 +# define ADC_ISC_DCINSS3 (0x8) /* Digital Comparator Interrupt Status on SS3 */ +# define ADC_ISC_DCINSS2 (0x4) /* Digital Comparator Interrupt Status on SS2 */ +# define ADC_ISC_DCINSS1 (0x2) /* Digital Comparator Interrupt Status on SS1 */ +# define ADC_ISC_DCINSS0 (0x1) /* Digital Comparator Interrupt Status on SS0 */ +#define ADC_ISC_DMAIN_SHIFT 8 +# define ADC_ISC_DMAIN3 (0x8) /* SS3 DMA Interrupt Status and Clear */ +# define ADC_ISC_DMAIN2 (0x4) /* SS2 DMA Interrupt Status and Clear */ +# define ADC_ISC_DMAIN1 (0x2) /* SS1 DMA Interrupt Status and Clear */ +# define ADC_ISC_DMAIN0 (0x1) /* SS0 DMA Interrupt Status and Clear */ +#define ADC_ISC_IN_SHIFT 0 +# define ADC_ISC_IN3 (0x8) /* SS3 Interrupt Status and Clear */ +# define ADC_ISC_IN2 (0x4) /* SS2 Interrupt Status and Clear */ +# define ADC_ISC_IN1 (0x2) /* SS1 Interrupt Status and Clear */ +# define ADC_ISC_IN0 (0x1) /* SS0 Interrupt Status and Clear */ + +/* Bit fields in the TIVA_ADC_OSTAT register. */ + +#define ADC_OSTAT_OV3 0x00000008 /* SS3 FIFO Overflow */ +#define ADC_OSTAT_OV2 0x00000004 /* SS2 FIFO Overflow */ +#define ADC_OSTAT_OV1 0x00000002 /* SS1 FIFO Overflow */ +#define ADC_OSTAT_OV0 0x00000001 /* SS0 FIFO Overflow */ + +/* Bit fields in the TIVA_ADC_EMUX register. */ + +#define ADC_EMUX_SHIFT(n) (4 * (n)) /* SS EMUX Shift */ +#define ADC_EMUX_MASK(n) (0xF << ADC_EMUX_SHIFT(n)) /* SS EMUX Mask */ +# define ADC_EMUX_PROC (0x0) /* Processor (default) */ +# define ADC_EMUX_COMP0 (0x1) /* Analog Comparator 0 */ +# define ADC_EMUX_COMP1 (0x2) /* Analog Comparator 1 */ +# define ADC_EMUX_COMP2 (0x3) /* Analog Comparator 2 */ +# define ADC_EMUX_EXTERNAL (0x4) /* External (GPIO Pins) */ +# define ADC_EMUX_TIMER (0x5) /* Timer */ +# define ADC_EMUX_PWM0 (0x6) /* PWM generator 0 */ +# define ADC_EMUX_PWM1 (0x7) /* PWM generator 1 */ +# define ADC_EMUX_PWM2 (0x8) /* PWM generator 2 */ +# define ADC_EMUX_PWM3 (0x9) /* PWM generator 3 */ +# define ADC_EMUX_NEVER (0xe) /* Never Trigger */ +# define ADC_EMUX_ALWAYS (0xf) /* Always (continuously sample) */ + +/* Bit fields in the TIVA_ADC_USTAT register. */ + +#define ADC_USTAT_UV3 0x00000008 /* SS3 FIFO Underflow */ +#define ADC_USTAT_UV2 0x00000004 /* SS2 FIFO Underflow */ +#define ADC_USTAT_UV1 0x00000002 /* SS1 FIFO Underflow */ +#define ADC_USTAT_UV0 0x00000001 /* SS0 FIFO Underflow */ + +/* Bit fields in the TIVA_ADC_TSSEL register. */ + +#define ADC_TSSEL_PS_SHIFT(n) (((n)+((n)+1))*4) +#define ADC_TSSEL_PS_MASK(n) (0x3 << ADC_TSSEL_PS_SHIFT((n))) +# define ADC_TSSEL_PS_M (0x3) /* PWM module trigger select */ +# define ADC_TSSEL_PS_0 (0x0) /* Use PWM module 0 */ +# define ADC_TSSEL_PS_1 (0x1) /* Use PWM module 1 */ + +/* Bit fields in the TIVA_ADC_SSPRI register. */ + +#define ADC_SSPRI_SHIFT(n) ((n) * 4) /* SSE priority mask */ +#define ADC_SSPRI_MASK(n) (0x3 << ADC_SSPRI_SHIFT(n)) /* SSE priority mask */ +# define ADC_SSPRI_0 (0x0) /* SSE priority value 0 (highest) */ +# define ADC_SSPRI_1 (0x1) /* SSE priority value 1 (high) */ +# define ADC_SSPRI_2 (0x2) /* SSE priority value 2 (low) */ +# define ADC_SSPRI_3 (0x3) /* SSE priority value 3 (lowest) */ + +/* Bit fields in the TIVA_ADC_SPC register. */ + +#define ADC_SPC_PHASE_MASK 0x0000000F /* Phase Difference */ +#define ADC_SPC_PHASE_0 0x00000000 /* ADC sample lags by 0.0 */ +#define ADC_SPC_PHASE_22_5 0x00000001 /* ADC sample lags by 22.5 */ +#define ADC_SPC_PHASE_45 0x00000002 /* ADC sample lags by 45.0 */ +#define ADC_SPC_PHASE_67_5 0x00000003 /* ADC sample lags by 67.5 */ +#define ADC_SPC_PHASE_90 0x00000004 /* ADC sample lags by 90.0 */ +#define ADC_SPC_PHASE_112_5 0x00000005 /* ADC sample lags by 112.5 */ +#define ADC_SPC_PHASE_135 0x00000006 /* ADC sample lags by 135.0 */ +#define ADC_SPC_PHASE_157_5 0x00000007 /* ADC sample lags by 157.5 */ +#define ADC_SPC_PHASE_180 0x00000008 /* ADC sample lags by 180.0 */ +#define ADC_SPC_PHASE_202_5 0x00000009 /* ADC sample lags by 202.5 */ +#define ADC_SPC_PHASE_225 0x0000000A /* ADC sample lags by 225.0 */ +#define ADC_SPC_PHASE_247_5 0x0000000B /* ADC sample lags by 247.5 */ +#define ADC_SPC_PHASE_270 0x0000000C /* ADC sample lags by 270.0 */ +#define ADC_SPC_PHASE_292_5 0x0000000D /* ADC sample lags by 292.5 */ +#define ADC_SPC_PHASE_315 0x0000000E /* ADC sample lags by 315.0 */ +#define ADC_SPC_PHASE_337_5 0x0000000F /* ADC sample lags by 337.5 */ + +/* Bit fields in the TIVA_ADC_PSSI register. */ + +#define ADC_PSSI_GSYNC 0x80000000 /* Global Synchronize */ +#define ADC_PSSI_SYNCWAIT 0x08000000 /* Synchronize Wait */ + +#define ADC_PSSI_TRIG_MASK 0xf /* Enable triggering mask */ +# define ADC_PSSI_SS3 0x8 /* SS3 Initiate */ +# define ADC_PSSI_SS2 0x4 /* SS2 Initiate */ +# define ADC_PSSI_SS1 0x2 /* SS1 Initiate */ +# define ADC_PSSI_SS0 0x1 /* SS0 Initiate */ + +/* Bit fields in the TIVA_ADC_SAC register. */ + +#define ADC_SAC_AVG_MASK 0x00000007 /* Hardware Averaging Control */ +#define ADC_SAC_AVG_OFF 0x00000000 /* No hardware oversampling */ +#define ADC_SAC_AVG_2X 0x00000001 /* 2x hardware oversampling */ +#define ADC_SAC_AVG_4X 0x00000002 /* 4x hardware oversampling */ +#define ADC_SAC_AVG_8X 0x00000003 /* 8x hardware oversampling */ +#define ADC_SAC_AVG_16X 0x00000004 /* 16x hardware oversampling */ +#define ADC_SAC_AVG_32X 0x00000005 /* 32x hardware oversampling */ +#define ADC_SAC_AVG_64X 0x00000006 /* 64x hardware oversampling */ + +/* Bit fields in the TIVA_ADC_DCISC register. */ + +#define ADC_DCISC_DCINT7 0x00000080 /* Digital Comparator 7 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT6 0x00000040 /* Digital Comparator 6 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT5 0x00000020 /* Digital Comparator 5 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT4 0x00000010 /* Digital Comparator 4 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT3 0x00000008 /* Digital Comparator 3 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT2 0x00000004 /* Digital Comparator 2 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT1 0x00000002 /* Digital Comparator 1 Interrupt Status and Clear */ +#define ADC_DCISC_DCINT0 0x00000001 /* Digital Comparator 0 Interrupt Status and Clear */ + +/* Bit fields in the TIVA_ADC_CTL register. */ + +#define ADC_CTL_VREF_MASK 0x00000003 /* Voltage Reference Select */ +#define ADC_CTL_DITHER 0x00000040 /* Dither Mode Enable */ +#define ADC_CTL_VREF_INTERNAL 0x00000000 /* VDDA and GNDA are the voltage references */ +#define ADC_CTL_VREF_EXT_3V 0x00000001 /* The external VREFA+ and VREFA- inputs are the voltage references */ + +/* Bit fields in the TIVA_ADC_SSMUX register. */ + +#define ADC_SSMUX_MUX_SHIFT(n) ((n)*4) /* nth Sample Input Select */ +#define ADC_SSMUX_MUX_MASK(n) (0xF << ADC_SSMUX_MUX_SHIFT(n)) + +/* Bit fields in the TIVA_ADC_SSCTL register. */ + +#define ADC_SSCTL_SHIFT(n) ((n)*4) +#define ADC_SSCTL_MASK(n) (0xF << ADC_SSCTL_SHIFT((n))) +# define ADC_SSCTL_TS (0x8) /* Sample Temp Sensor Select */ +# define ADC_SSCTL_IE (0x4) /* Sample Interrupt Enable */ +# define ADC_SSCTL_END (0x2) /* Sample is End of Sequence */ +# define ADC_SSCTL_D (0x1) /* Sample Differential Input Select */ + +/* Bit fields in the TIVA_ADC_SSFIFO0 register. */ + +#define ADC_SSFIFO0_DATA_MASK 0x00000FFF /* Conversion Result Data */ +# define ADC_SSFIFO0_DATA_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFSTAT0 register. */ + +#define ADC_SSFSTAT0_HPTR_MASK 0x000000F0 /* FIFO Head Pointer */ +#define ADC_SSFSTAT_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */ +# define ADC_SSFSTAT_HPTR_SHIFT 4 +# define ADC_SSFSTAT_TPTR_SHIFT 0 +#define ADC_SSFSTAT_FULL 0x00001000 /* FIFO Full */ +#define ADC_SSFSTAT_EMPTY 0x00000100 /* FIFO Empty */ + +/* Bit fields in the TIVA_ADC_SSOP0 register. */ + +#define ADC_SSOP0_S7DCOP 0x10000000 /* Sample 7 Digital Comparator Operation */ +#define ADC_SSOP0_S6DCOP 0x01000000 /* Sample 6 Digital Comparator Operation */ +#define ADC_SSOP0_S5DCOP 0x00100000 /* Sample 5 Digital Comparator Operation */ +#define ADC_SSOP0_S4DCOP 0x00010000 /* Sample 4 Digital Comparator Operation */ +#define ADC_SSOP0_S3DCOP 0x00001000 /* Sample 3 Digital Comparator Operation */ +#define ADC_SSOP0_S2DCOP 0x00000100 /* Sample 2 Digital Comparator Operation */ +#define ADC_SSOP0_S1DCOP 0x00000010 /* Sample 1 Digital Comparator Operation */ +#define ADC_SSOP0_S0DCOP 0x00000001 /* Sample 0 Digital Comparator Operation */ + +/* Bit fields in the TIVA_ADC_SSDC0 register. */ + +#define ADC_SSDC0_S7DCSEL_MASK 0xF0000000 /* Sample 7 Digital Comparator Select */ +#define ADC_SSDC0_S6DCSEL_MASK 0x0F000000 /* Sample 6 Digital Comparator Select */ +#define ADC_SSDC0_S5DCSEL_MASK 0x00F00000 /* Sample 5 Digital Comparator Select */ +#define ADC_SSDC0_S4DCSEL_MASK 0x000F0000 /* Sample 4 Digital Comparator Select */ +#define ADC_SSDC0_S3DCSEL_MASK 0x0000F000 /* Sample 3 Digital Comparator Select */ +#define ADC_SSDC0_S2DCSEL_MASK 0x00000F00 /* Sample 2 Digital Comparator Select */ +#define ADC_SSDC0_S1DCSEL_MASK 0x000000F0 /* Sample 1 Digital Comparator Select */ +#define ADC_SSDC0_S0DCSEL_MASK 0x0000000F /* Sample 0 Digital Comparator Select */ +#define ADC_SSDC0_S6DCSEL_SHIFT 24 +#define ADC_SSDC0_S5DCSEL_SHIFT 20 +#define ADC_SSDC0_S4DCSEL_SHIFT 16 +#define ADC_SSDC0_S3DCSEL_SHIFT 12 +#define ADC_SSDC0_S2DCSEL_SHIFT 8 +#define ADC_SSDC0_S1DCSEL_SHIFT 4 +#define ADC_SSDC0_S0DCSEL_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSEMUX register. */ + +#define ADC_SSEMUX_MUX_SHIFT(n) ((n) * 4) /* Sample sequence extended mux n */ +#define ADC_SSEMUX_MUX_MASK(n) (0xF << ADC_SSEMUX_MUX_SHIFT(n)) /* Sample sequence extended mux n mask */ +# define ADC_SSEMUX_MUX_CHN_0_15 (0x0) /* SSE uses channels 0 to 15 */ +# define ADC_SSEMUX_MUX_CHN_16_23 (0x1) /* SSE uses channels 16 to 23 */ + +/* Bit fields in the TIVA_ADC_SSTSH register. */ + +#define ADC_SSTSH_SHIFT(n) ((n) * 4) +#define ADC_SSTSH_MASK(n) (0xf << (ADC_SSTSH_SHIFT(n))) /* nth Sample and Hold Period Select */ +# define ADC_SSTH_SHOLD_4 (0x0) /* Sample and hold 4 ADC clocks */ +# define ADC_SSTH_SHOLD_8 (0x2) /* Sample and hold 8 ADC clocks */ +# define ADC_SSTH_SHOLD_16 (0x4) /* Sample and hold 16 ADC clocks */ +# define ADC_SSTH_SHOLD_32 (0x6) /* Sample and hold 32 ADC clocks */ +# define ADC_SSTH_SHOLD_64 (0x8) /* Sample and hold 64 ADC clocks */ +# define ADC_SSTH_SHOLD_128 (0xa) /* Sample and hold 128 ADC clocks */ +# define ADC_SSTH_SHOLD_256 (0xc) /* Sample and hold 256 ADC clocks */ +# define SSTSH_TSH_TS ADC_SSTH_SHOLD_4 /* Same and hold time for the temp sensor should be at least 16 ADC ticks */ + +/* Bit fields in the TIVA_ADC_SSFIFO1 register. */ + +#define ADC_SSFIFO1_DATA_MASK 0x00000FFF /* Conversion Result Data */ +# define ADC_SSFIFO1_DATA_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFSTAT1 register. */ + +#define ADC_SSFSTAT1_HPTR_MASK 0x000000F0 /* FIFO Head Pointer */ +#define ADC_SSFSTAT1_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */ +# define ADC_SSFSTAT1_HPTR_SHIFT 4 +# define ADC_SSFSTAT1_TPTR_SHIFT 0 +#define ADC_SSFSTAT1_FULL 0x00001000 /* FIFO Full */ +#define ADC_SSFSTAT1_EMPTY 0x00000100 /* FIFO Empty */ + +/* Bit fields in the TIVA_ADC_SSOP1 register. */ + +#define ADC_SSOP1_S3DCOP 0x00001000 /* Sample 3 Digital Comparator Operation */ +#define ADC_SSOP1_S2DCOP 0x00000100 /* Sample 2 Digital Comparator Operation */ +#define ADC_SSOP1_S1DCOP 0x00000010 /* Sample 1 Digital Comparator Operation */ +#define ADC_SSOP1_S0DCOP 0x00000001 /* Sample 0 Digital Comparator Operation */ + +/* Bit fields in the TIVA_ADC_SSDC1 register. */ + +#define ADC_SSDC1_S3DCSEL_MASK 0x0000F000 /* Sample 3 Digital Comparator Select */ +#define ADC_SSDC1_S2DCSEL_MASK 0x00000F00 /* Sample 2 Digital Comparator Select */ +#define ADC_SSDC1_S1DCSEL_MASK 0x000000F0 /* Sample 1 Digital Comparator Select */ +#define ADC_SSDC1_S0DCSEL_MASK 0x0000000F /* Sample 0 Digital Comparator Select */ +# define ADC_SSDC1_S2DCSEL_SHIFT 8 +# define ADC_SSDC1_S1DCSEL_SHIFT 4 +# define ADC_SSDC1_S0DCSEL_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSTSH1 register. */ + +#define ADC_SSTSH1_TSH3_MASK 0x0000F000 /* 4th Sample and Hold Period Select */ +#define ADC_SSTSH1_TSH2_MASK 0x00000F00 /* 3rd Sample and Hold Period Select */ +#define ADC_SSTSH1_TSH1_MASK 0x000000F0 /* 2nd Sample and Hold Period Select */ +#define ADC_SSTSH1_TSH0_MASK 0x0000000F /* 1st Sample and Hold Period Select */ +# define ADC_SSTSH1_TSH3_SHIFT 12 +# define ADC_SSTSH1_TSH2_SHIFT 8 +# define ADC_SSTSH1_TSH1_SHIFT 4 +# define ADC_SSTSH1_TSH0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFIFO2 register. */ + +#define ADC_SSFIFO2_DATA_MASK 0x00000FFF /* Conversion Result Data */ +# define ADC_SSFIFO2_DATA_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFSTAT2 register. */ + +#define ADC_SSFSTAT2_HPTR_MASK 0x000000F0 /* FIFO Head Pointer */ +#define ADC_SSFSTAT2_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */ +# define ADC_SSFSTAT2_HPTR_SHIFT 4 +# define ADC_SSFSTAT2_TPTR_SHIFT 0 +#define ADC_SSFSTAT2_FULL 0x00001000 /* FIFO Full */ +#define ADC_SSFSTAT2_EMPTY 0x00000100 /* FIFO Empty */ + +/* Bit fields in the TIVA_ADC_SSOP2 register. */ + +#define ADC_SSOP2_S3DCOP 0x00001000 /* Sample 3 Digital Comparator Operation */ +#define ADC_SSOP2_S2DCOP 0x00000100 /* Sample 2 Digital Comparator Operation */ +#define ADC_SSOP2_S1DCOP 0x00000010 /* Sample 1 Digital Comparator Operation */ +#define ADC_SSOP2_S0DCOP 0x00000001 /* Sample 0 Digital Comparator Operation */ + +/* Bit fields in the TIVA_ADC_SSDC2 register. */ + +#define ADC_SSDC2_S3DCSEL_MASK 0x0000F000 /* Sample 3 Digital Comparator Select */ +#define ADC_SSDC2_S2DCSEL_MASK 0x00000F00 /* Sample 2 Digital Comparator Select */ +#define ADC_SSDC2_S1DCSEL_MASK 0x000000F0 /* Sample 1 Digital Comparator Select */ +#define ADC_SSDC2_S0DCSEL_MASK 0x0000000F /* Sample 0 Digital Comparator Select */ +# define ADC_SSDC2_S2DCSEL_SHIFT 8 +# define ADC_SSDC2_S1DCSEL_SHIFT 4 +# define ADC_SSDC2_S0DCSEL_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSTSH2 register. */ + +#define ADC_SSTSH2_TSH3_MASK 0x0000F000 /* 4th Sample and Hold Period Select */ +#define ADC_SSTSH2_TSH2_MASK 0x00000F00 /* 3rd Sample and Hold Period Select */ +#define ADC_SSTSH2_TSH1_MASK 0x000000F0 /* 2nd Sample and Hold Period Select */ +#define ADC_SSTSH2_TSH0_MASK 0x0000000F /* 1st Sample and Hold Period Select */ +# define ADC_SSTSH2_TSH3_SHIFT 12 +# define ADC_SSTSH2_TSH2_SHIFT 8 +# define ADC_SSTSH2_TSH1_SHIFT 4 +# define ADC_SSTSH2_TSH0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFIFO3 register. */ + +#define ADC_SSFIFO3_DATA_MASK 0x00000FFF /* Conversion Result Data */ +# define ADC_SSFIFO3_DATA_SHIFT 0 + +/* Bit fields in the TIVA_ADC_SSFSTAT3 register. */ + +#define ADC_SSFSTAT3_HPTR_MASK 0x000000F0 /* FIFO Head Pointer */ +#define ADC_SSFSTAT3_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */ +# define ADC_SSFSTAT3_HPTR_SHIFT 4 +# define ADC_SSFSTAT3_TPTR_SHIFT 0 +#define ADC_SSFSTAT3_FULL 0x00001000 /* FIFO Full */ +#define ADC_SSFSTAT3_EMPTY 0x00000100 /* FIFO Empty */ + +/* Bit fields in the TIVA_ADC_SSOP3 register. */ + +#define ADC_SSOP3_S0DCOP 0x00000001 /* Sample 0 Digital Comparator Operation */ + +/* Bit fields in the TIVA_ADC_SSDC3 register. */ + +#define ADC_SSDC3_S0DCSEL_MASK 0x0000000F /* Sample 0 Digital Comparator Select */ + +/* Bit fields in the TIVA_ADC_SSTSH3 register. */ + +#define ADC_SSTSH3_TSH0_MASK 0x0000000F /* 1st Sample and Hold Period Select */ +# define ADC_SSTSH3_TSH0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCRIC register. */ + +#define ADC_DCRIC_DCTRIG7 0x00800000 /* Digital Comparator Trigger 7 */ +#define ADC_DCRIC_DCTRIG6 0x00400000 /* Digital Comparator Trigger 6 */ +#define ADC_DCRIC_DCTRIG5 0x00200000 /* Digital Comparator Trigger 5 */ +#define ADC_DCRIC_DCTRIG4 0x00100000 /* Digital Comparator Trigger 4 */ +#define ADC_DCRIC_DCTRIG3 0x00080000 /* Digital Comparator Trigger 3 */ +#define ADC_DCRIC_DCTRIG2 0x00040000 /* Digital Comparator Trigger 2 */ +#define ADC_DCRIC_DCTRIG1 0x00020000 /* Digital Comparator Trigger 1 */ +#define ADC_DCRIC_DCTRIG0 0x00010000 /* Digital Comparator Trigger 0 */ +#define ADC_DCRIC_DCINT7 0x00000080 /* Digital Comparator Interrupt 7 */ +#define ADC_DCRIC_DCINT6 0x00000040 /* Digital Comparator Interrupt 6 */ +#define ADC_DCRIC_DCINT5 0x00000020 /* Digital Comparator Interrupt 5 */ +#define ADC_DCRIC_DCINT4 0x00000010 /* Digital Comparator Interrupt 4 */ +#define ADC_DCRIC_DCINT3 0x00000008 /* Digital Comparator Interrupt 3 */ +#define ADC_DCRIC_DCINT2 0x00000004 /* Digital Comparator Interrupt 2 */ +#define ADC_DCRIC_DCINT1 0x00000002 /* Digital Comparator Interrupt 1 */ +#define ADC_DCRIC_DCINT0 0x00000001 /* Digital Comparator Interrupt 0 */ + +/* Bit fields in the TIVA_ADC_DCCTL0 register. */ + +#define ADC_DCCTL0_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL0_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL0_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL0_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL0_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL0_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL0_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL0_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL0_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL0_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL0_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL0_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL0_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL0_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL0_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL0_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL0_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL0_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL0_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL0_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL1 register. */ + +#define ADC_DCCTL1_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL1_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL1_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL1_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL1_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL1_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL1_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL1_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL1_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL1_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL1_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL1_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL1_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL1_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL1_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL1_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL1_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL1_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL1_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL1_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL2 register. */ + +#define ADC_DCCTL2_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL2_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL2_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL2_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL2_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL2_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL2_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL2_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL2_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL2_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL2_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL2_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL2_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL2_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL2_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL2_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL2_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL2_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL2_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL2_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL3 register. */ + +#define ADC_DCCTL3_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL3_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL3_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL3_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL3_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL3_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL3_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL3_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL3_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL3_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL3_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL3_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL3_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL3_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL3_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL3_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL3_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL3_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL3_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL3_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL4 register. */ + +#define ADC_DCCTL4_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL4_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL4_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL4_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL4_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL4_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL4_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL4_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL4_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL4_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL4_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL4_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL4_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL4_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL4_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL4_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL4_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL4_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL4_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL4_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL5 register. */ + +#define ADC_DCCTL5_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL5_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL5_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL5_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL5_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL5_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL5_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL5_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL5_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL5_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL5_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL5_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL5_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL5_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL5_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL5_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL5_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL5_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL5_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL5_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL6 register. */ + +#define ADC_DCCTL6_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL6_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL6_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL6_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL6_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL6_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL6_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL6_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL6_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL6_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL6_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL6_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL6_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL6_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL6_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL6_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL6_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL6_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL6_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL6_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCTL7 register. */ + +#define ADC_DCCTL7_CTC_MASK 0x00000C00 /* Comparison Trigger Condition */ +#define ADC_DCCTL7_CTM_MASK 0x00000300 /* Comparison Trigger Mode */ +#define ADC_DCCTL7_CIC_MASK 0x0000000C /* Comparison Interrupt Condition */ +#define ADC_DCCTL7_CIM_MASK 0x00000003 /* Comparison Interrupt Mode */ +#define ADC_DCCTL7_CTE 0x00001000 /* Comparison Trigger Enable */ +#define ADC_DCCTL7_CTC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL7_CTC_MID 0x00000400 /* Mid Band */ +#define ADC_DCCTL7_CTC_HIGH 0x00000C00 /* High Band */ +#define ADC_DCCTL7_CTM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL7_CTM_ONCE 0x00000100 /* Once */ +#define ADC_DCCTL7_CTM_HALWAYS 0x00000200 /* Hysteresis Always */ +#define ADC_DCCTL7_CTM_HONCE 0x00000300 /* Hysteresis Once */ +#define ADC_DCCTL7_CIE 0x00000010 /* Comparison Interrupt Enable */ +#define ADC_DCCTL7_CIC_LOW 0x00000000 /* Low Band */ +#define ADC_DCCTL7_CIC_MID 0x00000004 /* Mid Band */ +#define ADC_DCCTL7_CIC_HIGH 0x0000000C /* High Band */ +#define ADC_DCCTL7_CIM_ALWAYS 0x00000000 /* Always */ +#define ADC_DCCTL7_CIM_ONCE 0x00000001 /* Once */ +#define ADC_DCCTL7_CIM_HALWAYS 0x00000002 /* Hysteresis Always */ +#define ADC_DCCTL7_CIM_HONCE 0x00000003 /* Hysteresis Once */ + +/* Bit fields in the TIVA_ADC_DCCMP0 register. */ + +#define ADC_DCCMP0_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP0_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP0_COMP1_SHIFT 16 +# define ADC_DCCMP0_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP1 register. */ + +#define ADC_DCCMP1_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP1_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP1_COMP1_SHIFT 16 +# define ADC_DCCMP1_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP2 register. */ + +#define ADC_DCCMP2_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP2_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP2_COMP1_SHIFT 16 +# define ADC_DCCMP2_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP3 register. */ + +#define ADC_DCCMP3_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP3_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP3_COMP1_SHIFT 16 +# define ADC_DCCMP3_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP4 register. */ + +#define ADC_DCCMP4_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP4_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP4_COMP1_SHIFT 16 +# define ADC_DCCMP4_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP5 register. */ + +#define ADC_DCCMP5_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP5_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP5_COMP1_SHIFT 16 +# define ADC_DCCMP5_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP6 register. */ + +#define ADC_DCCMP6_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP6_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP6_COMP1_SHIFT 16 +# define ADC_DCCMP6_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_DCCMP7 register. */ + +#define ADC_DCCMP7_COMP1_MASK 0x0FFF0000 /* Compare 1 */ +#define ADC_DCCMP7_COMP0_MASK 0x00000FFF /* Compare 0 */ +# define ADC_DCCMP7_COMP1_SHIFT 16 +# define ADC_DCCMP7_COMP0_SHIFT 0 + +/* Bit fields in the TIVA_ADC_PP register. */ + +#define ADC_PP_RSL_MASK 0x007C0000 /* Resolution */ +#define ADC_PP_TYPE_MASK 0x00030000 /* ADC Architecture */ +#define ADC_PP_DC_MASK 0x0000FC00 /* Digital Comparator Count */ +#define ADC_PP_CH_MASK 0x000003F0 /* ADC Channel Count */ +#define ADC_PP_MCR_MASK 0x0000000F /* Maximum Conversion Rate */ +#define ADC_PP_MSR_MASK 0x0000000F /* Maximum ADC Sample Rate */ +# define ADC_PP_RSL_SHIFT 18 +# define ADC_PP_DC_SHIFT 10 +# define ADC_PP_CH_SHIFT 4 +#define ADC_PP_APSHT 0x01000000 /* Application-Programmable Sample-and-Hold Time */ +#define ADC_PP_TS 0x00800000 /* Temperature Sensor */ +#define ADC_PP_TYPE_SAR 0x00000000 /* SAR */ +#define ADC_PP_MCR_FULL 0x00000007 /* Full conversion rate (FCONV) as defined by TADC and NSH */ +#define ADC_PP_MSR_125K 0x00000001 /* 125 ksps */ +#define ADC_PP_MSR_250K 0x00000003 /* 250 ksps */ +#define ADC_PP_MSR_500K 0x00000005 /* 500 ksps */ +#define ADC_PP_MSR_1M 0x00000007 /* 1 Msps */ + +/* Bit fields in the TIVA_ADC_PC register. */ + +#define ADC_PC_SR_MASK 0x0000000F /* ADC Sample Rate */ +#define ADC_PC_MCR_MASK 0x0000000F /* Conversion Rate */ +#define ADC_PC_SR_125K 0x00000001 /* 125 ksps */ +#define ADC_PC_SR_250K 0x00000003 /* 250 ksps */ +#define ADC_PC_SR_500K 0x00000005 /* 500 ksps */ +#define ADC_PC_SR_1M 0x00000007 /* 1 Msps */ +#define ADC_PC_MCR_1_8 0x00000001 /* Eighth conversion rate. After a conversion completes, the logic pauses for 112 TADC periods before starting the next conversion */ +#define ADC_PC_MCR_1_4 0x00000003 /* Quarter conversion rate. After a conversion completes, the logic pauses for 48 TADC periods before starting the next conversion */ +#define ADC_PC_MCR_1_2 0x00000005 /* Half conversion rate. After a conversion completes, the logic pauses for 16 TADC periods before starting the next conversion */ +#define ADC_PC_MCR_FULL 0x00000007 /* Full conversion rate (FCONV) as defined by TADC and NSH */ + +/* Bit fields in the TIVA_ADC_CC register. */ + +#define ADC_CC_CLKDIV_MASK (0x3F0) /* PLL VCO Clock Divisor */ +#define ADC_CC_CS_MASK (0x00F) /* ADC Clock Source */ +# define ADC_CC_CLKDIV_SHIFT 4 +#define ADC_CC_CS_SYSPLL (0x000) /* PLL VCO divided by CLKDIV */ +#define ADC_CC_CS_PIOSC (0x001) /* PIOSC */ +#define ADC_CC_CS_MOSC (0x002) /* MOSC */ + +#endif // __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ADC_H diff --git a/arch/arm/src/tiva/chip/tiva_epi.h b/arch/arm/src/tiva/chip/tiva_epi.h new file mode 100644 index 0000000000000000000000000000000000000000..612589ea142ca6093449a8b9829b922aba97cd0c --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_epi.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_epi.h + * + * Copyright (C) 2009-2013 Max Neklyudov. All rights reserved. + * Author: Max Neklyudov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_EPI_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_EPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* External Peripheral Interface Register Offsets ***********************************/ + +#define TIVA_EPI_CFG_OFFSET 0x000 +#define TIVA_EPI_SDRAMCFG_OFFSET 0x010 +#define TIVA_EPI_ADDRMAP_OFFSET 0x01C +#define TIVA_EPI_STAT_OFFSET 0x060 +#define TIVA_EPI_BAUD_OFFSET 0x004 + +/* External Peripheral Interface Register Addresses *********************************/ + +#define TIVA_EPI0_CFG (TIVA_EPI0_BASE + TIVA_EPI_CFG_OFFSET) +#define TIVA_EPI0_SDRAMCFG (TIVA_EPI0_BASE + TIVA_EPI_SDRAMCFG_OFFSET) +#define TIVA_EPI0_ADDRMAP (TIVA_EPI0_BASE + TIVA_EPI_ADDRMAP_OFFSET) +#define TIVA_EPI0_STAT (TIVA_EPI0_BASE + TIVA_EPI_STAT_OFFSET) +#define TIVA_EPI0_BAUD (TIVA_EPI0_BASE + TIVA_EPI_BAUD_OFFSET) + +/* External Peripheral Interface Register Bit Definitions ***************************/ + +/* EPI Configuration (EPICFG), offset 0x000 */ + +#define EPI_CFG_MODE_SHIFT 0 /* Bits 3-0: Mode Select */ +#define EPI_CFG_MODE_MASK (0x1f << EPI_CFG_MODE_SHIFT) +# define EPI_CFG_MODE_SDRAM (0x11 << EPI_CFG_MODE_SHIFT) /* SDRAM + BLKEN */ + +/* EPI Address Map (EPIADDRMAP), offset 0x01C */ + +#define EPI_ADDRMAP_ERADR_SHIFT 0 /* Bits 1-0: External RAM Address */ +#define EPI_ADDRMAP_ERADR_MASK (0x3 << EPI_ADDRMAP_ERADR_SHIFT) +# define EPI_ADDRMAP_ERADR_6 (0x1 << EPI_ADDRMAP_ERADR_SHIFT) +# define EPI_ADDRMAP_ERADR_8 (0x2 << EPI_ADDRMAP_ERADR_SHIFT) +#define EPI_ADDRMAP_ERSZ_SHIFT 2 /* Bits 3-2: External RAM Size */ +#define EPI_ADDRMAP_ERSZ_MASK (0x3 << EPI_ADDRMAP_ERSZ_SHIFT) +# define EPI_ADDRMAP_ERSZ_256B (0x0 << EPI_ADDRMAP_ERSZ_SHIFT) +# define EPI_ADDRMAP_ERSZ_64KB (0x1 << EPI_ADDRMAP_ERSZ_SHIFT) +# define EPI_ADDRMAP_ERSZ_16MB (0x2 << EPI_ADDRMAP_ERSZ_SHIFT) +# define EPI_ADDRMAP_ERSZ_512MB (0x3 << EPI_ADDRMAP_ERSZ_SHIFT) + +/* EPI Status (EPISTAT), offset 0x060 */ + +#define EPI_STAT_INITSEQ_SHIFT 6 /* Bits 6: Initialization Sequence */ +#define EPI_STAT_INITSEQ_MASK (0x1 << EPI_STAT_INITSEQ_SHIFT) + +/* EPI SDRAM Configuration (EPISDRAMCFG), offset 0x010 */ + +#define EPI_SDRAMCFG_SIZE_SHIFT 0 /* Bits 1-0: Size of SDRAM */ +#define EPI_SDRAMCFG_SIZE_MASK (3 << EPI_SDRAMCFG_SIZE_SHIFT) +# define EPI_SDRAMCFG_SIZE_8MB (0x0 << EPI_SDRAMCFG_SIZE_SHIFT) +# define EPI_SDRAMCFG_SIZE_16MB (0x1 << EPI_SDRAMCFG_SIZE_SHIFT) +# define EPI_SDRAMCFG_SIZE_32MB (0x2 << EPI_SDRAMCFG_SIZE_SHIFT) +# define EPI_SDRAMCFG_SIZE_64MB (0x3 << EPI_SDRAMCFG_SIZE_SHIFT) +#define EPI_SDRAMCFG_RFSH_SHIFT 16 /* Bits 26-16: Refresh Counter */ +#define EPI_SDRAMCFG_RFSH_MASK (0x7FF << EPI_SDRAMCFG_RFSH_SHIFT) +# define EPI_SDRAMCFG_RFSH(n) ((n) << EPI_SDRAMCFG_RFSH_SHIFT) +#define EPI_SDRAMCFG_FREQ_SHIFT 30 /* EPI Frequency Range */ +#define EPI_SDRAMCFG_FREQ_MASK (3 << EPI_SDRAMCFG_FREQ_SHIFT) +# define EPI_SDRAMCFG_FREQ_0_15MHZ (0x0 << EPI_SDRAMCFG_FREQ_SHIFT) +# define EPI_SDRAMCFG_FREQ_15_30MHZ (0x1 << EPI_SDRAMCFG_FREQ_SHIFT) +# define EPI_SDRAMCFG_FREQ_30_50MHZ (0x2 << EPI_SDRAMCFG_FREQ_SHIFT) +# define EPI_SDRAMCFG_FREQ_50_100MHZ (0x3 << EPI_SDRAMCFG_FREQ_SHIFT) + +/* EPI Main Baud Rate (EPIBAUD), offset 0x004 */ + +#define EPI_BAUD_COUNT0_SHIFT 0 +#define EPI_BAUD_COUNT0_MASK (0xFFFF << EPI_BAUD_COUNT0_SHIFT) +# define EPI_BAUD_COUNT0(n) ((n) << EPI_BAUD_COUNT0_SHIFT) + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_EPI_H */ diff --git a/arch/arm/src/tiva/chip/tiva_ethernet.h b/arch/arm/src/tiva/chip/tiva_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..7ed993b4da5398333036e5c9808baeb7dcdcc325 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_ethernet.h @@ -0,0 +1,51 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_ethernet.h + * + * Copyright (C) 2009-2010, 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ETHERNET_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# include "chip/tm4c_ethernet.h" +#elif defined(CONFIG_ARCH_CHIP_LM3S) +# include "chip/lm3s_ethernet.h" +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ETHERNET_H */ diff --git a/arch/arm/src/tiva/chip/tiva_flash.h b/arch/arm/src/tiva/chip/tiva_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..42c68807572062893234be1b57fe91546e384c9c --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_flash.h @@ -0,0 +1,56 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_flash.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_FLASH_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* The TM4C129 family has a different FLASH register layout */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# include "chip/tm4c_flash.h" + +/* Others (including LM4F and TM4C123) are similar to the LM3S family */ + +#else +# include "chip/lm3s_flash.h" +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_FLASH_H */ diff --git a/arch/arm/src/tiva/chip/tiva_gpio.h b/arch/arm/src/tiva/chip/tiva_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..c19856e4226231be8c5a490a7c8cf15cb567674e --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_gpio.h @@ -0,0 +1,1211 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_gpio.h + * + * Copyright (C) 2009-2010, 2013 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Jose Pablo Carballo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_GPIO_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* REVISIT: Why do we not use the AHB aperture for all GPIO accesses? */ + +#define TIVA_GPIOK_BASE TIVA_GPIOKAHB_BASE +#define TIVA_GPIOL_BASE TIVA_GPIOLAHB_BASE +#define TIVA_GPIOM_BASE TIVA_GPIOMAHB_BASE +#define TIVA_GPION_BASE TIVA_GPIONAHB_BASE +#define TIVA_GPIOP_BASE TIVA_GPIOPAHB_BASE +#define TIVA_GPIOQ_BASE TIVA_GPIOQAHB_BASE +#define TIVA_GPIOR_BASE TIVA_GPIORAHB_BASE +#define TIVA_GPIOS_BASE TIVA_GPIOSAHB_BASE +#define TIVA_GPIOT_BASE TIVA_GPIOTAHB_BASE + +/* GPIO Register Offsets ************************************************************/ + +#define TIVA_GPIO_DATA_OFFSET 0x0000 /* GPIO Data */ +#define TIVA_GPIO_DIR_OFFSET 0x0400 /* GPIO Direction */ +#define TIVA_GPIO_IS_OFFSET 0x0404 /* GPIO Interrupt Sense */ +#define TIVA_GPIO_IBE_OFFSET 0x0408 /* GPIO Interrupt Both Edges */ +#define TIVA_GPIO_IEV_OFFSET 0x040c /* GPIO Interrupt Event */ +#define TIVA_GPIO_IM_OFFSET 0x0410 /* GPIO Interrupt Mask */ +#define TIVA_GPIO_RIS_OFFSET 0x0414 /* GPIO Raw Interrupt Status */ +#define TIVA_GPIO_MIS_OFFSET 0x0418 /* GPIO Masked Interrupt Status */ +#define TIVA_GPIO_ICR_OFFSET 0x041c /* GPIO Interrupt Clear */ +#define TIVA_GPIO_AFSEL_OFFSET 0x0420 /* GPIO Alternate Function */ +#define TIVA_GPIO_DR2R_OFFSET 0x0500 /* Select GPIO 2-mA Drive Select */ +#define TIVA_GPIO_DR4R_OFFSET 0x0504 /* GPIO 4-mA Drive Select */ +#define TIVA_GPIO_DR8R_OFFSET 0x0508 /* GPIO 8-mA Drive Select */ +#define TIVA_GPIO_ODR_OFFSET 0x050c /* GPIO Open Drain Select */ +#define TIVA_GPIO_PUR_OFFSET 0x0510 /* GPIO Pull-Up Select */ +#define TIVA_GPIO_PDR_OFFSET 0x0514 /* GPIO Pull-Down Select */ +#define TIVA_GPIO_SLR_OFFSET 0x0518 /* GPIO Slew Rate Control Select */ +#define TIVA_GPIO_DEN_OFFSET 0x051c /* GPIO Digital Enable */ +#define TIVA_GPIO_LOCK_OFFSET 0x0520 /* GPIO Lock */ +#define TIVA_GPIO_CR_OFFSET 0x0524 /* GPIO Commit */ + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIO_AMSEL_OFFSET 0x0528 /* GPIO Analog Mode Select */ +# define TIVA_GPIO_PCTL_OFFSET 0x052c /* GPIO Port Control */ +# define TIVA_GPIO_ADCCTL_OFFSET 0x0530 /* GPIO ADC Control */ +# define TIVA_GPIO_DMACTL_OFFSET 0x0534 /* GPIO DMA Control */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIO_SI_OFFSET 0x0538 /* GPIO Select Interrupt */ +# define TIVA_GPIO_DR12R_OFFSET 0x053c /* GPIO 12-mA Drive Select */ +# define TIVA_GPIO_WAKEPEN_OFFSET 0x0540 /* GPIO Wake Pin Enable */ +# define TIVA_GPIO_WAKELVL_OFFSET 0x0544 /* GPIO Wake Level */ +# define TIVA_GPIO_WAKESTAT_OFFSET 0x0548 /* GPIO Wake Status */ + +# define TIVA_GPIO_PP_OFFSET 0x0fc0 /* GPIO Peripheral Property */ +# define TIVA_GPIO_PC_OFFSET 0x0fc4 /* GPIO Peripheral Configuration */ +#endif + +#define TIVA_GPIO_PERIPHID4_OFFSET 0x0fd0 /* GPIO Peripheral Identification 4 */ +#define TIVA_GPIO_PERIPHID5_OFFSET 0x0fd4 /* GPIO Peripheral Identification 5 */ +#define TIVA_GPIO_PERIPHID6_OFFSET 0x0fd8 /* GPIO Peripheral Identification 6 */ +#define TIVA_GPIO_PERIPHID7_OFFSET 0x0fdc /* GPIO Peripheral Identification 7 */ +#define TIVA_GPIO_PERIPHID0_OFFSET 0x0fe0 /* GPIO Peripheral Identification 0 */ +#define TIVA_GPIO_PERIPHID1_OFFSET 0x0fe4 /* GPIO Peripheral Identification 1 */ +#define TIVA_GPIO_PERIPHID2_OFFSET 0x0fe8 /* GPIO Peripheral Identification 2 */ +#define TIVA_GPIO_PERIPHID3_OFFSET 0x0fec /* GPIO Peripheral Identification 3 */ +#define TIVA_GPIO_PCELLID0_OFFSET 0x0ff0 /* GPIO PrimeCell Identification 0 */ +#define TIVA_GPIO_PCELLID1_OFFSET 0x0ff4 /* GPIO PrimeCell Identification 1 */ +#define TIVA_GPIO_PCELLID2_OFFSET 0x0ff8 /* GPIO PrimeCell Identification 2 */ +#define TIVA_GPIO_PCELLID3_OFFSET 0x0ffc /* GPIO PrimeCell Identification 3*/ + +/* GPIO Register Addresses **********************************************************/ + +#if TIVA_NPORTS > 0 + +# define TIVA_GPIOA_DATA (TIVA_GPIOA_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOA_DIR (TIVA_GPIOA_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOA_IS (TIVA_GPIOA_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOA_IBE (TIVA_GPIOA_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOA_IEV (TIVA_GPIOA_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOA_IM (TIVA_GPIOA_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOA_RIS (TIVA_GPIOA_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOA_MIS (TIVA_GPIOA_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOA_ICR (TIVA_GPIOA_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOA_AFSEL (TIVA_GPIOA_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOA_DR2R (TIVA_GPIOA_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOA_DR4R (TIVA_GPIOA_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOA_DR8R (TIVA_GPIOA_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOA_ODR (TIVA_GPIOA_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOA_PUR (TIVA_GPIOA_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOA_PDR (TIVA_GPIOA_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOA_SLR (TIVA_GPIOA_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOA_DEN (TIVA_GPIOA_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOA_LOCK (TIVA_GPIOA_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOA_CR (TIVA_GPIOA_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOA_AMSEL (TIVA_GPIOA_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOA_PCTL (TIVA_GPIOA_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOA_ADCCTL (TIVA_GPIOA_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOA_DMACTL (TIVA_GPIOA_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOA_SI (TIVA_GPIOA_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOA_DR12R (TIVA_GPIOA_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOA_WAKEPEN (TIVA_GPIOA_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOA_WAKELVL (TIVA_GPIOA_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOA_WAKESTAT (TIVA_GPIOA_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOA_PP (TIVA_GPIOA_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOA_PC (TIVA_GPIOA_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOA_PERIPHID4 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOA_PERIPHID5 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOA_PERIPHID6 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOA_PERIPHID7 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOA_PERIPHID0 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOA_PERIPHID1 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOA_PERIPHID2 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOA_PERIPHID3 (TIVA_GPIOA_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOA_PCELLID0 (TIVA_GPIOA_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOA_PCELLID1 (TIVA_GPIOA_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOA_PCELLID2 (TIVA_GPIOA_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOA_PCELLID3 (TIVA_GPIOA_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 1 + +# define TIVA_GPIOB_DATA (TIVA_GPIOB_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOB_DIR (TIVA_GPIOB_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOB_IS (TIVA_GPIOB_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOB_IBE (TIVA_GPIOB_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOB_IEV (TIVA_GPIOB_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOB_IM (TIVA_GPIOB_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOB_RIS (TIVA_GPIOB_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOB_MIS (TIVA_GPIOB_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOB_ICR (TIVA_GPIOB_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOB_AFSEL (TIVA_GPIOB_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOB_DR2R (TIVA_GPIOB_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOB_DR4R (TIVA_GPIOB_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOB_DR8R (TIVA_GPIOB_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOB_ODR (TIVA_GPIOB_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOB_PUR (TIVA_GPIOB_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOB_PDR (TIVA_GPIOB_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOB_SLR (TIVA_GPIOB_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOB_DEN (TIVA_GPIOB_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOB_LOCK (TIVA_GPIOB_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOB_CR (TIVA_GPIOB_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOB_AMSEL (TIVA_GPIOB_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOB_PCTL (TIVA_GPIOB_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOB_ADCCTL (TIVA_GPIOB_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOB_DMACTL (TIVA_GPIOB_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOB_SI (TIVA_GPIOB_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOB_DR12R (TIVA_GPIOB_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOB_WAKEPEN (TIVA_GPIOB_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOB_WAKELVL (TIVA_GPIOB_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOB_WAKESTAT (TIVA_GPIOB_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOB_PP (TIVA_GPIOB_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOB_PC (TIVA_GPIOB_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOB_PERIPHID4 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOB_PERIPHID5 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOB_PERIPHID6 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOB_PERIPHID7 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOB_PERIPHID0 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOB_PERIPHID1 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOB_PERIPHID2 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOB_PERIPHID3 (TIVA_GPIOB_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOB_PCELLID0 (TIVA_GPIOB_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOB_PCELLID1 (TIVA_GPIOB_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOB_PCELLID2 (TIVA_GPIOB_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOB_PCELLID3 (TIVA_GPIOB_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 2 + +# define TIVA_GPIOC_DATA (TIVA_GPIOC_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOC_DIR (TIVA_GPIOC_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOC_IS (TIVA_GPIOC_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOC_IBE (TIVA_GPIOC_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOC_IEV (TIVA_GPIOC_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOC_IM (TIVA_GPIOC_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOC_RIS (TIVA_GPIOC_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOC_MIS (TIVA_GPIOC_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOC_ICR (TIVA_GPIOC_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOC_AFSEL (TIVA_GPIOC_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOC_DR2R (TIVA_GPIOC_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOC_DR4R (TIVA_GPIOC_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOC_DR8R (TIVA_GPIOC_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOC_ODR (TIVA_GPIOC_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOC_PUR (TIVA_GPIOC_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOC_PDR (TIVA_GPIOC_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOC_SLR (TIVA_GPIOC_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOC_DEN (TIVA_GPIOC_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOC_LOCK (TIVA_GPIOC_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOC_CR (TIVA_GPIOC_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOC_AMSEL (TIVA_GPIOC_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOC_PCTL (TIVA_GPIOC_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOC_ADCCTL (TIVA_GPIOC_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOC_DMACTL (TIVA_GPIOC_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOC_SI (TIVA_GPIOC_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOC_DR12R (TIVA_GPIOC_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOC_WAKEPEN (TIVA_GPIOC_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOC_WAKELVL (TIVA_GPIOC_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOC_WAKESTAT (TIVA_GPIOC_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOC_PP (TIVA_GPIOC_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOC_PC (TIVA_GPIOC_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOC_PERIPHID4 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOC_PERIPHID5 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOC_PERIPHID6 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOC_PERIPHID7 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOC_PERIPHID0 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOC_PERIPHID1 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOC_PERIPHID2 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOC_PERIPHID3 (TIVA_GPIOC_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOC_PCELLID0 (TIVA_GPIOC_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOC_PCELLID1 (TIVA_GPIOC_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOC_PCELLID2 (TIVA_GPIOC_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOC_PCELLID3 (TIVA_GPIOC_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 3 + +# define TIVA_GPIOD_DATA (TIVA_GPIOD_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOD_DIR (TIVA_GPIOD_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOD_IS (TIVA_GPIOD_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOD_IBE (TIVA_GPIOD_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOD_IEV (TIVA_GPIOD_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOD_IM (TIVA_GPIOD_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOD_RIS (TIVA_GPIOD_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOD_MIS (TIVA_GPIOD_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOD_ICR (TIVA_GPIOD_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOD_AFSEL (TIVA_GPIOD_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOD_DR2R (TIVA_GPIOD_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOD_DR4R (TIVA_GPIOD_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOD_DR8R (TIVA_GPIOD_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOD_ODR (TIVA_GPIOD_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOD_PUR (TIVA_GPIOD_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOD_PDR (TIVA_GPIOD_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOD_SLR (TIVA_GPIOD_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOD_DEN (TIVA_GPIOD_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOD_LOCK (TIVA_GPIOD_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOD_CR (TIVA_GPIOD_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOD_AMSEL (TIVA_GPIOD_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOD_PCTL (TIVA_GPIOD_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOD_ADCCTL (TIVA_GPIOD_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOD_DMACTL (TIVA_GPIOD_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOD_SI (TIVA_GPIOD_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOD_DR12R (TIVA_GPIOD_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOD_WAKEPEN (TIVA_GPIOD_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOD_WAKELVL (TIVA_GPIOD_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOD_WAKESTAT (TIVA_GPIOD_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOD_PP (TIVA_GPIOD_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOD_PC (TIVA_GPIOD_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOD_PERIPHID4 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOD_PERIPHID5 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOD_PERIPHID6 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOD_PERIPHID7 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOD_PERIPHID0 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOD_PERIPHID1 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOD_PERIPHID2 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOD_PERIPHID3 (TIVA_GPIOD_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOD_PCELLID0 (TIVA_GPIOD_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOD_PCELLID1 (TIVA_GPIOD_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOD_PCELLID2 (TIVA_GPIOD_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOD_PCELLID3 (TIVA_GPIOD_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 4 + +# define TIVA_GPIOE_DATA (TIVA_GPIOE_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOE_DIR (TIVA_GPIOE_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOE_IS (TIVA_GPIOE_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOE_IBE (TIVA_GPIOE_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOE_IEV (TIVA_GPIOE_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOE_IM (TIVA_GPIOE_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOE_RIS (TIVA_GPIOE_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOE_MIS (TIVA_GPIOE_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOE_ICR (TIVA_GPIOE_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOE_AFSEL (TIVA_GPIOE_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOE_DR2R (TIVA_GPIOE_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOE_DR4R (TIVA_GPIOE_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOE_DR8R (TIVA_GPIOE_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOE_ODR (TIVA_GPIOE_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOE_PUR (TIVA_GPIOE_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOE_PDR (TIVA_GPIOE_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOE_SLR (TIVA_GPIOE_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOE_DEN (TIVA_GPIOE_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOE_LOCK (TIVA_GPIOE_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOE_CR (TIVA_GPIOE_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOE_AMSEL (TIVA_GPIOE_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOE_PCTL (TIVA_GPIOE_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOE_ADCCTL (TIVA_GPIOE_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOE_DMACTL (TIVA_GPIOE_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOE_SI (TIVA_GPIOE_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOE_DR12R (TIVA_GPIOE_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOE_WAKEPEN (TIVA_GPIOE_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOE_WAKELVL (TIVA_GPIOE_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOE_WAKESTAT (TIVA_GPIOE_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOE_PP (TIVA_GPIOE_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOE_PC (TIVA_GPIOE_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOE_PERIPHID4 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOE_PERIPHID5 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOE_PERIPHID6 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOE_PERIPHID7 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOE_PERIPHID0 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOE_PERIPHID1 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOE_PERIPHID2 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOE_PERIPHID3 (TIVA_GPIOE_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOE_PCELLID0 (TIVA_GPIOE_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOE_PCELLID1 (TIVA_GPIOE_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOE_PCELLID2 (TIVA_GPIOE_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOE_PCELLID3 (TIVA_GPIOE_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 5 + +# define TIVA_GPIOF_DATA (TIVA_GPIOF_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOF_DIR (TIVA_GPIOF_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOF_IS (TIVA_GPIOF_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOF_IBE (TIVA_GPIOF_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOF_IEV (TIVA_GPIOF_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOF_IM (TIVA_GPIOF_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOF_RIS (TIVA_GPIOF_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOF_MIS (TIVA_GPIOF_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOF_ICR (TIVA_GPIOF_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOF_AFSEL (TIVA_GPIOF_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOF_DR2R (TIVA_GPIOF_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOF_DR4R (TIVA_GPIOF_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOF_DR8R (TIVA_GPIOF_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOF_ODR (TIVA_GPIOF_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOF_PUR (TIVA_GPIOF_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOF_PDR (TIVA_GPIOF_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOF_SLR (TIVA_GPIOF_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOF_DEN (TIVA_GPIOF_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOF_LOCK (TIVA_GPIOF_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOF_CR (TIVA_GPIOF_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOF_AMSEL (TIVA_GPIOF_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOF_PCTL (TIVA_GPIOF_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOF_ADCCTL (TIVA_GPIOF_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOF_DMACTL (TIVA_GPIOF_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOF_SI (TIVA_GPIOF_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOF_DR12R (TIVA_GPIOF_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOF_WAKEPEN (TIVA_GPIOF_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOF_WAKELVL (TIVA_GPIOF_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOF_WAKESTAT (TIVA_GPIOF_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOF_PP (TIVA_GPIOF_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOF_PC (TIVA_GPIOF_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOF_PERIPHID4 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOF_PERIPHID5 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOF_PERIPHID6 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOF_PERIPHID7 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOF_PERIPHID0 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOF_PERIPHID1 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOF_PERIPHID2 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOF_PERIPHID3 (TIVA_GPIOF_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOF_PCELLID0 (TIVA_GPIOF_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOF_PCELLID1 (TIVA_GPIOF_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOF_PCELLID2 (TIVA_GPIOF_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOF_PCELLID3 (TIVA_GPIOF_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 6 + +# define TIVA_GPIOG_DATA (TIVA_GPIOG_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOG_DIR (TIVA_GPIOG_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOG_IS (TIVA_GPIOG_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOG_IBE (TIVA_GPIOG_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOG_IEV (TIVA_GPIOG_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOG_IM (TIVA_GPIOG_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOG_RIS (TIVA_GPIOG_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOG_MIS (TIVA_GPIOG_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOG_ICR (TIVA_GPIOG_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOG_AFSEL (TIVA_GPIOG_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOG_DR2R (TIVA_GPIOG_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOG_DR4R (TIVA_GPIOG_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOG_DR8R (TIVA_GPIOG_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOG_ODR (TIVA_GPIOG_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOG_PUR (TIVA_GPIOG_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOG_PDR (TIVA_GPIOG_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOG_SLR (TIVA_GPIOG_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOG_DEN (TIVA_GPIOG_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOG_LOCK (TIVA_GPIOG_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOG_CR (TIVA_GPIOG_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOG_AMSEL (TIVA_GPIOG_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOG_PCTL (TIVA_GPIOG_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOG_ADCCTL (TIVA_GPIOG_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOG_DMACTL (TIVA_GPIOG_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOG_SI (TIVA_GPIOG_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOG_DR12R (TIVA_GPIOG_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOG_WAKEPEN (TIVA_GPIOG_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOG_WAKELVL (TIVA_GPIOG_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOG_WAKESTAT (TIVA_GPIOG_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOG_PP (TIVA_GPIOG_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOG_PC (TIVA_GPIOG_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOG_PERIPHID4 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOG_PERIPHID5 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOG_PERIPHID6 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOG_PERIPHID7 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOG_PERIPHID0 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOG_PERIPHID1 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOG_PERIPHID2 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOG_PERIPHID3 (TIVA_GPIOG_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOG_PCELLID0 (TIVA_GPIOG_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOG_PCELLID1 (TIVA_GPIOG_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOG_PCELLID2 (TIVA_GPIOG_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOG_PCELLID3 (TIVA_GPIOG_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 7 + +# define TIVA_GPIOH_DATA (TIVA_GPIOH_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOH_DIR (TIVA_GPIOH_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOH_IS (TIVA_GPIOH_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOH_IBE (TIVA_GPIOH_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOH_IEV (TIVA_GPIOH_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOH_IM (TIVA_GPIOH_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOH_RIS (TIVA_GPIOH_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOH_MIS (TIVA_GPIOH_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOH_ICR (TIVA_GPIOH_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOH_AFSEL (TIVA_GPIOH_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOH_DR2R (TIVA_GPIOH_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOH_DR4R (TIVA_GPIOH_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOH_DR8R (TIVA_GPIOH_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOH_ODR (TIVA_GPIOH_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOH_PUR (TIVA_GPIOH_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOH_PDR (TIVA_GPIOH_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOH_SLR (TIVA_GPIOH_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOH_DEN (TIVA_GPIOH_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOH_LOCK (TIVA_GPIOH_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOH_CR (TIVA_GPIOH_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOH_AMSEL (TIVA_GPIOH_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOH_PCTL (TIVA_GPIOH_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOH_ADCCTL (TIVA_GPIOH_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOH_DMACTL (TIVA_GPIOH_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOH_SI (TIVA_GPIOH_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOH_DR12R (TIVA_GPIOH_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOH_WAKEPEN (TIVA_GPIOH_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOH_WAKELVL (TIVA_GPIOH_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOH_WAKESTAT (TIVA_GPIOH_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOH_PP (TIVA_GPIOH_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOH_PC (TIVA_GPIOH_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOH_PERIPHID4 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOH_PERIPHID5 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOH_PERIPHID6 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOH_PERIPHID7 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOH_PERIPHID0 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOH_PERIPHID1 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOH_PERIPHID2 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOH_PERIPHID3 (TIVA_GPIOH_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOH_PCELLID0 (TIVA_GPIOH_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOH_PCELLID1 (TIVA_GPIOH_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOH_PCELLID2 (TIVA_GPIOH_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOH_PCELLID3 (TIVA_GPIOH_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 8 + +# define TIVA_GPIOJ_DATA (TIVA_GPIOJ_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOJ_DIR (TIVA_GPIOJ_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOJ_IS (TIVA_GPIOJ_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOJ_IBE (TIVA_GPIOJ_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOJ_IEV (TIVA_GPIOJ_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOJ_IM (TIVA_GPIOJ_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOJ_RIS (TIVA_GPIOJ_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOJ_MIS (TIVA_GPIOJ_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOJ_ICR (TIVA_GPIOJ_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOJ_AFSEL (TIVA_GPIOJ_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOJ_DR2R (TIVA_GPIOJ_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOJ_DR4R (TIVA_GPIOJ_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOJ_DR8R (TIVA_GPIOJ_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOJ_ODR (TIVA_GPIOJ_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOJ_PUR (TIVA_GPIOJ_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOJ_PDR (TIVA_GPIOJ_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOJ_SLR (TIVA_GPIOJ_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOJ_DEN (TIVA_GPIOJ_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOJ_LOCK (TIVA_GPIOJ_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOJ_CR (TIVA_GPIOJ_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOJ_AMSEL (TIVA_GPIOJ_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOJ_PCTL (TIVA_GPIOJ_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOJ_ADCCTL (TIVA_GPIOJ_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOJ_DMACTL (TIVA_GPIOJ_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOJ_SI (TIVA_GPIOJ_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOJ_DR12R (TIVA_GPIOJ_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOJ_WAKEPEN (TIVA_GPIOJ_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOJ_WAKELVL (TIVA_GPIOJ_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOJ_WAKESTAT (TIVA_GPIOJ_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOJ_PP (TIVA_GPIOJ_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOJ_PC (TIVA_GPIOJ_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOJ_PERIPHID4 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOJ_PERIPHID5 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOJ_PERIPHID6 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOJ_PERIPHID7 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOJ_PERIPHID0 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOJ_PERIPHID1 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOJ_PERIPHID2 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOJ_PERIPHID3 (TIVA_GPIOJ_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOJ_PCELLID0 (TIVA_GPIOJ_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOJ_PCELLID1 (TIVA_GPIOJ_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOJ_PCELLID2 (TIVA_GPIOJ_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOJ_PCELLID3 (TIVA_GPIOJ_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 9 + +# define TIVA_GPIOK_DATA (TIVA_GPIOK_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOK_DIR (TIVA_GPIOK_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOK_IS (TIVA_GPIOK_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOK_IBE (TIVA_GPIOK_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOK_IEV (TIVA_GPIOK_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOK_IM (TIVA_GPIOK_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOK_RIS (TIVA_GPIOK_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOK_MIS (TIVA_GPIOK_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOK_ICR (TIVA_GPIOK_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOK_AFSEL (TIVA_GPIOK_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOK_DR2R (TIVA_GPIOK_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOK_DR4R (TIVA_GPIOK_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOK_DR8R (TIVA_GPIOK_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOK_ODR (TIVA_GPIOK_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOK_PUR (TIVA_GPIOK_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOK_PDR (TIVA_GPIOK_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOK_SLR (TIVA_GPIOK_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOK_DEN (TIVA_GPIOK_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOK_LOCK (TIVA_GPIOK_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOK_CR (TIVA_GPIOK_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOK_AMSEL (TIVA_GPIOK_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOK_PCTL (TIVA_GPIOK_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOK_ADCCTL (TIVA_GPIOK_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOK_DMACTL (TIVA_GPIOK_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOK_SI (TIVA_GPIOK_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOK_DR12R (TIVA_GPIOK_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOK_WAKEPEN (TIVA_GPIOK_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOK_WAKELVL (TIVA_GPIOK_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOK_WAKESTAT (TIVA_GPIOK_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOK_PP (TIVA_GPIOK_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOK_PC (TIVA_GPIOK_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOK_PERIPHID4 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOK_PERIPHID5 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOK_PERIPHID6 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOK_PERIPHID7 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOK_PERIPHID0 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOK_PERIPHID1 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOK_PERIPHID2 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOK_PERIPHID3 (TIVA_GPIOK_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOK_PCELLID0 (TIVA_GPIOK_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOK_PCELLID1 (TIVA_GPIOK_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOK_PCELLID2 (TIVA_GPIOK_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOK_PCELLID3 (TIVA_GPIOK_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 10 + +# define TIVA_GPIOL_DATA (TIVA_GPIOL_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOL_DIR (TIVA_GPIOL_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOL_IS (TIVA_GPIOL_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOL_IBE (TIVA_GPIOL_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOL_IEV (TIVA_GPIOL_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOL_IM (TIVA_GPIOL_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOL_RIS (TIVA_GPIOL_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOL_MIS (TIVA_GPIOL_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOL_ICR (TIVA_GPIOL_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOL_AFSEL (TIVA_GPIOL_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOL_DR2R (TIVA_GPIOL_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOL_DR4R (TIVA_GPIOL_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOL_DR8R (TIVA_GPIOL_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOL_ODR (TIVA_GPIOL_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOL_PUR (TIVA_GPIOL_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOL_PDR (TIVA_GPIOL_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOL_SLR (TIVA_GPIOL_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOL_DEN (TIVA_GPIOL_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOL_LOCK (TIVA_GPIOL_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOL_CR (TIVA_GPIOL_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOL_AMSEL (TIVA_GPIOL_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOL_PCTL (TIVA_GPIOL_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOL_ADCCTL (TIVA_GPIOL_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOL_DMACTL (TIVA_GPIOL_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOL_SI (TIVA_GPIOL_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOL_DR12R (TIVA_GPIOL_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOL_WAKEPEN (TIVA_GPIOL_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOL_WAKELVL (TIVA_GPIOL_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOL_WAKESTAT (TIVA_GPIOL_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOL_PP (TIVA_GPIOL_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOL_PC (TIVA_GPIOL_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOL_PERIPHID4 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOL_PERIPHID5 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOL_PERIPHID6 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOL_PERIPHID7 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOL_PERIPHID0 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOL_PERIPHID1 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOL_PERIPHID2 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOL_PERIPHID3 (TIVA_GPIOL_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOL_PCELLID0 (TIVA_GPIOL_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOL_PCELLID1 (TIVA_GPIOL_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOL_PCELLID2 (TIVA_GPIOL_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOL_PCELLID3 (TIVA_GPIOL_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 11 + +# define TIVA_GPIOM_DATA (TIVA_GPIOM_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOM_DIR (TIVA_GPIOM_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOM_IS (TIVA_GPIOM_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOM_IBE (TIVA_GPIOM_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOM_IEV (TIVA_GPIOM_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOM_IM (TIVA_GPIOM_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOM_RIS (TIVA_GPIOM_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOM_MIS (TIVA_GPIOM_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOM_ICR (TIVA_GPIOM_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOM_AFSEL (TIVA_GPIOM_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOM_DR2R (TIVA_GPIOM_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOM_DR4R (TIVA_GPIOM_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOM_DR8R (TIVA_GPIOM_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOM_ODR (TIVA_GPIOM_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOM_PUR (TIVA_GPIOM_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOM_PDR (TIVA_GPIOM_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOM_SLR (TIVA_GPIOM_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOM_DEN (TIVA_GPIOM_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOM_LOCK (TIVA_GPIOM_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOM_CR (TIVA_GPIOM_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOM_AMSEL (TIVA_GPIOM_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOM_PCTL (TIVA_GPIOM_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOM_ADCCTL (TIVA_GPIOM_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOM_DMACTL (TIVA_GPIOM_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOM_SI (TIVA_GPIOM_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOM_DR12R (TIVA_GPIOM_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOM_WAKEPEN (TIVA_GPIOM_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOM_WAKELVL (TIVA_GPIOM_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOM_WAKESTAT (TIVA_GPIOM_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOM_PP (TIVA_GPIOM_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOM_PC (TIVA_GPIOM_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOM_PERIPHID4 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOM_PERIPHID5 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOM_PERIPHID6 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOM_PERIPHID7 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOM_PERIPHID0 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOM_PERIPHID1 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOM_PERIPHID2 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOM_PERIPHID3 (TIVA_GPIOM_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOM_PCELLID0 (TIVA_GPIOM_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOM_PCELLID1 (TIVA_GPIOM_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOM_PCELLID2 (TIVA_GPIOM_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOM_PCELLID3 (TIVA_GPIOM_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 12 + +# define TIVA_GPION_DATA (TIVA_GPION_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPION_DIR (TIVA_GPION_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPION_IS (TIVA_GPION_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPION_IBE (TIVA_GPION_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPION_IEV (TIVA_GPION_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPION_IM (TIVA_GPION_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPION_RIS (TIVA_GPION_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPION_MIS (TIVA_GPION_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPION_ICR (TIVA_GPION_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPION_AFSEL (TIVA_GPION_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPION_DR2R (TIVA_GPION_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPION_DR4R (TIVA_GPION_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPION_DR8R (TIVA_GPION_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPION_ODR (TIVA_GPION_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPION_PUR (TIVA_GPION_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPION_PDR (TIVA_GPION_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPION_SLR (TIVA_GPION_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPION_DEN (TIVA_GPION_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPION_LOCK (TIVA_GPION_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPION_CR (TIVA_GPION_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPION_AMSEL (TIVA_GPION_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPION_PCTL (TIVA_GPION_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPION_ADCCTL (TIVA_GPION_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPION_DMACTL (TIVA_GPION_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPION_SI (TIVA_GPION_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPION_DR12R (TIVA_GPION_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPION_WAKEPEN (TIVA_GPION_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPION_WAKELVL (TIVA_GPION_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPION_WAKESTAT (TIVA_GPION_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPION_PP (TIVA_GPION_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPION_PC (TIVA_GPION_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPION_PERIPHID4 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPION_PERIPHID5 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPION_PERIPHID6 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPION_PERIPHID7 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPION_PERIPHID0 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPION_PERIPHID1 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPION_PERIPHID2 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPION_PERIPHID3 (TIVA_GPION_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPION_PCELLID0 (TIVA_GPION_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPION_PCELLID1 (TIVA_GPION_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPION_PCELLID2 (TIVA_GPION_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPION_PCELLID3 (TIVA_GPION_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 13 + +# define TIVA_GPIOP_DATA (TIVA_GPIOP_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOP_DIR (TIVA_GPIOP_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOP_IS (TIVA_GPIOP_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOP_IBE (TIVA_GPIOP_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOP_IEV (TIVA_GPIOP_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOP_IM (TIVA_GPIOP_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOP_RIS (TIVA_GPIOP_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOP_MIS (TIVA_GPIOP_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOP_ICR (TIVA_GPIOP_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOP_AFSEL (TIVA_GPIOP_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOP_DR2R (TIVA_GPIOP_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOP_DR4R (TIVA_GPIOP_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOP_DR8R (TIVA_GPIOP_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOP_ODR (TIVA_GPIOP_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOP_PUR (TIVA_GPIOP_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOP_PDR (TIVA_GPIOP_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOP_SLR (TIVA_GPIOP_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOP_DEN (TIVA_GPIOP_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOP_LOCK (TIVA_GPIOP_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOP_CR (TIVA_GPIOP_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOP_AMSEL (TIVA_GPIOP_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOP_PCTL (TIVA_GPIOP_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOP_ADCCTL (TIVA_GPIOP_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOP_DMACTL (TIVA_GPIOP_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOP_SI (TIVA_GPIOP_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOP_DR12R (TIVA_GPIOP_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOP_WAKEPEN (TIVA_GPIOP_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOP_WAKELVL (TIVA_GPIOP_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOP_WAKESTAT (TIVA_GPIOP_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOP_PP (TIVA_GPIOP_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOP_PC (TIVA_GPIOP_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOP_PERIPHID4 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOP_PERIPHID5 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOP_PERIPHID6 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOP_PERIPHID7 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOP_PERIPHID0 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOP_PERIPHID1 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOP_PERIPHID2 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOP_PERIPHID3 (TIVA_GPIOP_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOP_PCELLID0 (TIVA_GPIOP_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOP_PCELLID1 (TIVA_GPIOP_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOP_PCELLID2 (TIVA_GPIOP_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOP_PCELLID3 (TIVA_GPIOP_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 14 + +# define TIVA_GPIOQ_DATA (TIVA_GPIOQ_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOQ_DIR (TIVA_GPIOQ_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOQ_IS (TIVA_GPIOQ_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOQ_IBE (TIVA_GPIOQ_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOQ_IEV (TIVA_GPIOQ_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOQ_IM (TIVA_GPIOQ_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOQ_RIS (TIVA_GPIOQ_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOQ_MIS (TIVA_GPIOQ_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOQ_ICR (TIVA_GPIOQ_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOQ_AFSEL (TIVA_GPIOQ_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOQ_DR2R (TIVA_GPIOQ_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOQ_DR4R (TIVA_GPIOQ_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOQ_DR8R (TIVA_GPIOQ_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOQ_ODR (TIVA_GPIOQ_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOQ_PUR (TIVA_GPIOQ_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOQ_PDR (TIVA_GPIOQ_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOQ_SLR (TIVA_GPIOQ_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOQ_DEN (TIVA_GPIOQ_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOQ_LOCK (TIVA_GPIOQ_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOQ_CR (TIVA_GPIOQ_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOQ_AMSEL (TIVA_GPIOQ_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOQ_PCTL (TIVA_GPIOQ_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOQ_ADCCTL (TIVA_GPIOQ_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOQ_DMACTL (TIVA_GPIOQ_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOQ_SI (TIVA_GPIOQ_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOQ_DR12R (TIVA_GPIOQ_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOQ_WAKEPEN (TIVA_GPIOQ_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOQ_WAKELVL (TIVA_GPIOQ_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOQ_WAKESTAT (TIVA_GPIOQ_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOQ_PP (TIVA_GPIOQ_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOQ_PC (TIVA_GPIOQ_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOQ_PERIPHID4 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOQ_PERIPHID5 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOQ_PERIPHID6 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOQ_PERIPHID7 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOQ_PERIPHID0 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOQ_PERIPHID1 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOQ_PERIPHID2 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOQ_PERIPHID3 (TIVA_GPIOQ_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOQ_PCELLID0 (TIVA_GPIOQ_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOQ_PCELLID1 (TIVA_GPIOQ_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOQ_PCELLID2 (TIVA_GPIOQ_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOQ_PCELLID3 (TIVA_GPIOQ_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 15 + +# define TIVA_GPIOR_DATA (TIVA_GPIOR_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOR_DIR (TIVA_GPIOR_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOR_IS (TIVA_GPIOR_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOR_IBE (TIVA_GPIOR_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOR_IEV (TIVA_GPIOR_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOR_IM (TIVA_GPIOR_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOR_RIS (TIVA_GPIOR_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOR_MIS (TIVA_GPIOR_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOR_ICR (TIVA_GPIOR_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOR_AFSEL (TIVA_GPIOR_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOR_DR2R (TIVA_GPIOR_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOR_DR4R (TIVA_GPIOR_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOR_DR8R (TIVA_GPIOR_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOR_ODR (TIVA_GPIOR_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOR_PUR (TIVA_GPIOR_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOR_PDR (TIVA_GPIOR_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOR_SLR (TIVA_GPIOR_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOR_DEN (TIVA_GPIOR_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOR_LOCK (TIVA_GPIOR_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOR_CR (TIVA_GPIOR_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOR_AMSEL (TIVA_GPIOR_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOR_PCTL (TIVA_GPIOR_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOR_ADCCTL (TIVA_GPIOR_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOR_DMACTL (TIVA_GPIOR_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOR_SI (TIVA_GPIOR_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOR_DR12R (TIVA_GPIOR_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOR_WAKEPEN (TIVA_GPIOR_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOR_WAKELVL (TIVA_GPIOR_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOR_WAKESTAT (TIVA_GPIOR_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOR_PP (TIVA_GPIOR_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOR_PC (TIVA_GPIOR_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOR_PERIPHID4 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOR_PERIPHID5 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOR_PERIPHID6 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOR_PERIPHID7 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOR_PERIPHID0 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOR_PERIPHID1 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOR_PERIPHID2 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOR_PERIPHID3 (TIVA_GPIOR_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOR_PCELLID0 (TIVA_GPIOR_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOR_PCELLID1 (TIVA_GPIOR_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOR_PCELLID2 (TIVA_GPIOR_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOR_PCELLID3 (TIVA_GPIOR_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 16 + +# define TIVA_GPIOS_DATA (TIVA_GPIOS_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOS_DIR (TIVA_GPIOS_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOS_IS (TIVA_GPIOS_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOS_IBE (TIVA_GPIOS_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOS_IEV (TIVA_GPIOS_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOS_IM (TIVA_GPIOS_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOS_RIS (TIVA_GPIOS_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOS_MIS (TIVA_GPIOS_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOS_ICR (TIVA_GPIOS_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOS_AFSEL (TIVA_GPIOS_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOS_DR2R (TIVA_GPIOS_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOS_DR4R (TIVA_GPIOS_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOS_DR8R (TIVA_GPIOS_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOS_ODR (TIVA_GPIOS_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOS_PUR (TIVA_GPIOS_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOS_PDR (TIVA_GPIOS_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOS_SLR (TIVA_GPIOS_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOS_DEN (TIVA_GPIOS_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOS_LOCK (TIVA_GPIOS_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOS_CR (TIVA_GPIOS_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOS_AMSEL (TIVA_GPIOS_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOS_PCTL (TIVA_GPIOS_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOS_ADCCTL (TIVA_GPIOS_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOS_DMACTL (TIVA_GPIOS_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOS_SI (TIVA_GPIOS_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOS_DR12R (TIVA_GPIOS_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOS_WAKEPEN (TIVA_GPIOS_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOS_WAKELVL (TIVA_GPIOS_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOS_WAKESTAT (TIVA_GPIOS_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOS_PP (TIVA_GPIOS_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOS_PC (TIVA_GPIOS_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOS_PERIPHID4 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOS_PERIPHID5 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOS_PERIPHID6 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOS_PERIPHID7 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOS_PERIPHID0 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOS_PERIPHID1 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOS_PERIPHID2 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOS_PERIPHID3 (TIVA_GPIOS_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOS_PCELLID0 (TIVA_GPIOS_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOS_PCELLID1 (TIVA_GPIOS_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOS_PCELLID2 (TIVA_GPIOS_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOS_PCELLID3 (TIVA_GPIOS_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +#if TIVA_NPORTS > 17 + +# define TIVA_GPIOT_DATA (TIVA_GPIOT_BASE + TIVA_GPIO_DATA_OFFSET) +# define TIVA_GPIOT_DIR (TIVA_GPIOT_BASE + TIVA_GPIO_DIR_OFFSET) +# define TIVA_GPIOT_IS (TIVA_GPIOT_BASE + TIVA_GPIO_IS_OFFSET) +# define TIVA_GPIOT_IBE (TIVA_GPIOT_BASE + TIVA_GPIO_IBE_OFFSET) +# define TIVA_GPIOT_IEV (TIVA_GPIOT_BASE + TIVA_GPIO_IEV_OFFSET) +# define TIVA_GPIOT_IM (TIVA_GPIOT_BASE + TIVA_GPIO_IM_OFFSET) +# define TIVA_GPIOT_RIS (TIVA_GPIOT_BASE + TIVA_GPIO_RIS_OFFSET) +# define TIVA_GPIOT_MIS (TIVA_GPIOT_BASE + TIVA_GPIO_MIS_OFFSET) +# define TIVA_GPIOT_ICR (TIVA_GPIOT_BASE + TIVA_GPIO_ICR_OFFSET) +# define TIVA_GPIOT_AFSEL (TIVA_GPIOT_BASE + TIVA_GPIO_AFSEL_OFFSET) +# define TIVA_GPIOT_DR2R (TIVA_GPIOT_BASE + TIVA_GPIO_DR2R_OFFSET) +# define TIVA_GPIOT_DR4R (TIVA_GPIOT_BASE + TIVA_GPIO_DR4R_OFFSET) +# define TIVA_GPIOT_DR8R (TIVA_GPIOT_BASE + TIVA_GPIO_DR8R_OFFSET) +# define TIVA_GPIOT_ODR (TIVA_GPIOT_BASE + TIVA_GPIO_ODR_OFFSET) +# define TIVA_GPIOT_PUR (TIVA_GPIOT_BASE + TIVA_GPIO_PUR_OFFSET) +# define TIVA_GPIOT_PDR (TIVA_GPIOT_BASE + TIVA_GPIO_PDR_OFFSET) +# define TIVA_GPIOT_SLR (TIVA_GPIOT_BASE + TIVA_GPIO_SLR_OFFSET) +# define TIVA_GPIOT_DEN (TIVA_GPIOT_BASE + TIVA_GPIO_DEN_OFFSET) +# define TIVA_GPIOT_LOCK (TIVA_GPIOT_BASE + TIVA_GPIO_LOCK_OFFSET) +# define TIVA_GPIOT_CR (TIVA_GPIOT_BASE + TIVA_GPIO_CR_OFFSET) + +#if defined(LM4F) || defined(TM4C) +# define TIVA_GPIOT_AMSEL (TIVA_GPIOT_BASE + TIVA_GPIO_AMSEL_OFFSET) +# define TIVA_GPIOT_PCTL (TIVA_GPIOT_BASE + TIVA_GPIO_PCTL_OFFSET) +# define TIVA_GPIOT_ADCCTL (TIVA_GPIOT_BASE + TIVA_GPIO_ADCCTL_OFFSET) +# define TIVA_GPIOT_DMACTL (TIVA_GPIOT_BASE + TIVA_GPIO_DMACTL_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_GPIOT_SI (TIVA_GPIOT_BASE + TIVA_GPIO_SI_OFFSET) +# define TIVA_GPIOT_DR12R (TIVA_GPIOT_BASE + TIVA_GPIO_DR12R_OFFSET) +# define TIVA_GPIOT_WAKEPEN (TIVA_GPIOT_BASE + TIVA_GPIO_WAKEPEN_OFFSET) +# define TIVA_GPIOT_WAKELVL (TIVA_GPIOT_BASE + TIVA_GPIO_WAKELVL_OFFSET) +# define TIVA_GPIOT_WAKESTAT (TIVA_GPIOT_BASE + TIVA_GPIO_WAKESTAT_OFFSET) + +# define TIVA_GPIOT_PP (TIVA_GPIOT_BASE + TIVA_GPIO_PP_OFFSET) +# define TIVA_GPIOT_PC (TIVA_GPIOT_BASE + TIVA_GPIO_PC_OFFSET) +#endif + +# define TIVA_GPIOT_PERIPHID4 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID4_OFFSET) +# define TIVA_GPIOT_PERIPHID5 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID5_OFFSET) +# define TIVA_GPIOT_PERIPHID6 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID6_OFFSET) +# define TIVA_GPIOT_PERIPHID7 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID7_OFFSET) +# define TIVA_GPIOT_PERIPHID0 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID0_OFFSET) +# define TIVA_GPIOT_PERIPHID1 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID1_OFFSET) +# define TIVA_GPIOT_PERIPHID2 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID2_OFFSET) +# define TIVA_GPIOT_PERIPHID3 (TIVA_GPIOT_BASE + TIVA_GPIO_PERIPHID3_OFFSET) +# define TIVA_GPIOT_PCELLID0 (TIVA_GPIOT_BASE + TIVA_GPIO_PCELLID0_OFFSET) +# define TIVA_GPIOT_PCELLID1 (TIVA_GPIOT_BASE + TIVA_GPIO_PCELLID1_OFFSET) +# define TIVA_GPIOT_PCELLID2 (TIVA_GPIOT_BASE + TIVA_GPIO_PCELLID2_OFFSET) +# define TIVA_GPIOT_PCELLID3 (TIVA_GPIOT_BASE + TIVA_GPIO_PCELLID3_OFFSET) +#endif + +/* GPIO Register Bitfield Definitions ***********************************************/ + +/* GPIO Interrupt Mask */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_IM_DMAIME (1 << 8) /* Bit 8: GPIO μDMA Done Interrupt Mask Enable */ +#endif + +/* GPIO Raw Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_RIS_DMARIS (1 << 8) /* Bit 8: GPIO μDMA Done Interrupt Raw Status */ +#endif + +/* GPIO Masked Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_MIS_DMAMIS (1 << 8) /* Bit 8: GPIO μDMA Done Masked Interrupt Status */ +#endif + +/* GPIO Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_ICR_DMAIC (1 << 8) /* Bit 8: GPIO μDMA Interrupt Clear */ +#endif + +/* GPIO Lock */ + +#define GPIO_LOCK_UNLOCK 0x4c4f434b +#define GPIO_LOCK_LOCKED (1 << 0) /* Bit 0: GPIOCR register is locked */ + +/* GPIO Port Control */ + +#if defined(LM4F) || defined(TM4C) +# define GPIO_PCTL_PMC_SHIFT(n) ((n) << 2) +# define GPIO_PCTL_PMC_MASK(n) (15 << GPIO_PCTL_PMC_SHIFT(n)) + +# define GPIO_PCTL_PMC0_SHIFT (0) /* Bits 0-3: Port Mux Control 0 */ +# define GPIO_PCTL_PMC0_MASK (15 << GPIO_PCTL_PMC0_SHIFT) +# define GPIO_PCTL_PMC1_SHIFT (4) /* Bits 4-7: Port Mux Control 1 */ +# define GPIO_PCTL_PMC1_MASK (15 << GPIO_PCTL_PMC1_SHIFT) +# define GPIO_PCTL_PMC2_SHIFT (8) /* Bits 8-11: Port Mux Control 2 */ +# define GPIO_PCTL_PMC2_MASK (15 << GPIO_PCTL_PMC2_SHIFT) +# define GPIO_PCTL_PMC3_SHIFT (12) /* Bits 12-15: Port Mux Control 3 */ +# define GPIO_PCTL_PMC3_MASK (15 << GPIO_PCTL_PMC3_SHIFT) +# define GPIO_PCTL_PMC4_SHIFT (16) /* Bits 16-19: Port Mux Control 4 */ +# define GPIO_PCTL_PMC4_MASK (15 << GPIO_PCTL_PMC4_SHIFT) +# define GPIO_PCTL_PMC5_SHIFT (20) /* Bits 20-23: Port Mux Control 5 */ +# define GPIO_PCTL_PMC5_MASK (15 << GPIO_PCTL_PMC5_SHIFT) +# define GPIO_PCTL_PMC6_SHIFT (24) /* Bits 24-27: Port Mux Control 6 */ +# define GPIO_PCTL_PMC6_MASK (15 << GPIO_PCTL_PMC6_SHIFT) +# define GPIO_PCTL_PMC7_SHIFT (28) /* Bits 28-31: Port Mux Control 7 */ +# define GPIO_PCTL_PMC7_MASK (15 << GPIO_PCTL_PMC7_SHIFT) +#endif + +/* GPIO Select Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_SI_SUM (1 << 0) /* Bit 0: Summary Interrupt */ +#endif + +/* GPIO Peripheral Property */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_PP_EDE (1 << 0) /* Bit 0: Extended Drive Enable */ +#endif + +/* GPIO Peripheral Configuration */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define GPIO_PC_ +# define GPIO_PC_EDM_SHIFT(n) ((n) << 1) +# define GPIO_PC_EDM_MASK(n) (3 << GPIO_PC_EDM_SHIFT(n)) + +# define GPIO_PC_EDM0_SHIFT (0) /* Bits 0-1: Extended Drive Mode Bit 0 */ +# define GPIO_PC_EDM0_MASK (3 << GPIO_PC_EDM0_SHIFT) +# define GPIO_PC_EDM1_SHIFT (2) /* Bits 2-3: Extended Drive Mode Bit 1 */ +# define GPIO_PC_EDM1_MASK (3 << GPIO_PC_EDM1_SHIFT) +# define GPIO_PC_EDM2_SHIFT (4) /* Bits 4-5: Extended Drive Mode Bit 2 */ +# define GPIO_PC_EDM2_MASK (3 << GPIO_PC_EDM2_SHIFT) +# define GPIO_PC_EDM3_SHIFT (6) /* Bits 6-7: Extended Drive Mode Bit 3 */ +# define GPIO_PC_EDM3_MASK (3 << GPIO_PC_EDM3_SHIFT) +# define GPIO_PC_EDM4_SHIFT (8) /* Bits 8-9: Extended Drive Mode Bit 4 */ +# define GPIO_PC_EDM4_MASK (3 << GPIO_PC_EDM4_SHIFT) +# define GPIO_PC_EDM5_SHIFT (10) /* Bits 10-11: Extended Drive Mode Bit 5 */ +# define GPIO_PC_EDM5_MASK (3 << GPIO_PC_EDM5_SHIFT) +# define GPIO_PC_EDM6_SHIFT (12) /* Bits 12-13: Extended Drive Mode Bit 6 */ +# define GPIO_PC_EDM6_MASK (3 << GPIO_PC_EDM6_SHIFT) +# define GPIO_PC_EDM7_SHIFT (14) /* Bits 14-15: Extended Drive Mode Bit 7 */ +# define GPIO_PC_EDM7_MASK (3 << GPIO_PC_EDM7_SHIFT) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_GPIO_H */ diff --git a/arch/arm/src/tiva/chip/tiva_i2c.h b/arch/arm/src/tiva/chip/tiva_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..61c0fec5bed829cd4c89c72206a6f0b84b406a0b --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_i2c.h @@ -0,0 +1,1064 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_i2c.h + * + * Copyright (C) 2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_I2C_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* I2C Register Offsets *************************************************************/ + +/* I2C Master */ + +#define TIVA_I2CM_SA_OFFSET 0x0000 /* I2C Master Slave Address */ +#define TIVA_I2CM_CS_OFFSET 0x0004 /* I2C Master Control/Status */ +#define TIVA_I2CM_DR_OFFSET 0x0008 /* I2C Master Data */ +#define TIVA_I2CM_TPR_OFFSET 0x000c /* I2C Master Timer Period */ +#define TIVA_I2CM_IMR_OFFSET 0x0010 /* I2C Master Interrupt Mask */ +#define TIVA_I2CM_RIS_OFFSET 0x0014 /* I2C Master Raw Interrupt Status */ +#define TIVA_I2CM_MIS_OFFSET 0x0018 /* I2C Master Masked Interrupt Status */ +#define TIVA_I2CM_ICR_OFFSET 0x001c /* I2C Master Interrupt Clear */ +#define TIVA_I2CM_CR_OFFSET 0x0020 /* I2C Master Configuration */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM_CLKOCNT_OFFSET 0x0024 /* I2C Master Clock Low Timeout Count */ +# define TIVA_I2CM_BMON_OFFSET 0x002c /* I2C Master Bus Monitor */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM_BLEN_OFFSET 0x0030 /* I2C Master Burst Length */ +# define TIVA_I2CM_BCNT_OFFSET 0x0034 /* I2C Master Burst Count */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM_CR2_OFFSET 0x0038 /* I2C Master Configuration 2 */ +#endif + +/* I2C Slave */ + +#define TIVA_I2CS_OAR_OFFSET 0x0800 /* I2C Slave Own Address */ +#define TIVA_I2CS_CSR_OFFSET 0x0804 /* I2C Slave Control/Status */ +#define TIVA_I2CS_DR_OFFSET 0x0808 /* I2C Slave Data */ +#define TIVA_I2CS_IMR_OFFSET 0x080c /* I2C Slave Interrupt Mask */ +#define TIVA_I2CS_RIS_OFFSET 0x0810 /* I2C Slave Raw Interrupt Status */ +#define TIVA_I2CS_MIS_OFFSET 0x0814 /* I2C Slave Masked Interrupt Status */ +#define TIVA_I2CS_ICR_OFFSET 0x0818 /* I2C Slave Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS_SOAR2_OFFSET 0x081c /* I2C Slave Own Address 2 */ +# define TIVA_I2CS_ACKCTL_OFFSET 0x0820 /* I2C Slave ACK Control */ +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC_FIFODATA_OFFSET 0x0f00 /* I2C FIFO Data */ +# define TIVA_I2CSC_FIFOCTL_OFFSET 0x0f04 /* I2C FIFO Control */ +# define TIVA_I2CSC_FIFOSTATUS_OFFSET 0x0f08 /* I2C FIFO Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC_PP_OFFSET 0x0fc0 /* I2C Peripheral Properties */ +# define TIVA_I2CSC_PC_OFFSET 0x0fc4 /* I2C Peripheral Configuration */ +#endif + +/* I2C Register Addresses ***********************************************************/ + +#if TIVA_NI2C > 0 + +/* I2C0 Master */ + +#define TIVA_I2CM0_SA (TIVA_I2C0_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM0_CS (TIVA_I2C0_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM0_DR (TIVA_I2C0_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM0_TPR (TIVA_I2C0_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM0_IMR (TIVA_I2C0_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM0_RIS (TIVA_I2C0_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM0_MIS (TIVA_I2C0_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM0_ICR (TIVA_I2C0_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM0_CR (TIVA_I2C0_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM0_CLKOCNT (TIVA_I2C0_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM0_BMON (TIVA_I2C0_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM0_BLEN (TIVA_I2C0_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM0_BCNT (TIVA_I2C0_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM0_CR2 (TIVA_I2C0_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C0 Slave */ + +#define TIVA_I2CS0_OAR (TIVA_I2C0_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS0_CSR (TIVA_I2C0_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS0_DR (TIVA_I2C0_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS0_IMR (TIVA_I2C0_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS0_RIS (TIVA_I2C0_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS0_MIS (TIVA_I2C0_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS0_ICR (TIVA_I2C0_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS0_SOAR2 (TIVA_I2C0_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS0_ACKCTL (TIVA_I2C0_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C0 Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC0_FIFODATA (TIVA_I2C0_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC0_FIFOCTL (TIVA_I2C0_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC0_FIFOSTATUS (TIVA_I2C0_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC0_PP (TIVA_I2C0_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC0_PC (TIVA_I2C0_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 0 */ + +#if TIVA_NI2C > 1 + +/* I2C1 Master */ + +#define TIVA_I2CM1_SA (TIVA_I2C1_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM1_CS (TIVA_I2C1_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM1_DR (TIVA_I2C1_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM1_TPR (TIVA_I2C1_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM1_IMR (TIVA_I2C1_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM1_RIS (TIVA_I2C1_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM1_MIS (TIVA_I2C1_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM1_ICR (TIVA_I2C1_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM1_CR (TIVA_I2C1_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM1_CLKOCNT (TIVA_I2C1_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM1_BMON (TIVA_I2C1_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM1_BLEN (TIVA_I2C1_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM1_BCNT (TIVA_I2C1_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM1_CR2 (TIVA_I2C1_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C1 Slave */ + +#define TIVA_I2CS1_OAR (TIVA_I2C1_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS1_CSR (TIVA_I2C1_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS1_DR (TIVA_I2C1_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS1_IMR (TIVA_I2C1_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS1_RIS (TIVA_I2C1_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS1_MIS (TIVA_I2C1_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS1_ICR (TIVA_I2C1_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS1_SOAR2 (TIVA_I2C1_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS1_ACKCTL (TIVA_I2C1_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C1 Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC1_FIFODATA (TIVA_I2C1_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC1_FIFOCTL (TIVA_I2C1_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC1_FIFOSTATUS (TIVA_I2C1_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC1_PP (TIVA_I2C1_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC1_PC (TIVA_I2C1_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 1 */ + +#if TIVA_NI2C > 2 + +/* I2C2 Master */ + +#define TIVA_I2CM2_SA (TIVA_I2C2_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM2_CS (TIVA_I2C2_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM2_DR (TIVA_I2C2_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM2_TPR (TIVA_I2C2_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM2_IMR (TIVA_I2C2_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM2_RIS (TIVA_I2C2_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM2_MIS (TIVA_I2C2_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM2_ICR (TIVA_I2C2_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM2_CR (TIVA_I2C2_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM2_CLKOCNT (TIVA_I2C2_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM2_BMON (TIVA_I2C2_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM2_BLEN (TIVA_I2C2_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM2_BCNT (TIVA_I2C2_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM2_CR2 (TIVA_I2C2_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C2 Slave */ + +#define TIVA_I2CS2_OAR (TIVA_I2C2_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS2_CSR (TIVA_I2C2_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS2_DR (TIVA_I2C2_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS2_IMR (TIVA_I2C2_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS2_RIS (TIVA_I2C2_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS2_MIS (TIVA_I2C2_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS2_ICR (TIVA_I2C2_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS2_SOAR2 (TIVA_I2C2_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS2_ACKCTL (TIVA_I2C2_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C2 Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC2_FIFODATA (TIVA_I2C2_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC2_FIFOCTL (TIVA_I2C2_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC2_FIFOSTATUS (TIVA_I2C2_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC2_PP (TIVA_I2C2_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC2_PC (TIVA_I2C2_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 2 */ + +#if TIVA_NI2C > 3 + +/* I2C3 Master */ + +#define TIVA_I2CM3_SA (TIVA_I2C3_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM3_CS (TIVA_I2C3_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM3_DR (TIVA_I2C3_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM3_TPR (TIVA_I2C3_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM3_IMR (TIVA_I2C3_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM3_RIS (TIVA_I2C3_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM3_MIS (TIVA_I2C3_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM3_ICR (TIVA_I2C3_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM3_CR (TIVA_I2C3_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM3_CLKOCNT (TIVA_I2C3_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM3_BMON (TIVA_I2C3_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM3_BLEN (TIVA_I2C3_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM3_BCNT (TIVA_I2C3_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM3_CR2 (TIVA_I2C3_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C3 Slave */ + +#define TIVA_I2CS3_OAR (TIVA_I2C3_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS3_CSR (TIVA_I2C3_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS3_DR (TIVA_I2C3_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS3_IMR (TIVA_I2C3_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS3_RIS (TIVA_I2C3_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS3_MIS (TIVA_I2C3_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS3_ICR (TIVA_I2C3_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS3_SOAR2 (TIVA_I2C3_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS3_ACKCTL (TIVA_I2C3_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C3 Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC3_FIFODATA (TIVA_I2C3_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC3_FIFOCTL (TIVA_I2C3_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC3_FIFOSTATUS (TIVA_I2C3_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC3_PP (TIVA_I2C3_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC3_PC (TIVA_I2C3_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 3 */ + +#if TIVA_NI2C > 4 + +/* I2C4 Master */ + +#define TIVA_I2CM4_SA (TIVA_I2C4_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM4_CS (TIVA_I2C4_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM4_DR (TIVA_I2C4_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM4_TPR (TIVA_I2C4_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM4_IMR (TIVA_I2C4_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM4_RIS (TIVA_I2C4_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM4_MIS (TIVA_I2C4_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM4_ICR (TIVA_I2C4_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM4_CR (TIVA_I2C4_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM4_CLKOCNT (TIVA_I2C4_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM4_BMON (TIVA_I2C4_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM4_BLEN (TIVA_I2C4_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM4_BCNT (TIVA_I2C4_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM4_CR2 (TIVA_I2C4_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C4 Slave */ + +#define TIVA_I2CS4_OAR (TIVA_I2C4_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS4_CSR (TIVA_I2C4_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS4_DR (TIVA_I2C4_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS4_IMR (TIVA_I2C4_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS4_RIS (TIVA_I2C4_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS4_MIS (TIVA_I2C4_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS4_ICR (TIVA_I2C4_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS4_SOAR2 (TIVA_I2C4_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS4_ACKCTL (TIVA_I2C4_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C4 Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC4_FIFODATA (TIVA_I2C4_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC4_FIFOCTL (TIVA_I2C4_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC4_FIFOSTATUS (TIVA_I2C4_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC4_PP (TIVA_I2C4_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC4_PC (TIVA_I2C4_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 4 */ + +#if TIVA_NI2C > 5 + +/* I2C5 Master */ + +#define TIVA_I2CM5_SA (TIVA_I2C5_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM5_CS (TIVA_I2C5_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM5_DR (TIVA_I2C5_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM5_TPR (TIVA_I2C5_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM5_IMR (TIVA_I2C5_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM5_RIS (TIVA_I2C5_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM5_MIS (TIVA_I2C5_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM5_ICR (TIVA_I2C5_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM5_CR (TIVA_I2C5_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM5_CLKOCNT (TIVA_I2C5_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM5_BMON (TIVA_I2C5_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM5_BLEN (TIVA_I2C5_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM5_BCNT (TIVA_I2C5_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM5_CR2 (TIVA_I2C5_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C5 Slave */ + +#define TIVA_I2CS5_OAR (TIVA_I2C5_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS5_CSR (TIVA_I2C5_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS5_DR (TIVA_I2C5_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS5_IMR (TIVA_I2C5_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS5_RIS (TIVA_I2C5_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS5_MIS (TIVA_I2C5_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS5_ICR (TIVA_I2C5_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS5_SOAR2 (TIVA_I2C5_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS5_ACKCTL (TIVA_I2C5_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC5_FIFODATA (TIVA_I2C5_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC5_FIFOCTL (TIVA_I2C5_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC5_FIFOSTATUS (TIVA_I2C5_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC5_PP (TIVA_I2C5_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC5_PC (TIVA_I2C5_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 5 */ + +#if TIVA_NI2C > 6 + +/* I2C6 Master */ + +#define TIVA_I2CM6_SA (TIVA_I2C6_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM6_CS (TIVA_I2C6_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM6_DR (TIVA_I2C6_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM6_TPR (TIVA_I2C6_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM6_IMR (TIVA_I2C6_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM6_RIS (TIVA_I2C6_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM6_MIS (TIVA_I2C6_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM6_ICR (TIVA_I2C6_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM6_CR (TIVA_I2C6_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM6_CLKOCNT (TIVA_I2C6_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM6_BMON (TIVA_I2C6_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM6_BLEN (TIVA_I2C6_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM6_BCNT (TIVA_I2C6_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM6_CR2 (TIVA_I2C6_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C6 Slave */ + +#define TIVA_I2CS6_OAR (TIVA_I2C6_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS6_CSR (TIVA_I2C6_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS6_DR (TIVA_I2C6_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS6_IMR (TIVA_I2C6_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS6_RIS (TIVA_I2C6_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS6_MIS (TIVA_I2C6_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS6_ICR (TIVA_I2C6_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS6_SOAR2 (TIVA_I2C6_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS6_ACKCTL (TIVA_I2C6_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC6_FIFODATA (TIVA_I2C6_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC6_FIFOCTL (TIVA_I2C6_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC6_FIFOSTATUS (TIVA_I2C6_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC6_PP (TIVA_I2C6_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC6_PC (TIVA_I2C6_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 5 */ + +#if TIVA_NI2C > 7 + +/* I2C7 Master */ + +#define TIVA_I2CM7_SA (TIVA_I2C7_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM7_CS (TIVA_I2C7_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM7_DR (TIVA_I2C7_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM7_TPR (TIVA_I2C7_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM7_IMR (TIVA_I2C7_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM7_RIS (TIVA_I2C7_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM7_MIS (TIVA_I2C7_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM7_ICR (TIVA_I2C7_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM7_CR (TIVA_I2C7_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM7_CLKOCNT (TIVA_I2C7_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM7_BMON (TIVA_I2C7_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM7_BLEN (TIVA_I2C7_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM7_BCNT (TIVA_I2C7_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM7_CR2 (TIVA_I2C7_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C7 Slave */ + +#define TIVA_I2CS7_OAR (TIVA_I2C7_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS7_CSR (TIVA_I2C7_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS7_DR (TIVA_I2C7_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS7_IMR (TIVA_I2C7_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS7_RIS (TIVA_I2C7_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS7_MIS (TIVA_I2C7_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS7_ICR (TIVA_I2C7_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS7_SOAR2 (TIVA_I2C7_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS7_ACKCTL (TIVA_I2C7_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC7_FIFODATA (TIVA_I2C7_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC7_FIFOCTL (TIVA_I2C7_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC7_FIFOSTATUS (TIVA_I2C7_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC7_PP (TIVA_I2C7_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC7_PC (TIVA_I2C7_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 5 */ + +#if TIVA_NI2C > 8 + +/* I2C8 Master */ + +#define TIVA_I2CM8_SA (TIVA_I2C8_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM8_CS (TIVA_I2C8_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM8_DR (TIVA_I2C8_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM8_TPR (TIVA_I2C8_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM8_IMR (TIVA_I2C8_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM8_RIS (TIVA_I2C8_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM8_MIS (TIVA_I2C8_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM8_ICR (TIVA_I2C8_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM8_CR (TIVA_I2C8_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM8_CLKOCNT (TIVA_I2C8_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM8_BMON (TIVA_I2C8_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM8_BLEN (TIVA_I2C8_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM8_BCNT (TIVA_I2C8_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM8_CR2 (TIVA_I2C8_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C8 Slave */ + +#define TIVA_I2CS8_OAR (TIVA_I2C8_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS8_CSR (TIVA_I2C8_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS8_DR (TIVA_I2C8_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS8_IMR (TIVA_I2C8_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS8_RIS (TIVA_I2C8_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS8_MIS (TIVA_I2C8_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS8_ICR (TIVA_I2C8_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS8_SOAR2 (TIVA_I2C8_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS8_ACKCTL (TIVA_I2C8_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC8_FIFODATA (TIVA_I2C8_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC8_FIFOCTL (TIVA_I2C8_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC8_FIFOSTATUS (TIVA_I2C8_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC8_PP (TIVA_I2C8_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC8_PC (TIVA_I2C8_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 5 */ + +#if TIVA_NI2C > 9 + +/* I2C9 Master */ + +#define TIVA_I2CM9_SA (TIVA_I2C9_BASE + TIVA_I2CM_SA_OFFSET) +#define TIVA_I2CM9_CS (TIVA_I2C9_BASE + TIVA_I2CM_CS_OFFSET) +#define TIVA_I2CM9_DR (TIVA_I2C9_BASE + TIVA_I2CM_DR_OFFSET) +#define TIVA_I2CM9_TPR (TIVA_I2C9_BASE + TIVA_I2CM_TPR_OFFSET) +#define TIVA_I2CM9_IMR (TIVA_I2C9_BASE + TIVA_I2CM_IMR_OFFSET) +#define TIVA_I2CM9_RIS (TIVA_I2C9_BASE + TIVA_I2CM_RIS_OFFSET) +#define TIVA_I2CM9_MIS (TIVA_I2C9_BASE + TIVA_I2CM_MIS_OFFSET) +#define TIVA_I2CM9_ICR (TIVA_I2C9_BASE + TIVA_I2CM_ICR_OFFSET) +#define TIVA_I2CM9_CR (TIVA_I2C9_BASE + TIVA_I2CM_CR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CM9_CLKOCNT (TIVA_I2C9_BASE + TIVA_I2CM_CLKOCNT_OFFSET) +# define TIVA_I2CM9_BMON (TIVA_I2C9_BASE + TIVA_I2CM_BMON_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CM9_BLEN (TIVA_I2C9_BASE + TIVA_I2CM_BLEN_OFFSET) +# define TIVA_I2CM9_BCNT (TIVA_I2C9_BASE + TIVA_I2CM_BCNT_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_I2CM9_CR2 (TIVA_I2C9_BASE + TIVA_I2CM_CR2_OFFSET) +#endif + +/* I2C9 Slave */ + +#define TIVA_I2CS9_OAR (TIVA_I2C9_BASE + TIVA_I2CS_OAR_OFFSET) +#define TIVA_I2CS9_CSR (TIVA_I2C9_BASE + TIVA_I2CS_CSR_OFFSET) +#define TIVA_I2CS9_DR (TIVA_I2C9_BASE + TIVA_I2CS_DR_OFFSET) +#define TIVA_I2CS9_IMR (TIVA_I2C9_BASE + TIVA_I2CS_IMR_OFFSET) +#define TIVA_I2CS9_RIS (TIVA_I2C9_BASE + TIVA_I2CS_RIS_OFFSET) +#define TIVA_I2CS9_MIS (TIVA_I2C9_BASE + TIVA_I2CS_MIS_OFFSET) +#define TIVA_I2CS9_ICR (TIVA_I2C9_BASE + TIVA_I2CS_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CS9_SOAR2 (TIVA_I2C9_BASE + TIVA_I2CS_SOAR2_OFFSET) +# define TIVA_I2CS9_ACKCTL (TIVA_I2C9_BASE + TIVA_I2CS_ACKCTL_OFFSET) +#endif + +/* I2C Status and control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_I2CSC9_FIFODATA (TIVA_I2C9_BASE + TIVA_I2CSC_FIFODATA_OFFSET) +# define TIVA_I2CSC9_FIFOCTL (TIVA_I2C9_BASE + TIVA_I2CSC_FIFOCTL_OFFSET) +# define TIVA_I2CSC9_FIFOSTATUS (TIVA_I2C9_BASE + TIVA_I2CSC_FIFOSTATUS_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_I2CSC9_PP (TIVA_I2C9_BASE + TIVA_I2CSC_PP_OFFSET) +# define TIVA_I2CSC9_PC (TIVA_I2C9_BASE + TIVA_I2CSC_PC_OFFSET) +#endif +#endif /* TIVA_NI2C > 5 */ + +/* I2C_Register Bit Definitions *****************************************************/ + +/* I2C Master Slave Address (I2CM_SA) */ + +#define I2CM_SA_RS (1 << 0) /* Bit 0: Receive/Send */ +#define I2CM_SA_SA_SHIFT 1 /* Bits 7-1: I2C Slave Address */ +#define I2CM_SA_SA_MASK (0x7f << I2CM_SA_SA_SHIFT) + +/* I2C Master Control/Status (I2CM_CS) */ + +#define I2CM_CS_BUSY (1 << 0) /* Bit 0: I2C Busy (read) */ +#define I2CM_CS_ERROR (1 << 1) /* Bit 1: Error in last bus operation (read) */ +#define I2CM_CS_ADRACK (1 << 2) /* Bit 2: Acknowledge Address (read) */ +#define I2CM_CS_DATACK (1 << 3) /* Bit 3: Acknowledge Data (read) */ +#define I2CM_CS_ARBLST (1 << 4) /* Bit 4: Arbitration Lost (read) */ +#define I2CM_CS_IDLE (1 << 5) /* Bit 5: I2C Idle (read) */ +#define I2CM_CS_BUSBSY (1 << 6) /* Bit 6: Bus Busy (read) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_CS_CLKTO (1 << 7) /* Bit 7: Clock Timeout Error (read) */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_CS_ACTDMATX (1 << 30) /* Bit 30: DMA TX Active Status (read) */ +# define I2CM_CS_ACTDMARX (1 << 31) /* Bit 31: DMA RX Active Status (read) */ +#endif + +#define I2CM_CS_RUN (1 << 0) /* Bit 0: I2C Master Enable (write) */ +#define I2CM_CS_START (1 << 1) /* Bit 1: Generate START (write) */ +#define I2CM_CS_STOP (1 << 2) /* Bit 2: Generate STOP (write) */ +#define I2CM_CS_ACK (1 << 3) /* Bit 3: Data Acknowledge Enable (write) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_CS_HS (1 << 4) /* Bit 4: High-Speed Enable (write) */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_CS_QCMD (1 << 5) /* Bit 5: Quick Command (write) */ +# define I2CM_CS_BURST (1 << 6) /* Bit 6: Burst Enable (write) */ +#endif + +/* I2C Master Data (I2CM_DR) */ + +#define I2CM_DR_SHIFT (0) /* Bits 7-0: Data transferred */ +#define I2CM_DR_MASK (0xff << I2CM_DR_SHIFT) + +/* I2C Master Timer Period (I2CM_TPR) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_TPR_SHIFT (0) /* Bits 6-0: SCL Clock Period */ +# define I2CM_TPR_MASK (0x7f << I2CM_TPR_SHIFT) +# define I2CM_TPR_HS (1 << 7) /* Bit 7: High-Speed Enable (write) */ + +# if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_TPR_PULSEL_SHIFT (16) /* Bits 18-16: Glitch Suppression Pulse Width (write) */ +# define I2CM_TPR_PULSEL_MASK (7 << I2CM_TPR_PULSEL_SHIFT) +# define I2CM_TPR_PULSEL_BYPASS (0 << I2CM_TPR_PULSEL_SHIFT) /* Bypass */ +# define I2CM_TPR_PULSEL_1CLK (1 << I2CM_TPR_PULSEL_SHIFT) /* 1 clock */ +# define I2CM_TPR_PULSEL_2CLKS (2 << I2CM_TPR_PULSEL_SHIFT) /* 2 clocks */ +# define I2CM_TPR_PULSEL_3CLKS (3 << I2CM_TPR_PULSEL_SHIFT) /* 3 clocks */ +# define I2CM_TPR_PULSEL_4CLKS (4 << I2CM_TPR_PULSEL_SHIFT) /* 4 clocks */ +# define I2CM_TPR_PULSEL_8CLKS (5 << I2CM_TPR_PULSEL_SHIFT) /* 8 clocks */ +# define I2CM_TPR_PULSEL_16CLKS (6 << I2CM_TPR_PULSEL_SHIFT) /* 16 clocks */ +# define I2CM_TPR_PULSEL_31CLKS (7 << I2CM_TPR_PULSEL_SHIFT) /* 31 clocks */ +# endif + +#else +# define I2CM_TPR_SHIFT (0) /* Bits 7-0: SCL Clock Period */ +# define I2CM_TPR_MASK (0xff << I2CM_TPR_SHIFT) +#endif + +/* I2C Master Interrupt Mask (I2CM_IMR) */ + +#define I2CM_IMR_MIM (1 << 0) /* Bit 0: Master Interrupt Mask */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_IMR_CLKIM (1 << 1) /* Bit 1: Clock Timeout Interrupt Mask */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_IMR_DMARXIM (1 << 2) /* Bit 2: Receive DMA Interrupt Mask */ +# define I2CM_IMR_DMATXIM (1 << 3) /* Bit 3: Transmit DMA Interrupt Mask */ +# define I2CM_IMR_NACKIM (1 << 4) /* Bit 4: Address/Data NACK Interrupt Mask */ +# define I2CM_IMR_STARTIM (1 << 5) /* Bit 5: START Detection Interrupt Mask */ +# define I2CM_IMR_STOPIM (1 << 6) /* Bit 6: STOP Detection Interrupt Mask */ +# define I2CM_IMR_ARBLOSTIM (1 << 7) /* Bit 7: Arbitration Lost Interrupt Mask */ +# define I2CM_IMR_TXIM (1 << 8) /* Bit 8: Transmit FIFO Request Interrupt Mask */ +# define I2CM_IMR_RXIM (1 << 9) /* Bit 9: Receive FIFO Request Interrupt Mask */ +# define I2CM_IMR_TXFEIM (1 << 10) /* Bit 10: Transmit FIFO Empty Interrupt Mask */ +# define I2CM_IMR_RXFFIM (1 << 11) /* Bit 11: Receive FIFO Full Interrupt Mask */ +#endif + +/* I2C Master Raw Interrupt Status (I2CM_RIS) */ + +#define I2CM_RIS_MRIS (1 << 0) /* Bit 0: Master Raw Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_RIS_CLKRIS (1 << 1) /* Bit 1: Clock Timeout Raw Interrupt Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_RIS_DMARXRIS (1 << 2) /* Bit 2: Receive DMA Interrupt Status */ +# define I2CM_RIS_DMATXRIS (1 << 3) /* Bit 3: Transmit DMA Interrupt Status */ +# define I2CM_RIS_NACKRIS (1 << 4) /* Bit 4: Address/Data NACK Interrupt Status */ +# define I2CM_RIS_STARTRIS (1 << 5) /* Bit 5: START Detection Interrupt Status */ +# define I2CM_RIS_STOPRIS (1 << 6) /* Bit 6: STOP Detection Interrupt Status */ +# define I2CM_RIS_ARBLOSTRIS (1 << 7) /* Bit 7: Arbitration Lost Interrupt Status */ +# define I2CM_RIS_TXRIS (1 << 8) /* Bit 8: Transmit FIFO Request Interrupt Status */ +# define I2CM_RIS_RXRIS (1 << 9) /* Bit 9: Receive FIFO Request Interrupt Status */ +# define I2CM_RIS_TXFERIS (1 << 10) /* Bit 10: Transmit FIFO Empty Interrupt Status */ +# define I2CM_RIS_RXFFRIS (1 << 11) /* Bit 11: Receive FIFO Full Interrupt Status */ +#endif + +/* I2C Master Masked Interrupt Status (I2CM_MIS) */ + +#define I2CM_MIS_MMIS (1 << 0) /* Bit 0: Maseter Masked Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_MIS_CLKMIS (1 << 1) /* Bit 1: Clock Timeout Masked Interrupt Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_MIS_DMARXMIS (1 << 2) /* Bit 2: Receive DMA Interrupt Status */ +# define I2CM_MIS_DMATXMIS (1 << 3) /* Bit 3: Transmit DMA Interrupt Status */ +# define I2CM_MIS_NACKMIS (1 << 4) /* Bit 4: Address/Data NACK Interrupt Status */ +# define I2CM_MIS_STARTMIS (1 << 5) /* Bit 5: START Detection Interrupt Status */ +# define I2CM_MIS_STOPMIS (1 << 6) /* Bit 6: STOP Detection Interrupt Status */ +# define I2CM_MIS_ARBLOSTMIS (1 << 7) /* Bit 7: Arbitration Lost Interrupt Status */ +# define I2CM_MIS_TXMIS (1 << 8) /* Bit 8: Transmit FIFO Request Interrupt Status */ +# define I2CM_MIS_RXMIS (1 << 9) /* Bit 9: Receive FIFO Request Interrupt Status */ +# define I2CM_MIS_TXFEMIS (1 << 10) /* Bit 10: Transmit FIFO Empty Interrupt Status */ +# define I2CM_MIS_RXFFMIS (1 << 11) /* Bit 11: Receive FIFO Full Interrupt Status */ +#endif + +/* I2C Master Masked Interrupt Status (I2CM_ICR) */ + +#define I2CM_ICR_MIC (1 << 0) /* Bit 0: Master Masked Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_ICR_CLKC (1 << 1) /* Bit 1: Clock Timeout Interrupt Clear */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_ICR_DMARXIC (1 << 2) /* Bit 2: Receive DMA Interrupt Clear */ +# define I2CM_ICR_DMATXIC (1 << 3) /* Bit 3: Transmit DMA Interrupt Clear */ +# define I2CM_ICR_NACKIC (1 << 4) /* Bit 4: Address/Data NACK Interrupt Clear */ +# define I2CM_ICR_STARTIC (1 << 5) /* Bit 5: START Detection Interrupt Clear */ +# define I2CM_ICR_STOPIC (1 << 6) /* Bit 6: STOP Detection Interrupt Clear */ +# define I2CM_ICR_ARBLOSTIC (1 << 7) /* Bit 7: Arbitration Lost Interrupt Clear */ +# define I2CM_ICR_TXIC (1 << 8) /* Bit 8: Transmit FIFO Request Interrupt Clear */ +# define I2CM_ICR_RXIC (1 << 9) /* Bit 9: Receive FIFO Request Interrupt Clear */ +# define I2CM_ICR_TXFEIC (1 << 10) /* Bit 10: Transmit FIFO Empty Interrupt Mask */ +# define I2CM_ICR_RXFFIC (1 << 11) /* Bit 11: Receive FIFO Full Interrupt Clear */ +#endif + +/* I2C Master Configuration (I2CM_CR) */ + +#define I2CM_CR_LPBK (1 << 0) /* Bit 0:: I2C Loopback */ +#define I2CM_CR_MFE (1 << 4) /* Bit 4: I2C Master Function Enable */ +#define I2CM_CR_SFE (1 << 5) /* Bit 5: I2C Slave Function Enable */ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define I2CM_CR_GFE (1 << 6) /* Bit 6: I2C Glitch Filter Enable */ +#endif + +/* I2C Master Clock Low Timeout Count */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_CLKOCNT_CNTL_SHIFT (0) /* Bits 7-0: I2C Master Count */ +# define I2CM_CLKOCNT_CNTL_MASK (0xff << I2CM_CLKOCNT_CNTL_SHIFT) +#endif + +/* I2C Master Configuration */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CM_BMON_SCL (1 << 0) /* Bit 0: II2C SCL Status */ +# define I2CM_BMON_SCA (1 << 1) /* Bit 1: II2C SDA Status */ +#endif + +/* I2C Master Burst Length */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_BLEN_SHIFT (0) /* Bits 7-0: I2C Burst Length */ +# define I2CM_BLEN_MASK (0xff << I2CM_BLEN_SHIFT) +#endif + +/* I2C Master Burst Count */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CM_BCNT_SHIFT (0) /* Bits 7-0: I2C Burst Count */ +# define I2CM_BCNT_MASK (0xff << I2CM_BCNT_SHIFT) +#endif + +/* I2C Master Configuration 2 */ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define I2CM_CR2_GFPW_SHIFT (4) /* I2C Glitch Filter Pulse Width */ +# define I2CM_CR2_GFPW_MASK (7 << I2CM_CR2_GFPW_SHIFT) +# define I2CM_CR2_GFPW_BYPASS (0 << I2CM_CR2_GFPW_SHIFT) /* Bypass */ +# define I2CM_CR2_GFPW_1CLK (1 << I2CM_CR2_GFPW_SHIFT) /* 1 clock */ +# define I2CM_CR2_GFPW_2CLKS (2 << I2CM_CR2_GFPW_SHIFT) /* 2 clocks */ +# define I2CM_CR2_GFPW_3CLKS (3 << I2CM_CR2_GFPW_SHIFT) /* 3 clocks */ +# define I2CM_CR2_GFPW_4CLKS (4 << I2CM_CR2_GFPW_SHIFT) /* 4 clocks */ +# define I2CM_CR2_GFPW_8CLKS (5 << I2CM_CR2_GFPW_SHIFT) /* 8 clocks */ +# define I2CM_CR2_GFPW_16CLKS (6 << I2CM_CR2_GFPW_SHIFT) /* 16 clocks */ +# define I2CM_CR2_GFPW_31CLKS (7 << I2CM_CR2_GFPW_SHIFT) /* 31 clocks */ +#endif + +/* I2C Slave Own Address (I2CS_OAR) */ + +#define I2CS_OAR_MASK 0x7f /* Bits 6-0: I2C Slave Own Address */ + +/* I2C Slave Control/Status (I2CS_CSR) */ + +#define I2CS_CSR_RREQ (1 << 0) /* Bit 0: Receive Request (read) */ +#define I2CS_CSR_TREQ (1 << 1) /* Bit 1: Transmit Request (read) */ +#define I2CS_CSR_FBR (1 << 2) /* Bit 2: First Byte Received (read) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_CSR_OAR2SEL (1 << 3) /* Bit 3: OAR2 Address Matched (read) */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_CSR_QCMDST (1 << 4) /* Bit 4: Quick Command Status (read) */ +# define I2CS_CSR_QCMDRW (1 << 5) /* Bit 5: Quick Command Read / Write (read) */ +# define I2CS_CSR_ACTDMATX (1 << 30) /* Bit 30: DMA TX Active Status (read) */ +# define I2CS_CSR_ACTDMARX (1 << 31) /* Bit 31: DMA RX Active Status (read) */ +#endif + +#define I2CS_CSR_DA (1 << 0) /* Bit 0: Device Active (write) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_CSR_TXFIFO (1 << 1) /* Bit 1: TX FIFO Enable (write) */ +# define I2CS_CSR_RXFIFO (1 << 2) /* Bit 2: RX FIFO Enable (write) */ +#endif + +/* I2C Slave Data (I2CS_DR) */ + +#define I2CS_DR_SHIFT (0) /* Bits 7-0: Data for Transfer */ +#define I2CS_DR_MASK (0xff << I2CS_DR_SHIFT) + +/* I2C Slave Interrupt Mask (I2CS_IMR) */ + +#define I2CS_IMR_DATAIM (1 << 0) /* Bit 0: Data Interrupt Mask */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_IMR_STARTIM (1 << 1) /* Bit 1: Start Condition Interrupt Mask */ +# define I2CS_IMR_STOPIM (1 << 2) /* Bit 2: Stop Condition Interrupt Mask */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_IMR_DMARXIM (1 << 3) /* Bit 3: Receive DMA Interrupt Mask */ +# define I2CS_IMR_DMATXIM (1 << 4) /* Bit 4: Transmit DMA Interrupt Mask */ +# define I2CS_IMR_TXIM (1 << 5) /* Bit 5: Transmit FIFO Request Interrupt Mask */ +# define I2CS_IMR_RXIM (1 << 6) /* Bit 6: Receive FIFO Request Interrupt Mask */ +# define I2CS_IMR_TXFEIM (1 << 7) /* Bit 7: Transmit FIFO Empty Interrupt Mask */ +# define I2CS_IMR_RXFFIM (1 << 8) /* Bit 8: Receive FIFO Full Interrupt Mask */ +#endif + +/* I2C Slave Raw Interrupt Status (I2CS_RIS) */ + +#define I2CS_RIS_DATARIS (1 << 0) /* Bit 0: Data Raw Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_RIS_STARTRIS (1 << 1) /* Bit 1: Start Condition Raw Interrupt Status */ +# define I2CS_RIS_STOPRIS (1 << 2) /* Bit 2: Stop Condition Raw Interrupt Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_RIS_DMARXRIS (1 << 3) /* Bit 3: Receive DMA Interrupt Mask */ +# define I2CS_RIS_DMATXRIS (1 << 4) /* Bit 4: Transmit DMA Interrupt Mask */ +# define I2CS_RIS_TXRIS (1 << 5) /* Bit 5: Transmit FIFO Request Interrupt Mask */ +# define I2CS_RIS_RXRIS (1 << 6) /* Bit 6: Receive FIFO Request Interrupt Mask */ +# define I2CS_RIS_TXFERIS (1 << 7) /* Bit 7: Transmit FIFO Empty Interrupt Mask */ +# define I2CS_RIS_RXFFRIS (1 << 8) /* Bit 8: Receive FIFO Full Interrupt Mask */ +#endif + +/* I2C Slave Masked Interrupt Status (I2CS_MIS) */ + +#define I2CS_MIS_DATAMIS (1 << 0) /* Bit 0: Data Masked Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_MIS_STARTMIS (1 << 1) /* Bit 1: Start Condition Masked Interrupt Status */ +# define I2CS_MIS_STOPMIS (1 << 2) /* Bit 2: Stop Condition Masked Interrupt Status */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_MIS_DMARXMIS (1 << 3) /* Bit 3: Receive DMA Interrupt Mask */ +# define I2CS_MIS_DMATXMIS (1 << 4) /* Bit 4: Transmit DMA Interrupt Mask */ +# define I2CS_MIS_TXMIS (1 << 5) /* Bit 5: Transmit FIFO Request Interrupt Mask */ +# define I2CS_MIS_RXMIS (1 << 6) /* Bit 6: Receive FIFO Request Interrupt Mask */ +# define I2CS_MIS_TXFEMIS (1 << 7) /* Bit 7: Transmit FIFO Empty Interrupt Mask */ +# define I2CS_MIS_RXFFMIS (1 << 8) /* Bit 8: Receive FIFO Full Interrupt Mask */ +#endif + +/* I2C Slave Interrupt Clear (I2CS_ICR) */ + +#define I2CS_ICR_DATAIC (1 << 0) /* Bit 0: Data Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_ICR_STARTIC (1 << 1) /* Bit 1: Start Condition Interrupt Clear */ +# define I2CS_ICR_STOPIC (1 << 2) /* Bit 2: Stop Condition Interrupt Clear */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CS_ICR_DMARXIC (1 << 3) /* Bit 3: Receive DMA Interrupt Mask */ +# define I2CS_ICR_DMATXIC (1 << 4) /* Bit 4: Transmit DMA Interrupt Mask */ +# define I2CS_ICR_TXIC (1 << 5) /* Bit 5: Transmit FIFO Request Interrupt Mask */ +# define I2CS_ICR_RXIC (1 << 6) /* Bit 6: Receive FIFO Request Interrupt Mask */ +# define I2CS_ICR_TXFEIC (1 << 7) /* Bit 7: Transmit FIFO Empty Interrupt Mask */ +# define I2CS_ICR_RXFFIC (1 << 8) /* Bit 8: Receive FIFO Full Interrupt Mask */ +#endif + +/* I2C Slave Own Address 2 */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_SOAR2_SHIFT (0) /* Bits 0-6: I2C Slave Own Address 2 */ +# define I2CS_SOAR2_MASK (0x7f << I2CS_SOAR2_SHIFT) +# define I2CS_SOAR2_OAR2EN (1 << 7) /* Bit 7: I2C Slave Own Address 2 Enable */ +#endif + +/* I2C Slave ACK Control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CS_ACKCTL_ACKOEN (1 << 0) /* Bit 0: I2C Slave ACK Override Enable */ +# define I2CS_ACKCTL_ACKOVAL (1 << 1) /* Bit 1: I2C Slave ACK Override Value */ +#endif + +/* I2C FIFO Data */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CSC_FIFODATA_SHIFT (0) /* Bits 7-0: I2C RX FIFO Read / Write Data Byte */ +# define I2CSC_FIFODATA_MASK (0xff << I2CSC_FIFODATA_SHIFT) +#endif + +/* I2C FIFO Control */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CSC_FIFOCTRL_TXTRIG_SHIFT (0) /* Bits 2-0: TX FIFO Trigger */ +# define I2CSC_FIFOCTRL_TXTRIG_MASK (7 << I2CSC_FIFOCTRL_TXTRIG_SHIFT) +# define I2CSC_FIFOCTRL_TXTRIG(n) ((uint32_)(n) << I2CSC_FIFOCTRL_TXTRIG_SHIFT) +# define I2CSC_FIFOCTRL_DMATXENA (1 << 13) /* Bit 13: DMA TX Channel Enable */ +# define I2CSC_FIFOCTRL_TXFLUSH (1 << 14) /* Bit 14: TX FIFO Flush */ +# define I2CSC_FIFOCTRL_TXASGNMT (1 << 15) /* Bit 15: TX Control Assignment */ +# define I2CSC_FIFOCTRL_RXTRIG_SHIFT (16) /* Bits 18-16: RX FIFO Trigger */ +# define I2CSC_FIFOCTRL_RXTRIG_MASK (7 << I2CSC_FIFOCTRL_RXTRIG_SHIFT) +# define I2CSC_FIFOCTRL_RXTRIG(n) ((uint32_t)(n) << I2CSC_FIFOCTRL_RXTRIG_SHIFT) +# define I2CSC_FIFOCTRL_DMARXENA (1 << 20) /* Bit 29: DMA RX Channel Enable */ +# define I2CSC_FIFOCTRL_RXFLUSH (1 << 30) /* Bit 30: RX FIFO Flush */ +# define I2CSC_FIFOCTRL_RXASGNMT (1 << 31) /* Bit 31: RX Control Assignment */ +#endif + +/* I2C FIFO Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define I2CSC_FIFOSTATUS_TXFE (1 << 0) /* Bit 0: TX FIFO Empty */ +# define I2CSC_FIFOSTATUS_TXFF (1 << 1) /* Bit 1: TX FIFO Full */ +# define I2CSC_FIFOSTATUS_TXBLWTRIG (1 << 2) /* Bit 2: TX FIFO Below Trigger Level */ +# define I2CSC_FIFOSTATUS_RXFE (1 << 16) /* Bit 16: RX FIFO Empty */ +# define I2CSC_FIFOSTATUS_RXFF (1 << 17) /* Bit 17: RX FIFO Full */ +# define I2CSC_FIFOSTATUS_RXABVTRIG (1 << 18) /* Bit 18: RX FIFO Above Trigger Level */ +#endif + +/* I2C Peripheral Properties */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CSC_PP_HS (1 << 0) /* Bit 0: High-Speed Capable */ +#endif + +/* I2C Peripheral Configuration */ + +#if defined(CONFIG_ARCH_CHIP_TM4C) +# define I2CSC_PC_HS (1 << 0) /* Bit 0: High-Speed Capable */ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_I2C_H */ diff --git a/arch/arm/src/tiva/chip/tiva_memorymap.h b/arch/arm/src/tiva/chip/tiva_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..fd480315018bd7c2a619885576f52f5212ae972c --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_memorymap.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_memorymap.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_MEMORYMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map file for the specific Tiva/Stellaris chip */ + +#if defined(CONFIG_ARCH_CHIP_LM3S) +# include "chip/lm3s_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_LM4F) +# include "chip/lm4f_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_TM4C) +# include "chip/tm4c_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# include "chip/cc3200_memorymap.h" +#else +# error "Unsupported Tiva/Stellaris memory map" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_MEMORYMAP_H */ diff --git a/arch/arm/src/tiva/chip/tiva_pinmap.h b/arch/arm/src/tiva/chip/tiva_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..ffd45aeb13d64fd9d780750d2e072b5438163a80 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_pinmap.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_pinmap.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_PINMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the pin mapping file for the specific Tiva/Stellaris chip */ + +#if defined(CONFIG_ARCH_CHIP_LM3S) +# include "chip/lm3s_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_LM4F) +# include "chip/lm4f_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_TM4C) +# include "chip/tm4c_pinmap.h" +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# include "chip/cc3200_pinmap.h" +#else +# error "Unsupported Tiva/Stellaris PIN mapping" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_PINMAP_H */ diff --git a/arch/arm/src/tiva/chip/tiva_ssi.h b/arch/arm/src/tiva/chip/tiva_ssi.h new file mode 100644 index 0000000000000000000000000000000000000000..edf1a495858dcde0dc4544daae0c9e2a8ebb0a54 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_ssi.h @@ -0,0 +1,235 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_ssi.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SSI_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SSI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if TIVA_NSSI > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* SSI register offsets *************************************************************/ + +#define TIVA_SSI_CR0_OFFSET 0x000 /* SSI Control 0 */ +#define TIVA_SSI_CR1_OFFSET 0x004 /* SSI Control 1 */ +#define TIVA_SSI_DR_OFFSET 0x008 /* SSI Data */ +#define TIVA_SSI_SR_OFFSET 0x00c /* SSI Status */ +#define TIVA_SSI_CPSR_OFFSET 0x010 /* SSI Clock Prescale */ +#define TIVA_SSI_IM_OFFSET 0x014 /* SSI Interrupt Mask */ +#define TIVA_SSI_RIS_OFFSET 0x018 /* SSI Raw Interrupt Status */ +#define TIVA_SSI_MIS_OFFSET 0x01c /* SSI Masked Interrupt Status */ +#define TIVA_SSI_ICR_OFFSET 0x020 /* SSI Interrupt Clear */ +#define TIVA_SSI_PERIPHID4_OFFSET 0xfd0 /* SSI Peripheral Identification 4 */ +#define TIVA_SSI_PERIPHID5_OFFSET 0xfd4 /* SSI Peripheral Identification 5 */ +#define TIVA_SSI_PERIPHID6_OFFSET 0xfd8 /* SSI Peripheral Identification 6 */ +#define TIVA_SSI_PERIPHID7_OFFSET 0xfdc /* SSI Peripheral Identification 7 */ +#define TIVA_SSI_PERIPHID0_OFFSET 0xfe0 /* SSI Peripheral Identification 0 */ +#define TIVA_SSI_PERIPHID1_OFFSET 0xfe4 /* SSI Peripheral Identification 1 */ +#define TIVA_SSI_PERIPHID2_OFFSET 0xfe8 /* SSI Peripheral Identification 2 */ +#define TIVA_SSI_PERIPHID3_OFFSET 0xfec /* SSI Peripheral Identification 3 */ +#define TIVA_SSI_PCELLID0_OFFSET 0xff0 /* SSI PrimeCell Identification 0 */ +#define TIVA_SSI_PCELLID1_OFFSET 0xff4 /* SSI PrimeCell Identification 1 */ +#define TIVA_SSI_PCELLID2_OFFSET 0xff8 /* SSI PrimeCell Identification 2 */ +#define TIVA_SSI_PCELLID3_OFFSET 0xffc /* SSI PrimeCell Identification 3 */ + +/* SSI register addresses ***********************************************************/ + +#define TIVA_SSI0_CR0 (TIVA_SSI0_BASE + TIVA_SSI_CR0_OFFSET) +#define TIVA_SSI0_CR1 (TIVA_SSI0_BASE + TIVA_SSI_CR1_OFFSET) +#define TIVA_SSI0_DR (TIVA_SSI0_BASE + TIVA_SSI_DR_OFFSET) +#define TIVA_SSI0_SR (TIVA_SSI0_BASE + TIVA_SSI_SR_OFFSET) +#define TIVA_SSI0_CPSR (TIVA_SSI0_BASE + TIVA_SSI_CPSR_OFFSET) +#define TIVA_SSI0_IM (TIVA_SSI0_BASE + TIVA_SSI_IM_OFFSET) +#define TIVA_SSI0_RIS (TIVA_SSI0_BASE + TIVA_SSI_RIS_OFFSET) +#define TIVA_SSI0_MIS (TIVA_SSI0_BASE + TIVA_SSI_MIS_OFFSET) +#define TIVA_SSI0_ICR (TIVA_SSI0_BASE + TIVA_SSI_ICR_OFFSET) +#define TIVA_SSI0_PERIPHID4 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID4_OFFSET) +#define TIVA_SSI0_PERIPHID5 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID5_OFFSET) +#define TIVA_SSI0_PERIPHID6 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID6_OFFSET) +#define TIVA_SSI0_PERIPHID7 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID7_OFFSET) +#define TIVA_SSI0_PERIPHID0 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID0_OFFSET) +#define TIVA_SSI0_PERIPHID1 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID1_OFFSET) +#define TIVA_SSI0_PERIPHID2 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID2_OFFSET) +#define TIVA_SSI0_PERIPHID3 (TIVA_SSI0_BASE + TIVA_SSI_PERIPHID3_OFFSET) +#define TIVA_SSI0_PCELLID0 (TIVA_SSI0_BASE + TIVA_SSI_PCELLID0_OFFSET) +#define TIVA_SSI0_PCELLID1 (TIVA_SSI0_BASE + TIVA_SSI_PCELLID1_OFFSET) +#define TIVA_SSI0_PCELLID2 (TIVA_SSI0_BASE + TIVA_SSI_PCELLID2_OFFSET) +#define TIVA_SSI0_PCELLID3 (TIVA_SSI0_BASE + TIVA_SSI_PCELLID3_OFFSET) + +#if TIVA_NSSI > 1 +#define TIVA_SSI1_CR0 (TIVA_SSI1_BASE + TIVA_SSI_CR0_OFFSET) +#define TIVA_SSI1_CR1 (TIVA_SSI1_BASE + TIVA_SSI_CR1_OFFSET) +#define TIVA_SSI1_DR (TIVA_SSI1_BASE + TIVA_SSI_DR_OFFSET) +#define TIVA_SSI1_SR (TIVA_SSI1_BASE + TIVA_SSI_SR_OFFSET) +#define TIVA_SSI1_CPSR (TIVA_SSI1_BASE + TIVA_SSI_CPSR_OFFSET) +#define TIVA_SSI1_IM (TIVA_SSI1_BASE + TIVA_SSI_IM_OFFSET) +#define TIVA_SSI1_RIS (TIVA_SSI1_BASE + TIVA_SSI_RIS_OFFSET) +#define TIVA_SSI1_MIS (TIVA_SSI1_BASE + TIVA_SSI_MIS_OFFSET) +#define TIVA_SSI1_ICR (TIVA_SSI1_BASE + TIVA_SSI_ICR_OFFSET) +#define TIVA_SSI1_PERIPHID4 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID4_OFFSET) +#define TIVA_SSI1_PERIPHID5 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID5_OFFSET) +#define TIVA_SSI1_PERIPHID6 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID6_OFFSET) +#define TIVA_SSI1_PERIPHID7 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID7_OFFSET) +#define TIVA_SSI1_PERIPHID0 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID0_OFFSET) +#define TIVA_SSI1_PERIPHID1 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID1_OFFSET) +#define TIVA_SSI1_PERIPHID2 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID2_OFFSET) +#define TIVA_SSI1_PERIPHID3 (TIVA_SSI1_BASE + TIVA_SSI_PERIPHID3_OFFSET) +#define TIVA_SSI1_PCELLID0 (TIVA_SSI1_BASE + TIVA_SSI_PCELLID0_OFFSET) +#define TIVA_SSI1_PCELLID1 (TIVA_SSI1_BASE + TIVA_SSI_PCELLID1_OFFSET) +#define TIVA_SSI1_PCELLID2 (TIVA_SSI1_BASE + TIVA_SSI_PCELLID2_OFFSET) +#define TIVA_SSI1_PCELLID3 (TIVA_SSI1_BASE + TIVA_SSI_PCELLID3_OFFSET) + +#define TIVA_SSI_BASE(n) (TIVA_SSI0_BASE + (n)*0x01000) + +#define TIVA_SSI_CR0(n) (TIVA_SSI_BASE(n) + TIVA_SSI_CR0_OFFSET) +#define TIVA_SSI_CR1(n) (TIVA_SSI_BASE(n) + TIVA_SSI_CR1_OFFSET) +#define TIVA_SSI_DR(n) (TIVA_SSI_BASE(n) + TIVA_SSI_DR_OFFSET) +#define TIVA_SSI_SR(n) (TIVA_SSI_BASE(n) + TIVA_SSI_SR_OFFSET) +#define TIVA_SSI_CPSR(n) (TIVA_SSI_BASE(n) + TIVA_SSI_CPSR_OFFSET) +#define TIVA_SSI_IM(n) (TIVA_SSI_BASE(n) + TIVA_SSI_IM_OFFSET) +#define TIVA_SSI_RIS(n) (TIVA_SSI_BASE(n) + TIVA_SSI_RIS_OFFSET) +#define TIVA_SSI_MIS(n) (TIVA_SSI_BASE(n) + TIVA_SSI_MIS_OFFSET) +#define TIVA_SSI_ICR(n) (TIVA_SSI_BASE(n) + TIVA_SSI_ICR_OFFSET) +#define TIVA_SSI_PERIPHID4(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID4_OFFSET) +#define TIVA_SSI_PERIPHID5(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID5_OFFSET) +#define TIVA_SSI_PERIPHID6(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID6_OFFSET) +#define TIVA_SSI_PERIPHID7(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID7_OFFSET) +#define TIVA_SSI_PERIPHID0(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID0_OFFSET) +#define TIVA_SSI_PERIPHID1(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID1_OFFSET) +#define TIVA_SSI_PERIPHID2(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID2_OFFSET) +#define TIVA_SSI_PERIPHID3(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PERIPHID3_OFFSET) +#define TIVA_SSI_PCELLID0(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PCELLID0_OFFSET) +#define TIVA_SSI_PCELLID1(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PCELLID1_OFFSET) +#define TIVA_SSI_PCELLID2(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PCELLID2_OFFSET) +#define TIVA_SSI_PCELLID3(n) (TIVA_SSI_BASE(n) + TIVA_SSI_PCELLID3_OFFSET) +#endif /* TIVA_NSSI > 1 */ + +/* SSI register bit defitiions ******************************************************/ + +/* SSI Control 0 (SSICR0), offset 0x000 */ + +#define SSI_CR0_DSS_SHIFT 0 /* Bits 3-0: SSI Data Size Select */ +#define SSI_CR0_DSS_MASK (0x0f << SSI_CR0_DSS_SHIFT) +#define SSI_CR0_DSS(n) ((n-1) << SSI_CR0_DSS_SHIFT) /* n={4,5,..16} */ +#define SSI_CR0_FRF_SHIFT 4 /* Bits 5-4: SSI Frame Format Select */ +#define SSI_CR0_FRF_MASK (3 << SSI_CR0_FRF_SHIFT) +#define SSI_CR0_FRF_SPI (0 << SSI_CR0_FRF_SHIFT) /* Freescale SPI format */ +#define SSI_CR0_FRF_SSFF (1 << SSI_CR0_FRF_SHIFT) /* TI synchronous serial fram format */ +#define SSI_CR0_FRF_UWIRE (2 << SSI_CR0_FRF_SHIFT) /* MICROWIRE frame format */ + #define SSI_CR0_SPO (1 << 6) /* Bit 6: SSI Serial Clock Polarity */ +#define SSI_CR0_SPH (1 << 7) /* Bit 7: SSI Serial Clock Phase */ +#define SSI_CR0_SCR_SHIFT 8 /* Bits 15-8: SSI Serial Clock Rate */ +#define SSI_CR0_SCR_MASK (0xff << SSI_CR0_SCR_SHIFT) + +/* SSI Control 1 (SSICR1), offset 0x004 */ + +#define SSI_CR1_LBM (1 << 0) /* Bit 0: SSI Loopback Mode */ +#define SSI_CR1_SSE (1 << 1) /* Bit 1: SSI Synchronous Serial Port Enable */ +#define SSI_CR1_MS (1 << 2) /* Bit 2: SSI Master/Slave Select slave */ +#define SSI_CR1_SOD (1 << 3) /* Bit 3: SSI Slave Mode Output Disable */ + +/* SSI Data (SSIDR), offset 0x008 */ + +#define SSI_DR_MASK 0xffff /* Bits 15-0: SSI data */ + +/* SSI Status (SSISR), offset 0x00c */ + +#define SSI_SR_TFE (1 << 0) /* Bit 0: SSI Transmit FIFO Empty */ +#define SSI_SR_TNF (1 << 1) /* Bit 1: SSI Transmit FIFO Not Full */ +#define SSI_SR_RNE (1 << 2) /* Bit 2: SSI Receive FIFO Not Empty */ +#define SSI_SR_RFF (1 << 3) /* Bit 3: SSI Receive FIFO Full */ +#define SSI_SR_BSY (1 << 4) /* Bit 4: SSI Busy Bit */ + +/* SSI Clock Prescale (SSICPSR), offset 0x010 */ + +#define SSI_CPSR_DIV_MASK 0xff /* Bits 7-0: SSI Clock Prescale Divisor */ + +/* SSI Interrupt Mask (SSIIM), offset 0x014 */ + +#define SSI_IM_ROR (1 << 0) /* Bit 0: SSI Receive Overrun Interrupt Mask */ +#define SSI_IM_RT (1 << 1) /* Bit 1: SSI Receive Time-Out Interrupt Mask */ +#define SSI_IM_RX (1 << 2) /* Bit 2: SSI Receive FIFO Interrupt Mask */ +#define SSI_IM_TX (1 << 3) /* Bit 3: SSI Transmit FIFO Interrupt Mask */ + +/* SSI Raw Interrupt Status (SSIRIS), offset 0x018 */ + +#define SSI_RIS_ROR (1 << 0) /* Bit 0: SSI Receive Overrun Raw Interrupt Status */ +#define SSI_RIS_RT (1 << 1) /* Bit 1: SSI Receive Time-Out Raw Interrupt Status */ +#define SSI_RIS_RX (1 << 2) /* Bit 2: SSI Receive FIFO Raw Interrupt Status */ +#define SSI_RIS_TX (1 << 3) /* Bit 3: SSI Transmit FIFO Raw Interrupt Status */ + +/* SSI Masked Interrupt Status (SSIMIS), offset 0x01c */ + +#define SSI_MIS_ROR (1 << 0) /* Bit 0: SSI Receive Overrun Masked Interrupt Status */ +#define SSI_MIS_RT (1 << 1) /* Bit 1: SSI Receive Time-Out Masked Interrupt Status */ +#define SSI_MIS_RX (1 << 2) /* Bit 2: SSI Receive FIFO Masked Interrupt Status */ +#define SSI_MIS_TX (1 << 3) /* Bit 3: SSI Transmit FIFO Masked Interrupt Status */ + +/* SSI Interrupt Clear (SSIICR), offset 0x020 */ + +#define SSI_ICR_ROR (1 << 0) /* Bit 0: SSI Receive Overrun Interrupt Clear */ +#define SSI_ICR_RT (1 << 1) /* Bit 1: SSI Receive Time-Out Interrupt Clear */ + +/* SSI Peripheral Identification n (SSIPERIPHIDn), offset 0xfd0-0xfec */ + +#define SSI_PERIPHID_MASK 0xff /* Bits 7-0: SSI Peripheral ID n */ + +/* SSI PrimeCell Identification n (SSIPCELLIDn), offset 0xff0-0xffc */ + +#define SSI_PCELLID_MASK 0xff /* Bits 7-0: SSI Prime cell ID */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* TIVA_NSSI > 0 */ +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SSI_H */ diff --git a/arch/arm/src/tiva/chip/tiva_syscontrol.h b/arch/arm/src/tiva/chip/tiva_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..7ba32a372b531d071b4bed349d19ca45e1f82821 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_syscontrol.h @@ -0,0 +1,78 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_syscontrol.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SYSCONTROL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/* Include the system control header file for the specific Tiva/Stellaris chip */ + +#if defined(CONFIG_ARCH_CHIP_LM3S) +# include "chip/lm3s_syscontrol.h" +#elif defined(CONFIG_ARCH_CHIP_LM4F) +# include "chip/lm4f_syscontrol.h" +#elif defined(CONFIG_ARCH_CHIP_TM4C123) +# include "chip/tm4c123_syscontrol.h" +#elif defined(CONFIG_ARCH_CHIP_TM4C129) +# include "chip/tm4c129_syscontrol.h" +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# include "chip/cc3200_syscontrol.h" +#else +# error "Unsupported Tiva/Stellaris system control module" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/tiva_timer.h b/arch/arm/src/tiva/chip/tiva_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..9a7a3f1808c6b819d16d29c32747ab159c7134af --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_timer.h @@ -0,0 +1,812 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_timer.h + * + * Originally: + * + * Copyright (C) 2012, 2014 Max Nekludov. All rights reserved. + * Author: Max Nekludov + * + * Ongoing support and major revision to support the TM4C129 family + * (essentially a full file replacement): + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some bitfield definitions taken from a header file provided by: + * + * Copyright (C) 2014 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_TIMER_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPTM register offsets ************************************************************/ + +#define TIVA_TIMER_CFG_OFFSET 0x0000 /* GPTM Configuration */ +#define TIVA_TIMER_TAMR_OFFSET 0x0004 /* GPTM Timer A Mode */ +#define TIVA_TIMER_TBMR_OFFSET 0x0008 /* GPTM Timer B Mode */ +#define TIVA_TIMER_CTL_OFFSET 0x000c /* GPTM Control */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER_SYNC_OFFSET 0x0010 /* GPTM Synchronize (GPTM0 only) */ +#endif + +#define TIVA_TIMER_IMR_OFFSET 0x0018 /* GPTM Interrupt Mask */ +#define TIVA_TIMER_RIS_OFFSET 0x001c /* GPTM Raw Interrupt Status */ +#define TIVA_TIMER_MIS_OFFSET 0x0020 /* GPTM Masked Interrupt Status */ +#define TIVA_TIMER_ICR_OFFSET 0x0024 /* GPTM Interrupt Clear */ +#define TIVA_TIMER_TAILR_OFFSET 0x0028 /* GPTM Timer A Interval Load */ +#define TIVA_TIMER_TBILR_OFFSET 0x002c /* GPTM Timer B Interval Load */ +#define TIVA_TIMER_TAMATCHR_OFFSET 0x0030 /* GPTM Timer A Match */ +#define TIVA_TIMER_TBMATCHR_OFFSET 0x0034 /* GPTM Timer B Match */ +#define TIVA_TIMER_TAPR_OFFSET 0x0038 /* GPTM Timer A Prescale */ +#define TIVA_TIMER_TBPR_OFFSET 0x003c /* GPTM Timer B Prescale */ +#define TIVA_TIMER_TAPMR_OFFSET 0x0040 /* GPTM TimerA Prescale Match */ +#define TIVA_TIMER_TBPMR_OFFSET 0x0044 /* GPTM TimerB Prescale Match */ +#define TIVA_TIMER_TAR_OFFSET 0x0048 /* GPTM Timer A */ +#define TIVA_TIMER_TBR_OFFSET 0x004c /* GPTM Timer B */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER_TAV_OFFSET 0x0050 /* GPTM Timer A Value */ +# define TIVA_TIMER_TBV_OFFSET 0x0054 /* GPTM Timer B Value */ +# define TIVA_TIMER_RTCPD_OFFSET 0x0058 /* GPTM RTC Predivide */ +# define TIVA_TIMER_TAPS_OFFSET 0x005c /* GPTM Timer A Prescale Snapshot */ +# define TIVA_TIMER_TBPS_OFFSET 0x0060 /* GPTM Timer B Prescale Snapshot */ +# define TIVA_TIMER_TAPV_OFFSET 0x0064 /* GPTM Timer A Prescale Value */ +# define TIVA_TIMER_TBPV_OFFSET 0x0068 /* GPTM Timer B Prescale Value */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER_DMAEV_OFFSET 0x006c /* GPTM DMA Event */ +# define TIVA_TIMER_ADCEV_OFFSET 0x0070 /* GPTM ADC Event */ +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER_PP_OFFSET 0x0fc0 /* GPTM Peripheral Properties */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER_CC_OFFSET 0x0fc8 /* GPTM Clock Configuration */ +#endif + +/* GPTM register addresses **********************************************************/ + +#if TIVA_NTIMERS > 0 +#define TIVA_TIMER0_CFG (TIVA_TIMER0_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER0_TAMR (TIVA_TIMER0_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER0_TBMR (TIVA_TIMER0_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER0_CTL (TIVA_TIMER0_BASE + TIVA_TIMER_CTL_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER0_SYNC (TIVA_TIMER0_BASE + TIVA_TIMER_SYNC_OFFSET) +#endif + +#define TIVA_TIMER0_IMR (TIVA_TIMER0_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER0_RIS (TIVA_TIMER0_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER0_MIS (TIVA_TIMER0_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER0_ICR (TIVA_TIMER0_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER0_TAILR (TIVA_TIMER0_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER0_TBILR (TIVA_TIMER0_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER0_TAMATCHR (TIVA_TIMER0_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER0_TBMATCHR (TIVA_TIMER0_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER0_TAPR (TIVA_TIMER0_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER0_TBPR (TIVA_TIMER0_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER0_TAPMR (TIVA_TIMER0_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER0_TBPMR (TIVA_TIMER0_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER0_TAR (TIVA_TIMER0_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER0_TBR (TIVA_TIMER0_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER0_TAV (TIVA_TIMER0_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER0_TBV (TIVA_TIMER0_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER0_RTCPD (TIVA_TIMER0_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER0_TAPS (TIVA_TIMER0_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER0_TBPS (TIVA_TIMER0_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER0_TAPV (TIVA_TIMER0_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER0_TBPV (TIVA_TIMER0_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER0_DMAEV (TIVA_TIMER0_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER0_ADCEV (TIVA_TIMER0_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER0_PP (TIVA_TIMER0_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER0_CC (TIVA_TIMER0_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 0 */ + +#if TIVA_NTIMERS > 1 +#define TIVA_TIMER1_CFG (TIVA_TIMER1_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER1_TAMR (TIVA_TIMER1_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER1_TBMR (TIVA_TIMER1_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER1_CTL (TIVA_TIMER1_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER1_IMR (TIVA_TIMER1_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER1_RIS (TIVA_TIMER1_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER1_MIS (TIVA_TIMER1_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER1_ICR (TIVA_TIMER1_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER1_TAILR (TIVA_TIMER1_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER1_TBILR (TIVA_TIMER1_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER1_TAMATCHR (TIVA_TIMER1_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER1_TBMATCHR (TIVA_TIMER1_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER1_TAPR (TIVA_TIMER1_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER1_TBPR (TIVA_TIMER1_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER1_TAPMR (TIVA_TIMER1_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER1_TBPMR (TIVA_TIMER1_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER1_TAR (TIVA_TIMER1_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER1_TBR (TIVA_TIMER1_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER1_TAV (TIVA_TIMER1_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER1_TBV (TIVA_TIMER1_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER1_RTCPD (TIVA_TIMER1_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER1_TAPS (TIVA_TIMER1_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER1_TBPS (TIVA_TIMER1_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER1_TAPV (TIVA_TIMER1_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER1_TBPV (TIVA_TIMER1_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER1_DMAEV (TIVA_TIMER1_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER1_ADCEV (TIVA_TIMER1_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER1_PP (TIVA_TIMER1_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER1_CC (TIVA_TIMER1_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 1 */ + +#if TIVA_NTIMERS > 2 +#define TIVA_TIMER2_CFG (TIVA_TIMER2_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER2_TAMR (TIVA_TIMER2_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER2_TBMR (TIVA_TIMER2_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER2_CTL (TIVA_TIMER2_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER2_IMR (TIVA_TIMER2_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER2_RIS (TIVA_TIMER2_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER2_MIS (TIVA_TIMER2_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER2_ICR (TIVA_TIMER2_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER2_TAILR (TIVA_TIMER2_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER2_TBILR (TIVA_TIMER2_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER2_TAMATCHR (TIVA_TIMER2_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER2_TBMATCHR (TIVA_TIMER2_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER2_TAPR (TIVA_TIMER2_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER2_TBPR (TIVA_TIMER2_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER2_TAPMR (TIVA_TIMER2_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER2_TBPMR (TIVA_TIMER2_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER2_TAR (TIVA_TIMER2_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER2_TBR (TIVA_TIMER2_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER2_TAV (TIVA_TIMER2_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER2_TBV (TIVA_TIMER2_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER2_RTCPD (TIVA_TIMER2_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER2_TAPS (TIVA_TIMER2_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER2_TBPS (TIVA_TIMER2_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER2_TAPV (TIVA_TIMER2_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER2_TBPV (TIVA_TIMER2_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER2_DMAEV (TIVA_TIMER2_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER2_ADCEV (TIVA_TIMER2_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER2_PP (TIVA_TIMER2_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER2_CC (TIVA_TIMER2_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 2 */ + +#if TIVA_NTIMERS > 3 +#define TIVA_TIMER3_CFG (TIVA_TIMER3_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER3_TAMR (TIVA_TIMER3_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER3_TBMR (TIVA_TIMER3_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER3_CTL (TIVA_TIMER3_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER3_IMR (TIVA_TIMER3_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER3_RIS (TIVA_TIMER3_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER3_MIS (TIVA_TIMER3_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER3_ICR (TIVA_TIMER3_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER3_TAILR (TIVA_TIMER3_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER3_TBILR (TIVA_TIMER3_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER3_TAMATCHR (TIVA_TIMER3_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER3_TBMATCHR (TIVA_TIMER3_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER3_TAPR (TIVA_TIMER3_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER3_TBPR (TIVA_TIMER3_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER3_TAPMR (TIVA_TIMER3_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER3_TBPMR (TIVA_TIMER3_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER3_TAR (TIVA_TIMER3_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER3_TBR (TIVA_TIMER3_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER3_TAV (TIVA_TIMER3_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER3_TBV (TIVA_TIMER3_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER3_RTCPD (TIVA_TIMER3_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER3_TAPS (TIVA_TIMER3_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER3_TBPS (TIVA_TIMER3_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER3_TAPV (TIVA_TIMER3_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER3_TBPV (TIVA_TIMER3_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER3_DMAEV (TIVA_TIMER3_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER3_ADCEV (TIVA_TIMER3_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER3_PP (TIVA_TIMER3_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER3_CC (TIVA_TIMER3_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 3 */ + +#if TIVA_NTIMERS > 4 +#define TIVA_TIMER4_CFG (TIVA_TIMER4_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER4_TAMR (TIVA_TIMER4_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER4_TBMR (TIVA_TIMER4_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER4_CTL (TIVA_TIMER4_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER4_IMR (TIVA_TIMER4_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER4_RIS (TIVA_TIMER4_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER4_MIS (TIVA_TIMER4_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER4_ICR (TIVA_TIMER4_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER4_TAILR (TIVA_TIMER4_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER4_TBILR (TIVA_TIMER4_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER4_TAMATCHR (TIVA_TIMER4_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER4_TBMATCHR (TIVA_TIMER4_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER4_TAPR (TIVA_TIMER4_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER4_TBPR (TIVA_TIMER4_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER4_TAPMR (TIVA_TIMER4_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER4_TBPMR (TIVA_TIMER4_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER4_TAR (TIVA_TIMER4_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER4_TBR (TIVA_TIMER4_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER4_TAV (TIVA_TIMER4_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER4_TBV (TIVA_TIMER4_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER4_RTCPD (TIVA_TIMER4_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER4_TAPS (TIVA_TIMER4_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER4_TBPS (TIVA_TIMER4_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER4_TAPV (TIVA_TIMER4_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER4_TBPV (TIVA_TIMER4_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER4_DMAEV (TIVA_TIMER4_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER4_ADCEV (TIVA_TIMER4_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER4_PP (TIVA_TIMER4_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER4_CC (TIVA_TIMER4_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 4 */ + +#if TIVA_NTIMERS > 5 +#define TIVA_TIMER5_CFG (TIVA_TIMER5_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER5_TAMR (TIVA_TIMER5_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER5_TBMR (TIVA_TIMER5_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER5_CTL (TIVA_TIMER5_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER5_IMR (TIVA_TIMER5_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER5_RIS (TIVA_TIMER5_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER5_MIS (TIVA_TIMER5_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER5_ICR (TIVA_TIMER5_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER5_TAILR (TIVA_TIMER5_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER5_TBILR (TIVA_TIMER5_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER5_TAMATCHR (TIVA_TIMER5_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER5_TBMATCHR (TIVA_TIMER5_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER5_TAPR (TIVA_TIMER5_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER5_TBPR (TIVA_TIMER5_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER5_TAPMR (TIVA_TIMER5_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER5_TBPMR (TIVA_TIMER5_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER5_TAR (TIVA_TIMER5_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER5_TBR (TIVA_TIMER5_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER5_TAV (TIVA_TIMER5_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER5_TBV (TIVA_TIMER5_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER5_RTCPD (TIVA_TIMER5_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER5_TAPS (TIVA_TIMER5_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER5_TBPS (TIVA_TIMER5_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER5_TAPV (TIVA_TIMER5_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER5_TBPV (TIVA_TIMER5_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER5_DMAEV (TIVA_TIMER5_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER5_ADCEV (TIVA_TIMER5_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER5_PP (TIVA_TIMER5_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER5_CC (TIVA_TIMER5_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 5 */ + +#if TIVA_NTIMERS > 6 +#define TIVA_TIMER6_CFG (TIVA_TIMER6_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER6_TAMR (TIVA_TIMER6_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER6_TBMR (TIVA_TIMER6_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER6_CTL (TIVA_TIMER6_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER6_IMR (TIVA_TIMER6_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER6_RIS (TIVA_TIMER6_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER6_MIS (TIVA_TIMER6_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER6_ICR (TIVA_TIMER6_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER6_TAILR (TIVA_TIMER6_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER6_TBILR (TIVA_TIMER6_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER6_TAMATCHR (TIVA_TIMER6_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER6_TBMATCHR (TIVA_TIMER6_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER6_TAPR (TIVA_TIMER6_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER6_TBPR (TIVA_TIMER6_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER6_TAPMR (TIVA_TIMER6_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER6_TBPMR (TIVA_TIMER6_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER6_TAR (TIVA_TIMER6_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER6_TBR (TIVA_TIMER6_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER6_TAV (TIVA_TIMER6_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER6_TBV (TIVA_TIMER6_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER6_RTCPD (TIVA_TIMER6_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER6_TAPS (TIVA_TIMER6_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER6_TBPS (TIVA_TIMER6_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER6_TAPV (TIVA_TIMER6_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER6_TBPV (TIVA_TIMER6_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER6_DMAEV (TIVA_TIMER6_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER6_ADCEV (TIVA_TIMER6_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER6_PP (TIVA_TIMER6_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER6_CC (TIVA_TIMER6_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 6 */ + +#if TIVA_NTIMERS > 7 +#define TIVA_TIMER7_CFG (TIVA_TIMER7_BASE + TIVA_TIMER_CFG_OFFSET) +#define TIVA_TIMER7_TAMR (TIVA_TIMER7_BASE + TIVA_TIMER_TAMR_OFFSET) +#define TIVA_TIMER7_TBMR (TIVA_TIMER7_BASE + TIVA_TIMER_TBMR_OFFSET) +#define TIVA_TIMER7_CTL (TIVA_TIMER7_BASE + TIVA_TIMER_CTL_OFFSET) +#define TIVA_TIMER7_IMR (TIVA_TIMER7_BASE + TIVA_TIMER_IMR_OFFSET) +#define TIVA_TIMER7_RIS (TIVA_TIMER7_BASE + TIVA_TIMER_RIS_OFFSET) +#define TIVA_TIMER7_MIS (TIVA_TIMER7_BASE + TIVA_TIMER_MIS_OFFSET) +#define TIVA_TIMER7_ICR (TIVA_TIMER7_BASE + TIVA_TIMER_ICR_OFFSET) +#define TIVA_TIMER7_TAILR (TIVA_TIMER7_BASE + TIVA_TIMER_TAILR_OFFSET) +#define TIVA_TIMER7_TBILR (TIVA_TIMER7_BASE + TIVA_TIMER_TBILR_OFFSET) +#define TIVA_TIMER7_TAMATCHR (TIVA_TIMER7_BASE + TIVA_TIMER_TAMATCHR_OFFSET) +#define TIVA_TIMER7_TBMATCHR (TIVA_TIMER7_BASE + TIVA_TIMER_TBMATCHR_OFFSET) +#define TIVA_TIMER7_TAPR (TIVA_TIMER7_BASE + TIVA_TIMER_TAPR_OFFSET) +#define TIVA_TIMER7_TBPR (TIVA_TIMER7_BASE + TIVA_TIMER_TBPR_OFFSET) +#define TIVA_TIMER7_TAPMR (TIVA_TIMER7_BASE + TIVA_TIMER_TAPMR_OFFSET) +#define TIVA_TIMER7_TBPMR (TIVA_TIMER7_BASE + TIVA_TIMER_TBPMR_OFFSET) +#define TIVA_TIMER7_TAR (TIVA_TIMER7_BASE + TIVA_TIMER_TAR_OFFSET) +#define TIVA_TIMER7_TBR (TIVA_TIMER7_BASE + TIVA_TIMER_TBR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER7_TAV (TIVA_TIMER7_BASE + TIVA_TIMER_TAV_OFFSET) +# define TIVA_TIMER7_TBV (TIVA_TIMER7_BASE + TIVA_TIMER_TBV_OFFSET) +# define TIVA_TIMER7_RTCPD (TIVA_TIMER7_BASE + TIVA_TIMER_RTCPD_OFFSET) +# define TIVA_TIMER7_TAPS (TIVA_TIMER7_BASE + TIVA_TIMER_TAPS_OFFSET) +# define TIVA_TIMER7_TBPS (TIVA_TIMER7_BASE + TIVA_TIMER_TBPS_OFFSET) +# define TIVA_TIMER7_TAPV (TIVA_TIMER7_BASE + TIVA_TIMER_TAPV_OFFSET) +# define TIVA_TIMER7_TBPV (TIVA_TIMER7_BASE + TIVA_TIMER_TBPV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER7_DMAEV (TIVA_TIMER7_BASE + TIVA_TIMER_DMAEV_OFFSET) +# define TIVA_TIMER7_ADCEV (TIVA_TIMER7_BASE + TIVA_TIMER_ADCEV_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIVA_TIMER7_PP (TIVA_TIMER7_BASE + TIVA_TIMER_PP_OFFSET) +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_TIMER7_CC (TIVA_TIMER7_BASE + TIVA_TIMER_CC_OFFSET) +#endif +#endif /* TIVA_NTIMERS > 7 */ + +/* GPTM register bit definitions ****************************************************/ +/* GPTM Configuration (CFG) */ + +#define TIMER_CFG_CFG_SHIFT 0 /* Bits 2-0: Configuration */ +#define TIMER__CFG_MASK (7 << TIMER_CFG_CFG_SHIFT) +# define TIMER_CFG_CFG_32 (0 << TIMER_CFG_CFG_SHIFT) /* 32-bit timer configuration */ +# define TIMER_CFG_CFG_RTC (1 << TIMER_CFG_CFG_SHIFT) /* 32-bit real-time clock (RTC) counter configuration */ +# define TIMER_CFG_CFG_16 (4 << TIMER_CFG_CFG_SHIFT) /* 16-bit timer configuration */ + +/* GPTM Timer A/B Mode (TAMR and TBMR) */ + +#define TIMER_TnMR_TnMR_SHIFT 0 /* Bits 1-0: Timer A/B Mode */ +#define TIMER_TnMR_TnMR_MASK (3 << TIMER_TnMR_TnMR_SHIFT) +# define TIMER_TnMR_TnMR_ONESHOT (1 << TIMER_TnMR_TnMR_SHIFT) /* One-Shot Timer mode */ +# define TIMER_TnMR_TnMR_PERIODIC (2 << TIMER_TnMR_TnMR_SHIFT) /* Periodic Timer mode */ +# define TIMER_TnMR_TnMR_CAPTURE (3 << TIMER_TnMR_TnMR_SHIFT) /* Capture mode */ +#define TIMER_TnMR_TnCMR (1 << 2) /* Bit 2: Timer A/B Capture Mode */ +# define TIMER_TnMR_TnCMR_EDGECOUNT (0 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Count mode */ +# define TIMER_TnMR_TnCMR_EDGETIME (1 << TIMER_TnMR_TnCMR_SHIFT) /* Edge-Time mode */ +#define TIMER_TnMR_TnAMS (1 << 3) /* Bit 3: Timer A/B Alternate Mode Select */ +# define TIMER_TnMR_TnAMS_CAPTURE (0 << TIMER_TnMR_TnAMS_SHIFT) /* Capture mode is enabled */ +# define TIMER_TnMR_TnAMS_PWM (1 << TIMER_TnMR_TnAMS_SHIFT) /* PWM mode is enabled */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_TnMR_TnCDIR (1 << 4) /* Bit 4: Timer A/B Count Direction */ +# define TIMER_TnMR_TnCDIR_DOWN (0) /* Timer counts down */ +# define TIMER_TnMR_TnCDIR_UP TIMER_TnMR_TnCDIR /* Timer counts up (one-shot/periodic modes) */ +# define TIMER_TnMR_TnMIE (1 << 5) /* Bit 5: Timer A/B Match Interrupt Enable */ +# define TIMER_TnMR_TnWOT (1 << 6) /* Bit 6: GPTM Timer A/B Wait-on-Trigger */ +# define TIMER_TnMR_TnSNAPS (1 << 7) /* Bit 7: GPTM Timer A/B Snap-Shot Mode */ +# define TIMER_TnMR_TnILD (1 << 8) /* Bit 8: GPTM Timer A/B Interval Load Write */ +# define TIMER_TnMR_TnPWMIE (1 << 9) /* Bit 9: GPTM Timer A/B PWM Interrupt Enable */ +# define TIMER_TnMR_TnMRSU (1 << 10) /* Bit 10: GPTM Timer A/B Match Register Update */ +# define TIMER_TnMR_TnPLO (1 << 11) /* Bit 11: GPTM Timer A/B PWM Legacy Operation */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_TnMR_TnCINTD (1 << 12) /* Bit 12: One-shot/Periodic Interrupt Disable */ +# define TIMER_TnMR_TCACT_SHIFT (13) /* Bits 13-15: Timer Compare Action Select */ +# define TIMER_TnMR_TCACT_MASK (7 << TIMER_TnMR_TCACT_SHIFT) +# define TIMER_TnMR_TCACT_NONE (0 << TIMER_TnMR_TCACT_SHIFT) /* Disable compare operations */ +# define TIMER_TnMR_TCACT_TOGGLE (1 << TIMER_TnMR_TCACT_SHIFT) /* Toggle state on timeout */ +# define TIMER_TnMR_TCACT_CLRTO (2 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP on timeout */ +# define TIMER_TnMR_TCACT_SETTO (3 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP on timeout */ +# define TIMER_TnMR_TCACT_SETTOGTO (4 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP and toggle on TimeOut */ +# define TIMER_TnMR_TCACT_CLRTOGTO (5 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP and toggle on TimeOut */ +# define TIMER_TnMR_TCACT_SETCLRTO (6 << TIMER_TnMR_TCACT_SHIFT) /* Set CCP and clear on timeout */ +# define TIMER_TnMR_TCACT_CLRSETTO (7 << TIMER_TnMR_TCACT_SHIFT) /* Clear CCP and set on timeout */ +#endif + +/* GPTM Control (CTL) */ + +#define TIMER_CTL_TAEN (1 << 0) /* Bit 0: Timer A Enable */ +#define TIMER_CTL_TASTALL (1 << 1) /* Bit 1: Timer A Stall Enable */ +#define TIMER_CTL_TAEVENT_SHIFT (2) /* Bits 2-3: GPTM Timer A Event Mode */ +#define TIMER_CTL_TAEVENT_MASK (3 << TIMER_CTL_TAEVENT_SHIFT) +# define TIMER_CTL_TAEVENT_POS (0 << TIMER_CTL_TAEVENT_SHIFT) /* Positive edge */ +# define TIMER_CTL_TAEVENT_NEG (1 << TIMER_CTL_TAEVENT_SHIFT) /* Negative edge */ +# define TIMER_CTL_TAEVENT_BOTH (3 << TIMER_CTL_TAEVENT_SHIFT) /* Both edges */ +#define TIMER_CTL_RTCEN (1 << 4) /* Bit 4: GPTM RTC Stall Enable */ +#define TIMER_CTL_TAOTE (1 << 5) /* Bit 5: GPTM Timer A Output Trigger Enable */ +#define TIMER_CTL_TAPWML (1 << 6) /* Bit 6: GPTM Timer A PWM Output Level */ +#define TIMER_CTL_TBEN (1 << 8) /* Bit 8: GPTM Timer B Enable */ +#define TIMER_CTL_TBSTALL (1 << 9) /* Bit 9: GPTM Timer B Stall Enable */ +#define TIMER_CTL_TBEVENT_SHFIT (10) /* Bits 10-11: GPTM Timer B Event Mode */ +#define TIMER_CTL_TBEVENT_MASK (3 << TIMER_CTL_TBEVENT_SHFIT) +# define TIMER_CTL_TBEVENT_POS (0 << TIMER_CTL_TBEVENT_SHFIT) /* Positive edge */ +# define TIMER_CTL_TBEVENT_NEG (1 << TIMER_CTL_TBEVENT_SHFIT) /* Negative edge */ +# define TIMER_CTL_TBEVENT_BOTH (3 << TIMER_CTL_TBEVENT_SHFIT) /* Both edges */ +#define TIMER_CTL_TBOTE (1 << 13) /* Bit 13: GPTM Timer B Output Trigger Enable */ +#define TIMER_CTL_TBPWML (1 << 14) /* Bit 14: GPTM Timer B PWM Output Level */ + +/* GPTM Synchronize (GPTM0 only) */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_SYNC_NONE 0 /* GPTMn is not affected */ +# define TIMER_SYNC_TA 1 /* Timer A timeout event triggered */ +# define TIMER_SYNC_TB 2 /* Timer B timeout event triggered */ +# define TIMER_SYNC_TATB 3 /* Both Timer A/B timeout event triggered */ + +# define TIMER_SYNC_SYNCT_SHIFT(i) ((i) << 1) /* Synchronize GPTMi timer i */ +# define TIMER_SYNC_SYNCT_MASK(i) (3 << TIMER_SYNC_SYNCT_SHIFT(i)) +# define TIMER_SYNC_SYNCT(i,n) ((uint32_t)(n) << TIMER_SYNC_SYNCT_SHIFT(i)) +# define TIMER_SYNC_SYNCT_NONE(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT_TA(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT_TB(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT_TATB(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TATB) + +# define TIMER_SYNC_SYNCT0_SHIFT (0) /* Bits 0-1: Synchronize GPTM timer 0 */ +# define TIMER_SYNC_SYNCT0_MASK (3 << TIMER_SYNC_SYNCT0_SHIFT) +# define TIMER_SYNC_SYNCT0(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT0_SHIFT) +# define TIMER_SYNC_SYNCT0_NONE TIMER_SYNC_SYNCT0(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT0_TA TIMER_SYNC_SYNCT0(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT0_TB TIMER_SYNC_SYNCT0(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT0_TATB TIMER_SYNC_SYNCT0(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT1_SHIFT (2) /* Synchronize GPTM timer 1 */ +# define TIMER_SYNC_SYNCT1_MASK (3 << TIMER_SYNC_SYNCT1_SHIFT) +# define TIMER_SYNC_SYNCT1(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT1_SHIFT) +# define TIMER_SYNC_SYNCT1_NONE TIMER_SYNC_SYNCT1(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT1_TA TIMER_SYNC_SYNCT1(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT1_TB TIMER_SYNC_SYNCT1(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT1_TATB TIMER_SYNC_SYNCT1(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT2_SHIFT (4) /* Synchronize GPTM timer 2 */ +# define TIMER_SYNC_SYNCT2_MASK (3 << ) +# define TIMER_SYNC_SYNCT2(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT2_SHIFT) +# define TIMER_SYNC_SYNCT2_NONE TIMER_SYNC_SYNCT2(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT2_TA TIMER_SYNC_SYNCT2(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT2_TB TIMER_SYNC_SYNCT2(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT2_TATB TIMER_SYNC_SYNCT2(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT3_SHIFT (6) /* Synchronize GPTM timer 3 */ +# define TIMER_SYNC_SYNCT3_MASK (3 << ) +# define TIMER_SYNC_SYNCT3(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT3_SHIFT) +# define TIMER_SYNC_SYNCT3_NONE TIMER_SYNC_SYNCT3(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT3_TA TIMER_SYNC_SYNCT3(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT3_TB TIMER_SYNC_SYNCT3(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT3_TATB TIMER_SYNC_SYNCT3(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT4_SHIFT (8) /* Synchronize GPTM timer 4 */ +# define TIMER_SYNC_SYNCT4_MASK (3 << ) +# define TIMER_SYNC_SYNCT4(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT4_SHIFT) +# define TIMER_SYNC_SYNCT4_NONE TIMER_SYNC_SYNCT4(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT4_TA TIMER_SYNC_SYNCT4(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT4_TB TIMER_SYNC_SYNCT4(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT4_TATB TIMER_SYNC_SYNCT4(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT5_SHIFT (10) /* Synchronize GPTM timer 5 */ +# define TIMER_SYNC_SYNCT5_MASK (3 << ) +# define TIMER_SYNC_SYNCT5(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT5_SHIFT) +# define TIMER_SYNC_SYNCT5_NONE TIMER_SYNC_SYNCT5(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT5_TA TIMER_SYNC_SYNCT5(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT5_TB TIMER_SYNC_SYNCT5(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT5_TATB TIMER_SYNC_SYNCT5(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT6_SHIFT (12) /* Synchronize GPTM timer 6 */ +# define TIMER_SYNC_SYNCT6_MASK (3 << ) +# define TIMER_SYNC_SYNCT6(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT6_SHIFT) +# define TIMER_SYNC_SYNCT6_NONE TIMER_SYNC_SYNCT6(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT6_TA TIMER_SYNC_SYNCT6(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT6_TB TIMER_SYNC_SYNCT6(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT6_TATB TIMER_SYNC_SYNCT6(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCT7_SHIFT (14) /* Synchronize GPTM timer 7 */ +# define TIMER_SYNC_SYNCT7_MASK (3 << ) +# define TIMER_SYNC_SYNCT7(n) ((uint32_t)(n) << TIMER_SYNC_SYNCT7_SHIFT) +# define TIMER_SYNC_SYNCT7_NONE TIMER_SYNC_SYNCT7(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCT7_TA TIMER_SYNC_SYNCT7(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCT7_TB TIMER_SYNC_SYNCT7(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCT7_TATB TIMER_SYNC_SYNCT7(TIMER_SYNC_TATB) + +# define TIMER_SYNC_SYNCWT_SHIFT(i) ((i) << 1) /* Synchronize GPTMi 32/64-Bit Timer i */ +# define TIMER_SYNC_SYNCWT_MASK(i) (3 << TIMER_SYNC_SYNCT_SHIFT(i)) +# define TIMER_SYNC_SYNCWT(i,n) ((uint32_t)(n) << TIMER_SYNC_SYNCT_SHIFT(i)) +# define TIMER_SYNC_SYNCWT_NONE(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT_TA(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT_TB(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT_TATB(i) TIMER_SYNC_SYNCT(i,TIMER_SYNC_TATB) + +# define TIMER_SYNC_SYNCWT0_SHIFT (12) /* Synchronize WTM 32/64-Bit wide timer 0 */ +# define TIMER_SYNC_SYNCWT0_MASK (3 << TIMER_SYNC_SYNCWT0_SHIFT) +# define TIMER_SYNC_SYNCWT0(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT0_SHIFT) +# define TIMER_SYNC_SYNCWT0_NONE TIMER_SYNC_SYNCWT0(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT0_TA TIMER_SYNC_SYNCWT0(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT0_TB TIMER_SYNC_SYNCWT0(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT0_TATB TIMER_SYNC_SYNCWT0(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCWT1_SHIFT (14) /* Synchronize WTM 32/64-Bit wide timer 1 */ +# define TIMER_SYNC_SYNCWT1_MASK (3 << ) +# define TIMER_SYNC_SYNCWT1(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT1_SHIFT) +# define TIMER_SYNC_SYNCWT1_NONE TIMER_SYNC_SYNCWT1(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT1_TA TIMER_SYNC_SYNCWT1(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT1_TB TIMER_SYNC_SYNCWT1(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT1_TATB TIMER_SYNC_SYNCWT1(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCWT2_SHIFT (16) /* Synchronize WTM 32/64-Bit wide timer 2 */ +# define TIMER_SYNC_SYNCWT2_MASK (3 << ) +# define TIMER_SYNC_SYNCWT2(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT2_SHIFT) +# define TIMER_SYNC_SYNCWT2_NONE TIMER_SYNC_SYNCWT2(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT2_TA TIMER_SYNC_SYNCWT2(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT2_TB TIMER_SYNC_SYNCWT2(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT2_TATB TIMER_SYNC_SYNCWT2(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCWT3_SHIFT (18) /* Synchronize WTM 32/64-Bit wide timer 3 */ +# define TIMER_SYNC_SYNCWT3_MASK (3 << ) +# define TIMER_SYNC_SYNCWT3(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT3_SHIFT) +# define TIMER_SYNC_SYNCWT3_NONE TIMER_SYNC_SYNCWT3(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT3_TA TIMER_SYNC_SYNCWT3(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT3_TB TIMER_SYNC_SYNCWT3(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT3_TATB TIMER_SYNC_SYNCWT3(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCWT4_SHIFT (20) /* Synchronize WTM 32/64-Bit wide timer 4 */ +# define TIMER_SYNC_SYNCWT4_MASK (3 << ) +# define TIMER_SYNC_SYNCWT4(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT4_SHIFT) +# define TIMER_SYNC_SYNCWT4_NONE TIMER_SYNC_SYNCWT4(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT4_TA TIMER_SYNC_SYNCWT4(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT4_TB TIMER_SYNC_SYNCWT4(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT4_TATB TIMER_SYNC_SYNCWT4(TIMER_SYNC_TATB) +# define TIMER_SYNC_SYNCWT5_SHIFT (22) /* Synchronize WTM 32/64-Bit wide timer 5 */ +# define TIMER_SYNC_SYNCWT5_MASK (3 << ) +# define TIMER_SYNC_SYNCWT5(n) ((uint32_t)(n) << TIMER_SYNC_SYNCWT5_SHIFT) +# define TIMER_SYNC_SYNCWT5_NONE TIMER_SYNC_SYNCWT5(TIMER_SYNC_NONE) +# define TIMER_SYNC_SYNCWT5_TA TIMER_SYNC_SYNCWT5(TIMER_SYNC_TA) +# define TIMER_SYNC_SYNCWT5_TB TIMER_SYNC_SYNCWT5(TIMER_SYNC_TB) +# define TIMER_SYNC_SYNCWT5_TATB TIMER_SYNC_SYNCWT5(TIMER_SYNC_TATB) +#endif + +/* Common bit definitions used with: + * + * - GPTM Interrupt Mask (IMR) + * - GPTM Raw Interrupt Status (RIS) + * - GPTM Masked Interrupt Status (MIS) + * - GPTM Interrupt Clear (ICR) + */ + +#define TIMER_INT_TATO (1 << 0) /* Bit 0: Timer A Time-Out Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_INT_CAM (1 << 1) /* Bit 1: GPTM Timer A Capture Mode Match Interrupt */ +# define TIMER_INT_CAE (1 << 2) /* Bit 2: GPTM Timer A Capture Mode Event Interrupt */ +# define TIMER_INT_RTC (1 << 3) /* Bit 3: GPTM RTC Interrupt */ +# define TIMER_INT_TAM (1 << 4) /* Bit 4: GPTM Timer A Match Interrupt */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_INT_DMAA (1 << 5) /* Bit 5: GPTM Timer A DMA Done Interrupt */ +#endif + +#define TIMER_INT_TBTO (1 << 8) /* Bit 8: GPTM Timer B Time-Out Interrupt */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_INT_CBM (1 << 9) /* Bit 9: GPTM Timer B Capture Mode Match Interrupt */ +# define TIMER_INT_CBE (1 << 10) /* Bit 10: GPTM Timer B Capture Mode Event Interrupt */ +# define TIMER_INT_TBM (1 << 11) /* Bit 11: GPTM Timer B Match Interrupt */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_INT_DMAB (1 << 13) /* Bit 13: GPTM Timer B DMA Done Interrupt */ +#elif defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_INT_WUE (1 << 16) /* Bit 16: 32/64-Bit Wide GPTM Write Update Error Interrupt */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMERA_INTS 0x0000003f +# define TIMERB_INTS 0x00002f00 +# define TIMER_ALLINTS 0x00002f3f +#elif defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMERA_INTS 0x0000001f +# define TIMERB_INTS 0x00000f00 +# define TIMER_ALLINTS 0x00010f1f +#else +# define TIMERA_INTS 0x00000001 +# define TIMERB_INTS 0x00000100 +# define TIMER_ALLINTS 0x00000101 +#endif + +/* GPTM Timer A Interval Load (TAILR) (32-bit value) */ +/* GPTM Timer B Interval Load (TBILR) (32-bit value) */ +/* GPTM Timer A Match (TAMATCHR) (32-bit value) */ +/* GPTM Timer B Match (TBMATCHR) (32-bit value) */ + +/* GPTM Timer A/B Prescale (TnPR) */ + +#define TIMER_TnPR_TnPSR_SHIFT (0) /* Bits 0-8: GPTM Timer A/B Prescale */ +#define TIMER_TnPR_TnPSR_MASK (0xff << TIMER_TnPR_TnPSR_SHIFT) +# define TIMER_TnPR_TnPSR(n) ((uint32_t)(n) << TIMER_TnPR_TnPSR_SHIFT) + +/* GPTM Timer A/B Prescale Match (TnPMR) */ + +#define TIMER_TnPMR_TnPSMR_SHIFT (0) /* Bits 0-8: GPTM Timer A/B Prescale Match */ +#define TIMER_TnPMR_TnPSMR_MASK (0xff << TIMER_TnPMR_TnPSMR_SHIFT) +# define TIMER_TnPMR_TnPSMR(n) ((uint32_t)(n) << TIMER_TnPMR_TnPSMR_SHIFT) + +/* GPTM Timer A (TAR) (16/32-bit value) */ +/* GPTM Timer B (TBR) (16/32-bit value) */ +/* GPTM Timer A Value (TAV) (16/32-bit value) */ +/* GPTM Timer B Value (TBV) (16/32-bit value) */ + +/* GPTM RTC Predivide (RTCPD) */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_RTCPD_SHIFT (0) /* Bits 0-15: RTC Predivide Counter Value */ +# define TIMER_RTCPD_MASK (0xffff << TIMER_RTCPD_SHIFT) +# define TIMER_RTCPD(n) ((uint32_t)(n) << TIMER_RTCPD_SHIFT) +#endif + +/* GPTM Timer A/B Prescale Snapshot (TnPS) */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_TnPS_PSS_SHIFT (0) /* Bits 0-15: GPTM Timer A/B Prescaler Snapshot */ +# define TIMER_TnPS_PSS_MASK (0xffff << TIMER_TnPS_PSS_SHIFT) +# define TIMER_TnPS_PSS(n) ((uint32_t)(n) << TIMER_TnPS_PSS_SHIFT) +#endif + +/* GPTM Timer A/B Prescale Value (TnPV) */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_TnPV_PSS_SHIFT (0) /* Bits 0-15: GPTM Timer A/B Prescaler Value */ +# define TIMER_TnPS_PSS_MASK (0xffff << TIMER_TnPS_PSS_SHIFT) +# define TIMER_TnPS_PSS(n) ((uint32_t)(n) << TIMER_TnPS_PSS_SHIFT) +#endif + +/* GPTM DMA Event (DMAEV) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_DMAEV_TATODMAEN (1 << 0) /* Bit 0: GPTM A Time-Out Event DMA Trigger Enable */ +# define TIMER_DMAEV_CAMDMAEN (1 << 1) /* Bit 1: GPTM A Capture Match Event DMA Trigger Enable */ +# define TIMER_DMAEV_CAEDMAEN (1 << 2) /* Bit 2: GPTM A Capture Event DMA Trigger Enable */ +# define TIMER_DMAEV_RTCDMAEN (1 << 3) /* Bit 3: GPTM A RTC Match Event DMA Trigger Enable */ +# define TIMER_DMAEV_TAMDMAEN (1 << 4) /* Bit 4: GPTM A Mode Match Event DMA Trigger Enable */ +# define TIMER_DMAEV_TBTODMAEN (1 << 8) /* Bit 8: GPTM B Time-Out Event DMA Trigger Enable */ +# define TIMER_DMAEV_CBMDMAEN (1 << 9) /* Bit 9: GPTM B Capture Match Event DMA Trigger Enable */ +# define TIMER_DMAEV_CBEDMAEN (1 << 10) /* Bit 10: GPTM B Capture Event DMA Trigger Enable */ +# define TIMER_DMAEV_TBMDMAEN (1 << 11) /* Bit 11: GPTM B Mode Match Event DMA Trigger Enable */ +#endif + +/* GPTM ADC Event (ADCEV) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_ADCEV_TATOADCEN (1 << 0) /* Bit 0: GPTM A Time-Out Event ADC Trigger Enable */ +# define TIMER_ADCEV_CAMADCEN (1 << 1) /* Bit 1: GPTM A Capture Match Event ADC Trigger Enable */ +# define TIMER_ADCEV_CAEADCEN (1 << 2) /* Bit 2: GPTM A Capture Event ADC Trigger Enable */ +# define TIMER_ADCEV_RTCADCEN (1 << 3) /* Bit 3: GPTM RTC Match Event ADC Trigger Enable */ +# define TIMER_ADCEV_TAMADCEN (1 << 4) /* Bit 4: GPTM A Mode Match Event ADC Trigger Enable */ +# define TIMER_ADCEV_TBTOADCEN (1 << 8) /* Bit 8: GPTM B Time-Out Event ADC Trigger Enable */ +# define TIMER_ADCEV_CBMADCEN (1 << 9) /* Bit 9: GPTM B Capture Match Event ADC Trigger Enable */ +# define TIMER_ADCEV_CBEADCEN (1 << 10) /* Bit 10: GPTM B Capture Event ADC Trigger Enable */ +# define TIMER_ADCEV_TBMADCEN (1 << 11) /* Bit 11: GPTM B Mode Match Event ADC Trigger Enable */ +#endif + +/* GPTM Peripheral Properties (PP) */ + +#if defined(CONFIG_ARCH_CHIP_LM4F) || defined(CONFIG_ARCH_CHIP_TM4C) +# define TIMER_PP_SIZE_SHIFT (0) /* Bits 0-3: Count Size */ +# define TIMER_PP_SIZE_MASK (15 << TIMER_PP_SIZE_SHIFT) +# define TIMER_PP_SIZE_16 (0 << TIMER_PP_SIZE_SHIFT) /* Timer A/B 16 bits with 8-bit prescale */ +# define TIMER_PP_SIZE_32 (1 << TIMER_PP_SIZE_SHIFT) /* Timer A/B 32 bits with 16-bit prescale */ +#endif + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_PP_CHAIN (1 << 4) /* Bit 4: Chain with Other Timers */ +# define TIMER_PP_SYNCCNT (1 << 5) /* Bit 5: Synchronize Start */ +# define TIMER_PP_ALTCLK (1 << 6) /* Bit 6: Alternate Clock Source */ +#endif + +/* GPTM Clock Configuration */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIMER_CC_ALTCLK (1 << 0) /* Bit 0: Alternate Clock Source */ +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_TIMER_H */ diff --git a/arch/arm/src/tiva/chip/tiva_uart.h b/arch/arm/src/tiva/chip/tiva_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..a098072b2b6d1c274260d1100414eeb33152da88 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_uart.h @@ -0,0 +1,736 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_uart.h + * + * Copyright (C) 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TIVA_UART_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TIVA_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* UART register offsets ************************************************************/ + +#define TIVA_UART_DR_OFFSET 0x0000 /* UART Data */ +#define TIVA_UART_RSR_OFFSET 0x0004 /* UART Receive Status */ +#define TIVA_UART_ECR_OFFSET 0x0004 /* UART Error Clear */ +#define TIVA_UART_FR_OFFSET 0x0018 /* UART Flag */ +#define TIVA_UART_ILPR_OFFSET 0x0020 /* UART IrDA Low-Power Register */ +#define TIVA_UART_IBRD_OFFSET 0x0024 /* UART Integer Baud-Rate Divisor*/ +#define TIVA_UART_FBRD_OFFSET 0x0028 /* UART Fractional Baud-Rate Divisor */ +#define TIVA_UART_LCRH_OFFSET 0x002c /* UART Line Control */ +#define TIVA_UART_CTL_OFFSET 0x0030 /* UART Control */ +#define TIVA_UART_IFLS_OFFSET 0x0034 /* UART Interrupt FIFO Level Select */ +#define TIVA_UART_IM_OFFSET 0x0038 /* UART Interrupt Mask */ +#define TIVA_UART_RIS_OFFSET 0x003c /* UART Raw Interrupt Status */ +#define TIVA_UART_MIS_OFFSET 0x0040 /* UART Masked Interrupt Status */ +#define TIVA_UART_ICR_OFFSET 0x0044 /* UART Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART_DMACTL_OFFSET 0x0048 /* UART DMA Control */ +# define TIVA_UART_9BITADDR_OFFSET 0x00a4 /* UART 9-Bit Self Address */ +# define TIVA_UART_9BITAMASK_OFFSET 0x00a8 /* UART 9-Bit Self Address Mask */ +# define TIVA_UART_PP_OFFSET 0x0fc0 /* UART Peripheral Properties */ +# define TIVA_UART_CC_OFFSET 0x0fc8 /* UART Clock Configuration */ +#endif + +#define TIVA_UART_PERIPHID4_OFFSET 0x0fd0 /* UART Peripheral Identification 4 */ +#define TIVA_UART_PERIPHID5_OFFSET 0x0fd4 /* UART Peripheral Identification 5 */ +#define TIVA_UART_PERIPHID6_OFFSET 0x0fd8 /* UART Peripheral Identification 6 */ +#define TIVA_UART_PERIPHID7_OFFSET 0x0fdc /* UART Peripheral Identification 7 */ +#define TIVA_UART_PERIPHID0_OFFSET 0x0fe0 /* UART Peripheral Identification 0 */ +#define TIVA_UART_PERIPHID1_OFFSET 0x0fe4 /* UART Peripheral Identification 1 */ +#define TIVA_UART_PERIPHID2_OFFSET 0x0fe8 /* UART Peripheral Identification 2 */ +#define TIVA_UART_PERIPHID3_OFFSET 0x0fec /* UART Peripheral Identification 3 */ +#define TIVA_UART_PCELLID0_OFFSET 0x0ff0 /* UART PrimeCell Identification 0 */ +#define TIVA_UART_PCELLID1_OFFSET 0x0ff4 /* UART PrimeCell Identification 1 */ +#define TIVA_UART_PCELLID2_OFFSET 0x0ff8 /* UART PrimeCell Identification 2 */ +#define TIVA_UART_PCELLID3_OFFSET 0x0ffc /* UART PrimeCell Identification 3 */ + +/* UART register addresses **********************************************************/ + +#define TIVA_UART_BASE(n) (TIVA_UART0_BASE + (n)*0x01000) + +#define TIVA_UART_DR(n) (TIVA_UART_BASE(n) + TIVA_UART_DR_OFFSET) +#define TIVA_UART_RSR(n) (TIVA_UART_BASE(n) + TIVA_UART_RSR_OFFSET) +#define TIVA_UART_ECR(n) (TIVA_UART_BASE(n) + TIVA_UART_ECR_OFFSET) +#define TIVA_UART_FR(n) (TIVA_UART_BASE(n) + TIVA_UART_FR_OFFSET) +#define TIVA_UART_ILPR(n) (TIVA_UART_BASE(n) + TIVA_UART_ILPR_OFFSET) +#define TIVA_UART_IBRD(n) (TIVA_UART_BASE(n) + TIVA_UART_IBRD_OFFSET) +#define TIVA_UART_FBRD(n) (TIVA_UART_BASE(n) + TIVA_UART_FBRD_OFFSET) +#define TIVA_UART_LCRH(n) (TIVA_UART_BASE(n) + TIVA_UART_LCRH_OFFSET) +#define TIVA_UART_CTL(n) (TIVA_UART_BASE(n) + TIVA_UART_CTL_OFFSET) +#define TIVA_UART_IFLS(n) (TIVA_UART_BASE(n) + TIVA_UART_IFLS_OFFSET) +#define TIVA_UART_IM(n) (TIVA_UART_BASE(n) + TIVA_UART_IM_OFFSET) +#define TIVA_UART_RIS(n) (TIVA_UART_BASE(n) + TIVA_UART_RIS_OFFSET) +#define TIVA_UART_MIS(n) (TIVA_UART_BASE(n) + TIVA_UART_MIS_OFFSET) +#define TIVA_UART_ICR(n) (TIVA_UART_BASE(n) + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART_DMACTL(n) (TIVA_UART_BASE(n) + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART_9BITADDR(n) (TIVA_UART_BASE(n) + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART_9BITAMASK(n) (TIVA_UART_BASE(n) + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART_PP(n) (TIVA_UART_BASE(n) + TIVA_UART_PP_OFFSET) +# define TIVA_UART_CC(n) (TIVA_UART_BASE(n) + TIVA_UART_CC_OFFSET) +#endif + +#define TIVA_UART_PERIPHID4(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID4_OFFSET) +#define TIVA_UART_PERIPHID5(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID5_OFFSET) +#define TIVA_UART_PERIPHID6(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID6_OFFSET) +#define TIVA_UART_PERIPHID7(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID7_OFFSET) +#define TIVA_UART_PERIPHID0(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID0_OFFSET) +#define TIVA_UART_PERIPHID1(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID1_OFFSET) +#define TIVA_UART_PERIPHID2(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID2_OFFSET) +#define TIVA_UART_PERIPHID3(n) (TIVA_UART_BASE(n) + TIVA_UART_PERIPHID3_OFFSET) +#define TIVA_UART_PCELLID0(n) (TIVA_UART_BASE(n) + TIVA_UART_PCELLID0_OFFSET) +#define TIVA_UART_PCELLID1(n) (TIVA_UART_BASE(n) + TIVA_UART_PCELLID1_OFFSET) +#define TIVA_UART_PCELLID2(n) (TIVA_UART_BASE(n) + TIVA_UART_PCELLID2_OFFSET) +#define TIVA_UART_PCELLID3(n) (TIVA_UART_BASE(n) + TIVA_UART_PCELLID3_OFFSET) + +#if TIVA_NUARTS > 0 +# define TIVA_UART0_DR (TIVA_UART0_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART0_RSR (TIVA_UART0_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART0_ECR (TIVA_UART0_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART0_FR (TIVA_UART0_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART0_ILPR (TIVA_UART0_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART0_IBRD (TIVA_UART0_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART0_FBRD (TIVA_UART0_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART0_LCRH (TIVA_UART0_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART0_CTL (TIVA_UART0_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART0_IFLS (TIVA_UART0_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART0_IM (TIVA_UART0_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART0_RIS (TIVA_UART0_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART0_MIS (TIVA_UART0_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART0_ICR (TIVA_UART0_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART0_DMACTL (TIVA_UART0_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART0_9BITADDR (TIVA_UART0_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART0_9BITAMASK (TIVA_UART0_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART0_PP (TIVA_UART0_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART0_CC (TIVA_UART0_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART0_PERIPHID4 (TIVA_UART0_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART0_PERIPHID5 (TIVA_UART0_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART0_PERIPHID6 (TIVA_UART0_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART0_PERIPHID7 (TIVA_UART0_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART0_PERIPHID0 (TIVA_UART0_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART0_PERIPHID1 (TIVA_UART0_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART0_PERIPHID2 (TIVA_UART0_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART0_PERIPHID3 (TIVA_UART0_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART0_PCELLID0 (TIVA_UART0_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART0_PCELLID1 (TIVA_UART0_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART0_PCELLID2 (TIVA_UART0_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART0_PCELLID3 (TIVA_UART0_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 1 +# define TIVA_UART1_DR (TIVA_UART1_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART1_RSR (TIVA_UART1_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART1_ECR (TIVA_UART1_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART1_FR (TIVA_UART1_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART1_ILPR (TIVA_UART1_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART1_IBRD (TIVA_UART1_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART1_FBRD (TIVA_UART1_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART1_LCRH (TIVA_UART1_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART1_CTL (TIVA_UART1_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART1_IFLS (TIVA_UART1_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART1_IM (TIVA_UART1_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART1_RIS (TIVA_UART1_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART1_MIS (TIVA_UART1_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART1_ICR (TIVA_UART1_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART1_DMACTL (TIVA_UART1_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART1_9BITADDR (TIVA_UART1_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART1_9BITAMASK (TIVA_UART1_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART1_PP (TIVA_UART1_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART1_CC (TIVA_UART1_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART1_PERIPHID4 (TIVA_UART1_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART1_PERIPHID5 (TIVA_UART1_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART1_PERIPHID6 (TIVA_UART1_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART1_PERIPHID7 (TIVA_UART1_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART1_PERIPHID0 (TIVA_UART1_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART1_PERIPHID1 (TIVA_UART1_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART1_PERIPHID2 (TIVA_UART1_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART1_PERIPHID3 (TIVA_UART1_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART1_PCELLID0 (TIVA_UART1_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART1_PCELLID1 (TIVA_UART1_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART1_PCELLID2 (TIVA_UART1_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART1_PCELLID3 (TIVA_UART1_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 2 +# define TIVA_UART2_DR (TIVA_UART2_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART2_RSR (TIVA_UART2_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART2_ECR (TIVA_UART2_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART2_FR (TIVA_UART2_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART2_ILPR (TIVA_UART2_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART2_IBRD (TIVA_UART2_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART2_FBRD (TIVA_UART2_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART2_LCRH (TIVA_UART2_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART2_CTL (TIVA_UART2_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART2_IFLS (TIVA_UART2_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART2_IM (TIVA_UART2_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART2_RIS (TIVA_UART2_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART2_MIS (TIVA_UART2_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART2_ICR (TIVA_UART2_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART2_DMACTL (TIVA_UART2_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART2_9BITADDR (TIVA_UART2_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART2_9BITAMASK (TIVA_UART2_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART2_PP (TIVA_UART2_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART2_CC (TIVA_UART2_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART2_PERIPHID4 (TIVA_UART2_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART2_PERIPHID5 (TIVA_UART2_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART2_PERIPHID6 (TIVA_UART2_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART2_PERIPHID7 (TIVA_UART2_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART2_PERIPHID0 (TIVA_UART2_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART2_PERIPHID1 (TIVA_UART2_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART2_PERIPHID2 (TIVA_UART2_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART2_PERIPHID3 (TIVA_UART2_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART2_PCELLID0 (TIVA_UART2_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART2_PCELLID1 (TIVA_UART2_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART2_PCELLID2 (TIVA_UART2_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART2_PCELLID3 (TIVA_UART2_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 3 +# define TIVA_UART3_DR (TIVA_UART3_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART3_RSR (TIVA_UART3_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART3_ECR (TIVA_UART3_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART3_FR (TIVA_UART3_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART3_ILPR (TIVA_UART3_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART3_IBRD (TIVA_UART3_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART3_FBRD (TIVA_UART3_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART3_LCRH (TIVA_UART3_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART3_CTL (TIVA_UART3_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART3_IFLS (TIVA_UART3_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART3_IM (TIVA_UART3_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART3_RIS (TIVA_UART3_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART3_MIS (TIVA_UART3_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART3_ICR (TIVA_UART3_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART3_DMACTL (TIVA_UART3_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART3_9BITADDR (TIVA_UART3_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART3_9BITAMASK (TIVA_UART3_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART3_PP (TIVA_UART3_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART3_CC (TIVA_UART3_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART3_PERIPHID4 (TIVA_UART3_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART3_PERIPHID5 (TIVA_UART3_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART3_PERIPHID6 (TIVA_UART3_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART3_PERIPHID7 (TIVA_UART3_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART3_PERIPHID0 (TIVA_UART3_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART3_PERIPHID1 (TIVA_UART3_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART3_PERIPHID2 (TIVA_UART3_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART3_PERIPHID3 (TIVA_UART3_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART3_PCELLID0 (TIVA_UART3_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART3_PCELLID1 (TIVA_UART3_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART3_PCELLID2 (TIVA_UART3_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART3_PCELLID3 (TIVA_UART3_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 4 +# define TIVA_UART4_DR (TIVA_UART4_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART4_RSR (TIVA_UART4_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART4_ECR (TIVA_UART4_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART4_FR (TIVA_UART4_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART4_ILPR (TIVA_UART4_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART4_IBRD (TIVA_UART4_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART4_FBRD (TIVA_UART4_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART4_LCRH (TIVA_UART4_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART4_CTL (TIVA_UART4_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART4_IFLS (TIVA_UART4_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART4_IM (TIVA_UART4_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART4_RIS (TIVA_UART4_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART4_MIS (TIVA_UART4_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART4_ICR (TIVA_UART4_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART4_DMACTL (TIVA_UART4_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART4_9BITADDR (TIVA_UART4_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART4_9BITAMASK (TIVA_UART4_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART4_PP (TIVA_UART4_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART4_CC (TIVA_UART4_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART4_PERIPHID4 (TIVA_UART4_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART4_PERIPHID5 (TIVA_UART4_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART4_PERIPHID6 (TIVA_UART4_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART4_PERIPHID7 (TIVA_UART4_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART4_PERIPHID0 (TIVA_UART4_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART4_PERIPHID1 (TIVA_UART4_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART4_PERIPHID2 (TIVA_UART4_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART4_PERIPHID3 (TIVA_UART4_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART4_PCELLID0 (TIVA_UART4_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART4_PCELLID1 (TIVA_UART4_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART4_PCELLID2 (TIVA_UART4_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART4_PCELLID3 (TIVA_UART4_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 5 +# define TIVA_UART5_DR (TIVA_UART5_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART5_RSR (TIVA_UART5_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART5_ECR (TIVA_UART5_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART5_FR (TIVA_UART5_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART5_ILPR (TIVA_UART5_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART5_IBRD (TIVA_UART5_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART5_FBRD (TIVA_UART5_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART5_LCRH (TIVA_UART5_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART5_CTL (TIVA_UART5_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART5_IFLS (TIVA_UART5_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART5_IM (TIVA_UART5_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART5_RIS (TIVA_UART5_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART5_MIS (TIVA_UART5_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART5_ICR (TIVA_UART5_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART5_DMACTL (TIVA_UART5_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART5_9BITADDR (TIVA_UART5_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART5_9BITAMASK (TIVA_UART5_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART5_PP (TIVA_UART5_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART5_CC (TIVA_UART5_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART5_PERIPHID4 (TIVA_UART5_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART5_PERIPHID5 (TIVA_UART5_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART5_PERIPHID6 (TIVA_UART5_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART5_PERIPHID7 (TIVA_UART5_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART5_PERIPHID0 (TIVA_UART5_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART5_PERIPHID1 (TIVA_UART5_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART5_PERIPHID2 (TIVA_UART5_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART5_PERIPHID3 (TIVA_UART5_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART5_PCELLID0 (TIVA_UART5_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART5_PCELLID1 (TIVA_UART5_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART5_PCELLID2 (TIVA_UART5_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART5_PCELLID3 (TIVA_UART5_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 6 +# define TIVA_UART6_DR (TIVA_UART6_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART6_RSR (TIVA_UART6_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART6_ECR (TIVA_UART6_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART6_FR (TIVA_UART6_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART6_ILPR (TIVA_UART6_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART6_IBRD (TIVA_UART6_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART6_FBRD (TIVA_UART6_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART6_LCRH (TIVA_UART6_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART6_CTL (TIVA_UART6_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART6_IFLS (TIVA_UART6_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART6_IM (TIVA_UART6_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART6_RIS (TIVA_UART6_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART6_MIS (TIVA_UART6_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART6_ICR (TIVA_UART6_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART6_DMACTL (TIVA_UART6_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART6_9BITADDR (TIVA_UART6_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART6_9BITAMASK (TIVA_UART6_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART6_PP (TIVA_UART6_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART6_CC (TIVA_UART6_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART6_PERIPHID4 (TIVA_UART6_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART6_PERIPHID5 (TIVA_UART6_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART6_PERIPHID6 (TIVA_UART6_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART6_PERIPHID7 (TIVA_UART6_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART6_PERIPHID0 (TIVA_UART6_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART6_PERIPHID1 (TIVA_UART6_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART6_PERIPHID2 (TIVA_UART6_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART6_PERIPHID3 (TIVA_UART6_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART6_PCELLID0 (TIVA_UART6_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART6_PCELLID1 (TIVA_UART6_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART6_PCELLID2 (TIVA_UART6_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART6_PCELLID3 (TIVA_UART6_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +#if TIVA_NUARTS > 7 +# define TIVA_UART7_DR (TIVA_UART7_BASE + TIVA_UART_DR_OFFSET) +# define TIVA_UART7_RSR (TIVA_UART7_BASE + TIVA_UART_RSR_OFFSET) +# define TIVA_UART7_ECR (TIVA_UART7_BASE + TIVA_UART_ECR_OFFSET) +# define TIVA_UART7_FR (TIVA_UART7_BASE + TIVA_UART_FR_OFFSET) +# define TIVA_UART7_ILPR (TIVA_UART7_BASE + TIVA_UART_ILPR_OFFSET) +# define TIVA_UART7_IBRD (TIVA_UART7_BASE + TIVA_UART_IBRD_OFFSET) +# define TIVA_UART7_FBRD (TIVA_UART7_BASE + TIVA_UART_FBRD_OFFSET) +# define TIVA_UART7_LCRH (TIVA_UART7_BASE + TIVA_UART_LCRH_OFFSET) +# define TIVA_UART7_CTL (TIVA_UART7_BASE + TIVA_UART_CTL_OFFSET) +# define TIVA_UART7_IFLS (TIVA_UART7_BASE + TIVA_UART_IFLS_OFFSET) +# define TIVA_UART7_IM (TIVA_UART7_BASE + TIVA_UART_IM_OFFSET) +# define TIVA_UART7_RIS (TIVA_UART7_BASE + TIVA_UART_RIS_OFFSET) +# define TIVA_UART7_MIS (TIVA_UART7_BASE + TIVA_UART_MIS_OFFSET) +# define TIVA_UART7_ICR (TIVA_UART7_BASE + TIVA_UART_ICR_OFFSET) + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_UART7_DMACTL (TIVA_UART7_BASE + TIVA_UART_DMACTL_OFFSET) +# define TIVA_UART7_9BITADDR (TIVA_UART7_BASE + TIVA_UART_9BITADDR_OFFSET) +# define TIVA_UART7_9BITAMASK (TIVA_UART7_BASE + TIVA_UART_9BITAMASK_OFFSET) +# define TIVA_UART7_PP (TIVA_UART7_BASE + TIVA_UART_PP_OFFSET) +# define TIVA_UART7_CC (TIVA_UART7_BASE + TIVA_UART_CC_OFFSET) +#endif + +# define TIVA_UART7_PERIPHID4 (TIVA_UART7_BASE + TIVA_UART_PERIPHID4_OFFSET) +# define TIVA_UART7_PERIPHID5 (TIVA_UART7_BASE + TIVA_UART_PERIPHID5_OFFSET) +# define TIVA_UART7_PERIPHID6 (TIVA_UART7_BASE + TIVA_UART_PERIPHID6_OFFSET) +# define TIVA_UART7_PERIPHID7 (TIVA_UART7_BASE + TIVA_UART_PERIPHID7_OFFSET) +# define TIVA_UART7_PERIPHID0 (TIVA_UART7_BASE + TIVA_UART_PERIPHID0_OFFSET) +# define TIVA_UART7_PERIPHID1 (TIVA_UART7_BASE + TIVA_UART_PERIPHID1_OFFSET) +# define TIVA_UART7_PERIPHID2 (TIVA_UART7_BASE + TIVA_UART_PERIPHID2_OFFSET) +# define TIVA_UART7_PERIPHID3 (TIVA_UART7_BASE + TIVA_UART_PERIPHID3_OFFSET) +# define TIVA_UART7_PCELLID0 (TIVA_UART7_BASE + TIVA_UART_PCELLID0_OFFSET) +# define TIVA_UART7_PCELLID1 (TIVA_UART7_BASE + TIVA_UART_PCELLID1_OFFSET) +# define TIVA_UART7_PCELLID2 (TIVA_UART7_BASE + TIVA_UART_PCELLID2_OFFSET) +# define TIVA_UART7_PCELLID3 (TIVA_UART7_BASE + TIVA_UART_PCELLID3_OFFSET) +#endif + +/* UART register bit settings *******************************************************/ + +/* UART Data (DR) */ + +#define UART_DR_DATA_SHIFT 0 /* Bits 7-0: Data Transmitted or Received */ +#define UART_DR_DATA_MASK (0xff << UART_DR_DATA_SHIFT) +#define UART_DR_FE (1 << 8) /* Bit 8: UART Framing Error */ +#define UART_DR_PE (1 << 9) /* Bit 9: UART Parity Error */ +#define UART_DR_BE (1 << 10) /* Bit 10: UART Break Error */ +#define UART_DR_OE (1 << 11) /* Bit 11: UART Overrun Error */ + +/* UART Receive Status (RSR) */ + +#define UART_RSR_FE (1 << 0) /* Bit 0: UART Framing Error */ +#define UART_RSR_PE (1 << 1) /* Bit 1: UART Parity Error */ +#define UART_RSR_BE (1 << 2) /* Bit 2: UART Break Error */ +#define UART_RSR_OE (1 << 3) /* Bit 3: UART Overrun Error */ + +/* UART Error Clear (ECR), offset 0x004 */ +/* Writing any value to this register clears pending error indications */ + +/* UART Flag (FR) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_FR_CTS (1 << 0) /* Bit 0: Data Set Ready */ +# define UART_FR_DSR (1 << 1) /* Bit 1: Data Set Ready */ +# define UART_FR_DCD (1 << 2) /* Bit 2: Data Carrier Detect */ +#endif + +#define UART_FR_BUSY (1 << 3) /* Bit 3: UART Busy */ +#define UART_FR_RXFE (1 << 4) /* Bit 4: UART Receive FIFO Empty */ +#define UART_FR_TXFF (1 << 5) /* Bit 5: UART Transmit FIFO Full */ +#define UART_FR_RXFF (1 << 6) /* Bit 6: UART Receive FIFO Full */ +#define UART_FR_TXFE (1 << 7) /* Bit 7: UART Transmit FIFO Empty */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_FR_RI (1 << 8) /* Bit 8: Ring Indicator */ +#endif + +/* UART IrDA Low-Power Register (ILPR) */ + +#define UART_ILPR_DVSR_MASK (0xff) /* Bits 7-0: IrDA Low-Power Divisor */ + +/* UART Integer Baud-Rate Divisor (IBRD) */ + +#define UART_IBRD_DIVINT_MASK (0xffff) /* Bits 15-0: Integer Baud-Rate Divisor */ + +/* UART Fractional Baud-Rate Divisor (UARTFBRD) */ + +#define UART_FBRD_DIVFRAC_MASK (0x3f) /* Bits 5-0: Fractional Baud-Rate Divisor */ + +/* Register 7: UART Line Control (LCRH) */ + +#define UART_LCRH_BRK (1 << 0) /* Bit 0: UART Send Break */ +#define UART_LCRH_PEN (1 << 1) /* Bit 1: UART Parity Enable */ +#define UART_LCRH_EPS (1 << 2) /* Bit 2: UART Even Parity Select */ +#define UART_LCRH_STP2 (1 << 3) /* Bit 3: UART Two Stop Bits Select */ +#define UART_LCRH_FEN (1 << 4) /* Bit 4: UART Enable FIFOs */ +#define UART_LCRH_WLEN_SHIFT 5 /* Bits 6-5: UART Word Length */ +#define UART_LCRH_WLEN_MASK (3 << UART_LCRH_WLEN_SHIFT) +# define UART_LCRH_WLEN_5BITS (0 << UART_LCRH_WLEN_SHIFT) /* 5-bits (reset) */ +# define UART_LCRH_WLEN_6BITS (1 << UART_LCRH_WLEN_SHIFT) /* 6-bits */ +# define UART_LCRH_WLEN_7BITS (2 << UART_LCRH_WLEN_SHIFT) /* 7-bits */ +# define UART_LCRH_WLEN_8BITS (3 << UART_LCRH_WLEN_SHIFT) /* 8-bits */ +#define UART_LCRH_SPS (1 << 7) /* Bit 7: UART Stick Parity Select */ + +/* UART Control (CTL) */ + +#define UART_CTL_UARTEN (1 << 0) /* Bit 0: UART Enable */ +#define UART_CTL_SIREN (1 << 1) /* Bit 1: UART SIR Enable */ +#define UART_CTL_SIRLP (1 << 2) /* Bit 2: UART SIR Low Power Mode */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_CTL_SMART (1 << 3) /* Bit 3: ISO 7816 Smart Card Support */ +# define UART_CTL_EOT (1 << 4) /* Bit 4: End of Transmission */ +# define UART_CTL_HSE (1 << 5) /* Bit 5: High-Speed Enable */ +#endif + +#define UART_CTL_LBE (1 << 7) /* Bit 7: UART Loop Back Enable */ +#define UART_CTL_TXE (1 << 8) /* Bit 8: UART Transmit Enable */ +#define UART_CTL_RXE (1 << 9) /* Bit 9: UART Receive Enable */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_CTL_DTR (1 << 10) /* Bit 10: Data Terminal Ready */ +# define UART_CTL_RTS (1 << 11) /* Bit 11: Request to Send */ +# define UART_CTL_RTSEN (1 << 14) /* Bit 14: Enable Request to Send */ +# define UART_CTL_CTSEN (1 << 15) /* Bit 15: Enable Clear To Send */ +#endif + +/* UART Interrupt FIFO Level Select (IFLS) */ + +#define UART_IFLS_TXIFLSEL_SHIFT 0 /* Bits 2-0: UART Transmit Interrupt FIFO Level Select */ +#define UART_IFLS_TXIFLSEL_MASK (7 << UART_IFLS_TXIFLSEL_SHIFT) +# define UART_IFLS_TXIFLSEL_18th (0 << UART_IFLS_TXIFLSEL_SHIFT) /* 1/8th full */ +# define UART_IFLS_TXIFLSEL_14th (1 << UART_IFLS_TXIFLSEL_SHIFT) /* 1/4th full */ +# define UART_IFLS_TXIFLSEL_half (2 << UART_IFLS_TXIFLSEL_SHIFT) /* half full */ +# define UART_IFLS_TXIFLSEL_34th (3 << UART_IFLS_TXIFLSEL_SHIFT) /* 3/4th full */ +# define UART_IFLS_TXIFLSEL_78th (4 << UART_IFLS_TXIFLSEL_SHIFT) /* 7/8th full */ +#define UART_IFLS_RXIFLSEL_SHIFT 3 /* Bits 5-3: UART Receive Interrupt FIFO Level Select */ +#define UART_IFLS_RXIFLSEL_MASK (7 << UART_IFLS_RXIFLSEL_SHIFT) +# define UART_IFLS_RXIFLSEL_18th (0 << UART_IFLS_RXIFLSEL_SHIFT) /* 1/8th full */ +# define UART_IFLS_RXIFLSEL_14th (1 << UART_IFLS_RXIFLSEL_SHIFT) /* 1/4th full */ +# define UART_IFLS_RXIFLSEL_half (2 << UART_IFLS_RXIFLSEL_SHIFT) /* half full */ +# define UART_IFLS_RXIFLSEL_34th (3 << UART_IFLS_RXIFLSEL_SHIFT) /* 3/4th full */ +# define UART_IFLS_RXIFLSEL_78th (4 << UART_IFLS_RXIFLSEL_SHIFT) /* 7/8th full */ + +/* UART Interrupt Mask (IM) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_IM_RIIM (1 << 0) /* Bit 0: UART Ring Indicator Modem Interrupt Mask */ +# define UART_IM_CTSIM (1 << 1) /* Bit 1: UART Clear to Send Modem Interrupt Mask */ +# define UART_IM_DCDIM (1 << 2) /* Bit 2: UART Data Carrier Detect Modem Interrupt Mask */ +# define UART_IM_DSRIM (1 << 3) /* Bit 3: UART Data Set Ready Modem Interrupt Mask */ +#endif + +#define UART_IM_RXIM (1 << 4) /* Bit 4: UART Receive Interrupt Mask */ +#define UART_IM_TXIM (1 << 5) /* Bit 5: UART Transmit Interrupt Mask */ +#define UART_IM_RTIM (1 << 6) /* Bit 6: UART Receive Time-Out Interrupt Mask */ +#define UART_IM_FEIM (1 << 7) /* Bit 7: UART Framing Error Interrupt Mask */ +#define UART_IM_PEIM (1 << 8) /* Bit 8: UART Parity Error Interrupt Mask */ +#define UART_IM_BEIM (1 << 9) /* Bit 9: UART Break Error Interrupt Mask */ +#define UART_IM_OEIM (1 << 10) /* Bit 10: UART Overrun Error Interrupt Mask */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_IM_EOTIM (1 << 11) /* Bit 11: End of Transmission Interrupt Mask */ +# define UART_IM_9BITIM (1 << 12) /* Bit 12: 9-Bit Mode Interrupt Mask */ +# define UART_IM_DMARXIM (1 << 16) /* Bit 16: Receive DMA Interrupt Mask */ +# define UART_IM_DMATXIM (1 << 17) /* Bit 17: Transmit DMA Interrupt Mask */ +#endif + +/* UART Raw Interrupt Status (RIS) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_RIS_RIIS (1 << 0) /* Bit 0: UART Ring Indicator Modem Raw Interrupt Status */ +# define UART_RIS_CTSIS (1 << 1) /* Bit 1: UART Clear to Send Modem Raw Interrupt Status */ +# define UART_RIS_DCDIS (1 << 2) /* Bit 2: UART Data Carrier Detect Modem Raw Interrupt Status */ +# define UART_RIS_DSRIS (1 << 3) /* Bit 3: UART Data Set Ready Modem Raw Interrupt Status */ +#endif + +#define UART_RIS_RXRIS (1 << 4) /* Bit 4: UART Receive Raw Interrupt Status */ +#define UART_RIS_TXRIS (1 << 5) /* Bit 5: UART Transmit Raw Interrupt Status */ +#define UART_RIS_RTRIS (1 << 6) /* Bit 6: UART Receive Time-Out Raw Interrupt Status */ +#define UART_RIS_FERIS (1 << 7) /* Bit 7: UART Framing Error Raw Interrupt Status */ +#define UART_RIS_PERIS (1 << 8) /* Bit 8: UART Parity Error Raw Interrupt Status */ +#define UART_RIS_BERIS (1 << 9) /* Bit 9: UART Break Error Raw Interrupt Status */ +#define UART_RIS_OERIS (1 << 10) /* Bit 10: UART Overrun Error Raw Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_RIS_EOTIS (1 << 11) /* Bit 11: End of Transmission Raw Interrupt Status */ +# define UART_RIS_9BITIS (1 << 12) /* Bit 12: 9-Bit Mode Raw Interrupt Status */ +# define UART_RIS_DMARXIS (1 << 16) /* Bit 16: Receive DMA Raw Interrupt Status */ +# define UART_RIS_DMATXIS (1 << 17) /* Bit 17: Transmit DMA Raw Interrupt Status */ +#endif + +/* UART Masked Interrupt Status (MIS) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_MIS_RIIS (1 << 0) /* Bit 0: UART Ring Indicator Modem Masked Interrupt Status */ +# define UART_MIS_CTSIS (1 << 1) /* Bit 1: UART Clear to Send Modem Masked Interrupt Status */ +# define UART_MIS_DCDIS (1 << 2) /* Bit 2: UART Data Carrier Detect Modem Masked Interrupt Status */ +# define UART_MIS_DSRIS (1 << 3) /* Bit 3: UART Data Set Ready Modem Masked Interrupt Status */ +#endif + +#define UART_MIS_RXMIS (1 << 4) /* Bit 4: UART Receive Masked Interrupt Status */ +#define UART_MIS_TXMIS (1 << 5) /* Bit 5: UART Transmit Masked Interrupt Status */ +#define UART_MIS_RTMIS (1 << 6) /* Bit 6: UART Receive Time-Out Masked Interrupt Status */ +#define UART_MIS_FEMIS (1 << 7) /* Bit 7: UART Framing Error Masked Interrupt Status */ +#define UART_MIS_PEMIS (1 << 8) /* Bit 8: UART Parity Error Masked Interrupt Status */ +#define UART_MIS_BEMIS (1 << 9) /* Bit 9: UART Break Error Masked Interrupt Status */ +#define UART_MIS_OEMIS (1 << 10) /* Bit 10: UART Overrun Error Masked Interrupt Status */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_MIS_EOTIS (1 << 11) /* Bit 11: End of Transmission Masked Interrupt Status */ +# define UART_MIS_9BITIS (1 << 12) /* Bit 12: 9-Bit Mode Masked Interrupt Status */ +# define UART_MIS_DMARXIS (1 << 16) /* Bit 16: Receive DMA Masked Interrupt Status */ +# define UART_MIS_DMATXIS (1 << 17) /* Bit 17: Transmit DMA Masked Interrupt Status */ +#endif + +/* UART Interrupt Clear (ICR) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_ICR_RIIC (1 << 0) /* Bit 0: UART Ring Indicator Modem Interrupt Clear */ +# define UART_ICR_CTSIC (1 << 1) /* Bit 1: UART Clear to Send Modem Interrupt Clear */ +# define UART_ICR_DCDIC (1 << 2) /* Bit 2: UART Data Carrier Detect Modem Interrupt Clear */ +# define UART_ICR_DSRIC (1 << 3) /* Bit 3: UART Data Set Ready Modem Interrupt Clear */ +#endif + +#define UART_ICR_RXIC (1 << 4) /* Bit 4: Receive Interrupt Clear */ +#define UART_ICR_TXIC (1 << 5) /* Bit 5: Transmit Interrupt Clear */ +#define UART_ICR_RTIC (1 << 6) /* Bit 6: Receive Time-Out Interrupt Clear */ +#define UART_ICR_FEIC (1 << 7) /* Bit 7: Framing Error Interrupt Clear */ +#define UART_ICR_PEIC (1 << 8) /* Bit 8: Parity Error Interrupt Clear */ +#define UART_ICR_BEIC (1 << 9) /* Bit 9: Break Error Interrupt Clear */ +#define UART_ICR_OEIC (1 << 10) /* Bit 10: Overrun Error Interrupt Clear */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_ICR_EOTIC (1 << 11) /* Bit 11: End of Transmission Interrupt Clear */ +# define UART_ICR_9BITIC (1 << 12) /* Bit 12: 9-Bit Mode Interrupt Clear */ +# define UART_ICR_DMARXIC (1 << 16) /* Bit 16: Receive DMA Interrupt Clear */ +# define UART_ICR_DMATXIC (1 << 17) /* Bit 17: Transmit DMA Interrupt Clear */ +#endif + +/* UART DMA Control (DMACTL) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_DMACTL_RXDMAE (1 << 0) /* Bit 0: Receive DMA Enable */ +# define UART_DMACTL_TXDMAE (1 << 1) /* Bit 1: Transmit DMA Enable */ +# define UART_DMACTL_DMAERR (1 << 2) /* Bit 2: DMA on Error */ +#endif + +/* UART 9-Bit Self Address (9BITADDR) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_9BITADDR_ADDR_SHIFT (0) /* Bits 0-7: Self Address for 9-Bit Mode */ +# define UART_9BITADDR_ADDR_MASK (0xff << UART_9BITADDR_ADDR_SHIFT) +# define UART_9BITADDR_ADDR(n) ((uint32_t)(n) << UART_9BITADDR_ADDR_SHIFT) +# define UART_9BITADDR_9BITEN (1 << 15) /* Bit 15: Enable 9-Bit Mode */ +#endif + +/* UART 9-Bit Self Address Mask (9BITAMASK) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_9BITAMASK_MASK_SHIFT (0) /* Bits 0-7: Self Address Mask for 9-Bit Mode */ +# define UART_9BITAMASK_MASK_MASK (0xff << UART_9BITAMASK_MASK_SHIFT) +#endif + +/* UART Peripheral Properties (PP) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_PP_SC (1 << 0) /* Bit 0: Smart Card Support */ +# define UART_PP_NB (1 << 1) /* Bit 1: 9-Bit Support */ +# define UART_PP_MS (1 << 2) /* Bit 2: Modem Support */ +# define UART_PP_MSE (1 << 3) /* Bit 3: Modem Support Extended */ +#endif + +/* UART Clock Configuration (CC) */ + +#if defined(CONFIG_ARCH_CHIP_TM4C129) +# define UART_CC_CS_SHIFT (0) /* Bit 0-3: UART Baud Clock Source */ +# define UART_CC_CS_MASK (15 << UART_CC_CS_SHIFT) +# define UART_CC_CS_SYSCLK (0 << UART_CC_CS_SHIFT) /* System clock in RSCLKCFG */ +# define UART_CC_CS_ALTSRC (5 << UART_CC_CS_SHIFT) /* Alternate source in ALTCLKCFG */ +#endif + +/* UART Peripheral Identification 4 (PERIPHID4) */ + +#define UART_PERIPHID4_MASK (0xff) /* UART Peripheral ID Register[7:0] */ + +/* UART Peripheral Identification 5 (UARTPERIPHID5 */ + +#define UART_PERIPHID5_MASK (0xff) /* UART Peripheral ID Register[15:8] */ + +/* UART Peripheral Identification 6 (UARTPERIPHID6) */ + +#define UART_PERIPHID6_MASK (0xff) /* UART Peripheral ID Register[23:16] */ + +/* UART Peripheral Identification 7 (UARTPERIPHID7) */ + +#define UART_PERIPHID7_MASK (0xff) /* UART Peripheral ID Register[31:24] */ + +/* UART Peripheral Identification 0 (UARTPERIPHID0) */ + +#define UART_PERIPHID0_MASK (0xff) /* UART Peripheral ID Register[7:0] */ + +/* UART Peripheral Identification 1 (UARTPERIPHID1) */ + +#define UART_PERIPHID1_MASK (0xff) /* UART Peripheral ID Register[15:8] */ + +/* UART Peripheral Identification 2 (UARTPERIPHID2) */ + +#define UART_PERIPHID2_MASK (0xff) /* UART Peripheral ID Register[23:16] */ + +/* UART Peripheral Identification 3 (UARTPERIPHID3) */ + +#define UART_PERIPHID3_MASK (0xff) /* UART Peripheral ID Register[31:24] */ + +/* UART PrimeCell Identification 0 (CELLID0) */ + +#define UART_CELLID0_MASK (0xff) /* UART PrimeCell ID Register[7:0] */ + +/* UART PrimeCell Identification 1 (UARTPCELLID1) */ + +#define UART_CELLID1_MASK (0xff) /* UART PrimeCell ID Register[15:8] */ + +/* UART PrimeCell Identification 2 (UARTPCELLID2) */ + +#define UART_CELLID02MASK (0xff) /* UART PrimeCell ID Register[23:16] */ + +/* UART PrimeCell Identification 3 (UARTPCELLID3) */ + +#define UART_CELLID3_MASK (0xff) /* UART PrimeCell ID Register[31:24] */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TIVA_UART_H */ diff --git a/arch/arm/src/tiva/chip/tiva_vectors.h b/arch/arm/src/tiva/chip/tiva_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..8f95cd83fc482227a6a0ea49eb2e08c5e5f46f46 --- /dev/null +++ b/arch/arm/src/tiva/chip/tiva_vectors.h @@ -0,0 +1,68 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tiva_vectors.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* Include the vector file for the specific Tiva/Stellaris chip */ + +#if defined(CONFIG_ARCH_CHIP_LM3S) +# include "chip/lm3s_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_LM4F) +# include "chip/lm4f_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_TM4C) +# include "chip/tm4c_vectors.h" +#elif defined(CONFIG_ARCH_CHIP_CC3200) +# include "chip/cc3200_vectors.h" +#else +# error "Unsupported Tiva/Stellaris vector file" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ diff --git a/arch/arm/src/tiva/chip/tm4c123_syscontrol.h b/arch/arm/src/tiva/chip/tm4c123_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..6991e0b4110b79181bd1e92202e8634d275e6b91 --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c123_syscontrol.h @@ -0,0 +1,1859 @@ +/******************************************************************************************** + * arch/arm/src/tiva/chip/tm4c123_syscontrol.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C123_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C123_SYSCONTROL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* System Control Register Offsets **********************************************************/ + +#define TIVA_SYSCON_DID0_OFFSET 0x000 /* Device Identification 0 */ +#define TIVA_SYSCON_DID1_OFFSET 0x004 /* Device Identification 1 */ +#define TIVA_SYSCON_PBORCTL_OFFSET 0x030 /* Brown-Out Reset Control */ +#define TIVA_SYSCON_RIS_OFFSET 0x050 /* Raw Interrupt Status */ +#define TIVA_SYSCON_IMC_OFFSET 0x054 /* Interrupt Mask Control */ +#define TIVA_SYSCON_MISC_OFFSET 0x058 /* Masked Interrupt Status and Clear */ +#define TIVA_SYSCON_RESC_OFFSET 0x05c /* Reset Cause */ +#define TIVA_SYSCON_RCC_OFFSET 0x060 /* Run-Mode Clock Configuration */ +#define TIVA_SYSCON_GPIOHBCTL_OFFSET 0x06c /* GPIO High-Performance Bus Control */ +#define TIVA_SYSCON_RCC2_OFFSET 0x070 /* Run-Mode Clock Configuration 2 */ +#define TIVA_SYSCON_MOSCCTL_OFFSET 0x07c /* Main Oscillator Control */ +#define TIVA_SYSCON_DSLPCLKCFG_OFFSET 0x144 /* Deep Sleep Clock Configuration */ +#define TIVA_SYSCON_SYSPROP_OFFSET 0x14c /* System Properties */ +#define TIVA_SYSCON_PIOSCCAL_OFFSET 0x150 /* Precision Internal Oscillator Calibration */ +#define TIVA_SYSCON_PIOSCSTAT_OFFSET 0x154 /* Precision Internal Oscillator Statistics */ +#define TIVA_SYSCON_PLLFREQ0_OFFSET 0x160 /* PLL 0 Frequency */ +#define TIVA_SYSCON_PLLFREQ1_OFFSET 0x164 /* PLL 1 Frequency */ +#define TIVA_SYSCON_PLLSTAT_OFFSET 0x168 /* PLL Status */ +#define TIVA_SYSCON_SLPPWRCFG_OFFSET 0x188 /* Sleep Power Configuration */ +#define TIVA_SYSCON_DSLPPWRCFG_OFFSET 0x18c /* Deep-Sleep Power Configuration */ +#define TIVA_SYSCON_LDOSPCTL_OFFSET 0x1b4 /* LDO Sleep Power Control */ +#define TIVA_SYSCON_LDOSPCAL_OFFSET 0x1b8 /* LDO Sleep Power Calibration */ +#define TIVA_SYSCON_LDODPCTL_OFFSET 0x1bc /* LDO Deep-Sleep Power Control */ +#define TIVA_SYSCON_LDODPCAL_OFFSET 0x1c0 /* LDO Deep-Sleep Power Calibration */ +#define TIVA_SYSCON_SDPMST_OFFSET 0x1cc /* Sleep / Deep-Sleep Power Mode Status */ + +#define TIVA_SYSCON_PPWD_OFFSET 0x300 /* Watchdog Timer Peripheral Present */ +#define TIVA_SYSCON_PPTIMER_OFFSET 0x304 /* 16/32-Bit Timer Peripheral Present */ +#define TIVA_SYSCON_PPGPIO_OFFSET 0x308 /* GPIO Peripheral Present */ +#define TIVA_SYSCON_PPDMA_OFFSET 0x30c /* uDMA Peripheral Present */ +#define TIVA_SYSCON_PPHIB_OFFSET 0x314 /* Hibernation Peripheral Present */ +#define TIVA_SYSCON_PPUART_OFFSET 0x318 /* UART Present */ +#define TIVA_SYSCON_PPSSI_OFFSET 0x31c /* SSI Peripheral Present */ +#define TIVA_SYSCON_PPI2C_OFFSET 0x320 /* I2C Peripheral Present */ +#define TIVA_SYSCON_PPUSB_OFFSET 0x328 /* USB Peripheral Present */ +#define TIVA_SYSCON_PPCAN_OFFSET 0x334 /* CAN Peripheral Present */ +#define TIVA_SYSCON_PPADC_OFFSET 0x338 /* ADC Peripheral Present */ +#define TIVA_SYSCON_PPACMP_OFFSET 0x33c /* Analog Comparator Peripheral Present */ +#define TIVA_SYSCON_PPPWM_OFFSET 0x340 /* Pulse Width Modulator Peripheral Present */ +#define TIVA_SYSCON_PPQEI_OFFSET 0x344 /* Quadrature Encoder Peripheral Present */ +#define TIVA_SYSCON_PPEEPROM_OFFSET 0x358 /* EEPROM Peripheral Present */ +#define TIVA_SYSCON_PPWTIMER_OFFSET 0x35c /* 32/64-Bit Wide Timer Peripheral Present */ + +#define TIVA_SYSCON_SRWD_OFFSET 0x500 /* Watchdog Timer Software Reset */ +#define TIVA_SYSCON_SRTIMER_OFFSET 0x504 /* 16/32-Bit Timer Software Reset */ +#define TIVA_SYSCON_SRGPIO_OFFSET 0x508 /* GPIO Software Reset */ +#define TIVA_SYSCON_SRDMA_OFFSET 0x50c /* uDMA Software Reset */ +#define TIVA_SYSCON_SRHIB_OFFSET 0x514 /* Hibernation Software Reset */ +#define TIVA_SYSCON_SRUART_OFFSET 0x518 /* UART Software Reset*/ +#define TIVA_SYSCON_SRSSI_OFFSET 0x51c /* SSI Software Reset */ +#define TIVA_SYSCON_SRI2C_OFFSET 0x520 /* I2C Software Reset */ +#define TIVA_SYSCON_SRUSB_OFFSET 0x528 /* USB Software Reset */ +#define TIVA_SYSCON_SRCAN_OFFSET 0x534 /* CAN Software Reset */ +#define TIVA_SYSCON_SRADC_OFFSET 0x538 /* ADC Software Reset */ +#define TIVA_SYSCON_SRACMP_OFFSET 0x53c /* Analog Comparator Software Reset */ +#define TIVA_SYSCON_SRPWM_OFFSET 0x540 /* Pulse Width Modulator Software Reset */ +#define TIVA_SYSCON_SRQEI_OFFSET 0x544 /* Quadrature Encoder Interface Software Reset */ +#define TIVA_SYSCON_SREEPROM_OFFSET 0x558 /* EEPROM Software Reset */ +#define TIVA_SYSCON_SRWTIMER_OFFSET 0x55c /* 32/64-Bit Wide Timer Software Reset */ + +#define TIVA_SYSCON_RCGCWD_OFFSET 0x600 /* Watchdog Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCTIMER_OFFSET 0x604 /* 16/32-Bit Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCGPIO_OFFSET 0x608 /* GPIO Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCDMA_OFFSET 0x60c /* uDMA Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCHIB_OFFSET 0x614 /* Hibernation Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUART_OFFSET 0x618 /* UART Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCSSI_OFFSET 0x61c /* SSI Run Mode Clock Gating Control*/ +#define TIVA_SYSCON_RCGCI2C_OFFSET 0x620 /* I2C Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUSB_OFFSET 0x628 /* USB Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCCAN_OFFSET 0x634 /* CAN Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCADC_OFFSET 0x638 /* ADC Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCACMP_OFFSET 0x63c /* Analog Comparator Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCPWM_OFFSET 0x640 /* Pulse Width Modulator Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCQEI_OFFSET 0x644 /* Quadrature Encoder Interface Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEEPROM_OFFSET 0x658 /* EEPROM Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCWTIMER_OFFSET 0x65c /* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define TIVA_SYSCON_SCGCWD_OFFSET 0x700 /* Watchdog Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCTIMER_OFFSET 0x704 /* 16/32-Bit Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCGPIO_OFFSET 0x708 /* GPIO Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCDMA_OFFSET 0x70c /* uDMA Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCHIB_OFFSET 0x714 /* Hibernation Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUART_OFFSET 0x718 /* UART Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCSSI_OFFSET 0x71c /* SSI Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCI2C_OFFSET 0x720 /* I2C Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUSB_OFFSET 0x728 /* USB Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCCAN_OFFSET 0x734 /* CAN Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCADC_OFFSET 0x738 /* ADC Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCACMP_OFFSET 0x73c /* Analog Comparator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCPWM_OFFSET 0x740 /* PulseWidthModulator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCQEI_OFFSET 0x744 /* Quadrature Encoder Interface Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEEPROM_OFFSET 0x758 /* EEPROM Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCWTIMER_OFFSET 0x75c /* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_DCGCWD_OFFSET 0x800 /* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCTIMER_OFFSET 0x804 /* Clock Gating Control */ +#define TIVA_SYSCON_DCGCGPIO_OFFSET 0x808 /* GPIO Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCDMA_OFFSET 0x80c /* uDMA Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCHIB_OFFSET 0x814 /* Hibernation Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUART_OFFSET 0x818 /* UART Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCSSI_OFFSET 0x81c /* SSI Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCI2C_OFFSET 0x820 /* I2C Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUSB_OFFSET 0x828 /* USB Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCCAN_OFFSET 0x834 /* CAN Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCADC_OFFSET 0x838 /* ADC Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCACMP_OFFSET 0x83c /* Analog Comparator Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCPWM_OFFSET 0x840 /* Pulse Width Modulator Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCQEI_OFFSET 0x844 /* Quadrature Encoder Interface Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEEPROM_OFFSET 0x858 /* EEPROM Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCWTIMER_OFFSET 0x85c /* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define TIVA_SYSCON_PRWD_OFFSET 0xa00 /* Watchdog Timer Peripheral Ready */ +#define TIVA_SYSCON_PRTIMER_OFFSET 0xa04 /* 16/32-Bit Timer Peripheral Ready */ +#define TIVA_SYSCON_PRGPIO_OFFSET 0xa08 /* GPIO Peripheral Ready */ +#define TIVA_SYSCON_PRDMA_OFFSET 0xa0c /* uDMA Peripheral Ready */ +#define TIVA_SYSCON_PRHIB_OFFSET 0xa14 /* Hibernation Peripheral Ready */ +#define TIVA_SYSCON_PRUART_OFFSET 0xa18 /* UART Peripheral Ready */ +#define TIVA_SYSCON_PRSSI_OFFSET 0xa1c /* SSI Peripheral Ready */ +#define TIVA_SYSCON_PRI2C_OFFSET 0xa20 /* I2C Peripheral Ready */ +#define TIVA_SYSCON_PRUSB_OFFSET 0xa28 /* USB Peripheral Ready */ +#define TIVA_SYSCON_PRCAN_OFFSET 0xa34 /* CAN Peripheral Ready */ +#define TIVA_SYSCON_PRADC_OFFSET 0xa38 /* ADC Peripheral Ready */ +#define TIVA_SYSCON_PRACMP_OFFSET 0xa3c /* Analog Comparator Peripheral Ready */ +#define TIVA_SYSCON_PRPWM_OFFSET 0xa40 /* Pulse Width Modulator Peripheral Ready */ +#define TIVA_SYSCON_PRQEI_OFFSET 0xa44 /* Quadrature Encoder Interface Peripheral Ready */ +#define TIVA_SYSCON_PREEPROM_OFFSET 0xa58 /* EEPROM Peripheral Ready */ +#define TIVA_SYSCON_PRWTIMER_OFFSET 0xa5c /* 2/64-BitWide Timer Peripheral Ready */ + +/* System Control Legacy Register Offsets ***************************************************/ + +#define TIVA_SYSCON_DC0_OFFSET 0x008 /* Device Capabilities 0 */ +#define TIVA_SYSCON_DC1_OFFSET 0x010 /* Device Capabilities 1 */ +#define TIVA_SYSCON_DC2_OFFSET 0x014 /* Device Capabilities 2 */ +#define TIVA_SYSCON_DC3_OFFSET 0x018 /* Device Capabilities 3 */ +#define TIVA_SYSCON_DC4_OFFSET 0x01c /* Device Capabilities 4 */ +#define TIVA_SYSCON_DC5_OFFSET 0x020 /* Device Capabilities 5 */ +#define TIVA_SYSCON_DC6_OFFSET 0x024 /* Device Capabilities 6 */ +#define TIVA_SYSCON_DC7_OFFSET 0x028 /* Device Capabilities 7 */ +#define TIVA_SYSCON_DC8_OFFSET 0x02c /* Device Capabilities 8 */ + +#define TIVA_SYSCON_SRCR0_OFFSET 0x040 /* Software Reset Control 0 */ +#define TIVA_SYSCON_SRCR1_OFFSET 0x044 /* Software Reset Control 1 */ +#define TIVA_SYSCON_SRCR2_OFFSET 0x048 /* Software Reset Control 2 */ + +#define TIVA_SYSCON_RCGC0_OFFSET 0x100 /* Run Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_RCGC1_OFFSET 0x104 /* Run Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_RCGC2_OFFSET 0x108 /* Run Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_SCGC0_OFFSET 0x110 /* Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_SCGC1_OFFSET 0x114 /* Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_SCGC2_OFFSET 0x118 /* Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DCGC0_OFFSET 0x120 /* Deep Sleep Mode Clock Gating Control Register 0 */ +#define TIVA_SYSCON_DCGC1_OFFSET 0x124 /* Deep Sleep Mode Clock Gating Control Register 1 */ +#define TIVA_SYSCON_DCGC2_OFFSET 0x128 /* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define TIVA_SYSCON_DC9_OFFSET 0x190 /* Device Capabilities */ +#define TIVA_SYSCON_NVMSTAT_OFFSET 0x1a0 /* Non-Volatile Memory Information */ + +/* System Control Register Addresses ********************************************************/ + +#define TIVA_SYSCON_DID0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID0_OFFSET) +#define TIVA_SYSCON_DID1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DID1_OFFSET) +#define TIVA_SYSCON_PBORCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_PBORCTL_OFFSET) +#define TIVA_SYSCON_RIS (TIVA_SYSCON_BASE + TIVA_SYSCON_RIS_OFFSET) +#define TIVA_SYSCON_IMC (TIVA_SYSCON_BASE + TIVA_SYSCON_IMC_OFFSET) +#define TIVA_SYSCON_MISC (TIVA_SYSCON_BASE + TIVA_SYSCON_MISC_OFFSET) +#define TIVA_SYSCON_RESC (TIVA_SYSCON_BASE + TIVA_SYSCON_RESC_OFFSET) +#define TIVA_SYSCON_RCC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC_OFFSET) +#define TIVA_SYSCON_GPIOHBCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_GPIOHBCTL_OFFSET) +#define TIVA_SYSCON_RCC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCC2_OFFSET) +#define TIVA_SYSCON_MOSCCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_MOSCCTL_OFFSET) +#define TIVA_SYSCON_DSLPCLKCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPCLKCFG_OFFSET) +#define TIVA_SYSCON_SYSPROP (TIVA_SYSCON_BASE + TIVA_SYSCON_SYSPROP_OFFSET) +#define TIVA_SYSCON_PIOSCCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCCAL_OFFSET) +#define TIVA_SYSCON_PIOSCSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PIOSCSTAT_OFFSET) +#define TIVA_SYSCON_PLLFREQ0 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ0_OFFSET) +#define TIVA_SYSCON_PLLFREQ1 (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLFREQ1_OFFSET) +#define TIVA_SYSCON_PLLSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_PLLSTAT_OFFSET) +#define TIVA_SYSCON_SLPPWRCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_SLPPWRCFG_OFFSET) +#define TIVA_SYSCON_DSLPPWRCFG (TIVA_SYSCON_BASE + TIVA_SYSCON_DSLPPWRCFG_OFFSET) +#define TIVA_SYSCON_LDOSPCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDOSPCTL_OFFSET) +#define TIVA_SYSCON_LDOSPCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDOSPCAL_OFFSET) +#define TIVA_SYSCON_LDODPCTL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDODPCTL_OFFSET) +#define TIVA_SYSCON_LDODPCAL (TIVA_SYSCON_BASE + TIVA_SYSCON_LDODPCAL_OFFSET) +#define TIVA_SYSCON_SDPMST (TIVA_SYSCON_BASE + TIVA_SYSCON_SDPMST_OFFSET) + +#define TIVA_SYSCON_PPWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWD_OFFSET) +#define TIVA_SYSCON_PPTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPTIMER_OFFSET) +#define TIVA_SYSCON_PPGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PPGPIO_OFFSET) +#define TIVA_SYSCON_PPDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PPDMA_OFFSET) +#define TIVA_SYSCON_PPHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPHIB_OFFSET) +#define TIVA_SYSCON_PPUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUART_OFFSET) +#define TIVA_SYSCON_PPSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPSSI_OFFSET) +#define TIVA_SYSCON_PPI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PPI2C_OFFSET) +#define TIVA_SYSCON_PPUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PPUSB_OFFSET) +#define TIVA_SYSCON_PPCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PPCAN_OFFSET) +#define TIVA_SYSCON_PPADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PPADC_OFFSET) +#define TIVA_SYSCON_PPACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PPACMP_OFFSET) +#define TIVA_SYSCON_PPPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPPWM_OFFSET) +#define TIVA_SYSCON_PPQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_PPQEI_OFFSET) +#define TIVA_SYSCON_PPEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PPEEPROM_OFFSET) +#define TIVA_SYSCON_PPWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PPWTIMER_OFFSET) + +#define TIVA_SYSCON_SRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWD_OFFSET) +#define TIVA_SYSCON_SRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRTIMER_OFFSET) +#define TIVA_SYSCON_SRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SRGPIO_OFFSET) +#define TIVA_SYSCON_SRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SRDMA_OFFSET) +#define TIVA_SYSCON_SRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRHIB_OFFSET) +#define TIVA_SYSCON_SRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUART_OFFSET) +#define TIVA_SYSCON_SRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SRSSI_OFFSET) +#define TIVA_SYSCON_SRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SRI2C_OFFSET) +#define TIVA_SYSCON_SRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SRUSB_OFFSET) +#define TIVA_SYSCON_SRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCAN_OFFSET) +#define TIVA_SYSCON_SRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SRADC_OFFSET) +#define TIVA_SYSCON_SRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SRACMP_OFFSET) +#define TIVA_SYSCON_SRPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_SRPWM_OFFSET) +#define TIVA_SYSCON_SRQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_SRQEI_OFFSET) +#define TIVA_SYSCON_SREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SREEPROM_OFFSET) +#define TIVA_SYSCON_SRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SRWTIMER_OFFSET) + +#define TIVA_SYSCON_RCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWD_OFFSET) +#define TIVA_SYSCON_RCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCTIMER_OFFSET) +#define TIVA_SYSCON_RCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCGPIO_OFFSET) +#define TIVA_SYSCON_RCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCDMA_OFFSET) +#define TIVA_SYSCON_RCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCHIB_OFFSET) +#define TIVA_SYSCON_RCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUART_OFFSET) +#define TIVA_SYSCON_RCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCSSI_OFFSET) +#define TIVA_SYSCON_RCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCI2C_OFFSET) +#define TIVA_SYSCON_RCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCUSB_OFFSET) +#define TIVA_SYSCON_RCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCCAN_OFFSET) +#define TIVA_SYSCON_RCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCADC_OFFSET) +#define TIVA_SYSCON_RCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCACMP_OFFSET) +#define TIVA_SYSCON_RCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCPWM_OFFSET) +#define TIVA_SYSCON_RCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCQEI_OFFSET) +#define TIVA_SYSCON_RCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCEEPROM_OFFSET) +#define TIVA_SYSCON_RCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_SCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWD_OFFSET) +#define TIVA_SYSCON_SCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCTIMER_OFFSET) +#define TIVA_SYSCON_SCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCGPIO_OFFSET) +#define TIVA_SYSCON_SCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCDMA_OFFSET) +#define TIVA_SYSCON_SCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCHIB_OFFSET) +#define TIVA_SYSCON_SCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUART_OFFSET) +#define TIVA_SYSCON_SCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCSSI_OFFSET) +#define TIVA_SYSCON_SCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCI2C_OFFSET) +#define TIVA_SYSCON_SCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCUSB_OFFSET) +#define TIVA_SYSCON_SCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCCAN_OFFSET) +#define TIVA_SYSCON_SCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCADC_OFFSET) +#define TIVA_SYSCON_SCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCACMP_OFFSET) +#define TIVA_SYSCON_SCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCPWM_OFFSET +#define TIVA_SYSCON_SCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCQEI_OFFSET +#define TIVA_SYSCON_SCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCEEPROM_OFFSET) +#define TIVA_SYSCON_SCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_DCGCWD (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWD_OFFSET) +#define TIVA_SYSCON_DCGCTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCTIMER_OFFSET) +#define TIVA_SYSCON_DCGCGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCGPIO_OFFSET) +#define TIVA_SYSCON_DCGCDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCDMA_OFFSET) +#define TIVA_SYSCON_DCGCHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCHIB_OFFSET) +#define TIVA_SYSCON_DCGCUART (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUART_OFFSET) +#define TIVA_SYSCON_DCGCSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCSSI_OFFSET) +#define TIVA_SYSCON_DCGCI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCI2C_OFFSET) +#define TIVA_SYSCON_DCGCUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCUSB_OFFSET) +#define TIVA_SYSCON_DCGCCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCCAN_OFFSET) +#define TIVA_SYSCON_DCGCADC (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCADC_OFFSET) +#define TIVA_SYSCON_DCGCACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCACMP_OFFSET) +#define TIVA_SYSCON_DCGCPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCPWM_OFFSET) +#define TIVA_SYSCON_DCGCQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCQEI_OFFSET) +#define TIVA_SYSCON_DCGCEEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCEEPROM_OFFSET) +#define TIVA_SYSCON_DCGCWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGCWTIMER_OFFSET) + +#define TIVA_SYSCON_PRWD (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWD_OFFSET) +#define TIVA_SYSCON_PRTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRTIMER_OFFSET) +#define TIVA_SYSCON_PRGPIO (TIVA_SYSCON_BASE + TIVA_SYSCON_PRGPIO_OFFSET) +#define TIVA_SYSCON_PRDMA (TIVA_SYSCON_BASE + TIVA_SYSCON_PRDMA_OFFSET) +#define TIVA_SYSCON_PRHIB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRHIB_OFFSET) +#define TIVA_SYSCON_PRUART (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUART_OFFSET) +#define TIVA_SYSCON_PRSSI (TIVA_SYSCON_BASE + TIVA_SYSCON_PRSSI_OFFSET) +#define TIVA_SYSCON_PRI2C (TIVA_SYSCON_BASE + TIVA_SYSCON_PRI2C_OFFSET) +#define TIVA_SYSCON_PRUSB (TIVA_SYSCON_BASE + TIVA_SYSCON_PRUSB_OFFSET) +#define TIVA_SYSCON_PRCAN (TIVA_SYSCON_BASE + TIVA_SYSCON_PRCAN_OFFSET) +#define TIVA_SYSCON_PRADC (TIVA_SYSCON_BASE + TIVA_SYSCON_PRADC_OFFSET) +#define TIVA_SYSCON_PRACMP (TIVA_SYSCON_BASE + TIVA_SYSCON_PRACMP_OFFSET) +#define TIVA_SYSCON_PRPWM (TIVA_SYSCON_BASE + TIVA_SYSCON_PRPWM_OFFSET) +#define TIVA_SYSCON_PRQEI (TIVA_SYSCON_BASE + TIVA_SYSCON_PRQEI_OFFSET) +#define TIVA_SYSCON_PREEPROM (TIVA_SYSCON_BASE + TIVA_SYSCON_PREEPROM_OFFSET) +#define TIVA_SYSCON_PRWTIMER (TIVA_SYSCON_BASE + TIVA_SYSCON_PRWTIMER_OFFSET) + +/* System Control Legacy Register Addresses *************************************************/ + +#define TIVA_SYSCON_DC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC0_OFFSET) +#define TIVA_SYSCON_DC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC1_OFFSET) +#define TIVA_SYSCON_DC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC2_OFFSET) +#define TIVA_SYSCON_DC3 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC3_OFFSET) +#define TIVA_SYSCON_DC4 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC4_OFFSET) +#define TIVA_SYSCON_DC5 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC5_OFFSET) +#define TIVA_SYSCON_DC6 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC6_OFFSET) +#define TIVA_SYSCON_DC7 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC7_OFFSET) +#define TIVA_SYSCON_DC8 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC8_OFFSET) + +#define TIVA_SYSCON_SRCR0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR0_OFFSET) +#define TIVA_SYSCON_SRCR1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR1_OFFSET) +#define TIVA_SYSCON_SRCR2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SRCR2_OFFSET) + +#define TIVA_SYSCON_RCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC0_OFFSET) +#define TIVA_SYSCON_RCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC1_OFFSET) +#define TIVA_SYSCON_RCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_RCGC2_OFFSET) + +#define TIVA_SYSCON_SCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC0_OFFSET) +#define TIVA_SYSCON_SCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC1_OFFSET) +#define TIVA_SYSCON_SCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_SCGC2_OFFSET) + +#define TIVA_SYSCON_DCGC0 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC0_OFFSET) +#define TIVA_SYSCON_DCGC1 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC1_OFFSET) +#define TIVA_SYSCON_DCGC2 (TIVA_SYSCON_BASE + TIVA_SYSCON_DCGC2_OFFSET) + +#define TIVA_SYSCON_DC9 (TIVA_SYSCON_BASE + TIVA_SYSCON_DC9_OFFSET) +#define TIVA_SYSCON_NVMSTAT (TIVA_SYSCON_BASE + TIVA_SYSCON_NVMSTAT_OFFSET) + +/* System Control Register Bit Definitions **************************************************/ + +/* Device Identification 0 */ + +#define SYSCON_DID0_MINOR_SHIFT 0 /* Bits 7-0: Minor Revision of the device */ +#define SYSCON_DID0_MINOR_MASK (0xff << SYSCON_DID0_MINOR_SHIFT) +#define SYSCON_DID0_MAJOR_SHIFT 8 /* Bits 15-8: Major Revision of the device */ +#define SYSCON_DID0_MAJOR_MASK (0xff << SYSCON_DID0_MAJOR_SHIFT) +#define SYSCON_DID0_CLASS_SHIFT 16 /* Bits 23-16: Device Class */ +#define SYSCON_DID0_CLASS_MASK (0xff << SYSCON_DID0_CLASS_SHIFT) +#define SYSCON_DID0_VER_SHIFT 28 /* Bits 30-28: DID0 Version */ +#define SYSCON_DID0_VER_MASK (7 << SYSCON_DID0_VER_SHIFT) + +/* Device Identification 1 */ + +#define SYSCON_DID1_QUAL_SHIFT 0 /* Bits 1-0: Qualification Status */ +#define SYSCON_DID1_QUAL_MASK (0x03 << SYSCON_DID1_QUAL_SHIFT) +#define SYSCON_DID1_ROHS (1 << 2) /* Bit 2: RoHS-Compliance */ +#define SYSCON_DID1_PKG_SHIFT 3 /* Bits 4-3: Package Type */ +#define SYSCON_DID1_PKG_MASK (0x03 << SYSCON_DID1_PKG_SHIFT) +#define SYSCON_DID1_TEMP_SHIFT 5 /* Bits 7-5: Temperature Range */ +#define SYSCON_DID1_TEMP_MASK (0x07 << SYSCON_DID1_TEMP_SHIFT) +#define SYSCON_DID1_PINCOUNT_SHIFT 13 /* Bits 15-13: Package Pin Count */ +#define SYSCON_DID1_PINCOUNT_MASK (0x07 << SYSCON_DID1_PINCOUNT_SHIFT) +#define SYSCON_DID1_PARTNO_SHIFT 16 /* Bits 23-16: Part Number */ +#define SYSCON_DID1_PARTNO_MASK (0xff << SYSCON_DID1_PARTNO_SHIFT) +#define SYSCON_DID1_FAM_SHIFT 24 /* Bits 27-24: Family */ +#define SYSCON_DID1_FAM_MASK (0x0f << SYSCON_DID1_FAM_SHIFT) +#define SYSCON_DID1_VER_SHIFT 28 /* Bits 31-28: DID1 Version */ +#define SYSCON_DID1_VER_MASK (0x0f << SYSCON_DID1_VER_SHIFT) + +/* Brown-Out Reset Control */ + +#define SYSCON_PBORCTL_BORI1 (1 << 1) /* Bit 1: VDD under BOR1 Event Action */ +#define SYSCON_PBORCTL_BORI0 (1 << 2) /* Bit 2: VDD under BOR0 Event Action */ + +/* Raw Interrupt Status */ + +#define SYSCON_RIS_BORR1RIS (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Status */ +#define SYSCON_RIS_MOFRIS (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Status */ +#define SYSCON_RIS_PLLLRIS (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_USBPLLLRIS (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_MOSCPUPRIS (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Status */ +#define SYSCON_RIS_VDDARIS (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Status */ +#define SYSCON_RIS_BOR0RIS (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Status */ + +/* Interrupt Mask Control */ + +#define SYSCON_IMC_BORR1IM (1 << 1) /* Bit 1: VDD under BOR1 Interrupt Mask */ +#define SYSCON_IMC_MOFIM (1 << 3) /* Bit 3: Main Oscillator Failure Interrupt Mask */ +#define SYSCON_IMC_PLLLIM (1 << 6) /* Bit 6: PLL Lock Interrupt Mask */ +#define SYSCON_IMC_USBPLLLIM (1 << 7) /* Bit 7: USB PLL Lock Interrupt Mask */ +#define SYSCON_IMC_MOSCPUPIM (1 << 8) /* Bit 8: MOSC Power Up Interrupt Mask */ +#define SYSCON_IMC_VDDAIM (1 << 10) /* Bit 10: VDDA Power OK Event Interrupt Mask */ +#define SYSCON_IMC_BOR0IM (1 << 11) /* Bit 11: VDD under BOR0 Interrupt Mask */ + +/* Masked Interrupt Status and Clear */ + +#define SYSCON_MISC_BORR1MIS (1 << 1) /* Bit 1: VDD under BOR1 Masked Interrupt Status */ +#define SYSCON_MISC_MOFMIS (1 << 3) /* Bit 3: Main Oscillator Failure Masked Interrupt Status */ +#define SYSCON_MISC_PLLLMIS (1 << 6) /* Bit 6: PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_USBPLLLMIS (1 << 7) /* Bit 7: USB PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_MOSCPUPMIS (1 << 8) /* Bit 8: MOSC Power Up Masked Interrupt Status */ +#define SYSCON_MISC_VDDAMIS (1 << 10) /* Bit 10: VDDA Power OK Event Masked Interrupt Status */ +#define SYSCON_MISC_BOR0MIS (1 << 11) /* Bit 11: VDD under BOR0 Masked Interrupt Status */ + +/* Reset Cause */ + +#define SYSCON_RESC_EXT (1 << 0) /* Bit 0: External Reset */ +#define SYSCON_RESC_POR (1 << 1) /* Bit 1: Power-On Reset */ +#define SYSCON_RESC_BOR (1 << 2) /* Bit 2: Brown-Out Reset */ +#define SYSCON_RESC_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset */ +#define SYSCON_RESC_SW (1 << 4) /* Bit 4: Software Reset */ +#define SYSCON_RESC_WDT1 (1 << 5) /* Bit 5: Watchdog Timer 1 Reset */ +#define SYSCON_RESC_MOSCFAIL (1 << 16) /* Bit 16: MOSC Failure Reset */ + +/* Run-Mode Clock Configuration */ + +#define SYSCON_RCC_MOSCDIS (1 << 0) /* Bit 0: Main Oscillator Disable */ +#define SYSCON_RCC_OSCSRC_SHIFT 4 /* Bits 5-4: Oscillator Source */ +#define SYSCON_RCC_OSCSRC_MASK (0x03 << SYSCON_RCC_OSCSRC_SHIFT) +# define SYSCON_RCC_OSCSRC_MOSC (0 << SYSCON_RCC_OSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_RCC_OSCSRC_PIOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC_OSCSRC_PIOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC_OSCSRC_LFIOSC (3 << SYSCON_RCC_OSCSRC_SHIFT) /* Low-frequency internal oscillator */ +#define SYSCON_RCC_XTAL_SHIFT 6 /* Bits 10-6: Crystal Value */ +#define SYSCON_RCC_XTAL_MASK (31 << SYSCON_RCC_XTAL_SHIFT) +# define SYSCON_RCC_XTAL4000KHZ (6 << SYSCON_RCC_XTAL_SHIFT) /* 4 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4096KHZ (7 << SYSCON_RCC_XTAL_SHIFT) /* 4.096 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL4915p2KHZ (8 << SYSCON_RCC_XTAL_SHIFT) /* 4.9152 MHz (NO PLL) */ +# define SYSCON_RCC_XTAL5000KHZ (9 << SYSCON_RCC_XTAL_SHIFT) /* 5 MHz (USB) */ +# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.12 MHz */ +# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6 MHz (USB) */ +# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.144 MHz */ +# define SYSCON_RCC_XTAL7372p8KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728 MHz */ +# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8 MHz (USB) */ +# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.192 MHz */ +# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */ +# define SYSCON_RCC_XTAL12288KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */ +# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */ +# define SYSCON_RCC_XTAL14318p18KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */ +# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */ +# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */ +# define SYSCON_RCC_XTAL18000KHZ (23 << SYSCON_RCC_XTAL_SHIFT) /* 18.0 MHz (USB) */ +# define SYSCON_RCC_XTAL20000KHZ (24 << SYSCON_RCC_XTAL_SHIFT) /* 20.0 MHz (USB) */ +# define SYSCON_RCC_XTAL24000KHZ (25 << SYSCON_RCC_XTAL_SHIFT) /* 24.0 MHz (USB) */ +# define SYSCON_RCC_XTAL25000KHZ (26 << SYSCON_RCC_XTAL_SHIFT) /* 25.0 MHz (USB) */ +#define SYSCON_RCC_BYPASS (1 << 11) /* Bit 11: PLL Bypass */ +#define SYSCON_RCC_PWRDN (1 << 13) /* Bit 13: PLL Power Down */ +#define SYSCON_RCC_PWMDIV_SHIFT 17 /* Bits 19-17: PWM Unit Clock Divisor */ +#define SYSCON_RCC_PWMDIV_MASK (7 << SYSCON_RCC_PWMDIV_SHIFT) +# define SYSCON_RCC_PWMDIV_2 (0 << SYSCON_RCC_PWMDIV_SHIFT) /* /2 */ +# define SYSCON_RCC_PWMDIV_4 (1 << SYSCON_RCC_PWMDIV_SHIFT) /* /4 */ +# define SYSCON_RCC_PWMDIV_8 (2 << SYSCON_RCC_PWMDIV_SHIFT) /* /8 */ +# define SYSCON_RCC_PWMDIV_16 (3 << SYSCON_RCC_PWMDIV_SHIFT) /* /16 */ +# define SYSCON_RCC_PWMDIV_32 (4 << SYSCON_RCC_PWMDIV_SHIFT) /* /32 */ +# define SYSCON_RCC_PWMDIV_64 (7 << SYSCON_RCC_PWMDIV_SHIFT) /* /64 (default) */ +#define SYSCON_RCC_USEPWMDIV (1 << 20) /* Bit 20: Enable PWM Clock Divisor */ +#define SYSCON_RCC_USESYSDIV (1 << 22) /* Bit 22: Enable System Clock Divider */ +#define SYSCON_RCC_SYSDIV_SHIFT 23 /* Bits 26-23: System Clock Divisor */ +#define SYSCON_RCC_SYSDIV_MASK (0x0f << SYSCON_RCC_SYSDIV_SHIFT) +# define SYSCON_RCC_SYSDIV(n) (((n)-1) << SYSCON_RCC_SYSDIV_SHIFT) +#define SYSCON_RCC_ACG (1 << 27) /* Bit 27: Auto Clock Gating */ + +/* GPIO High-Performance Bus Control */ + +#define SYSCON_GPIOHBCTL_PORT(n) (1 << (n)) +# define SYSCON_GPIOHBCTL_PORTA (1 << 0) /* Bit 0: Port A Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTB (1 << 1) /* Bit 1: Port B Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTC (1 << 2) /* Bit 2: Port C Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTD (1 << 3) /* Bit 3: Port D Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTE (1 << 4) /* Bit 4: Port E Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTF (1 << 5) /* Bit 5: Port F Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTG (1 << 6) /* Bit 6: Port G Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTH (1 << 7) /* Bit 7: Port H Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTJ (1 << 8) /* Bit 8: Port J Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTK (1 << 9) /* Bit 9: Port K Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTL (1 << 10) /* Bit 10: Port L Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTM (1 << 11) /* Bit 11: Port M Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTN (1 << 12) /* Bit 12: Port N Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTP (1 << 13) /* Bit 13: Port P Advanced High-Performance Bus */ +# define SYSCON_GPIOHBCTL_PORTQ (1 << 14) /* Bit 14: Port Q Advanced High-Performance Bus */ + +/* Run-Mode Clock Configuration 2 */ + +#define SYSCON_RCC2_OSCSRC2_SHIFT 4 /* Bits 6-4: Oscillator Source */ +#define SYSCON_RCC2_OSCSRC2_MASK (7 << SYSCON_RCC2_OSCSRC2_SHIFT) +# define SYSCON_RCC2_OSCSRC2_MOSC (0 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Main oscillator */ +# define SYSCON_RCC2_OSCSRC2_PIOSC (1 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_RCC2_OSCSRC2_PIOSC4 (2 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_RCC2_OSCSRC2_LFIOSC (4 << SYSCON_RCC2_OSCSRC2_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_RCC2_OSCSRC2_32768HZ (7 << SYSCON_RCC2_OSCSRC2_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_RCC2_BYPASS2 (1 << 11) /* Bit 11: Bypass PLL */ +#define SYSCON_RCC2_PWRDN2 (1 << 13) /* Bit 13: Power-Down PLL */ +#define SYSCON_RCC2_USBPWRDN (1 << 14) /* Bit 14: Power-Down USB PLL */ +#define SYSCON_RCC2_SYSDIV2LSB (1 << 22) /* Bit 22: Additional LSB for SYSDIV2 */ +#define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */ +#define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT) +# define SYSCON_RCC2_SYSDIV_DIV400(n) (((n-1) >> 1) << SYSCON_RCC2_SYSDIV2_SHIFT) +#define SYSCON_RCC2_DIV400 (1 << 30) /* Bit 30: Divide PLL as 400 MHz vs. 200 MHz */ +#define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */ + +/* Main Oscillator Control */ + +#define SYSCON_MOSCCTL_CVAL (1 << 0) /* Bit 0: Clock Validation for MOSC */ +#define SYSCON_MOSCCTL_MOSCIM (1 << 1) /* Bit 1: MOSC Failure Action */ +#define SYSCON_MOSCCTL_NOXTAL (1 << 2) /* Bit 2: No Crystal Connected */ + +/* Deep Sleep Clock Configuration */ + +#define SYSCON_DSLPCLKCFG_PIOSCPD (1 << 1) /* Bit 1: PIOSC Power Down Request */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT 4 /* Bits 6-4: Clock Source */ +#define SYSCON_DSLPCLKCFG_DSOSCSRC_MASK (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) +# define SYSCON_DSLPCLKCFG_DSOSCSRC_MOSC (0 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Main oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC (1 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator (reset) */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_PIOSC4 (2 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Precision internal oscillator / 4 */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_LFIOSC (4 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* Low-frequency internal oscillator */ +# define SYSCON_DSLPCLKCFG_DSOSCSRC_32768KHZ (7 << SYSCON_DSLPCLKCFG_DSOSCSRC_SHIFT) /* 32.768KHz external oscillator */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT 23 /* Bits 28-23: Divider Field Override */ +#define SYSCON_DSLPCLKCFG_DSDIVORIDE_MASK (0x3f << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) +# define SYSCON_DSLPCLKCFG_DSDIVORIDE(b) (((n)-1) << SYSCON_DSLPCLKCFG_DSDIVORIDE_SHIFT) + +/* System Properties */ + +#define SYSCON_SYSPROP_FPU (1 << 0) /* Bit 0: FPU Present */ +#define SYSCON_SYSPROP_FLASHLPM (1 << 8) /* Bit 8: Flash Memory Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMLPM (1 << 10) /* Bit 10: SRAM Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMSM (1 << 11) /* Bit 11: SRAM Sleep/Deep-Sleep Standby Mode Present */ +#define SYSCON_SYSPROP_PIOSCPDE (1 << 12) /* Bit 12: PIOSC Power Down Present */ + +/* Precision Internal Oscillator Calibration */ + +#define SYSCON_PIOSCCAL_UT_SHIFT (0) /* Bits 0-6: User Trim Value */ +#define SYSCON_PIOSCCAL_UT_MASK (0x7f << SYSCON_PIOSCCAL_UT_SHIFT) +# define SYSCON_PIOSCCAL_UT(n) ((uint32_t)(n) << SYSCON_PIOSCCAL_UT_SHIFT) +#define SYSCON_PIOSCCAL_UPDATE (1 << 8) /* Bit 8: Update Trim */ +#define SYSCON_PIOSCCAL_CAL (1 << 9) /* Bit 9: Start Calibration */ +#define SYSCON_PIOSCCAL_UTEN (1 << 31) /* Bit 31: Use User Trim Value */ + +/* Precision Internal Oscillator Statistics */ + +#define SYSCON_PIOSCSTAT_CT_SHIFT (0) /* Bits 0-6: Calibration Trim Value */ +#define SYSCON_PIOSCSTAT_CT_MASK (0x7f << SYSCON_PIOSCSTAT_CT_SHIFT) +# define SYSCON_PIOSCSTAT_CT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_CT_SHIFT) +#define SYSCON_PIOSCSTAT_RESULT_SHIFT (8) /* Bits 8-9: Calibration Result */ +#define SYSCON_PIOSCSTAT_RESULT_MASK (3 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_RESULT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_RESULT_SHIFT) +#define SYSCON_PIOSCSTAT_DT_SHIFT (16) /* Bits 16-22: Default Trim Value */ +#define SYSCON_PIOSCSTAT_DT_MASK (0x7f << SYSCON_PIOSCSTAT_DT_SHIFT) +# define SYSCON_PIOSCSTAT_DT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_DT_SHIFT) + +/* PLL0 Frequency */ + +#define SYSCON_PLLFREQ0_MINT_SHIFT (0) /* Bits 0-9: PLL M Integer Value */ +#define SYSCON_PLLFREQ0_MINT_MASK (0x3ff << SYSCON_PLLFREQ0_MINT_SHIFT) +# define SYSCON_PLLFREQ0_MINT(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MINT_SHIFT) +#define SYSCON_PLLFREQ0_MFRAC_SHIFT (10) /* Bits 10-19: PLL M Fractional Value */ +#define SYSCON_PLLFREQ0_MFRAC_MASK (0x3ff << SYSCON_PLLFREQ0_MFRAC_SHIFT) +# define SYSCON_PLLFREQ0_MFRAC(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MFRAC_SHIFT) + +/* PLL1 Frequency */ + +#define SYSCON_PLLFREQ1_N_SHIFT (0) /* Bits 0-4: PLL N Value */ +#define SYSCON_PLLFREQ1_N_MASK (31 << SYSCON_PLLFREQ1_N_SHIFT) +# define SYSCON_PLLFREQ1_N(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_N_SHIFT) +#define SYSCON_PLLFREQ1_Q_SHIFT (8) /* Bits 8-12: PLL Q Value */ +#define SYSCON_PLLFREQ1_Q_MASK (31 << SYSCON_PLLFREQ1_Q_SHIFT) +# define SYSCON_PLLFREQ1_Q(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_Q_SHIFT) + +/* PLL Status */ + +#define SYSCON_PLLSTAT_LOCK (1 << 0) /* Bit 0: PLL Lock */ + +/* Sleep Power Configuration */ + +#define SYSCON_SLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_SLPPWRCFG_SRAMPM_MASK (3 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_SLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_LOWPWR (3 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_SLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_SLPPWRCFG_FLASHPM_MASK (3 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_SLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_FLASHPM_LOWPWRR (2 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ + +/* Deep-Sleep Power Configuration */ + +#define SYSCON_DSLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_DSLPPWRCFG_SRAMPM_MASK (3 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_DSLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_LOWPWR (3 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_DSLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_DSLPPWRCFG_FLASHPM_MASK (3 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_DSLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_FLASHPM_LOWPWR (2 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ + +/* LDO Sleep Power Control */ + +#define SYSCON_LDOSPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDOSPCTL_VLDO_MASK (0xff << SYSCON_LDOSPCTL_VLDO_SHIFT) +# define SYSCON_LDOSPCTL_VLDO_0p90V (0x12 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCTL_VLDO_0p95V (0x13 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCTL_VLDO_1p00V (0x14 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCTL_VLDO_1p05V (0x15 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCTL_VLDO_1p10V (0x16 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCTL_VLDO_1p15V (0x17 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCTL_VLDO_1p20V (0x18 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Sleep Power Calibration */ + +#define SYSCON_LDOSPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Sleep without PLL */ +#define SYSCON_LDOSPCAL_NOPLL_MASK (0xff << SYSCON_LDOSPCAL_NOPLL_SHIFT) +# define SYSCON_LDOSPCAL_NOPLL_0p90V (0x12 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_NOPLL_0p95V (0x13 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p00V (0x14 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p05V (0x15 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p10V (0x16 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p15V (0x17 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p20V (0x18 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCAL_WITHPLL_SHIFT (8) /* Bits 15-8: Sleep with PLL */ +#define SYSCON_LDOSPCAL_WITHPLL_MASK (0xff << SYSCON_LDOSPCAL_WITHPLL_SHIFT) +# define SYSCON_LDOSPCAL_WITHPLL_0p90V (0x12 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_WITHPLL_0p95V (0x13 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p00V (0x14 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p05V (0x15 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p10V (0x16 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p15V (0x17 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p20V (0x18 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.20 V */ + +/* LDO Deep-Sleep Power Control */ + +#define SYSCON_LDODPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDODPCTL_VLDO_MASK (0xff << SYSCON_LDODPCTL_VLDO_SHIFT) +# define SYSCON_LDODPCTL_VLDO_0p90V (0x12 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCTL_VLDO_0p95V (0x13 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCTL_VLDO_1p00V (0x14 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCTL_VLDO_1p05V (0x15 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCTL_VLDO_1p10V (0x16 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCTL_VLDO_1p15V (0x17 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCTL_VLDO_1p20V (0x18 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Deep-Sleep Power Calibration */ + +#define SYSCON_LDODPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Deep-Sleep without PLL */ +#define SYSCON_LDODPCAL_NOPLL_MASK (0xff << SYSCON_LDODPCAL_NOPLL_SHIFT) +# define SYSCON_LDODPCAL_NOPLL_0p90V (0x12 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_NOPLL_0p95V (0x13 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_NOPLL_1p00V (0x14 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_NOPLL_1p05V (0x15 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_NOPLL_1p10V (0x16 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_NOPLL_1p15V (0x17 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_NOPLL_1p20V (0x18 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCAL_30KHZ_SHIFT (8) /* Bits 15-8: Deep-Sleep with IOSC */ +#define SYSCON_LDODPCAL_30KHZ_MASK (0xff << SYSCON_LDODPCAL_30KHZ_SHIFT) +# define SYSCON_LDODPCAL_30KHZ_0p90V (0x12 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_30KHZ_0p95V (0x13 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_30KHZ_1p00V (0x14 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_30KHZ_1p05V (0x15 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_30KHZ_1p10V (0x16 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_30KHZ_1p15V (0x17 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_30KHZ_1p20V (0x18 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.20 V */ + +/* Sleep / Deep-Sleep Power Mode Status */ + +#define SYSCON_SDPMST_SPDERR (1 << 0) /* Bit 0: SRAM Power Down Request Error */ +#define SYSCON_SDPMST_FPDERR (1 << 1) /* Bit 1: Flash Memory Power Down Request Error */ +#define SYSCON_SDPMST_PPDERR (1 << 2) /* Bit 2: PIOSC Power Down Request Error */ +#define SYSCON_SDPMST_LDMINERR (1 << 3) /* Bit 3: VLDO Value Below Minimum Error in Deep-Sleep Mode */ +#define SYSCON_SDPMST_LSMINERR (1 << 4) /* Bit 4: VLDO Value Below Minimum Error in Sleep Mode */ +#define SYSCON_SDPMST_LMAXERR (1 << 6) /* Bit 6: VLDO Value Above Maximum Error */ +#define SYSCON_SDPMST_PPDW (1 << 7) /* Bit 7: PIOSC Power Down Request Warning */ +#define SYSCON_SDPMST_PRACT (1 << 16) /* Bit 16: Sleep or Deep-Sleep Power Request Active */ +#define SYSCON_SDPMST_LOWPWR (1 << 17) /* Bit 17: Sleep or Deep-Sleep Mode */ +#define SYSCON_SDPMST_FLASHLP (1 << 18) /* Bit 18: Flash Memory in Low Power State */ +#define SYSCON_SDPMST_LDOUA (1 << 19) /* Bit 19: LDO Update Active */ + +/* Watchdog Timer Peripheral Present */ + +#define SYSCON_PPWD(n) (1 << (n)) /* Bit n: WDTn present */ +# define SYSCON_PPWD_P0 (1 << 0) /* Bit 0: WDT0 present */ +# define SYSCON_PPWD_P1 (1 << 1) /* Bit 1: WDT1 present */ + +/* 16/32-Bit Timer Peripheral Present */ + +#define SYSCON_PPTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Present */ +# define SYSCON_PPTIMER_P0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 0 Present */ +# define SYSCON_PPTIMER_P5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 0 Present */ + +/* GPIO Peripheral Present */ + +#define SYSCON_PPGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Present */ +# define SYSCON_PPGPIO_P0 (1 << 0) /* Bit 0: GPIO Port A Present */ +# define SYSCON_PPGPIO_P1 (1 << 1) /* Bit 1: GPIO Port B Present */ +# define SYSCON_PPGPIO_P2 (1 << 2) /* Bit 2: GPIO Port C Present */ +# define SYSCON_PPGPIO_P3 (1 << 3) /* Bit 3: GPIO Port D Present */ +# define SYSCON_PPGPIO_P4 (1 << 4) /* Bit 4: GPIO Port E Present */ +# define SYSCON_PPGPIO_P5 (1 << 5) /* Bit 5: GPIO Port F Present */ +# define SYSCON_PPGPIO_P6 (1 << 6) /* Bit 6: GPIO Port G Present */ +# define SYSCON_PPGPIO_P7 (1 << 7) /* Bit 7: GPIO Port H Present */ +# define SYSCON_PPGPIO_P8 (1 << 8) /* Bit 8: GPIO Port J Present */ +# define SYSCON_PPGPIO_P9 (1 << 9) /* Bit 9: GPIO Port K Present */ +# define SYSCON_PPGPIO_P10 (1 << 10) /* Bit 10: GPIO Port L Present */ +# define SYSCON_PPGPIO_P11 (1 << 11) /* Bit 11: GPIO Port M Present */ +# define SYSCON_PPGPIO_P12 (1 << 12) /* Bit 12: GPIO Port N Present */ +# define SYSCON_PPGPIO_P13 (1 << 13) /* Bit 13: GPIO Port P Present */ +# define SYSCON_PPGPIO_P14 (1 << 14) /* Bit 14: GPIO Port Q Present */ + +/* uDMA Peripheral Present */ + +#define SYSCON_PPDMA_P0 (1 << 0) /* Bit 0: μDMA Module Present */ + +/* Hibernation Peripheral Present */ + +#define SYSCON_PPHIB_P0 (1 << 0) /* Bit 0: Hibernation Module Present */ + +/* UART Present */ + +#define SYSCON_PPUART(n) (1 << (n)) /* Bit n: UART Module n Present */ +# define SYSCON_PPUART_P0 (1 << 0) /* Bit 0: UART Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: UART Module 1 Present */ +# define SYSCON_PPUART_P2 (1 << 2) /* Bit 2: UART Module 2 Present */ +# define SYSCON_PPUART_P3 (1 << 3) /* Bit 3: UART Module 3 Present */ +# define SYSCON_PPUART_P4 (1 << 4) /* Bit 4: UART Module 4 Present */ +# define SYSCON_PPUART_P5 (1 << 5) /* Bit 5: UART Module 5 Present */ +# define SYSCON_PPUART_P6 (1 << 6) /* Bit 6: UART Module 6 Present */ +# define SYSCON_PPUART_P7 (1 << 7) /* Bit 7: UART Module 7 Present */ + +/* SSI Peripheral Present */ + +#define SYSCON_PPSSI(n) (1 << (n)) /* Bit n: SSI Module n Present */ +# define SYSCON_PPSSI_P0 (1 << 0) /* Bit 0: SSI Module 0 Present */ +# define SYSCON_PPSSI_P1 (1 << 1) /* Bit 1: SSI Module 1 Present */ +# define SYSCON_PPSSI_P2 (1 << 2) /* Bit 2: SSI Module 2 Present */ +# define SYSCON_PPSSI_P3 (1 << 3) /* Bit 3: SSI Module 3 Present */ + +/* I2C Peripheral Present */ + +#define SYSCON_PPI2C(n) (1 << (n)) /* Bit n: I2C Module n Present */ +# define SYSCON_PPI2C_P0 (1 << 0) /* Bit 0: I2C Module 0 Present */ +# define SYSCON_PPI2C_P1 (1 << 1) /* Bit 1: I2C Module 1 Present */ +# define SYSCON_PPI2C_P2 (1 << 2) /* Bit 2: I2C Module 2 Present */ +# define SYSCON_PPI2C_P3 (1 << 3) /* Bit 3: I2C Module 3 Present */ +# define SYSCON_PPI2C_P4 (1 << 4) /* Bit 4: I2C Module 4 Present */ +# define SYSCON_PPI2C_P5 (1 << 5) /* Bit 5: I2C Module 5 Present */ + +/* USB Peripheral Present */ + +#define SYSCON_PPUSB_P0 (1 << 0) /* Bit 0: USB Module Present */ + +/* CAN Peripheral Present */ + +#define SYSCON_PPCAN(n) (1 << (n)) /* Bit n: CAN Module n Present */ +# define SYSCON_PPCAN_P0 (1 << 0) /* Bit 0: CAN Module 0 Present */ +# define SYSCON_PPCAN_P1 (1 << 1) /* Bit 1: CAN Module 1 Present */ + +/* ADC Peripheral Present */ + +#define SYSCON_PPADC(n) (1 << (n)) /* Bit n: ADC Module n Present */ +# define SYSCON_PPADC_P0 (1 << 0) /* Bit 0: ADC Module 0 Present */ +# define SYSCON_PPADC_P1 (1 << 1) /* Bit 1: ADC Module 1 Present */ + +/* Analog Comparator Peripheral Present */ + +#define SYSCON_PPACMP_P0 (1 << 0) /* Bit 0: Analog Comparator Module Present */ + +/* Pulse Width Modulator Peripheral Present */ + +#define SYSCON_PPWM(n) (1 << (n)) /* Bit n: PWM Module n Present */ +# define SYSCON_PPWM_P0 (1 << 0) /* Bit 0: PWM Module 0 Present */ +# define SYSCON_PPWM_P1 (1 << 1) /* Bit 1: PWM Module 1 Present */ + +/* Quadrature Encoder Peripheral Present */ + +#define SYSCON_PPQEI(n) (1 << (n)) /* Bit n: QEI Module n Present */ +# define SYSCON_PPQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: QEI Module 1 Present */ + +/* EEPROM Peripheral Present */ + +#define SYSCON_PPEEPROM_P0 (1 << 0) /* Bit 0: EEPROM Module Present */ + +/* 32/64-Bit Wide Timer Peripheral Present */ + +#define SYSCON_PPWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Present */ +# define SYSCON_PPWTIMER_P0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Present */ +# define SYSCON_PPWTIMER_P1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Present */ +# define SYSCON_PPWTIMER_P2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Present */ +# define SYSCON_PPWTIMER_P3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Present */ +# define SYSCON_PPWTIMER_P4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Present */ +# define SYSCON_PPWTIMER_P5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Present */ + +/* Watchdog Timer Software Reset */ + +#define SYSCON_SRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Software Reset */ +# define SYSCON_SRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Software Reset */ +# define SYSCON_SRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Software Reset */ + +/* 16/32-Bit Timer Software Reset */ + +#define SYSCON_SRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Software Reset */ +# define SYSCON_SRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Software Reset */ + +/* GPIO Software Reset */ + +#define SYSCON_SRGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Software Reset */ +# define SYSCON_SRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Software Reset */ +# define SYSCON_SRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Software Reset */ +# define SYSCON_SRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Software Reset */ +# define SYSCON_SRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Software Reset */ +# define SYSCON_SRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Software Reset */ +# define SYSCON_SRPGIO_R5 (1 << 5) /* Bit 5: GPIO Port F Software Reset */ +# define SYSCON_SRPGIO_R6 (1 << 6) /* Bit 6: GPIO Port G Software Reset */ +# define SYSCON_SRPGIO_R7 (1 << 7) /* Bit 7: GPIO Port H Software Reset */ +# define SYSCON_SRPGIO_R8 (1 << 8) /* Bit 8: GPIO Port J Software Reset */ +# define SYSCON_SRPGIO_R9 (1 << 9) /* Bit 9: GPIO Port K Software Reset */ +# define SYSCON_SRPGIO_R10 (1 << 10) /* Bit 10: GPIO Port L Software Reset */ +# define SYSCON_SRPGIO_R11 (1 << 11) /* Bit 11: GPIO Port M Software Reset */ +# define SYSCON_SRPGIO_R12 (1 << 12) /* Bit 12: GPIO Port N Software Reset */ +# define SYSCON_SRPGIO_R13 (1 << 13) /* Bit 13: GPIO Port P Software Reset */ +# define SYSCON_SRPGIO_R14 (1 << 14) /* Bit 14: GPIO Port Q Software Reset */ + +/* uDMA Software Reset */ + +#define SYSCON_SRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Software Reset */ + +/* Hibernation Software Reset */ + +#define SYSCON_SRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Software Reset */ + +/* UART Software Reset*/ + +#define SYSCON_SRUARTR(n) (1 << (n)) /* Bit n: UART Module n Software Reset */ +# define SYSCON_SRUARTR_R0 (1 << 0) /* Bit 0: UART Module 0 Software Reset */ +# define SYSCON_SRUARTR_R1 (1 << 1) /* Bit 1: UART Module 1 Software Reset */ +# define SYSCON_SRUARTR_R2 (1 << 2) /* Bit 2: UART Module 2 Software Reset */ +# define SYSCON_SRUARTR_R3 (1 << 3) /* Bit 3: UART Module 3 Software Reset */ +# define SYSCON_SRUARTR_R4 (1 << 4) /* Bit 4: UART Module 4 Software Reset */ +# define SYSCON_SRUARTR_R5 (1 << 5) /* Bit 5: UART Module 5 Software Reset */ +# define SYSCON_SRUARTR_R6 (1 << 6) /* Bit 6: UART Module 6 Software Reset */ +# define SYSCON_SRUARTR_R7 (1 << 7) /* Bit 7: UART Module 7 Software Reset */ + +/* SSI Software Reset */ + +#define SYSCON_SRSSI(n) (1 << (n)) /* Bit n: SSI Module n Software Reset */ +# define SYSCON_SRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Software Reset */ +# define SYSCON_SRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Software Reset */ +# define SYSCON_SRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Software Reset */ +# define SYSCON_SRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Software Reset */ + +/* I2C Software Reset */ + +#define SYSCON_SRI2C(n) (1 << (n)) /* Bit n: I2C Module n Software Reset */ +# define SYSCON_SRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Software Reset */ +# define SYSCON_SRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Software Reset */ +# define SYSCON_SRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Software Reset */ +# define SYSCON_SRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Software Reset */ +# define SYSCON_SRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Software Reset */ +# define SYSCON_SRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Software Reset */ + +/* USB Software Reset */ + +#define SYSCON_SRUSB_R0 (1 << 0) /* Bit 0: USB Module Software Reset */ + +/* CAN Software Reset */ + +#define SYSCON_SRCAN(n) (1 << (n)) /* Bit n: CAN Module n Software Reset */ +# define SYSCON_SRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Software Reset */ +# define SYSCON_SRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Software Reset*/ + +/* ADC Software Reset */ + +#define SYSCON_SRADC(n) (1 << (n)) /* Bit n: ADC Module n Software Reset */ +# define SYSCON_SRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Software Reset */ +# define SYSCON_SRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Software Reset */ + +/* Analog Comparator Software Reset */ + +#define SYSCON_SRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Software Reset */ + +/* Pulse Width Modulator Software Reset */ + +#define SYSCON_SRPWM(n) (1 << (n)) /* Bit n: PWM Module n Software Reset */ +# define SYSCON_SRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Software Reset */ +# define SYSCON_SRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Software Reset */ + +/* Quadrature Encoder Interface Software Reset */ + +#define SYSCON_SRQEI(n) (1 << (n)) /* Bit n: QEI Module n Software Reset */ +# define SYSCON_SRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Software Reset */ +# define SYSCON_SRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Software Reset */ + +/* EEPROM Software Reset */ + +#define SYSCON_SREEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Software Reset */ + +/* 32/64-Bit Wide Timer Software Reset */ + +#define SYSCON_SRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Software Reset */ +# define SYSCON_SRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Software Reset */ +# define SYSCON_SRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Software Reset */ +# define SYSCON_SRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Software Reset */ +# define SYSCON_SRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Software Reset */ +# define SYSCON_SRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Software Reset */ +# define SYSCON_SRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Software Reset */ + +/* Watchdog Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Run Mode Clock Gating Control */ + +/* 16/32-Bit Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* GPIO Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCGPIO(n) (1 << (n)) /* Bit n: 16/32-Bit GPIO Port n Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R0 (1 << 0) /* Bit 0: 16/32-Bit GPIO Port A Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R1 (1 << 1) /* Bit 1: 16/32-Bit GPIO Port B Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R2 (1 << 2) /* Bit 2: 16/32-Bit GPIO Port C Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R3 (1 << 3) /* Bit 3: 16/32-Bit GPIO Port D Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R4 (1 << 4) /* Bit 4: 16/32-Bit GPIO Port E Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R5 (1 << 5) /* Bit 5: 16/32-Bit GPIO Port F Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R6 (1 << 6) /* Bit 6: 16/32-Bit GPIO Port G Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R7 (1 << 7) /* Bit 7: 16/32-Bit GPIO Port H Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R8 (1 << 8) /* Bit 8: 16/32-Bit GPIO Port J Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R9 (1 << 9) /* Bit 9: 16/32-Bit GPIO Port K Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R10 (1 << 10) /* Bit 10: 16/32-Bit GPIO Port L Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R11 (1 << 11) /* Bit 11: 16/32-Bit GPIO Port M Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R12 (1 << 12) /* Bit 12: 16/32-Bit GPIO Port N Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R13 (1 << 13) /* Bit 13: 16/32-Bit GPIO Port P Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R14 (1 << 14) /* Bit 14: 16/32-Bit GPIO Port Q Run Mode Clock Gating Control */ + +/* uDMA Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCDMA_R0 (1 << 0) /* Bit 0: μDMA Module Run Mode Clock Gating Control */ + +/* Hibernation Run Mode Clock Gating Control */ + +#define SYSCON_RCGCHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Run Mode Clock Gating Control */ + +/* UART Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCUART(n) (1 << (n)) /* Bit n: UART Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R0 (1 << 0) /* Bit 0: UART Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R1 (1 << 1) /* Bit 1: UART Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R2 (1 << 2) /* Bit 2: UART Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R3 (1 << 3) /* Bit 3: UART Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R4 (1 << 4) /* Bit 4: UART Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R5 (1 << 5) /* Bit 5: UART Module 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R6 (1 << 6) /* Bit 6: UART Module 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R7 (1 << 7) /* Bit 7: UART Module 7 Run Mode Clock Gating Control */ + +/* SSI Run Mode Clock Gating Control*/ + +#define SYSCON_RCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Run Mode Clock Gating Control */ + +/* I2C Run Mode Clock Gating Control */ + +#define SYSCON_RCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Run Mode Clock Gating Control */ + +/* USB Run Mode Clock Gating Control */ + +#define SYSCON_RCGCUSB_R0 (1 << 0) /* Bit 0: USB Module Run Mode Clock Gating Control */ + +/* CAN Run Mode Clock Gating Control */ + +#define SYSCON_RCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Run Mode Clock Gating Control */ + +/* ADC Run Mode Clock Gating Control */ + +#define SYSCON_RCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Run Mode Clock Gating Control */ + +/* Analog Comparator Run Mode Clock Gating Control */ + +#define SYSCON_RCGCACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Run Mode Clock Gating Control */ + +/* Pulse Width Modulator Run Mode Clock Gating Control */ + +#define SYSCON_RCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Run Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Run Mode Clock Gating Control */ + +#define SYSCON_RCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Run Mode Clock Gating Control */ + +/* EEPROM Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Run Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Run Mode Clock Gating Control */ + +/* Watchdog Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: Watchdog Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: Watchdog Timer 1 Sleep Mode Clock Gating Control */ + +/* 16/32-Bit Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* GPIO Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S0 (1 << 0) /* Bit 0: GPIO Port A Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S1 (1 << 1) /* Bit 1: GPIO Port B Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S2 (1 << 2) /* Bit 2: GPIO Port C Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S3 (1 << 3) /* Bit 3: GPIO Port D Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S4 (1 << 4) /* Bit 4: GPIO Port E Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S5 (1 << 5) /* Bit 5: GPIO Port F Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S6 (1 << 6) /* Bit 6: GPIO Port G Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S7 (1 << 7) /* Bit 7: GPIO Port H Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S8 (1 << 8) /* Bit 8: GPIO Port J Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S9 (1 << 9) /* Bit 9: GPIO Port K Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S10 (1 << 10) /* Bit 10: GPIO Port L Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S11 (1 << 11) /* Bit 11: GPIO Port M Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S12 (1 << 12) /* Bit 12: GPIO Port N Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S13 (1 << 13) /* Bit 13: GPIO Port P Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S14 (1 << 14) /* Bit 14: GPIO Port Q Sleep Mode Clock Gating Control */ + +/* uDMA Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCDMA_S0 (1 << 0) /* Bit 0: μDMA Module Sleep Mode Clock Gating Control */ + +/* Hibernation Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCHIB_S0 (1 << 0) /* Bit 0: Hibernation Module Sleep Mode Clock Gating Control */ + +/* UART Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUART(n) (1 << (n)) /* Bit n: UART Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S0 (1 << 0) /* Bit 0: UART Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S1 (1 << 1) /* Bit 1: UART Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S2 (1 << 2) /* Bit 2: UART Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S3 (1 << 3) /* Bit 3: UART Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S4 (1 << 4) /* Bit 4: UART Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S5 (1 << 5) /* Bit 5: UART Module 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S6 (1 << 6) /* Bit 6: UART Module 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S7 (1 << 7) /* Bit 7: UART Module 7 Sleep Mode Clock Gating Control */ + +/* SSI Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S0 (1 << 0) /* Bit 0: SSI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S1 (1 << 1) /* Bit 1: SSI Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S2 (1 << 2) /* Bit 2: SSI Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S3 (1 << 3) /* Bit 3: SSI Module 3 Sleep Mode Clock Gating Control */ + +/* I2C Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S0 (1 << 0) /* Bit 0: I2C Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S1 (1 << 1) /* Bit 1: I2C Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S2 (1 << 2) /* Bit 2: I2C Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S3 (1 << 3) /* Bit 3: I2C Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S4 (1 << 4) /* Bit 4: I2C Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S5 (1 << 5) /* Bit 5: I2C Module 5 Sleep Mode Clock Gating Control */ + +/* USB Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUSB_S0 (1 << 0) /* Bit 0: USB Module Sleep Mode Clock Gating Control */ + +/* CAN Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S0 (1 << 0) /* Bit 0: CAN Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S1 (1 << 1) /* Bit 1: CAN Module 1 Sleep Mode Clock Gating Control */ + +/* ADC Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S0 (1 << 0) /* Bit 0: ADC Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S1 (1 << 1) /* Bit 1: ADC Module 1 Sleep Mode Clock Gating Control */ + +/* Analog Comparator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCACMP_S0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Sleep Mode Clock Gating Control */ + +/* PulseWidthModulator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S0 (1 << 0) /* Bit 0: PWM Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S1 (1 << 1) /* Bit 1: PWM Module 1 Sleep Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S0 (1 << 0) /* Bit 0: QEI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S1 (1 << 1) /* Bit 1: QEI Module 1 Sleep Mode Clock Gating Control */ + +/* EEPROM Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEEPROM_S0 (1 << 0) /* Bit 0: EEPROM Module Sleep Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D0 (1 << 0) /* Bit 0: Watchdog Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D1 (1 << 1) /* Bit 1: Watchdog Timer 1 Deep-Sleep Mode Clock Gating Control */ + +/* Clock Gating Control */ + +#define SYSCON_DCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Deep-Sleep Mode Clock Gating Control */ + +/* GPIO Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D0 (1 << 0) /* Bit 0: GPIO Port A Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D1 (1 << 1) /* Bit 1: GPIO Port B Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D2 (1 << 2) /* Bit 2: GPIO Port C Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D3 (1 << 3) /* Bit 3: GPIO Port D Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D4 (1 << 4) /* Bit 4: GPIO Port E Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D5 (1 << 5) /* Bit 5: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D6 (1 << 6) /* Bit 6: GPIO Port G Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D7 (1 << 7) /* Bit 7: GPIO Port H Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D8 (1 << 8) /* Bit 8: GPIO Port J Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D9 (1 << 9) /* Bit 9: GPIO Port K Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D10 (1 << 10) /* Bit 10: GPIO Port L Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D11 (1 << 11) /* Bit 11: GPIO Port M Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D12 (1 << 12) /* Bit 12: GPIO Port N Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D13 (1 << 13) /* Bit 13: GPIO Port P Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D14 (1 << 14) /* Bit 14: GPIO Port Q Deep-Sleep Mode Clock Gating Control */ + +/* uDMA Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCDMA_D0 (1 << 0) /* Bit 0: μDMA Module Deep-Sleep Mode Clock Gating Control */ + +/* Hibernation Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCHIB_D0 (1 << 0) /* Bit 0: Hibernation Module Deep-Sleep Mode Clock Gating Control */ + +/* UART Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUART(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D6 (1 << 6) /* Bit 6: UART Module 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D7 (1 << 7) /* Bit 7: UART Module 7 Deep-Sleep Mode Clock Gating Control */ + +/* SSI Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D0 (1 << 0) /* Bit 0: SSI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D1 (1 << 1) /* Bit 1: SSI Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D2 (1 << 2) /* Bit 2: SSI Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D3 (1 << 3) /* Bit 3: SSI Module 3 Deep-Sleep Mode Clock Gating Control */ + +/* I2C Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D0 (1 << 0) /* Bit 0: I2C Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D1 (1 << 1) /* Bit 1: I2C Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D2 (1 << 2) /* Bit 2: I2C Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D3 (1 << 3) /* Bit 3: I2C Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D4 (1 << 4) /* Bit 4: I2C Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D5 (1 << 5) /* Bit 5: I2C Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* USB Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUSB_D0 (1 << 0) /* Bit 0: USB Module Deep-Sleep Mode Clock Gating Control */ + +/* CAN Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D0 (1 << 0) /* Bit 0: CAN Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D1 (1 << 1) /* Bit 1: CAN Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* ADC Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D0 (1 << 0) /* Bit 0: ADC Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D1 (1 << 1) /* Bit 1: ADC Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* Analog Comparator Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCACMP_D0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* Pulse Width Modulator Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D0 (1 << 0) /* Bit 0: PWM Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D1 (1 << 1) /* Bit 1: PWM Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* Quadrature Encoder Interface Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D0 (1 << 0) /* Bit 0: QEI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D1 (1 << 1) /* Bit 1: QEI Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* EEPROM Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEEPROM_D0 (1 << 0) /* Bit 0: EEPROM Module Deep-Sleep Mode Clock Gating Control */ + +/* 32/64-BitWide Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWTIMER(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Peripheral Ready */ + +#define SYSCON_PRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Peripheral Ready */ +# define SYSCON_PRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Peripheral Ready */ +# define SYSCON_PRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Peripheral Ready */ + +/* 16/32-Bit Timer Peripheral Ready */ + +#define SYSCON_PRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit General-Purpose Timer 5 Peripheral Ready */ + +/* GPIO Peripheral Ready */ + +#define SYSCON_PRGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Peripheral Ready */ +# define SYSCON_PRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Peripheral Ready */ +# define SYSCON_PRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Peripheral Ready */ +# define SYSCON_PRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Peripheral Ready */ +# define SYSCON_PRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Peripheral Ready */ +# define SYSCON_PRGPIO_R5 (1 << 5) /* Bit 5: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R6 (1 << 6) /* Bit 6: GPIO Port G Peripheral Ready */ +# define SYSCON_PRGPIO_R7 (1 << 7) /* Bit 7: GPIO Port H Peripheral Ready */ +# define SYSCON_PRGPIO_R8 (1 << 8) /* Bit 8: GPIO Port J Peripheral Ready */ +# define SYSCON_PRGPIO_R9 (1 << 9) /* Bit 9: GPIO Port K Peripheral Ready */ +# define SYSCON_PRGPIO_R10 (1 << 10) /* Bit 10: GPIO Port L Peripheral Ready */ +# define SYSCON_PRGPIO_R11 (1 << 11) /* Bit 11: GPIO Port M Peripheral Ready */ +# define SYSCON_PRGPIO_R12 (1 << 12) /* Bit 12: GPIO Port N Peripheral Ready */ +# define SYSCON_PRGPIO_R13 (1 << 13) /* Bit 13: GPIO Port P Peripheral Ready */ +# define SYSCON_PRGPIO_R14 (1 << 14) /* Bit 14: GPIO Port Q Peripheral Ready */ + +/* uDMA Peripheral Ready */ + +#define SYSCON_PRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Peripheral Ready */ + +/* Hibernation Peripheral Ready */ + +#define SYSCON_PRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Peripheral Ready */ + +/* UART Peripheral Ready */ + +#define SYSCON_PRUART(n) (1 << (n)) /* Bit n: UART Module n Peripheral Ready */ +# define SYSCON_PRUART_R0 (1 << 0) /* Bit 0: UART Module 0 Peripheral Ready */ +# define SYSCON_PRUART_R1 (1 << 1) /* Bit 1: UART Module 1 Peripheral Ready */ +# define SYSCON_PRUART_R2 (1 << 2) /* Bit 2: UART Module 2 Peripheral Ready */ +# define SYSCON_PRUART_R3 (1 << 3) /* Bit 3: UART Module 3 Peripheral Ready */ +# define SYSCON_PRUART_R4 (1 << 4) /* Bit 4: UART Module 4 Peripheral Ready */ +# define SYSCON_PRUART_R5 (1 << 5) /* Bit 5: UART Module 5 Peripheral Ready */ +# define SYSCON_PRUART_R6 (1 << 6) /* Bit 6: UART Module 6 Peripheral Ready */ +# define SYSCON_PRUART_R7 (1 << 7) /* Bit 7: UART Module 7 Peripheral Ready */ + +/* SSI Peripheral Ready */ + +#define SYSCON_PRSSI(n) (1 << (n)) /* Bit n: SSI Module n Peripheral Ready */ +# define SYSCON_PRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Peripheral Ready */ +# define SYSCON_PRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Peripheral Ready */ +# define SYSCON_PRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Peripheral Ready */ +# define SYSCON_PRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Peripheral Ready */ + +/* I2C Peripheral Ready */ + +#define SYSCON_PRI2C(n) (1 << (n)) /* Bit n: I2C Module n Peripheral Ready */ +# define SYSCON_PRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Peripheral Ready */ +# define SYSCON_PRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Peripheral Ready */ +# define SYSCON_PRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Peripheral Ready */ +# define SYSCON_PRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Peripheral Ready */ +# define SYSCON_PRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Peripheral Ready */ +# define SYSCON_PRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Peripheral Ready */ + +/* USB Peripheral Ready */ + +#define SYSCON_PRUSB_R0 (1 << 0) /* Bit 0: USB Module Peripheral Ready */ + +/* CAN Peripheral Ready */ + +#define SYSCON_PRCAN(n) (1 << (n)) /* Bit n: CAN Module n Peripheral Ready */ +# define SYSCON_PRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Peripheral Ready */ +# define SYSCON_PRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Peripheral Ready */ + +/* ADC Peripheral Ready */ + +#define SYSCON_PRADC(n) (1 << (n)) /* Bit n: ADC Module n Peripheral Ready */ +# define SYSCON_PRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Peripheral Ready */ +# define SYSCON_PRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Peripheral Ready */ + +/* Analog Comparator Peripheral Ready */ + +#define SYSCON_PRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Peripheral Ready */ + +/* Pulse Width Modulator Peripheral Ready */ + +#define SYSCON_PRPWM(n) (1 << (n)) /* Bit n: PWM Module n Peripheral Ready */ +# define SYSCON_PRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Peripheral Ready */ +# define SYSCON_PRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Peripheral Ready */ + +/* Quadrature Encoder Interface Peripheral Ready */ + +#define SYSCON_PRQEI(n) (1 << (n)) /* Bit n: QEI Module n Peripheral Ready */ +# define SYSCON_PRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Peripheral Ready */ +# define SYSCON_PRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Peripheral Ready */ + +/* EEPROM Peripheral Ready */ + +#define SYSCON_PREEPROM_0 (1 << 0) /* Bit 0: EEPROM Module Peripheral Ready */ + +/* 2/64-BitWide Timer Peripheral Ready */ + +#define SYSCON_PRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide General-Purpose Timer n Peripheral Ready */ +# define SYSCON_PRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide General-Purpose Timer 0 Peripheral Ready */ +# define SYSCON_PRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide General-Purpose Timer 1 Peripheral Ready */ +# define SYSCON_PRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide General-Purpose Timer 2 Peripheral Ready */ +# define SYSCON_PRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide General-Purpose Timer 3 Peripheral Ready */ +# define SYSCON_PRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide General-Purpose Timer 4 Peripheral Ready */ +# define SYSCON_PRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide General-Purpose Timer 5 Peripheral Ready */ + +/* System Control Legacy Register Bit Definitions *******************************************/ +/* Device Capabilities 0 */ + +#define SYSCON_DC0_FLASHSZ_SHIFT 0 /* Bits 15-0: FLASH Size */ +#define SYSCON_DC0_FLASHSZ_MASK (0xffff << SYSCON_DC0_FLASHSZ_SHIFT) +#define SYSCON_DC0_SRAMSZ_SHIFT 16 /* Bits 31-16: SRAM Size */ +#define SYSCON_DC0_SRAMSZ_MASK (0xffff << SYSCON_DC0_SRAMSZ_SHIFT) + +/* Device Capabilities 1 */ + +#define SYSCON_DC1_JTAG (1 << 0) /* Bit 0: JTAG Present */ +#define SYSCON_DC1_SWD (1 << 1) /* Bit 1: SWD Present */ +#define SYSCON_DC1_SWO (1 << 2) /* Bit 2: SWO Trace Port Present */ +#define SYSCON_DC1_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Present */ +#define SYSCON_DC1_PLL (1 << 4) /* Bit 4: PLL Present */ +#define SYSCON_DC1_TEMPSNS (1 << 5) /* Bit 5: Temp Sensor Present */ +#define SYSCON_DC1_HIB (1 << 6) /* Bit 6: Hibernation Module Present */ +#define SYSCON_DC1_MPU (1 << 7) /* Bit 7: MPU Present */ +#define SYSCON_DC1_MAXADC0SPD_SHIFT (8) /* Bits 9-8: Max ADC Speed */ +#define SYSCON_DC1_MAXADC0SPD_MASK (3 << SYSCON_DC1_MAXADC0SPD_SHIFT) +#define SYSCON_DC1_MAXADC1SPD_SHIFT (10) /* Bits 10-11: Max ADC Speed */ +#define SYSCON_DC1_MAXADC1SPD_MASK (3 << SYSCON_DC1_MAXADC1SPD_SHIFT) +#define SYSCON_DC1_MINSYSDIV_SHIFT 12 /* Bits 12-15: System Clock Divider Minimum */ +#define SYSCON_DC1_MINSYSDIV_MASK (15 << SYSCON_DC1_MINSYSDIV_SHIFT) +#define SYSCON_DC1_ADC0 (1 << 16) /* Bit 16: ADC0 Module Present */ +#define SYSCON_DC1_ADC1 (1 << 17) /* Bit 17: ADC1 Module Present */ +#define SYSCON_DC1_PWM0 (1 << 20) /* Bit 20: PWM0 Module Present */ +#define SYSCON_DC1_PWM1 (1 << 21) /* Bit 21: PWM1 Module Present */ +#define SYSCON_DC1_CAN0 (1 << 24) /* Bit 24: CAN0 Module Present */ +#define SYSCON_DC1_CAN1 (1 << 25) /* Bit 25: CAN1 Module Present */ +#define SYSCON_DC1_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Present */ + +/* Device Capabilities 2 */ + +#define SYSCON_DC2_UART0 (1 << 0) /* Bit 0: UART0 Module Present */ +#define SYSCON_DC2_UART1 (1 << 1) /* Bit 1: UART1 Module Present */ +#define SYSCON_DC2_UART2 (1 << 2) /* Bit 2: UART2 Module Present */ +#define SYSCON_DC2_SSI0 (1 << 4) /* Bit 4: SSI0 Module Present */ +#define SYSCON_DC2_SSI1 (1 << 5) /* Bit 5: SSI1 Module Present */ +#define SYSCON_DC2_QEI0 (1 << 8) /* Bit 8: QEI0 Module Present */ +#define SYSCON_DC2_QEI1 (1 << 9) /* Bit 9: QEI1 Module Present */ +#define SYSCON_DC2_I2C0 (1 << 12) /* Bit 12: I2C Module 0 Present */ +#define SYSCON_DC2_I2C0HS (1 << 13) /* Bit 13: I2C Module 0 Speed */ +#define SYSCON_DC2_I2C1 (1 << 14) /* Bit 14: I2C Module 1 Present */ +#define SYSCON_DC2_I2C1HS (1 << 15) /* Bit 15: I2C Module 1 Speed */ +#define SYSCON_DC2_TIMER0 (1 << 16) /* Bit 16: Timer 0 Present */ +#define SYSCON_DC2_TIMER1 (1 << 17) /* Bit 17: Timer 1 Present */ +#define SYSCON_DC2_TIMER2 (1 << 18) /* Bit 18: Timer 2 Present */ +#define SYSCON_DC2_TIMER3 (1 << 19) /* Bit 19: Timer 3 Present */ +#define SYSCON_DC2_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Present */ +#define SYSCON_DC2_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Present */ +#define SYSCON_DC2_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Present */ +#define SYSCON_DC2_I2S0 (1 << 28) /* Bit 28: I2S Module 0 Present */ +#define SYSCON_DC2_EPI0 (1 << 30) /* Bit 30: EPI Module 0 Present */ + +/* Device Capabilities 3 */ + +#define SYSCON_DC3_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define SYSCON_DC3_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define SYSCON_DC3_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define SYSCON_DC3_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define SYSCON_DC3_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define SYSCON_DC3_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define SYSCON_DC3_C0MINUS (1 << 6) /* Bit 6: C0- Pin Present */ +#define SYSCON_DC3_C0PLUS (1 << 7) /* Bit 7: C0+ Pin Present */ +#define SYSCON_DC3_C0O (1 << 8) /* Bit 8: C0o Pin Present */ +#define SYSCON_DC3_C1MINUS (1 << 9) /* Bit 9: C1- Pin Present */ +#define SYSCON_DC3_C1PLUS (1 << 10) /* Bit 10: C1+ Pin Present */ +#define SYSCON_DC3_C1O (1 << 11) /* Bit 11: C1o Pin Present */ +#define SYSCON_DC3_C2MINUS (1 << 12) /* Bit 12: C2- Pin Present */ +#define SYSCON_DC3_C2PLUS (1 << 13) /* Bit 13: C2+ Pin Present */ +#define SYSCON_DC3_C2O (1 << 14) /* Bit 14: C2o Pin Present */ +#define SYSCON_DC3_PWMFAULT (1 << 15) /* Bit 15: PWM Fault Pin Pre */ +#define SYSCON_DC3_ADC0AIN0 (1 << 16) /* Bit 16: ADC Module 0 AIN0 Pin Present */ +#define SYSCON_DC3_ADC0AIN1 (1 << 17) /* Bit 17: ADC Module 0 AIN1 Pin Present */ +#define SYSCON_DC3_ADC0AIN2 (1 << 18) /* Bit 18: ADC Module 0 AIN2 Pin Present */ +#define SYSCON_DC3_ADC0AIN3 (1 << 19) /* Bit 19: ADC Module 0 AIN3 Pin Present */ +#define SYSCON_DC3_ADC0AIN4 (1 << 20) /* Bit 20: ADC Module 0 AIN4 Pin Present */ +#define SYSCON_DC3_ADC0AIN5 (1 << 21) /* Bit 21: ADC Module 0 AIN5 Pin Present */ +#define SYSCON_DC3_ADC0AIN6 (1 << 22) /* Bit 22: ADC Module 0 AIN6 Pin Present */ +#define SYSCON_DC3_ADC0AIN7 (1 << 23) /* Bit 23: ADC Module 0 AIN7 Pin Present */ +#define SYSCON_DC3_CCP0 (1 << 24) /* Bit 24: T0CCP0 Pin Present */ +#define SYSCON_DC3_CCP1 (1 << 25) /* Bit 25: T0CCP1 Pin Present */ +#define SYSCON_DC3_CCP2 (1 << 26) /* Bit 26: T1CCP0 Pin Present */ +#define SYSCON_DC3_CCP3 (1 << 27) /* Bit 27: T1CCP1 Pin Present */ +#define SYSCON_DC3_CCP4 (1 << 28) /* Bit 28: T2CCP0 Pin Present */ +#define SYSCON_DC3_CCP5 (1 << 29) /* Bit 29: T2CCP1 Pin Present */ +#define SYSCON_DC3_32KHZ (1 << 31) /* Bit 31: 32KHz Input Clock Available */ + +/* Device Capabilities 4 */ + +#define SYSCON_DC4_GPIO(n) (1 << (n)) +#define SYSCON_DC4_GPIOA (1 << 0) /* Bit 0: GPIO Port A Present */ +#define SYSCON_DC4_GPIOB (1 << 1) /* Bit 1: GPIO Port B Present */ +#define SYSCON_DC4_GPIOC (1 << 2) /* Bit 2: GPIO Port C Present */ +#define SYSCON_DC4_GPIOD (1 << 3) /* Bit 3: GPIO Port D Present */ +#define SYSCON_DC4_GPIOE (1 << 4) /* Bit 4: GPIO Port E Present */ +#define SYSCON_DC4_GPIOF (1 << 5) /* Bit 5: GPIO Port F Present */ +#define SYSCON_DC4_GPIOG (1 << 6) /* Bit 6: GPIO Port G Present */ +#define SYSCON_DC4_GPIOH (1 << 7) /* Bit 7: GPIO Port H Present */ +#define SYSCON_DC4_GPIOJ (1 << 8) /* Bit 8: GPIO Port J Present */ + +#define SYSCON_DC4_ROM (1 << 12) /* Bit 12: Internal Code ROM Present */ +#define SYSCON_DC4_UDMA (1 << 13) /* Bit 13: Micro-DMA Module Present */ +#define SYSCON_DC4_CCP6 (1 << 14) /* Bit 14: T3CCP0 Pin Present */ +#define SYSCON_DC4_CCP7 (1 << 15) /* Bit 15: T3CCP1 Pin Present */ +#define SYSCON_DC4_PICAL (1 << 18) /* Bit 18: PIOSC Calibrate */ +#define SYSCON_DC4_E1588 (1 << 24) /* Bit 24: 1588 Capable */ +#define SYSCON_DC4_EMAC0 (1 << 28) /* Bit 28: Ethernet MAC0 Present */ +#define SYSCON_DC4_EPHY0 (1 << 30) /* Bit 30: Ethernet PHY0 Present */ + +/* Device Capabilities 5 */ + +#define TIVA_SYSCON_DC5_PWM0 (1 << 0) /* Bit 0: PWM0 Pin Present */ +#define TIVA_SYSCON_DC5_PWM1 (1 << 1) /* Bit 1: PWM1 Pin Present */ +#define TIVA_SYSCON_DC5_PWM2 (1 << 2) /* Bit 2: PWM2 Pin Present */ +#define TIVA_SYSCON_DC5_PWM3 (1 << 3) /* Bit 3: PWM3 Pin Present */ +#define TIVA_SYSCON_DC5_PWM4 (1 << 4) /* Bit 4: PWM4 Pin Present */ +#define TIVA_SYSCON_DC5_PWM5 (1 << 5) /* Bit 5: PWM5 Pin Present */ +#define TIVA_SYSCON_DC5_PWM6 (1 << 6) /* Bit 6: PWM6 Pin Present */ +#define TIVA_SYSCON_DC5_PWM7 (1 << 7) /* Bit 7: PWM7 Pin Present */ +#define TIVA_SYSCON_DC5_PWMESYNC (1 << 20) /* Bit 20: PWM Extended SYNC Active */ +#define TIVA_SYSCON_DC5_PWMEFLT (1 << 21) /* Bit 21: PWM Extended Fault Active */ +#define TIVA_SYSCON_DC5_PWMFAULT0 (1 << 24) /* Bit 24: PWM Fault 0 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT1 (1 << 25) /* Bit 25: PWM Fault 1 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT2 (1 << 26) /* Bit 26: PWM Fault 2 Pin Present */ +#define TIVA_SYSCON_DC5_PWMFAULT3 (1 << 27) /* Bit 27: PWM Fault 3 Pin Present */ + +/* Device Capabilities 6 */ + +#define TIVA_SYSCON_DC6_USB0_SHIFT (0) /* Bits 0-1: USB Module 0 Present */ +#define TIVA_SYSCON_DC6_USB0_MASK (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_NONE (1 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_DEVICE (2 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_HOST (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +# define TIVA_SYSCON_DC6_USB0_OTG (3 << TIVA_SYSCON_DC6_USB0_SHIFT) +#define TIVA_SYSCON_DC6_USB0PHY (1 << 4) /* Bit 4: USB Module 0 PHY Present */ + +/* Device Capabilities 7 */ + +#define TIVA_SYSCON_DC7_DMACH0 (1 << 0) /* Bit 0: DMA Channel 0 */ +#define TIVA_SYSCON_DC7_DMACH1 (1 << 1) /* Bit 1: DMA Channel 1 */ +#define TIVA_SYSCON_DC7_DMACH2 (1 << 2) /* Bit 2: DMA Channel 2 */ +#define TIVA_SYSCON_DC7_DMACH3 (1 << 3) /* Bit 3: DMA Channel 3 */ +#define TIVA_SYSCON_DC7_DMACH4 (1 << 4) /* Bit 4: DMA Channel 4 */ +#define TIVA_SYSCON_DC7_DMACH5 (1 << 5) /* Bit 5: DMA Channel 5 */ +#define TIVA_SYSCON_DC7_DMACH6 (1 << 6) /* Bit 6: DMA Channel 6 */ +#define TIVA_SYSCON_DC7_DMACH7 (1 << 7) /* Bit 7: DMA Channel 7 */ +#define TIVA_SYSCON_DC7_DMACH8 (1 << 8) /* Bit 8: DMA Channel 8 */ +#define TIVA_SYSCON_DC7_DMACH9 (1 << 9) /* Bit 9: DMA Channel 9 */ +#define TIVA_SYSCON_DC7_DMACH10 (1 << 10) /* Bit 10: DMA Channel 10 */ +#define TIVA_SYSCON_DC7_DMACH11 (1 << 11) /* Bit 11: DMA Channel 11 */ +#define TIVA_SYSCON_DC7_DMACH12 (1 << 12) /* Bit 12: DMA Channel 12 */ +#define TIVA_SYSCON_DC7_DMACH13 (1 << 13) /* Bit 13: DMA Channel 13 */ +#define TIVA_SYSCON_DC7_DMACH14 (1 << 14) /* Bit 14: DMA Channel 14 */ +#define TIVA_SYSCON_DC7_DMACH15 (1 << 15) /* Bit 15: DMA Channel 15 */ +#define TIVA_SYSCON_DC7_DMACH16 (1 << 16) /* Bit 16: DMA Channel 16 */ +#define TIVA_SYSCON_DC7_DMACH17 (1 << 17) /* Bit 17: DMA Channel 17 */ +#define TIVA_SYSCON_DC7_DMACH18 (1 << 18) /* Bit 18: DMA Channel 18 */ +#define TIVA_SYSCON_DC7_DMACH19 (1 << 19) /* Bit 19: DMA Channel 19 */ +#define TIVA_SYSCON_DC7_DMACH20 (1 << 20) /* Bit 20: DMA Channel 20 */ +#define TIVA_SYSCON_DC7_DMACH21 (1 << 21) /* Bit 21: DMA Channel 21 */ +#define TIVA_SYSCON_DC7_DMACH22 (1 << 22) /* Bit 22: DMA Channel 22 */ +#define TIVA_SYSCON_DC7_DMACH23 (1 << 23) /* Bit 23: DMA Channel 23 */ +#define TIVA_SYSCON_DC7_DMACH24 (1 << 24) /* Bit 24: DMA Channel 24 */ +#define TIVA_SYSCON_DC7_DMACH25 (1 << 25) /* Bit 25: DMA Channel 25 */ +#define TIVA_SYSCON_DC7_DMACH26 (1 << 26) /* Bit 26: DMA Channel 26 */ +#define TIVA_SYSCON_DC7_DMACH27 (1 << 27) /* Bit 27: DMA Channel 27 */ +#define TIVA_SYSCON_DC7_DMACH28 (1 << 28) /* Bit 28: DMA Channel 28 */ +#define TIVA_SYSCON_DC7_DMACH29 (1 << 29) /* Bit 29: DMA Channel 29 */ +#define TIVA_SYSCON_DC7_DMACH30 (1 << 30) /* Bit 30: DMA Channel 30 */ + +/* Device Capabilities 8 */ + +#define TIVA_SYSCON_DC8_ADC0AIN0 (1 << 0) /* Bit 0: ADC Module 0 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN1 (1 << 1) /* Bit 1: ADC Module 0 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN2 (1 << 2) /* Bit 2: ADC Module 0 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN3 (1 << 3) /* Bit 3: ADC Module 0 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN4 (1 << 4) /* Bit 4: ADC Module 0 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN5 (1 << 5) /* Bit 5: ADC Module 0 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN6 (1 << 6) /* Bit 6: ADC Module 0 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN7 (1 << 7) /* Bit 7: ADC Module 0 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN8 (1 << 8) /* Bit 8: ADC Module 0 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN9 (1 << 9) /* Bit 9: ADC Module 0 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN10 (1 << 10) /* Bit 10: ADC Module 0 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN11 (1 << 11) /* Bit 11: ADC Module 0 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN12 (1 << 12) /* Bit 12: ADC Module 0 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN13 (1 << 13) /* Bit 13: ADC Module 0 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN14 (1 << 14) /* Bit 14: ADC Module 0 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC0AIN15 (1 << 15) /* Bit 15: ADC Module 0 AIN15 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN0 (1 << 16) /* Bit 16: ADC Module 1 AIN0 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN1 (1 << 17) /* Bit 17: ADC Module 1 AIN1 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN2 (1 << 18) /* Bit 18: ADC Module 1 AIN2 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN3 (1 << 19) /* Bit 19: ADC Module 1 AIN3 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN4 (1 << 20) /* Bit 20: ADC Module 1 AIN4 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN5 (1 << 21) /* Bit 21: ADC Module 1 AIN5 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN6 (1 << 22) /* Bit 22: ADC Module 1 AIN6 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN7 (1 << 23) /* Bit 23: ADC Module 1 AIN7 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN8 (1 << 24) /* Bit 24: ADC Module 1 AIN8 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN9 (1 << 25) /* Bit 25: ADC Module 1 AIN9 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN10 (1 << 26) /* Bit 26: ADC Module 1 AIN10 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN11 (1 << 27) /* Bit 27: ADC Module 1 AIN11 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN12 (1 << 28) /* Bit 28: ADC Module 1 AIN12 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN13 (1 << 29) /* Bit 29: ADC Module 1 AIN13 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN14 (1 << 30) /* Bit 30: ADC Module 1 AIN14 Pin Present */ +#define TIVA_SYSCON_DC8_ADC1AIN15 (1 << 31) /* Bit 31: ADC Module 1 AIN15 Pin Present */ + +/* Software Reset Control 0 */ + +#define SYSCON_SRCR0_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset Control */ +#define SYSCON_SRCR0_HIB (1 << 6) /* Bit 6: Hibernation Module Reset Control */ +#define SYSCON_SRCR0_ADC0 (1 << 16) /* Bit 16: ADC0 Reset Control */ +#define SYSCON_SRCR0_ADC1 (1 << 17) /* Bit 17: ADC1 Reset Control */ +#define SYSCON_SRCR0_CAN0 (1 << 24) /* Bit 24: CAN0 Reset Control */ +#define SYSCON_SRCR0_CAN1 (1 << 25) /* Bit 24: CAN1 Reset Control */ +#define SYSCON_SRCR0_WDT1 (1 << 28) /* Bit 28: Watchdog Timer 1 Reset Control */ + +/* Software Reset Control 1 */ + +#define SYSCON_SRCR1_UART0 (1 << 0) /* Bit 0: UART0 Reset Control */ +#define SYSCON_SRCR1_UART1 (1 << 1) /* Bit 1: UART1 Reset Control */ +#define SYSCON_SRCR1_UART2 (1 << 2) /* Bit 2: UART2 Reset Control */ +#define SYSCON_SRCR1_SSI0 (1 << 4) /* Bit 4: SSI0 Reset Control */ +#define SYSCON_SRCR1_SSI1 (1 << 5) /* Bit 5: SSI1 Reset Control */ +#define SYSCON_SRCR1_QEI0 (1 << 8) /* Bit 8: QEI0 Reset Control */ +#define SYSCON_SRCR1_QEI1 (1 << 9) /* Bit 9: QEI1 Reset Control */ +#define SYSCON_SRCR1_I2C0 (1 << 12) /* Bit 12: I2C 0 Reset Control */ +#define SYSCON_SRCR1_I2C1 (1 << 14) /* Bit 14: I2C 1 Reset Control */ +#define SYSCON_SRCR1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Reset Control */ +#define SYSCON_SRCR1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Reset Control */ +#define SYSCON_SRCR1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Reset Control */ +#define SYSCON_SRCR1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Reset Control */ +#define SYSCON_SRCR1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Reset Control */ +#define SYSCON_SRCR1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Reset Control */ +#define SYSCON_SRCR1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Reset Control */ + +/* Software Reset Control 2 */ + +#define SYSCON_SRCR2_GPIO(n) (1 << (n)) +#define SYSCON_SRCR2_GPIOA (1 << 0) /* Bit 0: Port A Reset Control */ +#define SYSCON_SRCR2_GPIOB (1 << 1) /* Bit 1: Port B Reset Control */ +#define SYSCON_SRCR2_GPIOC (1 << 2) /* Bit 2: Port C Reset Control */ +#define SYSCON_SRCR2_GPIOD (1 << 3) /* Bit 3: Port D Reset Control */ +#define SYSCON_SRCR2_GPIOE (1 << 4) /* Bit 4: Port E Reset Control */ +#define SYSCON_SRCR2_GPIOF (1 << 5) /* Bit 5: Port F Reset Control */ +#define SYSCON_SRCR2_GPIOG (1 << 6) /* Bit 6: Port G Reset Control */ +#define SYSCON_SRCR2_GPIOH (1 << 7) /* Bit 7: Port H Reset Control */ +#define SYSCON_SRCR2_GPIOJ (1 << 8) /* Bit 8: Port J Reset Control */ +#define SYSCON_SRCR2_UDMA (1 << 13) /* Bit 13: Micro-DMA Reset Control */ +#define SYSCON_SRCR2_USB0 (1 << 16) /* Bit 16: USB0 Reset Control */ + +/* Run Mode Clock Gating Control Register 0 */ + +#define SYSCON_RCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_RCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_RCGC0_MAXADC0SPD_SHIFT (8) /* Bits 8-9: ADC0 Sample Speed */ +#define SYSCON_RCGC0_MAXADC0SPD_MASK (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_125KSPS (0 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_250KSPS (1 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_500KSPS (2 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC0_1MSPS (3 << SYSCON_RCGC0_MAXADC0SPD_SHIFT) +#define SYSCON_RCGC0_MAXADC1SPD_SHIFT (8) /* Bits 10-11: ADC1 Sample Speed */ +#define SYSCON_RCGC0_MAXADC1SPD_MASK (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_125KSPS (0 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_250KSPS (1 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_500KSPS (2 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +# define SYSCON_RCGC0_MAXADC1_1MSPS (3 << SYSCON_RCGC0_MAXADC1SPD_SHIFT) +#define SYSCON_RCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_RCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_RCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_RCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_RCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_RCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Run Mode Clock Gating Control Register 1 */ + +#define SYSCON_RCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_RCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_RCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_RCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_RCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_RCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_RCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_RCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_RCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_RCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_RCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_RCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_RCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Clock Gating */ + +/* Run Mode Clock Gating Control Register 2 */ + +#define SYSCON_RCGC2_GPIO(n) (1 << (n)) +#define SYSCON_RCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_RCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_RCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_RCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_RCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_RCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_RCGC2_GPIOG (1 << 6) /* Bit 6: Port GClock Gating Control */ +#define SYSCON_RCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_RCGC2_GPIOJ (1 << 8) /* Bit 8: Port J Clock Gating Control */ +#define SYSCON_RCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_RCGC2_USB0 (1 << 16) /* Bit 16: USB0 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_SCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_SCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_SCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_SCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_SCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_SCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_SCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_SCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_SCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_SCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_SCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_SCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_SCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_SCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_SCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_SCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_SCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_SCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_SCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_SCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_SCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 2 Clock Gating */ + +/* Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_SCGC2_GPIO(n) (1 << (n)) +#define SYSCON_SCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_SCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_SCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_SCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_SCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_SCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_SCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_SCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_SCGC2_GPIOI (1 << 8) /* Bit 8: Port I Clock Gating Control */ +#define SYSCON_SCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_SCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 0 */ + +#define SYSCON_DCGC0_WDT0 (1 << 3) /* Bit 3: WDT0 Clock Gating Control */ +#define SYSCON_DCGC0_HIB (1 << 6) /* Bit 6: HIB Clock Gating Control */ +#define SYSCON_DCGC0_ADC0 (1 << 16) /* Bit 16: ADC0 Clock Gating Control */ +#define SYSCON_DCGC0_ADC1 (1 << 17) /* Bit 17: ADC1 Clock Gating Control */ +#define SYSCON_DCGC0_PWM0 (1 << 20) /* Bit 20: PWM0 Clock Gating Control */ +#define SYSCON_DCGC0_CAN0 (1 << 24) /* Bit 24: CAN0 Clock Gating Control */ +#define SYSCON_DCGC0_CAN1 (1 << 25) /* Bit 25: CAN1 Clock Gating Control */ +#define SYSCON_DCGC0_WDT1 (1 << 28) /* Bit 28: WDT1 Clock Gating Control */ + +/* Deep Sleep Mode Clock Gating Control Register 1 */ + +#define SYSCON_DCGC1_UART0 (1 << 0) /* Bit 0: UART0 Clock Gating Control */ +#define SYSCON_DCGC1_UART1 (1 << 1) /* Bit 1: UART1 Clock Gating Control */ +#define SYSCON_DCGC1_UART2 (1 << 2) /* Bit 2: UART2 Clock Gating Control */ +#define SYSCON_DCGC1_SSI0 (1 << 4) /* Bit 4: SSI0 Clock Gating Control */ +#define SYSCON_DCGC1_SSI1 (1 << 5) /* Bit 5: SSI1 Clock Gating Control */ +#define SYSCON_DCGC1_QEI0 (1 << 8) /* Bit 8: QEI0 Clock Gating Control */ +#define SYSCON_DCGC1_QEI1 (1 << 9) /* Bit 9: QEI1 Clock Gating Control */ +#define SYSCON_DCGC1_I2C0 (1 << 12) /* Bit 12: I2C0 Clock Gating Control */ +#define SYSCON_DCGC1_I2C1 (1 << 14) /* Bit 14: I2C1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER0 (1 << 16) /* Bit 16: Timer 0 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER1 (1 << 17) /* Bit 17: Timer 1 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER2 (1 << 18) /* Bit 18: Timer 2 Clock Gating Control */ +#define SYSCON_DCGC1_TIMER3 (1 << 19) /* Bit 19: Timer 3 Clock Gating Control */ +#define SYSCON_DCGC1_COMP0 (1 << 24) /* Bit 24: Analog Comparator 0 Clock Gating */ +#define SYSCON_DCGC1_COMP1 (1 << 25) /* Bit 25: Analog Comparator 1 Clock Gating */ +#define SYSCON_DCGC1_COMP2 (1 << 26) /* Bit 26: Analog Comparator 6 Clock Gating */ + +/* Deep Sleep Mode Clock Gating Control Register 2 */ + +#define SYSCON_DCGC2_GPIO(n) (1 << (n)) +#define SYSCON_DCGC2_GPIOA (1 << 0) /* Bit 0: Port A Clock Gating Control */ +#define SYSCON_DCGC2_GPIOB (1 << 1) /* Bit 1: Port B Clock Gating Control */ +#define SYSCON_DCGC2_GPIOC (1 << 2) /* Bit 2: Port C Clock Gating Control */ +#define SYSCON_DCGC2_GPIOD (1 << 3) /* Bit 3: Port D Clock Gating Control */ +#define SYSCON_DCGC2_GPIOE (1 << 4) /* Bit 4: Port E Clock Gating Control */ +#define SYSCON_DCGC2_GPIOF (1 << 5) /* Bit 5: Port F Clock Gating Control */ +#define SYSCON_DCGC2_GPIOG (1 << 6) /* Bit 6: Port G Clock Gating Control */ +#define SYSCON_DCGC2_GPIOH (1 << 7) /* Bit 7: Port H Clock Gating Control */ +#define SYSCON_DCGC2_GPIOI (1 << 8) /* Bit 8: Port I Clock Gating Control */ +#define SYSCON_DCGC2_UDMA (1 << 13) /* Bit 13: Micro-DMA Clock Gating Control */ +#define SYSCON_DCGC2_USB0 (1 << 16) /* Bit 16: PHY0 Clock Gating Control */ + +/* Device Capabilities */ + +#define TIVA_SYSCON_DC9_ADC0DC0 (1 << 0) /* Bit 0: ADC0 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC0DC1 (1 << 1) /* Bit 1: ADC0 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC0DC2 (1 << 2) /* Bit 2: ADC0 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC0DC3 (1 << 3) /* Bit 3: ADC0 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC0DC4 (1 << 4) /* Bit 4: ADC0 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC0DC5 (1 << 5) /* Bit 5: ADC0 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC0DC6 (1 << 6) /* Bit 6: ADC0 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC0DC7 (1 << 7) /* Bit 7: ADC0 DC7 Present */ +#define TIVA_SYSCON_DC9_ADC1DC0 (1 << 16) /* Bit 16: ADC1 DC0 Present */ +#define TIVA_SYSCON_DC9_ADC1DC1 (1 << 17) /* Bit 17: ADC1 DC1 Present */ +#define TIVA_SYSCON_DC9_ADC1DC2 (1 << 18) /* Bit 18: ADC1 DC2 Present */ +#define TIVA_SYSCON_DC9_ADC1DC3 (1 << 19) /* Bit 19: ADC1 DC3 Present */ +#define TIVA_SYSCON_DC9_ADC1DC4 (1 << 20) /* Bit 20: ADC1 DC4 Present */ +#define TIVA_SYSCON_DC9_ADC1DC5 (1 << 21) /* Bit 21: ADC1 DC5 Present */ +#define TIVA_SYSCON_DC9_ADC1DC6 (1 << 22) /* Bit 22: ADC1 DC6 Present */ +#define TIVA_SYSCON_DC9_ADC1DC7 (1 << 23) /* Bit 23: ADC1 DC7 Present */ + +/* Non-Volatile Memory Information */ + +#define TIVA_SYSCON_NVMSTAT_FWB (1 << 0) /* Bit 0: 32 Word Flash Write Buffer Available */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TM4C123_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/tm4c129_syscontrol.h b/arch/arm/src/tiva/chip/tm4c129_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..5a4886ec6ccddbd8616bc30cda29bd6b2404ae19 --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c129_syscontrol.h @@ -0,0 +1,2098 @@ +/******************************************************************************************** + * arch/arm/src/tiva/chip/tm4c129_syscontrol.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C129_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C129_SYSCONTROL_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* System Control Register Offsets **********************************************************/ +/* System Control Registers (System Control Offset) */ + +#define TIVA_SYSCON_DID0_OFFSET 0x0000 /* Device Identification 0 */ +#define TIVA_SYSCON_DID1_OFFSET 0x0004 /* Device Identification 1 */ +#define TIVA_SYSCON_PTBOCTL_OFFSET 0x0038 /* Power-Temp Brown Out Control */ +#define TIVA_SYSCON_RIS_OFFSET 0x0050 /* Raw Interrupt Status */ +#define TIVA_SYSCON_IMC_OFFSET 0x0054 /* Interrupt Mask Control */ +#define TIVA_SYSCON_MISC_OFFSET 0x0058 /* Masked Interrupt Status and Clear */ +#define TIVA_SYSCON_RESC_OFFSET 0x005c /* Reset Cause */ +#define TIVA_SYSCON_PWRTC_OFFSET 0x0060 /* Power-Temperature Cause */ +#define TIVA_SYSCON_NMIC_OFFSET 0x0064 /* NMI Cause Register */ +#define TIVA_SYSCON_MOSCCTL_OFFSET 0x007c /* Main Oscillator Control */ +#define TIVA_SYSCON_RSCLKCFG_OFFSET 0x00b0 /* Run and Sleep Mode Configuration Register */ +#define TIVA_SYSCON_MEMTIM0_OFFSET 0x00c0 /* Memory Timing Parameter Register 0 */ +#define TIVA_SYSCON_ALTCLKCFG_OFFSET 0x0138 /* Alternate Clock Configuration */ +#define TIVA_SYSCON_DSCLKCFG_OFFSET 0x0144 /* Deep Sleep Clock Configuration Register */ +#define TIVA_SYSCON_DIVSCLK_OFFSET 0x0148 /* Divisor and Source Clock Configuration */ +#define TIVA_SYSCON_SYSPROP_OFFSET 0x014c /* System Properties */ +#define TIVA_SYSCON_PIOSCCAL_OFFSET 0x0150 /* Precision Internal Oscillator Calibration */ +#define TIVA_SYSCON_PIOSCSTAT_OFFSET 0x0154 /* Precision Internal Oscillator Statistics */ +#define TIVA_SYSCON_PLLFREQ0_OFFSET 0x0160 /* PLL Frequency 0 */ +#define TIVA_SYSCON_PLLFREQ1_OFFSET 0x0164 /* PLL Frequency 1 */ +#define TIVA_SYSCON_PLLSTAT_OFFSET 0x0168 /* PLL Status */ +#define TIVA_SYSCON_SLPPWRCFG_OFFSET 0x0188 /* Sleep Power Configuration */ +#define TIVA_SYSCON_DSLPPWRCFG_OFFSET 0x018c /* Deep-Sleep Power Configuration */ +#define TIVA_SYSCON_NVMSTAT_OFFSET 0x01a0 /* Non-Volatile Memory Information */ +#define TIVA_SYSCON_LDOSPCTL_OFFSET 0x01b4 /* LDO Sleep Power Control */ +#define TIVA_SYSCON_LDOSPCAL_OFFSET 0x01b8 /* LDO Sleep Power Calibration */ +#define TIVA_SYSCON_LDODPCTL_OFFSET 0x01bc /* LDO Deep-Sleep Power Control */ +#define TIVA_SYSCON_LDODPCAL_OFFSET 0x01c0 /* LDO Deep-Sleep Power Calibration */ +#define TIVA_SYSCON_SDPMST_OFFSET 0x01cc /* Sleep / Deep-Sleep Power Mode Status */ +#define TIVA_SYSCON_RESBEHAVCTL_OFFSET 0x01d8 /* Reset Behavior Control Register */ +#define TIVA_SYSCON_HSSR_OFFSET 0x01f4 /* Hardware System Service Request */ +#define TIVA_SYSCON_USBPDS_OFFSET 0x0280 /* USB Power Domain Status */ +#define TIVA_SYSCON_USBMPC_OFFSET 0x0284 /* USB Memory Power Control */ +#define TIVA_SYSCON_EMACPDS_OFFSET 0x0288 /* Ethernet MAC Power Domain Status */ +#define TIVA_SYSCON_EMACMPC_OFFSET 0x028c /* Ethernet MAC Memory Power Control */ +#define TIVA_SYSCON_LCDPDS_OFFSET 0x0290 /* LCD Power Domain Status */ +#define TIVA_SYSCON_LCDMPC_OFFSET 0x0294 /* LCD Memory Power Control */ +#define TIVA_SYSCON_CAN0PDS_OFFSET 0x0298 /* CAN 0 Power Domain Status */ +#define TIVA_SYSCON_CAN0MPC_OFFSET 0x029c /* CAN 0 Memory Power Control */ +#define TIVA_SYSCON_CAN1PDS_OFFSET 0x02a0 /* CAN 1 Power Domain Status */ +#define TIVA_SYSCON_CAN1MPC_OFFSET 0x02a4 /* CAN 1 Memory Power Control */ +#define TIVA_SYSCON_PPWD_OFFSET 0x0300 /* Watchdog Timer Peripheral Present */ +#define TIVA_SYSCON_PPTIMER_OFFSET 0x0304 /* 16/32-Bit Timer Peripheral Present */ +#define TIVA_SYSCON_PPGPIO_OFFSET 0x0308 /* GPIO Peripheral Present */ +#define TIVA_SYSCON_PPDMA_OFFSET 0x030c /* μDMA Peripheral Present */ +#define TIVA_SYSCON_PPEPI_OFFSET 0x0310 /* EPI Peripheral Present */ +#define TIVA_SYSCON_PPHIB_OFFSET 0x0314 /* Hibernation Peripheral Present */ +#define TIVA_SYSCON_PPUART_OFFSET 0x0318 /* UART Peripheral Present */ +#define TIVA_SYSCON_PPSSI_OFFSET 0x031c /* SSI Peripheral Present */ +#define TIVA_SYSCON_PPI2C_OFFSET 0x0320 /* I2C Peripheral Present */ +#define TIVA_SYSCON_PPUSB_OFFSET 0x0328 /* USB Peripheral Present */ +#define TIVA_SYSCON_PPEPHY_OFFSET 0x0330 /* Ethernet PHY Peripheral Present */ +#define TIVA_SYSCON_PPCAN_OFFSET 0x0334 /* CAN Peripheral Present */ +#define TIVA_SYSCON_PPADC_OFFSET 0x0338 /* ADC Peripheral Present */ +#define TIVA_SYSCON_PPACMP_OFFSET 0x033c /* ACMP Peripheral Present */ +#define TIVA_SYSCON_PPPWM_OFFSET 0x0340 /* PWM Peripheral Present */ +#define TIVA_SYSCON_PPQEI_OFFSET 0x0344 /* QE Interface Peripheral Present */ +#define TIVA_SYSCON_PPLPC_OFFSET 0x0348 /* Low Pin Count Interface Peripheral Present */ +#define TIVA_SYSCON_PPPECI_OFFSET 0x0350 /* Platform Environment Control Interface Peripheral Present */ +#define TIVA_SYSCON_PPFAN_OFFSET 0x0354 /* Fan Control Peripheral Present */ +#define TIVA_SYSCON_PPEEPROM_OFFSET 0x0358 /* EEPROM Peripheral Present */ +#define TIVA_SYSCON_PPWTIMER_OFFSET 0x035c /* 32/64-Bit Wide Timer Peripheral Present */ +#define TIVA_SYSCON_PPRTS_OFFSET 0x0370 /* Remote Temperature Sensor Peripheral Present */ +#define TIVA_SYSCON_PPCCM_OFFSET 0x0374 /* CRC/Crypto Modules Peripheral Present */ +#define TIVA_SYSCON_PPLCD_OFFSET 0x0390 /* LCD Peripheral Present */ +#define TIVA_SYSCON_PPOWIRE_OFFSET 0x0398 /* 1-Wire Peripheral Present */ +#define TIVA_SYSCON_PPEMAC_OFFSET 0x039c /* Ethernet MAC Peripheral Present */ +#define TIVA_SYSCON_PPPRB_OFFSET 0x03a0 /* Power Regulator Bus Peripheral Present */ +#define TIVA_SYSCON_PPHIM_OFFSET 0x03a4 /* Human Interface Master Peripheral Present */ +#define TIVA_SYSCON_SRWD_OFFSET 0x0500 /* Watchdog Timer Software Reset */ +#define TIVA_SYSCON_SRTIMER_OFFSET 0x0504 /* 16/32-Bit Timer Software Reset */ +#define TIVA_SYSCON_SRGPIO_OFFSET 0x0508 /* GPIO Software Reset */ +#define TIVA_SYSCON_SRDMA_OFFSET 0x050c /* μDMA Software Reset */ +#define TIVA_SYSCON_SREPI_OFFSET 0x0510 /* EPI Software Reset */ +#define TIVA_SYSCON_SRHIB_OFFSET 0x0514 /* Hibernation Software Reset */ +#define TIVA_SYSCON_SRUART_OFFSET 0x0518 /* UART Software Reset */ +#define TIVA_SYSCON_SRSSI_OFFSET 0x051c /* SSI Software Reset */ +#define TIVA_SYSCON_SRI2C_OFFSET 0x0520 /* I2C Software Reset */ +#define TIVA_SYSCON_SRUSB_OFFSET 0x0528 /* USB Software Reset */ +#define TIVA_SYSCON_SREPHY_OFFSET 0x0530 /* Ethernet PHY Software Reset */ +#define TIVA_SYSCON_SRCAN_OFFSET 0x0534 /* CAN Software Reset */ +#define TIVA_SYSCON_SRADC_OFFSET 0x0538 /* ADC Software Reset */ +#define TIVA_SYSCON_SRACMP_OFFSET 0x053c /* ACMP Software Reset */ +#define TIVA_SYSCON_SRPWM_OFFSET 0x0540 /* PWM Software Reset */ +#define TIVA_SYSCON_SRQEI_OFFSET 0x0544 /* QE Interface Software Reset */ +#define TIVA_SYSCON_SREEPROM_OFFSET 0x0558 /* EEPROM Software Reset */ +#define TIVA_SYSCON_SRWTIMER_OFFSET 0x055c /* 32/64-Bit Wide Timer Software Reset */ +#define TIVA_SYSCON_SRCCM_OFFSET 0x0574 /* CRC/Crypto Modules Software Reset */ +#define TIVA_SYSCON_SRLCD_OFFSET 0x0590 /* LCD Controller Software Reset */ +#define TIVA_SYSCON_SROWIRE_OFFSET 0x0598 /* 1-Wire Software Reset */ +#define TIVA_SYSCON_SREMAC_OFFSET 0x059c /* Ethernet MAC Software Reset */ +#define TIVA_SYSCON_RCGCWD_OFFSET 0x0600 /* Watchdog Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCTIMER_OFFSET 0x0604 /* 16/32-Bit Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCGPIO_OFFSET 0x0608 /* GPIO Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCDMA_OFFSET 0x060c /* μDMA Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEPI_OFFSET 0x0610 /* EPI Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCHIB_OFFSET 0x0614 /* Hibernation Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUART_OFFSET 0x0618 /* UART Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCSSI_OFFSET 0x061c /* SSI Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCI2C_OFFSET 0x0620 /* I2C Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCUSB_OFFSET 0x0628 /* USB Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEPHY_OFFSET 0x0630 /* Ethernet PHY Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCCAN_OFFSET 0x0634 /* CAN RunMode Clock Gating Control */ +#define TIVA_SYSCON_RCGCADC_OFFSET 0x0638 /* ADC Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCACMP_OFFSET 0x063c /* ACMP Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCPWM_OFFSET 0x0640 /* PWM Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCQEI_OFFSET 0x0644 /* QE Interface Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEEPROM_OFFSET 0x0658 /* EEPROM Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCWTIMER_OFFSET 0x065c /* 32/64-Bit Wide Timer Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCCCM_OFFSET 0x0674 /* CRC/CryptoModules Run Mode ClockGating Control */ +#define TIVA_SYSCON_RCGCLCD_OFFSET 0x0690 /* LCD Controller Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCOWIRE_OFFSET 0x0698 /* 1-Wire Run Mode Clock Gating Control */ +#define TIVA_SYSCON_RCGCEMAC_OFFSET 0x069c /* Ethernet MAC Run Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCWD_OFFSET 0x0700 /* Watchdog Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCTIMER_OFFSET 0x0704 /* 16/32-Bit Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCGPIO_OFFSET 0x0708 /* GPIO Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCDMA_OFFSET 0x070c /* μDMA Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEPI_OFFSET 0x0710 /* EPI Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCHIB_OFFSET 0x0714 /* Hibernation Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUART_OFFSET 0x0718 /* UART Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCSSI_OFFSET 0x071c /* SSI Sleep Mode Clock GatingControl */ +#define TIVA_SYSCON_SCGCI2C_OFFSET 0x0720 /* I2C Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCUSB_OFFSET 0x0728 /* USB Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEPHY_OFFSET 0x0730 /* Ethernet PHY Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCCAN_OFFSET 0x0734 /* CAN Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCADC_OFFSET 0x0738 /* ADC Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCACMP_OFFSET 0x073c /* ACMP Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCPWM_OFFSET 0x0740 /* PulseWidthModulator Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCQEI_OFFSET 0x0744 /* QE Interface Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEEPROM_OFFSET 0x0758 /* EEPROM Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCWTIMER_OFFSET 0x075c /* 32/64-Bit Wide Timer Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCCCM_OFFSET 0x0774 /* CRC/Crypto Modules Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCLCD_OFFSET 0x0790 /* LCD Controller Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCOWIRE_OFFSET 0x0798 /* 1-Wire Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_SCGCEMAC_OFFSET 0x079c /* Ethernet MAC Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCWD_OFFSET 0x0800 /* Watchdog Timer Deep-SleepMode Clock Gating Control */ +#define TIVA_SYSCON_DCGCTIMER_OFFSET 0x0804 /* 16/32-Bit Timer Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCGPIO_OFFSET 0x0808 /* GPIO Deep-Sleep Mode Clock */ +#define TIVA_SYSCON_DCGCDMA_OFFSET 0x080c /* μDMA Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEPI_OFFSET 0x0810 /* EPI Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCHIB_OFFSET 0x0814 /* Hibernation Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUART_OFFSET 0x0818 /* UART Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCSSI_OFFSET 0x081c /* SSI Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCI2C_OFFSET 0x0820 /* I2C Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCUSB_OFFSET 0x0828 /* USB Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEPHY_OFFSET 0x0830 /* Ethernet PHY Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCCAN_OFFSET 0x0834 /* CAN Deep-SleepMode Clock Gating Control */ +#define TIVA_SYSCON_DCGCADC_OFFSET 0x0838 /* ADC Deep-Sleep Mode ClockGating Control */ +#define TIVA_SYSCON_DCGCACMP_OFFSET 0x083c /* ACMP Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCPWM_OFFSET 0x0840 /* PWM Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCQEI_OFFSET 0x0844 /* QE Interface Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEEPROM_OFFSET 0x0858 /* EEPROM Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCWTIMER_OFFSET 0x085c /* 32/64-Bit Wide Timer Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCCCM_OFFSET 0x0874 /* CRC/Crypto Modules Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCLCD_OFFSET 0x0890 /* LCD Controller Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCOWIRE_OFFSET 0x0898 /* 1-Wire Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_DCGCEMAC_OFFSET 0x089c /* Ethernet MAC Deep-Sleep Mode Clock Gating Control */ +#define TIVA_SYSCON_PCWD_OFFSET 0x0900 /* Watchdog Timer Power Control */ +#define TIVA_SYSCON_PCTIMER_OFFSET 0x0904 /* 16/32-Bit Timer Power Control */ +#define TIVA_SYSCON_PCGPIO_OFFSET 0x0908 /* GPIO Power Control */ +#define TIVA_SYSCON_PCDMA_OFFSET 0x090c /* μDMA Power Control */ +#define TIVA_SYSCON_PCEPI_OFFSET 0x0910 /* External Peripheral Interface Power Control */ +#define TIVA_SYSCON_PCHIB_OFFSET 0x0914 /* Hibernation Power Control */ +#define TIVA_SYSCON_PCUART_OFFSET 0x0918 /* UART Power Control */ +#define TIVA_SYSCON_PCSSI_OFFSET 0x091c /* SSI Power Control */ +#define TIVA_SYSCON_PCI2C_OFFSET 0x0920 /* I2C Power Control */ +#define TIVA_SYSCON_PCUSB_OFFSET 0x0928 /* USB Power Control */ +#define TIVA_SYSCON_PCEPHY_OFFSET 0x0930 /* Ethernet PHY Power Control */ +#define TIVA_SYSCON_PCCAN_OFFSET 0x0934 /* CAN Power Control */ +#define TIVA_SYSCON_PCADC_OFFSET 0x0938 /* ADC Power Control */ +#define TIVA_SYSCON_PCACMP_OFFSET 0x093c /* ACMP Power Control */ +#define TIVA_SYSCON_PCPWM_OFFSET 0x0940 /* PWM Power Control */ +#define TIVA_SYSCON_PCQEI_OFFSET 0x0944 /* QE Interface Power Control */ +#define TIVA_SYSCON_PCEEPROM_OFFSET 0x0958 /* EEPROM Power Control */ +#define TIVA_SYSCON_PCCCM_OFFSET 0x0974 /* CRC/Crypto Modules Power Control */ +#define TIVA_SYSCON_PCLCD_OFFSET 0x0990 /* LCD Controller Power Control */ +#define TIVA_SYSCON_PCOWIRE_OFFSET 0x0998 /* 1-Wire Power Control */ +#define TIVA_SYSCON_PCEMAC_OFFSET 0x099c /* Ethernet MAC Power Control */ +#define TIVA_SYSCON_PRWD_OFFSET 0x0a00 /* Watchdog Timer Peripheral Ready */ +#define TIVA_SYSCON_PRTIMER_OFFSET 0x0a04 /* 16/32-Bit Timer Peripheral Ready */ +#define TIVA_SYSCON_PRGPIO_OFFSET 0x0a08 /* GPIO Peripheral Ready */ +#define TIVA_SYSCON_PRDMA_OFFSET 0x0a0c /* μDMA Peripheral Ready */ +#define TIVA_SYSCON_PREPI_OFFSET 0x0a10 /* EPI Peripheral Ready */ +#define TIVA_SYSCON_PRHIB_OFFSET 0x0a14 /* Hibernation Peripheral Ready */ +#define TIVA_SYSCON_PRUART_OFFSET 0x0a18 /* UART Peripheral Ready */ +#define TIVA_SYSCON_PRSSI_OFFSET 0x0a1c /* SSI Peripheral Ready */ +#define TIVA_SYSCON_PRI2C_OFFSET 0x0a20 /* I2C Peripheral Ready */ +#define TIVA_SYSCON_PRUSB_OFFSET 0x0a28 /* USB Peripheral Ready */ +#define TIVA_SYSCON_PREPHY_OFFSET 0x0a30 /* Ethernet PHY Peripheral Ready */ +#define TIVA_SYSCON_PRCAN_OFFSET 0x0a34 /* CAN Peripheral Ready */ +#define TIVA_SYSCON_PRADC_OFFSET 0x0a38 /* ADC Peripheral Ready */ +#define TIVA_SYSCON_PRACMP_OFFSET 0x0a3c /* ACMP Peripheral Ready */ +#define TIVA_SYSCON_PRPWM_OFFSET 0x0a40 /* PWM Peripheral Ready */ +#define TIVA_SYSCON_PRQEI_OFFSET 0x0a44 /* QE Interface Peripheral Ready */ +#define TIVA_SYSCON_PREEPROM_OFFSET 0x0a58 /* EEPROM Peripheral Ready */ +#define TIVA_SYSCON_PRWTIMER_OFFSET 0x0a5c /* 32/64-Bit Wide Timer Peripheral Ready */ +#define TIVA_SYSCON_PRCCM_OFFSET 0x0a74 /* CRC/Crypto Modules Peripheral Ready */ +#define TIVA_SYSCON_PRLCD_OFFSET 0x0a90 /* LCD Controller Peripheral Ready */ +#define TIVA_SYSCON_PROWIRE_OFFSET 0x0a98 /* 1-Wire Peripheral Ready */ +#define TIVA_SYSCON_PREMAC_OFFSET 0x0a9c /* Ethernet MAC Peripheral Ready */ +#define TIVA_SYSCON_UNIQUEID0_OFFSET 0x0f20 /* Unique ID 0 */ +#define TIVA_SYSCON_UNIQUEID1_OFFSET 0x0f24 /* Unique ID 1 */ +#define TIVA_SYSCON_UNIQUEID2_OFFSET 0x0f28 /* Unique ID 2 */ +#define TIVA_SYSCON_UNIQUEID3_OFFSET 0x0f2c /* Unique ID 3 */ + +/*( CCM System Control Registers (CCM Control Offset) */ + +#define TIVA_SYSCON_CCMCGREQ_OFFSET 0x0204 /* Cryptographic Modules Clock Gating Request */ + +/* System Control Register Addresses ********************************************************/ + +/* System Control Registers (System Control Offset) */ + +#define TIVA_SYSCON_DID0 (TIVA_SYSCON_BASE+TIVA_SYSCON_DID0_OFFSET) +#define TIVA_SYSCON_DID1 (TIVA_SYSCON_BASE+TIVA_SYSCON_DID1_OFFSET) +#define TIVA_SYSCON_PTBOCTL (TIVA_SYSCON_BASE+TIVA_SYSCON_PTBOCTL_OFFSET) +#define TIVA_SYSCON_RIS (TIVA_SYSCON_BASE+TIVA_SYSCON_RIS_OFFSET) +#define TIVA_SYSCON_IMC (TIVA_SYSCON_BASE+TIVA_SYSCON_IMC_OFFSET) +#define TIVA_SYSCON_MISC (TIVA_SYSCON_BASE+TIVA_SYSCON_MISC_OFFSET) +#define TIVA_SYSCON_RESC (TIVA_SYSCON_BASE+TIVA_SYSCON_RESC_OFFSET) +#define TIVA_SYSCON_PWRTC (TIVA_SYSCON_BASE+TIVA_SYSCON_PWRTC_OFFSET) +#define TIVA_SYSCON_NMIC (TIVA_SYSCON_BASE+TIVA_SYSCON_NMIC_OFFSET) +#define TIVA_SYSCON_MOSCCTL (TIVA_SYSCON_BASE+TIVA_SYSCON_MOSCCTL_OFFSET) +#define TIVA_SYSCON_RSCLKCFG (TIVA_SYSCON_BASE+TIVA_SYSCON_RSCLKCFG_OFFSET) +#define TIVA_SYSCON_MEMTIM0 (TIVA_SYSCON_BASE+TIVA_SYSCON_MEMTIM0_OFFSET) +#define TIVA_SYSCON_ALTCLKCFG (TIVA_SYSCON_BASE+TIVA_SYSCON_ALTCLKCFG_OFFSET) +#define TIVA_SYSCON_DSCLKCFG (TIVA_SYSCON_BASE+TIVA_SYSCON_DSCLKCFG_OFFSET) +#define TIVA_SYSCON_DIVSCLK (TIVA_SYSCON_BASE+TIVA_SYSCON_DIVSCLK_OFFSET) +#define TIVA_SYSCON_SYSPROP (TIVA_SYSCON_BASE+TIVA_SYSCON_SYSPROP_OFFSET) +#define TIVA_SYSCON_PIOSCCAL (TIVA_SYSCON_BASE+TIVA_SYSCON_PIOSCCAL_OFFSET) +#define TIVA_SYSCON_PIOSCSTAT (TIVA_SYSCON_BASE+TIVA_SYSCON_PIOSCSTAT_OFFSET) +#define TIVA_SYSCON_PLLFREQ0 (TIVA_SYSCON_BASE+TIVA_SYSCON_PLLFREQ0_OFFSET) +#define TIVA_SYSCON_PLLFREQ1 (TIVA_SYSCON_BASE+TIVA_SYSCON_PLLFREQ1_OFFSET) +#define TIVA_SYSCON_PLLSTAT (TIVA_SYSCON_BASE+TIVA_SYSCON_PLLSTAT_OFFSET) +#define TIVA_SYSCON_SLPPWRCFG (TIVA_SYSCON_BASE+TIVA_SYSCON_SLPPWRCFG_OFFSET) +#define TIVA_SYSCON_DSLPPWRCFG (TIVA_SYSCON_BASE+TIVA_SYSCON_DSLPPWRCFG_OFFSET) +#define TIVA_SYSCON_NVMSTAT (TIVA_SYSCON_BASE+TIVA_SYSCON_NVMSTAT_OFFSET) +#define TIVA_SYSCON_LDOSPCTL (TIVA_SYSCON_BASE+TIVA_SYSCON_LDOSPCTL_OFFSET) +#define TIVA_SYSCON_LDOSPCAL (TIVA_SYSCON_BASE+TIVA_SYSCON_LDOSPCAL_OFFSET) +#define TIVA_SYSCON_LDODPCTL (TIVA_SYSCON_BASE+TIVA_SYSCON_LDODPCTL_OFFSET) +#define TIVA_SYSCON_LDODPCAL (TIVA_SYSCON_BASE+TIVA_SYSCON_LDODPCAL_OFFSET) +#define TIVA_SYSCON_SDPMST (TIVA_SYSCON_BASE+TIVA_SYSCON_SDPMST_OFFSET) +#define TIVA_SYSCON_RESBEHAVCTL (TIVA_SYSCON_BASE+TIVA_SYSCON_RESBEHAVCTL_OFFSET) +#define TIVA_SYSCON_HSSR (TIVA_SYSCON_BASE+TIVA_SYSCON_HSSR_OFFSET) +#define TIVA_SYSCON_USBPDS (TIVA_SYSCON_BASE+TIVA_SYSCON_USBPDS_OFFSET) +#define TIVA_SYSCON_USBMPC (TIVA_SYSCON_BASE+TIVA_SYSCON_USBMPC_OFFSET) +#define TIVA_SYSCON_EMACPDS (TIVA_SYSCON_BASE+TIVA_SYSCON_EMACPDS_OFFSET) +#define TIVA_SYSCON_EMACMPC (TIVA_SYSCON_BASE+TIVA_SYSCON_EMACMPC_OFFSET) +#define TIVA_SYSCON_LCDPDS (TIVA_SYSCON_BASE+TIVA_SYSCON_LCDPDS_OFFSET) +#define TIVA_SYSCON_LCDMPC (TIVA_SYSCON_BASE+TIVA_SYSCON_LCDMPC_OFFSET) +#define TIVA_SYSCON_CAN0PDS (TIVA_SYSCON_BASE+TIVA_SYSCON_CAN0PDS_OFFSET) +#define TIVA_SYSCON_CAN0MPC (TIVA_SYSCON_BASE+TIVA_SYSCON_CAN0MPC_OFFSET) +#define TIVA_SYSCON_CAN1PDS (TIVA_SYSCON_BASE+TIVA_SYSCON_CAN1PDS_OFFSET) +#define TIVA_SYSCON_CAN1MPC (TIVA_SYSCON_BASE+TIVA_SYSCON_CAN1MPC_OFFSET) +#define TIVA_SYSCON_PPWD (TIVA_SYSCON_BASE+TIVA_SYSCON_PPWD_OFFSET) +#define TIVA_SYSCON_PPTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_PPTIMER_OFFSET) +#define TIVA_SYSCON_PPGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_PPGPIO_OFFSET) +#define TIVA_SYSCON_PPDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_PPDMA_OFFSET) +#define TIVA_SYSCON_PPEPI (TIVA_SYSCON_BASE+TIVA_SYSCON_PPEPI_OFFSET) +#define TIVA_SYSCON_PPHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_PPHIB_OFFSET) +#define TIVA_SYSCON_PPUART (TIVA_SYSCON_BASE+TIVA_SYSCON_PPUART_OFFSET) +#define TIVA_SYSCON_PPSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_PPSSI_OFFSET) +#define TIVA_SYSCON_PPI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_PPI2C_OFFSET) +#define TIVA_SYSCON_PPUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_PPUSB_OFFSET) +#define TIVA_SYSCON_PPEPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_PPEPHY_OFFSET) +#define TIVA_SYSCON_PPCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_PPCAN_OFFSET) +#define TIVA_SYSCON_PPADC (TIVA_SYSCON_BASE+TIVA_SYSCON_PPADC_OFFSET) +#define TIVA_SYSCON_PPACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_PPACMP_OFFSET) +#define TIVA_SYSCON_PPPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_PPPWM_OFFSET) +#define TIVA_SYSCON_PPQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_PPQEI_OFFSET) +#define TIVA_SYSCON_PPLPC (TIVA_SYSCON_BASE+TIVA_SYSCON_PPLPC_OFFSET) +#define TIVA_SYSCON_PPPECI (TIVA_SYSCON_BASE+TIVA_SYSCON_PPPECI_OFFSET) +#define TIVA_SYSCON_PPFAN (TIVA_SYSCON_BASE+TIVA_SYSCON_PPFAN_OFFSET) +#define TIVA_SYSCON_PPEEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_PPEEPROM_OFFSET) +#define TIVA_SYSCON_PPWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_PPWTIMER_OFFSET) +#define TIVA_SYSCON_PPRTS (TIVA_SYSCON_BASE+TIVA_SYSCON_PPRTS_OFFSET) +#define TIVA_SYSCON_PPCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_PPCCM_OFFSET) +#define TIVA_SYSCON_PPLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_PPLCD_OFFSET) +#define TIVA_SYSCON_PPOWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_PPOWIRE_OFFSET) +#define TIVA_SYSCON_PPEMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_PPEMAC_OFFSET) +#define TIVA_SYSCON_PPPRB (TIVA_SYSCON_BASE+TIVA_SYSCON_PPPRB_OFFSET) +#define TIVA_SYSCON_PPHIM (TIVA_SYSCON_BASE+TIVA_SYSCON_PPHIM_OFFSET) +#define TIVA_SYSCON_SRWD (TIVA_SYSCON_BASE+TIVA_SYSCON_SRWD_OFFSET) +#define TIVA_SYSCON_SRTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_SRTIMER_OFFSET) +#define TIVA_SYSCON_SRGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_SRGPIO_OFFSET) +#define TIVA_SYSCON_SRDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_SRDMA_OFFSET) +#define TIVA_SYSCON_SREPI (TIVA_SYSCON_BASE+TIVA_SYSCON_SREPI_OFFSET) +#define TIVA_SYSCON_SRHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_SRHIB_OFFSET) +#define TIVA_SYSCON_SRUART (TIVA_SYSCON_BASE+TIVA_SYSCON_SRUART_OFFSET) +#define TIVA_SYSCON_SRSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_SRSSI_OFFSET) +#define TIVA_SYSCON_SRI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_SRI2C_OFFSET) +#define TIVA_SYSCON_SRUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_SRUSB_OFFSET) +#define TIVA_SYSCON_SREPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_SREPHY_OFFSET) +#define TIVA_SYSCON_SRCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_SRCAN_OFFSET) +#define TIVA_SYSCON_SRADC (TIVA_SYSCON_BASE+TIVA_SYSCON_SRADC_OFFSET) +#define TIVA_SYSCON_SRACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_SRACMP_OFFSET) +#define TIVA_SYSCON_SRPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_SRPWM_OFFSET) +#define TIVA_SYSCON_SRQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_SRQEI_OFFSET) +#define TIVA_SYSCON_SREEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_SREEPROM_OFFSET) +#define TIVA_SYSCON_SRWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_SRWTIMER_OFFSET) +#define TIVA_SYSCON_SRCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_SRCCM_OFFSET) +#define TIVA_SYSCON_SRLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_SRLCD_OFFSET) +#define TIVA_SYSCON_SROWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_SROWIRE_OFFSET) +#define TIVA_SYSCON_SREMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_SREMAC_OFFSET) +#define TIVA_SYSCON_RCGCWD (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCWD_OFFSET) +#define TIVA_SYSCON_RCGCTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCTIMER_OFFSET) +#define TIVA_SYSCON_RCGCGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCGPIO_OFFSET) +#define TIVA_SYSCON_RCGCDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCDMA_OFFSET) +#define TIVA_SYSCON_RCGCEPI (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCEPI_OFFSET) +#define TIVA_SYSCON_RCGCHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCHIB_OFFSET) +#define TIVA_SYSCON_RCGCUART (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCUART_OFFSET) +#define TIVA_SYSCON_RCGCSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCSSI_OFFSET) +#define TIVA_SYSCON_RCGCI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCI2C_OFFSET) +#define TIVA_SYSCON_RCGCUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCUSB_OFFSET) +#define TIVA_SYSCON_RCGCEPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCEPHY_OFFSET) +#define TIVA_SYSCON_RCGCCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCCAN_OFFSET) +#define TIVA_SYSCON_RCGCADC (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCADC_OFFSET) +#define TIVA_SYSCON_RCGCACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCACMP_OFFSET) +#define TIVA_SYSCON_RCGCPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCPWM_OFFSET) +#define TIVA_SYSCON_RCGCQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCQEI_OFFSET) +#define TIVA_SYSCON_RCGCEEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCEEPROM_OFFSET) +#define TIVA_SYSCON_RCGCWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCWTIMER_OFFSET) +#define TIVA_SYSCON_RCGCCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCCCM_OFFSET) +#define TIVA_SYSCON_RCGCLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCLCD_OFFSET) +#define TIVA_SYSCON_RCGCOWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCOWIRE_OFFSET) +#define TIVA_SYSCON_RCGCEMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_RCGCEMAC_OFFSET) +#define TIVA_SYSCON_SCGCWD (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCWD_OFFSET) +#define TIVA_SYSCON_SCGCTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCTIMER_OFFSET) +#define TIVA_SYSCON_SCGCGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCGPIO_OFFSET) +#define TIVA_SYSCON_SCGCDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCDMA_OFFSET) +#define TIVA_SYSCON_SCGCEPI (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCEPI_OFFSET) +#define TIVA_SYSCON_SCGCHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCHIB_OFFSET) +#define TIVA_SYSCON_SCGCUART (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCUART_OFFSET) +#define TIVA_SYSCON_SCGCSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCSSI_OFFSET) +#define TIVA_SYSCON_SCGCI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCI2C_OFFSET) +#define TIVA_SYSCON_SCGCUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCUSB_OFFSET) +#define TIVA_SYSCON_SCGCEPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCEPHY_OFFSET) +#define TIVA_SYSCON_SCGCCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCCAN_OFFSET) +#define TIVA_SYSCON_SCGCADC (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCADC_OFFSET) +#define TIVA_SYSCON_SCGCACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCACMP_OFFSET) +#define TIVA_SYSCON_SCGCPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCPWM_OFFSET) +#define TIVA_SYSCON_SCGCQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCQEI_OFFSET) +#define TIVA_SYSCON_SCGCEEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCEEPROM_OFFSET) +#define TIVA_SYSCON_SCGCWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCWTIMER_OFFSET) +#define TIVA_SYSCON_SCGCCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCCCM_OFFSET) +#define TIVA_SYSCON_SCGCLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCLCD_OFFSET) +#define TIVA_SYSCON_SCGCOWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCOWIRE_OFFSET) +#define TIVA_SYSCON_SCGCEMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_SCGCEMAC_OFFSET) +#define TIVA_SYSCON_DCGCWD (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCWD_OFFSET) +#define TIVA_SYSCON_DCGCTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCTIMER_OFFSET) +#define TIVA_SYSCON_DCGCGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCGPIO_OFFSET) +#define TIVA_SYSCON_DCGCDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCDMA_OFFSET) +#define TIVA_SYSCON_DCGCEPI (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCEPI_OFFSET) +#define TIVA_SYSCON_DCGCHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCHIB_OFFSET) +#define TIVA_SYSCON_DCGCUART (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCUART_OFFSET) +#define TIVA_SYSCON_DCGCSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCSSI_OFFSET) +#define TIVA_SYSCON_DCGCI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCI2C_OFFSET) +#define TIVA_SYSCON_DCGCUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCUSB_OFFSET) +#define TIVA_SYSCON_DCGCEPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCEPHY_OFFSET) +#define TIVA_SYSCON_DCGCCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCCAN_OFFSET) +#define TIVA_SYSCON_DCGCADC (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCADC_OFFSET) +#define TIVA_SYSCON_DCGCACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCACMP_OFFSET) +#define TIVA_SYSCON_DCGCPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCPWM_OFFSET) +#define TIVA_SYSCON_DCGCQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCQEI_OFFSET) +#define TIVA_SYSCON_DCGCEEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCEEPROM_OFFSET) +#define TIVA_SYSCON_DCGCWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCWTIMER_OFFSET) +#define TIVA_SYSCON_DCGCCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCCCM_OFFSET) +#define TIVA_SYSCON_DCGCLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCLCD_OFFSET) +#define TIVA_SYSCON_DCGCOWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCOWIRE_OFFSET) +#define TIVA_SYSCON_DCGCEMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_DCGCEMAC_OFFSET) +#define TIVA_SYSCON_PCWD (TIVA_SYSCON_BASE+TIVA_SYSCON_PCWD_OFFSET) +#define TIVA_SYSCON_PCTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_PCTIMER_OFFSET) +#define TIVA_SYSCON_PCGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_PCGPIO_OFFSET) +#define TIVA_SYSCON_PCDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_PCDMA_OFFSET) +#define TIVA_SYSCON_PCEPI (TIVA_SYSCON_BASE+TIVA_SYSCON_PCEPI_OFFSET) +#define TIVA_SYSCON_PCHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_PCHIB_OFFSET) +#define TIVA_SYSCON_PCUART (TIVA_SYSCON_BASE+TIVA_SYSCON_PCUART_OFFSET) +#define TIVA_SYSCON_PCSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_PCSSI_OFFSET) +#define TIVA_SYSCON_PCI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_PCI2C_OFFSET) +#define TIVA_SYSCON_PCUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_PCUSB_OFFSET) +#define TIVA_SYSCON_PCEPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_PCEPHY_OFFSET) +#define TIVA_SYSCON_PCCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_PCCAN_OFFSET) +#define TIVA_SYSCON_PCADC (TIVA_SYSCON_BASE+TIVA_SYSCON_PCADC_OFFSET) +#define TIVA_SYSCON_PCACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_PCACMP_OFFSET) +#define TIVA_SYSCON_PCPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_PCPWM_OFFSET) +#define TIVA_SYSCON_PCQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_PCQEI_OFFSET) +#define TIVA_SYSCON_PCEEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_PCEEPROM_OFFSET) +#define TIVA_SYSCON_PCCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_PCCCM_OFFSET) +#define TIVA_SYSCON_PCLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_PCLCD_OFFSET) +#define TIVA_SYSCON_PCOWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_PCOWIRE_OFFSET) +#define TIVA_SYSCON_PCEMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_PCEMAC_OFFSET) +#define TIVA_SYSCON_PRWD (TIVA_SYSCON_BASE+TIVA_SYSCON_PRWD_OFFSET) +#define TIVA_SYSCON_PRTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_PRTIMER_OFFSET) +#define TIVA_SYSCON_PRGPIO (TIVA_SYSCON_BASE+TIVA_SYSCON_PRGPIO_OFFSET) +#define TIVA_SYSCON_PRDMA (TIVA_SYSCON_BASE+TIVA_SYSCON_PRDMA_OFFSET) +#define TIVA_SYSCON_PREPI (TIVA_SYSCON_BASE+TIVA_SYSCON_PREPI_OFFSET) +#define TIVA_SYSCON_PRHIB (TIVA_SYSCON_BASE+TIVA_SYSCON_PRHIB_OFFSET) +#define TIVA_SYSCON_PRUART (TIVA_SYSCON_BASE+TIVA_SYSCON_PRUART_OFFSET) +#define TIVA_SYSCON_PRSSI (TIVA_SYSCON_BASE+TIVA_SYSCON_PRSSI_OFFSET) +#define TIVA_SYSCON_PRI2C (TIVA_SYSCON_BASE+TIVA_SYSCON_PRI2C_OFFSET) +#define TIVA_SYSCON_PRUSB (TIVA_SYSCON_BASE+TIVA_SYSCON_PRUSB_OFFSET) +#define TIVA_SYSCON_PREPHY (TIVA_SYSCON_BASE+TIVA_SYSCON_PREPHY_OFFSET) +#define TIVA_SYSCON_PRCAN (TIVA_SYSCON_BASE+TIVA_SYSCON_PRCAN_OFFSET) +#define TIVA_SYSCON_PRADC (TIVA_SYSCON_BASE+TIVA_SYSCON_PRADC_OFFSET) +#define TIVA_SYSCON_PRACMP (TIVA_SYSCON_BASE+TIVA_SYSCON_PRACMP_OFFSET) +#define TIVA_SYSCON_PRPWM (TIVA_SYSCON_BASE+TIVA_SYSCON_PRPWM_OFFSET) +#define TIVA_SYSCON_PRQEI (TIVA_SYSCON_BASE+TIVA_SYSCON_PRQEI_OFFSET) +#define TIVA_SYSCON_PREEPROM (TIVA_SYSCON_BASE+TIVA_SYSCON_PREEPROM_OFFSET) +#define TIVA_SYSCON_PRWTIMER (TIVA_SYSCON_BASE+TIVA_SYSCON_PRWTIMER_OFFSET) +#define TIVA_SYSCON_PRCCM (TIVA_SYSCON_BASE+TIVA_SYSCON_PRCCM_OFFSET) +#define TIVA_SYSCON_PRLCD (TIVA_SYSCON_BASE+TIVA_SYSCON_PRLCD_OFFSET) +#define TIVA_SYSCON_PROWIRE (TIVA_SYSCON_BASE+TIVA_SYSCON_PROWIRE_OFFSET) +#define TIVA_SYSCON_PREMAC (TIVA_SYSCON_BASE+TIVA_SYSCON_PREMAC_OFFSET) +#define TIVA_SYSCON_UNIQUEID0 (TIVA_SYSCON_BASE+TIVA_SYSCON_UNIQUEID0_OFFSET) +#define TIVA_SYSCON_UNIQUEID1 (TIVA_SYSCON_BASE+TIVA_SYSCON_UNIQUEID1_OFFSET) +#define TIVA_SYSCON_UNIQUEID2 (TIVA_SYSCON_BASE+TIVA_SYSCON_UNIQUEID2_OFFSET) +#define TIVA_SYSCON_UNIQUEID3 (TIVA_SYSCON_BASE+TIVA_SYSCON_UNIQUEID3_OFFSET) + +/* CCM System Control Registers (CCM Control Offset) */ + +#define TIVA_SYSCON_CCMCGREQ (TIVA_CCM_BASE+TIVA_SYSCON_CCMCGREQ_OFFSET) + +/* System Control Register Bit Definitions **************************************************/ +/* System Control Registers (System Control Offset) */ + +/* Device Identification 0 */ + +#define SYSCON_DID0_MINOR_SHIFT 0 /* Bits 0-7: Minor Revision of the device */ +#define SYSCON_DID0_MINOR_MASK (0xff << SYSCON_DID0_MINOR_SHIFT) +# define SYSCON_DID0_MIN_0 (0 << SYSCON_DID0_MINOR_SHIFT) /* Initial device or revision */ +# define SYSCON_DID0_MIN_1 (1 << SYSCON_DID0_MINOR_SHIFT) /* First metal layer change */ +# define SYSCON_DID0_MIN_2 (2 << SYSCON_DID0_MINOR_SHIFT) /* Second metal layer change */ +#define SYSCON_DID0_MAJOR_SHIFT 8 /* Bits 8-15: Major Revision of the device */ +#define SYSCON_DID0_MAJOR_MASK (0xff << SYSCON_DID0_MAJOR_SHIFT) +# define SYSCON_DID0_MAJ_REVA (0 << SYSCON_DID0_MAJOR_SHIFT) /* Revision A */ +# define SYSCON_DID0_MAJ_REVB (1 << SYSCON_DID0_MAJOR_SHIFT) /* Revision B */ +# define SYSCON_DID0_MAJ_REVC (2 << SYSCON_DID0_MAJOR_SHIFT) /* Revision C */ +#define SYSCON_DID0_CLASS_SHIFT 16 /* Bits 16-23: Device Class */ +#define SYSCON_DID0_CLASS_MASK (0xff << SYSCON_DID0_CLASS_SHIFT) +# define SYSCON_DID0_CLASS_TM4C123 (5 << SYSCON_DID0_CLASS_SHIFT) /* Tiva TM4C123x and TM4E123x */ +# define SYSCON_DID0_CLASS_TM4C129 (10 << SYSCON_DID0_CLASS_SHIFT) /* Tiva TM4C129-class */ +#define SYSCON_DID0_VER_SHIFT 28 /* Bits 28-30: DID0 Version */ +#define SYSCON_DID0_VER_MASK (7 << SYSCON_DID0_VER_SHIFT) +# define SYSCON_DID0_VER_1 (1 << SYSCON_DID0_VER_SHIFT) /* Second version of DID0 format */ + +/* Device Identification 1 */ + +#define SYSCON_DID1_QUAL_SHIFT 0 /* Bits 1-0: Qualification Status */ +#define SYSCON_DID1_QUAL_MASK (3 << SYSCON_DID1_QUAL_SHIFT) +# define SYSCON_DID1_QUAL_ES (0 << SYSCON_DID1_QUAL_SHIFT) /* Engineering Sample */ +# define SYSCON_DID1_QUAL_PP (1 << SYSCON_DID1_QUAL_SHIFT) /* Pilot Production */ +# define SYSCON_DID1_QUAL_FQ (2 << SYSCON_DID1_QUAL_SHIFT) /* Fully Qualified */ +#define SYSCON_DID1_ROHS (1 << 2) /* Bit 2: RoHS-Compliance */ +#define SYSCON_DID1_PKG_SHIFT 3 /* Bits 3-4: Package Type */ +#define SYSCON_DID1_PKG_MASK (3 << SYSCON_DID1_PKG_SHIFT) +# define SYSCON_DID1_PKG_QFP (1 << SYSCON_DID1_PKG_SHIFT) /* QFP package */ +# define SYSCON_DID1_PKG_BGA (2 << SYSCON_DID1_PKG_SHIFT) /* BGA package */ +#define SYSCON_DID1_TEMP_SHIFT 5 /* Bits 5-7: Temperature Range */ +#define SYSCON_DID1_TEMP_MASK (7 << SYSCON_DID1_TEMP_SHIFT) +# define SYSCON_DID1_TEMP_C (0 << SYSCON_DID1_TEMP_SHIFT) /* Commercial temperature */ +# define SYSCON_DID1_TEMP_I (1 << SYSCON_DID1_TEMP_SHIFT) /* Industrial temperature */ +# define SYSCON_DID1_TEMP_E (2 << SYSCON_DID1_TEMP_SHIFT) /* Extended temperature */ +# define SYSCON_DID1_TEMP_IE (3 << SYSCON_DID1_TEMP_SHIFT) /* Industrial and extended */ +#define SYSCON_DID1_PINCOUNT_SHIFT 13 /* Bits 13-15: Package Pin Count */ +#define SYSCON_DID1_PINCOUNT_MASK (7 << SYSCON_DID1_PINCOUNT_SHIFT) +# define SYSCON_DID1_PINCNT_100 (2 << SYSCON_DID1_PINCOUNT_SHIFT) /* 100-pin LQFP */ +# define SYSCON_DID1_PINCNT_64 (3 << SYSCON_DID1_PINCOUNT_SHIFT) /* 64-pin LQFP */ +# define SYSCON_DID1_PINCNT_144 (4 << SYSCON_DID1_PINCOUNT_SHIFT) /* 144-pin LQFP */ +# define SYSCON_DID1_PINCNT_157 (5 << SYSCON_DID1_PINCOUNT_SHIFT) /* 157-pin BGA */ +# define SYSCON_DID1_PINCNT_128 (6 << SYSCON_DID1_PINCOUNT_SHIFT) /* 128-pin TQFP */ +# define SYSCON_DID1_PINCNT_1212 (7 << SYSCON_DID1_PINCOUNT_SHIFT) /* 212-pin BGA */ +#define SYSCON_DID1_PARTNO_SHIFT 16 /* Bits 16-23: Part Number */ +#define SYSCON_DID1_PARTNO_MASK (0xff << SYSCON_DID1_PARTNO_SHIFT) +# define SYSCON_DID1_TM4C1294NCPDT (31 << SYSCON_DID1_PARTNO_SHIFT) /* TM4C1294NCPDT */ +# define SYSCON_DID1_TM4C129XNCZAD (50 << SYSCON_DID1_PARTNO_SHIFT) /* TM4C129XNCZAD */ +#define SYSCON_DID1_FAM_SHIFT 24 /* Bits 24-27: Family */ +#define SYSCON_DID1_FAM_MASK (15 << SYSCON_DID1_FAM_SHIFT) +# define SYSCON_DID1_FAM_TIVA (0 << SYSCON_DID1_FAM_SHIFT) /* Tiva C family */ +#define SYSCON_DID1_VER_SHIFT 28 /* Bits 28-31: DID1 Version */ +#define SYSCON_DID1_VER_MASK (15 << SYSCON_DID1_VER_SHIFT) + #define SYSCON_DID1_VER_1 (1 << SYSCON_DID1_VER_SHIFT) /* Second version of DID1 format */ + +/* Power-Temp Brown Out Control */ + +#define SYSCON_PTBOCTL_VDD_UBOR_SHIFT (0) /* Bits 0-1: VDD (VDDS) under BOR Event Action */ +#define SYSCON_PTBOCTL_VDD_UBOR_MASK (3 << SYSCON_PTBOCTL_VDD_UBOR_SHIFT) +# define SYSCON_PTBOCTL_VDD_UBOR_NONE (0 << SYSCON_PTBOCTL_VDD_UBOR_SHIFT) /* No Action */ +# define SYSCON_PTBOCTL_VDD_UBOR_SYSINT (1 << SYSCON_PTBOCTL_VDD_UBOR_SHIFT) /* System control interrupt */ +# define SYSCON_PTBOCTL_VDD_UBOR_NMI (2 << SYSCON_PTBOCTL_VDD_UBOR_SHIFT) /* NMI */ +# define SYSCON_PTBOCTL_VDD_UBOR_RST (3 << SYSCON_PTBOCTL_VDD_UBOR_SHIFT) /* Reset */ +#define SYSCON_PTBOCTL_VDDA_UBOR_SHIFT (8) /* Bits 8-9: VDDA under BOR Event Action */ +#define SYSCON_PTBOCTL_VDDA_UBOR_MASK (3 << SYSCON_PTBOCTL_VDDA_UBOR_SHIFT) +# define SYSCON_PTBOCTL_VDDA_UBOR_NONE (0 << SYSCON_PTBOCTL_VDDA_UBOR_SHIFT) /* No Action */ +# define SYSCON_PTBOCTL_VDDA_UBOR_SYSINT (1 << SYSCON_PTBOCTL_VDDA_UBOR_SHIFT) /* System control interrupt */ +# define SYSCON_PTBOCTL_VDDA_UBOR_NMI (2 << SYSCON_PTBOCTL_VDDA_UBOR_SHIFT) /* NMI */ +# define SYSCON_PTBOCTL_VDDA_UBOR_RST (3 << SYSCON_PTBOCTL_VDDA_UBOR_SHIFT) /* Reset */ + +/* Raw Interrupt Status */ + +#define SYSCON_RIS_BOR1RIS (1 << 1) /* Bit 1: VDD under BOR1 Raw Interrupt Status */ +#define SYSCON_RIS_BORRIS (1 << 1) /* Bit 1: Brown-Out Reset Raw Interrupt Status */ +#define SYSCON_RIS_MOFRIS (1 << 3) /* Bit 3: Main Oscillator Failure Raw Interrupt Status */ +#define SYSCON_RIS_PLLLRIS (1 << 6) /* Bit 6: PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_USBPLLLRIS (1 << 7) /* Bit 7: USB PLL Lock Raw Interrupt Status */ +#define SYSCON_RIS_MOSCPUPRIS (1 << 8) /* Bit 8: MOSC Power Up Raw Interrupt Status */ +#define SYSCON_RIS_VDDARIS (1 << 10) /* Bit 10: VDDA Power OK Event Raw Interrupt Status */ +#define SYSCON_RIS_BOR0RIS (1 << 11) /* Bit 11: VDD under BOR0 Raw Interrupt Status */ + +/* Interrupt Mask Control */ + +#define SYSCON_IMC_BOR1IM (1 << 1) /* Bit 1: VDD under BOR1 Interrupt Mask */ +#define SYSCON_IMC_BORIM (1 << 1) /* Bit 1: Brown-Out Reset Interrupt Mask */ +#define SYSCON_IMC_MOFIM (1 << 3) /* Bit 3: Main Oscillator Failure Interrupt Mask */ +#define SYSCON_IMC_PLLLIM (1 << 6) /* Bit 6: PLL Lock Interrupt Mask */ +#define SYSCON_IMC_USBPLLLIM (1 << 7) /* Bit 7: USB PLL Lock Interrupt Mask */ +#define SYSCON_IMC_MOSCPUPIM (1 << 8) /* Bit 8: MOSC Power Up Interrupt Mask */ +#define SYSCON_IMC_VDDAIM (1 << 10) /* Bit 10: VDDA Power OK Interrupt Mask */ +#define SYSCON_IMC_BOR0IM (1 << 11) /* Bit 11: VDD under BOR0 Interrupt Mask */ + +/* Masked Interrupt Status and Clear */ + +#define SYSCON_MISC_BOR1MIS (1 << 1) /* Bit 1: VDD under BOR1 Masked Interrupt Status */ +#define SYSCON_MISC_BORMIS (1 << 1) /* Bit 1: BOR Masked Interrupt Status */ +#define SYSCON_MISC_MOFMIS (1 << 3) /* Bit 3: Main Oscillator Failure Masked Interrupt Status */ +#define SYSCON_MISC_PLLLMIS (1 << 6) /* Bit 6: PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_USBPLLLMIS (1 << 7) /* Bit 7: USB PLL Lock Masked Interrupt Status */ +#define SYSCON_MISC_MOSCPUPMIS (1 << 8) /* Bit 8: MOSC Power Up Masked Interrupt Status */ +#define SYSCON_MISC_VDDAMIS (1 << 10) /* Bit 10: VDDA Power OK Masked Interrupt Status */ +#define SYSCON_MISC_BOR0MIS (1 << 11) /* Bit 11: VDD under BOR0 Masked Interrupt Status */ + +/* Reset Cause */ + +#define SYSCON_RESC_EXT (1 << 0) /* Bit 0: External Reset */ +#define SYSCON_RESC_POR (1 << 1) /* Bit 1: Power-On Reset */ +#define SYSCON_RESC_BOR (1 << 2) /* Bit 2: Brown-Out Reset */ +#define SYSCON_RESC_WDT0 (1 << 3) /* Bit 3: Watchdog Timer 0 Reset */ +#define SYSCON_RESC_SW (1 << 4) /* Bit 4: Software Reset */ +#define SYSCON_RESC_WDT1 (1 << 5) /* Bit 5: Watchdog Timer 1 Reset */ +#define SYSCON_RESC_HIB (1 << 6) /* Bit 6: HIB Reset */ +#define SYSCON_RESC_HSSR (1 << 12) /* Bit 12: HSSR Reset */ +#define SYSCON_RESC_MOSCFAIL (1 << 16) /* Bit 16: MOSC Failure Reset */ + +/* Power-Temperature Cause */ + +#define SYSCON_PWRTC_VDD_UBOR (1 << 0) /* Bit 0: VDD Under BOR Status */ +#define SYSCON_PWRTC_VDDA_UBOR (1 << 4) /* Bit 4: VDDA Under BOR Status */ + +/* NMI Cause Register */ + +#define SYSCON_NMIC_EXTERNAL (1 << 0) /* Bit 0: External Pin NMI */ +#define SYSCON_NMIC_POWER (1 << 2) /* Bit 2: Power/Brown Out Event NMI */ +#define SYSCON_NMIC_WDT0 (1 << 3) /* Bit 3: Watch Dog Timer (WDT) 0 NMI */ +#define SYSCON_NMIC_WDT1 (1 << 5) /* Bit 5: Watch Dog Timer (WDT) 1 NMI */ +#define SYSCON_NMIC_TAMPER (1 << 9) /* Bit 9: Tamper Event NMI */ +#define SYSCON_NMIC_MOSCFAIL (1 << 16) /* Bit 16: MOSC Failure NMI */ + +/* Main Oscillator Control */ + +#define SYSCON_MOSCCTL_CVAL (1 << 0) /* Bit 0: Clock Validation for MOSC */ +#define SYSCON_MOSCCTL_MOSCIM (1 << 1) /* Bit 1: MOSC Failure Action */ +#define SYSCON_MOSCCTL_NOXTAL (1 << 2) /* Bit 2: No Crystal Connected */ +#define SYSCON_MOSCCTL_PWRDN (1 << 3) /* Bit 3: Power Down */ +#define SYSCON_MOSCCTL_OSCRNG (1 << 4) /* Bit 4: Oscillator Range */ + +/* Run and Sleep Mode Configuration Register */ + +#define SYSCON_RSCLKCFG_PSYSDIV_SHIFT (0) /* Bits 0-9:PLL System Clock Divisor */ +#define SYSCON_RSCLKCFG_PSYSDIV_MASK (0x3ff << SYSCON_RSCLKCFG_PSYSDIV_SHIFT) +# define SYSCON_RSCLKCFG_PSYSDIV(n) ((uint32_t)(n) << SYSCON_RSCLKCFG_PSYSDIV_SHIFT) +#define SYSCON_RSCLKCFG_OSYSDIV_SHIFT (10) /* Bits 10-19: Oscillator System Clock Divisor */ +#define SYSCON_RSCLKCFG_OSYSDIV_MASK (0x3ff << SYSCON_RSCLKCFG_OSYSDIV_SHIFT) +# define SYSCON_RSCLKCFG_OSYSDIV(n) ((uint32_t)(n) << SYSCON_RSCLKCFG_OSYSDIV_SHIFT) +#define SYSCON_RSCLKCFG_OSCSRC_SHIFT (20) /* Bits 20-23: Oscillator Source */ +#define SYSCON_RSCLKCFG_OSCSRC_MASK (15 << SYSCON_RSCLKCFG_OSCSRC_SHIFT) +# define SYSCON_RSCLKCFG_OSCSRC_PIOSC (0 << SYSCON_RSCLKCFG_OSCSRC_SHIFT) /* PIOSC is source */ +# define SYSCON_RSCLKCFG_OSCSRC_LFIOSC (1 << SYSCON_RSCLKCFG_OSCSRC_SHIFT) /* LFIOSC is source */ +# define SYSCON_RSCLKCFG_OSCSRC_MOSC (3 << SYSCON_RSCLKCFG_OSCSRC_SHIFT) /* MOSC is source */ +# define SYSCON_RSCLKCFG_OSCSRC_RTC (4 << SYSCON_RSCLKCFG_OSCSRC_SHIFT) /* RTCOSC is source */ +#define SYSCON_RSCLKCFG_PLLSRC_SHIFT (24) /* Bits 24-27: PLL Source */ +#define SYSCON_RSCLKCFG_PLLSRC_MASK (15 << SYSCON_RSCLKCFG_PLLSRC_SHIFT) +# define SYSCON_RSCLKCFG_PLLSRC_PIOSC (0 << SYSCON_RSCLKCFG_PLLSRC_SHIFT) /* PIOSC is clock source */ +# define SYSCON_RSCLKCFG_PLLSRC_MOSC (3 << SYSCON_RSCLKCFG_PLLSRC_SHIFT) /* MOSC is the clock source */ +#define SYSCON_RSCLKCFG_USEPLL (1 << 28) /* Bit 28: Use PLL */ +#define SYSCON_RSCLKCFG_ACG (1 << 29) /* Bit 29: Auto Clock Gating */ +#define SYSCON_RSCLKCFG_NEWFREQ (1 << 30) /* Bit 30: New PLLFREQ Accept */ +#define SYSCON_RSCLKCFG_MEMTIMU (1 << 31) /* Bit 31: Memory Timing Register Update */ + +/* Memory Timing Parameter Register 0 */ + +#define SYSCON_MEMTIM0_FWS_SHIFT (0) /* Bits 0-3: Flash Wait State */ +#define SYSCON_MEMTIM0_FWS_MASK (15 << SYSCON_MEMTIM0_FWS_SHIFT) +# define SYSCON_MEMTIM0_FWS(n) ((uint32_t)(n) << SYSCON_MEMTIM0_FWS_SHIFT) +#define SYSCON_MEMTIM0_FBCE (1 << 5) /* Bit 5: Flash Bank Clock Edge */ +#define SYSCON_MEMTIM0_FBCHT_SHIFT (6) /* Bits 6-9: Flash Bank Clock High Time */ +#define SYSCON_MEMTIM0_FBCHT_MASK (15 << SYSCON_MEMTIM0_FBCHT_SHIFT) +# define SYSCON_MEMTIM0_FBCHT_0p5 (0 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 1/2 system clock period */ +# define SYSCON_MEMTIM0_FBCHT_1 (1 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 1 system clock period */ +# define SYSCON_MEMTIM0_FBCHT_1p5 (2 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 1.5 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_2 (3 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 2 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_2p5 (4 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 2.5 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_3 (5 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 3 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_3p5 (6 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 3.5 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_4 (7 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 4 system clock periods */ +# define SYSCON_MEMTIM0_FBCHT_4p5 (8 << SYSCON_MEMTIM0_FBCHT_SHIFT) /* 4.5 system clock periods */ +#define SYSCON_MEMTIM0_EWS_SHIFT (16) /* Bits 16-19: EEPROM Wait States */ +#define SYSCON_MEMTIM0_EWS_MASK (15 << SYSCON_MEMTIM0_EWS_SHIFT) +# define SYSCON_MEMTIM0_EWS(n) ((uint32_t)(n) << SYSCON_MEMTIM0_EWS_SHIFT) +#define SYSCON_MEMTIM0_EBCE (1 << 21) /* Bit 21: EEPROM Bank Clock Edge */ +#define SYSCON_MEMTIM0_EBCHT_SHIFT (22) /* Bits 22-25: EEPROM Clock High Time */ +#define SYSCON_MEMTIM0_EBCHT_MASK (15 << SYSCON_MEMTIM0_EBCHT_SHIFT) +# define SYSCON_MEMTIM0_EBCHT_0p5 (0 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 1/2 system clock period */ +# define SYSCON_MEMTIM0_EBCHT_1 (1 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 1 system clock period */ +# define SYSCON_MEMTIM0_EBCHT_1p5 (2 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 1.5 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_2 (3 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 2 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_2p5 (4 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 2.5 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_3 (5 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 3 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_3p5 (6 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 3.5 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_4 (7 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 4 system clock periods */ +# define SYSCON_MEMTIM0_EBCHT_4p5 (8 << SYSCON_MEMTIM0_EBCHT_SHIFT) /* 4.5 system clock periods */ + +#define SYSCON_MEMTIM0_MB1 ((1 << 4) | (1 << 20)) /* Must be one */ + +/* Alternate Clock Configuration */ + +#define SYSCON_ALTCLKCFG_ALTCLK_SHIFT (0) /* Bits 0-3: Alternate Clock Source */ +#define SYSCON_ALTCLKCFG_ALTCLK_MASK (15 << SYSCON_ALTCLKCFG_ALTCLK_SHIFT) +# define SYSCON_ALTCLKCFG_ALTCLK_PIOSC (0 << SYSCON_ALTCLKCFG_ALTCLK_SHIFT) /* PIOSC */ +# define SYSCON_ALTCLKCFG_ALTCLK_RTCOSC (3 << SYSCON_ALTCLKCFG_ALTCLK_SHIFT) /* RTCOSC */ +# define SYSCON_ALTCLKCFG_ALTCLK_LFIOSC (4 << SYSCON_ALTCLKCFG_ALTCLK_SHIFT) /* LFIOSC */ + +/* Deep Sleep Clock Configuration Register */ + +#define SYSCON_DSCLKCFG_DSSYSDIV_SHIFT (0) /* Bits 0-9: Deep Sleep Clock Divisor */ +#define SYSCON_DSCLKCFG_DSSYSDIV_MASK (0x3ff << SYSCON_DSCLKCFG_DSSYSDIV_SHIFT) +# define SYSCON_DSCLKCFG_DSSYSDIV(n) ((uint32_t)(n) << SYSCON_DSCLKCFG_DSSYSDIV_SHIFT) +#define SYSCON_DSCLKCFG_DSOSCSRC_SHIFT (20) /* Bits 20-23: Deep Sleep Oscillator Source */ +#define SYSCON_DSCLKCFG_DSOSCSRC_MASK (15 << SYSCON_DSCLKCFG_DSOSCSRC_SHIFT) +# define SYSCON_DSCLKCFG_DSOSCSRC_PIOSC (0 << SYSCON_DSCLKCFG_DSOSCSRC_SHIFT) /* PIOSC */ +# define SYSCON_DSCLKCFG_DSOSCSRC_LFIOSC (2 << SYSCON_DSCLKCFG_DSOSCSRC_SHIFT) /* LFIOSC */ +# define SYSCON_DSCLKCFG_DSOSCSRC_MOSC (3 << SYSCON_DSCLKCFG_DSOSCSRC_SHIFT) /* MOSC */ +# define SYSCON_DSCLKCFG_DSOSCSRC_RTC (4 << SYSCON_DSCLKCFG_DSOSCSRC_SHIFT) /* RTCOSC */ +#define SYSCON_DSCLKCFG_MOSCDPD (1 << 30) /* Bit 30: MOSC Disable Power Down */ +#define SYSCON_DSCLKCFG_PIOSCPD (1 << 31) /* Bit 31: PIOSC Power Down */ + +/* Divisor and Source Clock Configuration */ + +#define SYSCON_DIVSCLK_DIV_SHIFT (0) /* Bits 0-7: Divisor Value */ +#define SYSCON_DIVSCLK_DIV_MASK (0xff << SYSCON_DIVSCLK_DIV_SHIFT) +# define SYSCON_DIVSCLK_DIV(n) ((uint32_t)(n) << SYSCON_DIVSCLK_DIV_SHIFT) +#define SYSCON_DIVSCLK_SRC_SHIFT (16) /* Bits 16-17: Clock Source */ +#define SYSCON_DIVSCLK_SRC_MASK (3 << SYSCON_DIVSCLK_SRC_SHIFT) +# define SYSCON_DIVSCLK_SRC_SYSCLK (0 << SYSCON_DIVSCLK_SRC_SHIFT) /* System Clock */ +# define SYSCON_DIVSCLK_SRC_PIOSC (1 << SYSCON_DIVSCLK_SRC_SHIFT) /* PIOSC */ +# define SYSCON_DIVSCLK_SRC_MOSC (2 << SYSCON_DIVSCLK_SRC_SHIFT) /* MOSC */ +#define SYSCON_DIVSCLK_EN (1 << 31) /* Bit31: DIVSCLK Enable */ + +/* System Properties */ + +#define SYSCON_SYSPROP_FPU (1 << 0) /* Bit 0: FPU Present */ +#define SYSCON_SYSPROP_LDOSEQ (1 << 5) /* Bit 5: Automatic LDO Sequence Control Present */ +#define SYSCON_SYSPROP_FLASHLPM (1 << 8) /* Bit 8: Flash Memory Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMLPM (1 << 10) /* Bit 10: SRAM Sleep/Deep-Sleep Low Power Mode Present */ +#define SYSCON_SYSPROP_SRAMSM (1 << 11) /* Bit 11: SRAM Sleep/Deep-Sleep Standby Mode Present */ +#define SYSCON_SYSPROP_PIOSCPDE (1 << 12) /* Bit 12: PIOSC Power Down Present */ +#define SYSCON_SYSPROP_TSPDE (1 << 16) /* Bit 16: Temp Sense Power Down Enable */ +#define SYSCON_SYSPROP_LDOSME (1 << 17) /* Bit 17: LDO Sleep Mode Enable */ + +/* Precision Internal Oscillator Calibration */ + +#define SYSCON_PIOSCCAL_UT_SHIFT (0) /* Bits 0-6: User Trim Value */ +#define SYSCON_PIOSCCAL_UT_MASK (0x7f << SYSCON_PIOSCCAL_UT_SHIFT) +# define SYSCON_PIOSCCAL_UT(n) ((uint32_t)(n) << SYSCON_PIOSCCAL_UT_SHIFT) +#define SYSCON_PIOSCCAL_UPDATE (1 << 8) /* Bit 8: Update Trim */ +#define SYSCON_PIOSCCAL_CAL (1 << 9) /* Bit 9: Start Calibration */ +#define SYSCON_PIOSCCAL_UTEN (1 << 31) /* Bit 31: Use User Trim Value */ + +/* Precision Internal Oscillator Statistics */ + +#define SYSCON_PIOSCSTAT_CT_SHIFT (0) /* Bits 0-6: Calibration Trim Value */ +#define SYSCON_PIOSCSTAT_CT_MASK (0x7f << SYSCON_PIOSCSTAT_CT_SHIFT) +# define SYSCON_PIOSCSTAT_CT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_CT_SHIFT) +#define SYSCON_PIOSCSTAT_RESULT_SHIFT (8) /* Bits 8-9: Calibration Result */ +#define SYSCON_PIOSCSTAT_RESULT_MASK (3 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_RESULT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_CRNONE (0 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_CRPASS (1 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +# define SYSCON_PIOSCSTAT_CRFAIL (2 << SYSCON_PIOSCSTAT_RESULT_SHIFT) +#define SYSCON_PIOSCSTAT_DT_SHIFT (16) /* Bits 16-22: Default Trim Value */ +#define SYSCON_PIOSCSTAT_DT_MASK (0x7f << SYSCON_PIOSCSTAT_DT_SHIFT) +# define SYSCON_PIOSCSTAT_DT(n) ((uint32_t)(n) << SYSCON_PIOSCSTAT_DT_SHIFT) + +/* PLL Frequency 0 */ + +#define SYSCON_PLLFREQ0_MINT_SHIFT (0) /* Bits 0-9: PLL M Integer Value */ +#define SYSCON_PLLFREQ0_MINT_MASK (0x3ff << SYSCON_PLLFREQ0_MINT_SHIFT) +# define SYSCON_PLLFREQ0_MINT(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MINT_SHIFT) +#define SYSCON_PLLFREQ0_MFRAC_SHIFT (10) /* Bits 10-19: PLL M Fractional Value */ +#define SYSCON_PLLFREQ0_MFRAC_MASK (0x3ff << SYSCON_PLLFREQ0_MFRAC_SHIFT) +# define SYSCON_PLLFREQ0_MFRAC(n) ((uint32_t)(n) << SYSCON_PLLFREQ0_MFRAC_SHIFT) +#define SYSCON_PLLFREQ0_PLLPWR (1 << 23) /* Bit 23: PLL Power */ + +/* PLL Frequency 1 */ + +#define SYSCON_PLLFREQ1_N_SHIFT (0) /* Bits 0-4: PLL N Value */ +#define SYSCON_PLLFREQ1_N_MASK (31 << SYSCON_PLLFREQ1_N_SHIFT) +# define SYSCON_PLLFREQ1_N(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_N_SHIFT) +#define SYSCON_PLLFREQ1_Q_SHIFT (8) /* Bits 8-12: PLL Q Value */ +#define SYSCON_PLLFREQ1_Q_MASK (31 << SYSCON_PLLFREQ1_Q_SHIFT) +# define SYSCON_PLLFREQ1_Q(n) ((uint32_t)(n) << SYSCON_PLLFREQ1_Q_SHIFT) + +/* PLL Status */ + +#define SYSCON_PLLSTAT_LOCK (1 << 0) /* Bit 0: PLL Lock */ + +/* Sleep Power Configuration */ + +#define SYSCON_SLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_SLPPWRCFG_SRAMPM_MASK (3 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_SLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_SLPPWRCFG_SRAMPM_LOWPWR (3 << SYSCON_SLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_SLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_SLPPWRCFG_FLASHPM_MASK (3 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_SLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_SLPPWRCFG_FLASHPM_LOWPWRR (2 << SYSCON_SLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ + +/* Deep-Sleep Power Configuration */ + +#define SYSCON_DSLPPWRCFG_SRAMPM_SHIFT (0) /* Bits 1-0: SRAM Power Modes */ +#define SYSCON_DSLPPWRCFG_SRAMPM_MASK (3 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) +# define SYSCON_DSLPPWRCFG_SRAMPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_STANDBY (1 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Standby Mode */ +# define SYSCON_DSLPPWRCFG_SRAMPM_LOWPWR (3 << SYSCON_DSLPPWRCFG_SRAMPM_SHIFT) /* Low Power Mode */ +#define SYSCON_DSLPPWRCFG_FLASHPM_SHIFT (4) /* Bits 5-4: Flash Power Modes */ +#define SYSCON_DSLPPWRCFG_FLASHPM_MASK (3 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) +# define SYSCON_DSLPPWRCFG_FLASHPM_ACTIVE (0 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Active Mode */ +# define SYSCON_DSLPPWRCFG_FLASHPM_LOWPWR (2 << SYSCON_DSLPPWRCFG_FLASHPM_SHIFT) /* Low Power Mode */ +#define SYSCON_DSLPPWRCFG_TSPD (1 << 8) /* Bit 8: Temperature Sense Power Down */ +#define SYSCON_DSLPPWRCFG_LDOSM (1 << 9) /* Bit 9: LDO Sleep Mode */ + + +/* Non-Volatile Memory Information */ + +#define TIVA_SYSCON_NVMSTAT_FWB (1 << 0) /* Bit 0: 32 Word Flash Write Buffer Available */ + +/* LDO Sleep Power Control */ + +#define SYSCON_LDOSPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDOSPCTL_VLDO_MASK (0xff << SYSCON_LDOSPCTL_VLDO_SHIFT) +# define SYSCON_LDOSPCTL_VLDO_0p90V (0x12 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCTL_VLDO_0p95V (0x13 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCTL_VLDO_1p00V (0x14 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCTL_VLDO_1p05V (0x15 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCTL_VLDO_1p10V (0x16 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCTL_VLDO_1p15V (0x17 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCTL_VLDO_1p20V (0x18 << SYSCON_LDOSPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Sleep Power Calibration */ + +#define SYSCON_LDOSPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Sleep without PLL */ +#define SYSCON_LDOSPCAL_NOPLL_MASK (0xff << SYSCON_LDOSPCAL_NOPLL_SHIFT) +# define SYSCON_LDOSPCAL_NOPLL_0p90V (0x12 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_NOPLL_0p95V (0x13 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p00V (0x14 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p05V (0x15 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p10V (0x16 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p15V (0x17 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_NOPLL_1p20V (0x18 << SYSCON_LDOSPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDOSPCAL_WITHPLL_SHIFT (8) /* Bits 15-8: Sleep with PLL */ +#define SYSCON_LDOSPCAL_WITHPLL_MASK (0xff << SYSCON_LDOSPCAL_WITHPLL_SHIFT) +# define SYSCON_LDOSPCAL_WITHPLL_0p90V (0x12 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDOSPCAL_WITHPLL_0p95V (0x13 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p00V (0x14 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p05V (0x15 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p10V (0x16 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p15V (0x17 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDOSPCAL_WITHPLL_1p20V (0x18 << SYSCON_LDOSPCAL_WITHPLL_SHIFT) /* 1.20 V */ + +/* LDO Deep-Sleep Power Control */ + +#define SYSCON_LDODPCTL_VLDO_SHIFT (0) /* Bits 7-0: LDO Output Voltage */ +#define SYSCON_LDODPCTL_VLDO_MASK (0xff << SYSCON_LDODPCTL_VLDO_SHIFT) +# define SYSCON_LDODPCTL_VLDO_0p90V (0x12 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCTL_VLDO_0p95V (0x13 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCTL_VLDO_1p00V (0x14 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCTL_VLDO_1p05V (0x15 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCTL_VLDO_1p10V (0x16 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCTL_VLDO_1p15V (0x17 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCTL_VLDO_1p20V (0x18 << SYSCON_LDODPCTL_VLDO_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCTL_VADJEN (1 << 31) /* Bit 31: Voltage Adjust Enable */ + +/* LDO Deep-Sleep Power Calibration */ + +#define SYSCON_LDODPCAL_NOPLL_SHIFT (0) /* Bits 7-0: Deep-Sleep without PLL */ +#define SYSCON_LDODPCAL_NOPLL_MASK (0xff << SYSCON_LDODPCAL_NOPLL_SHIFT) +# define SYSCON_LDODPCAL_NOPLL_0p90V (0x12 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_NOPLL_0p95V (0x13 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_NOPLL_1p00V (0x14 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_NOPLL_1p05V (0x15 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_NOPLL_1p10V (0x16 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_NOPLL_1p15V (0x17 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_NOPLL_1p20V (0x18 << SYSCON_LDODPCAL_NOPLL_SHIFT) /* 1.20 V */ +#define SYSCON_LDODPCAL_30KHZ_SHIFT (8) /* Bits 15-8: Deep-Sleep with IOSC */ +#define SYSCON_LDODPCAL_30KHZ_MASK (0xff << SYSCON_LDODPCAL_30KHZ_SHIFT) +# define SYSCON_LDODPCAL_30KHZ_0p90V (0x12 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.90 V */ +# define SYSCON_LDODPCAL_30KHZ_0p95V (0x13 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 0.95 V */ +# define SYSCON_LDODPCAL_30KHZ_1p00V (0x14 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.00 V */ +# define SYSCON_LDODPCAL_30KHZ_1p05V (0x15 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.05 V */ +# define SYSCON_LDODPCAL_30KHZ_1p10V (0x16 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.10 V */ +# define SYSCON_LDODPCAL_30KHZ_1p15V (0x17 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.15 V */ +# define SYSCON_LDODPCAL_30KHZ_1p20V (0x18 << SYSCON_LDODPCAL_30KHZ_SHIFT) /* 1.20 V */ + +/* Sleep / Deep-Sleep Power Mode Status */ + +#define SYSCON_SDPMST_SPDERR (1 << 0) /* Bit 0: SRAM Power Down Request Error */ +#define SYSCON_SDPMST_FPDERR (1 << 1) /* Bit 1: Flash Memory Power Down Request Error */ +#define SYSCON_SDPMST_PPDERR (1 << 2) /* Bit 2: PIOSC Power Down Request Error */ +#define SYSCON_SDPMST_LDMINERR (1 << 3) /* Bit 3: VLDO Value Below Minimum Error in Deep-Sleep Mode */ +#define SYSCON_SDPMST_LSMINERR (1 << 4) /* Bit 4: VLDO Value Below Minimum Error in Sleep Mode */ +#define SYSCON_SDPMST_LMAXERR (1 << 6) /* Bit 6: VLDO Value Above Maximum Error */ +#define SYSCON_SDPMST_PPDW (1 << 7) /* Bit 7: PIOSC Power Down Request Warning */ +#define SYSCON_SDPMST_PRACT (1 << 16) /* Bit 16: Sleep or Deep-Sleep Power Request Active */ +#define SYSCON_SDPMST_LOWPWR (1 << 17) /* Bit 17: Sleep or Deep-Sleep Mode */ +#define SYSCON_SDPMST_FLASHLP (1 << 18) /* Bit 18: Flash Memory in Low Power State */ +#define SYSCON_SDPMST_LDOUA (1 << 19) /* Bit 19: LDO Update Active */ + +/* Reset Behavior Control Register */ + +#define SYSCON_RESBEHAVCTL_EXTRES_SHIFT (0) /* Bits 0-1: External RST Pin Operation */ +#define SYSCON_RESBEHAVCTL_EXTRES_MASK (3 << SYSCON_RESBEHAVCTL_EXTRES_SHIFT) +# define SYSCON_RESBEHAVCTL_EXTRES_SYSRST (2 << SYSCON_RESBEHAVCTL_EXTRES_SHIFT) /* System reset */ +# define SYSCON_RESBEHAVCTL_EXTRES_POR (3 << SYSCON_RESBEHAVCTL_EXTRES_SHIFT) /* POR */ +#define SYSCON_RESBEHAVCTL_BOR_SHIFT (2) /* Bits 2-3: BOR Reset operation */ +#define SYSCON_RESBEHAVCTL_BOR_MASK (3 << SYSCON_RESBEHAVCTL_BOR_SHIFT) +# define SYSCON_RESBEHAVCTL_BOR_SYSRST (2 << SYSCON_RESBEHAVCTL_BOR_SHIFT) /* System reset */ +# define SYSCON_RESBEHAVCTL_BOR_POR (3 << SYSCON_RESBEHAVCTL_BOR_SHIFT) /* POR */ +#define SYSCON_RESBEHAVCTL_WDOG0_SHIFT (4) /* Bits 4-5: Watchdog 0 Reset Operation */ +#define SYSCON_RESBEHAVCTL_WDOG0_MASK (3 << SYSCON_RESBEHAVCTL_WDOG0_SHIFT) +# define SYSCON_RESBEHAVCTL_WDOG0_SYSRST (2 << SYSCON_RESBEHAVCTL_WDOG0_SHIFT) /* System reset */ +# define SYSCON_RESBEHAVCTL_WDOG0_POR (3 << SYSCON_RESBEHAVCTL_WDOG0_SHIFT) /* POR */ +#define SYSCON_RESBEHAVCTL_WDOG1_SHIFT (6) /* Bits 6-7: Watchdog 1 Reset Operation */ +#define SYSCON_RESBEHAVCTL_WDOG1_MASK (3 << SYSCON_RESBEHAVCTL_WDOG1_SHIFT) +# define SYSCON_RESBEHAVCTL_WDOG1_SYSRST (2 << SYSCON_RESBEHAVCTL_WDOG1_SHIFT) /* System reset */ +# define SYSCON_RESBEHAVCTL_WDOG1_POR (3 << SYSCON_RESBEHAVCTL_WDOG1_SHIFT) /* POR */ + +/* Hardware System Service Request */ + +#define SYSCON_HSSR_CDOFF_SHIFT (0) /* Bits 0-23: Command Descriptor Pointer */ +#define SYSCON_HSSR_CDOFF_MASK (0xffffff << SYSCON_HSSR_CDOFF_SHIFT) +# define SYSCON_HSSR_CDOFF(n) ((uint32_t)(n) << SYSCON_HSSR_CDOFF_SHIFT) +# define SYSCON_HSSR_CDOFF_NOREQ (0 << SYSCON_HSSR_CDOFF_SHIFT) /* No request pending */ +# define SYSCON_HSSR_CDOFF_ERROR (0xffffff << SYSCON_HSSR_CDOFF_SHIFT) /* An error occurred */ +#define SYSCON_HSSR_KEY_SHIFT (24) /* Bit 24-31: Write Key */ +#define SYSCON_HSSR_KEY_MASK (0xff << SYSCON_HSSR_KEY_SHIFT) +# define SYSCON_HSSR_KEY (0xca << SYSCON_HSSR_KEY_SHIFT) /* Key value */ + +/* USB Power Domain Status */ + +#define SYSCON_USBPDS_PWRSTAT_SHIFT (0) /* Bits 0-1: Power Domain Status */ +#define SYSCON_USBPDS_PWRSTAT_MASK (3 << SYSCON_USBPDS_PWRSTAT_SHIFT) +# define SYSCON_USBPDS_PWRSTAT_OFF (0 << SYSCON_USBPDS_PWRSTAT_SHIFT) /* OFF */ +# define SYSCON_USBPDS_PWRSTAT_ON (3 << SYSCON_USBPDS_PWRSTAT_SHIFT) /* ON */ +#define SYSCON_USBPDS_MEMSTAT_SHIFT (2) /* Bits 2-3: Memory Array Power Status */ +#define SYSCON_USBPDS_MEMSTAT_MASK (3 << SYSCON_USBPDS_PWRSTAT_SHIFT) +# define SYSCON_USBPDS_MEMSTAT_OFF (0 << SYSCON_USBPDS_PWRSTAT_SHIFT) /* Array OFF */ +# define SYSCON_USBPDS_MEMSTAT_RETAIN (1 << SYSCON_USBPDS_PWRSTAT_SHIFT) /* SRAM Retention */ +# define SYSCON_USBPDS_MEMSTAT_ON (3 << SYSCON_USBPDS_PWRSTAT_SHIFT) /* Array On */ + +/* USB Memory Power Control */ + +#define SYSCON_USBMPC_PWRCTL_SHIFT (0) /* Bits 0-1: Memory Array Power Control */ +#define SYSCON_USBMPC_PWRCTL_MASK (3 << SYSCON_USBMPC_PWRCTL_SHIFT) +# define SYSCON_USBMPC_PWRCTL_OFF (0 << SYSCON_USBMPC_PWRCTL_SHIFT) /* Array OFF */ +# define SYSCON_USBMPC_PWRCTL_RETAIN (1 << SYSCON_USBMPC_PWRCTL_SHIFT) /* SRAM Retention */ +# define SYSCON_USBMPC_PWRCTL_ON (3 << SYSCON_USBMPC_PWRCTL_SHIFT) /* Array On */ + +/* Ethernet MAC Power Domain Status */ + +#define SYSCON_EMACPDS_PWRSTAT_SHIFT (0) /* Bits 0-1: Power Domain Status */ +#define SYSCON_EMACPDS_PWRSTAT_MASK (3 << SYSCON_EMACPDS_PWRSTAT_SHIFT) +# define SYSCON_EMACPDS_PWRSTAT_OFF (0 << SYSCON_EMACPDS_PWRSTAT_SHIFT) /* OFF */ +# define SYSCON_EMACPDS_PWRSTAT_ON (3 << SYSCON_EMACPDS_PWRSTAT_SHIFT) /* ON */ +#define SYSCON_EMACPDS_MEMSTAT_SHIFT (2) /* Bits 2-3: Memory Array Power Status */ +#define SYSCON_EMACPDS_MEMSTAT_MASK (3 << SYSCON_EMACPDS_MEMSTAT_SHIFT) +# define SYSCON_EMACPDS_MEMSTAT_OFF (0 << SYSCON_EMACPDS_MEMSTAT_SHIFT) /* Array OFF */ +# define SYSCON_EMACPDS_MEMSTAT_ON (3 << SYSCON_EMACPDS_MEMSTAT_SHIFT) /* Array On */ + +/* Ethernet MAC Memory Power Control */ + +#define SYSCON_EMACMPC_PWRCTL_SHIFT (0) /* Bits 0-1: Memory Array Power Control */ +#define SYSCON_EMACMPC_PWRCTL_MASK (3 << SYSCON_EMACMPC_PWRCTL_SHIFT) +#define SYSCON_EMACMPC_PWRCTL_OFF (0 << SYSCON_EMACMPC_PWRCTL_SHIFT) /* Array OFF */ +#define SYSCON_EMACMPC_PWRCTL_ON (3 << SYSCON_EMACMPC_PWRCTL_SHIFT) /* Array On */ + +/* LCD Power Domain Status */ + +#define SYSCON_LCDPDS_PWRSTAT_SHIFT (0) /* Bits 0-1: Power Domain Status */ +#define SYSCON_LCDPDS_PWRSTAT_MASK (3 << SYSCON_LCDPDS_PWRSTAT_SHIFT) +# define SYSCON_LCDPDS_PWRSTAT_OFF (0 << SYSCON_LCDPDS_PWRSTAT_SHIFT) /* OFF */ +# define SYSCON_LCDPDS_PWRSTAT_ON (3 << SYSCON_LCDPDS_PWRSTAT_SHIFT) /* ON */ +#define SYSCON_LCDPDS_MEMSTAT_SHIFT (2) /* Bits 2-3: Memory Array Power Status */ +#define SYSCON_LCDPDS_MEMSTAT_MASK (3 << SYSCON_LCDPDS_MEMSTAT_SHIFT) +# define SYSCON_LCDPDS_MEMSTAT_OFF (0 << SYSCON_LCDPDS_MEMSTAT_SHIFT) /* Array OFF */ +# define SYSCON_LCDPDS_MEMSTAT_ON (3 << SYSCON_LCDPDS_MEMSTAT_SHIFT) /* Array On */ + +/* LCD Memory Power Control */ + +#define SYSCON_LCDMPC_PWRCTL_SHIFT (0) /* Bits 0-1: Memory Array Power Control */ +#define SYSCON_LCDMPC_PWRCTL_MASK (3 << SYSCON_LCDMPC_PWRCTL_SHIFT) +#define SYSCON_LCDMPC_PWRCTL_OFF (0 << SYSCON_LCDMPC_PWRCTL_SHIFT) /* Array OFF */ +#define SYSCON_LCDMPC_PWRCTL_ON (3 << SYSCON_LCDMPC_PWRCTL_SHIFT) /* Array On */ + +/* CAN 0 Power Domain Status */ + +#define SYSCON_CAN0PDS_PWRSTAT_SHIFT (0) /* Bits 0-1: Power Domain Status */ +#define SYSCON_CAN0PDS_PWRSTAT_MASK (3 << SYSCON_CAN0PDS_PWRSTAT_SHIFT) +# define SYSCON_CAN0PDS_PWRSTAT_OFF (0 << SYSCON_CAN0PDS_PWRSTAT_SHIFT) /* OFF */ +# define SYSCON_CAN0PDS_PWRSTAT_ON (3 << SYSCON_CAN0PDS_PWRSTAT_SHIFT) /* ON */ +#define SYSCON_CAN0PDS_MEMSTAT_SHIFT (2) /* Bits 2-3: Memory Array Power Status */ +#define SYSCON_CAN0PDS_MEMSTAT_MASK (3 << SYSCON_CAN0PDS_MEMSTAT_SHIFT) +# define SYSCON_CAN0PDS_MEMSTAT_OFF (0 << SYSCON_CAN0PDS_MEMSTAT_SHIFT) /* Array OFF */ +# define SYSCON_CAN0PDS_MEMSTAT_ON (3 << SYSCON_CAN0PDS_MEMSTAT_SHIFT) /* Array On */ + +/* CAN 0 Memory Power Control */ + +#define SYSCON_CAN0MPC_PWRCTL_SHIFT (0) /* Bits 0-1: Memory Array Power Control */ +#define SYSCON_CAN0MPC_PWRCTL_MASK (3 << SYSCON_CAN0MPC_PWRCTL_SHIFT) +#define SYSCON_CAN0MPC_PWRCTL_OFF (0 << SYSCON_CAN0MPC_PWRCTL_SHIFT) /* Array OFF */ +#define SYSCON_CAN0MPC_PWRCTL_ON (3 << SYSCON_CAN0MPC_PWRCTL_SHIFT) /* Array On */ + +/* CAN 1 Power Domain Status */ + +#define SYSCON_CAN1PDS_PWRSTAT_SHIFT (0) /* Bits 0-1: Power Domain Status */ +#define SYSCON_CAN1PDS_PWRSTAT_MASK (3 << SYSCON_CAN1PDS_PWRSTAT_SHIFT) +# define SYSCON_CAN1PDS_PWRSTAT_OFF (0 << SYSCON_CAN1PDS_PWRSTAT_SHIFT) /* OFF */ +# define SYSCON_CAN1PDS_PWRSTAT_ON (3 << SYSCON_CAN1PDS_PWRSTAT_SHIFT) /* ON */ +#define SYSCON_CAN1PDS_MEMSTAT_SHIFT (2) /* Bits 2-3: Memory Array Power Status */ +#define SYSCON_CAN1PDS_MEMSTAT_MASK (3 << SYSCON_CAN1PDS_MEMSTAT_SHIFT) +# define SYSCON_CAN1PDS_MEMSTAT_OFF (0 << SYSCON_CAN1PDS_MEMSTAT_SHIFT) /* Array OFF */ +# define SYSCON_CAN1PDS_MEMSTAT_ON (3 << SYSCON_CAN1PDS_MEMSTAT_SHIFT) /* Array On */ + +/* CAN 1 Memory Power Control */ + +#define SYSCON_CAN1MPC_PWRCTL_SHIFT (0) /* Bits 0-1: Memory Array Power Control */ +#define SYSCON_CAN1MPC_PWRCTL_MASK (3 << SYSCON_CAN1MPC_PWRCTL_SHIFT) +#define SYSCON_CAN1MPC_PWRCTL_OFF (0 << SYSCON_CAN1MPC_PWRCTL_SHIFT) /* Array OFF */ +#define SYSCON_CAN1MPC_PWRCTL_ON (3 << SYSCON_CAN1MPC_PWRCTL_SHIFT) /* Array On */ + +/* Watchdog Timer Peripheral Present */ + +#define SYSCON_PPWD(n) (1 << (n)) /* Bit n: WDTn present */ +# define SYSCON_PPWD_P0 (1 << 0) /* Bit 0: WDT0 present */ +# define SYSCON_PPWD_P1 (1 << 1) /* Bit 1: WDT1 present */ + +/* 16/32-Bit Timer Peripheral Present */ + +#define SYSCON_PPTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Present */ +# define SYSCON_PPTIMER_P0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P1 (1 << 1) /* Bit 1: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P2 (1 << 2) /* Bit 2: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P3 (1 << 3) /* Bit 3: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P4 (1 << 4) /* Bit 4: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P5 (1 << 5) /* Bit 5: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P6 (1 << 6) /* Bit 6: 16/32-Bit Timer 0 Present */ +# define SYSCON_PPTIMER_P7 (1 << 7) /* Bit 7: 16/32-Bit Timer 0 Present */ + +/* GPIO Peripheral Present */ + +#define SYSCON_PPGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Present */ +# define SYSCON_PPGPIO_P0 (1 << 0) /* Bit 0: GPIO Port A Present */ +# define SYSCON_PPGPIO_P1 (1 << 1) /* Bit 1: GPIO Port B Present */ +# define SYSCON_PPGPIO_P2 (1 << 2) /* Bit 2: GPIO Port C Present */ +# define SYSCON_PPGPIO_P3 (1 << 3) /* Bit 3: GPIO Port D Present */ +# define SYSCON_PPGPIO_P4 (1 << 4) /* Bit 4: GPIO Port E Present */ +# define SYSCON_PPGPIO_P5 (1 << 5) /* Bit 5: GPIO Port F Present */ +# define SYSCON_PPGPIO_P6 (1 << 6) /* Bit 6: GPIO Port G Present */ +# define SYSCON_PPGPIO_P7 (1 << 7) /* Bit 7: GPIO Port H Present */ +# define SYSCON_PPGPIO_P8 (1 << 8) /* Bit 8: GPIO Port J Present */ +# define SYSCON_PPGPIO_P9 (1 << 9) /* Bit 9: GPIO Port K Present */ +# define SYSCON_PPGPIO_P10 (1 << 10) /* Bit 10: GPIO Port L Present */ +# define SYSCON_PPGPIO_P11 (1 << 11) /* Bit 11: GPIO Port M Present */ +# define SYSCON_PPGPIO_P12 (1 << 12) /* Bit 12: GPIO Port N Present */ +# define SYSCON_PPGPIO_P13 (1 << 13) /* Bit 13: GPIO Port P Present */ +# define SYSCON_PPGPIO_P14 (1 << 14) /* Bit 14: GPIO Port Q Present */ +# define SYSCON_PPGPIO_P15 (1 << 15) /* Bit 15: GPIO Port R Present */ +# define SYSCON_PPGPIO_P16 (1 << 16) /* Bit 16: GPIO Port S Present */ +# define SYSCON_PPGPIO_P17 (1 << 17) /* Bit 17: GPIO Port T Present */ + +/* μDMA Peripheral Present */ + +#define SYSCON_PPDMA_P0 (1 << 0) /* Bit 0: μDMA Module Present */ + +/* EPI Peripheral Present */ + +#define SYSCON_PPEPI_P0 (1 << 0) /* Bit 0: EPI Module Present */ + +/* Hibernation Peripheral Present */ + +#define SYSCON_PPHIB_P0 (1 << 0) /* Bit 0: Hibernation Module Present */ + +/* UART Peripheral Present */ + +#define SYSCON_PPUART(n) (1 << (n)) /* Bit n: UART Module n Present */ +# define SYSCON_PPUART_P0 (1 << 0) /* Bit 0: UART Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: UART Module 1 Present */ +# define SYSCON_PPUART_P2 (1 << 2) /* Bit 2: UART Module 2 Present */ +# define SYSCON_PPUART_P3 (1 << 3) /* Bit 3: UART Module 3 Present */ +# define SYSCON_PPUART_P4 (1 << 4) /* Bit 4: UART Module 4 Present */ +# define SYSCON_PPUART_P5 (1 << 5) /* Bit 5: UART Module 5 Present */ +# define SYSCON_PPUART_P6 (1 << 6) /* Bit 6: UART Module 6 Present */ +# define SYSCON_PPUART_P7 (1 << 7) /* Bit 7: UART Module 7 Present */ + +/* SSI Peripheral Present */ + +#define SYSCON_PPSSI(n) (1 << (n)) /* Bit n: SSI Module n Present */ +# define SYSCON_PPSSI_P0 (1 << 0) /* Bit 0: SSI Module 0 Present */ +# define SYSCON_PPSSI_P1 (1 << 1) /* Bit 1: SSI Module 1 Present */ +# define SYSCON_PPSSI_P2 (1 << 2) /* Bit 2: SSI Module 2 Present */ +# define SYSCON_PPSSI_P3 (1 << 3) /* Bit 3: SSI Module 3 Present */ + +/* I2C Peripheral Present */ + +#define SYSCON_PPI2C(n) (1 << (n)) /* Bit n: I2C Module n Present */ +# define SYSCON_PPI2C_P0 (1 << 0) /* Bit 0: I2C Module 0 Present */ +# define SYSCON_PPI2C_P1 (1 << 1) /* Bit 1: I2C Module 1 Present */ +# define SYSCON_PPI2C_P2 (1 << 2) /* Bit 2: I2C Module 2 Present */ +# define SYSCON_PPI2C_P3 (1 << 3) /* Bit 3: I2C Module 3 Present */ +# define SYSCON_PPI2C_P4 (1 << 4) /* Bit 4: I2C Module 4 Present */ +# define SYSCON_PPI2C_P5 (1 << 5) /* Bit 5: I2C Module 5 Present */ +# define SYSCON_PPI2C_P6 (1 << 6) /* Bit 6: I2C Module 6 Present */ +# define SYSCON_PPI2C_P7 (1 << 7) /* Bit 7: I2C Module 7 Present */ +# define SYSCON_PPI2C_P8 (1 << 8) /* Bit 8: I2C Module 8 Present */ +# define SYSCON_PPI2C_P9 (1 << 9) /* Bit 9: I2C Module 9 Present */ + + +/* USB Peripheral Present */ + +#define SYSCON_PPUSB_P0 (1 << 0) /* Bit 0: USB Module Present */ + +/* Ethernet PHY Peripheral Present */ + +#define SYSCON_PPEPHY_P0 (1 << 0) /* Bit 0: Ethernet PHY Module Present */ + +/* CAN Peripheral Present */ + +#define SYSCON_PPCAN(n) (1 << (n)) /* Bit n: CAN Module n Present */ +# define SYSCON_PPCAN_P0 (1 << 0) /* Bit 0: CAN Module 0 Present */ +# define SYSCON_PPCAN_P1 (1 << 1) /* Bit 1: CAN Module 1 Present */ + +/* ADC Peripheral Present */ + +#define SYSCON_PPADC(n) (1 << (n)) /* Bit n: ADC Module n Present */ +# define SYSCON_PPADC_P0 (1 << 0) /* Bit 0: ADC Module 0 Present */ +# define SYSCON_PPADC_P1 (1 << 1) /* Bit 1: ADC Module 1 Present */ + +/* ACMP Peripheral Present */ + +#define SYSCON_PPACMP_P0 (1 << 0) /* Bit 0: Analog Comparator Module Present */ + +/* PWM Peripheral Present */ + +#define SYSCON_PPWM(n) (1 << (n)) /* Bit n: PWM Module n Present */ +# define SYSCON_PPWM_P0 (1 << 0) /* Bit 0: PWM Module 0 Present */ +# define SYSCON_PPWM_P1 (1 << 1) /* Bit 1: PWM Module 1 Present */ + +/* QE Interface Peripheral Present */ + +#define SYSCON_PPQEI(n) (1 << (n)) /* Bit n: QEI Module n Present */ +# define SYSCON_PPQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Present */ +# define SYSCON_PPUART_P1 (1 << 1) /* Bit 1: QEI Module 1 Present */ + +/* Low Pin Count Interface Peripheral Present */ + +#define SYSCON_PPLPC_P0 (1 << 0) /* Bit 0: LPC Module Present */ + +/* Platform Environment Control Interface Peripheral Present */ + +#define SYSCON_PPPECI_P0 (1 << 0) /* Bit 0: PECI Module Present */ + +/* Fan Control Peripheral Present */ + +#define SYSCON_PPFAN_P0 (1 << 0) /* Bit 0: FAN Module 0 Present */ + +/* EEPROM Peripheral Present */ + +#define SYSCON_PPEEPROM_P0 (1 << 0) /* Bit 0: EEPROM Module Present */ + +/* 32/64-Bit Wide Timer Peripheral Present */ + +#define SYSCON_PPWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide Timer n Present */ +# define SYSCON_PPWTIMER_P0 (1 << 0) /* Bit 0: 32/64-Bit Wide Timer 0 Present */ +# define SYSCON_PPWTIMER_P1 (1 << 1) /* Bit 1: 32/64-Bit Wide Timer 1 Present */ +# define SYSCON_PPWTIMER_P2 (1 << 2) /* Bit 2: 32/64-Bit Wide Timer 2 Present */ +# define SYSCON_PPWTIMER_P3 (1 << 3) /* Bit 3: 32/64-Bit Wide Timer 3 Present */ +# define SYSCON_PPWTIMER_P4 (1 << 4) /* Bit 4: 32/64-Bit Wide Timer 4 Present */ +# define SYSCON_PPWTIMER_P5 (1 << 5) /* Bit 5: 32/64-Bit Wide Timer 5 Present */ + +/* Remote Temperature Sensor Peripheral Present */ + +#define SYSCON_PPRTS_P0 (1 << 0) /* Bit 0: RTS Module Present */ + +/* CRC/Crypto Modules Peripheral Present */ + +#define SYSCON_PPCCM_P0 (1 << 0) /* Bit 0: CRC/Crypto Modules Present */ + +/* LCD Peripheral Present */ + +#define SYSCON_PPLCD_P0 (1 << 0) /* Bit 0: LCD Module Present */ + +/* 1-Wire Peripheral Present */ + +#define SYSCON_PPOWIRE_P0 (1 << 0) /* Bit 0: 1-Wire Module Present */ + +/* Ethernet MAC Peripheral Present */ + +#define SYSCON_PPEMAC_P0 (1 << 0) /* Bit 0: Ethernet Controller Module Present */ + +/* Power Regulator Bus Peripheral Present */ + +#define SYSCON_PPPRB__P0 (1 << 0) /* Bit 0: PRB Module Present */ + +/* Human Interface Master Peripheral Present */ + +#define SYSCON_PPHIM_P0 (1 << 0) /* Bit 0: HIM Module Present */ + +/* Watchdog Timer Software Reset */ + +#define SYSCON_SRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Software Reset */ +# define SYSCON_SRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Software Reset */ +# define SYSCON_SRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Software Reset */ + +/* 16/32-Bit Timer Software Reset */ + +#define SYSCON_SRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Software Reset */ +# define SYSCON_SRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Software Reset */ +# define SYSCON_SRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit Timer 1 Software Reset */ +# define SYSCON_SRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit Timer 2 Software Reset */ +# define SYSCON_SRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit Timer 3 Software Reset */ +# define SYSCON_SRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit Timer 4 Software Reset */ +# define SYSCON_SRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit Timer 5 Software Reset */ +# define SYSCON_SRTIMER_R6 (1 << 6) /* Bit 6: 16/32-Bit Timer 6 Software Reset */ +# define SYSCON_SRTIMER_R7 (1 << 7) /* Bit 7: 16/32-Bit Timer 7 Software Reset */ + +/* GPIO Software Reset */ + +#define SYSCON_SRGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Software Reset */ +# define SYSCON_SRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Software Reset */ +# define SYSCON_SRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Software Reset */ +# define SYSCON_SRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Software Reset */ +# define SYSCON_SRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Software Reset */ +# define SYSCON_SRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Software Reset */ +# define SYSCON_SRPGIO_R5 (1 << 5) /* Bit 5: GPIO Port F Software Reset */ +# define SYSCON_SRPGIO_R6 (1 << 6) /* Bit 6: GPIO Port G Software Reset */ +# define SYSCON_SRPGIO_R7 (1 << 7) /* Bit 7: GPIO Port H Software Reset */ +# define SYSCON_SRPGIO_R8 (1 << 8) /* Bit 8: GPIO Port J Software Reset */ +# define SYSCON_SRPGIO_R9 (1 << 9) /* Bit 9: GPIO Port K Software Reset */ +# define SYSCON_SRPGIO_R10 (1 << 10) /* Bit 10: GPIO Port L Software Reset */ +# define SYSCON_SRPGIO_R11 (1 << 11) /* Bit 11: GPIO Port M Software Reset */ +# define SYSCON_SRPGIO_R12 (1 << 12) /* Bit 12: GPIO Port N Software Reset */ +# define SYSCON_SRPGIO_R13 (1 << 13) /* Bit 13: GPIO Port P Software Reset */ +# define SYSCON_SRPGIO_R14 (1 << 14) /* Bit 14: GPIO Port Q Software Reset */ +# define SYSCON_SRPGIO_R15 (1 << 15) /* Bit 15: GPIO Port R Software Reset */ +# define SYSCON_SRPGIO_R16 (1 << 16) /* Bit 16: GPIO Port S Software Reset */ +# define SYSCON_SRPGIO_R17 (1 << 17) /* Bit 17: GPIO Port T Software Reset */ + +/* μDMA Software Reset */ + +#define SYSCON_SRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Software Reset */ + +/* EPI Software Reset */ + +#define SYSCON_SREPI_R0 (1 << 0) /* Bit 0: EPI Module Software Reset */ + +/* Hibernation Software Reset */ + +#define SYSCON_SRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Software Reset */ + +/* UART Software Reset */ + +#define SYSCON_SRUARTR(n) (1 << (n)) /* Bit n: UART Module n Software Reset */ +# define SYSCON_SRUARTR_R0 (1 << 0) /* Bit 0: UART Module 0 Software Reset */ +# define SYSCON_SRUARTR_R1 (1 << 1) /* Bit 1: UART Module 1 Software Reset */ +# define SYSCON_SRUARTR_R2 (1 << 2) /* Bit 2: UART Module 2 Software Reset */ +# define SYSCON_SRUARTR_R3 (1 << 3) /* Bit 3: UART Module 3 Software Reset */ +# define SYSCON_SRUARTR_R4 (1 << 4) /* Bit 4: UART Module 4 Software Reset */ +# define SYSCON_SRUARTR_R5 (1 << 5) /* Bit 5: UART Module 5 Software Reset */ +# define SYSCON_SRUARTR_R6 (1 << 6) /* Bit 6: UART Module 6 Software Reset */ +# define SYSCON_SRUARTR_R7 (1 << 7) /* Bit 7: UART Module 7 Software Reset */ + +/* SSI Software Reset */ + +#define SYSCON_SRSSI(n) (1 << (n)) /* Bit n: SSI Module n Software Reset */ +# define SYSCON_SRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Software Reset */ +# define SYSCON_SRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Software Reset */ +# define SYSCON_SRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Software Reset */ +# define SYSCON_SRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Software Reset */ + +/* I2C Software Reset */ + +#define SYSCON_SRI2C(n) (1 << (n)) /* Bit n: I2C Module n Software Reset */ +# define SYSCON_SRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Software Reset */ +# define SYSCON_SRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Software Reset */ +# define SYSCON_SRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Software Reset */ +# define SYSCON_SRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Software Reset */ +# define SYSCON_SRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Software Reset */ +# define SYSCON_SRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Software Reset */ +# define SYSCON_SRI2C_R6 (1 << 6) /* Bit 6: I2C Module 6 Software Reset */ +# define SYSCON_SRI2C_R7 (1 << 7) /* Bit 7: I2C Module 7 Software Reset */ +# define SYSCON_SRI2C_R8 (1 << 8) /* Bit 8: I2C Module 8 Software Reset */ +# define SYSCON_SRI2C_R9 (1 << 9) /* Bit 9: I2C Module 9 Software Reset */ + +/* USB Software Reset */ + +#define SYSCON_SRUSB_R0 (1 << 0) /* Bit 0: USB Module Software Reset */ + +/* Ethernet PHY Software Reset */ + +#define SYSCON_SREPHY_R0 (1 << 0) /* Bit 0: Ethernet PHY Module Software Reset */ + +/* CAN Software Reset */ + +#define SYSCON_SRCAN(n) (1 << (n)) /* Bit n: CAN Module n Software Reset */ +# define SYSCON_SRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Software Reset */ +# define SYSCON_SRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Software Reset*/ + +/* ADC Software Reset */ + +#define SYSCON_SRADC(n) (1 << (n)) /* Bit n: ADC Module n Software Reset */ +# define SYSCON_SRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Software Reset */ +# define SYSCON_SRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Software Reset */ + +/* ACMP Software Reset */ + +#define SYSCON_SRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Software Reset */ + +/* PWM Software Reset */ + +#define SYSCON_SRPWM(n) (1 << (n)) /* Bit n: PWM Module n Software Reset */ +# define SYSCON_SRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Software Reset */ +# define SYSCON_SRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Software Reset */ + +/* QE Interface Software Reset */ + +#define SYSCON_SRQEI(n) (1 << (n)) /* Bit n: QEI Module n Software Reset */ +# define SYSCON_SRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Software Reset */ +# define SYSCON_SRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Software Reset */ + +/* EEPROM Software Reset */ + +#define SYSCON_SREEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Software Reset */ + +/* 32/64-Bit Wide Timer Software Reset */ + +#define SYSCON_SRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide Timer n Software Reset */ +# define SYSCON_SRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide Timer 0 Software Reset */ +# define SYSCON_SRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide Timer 1 Software Reset */ +# define SYSCON_SRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide Timer 2 Software Reset */ +# define SYSCON_SRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide Timer 3 Software Reset */ +# define SYSCON_SRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide Timer 4 Software Reset */ +# define SYSCON_SRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide Timer 5 Software Reset */ + +/* CRC/Crypto Modules Software Reset */ + +#define SYSCON_SRCCM_R0 (1 << 0) /* Bit 0: CRC/Crypto Modules Software Reset */ + +/* LCD Controller Software Reset */ + +#define SYSCON_SRLCD_R0 (1 << 0) /* Bit 0: LCD Module 0 Software Reset */ + +/* 1-Wire Software Reset */ + +#define SYSCON_SROWIRE_R0 (1 << 0) /* Bit 0: 1-Wire Module Software Reset */ + +/* Ethernet MAC Software Reset */ + +#define SYSCON_SREMAC_R0 (1 << 0) /* Ethernet Controller MAC Module 0 Software Reset */ + +/* Watchdog Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Run Mode Clock Gating Control */ + +/* 16/32-Bit Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit Timer 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R6 (1 << 6) /* Bit 6: 16/32-Bit Timer 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCTIMER_R7 (1 << 7) /* Bit 7: 16/32-Bit Timer 7 Run Mode Clock Gating Control */ + +/* GPIO Run Mode Clock Gating Control */ + +#define SYSCON_RCGCGPIO(n) (1 << (n)) /* Bit n: 16/32-Bit GPIO Port n Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R0 (1 << 0) /* Bit 0: 16/32-Bit GPIO Port A Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R1 (1 << 1) /* Bit 1: 16/32-Bit GPIO Port B Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R2 (1 << 2) /* Bit 2: 16/32-Bit GPIO Port C Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R3 (1 << 3) /* Bit 3: 16/32-Bit GPIO Port D Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R4 (1 << 4) /* Bit 4: 16/32-Bit GPIO Port E Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R5 (1 << 5) /* Bit 5: 16/32-Bit GPIO Port F Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R6 (1 << 6) /* Bit 6: 16/32-Bit GPIO Port G Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R7 (1 << 7) /* Bit 7: 16/32-Bit GPIO Port H Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R8 (1 << 8) /* Bit 8: 16/32-Bit GPIO Port J Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R9 (1 << 9) /* Bit 9: 16/32-Bit GPIO Port K Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R10 (1 << 10) /* Bit 10: 16/32-Bit GPIO Port L Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R11 (1 << 11) /* Bit 11: 16/32-Bit GPIO Port M Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R12 (1 << 12) /* Bit 12: 16/32-Bit GPIO Port N Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R13 (1 << 13) /* Bit 13: 16/32-Bit GPIO Port P Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R14 (1 << 14) /* Bit 14: 16/32-Bit GPIO Port Q Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R15 (1 << 15) /* Bit 15: 16/32-Bit GPIO Port R Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R16 (1 << 16) /* Bit 16: 16/32-Bit GPIO Port S Run Mode Clock Gating Control */ +# define SYSCON_RCGCGPIO_R17 (1 << 17) /* Bit 17: 16/32-Bit GPIO Port T Run Mode Clock Gating Control */ + +/* μDMA Run Mode Clock Gating Control */ + +#define SYSCON_RCGCDMA_R0 (1 << 0) /* Bit 0: μDMA Module Run Mode Clock Gating Control */ + +/* EPI Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEPI_R0 (1 << 0) /* Bit 0: EPI Module Run Mode Clock Gating Control */ + +/* Hibernation Run Mode Clock Gating Control */ + +#define SYSCON_RCGCHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Run Mode Clock Gating Control */ + +/* UART Run Mode Clock Gating Control */ + +#define SYSCON_RCGCUART(n) (1 << (n)) /* Bit n: UART Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R0 (1 << 0) /* Bit 0: UART Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R1 (1 << 1) /* Bit 1: UART Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R2 (1 << 2) /* Bit 2: UART Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R3 (1 << 3) /* Bit 3: UART Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R4 (1 << 4) /* Bit 4: UART Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R5 (1 << 5) /* Bit 5: UART Module 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R6 (1 << 6) /* Bit 6: UART Module 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCUART_R7 (1 << 7) /* Bit 7: UART Module 7 Run Mode Clock Gating Control */ + +/* SSI Run Mode Clock Gating Control */ + +#define SYSCON_RCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Run Mode Clock Gating Control */ + +/* I2C Run Mode Clock Gating Control */ + +#define SYSCON_RCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R6 (1 << 6) /* Bit 6: I2C Module 6 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R7 (1 << 7) /* Bit 7: I2C Module 7 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R8 (1 << 8) /* Bit 8: I2C Module 8 Run Mode Clock Gating Control */ +# define SYSCON_RCGCI2C_R9 (1 << 9) /* Bit 9: I2C Module 9 Run Mode Clock Gating Control */ + +/* USB Run Mode Clock Gating Control */ + +#define SYSCON_RCGCUSB_R0 (1 << 0) /* Bit 0: USB Module Run Mode Clock Gating Control */ + +/* Ethernet PHY Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEPHY_R0 (1 << 0) /* Bit 0: Ethernet PHY Module Run Mode Clock Gating Control */ + +/* CAN RunMode Clock Gating Control */ + +#define SYSCON_RCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Run Mode Clock Gating Control */ + +/* ADC Run Mode Clock Gating Control */ + +#define SYSCON_RCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Run Mode Clock Gating Control */ + +/* ACMP Run Mode Clock Gating Control */ + +#define SYSCON_RCGCACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Run Mode Clock Gating Control */ + +/* PWM Run Mode Clock Gating Control */ + +#define SYSCON_RCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Run Mode Clock Gating Control */ + +/* QE Interface Run Mode Clock Gating Control */ + +#define SYSCON_RCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Run Mode Clock Gating Control */ + +/* EEPROM Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEEPROM_R0 (1 << 0) /* Bit 0: EEPROM Module Run Mode Clock Gating Control */ + +/* 32/64-Bit Wide Timer Run Mode Clock Gating Control */ + +#define SYSCON_RCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide Timer n Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide Timer 0 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide Timer 1 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide Timer 2 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide Timer 3 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide Timer 4 Run Mode Clock Gating Control */ +# define SYSCON_RCGCWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide Timer 5 Run Mode Clock Gating Control */ + +/* CRC/Crypto Modules RunMode ClockGating Control */ + +#define SYSCON_RCGCCCM_R0 (1 << 0) /* Bit 0: CRC and Cryptographic Modules Run Mode Clock Gating Control */ + +/* LCD Controller Run Mode Clock Gating Control */ + +#define SYSCON_RCGCLCD_R0 (1 << 0) /* Bit 0: LCD Controller Module 0 Run Mode Clock Gating Control */ + +/* 1-Wire Run Mode Clock Gating Control */ + +#define SYSCON_RCGCOWIRE_R0 (1 << 0) /* Bit 0: 1-Wire Module 0 Run Mode Clock Gating Control */ + +/* Ethernet MAC Run Mode Clock Gating Control */ + +#define SYSCON_RCGCEMAC_R0 (1 << 0) /* Bit 0: Ethernet MAC Module 0 Run Mode Clock Gating Control */ + +/* Watchdog Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: Watchdog Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: Watchdog Timer 1 Sleep Mode Clock Gating Control */ + +/* 16/32-Bit Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWD(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S1 (1 << 1) /* Bit 1: 16/32-Bit Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S2 (1 << 2) /* Bit 2: 16/32-Bit Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S3 (1 << 3) /* Bit 3: 16/32-Bit Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S4 (1 << 4) /* Bit 4: 16/32-Bit Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S5 (1 << 5) /* Bit 5: 16/32-Bit Timer 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S6 (1 << 6) /* Bit 6: 16/32-Bit Timer 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWD_S7 (1 << 7) /* Bit 7: 16/32-Bit Timer 7 Sleep Mode Clock Gating Control */ + +/* GPIO Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S0 (1 << 0) /* Bit 0: GPIO Port A Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S1 (1 << 1) /* Bit 1: GPIO Port B Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S2 (1 << 2) /* Bit 2: GPIO Port C Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S3 (1 << 3) /* Bit 3: GPIO Port D Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S4 (1 << 4) /* Bit 4: GPIO Port E Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S5 (1 << 5) /* Bit 5: GPIO Port F Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S6 (1 << 6) /* Bit 6: GPIO Port G Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S7 (1 << 7) /* Bit 7: GPIO Port H Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S8 (1 << 8) /* Bit 8: GPIO Port J Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S9 (1 << 9) /* Bit 9: GPIO Port K Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S10 (1 << 10) /* Bit 10: GPIO Port L Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S11 (1 << 11) /* Bit 11: GPIO Port M Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S12 (1 << 12) /* Bit 12: GPIO Port N Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S13 (1 << 13) /* Bit 13: GPIO Port P Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S14 (1 << 14) /* Bit 14: GPIO Port Q Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S15 (1 << 15) /* Bit 15: GPIO Port R Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S16 (1 << 16) /* Bit 16: GPIO Port S Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCGPIO_S17 (1 << 17) /* Bit 17: GPIO Port T Sleep Mode Clock Gating Control */ + +/* μDMA Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCDMA_S0 (1 << 0) /* Bit 0: μDMA Module Sleep Mode Clock Gating Control */ + +/* EPI Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEPI_S0 (1 << 0) /* Bit 0: EPI Module Sleep Mode Clock Gating Control */ + +/* Hibernation Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCHIB_S0 (1 << 0) /* Bit 0: Hibernation Module Sleep Mode Clock Gating Control */ + +/* UART Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUART(n) (1 << (n)) /* Bit n: UART Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S0 (1 << 0) /* Bit 0: UART Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S1 (1 << 1) /* Bit 1: UART Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S2 (1 << 2) /* Bit 2: UART Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S3 (1 << 3) /* Bit 3: UART Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S4 (1 << 4) /* Bit 4: UART Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S5 (1 << 5) /* Bit 5: UART Module 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S6 (1 << 6) /* Bit 6: UART Module 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCUART_S7 (1 << 7) /* Bit 7: UART Module 7 Sleep Mode Clock Gating Control */ + +/* SSI Sleep Mode Clock GatingControl */ + +#define SYSCON_SCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S0 (1 << 0) /* Bit 0: SSI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S1 (1 << 1) /* Bit 1: SSI Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S2 (1 << 2) /* Bit 2: SSI Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCSSI_S3 (1 << 3) /* Bit 3: SSI Module 3 Sleep Mode Clock Gating Control */ + +/* I2C Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S0 (1 << 0) /* Bit 0: I2C Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S1 (1 << 1) /* Bit 1: I2C Module 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S2 (1 << 2) /* Bit 2: I2C Module 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S3 (1 << 3) /* Bit 3: I2C Module 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S4 (1 << 4) /* Bit 4: I2C Module 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S5 (1 << 5) /* Bit 5: I2C Module 5 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S6 (1 << 6) /* Bit 6: I2C Module 6 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S7 (1 << 7) /* Bit 7: I2C Module 7 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S8 (1 << 8) /* Bit 8: I2C Module 8 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCI2C_S9 (1 << 9) /* Bit 9: I2C Module 9 Sleep Mode Clock Gating Control */ + +/* USB Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCUSB_S0 (1 << 0) /* Bit 0: USB Module Sleep Mode Clock Gating Control */ + +/* Ethernet PHY Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEPHY_S0 (1 << 0) /* Bit 0: PHY Module Sleep Mode Clock Gating Control */ + +/* CAN Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S0 (1 << 0) /* Bit 0: CAN Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCCAN_S1 (1 << 1) /* Bit 1: CAN Module 1 Sleep Mode Clock Gating Control */ + +/* ADC Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S0 (1 << 0) /* Bit 0: ADC Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCADC_S1 (1 << 1) /* Bit 1: ADC Module 1 Sleep Mode Clock Gating Control */ + +/* ACMP Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCACMP_S0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Sleep Mode Clock Gating Control */ + +/* PulseWidthModulator Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S0 (1 << 0) /* Bit 0: PWM Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCPWM_S1 (1 << 1) /* Bit 1: PWM Module 1 Sleep Mode Clock Gating Control */ + +/* QE Interface Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S0 (1 << 0) /* Bit 0: QEI Module 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCQEI_S1 (1 << 1) /* Bit 1: QEI Module 1 Sleep Mode Clock Gating Control */ + +/* EEPROM Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEEPROM_S0 (1 << 0) /* Bit 0: EEPROM Module Sleep Mode Clock Gating Control */ + +/* 32/64-Bit Wide Timer Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide Timer n Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S0 (1 << 0) /* Bit 0: 32/64-Bit Wide Timer 0 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S1 (1 << 1) /* Bit 1: 32/64-Bit Wide Timer 1 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S2 (1 << 2) /* Bit 2: 32/64-Bit Wide Timer 2 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S3 (1 << 3) /* Bit 3: 32/64-Bit Wide Timer 3 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S4 (1 << 4) /* Bit 4: 32/64-Bit Wide Timer 4 Sleep Mode Clock Gating Control */ +# define SYSCON_SCGCWTIMER_S5 (1 << 5) /* Bit 5: 32/64-Bit Wide Timer 5 Sleep Mode Clock Gating Control */ + +/* CRC/Crypto Modules Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCCCM_S0 (1 << 0) /* Bit 0: CRC and Cryptographic Modules Sleep Mode Clock Gating Control */ + +/* LCD Controller Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCLCD_S0 (1 << 0) /* Bit 0: LCD Controller Module 0 Sleep Mode Clock Gating Control */ + +/* 1-Wire Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCOWIRE_S0 (1 << 0) /* Bit 0: 1-Wire Module 0 Sleep Mode Clock Gating Control */ + +/* Ethernet MAC Sleep Mode Clock Gating Control */ + +#define SYSCON_SCGCEMAC_S0 (1 << 0) /* Bit 0: Ethernet MAC Module 0 Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Deep-SleepMode Clock Gating Control */ + +#define SYSCON_DCGCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D0 (1 << 0) /* Bit 0: Watchdog Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWD_D1 (1 << 1) /* Bit 1: Watchdog Timer 1 Deep-Sleep Mode Clock Gating Control */ + +/* 16/32-Bit Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D1 (1 << 1) /* Bit 1: 16/32-Bit Timer 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D2 (1 << 2) /* Bit 2: 16/32-Bit Timer 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D3 (1 << 3) /* Bit 3: 16/32-Bit Timer 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D4 (1 << 4) /* Bit 4: 16/32-Bit Timer 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D5 (1 << 5) /* Bit 5: 16/32-Bit Timer 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D6 (1 << 6) /* Bit 6: 16/32-Bit Timer 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCTIMER_D7 (1 << 7) /* Bit 7: 16/32-Bit Timer 7 Deep-Sleep Mode Clock Gating Control */ + +/* GPIO Deep-Sleep Mode Clock */ + +#define SYSCON_DCGCGPIO(n) (1 << (n)) /* Bit n: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D0 (1 << 0) /* Bit 0: GPIO Port A Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D1 (1 << 1) /* Bit 1: GPIO Port B Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D2 (1 << 2) /* Bit 2: GPIO Port C Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D3 (1 << 3) /* Bit 3: GPIO Port D Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D4 (1 << 4) /* Bit 4: GPIO Port E Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D5 (1 << 5) /* Bit 5: GPIO Port F Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D6 (1 << 6) /* Bit 6: GPIO Port G Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D7 (1 << 7) /* Bit 7: GPIO Port H Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D8 (1 << 8) /* Bit 8: GPIO Port J Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D9 (1 << 9) /* Bit 9: GPIO Port K Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D10 (1 << 10) /* Bit 10: GPIO Port L Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D11 (1 << 11) /* Bit 11: GPIO Port M Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D12 (1 << 12) /* Bit 12: GPIO Port N Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D13 (1 << 13) /* Bit 13: GPIO Port P Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D14 (1 << 14) /* Bit 14: GPIO Port Q Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D15 (1 << 15) /* Bit 15: GPIO Port R Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D16 (1 << 16) /* Bit 16: GPIO Port S Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCGPIO_D17 (1 << 17) /* Bit 17: GPIO Port T Deep-Sleep Mode Clock Gating Control */ + +/* μDMA Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCDMA_D0 (1 << 0) /* Bit 0: μDMA Module Deep-Sleep Mode Clock Gating Control */ + +/* EPI Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEPI_D0 (1 << 0) /* Bit 0: EPI Module Deep-Sleep Mode Clock Gating Control */ + +/* Hibernation Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCHIB_D0 (1 << 0) /* Bit 0: Hibernation Module Deep-Sleep Mode Clock Gating Control */ + +/* UART Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUART(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D6 (1 << 6) /* Bit 6: UART Module 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCUART_D7 (1 << 7) /* Bit 7: UART Module 7 Deep-Sleep Mode Clock Gating Control */ + +/* SSI Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCSSI(n) (1 << (n)) /* Bit n: SSI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D0 (1 << 0) /* Bit 0: SSI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D1 (1 << 1) /* Bit 1: SSI Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D2 (1 << 2) /* Bit 2: SSI Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCSSI_D3 (1 << 3) /* Bit 3: SSI Module 3 Deep-Sleep Mode Clock Gating Control */ + +/* I2C Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCI2C(n) (1 << (n)) /* Bit n: I2C Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D0 (1 << 0) /* Bit 0: I2C Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D1 (1 << 1) /* Bit 1: I2C Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D2 (1 << 2) /* Bit 2: I2C Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D3 (1 << 3) /* Bit 3: I2C Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D4 (1 << 4) /* Bit 4: I2C Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D5 (1 << 5) /* Bit 5: I2C Module 5 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D6 (1 << 6) /* Bit 6: I2C Module 6 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D7 (1 << 7) /* Bit 7: I2C Module 7 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D8 (1 << 8) /* Bit 8: I2C Module 8 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCI2C_D9 (1 << 9) /* Bit 9: I2C Module 9 Deep-Sleep Mode Clock Gating Control */ + +/* USB Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCUSB_D0 (1 << 0) /* Bit 0: USB Module Deep-Sleep Mode Clock Gating Control */ + +/* Ethernet PHY Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEPHY_D0 (1 << 0) /* Bit 0: PHY Module Deep-Sleep Mode Clock Gating Control */ + +/* CAN Deep-SleepMode Clock Gating Control */ + +#define SYSCON_DCGCCAN(n) (1 << (n)) /* Bit n: CAN Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D0 (1 << 0) /* Bit 0: CAN Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCCAN_D1 (1 << 1) /* Bit 1: CAN Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* ADC Deep-Sleep Mode ClockGating Control */ + +#define SYSCON_DCGCADC(n) (1 << (n)) /* Bit n: ADC Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D0 (1 << 0) /* Bit 0: ADC Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCADC_D1 (1 << 1) /* Bit 1: ADC Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* ACMP Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCACMP_D0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* PWM Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCPWM(n) (1 << (n)) /* Bit n: PWM Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D0 (1 << 0) /* Bit 0: PWM Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCPWM_D1 (1 << 1) /* Bit 1: PWM Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* QE Interface Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCQEI(n) (1 << (n)) /* Bit n: QEI Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D0 (1 << 0) /* Bit 0: QEI Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCQEI_D1 (1 << 1) /* Bit 1: QEI Module 1 Deep-Sleep Mode Clock Gating Control */ + +/* EEPROM Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEEPROM_D0 (1 << 0) /* Bit 0: EEPROM Module Deep-Sleep Mode Clock Gating Control */ + +/* 32/64-Bit Wide Timer Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCWTIMER(n) (1 << (n)) /* Bit n: UART Module n Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D0 (1 << 0) /* Bit 0: UART Module 0 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D1 (1 << 1) /* Bit 1: UART Module 1 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D2 (1 << 2) /* Bit 2: UART Module 2 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D3 (1 << 3) /* Bit 3: UART Module 3 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D4 (1 << 4) /* Bit 4: UART Module 4 Deep-Sleep Mode Clock Gating Control */ +# define SYSCON_DCGCWTIMER_D5 (1 << 5) /* Bit 5: UART Module 5 Deep-Sleep Mode Clock Gating Control */ + +/* CRC/Crypto Modules Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCCCM_D0 (1 << 0) /* Bit 0: CRC and Cryptographic Modules Deep-Sleep Mode Clock Gating Control */ + +/* LCD Controller Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCLCD_D0 (1 << 0) /* Bit 0: LCD Controller Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* 1-Wire Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCOWIRE_D0 (1 << 0) /* Bit 0: 1-Wire Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* Ethernet MAC Deep-Sleep Mode Clock Gating Control */ + +#define SYSCON_DCGCEMAC_D0 (1 << 0) /* Bit 0: Ethernet MAC Module 0 Deep-Sleep Mode Clock Gating Control */ + +/* Watchdog Timer Power Control */ + +#define SYSCON_PCWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Power Control */ +# define SYSCON_PCWD_P0 (1 << 0) /* Bit 0: Watchdog Timer 0 Power Control */ +# define SYSCON_PCWD_P1 (1 << 1) /* Bit 1: Watchdog Timer 1 Power Control */ + +/* 16/32-Bit Timer Power Control */ + +#define SYSCON_PCTIMER(n) (1 << (n)) /* Bit n: Timer n Power Control */ +# define SYSCON_PCTIMER_P7 (1 << 0) /* Bit 0: Timer 0 Power Control */ +# define SYSCON_PCTIMER_P6 (1 << 1) /* Bit 1: Timer 1 Power Control */ +# define SYSCON_PCTIMER_P5 (1 << 2) /* Bit 2: Timer 2 Power Control */ +# define SYSCON_PCTIMER_P4 (1 << 3) /* Bit 3: Timer 3 Power Control */ +# define SYSCON_PCTIMER_P3 (1 << 4) /* Bit 4: Timer 4 Power Control */ +# define SYSCON_PCTIMER_P2 (1 << 5) /* Bit 5: Timer 5 Power Control */ +# define SYSCON_PCTIMER_P1 (1 << 6) /* Bit 6: Timer 6 Power Control */ +# define SYSCON_PCTIMER_P0 (1 << 7) /* Bit 7: Timer 7 Power Control */ + +/* GPIO Power Control */ + +#define SYSCON_PCGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Power Control */ +# define SYSCON_PCGPIO_P0 (1 << 0) /* Bit 0: GPIO Port A Power Control */ +# define SYSCON_PCGPIO_P1 (1 << 1) /* Bit 1: GPIO Port B Power Control */ +# define SYSCON_PCGPIO_P2 (1 << 2) /* Bit 2: GPIO Port C Power Control */ +# define SYSCON_PCGPIO_P3 (1 << 3) /* Bit 3: GPIO Port D Power Control */ +# define SYSCON_PCGPIO_P4 (1 << 4) /* Bit 4: GPIO Port E Power Control */ +# define SYSCON_PCGPIO_P5 (1 << 5) /* Bit 5: GPIO Port F Power Control */ +# define SYSCON_PCGPIO_P6 (1 << 6) /* Bit 6: GPIO Port G Power Control */ +# define SYSCON_PCGPIO_P7 (1 << 7) /* Bit 7: GPIO Port H Power Control */ +# define SYSCON_PCGPIO_P8 (1 << 8) /* Bit 8: GPIO Port J Power Control */ +# define SYSCON_PCGPIO_P9 (1 << 9) /* Bit 9: GPIO Port K Power Control */ +# define SYSCON_PCGPIO_P10 (1 << 10) /* Bit 10: GPIO Port L Power Control */ +# define SYSCON_PCGPIO_P11 (1 << 11) /* Bit 11: GPIO Port M Power Control */ +# define SYSCON_PCGPIO_P12 (1 << 12) /* Bit 12: GPIO Port N Power Control */ +# define SYSCON_PCGPIO_P13 (1 << 13) /* Bit 13: GPIO Port P Power Control */ +# define SYSCON_PCGPIO_P14 (1 << 14) /* Bit 14: GPIO Port Q Power Control */ +# define SYSCON_PCGPIO_P15 (1 << 15) /* Bit 15: GPIO Port R Power Control */ +# define SYSCON_PCGPIO_P16 (1 << 16) /* Bit 16: GPIO Port S Power Control */ +# define SYSCON_PCGPIO_P17 (1 << 17) /* Bit 17: GPIO Port T Power Control */ + +/* μDMA Power Control */ + +#define SYSCON_PCDMA_P0 (1 << 0) /* Bit 0: uDMA Module Power Control */ + +/* External Peripheral Interface Power Control */ + +#define SYSCON_PCEPI_P0 (1 << 0) /* Bit 0: EPI Module Power Control */ + +/* Hibernation Power Control */ + +#define SYSCON_PCHIB_P0 (1 << 0) /* Bit 0: Hibernation Module Power Control */ + +/* UART Power Control */ + +#define SYSCON_PCUART(n) (1 << (n)) /* Bit n: UART Module n Power Control */ +# define SYSCON_PCUART_P0 (1 << 0) /* Bit 0: UART Module 0 Power Control */ +# define SYSCON_PCUART_P1 (1 << 1) /* Bit 1: UART Module 1 Power Control */ +# define SYSCON_PCUART_P2 (1 << 2) /* Bit 2: UART Module 2 Power Control */ +# define SYSCON_PCUART_P3 (1 << 3) /* Bit 3: UART Module 3 Power Control */ +# define SYSCON_PCUART_P4 (1 << 4) /* Bit 4: UART Module 4 Power Control */ +# define SYSCON_PCUART_P5 (1 << 5) /* Bit 5: UART Module 5 Power Control */ +# define SYSCON_PCUART_P6 (1 << 6) /* Bit 6: UART Module 6 Power Control */ +# define SYSCON_PCUART_P7 (1 << 7) /* Bit 7: UART Module 7 Power Control */ + +/* SSI Power Control */ + +#define SYSCON_PCSSI(n) (1 << (n)) /* Bit n: SSI Module n Power Control */ +# define SYSCON_PCSSI_P0 (1 << 0) /* Bit 0: SSI Module 0 Power Control */ +# define SYSCON_PCSSI_P1 (1 << 1) /* Bit 1: SSI Module 1 Power Control */ +# define SYSCON_PCSSI_P2 (1 << 2) /* Bit 2: SSI Module 2 Power Control */ +# define SYSCON_PCSSI_P3 (1 << 3) /* Bit 3: SSI Module 3 Power Control */ + +/* I2C Power Control */ + +#define SYSCON_PCI2C(n) (1 << (n)) /* Bit n: I2C Module n Power Control */ +# define SYSCON_PCI2C_P0 (1 << 0) /* Bit 0: I2C Module 0 Power Control */ +# define SYSCON_PCI2C_P1 (1 << 1) /* Bit 1: I2C Module 1 Power Control */ +# define SYSCON_PCI2C_P2 (1 << 2) /* Bit 2: I2C Module 2 Power Control */ +# define SYSCON_PCI2C_P3 (1 << 3) /* Bit 3: I2C Module 3 Power Control */ +# define SYSCON_PCI2C_P4 (1 << 4) /* Bit 4: I2C Module 4 Power Control */ +# define SYSCON_PCI2C_P5 (1 << 5) /* Bit 5: I2C Module 5 Power Control */ +# define SYSCON_PCI2C_P6 (1 << 6) /* Bit 6: I2C Module 6 Power Control */ +# define SYSCON_PCI2C_P7 (1 << 7) /* Bit 7: I2C Module 7 Power Control */ +# define SYSCON_PCI2C_P8 (1 << 8) /* Bit 8: I2C Module 8 Power Control */ +# define SYSCON_PCI2C_P9 (1 << 9) /* Bit 9: I2C Module 9 Power Control */ + +/* USB Power Control */ + +#define SYSCON_PCUSB_P0 (1 << 0) /* Bit 0: USB Module Power Control */ + +/* Ethernet PHY Power Control */ + +#define SYSCON_PCEPHY_P0 (1 << 0) /* Bit 0: Ethernet PHY Module Power Control */ + +/* CAN Power Control */ + +#define SYSCON_PCCAN(n) (1 << (n)) /* Bit n: CAN Module n Power Control */ +# define SYSCON_PCCAN_P0 (1 << 0) /* Bit 0: CAN Module 0 Power Control */ +# define SYSCON_PCCAN_P1 (1 << 1) /* Bit 1: CAN Module 1 Power Control */ + +/* ADC Power Control */ + +#define SYSCON_PCADC(n) (1 << (n)) /* Bit n: ADC Module n Power Control */ +# define SYSCON_PCADC_P0 (1 << 0) /* Bit 0: ADC Module 0 Power Control */ +# define SYSCON_PCADC_P1 (1 << 1) /* Bit 1: ADC Module 1 Power Control */ + +/* ACMP Power Control */ + +#define SYSCON_PCACMP_P0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Power Control */ + +/* PWM Power Control */ + +#define SYSCON_PCPWM_P0 (1 << 0) /* Bit 0: PWM Module 0 Power Control */ + +/* QE Interface Power Control */ + +#define SYSCON_PCQEI_P0 (1 << 0) /* Bit 0: QEI Module 0 Power Control */ + +/* EEPROM Power Control */ + +#define SYSCON_PCEEPROM_P0 (1 << 0) /* Bit 0: EEPROM Module 0 Power Control */ + +/* CRC/Crypto Modules Power Control */ + +#define SYSCON_PCCCM_P0 (1 << 0) /* Bit 0: CRC and Cryptographic Modules Power Control */ + +/* LCD Controller Power Control */ + +#define SYSCON_PCLCD_P0 (1 << 0) /* Bit 0: LCD Controller Module 0 Power Control */ + +/* 1-Wire Power Control */ + +#define SYSCON_PCOWIRE_P0 (1 << 0) /* Bit 0: 1-Wire Module 0 Power Control */ + +/* Ethernet MAC Power Control */ + +#define SYSCON_PCEMAC_P0 (1 << 0) /* Bit 0: Ethernet MAC Module 0 Power Control */ + +/* Watchdog Timer Peripheral Ready */ + +#define SYSCON_PRWD(n) (1 << (n)) /* Bit n: Watchdog Timer n Peripheral Ready */ +# define SYSCON_PRWD_R0 (1 << 0) /* Bit 0: Watchdog Timer 0 Peripheral Ready */ +# define SYSCON_PRWD_R1 (1 << 1) /* Bit 1: Watchdog Timer 1 Peripheral Ready */ + +/* 16/32-Bit Timer Peripheral Ready */ + +#define SYSCON_PRTIMER(n) (1 << (n)) /* Bit n: 16/32-Bit Timer n Peripheral Ready */ +# define SYSCON_PRTIMER_R0 (1 << 0) /* Bit 0: 16/32-Bit Timer 0 Peripheral Ready */ +# define SYSCON_PRTIMER_R1 (1 << 1) /* Bit 1: 16/32-Bit Timer 1 Peripheral Ready */ +# define SYSCON_PRTIMER_R2 (1 << 2) /* Bit 2: 16/32-Bit Timer 2 Peripheral Ready */ +# define SYSCON_PRTIMER_R3 (1 << 3) /* Bit 3: 16/32-Bit Timer 3 Peripheral Ready */ +# define SYSCON_PRTIMER_R4 (1 << 4) /* Bit 4: 16/32-Bit Timer 4 Peripheral Ready */ +# define SYSCON_PRTIMER_R5 (1 << 5) /* Bit 5: 16/32-Bit Timer 5 Peripheral Ready */ +# define SYSCON_PRTIMER_R6 (1 << 6) /* Bit 6: 16/32-Bit Timer 6 Peripheral Ready */ +# define SYSCON_PRTIMER_R7 (1 << 7) /* Bit 7: 16/32-Bit Timer 7 Peripheral Ready */ + +/* GPIO Peripheral Ready */ + +#define SYSCON_PRGPIO(n) (1 << (n)) /* Bit n: GPIO Port n Peripheral Ready */ +# define SYSCON_PRGPIO_R0 (1 << 0) /* Bit 0: GPIO Port A Peripheral Ready */ +# define SYSCON_PRGPIO_R1 (1 << 1) /* Bit 1: GPIO Port B Peripheral Ready */ +# define SYSCON_PRGPIO_R2 (1 << 2) /* Bit 2: GPIO Port C Peripheral Ready */ +# define SYSCON_PRGPIO_R3 (1 << 3) /* Bit 3: GPIO Port D Peripheral Ready */ +# define SYSCON_PRGPIO_R4 (1 << 4) /* Bit 4: GPIO Port E Peripheral Ready */ +# define SYSCON_PRGPIO_R5 (1 << 5) /* Bit 5: GPIO Port F Peripheral Ready */ +# define SYSCON_PRGPIO_R6 (1 << 6) /* Bit 6: GPIO Port G Peripheral Ready */ +# define SYSCON_PRGPIO_R7 (1 << 7) /* Bit 7: GPIO Port H Peripheral Ready */ +# define SYSCON_PRGPIO_R8 (1 << 8) /* Bit 8: GPIO Port J Peripheral Ready */ +# define SYSCON_PRGPIO_R9 (1 << 9) /* Bit 9: GPIO Port K Peripheral Ready */ +# define SYSCON_PRGPIO_R10 (1 << 10) /* Bit 10: GPIO Port L Peripheral Ready */ +# define SYSCON_PRGPIO_R11 (1 << 11) /* Bit 11: GPIO Port M Peripheral Ready */ +# define SYSCON_PRGPIO_R12 (1 << 12) /* Bit 12: GPIO Port N Peripheral Ready */ +# define SYSCON_PRGPIO_R13 (1 << 13) /* Bit 13: GPIO Port P Peripheral Ready */ +# define SYSCON_PRGPIO_R14 (1 << 14) /* Bit 14: GPIO Port Q Peripheral Ready */ +# define SYSCON_PRGPIO_R15 (1 << 15) /* Bit 15: GPIO Port R Peripheral Ready */ +# define SYSCON_PRGPIO_R16 (1 << 16) /* Bit 16: GPIO Port S Peripheral Ready */ +# define SYSCON_PRGPIO_R17 (1 << 17) /* Bit 17: GPIO Port T Peripheral Ready */ + +/* μDMA Peripheral Ready */ + +#define SYSCON_PRDMA_R0 (1 << 0) /* Bit 0: μDMA Module Peripheral Ready */ + +/* EPI Peripheral Ready */ + +#define SYSCON_PREPI_R0 (1 << 0) /* Bit 0: EPI Module Peripheral Ready */ + +/* Hibernation Peripheral Ready */ + +#define SYSCON_PRHIB_R0 (1 << 0) /* Bit 0: Hibernation Module Peripheral Ready */ + +/* UART Peripheral Ready */ + +#define SYSCON_PRUART(n) (1 << (n)) /* Bit n: UART Module n Peripheral Ready */ +# define SYSCON_PRUART_R0 (1 << 0) /* Bit 0: UART Module 0 Peripheral Ready */ +# define SYSCON_PRUART_R1 (1 << 1) /* Bit 1: UART Module 1 Peripheral Ready */ +# define SYSCON_PRUART_R2 (1 << 2) /* Bit 2: UART Module 2 Peripheral Ready */ +# define SYSCON_PRUART_R3 (1 << 3) /* Bit 3: UART Module 3 Peripheral Ready */ +# define SYSCON_PRUART_R4 (1 << 4) /* Bit 4: UART Module 4 Peripheral Ready */ +# define SYSCON_PRUART_R5 (1 << 5) /* Bit 5: UART Module 5 Peripheral Ready */ +# define SYSCON_PRUART_R6 (1 << 6) /* Bit 6: UART Module 6 Peripheral Ready */ +# define SYSCON_PRUART_R7 (1 << 7) /* Bit 7: UART Module 7 Peripheral Ready */ + +/* SSI Peripheral Ready */ + +#define SYSCON_PRSSI(n) (1 << (n)) /* Bit n: SSI Module n Peripheral Ready */ +# define SYSCON_PRSSI_R0 (1 << 0) /* Bit 0: SSI Module 0 Peripheral Ready */ +# define SYSCON_PRSSI_R1 (1 << 1) /* Bit 1: SSI Module 1 Peripheral Ready */ +# define SYSCON_PRSSI_R2 (1 << 2) /* Bit 2: SSI Module 2 Peripheral Ready */ +# define SYSCON_PRSSI_R3 (1 << 3) /* Bit 3: SSI Module 3 Peripheral Ready */ + +/* I2C Peripheral Ready */ + +#define SYSCON_PRI2C(n) (1 << (n)) /* Bit n: I2C Module n Peripheral Ready */ +# define SYSCON_PRI2C_R0 (1 << 0) /* Bit 0: I2C Module 0 Peripheral Ready */ +# define SYSCON_PRI2C_R1 (1 << 1) /* Bit 1: I2C Module 1 Peripheral Ready */ +# define SYSCON_PRI2C_R2 (1 << 2) /* Bit 2: I2C Module 2 Peripheral Ready */ +# define SYSCON_PRI2C_R3 (1 << 3) /* Bit 3: I2C Module 3 Peripheral Ready */ +# define SYSCON_PRI2C_R4 (1 << 4) /* Bit 4: I2C Module 4 Peripheral Ready */ +# define SYSCON_PRI2C_R5 (1 << 5) /* Bit 5: I2C Module 5 Peripheral Ready */ +# define SYSCON_PRI2C_R6 (1 << 6) /* Bit 6: I2C Module 5 Peripheral Ready */ +# define SYSCON_PRI2C_R7 (1 << 7) /* Bit 7: I2C Module 5 Peripheral Ready */ +# define SYSCON_PRI2C_R8 (1 << 8) /* Bit 8: I2C Module 5 Peripheral Ready */ +# define SYSCON_PRI2C_R9 (1 << 9) /* Bit 9: I2C Module 5 Peripheral Ready */ + +/* USB Peripheral Ready */ + +#define SYSCON_PRUSB_R0 (1 << 0) /* Bit 0: USB Module Peripheral Ready */ + +/* Ethernet PHY Peripheral Ready */ + +#define SYSCON_PREPHY_R0 (1 << 0) /* Bit 0: Ethernet PHY Module Peripheral Ready */ + +/* CAN Peripheral Ready */ + +#define SYSCON_PRCAN(n) (1 << (n)) /* Bit n: CAN Module n Peripheral Ready */ +# define SYSCON_PRCAN_R0 (1 << 0) /* Bit 0: CAN Module 0 Peripheral Ready */ +# define SYSCON_PRCAN_R1 (1 << 1) /* Bit 1: CAN Module 1 Peripheral Ready */ + +/* ADC Peripheral Ready */ + +#define SYSCON_PRADC(n) (1 << (n)) /* Bit n: ADC Module n Peripheral Ready */ +# define SYSCON_PRADC_R0 (1 << 0) /* Bit 0: ADC Module 0 Peripheral Ready */ +# define SYSCON_PRADC_R1 (1 << 1) /* Bit 1: ADC Module 1 Peripheral Ready */ + +/* ACMP Peripheral Ready */ + +#define SYSCON_PRACMP_R0 (1 << 0) /* Bit 0: Analog Comparator Module 0 Peripheral Ready */ + +/* PWM Peripheral Ready */ + +#define SYSCON_PRPWM(n) (1 << (n)) /* Bit n: PWM Module n Peripheral Ready */ +# define SYSCON_PRPWM_R0 (1 << 0) /* Bit 0: PWM Module 0 Peripheral Ready */ +# define SYSCON_PRPWM_R1 (1 << 1) /* Bit 1: PWM Module 1 Peripheral Ready */ + +/* QE Interface Peripheral Ready */ + +#define SYSCON_PRQEI(n) (1 << (n)) /* Bit n: QEI Module n Peripheral Ready */ +# define SYSCON_PRQEI_R0 (1 << 0) /* Bit 0: QEI Module 0 Peripheral Ready */ +# define SYSCON_PRQEI_R1 (1 << 1) /* Bit 1: QEI Module 1 Peripheral Ready */ + +/* EEPROM Peripheral Ready */ + +#define SYSCON_PREEPROM_0 (1 << 0) /* Bit 0: EEPROM Module Peripheral Ready */ + +/* 32/64-Bit Wide Timer Peripheral Ready */ + +#define SYSCON_PRWTIMER(n) (1 << (n)) /* Bit n: 32/64-Bit Wide Timer n Peripheral Ready */ +# define SYSCON_PRWTIMER_R0 (1 << 0) /* Bit 0: 32/64-Bit Wide Timer 0 Peripheral Ready */ +# define SYSCON_PRWTIMER_R1 (1 << 1) /* Bit 1: 32/64-Bit Wide Timer 1 Peripheral Ready */ +# define SYSCON_PRWTIMER_R2 (1 << 2) /* Bit 2: 32/64-Bit Wide Timer 2 Peripheral Ready */ +# define SYSCON_PRWTIMER_R3 (1 << 3) /* Bit 3: 32/64-Bit Wide Timer 3 Peripheral Ready */ +# define SYSCON_PRWTIMER_R4 (1 << 4) /* Bit 4: 32/64-Bit Wide Timer 4 Peripheral Ready */ +# define SYSCON_PRWTIMER_R5 (1 << 5) /* Bit 5: 32/64-Bit Wide Timer 5 Peripheral Ready */ + +/* CRC/Crypto Modules Peripheral Ready */ + +#define SYSCON_PRCCM_R0 (1 << 0) /* Bit 0: CRC and Cryptographic Modules Peripheral Ready */ + +/* LCD Controller Peripheral Ready */ + +#define SYSCON_PRLCD_R0 (1 << 0) /* Bit 0: LCD Controller Module 0 Peripheral Ready */ + +/* 1-Wire Peripheral Ready */ + +#define SYSCON_PROWIRE_R0 (1 << 0) /* Bit 0: 1-Wire Module 0 Peripheral Ready */ + +/* Ethernet MAC Peripheral Ready */ + +#define SYSCON_PREMAC_R0 (1 << 0) /* Bit 0: Ethernet MAC Module 0 Peripheral Ready */ + +/* Unique ID 0-3: 32-bit values */ + +/* CCM System Control Registers (CCM Control Offset) */ + +/* Cryptographic Modules Clock Gating Request */ + +#define SYSCON_CCMCGREQ_SHACFG (1 << 0) /* Bit 0: SHA/MD5 Clock Gating Request */ +#define SYSCON_CCMCGREQ_AESCFG (1 << 1) /* Bit 1: AES Clock Gating Request */ +#define SYSCON_CCMCGREQ_DESCFG (1 << 2) /* Bit 2: DES Clock Gating Request */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TM4C129_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/chip/tm4c_ethernet.h b/arch/arm/src/tiva/chip/tm4c_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..af9d43ffbb90cd5aee03f6f18f0fef4cdd33035f --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c_ethernet.h @@ -0,0 +1,1390 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tm4c_ethernet.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Includes some register bit definitions provided by: + * + * Copyright (C) 2014 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C_ETHERNET_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C_ETHERNET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Ethernet Controller Register Offsets *********************************************/ + +/* Ethernet MAC Register Offsets */ + +#define TIVA_EMAC_CFG_OFFSET 0x0000 /* Ethernet MAC Configuration */ +#define TIVA_EMAC_FRAMEFLTR_OFFSET 0x0004 /* Ethernet MAC Frame Filter */ +#define TIVA_EMAC_HASHTBLH_OFFSET 0x0008 /* Ethernet MAC Hash Table High */ +#define TIVA_EMAC_HASHTBLL_OFFSET 0x000c /* Ethernet MAC Hash Table Low */ +#define TIVA_EMAC_MIIADDR_OFFSET 0x0010 /* Ethernet MAC MII Address */ +#define TIVA_EMAC_MIIDATA_OFFSET 0x0014 /* Ethernet MAC MII Data Register */ +#define TIVA_EMAC_FLOWCTL_OFFSET 0x0018 /* Ethernet MAC Flow Control */ +#define TIVA_EMAC_VLANTG_OFFSET 0x001c /* Ethernet MAC VLAN Tag */ +#define TIVA_EMAC_STATUS_OFFSET 0x0024 /* Ethernet MAC Status */ +#define TIVA_EMAC_RWUFF_OFFSET 0x0028 /* Ethernet MAC Remote Wake-Up Frame Filter */ +#define TIVA_EMAC_PMTCTLSTAT_OFFSET 0x002c /* Ethernet MAC PMT Control and Status Register */ +#define TIVA_EMAC_RIS_OFFSET 0x0038 /* Ethernet MAC Raw Interrupt Status */ +#define TIVA_EMAC_IM_OFFSET 0x003c /* Ethernet MAC Interrupt Mask */ +#define TIVA_EMAC_ADDR0H_OFFSET 0x0040 /* Ethernet MAC Address 0 High */ +#define TIVA_EMAC_ADDR0L_OFFSET 0x0044 /* Ethernet MAC Address 0 Low Register */ +#define TIVA_EMAC_ADDR1H_OFFSET 0x0048 /* Ethernet MAC Address 1 High */ +#define TIVA_EMAC_ADDR1L_OFFSET 0x004c /* Ethernet MAC Address 1 Low */ +#define TIVA_EMAC_ADDR2H_OFFSET 0x0050 /* Ethernet MAC Address 2 High */ +#define TIVA_EMAC_ADDR2L_OFFSET 0x0054 /* Ethernet MAC Address 2 Low */ +#define TIVA_EMAC_ADDR3H_OFFSET 0x0058 /* Ethernet MAC Address 3 High */ +#define TIVA_EMAC_ADDR3L_OFFSET 0x005c /* Ethernet MAC Address 3 Low */ +#define TIVA_EMAC_WDOGTO_OFFSET 0x00dc /* Ethernet MAC Watchdog Timeout */ + +#define TIVA_EMAC_MMCCTRL_OFFSET 0x0100 /* Ethernet MAC MMC Control */ +#define TIVA_EMAC_MMCRXRIS_OFFSET 0x0104 /* Ethernet MAC MMC Receive Raw Interrupt Status */ +#define TIVA_EMAC_MMCTXRIS_OFFSET 0x0108 /* Ethernet MAC MMC Transmit Raw Interrupt Status */ +#define TIVA_EMAC_MMCRXIM_OFFSET 0x010c /* Ethernet MAC MMC Receive Interrupt Mask */ +#define TIVA_EMAC_MMCTXIM_OFFSET 0x0110 /* Ethernet MAC MMC Transmit Interrupt Mask */ +#define TIVA_EMAC_TXCNTGB_OFFSET 0x0118 /* Ethernet MAC Transmit Frame Count for Good and Bad Frames */ +#define TIVA_EMAC_TXCNTSCOL_OFFSET 0x014c /* Ethernet MAC Transmit Frame Count for Frames Transmitted after Single Collision */ +#define TIVA_EMAC_TXCNTMCOL_OFFSET 0x0150 /* Ethernet MAC Transmit Frame Count for Frames Transmitted after Multiple Collisions */ +#define TIVA_EMAC_TXOCTCNTG_OFFSET 0x0164 /* Ethernet MAC Transmit Octet Count Good */ +#define TIVA_EMAC_RXCNTGB_OFFSET 0x0180 /* Ethernet MAC Receive Frame Count for Good and Bad Frames */ +#define TIVA_EMAC_RXCNTCRCERR_OFFSET 0x0194 /* Ethernet MAC Receive Frame Count for CRC Error Frames */ +#define TIVA_EMAC_RXCNTALGNERR_OFFSET 0x0198 /* Ethernet MAC Receive Frame Count for Alignment Error Frames */ +#define TIVA_EMAC_RXCNTGUNI_OFFSET 0x01c4 /* Ethernet MAC Receive Frame Count for Good Unicast Frames */ + +#define TIVA_EMAC_VLNINCREP_OFFSET 0x0584 /* Ethernet MAC VLAN Tag Inclusion or Replacement */ +#define TIVA_EMAC_VLANHASH_OFFSET 0x0588 /* Ethernet MAC VLAN Hash Table */ + +#define TIVA_EMAC_TIMSTCTRL_OFFSET 0x0700 /* Ethernet MAC Timestamp Control */ +#define TIVA_EMAC_SUBSECINC_OFFSET 0x0704 /* Ethernet MAC Sub-Second Increment */ +#define TIVA_EMAC_TIMSEC_OFFSET 0x0708 /* Ethernet MAC System Time - Seconds */ +#define TIVA_EMAC_TIMNANO_OFFSET 0x070c /* Ethernet MAC System Time - Nanoseconds */ +#define TIVA_EMAC_TIMSECU_OFFSET 0x0710 /* Ethernet MAC System Time - Seconds Update */ +#define TIVA_EMAC_TIMNANOU_OFFSET 0x0714 /* Ethernet MAC System Time - Nanoseconds Update */ +#define TIVA_EMAC_TIMADD_OFFSET 0x0718 /* Ethernet MAC Timestamp Addend */ +#define TIVA_EMAC_TARGSEC_OFFSET 0x071c /* Ethernet MAC Target Time Seconds */ +#define TIVA_EMAC_TARGNANO_OFFSET 0x0720 /* Ethernet MAC Target Time Nanoseconds */ +#define TIVA_EMAC_HWORDSEC_OFFSET 0x0724 /* Ethernet MAC System Time-Higher Word Seconds */ +#define TIVA_EMAC_TIMSTAT_OFFSET 0x0728 /* Ethernet MAC Timestamp Status */ +#define TIVA_EMAC_PPSCTRL_OFFSET 0x072c /* Ethernet MAC PPS Control */ +#define TIVA_EMAC_PPS0INTVL_OFFSET 0x0760 /* Ethernet MAC PPS0 Interval */ +#define TIVA_EMAC_PPS0WIDTH_OFFSET 0x0764 /* Ethernet MAC PPS0 Width */ + +#define TIVA_EMAC_DMABUSMOD_OFFSET 0x0c00 /* Ethernet MAC DMA Bus Mode */ +#define TIVA_EMAC_TXPOLLD_OFFSET 0x0c04 /* Ethernet MAC Transmit Poll Demand */ +#define TIVA_EMAC_RXPOLLD_OFFSET 0x0c08 /* Ethernet MAC Receive Poll Demand */ +#define TIVA_EMAC_RXDLADDR_OFFSET 0x0c0c /* Ethernet MAC Receive Descriptor List Address */ +#define TIVA_EMAC_TXDLADDR_OFFSET 0x0c10 /* Ethernet MAC Transmit Descriptor List Address */ +#define TIVA_EMAC_DMARIS_OFFSET 0x0c14 /* Ethernet MAC DMA Interrupt Status */ +#define TIVA_EMAC_DMAOPMODE_OFFSET 0x0c18 /* Ethernet MAC DMA Operation Mode */ +#define TIVA_EMAC_DMAIM_OFFSET 0x0c1c /* Ethernet MAC DMA Interrupt Mask Register */ +#define TIVA_EMAC_MFBOC_OFFSET 0x0c20 /* Ethernet MAC Missed Frame and Buffer Overflow Counter */ +#define TIVA_EMAC_RXINTWDT_OFFSET 0x0c24 /* Ethernet MAC Receive Interrupt Watchdog Timer */ +#define TIVA_EMAC_HOSTXDESC_OFFSET 0x0c48 /* Ethernet MAC Current Host Transmit Descriptor */ +#define TIVA_EMAC_HOSRXDESC_OFFSET 0x0c4c /* Ethernet MAC Current Host Receive Descriptor */ +#define TIVA_EMAC_HOSTXBA_OFFSET 0x0c50 /* Ethernet MAC Current Host Transmit Buffer Address */ +#define TIVA_EMAC_HOSRXBA_OFFSET 0x0c54 /* Ethernet MAC Current Host Receive Buffer Address */ + +#define TIVA_EMAC_PP_OFFSET 0x0fc0 /* Ethernet MAC Peripheral Property Register */ +#define TIVA_EMAC_PC_OFFSET 0x0fc4 /* Ethernet MAC Peripheral Configuration Register */ +#define TIVA_EMAC_CC_OFFSET 0x0fc8 /* Ethernet MAC Clock Configuration Register */ +#define TIVA_EPHY_RIS_OFFSET 0x0fd0 /* Ethernet PHY Raw Interrupt Status */ +#define TIVA_EPHY_IM_OFFSET 0x0fd4 /* Ethernet PHY Interrupt Mask */ +#define TIVA_EPHY_MISC_OFFSET 0x0fd8 /* RW1C Ethernet PHY Masked Interrupt Status and Clear */ + +/* Ethernet Controller Register Addresses *******************************************/ + +#define TIVA_EMAC_CFG (TIVA_ETHCON_BASE + TIVA_EMAC_CFG_OFFSET) +#define TIVA_EMAC_FRAMEFLTR (TIVA_ETHCON_BASE + TIVA_EMAC_FRAMEFLTR_OFFSET) +#define TIVA_EMAC_HASHTBLH (TIVA_ETHCON_BASE + TIVA_EMAC_HASHTBLH_OFFSET) +#define TIVA_EMAC_HASHTBLL (TIVA_ETHCON_BASE + TIVA_EMAC_HASHTBLL_OFFSET) +#define TIVA_EMAC_MIIADDR (TIVA_ETHCON_BASE + TIVA_EMAC_MIIADDR_OFFSET) +#define TIVA_EMAC_MIIDATA (TIVA_ETHCON_BASE + TIVA_EMAC_MIIDATA_OFFSET) +#define TIVA_EMAC_FLOWCTL (TIVA_ETHCON_BASE + TIVA_EMAC_FLOWCTL_OFFSET) +#define TIVA_EMAC_VLANTG (TIVA_ETHCON_BASE + TIVA_EMAC_VLANTG_OFFSET) +#define TIVA_EMAC_STATUS (TIVA_ETHCON_BASE + TIVA_EMAC_STATUS_OFFSET) +#define TIVA_EMAC_RWUFF (TIVA_ETHCON_BASE + TIVA_EMAC_RWUFF_OFFSET) +#define TIVA_EMAC_PMTCTLSTAT (TIVA_ETHCON_BASE + TIVA_EMAC_PMTCTLSTAT_OFFSET) +#define TIVA_EMAC_RIS (TIVA_ETHCON_BASE + TIVA_EMAC_RIS_OFFSET) +#define TIVA_EMAC_IM (TIVA_ETHCON_BASE + TIVA_EMAC_IM_OFFSET) +#define TIVA_EMAC_ADDR0H (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR0H_OFFSET) +#define TIVA_EMAC_ADDR0L (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR0L_OFFSET) +#define TIVA_EMAC_ADDR1H (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR1H_OFFSET) +#define TIVA_EMAC_ADDR1L (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR1L_OFFSET) +#define TIVA_EMAC_ADDR2H (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR2H_OFFSET) +#define TIVA_EMAC_ADDR2L (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR2L_OFFSET) +#define TIVA_EMAC_ADDR3H (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR3H_OFFSET) +#define TIVA_EMAC_ADDR3L (TIVA_ETHCON_BASE + TIVA_EMAC_ADDR3L_OFFSET) +#define TIVA_EMAC_WDOGTO (TIVA_ETHCON_BASE + TIVA_EMAC_WDOGTO_OFFSET) +#define TIVA_EMAC_MMCCTRL (TIVA_ETHCON_BASE + TIVA_EMAC_MMCCTRL_OFFSET) +#define TIVA_EMAC_MMCRXRIS (TIVA_ETHCON_BASE + TIVA_EMAC_MMCRXRIS_OFFSET) +#define TIVA_EMAC_MMCTXRIS (TIVA_ETHCON_BASE + TIVA_EMAC_MMCTXRIS_OFFSET) +#define TIVA_EMAC_MMCRXIM (TIVA_ETHCON_BASE + TIVA_EMAC_MMCRXIM_OFFSET) +#define TIVA_EMAC_MMCTXIM (TIVA_ETHCON_BASE + TIVA_EMAC_MMCTXIM_OFFSET) +#define TIVA_EMAC_TXCNTGB (TIVA_ETHCON_BASE + TIVA_EMAC_TXCNTGB_OFFSET) +#define TIVA_EMAC_TXCNTSCOL (TIVA_ETHCON_BASE + TIVA_EMAC_TXCNTSCOL_OFFSET) +#define TIVA_EMAC_TXCNTMCOL (TIVA_ETHCON_BASE + TIVA_EMAC_TXCNTMCOL_OFFSET) +#define TIVA_EMAC_TXOCTCNTG (TIVA_ETHCON_BASE + TIVA_EMAC_TXOCTCNTG_OFFSET) +#define TIVA_EMAC_RXCNTGB (TIVA_ETHCON_BASE + TIVA_EMAC_RXCNTGB_OFFSET) +#define TIVA_EMAC_RXCNTCRCERR (TIVA_ETHCON_BASE + TIVA_EMAC_RXCNTCRCERR_OFFSET) +#define TIVA_EMAC_RXCNTALGNERR (TIVA_ETHCON_BASE + TIVA_EMAC_RXCNTALGNERR_OFFSET) +#define TIVA_EMAC_RXCNTGUNI (TIVA_ETHCON_BASE + TIVA_EMAC_RXCNTGUNI_OFFSET) +#define TIVA_EMAC_VLNINCREP (TIVA_ETHCON_BASE + TIVA_EMAC_VLNINCREP_OFFSET) +#define TIVA_EMAC_VLANHASH (TIVA_ETHCON_BASE + TIVA_EMAC_VLANHASH_OFFSET) +#define TIVA_EMAC_TIMSTCTRL (TIVA_ETHCON_BASE + TIVA_EMAC_TIMSTCTRL_OFFSET) +#define TIVA_EMAC_SUBSECINC (TIVA_ETHCON_BASE + TIVA_EMAC_SUBSECINC_OFFSET) +#define TIVA_EMAC_TIMSEC (TIVA_ETHCON_BASE + TIVA_EMAC_TIMSEC_OFFSET) +#define TIVA_EMAC_TIMNANO (TIVA_ETHCON_BASE + TIVA_EMAC_TIMNANO_OFFSET) +#define TIVA_EMAC_TIMSECU (TIVA_ETHCON_BASE + TIVA_EMAC_TIMSECU_OFFSET) +#define TIVA_EMAC_TIMNANOU (TIVA_ETHCON_BASE + TIVA_EMAC_TIMNANOU_OFFSET) +#define TIVA_EMAC_TIMADD (TIVA_ETHCON_BASE + TIVA_EMAC_TIMADD_OFFSET) +#define TIVA_EMAC_TARGSEC (TIVA_ETHCON_BASE + TIVA_EMAC_TARGSEC_OFFSET) +#define TIVA_EMAC_TARGNANO (TIVA_ETHCON_BASE + TIVA_EMAC_TARGNANO_OFFSET) +#define TIVA_EMAC_HWORDSEC (TIVA_ETHCON_BASE + TIVA_EMAC_HWORDSEC_OFFSET) +#define TIVA_EMAC_TIMSTAT (TIVA_ETHCON_BASE + TIVA_EMAC_TIMSTAT_OFFSET) +#define TIVA_EMAC_PPSCTRL (TIVA_ETHCON_BASE + TIVA_EMAC_PPSCTRL_OFFSET) +#define TIVA_EMAC_PPS0INTVL (TIVA_ETHCON_BASE + TIVA_EMAC_PPS0INTVL_OFFSET) +#define TIVA_EMAC_PPS0WIDTH (TIVA_ETHCON_BASE + TIVA_EMAC_PPS0WIDTH_OFFSET) +#define TIVA_EMAC_DMABUSMOD (TIVA_ETHCON_BASE + TIVA_EMAC_DMABUSMOD_OFFSET) +#define TIVA_EMAC_TXPOLLD (TIVA_ETHCON_BASE + TIVA_EMAC_TXPOLLD_OFFSET) +#define TIVA_EMAC_RXPOLLD (TIVA_ETHCON_BASE + TIVA_EMAC_RXPOLLD_OFFSET) +#define TIVA_EMAC_RXDLADDR (TIVA_ETHCON_BASE + TIVA_EMAC_RXDLADDR_OFFSET) +#define TIVA_EMAC_TXDLADDR (TIVA_ETHCON_BASE + TIVA_EMAC_TXDLADDR_OFFSET) +#define TIVA_EMAC_DMARIS (TIVA_ETHCON_BASE + TIVA_EMAC_DMARIS_OFFSET) +#define TIVA_EMAC_DMAOPMODE (TIVA_ETHCON_BASE + TIVA_EMAC_DMAOPMODE_OFFSET) +#define TIVA_EMAC_DMAIM (TIVA_ETHCON_BASE + TIVA_EMAC_DMAIM_OFFSET) +#define TIVA_EMAC_MFBOC (TIVA_ETHCON_BASE + TIVA_EMAC_MFBOC_OFFSET) +#define TIVA_EMAC_RXINTWDT (TIVA_ETHCON_BASE + TIVA_EMAC_RXINTWDT_OFFSET) +#define TIVA_EMAC_HOSTXDESC (TIVA_ETHCON_BASE + TIVA_EMAC_HOSTXDESC_OFFSET) +#define TIVA_EMAC_HOSRXDESC (TIVA_ETHCON_BASE + TIVA_EMAC_HOSRXDESC_OFFSET) +#define TIVA_EMAC_HOSTXBA (TIVA_ETHCON_BASE + TIVA_EMAC_HOSTXBA_OFFSET) +#define TIVA_EMAC_HOSRXBA (TIVA_ETHCON_BASE + TIVA_EMAC_HOSRXBA_OFFSET) +#define TIVA_EMAC_PP (TIVA_ETHCON_BASE + TIVA_EMAC_PP_OFFSET) +#define TIVA_EMAC_PC (TIVA_ETHCON_BASE + TIVA_EMAC_PC_OFFSET) +#define TIVA_EMAC_CC (TIVA_ETHCON_BASE + TIVA_EMAC_CC_OFFSET) +#define TIVA_EPHY_RIS (TIVA_ETHCON_BASE + TIVA_EPHY_RIS_OFFSET) +#define TIVA_EPHY_IM (TIVA_ETHCON_BASE + TIVA_EPHY_IM_OFFSET) +#define TIVA_EPHY_MISC (TIVA_ETHCON_BASE + TIVA_EPHY_MISC_OFFSET) + +/* MII Management Register Addresses */ + +#define TIVA_EPHY_BMCR 0x00 /* Ethernet PHY Basic Mode Control */ +#define TIVA_EPHY_BMSR 0x01 /* Ethernet PHY Basic Mode Status */ +#define TIVA_EPHY_ID1 0x02 /* Ethernet PHY Identifier Register 1 */ +#define TIVA_EPHY_ID2 0x03 /* Ethernet PHY Identifier Register 2 */ +#define TIVA_EPHY_ANA 0x04 /* Ethernet PHY Auto-Negotiation Advertisement */ +#define TIVA_EPHY_ANLPA 0x05 /* Ethernet PHY Auto-Negotiation Link Partner Ability */ +#define TIVA_EPHY_ANER 0x06 /* Ethernet PHY Auto-Negotiation Expansion */ +#define TIVA_EPHY_ANNPTR 0x07 /* Ethernet PHY Auto-Negotiation Next Page TX */ +#define TIVA_EPHY_ANLNPTR 0x08 /* Ethernet PHY Auto-Negotiation Link Partner Ability Next Page */ +#define TIVA_EPHY_CFG1 0x09 /* Ethernet PHY Configuration 1 */ +#define TIVA_EPHY_CFG2 0x0a /* Ethernet PHY Configuration 2 */ +#define TIVA_EPHY_CFG3 0x0b /* Ethernet PHY Configuration 3 */ +#define TIVA_EPHY_REGCTL 0x0d /* Ethernet PHY Register Control */ +#define TIVA_EPHY_ADDAR 0x0e /* Ethernet PHY Address or Data */ +#define TIVA_EPHY_STS 0x10 /* Ethernet PHY Status */ +#define TIVA_EPHY_SCR 0x11 /* Ethernet PHY Specific Control */ +#define TIVA_EPHY_MISR1 0x12 /* Ethernet PHY MII Interrupt Status 1 */ +#define TIVA_EPHY_MISR2 0x13 /* Ethernet PHY MII Interrupt Status 2 */ +#define TIVA_EPHY_FCSCR 0x14 /* Ethernet PHY False Carrier Sense Counter */ +#define TIVA_EPHY_RXERCNT 0x15 /* Ethernet PHY Receive Error Count */ +#define TIVA_EPHY_BISTCR 0x16 /* Ethernet PHY BIST Control */ +#define TIVA_EPHY_LEDCR 0x18 /* Ethernet PHY LED Control */ +#define TIVA_EPHY_CTL 0x19 /* Ethernet PHY Control */ +#define TIVA_EPHY_10BTSC 0x1a /* Ethernet PHY 10Base-T Status/Control */ +#define TIVA_EPHY_BICSR1 0x1b /* Ethernet PHY BIST Control and Status 1 */ +#define TIVA_EPHY_BICSR2 0x1c /* Ethernet PHY BIST Control and Status 2 */ +#define TIVA_EPHY_CDCR 0x1e /* Ethernet PHY Cable Diagnostic Control */ +#define TIVA_EPHY_RCR 0x1f /* Ethernet PHY Reset Control */ +#define TIVA_EPHY_LEDCFG 0x25 /* Ethernet PHY LED Configuration */ + +/* Ethernet Controller Register Bit Definitions *************************************/ + +/* Ethernet MAC Configuration */ + +#define EMAC_CFG_PRELEN_SHIFT (0) /* Bits 0-1: Preamble Length for Transmit */ +#define EMAC_CFG_PRELEN_MASK (3 << EMAC_CFG_PRELEN_SHIFT) +# define EMAC_CFG_PRELEN_7 (0 << EMAC_CFG_PRELEN_SHIFT) /* 7 bytes of preamble */ +# define EMAC_CFG_PRELEN_5 (1 << EMAC_CFG_PRELEN_SHIFT) /* 5 bytes of preamble */ +# define EMAC_CFG_PRELEN_3 (2 << EMAC_CFG_PRELEN_SHIFT) /* 3 bytes of preamble */ +#define EMAC_CFG_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define EMAC_CFG_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define EMAC_CFG_DC (1 << 4) /* Bit 4: Deferral Check */ +#define EMAC_CFG_BL_SHIFT (5) /* Bits 5-6: Back-Off Limit */ +#define EMAC_CFG_BL_MASK (3 << EMAC_CFG_BL_SHIFT) +# define EMAC_CFG_BL_10 (0 << EMAC_CFG_BL_SHIFT) /* k = min (n,10) */ +# define EMAC_CFG_BL_8 (1 << EMAC_CFG_BL_SHIFT) /* k = min (n,8) */ +# define EMAC_CFG_BL_4 (2 << EMAC_CFG_BL_SHIFT) /* k = min (n,4) */ +# define EMAC_CFG_BL_1 (3 << EMAC_CFG_BL_SHIFT) /* k = min (n,1) */ +#define EMAC_CFG_ACS (1 << 7) /* Bit 7: Automatic Pad or CRC Stripping */ +#define EMAC_CFG_DR (1 << 9) /* Bit 8: Disable Retry */ +#define EMAC_CFG_IPC (1 << 10) /* Bit 10: Checksum Offload */ +#define EMAC_CFG_DUPM (1 << 11) /* Bit 11: Duplex Mode */ +#define EMAC_CFG_LOOPBM (1 << 12) /* Bit 12: Loopback Mode */ +#define EMAC_CFG_DRO (1 << 13) /* Bit 13: Disable Receive Own */ +#define EMAC_CFG_FES (1 << 14) /* Bit 14: Speed */ +#define EMAC_CFG_PS (1 << 15) /* Bit 15: Port Select */ +#define EMAC_CFG_DISCRS (1 << 16) /* Bit 16: Disable Carrier Sense During Transmission */ +#define EMAC_CFG_IFG_SHIFT (17) /* Bits 17-19: Inter-Frame Gap (IFG) */ +#define EMAC_CFG_IFG_MASK (7 << EMAC_CFG_IFG_SHIFT) +# define EMAC_CFG_IFG(n) ((12-((n) >> 3)) << EMAC_CFG_IFG_SHIFT) /* n bit times, n=40,48,..96 */ +# define EMAC_CFG_IFG_96 (0 << EMAC_CFG_IFG_SHIFT) /* 96 bit times */ +# define EMAC_CFG_IFG_88 (1 << EMAC_CFG_IFG_SHIFT) /* 88 bit times */ +# define EMAC_CFG_IFG_80 (2 << EMAC_CFG_IFG_SHIFT) /* 80 bit times */ +# define EMAC_CFG_IFG_72 (3 << EMAC_CFG_IFG_SHIFT) /* 72 bit times */ +# define EMAC_CFG_IFG_64 (4 << EMAC_CFG_IFG_SHIFT) /* 64 bit times */ +# define EMAC_CFG_IFG_56 (5 << EMAC_CFG_IFG_SHIFT) /* 56 bit times */ +# define EMAC_CFG_IFG_48 (6 << EMAC_CFG_IFG_SHIFT) /* 48 bit times */ +# define EMAC_CFG_IFG_40 (7 << EMAC_CFG_IFG_SHIFT) /* 40 bit times */ +#define EMAC_CFG_JFEN (1 << 20) /* Bit 20: Jumbo Frame Enable */ +#define EMAC_CFG_JD (1 << 22) /* Bit 21: Jabber Disable */ +#define EMAC_CFG_WDDIS (1 << 23) /* Bit 23: Watchdog Disable */ +#define EMAC_CFG_CST (1 << 25) /* Bit 25: CRC Stripping for Type Frames */ +#define EMAC_CFG_TWOKPEN (1 << 27) /* Bit 27: IEEE 802 */ +#define EMAC_CFG_SADDR_SHIFT (28) /* Bits 28-30: Source Address Insertion or Replacement Control */ +#define EMAC_CFG_SADDR_MASK (7 << EMAC_CFG_SADDR_SHIFT) +# define EMAC_CFG_SADDR_RADDR0 (2 << EMAC_CFG_SADDR_SHIFT) /* Insert EMACADDR0x */ +# define EMAC_CFG_SADDR_IADDR0 (3 << EMAC_CFG_SADDR_SHIFT) /* Replace with EMACADDR0x */ +# define EMAC_CFG_SADDR_RADDR1 (6 << EMAC_CFG_SADDR_SHIFT) /* Insert EMACADDR1x */ +# define EMAC_CFG_SADDR_IADDR1 (7 << EMAC_CFG_SADDR_SHIFT) /* Replace with EMACADDR1x */ + +/* Ethernet MAC Frame Filter */ + +#define EMAC_FRAMEFLTR_PR (1 << 0) /* Bit 0: Promiscuous Mode */ +#define EMAC_FRAMEFLTR_HUC (1 << 1) /* Bit 1: Hash Unicast */ +#define EMAC_FRAMEFLTR_HMC (1 << 2) /* Bit 2: Hash Multicast */ +#define EMAC_FRAMEFLTR_DAIF (1 << 3) /* Bit 3: Destination Address (DA) Inverse Filtering */ +#define EMAC_FRAMEFLTR_PM (1 << 4) /* Bit 4: Pass All Multicast */ +#define EMAC_FRAMEFLTR_DBF (1 << 5) /* Bit 5: Disable Broadcast Frames */ +#define EMAC_FRAMEFLTR_PCF_SHIFT (6) /* Bits 6-7: Pass Control Frames */ +#define EMAC_FRAMEFLTR_PCF_MASK (3 << EMAC_FRAMEFLTR_PCF_SHIFT) +# define EMAC_FRAMEFLTR_PCF_NONE (0 << EMAC_FRAMEFLTR_PCF_SHIFT) /* Prevents all control frames */ +# define EMAC_FRAMEFLTR_PCF_PAUSE (1 << EMAC_FRAMEFLTR_PCF_SHIFT) /* Prevents all except PAUSE */ +# define EMAC_FRAMEFLTR_PCF_ALL (2 << EMAC_FRAMEFLTR_PCF_SHIFT) /* Forward all control frames */ +# define EMAC_FRAMEFLTR_PCF_FILTER (3 << EMAC_FRAMEFLTR_PCF_SHIFT) /* Forwards all that pass address filter */ +#define EMAC_FRAMEFLTR_SAIF (1 << 8) /* Bit 8: Source Address (SA) Inverse Filtering */ +#define EMAC_FRAMEFLTR_SAF (1 << 9) /* Bit 9: Source Address Filter Enable */ +#define EMAC_FRAMEFLTR_HPF (1 << 10) /* Bit 10: Hash or Perfect Filter */ +#define EMAC_FRAMEFLTR_VTFE (1 << 16) /* Bit 16: VLAN Tag Filter Enable */ +#define EMAC_FRAMEFLTR_RA (1 << 31) /* Bit 31: Receive All */ + +/* Ethernet MAC Hash Table High (32-bit data) */ +/* Ethernet MAC Hash Table Low (32-bit data) */ + +/* Ethernet MAC MII Address */ + +#define EMAC_MIIADDR_MIIB (1 << 0) /* Bit 0: MII Busy */ +#define EMAC_MIIADDR_MIIW (1 << 1) /* Bit 1: MII Write */ +#define EMAC_MIIADDR_CR_SHIFT (2) /* Bits 2-5: Clock Reference Frequency Selection */ +#define EMAC_MIIADDR_CR_MASK (15 << EMAC_MIIADDR_CR_SHIFT) +# define EMAC_MIIADDR_CR_60_100 (0 << EMAC_MIIADDR_CR_SHIFT) /* System Clock=60-100 MHz; MDIO clock=SYSCLK/42 */ +# define EMAC_MIIADDR_CR_100_150 (1 << EMAC_MIIADDR_CR_SHIFT) /* System Clock=100-150 MHz; MDIO clock=SYSCLK/62 */ +# define EMAC_MIIADDR_CR_20_35 (2 << EMAC_MIIADDR_CR_SHIFT) /* System Clock=20-35 MHz; MDIO clock=SYSCLK/16 */ +# define EMAC_MIIADDR_CR_35_60 (3 << EMAC_MIIADDR_CR_SHIFT) /* System Clock=35-60 MHz; MDIO clock=SYSCLK/26 */ +# define EMAC_MIIADDR_CR_150_168 (4 << EMAC_MIIADDR_CR_SHIFT) /* System Clock=150-168 MHz; MDIO clock=SYSCLK/102 */ +#define EMAC_MIIADDR_MII_SHIFT (6) /* Bits 6-10: MII Register */ +#define EMAC_MIIADDR_MII_MASK (31 << EMAC_MIIADDR_MII_SHIFT) +# define EMAC_MIIADDR_MII(n) ((uint32_t)(n) << EMAC_MIIADDR_MII_SHIFT) +#define EMAC_MIIADDR_PLA_SHIFT (11) /* Bits 11-15: Physical Layer Address */ +#define EMAC_MIIADDR_PLA_MASK (31 << EMAC_MIIADDR_PLA_SHIFT) +# define EMAC_MIIADDR_PLA(n) ((uint32_t)(n) << EMAC_MIIADDR_PLA_SHIFT) + +/* Ethernet MAC MII Data Register */ + +#define EMAC_MIIDATA_SHIFT (0) /* Bit 0-15: MII Data */ +#define EMAC_MIIDATA_MASK (0xffff << EMAC_MIIDATA_SHIFT) + +/* Ethernet MAC Flow Control */ + +#define EMAC_FLOWCTL_FCBBPA (1 << 0) /* Bit 0: Flow Control Busy or Back-pressure Activate */ +#define EMAC_FLOWCTL_TFE (1 << 1) /* Bit 1: Transmit Flow Control Enable */ +#define EMAC_FLOWCTL_RFE (1 << 2) /* Bit 2: Receive Flow Control Enable */ +#define EMAC_FLOWCTL_UP (1 << 3) /* Bit 3: Unicast Pause Frame Detect */ +#define EMAC_FLOWCTL_PLT_SHIFT (4) /* Bits 4-5: Pause Low Threshold */ +#define EMAC_FLOWCTL_PLT_MASK (3 << EMAC_FLOWCTL_PLT_SHIFT) +# define EMAC_FLOWCTL_PLT_M4 (0 << EMAC_FLOWCTL_PLT_SHIFT) /* Pause time minus 4 slot times */ +# define EMAC_FLOWCTL_PLT_M28 (1 << EMAC_FLOWCTL_PLT_SHIFT) /* Pause time minus 28 slot times */ +# define EMAC_FLOWCTL_PLT_M144 (2 << EMAC_FLOWCTL_PLT_SHIFT) /* Pause time minus 144 slot times */ +# define EMAC_FLOWCTL_PLT_M256 (3 << EMAC_FLOWCTL_PLT_SHIFT) /* Pause time minus 256 slot times */ +#define EMAC_FLOWCTL_DZQP (1 << 7) /* Bit 7: Disable Zero-Quanta Pause */ +#define EMAC_FLOWCTL_PT_SHIFT (16) /* Bits 16-31: Pause Time */ +#define EMAC_FLOWCTL_PT_MASK (0xffff << EMAC_FLOWCTL_PT_SHIFT) +# define EMAC_FLOWCTL_PT(n) ((uint32_t)(n) << EMAC_FLOWCTL_PT_SHIFT) + +/* Ethernet MAC VLAN Tag */ + +#define EMAC_VLANTG_VL_SHIFT (0) /* Bits 0-15: VLAN Tag Identifier for Receive Frames */ +#define EMAC_VLANTG_VL_MASK (0xffff << EMAC_VLANTG_VL_SHIFT) +#define EMAC_VLANTG_ETV (1 << 16) /* Bit 16: Enable 12-Bit VLAN Tag Comparison */ +#define EMAC_VLANTG_VTIM (1 << 17) /* Bit 17: VLAN Tag Inverse Match Enable */ +#define EMAC_VLANTG_ESVL (1 << 18) /* Bit 18: Enable S-VLAN */ +#define EMAC_VLANTG_VTHM (1 << 19) /* Bit 19: VLAN Tag Hash Table Match Enable */ + +/* Ethernet MAC Status */ + +#define EMAC_STATUS_RPE (1 << 0) /* Bit 0: MAC MII Receive Protocol Engine Status */ +#define EMAC_STATUS_RFCFC_SHIFT (1) /* Bits 1-2: MAC Receive Frame Controller FIFO Status */ +#define EMAC_STATUS_RFCFC_MASK (3 << EMAC_STATUS_RFCFC_SHIFT) +#define EMAC_STATUS_RWC (1 << 4) /* Bit 4: TX/RX Controller RX FIFO Write Controller Active Status */ +#define EMAC_STATUS_RRC_SHIFT (5) /* Bits 5-6: TX/RX Controller Read Controller State */ +#define EMAC_STATUS_RRC_MASK (3 << EMAC_STATUS_RRC_SHIFT) +# define EMAC_STATUS_RRC_IDLE (0 << EMAC_STATUS_RRC_SHIFT) /* IDLE state */ +# define EMAC_STATUS_RRC_STATUS (1 << EMAC_STATUS_RRC_SHIFT) /* Reading frame data */ +# define EMAC_STATUS_RRC_DATA (2 << EMAC_STATUS_RRC_SHIFT) /* Reading frame status (or timestamp) */ +# define EMAC_STATUS_RRC_FLUSH (3 << EMAC_STATUS_RRC_SHIFT) /* Flushing the frame data and status */ +#define EMAC_STATUS_RXF_SHIFT (8) /* Bits 8-9: TX/RX Controller RX FIFO Fill-level Status */ +#define EMAC_STATUS_RXF_MASK (3 << EMAC_STATUS_RXF_SHIFT) +# define EMAC_STATUS_RXF_EMPTY (0 << EMAC_STATUS_RXF_SHIFT) /* RX FIFO Empty */ +# define EMAC_STATUS_RXF_BELOW (1 << EMAC_STATUS_RXF_SHIFT) /* Below the flow-control deactivate threshold */ +# define EMAC_STATUS_RXF_ABOVE (2 << EMAC_STATUS_RXF_SHIFT) /* Above the flow-control activate threshold */ +# define EMAC_STATUS_RXF_FULL (3 << EMAC_STATUS_RXF_SHIFT) /* RX FIFO Full */ +#define EMAC_STATUS_TPE (1 << 16) /* Bit 16: MAC MII Transmit Protocol Engine Status */ +#define EMAC_STATUS_TFC_SHIFT (17) /* Bits 17-18: MAC Transmit Frame Controller Status */ +#define EMAC_STATUS_TFC_MASK (3 << EMAC_STATUS_TFC_SHIFT) +# define EMAC_STATUS_TFC_IDLE (0 << EMAC_STATUS_TFC_SHIFT) /* IDLE state */ +# define EMAC_STATUS_TFC_STATUS (1 << EMAC_STATUS_TFC_SHIFT) /* Waiting for status */ +# define EMAC_STATUS_TFC_PAUSE (2 << EMAC_STATUS_TFC_SHIFT) /* Generating and transmitting a PAUSE control frame */ +# define EMAC_STATUS_TFC_INPUT (3 << EMAC_STATUS_TFC_SHIFT) /* Transferring input frame for transmission */ +#define EMAC_STATUS_TXPAUSED (1 << 19) /* Bit 19: MAC Transmitter PAUSE */ +#define EMAC_STATUS_TRC_SHIFT (20) /* Bits 20-21: TX/RX Controller's TX FIFO Read Controller Status */ +#define EMAC_STATUS_TRC_MASK (3 << EMAC_STATUS_TRC_SHIFT) +# define EMAC_STATUS_TRC_IDLE (0 << EMAC_STATUS_TRC_SHIFT) /* IDLE state */ +# define EMAC_STATUS_TRC_READ (1 << EMAC_STATUS_TRC_SHIFT) /* READ state */ +# define EMAC_STATUS_TRC_WAIT (2 << EMAC_STATUS_TRC_SHIFT) /* Waiting for TX Status from MAC transmitter */ +# define EMAC_STATUS_TRC_WRFLUSH (3 << EMAC_STATUS_TRC_SHIFT) /* Writing received TX Status or flushing TX FIFO */ +#define EMAC_STATUS_TWC (1 << 22) /* Bit 22: TX/RX Controller TX FIFO Write Controller Active Status */ +#define EMAC_STATUS_TXFE (1 << 24) /* Bit 24: TX/RX Controller TX FIFO Not Empty Status */ +#define EMAC_STATUS_TXFF (1 << 25) /* Bit 25: TX/RX Controller TX FIFO Full Status */ + +/* Ethernet MAC Remote Wake-Up Frame Filter (32-bit data) */ + +/* Ethernet MAC PMT Control and Status Register */ + +#define EMAC_PMTCTLSTAT_PWRDWN (1 << 0) /* Bit 0: Power Down */ +#define EMAC_PMTCTLSTAT_MGKPKTEN (1 << 1) /* Bit 1: Magic Packet Enable */ +#define EMAC_PMTCTLSTAT_WUPFREN (1 << 2) /* Bit 2: Wake-Up Frame Enable */ +#define EMAC_PMTCTLSTAT_MGKPRX (1 << 5) /* Bit 3: Magic Packet Received */ +#define EMAC_PMTCTLSTAT_WUPRX (1 << 6) /* Bit 6: Wake-Up Frame Received */ +#define EMAC_PMTCTLSTAT_GLBLUCAST (1 << 9) /* Bit 7: Global Unicast */ +#define EMAC_PMTCTLSTAT_RWKPTR_SHIFT (24) /* Bits 24-26: Remote Wake-Up FIFO Pointer */ +#define EMAC_PMTCTLSTAT_RWKPTR_MASK (7 << EMAC_PMTCTLSTAT_RWKPTR_SHIFT) +# define EMAC_PMTCTLSTAT_RWKPTR(n) ((uint32_t)(n) << EMAC_PMTCTLSTAT_RWKPTR_SHIFT) +#define EMAC_PMTCTLSTAT_WUPFRRST (1 << 31) /* Bit 31: Wake-Up Frame Filter Register Pointer Reset */ + +/* Ethernet MAC Raw Interrupt Status */ + +#define EMAC_RIS_PMT (1 << 3) /* Bit 3: PMT Interrupt Status */ +#define EMAC_RIS_MMC (1 << 4) /* Bit 4: MMC Interrupt Status */ +#define EMAC_RIS_MMCRX (1 << 5) /* Bit 5: MMC Receive Interrupt Status */ +#define EMAC_RIS_MMCTX (1 << 6) /* Bit 6: MMC Transmit Interrupt Status */ +#define EMAC_RIS_TS (1 << 9) /* Bit 9: Timestamp Interrupt Status */ + +/* Ethernet MAC Interrupt Mask */ + +#define EMAC_IM_PMT (1 << 3) /* Bit 3: PMT Interrupt Mask */ +#define EMAC_IM_TSI (1 << 9) /* Bit 9: Timestamp Interrupt Mask */ +#define EMAC_IM_ALLINTS (EMAC_IM_PMT|EMAC_IM_TSI) + +/* Ethernet MAC Address 0 High */ +/* Ethernet MAC Address 0 Low Register (32-bit MAC Address0 [31:0]) */ + +#define EMAC_ADDR0H_ADDRHI_SHIFT (0) /* Bits 0-15: MAC Address0 [47:32] */ +#define EMAC_ADDR0H_ADDRHI_MASK (0xffff << EMAC_ADDR0H_ADDRHI_SHIFT) +# define EMAC_ADDR0H_ADDRHI(n) ((uint32_t)(n) << EMAC_ADDR0H_ADDRHI_SHIFT) +#define EMAC_ADDR0H_AE (1 << 31) /* Bit 31: Address Enable */ + +/* Ethernet MAC Address 1 High */ +/* Ethernet MAC Address 1 Low (32-bit MAC Address0 [31:0]) */ + +#define EMAC_ADDR1H_ADDRHI_SHIFT (0) /* Bits 0-15: MAC Address0 [47:32] */ +#define EMAC_ADDR1H_ADDRHI_MASK (0xffff << EMAC_ADDR1H_ADDRHI_SHIFT) +# define EMAC_ADDR1H_ADDRHI(n) ((uint32_t)(n) << EMAC_ADDR1H_ADDRHI_SHIFT) +#define EMAC_ADDR1H_MBC_SHIFT (24) /* Bits 24-29: Mask Byte Control */ +#define EMAC_ADDR1H_MBC_MASK (0x3f << EMAC_ADDR1H_MBC_SHIFT) +# define EMAC_ADDR1H_MBC(n) ((uint32_t)(n) << EMAC_ADDR1H_MBC_SHIFT) +# define EMAC_ADDR1H_EMACADDR1L_0 (1 << 24) /* ADDRLO [7:0] of EMACADDR1L register */ +# define EMAC_ADDR1H_EMACADDR1L_8 (1 << 25) /* ADDRLO [15:8] of EMACADDR1L register */ +# define EMAC_ADDR1H_EMACADDR1L_16 (1 << 26) /* ADDRLO [23:16] of EMACADDR1L register */ +# define EMAC_ADDR1H_EMACADDR1L_24 (1 << 27) /* ADDRLO [31:24] of EMACADDR1L register */ +# define EMAC_ADDR1H_EMACADDR1H_0 (1 << 28) /* ADDRHI [7:0] of EMACADDR1H */ +# define EMAC_ADDR1H_EMACADDR1H_8 (1 << 29) /* ADDRHI [15:8] of EMACADDR1H Register */ +#define EMAC_ADDR1H_SA (1 << 30) /* Bit 30: Source Address */ +#define EMAC_ADDR1H_AE (1 << 31) /* Bit 31: Address Enable */ + +/* Ethernet MAC Address 2 High */ +/* Ethernet MAC Address 2 Low (32-bit MAC Address0 [31:0]) */ + +#define EMAC_ADDR2H_ADDRHI_SHIFT (0) /* Bits 0-15: MAC Address0 [47:32] */ +#define EMAC_ADDR2H_ADDRHI_MASK (0xffff << EMAC_ADDR2H_ADDRHI_SHIFT) +# define EMAC_ADDR2H_ADDRHI(n) ((uint32_t)(n) << EMAC_ADDR2H_ADDRHI_SHIFT) +#define EMAC_ADDR2H_MBC_SHIFT (24) /* Bits 24-29: Mask Byte Control */ +#define EMAC_ADDR2H_MBC_MASK (0x3f << EMAC_ADDR2H_MBC_SHIFT) +# define EMAC_ADDR2H_MBC(n) ((uint32_t)(n) << EMAC_ADDR2H_MBC_SHIFT) +# define EMAC_ADDR2H_EMACADDR2L_0 (1 << 24) /* ADDRLO [7:0] of EMACADDR2L register */ +# define EMAC_ADDR2H_EMACADDR2L_8 (1 << 25) /* ADDRLO [15:8] of EMACADDR2L register */ +# define EMAC_ADDR2H_EMACADDR2L_16 (1 << 26) /* ADDRLO [23:16] of EMACADDR2L register */ +# define EMAC_ADDR2H_EMACADDR2L_24 (1 << 27) /* ADDRLO [31:24] of EMACADDR2L register */ +# define EMAC_ADDR2H_EMACADDR2H_0 (1 << 28) /* ADDRHI [7:0] of EMACADDR2H */ +# define EMAC_ADDR2H_EMACADDR2H_8 (1 << 29) /* ADDRHI [15:8] of EMACADDR2H Register */ +#define EMAC_ADDR2H_SA (1 << 30) /* Bit 30: Source Address */ +#define EMAC_ADDR2H_AE (1 << 31) /* Bit 31: Address Enable */ + +/* Ethernet MAC Address 3 High */ +/* Ethernet MAC Address 3 Low (32-bit MAC Address0 [31:0]) */ + +#define EMAC_ADDR3H_ADDRHI_SHIFT (0) /* Bits 0-15: MAC Address0 [47:32] */ +#define EMAC_ADDR3H_ADDRHI_MASK (0xffff << EMAC_ADDR3H_ADDRHI_SHIFT) +# define EMAC_ADDR3H_ADDRHI(n) ((uint32_t)(n) << EMAC_ADDR3H_ADDRHI_SHIFT) +#define EMAC_ADDR3H_MBC_SHIFT (24) /* Bits 24-29: Mask Byte Control */ +#define EMAC_ADDR3H_MBC_MASK (0x3f << EMAC_ADDR3H_MBC_SHIFT) +# define EMAC_ADDR3H_MBC(n) ((uint32_t)(n) << EMAC_ADDR3H_MBC_SHIFT) +# define EMAC_ADDR3H_EMACADDR3L_0 (1 << 24) /* ADDRLO [7:0] of EMACADDR3L register */ +# define EMAC_ADDR3H_EMACADDR3L_8 (1 << 25) /* ADDRLO [15:8] of EMACADDR3L register */ +# define EMAC_ADDR3H_EMACADDR3L_16 (1 << 26) /* ADDRLO [23:16] of EMACADDR3L register */ +# define EMAC_ADDR3H_EMACADDR3L_24 (1 << 27) /* ADDRLO [31:24] of EMACADDR3L register */ +# define EMAC_ADDR3H_EMACADDR3H_0 (1 << 28) /* ADDRHI [7:0] of EMACADDR3H */ +# define EMAC_ADDR3H_EMACADDR3H_8 (1 << 29) /* ADDRHI [15:8] of EMACADDR3H Register */ +#define EMAC_ADDR3H_SA (1 << 30) /* Bit 30: Source Address */ +#define EMAC_ADDR3H_AE (1 << 31) /* Bit 31: Address Enable */ + + +/* Ethernet MAC Watchdog Timeout */ + +#define EMAC_WDOGTO_WTO_SHIFT (0) /* Bits 0-13: Watchdog Timeout */ +#define EMAC_WDOGTO_WTO_MASK (0x3fff << EMAC_WDOGTO_WTO_SHIFT) +# define EMAC_WDOGTO_WTO(n) ((uint32_t)(n) << EMAC_WDOGTO_WTO_SHIFT) +#define EMAC_WDOGTO_PWE (1 << 16) /* Bit 16: Programmable Watchdog Enable */ + +/* Ethernet MAC MMC Control */ + +#define EMAC_MMCCTRL_CNTRST (1 << 0) /* Bit 0: Counters Reset */ +#define EMAC_MMCCTRL_CNTSTPRO (1 << 1) /* Bit 1: Counters Stop Rollover */ +#define EMAC_MMCCTRL_RSTONRD (1 << 2) /* Bit 2: Reset on Read */ +#define EMAC_MMCCTRL_CNTFREEZ (1 << 3) /* Bit 3: MMC Counter Freeze */ +#define EMAC_MMCCTRL_CNTPRST (1 << 4) /* Bit 4: Counters Preset */ +#define EMAC_MMCCTRL_CNTPRSTLVL (1 << 5) /* Bit 5: Full/Half Preset Level Value */ +#define EMAC_MMCCTRL_UCDBC (1 << 8) /* Bit 8: Update MMC Counters for Dropped Broadcast Frames */ + +/* Ethernet MAC MMC Receive Raw Interrupt Status */ + +#define EMAC_MMCRXRIS_GBF (1 << 0) /* Bit 0: MMC Receive Good Bad Frame Counter Interrupt Status */ +#define EMAC_MMCRXRIS_CRCERR (1 << 5) /* Bit 5: MMC Receive CRC Error Frame Counter Interrupt Status */ +#define EMAC_MMCRXRIS_ALGNERR (1 << 6) /* Bit 6: MMC Receive Alignment Error Frame Counter Interrupt Status */ +#define EMAC_MMCRXRIS_UCGF (1 << 17) /* Bit 17: MMC Receive Unicast Good Frame Counter Interrupt Status */ + +/* Ethernet MAC MMC Transmit Raw Interrupt Status */ + +#define EMAC_MMCTXRIS_GBF (1 << 1) /* Bit 1: MMC Transmit Good Bad Frame Counter Interrupt Status */ +#define EMAC_MMCTXRIS_SCOLLGF (1 << 14) /* Bit 14: MMC Transmit Single Collision Good Frame Counter Interrupt Status */ +#define EMAC_MMCTXRIS_MCOLLGF (1 << 15) /* Bit 15: MMC Transmit Multiple Collision Good Frame Counter Interrupt Status */ +#define EMAC_MMCTXRIS_OCTCNT (1 << 20) /* Bit 20: Octet Counter Interrupt Status */ + +/* Ethernet MAC MMC Receive Interrupt Mask */ + +#define EMAC_MMCRXIM_GBF (1 << 0) /* Bit 0: MMC Receive Good Bad Frame Counter Interrupt Mask */ +#define EMAC_MMCRXIM_CRCERR (1 << 5) /* Bit 5: MMC Receive CRC Error Frame Counter Interrupt Mask */ +#define EMAC_MMCRXIM_ALGNERR (1 << 6) /* Bit 6: MMC Receive Alignment Error Frame Counter Interrupt Mask */ +#define EMAC_MMCRXIM_UCGF (1 << 17) /* Bit 17: MMC Receive Unicast Good Frame Counter Interrupt Mask */ + +/* Ethernet MAC MMC Transmit Interrupt Mask */ + +#define EMAC_MMCTXIM_GBF (1 << 1) /* Bit 1: MMC Transmit Good Bad Frame Counter Interrupt Mask */ +#define EMAC_MMCTXIM_SCOLLGF (1 << 14) /* Bit 14: MMC Transmit Single Collision Good Frame Counter Interrupt Mask */ +#define EMAC_MMCTXIM_MCOLLGF (1 << 15) /* Bit 15: MMC Transmit Multiple Collision Good Frame Counter Interrupt Mask */ +#define EMAC_MMCTXIM_OCTCNT (1 << 20) /* Bit 20: MMC Transmit Good Octet Counter Interrupt Mask */ + +/* Ethernet MAC Transmit Frame Count for Good and Bad Frames (32-bit data) */ +/* Ethernet MAC Transmit Frame Count for Frames Transmitted after Single Collision (32-bit data) */ +/* Ethernet MAC Transmit Frame Count for Frames Transmitted after Multiple Collisions (32-bit data) */ +/* Ethernet MAC Transmit Octet Count Good (32-bit data) */ +/* Ethernet MAC Receive Frame Count for Good and Bad Frames (32-bit data) */ +/* Ethernet MAC Receive Frame Count for CRC Error Frames (32-bit data) */ +/* Ethernet MAC Receive Frame Count for Alignment Error Frames (32-bit data) */ +/* Ethernet MAC Receive Frame Count for Good Unicast Frames (32-bit data) */ + +/* Ethernet MAC VLAN Tag Inclusion or Replacement */ + +#define EMAC_VLNINCREP_VLT_SHIFT (0) /* Bits 0-15: VLAN Tag for Transmit Frames */ +#define EMAC_VLNINCREP_VLT_MASK (0xffff << EMAC_VLNINCREP_VLT_SHIFT) +# define EMAC_VLNINCREP_VLT(n) ((uint32_t)(n) << EMAC_VLNINCREP_VLT_SHIFT) +#define EMAC_VLNINCREP_VLC_SHIFT (16) /* Bits 16-17: VLAN Tag Control in Transmit Frames */ +#define EMAC_VLNINCREP_VLC_MASK (3 << EMAC_VLNINCREP_VLC_SHIFT) +# define EMAC_VLNINCREP_VLC_NONE (0 << EMAC_VLNINCREP_VLC_SHIFT) /* No VLAN tag deletion, insertion, or replacement */ +# define EMAC_VLNINCREP_VLC_TAGDEL (1 << EMAC_VLNINCREP_VLC_SHIFT) /* VLAN tag deletion */ +# define EMAC_VLNINCREP_VLC_TAGINS (2 << EMAC_VLNINCREP_VLC_SHIFT) /* VLAN tag insertion */ +# define EMAC_VLNINCREP_VLC_TAGREP (3 << EMAC_VLNINCREP_VLC_SHIFT) /* VLAN tag replacement */ +#define EMAC_VLNINCREP_VLP (1 << 18) /* Bit 18: VLAN Priority Control */ +#define EMAC_VLNINCREP_CSVL (1 << 19) /* Bit 19: C-VLAN or S-VLAN */ + +/* Ethernet MAC VLAN Hash Table */ + +#define EMAC_VLANHASH_VLHT_SHIFT (0) /* Bits 0-15: VLAN Hash Table */ +#define EMAC_VLANHASH_VLHT_MASK (0xffff << EMAC_VLANHASH_VLHT_SHIFT) + +/* Ethernet MAC Timestamp Control */ + +#define EMAC_TIMSTCTRL_TSEN (1 << 0) /* Bit 0: Timestamp Enable */ +#define EMAC_TIMSTCTRL_TSFCUPDT (1 << 1) /* Bit 1: Timestamp Fine or Coarse Update */ +#define EMAC_TIMSTCTRL_TSINIT (1 << 2) /* Bit 2: Timestamp Initialize */ +#define EMAC_TIMSTCTRL_TSUPDT (1 << 3) /* Bit 3: Timestamp Update */ +#define EMAC_TIMSTCTRL_INTTRIG (1 << 4) /* Bit 4: Timestamp Interrupt Trigger Enable */ +#define EMAC_TIMSTCTRL_ADDREGUP (1 << 5) /* Bit 5: Addend Register Update */ +#define EMAC_TIMSTCTRL_ALLF (1 << 8) /* Bit 8: Enable Timestamp For All Frames */ +#define EMAC_TIMSTCTRL_DGTLBIN (1 << 9) /* Bit 9: Timestamp Digital or Binary Rollover Control */ +#define EMAC_TIMSTCTRL_PTPVER2 (1 << 10) /* Bit 10: Enable PTP Packet Processing For Version 2 Format */ +#define EMAC_TIMSTCTRL_PTPETH (1 << 11) /* Bit 11: Enable Processing of PTP Over Ethernet Frames */ +#define EMAC_TIMSTCTRL_PTPIPV6 (1 << 12) /* Bit 12: Enable Processing of PTP Frames Sent Over IPv6-UDP */ +#define EMAC_TIMSTCTRL_PTPIPV4 (1 << 13) /* Bit 13: Enable Processing of PTP Frames Sent over IPv4-UDP */ +#define EMAC_TIMSTCTRL_TSEVNT (1 << 14) /* Bit 14: Enable Timestamp Snapshot for Event Messages */ +#define EMAC_TIMSTCTRL_TSMAST (1 << 15) /* Bit 15: Enable Snapshot for Messages Relevant to Master */ +#define EMAC_TIMSTCTRL_SELPTP_SHIFT (16) /* Bits 16-17: Select PTP packets for Taking Snapshots */ +#define EMAC_TIMSTCTRL_SELPTP_MASK (3 << EMAC_TIMSTCTRL_SELPTP_SHIFT) +# define EMAC_TIMSTCTRL_SELPTP(n) ((uint32_t)(n) << EMAC_TIMSTCTRL_SELPTP_SHIFT) +#define EMAC_TIMSTCTRL_PTPFLTR (1 << 18) /* Bit 18: Enable MAC address for PTP Frame Filtering */ + +/* Ethernet MAC Sub-Second Increment */ + +#define EMAC_SUBSECINC_SSINC_SHIFT (0) /* Bits 0-7: Sub-second Increment Value */ +#define EMAC_SUBSECINC_SSINC_MASK (0xff << EMAC_SUBSECINC_SSINC_SHIFT) + +/* Ethernet MAC System Time - Seconds (32-bit value) */ +/* Ethernet MAC System Time - Nanoseconds */ + +#define EMAC_TIMNANO_TSSS_SHIFT (0) /* Bits 0-30: Timestamp Sub-Seconds */ +#define EMAC_TIMNANO_TSSS_MASK (0x7fffffff << EMAC_TIMNANO_TSSS_SHIFT) + +/* Ethernet MAC System Time - Seconds Update (32-bit value) */ +/* Ethernet MAC System Time - Nanoseconds Update */ + +#define EMAC_TIMNANOU_TSSS_SHIFT (0) /* Bits 0-30: Timestamp Sub-Second */ +#define EMAC_TIMNANOU_TSSS_MASK (0x7fffffff << EMAC_TIMNANOU_TSSS_SHIFT) +#define EMAC_TIMNANOU_ADDSUB (1 << 31) /* Bit 31: Add or subtract time */ + +/* Ethernet MAC Timestamp Addend (32-bit value) */ +/* Ethernet MAC Target Time Seconds (32-bit value) */ +/* Ethernet MAC Target Time Nanoseconds */ + +#define EMAC_TARGNANO_TTSLO_SHIFT (0) /* Bits 0-30: Target Timestamp Low Register */ +#define EMAC_TARGNANO_TTSLO_MASK (0x7fffffff << EMAC_TARGNANO_TTSLO_SHIFT) +#define EMAC_TARGNANO_TRGTBUSY (1 << 31) /* Bit 31: Target Time Register Busy */ + +/* Ethernet MAC System Time-Higher Word Seconds */ + +#define EMAC_HWORDSEC_TSHWR_SHIFT (0) /* Bits 0-15: Target Timestamp Higher Word Register */ +#define EMAC_HWORDSEC_TSHWR_MASK (0xffff << EMAC_HWORDSEC_TSHWR_SHIFT) + +/* Ethernet MAC Timestamp Status */ + +#define EMAC_TIMSTAT_TSSOVF (1 << 0) /* Bit 0: Timestamp Seconds Overflow */ +#define EMAC_TIMSTAT_TSTARGT (1 << 1) /* Bit 1: Timestamp Target Time Reached */ + +/* Ethernet MAC PPS Control */ + +#define EMAC_PPSCTRL_PPSCTRL_SHIFT (0) /* Bits 0-3: EN0PPS Output Frequency Control (PPSCTRL) or Command Control (PPSCMD) */ +#define EMAC_PPSCTRL_PPSCTRL_MASK (15 << EMAC_PPSCTRL_PPSCTRL_SHIFT) +# define EMAC_PPSCTRL_PPSCTRL_1HZ (0 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* EN0PPS signal=PTP reference clock/sec */ +# define EMAC_PPSCTRL_PPSCTRL_2HZ (1 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=2 Hz; digital rollover=1 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_4HZ (2 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=4 Hz; digital rollover=2 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_8HZ (3 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=8 Hz; digital rollover=4 Hz, */ +# define EMAC_PPSCTRL_PPSCTRL_16HZ (4 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=16 Hz; digital rollover=8 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_32HZ (5 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=32 Hz; digital rollover=16 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_64HZ (6 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=64 Hz; digital rollover=32 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_128HZ (7 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=128 Hz; digital rollover=64 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_256HZ (8 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* binary rollover=256 Hz; digital rollover=128 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_512HZ (9 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* binary rollover=512 Hz; digital rollover=256 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_1024HZ (10 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* binary rollover=1.024 kHz; digital rollover=512 Hz */ +# define EMAC_PPSCTRL_PPSCTRL_2048HZ (11 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=2.048 kHz; digital rollover=1.024 kHz */ +# define EMAC_PPSCTRL_PPSCTRL_4096HZ (12 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=4.096 kHz; digital rollover=2.048 kHz */ +# define EMAC_PPSCTRL_PPSCTRL_8192HZ (13 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=8.192 kHz; digital rollover=4.096 kHz */ +# define EMAC_PPSCTRL_PPSCTRL_16384HZ (14 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=16.384 kHz; digital rollover=8.092 kHz */ +# define EMAC_PPSCTRL_PPSCTRL_32768HZ (15 << EMAC_PPSCTRL_PPSCTRL_SHIFT) /* Binary rollover=32.768 KHz; digital rollover=16.384 KHz */ +#define EMAC_PPSCTRL_PPSEN0 (1 << 4) /* Bit 4: Flexible PPS Output Mode Enable */ +#define EMAC_PPSCTRL_TRGMODS0_SHIFT (5) /* Bits 5-6: Target Time Register Mode for PPS0 Output */ +#define EMAC_PPSCTRL_TRGMODS0_MASK (3 << EMAC_PPSCTRL_TRGMODS0_SHIFT) +# define EMAC_PPSCTRL_TRGMODS0_INTONLY (0 << EMAC_PPSCTRL_TRGMODS0_SHIFT) /* Generate the interrupt event */ +# define EMAC_PPSCTRL_TRGMODS0_INTPPS0 (2 << EMAC_PPSCTRL_TRGMODS0_SHIFT) /* Generate the interrupt event and control EN0PPS */ +# define EMAC_PPSCTRL_TRGMODS0_PPS0ONLY (3 << EMAC_PPSCTRL_TRGMODS0_SHIFT) /* Control ENOPPS output */ + +/* Ethernet MAC PPS0 Interval (32-bit value) */ +/* Ethernet MAC PPS0 Width (32-bit value) */ + +/* Ethernet MAC DMA Bus Mode */ + +#define EMAC_DMABUSMOD_SWR (1 << 0) /* Bit 0: DMA Software Reset */ +#define EMAC_DMABUSMOD_DA (1 << 1) /* Bit 1: DMA Arbitration Scheme */ +#define EMAC_DMABUSMOD_DSL_SHIFT (2) /* Bits 2-6: Descriptor Skip Length */ +#define EMAC_DMABUSMOD_DSL_MASK (31 << EMAC_DMABUSMOD_DSL_SHIFT) +# define EMAC_DMABUSMOD_DSL(n) ((uint32_t)(n) << EMAC_DMABUSMOD_DSL_SHIFT) +#define EMAC_DMABUSMOD_ATDS (1 << 7) /* Bit 7: Alternate Descriptor Size */ +#define EMAC_DMABUSMOD_PBL_SHIFT (8) /* Bits 8-13: Programmable Burst Length */ +#define EMAC_DMABUSMOD_PBL_MASK (0x3f << EMAC_DMABUSMOD_PBL_SHIFT) +# define EMAC_DMABUSMOD_PBL(n) ((uint32_t)(n) << EMAC_DMABUSMOD_PBL_SHIFT) +#define EMAC_DMABUSMOD_PR_SHIFT (14) /* Bits 14-15: Priority Ratio */ +#define EMAC_DMABUSMOD_PR_MASK (3 << EMAC_DMABUSMOD_PR_SHIFT) +# define EMAC_DMABUSMOD_PR_1TO1 (0 << EMAC_DMABUSMOD_PR_SHIFT) /* Priority Ratio is 1:1 */ +# define EMAC_DMABUSMOD_PR_2TO1 (1 << EMAC_DMABUSMOD_PR_SHIFT) /* Priority Ratio is 2:1 */ +# define EMAC_DMABUSMOD_PR_3TO1 (2 << EMAC_DMABUSMOD_PR_SHIFT) /* Priority Ratio is 3:1 */ +# define EMAC_DMABUSMOD_PR_4TO1 (3 << EMAC_DMABUSMOD_PR_SHIFT) /* Priority Ratio is 4:1 */ +#define EMAC_DMABUSMOD_FB (1 << 16) /* Bit 16: Fixed Burst */ +#define EMAC_DMABUSMOD_RPBL_SHIFT (17) /* Bits 17:22: RX DMA Programmable Burst Length (PBL) */ +#define EMAC_DMABUSMOD_RPBL_MASK (0x3f << EMAC_DMABUSMOD_RPBL_SHIFT) +# define EMAC_DMABUSMOD_RPBL(n) ((uint32_t)(n) << EMAC_DMABUSMOD_RPBL_SHIFT) +#define EMAC_DMABUSMOD_USP (1 << 23) /* Bit 23: Use Separate Programmable Burst Length (PBL) */ +#define EMAC_DMABUSMOD_8XPBL (1 << 24) /* Bit 24: 8 x Programmable Burst Length (PBL) Mode */ +#define EMAC_DMABUSMOD_AAL (1 << 25) /* Bit 25: Address Aligned Beats */ +#define EMAC_DMABUSMOD_MB (1 << 26) /* Bit 26: Mixed Burst */ +#define EMAC_DMABUSMOD_TXPR (1 << 27) /* Bit 27: Transmit Priority */ +#define EMAC_DMABUSMOD_RIB (1 << 31) /* Bit 31: Rebuild Burst */ + +/* Ethernet MAC Transmit Poll Demand (32-bit value) */ +/* Ethernet MAC Receive Poll Demand (32-bit value) */ + +/* Ethernet MAC Receive Descriptor List Address */ + +#define EMAC_RXDLADDR_MASK (0xfffffffc) + +/* Ethernet MAC Transmit Descriptor List Address */ + +#define EMAC_TXDLADDR_MASK (0xfffffffc) + +/* Ethernet MAC DMA Interrupt Status and Ethernet MAC DMA Interrupt Mask Register (common bit definitions) */ + +#define EMAC_DMAINT_TI (1 << 0) /* Bit 0: Transmit interrupt */ +#define EMAC_DMAINT_TPSI (1 << 1) /* Bit 1: Transmit process stopped interrupt */ +#define EMAC_DMAINT_TBUI (1 << 2) /* Bit 2: Transmit buffer unavailable interrupt */ +#define EMAC_DMAINT_TJTI (1 << 3) /* Bit 3: Transmit jabber timeout interrupt */ +#define EMAC_DMAINT_OVFI (1 << 4) /* Bit 4: Overflow interrupt */ +#define EMAC_EMAINT_UNFI (1 << 5) /* Bit 5: Underflow interrupt */ +#define EMAC_DMAINT_RI (1 << 6) /* Bit 6: Receive interrupt */ +#define EMAC_DMAINT_RBUI (1 << 7) /* Bit 7: Receive buffer unavailable interrupt */ +#define EMAC_DMAINT_RPSI (1 << 8) /* Bit 8: Receive process stopped interrupt */ +#define EMAC_DMAINT_RWTI (1 << 9) /* Bit 9: Receive watchdog timeout interrupt */ +#define EMAC_DMAINT_ETI (1 << 10) /* Bit 10: Early transmit interrupt */ +#define EMAC_DMAINT_FBEI (1 << 13) /* Bit 13: Fatal bus error interrupt */ +#define EMAC_DMAINT_ERI (1 << 14) /* Bit 14: Early receive interrupt */ +#define EMAC_DMAINT_AIS (1 << 15) /* Bit 15: Abnormal interrupt summary */ +#define EMAC_DMAINT_NIS (1 << 16) /* Bit 16: Normal interrupt summary */ + +/* Ethernet MAC DMA Interrupt Status (unique fields) */ + +#define EMAC_DMARIS_RS_SHIFT (17) /* Bits 17-19: Received Process State */ +#define EMAC_DMARIS_RS_MASK (7 << EMAC_DMARIS_RS_SHIFT) +# define EMAC_DMARIS_RS_STOP (0 << EMAC_DMARIS_RS_SHIFT) /* Stopped: Reset or stop receive command issued */ +# define EMAC_DMARIS_RS_RUNRXTD (1 << EMAC_DMARIS_RS_SHIFT) /* Running: Fetching receive transfer descriptor */ +# define EMAC_DMARIS_RS_RUNRXD (3 << EMAC_DMARIS_RS_SHIFT) /* Running: Waiting for receive packet */ +# define EMAC_DMARIS_RS_SUSPEND (4 << EMAC_DMARIS_RS_SHIFT) /* Suspended: Receive descriptor unavailable */ +# define EMAC_DMARIS_RS_RUNCRD (5 << EMAC_DMARIS_RS_SHIFT) /* Running: Closing receive descriptor */ +# define EMAC_DMARIS_RS_TSWS (6 << EMAC_DMARIS_RS_SHIFT) /* Writing Timestamp */ +# define EMAC_DMARIS_RS_RUNTXD (7 << EMAC_DMARIS_RS_SHIFT) /* Running: Transferring receive packet data from buffer */ +#define EMAC_DMARIS_TS_SHIFT (20) /* Bits 20-22: Transmit Process State */ +#define EMAC_DMARIS_TS_MASK (7 << EMAC_DMARIS_TS_SHIFT) +# define EMAC_DMARIS_TS_STOP (0 << EMAC_DMARIS_TS_SHIFT) /* Stopped; Reset or Stop transmit command processed */ +# define EMAC_DMARIS_TS_RUNTXTD (1 << EMAC_DMARIS_TS_SHIFT) /* Running; Fetching transmit transfer descriptor */ +# define EMAC_DMARIS_TS_STATUS (2 << EMAC_DMARIS_TS_SHIFT) /* Running; Waiting for status */ +# define EMAC_DMARIS_TS_RUNTX (3 << EMAC_DMARIS_TS_SHIFT) /* Running; Reading data from host buffer and queuing to TX FIFO */ +# define EMAC_DMARIS_TS_TSTAMP (4 << EMAC_DMARIS_TS_SHIFT) /* Writing Timestamp */ +# define EMAC_DMARIS_TS_SUSPEND (6 << EMAC_DMARIS_TS_SHIFT) /* Suspended; Transmit descriptor unavailable or transmit underflow */ +# define EMAC_DMARIS_TS_RUNCTD (7 << EMAC_DMARIS_TS_SHIFT) /* Running; Closing transmit descriptor */ +#define EMAC_DMARIS_AE_SHIFT (23) /* Bits 23-25: Access Error */ +#define EMAC_DMARIS_AE_MASK (7 << EMAC_DMARIS_AE_SHIFT) +# define EMAC_DMARIS_AE_RXDMAWD (0 << EMAC_DMARIS_AE_SHIFT) /* Error during RX DMA Write Data Transfer */ +# define EMAC_DMARIS_AE_TXDMARD (3 << EMAC_DMARIS_AE_SHIFT) /* Error during TX DMA Read Data Transfer */ +# define EMAC_DMARIS_AE_RXDMADW (4 << EMAC_DMARIS_AE_SHIFT) /* Error during RX DMA Descriptor Write Access */ +# define EMAC_DMARIS_AE_TXDMADW (5 << EMAC_DMARIS_AE_SHIFT) /* Error during TX DMA Descriptor Write Access */ +# define EMAC_DMARIS_AE_RXDMADR (6 << EMAC_DMARIS_AE_SHIFT) /* Error during RX DMA Descriptor Read Access */ +# define EMAC_DMARIS_AE_TXDMADR (7 << EMAC_DMARIS_AE_SHIFT) /* Error during TX DMA Descriptor Read Access */ +#define EMAC_DMARIS_MMC (1 << 27) /* Bit 27: MAC MMC Interrupt */ +#define EMAC_DMARIS_PMT (1 << 28) /* Bit 28: MAC PMT Interrupt Status */ +#define EMAC_DMARIS_TT (1 << 29) /* Bit 29: Timestamp Trigger Interrupt Status */ + +/* Ethernet MAC DMA Operation Mode */ + +#define EMAC_DMAOPMODE_SR (1 << 1) /* Bit 1: Start or Stop Receive */ +#define EMAC_DMAOPMODE_OSF (1 << 2) /* Bit 2: Operate on Second Frame */ +#define EMAC_DMAOPMODE_RTC_SHIFT (3) /* Bits 3-4: Receive Threshold Control */ +#define EMAC_DMAOPMODE_RTC_MASK (3 << EMAC_DMAOPMODE_RTC_SHIFT) +# define EMAC_DMAOPMODE_RTC_64 (0 << EMAC_DMAOPMODE_RTC_SHIFT) /* 64 bytes */ +# define EMAC_DMAOPMODE_RTC_32 (1 << EMAC_DMAOPMODE_RTC_SHIFT) /* 32 bytes */ +# define EMAC_DMAOPMODE_RTC_96 (2 << EMAC_DMAOPMODE_RTC_SHIFT) /* 96 bytes */ +# define EMAC_DMAOPMODE_RTC_128 (3 << EMAC_DMAOPMODE_RTC_SHIFT) /* 128 bytes */ +#define EMAC_DMAOPMODE_DGF (1 << 5) /* Bit 5: Drop Giant Frame Enable */ +#define EMAC_DMAOPMODE_FUF (1 << 6) /* Bit 6: Forward Undersized Good Frames */ +#define EMAC_DMAOPMODE_FEF (1 << 7) /* Bit 7: Forward Error Frames */ +#define EMAC_DMAOPMODE_ST (1 << 13) /* Bit 13: Start or Stop Transmission Command */ +#define EMAC_DMAOPMODE_TTC_SHIFT (14) /* Bits 14-16: Transmit Threshold Control */ +#define EMAC_DMAOPMODE_TTC_MASK (7 << EMAC_DMAOPMODE_TTC_SHIFT) +# define EMAC_DMAOPMODE_TTC_64 (0 << EMAC_DMAOPMODE_TTC_SHIFT) /* 64 bytes */ +# define EMAC_DMAOPMODE_TTC_128 (1 << EMAC_DMAOPMODE_TTC_SHIFT) /* 128 bytes */ +# define EMAC_DMAOPMODE_TTC_192 (2 << EMAC_DMAOPMODE_TTC_SHIFT) /* 192 bytes */ +# define EMAC_DMAOPMODE_TTC_256 (3 << EMAC_DMAOPMODE_TTC_SHIFT) /* 256 bytes */ +# define EMAC_DMAOPMODE_TTC_40 (4 << EMAC_DMAOPMODE_TTC_SHIFT) /* 40 bytes */ +# define EMAC_DMAOPMODE_TTC_32 (5 << EMAC_DMAOPMODE_TTC_SHIFT) /* 32 bytes */ +# define EMAC_DMAOPMODE_TTC_24 (6 << EMAC_DMAOPMODE_TTC_SHIFT) /* 24 bytes */ +# define EMAC_DMAOPMODE_TTC_16 (7 << EMAC_DMAOPMODE_TTC_SHIFT) /* 16 bytes */ +#define EMAC_DMAOPMODE_FTF (1 << 20) /* Bit 20: Flush Transmit FIFO */ +#define EMAC_DMAOPMODE_TSF (1 << 21) /* Bit 21: Transmit Store and Forward */ +#define EMAC_DMAOPMODE_DFF (1 << 24) /* Bit 24: Disable Flushing of Received Frames */ +#define EMAC_DMAOPMODE_RSF (1 << 25) /* Bit 25: Receive Store and Forward */ +#define EMAC_DMAOPMODE_DT (1 << 26) /* Bit 26: Disable Dropping of TCP/IP Checksum Error Frames */ + +/* Ethernet MAC Missed Frame and Buffer Overflow Counter */ + +#define EMAC_MFBOC_MISFRMCNT_SHIFT (0) /* Bits 0-15: Missed Frame Counter */ +#define EMAC_MFBOC_MISFRMCNT_MASK (0xffff << EMAC_MFBOC_MISFRMCNT_SHIFT) +#define EMAC_MFBOC_MISCNTOVF (1 << 16) /* Bit 16: Overflow bit for Missed Frame Counter */ +#define EMAC_MFBOC_OVFFRMCNT_SHIFT (17) /* Bits 17-27: Overflow Frame Counter */ +#define EMAC_MFBOC_OVFFRMCNT_MASK (0x7ff << EMAC_MFBOC_OVFFRMCNT_SHIFT) +#define EMAC_MFBOC_OVFCNTOVF (1 << 28) /* Bit 28: Overflow Bit for FIFO Overflow Counter */ + +/* Ethernet MAC Receive Interrupt Watchdog Timer */ + +#define EMAC_RXINTWDT_RIWT_SHIFT (0) /* Bits 0-7: Receive Interrupt Watchdog Timer Count */ +#define EMAC_RXINTWDT_RIWT_MASK (0xff << EMAC_RXINTWDT_RIWT_SHIFT) + +/* Ethernet MAC Current Host Transmit Descriptor (32-bit value) */ +/* Ethernet MAC Current Host Receive Descriptor (32-bit value) */ +/* Ethernet MAC Current Host Transmit Buffer Address (32-bit value) */ +/* Ethernet MAC Current Host Receive Buffer Address (32-bit value) */ + +/* Ethernet MAC Peripheral Property Register */ + +#define EMAC_PP_PHYTYPE_SHIFT (0) /* Bits 0-2: Ethernet PHY Type */ +#define EMAC_PP_PHYTYPE_MASK (7 << EMAC_PP_PHYTYPE_SHIFT) +# define EMAC_PP_PHYTYPE_NONE (0 << EMAC_PP_PHYTYPE_SHIFT) /* No PHY */ +# define EMAC_PP_PHYTYPE_FURY (1 << EMAC_PP_PHYTYPE_SHIFT) /* Fury class PHY */ +# define EMAC_PP_PHYTYPE_TPFS (2 << EMAC_PP_PHYTYPE_SHIFT) /* Tempest/Firestorm class PHY */ +# define EMAC_PP_PHYTYPE_SNOWFLAKE (3 << EMAC_PP_PHYTYPE_SHIFT) /* Snowflake class PHY */ +#define EMAC_PP_MACTYPE_SHIFT (8) /* Bits 8-11: Ethernet MAC Type */ +#define EMAC_PP_MACTYPE_MASK (7 << EMAC_PP_MACTYPE_SHIFT) +# define EMAC_PP_MACTYPE_LM3S (0 << EMAC_PP_MACTYPE_SHIFT) /* Stellaris® LM3S-class MAC */ +# define EMAC_PP_MACTYPE_TM4C129X (1 << EMAC_PP_MACTYPE_SHIFT) /* Tiva TM4E129x-class MAC */ + +/* Ethernet MAC Peripheral Configuration Register */ + +#define EMAC_PC_PHYHOLD (1 << 0) /* Bit 0: Ethernet PHY Hold */ +#define EMAC_PC_ANMODE_SHIFT (1) /* Bits 1-2: Auto Negotiation Mode */ +#define EMAC_PC_ANMODE_MASK (3 << EMAC_PC_ANMODE_SHIFT) +# define EMAC_PC_ANMODE_10HD (0 << EMAC_PC_ANMODE_SHIFT) /* When ANEN = 0x0, mode is 10Base-T, Half-Duplex */ +# define EMAC_PC_ANMODE_10FD (1 << EMAC_PC_ANMODE_SHIFT) /* When ANEN = 0x0, mode is 10Base-T, Full-Duplex */ +# define EMAC_PC_ANMODE_100HD (2 << EMAC_PC_ANMODE_SHIFT) /* When ANEN = 0x0, mode is 100Base-TX, Half-Duplex */ +# define EMAC_PC_ANMODE_100FD (3 << EMAC_PC_ANMODE_SHIFT) /* When ANEN = 0x0, mode is 100Base-TX, Full-Duplex */ +#define EMAC_PC_ANEN (1 << 3) /* Bit 3: Auto Negotiation Enable */ +#define EMAC_PC_FASTANSEL_SHIFT (4) /* Bits 4-5: Fast Auto Negotiation Select */ +#define EMAC_PC_FASTANSEL_MASK (3 << EMAC_PC_FASTANSEL_SHIFT) +# define EMAC_PC_FASTANSEL(n) ((uint32_t)(n) << EMAC_PC_FASTANSEL_SHIFT) +#define EMAC_PC_FASTANEN (1 << 6) /* Bit 6: Fast Auto Negotiation Enable */ +#define EMAC_PC_EXTFD (1 << 7) /* Bit 7: Extended Full Duplex Ability */ +#define EMAC_PC_FASTLUPD (1 << 8) /* Bit 8: FAST Link-Up in Parallel Detect */ +#define EMAC_PC_FASTRXDV (1 << 9) /* Bit 9: Fast RXDV Detection */ +#define EMAC_PC_MDIXEN (1 << 10) /* Bit 10: MDIX Enable */ +#define EMAC_PC_FASTMDIX (1 << 11) /* Bit 11: Fast Auto MDI-X */ +#define EMAC_PC_RBSTMDIX (1 << 12) /* Bit 12: Robust Auto MDI-X */ +#define EMAC_PC_MDISWAP (1 << 13) /* Bit 13: MDI Swap */ +#define EMAC_PC_POLSWAP (1 << 14) /* Bit 14: Polarity Swap */ +#define EMAC_PC_FASTLDMODE_SHIFT (15) /* Bits 15-19: Fast Link Down Mode */ +#define EMAC_PC_FASTLDMODE_MASK (31 << EMAC_PC_FASTLDMODE_SHIFT) +# define EMAC_PC_FASTLDMODE(n) ((uint32_t)(n) << EMAC_PC_FASTLDMODE_SHIFT) +#define EMAC_PC_TDRRUN (1 << 20) /* Bit 20: TDR Auto Run */ +#define EMAC_PC_LRR (1 << 21) /* Bit 21: Link Loss Recovery */ +#define EMAC_PC_ISOMIILL (1 << 22) /* Bit 22: Isolate MII in Link Loss */ +#define EMAC_PC_RXERIDLE (1 << 23) /* Bit 23: RXER Detection During Idle */ +#define EMAC_PC_NIBDETDIS (1 << 24) /* Bit 24: Odd Nibble TXER Detection Disable */ +#define EMAC_PC_DIGRESTART (1 << 25) /* Bit 25: PHY Soft Restart */ +#define EMAC_PC_PINTFS_SHIFT (28) /* Bits 28-30: Ethernet Interface Select */ +#define EMAC_PC_PINTFS_MASK (7 << EMAC_PC_PINTFS_SHIFT) +# define EMAC_PC_PINTFS_MII (0 << EMAC_PC_PINTFS_SHIFT) /* MII: Internal PHY or external PHY connected via MII */ +# define EMAC_PC_PINTFS_RMII (4 << EMAC_PC_PINTFS_SHIFT) /* RMII: External PHY connected via RMII */ +#define EMAC_PC_PHYEXT (1 << 31) /* Bit 31: PHY Select */ + +/* Ethernet MAC Clock Configuration Register */ + +#define EMAC_CC_CLKEN (1 << 16) /* Bit 16: EN0RREF_CLK Signal Enable */ +#define EMAC_CC_POL (1 << 17) /* Bit 17: LED Polarity Control */ +#define EMAC_CC_PTPCEN (1 << 18) /* Bit 18: PTP Clock Reference Enable */ + +/* Ethernet PHY Raw Interrupt Status */ + +#define EMAC_PHYRIS_INT (1 << 0) /* Bit 0: Ethernet PHY Raw Interrupt Status */ + +/* Ethernet PHY Interrupt Mask */ + +#define EMAC_PHYIM_INT (1 << 0) /* Bit 0: Ethernet PHY Interrupt Mask */ + +/* RW1C Ethernet PHY Masked Interrupt Status and Clear */ + +#define EMAC_PHYMISC_INT (1 << 0) /* Bit 0: Ethernet PHY Status and Clear register */ + +/* MII Management Register Bit Definitions */ + +/* Ethernet PHY Basic Mode Control */ + +#define EPHY_BMCR_COLLTST (1 << 7) /* Bit 7: Collision Test */ +#define EPHY_BMCR_DUPLEXM (1 << 8) /* Bit 8: Duplex Mode */ +#define EPHY_BMCR_RESTARTAN (1 << 9) /* Bit 9: Restart Auto-Negotiation */ +#define EPHY_BMCR_ISOLATE (1 << 10) /* Bit 10: Port Isolate */ +#define EPHY_BMCR_PWRDWN (1 << 11) /* Bit 11: Power Down */ +#define EPHY_BMCR_ANEN (1 << 12) /* Bit 12: Auto-Negotiate Enable */ +#define EPHY_BMCR_SPEED (1 << 13) /* Bit 13: Speed Select */ +#define EPHY_BMCR_MIILOOPBK (1 << 14) /* Bit 14: MII Loopback */ +#define EPHY_BMCR_MIIRESET (1 << 15) /* Bit 15: MII Register reset */ + +/* Ethernet PHY Basic Mode Status */ + +#define EPHY_BMSR_EXTEN (1 << 0) /* Bit 0: Extended Capability Enable */ +#define EPHY_BMSR_JABBER (1 << 1) /* Bit 1: Jabber Detect */ +#define EPHY_BMSR_LINKSTAT (1 << 2) /* Bit 2: Link Status */ +#define EPHY_BMSR_ANEN (1 << 3) /* Bit 3: Auto Negotiation Enabled */ +#define EPHY_BMSR_RFAULT (1 << 4) /* Bit 4: Remote Fault */ +#define EPHY_BMSR_ANC (1 << 5) /* Bit 5: Auto-Negotiation Complete */ +#define EPHY_BMSR_MFPRESUP (1 << 6) /* Bit 6: Preamble Suppression Capable */ +#define EPHY_BMSR_10BTHD (1 << 11) /* Bit 11: 10 Base-T Half Duplex Capable */ +#define EPHY_BMSR_10BTFD (1 << 12) /* Bit 12: 10 Base-T Full Duplex Capable */ +#define EPHY_BMSR_100BTXHD (1 << 13) /* Bit 13: 100Base-TX Half Duplex Capable */ +#define EPHY_BMSR_100BTXFD (1 << 14) /* Bit 14: 100Base-TX Full Duplex Capable */ + +/* Ethernet PHY Identifier Register 1 (Most significant 16 bits of the OUI) */ +/* Ethernet PHY Identifier Register 2 */ + +#define EPHY_ID2_MDLREV_SHIFT (0) /* Bits 0-3: Model Revision Number */ +#define EPHY_ID2_MDLREV_MASK (15 << EPHY_ID2_MDLREV_SHIFT) +#define EPHY_ID2_VNDRMDL_SHIFT (4) /* Bits 4-9: Vendor Model Number */ +#define EPHY_ID2_VNDRMDL_MASK (0x3f << EPHY_ID2_VNDRMDL_SHIFT) +#define EPHY_ID2_OUILSB_SHIFT (10) /* Bits 10-15: OUI Least Significant Bits */ +#define EPHY_ID2_OUILSB_MASK (0x3f << EPHY_ID2_OUILSB_SHIFT) + +/* Ethernet PHY Auto-Negotiation Advertisement */ + +#define EPHY_ANA_SELECT_SHIFT (0) /* Bits 0-4: Protocol Selection */ +#define EPHY_ANA_SELECT_MASK (31 << EPHY_ANA_SELECT_SHIFT) +# define EPHY_ANA_SELECT(n) ((uint16_t)(n) << EPHY_ANA_SELECT_SHIFT) +# define EPHY_ANA_SELECT_802p3U (1 << EPHY_ANA_SELECT_SHIFT) +#define EPHY_ANA_10BT (1 << 5) /* Bit 5: 10Base-T Support */ +#define EPHY_ANA_10BTFD (1 << 6) /* Bit 6: 10Base-T Full Duplex Support */ +#define EPHY_ANA_100BTX (1 << 7) /* Bit 7: 100Base-TX Support */ +#define EPHY_ANA_100BTXFD (1 << 8) /* Bit 8: 100Base-TX Full Duplex Support */ +#define EPHY_ANA_100BT4 (1 << 9) /* Bit 9: 100Base-T4 Support */ +#define EPHY_ANA_PAUSE (1 << 10) /* Bit 10: PAUSE Support for Full Duplex Links */ +#define EPHY_ANA_ASMDUP (1 << 11) /* Bit 11: Asymmetric PAUSE support for Full Duplex Links */ +#define EPHY_ANA_RF (1 << 13) /* Bit 13: Remote Fault */ +#define EPHY_ANA_NP (1 << 15) /* Bit 15: Next Page Indication */ + +/* Ethernet PHY Auto-Negotiation Link Partner Ability */ + +#define EPHY_ANLPA_SELECT_SHIFT (0) /* Bits 0-4: Protocol Selection */ +#define EPHY_ANLPA_SELECT_MASK (31 << EPHY_ANLPA_SELECT_SHIFT) +# define EPHY_ANLPA_SELECT_802p3U (1 << EPHY_ANA_SELECT_SHIFT) +#define EPHY_ANLPA_10BT (1 << 5) /* Bit 5: 10Base-T Support */ +#define EPHY_ANLPA_10BTFD (1 << 6) /* Bit 6: 10Base-T Full Duplex Support */ +#define EPHY_ANLPA_100BTX (1 << 7) /* Bit 7: 100Base-TX Support */ +#define EPHY_ANLPA_100BTXFD (1 << 8) /* Bit 8: 100Base-TX Full Duplex Support */ +#define EPHY_ANLPA_100BT4 (1 << 9) /* Bit 9: 100Base-T4 Support */ +#define EPHY_ANLPA_PAUSE (1 << 10) /* Bit 10: PAUSE */ +#define EPHY_ANLPA_ASMDUP (1 << 11) /* Bit 11: Asymmetric PAUSE */ +#define EPHY_ANLPA_RF (1 << 13) /* Bit 13: Remote Fault */ +#define EPHY_ANLPA_ACK (1 << 14) /* Bit 14: Acknowledge */ +#define EPHY_ANLPA_NP (1 << 15) /* Bit 15: Next Page Indication */ + +/* Ethernet PHY Auto-Negotiation Expansion */ + +#define EPHY_ANER_LPANABLE (1 << 0) /* Bit 0: Link Partner Auto-Negotiation Able */ +#define EPHY_ANER_PAGERX (1 << 1) /* Bit 1: Link Code Word Page Received */ +#define EPHY_ANER_NPABLE (1 << 2) /* Bit 2: Next Page Able */ +#define EPHY_ANER_LPNPABLE (1 << 3) /* Bit 3: Link Partner Next Page Able */ +#define EPHY_ANER_PDF (1 << 4) /* Bit 4: Parallel Detection Fault */ + +/* Ethernet PHY Auto-Negotiation Next Page TX */ + +#define EPHY_ANNPTR_CODE_SHIFT (0) /* Bits 0-10: Code */ +#define EPHY_ANNPTR_CODE_MASK (0x7ff << EPHY_ANNPTR_CODE_SHIFT) +# define EPHY_ANNPTR_CODE(n) ((uint16_t)(n) << EPHY_ANNPTR_CODE_SHIFT) +#define EPHY_ANNPTR_TOGTX (1 << 11) /* Bit 11: Toggle */ +#define EPHY_ANNPTR_ACK2 (1 << 12) /* Bit 12: Acknowledge 2 */ +#define EPHY_ANNPTR_MP (1 << 13) /* Bit 13: Message Page */ +#define EPHY_ANNPTR_NP (1 << 15) /* Bit 15: Next Page Indication */ + +/* Ethernet PHY Auto-Negotiation Link Partner Ability Next Page */ + +#define EPHY_ANLNPTR_CODE_SHIFT (0) /* Bits 0-10: Code */ +#define EPHY_ANLNPTR_CODE_MASK (0x7ff << EPHY_ANLNPTR_CODE_SHIFT) +#define EPHY_ANLNPTR_TOG (1 << 11) /* Bit 11: Toggle */ +#define EPHY_ANLNPTR_ACK2 (1 << 12) /* Bit 12: Acknowledge 2 */ +#define EPHY_ANLNPTR_MP (1 << 13) /* Bit 13: Message Page */ +#define EPHY_ANLNPTR_ACK (1 << 14) /* Bit 14: Acknowledge */ +#define EPHY_ANLNPTR_NP (1 << 15) /* Bit 15: Next Page Indication */ + +/* Ethernet PHY Configuration 1 */ + +#define EPHY_CFG1_FRXDVDET (1 << 1) /* Bit 1: FAST RXDV Detection */ + +#define EPHY_CFG1_FANSEL_SHIFT (2) /* Bits 2-3: Fast Auto-Negotiation Select Configuration */ +#define EPHY_CFG1_FANSEL_MASK (3 << EPHY_CFG1_FANSEL_SHIFT) +# define EPHY_CFG1_FANSEL_BLT80 (0 << EPHY_CFG1_FANSEL_SHIFT) /* Break Link Timer: 80 ms */ +# define EPHY_CFG1_FANSEL_BLT120 (1 << EPHY_CFG1_FANSEL_SHIFT) /* Break Link Timer: 120 ms */ +# define EPHY_CFG1_FANSEL_BLT240 (2 << EPHY_CFG1_FANSEL_SHIFT) /* Break Link Timer: 240 ms */ +#define EPHY_CFG1_FASTANEN (1 << 4) /* Bit 4: Fast Auto Negotiation Enable */ +#define EPHY_CFG1_RAMDIX (1 << 5) /* Bit 5: Robust Auto MDI/MDIX */ +#define EPHY_CFG1_FAMDIX (1 << 6) /* Bit 6: Fast Auto MDI/MDIX */ +#define EPHY_CFG1_LLR (1 << 7) /* Bit 7: Link Loss Recovery */ +#define EPHY_CFG1_TDRAR (1 << 8) /* Bit 8: TDR Auto-Run at Link Down */ +#define EPHY_CFG1_DONE (1 << 15) /* Bit 15: Configuration Done */ + +/* Ethernet PHY Configuration 2 */ + +#define EPHY_CFG2_ODDNDETDIS (1 << 1) /* Bit 1: Detection of Transmit Error */ +#define EPHY_CFG2_RXERRIDLE (1 << 2) /* Bit 2: Detection of Receive Symbol Error During IDLE State */ +#define EPHY_CFG2_ISOMIILL (1 << 3) /* Bit 3: Isolate MII outputs when Enhanced Link is not Achievable */ +#define EPHY_CFG2_ENLEDLINK (1 << 4) /* Bit 4: Enhanced LED Functionality */ +#define EPHY_CFG2_EXTFD (1 << 5) /* Bit 5: Extended Full-Duplex Ability */ +#define EPHY_CFG2_FLUPPD (1 << 6) /* Bit 6: Fast Link-Up in Parallel Detect Mode */ + +/* Ethernet PHY Configuration 3 */ + +#define EPHY_CFG3_FLDWNM_SHIFT (0) /* Bits 0-4: Fast Link Down Modes */ +#define EPHY_CFG3_FLDWNM_MASK (31 << EPHY_CFG3_FLDWNM_SHIFT) +# define EPHY_CFG3_FLDWNM(n) ((uint16_t)(n) << EPHY_CFG3_FLDWNM_SHIFT) +#define EPHY_CFG3_MDIMDIXS (1 << 6) /* Bit 6: MDI/MDIX Swap */ +#define EPHY_CFG3_POLSWAP (1 << 7) /* Bit 7: Polarity Swap */ + +/* Ethernet PHY Register Control */ + +#define EPHY_REGCTL_DEVAD_SHIFT (0) /* Bits 0-4: Device Address */ +#define EPHY_REGCTL_DEVAD_MASK (31 << EPHY_REGCTL_DEVAD_SHIFT) +# define EPHY_REGCTL_DEVAD(n) ((uint16_t)(n) << EPHY_REGCTL_DEVAD_SHIFT) +#define EPHY_REGCTL_FUNC_SHIFT (14) /* Bits 14-15: Function */ +#define EPHY_REGCTL_FUNC_MASK (3 << EPHY_REGCTL_FUNC_SHIFT) +# define EPHY_REGCTL_FUNC_ADDR (0 << EPHY_REGCTL_FUNC_SHIFT) /* Address */ +# define EPHY_REGCTL_FUNC_DATANI (1 << EPHY_REGCTL_FUNC_SHIFT) /* Data, no post increment */ +# define EPHY_REGCTL_FUNC_DATAPIRW (2 << EPHY_REGCTL_FUNC_SHIFT) /* Data, post increment on read and write */ +# define EPHY_REGCTL_FUNC_DATAPIWO (3 << EPHY_REGCTL_FUNC_SHIFT) /* Data, post increment on write only */ + +/* Ethernet PHY Address or Data (16-bit value) */ + +/* Ethernet PHY Status */ + +#define EPHY_STS_LINK (1 << 0) /* Bit 0: Link Status */ +#define EPHY_STS_SPEED (1 << 1) /* Bit 1: Speed Status */ +#define EPHY_STS_DUPLEX (1 << 2) /* Bit 2: Duplex Status */ +#define EPHY_STS_MIILB (1 << 3) /* Bit 3: MII Loopback Status */ +#define EPHY_STS_ANS (1 << 4) /* Bit 4: Auto-Negotiation Status */ +#define EPHY_STS_JD (1 << 5) /* Bit 5: Jabber Detect */ +#define EPHY_STS_RF (1 << 6) /* Bit 6: Remote Fault */ +#define EPHY_STS_MIIREQ (1 << 7) /* Bit 7: MII Interrupt Pending */ +#define EPHY_STS_PAGERX (1 << 8) /* Bit 8: Link Code Page Received */ +#define EPHY_STS_DL (1 << 9) /* Bit 9: Descrambler Lock */ +#define EPHY_STS_SD (1 << 10) /* Bit 10: Signal Detect */ +#define EPHY_STS_FCSL (1 << 11) /* Bit 11: False Carrier Sense Latch */ +#define EPHY_STS_POLSTAT (1 << 12) /* Bit 12: Polarity Status */ +#define EPHY_STS_RXLERR (1 << 13) /* Bit 13: Receive Error Latch */ +#define EPHY_STS_MDIXM (1 << 14) /* Bit 14: MDI-X Mode */ + +/* Ethernet PHY Specific Control */ + +#define EPHY_SCR_INTEN (1 << 1) /* Bit 1: Interrupt Enable */ +#define EPHY_SCR_TINT (1 << 2) /* Bit 2: Test Interrupt */ +#define EPHY_SCR_COLFDM (1 << 4) /* Bit 4: Collision in Full-Duplex Mode */ +#define EPHY_SCR_LBFIFO_SHIFT (8) /* Bits 8-9: Loopback FIFO Depth */ +#define EPHY_SCR_LBFIFO_MASK (3 << EPHY_SCR_LBFIFO_SHIFT) +# define EPHY_SCR_LBFIFO_4 (0 << EPHY_SCR_LBFIFO_SHIFT) /* Four nibble FIFO */ +# define EPHY_SCR_LBFIFO_5 (1 << EPHY_SCR_LBFIFO_SHIFT) /* Five nibble FIFO */ +# define EPHY_SCR_LBFIFO_6 (2 << EPHY_SCR_LBFIFO_SHIFT) /* Six nibble FIFO */ +# define EPHY_SCR_LBFIFO_8 (3 << EPHY_SCR_LBFIFO_SHIFT) /* Eight nibble FIFO */ +#define EPHY_SCR_SBPYASS (1 << 11) /* Bit 11: Scrambler Bypass */ +#define EPHY_SCR_PSMODE_SHIFT (12) /* Bits 12-13: Power Saving Modes */ +#define EPHY_SCR_PSMODE_MASK (3 << EPHY_SCR_PSMODE_SHIFT) +# define EPHY_SCR_PSMODE_NORMAL (0 << EPHY_SCR_PSMODE_SHIFT) /* Normal operation mode. PHY is fully functional */ +# define EPHY_SCR_PSMODE_LOWPWR (1 << EPHY_SCR_PSMODE_SHIFT) /* IEEE Power Down */ +# define EPHY_SCR_PSMODE_ACTWOL (2 << EPHY_SCR_PSMODE_SHIFT) /* Active Sleep */ +# define EPHY_SCR_PSMODE_PASWOL (3 << EPHY_SCR_PSMODE_SHIFT) /* Passive Sleep */ +#define EPHY_SCR_PSEN (1 << 14) /* Bit 14: Power Saving Modes Enable */ +#define EPHY_SCR_DISCLK (1 << 15) /* Bit 15: Disable CLK */ + +/* Ethernet PHY MII Interrupt Status 1 */ + +#define EPHY_MISR1_RXHFEN (1 << 0) /* Bit 0: Receive Error Counter Register Half-Full Event Interrupt */ +#define EPHY_MISR1_FCHFEN (1 << 1) /* Bit 1: False Carrier Counter Register half-full Interrupt Enable */ +#define EPHY_MISR1_ANCEN (1 << 2) /* Bit 2: Auto-Negotiation Complete Interrupt Enable */ +#define EPHY_MISR1_DUPLEXMEN (1 << 3) /* Bit 3: Duplex Status Interrupt Enable */ +#define EPHY_MISR1_SPEEDEN (1 << 4) /* Bit 4: Speed Change Interrupt Enable */ +#define EPHY_MISR1_LINKSTATEN (1 << 5) /* Bit 5: Link Status Interrupt Enable */ +#define EPHY_MISR1_RXHF (1 << 8) /* Bit 8: Receive Error Counter Half-Full Interrupt */ +#define EPHY_MISR1_FCHF (1 << 9) /* Bit 9: False Carrier Counter Half-Full Interrupt */ +#define EPHY_MISR1_ANC (1 << 10) /* Bit 10: Auto-Negotiation Complete Interrupt */ +#define EPHY_MISR1_DUPLEXM (1 << 11) /* Bit 11: Change of Duplex Status Interrupt */ +#define EPHY_MISR1_SPEED (1 << 12) /* Bit 12: Change of Speed Status Interrupt */ +#define EPHY_MISR1_LINKSTAT (1 << 13) /* Bit 13: Change of Link Status Interrupt */ + +/* Ethernet PHY MII Interrupt Status 2 */ + +#define EPHY_MISR2_JABBEREN (1 << 0) /* Bit 0: Jabber Detect Event Interrupt Enable */ +#define EPHY_MISR2_POLINTEN (1 << 1) /* Bit 1: Polarity Changed Interrupt Enable */ +#define EPHY_MISR2_SLEEPEN (1 << 2) /* Bit 2: Sleep Mode Event Interrupt Enable */ +#define EPHY_MISR2_MDICOEN (1 << 3) /* Bit 3: MDI/MDIX Crossover Status Changed Interrupt Enable */ +#define EPHY_MISR2_LBFIFOEN (1 << 4) /* Bit 4: Loopback FIFO Overflow/Underflow Interrupt Enable */ +#define EPHY_MISR2_PAGERXEN (1 << 5) /* Bit 5: Page Receive Interrupt Enable */ +#define EPHY_MISR2_ANERREN (1 << 6) /* Bit 6: Auto-Negotiation Error Interrupt Enable */ +#define EPHY_MISR2_JABBER (1 << 8) /* Bit 8: Jabber Detect Event Interrupt */ +#define EPHY_MISR2_POLINT (1 << 9) /* Bit 9: Polarity Changed Interrupt */ +#define EPHY_MISR2_SLEEP (1 << 10) /* Bit 10: Sleep Mode Event Interrupt */ +#define EPHY_MISR2_MDICO (1 << 11) /* Bit 11: MDI/MDIX Crossover Status Changed Interrupt */ +#define EPHY_MISR2_LBFIFO (1 << 12) /* Bit 12: Loopback FIFO Overflow/Underflow Event Interrupt */ +#define EPHY_MISR2_PAGERX (1 << 13) /* Bit 13: Page Receive Interrupt */ +#define EPHY_MISR2_ANERR (1 << 14) /* Bit 14: Auto-Negotiation Error Interrupt */ + +/* Ethernet PHY False Carrier Sense Counter */ + +#define EPHY_FCSCR_FCSCNT_SHIFT (0) /* Bits 0-7: False Carrier Event Counter */ +#define EPHY_FCSCR_FCSCNT_MASK (0xff << EPHY_FCSCR_FCSCNT_SHIFT) + +/* Ethernet PHY Receive Error Count (16-bit value) */ + +/* Ethernet PHY BIST Control */ + +#define EPHY_BISTCR_LBMODE_SHIFT (0) /* Bits 0-4: Loopback Mode Select */ +#define EPHY_BISTCR_LBMODE_MASK (31 << EPHY_BISTCR_LBMODE_SHIFT) +# define EPHY_BISTCR_LBMODE_NPCSIN (1 << 0) /* Bit 0: Near-end loopback: PCS Input Loopback */ +# define EPHY_BISTCR_LBMODE_NPCSOUT (1 << 1) /* Bit 1: Near-end loopback: PCS Output Loopback (100Base-TX only) */ +# define EPHY_BISTCR_LBMODE_NDIG (1 << 2) /* Bit 2: Near-end loopback: Digital Loopback */ +# define EPHY_BISTCR_LBMODE_NANA (1 << 3) /* Bit 3: Near-end loopback: Analog Loopback (requires 100 Ohm termination) */ +# define EPHY_BISTCR_LBMODE_FREV (1 << 4) /* Bit 4: Far-end Loopback: Reverse Loopback */ +#define EPHY_BISTCR_TXMIILB (1 << 6) /* Bit 6: Transmit Data in MII Loopback Mode */ +#define EPHY_BISTCR_PWRMODE (1 << 8) /* Bit 8: Power Mode Indication */ +#define EPHY_BISTCR_PKTGENSTAT (1 << 9) /* Bit 9: Packet Generator Status Indication */ +#define EPHY_BISTCR_PRBSCHKSYNC (1 << 10) /* Bit 10: PRBS Checker Lock Sync Loss Indication */ +#define EPHY_BISTCR_PRBSCHKLK (1 << 11) /* Bit 11: PRBS Checker Lock Indication */ +#define EPHY_BISTCR_PKTEN (1 << 12) /* Bit 12: Packet Generation Enable */ +#define EPHY_BISTCR_PRBSPKT (1 << 13) /* Bit 13: Generated PRBS Packets */ +#define EPHY_BISTCR_PRBSM (1 << 14) /* Bit 14: PRBS Single/Continuous Mode */ + +/* Ethernet PHY LED Control */ + +#define EPHY_LEDCR_BLINKRATE_SHIFT (9) /* Bits 9-10: LED Blinking Rate (ON/OFF duration): */ +#define EPHY_LEDCR_BLINKRATE_MASK (3 << EPHY_LEDCR_BLINKRATE_SHIFT) +# define EPHY_LEDCR_BLINKRATE_20HZ (0 << EPHY_LEDCR_BLINKRATE_SHIFT) /* 20 Hz (50 ms) */ +# define EPHY_LEDCR_BLINKRATE_10HZ (1 << EPHY_LEDCR_BLINKRATE_SHIFT) /* 10 Hz (100 ms) */ +# define EPHY_LEDCR_BLINKRATE_5HZ (2 << EPHY_LEDCR_BLINKRATE_SHIFT) /* 5 Hz (200 ms) */ +# define EPHY_LEDCR_BLINKRATE_2HZ (3 << EPHY_LEDCR_BLINKRATE_SHIFT) /* 2 Hz (500 ms) */ + +/* Ethernet PHY Control */ + +#define EPHY_CTL_BYPLEDSTRCH (1 << 7) /* Bit 7: Bypass LED Stretching */ +#define EPHY_CTL_MIILNKSTAT (1 << 11) /* Bit 11: MII Link Status */ +#define EPHY_CTL_PAUSETX (1 << 12) /* Bit 12: Pause Transmit Negotiated Status */ +#define EPHY_CTL_PAUSERX (1 << 13) /* Bit 13: Pause Receive Negotiated Status */ +#define EPHY_CTL_FORCEMDI (1 << 14) /* Bit 14: Force MDIX */ +#define EPHY_CTL_AUTOMDI (1 << 15) /* Bit 15: Auto-MDIX Enable */ + +/* Ethernet PHY 10Base-T Status/Control */ + +#define EPHY_10BTSC_JABBERD (1 << 0) /* Bit 0: Jabber Disable */ +#define EPHY_10BTSC_POLSTAT (1 << 4) /* Bit 4: 10 Mb Polarity Status */ +#define EPHY_10BTSC_NLPDIS (1 << 7) /* Bit 7: Normal Link Pulse (NLP) Transmission Control */ +#define EPHY_10BTSC_SQUELCH_SHIFT (9) /* Bits 9-12: Squelch Configuration */ +#define EPHY_10BTSC_SQUELCH_MASK (15 << EPHY_10BTSC_SQUELCH_SHIFT) +# define EPHY_10BTSC_SQUELCH(n) ((uint16_t)(n) << EPHY_10BTSC_SQUELCH_SHIFT) +#define EPHY_10BTSC_RXTHEN (1 << 13) /* Bit 13: Lower Receiver Threshold Enable */ + +/* Ethernet PHY BIST Control and Status 1 */ + +#define EPHY_BICSR1_IPGLENGTH_SHIFT (0) /* Bits 0-7: BIST IPG Length */ +#define EPHY_BICSR1_IPGLENGTH_MASK (0xff << EPHY_BICSR1_IPGLENGTH_SHIFT) +# define EPHY_BICSR1_IPGLENGTH(n) ((uint16_t)(n) << EPHY_BICSR1_IPGLENGTH_SHIFT) +#define EPHY_BICSR1_ERRCNT_SHIFT (8) /* Bits 8-15: BIST Error Count */ +#define EPHY_BICSR1_ERRCNT_MASK (0xff << EPHY_BICSR1_ERRCNT_SHIFT) + +/* Ethernet PHY BIST Control and Status 2 */ + +#define EPHY_BICSR2_PKTLENGTH_SHIFT (0) /* Bits 0-10: BIST Packet Length */ +#define EPHY_BICSR2_PKTLENGTH_MASK (0x7ff << EPHY_BICSR2_PKTLENGTH_SHIFT) +# define EPHY_BICSR2_PKTLENGTH(n) ((uint16_t)(n << EPHY_BICSR2_PKTLENGTH_SHIFT) + +/* Ethernet PHY Cable Diagnostic Control */ + +#define EPHY_CDCR_FAIL (1 << 0) /* Bit 0: Cable Diagnostic Process Fail */ +#define EPHY_CDCR_DONE (1 << 1) /* Bit 1: Cable Diagnostic Process Done */ +#define EPHY_CDCR_LINKQUAL_SHIFT (8) /* Bits 8-9: Link Quality Indication */ +#define EPHY_CDCR_LINKQUAL_MASK (3 << EPHY_CDCR_LINKQUAL_SHIFT) +# define EPHY_CDCR_LINKQUAL_GOOD (1 << EPHY_CDCR_LINKQUAL_SHIFT) /* Good Quality Link Indication */ +# define EPHY_CDCR_LINKQUAL_MILD (2 << EPHY_CDCR_LINKQUAL_SHIFT) /* Mid- Quality Link Indication */ +# define EPHY_CDCR_LINKQUAL_POOR (3 << EPHY_CDCR_LINKQUAL_SHIFT) /* Poor Quality Link Indication */ +#define EPHY_CDCR_START (1 << 15) /* Bit 15: Cable Diagnostic Process Start */ + +/* Ethernet PHY Reset Control */ + +#define EPHY_RCR_SWRESTART (1 << 14) /* Bit 14: Software Restart */ +#define EPHY_RCR_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* Ethernet PHY LED Configuration */ + +#define EPHY_LEDCFG_LED0_SHIFT (0) /* Bit0-13: LED0 Configuration */ +#define EPHY_LEDCFG_LED0_MASK (15 << EPHY_LEDCFG_LED0_SHIFT) +# define EPHY_LEDCFG_LED0_LINK (0 << EPHY_LEDCFG_LED0_SHIFT) /* Link OK */ +# define EPHY_LEDCFG_LED0_RXTX (1 << EPHY_LEDCFG_LED0_SHIFT) /* RX/TX Activity */ +# define EPHY_LEDCFG_LED0_TX (2 << EPHY_LEDCFG_LED0_SHIFT) /* TX Activity */ +# define EPHY_LEDCFG_LED0_RX (3 << EPHY_LEDCFG_LED0_SHIFT) /* RX Activity */ +# define EPHY_LEDCFG_LED0_COL (4 << EPHY_LEDCFG_LED0_SHIFT) /* Collision */ +# define EPHY_LEDCFG_LED0_100BT (5 << EPHY_LEDCFG_LED0_SHIFT) /* 100-Base TX */ +# define EPHY_LEDCFG_LED0_10BT (6 << EPHY_LEDCFG_LED0_SHIFT) /* 10-Base TX */ +# define EPHY_LEDCFG_LED0_FD (7 << EPHY_LEDCFG_LED0_SHIFT) /* Full Duplex */ +# define EPHY_LEDCFG_LED0_LINKTXRX (8 << EPHY_LEDCFG_LED0_SHIFT) /* Link OK/Blink on TX/RX Activity */ +#define EPHY_LEDCFG_LED1_SHIFT (4) /* Bits 4-7: LED1 Configuration */ +#define EPHY_LEDCFG_LED1_MASK (15 << EPHY_LEDCFG_LED1_SHIFT) +# define EPHY_LEDCFG_LED1_LINK (0 << EPHY_LEDCFG_LED1_SHIFT) /* Link OK */ +# define EPHY_LEDCFG_LED1_RXTX (1 << EPHY_LEDCFG_LED1_SHIFT) /* RX/TX Activity */ +# define EPHY_LEDCFG_LED1_TX (2 << EPHY_LEDCFG_LED1_SHIFT) /* TX Activity */ +# define EPHY_LEDCFG_LED1_RX (3 << EPHY_LEDCFG_LED1_SHIFT) /* RX Activity */ +# define EPHY_LEDCFG_LED1_COL (4 << EPHY_LEDCFG_LED1_SHIFT) /* Collision */ +# define EPHY_LEDCFG_LED1_100BT (5 << EPHY_LEDCFG_LED1_SHIFT) /* 100-Base TX */ +# define EPHY_LEDCFG_LED1_10BT (6 << EPHY_LEDCFG_LED1_SHIFT) /* 10-Base TX */ +# define EPHY_LEDCFG_LED1_FD (7 << EPHY_LEDCFG_LED1_SHIFT) /* Full Duplex */ +# define EPHY_LEDCFG_LED1_LINKTXRX (8 << EPHY_LEDCFG_LED1_SHIFT) /* Link OK/Blink on TX/RX Activity */ +#define EPHY_LEDCFG_LED2_SHIFT (8) /* Bits 8-11: LED2 Configuration */ +#define EPHY_LEDCFG_LED2_MASK (15 << EPHY_LEDCFG_LED2_SHIFT) +# define EPHY_LEDCFG_LED2_LINK (0 << EPHY_LEDCFG_LED2_SHIFT) /* Link OK */ +# define EPHY_LEDCFG_LED2_RXTX (1 << EPHY_LEDCFG_LED2_SHIFT) /* RX/TX Activity */ +# define EPHY_LEDCFG_LED2_TX (2 << EPHY_LEDCFG_LED2_SHIFT) /* TX Activity */ +# define EPHY_LEDCFG_LED2_RX (3 << EPHY_LEDCFG_LED2_SHIFT) /* RX Activity */ +# define EPHY_LEDCFG_LED2_COL (4 << EPHY_LEDCFG_LED2_SHIFT) /* Collision */ +# define EPHY_LEDCFG_LED2_100BT (5 << EPHY_LEDCFG_LED2_SHIFT) /* 100-Base TX */ +# define EPHY_LEDCFG_LED2_10BT (6 << EPHY_LEDCFG_LED2_SHIFT) /* 10-Base TX */ +# define EPHY_LEDCFG_LED2_FD (7 << EPHY_LEDCFG_LED2_SHIFT) /* Full Duplex */ +# define EPHY_LEDCFG_LED2_LINKTXRX (8 << EPHY_LEDCFG_LED2_SHIFT) /* Link OK/Blink on TX/RX Activity */ + +/* DMA Descriptors **********************************************************************************/ +/* TDES0: Transmit descriptor Word0 */ + +#define EMAC_TDES0_DB (1 << 0) /* Bit 0: Deferred bit */ +#define EMAC_TDES0_UF (1 << 1) /* Bit 1: Underflow error */ +#define EMAC_TDES0_ED (1 << 2) /* Bit 2: Excessive deferral */ +#define EMAC_TDES0_CC_SHIFT (3) /* Bits 3-6: Collision count */ +#define EMAC_TDES0_CC_MASK (15 << EMAC_TDES0_CC_SHIFT) +#define EMAC_TDES0_VF (1 << 7) /* Bit 7: VLAN frame */ +#define EMAC_TDES0_EC (1 << 8) /* Bit 8: Excessive collision */ +#define EMAC_TDES0_LCO (1 << 9) /* Bit 9: Late collision */ +#define EMAC_TDES0_NC (1 << 10) /* Bit 10: No carrier */ +#define EMAC_TDES0_LCA (1 << 11) /* Bit 11: Loss of carrier */ +#define EMAC_TDES0_IPE (1 << 12) /* Bit 12: IP payload error */ +#define EMAC_TDES0_FF (1 << 13) /* Bit 13: Frame flushed */ +#define EMAC_TDES0_JT (1 << 14) /* Bit 14: Jabber timeout */ +#define EMAC_TDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define EMAC_TDES0_IHE (1 << 16) /* Bit 16: IP header error */ +#define EMAC_TDES0_TTSS (1 << 17) /* Bit 17: Transmit time stamp status */ +#define EMAC_TDES0_VLIC_SHIFT (18) /* Bits 18-19: VLAN Insertion Control */ +#define EMAC_TDES0_VLIC_MASK (3 << EMAC_TDES0_VLIC_SHIFT) +# define EMAC_TDES0_VLIC_NOACTION (0 << EMAC_TDES0_VLIC_SHIFT) /* Do not add a VLAN tag */ +# define EMAC_TDES0_VLIC_REMOVE (1 << EMAC_TDES0_VLIC_SHIFT) /* Remove the VLAN tag before sending */ +# define EMAC_TDES0_VLIC_INSERT (2 << EMAC_TDES0_VLIC_SHIFT) /* Insert a VLAN tag (EMACVLNINCREP) */ +# define EMAC_TDES0_VLIC_REPLACE (3 << EMAC_TDES0_VLIC_SHIFT) /* Replace the VLAN tag i(EMACVLNINCREP) */ +#define EMAC_TDES0_TCH (1 << 20) /* Bit 20: Second address chained */ +#define EMAC_TDES0_TER (1 << 21) /* Bit 21: Transmit end of ring */ +#define EMAC_TDES0_CIC_SHIFT (22) /* Bits 22-23: Checksum insertion control */ +#define EMAC_TDES0_CIC_MASK (3 << EMAC_TDES0_CIC_SHIFT) +# define EMAC_TDES0_CIC_DISABLED (0 << EMAC_TDES0_CIC_SHIFT) /* Checksum disabled */ +# define EMAC_TDES0_CIC_IH (1 << EMAC_TDES0_CIC_SHIFT) /* Insert IPv4 header checksum */ +# define EMAC_TDES0_CIC_IHPL (2 << EMAC_TDES0_CIC_SHIFT) /* Insert TCP/UDP/ICMP checksum */ +# define EMAC_TDES0_CIC_ALL (3 << EMAC_TDES0_CIC_SHIFT) /* TCP/UDP/ICMP checksum fully calculated */ +#define EMAC_TDES0_CRCR (1 << 24) /* Bit 24: CRC Replacement Control */ +#define EMAC_TDES0_TTSE (1 << 25) /* Bit 25: Transmit time stamp enable */ +#define EMAC_TDES0_DP (1 << 26) /* Bit 26: Disable pad */ +#define EMAC_TDES0_DC (1 << 27) /* Bit 27: Disable CRC */ +#define EMAC_TDES0_FS (1 << 28) /* Bit 28: First segment */ +#define EMAC_TDES0_LS (1 << 29) /* Bit 29: Last segment */ +#define EMAC_TDES0_IC (1 << 30) /* Bit 30: Interrupt on completion */ +#define EMAC_TDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* TDES1: Transmit descriptor Word1 */ + +#define EMAC_TDES1_TBS1_SHIFT (0) /* Bits 0-12: Transmit buffer 1 size */ +#define EMAC_TDES1_TBS1_MASK (0x1fff << EMAC_TDES1_TBS1_SHIFT) +# define EMAC_TDES1_TBS1(n) ((uint32_t)(n) << EMAC_TDES1_TBS1_SHIFT) +#define EMAC_TDES1_TBS2_SHIFT (16) /* Bits 16-28: Transmit buffer 2 size */ +#define EMAC_TDES1_TBS2_MASK (0x1fff << EMAC_TDES1_TBS2_SHIFT) +# define EMAC_TDES1_TBS2(n) ((uint32_t)(n) << EMAC_TDES1_TBS2_SHIFT) +#define EMAC_TDES1_CTRL_SHIFT (29) /* Bits 29-31:SA Insertion Control */ +#define EMAC_TDES1_CTRL_MASK (7 << EMAC_TDES1_CTRL_SHIFT) +# define EMAC_TDES1_CTRL_NOACTION (0 << EMAC_TDES1_CTRL_SHIFT) /* Do not include the source address */ +# define EMAC_TDES1_CTRL_INSERT (1 << EMAC_TDES1_CTRL_SHIFT) /* Insert the source address */ +# define EMAC_TDES1_CTRL_REPLACE (2 << EMAC_TDES1_CTRL_SHIFT) /* Replace the source address */ + +/* TDES2: Transmit descriptor Word2 (32-bit address) */ +/* TDES3: Transmit descriptor Word3 (32-bit address) */ +/* TDES6: Transmit descriptor Word6 (32-bit time stamp) */ +/* TDES7: Transmit descriptor Word7 (32-bit time stamp) */ + +/* RDES0: Receive descriptor Word0 */ + +#define EMAC_RDES0_ESA (1 << 0) /* Bit 0: Extended status available */ +#define EMAC_RDES0_CE (1 << 1) /* Bit 1: CRC error */ +#define EMAC_RDES0_DBE (1 << 2) /* Bit 2: Dribble bit error */ +#define EMAC_RDES0_RE (1 << 3) /* Bit 3: Receive error */ +#define EMAC_RDES0_RWT (1 << 4) /* Bit 4: Receive watchdog timeout */ +#define EMAC_RDES0_FT (1 << 5) /* Bit 5: Frame type */ +#define EMAC_RDES0_LCO (1 << 6) /* Bit 6: Late collision */ +#define EMAC_RDES0_TSV (1 << 7) /* Bit 7: Time stamp available */ +#define EMAC_RDES0_GIANT (1 << 7) /* Bit 7: Giant frame */ +#define EMAC_RDES0_LS (1 << 8) /* Bit 8: Last descriptor */ +#define EMAC_RDES0_FS (1 << 9) /* Bit 9: First descriptor */ +#define EMAC_RDES0_VLAN (1 << 10) /* Bit 10: VLAN tag */ +#define EMAC_RDES0_OE (1 << 11) /* Bit 11: Overflow error */ +#define EMAC_RDES0_LE (1 << 12) /* Bit 12: Length error */ +#define EMAC_RDES0_SAF (1 << 13) /* Bit 13: Source address filter fail */ +#define EMAC_RDES0_DE (1 << 14) /* Bit 14: Descriptor error */ +#define EMAC_RDES0_ES (1 << 15) /* Bit 15: Error summary */ +#define EMAC_RDES0_FL_SHIFT (16) /* Bits 16-29: Frame length */ +#define EMAC_RDES0_FL_MASK (0x3fff << EMAC_RDES0_FL_SHIFT) +#define EMAC_RDES0_AFM (1 << 30) /* Bit 30: Destination address filter fail */ +#define EMAC_RDES0_OWN (1 << 31) /* Bit 31: Own bit */ + +/* RDES1: Receive descriptor Word1 */ + +#define EMAC_RDES1_RBS1_SHIFT (0) /* Bits 0-12: Receive buffer 1 size */ +#define EMAC_RDES1_RBS1_MASK (0x1fff << EMAC_RDES1_RBS1_SHIFT) + /* Bit 13: Reserved */ +#define EMAC_RDES1_RCH (1 << 14) /* Bit 14: Second address chained */ +#define EMAC_RDES1_RER (1 << 15) /* Bit 15: Receive end of ring */ +#define EMAC_RDES1_RBS2_SHIFT (16) /* Bits 16-28: Receive buffer 2 size */ +#define EMAC_RDES1_RBS2_MASK (0x1fff << EMAC_RDES1_RBS2_SHIFT) +#define EMAC_RDES1_DIC (1 << 31) /* Bit 31: Disable interrupt on completion */ + +/* RDES2: Receive descriptor Word2 (32-bit address) */ +/* RDES3: Receive descriptor Word3 (32-bit address) */ + +/* RDES4: Receive descriptor Word4 */ + +#define EMAC_RDES4_IPPT_SHIFT (0) /* Bits 0-2: IP payload type */ +#define EMAC_RDES4_IPPT_MASK (7 << EMAC_RDES4_IPPT_SHIFT) +# define EMAC_RDES4_IPPT_UNKNOWN (0 << EMAC_RDES4_IPPT_SHIFT) /* Unknown */ +# define EMAC_RDES4_IPPT_UDP (1 << EMAC_RDES4_IPPT_SHIFT) /* UDP payload in IP datagram */ +# define EMAC_RDES4_IPPT_TCP (2 << EMAC_RDES4_IPPT_SHIFT) /* TCP payload in IP datagram */ +# define EMAC_RDES4_IPPT_ICMP (3 << EMAC_RDES4_IPPT_SHIFT) /* ICMP payload in IP datagram */ +#define EMAC_RDES4_IPHE (1 << 3) /* Bit 3: IP header error */ +#define EMAC_RDES4_IPPE (1 << 4) /* Bit 4: IP payload error */ +#define EMAC_RDES4_IPCB (1 << 5) /* Bit 5: IP checksum bypassed */ +#define EMAC_RDES4_IPV4PR (1 << 6) /* Bit 6: IPv4 packet received */ +#define EMAC_RDES4_IPV6PR (1 << 7) /* Bit 7: IPv6 packet received */ +#define EMAC_RDES4_PMT_SHIFT (8) /* Bits 8-11: PTP message type */ +#define EMAC_RDES4_PMT_MASK (15 << EMAC_RDES4_PMT_SHIFT) +# define EMAC_RDES4_PMT_NONE (0 << EMAC_RDES4_PMT_SHIFT) /* No PTP message received */ +# define EMAC_RDES4_PMT_SYNC (1 << EMAC_RDES4_PMT_SHIFT) /* SYNC (all clock types) */ +# define EMAC_RDES4_PMT_FOLLOWUP (2 << EMAC_RDES4_PMT_SHIFT) /* Follow_Up (all clock types) */ +# define EMAC_RDES4_PMT_DELAYREQ (3 << EMAC_RDES4_PMT_SHIFT) /* Delay_Req (all clock types) */ +# define EMAC_RDES4_PMT_DELAYRESP (4 << EMAC_RDES4_PMT_SHIFT) /* Delay_Resp (all clock types) */ +# define EMAC_RDES4_PMT_PDELREQAM (5 << EMAC_RDES4_PMT_SHIFT) /* Pdelay_Req (in peer-to-peer + * transparent clock) or Announce (in + * ordinary or boundary clock) */ +# define EMAC_RDES4_PMT_PDELREQMM (6 << EMAC_RDES4_PMT_SHIFT) /* Pdelay_Resp (in peer-to-peer + * transparent clock) or Management (in + * ordinary or boundary clock) */ +# define EMAC_RDES4_PMT_PDELREQFUS (7 << EMAC_RDES4_PMT_SHIFT) /* Pdelay_Resp_Follow_Up (in + * peer-to-peer transparent clock) or + * Signaling (for ordinary or boundary + * clock) */ +# define EMAC_RDES4_PMT_ANNOUNCE (8 << EMAC_RDES4_PMT_SHIFT) /* Announce */ +# define EMAC_RDES4_PMT_MANAGEMENT (9 << EMAC_RDES4_PMT_SHIFT) /* Management */ +# define EMAC_RDES4_PMT_SIGNALING (10 << EMAC_RDES4_PMT_SHIFT) /* Signaling */ +# define EMAC_RDES4_PMT_PTP (15 << EMAC_RDES4_PMT_SHIFT) /* PTP packet w/ Reserved message type */ +#define EMAC_RDES4_PFT (1 << 12) /* Bit 12: PTP frame type */ +#define EMAC_RDES4_PV (1 << 13) /* Bit 13: PTP version */ +#define EMAC_RDES4_TSD (1 << 14) /* Bit 14: Time stampe dropped */ + +/* RDES5: Receive descriptor Word5 - Reserved */ +/* RDES6: Receive descriptor Word6 (32-bit time stamp) */ +/* RDES7: Receive descriptor Word7 (32-bit time stamp) */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Ethernet TX DMA Descriptor */ + +struct emac_txdesc_s +{ + /* Normal DMA descriptor words */ + + volatile uint32_t tdes0; /* Status */ + volatile uint32_t tdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t tdes2; /* Buffer1 address pointer */ + volatile uint32_t tdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp */ + +#ifdef CONFIG_TIVA_EMAC_ENHANCEDDESC + volatile uint32_t tdes4; /* Reserved */ + volatile uint32_t tdes5; /* Reserved */ + volatile uint32_t tdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t tdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/* Ethernet RX DMA Descriptor */ + +struct emac_rxdesc_s +{ + volatile uint32_t rdes0; /* Status */ + volatile uint32_t rdes1; /* Control and buffer1/2 lengths */ + volatile uint32_t rdes2; /* Buffer1 address pointer */ + volatile uint32_t rdes3; /* Buffer2 or next descriptor address pointer */ + + /* Enhanced DMA descriptor words with time stamp and PTP support */ + +#ifdef CONFIG_TIVA_EMAC_ENHANCEDDESC + volatile uint32_t rdes4; /* Extended status for PTP receive descriptor */ + volatile uint32_t rdes5; /* Reserved */ + volatile uint32_t rdes6; /* Time Stamp Low value for transmit and receive */ + volatile uint32_t rdes7; /* Time Stamp High value for transmit and receive */ +#endif +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TM4C_ETHERNET_H */ diff --git a/arch/arm/src/tiva/chip/tm4c_flash.h b/arch/arm/src/tiva/chip/tm4c_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..d18a07581e0fc0c7cbc9b0be59c1b0541c0ee6f8 --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c_flash.h @@ -0,0 +1,404 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tm4c_flash.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on register definitions provided by: + * + * Copyright (C) 2014 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C_FLASH_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* FLASH dimensions ****************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_TM4C129XNC) || defined(CONFIG_ARCH_CHIP_TM4C1294NC) + +/* For the TM4C129X family, the Flash memory is configured in groups of four banks + * four banks of 16K x 128 bits (4 * 256 KB total) which are two-way interleaved. + * Because the memory is two-way interleaved and each bank individually is an 8-KB + * sector, when the user erases a sector, using the ERASE bits in the Flash Memory + * Control (FMC) register, it is a 16 KB erase. + */ + +# define TIVA_FLASH_NPAGES 64 +# define TIVA_FLASH_PAGESIZE 16384 +# define FLASH_PROTECT_SIZE 2048 + +#else +# warning "No flash dimensions defined for selected chip." +#endif + +#define TIVA_FLASH_SIZE (TIVA_FLASH_NPAGES * TIVA_FLASH_PAGESIZE) + +/* Flash register offsets ************************************************************/ + +/* Internal Memory Registers (Relative to Internal Memory Control Offset) */ + +#define TIVA_FLASH_FMA_OFFSET 0x0000 /* Flash Memory Address */ +#define TIVA_FLASH_FMD_OFFSET 0x0004 /* Flash Memory Data */ +#define TIVA_FLASH_FMC_OFFSET 0x0008 /* Flash Memory Control */ +#define TIVA_FLASH_FCRIS_OFFSET 0x000c /* Flash Controller Raw Interrupt Status */ +#define TIVA_FLASH_FCIM_OFFSET 0x0010 /* Flash Controller Interrupt Mask */ +#define TIVA_FLASH_FCMISC_OFFSET 0x0014 /* Flash Controller Masked Interrupt Status and Clear */ +#define TIVA_FLASH_FMC2_OFFSET 0x0020 /* Flash Memory Control 2 */ +#define TIVA_FLASH_FWBVAL_OFFSET 0x0030 /* Flash Write Buffer Valid */ +#define TIVA_FLASH_FLPEKEY_OFFSET 0x003c /* Flash Program/Erase Key */ +#define TIVA_FLASH_FWBN_OFFSET 0x0100 /* Flash Write Buffer n */ +#define TIVA_FLASH_PP_OFFSET 0x0fc0 /* Flash Peripheral Properties */ +#define TIVA_FLASH_FSIZE_OFFSET 0x0fc0 /* Flash Size */ +#define TIVA_FLASH_SSIZE_OFFSET 0x0fc4 /* SRAM Size */ +#define TIVA_FLASH_CONF_OFFSET 0x0fc8 /* Flash Configuration Register */ +#define TIVA_FLASH_ROMSWMAP_OFFSET 0x0fcc /* ROM Software Map */ +#define TIVA_FLASH_DMASZ_OFFSET 0x0fd0 /* Flash DMA Address Size */ +#define TIVA_FLASH_DMAST_OFFSET 0x0fd4 /* Flash DMA Starting Address */ + +/* Memory Registers (Relative to System Control Offset) */ + +#define TIVA_FLASH_RVP_OFFSET 0x00d4 /* Reset Vector Pointer */ +#define TIVA_FLASH_RMCTL_OFFSET 0x00f0 /* ROM Control */ +#define TIVA_FLASH_BOOTCFG_OFFSET 0x01d0 /* Boot Configuration */ +#define TIVA_FLASH_USERREG0_OFFSET 0x01e0 /* User Register 0 */ +#define TIVA_FLASH_USERREG1_OFFSET 0x01e4 /* User Register 1 */ +#define TIVA_FLASH_USERREG2_OFFSET 0x01e8 /* User Register 2 */ +#define TIVA_FLASH_USERREG3_OFFSET 0x01ec /* User Register 3 */ +#define TIVA_FLASH_FMPRE0_OFFSET 0x0200 /* Flash Memory Protection Read Enable 0 */ +#define TIVA_FLASH_FMPRE1_OFFSET 0x0204 /* Flash Memory Protection Read Enable 1 */ +#define TIVA_FLASH_FMPRE2_OFFSET 0x0208 /* Flash Memory Protection Read Enable 2 */ +#define TIVA_FLASH_FMPRE3_OFFSET 0x020c /* Flash Memory Protection Read Enable 3 */ +#define TIVA_FLASH_FMPRE4_OFFSET 0x0210 /* Flash Memory Protection Read Enable 4 */ +#define TIVA_FLASH_FMPRE5_OFFSET 0x0214 /* Flash Memory Protection Read Enable 5 */ +#define TIVA_FLASH_FMPRE6_OFFSET 0x0218 /* Flash Memory Protection Read Enable 6 */ +#define TIVA_FLASH_FMPRE7_OFFSET 0x021c /* Flash Memory Protection Read Enable 7 */ +#define TIVA_FLASH_FMPRE8_OFFSET 0x0220 /* Flash Memory Protection Read Enable 8 */ +#define TIVA_FLASH_FMPRE9_OFFSET 0x0224 /* Flash Memory Protection Read Enable 9 */ +#define TIVA_FLASH_FMPRE10_OFFSET 0x0228 /* Flash Memory Protection Read Enable 10 */ +#define TIVA_FLASH_FMPRE11_OFFSET 0x022c /* Flash Memory Protection Read Enable 11 */ +#define TIVA_FLASH_FMPRE12_OFFSET 0x0230 /* Flash Memory Protection Read Enable 12 */ +#define TIVA_FLASH_FMPRE13_OFFSET 0x0234 /* Flash Memory Protection Read Enable 13 */ +#define TIVA_FLASH_FMPRE14_OFFSET 0x0238 /* Flash Memory Protection Read Enable 14 */ +#define TIVA_FLASH_FMPRE15_OFFSET 0x023c /* Flash Memory Protection Read Enable 15 */ +#define TIVA_FLASH_FMPPE0_OFFSET 0x0400 /* Flash Memory Protection Program Enable 0 */ +#define TIVA_FLASH_FMPPE1_OFFSET 0x0404 /* Flash Memory Protection Program Enable 1 */ +#define TIVA_FLASH_FMPPE2_OFFSET 0x0408 /* Flash Memory Protection Program Enable 2 */ +#define TIVA_FLASH_FMPPE3_OFFSET 0x040c /* Flash Memory Protection Program Enable 3 */ +#define TIVA_FLASH_FMPPE4_OFFSET 0x0410 /* Flash Memory Protection Program Enable 4 */ +#define TIVA_FLASH_FMPPE5_OFFSET 0x0414 /* Flash Memory Protection Program Enable 5 */ +#define TIVA_FLASH_FMPPE6_OFFSET 0x0418 /* Flash Memory Protection Program Enable 6 */ +#define TIVA_FLASH_FMPPE7_OFFSET 0x041c /* Flash Memory Protection Program Enable 7 */ +#define TIVA_FLASH_FMPPE8_OFFSET 0x0420 /* Flash Memory Protection Program Enable 8 */ +#define TIVA_FLASH_FMPPE9_OFFSET 0x0424 /* Flash Memory Protection Program Enable 9 */ +#define TIVA_FLASH_FMPPE10_OFFSET 0x0428 /* Flash Memory Protection Program Enable 10 */ +#define TIVA_FLASH_FMPPE11_OFFSET 0x042c /* Flash Memory Protection Program Enable 11 */ +#define TIVA_FLASH_FMPPE12_OFFSET 0x0430 /* Flash Memory Protection Program Enable 12 */ +#define TIVA_FLASH_FMPPE13_OFFSET 0x0434 /* Flash Memory Protection Program Enable 13 */ +#define TIVA_FLASH_FMPPE14_OFFSET 0x0438 /* Flash Memory Protection Program Enable 14 */ +#define TIVA_FLASH_FMPPE15_OFFSET 0x043c /* Flash Memory Protection Program Enable 15 */ + +/* Flash register addresses **********************************************************/ +/* Internal Memory Registers (Internal Memory Control Offset) */ + +#define TIVA_FLASH_FMA (TIVA_FLASHCON_BASE + TIVA_FLASH_FMA_OFFSET) +#define TIVA_FLASH_FMD (TIVA_FLASHCON_BASE + TIVA_FLASH_FMD_OFFSET) +#define TIVA_FLASH_FMC (TIVA_FLASHCON_BASE + TIVA_FLASH_FMC_OFFSET) +#define TIVA_FLASH_FCRIS (TIVA_FLASHCON_BASE + TIVA_FLASH_FCRIS_OFFSET) +#define TIVA_FLASH_FCIM (TIVA_FLASHCON_BASE + TIVA_FLASH_FCIM_OFFSET) +#define TIVA_FLASH_FCMISC (TIVA_FLASHCON_BASE + TIVA_FLASH_FCMISC_OFFSET) +#define TIVA_FLASH_FMC2 (TIVA_FLASHCON_BASE + TIVA_FLASH_FMC2_OFFSET) +#define TIVA_FLASH_FWBVAL (TIVA_FLASHCON_BASE + TIVA_FLASH_FWBVAL_OFFSET) +#define TIVA_FLASH_FLPEKEY (TIVA_FLASHCON_BASE + TIVA_FLASH_FLPEKEY_OFFSET) +#define TIVA_FLASH_FWBN (TIVA_FLASHCON_BASE + TIVA_FLASH_FWBN_OFFSET) +#define TIVA_FLASH_PP (TIVA_FLASHCON_BASE + TIVA_FLASH_PP_OFFSET) +#define TIVA_FLASH_FSIZE (TIVA_FLASHCON_BASE + TIVA_FLASH_FSIZE_OFFSET) +#define TIVA_FLASH_SSIZE (TIVA_FLASHCON_BASE + TIVA_FLASH_SSIZE_OFFSET) +#define TIVA_FLASH_CONF (TIVA_FLASHCON_BASE + TIVA_FLASH_CONF_OFFSET) +#define TIVA_FLASH_ROMSWMAP (TIVA_FLASHCON_BASE + TIVA_FLASH_ROMSWMAP_OFFSET) +#define TIVA_FLASH_DMASZ (TIVA_FLASHCON_BASE + TIVA_FLASH_DMASZ_OFFSET) +#define TIVA_FLASH_DMAST (TIVA_FLASHCON_BASE + TIVA_FLASH_DMAST_OFFSET) + +/* Memory Registers (System Control Offset) */ + +#define TIVA_FLASH_RVP (TIVA_SYSCON_BASE + TIVA_FLASH_RVP_OFFSET) +#define TIVA_FLASH_RMCTL (TIVA_SYSCON_BASE + TIVA_FLASH_RMCTL_OFFSET) +#define TIVA_FLASH_BOOTCFG (TIVA_SYSCON_BASE + TIVA_FLASH_BOOTCFG_OFFSET) +#define TIVA_FLASH_USERREG0 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG0_OFFSET) +#define TIVA_FLASH_USERREG1 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG1_OFFSET) +#define TIVA_FLASH_USERREG2 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG2_OFFSET) +#define TIVA_FLASH_USERREG3 (TIVA_SYSCON_BASE + TIVA_FLASH_USERREG3_OFFSET) +#define TIVA_FLASH_FMPRE0 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE0_OFFSET) +#define TIVA_FLASH_FMPRE1 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE1_OFFSET) +#define TIVA_FLASH_FMPRE2 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE2_OFFSET) +#define TIVA_FLASH_FMPRE3 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE3_OFFSET) +#define TIVA_FLASH_FMPRE4 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE4_OFFSET) +#define TIVA_FLASH_FMPRE5 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE5_OFFSET) +#define TIVA_FLASH_FMPRE6 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE6_OFFSET) +#define TIVA_FLASH_FMPRE7 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE7_OFFSET) +#define TIVA_FLASH_FMPRE8 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE8_OFFSET) +#define TIVA_FLASH_FMPRE9 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE9_OFFSET) +#define TIVA_FLASH_FMPRE10 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE10_OFFSET) +#define TIVA_FLASH_FMPRE11 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE11_OFFSET) +#define TIVA_FLASH_FMPRE12 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE12_OFFSET) +#define TIVA_FLASH_FMPRE13 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE13_OFFSET) +#define TIVA_FLASH_FMPRE14 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE14_OFFSET) +#define TIVA_FLASH_FMPRE15 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPRE15_OFFSET) +#define TIVA_FLASH_FMPPE0 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE0_OFFSET) +#define TIVA_FLASH_FMPPE1 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE1_OFFSET) +#define TIVA_FLASH_FMPPE2 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE2_OFFSET) +#define TIVA_FLASH_FMPPE3 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE3_OFFSET) +#define TIVA_FLASH_FMPPE4 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE4_OFFSET) +#define TIVA_FLASH_FMPPE5 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE5_OFFSET) +#define TIVA_FLASH_FMPPE6 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE6_OFFSET) +#define TIVA_FLASH_FMPPE7 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE7_OFFSET) +#define TIVA_FLASH_FMPPE8 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE8_OFFSET) +#define TIVA_FLASH_FMPPE9 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE9_OFFSET) +#define TIVA_FLASH_FMPPE10 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE10_OFFSET) +#define TIVA_FLASH_FMPPE11 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE11_OFFSET) +#define TIVA_FLASH_FMPPE12 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE12_OFFSET) +#define TIVA_FLASH_FMPPE13 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE13_OFFSET) +#define TIVA_FLASH_FMPPE14 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE14_OFFSET) +#define TIVA_FLASH_FMPPE15 (TIVA_SYSCON_BASE + TIVA_FLASH_FMPPE15_OFFSET) + +/* Flash register bit definitions ****************************************************/ + +/* Internal Memory Registers (Relative to Internal Memory Control Offset) */ + +/* Flash Memory Address */ + +#define FLASH_FMA_OFFSET_SHIFT (0)/* Bits 0-19: Address Offset */ +#define FLASH_FMA_OFFSET_MASK (0xfffff << FLASH_FMA_OFFSET_SHIFT) + +/* Flash Memory Data (32-bit value) */ + +/* Flash Memory Control */ + +#define FLASH_FMC_WRITE (1 << 0) /* Bit 0: Write a Word into Flash Memory */ +#define FLASH_FMC_ERASE (1 << 1) /* Bit 1: Erase a Page of Flash Memory */ +#define FLASH_FMC_MERASE (1 << 2) /* Bit 2: Mass Erase Flash Memory */ +#define FLASH_FMC_COMT (1 << 3) /* Bit 3: Commit Register Value */ +#define FLASH_FMC_WRKEY_SHIFT (16) /* Bits 16-31: FLASH write key */ +#define FLASH_FMC_WRKEY_MASK (0xffff << FLASH_FMC_WRKEY_SHIFT) +# define FLASH_FMC_WRKEY (0xa442 << FLASH_FMC_WRKEY_SHIFT) + +/* Flash Controller Raw Interrupt Status */ + +#define FLASH_FCRIS_ARIS (1 << 0) /* Bit 0: Access Raw Interrupt Status */ +#define FLASH_FCRIS_PRIS (1 << 1) /* Bit 1: Programming Raw Interrupt Status */ +#define FLASH_FCRIS_ERIS (1 << 2) /* Bit 2: EEPROM Raw Interrupt Status */ +#define FLASH_FCRIS_VOLTRIS (1 << 9) /* Bit 9: Pump Voltage Raw Interrupt Status */ +#define FLASH_FCRIS_INVDRIS (1 << 10) /* Bit 10: Invalid Data Raw Interrupt Status */ +#define FLASH_FCRIS_ERRIS (1 << 11) /* Bit 11: Erase Verify Error Raw Interrupt Status */ +#define FLASH_FCRIS_PROGRIS (1 << 13) /* Bit 13: Program Verify Error Raw Interrupt Status */ + +/* Flash Controller Interrupt Mask */ + +#define FLASH_FCIM_AMASK (1 << 0) /* Bit 0: Access Interrupt Mask */ +#define FLASH_FCIM_PMASK (1 << 1) /* Bit 1: Programming Interrupt Mask */ +#define FLASH_FCIM_EMASK (1 << 2) /* Bit 2: EEPROM Interrupt Mask */ +#define FLASH_FCIM_VOLTMASK (1 << 9) /* Bit 8: VOLT Interrupt Mask */ +#define FLASH_FCIM_INVDMASK (1 << 10) /* Bit 10: Invalid Data Interrupt Mask */ +#define FLASH_FCIM_ERMASK (1 << 11) /* Bit 11: ERVER Interrupt Mask */ +#define FLASH_FCIM_PROGMASK (1 << 13) /* Bit 13: PROGVER Interrupt Mask */ + +/* Flash Controller Masked Interrupt Status and Clear */ + +#define FLASH_FCMISC_AMISC (1 << 0) /* Bit 0: Access Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_PMISC (1 << 1) /* Bit 1: Programming Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_EMISC (1 << 2) /* Bit 2: EEPROM Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_VOLTMISC (1 << 9) /* Bit 9: VOLT Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_INVDMISC (1 << 10) /* Bit 10: Invalid Data Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_ERMISC (1 << 11) /* Bit 11: ERVER Masked Interrupt Status and Clear */ +#define FLASH_FCMISC_PROGMISC (1 << 13) /* Bit 13: PROGVER Masked Interrupt Status and Clear */ + +/* Flash Memory Control 2 */ + +#define FLASH_FMC2_WRBUF (1 << 0) /* Bit 0: Buffered Flash Memory Write */ +#define FLASH_FMC_WRKEY_SHIFT (16) /* Bits 16-31: FLASH write key */ +#define FLASH_FMC_WRKEY_MASK (0xffff << FLASH_FMC_WRKEY_SHIFT) +# define FLASH_FMC_WRKEY (0xa442 << FLASH_FMC_WRKEY_SHIFT) + +/* Flash Write Buffer Valid (32-bit value) */ + +/* Flash Program/Erase Key */ + +#define FLASH_FLPEKEY_PEKEY_SHIFT (0) /* Bits 0-16: Key Value */ +#define FLASH_FLPEKEY_PEKEY_MASK (0xffff << FLASH_FLPEKEY_PEKEY_SHIFT) + +/* Flash Write Buffer n (32-bit value) */ + +/* Flash Peripheral Properties */ + +#define FLASH_PP_SIZE_SHIFT (0) /* Bits 0-15: Flash Size */ +#define FLASH_PP_SIZE_MASK (0xffff << FLASH_PP_SIZE_SHIFT) +# define FLASH_PP_SIZE_512KB (255 << FLASH_PP_SIZE_SHIFT)/* 512 KB of Flash */ +# define FLASH_PP_SIZE_1MB (511 << FLASH_PP_SIZE_SHIFT)/* 1024 KB of Flash */ +#define FLASH_PP_MAINSS_SHIFT (16) /* Bit1 16-18: Flash Sector Size of the physical bank */ +#define FLASH_PP_MAINSS_MASK (7 << FLASH_PP_MAINSS_SHIFT) +# define FLASH_PP_MAINSS_1KB (0 << FLASH_PP_MAINSS_SHIFT) /* 1 KB */ +# define FLASH_PP_MAINSS_2KB (1 << FLASH_PP_MAINSS_SHIFT) /* 2 KB */ +# define FLASH_PP_MAINSS_4KB (2 << FLASH_PP_MAINSS_SHIFT) /* 4 KB */ +# define FLASH_PP_MAINSS_8KB (3 << FLASH_PP_MAINSS_SHIFT) /* 8 KB */ +# define FLASH_PP_MAINSS_16KB (4 << FLASH_PP_MAINSS_SHIFT) /* 16 KB */ +#define FLASH_PP_EESS_SHIFT (19) /* Bits 19-22: EEPROM Sector Size of the physical bank */ +#define FLASH_PP_EESS_MASK (15 << FLASH_PP_EESS_SHIFT) +# define FLASH_PP_EESS_1KB (0 << FLASH_PP_EESS_SHIFT) /* 1 KB */ +# define FLASH_PP_EESS_2KB (1 << FLASH_PP_EESS_SHIFT) /* 2 KB */ +# define FLASH_PP_EESS_4KB (2 << FLASH_PP_EESS_SHIFT) /* 4 KB */ +# define FLASH_PP_EESS_8KB (3 << FLASH_PP_EESS_SHIFT) /* 8 KB */ +#define FLASH_PP_DFA (1 << 28) /* Bit 28: DMA Flash Access */ +#define FLASH_PP_FMM (1 << 29) /* Bit 29: Flash Mirror Mode */ +#define FLASH_PP_PFC (1 << 30) /* Bit 30: Prefetch Buffer Mode */ + +/* Flash Size */ + +#define FLASH_FSIZE_SIZE_SHIFT (0) /* Bits 0-15: Flash Size */ +#define FLASH_FSIZE_SIZE_MASK (0xffff << FLASH_FSIZE_SIZE_SHIFT) +#define FLASH_FSIZE_SIZE_32KB (15 << FLASH_FSIZE_SIZE_SHIFT) /* 32 KB of Flash */ +#define FLASH_FSIZE_SIZE_64KB (31 << FLASH_FSIZE_SIZE_SHIFT) /* 64 KB of Flash */ +#define FLASH_FSIZE_SIZE_128KB (63 << FLASH_FSIZE_SIZE_SHIFT) /* 128 KB of Flash */ +#define FLASH_FSIZE_SIZE_256KB (127 << FLASH_FSIZE_SIZE_SHIFT) /* 256 KB of Flash */ + +/* SRAM Size */ + +#define FLASH_SSIZE_SIZE_SHIFT (0) /* Bits 0-15: SRAM Size */ +#define FLASH_SSIZE_SIZE_MASK (0xffff << FLASH_SSIZE_SIZE_SHIFT) +# define FLASH_SSIZE_SIZE_12KB (47 << FLASH_SSIZE_SIZE_SHIFT) /* 12 KB of SRAM */ +# define FLASH_SSIZE_SIZE_24KB (95 << FLASH_SSIZE_SIZE_SHIFT) /* 24 KB of SRAM */ +# define FLASH_SSIZE_SIZE_32KB (127 << FLASH_SSIZE_SIZE_SHIFT) /* 32 KB of SRAM */ +# define FLASH_SSIZE_SIZE_256KB (1023 << FLASH_SSIZE_SIZE_SHIFT) /* 256 KB of SRAM */ + +/* Flash Configuration Register */ + +#define FLASH_CONF_FPFOFF (1 << 16) /* Bit 16: Force Prefetch Off */ +#define FLASH_CONF_FPFON (1 << 17) /* Bit 17: Force Prefetch On */ +#define FLASH_CONF_CLRTV (1 << 20) /* Bit 20: Clear Valid Tags */ +#define FLASH_CONF_SPFE (1 << 29) /* Bit 29: Single Prefetch Mode Enable */ +#define FLASH_CONF_FMME (1 << 30) /* Bit 30: Flash Mirror Mode Enable */ + +/* ROM Software Map */ + +#define FLASH_ROMSWMAP_SW0EN_SHIFT (0) /* Bits 0-1: ROM SW Region 0 Availability */ +#define FLASH_ROMSWMAP_SW0EN_MASK (3 << FLASH_ROMSWMAP_SW0EN_SHIFT) +# define FLASH_ROMSWMAP_SW0EN_NOTVIS (0 << FLASH_ROMSWMAP_SW0EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SAFERTOS (1 << FLASH_ROMSWMAP_SW0EN_SHIFT) /* SafeRTOS Present */ +# define FLASH_ROMSWMAP_SW0EN_CORE (1 << FLASH_ROMSWMAP_SW0EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW1EN_SHIFT (2) /* Bits 2-3: ROM SW Region 1 Availability */ +#define FLASH_ROMSWMAP_SW1EN_MASK (3 << FLASH_ROMSWMAP_SW1EN_SHIFT) +# define FLASH_ROMSWMAP_SW1EN_NOTVIS (0 << FLASH_ROMSWMAP_SW1EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW1EN_CORE (1 << FLASH_ROMSWMAP_SW1EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW2EN_SHIFT (4) /* Bits 4-5: ROM SW Region 2 Availability */ +#define FLASH_ROMSWMAP_SW2EN_MASK (3 << FLASH_ROMSWMAP_SW2EN_SHIFT) +# define FLASH_ROMSWMAP_SW2EN_NOTVIS (0 << FLASH_ROMSWMAP_SW2EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW2EN_CORE (1 << FLASH_ROMSWMAP_SW2EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW3EN_SHIFT (6) /* Bits 6-7: ROM SW Region 3 Availability */ +#define FLASH_ROMSWMAP_SW3EN_MASK (3 << FLASH_ROMSWMAP_SW3EN_SHIFT) +# define FLASH_ROMSWMAP_SW3EN_NOTVIS (0 << FLASH_ROMSWMAP_SW3EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW3EN_CORE (1 << FLASH_ROMSWMAP_SW3EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW4EN_SHIFT (8) /* Bits 8-9: ROM SW Region 4 Availability */ +#define FLASH_ROMSWMAP_SW4EN_MASK (3 << FLASH_ROMSWMAP_SW4EN_SHIFT) +# define FLASH_ROMSWMAP_SW4EN_NOTVIS (0 << FLASH_ROMSWMAP_SW4EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW4EN_CORE (1 << FLASH_ROMSWMAP_SW4EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW5EN_SHIFT (10) /* Bits 10-11: ROM SW Region 5 Availability */ +#define FLASH_ROMSWMAP_SW5EN_MASK (3 << FLASH_ROMSWMAP_SW5EN_SHIFT) +# define FLASH_ROMSWMAP_SW5EN_NOTVIS (0 << FLASH_ROMSWMAP_SW5EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW5EN_CORE (1 << FLASH_ROMSWMAP_SW5EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW6EN_SHIFT (12) /* Bits 12-13: ROM SW Region 6 Availability */ +#define FLASH_ROMSWMAP_SW6EN_MASK (3 << FLASH_ROMSWMAP_SW6EN_SHIFT) +# define FLASH_ROMSWMAP_SW6EN_NOTVIS (0 << FLASH_ROMSWMAP_SW6EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW6EN_CORE (1 << FLASH_ROMSWMAP_SW6EN_SHIFT) /* Region available to core */ +#define FLASH_ROMSWMAP_SW7EN_SHIFT (14) /* Bits 14-15: ROM SW Region 7 Availability */ +#define FLASH_ROMSWMAP_SW7EN_MASK (3 << FLASH_ROMSWMAP_SW7EN_SHIFT) +# define FLASH_ROMSWMAP_SW7EN_NOTVIS (0 << FLASH_ROMSWMAP_SW7EN_SHIFT) /* Software region not available to the core */ +# define FLASH_ROMSWMAP_SW7EN_CORE (1 << FLASH_ROMSWMAP_SW7EN_SHIFT) /* Region available to core */ + +/* Flash DMA Address Size */ + +#define FLASH_DMASZ_SIZE_SHIFT (0) /* Bits 0-17 uDMA-accessible Memory Size */ +#define FLASH_DMASZ_SIZE_MASK (0x3ffff << FLASH_DMASZ_SIZE_SHIFT) + +/* Flash DMA Starting Address */ + +#define FLASH_DMAST_ADDR_MASK (0x1ffff800) /* Bits 11-18: Starting address of the + * flash region accessible by uDMA */ + +/* Memory Registers (System Control Offset) */ + +/* Reset Vector Pointer (32-bit value) */ + +/* ROM Control */ + +#define FLASH_RMCTL_BA (1 << 0) /* Bit 0: Boot Alias */ + +/* Boot Configuration */ + +#define FLASH_BOOTCFG_DBG0 (1 << 0) /* Bit 0: Debug Control 0 */ +#define FLASH_BOOTCFG_DBG1 (1 << 1) /* Bit 1: Debug Control 1 */ +#define FLASH_BOOTCFG_KEY (1 << 4) /* Bit 4: KEY Select */ +#define FLASH_BOOTCFG_EN (1 << 8) /* Bit 8: Boot GPIO Enable */ +#define FLASH_BOOTCFG_POL (1 << 9) /* Bit 9: Boot GPIO Polarity */ +#define FLASH_BOOTCFG_PIN_SHIFT (10) /* Bits 10-12: Boot GPIO Pin */ +#define FLASH_BOOTCFG_PIN_MASK (7 << FLASH_BOOTCFG_PIN_SHIFT) +# define FLASH_BOOTCFG_PIN_0 (0 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 0 */ +# define FLASH_BOOTCFG_PIN_1 (1 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 1 */ +# define FLASH_BOOTCFG_PIN_2 (2 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 2 */ +# define FLASH_BOOTCFG_PIN_3 (3 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 3 */ +# define FLASH_BOOTCFG_PIN_4 (4 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 4 */ +# define FLASH_BOOTCFG_PIN_5 (5 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 5 */ +# define FLASH_BOOTCFG_PIN_6 (6 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 6 */ +# define FLASH_BOOTCFG_PIN_7 (7 << FLASH_BOOTCFG_PIN_SHIFT) /* Pin 7 */ +#define FLASH_BOOTCFG_PORT_SHIFT (13) /* Bits 13-15: Boot GPIO Port */ +#define FLASH_BOOTCFG_PORT_MASK (7 << FLASH_BOOTCFG_PORT_SHIFT) +# define FLASH_BOOTCFG_PORT_A (0 << FLASH_BOOTCFG_PORT_SHIFT) /* Port A */ +# define FLASH_BOOTCFG_PORT_B (1 << FLASH_BOOTCFG_PORT_SHIFT) /* Port B */ +# define FLASH_BOOTCFG_PORT_C (2 << FLASH_BOOTCFG_PORT_SHIFT) /* Port C */ +# define FLASH_BOOTCFG_PORT_D (3 << FLASH_BOOTCFG_PORT_SHIFT) /* Port D */ +# define FLASH_BOOTCFG_PORT_E (4 << FLASH_BOOTCFG_PORT_SHIFT) /* Port E */ +# define FLASH_BOOTCFG_PORT_F (5 << FLASH_BOOTCFG_PORT_SHIFT) /* Port F */ +# define FLASH_BOOTCFG_PORT_G (6 << FLASH_BOOTCFG_PORT_SHIFT) /* Port G */ +# define FLASH_BOOTCFG_PORT_H (7 << FLASH_BOOTCFG_PORT_SHIFT) /* Port H */ +#define FLASH_BOOTCFG_NW (1 << 31) /* Bit 31: Not Written */ + +/* User Register 0-3 (32-bit value) */ +/* Flash Memory Protection Read Enable 0-15 (32-bit, bit-encoded) */ +/* Flash Memory Protection Program Enable 0-15 (32-bit, bit-encoded) */ + +#endif // __ARCH_ARM_SRC_TIVA_CHIP_TM4C_FLASH_H diff --git a/arch/arm/src/tiva/chip/tm4c_memorymap.h b/arch/arm/src/tiva/chip/tm4c_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..1a118bafdc7268dd5e30c3e7ae5d2f3b24159faf --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c_memorymap.h @@ -0,0 +1,577 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tm4c_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C_MEMORYMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory map ***********************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */ + /* -0x00ffffff: Reserved */ +# define TIVA_ROM_BASE 0x01000000 /* -0x1fffffff: Reserved for ROM */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x20007fff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x220fffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000- */ + /* -0xdfffffff: Reserved */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ +# define TIVA_ETM_BASE 0xe0041000 /* -0xe0041fff: Embedded Trace Macrocell */ + /* -0xffffffff: Reserved */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) +# define TIVA_FLASH_BASE 0x00000000 /* -0x0003ffff: On-chip FLASH */ + /* -0x00ffffff: Reserved */ +# define TIVA_ROM_BASE 0x01000000 /* -0x1fffffff: Reserved for ROM */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x20007fff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x220fffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000- */ + /* -0xdfffffff: Reserved */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ +# define TIVA_ETM_BASE 0xe0041000 /* -0xe0041fff: Embedded Trace Macrocell */ + /* -0xffffffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) || defined(CONFIG_ARCH_CHIP_TM4C1294NC) +# define TIVA_FLASH_BASE 0x00000000 /* -0x000fffff: On-chip FLASH */ + /* -0x01ffffff: Reserved */ +# define TIVA_ROM_BASE 0x02000000 /* -0x02ffffff: On-chip ROM (16 MB) */ + /* -0x1fffgfff: Reserved */ +# define TIVA_SRAM_BASE 0x20000000 /* -0x2006ffff: Bit-banded on-chip SRAM */ + /* -0x21ffffff: Reserved */ +# define TIVA_ASRAM_BASE 0x22000000 /* -0x2234ffff: Bit-band alias of 20000000- */ + /* -0x3fffffff: Reserved */ +# define TIVA_PERIPH1_BASE 0x40000000 /* -0x4001ffff: FiRM Peripherals */ + /* -0x41ffffff: Peripherals */ +# define TIVA_APERIPH_BASE 0x42000000 /* -0x43ffffff: Bit-band alias of 40000000-400fffff */ +# define TIVA_PERIPH2_BASE 0x44000000 /* -0x4001ffff: More Peripherals */ + /* -0x5fffffff: Reserved */ +# define TIVA_EPIRAM_BASE 0x60000000 /* -0xdfffffff: EPI0 mapped peripheral and RAM */ +# define TIVA_ITM_BASE 0xe0000000 /* -0xe0000fff: Instrumentation Trace Macrocell */ +# define TIVA_DWT_BASE 0xe0001000 /* -0xe0001fff: Data Watchpoint and Trace */ +# define TIVA_FPB_BASE 0xe0002000 /* -0xe0002fff: Flash Patch and Breakpoint */ + /* -0xe000dfff: Reserved */ +# define TIVA_NVIC_BASE 0xe000e000 /* -0xe000efff: Nested Vectored Interrupt Controller */ + /* -0xe003ffff: Reserved */ +# define TIVA_TPIU_BASE 0xe0040000 /* -0xe0040fff: Trace Port Interface Unit */ +# define TIVA_ETM_BASE 0xe0041000 /* -0xe0041fff: Embedded Trace Macrocell */ + /* -0xffffffff: Reserved */ +#else +# error "Memory map not specified for this TM4C chip" +#endif + +/* Peripheral base addresses ********************************************************/ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) + +/* Peripheral Base Addresses */ + +# define TIVA_WDOG0_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH_BASE + 0x26000) /* -0x26fff: GPIO Port G */ +# define TIVA_GPIOH_BASE (TIVA_PERIPH_BASE + 0x27000) /* -0x27fff: GPIO Port H */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM 0 */ +# define TIVA_PWM1_BASE (TIVA_PERIPH_BASE + 0x29000) /* -0x29fff: PWM 1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ +# define TIVA_WTIMER0_BASE (TIVA_PERIPH_BASE + 0x36000) /* -0x36fff: 32/64 Wide Timer 0 */ +# define TIVA_WTIMER1_BASE (TIVA_PERIPH_BASE + 0x37000) /* -0x37fff: 32/64 Wide Timer 1 */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ +# define TIVA_GPIOJ_BASE (TIVA_PERIPH_BASE + 0x3d000) /* -0x3dfff: GPIO Port J */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH_BASE + 0x41000) /* -0x41fff: CAN Controller 1 */ + /* -0x4bfff: Reserved */ +# define TIVA_WTIMER2_BASE (TIVA_PERIPH_BASE + 0x4c000) /* -0x4cfff: 32/64 Wide Timer 2 */ +# define TIVA_WTIMER3_BASE (TIVA_PERIPH_BASE + 0x4d000) /* -0x4dfff: 32/64 Wide Timer 3 */ +# define TIVA_WTIMER4_BASE (TIVA_PERIPH_BASE + 0x4e000) /* -0x4efff: 32/64 Wide Timer 4 */ +# define TIVA_WTIMER5_BASE (TIVA_PERIPH_BASE + 0x4f000) /* -0x4ffff: 32/64 Wide Timer 5 */ +# define TIVA_USB_BASE (TIVA_PERIPH_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ +# define TIVA_GPIOGAHB_BASE (TIVA_PERIPH_BASE + 0x5e000) /* -0x5efff: GPIO Port G (AHB aperture) */ +# define TIVA_GPIOHAHB_BASE (TIVA_PERIPH_BASE + 0x5f000) /* -0x5ffff: GPIO Port H (AHB aperture) */ +# define TIVA_GPIOJAHB_BASE (TIVA_PERIPH_BASE + 0x60000) /* -0x60fff: GPIO Port J (AHB aperture) */ +# define TIVA_GPIOKAHB_BASE (TIVA_PERIPH_BASE + 0x61000) /* -0x61fff: GPIO Port K (AHB aperture) */ +# define TIVA_GPIOLAHB_BASE (TIVA_PERIPH_BASE + 0x62000) /* -0x62fff: GPIO Port L (AHB aperture) */ +# define TIVA_GPIOMAHB_BASE (TIVA_PERIPH_BASE + 0x63000) /* -0x63fff: GPIO Port M (AHB aperture) */ +# define TIVA_GPIONAHB_BASE (TIVA_PERIPH_BASE + 0x64000) /* -0x64fff: GPIO Port N (AHB aperture) */ +# define TIVA_GPIOPAHB_BASE (TIVA_PERIPH_BASE + 0x65000) /* -0x65fff: GPIO Port P (AHB aperture) */ +# define TIVA_GPIOQAHB_BASE (TIVA_PERIPH_BASE + 0x66000) /* -0x66fff: GPIO Port Q (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xbffff: Reserved */ +# define TIVA_I2C4_BASE (TIVA_PERIPH_BASE + 0xc0000) /* -0x20fff: I2C4 */ +# define TIVA_I2C5_BASE (TIVA_PERIPH_BASE + 0xc1000) /* -0x21fff: I2C5 */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) + +/* Peripheral Base Addresses */ + +# define TIVA_WDOG0_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM 0 */ +# define TIVA_PWM1_BASE (TIVA_PERIPH_BASE + 0x29000) /* -0x29fff: PWM 1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ +# define TIVA_WTIMER0_BASE (TIVA_PERIPH_BASE + 0x36000) /* -0x36fff: 32/64 Wide Timer 0 */ +# define TIVA_WTIMER1_BASE (TIVA_PERIPH_BASE + 0x37000) /* -0x37fff: 32/64 Wide Timer 1 */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH_BASE + 0x41000) /* -0x41fff: CAN Controller 1 */ + /* -0x4bfff: Reserved */ +# define TIVA_WTIMER2_BASE (TIVA_PERIPH_BASE + 0x4c000) /* -0x4cfff: 32/64 Wide Timer 2 */ +# define TIVA_WTIMER3_BASE (TIVA_PERIPH_BASE + 0x4d000) /* -0x4dfff: 32/64 Wide Timer 3 */ +# define TIVA_WTIMER4_BASE (TIVA_PERIPH_BASE + 0x4e000) /* -0x4efff: 32/64 Wide Timer 4 */ +# define TIVA_WTIMER5_BASE (TIVA_PERIPH_BASE + 0x4f000) /* -0x4ffff: 32/64 Wide Timer 5 */ +# define TIVA_USB_BASE (TIVA_PERIPH_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PM) + +/* Peripheral Base Addresses */ + +# define TIVA_WDOG0_BASE (TIVA_PERIPH_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +# define TIVA_I2C0_BASE (TIVA_PERIPH_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_PWM0_BASE (TIVA_PERIPH_BASE + 0x28000) /* -0x28fff: PWM 0 */ +# define TIVA_PWM1_BASE (TIVA_PERIPH_BASE + 0x29000) /* -0x29fff: PWM 1 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ +# define TIVA_WTIMER0_BASE (TIVA_PERIPH_BASE + 0x36000) /* -0x36fff: 32/64 Wide Timer 0 */ +# define TIVA_WTIMER1_BASE (TIVA_PERIPH_BASE + 0x37000) /* -0x37fff: 32/64 Wide Timer 1 */ +# define TIVA_ADC0_BASE (TIVA_PERIPH_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH_BASE + 0x40000) /* -0x40fff: CAN Controller 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH_BASE + 0x41000) /* -0x41fff: CAN Controller 1 */ + /* -0x4bfff: Reserved */ +# define TIVA_WTIMER2_BASE (TIVA_PERIPH_BASE + 0x4c000) /* -0x4cfff: 32/64 Wide Timer 2 */ +# define TIVA_WTIMER3_BASE (TIVA_PERIPH_BASE + 0x4d000) /* -0x4dfff: 32/64 Wide Timer 3 */ +# define TIVA_WTIMER4_BASE (TIVA_PERIPH_BASE + 0x4e000) /* -0x4efff: 32/64 Wide Timer 4 */ +# define TIVA_WTIMER5_BASE (TIVA_PERIPH_BASE + 0x4f000) /* -0x4ffff: 32/64 Wide Timer 5 */ +# define TIVA_USB_BASE (TIVA_PERIPH_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) + +/* Peripheral region 1 */ + +# define TIVA_WDOG0_BASE (TIVA_PERIPH1_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH1_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH1_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH1_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH1_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH1_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH1_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH1_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH1_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH1_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH1_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH1_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH1_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH1_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH1_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH1_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH1_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH1_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +# define TIVA_I2C0_BASE (TIVA_PERIPH1_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH1_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH1_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH1_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH1_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH1_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH1_BASE + 0x26000) /* -0x26fff: GPIO Port G */ +# define TIVA_GPIOH_BASE (TIVA_PERIPH1_BASE + 0x27000) /* -0x27fff: GPIO Port H */ +# define TIVA_PWM0_BASE (TIVA_PERIPH1_BASE + 0x28000) /* -0x28fff: PWM 0 */ + /* -0x2bfff: Reserved */ +# define TIVA_QEI0_BASE (TIVA_PERIPH1_BASE + 0x2c000) /* -0x2cfff: QEI 0 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH1_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH1_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH1_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH1_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH1_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH1_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH1_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH1_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH1_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ +# define TIVA_GPIOJ_BASE (TIVA_PERIPH1_BASE + 0x3d000) /* -0x3dfff: GPIO Port J */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH1_BASE + 0x40000) /* -0x40fff: CAN Controller 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH1_BASE + 0x41000) /* -0x41fff: CAN Controller 1 */ + /* -0x4ffff: Reserved */ +# define TIVA_USB_BASE (TIVA_PERIPH1_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH1_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH1_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH1_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH1_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH1_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH1_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ +# define TIVA_GPIOGAHB_BASE (TIVA_PERIPH1_BASE + 0x5e000) /* -0x5efff: GPIO Port G (AHB aperture) */ +# define TIVA_GPIOHAHB_BASE (TIVA_PERIPH1_BASE + 0x5f000) /* -0x5ffff: GPIO Port H (AHB aperture) */ +# define TIVA_GPIOJAHB_BASE (TIVA_PERIPH1_BASE + 0x60000) /* -0x60fff: GPIO Port J (AHB aperture) */ +# define TIVA_GPIOKAHB_BASE (TIVA_PERIPH1_BASE + 0x61000) /* -0x61fff: GPIO Port K (AHB aperture) */ +# define TIVA_GPIOLAHB_BASE (TIVA_PERIPH1_BASE + 0x62000) /* -0x62fff: GPIO Port L (AHB aperture) */ +# define TIVA_GPIOMAHB_BASE (TIVA_PERIPH1_BASE + 0x63000) /* -0x63fff: GPIO Port M (AHB aperture) */ +# define TIVA_GPIONAHB_BASE (TIVA_PERIPH1_BASE + 0x64000) /* -0x64fff: GPIO Port N (AHB aperture) */ +# define TIVA_GPIOPAHB_BASE (TIVA_PERIPH1_BASE + 0x65000) /* -0x65fff: GPIO Port P (AHB aperture) */ +# define TIVA_GPIOQAHB_BASE (TIVA_PERIPH1_BASE + 0x66000) /* -0x66fff: GPIO Port Q (AHB aperture) */ +# define TIVA_GPIORAHB_BASE (TIVA_PERIPH1_BASE + 0x67000) /* -0x67fff: GPIO Port R (AHB aperture) */ +# define TIVA_GPIOSAHB_BASE (TIVA_PERIPH1_BASE + 0x68000) /* -0x68fff: GPIO Port S (AHB aperture) */ +# define TIVA_GPIOTAHB_BASE (TIVA_PERIPH1_BASE + 0x69000) /* -0x69fff: GPIO Port T (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH1_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xb5fff: Reserved */ +# define TIVA_1WIRE_BASE (TIVA_PERIPH1_BASE + 0xb6000) /* -0xb6fff: EEPROM and Key Locker */ + /* -0xb7fff: Reserved */ +# define TIVA_I2C8_BASE (TIVA_PERIPH1_BASE + 0xb8000) /* -0xb8fff: I2C8 */ +# define TIVA_I2C9_BASE (TIVA_PERIPH1_BASE + 0xb9000) /* -0xb9fff: I2C9 */ + /* -0xbffff: Reserved */ +# define TIVA_I2C4_BASE (TIVA_PERIPH1_BASE + 0xc0000) /* -0xc0fff: I2C4 */ +# define TIVA_I2C5_BASE (TIVA_PERIPH1_BASE + 0xc1000) /* -0xc1fff: I2C5 */ +# define TIVA_I2C6_BASE (TIVA_PERIPH1_BASE + 0xc2000) /* -0xc2fff: I2C6 */ +# define TIVA_I2C7_BASE (TIVA_PERIPH1_BASE + 0xc3000) /* -0xc3fff: I2C7 */ + /* -0xcffff: Reserved */ +# define TIVA_EPI0_BASE (TIVA_PERIPH1_BASE + 0xd0000) /* -0xd0fff: EPI0 */ + /* -0xdffff: Reserved */ +# define TIVA_TIMER6_BASE (TIVA_PERIPH1_BASE + 0xe0000) /* -0xe0fff: 16/32 Timer 6 */ +# define TIVA_TIMER7_BASE (TIVA_PERIPH1_BASE + 0xe1000) /* -0xe1fff: 16/32 Timer 7 */ + /* -0xebfff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH1_BASE + 0xec000) /* -0xecfff: Ethernet Controller */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH1_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH1_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH1_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH1_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH1_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + +/* Peripheral region 2 */ + /* -0x2ffff: Reserved */ +# define TIVA_CCM_BASE (TIVA_PERIPH2_BASE + 0x30000) /* -0x30fff: CRC/Cryptographic Control */ + /* -0x33fff: Reserved */ +# define TIVA_SHAMD5_BASE (TIVA_PERIPH2_BASE + 0x34000) /* -0x35fff: SHA/MD5 */ +# define TIVA_AES_BASE (TIVA_PERIPH2_BASE + 0x36000) /* -0x37fff: AES */ +# define TIVA_DES_BASE (TIVA_PERIPH2_BASE + 0x38000) /* -0x39fff: DES */ + /* -0x4ffff: Reserved */ +# define TIVA_LCD_BASE (TIVA_PERIPH2_BASE + 0x50000) /* -0x50fff: LCD */ + /* -0x53fff: Reserved */ +# define TIVA_EPHY_BASE (TIVA_PERIPH2_BASE + 0x54000) /* -0x54fff: EPHY */ + /* -0xfffff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_TM4C1294NC) +/* Peripheral region 1 */ +# define TIVA_WDOG0_BASE (TIVA_PERIPH1_BASE + 0x00000) /* -0x00fff: Watchdog Timer 0 */ +# define TIVA_WDOG1_BASE (TIVA_PERIPH1_BASE + 0x01000) /* -0x00fff: Watchdog Timer 1 */ + /* -0x03fff: Reserved */ +# define TIVA_GPIOA_BASE (TIVA_PERIPH1_BASE + 0x04000) /* -0x04fff: GPIO Port A */ +# define TIVA_GPIOB_BASE (TIVA_PERIPH1_BASE + 0x05000) /* -0x05fff: GPIO Port B */ +# define TIVA_GPIOC_BASE (TIVA_PERIPH1_BASE + 0x06000) /* -0x06fff: GPIO Port C */ +# define TIVA_GPIOD_BASE (TIVA_PERIPH1_BASE + 0x07000) /* -0x07fff: GPIO Port D */ +# define TIVA_SSI0_BASE (TIVA_PERIPH1_BASE + 0x08000) /* -0x08fff: SSI0 */ +# define TIVA_SSI1_BASE (TIVA_PERIPH1_BASE + 0x09000) /* -0x09fff: SSI1 */ +# define TIVA_SSI2_BASE (TIVA_PERIPH1_BASE + 0x0a000) /* -0x0afff: SSI2 */ +# define TIVA_SSI3_BASE (TIVA_PERIPH1_BASE + 0x0b000) /* -0x0bfff: SSI3 */ +# define TIVA_UART0_BASE (TIVA_PERIPH1_BASE + 0x0c000) /* -0x0cfff: UART0 */ +# define TIVA_UART1_BASE (TIVA_PERIPH1_BASE + 0x0d000) /* -0x0dfff: UART1 */ +# define TIVA_UART2_BASE (TIVA_PERIPH1_BASE + 0x0e000) /* -0x0efff: UART2 */ +# define TIVA_UART3_BASE (TIVA_PERIPH1_BASE + 0x0f000) /* -0x0ffff: UART3 */ +# define TIVA_UART4_BASE (TIVA_PERIPH1_BASE + 0x10000) /* -0x10fff: UART4 */ +# define TIVA_UART5_BASE (TIVA_PERIPH1_BASE + 0x11000) /* -0x11fff: UART5 */ +# define TIVA_UART6_BASE (TIVA_PERIPH1_BASE + 0x12000) /* -0x12fff: UART6 */ +# define TIVA_UART7_BASE (TIVA_PERIPH1_BASE + 0x13000) /* -0x13fff: UART7 */ + /* -0x1ffff: Reserved */ +# define TIVA_I2C0_BASE (TIVA_PERIPH1_BASE + 0x20000) /* -0x20fff: I2C0 */ +# define TIVA_I2C1_BASE (TIVA_PERIPH1_BASE + 0x21000) /* -0x21fff: I2C1 */ +# define TIVA_I2C2_BASE (TIVA_PERIPH1_BASE + 0x22000) /* -0x22fff: I2C2 */ +# define TIVA_I2C3_BASE (TIVA_PERIPH1_BASE + 0x23000) /* -0x23fff: I2C3 */ +# define TIVA_GPIOE_BASE (TIVA_PERIPH1_BASE + 0x24000) /* -0x24fff: GPIO Port E */ +# define TIVA_GPIOF_BASE (TIVA_PERIPH1_BASE + 0x25000) /* -0x25fff: GPIO Port F */ +# define TIVA_GPIOG_BASE (TIVA_PERIPH1_BASE + 0x26000) /* -0x26fff: GPIO Port G */ +# define TIVA_GPIOH_BASE (TIVA_PERIPH1_BASE + 0x27000) /* -0x27fff: GPIO Port H */ +# define TIVA_PWM0_BASE (TIVA_PERIPH1_BASE + 0x28000) /* -0x28fff: PWM 0 */ + /* -0x2bfff: Reserved */ +# define TIVA_QEI0_BASE (TIVA_PERIPH1_BASE + 0x2c000) /* -0x2cfff: QEI 0 */ + /* -0x2ffff: Reserved */ +# define TIVA_TIMER0_BASE (TIVA_PERIPH1_BASE + 0x30000) /* -0x30fff: 16/32 Timer 0 */ +# define TIVA_TIMER1_BASE (TIVA_PERIPH1_BASE + 0x31000) /* -0x31fff: 16/32 Timer 1 */ +# define TIVA_TIMER2_BASE (TIVA_PERIPH1_BASE + 0x32000) /* -0x32fff: 16/32 Timer 2 */ +# define TIVA_TIMER3_BASE (TIVA_PERIPH1_BASE + 0x33000) /* -0x33fff: 16/32 Timer 3 */ +# define TIVA_TIMER4_BASE (TIVA_PERIPH1_BASE + 0x34000) /* -0x34fff: 16/32 Timer 4 */ +# define TIVA_TIMER5_BASE (TIVA_PERIPH1_BASE + 0x35000) /* -0x35fff: 16/32 Timer 5 */ + /* -0x37fff: Reserved */ +# define TIVA_ADC0_BASE (TIVA_PERIPH1_BASE + 0x38000) /* -0x38fff: ADC 0 */ +# define TIVA_ADC1_BASE (TIVA_PERIPH1_BASE + 0x39000) /* -0x39fff: ADC 1 */ + /* -0x3bfff: Reserved */ +# define TIVA_CMP_BASE (TIVA_PERIPH1_BASE + 0x3c000) /* -0x3cfff: Analog Comparators */ +# define TIVA_GPIOJ_BASE (TIVA_PERIPH1_BASE + 0x3d000) /* -0x3dfff: GPIO Port J */ + /* -0x3ffff: Reserved */ +# define TIVA_CAN0_BASE (TIVA_PERIPH1_BASE + 0x40000) /* -0x40fff: CAN Controller 0 */ +# define TIVA_CAN1_BASE (TIVA_PERIPH1_BASE + 0x41000) /* -0x41fff: CAN Controller 1 */ + /* -0x4ffff: Reserved */ +# define TIVA_USB_BASE (TIVA_PERIPH1_BASE + 0x50000) /* -0x50fff: USB */ + /* -0x57fff: Reserved */ +# define TIVA_GPIOAAHB_BASE (TIVA_PERIPH1_BASE + 0x58000) /* -0x58fff: GPIO Port A (AHB aperture) */ +# define TIVA_GPIOBAHB_BASE (TIVA_PERIPH1_BASE + 0x59000) /* -0x59fff: GPIO Port B (AHB aperture) */ +# define TIVA_GPIOCAHB_BASE (TIVA_PERIPH1_BASE + 0x5a000) /* -0x5afff: GPIO Port C (AHB aperture) */ +# define TIVA_GPIODAHB_BASE (TIVA_PERIPH1_BASE + 0x5b000) /* -0x5bfff: GPIO Port D (AHB aperture) */ +# define TIVA_GPIOEAHB_BASE (TIVA_PERIPH1_BASE + 0x5c000) /* -0x5cfff: GPIO Port E (AHB aperture) */ +# define TIVA_GPIOFAHB_BASE (TIVA_PERIPH1_BASE + 0x5d000) /* -0x5dfff: GPIO Port F (AHB aperture) */ +# define TIVA_GPIOGAHB_BASE (TIVA_PERIPH1_BASE + 0x5e000) /* -0x5efff: GPIO Port G (AHB aperture) */ +# define TIVA_GPIOHAHB_BASE (TIVA_PERIPH1_BASE + 0x5f000) /* -0x5ffff: GPIO Port H (AHB aperture) */ +# define TIVA_GPIOJAHB_BASE (TIVA_PERIPH1_BASE + 0x60000) /* -0x60fff: GPIO Port J (AHB aperture) */ +# define TIVA_GPIOKAHB_BASE (TIVA_PERIPH1_BASE + 0x61000) /* -0x61fff: GPIO Port K (AHB aperture) */ +# define TIVA_GPIOLAHB_BASE (TIVA_PERIPH1_BASE + 0x62000) /* -0x62fff: GPIO Port L (AHB aperture) */ +# define TIVA_GPIOMAHB_BASE (TIVA_PERIPH1_BASE + 0x63000) /* -0x63fff: GPIO Port M (AHB aperture) */ +# define TIVA_GPIONAHB_BASE (TIVA_PERIPH1_BASE + 0x64000) /* -0x64fff: GPIO Port N (AHB aperture) */ +# define TIVA_GPIOPAHB_BASE (TIVA_PERIPH1_BASE + 0x65000) /* -0x65fff: GPIO Port P (AHB aperture) */ +# define TIVA_GPIOQAHB_BASE (TIVA_PERIPH1_BASE + 0x66000) /* -0x66fff: GPIO Port Q (AHB aperture) */ + /* -0xaefff: Reserved */ +# define TIVA_EEPROM_BASE (TIVA_PERIPH1_BASE + 0xaf000) /* -0xaffff: EEPROM and Key Locker */ + /* -0xb7fff: Reserved */ +# define TIVA_I2C8_BASE (TIVA_PERIPH1_BASE + 0xb8000) /* -0xb8fff: I2C8 */ +# define TIVA_I2C9_BASE (TIVA_PERIPH1_BASE + 0xb9000) /* -0xb9fff: I2C9 */ + /* -0xbffff: Reserved */ +# define TIVA_I2C4_BASE (TIVA_PERIPH1_BASE + 0xc0000) /* -0xc0fff: I2C4 */ +# define TIVA_I2C5_BASE (TIVA_PERIPH1_BASE + 0xc1000) /* -0xc1fff: I2C5 */ +# define TIVA_I2C6_BASE (TIVA_PERIPH1_BASE + 0xc2000) /* -0xc2fff: I2C6 */ +# define TIVA_I2C7_BASE (TIVA_PERIPH1_BASE + 0xc3000) /* -0xc3fff: I2C7 */ + /* -0xcffff: Reserved */ +# define TIVA_EPI0_BASE (TIVA_PERIPH1_BASE + 0xd0000) /* -0xd0fff: EPI0 */ + /* -0xdffff: Reserved */ +# define TIVA_TIMER6_BASE (TIVA_PERIPH1_BASE + 0xe0000) /* -0xe0fff: 16/32 Timer 6 */ +# define TIVA_TIMER7_BASE (TIVA_PERIPH1_BASE + 0xe1000) /* -0xe1fff: 16/32 Timer 7 */ + /* -0xebfff: Reserved */ +# define TIVA_ETHCON_BASE (TIVA_PERIPH1_BASE + 0xec000) /* -0xecfff: Ethernet Controller */ + /* -0xf8fff: Reserved */ +# define TIVA_SYSEXC_BASE (TIVA_PERIPH1_BASE + 0xf9000) /* -0xf9fff: System Exception Control */ + /* -0xfbfff: Reserved */ +# define TIVA_HIBERNATE_BASE (TIVA_PERIPH1_BASE + 0xfc000) /* -0xfcfff: Hibernation Controller */ +# define TIVA_FLASHCON_BASE (TIVA_PERIPH1_BASE + 0xfd000) /* -0xfdfff: FLASH Control */ +# define TIVA_SYSCON_BASE (TIVA_PERIPH1_BASE + 0xfe000) /* -0xfefff: System Control */ +# define TIVA_UDMA_BASE (TIVA_PERIPH1_BASE + 0xff000) /* -0xfffff: Micro Direct Memory Access */ + +/* Peripheral region 2 */ + /* -0x2ffff: Reserved */ +# define TIVA_CCM_BASE (TIVA_PERIPH2_BASE + 0x30000) /* -0x30fff: CRC/Cryptographic Control */ + /* -0x53fff: Reserved */ +# define TIVA_EPHY_BASE (TIVA_PERIPH2_BASE + 0x54000) /* -0x54fff: EPHY 0 */ + /* -0xfffff: Reserved */ +#else +# error "Peripheral base addresses not specified for this Tiva chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TM4C_MEMORYMAP_H */ diff --git a/arch/arm/src/tiva/chip/tm4c_pinmap.h b/arch/arm/src/tiva/chip/tm4c_pinmap.h new file mode 100644 index 0000000000000000000000000000000000000000..ec9bceca5de523dd94e37b394deabb33ad199fd9 --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c_pinmap.h @@ -0,0 +1,1429 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tm4c_pinmap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_CHIP_TM4C_PINMAP_H +#define __ARCH_ARM_SRC_TIVA_CHIP_TM4C_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alternate Pin Functions. All members of the TM4C family share the same pin + * multiplexing (although they may differ in the pins physically available). + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects via PN0 on some board, then the following definitions should + * appear in the board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configure PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as frequency, + * open-drain/push-pull, and pull-up/down! Just the basics are defined for most + * pins in this file. + */ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) + +# define GPIO_ADC_AIN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_AIN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_AIN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_AIN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_AIN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_ADC_AIN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_ADC_AIN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_ADC_AIN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_ADC_AIN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_AIN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_AIN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_AIN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_ADC_AIN12 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_AIN13 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_AIN14 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_AIN15 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_AIN16 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_ADC_AIN17 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_ADC_AIN18 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_ADC_AIN19 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_ADC_AIN20 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_7) +# define GPIO_ADC_AIN21 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_6) +# define GPIO_ADC_AIN22 (GPIO_FUNC_ANINPUT | GPIO_PORTN | GPIO_PIN_1) +# define GPIO_ADC_AIN23 (GPIO_FUNC_ANINPUT | GPIO_PORTN | GPIO_PIN_0) + +# define GPIO_CAN0_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_0) +# define GPIO_CAN0_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CAN0_RX_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_CAN0_RX_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_CAN0_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_1) +# define GPIO_CAN0_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_CAN0_TX_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_CAN0_TX_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_CAN1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_CAN1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_6) +# define GPIO_CAN1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_CAN1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_7) + +# define GPIO_CMP0_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_CMP0_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_CMP0_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CMP0_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_CMP1_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_CMP1_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_CMP1_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_CMP1_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_CMP2_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTJ | GPIO_PIN_5) +# define GPIO_CMP2_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_CMP2_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_CMP2_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTJ | GPIO_PIN_4) + +# define GPIO_HIB_RTCCLK (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTK | GPIO_PIN_4) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_I2C1_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_I2C1_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_I2C2_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_6) +# define GPIO_I2C2_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_I2C3_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_I2C3_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_I2C4_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_I2C5_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_I2C5_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTG | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) + +# define GPIO_M0_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_M0_PWM0_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_M0_PWM0_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_M0_PWM1_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_M0_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_M0_PWM1_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_M0_PWM2_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_M0_PWM2_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_M0_PWM2_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_M0_PWM3_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_M0_PWM3_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_M0_PWM3_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_M0_PWM4_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_M0_PWM4_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_M0_PWM4_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_M0_PWM4_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_M0_PWM4_5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_4) +# define GPIO_M0_PWM5_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_M0_PWM5_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_M0_PWM5_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_M0_PWM5_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_M0_PWM5_5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_M0_PWM6_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_6) +# define GPIO_M0_PWM6_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_M0_PWM6_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_M0_PWM6_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_M0_PWM6_5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_M0_PWM6_6 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_6) +# define GPIO_M0_PWM7_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_7) +# define GPIO_M0_PWM7_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_M0_PWM7_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_M0_PWM7_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_M0_PWM7_5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_M0_PWM7_6 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTH | GPIO_PIN_7) +# define GPIO_M0_PWM_FAULT0_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT0_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_M0_PWM_FAULT0_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT0_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_M0_PWM_FAULT0_5 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_M0_PWM_FAULT1_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_M0_PWM_FAULT1_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_M0_PWM_FAULT1_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT1_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_M0_PWM_FAULT1_5 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_M0_PWM_FAULT2_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_M0_PWM_FAULT2_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_M0_PWM_FAULT2_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT2_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_M0_PWM_FAULT3_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTF | GPIO_PIN_5) +# define GPIO_M0_PWM_FAULT3_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_M0_PWM_FAULT3_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_M1_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_M1_PWM0_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_M1_PWM0_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_M1_PWM1_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_M1_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_M1_PWM1_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_M1_PWM2_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_M1_PWM2_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_M1_PWM2_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_M1_PWM2_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_M1_PWM3_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_M1_PWM3_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_M1_PWM3_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_M1_PWM3_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_M1_PWM4_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_4) +# define GPIO_M1_PWM4_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_M1_PWM4_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_M1_PWM5_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_5) +# define GPIO_M1_PWM5_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_M1_PWM5_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_M1_PWM6_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_6) +# define GPIO_M1_PWM6_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_6) +# define GPIO_M1_PWM6_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M1_PWM7_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_7) +# define GPIO_M1_PWM7_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_7) +# define GPIO_M1_PWM7_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_M1_PWM_FAULT0_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_M1_PWM_FAULT0_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_M1_PWM_FAULT0_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_7) +# define GPIO_M1_PWM_FAULT1_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_M1_PWM_FAULT1_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_M1_PWM_FAULT2_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_M1_PWM_FAULT2_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_M1_PWM_FAULT3 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_3) + +# define GPIO_NMI_1 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_NMI_2 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_0) + +# define GPIO_QEI0_IDX_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_QEI0_IDX_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTJ | GPIO_PIN_2) +# define GPIO_QEI0_IDX_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_QEI0_IDX_4 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_QEI0_PHA_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTH | GPIO_PIN_4) +# define GPIO_QEI0_PHA_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_QEI0_PHA_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_QEI0_PHB_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_QEI0_PHB_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_QEI0_PHB_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_QEI1_IDX_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_QEI1_IDX_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_QEI1_IDX_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_QEI1_PHA_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_QEI1_PHA_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_QEI1_PHA_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_QEI1_PHB_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_QEI1_PHB_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_QEI1_PHB_3 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_4) + +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_SSI0_RX (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_TX (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI1_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI1_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_SSI1_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI1_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_SSI1_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI1_RX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI1_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI1_TX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI2_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_SSI2_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_4) +# define GPIO_SSI2_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_SSI2_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_SSI2_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_SSI2_RX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_6) +# define GPIO_SSI2_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_SSI2_TX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_7) +# define GPIO_SSI3_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI3_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_SSI3_CLK_3 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_SSI3_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI3_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_SSI3_FSS_3 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_SSI3_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI3_RX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_SSI3_RX_3 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_SSI3_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI3_TX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_SSI3_TX_3 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_3) + +# define GPIO_TCK_SWCLK (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_TDI (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_TDO_SWO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_TMS_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_TR_CLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TR_D0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TR_D1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TR_D2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TR_D3 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_4) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TIM0_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TIM0_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TIM1_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_0) +# define GPIO_TIM1_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TIM1_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_1) +# define GPIO_TIM1_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_TIM2_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_2) +# define GPIO_TIM2_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_TIM2_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM2_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_5) +# define GPIO_TIM2_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_3) +# define GPIO_TIM2_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_TIM3_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM3_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_6) +# define GPIO_TIM3_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_4) +# define GPIO_TIM3_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_TIM3_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_TIM3_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_7) +# define GPIO_TIM3_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTJ | GPIO_PIN_5) +# define GPIO_TIM3_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_TIM4_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_TIM4_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_TIM4_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_TIM4_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_TIM4_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_TIM4_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_TIM4_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_TIM4_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_TIM5_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_TIM5_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_TIM5_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_TIM5_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_TIM5_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_TIM5_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_TIM5_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_3) +# define GPIO_TIM5_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_3) + +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART1_DCD (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_UART1_DSR (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_UART1_DTR (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_UART1_RI (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_7) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART2_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_UART2_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_UART2_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_UART2_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_UART3_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_UART3_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_UART4_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART4_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_0) +# define GPIO_UART4_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART4_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_1) +# define GPIO_UART5_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_UART5_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_2) +# define GPIO_UART5_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_UART5_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_3) +# define GPIO_UART6_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_UART6_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_4) +# define GPIO_UART6_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_UART6_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_5) +# define GPIO_UART7_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_UART7_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_UART7_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_UART7_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_5) + +# define GPIO_USB0_DM (GPIO_FUNC_ANIO | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_USB0_DP (GPIO_FUNC_ANIO | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_USB0_EPEN_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_USB0_EPEN_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_USB0_EPEN_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_USB0_EPEN_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_USB0_ID (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_USB0_PFLT_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_USB0_PFLT_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_USB0_PFLT_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_5) +# define GPIO_USB0_PFLT_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_USB0_VBUS (GPIO_FUNC_ANIO | GPIO_PORTB | GPIO_PIN_1) + +# define GPIO_WTIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_WTIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_WTIM0_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_WTIM0_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_WTIM0_CCP0_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_WTIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_WTIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_WTIM0_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_WTIM0_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_WTIM0_CCP1_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_WTIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_WTIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_WTIM1_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_WTIM1_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_6) +# define GPIO_WTIM1_CCP0_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_WTIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_WTIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_WTIM1_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_WTIM1_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_7) +# define GPIO_WTIM1_CCP1_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_WTIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_WTIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_WTIM2_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_WTIM2_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_WTIM2_CCP0_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_WTIM2_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_WTIM2_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_WTIM2_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_WTIM2_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_WTIM2_CCP1_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_WTIM3_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_WTIM3_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_4) +# define GPIO_WTIM3_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_WTIM3_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_WTIM3_CCP0_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_WTIM3_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_WTIM3_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_WTIM3_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_WTIM3_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_WTIM3_CCP1_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_WTIM4_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_WTIM4_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_6) +# define GPIO_WTIM4_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_6) +# define GPIO_WTIM4_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_4) +# define GPIO_WTIM4_CCP0_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_WTIM4_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_WTIM4_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_7) +# define GPIO_WTIM4_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTN | GPIO_PIN_7) +# define GPIO_WTIM4_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_5) +# define GPIO_WTIM4_CCP1_5 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_WTIM5_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_WTIM5_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_WTIM5_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_6) +# define GPIO_WTIM5_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_WTIM5_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_WTIM5_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_WTIM5_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_7) +# define GPIO_WTIM5_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTM | GPIO_PIN_3) + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) + +# define GPIO_ADC_AIN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_AIN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_AIN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_AIN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_AIN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_AIN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_AIN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_AIN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_AIN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_AIN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_AIN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_AIN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) + +# define GPIO_CAN0_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CAN0_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_CAN0_RX_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_CAN0_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_CAN0_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_CAN0_TX_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_CAN1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_CAN1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTA | GPIO_PIN_1) + +# define GPIO_CMP0_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_CMP0_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_CMP0_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_CMP1_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_CMP1_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_9 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_CMP1_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_5) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_I2C2_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTE | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_I2C3_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) + +# define GPIO_M0_PWM0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_M0_PWM1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_M0_PWM2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_M0_PWM3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_M0_PWM4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_M0_PWM5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_M0_PWM6 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_M0_PWM7 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_4 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_M0_PWM_FAULT0_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT0_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_M0_PWM_FAULT0_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_4 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M1_PWM0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_M1_PWM1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_M1_PWM2_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_M1_PWM2_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_M1_PWM3_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_M1_PWM3_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_M1_PWM4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_M1_PWM5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_M1_PWM6 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M1_PWM7 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_M1_PWM_FAULT0_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_4) + +# define GPIO_NMI_1 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_NMI_2 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_0) + +# define GPIO_QEI0_IDX_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_QEI0_IDX_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_QEI0_PHA_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_QEI0_PHA_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_QEI0_PHB_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_QEI0_PHB_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_QEI1_IDX (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_QEI1_PHA (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_QEI1_PHB (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTC | GPIO_PIN_6) + +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_SSI0_RX (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_TX (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI1_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI1_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_SSI1_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI1_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_SSI1_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI1_RX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI1_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI1_TX_2 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI2_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_SSI2_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_SSI2_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_SSI2_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_SSI3_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI3_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI3_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI3_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_3) + +# define GPIO_TCK_SWCLK (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_TDI (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_TDO_SWO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_TMS_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_TR_CLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TR_D0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TR_D1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_TIM2_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM3_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM3_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_TIM4_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_TIM4_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_TIM5_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_TIM5_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_3) + +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART2_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_UART2_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_UART3_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_UART3_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_UART4_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART4_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART5_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_UART5_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_UART6_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_UART6_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_UART7_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_UART7_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_1) + +# define GPIO_USB0_EPEN_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_USB0_EPEN_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_USB0_EPEN_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_8 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_USB0_ID (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_USB0_PFLT_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_USB0_PFLT_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_USB0_VBUS (GPIO_FUNC_ANIO | GPIO_PORTB | GPIO_PIN_1) + +# define GPIO_WTIM0_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_WTIM0_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_WTIM1_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_WTIM1_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_WTIM2_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_WTIM2_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_WTIM3_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_WTIM3_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_WTIM4_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_WTIM4_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_WTIM5_CCP0 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_WTIM5_CCP1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTD | GPIO_PIN_7) + +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) + +# define GPIO_ADC_AIN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_AIN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_AIN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_AIN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_AIN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_ADC_AIN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_ADC_AIN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_ADC_AIN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_ADC_AIN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_AIN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_AIN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_AIN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_ADC_AIN12 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_AIN13 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_AIN14 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_AIN15 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_AIN16 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_ADC_AIN17 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_ADC_AIN18 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_ADC_AIN19 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_ADC_AIN20 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_6) +# define GPIO_ADC_AIN21 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_7) +# define GPIO_ADC_AIN22 (GPIO_FUNC_ANINPUT | GPIO_PORTP | GPIO_PIN_7) +# define GPIO_ADC_AIN23 (GPIO_FUNC_ANINPUT | GPIO_PORTP | GPIO_PIN_6) + +# define GPIO_CAN0_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_CAN0_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTT | GPIO_PIN_0) +# define GPIO_CAN0_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_CAN0_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTT | GPIO_PIN_1) +# define GPIO_CAN1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_CAN1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTT | GPIO_PIN_2) +# define GPIO_CAN1_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_CAN1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTT | GPIO_PIN_3) + +# define GPIO_CMP0_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_CMP0_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_CMP1_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_CMP1_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_CMP2_OUT (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_2) + +# define GPIO_EN0_COL (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_EN0_CRS (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_EN0_INTRN_1 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EN0_INTRN_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_EN0_LED0_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_EN0_LED0_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EN0_LED1_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_EN0_LED1_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_EN0_LED2_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_EN0_LED2_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_EN0_MDC_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_EN0_MDC_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_EN0_MDIO_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_EN0_MDIO_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_EN0_PPS_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_EN0_PPS_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_EN0_PPS_3 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTJ | GPIO_PIN_0) +# define GPIO_EN0_RREF_CLK (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTM | GPIO_PIN_4) +# define GPIO_EN0_RXCK (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_EN0_RXD0_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_5) +# define GPIO_EN0_RXD0_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTT | GPIO_PIN_0) +# define GPIO_EN0_RXD1_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_6) +# define GPIO_EN0_RXD1_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTT | GPIO_PIN_1) +# define GPIO_EN0_RXD2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_EN0_RXD3 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EN0_RXDV_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_EN0_RXDV_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTS | GPIO_PIN_7) +# define GPIO_EN0_RXER_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_EN0_RXER_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTS | GPIO_PIN_6) +# define GPIO_EN0_TXCK (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_EN0_TXD0_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_EN0_TXD0_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTS | GPIO_PIN_4) +# define GPIO_EN0_TXD1_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_EN0_TXD1_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTS | GPIO_PIN_5) +# define GPIO_EN0_TXD2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_EN0_TXD3 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_EN0_TXEN_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_EN0_TXEN_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTR | GPIO_PIN_7) +# define GPIO_EN0_TXER (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTN | GPIO_PIN_6) + +# define GPIO_EPI0_S0_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_EPI0_S0_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_EPI0_S1_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_EPI0_S1_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_EPI0_S2_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_EPI0_S2_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_EPI0_S3_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_EPI0_S3_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_EPI0_S4 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_EPI0_S5 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_EPI0_S6 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_EPI0_S7 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_EPI0_S8 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_EPI0_S9 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_EPI0_S10 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_EPI0_S11 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_EPI0_S12 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTM | GPIO_PIN_3) +# define GPIO_EPI0_S13 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_EPI0_S14 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_EPI0_S15 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_EPI0_S16 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_EPI0_S17 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_EPI0_S18 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_EPI0_S19 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_EPI0_S20 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_EPI0_S21 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_EPI0_S22 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_EPI0_S23 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_EPI0_S24 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_EPI0_S25 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_EPI0_S26 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_EPI0_S27 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_EPI0_S28 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_EPI0_S29_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_EPI0_S29_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_EPI0_S30_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_EPI0_S30_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_EPI0_S31 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_EPI0_S32 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EPI0_S33 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_EPI0_S34 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_EPI0_S35 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_5) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_I2C1_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_0) +# define GPIO_I2C1_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_I2C2_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_I2C2_SCL_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_I2C2_SCL_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_2) +# define GPIO_I2C2_SCL_5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_3 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_I2C2_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTL | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_3 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_6 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_4 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_5 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTN | GPIO_PIN_4 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_I2C3_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_I2C3_SCL_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_4) +# define GPIO_I2C3_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SDA_3 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_I2C4_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_I2C4_SCL_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_6) +# define GPIO_I2C4_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SDA_3 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTR | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_I2C5_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_I2C5_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C6_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_I2C6_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_I2C6_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C6_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_I2C7_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_I2C7_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_I2C8_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_I2C8_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C9_SCL_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_I2C9_SCL_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTE | GPIO_PIN_6) +# define GPIO_I2C9_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C9_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTE | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) + +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_JTAG_SWO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TCK (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_TDI (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_JTAG_TDO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TMS (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_LCD_AC (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTJ | GPIO_PIN_6) +# define GPIO_LCD_CP (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_0) +# define GPIO_LCD_DATA00 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_4) +# define GPIO_LCD_DATA01 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_5) +# define GPIO_LCD_DATA02 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_7) +# define GPIO_LCD_DATA03 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_3) +# define GPIO_LCD_DATA04 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_6) +# define GPIO_LCD_DATA05 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_7) +# define GPIO_LCD_DATA06 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_4) +# define GPIO_LCD_DATA07 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_5) +# define GPIO_LCD_DATA08 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_6) +# define GPIO_LCD_DATA09 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_7) +# define GPIO_LCD_DATA10 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTT | GPIO_PIN_0) +# define GPIO_LCD_DATA11 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTT | GPIO_PIN_1) +# define GPIO_LCD_DATA12 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_7) +# define GPIO_LCD_DATA13 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTN | GPIO_PIN_6) +# define GPIO_LCD_DATA14 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTJ | GPIO_PIN_2) +# define GPIO_LCD_DATA15 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTJ | GPIO_PIN_3) +# define GPIO_LCD_DATA16 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTJ | GPIO_PIN_4) +# define GPIO_LCD_DATA17 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTJ | GPIO_PIN_5) +# define GPIO_LCD_DATA18 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTT | GPIO_PIN_2) +# define GPIO_LCD_DATA19 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTT | GPIO_PIN_3) +# define GPIO_LCD_DATA20 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_0) +# define GPIO_LCD_DATA21 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_1) +# define GPIO_LCD_DATA22 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_2) +# define GPIO_LCD_DATA23 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTS | GPIO_PIN_3) +# define GPIO_LCD_FP (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_1) +# define GPIO_LCD_LP (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTR | GPIO_PIN_2) +# define GPIO_LCD_MCLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_6) + +# define GPIO_M0_PWM_FAULT0_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_M0_PWM_FAULT0_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_0) +# define GPIO_M0_PWM_FAULT1_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_M0_PWM_FAULT1_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_1) +# define GPIO_M0_PWM_FAULT2_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_M0_PWM_FAULT2_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_2) +# define GPIO_M0_PWM_FAULT3_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_M0_PWM_FAULT3_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_3) +# define GPIO_M0_PWM0_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_M0_PWM0_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_0) +# define GPIO_M0_PWM1_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_M0_PWM1_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_1) +# define GPIO_M0_PWM2_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M0_PWM2_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_2) +# define GPIO_M0_PWM3_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_M0_PWM3_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_3) +# define GPIO_M0_PWM4_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_M0_PWM4_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_4) +# define GPIO_M0_PWM5_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_M0_PWM5_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_5) +# define GPIO_M0_PWM6_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_M0_PWM6_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_6) +# define GPIO_M0_PWM7_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_M0_PWM7_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTR | GPIO_PIN_7) + +# define GPIO_NMI_1 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_NMI_2 (GPIO_FUNC_PFIO | GPIO_ALT_8 | GPIO_PORTE | GPIO_PIN_7) + +# define GPIO_OWALT_1 (GPIO_FUNC_PFIO | GPIO_ALT_4 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_OWALT_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_OWIRE_1 (GPIO_FUNC_PFIO | GPIO_ALT_4 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_OWIRE_2 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_OWIRE_3 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_OWIRE_4 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_OWIRE_5 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_OWIRE_6 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTP | GPIO_PIN_7) + +# define GPIO_QEI0_IDX_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_QEI0_IDX_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_6) +# define GPIO_QEI0_PHA_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_QEI0_PHA_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_4) +# define GPIO_QEI0_PHB_1 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_QEI0_PHB_2 (GPIO_FUNC_PFIO | GPIO_ALT_6 | GPIO_PORTS | GPIO_PIN_5) + +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_SSI0_XDAT0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_XDAT1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI0_XDAT2 (GPIO_FUNC_PFIO | GPIO_ALT_12 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_SSI0_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_12 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_SSI1_CLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_SSI1_FSS (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_SSI1_XDAT0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_SSI1_XDAT1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_SSI1_XDAT2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_SSI1_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_SSI2_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI2_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_7) +# define GPIO_SSI2_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI2_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_6) +# define GPIO_SSI2_XDAT0_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI2_XDAT0_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_SSI2_XDAT1_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI2_XDAT1_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_SSI2_XDAT2_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_SSI2_XDAT2_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_3) +# define GPIO_SSI2_XDAT3_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_SSI2_XDAT3_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTG | GPIO_PIN_2) +# define GPIO_SSI3_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_SSI3_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_SSI3_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_SSI3_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_SSI3_XDAT0_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI3_XDAT0_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_SSI3_XDAT1_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI3_XDAT1_2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_SSI3_XDAT2_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_SSI3_XDAT2_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_SSI3_XDAT3_1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTF | GPIO_PIN_5) +# define GPIO_SSI3_XDAT3_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_1) + +# define GPIO_SYSCON_DIVSCLK (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_4) + +# define GPIO_TR_CLK (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TR_D0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TR_D1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TR_D2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TR_D3 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_4) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_TIM0_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_TIM0_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTR | GPIO_PIN_4) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_TIM0_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_TIM0_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTR | GPIO_PIN_5) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_TIM1_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_TIM1_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTR | GPIO_PIN_6) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_TIM1_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_TIM1_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTR | GPIO_PIN_7) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_TIM2_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_0) +# define GPIO_TIM2_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_TIM2_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_TIM2_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_1) +# define GPIO_TIM3_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_TIM3_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_TIM3_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_TIM3_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_2) +# define GPIO_TIM3_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_TIM3_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_TIM3_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_3) +# define GPIO_TIM3_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_3) +# define GPIO_TIM4_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM4_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_TIM4_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_4) +# define GPIO_TIM4_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_4) +# define GPIO_TIM4_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM4_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_TIM4_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_5) +# define GPIO_TIM4_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_5) +# define GPIO_TIM5_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM5_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_TIM5_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_6) +# define GPIO_TIM5_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_TIM5_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_TIM5_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTS | GPIO_PIN_7) +# define GPIO_TIM6_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_6) +# define GPIO_TIM6_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_TIM6_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTT | GPIO_PIN_0) +# define GPIO_TIM6_CCP0_4 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_TIM6_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_7) +# define GPIO_TIM6_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_TIM6_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTT | GPIO_PIN_1) +# define GPIO_TIM6_CCP1_4 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_TIM7_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_TIM7_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_TIM7_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTT | GPIO_PIN_2) +# define GPIO_TIM7_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_TIM7_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_TIM7_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTT | GPIO_PIN_3) + +# define GPIO_UART0_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_UART0_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_6) +# define GPIO_UART0_CTS_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTG | GPIO_PIN_4) +# define GPIO_UART0_CTS_4 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_UART0_CTS_5 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_4) +# define GPIO_UART0_DCD_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_UART0_DCD_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_5) +# define GPIO_UART0_DCD_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_UART0_DSR_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_UART0_DSR_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_UART0_DSR_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_UART0_DTR_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_4) +# define GPIO_UART0_DTR_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_UART0_RI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_5) +# define GPIO_UART0_RI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_UART0_RI_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_UART0_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_UART0_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_7) +# define GPIO_UART0_RTS_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTG | GPIO_PIN_5) +# define GPIO_UART0_RTS_4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_UART1_DCD_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_UART1_DCD_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_UART1_DCD_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_6) +# define GPIO_UART1_DSR_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_UART1_DSR_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_UART1_DSR_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTS | GPIO_PIN_2) +# define GPIO_UART1_DTR_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_UART1_DTR_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_UART1_DTR_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_6) +# define GPIO_UART1_RI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_UART1_RI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_UART1_RI_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_7) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_0) +# define GPIO_UART1_RTS_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_7) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_4) +# define GPIO_UART1_RX_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTR | GPIO_PIN_5) +# define GPIO_UART1_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART1_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_5) +# define GPIO_UART1_TX_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTR | GPIO_PIN_6) +# define GPIO_UART2_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_UART2_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_3) +# define GPIO_UART2_CTS_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_UART2_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_UART2_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_2) +# define GPIO_UART2_RTS_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_UART2_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_UART2_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_UART2_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_UART2_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_UART3_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_5) +# define GPIO_UART3_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_UART3_CTS_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_UART3_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_4) +# define GPIO_UART3_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_UART3_RTS_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_UART3_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_UART3_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_0) +# define GPIO_UART3_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_UART3_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_1) +# define GPIO_UART4_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_UART4_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_7) +# define GPIO_UART4_CTS_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_7) +# define GPIO_UART4_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_6) +# define GPIO_UART4_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_UART4_RTS_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_6) +# define GPIO_UART4_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_UART4_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_UART4_RX_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTR | GPIO_PIN_1) +# define GPIO_UART4_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_UART4_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_UART4_TX_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTR | GPIO_PIN_0) +# define GPIO_UART5_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_UART5_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_6) +# define GPIO_UART5_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_UART5_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_7) +# define GPIO_UART6_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_UART6_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_UART7_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART7_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_6) +# define GPIO_UART7_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_UART7_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTH | GPIO_PIN_7) + +# define GPIO_USB0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_USB0_D0 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_USB0_D1 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_USB0_D2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_USB0_D3 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_USB0_D4 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_USB0_D5 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_USB0_D6 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_USB0_D7 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_USB0_DIR (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_USB0_EPEN_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_11 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_USB0_EPEN_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_USB0_EPEN_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_USB0_ID (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_USB0_NXT (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_USB0_PFLT_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_USB0_PFLT_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_USB0_STP (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_USB0_VBUS (GPIO_FUNC_ANIO | GPIO_PORTB | GPIO_PIN_1) + +# define GPIO_RTC_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_RTC_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_RTC_CLK_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_3) + +#elif defined(CONFIG_ARCH_CHIP_TM4C1294NC) +# define GPIO_ADC_AIN0 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_ADC_AIN1 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_ADC_AIN2 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_ADC_AIN3 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_ADC_AIN4 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_ADC_AIN5 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_ADC_AIN6 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_ADC_AIN7 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_ADC_AIN8 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_ADC_AIN9 (GPIO_FUNC_ANINPUT | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_ADC_AIN10 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_ADC_AIN11 (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_ADC_AIN12 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_ADC_AIN13 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_ADC_AIN14 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_ADC_AIN15 (GPIO_FUNC_ANINPUT | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_ADC_AIN16 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_ADC_AIN17 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_ADC_AIN18 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_ADC_AIN19 (GPIO_FUNC_ANINPUT | GPIO_PORTK | GPIO_PIN_3) + +# define GPIO_CAN0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_CAN0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_CAN1_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_CAN1_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTB | GPIO_PIN_1) + +# define GPIO_CMP0_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_CMP0_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_CMP0_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_CMP0_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_CMP1_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_CMP1_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_CMP1_OUT_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_CMP1_OUT_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_CMP2_PIN (GPIO_FUNC_ANINPUT | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_CMP2_NIN (GPIO_FUNC_ANINPUT | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_CMP2_OUT (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_2) + +# define GPIO_EN0_LED0_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_EN0_LED0_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EN0_LED1_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_EN0_LED1_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_EN0_LED2_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_EN0_LED2_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_EN0_PPS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_EN0_PPS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTJ | GPIO_PIN_0) + +# define GPIO_EPI0_S0_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_EPI0_S0_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_EPI0_S1_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_EPI0_S1_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_EPI0_S2_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_EPI0_S2_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_EPI0_S3_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_EPI0_S3_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_EPI0_S4 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_EPI0_S5 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_EPI0_S6 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_EPI0_S7 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_EPI0_S8 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_EPI0_S9 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_EPI0_S10 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_EPI0_S11 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_EPI0_S12 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTM | GPIO_PIN_3) +# define GPIO_EPI0_S13 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_EPI0_S14 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_EPI0_S15 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_EPI0_S16 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_EPI0_S17 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_EPI0_S18 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_EPI0_S19 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_EPI0_S20 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_EPI0_S21 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_EPI0_S22 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_EPI0_S23 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_EPI0_S24 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_EPI0_S25 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_EPI0_S26 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_EPI0_S27 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_EPI0_S28 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_EPI0_S29_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_EPI0_S29_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_EPI0_S30_1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_EPI0_S30_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_EPI0_S31 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_5) +# define GPIO_EPI0_S32 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_EPI0_S33 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_EPI0_S34 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_EPI0_S35 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTN | GPIO_PIN_5) + +# define GPIO_HIB_RTCCLK_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_HIB_RTCCLK_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_HIB_RTCCLK_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_3) + +# define GPIO_I2C0_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_2 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C0_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C1_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTG | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTL | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTN | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SCL_3 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTL | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C2_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_3 | GPIO_PORTN | GPIO_PIN_4 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_4 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C3_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_6 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C4_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTK | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SCL_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SCL_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_4 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C5_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTB | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C6_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_6 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C6_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_7 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SCL_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_4 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SCL_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_5 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C7_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SCL_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_2 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SCL_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_2 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SDA_1 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C8_SDA_2 (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTD | GPIO_PIN_3 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C9_SCL (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_0 | GPIO_PADTYPE_ODWPU) +# define GPIO_I2C9_SDA (GPIO_FUNC_PFODIO | GPIO_ALT_2 | GPIO_PORTA | GPIO_PIN_1 | GPIO_PADTYPE_ODWPU) + +# define GPIO_JTAG_SWCLK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_SWDIO (GPIO_FUNC_PFIO | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) +# define GPIO_JTAG_SWO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TCK (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_0) +# define GPIO_JTAG_TDI (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_2) +# define GPIO_JTAG_TDO (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_3) +# define GPIO_JTAG_TMS (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_1) + +# define GPIO_M0_PWM_FAULT0 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_M0_PWM_FAULT1 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_6) +# define GPIO_M0_PWM_FAULT2 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_M0_PWM_FAULT3 (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_M0_PWM0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_M0_PWM1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_M0_PWM2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_M0_PWM3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_M0_PWM4 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_0) +# define GPIO_M0_PWM5 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTG | GPIO_PIN_1) +# define GPIO_M0_PWM6 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_4) +# define GPIO_M0_PWM7 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_6 | GPIO_PORTK | GPIO_PIN_5) + +# define GPIO_NMI (GPIO_FUNC_PFINPUT | GPIO_ALT_8 | GPIO_PORTD | GPIO_PIN_7) + +# define GPIO_QEI0_IDX (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_QEI0_PHA (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_QEI0_PHB (GPIO_FUNC_PFINPUT | GPIO_ALT_6 | GPIO_PORTL | GPIO_PIN_2) + +# define GPIO_RTC_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_5 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_RTC_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTC | GPIO_PIN_5) +# define GPIO_RTC_CLK_3 (GPIO_FUNC_PFIO | GPIO_ALT_7 | GPIO_PORTP | GPIO_PIN_3) + +# define GPIO_SSI0_CLK (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_SSI0_FSS (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_SSI0_TX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_XDAT0 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_SSI0_RX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI0_XDAT1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_SSI0_XDAT2 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_SSI0_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_13 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_SSI1_CLK (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_SSI1_FSS (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_SSI1_TX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_SSI1_XDAT0 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_SSI1_RX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_SSI1_XDAT1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTE | GPIO_PIN_5) +# define GPIO_SSI1_XDAT2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_SSI1_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_SSI2_CLK (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_SSI2_FSS (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_SSI2_TX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI2_XDAT0 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_SSI2_RX (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI2_XDAT1 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_SSI2_XDAT2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_SSI2_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_SSI3_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_SSI3_CLK_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_0) +# define GPIO_SSI3_FSS_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_SSI3_FSS_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_1) +# define GPIO_SSI3_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI3_TX_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_SSI3_XDAT0_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_SSI3_XDAT0_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_2) +# define GPIO_SSI3_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI3_RX_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_SSI3_XDAT1_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_SSI3_XDAT1_2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTQ | GPIO_PIN_3) +# define GPIO_SSI3_XDAT2_1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTF | GPIO_PIN_4) +# define GPIO_SSI3_XDAT2_2 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_SSI3_XDAT3 (GPIO_FUNC_PFIO | GPIO_ALT_15 | GPIO_PORTP | GPIO_PIN_1) + +# define GPIO_SYSCON_DIVSCLK (GPIO_FUNC_PFOUTPUT | GPIO_ALT_7 | GPIO_PORTQ | GPIO_PIN_4) + +# define GPIO_TR_CLK (GPIO_FUNC_PFOUTPUT | GPIO_ALT_15 | GPIO_PORTF | GPIO_PIN_3) +# define GPIO_TR_D0 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_15 | GPIO_PORTF | GPIO_PIN_2) +# define GPIO_TR_D1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_15 | GPIO_PORTF | GPIO_PIN_1) +# define GPIO_TR_D2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_15 | GPIO_PORTF | GPIO_PIN_0) +# define GPIO_TR_D3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_15 | GPIO_PORTF | GPIO_PIN_4) + +# define GPIO_TIM0_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_TIM0_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_0) +# define GPIO_TIM0_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_TIM0_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_TIM0_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_1) +# define GPIO_TIM0_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_TIM1_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_TIM1_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_2) +# define GPIO_TIM1_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_TIM1_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_TIM1_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_3) +# define GPIO_TIM1_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_TIM2_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_TIM2_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_0) +# define GPIO_TIM2_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_TIM2_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_1) +# define GPIO_TIM3_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_TIM3_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_TIM3_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_2) +# define GPIO_TIM3_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_TIM3_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_TIM3_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_3) +# define GPIO_TIM4_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_TIM4_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_TIM4_CCP0_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_4) +# define GPIO_TIM4_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_TIM4_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_TIM4_CCP1_3 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_5) +# define GPIO_TIM5_CCP0_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_TIM5_CCP0_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_TIM5_CCP1_1 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_TIM5_CCP1_2 (GPIO_FUNC_PFIO | GPIO_ALT_3 | GPIO_PORTM | GPIO_PIN_7) + +# define GPIO_UART0_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_4) +# define GPIO_UART0_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_1) +# define GPIO_UART0_CTS_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_4) +# define GPIO_UART0_DCD_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_2) +# define GPIO_UART0_DCD_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_5) +# define GPIO_UART0_DCD_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_UART0_DSR_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_3) +# define GPIO_UART0_DSR_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_6) +# define GPIO_UART0_DSR_3 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_UART0_DTR (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_UART0_RI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_7) +# define GPIO_UART0_RI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTM | GPIO_PIN_7) +# define GPIO_UART0_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_5) +# define GPIO_UART0_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTH | GPIO_PIN_0) +# define GPIO_UART0_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_0) +# define GPIO_UART0_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_1) +# define GPIO_UART1_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_1) +# define GPIO_UART1_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_UART1_DCD_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_2) +# define GPIO_UART1_DCD_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_UART1_DSR_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_1) +# define GPIO_UART1_DSR_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_UART1_DTR_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_3) +# define GPIO_UART1_DTR_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_UART1_RI_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_4) +# define GPIO_UART1_RI_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_UART1_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTE | GPIO_PIN_0) +# define GPIO_UART1_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTN | GPIO_PIN_0) +# define GPIO_UART1_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_UART1_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTQ | GPIO_PIN_4) +# define GPIO_UART1_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTB | GPIO_PIN_1) +# define GPIO_UART2_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_UART2_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_3) +# define GPIO_UART2_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_UART2_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_2) +# define GPIO_UART2_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_UART2_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_4) +# define GPIO_UART2_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_UART2_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTD | GPIO_PIN_5) +# define GPIO_UART3_CTS_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_UART3_CTS_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_5) +# define GPIO_UART3_RTS_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_UART3_RTS_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_2 | GPIO_PORTN | GPIO_PIN_4) +# define GPIO_UART3_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_4) +# define GPIO_UART3_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_0) +# define GPIO_UART3_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_5) +# define GPIO_UART3_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTJ | GPIO_PIN_1) +# define GPIO_UART4_CTS (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_3) +# define GPIO_UART4_RTS (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_2) +# define GPIO_UART4_RX_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_2) +# define GPIO_UART4_RX_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_0) +# define GPIO_UART4_TX_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTA | GPIO_PIN_3) +# define GPIO_UART4_TX_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTK | GPIO_PIN_1) +# define GPIO_UART5_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_6) +# define GPIO_UART5_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_7) +# define GPIO_UART6_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_0) +# define GPIO_UART6_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTP | GPIO_PIN_1) +# define GPIO_UART7_RX (GPIO_FUNC_PFINPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_4) +# define GPIO_UART7_TX (GPIO_FUNC_PFOUTPUT | GPIO_ALT_1 | GPIO_PORTC | GPIO_PIN_5) + +# define GPIO_USB0_CLK (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_3) +# define GPIO_USB0_D0 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_0) +# define GPIO_USB0_D1 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_1) +# define GPIO_USB0_D2 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_2) +# define GPIO_USB0_D3 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_3) +# define GPIO_USB0_D4 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_4) +# define GPIO_USB0_D5 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTL | GPIO_PIN_5) +# define GPIO_USB0_D6 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_5) +# define GPIO_USB0_D7 (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_4) +# define GPIO_USB0_DIR (GPIO_FUNC_PFOUTPUT | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_3) +# define GPIO_USB0_DM (GPIO_FUNC_ANIO | GPIO_PORTL | GPIO_PIN_7) +# define GPIO_USB0_DP (GPIO_FUNC_ANIO | GPIO_PORTL | GPIO_PIN_6) +# define GPIO_USB0_EPEN_1 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_6) +# define GPIO_USB0_EPEN_2 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_11 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_USB0_EPEN_3 (GPIO_FUNC_PFOUTPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_6) +# define GPIO_USB0_ID (GPIO_FUNC_ANINPUT | GPIO_PORTB | GPIO_PIN_0) +# define GPIO_USB0_NXT (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTP | GPIO_PIN_2) +# define GPIO_USB0_PFLT_1 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTA | GPIO_PIN_7) +# define GPIO_USB0_PFLT_2 (GPIO_FUNC_PFINPUT | GPIO_ALT_5 | GPIO_PORTD | GPIO_PIN_7) +# define GPIO_USB0_STP (GPIO_FUNC_PFIO | GPIO_ALT_14 | GPIO_PORTB | GPIO_PIN_2) +# define GPIO_USB0_VBUS (GPIO_FUNC_ANIO | GPIO_PORTB | GPIO_PIN_1) + +#else +# error "Unknown TIVA chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_TIVA_CHIP_TM4C_PINMAP_H */ diff --git a/arch/arm/src/tiva/chip/tm4c_vectors.h b/arch/arm/src/tiva/chip/tm4c_vectors.h new file mode 100644 index 0000000000000000000000000000000000000000..1eccdd2e3feb27ebfe59b29ccdfcb794a3a04731 --- /dev/null +++ b/arch/arm/src/tiva/chip/tm4c_vectors.h @@ -0,0 +1,676 @@ +/************************************************************************************ + * arch/arm/src/tiva/chip/tm4c_vectors.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Vectors + ************************************************************************************/ + +/* This file is included by tiva_vectors.S. It provides the macro VECTOR that + * supplies each Tiva vector in terms of a (lower-case) ISR label and an + * (upper-case) IRQ number as defined in arch/arm/include/tiva/tm4c_irq.h. + * tiva_vectors.S will define the VECTOR in different ways in order to generate + * the interrupt vectors and handlers in their final form. + */ + +#if defined(CONFIG_ARCH_CHIP_TM4C123GH6ZRB) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 155 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 155 + +# else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwm0_fault, TIVA_IRQ_PWM0_FAULT) /* Vector 25: PWM0 Fault */ +VECTOR(tiva_pwm0_gen0, TIVA_IRQ_PWM0_GEN0) /* Vector 26: PWM0 Generator 0 */ +VECTOR(tiva_pwm0_gen1, TIVA_IRQ_PWM0_GEN1) /* Vector 27: PWM0 Generator 1 */ +VECTOR(tiva_pwm0_gen2, TIVA_IRQ_PWM0_GEN2) /* Vector 28: PWM0 Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +VECTOR(tiva_compare0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_compare1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +VECTOR(tiva_compare2, TIVA_IRQ_COMPARE2) /* Vector 43: Analog Comparator 2 */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +VECTOR(tiva_gpioh, TIVA_IRQ_GPIOH) /* Vector 48: GPIO Port H */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 49: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_qei1, TIVA_IRQ_QEI1) /* Vector 54: QEI1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 55: CAN 0 */ +VECTOR(tiva_can1, TIVA_IRQ_CAN1) /* Vector 56: CAN 1 */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +UNUSED(TIVA_RESERVED_58) /* Vector 58: Reserved */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 60: USB */ +VECTOR(tiva_pwm0_gen3, TIVA_IRQ_PWM0_GEN3) /* Vector 61: PWM0 Generator 3 */ +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 62: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR) /* Vector 63: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 64: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 65: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 66: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 67: ADC1 Sequence 3 */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +VECTOR(tiva_gpioj, TIVA_IRQ_GPIOJ) /* Vector 70: GPIO Port J */ +VECTOR(tiva_gpiok, TIVA_IRQ_GPIOK) /* Vector 71: GPIO Port K */ +VECTOR(tiva_gpiol, TIVA_IRQ_GPIOL) /* Vector 72: GPIO Port L */ +VECTOR(tiva_ssi2, TIVA_IRQ_SSI2) /* Vector 73: SSI 2 */ +VECTOR(tiva_ssi3, TIVA_IRQ_SSI3) /* Vector 74: SSI 3 */ +VECTOR(tiva_uart3, TIVA_IRQ_UART3) /* Vector 75: UART 3 */ +VECTOR(tiva_uart4, TIVA_IRQ_UART4) /* Vector 76: UART 4 */ +VECTOR(tiva_uart5, TIVA_IRQ_UART5) /* Vector 77: UART 5 */ +VECTOR(tiva_uart6, TIVA_IRQ_UART6) /* Vector 78: UART 6 */ +VECTOR(tiva_uart7, TIVA_IRQ_UART7) /* Vector 79: UART 7 */ + +UNUSED(TIVA_RESERVED_80) /* Vector 80: Reserved */ +UNUSED(TIVA_RESERVED_81) /* Vector 81: Reserved */ +UNUSED(TIVA_RESERVED_82) /* Vector 82: Reserved */ +UNUSED(TIVA_RESERVED_83) /* Vector 83: Reserved */ +VECTOR(tiva_i2c2, TIVA_IRQ_I2C2) /* Vector 84: I2C 2 */ +VECTOR(tiva_i2c3, TIVA_IRQ_I2C3) /* Vector 85: I2C 3 */ +VECTOR(tiva_timer4a, TIVA_IRQ_TIMER4A) /* Vector 86: 16/32-Bit Timer 4 A */ +VECTOR(tiva_timer4b, TIVA_IRQ_TIMER4B) /* Vector 87: 16/32-Bit Timer 4 B */ +UNUSED(TIVA_RESERVED_88) /* Vector 88: Reserved */ +UNUSED(TIVA_RESERVED_89) /* Vector 89: Reserved */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +UNUSED(TIVA_RESERVED_91) /* Vector 91: Reserved */ +UNUSED(TIVA_RESERVED_92) /* Vector 92: Reserved */ +UNUSED(TIVA_RESERVED_93) /* Vector 93: Reserved */ +UNUSED(TIVA_RESERVED_94) /* Vector 94: Reserved */ +UNUSED(TIVA_RESERVED_95) /* Vector 95: Reserved */ +UNUSED(TIVA_RESERVED_96) /* Vector 96: Reserved */ +UNUSED(TIVA_RESERVED_97) /* Vector 97: Reserved */ +UNUSED(TIVA_RESERVED_98) /* Vector 98: Reserved */ +UNUSED(TIVA_RESERVED_99) /* Vector 99: Reserved */ + +UNUSED(TIVA_RESERVED_100) /* Vector 100: Reserved */ +UNUSED(TIVA_RESERVED_101) /* Vector 101: Reserved */ +UNUSED(TIVA_RESERVED_102) /* Vector 102: Reserved */ +UNUSED(TIVA_RESERVED_103) /* Vector 103: Reserved */ +UNUSED(TIVA_RESERVED_104) /* Vector 104: Reserved */ +UNUSED(TIVA_RESERVED_105) /* Vector 105: Reserved */ +UNUSED(TIVA_RESERVED_106) /* Vector 106: Reserved */ +UNUSED(TIVA_RESERVED_107) /* Vector 107: Reserved */ +VECTOR(tiva_timer5a, TIVA_IRQ_TIMER5A) /* Vector 108: 16/32-Bit Timer 5 A */ +VECTOR(tiva_timer5b, TIVA_IRQ_TIMER5B) /* Vector 109: 16/32-Bit Timer 5 B */ + +VECTOR(tiva_wtimer0a, TIVA_IRQ_WTIMER0A) /* Vector 110: 32/64-Bit Timer 0 A */ +VECTOR(tiva_wtimer0b, TIVA_IRQ_WTIMER0B) /* Vector 111: 32/64-Bit Timer 0 B */ +VECTOR(tiva_wtimer1a, TIVA_IRQ_WTIMER1A) /* Vector 112: 32/64-Bit Timer 1 A */ +VECTOR(tiva_wtimer1b, TIVA_IRQ_WTIMER1B) /* Vector 113: 32/64-Bit Timer 1 B */ +VECTOR(tiva_wtimer2a, TIVA_IRQ_WTIMER2A) /* Vector 114: 32/64-Bit Timer 2 A */ +VECTOR(tiva_wtimer2b, TIVA_IRQ_WTIMER2B) /* Vector 115: 32/64-Bit Timer 2 B */ +VECTOR(tiva_wtimer3a, TIVA_IRQ_WTIMER3A) /* Vector 116: 32/64-Bit Timer 3 A */ +VECTOR(tiva_wtimer3b, TIVA_IRQ_WTIMER3B) /* Vector 117: 32/64-Bit Timer 3 B */ +VECTOR(tiva_wtimer4a, TIVA_IRQ_WTIMER4A) /* Vector 118: 32/64-Bit Timer 4 A */ +VECTOR(tiva_WTIMER4B, TIVA_IRQ_WTIMER4B) /* Vector 119: 32/64-Bit Timer 4 B */ + +VECTOR(tiva_wtimer5a, TIVA_IRQ_WTIMER5A) /* Vector 120: 32/64-Bit Timer 5 A */ +VECTOR(tiva_wtimer5b, TIVA_IRQ_WTIMER5B) /* Vector 121: 32/64-Bit Timer 5 B */ +VECTOR(tiva_system, TIVA_IRQ_SYSTEM) /* Vector 122: System Exception (imprecise) */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +VECTOR(tiva_i2c4, TIVA_IRQ_I2C4) /* Vector 125: I2C4 */ +VECTOR(tiva_i2c5, TIVA_IRQ_I2C5) /* Vector 126: I2C5 */ +VECTOR(tiva_gpiom, TIVA_IRQ_GPIOM) /* Vector 127: GPIO Port M */ +VECTOR(tiva_gpion, TIVA_IRQ_GPION) /* Vector 128: GPIO Port N */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +UNUSED(TIVA_RESERVED_130) /* Vector 130: Reserved */ +UNUSED(TIVA_RESERVED_131) /* Vector 131: Reserved */ +VECTOR(tiva_gpiop, TIVA_IRQ_GPIOP) /* Vector 132: GPIO Port P (Summary or P0) */ +VECTOR(tiva_gpiop1, TIVA_IRQ_GPIOP1) /* Vector 133: GPIO Port P1 */ +VECTOR(tiva_gpiop2, TIVA_IRQ_GPIOP2) /* Vector 134: GPIO Port P2 */ +VECTOR(tiva_gpiop3, TIVA_IRQ_GPIOP3) /* Vector 135: GPIO Port P3 */ +VECTOR(tiva_gpiop4, TIVA_IRQ_GPIOP4) /* Vector 136: GPIO Port P4 */ +VECTOR(tiva_gpiop5, TIVA_IRQ_GPIOP5) /* Vector 137: GPIO Port P5 */ +VECTOR(tiva_gpiop6, TIVA_IRQ_GPIOP6) /* Vector 138: GPIO Port P6 */ +VECTOR(tiva_gpiop7, TIVA_IRQ_GPIOP7) /* Vector 139: GPIO Port P7 */ + +VECTOR(tiva_gpioq, TIVA_IRQ_GPIOQ) /* Vector 140: GPIO Port Q (Summary or Q0) */ +VECTOR(tiva_gpioq1, TIVA_IRQ_GPIOQ1) /* Vector 141: GPIO Port Q1 */ +VECTOR(tiva_gpioq2, TIVA_IRQ_GPIOQ2) /* Vector 142: GPIO Port Q2 */ +VECTOR(tiva_gpioq3, TIVA_IRQ_GPIOQ3) /* Vector 143: GPIO Port Q3 */ +VECTOR(tiva_gpioq4, TIVA_IRQ_GPIOQ4) /* Vector 144: GPIO Port Q4 */ +VECTOR(tiva_gpioq5, TIVA_IRQ_GPIOQ5) /* Vector 145: GPIO Port Q5 */ +VECTOR(tiva_gpioq6, TIVA_IRQ_GPIOQ6) /* Vector 146: GPIO Port Q6 */ +VECTOR(tiva_gpioq7, TIVA_IRQ_GPIOQ7) /* Vector 147: GPIO Port Q7 */ +UNUSED(TIVA_RESERVED_148) /* Vector 148: Reserved */ +UNUSED(TIVA_RESERVED_149) /* Vector 149: Reserved */ + +VECTOR(tiva_pwm1_gen0, TIVA_IRQ_PWM1_GEN0) /* Vector 150: PWM1 Generator 0 */ +VECTOR(tiva_pwm1_gen1, TIVA_IRQ_PWM1_GEN1) /* Vector 151: PWM1 Generator 1 */ +VECTOR(tiva_pwm1_gen2, TIVA_IRQ_PWM1_GEN2) /* Vector 152: PWM1 Generator 2 */ +VECTOR(tiva_pwm1_gen3, TIVA_IRQ_PWM1_GEN3) /* Vector 153: PWM1 Generator 3 */ +VECTOR(tiva_pwm1_fault, TIVA_IRQ_PWM1_FAULT) /* Vector 154: PWM1 Fault */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 155 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 155 + +# else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwm0_fault, TIVA_IRQ_PWM0_FAULT) /* Vector 25: PWM0 Fault */ +VECTOR(tiva_pwm0_gen0, TIVA_IRQ_PWM0_GEN0) /* Vector 26: PWM0 Generator 0 */ +VECTOR(tiva_pwm0_gen1, TIVA_IRQ_PWM0_GEN1) /* Vector 27: PWM0 Generator 1 */ +VECTOR(tiva_pwm0_gen2, TIVA_IRQ_PWM0_GEN2) /* Vector 28: PWM0 Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +VECTOR(tiva_compare0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_compare1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +VECTOR(tiva_compare2, TIVA_IRQ_COMPARE2) /* Vector 43: Analog Comparator 2 */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +UNUSED(TIVA_RESERVED_47) /* Vector 47: GPIO Port G */ +UNUSED(TIVA_RESERVED_48) /* Vector 48: GPIO Port H */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 49: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_qei1, TIVA_IRQ_QEI1) /* Vector 54: QEI1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 55: CAN 0 */ +VECTOR(tiva_can1, TIVA_IRQ_CAN1) /* Vector 56: CAN 1 */ +UNUSED(TIVA_RESERVED_57) /* Vector 57: Reserved */ +UNUSED(TIVA_RESERVED_58) /* Vector 58: Reserved */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 59: Hibernation Module */ + +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 60: USB */ +VECTOR(tiva_pwm0_gen3, TIVA_IRQ_PWM0_GEN3) /* Vector 61: PWM0 Generator 3 */ +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 62: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR) /* Vector 63: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 64: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 65: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 66: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 67: ADC1 Sequence 3 */ +UNUSED(TIVA_RESERVED_68) /* Vector 68: Reserved */ +UNUSED(TIVA_RESERVED_69) /* Vector 69: Reserved */ + +UNUSED(TIVA_RESERVED_70) /* Vector 70: GPIO Port J */ +UNUSED(TIVA_RESERVED_71) /* Vector 71: GPIO Port K */ +UNUSED(TIVA_RESERVED_72) /* Vector 72: GPIO Port L */ +VECTOR(tiva_ssi2, TIVA_IRQ_SSI2) /* Vector 73: SSI 2 */ +VECTOR(tiva_ssi3, TIVA_IRQ_SSI3) /* Vector 74: SSI 3 */ +VECTOR(tiva_uart3, TIVA_IRQ_UART3) /* Vector 75: UART 3 */ +VECTOR(tiva_uart4, TIVA_IRQ_UART4) /* Vector 76: UART 4 */ +VECTOR(tiva_uart5, TIVA_IRQ_UART5) /* Vector 77: UART 5 */ +VECTOR(tiva_uart6, TIVA_IRQ_UART6) /* Vector 78: UART 6 */ +VECTOR(tiva_uart7, TIVA_IRQ_UART7) /* Vector 79: UART 7 */ + +UNUSED(TIVA_RESERVED_80) /* Vector 80: Reserved */ +UNUSED(TIVA_RESERVED_81) /* Vector 81: Reserved */ +UNUSED(TIVA_RESERVED_82) /* Vector 82: Reserved */ +UNUSED(TIVA_RESERVED_83) /* Vector 83: Reserved */ +VECTOR(tiva_i2c2, TIVA_IRQ_I2C2) /* Vector 84: I2C 2 */ +VECTOR(tiva_i2c3, TIVA_IRQ_I2C3) /* Vector 85: I2C 3 */ +VECTOR(tiva_timer4a, TIVA_IRQ_TIMER4A) /* Vector 86: 16/32-Bit Timer 4 A */ +VECTOR(tiva_timer4b, TIVA_IRQ_TIMER4B) /* Vector 87: 16/32-Bit Timer 4 B */ +UNUSED(TIVA_RESERVED_88) /* Vector 88: Reserved */ +UNUSED(TIVA_RESERVED_89) /* Vector 89: Reserved */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +UNUSED(TIVA_RESERVED_91) /* Vector 91: Reserved */ +UNUSED(TIVA_RESERVED_92) /* Vector 92: Reserved */ +UNUSED(TIVA_RESERVED_93) /* Vector 93: Reserved */ +UNUSED(TIVA_RESERVED_94) /* Vector 94: Reserved */ +UNUSED(TIVA_RESERVED_95) /* Vector 95: Reserved */ +UNUSED(TIVA_RESERVED_96) /* Vector 96: Reserved */ +UNUSED(TIVA_RESERVED_97) /* Vector 97: Reserved */ +UNUSED(TIVA_RESERVED_98) /* Vector 98: Reserved */ +UNUSED(TIVA_RESERVED_99) /* Vector 99: Reserved */ + +UNUSED(TIVA_RESERVED_100) /* Vector 100: Reserved */ +UNUSED(TIVA_RESERVED_101) /* Vector 101: Reserved */ +UNUSED(TIVA_RESERVED_102) /* Vector 102: Reserved */ +UNUSED(TIVA_RESERVED_103) /* Vector 103: Reserved */ +UNUSED(TIVA_RESERVED_104) /* Vector 104: Reserved */ +UNUSED(TIVA_RESERVED_105) /* Vector 105: Reserved */ +UNUSED(TIVA_RESERVED_106) /* Vector 106: Reserved */ +UNUSED(TIVA_RESERVED_107) /* Vector 107: Reserved */ +VECTOR(tiva_timer5a, TIVA_IRQ_TIMER5A) /* Vector 108: 16/32-Bit Timer 5 A */ +VECTOR(tiva_timer5b, TIVA_IRQ_TIMER5B) /* Vector 109: 16/32-Bit Timer 5 B */ + +VECTOR(tiva_wtimer0a, TIVA_IRQ_WTIMER0A) /* Vector 110: 32/64-Bit Timer 0 A */ +VECTOR(tiva_wtimer0b, TIVA_IRQ_WTIMER0B) /* Vector 111: 32/64-Bit Timer 0 B */ +VECTOR(tiva_wtimer1a, TIVA_IRQ_WTIMER1A) /* Vector 112: 32/64-Bit Timer 1 A */ +VECTOR(tiva_wtimer1b, TIVA_IRQ_WTIMER1B) /* Vector 113: 32/64-Bit Timer 1 B */ +VECTOR(tiva_wtimer2a, TIVA_IRQ_WTIMER2A) /* Vector 114: 32/64-Bit Timer 2 A */ +VECTOR(tiva_wtimer2b, TIVA_IRQ_WTIMER2B) /* Vector 115: 32/64-Bit Timer 2 B */ +VECTOR(tiva_wtimer3a, TIVA_IRQ_WTIMER3A) /* Vector 116: 32/64-Bit Timer 3 A */ +VECTOR(tiva_wtimer3b, TIVA_IRQ_WTIMER3B) /* Vector 117: 32/64-Bit Timer 3 B */ +VECTOR(tiva_wtimer4a, TIVA_IRQ_WTIMER4A) /* Vector 118: 32/64-Bit Timer 4 A */ +VECTOR(tiva_WTIMER4B, TIVA_IRQ_WTIMER4B) /* Vector 119: 32/64-Bit Timer 4 B */ + +VECTOR(tiva_wtimer5a, TIVA_IRQ_WTIMER5A) /* Vector 120: 32/64-Bit Timer 5 A */ +VECTOR(tiva_wtimer5b, TIVA_IRQ_WTIMER5B) /* Vector 121: 32/64-Bit Timer 5 B */ +VECTOR(tiva_system, TIVA_IRQ_SYSTEM) /* Vector 122: System Exception (imprecise) */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +UNUSED(TIVA_RESERVED_125) /* Vector 125: Reserved */ +UNUSED(TIVA_RESERVED_126) /* Vector 126: Reserved */ +UNUSED(TIVA_RESERVED_127) /* Vector 127: Reserved */ +UNUSED(TIVA_RESERVED_128) /* Vector 128: Reserved */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +UNUSED(TIVA_RESERVED_130) /* Vector 130: Reserved */ +UNUSED(TIVA_RESERVED_131) /* Vector 131: Reserved */ +UNUSED(TIVA_RESERVED_132) /* Vector 132: Reserved */ +UNUSED(TIVA_RESERVED_133) /* Vector 133: Reserved */ +UNUSED(TIVA_RESERVED_134) /* Vector 134: Reserved */ +UNUSED(TIVA_RESERVED_135) /* Vector 135: Reserved */ +UNUSED(TIVA_RESERVED_136) /* Vector 136: Reserved */ +UNUSED(TIVA_RESERVED_137) /* Vector 137: Reserved */ +UNUSED(TIVA_RESERVED_138) /* Vector 138: Reserved */ +UNUSED(TIVA_RESERVED_139) /* Vector 139: Reserved */ + +UNUSED(TIVA_RESERVED_140) /* Vector 140: Reserved */ +UNUSED(TIVA_RESERVED_141) /* Vector 141: Reserved */ +UNUSED(TIVA_RESERVED_142) /* Vector 142: Reserved */ +UNUSED(TIVA_RESERVED_143) /* Vector 143: Reserved */ +UNUSED(TIVA_RESERVED_144) /* Vector 144: Reserved */ +UNUSED(TIVA_RESERVED_145) /* Vector 145: Reserved */ +UNUSED(TIVA_RESERVED_146) /* Vector 146: Reserved */ +UNUSED(TIVA_RESERVED_147) /* Vector 147: Reserved */ +UNUSED(TIVA_RESERVED_148) /* Vector 148: Reserved */ +UNUSED(TIVA_RESERVED_149) /* Vector 149: Reserved */ + +VECTOR(tiva_pwm1_gen0, TIVA_IRQ_PWM1_GEN0) /* Vector 150: PWM1 Generator 0 */ +VECTOR(tiva_pwm1_gen1, TIVA_IRQ_PWM1_GEN1) /* Vector 151: PWM1 Generator 1 */ +VECTOR(tiva_pwm1_gen2, TIVA_IRQ_PWM1_GEN2) /* Vector 152: PWM1 Generator 2 */ +VECTOR(tiva_pwm1_gen3, TIVA_IRQ_PWM1_GEN3) /* Vector 153: PWM1 Generator 3 */ +VECTOR(tiva_pwm1_fault, TIVA_IRQ_PWM1_FAULT) /* Vector 154: PWM1 Fault */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C129XNC) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 130 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 130 + +# else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwm0_fault, TIVA_IRQ_PWM0_FAULT) /* Vector 25: PWM0 Fault */ +VECTOR(tiva_pwm0_gen0, TIVA_IRQ_PWM0_GEN0) /* Vector 26: PWM0 Generator 0 */ +VECTOR(tiva_pwm0_gen1, TIVA_IRQ_PWM0_GEN1) /* Vector 27: PWM0 Generator 1 */ +VECTOR(tiva_pwm0_gen2, TIVA_IRQ_PWM0_GEN2) /* Vector 28: PWM0 Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +VECTOR(tiva_compare0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_compare1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +VECTOR(tiva_compare2, TIVA_IRQ_COMPARE2) /* Vector 43: Analog Comparator 2 */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +VECTOR(tiva_gpioh, TIVA_IRQ_GPIOH) /* Vector 48: GPIO Port H */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 49: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 54: CAN 0 */ +VECTOR(tiva_can1, TIVA_IRQ_CAN1) /* Vector 55: CAN 1 */ +VECTOR(tiva_ethcon, TIVA_IRQ_ETHCON) /* Vector 56: Ethernet MAC */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 57: Hibernation Module */ +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 58: USB MAC */ +VECTOR(tiva_pwm0_gen3, TIVA_IRQ_PWM0_GEN3) /* Vector 59: PWM0 Generator 3 */ + +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 60: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR) /* Vector 61: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 62: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 63: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 64: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 65: ADC1 Sequence 3 */ +VECTOR(tiva_epi0, TIVA_IRQ_EPI0) /* Vector 66: ADC1 Sequence 3 */ +VECTOR(tiva_gpioj, TIVA_IRQ_GPIOJ) /* Vector 67: GPIO Port J */ +VECTOR(tiva_gpiok, TIVA_IRQ_GPIOK) /* Vector 68: GPIO Port K */ +VECTOR(tiva_gpiol, TIVA_IRQ_GPIOL) /* Vector 69: GPIO Port L */ + +VECTOR(tiva_ssi2, TIVA_IRQ_SSI2) /* Vector 70: SSI 2 */ +VECTOR(tiva_ssi3, TIVA_IRQ_SSI3) /* Vector 71: SSI 3 */ +VECTOR(tiva_uart3, TIVA_IRQ_UART3) /* Vector 72: UART 3 */ +VECTOR(tiva_uart4, TIVA_IRQ_UART4) /* Vector 73: UART 4 */ +VECTOR(tiva_uart5, TIVA_IRQ_UART5) /* Vector 74: UART 5 */ +VECTOR(tiva_uart6, TIVA_IRQ_UART6) /* Vector 75: UART 6 */ +VECTOR(tiva_uart7, TIVA_IRQ_UART7) /* Vector 76: UART 7 */ +VECTOR(tiva_i2c2, TIVA_IRQ_I2C2) /* Vector 77: I2C 2 */ +VECTOR(tiva_i2c3, TIVA_IRQ_I2C3) /* Vector 78: I2C 3 */ +VECTOR(tiva_timer4a, TIVA_IRQ_TIMER4A) /* Vector 79: 16/32-Bit Timer 4 A */ + +VECTOR(tiva_timer4b, TIVA_IRQ_TIMER4B) /* Vector 80: 16/32-Bit Timer 4 B */ +VECTOR(tiva_timer5a, TIVA_IRQ_TIMER5A) /* Vector 81: 16/32-Bit Timer 5 A */ +VECTOR(tiva_timer5b, TIVA_IRQ_TIMER5B) /* Vector 82: 16/32-Bit Timer 5 B */ +VECTOR(tiva_float, TIVA_IRQ_FLOAT) /* Vector 83: Floating point exception */ +UNUSED(TIVA_RESERVED_84) /* Vector 84: Reserved */ +UNUSED(TIVA_RESERVED_85) /* Vector 85: Reserved */ +VECTOR(tiva_i2c4, TIVA_IRQ_I2C4) /* Vector 86: I2C 2 */ +VECTOR(tiva_i2c5, TIVA_IRQ_I2C5) /* Vector 87: I2C 3 */ +VECTOR(tiva_gpiom, TIVA_IRQ_GPIOM) /* Vector 88: GPIO Port M */ +VECTOR(tiva_gpion, TIVA_IRQ_GPION) /* Vector 89: GPIO Port N */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +VECTOR(tiva_tamper, TIVA_IRQ_TAMPER) /* Vector 91: Tamper */ +VECTOR(tiva_gpiop, TIVA_IRQ_GPIOP) /* Vector 92: GPIO Port P (Summary or P0) */ +VECTOR(tiva_gpiop1, TIVA_IRQ_GPIOP1) /* Vector 93: GPIO Port P1 */ +VECTOR(tiva_gpiop2, TIVA_IRQ_GPIOP2) /* Vector 94: GPIO Port P2 */ +VECTOR(tiva_gpiop3, TIVA_IRQ_GPIOP3) /* Vector 95: GPIO Port P3 */ +VECTOR(tiva_gpiop4, TIVA_IRQ_GPIOP4) /* Vector 96: GPIO Port P4 */ +VECTOR(tiva_gpiop5, TIVA_IRQ_GPIOP5) /* Vector 97: GPIO Port P5 */ +VECTOR(tiva_gpiop6, TIVA_IRQ_GPIOP6) /* Vector 98: GPIO Port P6 */ +VECTOR(tiva_gpiop7, TIVA_IRQ_GPIOP7) /* Vector 99: GPIO Port P7 */ + +VECTOR(tiva_gpioq, TIVA_IRQ_GPIOQ) /* Vector 100: GPIO Port Q (Summary or Q0) */ +VECTOR(tiva_gpioq1, TIVA_IRQ_GPIOQ1) /* Vector 101: GPIO Port Q1 */ +VECTOR(tiva_gpioq2, TIVA_IRQ_GPIOQ2) /* Vector 102: GPIO Port Q2 */ +VECTOR(tiva_gpioq3, TIVA_IRQ_GPIOQ3) /* Vector 103: GPIO Port Q3 */ +VECTOR(tiva_gpioq4, TIVA_IRQ_GPIOQ4) /* Vector 104: GPIO Port Q4 */ +VECTOR(tiva_gpioq5, TIVA_IRQ_GPIOQ5) /* Vector 105: GPIO Port Q5 */ +VECTOR(tiva_gpioq6, TIVA_IRQ_GPIOQ6) /* Vector 106: GPIO Port Q6 */ +VECTOR(tiva_gpioq7, TIVA_IRQ_GPIOQ7) /* Vector 107: GPIO Port Q7 */ +VECTOR(tiva_gpior, TIVA_IRQ_GPIOR) /* Vector 108: GPIO Port R */ +VECTOR(tiva_gpios, TIVA_IRQ_GPIOS) /* Vector 109: GPIO Port S */ + +VECTOR(tiva_shamd5, TIVA_IRQ_SHAMD5) /* Vector 110: SHA/MD5 */ +VECTOR(tiva_aes, TIVA_IRQ_AES) /* Vector 111: AES */ +VECTOR(tiva_des, TIVA_IRQ_DES) /* Vector 112: DES */ +VECTOR(tiva_lcd, TIVA_IRQ_LCD) /* Vector 113: LCD */ +VECTOR(tiva_timer6a, TIVA_IRQ_TIMER6A) /* Vector 114: 16/32-Bit Timer 6 A */ +VECTOR(tiva_timer6b, TIVA_IRQ_TIMER6B) /* Vector 115: 16/32-Bit Timer 6 B */ +VECTOR(tiva_timer7a, TIVA_IRQ_TIMER7A) /* Vector 116: 16/32-Bit Timer 7 A */ +VECTOR(tiva_timer7b, TIVA_IRQ_TIMER7B) /* Vector 117: 16/32-Bit Timer 7 B */ +VECTOR(tiva_i2c6, TIVA_IRQ_I2C6) /* Vector 118: I2C 6 */ +VECTOR(tiva_i2c7, TIVA_IRQ_I2C7) /* Vector 119: I2C 7 */ + +UNUSED(TIVA_RESERVED_120) /* Vector 120: Reserved */ +VECTOR(tiva_1wire, TIVA_IRQ_1WIRE) /* Vector 121: I2C 7 */ +UNUSED(TIVA_RESERVED_122) /* Vector 122: Reserved */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +VECTOR(tiva_i2c8, TIVA_IRQ_I2C8) /* Vector 125: I2C 8 */ +VECTOR(tiva_i2c9, TIVA_IRQ_I2C9) /* Vector 126: I2C 9 */ +VECTOR(tiva_gpiot, TIVA_IRQ_GPIOT) /* Vector 127: GPIO Port T */ +UNUSED(TIVA_RESERVED_128) /* Vector 128: Reserved */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ + +#elif defined(CONFIG_ARCH_CHIP_TM4C1294NC) + +/* If the common ARMv7-M vector handling is used, then all it needs is the following + * definition that provides the number of supported vectors. + */ + +# ifdef CONFIG_ARMV7M_CMNVECTOR + +/* Reserve 130 interrupt table entries for I/O interrupts. */ + +ARMV7M_PERIPHERAL_INTERRUPTS 130 + +# else + +VECTOR(tiva_gpioa, TIVA_IRQ_GPIOA) /* Vector 16: GPIO Port A */ +VECTOR(tiva_gpiob, TIVA_IRQ_GPIOB) /* Vector 17: GPIO Port B */ +VECTOR(tiva_gpioc, TIVA_IRQ_GPIOC) /* Vector 18: GPIO Port C */ +VECTOR(tiva_gpiod, TIVA_IRQ_GPIOD) /* Vector 19: GPIO Port D */ + +VECTOR(tiva_gpioe, TIVA_IRQ_GPIOE) /* Vector 20: GPIO Port E */ +VECTOR(tiva_uart0, TIVA_IRQ_UART0) /* Vector 21: UART 0 */ +VECTOR(tiva_uart1, TIVA_IRQ_UART1) /* Vector 22: UART 1 */ +VECTOR(tiva_ssi0, TIVA_IRQ_SSI0) /* Vector 23: SSI 0 */ +VECTOR(tiva_i2c0, TIVA_IRQ_I2C0) /* Vector 24: I2C 0 */ +VECTOR(tiva_pwm0_fault, TIVA_IRQ_PWM0_FAULT) /* Vector 25: PWM0 Fault */ +VECTOR(tiva_pwm0_gen0, TIVA_IRQ_PWM0_GEN0) /* Vector 26: PWM0 Generator 0 */ +VECTOR(tiva_pwm0_gen1, TIVA_IRQ_PWM0_GEN1) /* Vector 27: PWM0 Generator 1 */ +VECTOR(tiva_pwm0_gen2, TIVA_IRQ_PWM0_GEN2) /* Vector 28: PWM0 Generator 2 */ +VECTOR(tiva_qei0, TIVA_IRQ_QEI0) /* Vector 29: QEI0 */ + +VECTOR(tiva_adc0, TIVA_IRQ_ADC0) /* Vector 30: ADC Sequence 0 */ +VECTOR(tiva_adc1, TIVA_IRQ_ADC1) /* Vector 31: ADC Sequence 1 */ +VECTOR(tiva_adc2, TIVA_IRQ_ADC2) /* Vector 32: ADC Sequence 2 */ +VECTOR(tiva_adc3, TIVA_IRQ_ADC3) /* Vector 33: ADC Sequence 3 */ +VECTOR(tiva_wdog, TIVA_IRQ_WDOG) /* Vector 34: Watchdog Timers 0 and 1 */ +VECTOR(tiva_timer0a, TIVA_IRQ_TIMER0A) /* Vector 35: 16/32-Bit Timer 0 A */ +VECTOR(tiva_timer0b, TIVA_IRQ_TIMER0B) /* Vector 36: 16/32-Bit Timer 0 B */ +VECTOR(tiva_timer1a, TIVA_IRQ_TIMER1A) /* Vector 37: 16/32-Bit Timer 1 A */ +VECTOR(tiva_timer1b, TIVA_IRQ_TIMER1B) /* Vector 38: 16/32-Bit Timer 1 B */ +VECTOR(tiva_timer2a, TIVA_IRQ_TIMER2A) /* Vector 39: 16/32-Bit Timer 2 A */ + +VECTOR(tiva_timer2b, TIVA_IRQ_TIMER2B) /* Vector 40: 16/32-Bit Timer 2 B */ +VECTOR(tiva_compare0, TIVA_IRQ_COMPARE0) /* Vector 41: Analog Comparator 0 */ +VECTOR(tiva_compare1, TIVA_IRQ_COMPARE1) /* Vector 42: Analog Comparator 1 */ +VECTOR(tiva_compare2, TIVA_IRQ_COMPARE2) /* Vector 43: Analog Comparator 2 */ +VECTOR(tiva_syscon, TIVA_IRQ_SYSCON) /* Vector 44: System Control */ +VECTOR(tiva_flashcon, TIVA_IRQ_FLASHCON) /* Vector 45: FLASH and EEPROM Control */ +VECTOR(tiva_gpiof, TIVA_IRQ_GPIOF) /* Vector 46: GPIO Port F */ +VECTOR(tiva_gpiog, TIVA_IRQ_GPIOG) /* Vector 47: GPIO Port G */ +VECTOR(tiva_gpioh, TIVA_IRQ_GPIOH) /* Vector 48: GPIO Port H */ +VECTOR(tiva_uart2, TIVA_IRQ_UART2) /* Vector 49: UART 2 */ + +VECTOR(tiva_ssi1, TIVA_IRQ_SSI1) /* Vector 50: SSI 1 */ +VECTOR(tiva_timer3a, TIVA_IRQ_TIMER3A) /* Vector 51: 16/32-Bit Timer 3 A */ +VECTOR(tiva_timer3b, TIVA_IRQ_TIMER3B) /* Vector 52: 16/32-Bit Timer 3 B */ +VECTOR(tiva_i2c1, TIVA_IRQ_I2C1) /* Vector 53: I2C 1 */ +VECTOR(tiva_can0, TIVA_IRQ_CAN0) /* Vector 54: CAN 0 */ +VECTOR(tiva_can1, TIVA_IRQ_CAN1) /* Vector 55: CAN 1 */ +VECTOR(tiva_ethcon, TIVA_IRQ_ETHCON) /* Vector 56: Ethernet MAC */ +VECTOR(tiva_hibernate, TIVA_IRQ_HIBERNATE) /* Vector 57: Hibernation Module */ +VECTOR(tiva_usb, TIVA_IRQ_USB) /* Vector 58: USB MAC */ +VECTOR(tiva_pwm0_gen3, TIVA_IRQ_PWM0_GEN3) /* Vector 59: PWM0 Generator 3 */ + +VECTOR(tiva_udmasoft, TIVA_IRQ_UDMASOFT) /* Vector 60: uDMA Software */ +VECTOR(tiva_udmaerro, TIVA_IRQ_UDMAERROR) /* Vector 61: uDMA Error */ +VECTOR(tiva_adc1_0, TIVA_IRQ_ADC1_0) /* Vector 62: ADC1 Sequence 0 */ +VECTOR(tiva_adc1_1, TIVA_IRQ_ADC1_1) /* Vector 63: ADC1 Sequence 1 */ +VECTOR(tiva_adc1_2, TIVA_IRQ_ADC1_2) /* Vector 64: ADC1 Sequence 2 */ +VECTOR(tiva_adc1_3, TIVA_IRQ_ADC1_3) /* Vector 65: ADC1 Sequence 3 */ +VECTOR(tiva_epi0, TIVA_IRQ_EPI0) /* Vector 66: ADC1 Sequence 3 */ +VECTOR(tiva_gpioj, TIVA_IRQ_GPIOJ) /* Vector 67: GPIO Port J */ +VECTOR(tiva_gpiok, TIVA_IRQ_GPIOK) /* Vector 68: GPIO Port K */ +VECTOR(tiva_gpiol, TIVA_IRQ_GPIOL) /* Vector 69: GPIO Port L */ + +VECTOR(tiva_ssi2, TIVA_IRQ_SSI2) /* Vector 70: SSI 2 */ +VECTOR(tiva_ssi3, TIVA_IRQ_SSI3) /* Vector 71: SSI 3 */ +VECTOR(tiva_uart3, TIVA_IRQ_UART3) /* Vector 72: UART 3 */ +VECTOR(tiva_uart4, TIVA_IRQ_UART4) /* Vector 73: UART 4 */ +VECTOR(tiva_uart5, TIVA_IRQ_UART5) /* Vector 74: UART 5 */ +VECTOR(tiva_uart6, TIVA_IRQ_UART6) /* Vector 75: UART 6 */ +VECTOR(tiva_uart7, TIVA_IRQ_UART7) /* Vector 76: UART 7 */ +VECTOR(tiva_i2c2, TIVA_IRQ_I2C2) /* Vector 77: I2C 2 */ +VECTOR(tiva_i2c3, TIVA_IRQ_I2C3) /* Vector 78: I2C 3 */ +VECTOR(tiva_timer4a, TIVA_IRQ_TIMER4A) /* Vector 79: 16/32-Bit Timer 4 A */ + +VECTOR(tiva_timer4b, TIVA_IRQ_TIMER4B) /* Vector 80: 16/32-Bit Timer 4 B */ +VECTOR(tiva_timer5a, TIVA_IRQ_TIMER5A) /* Vector 81: 16/32-Bit Timer 5 A */ +VECTOR(tiva_timer5b, TIVA_IRQ_TIMER5B) /* Vector 82: 16/32-Bit Timer 5 B */ +VECTOR(tiva_float, TIVA_IRQ_FLOAT) /* Vector 83: Floating point exception */ +UNUSED(TIVA_RESERVED_84) /* Vector 84: Reserved */ +UNUSED(TIVA_RESERVED_85) /* Vector 85: Reserved */ +VECTOR(tiva_i2c4, TIVA_IRQ_I2C4) /* Vector 86: I2C 2 */ +VECTOR(tiva_i2c5, TIVA_IRQ_I2C5) /* Vector 87: I2C 3 */ +VECTOR(tiva_gpiom, TIVA_IRQ_GPIOM) /* Vector 88: GPIO Port M */ +VECTOR(tiva_gpion, TIVA_IRQ_GPION) /* Vector 89: GPIO Port N */ + +UNUSED(TIVA_RESERVED_90) /* Vector 90: Reserved */ +VECTOR(tiva_tamper, TIVA_IRQ_TAMPER) /* Vector 91: Tamper */ +VECTOR(tiva_gpiop, TIVA_IRQ_GPIOP) /* Vector 92: GPIO Port P (Summary or P0) */ +VECTOR(tiva_gpiop1, TIVA_IRQ_GPIOP1) /* Vector 93: GPIO Port P1 */ +VECTOR(tiva_gpiop2, TIVA_IRQ_GPIOP2) /* Vector 94: GPIO Port P2 */ +VECTOR(tiva_gpiop3, TIVA_IRQ_GPIOP3) /* Vector 95: GPIO Port P3 */ +VECTOR(tiva_gpiop4, TIVA_IRQ_GPIOP4) /* Vector 96: GPIO Port P4 */ +VECTOR(tiva_gpiop5, TIVA_IRQ_GPIOP5) /* Vector 97: GPIO Port P5 */ +VECTOR(tiva_gpiop6, TIVA_IRQ_GPIOP6) /* Vector 98: GPIO Port P6 */ +VECTOR(tiva_gpiop7, TIVA_IRQ_GPIOP7) /* Vector 99: GPIO Port P7 */ + +VECTOR(tiva_gpioq, TIVA_IRQ_GPIOQ) /* Vector 100: GPIO Port Q (Summary or Q0) */ +VECTOR(tiva_gpioq1, TIVA_IRQ_GPIOQ1) /* Vector 101: GPIO Port Q1 */ +VECTOR(tiva_gpioq2, TIVA_IRQ_GPIOQ2) /* Vector 102: GPIO Port Q2 */ +VECTOR(tiva_gpioq3, TIVA_IRQ_GPIOQ3) /* Vector 103: GPIO Port Q3 */ +VECTOR(tiva_gpioq4, TIVA_IRQ_GPIOQ4) /* Vector 104: GPIO Port Q4 */ +VECTOR(tiva_gpioq5, TIVA_IRQ_GPIOQ5) /* Vector 105: GPIO Port Q5 */ +VECTOR(tiva_gpioq6, TIVA_IRQ_GPIOQ6) /* Vector 106: GPIO Port Q6 */ +VECTOR(tiva_gpioq7, TIVA_IRQ_GPIOQ7) /* Vector 107: GPIO Port Q7 */ +UNUSED(TIVA_RESERVED_108) /* Vector 108: Reserved */ +UNUSED(TIVA_RESERVED_109) /* Vector 109: Reserved */ + +UNUSED(TIVA_RESERVED_110) /* Vector 110: Reserved */ +UNUSED(TIVA_RESERVED_111) /* Vector 111: Reserved */ +UNUSED(TIVA_RESERVED_112) /* Vector 112: Reserved */ +UNUSED(TIVA_RESERVED_113) /* Vector 113: Reserved */ +VECTOR(tiva_timer6a, TIVA_IRQ_TIMER6A) /* Vector 114: 16/32-Bit Timer 6 A */ +VECTOR(tiva_timer6b, TIVA_IRQ_TIMER6B) /* Vector 115: 16/32-Bit Timer 6 B */ +VECTOR(tiva_timer7a, TIVA_IRQ_TIMER7A) /* Vector 116: 16/32-Bit Timer 7 A */ +VECTOR(tiva_timer7b, TIVA_IRQ_TIMER7B) /* Vector 117: 16/32-Bit Timer 7 B */ +VECTOR(tiva_i2c6, TIVA_IRQ_I2C6) /* Vector 118: I2C 6 */ +VECTOR(tiva_i2c7, TIVA_IRQ_I2C7) /* Vector 119: I2C 7 */ + +UNUSED(TIVA_RESERVED_120) /* Vector 120: Reserved */ +UNUSED(TIVA_RESERVED_121) /* Vector 121: Reserved */ +UNUSED(TIVA_RESERVED_122) /* Vector 122: Reserved */ +UNUSED(TIVA_RESERVED_123) /* Vector 123: Reserved */ +UNUSED(TIVA_RESERVED_124) /* Vector 124: Reserved */ +VECTOR(tiva_i2c8, TIVA_IRQ_I2C8) /* Vector 125: I2C 8 */ +VECTOR(tiva_i2c9, TIVA_IRQ_I2C9) /* Vector 126: I2C 9 */ +UNUSED(TIVA_RESERVED_127) /* Vector 127: Reserved */ +UNUSED(TIVA_RESERVED_128) /* Vector 128: Reserved */ +UNUSED(TIVA_RESERVED_129) /* Vector 129: Reserved */ + +# endif /* CONFIG_ARMV7M_CMNVECTOR */ +#else +# error "Vectors not known for this Tiva chip" +#endif diff --git a/arch/arm/src/tiva/lm3s_ethernet.c b/arch/arm/src/tiva/lm3s_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..5544e2544213f75c42ce7a9537b4a8782edb0afb --- /dev/null +++ b/arch/arm/src/tiva/lm3s_ethernet.c @@ -0,0 +1,1545 @@ +/**************************************************************************** + * arch/arm/src/tiva/lm3s_ethernet.c + * + * Copyright (C) 2009-2010, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_TIVA_ETHERNET) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "chip.h" +#include "up_arch.h" + +#include "tiva_gpio.h" +#include "tiva_ethernet.h" +#include "chip/tiva_pinmap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER should not be selected +#endif + +/* Half duplex can be forced if CONFIG_TIVA_ETHHDUPLEX is defined. */ + +#ifdef CONFIG_TIVA_ETHHDUPLEX +# define TIVA_DUPLEX_SETBITS 0 +# define TIVA_DUPLEX_CLRBITS MAC_TCTL_DUPLEX +#else +# define TIVA_DUPLEX_SETBITS MAC_TCTL_DUPLEX +# define TIVA_DUPLEX_CLRBITS 0 +#endif + +/* Auto CRC generation can be suppressed if CONFIG_TIVA_ETHNOAUTOCRC is definde */ + +#ifdef CONFIG_TIVA_ETHNOAUTOCRC +# define TIVA_CRC_SETBITS 0 +# define TIVA_CRC_CLRBITS MAC_TCTL_CRC +#else +# define TIVA_CRC_SETBITS MAC_TCTL_CRC +# define TIVA_CRC_CLRBITS 0 +#endif + +/* Tx padding can be suppressed if CONFIG_TIVA_ETHNOPAD is defined */ + +#ifdef CONFIG_TIVA_ETHNOPAD +# define TIVA_PADEN_SETBITS 0 +# define TIVA_PADEN_CLRBITS MAC_TCTL_PADEN +#else +# define TIVA_PADEN_SETBITS MAC_TCTL_PADEN +# define TIVA_PADEN_CLRBITS 0 +#endif + +#define TIVA_TCTCL_SETBITS (TIVA_DUPLEX_SETBITS|TIVA_CRC_SETBITS|TIVA_PADEN_SETBITS) +#define TIVA_TCTCL_CLRBITS (TIVA_DUPLEX_CLRBITS|TIVA_CRC_CLRBITS|TIVA_PADEN_CLRBITS) + +/* Multicast frames can be enabled by defining CONFIG_TIVA_MULTICAST */ + +#ifdef CONFIG_TIVA_MULTICAST +# define TIVA_AMUL_SETBITS MAC_RCTL_AMUL +# define TIVA_AMUL_CLRBITS 0 +#else +# define TIVA_AMUL_SETBITS 0 +# define TIVA_AMUL_CLRBITS MAC_RCTL_AMUL +#endif + +/* Promiscuous mode can be enabled by defining CONFIG_TIVA_PROMISCUOUS */ + +#ifdef CONFIG_TIVA_PROMISCUOUS +# define TIVA_PRMS_SETBITS MAC_RCTL_PRMS +# define TIVA_PRMS_CLRBITS 0 +#else +# define TIVA_PRMS_SETBITS 0 +# define TIVA_PRMS_CLRBITS MAC_RCTL_PRMS +#endif + +/* Bad CRC rejection can be enabled by define CONFIG_TIVA_BADCRC */ + +#ifdef CONFIG_TIVA_BADCRC +# define TIVA_BADCRC_SETBITS MAC_RCTL_BADCRC +# define TIVA_BADCRC_CLRBITS 0 +#else +# define TIVA_BADCRC_SETBITS 0 +# define TIVA_BADCRC_CLRBITS MAC_RCTL_BADCRC +#endif + +#define TIVA_RCTCL_SETBITS (TIVA_AMUL_SETBITS|TIVA_PRMS_SETBITS|TIVA_BADCRC_SETBITS) +#define TIVA_RCTCL_CLRBITS (TIVA_AMUL_CLRBITS|TIVA_PRMS_CLRBITS|TIVA_BADCRC_CLRBITS) + +/* CONFIG_TIVA_DUMPPACKET will dump the contents of each packet to the console. */ + +#ifdef CONFIG_TIVA_DUMPPACKET +# define tiva_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define tiva_dumppacket(m,a,n) +#endif + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define TIVA_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define TIVA_TXTIMEOUT (60*CLK_TCK) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define ETHBUF ((struct eth_hdr_s *)priv->ld_dev.d_buf) + +#define TIVA_MAX_MDCCLK 2500000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The tiva_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct tiva_driver_s +{ + /* The following fields would only be necessary on chips that support + * multiple Ethernet controllers. + */ + +#if TIVA_NETHCONTROLLERS > 1 + uint32_t ld_base; /* Ethernet controller base address */ + int ld_irq; /* Ethernet controller IRQ */ +#endif + + bool ld_bifup; /* true:ifup false:ifdown */ + WDOG_ID ld_txpoll; /* TX poll timer */ + WDOG_ID ld_txtimeout; /* TX timeout timer */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s ld_dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct tiva_driver_s g_lm3sdev[TIVA_NETHCONTROLLERS]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Miscellaneous low level helpers */ + +#if TIVA_NETHCONTROLLERS > 1 +static uint32_t tiva_ethin(struct tiva_driver_s *priv, int offset); +static void tiva_ethout(struct tiva_driver_s *priv, int offset, uint32_t value); +#else +static inline uint32_t tiva_ethin(struct tiva_driver_s *priv, int offset); +static inline void tiva_ethout(struct tiva_driver_s *priv, int offset, uint32_t value); +#endif +static void tiva_ethreset(struct tiva_driver_s *priv); +#if 0 /* Not used */ +static void tiva_phywrite(struct tiva_driver_s *priv, int regaddr, uint16_t value); +#endif +static uint16_t tiva_phyread(struct tiva_driver_s *priv, int regaddr); + +/* Common TX logic */ + +static int tiva_transmit(struct tiva_driver_s *priv); +static int tiva_txpoll(struct net_driver_s *dev); + +/* Interrupt handling */ + +static void tiva_receive(struct tiva_driver_s *priv); +static void tiva_txdone(struct tiva_driver_s *priv); +static int tiva_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static void tiva_polltimer(int argc, uint32_t arg, ...); +static void tiva_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int tiva_ifup(struct net_driver_s *dev); +static int tiva_ifdown(struct net_driver_s *dev); +static int tiva_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: tiva_ethin + * + * Description: + * Read a register from the Ethernet module + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Byte offset of the register from the ethernet base address + * + * Returned Value: + * Register value + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS > 1 +static uint32_t tiva_ethin(struct tiva_driver_s *priv, int offset) +{ + return getreg32(priv->ld_base + offset); +} +#else +static inline uint32_t tiva_ethin(struct tiva_driver_s *priv, int offset) +{ + return getreg32(TIVA_ETHCON_BASE + offset); +} +#endif + +/**************************************************************************** + * Function: tiva_ethout + * + * Description: + * Write a register to the Ethernet module + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Byte offset of the register from the ethernet base address + * value - The value to write the Ethernet register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS > 1 +static void tiva_ethout(struct tiva_driver_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->ld_base + offset); +} +#else +static inline void tiva_ethout(struct tiva_driver_s *priv, int offset, uint32_t value) +{ + putreg32(value, TIVA_ETHCON_BASE + offset); +} +#endif + +/**************************************************************************** + * Function: tiva_ethreset + * + * Description: + * Configure and reset the Ethernet module, leaving it in a disabled state. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_ethreset(struct tiva_driver_s *priv) +{ + irqstate_t flags; + uint32_t regval; + +#if TIVA_NETHCONTROLLERS > 1 +# error "If multiple interfaces are supported, this function would have to be redesigned" +#endif + + /* Make sure that clocking is enabled for the Ethernet (and PHY) peripherals */ + + flags = enter_critical_section(); + regval = getreg32(TIVA_SYSCON_RCGC2); + regval |= (SYSCON_RCGC2_EMAC0 | SYSCON_RCGC2_EPHY0); + putreg32(regval, TIVA_SYSCON_RCGC2); + nllvdbg("RCGC2: %08x\n", regval); + + /* Put the Ethernet controller into the reset state */ + + regval = getreg32(TIVA_SYSCON_SRCR2); + regval |= (SYSCON_SRCR2_EMAC0 | SYSCON_SRCR2_EPHY0); + putreg32(regval, TIVA_SYSCON_SRCR2); + + /* Wait just a bit. This is a much longer delay than necessary */ + + up_mdelay(2); + + /* Then take the Ethernet controller out of the reset state */ + + regval &= ~(SYSCON_SRCR2_EMAC0 | SYSCON_SRCR2_EPHY0); + putreg32(regval, TIVA_SYSCON_SRCR2); + nllvdbg("SRCR2: %08x\n", regval); + + /* Wait just a bit, again. If we touch the ethernet too soon, we may busfault. */ + + up_mdelay(2); + + /* Enable Port F for Ethernet LEDs: LED0=Bit 3; LED1=Bit 2 */ + +#ifdef CONFIG_TIVA_ETHLEDS + /* Configure the pins for the peripheral function */ + + tiva_configgpio(GPIO_ETHPHY_LED0 | GPIO_STRENGTH_2MA | GPIO_PADTYPE_STD); + tiva_configgpio(GPIO_ETHPHY_LED1 | GPIO_STRENGTH_2MA | GPIO_PADTYPE_STD); +#endif + + /* Disable all Ethernet controller interrupts */ + + regval = tiva_ethin(priv, TIVA_MAC_IM_OFFSET); + regval &= ~MAC_IM_ALLINTS; + tiva_ethout(priv, TIVA_MAC_IM_OFFSET, regval); + + /* Clear any pending interrupts (shouldn't be any) */ + + regval = tiva_ethin(priv, TIVA_MAC_RIS_OFFSET); + tiva_ethout(priv, TIVA_MAC_IACK_OFFSET, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Function: tiva_phywrite + * + * Description: + * Write a 16-bit word to a PHY register + * + * Parameters: + * priv - Reference to the driver state structure + * regaddr - Address of the PHY register to write + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void tiva_phywrite(struct tiva_driver_s *priv, int regaddr, uint16_t value) +{ + /* Wait for any MII transactions in progress to complete */ + + while ((tiva_ethin(priv, TIVA_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0); + + /* Set up the data to be written */ + + DEBUGASSERT(value < MAC_MTXD_MASK); + tiva_ethout(priv, TIVA_MAC_MTXD_OFFSET, value); + + /* Set up the PHY register address and start the write operation */ + + regaddr <<= MAC_MCTL_REGADR_SHIFT; + DEBUGASSERT((regaddr & MAC_MTXD_MASK) == regaddr); + tiva_ethout(priv, TIVA_MAC_MCTL_OFFSET, regaddr | MAC_MCTL_WRITE | MAC_MCTL_START); + + /* Wait for the write transaction to complete */ + + while ((tiva_ethin(priv, TIVA_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0); +} +#endif + +/**************************************************************************** + * Function: tiva_phyread + * + * Description: + * Write a 16-bit word to a PHY register + * + * Parameters: + * priv - Reference to the driver state structure + * regaddr - Address of the PHY register to write + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +static uint16_t tiva_phyread(struct tiva_driver_s *priv, int regaddr) +{ + /* Wait for any MII transactions in progress to complete */ + + while ((tiva_ethin(priv, TIVA_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0); + + /* Set up the PHY register address and start the read operation */ + + regaddr <<= MAC_MCTL_REGADR_SHIFT; + DEBUGASSERT((regaddr & MAC_MTXD_MASK) == regaddr); + tiva_ethout(priv, TIVA_MAC_MCTL_OFFSET, regaddr | MAC_MCTL_START); + + /* Wait for the write transaction to complete */ + + while ((tiva_ethin(priv, TIVA_MAC_MCTL_OFFSET) & MAC_MCTL_START) != 0); + + /* Read and return the PHY data */ + + return (uint16_t)(tiva_ethin(priv, TIVA_MAC_MRXD_OFFSET) & MAC_MTRD_MASK); +} + +/**************************************************************************** + * Function: tiva_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +static int tiva_transmit(struct tiva_driver_s *priv) +{ + irqstate_t flags; + uint32_t regval; + uint8_t *dbuf; + int pktlen; + int bytesleft; + int ret = -EBUSY; + + /* Verify that the hardware is ready to send another packet */ + + flags = enter_critical_section(); + if ((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0) + { + /* Increment statistics */ + + NETDEV_TXPACKETS(&priv->ld_dev); + tiva_dumppacket("Transmit packet", priv->ld_dev.d_buf, priv->ld_dev.d_len); + + /* Transfer the packet into the Tx FIFO. The LS 16-bits of the first + * 32-bit word written to the Tx FIFO contains the Ethernet payload + * data length. That is the full length of the message (d_len) minus + * the size of the Ethernet header (14). + */ + + pktlen = priv->ld_dev.d_len; + nllvdbg("Sending packet, pktlen: %d\n", pktlen); + DEBUGASSERT(pktlen > ETH_HDRLEN); + + dbuf = priv->ld_dev.d_buf; + regval = (uint32_t)(pktlen - 14); + regval |= ((uint32_t)(*dbuf++) << 16); + regval |= ((uint32_t)(*dbuf++) << 24); + tiva_ethout(priv, TIVA_MAC_DATA_OFFSET, regval); + + /* Write all of the whole, 32-bit values in the middle of the packet */ + + for (bytesleft = pktlen - 2; bytesleft > 3; bytesleft -= 4, dbuf += 4) + { + /* Transfer a whole word from the user buffer. Note, the user + * buffer may be un-aligned. + */ + + tiva_ethout(priv, TIVA_MAC_DATA_OFFSET, *(uint32_t *)dbuf); + } + + /* Write the last, partial word in the FIFO */ + + if (bytesleft > 0) + { + /* Write the last word */ + + regval = 0; + switch (bytesleft) + { + case 0: + default: + break; + + case 3: + regval |= ((uint32_t)dbuf[2] << 16); + case 2: + regval |= ((uint32_t)dbuf[1] << 8); + case 1: + regval |= (uint32_t)dbuf[0]; + break; + } + + tiva_ethout(priv, TIVA_MAC_DATA_OFFSET, regval); + } + + /* Activate the transmitter */ + + tiva_ethout(priv, TIVA_MAC_TR_OFFSET, MAC_TR_NEWTX); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->ld_txtimeout, TIVA_TXTIMEOUT, tiva_txtimeout, 1, (uint32_t)priv); + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Function: tiva_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_txpoll(struct net_driver_s *dev) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)dev->d_private; + int ret = OK; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + nllvdbg("Poll result: d_len=%d\n", priv->ld_dev.d_len); + if (priv->ld_dev.d_len > 0) + { + DEBUGASSERT((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0); + + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->ld_dev.d_flags)) +#endif + { + arp_out(&priv->ld_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->ld_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet. tiva_transmit() will return zero if the + * packet was successfully handled. + */ + + ret = tiva_transmit(priv); + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: tiva_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_receive(struct tiva_driver_s *priv) +{ + uint32_t regval; + uint8_t *dbuf; + int pktlen; + int bytesleft; + + /* Loop while there are incoming packets to be processed */ + + while ((tiva_ethin(priv, TIVA_MAC_NP_OFFSET) & MAC_NP_MASK) != 0) + { + /* Update statistics */ + + NETDEV_RXPACKETS(&priv->ld_dev); + + /* Copy the data data from the hardware to priv->ld_dev.d_buf. Set + * amount of data in priv->ld_dev.d_len + */ + + dbuf = priv->ld_dev.d_buf; + + /* The packet frame length begins in the LS 16-bits of the first + * word from the FIFO followed by the Ethernet header beginning + * in the MS 16-bits of the first word. + * + * Pick off the packet length from the first word. This packet length + * includes the len/type field (size 2) and the FCS (size 4). + */ + + regval = tiva_ethin(priv, TIVA_MAC_DATA_OFFSET); + pktlen = (int)(regval & 0x0000ffff); + nllvdbg("Receiving packet, pktlen: %d\n", pktlen); + + /* Check if the pktlen is valid. It should be large enough to hold + * an Ethernet header and small enough to fit entirely in the I/O + * buffer. Six is subtracted to acount for the 2-byte length/type + * and 4 byte FCS that are not copied into the uIP packet. + */ + + if (pktlen > (CONFIG_NET_ETH_MTU + 6) || pktlen <= (ETH_HDRLEN + 6)) + { + int wordlen; + + /* We will have to drop this packet */ + + nlldbg("Bad packet size dropped (%d)\n", pktlen); + NETDEV_RXERRORS(&priv->ld_dev); + + /* The number of bytes and words left to read is pktlen - 4 (including, + * the final, possibly partial word) because we've already read 4 bytes. + */ + + wordlen = (pktlen - 1) >> 2; + + /* Read and discard the remaining words in the FIFO */ + + while (wordlen--) + { + (void)tiva_ethin(priv, TIVA_MAC_DATA_OFFSET); + } + + /* Check for another packet */ + + continue; + } + + /* Save the first two bytes from the first word */ + + *dbuf++ = (uint8_t)((regval >> 16) & 0xff); + *dbuf++ = (uint8_t)((regval >> 24) & 0xff); + + /* Read all of the whole, 32-bit values in the middle of the packet. + * We've already read the length (2 bytes) plus the first two bytes + * of data. + */ + + for (bytesleft = pktlen - 4; bytesleft > 7; bytesleft -= 4, dbuf += 4) + { + /* Transfer a whole word to the user buffer. Note, the user + * buffer may be un-aligned. + */ + + *(uint32_t *)dbuf = tiva_ethin(priv, TIVA_MAC_DATA_OFFSET); + } + + /* Handle the last, partial word in the FIFO (0-3 bytes) and discard + * the 4-byte FCS. + */ + + for (; bytesleft > 0; bytesleft -= 4) + { + /* Read the last word. And transfer all but the last four + * bytes of the FCS into the user buffer. + */ + + regval = tiva_ethin(priv, TIVA_MAC_DATA_OFFSET); + switch (bytesleft) + { + default: + break; + + case 7: + dbuf[2] = (regval >> 16) & 0xff; + case 6: + dbuf[1] = (regval >> 8) & 0xff; + case 5: + dbuf[0] = regval & 0xff; + break; + } + } + + /* Pass the packet length to uIP MINUS 2 bytes for the length and + * 4 bytes for the FCS. + */ + + priv->ld_dev.d_len = pktlen - 6; + tiva_dumppacket("Received packet", priv->ld_dev.d_buf, priv->ld_dev.d_len); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->ld_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (ETHBUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->ld_dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->ld_dev); + ipv4_input(&priv->ld_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->ld_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->ld_dev.d_flags)) +#endif + { + arp_out(&priv->ld_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->ld_dev); + } +#endif + + /* And send the packet */ + + tiva_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (ETHBUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->ld_dev); + + /* Give the IPv6 packet to the network layer */ + + arp_ipin(&priv->ld_dev); + ipv6_input(&priv->ld_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->ld_dev.d_flags)) + { + arp_out(&priv->ld_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->ld_dev); + } +#endif + + /* And send the packet */ + + tiva_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (ETHBUF->type == htons(ETHTYPE_ARP)) + { + nllvdbg("ARP packet received (%02x)\n", ETHBUF->type); + NETDEV_RXARP(&priv->ld_dev); + + arp_arpin(&priv->ld_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->ld_dev.d_len > 0) + { + tiva_transmit(priv); + } + } + else +#endif + { + nlldbg("Unsupported packet type dropped (%02x)\n", htons(ETHBUF->type)); + NETDEV_RXDROPPED(&priv->ld_dev); + } + } +} + +/**************************************************************************** + * Function: tiva_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_txdone(struct tiva_driver_s *priv) +{ + /* Cancel the TX timeout */ + + wd_cancel(priv->ld_txtimeout); + + /* Verify that the Tx FIFO is not in use. The NEWTX bit initiates an + * Ethernet transmission once the packet has been placed in the TX FIFO. + * This bit is cleared once the transmission has been completed. Since + * we get here because of of TXEMP which indicates that the packet was + * transmitted and that the TX FIFO is empty, NEWTX should always be zero + * at this point. + */ + + DEBUGASSERT((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->ld_dev, tiva_txpoll); +} + +/**************************************************************************** + * Function: tiva_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_interrupt(int irq, FAR void *context) +{ + register struct tiva_driver_s *priv; + uint32_t ris; + +#if TIVA_NETHCONTROLLERS > 1 +# error "A mechanism to associate and interface with an IRQ is needed" +#else + priv = &g_lm3sdev[0]; +#endif + + /* Read the raw interrupt status register */ + + ris = tiva_ethin(priv, TIVA_MAC_RIS_OFFSET); + + /* Clear all pending interrupts */ + + tiva_ethout(priv, TIVA_MAC_IACK_OFFSET, ris); + + /* Check for errors */ + +#if defined(CONFIG_NETDEV_STATISTICS) + if ((ris & MAC_RIS_TXER) != 0) + { + /* Tx error */ + + NETDEV_TXERRORS(&priv->ld_dev); + } + + if ((ris & MAC_RIS_FOV) != 0) + { + /* Rx FIFO overrun */ + + NETDEV_RXERRORS(&priv->ld_dev); + } + + if ((ris & MAC_RIS_RXER) != 0) + { + /* Rx error */ + + NETDEV_RXERRORS(&priv->ld_dev); + } +#endif + + /* Handle (unmasked) interrupts according to status bit settings */ + + ris &= tiva_ethin(priv, TIVA_MAC_IM_OFFSET); + + /* Is this an Rx interrupt (meaning that a packet has been received)? */ + + if ((ris & MAC_RIS_RXINT) != 0) + { + /* Handle the incoming packet */ + + tiva_receive(priv); + } + + /* Is this an Tx interrupt (meaning that the Tx FIFO is empty)? */ + + if ((ris & MAC_RIS_TXEMP) != 0) + { + /* Handle the complete of the transmission */ + + tiva_txdone(priv); + } + + /* Enable Ethernet interrupts (perhaps excluding the TX done interrupt if + * there are no pending transmissions). + */ + + return OK; +} + +/**************************************************************************** + * Function: tiva_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_txtimeout(int argc, uint32_t arg, ...) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)arg; + + /* Increment statistics */ + + nlldbg("Tx timeout\n"); + NETDEV_TXTIMEOUTS(&priv->ld_dev); + + /* Then reset the hardware */ + + DEBUGASSERT(priv->ld_bifup); + tiva_ifdown(&priv->ld_dev); + tiva_ifup(&priv->ld_dev); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->ld_dev, tiva_txpoll); +} + +/**************************************************************************** + * Function: tiva_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_polltimer(int argc, uint32_t arg, ...) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)arg; + + /* Check if we can send another Tx packet now. The NEWTX bit initiates an + * Ethernet transmission once the packet has been placed in the TX FIFO. + * This bit is cleared once the transmission has been completed. + * + * NOTE: This can cause missing poll cycles and, hence, some timing + * inaccuracies. + */ + + if ((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0) + { + /* If so, update TCP timing states and poll uIP for new XMIT data */ + + (void)devif_timer(&priv->ld_dev, tiva_txpoll); + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_polltimer, 1, arg); + } +} + +/**************************************************************************** + * Function: tiva_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_ifup(struct net_driver_s *dev) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)dev->d_private; + irqstate_t flags; + uint32_t regval; + uint32_t div; + uint16_t phyreg; + + nlldbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Enable and reset the Ethernet controller */ + + flags = enter_critical_section(); + tiva_ethreset(priv); + + /* Set the management clock divider register for access to the PHY + * register set. The MDC clock is divided down from the system clock per: + * + * MDCCLK_FREQUENCY = SYSCLK_FREQUENCY / (2 * (div + 1)) + * div = (SYSCLK_FREQUENCY / 2 / MDCCLK_FREQUENCY) - 1 + * + * Where the maximum value for MDCCLK_FREQUENCY is 2,500,000. We will + * add 1 to assure the max TIVA_MAX_MDCCLK is not exceeded. + */ + + div = SYSCLK_FREQUENCY / 2 / TIVA_MAX_MDCCLK; + tiva_ethout(priv, TIVA_MAC_MDV_OFFSET, div); + nllvdbg("MDV: %08x\n", div); + + /* Then configure the Ethernet Controller for normal operation + * + * Setup the transmit control register (Full duplex, TX CRC Auto Generation, + * TX Padding Enabled). + */ + + regval = tiva_ethin(priv, TIVA_MAC_TCTL_OFFSET); + regval &= ~TIVA_TCTCL_CLRBITS; + regval |= TIVA_TCTCL_SETBITS; + tiva_ethout(priv, TIVA_MAC_TCTL_OFFSET, regval); + nllvdbg("TCTL: %08x\n", regval); + + /* Setup the receive control register (Disable multicast frames, disable + * promiscuous mode, disable bad CRC rejection). + */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval &= ~TIVA_RCTCL_CLRBITS; + regval |= TIVA_RCTCL_SETBITS; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + nllvdbg("RCTL: %08x\n", regval); + + /* Setup the time stamp configuration register */ + +#ifdef TIVA_ETHTS + regval = tiva_ethin(priv, TIVA_MAC_TS_OFFSET); +#ifdef CONFIG_TIVA_TIMESTAMP + regval |= MAC_TS_EN; +#else + regval &= ~(MAC_TS_EN); +#endif + tiva_ethout(priv, TIVA_MAC_TS_OFFSET, regval); + nllvdbg("TS: %08x\n", regval); +#endif + + /* Wait for the link to come up. This following is not very conservative + * of system resources -- it really should wait gracefully on a semaphore + * and the interrupt handler should post the semaphore when LINKSTATUS is + * set + */ + + nlldbg("Waiting for link\n"); + do + { + phyreg = tiva_phyread(priv, MII_MSR); + } + while ((phyreg & MII_MSR_LINKSTATUS) == 0); + nlldbg("Link established\n"); + + /* Reset the receive FIFO */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval |= MAC_RCTL_RSTFIFO; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Enable the Ethernet receiver */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval |= MAC_RCTL_RXEN; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Enable the Ethernet transmitter */ + + regval = tiva_ethin(priv, TIVA_MAC_TCTL_OFFSET); + regval |= MAC_TCTL_TXEN; + tiva_ethout(priv, TIVA_MAC_TCTL_OFFSET, regval); + + /* Reset the receive FIFO (again) */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval |= MAC_RCTL_RSTFIFO; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Enable the Ethernet interrupt */ + +#if TIVA_NETHCONTROLLERS > 1 + up_enable_irq(priv->irq); +#else + up_enable_irq(TIVA_IRQ_ETHCON); +#endif + + /* Enable the Ethernet RX packet receipt interrupt */ + + regval = tiva_ethin(priv, TIVA_MAC_IM_OFFSET); + regval |= MAC_IM_RXINTM; + tiva_ethout(priv, TIVA_MAC_IM_OFFSET, regval); + + /* Program the hardware with it's MAC address (for filtering) */ + + regval = (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[3] << 24 | + (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[2] << 16 | + (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[1] << 8 | + (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[0]; + tiva_ethout(priv, TIVA_MAC_IA0_OFFSET, regval); + + regval = (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[5] << 8 | + (uint32_t)priv->ld_dev.d_mac.ether_addr_octet[4]; + tiva_ethout(priv, TIVA_MAC_IA1_OFFSET, regval); + + /* Set and activate a timer process */ + + (void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_polltimer, 1, (uint32_t)priv); + + priv->ld_bifup = true; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: tiva_ifdown + * + * Description: + * NuttX Callback: Stop the interface. The only way to restore normal + * behavior is to call tiva_ifup(). + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_ifdown(struct net_driver_s *dev) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)dev->d_private; + irqstate_t flags; + uint32_t regval; + + nlldbg("Taking down: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Cancel the TX poll timer and TX timeout timers */ + + flags = enter_critical_section(); + wd_cancel(priv->ld_txpoll); + wd_cancel(priv->ld_txtimeout); + + /* Disable the Ethernet interrupt */ + +#if TIVA_NETHCONTROLLERS > 1 + up_disable_irq(priv->irq); +#else + up_disable_irq(TIVA_IRQ_ETHCON); +#endif + + /* Disable all Ethernet controller interrupt sources */ + + regval = tiva_ethin(priv, TIVA_MAC_IM_OFFSET); + regval &= ~MAC_IM_ALLINTS; + tiva_ethout(priv, TIVA_MAC_IM_OFFSET, regval); + + /* Reset the receive FIFO */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval |= MAC_RCTL_RSTFIFO; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Disable the Ethernet receiver */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval &= ~MAC_RCTL_RXEN; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Disable the Ethernet transmitter */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval &= ~MAC_TCTL_TXEN; + tiva_ethout(priv, TIVA_MAC_TCTL_OFFSET, regval); + + /* Reset the receive FIFO (again) */ + + regval = tiva_ethin(priv, TIVA_MAC_RCTL_OFFSET); + regval |= MAC_RCTL_RSTFIFO; + tiva_ethout(priv, TIVA_MAC_RCTL_OFFSET, regval); + + /* Clear any pending interrupts */ + + regval = tiva_ethin(priv, TIVA_MAC_RIS_OFFSET); + tiva_ethout(priv, TIVA_MAC_IACK_OFFSET, regval); + + /* The interface is now DOWN */ + + priv->ld_bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: tiva_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int tiva_txavail(struct net_driver_s *dev) +{ + struct tiva_driver_s *priv = (struct tiva_driver_s *)dev->d_private; + irqstate_t flags; + + /* Ignore the notification if the interface is not yet up or if the Tx FIFO + * hardware is not available at this time. The NEWTX bit initiates an + * Ethernet transmission once the packet has been placed in the TX FIFO. + * This bit is cleared once the transmission has been completed. When the + * transmission completes, tiva_txdone() will be called and the Tx polling + * will occur at that time. + */ + + flags = enter_critical_section(); + if (priv->ld_bifup && (tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0) + { + /* If the interface is up and we can use the Tx FIFO, then poll uIP + * for new Tx data + */ + + (void)devif_poll(&priv->ld_dev, tiva_txpoll); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: tiva_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct tiva_driver_s *priv = (FAR struct tiva_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Multicast MAC support not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Function: tiva_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct tiva_driver_s *priv = (FAR struct tiva_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Multicast MAC support not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: tiva_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS > 1 +int tiva_ethinitialize(int intf) +#else +static inline int tiva_ethinitialize(int intf) +#endif +{ + struct tiva_driver_s *priv = &g_lm3sdev[intf]; + int ret; + + /* Check if the Ethernet module is present */ + + ndbg("Setting up eth%d\n", intf); + +#if TIVA_NETHCONTROLLERS > 1 +# error "This debug check only works with one interface" +#else + DEBUGASSERT((getreg32(TIVA_SYSCON_DC4) & (SYSCON_DC4_EMAC0 | SYSCON_DC4_EPHY0)) == + (SYSCON_DC4_EMAC0 | SYSCON_DC4_EPHY0)); +#endif + DEBUGASSERT((unsigned)intf < TIVA_NETHCONTROLLERS); + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct tiva_driver_s)); + priv->ld_dev.d_ifup = tiva_ifup; /* I/F down callback */ + priv->ld_dev.d_ifdown = tiva_ifdown; /* I/F up (new IP address) callback */ + priv->ld_dev.d_txavail = tiva_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->ld_dev.d_addmac = tiva_addmac; /* Add multicast MAC address */ + priv->ld_dev.d_rmmac = tiva_rmmac; /* Remove multicast MAC address */ +#endif + priv->ld_dev.d_private = (void *)priv; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + +#if TIVA_NETHCONTROLLERS > 1 +# error "A mechanism to associate base address an IRQ with an interface is needed" + priv->ld_base = ??; /* Ethernet controller base address */ + priv->ld_irq = ??; /* Ethernet controller IRQ number */ +#endif + priv->ld_txpoll = wd_create(); /* Create periodic poll timer */ + priv->ld_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* If the board can provide us with a MAC address, get the address + * from the board now. The MAC will not be applied until tiva_ifup() + * is called (and the MAC can be overwritten with a netdev ioctl call). + */ + +#ifdef CONFIG_TIVA_BOARDMAC + tiva_ethernetmac(&priv->ld_dev.d_mac); +#endif + + /* Perform minimal, one-time initialization -- just reset the controller and + * leave it disabled. The Ethernet controller will be reset and properly + * re-initialized each time tiva_ifup() is called. + */ + + tiva_ethreset(priv); + tiva_ifdown(&priv->ld_dev); + + /* Attach the IRQ to the driver */ + +#if TIVA_NETHCONTROLLERS > 1 + ret = irq_attach(priv->irq, tiva_interrupt); +#else + ret = irq_attach(TIVA_IRQ_ETHCON, tiva_interrupt); +#endif + if (ret != 0) + { + /* We could not attach the ISR to the IRQ */ + + return -EAGAIN; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->ld_dev, NET_LL_ETHERNET); + return OK; +} + + +/************************************************************************************ + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one interface + * in the chip, then board-specific logic will have to provide this function to + * determine which, if any, Ethernet controllers should be initialized. + * + ************************************************************************************/ + +#if TIVA_NETHCONTROLLERS == 1 +void up_netinitialize(void) +{ + (void)tiva_ethinitialize(0); +} +#endif + +#endif /* CONFIG_NET && CONFIG_TIVA_ETHERNET */ diff --git a/arch/arm/src/tiva/tiva_adc.h b/arch/arm/src/tiva/tiva_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..c6fc9ac2e07012c6f868e77144e1ea4230d9ee3b --- /dev/null +++ b/arch/arm/src/tiva/tiva_adc.h @@ -0,0 +1,693 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_adc.h + * + * Copyright (C) 2015 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_ADC_H +#define __ARCH_ARM_SRC_TIVA_TIVA_ADC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "chip.h" + +#ifdef CONFIG_TIVA_ADC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_TIVA_ADC_REGDEBUG +#endif + +/* ADC Configuration values */ + +#ifdef CONFIG_ARCH_CHIP_TM4C123 +# define TIVA_ADC_CLOCK_MAX (16000000) +# define TIVA_ADC_CLOCK_MIN (16000000) +#elif defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_ADC_CLOCK_MAX (32000000) +# define TIVA_ADC_CLOCK_MIN (16000000) +#else +# error TIVA_tiva_adc_clock: unsupported architecture +#endif + +/* Allow the same function call to be used for sample rate */ + +#ifdef CONFIG_ARCH_CHIP_TM4C123 +# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_SR_125K) +# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_SR_250K) +# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_SR_500K) +# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_SR_1M) +#elif defined(CONFIG_ARCH_CHIP_TM4C129) +# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_MCR_1_8) +# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_MCR_1_4) +# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_MCR_1_2) +# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_MCR_FULL) +#else +# error TIVA_ADC_SAMPLE_RATE: unsupported architecture +#endif + +/* Sample Sequencer triggers */ + +#define TIVA_ADC_TRIG_SW (ADC_EMUX_PROC) /* Processor (default) */ +#define TIVA_ADC_TRIG_EXTERNAL (ADC_EMUX_EXTERNAL) /* External (GPIO Pins) */ +#define TIVA_ADC_TRIG_TIMER (ADC_EMUX_TIMER) /* Timer */ +#define TIVA_ADC_TRIG_PWM0 (ADC_EMUX_PWM0) /* PWM generator 0 */ +#define TIVA_ADC_TRIG_PWM1 (ADC_EMUX_PWM1) /* PWM generator 1 */ +#define TIVA_ADC_TRIG_PWM2 (ADC_EMUX_PWM2) /* PWM generator 2 */ +#define TIVA_ADC_TRIG_PWM3 (ADC_EMUX_PWM3) /* PWM generator 3 */ +#define TIVA_ADC_TRIG_NEVER (ADC_EMUX_NEVER) /* Never Trigger */ +#define TIVA_ADC_TRIG_ALWAYS (ADC_EMUX_ALWAYS) /* Always (continuously sample) */ + +/* Step configuration */ + +#define TIVA_ADC_FLAG_TS (ADC_SSCTL_TS) /* Sample Temp Sensor Select */ +#define TIVA_ADC_FLAG_IE (ADC_SSCTL_IE) /* Sample Interrupt Enable */ +#define TIVA_ADC_FLAG_END (ADC_SSCTL_END) /* Sample is End of Sequence */ + +#define TIVA_ADC_PWM_TRIG_IOCTL _ANIOC(0x00F0) + +/* PWM trigger ioctl support ***********************************************/ + +#define TIVA_ADC_PWM_TRIG(sse, pwm, mod) \ + ((((mod) << 4) << ((pwm) * 8)) + (sse)) + +/* Misc utility *************************************************************/ + +#define ADC_PER_CHIP 2 +#define SSE_PER_ADC 4 +#define SSE_IDX(a,s) (((a)*SSE_PER_ADC) + (s)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Step configuration options */ + +struct tiva_adc_step_cfg_s +{ + uint8_t adc; /* Parent peripheral */ + uint8_t sse; /* Parent sample sequencer (SSE) */ + uint8_t step; /* Which step in the sequencer */ + uint8_t shold; /* Sample and hold time */ + uint8_t flags; /* Last step? Interrupt enabled? + * Internal temperature sensor? */ + uint8_t ain; /* Which analog input */ +}; + +/* Sample Sequencer configuration options */ + +struct tiva_adc_sse_cfg_s +{ + uint8_t priority; /* Conversion priority, 0-3 no duplicates */ + uint8_t trigger; /* Trigger source */ +}; + +/* ADC peripheral configuration options */ + +struct tiva_adc_cfg_s +{ + uint8_t adc; /* ADC peripheral number */ + bool sse[4]; /* active SSEs in a bitmask */ + struct tiva_adc_sse_cfg_s ssecfg[4]; /* SSE configuration */ + uint8_t steps; /* Size of the stepcfg array */ + struct tiva_adc_step_cfg_s *stepcfg; /* Step configuration array */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Only allow access to upper level ADC drivers if they are enabled */ +#ifdef CONFIG_ADC + +/**************************************************************************** + * Driver Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_adc_initialize + * + * Description: + * Configuration and bind the ADC to the ADC lower half instance and + * register the ADC driver at 'devpath'. + * + * Input Parameters: + * devpath - The full path to the ADC device. This should be of the + * form /dev/adc0 + * cfg - ADC configuration structure, configures the whole ADC. + * clock - clock speed for all ADC's. This is only set once for the first + * call to tiva_adc_initialize, otherwise the values are ignored. + * sample_rate - maximum sample rate of any ADC. This is only set once + * for the first call to tiva_adc_initialize, otherwise the values are + * ignored. + * + ****************************************************************************/ + +int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg, + uint32_t clock, uint8_t sample_rate); + +/**************************************************************************** + * Interfaces exported from the ADC driver + ****************************************************************************/ + +struct tiva_adc_s; + +/**************************************************************************** + * Name: tiva_adc_lock + * + * Description: + * Get exclusive access to the ADC interface + * + ****************************************************************************/ + +void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse); + +/**************************************************************************** + * Name: tiva_adc_unlock + * + * Description: + * Relinquish the lock on the ADC interface + * + ****************************************************************************/ + +void tiva_adc_unlock(FAR struct tiva_adc_s *priv, int sse); + +#endif /* CONFIG_ADC */ + +/**************************************************************************** + * Library Function Prototypes + ****************************************************************************/ + +/* Initialization routines **************************************************/ + +/**************************************************************************** + * Name: tiva_adc_one_time_init + * + * Description: + * Perform one-time initialization of global ADC settings; clock frequency + * and sampling rate. + * + * Assumptions/Limitations: + * Peripheral must be powered before one-time initialization. + * + ****************************************************************************/ + +void tiva_adc_one_time_init(uint32_t clock, uint8_t sample_rate); + +/**************************************************************************** + * Name: tiva_adc_configure + * + * Description: + * Performs configuration of a single ADC, it's valid sample sequencers and + * available steps. + * + ****************************************************************************/ + +void tiva_adc_configure(struct tiva_adc_cfg_s *cfg); + +/**************************************************************************** + * Name: tiva_adc_sse_cfg + * + * Description: + * Configure the sample sequencer. + * + ****************************************************************************/ + +void tiva_adc_sse_cfg(uint8_t adc, uint8_t sse, + struct tiva_adc_sse_cfg_s *ssecfg); + +/**************************************************************************** + * Name: tiva_adc_step_cfg + * + * Description: + * Configures a sample sequencer step. + * + ****************************************************************************/ + +void tiva_adc_step_cfg(struct tiva_adc_step_cfg_s *stepcfg); + +/**************************************************************************** + * Name: tiva_adc_get_trigger + * + * Description: + * For a given adc, sse and step, get the AIN (channel) associated. + * + ****************************************************************************/ + +uint8_t tiva_adc_get_trigger(uint8_t adc, uint8_t sse); + +/**************************************************************************** + * Name: tiva_adc_get_ain + * + * Description: + * For a given adc, sse and step, get the AIN (channel) associated. + * + ****************************************************************************/ + +uint8_t tiva_adc_get_ain(uint8_t adc, uint8_t sse, uint8_t step); + +/* IRQS *********************************************************************/ + +/**************************************************************************** + * Name: tiva_adc_irq_attach + * + * Description: + * Attach a custom interrupt handler. + * + ****************************************************************************/ + +void tiva_adc_irq_attach(uint8_t adc, uint8_t sse, xcpt_t isr); + +/**************************************************************************** + * Name: tiva_adc_irq_detach + * + * Description: + * detach an interrupt handler. + * + ****************************************************************************/ + +void tiva_adc_irq_detach(uint8_t adc, uint8_t sse); + +/**************************************************************************** + * Name: tiva_adc_getirq + * + * Description: + * Maps ADC and SSE value to the correct IRQ value. + * + ****************************************************************************/ + +int tiva_adc_getirq(uint8_t adc, uint8_t sse); + +/* Common peripheral level **************************************************/ + +/**************************************************************************** + * Name: tiva_adc_enable + * + * Description: + * Toggles the operational state of the ADC peripheral + * + * Input Parameters: + * state - operation state + * + ****************************************************************************/ + +int tiva_adc_enable(uint8_t adc, bool state); + +/**************************************************************************** + * Name: tiva_adc_clock + * + * Description: + * Sets the ADC peripherals clock to the desired frequency. + * + * Input Parameters: + * freq - ADC clock value; dependent on platform: + * + * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation, + * however the PIOSC allows the ADC to operate in deep sleep mode. + * + * TM4C129 - For the 129, there is still a selection between various internal + * clocks, however the output frequency is variable (16 MHz - 32 MHz); so it + * is much more intuitive to allow the clock variable be a frequency value. + * + ****************************************************************************/ + +void tiva_adc_clock(uint32_t freq); + +/**************************************************************************** + * Name: tiva_adc_vref + * + * Description: + * Sets the ADC peripherals clock to the desired frequency. + * + * Input Parameters: + * vref - ADC clock voltage reference source + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_TM4C129 +void tiva_adc_vref(uint8_t vref); +#endif + +/* Peripheral (base) level **************************************************/ + +/**************************************************************************** + * Name: tiva_adc_sample_rate + * + * Description: + * Sets the ADC sample rate as follows for each processor. + * TM4C123 - by maximum samples: 125 ksps, 250 ksps, 500 ksps or 1 Msps + * TM4C129 - by a divisor either being full, half, quarter or + * an eighth. + * + * Input Parameters: + * rate - ADC sample rate divisor + * + ****************************************************************************/ + +void tiva_adc_sample_rate(uint8_t rate); + +/**************************************************************************** + * Name: tiva_adc_proc_trig + * + * Description: + * Triggers the sample sequence to start it's conversion(s) and store them + * to the FIFO. This is only required when the trigger source is set to the + * processor. + * + * Input parameters: + * adc - which ADC peripherals' sample sequencers to trigger + * sse_mask - sample sequencer bitmask, each sse is 1 shifted by the sse + * number. e.g. + * SSE0 = 1 << 0 + * SSE1 = 1 << 1 + * SSE2 = 1 << 2 + * SSE3 = 1 << 3 + * + ****************************************************************************/ + +void tiva_adc_proc_trig(uint8_t adc, uint8_t sse_mask); + +/**************************************************************************** + * Name: tiva_adc_int_status + * + * Description: + * Returns raw interrupt status for the input ADC + * + * Input parameters: + * adc - which ADC peripherals' interrupt status to retrieve + * + ****************************************************************************/ + +uint32_t tiva_adc_int_status(uint8_t adc); + +/* Sample Sequencer (SSE) level *********************************************/ + +/**************************************************************************** + * Name: tiva_adc_sse_enable + * + * Description: + * Sets the operation state of an ADC's sample sequencer (SSE). SSEs must + * be configured before being enabled. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer enable/disable state + * + * Return value: + * Actual state of the ACTSS register. + * + ****************************************************************************/ + +uint8_t tiva_adc_sse_enable(uint8_t adc, uint8_t sse, bool state); + +/**************************************************************************** + * Name: tiva_adc_sse_trigger + * + * Description: + * Sets the trigger configuration for an ADC's sample sequencer (SSE). + * Possible triggers are the following: + * - Processor + * - PWMs, requires that one of the PWMnn_TRIG_CFG defines be OR'd + * into the trigger value. + * - Timers + * - GPIO (which GPIO is platform specific, consult the datasheet) + * - Always + * - !!UNSUPPORTED: Comparators + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * trigger - interrupt trigger + * + ****************************************************************************/ + +void tiva_adc_sse_trigger(uint8_t adc, uint8_t sse, uint32_t trigger); + +/**************************************************************************** + * Name: tiva_adc_sse_pwm_trig + * + * Description: + * Additional triggering configuration for PWM. Sets which PWM and which + * generator. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * cfg - which PWM modulator and generator to use, use TIVA_ADC_PWM_TRIG + * to encode the value correctly + * + ****************************************************************************/ + +#ifdef CONFIG_EXPERIMENTAL +void tiva_adc_sse_pwm_trig(uint8_t adc, uint8_t sse, uint32_t cfg); +#endif + +/**************************************************************************** + * Name: tiva_adc_sse_int_enable + * + * Description: + * Sets the interrupt state of an ADC's sample sequencer (SSE). SSEs must + * be enabled before setting interrupt state. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer enable/disable interrupt state + * + ****************************************************************************/ + +void tiva_adc_sse_int_enable(uint8_t adc, uint8_t sse, bool state); + +/**************************************************************************** + * Name: tiva_adc_sse_int_status + * + * Description: + * Returns interrupt status for the specificed SSE + * + * Input parameters: + * adc - which ADC peripherals' interrupt status to retrieve + * sse - which SSE interrupt status to retrieve + * + ****************************************************************************/ + +bool tiva_adc_sse_int_status(uint8_t adc, uint8_t sse); + +/**************************************************************************** + * Name: tiva_adc_sse_clear_int + * + * Description: + * Clears the interrupt bit for the SSE. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer + * + ****************************************************************************/ + +void tiva_adc_sse_clear_int(uint8_t adc, uint8_t sse); + +/**************************************************************************** + * Name: tiva_adc_sse_data + * + * Description: + * Retrieves data from the FIFOs for all steps in the given sample sequencer. + * The input data buffer MUST be as large or larger than the sample sequencer. + * otherwise + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * + * Return value: + * number of steps read from FIFO. + * + ****************************************************************************/ + +uint8_t tiva_adc_sse_data(uint8_t adc, uint8_t sse, int32_t *buf); + +/**************************************************************************** + * Name: tiva_adc_sse_priority + * + * Description: + * Sets the priority configuration for an ADC's sample sequencer (SSE). The + * priority value ranges from 0 to 3, 0 being the highest priority, 3 being + * the lowest. There can be no duplicate values. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * priority - conversion priority + * + ****************************************************************************/ + +void tiva_adc_sse_priority(uint8_t adc, uint8_t sse, uint8_t priority); + +/**************************************************************************** + * Name: tiva_adc_sse_register_chn + * + * Description: + * Registers an input channel to an SSE. Channels are registered according + * to the step and channel values stored in the channel struct. If the SSE + * already has a channel registered, it is overwritten by the new channel. + * + * *SSEMUX only supported on TM4C129 devices + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer step + * ain - analog input pin + * + ****************************************************************************/ + +void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t ain); + +/**************************************************************************** + * Name: tiva_adc_sse_differential + * + * Description: + * Sets the differential capability for a SSE. !! UNSUPPORTED + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * diff - differential configuration + * + ****************************************************************************/ + +void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t diff); + +/**************************************************************************** + * Name: tiva_adc_sse_sample_hold_time + * + * Description: + * Set the sample and hold time for this step. + * + * This is not available on all devices, however on devices that do not + * support this feature these reserved bits are ignored on write access. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * shold - sample and hold time + * + ****************************************************************************/ + +#ifdef CONFIG_EXPERIMENTAL +void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t shold); +#endif + +/**************************************************************************** + * Name: tiva_adc_sse_step_cfg + * + * Description: + * Configures the given SSE step to one of the following options: + * -Temperature sensor select: this step is muxed to the internal + * temperature sensor. + * -Interrupt enabled select: this step causes the interrupt bit to + * be set and, if the MASK0 bit in ADC_IM register is set, the + * interrupt is promoted to the interrupt controller. + * -Sequence end select: This step is the last sequence to be sampled. + * This MUST be set somewhere in the SSE. + * -*Comparator/Differential select: The analog input is differentially + * sampled. The corresponding ADCSSMUXn nibble must be set to the pair + * number "i", where the paired inputs are "2i and 2i+1". Because the + * temperature sensor does not have a differential option, this bit must + * not be set when the TS3 bit is set. + * + * *Comparator/Differential functionality is unsupported and ignored. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * cfg - step configuration + * + ****************************************************************************/ + +void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn, uint8_t cfg); + +/**************************************************************************** + * Name: tiva_adc_dump_reg_cfg + * + * Description: + * Dump all configured registers for the given ADC and SSE. This should + * only be used to verify that configuration routines were accurate. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_ANALOG +void tiva_adc_dump_reg_cfg(uint8_t adc, uint8_t sse); +#endif + +# undef EXTERN +# ifdef __cplusplus +} +# endif +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_TIVA_ADC */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_ADC_H */ diff --git a/arch/arm/src/tiva/tiva_adclib.c b/arch/arm/src/tiva/tiva_adclib.c new file mode 100644 index 0000000000000000000000000000000000000000..64fb93552d25b409a0af644faef10427edcd6489 --- /dev/null +++ b/arch/arm/src/tiva/tiva_adclib.c @@ -0,0 +1,1106 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_adclib.c + * + * Copyright (C) 2015 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * References: + * + * TM4C123GH6PM Series Data Sheet + * TI Tivaware driverlib ADC sample code. + * + * The Tivaware sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved. + * Software License Agreement + * + * 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 Texas Instruments Incorporated 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 THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library. + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "tiva_gpio.h" +#include "tiva_adc.h" +#include "chip/tiva_adc.h" +#include "chip/tiva_pinmap.h" + +#if defined (CONFIG_TIVA_ADC0) || defined (CONFIG_TIVA_ADC1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CLOCK_CONFIG(div, src) \ + (((((div) << ADC_CC_CLKDIV_SHIFT) & ADC_CC_CLKDIV_MASK) | \ + ((src) & ADC_CC_CS_MASK)) & (ADC_CC_CLKDIV_MASK + ADC_CC_CS_MASK)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t sse2irq[] = +{ +#ifdef CONFIG_TIVA_ADC0 + TIVA_IRQ_ADC0, TIVA_IRQ_ADC1, TIVA_IRQ_ADC2, TIVA_IRQ_ADC3 +#endif +#ifdef CONFIG_TIVA_ADC1 + , TIVA_IRQ_ADC1_0, TIVA_IRQ_ADC1_1, TIVA_IRQ_ADC1_2, TIVA_IRQ_ADC1_3 +#endif +}; + +static uint32_t ain2gpio[] = +{ +#ifdef GPIO_ADC_AIN0 + GPIO_ADC_AIN0 +#endif +#ifdef GPIO_ADC_AIN1 + , GPIO_ADC_AIN1 +#endif +#ifdef GPIO_ADC_AIN2 + , GPIO_ADC_AIN2 +#endif +#ifdef GPIO_ADC_AIN3 + , GPIO_ADC_AIN3 +#endif +#ifdef GPIO_ADC_AIN4 + , GPIO_ADC_AIN4 +#endif +#ifdef GPIO_ADC_AIN5 + , GPIO_ADC_AIN5 +#endif +#ifdef GPIO_ADC_AIN6 + , GPIO_ADC_AIN6 +#endif +#ifdef GPIO_ADC_AIN7 + , GPIO_ADC_AIN7 +#endif +#ifdef GPIO_ADC_AIN8 + , GPIO_ADC_AIN8 +#endif +#ifdef GPIO_ADC_AIN9 + , GPIO_ADC_AIN9 +#endif +#ifdef GPIO_ADC_AIN10 + , GPIO_ADC_AIN10 +#endif +#ifdef GPIO_ADC_AIN11 + , GPIO_ADC_AIN11 +#endif +#ifdef GPIO_ADC_AIN12 + , GPIO_ADC_AIN12 +#endif +#ifdef GPIO_ADC_AIN13 + , GPIO_ADC_AIN13 +#endif +#ifdef GPIO_ADC_AIN14 + , GPIO_ADC_AIN14 +#endif +#ifdef GPIO_ADC_AIN15 + , GPIO_ADC_AIN15 +#endif +#ifdef GPIO_ADC_AIN16 + , GPIO_ADC_AIN16 +#endif +#ifdef GPIO_ADC_AIN17 + , GPIO_ADC_AIN17 +#endif +#ifdef GPIO_ADC_AIN18 + , GPIO_ADC_AIN18 +#endif +#ifdef GPIO_ADC_AIN19 + , GPIO_ADC_AIN19 +#endif +#ifdef GPIO_ADC_AIN20 + , GPIO_ADC_AIN20 +#endif +#ifdef GPIO_ADC_AIN21 + , GPIO_ADC_AIN21 +#endif +#ifdef GPIO_ADC_AIN22 + , GPIO_ADC_AIN22 +#endif +#ifdef GPIO_ADC_AIN23 + , GPIO_ADC_AIN23 +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_adc_one_time_init + * + * Description: + * Perform one-time initialization of global ADC settings; clock frequency + * and sampling rate. + * + * Assumptions/Limitations: + * Peripheral must be powered before one-time initialization. + * + ****************************************************************************/ + +void tiva_adc_one_time_init(uint32_t clock, uint8_t sample_rate) +{ + static bool one_time_init = false; + +#ifdef CONFIG_DEBUG_ANALOG + avdbg("setting clock=%d MHz sample rate=%d\n", + clock, sample_rate); +#endif + + /* Have the common peripheral properties already been initialized? If yes, + * continue. + */ + + if (one_time_init == false) + { + avdbg("performing ADC one-time initialization...\n"); + /* set clock */ + + tiva_adc_clock(clock); + + /* set sampling rate */ + + tiva_adc_sample_rate(sample_rate); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* voltage reference */ + + tiva_adc_vref(); +#endif + one_time_init = true; + } +#ifdef CONFIG_DEBUG_ANALOG + else + { + avdbg("one time initialization previously completed\n"); + } +#endif +} + +/**************************************************************************** + * Name: tiva_adc_configure + * + * Description: + * Performs configuration of a single ADC, it's valid sample sequencers and + * available steps. + * + ****************************************************************************/ + +void tiva_adc_configure(struct tiva_adc_cfg_s *cfg) +{ + uint8_t s; + uint8_t c; + + avdbg("configure ADC%d...\n", cfg->adc); + + /* Configure each SSE */ + + for (s = 0; s < 4; ++s) + { + if (cfg->sse[s]) + { + tiva_adc_sse_cfg(cfg->adc, s, &cfg->ssecfg[s]); + } +#ifdef CONFIG_DEBUG_ANALOG + else + { + avdbg("ADC%d SSE%d has no configuration\n", cfg->adc, s); + } +#endif + } + + /* Configure each step */ + + for (c = 0; c < cfg->steps; ++c) + { + tiva_adc_step_cfg(&cfg->stepcfg[c]); + } + +#ifdef CONFIG_DEBUG_ANALOG + tiva_adc_dump_reg_cfg(cfg->adc, 0); +#endif +} + +/**************************************************************************** + * Name: tiva_adc_sse_cfg + * + * Description: + * Configure the sample sequencer. + * + ****************************************************************************/ + +void tiva_adc_sse_cfg(uint8_t adc, uint8_t sse, + struct tiva_adc_sse_cfg_s *ssecfg) +{ + avdbg("configure ADC%d SSE%d...\n", adc, sse); +#ifdef CONFIG_DEBUG_ANALOG + avdbg("priority=%d trigger=%d...\n", ssecfg->priority, ssecfg->trigger); +#endif + + uint8_t priority = ssecfg->priority; + uint8_t trigger = ssecfg->trigger; + + /* Ensure SSE is disabled before configuring */ + + tiva_adc_sse_enable(adc, sse, false); + + /* Set conversion priority and trigger source for all steps in the SSE */ + + tiva_adc_sse_priority(adc, sse, priority); + tiva_adc_sse_trigger(adc, sse, trigger); +} + +/**************************************************************************** + * Name: tiva_adc_step_cfg + * + * Description: + * Configures a sample sequencer step. + * + ****************************************************************************/ + +void tiva_adc_step_cfg(struct tiva_adc_step_cfg_s *stepcfg) +{ +#ifdef CONFIG_DEBUG_ANALOG + avdbg(" shold=0x%02x flags=0x%02x ain=%d...\n", + stepcfg->shold, stepcfg->flags, stepcfg->ain); +#endif + + uint8_t adc = stepcfg->adc; + uint8_t sse = stepcfg->sse; + uint8_t step = stepcfg->step; +#ifdef CONFIG_EXPERIMENTAL + uint8_t shold = stepcfg->shold; +#endif + uint8_t flags = stepcfg->flags; + uint8_t ain = stepcfg->ain; + uint32_t gpio = ain2gpio[stepcfg->ain]; + + avdbg("configure ADC%d SSE%d STEP%d...\n", adc, sse, step); + + /* Configure the AIN GPIO for analog input if not flagged to be muxed to + * the internal temperature sensor + */ + + if ((flags & TIVA_ADC_FLAG_TS) != TIVA_ADC_FLAG_TS) + { + tiva_configgpio(gpio); + } + + /* Register, set sample/hold time and configure the step */ + + tiva_adc_sse_register_chn(adc, sse, step, ain); + tiva_adc_sse_differential(adc, sse, step, 0); /* TODO: update when differential + * support is added. */ +#ifdef CONFIG_EXPERIMENTAL + tiva_adc_sse_sample_hold_time(adc, sse, step, shold); +#endif + tiva_adc_sse_step_cfg(adc, sse, step, flags); +} + +/**************************************************************************** + * Name: tiva_adc_get_trigger + * + * Description: + * For a given adc, sse and step, get the AIN (channel) associated. + * + ****************************************************************************/ + +uint8_t tiva_adc_get_trigger(uint8_t adc, uint8_t sse) +{ + uintptr_t emuxaddr = TIVA_ADC_EMUX(adc); + uint32_t emux = getreg32(emuxaddr) & ADC_EMUX_MASK(sse); + return (emux >> ADC_EMUX_SHIFT(sse)); +} + +/**************************************************************************** + * Name: tiva_adc_get_ain + * + * Description: + * For a given adc, sse and step, get the AIN (channel) associated. + * + ****************************************************************************/ + +uint8_t tiva_adc_get_ain(uint8_t adc, uint8_t sse, uint8_t step) +{ + uintptr_t ssmuxaddr = TIVA_ADC_BASE(adc)+TIVA_ADC_SSMUX(sse); + uint32_t ssmux = getreg32(ssmuxaddr) & ADC_SSMUX_MUX_MASK(step); + return (ssmux >> ADC_SSMUX_MUX_SHIFT(step)); +} + +/* IRQS *********************************************************************/ + +/**************************************************************************** + * Name: tiva_adc_irq_attach + * + * Description: + * Attach a custom interrupt handler. + * + ****************************************************************************/ + +void tiva_adc_irq_attach(uint8_t adc, uint8_t sse, xcpt_t isr) +{ + + uint32_t ret = 0; + int irq = sse2irq[SSE_IDX(adc, sse)]; + +#ifdef CONFIG_DEBUG_ANALOG + avdbg("assigning ISR=0x%p to ADC%d SSE%d IRQ=0x%02x...\n", + isr, adc, sse, irq); +#endif + + ret = irq_attach(irq, isr); + if (ret < 0) + { + adbg("ERROR: Failed to attach IRQ %d: %d\n", irq, ret); + return; + } + + up_enable_irq(irq); +} + +/**************************************************************************** + * Name: tiva_adc_irq_detach + * + * Description: + * detach an interrupt handler. + * + ****************************************************************************/ + +void tiva_adc_irq_detach(uint8_t adc, uint8_t sse) +{ + uint32_t ret = 0; + int irq = sse2irq[SSE_IDX(adc, sse)]; + + /* Disable ADC interrupts at the level of the AIC */ + + up_disable_irq(irq); + + /* Then detach the ADC interrupt handler. */ + + ret = irq_detach(irq); + if (ret < 0) + { + adbg("ERROR: Failed to detach IRQ %d: %d\n", irq, ret); + return; + } +} + +/**************************************************************************** + * Name: tiva_adc_getirq + * + * Description: + * Maps ADC and SSE value to the correct IRQ value. + * + ****************************************************************************/ + +int tiva_adc_getirq(uint8_t adc, uint8_t sse) +{ + return sse2irq[SSE_IDX(adc, sse)]; +} + +/* Peripheral (base) level **************************************************/ + +/**************************************************************************** + * Name: tiva_adc_enable + * + * Description: + * Toggles the operational state of the ADC peripheral + * + * Input Parameters: + * state - operation state + * + ****************************************************************************/ + +int tiva_adc_enable(uint8_t adc, bool state) +{ + if (state == true) + { + /* Enable clocking to the ADC peripheral */ + +#ifdef TIVA_SYSCON_RCGCADC + modifyreg32(TIVA_SYSCON_RCGCADC, 0, 1 << adc); +#else + modifyreg32(TIVA_SYSCON_RCGC0, 0, SYSCON_RCGC0_ADC0); +#endif + return OK; + } + else if (state == false) + { + /* Disable clocking to the ADC peripheral */ + +#ifdef TIVA_SYSCON_RCGCADC + modifyreg32(TIVA_SYSCON_RCGCADC, 1 << adc, 0); +#else + modifyreg32(TIVA_SYSCON_RCGC0, SYSCON_RCGC0_ADC0, 0); +#endif + return OK; + } + + /* ERROR! */ + + return -1; +} + +/**************************************************************************** + * Name: tiva_adc_clock + * + * Description: + * Sets the ADC peripherals clock to the desired frequency. + * + * Input Parameters: + * freq - ADC clock value; dependent on platform: + * + * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation, + * however the PIOSC allows the ADC to operate in deep sleep mode. + * + * TM4C129 - For the 129, there is still a selection between various internal + * clocks, however the output frequency is variable (16 MHz - 32 MHz); so it + * is much more intuitive to allow the clock variable be a frequency value. + * + ****************************************************************************/ + +void tiva_adc_clock(uint32_t freq) +{ +#if defined(CONFIG_ARCH_CHIP_TM4C123) + /* For the TM4C123, the ADC clock source does not affect the frequency, it + * runs at 16 MHz regardless. You end up selecting between the MOSC (default) + * or the PIOSC. The PIOSC allows the ADC to operate even in deep sleep mode. + * Since this is the case, the clock value for the TM4C123 is always 16 MHz + */ + + uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET); + modifyreg32(ccreg, ADC_CC_CS_MASK, (ADC_CC_CS_PIOSC & ADC_CC_CS_MASK)); + +#elif defined (CONFIG_ARCH_CHIP_TM4C129) + /* check clock bounds and specific match cases */ + + uint32_t clk_src = 0; + uint32_t div = 0; + if (freq > TIVA_ADC_CLOCK_MAX) + { + clk_src = ADC_CC_CS_SYSPLL; + div = (BOARD_FVCO_FREQUENCY / TIVA_ADC_CLOCK_MAX); + } + else if (freq < TIVA_ADC_CLOCK_MIN) + { + clk_src = ADC_CC_CS_PIOSC; + div = 1; + } + else if (freq == XTAL_FREQUENCY) + { + clk_src = ADC_CC_CS_MOSC; + div = 1; + } + else + { + clk_src = ADC_CC_CS_SYSPLL; + div = (BOARD_FVCO_FREQUENCY / freq); + } + + uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET); + modifyreg32(ccreg, ADC_CC_CLKDIV_MASK, CLOCK_CONFIG(div, clk_src)); +#else +# error Unsupported architecture reported +#endif +} + +/**************************************************************************** + * Name: tiva_adc_vref + * + * Description: + * Sets the ADC peripherals clock to the desired frequency. + * + * Input Parameters: + * vref - ADC clock voltage reference source + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_TM4C129 +void tiva_adc_vref(uint8_t vref) +{ + uintptr_t ctlreg = (TIVA_ADC0_BASE + TIVA_ADC_CTL_OFFSET); + modifyreg32(ctlreg, ADC_CTL_VREF_MASK, (vref & ADC_CTL_VREF_MASK)); +} +#endif + +/**************************************************************************** + * Name: tiva_adc_sample_rate + * + * Description: + * Sets the ADC sample rate as follows for each processor. + * TM4C123 - by maximum samples: 125 ksps, 250 ksps, 500 ksps or 1 Msps + * TM4C129 - by a divisor either being full, half, quarter or + * an eighth. + * + * Input Parameters: + * rate - ADC sample rate divisor + * + ****************************************************************************/ + +void tiva_adc_sample_rate(uint8_t rate) +{ + uintptr_t pcreg = (TIVA_ADC0_BASE + TIVA_ADC_PC_OFFSET); + + /* NOTE: ADC_PC_SR_MASK is intended for use with the TM4C123, the + * alternative is ADC_PC_MCR_MASK for the TM4C129. However both masks + * mask off the first 4 bits (0xF) so there is no need to distinguish + * between the two. + */ + + modifyreg32(pcreg, ADC_PC_SR_MASK, (rate & ADC_PC_SR_MASK)); +} + +/**************************************************************************** + * Name: tiva_adc_proc_trig + * + * Description: + * Triggers the sample sequence to start it's conversion(s) and store them + * to the FIFO. This is only required when the trigger source is set to the + * processor. + * + * Input parameters: + * adc - which ADC peripherals' sample sequencers to trigger + * sse_mask - sample sequencer bitmask, each sse is 1 shifted by the sse + * number. e.g. + * SSE0 = 1 << 0 + * SSE1 = 1 << 1 + * SSE2 = 1 << 2 + * SSE3 = 1 << 3 + * + ****************************************************************************/ + +void tiva_adc_proc_trig(uint8_t adc, uint8_t sse_mask) +{ + uintptr_t pssireg = TIVA_ADC_PSSI(adc); + putreg32((sse_mask & ADC_PSSI_TRIG_MASK), pssireg); +#ifdef CONFIG_TIVA_ADC_SYNC +# warning CONFIG_TIVA_ADC_SYNC unsupported at this time. +#endif +} + +/**************************************************************************** + * Name: tiva_adc_int_status + * + * Description: + * Returns raw interrupt status for the input ADC + * + * Input parameters: + * adc - which ADC peripherals' interrupt status to retrieve + * + ****************************************************************************/ + +uint32_t tiva_adc_int_status(uint8_t adc) +{ + uint32_t ris = getreg32(TIVA_ADC_RIS(adc)); + return ris; +} + +/* Sample sequencer (SSE) functions *****************************************/ + +/**************************************************************************** + * Name: tiva_adc_sse_enable + * + * Description: + * Sets the operation state of an ADC's sample sequencer (SSE). SSEs must + * be configured before being enabled. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer enable/disable state + * + * Return value: + * Actual state of the ACTSS register. + * + ****************************************************************************/ + +uint8_t tiva_adc_sse_enable(uint8_t adc, uint8_t sse, bool state) +{ + avdbg("ADC%d SSE%d=%01d\n", adc, sse, state); + + uintptr_t actssreg = TIVA_ADC_ACTSS(adc); + if (state == true) + { + modifyreg32(actssreg, 0, (1 << sse)); + } + else + { + modifyreg32(actssreg, (1 << sse), 0); + } + + return (getreg32(actssreg) & 0xF); +} + +/**************************************************************************** + * Name: tiva_adc_sse_trigger + * + * Description: + * Sets the trigger configuration for an ADC's sample sequencer (SSE). + * Possible triggers are the following: + * - Processor + * - PWMs, requires that one of the PWMnn_TRIG_CFG defines be OR'd + * into the trigger value. + * - Timers + * - GPIO (which GPIO is platform specific, consult the datasheet) + * - Always + * - !!UNSUPPORTED: Comparators + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * trigger - interrupt trigger + * + ****************************************************************************/ + +void tiva_adc_sse_trigger(uint8_t adc, uint8_t sse, uint32_t trigger) +{ + uintptr_t emuxreg = (TIVA_ADC_EMUX(adc)); + uint32_t trig = ((trigger << ADC_EMUX_SHIFT(sse)) & ADC_EMUX_MASK(sse)); + modifyreg32(emuxreg, ADC_EMUX_MASK(sse), trig); + + /* NOTE: PWM triggering needs an additional register to be set (ADC_TSSEL) + * A platform specific IOCTL command is provided to configure the triggering. + */ +} + +/**************************************************************************** + * Name: tiva_adc_sse_pwm_trig + * + * Description: + * Additional triggering configuration for PWM. Sets which PWM and which + * generator. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * cfg - which PWM modulator and generator to use, use TIVA_ADC_PWM_TRIG + * to encode the value correctly + * + ****************************************************************************/ + +#ifdef CONFIG_EXPERIMENTAL +void tiva_adc_sse_pwm_trig(uint8_t adc, uint8_t sse, uint32_t cfg) +{ + /* PWM triggering needs an additional register to be set (ADC_TSSEL) */ + + uintptr_t tsselreg = TIVA_ADC_TSSEL(adc); + + modifyreg32(tsselreg, ADC_TSSEL_PS_MASK(see), cfg); +} +#endif + +/**************************************************************************** + * Name: tiva_adc_sse_int_enable + * + * Description: + * Sets the interrupt state of an ADC's sample sequencer (SSE). SSEs must + * be enabled before setting interrupt state. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer enable/disable interrupt state + * + ****************************************************************************/ + +void tiva_adc_sse_int_enable(uint8_t adc, uint8_t sse, bool state) +{ + irqstate_t flags; + uintptr_t imreg = TIVA_ADC_IM(adc); + int irq = tiva_adc_getirq(adc, sse); + + flags = enter_critical_section(); + up_disable_irq(irq); + + tiva_adc_sse_clear_int(adc, sse); + + if (state == true) + { + modifyreg32(imreg, 0, (1 << sse)); + } + else + { + modifyreg32(imreg, (1 << sse), 0); + } + + up_enable_irq(irq); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: tiva_adc_sse_int_status + * + * Description: + * Returns interrupt status for the specificed SSE + * + * Input parameters: + * adc - which ADC peripherals' interrupt status to retrieve + * sse - which SSE interrupt status to retrieve + * + ****************************************************************************/ + +bool tiva_adc_sse_int_status(uint8_t adc, uint8_t sse) +{ + uint32_t intstat = tiva_adc_int_status(adc); + uint32_t sseintstat = intstat & (1 << sse); + return sseintstat > 0 ? true : false; +} + +/**************************************************************************** + * Name: tiva_adc_sse_clear_int + * + * Description: + * Clears the interrupt bit for the SSE. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * state - sample sequencer + * + ****************************************************************************/ + +void tiva_adc_sse_clear_int(uint8_t adc, uint8_t sse) +{ + uintptr_t iscreg = TIVA_ADC_ISC(adc); + modifyreg32(iscreg, 0, (1 << sse)); +} + +/**************************************************************************** + * Name: tiva_adc_sse_data + * + * Description: + * Retrieves data from the FIFOs for all steps in the given sample sequencer. + * The input data buffer MUST be as large or larger than the sample sequencer. + * otherwise + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * + * Return value: + * number of steps read from FIFO. + * + ****************************************************************************/ + +uint8_t tiva_adc_sse_data(uint8_t adc, uint8_t sse, int32_t *buf) +{ + uint32_t ssfstatreg = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFSTAT(sse)); + uint8_t fifo_count = 0; + + /* Read samples from the FIFO until it is empty */ + + while (!(ssfstatreg & ADC_SSFSTAT_EMPTY) && fifo_count < 8) + { + /* Read the FIFO and copy it to the destination */ + + buf[fifo_count] = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFIFO(sse)); + fifo_count++; + + /* refresh fifo status register state */ + + ssfstatreg = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFSTAT(sse)); + } + + avdbg("fifo=%d\n", fifo_count); + + return fifo_count; +} + +/**************************************************************************** + * Name: tiva_adc_sse_priority + * + * Description: + * Sets the priority configuration for an ADC's sample sequencer (SSE). The + * priority value ranges from 0 to 3, 0 being the highest priority, 3 being + * the lowest. There can be no duplicate values. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * priority - conversion priority + * + ****************************************************************************/ + +void tiva_adc_sse_priority(uint8_t adc, uint8_t sse, uint8_t priority) +{ + uintptr_t ssprireg = TIVA_ADC_SSPRI(adc); + uint32_t sspri = 0; + + sspri = (priority << ADC_SSPRI_SHIFT(sse)) & ADC_SSPRI_MASK(sse); + modifyreg32(ssprireg, ADC_SSPRI_MASK(sse), sspri); +} + +/**************************************************************************** + * Name: tiva_adc_sse_register_chn + * + * Description: + * Registers an input channel to an SSE. Channels are registered according + * to the step and channel values stored in the channel struct. If the SSE + * already has a channel registered, it is overwritten by the new channel. + * + * *SSEMUX only supported on TM4C129 devices + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer step + * ain - analog input pin + * + ****************************************************************************/ + +void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn, + uint32_t ain) +{ + /* Configure SSE mux (SSMUX) with step number */ + + uintptr_t ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSMUX(sse)); + uint32_t step = 0; + + step = ((ain << ADC_SSMUX_MUX_SHIFT(chn)) & ADC_SSMUX_MUX_MASK(chn)); + modifyreg32(ssmuxreg, ADC_SSMUX_MUX_MASK(chn), step); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Configure SSE extended mux (SSEMUX) with step number and configuration */ + + ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSEMUX(sse)); + step = ((1 << ADC_SSEMUX_MUX_SHIFT(chn)) & ADC_SSEMUX_MUX_MASK(chn)); + modifyreg32(ssmuxreg, ADC_SSEMUX_MUX_MASK(chn), step); +#endif +} + +/**************************************************************************** + * Name: tiva_adc_sse_differential + * + * Description: + * Sets the differential capability for a SSE. !! UNSUPPORTED + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * diff - differential configuration + * + ****************************************************************************/ + +void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t diff) +{ +#ifdef CONFIG_TIVA_ADC_DIFFERENTIAL +# error CONFIG_TIVA_ADC_DIFFERENTIAL unsupported!! +#else + /* for now, ensure the FIFO is used and differential sampling is disabled */ + + uintptr_t ssopreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSOP(sse)); + uint32_t sdcopcfg = (1 << chn); + modifyreg32(ssopreg, sdcopcfg, 0); +#endif +} + +/**************************************************************************** + * Name: tiva_adc_sse_sample_hold_time + * + * Description: + * Set the sample and hold time for this step. + * + * This is not available on all devices, however on devices that do not + * support this feature these reserved bits are ignored on write access. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * shold - sample and hold time + * + ****************************************************************************/ + +#ifdef CONFIG_EXPERIMENTAL +void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, + uint8_t chn, uint32_t shold) +{ + uintptr_t sstshreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSTSH(sse)); + modifyreg32(sstshreg, ADC_SSTSH_MASK(sse), (shold << ADC_SSTSH_SHIFT(sse))); +} +#endif + +/**************************************************************************** + * Name: tiva_adc_sse_step_cfg + * + * Description: + * Configures the given SSE step to one of the following options: + * -Temperature sensor select: this step is muxed to the internal + * temperature sensor. + * -Interrupt enabled select: this step causes the interrupt bit to + * be set and, if the MASK0 bit in ADC_IM register is set, the + * interrupt is promoted to the interrupt controller. + * -Sequence end select: This step is the last sequence to be sampled. + * This MUST be set somewhere in the SSE. + * -*Comparator/Differential select: The analog input is differentially + * sampled. The corresponding ADCSSMUXn nibble must be set to the pair + * number "i", where the paired inputs are "2i and 2i+1". Because the + * temperature sensor does not have a differential option, this bit must + * not be set when the TS3 bit is set. + * + * *Comparator/Differential functionality is unsupported and ignored. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * chn - sample sequencer channel + * cfg - step configuration + * + ****************************************************************************/ + +void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn, uint8_t cfg) +{ + uintptr_t ssctlreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSCTL(sse)); + uint32_t ctlcfg = cfg << ADC_SSCTL_SHIFT(chn) & ADC_SSCTL_MASK(chn); + modifyreg32(ssctlreg, ADC_SSCTL_MASK(chn), ctlcfg); +} + +/**************************************************************************** + * Name: tiva_adc_dump_reg_cfg + * + * Description: + * Dump all configured registers for the given ADC and SSE. This should + * only be used to verify that configuration routines were accurate. + * + * Input parameters: + * adc - peripheral state + * sse - sample sequencer + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_ANALOG +void tiva_adc_dump_reg_cfg(uint8_t adc, uint8_t sse) +{ + /* one-time initialization */ + + uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET); /* Clock */ + uintptr_t pcreg = (TIVA_ADC0_BASE + TIVA_ADC_PC_OFFSET); /* Sample rate */ + + /* SSE cfg */ + + uintptr_t actssreg = TIVA_ADC_ACTSS(adc); /* SSE enable state */ + uintptr_t ssprireg = TIVA_ADC_SSPRI(adc); /* SSE priority */ + uintptr_t emuxreg = TIVA_ADC_EMUX(adc); /* SSE trigger */ + + /* step cfg */ + + uintptr_t ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSMUX(sse)); /* step registration */ +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uintptr_t ssemuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSEMUX(sse)); /* extended mux registration */ +#endif + uintptr_t ssopreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSOP(sse)); /* differential status */ +#ifdef CONFIG_EXPERIMENTAL + uintptr_t sstshreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSTSH(sse)); /* sample and hold time */ +#endif + uintptr_t ssctlreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSCTL(sse)); /* step configuration */ + + /* Get register contents */ + + uint32_t cc = getreg32(ccreg); + uint32_t pc = getreg32(pcreg); + + /* SSE cfg */ + + uint32_t actss = getreg32(actssreg); + uint32_t sspri = getreg32(ssprireg); + uint32_t emux = getreg32(emuxreg); + + /* step cfg */ + + uint32_t ssmux = getreg32(ssmuxreg); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uint32_t ssemux = getreg32(ssemuxreg); +#endif + uint32_t ssop = getreg32(ssopreg); +#ifdef CONFIG_EXPERIMENTAL + uint32_t sstsh = getreg32(sstshreg); +#endif + uint32_t ssctl = getreg32(ssctlreg); + + /* Dump register contents */ + + avdbg("CC [0x%08x]=0x%08x\n", ccreg, cc); + avdbg("PC [0x%08x]=0x%08x\n", pcreg, pc); + avdbg("ACTSS [0x%08x]=0x%08x\n", actssreg, actss); + avdbg("SSPRI [0x%08x]=0x%08x\n", ssprireg, sspri); + avdbg("EMUX [0x%08x]=0x%08x\n", emuxreg, emux); + avdbg("SSMUX [0x%08x]=0x%08x\n", ssmuxreg, ssmux); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + avdbg("SSEMUX [0x%08x]=0x%08x\n", ssemuxreg, ssemux); +#endif + avdbg("SSOP [0x%08x]=0x%08x\n", ssopreg, ssop); +#ifdef CONFIG_EXPERIMENTAL + avdbg("SSTSH [0x%08x]=0x%08x\n", sstshreg, sstsh); +#endif + avdbg("SSCTL [0x%08x]=0x%08x\n", ssctlreg, ssctl); + +} +#endif /* CONFIG_DEBUG_ANALOG */ +#endif /* CONFIG_TIVA_ADC0 || CONFIG_TIVA_ADC1 */ diff --git a/arch/arm/src/tiva/tiva_adclow.c b/arch/arm/src/tiva/tiva_adclow.c new file mode 100644 index 0000000000000000000000000000000000000000..7b2f8e2d9d08bc3f10519cd8477ea26f267074e6 --- /dev/null +++ b/arch/arm/src/tiva/tiva_adclow.c @@ -0,0 +1,1044 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_adclow.c + * + * Copyright (C) 2015 TRD2 Inc. All rights reserved. + * Author: Calvin Maguranis + * + * References: + * + * TM4C123GH6PM Series Data Sheet + * TI Tivaware driverlib ADC sample code. + * + * The Tivaware sample code has a BSD compatible license that requires this + * copyright notice: + * + * Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved. + * Software License Agreement + * + * 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 Texas Instruments Incorporated 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 THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library. + ****************************************************************************/ + +/* Keep in mind that for every step there should be another entry in the + * CONFIG_ADC_FIFOSIZE value. + * e.g. if there are 12 steps in use; CONFIG_ADC_FIFOSIZE = 12+1 = 13 + * if there are 3 steps in use; CONFIG_ADC_FIFOSIZE = 3+1 = 4 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "tiva_gpio.h" +#include "tiva_adc.h" +#include "chip/tiva_adc.h" +#include "chip/tiva_pinmap.h" +#include "chip/tiva_syscontrol.h" + +#if defined (CONFIG_TIVA_ADC) && defined (CONFIG_ADC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_TIVA_ADC_CLOCK +# define CONFIG_TIVA_ADC_CLOCK TIVA_ADC_CLOCK_MIN +#endif + +#ifdef CONFIG_TIVA_ADC_VREF +# ifndef CONFIG_ARCH_CHIP_TM4C129 +# error Voltage reference selection only supported in TM4C129 parts +# endif +#endif + +#ifdef CONFIG_TIVA_ADC_ALT_CLK +# warning CONFIG_TIVA_ADC_ALT_CLK unsupported. +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#endif +#ifndef CONFIG_SCHED_HPWORK +# error High priority worker threads is required (CONFIG_SCHED_HPWORK) +#endif + +/* PWM trigger support definitions ******************************************/ + +/* Decodes the PWM generator and module from trigger and converts + * to the TSSEL_PS register + */ + +#define ADC_TRIG_PWM_CFG(t) \ + (1 << (ADC_TSSEL_PS_SHIFT(ADC_TRIG_gen(t)))) + +/* ADC support definitions **************************************************/ + +#define SSE_PROC_TRIG(n) (1 << (n)) +#define SEM_PROCESS_PRIVATE 0 +#define SEM_PROCESS_SHARED 1 + +/* DEBUG ********************************************************************/ + +#ifdef CONFIG_DEBUG_ANALOG +#endif + +/**************************************************************************** + * Public Functions + * **************************************************************************/ + +/* Upper level ADC driver ***************************************************/ + +static void tiva_adc_reset(struct adc_dev_s *dev); +static int tiva_adc_setup(struct adc_dev_s *dev); +static void tiva_adc_shutdown(struct adc_dev_s *dev); +static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable); +static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* ADC lower half device operations */ + +static const struct adc_ops_s g_adcops = +{ + .ao_reset = tiva_adc_reset, + .ao_setup = tiva_adc_setup, + .ao_shutdown = tiva_adc_shutdown, + .ao_rxint = tiva_adc_rxint, + .ao_ioctl = tiva_adc_ioctl, +}; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct tiva_adc_s +{ + struct adc_dev_s *dev; + bool cfg; /* Configuration state */ + bool ena; /* Operation state */ + uint8_t devno; /* ADC device number */ +}; + +struct tiva_adc_sse_s +{ + sem_t exclsem; /* Mutual exclusion semaphore */ + struct work_s work; /* Supports the interrupt handling "bottom half" */ + bool cfg; /* Configuration state */ + bool ena; /* Sample sequencer operation state */ + uint8_t adc; /* Parent peripheral */ + uint8_t num; /* SSE number */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void tiva_adc_interrupt(struct tiva_adc_sse_s *sse); +#ifdef CONFIG_DEBUG_ANALOG +static void tiva_adc_runtimeobj_ptrs(void); +static void tiva_adc_runtimeobj_vals(void); +static void tiva_adc_dump_dev(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Run-time ADC objects */ + +#ifdef CONFIG_TIVA_ADC0 +static struct adc_dev_s dev0; +static struct tiva_adc_s adc0; + +static struct tiva_adc_sse_s sse00; +static struct tiva_adc_sse_s sse01; +static struct tiva_adc_sse_s sse02; +static struct tiva_adc_sse_s sse03; +#endif + +#ifdef CONFIG_TIVA_ADC1 +static struct adc_dev_s dev1; +static struct tiva_adc_s adc1; + +static struct tiva_adc_sse_s sse10; +static struct tiva_adc_sse_s sse11; +static struct tiva_adc_sse_s sse12; +static struct tiva_adc_sse_s sse13; +#endif + +/* Offer run-time ADC objects in array form to help reduce the reliance on + * hard-coded, non-generic function calls. + */ + +static struct adc_dev_s *g_devs[] = +{ +#ifdef CONFIG_TIVA_ADC0 + &dev0, +#else + NULL, +#endif +#ifdef CONFIG_TIVA_ADC1 + &dev1 +#else + NULL +#endif +}; + +static struct tiva_adc_s *g_adcs[] = +{ +#ifdef CONFIG_TIVA_ADC0 + &adc0, +#else + NULL, +#endif +#ifdef CONFIG_TIVA_ADC1 + &adc1 +#else + NULL +#endif +}; + +static struct tiva_adc_sse_s *g_sses[] = +{ +#ifdef CONFIG_TIVA_ADC0 + &sse00, &sse01, &sse02, &sse03, +#else + NULL, NULL, NULL, NULL, +#endif +#ifdef CONFIG_TIVA_ADC1 + &sse10, &sse11, &sse12, &sse13 +#else + NULL, NULL, NULL, NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Interrupt handlers are inevitably hard-coded and specific */ + +#ifdef CONFIG_TIVA_ADC0 +static int tiva_adc0_sse0_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse00); + return OK; +} + +static int tiva_adc0_sse1_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse01); + return OK; +} + +static int tiva_adc0_sse2_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse02); + return OK; +} + +static int tiva_adc0_sse3_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse03); + return OK; +} +#endif + +#ifdef CONFIG_TIVA_ADC1 +static int tiva_adc1_sse0_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse10); + return OK; +} + +static int tiva_adc1_sse1_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse11); + return OK; +} + +static int tiva_adc1_sse2_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse12); + return OK; +} + +static int tiva_adc1_sse3_interrupt(int irq, void *context) +{ + tiva_adc_interrupt(&sse13); + return OK; +} +#endif + +static void tiva_adc_irqinitialize(struct tiva_adc_cfg_s *cfg) +{ + avdbg("initialize irqs for ADC%d...\n", cfg->adc); + +#ifdef CONFIG_TIVA_ADC0 + if (cfg->adc == 0) + { + if (cfg->sse[0] && (cfg->ssecfg[0].trigger > 0)) + { + tiva_adc_irq_attach(0, 0, tiva_adc0_sse0_interrupt); + } + + if (cfg->sse[1] && (cfg->ssecfg[1].trigger > 0)) + { + tiva_adc_irq_attach(0, 1, tiva_adc0_sse1_interrupt); + } + + if (cfg->sse[2] && (cfg->ssecfg[2].trigger > 0)) + { + tiva_adc_irq_attach(0, 2, tiva_adc0_sse2_interrupt); + } + + if (cfg->sse[3] && (cfg->ssecfg[3].trigger > 0)) + { + tiva_adc_irq_attach(0, 3, tiva_adc0_sse3_interrupt); + } + } +#endif +#ifdef CONFIG_TIVA_ADC1 + if (cfg->adc == 1) + { + if (cfg->sse[0] && (cfg->ssecfg[0].trigger > 0)) + { + tiva_adc_irq_attach(1, 0, tiva_adc1_sse0_interrupt); + } + + if (cfg->sse[1] && (cfg->ssecfg[1].trigger > 0)) + { + tiva_adc_irq_attach(1, 1, tiva_adc1_sse1_interrupt); + } + + if (cfg->sse[2] && (cfg->ssecfg[2].trigger > 0)) + { + tiva_adc_irq_attach(1, 2, tiva_adc1_sse2_interrupt); + } + + if (cfg->sse[3] && (cfg->ssecfg[3].trigger > 0)) + { + tiva_adc_irq_attach(1, 3, tiva_adc1_sse3_interrupt); + } + } +#endif +} + +/**************************************************************************** + * Name: tiva_adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This is + * called before tiva_adc_setup() and on error conditions. + * + * Resetting disables interrupts and the enabled SSEs for the ADC. + * + ****************************************************************************/ + +static void tiva_adc_reset(struct adc_dev_s *dev) +{ + avdbg("Resetting...\n"); + + struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv; + struct tiva_adc_sse_s *sse; + uint8_t s; + + tiva_adc_rxint(dev, false); + + for (s = 0; s < 4; ++s) + { + sse = g_sses[SSE_IDX(priv->devno, s)]; + + if (sse->ena == true) + { + tiva_adc_sse_enable(priv->devno, s, false); + sse->ena = false; + } + } +} + +/**************************************************************************** + * Name: tiva_adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * Interrupts are all disabled upon return. + * + ****************************************************************************/ + +static int tiva_adc_setup(struct adc_dev_s *dev) +{ + avdbg("Setup\n"); + + struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv; + struct tiva_adc_sse_s *sse; + uint8_t s = 0; + + priv->ena = true; + + for (s = 0; s < 4; ++s) + { + sse = g_sses[SSE_IDX(priv->devno, s)]; + if (sse->cfg == true) + { + tiva_adc_sse_enable(priv->devno, s, true); + sse->ena = true; + } + } + + tiva_adc_rxint(dev, false); + return OK; +} + +/**************************************************************************** + * Name: tiva_adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + ****************************************************************************/ + +static void tiva_adc_shutdown(struct adc_dev_s *dev) +{ + struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv; + avdbg("Shutdown\n"); + + DEBUGASSERT(priv->ena); + + /* Resetting the ADC peripheral disables interrupts and all SSEs */ + + tiva_adc_reset(dev); + + /* Currently all of the setup operations are undone in reset() */ + +#if 0 + struct tiva_adc_sse_s *sse; + uint8_t s = 0; + + for (s = 0; s < 4; ++s) + { + } +#endif + + priv->ena = false; +} + +/**************************************************************************** + * Name: tiva_adc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + * Input Parameters: + * enable - the enable state of interrupts for this device + * + ****************************************************************************/ + +static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable) +{ + avdbg("RXINT=%d\n", enable); + + struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv; + struct tiva_adc_sse_s *sse; + uint32_t trigger; + uint8_t s = 0; + + DEBUGASSERT(priv->ena); + + for (s = 0; s < 4; ++s) + { + trigger = tiva_adc_get_trigger(priv->devno, s); + sse = g_sses[SSE_IDX(priv->devno, s)]; + if ((sse->ena == true) + && (trigger > 0)) + { + tiva_adc_sse_int_enable(priv->devno, s, enable); + } + } +} + +/**************************************************************************** + * Name: tiva_adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * cmd - ADC ioctl command + * arg - argument for the ioctl command + * + * Returned Value: + * Non negative value on success; negative value on failure. + * + ****************************************************************************/ + +static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + int ret = OK; + + avdbg("cmd=%d arg=%ld\n", cmd, arg); + + switch (cmd) + { + /* Software trigger */ + + case ANIOC_TRIGGER: + { + struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv; + uint8_t i = 0; + uint8_t fifo_count = 0; + uint8_t sse = (uint8_t) arg; + int32_t buf[8]; + + /* Get exclusive access to the driver data structure */ + + tiva_adc_lock(priv, sse); + + /* Start conversion and wait for end of conversion */ + + tiva_adc_proc_trig(priv->devno, (uint8_t)SSE_PROC_TRIG(sse)); + while (!tiva_adc_sse_int_status(priv->devno, sse)) + { + usleep(100); + } + + tiva_adc_sse_clear_int(priv->devno, sse); + + /* Pass sampled data to upper ADC driver */ + + fifo_count = tiva_adc_sse_data(priv->devno, sse, buf); + + for (i = 0; i < fifo_count; ++i) + { + (void)adc_receive(dev, + tiva_adc_get_ain(priv->devno, sse, i), + buf[i]); + } + + /* Release our lock on the ADC structure */ + + tiva_adc_unlock(priv, sse); + } + break; + + /* PWM triggering */ + +#warning Missing Logic + + /* TODO: Needs to be tested */ + +#ifdef CONFIG_EXPERIMENTAL + case TIVA_ADC_PWM_TRIG_IOCTL: + { + uint8_t sse = (uint8_t)(arg & 0x2); + uint8_t regval = tiva_adc_get_trigger(adc, sse); + + /* Verify input SSE trigger is a PWM trigger */ + + if ((regval & TIVA_ADC_TRIG_PWM0) || + (regval & TIVA_ADC_TRIG_PWM1) || + (regval & TIVA_ADC_TRIG_PWM2) || + (regval & TIVA_ADC_TRIG_PWM3)) + { + tiva_adc_sse_pwm_trig(adc, sse, (uint32_t)(arg&0xFFFFFFFC)); + } + } + break; +#endif + +#warning Missing Logic + + /* Unsupported or invalid command */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: tiva_adc_read + * + * Description: + * This function executes on the worker thread. It is scheduled by + * tiva_adc_interrupt whenever any enabled event occurs. All interrupts + * are disabled when this function runs. tiva_adc_read will + * re-enable interrupts when it completes processing all pending events. + * + * Input Parameters + * arg - The ADC SSE data structure cast to (void *) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void tiva_adc_read(void *arg) +{ + struct tiva_adc_sse_s *sse = (struct tiva_adc_sse_s *)arg; + struct adc_dev_s *dev = 0; + int irq = tiva_adc_getirq(sse->adc, sse->num); + uint8_t i = 0; + uint8_t fifo_count = 0; + int32_t buf[8]; + + /* Get exclusive access to the driver data structure */ + + tiva_adc_lock(g_adcs[sse->adc], sse->num); + + /* Get sampled data */ + + fifo_count = tiva_adc_sse_data(sse->adc, sse->num, buf); + + /* Determine which adc_dev_s we need */ + + dev = g_devs[sse->adc]; + if (dev == NULL) + { + /* This is a serious error: indicates invalid pointer indirection + * and should cause a full system stop. + */ + alldbg("PANIC!!! Invalid ADC device number given %d\n", sse->adc); + PANIC(); + return; + } + + for (i = 0; i < fifo_count; ++i) + { + (void)adc_receive(dev, + tiva_adc_get_ain(sse->adc, sse->num, i), + buf[i]); + avdbg("AIN%d=0x%04x\n", + tiva_adc_get_ain(sse->adc, sse->num, i), buf[i]); + } + + /* Exit, re-enabling ADC interrupts */ + + up_enable_irq(irq); + + /* Release our lock on the ADC structure */ + + tiva_adc_unlock(g_adcs[sse->adc], sse->num); +} + +/**************************************************************************** + * Name: tiva_adc_interrupt + * + * Description: + * This function is called by every interrupt handler and handles the + * actual worker dispatching. + * + ****************************************************************************/ + +static void tiva_adc_interrupt(struct tiva_adc_sse_s *sse) +{ + int ret; + int irq = tiva_adc_getirq(sse->adc, sse->num); + + DEBUGASSERT(sse->ena == true); + + /* disable further interrupts. Interrupts will be re-enabled + * after the worker thread executes. + */ + + up_disable_irq(irq); + + /* Clear interrupt status */ + + tiva_adc_sse_clear_int(sse->adc, sse->num); + + /* Transfer processing to the worker thread. Since interrupts are + * disabled while the work is pending, no special action should be + * required to protected the work queue. + */ + + DEBUGASSERT(sse->work.worker == NULL); + ret = work_queue(HPWORK, &sse->work, tiva_adc_read, sse, 0); + if (ret != 0) + { + adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n", + ret, sse->adc, sse->num); + } +} + +/**************************************************************************** + * Name: tiva_adc_struct_init + * + * Description: + * Initialize public and private adc structures their member SSE's. + * + ****************************************************************************/ + +static struct tiva_adc_s *tiva_adc_struct_init(struct tiva_adc_cfg_s *cfg) +{ + struct tiva_adc_s *adc = g_adcs[cfg->adc]; + struct tiva_adc_sse_s *sse = 0; + uint8_t s = 0; + + /* Do not re-initialize the run-time structures, there is a chance another + * process is also using this ADC. + */ + + if (adc->cfg == true) + { + goto tiva_adc_struct_init_ok; + } + else + { + if (adc != NULL) + { + adc->ena = false; + adc->devno = cfg->adc; + + for (s = 0; s < 4; s++) + { + + /* Only configure selected SSEs */ + + if (cfg->sse[s]) + { + sse = g_sses[SSE_IDX(cfg->adc, s)]; + + if (sse != NULL) + { + sse->adc = cfg->adc; + sse->num = s; + sem_init(&sse->exclsem, SEM_PROCESS_PRIVATE, 1); + sse->ena = false; + sse->cfg = true; + } + else + { + goto tiva_adc_struct_init_error; + } + } + } + + /* Initialize the public ADC device data structure */ + + adc->dev = g_devs[cfg->adc]; + if (adc->dev != NULL) + { + adc->dev->ad_ops = &g_adcops; + adc->dev->ad_priv = adc; + } + else + { + goto tiva_adc_struct_init_error; + } + goto tiva_adc_struct_init_ok; + } + else + { + goto tiva_adc_struct_init_error; + } + } + +tiva_adc_struct_init_error: + avdbg("Invalid ADC device number: expected=%d actual=%d\n", + 0, cfg->adc); + avdbg("ADC%d (CONFIG_TIVA_ADC%d) must be enabled in Kconfig first!", + cfg->adc, cfg->adc); + return NULL; + +tiva_adc_struct_init_ok: + adc->cfg = true; + return adc; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_adc_initialize + * + * Description: + * Configuration and bind the ADC to the ADC lower half instance and + * register the ADC driver at 'devpath'. + * + * Input Parameters: + * devpath - The full path to the ADC device. This should be of the + * form /dev/adc0 + * cfg - ADC configuration structure, configures the whole ADC. + * clock - clock speed for all ADC's. This is only set once for the first + * call to tiva_adc_initialize, otherwise the values are ignored. + * sample_rate - maximum sample rate of any ADC. This is only set once + * for the first call to tiva_adc_initialize, otherwise the values are + * ignored. + * + ****************************************************************************/ + +int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg, + uint32_t clock, uint8_t sample_rate) +{ + struct tiva_adc_s *adc; + int ret = 0; + + avdbg("initializing...\n"); + + /* Initialize the private ADC device data structure */ + + adc = tiva_adc_struct_init(cfg); + if (adc == NULL) + { + adbg("Invalid ADC device number: expected=%d actual=%d\n", + 0, cfg->adc); + return -ENODEV; + } + + /* Turn on peripheral */ + + if (tiva_adc_enable(adc->devno, true) < 0) + { + adbg("ERROR: failure to power ADC peripheral (devno=%d)\n", + cfg->adc); + return ret; + } + + /* Perform actual initialization */ + + tiva_adc_one_time_init(clock, sample_rate); + tiva_adc_configure(cfg); + tiva_adc_irqinitialize(cfg); + + /* Now we are initialized */ + + adc->ena = true; + +#ifdef CONFIG_DEBUG_ANALOG + tiva_adc_runtimeobj_vals(); +#endif + + /* Ensure our lower half is valid */ + + if (adc->dev == NULL) + { + adbg("ERROR: Failed to get interface %s\n", devpath); + return -ENODEV; + } + + avdbg("adc_dev_s=0x%08x\n", adc->dev); + + /* Register the ADC driver */ + + avdbg("Register the ADC driver at %s\n", devpath); + + ret = adc_register(devpath, adc->dev); + if (ret < 0) + { + adbg("ERROR: Failed to register %s to character driver: %d\n", + devpath, ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: tiva_adc_lock + * + * Description: + * Get exclusive access to the ADC interface + * + ****************************************************************************/ + +void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse) +{ + avdbg("Locking...\n"); + + struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)]; + int ret; +#ifdef CONFIG_DEBUG_ANALOG + uint16_t loop_count = 0; +#endif + + do + { + ret = sem_wait(&s->exclsem); + + /* This should only fail if the wait was canceled by an signal (and the + * worker thread will receive a lot of signals). + */ + + DEBUGASSERT(ret == OK || errno == EINTR); + +#ifdef CONFIG_DEBUG_ANALOG + if (loop_count % 1000) + { + avdbg("loop=%d\n"); + } + ++loop_count; +#endif + } + while (ret < 0); +} + +/**************************************************************************** + * Name: tiva_adc_unlock + * + * Description: + * Relinquish the lock on the ADC interface + * + ****************************************************************************/ + +void tiva_adc_unlock(FAR struct tiva_adc_s *priv, int sse) +{ + avdbg("Unlocking\n"); + struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)]; + sem_post(&s->exclsem); +} + +/* DEBUG ********************************************************************/ + +#ifdef CONFIG_DEBUG_ANALOG + +/**************************************************************************** + * Name: tiva_adc_runtimeobj_ptrs + * + * Description: + * Dumps the address of all run-time objects for verification. + * + ****************************************************************************/ + +static void tiva_adc_runtimeobj_ptrs(void) +{ +# ifdef CONFIG_TIVA_ADC0 + avdbg("ADC0 [struct] [global value] [array value]\n"); + avdbg(" adc_dev_s dev0=0x%08x g_devs[0]=0x%08x\n", + &dev0, g_devs[0]); + avdbg(" tiva_adc_s adc0=0x%08x g_adcs[0]=0x%08x\n", + &adc0, g_adcs[0]); + avdbg(" tiva_adc_sse_s sse0=0x%08x g_sses[0,0]=0x%08x\n", + &sse00, g_sses[SSE_IDX(0, 0)]); + avdbg(" tiva_adc_sse_s sse1=0x%08x g_sses[0,1]=0x%08x\n", + &sse01, g_sses[SSE_IDX(0, 1)]); + avdbg(" tiva_adc_sse_s sse2=0x%08x g_sses[0,2]=0x%08x\n", + &sse02, g_sses[SSE_IDX(0, 2)]); + avdbg(" tiva_adc_sse_s sse3=0x%08x g_sses[0,3]=0x%08x\n", + &sse03, g_sses[SSE_IDX(0, 3)]); +# endif +# ifdef CONFIG_TIVA_ADC1 + avdbg("ADC1 [struct] [global value] [array value]\n"); + avdbg(" adc_dev_s dev1=0x%08x g_devs[1]=0x%08x\n", + &dev1, g_devs[1]); + avdbg(" tiva_adc_s adc1=0x%08x g_adcs[1]=0x%08x\n", + &adc1, g_adcs[1]); + avdbg(" tiva_adc_sse_s sse0=0x%08x g_sses[1,0]=0x%08x\n", + &sse10, g_sses[SSE_IDX(1, 0)]); + avdbg(" tiva_adc_sse_s sse1=0x%08x g_sses[1,1]=0x%08x\n", + &sse11, g_sses[SSE_IDX(1, 1)]); + avdbg(" tiva_adc_sse_s sse2=0x%08x g_sses[1,2]=0x%08x\n", + &sse12, g_sses[SSE_IDX(1, 2)]); + avdbg(" tiva_adc_sse_s sse3=0x%08x g_sses[1,3]=0x%08x\n", + &sse13, g_sses[SSE_IDX(1, 3)]); +# endif +} + +static void tiva_adc_runtimeobj_vals(void) +{ + struct tiva_adc_sse_s *sse; + uint8_t s; +# ifdef CONFIG_TIVA_ADC0 + avdbg("ADC0 [0x%08x] cfg=%d ena=%d devno=%d\n", + &adc0, adc0.cfg, adc0.ena, adc0.devno); + + for (s = 0; s < 4; ++s) + { + sse = g_sses[SSE_IDX(0, s)]; + avdbg("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n", + s, sse, sse->adc, sse->cfg, sse->ena, sse->num); + } +# endif +# ifdef CONFIG_TIVA_ADC1 + avdbg("ADC1 [0x%08x] cfg=%d ena=%d devno=%d\n", + &adc1, adc1.cfg, adc1.ena, adc1.devno); + + for (s = 0; s < 4; ++s) + { + sse = g_sses[SSE_IDX(1, s)]; + avdbg("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n", + s, sse, sse->adc, sse->cfg, sse->ena, sse->num); + } +# endif +} + +/**************************************************************************** + * Name: tiva_adc_unlock + * + * Description: + * umps the device level objects for verification. + * + ****************************************************************************/ + +static void tiva_adc_dump_dev(void) +{ +# ifdef CONFIG_TIVA_ADC0 + avdbg("adc_ops_s g_adcops=0x%08x adc0.dev->ad_ops=0x%08x\n", + &g_adcops, adc0.dev->ad_ops); + avdbg("tiva_adc_s adc0=0x%08x adc0.dev->ad_priv=0x%08x\n", + &adc0, adc0.dev->ad_priv); +# endif +# ifdef CONFIG_TIVA_ADC1 + avdbg("adc_ops_s g_adcops=0x%08x adc1.dev->ad_ops=0x%08x\n", + &g_adcops, adc1.dev->ad_ops); + avdbg("tiva_adc_s adc1=0x%08x adc1.dev->ad_priv=0x%08x\n", + &adc1, adc1.dev->ad_priv); +# endif +} +#endif + +#endif /* CONFIG_TIVA_ADC && CONFIG_ADC */ diff --git a/arch/arm/src/tiva/tiva_allocateheap.c b/arch/arm/src/tiva/tiva_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..06df87bb31b899daed0cd8625a8c8f029d5de342 --- /dev/null +++ b/arch/arm/src/tiva/tiva_allocateheap.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_allocateheap.c + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "tiva_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + tiva_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif diff --git a/arch/arm/src/tiva/tiva_dumpgpio.c b/arch/arm/src/tiva/tiva_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..89ae3a462b2f6da0af322c9f0e6ca8661f3f1d77 --- /dev/null +++ b/arch/arm/src/tiva/tiva_dumpgpio.c @@ -0,0 +1,197 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_dumpgpio.c + * + * Copyright (C) 2009-2010, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "tiva_gpio.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +static const char g_portchar[TIVA_NPORTS] = +{ +#if TIVA_NPORTS > 0 + 'A' +#endif +#if TIVA_NPORTS > 1 + , 'B' +#endif +#if TIVA_NPORTS > 2 + , 'C' +#endif +#if TIVA_NPORTS > 3 + , 'D' +#endif +#if TIVA_NPORTS > 4 + , 'E' +#endif +#if TIVA_NPORTS > 5 + , 'F' +#endif +#if TIVA_NPORTS > 6 + , 'G' +#endif +#if TIVA_NPORTS > 7 + , 'H' +#endif +#if TIVA_NPORTS > 8 + , 'J' +#endif +#if TIVA_NPORTS > 9 + , 'K' +#endif +#if TIVA_NPORTS > 10 + , 'L' +#endif +#if TIVA_NPORTS > 11 + , 'M' +#endif +#if TIVA_NPORTS > 12 + , 'N' +#endif +#if TIVA_NPORTS > 13 + , 'P' +#endif +#if TIVA_NPORTS > 14 + , 'Q' +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_gpioport + * + * Description: + * Given a GPIO enumeration value, return the base address of the + * associated GPIO registers. + * + ****************************************************************************/ + +static inline uint8_t tiva_gpioport(int port) +{ + return port < TIVA_NPORTS ? g_portchar[port] : '?'; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: tiva_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int tiva_dumpgpio(uint32_t pinset, const char *msg) +{ +#ifdef CONFIG_DEBUG + irqstate_t flags; + unsigned int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + uintptr_t base; +#ifdef TIVA_SYSCON_RCGCGPIO + uint32_t rcgcgpio; +#else + uint32_t rcgc2; +#endif + bool enabled; + + /* Get the base address associated with the GPIO port */ + + base = tiva_gpiobaseaddress(port); + DEBUGASSERT(base != 0); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); +#ifdef TIVA_SYSCON_RCGCGPIO + rcgcgpio = getreg32(TIVA_SYSCON_RCGCGPIO); + enabled = ((rcgcgpio & SYSCON_RCGCGPIO(port)) != 0); +#else + rcgc2 = getreg32(TIVA_SYSCON_RCGC2); + enabled = ((rcgc2 & SYSCON_RCGC2_GPIO(port)) != 0); +#endif + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + tiva_gpioport(port), pinset, base, msg); +#ifdef TIVA_SYSCON_RCGCGPIO + lldbg("RCGCGPIO: %08x (%s)\n", + rcgcgpio, enabled ? "enabled" : "disabled"); +#else + lldbg(" RCGC2: %08x (%s)\n", + rcgc2, enabled ? "enabled" : "disabled"); +#endif + + /* Don't bother with the rest unless the port is enabled */ + + if (enabled) + { + lldbg(" AFSEL: %02x DEN: %02x DIR: %02x DATA: %02x\n", + getreg32(base + TIVA_GPIO_AFSEL_OFFSET), getreg32(base + TIVA_GPIO_DEN_OFFSET), + getreg32(base + TIVA_GPIO_DIR_OFFSET), getreg32(base + TIVA_GPIO_DATA_OFFSET + 0x3fc)); + lldbg(" IS: %02x IBE: %02x IEV: %02x IM: %02x RIS: %08x MIS: %08x\n", + getreg32(base + TIVA_GPIO_IEV_OFFSET), getreg32(base + TIVA_GPIO_IM_OFFSET), + getreg32(base + TIVA_GPIO_RIS_OFFSET), getreg32(base + TIVA_GPIO_MIS_OFFSET)); + lldbg(" 2MA: %02x 4MA: %02x 8MA: %02x ODR: %02x PUR %02x PDR: %02x SLR: %02x\n", + getreg32(base + TIVA_GPIO_DR2R_OFFSET), getreg32(base + TIVA_GPIO_DR4R_OFFSET), + getreg32(base + TIVA_GPIO_DR8R_OFFSET), getreg32(base + TIVA_GPIO_ODR_OFFSET), + getreg32(base + TIVA_GPIO_PUR_OFFSET), getreg32(base + TIVA_GPIO_PDR_OFFSET), + getreg32(base + TIVA_GPIO_SLR_OFFSET)); + } + + leave_critical_section(flags); +#endif /* CONFIG_DEBUG */ + + return OK; +} diff --git a/arch/arm/src/tiva/tiva_enableclks.h b/arch/arm/src/tiva/tiva_enableclks.h new file mode 100644 index 0000000000000000000000000000000000000000..5f876032b0ee72658fa2c0b52df7b760bad086ec --- /dev/null +++ b/arch/arm/src/tiva/tiva_enableclks.h @@ -0,0 +1,433 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_enableclks.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_ENABLECLKS_H +#define __ARCH_ARM_SRC_TIVA_TIVA_ENABLECLKS_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/tiva_syscontrol.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Clocks are enabled or disabled by setting or clearing a bit (b) in a system + * control register (a)) + */ + +#define tiva_enableclk(a,b) modifyreg32((a),0,(b)) +#define tiva_disableclk(a,b) modifyreg32((a),(b),0) + +/* Watchdog Timer Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCWD +# define tiva_wdt_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCWD,SYSCON_RCGCWD(p)) +# define tiva_wdt_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCWD,SYSCON_RCGCWD(p)) + +# define tiva_wdt0_enableclk() tiva_wdt_enableclk(0) +# define tiva_wdt1_enableclk() tiva_wdt_enableclk(1) + +# define tiva_wdt0_disableclk() tiva_wdt_disableclk(0) +# define tiva_wdt1_disableclk() tiva_wdt_disableclk(1) +#else +#endif + +/* 16/32-Bit Timer Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCTIMER +# define tiva_gptm_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCTIMER,SYSCON_RCGCTIMER(p)) +# define tiva_gptm_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCTIMER,SYSCON_RCGCTIMER(p)) + +# define tiva_gptm0_enableclk() tiva_gptm_enableclk(0) +# define tiva_gptm1_enableclk() tiva_gptm_enableclk(1) +# define tiva_gptm2_enableclk() tiva_gptm_enableclk(2) +# define tiva_gptm3_enableclk() tiva_gptm_enableclk(3) +# define tiva_gptm4_enableclk() tiva_gptm_enableclk(4) +# define tiva_gptm5_enableclk() tiva_gptm_enableclk(5) +# define tiva_gptm6_enableclk() tiva_gptm_enableclk(6) +# define tiva_gptm7_enableclk() tiva_gptm_enableclk(7) + +# define tiva_gptm0_disableclk() tiva_gptm_disableclk(0) +# define tiva_gptm1_disableclk() tiva_gptm_disableclk(1) +# define tiva_gptm2_disableclk() tiva_gptm_disableclk(2) +# define tiva_gptm3_disableclk() tiva_gptm_disableclk(3) +# define tiva_gptm4_disableclk() tiva_gptm_disableclk(4) +# define tiva_gptm5_disableclk() tiva_gptm_disableclk(5) +# define tiva_gptm6_disableclk() tiva_gptm_disableclk(6) +# define tiva_gptm7_disableclk() tiva_gptm_disableclk(7) +#else +#endif + +/* GPIO Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCGPIO +# define tiva_gpio_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCGPIO,SYSCON_RCGCGPIO(p)) +# define tiva_gpio_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCGPIO,SYSCON_RCGCGPIO(p)) + +# define tiva_gpioa_enableclk() tiva_gpio_enableclk(0) +# define tiva_gpiob_enableclk() tiva_gpio_enableclk(1) +# define tiva_gpioc_enableclk() tiva_gpio_enableclk(2) +# define tiva_gpiod_enableclk() tiva_gpio_enableclk(3) +# define tiva_gpioe_enableclk() tiva_gpio_enableclk(4) +# define tiva_gpiof_enableclk() tiva_gpio_enableclk(5) +# define tiva_gpiog_enableclk() tiva_gpio_enableclk(6) +# define tiva_gpioh_enableclk() tiva_gpio_enableclk(7) +# define tiva_gpioj_enableclk() tiva_gpio_enableclk(8) +# define tiva_gpiok_enableclk() tiva_gpio_enableclk(9) +# define tiva_gpiol_enableclk() tiva_gpio_enableclk(10) +# define tiva_gpiom_enableclk() tiva_gpio_enableclk(11) +# define tiva_gpion_enableclk() tiva_gpio_enableclk(12) +# define tiva_gpiop_enableclk() tiva_gpio_enableclk(13) +# define tiva_gpioq_enableclk() tiva_gpio_enableclk(14) +# define tiva_gpior_enableclk() tiva_gpio_enableclk(15) +# define tiva_gpios_enableclk() tiva_gpio_enableclk(16) +# define tiva_gpiot_enableclk() tiva_gpio_enableclk(17) + +# define tiva_gpioa_disableclk() tiva_gpio_disableclk(0) +# define tiva_gpiob_disableclk() tiva_gpio_disableclk(1) +# define tiva_gpioc_disableclk() tiva_gpio_disableclk(2) +# define tiva_gpiod_disableclk() tiva_gpio_disableclk(3) +# define tiva_gpioe_disableclk() tiva_gpio_disableclk(4) +# define tiva_gpiof_disableclk() tiva_gpio_disableclk(5) +# define tiva_gpiog_disableclk() tiva_gpio_disableclk(6) +# define tiva_gpioh_disableclk() tiva_gpio_disableclk(7) +# define tiva_gpioj_disableclk() tiva_gpio_disableclk(8) +# define tiva_gpiok_disableclk() tiva_gpio_disableclk(9) +# define tiva_gpiol_disableclk() tiva_gpio_disableclk(10) +# define tiva_gpiom_disableclk() tiva_gpio_disableclk(11) +# define tiva_gpion_disableclk() tiva_gpio_disableclk(12) +# define tiva_gpiop_disableclk() tiva_gpio_disableclk(13) +# define tiva_gpioq_disableclk() tiva_gpio_disableclk(14) +# define tiva_gpior_disableclk() tiva_gpio_disableclk(15) +# define tiva_gpios_disableclk() tiva_gpio_disableclk(16) +# define tiva_gpiot_disableclk() tiva_gpio_disableclk(17) + +#else +# define tiva_gpio_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGC2,SYSCON_RCGC2_GPIO(p)) +# define tiva_gpio_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGC2,SYSCON_RCGC2_GPIO(p)) + +# define tiva_gpioa_enableclk() tiva_gpio_enableclk(0) +# define tiva_gpiob_enableclk() tiva_gpio_enableclk(1) +# define tiva_gpioc_enableclk() tiva_gpio_enableclk(2) +# define tiva_gpiod_enableclk() tiva_gpio_enableclk(3) +# define tiva_gpioe_enableclk() tiva_gpio_enableclk(4) +# define tiva_gpiof_enableclk() tiva_gpio_enableclk(5) +# define tiva_gpiog_enableclk() tiva_gpio_enableclk(6) +# define tiva_gpioh_enableclk() tiva_gpio_enableclk(7) +# define tiva_gpioj_enableclk() tiva_gpio_enableclk(8) +# define tiva_gpiok_enableclk() tiva_gpio_enableclk(9) +# define tiva_gpiol_enableclk() tiva_gpio_enableclk(10) +# define tiva_gpiom_enableclk() tiva_gpio_enableclk(11) +# define tiva_gpion_enableclk() tiva_gpio_enableclk(12) +# define tiva_gpiop_enableclk() tiva_gpio_enableclk(13) +# define tiva_gpioq_enableclk() tiva_gpio_enableclk(14) + +# define tiva_gpioa_disableclk() tiva_gpio_disableclk(0) +# define tiva_gpiob_disableclk() tiva_gpio_disableclk(1) +# define tiva_gpioc_disableclk() tiva_gpio_disableclk(2) +# define tiva_gpiod_disableclk() tiva_gpio_disableclk(3) +# define tiva_gpioe_disableclk() tiva_gpio_disableclk(4) +# define tiva_gpiof_disableclk() tiva_gpio_disableclk(5) +# define tiva_gpiog_disableclk() tiva_gpio_disableclk(6) +# define tiva_gpioh_disableclk() tiva_gpio_disableclk(7) +# define tiva_gpioj_disableclk() tiva_gpio_disableclk(8) +# define tiva_gpiok_disableclk() tiva_gpio_disableclk(9) +# define tiva_gpiol_disableclk() tiva_gpio_disableclk(10) +# define tiva_gpiom_disableclk() tiva_gpio_disableclk(11) +# define tiva_gpion_disableclk() tiva_gpio_disableclk(12) +# define tiva_gpiop_disableclk() tiva_gpio_disableclk(13) +# define tiva_gpioq_disableclk() tiva_gpio_disableclk(14) + +#endif + +/* μDMA Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCDMA +# define tiva_udma_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCDMA,SYSCON_RCGCDMA_R0) +# define tiva_udma_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCDMA,SYSCON_RCGCDMA_R0) +#else +#endif + +/* EPI Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCEPI +# define tiva_epi_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCEPI,SYSCON_RCGCEPI_R0) +# define tiva_epi_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCEPI,SYSCON_RCGCEPI_R0) +#else +#endif + +/* Hibernation Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCHIB +# define tiva_hib_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCHIB,SYSCON_RCGCHIB_R0) +# define tiva_hib_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCHIB,SYSCON_RCGCHIB_R0) +#else +#endif + +/* UART Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCUART +# define tiva_uart_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCUART,SYSCON_RCGCUART(p)) +# define tiva_uart_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCUART,SYSCON_RCGCUART(p)) + +# define tiva_uart0_enableclk() tiva_uart_enableclk(0) +# define tiva_uart1_enableclk() tiva_uart_enableclk(1) +# define tiva_uart2_enableclk() tiva_uart_enableclk(2) +# define tiva_uart3_enableclk() tiva_uart_enableclk(3) +# define tiva_uart4_enableclk() tiva_uart_enableclk(4) +# define tiva_uart5_enableclk() tiva_uart_enableclk(5) +# define tiva_uart6_enableclk() tiva_uart_enableclk(6) +# define tiva_uart7_enableclk() tiva_uart_enableclk(7) + +# define tiva_uart0_disableclk() tiva_uart_disableclk(0) +# define tiva_uart1_disableclk() tiva_uart_disableclk(1) +# define tiva_uart2_disableclk() tiva_uart_disableclk(2) +# define tiva_uart3_disableclk() tiva_uart_disableclk(3) +# define tiva_uart4_disableclk() tiva_uart_disableclk(4) +# define tiva_uart5_disableclk() tiva_uart_disableclk(5) +# define tiva_uart6_disableclk() tiva_uart_disableclk(6) +# define tiva_uart7_disableclk() tiva_uart_disableclk(7) +#else +# define tiva_uart0_enableclk() tiva_enableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART0) +# define tiva_uart1_enableclk() tiva_enableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART1) +# define tiva_uart2_enableclk() tiva_enableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART2) + +# define tiva_uart0_disableclk() tiva_disableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART0) +# define tiva_uart1_disableclk() tiva_disableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART1) +# define tiva_uart2_disableclk() tiva_disableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_UART2) +#endif + +/* SSI Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCSSI +# define tiva_ssi_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCSSI,SYSCON_RCGCSSI(p)) +# define tiva_ssi_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCSSI,SYSCON_RCGCSSI(p)) + +# define tiva_ssi0_enableclk() tiva_ssi_enableclk(0) +# define tiva_ssi1_enableclk() tiva_ssi_enableclk(1) +# define tiva_ssi2_enableclk() tiva_ssi_enableclk(2) +# define tiva_ssi3_enableclk() tiva_ssi_enableclk(3) + +# define tiva_ssi0_disableclk() tiva_ssi_disableclk(0) +# define tiva_ssi1_disableclk() tiva_ssi_disableclk(1) +# define tiva_ssi2_disableclk() tiva_ssi_disableclk(2) +# define tiva_ssi3_disableclk() tiva_ssi_disableclk(3) +#else +# define tiva_ssi0_enableclk() tiva_enableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_SSI0) +# define tiva_ssi1_enableclk() tiva_enableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_SSI1) + +# define tiva_ssi0_disableclk() tiva_disableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_SSI0) +# define tiva_ssi1_disableclk() tiva_disableclk(TIVA_SYSCON_RCGC1,SYSCON_RCGC1_SSI1) +#endif + +/* I2C Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCI2C +# define tiva_i2c_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCI2C,SYSCON_RCGCI2C(p)) +# define tiva_i2c_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCI2C,SYSCON_RCGCI2C(p)) + +# define tiva_i2c0_enableclk() tiva_i2c_enableclk(0) +# define tiva_i2c1_enableclk() tiva_i2c_enableclk(1) +# define tiva_i2c2_enableclk() tiva_i2c_enableclk(2) +# define tiva_i2c3_enableclk() tiva_i2c_enableclk(3) +# define tiva_i2c4_enableclk() tiva_i2c_enableclk(4) +# define tiva_i2c5_enableclk() tiva_i2c_enableclk(5) +# define tiva_i2c6_enableclk() tiva_i2c_enableclk(6) +# define tiva_i2c7_enableclk() tiva_i2c_enableclk(7) +# define tiva_i2c8_enableclk() tiva_i2c_enableclk(8) +# define tiva_i2c9_enableclk() tiva_i2c_enableclk(9) + +# define tiva_i2c0_disableclk() tiva_i2c_disableclk(0) +# define tiva_i2c1_disableclk() tiva_i2c_disableclk(1) +# define tiva_i2c2_disableclk() tiva_i2c_disableclk(2) +# define tiva_i2c3_disableclk() tiva_i2c_disableclk(3) +# define tiva_i2c4_disableclk() tiva_i2c_disableclk(4) +# define tiva_i2c5_disableclk() tiva_i2c_disableclk(5) +# define tiva_i2c6_disableclk() tiva_i2c_disableclk(6) +# define tiva_i2c7_disableclk() tiva_i2c_disableclk(7) +# define tiva_i2c8_disableclk() tiva_i2c_disableclk(8) +# define tiva_i2c9_disableclk() tiva_i2c_disableclk(9) +#else +#endif + +/* USB Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCUSB +# define tiva_usb_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCUSB,SYSCON_RCGCUSB_R0) +# define tiva_usb_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCUSB,SYSCON_RCGCUSB_R0) +#else +#endif + +/* Ethernet PHY Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCEPHY +# define tiva_ephy_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCEPHY,SYSCON_RCGCEPHY_R0) +# define tiva_ephy_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCEPHY,SYSCON_RCGCEPHY_R0) +#else +#endif + +/* CAN RunMode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCCAN +# define tiva_can_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCCAN,SYSCON_RCGCCAN(p)) +# define tiva_can_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCCAN,SYSCON_RCGCCAN(p)) + +# define tiva_can0_enableclk() tiva_can_enableclk(0) +# define tiva_can1_enableclk() tiva_can_enableclk(1) + +# define tiva_can0_disableclk() tiva_can_disableclk(0) +# define tiva_can1_disableclk() tiva_can_disableclk(1) +#else +#endif + +/* ADC Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCADC +# define tiva_adc_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCADC,SYSCON_RCGCADC(p)) +# define tiva_adc_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCADC,SYSCON_RCGCADC(p)) + +# define tiva_adc0_enableclk() tiva_adc_enableclk(0) +# define tiva_adc1_enableclk() tiva_adc_enableclk(1) + +# define tiva_adc0_disableclk() tiva_adc_disableclk(0) +# define tiva_adc1_disableclk() tiva_adc_disableclk(1) +#else +#endif + +/* ACMP Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCACMP +# define tiva_acmp_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCACMP,SYSCON_RCGCACMP_R0) +# define tiva_acmp_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCACMP,SYSCON_RCGCACMP_R0) +#else +#endif + +/* PWM Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCPWM +# define tiva_pwm_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCPWM,SYSCON_RCGCPWM(p)) +# define tiva_pwm_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCPWM,SYSCON_RCGCPWM(p)) + +# define tiva_pwm0_enableclk() tiva_pwm_enableclk(0) +# define tiva_pwm1_enableclk() tiva_pwm_enableclk(1) + +# define tiva_pwm0_disableclk() tiva_pwm_disableclk(0) +# define tiva_pwm1_disableclk() tiva_pwm_disableclk(1) +#else +#endif + +/* QE Interface Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCQEI +# define tiva_qei_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCQEI,SYSCON_RCGCQEI(p)) +# define tiva_qei_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCQEI,SYSCON_RCGCQEI(p)) + +# define tiva_qei0_enableclk() tiva_qei_enableclk(0) +# define tiva_qei1_enableclk() tiva_qei_enableclk(1) + +# define tiva_qei0_disableclk() tiva_qei_disableclk(0) +# define tiva_qei1_disableclk() tiva_qei_disableclk(1) +#else +#endif + +/* EEPROM Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCEEPROM +# define tiva_eeprom_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCEEPROM,SYSCON_RCGCEEPROM_R0) +# define tiva_eeprom_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCEEPROM,SYSCON_RCGCEEPROM_R0) +#else +#endif + +/* 32/64-Bit Wide Timer Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCWTIMER +# define tiva_wtm_enableclk(p) tiva_enableclk(TIVA_SYSCON_RCGCWTIMER,SYSCON_RCGCWTIMER(p)) +# define tiva_wtm_disableclk(p) tiva_disableclk(TIVA_SYSCON_RCGCWTIMER,SYSCON_RCGCWTIMER(p)) + +# define tiva_wtm0_enableclk() tiva_wtm_enableclk(0) +# define tiva_wtm1_enableclk() tiva_wtm_enableclk(1) +# define tiva_wtm2_enableclk() tiva_wtm_enableclk(2) +# define tiva_wtm3_enableclk() tiva_wtm_enableclk(3) +# define tiva_wtm4_enableclk() tiva_wtm_enableclk(4) +# define tiva_wtm5_enableclk() tiva_wtm_enableclk(5) + +# define tiva_wtm0_disableclk() tiva_wtm_disableclk(0) +# define tiva_wtm1_disableclk() tiva_wtm_disableclk(1) +# define tiva_wtm2_disableclk() tiva_wtm_disableclk(2) +# define tiva_wtm3_disableclk() tiva_wtm_disableclk(3) +# define tiva_wtm4_disableclk() tiva_wtm_disableclk(4) +# define tiva_wtm5_disableclk() tiva_wtm_disableclk(5) +#else +#endif + +/* CRC/Crypto Modules RunMode ClockGating Control */ + +#ifdef TIVA_SYSCON_RCGCCCM +# define tiva_ccm_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCCCM,SYSCON_RCGCCCM_R0) +# define tiva_ccm_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCCCM,SYSCON_RCGCCCM_R0) +#else +#endif + +/* LCD Controller Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCLCD +# define tiva_lcd_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCLCD,SYSCON_RCGCLCD_R0) +# define tiva_lcd_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCLCD,SYSCON_RCGCLCD_R0) +#else +#endif + +/* 1-Wire Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCOWIRE +# define tiva_owire_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCOWIRE,SYSCON_RCGCOWIRE_R0) +# define tiva_owire_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCOWIRE,SYSCON_RCGCOWIRE_R0) +#else +#endif + +/* Ethernet MAC Run Mode Clock Gating Control */ + +#ifdef TIVA_SYSCON_RCGCEMAC +# define tiva_emac_enableclk() tiva_enableclk(TIVA_SYSCON_RCGCEMAC,SYSCON_RCGCEMAC_R0) +# define tiva_emac_disableclk() tiva_disableclk(TIVA_SYSCON_RCGCEMAC,SYSCON_RCGCEMAC_R0) +#else +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_ENABLECLKS_H */ diff --git a/arch/arm/src/tiva/tiva_enablepwr.h b/arch/arm/src/tiva/tiva_enablepwr.h new file mode 100644 index 0000000000000000000000000000000000000000..28b91722e890f291c4e92bcaedab9d5dfe27de37 --- /dev/null +++ b/arch/arm/src/tiva/tiva_enablepwr.h @@ -0,0 +1,429 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_enablepwr.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_ENABLEPWR_H +#define __ARCH_ARM_SRC_TIVA_TIVA_ENABLEPWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/tiva_syscontrol.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Power control is enabled or disabled by setting or clearing a bit (b) in a system + * control register (a)) + */ + +#define tiva_enablepwr(a,b) modifyreg32((a),0,(b)) +#define tiva_disablepwr(a,b) modifyreg32((a),(b),0) + +/* Watchdog Timer Power Control */ + +#ifdef TIVA_SYSCON_PCWD +# define tiva_wdt_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCWD,SYSCON_PCWD(p)) +# define tiva_wdt_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCWD,SYSCON_PCWD(p)) +#else +# define tiva_wdt_enablepwr(p) +# define tiva_wdt_disablepwr(p) +#endif + +#define tiva_wdt0_enablepwr() tiva_wdt_enablepwr(0) +#define tiva_wdt1_enablepwr() tiva_wdt_enablepwr(1) + +#define tiva_wdt0_disablepwr() tiva_wdt_disablepwr(0) +#define tiva_wdt1_disablepwr() tiva_wdt_disablepwr(1) + +/* 16/32-Bit Timer Power Control */ + +#ifdef TIVA_SYSCON_PCTIMER +# define tiva_gptm_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCTIMER,SYSCON_PCTIMER(p)) +# define tiva_gptm_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCTIMER,SYSCON_PCTIMER(p)) +#else +# define tiva_gptm_enablepwr(p) +# define tiva_gptm_disablepwr(p) +#endif + +#define tiva_gptm0_enablepwr() tiva_gptm_enablepwr(0) +#define tiva_gptm1_enablepwr() tiva_gptm_enablepwr(1) +#define tiva_gptm2_enablepwr() tiva_gptm_enablepwr(2) +#define tiva_gptm3_enablepwr() tiva_gptm_enablepwr(3) +#define tiva_gptm4_enablepwr() tiva_gptm_enablepwr(4) +#define tiva_gptm5_enablepwr() tiva_gptm_enablepwr(5) +#define tiva_gptm6_enablepwr() tiva_gptm_enablepwr(6) +#define tiva_gptm7_enablepwr() tiva_gptm_enablepwr(7) + +#define tiva_gptm0_disablepwr() tiva_gptm_disablepwr(0) +#define tiva_gptm1_disablepwr() tiva_gptm_disablepwr(1) +#define tiva_gptm2_disablepwr() tiva_gptm_disablepwr(2) +#define tiva_gptm3_disablepwr() tiva_gptm_disablepwr(3) +#define tiva_gptm4_disablepwr() tiva_gptm_disablepwr(4) +#define tiva_gptm5_disablepwr() tiva_gptm_disablepwr(5) +#define tiva_gptm6_disablepwr() tiva_gptm_disablepwr(6) +#define tiva_gptm7_disablepwr() tiva_gptm_disablepwr(7) + +/* GPIO Power Control */ + +#ifdef TIVA_SYSCON_PCGPIO +# define tiva_gpio_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCGPIO,SYSCON_PCGPIO(p)) +# define tiva_gpio_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCGPIO,SYSCON_PCGPIO(p)) +#else +# define tiva_gpio_enablepwr(p) +# define tiva_gpio_disablepwr(p) +#endif + +#define tiva_gpioa_enablepwr() tiva_gpio_enablepwr(0) +#define tiva_gpiob_enablepwr() tiva_gpio_enablepwr(1) +#define tiva_gpioc_enablepwr() tiva_gpio_enablepwr(2) +#define tiva_gpiod_enablepwr() tiva_gpio_enablepwr(3) +#define tiva_gpioe_enablepwr() tiva_gpio_enablepwr(4) +#define tiva_gpiof_enablepwr() tiva_gpio_enablepwr(5) +#define tiva_gpiog_enablepwr() tiva_gpio_enablepwr(6) +#define tiva_gpioh_enablepwr() tiva_gpio_enablepwr(7) +#define tiva_gpioj_enablepwr() tiva_gpio_enablepwr(8) +#define tiva_gpiok_enablepwr() tiva_gpio_enablepwr(9) +#define tiva_gpiol_enablepwr() tiva_gpio_enablepwr(10) +#define tiva_gpiom_enablepwr() tiva_gpio_enablepwr(11) +#define tiva_gpion_enablepwr() tiva_gpio_enablepwr(12) +#define tiva_gpiop_enablepwr() tiva_gpio_enablepwr(13) +#define tiva_gpioq_enablepwr() tiva_gpio_enablepwr(14) +#define tiva_gpior_enablepwr() tiva_gpio_enablepwr(15) +#define tiva_gpios_enablepwr() tiva_gpio_enablepwr(16) +#define tiva_gpiot_enablepwr() tiva_gpio_enablepwr(17) + +#define tiva_gpioa_disablepwr() tiva_gpio_disablepwr(0) +#define tiva_gpiob_disablepwr() tiva_gpio_disablepwr(1) +#define tiva_gpioc_disablepwr() tiva_gpio_disablepwr(2) +#define tiva_gpiod_disablepwr() tiva_gpio_disablepwr(3) +#define tiva_gpioe_disablepwr() tiva_gpio_disablepwr(4) +#define tiva_gpiof_disablepwr() tiva_gpio_disablepwr(5) +#define tiva_gpiog_disablepwr() tiva_gpio_disablepwr(6) +#define tiva_gpioh_disablepwr() tiva_gpio_disablepwr(7) +#define tiva_gpioj_disablepwr() tiva_gpio_disablepwr(8) +#define tiva_gpiok_disablepwr() tiva_gpio_disablepwr(9) +#define tiva_gpiol_disablepwr() tiva_gpio_disablepwr(10) +#define tiva_gpiom_disablepwr() tiva_gpio_disablepwr(11) +#define tiva_gpion_disablepwr() tiva_gpio_disablepwr(12) +#define tiva_gpiop_disablepwr() tiva_gpio_disablepwr(13) +#define tiva_gpioq_disablepwr() tiva_gpio_disablepwr(14) +#define tiva_gpior_disablepwr() tiva_gpio_disablepwr(15) +#define tiva_gpios_disablepwr() tiva_gpio_disablepwr(16) +#define tiva_gpiot_disablepwr() tiva_gpio_disablepwr(17) + +/* μDMA Power Control */ + +#ifdef TIVA_SYSCON_PCDMA +# define tiva_udma_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCDMA,SYSCON_PCDMA_P0) +# define tiva_udma_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCDMA,SYSCON_PCDMA_P0) +#else +# define tiva_udma_enablepwr() +# define tiva_udma_disablepwr() +#endif + +/* EPI Power Control */ + +#ifdef TIVA_SYSCON_PCEPI +# define tiva_epi_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCEPI,SYSCON_PCEPI_P0) +# define tiva_epi_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCEPI,SYSCON_PCEPI_P0) +#else +# define tiva_epi_enablepwr() +# define tiva_epi_disablepwr() +#endif + +/* Hibernation Power Control */ + +#ifdef TIVA_SYSCON_PCHIB +# define tiva_hib_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCHIB,SYSCON_PCHIB_P0) +# define tiva_hib_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCHIB,SYSCON_PCHIB_P0) +#else +# define tiva_hib_enablepwr() +# define tiva_hib_disablepwr() +#endif + +/* UART Power Control */ + +#ifdef TIVA_SYSCON_PCUART +# define tiva_uart_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCUART,SYSCON_PCUART(p)) +# define tiva_uart_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCUART,SYSCON_PCUART(p)) +#else +# define tiva_uart_enablepwr(p) +# define tiva_uart_disablepwr(p) +#endif + +#define tiva_uart0_enablepwr() tiva_uart_enablepwr(0) +#define tiva_uart1_enablepwr() tiva_uart_enablepwr(1) +#define tiva_uart2_enablepwr() tiva_uart_enablepwr(2) +#define tiva_uart3_enablepwr() tiva_uart_enablepwr(3) +#define tiva_uart4_enablepwr() tiva_uart_enablepwr(4) +#define tiva_uart5_enablepwr() tiva_uart_enablepwr(5) +#define tiva_uart6_enablepwr() tiva_uart_enablepwr(6) +#define tiva_uart7_enablepwr() tiva_uart_enablepwr(7) + +#define tiva_uart0_disablepwr() tiva_uart_disablepwr(0) +#define tiva_uart1_disablepwr() tiva_uart_disablepwr(1) +#define tiva_uart2_disablepwr() tiva_uart_disablepwr(2) +#define tiva_uart3_disablepwr() tiva_uart_disablepwr(3) +#define tiva_uart4_disablepwr() tiva_uart_disablepwr(4) +#define tiva_uart5_disablepwr() tiva_uart_disablepwr(5) +#define tiva_uart6_disablepwr() tiva_uart_disablepwr(6) +#define tiva_uart7_disablepwr() tiva_uart_disablepwr(7) + +/* SSI Power Control */ + +#ifdef TIVA_SYSCON_PCSSI +# define tiva_ssi_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCSSI,SYSCON_PCSSI(p)) +# define tiva_ssi_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCSSI,SYSCON_PCSSI(p)) +#else +# define tiva_ssi_enablepwr(p) +# define tiva_ssi_disablepwr(p) +#endif + +#define tiva_ssi0_enablepwr() tiva_ssi_enablepwr(0) +#define tiva_ssi1_enablepwr() tiva_ssi_enablepwr(1) +#define tiva_ssi2_enablepwr() tiva_ssi_enablepwr(2) +#define tiva_ssi3_enablepwr() tiva_ssi_enablepwr(3) + +#define tiva_ssi0_disablepwr() tiva_ssi_disablepwr(0) +#define tiva_ssi1_disablepwr() tiva_ssi_disablepwr(1) +#define tiva_ssi2_disablepwr() tiva_ssi_disablepwr(2) +#define tiva_ssi3_disablepwr() tiva_ssi_disablepwr(3) + +/* I2C Power Control */ + +#ifdef TIVA_SYSCON_PCI2C +# define tiva_i2c_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCI2C,SYSCON_PCI2C(p)) +# define tiva_i2c_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCI2C,SYSCON_PCI2C(p)) +#else +# define tiva_i2c_enablepwr(p) +# define tiva_i2c_disablepwr(p) +#endif + +#define tiva_i2c0_enablepwr() tiva_i2c_enablepwr(0) +#define tiva_i2c1_enablepwr() tiva_i2c_enablepwr(1) +#define tiva_i2c2_enablepwr() tiva_i2c_enablepwr(2) +#define tiva_i2c3_enablepwr() tiva_i2c_enablepwr(3) +#define tiva_i2c4_enablepwr() tiva_i2c_enablepwr(4) +#define tiva_i2c5_enablepwr() tiva_i2c_enablepwr(5) +#define tiva_i2c6_enablepwr() tiva_i2c_enablepwr(6) +#define tiva_i2c7_enablepwr() tiva_i2c_enablepwr(7) +#define tiva_i2c8_enablepwr() tiva_i2c_enablepwr(8) +#define tiva_i2c9_enablepwr() tiva_i2c_enablepwr(9) + +#define tiva_i2c0_disablepwr() tiva_i2c_disablepwr(0) +#define tiva_i2c1_disablepwr() tiva_i2c_disablepwr(1) +#define tiva_i2c2_disablepwr() tiva_i2c_disablepwr(2) +#define tiva_i2c3_disablepwr() tiva_i2c_disablepwr(3) +#define tiva_i2c4_disablepwr() tiva_i2c_disablepwr(4) +#define tiva_i2c5_disablepwr() tiva_i2c_disablepwr(5) +#define tiva_i2c6_disablepwr() tiva_i2c_disablepwr(6) +#define tiva_i2c7_disablepwr() tiva_i2c_disablepwr(7) +#define tiva_i2c8_disablepwr() tiva_i2c_disablepwr(8) +#define tiva_i2c9_disablepwr() tiva_i2c_disablepwr(9) + +/* USB Power Control */ + +#ifdef TIVA_SYSCON_PCUSB +# define tiva_usb_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCUSB,SYSCON_PCUSB_P0) +# define tiva_usb_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCUSB,SYSCON_PCUSB_P0) +#else +# define tiva_usb_enablepwr() +# define tiva_usb_disablepwr() +#endif + +/* Ethernet PHY Power Control */ + +#ifdef TIVA_SYSCON_PCEPHY +# define tiva_ephy_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCEPHY,SYSCON_PCEPHY_P0) +# define tiva_ephy_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCEPHY,SYSCON_PCEPHY_P0) +#else +# define tiva_ephy_enablepwr() +# define tiva_ephy_disablepwr() +#endif + +/* CAN RunMode Clock Gating Control */ + +#ifdef TIVA_SYSCON_PCCAN +# define tiva_can_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCCAN,SYSCON_PCCAN(p)) +# define tiva_can_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCCAN,SYSCON_PCCAN(p)) +#else +# define tiva_can_enablepwr(p) +# define tiva_can_disablepwr(p) +#endif + +#define tiva_can0_enablepwr() tiva_can_enablepwr(0) +#define tiva_can1_enablepwr() tiva_can_enablepwr(1) + +#define tiva_can0_disablepwr() tiva_can_disablepwr(0) +#define tiva_can1_disablepwr() tiva_can_disablepwr(1) + +/* ADC Power Control */ + +#ifdef TIVA_SYSCON_PCADC +# define tiva_adc_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCADC,SYSCON_PCADC(p)) +# define tiva_adc_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCADC,SYSCON_PCADC(p)) +#else +# define tiva_adc_enablepwr(p) +# define tiva_adc_disablepwr(p) +#endif + +#define tiva_adc0_enablepwr() tiva_adc_enablepwr(0) +#define tiva_adc1_enablepwr() tiva_adc_enablepwr(1) + +#define tiva_adc0_disablepwr() tiva_adc_disablepwr(0) +#define tiva_adc1_disablepwr() tiva_adc_disablepwr(1) + +/* ACMP Power Control */ + +#ifdef TIVA_SYSCON_PCACMP +# define tiva_acmp_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCACMP,SYSCON_PCACMP_P0) +# define tiva_acmp_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCACMP,SYSCON_PCACMP_P0) +#else +# define tiva_acmp_enablepwr() +# define tiva_acmp_disablepwr() +#endif + +/* PWM Power Control */ + +#ifdef TIVA_SYSCON_PCPWM +# define tiva_pwm_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCPWM,SYSCON_PCPWM(p)) +# define tiva_pwm_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCPWM,SYSCON_PCPWM(p)) +#else +# define tiva_pwm_enablepwr(p) +# define tiva_pwm_disablepwr(p) +#endif + +#define tiva_pwm0_enablepwr() tiva_pwm_enablepwr(0) +#define tiva_pwm1_enablepwr() tiva_pwm_enablepwr(1) + +#define tiva_pwm0_disablepwr() tiva_pwm_disablepwr(0) +#define tiva_pwm1_disablepwr() tiva_pwm_disablepwr(1) + +/* QE Interface Power Control */ + +#ifdef TIVA_SYSCON_PCQEI +# define tiva_qei_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCQEI,SYSCON_PCQEI(p)) +# define tiva_qei_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCQEI,SYSCON_PCQEI(p)) +#else +# define tiva_qei_enablepwr(p) +# define tiva_qei_disablepwr(p) +#endif + +#define tiva_qei0_enablepwr() tiva_qei_enablepwr(0) +#define tiva_qei1_enablepwr() tiva_qei_enablepwr(1) + +#define tiva_qei0_disablepwr() tiva_qei_disablepwr(0) +#define tiva_qei1_disablepwr() tiva_qei_disablepwr(1) + +/* EEPROM Power Control */ + +#ifdef TIVA_SYSCON_PCEEPROM +# define tiva_eeprom_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCEEPROM,SYSCON_PCEEPROM_P0) +# define tiva_eeprom_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCEEPROM,SYSCON_PCEEPROM_P0) +#else +# define tiva_eeprom_enablepwr() +# define tiva_eeprom_disablepwr() +#endif + +/* 32/64-Bit Wide Timer Power Control */ + +#ifdef TIVA_SYSCON_PCWTIMER +# define tiva_wtm_enablepwr(p) tiva_enablepwr(TIVA_SYSCON_PCWTIMER,SYSCON_PCWTIMER(p)) +# define tiva_wtm_disablepwr(p) tiva_disablepwr(TIVA_SYSCON_PCWTIMER,SYSCON_PCWTIMER(p)) +#else +# define tiva_wtm_enablepwr(p) +# define tiva_wtm_disablepwr(p) +#endif + +#define tiva_wtm0_enablepwr() tiva_wtm_enablepwr(0) +#define tiva_wtm1_enablepwr() tiva_wtm_enablepwr(1) +#define tiva_wtm2_enablepwr() tiva_wtm_enablepwr(2) +#define tiva_wtm3_enablepwr() tiva_wtm_enablepwr(3) +#define tiva_wtm4_enablepwr() tiva_wtm_enablepwr(4) +#define tiva_wtm5_enablepwr() tiva_wtm_enablepwr(5) + +#define tiva_wtm0_disablepwr() tiva_wtm_disablepwr(0) +#define tiva_wtm1_disablepwr() tiva_wtm_disablepwr(1) +#define tiva_wtm2_disablepwr() tiva_wtm_disablepwr(2) +#define tiva_wtm3_disablepwr() tiva_wtm_disablepwr(3) +#define tiva_wtm4_disablepwr() tiva_wtm_disablepwr(4) +#define tiva_wtm5_disablepwr() tiva_wtm_disablepwr(5) + +/* CRC/Crypto Modules RunMode ClockGating Control */ + +#ifdef TIVA_SYSCON_PCCCM +# define tiva_ccm_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCCCM,SYSCON_PCCCM_P0) +# define tiva_ccm_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCCCM,SYSCON_PCCCM_P0) +#else +# define tiva_ccm_enablepwr() +# define tiva_ccm_disablepwr() +#endif + +/* LCD Controller Power Control */ + +#ifdef TIVA_SYSCON_PCLCD +# define tiva_lcd_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCLCD,SYSCON_PCLCD_P0) +# define tiva_lcd_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCLCD,SYSCON_PCLCD_P0) +#else +# define tiva_lcd_enablepwr() +# define tiva_lcd_disablepwr() +#endif + +/* 1-Wire Power Control */ + +#ifdef TIVA_SYSCON_PCOWIRE +# define tiva_owire_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCOWIRE,SYSCON_PCOWIRE_P0) +# define tiva_owire_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCOWIRE,SYSCON_PCOWIRE_P0) +#else +# define tiva_owire_enablepwr() +# define tiva_owire_disablepwr() +#endif + +/* Ethernet MAC Power Control */ + +#ifdef TIVA_SYSCON_PCEMAC +# define tiva_emac_enablepwr() tiva_enablepwr(TIVA_SYSCON_PCEMAC,SYSCON_PCEMAC_P0) +# define tiva_emac_disablepwr() tiva_disablepwr(TIVA_SYSCON_PCEMAC,SYSCON_PCEMAC_P0) +#else +# define tiva_emac_enablepwr() +# define tiva_emac_disablepwr() +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_ENABLEPWR_H */ diff --git a/arch/arm/src/tiva/tiva_ethernet.h b/arch/arm/src/tiva/tiva_ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..534d234375b4f5a4a3a1cc8397ed3279918d70de --- /dev/null +++ b/arch/arm/src/tiva/tiva_ethernet.h @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_ethernet.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_ETHERNET_H +#define __ARCH_ARM_SRC_TIVA_TIVA_ETHERNET_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Function: tiva_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the Tiva/Stellaris + * chip supports multiple Ethernet controllers, then board specific logic + * must implement up_netinitialize() and call this function to initialize + * the desired interfaces. + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS > 1 +int tiva_ethinitialize(int intf); +#endif + +/**************************************************************************** + * Name: tiva_ethernetmac + * + * Description: + * For the Ethernet Eval Kits, the MAC address will be stored in the non- + * volatile USER0 and USER1 registers. If CONFIG_TIVA_BOARDMAC is defined, + * this function will obtain the MAC address from these registers. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_BOARDMAC +struct ether_addr; +void tiva_ethernetmac(struct ether_addr *ethaddr); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_ETHERNET_H */ diff --git a/arch/arm/src/tiva/tiva_flash.c b/arch/arm/src/tiva/tiva_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..0dd70dd1dcb313b8f5f51f831c2c48433a6545b1 --- /dev/null +++ b/arch/arm/src/tiva/tiva_flash.c @@ -0,0 +1,348 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_flash.c + * + * Copyright (c) 2013 Max Holtzberg. All rights reserved. + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * + * Authors: Max Holtzberg + * Gregory Nutt + * + * This code is derived from drivers/mtd/skeleton.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip.h" + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TIVA_VIRTUAL_NPAGES (TIVA_FLASH_NPAGES - CONFIG_TIVA_FLASH_STARTPAGE) +#define TIVA_VIRTUAL_BASE (TIVA_FLASH_BASE \ + + CONFIG_TIVA_FLASH_STARTPAGE * TIVA_FLASH_PAGESIZE) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type represents the state of the MTD device. The struct mtd_dev_s + * must appear at the beginning of the definition so that you can freely + * cast between pointers to struct mtd_dev_s and struct tiva_dev_s. + */ + +struct tiva_dev_s +{ + struct mtd_dev_s mtd; + + /* Other implementation specific data may follow here */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* MTD driver methods */ + +static int tiva_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t tiva_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t tiva_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t tiva_read(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buf); +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t tiva_write(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buf); +#endif +static int tiva_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This structure holds the state of the MTD driver */ + +static struct tiva_dev_s g_lmdev = +{ + { + tiva_erase, + tiva_bread, + tiva_bwrite, + tiva_read, +#ifdef CONFIG_MTD_BYTE_WRITE + tiva_write, +#endif + tiva_ioctl + }, + /* Initialization of any other implementation specific data goes here */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_erase + * + * Description: + * Erase several blocks, each of the size previously reported. + * + ****************************************************************************/ + +static int tiva_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks) +{ + int curpage; + uint32_t pageaddr; + + DEBUGASSERT(nblocks <= TIVA_VIRTUAL_NPAGES); + + for (curpage = startblock; curpage < nblocks; curpage++) + { + pageaddr = TIVA_VIRTUAL_BASE + curpage * TIVA_FLASH_PAGESIZE; + + fvdbg("Erase page at %08x\n", pageaddr); + + /* set page address */ + + putreg32((pageaddr << FLASH_FMA_OFFSET_SHIFT) & FLASH_FMA_OFFSET_MASK, + TIVA_FLASH_FMA); + + /* set flash write key and erase bit */ + + putreg32(FLASH_FMC_WRKEY | FLASH_FMC_ERASE, TIVA_FLASH_FMC); + + /* wait until erase has finished */ + + while (getreg32(TIVA_FLASH_FMC) & FLASH_FMC_ERASE); + } + + return OK; +} + +/**************************************************************************** + * Name: tiva_bread + * + * Description: + * Read the specified number of blocks into the user provided buffer. + * + ****************************************************************************/ + +static ssize_t tiva_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, + FAR uint8_t *buf) +{ + DEBUGASSERT(startblock + nblocks <= TIVA_VIRTUAL_NPAGES); + + memcpy(buf, (void *)(TIVA_VIRTUAL_BASE + startblock * TIVA_FLASH_PAGESIZE), + nblocks * TIVA_FLASH_PAGESIZE); + + return nblocks; +} + +/**************************************************************************** + * Name: tiva_bwrite + * + * Description: + * Write the specified number of blocks from the user provided buffer. + * + ****************************************************************************/ + +static ssize_t tiva_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, + FAR const uint8_t *buf) +{ + FAR uint32_t *src = (uint32_t *)buf; + FAR uint32_t *dst = (uint32_t *)(TIVA_VIRTUAL_BASE + startblock * TIVA_FLASH_PAGESIZE); + int i; + + DEBUGASSERT(nblocks <= TIVA_VIRTUAL_NPAGES); + + for (i = 0; i < (nblocks * TIVA_FLASH_PAGESIZE) >> 2; i++) + { + /* set data to write */ + + putreg32(*src++, TIVA_FLASH_FMD); + + /* set destination address */ + + putreg32((uint32_t)dst++, TIVA_FLASH_FMA); + + /* start write */ + + putreg32(FLASH_FMC_WRKEY | FLASH_FMC_WRITE, TIVA_FLASH_FMC); + + /* wait until write has finished */ + + while (getreg32(TIVA_FLASH_FMC) & FLASH_FMC_WRITE); + } + + return nblocks; +} + +/**************************************************************************** + * Name: tiva_read + * + * Description: + * Read the specified number of bytes to the user provided buffer. + * + ****************************************************************************/ + +static ssize_t tiva_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR uint8_t *buf) +{ + DEBUGASSERT(offset + nbytes < TIVA_VIRTUAL_NPAGES * TIVA_FLASH_PAGESIZE); + + memcpy(buf, (void *)(TIVA_VIRTUAL_BASE + offset), nbytes); + + return nbytes; +} + +/**************************************************************************** + * Name: tiva_write + * + * Description: + * Some FLASH parts have the ability to write an arbitrary number of + * bytes to an arbitrary offset on the device. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t tiva_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR const uint8_t *buf) +{ + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: tiva_ioctl + ****************************************************************************/ + +static int tiva_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) +{ + int ret = -EINVAL; /* Assume good command with bad parameters */ + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg; + if (geo) + { + /* Populate the geometry structure with information needed to know + * the capacity and how to access the device. + * + * NOTE: that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but the client + * will expect the device logic to do whatever is necessary to make it + * appear so. + */ + + geo->blocksize = TIVA_FLASH_PAGESIZE; /* Size of one read/write block */ + geo->erasesize = TIVA_FLASH_PAGESIZE; /* Size of one erase block */ + geo->neraseblocks = TIVA_VIRTUAL_NPAGES; + ret = OK; + } + } + break; + + case MTDIOC_XIPBASE: + { + FAR void **ppv = (FAR void**)arg; + + if (ppv) + { + /* If media is directly acccesible, return (void*) base address + * of device memory. NULL otherwise. It is acceptable to omit + * this case altogether and simply return -ENOTTY. + */ + + *ppv = (void *)TIVA_VIRTUAL_BASE; + ret = OK; + } + } + break; + + case MTDIOC_BULKERASE: + { + /* Erase the entire device */ + + tiva_erase(dev, 0, TIVA_VIRTUAL_NPAGES); + + ret = OK; + } + break; + + default: + ret = -ENOTTY; /* Bad command */ + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_initialize + * + * Description: + * Create and initialize an MTD device instance. MTD devices are not + * registered in the file system, but are created as instances that can + * be bound to other functions (such as a block or character driver front + * end). + * + ****************************************************************************/ + +FAR struct mtd_dev_s *up_flashinitialize(void) +{ + /* Return the implementation-specific state structure as the MTD device */ + + return (FAR struct mtd_dev_s *)&g_lmdev; +} diff --git a/arch/arm/src/tiva/tiva_gpio.c b/arch/arm/src/tiva/tiva_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..1ca011909a6a4e8d8abb2294999669832a6b9838 --- /dev/null +++ b/arch/arm/src/tiva/tiva_gpio.c @@ -0,0 +1,1006 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_gpio.c + * + * Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" +#include "tiva_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* These definitions are part of the implementation of the GPIO pad + * configuration of Table 9-1 in the LM3S6918 data sheet. + */ + +#define AMSEL_SHIFT 6 +#define AMSEL_1 (1 << AMSEL_SHIFT) /* Set/clear bit in GPIO AMSEL register */ +#define AMSEL_0 0 +#define AMSEL_X 0 + +#define AFSEL_SHIFT 5 +#define AFSEL_1 (1 << AFSEL_SHIFT) /* Set/clear bit in GPIO AFSEL register */ +#define AFSEL_0 0 +#define AFSEL_X 0 + +#define DIR_SHIFT 4 +#define DIR_1 (1 << DIR_SHIFT) /* Set/clear bit in GPIO DIR register */ +#define DIR_0 0 +#define DIR_X 0 + +#define ODR_SHIFT 3 +#define ODR_1 (1 << ODR_SHIFT) /* Set/clear bit in GPIO ODR register */ +#define ODR_0 0 +#define ODR_X 0 + +#define DEN_SHIFT 2 +#define DEN_1 (1 << DEN_SHIFT) /* Set/clear bit in GPIO DEN register */ +#define DEN_0 0 +#define DEN_X 0 + +#define PUR_SHIFT 1 +#define PUR_1 (1 << PUR_SHIFT) /* Set/clear bit in GPIO PUR register */ +#define PUR_0 0 +#define PUR_X 0 + +#define PDR_SHIFT 0 +#define PDR_1 (1 << PDR_SHIFT) /* Set/clear bit in GPIO PDR register */ +#define PDR_0 0 +#define PDR_X 0 + +#define GPIO_INPUT_SETBITS (AMSEL_0 | AFSEL_0 | DIR_0 | ODR_0 | DEN_1 | PUR_X | PDR_X) +#define GPIO_INPUT_CLRBITS (AMSEL_1 | AFSEL_1 | DIR_1 | ODR_1 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_OUTPUT_SETBITS (AMSEL_0 | AFSEL_0 | DIR_1 | ODR_0 | DEN_1 | PUR_X | PDR_X) +#define GPIO_OUTPUT_CLRBITS (AMSEL_1 | AFSEL_1 | DIR_0 | ODR_1 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_ODINPUT_SETBITS (AMSEL_0 | AFSEL_0 | DIR_0 | ODR_1 | DEN_1 | PUR_X | PDR_X) +#define GPIO_ODINPUT_CLRBITS (AMSEL_1 | AFSEL_1 | DIR_1 | ODR_0 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_ODOUTPUT_SETBITS (AMSEL_0 | AFSEL_0 | DIR_1 | ODR_1 | DEN_1 | PUR_X | PDR_X) +#define GPIO_ODOUTPUT_CLRBITS (AMSEL_1 | AFSEL_1 | DIR_0 | ODR_0 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_PFODIO_SETBITS (AMSEL_0 | AFSEL_1 | DIR_X | ODR_1 | DEN_1 | PUR_X | PDR_X) +#define GPIO_PFODIO_CLRBITS (AMSEL_1 | AFSEL_0 | DIR_X | ODR_0 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_PFIO_SETBITS (AMSEL_0 | AFSEL_1 | DIR_X | ODR_0 | DEN_1 | PUR_X | PDR_X) +#define GPIO_PFIO_CLRBITS (AMSEL_1 | AFSEL_0 | DIR_X | ODR_1 | DEN_0 | PUR_X | PDR_X) + +#define GPIO_ANINPUT_SETBITS (AMSEL_1 | AFSEL_0 | DIR_0 | ODR_0 | DEN_0 | PUR_0 | PDR_0) +#define GPIO_ANINPUT_CLRBITS (AMSEL_0 | AFSEL_1 | DIR_1 | ODR_1 | DEN_1 | PUR_1 | PDR_1) + +#define GPIO_INTERRUPT_SETBITS (AMSEL_0 | AFSEL_0 | DIR_0 | ODR_0 | DEN_1 | PUR_X | PDR_X) +#define GPIO_INTERRUPT_CLRBITS (AMSEL_1 | AFSEL_1 | DIR_1 | ODR_1 | DEN_0 | PUR_X | PDR_X) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct gpio_func_s +{ + uint8_t setbits; /* A set of GPIO register bits to set */ + uint8_t clrbits; /* A set of GPIO register bits to clear */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gpio_func_s g_funcbits[] = +{ + {GPIO_INPUT_SETBITS, GPIO_INPUT_CLRBITS}, /* GPIO_FUNC_INPUT */ + {GPIO_OUTPUT_SETBITS, GPIO_OUTPUT_CLRBITS}, /* GPIO_FUNC_OUTPUT */ + {GPIO_ODINPUT_SETBITS, GPIO_ODINPUT_CLRBITS}, /* GPIO_FUNC_ODINPUT */ + {GPIO_ODOUTPUT_SETBITS, GPIO_ODOUTPUT_CLRBITS}, /* GPIO_FUNC_ODOUTPUT */ + {GPIO_PFODIO_SETBITS, GPIO_PFODIO_CLRBITS}, /* GPIO_FUNC_PFODIO */ + {GPIO_PFIO_SETBITS, GPIO_PFIO_CLRBITS}, /* GPIO_FUNC_PFIO */ + {GPIO_ANINPUT_SETBITS, GPIO_ANINPUT_CLRBITS}, /* GPIO_FUNC_ANINPUT */ + {GPIO_INTERRUPT_SETBITS, GPIO_INTERRUPT_CLRBITS}, /* GPIO_FUNC_INTERRUPT */ +}; + +/* NOTE: this is duplicated in tiva_dumpgpio.c */ + +static const uintptr_t g_gpiobase[TIVA_NPORTS] = +{ +#if TIVA_NPORTS > 0 + TIVA_GPIOA_BASE +#endif +#if TIVA_NPORTS > 1 + , TIVA_GPIOB_BASE +#endif +#if TIVA_NPORTS > 2 + , TIVA_GPIOC_BASE +#endif +#if TIVA_NPORTS > 3 + , TIVA_GPIOD_BASE +#endif +#if TIVA_NPORTS > 4 + , TIVA_GPIOE_BASE +#endif +#if TIVA_NPORTS > 5 + , TIVA_GPIOF_BASE +#endif +#if TIVA_NPORTS > 6 + , TIVA_GPIOG_BASE +#endif +#if TIVA_NPORTS > 7 + , TIVA_GPIOH_BASE +#endif +#if TIVA_NPORTS > 8 + , TIVA_GPIOJ_BASE +#endif +#if TIVA_NPORTS > 9 + , TIVA_GPIOK_BASE +#endif +#if TIVA_NPORTS > 10 + , TIVA_GPIOL_BASE +#endif +#if TIVA_NPORTS > 11 + , TIVA_GPIOM_BASE +#endif +#if TIVA_NPORTS > 12 + , TIVA_GPION_BASE +#endif +#if TIVA_NPORTS > 13 + , TIVA_GPIOP_BASE +#endif +#if TIVA_NPORTS > 14 + , TIVA_GPIOQ_BASE +#endif +#if TIVA_NPORTS > 15 + , TIVA_GPIOR_BASE +#endif +#if TIVA_NPORTS > 16 + , TIVA_GPIOS_BASE +#endif +#if TIVA_NPORTS > 17 + , TIVA_GPIOT_BASE +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_gpiobaseaddress + * + * Description: + * Given a GPIO enumeration value, return the base address of the + * associated GPIO registers. + * + ****************************************************************************/ + +inline uintptr_t tiva_gpiobaseaddress(unsigned int port) +{ + uintptr_t gpiobase = 0; + if (port < TIVA_NPORTS) + { + gpiobase = g_gpiobase[port]; + } + + return gpiobase; +} + +/**************************************************************************** + * Name: tiva_gpiofunc + * + * Description: + * Configure GPIO registers for a specific function. Overwrites certain + * padtype configurations. + * + ****************************************************************************/ + +static void tiva_gpiofunc(uint32_t base, uint32_t pinno, + const struct gpio_func_s *func) +{ + uint32_t setbit; + uint32_t clrbit; + + /* Set/clear/ignore the GPIO DIR bit. "The GPIODIR register is the data + * direction register. Bits set to 1 in the GPIODIR register configure + * the corresponding pin to be an output, while bits set to 0 configure + * the pins to be inputs. All bits are cleared by a reset, meaning all + * GPIO pins are inputs by default. + */ + + setbit = (((uint32_t)func->setbits >> DIR_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> DIR_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_DIR_OFFSET, clrbit, setbit); + } + + /* Set/clear/ignore the GPIO AFSEL bit. "The GPIOAFSEL register is the + * mode control select register. Writing a 1 to any bit in this register + * selects the hardware control for the corresponding GPIO line. All bits + * are cleared by a reset, therefore no GPIO line is set to hardware + * control by default." + * + * NOTE: In order to set JTAG/SWD GPIOs, it is also necessary to lock, + * commit and unlock the GPIO. That is not implemented here. + */ + + setbit = (((uint32_t)func->setbits >> AFSEL_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> AFSEL_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_AFSEL_OFFSET, clrbit, setbit); + } + + /* Set/clear/ignore the GPIO ODR bit. "The GPIO ODR register is the open + * drain control register. Setting a bit in this register enables the open + * drain configuration of the corresponding GPIO pad. When open drain mode + * is enabled, the corresponding bit should also be set in the GPIO Digital + * Input Enable (GPIO DEN) register ... Corresponding bits in the drive + * strength registers (GPIO DR2R, GPIO DR4R, GPIO DR8R, and GPIO SLR ) can + * be set to achieve the desired rise and fall times. The GPIO acts as an + * open drain input if the corresponding bit in the GPIO DIR register is + * set to 0; and as an open drain output when set to 1." + */ + + setbit = (((uint32_t)func->setbits >> ODR_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> ODR_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_ODR_OFFSET, clrbit, setbit); + } + + /* Set/clear the GPIO PUR bit. "The GPIOPUR register is the pull-up + * control register. When a bit is set to 1, it enables a weak pull-up + * resistor on the corresponding GPIO signal. Setting a bit in GPIOPUR + * automatically clears the corresponding bit in the GPIO Pull-Down + * Select (GPIOPDR) register ..." + */ + + setbit = (((uint32_t)func->setbits >> PUR_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> PUR_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_PUR_OFFSET, clrbit, setbit); + } + + /* Set/clear the GPIO PDR bit. "The GPIOPDR register is the pull-down + * control register. When a bit is set to 1, it enables a weak pull-down + * resistor on the corresponding GPIO signal. Setting a bit in GPIOPDR + * automatically clears the corresponding bit in the GPIO Pull-Up Select + * (GPIOPUR) register ..." + */ + + setbit = (((uint32_t)func->setbits >> PDR_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> PDR_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_PDR_OFFSET, clrbit, setbit); + } + + /* Set/clear the GPIO DEN bit. "The GPIODEN register is the digital enable + * register. By default, with the exception of the GPIO signals used for + * JTAG/SWD function, all other GPIO signals are configured out of reset + * to be undriven (tristate). Their digital function is disabled; they do + * not drive a logic value on the pin and they do not allow the pin voltage + * into the GPIO receiver. To use the pin in a digital function (either + * GPIO or alternate function), the corresponding GPIODEN bit must be set." + */ + + setbit = (((uint32_t)func->setbits >> DEN_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> DEN_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_DEN_OFFSET, clrbit, setbit); + } + +#if defined(LM4F) || defined(TM4C) + /* Set/clear/ignore the GPIO AMSEL bit. "The GPIOAMSEL register controls + * isolation circuits to the analog side of a unified I/O pad. Because + * the GPIOs may be driven by a 5-V source and affect analog operation, + * analog circuitry requires isolation from the pins when they are not + * used in their analog function. Each bit of this register controls the + * isolation circuitry for the corresponding GPIO signal. + */ + + setbit = (((uint32_t)func->setbits >> AMSEL_SHIFT) & 1) << pinno; + clrbit = (((uint32_t)func->clrbits >> AMSEL_SHIFT) & 1) << pinno; + + if (setbit || clrbit) + { + modifyreg32(base + TIVA_GPIO_AMSEL_OFFSET, clrbit, setbit); + } +#endif +} + +/**************************************************************************** + * Name: tiva_gpiopadstrength + * + * Description: + * Set up pad strength and pull-ups + * + ****************************************************************************/ + +static inline void tiva_gpiopadstrength(uint32_t base, uint32_t pin, + uint32_t pinset) +{ + int strength = (pinset & GPIO_STRENGTH_MASK); + uint32_t slrset = 0; + uint32_t slrclr = 0; + uint32_t dr2rset = 0; + uint32_t dr2rclr = 0; + uint32_t dr4rset = 0; + uint32_t dr4rclr = 0; + uint32_t dr8rset = 0; + uint32_t dr8rclr = 0; + + /* Set the output drive strength. */ + + switch (strength) + { + case GPIO_STRENGTH_2MA: + { + dr2rset = pin; + dr4rclr = pin; + dr8rclr = pin; + slrclr = pin; + } + break; + + case GPIO_STRENGTH_4MA: + { + dr2rclr = pin; + dr4rset = pin; + dr8rclr = pin; + slrclr = pin; + } + break; + + case GPIO_STRENGTH_8MA: + { + dr2rclr = pin; + dr4rclr = pin; + dr8rset = pin; + slrclr = pin; + } + break; + + case GPIO_STRENGTH_8MASC: + { + dr2rclr = pin; + dr4rclr = pin; + dr8rset = pin; + slrset = pin; + } + break; + +#ifdef CONFIG_ARCH_CHIP_TM4C129 +# if 0 + case GPIO_STRENGTH_10MA: + { + } + break; + + case GPIO_STRENGTH_10MASC: + { + } + break; + + case GPIO_STRENGTH_12MA: + { + } + break; + + case GPIO_STRENGTH_12MASC: + { + } + break; + +# endif +#endif + default: + break; + } + + modifyreg32(base + TIVA_GPIO_DR2R_OFFSET, dr2rclr, dr2rset); + modifyreg32(base + TIVA_GPIO_DR4R_OFFSET, dr4rclr, dr4rset); + modifyreg32(base + TIVA_GPIO_DR8R_OFFSET, dr8rclr, dr8rset); + modifyreg32(base + TIVA_GPIO_SLR_OFFSET, slrclr, slrset); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* TODO: Add TM4C129 registers (TIVA_GPIO_DR12R) */ +# if 0 + /* Set the 12-mA drive select register. This register only appears in + * TM4E111 and later device classes, but is a harmless write on older + * devices. + */ + + /* Set the GPIO peripheral configuration register first as required. This + * register only appears in TM4E111 and later device classes, but is a + * harmless write on older devices. Walk pins 0-7 and clear or set the + * provided PC[EDMn] encoding. + */ +# endif // 0 +#endif +} + +/**************************************************************************** + * Name: tiva_gpiopadtype + * + * Description: + * Set up pad strength and pull-ups. Some of these values may be over- + * written by tiva_gpiofunc, depending on the function selection. Others + * are optional for different function selections. + * + ****************************************************************************/ + +static inline void tiva_gpiopadtype(uint32_t base, uint32_t pin, + uint32_t pinset) +{ + int padtype = (pinset & GPIO_PADTYPE_MASK); + uint32_t odrset = 0; + uint32_t odrclr = 0; + uint32_t purset = 0; + uint32_t purclr = 0; + uint32_t pdrset = 0; + uint32_t pdrclr = 0; + uint32_t denset = 0; + uint32_t denclr = 0; +#if defined(LM4F) || defined(TM4C) + uint32_t amselset = 0; + uint32_t amselclr = 0; +#endif + + /* Set the pin type. */ + + switch (padtype) + { + case GPIO_PADTYPE_STD: + { + odrclr = pin; + purclr = pin; + pdrclr = pin; + denset = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_STDWPU: + { + odrclr = pin; + purset = pin; + pdrclr = pin; + denset = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_STDWPD: + { + odrclr = pin; + purclr = pin; + pdrset = pin; + denset = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_OD: + { + odrset = pin; + purclr = pin; + pdrclr = pin; + denset = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_ODWPU: + { + odrset = pin; + purset = pin; + pdrclr = pin; + denclr = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_ODWPD: + { + odrset = pin; + purclr = pin; + pdrset = pin; + denclr = pin; +#if defined(LM4F) || defined(TM4C) + amselclr = pin; +#endif + } + break; + + case GPIO_PADTYPE_ANALOG: + { + odrclr = pin; + purclr = pin; + pdrclr = pin; + denclr = pin; +#if defined(LM4F) || defined(TM4C) + amselset = pin; +#endif + } + break; + + default: + break; + } + + modifyreg32(base + TIVA_GPIO_ODR_OFFSET, odrclr, odrset); + modifyreg32(base + TIVA_GPIO_PUR_OFFSET, purclr, purset); + modifyreg32(base + TIVA_GPIO_PDR_OFFSET, pdrclr, pdrset); + modifyreg32(base + TIVA_GPIO_DEN_OFFSET, denclr, denset); + +#if defined(LM4F) || defined(TM4C) + modifyreg32(base + TIVA_GPIO_AMSEL_OFFSET, amselclr, amselset); +#endif + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Set the wake pin enable register and the wake level register. These + * registers only appear in TM4E111 and later device classes, but are + * harmless writes on older devices. + */ +#endif +} + +/**************************************************************************** + * Name: tiva_initoutput + * + * Description: + * Set the GPIO output value + * + ****************************************************************************/ + +static inline void tiva_initoutput(uint32_t pinset) +{ + bool value = ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO); + tiva_gpiowrite(pinset, value); +} + +/**************************************************************************** + * Name: tiva_interrupt + * + * Description: + * Configure the interrupt pin. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_GPIO_IRQS +static inline void tiva_interrupt(uint32_t pinset) +{ + uint8_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + uint8_t pin = 1 << (pinset & GPIO_PIN_MASK); + uintptr_t base = tiva_gpiobaseaddress(port); + uint32_t inttype = pinset & GPIO_INT_MASK; + + uint32_t isset = 0; + uint32_t ibeset = 0; + uint32_t ievset = 0; + uint32_t isclr = 0; + uint32_t ibeclr = 0; + uint32_t ievclr = 0; + + /* Mask and clear the GPIO interrupt */ + + tiva_gpioirqdisable(port, pin); + tiva_gpioirqclear(port, pin); + + /* handle according to the selected interrupt type */ + + switch (inttype) + { + case GPIO_INT_FALLINGEDGE: + { + isset = pin; + ibeclr = pin; + ievset = pin; + } + break; + + case GPIO_INT_RISINGEDGE: + { + isclr = pin; + ibeclr = pin; + ievset = pin; + } + break; + + case GPIO_INT_BOTHEDGES: + { + isclr = pin; + ibeset = pin; + ievclr = pin; + } + break; + + case GPIO_INT_LOWLEVEL: + { + isset = pin; + ibeclr = pin; + ievclr = pin; + } + break; + + case GPIO_INT_HIGHLEVEL: + { + isset = pin; + ibeclr = pin; + ievset = pin; + } + break; + + default: + break; + } + + /* "The GPIO IBE register is the interrupt both-edges register. When the + * corresponding bit in the GPIO Interrupt Sense (GPIO IS) register ... is + * set to detect edges, bits set to High in GPIO IBE configure the + * corresponding pin to detect both rising and falling edges, regardless + * of the corresponding bit in the GPIO Interrupt Event (GPIO IEV) register ... + * Clearing a bit configures the pin to be controlled by GPIOIEV. All bits + * are cleared by a reset. + */ + + modifyreg32(base + TIVA_GPIO_IBE_OFFSET, ibeclr, ibeset); + + /* "The GPIO IS register is the interrupt sense register. Bits set to + * 1 in GPIOIS configure the corresponding pins to detect levels, while + * bits set to 0 configure the pins to detect edges. All bits are cleared + * by a reset. + */ + + modifyreg32(base + TIVA_GPIO_IS_OFFSET, isclr, isset); + + /* "The GPIOIEV register is the interrupt event register. Bits set to + * High in GPIO IEV configure the corresponding pin to detect rising edges + * or high levels, depending on the corresponding bit value in the GPIO + * Interrupt Sense (GPIO IS) register... Clearing a bit configures the pin to + * detect falling edges or low levels, depending on the corresponding bit + * value in GPIOIS. All bits are cleared by a reset. + */ + + modifyreg32(base + TIVA_GPIO_IEV_OFFSET, ievclr, ievset); + +#ifdef CONFIG_DEBUG_GPIO + uint32_t regval; + gpiovdbg("reg expected actual: [interrupt type=%d]\n", inttype); + regval = (getreg32(base+TIVA_GPIO_IS_OFFSET) & pin) ? pin : 0; + gpiovdbg("IS 0x%08x 0x%08x\n", isset, regval); + regval = (getreg32(base+TIVA_GPIO_IBE_OFFSET) & pin) ? pin : 0; + gpiovdbg("IBE 0x%08x 0x%08x\n", ibeset, regval); + regval = (getreg32(base+TIVA_GPIO_IEV_OFFSET) & pin) ? pin : 0; + gpiovdbg("IEV 0x%08x 0x%08x\n", ievset, regval); +#endif +} +#endif + +/**************************************************************************** + * Name: tiva_portcontrol + * + * Description: + * Set the pin alternate function in the port control register. + * + ****************************************************************************/ + +#if defined(LM4F) || defined(TM4C) +static inline void tiva_portcontrol(uint32_t base, uint32_t pinno, + uint32_t pinset, + const struct gpio_func_s *func) +{ + uint32_t alt = 0; + uint32_t mask; + uint32_t regval; + + /* Is this pin an alternate function pin? */ + + if ((func->setbits & AFSEL_1) != 0) + { + /* Yes, extract the alternate function number from the pin + * configuration. + */ + + alt = (pinset & GPIO_ALT_MASK) >> GPIO_ALT_SHIFT; + } + + /* Set the alternate function in the port control register */ + + regval = getreg32(base + TIVA_GPIO_PCTL_OFFSET); + mask = GPIO_PCTL_PMC_MASK(pinno); + regval &= ~mask; + regval |= (alt << GPIO_PCTL_PMC_SHIFT(pinno)) & mask; + putreg32(regval, base + TIVA_GPIO_PCTL_OFFSET); +} +#else +# define tiva_portcontrol(b,p,c,f) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int tiva_configgpio(uint32_t pinset) +{ + irqstate_t flags; + unsigned int func; + unsigned int port; + unsigned int pinno; + uintptr_t base; + uint32_t pin; + + /* Decode the basics */ + + func = (pinset & GPIO_FUNC_MASK) >> GPIO_FUNC_SHIFT; + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pinno = (pinset & GPIO_PIN_MASK); + pin = (1 << pinno); + + DEBUGASSERT(func <= GPIO_FUNC_MAX); + + /* Get the base address associated with the GPIO port */ + + base = tiva_gpiobaseaddress(port); + DEBUGASSERT(base != 0); + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + + /* Enable power and clocking for this GPIO peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the GPIO + * peripheral. This is not an essential step since enabling clocking + * will also apply power. The only significance is that the GPIO state + * will be retained if the GPIO clocking is subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking to + * the GPIO peripheral, bringing it a fully functional state. + */ + + tiva_gpio_enablepwr(port); + tiva_gpio_enableclk(port); + + /* First, set the port to digital input. This is the safest state in which + * to perform reconfiguration. + */ + + tiva_gpiofunc(base, pinno, &g_funcbits[0]); + tiva_portcontrol(base, pinno, pinset, &g_funcbits[0]); + + /* Then set up pad strengths and pull-ups. These setups should be done before + * setting up the function because some function settings will over-ride these + * user options. + */ + + tiva_gpiopadstrength(base, pin, pinset); + tiva_gpiopadtype(base, pin, pinset); + + /* Then set up the real pin function */ + + tiva_gpiofunc(base, pinno, &g_funcbits[func]); + tiva_portcontrol(base, pinno, pinset, &g_funcbits[func]); + + /* Special case GPIO digital output pins */ + + if (func == 1 || func == 3 || func == 5) + { + tiva_initoutput(pinset); + } + +#ifdef CONFIG_TIVA_GPIO_IRQS + /* Special setup for interrupt GPIO pins */ + + else if (func == 7) + { + tiva_interrupt(pinset); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: tiva_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void tiva_gpiowrite(uint32_t pinset, bool value) +{ + unsigned int port; + unsigned int pinno; + uintptr_t base; + + /* Decode the basics */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pinno = (pinset & GPIO_PIN_MASK); + + /* Get the base address associated with the GPIO port */ + + base = tiva_gpiobaseaddress(port); + + /* "The GPIO DATA register is the data register. In software control mode, + * values written in the GPIO DATA register are transferred onto the GPIO + * port pins if the respective pins have been configured as outputs through + * the GPIO Direction (GPIO DIR) register ... + * + * "In order to write to GPIO DATA, the corresponding bits in the mask, + * resulting from the address bus bits [9:2], must be High. Otherwise, the + * bit values remain unchanged by the write. + * + * "... All bits are cleared by a reset." + */ + + putreg32((uint32_t)value << pinno, base + TIVA_GPIO_DATA_OFFSET + (1 << (pinno + 2))); +} + +/**************************************************************************** + * Name: tiva_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool tiva_gpioread(uint32_t pinset) +{ + unsigned int port; + unsigned int pinno; + uintptr_t base; + + /* Decode the basics */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pinno = (pinset & GPIO_PIN_MASK); + + /* Get the base address associated with the GPIO port */ + + base = tiva_gpiobaseaddress(port); + + /* "... the values read from this register are determined for each bit + * by the mask bit derived from the address used to access the data register, + * bits [9:2]. Bits that are 1 in the address mask cause the corresponding + * bits in GPIODATA to be read, and bits that are 0 in the address mask cause + * the corresponding bits in GPIO DATA to be read as 0, regardless of their + * value. + * + * "A read from GPIO DATA returns the last bit value written if the respective + * pins are configured as outputs, or it returns the value on the + * corresponding input pin when these are configured as inputs. All bits + * are cleared by a reset." + */ + return (getreg32(base + TIVA_GPIO_DATA_OFFSET + (1 << (pinno + 2))) != 0); +} + +/**************************************************************************** + * Name: tiva_gpio_lockport + * + * Description: + * Certain pins require to be unlocked from the NMI to use for normal GPIO + * use. See table 10-10 in datasheet for pins with special considerations. + * + ****************************************************************************/ + +void tiva_gpio_lockport(uint32_t pinset, bool lock) +{ + unsigned int port; + unsigned int pinno; + uintptr_t base; + uint32_t pinmask; + + /* Decode the basics */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pinno = (pinset & GPIO_PIN_MASK); + pinmask = 1 << pinno; + + /* Get the base address associated with the GPIO port */ + + base = tiva_gpiobaseaddress(port); + + /* allow access to the TIVA_GPIO_CR_OFFSET register */ + + modifyreg32(base + TIVA_GPIO_LOCK_OFFSET, 0, GPIO_LOCK_UNLOCK); + + /* lock or unlock the pin */ + + if (lock) + { +#ifdef CONFIG_DEBUG_GPIO + gpiovdbg(" locking port=%d pin=%d\n", port, pinno); +#endif + modifyreg32(base + TIVA_GPIO_CR_OFFSET, pinmask, 0); + } + else + { +#ifdef CONFIG_DEBUG_GPIO + gpiovdbg("unlocking port=%d pin=%d\n", port, pinno); +#endif + modifyreg32(base + TIVA_GPIO_CR_OFFSET, 0, pinmask); + } + + /* Restrict access to the TIVA_GPIO_CR_OFFSET register */ + + modifyreg32(base + TIVA_GPIO_LOCK_OFFSET, GPIO_LOCK_UNLOCK, GPIO_LOCK_LOCKED); +} diff --git a/arch/arm/src/tiva/tiva_gpio.h b/arch/arm/src/tiva/tiva_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..12b466042e35f3eac46e73555ba0f9bf045af50c --- /dev/null +++ b/arch/arm/src/tiva/tiva_gpio.h @@ -0,0 +1,504 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_gpio.h + * + * Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * With modifications from Calvin Maguranis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_GPIO_H +#define __ARCH_ARM_SRC_TIVA_TIVA_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_LM3S) || defined(CONFIG_ARCH_CHIP_LM4F) || \ + defined(CONFIG_ARCH_CHIP_CC3200) + + /* I don't believe that any of these families support interrupts on port J. Many + * do not support interrupts on port H either. + */ + +# undef CONFIG_TIVA_GPIOJ_IRQS + +#elif defined(CONFIG_ARCH_CHIP_TM4C) + +/* The TM4C123GH6PMI supports ports A-F of which any can support interrupts */ + +# if defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI) +# undef CONFIG_TIVA_GPIOP_IRQS /* P-Q */ +# undef CONFIG_TIVA_GPIOQ_IRQS + +/* The TM4C123GH6PGE supports interrupts only on port P */ + +# elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PGE) +# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */ +# undef CONFIG_TIVA_GPIOB_IRQS +# undef CONFIG_TIVA_GPIOC_IRQS +# undef CONFIG_TIVA_GPIOD_IRQS +# undef CONFIG_TIVA_GPIOE_IRQS +# undef CONFIG_TIVA_GPIOF_IRQS + +# undef CONFIG_TIVA_GPIOQ_IRQS /* Q */ + +/* The TM4C123GH6ZRB and the TM4C129x support interrupts only on ports P and Q. */ + +# else +# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */ +# undef CONFIG_TIVA_GPIOB_IRQS +# undef CONFIG_TIVA_GPIOC_IRQS +# undef CONFIG_TIVA_GPIOD_IRQS +# undef CONFIG_TIVA_GPIOE_IRQS +# undef CONFIG_TIVA_GPIOF_IRQS + +# endif + +/* No supported architecture supports interrupts on ports G-N or R-T */ + +# undef CONFIG_TIVA_GPIOG_IRQS /* G-N */ +# undef CONFIG_TIVA_GPIOH_IRQS +# undef CONFIG_TIVA_GPIOJ_IRQS +# undef CONFIG_TIVA_GPIOK_IRQS +# undef CONFIG_TIVA_GPIOL_IRQS +# undef CONFIG_TIVA_GPIOM_IRQS +# undef CONFIG_TIVA_GPION_IRQS + +# undef CONFIG_TIVA_GPIOR_IRQS /* R-T */ +# undef CONFIG_TIVA_GPIOS_IRQS +# undef CONFIG_TIVA_GPIOT_IRQS + +#endif + +/* Mark GPIO interrupts as disabled for non-existent GPIO ports. */ + +#if TIVA_NPORTS < 1 +# undef CONFIG_TIVA_GPIOA_IRQS +#endif +#if TIVA_NPORTS < 2 +# undef CONFIG_TIVA_GPIOB_IRQS +#endif +#if TIVA_NPORTS < 3 +# undef CONFIG_TIVA_GPIOC_IRQS +#endif +#if TIVA_NPORTS < 4 +# undef CONFIG_TIVA_GPIOD_IRQS +#endif +#if TIVA_NPORTS < 5 +# undef CONFIG_TIVA_GPIOE_IRQS +#endif +#if TIVA_NPORTS < 6 +# undef CONFIG_TIVA_GPIOF_IRQS +#endif +#if TIVA_NPORTS < 7 +# undef CONFIG_TIVA_GPIOG_IRQS +#endif +#if TIVA_NPORTS < 8 +# undef CONFIG_TIVA_GPIOH_IRQS +#endif +#if TIVA_NPORTS < 9 +# undef CONFIG_TIVA_GPIOJ_IRQS +#endif +#if TIVA_NPORTS < 10 +# undef CONFIG_TIVA_GPIOK_IRQS +#endif +#if TIVA_NPORTS < 11 +# undef CONFIG_TIVA_GPIOL_IRQS +#endif +#if TIVA_NPORTS < 12 +# undef CONFIG_TIVA_GPIOM_IRQS +#endif +#if TIVA_NPORTS < 13 +# undef CONFIG_TIVA_GPION_IRQS +#endif +#if TIVA_NPORTS < 14 +# undef CONFIG_TIVA_GPIOP_IRQS +#endif +#if TIVA_NPORTS < 15 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 16 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 17 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif +#if TIVA_NPORTS < 18 +# undef CONFIG_TIVA_GPIOQ_IRQS +#endif + +/* Bit-encoded input to tiva_configgpio() *******************************************/ + +/* Encoding: + * + * LM3S: FFFS SPPP III. .... .... ...V PPPP PBBB + * LM4F: FFFS SPPP III. AAAA .... ...V PPPP PBBB + * TM4C: FFFS SPPP III. AAAA .... ...V PPPP PBBB + * + * TODO: The LM4F/TM4C also support configuration of pins to trigger ADC and/or uDMA. + * That configuration is not addressed in this this encoding. + */ + +/* These bits set the primary function of the pin: + * + * FFFn .... .... .... .... .... .... .... + */ + +#define GPIO_FUNC_SHIFT 29 /* Bit 31-29: GPIO function */ +#define GPIO_FUNC_MASK (7 << GPIO_FUNC_SHIFT) /* (See table 9-1 in data sheet) */ +# define GPIO_FUNC_INPUT (0 << GPIO_FUNC_SHIFT) /* Digital GPIO input */ +# define GPIO_FUNC_OUTPUT (1 << GPIO_FUNC_SHIFT) /* Digital GPIO output */ +# define GPIO_FUNC_ODINPUT (2 << GPIO_FUNC_SHIFT) /* Open-drain GPIO input */ +# define GPIO_FUNC_ODOUTPUT (3 << GPIO_FUNC_SHIFT) /* Open-drain GPIO output */ +# define GPIO_FUNC_PFODIO (4 << GPIO_FUNC_SHIFT) /* Open-drain input/output (I2C) */ +# define GPIO_FUNC_PFINPUT (5 << GPIO_FUNC_SHIFT) /* Digital input (Timer, CCP) */ +# define GPIO_FUNC_PFOUTPUT (5 << GPIO_FUNC_SHIFT) /* Digital output (Timer, PWM, Comparator) */ +# define GPIO_FUNC_PFIO (5 << GPIO_FUNC_SHIFT) /* Digital input/output (SSI, UART) */ +# define GPIO_FUNC_ANINPUT (6 << GPIO_FUNC_SHIFT) /* Analog input (ADC, Comparator) */ +# define GPIO_FUNC_ANIO (6 << GPIO_FUNC_SHIFT) /* REVISIT: Analog input/output (USB) */ +# define GPIO_FUNC_INTERRUPT (7 << GPIO_FUNC_SHIFT) /* Interrupt function */ +# define GPIO_FUNC_MAX GPIO_FUNC_INTERRUPT + +/* That primary may be modified by the following options + * + * ...S SPPP .... .... .... .... .... .... + */ + +#define GPIO_STRENGTH_SHIFT 27 /* Bits 28-27: Pad drive strength */ +#define GPIO_STRENGTH_MASK (3 << GPIO_STRENGTH_SHIFT) +# define GPIO_STRENGTH_2MA (0 << GPIO_STRENGTH_SHIFT) /* 2mA pad drive strength */ +# define GPIO_STRENGTH_4MA (1 << GPIO_STRENGTH_SHIFT) /* 4mA pad drive strength */ +# define GPIO_STRENGTH_8MA (2 << GPIO_STRENGTH_SHIFT) /* 8mA pad drive strength */ +# define GPIO_STRENGTH_8MASC (3 << GPIO_STRENGTH_SHIFT) /* 8mA Pad drive with slew rate control */ +# define GPIO_STRENGTH_MAX GPIO_STRENGTH_8MASC + +#define GPIO_PADTYPE_SHIFT 24 /* Bits 26-24: Pad type */ +#define GPIO_PADTYPE_MASK (7 << GPIO_PADTYPE_SHIFT) +# define GPIO_PADTYPE_STD (0 << GPIO_PADTYPE_SHIFT) /* Push-pull */ +# define GPIO_PADTYPE_STDWPU (1 << GPIO_PADTYPE_SHIFT) /* Push-pull with weak pull-up */ +# define GPIO_PADTYPE_STDWPD (2 << GPIO_PADTYPE_SHIFT) /* Push-pull with weak pull-down */ +# define GPIO_PADTYPE_OD (3 << GPIO_PADTYPE_SHIFT) /* Open-drain */ +# define GPIO_PADTYPE_ODWPU (4 << GPIO_PADTYPE_SHIFT) /* Open-drain with weak pull-up */ +# define GPIO_PADTYPE_ODWPD (5 << GPIO_PADTYPE_SHIFT) /* Open-drain with weak pull-down */ +# define GPIO_PADTYPE_ANALOG (6 << GPIO_PADTYPE_SHIFT) /* Analog comparator */ + +/* If the pin is an interrupt, then the following options apply + * + * .... .... III. .... .... .... .... .... + */ + +#define GPIO_INT_SHIFT 21 /* Bits 23-21: Interrupt type */ +#define GPIO_INT_MASK (7 << GPIO_INT_SHIFT) +# define GPIO_INT_FALLINGEDGE (0 << GPIO_INT_SHIFT) /* Interrupt on falling edge */ +# define GPIO_INT_RISINGEDGE (1 << GPIO_INT_SHIFT) /* Interrupt on rising edge */ +# define GPIO_INT_BOTHEDGES (2 << GPIO_INT_SHIFT) /* Interrupt on both edges */ +# define GPIO_INT_LOWLEVEL (3 << GPIO_INT_SHIFT) /* Interrupt on low level */ +# define GPIO_INT_HIGHLEVEL (4 << GPIO_INT_SHIFT) /* Interrupt on high level */ + +/* The LM4F/TM4C supports up to 15 alternate functions per pin: + * + * LM4F: .... .... .... AAAA .... .... .... .... + * TM4C: .... .... .... AAAA .... .... .... .... + */ + +#if defined(LM4F) || defined(TM4C) +# define GPIO_ALT_SHIFT 16 /* Bits 16-19: Alternate function */ +# define GPIO_ALT_MASK (15 << GPIO_ALT_SHIFT) +# define GPIO_ALT(n) ((n) << GPIO_ALT_SHIFT) +# define GPIO_ALT_NONE (0 << GPIO_ALT_SHIFT) +# define GPIO_ALT_1 (1 << GPIO_ALT_SHIFT) +# define GPIO_ALT_2 (2 << GPIO_ALT_SHIFT) +# define GPIO_ALT_3 (3 << GPIO_ALT_SHIFT) +# define GPIO_ALT_4 (4 << GPIO_ALT_SHIFT) +# define GPIO_ALT_5 (5 << GPIO_ALT_SHIFT) +# define GPIO_ALT_6 (6 << GPIO_ALT_SHIFT) +# define GPIO_ALT_7 (7 << GPIO_ALT_SHIFT) +# define GPIO_ALT_8 (8 << GPIO_ALT_SHIFT) +# define GPIO_ALT_9 (9 << GPIO_ALT_SHIFT) +# define GPIO_ALT_10 (10 << GPIO_ALT_SHIFT) +# define GPIO_ALT_11 (11 << GPIO_ALT_SHIFT) +# define GPIO_ALT_12 (12 << GPIO_ALT_SHIFT) +# define GPIO_ALT_13 (13 << GPIO_ALT_SHIFT) +# define GPIO_ALT_14 (14 << GPIO_ALT_SHIFT) +# define GPIO_ALT_15 (15 << GPIO_ALT_SHIFT) +#endif + +/* If the pin is an GPIO digital output, then this identifies the initial output value: + * .... .... .... .... .... ...V .... .... + */ + +#define GPIO_VALUE_SHIFT 8 /* Bit 8: If output, inital value of output */ +#define GPIO_VALUE_MASK (1 << GPIO_VALUE_SHIFT) +# define GPIO_VALUE_ZERO (0 << GPIO_VALUE_SHIFT) /* Initial value is zero */ +# define GPIO_VALUE_ONE (1 << GPIO_VALUE_SHIFT) /* Initial value is one */ + +/* This identifies the GPIO port + * .... .... .... .... .... .... .PPP P... + */ + +#define GPIO_PORT_SHIFT 3 /* Bit 3-7: Port number */ +#define GPIO_PORT_MASK (31 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ +# define GPIO_PORTJ (8 << GPIO_PORT_SHIFT) /* GPIOJ */ +# define GPIO_PORTK (9 << GPIO_PORT_SHIFT) /* GPIOK */ +# define GPIO_PORTL (10 << GPIO_PORT_SHIFT) /* GPIOL */ +# define GPIO_PORTM (11 << GPIO_PORT_SHIFT) /* GPIOM */ +# define GPIO_PORTN (12 << GPIO_PORT_SHIFT) /* GPION */ +# define GPIO_PORTP (13 << GPIO_PORT_SHIFT) /* GPIOP */ +# define GPIO_PORTQ (14 << GPIO_PORT_SHIFT) /* GPIOQ */ +# define GPIO_PORTR (15 << GPIO_PORT_SHIFT) /* GPIOR */ +# define GPIO_PORTS (16 << GPIO_PORT_SHIFT) /* GPIOS */ +# define GPIO_PORTT (17 << GPIO_PORT_SHIFT) /* GPIOT */ + +/* This identifies the pin number in the port: + * .... .... .... .... .... .... .... .BBB + */ + +#define GPIO_PIN_SHIFT 0 /* Bits 0-2: GPIO pin: 0-7 */ +#define GPIO_PIN_MASK (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN_0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN_1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN_2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN_3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN_4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN_5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN_6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN_7 (7 << GPIO_PIN_SHIFT) + +/* Debug ********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GPIO +#endif + +#ifdef CONFIG_DEBUG_GPIO +# define gpiodbg(format, ...) dbg(format, ##__VA_ARGS__) +# define gpiolldbg(format, ...) lldbg(format, ##__VA_ARGS__) +# define gpiovdbg(format, ...) vdbg(format, ##__VA_ARGS__) +# define gpiollvdbg(format, ...) llvdbg(format, ##__VA_ARGS__) +#else +# define gpiodbg(x...) +# define gpiolldbg(x...) +# define gpiovdbg(x...) +# define gpiollvdbg(x...) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +uintptr_t tiva_gpiobaseaddress(unsigned int port); + +/**************************************************************************** + * Name: tiva_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int tiva_configgpio(uint32_t pinset); + +/**************************************************************************** + * Name: tiva_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void tiva_gpiowrite(uint32_t pinset, bool value); + +/**************************************************************************** + * Name: tiva_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool tiva_gpioread(uint32_t pinset); + +/**************************************************************************** + * Function: tiva_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int tiva_dumpgpio(uint32_t pinset, const char *msg); + +/**************************************************************************** + * Name: tiva_gpio_lockport + * + * Description: + * Certain pins require to be unlocked from the NMI to use for normal GPIO + * use. See table 10-10 in datasheet for pins with special considerations. + * + ****************************************************************************/ + +void tiva_gpio_lockport(uint32_t pinset, bool lock); + +#ifdef CONFIG_DEBUG_GPIO +void tiva_gpio_dumpconfig(uint32_t pinset); +#endif + +#ifdef CONFIG_TIVA_GPIO_IRQS +/**************************************************************************** + * Name: gpio_irqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler + * + ****************************************************************************/ + +int weak_function tiva_gpioirqinitialize(void); + +/**************************************************************************** + * Name: tiva_gpioirqattach + * + * Description: + * Attach a GPIO interrupt to the provided 'isr' + * + * Returns: + * oldhandler - the old interrupt handler assigned to this pin. + * + ****************************************************************************/ + +xcpt_t tiva_gpioirqattach(uint32_t pinset, xcpt_t isr); +# define tiva_gpioirqdetach(pinset) tiva_gpioirqattach(pinset, NULL) + +/**************************************************************************** + * Name: tiva_gpioportirqattach + * + * Description: + * Attach 'isr' to the GPIO port. Only use this if you want to handle + * the entire ports interrupts explicitly. + * + ****************************************************************************/ + +void tiva_gpioportirqattach(uint8_t port, xcpt_t isr); +# define tiva_gpioportirqdetach(port) tiva_gpioportirqattach(port, NULL) + +/**************************************************************************** + * Name: tiva_gpioirqenable + * + * Description: + * Enable the GPIO port IRQ + * + ****************************************************************************/ + +void tiva_gpioirqenable(uint8_t port, uint8_t pin); + +/**************************************************************************** + * Name: tiva_gpioirqdisable + * + * Description: + * Disable the GPIO port IRQ + * + ****************************************************************************/ + +void tiva_gpioirqdisable(uint8_t port, uint8_t pin); + +/**************************************************************************** + * Name: tiva_gpioirqstatus + * + * Description: + * Returns raw or masked interrupt status. + * + ****************************************************************************/ + +uint32_t tiva_gpioirqstatus(uint8_t port, bool masked); + +/**************************************************************************** + * Name: tiva_gpioirqclear + * + * Description: + * Clears the interrupt status of the input base + * + ****************************************************************************/ + +void tiva_gpioirqclear(uint8_t port, uint32_t pinmask); + +#endif /* CONFIG_TIVA_GPIO_IRQS */ + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_GPIO_H */ diff --git a/arch/arm/src/tiva/tiva_gpioirq.c b/arch/arm/src/tiva/tiva_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..33b5fa0e3a66dd17f130373cfbfbeaa32e541740 --- /dev/null +++ b/arch/arm/src/tiva/tiva_gpioirq.c @@ -0,0 +1,801 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_gpioirq.c + * + * Copyright (C) 2009-2010, 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" + +#include "up_internal.h" +#include "up_arch.h" +#include "irq/irq.h" + +#include "tiva_gpio.h" + +#ifdef CONFIG_TIVA_GPIO_IRQS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TIVA_NPINS 8 +#define TIVA_NIRQ_PINS (TIVA_NPORTS * TIVA_NPINS) +#define TIVA_GPIO_IRQ_IDX(port,pin) ((port*TIVA_NPINS)+(pin)) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* A table of handlers for each GPIO port interrupt */ + +static FAR xcpt_t g_gpioportirqvector[TIVA_NIRQ_PINS]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gpioport2irq + * + * Description: + * Translates from GPIO port to GPIO IRQ. + * + ****************************************************************************/ + +static int gpioport2irq(uint8_t port) +{ + int irq = -1; + + switch (port) + { +#ifdef CONFIG_TIVA_GPIOA_IRQS + case (GPIO_PORTA >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOA; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOB_IRQS + case (GPIO_PORTB >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOB; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOC_IRQS + case (GPIO_PORTC >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOC; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOD_IRQS + case (GPIO_PORTD >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOD; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOE_IRQS + case (GPIO_PORTE >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOE; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOF_IRQS + case (GPIO_PORTF >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOF; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOG_IRQS + case (GPIO_PORTG >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOG; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOH_IRQS + case (GPIO_PORTH >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOH; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOJ_IRQS + case (GPIO_PORTJ >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOJ; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOK_IRQS + case (GPIO_PORTK >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOK; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOL_IRQS + case (GPIO_PORTL >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOL; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOM_IRQS + case (GPIO_PORTM >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOM; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPION_IRQS + case (GPIO_PORTN >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPION; + } + break; +#endif +#ifdef CONFIG_TIVA_GPIOP_IRQS + case (GPIO_PORTP >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOP; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOQ_IRQS + case (GPIO_PORTQ >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOQ; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOR_IRQS + case (GPIO_PORTR >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOR; + } + break; +#endif + +#ifdef CONFIG_TIVA_GPIOS_IRQS + case (GPIO_PORTS >> GPIO_PORT_SHIFT): + { + irq = TIVA_IRQ_GPIOS; + } + break; +#endif + } + + return irq; +} + +/**************************************************************************** + * Name: tiva_gpioirqstatus + * + * Description: + * Returns raw or masked interrupt status. + * + ****************************************************************************/ + +uint32_t tiva_gpioirqstatus(uint8_t port, bool masked) +{ + uintptr_t base = tiva_gpiobaseaddress(port); + + if (masked) + { + return getreg32(base + TIVA_GPIO_MIS_OFFSET); + } + else + { + return getreg32(base + TIVA_GPIO_RIS_OFFSET); + } +} + +/**************************************************************************** + * Name: tiva_gpioirqclear + * + * Description: + * Clears the interrupt status of the input base + * + ****************************************************************************/ + +void tiva_gpioirqclear(uint8_t port, uint32_t pinmask) +{ + uintptr_t base = tiva_gpiobaseaddress(port); + + /* "The GPIOICR register is the interrupt clear register. Writing a 1 to a bit + * in this register clears the corresponding interrupt edge detection logic + * register. Writing a 0 has no effect." + */ + + modifyreg32(base + TIVA_GPIO_ICR_OFFSET, 0, pinmask); +} + +/**************************************************************************** + * Name: tiva_gpioporthandler + * + * Description: + * Handle interrupts on each enabled GPIO port + * + ****************************************************************************/ + +static int tiva_gpioporthandler(uint8_t port, void *context) +{ + + int irq = gpioport2irq(port); /* GPIO port interrupt vector */ + uint32_t mis = tiva_gpioirqstatus(port, true); /* Masked Interrupt Status */ + uint8_t pin; /* Pin number */ + + tiva_gpioirqclear(port, 0xff); + gpiollvdbg("mis=0b%08b\n", mis & 0xff); + + /* Now process each IRQ pending in the MIS */ + + if (mis != 0) + { + for (pin = 0; pin < TIVA_NPINS; ++pin) + { + if (((mis >> pin) & 1) != 0) + { + gpiollvdbg("port=%d pin=%d irq=%p index=%d\n", + port, pin, + g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pin)], + TIVA_GPIO_IRQ_IDX(port, pin)); + + g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pin)](irq, context); + } + } + } + + return OK; +} + +#ifdef CONFIG_TIVA_GPIOA_IRQS +static int tiva_gpioahandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTA >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOB_IRQS +static int tiva_gpiobhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTB >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOC_IRQS +static int tiva_gpiochandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTC >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOD_IRQS +static int tiva_gpiodhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTD >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOE_IRQS +static int tiva_gpioehandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTE >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOF_IRQS +static int tiva_gpiofhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTF >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOG_IRQS +static int tiva_gpioghandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTG >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOH_IRQS +static int tiva_gpiohhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTH >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOJ_IRQS +static int tiva_gpiojhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTJ >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOK_IRQS +static int tiva_gpiokhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTK >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOL_IRQS +static int tiva_gpiolhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTL >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOM_IRQS +static int tiva_gpiomhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTM >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPION_IRQS +static int tiva_gpionhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTN >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOP_IRQS +static int tiva_gpiophandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTP >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOQ_IRQS +static int tiva_gpioqhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTQ >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOR_IRQS +static int tiva_gpiorhandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTR >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +#ifdef CONFIG_TIVA_GPIOS_IRQS +static int tiva_gpioshandler(int irq, FAR void *context) +{ + irqstate_t flags; + flags = enter_critical_section(); + up_disable_irq(irq); + int ret = tiva_gpioporthandler((GPIO_PORTS >> GPIO_PORT_SHIFT), context); + up_enable_irq(irq); + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_gpioirqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler + * + ****************************************************************************/ + +int tiva_gpioirqinitialize(void) +{ + int i; + + /* Point all interrupt vectors to the unexpected interrupt */ + + for (i = 0; i < TIVA_NIRQ_PINS; ++i) + { + g_gpioportirqvector[i] = irq_unexpected_isr; + } + + gpiovdbg("tiva_gpioirqinitialize isr=%d/%d irq_unexpected_isr=%p\n", + i, TIVA_NIRQ_PINS, irq_unexpected_isr); + + /* Then attach each GPIO interrupt handlers and enable corresponding GPIO + * interrupts + */ + +#ifdef CONFIG_TIVA_GPIOA_IRQS + irq_attach(TIVA_IRQ_GPIOA, tiva_gpioahandler); + up_enable_irq(TIVA_IRQ_GPIOA); +#endif + +#ifdef CONFIG_TIVA_GPIOB_IRQS + irq_attach(TIVA_IRQ_GPIOB, tiva_gpiobhandler); + up_enable_irq(TIVA_IRQ_GPIOB); +#endif + +#ifdef CONFIG_TIVA_GPIOC_IRQS + irq_attach(TIVA_IRQ_GPIOC, tiva_gpiochandler); + up_enable_irq(TIVA_IRQ_GPIOC); +#endif + +#ifdef CONFIG_TIVA_GPIOD_IRQS + irq_attach(TIVA_IRQ_GPIOD, tiva_gpiodhandler); + up_enable_irq(TIVA_IRQ_GPIOD); +#endif + +#ifdef CONFIG_TIVA_GPIOE_IRQS + irq_attach(TIVA_IRQ_GPIOE, tiva_gpioehandler); + up_enable_irq(TIVA_IRQ_GPIOE); +#endif + +#ifdef CONFIG_TIVA_GPIOF_IRQS + irq_attach(TIVA_IRQ_GPIOF, tiva_gpiofhandler); + up_enable_irq(TIVA_IRQ_GPIOF); +#endif + +#ifdef CONFIG_TIVA_GPIOG_IRQS + irq_attach(TIVA_IRQ_GPIOG, tiva_gpioghandler); + up_enable_irq(TIVA_IRQ_GPIOG); +#endif + +#ifdef CONFIG_TIVA_GPIOH_IRQS + irq_attach(TIVA_IRQ_GPIOH, tiva_gpiohhandler); + up_enable_irq(TIVA_IRQ_GPIOH); +#endif + +#ifdef CONFIG_TIVA_GPIOJ_IRQS + irq_attach(TIVA_IRQ_GPIOJ, tiva_gpiojhandler); + up_enable_irq(TIVA_IRQ_GPIOJ); +#endif + +#ifdef CONFIG_TIVA_GPIOK_IRQS + irq_attach(TIVA_IRQ_GPIOK, tiva_gpiokhandler); + up_enable_irq(TIVA_IRQ_GPIOK); +#endif + +#ifdef CONFIG_TIVA_GPIOL_IRQS + irq_attach(TIVA_IRQ_GPIOL, tiva_gpiolhandler); + up_enable_irq(TIVA_IRQ_GPIOL); +#endif + +#ifdef CONFIG_TIVA_GPIOM_IRQS + irq_attach(TIVA_IRQ_GPIOM, tiva_gpiomhandler); + up_enable_irq(TIVA_IRQ_GPIOM); +#endif + +#ifdef CONFIG_TIVA_GPION_IRQS + irq_attach(TIVA_IRQ_GPION, tiva_gpionhandler); + up_enable_irq(TIVA_IRQ_GPION); +#endif + +#ifdef CONFIG_TIVA_GPIOP_IRQS + irq_attach(TIVA_IRQ_GPIOP, tiva_gpiophandler); + up_enable_irq(TIVA_IRQ_GPIOP); +#endif + +#ifdef CONFIG_TIVA_GPIOQ_IRQS + irq_attach(TIVA_IRQ_GPIOQ, tiva_gpioqhandler); + up_enable_irq(TIVA_IRQ_GPIOQ); +#endif + +#ifdef CONFIG_TIVA_GPIOR_IRQS + irq_attach(TIVA_IRQ_GPIOR, tiva_gpiorhandler); + up_enable_irq(TIVA_IRQ_GPIOR); +#endif + +#ifdef CONFIG_TIVA_GPIOS_IRQS + irq_attach(TIVA_IRQ_GPIOS, tiva_gpioshandler); + up_enable_irq(TIVA_IRQ_GPIOS); +#endif + + return OK; +} + +/**************************************************************************** + * Name: tiva_gpioirqattach + * + * Description: + * Attach in GPIO interrupt to the provided 'isr'. If isr==NULL, then the + * irq_unexpected_isr handler is assigned and the pin's interrupt mask is + * disabled to stop further interrupts. Otherwise, the new isr is linked + * and the pin's interrupt mask is set. + * + * Returns: + * oldhandler - the old interrupt handler assigned to this pin. + * + ****************************************************************************/ + +xcpt_t tiva_gpioirqattach(uint32_t pinset, xcpt_t isr) +{ + irqstate_t flags; + xcpt_t oldhandler = NULL; + uint8_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + uint8_t pinno = (pinset & GPIO_PIN_MASK); + uint8_t pin = 1 << pinno; + + /* assign per-pin interrupt handlers */ + + if (port < TIVA_NPORTS) + { + flags = enter_critical_section(); + + /* store the older handler to return */ + + oldhandler = g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)]; + + /* If the new ISR is NULL, then the ISR is being detached. + * In this case, disable the ISR and direct any interrupts + * to the unexpected interrupt handler. + */ + + gpiovdbg("assign port=%d pin=%d function=%p to idx=%d\n", + port, pinno, isr, TIVA_GPIO_IRQ_IDX(port, pinno)); + + if (isr == NULL) + { + tiva_gpioirqdisable(port, pin); + g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)] = irq_unexpected_isr; + } + else + { + g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)] = isr; + tiva_gpioirqenable(port, pin); + } + + leave_critical_section(flags); + } + + return oldhandler; +} + +/**************************************************************************** + * Name: tiva_gpioportirqattach + * + * Description: + * Attach 'isr' to the GPIO port. Only use this if you want to handle + * the entire ports interrupts explicitly. + * + ****************************************************************************/ + +void tiva_gpioportirqattach(uint8_t port, xcpt_t isr) +{ + irqstate_t flags; + int irq = gpioport2irq(port); + + /* assign port interrupt handler */ + + if (port < TIVA_NPORTS) + { + flags = enter_critical_section(); + + /* If the new ISR is NULL, then the ISR is being detached. + * In this case, disable the ISR and direct any interrupts + * to the unexpected interrupt handler. + */ + + gpiovdbg("assign function=%p to port=%d\n", isr, port); + + if (isr == NULL) + { + tiva_gpioirqdisable(port, 0xff); + irq_attach(irq, irq_unexpected_isr); + } + else + { + irq_attach(irq, isr); + tiva_gpioirqenable(port, 0xff); + } + + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: tiva_gpioirqenable + * + * Description: + * Enable the GPIO port IRQ + * + ****************************************************************************/ + +void tiva_gpioirqenable(uint8_t port, uint8_t pin) +{ + uintptr_t base = tiva_gpiobaseaddress(port); + + /* Enable the GPIO interrupt. "The GPIO IM register is the interrupt + * mask register. Bits set to High in GPIO IM allow the corresponding + * pins to trigger their individual interrupts and the combined GPIO INTR + * line. Clearing a bit disables interrupt triggering on that pin. All + * bits are cleared by a reset. + */ + + modifyreg32(base + TIVA_GPIO_IM_OFFSET, 0, pin); +} + +/**************************************************************************** + * Name: tiva_gpioirqdisable + * + * Description: + * Disable the GPIO port IRQ + * + ****************************************************************************/ + +void tiva_gpioirqdisable(uint8_t port, uint8_t pin) +{ + uintptr_t base = tiva_gpiobaseaddress(port); + + /* Disable the GPIO interrupt. "The GPIO IM register is the interrupt + * mask register. Bits set to High in GPIO IM allow the corresponding + * pins to trigger their individual interrupts and the combined GPIO INTR + * line. Clearing a bit disables interrupt triggering on that pin. All + * bits are cleared by a reset. + */ + + modifyreg32(base + TIVA_GPIO_IM_OFFSET, pin, 0); +} + +#endif /* CONFIG_TIVA_GPIO_IRQS */ diff --git a/arch/arm/src/tiva/tiva_i2c.c b/arch/arm/src/tiva/tiva_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..28450836f844a514bc7a39bc67376405dad16283 --- /dev/null +++ b/arch/arm/src/tiva/tiva_i2c.c @@ -0,0 +1,2300 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_i2c.c + * + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * The basic structure of this driver derives in spirit (if nothing more) from the + * NuttX STM32 I2C driver which has: + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" + +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" +#include "tiva_gpio.h" +#include "chip/tiva_pinmap.h" +#include "chip/tiva_syscontrol.h" +#include "tiva_i2c.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_TIVA_I2C0) || defined(CONFIG_TIVA_I2C1) || \ + defined(CONFIG_TIVA_I2C2) || defined(CONFIG_TIVA_I2C3) || \ + defined(CONFIG_TIVA_I2C4) || defined(CONFIG_TIVA_I2C5) || \ + defined(CONFIG_TIVA_I2C6) || defined(CONFIG_TIVA_I2C7) || \ + defined(CONFIG_TIVA_I2C8) || defined(CONFIG_TIVA_I2C9) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. Instead, + * CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_TIVA_I2C_TIMEOSEC) && !defined(CONFIG_TIVA_I2C_TIMEOMS) +# define CONFIG_TIVA_I2C_TIMEOSEC 0 +# define CONFIG_TIVA_I2C_TIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_TIVA_I2C_TIMEOSEC) +# define CONFIG_TIVA_I2C_TIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_TIVA_I2C_TIMEOMS) +# define CONFIG_TIVA_I2C_TIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_TIVA_I2C_TIMEOTICKS +# define CONFIG_TIVA_I2C_TIMEOTICKS \ + (SEC2TICK(CONFIG_TIVA_I2C_TIMEOSEC) + MSEC2TICK(CONFIG_TIVA_I2C_TIMEOMS)) +#endif + +#ifndef CONFIG_TIVA_I2C_DYNTIMEO_STARTSTOP +# define CONFIG_TIVA_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_TIVA_I2C_TIMEOTICKS) +#endif + +/* GPIO pins ************************************************************************/ +/* Macros to convert a I2C pin to a GPIO output */ + +#define I2C_INPUT (GPIO_FUNC_INPUT) +#define I2C_OUTPUT (GPIO_FUNC_ODOUTPUT | GPIO_PADTYPE_OD | GPIO_VALUE_ONE) + +#define MKI2C_INPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_INPUT) +#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) + +/* Debug ****************************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +#ifndef CONFIG_DEBUG +# undef CONFIG_TIVA_I2C_REGDEBUG +#endif + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level + * debug interface syslog() but does not require that any other debug + * is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define tiva_i2c_tracereset(p) +# define tiva_i2c_tracenew(p,s) +# define tiva_i2c_traceevent(p,e,a) +# define tiva_i2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Interrupt state */ + +enum tiva_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for data transfer to complete */ + INTSTATE_DONE /* Interrupt activity complete */ +}; + +/* Trace events */ + +enum tiva_trace_e +{ + I2CEVENT_NONE = 0, /* No events have occurred with this status */ + I2CEVENT_SENDADDRESS, /* Address sent, param = address */ + I2CEVENT_ERROR, /* Error occurred, param = MCS */ + I2CEVENT_BUSY, /* Still busy, param = MCS */ + I2CEVENT_XFRDONE, /* Transfer completed without error, param = mcnt */ + I2CEVENT_RECVSETUP, /* Setup to receive the next byte, param = mcnt */ + I2CEVENT_SENDBYTE, /* Send byte, param = mcnt */ + I2CEVENT_SPURIOUS, /* Spurious interrupt received, param = msgc */ + I2CEVENT_NEXTMSG, /* Starting next message, param = msgc */ + I2CEVENT_TIMEOUT, /* Software detected timeout, param = RIS */ + I2CEVENT_DONE /* All messages transferred, param = intstate */ +}; + +/* Trace data */ + +struct tiva_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + enum tiva_trace_e event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + systime_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct tiva_i2c_config_s +{ + uintptr_t base; /* I2C base address */ +#ifndef TIVA_SYSCON_RCGCI2C + uint32_t rcgbit; /* Bit in the RCG1 register to enable clocking */ +#endif +#ifndef TIVA_SYSCON_SRI2C + uint32_t rstbit; /* Bit in the SRCR1 register to reset I2C */ +#endif + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ +#ifndef CONFIG_I2C_POLLED + int (*isr)(int, void *); /* Interrupt handler */ + uint8_t irq; /* IRQ number */ +#endif + uint8_t devno; /* I2Cn where n = devno */ +}; + +/* I2C Device Private Data */ + +struct tiva_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + const struct tiva_i2c_config_s *config; /* Port configuration */ + sem_t exclsem; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t waitsem; /* Interrupt wait semaphore */ +#endif + uint8_t refs; /* Reference count */ + volatile uint8_t intstate; /* Interrupt handshake (see enum tiva_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *mptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int mcnt; /* Current message length */ + uint16_t mflags; /* Current message flags */ + uint32_t mstatus; /* MCS register at the end of the transfer */ + +#ifdef CONFIG_TIVA_I2C_REGDEBUG + /* Register level debug */ + + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif + +#ifdef CONFIG_I2C_TRACE + /* I2C trace support */ + + int tndx; /* Trace array index */ + int tcount; /* Number of events with this status */ + systime_t ttime; /* Time when the trace was started */ + uint32_t tstatus; /* Last status read */ + + /* The actual trace data */ + + struct tiva_trace_s trace[CONFIG_I2C_NTRACE]; +#endif +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +#ifdef CONFIG_TIVA_I2C_REGDEBUG +static bool tiva_i2c_checkreg(struct tiva_i2c_priv_s *priv, bool wr, + uint32_t regval, uintptr_t regaddr); +static uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv, unsigned int offset); +static void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv, unsigned int offset, + uint32_t value); +#else +static inline uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv, + unsigned int offset); +static inline void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv, + unsigned int offset, uint32_t value); +#endif +static inline void tiva_i2c_sem_wait(struct tiva_i2c_priv_s *priv); + +#ifdef CONFIG_TIVA_I2C_DYNTIMEO +static useconds_t tiva_i2c_tousecs(int msgc, struct i2c_msg_s *msgv); +#endif /* CONFIG_TIVA_I2C_DYNTIMEO */ + +static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv); +static inline void tiva_i2c_sem_post(struct tiva_i2c_priv_s *priv); +static inline void tiva_i2c_sem_init(struct tiva_i2c_priv_s *priv); +static inline void tiva_i2c_sem_destroy(struct tiva_i2c_priv_s *priv); + +#ifdef CONFIG_I2C_TRACE +static void tiva_i2c_tracereset(struct tiva_i2c_priv_s *priv); +static void tiva_i2c_tracenew(struct tiva_i2c_priv_s *priv, uint32_t status); +static void tiva_i2c_traceevent(struct tiva_i2c_priv_s *priv, + enum tiva_trace_e event, uint32_t parm); +static void tiva_i2c_tracedump(struct tiva_i2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +static void tiva_i2c_startxfr(struct tiva_i2c_priv_s *priv); +static void tiva_i2c_nextxfr(struct tiva_i2c_priv_s *priv, uint32_t cmd); +static int tiva_i2c_interrupt(struct tiva_i2c_priv_s * priv, uint32_t status); + +#ifndef CONFIG_I2C_POLLED +#ifdef CONFIG_TIVA_I2C0 +static int tiva_i2c0_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C1 +static int tiva_i2c1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C2 +static int tiva_i2c2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C3 +static int tiva_i2c3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C4 +static int tiva_i2c4_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C5 +static int tiva_i2c5_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C6 +static int tiva_i2c6_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C7 +static int tiva_i2c7_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C8 +static int tiva_i2c8_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TIVA_I2C9 +static int tiva_i2c9_interrupt(int irq, void *context); +#endif +#endif /* !CONFIG_I2C_POLLED */ + +static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv, uint32_t frequency); +static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv); +static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency); +static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv, + int msgc); +#ifdef CONFIG_I2C_RESET +static int tiva_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/* I2C Interface */ + +static const struct i2c_ops_s tiva_i2c_ops = +{ + .transfer = tiva_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = tiva_i2c_reset +#endif +}; + +#ifdef CONFIG_TIVA_I2C0 +static const struct tiva_i2c_config_s tiva_i2c0_config = +{ + .base = TIVA_I2C0_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C0, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C0, +#endif + .scl_pin = GPIO_I2C0_SCL, + .sda_pin = GPIO_I2C0_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c0_interrupt, + .irq = TIVA_IRQ_I2C0, +#endif + .devno = 0, +}; + +static struct tiva_i2c_priv_s tiva_i2c0_priv; +#endif + +#ifdef CONFIG_TIVA_I2C1 +static const struct tiva_i2c_config_s tiva_i2c1_config = +{ + .base = TIVA_I2C1_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C1, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C1, +#endif + .scl_pin = GPIO_I2C1_SCL, + .sda_pin = GPIO_I2C1_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c1_interrupt, + .irq = TIVA_IRQ_I2C1, +#endif + .devno = 1, +}; + +static struct tiva_i2c_priv_s tiva_i2c1_priv; +#endif + +#ifdef CONFIG_TIVA_I2C2 +static const struct tiva_i2c_config_s tiva_i2c2_config = +{ + .base = TIVA_I2C2_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C2, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C2, +#endif + .scl_pin = GPIO_I2C2_SCL, + .sda_pin = GPIO_I2C2_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c2_interrupt, + .irq = TIVA_IRQ_I2C2, +#endif + .devno = 2, +}; + +static struct tiva_i2c_priv_s tiva_i2c2_priv; +#endif + +#ifdef CONFIG_TIVA_I2C3 +static const struct tiva_i2c_config_s tiva_i2c3_config = +{ + .base = TIVA_I2C3_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C3, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C3, +#endif + .scl_pin = GPIO_I2C3_SCL, + .sda_pin = GPIO_I2C3_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c3_interrupt, + .irq = TIVA_IRQ_I2C3, +#endif + .devno = 3, +}; + +static struct tiva_i2c_priv_s tiva_i2c3_priv; +#endif + +#ifdef CONFIG_TIVA_I2C4 +static const struct tiva_i2c_config_s tiva_i2c4_config = +{ + .base = TIVA_I2C4_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C4, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C4, +#endif + .scl_pin = GPIO_I2C4_SCL, + .sda_pin = GPIO_I2C4_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c4_interrupt, + .irq = TIVA_IRQ_I2C4, +#endif + .devno = 4, +}; + +static struct tiva_i2c_priv_s tiva_i2c4_priv; +#endif + +#ifdef CONFIG_TIVA_I2C5 +static const struct tiva_i2c_config_s tiva_i2c5_config = +{ + .base = TIVA_I2C5_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C5, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C5, +#endif + .scl_pin = GPIO_I2C5_SCL, + .sda_pin = GPIO_I2C5_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c5_interrupt, + .irq = TIVA_IRQ_I2C5, +#endif + .devno = 5, +}; + +static struct tiva_i2c_priv_s tiva_i2c5_priv; +#endif + +#ifdef CONFIG_TIVA_I2C6 +static const struct tiva_i2c_config_s tiva_i2c6_config = +{ + .base = TIVA_I2C6_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C6, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C6, +#endif + .scl_pin = GPIO_I2C6_SCL, + .sda_pin = GPIO_I2C6_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c6_interrupt, + .irq = TIVA_IRQ_I2C6, +#endif + .devno = 6, +}; + +static struct tiva_i2c_priv_s tiva_i2c6_priv; +#endif + +#ifdef CONFIG_TIVA_I2C7 +static const struct tiva_i2c_config_s tiva_i2c7_config = +{ + .base = TIVA_I2C7_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C7, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C7, +#endif + .scl_pin = GPIO_I2C7_SCL, + .sda_pin = GPIO_I2C7_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c7_interrupt, + .irq = TIVA_IRQ_I2C7, +#endif + .devno = 7, +}; + +static struct tiva_i2c_priv_s tiva_i2c7_priv; +#endif + +#ifdef CONFIG_TIVA_I2C8 +static const struct tiva_i2c_config_s tiva_i2c8_config = +{ + .base = TIVA_I2C8_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C8, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C8, +#endif + .scl_pin = GPIO_I2C8_SCL, + .sda_pin = GPIO_I2C8_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c8_interrupt, + .irq = TIVA_IRQ_I2C8, +#endif + .devno = 8, +}; + +static struct tiva_i2c_priv_s tiva_i2c8_priv; +#endif + +#ifdef CONFIG_TIVA_I2C9 +static const struct tiva_i2c_config_s tiva_i2c9_config = +{ + .base = TIVA_I2C9_BASE, +#ifndef TIVA_SYSCON_RCGCI2C + .rcgbit = SYSCON_RCGC1_I2C9, +#endif +#ifndef TIVA_SYSCON_SRI2C + .rstbit = SYSCON_SRCR1_I2C9, +#endif + .scl_pin = GPIO_I2C9_SCL, + .sda_pin = GPIO_I2C9_SDA, +#ifndef CONFIG_I2C_POLLED + .isr = tiva_i2c9_interrupt, + .irq = TIVA_IRQ_I2C9, +#endif + .devno = 9, +}; + +static struct tiva_i2c_priv_s tiva_i2c9_priv; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ************************************************************************************/ + +#ifdef CONFIG_TIVA_I2C_REGDEBUG +static bool tiva_i2c_checkreg(struct tiva_i2c_priv_s *priv, bool wr, + uint32_t regval, uintptr_t regaddr) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + regaddr == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_getreg + * + * Description: + * Get a 16-bit register value by offset + * + ************************************************************************************/ + +#ifdef CONFIG_TIVA_I2C_REGDEBUG +static uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv, unsigned int offset) +{ + uintptr_t regaddr = priv->config->base + offset; + uint32_t regval = getreg32(regaddr); + + if (tiva_i2c_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } + + return regval; +} +#else +static inline uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv, + unsigned int offset) +{ + return getreg32(priv->config->base + offset); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_putreg + * + * Description: + * Put a 16-bit register value by offset + * + ************************************************************************************/ + +#ifdef CONFIG_TIVA_I2C_REGDEBUG +static void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv, unsigned int offset, + uint32_t regval) +{ + uintptr_t regaddr = priv->config->base + offset; + + if (tiva_i2c_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } + + putreg32(regval, regaddr); +} +#else +static inline void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv, + unsigned int offset, uint32_t regval) +{ + putreg32(regval, priv->config->base + offset); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void tiva_i2c_sem_wait(struct tiva_i2c_priv_s *priv) +{ + while (sem_wait(&priv->exclsem) != 0) + { + ASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: tiva_i2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be processed. + * + ************************************************************************************/ + +#ifdef CONFIG_TIVA_I2C_DYNTIMEO +static useconds_t tiva_i2c_tousecs(int msgc, struct i2c_msg_s *msgv) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgv[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_TIVA_I2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ************************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + int ret; + + flags = enter_critical_section(); + + /* Enable the master interrupt. The I2C master module generates an interrupt when + * a transaction completes (either transmit or receive), when arbitration is lost, + * or when an error occurs during a transaction. + */ + + tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, I2CM_IMR_MIM); + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + do + { + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_TIVA_I2C_TIMEOSEC > 0 + abstime.tv_sec += CONFIG_TIVA_I2C_TIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_TIVA_I2C_DYNTIMEO + abstime.tv_nsec += 1000 * tiva_i2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_TIVA_I2C_TIMEOMS > 0 + abstime.tv_nsec += CONFIG_TIVA_I2C_TIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + + /* Wait until either the transfer is complete or the timeout expires */ + + ret = sem_timedwait(&priv->waitsem, &abstime); + if (ret != OK && errno != EINTR) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by sem_timedwait. + * NOTE that we try again if we are awakened by a signal (EINTR). + */ + + tiva_i2c_traceevent(priv, I2CEVENT_TIMEOUT, + tiva_i2c_getreg(priv, TIVA_I2CM_RIS_OFFSET)); + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, 0); + + leave_critical_section(flags); + return ret; +} +#else +static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv) +{ + systime_t timeout; + systime_t start; + systime_t elapsed; + uint32_t status; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_TIVA_I2C_DYNTIMEO + timeout = USEC2TICK(tiva_i2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_TIVA_I2C_TIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * sem_timedwait() sleeps. + */ + + start = clock_systimer(); + + do + { + /* Read the raw interrupt status */ + + status = tiva_i2c_getreg(priv, TIVA_I2CM_RIS_OFFSET); + + /* Poll by simply calling the timer interrupt handler with the raw + * interrupt status until it reports that it is done. + */ + + tiva_i2c_interrupt(priv, status); + + /* Calculate the elapsed time */ + + elapsed = clock_systimer() - start; + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cvdbg("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void tiva_i2c_sem_post(struct tiva_i2c_priv_s *priv) +{ + sem_post(&priv->exclsem); +} + +/************************************************************************************ + * Name: tiva_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void tiva_i2c_sem_init(struct tiva_i2c_priv_s *priv) +{ + sem_init(&priv->exclsem, 0, 1); +#ifndef CONFIG_I2C_POLLED + sem_init(&priv->waitsem, 0, 0); +#endif +} + +/************************************************************************************ + * Name: tiva_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void tiva_i2c_sem_destroy(struct tiva_i2c_priv_s *priv) +{ + sem_destroy(&priv->exclsem); +#ifndef CONFIG_I2C_POLLED + sem_destroy(&priv->waitsem); +#endif +} + +/************************************************************************************ + * Name: tiva_i2c_trace + * + * Description: + * I2C trace instrumentation + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void tiva_i2c_traceclear(struct tiva_i2c_priv_s *priv) +{ + struct tiva_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void tiva_i2c_tracereset(struct tiva_i2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->tcount = 0; + priv->ttime = clock_systimer(); + priv->tstatus = 0; + tiva_i2c_traceclear(priv); +} + +static void tiva_i2c_tracenew(struct tiva_i2c_priv_s *priv, uint32_t status) +{ + struct tiva_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("I2C%d: ERROR: Trace table overflow\n", priv->config->devno); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + tiva_i2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systimer(); + + /* Save the status and reset the count */ + + priv->tstatus = status; + priv->tcount = 1; + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void tiva_i2c_traceevent(struct tiva_i2c_priv_s *priv, + enum tiva_trace_e event, uint32_t parm) +{ + struct tiva_trace_s *trace; + + if (event != I2CEVENT_NONE) + { + trace = &priv->trace[priv->tndx]; + if (trace->event != event) + { + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + trace->count = priv->tcount; + trace->time = clock_systimer(); + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE-1)) + { + i2cdbg("I2C%d: ERROR: Trace table overflow\n", priv->config->devno); + return; + } + + priv->tndx++; + priv->tcount++; + tiva_i2c_traceclear(priv); + + trace = &priv->trace[priv->tndx]; + trace->status = priv->tstatus; + trace->count = priv->tcount; + trace->time = clock_systimer(); + } + else + { + priv->tcount++; + } + } +} + +static void tiva_i2c_tracedump(struct tiva_i2c_priv_s *priv) +{ + struct tiva_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systimer() - priv->ttime)); + + for (i = 0; i <= priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %3d EVENT: %2d PARM: %08x TIME: %d\n", + i+1, trace->status, trace->count, trace->event, trace->parm, + trace->time - priv->ttime); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/************************************************************************************ + * Name: tiva_i2c_startxfr + * + * Description: + * Send the START conditions/force Master mode + * + ************************************************************************************/ + +static void tiva_i2c_startxfr(struct tiva_i2c_priv_s *priv) +{ + struct i2c_msg_s *msg; + uint32_t regval; + + DEBUGASSERT(priv && priv->msgc > 0); + + /* Get run-time data for the next message */ + + msg = priv->msgv; + priv->mptr = msg->buffer; + priv->mcnt = msg->length; + priv->mflags = msg->flags; + + /* Set the Master Slave Address */ + + regval = (uint32_t)msg->addr << I2CM_SA_SA_SHIFT; + if ((msg->flags & I2C_M_READ) != 0) + { + regval |= I2CM_SA_RS; + } + + tiva_i2c_putreg(priv, TIVA_I2CM_SA_OFFSET, regval); + tiva_i2c_traceevent(priv, I2CEVENT_SENDADDRESS, msg->addr); + + /* Then initiate the transfer */ + + tiva_i2c_nextxfr(priv, I2CM_CS_START); +} + +/************************************************************************************ + * Name: tiva_i2c_nextxfr + * + * Description: + * Common Interrupt Service Routine + * + ************************************************************************************/ + +static void tiva_i2c_nextxfr(struct tiva_i2c_priv_s *priv, uint32_t cmd) +{ + /* Set up the basic command. The STOP bit should be set on the last byte transfer. + * + * - CASE 1: If this is the last message in the sequence, then the stop bit should + * always be set. + * - CASE 2.1.1: The next message may be another read or write of the SAME + * direction (read or write) and to the SAME address WITHOUT repeated start, in + * which case this is really just a continuation of the message. No STOP is + * needed. + * - CASE 2.x.2: The next message may be to the SAME address WITH repeated start. + * Because the repeated start, a direction change is possible. This is still + * a continuation of the same message sequence and so no STOP is needed. + * - CASE 2.2.x: The next message may be a DIFFERENT address WITHOUT repeated + * start. This would be an error; The STOP will be sent, the next message will + * fail. + */ + + cmd |= I2CM_CS_RUN; + if (priv->mcnt < 2) + { + /* Are there more messages in this sequence? */ + + if (priv->msgc < 2) + { + /* No.. send the STOP */ + + cmd |= I2CM_CS_STOP; + } + else + { + /* Yes.. peek at the next message */ + + struct i2c_msg_s *curr = priv->msgv; + struct i2c_msg_s *next = curr + 1; + + /* Same address as the current message? */ + + if (curr->addr != next->addr) + { + /* No.. send the STOP */ + + cmd |= I2CM_CS_STOP; + } + } + } + + /* Set up to transfer the next byte. Are we sending or receiving? */ + + if ((priv->mflags & I2C_M_READ) != 0) + { + /* We are receiving data. We need to ACK UNLESS we are going to send + * STOP. + */ + + if ((cmd & I2CM_CS_STOP) == 0) + { + cmd |= I2CM_CS_ACK; + } + + /* Write the command to the control register to receive the next byte. */ + + tiva_i2c_putreg(priv, TIVA_I2CM_CS_OFFSET, cmd); + tiva_i2c_traceevent(priv, I2CEVENT_RECVSETUP, priv->mcnt); + } + else + { + uint32_t dr; + + /* We are sending data. Write the data to be sent to the DR register. */ + + dr = (uint32_t)*priv->mptr++; + tiva_i2c_putreg(priv, TIVA_I2CM_DR_OFFSET, dr << I2CM_DR_SHIFT); + + /* Write the command to the control register to send the byte in the DR + * register. + */ + + tiva_i2c_putreg(priv, TIVA_I2CM_CS_OFFSET, cmd); + tiva_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->mcnt); + } + + priv->intstate = INTSTATE_WAITING; +} + +/************************************************************************************ + * Name: tiva_i2c_interrupt + * + * Description: + * Common Interrupt Service Routine + * + ************************************************************************************/ + +static int tiva_i2c_interrupt(struct tiva_i2c_priv_s *priv, uint32_t status) +{ + /* Check for new trace setup */ + + tiva_i2c_tracenew(priv, status); + + /* Check for a master interrupt? The I2C master module generates an interrupt when + * a transaction completes (either transmit or receive), when arbitration is lost, + * or when an error occurs during a transaction. + */ + + if ((status & I2CM_RIS_MRIS) != 0) + { + uint32_t mcs; + +#ifndef CONFIG_I2C_POLLED + /* Clear the pending master interrupt */ + + tiva_i2c_putreg(priv, TIVA_I2CM_ICR_OFFSET, I2CM_ICR_MIC); + status &= ~I2CM_RIS_MRIS; + + /* Workaround for I2C master interrupt clear errata for rev B Tiva + * devices. For later devices, this write is ignored and therefore + * harmless (other than the slight performance hit). + */ + + (void)tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); +#endif + + /* We need look at the Master Control/Status register to determine the cause + * of the master interrupt. + */ + + mcs = tiva_i2c_getreg(priv, TIVA_I2CM_CS_OFFSET); + + /* If the busy bit is set, then the other bits are not valid */ + + if ((mcs & I2CM_CS_BUSY) != 0) + { + tiva_i2c_traceevent(priv, I2CEVENT_BUSY, mcs); + } + + /* Check for errors, in which case, stop the transfer and return. */ + +#if 0 /* I2CM_CS_CLKTO */ + else if ((mcs & (I2CM_CS_ERROR | I2CM_CS_ARBLST | I2CM_CS_CLKTO)) != 0) +#else + else if ((mcs & (I2CM_CS_ERROR | I2CM_CS_ARBLST)) != 0) +#endif + { + tiva_i2c_traceevent(priv, I2CEVENT_ERROR, mcs); + + /* Disable further interrupts */ + + tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, 0); + +#ifndef CONFIG_I2C_POLLED + /* Is there a thread waiting for this event (there should be) */ + + if (priv->intstate != INTSTATE_IDLE && + priv->intstate != INTSTATE_DONE) + { + /* Yes.. inform the thread that the transfer is complete + * and wake it up. + */ + + sem_post(&priv->waitsem); + priv->mstatus = mcs; + priv->intstate = INTSTATE_DONE; + } +#else + priv->mstatus = mcs; + priv->intstate = INTSTATE_DONE; +#endif + } + + /* Otherwise, the last transfer must have completed successfully */ + + else + { + int dr; + + tiva_i2c_traceevent(priv, I2CEVENT_XFRDONE, priv->mcnt); + + /* Read from the DR register */ + + dr = tiva_i2c_getreg(priv, TIVA_I2CM_DR_OFFSET); + + /* We check for msgc > 0 here as an unexpected interrupt with + * due to noise on the I2C cable can otherwise cause msgc to + * wrap causing memory overwrite + */ + + if (priv->msgc > 0 && priv->msgv != NULL) + { + /* Was this the completion of an address or of the data portion + * of the transfer? + */ + + DEBUGASSERT(priv->mcnt > 0); + + if (priv->intstate == INTSTATE_WAITING) + { + /* Data transfer completed. Are we sending or receiving data? */ + + if ((priv->mflags & I2C_M_READ) != 0) + { + /* We are receiving data. Copy the received data to + * the user buffer + */ + + *priv->mptr++ = (uint8_t)dr; + } + + /* Decrement the count of bytes remaining to be sent */ + + priv->mcnt--; + } + + /* Was that the last byte of this message? */ + + if (priv->mcnt > 0) + { + /* Send the next byte */ + + tiva_i2c_nextxfr(priv, 0); + } + else + { + /* Increment to next pointer and decrement message count */ + + priv->msgv++; + priv->msgc--; + + /* Is there another message to be sent? */ + + if (priv->msgc > 0) + { + /* Do we need to terminate or restart after this byte? + * If there are more messages to send, then we may + * continue with or without the (repeated) start bit. + */ + + tiva_i2c_traceevent(priv, I2CEVENT_NEXTMSG, priv->msgc); + if ((priv->msgv->flags & I2C_M_NORESTART) != 0) + { + /* Just continue transferring data. In this case, + * no STOP was sent at the end of the last message + * and the there is no new address. + * + * REVISIT: In this case, the address or the + * direction of the transfer cannot be permitted to + * change + */ + + tiva_i2c_nextxfr(priv, 0); + } + else + { + /* Set the repeated start. No STOP was sent at the + * end of the previous message. + */ + + tiva_i2c_startxfr(priv); + } + } + else + { + /* No.. then we are finished */ + + tiva_i2c_traceevent(priv, I2CEVENT_DONE, priv->intstate); + + /* Disable further interrupts */ + + tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, 0); + +#ifndef CONFIG_I2C_POLLED + /* Is there a thread waiting for this event (there + * should be) + */ + + if (priv->intstate != INTSTATE_IDLE && + priv->intstate != INTSTATE_DONE) + { + /* Yes.. inform the thread that the transfer is + * complete and wake it up. + */ + + sem_post(&priv->waitsem); + priv->mstatus = 0; + priv->intstate = INTSTATE_DONE; + } +#else + priv->mstatus = 0; + priv->intstate = INTSTATE_DONE; +#endif + } + } + } + + /* There is no pending message? Must be a spurious interrupt */ + + else + { + tiva_i2c_traceevent(priv, I2CEVENT_SPURIOUS, priv->msgc); + } + } + } + + /* Make sure that all pending interrupts were handled */ + +#ifndef CONFIG_I2C_POLLED + DEBUGASSERT(status == 0); +#endif + return OK; +} + +/************************************************************************************ + * Name: tiva_i2c0_interrupt + * + * Description: + * I2C0 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C0) +static int tiva_i2c0_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c0_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c1_interrupt + * + * Description: + * I2C1 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C1) +static int tiva_i2c1_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c1_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c2_interrupt + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C2) +static int tiva_i2c2_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c2_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c3_interrupt + * + * Description: + * I2C2 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C3) +static int tiva_i2c3_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c3_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c4_interrupt + * + * Description: + * I2C4 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C4) +static int tiva_i2c4_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c4_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c5_interrupt + * + * Description: + * I2C5 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C5) +static int tiva_i2c5_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c5_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c6_interrupt + * + * Description: + * I2C6 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C6) +static int tiva_i2c6_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c6_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c7_interrupt + * + * Description: + * I2C7 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C7) +static int tiva_i2c7_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c7_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c8_interrupt + * + * Description: + * I2C8 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C8) +static int tiva_i2c8_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c8_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c9_interrupt + * + * Description: + * I2C9 interrupt service routine + * + ************************************************************************************/ + +#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C9) +static int tiva_i2c9_interrupt(int irq, void *context) +{ + struct tiva_i2c_priv_s *priv; + uint32_t status; + + /* Read the masked interrupt status */ + + priv = &tiva_i2c9_priv; + status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET); + + /* Let the common interrupt handler do the rest of the work */ + + return tiva_i2c_interrupt(priv, status); +} +#endif + +/************************************************************************************ + * Name: tiva_i2c_initialize + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv, uint32_t frequency) +{ + const struct tiva_i2c_config_s *config = priv->config; + uint32_t regval; + int ret; + + i2cvdbg("I2C%d: refs=%d\n", config->devno, priv->refs); + + /* Enable power and clocking to the I2C peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the I2C + * peripheral. This is not an essential step since enabling clocking + * will also apply power. The only significance is that the I2C state + * will be retained if the I2C clocking is subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking to + * the I2C peripheral, bringing it a fully functional state. + */ + +#ifdef TIVA_SYSCON_RCGCI2C + tiva_i2c_enablepwr(config->devno); + tiva_i2c_enableclk(config->devno); + + i2cvdbg("I2C%d: RCGI2C[%08x]=%08x\n", + config->devno, TIVA_SYSCON_RCGCI2C, getreg32(TIVA_SYSCON_RCGCI2C)); +#else + modifyreg32(TIVA_SYSCON_RCGC1, 0, priv->rcgbit); + + i2cvdbg("I2C%d: RCGC1[%08x]=%08x\n", + config->devno, TIVA_SYSCON_RCGC1, getreg32(TIVA_SYSCON_RCGC1)); +#endif + + /* Reset the I2C block */ + +#ifdef TIVA_SYSCON_SRI2C + modifyreg32(TIVA_SYSCON_SRI2C, 0, SYSCON_SRI2C(config->devno)); + modifyreg32(TIVA_SYSCON_SRI2C, SYSCON_SRI2C(config->devno), 0); +#else + modifyreg32(TIVA_SYSCON_SRCR1, 0, priv->rstbit); + modifyreg32(TIVA_SYSCON_SRCR1, priv->rstbit, 0); +#endif + + /* Configure pins */ + + i2cvdbg("I2C%d: SCL=%08x SDA=%08x\n", + config->devno, config->scl_pin, config->sda_pin); + + ret = tiva_configgpio(config->scl_pin); + if (ret < 0) + { + i2cvdbg("I2C%d: tiva_configgpio(%08x) failed: %d\n", + config->scl_pin, ret); + return ret; + } + + ret = tiva_configgpio(config->sda_pin); + if (ret < 0) + { + i2cvdbg("I2C%d: tiva_configgpio(%08x) failed: %d\n", + config->sda_pin, ret); + tiva_configgpio(MKI2C_INPUT(config->scl_pin)); + return ret; + } + + /* Enable the I2C master block */ + + regval = tiva_i2c_getreg(priv, TIVA_I2CM_CR_OFFSET); + regval |= I2CM_CR_MFE; + tiva_i2c_putreg(priv, TIVA_I2CM_CR_OFFSET, regval); + +#ifdef TIVA_I2CSC_PC_OFFSET +#ifdef CONFIG_TIVA_I2C_HIGHSPEED + /* Enable high-speed mode */ + + tiva_i2c_putreg(priv, TIVA_I2CSC_PC_OFFSET, I2CSC_PC_HS); +#else + /* Disable high-speed mode */ + + tiva_i2c_putreg(priv, TIVA_I2CSC_PC_OFFSET, 0); +#endif +#endif + + /* Configure the the initial I2C clock frequency. */ + + tiva_i2c_setclock(priv, frequency); + + /* Attach interrupt handlers and enable interrupts at the NVIC (still + * disabled at the source). + */ + +#ifndef CONFIG_I2C_POLLED + (void)irq_attach(config->irq, config->isr); + up_enable_irq(config->irq); +#endif + + return OK; +} + +/************************************************************************************ + * Name: tiva_i2c_uninitialize + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv) +{ + uint32_t regval; + + i2cvdbg("I2C%d: refs=%d\n", priv->config->devno, priv->refs); + + /* Disable I2C */ + + regval = tiva_i2c_getreg(priv, TIVA_I2CM_CR_OFFSET); + regval &= ~I2CM_CR_MFE; + tiva_i2c_putreg(priv, TIVA_I2CM_CR_OFFSET, regval); + + /* Unconfigure GPIO pins */ + + tiva_configgpio(MKI2C_INPUT(priv->config->scl_pin)); + tiva_configgpio(MKI2C_INPUT(priv->config->sda_pin)); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->irq); + irq_detach(priv->config->irq); +#endif + + /* Disable clocking */ + +#ifdef TIVA_SYSCON_RCGCI2C + modifyreg32(TIVA_SYSCON_RCGCI2C, SYSCON_RCGCI2C(priv->config->devno), 0); +#else + modifyreg32(TIVA_SYSCON_RCGC1, priv->rcgbit, 0); +#endif + + return OK; +} + +/************************************************************************************ + * Name: tiva_i2c_setclock + * + * Description: + * Set the I2C frequency + * + ************************************************************************************/ + +static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency) +{ + uint32_t regval; + uint32_t tmp; + + i2cvdbg("I2C%d: frequency: %u\n", priv->config->devno, frequency); + + /* Has the I2C bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Calculate the clock divider that results in the highest frequency that + * is than or equal to the desired speed. + */ + + tmp = 2 * 10 * frequency; + regval = (((SYSCLK_FREQUENCY + tmp - 1) / tmp) - 1) << I2CM_TPR_SHIFT; + + DEBUGASSERT((regval & I2CM_TPR_MASK) == regval); + tiva_i2c_putreg(priv, TIVA_I2CM_TPR_OFFSET, regval); + +#if defined(CONFIG_TIVA_I2C_HIGHSPEED) && defined(TIVA_I2CSC_PC_OFFSET) + /* If the I2C peripheral is High-Speed enabled then choose the highest + * speed that is less than or equal to 3.4 Mbps. + */ + + regval = tiva_i2c_getreg(priv, TIVA_I2CSC_PC_OFFSET); + if ((regval & I2CSC_PC_HS) != 0) + { + tmp = (2 * 3 * 3400000); + regval = (((SYSCLK_FREQUENCY + tmp - 1) / tmp) - 1) << I2CM_TPR_SHIFT; + + tiva_i2c_putreg(priv, TIVA_I2CM_TPR_OFFSET, I2CM_TPR_HS | regval); + } +#endif + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/************************************************************************************ + * Name: tiva_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ************************************************************************************/ + +static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv, + int msgc) +{ + struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev; + uint32_t regval; + int ret = OK; + + DEBUGASSERT(priv && priv->config && msgv && msgc > 0); + i2cvdbg("I2C%d: msgc=%d\n", priv->config->devno, msgc); + + tiva_i2c_sem_wait(priv); /* Ensure that address or flags don't change meanwhile */ + + /* Reset mptr and mcnt to ensure an unexpected data interrupt doesn't + * overwrite stale data. + */ + + priv->mcnt = 0; + priv->mptr = NULL; + priv->msgv = msgv; + priv->msgc = msgc; + priv->mstatus = 0; + + /* Reset I2C trace logic */ + + tiva_i2c_tracereset(priv); + tiva_i2c_tracenew(priv, 0); + + /* Set I2C clock frequency + * + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + tiva_i2c_setclock(priv, msgv->frequency); + + /* Send the address, then the process moves into the ISR. I2C + * interrupts will be enabled within tiva_i2c_waitdone(). + */ + + tiva_i2c_startxfr(priv); + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (tiva_i2c_sem_waitdone(priv) < 0) + { + i2cdbg("I2C%d: ERROR: Timed out\n", priv->config->devno); + ret = -ETIMEDOUT; + } +#if 0 /* I2CM_CS_CLKTO */ + else if ((priv->mstatus & (I2CM_CS_ERROR | I2CM_CS_ARBLST | I2CM_CS_CLKTO)) != 0) +#else + else if ((priv->mstatus & (I2CM_CS_ERROR | I2CM_CS_ARBLST)) != 0) +#endif + { + i2cdbg("I2C%d: ERROR: I2C error status: %08x\n", + priv->config->devno, priv->mstatus); + + if ((priv->mstatus & I2CM_CS_ARBLST) != 0) + { + /* Arbitration Lost */ + + ret = -EAGAIN; + } + else if ((priv->mstatus & (I2CM_CS_ADRACK | I2CM_CS_DATACK)) != 0) + { + /* Acknowledge Failure */ + + ret = -ENXIO; + } +#if 0 /* I2CM_CS_CLKTO */ + else if ((priv->mstatus & I2CM_CS_CLKTO) != 0) + { + /* Timeout */ + + ret = -ETIME; + } +#endif + else + { + /* Something else? */ + + ret = -EIO; + } + } + + /* This is not an error, but should not happen. The I2CM_CS_BUSBSY signal + * can hang, however. This normally indicates the STOP was never sent, + * possibly because some other error occurred. + * + * The status bits are not valid if BUSY is set. But in this context I + * assume that busy bit stuck on would be a very bad situation, worthy + * of a reset. + */ + + regval = tiva_i2c_getreg(priv, TIVA_I2CM_CS_OFFSET); + if ((regval & (I2CM_CS_BUSY | I2CM_CS_BUSBSY)) != 0) + { + /* I2C Bus is for some reason busy. If I2CM_CS_BUSY then none of the + * other bits are valid. + */ + + i2cdbg("I2C%d: ERROR: I2C still busy: %08x\n", + priv->config->devno, regval); + + /* Reset and reinitialize the I2C hardware */ + + tiva_i2c_initialize(priv, priv->frequency); + + /* Is the busy condition a consequence of some other error? */ + + if (ret == OK) + { + /* No... then just being busy is the cause of the error */ + + ret = -EBUSY; + } + } + + /* Dump the trace result */ + + tiva_i2c_tracedump(priv); + + /* Ensure that no ISR happening after we finish can overwrite any user data */ + + priv->mcnt = 0; + priv->mptr = NULL; + + tiva_i2c_sem_post(priv); + return ret; +} + +/************************************************************************************ + * Name: tiva_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int tiva_i2c_reset(FAR struct i2c_master_s * dev) +{ + struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + int ret = ERROR; + + DEBUGASSERT(priv && priv->config); + i2cvdbg("I2C%d:\n", priv->config->devno); + + /* Our caller must own a ref */ + + ASSERT(priv->refs > 0); + + /* Lock out other clients */ + + tiva_i2c_sem_wait(priv); + + /* Un-initialize the port */ + + tiva_i2c_uninitialize(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + tiva_configgpio(scl_gpio); + tiva_configgpio(sda_gpio); + + /* Let SDA go high */ + + tiva_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!tiva_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!tiva_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + tiva_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + tiva_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + tiva_gpiowrite(sda_gpio, 0); + up_udelay(10); + tiva_gpiowrite(scl_gpio, 0); + up_udelay(10); + tiva_gpiowrite(scl_gpio, 1); + up_udelay(10); + tiva_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + tiva_configgpio(MKI2C_INPUT(sda_gpio)); + tiva_configgpio(MKI2C_INPUT(scl_gpio)); + + /* Re-init the port */ + + tiva_i2c_initialize(priv, priv->frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + tiva_i2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: tiva_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ************************************************************************************/ + +struct i2c_master_s *tiva_i2cbus_initialize(int port) +{ + struct tiva_i2c_priv_s *priv = NULL; + const struct tiva_i2c_config_s *config; + int flags; + + i2cvdbg("I2C%d: Initialize\n", port); + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_TIVA_I2C0 + case 0: + priv = &tiva_i2c0_priv; + config = &tiva_i2c0_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C1 + case 1: + priv = &tiva_i2c1_priv; + config = &tiva_i2c1_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C2 + case 2: + priv = &tiva_i2c2_priv; + config = &tiva_i2c2_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C3 + case 3: + priv = &tiva_i2c3_priv; + config = &tiva_i2c3_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C4 + case 4: + priv = &tiva_i2c4_priv; + config = &tiva_i2c4_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C5 + case 5: + priv = &tiva_i2c5_priv; + config = &tiva_i2c5_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C6 + case 6: + priv = &tiva_i2c6_priv; + config = &tiva_i2c6_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C7 + case 7: + priv = &tiva_i2c7_priv; + config = &tiva_i2c7_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C8 + case 8: + priv = &tiva_i2c8_priv; + config = &tiva_i2c8_config; + break; +#endif + +#ifdef CONFIG_TIVA_I2C9 + case 9: + priv = &tiva_i2c9_priv; + config = &tiva_i2c9_config; + break; +#endif + + default: + i2cdbg("I2C%d: ERROR: Not supported\n", port); + return NULL; + } + + /* Initialize private device structure */ + + priv->ops = &tiva_i2c_ops; + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + priv->refs++; + if (priv->refs == 1) + { + /* Initialize the device structure */ + + priv->config = config; + tiva_i2c_sem_init(priv); + + /* Initialize the I2C hardware */ + + tiva_i2c_initialize(priv, 100000); + } + + leave_critical_section(flags); + return (struct i2c_master_s *)priv; +} + +/************************************************************************************ + * Name: tiva_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ************************************************************************************/ + +int tiva_i2cbus_uninitialize(struct i2c_master_s *dev) +{ + struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev; + int flags; + + DEBUGASSERT(priv && priv->config && priv->refs > 0); + + i2cvdbg("I2C%d: Uninitialize\n", priv->config->devno); + + /* Decrement reference count and check for underflow */ + + flags = enter_critical_section(); + + /* Check if the reference count will decrement to zero */ + + if (priv->refs < 2) + { + /* Yes.. Disable power and other HW resource (GPIO's) */ + + tiva_i2c_uninitialize(priv); + priv->refs = 0; + + /* Release unused resources */ + + tiva_i2c_sem_destroy(priv); + } + else + { + /* No.. just decrement the number of references to the device */ + + priv->refs--; + } + + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_TIVA_I2C0 ... CONFIG_TIVA_I2C9 */ diff --git a/arch/arm/src/tiva/tiva_i2c.h b/arch/arm/src/tiva/tiva_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..33acca1116ca53075dce38f3b3c4a923d53560af --- /dev/null +++ b/arch/arm/src/tiva/tiva_i2c.h @@ -0,0 +1,89 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_i2c.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_I2C_H +#define __ARCH_ARM_SRC_TIVA_TIVA_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "chip/tiva_i2c.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *tiva_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: tiva_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the tiva_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int tiva_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_I2C_H */ diff --git a/arch/arm/src/tiva/tiva_irq.c b/arch/arm/src/tiva/tiva_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..67f8f1806020490de47f4c30dc6465fc90df2c0c --- /dev/null +++ b/arch/arm/src/tiva/tiva_irq.c @@ -0,0 +1,632 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_irq.c + * + * Copyright (C) 2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip.h" +#include "tiva_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void tiva_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + +#if NR_VECTORS < 64 + lldbg(" IRQ ENABLE: %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE)); +#elif NR_VECTORS < 96 + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); +#elif NR_VECTORS < 128 + lldbg(" IRQ ENABLE: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE), getreg32(NVIC_IRQ96_127_ENABLE)); +#endif +#if NR_VECTORS > 127 +# warning Missing output +#endif + + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); +#if NR_VECTORS > 47 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); +#endif +#if NR_VECTORS > 63 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); +#endif +#if NR_VECTORS > 79 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), getreg32(NVIC_IRQ92_95_PRIORITY)); +#endif +#if NR_VECTORS > 95 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), getreg32(NVIC_IRQ108_111_PRIORITY)); +#endif +#if NR_VECTORS > 111 + lldbg(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ112_115_PRIORITY), getreg32(NVIC_IRQ116_119_PRIORITY), + getreg32(NVIC_IRQ120_123_PRIORITY), getreg32(NVIC_IRQ124_127_PRIORITY)); +#endif +#if NR_VECTORS > 127 +# warning Missing output +#endif + leave_critical_section(flags); +} +#else +# define tiva_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: tiva_nmi, tiva_busfault, tiva_usagefault, tiva_pendsv, + * tiva_dbgmonitor, tiva_pendsv, tiva_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +static int tiva_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int tiva_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int tiva_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int tiva_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int tiva_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int tiva_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: tiva_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void tiva_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: tiva_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int tiva_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= TIVA_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= TIVA_IRQ_INTERRUPTS) + { + if (irq >= NR_IRQS) + { + return ERROR; /* Invalid IRQ number */ + } + + if (irq < TIVA_IRQ_INTERRUPTS + 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - TIVA_IRQ_INTERRUPTS); + } + else if (irq < TIVA_IRQ_INTERRUPTS + 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - TIVA_IRQ_INTERRUPTS - 32); + } +#if NR_VECTORS > 63 + else if (irq < TIVA_IRQ_INTERRUPTS + 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - TIVA_IRQ_INTERRUPTS - 64); + } +#if NR_VECTORS > 95 + else if (irq < TIVA_IRQ_INTERRUPTS + 128) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (irq - TIVA_IRQ_INTERRUPTS - 96); + } +#if NR_VECTORS > 127 +# warning Missing logic +#endif +#endif +#endif + else + { + return ERROR; /* Internal confusion */ + } + } + + /* Handler processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == TIVA_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == TIVA_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == TIVA_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == TIVA_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + +#ifdef CONFIG_ARCH_CHIP_CC3200 + putreg32((uint32_t)CONFIG_RAM_START, NVIC_VECTAB); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Initialize support for GPIO interrupts if included in this build */ + +#ifdef CONFIG_TIVA_GPIO_IRQS +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (tiva_gpioirqinitialize != NULL) +#endif + { + tiva_gpioirqinitialize(); + } +#endif + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(TIVA_IRQ_SVCALL, up_svcall); + irq_attach(TIVA_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(TIVA_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + tiva_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(TIVA_IRQ_MEMFAULT, up_memfault); + up_enable_irq(TIVA_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(TIVA_IRQ_NMI, tiva_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(TIVA_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(TIVA_IRQ_BUSFAULT, tiva_busfault); + irq_attach(TIVA_IRQ_USAGEFAULT, tiva_usagefault); + irq_attach(TIVA_IRQ_PENDSV, tiva_pendsv); + irq_attach(TIVA_IRQ_DBGMONITOR, tiva_dbgmonitor); + irq_attach(TIVA_IRQ_RESERVED, tiva_reserved); +#endif + + tiva_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (tiva_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= TIVA_IRQ_INTERRUPTS) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + tiva_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (tiva_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= TIVA_IRQ_INTERRUPTS) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + tiva_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= TIVA_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < TIVA_IRQ_INTERRUPTS) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= TIVA_IRQ_INTERRUPTS; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + tiva_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/tiva/tiva_lowputc.c b/arch/arm/src/tiva/tiva_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..e355fce67a74e266ef1124eef96a7153b60e1834 --- /dev/null +++ b/arch/arm/src/tiva/tiva_lowputc.c @@ -0,0 +1,375 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_lowputc.c + * + * Copyright (C) 2009-2010, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" +#include "tiva_periphrdy.h" +#include "tiva_gpio.h" +#include "chip/tiva_pinmap.h" + +#include "tiva_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration **********************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 0 +# define TIVA_CONSOLE_BASE TIVA_UART0_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART0_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART0_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART0_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 1 +# define TIVA_CONSOLE_BASE TIVA_UART1_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART1_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART1_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART1_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 2 +# define TIVA_CONSOLE_BASE TIVA_UART2_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART2_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART2_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART2_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 3 +# define TIVA_CONSOLE_BASE TIVA_UART3_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART3_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART3_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART3_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART3_2STOP +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 4 +# define TIVA_CONSOLE_BASE TIVA_UART4_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART4_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART4_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART4_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART4_2STOP +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 5 +# define TIVA_CONSOLE_BASE TIVA_UART5_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART5_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART5_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART5_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART5_2STOP +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 6 +# define TIVA_CONSOLE_BASE TIVA_UART6_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART6_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART6_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART6_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART6_2STOP +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define TIVA_CONSOLE_UART 7 +# define TIVA_CONSOLE_BASE TIVA_UART7_BASE +# define TIVA_CONSOLE_BAUD CONFIG_UART7_BAUD +# define TIVA_CONSOLE_BITS CONFIG_UART7_BITS +# define TIVA_CONSOLE_PARITY CONFIG_UART7_PARITY +# define TIVA_CONSOLE_2STOP CONFIG_UART7_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get LCRH settings */ + +#if TIVA_CONSOLE_BITS == 5 +# define UART_LCRH_NBITS UART_LCRH_WLEN_5BITS +#elif TIVA_CONSOLE_BITS == 6 +# define UART_LCRH_NBITS UART_LCRH_WLEN_6BITS +#elif TIVA_CONSOLE_BITS == 7 +# define UART_LCRH_NBITS UART_LCRH_WLEN_7BITS +#elif TIVA_CONSOLE_BITS == 8 +# define UART_LCRH_NBITS UART_LCRH_WLEN_8BITS +#else +# error "Number of bits not supported" +#endif + +#if TIVA_CONSOLE_PARITY == 0 +# define UART_LCRH_PARITY (0) +#elif TIVA_CONSOLE_PARITY == 1 +# define UART_LCRH_PARITY UART_LCRH_PEN +#elif TIVA_CONSOLE_PARITY == 2 +# define UART_LCRH_PARITY (UART_LCRH_PEN|UART_LCRH_EPS) +#else +# error "Invalid parity selection" +#endif + +#if TIVA_CONSOLE_2STOP != 0 +# define UART_LCRH_NSTOP UART_LCRH_STP2 +#else +# define UART_LCRH_NSTOP (0) +#endif + +#define UART_LCRH_VALUE (UART_LCRH_NBITS|UART_LCRH_PARITY|UART_LCRH_NSTOP|UART_LCRH_FEN) + +/* Calculate BAUD rate from the SYS clock: + * + * "The baud-rate divisor is a 22-bit number consisting of a 16-bit integer and a 6-bit + * fractional part. The number formed by these two values is used by the baud-rate generator + * to determine the bit period. Having a fractional baud-rate divider allows the UART to + * generate all the standard baud rates. + * + * "The 16-bit integer is loaded through the UART Integer Baud-Rate Divisor (UARTIBRD) + * register ... and the 6-bit fractional part is loaded with the UART Fractional Baud-Rate + * Divisor (UARTFBRD) register... The baud-rate divisor (BRD) has the following relationship + * to the system clock (where BRDI is the integer part of the BRD and BRDF is the fractional + * part, separated by a decimal place.): + * + * "BRD = BRDI + BRDF = UARTSysClk / (16 * Baud Rate) + * + * "where UARTSysClk is the system clock connected to the UART. The 6-bit fractional number + * (that is to be loaded into the DIVFRAC bit field in the UARTFBRD register) can be calculated + * by taking the fractional part of the baud-rate divisor, multiplying it by 64, and adding 0.5 + * to account for rounding errors: + * + * "UARTFBRD[DIVFRAC] = integer(BRDF * 64 + 0.5) + * + * "The UART generates an internal baud-rate reference clock at 16x the baud-rate (referred + * to as Baud16). This reference clock is divided by 16 to generate the transmit clock, and is + * used for error detection during receive operations. + * + * "Along with the UART Line Control, High Byte (UARTLCRH) register ..., the UARTIBRD and + * UARTFBRD registers form an internal 30-bit register. This internal register is only + * updated when a write operation to UARTLCRH is performed, so any changes to the baud-rate + * divisor must be followed by a write to the UARTLCRH register for the changes to take effect. ..." + */ + +#define TIVA_BRDDEN (16 * TIVA_CONSOLE_BAUD) +#define TIVA_BRDI (SYSCLK_FREQUENCY / TIVA_BRDDEN) +#define TIVA_REMAINDER (SYSCLK_FREQUENCY - TIVA_BRDDEN * TIVA_BRDI) +#define TIVA_DIVFRAC ((TIVA_REMAINDER * 64 + (TIVA_BRDDEN/2)) / TIVA_BRDDEN) + +/* For example: TIVA_CONSOLE_BAUD = 115,200, SYSCLK_FREQUENCY = 50,000,000: + * + * TIVA_BRDDEN = (16 * 115,200) = 1,843,200 + * TIVA_BRDI = 50,000,000 / 1,843,200 = 27 + * TIVA_REMAINDER = 50,000,000 - 1,843,200 * 27 = 233,600 + * TIVA_DIVFRAC = (233,600 * 64 + 921,600) / 1,843,200 = 8 + * + * Which should yied BAUD = 50,000,000 / (16 * (27 + 8/64)) = 115207.37 + */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait until the TX FIFO is not full */ + + while ((getreg32(TIVA_CONSOLE_BASE + TIVA_UART_FR_OFFSET) & UART_FR_TXFF) != 0); + + /* Then send the character */ + + putreg32((uint32_t)ch, TIVA_CONSOLE_BASE + TIVA_UART_DR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowsetup(void) +{ +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t ctl; +#endif + + /* Enable the selected UARTs and configure GPIO pins needed by the + * the selected UARTs. NOTE: The serial driver later depends on + * this pin configuration -- whether or not a serial console is selected. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the UART + * peripheral. This is not an essential step since enabling clocking + * will also apply power. The only significance is that the UART state + * will be retained if the UART clocking is subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking to + * the UART peripheral, bringing it a fully functional state. + */ + +#ifdef CONFIG_TIVA_UART0 + tiva_uart0_enablepwr(); + tiva_uart0_enableclk(); + + tiva_configgpio(GPIO_UART0_RX); + tiva_configgpio(GPIO_UART0_TX); +#endif + +#ifdef CONFIG_TIVA_UART1 + tiva_uart1_enablepwr(); + tiva_uart1_enableclk(); + + tiva_configgpio(GPIO_UART1_RX); + tiva_configgpio(GPIO_UART1_TX); +#endif + +#ifdef CONFIG_TIVA_UART2 + tiva_uart2_enablepwr(); + tiva_uart2_enableclk(); + + tiva_configgpio(GPIO_UART2_RX); + tiva_configgpio(GPIO_UART2_TX); +#endif + +#ifdef CONFIG_TIVA_UART3 + tiva_uart3_enablepwr(); + tiva_uart3_enableclk(); + + tiva_configgpio(GPIO_UART3_RX); + tiva_configgpio(GPIO_UART3_TX); +#endif + +#ifdef CONFIG_TIVA_UART4 + tiva_uart4_enablepwr(); + tiva_uart4_enableclk(); + + tiva_configgpio(GPIO_UART4_RX); + tiva_configgpio(GPIO_UART4_TX); +#endif + +#ifdef CONFIG_TIVA_UART5 + tiva_uart5_enablepwr(); + tiva_uart5_enableclk(); + + tiva_configgpio(GPIO_UART5_RX); + tiva_configgpio(GPIO_UART5_TX); +#endif + +#ifdef CONFIG_TIVA_UART6 + tiva_uart6_enablepwr(); + tiva_uart6_enableclk(); + + tiva_configgpio(GPIO_UART6_RX); + tiva_configgpio(GPIO_UART6_TX); +#endif + +#ifdef CONFIG_TIVA_UART7 + tiva_uart7_enablepwr(); + tiva_uart7_enableclk(); + + tiva_configgpio(GPIO_UART7_RX); + tiva_configgpio(GPIO_UART7_TX); +#endif + + /* Enable the selected console device */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) +#ifdef TIVA_SYSCON_PRUART + /* Wait for the console UART to be ready before writing to the UART + * registers. + */ + + while (!tiva_periphrdy(TIVA_SYSCON_PRUART, + SYSCON_PRUART(TIVA_CONSOLE_UART))); +#endif + + /* Disable the UART by clearing the UARTEN bit in the UART CTL register */ + + ctl = getreg32(TIVA_CONSOLE_BASE + TIVA_UART_CTL_OFFSET); + ctl &= ~UART_CTL_UARTEN; + putreg32(ctl, TIVA_CONSOLE_BASE + TIVA_UART_CTL_OFFSET); + + /* Write the integer portion of the BRD to the UART IBRD register */ + + putreg32(TIVA_BRDI, TIVA_CONSOLE_BASE + TIVA_UART_IBRD_OFFSET); + + /* Write the fractional portion of the BRD to the UART FBRD register */ + + putreg32(TIVA_DIVFRAC, TIVA_CONSOLE_BASE + TIVA_UART_FBRD_OFFSET); + + /* Write the desired serial parameters to the UART LCRH register */ + + putreg32(UART_LCRH_VALUE, TIVA_CONSOLE_BASE + TIVA_UART_LCRH_OFFSET); + + /* Enable the UART by setting the UARTEN bit in the UART CTL register */ + + ctl |= (UART_CTL_UARTEN | UART_CTL_TXE | UART_CTL_RXE); + putreg32(ctl, TIVA_CONSOLE_BASE + TIVA_UART_CTL_OFFSET); +#endif +} diff --git a/arch/arm/src/tiva/tiva_lowputc.h b/arch/arm/src/tiva/tiva_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..405813ee8fb92b9abb3faff4535221286f100111 --- /dev/null +++ b/arch/arm/src/tiva/tiva_lowputc.h @@ -0,0 +1,205 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_lowputc.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_LOWPUTC_H +#define __ARCH_ARM_SRC_TIVA_TIVA_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration *******************************************************************/ + +#if TIVA_NUARTS < 8 +# undef CONFIG_TIVA_UART7 +# undef CONFIG_UART7_SERIAL_CONSOLE +# if TIVA_NUARTS < 7 +# undef CONFIG_TIVA_UART6 +# undef CONFIG_UART6_SERIAL_CONSOLE +# if TIVA_NUARTS < 6 +# undef CONFIG_TIVA_UART5 +# undef CONFIG_UART5_SERIAL_CONSOLE +# if TIVA_NUARTS < 5 +# undef CONFIG_TIVA_UART4 +# undef CONFIG_UART4_SERIAL_CONSOLE +# if TIVA_NUARTS < 4 +# undef CONFIG_TIVA_UART3 +# undef CONFIG_UART3_SERIAL_CONSOLE +# if TIVA_NUARTS < 3 +# undef CONFIG_TIVA_UART2 +# undef CONFIG_UART2_SERIAL_CONSOLE +# if TIVA_NUARTS < 2 +# undef CONFIG_TIVA_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# endif +# endif +# endif +# endif +# endif +# endif +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART0) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART1) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART2) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART3) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART4) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART5) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART6) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_TIVA_UART7) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# warning "No valid CONFIG_UARTn_SERIAL_CONSOLE Setting" +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization. + * + ****************************************************************************/ + +void up_lowsetup(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_LOWPUTC_H */ diff --git a/arch/arm/src/tiva/tiva_mpuinit.c b/arch/arm/src/tiva/tiva_mpuinit.c new file mode 100644 index 0000000000000000000000000000000000000000..a9a6aed9a21aec795cfa83b6b03d6a1b9fc8694f --- /dev/null +++ b/arch/arm/src/tiva/tiva_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_mpuinit.c + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "tiva_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void tiva_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: tiva_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void tiva_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/tiva/tiva_mpuinit.h b/arch/arm/src/tiva/tiva_mpuinit.h new file mode 100644 index 0000000000000000000000000000000000000000..82dde88d74a0d0a90ae1cd451f4a3a4e259e1539 --- /dev/null +++ b/arch/arm/src/tiva/tiva_mpuinit.h @@ -0,0 +1,90 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_mpuinit.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_MPUINIT_H +#define __ARCH_ARM_SRC_TIVA_TIVA_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: tiva_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void tiva_mpuinitialize(void); +#else +# define tiva_mpuinitialize() +#endif + +/**************************************************************************** + * Name: tiva_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void tiva_mpu_uheap(uintptr_t start, size_t size); +#else +# define tiva_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_MPUINIT_H */ diff --git a/arch/arm/src/tiva/tiva_periphrdy.h b/arch/arm/src/tiva/tiva_periphrdy.h new file mode 100644 index 0000000000000000000000000000000000000000..b7e86158d8e9aeb1e07a081434ddc82be18629d2 --- /dev/null +++ b/arch/arm/src/tiva/tiva_periphrdy.h @@ -0,0 +1,309 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_periphrdy.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVAPERIPHRDY_H +#define __ARCH_ARM_SRC_TIVA_TIVAPERIPHRDY_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/tiva_syscontrol.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* We determine if a peripheral is ready by testing a bit (b) in system control + * register (a). + */ + +#define tiva_periphrdy(a,b) ((getreg32(a) & (b)) != 0) + +/* Watchdog Timer Power Control */ + +#ifdef TIVA_SYSCON_PRWD +# define tiva_wdt_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRWD,SYSCON_PRWD(p)) +#else +# define tiva_wdt_periphrdy(p) (true) +#endif + +#define tiva_wdt0_periphrdy() tiva_wdt_periphrdy(0) +#define tiva_wdt1_periphrdy() tiva_wdt_periphrdy(1) + +/* 16/32-Bit Timer Power Control */ + +#ifdef TIVA_SYSCON_PRTIMER +# define tiva_gptm_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRTIMER,SYSCON_PRTIMER(p)) +#else +# define tiva_gptm_periphrdy(p) (true) +#endif + +#define tiva_gptm0_periphrdy() tiva_gptm_periphrdy(0) +#define tiva_gptm1_periphrdy() tiva_gptm_periphrdy(1) +#define tiva_gptm2_periphrdy() tiva_gptm_periphrdy(2) +#define tiva_gptm3_periphrdy() tiva_gptm_periphrdy(3) +#define tiva_gptm4_periphrdy() tiva_gptm_periphrdy(4) +#define tiva_gptm5_periphrdy() tiva_gptm_periphrdy(5) +#define tiva_gptm6_periphrdy() tiva_gptm_periphrdy(6) +#define tiva_gptm7_periphrdy() tiva_gptm_periphrdy(7) + +/* GPIO Power Control */ + +#ifdef TIVA_SYSCON_PRGPIO +# define tiva_gpio_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRGPIO,SYSCON_PRGPIO(p)) +#else +# define tiva_gpio_periphrdy(p) (true) +#endif + +#define tiva_gpioa_periphrdy() tiva_gpio_periphrdy(0) +#define tiva_gpiob_periphrdy() tiva_gpio_periphrdy(1) +#define tiva_gpioc_periphrdy() tiva_gpio_periphrdy(2) +#define tiva_gpiod_periphrdy() tiva_gpio_periphrdy(3) +#define tiva_gpioe_periphrdy() tiva_gpio_periphrdy(4) +#define tiva_gpiof_periphrdy() tiva_gpio_periphrdy(5) +#define tiva_gpiog_periphrdy() tiva_gpio_periphrdy(6) +#define tiva_gpioh_periphrdy() tiva_gpio_periphrdy(7) +#define tiva_gpioj_periphrdy() tiva_gpio_periphrdy(8) +#define tiva_gpiok_periphrdy() tiva_gpio_periphrdy(9) +#define tiva_gpiol_periphrdy() tiva_gpio_periphrdy(10) +#define tiva_gpiom_periphrdy() tiva_gpio_periphrdy(11) +#define tiva_gpion_periphrdy() tiva_gpio_periphrdy(12) +#define tiva_gpiop_periphrdy() tiva_gpio_periphrdy(13) +#define tiva_gpioq_periphrdy() tiva_gpio_periphrdy(14) +#define tiva_gpior_periphrdy() tiva_gpio_periphrdy(15) +#define tiva_gpios_periphrdy() tiva_gpio_periphrdy(16) +#define tiva_gpiot_periphrdy() tiva_gpio_periphrdy(17) + +/* μDMA Power Control */ + +#ifdef TIVA_SYSCON_PRDMA +# define tiva_udma_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRDMA,SYSCON_PRDMA_R0) +#else +# define tiva_udma_periphrdy() (true) +#endif + +/* EPI Power Control */ + +#ifdef TIVA_SYSCON_PREPI +# define tiva_epi_periphrdy() tiva_periphrdy(TIVA_SYSCON_PREPI,SYSCON_PREPI_R0) +#else +# define tiva_epi_periphrdy() (true) +#endif + +/* Hibernation Power Control */ + +#ifdef TIVA_SYSCON_PRHIB +# define tiva_hib_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRHIB,SYSCON_PRHIB_R0) +#else +# define tiva_hib_periphrdy() (true) +#endif + +/* UART Power Control */ + +#ifdef TIVA_SYSCON_PRUART +# define tiva_uart_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRUART,SYSCON_PRUART(p)) +#else +# define tiva_uart_periphrdy(p) (true) +#endif + +#define tiva_uart0_periphrdy() tiva_uart_periphrdy(0) +#define tiva_uart1_periphrdy() tiva_uart_periphrdy(1) +#define tiva_uart2_periphrdy() tiva_uart_periphrdy(2) +#define tiva_uart3_periphrdy() tiva_uart_periphrdy(3) +#define tiva_uart4_periphrdy() tiva_uart_periphrdy(4) +#define tiva_uart5_periphrdy() tiva_uart_periphrdy(5) +#define tiva_uart6_periphrdy() tiva_uart_periphrdy(6) +#define tiva_uart7_periphrdy() tiva_uart_periphrdy(7) + +/* SSI Power Control */ + +#ifdef TIVA_SYSCON_PRSSI +# define tiva_ssi_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRSSI,SYSCON_PRSSI(p)) +#else +# define tiva_ssi_periphrdy(p) (true) +#endif + +#define tiva_ssi0_periphrdy() tiva_ssi_periphrdy(0) +#define tiva_ssi1_periphrdy() tiva_ssi_periphrdy(1) +#define tiva_ssi2_periphrdy() tiva_ssi_periphrdy(2) +#define tiva_ssi3_periphrdy() tiva_ssi_periphrdy(3) + +/* I2C Power Control */ + +#ifdef TIVA_SYSCON_PRI2C +# define tiva_i2c_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRI2C,SYSCON_PRI2C(p)) +#else +# define tiva_i2c_periphrdy(p) (true) +#endif + +#define tiva_i2c0_periphrdy() tiva_i2c_periphrdy(0) +#define tiva_i2c1_periphrdy() tiva_i2c_periphrdy(1) +#define tiva_i2c2_periphrdy() tiva_i2c_periphrdy(2) +#define tiva_i2c3_periphrdy() tiva_i2c_periphrdy(3) +#define tiva_i2c4_periphrdy() tiva_i2c_periphrdy(4) +#define tiva_i2c5_periphrdy() tiva_i2c_periphrdy(5) +#define tiva_i2c6_periphrdy() tiva_i2c_periphrdy(6) +#define tiva_i2c7_periphrdy() tiva_i2c_periphrdy(7) +#define tiva_i2c8_periphrdy() tiva_i2c_periphrdy(8) +#define tiva_i2c9_periphrdy() tiva_i2c_periphrdy(9) + +/* USB Power Control */ + +#ifdef TIVA_SYSCON_PRUSB +# define tiva_usb_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRUSB,SYSCON_PRUSB_R0) +#else +# define tiva_usb_periphrdy() (true) +#endif + +/* Ethernet PHY Power Control */ + +#ifdef TIVA_SYSCON_PREPHY +# define tiva_ephy_periphrdy() tiva_periphrdy(TIVA_SYSCON_PREPHY,SYSCON_PREPHY_R0) +#else +# define tiva_ephy_periphrdy() (true) +#endif + +/* CAN RunMode Clock Gating Control */ + +#ifdef TIVA_SYSCON_PRCAN +# define tiva_can_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRCAN,SYSCON_PRCAN(p)) +#else +# define tiva_can_periphrdy(p) (true) +#endif + +#define tiva_can0_periphrdy() tiva_can_periphrdy(0) +#define tiva_can1_periphrdy() tiva_can_periphrdy(1) + +/* ADC Power Control */ + +#ifdef TIVA_SYSCON_PRADC +# define tiva_adc_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRADC,SYSCON_PRADC(p)) +#else +# define tiva_adc_periphrdy(p) (true) +#endif + +#define tiva_adc0_periphrdy() tiva_adc_periphrdy(0) +#define tiva_adc1_periphrdy() tiva_adc_periphrdy(1) + +/* ACMP Power Control */ + +#ifdef TIVA_SYSCON_PRACMP +# define tiva_acmp_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRACMP,SYSCON_PRACMP_R0) +#else +# define tiva_acmp_periphrdy() (true) +#endif + +/* PWM Power Control */ + +#ifdef TIVA_SYSCON_PRPWM +# define tiva_pwm_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRPWM,SYSCON_PRPWM(p)) +#else +# define tiva_pwm_periphrdy(p) (true) +#endif + +#define tiva_pwm0_periphrdy() tiva_pwm_periphrdy(0) +#define tiva_pwm1_periphrdy() tiva_pwm_periphrdy(1) + +/* QE Interface Power Control */ + +#ifdef TIVA_SYSCON_PRQEI +# define tiva_qei_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRQEI,SYSCON_PRQEI(p)) +#else +# define tiva_qei_periphrdy(p) (true) +#endif + +#define tiva_qei0_periphrdy() tiva_qei_periphrdy(0) +#define tiva_qei1_periphrdy() tiva_qei_periphrdy(1) + +/* EEPROM Power Control */ + +#ifdef TIVA_SYSCON_PREEPROM +# define tiva_eeprom_periphrdy() tiva_periphrdy(TIVA_SYSCON_PREEPROM,SYSCON_PREEPROM_R0) +#else +# define tiva_eeprom_periphrdy() (true) +#endif + +/* 32/64-Bit Wide Timer Power Control */ + +#ifdef TIVA_SYSCON_PRWTIMER +# define tiva_wtm_periphrdy(p) tiva_periphrdy(TIVA_SYSCON_PRWTIMER,SYSCON_PRWTIMER(p)) +#else +# define tiva_wtm_periphrdy(p) (true) +#endif + +#define tiva_wtm0_periphrdy() tiva_wtm_periphrdy(0) +#define tiva_wtm1_periphrdy() tiva_wtm_periphrdy(1) +#define tiva_wtm2_periphrdy() tiva_wtm_periphrdy(2) +#define tiva_wtm3_periphrdy() tiva_wtm_periphrdy(3) +#define tiva_wtm4_periphrdy() tiva_wtm_periphrdy(4) +#define tiva_wtm5_periphrdy() tiva_wtm_periphrdy(5) + +/* CRC/Crypto Modules RunMode ClockGating Control */ + +#ifdef TIVA_SYSCON_PRCCM +# define tiva_ccm_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRCCM,SYSCON_PRCCM_R0) +#else +# define tiva_ccm_periphrdy() (true) +#endif + +/* LCD Controller Power Control */ + +#ifdef TIVA_SYSCON_PRLCD +# define tiva_lcd_periphrdy() tiva_periphrdy(TIVA_SYSCON_PRLCD,SYSCON_PRLCD_R0) +#else +# define tiva_lcd_periphrdy() (true) +#endif + +/* 1-Wire Power Control */ + +#ifdef TIVA_SYSCON_PROWIRE +# define tiva_owire_periphrdy() tiva_periphrdy(TIVA_SYSCON_PROWIRE,SYSCON_PROWIRE_R0) +#else +# define tiva_owire_periphrdy() (true) +#endif + +/* Ethernet MAC Power Control */ + +#ifdef TIVA_SYSCON_PREMAC +# define tiva_emac_periphrdy() tiva_periphrdy(TIVA_SYSCON_PREMAC,SYSCON_PREMAC_R0) +#else +# define tiva_emac_periphrdy() (true) +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVAPERIPHRDY_H */ diff --git a/arch/arm/src/tiva/tiva_serial.c b/arch/arm/src/tiva/tiva_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..fb9ea3ee61aac155eb38b15a7552bf1430f91808 --- /dev/null +++ b/arch/arm/src/tiva/tiva_serial.c @@ -0,0 +1,1408 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_serial.c + * + * Copyright (C) 2009-2010, 2012-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "tiva_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Is there a UART enabled? */ + +#if !defined(CONFIG_TIVA_UART0) && !defined(CONFIG_TIVA_UART1) && !defined(CONFIG_TIVA_UART2) && \ + !defined(CONFIG_TIVA_UART3) && !defined(CONFIG_TIVA_UART4) && !defined(CONFIG_TIVA_UART5) && \ + !defined(CONFIG_TIVA_UART6) && !defined(CONFIG_TIVA_UART7) +# error "No UARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we + * still must provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1-7? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-5 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART5 is console */ +# define TTYS5_DEV g_uart5port /* UART5 is ttyS0 */ +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart6port /* UART6 is console */ +# define TTYS5_DEV g_uart6port /* UART6 is ttyS0 */ +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart7port /* UART7 is console */ +# define TTYS5_DEV g_uart7port /* UART7 is ttyS0 */ +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_TIVA_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART5) +# define TTYS0_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART6) +# define TTYS0_DEV g_uart6port /* UART5 is ttyS0 */ +# define UART6_ASSIGNED 1 +# elif defined(CONFIG_TIVA_UART7) +# define TTYS0_DEV g_uart7port /* UART5 is ttyS0 */ +# define UART7_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-7 excluding the console UART. */ + +#if defined(CONFIG_TIVA_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS1_DEV g_uart6port /* UART6 is ttyS1 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS1_DEV g_uart7port /* UART7 is ttyS1 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-7. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-7 could also be the + * console. + */ + +#if defined(CONFIG_TIVA_UART1) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS2_DEV g_uart6port /* UART6 is ttyS2 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS2_DEV g_uart7port /* UART7 is ttyS2 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-7. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-7 could also be the console. + */ + +#if defined(CONFIG_TIVA_UART2) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS3_DEV g_uart6port /* UART6 is ttyS3 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS3_DEV g_uart7port /* UART7 is ttyS3 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART3-7. It can't be UART0-2 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 3-7 could also be the console. + */ + +#if defined(CONFIG_TIVA_UART3) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart3port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS4_DEV g_uart6port /* UART6 is ttyS4 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS4_DEV g_uart7port /* UART7 is ttyS4 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART4-7. It can't be UART0-3 because + * those have already been assigned to ttsyS0, 1, 2, 3 or 4. One of + * UART 4-7 could also be the console. + */ + +#if defined(CONFIG_TIVA_UART4) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS5_DEV g_uart5port /* UART5 is ttyS5 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS5_DEV g_uart6port /* UART6 is ttyS5 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS5_DEV g_uart7port /* UART7 is ttyS5 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys6. This could be one of UART5-7. It can't be UART0-4 because + * those have already been assigned to ttsyS0, 1, 2, 3, 4, or 5. One of + * UART 5-7 could also be the console. + */ + +#if defined(CONFIG_TIVA_UART5) && !defined(UART5_ASSIGNED) +# define TTYS6_DEV g_uart5port /* UART5 is ttyS6 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS6_DEV g_uart6port /* UART6 is ttyS6 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS6_DEV g_uart7port /* UART7 is ttyS6 */ +# define UART7_ASSIGNED 1 +#endif + +/* Pick ttys7. This could be one of UART6-7. It can't be UART0-5 because + * those have already been assigned to ttsyS0, 1, 2, 3, 4, or 6. One of + * UART 6-7 could also be the console. + */ + +#if defined(CONFIG_TIVA_UART6) && !defined(UART6_ASSIGNED) +# define TTYS7_DEV g_uart6port /* UART6 is ttyS7 */ +# define UART6_ASSIGNED 1 +#elif defined(CONFIG_TIVA_UART7) && !defined(UART7_ASSIGNED) +# define TTYS7_DEV g_uart7port /* UART7 is ttyS7 */ +# define UART7_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t im; /* Saved IM value */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_TIVA_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART6 +static char g_uart6rxbuffer[CONFIG_UART6_RXBUFSIZE]; +static char g_uart6txbuffer[CONFIG_UART6_TXBUFSIZE]; +#endif +#ifdef CONFIG_TIVA_UART7 +static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; +static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; +#endif + +/* This describes the state of the Stellaris uart0 port. */ + +#ifdef CONFIG_TIVA_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = TIVA_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = TIVA_IRQ_UART0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the Stellaris uart1 port. */ + +#ifdef CONFIG_TIVA_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = TIVA_UART1_BASE, + .baud = CONFIG_UART1_BAUD, + .irq = TIVA_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the Stellaris uart2 port. */ + +#ifdef CONFIG_TIVA_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = TIVA_UART2_BASE, + .baud = CONFIG_UART2_BAUD, + .irq = TIVA_IRQ_UART2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the Stellaris uart3 port. */ + +#ifdef CONFIG_TIVA_UART3 +static struct up_dev_s g_uart3priv = +{ + .uartbase = TIVA_UART3_BASE, + .baud = CONFIG_UART3_BAUD, + .irq = TIVA_IRQ_UART3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the Stellaris uart4 port. */ + +#ifdef CONFIG_TIVA_UART4 +static struct up_dev_s g_uart4priv = +{ + .uartbase = TIVA_UART4_BASE, + .baud = CONFIG_UART4_BAUD, + .irq = TIVA_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the Stellaris uart5 port. */ + +#ifdef CONFIG_TIVA_UART5 +static struct up_dev_s g_uart5priv = +{ + .uartbase = TIVA_UART5_BASE, + .baud = CONFIG_UART5_BAUD, + .irq = TIVA_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +}; + +static uart_dev_t g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +/* This describes the state of the Stellaris uart6 port. */ + +#ifdef CONFIG_TIVA_UART6 +static struct up_dev_s g_uart6priv = +{ + .uartbase = TIVA_UART6_BASE, + .baud = CONFIG_UART6_BAUD, + .irq = TIVA_IRQ_UART6, + .parity = CONFIG_UART6_PARITY, + .bits = CONFIG_UART6_BITS, + .stopbits2 = CONFIG_UART6_2STOP, +}; + +static uart_dev_t g_uart6port = +{ + .recv = + { + .size = CONFIG_UART6_RXBUFSIZE, + .buffer = g_uart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART6_TXBUFSIZE, + .buffer = g_uart6txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart6priv, +}; +#endif + +/* This describes the state of the Stellaris uart7 port. */ + +#ifdef CONFIG_TIVA_UART7 +static struct up_dev_s g_uart7priv = +{ + .uartbase = TIVA_UART7_BASE, + .baud = CONFIG_UART7_BAUD, + .irq = TIVA_IRQ_UART7, + .parity = CONFIG_UART7_PARITY, + .bits = CONFIG_UART7_BITS, + .stopbits2 = CONFIG_UART7_2STOP, +}; + +static uart_dev_t g_uart7port = +{ + .recv = + { + .size = CONFIG_UART7_RXBUFSIZE, + .buffer = g_uart7rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART7_TXBUFSIZE, + .buffer = g_uart7txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart7priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint32_t *im) +{ + /* Return the current interrupt mask value */ + + if (im) + { + *im = priv->im; + } + + /* Disable all interrupts */ + + priv->im = 0; + up_serialout(priv, TIVA_UART_IM_OFFSET, 0); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint32_t im) +{ + priv->im = im; + up_serialout(priv, TIVA_UART_IM_OFFSET, im); +} + +/**************************************************************************** + * Name: up_waittxnotfull + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +static inline void up_waittxnotfull(struct up_dev_s *priv) +{ + volatile int tmp; + + /* Limit how long we will wait for the TX available condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check Tx FIFO is full */ + + if ((up_serialin(priv, TIVA_UART_FR_OFFSET) & UART_FR_TXFF) == 0) + { + /* The Tx FIFO is not full... return */ + + break; + } + } + + /* If we get here, then the wait has timed out and the Tx FIFO remains + * full. + */ +} +#endif + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t lcrh; + uint32_t ctl; +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t den; + uint32_t brdi; + uint32_t remainder; + uint32_t divfrac; + + /* Note: The logic here depends on the fact that that the UART module + * was enabled and the GPIOs were configured in up_lowsetup(). + */ + + /* Disable the UART by clearing the UARTEN bit in the UART CTL register */ + + ctl = up_serialin(priv, TIVA_UART_CTL_OFFSET); + ctl &= ~UART_CTL_UARTEN; + up_serialout(priv, TIVA_UART_CTL_OFFSET, ctl); + + /* Calculate BAUD rate from the SYS clock: + * + * "The baud-rate divisor is a 22-bit number consisting of a 16-bit integer + * and a 6-bit fractional part. The number formed by these two values is + * used by the baud-rate generator to determine the bit period. Having a + * fractional baud-rate divider allows the UART to generate all the standard + * baud rates. + * + * "The 16-bit integer is loaded through the UART Integer Baud-Rate Divisor + * (UARTIBRD) register ... and the 6-bit fractional part is loaded with the + * UART Fractional Baud-Rate Divisor (UARTFBRD) register... The baud-rate + * divisor (BRD) has the following relationship to the system clock (where + * BRDI is the integer part of the BRD and BRDF is the fractional part, + * separated by a decimal place.): + * + * "BRD = BRDI + BRDF = UARTSysClk / (16 * Baud Rate) + * + * "where UARTSysClk is the system clock connected to the UART. The 6-bit + * fractional number (that is to be loaded into the DIVFRAC bit field in the + * UARTFBRD register) can be calculated by taking the fractional part of the + * baud-rate divisor, multiplying it by 64, and adding 0.5 to account for + * rounding errors: + * + * "UARTFBRD[DIVFRAC] = integer(BRDF * 64 + 0.5) + * + * "The UART generates an internal baud-rate reference clock at 16x the baud- + * rate (referred to as Baud16). This reference clock is divided by 16 to + * generate the transmit clock, and is used for error detection during receive + * operations. + * + * "Along with the UART Line Control, High Byte (UARTLCRH) register ..., the + * UARTIBRD and UARTFBRD registers form an internal 30-bit register. This + * internal register is only updated when a write operation to UARTLCRH is + * performed, so any changes to the baud-rate divisor must be followed by a + * write to the UARTLCRH register for the changes to take effect. ..." + */ + + den = priv->baud << 4; + brdi = SYSCLK_FREQUENCY / den; + remainder = SYSCLK_FREQUENCY - den * brdi; + divfrac = ((remainder << 6) + (den >> 1)) / den; + + up_serialout(priv, TIVA_UART_IBRD_OFFSET, brdi); + up_serialout(priv, TIVA_UART_FBRD_OFFSET, divfrac); + + /* Set up the LCRH register */ + + lcrh = 0; + switch (priv->bits) + { + case 5: + lcrh |= UART_LCRH_WLEN_5BITS; + break; + case 6: + lcrh |= UART_LCRH_WLEN_6BITS; + break; + case 7: + lcrh |= UART_LCRH_WLEN_7BITS; + break; + case 8: + default: + lcrh |= UART_LCRH_WLEN_8BITS; + break; + } + + switch (priv->parity) + { + case 0: + default: + break; + case 1: + lcrh |= UART_LCRH_PEN; + break; + case 2: + lcrh |= UART_LCRH_PEN | UART_LCRH_EPS; + break; + } + + if (priv->stopbits2) + { + lcrh |= UART_LCRH_STP2; + } + + up_serialout(priv, TIVA_UART_LCRH_OFFSET, lcrh); +#endif + + /* Set the UART to interrupt whenever the TX FIFO is almost empty or when + * any character is received. + */ + + up_serialout(priv, TIVA_UART_IFLS_OFFSET, + UART_IFLS_TXIFLSEL_18th | UART_IFLS_RXIFLSEL_18th); + + /* Flush the Rx and Tx FIFOs -- How do you do that? */ + + /* Enable Rx interrupts from the UART except for Tx interrupts. We don't want + * Tx interrupts until we have something to send. We will check for serial + * errors as part of Rx interrupt processing (no interrupts will be received + * yet because the interrupt is still disabled at the interrupt controller. + */ + + up_serialout(priv, TIVA_UART_IM_OFFSET, UART_IM_RXIM | UART_IM_RTIM); + + /* Enable the FIFOs */ + +#ifdef CONFIG_SUPPRESS_UART_CONFIG + lcrh = up_serialin(priv, TIVA_UART_LCRH_OFFSET); +#endif + lcrh |= UART_LCRH_FEN; + up_serialout(priv, TIVA_UART_LCRH_OFFSET, lcrh); + + /* Enable Rx, Tx, and the UART */ + +#ifdef CONFIG_SUPPRESS_UART_CONFIG + ctl = up_serialin(priv, TIVA_UART_CTL_OFFSET); +#endif + ctl |= (UART_CTL_UARTEN | UART_CTL_TXE | UART_CTL_RXE); + up_serialout(priv, TIVA_UART_CTL_OFFSET, ctl); + + /* Set up the cache IM value */ + + priv->im = up_serialin(priv, TIVA_UART_IM_OFFSET); + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t mis; + int passes; + bool handled; + +#ifdef CONFIG_TIVA_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_TIVA_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_TIVA_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif +#ifdef CONFIG_TIVA_UART3 + if (g_uart3priv.irq == irq) + { + dev = &g_uart3port; + } + else +#endif +#ifdef CONFIG_TIVA_UART4 + if (g_uart4priv.irq == irq) + { + dev = &g_uart4port; + } + else +#endif +#ifdef CONFIG_TIVA_UART5 + if (g_uart5priv.irq == irq) + { + dev = &g_uart5port; + } + else +#endif +#ifdef CONFIG_TIVA_UART6 + if (g_uart6priv.irq == irq) + { + dev = &g_uart6port; + } + else +#endif +#ifdef CONFIG_TIVA_UART7 + if (g_uart7priv.irq == irq) + { + dev = &g_uart7port; + } + else +#endif + { + PANIC(); + } + + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked UART status and clear the pending interrupts. */ + + mis = up_serialin(priv, TIVA_UART_MIS_OFFSET); + up_serialout(priv, TIVA_UART_ICR_OFFSET, mis); + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) != 0) + { + /* Rx buffer not empty ... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + if ((mis & UART_MIS_TXMIS) != 0) + { + /* Tx FIFO not full ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rxd; + + /* Get the Rx byte + 4 bits of error information. Return those in status */ + + rxd = up_serialin(priv, TIVA_UART_DR_OFFSET); + *status = rxd; + + /* The lower 8bits of the Rx data is the actual recevied byte */ + + return rxd & 0xff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx FIFO (or an Rx + * timeout occurs. + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= (UART_IM_RXIM | UART_IM_RTIM); +#endif + } + else + { + priv->im &= ~(UART_IM_RXIM | UART_IM_RTIM); + } + up_serialout(priv, TIVA_UART_IM_OFFSET, priv->im); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, TIVA_UART_FR_OFFSET) & UART_FR_RXFE) == 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, TIVA_UART_DR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX fifo is half emptied */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_IM_TXIM; + up_serialout(priv, TIVA_UART_IM_OFFSET, priv->im); + + /* The serial driver wants an interrupt here, but will not get get + * one unless we "prime the pump." I believe that this is because + * behave like a level interrupt and the Stellaris interrupts behave + * (at least by default) like edge interrupts. + * + * In any event, faking a TX interrupt here solves the problem; + * Call uart_xmitchars() just as would have been done if we recieved + * the TX interrupt. + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->im &= ~UART_IM_TXIM; + up_serialout(priv, TIVA_UART_IM_OFFSET, priv->im); + } + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, TIVA_UART_FR_OFFSET) & UART_FR_TXFF) == 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, TIVA_UART_FR_OFFSET) & UART_FR_TXFE) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* NOTE: All GPIO configuration for the UARTs was performed in + * up_lowsetup + */ + + /* Disable all UARTS */ + + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + up_disableuartint(TTYS2_DEV.priv, NULL); +#endif +#ifdef TTYS3_DEV + up_disableuartint(TTYS3_DEV.priv, NULL); +#endif +#ifdef TTYS4_DEV + up_disableuartint(TTYS4_DEV.priv, NULL); +#endif +#ifdef TTYS5_DEV + up_disableuartint(TTYS5_DEV.priv, NULL); +#endif +#ifdef TTYS6_DEV + up_disableuartint(TTYS6_DEV.priv, NULL); +#endif +#ifdef TTYS7_DEV + up_disableuartint(TTYS7_DEV.priv, NULL); +#endif + + /* Configure whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +#ifdef TTYS6_DEV + (void)uart_register("/dev/ttyS6", &TTYS6_DEV); +#endif +#ifdef TTYS7_DEV + (void)uart_register("/dev/ttyS7", &TTYS7_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t im; + + up_disableuartint(priv, &im); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxnotfull(priv); + up_serialout(priv, TIVA_UART_DR_OFFSET, (uint32_t)'\r'); + } + + up_waittxnotfull(priv); + up_serialout(priv, TIVA_UART_DR_OFFSET, (uint32_t)ch); + + up_waittxnotfull(priv); + up_restoreuartint(priv, im); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/tiva/tiva_ssi.c b/arch/arm/src/tiva/tiva_ssi.c new file mode 100644 index 0000000000000000000000000000000000000000..6870b9eb374b2a9ad3efd91c10817763e83c1fa0 --- /dev/null +++ b/arch/arm/src/tiva/tiva_ssi.c @@ -0,0 +1,1708 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_ssi.c + * + * Copyright (C) 2009-2010, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" +#include "tiva_gpio.h" +#include "tiva_ssi.h" +#include "chip/tiva_pinmap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Enables debug output from this file (needs CONFIG_DEBUG with + * CONFIG_DEBUG_VERBOSE too) + */ + +#undef SSI_DEBUG /* Define to enable debug */ + +#ifdef SSI_DEBUG +# define ssidbg lldbg +# define ssivdbg llvdbg +#else +# define ssidbg(x...) +# define ssivdbg(x...) +#endif + +/* How many SSI modules does this chip support? The LM3S6918 supports 2 SSI + * modules, the LM3S6965 and LM3S8962 support 1 module (others may support more than 2-- in + * such case, the following must be expanded). + */ + +#if TIVA_NSSI < 1 +# undef CONFIG_TIVA_SSI0 +# undef CONFIG_TIVA_SSI1 +# undef CONFIG_TIVA_SSI2 +# undef CONFIG_TIVA_SSI3 +#elif TIVA_NSSI < 2 +# undef CONFIG_TIVA_SSI1 +# undef CONFIG_TIVA_SSI2 +# undef CONFIG_TIVA_SSI3 +#elif TIVA_NSSI < 3 +# undef CONFIG_TIVA_SSI2 +# undef CONFIG_TIVA_SSI3 +#elif TIVA_NSSI < 4 +# undef CONFIG_TIVA_SSI3 +#endif + +/* Which SSI modules have been enabled? */ + +#ifdef CONFIG_TIVA_SSI0 +# define SSI0_NDX 0 /* Index to SSI0 in g_ssidev[] */ +# define __SSI1_NDX 1 /* Next available index */ +#else +# define __SSI1_NDX 0 /* Next available index */ +#endif + +#ifdef CONFIG_TIVA_SSI1 +# define SSI1_NDX __SSI1_NDX /* Index to SSI1 in g_ssidev[] */ +# define __SSI2_NDX (__SSI1_NDX + 1) /* Next available index */ +#else +# define __SSI2_NDX __SSI1_NDX /* Next available index */ +#endif + +#ifdef CONFIG_TIVA_SSI2 +# define SSI2_NDX __SSI2_NDX /* Index to SSI2 in g_ssidev[] */ +# define __SSI3_NDX (__SSI2_NDX + 1) /* Next available index */ +#else +# define __SSI3_NDX __SSI2_NDX /* Next available index */ +#endif + +#ifdef CONFIG_TIVA_SSI3 +# define SSI3_NDX __SSI3_NDX /* Index to SSI3 in g_ssidev[] */ +# define NSSI_ENABLED (__SSI3_NDX + 1) /* Number of SSI peripheral senabled */ +#else +# define NSSI_ENABLED __SSI3_NDX /* Number of SSI peripheral senabled */ +#endif + +/* Compile the rest of the file only if at least one SSI interface has been + * enabled. + */ + +#if NSSI_ENABLED > 0 + +/* Some special definitions if there is exactly one interface enabled */ + +#if NSSI_ENABLED < 2 +# if defined(CONFIG_TIVA_SSI0) +# define SSI_BASE TIVA_SSI0_BASE +# define SSI_IRQ TIVA_IRQ_SSI0 +# elif defined(CONFIG_TIVA_SSI1) +# define SSI_BASE TIVA_SSI1_BASE +# define SSI_IRQ TIVA_IRQ_SSI1 +# elif defined(CONFIG_TIVA_SSI2) +# define SSI_BASE TIVA_SSI2_BASE +# define SSI_IRQ TIVA_IRQ_SSI2 +# elif defined(CONFIG_TIVA_SSI3) +# define SSI_BASE TIVA_SSI3_BASE +# define SSI_IRQ TIVA_IRQ_SSI3 +# else +# error Help me... I am confused +# endif +#endif + +/* The number of (16-bit) words that will fit in the Tx FIFO */ + +#define TIVA_TXFIFO_WORDS 8 + +/* Configuration settings */ + +#ifndef CONFIG_SSI_TXLIMIT +# define CONFIG_SSI_TXLIMIT (TIVA_TXFIFO_WORDS/2) +#endif + +#if CONFIG_SSI_TXLIMIT < 1 || CONFIG_SSI_TXLIMIT > TIVA_TXFIFO_WORDS +# error "Invalid range for CONFIG_SSI_TXLIMIT" +#endif + +#if CONFIG_SSI_TXLIMIT && CONFIG_SSI_TXLIMIT < (TIVA_TXFIFO_WORDS/2) +# error "CONFIG_SSI_TXLIMIT must be at least half the TX FIFO size" +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct tiva_ssidev_s +{ + const struct spi_ops_s *ops; /* Common SPI operations */ +#ifndef CONFIG_SSI_POLLWAIT + sem_t xfrsem; /* Wait for transfer to complete */ +#endif + + /* These following are the source and destination buffers of the transfer. + * they are retained in this structure so that they will be accessible + * from an interrupt handler. The actual type of the buffer is uint8_t if + * nbits <=8 and uint16_t if nbits >8. + */ + + void *txbuffer; /* Source buffer */ + void *rxbuffer; /* Destination buffer */ + + /* These are functions pointers that are configured to perform the + * appropriate transfer for the particular kind of exchange that is + * occurring. Differnt functions may be selected depending on (1) + * if the tx or txbuffer is NULL and depending on the number of bits + * per word. + */ + + void (*txword)(struct tiva_ssidev_s *priv); + void (*rxword)(struct tiva_ssidev_s *priv); + +#if NSSI_ENABLED > 1 + uint32_t base; /* SSI register base address */ +#endif + + int ntxwords; /* Number of words left to transfer on the Tx FIFO */ + int nrxwords; /* Number of words received on the Rx FIFO */ + int nwords; /* Number of words to be exchanged */ + uint8_t nbits; /* Current number of bits per word */ + +#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 + uint8_t irq; /* SSI IRQ number */ +#endif + + /* Enforce mutual exclusion and remember some configuration settings to + * reduce the overhead of constant SPI re-configuration. + */ + + sem_t exclsem; /* For exclusive access to the SSI bus */ + uint32_t frequency; /* Current desired SCLK frequency */ + uint32_t actual; /* Current actual SCLK frequency */ + uint8_t mode; /* Current mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SSI register access */ + +static inline uint32_t ssi_getreg(struct tiva_ssidev_s *priv, + unsigned int offset); +static inline void ssi_putreg(struct tiva_ssidev_s *priv, unsigned int offset, + uint32_t value); + +/* Misc helpers */ + +static uint32_t ssi_disable(struct tiva_ssidev_s *priv); +static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable); + +#ifndef CONFIG_SSI_POLLWAIT +static void ssi_semtake(sem_t *sem); +#define ssi_semgive(s) sem_post(s); +#endif + +/* SSI data transfer */ + +static void ssi_txnull(struct tiva_ssidev_s *priv); +static void ssi_txuint16(struct tiva_ssidev_s *priv); +static void ssi_txuint8(struct tiva_ssidev_s *priv); +static void ssi_rxnull(struct tiva_ssidev_s *priv); +static void ssi_rxuint16(struct tiva_ssidev_s *priv); +static void ssi_rxuint8(struct tiva_ssidev_s *priv); +static inline bool ssi_txfifofull(struct tiva_ssidev_s *priv); +static inline bool ssi_rxfifoempty(struct tiva_ssidev_s *priv); +#if CONFIG_SSI_TXLIMIT == 1 && defined(CONFIG_SSI_POLLWAIT) +static inline int ssi_performtx(struct tiva_ssidev_s *priv); +#else +static int ssi_performtx(struct tiva_ssidev_s *priv); +#endif +static inline void ssi_performrx(struct tiva_ssidev_s *priv); +static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer, + void *rxbuffer, unsigned int nwords); + +/* Interrupt handling */ + +#ifndef CONFIG_SSI_POLLWAIT +static inline struct tiva_ssidev_s *ssi_mapirq(int irq); +static int ssi_interrupt(int irq, void *context); +#endif + +/* SPI methods */ + +static int ssi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t ssi_setfrequencyinternal(struct tiva_ssidev_s *priv, + uint32_t frequency); +static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void ssi_setmodeinternal(struct tiva_ssidev_s *priv, + enum spi_mode_e mode); +static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void ssi_setbitsinternal(struct tiva_ssidev_s *priv, int nbits); +static void ssi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t ssi_send(FAR struct spi_dev_s *dev, uint16_t wd); +#ifdef CONFIG_SPI_EXCHANGE +static void ssi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#else +static void ssi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords); +static void ssi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Common SSI operations */ + +static const struct spi_ops_s g_spiops = +{ + .lock = ssi_lock, + .select = tiva_ssiselect, /* Provided externally by board logic */ + .setfrequency = ssi_setfrequency, + .setmode = ssi_setmode, + .setbits = ssi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = tiva_ssistatus, /* Provided externally by board logic */ +#ifdef CONFIG_SPI_CMDDATA + .cmddata = tiva_ssicmddata, +#endif + .send = ssi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = ssi_exchange, +#else + .sndblock = ssi_sndblock, + .recvblock = ssi_recvblock, +#endif +}; + +/* This supports is up to two SSI busses/ports */ + +static struct tiva_ssidev_s g_ssidev[] = +{ +#ifdef CONFIG_TIVA_SSI0 + { + .ops = &g_spiops, +#if NSSI_ENABLED > 1 + .base = TIVA_SSI0_BASE, +#endif +#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 + .irq = TIVA_IRQ_SSI0, +#endif + }, +#endif +#ifdef CONFIG_TIVA_SSI1 + { + .ops = &g_spiops, +#if NSSI_ENABLED > 1 + .base = TIVA_SSI1_BASE, +#endif +#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 + .irq = TIVA_IRQ_SSI1, +#endif + }, +#endif +#ifdef CONFIG_TIVA_SSI2 + { + .ops = &g_spiops, +#if NSSI_ENABLED > 1 + .base = TIVA_SSI2_BASE, +#endif +#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 + .irq = TIVA_IRQ_SSI2, +#endif + }, +#endif +#ifdef CONFIG_TIVA_SSI3 + { + .ops = &g_spiops, +#if NSSI_ENABLED > 1 + .base = TIVA_SSI3_BASE, +#endif +#if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 + .irq = TIVA_IRQ_SSI3, +#endif + }, +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssi_getreg + * + * Description: + * Read the SSI register at this offeset + * + * Input Parameters: + * priv - Device-specific state data + * offset - Offset to the SSI register from the register base address + * + * Returned Value: + * Value of the register at this offset + * + ****************************************************************************/ + +static inline uint32_t ssi_getreg(struct tiva_ssidev_s *priv, + unsigned int offset) +{ +#if NSSI_ENABLED > 1 + return getreg32(priv->base + offset); +#else + return getreg32(SSI_BASE + offset); +#endif +} + +/**************************************************************************** + * Name: ssi_putreg + * + * Description: + * Write the value to the SSI register at this offeset + * + * Input Parameters: + * priv - Device-specific state data + * offset - Offset to the SSI register from the register base address + * value - Value to write + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void ssi_putreg(struct tiva_ssidev_s *priv, + unsigned int offset, uint32_t value) +{ +#if NSSI_ENABLED > 1 + putreg32(value, priv->base + offset); +#else + putreg32(value, SSI_BASE + offset); +#endif +} + +/**************************************************************************** + * Name: ssi_disable + * + * Description: + * Disable SSI operation. NOTE: The SSI must be disabled before any control + * registers can be re-programmed. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * State of the SSI before the SSE was disabled + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static uint32_t ssi_disable(struct tiva_ssidev_s *priv) +{ + uint32_t retval; + uint32_t regval; + + retval = ssi_getreg(priv, TIVA_SSI_CR1_OFFSET); + regval = (retval & ~SSI_CR1_SSE); + ssi_putreg(priv, TIVA_SSI_CR1_OFFSET, regval); + ssivdbg("CR1: %08x\n", regval); + return retval; +} + +/**************************************************************************** + * Name: ssi_enable + * + * Description: + * Restore the SSI operational state + * + * Input Parameters: + * priv - Device-specific state data + * enable - The previous operational state + * + * Returned Value: + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static void ssi_enable(struct tiva_ssidev_s *priv, uint32_t enable) +{ + uint32_t regval = ssi_getreg(priv, TIVA_SSI_CR1_OFFSET); + regval &= ~SSI_CR1_SSE; + regval |= (enable & SSI_CR1_SSE); + ssi_putreg(priv, TIVA_SSI_CR1_OFFSET, regval); + ssivdbg("CR1: %08x\n", regval); +} + +/**************************************************************************** + * Name: ssi_semtake + * + * Description: + * Wait for a semaphore (handling interruption by signals); + * + * Input Parameters: + * priv - Device-specific state data + * enable - The previous operational state + * + * Returned Value: + * + ****************************************************************************/ + +#ifndef CONFIG_SSI_POLLWAIT +static void ssi_semtake(sem_t *sem) +{ + int ret; + do + { + ret = sem_wait(sem); + } + while (ret < 0 && errno == EINTR); + DEBUGASSERT(ret == 0); +} +#endif + +/**************************************************************************** + * Name: ssi_txnull, ssi_txuint16, and ssi_txuint8 + * + * Description: + * Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the txbuffer + * pointer appropriately. The selected function dependes on (1) if there + * is a source txbuffer provided, and (2) if the number of bits per + * word is <=8 or >8. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssi_txnull(struct tiva_ssidev_s *priv) +{ + ssivdbg("TX: ->0xffff\n"); + ssi_putreg(priv, TIVA_SSI_DR_OFFSET, 0xffff); +} + +static void ssi_txuint16(struct tiva_ssidev_s *priv) +{ + uint16_t *ptr = (uint16_t *)priv->txbuffer; + ssivdbg("TX: %p->%04x\n", ptr, *ptr); + ssi_putreg(priv, TIVA_SSI_DR_OFFSET, (uint32_t)(*ptr++)); + priv->txbuffer = (void *)ptr; +} + +static void ssi_txuint8(struct tiva_ssidev_s *priv) +{ + uint8_t *ptr = (uint8_t *)priv->txbuffer; + ssivdbg("TX: %p->%02x\n", ptr, *ptr); + ssi_putreg(priv, TIVA_SSI_DR_OFFSET, (uint32_t)(*ptr++)); + priv->txbuffer = (void *)ptr; +} + +/**************************************************************************** + * Name: ssi_rxnull, ssi_rxuint16, and ssi_rxuint8 + * + * Description: + * Discard input, save a uint8_t, or or save a uint16_t from Tx FIFO in the + * user rxvbuffer and update the rxbuffer pointer appropriately. The + * selected function dependes on (1) if there is a desination rxbuffer + * provided, and (2) if the number of bits per word is <=8 or >8. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ssi_rxnull(struct tiva_ssidev_s *priv) +{ +#if defined(SSI_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) + uint32_t regval = ssi_getreg(priv, TIVA_SSI_DR_OFFSET); + ssivdbg("RX: discard %04x\n", regval); +#else + (void)ssi_getreg(priv, TIVA_SSI_DR_OFFSET); +#endif +} + +static void ssi_rxuint16(struct tiva_ssidev_s *priv) +{ + uint16_t *ptr = (uint16_t *)priv->rxbuffer; + *ptr = (uint16_t)ssi_getreg(priv, TIVA_SSI_DR_OFFSET); + ssivdbg("RX: %p<-%04x\n", ptr, *ptr); + priv->rxbuffer = (void *)(++ptr); +} + +static void ssi_rxuint8(struct tiva_ssidev_s *priv) +{ + uint8_t *ptr = (uint8_t *)priv->rxbuffer; + *ptr = (uint8_t)ssi_getreg(priv, TIVA_SSI_DR_OFFSET); + ssivdbg("RX: %p<-%02x\n", ptr, *ptr); + priv->rxbuffer = (void *)(++ptr); +} + +/**************************************************************************** + * Name: ssi_txfifofull + * + * Description: + * Return true if the Tx FIFO is full + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: Not full + * + ****************************************************************************/ + +static inline bool ssi_txfifofull(struct tiva_ssidev_s *priv) +{ + return (ssi_getreg(priv, TIVA_SSI_SR_OFFSET) & SSI_SR_TNF) == 0; +} + +/**************************************************************************** + * Name: ssi_rxfifoempty + * + * Description: + * Return true if the Rx FIFO is empty + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: Not empty + * + ****************************************************************************/ + +static inline bool ssi_rxfifoempty(struct tiva_ssidev_s *priv) +{ + return (ssi_getreg(priv, TIVA_SSI_SR_OFFSET) & SSI_SR_RNE) == 0; +} + +/**************************************************************************** + * Name: ssi_performtx + * + * Description: + * If the Tx FIFO is empty, then transfer as many words as we can to + * the FIFO. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * The number of words written to the Tx FIFO (a value from 0 to 8, + * inclusive). + * + ****************************************************************************/ + +#if CONFIG_SSI_TXLIMIT == 1 && defined(CONFIG_SSI_POLLWAIT) +static inline int ssi_performtx(struct tiva_ssidev_s *priv) +{ + /* Check if the Tx FIFO is full and more data to transfer */ + + if (!ssi_txfifofull(priv) && priv->ntxwords > 0) + { + /* Transfer one word to the Tx FIFO */ + + priv->txword(priv); + priv->ntxwords--; + return 1; + } + return 0; +} + +#else /* CONFIG_SSI_TXLIMIT == 1 CONFIG_SSI_POLLWAIT */ + +static int ssi_performtx(struct tiva_ssidev_s *priv) +{ +#ifndef CONFIG_SSI_POLLWAIT + uint32_t regval; +#endif + int ntxd = 0; /* Number of words written to Tx FIFO */ + + /* Check if the Tx FIFO is full */ + + if (!ssi_txfifofull(priv)) + { + /* Not full.. Check if all of the Tx words have been sent */ + + if (priv->ntxwords > 0) + { + /* No.. Transfer more words until either the Tx FIFO is full or + * until all of the user provided data has been sent. + */ +#ifdef CONFIG_SSI_TXLIMIT + /* Further limit the number of words that we put into the Tx + * FIFO to CONFIG_SSI_TXLIMIT. Otherwise, we could + * overrun the Rx FIFO on a very fast SSI bus. + */ + for (; ntxd < priv->ntxwords && ntxd < CONFIG_SSI_TXLIMIT && !ssi_txfifofull(priv); ntxd++) +#else + for (; ntxd < priv->ntxwords && !ssi_txfifofull(priv); ntxd++) +#endif + { + priv->txword(priv); + } + + /* Update the count of words to to transferred */ + + priv->ntxwords -= ntxd; + } + + /* Check again... Now have all of the Tx words been sent? */ + +#ifndef CONFIG_SSI_POLLWAIT + regval = ssi_getreg(priv, TIVA_SSI_IM_OFFSET); + if (priv->ntxwords > 0) + { + /* No.. Enable the Tx FIFO interrupt. This interrupt occurs + * when the Tx FIFO is 1/2 full or less. + */ + +#ifdef CONFIG_DEBUG + regval |= (SSI_IM_TX | SSI_RIS_ROR); +#else + regval |= SSI_IM_TX; +#endif + } + else + { + /* Yes.. Disable the Tx FIFO interrupt. The final stages of + * the transfer will be driven by Rx FIFO interrupts. + */ + + regval &= ~(SSI_IM_TX | SSI_RIS_ROR); + } + ssi_putreg(priv, TIVA_SSI_IM_OFFSET, regval); +#endif /* CONFIG_SSI_POLLWAIT */ + } + return ntxd; +} + +#endif /* CONFIG_SSI_TXLIMIT == 1 CONFIG_SSI_POLLWAIT */ + +/**************************************************************************** + * Name: ssi_performrx + * + * Description: + * Transfer as many bytes as possible from the Rx FIFO to the user Rx + * buffer (if one was provided). + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void ssi_performrx(struct tiva_ssidev_s *priv) +{ +#ifndef CONFIG_SSI_POLLWAIT + uint32_t regval; +#endif + + /* Loop while data is available in the Rx FIFO */ + + while (!ssi_rxfifoempty(priv)) + { + /* Have all of the requested words been transferred from the Rx FIFO? */ + + if (priv->nrxwords < priv->nwords) + { + /* No.. Read more data from Rx FIFO */ + + priv->rxword(priv); + priv->nrxwords++; + } + } + + /* The Rx FIFO is now empty. While there is Tx data to be sent, the + * transfer will be driven by Tx FIFO interrupts. The final part + * of the transfer is driven by Rx FIFO interrupts only. + */ + +#ifndef CONFIG_SSI_POLLWAIT + regval = ssi_getreg(priv, TIVA_SSI_IM_OFFSET); + if (priv->ntxwords == 0 && priv->nrxwords < priv->nwords) + { + /* There are no more outgoing words to send, but there are + * additional incoming words expected (I would think that this + * a real corner case, be we will handle it with an extra + * interrupt, probably an Rx timeout). + */ + +#ifdef CONFIG_DEBUG + regval |= (SSI_IM_RX | SSI_IM_RT | SSI_IM_ROR); +#else + regval |= (SSI_IM_RX | SSI_IM_RT); +#endif + } + else + { + /* No.. there are either more Tx words to send or all Rx words + * have received. Disable Rx FIFO interrupts. + */ + + regval &= ~(SSI_IM_RX | SSI_IM_RT); + } + ssi_putreg(priv, TIVA_SSI_IM_OFFSET, regval); +#endif /* CONFIG_SSI_POLLWAIT */ +} + +/**************************************************************************** + * Name: ssi_transfer + * + * Description: + * Exchange a block data with the SPI device + * + * Input Parameters: + * priv - Device-specific state data + * txbuffer - The buffer of data to send to the device (may be NULL). + * rxbuffer - The buffer to receive data from the device (may be NULL). + * nwords - The total number of words to be exchanged. If the interface + * uses <= 8 bits per word, then this is the number of uint8_t's; + * if the interface uses >8 bits per word, then this is the + * number of uint16_t's + * + * Returned Value: + * 0: success, <0:Negated error number on failure + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static int ssi_transfer(struct tiva_ssidev_s *priv, const void *txbuffer, + void *rxbuffer, unsigned int nwords) +{ +#ifndef CONFIG_SSI_POLLWAIT + irqstate_t flags; +#endif + int ntxd; + + ssidbg("txbuffer: %p rxbuffer: %p nwords: %d\n", txbuffer, rxbuffer, nwords); + + /* Set up to perform the transfer */ + + priv->txbuffer = (uint8_t *)txbuffer; /* Source buffer */ + priv->rxbuffer = (uint8_t *)rxbuffer; /* Destination buffer */ + priv->ntxwords = nwords; /* Number of words left to send */ + priv->nrxwords = 0; /* Number of words received */ + priv->nwords = nwords; /* Total number of exchanges */ + + /* Set up the low-level data transfer function pointers */ + + if (priv->nbits > 8) + { + priv->txword = ssi_txuint16; + priv->rxword = ssi_rxuint16; + } + else + { + priv->txword = ssi_txuint8; + priv->rxword = ssi_rxuint8; + } + + if (!txbuffer) + { + priv->txword = ssi_txnull; + } + + if (!rxbuffer) + { + priv->rxword = ssi_rxnull; + } + + /* Prime the Tx FIFO to start the sequence (saves one interrupt). + * At this point, all SSI interrupts should be disabled, but the + * operation of ssi_performtx() will set up the interrupts + * approapriately (if nwords > TxFIFO size). + */ + +#ifndef CONFIG_SSI_POLLWAIT + flags = enter_critical_section(); + ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n", + priv->ntxwords, priv->nrxwords, priv->nwords, + ssi_getreg(priv, TIVA_SSI_SR_OFFSET)); + + ntxd = ssi_performtx(priv); + UNUSED(ntxd); + + /* For the case where nwords < Tx FIFO size, ssi_performrx will + * configure interrupts correctly for the final phase of the + * the transfer. + */ + + ssi_performrx(priv); + + ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n", + priv->ntxwords, priv->nrxwords, priv->nwords, + ssi_getreg(priv, TIVA_SSI_SR_OFFSET), + ssi_getreg(priv, TIVA_SSI_IM_OFFSET)); + + /* Wait for the transfer to complete. Since there is no handshake + * with SPI, the following should complete even if there are problems + * with the transfer, so it should be safe with no timeout. + */ + + ssivdbg("Waiting for transfer complete\n"); + leave_critical_section(flags); + do + { + ssi_semtake(&priv->xfrsem); + } + while (priv->nrxwords < priv->nwords); + ssidbg("Transfer complete\n"); + +#else + /* Perform the transfer using polling logic. This will totally + * dominate the CPU until the transfer is complete. Only recommended + * if (1) your SPI is very fast, and (2) if you only use very short + * transfers. + */ + + do + { + /* Handle outgoing Tx FIFO transfers */ + + ntxd = ssi_performtx(priv); + UNUSED(ntxd); + + /* Handle incoming Rx FIFO transfers */ + + ssi_performrx(priv); + + /* If there are other threads at this same priority level, + * the following may help: + */ + + sched_yield(); + } + while (priv->nrxwords < priv->nwords); +#endif + + return OK; +} + +/**************************************************************************** + * Name: ssi_mapirq + * + * Description: + * Map an IRQ number into the appropriate SSI device + * + * Input Parameters: + * irq - The IRQ number to be mapped + * + * Returned Value: + * On success, a reference to the private data structgure for this IRQ. + * NULL on failure. + * + ****************************************************************************/ + +#ifndef CONFIG_SSI_POLLWAIT +static inline struct tiva_ssidev_s *ssi_mapirq(int irq) +{ + switch (irq) + { +#ifdef CONFIG_TIVA_SSI0 + case TIVA_IRQ_SSI0: + return &g_ssidev[SSI0_NDX]; +#endif +#ifdef CONFIG_TIVA_SSI1 + case TIVA_IRQ_SSI1: + return &g_ssidev[SSI1_NDX]; +#endif +#ifdef CONFIG_TIVA_SSI2 + case TIVA_IRQ_SSI2: + return &g_ssidev[SSI2_NDX]; +#endif +#ifdef CONFIG_TIVA_SSI3 + case TIVA_IRQ_SSI3: + return &g_ssidev[SSI3_NDX]; +#endif + default: + return NULL; + } +} +#endif + +/**************************************************************************** + * Name: ssi_interrupt + * + * Description: + * Exchange a block data with the SSI device + * + * Input Parameters: + * priv - Device-specific state data + * txbuffer - The buffer of data to send to the device (may be NULL). + * rxbuffer - The buffer to receive data from the device (may be NULL). + * nwords - The total number of words to be exchanged. If the interface + * uses <= 8 bits per word, then this is the number of uint8_t's; + * if the interface uses >8 bits per word, then this is the + * number of uint16_t's + * + * Returned Value: + * 0: success, <0:Negated error number on failure + * + ****************************************************************************/ + +#ifndef CONFIG_SSI_POLLWAIT +static int ssi_interrupt(int irq, void *context) +{ + struct tiva_ssidev_s *priv = ssi_mapirq(irq); + uint32_t regval; + + DEBUGASSERT(priv != NULL); + + /* Clear pending interrupts */ + + regval = ssi_getreg(priv, TIVA_SSI_RIS_OFFSET); + ssi_putreg(priv, TIVA_SSI_ICR_OFFSET, regval); + + /* Check for Rx FIFO overruns */ + +#ifdef SSI_DEBUG + if ((regval & SSI_RIS_ROR) != 0) + { + ssidbg("Rx FIFO Overrun!\n"); + } +#endif + + ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n", + priv->ntxwords, priv->nrxwords, priv->nwords, + ssi_getreg(priv, TIVA_SSI_SR_OFFSET)); + + /* Handle outgoing Tx FIFO transfers */ + + (void)ssi_performtx(priv); + + /* Handle incoming Rx FIFO transfers */ + + ssi_performrx(priv); + + ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n", + priv->ntxwords, priv->nrxwords, priv->nwords, + ssi_getreg(priv, TIVA_SSI_SR_OFFSET), + ssi_getreg(priv, TIVA_SSI_IM_OFFSET)); + + /* Check if the transfer is complete */ + + if (priv->nrxwords >= priv->nwords) + { + /* Yes.. Disable all SSI interrupt sources */ + + ssi_putreg(priv, TIVA_SSI_IM_OFFSET, 0); + + /* Wake up the waiting thread */ + + ssidbg("Transfer complete\n"); + ssi_semgive(&priv->xfrsem); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: ssi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ssi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct tiva_ssidev_s *priv = (FAR struct tiva_ssidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: ssi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static uint32_t ssi_setfrequencyinternal(struct tiva_ssidev_s *priv, + uint32_t frequency) +{ + uint32_t maxdvsr; + uint32_t cpsdvsr; + uint32_t regval; + uint32_t scr; + uint32_t actual; + + ssidbg("frequency: %d\n", frequency); + DEBUGASSERT(frequency); + + /* Has the frequency changed? */ + + if (frequency != priv->frequency) + { + /* "The serial bit rate is derived by dividing down the input clock + * (FSysClk). The clock is first divided by an even prescale value + * CPSDVSR from 2 to 254, which is programmed in the SSI Clock Prescale + * (SSI_CPSR) register ... The clock is further divided by a value + * from 1 to 256, which is 1 + SCR, where SCR is the value programmed + * i n the SSI Control0 (SSICR0) register ... + * + * "The frequency of the output clock SSIClk is defined by: + * + * "SSIClk = FSysClk / (CPSDVSR * (1 + SCR)) + * + * "Note: Although the SSIClk transmit clock can theoretically be 25 MHz, + * the module may not be able to operate at that speed. For master mode, + * the system clock must be at least two times faster than the SSIClk. + * For slave mode, the system clock must be at least 12 times faster + * than the SSIClk." + */ + + if (frequency > SYSCLK_FREQUENCY/2) + { + frequency = SYSCLK_FREQUENCY/2; + } + + /* Find optimal values for CPSDVSR and SCR. This loop is inefficient, + * but should not have to execute many times. + * + * EXAMPLE 1: SYSCLK_FREQUENCY=50,000,0000 and frequency=400,000. + * + * maxcvsr = 125 + * 1. cpsdvsr = 2, scr = 61 -> DONE + * + * This would correspond to an actual frequency of: + * 50,000,000 / (2 * (62)) = 403,226 + * + * EXAMPLE 2: SYSCLK_FREQUENCY=50,000,0000 and frequency=25,000,000. + * + * maxcvsr = 2 + * 1. cpsdvsr = 2, scr = 0 -> DONE + * + * This would correspond to an actual frequency of: + * 50,000,000 / (2 * (1)) = 25,000,000 + */ + + maxdvsr = SYSCLK_FREQUENCY / frequency; + cpsdvsr = 0; + do + { + cpsdvsr += 2; + scr = (maxdvsr / cpsdvsr) - 1; + } + while (scr > 255); + + /* Set CPDVSR */ + + DEBUGASSERT(cpsdvsr < 255); + ssi_putreg(priv, TIVA_SSI_CPSR_OFFSET, cpsdvsr); + + /* Set SCR */ + + regval = ssi_getreg(priv, TIVA_SSI_CR0_OFFSET); + regval &= ~SSI_CR0_SCR_MASK; + regval |= (scr << SSI_CR0_SCR_SHIFT); + ssi_putreg(priv, TIVA_SSI_CR0_OFFSET, regval); + ssivdbg("CR0: %08x CPSR: %08x\n", regval, cpsdvsr); + + /* Calcluate the actual frequency */ + + actual = SYSCLK_FREQUENCY / (cpsdvsr * (scr + 1)); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + + priv->frequency = frequency; + priv->actual = actual; + } + + return priv->actual; +} + +static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + uint32_t enable; + uint32_t actual; + + /* NOTE that the SSI must be disabled when setting any configuration registers. */ + + enable = ssi_disable(priv); + actual = ssi_setfrequencyinternal(priv, frequency); + ssi_enable(priv, enable); + return actual; +} + +/**************************************************************************** + * Name: ssi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static void ssi_setmodeinternal(struct tiva_ssidev_s *priv, enum spi_mode_e mode) +{ + uint32_t modebits; + uint32_t regval; + + ssidbg("mode: %d\n", mode); + DEBUGASSERT(priv); + + /* Has the number of bits per word changed? */ + + if (mode != priv->mode) + { + /* Select the CTL register bits based on the selected mode */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */ + modebits = 0; + break; + + case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */ + modebits = SSI_CR0_SPH; + break; + + case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */ + modebits = SSI_CR0_SPO; + break; + + case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */ + modebits = SSI_CR0_SPH | SSI_CR0_SPO; + break; + + default: + return; + } + + /* Then set the selected mode: Freescale SPI format, mode0-3 */ + + regval = ssi_getreg(priv, TIVA_SSI_CR0_OFFSET); + regval &= ~(SSI_CR0_FRF_MASK | SSI_CR0_SPH | SSI_CR0_SPO); + regval |= modebits; + ssi_putreg(priv, TIVA_SSI_CR0_OFFSET, regval); + ssivdbg("CR0: %08x\n", regval); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + uint32_t enable; + + /* NOTE that the SSI must be disabled when setting any configuration registers. */ + + enable = ssi_disable(priv); + ssi_setmodeinternal(priv, mode); + ssi_enable(priv, enable); +} + +/**************************************************************************** + * Name: ssi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + * Assumption: + * Caller holds a lock on the SPI bus + * + ****************************************************************************/ + +static void ssi_setbitsinternal(struct tiva_ssidev_s *priv, int nbits) +{ + uint32_t regval; + + ssidbg("nbits: %d\n", nbits); + DEBUGASSERT(priv); + if (nbits != priv->nbits && nbits >= 4 && nbits <= 16) + { + regval = ssi_getreg(priv, TIVA_SSI_CR0_OFFSET); + regval &= ~SSI_CR0_DSS_MASK; + regval |= ((nbits - 1) << SSI_CR0_DSS_SHIFT); + ssi_putreg(priv, TIVA_SSI_CR0_OFFSET, regval); + ssivdbg("CR0: %08x\n", regval); + + priv->nbits = nbits; + } +} + +static void ssi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + uint32_t enable; + + /* NOTE that the SSI must be disabled when setting any configuration registers. */ + + enable = ssi_disable(priv); + ssi_setbitsinternal(priv, nbits); + ssi_enable(priv, enable); +} + +/**************************************************************************** + * Name: ssi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t ssi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + uint16_t response = 0; + + (void)ssi_transfer(priv, &wd, &response, 1); + return response; +} + +/**************************************************************************** + * Name: SPI_EXCHANGE + * + * Description: + * Exahange a block of data from SPI. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_EXCHANGE +static void ssi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + (void)ssi_transfer(priv, txbuffer, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: ssi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void ssi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + (void)ssi_transfer(priv, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: ssi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void ssi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev; + (void)ssi_transfer(priv, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_ssibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SSI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *tiva_ssibus_initialize(int port) +{ + struct tiva_ssidev_s *priv; + irqstate_t flags; + + ssidbg("port: %d\n", port); + + /* Set up for the selected port */ + + flags = enter_critical_section(); + switch (port) + { +#ifdef CONFIG_TIVA_SSI0 + case 0: + /* Select SSI0 */ + + priv = &g_ssidev[SSI0_NDX]; + + /* Enable power and clocking to the SSI0 peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the + * SSI0 peripheral. This is not an essential step since enabling + * clocking will also apply power. The only significance is that + * the SSI0 state will be retained if the SSI0 clocking is + * subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking + * to the SSI0 peripheral, bringing it a fully functional state. + */ + + tiva_ssi0_enablepwr(); + tiva_ssi0_enableclk(); + + /* Configure SSI0 GPIOs (NOTE that SS is not initialized here, the + * logic in this file makes no assumptions about chip select) + */ + + tiva_configgpio(GPIO_SSI0_CLK); /* PA2: SSI0 clock (SSI0Clk) */ + /* tiva_configgpio(GPIO_SSI0_FSS); PA3: SSI0 frame (SSI0Fss) */ + tiva_configgpio(GPIO_SSI0_RX); /* PA4: SSI0 receive (SSI0Rx) */ + tiva_configgpio(GPIO_SSI0_TX); /* PA5: SSI0 transmit (SSI0Tx) */ + break; +#endif /* CONFIG_TIVA_SSI0 */ + +#ifdef CONFIG_TIVA_SSI1 + case 1: + /* Select SSI1 */ + + priv = &g_ssidev[SSI1_NDX]; + + /* Enable power and clocking to the SSI1 peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the + * SSI1 peripheral. This is not an essential step since enabling + * clocking will also apply power. The only significance is that + * the SSI1 state will be retained if the SSI1 clocking is + * subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking + * to the SSI1 peripheral, bringing it a fully functional state. + */ + + tiva_ssi1_enablepwr(); + tiva_ssi1_enableclk(); + + /* Configure SSI1 GPIOs */ + + tiva_configgpio(GPIO_SSI1_CLK); /* PE0: SSI1 clock (SSI1Clk) */ + /* tiva_configgpio(GPIO_SSI1_FSS); PE1: SSI1 frame (SSI1Fss) */ + tiva_configgpio(GPIO_SSI1_RX); /* PE2: SSI1 receive (SSI1Rx) */ + tiva_configgpio(GPIO_SSI1_TX); /* PE3: SSI1 transmit (SSI1Tx) */ + break; +#endif /* CONFIG_TIVA_SSI1 */ + +#ifdef CONFIG_TIVA_SSI2 + case 2: + /* Select SSI2 */ + + priv = &g_ssidev[SSI2_NDX]; + + /* Enable power and clocking to the SSI2 peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the + * SSI2 peripheral. This is not an essential step since enabling + * clocking will also apply power. The only significance is that + * the SSI2 state will be retained if the SSI2 clocking is + * subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking + * to the SSI2 peripheral, bringing it a fully functional state. + */ + + tiva_ssi2_enablepwr(); + tiva_ssi2_enableclk(); + + /* Configure SSI2 GPIOs */ + + tiva_configgpio(GPIO_SSI2_CLK); /* PE0: SSI2 clock (SSI2Clk) */ + /* tiva_configgpio(GPIO_SSI2_FSS); PE1: SSI2 frame (SSI2Fss) */ + tiva_configgpio(GPIO_SSI2_RX); /* PE2: SSI2 receive (SSI2Rx) */ + tiva_configgpio(GPIO_SSI2_TX); /* PE3: SSI2 transmit (SSI2Tx) */ + break; +#endif /* CONFIG_TIVA_SSI2 */ + +#ifdef CONFIG_TIVA_SSI3 + case 3: + /* Select SSI3 */ + + priv = &g_ssidev[SSI3_NDX]; + + /* Enable power and clocking to the SSI3 peripheral. + * + * - Enable Power (TM4C129 family only): Applies power (only) to the + * SSI3 peripheral. This is not an essential step since enabling + * clocking will also apply power. The only significance is that + * the SSI3 state will be retained if the SSI3 clocking is + * subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking + * to the SSI3 peripheral, bringing it a fully functional state. + */ + + tiva_ssi1_enablepwr(); + tiva_ssi1_enableclk(); + + /* Configure SSI3 GPIOs */ + + tiva_configgpio(GPIO_SSI3_CLK); /* PE0: SSI3 clock (SSI3Clk) */ + /* tiva_configgpio(GPIO_SSI3_FSS); PE1: SSI3 frame (SSI3Fss) */ + tiva_configgpio(GPIO_SSI3_RX); /* PE2: SSI3 receive (SSI3Rx) */ + tiva_configgpio(GPIO_SSI3_TX); /* PE3: SSI3 transmit (SSI3Tx) */ + break; +#endif /* CONFIG_TIVA_SSI1 */ + + default: + leave_critical_section(flags); + return NULL; + } + + /* Initialize the state structure */ + +#ifndef CONFIG_SSI_POLLWAIT + sem_init(&priv->xfrsem, 0, 0); +#endif + sem_init(&priv->exclsem, 0, 1); + + /* Set all CR1 fields to reset state. This will be master mode. */ + + ssi_putreg(priv, TIVA_SSI_CR1_OFFSET, 0); + + /* Set all CR0 fields to the reset state. This will also select Freescale SPI mode. */ + + ssi_putreg(priv, TIVA_SSI_CR0_OFFSET, 0); + + /* Set the initial mode to mode 0. The application may override + * this initial setting using the setmode() method. + */ + + ssi_setmodeinternal(priv, SPIDEV_MODE0); + + /* Set the initial data width to 8-bits. The application may + * override this initial setting using the setbits() method. + */ + + ssi_setbitsinternal(priv, 8); + + /* Pick some initialize clock frequency. 400,000Hz is the startup + * MMC/SD frequency used for card detection. The application may + * override this setting using the setfrequency() method. + */ + + ssi_setfrequencyinternal(priv, 400000); + + /* Disable all SSI interrupt sources. They will be enabled only + * while there is an SSI transfer in progress. + */ + + ssi_putreg(priv, TIVA_SSI_IM_OFFSET, 0); + + /* Attach the interrupt */ + +#ifndef CONFIG_SSI_POLLWAIT +#if NSSI_ENABLED > 1 + irq_attach(priv->irq, (xcpt_t)ssi_interrupt); +#else + irq_attach(SSI_IRQ, (xcpt_t)ssi_interrupt); +#endif +#endif /* CONFIG_SSI_POLLWAIT */ + + /* Enable the SSI for operation */ + + ssi_enable(priv, SSI_CR1_SSE); + + /* Enable SSI interrupts (They are still disabled at the source). */ + +#ifndef CONFIG_SSI_POLLWAIT +#if NSSI_ENABLED > 1 + up_enable_irq(priv->irq); +#else + up_enable_irq(SSI_IRQ); +#endif +#endif /* CONFIG_SSI_POLLWAIT */ + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* NSSI_ENABLED > 0 */ diff --git a/arch/arm/src/tiva/tiva_ssi.h b/arch/arm/src/tiva/tiva_ssi.h new file mode 100644 index 0000000000000000000000000000000000000000..6ef306cefc7c692480808766dee42ba60a8c6064 --- /dev/null +++ b/arch/arm/src/tiva/tiva_ssi.h @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_ssi.h + * + * Copyright (C) 2009-2010, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_SSI_H +#define __ARCH_ARM_SRC_TIVA_TIVA_SSI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Name: tiva_ssibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SSI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s; +FAR struct spi_dev_s *tiva_ssibus_initialize(int port); + +/**************************************************************************** + * The external functions, tiva_ssiselect, tiva_ssistatus, and + * tiva_ssicmddata must be provided by board-specific logic. These are + * implementations of the select, status, and cmddata methods of the SPI + * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). + * All other methods (including tiva_ssibus_initialize()) are provided by common + * logic. To use this common SPI logic on your board: + * + * 1. Provide logic in tiva_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide tiva_ssiselect() and tiva_ssistatus() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration, provide + * the tiva_ssicmddata() function in your board-specific logic. This + * functions will perform cmd/data selection operations using GPIOs in + * the way your board is configured. + * 4. Add a call to tiva_ssibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by tiva_ssibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; +void tiva_ssiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t tiva_ssistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int tiva_ssicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_SSI_H */ diff --git a/arch/arm/src/tiva/tiva_start.c b/arch/arm/src/tiva/tiva_start.c new file mode 100644 index 0000000000000000000000000000000000000000..6ecc46223eb8f4c0a7beb824a31d3e79d7e3c868 --- /dev/null +++ b/arch/arm/src/tiva/tiva_start.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_start.c + * + * Copyright (C) 2009, 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "tiva_lowputc.h" +#include "tiva_syscontrol.h" +#include "tiva_userspace.h" +#include "tiva_start.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ +#ifdef CONFIG_BOOT_RUNFROMFLASH + const uint32_t *src; +#endif + uint32_t *dest; + + /* Configure the UART so that we can get debug output as soon as possible */ + +#ifdef CONFIG_TIVA_BOARD_EARLYINIT + board_earlyinit(); +#else + up_clockconfig(); + up_lowsetup(); +#endif + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + showprogress('B'); + +#ifdef CONFIG_BOOT_RUNFROMFLASH + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + showprogress('C'); +#endif + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + tiva_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + tiva_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/tiva/tiva_start.h b/arch/arm/src/tiva/tiva_start.h new file mode 100644 index 0000000000000000000000000000000000000000..ab4a2cd9292db2f43c7f1dc75aa5b7814b63a2b9 --- /dev/null +++ b/arch/arm/src/tiva/tiva_start.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_start.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_START_H +#define __ARCH_ARM_SRC_TIVA_TIVA_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_earlyinit + * + * Description: + * If CONFIG_TIVA_BOARD_EARLYINIT, then board-specific logic must provide + * the function board_earlyinit() to provide very customized lower-level + * board bringup. board_earlyinit() will be called by the start-up logic + * instead of up_clockconfig() and up_lowsetup(). + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_BOARD_EARLYINIT +void board_earlyinit(void); +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_START_H */ diff --git a/arch/arm/src/tiva/tiva_syscontrol.c b/arch/arm/src/tiva/tiva_syscontrol.c new file mode 100644 index 0000000000000000000000000000000000000000..4f056033c4fb033c1391b8591316dcae38c0a657 --- /dev/null +++ b/arch/arm/src/tiva/tiva_syscontrol.c @@ -0,0 +1,435 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_syscontrol.c + * + * Copyright (C) 2009-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "chip.h" +#include "tiva_syscontrol.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(LM4F) || defined(TM4C) +# define RCC_XTALMASK (SYSCON_RCC_XTAL_MASK | SYSCON_RCC_OSCSRC_MASK | \ + SYSCON_RCC_PWRDN) +# define RCC2_XTALMASK (SYSCON_RCC2_OSCSRC2_MASK | SYSCON_RCC2_PWRDN2 | \ + SYSCON_RCC2_DIV400 | SYSCON_RCC2_USERCC2) +# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK | SYSCON_RCC_USESYSDIV | \ + SYSCON_RCC_MOSCDIS) +# define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2LSB | SYSCON_RCC2_SYSDIV2_MASK) +#else +# define RCC_OSCMASK (SYSCON_RCC_IOSCDIS | SYSCON_RCC_MOSCDIS) +# define RCC_XTALMASK (SYSCON_RCC_XTAL_MASK | SYSCON_RCC_OSCSRC_MASK | \ + SYSCON_RCC_PWRDN) +# define RCC2_XTALMASK (SYSCON_RCC2_OSCSRC2_MASK | SYSCON_RCC2_PWRDN2 | \ + SYSCON_RCC2_SYSDIV2_MASK | SYSCON_RCC2_USERCC2) +# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK | SYSCON_RCC_USESYSDIV | \ + SYSCON_RCC_IOSCDIS | SYSCON_RCC_MOSCDIS) +# define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2_MASK) +#endif + +#define FAST_OSCDELAY (512*1024) +#define SLOW_OSCDELAY (4*1024) +#define PLLLOCK_DELAY (32*1024) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_delay + * + * Description: + * Wait for the newly selected oscillator(s) to settle. This is tricky because + * the time that we wait can be significant and is determined by the previous + * clock setting, not the one that we are configuring. + * + ****************************************************************************/ + +static inline void tiva_delay(uint32_t delay) +{ + __asm__ __volatile__("1:\n" + "\tsubs %0, #1\n" + "\tbne 1b\n" + : "=r"(delay) : "r"(delay)); +} + +/**************************************************************************** + * Name: tiva_oscdelay + * + * Description: + * Wait for the newly selected oscillator(s) to settle. This is tricky because + * the time that we wait can be significant and is determined by the previous + * clock setting, not the one that we are configuring. + * + ****************************************************************************/ + +static inline void tiva_oscdelay(uint32_t rcc, uint32_t rcc2) +{ + /* Wait for the oscillator to stabilize. A smaller delay is used if the + * current clock rate is very slow. + */ + + uint32_t delay = FAST_OSCDELAY; + + /* Are we currently using RCC2? */ + + if ((rcc2 & SYSCON_RCC2_USERCC2) != 0) + { + uint32_t rcc2src = rcc2 & SYSCON_RCC2_OSCSRC2_MASK; + if ((rcc2src == SYSCON_RCC2_OSCSRC2_LFIOSC) || + (rcc2src == SYSCON_RCC2_OSCSRC2_32768HZ)) + { + delay = SLOW_OSCDELAY; + } + } + + /* No.. using OSCSRC in RCC */ + + else + { + uint32_t rccsrc = rcc & SYSCON_RCC_OSCSRC_MASK; + if (rccsrc == SYSCON_RCC_OSCSRC_LFIOSC) + { + delay = SLOW_OSCDELAY; + } + } + + /* Then delay that number of loops */ + + tiva_delay(delay); +} + +/**************************************************************************** + * Name: tiva_pll_lock + * + * Description: + * The new RCC values have been selected... wait for the PLL to lock on + * + ****************************************************************************/ + +static inline void tiva_pll_lock(void) +{ + volatile uint32_t delay; + + /* Loop until the lock is achieved or until a timeout occurs */ + + for (delay = PLLLOCK_DELAY; delay > 0; delay--) + { + /* Check if the PLL is locked on */ + + if ((getreg32(TIVA_SYSCON_RIS) & SYSCON_RIS_PLLLRIS) != 0) + { + /* Yes.. return now */ + + return; + } + } + + /* If we get here, then PLL lock was not achieved */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_clockconfig + * + * Description: + * Called to change to new clock based on desired rcc and rcc2 settings. + * This is use to set up the initial clocking but can be used later to + * support slow clocked, low power consumption modes. + * + ****************************************************************************/ + +void tiva_clockconfig(uint32_t newrcc, uint32_t newrcc2) +{ + uint32_t rcc; + uint32_t rcc2; + + /* Get the current values of the RCC and RCC2 registers */ + + rcc = getreg32(TIVA_SYSCON_RCC); + rcc2 = getreg32(TIVA_SYSCON_RCC2); + + /* We are probably using the main oscillator. The main oscillator is + * disabled on reset and so probably must be enabled here. The internal + * oscillator is enabled on reset and if that is selected, most likely + * nothing needs to be done. + */ + +#if defined(LM4F) || defined(TM4C) + if ((rcc & SYSCON_RCC_MOSCDIS) != 0 && (newrcc & SYSCON_RCC_MOSCDIS) == 0) + { + uint32_t dummy; + + /* According to TM4C123GH6PM datasheet page 231 item 5.3 we must perform + * the following steps to initialize and configure TM4C123G chip to use + * a PLL based system clock. + * + * 1. Bypass the PLL and system clock divider by setting the BYPASS bit + * and clearing the USESYS bit in the RCC register. + * + * 2. Select the crystal value (XTAL) and oscillator source (OSCSRC), + * and clear the PWRDN bit in RCC/RCC2. Setting the XTAL field + * automatically pulls valid PLL configuration data for the appropriate + * crystal, and clearing the PWRDN bit powers and enables the PLL and + * its output. + * + * 3. Select the desired system divider (SYSDIV) in RCC/RCC2 and set the + * USESYS bit in RCC. The SYSDIV field determines the system + * frequency for the microcontroller. + * + * 4. Wait for the PLL to lock by polling the PLLLRIS bit in the Raw + * Interrupt Status (RIS) register. + * + * 5. Enable use of the PLL by clearing the BYPASS bit in RCC/RCC2. + */ + + /* Step 1 - Temporarily bypass the PLL and system clock dividers */ + + rcc |= SYSCON_RCC_BYPASS; + rcc &= ~(SYSCON_RCC_USESYSDIV); + + rcc2 |= SYSCON_RCC2_BYPASS2; + + /* According to TM4C123GH6PM datasheet we must write RCC register prior + * to writing the RCC2 register. + */ + + putreg32(rcc, TIVA_SYSCON_RCC); + dummy = getreg32(TIVA_SYSCON_RCC); + UNUSED(dummy); + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Step 2 - Set the new crystal value, oscillator source and PLL + * configuration. + */ + + rcc &= ~RCC_XTALMASK; + rcc |= (newrcc & RCC_XTALMASK); + + rcc2 &= ~RCC2_XTALMASK; + rcc2 |= (newrcc2 & RCC2_XTALMASK); + + /* Write the new RCC/RCC2 values. + * + * LM4F120 Data Sheet: "Write the RCC register prior to writing the + * RCC2 register. If a subsequent write to the RCC register is required, + * include another register access after writing the RCC register and + * before writing the RCC2 register." + */ + + putreg32(rcc, TIVA_SYSCON_RCC); + dummy = getreg32(TIVA_SYSCON_RCC); + UNUSED(dummy); + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Wait for the new crystal value and oscillator source to take effect */ + + tiva_delay(16); + + /* Step 3 - Set the requested system divider and disable the non- + * selected oscillators. + */ + + rcc &= ~RCC_DIVMASK; + rcc |= (newrcc & RCC_DIVMASK); + + rcc2 &= ~RCC2_DIVMASK; + rcc2 |= (newrcc2 & RCC2_DIVMASK); + + putreg32(rcc, TIVA_SYSCON_RCC); + dummy = getreg32(TIVA_SYSCON_RCC); + UNUSED(dummy); + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Step 4 - Will the PLL output be used to clock the system? */ + + if ((newrcc & SYSCON_RCC_BYPASS) == 0) + { + /* Yes, wait until l the PLL is locked */ + + tiva_pll_lock(); + + /* Step 5 - Then enable the PLL */ + + rcc &= ~SYSCON_RCC_BYPASS; + rcc2 &= ~SYSCON_RCC2_BYPASS2; + + putreg32(rcc, TIVA_SYSCON_RCC); + dummy = getreg32(TIVA_SYSCON_RCC); + UNUSED(dummy); + putreg32(rcc2, TIVA_SYSCON_RCC2); + } + } +#elif defined(CONFIG_ARCH_CHIP_CC3200) +#if 0 + /* NOTE: we do this in up_earlyconsoleinit() */ + + cc3200_init(); +#endif +#else + if (((rcc & SYSCON_RCC_MOSCDIS) != 0 && (newrcc & SYSCON_RCC_MOSCDIS) == 0) || + ((rcc & SYSCON_RCC_IOSCDIS) != 0 && (newrcc & SYSCON_RCC_IOSCDIS) == 0)) + { + /* Temporarily bypass the PLL and system clock dividers */ + + rcc |= SYSCON_RCC_BYPASS; + rcc &= ~(SYSCON_RCC_USESYSDIV); + putreg32(rcc, TIVA_SYSCON_RCC); + + rcc2 |= SYSCON_RCC2_BYPASS2; + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Enable any selected oscillators (but don't disable any yet) */ + + rcc &= (~RCC_OSCMASK | (newrcc & RCC_OSCMASK)); + putreg32(rcc, TIVA_SYSCON_RCC); + + /* Wait for the newly selected oscillator(s) to settle. This is tricky because + * the time that we wait can be significant and is determined by the previous + * clock setting, not the one that we are configuring. + */ + + tiva_oscdelay(rcc, rcc2); + + /* Set the new crystal value, oscillator source and PLL configuration */ + + rcc &= ~RCC_XTALMASK; + rcc |= (newrcc & RCC_XTALMASK); + + rcc2 &= ~RCC2_XTALMASK; + rcc2 |= (newrcc2 & RCC2_XTALMASK); + + /* Clear the PLL lock interrupt */ + + putreg32(SYSCON_MISC_PLLLMIS, TIVA_SYSCON_MISC); + + /* Write the new RCC/RCC2 values. + * + * Original LM3S Logic: Order depends upon whether RCC2 or RCC is + * currently enabled. + */ + + putreg32(rcc, TIVA_SYSCON_RCC); + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Wait for the new crystal value and oscillator source to take effect */ + + tiva_delay(16); + + /* Set the requested system divider and disable the non-selected osciallators */ + + rcc &= ~RCC_DIVMASK; + rcc |= (newrcc & RCC_DIVMASK); + + rcc2 &= ~RCC2_DIVMASK; + rcc2 |= (newrcc2 & RCC2_DIVMASK); + + /* Will the PLL output be used to clock the system? */ + + if ((newrcc & SYSCON_RCC_BYPASS) == 0) + { + /* Yes, wait until the PLL is locked */ + + tiva_pll_lock(); + + /* Then enable the PLL */ + + rcc &= ~SYSCON_RCC_BYPASS; + rcc2 &= ~SYSCON_RCC2_BYPASS2; + } + + /* Now we can set the final RCC/RCC2 values */ + + putreg32(rcc, TIVA_SYSCON_RCC); + putreg32(rcc2, TIVA_SYSCON_RCC2); + + /* Wait for the system divider to be effective */ + + tiva_delay(6); + } +#endif +} + +/**************************************************************************** + * Name: up_clockconfig + * + * Description: + * Called early in the boot sequence (before .data and .bss are available) + * in order to configure initial clocking. + * + ****************************************************************************/ + +void up_clockconfig(void) +{ +#ifdef CONFIG_LM_REVA2 + /* Some early LM3 silicon returned an increase LDO voltage or 2.75V to work + * around a PLL bug + */ + + putreg32(SYSCON_LPDOPCTL_2750MV, TIVA_SYSCON_LDOPCTL); +#endif + + /* Set the clocking to run with the default settings provided in the board.h + * header file + */ + + tiva_clockconfig(TIVA_RCC_VALUE, TIVA_RCC2_VALUE); +} diff --git a/arch/arm/src/tiva/tiva_syscontrol.h b/arch/arm/src/tiva/tiva_syscontrol.h new file mode 100644 index 0000000000000000000000000000000000000000..fc1bef59506f6d53b12063c89c5bd58b1f8b7bff --- /dev/null +++ b/arch/arm/src/tiva/tiva_syscontrol.h @@ -0,0 +1,151 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_syscontrol.h + * + * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_SYSCONTROL_H +#define __ARCH_ARM_SRC_TIVA_TIVA_SYSCONTROL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_TM4C129 +/* Helpers for use with the TM4C129 version of tiva_clockconfig() */ + +# define M2PLLFREQ0(mint,mfrac) \ + ((uint32_t)((mint) << SYSCON_PLLFREQ0_MINT_SHIFT) | \ + (uint32_t)((mfrac) << SYSCON_PLLFREQ0_MFRAC_SHIFT)) + +# define QN2PLLFREQ1(q,n) \ + ((uint32_t)(((n) - 1) << SYSCON_PLLFREQ1_N_SHIFT) | \ + (uint32_t)(((q) - 1) << SYSCON_PLLFREQ1_Q_SHIFT)) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_TM4C129 +/**************************************************************************** + * Name: tiva_clockconfig + * + * Description: + * Called to change to new clock based on desired pllfreq0, pllfreq1, and + * sysdiv settings. This is use to set up the initial clocking but can be + * used later to support slow clocked, low power consumption modes. + * + * The pllfreq0 and pllfreq1 settings derive from the PLL M, N, and Q + * values to generate Fvco like: + * + * Fin = Fxtal / Q / N -OR- Fpiosc / Q / N + * Mdiv = Mint + (MFrac / 1024) + * Fvco = Fin * Mdiv + * + * When the PLL is active, the system clock frequency (SysClk) is + * calculated using the following equation: + * + * SysClk = Fvco/ sysdiv + * + * NOTE: The input clock to the PLL may be either the external crystal + * (Fxtal) or PIOSC (Fpiosc). This logic supports only the external + * crystal as the PLL source clock. + * + * Input Parameters: + * pllfreq0 - PLLFREQ0 register value (see helper macro M2PLLFREQ0() + * pllfreq1 - PLLFREQ1 register value (see helper macro QN2PLLFREQ1() + * sysdiv - Fvco divider value + * + * Returned Value: + * The resulting SysClk frequency + * + ****************************************************************************/ + +uint32_t tiva_clockconfig(uint32_t pllfreq0, uint32_t pllfreq1, uint32_t sysdiv); + +#else +/**************************************************************************** + * Name: tiva_clockconfig + * + * Description: + * Called to change to new clock based on desired rcc and rcc2 settings. + * This is use to set up the initial clocking but can be used later to + * support slow clocked, low power consumption modes. + * + ****************************************************************************/ + +void tiva_clockconfig(uint32_t newrcc, uint32_t newrcc2); +#endif + +/**************************************************************************** + * Name: up_clockconfig + * + * Description: + * Called early in the boot sequence (before .data and .bss are available) + * in order to configure initial clocking. + * + ****************************************************************************/ + +void up_clockconfig(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_SYSCONTROL_H */ diff --git a/arch/arm/src/tiva/tiva_timer.h b/arch/arm/src/tiva/tiva_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..0f262bc73e24039ff52fef4c448a20ac77009f73 --- /dev/null +++ b/arch/arm/src/tiva/tiva_timer.h @@ -0,0 +1,863 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_timer.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_TIMER_H +#define __ARCH_ARM_SRC_TIVA_TIVA_TIMER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "chip/tiva_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Make sure that no timers are enabled that are not supported by the + * architecture. + */ + +#if TIVA_NTIMERS < 8 +# undef CONFIG_TIVA_TIMER7 +# if TIVA_NTIMERS < 7 +# undef CONFIG_TIVA_TIMER6 +# if TIVA_NTIMERS < 6 +# undef CONFIG_TIVA_TIMER5 +# if TIVA_NTIMERS < 5 +# undef CONFIG_TIVA_TIMER4 +# if TIVA_NTIMERS < 4 +# undef CONFIG_TIVA_TIMER3 +# if TIVA_NTIMERS < 3 +# undef CONFIG_TIVA_TIMER2 +# if TIVA_NTIMERS < 2 +# undef CONFIG_TIVA_TIMER1 +# if TIVA_NTIMERS < 1 +# undef CONFIG_TIVA_TIMER0 +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + +/* Used with the synca and syncb fields of struct tiva_timerconfig_s */ + +#define TIMER_SYNC(n) (1 << (n)) + +/* Identifies 16-bit timer A and timer B. In contexts where an index is + * needed, the 32-bit timer is equivalent to the timer A index. + */ + +#define TIMER32 0 +#define TIMER16A 0 +#define TIMER16B 1 + +/* Flags bit definitions in configuration structures. NOTE: not all flags + * apply in all timer modes. Applicable modes noted with: + * + * a. 32-bit one shot timer + * b. 32-bit periodic timer + * c. 32-bit one shot timer + * d. 32-bit periodic timer + * e. 32-bit RTC timer + */ + +#define TIMER_FLAG_COUNTUP (1 << 0) /* Bit 0: Count up (abcd) */ +#define TIMER_FLAG_ADCTIMEOUT (1 << 1) /* Bit 1: Generate ADC trigger on + * timeout (abcd) */ +#define TIMER_FLAG_ADCRTCM (1 << 2) /* Bit 2: Generate ADC trigger on + * RTC match (e) */ +#define TIMER_FLAG_ADCMATCH (1 << 3) /* Bit 3: Generate ADC trigger on + * match (abcd) */ +#define TIMER_FLAG_DMATIMEOUT (1 << 4) /* Bit 4: Generate uDMA trigger on + * timeout (abcd) */ +#define TIMER_FLAG_DMARTCM (1 << 5) /* Bit 5: Generate uDMA trigger on + * RTC match (e) */ +#define TIMER_FLAG_DMAMATCH (1 << 6) /* Bit 6: Generate uDMA trigger on + * match (abcd) */ + +#define TIMER_ISCOUNTUP(c) ((((c)->flags) & TIMER_FLAG_COUNTUP) != 0) +#define TIMER_ISADCTIMEOUT(c) ((((c)->flags) & TIMER_FLAG_ADCTIMEOUT) != 0) +#define TIMER_ISADCRTCM(c) ((((c)->flags) & TIMER_FLAG_ADCRTCM) != 0) +#define TIMER_ISADCMATCH(c) ((((c)->flags) & TIMER_FLAG_ADCMATCH) != 0) +#define TIMER_ISDMATIMEOUT(c) ((((c)->flags) & TIMER_FLAG_DMATIMEOUT) != 0) +#define TIMER_ISDMARTCM(c) ((((c)->flags) & TIMER_FLAG_DMARTCM) != 0) +#define TIMER_ISDMAMATCH(c) ((((c)->flags) & TIMER_FLAG_DMAMATCH) != 0) + +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the timer + * driver. NOTE: that only lldbg types are used so that the output is + * immediately available. + */ + +#ifdef CONFIG_DEBUG_TIMER +# define timdbg lldbg +# define timvdbg llvdbg +#else +# define timdbg(x...) +# define timvdbg(x...) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This enumeration identifies all supported 32-bit timer modes of operation + * + * NOTES: + * - TIMER32_MODE_RTC: The input clock on a CCP0 input is required to be + * 32.768 KHz in RTC mode. The clock signal is then divided down to a 1-Hz + * rate and is passed along to the input of the counter. + */ + +enum tiva_timer32mode_e +{ + TIMER16_MODE = 0, /* Use 16-bit timers, not 32-bit timer */ + TIMER32_MODE_ONESHOT, /* 32-bit programmable one-shot timer */ + TIMER32_MODE_PERIODIC, /* 32-bit programmable periodic timer */ + TIMER32_MODE_RTC /* 32-bit RTC with external 32.768-KHz input */ +}; + +/* This enumeration identifies all supported 16-bit timer A/B modes of + * operation. + */ + +enum tiva_timer16mode_e +{ + TIMER16_MODE_NONE = 0, /* 16-bit timer not used */ + TIMER16_MODE_ONESHOT, /* 16-bit programmable one-shot timer */ + TIMER16_MODE_PERIODIC, /* 16-bit programmable periodic timer */ + TIMER16_MODE_COUNT_CAPTURE, /* 16-bit input edge-count capture mode w/8-bit prescaler */ + TIMER16_MODE_TIME_CAPTURE, /* 16-bit input time capture mode w/8-bit prescaler */ + TIMER16_MODE_PWM /* 16-bit PWM output mode w/8-bit prescaler */ +}; + +/* This type represents the opaque handler returned by tiva_gptm_configure() */ + +typedef FAR void *TIMER_HANDLE; + +#ifdef CONFIG_TIVA_TIMER_32BIT +/* This type describes the 32-bit timer interrupt handler. + * + * Input Parameters: + * handle - The same value as returned by tiva_gptm_configure() + * arg - The same value provided in struct tiva_timer32config_s + * status - The value of the GPTM masked status register that caused the + * interrupt + */ + +struct tiva_gptm32config_s; +typedef void (*timer32_handler_t)(TIMER_HANDLE handle, void *arg, + uint32_t status); + +/* This structure describes the configuration of one 32-bit timer */ + +struct tiva_timer32config_s +{ + uint8_t flags; /* See TIMER_FLAG_* definitions */ + timer32_handler_t handler; /* Non-NULL: Interrupts will be enabled + * and forwarded to this function */ + void *arg; /* Argument that accompanies the handler + * callback. + */ + + /* Mode-specific parameters may follow */ +}; +#endif + +#ifdef CONFIG_TIVA_TIMER_16BIT +/* This type describes the 16-bit timer interrupt handler + * + * Input Parameters: + * handle - The same value as returned by tiva_gptm_configure() + * arg - The same value provided in struct tiva_timer16config_s + * status - The value of the GPTM masked status register that caused the + * interrupt. + * tmndx - Either TIMER16A or TIMER16B. This may be useful in the + * event that the same handler is used for Timer A and B. + */ + +struct tiva_gptm16config_s; +typedef void (*timer16_handler_t)(TIMER_HANDLE handle, void *arg, + uint32_t status, int tmndx); + +/* This structure describes the configuration of one 16-bit timer A/B */ + +struct tiva_timer16config_s +{ + uint8_t mode; /* See enum tiva_timermode_e */ + uint8_t flags; /* See TIMER_FLAG_* definitions */ + timer16_handler_t handler; /* Non-NULL: Interrupts will be enabled + * and forwarded to this function */ + void *arg; /* Argument that accompanies the handler + * callback. + */ + + /* Mode-specific parameters may follow */ +}; +#endif + +/* This structure describes usage of both timers on a GPTIM module */ + +struct tiva_gptmconfig_s +{ + uint8_t gptm; /* GPTM number */ + uint8_t mode; /* See enum tiva_timer32mode_e */ + bool alternate; /* False: Use SysClk; True: Use alternate clock source */ +}; + +#ifdef CONFIG_TIVA_TIMER_32BIT +/* This structure is cast compatible with struct tiva_gptmconfig_s and + * describes usage of the single 32-bit timers on a GPTM module. + */ + +struct tiva_gptm32config_s +{ + struct tiva_gptmconfig_s cmn; + struct tiva_timer32config_s config; +}; +#endif + +/* This structure is cast compatible with struct tiva_gptmconfig_s and + * describes usage of both bit-bit timers A/B on a GPTM module. + */ + +#ifdef CONFIG_TIVA_TIMER_16BIT +struct tiva_gptm16config_s +{ + struct tiva_gptmconfig_s cmn; + struct tiva_timer16config_s config[2]; +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_gptm_configure + * + * Description: + * Configure a general purpose timer module to operate in the provided + * modes. + * + * Input Parameters: + * gptm - Describes the configure of the GPTM timer resources + * + * Returned Value: + * On success, a non-NULL handle is returned that can be used with the + * other timer interfaces. NULL is returned on any failure to initialize + * the timer. + * + ****************************************************************************/ + +TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *gptm); + +/**************************************************************************** + * Name: tiva_gptm_release + * + * Description: + * Release resources held by the timer instance. After this function is + * called, the timer handle is invalid and must not be used further. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_release(TIMER_HANDLE handle); + +/**************************************************************************** + * Name: tiva_gptm_putreg + * + * Description: + * This function permits setting of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * value - The value to write to the timer register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value); + +/**************************************************************************** + * Name: tiva_gptm_getreg + * + * Description: + * This function permits reading of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * + * Returned Value: + * The 32-bit value read at the provided offset into the timer register base + * address. + * + ****************************************************************************/ + +uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset); + +/**************************************************************************** + * Name: tiva_gptm_modifyreg + * + * Description: + * This function permits atomic of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * clrbits - The collection of bits to be cleared in the register + * setbits - The collection of bits to be set in the register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, + uint32_t clrbits, uint32_t setbits); + +/**************************************************************************** + * Name: tiva_timer32_start + * + * Description: + * After tiva_gptm_configure() has been called to configure a 32-bit timer, + * this function must be called to start the timer(s). + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_start(TIMER_HANDLE handle); +#endif + +/**************************************************************************** + * Name: tiva_timer16_start + * + * Description: + * After tiva_gptm_configure() has been called to configure 16-bit timer(s), + * this function must be called to start one 16-bit timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_start(TIMER_HANDLE handle, int tmndx); + +# define tiva_timer16a_start(h) tiva_timer16_start(h, TIMER16A) +# define tiva_timer16b_start(h) tiva_timer16_start(h, TIMER16B) +#endif + +/**************************************************************************** + * Name: tiva_timer32_stop + * + * Description: + * After tiva_timer32_start() has been called to start a 32-bit timer, + * this function may be called to stop the timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_stop(TIMER_HANDLE handle); +#endif + +/**************************************************************************** + * Name: tiva_timer16_stop + * + * Description: + * After tiva_timer32_start() has been called to start a 16-bit timer, + * this function may be called to stop the timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx); + +# define tiva_timer16a_stop(h) tiva_timer16_stop(h, TIMER16A) +# define tiva_timer16b_stop(h) tiva_timer16_stop(h, TIMER16B) +#endif + +/**************************************************************************** + * Name: tiva_timer32_counter + * + * Description: + * Return the current 32-bit counter value of the 32-bit timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * The current 32-bit counter value. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +static inline uint32_t tiva_timer32_counter(TIMER_HANDLE handle) +{ + return tiva_gptm_getreg(handle, TIVA_TIMER_TAR_OFFSET); +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_counter + * + * Description: + * Return the current 24-bit counter value of the 16-bit timer. + * + * The timer 24-bit value is the 16-bit counter value AND the 8-bit + * prescaler value. From the caller's point of view the match value is + * the 24-bit timer at the timer input clock frequency. + * + * When counting down in periodic modes, the prescaler contains the + * least-significant bits of the count. When counting up, the prescaler + * holds the most-significant bits of the count. But the caller is + * protected from this complexity. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * The current 24-bit counter value. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +uint32_t tiva_timer16_counter(TIMER_HANDLE handle, int tmndx); + +# define tiva_timer16a_counter(h) tiva_timer16_counter(h, TIMER16A) +# define tiva_timer16b_counter(h) tiva_timer16_counter(h, TIMER16B) +#endif + +/**************************************************************************** + * Name: tiva_timer32_setinterval + * + * Description: + * This function may be called at any time to change the timer interval + * load value of a 32-bit timer. + * + * It the timer is configured as a 32-bit one-shot or periodic timer, then + * then function will also enable timeout interrupts. + * + * NOTE: As of this writing, there is no interface to disable the timeout + * interrupts once they have been enabled. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * interval - The value to write to the timer interval load register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_setinterval(TIMER_HANDLE handle, uint32_t interval); +#endif + +/**************************************************************************** + * Name: tiva_timer16_setinterval + * + * Description: + * This function may be called at any time to change the timer interval + * load value of a 16-bit timer. + * + * It the timer is configured as a 16-bit one-shot or periodic timer, then + * then function will also enable timeout interrupts. + * + * NOTE: As of this writing, there is no interface to disable the timeout + * interrupts once they have been enabled. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * interval - The value to write to the timer interval load register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_setinterval(TIMER_HANDLE handle, uint16_t interval, int tmndx); + +# define tiva_timer16a_setinterval(h,l) tiva_timer16_setinterval(h,l,TIMER16A) +# define tiva_timer16b_setinterval(h,l) tiva_timer16_setinterval(h,l,TIMER16B) +#endif + +/**************************************************************************** + * Name: tiva_timer32_remaining + * + * Description: + * Get the time remaining before a one-shot or periodic 32-bit timer + * expires. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure(). + * + * Returned Value: + * Time remaining until the next timeout interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +uint32_t tiva_timer32_remaining(TIMER_HANDLE handle); +#endif + +/**************************************************************************** + * Name: tiva_timer16_remaining + * + * Description: + * Get the time remaining before a one-shot or periodic 16-bit timer + * expires. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure(). + * + * Returned Value: + * Time remaining until the next timeout interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER16_PERIODIC +/* To be provided */ +#endif + +/**************************************************************************** + * Name: tiva_timer32_absmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 32-bit timer. This function sets the match register + * the the absolute value specified. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * absmatch - The absolute value to write to the timer match register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +static inline void tiva_timer32_absmatch(TIMER_HANDLE handle, + uint32_t absmatch) +{ + tiva_gptm_putreg(handle, TIVA_TIMER_TAMATCHR_OFFSET, absmatch); +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_absmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 16-bit timer. This function sets the match register + * the the absolute value specified. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * absmatch - The value to write to the timer match register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +static inline void tiva_timer16_absmatch(TIMER_HANDLE handle, + uint16_t absmatch, int tmndx) +{ + unsigned int regoffset = + tmndx ? TIVA_TIMER_TBMATCHR_OFFSET : TIVA_TIMER_TAMATCHR_OFFSET; + + tiva_gptm_putreg(handle, regoffset, absmatch); +} + +static inline void tiva_timer16a_absmatch(TIMER_HANDLE handle, uint16_t absmatch) +{ + tiva_gptm_putreg(handle, TIVA_TIMER_TAMATCHR_OFFSET, absmatch); +} + +static inline void tiva_timer16b_absmatch(TIMER_HANDLE handle, uint16_t absmatch) +{ + tiva_gptm_putreg(handle, TIVA_TIMER_TBMATCHR_OFFSET, absmatch); +} +#endif + +/**************************************************************************** + * Name: tiva_rtc_settime + * + * Description: + * Set the 32-bit RTC timer counter. When RTC mode is selected for the + * first time after reset, the counter is loaded with a value of 1. All + * subsequent load values must be written to the concatenated GPTM Timer A + * Interval Load (GPTMTAILR) registers. If the GPTMTnILR register is + * loaded with a new value, the counter begins counting at that value + * and rolls over at the fixed value of 0xffffffff. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * newtime - The new RTC time (seconds) + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_RTC +static inline void tiva_rtc_settime(TIMER_HANDLE handle, uint32_t newtime) +{ + tiva_gptm_putreg(handle, TIVA_TIMER_TAILR_OFFSET, newtime); +} +#endif + +/**************************************************************************** + * Name: tiva_rtc_setalarm + * + * Description: + * Setup to receive an interrupt when the RTC counter equals a match time + * value. This function sets the match register to the current timer + * counter register value PLUS the relative value provided. The relative + * value then is an offset in seconds from the current time. + * + * If an interrupt handler is provided, then the RTC match interrupt will + * be enabled. A single RTC match interrupt will be generated; further + * RTC match interrupts will be disabled. + * + * NOTE: Use of this function is only meaningful for a a 32-bit RTC time. + * NOTE: An interrupt handler address must provided in the configuration. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * delay - A relative time in the future (seconds) + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_RTC +void tiva_rtc_setalarm(TIMER_HANDLE handle, uint32_t delay); +#endif + +/**************************************************************************** + * Name: tiva_timer32_relmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 32-bit timer. This function sets the match register + * to the current timer counter register value PLUS the relative value + * provided. The relative value then is some the offset to some timer + * counter value in the future. + * + * If an interrupt handler is provided, then the match interrupt will also + * be enabled. A single match interrupt will be generated; further match + * interrupts will be disabled. + * + * NOTE: Use of this function is only meaningful for a 32-bit free- + * runnning, periodic timer. + * + * WARNING: For free-running timers, the relative match value should be + * sufficiently far in the future to avoid race conditions. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * relmatch - The value to write to the timer match register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch); +#endif + +/**************************************************************************** + * Name: tiva_timer16_relmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 16-bit timer. This function sets the match register + * to the current timer counter register value PLUS the relative value + * provided. The relative value then is some the offset to some timer + * counter value in the future. + * + * If an interrupt handler is provided, then the match interrupt will also + * be enabled. A single match interrupt will be generated; further match + * interrupts will be disabled. + * + * NOTE: Use of this function is only meaningful for a 16-bit free- + * runnning, periodic timer. + * + * NOTE: The relmatch input is a really a 24-bit value; it is the 16-bit + * match counter match value AND the 8-bit prescaler match value. From + * the caller's point of view the match value is the 24-bit time to match + * driven at the timer input clock frequency. + * + * When counting down in periodic modes, the prescaler contains the + * least-significant bits of the count. When counting up, the prescaler + * holds the most-significant bits of the count. But the caller is + * protected from this complexity. + * + * WARNING: For free-running timers, the relative match value should be + * sufficiently far in the future to avoid race conditions. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * relmatch - The value to write to the timer match register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER16_PERIODIC +void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx); + +# define tiva_timer16a_relmatch(h,r) tiva_timer16_relmatch(h,r,TIMER16A) +# define tiva_timer16b_relmatch(h,r) tiva_timer16_relmatch(h,r,TIMER16B) +#endif + +/**************************************************************************** + * Name: tiva_gptm0_synchronize + * + * Description: + * Trigger timers from GPTM0 output. This is part of the timer + * configuration logic and should be called before timers are enabled. + * + * Input Parameters: + * sync - The value to write to the GPTM0 SYNC register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVER_TIMER0 +static inline void tiva_gptm0_synchronize(uint32_t sync) +{ + putreg32(sync, TIVA_TIMER0_SYNC); +} +#endif + +/**************************************************************************** + * Name: tiva_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * NOTES: + * 1. Only 32-bit periodic timers are supported. + * 2. Timeout interrupts are disabled until tiva_timer32_setinterval() is + * called. + * 3. Match interrupts are disabled until tiva_timer32_relmatch() is + * called. + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * config - 32-bit timer configuration values. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIMER +int tiva_timer_initialize(FAR const char *devpath, + struct tiva_gptm32config_s *config); +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_TIMER_H */ diff --git a/arch/arm/src/tiva/tiva_timerisr.c b/arch/arm/src/tiva/tiva_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..76fd7e96cbc89c90bf0064a683146ed342bdf4f3 --- /dev/null +++ b/arch/arm/src/tiva/tiva_timerisr.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_timerisr.c + * + * Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The timer counts at the rate SYSCLK_FREQUENCY as defined in the board.h + * header file. + */ + +#define SYSTICK_RELOAD ((SYSCLK_FREQUENCY / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify taht the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(TIVA_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(TIVA_IRQ_SYSTICK); +} diff --git a/arch/arm/src/tiva/tiva_timerlib.c b/arch/arm/src/tiva/tiva_timerlib.c new file mode 100644 index 0000000000000000000000000000000000000000..fd6b5805db9d79ae20261d9fcf2c7828772e602c --- /dev/null +++ b/arch/arm/src/tiva/tiva_timerlib.c @@ -0,0 +1,3050 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_timerlib.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "chip/tiva_syscontrol.h" +#include "chip/tiva_timer.h" + +#include "tiva_enableclks.h" +#include "tiva_enablepwr.h" +#include "tiva_periphrdy.h" +#include "tiva_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure retains the fixed, well-known attributes of a GPTM module */ + +struct tiva_gptmattr_s +{ + uintptr_t base; /* Register base address */ + uint16_t irq[2]; /* Timer A/B interrupt numbers */ +#ifdef CONFIG_TIVA_TIMER_32BIT + xcpt_t handler32; /* Handler for 32-bit timer interrupts */ +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + xcpt_t handler16[2]; /* Handlers for 16-bit timer A/B interrupts */ +#endif +}; + +/* This structure represents the state of a GPTM module */ + +struct tiva_gptmstate_s +{ + /* Constant timer attributes and configuration */ + + const struct tiva_gptmattr_s *attr; + const struct tiva_gptmconfig_s *config; + + /* Variable state values */ + + uint32_t clkin; /* Frequency of the input clock */ + uint32_t imr; /* Interrupt mask value. Zero if no interrupts */ + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Register level debug */ + + bool wrlast; /* Last was a write */ + uintptr_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register Access */ + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG +static bool tiva_timer_checkreg(struct tiva_gptmstate_s *priv, bool wr, + uint32_t regval, uintptr_t regaddr); +#endif +static uint32_t tiva_getreg(struct tiva_gptmstate_s *priv, unsigned int offset); +static void tiva_putreg(struct tiva_gptmstate_s *priv, unsigned int offset, + uint32_t regval); + +/* Interrupt handling */ + +#ifdef CONFIG_TIVA_TIMER_32BIT +static int tiva_timer32_interrupt(struct tiva_gptmstate_s *priv); +# ifdef CONFIG_TIVA_TIMER0 +static int tiva_gptm0_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER1 +static int tiva_gptm1_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER2 +static int tiva_gptm2_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER3 +static int tiva_gptm3_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER4 +static int tiva_gptm4_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER5 +static int tiva_gptm5_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER6 +static int tiva_gptm6_interrupt(int irq, FAR void *context); +# endif +# ifdef CONFIG_TIVA_TIMER7 +static int tiva_gptm7_interrupt(int irq, FAR void *context); +#endif +#endif /* CONFIG_TIVA_TIMER_32BIT */ + +#ifdef CONFIG_TIVA_TIMER_16BIT +static int tiva_timer16_interrupt(struct tiva_gptmstate_s *priv, + int tmndx); +#ifdef CONFIG_TIVA_TIMER0 +static int tiva_timer0a_interrupt(int irq, FAR void *context); +static int tiva_timer0b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER1 +static int tiva_timer1a_interrupt(int irq, FAR void *context); +static int tiva_timer1b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER2 +static int tiva_timer2a_interrupt(int irq, FAR void *context); +static int tiva_timer2b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER3 +static int tiva_timer3a_interrupt(int irq, FAR void *context); +static int tiva_timer3b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER4 +static int tiva_timer4a_interrupt(int irq, FAR void *context); +static int tiva_timer4b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER5 +static int tiva_timer5a_interrupt(int irq, FAR void *context); +static int tiva_timer5b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER6 +static int tiva_timer6a_interrupt(int irq, FAR void *context); +static int tiva_timer6b_interrupt(int irq, FAR void *context); +#endif +#ifdef CONFIG_TIVA_TIMER7 +static int tiva_timer7a_interrupt(int irq, FAR void *context); +static int tiva_timer7b_interrupt(int irq, FAR void *context); +#endif +#endif /* CONFIG_TIVA_TIMER_16BIT */ + +/* Timer initialization and configuration */ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer); +#endif /* CONFIG_TIVA_TIMER32_PERIODIC */ +#ifdef CONFIG_TIVA_TIMER16_PERIODIC +static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, int tmndx); +#endif +#ifdef CONFIG_TIVA_TIMER32_RTC +static int tiva_rtc_mode32(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer); +#endif +#ifdef CONFIG_TIVA_TIMER32_EDGECOUNT +static int tiva_input_edgecount_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, int tmndx); +#endif +#ifdef CONFIG_TIVA_TIMER32_TIMECAP +static int tiva_input_time_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, int tmndx); +#endif +#ifdef CONFIG_TIVA_TIMER32_PWM +static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, int tmndx); + +#endif +#ifdef CONFIG_TIVA_TIMER_32BIT +static int tiva_timer32_configure(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer); +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT +static int tiva_timer16_configure(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, int tmndx); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER0 +static const struct tiva_gptmattr_s g_gptm0_attr = +{ + .base = TIVA_TIMER0_BASE, + .irq = { TIVA_IRQ_TIMER0A, TIVA_IRQ_TIMER0B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm0_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer0a_interrupt, tiva_timer0b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm0_state; +#endif + +#ifdef CONFIG_TIVA_TIMER1 +static const struct tiva_gptmattr_s g_gptm1_attr = +{ + .base = TIVA_TIMER1_BASE, + .irq = { TIVA_IRQ_TIMER1A, TIVA_IRQ_TIMER1B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm1_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer1a_interrupt, tiva_timer1b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm1_state; +#endif + +#ifdef CONFIG_TIVA_TIMER2 +static const struct tiva_gptmattr_s g_gptm2_attr = +{ + .base = TIVA_TIMER2_BASE, + .irq = { TIVA_IRQ_TIMER2A, TIVA_IRQ_TIMER2B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm2_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer2a_interrupt, tiva_timer2b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm2_state; +#endif + +#ifdef CONFIG_TIVA_TIMER3 +static const struct tiva_gptmattr_s g_gptm3_attr = +{ + .base = TIVA_TIMER3_BASE, + .irq = { TIVA_IRQ_TIMER3A, TIVA_IRQ_TIMER3B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm3_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer3a_interrupt, tiva_timer3b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm3_state; +#endif + +#ifdef CONFIG_TIVA_TIMER4 +static const struct tiva_gptmattr_s g_gptm4_attr = +{ + .base = TIVA_TIMER4_BASE, + .irq = { TIVA_IRQ_TIMER4A, TIVA_IRQ_TIMER4B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm4_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer4a_interrupt, tiva_timer4b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm4_state; +#endif + +#ifdef CONFIG_TIVA_TIMER5 +static const struct tiva_gptmattr_s g_gptm5_attr = +{ + .base = TIVA_TIMER5_BASE, + .irq = { TIVA_IRQ_TIMER5A, TIVA_IRQ_TIMER5B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm5_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer5a_interrupt, tiva_timer5b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm5_state; +#endif + +#ifdef CONFIG_TIVA_TIMER6 +static const struct tiva_gptmattr_s g_gptm6_attr = +{ + .base = TIVA_TIMER6_BASE, + .irq = { TIVA_IRQ_TIMER6A, TIVA_IRQ_TIMER6B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm6_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer6a_interrupt, tiva_timer6b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm6_state; +#endif + +#ifdef CONFIG_TIVA_TIMER7 +static const struct tiva_gptmattr_s g_gptm7_attr = +{ + .base = TIVA_TIMER7_BASE, + .irq = { TIVA_IRQ_TIMER7A, TIVA_IRQ_TIMER7B }, +#ifdef CONFIG_TIVA_TIMER_32BIT + .handler32 = tiva_gptm7_interrupt, +#endif +#ifdef CONFIG_TIVA_TIMER_16BIT + .handler16 = { tiva_timer7a_interrupt, tiva_timer7b_interrupt }, +#endif +}; + +static struct tiva_gptmstate_s g_gptm7_state; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG +static bool tiva_timer_checkreg(struct tiva_gptmstate_s *priv, bool wr, + uint32_t regval, uintptr_t regaddr) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + regaddr == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: tiva_getreg + * + * Description: + * Read one 32-bit GPTM register + * + ****************************************************************************/ + +static uint32_t tiva_getreg(struct tiva_gptmstate_s *priv, unsigned int offset) +{ + uintptr_t regaddr = priv->attr->base + offset; + uint32_t regval = getreg32(regaddr); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + if (tiva_timer_checkreg(priv, false, regval, regaddr)) + { + lldbg("%08x->%08x\n", regaddr, regval); + } +#endif + + return regval; +} + +/**************************************************************************** + * Name: tiva_putreg + * + * Description: + * Write one 32-bit GPTM register + * + ****************************************************************************/ + +static void tiva_putreg(struct tiva_gptmstate_s *priv, unsigned int offset, + uint32_t regval) +{ + uintptr_t regaddr = priv->attr->base + offset; + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + if (tiva_timer_checkreg(priv, true, regval, regaddr)) + { + lldbg("%08x<-%08x\n", regaddr, regval); + } +#endif + + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: tiva_modifyreg + * + * Description: + * This function permits atomic of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + ****************************************************************************/ + +static void tiva_modifyreg(struct tiva_gptmstate_s *priv, unsigned int offset, + uint32_t clrbits, uint32_t setbits) +{ +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = tiva_getreg(priv, offset); + regval &= ~clrbits; + regval |= setbits; + tiva_putreg(priv, offset, regval); + leave_critical_section(flags); +#else + uintptr_t regaddr = priv->attr->base + offset; + modifyreg32(regaddr, clrbits, setbits); +#endif +} + +/**************************************************************************** + * Name: tiva_timer32_interrupt + * + * Description: + * Common interrupt handler for 32-bit timers + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +static int tiva_timer32_interrupt(struct tiva_gptmstate_s *priv) +{ + const struct tiva_gptm32config_s *config32; + const struct tiva_timer32config_s *timer32; + uint32_t status; + + DEBUGASSERT(priv && priv->attr && priv->config); + + /* Get the set of pending interrupts from the mask interrupt status + * register. + */ + + status = tiva_getreg(priv, TIVA_TIMER_MIS_OFFSET); + DEBUGASSERT(status != 0); + + if (status != 0) + { + tiva_putreg(priv, TIVA_TIMER_ICR_OFFSET, status); + + /* If this was a match (or RTC match) interrupt, then disable further + * match interrupts. + */ + + if ((status & (TIMER_INT_TAM | TIMER_INT_RTC)) != 0) + { + status &= ~(TIMER_INT_TAM | TIMER_INT_RTC); + tiva_putreg(priv, TIVA_TIMER_IMR_OFFSET, priv->imr); + } + + /* Get the timer configuration from the private state structure */ + + config32 = (const struct tiva_gptm32config_s *)priv->config; + timer32 = &config32->config; + + /* Forward the interrupt to the handler. There should always be a non- + * NULL handler in this case. + */ + + DEBUGASSERT(timer32->handler); + if (timer32->handler) + { + timer32->handler((TIMER_HANDLE)priv, timer32->arg, status); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: tiva_gptmN_interrupt, N=0..7 + * + * Description: + * Individual interrupt handlers for each 32-bit timer + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +#ifdef CONFIG_TIVA_TIMER0 +static int tiva_gptm0_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm0_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER1 +static int tiva_gptm1_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm1_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER2 +static int tiva_gptm2_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm2_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER3 +static int tiva_gptm3_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm3_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER4 +static int tiva_gptm4_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm4_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER5 +static int tiva_gptm5_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm5_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER6 +static int tiva_gptm6_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm6_state); +} +#endif + +#ifdef CONFIG_TIVA_TIMER7 +static int tiva_gptm7_interrupt(int irq, FAR void *context) +{ + return tiva_timer32_interrupt(&g_gptm7_state); +} +#endif +#endif + +/**************************************************************************** + * Name: tiva_timer16_interrupt + * + * Description: + * Common interrupt handler for 16-bit timers + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +static int tiva_timer16_interrupt(struct tiva_gptmstate_s *priv, int tmndx) +{ + const struct tiva_gptm16config_s *config16; + const struct tiva_timer16config_s *timer16; + uint32_t intmask; + uint32_t status; + + DEBUGASSERT(priv && priv->attr && priv->config && (unsigned)tmndx < 2); + + /* Read the masked interrupt status, masking out bits only for this timer. */ + + intmask = tmndx ? TIMERB_INTS : TIMERA_INTS; + status = tiva_getreg(priv, TIVA_TIMER_MIS_OFFSET) & intmask; + DEBUGASSERT(status != 0); + + if (status != 0) + { + /* Clear all pending interrupts for this timer */ + + tiva_putreg(priv, TIVA_TIMER_ICR_OFFSET, status); + + /* If this was a match interrupt, then disable further match + * interrupts. + */ + + if ((status & (TIMER_INT_TAM | TIMER_INT_TBM)) != 0) + { + priv->imr &= ~((TIMER_INT_TAM | TIMER_INT_TBM) & intmask); + tiva_putreg(priv, TIVA_TIMER_IMR_OFFSET, priv->imr); + } + + /* Get the timer configuration from the private state structure */ + + config16 = (const struct tiva_gptm16config_s *)priv->config; + timer16 = &config16->config[tmndx]; + + /* Forward the interrupt to the handler. There should always be a + * non-NULL handler in this context. + */ + + DEBUGASSERT(timer16->handler); + if (timer16->handler) + { + timer16->handler((TIMER_HANDLE)priv, timer16->arg, status, tmndx); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: tiva_timerNa_interrupt, tiva_timerNb_interrupt, N=0..7 + * + * Description: + * Individual interrupt handlers for each 16-bit timer + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +#ifdef CONFIG_TIVA_TIMER0 +static int tiva_timer0a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm0_state, TIMER16A); +} + +static int tiva_timer0b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm0_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER1 +static int tiva_timer1a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm1_state, TIMER16A); +} + +static int tiva_timer1b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm1_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER2 +static int tiva_timer2a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm2_state, TIMER16A); +} + +static int tiva_timer2b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm2_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER3 +static int tiva_timer3a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm3_state, TIMER16A); +} + +static int tiva_timer3b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm3_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER4 +static int tiva_timer4a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm4_state, TIMER16A); +} + +static int tiva_timer4b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm4_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER5 +static int tiva_timer5a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm5_state, TIMER16A); +} + +static int tiva_timer5b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm5_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER6 +static int tiva_timer6a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm6_state, TIMER16A); +} + +static int tiva_timer6b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm6_state, TIMER16B); +} +#endif + +#ifdef CONFIG_TIVA_TIMER7 +static int tiva_timer7a_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm7_state, TIMER16A); +} + +static int tiva_timer7b_interrupt(int irq, FAR void *context) +{ + return tiva_timer16_interrupt(&g_gptm7_state, TIMER16B); +} +#endif +#endif + +/**************************************************************************** + * Name: tiva_oneshot_periodic_mode32 + * + * Description: + * Configure a 32-bit timer to operate in one-shot or periodic mode + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +static int tiva_oneshot_periodic_mode32(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer) +{ + uint32_t regval; + + /* The GPTM is configured for One-Shot and Periodic modes by the following + * sequence: + * + * 1. Ensure the timer is disabled (the TAEN bit in the GPTMCTL register + * is cleared) before making any changes. + * + * NOTE: The TAEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. Write the GPTM Configuration Register (GPTMCFG) to select 32-bit + * operation. + */ + + tiva_putreg(priv, TIVA_TIMER_CFG_OFFSET, TIMER_CFG_CFG_32); + + /* 3. Configure the TAMR field in the GPTM Timer n Mode Register + * (GPTMTAMR): + * + * a. Write a value of 0x1 for One-Shot mode. + * b. Write a value of 0x2 for Periodic mode. + * + * When Timer A and TimerB are concatenated, the GPTMTBMR register is + * ignored and GPTMTAMR controls the modes for both Timer A and Timer B + */ + + regval = tiva_getreg(priv, TIVA_TIMER_TAMR_OFFSET); + regval &= ~TIMER_TnMR_TnMR_MASK; + + if (priv->config->mode == TIMER32_MODE_ONESHOT) + { + regval |= TIMER_TnMR_TnMR_ONESHOT; + } + else /* if (priv->config->mode == TIMER32_MODE_PERIODIC) */ + { + regval |= TIMER_TnMR_TnMR_PERIODIC; + } + + tiva_putreg(priv, TIVA_TIMER_TAMR_OFFSET, regval); + + /* 4. Optionally configure the TASNAPS, TAWOT, TAMINTD, and TACDIR bits in + * the GPTMTAMR register to select whether to capture the value of the + * free-running timer at time-out, use an external trigger to start + * counting, configure an additional trigger or interrupt, and count up + * or down. + * + * TASNAPS - GPTM Timer A Snap-Shot Mode + * 0: Snap-shot mode is disabled (default) + * 1: If the 32-bit timeris configured in the periodic mode, + * the actual free-running, capture or snapshot value of + * the timer is loaded at the time-out event/capture or + * snapshot event into the concatenated GPTM Timer A + * (GPTMTAR) register. + * TAWOT - GPTM Timer A Wait-on-Trigger + * 0: The 32-bit timer begins counting as soon as it is + * enabled (default). + * 1: If the 32-bit timer is enabled, it does not begin + * counting until it receives a trigger from the timer + * in the previous position in the daisy chain. + * TAINTD - One-shot/Periodic Interrupt Disable + * 0: Time-out interrupt functions as normal. + * 1: Time-out interrupt are disabled (default). + * TACDIR - GPTM Timer A Count Direction + * 0: The timer counts down (default). + * 1: The timer counts up. When counting up, the timer + * starts from a value of 0. + * + * NOTE: one-shot/periodic timeout interrupts remain disabled until + * tiva_timer32_setinterval is called. + */ + + /* Setup defaults */ + + regval &= (TIMER_TnMR_TnCDIR | TIMER_TnMR_TnWOT | TIMER_TnMR_TnCDIR); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + regval |= TIMER_TnMR_TnCINTD; +#endif + + /* Enable snapshot mode? + * + * In periodic, snap-shot mode (TnMR field is 0x2 and the TnSNAPS bit is + * set in the GPTMTnMR register), the value of the timer at the time-out + * event is loaded into the GPTMTnR register and the value of the + * prescaler is loaded into the GPTMTnPS register. The free-running + * counter value is shown in the GPTMTnV register. In this manner, + * software can determine the time elapsed from the interrupt assertion + * to the ISR entry by examining the snapshot values and the current value + * of the free-running timer. Snapshot mode is not available when the + * timer is configured in one-shot mode. + * + * TODO: Not implemented + */ +#warning Missing Logic + + /* Enable wait-on-trigger? + * + * TODO: Not implemented + */ +#warning Missing Logic + + /* Enable count down? */ + + if (TIMER_ISCOUNTUP(timer)) + { + regval |= TIMER_TnMR_TnCDIR_UP; + } + + tiva_putreg(priv, TIVA_TIMER_TAMR_OFFSET, regval); + + /* Enable and configure ADC trigger outputs */ + if (TIMER_ISADCTIMEOUT(timer) || TIMER_ISADCMATCH(timer)) + { +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable timeout triggers now (match triggers will be + * enabled when the first match value is set). + */ + + if (TIMER_ISADCTIMEOUT(timer)) + { + tiva_putreg(priv, TIVA_TIMER_ADCEV_OFFSET, TIMER_ADCEV_TATOADCEN); + } +#endif + + /* Enable ADC trigger outputs by setting the TAOTE bit in the + * control register. + */ + + regval = tiva_getreg(priv, TIVA_TIMER_CTL_OFFSET); + regval |= TIMER_CTL_TAOTE; + tiva_putreg(priv, TIVA_TIMER_CTL_OFFSET, regval); + } + + /* In addition, if using CCP pins, the TCACT field can be programmed to + * configure the compare action. + */ +#warning Missing Logic + + /* TODO: Enable and configure uDMA trigger outputs */ + + /* 5. Load the start value into the GPTM Timer n Interval Load Register + * (GPTMTAILR). + * + * When a GPTM is configured to one of the 32-bit modes, GPTMTAILR + * appears as a 32-bit register; the upper 16-bits correspond to bits + * 15:0 of the GPTM Timer B Interval Load (GPTMTBILR) register. + * Writes to GPTMTBILR are ignored. + * + * NOTE: The default is a free-running timer. The timer interval + * reload register is clear here. It can be set to any value + * desired by calling tiva_timer32_setinterval(). + */ + + tiva_putreg(priv, TIVA_TIMER_TAILR_OFFSET, 0); + + /* Preload the timer counter register by setting the timer value register. + * The timer value will be copied to the timer counter register on the + * next clock cycle. + */ + + if (TIMER_ISCOUNTUP(timer)) + { + /* Count up from zero */ + + tiva_putreg(priv, TIVA_TIMER_TAV_OFFSET, 0); + } + else + { + /* Count down from the timer reload value */ + + tiva_putreg(priv, TIVA_TIMER_TAV_OFFSET, regval); + } + + /* 6. If interrupts are required, set the appropriate bits in the GPTM + * Interrupt Mask Register (GPTMIMR). + * + * NOTE: Interrupts are still disabled at the NVIC. Interrupts will + * be enabled at the NVIC after the timer is started. + */ + + tiva_putreg(priv, TIVA_TIMER_IMR_OFFSET, priv->imr); + + /* 7. Set the TAEN bit in the GPTMCTL register to enable the timer and + * start counting. + * 8. Poll the GPTMRIS register or wait for the interrupt to be generated + * (if enabled). In both cases, the status flags are cleared by writing + * a 1 to the appropriate bit of the GPTM Interrupt Clear Register + * (GPTMICR). + * + * NOTE: This timer is not started until tiva_gptm_enable() is called. + */ + + return OK; +} +#endif + +/**************************************************************************** + * Name: tiva_oneshot_periodic_mode16 + * + * Description: + * Configure 16-bit timer A/B to operate in one-short or periodic mode + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER16_PERIODIC +static int tiva_oneshot_periodic_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, + int tmndx) +{ + unsigned int regoffset; + uint32_t regval; + + /* The GPTM is configured for One-Shot and Periodic modes by the following + * sequence: + * + * 1. Ensure the timer is disabled (the TnEN bit in the GPTMCTL register + * is cleared) before making any changes. + * + * NOTE: The TnEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. Write the GPTM Configuration Register (GPTMCFG) to select 16-bit + * operation. + * + * NOTE: 16-bit mode of operation was already selected in + * tiva_gptm_configure() before this function was called. + * + * 3. Configure the TnMR field in the GPTM Timer n Mode Register + * (GPTMTnMR): + * a. Write a value of 0x1 for One-Shot mode. + * b. Write a value of 0x2 for Periodic mode. + */ + + regoffset = tmndx ? TIVA_TIMER_TBMR_OFFSET : TIVA_TIMER_TAMR_OFFSET; + regval = tiva_getreg(priv, regoffset); + regval &= ~TIMER_TnMR_TnMR_MASK; + + if (timer->mode == TIMER16_MODE_ONESHOT) + { + regval |= TIMER_TnMR_TnMR_ONESHOT; + } + else /* if (timer->mode == TIMER16_MODE_PERIODIC) */ + { + regval |= TIMER_TnMR_TnMR_PERIODIC; + } + + tiva_putreg(priv, regoffset, regval); + + /* 4. Optionally configure the TnSNAPS, TnWOT, TnMINTD, and TnCDIR bits in + * the GPTMTnMR register to select whether to capture the value of the + * free-running timer at time-out, use an external trigger to start + * counting, configure an additional trigger or interrupt, and count up + * or down. In addition, if using CCP pins, the TCACT field can be + * programmed to configure the compare action. + * + * TnSNAPS - GPTM Timer A/B Snap-Shot Mode + * 0: Snap-shot mode is disabled (default) + * 1: If the 16-bit timer is configured in the periodic mode, + * the actual free-running, capture or snapshot value of + * the timer is loaded at the time-out event/capture or + * snapshot event into the GPTM Timer A/B (GPTMTnR) + * register. If the timer prescaler is used, the prescaler + * snapshot is loaded into the GPTM Timer A/B (GPTMTnPR). + * TnWOT - GPTM Timer A/B Wait-on-Trigger + * 0: The 16-bit begins counting as soon as it is enabled (default). + * 1: If the 16-bit timer is enabled, it does not begin counting + * until it receives a trigger from the timer in the + * previous position in the daisy chain. + * TnINTD - One-shot/Periodic Interrupt Disable + * 0: Time-out interrupt functions as normal. + * 1: Time-out interrupt are disabled (default). + * TnCDIR - GPTM Timer A/B Count Direction + * 0: The timer counts down (default). + * 1: The timer counts up. When counting up, the timer + * starts from a value of 0. + * + * NOTE: one-shot/periodic timeout interrupts remain disabled until + * tiva_timer32_setinterval is called. + */ + + /* Setup defaults */ + + regval &= (TIMER_TnMR_TnCDIR | TIMER_TnMR_TnWOT | TIMER_TnMR_TnCDIR); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + regval |= TIMER_TnMR_TnCINTD; +#endif + + /* Enable snapshot mode? + * + * In periodic, snap-shot mode (TnMR field is 0x2 and the TnSNAPS bit is + * set in the GPTMTnMR register), the value of the timer at the time-out + * event is loaded into the GPTMTnR register and the value of the + * prescaler is loaded into the GPTMTnPS register. The free-running + * counter value is shown in the GPTMTnV register. In this manner, + * software can determine the time elapsed from the interrupt assertion + * to the ISR entry by examining the snapshot values and the current value + * of the free-running timer. Snapshot mode is not available when the + * timer is configured in one-shot mode. + * + * TODO: Not implemented + */ +#warning Missing Logic + + /* Enable wait-on-trigger? + * + * TODO: Not implemented + */ +#warning Missing Logic + + /* Enable count down? */ + + if (TIMER_ISCOUNTUP(timer)) + { + regval |= TIMER_TnMR_TnCDIR_UP; + } + + tiva_putreg(priv, regoffset, regval); + + /* Enable and configure ADC trigger outputs */ + + if (TIMER_ISADCTIMEOUT(timer) || TIMER_ISADCMATCH(timer)) + { + /* Enable ADC trigger outputs by setting the TnOTE bit in the + * control register. + */ + + regval = tiva_getreg(priv, TIVA_TIMER_CTL_OFFSET); + regval |= tmndx ? TIMER_CTL_TBOTE : TIMER_CTL_TAOTE; + tiva_putreg(priv, TIVA_TIMER_CTL_OFFSET, regval); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable timeout triggers now (match triggers will be + * enabled when the first match value is set). + */ + + if (TIMER_ISADCTIMEOUT(timer)) + { + regval = tmndx ? TIMER_ADCEV_TBTOADCEN : TIMER_ADCEV_TATOADCEN; + tiva_putreg(priv, TIVA_TIMER_ADCEV_OFFSET, regval); + } +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + } + + /* TODO: Enable and configure uDMA trigger outputs */ + + /* In addition, if using CCP pins, the TCACT field can be programmed to + * configure the compare action. + */ +#warning Missing Logic + + /* 5. Load the start value into the GPTM Timer n Interval Load Register + * (GPTMTnILR). + * + * NOTE: The default is a free-running timer. The timer interval + * reload and prescale registers are cleared here. They can be set to + * any value desired by calling tiva_timer32_setinterval(). + */ + + regoffset = tmndx ? TIVA_TIMER_TBPR_OFFSET : TIVA_TIMER_TAPR_OFFSET; + tiva_putreg(priv, regoffset, 0); + + regoffset = tmndx ? TIVA_TIMER_TBILR_OFFSET : TIVA_TIMER_TAILR_OFFSET; + tiva_putreg(priv, regoffset, 0); + + /* Preload the timer counter register by setting the timer value register. + * The timer value will be copied to the timer counter register on the + * next clock cycle. + */ + + regoffset = tmndx ? TIVA_TIMER_TBV_OFFSET : TIVA_TIMER_TAV_OFFSET; + if (TIMER_ISCOUNTUP(timer)) + { + /* Count up from zero */ + + tiva_putreg(priv, regoffset, 0); + } + else + { + /* Count down from the timer reload value */ + + tiva_putreg(priv, regoffset, regval); + } + + /* 6. If interrupts are required, set the appropriate bits in the GPTM + * Interrupt Mask Register (GPTMIMR). + * + * NOTE: Interrupts are still disabled at the NVIC. Interrupts will + * be enabled at the NVIC after the timer is started. + */ + + tiva_putreg(priv, TIVA_TIMER_IMR_OFFSET, priv->imr); + + /* 7. Set the TnEN bit in the GPTMCTL register to enable the timer and + * start counting. + * 8. Poll the GPTMRIS register or wait for the interrupt to be generated + * (if enabled). In both cases, the status flags are cleared by writing + * a 1 to the appropriate bit of the GPTM Interrupt Clear Register + * (GPTMICR). + * + * NOTE: This timer is not started until tiva_gptm_enable() is called. + */ + + return OK; +} +#endif + +/**************************************************************************** + * Name: tiva_rtc_mode32 + * + * Description: + * Configure a 32-bit timer to operate in RTC mode + * + * The input clock on a CCP0 input is required to be 32.768 KHz in RTC + * mode. The clock signal is then divided down to a 1-Hz rate and is + * passed along to the input of the counter. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_RTC +static int tiva_rtc_mode32(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer) +{ + uint32_t regval; + + /* To use the RTC mode, the timer must have a 32.768-KHz input signal on + * an even CCP input. To enable the RTC feature, follow these steps: + * + * 1. Ensure the timer is disabled (the TAEN bit is cleared) before making + * any changes. + * + * NOTE: The TAEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. If the timer has been operating in a different mode prior to this, + * clear any residual set bits in the GPTM Timer n Mode (GPTMTnMR) + * register before reconfiguring. + * + * NOTE: The TAMR and TBMR registers were cleared when the timer + * was reset prior to calling this function. + * + * 3. Write the GPTM Configuration Register (GPTMCFG) with a to select + * the 32-bit RTC mode. + */ + + tiva_putreg(priv, TIVA_TIMER_CFG_OFFSET, TIMER_CFG_CFG_RTC); + + /* 4. Write the match value to the GPTM Timer n Match Register + * (GPTMTnMATCHR). + * + * NOTE: The match register is not set until tiva_rtc_setalarm() is + * called. + * + * 5. Set/clear the RTCEN and TnSTALL bit in the GPTM Control Register + * (GPTMCTL) as needed. + * + * RTCEN - 1: RTC counting continues while the processor is + * halted by the debugger + * TASTALL - 1: Timer A freezes counting while the processor is + * halted by the debugger. + */ + + regval = tiva_getreg(priv, TIVA_TIMER_CTL_OFFSET); +#ifdef CONFIG_DEBUG_SYMBOLS + regval |= (TIMER_CTL_RTCEN | TIMER_CTL_TASTALL); +#else + regval &= ~(TIMER_CTL_RTCEN | TIMER_CTL_TASTALL); +#endif + tiva_putreg(priv, TIVA_TIMER_CTL_OFFSET, regval); + + /* 6. If interrupts are required, set the RTCIM bit in the GPTM Interrupt + * Mask Register (GPTMIMR). + * + * NOTE: RTC interrupts are not enabled until tiva_rtc_setalarm() is + * called. + * + * 7. Set the TAEN bit in the GPTMCTL register to enable the timer and + * start counting. + * + * When the timer count equals the value in the GPTMTnMATCHR register, + * the GPTM asserts the RTCRIS bit in the GPTMRIS register and continues + * counting until Timer A is disabled or a hardware reset. The interrupt + * is cleared by writing the RTCCINT bit in the GPTMICR register. Note + * that if the GPTMTnILR register is loaded with a new value, the timer + * begins counting at this new value and continues until it reaches + * 0xFFFF.FFFF, at which point it rolls over. + * + * NOTE: The RTC timer will not be enabled until tiva_gptm_enable() is + * called. + */ + + return OK; +} +#endif + +/**************************************************************************** + * Name: tiva_input_edgecount_mode16 + * + * Description: + * Configure 16-bit timer A/B to operate in Input Edge-Count mode + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_EDGECOUNT +static int tiva_input_edgecount_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, + int tmndx) +{ + /* A timer is configured to Input Edge-Count mode by the following sequence: + * + * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making + * any changes. + * + * NOTE: The TnEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. Write the GPTM Configuration Register (GPTMCFG) to select 16-bit + * operation. + * + * NOTE: 16-bit mode of operation was already selected in + * tiva_gptm_configure() before this function was called. + * + * 3. In the GPTM Timer Mode (GPTMTnMR) register, write the TnCMR field to + * 0x0 and the TnMR field to 0x3. + */ + + /* 4. Configure the type of event(s) that the timer captures by writing + * the TnEVENT field of the GPTM Control (GPTMCTL) register. + */ + + /* 5. Program registers according to count direction: + * + * - In down-count mode, the GPTMTnMATCHR and GPTMTnPMR registers are + * configured so that the difference between the value in the GPTMTnILR + * and GPTMTnPR registers and the GPTMTnMATCHR and GPTMTnPMR registers + * equals the number of edge events that must be counted. + * + * - In up-count mode, the timer counts from 0x0 to the value in the + * GPTMTnMATCHR and GPTMTnPMR registers. Note that when executing an + * up-count, the value of the GPTMTnPR and GPTMTnILR must be greater + * than the value of GPTMTnPMR and GPTMTnMATCHR. + */ + + /* 6. If interrupts are required, set the CnMIM bit in the GPTM Interrupt + * Mask (GPTMIMR) register. + */ +#warning Missing Logic + + /* 7. Set the TnEN bit in the GPTMCTL register to enable the timer and + * begin waiting for edge events. + * 8. Poll the CnMRIS bit in the GPTMRIS register or wait for the + * interrupt to be generated (if enabled). In both cases, the status + * flags are cleared by writing a 1 to the CnMCINT bit of the GPTM + * Interrupt Clear (GPTMICR) register. + * + * When counting down in Input Edge-Count Mode, the timer stops after the + * programmed number of edge events has been detected. To re-enable the + * timer, ensure that the TnEN bit is cleared and repeat steps 4 through 8. + * + * NOTE: This timer is not started until tiva_gptm_enable() is called. + */ + + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: tiva_input_time_mode16 + * + * Description: + * Configure 16-bit timer A/B to operate in Input Time mode + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_TIMECAP +static int tiva_input_time_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, + int tmndx) +{ + /* A timer is configured to Input Edge Time mode by the following sequence: + * + * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making + * any changes. + * + * NOTE: The TnEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. Write the GPTM Configuration Register (GPTMCFG) to select 16-bit + * operation. + * + * NOTE: 16-bit mode of operation was already selected in + * tiva_gptm_configure() before this function was called. + * + * 3. In the GPTM Timer Mode (GPTMTnMR) register, write the TnCMR field to + * 0x1 and the TnMR field to 0x3 and select a count direction by + * programming the TnCDIR bit. + */ + + /* 4. Configure the type of event that the timer captures by writing the + * TnEVENT field of the GPTM Control (GPTMCTL) register. + */ + + /* 5. If a prescaler is to be used, write the prescale value to the GPTM + * Timer n Prescale Register (GPTMTnPR). + */ + + /* 6. Load the timer start value into the GPTM Timer n Interval Load + * (GPTMTnILR) register. + * + * REVISIT: When the ALTCLK bit is set in the GPTMCC register to enable + * using the alternate clock source, the synchronization imposes + * restrictions on the starting count value (down-count), terminal value + * (up-count) and the match value. This restriction applies to all modes + * of operation. Each event must be spaced by 4 Timer (ALTCLK) clock + * periods + 2 system clock periods. If some events do not meet this + * requirement, then it is possible that the timer block may need to be + * reset for correct functionality to be restored. + * + * Example: ALTCLK= TPIOSC = 62.5ns (16Mhz Trimmed) + * Thclk = 1us (1Mhz) + * 4*62.5ns + 2*1us = 2.25us 2.25us/62.5ns = 36 or 0x23 + * + * The minimum values for the periodic or one-shot with a match + * interrupt enabled are: GPTMTAMATCHR = 0x23 GPTMTAILR = 0x46" + */ + + /* 7. If interrupts are required, set the CnEIM bit in the GPTM Interrupt + * Mask (GPTMIMR) register. + */ +#warning Missing Logic + + /* 8. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable the + * timer and start counting. + * 9. Poll the CnERIS bit in the GPTMRIS register or wait for the interrupt + * to be generated (if enabled). In both cases, the status flags are + * cleared by writing a 1 to the CnECINT bit of the GPTM Interrupt + * Clear (GPTMICR) register. The time at which the event happened can + * be obtained by reading the GPTM Timer n (GPTMTnR) register. + * + * In Input Edge Timing mode, the timer continues running after an edge + * event has been detected, but the timer interval can be changed at any + * time by writing the GPTMTnILR register and clearing the TnILD bit in + * the GPTMTnMR register. The change takes effect at the next cycle after + * the write. + * + * NOTE: This timer is not started until tiva_gptm_enable() is called. + */ + + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: tiva_pwm_mode16 + * + * Description: + * Configure 16-bit timer A/B to operate in PWM mode + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PWM +static int tiva_pwm_mode16(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, + int tmndx) +{ + /* A timer is configured to PWM mode using the following sequence: + * + * 1. Ensure the timer is disabled (the TnEN bit is cleared) before making + * any changes. + * + * NOTE: The TnEN bit was cleared when the timer was reset prior to + * calling this function. + * + * 2. Write the GPTM Configuration Register (GPTMCFG) to select 16-bit + * operation. + * + * NOTE: 16-bit mode of operation was already selected in + * tiva_gptm_configure() before this function was called. + * + * 3. In the GPTM Timer Mode (GPTMTnMR) register, set the TnAMS bit to + * 0x1, the TnCMR bit to 0x0, and the TnMR field to 0x2. + */ + + /* 4. Configure the output state of the PWM signal (whether or not it is + * inverted) in the TnPWML field of the GPTM Control (GPTMCTL) register. + */ + + /* 5. If a prescaler is to be used, write the prescale value to the GPTM + * Timer n Prescale Register (GPTMTnPR). + */ + + /* 6. If PWM interrupts are used, configure the interrupt condition in the + * TnEVENT field in the GPTMCTL register and enable the interrupts by + * setting the TnPWMIE bit in the GPTMTnMR register. Note that edge + * detect interrupt behavior is reversed when the PWM output is + * inverted. + */ + + /* 7. Load the timer start value into the GPTM Timer n Interval Load + * (GPTMTnILR) register. + * + * REVISIT: When the ALTCLK bit is set in the GPTMCC register to enable + * using the alternate clock source, the synchronization imposes + * restrictions on the starting count value (down-count), terminal value + * (up-count) and the match value. This restriction applies to all modes + * of operation. Each event must be spaced by 4 Timer (ALTCLK) clock + * periods + 2 system clock periods. If some events do not meet this + * requirement, then it is possible that the timer block may need to be + * reset for correct functionality to be restored. + * + * Example: ALTCLK= TPIOSC = 62.5ns (16Mhz Trimmed) + * Thclk = 1us (1Mhz) + * 4*62.5ns + 2*1us = 2.25us 2.25us/62.5ns = 36 or 0x23 + * + * The minimum values for the periodic or one-shot with a match + * interrupt enabled are: GPTMTAMATCHR = 0x23 GPTMTAILR = 0x46" + */ + + /* 8. Load the GPTM Timer n Match (GPTMTnMATCHR) register with the match + * value. + */ +#warning Missing Logic + + /* 9. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable + * the timer and begin generation of the output PWM signal. + * + * In PWM Time mode, the timer continues running after the PWM signal has + * been generated. The PWM period can be adjusted at any time by writing + * the GPTMTnILR register, and the change takes effect at the next cycle + * after the write. + * + * NOTE: This timer is not started until tiva_gptm_enable() is called. + */ + + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: tiva_timer32_configure + * + * Description: + * Configure the 32-bit timer to operate in the provided mode. + * + ****************************************************************************/ +#ifdef CONFIG_TIVA_TIMER_32BIT +static int tiva_timer32_configure(struct tiva_gptmstate_s *priv, + const struct tiva_timer32config_s *timer) +{ + switch (priv->config->mode) + { +#ifdef CONFIG_TIVA_TIMER32_PERIODIC + case TIMER32_MODE_ONESHOT: /* 32-bit programmable one-shot timer */ + case TIMER32_MODE_PERIODIC: /* 32-bit programmable periodic timer */ + return tiva_oneshot_periodic_mode32(priv, timer); +#endif /* CONFIG_TIVA_TIMER32_PERIODIC */ + +#ifdef CONFIG_TIVA_TIMER32_RTC + case TIMER32_MODE_RTC: /* 32-bit RTC with external 32.768-KHz + * input */ + return tiva_rtc_mode32(priv, timer); +#endif + + default: + return -EINVAL; + } +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_configure + * + * Description: + * Configure 16-bit timer A or B to operate in the provided mode. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +static int tiva_timer16_configure(struct tiva_gptmstate_s *priv, + const struct tiva_timer16config_s *timer, + int tmndx) +{ + /* Configure the timer per the selected mode */ + + switch (timer->mode) + { + case TIMER16_MODE_NONE: + return OK; + +#ifdef CONFIG_TIVA_TIMER16_PERIODIC + case TIMER16_MODE_ONESHOT: /* 16-bit programmable one-shot timer */ + case TIMER16_MODE_PERIODIC: /* 16-bit programmable periodic timer */ + return tiva_oneshot_periodic_mode16(priv, timer, tmndx); +#endif + +#ifdef CONFIG_TIVA_TIMER32_EDGECOUNT + case TIMER16_MODE_COUNT_CAPTURE: /* 16-bit input-edge count-capture + * mode w/8-bit prescaler */ + return tiva_input_edgecount_mode16(priv, timer, tmndx); +#endif + +#ifdef CONFIG_TIVA_TIMER32_TIMECAP + case TIMER16_MODE_TIME_CAPTURE: /* 16-bit input-edge time-capture + * mode w/8-bit prescaler */ + return tiva_input_time_mode16(priv, timer, tmndx); +#endif + +#ifdef CONFIG_TIVA_TIMER32_PWM + case TIMER16_MODE_PWM: /* 16-bit PWM output mode w/8-bit + * prescaler */ + return tiva_pwm_mode16(priv, timer, tmndx); +#endif + + default: + return -EINVAL; + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_gptm_configure + * + * Description: + * Configure a general purpose timer module to operate in the provided + * modes. + * + * Input Parameters: + * gptm - Describes the configure of the GPTM timer resources + * + * Returned Value: + * On success, a non-NULL handle is returned that can be used with the + * other timer interfaces. NULL is returned on any failure to initialize + * the timer. + * + ****************************************************************************/ + +TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *config) +{ + const struct tiva_gptmattr_s *attr; + struct tiva_gptmstate_s *priv; + uint32_t regval; + int ret; + + DEBUGASSERT(config); + + /* Select the GPTM module. */ + + switch (config->gptm) + { +#ifdef CONFIG_TIVA_TIMER0 + case 0: + /* Enable GPTM0 clocking and power */ + + attr = &g_gptm0_attr; + priv = &g_gptm0_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER1 + case 1: + attr = &g_gptm1_attr; + priv = &g_gptm1_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER2 + case 2: + attr = &g_gptm2_attr; + priv = &g_gptm2_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER3 + case 3: + attr = &g_gptm3_attr; + priv = &g_gptm3_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER4 + case 4: + attr = &g_gptm4_attr; + priv = &g_gptm4_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER5 + case 5: + attr = &g_gptm5_attr; + priv = &g_gptm5_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER6 + case 6: + attr = &g_gptm6_attr; + priv = &g_gptm6_state; + break; +#endif + +#ifdef CONFIG_TIVA_TIMER7 + case 7: + attr = &g_gptm7_attr; + priv = &g_gptm7_state; + break; +#endif + + default: + return (TIMER_HANDLE)NULL; + } + + /* Initialize the state structure */ + + memset(priv, 0, sizeof(struct tiva_gptmstate_s)); + priv->attr = attr; + priv->config = config; + + /* Disable and detach all interrupt handlers */ + + up_disable_irq(attr->irq[TIMER16A]); + up_disable_irq(attr->irq[TIMER16B]); + + (void)irq_detach(attr->irq[TIMER16A]); + (void)irq_detach(attr->irq[TIMER16B]); + + /* Enable power and clocking to the GPTM module + * + * - Enable Power (TM4C129 family only): Applies power (only) to the GPTM + * module. This is not an essential step since enabling clocking + * will also apply power. The only significance is that the GPTM state + * will be retained if the GPTM clocking is subsequently disabled. + * - Enable Clocking (All families): Applies both power and clocking to + * the GPTM module, bringing it a fully functional state. + */ + + tiva_gptm_enableclk(config->gptm); + tiva_gptm_enablepwr(config->gptm); + + /* Wait for the gptm to become ready before modifying its registers */ + + while (!tiva_gptm_periphrdy(config->gptm)); + + /* Reset the timer to be certain that it is in the disabled state */ + + regval = getreg32(TIVA_SYSCON_SRTIMER); + regval |= SYSCON_SRTIMER(config->gptm); + putreg32(regval, TIVA_SYSCON_SRTIMER); + + regval &= ~SYSCON_SRTIMER(config->gptm); + putreg32(regval, TIVA_SYSCON_SRTIMER); + + /* Wait for the reset to complete */ + + while (!tiva_emac_periphrdy()); + up_udelay(250); + + /* Select the alternate timer clock source is so requested. The general + * purpose timer has the capability of being clocked by either the system + * clock or an alternate clock source. By setting the ALTCLK bit in the + * GPTM Clock Configuration (GPTMCC) register, software can selects an + * alternate clock source as programmed in the Alternate Clock + * Configuration (ALTCLKCFG) register in the System Control Module. The + * alternate clock source options available are PIOSC, RTCOSC and LFIOSC. + * + * NOTE: The actual alternate clock source selection is a global property + * and cannot be configure on a timer-by-timer basis here. That selection + * must be done by common logic earlier in the initialization sequence. + * + * NOTE: Both the frequency of the SysClk (SYSCLK_FREQUENCY) and of the + * alternate clock (ALTCLK_FREQUENCY) must be provided in the board.h + * header file. + */ + + if (config->alternate) + { +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable the alternate clock source */ + + regval = tiva_getreg(priv, TIVA_TIMER_CC_OFFSET); + regval |= TIMER_CC_ALTCLK; + tiva_putreg(priv, TIVA_TIMER_CC_OFFSET, regval); + + /* Remember the frequency of the input clock */ + + priv->clkin = ALTCLK_FREQUENCY; +#else + timvdbg("tiva_gptm_configure: Error: alternate clock only available on TM4C129 devices\n"); + return (TIMER_HANDLE)NULL; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + } + else + { + /* Remember the frequency of the input clock */ + + priv->clkin = SYSCLK_FREQUENCY; + } + + /* Then [re-]configure the timer into the new configuration */ + + if (config->mode != TIMER16_MODE) + { +#ifdef CONFIG_TIVA_TIMER_32BIT + const struct tiva_gptm32config_s *config32 = + (const struct tiva_gptm32config_s *)config; + + /* Attach the 32-bit timer interrupt handler (but do not yet enable + * the interrupt). + */ + + ret = irq_attach(attr->irq[TIMER32], attr->handler32); + if (ret == OK) + { + /* Configure the 32-bit timer */ + + ret = tiva_timer32_configure(priv, &config32->config); + } +#else + return (TIMER_HANDLE)NULL; +#endif + } + else + { +#ifdef CONFIG_TIVA_TIMER_16BIT + const struct tiva_gptm16config_s *config16 = + (const struct tiva_gptm16config_s *)config; + + /* Attach the 16-bit timer interrupt handlers (but do not yet enable + * the interrupts). + */ + + ret = irq_attach(attr->irq[TIMER16A], attr->handler16[TIMER16A]); + if (ret == OK) + { + ret = irq_attach(attr->irq[TIMER16B], attr->handler16[TIMER16B]); + } + + if (ret == OK) + { + /* Write the GPTM Configuration Register (GPTMCFG) to select 16- + * bit operation. + */ + + tiva_putreg(priv, TIVA_TIMER_CFG_OFFSET, TIMER_CFG_CFG_16); + + /* Configure 16-bit timer A */ + + ret = tiva_timer16_configure(priv, &config16->config[TIMER16A], + TIMER16A); + } + + /* Configure 16-bit timer B */ + + if (ret == OK) + { + ret = tiva_timer16_configure(priv, &config16->config[TIMER16B], + TIMER16B); + } +#else + return (TIMER_HANDLE)NULL; +#endif + } + + /* Return the timer handler if successfully configured */ + + return ret < 0 ? (TIMER_HANDLE)NULL : (TIMER_HANDLE)priv; +} + +/**************************************************************************** + * Name: tiva_gptm_release + * + * Description: + * Release resources held by the timer instance. After this function is + * called, the timer handle is invalid and must not be used further. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_release(TIMER_HANDLE handle) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptmconfig_s *config; + const struct tiva_gptmattr_s *attr; + uint32_t regval; + + DEBUGASSERT(priv && priv->attr && priv->config); + config = priv->config; + attr = priv->attr; + + /* Disable and detach interrupt handlers */ + + up_disable_irq(attr->irq[TIMER16A]); + up_disable_irq(attr->irq[TIMER16B]); + + (void)irq_detach(attr->irq[TIMER16A]); + (void)irq_detach(attr->irq[TIMER16B]); + + /* Reset the time to be certain that it is in the disabled state */ + + regval = getreg32(TIVA_SYSCON_SRTIMER); + regval |= SYSCON_SRTIMER(config->gptm); + putreg32(regval, TIVA_SYSCON_SRTIMER); + + regval &= ~SYSCON_SRTIMER(config->gptm); + putreg32(regval, TIVA_SYSCON_SRTIMER); + + /* Wait for the reset to complete */ + + while (!tiva_emac_periphrdy()); + up_udelay(250); + + /* Disable power and clocking to the GPTM module */ + + tiva_gptm_disableclk(config->gptm); + tiva_gptm_disablepwr(config->gptm); + + /* Un-initialize the state structure */ + + memset(priv, 0, sizeof(struct tiva_gptmstate_s)); +} + +/**************************************************************************** + * Name: tiva_gptm_putreg + * + * Description: + * This function permits setting of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * value - The value to write to the timer register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_putreg(TIMER_HANDLE handle, unsigned int offset, uint32_t value) +{ + DEBUGASSERT(handle); + tiva_putreg((struct tiva_gptmstate_s *)handle, offset, value); +} + +/**************************************************************************** + * Name: tiva_gptm_getreg + * + * Description: + * This function permits reading of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * + * Returned Value: + * The 32-bit value read at the provided offset into the timer register base + * address. + * + ****************************************************************************/ + +uint32_t tiva_gptm_getreg(TIMER_HANDLE handle, unsigned int offset) +{ + DEBUGASSERT(handle); + return tiva_getreg((struct tiva_gptmstate_s *)handle, offset); +} + +/**************************************************************************** + * Name: tiva_gptm_modifyreg + * + * Description: + * This function permits atomic of any timer register by its offset into + * the timer block. Its primary purpose is to support inline functions + * defined in this header file. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * offset - The offset to the timer register to be written + * clrbits - The collection of bits to be cleared in the register + * setbits - The collection of bits to be set in the register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void tiva_gptm_modifyreg(TIMER_HANDLE handle, unsigned int offset, + uint32_t clrbits, uint32_t setbits) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + + DEBUGASSERT(priv && priv->attr); + tiva_modifyreg(priv, offset, clrbits, setbits); +} + +/**************************************************************************** + * Name: tiva_timer32_start + * + * Description: + * After tiva_gptm_configure() has been called to configure a 32-bit timer, + * this function must be called to start the timer(s). + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_start(TIMER_HANDLE handle) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + + DEBUGASSERT(priv && priv->attr); + + /* Set the TAEN bit in the GPTMCTL register to enable the 32-bit timer and + * start counting + */ + + tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, 0, TIMER_CTL_TAEN); + + /* Enable interrupts at the NVIC if interrupts are expected */ + + if (priv->imr) + { + up_enable_irq(priv->attr->irq[TIMER32]); + } +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_start + * + * Description: + * After tiva_gptm_configure() has been called to configure 16-bit timer(s), + * this function must be called to start one 16-bit timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_start(TIMER_HANDLE handle, int tmndx) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + uint32_t setbits; + uint32_t intmask; + + DEBUGASSERT(priv && priv->attr && (unsigned)tmndx < 2); + + /* Set the TnEN bit in the GPTMCTL register to enable the 16-bit timer and + * start counting + */ + + setbits = tmndx ? TIMER_CTL_TBEN : TIMER_CTL_TAEN; + tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, 0, setbits); + + /* Enable interrupts at the NVIC if interrupts are expected */ + + intmask = tmndx ? TIMERB_INTS : TIMERA_INTS; + if ((priv->imr & intmask) != 0) + { + up_enable_irq(priv->attr->irq[tmndx]); + } +} +#endif + +/**************************************************************************** + * Name: tiva_timer32_stop + * + * Description: + * After tiva_timer32_start() has been called to start a 32-bit timer, + * this function may be called to stop the timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_stop(TIMER_HANDLE handle) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + + DEBUGASSERT(priv && priv->attr); + + /* Disable interrupts at the NVIC */ + + up_disable_irq(priv->attr->irq[TIMER32]); + + /* Clear the TAEN bit in the GPTMCTL register to disable the 16-bit timer */ + + tiva_modifyreg(priv, TIVA_TIMER_CTL_OFFSET, TIMER_CTL_TAEN, 0); +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_stop + * + * Description: + * After tiva_timer32_start() has been called to start a 16-bit timer, + * this function may be called to stop the timer. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_stop(TIMER_HANDLE handle, int tmndx) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + uint32_t clrbits; + + DEBUGASSERT(priv && priv->attr && (unsigned)tmndx < 2); + + /* Disable interrupts at the NVIC */ + + up_disable_irq(priv->attr->irq[tmndx]); + + /* Clear the TnEN bit in the GPTMCTL register to disable the 16-bit timer */ + + clrbits = tmndx ? TIMER_CTL_TBEN : TIMER_CTL_TAEN; + tiva_gptm_modifyreg(handle, TIVA_TIMER_CTL_OFFSET, clrbits, 0); +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_counter + * + * Description: + * Return the current 24-bit counter value of the 16-bit timer. + * + * The timer 24-bit value is the 16-bit counter value AND the 8-bit + * prescaler value. From the caller's point of view the match value is + * the 24-bit timer at the timer input clock frequency. + * + * When counting down in periodic modes, the prescaler contains the + * least-significant bits of the count. When counting up, the prescaler + * holds the most-significant bits of the count. But the caller is + * protected from this complexity. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * The current 24-bit counter value. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +uint32_t tiva_timer16_counter(TIMER_HANDLE handle, int tmndx) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptm16config_s *gptm; + const struct tiva_timer16config_s *config; + irqstate_t flags; + uintptr_t base; + uintptr_t timerr; + uintptr_t prescr; + uint32_t timerv; + uint32_t prescv; + uint32_t checkv; + uint32_t counter; + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode == TIMER16_MODE && (unsigned)tmndx < 2); + + /* Get settings common to both 16-bit timers */ + + gptm = (const struct tiva_gptm16config_s *)priv->config; + base = priv->attr->base; + + /* Get settings unique to one of the 16-bit timers */ + + if (tmndx) + { + /* Get the Timer B configuration */ + + config = &gptm->config[TIMER16B]; + + /* Get Timer B register addresses */ + + timerr = base + TIVA_TIMER_TBR_OFFSET; + prescr = base + TIVA_TIMER_TBPR_OFFSET; + } + else + { + /* Get the Timer A configuration */ + + config = &gptm->config[TIMER16A]; + + /* Get Timer A register addresses */ + + timerr = base + TIVA_TIMER_TAR_OFFSET; + prescr = base + TIVA_TIMER_TAPR_OFFSET; + } + + /* Are we counting up or down? */ + + if (TIMER_ISCOUNTUP(config)) + { + /* We are counting up. The prescaler holds the most-significant bits of + * the count. Sample these registers until we are assured that there + * is no roll-over from the counter to the prescaler register. + */ + + do + { + flags = enter_critical_section(); + checkv = getreg32(prescr); + timerv = getreg32(timerr); + prescv = getreg32(prescr); + leave_critical_section(flags); + } + while (checkv != prescv); + + /* Then form the 32-bit counter value with the prescaler as the most + * significant 8-bits. + */ + + counter = (prescv & 0xff) << 16 | (timerv & 0xffff); + } + else + { + /* We are counting down. The prescaler contains the least-significant + * bits of the count. Sample these registers until we are assured that + * there is no roll-over from the counter to the counter register. + */ + + do + { + flags = enter_critical_section(); + checkv = getreg32(timerr); + prescv = getreg32(prescr); + timerv = getreg32(timerr); + leave_critical_section(flags); + } + while (checkv != timerv); + + /* Then form the 32-bit counter value with the counter as the most + * significant 8-bits. + */ + + counter = (timerv & 0xffff) << 8 | (prescv & 0xff); + } + + /* Return the counter value */ + + return counter; +} +#endif + +/**************************************************************************** + * Name: tiva_timer32_setinterval + * + * Description: + * This function may be called at any time to change the timer interval + * load value of a 32-bit timer. + * + * It the timer is configured as a 32-bit one-shot or periodic timer, then + * then function will also enable timeout interrupts. + * + * NOTE: As of this writing, there is no interface to disable the timeout + * interrupts once they have been enabled. + * + * REVISIT: When the ALTCLK bit is set in the GPTMCC register to enable + * using the alternate clock source, the synchronization imposes + * restrictions on the starting count value (down-count), terminal value + * (up-count) and the match value. This restriction applies to all modes + * of operation. Each event must be spaced by 4 Timer (ALTCLK) clock + * periods + 2 system clock periods. If some events do not meet this + * requirement, then it is possible that the timer block may need to be + * reset for correct functionality to be restored. + * + * Example: ALTCLK= TPIOSC = 62.5ns (16Mhz Trimmed) + * Thclk = 1us (1Mhz) + * 4*62.5ns + 2*1us = 2.25us 2.25us/62.5ns = 36 or 0x23 + * + * The minimum values for the periodic or one-shot with a match + * interrupt enabled are: GPTMTAMATCHR = 0x23 GPTMTAILR = 0x46" + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * interval - The value to write to the timer interval load register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_32BIT +void tiva_timer32_setinterval(TIMER_HANDLE handle, uint32_t interval) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptm32config_s *config; + const struct tiva_timer32config_s *timer; + irqstate_t flags; + uintptr_t base; + uintptr_t loadr; + uintptr_t imrr; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uintptr_t moder; + uint32_t modev1; + uint32_t modev2; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + bool toints; + + DEBUGASSERT(priv); + DEBUGASSERT(priv->attr); + DEBUGASSERT(priv->config); + config = (const struct tiva_gptm32config_s *)priv->config; + + DEBUGASSERT(config->cmn.mode != TIMER16_MODE); + timer = &config->config; + + /* Do we need to enable timeout interrupts? Interrupts are only enabled + * if (1) the user has provided a handler, and (2) the timer timer is + * configure as a one-short or periodic timer. + */ + + base = priv->attr->base; + toints = false; + + if (timer->handler && + (config->cmn.mode == TIMER32_MODE_ONESHOT || + config->cmn.mode == TIMER32_MODE_PERIODIC)) + { + toints = true; + } + + loadr = base + TIVA_TIMER_TAILR_OFFSET; + imrr = base + TIVA_TIMER_IMR_OFFSET; + + /* Make the following atomic */ + + flags = enter_critical_section(); + + /* Set the new timeout interval */ + + putreg32(interval, loadr); + + /* Enable/disable timeout interrupts */ + + if (toints) + { +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Clearing the TACINTD bit allows the time-out interrupt to be + * generated as normal + */ + moder = base + TIVA_TIMER_TAMR_OFFSET; + modev1 = getreg32(moder); + modev2 = modev1 & ~TIMER_TnMR_TnCINTD; + putreg32(modev2, moder); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + /* Set the new interrupt mask */ + + priv->imr |= TIMER_INT_TATO; + putreg32(priv->imr, imrr); + } + + leave_critical_section(flags); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Generate low-level debug output outside of the critical section */ + + lldbg("%08x<-%08x\n", loadr, interval); + if (toints) + { +# ifdef CONFIG_ARCH_CHIP_TM4C129 + lldbg("%08x->%08x\n", moder, modev1); + lldbg("%08x<-%08x\n", moder, modev2); +# endif /* CONFIG_ARCH_CHIP_TM4C129 */ + lldbg("%08x<-%08x\n", imrr, priv->imr); + } +#endif +} +#endif + +/**************************************************************************** + * Name: tiva_timer16_setinterval + * + * Description: + * This function may be called at any time to change the timer interval + * load value of a 16-bit timer. + * + * It the timer is configured as a 16-bit one-shot or periodic timer, then + * then function will also enable timeout interrupts. + * + * NOTE: As of this writing, there is no interface to disable the timeout + * interrupts once they have been enabled. + * + * REVISIT: When the ALTCLK bit is set in the GPTMCC register to enable + * using the alternate clock source, the synchronization imposes + * restrictions on the starting count value (down-count), terminal value + * (up-count) and the match value. This restriction applies to all modes + * of operation. Each event must be spaced by 4 Timer (ALTCLK) clock + * periods + 2 system clock periods. If some events do not meet this + * requirement, then it is possible that the timer block may need to be + * reset for correct functionality to be restored. + * + * Example: ALTCLK= TPIOSC = 62.5ns (16Mhz Trimmed) + * Thclk = 1us (1Mhz) + * 4*62.5ns + 2*1us = 2.25us 2.25us/62.5ns = 36 or 0x23 + * + * The minimum values for the periodic or one-shot with a match + * interrupt enabled are: GPTMTAMATCHR = 0x23 GPTMTAILR = 0x46" + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * interval - The value to write to the timer interval load register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER_16BIT +void tiva_timer16_setinterval(TIMER_HANDLE handle, uint16_t interval, int tmndx) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptm16config_s *config; + const struct tiva_timer16config_s *timer; + irqstate_t flags; + uintptr_t base; + uintptr_t loadr; + uintptr_t imrr; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uintptr_t moder; + uint32_t modev1; + uint32_t modev2; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + uint32_t intbit; + bool toints; + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode != TIMER16_MODE); + config = (const struct tiva_gptm16config_s *)priv->config; + timer = &config->config[tmndx]; + + /* Pre-calculate as much as possible outside of the critical section */ + + base = priv->attr->base; + if (tmndx) + { + intbit = TIMER_INT_TBTO; + loadr = base + TIVA_TIMER_TBILR_OFFSET; + } + else + { + intbit = TIMER_INT_TATO; + loadr = base + TIVA_TIMER_TAILR_OFFSET; + } + + imrr = base + TIVA_TIMER_IMR_OFFSET; + + /* Do we need to enable timeout interrupts? Interrupts are only enabled + * if (1) the user has provided a handler, and (2) the timer timer is + * configure as a one-short or periodic timer. + */ + + toints = false; + + if (timer->handler && + (config->cmn.mode == TIMER16_MODE_ONESHOT || + config->cmn.mode == TIMER16_MODE_PERIODIC)) + { + toints = true; + } + + /* Make the following atomic */ + + flags = enter_critical_section(); + + /* Set the new timeout interval */ + + putreg32(interval, loadr); + + /* Enable/disable timeout interrupts */ + + if (toints) + { +#ifdef CONFIG_ARCH_CHIP_TM4C129 + if (tmndx) + { + moder = base + TIVA_TIMER_TBMR_OFFSET; + } + else + { + moder = base + TIVA_TIMER_TAMR_OFFSET; + } + + /* Clearing the TACINTD bit allows the time-out interrupt to be + * generated as normal + */ + + modev1 = getreg32(moder); + modev2 = modev1 & ~TIMER_TnMR_TnCINTD; + putreg32(modev2, moder); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + /* Set the new interrupt mask */ + + priv->imr |= intbit; + putreg32(priv->imr, imrr); + } + + leave_critical_section(flags); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Generate low-level debug output outside of the critical section */ + + lldbg("%08x<-%08x\n", loadr, interval); + if (toints) + { +#ifdef CONFIG_ARCH_CHIP_TM4C129 + lldbg("%08x->%08x\n", moder, modev1); + lldbg("%08x<-%08x\n", moder, modev2); +#endif + lldbg("%08x<-%08x\n", imrr, priv->imr); + } +#endif +} +#endif + +/**************************************************************************** + * Name: tiva_timer32_remaining + * + * Description: + * Get the time remaining before a one-shot or periodic 32-bit timer + * expires. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure(). + * + * Returned Value: + * Time remaining until the next timeout interrupt. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +uint32_t tiva_timer32_remaining(TIMER_HANDLE handle) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptm32config_s *config; + irqstate_t flags; + uint32_t counter; + uint32_t status; + uint32_t interval; + uint32_t remaining; + + timvdbg("Entry\n"); + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode != TIMER16_MODE); + + config = (const struct tiva_gptm32config_s *)priv->config; + DEBUGASSERT(config->cmn.mode == TIMER32_MODE_ONESHOT || + config->cmn.mode == TIMER32_MODE_PERIODIC); + + /* These values can be modified if a timer interrupt were to occur. Best + * to do this is a critical section. + */ + + flags = enter_critical_section(); + + /* Get the time remaining until the timer expires (in clock ticks). + * Since we have selected a count-up timer timer and the interval will + * expire when the count-up timer equals the timeout value, the + * difference between the current count value and the timeout is the + * time remaining. + * + * There is a race condition here. What if the timer expires and + * counter rolls over between the time that we disabled interrupts + * above and the time that we read the counter below? + */ + + counter = tiva_getreg(priv, TIVA_TIMER_TAR_OFFSET); + + /* If the timer rolled over, there would be a pending timer interrupt. In + * that case, the time remaining time is zero. + */ + + status = tiva_getreg(priv, TIVA_TIMER_MIS_OFFSET); + if ((status & TIMER_INT_TATO) != 0) + { + remaining = 0; + } + else + { + /* Is this a count-up or a count-down timer? */ + + if (TIMER_ISCOUNTUP(&config->config)) + { + /* Counting up.. When the timer is counting up and it reaches the + * timeout event (the value in the GPTMTAILR, the timer reloads + * with zero. + * + * Get the current timer interval value */ + + interval = tiva_getreg(priv, TIVA_TIMER_TAILR_OFFSET); + + /* The time remaining is the current interval reload value minus + * the above sampled counter value. + * + * REVISIT: Or the difference +1? + */ + + DEBUGASSERT(interval == 0 || interval >= counter); + remaining = interval - counter; + } + else + { + /* Counting down: When the timer is counting down and it reaches + * the timeout event (0x0), the timer reloads its start value + * from the GPTMTAILR register on the next cycle. + * + * The time remaining it then just the the value of the counter + * register. + * + * REVISIT: Or the counter value +1? + */ + + remaining = counter; + } + } + + leave_critical_section(flags); + return remaining; +} +#endif /* CONFIG_TIVA_TIMER32_PERIODIC */ + +/**************************************************************************** + * Name: tiva_rtc_setalarm + * + * Description: + * Setup to receive an interrupt when the RTC counter equals a match time + * value. This function sets the match register to the current timer + * counter register value PLUS the relative value provided. The relative + * value then is an offset in seconds from the current time. + * + * NOTE: Use of this function is only meaningful for a a 32-bit RTC time. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * delay - A relative time in the future (seconds) + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_RTC +void tiva_rtc_setalarm(TIMER_HANDLE handle, uint32_t delay) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_timer32config_s *config; + irqstate_t flags; + uintptr_t base; + uint32_t counter; + uint32_t match; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uint32_t adcev; + uint32_t adcbits; +#endif + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode == TIMER32_MODE_RTC); + + /* Update the saved IMR if an interrupt will be needed */ + + config = (const struct tiva_timer32config_s *)priv->config; + if (config->handler) + { + /* Update the saved IMR to enable the RTC match interrupt */ + + priv->imr |= TIMER_INT_RTC; + } + + /* This must be done without interrupt or context switches to minimize + * race conditions with the free-running timer. Note that we also + * by-pass the normal register accesses to keep the latency to a + * minimum. + */ + + base = priv->attr->base; + + flags = enter_critical_section(); + + /* Set the match register to the current value of the timer counter plus + * the provided relative delay value. + */ + + counter = getreg32(base + TIVA_TIMER_TAR_OFFSET); + match = counter + delay; + putreg32(match, base + TIVA_TIMER_TAMATCHR_OFFSET); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable ADC trigger (if selected). NOTE the TAOTE bit was already + * selected in the GPTMCTL register when the timer was configured. + */ + + adcev = getreg32(base + TIVA_TIMER_ADCEV_OFFSET); + adcbits = TIMER_ISADCRTCM(config) ? TIMER_ADCEV_RTCADCEN : 0; + putreg32(adcev | adcbits, base + TIVA_TIMER_ADCEV_OFFSET); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + /* TODO: Set uDMA trigger in the same manner */ + + /* Enable interrupts as necessary */ + + putreg32(priv->imr, base + TIVA_TIMER_IMR_OFFSET); + leave_critical_section(flags); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Generate low-level debug output outside of the critical section */ + + lldbg("%08x->%08x\n", base + TIVA_TIMER_TAR_OFFSET, counter); + lldbg("%08x<-%08x\n", base + TIVA_TIMER_TAMATCHR_OFFSET, match); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + lldbg("%08x->%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev); + lldbg("%08x<-%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev | adcbits); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + lldbg("%08x<-%08x\n", base + TIVA_TIMER_IMR_OFFSET, priv->imr); +#endif +} +#endif + +/**************************************************************************** + * Name: tiva_timer32_relmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 32-bit timer. This function sets the match register + * to the current timer counter register value PLUS the relative value + * provided. The relative value then is some the offset to some timer + * counter value in the future. + * + * If an interrupt handler is provided, then the match interrupt will also + * be enabled. A single match interrupt will be generated; further match + * interrupts will be disabled. + * + * NOTE: Use of this function is only meaningful for a free-runnning, + * periodic timer. + * + * WARNING: For free-running timers, the relative match value should be + * sufficiently far in the future to avoid race conditions. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * relmatch - The value to write to the timer match register + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER32_PERIODIC +void tiva_timer32_relmatch(TIMER_HANDLE handle, uint32_t relmatch) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_timer32config_s *config; + uintptr_t base; + irqstate_t flags; + uint32_t counter; + uint32_t match; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uint32_t adcev; + uint32_t adcbits; +#endif + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode != TIMER16_MODE); + + /* Update the saved IMR if an interrupt will be needed */ + + config = (const struct tiva_timer32config_s *)priv->config; + if (config->handler) + { + /* Enable the match interrupt */ + + priv->imr |= TIMER_INT_TAM; + } + + /* This must be done without interrupt or context switches to minimize + * race conditions with the free-running timer. Note that we also + * by-pass the normal register accesses to keep the latency to a + * minimum. + */ + + base = priv->attr->base; + flags = enter_critical_section(); + + /* Set the match register to the current value of the timer counter plus + * the provided relative match value. + * + * NOTE that the prescale match is not used with the 32-bit timer. + */ + + counter = getreg32(base + TIVA_TIMER_TAR_OFFSET); + match = counter + relmatch; + putreg32(match, base + TIVA_TIMER_TAMATCHR_OFFSET); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable ADC trigger (if selected). NOTE the TAOTE bit was already + * selected in the GPTMCTL register when the timer was configured. + */ + + adcev = getreg32(base + TIVA_TIMER_ADCEV_OFFSET); + adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CAMADCEN : 0; + putreg32(adcev | adcbits, base + TIVA_TIMER_ADCEV_OFFSET); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + /* Enable interrupts as necessary */ + + putreg32(priv->imr, base + TIVA_TIMER_IMR_OFFSET); + leave_critical_section(flags); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Generate low-level debug output outside of the critical section */ + + lldbg("%08x->%08x\n", base + TIVA_TIMER_TAR_OFFSET, counter); + lldbg("%08x<-%08x\n", base + TIVA_TIMER_TAMATCHR_OFFSET, match); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + lldbg("%08x->%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev); + lldbg("%08x<-%08x\n", base + TIVA_TIMER_ADCEV_OFFSET, adcev | adcbits); +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + lldbg("%08x<-%08x\n", base + TIVA_TIMER_IMR_OFFSET, priv->imr); +#endif /* CONFIG_TIVA_TIMER_REGDEBUG */ + +} +#endif /* CONFIG_TIVA_TIMER32_PERIODIC */ + +/**************************************************************************** + * Name: tiva_timer16_relmatch + * + * Description: + * This function may be called at any time to change the timer interval + * match value of a 16-bit timer. This function sets the match register + * to the current timer counter register value PLUS the relative value + * provided. The relative value then is some the offset to some timer + * counter value in the future. + * + * If an interrupt handler is provided, then the match interrupt will also + * be enabled. A single match interrupt will be generated; further match + * interrupts will be disabled. + * + * NOTE: Use of this function is only meaningful for a free-runnning, + * periodic timer. + * + * NOTE: The relmatch input is a really a 24-bit value; it is the 16-bit + * match counter match value AND the 8-bit prescaler match value. From + * the caller's point of view the match value is the 24-bit time to match + * driven at the timer input clock frequency. + * + * When counting down in periodic modes, the prescaler contains the + * least-significant bits of the count. When counting up, the prescaler + * holds the most-significant bits of the count. But the caller is + * protected from this complexity. + * + * WARNING: For free-running timers, the relative match value should be + * sufficiently far in the future to avoid race conditions. + * + * Input Parameters: + * handle - The handle value returned by tiva_gptm_configure() + * relmatch - The value to write to the timer match register + * tmndx - Either TIMER16A or TIMER16B to select the 16-bit timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_TIMER16_PERIODIC +void tiva_timer16_relmatch(TIMER_HANDLE handle, uint32_t relmatch, int tmndx) +{ + struct tiva_gptmstate_s *priv = (struct tiva_gptmstate_s *)handle; + const struct tiva_gptm16config_s *gptm; + const struct tiva_timer16config_s *config; + irqstate_t flags; + uintptr_t base; + uintptr_t timerr; + uintptr_t prescr; + uintptr_t matchr; + uintptr_t prematchr; + uintptr_t imr; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + uintptr_t adcevr; + uint32_t adcevv; + uint32_t adcbits; +#endif + uint32_t timerv; + uint32_t prescv; + uint32_t matchv; + uint32_t prematchv; + uint32_t counter; + bool countup; + + DEBUGASSERT(priv && priv->attr && priv->config && + priv->config->mode == TIMER16_MODE && (unsigned)tmndx < 2); + + /* Pre-calculate as much as possible before entering the critical section */ + + gptm = (const struct tiva_gptm16config_s *)priv->config; + base = priv->attr->base; + + if (tmndx) + { + /* Update the saved IMR if an interrupt will be needed */ + + config = &gptm->config[TIMER16B]; + if (config->handler) + { + /* Enable the Timer B match interrupt */ + + priv->imr |= TIMER_INT_TBM; + } + + /* Get Timer B register addresses */ + + timerr = base + TIVA_TIMER_TBR_OFFSET; + prescr = base + TIVA_TIMER_TBPR_OFFSET; + matchr = base + TIVA_TIMER_TBMATCHR_OFFSET; + prematchr = base + TIVA_TIMER_TBPMR_OFFSET; + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Do we need to enable ADC trigger on the match? */ + + adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CBMADCEN : 0; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + } + else + { + /* Update the saved IMR if an interrupt will be needed */ + + config = &gptm->config[TIMER16A]; + if (config->handler) + { + /* Enable the Timer A match interrupt */ + + priv->imr |= TIMER_INT_TAM; + } + + /* Get Timer A register addresses */ + + timerr = base + TIVA_TIMER_TAR_OFFSET; + prescr = base + TIVA_TIMER_TAPR_OFFSET; + matchr = base + TIVA_TIMER_TAMATCHR_OFFSET; + prematchr = base + TIVA_TIMER_TAPMR_OFFSET; + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Do we need to enable ADC trigger on the match? */ + + adcbits = TIMER_ISADCMATCH(config) ? TIMER_ADCEV_CAMADCEN : 0; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + } + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + adcevr = base + TIVA_TIMER_ADCEV_OFFSET; +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + imr = base + TIVA_TIMER_IMR_OFFSET; + countup = TIMER_ISCOUNTUP(config); + + /* This must be done without interrupt or context switches to minimize + * race conditions with the free-running timer. Note that we also + * by-pass the normal register accesses to keep the latency to a + * minimum. + */ + + flags = enter_critical_section(); + timerv = getreg32(timerr) & 0xffff; + prescv = getreg32(prescr) & 0xff; + + /* Are we counting up or down? */ + + if (countup) + { + /* When counting up in one-shot or periodic modes, the prescaler + * acts as a timer extension and holds the most-significant bits + * of the count + */ + + counter = prescv << 16 | timerv; + counter += relmatch; + matchv = counter & 0xffff; + prematchv = (counter >> 8) & 0xff; + } + else + { + /* When counting down in one-shot or periodic modes, the prescaler + * acts as a true prescaler and contains the least-significant bits + * of the count. + */ + + counter = timerv << 8 | prescv; + counter += relmatch; + matchv = (counter >> 8) & 0xffff; + prematchv = counter & 0xff; + } + + /* Set the match and prescacle match registers */ + + putreg32(matchv, matchr); + putreg32(prematchv, prematchr); + +#ifdef CONFIG_ARCH_CHIP_TM4C129 + /* Enable ADC trigger (if selected). NOTE the TnOTE bit was already + * selected in the GPTMCTL register when the timer was configured. + */ + + adcevv = getreg32(adcevr); + putreg32(adcevv | adcbits, adcevr); +#endif + + /* Enable interrupts as necessary */ + + putreg32(priv->imr, imr); + leave_critical_section(flags); + +#ifdef CONFIG_TIVA_TIMER_REGDEBUG + /* Generate low-level debug output outside of the critical section */ + + lldbg("%08x->%08x\n", timerr, timerv); + lldbg("%08x->%08x\n", prescr, prescv); + lldbg("%08x<-%08x\n", matchr, matchv); + lldbg("%08x<-%08x\n", prematchr, prematchv); +#ifdef CONFIG_ARCH_CHIP_TM4C129 + lldbg("%08x->%08x\n", adcevr, adcevv); + lldbg("%08x<-%08x\n", adcevr, adcevv | adcbits); +#endif + lldbg("%08x<-%08x\n", imr, priv->imr); +#endif +} +#endif diff --git a/arch/arm/src/tiva/tiva_timerlow32.c b/arch/arm/src/tiva/tiva_timerlow32.c new file mode 100644 index 0000000000000000000000000000000000000000..ac3ac065f53531fae325d0b3ef5d7e2138be2c13 --- /dev/null +++ b/arch/arm/src/tiva/tiva_timerlow32.c @@ -0,0 +1,635 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_timerlow32.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "tiva_timer.h" + +#if defined(CONFIG_TIMER) && defined(CONFIG_TIVA_TIMER) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct tiva_lowerhalf_s +{ + const struct timer_ops_s *ops; /* Lower half operations */ + struct tiva_gptm32config_s config; /* Persistent timer configuration */ + TIMER_HANDLE handle; /* Contained timer handle */ + tccb_t handler; /* Current user interrupt handler */ + uint32_t clkin; /* Input clock frequency */ + uint32_t timeout; /* The current timeout value (us) */ + uint32_t clkticks; /* Actual clock ticks for current interval */ + uint32_t adjustment; /* Time lost due to truncation (us) */ + bool started; /* True: Timer has been started */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Helper functions *********************************************************/ + +static uint32_t tiva_usec2ticks(struct tiva_lowerhalf_s *priv, uint32_t usecs); +static uint32_t tiva_ticks2usec(struct tiva_lowerhalf_s *priv, uint32_t ticks); +static void tiva_timeout(struct tiva_lowerhalf_s *priv, uint32_t timeout); + +/* Interrupt handling *******************************************************/ + +static void tiva_timer_handler(TIMER_HANDLE handle, void *arg, uint32_t status); + +/* "Lower half" driver methods **********************************************/ + +static int tiva_start(struct timer_lowerhalf_s *lower); +static int tiva_stop(struct timer_lowerhalf_s *lower); +static int tiva_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status); +static int tiva_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout); +static tccb_t tiva_sethandler(struct timer_lowerhalf_s *lower, + tccb_t handler); +static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_timer_ops = +{ + .start = tiva_start, + .stop = tiva_stop, + .getstatus = tiva_getstatus, + .settimeout = tiva_settimeout, + .sethandler = tiva_sethandler, + .ioctl = tiva_ioctl, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_usec2ticks + * + * Description: + * Convert microseconds to timer clock ticks. + * + * Input Parameters: + * priv - A pointer to a private timer driver lower half instance + * usecs - The number of usecs to convert + * + * Returned Values: + * The time converted to clock ticks. + * + ****************************************************************************/ + +static uint32_t tiva_usec2ticks(struct tiva_lowerhalf_s *priv, uint32_t usecs) +{ + uint64_t bigticks; + + bigticks = ((uint64_t)usecs * (uint64_t)priv->clkin) / 1000000; + if (bigticks > UINT32_MAX) + { + return UINT32_MAX; + } + + return (uint32_t)bigticks; +} + +/**************************************************************************** + * Name: tiva_ticks2usec + * + * Description: + * Convert timer clock ticks to microseconds. + * + * Input Parameters: + * priv - A pointer to a private timer driver lower half instance + * usecs - The number of ticks to convert + * + * Returned Values: + * The time converted to microseconds. + * + ****************************************************************************/ + +static uint32_t tiva_ticks2usec(struct tiva_lowerhalf_s *priv, uint32_t ticks) +{ + uint64_t bigusec; + + bigusec = (1000000ull * (uint64_t)ticks) / priv->clkin; + if (bigusec > UINT32_MAX) + { + return UINT32_MAX; + } + + return (uint32_t)bigusec; +} + +/**************************************************************************** + * Name: tiva_timeout + * + * Description: + * Calculate a new timeout value. + * + * Input Parameters: + * priv - A pointer to a private timer driver lower half instance + * timeout - The new timeout value in microseconds. + * + * Returned Values: + * None + * + ****************************************************************************/ + +static void tiva_timeout(struct tiva_lowerhalf_s *priv, uint32_t timeout) +{ + timvdbg("Entry: timeout=%d\n", timeout); + + /* Save the desired timeout value */ + + priv->timeout = timeout; + + /* Calculate the actual timeout value in clock ticks */ + + priv->clkticks = tiva_usec2ticks(priv, timeout); + + /* Calculate an adjustment due to truncation in timer resolution */ + + timeout = tiva_ticks2usec(priv, priv->clkticks); + priv->adjustment = priv->timeout - timeout; + + timvdbg("clkin=%d clkticks=%d timeout=%d, adjustment=%d\n", + priv->clkin, priv->clkticks, priv->timeout, priv->adjustment); +} + +/**************************************************************************** + * Name: tiva_timer_handler + * + * Description: + * 32-bit timer interrupt handler + * + * Input Parameters: + * Usual 32-bit timer interrupt handler arguments. + * + * Returned Values: + * None + * + ****************************************************************************/ + +static void tiva_timer_handler(TIMER_HANDLE handle, void *arg, uint32_t status) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)arg; + + timvdbg("Entry: status=%08x\n", status); + DEBUGASSERT(arg && status); + + /* Check if the timeout interrupt is pending */ + + if ((status & TIMER_INT_TATO) != 0) + { + uint32_t timeout; + + /* Is there a registered handler? If the handler has been nullified, + * the timer will be stopped. + */ + + if (priv->handler && priv->handler(&priv->timeout)) + { + /* Calculate new ticks / dither adjustment */ + + priv->clkticks = tiva_usec2ticks(priv, priv->adjustment + priv->timeout); + + /* Set next interval interval. TODO: make sure the interval is not + * so soon it will be missed! + */ + +#if 0 /* Too much in this context */ + tiva_timer32_setinterval(priv->handle, priv->clkticks); +#else + tiva_gptm_putreg(priv->handle, TIVA_TIMER_TAILR_OFFSET, priv->clkticks); +#endif + + /* Calculate the next adjustment */ + + timeout = tiva_ticks2usec(priv, priv->clkticks); + priv->adjustment = (priv->adjustment + priv->timeout) - timeout; + } + else + { + /* No handler or the handler returned false.. stop the timer */ + + tiva_timer32_stop(priv->handle); + timvdbg("Stopped\n"); + } + } +} + +/**************************************************************************** + * Name: tiva_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int tiva_start(struct timer_lowerhalf_s *lower) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower; + + timvdbg("Entry: started %d\n", priv->started); + + /* Has the timer already been started? */ + + if (!priv->started) + { + /* Start the timer */ + + tiva_timer32_start(priv->handle); + priv->started = true; + return OK; + } + + /* Return EBUSY to indicate that the timer was already running */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: tiva_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int tiva_stop(struct timer_lowerhalf_s *lower) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower; + + timvdbg("Entry: started %d\n", priv->started); + + /* Has the timer already been started? */ + + if (priv->started) + { + /* Stop the timer */ + + tiva_timer32_stop(priv->handle); + priv->started = false; + return OK; + } + + /* Return ENODEV to indicate that the timer was not running */ + + return -ENODEV; +} + +/**************************************************************************** + * Name: tiva_getstatus + * + * Description: + * Get the current timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * status - The location to return the status information. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int tiva_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower; + uint32_t remaining; + + timvdbg("Entry\n"); + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = 0; + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->handler) + { + status->flags |= TCFLAGS_HANDLER; + } + + /* Return the actual timeout in microseconds */ + + status->timeout = priv->timeout; + + /* Get the time remaining until the timer expires (in microseconds). */ + + remaining = tiva_timer32_remaining(priv->handle); + status->timeleft = tiva_ticks2usec(priv, remaining); + + timvdbg(" flags : %08x\n", status->flags); + timvdbg(" timeout : %d\n", status->timeout); + timvdbg(" timeleft : %d\n", status->timeleft); + return OK; +} + +/**************************************************************************** + * Name: tiva_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int tiva_settimeout(struct timer_lowerhalf_s *lower, uint32_t timeout) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower; + + DEBUGASSERT(priv); + + if (priv->started) + { + return -EPERM; + } + + timvdbg("Entry: timeout=%d\n", timeout); + + /* Calculate the the new time settings */ + + tiva_timeout(priv, timeout); + + /* Reset the timer interval */ + + tiva_timer32_setinterval(priv->handle, priv->clkticks); + return OK; +} + +/**************************************************************************** + * Name: tiva_sethandler + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * newhandler - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * + * Returned Values: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static tccb_t tiva_sethandler(struct timer_lowerhalf_s *lower, + tccb_t handler) +{ + struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower; + irqstate_t flags; + tccb_t oldhandler; + + flags = enter_critical_section(); + + DEBUGASSERT(priv); + timvdbg("Entry: handler=%p\n", handler); + + /* Get the old handler return value */ + + oldhandler = priv->handler; + + /* Save the new handler */ + + priv->handler = handler; + + leave_critical_section(flags); + return oldhandler; +} + +/**************************************************************************** + * Name: tiva_ioctl + * + * Description: + * Any ioctl commands that are not recognized by the "upper-half" driver + * are forwarded to the lower half driver through this method. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower-half" + * driver state structure. + * cmd - The ioctl command value + * arg - The optional argument that accompanies the 'cmd'. The + * interpretation of this argument depends on the particular + * command. + * + * Returned Values: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + int ret = -ENOTTY; + + DEBUGASSERT(priv); + timvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * NOTES: + * 1. Only 32-bit periodic timers are supported. + * 2. Timeout interrupts are disabled until tiva_timer32_setinterval() is + * called. + * 3. Match interrupts are disabled until tiva_timer32_relmatch() is + * called. + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * config - 32-bit timer configuration values. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int tiva_timer_initialize(FAR const char *devpath, + struct tiva_gptm32config_s *config) +{ + struct tiva_lowerhalf_s *priv; + void *drvr; + int ret; + + timvdbg("\n"); + DEBUGASSERT(devpath); + + /* Allocate an instance of the lower half state structure */ + + priv = (struct tiva_lowerhalf_s *)kmm_zalloc(sizeof(struct tiva_lowerhalf_s)); + if (!priv) + { + timdbg("ERROR: Failed to allocate driver structure\n"); + return -ENOMEM; + } + + /* Initialize the non-zero elements of lower half state structure */ + + priv->ops = &g_timer_ops; +#ifdef CONFIG_ARCH_CHIP_TM4C129 + priv->clkin = config->cmn.alternate ? ALTCLK_FREQUENCY : SYSCLK_FREQUENCY; +#else + if (config->cmn.alternate) + { + timdbg("ERROR: Alternate clock unsupported on TM4C123 architecture\n"); + return -ENOMEM; + } + else + { + priv->clkin = SYSCLK_FREQUENCY; + } +#endif /* CONFIG_ARCH_CHIP_TM4C129 */ + + config->config.handler = tiva_timer_handler; + config->config.arg = priv; + memcpy(&(priv->config), config, sizeof(struct tiva_gptm32config_s)); + + /* Set the initial timer interval */ + + tiva_timeout(priv, 0); + + /* Create the timer handle */ + + priv->handle = tiva_gptm_configure((const struct tiva_gptmconfig_s *)&priv->config); + if (!priv->handle) + { + timdbg("ERROR: Failed to create timer handle\n"); + ret = -EINVAL; + goto errout_with_alloc; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be used with timer_unregister(). + * REVISIT: The returned handle is discard here. + */ + + drvr = timer_register(devpath, (struct timer_lowerhalf_s *)priv); + if (!drvr) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'depath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + + ret = -EEXIST; + goto errout_with_timer; + } + + return OK; + +errout_with_timer: + tiva_gptm_release(priv->handle); /* Free timer resources */ + +errout_with_alloc: + kmm_free(priv); /* Free the allocated state structure */ + return ret; /* Return the error indication */ +} + +#endif /* CONFIG_TIMER && CONFIG_TIVA_TIMER */ diff --git a/arch/arm/src/tiva/tiva_userspace.c b/arch/arm/src/tiva/tiva_userspace.c new file mode 100644 index 0000000000000000000000000000000000000000..b041a5d58cc1378173df7b5767782dc9c7894f58 --- /dev/null +++ b/arch/arm/src/tiva/tiva_userspace.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/tiva/tiva_userspace.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "tiva_mpuinit.h" +#include "tiva_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void tiva_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + tiva_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/tiva/tiva_userspace.h b/arch/arm/src/tiva/tiva_userspace.h new file mode 100644 index 0000000000000000000000000000000000000000..cdfced14267f7aa3dea22ebf6f7445b7d9243279 --- /dev/null +++ b/arch/arm/src/tiva/tiva_userspace.h @@ -0,0 +1,76 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_userspace.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TIVA_TIVA_USERSPACE_H +#define __ARCH_ARM_SRC_TIVA_TIVA_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: tiva_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void tiva_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_TIVA_TIVA_USERSPACE_H */ diff --git a/arch/arm/src/tiva/tiva_vectors.S b/arch/arm/src/tiva/tiva_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..4f56269ba444b7f3c843f8da42e75d59934629ac --- /dev/null +++ b/arch/arm/src/tiva/tiva_vectors.S @@ -0,0 +1,488 @@ +/************************************************************************************ + * arch/arm/src/tiva/tiva_vectors.S + * + * Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "exc_return.h" + +/************************************************************************************ + * Configuration + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + /* In kernel mode without an interrupt stack, this interrupt handler will set the + * MSP to the stack pointer of the interrupted thread. If the interrupted thread + * was a privileged thread, that will be the MSP otherwise it will be the PSP. If + * the PSP is used, then the value of the MSP will be invalid when the interrupt + * handler returns because it will be a pointer to an old position in the + * unprivileged stack. Then when the high priority interrupt occurs and uses this + * stale MSP, there will most likely be a system failure. + * + * If the interrupt stack is selected, on the other hand, then the interrupt + * handler will always set the the MSP to the interrupt stack. So when the high + * priority interrupt occurs, it will either use the MSP of the last privileged + * thread to run or, in the case of the nested interrupt, the interrupt stack if + * no privileged task has run. + */ + +# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 4 +# error Interrupt stack must be used with high priority interrupts in kernel mode +# endif + + /* Use the the BASEPRI to control interrupts is required if nested, high + * priority interrupts are supported. + */ + +# ifndef CONFIG_ARMV7M_USEBASEPRI +# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT +# endif +#endif + +/* Memory Map ***********************************************************************/ +/* + * 0x0000:0000 - Beginning of FLASH. Address of vectors (if not using bootloader) + * 0x0002:0000 - Address of vectors if using bootloader + * 0x0003:ffff - End of flash + * 0x2000:0000 - Start of SRAM and start of .data (_sdata) + * - End of .data (_edata) abd start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, start of heap + * 0x2000:ffff - End of SRAM and end of heap + */ + +#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "tiva_vectors.S" + +/* Check if common ARMv7 interrupt vectoring is used (see arch/arm/src/armv7-m/up_vectors.S) */ + +#ifndef CONFIG_ARMV7M_CMNVECTOR + + .globl __start + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/* On entry into an IRQ, the hardware automatically saves the xPSR, PC, LR, R12, R0-R3 + * registers on the stack, then branches to an instantantiation of the following + * macro. This macro simply loads the IRQ number into R0, then jumps to the common + * IRQ handling logic. + */ + + .macro HANDLER, label, irqno + .thumb_func +\label: + mov r0, #\irqno + b exception_common + .endm + +/************************************************************************************ + * Vectors + ************************************************************************************/ + + .section .vectors, "ax" + .code 16 + .align 2 + .globl _vectors + .type _vectors, function + +_vectors: + +/* Processor Exceptions */ + + .word IDLE_STACK /* Vector 0: Reset stack pointer */ + .word __start /* Vector 1: Reset vector */ + .word tiva_nmi /* Vector 2: Non-Maskable Interrupt (NMI) */ + .word tiva_hardfault /* Vector 3: Hard fault */ + .word tiva_mpu /* Vector 4: Memory management (MPU) */ + .word tiva_busfault /* Vector 5: Bus fault */ + .word tiva_usagefault /* Vector 6: Usage fault */ + .word tiva_reserved /* Vector 7: Reserved */ + .word tiva_reserved /* Vector 8: Reserved */ + .word tiva_reserved /* Vector 9: Reserved */ + .word tiva_reserved /* Vector 10: Reserved */ + .word tiva_svcall /* Vector 11: SVC call */ + .word tiva_dbgmonitor /* Vector 12: Debug monitor */ + .word tiva_reserved /* Vector 13: Reserved */ + .word tiva_pendsv /* Vector 14: Pendable system service request */ + .word tiva_systick /* Vector 15: System tick */ + +/* External Interrupts */ + +/* External Interrupts */ + +#undef VECTOR +#define VECTOR(l,i) .word l + +#undef UNUSED +#define UNUSED(i) .word tiva_reserved + +#include "chip/chip/tiva_vectors.h" + .size _vectors, .-_vectors + +/************************************************************************************ + * .text + ************************************************************************************/ + + .text + .type handlers, function + .thumb_func +handlers: + HANDLER tiva_reserved, TIVA_IRQ_RESERVED /* Unexpected/reserved vector */ + HANDLER tiva_nmi, TIVA_IRQ_NMI /* Vector 2: Non-Maskable Interrupt (NMI) */ + HANDLER tiva_hardfault, TIVA_IRQ_HARDFAULT /* Vector 3: Hard fault */ + HANDLER tiva_mpu, TIVA_IRQ_MEMFAULT /* Vector 4: Memory management (MPU) */ + HANDLER tiva_busfault, TIVA_IRQ_BUSFAULT /* Vector 5: Bus fault */ + HANDLER tiva_usagefault, TIVA_IRQ_USAGEFAULT /* Vector 6: Usage fault */ + HANDLER tiva_svcall, TIVA_IRQ_SVCALL /* Vector 11: SVC call */ + HANDLER tiva_dbgmonitor, TIVA_IRQ_DBGMONITOR /* Vector 12: Debug Monitor */ + HANDLER tiva_pendsv, TIVA_IRQ_PENDSV /* Vector 14: Penable system service request */ + HANDLER tiva_systick, TIVA_IRQ_SYSTICK /* Vector 15: System tick */ + +#undef VECTOR +#define VECTOR(l,i) HANDLER l, i + +#undef UNUSED +#define UNUSED(i) + +#include "chip/chip/tiva_vectors.h" + +/* Common IRQ handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * R0 contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .globl exception_common + .type exception_common, function +exception_common: + + /* Complete the context save */ + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: +#endif + + /* r1 holds the value of the stack pointer AFTER the exception handling logic + * pushed the various registers onto the stack. Get r2 = the value of the + * stack pointer BEFORE the interrupt modified it. + */ + + mov r2, sp /* R2=Copy of the main/process stack pointer */ + add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ +#ifdef CONFIG_ARMV7M_USEBASEPRI + mrs r3, basepri /* R3=Current BASEPRI setting */ +#else + mrs r3, primask /* R3=Current PRIMASK setting */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register save. + * Lazy FPU register saving is used. FPU registers will be saved in this + * block only if a context switch occurs (this means, of course, that the FPU + * cannot be used in interrupt processing). + */ + + sub sp, #(4*SW_FPU_REGS) +#endif + + /* Save the remaining registers on the stack after the registers pushed + * by the exception handling logic. r2=SP and r3=primask or basepri, r4-r11, + * r14=register values. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ +#else + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + /* Disable interrupts, select the stack to use for interrupt handling + * and call up_doirq to handle the interrupt + */ + + cpsid i /* Disable further interrupts */ + +#else + /* Set the BASEPRI register so that further normal interrupts will be + * masked. Nested, high priority may still occur, however. + */ + + mov r2, #NVIC_SYSH_DISABLE_PRIORITY + msr basepri, r2 /* Set the BASEPRI */ +#endif + + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + + /* Also save the top of the stack in a preserved register */ + + mov r4, sp + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use + * a special special interrupt stack pointer. The way that this is done + * here prohibits nested interrupts without some additional logic! + */ + + ldr sp, =g_intstackbase + +#else + /* Otherwise, we will re-use the interrupted thread's stack. That may + * mean using either MSP or PSP stack for interrupt level processing (in + * kernel mode). + */ + + bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */ + mov sp, r2 /* Instantiate the aligned stack */ + +#endif + + bl up_doirq /* R0=IRQ, R1=register save (msp) */ + mov r1, r4 /* Recover R1=main stack pointer */ + + /* On return from up_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 2f /* Branch if no context switch */ + + /* We are returning with a pending context switch. + * + * If the FPU is enabled, then we will need to restore FPU registers. + * This is not done in normal interrupt save/restore because the cost + * is prohibitive. This is only done when switching contexts. A + * consequence of this is that floating point operations may not be + * performed in interrupt handling logic. + * + * Here: + * r0 = Address of the register save area + + * NOTE: It is a requirement that up_restorefpu() preserve the value of + * r0! + */ + +#ifdef CONFIG_ARCH_FPU + bl up_restorefpu /* Restore the FPU registers */ +#endif + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie in the + * stack but, rather, within a TCB structure. We'll have to copy some + * values to the stack. + */ + + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ + ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ +#ifdef CONFIG_BUILD_PROTECTED + ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + b 3f /* Re-join common logic */ + + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created + * + * Here: + * r1 = Address of the return stack (same as r0) + */ + +2: +#ifdef CONFIG_BUILD_PROTECTED + ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */ +#else + ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */ +#endif + +#ifdef CONFIG_ARCH_FPU + /* Skip over the block of memory reserved for floating pointer register + * save. Then R1 is the address of the HW save area + */ + + add r1, #(4*SW_FPU_REGS) +#endif + + /* Set up to return from the exception + * + * Here: + * r1 = Address on the target thread's stack position at the start of + * the registers saved by hardware + * r3 = primask or basepri + * r4-r11 = restored register values + */ + +3: + +#ifdef CONFIG_BUILD_PROTECTED + /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1 + * (handler mode) if the stack is on the MSP. It can only be on the PSP if + * EXC_RETURN is 0xfffffffd (unprivileged thread) + */ + + mrs r2, control /* R2=Contents of the control register */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 4f /* Branch if privileged */ + + orr r2, r2, #1 /* Unprivileged mode */ + msr psp, r1 /* R1=The process stack pointer */ + b 5f +4: + bic r2, r2, #1 /* Privileged mode */ + msr msp, r1 /* R1=The main stack pointer */ +5: + msr control, r2 /* Save the updated control register */ +#else + msr msp, r1 /* Recover the return MSP value */ + + /* Preload r14 with the special return value first (so that the return + * actually occurs with interrupts still disabled). + */ + + ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */ +#endif + + /* Restore the interrupt state */ + +#ifdef CONFIG_ARMV7M_USEBASEPRI + msr basepri, r3 /* Restore interrupts priority masking */ +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT + cpsie i /* Re-enable interrupts */ +#endif + +#else + msr primask, r3 /* Restore interrupts */ +#endif + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) continue to use the MSP + */ + + bx r14 /* And return */ + .size handlers, .-handlers + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + .bss + .global g_intstackalloc + .global g_intstackbase + .align 8 +g_intstackalloc: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~7) +g_intstackbase: + .size g_intstackalloc, .-g_intstackalloc +#endif +#endif /* CONFIG_ARMV7M_CMNVECTOR */ + +/************************************************************************************ + * .rodata + ************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + + .end diff --git a/arch/arm/src/tiva/tm4c129_syscontrol.c b/arch/arm/src/tiva/tm4c129_syscontrol.c new file mode 100644 index 0000000000000000000000000000000000000000..56b8bba9e81943a162e95b1eabf1ffdac9af092e --- /dev/null +++ b/arch/arm/src/tiva/tm4c129_syscontrol.c @@ -0,0 +1,413 @@ +/**************************************************************************** + * arch/arm/src/tiva/tm4c129_syscontrol.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "chip.h" +#include "tiva_syscontrol.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if XTAL_FREQUENCY < 5000000 || XTAL_FREQUENCY > 25000000 +# error Crystal frequency is not supported +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure supports mapping of a frequency to optimal memory timing */ + +struct f2memtim0_s +{ + uint32_t frequency; + uint32_t memtim0; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This structure supports mapping of a frequency to optimal memory timing */ + +static const struct f2memtim0_s g_f2memtim0[] = +{ + { + 16000000, + (SYSCON_MEMTIM0_FWS(0) | SYSCON_MEMTIM0_FBCE | SYSCON_MEMTIM0_FBCHT_0p5 | + SYSCON_MEMTIM0_EWS(0) | SYSCON_MEMTIM0_EBCE | SYSCON_MEMTIM0_EBCHT_0p5 | + SYSCON_MEMTIM0_MB1) + }, + { + 40000000, + (SYSCON_MEMTIM0_FWS(1) | SYSCON_MEMTIM0_FBCHT_1p5 | + SYSCON_MEMTIM0_EWS(1) | SYSCON_MEMTIM0_EBCHT_1p5 | + SYSCON_MEMTIM0_MB1) + }, + { + 60000000, + (SYSCON_MEMTIM0_FWS(2) | SYSCON_MEMTIM0_FBCHT_2 | + SYSCON_MEMTIM0_EWS(2) | SYSCON_MEMTIM0_EBCHT_2 | + SYSCON_MEMTIM0_MB1) + }, + { + 80000000, + (SYSCON_MEMTIM0_FWS(3) | SYSCON_MEMTIM0_FBCHT_2p5 | + SYSCON_MEMTIM0_EWS(3) | SYSCON_MEMTIM0_EBCHT_2p5 | + SYSCON_MEMTIM0_MB1) + }, + { + 100000000, + (SYSCON_MEMTIM0_FWS(4) | SYSCON_MEMTIM0_FBCHT_3 | + SYSCON_MEMTIM0_EWS(4) | SYSCON_MEMTIM0_EBCHT_3 | + SYSCON_MEMTIM0_MB1) + }, + { + 120000000, + (SYSCON_MEMTIM0_FWS(5) | SYSCON_MEMTIM0_FBCHT_3p5 | + SYSCON_MEMTIM0_EWS(5) | SYSCON_MEMTIM0_EBCHT_3p5 | + SYSCON_MEMTIM0_MB1) + }, +}; + +#define NMEMTIM0_SETTINGS (sizeof(g_f2memtim0) / sizeof(struct f2memtim0_s)) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_memtim0 + * + * Description: + * Given a SysClk frequency, perform a table lookup to select the optimal + * FLASH and EEPROM configuration for the MEMTIM0 register. + * + ****************************************************************************/ + +static uint32_t tiva_memtim0(uint32_t sysclk) +{ + int i; + + /* Search for the optimal memory timing */ + + for (i = 0; i < NMEMTIM0_SETTINGS; i++) + { + /* Check if if the SysClk is less than the maximum frequency for this + * flash memory timing. + */ + + if (sysclk <= g_f2memtim0[i].frequency) + { + /* Yes.. then this FLASH memory timing is the best choice for the + * given system clock frequency. + */ + + return(g_f2memtim0[i].memtim0); + } + } + + /* No appropriate flash memory timing could be found. The device is + * being clocked too fast. + */ + + DEBUGPANIC(); + return 0; +} + +/**************************************************************************** + * Name: tiva_vco_frequency + * + * Description: + * Given the crystal frequency and the PLLFREQ0 and PLLFREQ1 register + * settings, return the SysClk frequency. + * + ****************************************************************************/ + +static uint32_t tiva_vco_frequency(uint32_t pllfreq0, uint32_t pllfreq1) +{ + uint64_t fvcob10; + uint32_t mint; + uint32_t mfrac; + uint32_t q; + uint32_t n; + uint32_t mdivb10; + + /* Extract all of the values from the hardware register values. */ + + mfrac = (pllfreq0 & SYSCON_PLLFREQ0_MFRAC_MASK) >> SYSCON_PLLFREQ0_MFRAC_SHIFT; + mint = (pllfreq0 & SYSCON_PLLFREQ0_MINT_MASK) >> SYSCON_PLLFREQ0_MINT_SHIFT; + q = ((pllfreq1 & SYSCON_PLLFREQ1_Q_MASK) >> SYSCON_PLLFREQ1_Q_SHIFT) + 1; + n = ((pllfreq1 & SYSCON_PLLFREQ1_N_MASK) >> SYSCON_PLLFREQ1_N_SHIFT) + 1; + + /* Algorithm: + * + * Fin = Fxtal / Q / N (-OR- Fpiosc / Q / N) + * Mdiv = Mint + (MFrac / 1024) + * Fvco = Fin * Mdiv + */ + + mdivb10 = (mint << 10) + mfrac; + fvcob10 = (mdivb10 * (uint64_t)XTAL_FREQUENCY) / (q * n); + return (uint32_t)(fvcob10 >> 10); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tiva_clockconfig + * + * Description: + * Called to change to new clock based on desired pllfreq0, pllfreq1, and + * sysdiv settings. This is use to set up the initial clocking but can be + * used later to support slow clocked, low power consumption modes. + * + * The pllfreq0 and pllfreq1 settings derive from the PLL M, N, and Q + * values to generate Fvco like: + * + * Fin = Fxtal / Q / N -OR- Fpiosc / Q / N + * Mdiv = Mint + (MFrac / 1024) + * Fvco = Fin * Mdiv + * + * When the PLL is active, the system clock frequency (SysClk) is + * calculated using the following equation: + * + * SysClk = Fvco/ sysdiv + * + * NOTE: The input clock to the PLL may be either the external crystal + * (Fxtal) or PIOSC (Fpiosc). This logic supports only the external + * crystal as the PLL source clock. + * + * Input Parameters: + * pllfreq0 - PLLFREQ0 register value (see helper macro M2PLLFREQ0() + * pllfreq1 - PLLFREQ1 register value (see helper macro QN2PLLFREQ1() + * sysdiv - Fvco divider value + * + * Returned Value: + * The resulting SysClk frequency + * + ****************************************************************************/ + +uint32_t tiva_clockconfig(uint32_t pllfreq0, uint32_t pllfreq1, uint32_t sysdiv) +{ + uint32_t sysclk; + uint32_t regval; + int32_t timeout; + bool newpll; + + /* Clear MOSC power down, high oscillator range setting, and no crystal + * present settings. + */ + + regval = getreg32(TIVA_SYSCON_MOSCCTL); + regval &= ~(SYSCON_MOSCCTL_OSCRNG | SYSCON_MOSCCTL_PWRDN | + SYSCON_MOSCCTL_NOXTAL); + +#if XTAL_FREQUENCY >= 10000000 + /* Increase the drive strength for MOSC of 10 MHz and above. */ + + regval |= SYSCON_MOSCCTL_OSCRNG; +#endif + + putreg32(regval, TIVA_SYSCON_MOSCCTL); + + /* Set the memory timings for the maximum external frequency since this + * could be a switch to PIOSC or possibly to MOSC which can be up to + * 25MHz. + */ + + regval = tiva_memtim0(25000000); + putreg32(regval, TIVA_SYSCON_MEMTIM0); + + /* Clear any previous PLL divider and source setup. Update the clock + * configuration to switch back to PIOSC. + */ + + regval = getreg32(TIVA_SYSCON_RSCLKCFG); + regval &= ~(SYSCON_RSCLKCFG_PSYSDIV_MASK | SYSCON_RSCLKCFG_OSCSRC_MASK | + SYSCON_RSCLKCFG_PLLSRC_MASK | SYSCON_RSCLKCFG_USEPLL); + regval |= SYSCON_RSCLKCFG_MEMTIMU; + putreg32(regval, TIVA_SYSCON_RSCLKCFG); + + /* If there were no changes to the PLL do not force the PLL to lock by + * writing the PLL settings. + */ + + newpll = (getreg32(TIVA_SYSCON_PLLFREQ1) != pllfreq1 || + getreg32(TIVA_SYSCON_PLLFREQ0) != pllfreq0); + + /* If there are new PLL settings write them. */ + + if (newpll) + { + /* Set the oscillator source. */ + + regval = getreg32(TIVA_SYSCON_RSCLKCFG); + regval |= (SYSCON_RSCLKCFG_OSCSRC_MOSC | SYSCON_RSCLKCFG_PLLSRC_MOSC); + putreg32(regval, TIVA_SYSCON_RSCLKCFG); + + /* Set the M, N and Q values provided by the pllfreq0 and pllfreq1 + * parameters. + */ + + putreg32(pllfreq1, TIVA_SYSCON_PLLFREQ1); + + regval = getreg32(TIVA_SYSCON_PLLFREQ0); + regval &= SYSCON_PLLFREQ0_PLLPWR; + pllfreq0 |= regval; + putreg32(pllfreq0, TIVA_SYSCON_PLLFREQ0); + } + + /* Calculate the actual system clock. */ + + sysclk = tiva_vco_frequency(pllfreq0, pllfreq1) / sysdiv; + + /* Set the Flash and EEPROM timing values. */ + + regval = tiva_memtim0(sysclk); + putreg32(regval, TIVA_SYSCON_MEMTIM0); + + /* Was the PLL already powered up? */ + + if ((getreg32(TIVA_SYSCON_PLLFREQ0) & SYSCON_PLLFREQ0_PLLPWR) != 0) + { + /* Yes.. Is this a new PLL setting? */ + + if (newpll == true) + { + /* Yes.. Trigger the PLL to lock to the new frequency. */ + + regval = getreg32(TIVA_SYSCON_RSCLKCFG); + regval |= SYSCON_RSCLKCFG_NEWFREQ; + putreg32(regval, TIVA_SYSCON_RSCLKCFG); + } + } + else + { + /* No... Not already powered. Power up the PLL now. */ + + regval = getreg32(TIVA_SYSCON_PLLFREQ0); + regval |= SYSCON_PLLFREQ0_PLLPWR; + putreg32(regval, TIVA_SYSCON_PLLFREQ0); + } + + /* Wait until the PLL has locked. */ + + for (timeout = 32768; timeout > 0; timeout--) + { + /* Check if the PLL has locked */ + + if ((getreg32(TIVA_SYSCON_PLLSTAT) & SYSCON_PLLSTAT_LOCK) != 0) + { + /* The PLL has reported that it is locked. Switch over to the + * PLL. + */ + + regval = getreg32(TIVA_SYSCON_RSCLKCFG); + regval |= SYSCON_RSCLKCFG_PSYSDIV(sysdiv - 1) | + SYSCON_RSCLKCFG_OSCSRC_MOSC | + SYSCON_RSCLKCFG_PLLSRC_MOSC | + SYSCON_RSCLKCFG_USEPLL | + SYSCON_RSCLKCFG_MEMTIMU; + putreg32(regval, TIVA_SYSCON_RSCLKCFG); + + /* And return the new SysClk frequency */ + + return sysclk; + } + } + + /* We get here on a timout, failing to get the PLL lock indication */ + + DEBUGPANIC(); + return 0; +} + +/**************************************************************************** + * Name: up_clockconfig + * + * Description: + * Called early in the boot sequence (before .data and .bss are available) + * in order to configure initial clocking. + * + ****************************************************************************/ + +void up_clockconfig(void) +{ + uint32_t pllfreq0; + uint32_t pllfreq1; + + /* Set the clocking to run with the default settings provided in the board.h + * header file + */ + + pllfreq0 = M2PLLFREQ0(BOARD_PLL_MINT, BOARD_PLL_MFRAC); + pllfreq1 = QN2PLLFREQ1(BOARD_PLL_Q, BOARD_PLL_N); + tiva_clockconfig(pllfreq0, pllfreq1, BOARD_PLL_SYSDIV); + + /* Set up the alternate clock source + * + * The ALTCLK provides a clock source of numerous frequencies to the + * general-purpose timer, SSI, and UART modules. The default source for + * the ALTCLK is the Precision Internal Oscillator (PIOSC). The + * Hibernation Real-time Clock (RTCOSC) and Low Frequency Internal + * Oscillator (LFIOSC) are alternatives. If the RTCOSC Output is + * selected, the clock source must also be enabled in the Hibernation + * module. + */ + + putreg32(BOARD_ALTCLKCFG, TIVA_SYSCON_ALTCLKCFG); +} diff --git a/arch/arm/src/tiva/tm4c_ethernet.c b/arch/arm/src/tiva/tm4c_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..d8e73bec3a3266c4350d0b35443459f425f8d9ec --- /dev/null +++ b/arch/arm/src/tiva/tm4c_ethernet.c @@ -0,0 +1,4455 @@ +/**************************************************************************** + * arch/arm/src/tiva/tm4c_ethernet.c + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_TIVA_ETHERNET) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_NET_NOINTS +# include +#endif + +#include +#include +#include + +#ifdef CONFIG_TIVA_PHY_INTERRUPTS +# include +#endif + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_internal.h" + +#include "chip.h" +#include "tiva_gpio.h" +#include "tiva_syscontrol.h" +#include "tiva_enablepwr.h" +#include "tiva_enableclks.h" +#include "tiva_periphrdy.h" +#include "tiva_ethernet.h" + +#include "chip/tiva_pinmap.h" +#include + +/* TIVA_NETHCONTROLLERS determines the number of physical interfaces + * that will be supported. + */ + +#if TIVA_NETHCONTROLLERS > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#if TIVA_NETHCONTROLLERS > 1 +# error Logic to support multiple Ethernet interfaces is incomplete +#endif + +/* If processing is not done at the interrupt level, then high priority + * work queue support is required. + */ + +#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK) +# error High priority work queue support is required +#endif + +/* Are we using the internal PHY or an external PHY? */ + +#if defined(CONFIG_TIVA_PHY_INTERNAL) + +/* Internal PHY */ + +# if defined(CONFIG_TIVA_PHY_MII) ||defined(CONFIG_TIVA_PHY_RMII) +# warning CONFIG_TIVA_PHY_MII or CONFIG_TIVA_PHY_RMII defined with internal PHY +# endif + +# undef CONFIG_TIVA_PHY_MII +# undef CONFIG_TIVA_PHY_RMII + +/* Properties of the internal PHY are hard-coded */ + +# undef CONFIG_TIVA_PHYADDR +# undef CONFIG_TIVA_PHYSR_ALTCONFIG +# undef CONFIG_TIVA_PHYSR_ALTMODE +# undef CONFIG_TIVA_PHYSR_10HD +# undef CONFIG_TIVA_PHYSR_100HD +# undef CONFIG_TIVA_PHYSR_10FD +# undef CONFIG_TIVA_PHYSR_100FD +# undef CONFIG_TIVA_PHYSR_SPEED +# undef CONFIG_TIVA_PHYSR_100MBPS +# undef CONFIG_TIVA_PHYSR_MODE +# undef CONFIG_TIVA_PHYSR_FULLDUPLEX + +# define CONFIG_TIVA_PHYADDR 0 +# define CONFIG_TIVA_PHYSR TIVA_EPHY_STS +# define CONFIG_TIVA_PHYSR_SPEED EPHY_STS_SPEED +# define CONFIG_TIVA_PHYSR_100MBPS 0 +# define CONFIG_TIVA_PHYSR_MODE EPHY_STS_DUPLEX +# define CONFIG_TIVA_PHYSR_FULLDUPLEX EPHY_STS_DUPLEX + +#else + +/* External PHY. Properties must be provided in the configuration */ + +# if !defined(CONFIG_TIVA_PHY_MII) && !defined(CONFIG_TIVA_PHY_RMII) +# warning None of CONFIG_TIVA_PHY_INTERNAL, CONFIG_TIVA_PHY_MII, or CONFIG_TIVA_PHY_RMII defined +# endif + +# if defined(CONFIG_TIVA_PHY_MII) && defined(CONFIG_TIVA_PHY_RMII) +# error Both CONFIG_TIVA_PHY_MII and CONFIG_TIVA_PHY_RMII defined +# endif +#endif + +#ifndef CONFIG_TIVA_PHYADDR +# error CONFIG_TIVA_PHYADDR must be defined in the NuttX configuration +#endif + +#ifdef CONFIG_TIVA_AUTONEG +# ifndef CONFIG_TIVA_PHYSR +# error CONFIG_TIVA_PHYSR must be defined in the NuttX configuration +# endif +# ifdef CONFIG_TIVA_PHYSR_ALTCONFIG +# ifndef CONFIG_TIVA_PHYSR_ALTMODE +# error CONFIG_TIVA_PHYSR_ALTMODE must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_10HD +# error CONFIG_TIVA_PHYSR_10HD must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_100HD +# error CONFIG_TIVA_PHYSR_100HD must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_10FD +# error CONFIG_TIVA_PHYSR_10FD must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_100FD +# error CONFIG_TIVA_PHYSR_100FD must be defined in the NuttX configuration +# endif +# else +# ifndef CONFIG_TIVA_PHYSR_SPEED +# error CONFIG_TIVA_PHYSR_SPEED must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_100MBPS +# error CONFIG_TIVA_PHYSR_100MBPS must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_MODE +# error CONFIG_TIVA_PHYSR_MODE must be defined in the NuttX configuration +# endif +# ifndef CONFIG_TIVA_PHYSR_FULLDUPLEX +# error CONFIG_TIVA_PHYSR_FULLDUPLEX must be defined in the NuttX configuration +# endif +# endif +#endif + +#ifdef CONFIG_TIVA_EMAC_PTP +# warning CONFIG_TIVA_EMAC_PTP is not yet supported +#endif + +/* This driver does not use enhanced descriptors. Enhanced descriptors must + * be used, however, if time stamping or and/or IPv4 checksum offload is + * supported. + */ + +#undef CONFIG_TIVA_EMAC_ENHANCEDDESC +#undef CONFIG_TIVA_EMAC_HWCHECKSUM + +/* Ethernet buffer sizes, number of buffers, and number of descriptors */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error CONFIG_NET_MULTIBUFFER is required +#endif + +#ifndef CONFIG_TIVA_EMAC_NRXDESC +# define CONFIG_TIVA_EMAC_NRXDESC 8 +#endif + +#ifndef CONFIG_TIVA_EMAC_NTXDESC +# define CONFIG_TIVA_EMAC_NTXDESC 4 +#endif + +/* Add 4 to the configured buffer size to account for the 2 byte checksum + * memory needed at the end of the maximum size packet. Buffer sizes must + * be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We + * will use the 16-byte alignment in all cases. + */ + +#define OPTIMAL_EMAC_BUFSIZE ((CONFIG_NET_ETH_MTU + 4 + 15) & ~15) + +#if OPTIMAL_EMAC_BUFSIZE > EMAC_TDES1_TBS1_MASK +# error OPTIMAL_EMAC_BUFSIZE is too large +#endif + +#if (OPTIMAL_EMAC_BUFSIZE & 15) != 0 +# error OPTIMAL_EMAC_BUFSIZE must be aligned +#endif + +#if OPTIMAL_EMAC_BUFSIZE != OPTIMAL_EMAC_BUFSIZE +# warning You using an incomplete/untested configuration +#endif + +/* We need at least one more free buffer than transmit buffers */ + +#define TIVA_EMAC_NFREEBUFFERS (CONFIG_TIVA_EMAC_NTXDESC+1) + +/* Extremely detailed register debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_TIVA_ETHERNET_REGDEBUG +#endif + +/* Clocking *****************************************************************/ +/* Set MIIADDR CR bits depending on SysClk frequency */ + +#if SYSCLK_FREQUENCY >= 20000000 && SYSCLK_FREQUENCY < 35000000 +# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_20_35 +#elif SYSCLK_FREQUENCY >= 35000000 && SYSCLK_FREQUENCY <= 64000000 +# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_35_60 +#elif SYSCLK_FREQUENCY >= 60000000 && SYSCLK_FREQUENCY <= 104000000 +# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_60_100 +#elif SYSCLK_FREQUENCY >= 100000000 && SYSCLK_FREQUENCY <= 150000000 +# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_100_150 +#elif SYSCLK_FREQUENCY >= 150000000 && SYSCLK_FREQUENCY <= 168000000 +# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_150_168 +#else +# error SYSCLK_FREQUENCY not supportable +#endif + +/* Timing *******************************************************************/ +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per + * second + */ + +#define TIVA_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define TIVA_TXTIMEOUT (60*CLK_TCK) + +/* PHY reset/configuration delays in milliseconds */ + +#define PHY_RESET_DELAY (65) +#define PHY_CONFIG_DELAY (1000) + +/* PHY read/write delays in loop counts */ + +#define PHY_READ_TIMEOUT (0x0004ffff) +#define PHY_WRITE_TIMEOUT (0x0004ffff) +#define PHY_RETRY_TIMEOUT (0x0004ffff) + +/* Register values **********************************************************/ + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * EMAC_CFG_RE Bit 2: Receiver enable + * EMAC_CFG_TE Bit 3: Transmitter enable + * EMAC_CFG_DC Bit 4: Deferral check + * EMAC_CFG_BL Bits 5-6: Back-off limit + * EMAC_CFG_ACS Bit 7: Automatic pad/CRC stripping + * EMAC_CFG_DR Bit 9: Retry disable + * EMAC_CFG_IPC Bit 10: IPv4 checksum offload + * EMAC_CFG_DUPM Bit 11: Duplex mode + * EMAC_CFG_LOOPBM Bit 12: Loopback mode + * EMAC_CFG_DRO Bit 13: Receive own disable + * EMAC_CFG_FES Bit 14: Fast Ethernet speed + * EMAC_CFG_PS Bit 15: Port Select + * EMAC_CFG_DISCRS Bit 16: Carrier sense disable + * EMAC_CFG_IFG Bits 17-19: Interframe gap + * EMAC_CFG_JFEN Bit 20: Jumbo Frame Enable + * EMAC_CFG_JD Bit 22: Jabber disable + * EMAC_CFG_WDDIS Bit 23: Watchdog disable + * EMAC_CFG_CST Bit 25: CRC stripping for Type frames + * EMAC_CFG_TWOKPEN Bit 27: IEEE 802 + * EMAC_CFG_SADDR Bits 28-30: Source Address Insertion or Replacement Control + */ + +#define MACCR_CLEAR_BITS \ + (EMAC_CFG_RE | EMAC_CFG_TE | EMAC_CFG_DC | EMAC_CFG_BL_MASK | \ + EMAC_CFG_ACS | EMAC_CFG_DR | EMAC_CFG_IPC | EMAC_CFG_DUPM | \ + EMAC_CFG_LOOPBM | EMAC_CFG_DRO | EMAC_CFG_FES | EMAC_CFG_DISCRS | \ + EMAC_CFG_IFG_MASK | EMAC_CFG_JD | EMAC_CFG_WDDIS | EMAC_CFG_CST) + +/* The following bits are set or left zero unconditionally in all modes. + * + * EMAC_CFG_RE Receiver enable 0 (disabled) + * EMAC_CFG_TE Transmitter enable 0 (disabled) + * EMAC_CFG_DC Deferral check 0 (disabled) + * EMAC_CFG_BL Back-off limit 0 (10) + * EMAC_CFG_ACS Automatic pad/CRC stripping 0 (disabled) + * EMAC_CFG_DR Retry disable 1 (disabled) + * EMAC_CFG_IPC IPv4 checksum offload Depends on CONFIG_TIVA_EMAC_HWCHECKSUM + * EMAC_CFG_LOOPBM Loopback mode 0 (disabled) + * EMAC_CFG_DRO Receive own disable 0 (enabled) + * EMAC_CFG_PS Port Select (read-only) + * EMAC_CFG_DISCRS Carrier sense disable 0 (enabled) + * EMAC_CFG_IFG Interframe gap 0 (96 bits) + * EMAC_CFG_JFEN Jumbo Frame Enable 0 (jumbo frame creates error) + * EMAC_CFG_JD Jabber disable 0 (enabled) + * EMAC_CFG_WDDIS Watchdog disable 0 (enabled) + * EMAC_CFG_CST CRC stripping for Type frames 0 (disabled, F2/F4 only) + * EMAC_CFG_TWOKPEN IEEE 802 0 (>1518 == giant frame) + * EMAC_CFG_SADDR Source Address Insertion or + * Replacement Control + * + * The following are set conditionally based on mode and speed. + * + * EMAC_CFG_DUPM Duplex mode Depends on priv->fduplex + * EMAC_CFG_FES Fast Ethernet speed Depends on priv->mbps100 + */ + +#ifdef CONFIG_TIVA_EMAC_HWCHECKSUM +# define MACCR_SET_BITS \ + (EMAC_CFG_BL_10 | EMAC_CFG_DR | EMAC_CFG_IPC | EMAC_CFG_IFG_96) +#else +# define MACCR_SET_BITS \ + (EMAC_CFG_BL_10 | EMAC_CFG_DR | EMAC_CFG_IFG_96) +#endif + +/* Clear the MACCR bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * EMAC_FRAMEFLTR_PR Bit 0: Promiscuous mode + * EMAC_FRAMEFLTR_HUC Bit 1: Hash unicast + * EMAC_FRAMEFLTR_HMC Bit 2: Hash multicast + * EMAC_FRAMEFLTR_DAIF Bit 3: Destination address inverse filtering + * EMAC_FRAMEFLTR_PM Bit 4: Pass all multicast + * EMAC_FRAMEFLTR_DBF Bit 5: Broadcast frames disable + * EMAC_FRAMEFLTR_PCF Bits 6-7: Pass control frames + * EMAC_FRAMEFLTR_SAIF Bit 8: Source address inverse filtering + * EMAC_FRAMEFLTR_SAF Bit 9: Source address filter + * EMAC_FRAMEFLTR_HPF Bit 10: Hash or perfect filter + * EMAC_FRAMEFLTR_VTFE Bit 16: VLAN Tag Filter Enable + * EMAC_FRAMEFLTR_RA Bit 31: Receive all + */ + +#define FRAMEFLTR_CLEAR_BITS \ + (EMAC_FRAMEFLTR_PR | EMAC_FRAMEFLTR_HUC | EMAC_FRAMEFLTR_HMC | EMAC_FRAMEFLTR_DAIF | \ + EMAC_FRAMEFLTR_PM | EMAC_FRAMEFLTR_DBF | EMAC_FRAMEFLTR_PCF_MASK | EMAC_FRAMEFLTR_SAIF | \ + EMAC_FRAMEFLTR_SAF | EMAC_FRAMEFLTR_HPF | EMAC_FRAMEFLTR_RA) + +/* The following bits are set or left zero unconditionally in all modes. + * + * EMAC_FRAMEFLTR_PR Promiscuous mode 0 (disabled) + * EMAC_FRAMEFLTR_HUC Hash unicast 0 (perfect dest filtering) + * EMAC_FRAMEFLTR_HMC Hash multicast 0 (perfect dest filtering) + * EMAC_FRAMEFLTR_DAIF Destination address inverse filtering 0 (normal) + * EMAC_FRAMEFLTR_PM Pass all multicast 0 (Depends on HM bit) + * EMAC_FRAMEFLTR_DBF Broadcast frames disable 0 (enabled) + * EMAC_FRAMEFLTR_PCF Pass control frames 1 (block all but PAUSE) + * EMAC_FRAMEFLTR_SAIF Source address inverse filtering 0 (not used) + * EMAC_FRAMEFLTR_SAF Source address filter 0 (disabled) + * EMAC_FRAMEFLTR_HPF Hash or perfect filter 0 (Only matching frames passed) + * EMAC_FRAMEFLTR_VTFE VLAN Tag Filter Enable 0 (VLAN tag ignored) + * EMAC_FRAMEFLTR_RA Receive all 0 (disabled) + */ + +#define FRAMEFLTR_SET_BITS (EMAC_FRAMEFLTR_PCF_PAUSE) + +/* Clear the FLOWCTL bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * EMAC_FLOWCTL_FCBBPA Bit 0: Flow control busy/back pressure activate + * EMAC_FLOWCTL_TFE Bit 1: Transmit flow control enable + * EMAC_FLOWCTL_RFE Bit 2: Receive flow control enable + * EMAC_FLOWCTL_UP Bit 3: Unicast pause frame detect + * EMAC_FLOWCTL_PLT Bits 4-5: Pause low threshold + * EMAC_FLOWCTL_DZQP Bit 7: Zero-quanta pause disable + * EMAC_FLOWCTL_PT Bits 16-31: Pause time + */ + +#define FLOWCTL_CLEAR_MASK \ + (EMAC_FLOWCTL_FCBBPA | EMAC_FLOWCTL_TFE | EMAC_FLOWCTL_RFE | EMAC_FLOWCTL_UP | \ + EMAC_FLOWCTL_PLT_MASK | EMAC_FLOWCTL_DZQP | EMAC_FLOWCTL_PT_MASK) + +/* The following bits are set or left zero unconditionally in all modes. + * + * EMAC_FLOWCTL_FCBBPA Flow control busy/back pressure activate 0 (no pause control frame) + * EMAC_FLOWCTL_TFE Transmit flow control enable 0 (disabled) + * EMAC_FLOWCTL_RFE Receive flow control enable 0 (disabled) + * EMAC_FLOWCTL_UP Unicast pause frame detect 0 (disabled) + * EMAC_FLOWCTL_PLT Pause low threshold 0 (pause time - 4) + * EMAC_FLOWCTL_DZQP Zero-quanta pause disable 1 (disabled) + * EMAC_FLOWCTL_PT Pause time 0 + */ + +#define FLOWCTL_SET_MASK (EMAC_FLOWCTL_PLT_M4 | EMAC_FLOWCTL_DZQP) + +/* Clear the DMAOPMODE bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * EMAC_DMAOPMODE_SR Bit 1: Start/stop receive + * EMAC_DMAOPMODE_OSF Bit 2: Operate on second frame + * EMAC_DMAOPMODE_RTC Bits 3-4: Receive threshold control + * EMAC_DMAOPMODE_DGF Bit 5: Drop giant frames enable + * EMAC_DMAOPMODE_FUF Bit 6: Forward undersized good frames + * EMAC_DMAOPMODE_FEF Bit 7: Forward error frames + * EMAC_DMAOPMODE_ST Bit 13: Start/stop transmission + * EMAC_DMAOPMODE_TTC Bits 14-16: Transmit threshold control + * EMAC_DMAOPMODE_FTF Bit 20: Flush transmit FIFO + * EMAC_DMAOPMODE_TSF Bit 21: Transmit store and forward + * EMAC_DMAOPMODE_DFF Bit 24: Disable flushing of received frames + * EMAC_DMAOPMODE_RSF Bit 25: Receive store and forward + * EMAC_DMAOPMODE_DT Bit 26: Dropping of TCP/IP checksum error frames disable + */ + +#define DMAOPMODE_CLEAR_MASK \ + (EMAC_DMAOPMODE_SR | EMAC_DMAOPMODE_OSF | EMAC_DMAOPMODE_RTC_MASK | EMAC_DMAOPMODE_DGF | \ + EMAC_DMAOPMODE_FUF | EMAC_DMAOPMODE_FEF | EMAC_DMAOPMODE_ST | EMAC_DMAOPMODE_TTC_MASK | \ + EMAC_DMAOPMODE_FTF | EMAC_DMAOPMODE_TSF | EMAC_DMAOPMODE_DFF | EMAC_DMAOPMODE_RSF | \ + EMAC_DMAOPMODE_DT) + +/* The following bits are set or left zero unconditionally in all modes. + * + * EMAC_DMAOPMODE_SR Start/stop receive 0 (not running) + * EMAC_DMAOPMODE_OSF Operate on second frame 1 (enabled) + * EMAC_DMAOPMODE_RTC Receive threshold control 0 (64 bytes) + * EMAC_DMAOPMODE_FUF Forward undersized good frames 0 (disabled) + * EMAC_DMAOPMODE_FEF Forward error frames 0 (disabled) + * EMAC_DMAOPMODE_ST Start/stop transmission 0 (not running) + * EMAC_DMAOPMODE_TTC Transmit threshold control 0 (64 bytes) + * EMAC_DMAOPMODE_FTF Flush transmit FIFO 0 (no flush) + * EMAC_DMAOPMODE_TSF Transmit store and forward Depends on CONFIG_TIVA_EMAC_HWCHECKSUM + * EMAC_DMAOPMODE_DFF Disable flushing of received frames 0 (enabled) + * EMAC_DMAOPMODE_RSF Receive store and forward Depends on CONFIG_TIVA_EMAC_HWCHECKSUM + * EMAC_DMAOPMODE_DT Dropping of TCP/IP checksum error Depends on CONFIG_TIVA_EMAC_HWCHECKSUM + * frames disable + * + * When the checksum offload feature is enabled, we need to enable the Store + * and Forward mode: the store and forward guarantee that a whole frame is + * stored in the FIFO, so the MAC can insert/verify the checksum, if the + * checksum is OK the DMA can handle the frame otherwise the frame is dropped + */ + +#ifdef CONFIG_TIVA_EMAC_HWCHECKSUM +# define DMAOPMODE_SET_MASK \ + (EMAC_DMAOPMODE_OSF | EMAC_DMAOPMODE_RTC_64 | EMAC_DMAOPMODE_TTC_64 | \ + EMAC_DMAOPMODE_TSF | EMAC_DMAOPMODE_RSF) +#else +# define DMAOPMODE_SET_MASK \ + (EMAC_DMAOPMODE_OSF | EMAC_DMAOPMODE_RTC_64 | EMAC_DMAOPMODE_TTC_64 | \ + EMAC_DMAOPMODE_DT) +#endif + +/* Clear the DMABUSMOD bits that will be setup during MAC initialization (or that + * are cleared unconditionally). Per the reference manual, all reserved bits + * must be retained at their reset value. + * + * EMAC_DMABUSMOD_SWR Bit 0: Software reset + * EMAC_DMABUSMOD_DA Bit 1: DMA Arbitration + * EMAC_DMABUSMOD_DSL Bits 2-6: Descriptor skip length + * EMAC_DMABUSMOD_ATDS Bit 7: Enhanced descriptor format enable + * EMAC_DMABUSMOD_PBL Bits 8-13: Programmable burst length + * EMAC_DMABUSMOD_PR Bits 14-15: RX TX priority ratio + * EMAC_DMABUSMOD_FB Bit 16: Fixed burst + * EMAC_DMABUSMOD_RPBL Bits 17-22: RX DMA programmable bust length + * EMAC_DMABUSMOD_USP Bit 23: Use separate PBL + * EMAC_DMABUSMOD_8XPBL Bit 24: 8x programmable burst length mode + * EMAC_DMABUSMOD_AAL Bit 25: Address-aligned beats + * EMAC_DMABUSMOD_MB Bit 26: Mixed burst (F2/F4 only) + * EMAC_DMABUSMOD_TXPR Bit 27: Transmit Priority + * EMAC_DMABUSMOD_RIB Bit 31: Rebuild Burst + */ + +#define DMABUSMOD_CLEAR_MASK \ + (EMAC_DMABUSMOD_SWR | EMAC_DMABUSMOD_DA | EMAC_DMABUSMOD_DSL_MASK | \ + EMAC_DMABUSMOD_ATDS | EMAC_DMABUSMOD_PBL_MASK | EMAC_DMABUSMOD_PR_MASK | \ + EMAC_DMABUSMOD_FB | EMAC_DMABUSMOD_RPBL_MASK | EMAC_DMABUSMOD_USP | \ + EMAC_DMABUSMOD_8XPBL | EMAC_DMABUSMOD_AAL | EMAC_DMABUSMOD_MB | \ + EMAC_DMABUSMOD_TXPR | EMAC_DMABUSMOD_RIB) + +/* The following bits are set or left zero unconditionally in all modes. + * + * EMAC_DMABUSMOD_SWR Software reset 0 (no reset) + * EMAC_DMABUSMOD_DA DMA Arbitration 1 (fixed priority) + * EMAC_DMABUSMOD_DSL Descriptor skip length 0 + * EMAC_DMABUSMOD_ATDS Enhanced descriptor format enable Depends on CONFIG_TIVA_EMAC_ENHANCEDDESC + * EMAC_DMABUSMOD_PBL Programmable burst length Depends on EMAC_DMA_RXBURST + * EMAC_DMABUSMOD_PR RX TX priority ratio 0 1:1 + * EMAC_DMABUSMOD_FB Fixed burst 0 (disabled) + * EMAC_DMABUSMOD_RPBL RX DMA programmable burst length Depends on EMAC_DMA_TXBURST + * EMAC_DMABUSMOD_USP Use separate PBL Depends on EMAC_DMA_RX/TXBURST + * EMAC_DMABUSMOD_8XPBL 8x programmable burst length mode Depends on EMAC_DMA_RX/TXBURST + * EMAC_DMABUSMOD_AAL Address-aligned beats 0 (disabled) + * EMAC_DMABUSMOD_MB Mixed burst 1 (enabled) + * EMAC_DMABUSMOD_TXPR Transmit Priority 0 (RX DMA has priority over TX) + * EMAC_DMABUSMOD_RIB Rebuild Burst 0 + */ + +#define EMAC_DMA_RXBURST 4 +#define EMAC_DMA_TXBURST 4 + +#if EMAC_DMA_RXBURST > 32 || EMAC_DMA_TXBURST > 32 +# define __EMAC_DMABUSMOD_8XPBL 0 +# define __EMAC_DMA_RXBURST EMAC_DMA_RXBURST +# define __EMAC_DMA_TXBURST EMAC_DMA_TXBURST +#else + /* Divide both burst lengths by 8 and set the 8X burst length multiplier */ + +# define __EMAC_DMABUSMOD_8XPBL EMAC_DMABUSMOD_8XPBL +# define __EMAC_DMA_RXBURST (EMAC_DMA_RXBURST >> 3) +# define __EMAC_DMA_TXBURST (EMAC_DMA_TXBURST >> 3) +#endif + +#define __EMAC_DMABUSMOD_PBL EMAC_DMABUSMOD_PBL(__EMAC_DMA_RXBURST) + +/* Are the receive and transmit burst lengths the same? */ + +#if __EMAC_DMA_RXBURST == __EMAC_DMA_TXBURST + /* Yes.. Set up to use a single burst length */ + +# define __EMAC_DMABUSMOD_USP 0 +# define __EMAC_DMABUSMOD_RPBL 0 +#else + /* No.. Use separate burst lengths for each */ + +# define __EMAC_DMABUSMOD_USP EMAC_DMABUSMOD_USP +# define __EMAC_DMABUSMOD_RPBL EMAC_DMABUSMOD_RPBL(__EMAC_DMA_TXBURST) +#endif + +#ifdef CONFIG_TIVA_EMAC_ENHANCEDDESC +# define __EMAC_DMABUSMOD_ATDS EMAC_DMABUSMOD_ATDS +#else +# define __EMAC_DMABUSMOD_ATDS 0 +#endif + +#define DMABUSMOD_SET_MASK \ + (EMAC_DMABUSMOD_DA | EMAC_DMABUSMOD_DSL(0) | __EMAC_DMABUSMOD_ATDS | \ + __EMAC_DMABUSMOD_PBL | __EMAC_DMABUSMOD_RPBL | __EMAC_DMABUSMOD_USP | \ + __EMAC_DMABUSMOD_8XPBL | EMAC_DMABUSMOD_MB) + +/* Interrupt bit sets *******************************************************/ +/* All interrupts in the normal and abnormal interrupt summary. Early transmit + * interrupt (ETI) is excluded from the abnormal set because it causes too + * many interrupts and is not interesting. + */ + +#define EMAC_DMAINT_NORMAL \ + (EMAC_DMAINT_TI | EMAC_DMAINT_TBUI | EMAC_DMAINT_RI | EMAC_DMAINT_ERI) + +#define EMAC_DMAINT_ABNORMAL \ + (EMAC_DMAINT_TPSI | EMAC_DMAINT_TJTI | EMAC_DMAINT_OVFI | EMAC_EMAINT_UNFI | \ + EMAC_DMAINT_RBUI | EMAC_DMAINT_RPSI | EMAC_DMAINT_RWTI | /* EMAC_DMAINT_ETI | */ \ + EMAC_DMAINT_FBEI) + +/* Normal receive, transmit, error interrupt enable bit sets */ + +#define EMAC_DMAINT_RECV_ENABLE (EMAC_DMAINT_NIS | EMAC_DMAINT_RI) +#define EMAC_DMAINT_XMIT_ENABLE (EMAC_DMAINT_NIS | EMAC_DMAINT_TI) +#define EMAC_DMAINT_XMIT_DISABLE (EMAC_DMAINT_TI) + +#ifdef CONFIG_DEBUG_NET +# define EMAC_DMAINT_ERROR_ENABLE (EMAC_DMAINT_AIS | EMAC_DMAINT_ABNORMAL) +#else +# define EMAC_DMAINT_ERROR_ENABLE (0) +#endif + +/* Helpers ******************************************************************/ +/* This is a helper pointer for accessing the contents of the Ethernet + * header + */ + +#define BUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The tiva_ethmac_s encapsulates all state information for a single hardware + * interface + */ + +struct tiva_ethmac_s +{ + uint8_t ifup : 1; /* true:ifup false:ifdown */ + uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */ + uint8_t fduplex : 1; /* Full (vs. half) duplex */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ +#ifdef CONFIG_NET_NOINTS + struct work_s work; /* For deferring work to the work queue */ +#endif +#ifdef CONFIG_TIVA_PHY_INTERRUPTS + xcpt_t handler; /* Attached PHY interrupt handler */ +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by network subsystem */ + + /* Used to track transmit and receive descriptors */ + + struct emac_txdesc_s *txhead; /* Next available TX descriptor */ + struct emac_rxdesc_s *rxhead; /* Next available RX descriptor */ + + struct emac_txdesc_s *txtail; /* First "in_flight" TX descriptor */ + struct emac_rxdesc_s *rxcurr; /* First RX descriptor of the segment */ + uint16_t segments; /* RX segment count */ + uint16_t inflight; /* Number of TX transfers "in_flight" */ + sq_queue_t freeb; /* The free buffer list */ + + /* Descriptor allocations */ + + struct emac_rxdesc_s rxtable[CONFIG_TIVA_EMAC_NRXDESC]; + struct emac_txdesc_s txtable[CONFIG_TIVA_EMAC_NTXDESC]; + + /* Buffer allocations */ + + uint8_t rxbuffer[CONFIG_TIVA_EMAC_NRXDESC*OPTIMAL_EMAC_BUFSIZE]; + uint8_t alloc[TIVA_EMAC_NFREEBUFFERS*OPTIMAL_EMAC_BUFSIZE]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct tiva_ethmac_s g_tiva_ethmac[TIVA_NETHCONTROLLERS]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Register operations ******************************************************/ + +#if defined(CONFIG_TIVA_ETHERNET_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t tiva_getreg(uint32_t addr); +static void tiva_putreg(uint32_t val, uint32_t addr); +static void tiva_checksetup(void); +#else +# define tiva_getreg(addr) getreg32(addr) +# define tiva_putreg(val,addr) putreg32(val,addr) +# define tiva_checksetup() +#endif + +/* Free buffer management */ + +static void tiva_initbuffer(FAR struct tiva_ethmac_s *priv); +static inline uint8_t *tiva_allocbuffer(FAR struct tiva_ethmac_s *priv); +static inline void tiva_freebuffer(FAR struct tiva_ethmac_s *priv, uint8_t *buffer); +static inline bool tiva_isfreebuffer(FAR struct tiva_ethmac_s *priv); + +/* Common TX logic */ + +static int tiva_transmit(FAR struct tiva_ethmac_s *priv); +static int tiva_txpoll(struct net_driver_s *dev); +static void tiva_dopoll(FAR struct tiva_ethmac_s *priv); + +/* Interrupt handling */ + +static void tiva_enableint(FAR struct tiva_ethmac_s *priv, uint32_t ierbit); +static void tiva_disableint(FAR struct tiva_ethmac_s *priv, uint32_t ierbit); + +static void tiva_freesegment(FAR struct tiva_ethmac_s *priv, + FAR struct emac_rxdesc_s *rxfirst, int segments); +static int tiva_recvframe(FAR struct tiva_ethmac_s *priv); +static void tiva_receive(FAR struct tiva_ethmac_s *priv); +static void tiva_freeframe(FAR struct tiva_ethmac_s *priv); +static void tiva_txdone(FAR struct tiva_ethmac_s *priv); +static inline void tiva_interrupt_process(FAR struct tiva_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void tiva_interrupt_work(FAR void *arg); +#endif +static int tiva_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static inline void tiva_txtimeout_process(FAR struct tiva_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void tiva_txtimeout_work(FAR void *arg); +#endif +static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...); + +static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void tiva_poll_work(FAR void *arg); +#endif +static void tiva_poll_expiry(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int tiva_ifup(struct net_driver_s *dev); +static int tiva_ifdown(struct net_driver_s *dev); +static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv); +#ifdef CONFIG_NET_NOINTS +static void tiva_txavail_work(FAR void *arg); +#endif +static int tiva_txavail(struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NET_IGMP +static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int tiva_ioctl(struct net_driver_s *dev, int cmd, long arg); +#endif + +/* Descriptor Initialization */ + +static void tiva_txdescinit(FAR struct tiva_ethmac_s *priv); +static void tiva_rxdescinit(FAR struct tiva_ethmac_s *priv); + +/* PHY Initialization */ + +#ifdef CONFIG_TIVA_PHY_INTERRUPTS +static void tiva_phy_intenable(bool enable); +#endif +static int tiva_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value); +static int tiva_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value); +static int tiva_phyinit(FAR struct tiva_ethmac_s *priv); + +/* MAC/DMA Initialization */ + +static void tiva_phy_configure(FAR struct tiva_ethmac_s *priv); +static inline void tiva_phy_initialize(FAR struct tiva_ethmac_s *priv); + +static void tiva_ethreset(FAR struct tiva_ethmac_s *priv); +static int tiva_macconfig(FAR struct tiva_ethmac_s *priv); +static void tiva_macaddress(FAR struct tiva_ethmac_s *priv); +#ifdef CONFIG_NET_ICMPv6 +static void tiva_ipv6multicast(FAR struct tiva_ethmac_s *priv); +#endif +static int tiva_macenable(FAR struct tiva_ethmac_s *priv); +static int tive_emac_configure(FAR struct tiva_ethmac_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: tiva_getreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * addr - The register address to read + * + * Returned Value: + * The value read from the register + * + ****************************************************************************/ + +#if defined(CONFIG_TIVA_ETHERNET_REGDEBUG) && defined(CONFIG_DEBUG) +static uint32_t tiva_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: tiva_putreg + * + * Description: + * This function may to used to intercept an monitor all register accesses. + * Clearly this is nothing you would want to do unless you are debugging + * this driver. + * + * Input Parameters: + * val - The value to write to the register + * addr - The register address to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_TIVA_ETHERNET_REGDEBUG) && defined(CONFIG_DEBUG) +static void tiva_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: tiva_checksetup + * + * Description: + * Show the state of critical configuration registers. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_TIVA_ETHERNET_REGDEBUG) && defined(CONFIG_DEBUG) +static void tiva_checksetup(void) +{ +} +#endif + +/**************************************************************************** + * Function: tiva_initbuffer + * + * Description: + * Initialize the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called during early driver initialization before Ethernet interrupts + * are enabled. + * + ****************************************************************************/ + +static void tiva_initbuffer(FAR struct tiva_ethmac_s *priv) +{ + uint8_t *buffer; + int i; + + /* Initialize the head of the free buffer list */ + + sq_init(&priv->freeb); + + /* Add all of the pre-allocated buffers to the free buffer list */ + + for (i = 0, buffer = priv->alloc; + i < TIVA_EMAC_NFREEBUFFERS; + i++, buffer += OPTIMAL_EMAC_BUFSIZE) + { + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); + } +} + +/**************************************************************************** + * Function: tiva_allocbuffer + * + * Description: + * Allocate one buffer from the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * Pointer to the allocated buffer on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline uint8_t *tiva_allocbuffer(FAR struct tiva_ethmac_s *priv) +{ + /* Allocate a buffer by returning the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->freeb); +} + +/**************************************************************************** + * Function: tiva_freebuffer + * + * Description: + * Return a buffer to the free buffer list. + * + * Parameters: + * priv - Reference to the driver state structure + * buffer - A pointer to the buffer to be freed + * + * Returned Value: + * None + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static inline void tiva_freebuffer(FAR struct tiva_ethmac_s *priv, uint8_t *buffer) +{ + /* Free the buffer by adding it to to the end of the free buffer list */ + + sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb); +} + +/**************************************************************************** + * Function: tiva_isfreebuffer + * + * Description: + * Return TRUE if the free buffer list is not empty. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * True if there are one or more buffers in the free buffer list; + * false if the free buffer list is empty + * + * Assumptions: + * None. + * + ****************************************************************************/ + +static inline bool tiva_isfreebuffer(FAR struct tiva_ethmac_s *priv) +{ + /* Return TRUE if the free buffer list is not empty */ + + return !sq_empty(&priv->freeb); +} + +/**************************************************************************** + * Function: tiva_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int tiva_transmit(FAR struct tiva_ethmac_s *priv) +{ + struct emac_txdesc_s *txdesc; + struct emac_txdesc_s *txfirst; + + /* The internal (optimal) uIP buffer size may be configured to be larger + * than the Ethernet buffer size. + */ + +#if OPTIMAL_EMAC_BUFSIZE > OPTIMAL_EMAC_BUFSIZE + uint8_t *buffer; + int bufcount; + int lastsize; + int i; +#endif + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + txdesc = priv->txhead; + txfirst = txdesc; + + nvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n", + priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0); + + DEBUGASSERT(txdesc && (txdesc->tdes0 & EMAC_TDES0_OWN) == 0); + + /* Is the size to be sent greater than the size of the Ethernet buffer? */ + + DEBUGASSERT(priv->dev.d_len > 0 && priv->dev.d_buf != NULL); + +#if OPTIMAL_EMAC_BUFSIZE > OPTIMAL_EMAC_BUFSIZE + if (priv->dev.d_len > OPTIMAL_EMAC_BUFSIZE) + { + /* Yes... how many buffers will be need to send the packet? */ + + bufcount = (priv->dev.d_len + (OPTIMAL_EMAC_BUFSIZE-1)) / OPTIMAL_EMAC_BUFSIZE; + lastsize = priv->dev.d_len - (bufcount - 1) * OPTIMAL_EMAC_BUFSIZE; + + nvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize); + + /* Set the first segment bit in the first TX descriptor */ + + txdesc->tdes0 |= EMAC_TDES0_FS; + + /* Set up all but the last TX descriptor */ + + buffer = priv->dev.d_buf; + + for (i = 0; i < bufcount; i++) + { + /* This could be a normal event but the design does not handle it */ + + DEBUGASSERT((txdesc->tdes0 & EMAC_TDES0_OWN) == 0); + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)buffer; + + /* Set the buffer size in all TX descriptors */ + + if (i == (bufcount-1)) + { + /* This is the last segment. Set the last segment bit in the + * last TX descriptor and ask for an interrupt when this + * segment transfer completes. + */ + + txdesc->tdes0 |= (EMAC_TDES0_LS | EMAC_TDES0_IC); + + /* This segement is, most likely, of fractional buffersize */ + + txdesc->tdes1 = lastsize; + buffer += lastsize; + } + else + { + /* This is not the last segment. We don't want an interrupt + * when this segment transfer completes. + */ + + txdesc->tdes0 &= ~EMAC_TDES0_IC; + + /* The size of the transfer is the whole buffer */ + + txdesc->tdes1 = OPTIMAL_EMAC_BUFSIZE; + buffer += OPTIMAL_EMAC_BUFSIZE; + } + + /* Give the descriptor to DMA */ + + txdesc->tdes0 |= EMAC_TDES0_OWN; + txdesc = (struct emac_txdesc_s *)txdesc->tdes3; + } + } + else +#endif + { + /* The single descriptor is both the first and last segment. And we do + * want an interrupt when the transfer completes. + */ + + txdesc->tdes0 |= (EMAC_TDES0_FS | EMAC_TDES0_LS | EMAC_TDES0_IC); + + /* Set frame size */ + + DEBUGASSERT(priv->dev.d_len <= CONFIG_NET_ETH_MTU); + txdesc->tdes1 = priv->dev.d_len; + + /* Set the Buffer1 address pointer */ + + txdesc->tdes2 = (uint32_t)priv->dev.d_buf; + + /* Set OWN bit of the TX descriptor tdes0. This gives the buffer to + * Ethernet DMA + */ + + txdesc->tdes0 |= EMAC_TDES0_OWN; + + /* Point to the next available TX descriptor */ + + txdesc = (struct emac_txdesc_s *)txdesc->tdes3; + } + + /* Remember where we left off in the TX descriptor chain */ + + priv->txhead = txdesc; + + /* Detach the buffer from priv->dev structure. That buffer is now + * "in-flight". + */ + + priv->dev.d_buf = NULL; + priv->dev.d_len = 0; + + /* If there is no other TX buffer, in flight, then remember the location + * of the TX descriptor. This is the location to check for TX done events. + */ + + if (!priv->txtail) + { + DEBUGASSERT(priv->inflight == 0); + priv->txtail = txfirst; + } + + /* Increment the number of TX transfer in-flight */ + + priv->inflight++; + + nvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* If all TX descriptors are in-flight, then we have to disable receive interrupts + * too. This is because receive events can trigger more un-stoppable transmit + * events. + */ + + if (priv->inflight >= CONFIG_TIVA_EMAC_NTXDESC) + { + tiva_disableint(priv, EMAC_DMAINT_RI); + } + + /* Check if the TX Buffer unavailable flag is set */ + + if ((tiva_getreg(TIVA_EMAC_DMARIS) & EMAC_DMAINT_TBUI) != 0) + { + /* Clear TX Buffer unavailable flag */ + + tiva_putreg(EMAC_DMAINT_TBUI, TIVA_EMAC_DMARIS); + + /* Resume DMA transmission */ + + tiva_putreg(0, TIVA_EMAC_TXPOLLD); + } + + /* Enable TX interrupts */ + + tiva_enableint(priv, EMAC_DMAINT_TI); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, TIVA_TXTIMEOUT, tiva_txtimeout_expiry, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: tiva_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int tiva_txpoll(struct net_driver_s *dev) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private; + + DEBUGASSERT(priv->dev.d_buf != NULL); + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + tiva_transmit(priv); + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the TX poll if we are unable to accept another packet for + * transmission. + * + * In a race condition, EMAC_TDES0_OWN may be cleared BUT still not available + * because tiva_freeframe() has not yet run. If tiva_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_TIVA_EMAC_NTXDESC). + */ + + if ((priv->txhead->tdes0 & EMAC_TDES0_OWN) != 0 || + priv->txhead->tdes2 != 0) + { + /* We have to terminate the poll if we have no more descriptors + * available for another transfer. + */ + + return -EBUSY; + } + + /* We have the descriptor, we can continue the poll. Allocate a new + * buffer for the poll. + */ + + dev->d_buf = tiva_allocbuffer(priv); + + /* We can't continue the poll if we have no buffers */ + + if (dev->d_buf == NULL) + { + /* Terminate the poll. */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: tiva_dopoll + * + * Description: + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (tiva_txdone), + * 2. When new TX data is available (tiva_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (tiva_txtimeout_process). + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_dopoll(FAR struct tiva_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or + * CPU. We cannot perform the TX poll if we are unable to accept + * another packet for transmission. + * + * In a race condition, EMAC_TDES0_OWN may be cleared BUT still not available + * because tiva_freeframe() has not yet run. If tiva_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_TIVA_EMAC_NTXDESC). + */ + + if ((priv->txhead->tdes0 & EMAC_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then poll uIP for new XMIT data. + * Allocate a buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = tiva_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + (void)devif_poll(dev, tiva_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + tiva_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: tiva_enableint + * + * Description: + * Enable a "normal" interrupt + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_enableint(FAR struct tiva_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Enable the specified "normal" interrupt */ + + regval = tiva_getreg(TIVA_EMAC_DMAIM); + regval |= (EMAC_DMAINT_NIS | ierbit); + tiva_putreg(regval, TIVA_EMAC_DMAIM); +} + +/**************************************************************************** + * Function: tiva_disableint + * + * Description: + * Disable a normal interrupt. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_disableint(FAR struct tiva_ethmac_s *priv, uint32_t ierbit) +{ + uint32_t regval; + + /* Disable the "normal" interrupt */ + + regval = tiva_getreg(TIVA_EMAC_DMAIM); + regval &= ~ierbit; + + /* Are all "normal" interrupts now disabled? */ + + if ((regval & EMAC_DMAINT_NORMAL) == 0) + { + /* Yes.. disable normal interrupts */ + + regval &= ~EMAC_DMAINT_NIS; + } + + tiva_putreg(regval, TIVA_EMAC_DMAIM); +} + +/**************************************************************************** + * Function: tiva_freesegment + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors to the received frame. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_freesegment(FAR struct tiva_ethmac_s *priv, + FAR struct emac_rxdesc_s *rxfirst, int segments) +{ + struct emac_rxdesc_s *rxdesc; + int i; + + nvdbg("rxfirst: %p segments: %d\n", rxfirst, segments); + + /* Set OWN bit in RX descriptors. This gives the buffers back to DMA */ + + rxdesc = rxfirst; + for (i = 0; i < segments; i++) + { + rxdesc->rdes0 = EMAC_RDES0_OWN; + rxdesc = (struct emac_rxdesc_s *)rxdesc->rdes3; + } + + /* Reset the segment managment logic */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Check if the RX Buffer unavailable flag is set */ + + if ((tiva_getreg(TIVA_EMAC_DMARIS) & EMAC_DMAINT_RBUI) != 0) + { + /* Clear RBUS Ethernet DMA flag */ + + tiva_putreg(EMAC_DMAINT_RBUI, TIVA_EMAC_DMARIS); + + /* Resume DMA reception */ + + tiva_putreg(0, TIVA_EMAC_RXPOLLD); + } +} + +/**************************************************************************** + * Function: tiva_recvframe + * + * Description: + * The function is called when a frame is received using the DMA receive + * interrupt. It scans the RX descriptors of the received frame. + * + * NOTE: This function will silently discard any packets containing errors. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK if a packet was successfully returned; -EAGAIN if there are no + * further packets available + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static int tiva_recvframe(FAR struct tiva_ethmac_s *priv) +{ + struct emac_rxdesc_s *rxdesc; + struct emac_rxdesc_s *rxcurr; + uint8_t *buffer; + int i; + + nvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if there are free buffers. We cannot receive new frames in this + * design unless there is at least one free buffer. + */ + + if (!tiva_isfreebuffer(priv)) + { + nlldbg("No free buffers\n"); + return -ENOMEM; + } + + /* Scan descriptors owned by the CPU. Scan until: + * + * 1) We find a descriptor still owned by the DMA, + * 2) We have examined all of the RX descriptors, or + * 3) All of the TX descriptors are in flight. + * + * This last case is obscure. It is due to that fact that each packet + * that we receive can generate an unstoppable transmisson. So we have + * to stop receiving when we can not longer transmit. In this case, the + * transmit logic should also have disabled further RX interrupts. + */ + + rxdesc = priv->rxhead; + for (i = 0; + (rxdesc->rdes0 & EMAC_RDES0_OWN) == 0 && + i < CONFIG_TIVA_EMAC_NRXDESC && + priv->inflight < CONFIG_TIVA_EMAC_NTXDESC; + i++) + { + /* Check if this is the first segment in the frame */ + + if ((rxdesc->rdes0 & EMAC_RDES0_FS) != 0 && + (rxdesc->rdes0 & EMAC_RDES0_LS) == 0) + { + priv->rxcurr = rxdesc; + priv->segments = 1; + } + + /* Check if this is an intermediate segment in the frame */ + + else if (((rxdesc->rdes0 & EMAC_RDES0_LS) == 0) && + ((rxdesc->rdes0 & EMAC_RDES0_FS) == 0)) + { + priv->segments++; + } + + /* Otherwise, it is the last segment in the frame */ + + else + { + priv->segments++; + + /* Check if the there is only one segment in the frame */ + + if (priv->segments == 1) + { + rxcurr = rxdesc; + } + else + { + rxcurr = priv->rxcurr; + } + + nvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + /* Check if any errors are reported in the frame */ + + if ((rxdesc->rdes0 & EMAC_RDES0_ES) == 0) + { + struct net_driver_s *dev = &priv->dev; + + /* Get the Frame Length of the received packet: substruct 4 + * bytes of the CRC + */ + + dev->d_len = ((rxdesc->rdes0 & EMAC_RDES0_FL_MASK) >> EMAC_RDES0_FL_SHIFT) - 4; + + /* Get a buffer from the free list. We don't even check if + * this is successful because we already assure the free + * list is not empty above. + */ + + buffer = tiva_allocbuffer(priv); + + /* Take the buffer from the RX descriptor of the first free + * segment, put it into the uIP device structure, then replace + * the buffer in the RX descriptor with the newly allocated + * buffer. + */ + + DEBUGASSERT(dev->d_buf == NULL); + dev->d_buf = (uint8_t *)rxcurr->rdes2; + rxcurr->rdes2 = (uint32_t)buffer; + + /* Return success, remebering where we should re-start scanning + * and resetting the segment scanning logic + */ + + priv->rxhead = (struct emac_rxdesc_s *)rxdesc->rdes3; + tiva_freesegment(priv, rxcurr, priv->segments); + + nvdbg("rxhead: %p d_buf: %p d_len: %d\n", + priv->rxhead, dev->d_buf, dev->d_len); + + return OK; + } + else + { + /* Drop the frame that contains the errors, reset the segment + * scanning logic, and continue scanning with the next frame. + */ + + nlldbg("DROPPED: RX descriptor errors: %08x\n", rxdesc->rdes0); + tiva_freesegment(priv, rxcurr, priv->segments); + } + } + + /* Try the next descriptor */ + + rxdesc = (struct emac_rxdesc_s *)rxdesc->rdes3; + } + + /* We get here after all of the descriptors have been scanned or when rxdesc points + * to the first descriptor owned by the DMA. Remember where we left off. + */ + + priv->rxhead = rxdesc; + + nvdbg("rxhead: %p rxcurr: %p segments: %d\n", + priv->rxhead, priv->rxcurr, priv->segments); + + return -EAGAIN; +} + +/**************************************************************************** + * Function: tiva_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_receive(FAR struct tiva_ethmac_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + + /* Loop while while tiva_recvframe() successfully retrieves valid + * Ethernet frames. + */ + + while (tiva_recvframe(priv) == OK) + { +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* Check if the packet is a valid size for the uIP buffer configuration + * (this should not happen) + */ + + if (dev->d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("DROPPED: Too big: %d\n", dev->d_len); + } + else + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + /* And send the packet */ + + tiva_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("IPv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + tiva_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + nvdbg("ARP frame\n"); + + /* Handle ARP packet */ + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + tiva_transmit(priv); + } + } + else +#endif + { + nlldbg("DROPPED: Unknown type: %04x\n", BUF->type); + } + + /* We are finished with the RX buffer. NOTE: If the buffer is + * re-used for transmission, the dev->d_buf field will have been + * nullified. + */ + + if (dev->d_buf) + { + /* Free the receive packet buffer */ + + tiva_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + dev->d_len = 0; + } + } +} + +/**************************************************************************** + * Function: tiva_freeframe + * + * Description: + * Scans the TX descriptors and frees the buffers of completed TX transfers. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void tiva_freeframe(FAR struct tiva_ethmac_s *priv) +{ + FAR struct emac_txdesc_s *txdesc; + int i; + + nvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + + /* Scan for "in-flight" descriptors owned by the CPU */ + + txdesc = priv->txtail; + if (txdesc) + { + DEBUGASSERT(priv->inflight > 0); + + for (i = 0; (txdesc->tdes0 & EMAC_TDES0_OWN) == 0; i++) + { + /* There should be a buffer assigned to all in-flight + * TX descriptors. + */ + + nvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n", + txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3); + + DEBUGASSERT(txdesc->tdes2 != 0); + + /* Check if this is the first segment of a TX frame. */ + + if ((txdesc->tdes0 & EMAC_TDES0_FS) != 0) + { + /* Yes.. Free the buffer */ + + tiva_freebuffer(priv, (uint8_t *)txdesc->tdes2); + } + + /* In any event, make sure that TDES2 is nullified. */ + + txdesc->tdes2 = 0; + + /* Check if this is the last segment of a TX frame */ + + if ((txdesc->tdes0 & EMAC_TDES0_LS) != 0) + { + /* Yes.. Decrement the number of frames "in-flight". */ + + priv->inflight--; + + /* If all of the TX descriptors were in-flight, then RX interrupts + * may have been disabled... we can re-enable them now. + */ + + tiva_enableint(priv, EMAC_DMAINT_RI); + + /* If there are no more frames in-flight, then bail. */ + + if (priv->inflight <= 0) + { + priv->txtail = NULL; + priv->inflight = 0; + return; + } + } + + /* Try the next descriptor in the TX chain */ + + txdesc = (struct emac_txdesc_s *)txdesc->tdes3; + } + + /* We get here if (1) there are still frames "in-flight". Remember + * where we left off. + */ + + priv->txtail = txdesc; + + nvdbg("txhead: %p txtail: %p inflight: %d\n", + priv->txhead, priv->txtail, priv->inflight); + } +} + +/**************************************************************************** + * Function: tiva_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void tiva_txdone(FAR struct tiva_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + DEBUGASSERT(priv->txtail != NULL); + + /* Scan the TX descriptor change, returning buffers to free list */ + + tiva_freeframe(priv); + dev->d_buf = NULL; + dev->d_len = 0; + + /* If no further xmits are pending, then cancel the TX timeout */ + + if (priv->inflight <= 0) + { + /* Cancel the TX timeout */ + + wd_cancel(priv->txtimeout); + + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv); + + /* And disable further TX interrupts. */ + + tiva_disableint(priv, EMAC_DMAINT_TI); + } + + /* Then poll uIP for new XMIT data */ + + tiva_dopoll(priv); +} + +/**************************************************************************** + * Function: tiva_interrupt_process + * + * Description: + * Interrupt processing. This may be performed either within the interrupt + * handler or on the worker thread, depending upon the configuration + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +static inline void tiva_interrupt_process(FAR struct tiva_ethmac_s *priv) +{ + uint32_t dmaris; + + /* Get the DMA interrupt status bits (no MAC interrupts are expected) */ + + dmaris = tiva_getreg(TIVA_EMAC_DMARIS); + + /* Mask only enabled interrupts. This depends on the fact that the interrupt + * related bits (0-16) correspond in these two registers. + */ + + dmaris &= tiva_getreg(TIVA_EMAC_DMAIM); + + /* Check if there are pending "normal" interrupts */ + + if ((dmaris & EMAC_DMAINT_NIS) != 0) + { + /* Yes.. Check if we received an incoming packet, if so, call + * tiva_receive() + */ + + if ((dmaris & EMAC_DMAINT_RI) != 0) + { + /* Clear the pending receive interrupt */ + + tiva_putreg(EMAC_DMAINT_RI, TIVA_EMAC_DMARIS); + + /* Handle the received package */ + + tiva_receive(priv); + } + + /* Check if a packet transmission just completed. If so, call + * tiva_txdone(). This may disable further TX interrupts if there + * are no pending transmissions. + */ + + if ((dmaris & EMAC_DMAINT_TI) != 0) + { + /* Clear the pending receive interrupt */ + + tiva_putreg(EMAC_DMAINT_TI, TIVA_EMAC_DMARIS); + + /* Check if there are pending transmissions */ + + tiva_txdone(priv); + } + + /* Clear the pending normal summary interrupt */ + + tiva_putreg(EMAC_DMAINT_NIS, TIVA_EMAC_DMARIS); + } + + /* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */ + +#ifdef CONFIG_DEBUG_NET + + /* Check if there are pending "abnormal" interrupts */ + + if ((dmaris & EMAC_DMAINT_AIS) != 0) + { + /* Just let the user know what happened */ + + nlldbg("Abnormal event(s): %08x\n", dmaris); + + /* Clear all pending abnormal events */ + + tiva_putreg(EMAC_DMAINT_ABNORMAL, TIVA_EMAC_DMARIS); + + /* Clear the pending abnormal summary interrupt */ + + tiva_putreg(EMAC_DMAINT_AIS, TIVA_EMAC_DMARIS); + } +#endif +} + +/**************************************************************************** + * Function: tiva_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void tiva_interrupt_work(FAR void *arg) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + net_lock_t state; + + DEBUGASSERT(priv); + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + tiva_interrupt_process(priv); + net_unlock(state); + + /* Re-enable Ethernet interrupts at the NVIC */ + + up_enable_irq(TIVA_IRQ_ETHCON); +} +#endif + +/**************************************************************************** + * Function: tiva_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_interrupt(int irq, FAR void *context) +{ + FAR struct tiva_ethmac_s *priv = &g_tiva_ethmac[0]; + +#ifdef CONFIG_NET_NOINTS + uint32_t dmaris; + + /* Get the raw interrupt status. */ + + dmaris = tiva_getreg(TIVA_EMAC_DMARIS); + if (dmaris != 0) + { + /* Disable further Ethernet interrupts. Because Ethernet interrupts + * are also disabled if the TX timeout event occurs, there can be no + * race condition here. + */ + + up_disable_irq(TIVA_IRQ_ETHCON); + + /* Check if a packet transmission just completed. */ + + if ((dmaris & EMAC_DMAINT_TI) != 0) + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->txtimeout); + } + + /* Cancel any pending poll work */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, tiva_interrupt_work, priv, 0); + } + +#else + /* Process the interrupt now */ + + tiva_interrupt_process(priv); +#endif + +#ifdef CONFIG_TIVA_PHY_INTERRUPTS + /* Check for pending PHY interrupts */ + + if ((tiva_getreg(TIVA_EPHY_MISC) & EMAC_PHYMISC_INT) != 0) + { + /* Clear the pending PHY interrupt */ + + tiva_putreg(EMAC_PHYMISC_INT, TIVA_EPHY_MISC); + + /* Dispatch to the registered handler */ + + if (priv->handler) + { + (void)priv->handler(irq, context); + } + } +#endif + + return OK; +} + +/**************************************************************************** + * Function: tiva_txtimeout_process + * + * Description: + * Process a TX timeout. Called from the either the watchdog timer + * expiration logic or from the worker thread, depending upon the + * configuration. The timeout means that the last TX never completed. + * Reset the hardware and start again. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static inline void tiva_txtimeout_process(FAR struct tiva_ethmac_s *priv) +{ + /* Reset the hardware. Just take the interface down, then back up again. */ + + tiva_ifdown(&priv->dev); + tiva_ifup(&priv->dev); + + /* Then poll uIP for new XMIT data */ + + tiva_dopoll(priv); +} + +/**************************************************************************** + * Function: tiva_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void tiva_txtimeout_work(FAR void *arg) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + net_lock_t state; + + /* Process pending Ethernet interrupts */ + + state = net_lock(); + tiva_txtimeout_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: tiva_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + + nlldbg("Timeout!\n"); + +#ifdef CONFIG_NET_NOINTS + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + * + * Interrupts will be re-enabled when tiva_ifup() is called. + */ + + up_disable_irq(TIVA_IRQ_ETHCON); + + /* Cancel any pending poll or interrupt work. This will have no effect + * on work that has already been started. + */ + + work_cancel(HPWORK, &priv->work); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, tiva_txtimeout_work, priv, 0); + +#else + /* Process the timeout now */ + + tiva_txtimeout_process(priv); +#endif +} + +/**************************************************************************** + * Function: tiva_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + + /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We + * cannot perform the timer poll if we are unable to accept another packet + * for transmission. Hmmm.. might be bug here. Does this mean if there is + * a transmit in progress, we will miss TCP time state updates? + * + * In a race condition, EMAC_TDES0_OWN may be cleared BUT still not available + * because tiva_freeframe() has not yet run. If tiva_freeframe() has run, + * the buffer1 pointer (tdes2) will be nullified (and inflight should be < + * CONFIG_TIVA_EMAC_NTXDESC). + */ + + if ((priv->txhead->tdes0 & EMAC_TDES0_OWN) == 0 && + priv->txhead->tdes2 == 0) + { + /* If we have the descriptor, then perform the timer poll. Allocate a + * buffer for the poll. + */ + + DEBUGASSERT(dev->d_len == 0 && dev->d_buf == NULL); + dev->d_buf = tiva_allocbuffer(priv); + + /* We can't poll if we have no buffers */ + + if (dev->d_buf) + { + /* Update TCP timing states and poll uIP for new XMIT data. + */ + + (void)devif_timer(dev, tiva_txpoll); + + /* We will, most likely end up with a buffer to be freed. But it + * might not be the same one that we allocated above. + */ + + if (dev->d_buf) + { + DEBUGASSERT(dev->d_len == 0); + tiva_freebuffer(priv, dev->d_buf); + dev->d_buf = NULL; + } + } + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv); +} + +/**************************************************************************** + * Function: tiva_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * Ethernet interrupts are disabled + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void tiva_poll_work(FAR void *arg) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + tiva_poll_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: tiva_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void tiva_poll_expiry(int argc, uint32_t arg, ...) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->work, tiva_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv); + } + +#else + /* Process the interrupt now */ + + tiva_poll_process(priv); +#endif +} + +/**************************************************************************** + * Function: tiva_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_ifup(struct net_driver_s *dev) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private; + int ret; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Configure the Ethernet interface for DMA operation. */ + + ret = tive_emac_configure(priv); + if (ret < 0) + { + return ret; + } + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->ifup = true; + up_enable_irq(TIVA_IRQ_ETHCON); + + tiva_checksetup(); + return OK; +} + +/**************************************************************************** + * Function: tiva_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_ifdown(struct net_driver_s *dev) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private; + irqstate_t flags; + + nvdbg("Taking the network down\n"); + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(TIVA_IRQ_ETHCON); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the tiva_ifup() always + * successfully brings the interface back up. + */ + + tiva_ethreset(priv); + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: tiva_txavail_process + * + * Description: + * Perform an out-of-cycle poll. + * + * Parameters: + * priv - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv) +{ + nvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + tiva_dopoll(priv); + } +} + +/**************************************************************************** + * Function: tiva_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void tiva_txavail_work(FAR void *arg) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + tiva_txavail_process(priv); + net_unlock(state); +} +#endif + +/**************************************************************************** + * Function: tiva_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int tiva_txavail(struct net_driver_s *dev) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private; + +#ifdef CONFIG_NET_NOINTS + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, tiva_txavail_work, priv, 0); + } + +#else + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Perform the out-of-cycle poll now */ + + tiva_txavail_process(priv); + leave_critical_section(flags); +#endif + + return OK; +} + +/**************************************************************************** + * Function: tiva_calcethcrc + * + * Description: + * Function to calculate the CRC used to check an ethernet frame + * + * Parameters: + * data - the data to be checked + * length - length of the data + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static uint32_t tiva_calcethcrc(const uint8_t *data, size_t length) +{ + uint32_t crc = 0xffffffff; + size_t i; + int j; + + for (i = 0; i < length; i++) + { + for (j = 0; j < 8; j++) + { + if (((crc >> 31) ^ (data[i] >> j)) & 0x01) + { + /* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ + crc = (crc << 1) ^ 0x04c11db7; + } + else + { + crc = crc << 1; + } + } + } + + return ~crc; +} +#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: tiva_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Add the MAC address to the hardware multicast hash table */ + + crc = tiva_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = TIVA_EMAC_HASHTBLH; + hashindex -= 32; + } + else + { + registeraddress = TIVA_EMAC_HASHTBLL; + } + + temp = tiva_getreg(registeraddress); + temp |= 1 << hashindex; + tiva_putreg(temp, registeraddress); + + temp = tiva_getreg(TIVA_EMAC_FRAMEFLTR); + temp |= (EMAC_FRAMEFLTR_HMC | EMAC_FRAMEFLTR_HPF); + tiva_putreg(temp, TIVA_EMAC_FRAMEFLTR); + + return OK; +} +#endif + +/**************************************************************************** + * Function: tiva_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + uint32_t crc; + uint32_t hashindex; + uint32_t temp; + uint32_t registeraddress; + + nvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Remove the MAC address to the hardware multicast hash table */ + + crc = tiva_calcethcrc(mac, 6); + + hashindex = (crc >> 26) & 0x3F; + + if (hashindex > 31) + { + registeraddress = TIVA_EMAC_HASHTBLH; + hashindex -= 32; + } + else + { + registeraddress = TIVA_EMAC_HASHTBLL; + } + + temp = tiva_getreg(registeraddress); + temp &= ~(1 << hashindex); + tiva_putreg(temp, registeraddress); + + /* If there is no address registered any more, delete multicast filtering */ + + if (tiva_getreg(TIVA_EMAC_HASHTBLH) == 0 && + tiva_getreg(TIVA_EMAC_HASHTBLL) == 0) + { + temp = tiva_getreg(TIVA_EMAC_FRAMEFLTR); + temp &= ~(EMAC_FRAMEFLTR_HMC | EMAC_FRAMEFLTR_HPF); + tiva_putreg(temp, TIVA_EMAC_FRAMEFLTR); + } + + return OK; +} +#endif + +/**************************************************************************** + * Function: tiva_txdescinit + * + * Description: + * Initializes the DMA TX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_txdescinit(FAR struct tiva_ethmac_s *priv) +{ + struct emac_txdesc_s *txdesc; + int i; + + /* priv->txhead will point to the first, available TX descriptor in the chain. + * Set the priv->txhead pointer to the first descriptor in the table. + */ + + priv->txhead = priv->txtable; + + /* priv->txtail will point to the first segment of the oldest pending + * "in-flight" TX transfer. NULL means that there are no active TX + * transfers. + */ + + priv->txtail = NULL; + priv->inflight = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_TIVA_EMAC_NTXDESC; i++) + { + txdesc = &priv->txtable[i]; + + /* Set Second Address Chained bit */ + + txdesc->tdes0 = EMAC_TDES0_TCH; + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the checksum insertion for the TX frames */ + + txdesc->tdes0 |= EMAC_TDES0_CIC_ALL; +#endif + + /* Clear Buffer1 address pointer (buffers will be assigned as they + * are used) + */ + + txdesc->tdes2 = 0; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_TIVA_EMAC_NTXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + txdesc->tdes3 = (uint32_t)&priv->txtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + txdesc->tdes3 = (uint32_t)priv->txtable; + } + } + + /* Set Transmit Descriptor List Address Register */ + + tiva_putreg((uint32_t)priv->txtable, TIVA_EMAC_TXDLADDR); +} + +/**************************************************************************** + * Function: tiva_rxdescinit + * + * Description: + * Initializes the DMA RX descriptors in chain mode. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_rxdescinit(FAR struct tiva_ethmac_s *priv) +{ + struct emac_rxdesc_s *rxdesc; + int i; + + /* priv->rxhead will point to the first, RX descriptor in the chain. + * This will be where we receive the first incomplete frame. + */ + + priv->rxhead = priv->rxtable; + + /* If we accumulate the frame in segments, priv->rxcurr points to the + * RX descriptor of the first segment in the current TX frame. + */ + + priv->rxcurr = NULL; + priv->segments = 0; + + /* Initialize each TX descriptor */ + + for (i = 0; i < CONFIG_TIVA_EMAC_NRXDESC; i++) + { + rxdesc = &priv->rxtable[i]; + + /* Set Own bit of the RX descriptor rdes0 */ + + rxdesc->rdes0 = EMAC_RDES0_OWN; + + /* Set Buffer1 size and Second Address Chained bit and enabled DMA + * RX desc receive interrupt + */ + + rxdesc->rdes1 = EMAC_RDES1_RCH | (uint32_t)OPTIMAL_EMAC_BUFSIZE; + + /* Set Buffer1 address pointer */ + + rxdesc->rdes2 = (uint32_t)&priv->rxbuffer[i*OPTIMAL_EMAC_BUFSIZE]; + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + + if (i < (CONFIG_TIVA_EMAC_NRXDESC-1)) + { + /* Set next descriptor address register with next descriptor base + * address + */ + + rxdesc->rdes3 = (uint32_t)&priv->rxtable[i+1]; + } + else + { + /* For last descriptor, set next descriptor address register equal + * to the first descriptor base address + */ + + rxdesc->rdes3 = (uint32_t)priv->rxtable; + } + } + + /* Set Receive Descriptor List Address Register */ + + tiva_putreg((uint32_t)priv->rxtable, TIVA_EMAC_RXDLADDR); +} + +/**************************************************************************** + * Function: tiva_ioctl + * + * Description: + * Executes the SIOCxMIIxxx command and responds using the request struct + * that must be provided as its 2nd parameter. + * + * When called with SIOCGMIIPHY it will get the PHY address for the device + * and write it to the req->phy_id field of the request struct. + * + * When called with SIOCGMIIREG it will read a register of the PHY that is + * specified using the req->reg_no struct field and then write its output + * to the req->val_out field. + * + * When called with SIOCSMIIREG it will write to a register of the PHY that + * is specified using the req->reg_no struct field and use req->val_in as + * its input. + * + * Parameters: + * dev - Ethernet device structure + * cmd - SIOCxMIIxxx command code + * arg - Request structure also used to return values + * + * Returned Value: Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_PHY_IOCTL +static int tiva_ioctl(struct net_driver_s *dev, int cmd, long arg) +{ + int ret; + + switch (cmd) + { +#ifdef CONFIG_TIVA_PHY_INTERRUPTS + case SIOCMIINOTIFY: /* Set up for PHY event notifications */ + { + struct mii_iotcl_notify_s *req = (struct mii_iotcl_notify_s *)((uintptr_t)arg); + + ret = phy_notify_subscribe(dev->d_ifname, req->pid, req->signo, req->arg); + if (ret == OK) + { + /* Enable PHY link up/down interrupts */ + + tiva_phy_intenable(true); + } + } + break; +#endif + + case SIOCGMIIPHY: /* Get MII PHY address */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + req->phy_id = CONFIG_TIVA_PHYADDR; + ret = OK; + } + break; + + case SIOCGMIIREG: /* Get register from MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = tiva_phyread(req->phy_id, req->reg_num, &req->val_out); + } + break; + + case SIOCSMIIREG: /* Set register in MII PHY */ + { + struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg); + ret = tiva_phywrite(req->phy_id, req->reg_num, req->val_in); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + +/**************************************************************************** + * Function: tiva_phy_intenable + * + * Description: + * Enable link up/down PHY interrupts. The interrupt protocol is like this: + * + * - Interrupt status is cleared when the interrupt is enabled. + * - Interrupt occurs. Interrupt is disabled (at the processor level) when + * is received. + * - Interrupt status is cleared when the interrupt is re-enabled. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno (-ETIMEDOUT) on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_PHY_INTERRUPTS +static void tiva_phy_intenable(bool enable) +{ +#ifdef CONFIG_TIVA_PHY_INTERNAL + uint16_t phyval; + int ret; + + /* Disable further PHY interrupts until we complete this setup */ + + tiva_putreg(0, TIVA_EPHY_IM); + + /* Enable/disable event based PHY interrupts */ + /* REVISIT: There is an issue here: The PHY interrupt handler is called + * from the interrupt level and it, in turn, will call this function to + * disabled further interrupts. Subsequent link status processing will + * also call tiva_phyread() to access PHY registers and will, eventually, + * call this function again to re-enable the PHY interrupt. The control + * between interrupt level access to the PHY and non-interrupt level + * access to the PHY is not well enforced but is probably okay just due + * to the sequencing of things. + */ + + if (enable) + { + /* Configure interrupts on link status change events */ + + ret = tiva_phywrite(CONFIG_TIVA_PHYADDR, TIVA_EPHY_MISR1, + EPHY_MISR1_LINKSTATEN); + if (ret == OK) + { + /* Enable PHY event based interrupts */ + + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, TIVA_EPHY_SCR, &phyval); + if (ret == OK) + { + phyval |= EPHY_SCR_INTEN; + ret = tiva_phywrite(CONFIG_TIVA_PHYADDR, TIVA_EPHY_SCR, phyval); + if (ret == OK) + { + /* Enable PHY interrupts */ + + tiva_putreg(EMAC_PHYIM_INT, TIVA_EPHY_IM); + } + } + } + } + else + { + /* Read the MISR1 register in order to clear any pending link status + * interrupts. + */ + + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, TIVA_EPHY_MISR1, &phyval); + if (ret == OK) + { + /* Disable PHY event based interrupts */ + + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, TIVA_EPHY_SCR, &phyval); + if (ret == OK) + { + phyval |= EPHY_SCR_INTEN; + (void)tiva_phywrite(CONFIG_TIVA_PHYADDR, TIVA_EPHY_SCR, phyval); + } + } + } + +#else + /* Interrupt configuration logic for external PHYs depends on the + * particular PHY part connected. + */ + +#warning Missing logic + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Function: tiva_phyread + * + * Description: + * Read a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The location to return the 16-bit PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MIIADDR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = tiva_getreg(TIVA_EMAC_MIIADDR); + regval &= EMAC_MIIADDR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the buy bit. + * the EMAC_MIIADDR_MIIW is clear, indicating a read operation. + */ + + regval |= (((uint32_t)phydevaddr << EMAC_MIIADDR_PLA_SHIFT) & EMAC_MIIADDR_PLA_MASK); + regval |= (((uint32_t)phyregaddr << EMAC_MIIADDR_MII_SHIFT) & EMAC_MIIADDR_MII_MASK); + regval |= EMAC_MIIADDR_MIIB; + + tiva_putreg(regval, TIVA_EMAC_MIIADDR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_READ_TIMEOUT; timeout++) + { + if ((tiva_getreg(TIVA_EMAC_MIIADDR) & EMAC_MIIADDR_MIIB) == 0) + { + *value = (uint16_t)tiva_getreg(TIVA_EMAC_MIIDATA); + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x\n", + phydevaddr, phyregaddr); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: tiva_phywrite + * + * Description: + * Write to a PHY register. + * + * Parameters: + * phydevaddr - The PHY device address + * phyregaddr - The PHY register address + * value - The 16-bit value to write to the PHY register value. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value) +{ + volatile uint32_t timeout; + uint32_t regval; + + /* Configure the MIIADDR register, preserving CSR Clock Range CR[2:0] bits */ + + regval = tiva_getreg(TIVA_EMAC_MIIADDR); + regval &= EMAC_MIIADDR_CR_MASK; + + /* Set the PHY device address, PHY register address, and set the busy bit. + * the EMAC_MIIADDR_MIIW is set, indicating a write operation. + */ + + regval |= (((uint32_t)phydevaddr << EMAC_MIIADDR_PLA_SHIFT) & EMAC_MIIADDR_PLA_MASK); + regval |= (((uint32_t)phyregaddr << EMAC_MIIADDR_MII_SHIFT) & EMAC_MIIADDR_MII_MASK); + regval |= (EMAC_MIIADDR_MIIB | EMAC_MIIADDR_MIIW); + + /* Write the value into the MACIIDR register before setting the new MIIADDR + * register value. + */ + + tiva_putreg(value, TIVA_EMAC_MIIDATA); + tiva_putreg(regval, TIVA_EMAC_MIIADDR); + + /* Wait for the transfer to complete */ + + for (timeout = 0; timeout < PHY_WRITE_TIMEOUT; timeout++) + { + if ((tiva_getreg(TIVA_EMAC_MIIADDR) & EMAC_MIIADDR_MIIB) == 0) + { + return OK; + } + } + + ndbg("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x value: %04x\n", + phydevaddr, phyregaddr, value); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Function: tiva_phyinit + * + * Description: + * Configure the PHY and determine the link speed/duplex. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_phyinit(FAR struct tiva_ethmac_s *priv) +{ +#ifdef CONFIG_TIVA_AUTONEG + volatile uint32_t timeout; +#endif + uint32_t regval; + uint16_t phyval; + int ret; + + /* Assume 10MBps and half duplex */ + + priv->mbps100 = 0; + priv->fduplex = 0; + + /* Setup up PHY clocking by setting the CR field in the MIIADDR register */ + + regval = tiva_getreg(TIVA_EMAC_MIIADDR); + regval &= ~EMAC_MIIADDR_CR_MASK; + regval |= EMAC_MIIADDR_CR; + tiva_putreg(regval, TIVA_EMAC_MIIADDR); + + /* Put the PHY in reset mode */ + + ret = tiva_phywrite(CONFIG_TIVA_PHYADDR, MII_MCR, MII_MCR_RESET); + if (ret < 0) + { + ndbg("Failed to reset the PHY: %d\n", ret); + return ret; + } + + up_mdelay(PHY_RESET_DELAY); + + /* Perform auto-negotiation if so configured */ + +#ifdef CONFIG_TIVA_AUTONEG + /* Wait for link status */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_LINKSTATUS) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for link status: %04x\n", phyval); + return -ETIMEDOUT; + } + + /* Enable auto-negotiation */ + + ret = tiva_phywrite(CONFIG_TIVA_PHYADDR, MII_MCR, MII_MCR_ANENABLE); + if (ret < 0) + { + ndbg("Failed to enable auto-negotiation: %d\n", ret); + return ret; + } + + /* Wait until auto-negotiation completes */ + + for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++) + { + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, MII_MSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY MSR: %d\n", ret); + return ret; + } + else if ((phyval & MII_MSR_ANEGCOMPLETE) != 0) + { + break; + } + } + + if (timeout >= PHY_RETRY_TIMEOUT) + { + ndbg("Timed out waiting for auto-negotiation\n"); + return -ETIMEDOUT; + } + + /* Read the result of the auto-negotiation from the PHY-specific register */ + + ret = tiva_phyread(CONFIG_TIVA_PHYADDR, CONFIG_TIVA_PHYSR, &phyval); + if (ret < 0) + { + ndbg("Failed to read PHY status register\n"); + return ret; + } + + /* Remember the selected speed and duplex modes */ + + nvdbg("PHYSR[%d]: %04x\n", CONFIG_TIVA_PHYSR, phyval); + + /* Different PHYs present speed and mode information in different ways. IF + * This CONFIG_TIVA_PHYSR_ALTCONFIG is selected, this indicates that the PHY + * represents speed and mode information are combined, for example, with + * separate bits for 10HD, 100HD, 10FD and 100FD. + */ + +#ifdef CONFIG_TIVA_PHYSR_ALTCONFIG + switch (phyval & CONFIG_TIVA_PHYSR_ALTMODE) + { + default: + case CONFIG_TIVA_PHYSR_10HD: + priv->fduplex = 0; + priv->mbps100 = 0; + break; + + case CONFIG_TIVA_PHYSR_100HD: + priv->fduplex = 0; + priv->mbps100 = 1; + break; + + case CONFIG_TIVA_PHYSR_10FD: + priv->fduplex = 1; + priv->mbps100 = 0; + break; + + case CONFIG_TIVA_PHYSR_100FD: + priv->fduplex = 1; + priv->mbps100 = 1; + break; + } + + /* Different PHYs present speed and mode information in different ways. Some + * will present separate information for speed and mode (this is the default). + * Those PHYs, for example, may provide a 10/100 Mbps indication and a separate + * full/half duplex indication. + */ + +#else + if ((phyval & CONFIG_TIVA_PHYSR_MODE) == CONFIG_TIVA_PHYSR_FULLDUPLEX) + { + priv->fduplex = 1; + } + + if ((phyval & CONFIG_TIVA_PHYSR_SPEED) == CONFIG_TIVA_PHYSR_100MBPS) + { + priv->mbps100 = 1; + } +#endif + +#else /* Auto-negotion not selected */ + + phyval = 0; +#ifdef CONFIG_TIVA_ETHFD + phyval |= MII_MCR_FULLDPLX; +#endif +#ifdef CONFIG_TIVA_ETH100MBPS + phyval |= MII_MCR_SPEED100; +#endif + + ret = tiva_phywrite(CONFIG_TIVA_PHYADDR, MII_MCR, phyval); + if (ret < 0) + { + ndbg("Failed to write the PHY MCR: %d\n", ret); + return ret; + } + up_mdelay(PHY_CONFIG_DELAY); + + /* Remember the selected speed and duplex modes */ + +#ifdef CONFIG_TIVA_ETHFD + priv->fduplex = 1; +#endif +#ifdef CONFIG_TIVA_ETH100MBPS + priv->mbps100 = 1; +#endif +#endif + + ndbg("Duplex: %s Speed: %d MBps\n", + priv->fduplex ? "FULL" : "HALF", + priv->mbps100 ? 100 : 10); + + return OK; +} + +/**************************************************************************** + * Function: tiva_phy_configure + * + * Description: + * Configure to support the selected PHY. Called after each reset since + * many properties of the PHY configuration are lost at each reset. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_phy_configure(FAR struct tiva_ethmac_s *priv) +{ + uint32_t regval; + + /* Set up the PHY configuration */ + +#if defined(CONFIG_TIVA_PHY_RMII) + regval = EMAC_PC_PINTFS_RMII | EMAC_PC_PHYEXT; +#elif defined(CONFIG_TIVA_PHY_MII) + regval = EMAC_PC_PINTFS_MII | EMAC_PC_PHYEXT; +#else /* defined(CONFIG_TIVA_PHY_INTERNAL) */ + regval = EMAC_PC_MDIXEN | EMAC_PC_ANMODE_100FD | EMAC_PC_ANEN | + EMAC_PC_PINTFS_MII; +#endif + tiva_putreg(regval, TIVA_EMAC_PC); + +#ifdef CONFIG_TIVA_PHY_INTERNAL + /* If we are using the internal PHY, reset it to ensure that new + * configuration is latched. + */ + + regval = tiva_getreg(TIVA_SYSCON_SREPHY); + regval |= SYSCON_SREPHY_R0; + tiva_putreg(regval, TIVA_SYSCON_SREPHY); + + regval &= ~SYSCON_SREPHY_R0; + tiva_putreg(regval, TIVA_SYSCON_SREPHY); + + /* Wait for the reset to complete */ + + while (!tiva_ephy_periphrdy()); + up_udelay(250); +#endif + + /* Disable all MMC interrupts as these are enabled by default at reset */ + + tiva_putreg(0xffffffff, TIVA_EMAC_MMCRXIM); + tiva_putreg(0xffffffff, TIVA_EMAC_MMCTXIM); + + /* If using an external RMII PHY, we must enable the external clock */ + + regval = tiva_getreg(TIVA_EMAC_CC); + +#if defined(CONFIG_TIVA_PHY_RMII) + /* Enable the external clock source input to the RMII interface signal + * EN0RREF_CLK by setting both the CLKEN bit in the Ethernet Clock + * Configuration (EMACCC) register. The external clock source must be + * 50 MHz with a frequency tolerance of 50 PPM. + */ + + regval = tiva_getreg(TIVA_EMAC_CC); +#else + /* Disable the external clock */ + + regval &= ~EMAC_CC_CLKEN; +#endif + + tiva_putreg(regval, TIVA_EMAC_CC); +} + +/**************************************************************************** + * Function: tiva_phy_initialize + * + * Description: + * Perform one-time PHY initialization + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void tiva_phy_initialize(FAR struct tiva_ethmac_s *priv) +{ + /* Enable the clock to the PHY module */ + + nllvdbg("Enable EPHY clocking\n"); + tiva_ephy_enableclk(); + + /* What until the PREPHY register indicates that the PHY is ready before + * continuing. + */ + + while (!tiva_ephy_periphrdy()); + up_udelay(250); + + /* Enable power to the Ethernet PHY */ + + nllvdbg("Enable EPHY power\n"); + tiva_ephy_enablepwr(); + + /* What until the PREPHY register indicates that the PHY registers are ready + * to be accessed. + */ + + while (!tiva_ephy_periphrdy()); + up_udelay(250); + + nllvdbg("RCGCEPHY: %08x PCEPHY: %08x PREPHY: %08x\n", + getreg32(TIVA_SYSCON_RCGCEPHY), + getreg32(TIVA_SYSCON_PCEPHY), + getreg32(TIVA_SYSCON_PREPHY)); + nllvdbg("Configure PHY GPIOs\n"); + +#ifdef CONFIG_TIVA_PHY_INTERNAL + /* Integrated PHY: + * + * "The Ethernet Controller Module and Integrated PHY receive two clock inputs: + * - A gated system clock acts as the clock source to the Control and Status + * registers (CSR) of the Ethernet MAC. The SYSCLK frequency for Run, Sleep + * and Deep Sleep mode is programmed in the System Control module. ... + * - The PHY receives the main oscillator (MOSC) which must be 25 MHz ± 50 ppm + * for proper operation. The MOSC source can be a single-ended source or a + * crystal." + * + * These are currently set up in tiva_clockconfig() before this function runs. + * + * MII/RMII Clocking: + * + * External PHY support is not yet implemented. + */ + + /* PHY interface pins: + * + * EN0TXOP - Fixed pin assignment + * EN0TXON - Fixed pin assignment + * EN0RXIP - Fixed pin assignment + * EN0RXIN - Fixed pin assignment + * RBIAS - Fixed pin assignment + * EN0LED0 - Configured GPIO output + * EN0LED1 - Configured GPIO output + * EN0LED2 - Configured GPIO output + */ + + tiva_configgpio(GPIO_EN0_LED0); + tiva_configgpio(GPIO_EN0_LED1); + tiva_configgpio(GPIO_EN0_LED2); + +#else /* if defined(CONFIG_TIVA_PHY_MII) || defined(CONFIG_TIVA_PHY_RMII) */ + /* External PHY interrupt pin */ + + tiva_configgpio(GPIO_EN0_INTRN); + + /* Configure GPIO pins to support MII or RMII */ + /* MDC and MDIO are common to both modes */ + + tiva_configgpio(GPIO_EN0_MDC); + tiva_configgpio(GPIO_EN0_MDIO); + +#if defined(CONFIG_TIVA_PHY_MII) + /* Set up the MII interface */ + + /* "Four clock inputs are driven into the Ethernet MAC when the MII + * configuration is enabled. The clocks are described as follows: + * + * - Gated system clock (SYSCLK): The SYSCLK signal acts as the clock + * source to the Control and Status registers (CSR) of the Ethernet + * MAC. The SYSCLK frequency for Run, Sleep and Deep Sleep mode is + * programmed in the System Control module. ... + * - MOSC: A gated version of the MOSC clock is provided as the Precision + * Time Protocol (PTP) reference clock (PTPREF_CLK). The MOSC clock + * source can be a single-ended source on the OSC0 pin or a crystal + * on the OSC0 and OSC1 pins. When advanced timestamping is used and + * the Precision Timer Protocol (PTP) module has been enabled by setting + * the PTPCEN bit in the EMACCC register, the MOSC drives PTPREF_CLK. + * PTPREF_CLK has a minimum frequency requirement of 5 MHz and a + * maximum frequency of 25 MHz. ... + * - EN0RXCK: This clock signal is driven by the external PHY oscillator + * and is either 2.5 or 25 MHz depending on whether the device is + * operating at 10 Mbps or 100 Mbps. + * - EN0TXCK This clock signal is driven by the external PHY oscillator + * and is either 2.5 or 25 MHz depending on whether the device is + * operating at 10 Mbps or 100 Mbps." + */ + + /* MII interface pins (17): + * + * MII_TX_CLK, MII_TXD[3:0], MII_TX_EN, MII_RX_CLK, MII_RXD[3:0], MII_RX_ER, + * MII_RX_DV, MII_CRS, MII_COL, MDC, MDIO + */ + + tiva_configgpio(GPIO_EN0_MII_COL); + tiva_configgpio(GPIO_EN0_MII_CRS); + tiva_configgpio(GPIO_EN0_MII_RXD0); + tiva_configgpio(GPIO_EN0_MII_RXD1); + tiva_configgpio(GPIO_EN0_MII_RXD2); + tiva_configgpio(GPIO_EN0_MII_RXD3); + tiva_configgpio(GPIO_EN0_MII_RX_CLK); + tiva_configgpio(GPIO_EN0_MII_RX_DV); + tiva_configgpio(GPIO_EN0_MII_RX_ER); + tiva_configgpio(GPIO_EN0_MII_TXD0); + tiva_configgpio(GPIO_EN0_MII_TXD1); + tiva_configgpio(GPIO_EN0_MII_TXD2); + tiva_configgpio(GPIO_EN0_MII_TXD3); + tiva_configgpio(GPIO_EN0_MII_TX_CLK); + tiva_configgpio(GPIO_EN0_MII_TX_EN); + +#elif defined(CONFIG_TIVA_PHY_RMII) + /* Set up the RMII interface. */ + + /* "There are three clock sources that interface to the Ethernet MAC in + * an RMII configuration: + * + * - Gated system clock (SYSCLK): The SYSCLK signal acts as the clock + * source to the Control and Status registers (CSR) of the Ethernet MAC. + * The SYSCLK frequency for Run, Sleep and Deep Sleep mode is programmed + * in the System Control module. ... + * - MOSC: A gated version of the MOSC clock is provided as the Precision + * Time Protocol (PTP) reference clock (PTPREF_CLK). The MOSC clock + * source can be a single-ended source on the OSC0 pin or a crystal on + * the OSC0 and OSC1 pins. When advanced timestamping is used and + * the PTP module has been enabled by setting the PTPCEN bit in the + * EMACCC register, the MOSC drives PTPREF_CLK. PTPREF_CLK has a minimum + * frequency requirement of 5 MHz and a maximum frequency of 25 MHz. ... + * - EN0REF_CLK: When using RMII, a 50 MHz external reference clock must + * drive the EN0REF_CLK input signal and the external PHY. Depending on + * the configuration of the FES bit in the Ethernet MAC Configuration + * (EMACCFG) register, the reference clock input (EN0REF_CLK) is divided + * by 20 for 10 Mbps or 2 for 100 Mbps operation and used as the clock + * for receive and transmit data." + */ + + /* RMII interface pins (7): + * + * RMII_TXD[1:0], RMII_TX_EN, RMII_RXD[1:0], RMII_CRS_DV, MDC, MDIO, + * RMII_REF_CLK + */ + + tiva_configgpio(GPIO_EN0_RMII_CRS_DV); + tiva_configgpio(GPIO_EN0_RMII_REF_CLK); + tiva_configgpio(GPIO_EN0_RMII_RXD0); + tiva_configgpio(GPIO_EN0_RMII_RXD1); + tiva_configgpio(GPIO_EN0_RMII_TXD0); + tiva_configgpio(GPIO_EN0_RMII_TXD1); + /* tiva_configgpio(GPIO_EN0_RMII_TX_CLK); not needed? */ + tiva_configgpio(GPIO_EN0_RMII_TX_EN); + +#endif + + /* Enable pulse-per-second (PPS) output signal */ + + tiva_configgpio(GPIO_EN0_PPS); +#endif +} + +/**************************************************************************** + * Function: tiva_ethreset + * + * Description: + * Reset the Ethernet block. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_ethreset(FAR struct tiva_ethmac_s *priv) +{ + uint32_t regval; + +#if 0 /* REVISIT: This causes the DMABUSMOD reset to hang. */ + /* Reset the Ethernet MAC */ + + regval = tiva_getreg(TIVA_SYSCON_SREMAC); + regval |= SYSCON_SREMAC_R0; + tiva_putreg(regval, TIVA_SYSCON_SREMAC); + + regval &= ~SYSCON_SREMAC_R0; + tiva_putreg(regval, TIVA_SYSCON_SREMAC); + + /* Wait for the reset to complete */ + + while (!tiva_emac_periphrdy()); + up_udelay(250); +#endif + + /* Perform a software reset by setting the SWR bit in the DMABUSMOD register. + * This Resets all MAC subsystem internal registers and logic. After this + * reset all the registers holds their reset values. + */ + + regval = tiva_getreg(TIVA_EMAC_DMABUSMOD); + regval |= EMAC_DMABUSMOD_SWR; + tiva_putreg(regval, TIVA_EMAC_DMABUSMOD); + + /* Wait for software reset to complete. The SWR bit is cleared automatically + * after the reset operation has completed in all of the core clock domains. + */ + + while ((tiva_getreg(TIVA_EMAC_DMABUSMOD) & EMAC_DMABUSMOD_SWR) != 0); + up_udelay(250); + + /* Reconfigure the PHY. Some PHY configurations will be lost as a + * consequence of the EMAC reset + */ + + tiva_phy_configure(priv); +} + +/**************************************************************************** + * Function: tiva_macconfig + * + * Description: + * Configure the Ethernet MAC for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_macconfig(FAR struct tiva_ethmac_s *priv) +{ + uint32_t regval; + + /* Set up the MACCR register */ + + regval = tiva_getreg(TIVA_EMAC_CFG); + regval &= ~MACCR_CLEAR_BITS; + regval |= MACCR_SET_BITS; + + if (priv->fduplex) + { + /* Set the DM bit for full duplex support */ + + regval |= EMAC_CFG_DUPM; + } + + if (priv->mbps100) + { + /* Set the FES bit for 100Mbps fast Ethernet support */ + + regval |= EMAC_CFG_FES; + } + + tiva_putreg(regval, TIVA_EMAC_CFG); + + /* Set up the FRAMEFLTR register */ + + regval = tiva_getreg(TIVA_EMAC_FRAMEFLTR); + regval &= ~FRAMEFLTR_CLEAR_BITS; + regval |= FRAMEFLTR_SET_BITS; + tiva_putreg(regval, TIVA_EMAC_FRAMEFLTR); + + /* Set up the HASHTBLH and HASHTBLL registers */ + + tiva_putreg(0, TIVA_EMAC_HASHTBLH); + tiva_putreg(0, TIVA_EMAC_HASHTBLL); + + /* Setup up the FLOWCTL register */ + + regval = tiva_getreg(TIVA_EMAC_FLOWCTL); + regval &= ~FLOWCTL_CLEAR_MASK; + regval |= FLOWCTL_SET_MASK; + tiva_putreg(regval, TIVA_EMAC_FLOWCTL); + + /* Setup up the VLANTG register */ + + tiva_putreg(0, TIVA_EMAC_VLANTG); + + /* DMA Configuration */ + /* Set up the DMAOPMODE register */ + + regval = tiva_getreg(TIVA_EMAC_DMAOPMODE); + regval &= ~DMAOPMODE_CLEAR_MASK; + regval |= DMAOPMODE_SET_MASK; + tiva_putreg(regval, TIVA_EMAC_DMAOPMODE); + + /* Set up the DMABUSMOD register */ + + regval = tiva_getreg(TIVA_EMAC_DMABUSMOD); + regval &= ~DMABUSMOD_CLEAR_MASK; + regval |= DMABUSMOD_SET_MASK; + tiva_putreg(regval, TIVA_EMAC_DMABUSMOD); + + return OK; +} + +/**************************************************************************** + * Function: tiva_macaddress + * + * Description: + * Configure the selected MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static void tiva_macaddress(FAR struct tiva_ethmac_s *priv) +{ + FAR struct net_driver_s *dev = &priv->dev; + uint32_t regval; + + nvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_ifname, + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + + /* Set the MAC address high register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[5] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[4]; + tiva_putreg(regval, TIVA_EMAC_ADDR0H); + + /* Set the MAC address low register */ + + regval = ((uint32_t)dev->d_mac.ether_addr_octet[3] << 24) | + ((uint32_t)dev->d_mac.ether_addr_octet[2] << 16) | + ((uint32_t)dev->d_mac.ether_addr_octet[1] << 8) | + (uint32_t)dev->d_mac.ether_addr_octet[0]; + tiva_putreg(regval, TIVA_EMAC_ADDR0L); +} + +/**************************************************************************** + * Function: tiva_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void tiva_ipv6multicast(FAR struct tiva_ethmac_s *priv) +{ + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)tiva_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)tiva_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)tiva_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Function: tiva_macenable + * + * Description: + * Enable normal MAC operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tiva_macenable(FAR struct tiva_ethmac_s *priv) +{ + uint32_t regval; + + /* Set the MAC address */ + + tiva_macaddress(priv); + +#ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + tiva_ipv6multicast(priv); +#endif + + /* Enable transmit state machine of the MAC for transmission on the MII */ + + regval = tiva_getreg(TIVA_EMAC_CFG); + regval |= EMAC_CFG_TE; + tiva_putreg(regval, TIVA_EMAC_CFG); + + /* Flush Transmit FIFO */ + + regval = tiva_getreg(TIVA_EMAC_DMAOPMODE); + regval |= EMAC_DMAOPMODE_FTF; + tiva_putreg(regval, TIVA_EMAC_DMAOPMODE); + + /* Enable receive state machine of the MAC for reception from the MII */ + + /* Enables or disables the MAC reception. */ + + regval = tiva_getreg(TIVA_EMAC_CFG); + regval |= EMAC_CFG_RE; + tiva_putreg(regval, TIVA_EMAC_CFG); + + /* Start DMA transmission */ + + regval = tiva_getreg(TIVA_EMAC_DMAOPMODE); + regval |= EMAC_DMAOPMODE_ST; + tiva_putreg(regval, TIVA_EMAC_DMAOPMODE); + + /* Start DMA reception */ + + regval = tiva_getreg(TIVA_EMAC_DMAOPMODE); + regval |= EMAC_DMAOPMODE_SR; + tiva_putreg(regval, TIVA_EMAC_DMAOPMODE); + + /* Enable Ethernet DMA interrupts. */ + + tiva_putreg(EMAC_IM_ALLINTS, TIVA_EMAC_IM); + + /* Ethernet DMA supports two classes of interrupts: Normal interrupt + * summary (NIS) and Abnormal interrupt summary (AIS) with a variety + * individual normal and abnormal interrupting events. Here only + * the normal receive event is enabled (unless DEBUG is enabled). Transmit + * events will only be enabled when a transmit interrupt is expected. + */ + + tiva_putreg((EMAC_DMAINT_RECV_ENABLE | EMAC_DMAINT_ERROR_ENABLE), + TIVA_EMAC_DMAIM); + return OK; +} + +/**************************************************************************** + * Function: tive_emac_configure + * + * Description: + * Configure the Ethernet interface for DMA operation. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +static int tive_emac_configure(FAR struct tiva_ethmac_s *priv) +{ + int ret; + + /* NOTE: The Ethernet clocks were initialized earlier in the start-up + * sequence. + */ + + /* Reset the Ethernet block */ + + nvdbg("Reset the Ethernet block\n"); + tiva_ethreset(priv); + + /* Initialize the PHY */ + + nvdbg("Initialize the PHY\n"); + ret = tiva_phyinit(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the MAC and DMA */ + + nvdbg("Initialize the MAC and DMA\n"); + ret = tiva_macconfig(priv); + if (ret < 0) + { + return ret; + } + + /* Initialize the free buffer list */ + + tiva_initbuffer(priv); + + /* Initialize TX Descriptors list: Chain Mode */ + + tiva_txdescinit(priv); + + /* Initialize RX Descriptors list: Chain Mode */ + + tiva_rxdescinit(priv); + + /* Enable normal MAC operation */ + + nvdbg("Enable normal operation\n"); + return tiva_macenable(priv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: tiva_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the Tiva chip + * supports multiple Ethernet controllers, then board specific logic + * must implement up_netinitialize() and call this function to initialize + * the desired interfaces. + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS == 1 +static inline +#endif + +int tiva_ethinitialize(int intf) +{ + struct tiva_ethmac_s *priv; + uint32_t regval; + + nllvdbg("intf: %d\n", intf); + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(intf < TIVA_NETHCONTROLLERS); + priv = &g_tiva_ethmac[intf]; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct tiva_ethmac_s)); + priv->dev.d_ifup = tiva_ifup; /* I/F up (new IP address) callback */ + priv->dev.d_ifdown = tiva_ifdown; /* I/F down callback */ + priv->dev.d_txavail = tiva_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = tiva_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = tiva_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_PHY_IOCTL + priv->dev.d_ioctl = tiva_ioctl; /* Support PHY ioctl() calls */ +#endif + priv->dev.d_private = (void *)g_tiva_ethmac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + +#ifdef CONFIG_TIVA_BOARDMAC + /* If the board can provide us with a MAC address, get the address + * from the board now. The MAC will not be applied until tiva_ifup() + * is called (and the MAC can be overwritten with a netdev ioctl call). + */ + + tiva_ethernetmac(&priv->dev.d_mac); +#endif + + /* Enable power and clocking to the Ethernet MAC + * + * - Enable Power: Applies power (only) to the EMAC peripheral. This is not + * an essential step since enabling clocking will also apply power. The + * only significance is that the EMAC state will be retained if the EMAC + * clocking is subsequently disabled. + * - Enable Clocking: Applies both power and clocking to the EMAC peripheral, + * bringing it a fully functional state. + */ + + nllvdbg("Enable EMAC clocking\n"); + tiva_emac_enablepwr(); /* Ethernet MAC Power Control */ + tiva_emac_enableclk(); /* Ethernet MAC Run Mode Clock Gating Control */ + + /* What until the PREMAC register indicates that the EMAC registers are ready + * to be accessed. + */ + + while (!tiva_emac_periphrdy()); + up_udelay(250); + + /* Show all EMAC clocks */ + + nllvdbg("RCGCEMAC: %08x PCEMAC: %08x PREMAC: %08x MOSCCTL: %08x\n", + getreg32(TIVA_SYSCON_RCGCEMAC), + getreg32(TIVA_SYSCON_PCEMAC), + getreg32(TIVA_SYSCON_PREMAC), + getreg32(TIVA_SYSCON_MOSCCTL)); + + /* Configure clocking and GPIOs to support the internal/eternal PHY */ + + tiva_phy_initialize(priv); + + /* Attach the IRQ to the driver */ + + if (irq_attach(TIVA_IRQ_ETHCON, tiva_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Wait for EMAC to come out of reset. The SWR bit is cleared automatically + * after the reset operation has completed in all of the core clock domains. + */ + + while ((tiva_getreg(TIVA_EMAC_DMABUSMOD) & EMAC_DMABUSMOD_SWR) != 0); + up_udelay(250); + +#if 0 /* REVISIT: Part of work around to avoid DMABUSMOD SWR hangs */ + /* Put the interface in the down state. */ + + tiva_ifdown(&priv->dev); + +#else + /* Reset the Ethernet MAC */ + + regval = tiva_getreg(TIVA_SYSCON_SREMAC); + regval |= SYSCON_SREMAC_R0; + tiva_putreg(regval, TIVA_SYSCON_SREMAC); + + regval &= ~SYSCON_SREMAC_R0; + tiva_putreg(regval, TIVA_SYSCON_SREMAC); + + /* Wait for the reset to complete */ + + while (!tiva_emac_periphrdy()); + up_udelay(250); +#endif + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + nllvdbg("Registering Ethernet device\n"); + return netdev_register(&priv->dev, NET_LL_ETHERNET); +} + +/**************************************************************************** + * Function: up_netinitialize + * + * Description: + * This is the "standard" network initialization logic called from the + * low-level initialization logic in up_initialize.c. If TIVA_NETHCONTROLLERS + * greater than one, then board specific logic will have to supply a + * version of up_netinitialize() that calls tiva_ethinitialize() with + * the appropriate interface number. + * + * Parameters: + * None. + * + * Returned Value: + * None. + * + * Assumptions: + * + ****************************************************************************/ + +#if TIVA_NETHCONTROLLERS == 1 +void up_netinitialize(void) +{ + (void)tiva_ethinitialize(0); +} +#endif + +/**************************************************************************** + * Name: arch_phy_irq + * + * Description: + * This function may be called to register an interrupt handler that will + * be called when a PHY interrupt occurs. This function both attaches + * the interrupt handler and enables the interrupt if 'handler' is non- + * NULL. If handler is NULL, then the interrupt is detached and disabled + * instead. + * + * The PHY interrupt is always disabled upon return. The caller must + * call back through the enable function point to control the state of + * the interrupt. + * + * This interrupt may or may not be available on a given platform depending + * on how the network hardware architecture is implemented. In a typical + * case, the PHY interrupt is provided to board-level logic as a GPIO + * interrupt (in which case this is a board-specific interface and really + * should be called board_phy_irq()); In other cases, the PHY interrupt + * may be cause by the chip's MAC logic (in which case arch_phy_irq()) is + * an appropriate name. Other other boards, there may be no PHY interrupts + * available at all. If client attachable PHY interrupts are available + * from the board or from the chip, then CONFIG_ARCH_PHY_INTERRUPT should + * be defined to indicate that fact. + * + * Typical usage: + * a. OS service logic (not application logic*) attaches to the PHY + * PHY interrupt and enables the PHY interrupt. + * b. When the PHY interrupt occurs: (1) the interrupt should be + * disabled and () work should be scheduled on the worker thread (or + * perhaps a dedicated application thread). + * c. That worker thread should use the SIOCGMIIPHY, SIOCGMIIREG, + * and SIOCSMIIREG ioctl calls** to communicate with the PHY, + * determine what network event took place (Link Up/Down?), and + * take the appropriate actions. + * d. It should then interact the the PHY to clear any pending + * interrupts, then re-enable the PHY interrupt. + * + * * This is an OS internal interface and should not be used from + * application space. Rather applications should use the SIOCMIISIG + * ioctl to receive a signal when a PHY event occurs. + * ** This interrupt is really of no use if the Ethernet MAC driver + * does not support these ioctl calls. + * + * Input Parameters: + * intf - Identifies the network interface. For example "eth0". Only + * useful on platforms that support multiple Ethernet interfaces + * and, hence, multiple PHYs and PHY interrupts. + * handler - The client interrupt handler to be invoked when the PHY + * asserts an interrupt. Must reside in OS space, but can + * signal tasks in user space. A value of NULL can be passed + * in order to detach and disable the PHY interrupt. + * enable - A function pointer that be unsed to enable or disable the + * PHY interrupt. + * + * Returned Value: + * The previous PHY interrupt handler address is returned. This allows you + * to temporarily replace an interrupt handler, then restore the original + * interrupt handler. NULL is returned if there is was not handler in + * place when the call was made. + * + ****************************************************************************/ + +#ifdef CONFIG_TIVA_PHY_INTERRUPTS +xcpt_t arch_phy_irq(FAR const char *intf, xcpt_t handler, phy_enable_t *enable) +{ + struct tiva_ethmac_s *priv; + irqstate_t flags; + xcpt_t oldhandler; + + DEBUGASSERT(intf); + nvdbg("%s: handler=%p\n", intf, handler); + + /* Get the interface structure associated with this interface. */ + +#if TIVA_NETHCONTROLLERS > 1 + /* REVISIT: Additional logic needed if there are multiple EMACs */ + + warning Missing logic +#endif + priv = g_tiva_ethmac; + + /* Disable interrupts until we are done. This guarantees that the + * following operations are atomic. + */ + + flags = enter_critical_section(); + + /* Get the old interrupt handler and save the new one */ + + oldhandler = priv->handler; + priv->handler = handler; + + /* Return with the interrupt disabled in any case */ + + tiva_phy_intenable(false); + + /* Return the enabling function pointer */ + + if (enable) + { + *enable = handler ? tiva_phy_intenable : NULL; + } + + /* Return the old handler (so that it can be restored) */ + + leave_critical_section(flags); + return oldhandler; +} +#endif /* CONFIG_TIVA_PHY_INTERRUPTS */ + +#endif /* TIVA_NETHCONTROLLERS > 0 */ +#endif /* CONFIG_NET && CONFIG_TIVA_ETHERNET */ diff --git a/arch/arm/src/tms570/Kconfig b/arch/arm/src/tms570/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..81136d3e339aa4b1ea8cc264cce273be8cea0b8d --- /dev/null +++ b/arch/arm/src/tms570/Kconfig @@ -0,0 +1,114 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_TMS570 + +comment "TMS570 Configuration Options" + +# Chip Capabilities + +config TMS570_HAVE_SCI2 + bool + default n + +# Summary Configurations + +# Chip Selection + +choice + prompt "TI TMS570 Chip Selection" + default ARCH_CHIP_TMS570LS1227ZWT + +config ARCH_CHIP_TMS570LS0232PZ + bool "TI TMS570LS0232PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0332PZ + bool "TI TMS570LS0332PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0432PZ + bool "TI TMS570LS0432PZ" + select ARCH_CORTEXR4 + +config ARCH_CHIP_TMS570LS0714PZ + bool "TI TMS570LS0714PZ" + select ARCH_CORTEXR4F + select TMS570_HAVE_SCI2 + +config ARCH_CHIP_TMS570LS0714PGE + bool "TI TMS570LS0714PGE" + select ARCH_CORTEXR4F + select TMS570_HAVE_SCI2 + +config ARCH_CHIP_TMS570LS0714ZWT + bool "TI TMS570LS0714ZWT" + select ARCH_CORTEXR4F + select TMS570_HAVE_SCI2 + +config ARCH_CHIP_TMS570LS1227ZWT + bool "TI TMS570LS1227ZWT" + select ARCH_CORTEXR4F + select TMS570_HAVE_SCI2 + +endchoice # TI TMS570 Chip Selection + +menu "TMS570 Peripheral Support" + +config TMS570_MIBADC + bool "MibADC" + default n + +config TMS570_DCAN1 + bool "Controller Area Network 1 (DCAN1)" + default n + +config TMS570_DCAN2 + bool "Controller Area Network 1 (DCAN2)" + default n + +config TMS570_QEP + bool "Enhanced Quadrature Encoder Unit (eQEP)" + default n + +config TMS570_N2HET + bool "High-End Timer (N2HET)" + default n + +config TMS570_DCAN1 + bool "Controller Area Network 1 (D" + default n + +config TMS570_MIBASPI1 + bool "Multi-Buffered Serial Peripheral Interface Module (MibSPI1)" + default n + +config TMS570_SCI1 + bool "Serial Communication Interface 1 (SCI1)" + default n + select ARCH_HAVE_SCI1 + select ARCH_HAVE_SERIAL_TERMIOS + +config TMS570_SCI2 + bool "Serial Communication Interface 2 (SCI2)" + default n + depends on TMS570_HAVE_SCI2 + select ARCH_HAVE_SCI1 + select ARCH_HAVE_SERIAL_TERMIOS + +endmenu # TMS570 Peripheral Support + +config TMS570_GIO_IRQ + bool "GIO pin interrupts" + ---help--- + Build in support for interrupting GIO pins + +config TMS570_SELFTEST + bool "Power-on Selftest" + default n + ---help--- + Enable power-on self-test of memories and ECC logic. + +endif # ARCH_CHIP_TMS570 diff --git a/arch/arm/src/tms570/Make.defs b/arch/arm/src/tms570/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..aaabbe4686ca5b64cca7f5117095faa36f930df2 --- /dev/null +++ b/arch/arm/src/tms570/Make.defs @@ -0,0 +1,123 @@ +############################################################################ +# arch/arm/tms570/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The vector table is the "head" object, i.e., the one that must forced into +# the link in order to draw in all of the other components + +HEAD_ASRC = arm_vectortab.S + +# Common assembly language files + +CMN_ASRCS += arm_vectors.S arm_head.S arm_fullcontextrestore.S +CMN_ASRCS += arm_saveusercontext.S arm_vectoraddrexcptn.S arm_vfork.S +CMN_ASRCS += arm_testset.S +CMN_ASRCS += cp15_coherent_dcache.S cp15_invalidate_dcache.S +CMN_ASRCS += cp15_clean_dcache.S cp15_flush_dcache.S +CMN_ASRCS += cp15_invalidate_dcache_all.S + +# Configuration dependent assembly language files + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_fpuconfig.S +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += arm_memcpy.S +endif + +# Common C source files + +CMN_CSRCS = up_allocateheap.c up_initialize.c up_idle.c up_interruptcontext.c +CMN_CSRCS += up_exit.c up_createstack.c up_releasestack.c up_usestack.c +CMN_CSRCS += up_vfork.c up_puts.c up_mdelay.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c +CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_prefetchabort.c +CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c +CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c + +# Configuration dependent C files + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += arm_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += arm_signal_dispatch.c +CMN_UASRCS += arm_signal_handler.S +endif +endif + +ifeq ($(CONFIG_ARMV7R_L2CC_PL310),y) +CMN_CSRCS += arm_l2cc_pl310.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += arm_elf.c arm_coherent_dcache.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_savefpu.S arm_restorefpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# SAMA5-specific assembly language files + +CHIP_ASRCS = + +# SAMA5-specific C source files + +CHIP_CSRCS = tms570_boot.c tms570_clockconfig.c tms570_esm.c tms570_gio.c +CHIP_CSRCS += tms570_irq.c tms570_lowputc.c tms570_serial.c + +# Configuration dependent C and assembly language files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += tms570_timerisr.c +endif + +ifeq ($(CONFIG_TMS570_SELFTEST),y) +CHIP_CSRCS += tms570_selftest.c +endif + +ifeq ($(CONFIG_TMS570_GIO_IRQ),y) +CHIP_CSRCS += tms570_gioirq.c +endif diff --git a/arch/arm/src/tms570/chip.h b/arch/arm/src/tms570/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..4d45ecad832ae7be064d3eed25cf491b3f0cb656 --- /dev/null +++ b/arch/arm/src/tms570/chip.h @@ -0,0 +1,57 @@ +/************************************************************************************ + * arch/arm/src/tms570/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/tms570_memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Cache line sizes (in bytes)for the SAVA5Dx */ + +#define ARMV7A_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7A_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_H */ diff --git a/arch/arm/src/tms570/chip/tms570_esm.h b/arch/arm/src/tms570/chip/tms570_esm.h new file mode 100644 index 0000000000000000000000000000000000000000..cd1ac9877c6d1b5d42bb4cc6bf517503d9de35c3 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_esm.h @@ -0,0 +1,211 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_esm.h + * Error Signalling Module Error Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_ESM_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_ESM_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#define ESM_GROUP1 0 +#define ESM_GROUP2 1 +#define ESM_GROUP3 2 + +/* Register Offsets *********************************************************************************/ + +#define TMS570_ESM_EEPAPR1_OFFSET 0x0000 /* ESM Enable ERROR Pin Action/Response Register 1 */ +#define TMS570_ESM_DEPAPR1_OFFSET 0x0004 /* ESM Disable ERROR Pin Action/Response Register 1 */ +#define TMS570_ESM_IESR1_OFFSET 0x0008 /* ESM Interrupt Enable Set/Status Register 1 */ +#define TMS570_ESM_IECR1_OFFSET 0x000c /* ESM Interrupt Enable Clear/Status Register 1 */ +#define TMS570_ESM_ILSR1_OFFSET 0x0010 /* Interrupt Level Set/Status Register 1 */ +#define TMS570_ESM_ILCR1_OFFSET 0x0014 /* Interrupt Level Clear/Status Register 1 */ +#define TMS570_ESM_SRA_OFFSET(n) (0x0018 + ((n) << 2)) /* n=0, 1, 2 */ +# define TMS570_ESM_SR1_OFFSET 0x0018 /* ESM Status Register for group 1 */ +# define TMS570_ESM_SR2_OFFSET 0x001c /* ESM Status Register for group 2 */ +# define TMS570_ESM_SR3_OFFSET 0x0020 /* ESM Status Register for group 3 */ +#define TMS570_ESM_EPSR_OFFSET 0x0024 /* ESM ERROR Pin Status Register */ +#define TMS570_ESM_IOFFHR_OFFSET 0x0028 /* ESM Interrupt Offset High Register */ +#define TMS570_ESM_IOFFLR_OFFSET 0x002c /* ESM Interrupt Offset Low Register */ +#define TMS570_ESM_LTCR_OFFSET 0x0030 /* ESM Low-Time Counter Register Section */ +#define TMS570_ESM_LTCPR_OFFSET 0x0034 /* ESM Low-Time Counter Preload Register */ +#define TMS570_ESM_EKR_OFFSET 0x0038 /* ESM Error Key Register */ +#define TMS570_ESM_SSR2_OFFSET 0x003c /* ESM Status Shadow Register 2 */ +#define TMS570_ESM_IEPSR4_OFFSET 0x0040 /* ESM Influence ERROR Pin Set/Status Register 4 */ +#define TMS570_ESM_IEPCR4_OFFSET 0x0044 /* ESM Influence ERROR Pin Clear/Status Register 4 */ +#define TMS570_ESM_IESR4_OFFSET 0x0048 /* ESM Interrupt Enable Set/Status Register 4 */ +#define TMS570_ESM_IECR4_OFFSET 0x004c /* ESM Interrupt Enable Clear/Status Register 4 */ +#define TMS570_ESM_ILSR4_OFFSET 0x0050 /* Interrupt Level Set/Status Register 4 */ +#define TMS570_ESM_ILCR4_OFFSET 0x0054 /* Interrupt Level Clear/Status Register 4 */ +#define TMS570_ESM_SR4_OFFSET 0x0058 /* ESM Status Register 4 */ +#define TMS570_ESM_SRB_OFFSET(n) (0x0058 + (((n)-4) << 2)) /* n=4, 5, 6 */ +# define TMS570_ESM_SR4_OFFSET 0x0058 /* ESM Status Register for group 4 */ +# define TMS570_ESM_SR5_OFFSET 0x005c /* ESM Status Register for group 5 */ +# define TMS570_ESM_SR6_OFFSET 0x0060 /* ESM Status Register for group 6 */ +#define TMS570_ESM_SSR5_OFFSET 0x0064 /* ESM Status Shadow Register 5 */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_ESM_EEPAPR1 (TMS570_ESM_BASE+TMS570_ESM_EEPAPR1_OFFSET) +#define TMS570_ESM_DEPAPR1 (TMS570_ESM_BASE+TMS570_ESM_DEPAPR1_OFFSET) +#define TMS570_ESM_IESR1 (TMS570_ESM_BASE+TMS570_ESM_IESR1_OFFSET) +#define TMS570_ESM_IECR1 (TMS570_ESM_BASE+TMS570_ESM_IECR1_OFFSET) +#define TMS570_ESM_ILSR1 (TMS570_ESM_BASE+TMS570_ESM_ILSR1_OFFSET) +#define TMS570_ESM_ILCR1 (TMS570_ESM_BASE+TMS570_ESM_ILCR1_OFFSET) +#define TMS570_ESM_SRA(n) (TMS570_ESM_BASE+TMS570_ESM_SRA_OFFSET(n)) +# define TMS570_ESM_SR1 (TMS570_ESM_BASE+TMS570_ESM_SR1_OFFSET) +# define TMS570_ESM_SR2 (TMS570_ESM_BASE+TMS570_ESM_SR2_OFFSET) +# define TMS570_ESM_SR3 (TMS570_ESM_BASE+TMS570_ESM_SR3_OFFSET) +#define TMS570_ESM_EPSR (TMS570_ESM_BASE+TMS570_ESM_EPSR_OFFSET) +#define TMS570_ESM_IOFFHR (TMS570_ESM_BASE+TMS570_ESM_IOFFHR_OFFSET) +#define TMS570_ESM_IOFFLR (TMS570_ESM_BASE+TMS570_ESM_IOFFLR_OFFSET) +#define TMS570_ESM_LTCR (TMS570_ESM_BASE+TMS570_ESM_LTCR_OFFSET) +#define TMS570_ESM_LTCPR (TMS570_ESM_BASE+TMS570_ESM_LTCPR_OFFSET) +#define TMS570_ESM_EKR (TMS570_ESM_BASE+TMS570_ESM_EKR_OFFSET) +#define TMS570_ESM_SSR2 (TMS570_ESM_BASE+TMS570_ESM_SSR2_OFFSET) +#define TMS570_ESM_IEPSR4 (TMS570_ESM_BASE+TMS570_ESM_IEPSR4_OFFSET) +#define TMS570_ESM_IEPCR4 (TMS570_ESM_BASE+TMS570_ESM_IEPCR4_OFFSET) +#define TMS570_ESM_IESR4 (TMS570_ESM_BASE+TMS570_ESM_IESR4_OFFSET) +#define TMS570_ESM_IECR4 (TMS570_ESM_BASE+TMS570_ESM_IECR4_OFFSET) +#define TMS570_ESM_ILSR4 (TMS570_ESM_BASE+TMS570_ESM_ILSR4_OFFSET) +#define TMS570_ESM_ILCR4 (TMS570_ESM_BASE+TMS570_ESM_ILCR4_OFFSET) +#define TMS570_ESM_SR4 (TMS570_ESM_BASE+TMS570_ESM_SR4_OFFSET) +#define TMS570_ESM_SRB(n) (TMS570_ESM_BASE+TMS570_ESM_SRB_OFFSET(n)) +# define TMS570_ESM_SR4 (TMS570_ESM_BASE+TMS570_ESM_SR4_OFFSET) +# define TMS570_ESM_SR5 (TMS570_ESM_BASE+TMS570_ESM_SR5_OFFSET) +# define TMS570_ESM_SR6 (TMS570_ESM_BASE+TMS570_ESM_SR6_OFFSET) +#define TMS570_ESM_SSR5 (TMS570_ESM_BASE+TMS570_ESM_SSR5_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* ESM Enable ERROR Pin Action/Response Register 1 */ + +#define ESM_EEPAPR1_CHAN(n) (1 << (n)) /* Bit n: Channel n enable */ + +/* ESM Disable ERROR Pin Action/Response Register 1 */ + +#define ESM_DEPAPR1_CHAN(n) (1 << (n)) /* Bit n: Channel n disable */ + +/* ESM Interrupt Enable Set/Status Register 1 */ + +#define ESM_IESR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt enable */ + +/* ESM Interrupt Enable Clear/Status Register 1 */ + +#define ESM_IECR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt clear */ + +/* Interrupt Level Set/Status Register 1 */ + +#define ESM_ILSR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt level high */ + +/* Interrupt Level Clear/Status Register 1 */ + +#define ESM_ILCR1_INT(n) (1 << (n)) /* Bit n: Channel n interrupt level low (write) */ + +/* ESM Status Register for groups 1, 2, 3, and 4 */ + +#define ESM_SR_PENDING(n) (1 << (n)) /* Bit n: Channel n error interrupt pending (read) */ +#define ESM_SR_CLEAR(n) (1 << (n)) /* Bit n: Channel n error interrupt clear (write) */ + +/* ESM ERROR Pin Status Register */ + +#define ESM_EPSR_NOERROR(n) (1 << (n)) /* Bit n: Channel n no error (read) */ + +/* ESM Interrupt Offset High Register */ + +#define ESM_IOFFHR_MASK 0x0000007f /* Bits 0-6: Interrupt offset high level */ + +/* ESM Interrupt Offset Low Register */ + +#define ESM_IOFFLR_MASK 0x0000007f /* Bits 0-6: Interrupt offset low level */ + +/* ESM Low-Time Counter Register Section */ + +#define ESM_LTCR_MASK 0x0000ffff /* Bits 0-15: ERROR pin low time counter */ + +/* ESM Low-Time Counter Preload Register */ + +#define ESM_LTCPR_MASK 0x0000ffff /* Bits 0-15: ERROR pin low time counter pre-load */ + +/* ESM Error Key Register */ + +#define ESM_EKR_MASK 0x0000000f /* Bits 0-3: Error key value */ +# define ESM_EKR_NORMAL 0x00000000 /* Activates normal mode */ +# define ESM_EKR_ERROR 0x00000005 /* nERROR set high when LTC completes */ +# define ESM_EKR_FORCE 0x0000000a /* Forces error on nERROR pin */ + +/* ESM Status Shadow Register 2 */ + +#define ESM_SSR2_ERROR(n) (1 << (n)) /* Bit n: Channel n error occurred (read) */ +#define ESM_SSR2_CLEAR(n) (1 << (n)) /* Bit n: Channel n error clear (write) */ + +/* ESM Influence ERROR Pin Set/Status Register 4 */ + +#define ESM_IEPSR4_CHAN(n) (1 << (n)) /* Bit n: Channel n read failure enable */ + +/* ESM Influence ERROR Pin Clear/Status Register 4 */ + +#define ESM_IEPCR4_CHAN(n) (1 << (n)) /* Bit n: Channel n read failure disable */ + +/* ESM Interrupt Enable Set/Status Register 4 */ + +#define ESM_IESR4_CHAN(n) (1 << (n)) /* Bit n: Channel n interrupt enable */ + +/* ESM Interrupt Enable Clear/Status Register 4 */ + +#define ESM_IECR4_CHAN(n) (1 << (n)) /* Bit n: Channel n interrupt disable */ + +/* Interrupt Level Set/Status Register 4 */ + +#define ESM_ILSR4_CHAN(n) (1 << (n)) /* Bit n: Maps channel n high level interrupt */ + +/* Interrupt Level Clear/Status Register 4 */ + +#define ESM_ILCR4_CHAN(n) (1 << (n)) /* Bit n: Maps channel n low level interrupt */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_ESM_H */ diff --git a/arch/arm/src/tms570/chip/tms570_flash.h b/arch/arm/src/tms570/chip/tms570_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..d1b14666760cd58747a249bc131dd76e9382712a --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_flash.h @@ -0,0 +1,271 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_flash.h + * FLASH Module Controller Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_FLASH_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_FLASH_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_FLASH_FRDCNTL_OFFSET 0x000 /* Flash Option Control Register */ +#define TMS570_FLASH_FEDACTRL1_OFFSET 0x008 /* Flash Error Detection and Correction Control Register 1 */ +#define TMS570_FLASH_FEDACTRL2_OFFSET 0x00c /* Flash Error Detection and Correction Control Register 2 */ +#define TMS570_FLASH_FCORERRCNT_OFFSET 0x010 /* Flash Correctable Error Count Register */ +#define TMS570_FLASH_FCORERRADD_OFFSET 0x014 /* Flash Correctable Error Address Register */ +#define TMS570_FLASH_FCORERRPOS_OFFSET 0x018 /* Flash Correctable Error Position Register */ +#define TMS570_FLASH_FEDACSTATUS_OFFSET 0x01c /* Flash Error Detection and Correction Status Register */ +#define TMS570_FLASH_FUNCERRADD_OFFSET 0x020 /* Flash Un-Correctable Error Address Register */ +#define TMS570_FLASH_FEDACSDIS_OFFSET 0x024 /* Flash Error Detection and Correction Sector Disable Register */ +#define TMS570_FLASH_FPRIMADDTAG_OFFSET 0x028 /* Flash Primary Address Tag Register */ +#define TMS570_FLASH_FDUPDDTAG_OFFSET 0x02c /* Flash Duplicate Address Tag Register */ +#define TMS570_FLASH_FBPROT_OFFSET 0x030 /* Flash Bank Protection Register */ +#define TMS570_FLASH_FBSE_OFFSET 0x034 /* Flash Bank Sector Enable Register */ +#define TMS570_FLASH_FBBUSY_OFFSET 0x038 /* Flash Bank Busy Register */ +#define TMS570_FLASH_FBAC_OFFSET 0x03c /* Flash Bank Access Control Register */ +#define TMS570_FLASH_FBFALLBACK_OFFSET 0x040 /* Flash Bank Fallback Power Register */ +#define TMS570_FLASH_FBPRDY_OFFSET 0x044 /* Flash Bank/Pump Ready Register */ +#define TMS570_FLASH_FPAC1_OFFSET 0x048 /* Flash Pump Access Control Register 1 */ +#define TMS570_FLASH_FPAC2_OFFSET 0x04c /* Flash Pump Access Control Register 2 */ +#define TMS570_FLASH_FMAC_OFFSET 0x050 /* Flash Module Access Control Register */ +#define TMS570_FLASH_FMSTAT_OFFSET 0x054 /* Flash Module Status Register */ +#define TMS570_FLASH_FEMUDMSW_OFFSET 0x058 /* EEPROM Emulation Data MSW Register */ +#define TMS570_FLASH_FEMUDLSW_OFFSET 0x05c /* EEPROM Emulation Data LSW Register */ +#define TMS570_FLASH_FEMUECC_OFFSET 0x060 /* EEPROM Emulation ECC Register */ +#define TMS570_FLASH_FEMUADDR_OFFSET 0x068 /* EEPROM Emulation Address Register */ +#define TMS570_FLASH_FDIAGCTRL_OFFSET 0x06c /* Diagnostic Control Register */ +#define TMS570_FLASH_FRAWDATAH_OFFSET 0x070 /* Uncorrected Raw Data High Register */ +#define TMS570_FLASH_FRAWDATAL_OFFSET 0x074 /* Uncorrected Raw Data Low Register */ +#define TMS570_FLASH_FRAWECC_OFFSET 0x078 /* Uncorrected Raw ECC Register */ +#define TMS570_FLASH_FPAROVR_OFFSET 0x07c /* Parity Override Register */ +#define TMS570_FLASH_FEDACSDIS2_OFFSET 0x0c0 /* Flash Error Detection and Correction Sector Disable Register 2 */ +#define TMS570_FLASH_FSMWRENA_OFFSET 0x288 /* FSM Register Write Enable */ +#define TMS570_FLASH_FSMSECTOR_OFFSET 0x2a4 /* FSM Sector Register */ +#define TMS570_FLASH_EEPROMCFG_OFFSET 0x2b8 /* EEPROM Emulation Configuration Register */ +#define TMS570_FLASH_EECTRL1_OFFSET 0x308 /* EEPROM Emulation Error Detection and Correction Control Register 1 */ +#define TMS570_FLASH_EECTRL2_OFFSET 0x30c /* EEPROM Emulation Error Detection and Correction Control Register 2 */ +#define TMS570_FLASH_EECORERRCNT_OFFSET 0x310 /* EEPROM Emulation Correctable Error Count Register */ +#define TMS570_FLASH_EECORERRADD_OFFSET 0x314 /* EEPROM Emulation Correctable Error Address Register */ +#define TMS570_FLASH_EECORERRPOS_OFFSET 0x318 /* EEPROM Emulation Correctable Error Bit Position Register */ +#define TMS570_FLASH_EESTATUS_OFFSET 0x31c /* EEPROM Emulation Error Status Register */ +#define TMS570_FLASH_EEUNCERRADD_OFFSET 0x320 /* EEPROM Emulation Un-Correctable Error Address Register */ +#define TMS570_FLASH_FCFGBANK_OFFSET 0x400 /* Flash Bank Configuration Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_FLASH_FRDCNTL (TMS570_FWRAP_BASE+TMS570_FLASH_FRDCNTL_OFFSET) +#define TMS570_FLASH_FEDACTRL1 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACTRL1_OFFSET) +#define TMS570_FLASH_FEDACTRL2 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACTRL2_OFFSET) +#define TMS570_FLASH_FCORERRCNT (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRCNT_OFFSET) +#define TMS570_FLASH_FCORERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRADD_OFFSET) +#define TMS570_FLASH_FCORERRPOS (TMS570_FWRAP_BASE+TMS570_FLASH_FCORERRPOS_OFFSET) +#define TMS570_FLASH_FEDACSTATUS (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSTATUS_OFFSET) +#define TMS570_FLASH_FUNCERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_FUNCERRADD_OFFSET) +#define TMS570_FLASH_FEDACSDIS (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSDIS_OFFSET) +#define TMS570_FLASH_FPRIMADDTAG (TMS570_FWRAP_BASE+TMS570_FLASH_FPRIMADDTAG_OFFSET) +#define TMS570_FLASH_FDUPDDTAG (TMS570_FWRAP_BASE+TMS570_FLASH_FDUPDDTAG_OFFSET) +#define TMS570_FLASH_FBPROT (TMS570_FWRAP_BASE+TMS570_FLASH_FBPROT_OFFSET) +#define TMS570_FLASH_FBSE (TMS570_FWRAP_BASE+TMS570_FLASH_FBSE_OFFSET) +#define TMS570_FLASH_FBBUSY (TMS570_FWRAP_BASE+TMS570_FLASH_FBBUSY_OFFSET) +#define TMS570_FLASH_FBAC (TMS570_FWRAP_BASE+TMS570_FLASH_FBAC_OFFSET) +#define TMS570_FLASH_FBFALLBACK (TMS570_FWRAP_BASE+TMS570_FLASH_FBFALLBACK_OFFSET) +#define TMS570_FLASH_FBPRDY (TMS570_FWRAP_BASE+TMS570_FLASH_FBPRDY_OFFSET) +#define TMS570_FLASH_FPAC1 (TMS570_FWRAP_BASE+TMS570_FLASH_FPAC1_OFFSET) +#define TMS570_FLASH_FPAC2 (TMS570_FWRAP_BASE+TMS570_FLASH_FPAC2_OFFSET) +#define TMS570_FLASH_FMAC (TMS570_FWRAP_BASE+TMS570_FLASH_FMAC_OFFSET) +#define TMS570_FLASH_FMSTAT (TMS570_FWRAP_BASE+TMS570_FLASH_FMSTAT_OFFSET) +#define TMS570_FLASH_FEMUDMSW (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUDMSW_OFFSET) +#define TMS570_FLASH_FEMUDLSW (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUDLSW_OFFSET) +#define TMS570_FLASH_FEMUECC (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUECC_OFFSET) +#define TMS570_FLASH_FEMUADDR (TMS570_FWRAP_BASE+TMS570_FLASH_FEMUADDR_OFFSET) +#define TMS570_FLASH_FDIAGCTRL (TMS570_FWRAP_BASE+TMS570_FLASH_FDIAGCTRL_OFFSET) +#define TMS570_FLASH_FRAWDATAH (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWDATAH_OFFSET) +#define TMS570_FLASH_FRAWDATAL (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWDATAL_OFFSET) +#define TMS570_FLASH_FRAWECC (TMS570_FWRAP_BASE+TMS570_FLASH_FRAWECC_OFFSET) +#define TMS570_FLASH_FPAROVR (TMS570_FWRAP_BASE+TMS570_FLASH_FPAROVR_OFFSET) +#define TMS570_FLASH_FEDACSDIS2 (TMS570_FWRAP_BASE+TMS570_FLASH_FEDACSDIS2_OFFSET) +#define TMS570_FLASH_FSMWRENA (TMS570_FWRAP_BASE+TMS570_FLASH_FSMWRENA_OFFSET) +#define TMS570_FLASH_FSMSECTOR (TMS570_FWRAP_BASE+TMS570_FLASH_FSMSECTOR_OFFSET) +#define TMS570_FLASH_EEPROMCFG (TMS570_FWRAP_BASE+TMS570_FLASH_EEPROMCFG_OFFSET) +#define TMS570_FLASH_EECTRL1 (TMS570_FWRAP_BASE+TMS570_FLASH_EECTRL1_OFFSET) +#define TMS570_FLASH_EECTRL2 (TMS570_FWRAP_BASE+TMS570_FLASH_EECTRL2_OFFSET) +#define TMS570_FLASH_EECORERRCNT (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRCNT_OFFSET) +#define TMS570_FLASH_EECORERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRADD_OFFSET) +#define TMS570_FLASH_EECORERRPOS (TMS570_FWRAP_BASE+TMS570_FLASH_EECORERRPOS_OFFSET) +#define TMS570_FLASH_EESTATUS (TMS570_FWRAP_BASE+TMS570_FLASH_EESTATUS_OFFSET) +#define TMS570_FLASH_EEUNCERRADD (TMS570_FWRAP_BASE+TMS570_FLASH_EEUNCERRADD_OFFSET) +#define TMS570_FLASH_FCFGBANK (TMS570_FWRAP_BASE+TMS570_FLASH_FCFGBANK_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Flash Option Control Register */ + +#define FLASH_FRDCNTL_ENPIPE (1 << 0) /* Bit 0: Enable Pipeline Mode */ +#define FLASH_FRDCNTL_ASWSTEN (1 << 4) /* Bit 4: Address Setup Wait State Enable */ +#define FLASH_FRDCNTL_RWAIT_SHIFT (8) /* Bits 8-11: Random/data Read Wait State */ +#define FLASH_FRDCNTL_RWAIT_MASK (15 << FLASH_FRDCNTL_RWAIT_SHIFT) +# define FLASH_FRDCNTL_RWAIT(n) ((uint32_t)(n) << FLASH_FRDCNTL_RWAIT_SHIFT) + +/* Flash Error Detection and Correction Control Register 1 */ +#define FLASH_FEDACTRL1_ +/* Flash Error Detection and Correction Control Register 2 */ +#define FLASH_FEDACTRL2_ +/* Flash Correctable Error Count Register */ +#define FLASH_FCORERRCNT_ +/* Flash Correctable Error Address Register */ +#define FLASH_FCORERRADD_ +/* Flash Correctable Error Position Register */ +#define FLASH_FCORERRPOS_ +/* Flash Error Detection and Correction Status Register */ +#define FLASH_FEDACSTATUS_ +/* Flash Un-Correctable Error Address Register */ +#define FLASH_FUNCERRADD_ +/* Flash Error Detection and Correction Sector Disable Register */ +#define FLASH_FEDACSDIS_ +/* Flash Primary Address Tag Register */ +#define FLASH_FPRIMADDTAG_ +/* Flash Duplicate Address Tag Register */ +#define FLASH_FDUPDDTAG_ +/* Flash Bank Protection Register */ +#define FLASH_FBPROT_ +/* Flash Bank Sector Enable Register */ +#define FLASH_FBSE_ +/* Flash Bank Busy Register */ +#define FLASH_FBBUSY_ +/* Flash Bank Access Control Register */ +#define FLASH_FBAC_ + +/* Flash Bank Fallback Power Register */ + +#define FLASH_FBFALLBACK_BANKPWR0_SHIFT (0) /* Bit 0: Bank 0 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR0_MASK (3 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_STDBY (1 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR0_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR0_SHIFT) +#define FLASH_FBFALLBACK_BANKPWR1_SHIFT (2) /* Bit 2: Bank 1 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR1_MASK (3 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_STDBY (1 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR1_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR1_SHIFT) +#define FLASH_FBFALLBACK_BANKPWR7_SHIFT (14) /* Bit 14: Bank 7 Fallback Power Mode */ +#define FLASH_FBFALLBACK_BANKPWR7_MASK (3 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_SLEEP (0 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_STDBY (1 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) +# define FLASH_FBFALLBACK_BANKPWR7_ACTIV (3 << FLASH_FBFALLBACK_BANKPWR7_SHIFT) + +/* Flash Bank/Pump Ready Register */ +#define FLASH_FBPRDY_ +/* Flash Pump Access Control Register 1 */ +#define FLASH_FPAC1_ +/* Flash Pump Access Control Register 2 */ +#define FLASH_FPAC2_ +/* Flash Module Access Control Register */ +#define FLASH_FMAC_ +/* Flash Module Status Register */ +#define FLASH_FMSTAT_ +/* EEPROM Emulation Data MSW Register */ +#define FLASH_FEMUDMSW_ +/* EEPROM Emulation Data LSW Register */ +#define FLASH_FEMUDLSW_ +/* EEPROM Emulation ECC Register */ +#define FLASH_FEMUECC_ +/* EEPROM Emulation Address Register */ +#define FLASH_FEMUADDR_ +/* Diagnostic Control Register */ +#define FLASH_FDIAGCTRL_ +/* Uncorrected Raw Data High Register */ +#define FLASH_FRAWDATAH_ +/* Uncorrected Raw Data Low Register */ +#define FLASH_FRAWDATAL_ +/* Uncorrected Raw ECC Register */ +#define FLASH_FRAWECC_ +/* Parity Override Register */ +#define FLASH_FPAROVR_ +/* Flash Error Detection and Correction Sector Disable Register 2 */ +#define FLASH_FEDACSDIS2_ + +/* FSM Register Write Enable */ + +#define FLASH_FSMWRENA_ENABLE_SHIFT (0) /* Bits 0-2: FSM Write Enable */ +#define FLASH_FSMWRENA_ENABLE_MASK (7 << FLASH_FSMWRENA_ENABLE_SHIFT) +# define FLASH_FSMWRENA_ENABLE (5 << FLASH_FSMWRENA_ENABLE_SHIFT) /* Enable write to FSM registers */ +# define FLASH_FSMWRENA_DISABLE (2 << FLASH_FSMWRENA_ENABLE_SHIFT) /* Any other value disables */ + +/* FSM Sector Register */ +#define FLASH_FSMSECTOR_ + +/* EEPROM Emulation Configuration Register */ + +#define FLASH_EEPROMCFG_GRACE_SHIFT (0) /* Bits 0-7: Auto-suspend Startup Grace Period */ +#define FLASH_EEPROMCFG_GRACE_MASK (0xff << FLASH_EEPROMCFG_GRACE_SHIFT) +# define FLASH_EEPROMCFG_GRACE(n) ((uint32_t)(n) << FLASH_EEPROMCFG_GRACE_SHIFT) +#define FLASH_EEPROMCFG_AUTOSUSPEN (1 << 8) /* Bit 8: Auto suspend enable */ +#define FLASH_EEPROMCFG_EWAIT_SHIFT (16) /* Bits 16-19: EEPROM Wait state Counter */ +#define FLASH_EEPROMCFG_EWAIT_MASK (15 << FLASH_EEPROMCFG_EWAIT_SHIFT) +# define FLASH_EEPROMCFG_EWAIT(n) ((uint32_t)(n) << FLASH_EEPROMCFG_EWAIT_SHIFT) + +/* EEPROM Emulation Error Detection and Correction Control Register 1 */ +#define FLASH_EECTRL1_ +/* EEPROM Emulation Error Detection and Correction Control Register 2 */ +#define FLASH_EECTRL2_ +/* EEPROM Emulation Correctable Error Count Register */ +#define FLASH_EECORERRCNT_ +/* EEPROM Emulation Correctable Error Address Register */ +#define FLASH_EECORERRADD_ +/* EEPROM Emulation Correctable Error Bit Position Register */ +#define FLASH_EECORERRPOS_ +/* EEPROM Emulation Error Status Register */ +#define FLASH_EESTATUS_ +/* EEPROM Emulation Un-Correctable Error Address Register */ +#define FLASH_EEUNCERRADD_ +/* Flash Bank Configuration Register */ +#define FLASH_FCFGBANK_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_FLASH_H */ diff --git a/arch/arm/src/tms570/chip/tms570_gio.h b/arch/arm/src/tms570/chip/tms570_gio.h new file mode 100644 index 0000000000000000000000000000000000000000..1599e58ff5a34bb603b4859a80a2b3a47ab0db40 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_gio.h @@ -0,0 +1,445 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_gio.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_GIO_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_GIO_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#define TMS570_GIOA 0 +#define TMS570_GIOB 1 +#define TMS570_GIOC 2 +#define TMS570_GIOD 3 +#define TMS570_GIOE 4 +#define TMS570_GIOF 5 +#define TMS570_GIOG 6 +#define TMS570_GIOH 7 + +#define TMS570_NPORTS 8 +#define TMS570_NIRQPORTS 4 + +/* Register Offsets *********************************************************************************/ + +#define TMS570_GIO_GCR0_OFFSET 0x0000 /* GIO Global Control Register */ +#define TMS570_GIO_INTDET_OFFSET 0x0008 /* GIO Interrupt Detect Register */ +#define TMS570_GIO_POL_OFFSET 0x000c /* GIO Interrupt Polarity Register */ +#define TMS570_GIO_ENASET_OFFSET 0x0010 /* GIO Interrupt Enable Set Register */ +#define TMS570_GIO_ENACLR_OFFSET 0x0014 /* GIO Interrupt Enable Clear Register */ +#define TMS570_GIO_LVLSET_OFFSET 0x0018 /* GIO Interrupt Priority Set Register */ +#define TMS570_GIO_LVLCLR_OFFSET 0x001c /* GIO Interrupt Priority Clear Register */ +#define TMS570_GIO_FLG_OFFSET 0x0020 /* GIO Interrupt Flag Register */ +#define TMS570_GIO_OFF1_OFFSET 0x0024 /* GIO Offset 1 Register */ +#define TMS570_GIO_OFF2_OFFSET 0x0028 /* GIO Offset 2 Register */ +#define TMS570_GIO_EMU1_OFFSET 0x002c /* GIO Emulation 1 Register */ +#define TMS570_GIO_EMU2_OFFSET 0x0030 /* GIO Emulation 2 Register */ + +#define TMS570_GIO_OFFSET(n) (0x0034 + ((n) << 5)) +#define TMS570_GIO_DIR_OFFSET 0x0000 /* GIO Data Direction Register */ +#define TMS570_GIO_DIN_OFFSET 0x0004 /* GIO Data Input Register */ +#define TMS570_GIO_DOUT_OFFSET 0x0008 /* GIO Data Output Register */ +#define TMS570_GIO_DSET_OFFSET 0x000c /* GIO Data Set Register */ +#define TMS570_GIO_DCLR_OFFSET 0x0010 /* GIO Data Clear Register */ +#define TMS570_GIO_PDR_OFFSET 0x0014 /* GIO Open Drain Register */ +#define TMS570_GIO_PULDIS_OFFSET 0x0018 /* GIO Pull Disable Register */ +#define TMS570_GIO_PSL_OFFSET 0x001c /* GIO Pull Select Register */ + +#define TMS570_GIOA_DIR_OFFSET 0x0034 /* GIOA Data Direction Register */ +#define TMS570_GIOA_DIN_OFFSET 0x0038 /* GIOA Data Input Register */ +#define TMS570_GIOA_DOUT_OFFSET 0x003c /* GIOA Data Output Register */ +#define TMS570_GIOA_DSET_OFFSET 0x0040 /* GIOA Data Set Register */ +#define TMS570_GIOA_DCLR_OFFSET 0x0044 /* GIOA Data Clear Register */ +#define TMS570_GIOA_PDR_OFFSET 0x0048 /* GIOA Open Drain Register */ +#define TMS570_GIOA_PULDIS_OFFSET 0x004c /* GIOA Pull Disable Register */ +#define TMS570_GIOA_PSL_OFFSET 0x0050 /* GIOA Pull Select Register */ + +#define TMS570_GIOB_DIR_OFFSET 0x0054 /* GIOB Data Direction Register */ +#define TMS570_GIOB_DIN_OFFSET 0x0058 /* GIOB Data Input Register */ +#define TMS570_GIOB_DOUT_OFFSET 0x005c /* GIOB Data Output Register */ +#define TMS570_GIOB_DSET_OFFSET 0x0060 /* GIOB Data Set Register */ +#define TMS570_GIOB_DCLR_OFFSET 0x0064 /* GIOB Data Clear Register */ +#define TMS570_GIOB_PDR_OFFSET 0x0068 /* GIOB Open Drain Register */ +#define TMS570_GIOB_PULDIS_OFFSET 0x006c /* GIOB Pull Disable Register */ +#define TMS570_GIOB_PSL_OFFSET 0x0070 /* GIOB Pull Select Register */ + +#define TMS570_GIOC_DIR_OFFSET 0x0074 /* GIOC Data Direction Register */ +#define TMS570_GIOC_DIN_OFFSET 0x0078 /* GIOC Data Input Register */ +#define TMS570_GIOC_DOUT_OFFSET 0x007c /* GIOC Data Output Register */ +#define TMS570_GIOC_DSET_OFFSET 0x0080 /* GIOC Data Set Register */ +#define TMS570_GIOC_DCLR_OFFSET 0x0084 /* GIOC Data Clear Register */ +#define TMS570_GIOC_PDR_OFFSET 0x0088 /* GIOC Open Drain Register */ +#define TMS570_GIOC_PULDIS_OFFSET 0x008c /* GIOC Pull Disable Register */ +#define TMS570_GIOC_PSL_OFFSET 0x0090 /* GIOC Pull Select Register */ + +#define TMS570_GIOD_DIR_OFFSET 0x0094 /* GIOD Data Direction Register */ +#define TMS570_GIOD_DIN_OFFSET 0x0098 /* GIOD Data Input Register */ +#define TMS570_GIOD_DOUT_OFFSET 0x009c /* GIOD Data Output Register */ +#define TMS570_GIOD_DSET_OFFSET 0x00a0 /* GIOD Data Set Register */ +#define TMS570_GIOD_DCLR_OFFSET 0x00a4 /* GIOD Data Clear Register */ +#define TMS570_GIOD_PDR_OFFSET 0x00a8 /* GIOD Open Drain Register */ +#define TMS570_GIOD_PULDIS_OFFSET 0x00ac /* GIOD Pull Disable Register */ +#define TMS570_GIOD_PSL_OFFSET 0x00b0 /* GIOD Pull Select Register */ + +#define TMS570_GIOE_DIR_OFFSET 0x00b4 /* GIOE Data Direction Register */ +#define TMS570_GIOE_DIN_OFFSET 0x00b8 /* GIOE Data Input Register */ +#define TMS570_GIOE_DOUT_OFFSET 0x00bc /* GIOE Data Output Register */ +#define TMS570_GIOE_DSET_OFFSET 0x00c0 /* GIOE Data Set Register */ +#define TMS570_GIOE_DCLR_OFFSET 0x00c4 /* GIOE Data Clear Register */ +#define TMS570_GIOE_PDR_OFFSET 0x00c8 /* GIOE Open Drain Register */ +#define TMS570_GIOE_PULDIS_OFFSET 0x00cc /* GIOE Pull Disable Register */ +#define TMS570_GIOE_PSL_OFFSET 0x00d0 /* GIOE Pull Select Register */ + +#define TMS570_GIOF_DIR_OFFSET 0x00d4 /* GIOF Data Direction Register */ +#define TMS570_GIOF_DIN_OFFSET 0x00d8 /* GIOF Data Input Register */ +#define TMS570_GIOF_DOUT_OFFSET 0x00dc /* GIOF Data Output Register */ +#define TMS570_GIOF_DSET_OFFSET 0x00e0 /* GIOF Data Set Register */ +#define TMS570_GIOF_DCLR_OFFSET 0x00e4 /* GIOF Data Clear Register */ +#define TMS570_GIOF_PDR_OFFSET 0x00e8 /* GIOF Open Drain Register */ +#define TMS570_GIOF_PULDIS_OFFSET 0x00ec /* GIOF Pull Disable Register */ +#define TMS570_GIOF_PSL_OFFSET 0x00f0 /* GIOF Pull Select Register */ + +#define TMS570_GIOG_DIR_OFFSET 0x00f4 /* GIOG Data Direction Register */ +#define TMS570_GIOG_DIN_OFFSET 0x00f8 /* GIOG Data Input Register */ +#define TMS570_GIOG_DOUT_OFFSET 0x00fc /* GIOG Data Output Register */ +#define TMS570_GIOG_DSET_OFFSET 0x0100 /* GIOG Data Set Register */ +#define TMS570_GIOG_DCLR_OFFSET 0x0104 /* GIOG Data Clear Register */ +#define TMS570_GIOG_PDR_OFFSET 0x0108 /* GIOG Open Drain Register */ +#define TMS570_GIOG_PULDIS_OFFSET 0x010c /* GIOG Pull Disable Register */ +#define TMS570_GIOG_PSL_OFFSET 0x0110 /* GIOG Pull Select Register */ + +#define TMS570_GIOH_DIR_OFFSET 0x0114 /* GIOH Data Direction Register */ +#define TMS570_GIOH_DIN_OFFSET 0x0118 /* GIOH Data Input Register */ +#define TMS570_GIOH_DOUT_OFFSET 0x011c /* GIOH Data Output Register */ +#define TMS570_GIOH_DSET_OFFSET 0x0120 /* GIOH Data Set Register */ +#define TMS570_GIOH_DCLR_OFFSET 0x0124 /* GIOH Data Clear Register */ +#define TMS570_GIOH_PDR_OFFSET 0x0128 /* GIOH Open Drain Register */ +#define TMS570_GIOH_PULDIS_OFFSET 0x012c /* GIOH Pull Disable Register */ +#define TMS570_GIOH_PSL_OFFSET 0x0130 /* GIOH Pull Select Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_GIO_GCR0 (TMS570_GIO_BASE+TMS570_GIO_GCR0_OFFSET) +#define TMS570_GIO_INTDET (TMS570_GIO_BASE+TMS570_GIO_INTDET_OFFSET) +#define TMS570_GIO_POL (TMS570_GIO_BASE+TMS570_GIO_POL_OFFSET) +#define TMS570_GIO_ENASET (TMS570_GIO_BASE+TMS570_GIO_ENASET_OFFSET) +#define TMS570_GIO_ENACLR (TMS570_GIO_BASE+TMS570_GIO_ENACLR_OFFSET) +#define TMS570_GIO_LVLSET (TMS570_GIO_BASE+TMS570_GIO_LVLSET_OFFSET) +#define TMS570_GIO_LVLCLR (TMS570_GIO_BASE+TMS570_GIO_LVLCLR_OFFSET) +#define TMS570_GIO_FLG (TMS570_GIO_BASE+TMS570_GIO_FLG_OFFSET) +#define TMS570_GIO_OFF1 (TMS570_GIO_BASE+TMS570_GIO_OFF1_OFFSET) +#define TMS570_GIO_OFF2 (TMS570_GIO_BASE+TMS570_GIO_OFF2_OFFSET) +#define TMS570_GIO_EMU1 (TMS570_GIO_BASE+TMS570_GIO_EMU1_OFFSET) +#define TMS570_GIO_EMU2 (TMS570_GIO_BASE+TMS570_GIO_EMU2_OFFSET) + +#define TMS570_GIO_PORTBASE(n) (TMS570_GIO_BASE+TMS570_GIO_OFFSET(n)) +#define TMS570_GIO_DIR(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_DIR_OFFSET) +#define TMS570_GIO_DIN(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_DIN_OFFSET) +#define TMS570_GIO_DOUT(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_DOUT_OFFSET) +#define TMS570_GIO_DSET(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_DSET_OFFSET) +#define TMS570_GIO_DCLR(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_DCLR_OFFSET) +#define TMS570_GIO_PDR(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_PDR_OFFSET) +#define TMS570_GIO_PULDIS(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_PULDIS_OFFSET) +#define TMS570_GIO_PSL(n) (TMS570_GIO_PORTBASE(n)+TMS570_GIO_PSL_OFFSET) + +#define TMS570_GIOA_DIR (TMS570_GIO_BASE+TMS570_GIOA_DIR_OFFSET) +#define TMS570_GIOA_DIN (TMS570_GIO_BASE+TMS570_GIOA_DIN_OFFSET) +#define TMS570_GIOA_DOUT (TMS570_GIO_BASE+TMS570_GIOA_DOUT_OFFSET) +#define TMS570_GIOA_DSET (TMS570_GIO_BASE+TMS570_GIOA_DSET_OFFSET) +#define TMS570_GIOA_DCLR (TMS570_GIO_BASE+TMS570_GIOA_DCLR_OFFSET) +#define TMS570_GIOA_PDR (TMS570_GIO_BASE+TMS570_GIOA_PDR_OFFSET) +#define TMS570_GIOA_PULDIS (TMS570_GIO_BASE+TMS570_GIOA_PULDIS_OFFSET) +#define TMS570_GIOA_PSL (TMS570_GIO_BASE+TMS570_GIOA_PSL_OFFSET) + +#define TMS570_GIOB_DIR (TMS570_GIO_BASE+TMS570_GIOB_DIR_OFFSET) +#define TMS570_GIOB_DIN (TMS570_GIO_BASE+TMS570_GIOB_DIN_OFFSET) +#define TMS570_GIOB_DOUT (TMS570_GIO_BASE+TMS570_GIOB_DOUT_OFFSET) +#define TMS570_GIOB_DSET (TMS570_GIO_BASE+TMS570_GIOB_DSET_OFFSET) +#define TMS570_GIOB_DCLR (TMS570_GIO_BASE+TMS570_GIOB_DCLR_OFFSET) +#define TMS570_GIOB_PDR (TMS570_GIO_BASE+TMS570_GIOB_PDR_OFFSET) +#define TMS570_GIOB_PULDIS (TMS570_GIO_BASE+TMS570_GIOB_PULDIS_OFFSET) +#define TMS570_GIOB_PSL (TMS570_GIO_BASE+TMS570_GIOB_PSL_OFFSET) + +#define TMS570_GIOC_DIR (TMS570_GIO_BASE+TMS570_GIOC_DIR_OFFSET) +#define TMS570_GIOC_DIN (TMS570_GIO_BASE+TMS570_GIOC_DIN_OFFSET) +#define TMS570_GIOC_DOUT (TMS570_GIO_BASE+TMS570_GIOC_DOUT_OFFSET) +#define TMS570_GIOC_DSET (TMS570_GIO_BASE+TMS570_GIOC_DSET_OFFSET) +#define TMS570_GIOC_DCLR (TMS570_GIO_BASE+TMS570_GIOC_DCLR_OFFSET) +#define TMS570_GIOC_PDR (TMS570_GIO_BASE+TMS570_GIOC_PDR_OFFSET) +#define TMS570_GIOC_PULDIS (TMS570_GIO_BASE+TMS570_GIOC_PULDIS_OFFSET) +#define TMS570_GIOC_PSL (TMS570_GIO_BASE+TMS570_GIOC_PSL_OFFSET) + +#define TMS570_GIOD_DIR (TMS570_GIO_BASE+TMS570_GIOD_DIR_OFFSET) +#define TMS570_GIOD_DIN (TMS570_GIO_BASE+TMS570_GIOD_DIN_OFFSET) +#define TMS570_GIOD_DOUT (TMS570_GIO_BASE+TMS570_GIOD_DOUT_OFFSET) +#define TMS570_GIOD_DSET (TMS570_GIO_BASE+TMS570_GIOD_DSET_OFFSET) +#define TMS570_GIOD_DCLR (TMS570_GIO_BASE+TMS570_GIOD_DCLR_OFFSET) +#define TMS570_GIOD_PDR (TMS570_GIO_BASE+TMS570_GIOD_PDR_OFFSET) +#define TMS570_GIOD_PULDIS (TMS570_GIO_BASE+TMS570_GIOD_PULDIS_OFFSET) +#define TMS570_GIOD_PSL (TMS570_GIO_BASE+TMS570_GIOD_PSL_OFFSET) + +#define TMS570_GIOE_DIR (TMS570_GIO_BASE+TMS570_GIOE_DIR_OFFSET) +#define TMS570_GIOE_DIN (TMS570_GIO_BASE+TMS570_GIOE_DIN_OFFSET) +#define TMS570_GIOE_DOUT (TMS570_GIO_BASE+TMS570_GIOE_DOUT_OFFSET) +#define TMS570_GIOE_DSET (TMS570_GIO_BASE+TMS570_GIOE_DSET_OFFSET) +#define TMS570_GIOE_DCLR (TMS570_GIO_BASE+TMS570_GIOE_DCLR_OFFSET) +#define TMS570_GIOE_PDR (TMS570_GIO_BASE+TMS570_GIOE_PDR_OFFSET) +#define TMS570_GIOE_PULDIS (TMS570_GIO_BASE+TMS570_GIOE_PULDIS_OFFSET) +#define TMS570_GIOE_PSL (TMS570_GIO_BASE+TMS570_GIOE_PSL_OFFSET) + +#define TMS570_GIOF_DIR (TMS570_GIO_BASE+TMS570_GIOF_DIR_OFFSET) +#define TMS570_GIOF_DIN (TMS570_GIO_BASE+TMS570_GIOF_DIN_OFFSET) +#define TMS570_GIOF_DOUT (TMS570_GIO_BASE+TMS570_GIOF_DOUT_OFFSET) +#define TMS570_GIOF_DSET (TMS570_GIO_BASE+TMS570_GIOF_DSET_OFFSET) +#define TMS570_GIOF_DCLR (TMS570_GIO_BASE+TMS570_GIOF_DCLR_OFFSET) +#define TMS570_GIOF_PDR (TMS570_GIO_BASE+TMS570_GIOF_PDR_OFFSET) +#define TMS570_GIOF_PULDIS (TMS570_GIO_BASE+TMS570_GIOF_PULDIS_OFFSET) +#define TMS570_GIOF_PSL (TMS570_GIO_BASE+TMS570_GIOF_PSL_OFFSET) + +#define TMS570_GIOG_DIR (TMS570_GIO_BASE+TMS570_GIOG_DIR_OFFSET) +#define TMS570_GIOG_DIN (TMS570_GIO_BASE+TMS570_GIOG_DIN_OFFSET) +#define TMS570_GIOG_DOUT (TMS570_GIO_BASE+TMS570_GIOG_DOUT_OFFSET) +#define TMS570_GIOG_DSET (TMS570_GIO_BASE+TMS570_GIOG_DSET_OFFSET) +#define TMS570_GIOG_DCLR (TMS570_GIO_BASE+TMS570_GIOG_DCLR_OFFSET) +#define TMS570_GIOG_PDR (TMS570_GIO_BASE+TMS570_GIOG_PDR_OFFSET) +#define TMS570_GIOG_PULDIS (TMS570_GIO_BASE+TMS570_GIOG_PULDIS_OFFSET) +#define TMS570_GIOG_PSL (TMS570_GIO_BASE+TMS570_GIOG_PSL_OFFSET) + +#define TMS570_GIOH_DIR (TMS570_GIO_BASE+TMS570_GIOH_DIR_OFFSET) +#define TMS570_GIOH_DIN (TMS570_GIO_BASE+TMS570_GIOH_DIN_OFFSET) +#define TMS570_GIOH_DOUT (TMS570_GIO_BASE+TMS570_GIOH_DOUT_OFFSET) +#define TMS570_GIOH_DSET (TMS570_GIO_BASE+TMS570_GIOH_DSET_OFFSET) +#define TMS570_GIOH_DCLR (TMS570_GIO_BASE+TMS570_GIOH_DCLR_OFFSET) +#define TMS570_GIOH_PDR (TMS570_GIO_BASE+TMS570_GIOH_PDR_OFFSET) +#define TMS570_GIOH_PULDIS (TMS570_GIO_BASE+TMS570_GIOH_PULDIS_OFFSET) +#define TMS570_GIOH_PSL (TMS570_GIO_BASE+TMS570_GIOH_PSL_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* GIO Global Control Register */ + +#define GIO_GCR0_RESET (1 << 0) /* Bit 0: GIO reset */ + +/* GIO Interrupt Detect Register */ + +#define GIO_INTDET_PORT_SHIFT(p) ((p) << 3) +#define GIO_INTDET_PORT_MASK(p) (0xff << GIO_INTDET_PORT_SHIFT(p)) +# define GIO_INTDET_PORT_PIN(p,n) (1 << (GIO_INTDET_PORT_SHIFT(p) + (n))) + +#define GIO_INTDET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt detection select for pins GIOA[7:0] */ +#define GIO_INTDET_GIOA_MASK (0xff << GIO_INTDET_GIOA_SHIFT) +# define GIO_INTDET_GIOA_PIN(n) (1 << (GIO_INTDET_GIOA_SHIFT + (n))) +#define GIO_INTDET_GIOB_SHIFT (8) /* Bits 8-15: Interrupt detection select for pins GIOB[7:0] */ +#define GIO_INTDET_GIOB_MASK (0xff << GIO_INTDET_GIOB_SHIFT) +# define GIO_INTDET_GIOB_PIN(n) (1 << (GIO_INTDET_GIOB_SHIFT + (n))) +#define GIO_INTDET_GIOC_SHIFT (16) /* Bits 16-23: Interrupt detection select for pins GIOC[7:0] */ +#define GIO_INTDET_GIOC_MASK (0xff << GIO_INTDET_GIOC_SHIFT) +# define GIO_INTDET_GIOC_PIN(n) (1 << (GIO_INTDET_GIOC_SHIFT + (n))) +#define GIO_INTDET_GIOD_SHIFT (24) /* Bits 24-31: Interrupt detection select for pins GIOD[7:0] */ +#define GIO_INTDET_GIOD_MASK (0xff << GIO_INTDET_GIOD_SHIFT) +# define GIO_INTDET_GIOD_PIN(n) (1 << (GIO_INTDET_GIOD_SHIFT + (n))) + +/* GIO Interrupt Polarity Register */ + +#define GIO_POL_PORT_SHIFT(p) ((p) << 3) +#define GIO_POL_PORT_MASK(p) (0xff << GIO_POL_PORT_SHIFT(p)) +# define GIO_POL_PORT_PIN(p,n) (1 << (GIO_POL_PORT_SHIFT(p) + (n))) + +#define GIO_POL_GIOA_SHIFT (0) /* Bits 0-7: Interrupt polarity select for pins GIOA[7:0] */ +#define GIO_POL_GIOA_MASK (0xff << GIO_POL_GIOA_SHIFT) +# define GIO_POL_GIOA_PIN(n) (1 << (GIO_POL_GIOA_SHIFT + (n))) +#define GIO_POL_GIOB_SHIFT (8) /* Bits 8-15: Interrupt polarity select for pins GIOB[7:0] */ +#define GIO_POL_GIOB_MASK (0xff << GIO_POL_GIOB_SHIFT) +# define GIO_POL_GIOB_PIN(n) (1 << (GIO_POL_GIOB_SHIFT + (n))) +#define GIO_POL_GIOC_SHIFT (16) /* Bits 16-23: Interrupt polarity select for pins GIOC[7:0] */ +#define GIO_POL_GIOC_MASK (0xff << GIO_POL_GIOC_SHIFT) +# define GIO_POL_GIOC_PIN(n) (1 << (GIO_POL_GIOC_SHIFT + (n))) +#define GIO_POL_GIOD_SHIFT (24) /* Bits 24-31: Interrupt polarity select for pins GIOD[7:0] */ +#define GIO_POL_GIOD_MASK (0xff << GIO_POL_GIOD_SHIFT) +# define GIO_POL_GIOD_PIN(n) (1 << (GIO_POL_GIOD_SHIFT + (n))) + +/* GIO Interrupt Enable Set Register */ + +#define GIO_ENASET_PORT_SHIFT(p) ((p) << 3) +#define GIO_ENASET_PORT_MASK(p) (0xff << GIO_ENASET_PORT_SHIFT(p)) +# define GIO_ENASET_PORT_PIN(p,n) (1 << (GIO_ENASET_PORT_SHIFT(p) + (n))) + +#define GIO_ENASET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt enable for pins GIOA[7:0] */ +#define GIO_ENASET_GIOA_MASK (0xff << GIO_ENASET_GIOA_SHIFT) +# define GIO_ENASET_GIOA_PIN(n) (1 << (GIO_ENASET_GIOA_SHIFT + (n))) +#define GIO_ENASET_GIOB_SHIFT (8) /* Bits 8-15: Interrupt enable for pins GIOB[7:0] */ +#define GIO_ENASET_GIOB_MASK (0xff << GIO_ENASET_GIOB_SHIFT) +# define GIO_ENASET_GIOB_PIN(n) (1 << (GIO_ENASET_GIOB_SHIFT + (n))) +#define GIO_ENASET_GIOC_SHIFT (16) /* Bits 16-23: Interrupt enable for pins GIOC[7:0] */ +#define GIO_ENASET_GIOC_MASK (0xff << GIO_ENASET_GIOC_SHIFT) +# define GIO_ENASET_GIOC_PIN(n) (1 << (GIO_ENASET_GIOC_SHIFT + (n))) +#define GIO_ENASET_GIOD_SHIFT (24) /* Bits 24-31: Interrupt enable for pins GIOD[7:0] */ +#define GIO_ENASET_GIOD_MASK (0xff << GIO_ENASET_GIOD_SHIFT) +# define GIO_ENASET_GIOD_PIN(n) (1 << (GIO_ENASET_GIOD_SHIFT + (n))) + +/* GIO Interrupt Enable Clear Register */ + +#define GIO_ENACLR_PORT_SHIFT(p) ((p) << 3) +#define GIO_ENACLR_PORT_MASK(p) (0xff << GIO_ENACLR_PORT_SHIFT(p)) +# define GIO_ENACLR_PORT_PIN(p,n) (1 << (GIO_ENACLR_PORT_SHIFT(p) + (n))) + +#define GIO_ENACLR_GIOA_SHIFT (0) /* Bits 0-7: Interrupt disable for pins GIOA[7:0] */ +#define GIO_ENACLR_GIOA_MASK (0xff << GIO_ENACLR_GIOA_SHIFT) +# define GIO_ENACLR_GIOA_PIN(n) (1 << (GIO_ENACLR_GIOA_SHIFT + (n))) +#define GIO_ENACLR_GIOB_SHIFT (8) /* Bits 8-15: Interrupt disable for pins GIOB[7:0] */ +#define GIO_ENACLR_GIOB_MASK (0xff << GIO_ENACLR_GIOB_SHIFT) +# define GIO_ENACLR_GIOB_PIN(n) (1 << (GIO_ENACLR_GIOB_SHIFT + (n))) +#define GIO_ENACLR_GIOC_SHIFT (16) /* Bits 16-23: Interrupt disable for pins GIOC[7:0] */ +#define GIO_ENACLR_GIOC_MASK (0xff << GIO_ENACLR_GIOC_SHIFT) +# define GIO_ENACLR_GIOC_PIN(n) (1 << (GIO_ENACLR_GIOC_SHIFT + (n))) +#define GIO_ENACLR_GIOD_SHIFT (24) /* Bits 24-31: Interrupt disable for pins GIOD[7:0] */ +#define GIO_ENACLR_GIOD_MASK (0xff << GIO_ENACLR_GIOD_SHIFT) +# define GIO_ENACLR_GIOD_PIN(n) (1 << (GIO_ENACLR_GIOD_SHIFT + (n))) + +/* GIO Interrupt Priority Set Register */ + +#define GIO_LVLSET_PORT_SHIFT(p) ((p) << 3) +#define GIO_LVLSET_PORT_MASK(p) (0xff << GIO_LVLSET_PORT_SHIFT(p)) +# define GIO_LVLSET_PORT_PIN(p,n) (1 << (GIO_LVLSET_PORT_SHIFT(p) + (n))) + +#define GIO_LVLSET_GIOA_SHIFT (0) /* Bits 0-7: Interrupt high level select for pins GIOA[7:0] */ +#define GIO_LVLSET_GIOA_MASK (0xff << GIO_LVLSET_GIOA_SHIFT) +# define GIO_LVLSET_GIOA_PIN(n) (1 << (GIO_LVLSET_GIOA_SHIFT + (n))) +#define GIO_LVLSET_GIOB_SHIFT (8) /* Bits 8-15: Interrupt high level select for pins GIOB[7:0] */ +#define GIO_LVLSET_GIOB_MASK (0xff << GIO_LVLSET_GIOB_SHIFT) +# define GIO_LVLSET_GIOB_PIN(n) (1 << (GIO_LVLSET_GIOB_SHIFT + (n))) +#define GIO_LVLSET_GIOC_SHIFT (16) /* Bits 16-23: Interrupt high level select for pins GIOC[7:0] */ +#define GIO_LVLSET_GIOC_MASK (0xff << GIO_LVLSET_GIOC_SHIFT) +# define GIO_LVLSET_GIOC_PIN(n) (1 << (GIO_LVLSET_GIOC_SHIFT + (n))) +#define GIO_LVLSET_GIOD_SHIFT (24) /* Bits 24-31: Interrupt high level select for pins GIOD[7:0] */ +#define GIO_LVLSET_GIOD_MASK (0xff << GIO_LVLSET_GIOD_SHIFT) +# define GIO_LVLSET_GIOD_PIN(n) (1 << (GIO_LVLSET_GIOD_SHIFT + (n))) + +/* GIO Interrupt Priority Clear Register */ + +#define GIO_LVLCLR_PORT_SHIFT(p) ((p) << 3) +#define GIO_LVLCLR_PORT_MASK(p) (0xff << GIO_LVLCLR_PORT_SHIFT(p)) +# define GIO_LVLCLR_PORT_PIN(p,n) (1 << (GIO_LVLCLR_PORT_SHIFT(p) + (n))) + +#define GIO_LVLCLR_GIOA_SHIFT (0) /* Bits 0-7: Interrupt low level select for pins GIOA[7:0] */ +#define GIO_LVLCLR_GIOA_MASK (0xff << GIO_LVLCLR_GIOA_SHIFT) +# define GIO_LVLCLR_GIOA_PIN(n) (1 << (GIO_LVLCLR_GIOA_SHIFT + (n))) +#define GIO_LVLCLR_GIOB_SHIFT (8) /* Bits 8-15: Interrupt low level select for pins GIOB[7:0] */ +#define GIO_LVLCLR_GIOB_MASK (0xff << GIO_LVLCLR_GIOB_SHIFT) +# define GIO_LVLCLR_GIOB_PIN(n) (1 << (GIO_LVLCLR_GIOB_SHIFT + (n))) +#define GIO_LVLCLR_GIOC_SHIFT (16) /* Bits 16-23: Interrupt low level select for pins GIOC[7:0] */ +#define GIO_LVLCLR_GIOC_MASK (0xff << GIO_LVLCLR_GIOC_SHIFT) +# define GIO_LVLCLR_GIOC_PIN(n) (1 << (GIO_LVLCLR_GIOC_SHIFT + (n))) +#define GIO_LVLCLR_GIOD_SHIFT (24) /* Bits 24-31: Interrupt low level select for pins GIOD[7:0] */ +#define GIO_LVLCLR_GIOD_MASK (0xff << GIO_LVLCLR_GIOD_SHIFT) +# define GIO_LVLCLR_GIOD_PIN(n) (1 << (GIO_LVLCLR_GIOD_SHIFT + (n))) + +/* GIO Interrupt Flag Register */ + +#define GIO_FLG_PORT_SHIFT(p) ((p) << 3) +#define GIO_FLG_PORT_MASK(p) (0xff << GIO_FLG_PORT_SHIFT(p)) +# define GIO_FLG_PORT_PIN(p,n) (1 << (GIO_FLG_PORT_SHIFT(p) + (n))) + +#define GIO_FLG_GIOA_SHIFT (0) /* Bits 0-7: Interrupt flag for pins GIOA[7:0] */ +#define GIO_FLG_GIOA_MASK (0xff << GIO_FLG_GIOA_SHIFT) +# define GIO_FLG_GIOA_PIN(n) (1 << (GIO_FLG_GIOA_SHIFT + (n))) +#define GIO_FLG_GIOB_SHIFT (8) /* Bits 8-15: Interrupt flag for pins GIOB[7:0] */ +#define GIO_FLG_GIOB_MASK (0xff << GIO_FLG_GIOB_SHIFT) +# define GIO_FLG_GIOB_PIN(n) (1 << (GIO_FLG_GIOB_SHIFT + (n))) +#define GIO_FLG_GIOC_SHIFT (16) /* Bits 16-23: Interrupt flag for pins GIOC[7:0] */ +#define GIO_FLG_GIOC_MASK (0xff << GIO_FLG_GIOC_SHIFT) +# define GIO_FLG_GIOC_PIN(n) (1 << (GIO_FLG_GIOC_SHIFT + (n))) +#define GIO_FLG_GIOD_SHIFT (24) /* Bits 24-31: Interrupt flag for pins GIOD[7:0] */ +#define GIO_FLG_GIOD_MASK (0xff << GIO_FLG_GIOD_SHIFT) +# define GIO_FLG_GIOD_PIN(n) (1 << (GIO_FLG_GIOD_SHIFT + (n))) + +/* GIO Offset 1/2 Register and GIO Emulation 1/2 Register */ + +#define GIO_OFF_MASK (0x3f) /* Bits 0-5: GIO offset */ +# define GIO_OFF_NONE (0x00) /* No interrupt pending */ +# define GIO_OFF_GIOA0 (0x01) /* GIOA0 interrupt pending */ +# define GIO_OFF_GIOA1 (0x02) /* GIOA1 interrupt pending */ +# define GIO_OFF_GIOA2 (0x03) /* GIOA2 interrupt pending */ +# define GIO_OFF_GIOA3 (0x04) /* GIOA3 interrupt pending */ +# define GIO_OFF_GIOA4 (0x05) /* GIOA4 interrupt pending */ +# define GIO_OFF_GIOA5 (0x06) /* GIOA5 interrupt pending */ +# define GIO_OFF_GIOA6 (0x07) /* GIOA6 interrupt pending */ +# define GIO_OFF_GIOA7 (0x08) /* GIOA7 interrupt pending */ +# define GIO_OFF_GIOB0 (0x09) /* GIOB0 interrupt pending */ +# define GIO_OFF_GIOB1 (0x0a) /* GIOB1 interrupt pending */ +# define GIO_OFF_GIOB2 (0x0b) /* GIOB2 interrupt pending */ +# define GIO_OFF_GIOB3 (0x0c) /* GIOB3 interrupt pending */ +# define GIO_OFF_GIOB4 (0x0d) /* GIOB4 interrupt pending */ +# define GIO_OFF_GIOB5 (0x0e) /* GIOB5 interrupt pending */ +# define GIO_OFF_GIOB6 (0x0f) /* GIOB6 interrupt pending */ +# define GIO_OFF_GIOB7 (0x10) /* GIOB7 interrupt pending */ +# define GIO_OFF_GIOC0 (0x11) /* GIOC0 interrupt pending */ +# define GIO_OFF_GIOC1 (0x12) /* GIOC1 interrupt pending */ +# define GIO_OFF_GIOC2 (0x13) /* GIOC2 interrupt pending */ +# define GIO_OFF_GIOC3 (0x14) /* GIOC3 interrupt pending */ +# define GIO_OFF_GIOC4 (0x15) /* GIOC4 interrupt pending */ +# define GIO_OFF_GIOC5 (0x16) /* GIOC5 interrupt pending */ +# define GIO_OFF_GIOC6 (0x17) /* GIOC6 interrupt pending */ +# define GIO_OFF_GIOC7 (0x18) /* GIOC7 interrupt pending */ +# define GIO_OFF_GIOD0 (0x19) /* GIOD0 interrupt pending */ +# define GIO_OFF_GIOD1 (0x1a) /* GIOD1 interrupt pending */ +# define GIO_OFF_GIOD2 (0x1b) /* GIOD2 interrupt pending */ +# define GIO_OFF_GIOD3 (0x1c) /* GIOD3 interrupt pending */ +# define GIO_OFF_GIOD4 (0x1d) /* GIOD4 interrupt pending */ +# define GIO_OFF_GIOD5 (0x1e) /* GIOD5 interrupt pending */ +# define GIO_OFF_GIOD6 (0x1f) /* GIOD6 interrupt pending */ +# define GIO_OFF_GIOD7 (0x20) /* GIOD7 interrupt pending */ + +/* GIO Data Direction Register, GIO Data Input Register, GIO Data Output Register, + * GIO Data Set Register, GIO Data Clear Register, GIO Open Drain Register, + * GIO Pull Disable Register, and GIO Pull Select Register + */ + +#define GIO_PIN(n) (1 << (n)) /* Bit n: Corresponds to pin n */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_GIO_H */ diff --git a/arch/arm/src/tms570/chip/tms570_iomm.h b/arch/arm/src/tms570/chip/tms570_iomm.h new file mode 100644 index 0000000000000000000000000000000000000000..bafd17420a1d49f5187346b7970696457e7172d3 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_iomm.h @@ -0,0 +1,191 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_iomm.h + * I/O Muliplexing and Control Module (IOMM) Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_IOMM_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_IOMM_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_IOMM_REVISION_OFFSET 0x0000 /* Revision Register */ +#define TMS570_IOMM_BOOT_OFFSET 0x0020 /* Boot Mode Register */ +#define TMS570_IOMM_KICK0_OFFSET 0x0038 /* Kicker Register 0 */ +#define TMS570_IOMM_KICK1_OFFSET 0x003c /* Kicker Register 1 */ +#define TMS570_IOMM_ERRRAWSTATUS_OFFSET 0x00e0 /* Error Raw Status / Set Register */ +#define TMS570_IOMM_ERRSTATUS_OFFSET 0x00e4 /* Error Enabled Status / Clear Register */ +#define TMS570_IOMM_ERRENABLE_OFFSET 0x00e8 /* Error Signaling Enable Register */ +#define TMS570_IOMM_ERRENABLECLR_OFFSET 0x00ec /* Error Signaling Enable Clear Register */ +#define TMS570_IOMM_FAULTADDRESS_OFFSET 0x00f4 /* Fault Address Register */ +#define TMS570_IOMM_FAULTSTATUS_OFFSET 0x00f8 /* Fault Status Register */ +#define TMS570_IOMM_FAULTCLR_OFFSET 0x00fc /* Fault Clear Register */ + +#define TMS570_IOMM_PINMMR_OFFSET(n) (0x0110 + ((unsigned int)(n) << 2)) +# define TMS570_IOMM_PINMMR0_OFFSET 0x0110 /* Pin Multiplexing Control Register 0 */ +# define TMS570_IOMM_PINMMR1_OFFSET 0x0114 /* Pin Multiplexing Control Register 1 */ +# define TMS570_IOMM_PINMMR2_OFFSET 0x0118 /* Pin Multiplexing Control Register 2 */ +# define TMS570_IOMM_PINMMR3_OFFSET 0x011c /* Pin Multiplexing Control Register 3 */ +# define TMS570_IOMM_PINMMR4_OFFSET 0x0120 /* Pin Multiplexing Control Register 4 */ +# define TMS570_IOMM_PINMMR5_OFFSET 0x0124 /* Pin Multiplexing Control Register 5 */ +# define TMS570_IOMM_PINMMR6_OFFSET 0x0128 /* Pin Multiplexing Control Register 6 */ +# define TMS570_IOMM_PINMMR7_OFFSET 0x012c /* Pin Multiplexing Control Register 7 */ +# define TMS570_IOMM_PINMMR8_OFFSET 0x0130 /* Pin Multiplexing Control Register 8 */ +# define TMS570_IOMM_PINMMR9_OFFSET 0x0134 /* Pin Multiplexing Control Register 9 */ +# define TMS570_IOMM_PINMMR10_OFFSET 0x0138 /* Pin Multiplexing Control Register 10 */ +# define TMS570_IOMM_PINMMR11_OFFSET 0x013c /* Pin Multiplexing Control Register 11 */ +# define TMS570_IOMM_PINMMR12_OFFSET 0x0140 /* Pin Multiplexing Control Register 12 */ +# define TMS570_IOMM_PINMMR13_OFFSET 0x0144 /* Pin Multiplexing Control Register 13 */ +# define TMS570_IOMM_PINMMR14_OFFSET 0x0148 /* Pin Multiplexing Control Register 14 */ +# define TMS570_IOMM_PINMMR15_OFFSET 0x014c /* Pin Multiplexing Control Register 15 */ +# define TMS570_IOMM_PINMMR16_OFFSET 0x0150 /* Pin Multiplexing Control Register 16 */ +# define TMS570_IOMM_PINMMR17_OFFSET 0x0154 /* Pin Multiplexing Control Register 17 */ +# define TMS570_IOMM_PINMMR18_OFFSET 0x0158 /* Pin Multiplexing Control Register 18 */ +# define TMS570_IOMM_PINMMR19_OFFSET 0x015c /* Pin Multiplexing Control Register 19 */ +# define TMS570_IOMM_PINMMR20_OFFSET 0x0160 /* Pin Multiplexing Control Register 20 */ +# define TMS570_IOMM_PINMMR21_OFFSET 0x0164 /* Pin Multiplexing Control Register 21 */ +# define TMS570_IOMM_PINMMR22_OFFSET 0x0168 /* Pin Multiplexing Control Register 22 */ +# define TMS570_IOMM_PINMMR23_OFFSET 0x016c /* Pin Multiplexing Control Register 23 */ +# define TMS570_IOMM_PINMMR24_OFFSET 0x0170 /* Pin Multiplexing Control Register 24 */ +# define TMS570_IOMM_PINMMR25_OFFSET 0x0174 /* Pin Multiplexing Control Register 25 */ +# define TMS570_IOMM_PINMMR26_OFFSET 0x0178 /* Pin Multiplexing Control Register 26 */ +# define TMS570_IOMM_PINMMR27_OFFSET 0x017c /* Pin Multiplexing Control Register 27 */ +# define TMS570_IOMM_PINMMR28_OFFSET 0x0180 /* Pin Multiplexing Control Register 28 */ +# define TMS570_IOMM_PINMMR29_OFFSET 0x0184 /* Pin Multiplexing Control Register 29 */ +# define TMS570_IOMM_PINMMR30_OFFSET 0x0188 /* Pin Multiplexing Control Register 30 */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_IOMM_REVISION (TMS570_IOMM_BASE+TMS570_IOMM_REVISION_OFFSET) +#define TMS570_IOMM_BOOT (TMS570_IOMM_BASE+TMS570_IOMM_BOOT_OFFSET) +#define TMS570_IOMM_KICK0 (TMS570_IOMM_BASE+TMS570_IOMM_KICK0_OFFSET) +#define TMS570_IOMM_KICK1 (TMS570_IOMM_BASE+TMS570_IOMM_KICK1_OFFSET) +#define TMS570_IOMM_ERRRAWSTATUS (TMS570_IOMM_BASE+TMS570_IOMM_ERRRAWSTATUS_OFFSET) +#define TMS570_IOMM_ERRSTATUS (TMS570_IOMM_BASE+TMS570_IOMM_ERRSTATUS_OFFSET) +#define TMS570_IOMM_ERRENABLE (TMS570_IOMM_BASE+TMS570_IOMM_ERRENABLE_OFFSET) +#define TMS570_IOMM_ERRENABLECLR (TMS570_IOMM_BASE+TMS570_IOMM_ERRENABLECLR_OFFSET) +#define TMS570_IOMM_FAULTADDRESS (TMS570_IOMM_BASE+TMS570_IOMM_FAULTADDRESS_OFFSET) +#define TMS570_IOMM_FAULTSTATUS (TMS570_IOMM_BASE+TMS570_IOMM_FAULTSTATUS_OFFSET) +#define TMS570_IOMM_FAULTCLR (TMS570_IOMM_BASE+TMS570_IOMM_FAULTCLR_OFFSET) + +#define TMS570_IOMM_PINMMR(n) (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR_OFFSET(n)) +# define TMS570_IOMM_PINMMR0 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR0_OFFSET) +# define TMS570_IOMM_PINMMR1 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR1_OFFSET) +# define TMS570_IOMM_PINMMR2 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR2_OFFSET) +# define TMS570_IOMM_PINMMR3 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR3_OFFSET) +# define TMS570_IOMM_PINMMR4 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR4_OFFSET) +# define TMS570_IOMM_PINMMR5 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR5_OFFSET) +# define TMS570_IOMM_PINMMR6 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR6_OFFSET) +# define TMS570_IOMM_PINMMR7 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR7_OFFSET) +# define TMS570_IOMM_PINMMR8 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR8_OFFSET) +# define TMS570_IOMM_PINMMR9 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR9_OFFSET) +# define TMS570_IOMM_PINMMR10 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR10_OFFSET) +# define TMS570_IOMM_PINMMR11 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR11_OFFSET) +# define TMS570_IOMM_PINMMR12 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR12_OFFSET) +# define TMS570_IOMM_PINMMR13 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR13_OFFSET) +# define TMS570_IOMM_PINMMR14 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR14_OFFSET) +# define TMS570_IOMM_PINMMR15 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR15_OFFSET) +# define TMS570_IOMM_PINMMR16 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR16_OFFSET) +# define TMS570_IOMM_PINMMR17 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR17_OFFSET) +# define TMS570_IOMM_PINMMR18 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR18_OFFSET) +# define TMS570_IOMM_PINMMR19 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR19_OFFSET) +# define TMS570_IOMM_PINMMR20 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR20_OFFSET) +# define TMS570_IOMM_PINMMR21 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR21_OFFSET) +# define TMS570_IOMM_PINMMR22 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR22_OFFSET) +# define TMS570_IOMM_PINMMR23 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR23_OFFSET) +# define TMS570_IOMM_PINMMR24 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR24_OFFSET) +# define TMS570_IOMM_PINMMR25 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR25_OFFSET) +# define TMS570_IOMM_PINMMR26 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR26_OFFSET) +# define TMS570_IOMM_PINMMR27 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR27_OFFSET) +# define TMS570_IOMM_PINMMR28 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR28_OFFSET) +# define TMS570_IOMM_PINMMR29 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR29_OFFSET) +# define TMS570_IOMM_PINMMR30 (TMS570_IOMM_BASE+TMS570_IOMM_PINMMR30_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Revision Register */ +#define IOMM_REVISION_ +/* Boot Mode Register */ +#define IOMM_BOOT_ + +/* Kicker Register 0 */ + +#define IOMM_KICK0_UNLOCK 0x83e70b13 /* Unlock value */ +#define IOMM_KICK0_LOCK 0x00000000 /* Any other value locks */ + +/* Kicker Register 1 */ + +#define IOMM_KICK1_UNLOCK 0x95a4f1e0 /* Unlock value */ +#define IOMM_KICK1_LOCK 0x00000000 /* Any other value locks */ + +/* Error Raw Status / Set Register */ +#define IOMM_ERRRAWSTATUS_ +/* Error Enabled Status / Clear Register */ +#define IOMM_ERRSTATUS_ +/* Error Signaling Enable Register */ +#define IOMM_ERRENABLE_ +/* Error Signaling Enable Clear Register */ +#define IOMM_ERRENABLECLR_ +/* Fault Address Register */ +#define IOMM_FAULTADDRESS_ +/* Fault Status Register */ +#define IOMM_FAULTSTATUS_ +/* Fault Clear Register */ +#define IOMM_FAULTCLR_ + +/* Pin Multiplexing Control Register n, n=0..30. Each 8-bit field controls the functionality of + * one pin/ball. There are then a maximum of 31*4 = 124 pin/ball configurations supported. + */ + +#define IOMM_PINMMR_REGNDX(n) ((n) >> 2) +#define IOMM_PINMMR_PINSHIFT(n) (((n) & 3) << 3) +#define IOMM_PINMMR_PINMASK(n) (0xff << IOMM_PINMMR_PINSHIFT(n)) +# define IOMM_PINMMR_PINVALUE(n,v) ((uint32_t)(v) << IOMM_PINMMR_PINSHIFT(n)) + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_IOMM_H */ diff --git a/arch/arm/src/tms570/chip/tms570_memorymap.h b/arch/arm/src/tms570/chip/tms570_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..dc452cdaeecd2a0483c7ec2aea668abd2421767b --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_memorymap.h @@ -0,0 +1,63 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_MEMORYMAP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_MEMORYMAP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ) +# error No memory map for the TMS570LS0232PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) +# include "chip/tms570ls04x03x_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) +# include "chip/tms570ls04x03x_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ) +# error No memory map for the TMS570LS0714PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE) +# error No memory map for the TMS570LS0714PGE +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT) +# error No memory map for the TMS570LS0714ZWT +#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT) +# error No memory map for the TMS570LS1227ZWT +#else +# error "Unrecognized Hercules chip" +#endif + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_MEMORYMAP_H */ diff --git a/arch/arm/src/tms570/chip/tms570_pbist.h b/arch/arm/src/tms570/chip/tms570_pbist.h new file mode 100644 index 0000000000000000000000000000000000000000..2e4cfb5d725f259bf6062b61c1c7bc44db823b99 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_pbist.h @@ -0,0 +1,248 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_pbist.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PBIST_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PBIST_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* PBIST RAM Groups */ + +#define PBIST_PBIST_ROM_GROUP 1 /* ROM */ +#define PBIST_STC_ROM_GROUP 2 /* ROM */ +#define PBIST_DCAN1_RAM_GROUP 3 /* Dual-port */ +#define PBIST_DCAN2_RAM_GROUP 4 /* Dual-port */ +#define PBIST_ESRAM1_RAM_GROUP 6 /* Single-port */ +#define PBIST_MIBSPI1_RAM_GROUP 7 /* Dual-port */ +#define PBIST_VIM_RAM_GROUP 10 /* Dual-port */ +#define PBIST_MIBADC_RAM_GROUP 11 /* Dual-port */ +#define PBIST_N2HET_RAM_GROUP 13 /* Dual-port */ +#define PBIST_HET_TU_RAM_GROUP 14 /* Dual-port */ + +/* RAM Group Select */ + +#define PBIST_PBIST_ROM_RGS 1 /* ROM */ +#define PBIST_STC_ROM_RGS 2 /* ROM */ +#define PBIST_DCAN1_RAM_RGS 3 /* Dual-port */ +#define PBIST_DCAN2_RAM_RGS 4 /* Dual-port */ +#define PBIST_ESRAM1_RAM_RGS 6 /* Single-port */ +#define PBIST_MIBSPI1_RAM_RGS 7 /* Dual-port */ +#define PBIST_VIM_RAM_RGS 8 /* Dual-port */ +#define PBIST_MIBADC_RAM_RGS 9 /* Dual-port */ +#define PBIST_N2HET_RAM_RGS 11 /* Dual-port */ +#define PBIST_HET_TU_RAM_RGS 12 /* Dual-port */ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_PBIST_RAMT_OFFSET 0x0160 /* RAM Configuration Register */ +#define TMS570_PBIST_DLR_OFFSET 0x0164 /* Datalogger Register */ +#define TMS570_PBIST_PCR_OFFSET 0x016c /* Program Control Register */ +#define TMS570_PBIST_PACT_OFFSET 0x0180 /* PBIST Activate/ROM Clock Enable Register */ +#define TMS570_PBIST_PBISTID_OFFSET 0x0184 /* PBIST ID Register */ +#define TMS570_PBIST_OVER_OFFSET 0x0188 /* Override Register */ +#define TMS570_PBIST_FSRF0_OFFSET 0x0190 /* Fail Status Fail Register 0 */ +#define TMS570_PBIST_FSRF1_OFFSET 0x0194 /* Fail Status Fail Register 1 */ +#define TMS570_PBIST_FSRC0_OFFSET 0x0198 /* Fail Status Count Register 0 */ +#define TMS570_PBIST_FSRC1_OFFSET 0x019c /* Fail Status Count Register 1 */ +#define TMS570_PBIST_FSRA0_OFFSET 0x01a0 /* Fail Status Address 0 Register */ +#define TMS570_PBIST_FSRA1_OFFSET 0x01a4 /* Fail Status Address 1 Register */ +#define TMS570_PBIST_FSRDL0_OFFSET 0x01a8 /* Fail Status Data Register 0 */ +#define TMS570_PBIST_FSRDL1_OFFSET 0x01b0 /* Fail Status Data Register 1 */ +#define TMS570_PBIST_ROM_OFFSET 0x01c0 /* ROM Mask Register */ +#define TMS570_PBIST_ALGO_OFFSET 0x01c4 /* ROM Algorithm Mask Register */ +#define TMS570_PBIST_RINFOL_OFFSET 0x01c8 /* RAM Info Mask Lower Register */ +#define TMS570_PBIST_RINFOU_OFFSET 0x01cc /* RAM Info Mask Upper Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_PBIST_RAMT (TMS570_PBIST_BASE+TMS570_PBIST_RAMT_OFFSET) +#define TMS570_PBIST_DLR (TMS570_PBIST_BASE+TMS570_PBIST_DLR_OFFSET) +#define TMS570_PBIST_PCR (TMS570_PBIST_BASE+TMS570_PBIST_PCR_OFFSET) +#define TMS570_PBIST_PACT (TMS570_PBIST_BASE+TMS570_PBIST_PACT_OFFSET) +#define TMS570_PBIST_PBISTID (TMS570_PBIST_BASE+TMS570_PBIST_PBISTID_OFFSET) +#define TMS570_PBIST_OVER (TMS570_PBIST_BASE+TMS570_PBIST_OVER_OFFSET) +#define TMS570_PBIST_FSRF0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRF0_OFFSET) +#define TMS570_PBIST_FSRF1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRF1_OFFSET) +#define TMS570_PBIST_FSRC0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRC0_OFFSET) +#define TMS570_PBIST_FSRC1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRC1_OFFSET) +#define TMS570_PBIST_FSRA0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRA0_OFFSET) +#define TMS570_PBIST_FSRA1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRA1_OFFSET) +#define TMS570_PBIST_FSRDL0 (TMS570_PBIST_BASE+TMS570_PBIST_FSRDL0_OFFSET) +#define TMS570_PBIST_FSRDL1 (TMS570_PBIST_BASE+TMS570_PBIST_FSRDL1_OFFSET) +#define TMS570_PBIST_ROM (TMS570_PBIST_BASE+TMS570_PBIST_ROM_OFFSET) +#define TMS570_PBIST_ALGO (TMS570_PBIST_BASE+TMS570_PBIST_ALGO_OFFSET) +#define TMS570_PBIST_RINFOL (TMS570_PBIST_BASE+TMS570_PBIST_RINFOL_OFFSET) +#define TMS570_PBIST_RINFOU (TMS570_PBIST_BASE+TMS570_PBIST_RINFOU_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* RAM Configuration Register */ + +#define PBIST_RAMT_RLS_SHIFT (0) /* Bits 0-1: RAM Latency Select */ +#define PBIST_RAMT_RLS_MASK (3 << PBIST_RAMT_RLS_SHIFT) +# define PBIST_RAMT_RLS(n) ((uint32_t)(n) << PBIST_RAMT_RLS_SHIFT) +#define PBIST_RAMT_PLS_SHIFT (2) /* Bits 2-5: Pipeline Latency Select */ +#define PBIST_RAMT_PLS_MASK (15 << PBIST_RAMT_PLS_SHIFT) +# define PBIST_RAMT_PLS(n) ((uint32_t)(n) << PBIST_RAMT_PLS_SHIFT) +#define PBIST_RAMT_SMS_SHIFT (6) /* Bits 6-7: Sense Margin Select Register */ +#define PBIST_RAMT_SMS_MASK (3 << PBIST_RAMT_SMS_SHIFT) +# define PBIST_RAMT_SMS(n) ((uint32_t)(n) << PBIST_RAMT_SMS_SHIFT) +#define PBIST_RAMT_DWR_SHIFT (8) /* Bits 8-15: Data Width Register */ +#define PBIST_RAMT_DWR_MASK (0xff << PBIST_RAMT_DWR_SHIFT) +# define PBIST_RAMT_DWR(n) ((uint32_t)(n) << PBIST_RAMT_DWR_SHIFT) +#define PBIST_RAMT_RDS_SHIFT (16) /* Bits 16-23: Return Data Select */ +#define PBIST_RAMT_RDS_MASK (0xff << PBIST_RAMT_RDS_SHIFT) +# define PBIST_RAMT_RDS(n) ((uint32_t)(n) << PBIST_RAMT_RDS_SHIFT) +#define PBIST_RAMT_RGS_SHIFT (14) /* Bits 24-31: Ram Group Select */ +#define PBIST_RAMT_RGS_MASK (0xff << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS(n) ((uint32_t)(n) << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_PBIST_ROM (PBIST_PBIST_ROM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_STC_ROM (PBIST_STC_ROM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_DCAN1_RAM (PBIST_DCAN1_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_DCAN2_RAM (PBIST_DCAN2_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_ESRAM1_RAM (PBIST_ESRAM1_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_MIBSPI1_RAM (PBIST_MIBSPI1_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_VIM_RAM (PBIST_VIM_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_MIBADC_RAM (PBIST_MIBADC_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_N2HET_RAM (PBIST_N2HET_RAM_RGS << PBIST_RAMT_RGS_SHIFT) +# define PBIST_RAMT_RGS_HET_TU_RAM (PBIST_HET_TU_RAM_RGS << PBIST_RAMT_RGS_SHIFT) + +/* Datalogger Register */ + +#define PBIST_DLR_DLR2 (1 << 2) /* Bit 2: ROM-based testing */ +#define PBIST_DLR_DLR4 (1 << 4) /* Bit 4: Configuration access */ + +/* Program Control Register */ + +#define PBIST_PCR_STR_SHIFT (0) /* Bits 0-4: PBIST Controller Mode */ +#define PBIST_PCR_STR_MASK (0x1f << PBIST_PCR_STR_SHIFT) +# define PBIST_PCR_STR_START (1 << PBIST_PCR_STR_SHIFT) /* Start / Time Stamp mode restart */ +# define PBIST_PCR_STR_RESUME (2 << PBIST_PCR_STR_SHIFT) /* Resume / Emulation read */ +# define PBIST_PCR_STR_STOP (4 << PBIST_PCR_STR_SHIFT) /* Stop */ +# define PBIST_PCR_STR_STEP (8 << PBIST_PCR_STR_SHIFT) /* Step / Step for emulation mode */ +# define PBIST_PCR_STR_MISR (16 << PBIST_PCR_STR_SHIFT) /* Check MISR mode */ + +/* PBIST Activate/ROM Clock Enable Register */ + +#define PBIST_PACT_PACT0 (1 << 0) /* Bit 0: ROM Clock Enable */ +#define PBIST_PACT_PACT1 (1 << 1) /* Bit 1: PBIST Activate */ + +/* PBIST ID Register */ + +#define PBIST_PBISTID_SHIFT (0) /* Bits 0-7: PBIST controller ID */ +#define PBIST_PBISTID_MASK (0xff << PBIST_PBISTID_SHIFT) +# define PBIST_PBISTID(n) ((uint32_t)(n) << PBIST_PBISTID_SHIFT) + +/* Override Register */ + +#define PBIST_OVER_OVER0 (1 << 0) /* Bit 0: RINFO Override Bit */ + +/* Fail Status Fail Register 0/1 */ + +#define PBIST_FSRF (1 << 0) /* Bit 0: Fail Status */ + +/* Fail Status Count Register 0/1 */ + +#define PBIST_FSRC_SHIFT (0) /* Bits 0-7: Failure status count */ +#define PBIST_FSRC_MASK (0xff << PBIST_FSRC0_SHIFT) + +/* Fail Status Address 0/1 Register */ + +#define PBIST_FSRA_SHIFT (0) /* Bits 0-15: Failure status address */ +#define PBIST_FSRA_MASK (0xffff << PBIST_FSRA_SHIFT) + +/* Fail Status Data Register 0/1 (32-bit data) */ + +/* ROM Mask Register */ + +#define PBIST_ROM_SHIFT (0) /* Bits 0-1: ROM Mask */ +#define PBIST_ROM_MASK (3 << PBIST_ROM_SHIFT) +# define PBIST_ROM_NONE (0 << PBIST_ROM_SHIFT) /* No information used from ROM */ +# define PBIST_ROM_RAMINFO (1 << PBIST_ROM_SHIFT) /* Only RAM Group information from ROM */ +# define PBIST_ROM_ALGOINFO (2 << PBIST_ROM_SHIFT) /* Only Algorithm information from ROM */ +# define PBIST_ROM_BOTH (3 << PBIST_ROM_SHIFT) /* Both Algorithm and RAM information from ROM */ + +/* ROM Algorithm Mask Register */ + +#define PBIST_ALGO_TripleReadSlow (1 << 0) +#define PBIST_ALGO_TripleReadFast (1 << 1) +#define PBIST_ALGO_March13N_DP (1 << 2) +#define PBIST_ALGO_March13N_SP (1 << 3) +#define PBIST_ALGO_DOWN1a_DP (1 << 4) +#define PBIST_ALGO_DOWN1a_SP (1 << 5) +#define PBIST_ALGO_MapColumn_DP (1 << 6) +#define PBIST_ALGO_MapColumn_SP (1 << 7) +#define PBIST_ALGO_Precharge_DP (1 << 8) +#define PBIST_ALGO_Precharge_SP (1 << 9) +#define PBIST_ALGO_DTXN2a_DP (1 << 10) +#define PBIST_ALGO_DTXN2a_SP (1 << 11) +#define PBIST_ALGO_PMOSOpen_DP (1 << 12) +#define PBIST_ALGO_PMOSOpen_SP (1 << 13) +#define PBIST_ALGO_PPMOSOpenSlice1_DP (1 << 14) +#define PBIST_ALGO_PPMOSOpenSlice1_SP (1 << 15) +#define PBIST_ALGO_PPMOSOpenSlice2_DP (1 << 16) +#define PBIST_ALGO_PPMOSOpenSlice2_SP (1 << 17) + +/* RAM Info Mask Lower Register */ + +#define PBIST_RINFOL(n) (1 << ((n)-1)) /* Bit n: Select RAM group n+1 */ +# define PBIST_RINFOL_PBIST_ROM PBIST_RINFOL(PBIST_PBIST_ROM_GROUP) +# define PBIST_RINFOL_STC_ROM PBIST_RINFOL(PBIST_STC_ROM_GROUP) +# define PBIST_RINFOL_DCAN1_RAM PBIST_RINFOL(PBIST_DCAN1_RAM_GROUP) +# define PBIST_RINFOL_DCAN2_RAM PBIST_RINFOL(PBIST_DCAN2_RAM_GROUP) +# define PBIST_RINFOL_ESRAM1_RAM PBIST_RINFOL(PBIST_ESRAM1_RAM_GROUP) +# define PBIST_RINFOL_MIBSPI1_RAM PBIST_RINFOL(PBIST_MIBSPI1_RAM_GROUP) +# define PBIST_RINFOL_VIM_RAM PBIST_RINFOL(PBIST_VIM_RAM_GROUP) +# define PBIST_RINFOL_MIBADC_RAM PBIST_RINFOL(PBIST_MIBADC_RAM_GROUP) +# define PBIST_RINFOL_N2HET_RAM PBIST_RINFOL(PBIST_N2HET_RAM_GROUP) +# define PBIST_RINFOL_HET_TU_RAM PBIST_RINFOL(PBIST_HET_TU_RAM_GROUP) + +/* RAM Info Mask Upper Register */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PBIST_H */ diff --git a/arch/arm/src/tms570/chip/tms570_pcr.h b/arch/arm/src/tms570/chip/tms570_pcr.h new file mode 100644 index 0000000000000000000000000000000000000000..c928da5e6ce41df15080f89e61aebda37e60b06e --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_pcr.h @@ -0,0 +1,396 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_pcr.h + * Peripheral Control Register (PCR) Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PCR_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PCR_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_PCR_PMPROTSET0_OFFSET 0x0000 /* Peripheral Memory Protection Set Register 0 */ +#define TMS570_PCR_PMPROTSET1_OFFSET 0x0004 /* Peripheral Memory Protection Set Register 1 */ +#define TMS570_PCR_PMPROTCLR0_OFFSET 0x0010 /* Peripheral Memory Protection Clear Register 0 */ +#define TMS570_PCR_PMPROTCLR1_OFFSET 0x0014 /* Peripheral Memory Protection Clear Register 1 */ +#define TMS570_PCR_PPROTSET0_OFFSET 0x0020 /* Peripheral Protection Set Register 0 */ +#define TMS570_PCR_PPROTSET1_OFFSET 0x0024 /* Peripheral Protection Set Register 1 */ +#define TMS570_PCR_PPROTSET2_OFFSET 0x0028 /* Peripheral Protection Set Register 2 */ +#define TMS570_PCR_PPROTSET3_OFFSET 0x002c /* Peripheral Protection Set Register 3 */ +#define TMS570_PCR_PPROTCLR0_OFFSET 0x0040 /* Peripheral Protection Clear Register 0 */ +#define TMS570_PCR_PPROTCLR1_OFFSET 0x0044 /* Peripheral Protection Clear Register 1 */ +#define TMS570_PCR_PPROTCLR2_OFFSET 0x0048 /* Peripheral Protection Clear Register 2 */ +#define TMS570_PCR_PPROTCLR3_OFFSET 0x004c /* Peripheral Protection Clear Register 3 */ +#define TMS570_PCR_PCSPWRDWNSET0_OFFSET 0x0060 /* Peripheral Memory Power-Down Set Register 0 */ +#define TMS570_PCR_PCSPWRDWNSET1_OFFSET 0x0064 /* Peripheral Memory Power-Down Set Register 1 */ +#define TMS570_PCR_PCSPWRDWNCLR0_OFFSET 0x0070 /* Peripheral Memory Power-Down Clear Register 0 */ +#define TMS570_PCR_PCSPWRDWNCLR1_OFFSET 0x0074 /* Peripheral Memory Power-Down Clear Register 1 */ +#define TMS570_PCR_PSPWRDWNSET0_OFFSET 0x0080 /* Peripheral Power-Down Set Register 0 */ +#define TMS570_PCR_PSPWRDWNSET1_OFFSET 0x0084 /* Peripheral Power-Down Set Register 1 */ +#define TMS570_PCR_PSPWRDWNSET2_OFFSET 0x0088 /* Peripheral Power-Down Set Register 2 */ +#define TMS570_PCR_PSPWRDWNSET3_OFFSET 0x008c /* Peripheral Power-Down Set Register 3 */ +#define TMS570_PCR_PSPWRDWNCLR0_OFFSET 0x00a0 /* Peripheral Power-Down Clear Register 0 */ +#define TMS570_PCR_PSPWRDWNCLR1_OFFSET 0x00a4 /* Peripheral Power-Down Clear Register 1 */ +#define TMS570_PCR_PSPWRDWNCLR2_OFFSET 0x00a8 /* Peripheral Power-Down Clear Register 2 */ +#define TMS570_PCR_PSPWRDWNCLR3_OFFSET 0x00ac /* Peripheral Power-Down Clear Register 3 */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_PCR_PMPROTSET0 (TMS570_PCR_BASE+TMS570_PCR_PMPROTSET0_OFFSET) +#define TMS570_PCR_PMPROTSET1 (TMS570_PCR_BASE+TMS570_PCR_PMPROTSET1_OFFSET) +#define TMS570_PCR_PMPROTCLR0 (TMS570_PCR_BASE+TMS570_PCR_PMPROTCLR0_OFFSET) +#define TMS570_PCR_PMPROTCLR1 (TMS570_PCR_BASE+TMS570_PCR_PMPROTCLR1_OFFSET) +#define TMS570_PCR_PPROTSET0 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET0_OFFSET) +#define TMS570_PCR_PPROTSET1 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET1_OFFSET) +#define TMS570_PCR_PPROTSET2 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET2_OFFSET) +#define TMS570_PCR_PPROTSET3 (TMS570_PCR_BASE+TMS570_PCR_PPROTSET3_OFFSET) +#define TMS570_PCR_PPROTCLR0 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR0_OFFSET) +#define TMS570_PCR_PPROTCLR1 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR1_OFFSET) +#define TMS570_PCR_PPROTCLR2 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR2_OFFSET) +#define TMS570_PCR_PPROTCLR3 (TMS570_PCR_BASE+TMS570_PCR_PPROTCLR3_OFFSET) +#define TMS570_PCR_PCSPWRDWNSET0 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNSET0_OFFSET) +#define TMS570_PCR_PCSPWRDWNSET1 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNSET1_OFFSET) +#define TMS570_PCR_PCSPWRDWNCLR0 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNCLR0_OFFSET) +#define TMS570_PCR_PCSPWRDWNCLR1 (TMS570_PCR_BASE+TMS570_PCR_PCSPWRDWNCLR1_OFFSET) +#define TMS570_PCR_PSPWRDWNSET0 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET0_OFFSET) +#define TMS570_PCR_PSPWRDWNSET1 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET1_OFFSET) +#define TMS570_PCR_PSPWRDWNSET2 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET2_OFFSET) +#define TMS570_PCR_PSPWRDWNSET3 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNSET3_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR0 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR0_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR1 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR1_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR2 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR2_OFFSET) +#define TMS570_PCR_PSPWRDWNCLR3 (TMS570_PCR_BASE+TMS570_PCR_PSPWRDWNCLR3_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Peripheral Memory Protection Set Register 0 */ +#define PCR_PMPROTSET0_ + +/* Peripheral Memory Protection Set Register 1 */ +#define PCR_PMPROTSET1_ + +/* Peripheral Memory Protection Clear Register 0 */ +#define PCR_PMPROTCLR0_ + +/* Peripheral Memory Protection Clear Register 1 */ +#define PCR_PMPROTCLR1_ + +/* Peripheral Protection Set Register 0 */ +#define PCR_PPROTSET0_ + +/* Peripheral Protection Set Register 1 */ +#define PCR_PPROTSET1_ + +/* Peripheral Protection Set Register 2 */ +#define PCR_PPROTSET2_ + +/* Peripheral Protection Set Register 3 */ +#define PCR_PPROTSET3_ + +/* Peripheral Protection Clear Register 0 */ +#define PCR_PPROTCLR0_ + +/* Peripheral Protection Clear Register 1 */ +#define PCR_PPROTCLR1_ + +/* Peripheral Protection Clear Register 2 */ +#define PCR_PPROTCLR2_ + +/* Peripheral Protection Clear Register 3 */ +#define PCR_PPROTCLR3_ + +/* Peripheral Memory Power-Down Set Register 0 */ +#define PCR_PCSPWRDWNSET0_ + +/* Peripheral Memory Power-Down Set Register 1 */ +#define PCR_PCSPWRDWNSET1_ + +/* Peripheral Memory Power-Down Clear Register 0 */ +#define PCR_PCSPWRDWNCLR0_ + +/* Peripheral Memory Power-Down Clear Register 1 */ +#define PCR_PCSPWRDWNCLR1_ + +/* Peripheral Power-Down Set Register 0 and Peripheral Power-Down Clear Register 0 */ + +#define PCR_PSPWERDWN0_PS0_SHIFT (0) /* Bits 0-3: Quadrants for PS0 */ +#define PCR_PSPWERDWN0_PS0_MASK (15 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q1 (1 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q2 (2 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q3 (4 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_Q4 (8 << PCR_PSPWERDWN0_PS0_SHIFT) +# define PCR_PSPWERDWN0_PS0_QALL (15 << PCR_PSPWERDWN0_PS0_SHIFT) +#define PCR_PSPWERDWN0_PS1_SHIFT (4) /* Bits 4-7: Quadrants for PS1 */ +#define PCR_PSPWERDWN0_PS1_MASK (15 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q1 (1 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q2 (2 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q3 (4 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_Q4 (8 << PCR_PSPWERDWN0_PS1_SHIFT) +# define PCR_PSPWERDWN0_PS1_QALL (15 << PCR_PSPWERDWN0_PS1_SHIFT) +#define PCR_PSPWERDWN0_PS2_SHIFT (8) /* Bits 8-11: Quadrants for PS2 */ +#define PCR_PSPWERDWN0_PS2_MASK (15 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q1 (1 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q2 (2 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q3 (4 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_Q4 (8 << PCR_PSPWERDWN0_PS2_SHIFT) +# define PCR_PSPWERDWN0_PS2_QALL (15 << PCR_PSPWERDWN0_PS2_SHIFT) +#define PCR_PSPWERDWN0_PS3_SHIFT (12) /* Bits 12-15: Quadrants for PS3 */ +#define PCR_PSPWERDWN0_PS3_MASK (15 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q1 (1 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q2 (2 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q3 (4 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_Q4 (8 << PCR_PSPWERDWN0_PS3_SHIFT) +# define PCR_PSPWERDWN0_PS3_QALL (15 << PCR_PSPWERDWN0_PS3_SHIFT) +#define PCR_PSPWERDWN0_PS4_SHIFT (16) /* Bits 16-19: Quadrants for PS4 */ +#define PCR_PSPWERDWN0_PS4_MASK (15 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q1 (1 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q2 (2 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q3 (4 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_Q4 (8 << PCR_PSPWERDWN0_PS4_SHIFT) +# define PCR_PSPWERDWN0_PS4_QALL (15 << PCR_PSPWERDWN0_PS4_SHIFT) +#define PCR_PSPWERDWN0_PS5_SHIFT (20) /* Bits 20-23: Quadrants for PS5 */ +#define PCR_PSPWERDWN0_PS5_MASK (15 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q1 (1 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q2 (2 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q3 (4 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_Q4 (8 << PCR_PSPWERDWN0_PS5_SHIFT) +# define PCR_PSPWERDWN0_PS5_QALL (15 << PCR_PSPWERDWN0_PS5_SHIFT) +#define PCR_PSPWERDWN0_PS6_SHIFT (24) /* Bits 24-27: Quadrants for PS6 */ +#define PCR_PSPWERDWN0_PS6_MASK (15 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q1 (1 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q2 (2 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q3 (4 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_Q4 (8 << PCR_PSPWERDWN0_PS6_SHIFT) +# define PCR_PSPWERDWN0_PS6_QALL (15 << PCR_PSPWERDWN0_PS6_SHIFT) +#define PCR_PSPWERDWN0_PS7_SHIFT (28) /* Bits 28-31: Quadrants for PS7 */ +#define PCR_PSPWERDWN0_PS7_MASK (15 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q1 (1 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q2 (2 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q3 (4 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_Q4 (8 << PCR_PSPWERDWN0_PS7_SHIFT) +# define PCR_PSPWERDWN0_PS7_QALL (15 << PCR_PSPWERDWN0_PS7_SHIFT) + +/* Peripheral Power-Down Set Register 1 and Peripheral Power-Down Clear Register 1 */ + +#define PCR_PSPWERDWN1_PS8_SHIFT (0) /* Bits 0-3: Quadrants for PS8 */ +#define PCR_PSPWERDWN1_PS8_MASK (15 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q1 (1 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q2 (2 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q3 (4 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_Q4 (8 << PCR_PSPWERDWN1_PS8_SHIFT) +# define PCR_PSPWERDWN1_PS8_QALL (15 << PCR_PSPWERDWN1_PS8_SHIFT) +#define PCR_PSPWERDWN1_PS9_SHIFT (4) /* Bits 4-7: Quadrants for PS9 */ +#define PCR_PSPWERDWN1_PS9_MASK (15 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q1 (1 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q2 (2 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q3 (4 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_Q4 (8 << PCR_PSPWERDWN1_PS9_SHIFT) +# define PCR_PSPWERDWN1_PS9_QALL (15 << PCR_PSPWERDWN1_PS9_SHIFT) +#define PCR_PSPWERDWN1_PS10_SHIFT (8) /* Bits 8-11: Quadrants for PS10 */ +#define PCR_PSPWERDWN1_PS10_MASK (15 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q1 (1 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q2 (2 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q3 (4 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_Q4 (8 << PCR_PSPWERDWN1_PS10_SHIFT) +# define PCR_PSPWERDWN1_PS10_QALL (15 << PCR_PSPWERDWN1_PS10_SHIFT) +#define PCR_PSPWERDWN1_PS11_SHIFT (12) /* Bits 12-15: Quadrants for PS11 */ +#define PCR_PSPWERDWN1_PS11_MASK (15 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q1 (1 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q2 (2 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q3 (4 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_Q4 (8 << PCR_PSPWERDWN1_PS11_SHIFT) +# define PCR_PSPWERDWN1_PS11_QALL (15 << PCR_PSPWERDWN1_PS11_SHIFT) +#define PCR_PSPWERDWN1_PS12_SHIFT (16) /* Bits 16-19: Quadrants for PS12 */ +#define PCR_PSPWERDWN1_PS12_MASK (15 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q1 (1 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q2 (2 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q3 (4 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_Q4 (8 << PCR_PSPWERDWN1_PS12_SHIFT) +# define PCR_PSPWERDWN1_PS12_QALL (15 << PCR_PSPWERDWN1_PS12_SHIFT) +#define PCR_PSPWERDWN1_PS13_SHIFT (20) /* Bits 20-23: Quadrants for PS13 */ +#define PCR_PSPWERDWN1_PS13_MASK (15 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q1 (1 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q2 (2 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q3 (4 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_Q4 (8 << PCR_PSPWERDWN1_PS13_SHIFT) +# define PCR_PSPWERDWN1_PS13_QALL (15 << PCR_PSPWERDWN1_PS13_SHIFT) +#define PCR_PSPWERDWN1_PS14_SHIFT (24) /* Bits 24-27: Quadrants for PS14 */ +#define PCR_PSPWERDWN1_PS14_MASK (15 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q1 (1 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q2 (2 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q3 (4 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_Q4 (8 << PCR_PSPWERDWN1_PS14_SHIFT) +# define PCR_PSPWERDWN1_PS14_QALL (15 << PCR_PSPWERDWN1_PS14_SHIFT) +#define PCR_PSPWERDWN1_PS15_SHIFT (28) /* Bits 28-31: Quadrants for PS15 */ +#define PCR_PSPWERDWN1_PS15_MASK (15 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q1 (1 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q2 (2 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q3 (4 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_Q4 (8 << PCR_PSPWERDWN1_PS15_SHIFT) +# define PCR_PSPWERDWN1_PS15_QALL (15 << PCR_PSPWERDWN1_PS15_SHIFT) + +/* Peripheral Power-Down Set Register 2 and Peripheral Power-Down Clear Register 2*/ + +#define PCR_PSPWERDWN2_PS16_SHIFT (0) /* Bits 0-3: Quadrants for PS16 */ +#define PCR_PSPWERDWN2_PS16_MASK (15 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q1 (1 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q2 (2 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q3 (4 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_Q4 (8 << PCR_PSPWERDWN2_PS16_SHIFT) +# define PCR_PSPWERDWN2_PS16_QALL (15 << PCR_PSPWERDWN2_PS16_SHIFT) +#define PCR_PSPWERDWN2_PS17_SHIFT (4) /* Bits 4-7: Quadrants for PS17 */ +#define PCR_PSPWERDWN2_PS17_MASK (15 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q1 (1 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q2 (2 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q3 (4 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_Q4 (8 << PCR_PSPWERDWN2_PS17_SHIFT) +# define PCR_PSPWERDWN2_PS17_QALL (15 << PCR_PSPWERDWN2_PS17_SHIFT) +#define PCR_PSPWERDWN2_PS18_SHIFT (8) /* Bits 8-11: Quadrants for PS18 */ +#define PCR_PSPWERDWN2_PS18_MASK (15 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q1 (1 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q2 (2 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q3 (4 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_Q4 (8 << PCR_PSPWERDWN2_PS18_SHIFT) +# define PCR_PSPWERDWN2_PS18_QALL (15 << PCR_PSPWERDWN2_PS18_SHIFT) +#define PCR_PSPWERDWN2_PS19_SHIFT (12) /* Bits 12-15: Quadrants for PS19 */ +#define PCR_PSPWERDWN2_PS19_MASK (15 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q1 (1 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q2 (2 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q3 (4 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_Q4 (8 << PCR_PSPWERDWN2_PS19_SHIFT) +# define PCR_PSPWERDWN2_PS19_QALL (15 << PCR_PSPWERDWN2_PS19_SHIFT) +#define PCR_PSPWERDWN2_PS20_SHIFT (16) /* Bits 16-19: Quadrants for PS20 */ +#define PCR_PSPWERDWN2_PS20_MASK (15 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q1 (1 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q2 (2 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q3 (4 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_Q4 (8 << PCR_PSPWERDWN2_PS20_SHIFT) +# define PCR_PSPWERDWN2_PS20_QALL (15 << PCR_PSPWERDWN2_PS20_SHIFT) +#define PCR_PSPWERDWN2_PS21_SHIFT (20) /* Bits 20-23: Quadrants for PS21 */ +#define PCR_PSPWERDWN2_PS21_MASK (15 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q1 (1 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q2 (2 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q3 (4 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_Q4 (8 << PCR_PSPWERDWN2_PS21_SHIFT) +# define PCR_PSPWERDWN2_PS21_QALL (15 << PCR_PSPWERDWN2_PS21_SHIFT) +#define PCR_PSPWERDWN2_PS22_SHIFT (24) /* Bits 24-27: Quadrants for PS22 */ +#define PCR_PSPWERDWN2_PS22_MASK (15 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q1 (1 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q2 (2 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q3 (4 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_Q4 (8 << PCR_PSPWERDWN2_PS22_SHIFT) +# define PCR_PSPWERDWN2_PS22_QALL (15 << PCR_PSPWERDWN2_PS22_SHIFT) +#define PCR_PSPWERDWN2_PS23_SHIFT (28) /* Bits 28-31: Quadrants for PS23 */ +#define PCR_PSPWERDWN2_PS23_MASK (15 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q1 (1 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q2 (2 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q3 (4 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_Q4 (8 << PCR_PSPWERDWN2_PS23_SHIFT) +# define PCR_PSPWERDWN2_PS23_QALL (15 << PCR_PSPWERDWN2_PS23_SHIFT) + +/* Peripheral Power-Down Set Register 3 and Peripheral Power-Down Clear Register 3 */ + +#define PCR_PSPWERDWN3_PS24_SHIFT (0) /* Bits 0-3: Quadrants for PS24 */ +#define PCR_PSPWERDWN3_PS24_MASK (15 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q1 (1 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q2 (2 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q3 (4 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_Q4 (8 << PCR_PSPWERDWN3_PS24_SHIFT) +# define PCR_PSPWERDWN3_PS24_QALL (15 << PCR_PSPWERDWN3_PS24_SHIFT) +#define PCR_PSPWERDWN3_PS25_SHIFT (4) /* Bits 4-7: Quadrants for PS25 */ +#define PCR_PSPWERDWN3_PS25_MASK (15 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q1 (1 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q2 (2 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q3 (4 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_Q4 (8 << PCR_PSPWERDWN3_PS25_SHIFT) +# define PCR_PSPWERDWN3_PS25_QALL (15 << PCR_PSPWERDWN3_PS25_SHIFT) +#define PCR_PSPWERDWN3_PS26_SHIFT (8) /* Bits 8-11: Quadrants for PS26 */ +#define PCR_PSPWERDWN3_PS26_MASK (15 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q1 (1 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q2 (2 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q3 (4 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_Q4 (8 << PCR_PSPWERDWN3_PS26_SHIFT) +# define PCR_PSPWERDWN3_PS26_QALL (15 << PCR_PSPWERDWN3_PS26_SHIFT) +#define PCR_PSPWERDWN3_PS27_SHIFT (12) /* Bits 12-15: Quadrants for PS27 */ +#define PCR_PSPWERDWN3_PS27_MASK (15 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q1 (1 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q2 (2 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q3 (4 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_Q4 (8 << PCR_PSPWERDWN3_PS27_SHIFT) +# define PCR_PSPWERDWN3_PS27_QALL (15 << PCR_PSPWERDWN3_PS27_SHIFT) +#define PCR_PSPWERDWN3_PS28_SHIFT (16) /* Bits 16-19: Quadrants for PS28 */ +#define PCR_PSPWERDWN3_PS28_MASK (15 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q1 (1 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q2 (2 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q3 (4 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_Q4 (8 << PCR_PSPWERDWN3_PS28_SHIFT) +# define PCR_PSPWERDWN3_PS28_QALL (15 << PCR_PSPWERDWN3_PS28_SHIFT) +#define PCR_PSPWERDWN3_PS29_SHIFT (20) /* Bits 20-23: Quadrants for PS29 */ +#define PCR_PSPWERDWN3_PS29_MASK (15 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q1 (1 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q2 (2 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q3 (4 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_Q4 (8 << PCR_PSPWERDWN3_PS29_SHIFT) +# define PCR_PSPWERDWN3_PS29_QALL (15 << PCR_PSPWERDWN3_PS29_SHIFT) +#define PCR_PSPWERDWN3_PS30_SHIFT (24) /* Bits 24-27: Quadrants for PS30 */ +#define PCR_PSPWERDWN3_PS30_MASK (15 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q1 (1 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q2 (2 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q3 (4 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_Q4 (8 << PCR_PSPWERDWN3_PS30_SHIFT) +# define PCR_PSPWERDWN3_PS30_QALL (15 << PCR_PSPWERDWN3_PS30_SHIFT) +#define PCR_PSPWERDWN3_PS31_SHIFT (28) /* Bits 28-31: Quadrants for PS31 */ +#define PCR_PSPWERDWN3_PS31_MASK (15 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q1 (1 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q2 (2 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q3 (4 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_Q4 (8 << PCR_PSPWERDWN3_PS31_SHIFT) +# define PCR_PSPWERDWN3_PS31_QALL (15 << PCR_PSPWERDWN3_PS31_SHIFT) + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PCR_H */ diff --git a/arch/arm/src/tms570/chip/tms570_pinmux.h b/arch/arm/src/tms570/chip/tms570_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..281fc09b9f06ac36164bd361cc363b6bd383e38a --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_pinmux.h @@ -0,0 +1,76 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_pinmux.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PINMUX_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PINMUX_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0232PZ) +# error No pin multiplexing for the TMS570LS0232PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) +# include "chip/tms570ls04x03x_pinmux.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) +# include "chip/tms570ls04x03x_pinmux.h" +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PZ) +# error No pin multiplexing for the TMS570LS0714PZ +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714PGE) +# error No pin multiplexing for the TMS570LS0714PGE +#elif defined(CONFIG_ARCH_CHIP_TMS570LS0714ZWT) +# error No pin multiplexing for the TMS570LS0714ZWT +#elif defined(CONFIG_ARCH_CHIP_TMS570LS1227ZWT) +# error No pin multiplexing for the TMS570LS1227ZWT +#else +# error "Unrecognized Hercules chip" +#endif + +/**************************************************************************************************** + * Pulbic Type Definitions + ****************************************************************************************************/ + +/* Each chip-specific pinmux header file defines initializers for a type like: */ + +struct tms570_pinmux_s +{ + uint8_t mmrndx; /* Index to the PINMMR register, 0-30 */ + uint8_t shift; /* Shift value to isolate the pin field in the PINMMR register */ + uint8_t value; /* The new value for the pin field in the PINMMR register */ +}; + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_PINMUX_H */ diff --git a/arch/arm/src/tms570/chip/tms570_rti.h b/arch/arm/src/tms570/chip/tms570_rti.h new file mode 100644 index 0000000000000000000000000000000000000000..69fc30739d3c4caa2f99c9b80ee2c6ba4cd780e8 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_rti.h @@ -0,0 +1,203 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_rti.h + * Real Time Interrupt (RTI) Module Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_RTI_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_RTI_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_RTI_GCTRL_OFFSET 0x0000 /* RTI Global Control Register */ + /* 0x0004 RTITBCTRL Reserved. Do NOT use. */ +#define TMS570_RTI_CAPCTRL_OFFSET 0x0008 /* RTI Capture Control Register */ +#define TMS570_RTI_COMPCTRL_OFFSET 0x000c /* RTI Compare Control Register */ +#define TMS570_RTI_FRC0_OFFSET 0x0010 /* RTI Free Running Counter 0 Register */ +#define TMS570_RTI_UC0_OFFSET 0x0014 /* RTI Up Counter 0 Register */ +#define TMS570_RTI_CPUC0_OFFSET 0x0018 /* RTI Compare Up Counter 0 Register */ +#define TMS570_RTI_CAFRC0_OFFSET 0x0020 /* RTI Capture Free Running Counter 0 Register */ +#define TMS570_RTI_CAUC0_OFFSET 0x0024 /* RTI Capture Up Counter 0 Register */ +#define TMS570_RTI_FRC1_OFFSET 0x0030 /* RTI Free Running Counter 1 Register */ +#define TMS570_RTI_UC1_OFFSET 0x0034 /* RTI Up Counter 1 Register */ +#define TMS570_RTI_CPUC1_OFFSET 0x0038 /* RTI Compare Up Counter 1 Register */ +#define TMS570_RTI_CAFRC1_OFFSET 0x0040 /* RTI Capture Free Running Counter 1 Register */ +#define TMS570_RTI_CAUC1_OFFSET 0x0044 /* RTI Capture Up Counter 1 Register */ +#define TMS570_RTI_COMP0_OFFSET 0x0050 /* RTI Compare 0 Register Section */ +#define TMS570_RTI_UDCP0_OFFSET 0x0054 /* RTI Update Compare 0 Register */ +#define TMS570_RTI_COMP1_OFFSET 0x0058 /* RTI Compare 1 Register */ +#define TMS570_RTI_UDCP1_OFFSET 0x005c /* RTI Update Compare 1 Register */ +#define TMS570_RTI_COMP2_OFFSET 0x0060 /* RTI Compare 2 Register */ +#define TMS570_RTI_UDCP2_OFFSET 0x0064 /* RTI Update Compare 2 Register */ +#define TMS570_RTI_COMP3_OFFSET 0x0068 /* RTI Compare 3 Register */ +#define TMS570_RTI_UDCP3_OFFSET 0x006c /* RTI Update Compare 3 Register */ + /* 0x0070 RTITBLCOMP Reserved. Do NOT use. */ + /* 0x0074 RTITBHCOMP Reserved. Do NOT use. */ +#define TMS570_RTI_SETINTENA_OFFSET 0x0080 /* RTI Set Interrupt Enable Register */ +#define TMS570_RTI_CLEARINTENA_OFFSET 0x0084 /* RTI Clear Interrupt Enable Register */ +#define TMS570_RTI_INTFLAG_OFFSET 0x0088 /* RTI Interrupt Flag Register */ +#define TMS570_RTI_DWDCTRL_OFFSET 0x0090 /* Digital Watchdog Control Register */ +#define TMS570_RTI_DWDPRLD_OFFSET 0x0094 /* Digital Watchdog Preload Register */ +#define TMS570_RTI_WDSTATUS_OFFSET 0x0098 /* Watchdog Status Register */ +#define TMS570_RTI_WDKEY_OFFSET 0x009c /* RTI Watchdog Key Register */ +#define TMS570_RTI_DWDCNTR_OFFSET 0x00a0 /* RTI Digital Watchdog Down Counter Register */ +#define TMS570_RTI_WWDRXNCTRL_OFFSET 0x00a4 /* Digital Windowed Watchdog Reaction Control Register Section */ +#define TMS570_RTI_WWDSIZECTRL_OFFSET 0x00a8 /* Digital Windowed Watchdog Window Size Control Register */ +#define TMS570_RTI_INTCLRENABLE_OFFSET 0x00ac /* RTI Compare Interrupt Clear Enable Register */ +#define TMS570_RTI_COMP0CLR_OFFSET 0x00b0 /* RTI Compare 0 Clear Register */ +#define TMS570_RTI_COMP1CLR_OFFSET 0x00b4 /* RTI Compare 1 Clear Register */ +#define TMS570_RTI_COMP2CLR_OFFSET 0x00b8 /* RTI Compare 2 Clear Register */ +#define TMS570_RTI_COMP3CLR_OFFSET 0x00bc /* RTI Compare 3 Clear Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_RTI_GCTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_GCTRL_OFFSET) +#define TMS570_RTI_CAPCTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_CAPCTRL_OFFSET) +#define TMS570_RTI_COMPCTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_COMPCTRL_OFFSET) +#define TMS570_RTI_FRC0 (TMS570_RTIDWWD_BASE+TMS570_RTI_FRC0_OFFSET) +#define TMS570_RTI_UC0 (TMS570_RTIDWWD_BASE+TMS570_RTI_UC0_OFFSET) +#define TMS570_RTI_CPUC0 (TMS570_RTIDWWD_BASE+TMS570_RTI_CPUC0_OFFSET) +#define TMS570_RTI_CAFRC0 (TMS570_RTIDWWD_BASE+TMS570_RTI_CAFRC0_OFFSET) +#define TMS570_RTI_CAUC0 (TMS570_RTIDWWD_BASE+TMS570_RTI_CAUC0_OFFSET) +#define TMS570_RTI_FRC1 (TMS570_RTIDWWD_BASE+TMS570_RTI_FRC1_OFFSET) +#define TMS570_RTI_UC1 (TMS570_RTIDWWD_BASE+TMS570_RTI_UC1_OFFSET) +#define TMS570_RTI_CPUC1 (TMS570_RTIDWWD_BASE+TMS570_RTI_CPUC1_OFFSET) +#define TMS570_RTI_CAFRC1 (TMS570_RTIDWWD_BASE+TMS570_RTI_CAFRC1_OFFSET) +#define TMS570_RTI_CAUC1 (TMS570_RTIDWWD_BASE+TMS570_RTI_CAUC1_OFFSET) +#define TMS570_RTI_COMP0 (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP0_OFFSET) +#define TMS570_RTI_UDCP0 (TMS570_RTIDWWD_BASE+TMS570_RTI_UDCP0_OFFSET) +#define TMS570_RTI_COMP1 (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP1_OFFSET) +#define TMS570_RTI_UDCP1 (TMS570_RTIDWWD_BASE+TMS570_RTI_UDCP1_OFFSET) +#define TMS570_RTI_COMP2 (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP2_OFFSET) +#define TMS570_RTI_UDCP2 (TMS570_RTIDWWD_BASE+TMS570_RTI_UDCP2_OFFSET) +#define TMS570_RTI_COMP3 (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP3_OFFSET) +#define TMS570_RTI_UDCP3 (TMS570_RTIDWWD_BASE+TMS570_RTI_UDCP3_OFFSET) +#define TMS570_RTI_SETINTENA (TMS570_RTIDWWD_BASE+TMS570_RTI_SETINTENA_OFFSET) +#define TMS570_RTI_CLEARINTENA (TMS570_RTIDWWD_BASE+TMS570_RTI_CLEARINTENA_OFFSET) +#define TMS570_RTI_INTFLAG (TMS570_RTIDWWD_BASE+TMS570_RTI_INTFLAG_OFFSET) +#define TMS570_RTI_DWDCTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_DWDCTRL_OFFSET) +#define TMS570_RTI_DWDPRLD (TMS570_RTIDWWD_BASE+TMS570_RTI_DWDPRLD_OFFSET) +#define TMS570_RTI_WDSTATUS (TMS570_RTIDWWD_BASE+TMS570_RTI_WDSTATUS_OFFSET) +#define TMS570_RTI_WDKEY (TMS570_RTIDWWD_BASE+TMS570_RTI_WDKEY_OFFSET) +#define TMS570_RTI_DWDCNTR (TMS570_RTIDWWD_BASE+TMS570_RTI_DWDCNTR_OFFSET) +#define TMS570_RTI_WWDRXNCTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_WWDRXNCTRL_OFFSET) +#define TMS570_RTI_WWDSIZECTRL (TMS570_RTIDWWD_BASE+TMS570_RTI_WWDSIZECTRL_OFFSET) +#define TMS570_RTI_INTCLRENABLE (TMS570_RTIDWWD_BASE+TMS570_RTI_INTCLRENABLE_OFFSET) +#define TMS570_RTI_COMP0CLR (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP0CLR_OFFSET) +#define TMS570_RTI_COMP1CLR (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP1CLR_OFFSET) +#define TMS570_RTI_COMP2CLR (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP2CLR_OFFSET) +#define TMS570_RTI_COMP3CLR (TMS570_RTIDWWD_BASE+TMS570_RTI_COMP3CLR_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* RTI Global Control Register */ + +#define RTI_GCTRL_CNT0EN (1 << 0) /* Bit 0: Counter 0 enable */ +#define RTI_GCTRL_CNT1EN (1 << 1) /* Bit 1: Counter 1 enable */ +#define RTI_GCTRL_COS (1 << 15) /* Bit 15: Continue on suspend */ + +/* RTI Capture Control Register */ + +#define RTI_CAPCTRL_CAPCNTR0 (1 << 0) /* Bit 0: Capture counter 0 */ +#define RTI_CAPCTRL_CAPCNTR1 (1 << 1) /* Bit 1: Capture counter 1 */ + +/* RTI Compare Control Register */ + +#define RTI_COMPCTRL_COMPSEL0 (1 << 0) /* Bit 0: Compare select 0 */ +#define RTI_COMPCTRL_COMPSEL1 (1 << 4) /* Bit 4: Compare select 1 */ +#define RTI_COMPCTRL_COMPSEL2 (1 << 8) /* Bit 8: Compare select 2 */ +#define RTI_COMPCTRL_COMPSEL3 (1 << 12) /* Bit 12: Compare select 3 */ + +/* RTI Free Running Counter 0/1 Register (32-bit counter value) */ +/* RTI Up Counter 0/1 Register (32-bit counter value) */ +/* RTI Compare Up Counter 0/1 Register (32-bit counter value) */ +/* RTI Capture Free Running Counter 0/1 Register (32-bit counter value) */ +/* RTI Capture Up Counter 0/1 Register (32-bit counter value) */ +/* RTI Compare 0/1/2/3 Register Section (32-bit counter value) */ +/* RTI Update Compare 0/1/2/3 Register (32-bit counter value) */ + +/* RTI Set Interrupt Enable Register, RTI Clear Interrupt Enable Register, and + * RTI Interrupt Flag Register + */ + +#define RTI_INT0 (1 << 0) /* Bit 0: Compare interrupt 0 */ +#define RTI_INT1 (1 << 1) /* Bit 1: Compare interrupt 1 */ +#define RTI_INT2 (1 << 2) /* Bit 2: Compare interrupt 2 */ +#define RTI_INT3 (1 << 3) /* Bit 3: Compare interrupt 3 */ +#define RTI_TBINT (1 << 16) /* Bit 16: Timebase interrupt */ +#define RTI_OVL0INT (1 << 17) /* Bit 17: Free running counter 0 overflow interrupt */ +#define RTI_OVL1INT (1 << 18) /* Bit 18: Free running counter 1 overflow interrupt */ +#define RTI_ALLINTS 0x0007000f + +/* Digital Watchdog Control Register */ +#define RTI_DWDCTRL_ +/* Digital Watchdog Preload Register */ +#define RTI_DWDPRLD_ +/* Watchdog Status Register */ +#define RTI_WDSTATUS_ +/* RTI Watchdog Key Register */ +#define RTI_WDKEY_ +/* RTI Digital Watchdog Down Counter Register */ +#define RTI_DWDCNTR_ +/* Digital Windowed Watchdog Reaction Control Register Section */ +#define RTI_WWDRXNCTRL_ +/* Digital Windowed Watchdog Window Size Control Register */ +#define RTI_WWDSIZECTRL_ +/* RTI Compare Interrupt Clear Enable Register */ +#define RTI_INTCLRENABLE_ +/* RTI Compare 0 Clear Register */ +#define RTI_COMP0CLR_ +/* RTI Compare 1 Clear Register */ +#define RTI_COMP1CLR_ +/* RTI Compare 2 Clear Register */ +#define RTI_COMP2CLR_ +/* RTI Compare 3 Clear Register */ +#define RTI_COMP3CLR_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_RTI_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sci.h b/arch/arm/src/tms570/chip/tms570_sci.h new file mode 100644 index 0000000000000000000000000000000000000000..71c4857c68bb9f0d776a77d072378ba33a6c2f12 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sci.h @@ -0,0 +1,365 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sci.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SCI_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SCI_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SCI_GCR0_OFFSET 0x0000 /* SCI Global Control Register 0 */ +#define TMS570_SCI_GCR1_OFFSET 0x0004 /* SCI Global Control Register 1 */ +#define TMS570_SCI_GCR2_OFFSET 0x0008 /* SCI Global Control Register 2 */ +#define TMS570_SCI_SETINT_OFFSET 0x000c /* SCI Set Interrupt Register */ +#define TMS570_SCI_CLEARINT_OFFSET 0x0010 /* SCI Clear Interrupt Register */ +#define TMS570_SCI_SETINTLVL_OFFSET 0x0014 /* SCI Set Interrupt Level Register */ +#define TMS570_SCI_CLEARINTLVL_OFFSET 0x0018 /* SCI Clear Interrupt Level Register */ +#define TMS570_SCI_FLR_OFFSET 0x001c /* SCI Flags Register */ +#define TMS570_SCI_INTVECT0_OFFSET 0x0020 /* SCI Interrupt Vector Offset 0 */ +#define TMS570_SCI_INTVECT1_OFFSET 0x0024 /* SCI Interrupt Vector Offset 1 */ +#define TMS570_SCI_FORMAT_OFFSET 0x0028 /* SCI Format Control Register */ +#define TMS570_SCI_BRS_OFFSET 0x002c /* Baud Rate Selection Register */ +#define TMS570_SCI_ED_OFFSET 0x0030 /* Receiver Emulation Data Buffer */ +#define TMS570_SCI_RD_OFFSET 0x0034 /* Receiver Data Buffer */ +#define TMS570_SCI_TD_OFFSET 0x0038 /* Transmit Data Buffer */ +#define TMS570_SCI_PIO0_OFFSET 0x003c /* SCI Pin I/O Control Register 0 */ +#define TMS570_SCI_PIO1_OFFSET 0x0040 /* SCI Pin I/O Control Register 1 */ +#define TMS570_SCI_PIO2_OFFSET 0x0044 /* SCI Pin I/O Control Register 2 */ +#define TMS570_SCI_PIO3_OFFSET 0x0048 /* SCI Pin I/O Control Register 3 */ +#define TMS570_SCI_PIO4_OFFSET 0x004c /* SCI Pin I/O Control Register 4 */ +#define TMS570_SCI_PIO5_OFFSET 0x0050 /* SCI Pin I/O Control Register 5 */ +#define TMS570_SCI_PIO6_OFFSET 0x0054 /* SCI Pin I/O Control Register 6 */ +#define TMS570_SCI_PIO7_OFFSET 0x0058 /* SCI Pin I/O Control Register 7 */ +#define TMS570_SCI_PIO8_OFFSET 0x005c /* SCI Pin I/O Control Register 8 */ +#define TMS570_LIN_COMPARE_OFFSET 0x0060 /* LIN Compare Register */ +#define TMS570_LIN_RD0_OFFSET 0x0064 /* LIN Receive Buffer 0 Register */ +#define TMS570_LIN_RD1_OFFSET 0x0068 /* LIN Receive Buffer 1 Register */ +#define TMS570_LIN_MASK_OFFSET 0x006c /* LIN Mask Register */ +#define TMS570_LIN_ID_OFFSET 0x0070 /* LIN Identification Register */ +#define TMS570_LIN_TD0_OFFSET 0x0074 /* LIN Transmit Buffer 0 */ +#define TMS570_LIN_TD1_OFFSET 0x0078 /* LIN Transmit Buffer 1 */ +#define TMS570_SCI_MBRS_OFFSET 0x007c /* Maximum Baud Rate Selection Register */ +#define TMS570_SCI_IODFTCTRL_OFFSET 0x0090 /* Input/Output Error Enable Register */ + +/* Friendler register aliases */ + +#define TMS570_SCI_FUN_OFFSET TMS570_SCI_PIO0_OFFSET /* Pin Function Register */ +#define TMS570_SCI_DIR_OFFSET TMS570_SCI_PIO1_OFFSET /* Pin Direction Register */ +#define TMS570_SCI_DIN_OFFSET TMS570_SCI_PIO2_OFFSET /* Pin Data In Register */ +#define TMS570_SCI_DOUT_OFFSET TMS570_SCI_PIO3_OFFSET /* Pin Data Out Register */ +#define TMS570_SCI_SET_OFFSET TMS570_SCI_PIO4_OFFSET /* Pin Data Set Register */ +#define TMS570_SCI_CLR_OFFSET TMS570_SCI_PIO5_OFFSET /* Pin Data Clr Register */ +#define TMS570_SCI_ODR_OFFSET TMS570_SCI_PIO6_OFFSET /* Pin Open Drain Output Enable Register */ +#define TMS570_SCI_PD_OFFSET TMS570_SCI_PIO7_OFFSET /* Pin Pullup/Pulldown Disable Register */ +#define TMS570_SCI_PSL_OFFSET TMS570_SCI_PIO8_OFFSET /* Pin Pullup/Pulldown Selection Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SCI1_GCR0 (TMS570_SCI1_BASE+TMS570_SCI_GCR0_OFFSET) +#define TMS570_SCI1_GCR1 (TMS570_SCI1_BASE+TMS570_SCI_GCR1_OFFSET) +#define TMS570_SCI1_GCR2 (TMS570_SCI1_BASE+TMS570_SCI_GCR2_OFFSET) +#define TMS570_SCI1_SETINT (TMS570_SCI1_BASE+TMS570_SCI_SETINT_OFFSET) +#define TMS570_SCI1_CLEARINT (TMS570_SCI1_BASE+TMS570_SCI_CLEARINT_OFFSET) +#define TMS570_SCI1_SETINTLVL (TMS570_SCI1_BASE+TMS570_SCI_SETINTLVL_OFFSET) +#define TMS570_SCI1_CLEARINTLVL (TMS570_SCI1_BASE+TMS570_SCI_CLEARINTLVL_OFFSET) +#define TMS570_SCI1_FLR (TMS570_SCI1_BASE+TMS570_SCI_FLR_OFFSET) +#define TMS570_SCI1_INTVECT0 (TMS570_SCI1_BASE+TMS570_SCI_INTVECT0_OFFSET) +#define TMS570_SCI1_INTVECT1 (TMS570_SCI1_BASE+TMS570_SCI_INTVECT1_OFFSET) +#define TMS570_SCI1_FORMAT (TMS570_SCI1_BASE+TMS570_SCI_FORMAT_OFFSET) +#define TMS570_SCI1_BRS (TMS570_SCI1_BASE+TMS570_SCI_BRS_OFFSET) +#define TMS570_SCI1_ED (TMS570_SCI1_BASE+TMS570_SCI_ED_OFFSET) +#define TMS570_SCI1_RD (TMS570_SCI1_BASE+TMS570_SCI_RD_OFFSET) +#define TMS570_SCI1_TD (TMS570_SCI1_BASE+TMS570_SCI_TD_OFFSET) +#define TMS570_SCI1_PIO0 (TMS570_SCI1_BASE+TMS570_SCI_PIO0_OFFSET) +#define TMS570_SCI1_PIO1 (TMS570_SCI1_BASE+TMS570_SCI_PIO1_OFFSET) +#define TMS570_SCI1_PIO2 (TMS570_SCI1_BASE+TMS570_SCI_PIO2_OFFSET) +#define TMS570_SCI1_PIO3 (TMS570_SCI1_BASE+TMS570_SCI_PIO3_OFFSET) +#define TMS570_SCI1_PIO4 (TMS570_SCI1_BASE+TMS570_SCI_PIO4_OFFSET) +#define TMS570_SCI1_PIO5 (TMS570_SCI1_BASE+TMS570_SCI_PIO5_OFFSET) +#define TMS570_SCI1_PIO6 (TMS570_SCI1_BASE+TMS570_SCI_PIO6_OFFSET) +#define TMS570_SCI1_PIO7 (TMS570_SCI1_BASE+TMS570_SCI_PIO7_OFFSET) +#define TMS570_SCI1_PIO8 (TMS570_SCI1_BASE+TMS570_SCI_PIO8_OFFSET) +#define TMS570_LIN1_COMPARE (TMS570_SCI1_BASE+TMS570_LIN_COMPARE_OFFSET) +#define TMS570_LIN1_RD0 (TMS570_SCI1_BASE+TMS570_LIN_RD0_OFFSET) +#define TMS570_LIN1_RD1 (TMS570_SCI1_BASE+TMS570_LIN_RD1_OFFSET) +#define TMS570_LIN1_MASK (TMS570_SCI1_BASE+TMS570_LIN_MASK_OFFSET) +#define TMS570_LIN1_ID (TMS570_SCI1_BASE+TMS570_LIN_ID_OFFSET) +#define TMS570_LIN1_TD0 (TMS570_SCI1_BASE+TMS570_LIN_TD0_OFFSET) +#define TMS570_LIN1_TD1 (TMS570_SCI1_BASE+TMS570_LIN_TD1_OFFSET) +#define TMS570_SCI1_MBRS (TMS570_SCI1_BASE+TMS570_SCI_MBRS_OFFSET) +#define TMS570_SCI1_IODFTCTRL (TMS570_SCI1_BASE+TMS570_SCI_IODFTCTRL_OFFSET) + +#define TMS570_SCI1_FUN TMS570_SCI_PIO0 /* Pin Function Register */ +#define TMS570_SCI1_DIR TMS570_SCI_PIO1 /* Pin Direction Register */ +#define TMS570_SCI1_DIN TMS570_SCI_PIO2 /* Pin Data In Register */ +#define TMS570_SCI1_DOUT TMS570_SCI_PIO3 /* Pin Data Out Register */ +#define TMS570_SCI1_SET TMS570_SCI_PIO4 /* Pin Data Set Register */ +#define TMS570_SCI1_CLR TMS570_SCI_PIO5 /* Pin Data Clr Register */ +#define TMS570_SCI1_ODR TMS570_SCI_PIO6 /* Pin Open Drain Output Enable Register */ +#define TMS570_SCI1_PD TMS570_SCI_PIO7 /* Pin Pullup/Pulldown Disable Register */ +#define TMS570_SCI1_PSL TMS570_SCI_PIO8 /* Pin Pullup/Pulldown Selection Register */ + +#if TMS570_NSCI > 1 +# define TMS570_SCI2_GCR0 (TMS570_SCI2_BASE+TMS570_SCI_GCR0_OFFSET) +# define TMS570_SCI2_GCR1 (TMS570_SCI2_BASE+TMS570_SCI_GCR1_OFFSET) +# define TMS570_SCI2_GCR2 (TMS570_SCI2_BASE+TMS570_SCI_GCR2_OFFSET) +# define TMS570_SCI2_SETINT (TMS570_SCI2_BASE+TMS570_SCI_SETINT_OFFSET) +# define TMS570_SCI2_CLEARINT (TMS570_SCI2_BASE+TMS570_SCI_CLEARINT_OFFSET) +# define TMS570_SCI2_SETINTLVL (TMS570_SCI2_BASE+TMS570_SCI_SETINTLVL_OFFSET) +# define TMS570_SCI2_CLEARINTLVL (TMS570_SCI2_BASE+TMS570_SCI_CLEARINTLVL_OFFSET) +# define TMS570_SCI2_FLR (TMS570_SCI2_BASE+TMS570_SCI_FLR_OFFSET) +# define TMS570_SCI2_INTVECT0 (TMS570_SCI2_BASE+TMS570_SCI_INTVECT0_OFFSET) +# define TMS570_SCI2_INTVECT1 (TMS570_SCI2_BASE+TMS570_SCI_INTVECT1_OFFSET) +# define TMS570_SCI2_FORMAT (TMS570_SCI2_BASE+TMS570_SCI_FORMAT_OFFSET) +# define TMS570_SCI2_BRS (TMS570_SCI2_BASE+TMS570_SCI_BRS_OFFSET) +# define TMS570_SCI2_ED (TMS570_SCI2_BASE+TMS570_SCI_ED_OFFSET) +# define TMS570_SCI2_RD (TMS570_SCI2_BASE+TMS570_SCI_RD_OFFSET) +# define TMS570_SCI2_TD (TMS570_SCI2_BASE+TMS570_SCI_TD_OFFSET) +# define TMS570_SCI2_PIO0 (TMS570_SCI2_BASE+TMS570_SCI_PIO0_OFFSET) +# define TMS570_SCI2_PIO1 (TMS570_SCI2_BASE+TMS570_SCI_PIO1_OFFSET) +# define TMS570_SCI2_PIO2 (TMS570_SCI2_BASE+TMS570_SCI_PIO2_OFFSET) +# define TMS570_SCI2_PIO3 (TMS570_SCI2_BASE+TMS570_SCI_PIO3_OFFSET) +# define TMS570_SCI2_PIO4 (TMS570_SCI2_BASE+TMS570_SCI_PIO4_OFFSET) +# define TMS570_SCI2_PIO5 (TMS570_SCI2_BASE+TMS570_SCI_PIO5_OFFSET) +# define TMS570_SCI2_PIO6 (TMS570_SCI2_BASE+TMS570_SCI_PIO6_OFFSET) +# define TMS570_SCI2_PIO7 (TMS570_SCI2_BASE+TMS570_SCI_PIO7_OFFSET) +# define TMS570_SCI2_PIO8 (TMS570_SCI2_BASE+TMS570_SCI_PIO8_OFFSET) +# define TMS570_LIN2_COMPARE (TMS570_SCI2_BASE+TMS570_LIN_COMPARE_OFFSET) +# define TMS570_LIN2_RD0 (TMS570_SCI2_BASE+TMS570_LIN_RD0_OFFSET) +# define TMS570_LIN2_RD1 (TMS570_SCI2_BASE+TMS570_LIN_RD1_OFFSET) +# define TMS570_LIN2_MASK (TMS570_SCI2_BASE+TMS570_LIN_MASK_OFFSET) +# define TMS570_LIN2_ID (TMS570_SCI2_BASE+TMS570_LIN_ID_OFFSET) +# define TMS570_LIN2_TD0 (TMS570_SCI2_BASE+TMS570_LIN_TD0_OFFSET) +# define TMS570_LIN2_TD1 (TMS570_SCI2_BASE+TMS570_LIN_TD1_OFFSET) +# define TMS570_SCI2_MBRS (TMS570_SCI2_BASE+TMS570_SCI_MBRS_OFFSET) +# define TMS570_SCI2_IODFTCTRL (TMS570_SCI2_BASE+TMS570_SCI_IODFTCTRL_OFFSET) + +# define TMS570_SCI1_FUN TMS570_SCI_PIO0 /* Pin Function Register */ +# define TMS570_SCI1_DIR TMS570_SCI_PIO1 /* Pin Direction Register */ +# define TMS570_SCI1_DIN TMS570_SCI_PIO2 /* Pin Data In Register */ +# define TMS570_SCI1_DOUT TMS570_SCI_PIO3 /* Pin Data Out Register */ +# define TMS570_SCI1_SET TMS570_SCI_PIO4 /* Pin Data Set Register */ +# define TMS570_SCI1_CLR TMS570_SCI_PIO5 /* Pin Data Clr Register */ +# define TMS570_SCI1_ODR TMS570_SCI_PIO6 /* Pin Open Drain Output Enable Register */ +# define TMS570_SCI1_PD TMS570_SCI_PIO7 /* Pin Pullup/Pulldown Disable Register */ +# define TMS570_SCI1_PSL TMS570_SCI_PIO8 /* Pin Pullup/Pulldown Selection Register */ +#endif + +/* Register Bit-Field Definitions *******************************************************************/ + +/* SCI Global Control Register 0 */ + +#define SCI_GCR0_RESET (1 << 0) /* Bit 0: SCI/LIN module is out of reset */ + +/* SCI Global Control Register 1 */ + +#define SCI_GCR1_COMM (1 << 0) /* Bit 0: SCI/LIN communication mode */ +#define SCI_GCR1_TIMING (1 << 1) /* Bit 1: SCI timing mode */ +#define SCI_GCR1_PARENA (1 << 2) /* Bit 2: Parity enable */ +#define SCI_GCR1_PARITY (1 << 3) /* Bit 3: SCI parity odd/even selection */ +#define SCI_GCR1_STOP (1 << 4) /* Bit 4: SCI number of stop bits per frame */ +#define SCI_GCR1_CLOCK (1 << 5) /* Bit 5: SCI internal clock enable */ +#define SCI_GCR1_LIN (1 << 6) /* Bit 6: LIN mode */ +#define SCI_GCR1_SWRST (1 << 7) /* Bit 7: Software reset (active low) */ +#define SCI_GCR1_SLEEP (1 << 8) /* Bit 8: SCI sleep */ +#define SCI_GCR1_ADAPT (1 << 9) /* Bit 9: Adapt */ +#define SCI_GCR1_MBUF (1 << 10) /* Bit 10: Multibuffer mode */ +#define SCI_GCR1_CTYPE (1 << 11) /* Bit 11: Checksum type */ +#define SCI_GCR1_HGEN (1 << 12) /* Bit 12: HGEN control */ +#define SCI_GCR1_STOPEXT (1 << 13) /* Bit 13: Stop extended frame communication */ +#define SCI_GCR1_LOOPBACK (1 << 16) /* Bit 16: Loopback bit */ +#define SCI_GCR1_CONT (1 << 17) /* Bit 13: Continue on suspend */ +#define SCI_GCR1_RXENA (1 << 24) /* Bit 24: Receive enable */ +#define SCI_GCR1_TXENA (1 << 25) /* Bit 25: Transmit enable */ + +/* SCI Global Control Register 2 */ + +#define SCI_GCR2_POWERDOWN (1 << 0) /* Bit 0: Power down */ +#define SCI_GCR2_GENWU (1 << 8) /* Bit 8: Generate wakeup signal */ +#define SCI_GCR2_SC (1 << 16) /* Bit 16: Send checksum byte */ +#define SCI_GCR2_CC (1 << 17) /* Bit 17: Compare checksum */ + +/* SCI Set Interrupt Register, + * SCI Clear Interrupt Register, + ( SCI Set Interrupt Level Register, and + * SCI Clear Interrupt Level Register + */ + +#define SCI_INT_BRKDT (1 << 0) /* Bit 0: Break detect interrupt */ +#define SCI_INT_WAKEUP (1 << 1) /* Bit 1: Wake-up interrupt */ +#define SCI_INT_TIMEOUT (1 << 4) /* Bit 4: Timeout interrupt */ +#define SCI_INT_TOAWUS (1 << 6) /* Bit 6: Timeout after wakeup signal interrupt */ +#define SCI_INT_TOA3WUS (1 << 7) /* Bit 7: Timeout after 2 Wakeup signls interrupt */ +#define SCI_INT_TX (1 << 8) /* Bit 8: Tranmitter interrupt */ +#define SCI_INT_RX (1 << 9) /* Bit 9: Receiver interrupt */ +#define SCI_INT_ID (1 << 13) /* Bit 13: Identification interrupt */ +#define SCI_INT_PE (1 << 24) /* Bit 24: Parity error interrupt */ +#define SCI_INT_OE (1 << 25) /* Bit 25: Overrun error interrupt */ +#define SCI_INT_FE (1 << 26) /* Bit 26: Framing error interrupt */ +#define SCI_INT_NRE (1 << 27) /* Bit 27: No response error interrupt */ +#define SCI_INT_ISFE (1 << 28) /* Bit 28: Inconsistent synch field error interrupt */ +#define SCI_INT_CE (1 << 29) /* Bit 29: Checksum error interrupt */ +#define SCI_INT_PBE (1 << 30) /* Bit 30: Physical bus error interrupt */ +#define SCI_INT_BE (1 << 31) /* Bit 31: Bit error interrupt */ + +#define SCI_INT_ALLERRORS 0xff000001 +#define SCI_INT_LINERRORS 0xff000000 +#define SCI_INT_SCIERRORS 0x87000001 +#define SCI_INT_ALLINTS 0xff0023d3 + +/* SCI Flags Register */ + +#define SCI_FLR_BRKDT (1 << 0) /* Bit 0: Break detect flag */ +#define SCI_FLR_WAKEUP (1 << 1) /* Bit 1: Wake-up flag */ +#define SCI_FLR_IDLE (1 << 2) /* Bit 2: SCI receiver in idle state */ +#define SCI_FLR_BUSY (1 << 3) /* Bit 3: Bus busy flag */ +#define SCI_FLR_TIMEOUT (1 << 4) /* Bit 4: Timeout flag */ +#define SCI_FLR_TOAWUS (1 << 6) /* Bit 6: Timeout after wakeup signal flag */ +#define SCI_FLR_TOA3WUS (1 << 7) /* Bit 7: Timeout after 2 Wakeup signls flag */ +#define SCI_FLR_TXRDY (1 << 8) /* Bit 8: Transmitter buffer register ready flag */ +#define SCI_FLR_RXRDY (1 << 9) /* Bit 9: Receiver ready flag */ +#define SCI_FLR_TXWAKE (1 << 10) /* Bit 10: Transmitter wakeup method select */ +#define SCI_FLR_TXEMPTY (1 << 11) /* Bit 11: Transmitter empty flag */ +#define SCI_FLR_RXWAKE (1 << 12) /* Bit 12: Receiver wakeup detect flag */ +#define SCI_FLR_IDTX (1 << 13) /* Bit 13: Identifier on transmit flag */ +#define SCI_FLR_IDRX (1 << 14) /* Bit 14: Identifier on receive flag */ +#define SCI_FLR_PE (1 << 24) /* Bit 24: Parity error flag */ +#define SCI_FLR_OE (1 << 25) /* Bit 25: Overrun error flag */ +#define SCI_FLR_FE (1 << 26) /* Bit 26: Framing error flag */ +#define SCI_FLR_NRE (1 << 27) /* Bit 27: No response error flag */ +#define SCI_FLR_ISFE (1 << 28) /* Bit 28: Inconsistent synch field error flag */ +#define SCI_FLR_CE (1 << 29) /* Bit 29: checksum error flag */ +#define SCI_FLR_PBE (1 << 30) /* Bit 30: Physical bus error flag */ +#define SCI_FLR_BE (1 << 31) /* Bit 31: Bit error flag */ + +/* SCI Interrupt Vector Offset 0/1 */ + +#define SCI_INTVECT_MASK (0x1f) /* Bits 0-4: Interrupt vector offset */ +# define SCI_INTVECT_NONE (0) /* No interrupt */ +# define SCI_INTVECT_WAKEUP (1) /* Wake-up interrupt */ +# define SCI_INTVECT_ISFE (2) /* Inconsistent synch field error interrupt */ +# define SCI_INTVECT_PE (3) /* Parity error interrupt */ +# define SCI_INTVECT_ID (4) /* Identification interrupt */ +# define SCI_INTVECT_PBE (5) /* Physical bus error interrupt */ +# define SCI_INTVECT_FE (6) /* Framing error interrupt */ +# define SCI_INTVECT_BRKDT (7) /* Break detect interrupt */ +# define SCI_INTVECT_CE (8) /* Checksum error interrupt */ +# define SCI_INTVECT_OE (9) /* Overrun error interrupt */ +# define SCI_INTVECT_BE (10) /* Bit error interrupt */ +# define SCI_INTVECT_RX (11) /* Receive interrupt */ +# define SCI_INTVECT_TX (12) /* Tranmit interrupt */ +# define SCI_INTVECT_NRE (13) /* No response error interrupt */ +# define SCI_INTVECT_TOAWUS (14) /* Timeout after wakeup signal interrupt */ +# define SCI_INTVECT_TOA3WUS (15) /* Timeout after 2 Wakeup signls interrupt */ +# define SCI_INTVECT_TIMEOUT (16) /* Timeout interrupt */ + +/* SCI Format Control Register */ + +#define SCI_FORMAT_CHAR_SHIFT (0) /* Bits 0-2: Frame length control bits */ +#define SCI_FORMAT_CHAR_MASK (7 << SCI_FORMAT_CHAR_SHIFT) +# define SCI_FORMAT_CHAR(n) ((uint32_t)(n) << SCI_FORMAT_CHAR_SHIFT) +#define SCI_FORMAT_LENGTH_SHIFT (16) /* Bits 16-18: Character length control bits */ +#define SCI_FORMAT_LENGTH_MASK (7 << SCI_FORMAT_LENGTH_SHIFT) +# define SCI_FORMAT_LENGTH(n) ((uint32_t)(n) << SCI_FORMAT_LENGTH_SHIFT) + +/* Baud Rate Selection Register */ + +#define SCI_BRS_P_SHIFT (0) /* Bits 0-23: Baud integer divider */ +#define SCI_BRS_P_MASK (0x00ffffff << SCI_BRS_P_SHIFT) +# define SCI_BRS_P(n) ((uint32_t)(n) << SCI_BRS_P_SHIFT) +#define SCI_BRS_M_SHIFT (24) /* Bits 24-27: SCI/LIN 4-bit fractional divider selection */ +#define SCI_BRS_M_MASK (15 << SCI_BRS_M_SHIFT) +# define SCI_BRS_M(n) ((uint32_t)(n) << SCI_BRS_M_SHIFT) +#define SCI_BRS_U_SHIFT (28) /* Bits 28-30: SCI/LIN super fractional divider */ +#define SCI_BRS_U_MASK (7 << SCI_BRS_U_SHIFT) +# define SCI_BRS_U(n) ((uint32_t)(n) << SCI_BRS_U_SHIFT) + +/* Receiver Emulation Data Buffer */ +#define SCI_ED_ +/* Receiver Data Buffer */ +#define SCI_RD_ +/* Transmit Data Buffer */ +#define SCI_TD_ + +/* SCI Pin I/O Control Register 0: Pin Function Register, + * SCI Pin I/O Control Register 1: Pin Direction Register, + * SCI Pin I/O Control Register 2: Pin Data In Register, + * SCI Pin I/O Control Register 3: Pin Data Out Register, + * SCI Pin I/O Control Register 4: Pin Data Set Register, + * SCI Pin I/O Control Register 5: Pin Data Clr Register, + * SCI Pin I/O Control Register 6: Pin Open Drain Output Enable Register, + * SCI Pin I/O Control Register 7: Pin Pullup/Pulldown Disable Register, and + * SCI Pin I/O Control Register 8: Pin Pullup/Pulldown Selection Register. + */ + +#define SCI_PIO_RX (1 << 1) /* Bit 1: RX pin */ +#define SCI_PIO_TX (1 << 2) /* Bit 2: TX pin */ + +/* LIN Compare Register */ +#define LIN_COMPARE_ +/* LIN Receive Buffer 0 Register */ +#define LIN_RD0_ +/* LIN Receive Buffer 1 Register */ +#define LIN_RD1_ +/* LIN Mask Register */ +#define LIN_MASK_ +/* LIN Identification Register */ +#define LIN_ID_ +/* LIN Transmit Buffer 0 */ +#define LIN_TD0_ +/* LIN Transmit Buffer 1 */ +#define LIN_TD1_ +/* Maximum Baud Rate Selection Register */ +#define SCI_MBRS_ +/* Input/Output Error Enable Register */ +#define SCI_IODFTCTRL_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SCI_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sys.h b/arch/arm/src/tms570/chip/tms570_sys.h new file mode 100644 index 0000000000000000000000000000000000000000..8ed50d1b4a3fa6e767ff8b9eda448fb59f386158 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sys.h @@ -0,0 +1,622 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sys.h + * Primary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* The LPO trim value may be programmed into the TI OTP: */ + +#define TMS570_TITCM_LPOTRIM_OFFSET 0x01b4 +#define TMS570_TITCM_LPOTRIM (TMS570_TITCM_BASE+TMS570_TITCM_LPOTRIM_OFFSET) +# define TMS570_TITCM_LPOTRIM_SHIFT (16) /* Bits 16-31: LPO trim value */ +# define TMS570_TITCM_LPOTRIM_MASK (0xffff << TMS570_TITCM_LPOTRIM_SHIFT) + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SYS_PC1_OFFSET 0x0000 /* SYS Pin Control Register 1 */ +#define TMS570_SYS_PC2_OFFSET 0x0004 /* SYS Pin Control Register 2 */ +#define TMS570_SYS_PC3_OFFSET 0x0008 /* SYS Pin Control Register 3 */ +#define TMS570_SYS_PC4_OFFSET 0x000c /* SYS Pin Control Register 4 */ +#define TMS570_SYS_PC5_OFFSET 0x0010 /* SYS Pin Control Register 5 */ +#define TMS570_SYS_PC6_OFFSET 0x0014 /* SYS Pin Control Register 6 */ +#define TMS570_SYS_PC7_OFFSET 0x0018 /* SYS Pin Control Register 7 */ +#define TMS570_SYS_PC8_OFFSET 0x001c /* SYS Pin Control Register 8 */ +#define TMS570_SYS_PC9_OFFSET 0x0020 /* SYS Pin Control Register 9 */ +#define TMS570_SYS_CSDIS_OFFSET 0x0030 /* Clock Source Disable Register */ +#define TMS570_SYS_CSDISSET_OFFSET 0x0034 /* Clock Source Disable Set Register */ +#define TMS570_SYS_CSDISCLR_OFFSET 0x0038 /* Clock Source Disable Clear Register */ +#define TMS570_SYS_CDDIS_OFFSET 0x003c /* Clock Domain Disable Register */ +#define TMS570_SYS_CDDISSET_OFFSET 0x0040 /* Clock Domain Disable Set Register */ +#define TMS570_SYS_CDDISCLR_OFFSET 0x0044 /* Clock Domain Disable Clear Register */ +#define TMS570_SYS_GHVSRC_OFFSET 0x0048 /* GCLK, HCLK, VCLK, and VCLK2 Source Register */ +#define TMS570_SYS_VCLKASRC_OFFSET 0x004c /* Peripheral Asynchronous Clock Source Register */ +#define TMS570_SYS_RCLKSRC_OFFSET 0x0050 /* RTI Clock Source Register */ +#define TMS570_SYS_CSVSTAT_OFFSET 0x0054 /* Clock Source Valid Status Register */ +#define TMS570_SYS_MSTGCR_OFFSET 0x0058 /* Memory Self-Test Global Control Register */ +#define TMS570_SYS_MINITGCR_OFFSET 0x005c /* Memory Hardware Initialization Global Control Register */ +#define TMS570_SYS_MSIENA_OFFSET 0x0060 /* Memory Self-Test/Initialization Enable Register */ +#define TMS570_SYS_MSTFAIL_OFFSET 0x0064 /* Memory Self-Test Fail Status Register */ +#define TMS570_SYS_MSTCGSTAT_OFFSET 0x0068 /* MSTC Global Status Register */ +#define TMS570_SYS_MINISTAT_OFFSET 0x006c /* Memory Hardware Initialization Status Register */ +#define TMS570_SYS_PLLCTL1_OFFSET 0x0070 /* PLL Control Register 1 */ +#define TMS570_SYS_PLLCTL2_OFFSET 0x0074 /* PLL Control Register 2 */ +#define TMS570_SYS_PC10_OFFSET 0x0078 /* SYS Pin Control Register 10 */ +#define TMS570_SYS_DIEIDL_OFFSET 0x007c /* Die Identification Register, Lower Word */ +#define TMS570_SYS_DIEIDH_OFFSET 0x0080 /* Die Identification Register, Upper Word */ +#define TMS570_SYS_LPOMONCTL_OFFSET 0x0088 /* LPO/Clock Monitor Control Register */ +#define TMS570_SYS_CLKTEST_OFFSET 0x008c /* Clock Test Register */ +#define TMS570_SYS_DFTCTRLREG_OFFSET 0x0090 /* DFT Control Register */ +#define TMS570_SYS_DFTCTRLREG2_OFFSET 0x0094 /* DFT Control Register 2 */ +#define TMS570_SYS_GPREG1_OFFSET 0x00a0 /* General Purpose Register */ +#define TMS570_SYS_IMPFASTS_OFFSET 0x00a8 /* Imprecise Fault Status Register */ +#define TMS570_SYS_IMPFTADD_OFFSET 0x00ac /* Imprecise Fault Write Address Register */ +#define TMS570_SYS_SSIR1_OFFSET 0x00b0 /* System Software Interrupt Request 1 Register */ +#define TMS570_SYS_SSIR2_OFFSET 0x00b4 /* System Software Interrupt Request 2 Register */ +#define TMS570_SYS_SSIR3_OFFSET 0x00b8 /* System Software Interrupt Request 3 Register */ +#define TMS570_SYS_SSIR4_OFFSET 0x00bc /* System Software Interrupt Request 4 Register */ +#define TMS570_SYS_RAMGCR_OFFSET 0x00c0 /* RAM Control Register */ +#define TMS570_SYS_BMMCR1_OFFSET 0x00c4 /* Bus Matrix Module Control Register 1 */ +#define TMS570_SYS_CPURSTCR_OFFSET 0x00cc /* CPU Reset Control Register */ +#define TMS570_SYS_CLKCNTL_OFFSET 0x00d0 /* Clock Control Register */ +#define TMS570_SYS_ECPCNTL_OFFSET 0x00d4 /* ECP Control Register */ +#define TMS570_SYS_DEVCR1_OFFSET 0x00dc /* DEV Parity Control Register 1 */ +#define TMS570_SYS_ECR_OFFSET 0x00e0 /* System Exception Control Register */ +#define TMS570_SYS_ESR_OFFSET 0x00e4 /* System Exception Status Register */ +#define TMS570_SYS_TASR_OFFSET 0x00e8 /* System Test Abort Status Register */ +#define TMS570_SYS_GLBSTAT_OFFSET 0x00ec /* Global Status Register */ +#define TMS570_SYS_DEVID_OFFSET 0x00f0 /* Device Identification Register */ +#define TMS570_SYS_SSIVEC_OFFSET 0x00f4 /* Software Interrupt Vector Register */ +#define TMS570_SYS_SSIF_OFFSET 0x00f8 /* System Software Interrupt Flag Register */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SYS_PC1 (TMS570_SYS_BASE+TMS570_SYS_PC1_OFFSET) +#define TMS570_SYS_PC2 (TMS570_SYS_BASE+TMS570_SYS_PC2_OFFSET) +#define TMS570_SYS_PC3 (TMS570_SYS_BASE+TMS570_SYS_PC3_OFFSET) +#define TMS570_SYS_PC4 (TMS570_SYS_BASE+TMS570_SYS_PC4_OFFSET) +#define TMS570_SYS_PC5 (TMS570_SYS_BASE+TMS570_SYS_PC5_OFFSET) +#define TMS570_SYS_PC6 (TMS570_SYS_BASE+TMS570_SYS_PC6_OFFSET) +#define TMS570_SYS_PC7 (TMS570_SYS_BASE+TMS570_SYS_PC7_OFFSET) +#define TMS570_SYS_PC8 (TMS570_SYS_BASE+TMS570_SYS_PC8_OFFSET) +#define TMS570_SYS_PC9 (TMS570_SYS_BASE+TMS570_SYS_PC9_OFFSET) +#define TMS570_SYS_CSDIS (TMS570_SYS_BASE+TMS570_SYS_CSDIS_OFFSET) +#define TMS570_SYS_CSDISSET (TMS570_SYS_BASE+TMS570_SYS_CSDISSET_OFFSET) +#define TMS570_SYS_CSDISCLR (TMS570_SYS_BASE+TMS570_SYS_CSDISCLR_OFFSET) +#define TMS570_SYS_CDDIS (TMS570_SYS_BASE+TMS570_SYS_CDDIS_OFFSET) +#define TMS570_SYS_CDDISSET (TMS570_SYS_BASE+TMS570_SYS_CDDISSET_OFFSET) +#define TMS570_SYS_CDDISCLR (TMS570_SYS_BASE+TMS570_SYS_CDDISCLR_OFFSET) +#define TMS570_SYS_GHVSRC (TMS570_SYS_BASE+TMS570_SYS_GHVSRC_OFFSET) +#define TMS570_SYS_VCLKASRC (TMS570_SYS_BASE+TMS570_SYS_VCLKASRC_OFFSET) +#define TMS570_SYS_RCLKSRC (TMS570_SYS_BASE+TMS570_SYS_RCLKSRC_OFFSET) +#define TMS570_SYS_CSVSTAT (TMS570_SYS_BASE+TMS570_SYS_CSVSTAT_OFFSET) +#define TMS570_SYS_MSTGCR (TMS570_SYS_BASE+TMS570_SYS_MSTGCR_OFFSET) +#define TMS570_SYS_MINITGCR (TMS570_SYS_BASE+TMS570_SYS_MINITGCR_OFFSET) +#define TMS570_SYS_MSIENA (TMS570_SYS_BASE+TMS570_SYS_MSIENA_OFFSET) +#define TMS570_SYS_MSTFAIL (TMS570_SYS_BASE+TMS570_SYS_MSTFAIL_OFFSET) +#define TMS570_SYS_MSTCGSTAT (TMS570_SYS_BASE+TMS570_SYS_MSTCGSTAT_OFFSET) +#define TMS570_SYS_MINISTAT (TMS570_SYS_BASE+TMS570_SYS_MINISTAT_OFFSET) +#define TMS570_SYS_PLLCTL1 (TMS570_SYS_BASE+TMS570_SYS_PLLCTL1_OFFSET) +#define TMS570_SYS_PLLCTL2 (TMS570_SYS_BASE+TMS570_SYS_PLLCTL2_OFFSET) +#define TMS570_SYS_PC10 (TMS570_SYS_BASE+TMS570_SYS_PC10_OFFSET) +#define TMS570_SYS_DIEIDL (TMS570_SYS_BASE+TMS570_SYS_DIEIDL_OFFSET) +#define TMS570_SYS_DIEIDH (TMS570_SYS_BASE+TMS570_SYS_DIEIDH_OFFSET) +#define TMS570_SYS_LPOMONCTL (TMS570_SYS_BASE+TMS570_SYS_LPOMONCTL_OFFSET) +#define TMS570_SYS_CLKTEST (TMS570_SYS_BASE+TMS570_SYS_CLKTEST_OFFSET) +#define TMS570_SYS_DFTCTRLREG (TMS570_SYS_BASE+TMS570_SYS_DFTCTRLREG_OFFSET) +#define TMS570_SYS_DFTCTRLREG2 (TMS570_SYS_BASE+TMS570_SYS_DFTCTRLREG2_OFFSET) +#define TMS570_SYS_GPREG1 (TMS570_SYS_BASE+TMS570_SYS_GPREG1_OFFSET) +#define TMS570_SYS_IMPFASTS (TMS570_SYS_BASE+TMS570_SYS_IMPFASTS_OFFSET) +#define TMS570_SYS_IMPFTADD (TMS570_SYS_BASE+TMS570_SYS_IMPFTADD_OFFSET) +#define TMS570_SYS_SSIR1 (TMS570_SYS_BASE+TMS570_SYS_SSIR1_OFFSET) +#define TMS570_SYS_SSIR2 (TMS570_SYS_BASE+TMS570_SYS_SSIR2_OFFSET) +#define TMS570_SYS_SSIR3 (TMS570_SYS_BASE+TMS570_SYS_SSIR3_OFFSET) +#define TMS570_SYS_SSIR4 (TMS570_SYS_BASE+TMS570_SYS_SSIR4_OFFSET) +#define TMS570_SYS_RAMGCR (TMS570_SYS_BASE+TMS570_SYS_RAMGCR_OFFSET) +#define TMS570_SYS_BMMCR1 (TMS570_SYS_BASE+TMS570_SYS_BMMCR1_OFFSET) +#define TMS570_SYS_CPURSTCR (TMS570_SYS_BASE+TMS570_SYS_CPURSTCR_OFFSET) +#define TMS570_SYS_CLKCNTL (TMS570_SYS_BASE+TMS570_SYS_CLKCNTL_OFFSET) +#define TMS570_SYS_ECPCNTL (TMS570_SYS_BASE+TMS570_SYS_ECPCNTL_OFFSET) +#define TMS570_SYS_DEVCR1 (TMS570_SYS_BASE+TMS570_SYS_DEVCR1_OFFSET) +#define TMS570_SYS_ECR (TMS570_SYS_BASE+TMS570_SYS_ECR_OFFSET) +#define TMS570_SYS_ESR (TMS570_SYS_BASE+TMS570_SYS_ESR_OFFSET) +#define TMS570_SYS_TASR (TMS570_SYS_BASE+TMS570_SYS_TASR_OFFSET) +#define TMS570_SYS_GLBSTAT (TMS570_SYS_BASE+TMS570_SYS_GLBSTAT_OFFSET) +#define TMS570_SYS_DEVID (TMS570_SYS_BASE+TMS570_SYS_DEVID_OFFSET) +#define TMS570_SYS_SSIVEC (TMS570_SYS_BASE+TMS570_SYS_SSIVEC_OFFSET) +#define TMS570_SYS_SSIF (TMS570_SYS_BASE+TMS570_SYS_SSIF_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* SYS Pin Control Register 1 */ + +#define SYS_PC1_ECPCLKFUN (1 << 0) /* Bit 0: ECLK function */ + +/* SYS Pin Control Register 2 */ + +#define SYS_PC2_ECPCLKDIR (1 << 0) /* Bit 0: ECLK data direction */ + +/* SYS Pin Control Register 3 */ + +#define SYS_PC3_ECPCLKDIN (1 << 0) /* Bit 0: ECLK data in */ + +/* SYS Pin Control Register 4 */ + +#define SYS_PC4_ECPCLKDOUT (1 << 0) /* Bit 0: ECLK data out write */ + +/* SYS Pin Control Register 5 */ + +#define SYS_PC5_ECPCLKSET (1 << 0) /* Bit 0: ECLK data out set */ + +/* SYS Pin Control Register 6 */ + +#define SYS_PC6_ECPCLKCLR (1 << 0) /* Bit 0: ECLK data out clear */ + +/* SYS Pin Control Register 7 */ + +#define SYS_PC7_ECPCLKODE (1 << 0) /* Bit 0: ECLK open drain enable */ + +/* SYS Pin Control Register 8 */ + +#define SYS_PC8_ECPCLKPUE (1 << 0) /* Bit 0: ECLK pull enable */ + +/* SYS Pin Control Register 9 */ + +#define SYS_PC9_ECPCLKPS (1 << 0) /* Bit 0: ECLK pull up/pull down select */ + +/* Clock Source Disable Register, Clock Source Disable Set Register, and Clock Source + * Disable Clear Register + */ + +#define SYS_CSDIS_CLKSR0OFF (1 << 0) /* Bit 0: Clock source 0 */ +#define SYS_CSDIS_CLKSR1OFF (1 << 1) /* Bit 1: Clock source 1 */ +#define SYS_CSDIS_CLKSR3OFF (1 << 3) /* Bit 3: Clock source 3 */ +#define SYS_CSDIS_CLKSR4OFF (1 << 4) /* Bit 4: Clock source 4 */ +#define SYS_CSDIS_CLKSR5OFF (1 << 5) /* Bit 5: Clock source 5 */ +#define SYS_CSDIS_CLKSROFFALL (0x3b) + +#define SYS_CSDIS_CLKSRC_OSC SYS_CSDIS_CLKSR0OFF /* Oscillator */ +#define SYS_CSDIS_CLKSRC_PLL SYS_CSDIS_CLKSR1OFF /* PLL */ +#define SYS_CSDIS_CLKSRC_EXTCLKIN SYS_CSDIS_CLKSR3OFF /* EXTCLKIN */ +#define SYS_CSDIS_CLKSRC_LFLPO SYS_CSDIS_CLKSR4OFF /* Low Frequency LPO (Low Power Oscillator) clock */ +#define SYS_CSDIS_CLKSRC_HFLPO SYS_CSDIS_CLKSR5OFF /* High Frequency LPO (Low Power Oscillator) clock */ + +/* Clock Domain Disable Register, Clock Domain Disable Set Register, and Clock Domain + * Disable Clear Register. + */ + +#define SYS_CDDIS_GCLKOFF (1 << 0) /* Bit 0: GCLK domain off */ +#define SYS_CDDIS_HCLKOFF (1 << 1) /* Bit 1: HCLK and VCLK_sys domains off */ +#define SYS_CDDIS_VCLKPOFF (1 << 2) /* Bit 2: VCLK_periph domain off */ +#define SYS_CDDIS_VCLK2OFF (1 << 3) /* Bit 3: VCLK2 domain off */ +#define SYS_CDDIS_VCLKA1OFF (1 << 4) /* Bit 4: VCLKA1 domain off */ +#define SYS_CDDIS_RTICLK1OFF (1 << 6) /* Bit 6: RTICLK1 domain off */ +#define SYS_CDDIS_VCLKEQEPOFF (1 << 9) /* Bit 9: VCLK_EQEP_OFF domain off */ + +/* GCLK, HCLK, VCLK, and VCLK2 Source Register */ + +#define SYS_CLKSRC_OSC 0 /* Alias for oscillator clock Source */ +#define SYS_CLKSRC_PLL1 1 /* Alias for Pll1 clock Source */ +#define SYS_CLKSRC_EXTERNAL1 3 /* Alias for external clock Source */ +#define SYS_CLKSRC_LPOLOW 4 /* Alias for low power oscillator low clock Source */ +#define SYS_CLKSRC_LPOHIGH 5 /* Alias for low power oscillator high clock Source */ +#define SYS_CLKSRC_PLL2 6 /* Alias for Pll2 clock Source */ +#define SYS_CLKSRC_EXTERNAL2 7 /* Alias for external 2 clock Source */ +#define SYS_CLKSRC_VCLK 9 /* Alias for synchronous VCLK1 clock Source */ + +#define SYS_GHVSRC_GHVSRC_SHIFT (0) /* Bits 0-3: GCLK, HCLK, VCLK, VCLK2 current source */ +#define SYS_GHVSRC_GHVSRC_MASK (15 << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_SRC(n) ((uint32_t)(n) << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_SRC0 (0 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source0 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC1 (1 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source1 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC2 (2 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source2 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC3 (3 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source3 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC4 (4 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source4 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC5 (5 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source5 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC6 (6 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source6 for GCLK, HCLK, VCLK, VCLK2 */ +# define SYS_GHVSRC_GHVSRC_SRC7 (7 << SYS_GHVSRC_GHVSRC_SHIFT) /* Clock source7 for GCLK, HCLK, VCLK, VCLK2 */ + +# define SYS_GHVSRC_GHVSRC_SRC(n) ((uint32_t)(n) << SYS_GHVSRC_GHVSRC_SHIFT) +# define SYS_GHVSRC_GHVSRC_OSC SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_GHVSRC_PLL1 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_GHVSRC_EXTERNAL1 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_GHVSRC_LPOLOW SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_GHVSRC_LPOHIGH SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_GHVSRC_PLL2 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_GHVSRC_EXTERNAL2 SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_GHVSRC_VCLK SYS_GHVSRC_GHVSRC_SRC(SYS_CLKSRC_VCLK) + +#define SYS_GHVSRC_HVLPM_SHIFT (16) /* Bits 16-19: HCLK, VCLK, VCLK2 source on wakeup when GCLK is turned off */ +#define SYS_GHVSRC_HVLPM_MASK (15 << SYS_GHVSRC_HVLPM_SHIFT) +# define SYS_GHVSRC_HVLPM_SRC0 (0 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source0 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC1 (1 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source1 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC2 (2 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source2 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC3 (3 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source3 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC4 (4 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source4 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC5 (5 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source5 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC6 (6 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source6 for HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_HVLPM_SRC7 (7 << SYS_GHVSRC_HVLPM_SHIFT) /* Clock source7 for HCLK, VCLK, VCLK2 on wakeup */ + +# define SYS_GHVSRC_HVLPM(n) ((uint32_t)(n) << SYS_GHVSRC_HVLPM_SHIFT) +# define SYS_GHVSRC_HVLPM_OSC SYS_GHVSRC_HVLPM(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_HVLPM_PLL1 SYS_GHVSRC_HVLPM(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_HVLPM_EXTERNAL1 SYS_GHVSRC_HVLPM(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_HVLPM_LPOLOW SYS_GHVSRC_HVLPM(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_HVLPM_LPOHIGH SYS_GHVSRC_HVLPM(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_HVLPM_PLL2 SYS_GHVSRC_HVLPM(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_HVLPM_EXTERNAL2 SYS_GHVSRC_HVLPM(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_HVLPM_VCLK SYS_GHVSRC_HVLPM(SYS_CLKSRC_VCLK) + +#define SYS_GHVSRC_GHVWAKE_SHIFT (24) /* Bits 24-17: GCLK, HCLK, VCLK, VCLK2 source on wakeup */ +#define SYS_GHVSRC_GHVWAKE_MASK (15 << SYS_GHVSRC_GHVWAKE_SHIFT) +# define SYS_GHVSRC_GHVWAKE_SRC0 (0 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source0 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC1 (1 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source1 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC2 (2 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source2 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC3 (3 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source3 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC4 (4 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source4 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC5 (5 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source5 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC6 (6 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source6 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ +# define SYS_GHVSRC_GHVWAKE_SRC7 (7 << SYS_GHVSRC_GHVWAKE_SHIFT) /* Clock source7 for GCLK, HCLK, VCLK, VCLK2 on wakeup */ + +# define SYS_GHVSRC_GHVWAKE(n) ((uint32_t)(n) << SYS_GHVSRC_GHVWAKE_SHIFT) +# define SYS_GHVSRC_GHVWAKE_OSC SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_OSC) +# define SYS_GHVSRC_GHVWAKE_PLL1 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_PLL1) +# define SYS_GHVSRC_GHVWAKE_EXTERNAL1 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_EXTERNAL1) +# define SYS_GHVSRC_GHVWAKE_LPOLOW SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_LPOLOW) +# define SYS_GHVSRC_GHVWAKE_LPOHIGH SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_LPOHIGH) +# define SYS_GHVSRC_GHVWAKE_PLL2 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_PLL2) +# define SYS_GHVSRC_GHVWAKE_EXTERNAL2 SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_EXTERNAL2) +# define SYS_GHVSRC_GHVWAKE_VCLK SYS_GHVSRC_GHVWAKE(SYS_CLKSRC_VCLK) + +/* Peripheral Asynchronous Clock Source Register */ + +#define SYS_VCLKASRC_VCLKA1S_SHIFT (0) /* Bits 0-3: Peripheral asynchronous clock1 source */ +#define SYS_VCLKASRC_VCLKA1S_MASK (15 << SYS_VCLKASRC_VCLKA1S_SHIFT) +# define SYS_VCLKASRC_VCLKA1S_SRC0 (0 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source0 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC1 (1 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source1 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC2 (2 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source2 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC3 (3 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source3 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC4 (4 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source4 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC5 (5 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source5 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC6 (6 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source6 for RTICLK1 */ +# define SYS_VCLKASRC_VCLKA1S_SRC7 (7 << SYS_VCLKASRC_VCLKA1S_SHIFT) /* Clock source7 for RTICLK1 */ + +# define SYS_VCLKASRC_VCLKA1S(n) ((uint32_t)(n) << SYS_VCLKASRC_VCLKA1S_SHIFT) +# define SYS_VCLKASRC_VCLKA1S_OSC SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_OSC) +# define SYS_VCLKASRC_VCLKA1S_PLL1 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_PLL1) +# define SYS_VCLKASRC_VCLKA1S_EXTERNAL1 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_EXTERNAL1) +# define SYS_VCLKASRC_VCLKA1S_LPOLOW SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_LPOLOW) +# define SYS_VCLKASRC_VCLKA1S_LPOHIGH SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_LPOHIGH) +# define SYS_VCLKASRC_VCLKA1S_PLL2 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_PLL2) +# define SYS_VCLKASRC_VCLKA1S_EXTERNAL2 SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_EXTERNAL2) +# define SYS_VCLKASRC_VCLKA1S_VCLK SYS_VCLKASRC_VCLKA1S(SYS_CLKSRC_VCLK) + +/* RTI Clock Source Register */ + +#define SYS_RCLKSRC_RTI1SRC_SHIFT (0) /* Bits 0-3: RTI clock1 source */ +#define SYS_RCLKSRC_RTI1SRC_MASK (15 << SYS_RCLKSRC_RTI1SRC_SHIFT) +# define SYS_RCLKSRC_RTI1SRC_SRC0 (0 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source0 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC1 (1 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source1 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC2 (2 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source2 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC3 (3 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source3 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC4 (4 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source4 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC5 (5 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source5 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC6 (6 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source6 for RTICLK1 */ +# define SYS_RCLKSRC_RTI1SRC_SRC7 (7 << SYS_RCLKSRC_RTI1SRC_SHIFT) /* Clock source7 for RTICLK1 */ + +# define SYS_RCLKSRC_RTI1SRC(n) ((uint32_t)(n) << SYS_RCLKSRC_RTI1SRC_SHIFT) +# define SYS_RCLKSRC_RTI1SRC_OSC SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_OSC) +# define SYS_RCLKSRC_RTI1SRC_PLL1 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_PLL1) +# define SYS_RCLKSRC_RTI1SRC_EXTERNAL1 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_EXTERNAL1) +# define SYS_RCLKSRC_RTI1SRC_LPOLOW SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_LPOLOW) +# define SYS_RCLKSRC_RTI1SRC_LPOHIGH SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_LPOHIGH) +# define SYS_RCLKSRC_RTI1SRC_PLL2 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_PLL2) +# define SYS_RCLKSRC_RTI1SRC_EXTERNAL2 SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_EXTERNAL2) +# define SYS_RCLKSRC_RTI1SRC_VCLK SYS_RCLKSRC_RTI1SRC(SYS_CLKSRC_VCLK) + +#define SYS_RCLKSRC_RTI1DIV_SHIFT (8) /* Bits 8-9: RTI clock 1 divider */ +#define SYS_RCLKSRC_RTI1DIV_MASK (3 << SYS_RCLKSRC_RTI1DIV_SHIFT) +# define SYS_RCLKSRC_RTI1DIV_DIV1 (0 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 1 */ +# define SYS_RCLKSRC_RTI1DIV_DIV2 (1 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 2 */ +# define SYS_RCLKSRC_RTI1DIV_DIV4 (2 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 4 */ +# define SYS_RCLKSRC_RTI1DIV_DIV8 (3 << SYS_RCLKSRC_RTI1DIV_SHIFT) /* RTICLK1 divider value is 8 */ + +/* Clock Source Valid Status Register */ + +#define SYS_CSVSTAT_CLKSR0V (1 << 0) /* Bit 0: Clock source xx valid */ +#define SYS_CSVSTAT_CLKSR1V (1 << 1) /* Bit 1: Clock source xx valid */ +#define SYS_CSVSTAT_CLKSR3V (1 << 3) /* Bit 3: Clock source xx valid */ +#define SYS_CSVSTAT_CLKSR4V (1 << 4) /* Bit 4: Clock source xx valid */ +#define SYS_CSVSTAT_CLKSR5V (1 << 5) /* Bit 5: Clock source xx valid */ +#define SYS_CSVSTAT_CLKSRVALL (0x3b) + +/* Memory Self-Test Global Control Register */ + +#define SYS_MSTGCR_MSTGENA_SHIFT (0) /* Bits 0-3: Memory self-test controller global enable key */ +#define SYS_MSTGCR_MSTGENA_MASK (15 << SYS_MSTGCR_MSTGENA_SHIFT) +# define SYS_MSTGCR_MSTGENA_ENABLE (10 << SYS_MSTGCR_MSTGENA_SHIFT) +# define SYS_MSTGCR_MSTGENA_DISABLE (5 << SYS_MSTGCR_MSTGENA_SHIFT) +#define SYS_MSTGCR_ROMDIV_SHIFT (8) /* Bits 8-9: Prescaler divider bits for ROM clock source */ +#define SYS_MSTGCR_ROMDIV_MASK (3 << SYS_MSTGCR_ROMDIV_SHIFT) +# define SYS_MSTGCR_ROMDIV_DIV1 (0 << SYS_MSTGCR_ROMDIV_SHIFT) /* ROM clock=HCL/1; PBIST reset=16 VBUS cycles */ +# define SYS_MSTGCR_ROMDIV_DIV2 (1 << SYS_MSTGCR_ROMDIV_SHIFT) /* ROM clock=HCLK/2; PBIST reset=32 VBUS cycles */ +# define SYS_MSTGCR_ROMDIV_DIV4 (2 << SYS_MSTGCR_ROMDIV_SHIFT) /* ROM clock=HCLK/4. PBIST reset=64 VBUS cycles */ +# define SYS_MSTGCR_ROMDIV_DIV8 (3 << SYS_MSTGCR_ROMDIV_SHIFT) /* ROM clock=HCLK/8. PBIST reset=96 VBUS cycles */ + +/* Memory Hardware Initialization Global Control Register */ + +#define SYS_MINITGCR_MASK (0xff) /* Bits 0-7: Memory hardware initialization key */ +# define SYS_MINITGCR_ENABLE (0x0a) /* Enable */ +# define SYS_MINITGCR_DISABLE (0x05) /* Any other value disables */ + +/* Memory Self-Test/Initialization Enable Register */ + +#if defined(CONFIG_ARCH_CHIP_TMS570LS0332PZ) || defined(CONFIG_ARCH_CHIP_TMS570LS0432PZ) + /* From TMS570LS0x32 Data Sheet */ + +# define SYS_MSIENA_RAM (1 << 0) +# define SYS_MSIENA_VIM_RAM (1 << 2) +# define SYS_MSIENA_N2HET_RAM (1 << 3) +# define SYS_MSIENA_HTU_RAM (1 << 4) +# define SYS_MSIENA_DCAN1_RAM (1 << 5) +# define SYS_MSIENA_DCAN2_RAM (1 << 6) +# define SYS_MSIENA_MIBSPI1_RAM (1 << 7) +# define SYS_MSIENA_MIBADC_RAM (1 << 8) +#endif + +/* Memory Self-Test Fail Status Register */ +#define SYS_MSTFAIL_ + +/* MSTC Global Status Register */ + +#define SYS_MSTCGSTAT_MSTDONE (1 << 0) /* Bit 0: Memory self-test done */ +#define SYS_MSTCGSTAT_MINIDONE (1 << 8) /* Bit 8: Hardware initialization of all memory done */ + +/* Memory Hardware Initialization Status Register */ +#define SYS_MINISTAT_ + +/* PLL Control Register 1 */ + +#define SYS_PLLCTL1_PLLMUL_SHIFT (0) /* Bits 0-15: PLL Multiplication Factor */ +#define SYS_PLLCTL1_PLLMUL_MASK (0xffff << SYS_PLLCTL1_PLLMUL_SHIFT) +# define SYS_PLLCTL1_PLLMUL(n) ((uint32_t)(n) << SYS_PLLCTL1_PLLMUL_SHIFT) +#define SYS_PLLCTL1_REFCLKDIV_SHIFT (16) /* Bits 16-21: Reference Clock Divider */ +#define SYS_PLLCTL1_REFCLKDIV_MASK (0x3f << SYS_PLLCTL1_REFCLKDIV_SHIFT) +# define SYS_PLLCTL1_REFCLKDIV(n) ((uint32_t)(n) << SYS_PLLCTL1_REFCLKDIV_SHIFT) +#define SYS_PLLCTL1_ROF (1 << 23) /* Bit 23: Reset on Oscillator Fail */ +#define SYS_PLLCTL1_PLLDIV_SHIFT (24) /* Bits 24-28: PLL Output Clock Divider */ +#define SYS_PLLCTL1_PLLDIV_MASK (0x1f << SYS_PLLCTL1_PLLDIV_SHIFT) +# define SYS_PLLCTL1_PLLDIV(n) ((uint32_t)(n) << SYS_PLLCTL1_PLLDIV_SHIFT) +# define SYS_PLLCTL1_PLLDIV_MAX SYS_PLLCTL1_PLLDIV_MASK +#define SYS_PLLCTL1_MASKSLIP_SHIFT (29) /* Bits 29-30: Mask detection of PLL slip */ +#define SYS_PLLCTL1_MASKSLIP_MASK (3 << SYS_PLLCTL1_MASKSLIP_SHIFT) +# define SYS_PLLCTL1_MASKSLIP_DISABLE (0 << SYS_PLLCTL1_MASKSLIP_SHIFT) /* All values but 2 disable */ +# define SYS_PLLCTL1_MASKSLIP_ENABLE (2 << SYS_PLLCTL1_MASKSLIP_SHIFT) +#define SYS_PLLCTL1_ROS (1 << 31) /* Bit 31: Reset on PLL Slip */ + +/* PLL Control Register 2 */ + +#define SYS_PLLCTL2_SPRAMOUNT_SHIFT (0) /* Bits 0-8: Spreading Amount */ +#define SYS_PLLCTL2_SPRAMOUNT_MASK (0xff << SYS_PLLCTL2_SPRAMOUNT_SHIFT) +# define SYS_PLLCTL2_SPRAMOUNT(n) ((uint32_t)(n) << SYS_PLLCTL2_SPRAMOUNT_SHIFT) +#define SYS_PLLCTL2_ODPLL_SHIFT (9) /* Bits 9-11: Internal PLL Output Divider */ +#define SYS_PLLCTL2_ODPLL_MASK (7 << SYS_PLLCTL2_ODPLL_SHIFT) +# define SYS_PLLCTL2_ODPLL(n) ((uint32_t)(n) << SYS_PLLCTL2_ODPLL_SHIFT) +#define SYS_PLLCTL2_MULMOD_SHIFT (12) /* Bits 12-20: Multiplier Correction when Frequency Modulation is enabled */ +#define SYS_PLLCTL2_MULMOD_MASK (0x1ff << SYS_PLLCTL2_MULMOD_SHIFT) +# define SYS_PLLCTL2_MULMOD(n) ((uint32_t)(n) << SYS_PLLCTL2_MULMOD_SHIFT) +#define SYS_PLLCTL2_SPRRATE_SHIFT (22) /* Bits 22-30: NS = SPREADINGRATE + 1 */ +#define SYS_PLLCTL2_SPRRATE_MASK (0x1ff << SYS_PLLCTL2_SPRRATE_SHIFT) +# define SYS_PLLCTL2_SPRRATE(n) ((uint32_t)(n) << SYS_PLLCTL2_SPRRATE_SHIFT) +#define SYS_PLLCTL2_FMENA (1 << 31) /* Bit 31: Frequency Modulation Enable */ + +/* SYS Pin Control Register 10 */ + +#define SYS_PC10_ECLCSLEW (1 << 0) /* Bit 0: ECLK slew control */ + +/* Die Identification Register, Lower Word */ +#define SYS_DIEIDL_ +/* Die Identification Register, Upper Word */ +#define SYS_DIEIDH_ +/* LPO/Clock Monitor Control Register */ + +#define SYS_LPOMONCTL_LFTRIM_SHIFT (0) /* Bits 0-4: Low frequency oscillator trim value */ +#define SYS_LPOMONCTL_LFTRIM_MASK (31 << SYS_LPOMONCTL_LFTRIM_SHIFT) +# define SYS_LPOMONCTL_20p67 (0 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 20.67% */ +# define SYS_LPOMONCTL_25p76 (1 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 25.76% */ +# define SYS_LPOMONCTL_30p84 (2 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 30.84% */ +# define SYS_LPOMONCTL_35p90 (3 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 35.90% */ +# define SYS_LPOMONCTL_40p93 (4 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 40.93% */ +# define SYS_LPOMONCTL_45p95 (5 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 45.95% */ +# define SYS_LPOMONCTL_50p97 (6 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 50.97% */ +# define SYS_LPOMONCTL_55p91 (7 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 55.91% */ +# define SYS_LPOMONCTL_60p86 (8 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 60.86% */ +# define SYS_LPOMONCTL_65p78 (9 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 65.78% */ +# define SYS_LPOMONCTL_70p75 (10 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 70.75% */ +# define SYS_LPOMONCTL_75p63 (11 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 75.63% */ +# define SYS_LPOMONCTL_80p61 (12 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 80.61% */ +# define SYS_LPOMONCTL_85p39 (13 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 85.39% */ +# define SYS_LPOMONCTL_90p23 (14 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 90.23% */ +# define SYS_LPOMONCTL_95p11 (15 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 95.11% */ +# define SYS_LPOMONCTL_100p00 (16 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 100.00% */ +# define SYS_LPOMONCTL_104p84 (17 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 104.84% */ +# define SYS_LPOMONCTL_109p51 (18 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 109.51% */ +# define SYS_LPOMONCTL_114p31 (19 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 114.31% */ +# define SYS_LPOMONCTL_119p01 (20 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 119.01% */ +# define SYS_LPOMONCTL_123p75 (21 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 123.75% */ +# define SYS_LPOMONCTL_128p62 (22 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 128.62% */ +# define SYS_LPOMONCTL_133p31 (23 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 133.31% */ +# define SYS_LPOMONCTL_138p03 (24 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 138.03% */ +# define SYS_LPOMONCTL_142p75 (25 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 142.75% */ +# define SYS_LPOMONCTL_147p32 (26 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 147.32% */ +# define SYS_LPOMONCTL_152p02 (27 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 152.02% */ +# define SYS_LPOMONCTL_156p63 (28 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 156.63% */ +# define SYS_LPOMONCTL_161p38 (29 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 161.38% */ +# define SYS_LPOMONCTL_165p90 (30 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 165.90% */ +# define SYS_LPOMONCTL_170p42 (31 << SYS_LPOMONCTL_LFTRIM_SHIFT) /* 170.42% */ +#define SYS_LPOMONCTL_HFTRIM_SHIFT (8) /* Bits 8-12: High frequency oscillator trim value */ +#define SYS_LPOMONCTL_HFTRIM_MASK (31 << SYS_LPOMONCTL_HFTRIM_SHIFT) +# define SYS_LPOMONCTL_HFTRIM_29p52 (0 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 29.52% */ +# define SYS_LPOMONCTL_HFTRIM_34p24 (1 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 34.24% */ +# define SYS_LPOMONCTL_HFTRIM_38p85 (2 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 38.85% */ +# define SYS_LPOMONCTL_HFTRIM_43p45 (3 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 43.45% */ +# define SYS_LPOMONCTL_HFTRIM_47p99 (4 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 47.99% */ +# define SYS_LPOMONCTL_HFTRIM_52p55 (5 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 52.55% */ +# define SYS_LPOMONCTL_HFTRIM_57p02 (6 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 57.02% */ +# define SYS_LPOMONCTL_HFTRIM_61p46 (7 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 61.46% */ +# define SYS_LPOMONCTL_HFTRIM_65p92 (8 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 65.92% */ +# define SYS_LPOMONCTL_HFTRIM_70p17 (9 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 70.17% */ +# define SYS_LPOMONCTL_HFTRIM_74p55 (10 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 74.55% */ +# define SYS_LPOMONCTL_HFTRIM_78p92 (11 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 78.92% */ +# define SYS_LPOMONCTL_HFTRIM_83p17 (12 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 83.17% */ +# define SYS_LPOMONCTL_HFTRIM_87p43 (13 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 87.43% */ +# define SYS_LPOMONCTL_HFTRIM_91p75 (14 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 91.75% */ +# define SYS_LPOMONCTL_HFTRIM_95p89 (15 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 95.89% */ +# define SYS_LPOMONCTL_HFTRIM_100p00 (16 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 100.00% */ +# define SYS_LPOMONCTL_HFTRIM_104p09 (17 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 104.09% */ +# define SYS_LPOMONCTL_HFTRIM_108p17 (18 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 108.17% */ +# define SYS_LPOMONCTL_HFTRIM_112p32 (19 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 112.32% */ +# define SYS_LPOMONCTL_HFTRIM_116p41 (20 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 116.41% */ +# define SYS_LPOMONCTL_HFTRIM_120p67 (21 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 120.67% */ +# define SYS_LPOMONCTL_HFTRIM_124p42 (22 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 124.42% */ +# define SYS_LPOMONCTL_HFTRIM_128p38 (23 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 128.38% */ +# define SYS_LPOMONCTL_HFTRIM_132p24 (24 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 132.24% */ +# define SYS_LPOMONCTL_HFTRIM_136p15 (25 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 136.15% */ +# define SYS_LPOMONCTL_HFTRIM_140p15 (26 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 140.15% */ +# define SYS_LPOMONCTL_HFTRIM_143p94 (27 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 143.94% */ +# define SYS_LPOMONCTL_HFTRIM_148p02 (28 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 148.02% */ +# define SYS_LPOMONCTL_HFTRIM_151p80 (29 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 151.80% */ +# define SYS_LPOMONCTL_HFTRIM_155p50 (30 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 155.50% */ +# define SYS_LPOMONCTL_HFTRIM_159p35 (31 << SYS_LPOMONCTL_HFTRIM_SHIFT) /* 159.35% */ +#define SYS_LPOMONCTL_OSCFRQCONFIGCNT (1 << 16) /* Bit 16: Configures the counter based on OSC frequency. */ +#define SYS_LPOMONCTL_BIASENABLE (1 << 24) /* Bit 24: Bias enable. */ + +/* Clock Test Register */ +#define SYS_CLKTEST_ +/* DFT Control Register */ +#define SYS_DFTCTRLREG_ +/* DFT Control Register 2 */ +#define SYS_DFTCTRLREG2_ +/* General Purpose Register */ +#define SYS_GPREG1_ +/* Imprecise Fault Status Register */ +#define SYS_IMPFASTS_ +/* Imprecise Fault Write Address Register */ +#define SYS_IMPFTADD_ +/* System Software Interrupt Request 1 Register */ +#define SYS_SSIR1_ +/* System Software Interrupt Request 2 Register */ +#define SYS_SSIR2_ +/* System Software Interrupt Request 3 Register */ +#define SYS_SSIR3_ +/* System Software Interrupt Request 4 Register */ +#define SYS_SSIR4_ +/* RAM Control Register */ +#define SYS_RAMGCR_ +/* Bus Matrix Module Control Register 1 */ +#define SYS_BMMCR1_ +/* CPU Reset Control Register */ +#define SYS_CPURSTCR_ + +/* Clock Control Register */ + +#define SYS_CLKCNTL_PENA (1 << 8) /* Bit 8: Peripheral enable bit */ +#define SYS_CLKCNTL_VCLKR_SHIFT (16) /* Bits 16-19: VBUS clock ratio */ +#define SYS_CLKCNTL_VCLKR_MASK (15 << SYS_CLKCNTL_VCLKR_SHIFT) +# define SYS_CLKCNTL_VCLKR_DIV1 (0 << SYS_CLKCNTL_VCLKR_SHIFT) +# define SYS_CLKCNTL_VCLKR_DIV2 (1 << SYS_CLKCNTL_VCLKR_SHIFT) +#define SYS_CLKCNTL_VCLKR2_SHIFT (24) /* Bits 24-27: VBUS clock2 ratio */ +#define SYS_CLKCNTL_VCLKR2_MASK (15 << SYS_CLKCNTL_VCLKR2_SHIFT) +# define SYS_CLKCNTL_VCLKR2_DIV1 (0 << SYS_CLKCNTL_VCLKR2_SHIFT) +# define SYS_CLKCNTL_VCLKR2_DIV2 (1 << SYS_CLKCNTL_VCLKR2_SHIFT) + +/* ECP Control Register */ + +#define SYS_ECPCNTL_ECPDIV_SHIFT (0) /* Bits 0-15: ECP divider value */ +#define SYS_ECPCNTL_ECPDIV_MASK (0xffff << SYS_ECPCNTL_ECPDIV_SHIFT) +# define SYS_ECPCNTL_ECPDIV(n) ((uint32_t)(n) << SYS_ECPCNTL_ECPDIV_SHIFT) +#define SYS_ECPCNTL_ECPINSEL_SHIFT (16) /* Bits 16-17: Select ECP input clock source */ +#define SYS_ECPCNTL_ECPINSEL_MASK (3 << SYS_ECPCNTL_ECPINSEL_SHIFT) +# define SYS_ECPCNTL_ECPINSEL_LOW (0 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* Tied Low */ +# define SYS_ECPCNTL_ECPINSEL_HCLK (1 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* HCLK */ +# define SYS_ECPCNTL_ECPINSEL_EXTCLK (2 << SYS_ECPCNTL_ECPINSEL_SHIFT) /* External clock */ +#define SYS_ECPCNTL_ECPCOS (1 << 23) /* Bit 23: ECP continue on suspend */ +#define SYS_ECPCNTL_ECPSSEL (1 << 24) /* Bit 24: Select VCLK os OSCIN as for ECLK */ + +/* DEV Parity Control Register 1 */ +#define SYS_DEVCR1_ +/* System Exception Control Register */ +#define SYS_ECR_ +/* System Exception Status Register */ + +#define SYS_ESR_MPMODE (1 << 0) /* Bit 0: Current memory protection unit (MPU) mode */ +#define SYS_ESR_EXTRST (1 << 3) /* Bit 3: External reset flag */ +#define SYS_ESR_SWRST (1 << 4) /* Bit 4: Software reset flag */ +#define SYS_ESR_CPURST (1 << 5) /* Bit 5: CPU reset flag */ +#define SYS_ESR_WDRST (1 << 13) /* Bit 13: Watchdog reset flag */ +#define SYS_ESR_OSCRST (1 << 14) /* Bit 14: Reset caused by an oscillator failure or PLL cycle slip */ +#define SYS_ESR_PORST (1 << 15) /* Bit 15: Power-up reset */ + +#define SYS_ESR_RSTALL (0x0000e038) +#define SYS_ESR_FAILALL (0x00006000) + +/* System Test Abort Status Register */ +#define SYS_TASR_ +/* Global Status Register */ +#define SYS_GLBSTAT_ +/* Device Identification Register */ +#define SYS_DEVID_ +/* Software Interrupt Vector Register */ +#define SYS_SSIVEC_ +/* System Software Interrupt Flag Register */ +#define SYS_SSIF_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS_H */ diff --git a/arch/arm/src/tms570/chip/tms570_sys2.h b/arch/arm/src/tms570/chip/tms570_sys2.h new file mode 100644 index 0000000000000000000000000000000000000000..9edb33cd396736e0cc0d06cc6eda6eb9053ade33 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_sys2.h @@ -0,0 +1,93 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_sys2.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS2_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS2_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define TMS570_SYS2_STCCLKDIV_OFFSET 0x0008 /* CPU Logic BIST Clock Divider */ +#define TMS570_SYS2_CLKSLIP_OFFSET 0x0070 /* Clock Slip Register */ +#define TMS570_SYS2_EFC_CTLREG_OFFSET 0x00ec /* EFUSE Controller Control Register */ +#define TMS570_SYS2_DIEDL_REG0_OFFSET 0x00f0 /* Die Identification Register Lower Word */ +#define TMS570_SYS2_DIEDH_REG1_OFFSET 0x00f4 /* Die Identification Register Upper Word */ +#define TMS570_SYS2_DIEDL_REG2_OFFSET 0x00f8 /* Die Identification Register Lower Word */ +#define TMS570_SYS2_DIEDH_REG3_OFFSET 0x00fc /* Die Identification Register Upper Word */ + +/* Register Addresses *******************************************************************************/ + +#define TMS570_SYS2_STCCLKDIV (TMS570_SYS2_BASE+TMS570_SYS2_STCCLKDIV_OFFSET) +#define TMS570_SYS2_CLKSLIP (TMS570_SYS2_BASE+TMS570_SYS2_CLKSLIP_OFFSET) +#define TMS570_SYS2_EFC_CTLREG (TMS570_SYS2_BASE+TMS570_SYS2_EFC_CTLREG_OFFSET) +#define TMS570_SYS2_DIEDL_REG0 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDL_REG0_OFFSET) +#define TMS570_SYS2_DIEDH_REG1 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDH_REG1_OFFSET) +#define TMS570_SYS2_DIEDL_REG2 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDL_REG2_OFFSET) +#define TMS570_SYS2_DIEDH_REG3 (TMS570_SYS2_BASE+TMS570_SYS2_DIEDH_REG3_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* CPU Logic BIST Clock Divider */ +#define SYS2_STCCLKDIV_ +/* Clock Slip Register */ +#define SYS2_CLKSLIP_ +/* EFUSE Controller Control Register */ +#define SYS2_EFC_CTLREG_ +/* Die Identification Register Lower Word */ +#define SYS2_DIEDL_REG0_ +/* Die Identification Register Upper Word */ +#define SYS2_DIEDH_REG1_ +/* Die Identification Register Lower Word */ +#define SYS2_DIEDL_REG2_ +/* Die Identification Register Upper Word */ +#define SYS2_DIEDH_REG3_ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_SYS2_H */ diff --git a/arch/arm/src/tms570/chip/tms570_vim.h b/arch/arm/src/tms570/chip/tms570_vim.h new file mode 100644 index 0000000000000000000000000000000000000000..9b30c33374c2b707b0d019e9222e139167466f45 --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570_vim.h @@ -0,0 +1,218 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570_vim.h + * Vector Intererrupt Manager (VIM) Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570_VIM_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570_VIM_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +#define VIM_REGNDX(ch) ((ch) >> 5) +#define VIM_REGBIT(ch) ((ch) & 31) + +/* Register Offsets *********************************************************************************/ + +/* Register Offsets relative to the VIM Parity Frame */ + +#define TMS570_VIM_PARFLG_OFFSET 0x00ec /* Interrupt Vector Table Parity Flag Register */ +#define TMS570_VIM_PARCTL_OFFSET 0x00f0 /* Interrupt Vector Table Parity Control Register */ +#define TMS570_VIM_ADDERR_OFFSET 0x00f4 /* Address Parity Error Register */ +#define TMS570_VIM_FBPARERR_OFFSET 0x00f8 /* Fall-Back Address Parity Error Register */ + +/* Register Offsets relative to the VIM Frame */ + +#define TMS570_VIM_IRQINDEX_OFFSET 0x0000 /* IRQ Index Offset Vector Register */ +#define TMS570_VIM_FIQINDEX_OFFSET 0x0004 /* FIQ Index Offset Vector Register */ +#define TMS570_VIM_FIRQPR_OFFSET(n) (0x0010 + ((n) << 2)) +# define TMS570_VIM_FIRQPR0_OFFSET 0x0010 /* FIQ/IRQ Program Control Register 0 */ +# define TMS570_VIM_FIRQPR1_OFFSET 0x0014 /* FIQ/IRQ Program Control Register 1 */ +# define TMS570_VIM_FIRQPR2_OFFSET 0x0018 /* FIQ/IRQ Program Control Register 2 */ +#define TMS570_VIM_INTREQ_OFFSET(n) (0x0020 + ((n) << 2)) +# define TMS570_VIM_INTREQ0_OFFSET 0x0020 /* Pending Interrupt Read Location Register 0 */ +# define TMS570_VIM_INTREQ1_OFFSET 0x0024 /* Pending Interrupt Read Location Register 1 */ +# define TMS570_VIM_INTREQ2_OFFSET 0x0028 /* Pending Interrupt Read Location Register 2 */ +#define TMS570_VIM_REQENASET_OFFSET(n) (0x0030 + ((n) << 2)) +# define TMS570_VIM_REQENASET0_OFFSET 0x0030 /* Interrupt Enable Set Register 0 */ +# define TMS570_VIM_REQENASET1_OFFSET 0x0034 /* Interrupt Enable Set Register 1 */ +# define TMS570_VIM_REQENASET2_OFFSET 0x0038 /* Interrupt Enable Set Register 2 */ +#define TMS570_VIM_REQENACLR_OFFSET(n) (0x0040 + ((n) << 2)) +# define TMS570_VIM_REQENACLR0_OFFSET 0x0040 /* Interrupt Enable Clear Register 0 */ +# define TMS570_VIM_REQENACLR1_OFFSET 0x0044 /* Interrupt Enable Clear Register 1 */ +# define TMS570_VIM_REQENACLR2_OFFSET 0x0048 /* Interrupt Enable Clear Register 2 */ +#define TMS570_VIM_WAKEENASET_OFFSET(n) (0x0050 + ((n) << 2)) +# define TMS570_VIM_WAKEENASET0_OFFSET 0x0050 /* Wake-up Enable Set Register 0 */ +# define TMS570_VIM_WAKEENASET1_OFFSET 0x0054 /* Wake-up Enable Set Register 1 */ +# define TMS570_VIM_WAKEENASET2_OFFSET 0x0058 /* Wake-up Enable Set Register 2 */ +#define TMS570_VIM_WAKEENACLR_OFFSET(n) (0x0060 + ((n) << 2)) +# define TMS570_VIM_WAKEENACLR0_OFFSET 0x0060 /* Wake-up Enable Clear Register 0 */ +# define TMS570_VIM_WAKEENACLR1_OFFSET 0x0064 /* Wake-up Enable Clear Register 1 */ +# define TMS570_VIM_WAKEENACLR2_OFFSET 0x0068 /* Wake-up Enable Clear Register 2 */ +#define TMS570_VIM_IRQVECREG_OFFSET 0x0070 /* IRQ Interrupt Vector Register */ +#define TMS570_VIM_FIQVECREG_OFFSET 0x0074 /* FIQ Interrupt Vector Register */ +#define TMS570_VIM_CAPEVT_OFFSET 0x0078 /* Capture Event Register */ + +/* 0x0080-0x00dc VIM Interrupt Control Register */ + +#define TMS570_VIM_CHANCTRL_INDEX(n) ((n) >> 2) +#define TMS570_VIM_CHANCTRL_OFFSET(n) (0x0080 << (TMS570_VIM_CHANCTRL_INDEX(n) << 2)) + +/* Register Addresses *******************************************************************************/ + +/* VIM Parity Frame Registers */ + +#define TMS570_VIM_PARFLG (TMS570_VIMPAR_BASE+TMS570_VIM_PARFLG_OFFSET) +#define TMS570_VIM_PARCTL (TMS570_VIMPAR_BASE+TMS570_VIM_PARCTL_OFFSET) +#define TMS570_VIM_ADDERR (TMS570_VIMPAR_BASE+TMS570_VIM_ADDERR_OFFSET) +#define TMS570_VIM_FBPARERR (TMS570_VIMPAR_BASE+TMS570_VIM_FBPARERR_OFFSET) + +/* VIM Frame Registers */ + +#define TMS570_VIM_IRQINDEX (TMS570_VIM_BASE+TMS570_VIM_IRQINDEX_OFFSET) +#define TMS570_VIM_FIQINDEX (TMS570_VIM_BASE+TMS570_VIM_FIQINDEX_OFFSET) +#define TMS570_VIM_FIRQPR(n) (TMS570_VIM_BASE+TMS570_VIM_FIRQPR_OFFSET(n)) +# define TMS570_VIM_FIRQPR0 (TMS570_VIM_BASE+TMS570_VIM_FIRQPR0_OFFSET) +# define TMS570_VIM_FIRQPR1 (TMS570_VIM_BASE+TMS570_VIM_FIRQPR1_OFFSET) +# define TMS570_VIM_FIRQPR2 (TMS570_VIM_BASE+TMS570_VIM_FIRQPR2_OFFSET) +#define TMS570_VIM_INTREQ(n) (TMS570_VIM_BASE+TMS570_VIM_INTREQ_OFFSET(n)) +# define TMS570_VIM_INTREQ0 (TMS570_VIM_BASE+TMS570_VIM_INTREQ0_OFFSET) +# define TMS570_VIM_INTREQ1 (TMS570_VIM_BASE+TMS570_VIM_INTREQ1_OFFSET) +# define TMS570_VIM_INTREQ2 (TMS570_VIM_BASE+TMS570_VIM_INTREQ2_OFFSET) +#define TMS570_VIM_REQENASET(n) (TMS570_VIM_BASE+TMS570_VIM_REQENASET_OFFSET(n)) +# define TMS570_VIM_REQENASET0 (TMS570_VIM_BASE+TMS570_VIM_REQENASET0_OFFSET) +# define TMS570_VIM_REQENASET1 (TMS570_VIM_BASE+TMS570_VIM_REQENASET1_OFFSET) +# define TMS570_VIM_REQENASET2 (TMS570_VIM_BASE+TMS570_VIM_REQENASET2_OFFSET) +#define TMS570_VIM_REQENACLR(n) (TMS570_VIM_BASE+TMS570_VIM_REQENACLR_OFFSET(n)) +# define TMS570_VIM_REQENACLR0 (TMS570_VIM_BASE+TMS570_VIM_REQENACLR0_OFFSET) +# define TMS570_VIM_REQENACLR1 (TMS570_VIM_BASE+TMS570_VIM_REQENACLR1_OFFSET) +# define TMS570_VIM_REQENACLR2 (TMS570_VIM_BASE+TMS570_VIM_REQENACLR2_OFFSET) +#define TMS570_VIM_WAKEENASET(n) (TMS570_VIM_BASE+TMS570_VIM_WAKEENASET_OFFSET(n)) +# define TMS570_VIM_WAKEENASET0 (TMS570_VIM_BASE+TMS570_VIM_WAKEENASET0_OFFSET) +# define TMS570_VIM_WAKEENASET1 (TMS570_VIM_BASE+TMS570_VIM_WAKEENASET1_OFFSET) +# define TMS570_VIM_WAKEENASET2 (TMS570_VIM_BASE+TMS570_VIM_WAKEENASET2_OFFSET) +#define TMS570_VIM_WAKEENACLR(n) (TMS570_VIM_BASE+TMS570_VIM_WAKEENACLR_OFFSET(n)) +# define TMS570_VIM_WAKEENACLR0 (TMS570_VIM_BASE+TMS570_VIM_WAKEENACLR0_OFFSET) +# define TMS570_VIM_WAKEENACLR1 (TMS570_VIM_BASE+TMS570_VIM_WAKEENACLR1_OFFSET) +# define TMS570_VIM_WAKEENACLR2 (TMS570_VIM_BASE+TMS570_VIM_WAKEENACLR2_OFFSET) +#define TMS570_VIM_IRQVECREG (TMS570_VIM_BASE+TMS570_VIM_IRQVECREG_OFFSET) +#define TMS570_VIM_FIQVECREG (TMS570_VIM_BASE+TMS570_VIM_FIQVECREG_OFFSET) +#define TMS570_VIM_CAPEVT (TMS570_VIM_BASE+TMS570_VIM_CAPEVT_OFFSET) + +/* 0x0080-0x00dc VIM Interrupt Control Register */ + +#define TMS570_VIM_CHANCTRL(n) (TMS570_VIM_BASE+TMS570_VIM_CHANCTRL_OFFSET(n)) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Interrupt Vector Table Parity Flag Register */ +#define VIM_PARFLG_ +/* Interrupt Vector Table Parity Control Register */ +#define VIM_PARCTL_ +/* Address Parity Error Register */ +#define VIM_ADDERR_ +/* Fall-Back Address Parity Error Register */ +#define VIM_FBPARERR_ + +/* IRQ Index Offset Vector Register */ + +#define VIM_IRQINDEX_MASK (0x000000ff) /* IRQ index vector */ + +/* FIQ Index Offset Vector Register */ + +#define VIM_FIQINDEX_MASK (0x000000ff) /* FIQ index vector */ + +/* FIQ/IRQ Program Control Register 0 */ +#define VIM_FIRQPR0_ +/* FIQ/IRQ Program Control Register 1 */ +#define VIM_FIRQPR1_ +/* FIQ/IRQ Program Control Register 2 */ +#define VIM_FIRQPR2_ +/* Pending Interrupt Read Location Register 0 */ +#define VIM_INTREQ0_ +/* Pending Interrupt Read Location Register 1 */ +#define VIM_INTREQ1_ +/* Pending Interrupt Read Location Register 2 */ +#define VIM_INTREQ2_ +/* Interrupt Enable Set Register 0 */ +#define VIM_REQENASET0_ +/* Interrupt Enable Set Register 1 */ +#define VIM_REQENASET1_ +/* Interrupt Enable Set Register 2 */ +#define VIM_REQENASET2_ +/* Interrupt Enable Clear Register 0 */ +#define VIM_REQENACLR0_ +/* Interrupt Enable Clear Register 1 */ +#define VIM_REQENACLR1_ +/* Interrupt Enable Clear Register 2 */ +#define VIM_REQENACLR2_ +/* Wake-up Enable Set Register 0 */ +#define VIM_WAKEENASET0_ +/* Wake-up Enable Set Register 1 */ +#define VIM_WAKEENASET1_ +/* Wake-up Enable Set Register 2 */ +#define VIM_WAKEENASET2_ +/* Wake-up Enable Clear Register 0 */ +#define VIM_WAKEENACLR0_ +/* Wake-up Enable Clear Register 1 */ +#define VIM_WAKEENACLR1_ +/* Wake-up Enable Clear Register 2 */ +#define VIM_WAKEENACLR2_ +/* IRQ Interrupt Vector Register */ +#define VIM_IRQVECREG_ +/* FIQ Interrupt Vector Register */ +#define VIM_FIQVECREG_ +/* Capture Event Register */ +#define VIM_CAPEVT_ + +/* 0x0080-0x00dc VIM Interrupt Control Register */ + +#define VIM_CHANCTRL_SHIFT(n) (((n) & 3) << 3) +#define VIM_CHANCTRL_MASK(n) (0xff << VIM_CHANCTRL_SHIFT(n)) +# define VIM_CHANCTRL(n,v) ((uint32_t)(v) << VIM_CHANCTRL_SHIFT(n)) + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570_VIM_H */ diff --git a/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h b/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..df12323497d743518b395e211ba31892b82134fe --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h @@ -0,0 +1,131 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570ls04x03x_memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Memory Map Overview */ + +#define TMS570_FLASH_BASE 0x00000000 /* 0x00000000-0x0005ffff: Program FLASH */ + /* 0x00060000-0x07ffffff: Reserved */ +#define TMS570_RAM_BASE 0x08000000 /* 0x08000000-0x08007fff: RAM */ + /* 0x08008000-0x1fffffff: Reserved */ +#define TMS570_MIRROR_BASE 0x20000000 /* 0x20000000-0x2005ffff: Program FLASH mirror */ + /* 0x20060000-0xefffffff: Reserved */ +#define TMS570_BUS2_BASE 0xf0000000 /* 0xf0000000-0xf07fffff: Flash Module BUS2 Interface */ + /* 0xf0800000-0xfbffffff: Reserved */ +#define TMS570_PERIPH2_BASE 0xfc000000 /* 0xfc000000-0xfcffffff: Peripherals - Frame 2 */ + /* 0xfd000000-0xfdffffff: Reserved */ +#define TMS570_CRC_BASE 0xfe000000 /* 0xfe000000-0xfeffffff: CRC */ +#define TMS570_PERIPH1_BASE 0xff000000 /* 0xff000000-0xff7fffff: Peripherals - Frame 1 */ +#define TMS570_SYSTEM_BASE 0xfff80000 /* 0xff800000-0xffffffff: System Modules */ + +/* Flash Bus2 Interface: OTP, ECC, EEPROM Bank */ + +#define TMS570_CUSTTCM_BASE 0xf0000000 /* 0xf0000000-0xf000dfff: Customer OTP, TCM FLASH bank */ +#define TMS570_CUSTEEPROM_BASE 0xf000e000 /* 0xf000e000-0xf000ffff: Customer OTP, EEPROM bank */ +#define TMS570_CUSTECC_BASE 0xf0040000 /* 0xf0040000-0xf00403ff: Customer OTP-ECC, TCM FLASH bank */ +#define TMS570_CUSTECCEEPROM_BASE 0xf0040000 /* 0xf0041c00-0xf0041fff: Customer OTP-ECC, EEPROM bank */ + +#define TMS570_TITCM_BASE 0xf0080000 /* 0xf0080000-0xf008dfff: TI OTP, TCM FLASH bank */ +#define TMS570_TIEEPROM_BASE 0xf008e000 /* 0xf008e000-0xf008ffff: TI OTP, EEPROM bank */ +#define TMS570_TIECC_BASE 0xf00c0000 /* 0xf00c0000-0xf00c03ff: TI OTP-ECC, TCM FLASH bank */ +#define TMS570_TIECCEEPROM_BASE 0xf00c1c00 /* 0xf00c1c00-0xf00c1fff: TI OTP-ECC, EEPROM bank */ + +#define TMS570_EEC_BASE 0xf0100000 /* 0xf0100000-0xf013ffff: EEPROM Bank - EEC */ +#define TMS570_EEPROM_BASE 0xf0200000 /* 0xf0200000-0xf03fffff: EEPROM Bank */ +#define TMS570_FDATA_BASE 0xf0400000 /* 0xf0400000-0xf04fffff: FLASH Data Space - ECC */ + +/* Debug Components */ + +#define TMS570_CORESIGHT_BASE 0xffa00000 /* 0xffa00000-0xffa00fff: CoreSight Debug ROM */ +#define TMS570_CORTEXR4_BASE 0xffa01000 /* 0xffa01000-0xffa01fff: Cortex-R4 Debug */ + +/* Peripheral Memories */ + +#define TMS570_MIBSPI1RAM_BASE 0xff0e0000 /* 0xff0e0000-0xff0fffff: MIBSPI1 RAM */ +#define TMS570_DCAN2RAM_BASE 0xff1c0000 /* 0xff1c0000-0xff1dffff: DCAN2 RAM */ +#define TMS570_DCAN1RAM_BASE 0xff1e0000 /* 0xff1c0000-0xff1fffff: DCAN1 RAM */ +#define TMS570_MIBADCRAM_BASE 0xff3e0000 /* 0xff3e0000-0xff3fffff: MIBADC RAM */ +#define TMS570_MIBADCLUT_BASE 0xff3e0000 /* 0xff3e0000-0xff3fffff: MIBADC Lookup Table */ +#define TMS570_N2HETRAM_BASE 0xff460000 /* 0xff460000-0xff47ffff: N2HET RAM */ +#define TMS570_HETTURAM_BASE 0xff4e0000 /* 0xff4e0000-0xff4fffff: HET TU RAM */ + +/* Peripheral Control Registers */ + +#define TMS570_HTU_BASE 0xfff7a400 /* 0xfff7a400-0xfff7a4ff: HTU */ +#define TMS570_N2HET_BASE 0xfff7b800 /* 0xfff7b800-0xfff7b8ff: N2HET */ +#define TMS570_GIO_BASE 0xfff7bc00 /* 0xfff7bc00-0xfff7bcff: GIO */ +#define TMS570_MIBADC_BASE 0xfff7bc00 /* 0xfff7c000-0xfff7c1ff: MIBADC */ +#define TMS570_DCAN1_BASE 0xfff7dc00 /* 0xfff7dc00-0xfff7ddff: DCAN1 */ +#define TMS570_DCAN2_BASE 0xfff7de00 /* 0xfff7de00-0xfff7dfff: DCAN2 */ +#define TMS570_SCI1_BASE 0xfff7e400 /* 0xfff7e400-0xfff7e4ff: SCI1/LIN1 */ +#define TMS570_MIBSPI1_BASE 0xfff7f400 /* 0xfff7f400-0xfff7f5ff: MibSPI1 */ +#define TMS570_SPI2_BASE 0xfff7f600 /* 0xfff7f600-0xfff7f7ff: SPI2 */ +#define TMS570_SPI3_BASE 0xfff7f800 /* 0xfff7f800-0xfff7f9ff: SPI3 */ +#define TMS570_EQEP_BASE 0xfff79900 /* 0xfff79900-0xfff799ff: EQEP */ +#define TMS570_EQEPM_BASE 0xfcf79900 /* 0xfcf79900-0xfcf799ff: EQEP (Mirrored) */ + +/* System Modules Control Registers and Memories */ + +#define TMS570_VIMRAM_BASE 0xfff82000 /* 0xfff82000-0xfff82fff: VIM RAM */ +#define TMS570_FWRAP_BASE 0xfff87000 /* 0xfff87000-0xfff87fff: Flash Wrapper */ +#define TMS570_EFFC_BASE 0xfff8c000 /* 0xfff8c000-0xfff8cfff: eFuse Farm Controller */ +#define TMS570_PCR_BASE 0xffffe000 /* 0xffffe000-0xffffe0ff: PCR registers */ +#define TMS570_SYS2_BASE 0xffffe100 /* 0xffffe100-0xffffe1ff: System Module - Frame 2 */ +#define TMS570_PBIST_BASE 0xffffe400 /* 0xffffe400-0xffffe5ff: PBIST */ +#define TMS570_STC_BASE 0xffffe600 /* 0xffffe600-0xffffe6ff: STC */ +#define TMS570_IOMM_BASE 0xffffea00 /* 0xffffea00-0xffffeBff: IOMM Multiplexing */ +#define TMS570_DCC_BASE 0xffffec00 /* 0xffffec00-0xffffeCff: DCC */ +#define TMS570_ESM_BASE 0xfffff500 /* 0xfffff500-0xfffff5ff: ESM */ +#define TMS570_CCMR4_BASE 0xfffff600 /* 0xfffff600-0xfffff6ff: CCM-R4 */ +#define TMS570_RAMECCE_BASE 0xfffff800 /* 0xfffff800-0xfffff8ff: RAM ECC even */ +#define TMS570_RAMECCO_BASE 0xfffff900 /* 0xfffff900-0xfffff9ff: RAM ECC odd */ +#define TMS570_RTIDWWD_BASE 0xfffffc00 /* 0xfffffc00-0xfffffcff: RTI + DWWD */ +#define TMS570_VIMPAR_BASE 0xfffffd00 /* 0xfffffd00-0xfffffdff: VIM Parity */ +#define TMS570_VIM_BASE 0xfffffe00 /* 0xfffffe00-0xfffffeff: VIM */ +#define TMS570_SYS_BASE 0xffffff00 /* 0xffffff00-0xffffffff: System Module - Frame 1 */ + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_MEMORYMAP_H */ diff --git a/arch/arm/src/tms570/chip/tms570ls04x03x_pinmux.h b/arch/arm/src/tms570/chip/tms570ls04x03x_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..113d9dfc757e810dd605d0cf813836f6954a01ad --- /dev/null +++ b/arch/arm/src/tms570/chip/tms570ls04x03x_pinmux.h @@ -0,0 +1,257 @@ +/**************************************************************************************************** + * arch/arm/src/tms570/chip/tms570ls04x03x_pinmux.h + * Secondary System Control Register Definitions + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * TMS570LS04x/03x 16/32-Bit RISC Flash Microcontroller, Technical Reference Manual, Texas + * Instruments, Literature Number: SPNU517A, September 2013 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_PINMUX_H +#define __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_PINMUX_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip/tms570_memorymap.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* DEFAULT SELECTION ALTERNATE SELECTION ALTERNATE SELECTION BIT + * FUNCTION BIT FUNCTION 1 BIT FUNCTION 2 BIT + * + * GIOA[0] PINMMR0[8] SPI3nCS[3] PINMMR0[9] - - + * GIOA[1] PINMMR1[0] SPI3nCS[2] PINMMR1[1] - - + * GIOA[2] PINMMR1[8] SPI3nCS[1] PINMMR1[9] - - + * GIOA[3] PINMMR1[16] SPI2nCS[3] PINMMR1[17] - - + * GIOA[4] PINMMR1[24] SPI2nCS[2] PINMMR1[25] - - + * GIOA[5] PINMMR2[0] EXTCLKIN PINMMR2[1] - - + * GIOA[6] PINMMR2[8] SPI2nCS[1] PINMMR2[9] N2HET[31] PINMMR2[10] + * GIOA[7] PINMMR2[16] N2HET[29] PINMMR2[17] - - + * MIBSPI1nCS[2] PINMMR3[0] N2HET[20] PINMMR3[1] N2HET[19] PINMMR3[2] + * SPI3CLK PINMMR3[16] EQEPA PINMMR3[17] - - + * SPI3nENA PINMMR3[24] EQEPB PINMMR3[25] - - + * SPI3nCS[0] PINMMR4[0] EQEPI PINMMR4[1] - - + * MIBSPI1nCS[3] PINMMR4[8] N2HET[26] PINMMR4[9] - - + * ADEVT PINMMR4[16] N2HET[28] PINMMR4[17] - - + * MIBSPI1nENA PINMMR5[8] N2HET[23] PINMMR5[9] NHET[30] PINMMR5[10] + * MIBSPI1nCS[1] PINMMR6[8] EQEPS PINMMR6[9] N2HET[17] PINMMR6[10] + */ + +#define PINMUX_GIOA0_PINMMR 0 +#define PINMUX_GIOA0_SHIFT 8 +#define PINMUX_GIOA0_VALUE 1 +#define PINMUX_GIOA0_PIN {PINMUX_GIOA0_PINMMR, PINMUX_GIOA0_SHIFT, PINMUX_GIOA0_VALUE} + +#define PINMUX_SPI3NCS3_PINMMR 0 +#define PINMUX_SPI3NCS3_SHIFT 8 +#define PINMUX_SPI3NCS3_VALUE 2 +#define PINMUX_SPI3NCS3_PIN {PINMUX_SPI3NCS3_PINMMR, PINMUX_SPI3NCS3_SHIFT, PINMUX_SPI3NCS3_VALUE} + +#define PINMUX_GIOA1_PINMMR 1 +#define PINMUX_GIOA1_SHIFT 0 +#define PINMUX_GIOA1_VALUE 1 +#define PINMUX_GIOA1_PIN {PINMUX_GIOA1_PINMMR, PINMUX_GIOA1_SHIFT, PINMUX_GIOA1_VALUE} + +#define PINMUX_SPI3NCS2_PINMMR 1 +#define PINMUX_SPI3NCS2_SHIFT 0 +#define PINMUX_SPI3NCS2_VALUE 2 +#define PINMUX_SPI3NCS2_PIN {PINMUX_SPI3NCS2_PINMMR, PINMUX_SPI3NCS2_SHIFT, PINMUX_SPI3NCS2_VALUE} + +#define PINMUX_GIOA2_PINMMR 1 +#define PINMUX_GIOA2_SHIFT 8 +#define PINMUX_GIOA2_VALUE 1 +#define PINMUX_GIOA2_PIN {PINMUX_GIOA2_PINMMR, PINMUX_GIOA2_SHIFT, PINMUX_GIOA2_VALUE} + +#define PINMUX_SPI3NCS1_PINMMR 1 +#define PINMUX_SPI3NCS1_SHIFT 8 +#define PINMUX_SPI3NCS1_VALUE 2 +#define PINMUX_SPI3NCS1_PIN {PINMUX_SPI3NCS1_PINMMR, PINMUX_SPI3NCS1_SHIFT, PINMUX_SPI3NCS1_VALUE} + +#define PINMUX_GIOA3_PINMMR 1 +#define PINMUX_GIOA3_SHIFT 16 +#define PINMUX_GIOA3_VALUE 1 +#define PINMUX_GIOA3_PIN {PINMUX_GIOA3_PINMMR, PINMUX_GIOA3_SHIFT, PINMUX_GIOA3_VALUE} + +#define PINMUX_SPI2NCS3_PINMMR 1 +#define PINMUX_SPI2NCS3_SHIFT 16 +#define PINMUX_SPI2NCS3_VALUE 2 +#define PINMUX_SPI2NCS3_PIN {PINMUX_SPI2NCS3_PINMMR, PINMUX_SPI2NCS3_SHIFT, PINMUX_SPI2NCS3_VALUE} + +#define PINMUX_GIOA4_PINMMR 1 +#define PINMUX_GIOA4_SHIFT 24 +#define PINMUX_GIOA4_VALUE 1 +#define PINMUX_GIOA4_PIN {PINMUX_GIOA4_PINMMR, PINMUX_GIOA4_SHIFT, PINMUX_GIOA4_VALUE} + +#define PINMUX_SPI2NCS2_PINMMR 1 +#define PINMUX_SPI2NCS2_SHIFT 24 +#define PINMUX_SPI2NCS2_VALUE 2 +#define PINMUX_SPI2NCS2_PIN {PINMUX_SPI2NCS2_PINMMR, PINMUX_SPI2NCS2_SHIFT, PINMUX_SPI2NCS2_VALUE} + +#define PINMUX_GIOA5_PINMMR 2 +#define PINMUX_GIOA5_SHIFT 0 +#define PINMUX_GIOA5_VALUE 1 +#define PINMUX_GIOA5_PIN {PINMUX_GIOA5_PINMMR, PINMUX_GIOA5_SHIFT, PINMUX_GIOA5_VALUE} + +#define PINMUX_EXTCLKIN_PINMMR 2 +#define PINMUX_EXTCLKIN_SHIFT 0 +#define PINMUX_EXTCLKIN_VALUE 2 +#define PINMUX_EXTCLKIN_PIN {PINMUX_EXTCLKIN_PINMMR, PINMUX_EXTCLKIN_SHIFT, PINMUX_EXTCLKIN_VALUE} + +#define PINMUX_GIOA6_PINMMR 2 +#define PINMUX_GIOA6_SHIFT 8 +#define PINMUX_GIOA6_VALUE 1 +#define PINMUX_GIOA6_PIN {PINMUX_GIOA6_PINMMR, PINMUX_GIOA6_SHIFT, PINMUX_GIOA6_VALUE} + +#define PINMUX_SPI2NCS1_PINMMR 2 +#define PINMUX_SPI2NCS1_SHIFT 8 +#define PINMUX_SPI2NCS1_VALUE 2 +#define PINMUX_SPI2NCS1_PIN {PINMUX_SPI2NCS1_PINMMR, PINMUX_SPI2NCS1_SHIFT, PINMUX_SPI2NCS1_VALUE} + +#define PINMUX_N2HET31_PINMMR 2 +#define PINMUX_N2HET31_SHIFT 8 +#define PINMUX_N2HET31_VALUE 4 +#define PINMUX_N2HET31_PIN {PINMUX_N2HET31_PINMMR, PINMUX_N2HET31_SHIFT, PINMUX_N2HET31_VALUE} + +#define PINMUX_GIOA7_PINMMR 2 +#define PINMUX_GIOA7_SHIFT 16 +#define PINMUX_GIOA7_VALUE 1 +#define PINMUX_GIOA7_PIN {PINMUX_GIOA7_PINMMR, PINMUX_GIOA7_SHIFT, PINMUX_GIOA7_VALUE} + +#define PINMUX_N2HET29_PINMMR 2 +#define PINMUX_N2HET29_SHIFT 16 +#define PINMUX_N2HET29_VALUE 2 +#define PINMUX_N2HET29_PIN {PINMUX_N2HET29_PINMMR, PINMUX_N2HET29_SHIFT, PINMUX_N2HET29_VALUE} + +#define PINMUX_MIBSPI1NCS2_PINMMR 3 +#define PINMUX_MIBSPI1NCS2_SHIFT 0 +#define PINMUX_MIBSPI1NCS2_VALUE 1 +#define PINMUX_MIBSPI1NCS2_PIN {PINMUX_MIBSPI1NCS2_PINMMR, PINMUX_MIBSPI1NCS2_SHIFT, PINMUX_MIBSPI1NCS2_VALUE} + +#define PINMUX_N2HET20_PINMMR 3 +#define PINMUX_N2HET20_SHIFT 0 +#define PINMUX_N2HET20_VALUE 2 +#define PINMUX_N2HET20_PIN {PINMUX_N2HET20_PINMMR, PINMUX_N2HET20_SHIFT, PINMUX_N2HET20_VALUE} + +#define PINMUX_N2HET19_PINMMR 3 +#define PINMUX_N2HET19_SHIFT 0 +#define PINMUX_N2HET19_VALUE 4 +#define PINMUX_N2HET19_PIN {PINMUX_N2HET19_PINMMR, PINMUX_N2HET19_SHIFT, PINMUX_N2HET19_VALUE} + +#define PINMUX_SPI3CLK_PINMMR 3 +#define PINMUX_SPI3CLK_SHIFT 16 +#define PINMUX_SPI3CLK_VALUE 1 +#define PINMUX_SPI3CLK_PIN {PINMUX_SPI3CLK_PINMMR, PINMUX_SPI3CLK_SHIFT, PINMUX_N2HET20_VALUE} + +#define PINMUX_EQEPA_PINMMR 3 +#define PINMUX_EQEPA_SHIFT 16 +#define PINMUX_EQEPA_VALUE 2 +#define PINMUX_EQEPA_PIN {PINMUX_EQEPA_PINMMR, PINMUX_EQEPA_SHIFT, PINMUX_EQEPA_VALUE} + +#define PINMUX_SPI3NENA_PINMMR 3 +#define PINMUX_SPI3NENA_SHIFT 24 +#define PINMUX_SPI3NENA_VALUE 1 +#define PINMUX_SPI3NENA_PIN {PINMUX_SPI3NENA_PINMMR, PINMUX_SPI3NENA_SHIFT, PINMUX_SPI3NENA_VALUE} + +#define PINMUX_EQEPB_PINMMR 3 +#define PINMUX_EQEPB_SHIFT 24 +#define PINMUX_EQEPB_VALUE 2 +#define PINMUX_EQEPB_PIN {PINMUX_EQEPB_PINMMR, PINMUX_EQEPB_SHIFT, PINMUX_EQEPB_VALUE} + +#define PINMUX_SPI3NCS0_PINMMR 4 +#define PINMUX_SPI3NCS0_SHIFT 0 +#define PINMUX_SPI3NCS0_VALUE 1 +#define PINMUX_SPI3NCS0_PIN {PINMUX_SPI3NCS0_PINMMR, PINMUX_SPI3NCS0_SHIFT, PINMUX_SPI3NCS0_VALUE} + +#define PINMUX_EQEPI_PINMMR 4 +#define PINMUX_EQEPI_SHIFT 0 +#define PINMUX_EQEPI_VALUE 2 +#define PINMUX_EQEPI_PIN {PINMUX_EQEPI_PINMMR, PINMUX_EQEPI_SHIFT, PINMUX_EQEPI_VALUE} + +#define PINMUX_MIBSPI1NCS3_PINMMR 4 +#define PINMUX_MIBSPI1NCS3_SHIFT 8 +#define PINMUX_MIBSPI1NCS3_VALUE 1 +#define PINMUX_MIBSPI1NCS3_PIN {PINMUX_MIBSPI1NCS3_PINMMR, PINMUX_MIBSPI1NCS3_SHIFT, PINMUX_MIBSPI1NCS3_VALUE} + +#define PINMUX_N2HET26_PINMMR 4 +#define PINMUX_N2HET26_SHIFT 8 +#define PINMUX_N2HET26_VALUE 2 +#define PINMUX_N2HET26_PIN {PINMUX_N2HET26_PINMMR, PINMUX_N2HET26_SHIFT, PINMUX_N2HET26_VALUE} + +#define PINMUX_ADEVT_PINMMR 4 +#define PINMUX_ADEVT_SHIFT 16 +#define PINMUX_ADEVT_VALUE 1 +#define PINMUX_ADEVT_PIN {PINMUX_ADEVT_PINMMR, PINMUX_ADEVT_SHIFT, PINMUX_ADEVT_VALUE} + +#define PINMUX_N2HET28_PINMMR 4 +#define PINMUX_N2HET28_SHIFT 16 +#define PINMUX_N2HET28_VALUE 2 +#define PINMUX_N2HET28_PIN {PINMUX_N2HET28_PINMMR, PINMUX_N2HET28_SHIFT, PINMUX_N2HET28_VALUE} + +#define PINMUX_MIBSPI1NENA_PINMMR 5 +#define PINMUX_MIBSPI1NENA_SHIFT 8 +#define PINMUX_MIBSPI1NENA_VALUE 1 +#define PINMUX_MIBSPI1NENA_PIN {PINMUX_MIBSPI1NENA_PINMMR, PINMUX_MIBSPI1NENA_SHIFT, PINMUX_MIBSPI1NENA_VALUE} + +#define PINMUX_N2HET23_PINMMR 5 +#define PINMUX_N2HET23_SHIFT 8 +#define PINMUX_N2HET23_VALUE 2 +#define PINMUX_N2HET23_PIN {PINMUX_N2HET23_PINMMR, PINMUX_N2HET23_SHIFT, PINMUX_N2HET23_VALUE} + +#define PINMUX_N2HET30_PINMMR 5 +#define PINMUX_N2HET30_SHIFT 8 +#define PINMUX_N2HET30_VALUE 4 +#define PINMUX_N2HET30_PIN {PINMUX_N2HET30_PINMMR, PINMUX_N2HET30_SHIFT, PINMUX_N2HET30_VALUE} + +#define PINMUX_MIBSPI1NCS1_PINMMR 6 +#define PINMUX_MIBSPI1NCS1_SHIFT 8 +#define PINMUX_MIBSPI1NCS1_VALUE 1 +#define PINMUX_MIBSPI1NCS1_PIN {PINMUX_MIBSPI1NCS1_PINMMR, PINMUX_MIBSPI1NCS1_SHIFT, PINMUX_MIBSPI1NCS1_VALUE} + +#define PINMUX_EQEPS_PINMMR 6 +#define PINMUX_EQEPS_SHIFT 8 +#define PINMUX_EQEPS_VALUE 2 +#define PINMUX_EQEPS_PIN {PINMUX_EQEPS_PINMMR, PINMUX_EQEPS_SHIFT, PINMUX_EQEPS_VALUE} + +#define PINMUX_N2HET17_PINMMR 6 +#define PINMUX_N2HET17_SHIFT 8 +#define PINMUX_N2HET17_VALUE 4 +#define PINMUX_N2HET17_PIN {PINMUX_N2HET17_PINMMR, PINMUX_N2HET17_SHIFT, PINMUX_N2HET17_VALUE} + +#endif /* __ARCH_ARM_SRC_TMS570_CHIP_TMS570LS04X03X_PINMUX_H */ diff --git a/arch/arm/src/tms570/tms570_boot.c b/arch/arm/src/tms570/tms570_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..66c92862f55d16a479219c50938fbefe7fb2833f --- /dev/null +++ b/arch/arm/src/tms570/tms570_boot.c @@ -0,0 +1,482 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_boot.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This is primarily original code. However, some logic in this file was + * inspired/leveraged from TI's Project0 which has a compatible BSD license + * and credit should be given in any case: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "arm.h" +#include "cache.h" +#include "fpu.h" +#include "sctlr.h" +#include "up_internal.h" +#include "up_arch.h" + +#include + +#include "chip/tms570_sys.h" +#include "chip/tms570_esm.h" +#include "chip/tms570_pbist.h" +#include "tms570_clockconfig.h" +#include "tms570_selftest.h" +#include "tms570_gio.h" +#include "tms570_esm.h" +#include "tms570_boot.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_ARMV7R_MEMINIT +# error CONFIG_ARMV7R_MEMINIT is required by this architecture. +#endif + +#ifndef CONFIG_ARCH_LOWVECTORS +# error CONFIG_ARCH_LOWVECTORS is required by this architecture. +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_event_export + * + * Description: + * Enable CPU Event Export by setting the X bit in the PMCR. In general, + * this bit enables the exporting of events to another debug device, such + * as a trace macrocell, over an event bus. + * + * For the TMS570, this allows the CPU to signal any single-bit or double + * -bit errors detected by its ECC logic for accesses to program flash or + * data RAM. + * + ****************************************************************************/ + +static inline void tms570_event_export(void) +{ + uint32_t pmcr = cp15_rdpmcr(); + pmcr |= PCMR_X; + cp15_wrpmcr(pmcr); +} + +/**************************************************************************** + * Name: tms570_check_reset + * + * Description: + * Assert if we go here through any mechanism other than a power-on reset. + * + ****************************************************************************/ + +static inline void tms570_check_reset(void) +{ +#ifdef CONFIG_DEBUG + uint32_t regval; + + /* Read from the system exception status register to identify the cause of + * the CPU reset. + */ + + regval = getreg32(TMS570_SYS_ESR); + + /* Clear all reset status flags on normal reset */ + + regval = getreg32(TMS570_SYS_ESR); + putreg32(SYS_ESR_RSTALL, TMS570_SYS_ESR); + + /* Check for abnormal reset causes: Oscillator failures or watchdog + * timers. Ignore normal reset causes: External reset, software reset, CPU + * reset, power-on reset + * + * REVISIT: The reset cause is not used in the current design. But if you + * need to know the cause of the reset, here is where you would want to + * do that. + */ + +#if 0 + ASSERT((regval & SYS_ESR_FAILALL) == 0); +#else + UNUSED(regval); +#endif + +#else + /* Clear all reset status flags */ + + putreg32(SYS_ESR_RSTALL, TMS570_SYS_ESR); +#endif +} + +/**************************************************************************** + * Name: tms570_enable_ramecc + * + * Description: + * This function enables the CPU's ECC logic for accesses to B0TCM and + * B1TCM. + * + ****************************************************************************/ + +static inline void tms570_enable_ramecc(void) +{ + uint32_t actlr = cp15_rdactlr(); + actlr |= 0x0c000000; + cp15_wractlr(actlr); +} + +/**************************************************************************** + * Name: tms570_memory_initialize + * + * Description: + * Perform memroy initialization of selected RAMs + * + * This function uses the system module's hardware for auto-initialization + * of memories and their associated protection schemes. + * + ****************************************************************************/ + +static void tms570_memory_initialize(uint32_t ramset) +{ + /* Enable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_ENABLE, TMS570_SYS_MINITGCR); + + /* Enable Memory Hardware Initialization for selected RAM's */ + + putreg32(ramset, TMS570_SYS_MSIENA); + + /* Wait until Memory Hardware Initialization complete */ + + while((getreg32(TMS570_SYS_MSTCGSTAT) & SYS_MSTCGSTAT_MINIDONE) == 0); + + /* Disable Memory Hardware Initialization */ + + putreg32(SYS_MINITGCR_DISABLE, TMS570_SYS_MINITGCR); +} + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Re-initialize the stack and frame pointers and branch to OS start. + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + naked_function noreturn_function; + +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tldr ip, =g_idle_topstack\n" /* IP=address of g_idle_topstack */ + "\tldr sp, [ip]\n" /* Reset the stack pointer */ + "\tmov fp, #0\n" /* Reset the frame pointer */ + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} + +#else +static void go_os_start(void) naked_function noreturn_function; + +static void go_os_start(void) +{ + /* Reset the stack/frame pointer and jump to os_start(). */ + + __asm__ __volatile__ + ( + "\tldr ip, =g_idle_topstack\n" /* IP=address of g_idle_topstack */ + "\tldr sp, [ip]\n" /* Reset the stack pointer */ + "\tmov fp, #0\n" /* Reset the frame pointer */ + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + * Boot Sequence + * + * 1. The __start entry point in armv7-r/arm_head.S is invoked upon power- + * on reset. + * 2. __start prepares CPU for code execution. + * 3a. If CONFIG_ARMV7R_MEMINIT is not defined, then __start will prepare + * memory resources by calling arm_data_initialize() and will then + * branch this function. + * 3b. Otherwise, this function will be called without having initialized + * memory resources! We need to be very careful in this case. Here, + * this function will call tms570_boardinitialize() which, among other + * things, must initialize SDRAM memory. After initializatino of the + * memories, this function will call arm_data_initialize() to + * initialize the memory resources + * 4. This function will then branch to os_start() to start the operating + * system. + * + ****************************************************************************/ + +void arm_boot(void) +{ + /* Enable CPU Event Export. + * + * This allows the CPU to signal any single-bit or double-bit errors + * detected by its ECC logic for accesses to program flash or data RAM. + */ + + tms570_event_export(); + + /* Verify that we got here via a power-up reset */ + + tms570_check_reset(); + + /* Check if there were ESM group3 errors during power-up. + * + * These could occur during eFuse auto-load or during reads from flash OTP + * during power-up. Device operation is not reliable and not recommended + * in this case. + * + * An ESM group3 error only drives the nERROR pin low. An external circuit + * that monitors the nERROR pin must take the appropriate action to ensure + * that the system is placed in a safe state, as determined by the + * application. + */ + + ASSERT(getreg32(TMS570_ESM_SR3) == 0); + + /* Initialize clocking to settings provided by board-specific logic */ + + tms570_clockconfig(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Run a diagnostic check on the memory self-test controller. + * + * REVISIT: This is a destructive test. It will most likely clobber the + * current stack content and result in a failure if this function were to + * attempt to return. + */ + + tms570_memtest_selftest(); + + /* Run the memory selftest on CPU RAM. */ + + tms570_memtest_start(PBIST_RINFOL_ESRAM1_RAM); + ASSERT(tms570_memtest_complete() == OK); +#endif /* CONFIG_TMS570_SELFTEST */ + + /* Initialize CPU RAM. */ + + tms570_memory_initialize(SYS_MSIENA_RAM); + + /* Enable ECC checking for TCRAM accesses. */ + + tms570_enable_ramecc(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Perform PBIST on all dual-port memories */ + + tms570_memtest_start(PBIST_RINFOL_VIM_RAM +#ifdef CONFIG_TMS570_DCAN1 + | PBIST_RINFOL_DCAN1_RAM +#endif +#ifdef CONFIG_TMS570_DCAN2 + | PBIST_RINFOL_DCAN2_RAM +#endif +#ifdef CONFIG_TMS570_MIBASPI1 + | PBIST_RINFOL_MIBSPI1_RAM +#endif +#ifdef CONFIG_TMS570_MIBASPI1 + | PBIST_RINFOL_MIBADC_RAM +#endif +#ifdef CONFIG_TMS570_N2HET + | PBIST_RINFOL_N2HET_RAM + | PBIST_RINFOL_HET_TU_RAM +#endif + ); + + /* Test the CPU ECC mechanism for RAM accesses. */ + + tms570_cpuecc_selftest(); + + /* Wait for the memory test to complete */ + + ASSERT(tms570_memtest_complete() == OK); +#endif /* CONFIG_TMS570_SELFTEST */ + +#ifdef CONFIG_TMS570_MIBASPI1 + /* Release the MibSPI1 modules from local reset. + * + * This will cause the MibSPI1 RAMs to be initialized along with the + * parity memory. + */ + + putreg32(MIBSPI_GCR0_RESET, TMS570_MIBSPI_GCR0); +#endif + + /* Initialize all on-chip SRAMs except for MibSPIx RAMs. + * + * The MibSPIx modules have their own auto-initialization mechanism which + * is triggered as soon as the modules are brought out of local reset. + * + * The system module auto-init will hang on the MibSPI RAM if the module + * is still in local reset. + */ + + tms570_memory_initialize(SYS_MSIENA_VIM_RAM +#ifdef CONFIG_TMS570_N2HET + | SYS_MSIENA_N2HET_RAM | SYS_MSIENA_HTU_RAM +#endif +#ifdef CONFIG_TMS570_DCAN1 + | SYS_MSIENA_DCAN1_RAM +#endif +#ifdef CONFIG_TMS570_DCAN2 + | SYS_MSIENA_DCAN2_RAM +#endif +#ifdef CONFIG_TMS570_MIBADC + | SYS_MSIENA_MIBADC_RAM +#endif + ); + +#ifdef CONFIG_TMS570_SELFTEST + /* Test the parity protection mechanism for peripheral RAMs */ +#warning Missing logic +#endif + +#ifdef CONFIG_TMS570_MIBASPI1 + /* Wait for MibSPI1 RAM to complete initialization */ +#warning Missing logic +#endif + + /* Configure system response to error conditions */ + + tms570_esm_initialize(); + +#ifdef CONFIG_ARCH_FPU + /* Initialize the FPU */ + + arm_fpuconfig(); +#endif + +#ifdef CONFIG_ARMV7R_MEMINIT + /* Initialize the .bss and .data sections as well as RAM functions + * now after RAM has been initialized. + * + * NOTE that if SDRAM were supported, this call might have to be + * performed after returning from tms570_board_initialize() + */ + + arm_data_initialize(); +#endif + + /* Initialize GIO for use by board initialization logic */ + + tms570_gio_initialize(); + + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (GIOs, LEDs, etc). + * + * NOTE: We must use caution prior to this point to make sure that + * the logic does not access any global variables that might lie + * in SDRAM. + */ + + tms570_board_initialize(); + + /* Perform common, low-level chip initialization (might do nothing) */ + + tms570_lowsetup(); + + /* Then start NuttX */ + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Branch to os_start(), resetting the stack and frame pointers. */ + + go_os_start(); +#endif +} diff --git a/arch/arm/src/tms570/tms570_boot.h b/arch/arm/src/tms570/tms570_boot.h new file mode 100644 index 0000000000000000000000000000000000000000..ae3611144eebb2fe68b1cf6939495210352b92d8 --- /dev/null +++ b/arch/arm/src/tms570/tms570_boot.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/arm/src/tms570/tms570_boot.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_BOOT_H +#define __ARCH_ARM_SRC_TMS570_TMS570_BOOT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the linker + * script. _ebss lies at the end of the BSS region. The idle task stack starts at + * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is + * the thread that the system boots on and, eventually, becomes the IDLE, do + * nothing task that runs only when there is nothing else to run. The heap + * continues from there until the end of memory. g_idle_topstack is a read-only + * variable the provides this computed address. + */ + +EXTERN const uintptr_t g_idle_topstack; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: tms570_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console SCI. This SCI done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void tms570_lowsetup(void); + +/************************************************************************************ + * Name: tms570_boardinitialize + * + * Description: + * All TMS570 architectures must provide the following entry point. This function + * is called near the beginning of _start. This function is called after clocking + * has been configured but before caches have been enabled and before any devices + * have been initialized. .data/.bss memory may or may not have been initialized + * (see the "special precautions" below). + * + * This function must perform low level initialization including + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (GIOs, LEDs, etc). + * - Setup of the console SCI. This SCI done early so that the serial console + * is available for debugging very early in the boot sequence. + * + * Special precautions must be taken if .data/.bss lie in SRAM. in that case, + * the boot logic cannot initialize .data or .bss. The function must then: + * + * - Take precautions to assume that logic does not access any global data that + * might lie in SDRAM. + * - Call the function arm_data_initialize() as soon as SDRAM has been + * properly configured for use. + * + ************************************************************************************/ + +void tms570_board_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_BOOT_H */ diff --git a/arch/arm/src/tms570/tms570_clockconfig.c b/arch/arm/src/tms570/tms570_clockconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..2e8b76a480f2d7ed1560c88aa147a1082ca568c1 --- /dev/null +++ b/arch/arm/src/tms570/tms570_clockconfig.c @@ -0,0 +1,592 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_clockconfig.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some logic in this file was inspired/leveraged from TI's Project0 which + * has a compatible BSD license: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_arch.h" + +#include "chip/tms570_sys.h" +#include "chip/tms570_pcr.h" +#include "chip/tms570_flash.h" +#include "chip/tms570_iomm.h" +#include "chip/tms570_pinmux.h" + +#include "tms570_selftest.h" +#include "tms570_clockconfig.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef BOARD_VCLK_DIVIDER +# error BOARD_VCLK_DIVIDER is not defined +#endif + +#if BOARD_VCLK_DIVIDER == 1 +# define SYS_CLKCNTL_VCLKR SYS_CLKCNTL_VCLKR_DIV1 +#elif BOARD_VCLK_DIVIDER == 2 +# define SYS_CLKCNTL_VCLKR SYS_CLKCNTL_VCLKR_DIV2 +#else +# error Invalid value for BOARD_VCLK_DIVIDER +#endif + +#ifndef BOARD_VCLK2_DIVIDER +# error BOARD_VCLK2_DIVIDER is not defined +#endif + +#if BOARD_VCLK2_DIVIDER == 1 +# define SYS_CLKCNTL_VCLKR2 SYS_CLKCNTL_VCLKR2_DIV1 +#elif BOARD_VCLK2_DIVIDER == 2 +# define SYS_CLKCNTL_VCLKR2 SYS_CLKCNTL_VCLKR_DIV2 +#else +# error Invalid value for SYS_CLKCNTL_VCLKR2_DIV2 +#endif + +#ifndef BOARD_RTICLK_DIVIDER +# error BOARD_RTICLK_DIVIDER is not defined +#endif + +#if BOARD_RTICLK_DIVIDER == 1 +# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV1 +#elif BOARD_RTICLK_DIVIDER == 2 +# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV2 +#elif BOARD_RTICLK_DIVIDER == 4 +# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV4 +#elif BOARD_RTICLK_DIVIDER == 78 +# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV8 +#else +# error Invalid value for SYS_CLKCNTL_VCLKR2_DIV2 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct tms570_pinmux_s g_pinmux_table[] = +{ + BOARD_PINMUX_INITIALIZER +}; + +#define NPINMUX (sizeof(g_pinmux_table) / sizeof(struct tms570_pinmux_s)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_pll_setup + * + * Description: + * Configure PLL control registers. The PLL takes (127 + 1024 NR) + * oscillator cycles to acquire lock. This initialization sequence + * performs all the actions that are not required to be done at full + * application speed while the PLL locks. + * + ****************************************************************************/ + +static void tms570_pll_setup(void) +{ + uint32_t regval; + + /* Configure PLL control registers */ + + /* Setup pll control register 1 + * + * REFCLKDIV controls input clock divider: + * + * NR = REFCLKDIV+1 + * Fintclk = Fclkin / NR + * + * PLLMUL controls multipler on divided input clock (Fintclk): + * + * Non-modulated: + * NF = (PLLMUL + 256) / 256 + * Modulated: + * NF = (PLLMUL + MULMOD + 256) / 256 + * + * Foutputclk = Fintclk x NF (150MHz - 550MHz) + * + * ODPLL controls internal PLL output divider: + * + * OD = ODPLL+1 + * Fpostodclk = Foutputclock / OD + * + * Final divisor, R, controls PLL output: + * + * R = PLLDIV + 1 + * Fpllclock = Fpostodclk / R + * + * Or: + * + * Fpllclock = = (Fclkin / NR) x NF / OD / R + * + * For example, if the clock source is a 16MHz crystal, then + * + * Fclkin = 16,000,000 + * NR = 6 (REFCLKDIV=5) + * NF = 120 (PLLMUL = 119 * 256) + * OD = 1 (ODPLL = 0) + * R = 32 (PLLDIV=31) + * + * Then: + * + * Fintclk = 16 MHz / 6 = 2.667 MHz + * Foutputclock = 2.667 MHz * 120 = 320 MHz + * Fpostodclock = 320 MHz / 2 = 160 MHz + * Fpllclock = 160 MHz / 2 = 80 MHz + * + * NOTE: That R is temporary set to the maximum (32) here. + */ + + regval = SYS_PLLCTL1_PLLMUL((BOARD_PLL_NF - 1) << 8) | + SYS_PLLCTL1_REFCLKDIV(BOARD_PLL_NR - 1) | + SYS_PLLCTL1_PLLDIV_MAX | + SYS_PLLCTL1_MASKSLIP_DISABLE; + putreg32(regval, TMS570_SYS_PLLCTL1); + + /* Setup pll control register 2 */ + + regval = SYS_PLLCTL2_SPRAMOUNT(61) | + SYS_PLLCTL2_ODPLL(BOARD_PLL_OD - 1) | + SYS_PLLCTL2_MULMOD(7) | + SYS_PLLCTL2_SPRRATE(255); + putreg32(regval, TMS570_SYS_PLLCTL2); + + /* Enable PLL(s) to start up or Lock. + * + * On wakeup, only clock sources 0, 4, and 5 are enabled: Oscillator, Low + * and high Frequency LPO. Clear bit 1 to enable the PLL. Only the + * external clock remains disabled. + */ + + regval = SYS_CSDIS_CLKSRC_EXTCLKIN; + putreg32(regval, TMS570_SYS_CSDIS); +} + +/**************************************************************************** + * Name: tms570_peripheral_initialize + * + * Description: + * Release peripherals from reset and enable clocks to all peripherals. + * + ****************************************************************************/ + +static void tms570_peripheral_initialize(void) +{ + uint32_t regval; + uint32_t clkcntl; + + /* Disable Peripherals by clearing the PENA bit in the CLKCNTRL register + * before peripheral powerup + */ + + clkcntl = getreg32(TMS570_SYS_CLKCNTL); + clkcntl &= ~SYS_CLKCNTL_PENA; + putreg32(clkcntl, TMS570_SYS_CLKCNTL); + + /* Release peripherals from reset and enable clocks to all peripherals. + * Power-up all peripherals by clearing the power down bit for each + * quadrant of each peripheral. + * + * REVISIT: Should we only enable peripherals that are configured? + */ + + regval = PCR_PSPWERDWN0_PS0_QALL | PCR_PSPWERDWN0_PS1_QALL | + PCR_PSPWERDWN0_PS2_QALL | PCR_PSPWERDWN0_PS3_QALL | + PCR_PSPWERDWN0_PS4_QALL | PCR_PSPWERDWN0_PS5_QALL | + PCR_PSPWERDWN0_PS6_QALL | PCR_PSPWERDWN0_PS7_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR0); + + regval = PCR_PSPWERDWN1_PS8_QALL | PCR_PSPWERDWN1_PS9_QALL | + PCR_PSPWERDWN1_PS10_QALL | PCR_PSPWERDWN1_PS11_QALL | + PCR_PSPWERDWN1_PS12_QALL | PCR_PSPWERDWN1_PS13_QALL | + PCR_PSPWERDWN1_PS14_QALL | PCR_PSPWERDWN1_PS15_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR1); + + regval = PCR_PSPWERDWN2_PS16_QALL | PCR_PSPWERDWN2_PS17_QALL | + PCR_PSPWERDWN2_PS18_QALL | PCR_PSPWERDWN2_PS19_QALL | + PCR_PSPWERDWN2_PS20_QALL | PCR_PSPWERDWN2_PS21_QALL | + PCR_PSPWERDWN2_PS22_QALL | PCR_PSPWERDWN2_PS23_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR2); + + regval = PCR_PSPWERDWN3_PS24_QALL | PCR_PSPWERDWN3_PS25_QALL | + PCR_PSPWERDWN3_PS26_QALL | PCR_PSPWERDWN3_PS27_QALL | + PCR_PSPWERDWN3_PS28_QALL | PCR_PSPWERDWN3_PS29_QALL | + PCR_PSPWERDWN3_PS30_QALL | PCR_PSPWERDWN3_PS31_QALL; + putreg32(regval, TMS570_PCR_PSPWRDWNCLR3); + + /* Enable Peripherals */ + + clkcntl |= SYS_CLKCNTL_PENA; + putreg32(clkcntl, TMS570_SYS_CLKCNTL); +} + +/**************************************************************************** + * Name: tms570_pin_multiplex + * + * Description: + * Configure the field for a single pin in a PINMMR register + * + ****************************************************************************/ + +static void tms570_pin_multiplex(FAR const struct tms570_pinmux_s *pinmux) +{ + uintptr_t regaddr; + uint32_t regval; + + regaddr = TMS570_IOMM_PINMMR(pinmux->mmrndx); + regval = getreg32(regaddr); + regval &= ~(0xff << pinmux->shift); + regval |= ((uint32_t)(pinmux->value) << pinmux->shift); + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: tms570_io_multiplex + * + * Description: + * Configure the all pins in the board-provided pinmux table. + * + ****************************************************************************/ + +static void tms570_io_multiplex(void) +{ + int i; + + /* Enable access to pin multiplexing registers */ + + putreg32(IOMM_KICK0_UNLOCK, TMS570_IOMM_KICK0); + putreg32(IOMM_KICK1_UNLOCK, TMS570_IOMM_KICK1); + + /* Configure each pin selected by the board-specific logic */ + + for (i = 0; i < NPINMUX; i++) + { + tms570_pin_multiplex(&g_pinmux_table[i]); + } + + /* Disable access to pin multiplexing registers */ + + putreg32(IOMM_KICK0_LOCK, TMS570_IOMM_KICK0); + putreg32(IOMM_KICK1_LOCK, TMS570_IOMM_KICK1); +} + +/**************************************************************************** + * Name: tms570_lpo_trim + * + * Description: + * Configure the LPO such that HF LPO is as close to 10MHz as possible. + * + ****************************************************************************/ + +static void tms570_lpo_trim(void) +{ + uint32_t regval; + uint32_t lotrim; + + /* The LPO trim value may be available in TI OTP */ + + lotrim = (getreg32(TMS570_TITCM_LPOTRIM) & TMS570_TITCM_LPOTRIM_MASK) << + TMS570_TITCM_LPOTRIM_SHIFT; + + /* Use if the LPO trim value TI OTP if programmed. Otherwise, use a + * default value. + */ + + if (lotrim != 0xffff) + { + regval = SYS_LPOMONCTL_BIASENABLE | lotrim; + } + else + { + regval = SYS_LPOMONCTL_BIASENABLE | + SYS_LPOMONCTL_HFTRIM_100p00 | + SYS_LPOMONCTL_60p86; + } + + putreg32(regval, TMS570_SYS_LPOMONCTL); +} + +/**************************************************************************** + * Name: tms570_flash_setup + * + * Description: + * Set up flash address and data wait states based on the target CPU clock + * frequency The number of address and data wait states for the target CPU + * clock frequency are specified in the specific part's datasheet. + * + ****************************************************************************/ + +static void tms570_flash_setup(void) +{ + uint32_t regval; + + /* Setup flash read mode, address wait states and data wait states + * + * ENPIPE=1, Bit 0, Enable pipeline mode. + * ASWSTEN=0/1, Bit 1, Address Setup Wait State is enabled/disabled. + * RWAIT=BOARD_RWAIT, Bits 8-11, Wait states added to FLASH read access + */ + + regval = FLASH_FRDCNTL_ENPIPE | FLASH_FRDCNTL_RWAIT(BOARD_RWAIT); +#if defined(BOARD_ASWAIT) && BOARD_ASWAIT > 0 + regval |= FLASH_FRDCNTL_ASWSTEN; +#endif + putreg32(regval, TMS570_FLASH_FRDCNTL); + + /* Setup flash access wait states for bank 7 + * + * AUTOSTART_GRACE=2, Bits 0-7, Auto-suspend Startup Grace Period + * AUTOSUSPEN=0, Bit 8, Auto suspend is disabled. + * EWAIT=4, Bits 16-19, EEPROM wait states + */ + + putreg32(FLASH_FSMWRENA_ENABLE, TMS570_FLASH_FSMWRENA); + regval = FLASH_EEPROMCFG_GRACE(2) | FLASH_EEPROMCFG_EWAIT(BOARD_EWAIT); + putreg32(regval, TMS570_FLASH_EEPROMCFG); + putreg32(FLASH_FSMWRENA_DISABLE, TMS570_FLASH_FSMWRENA); + + /* Setup flash bank power modes */ + + regval = FLASH_FBFALLBACK_BANKPWR0_ACTIV | + FLASH_FBFALLBACK_BANKPWR1_SLEEP | + FLASH_FBFALLBACK_BANKPWR7_ACTIV; + putreg32(regval, TMS570_FLASH_FBFALLBACK); +} + +/**************************************************************************** + * Name: tms570_clocksrc_configure + * + * Description: + * Finalize PLL configuration, enable and configure clocks sources. + * + ****************************************************************************/ + +static void tms570_clocksrc_configure(void) +{ + uint32_t regval; + uint32_t csvstat; + uint32_t csdis; + + /* Disable / Enable clock domains. Writing a '1' to the CDDIS register turns + * the clock off. + * + * GCLK Bit 0 On + * HCLK/VCLK_sys Bit 1 On + * VCLK_periph Bit 2 On + * VCLK2 Bit 3 On + * VCLKA1 Bit 4 On + * RTICLK1 Bit 6 On + * TCLK_EQEP Bit 9 On + */ + + putreg32(0, TMS570_SYS_CDDIS); + + /* Work Around for Errata SYS#46: Errata Description: Clock Source + * Switching Not Qualified with Clock Source Enable And Clock Source Valid + * Workaround: Always check the CSDIS register to make sure the clock source + * is turned on and check the CSVSTAT register to make sure the clock source + * is valid. Then write to GHVSRC to switch the clock. + */ + + do + { + /* Get the set of valid clocks */ + + csvstat = getreg32(TMS570_SYS_CSVSTAT) & SYS_CSVSTAT_CLKSRVALL; + + /* Get the (inverted) state of each clock. Inverted so that '1' means + * ON not OFF. + */ + + csdis = (getreg32(TMS570_SYS_CSDIS) ^ SYS_CSDIS_CLKSROFFALL) & + SYS_CSDIS_CLKSROFFALL; + } + while ((csvstat & csdis) != csdis); + + + /* Now the PLLs are locked and the PLL outputs can be sped up. The R- + * divider was programmed to be 0xF. Now this divider is changed to + * programmed value + */ + + regval = getreg32(TMS570_SYS_PLLCTL1); + regval &= ~SYS_PLLCTL1_PLLDIV_MASK; + regval |= SYS_PLLCTL1_PLLDIV(BOARD_PLL_R - 1); + putreg32(regval, TMS570_SYS_PLLCTL1); + + /* Map device clock domains to desired sources and configure top-level + * dividers. All clock domains were working off the default clock sources + * until this point. + * + * Setup GCLK, HCLK and VCLK clock source for normal operation, power down + * mode and after wakeup + */ + + regval = SYS_GHVSRC_GHVSRC_PLL1 | SYS_GHVSRC_HVLPM_PLL1 | + SYS_GHVSRC_GHVWAKE_PLL1; + putreg32(regval, TMS570_SYS_GHVSRC); + + /* Setup synchronous peripheral clock dividers for VCLK1, VCLK2, VCLK3 */ + + regval = getreg32(TMS570_SYS_CLKCNTL); + regval &= ~(SYS_CLKCNTL_VCLKR2_MASK | SYS_CLKCNTL_VCLKR_MASK); + regval |= SYS_CLKCNTL_VCLKR2 | SYS_CLKCNTL_VCLKR; + putreg32(regval, TMS570_SYS_CLKCNTL); + + /* Setup RTICLK1 and RTICLK2 clocks */ + + regval = SYS_RCLKSRC_RTI1SRC_VCLK | SYS_RCLKSRC_RTI1DIV; + putreg32(regval, TMS570_SYS_RCLKSRC); + + /* Setup asynchronous peripheral clock sources for AVCLK1 */ + + putreg32(SYS_VCLKASRC_VCLKA1S_VCLK, TMS570_SYS_VCLKASRC); +} + +/**************************************************************************** + * Name: tms570_eclk_configure + * + * Description: + * Configure the External Clock (ECLK) pin. + * + ****************************************************************************/ + +static void tms570_eclk_configure(void) +{ + uint32_t regval; + + /* Configure ECLK pins + * + * PC1 0=ECLK is in GIO mode + * PC4 0=ECLK pin is driven to logic low + * PC2 1=ECLK pin is an output + * PC7 0=CLK pin is configured in push/pull mode + * PC8 0=ECLK pull enable is active + * PC9 1=ECLK pull up is selected, when pull up/pull down logic is enabled + */ + + putreg32(0, TMS570_SYS_PC1); + putreg32(0, TMS570_SYS_PC4); + putreg32(SYS_PC2_ECPCLKDIR, TMS570_SYS_PC2); + putreg32(0, TMS570_SYS_PC7); + putreg32(0, TMS570_SYS_PC8); + putreg32(SYS_PC9_ECPCLKPS, TMS570_SYS_PC9); + + /* Setup ECLK: + * + * ECPDIV=7 Bits 0-15, ECP divider value = 8 + * ECPINSEL=0 Bits 16-17, Select ECP input clock source is tied low + * ECPCOS=0 Bit 23, ECLK output is disabled in suspend mode + * ECPINSEL=0 Bit 24, VCLK is selected as the ECP clock source + */ + + regval = SYS_ECPCNTL_ECPDIV(8-1) | SYS_ECPCNTL_ECPINSEL_LOW; + putreg32(regval, TMS570_SYS_ECPCNTL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_clockconfig + * + * Description: + * Called to initialize TMS570 clocking. This does whatever setup is + * needed to put the SoC in a usable state. This includes, but is not + * limited to, the initialization of clocking using the settings in the + * board.h header file. + * + ****************************************************************************/ + +void tms570_clockconfig(void) +{ + /* Configure PLL control registers and enable PLLs. */ + + tms570_pll_setup(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Run eFuse controller start-up checks and start eFuse controller ECC + * self-test.*/ + + tms570_efc_selftest_start(); +#endif /* CONFIG_TMS570_SELFTEST */ + + /* Enable clocks to peripherals and release peripheral reset */ + + tms570_peripheral_initialize(); + + /* Configure device-level multiplexing and I/O multiplexing */ + + tms570_io_multiplex(); + +#ifdef CONFIG_TMS570_SELFTEST + /* Wait for eFuse controller self-test to complete and check results */ + + ASSERT(tms570_efc_selftest_complete() == 0); +#endif + + /* Set up flash address and data wait states. */ + + tms570_flash_setup(); + + /* Configure the LPO such that HF LPO is as close to 10MHz as possible */ + + tms570_lpo_trim(); + + /* Finalize PLL configuration, enable and configure clocks sources. */ + + tms570_clocksrc_configure(); + + /* Configure ECLK */ + + tms570_eclk_configure(); +} diff --git a/arch/arm/src/tms570/tms570_clockconfig.h b/arch/arm/src/tms570/tms570_clockconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..40255154bdf1977f9f64c214026627ac502b35be --- /dev/null +++ b/arch/arm/src/tms570/tms570_clockconfig.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_clockconfig.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_TMS570_TMS570_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_clockconfig + * + * Description: + * Called to initialize TMS570 clocking. This does whatever setup is needed to + * put the SoC in a usable state. This includes, but is not limited to, the + * initialization of clocking using the settings in the board.h header file. + * + ****************************************************************************/ + +void tms570_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_CLOCKCONFIG_H */ diff --git a/arch/arm/src/tms570/tms570_esm.c b/arch/arm/src/tms570/tms570_esm.c new file mode 100644 index 0000000000000000000000000000000000000000..a3259e4050f0c4e81a35ee641d85d714298d1c1c --- /dev/null +++ b/arch/arm/src/tms570/tms570_esm.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_esm.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from the TI "Project0" sample code which has a compatible 3- + * clause BSD license: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Texas Instruments Incorporated, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/tms570_esm.h" +#include "tms570_esm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_esm_initialize + * + * Description: + * Initialize the ESM. + * + ****************************************************************************/ + +int tms570_esm_initialize(void) +{ + uint32_t regval; + + /* Disable error pin channels */ + + putreg32(0xffffffff, TMS570_ESM_DEPAPR1); + putreg32(0xffffffff, TMS570_ESM_IEPCR4); + + /* Disable interrupts */ + + putreg32(0xffffffff, TMS570_ESM_IECR1); + putreg32(0xffffffff, TMS570_ESM_IECR4); + + /* Clear error status flags */ + + putreg32(0xffffffff, TMS570_ESM_SR1); + putreg32(0xffffffff, TMS570_ESM_SR2); + putreg32(0xffffffff, TMS570_ESM_SSR2); + putreg32(0xffffffff, TMS570_ESM_SR3); + putreg32(0xffffffff, TMS570_ESM_SR4); + putreg32(0xffffffff, TMS570_ESM_SR5); + putreg32(0xffffffff, TMS570_ESM_SSR5); + putreg32(0xffffffff, TMS570_ESM_SR6); + + /* Setup LPC preload */ + + putreg32(16384 - 1, TMS570_ESM_LTCPR); + + /* Reset error pin */ + + regval = getreg32(TMS570_ESM_EPSR); + if (regval == 0) + { + putreg32(5, TMS570_ESM_EKR); + } + else + { + putreg32(0, TMS570_ESM_EKR); + } + + /* Clear interrupt level. All channels set to low level interrupt. */ + + putreg32(0xffffffff, TMS570_ESM_ILCR1); + putreg32(0xffffffff, TMS570_ESM_ILCR4); + + /* Set interrupt level (Writing zero does nothing) */ + + putreg32(0, TMS570_ESM_ILSR1); + putreg32(0, TMS570_ESM_ILSR4); + + /* Enable error pin channels */ + + putreg32(0, TMS570_ESM_EEPAPR1); + putreg32(0, TMS570_ESM_IEPSR4); + + /* Enable interrupts */ + + putreg32(0, TMS570_ESM_IESR1); + putreg32(0, TMS570_ESM_IESR4); + return OK; +} + +/**************************************************************************** + * Name: tms570_esm_interrupt + * + * Description: + * ESM interrupt handler + * + ****************************************************************************/ + +int tms570_esm_interrupt(int irq, void *context) +{ + /* Save the saved processor context in CURRENT_REGS where it can be accessed + * for register dumps and possibly context switching. + */ + + CURRENT_REGS = (uint32_t *)context; + + /* Crash -- possibly showing diagnostic debug information. */ + + lldbg("ESM Interrupt. PC: %08x\n", CURRENT_REGS[REG_PC]); + PANIC(); + return OK; /* To keep the compiler happy */ +} diff --git a/arch/arm/src/tms570/tms570_esm.h b/arch/arm/src/tms570/tms570_esm.h new file mode 100644 index 0000000000000000000000000000000000000000..7222cc17fedd56715dc3296942bd09ea13c747de --- /dev/null +++ b/arch/arm/src/tms570/tms570_esm.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_esm.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_ESM_H +#define __ARCH_ARM_SRC_TMS570_TMS570_ESM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_esm_initialize + * + * Description: + * Initialize the ESM. + * + ****************************************************************************/ + +int tms570_esm_initialize(void); + +/**************************************************************************** + * Name: tms570_esm_interrupt + * + * Description: + * ESM interrupt handler + * + ****************************************************************************/ + +int tms570_esm_interrupt(int irq, void *context); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_ESM_H */ diff --git a/arch/arm/src/tms570/tms570_gio.c b/arch/arm/src/tms570/tms570_gio.c new file mode 100644 index 0000000000000000000000000000000000000000..159ee05e4faf863eb45c0a37b3219891316fc48b --- /dev/null +++ b/arch/arm/src/tms570/tms570_gio.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_gio.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/tms570_gio.h" +#include "tms570_gio.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +static const char g_portchar[TMS570_NPORTS] = +{ + 'A' +#if TMS570_NPORTS > 1 + , 'B' +#endif +#if TMS570_NPORTS > 2 + , 'C' +#endif +#if TMS570_NPORTS > 3 + , 'D' +#endif +#if TMS570_NPORTS > 4 + , 'E' +#endif +#if TMS570_NPORTS > 5 + , 'F' +#endif +#if TMS570_NPORTS > 6 + , 'G' +#endif +#if TMS570_NPORTS > 7 + , 'H' +#endif +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_gio_initialize + * + * Description: + * Take the GIO block out of reset and assure that it is ready for use. + * + ****************************************************************************/ + +int tms570_gio_initialize(void) +{ + /* Take the GIO block out of reset */ + + putreg32(GIO_GCR0_RESET, TMS570_GIO_GCR0); + + /* Disable all pin interrupts on the pin. Make sure they are all level 0. */ + + putreg32(0xffffffff, TMS570_GIO_ENACLR); + putreg32(0xffffffff, TMS570_GIO_LVLCLR); + return OK; +} + +/**************************************************************************** + * Name: tms570_configgio + * + * Description: + * Configure a GIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int tms570_configgio(gio_pinset_t cfgset) +{ + uint32_t port = tms570_gio_port(cfgset); + uintptr_t base = tms570_gio_base(cfgset); + uint32_t pin = tms570_gio_pin(cfgset); + uint32_t pinmask = tms570_gio_pinmask(cfgset); + uint32_t regval; + irqstate_t flags; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = enter_critical_section(); + + /* Force the pin to be an input for now */ + + regval = getreg32(base + TMS570_GIO_DIR_OFFSET); + regval &= ~pinmask; + putreg32(regval, base + TMS570_GIO_DIR_OFFSET); + + /* Disable interrupts on the pin. Make sure this is a level 0 pin. */ + + putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR); + putreg32(GIO_LVLCLR_PORT_PIN(port, pin), TMS570_GIO_LVLCLR); + + /* Setup settings common to both input and output pins */ + /* Enable/disable the pull-up/down as requested */ + + switch (cfgset & GIO_CFG_MASK) + { + case GIO_CFG_DEFAULT: /* Default, no attribute */ + default: + { + /* Disable pull functionality */ + + regval = getreg32(base + TMS570_GIO_PULDIS_OFFSET); + regval &= ~pinmask; + putreg32(regval, base + TMS570_GIO_PULDIS_OFFSET); + } + break; + + case GIO_CFG_PULLUP: /* Internal pull-up */ + { + /* Select pull-up */ + + regval = getreg32(base + TMS570_GIO_PSL_OFFSET); + regval |= pinmask; + putreg32(regval, base + TMS570_GIO_PSL_OFFSET); + + /* Enable pull functionality */ + + regval = getreg32(base + TMS570_GIO_PULDIS_OFFSET); + regval |= pinmask; + putreg32(regval, base + TMS570_GIO_PULDIS_OFFSET); + } + break; + + case GIO_CFG_PULLDOWN: /* Internal pull-down */ + { + /* Select pull-down */ + + regval = getreg32(base + TMS570_GIO_PSL_OFFSET); + regval |= pinmask; + putreg32(regval, base + TMS570_GIO_PSL_OFFSET); + + /* Enable pull functionality */ + + regval = getreg32(base + TMS570_GIO_DIR_OFFSET); + regval |= pinmask; + putreg32(regval, base + TMS570_GIO_DIR_OFFSET); + } + break; + } + + /* Then do unique operations for an output pin */ + + if ((cfgset & GIO_MODE_MASK) == GIO_OUTPUT) + { + /* Enable the open drain driver if requested */ + + regval = getreg32(base + TMS570_GIO_PDR_OFFSET); + if ((cfgset & GIO_OPENDRAIN) != 0) + { + regval |= pinmask; + } + else + { + regval &= ~pinmask; + } + + putreg32(regval, base + TMS570_GIO_PDR_OFFSET); + + /* Set default output value */ + + if ((cfgset & GIO_OUTPUT_SET) != 0) + { + putreg32(pinmask, base + TMS570_GIO_DSET_OFFSET); + } + else + { + putreg32(pinmask, base + TMS570_GIO_DCLR_OFFSET); + } + + /* Finally, configure the pin as an output */ + + regval = getreg32(base + TMS570_GIO_DIR_OFFSET); + regval |= pinmask; + putreg32(regval, base + TMS570_GIO_DIR_OFFSET); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: tms570_giowrite + * + * Description: + * Write one or zero to the selected GIO pin + * + ****************************************************************************/ + +void tms570_giowrite(gio_pinset_t pinset, bool value) +{ + uintptr_t base = tms570_gio_base(pinset); + uint32_t pinmask = tms570_gio_pinmask(pinset); + + if (value) + { + putreg32(pinmask, base + TMS570_GIO_DSET_OFFSET); + } + else + { + putreg32(pinmask, base + TMS570_GIO_DCLR_OFFSET); + } +} + +/**************************************************************************** + * Name: tms570_gioread + * + * Description: + * Read one or zero from the selected GIO pin + * + ****************************************************************************/ + +bool tms570_gioread(gio_pinset_t pinset) +{ + uintptr_t base = tms570_gio_base(pinset); + uint32_t pinmask = tms570_gio_pinmask(pinset); + uint32_t regval; + + if ((pinset & GIO_MODE_MASK) == GIO_OUTPUT) + { + regval = getreg32(base + TMS570_GIO_DOUT_OFFSET); + } + else + { + regval = getreg32(base + TMS570_GIO_DIN_OFFSET); + } + + return (regval & pinmask) != 0; +} + +/************************************************************************************ + * Function: tms570_dumpgio + * + * Description: + * Dump all GIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int tms570_dumpgio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + unsigned int port; + + lldbg("GIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + /* Get the base address associated with the GIO port */ + + port = (pinset & GIO_PORT_MASK) >> GIO_PORT_SHIFT; + base = TMS570_GIO_PORTBASE(port); + + /* The following requires exclusive access to the GIO registers */ + + flags = enter_critical_section(); + + /* Show global GIO registers */ + + lldbg(" GCR0: %08x INTDET: %08x POL: %08x ENA: %08x\n", + getreg32(TMS570_GIO_GCR0), getreg32(TMS570_GIO_INTDET), + getreg32(TMS570_GIO_POL), getreg32(TMS570_GIO_ENASET)); + lldbg(" LVL: %08x FLG: %08x EMU1: %08x EMU2: %08x\n", + getreg32(TMS570_GIO_LVLSET), getreg32(TMS570_GIO_FLG), + getreg32(TMS570_GIO_EMU1), getreg32(TMS570_GIO_EMU2)); + + /* Port specific registers */ + + lldbg(" DIR: %08x DIN: %08x DOUT: %08x PDR: %08x\n", + getreg32(base + TMS570_GIO_DIR_OFFSET), getreg32(base + TMS570_GIO_DIN_OFFSET), + getreg32(base + TMS570_GIO_DOUT_OFFSET), getreg32(base + TMS570_GIO_PDR_OFFSET)); + lldbg(" PULDIS: %08x PSL: %08x\n", + getreg32(base + TMS570_GIO_PULDIS_OFFSET), getreg32(base + TMS570_GIO_PSL_OFFSET)); + + leave_critical_section(flags); + return OK; +} +#endif diff --git a/arch/arm/src/tms570/tms570_gio.h b/arch/arm/src/tms570/tms570_gio.h new file mode 100644 index 0000000000000000000000000000000000000000..bc59e8b1e22689b3e506b5ed25c30cbafc500968 --- /dev/null +++ b/arch/arm/src/tms570/tms570_gio.h @@ -0,0 +1,343 @@ +/************************************************************************************ + * arch/arm/src/tms570/tms570_gio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_GIO_H +#define __ARCH_ARM_SRC_TMS570_TMS570_GIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include + +#include "chip/tms570_gio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bit-encoded input to tms570_configgio() ********************************************/ + +/* 32-bit Encoding: + * + * .... .... .... .... M.CC IIOV PPP. .BBB + */ + +/* Input/Output mode: + * + * .... .... .... .... M... .... .... .... + */ + +#define GIO_MODE_SHIFT (15) /* Bit 15: GIO mode */ +#define GIO_MODE_MASK (1 << GIO_MODE_SHIFT) +# define GIO_INPUT (0 << GIO_MODE_SHIFT) /* GIO Input */ +# define GIO_OUTPUT (1 << GIO_MODE_SHIFT) /* GIO Output */ + +/* These bits set the configuration of the pin: + * NOTE: No definitions for parallel capture mode + * + * .... .... .... .... ..CC .... .... .... + */ + +#define GIO_CFG_SHIFT (12) /* Bits 12-14: GIO configuration bits */ +#define GIO_CFG_MASK (3 << GIO_CFG_SHIFT) +# define GIO_CFG_DEFAULT (0 << GIO_CFG_SHIFT) /* Default, no attribute */ +# define GIO_CFG_PULLUP (1 << GIO_CFG_SHIFT) /* Bit 16: Internal pull-up */ +# define GIO_CFG_PULLDOWN (2 << GIO_CFG_SHIFT) /* Bit 17: Internal pull-down */ + +/* Interrupt modes: + * + * .... .... .... .... .... II.. .... .... + */ + +#define GIO_INT_SHIFT (10) /* Bits 10-11: GIO interrupt bits */ +#define GIO_INT_MASK (3 << GIO_INT_SHIFT) +# define GIO_INT_NONE (0 << GIO_INT_SHIFT) +# define GIO_INT_RISING (1 << GIO_INT_SHIFT) +# define GIO_INT_FALLING (2 << GIO_INT_SHIFT) +# define GIO_INT_BOTHEDGES (3 << GIO_INT_SHIFT) + +/* If the pin is an GIO output, then this selects the open drain output + * + * .... .... .... .... .... ..O. .... .... + */ + +#define GIO_OPENDRAIN (1 << 9) /* Bit 9: Open drain mode */ + +/* If the pin is an GIO output, then this identifies the initial output value: + * + * .... .... .... .... .... ...V .... .... + */ + +#define GIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */ +#define GIO_OUTPUT_CLEAR (0) + +/* This identifies the GIO port: + * + * .... .... .... .... .... .... PPP. .... + */ + +#define GIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GIO_PORT_MASK (7 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOA (0 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOB (1 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOC (2 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOD (3 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOE (4 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOF (5 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOG (6 << GIO_PORT_SHIFT) +# define GIO_PORT_GIOH (7 << GIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * .... .... .... .... .... .... .... .BBB + */ + +#define GIO_PIN_SHIFT (0) /* Bits 0-2: GIO number: 0-7 */ +#define GIO_PIN_MASK (7 << GIO_PIN_SHIFT) +# define GIO_PIN0 (0 << GIO_PIN_SHIFT) +# define GIO_PIN1 (1 << GIO_PIN_SHIFT) +# define GIO_PIN2 (2 << GIO_PIN_SHIFT) +# define GIO_PIN3 (3 << GIO_PIN_SHIFT) +# define GIO_PIN4 (4 << GIO_PIN_SHIFT) +# define GIO_PIN5 (5 << GIO_PIN_SHIFT) +# define GIO_PIN6 (6 << GIO_PIN_SHIFT) +# define GIO_PIN7 (7 << GIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint16_t gio_pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: tms570_gio_base + * + * Description: + * Return the base address of the GIO register set + * + ****************************************************************************/ + +static inline uintptr_t tms570_gio_base(gio_pinset_t cfgset) +{ + int port = (cfgset & GIO_PORT_MASK) >> GIO_PORT_SHIFT; + return TMS570_GIO_PORTBASE(port); +} + +/**************************************************************************** + * Name: tms570_gio_port + * + * Description: + * Return the GIO port number + * + ****************************************************************************/ + +static inline int tms570_gio_port(gio_pinset_t cfgset) +{ + return (cfgset & GIO_PORT_MASK) >> GIO_PORT_SHIFT; +} + +/**************************************************************************** + * Name: tms570_gio_pin + * + * Description: + * Return the GIO pin number + * + ****************************************************************************/ + +static inline int tms570_gio_pin(gio_pinset_t cfgset) +{ + return (cfgset & GIO_PIN_MASK) >> GIO_PIN_SHIFT; +} + +/**************************************************************************** + * Name: tms570_gio_pinmask + * + * Description: + * Return the GIO pin bit maskt + * + ****************************************************************************/ + +static inline int tms570_gio_pinmask(gio_pinset_t cfgset) +{ + return 1 << ((cfgset & GIO_PIN_MASK) >> GIO_PIN_SHIFT); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/**************************************************************************** + * Name: tms570_gio_initialize + * + * Description: + * Take the GIO block out of reset and assure that it is ready for use. + * + ****************************************************************************/ + +int tms570_gio_initialize(void); + +/************************************************************************************ + * Name: tms570_gioirq_initialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_TMS570_GIO_IRQ +void tms570_gioirq_initialize(void); +#else +# define tms570_gioirq_initialize() +#endif + +/************************************************************************************ + * Name: tms570_configgio + * + * Description: + * Configure a GIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int tms570_configgio(gio_pinset_t cfgset); + +/************************************************************************************ + * Name: tms570_giowrite + * + * Description: + * Write one or zero to the selected GIO pin + * + ************************************************************************************/ + +void tms570_giowrite(gio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: tms570_gioread + * + * Description: + * Read one or zero from the selected GIO pin + * + ************************************************************************************/ + +bool tms570_gioread(gio_pinset_t pinset); + +/************************************************************************************ + * Name: tms570_gioirq + * + * Description: + * Configure an interrupt for the specified GIO pin. + * + ************************************************************************************/ + +#ifdef CONFIG_TMS570_GIO_IRQ +void tms570_gioirq(gio_pinset_t pinset); +#else +# define tms570_gioirq(pinset) +#endif + +/************************************************************************************ + * Name: tms570_gioirqenable + * + * Description: + * Enable the interrupt for specified GIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_TMS570_GIO_IRQ +void tms570_gioirqenable(int irq); +#else +# define tms570_gioirqenable(irq) +#endif + +/************************************************************************************ + * Name: tms570_gioirqdisable + * + * Description: + * Disable the interrupt for specified GIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_TMS570_GIO_IRQ +void tms570_gioirqdisable(int irq); +#else +# define tms570_gioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: tms570_dumpgio + * + * Description: + * Dump all GIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int tms570_dumpgio(uint32_t pinset, const char *msg); +#else +# define tms570_dumpgio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_GIO_H */ diff --git a/arch/arm/src/tms570/tms570_gioirq.c b/arch/arm/src/tms570/tms570_gioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..6eca48e629300c36d746e515792083911079dd48 --- /dev/null +++ b/arch/arm/src/tms570/tms570_gioirq.c @@ -0,0 +1,256 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_gioirq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "tms570_gio.h" +#include "chip/tms570_gio.h" + +#ifdef CONFIG_TMS570_GIO_IRQ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_gio_interrupt + * + * Description: + * Receive GIO interrupts + * + ****************************************************************************/ + +static int tms3570_gio_interrupt(int irq, void *context) +{ + uint32_t off1; + int irq2; + + /* Loop until all pending GIO interrupts have been processed */ + + while ((off1 = getreg32(TMS570_GIO_OFF1)) != GIO_OFF_NONE) + { + /* Convert the offset value to the second-level IRQ number */ + + irq2 = off1 + TMS570_IRQ_GIOA0 - 1; + + /* And dispatch the second-level GIO IRQ */ + + irq_dispatch(irq2, context); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_gioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GIO pins. + * + ****************************************************************************/ + +void tms570_gioirq_initialize(void) +{ + /* Disable all pin interrupts on the pin. Make sure they are all level 0. */ + + putreg32(0xffffffff, TMS570_GIO_ENACLR); + putreg32(0xffffffff, TMS570_GIO_LVLCLR); + + /* Attach and enable the GIO level 0 interrupt */ + + DEBUGVERIFY(irq_attach(TMS570_REQ_GIO_0, tms3570_gio_interrupt)); + up_enable_irq(TMS570_REQ_GIO_0); +} + +/************************************************************************************ + * Name: tms570_gioirq + * + * Description: + * Configure an interrupt for the specified GIO pin. + * + ************************************************************************************/ + +void tms570_gioirq(gio_pinset_t pinset) +{ + uint32_t port = tms570_gio_port(pinset); + uint32_t pin = tms570_gio_pin(pinset); + irqstate_t flags; + uint32_t regval; + + /* Start with the pin interrupts disabled. Make sure that level 0 is selected. */ + + putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR); + putreg32(GIO_LVLCLR_PORT_PIN(port, pin), TMS570_GIO_LVLCLR); + + /* Make sure that the pin is configured as an input and that interrupts can e + * supported on this port. + */ + + if ((pinset & GIO_MODE_MASK) == GIO_INPUT && port < TMS570_NIRQPORTS) + { + flags = enter_critical_section(); + switch (pinset & GIO_INT_MASK) + { + case GIO_INT_NONE: + default: + break; + + case GIO_INT_RISING: + { + /* Enable rising edge detectioni */ + + regval = getreg32(TMS570_GIO_POL); + regval |= GIO_POL_PORT_PIN(port, pin); + putreg32(regval, TMS570_GIO_POL); + + /* Disable both rising and falling edge detection */ + + regval = getreg32(TMS570_GIO_INTDET); + regval &= ~GIO_INTDET_PORT_PIN(port, pin); + putreg32(regval, TMS570_GIO_INTDET); + } + break; + + case GIO_INT_FALLING: + { + /* Enable falling edge detectioni */ + + regval = getreg32(TMS570_GIO_POL); + regval &= ~GIO_POL_PORT_PIN(port, pin); + putreg32(regval, TMS570_GIO_POL); + + /* Disable both rising and falling edge detection */ + + regval = getreg32(TMS570_GIO_INTDET); + regval &= ~GIO_INTDET_PORT_PIN(port, pin); + putreg32(regval, TMS570_GIO_INTDET); + } + break; + + case GIO_INT_BOTHEDGES: + { + /* Enable both rising and falling edge detection */ + + regval = getreg32(TMS570_GIO_INTDET); + regval |= GIO_INTDET_PORT_PIN(port, pin); + putreg32(regval, TMS570_GIO_INTDET); + } + break; + } + + leave_critical_section(flags); + } +} + +/************************************************************************************ + * Name: tms570_gioirqenable + * + * Description: + * Enable the interrupt for specified GIO IRQ + * + ************************************************************************************/ + +void tms570_gioirqenable(int irq) +{ + int offset; + int port; + int pin; + + offset = irq - TMS570_IRQ_GIOA0; + if (offset < TMS570_NGIO_IRQS) + { + /* Convert the offset IRQ number to a port and pin number */ + + pin = offset & 7; + port = offset >> 3; + + /* Enable this pin interrupt */ + + putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENASET); + } +} + +/************************************************************************************ + * Name: tms570_gioirqdisable + * + * Description: + * Disable the interrupt for specified GIO IRQ + * + ************************************************************************************/ + +void tms570_gioirqdisable(int irq) +{ + int offset; + int port; + int pin; + + offset = irq - TMS570_IRQ_GIOA0; + if (offset < TMS570_NGIO_IRQS) + { + /* Convert the offset IRQ number to a port and pin number */ + + pin = offset & 7; + port = offset >> 3; + + /* Enable this pin interrupt */ + + putreg32(GIO_ENACLR_PORT_PIN(port, pin), TMS570_GIO_ENACLR); + } +} + +#endif /* CONFIG_TMS570_GIO_IRQ */ diff --git a/arch/arm/src/tms570/tms570_irq.c b/arch/arm/src/tms570/tms570_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..da9f8c5656f9b2415258fc66476aa93ed33e340e --- /dev/null +++ b/arch/arm/src/tms570/tms570_irq.c @@ -0,0 +1,409 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_irq.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/tms570_vim.h" +#include "tms570_gio.h" +#include "tms570_esm.h" +#include "tms570_irq.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_error_handler + ****************************************************************************/ + +static void tms570_error_handler(void) +{ + PANIC(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + + * The device supports three different possibilities for software to handle + * interrupts: + * + * 1. Index interrupts mode (compatible with TMS470R1x legacy code), + * 2. Register vectored interrupts (automatically provide vector address + * to application) + * 3. Hardware vectored interrupts (automatically dispatch to ISR, IRQ + * only) + * + * Only the indexed mode is supported here: After the interrupt is received + * by the CPU, the CPU branches to 0x18 (IRQ) or 0x1C (FIQ) to execute the + * main ISR. The main ISR routine reads the offset register (IRQINDEX, + * FIQINDEX) to determine the source of the interrupt. + * + * To use mode 2), it would only be necessary to initialize the VIM_RAM. + * To use mode 3), it would be necessary to initialize the VIM_RAM and also + * to set the vector enable (VE) bit in the CP15 R1 register. This bit is + * zero on reset so that the default state after reset is backward + * compatible to earlier ARM CPU. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + FAR uintptr_t *vimram; + int i; + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); +#endif + + /* Initialize VIM RAM vectors. These vectors are not used in the current + * interrupt handler logic. + */ + + vimram = (FAR uintptr_t *)TMS570_VIMRAM_BASE; + for (i = 0; i < (TMS570_IRQ_NCHANNELS + 1); i++) + { + *vimram++ = (uintptr_t)tms570_error_handler; + } + + /* Set Fall-Back Address Parity Error Register (also not used) */ + + putreg32((uint32_t)tms570_error_handler, TMS570_VIM_FBPARERR); + + /* Assign all interrupt requests to the VIM channel of the same value. + * NOTE: Nothing need be done. That is the power-on default mapping. + */ + + /* Assign all channels to IRQs */ + + putreg32(0, TMS570_VIM_FIRQPR0); + putreg32(0, TMS570_VIM_FIRQPR1); + putreg32(0, TMS570_VIM_FIRQPR2); +#ifdef TMS570_VIM_FIRQPR3 + putreg32(0, TMS570_VIM_FIRQPR3); +#endif + + /* Disable all interrupts */ + + putreg32(0xfffffffc, TMS570_VIM_REQENACLR0); + putreg32(0xffffffff, TMS570_VIM_REQENACLR1); + putreg32(0xffffffff, TMS570_VIM_REQENACLR2); +#ifdef TMS570_VIM_REQENACLR3 + putreg32(0xffffffff, TMS570_VIM_REQENACLR3); +#endif + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ + /* By default, interrupt CHAN0 is mapped to ESM (Error Signal Module) + * high level interrupt and CHAN1 is reserved for other NMI. For safety + * reasons, these two channels are mapped to FIQ only and can NOT be + * disabled through ENABLE registers. + */ + +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS +#ifdef CONFIG_TMS570_GIO_IRQ + /* Initialize logic to support a second level of interrupt decoding for + * GIO pins. + */ + + tms570_gioirq_initialize(); +#endif + + /* Attach and enable ESM interrupts. The high level interrupt is really + * an NMI. + */ + + (void)irq_attach(TMS570_REQ_ESMHIGH, tms570_esm_interrupt); + (void)irq_attach(TMS570_REQ_ESMLO, tms570_esm_interrupt); + up_enable_irq(TMS570_REQ_ESMHIGH); + up_enable_irq(TMS570_REQ_ESMLO); + + /* And finally, enable interrupts globally */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: arm_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *arm_decodeirq(uint32_t *regs) +{ + int vector; + + /* Check for a VRAM parity error. + * + * REVISIT: This is not to critical in this implementation since VIM RAM + * is not used. + */ + + /* Get the interrupting vector number from the IRQINDEX register. Zero, + * the "phantom" vector will returned. + */ + + vector = getreg32(TMS570_VIM_IRQINDEX) & VIM_IRQINDEX_MASK; + if (vector > 0) + { + /* Dispatch the interrupt. NOTE that the IRQ number is the vector + * number offset by one to skip over the "phantom" vector. + */ + + regs = arm_doirq(vector - 1, regs); + } + + return regs; +} + +/**************************************************************************** + * Name: arm_decodefiq + * + * Description: + * This function is called from the FIQ vector handler in arm_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call arm_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ +uint32_t *arm_decodefiq(FAR uint32_t *regs) +{ + int vector; + + /* Check for a VRAM parity error. + * + * REVISIT: This is not to critical in this implementation since VIM RAM + * is not used. + */ + + /* Get the interrupting vector number from the FIQINDEX register. Zero, + * the "phantom" vector will returned. + */ + + vector = getreg32(TMS570_VIM_FIQINDEX) & VIM_FIQINDEX_MASK; + if (vector > 0) + { + /* Dispatch the interrupt. NOTE that the IRQ number is the vector + * number offset by one to skip over the "phantom" vector. + */ + + regs = arm_doirq(vector - 1, regs); + } + + return regs; +} +#endif + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ or FIQ specified by 'channel' + * + ****************************************************************************/ + +void up_disable_irq(int channel) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bitmask; + unsigned int regndx; + + DEBUGASSERT(channel >= 0 && channel < TMS570_IRQ_NCHANNELS); + + /* Offset to account for the "phantom" vector */ + + channel++; + regndx = VIM_REGNDX(channel); + channel = VIM_REGBIT(channel); + bitmask = (1 << channel); + + /* Disable the IRQ/FIQ by setting the corresponding REQENACLR bit. */ + + regaddr = TMS570_VIM_REQENACLR(regndx); + regval = getreg32(regaddr); + regaddr |= bitmask; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'channel' + * + ****************************************************************************/ + +void up_enable_irq(int channel) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bitmask; + unsigned int regndx; + + DEBUGASSERT(channel >= 0 && channel < TMS570_IRQ_NCHANNELS); + + /* Offset to account for the "phantom" vector */ + + channel++; + regndx = VIM_REGNDX(channel); + channel = VIM_REGBIT(channel); + bitmask = (1 << channel); + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ + /* Select IRQ (vs FIQ) by clearing the corresponding FIRQPR bit */ + + regaddr = TMS570_VIM_FIRQPR(regndx); + regval = getreg32(regaddr); + regaddr &= ~bitmask; + putreg32(regval, regaddr); +#endif + + /* Enable the IRQ by setting the corresponding REQENASET bit. */ + + regaddr = TMS570_VIM_REQENASET(regndx); + regval = getreg32(regaddr); + regaddr |= bitmask; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: up_enable_fiq + * + * Description: + * Enable the FIQ specified by 'channel' + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ +void up_enable_fiq(int channel) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bitmask; + unsigned int regndx; + + DEBUGASSERT(channel >= 0 && channel < TMS570_IRQ_NCHANNELS); + + /* Offset to account for the "phantom" vector */ + + channel++; + regndx = VIM_REGNDX(channel); + channel = VIM_REGBIT(channel); + bitmask = (1 << channel); + + /* Select FIQ (vs IRQ) by setting the corresponding FIRQPR bit */ + + regaddr = TMS570_VIM_FIRQPR(regndx); + regval = getreg32(regaddr); + regaddr &= ~bitmask; + putreg32(regval, regaddr); + + /* Enable the FIQ by setting the corresponding REQENASET bit. */ + + regaddr = TMS570_VIM_REQENASET(regndx); + regval = getreg32(regaddr); + regaddr |= bitmask; + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +} diff --git a/arch/arm/src/tms570/tms570_irq.h b/arch/arm/src/tms570/tms570_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..eba6c7eba6abeff8f7379058ccb43d2550b1f444 --- /dev/null +++ b/arch/arm/src/tms570/tms570_irq.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_IRQ_H +#define __ARCH_ARM_SRC_TMS570_TMS570_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_enable_fiq + * + * Description: + * Enable the FIQ specified by 'channel' + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ +void up_enable_fiq(int channel); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_IRQ_H */ diff --git a/arch/arm/src/tms570/tms570_lowputc.c b/arch/arm/src/tms570/tms570_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..c5d21319e60bcb7d41ad3775e91455ee0355415a --- /dev/null +++ b/arch/arm/src/tms570/tms570_lowputc.c @@ -0,0 +1,375 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_lowputc.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Includes some logic from TI sample which has a compatibile three-clause + * BSD license and: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/tms570_sci.h" +#include "tms570_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* Select SCI parameters for the selected console */ + +#if defined(CONFIG_SCI1_SERIAL_CONSOLE) && defined(CONFIG_TMS570_SCI1) +# define TMS570_CONSOLE_BASE TMS570_SCI1_BASE +# define TMS570_CONSOLE_BAUD CONFIG_SCI1_BAUD +# define TMS570_CONSOLE_BITS CONFIG_SCI1_BITS +# define TMS570_CONSOLE_PARITY CONFIG_SCI1_PARITY +# define TMS570_CONSOLE_2STOP CONFIG_SCI1_2STOP +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_SCI2_SERIAL_CONSOLE) && defined(CONFIG_TMS570_SCI2) +# define TMS570_CONSOLE_BASE TMS570_SCI2_BASE +# define TMS570_CONSOLE_BAUD CONFIG_SCI2_BAUD +# define TMS570_CONSOLE_BITS CONFIG_SCI2_BITS +# define TMS570_CONSOLE_PARITY CONFIG_SCI2_PARITY +# define TMS570_CONSOLE_2STOP CONFIG_SCI2_2STOP +# define HAVE_SERIAL_CONSOLE 1 +#else +# error "No CONFIG_SCIn_SERIAL_CONSOLE Setting" +# undef HAVE_SERIAL_CONSOLE +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +static const struct sci_config_s g_console_config = +{ + .baud = TMS570_CONSOLE_BAUD, + .parity = TMS570_CONSOLE_PARITY, + .bits = TMS570_CONSOLE_BITS, + .stopbits2 = TMS570_CONSOLE_2STOP, +}; +#endif /* HAVE_SERIAL_CONSOLE */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_sci_initialize + * + * Description: + * Perform one-time initialization of the SCI module. + * + ****************************************************************************/ + +static void tms570_sci_initialize(uint32_t base) +{ + /* Bring SCI1 out of reset */ + + putreg32(SCI_GCR0_RESET, base + TMS570_SCI_GCR0_OFFSET); + + /* Configure pins */ + /* Pin Function Register: RX is receive pin, TX is transmit pin. */ + + putreg32(SCI_PIO_RX | SCI_PIO_TX, base + TMS570_SCI_FUN_OFFSET); + + /* Pin Data Out Register: Output values are logic low. Irrelevant because + * TX FUNC != 0 and RX FUNC != 0 + */ + + putreg32(0, base + TMS570_SCI_DOUT_OFFSET); + + /* Pin Direction Register: General purpose inputs. Irrelevant because + * TX FUNC != 0 and RX FUNC != 0. + */ + + putreg32(0, base + TMS570_SCI_DIR_OFFSET); + + /* Set SCI pins open drain enable: ODR functionality disabled. Irrelevant + * because TX FUNC != 0 and RX FUNC != 0 + */ + + putreg32(0, base + TMS570_SCI_ODR_OFFSET); + + /* Set SCI pins pullup/pulldown enable: Pull control enabled */ + + putreg32(0, base + TMS570_SCI_PD_OFFSET); + + /* Set SCI pins pullup/pulldown select: Pulled up */ + + putreg32(SCI_PIO_RX | SCI_PIO_TX, base + TMS570_SCI_PSL_OFFSET); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + irqstate_t flags; + + for (; ; ) + { + /* Wait for the transmitter to be available */ + + while ((getreg32(TMS570_CONSOLE_BASE + TMS570_SCI_FLR_OFFSET) & + SCI_FLR_TXRDY) == 0); + + /* Disable interrupts so that the test and the transmission are + * atomic. + */ + + flags = enter_critical_section(); + if ((getreg32(TMS570_CONSOLE_BASE + TMS570_SCI_FLR_OFFSET) & + SCI_FLR_TXRDY) != 0) + { + /* Send the character */ + + putreg32((uint32_t)ch, TMS570_CONSOLE_BASE + TMS570_SCI_TD_OFFSET); + leave_critical_section(flags); + return; + } + + leave_critical_section(flags); + } +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +/**************************************************************************** + * Name: tms570_lowsetup + * + * Description: + * This performs basic initialization of the SCI used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void tms570_lowsetup(void) +{ +#ifdef CONFIG_TMS570_SCI1 + /* Perform one-time SCI initialization */ + + tms570_sci_initialize(TMS570_SCI1_BASE); +#endif + +#ifdef CONFIG_TMS570_SCI2 + /* Perform one-time SCI initialization */ + + tms570_sci_initialize(TMS570_SCI2_BASE); +#endif + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_SCI_CONFIG) + /* Configure the console (only) */ + + tms570_sci_configure(TMS570_CONSOLE_BASE, &g_console_config); +#endif +} + +/************************************************************************************ + * Name: tms570_sci_configure + * + * Description: + * Configure an SCI for non-interrupt driven operation + * + ************************************************************************************/ + +int tms570_sci_configure(uint32_t base, FAR const struct sci_config_s *config) +{ + uint64_t divb7; + uint64_t intpart; + uint64_t frac; + uint32_t p; + uint32_t m; + uint32_t u; + uint32_t nbits; + uint32_t regval; + uint32_t gcr1; + + /* Pre-calculate the baudrate divisor with 7 bits of fraction + * + * The input clock to the baud rate generator is VCLK. + * Asynchronous timing is assumed. + */ + + divb7 = ((uint64_t)BOARD_VCLK_FREQUENCY << 7) / (config->baud >> 4); + + /* Break out the integer and fractional parts */ + + intpart = divb7 >> 7; + if (intpart < 1) + { + /* Baud cannot be represented */ + + DEBUGPANIC(); + return -ERANGE; + } + + if (--intpart > 0x00ffffff) + { + /* Baud cannot be represented */ + + DEBUGPANIC(); + return -ERANGE; + } + + /* Disable all interrupts and map them all to INT0 */ + + putreg32(SCI_INT_ALLINTS, base + TMS570_SCI_CLEARINT_OFFSET); + putreg32(SCI_INT_ALLINTS, base + TMS570_SCI_CLEARINTLVL_OFFSET); + + /* Global control 1: + * COMM=0 Idle line mode is used. + * TIMING=1 Asynchronous timing is used. + * PARENA=? Depends on configuration settings + * PARITY=? Depends on configuration settings + * STOP=? Depends on configuration settings + * CLOCK=1 The internal SCICLK is the clock source + * LIN=0 LIN mode is disabled + * SWRST=0 SCI is initiailized and held in reset state + * SLEEP=0 Sleep mode is disabled + * ADAPT=0 Automatic baud rate adjustment is disabled + * MBUF=0 The multi-buffer mode is disabled. + * CTYPE=0 Classic checksum is used. + * HGEN=0 (Effective in LIN mode only) + * STOPEXT=0 (Effective in LIN mode only) + * LOOPBACK=0 Loop back mode is disabled + * CONT=0 Freeze SCI when debug mode is entered + * RXENA=1 Receiver is enabled + * TXENA=1 Transmitter is enabled + */ + + gcr1 = (SCI_GCR1_TIMING | SCI_GCR1_CLOCK | SCI_GCR1_RXENA | SCI_GCR1_TXENA); + + DEBUGASSERT(config->parity >= 0 && config->parity <= 2); + if (config->parity == 1) + { + gcr1 |= SCI_GCR1_PARENA; + } + else if (config->parity == 2) + { + gcr1 |= (SCI_GCR1_PARENA | SCI_GCR1_PARITY); + } + + if (config->stopbits2) + { + gcr1 |= SCI_GCR1_STOP; + } + + putreg32(gcr1, base + TMS570_SCI_GCR1_OFFSET); + + /* Set baud divisor using the pre-calculated values */ + + p = (uint32_t)intpart; + frac = (uint32_t)(divb7 & 0x3f); + m = frac >> 3; + u = frac & 3; + + regval = SCI_BRS_P(p) | SCI_BRS_M(m) | SCI_BRS_U(u); + putreg32(regval, base + TMS570_SCI_BRS_OFFSET); + + /* Transmission length */ + + nbits = config->bits; + DEBUGASSERT(nbits >= 1 && nbits <= 8); + + if (nbits < 1) + { + nbits = 1; + } + else if (nbits > 8) + { + nbits = 8; + } + + regval = SCI_FORMAT_CHAR(nbits - 1); + putreg32(regval, base + TMS570_SCI_FORMAT_OFFSET); + + /* Put the SCI in its operational state. */ + + gcr1 |= SCI_GCR1_SWRST; + putreg32(gcr1, base + TMS570_SCI_GCR1_OFFSET); + return OK; +} diff --git a/arch/arm/src/tms570/tms570_lowputc.h b/arch/arm/src/tms570/tms570_lowputc.h new file mode 100644 index 0000000000000000000000000000000000000000..061f976fc87879eb9de945bcba26695e18a0cad4 --- /dev/null +++ b/arch/arm/src/tms570/tms570_lowputc.h @@ -0,0 +1,122 @@ +/************************************************************************************ + * arch/arm/src/tms570/tms570_lowputc.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_LOWPUTC_H +#define __ARCH_ARM_SRC_TMS570_TMS570_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* This structure describes the configuration of an SCI UART */ + +struct sci_config_s +{ + uint32_t baud; /* Configured baud */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5-9) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: tms570_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console SCI. This SCI done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void tms570_lowsetup(void); + +/************************************************************************************ + * Name: tms570_sci_configure + * + * Description: + * Configure an SCI for non-interrupt driven operation + * + ************************************************************************************/ + +int tms570_sci_configure(uint32_t base, FAR const struct sci_config_s *config); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_LOWPUTC_H */ diff --git a/arch/arm/src/tms570/tms570_selftest.c b/arch/arm/src/tms570/tms570_selftest.c new file mode 100644 index 0000000000000000000000000000000000000000..3abb8d7122446f764a9b6f34dd26b9fc2df27a28 --- /dev/null +++ b/arch/arm/src/tms570/tms570_selftest.c @@ -0,0 +1,354 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_selftest.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Most logic in this file was leveraged from TI's Project0 which has a + * compatible BSD license: + * + * Copyright (c) 2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, Texas Instruments Incorporated, 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip/tms570_sys.h" +#include "chip/tms570_pbist.h" +#include "tms570_selftest.h" + +#ifdef CONFIG_TMS570_SELFTEST + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pbist_memtest_start + * + * Description: + * This function performs Memory Built-in Self test using PBIST module. + * + * Input Parameters: + * rinfol - The OR of each RAM grouping bit. See the PBIST_RINFOL* + * definitions in chip/tms570_pbist.h + * algomask - The list of algorithms to be run. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pbist_memtest_start(uint32_t rinfol, uint32_t algomask) +{ + uint32_t regval; + volatile int i; + + /* PBIST ROM clock frequency = HCLK frequency /2 */ + + regval = getreg32(TMS570_SYS_MSTGCR); + regval &= ~SYS_MSTGCR_ROMDIV_MASK; + regval |= SYS_MSTGCR_ROMDIV_DIV2; + putreg32(regval, TMS570_SYS_MSTGCR); + + /* Enable PBIST controller */ + + putreg32(SYS_MSIENA_RAM, TMS570_SYS_MSIENA); + + /* clear MSTGENA field */ + + regval = getreg32(TMS570_SYS_MSTGCR); + regval &= ~SYS_MSTGCR_MSTGENA_MASK; + putreg32(regval, TMS570_SYS_MSTGCR); + + /* Enable PBIST self-test */ + + regval |= SYS_MSTGCR_MSTGENA_ENABLE; + putreg32(regval, TMS570_SYS_MSTGCR); + + /* Wait for 32 VBUS clock cycles at least, based on HCLK to VCLK ratio */ + + for (i = 0; i < (32 + (32 * 0)); i++); + + /* Enable PBIST clocks and ROM clock */ + + regval = (PBIST_PACT_PACT0 | PBIST_PACT_PACT1); + putreg32(regval, TMS570_PBIST_PACT); + + /* Select all algorithms to be tested */ + + putreg32(algomask, TMS570_PBIST_ALGO); + + /* Select RAM groups */ + + putreg32(rinfol, TMS570_PBIST_RINFOL); + + /* Select all RAM groups */ + + putreg32(0, TMS570_PBIST_RINFOU); + + /* ROM contents will not override RINFOx settings */ + + putreg32(0, TMS570_PBIST_OVER); + + /* Algorithm code is loaded from ROM */ + + putreg32(PBIST_ROM_BOTH, TMS570_PBIST_ROM); + + /* Start PBIST */ + + regval = (PBIST_DLR_DLR2 | PBIST_DLR_DLR4); + putreg32(PBIST_ROM_BOTH, TMS570_PBIST_DLR); +} + +/**************************************************************************** + * Name: pbist_test_complete + * + * Description: + * Return true if the PBIST test is completed + * + * Input Parameters: + * None + * + * Returned Value: + * true if the PBIST test is compelte + * + ****************************************************************************/ + +static inline bool pbist_test_complete(void) +{ + return ((getreg32(TMS570_SYS_MSTCGSTAT) & SYS_MSTCGSTAT_MSTDONE) != 0); +} + +/**************************************************************************** + * Name: pbist_test_passed + * + * Description: + * Return true if the PBIST test passed + * + * Input Parameters: + * None + * + * Returned Value: + * true if the PBIST test passed + * + ****************************************************************************/ + +static inline bool pbist_test_passed(void) +{ + return ((getreg32(TMS570_PBIST_FSRF0) & PBIST_FSRF) == 0 && + (getreg32(TMS570_PBIST_FSRF1) & PBIST_FSRF) == 0); +} + +/**************************************************************************** + * Name: pbist_stop + * + * Description: + * This function is called to stop PBIST after test is performed. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pbist_stop(void) +{ + uint32_t regval; + + /* Disable PBIST clocks and ROM clock */ + + putreg32(0, TMS570_PBIST_PACT); + + regval = getreg32(TMS570_SYS_MSTGCR); + regval &= ~SYS_MSTGCR_MSTGENA_MASK; + putreg32(regval, TMS570_SYS_MSTGCR); + + regval |= SYS_MSTGCR_MSTGENA_DISABLE; + putreg32(regval, TMS570_SYS_MSTGCR); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_memtest_selftest + * + * Description: + * Run a diagnostic check on the memory self-test controller. + * + * This function chooses a RAM test algorithm and runs it on an on-chip + * ROM. The memory self-test is expected to fail. The function ensures + * that the PBIST controller is capable of detecting and indicating a + * memory self-test failure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void tms570_memtest_selftest(void) +{ +#warning Missing Logic +} + +/**************************************************************************** + * Name: tms570_memtest_start + * + * Description: + * Start the memory test on the selecte set of RAMs. This test does not + * return until the memory test is completed. + * + * Input Parameters: + * rinfol - The OR of each RAM grouping bit. See the PBIST_RINFOL* + * definitions in chip/tms570_pbist.h + * + * Returned Value: + * None + * + ****************************************************************************/ + +void tms570_memtest_start(uint32_t rinfol) +{ + pbist_memtest_start(rinfol, PBIST_ALGO_March13N_SP); +} + +/**************************************************************************** + * Name: tms570_memtest_complete + * + * Description: + * Wait for memory self-test to complete and return the result. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int tms570_memtest_complete(void) +{ + bool pass; + /* Wait for the test to complete */ + + while (!pbist_test_complete()); + + /* Get the test result */ + + pass = pbist_test_passed(); + + /* Disable PBIST clocks and disable memory self-test mode */ + + pbist_stop(); + + /* Then return the test result */ + + return pass ? OK : ERROR; +} + +/**************************************************************************** + * Name: tms570_efc_selftest_start + * + * Description: + * Run eFuse controller start-up checks and start eFuse controller ECC + * self-test. This includes a check for the eFuse controller error + * outputs to be stuck-at-zero. + * + ****************************************************************************/ + +void tms570_efc_selftest_start(void) +{ +#warning Missing Logic +} + +/**************************************************************************** + * Name: tms570_efc_selftest_complete + * + * Description: + * Wait for eFuse controller self-test to complete and return the result. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int tms570_efc_selftest_complete(void) +{ +#warning Missing Logic + return OK; +} + +/**************************************************************************** + * Name: tms570_cpuecc_selftest + * + * Description: + * Test the CPU ECC mechanism for RAM accesses. + * + * Cause single-bit and double-bit errors in TCRAM accesses by corrupting + * 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit + * error in the ECC causes a data abort exception. The data abort handler + * must include logic written to look for deliberately caused exception and + * to return the code execution to the instruction following the one that + * caused the abort. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +#if 0 /* Needs change to data abort handler */ +int tms570_cpuecc_selftest(void) +{ +#warning Missing Logic + return OK; +} +#endif + +#endif /* CONFIG_TMS570_SELFTEST */ diff --git a/arch/arm/src/tms570/tms570_selftest.h b/arch/arm/src/tms570/tms570_selftest.h new file mode 100644 index 0000000000000000000000000000000000000000..696bc54fe3b1382d3b95321b9fc1f873fe16ad2f --- /dev/null +++ b/arch/arm/src/tms570/tms570_selftest.h @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_selftest.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_TMS570_SELFTEST_H +#define __ARCH_ARM_SRC_TMS570_TMS570_SELFTEST_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_TMS570_SELFTEST + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_memtest_selftest + * + * Description: + * Run a diagnostic check on the memory self-test controller. + * + * This function chooses a RAM test algorithm and runs it on an on-chip + * ROM. The memory self-test is expected to fail. The function ensures + * that the PBIST controller is capable of detecting and indicating a + * memory self-test failure. + * + ****************************************************************************/ + +void tms570_memtest_selftest(void); + +/**************************************************************************** + * Name: tms570_memtest_start + * + * Description: + * Start the memory test on the selected set of RAMs. + * + * Input Paramters: + * rinfol - The OR of each RAM grouping bit. See the PBIST_RINFOL* + * definitions in chip/tms570_pbist.h + * + ****************************************************************************/ + +void tms570_memtest_start(uint32_t rinfol); + +/**************************************************************************** + * Name: tms570_memtest_complete + * + * Description: + * Wait for memory self-test to complete and return the result. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int tms570_memtest_complete(void); + +/**************************************************************************** + * Name: tms570_efc_selftest_start + * + * Description: + * Run eFuse controller start-up checks and start eFuse controller ECC + * self-test. This includes a check for the eFuse controller error + * outputs to be stuck-at-zero. + * + ****************************************************************************/ + +void tms570_efc_selftest_start(void); + +/**************************************************************************** + * Name: tms570_efc_selftest_complete + * + * Description: + * Wait for eFuse controller self-test to complete and return the result. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int tms570_efc_selftest_complete(void); + +/**************************************************************************** + * Name: tms570_cpuecc_selftest + * + * Description: + * Test the CPU ECC mechanism for RAM accesses. + * + * Cause single-bit and double-bit errors in TCRAM accesses by corrupting + * 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit + * error in the ECC causes a data abort exception. The data abort handler + * must include logic written to look for deliberately caused exception and + * to return the code execution to the instruction following the one that + * caused the abort. + * + * Returned Value: + * Zero (OK) if the test passed; A negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +#define tms570_cpuecc_selftest() + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_TMS570_SELFTEST */ +#endif /* __ARCH_ARM_SRC_TMS570_TMS570_SELFTEST_H */ diff --git a/arch/arm/src/tms570/tms570_serial.c b/arch/arm/src/tms570/tms570_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..b52755ac3ec62efe97e86dd91052e521d75e906e --- /dev/null +++ b/arch/arm/src/tms570/tms570_serial.c @@ -0,0 +1,913 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_serial.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/tms570_sci.h" +#include "tms570_lowputc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/* Which SCI with be tty0/console and which tty1? */ + +/* First pick the console and ttys0. This could be any of SCI1-1 */ + +#if defined(CONFIG_SCI1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci1port /* SCI1 is console */ +# define TTYS0_DEV g_sci1port /* SCI1 is ttyS0 */ +# define SCI1_ASSIGNED 1 +#elif defined(CONFIG_SCI2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci2port /* SCI2 is console */ +# define TTYS0_DEV g_sci2port /* SCI2 is ttyS0 */ +# define SCI2_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_TMS570_SCI1) +# define TTYS0_DEV g_sci1port /* SCI1 is ttyS0 */ +# define SCI1_ASSIGNED 1 +# elif defined(CONFIG_TMS570_SCI2) +# define TTYS0_DEV g_sci2port /* SCI2 is ttyS0 */ +# define SCI2_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of SCI1-1, excluding the console + * SCI. + */ + +#if defined(CONFIG_TMS570_SCI1) && !defined(SCI1_ASSIGNED) +# define TTYS1_DEV g_sci1port /* SCI1 is ttyS1 */ +# define SCI1_ASSIGNED 1 +#elif defined(CONFIG_TMS570_SCI2) && !defined(SCI2_ASSIGNED) +# define TTYS1_DEV g_sci2port /* SCI2 is ttyS1 */ +# define SCI2_ASSIGNED 1 +#endif + +/* BAUD definitions + * + * The source clock is selectable and could be one of: + * + * - The peripheral clock + * - A division of the peripheral clock, where the divider is product- + * dependent, but generally set to 8 + * - A processor/peripheral independent clock source fully programmable + * provided by PMC (PCK) + * - The external clock, available on the SCK pin + * + * Only the first two options are supported by this driver. The divided + * peripheral clock is only used for very low BAUD selections. + */ + +#define FAST_SCI_CLOCK BOARD_MCK_FREQUENCY +#define SLOW_SCI_CLOCK (BOARD_MCK_FREQUENCY >> 3) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct tms570_dev_s +{ + const uint32_t scibase; /* Base address of SCI registers */ + struct sci_config_s config; /* SCI configuration */ + xcpt_t handler; /* Interrupt handler */ + uint8_t irq; /* IRQ associated with this SCI */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int tms570_setup(struct uart_dev_s *dev); +static void tms570_shutdown(struct uart_dev_s *dev); +static int tms570_attach(struct uart_dev_s *dev); +static void tms570_detach(struct uart_dev_s *dev); +static int tms570_interrupt(struct uart_dev_s *dev); +#ifdef CONFIG_TMS570_SCI1 +static int tms570_sci1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_TMS570_SCI2 +static int tms570_sci2_interrupt(int irq, void *context); +#endif +static int tms570_ioctl(struct file *filep, int cmd, unsigned long arg); +static int tms570_receive(struct uart_dev_s *dev, uint32_t *status); +static void tms570_rxint(struct uart_dev_s *dev, bool enable); +static bool tms570_rxavailable(struct uart_dev_s *dev); +static void tms570_send(struct uart_dev_s *dev, int ch); +static void tms570_txint(struct uart_dev_s *dev, bool enable); +static bool tms570_txready(struct uart_dev_s *dev); +static bool tms570_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_sci_ops = +{ + .setup = tms570_setup, + .shutdown = tms570_shutdown, + .attach = tms570_attach, + .detach = tms570_detach, + .ioctl = tms570_ioctl, + .receive = tms570_receive, + .rxint = tms570_rxint, + .rxavailable = tms570_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = tms570_send, + .txint = tms570_txint, + .txready = tms570_txready, + .txempty = tms570_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_TMS570_SCI1 +static char g_sci1rxbuffer[CONFIG_SCI1_RXBUFSIZE]; +static char g_sci1txbuffer[CONFIG_SCI1_TXBUFSIZE]; +#endif +#ifdef CONFIG_TMS570_SCI2 +static char g_sci2rxbuffer[CONFIG_SCI2_RXBUFSIZE]; +static char g_sci2txbuffer[CONFIG_SCI2_TXBUFSIZE]; +#endif + +/* This describes the state of the SCI1 port. */ + +#ifdef CONFIG_TMS570_SCI1 +static struct tms570_dev_s g_sci1priv = +{ + .scibase = TMS570_SCI1_BASE, + .config = + { + .baud = CONFIG_SCI1_BAUD, + .parity = CONFIG_SCI1_PARITY, + .bits = CONFIG_SCI1_BITS, + .stopbits2 = CONFIG_SCI1_2STOP, + }, + .handler = tms570_sci1_interrupt, + .irq = TMS570_REQ_SCI1_0, +}; + +static uart_dev_t g_sci1port = +{ + .recv = + { + .size = CONFIG_SCI1_RXBUFSIZE, + .buffer = g_sci1rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI1_TXBUFSIZE, + .buffer = g_sci1txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci1priv, +}; +#endif + +/* This describes the state of the SCI2 port. */ + +#ifdef CONFIG_TMS570_SCI2 +static struct tms570_dev_s g_sci2priv = +{ + .scibase = TMS570_SCI2_BASE, + .config = + { + .baud = CONFIG_SCI2_BAUD, + .parity = CONFIG_SCI2_PARITY, + .bits = CONFIG_SCI2_BITS, + .stopbits2 = CONFIG_SCI2_2STOP, + }, + .handler = tms570_sci2_interrupt, + .irq = TMS570_REQ_SCI2_0, +}; + +static uart_dev_t g_sci2port = +{ + .recv = + { + .size = CONFIG_SCI2_RXBUFSIZE, + .buffer = g_sci2rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI2_TXBUFSIZE, + .buffer = g_sci2txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_serialin + ****************************************************************************/ + +static inline uint32_t tms570_serialin(struct tms570_dev_s *priv, int offset) +{ + return getreg32(priv->scibase + offset); +} + +/**************************************************************************** + * Name: tms570_serialout + ****************************************************************************/ + +static inline void tms570_serialout(struct tms570_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->scibase + offset); +} + +/**************************************************************************** + * Name: tms570_restoresciint + ****************************************************************************/ + +static inline void tms570_restoresciint(struct tms570_dev_s *priv, + uint32_t ints) +{ + /* Restore the previous interrupt state (assuming all interrupts disabled) */ + + tms570_serialout(priv, TMS570_SCI_SETINT_OFFSET, ints); +} + +/**************************************************************************** + * Name: tms570_disableallints + ****************************************************************************/ + +static void tms570_disableallints(struct tms570_dev_s *priv, uint32_t *ints) +{ + irqstate_t flags; + + /* The following must be atomic */ + + flags = enter_critical_section(); + if (ints) + { + /* Return the current enable bitsopop9 */ + + *ints = tms570_serialin(priv, TMS570_SCI_SETINT_OFFSET); + } + + /* Disable all interrupts */ + + tms570_serialout(priv, TMS570_SCI_CLEARINT_OFFSET, SCI_INT_ALLINTS); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: tms570_setup + * + * Description: + * Configure the SCI baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int tms570_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_SCI_CONFIG + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + + /* Configure baud, number of bits, stop bits, and parity */ + + return tms570_sci_configure(priv->scibase, &priv->config); +#else + return OK; +#endif +} + +/**************************************************************************** + * Name: tms570_shutdown + * + * Description: + * Disable the SCI. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void tms570_shutdown(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + + /* Reset and disable receiver and transmitter */ + + tms570_serialout(priv, TMS570_SCI_GCR1_OFFSET, 0); + + /* Disable all interrupts */ + + tms570_disableallints(priv, NULL); +} + +/**************************************************************************** + * Name: tms570_attach + * + * Description: + * Configure the SCI to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int tms570_attach(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->handler); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the SCI + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: tms570_detach + * + * Description: + * Detach SCI interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void tms570_detach(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: tms570_interrupt + * + * Description: + * This is the common SCI interrupt handler. It will be invoked + * when an interrupt received on the device. It should call + * sci_transmitchars or sci_receivechar to perform the appropriate data + * transfers. + * + ****************************************************************************/ + +static int tms570_interrupt(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv; + uint32_t intvec; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct tms570_dev_s *)dev->priv; + + /* Loop until there are no further pending interrupts */ + + for (; ; ) + { + /* Get the next pending interrupt. For most interrupts, reading the + * INVECT0 register clears the corresonding INTFLAG. + */ + + intvec = tms570_serialin(priv, TMS570_SCI_INTVECT0_OFFSET) & SCI_INTVECT_MASK; + + /* Handle the pending interrupt */ + + switch (intvec) + { + case SCI_INTVECT_NONE: /* No interrupt */ + return OK; + + case SCI_INTVECT_WAKEUP: /* Wake-up interrupt */ + /* SCI sets the WAKEUP flag if bus activity on the RX line + * either prevents power-down mode from being entered, or RX + * line activity causes an exit from power-down mode. If + * enabled wakeup interrupt is triggered once WAKEUP flag is + * set. + * + * REVISIT: This interrupt is ignored because for now the + * break detect interrupt is never enabled. + */ + + break; + + /* SCI Errors + * + * REVISIT: These error interrupta are ignored because for now the + * break detect interrupt is never enabled. + */ + + case SCI_INTVECT_PE: /* Parity error interrupt */ + case SCI_INTVECT_FE: /* Framing error interrupt */ + case SCI_INTVECT_OE: /* Overrun error interrupt */ + case SCI_INTVECT_BRKDT: /* Break detect interrupt */ + case SCI_INTVECT_BE: /* Bit error interrupt */ + break; + + case SCI_INTVECT_RX: /* Receive interrupt */ + { + /* Receive data ready... process incoming bytes */ + + uart_recvchars(dev); + } + break; + + case SCI_INTVECT_TX: /* Tranmit interrupt */ + { + /* Transmit data register available ... process outgoing bytes */ + + uart_xmitchars(dev); + } + break; + + /* LIN mode only. These should never occur in SCI mode */ + + case SCI_INTVECT_ISFE: /* Inconsistent synch field error interrupt */ + case SCI_INTVECT_ID: /* Identification interrupt */ + case SCI_INTVECT_PBE: /* Physical bus error interrupt */ + case SCI_INTVECT_CE: /* Checksum error interrupt */ + case SCI_INTVECT_NRE: /* No response error interrupt */ + case SCI_INTVECT_TOAWUS: /* Timeout after wakeup signal interrupt */ + case SCI_INTVECT_TOA3WUS: /* Timeout after 2 Wakeup signls interrupt */ + case SCI_INTVECT_TIMEOUT: /* Timeout interrupt */ + + default: + PANIC(); + } + } + + return OK; +} + +/**************************************************************************** + * Name: tms570_sci[n]_interrupt + * + * Description: + * SCI interrupt handlers + * + ****************************************************************************/ + +#ifdef CONFIG_TMS570_SCI1 +static int tms570_sci1_interrupt(int irq, void *context) +{ + return tms570_interrupt(&g_sci1port); +} +#endif +#ifdef CONFIG_TMS570_SCI2 +static int tms570_sci2_interrupt(int irq, void *context) +{ + return tms570_interrupt(&g_sci2port); +} +#endif + +/**************************************************************************** + * Name: tms570_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int tms570_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct tms570_dev_s *user = (struct tms570_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct tms570_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Return baud */ + + cfsetispeed(termiosp, priv->config.baud); + + /* Return parity */ + + termiosp->c_cflag = ((priv->config.parity != 0) ? PARENB : 0) | + ((priv->config.parity == 1) ? PARODD : 0); + + /* Return stop bits */ + + termiosp->c_cflag |= (priv->config.stopbits2) ? CSTOPB : 0; + + /* Return number of bits */ + + switch (priv->config.bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + default: + case 8: + termiosp->c_cflag |= CS8; + break; + + case 9: + termiosp->c_cflag |= CS8 /* CS9 */; + break; + } + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + uint32_t baud; + uint32_t ints; + uint8_t parity; + uint8_t nbits; + bool stop2; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Decode baud. */ + + ret = OK; + baud = cfgetispeed(termiosp); + + /* Decode number of bits */ + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + nbits = 5; + break; + + case CS6: + nbits = 6; + break; + + case CS7: + nbits = 7; + break; + + case CS8: + nbits = 8; + break; +#if 0 + case CS9: + nbits = 9; + break; +#endif + default: + ret = -EINVAL; + break; + } + + /* Decode parity */ + + if ((termiosp->c_cflag & PARENB) != 0) + { + parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + parity = 0; + } + + /* Decode stop bits */ + + stop2 = (termiosp->c_cflag & CSTOPB) != 0; + + /* Verify that all settings are valid before committing */ + + if (ret == OK) + { + /* Commit */ + + priv->config.baud = baud; + priv->config.parity = parity; + priv->config.bits = nbits; + priv->config.stopbits2 = stop2; + + /* effect the changes immediately - note that we do not + * implement TCSADRAIN / TCSAFLUSH + */ + + tms570_disableallints(priv, &ints); + ret = tms570_sci_configure(priv->scibase, &priv->config); + + /* Restore the interrupt state */ + + tms570_restoresciint(priv, ints); + } + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: tms570_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the SCI. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int tms570_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + + /* Return the error information in the saved status. */ + + *status = tms570_serialin(priv, TMS570_SCI_FLR_OFFSET); + + /* Then return the actual received byte */ + + return (int)(tms570_serialin(priv, TMS570_SCI_RD_OFFSET) & 0xff); +} + +/**************************************************************************** + * Name: tms570_rxint + * + * Description: + * Call to enable or disable RXRDY interrupts + * + ****************************************************************************/ + +static void tms570_rxint(struct uart_dev_s *dev, bool enable) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + tms570_serialout(priv, TMS570_SCI_SETINT_OFFSET, SCI_INT_RX); +#endif + } + else + { + tms570_serialout(priv, TMS570_SCI_CLEARINT_OFFSET, SCI_INT_RX); + } +} + +/**************************************************************************** + * Name: tms570_rxavailable + * + * Description: + * Return true if the receive holding register is not empty + * + ****************************************************************************/ + +static bool tms570_rxavailable(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + return ((tms570_serialin(priv, TMS570_SCI_FLR_OFFSET) & SCI_FLR_RXRDY) != 0); +} + +/**************************************************************************** + * Name: tms570_send + * + * Description: + * This method will send one byte on the SCI + *- + ****************************************************************************/ + +static void tms570_send(struct uart_dev_s *dev, int ch) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + tms570_serialout(priv, TMS570_SCI_TD_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: tms570_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void tms570_txint(struct uart_dev_s *dev, bool enable) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX holding register register + * is empty + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + tms570_serialout(priv, TMS570_SCI_SETINT_OFFSET, SCI_INT_TX); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + tms570_serialout(priv, TMS570_SCI_CLEARINT_OFFSET, SCI_INT_TX); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: tms570_txready + * + * Description: + * Return true if the transmit holding register is empty (TXRDY) + * + ****************************************************************************/ + +static bool tms570_txready(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + return ((tms570_serialin(priv, TMS570_SCI_FLR_OFFSET) & SCI_FLR_TXRDY) != 0); +} + +/**************************************************************************** + * Name: tms570_txempty + * + * Description: + * Return true if the transmit holding and shift registers are empty + * + ****************************************************************************/ + +static bool tms570_txempty(struct uart_dev_s *dev) +{ + struct tms570_dev_s *priv = (struct tms570_dev_s *)dev->priv; + return ((tms570_serialin(priv, TMS570_SCI_FLR_OFFSET) & SCI_FLR_TXEMPTY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Disable all SCIS */ + + tms570_disableallints(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + tms570_disableallints(TTYS1_DEV.priv, NULL); +#endif + +#ifdef HAVE_SERIAL_CONSOLE + /* Configure whichever one is the console. NOTE: This was already done + * in tms570_lowsetup(). + */ + + CONSOLE_DEV.isconsole = true; + tms570_setup(&CONSOLE_DEV); + + /* Register the console */ + + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all SCIs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/tms570/tms570_timerisr.c b/arch/arm/src/tms570/tms570_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..4744ccbdb8f33311ff3e20fd6e87d3fced1d3f6a --- /dev/null +++ b/arch/arm/src/tms570/tms570_timerisr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/tms570_rti.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The input clock to the RTI is the RTICLK. The RTI source is always VCLK + * which may be divided down by 2. The correct RTICLK frequency must be + * provided by board.h file as BOARD_RTICLK_FREQUENCY. + */ + +#ifndef BOARD_RTICLK_FREQUENCY +# error BOARD_RTICLK_FREQUENCY not defined +#endif + +/* Timing Calculations: + * + * FRC0CLK = RTICLK / (CPUC0 + 1) Hz + * Tcount = 1 / FRC0CLK Seconds + * = 1,000,000 / FRC0CLK Microseconds + * CMP0 = Period / Tcount + * = CONFIG_USEC_PER_TICK * FRC0CLK / 1,000,000 + * = CONFIG_USEC_PER_TICK * RTICLK / (CPUC0 + 1) / 1,000,000 + * + * For Example: + * VCLK = 80,000,000 Hz + * RTICLK = VCLK / 2 Hz + * = 40,000,000 Hz + * CPUC0 = 39 + * FR0CLK = 1,000,000 Hz + * Tcount = 1 Microsecond + * CONFIG_USEC_PER_TICK = 10,000 Microseconds + * CMP0 = 10,000 * 40,000,000 / 40 / 1,000,000 + * = 10, 000 = CONFIG_USEC_PER_TICK + */ + +#if BOARD_RTICLK_FREQUENCY > 10000000 + /* Use FR0CLK = 1MHz with CPUC0 at least 9 */ + +# define RTI_FRC0CLK (1000000) +#elif BOARD_RTICLK_FREQUENCY > 5000000 + /* Use FR0CLK = 500KHz with CPUC0 at least 9 */ + +# define RTI_FRC0CLK (500000) +#elif BOARD_RTICLK_FREQUENCY > 1000000 + /* Use FR0CLK = 100KHz with CPUC0 at least 9 */ + +# define RTI_FRC0CLK (100000) +#else +# error No logic for this value of RTICLK +#endif + +/* CPUC0 = RTICLK / FRC0CLK - 1 + * + * NOTES: + * - The following calculation performs rounding. + */ + +#define RTI_CPUC0 (((BOARD_RTICLK_FREQUENCY + RTI_FRC0CLK / 2) / RTI_FRC0CLK) - 1) + +/* CMP0 = CONFIG_USEC_PER_TICK * FRC0CLK / 1,000,000 + * + * NOTES: + * - The following calculation performs rounding. + * - The following calculation avoids integer overflow by depending on + * FRCLK being a multiple of 100,000 + */ + +#define RTI_CMP0 ((CONFIG_USEC_PER_TICK * (RTI_FRC0CLK / 100000) + 50) / 100) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Cleear the RTI Compare 0 interrupts */ + + putreg32(RTI_INT0, TMS570_RTI_INTFLAG); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Disable all RTI interrupts */ + + up_disable_irq(TMS570_REQ_RTICMP0); + putreg32(RTI_ALLINTS, TMS570_RTI_CLEARINTENA); + + /* Configure RTICOMP0 register and the RTIUDCP0 Register to initialize with + * the calculated compare value. + */ + + putreg32(RTI_CMP0, TMS570_RTI_COMP0); + putreg32(RTI_CMP0, TMS570_RTI_UDCP0); + + /* Configure the FRC0CLK clock by setting the RTICPUC0 register to the + * calculated value. + */ + + putreg32(RTI_CMP0, TMS570_RTI_CPUC0); + + /* Initialize the free-running counter and the RTI up-counter */ + + putreg32(0, TMS570_RTI_FRC0); + putreg32(0, TMS570_RTI_UC0); + + /* Clear any pending interrupts */ + + putreg32(RTI_ALLINTS, TMS570_RTI_COMP0); + + /* Enable the RTI Compare 0 interrupts (still disabled at the VIM) */ + + putreg32(RTI_INT0, TMS570_RTI_SETINTENA); + + /* Enable counter 0 */ + + putreg32(RTI_GCTRL_CNT0EN, TMS570_RTI_GCTRL); + + /* Attach the interrupt handler to the RTI Compare 0 interrupt */ + + DEBUGVERIFY(irq_attach(TMS570_REQ_RTICMP0, (xcpt_t)up_timerisr)); + + /* Enable RTI compare 0 interrupts at the VIM */ + + up_enable_irq(TMS570_REQ_RTICMP0); +} diff --git a/arch/avr/Kconfig b/arch/avr/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..6f9a85c9748be76c533b5278947618bcd90b2120 --- /dev/null +++ b/arch/avr/Kconfig @@ -0,0 +1,67 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_AVR + +choice + prompt "Atmel AVR chip selection" + default ARCH_CHIP_AT32UC3B0256 + +config ARCH_CHIP_ATMEGA + bool "ATMega family" + select ARCH_FAMILY_AVR + select MM_SMALL + ---help--- + Atmel ATMega family of 8-bit AVRs. + +config ARCH_CHIP_AT90USB + bool "AT90USB family" + select ARCH_FAMILY_AVR + select MM_SMALL + ---help--- + Atmel AT90USB family of 8-bit AVRs. + +config ARCH_CHIP_AT32UC3 + bool "AVR32 AT32UC3* family" + select ARCH_FAMILY_AVR32 + ---help--- + Atmel AT32UC3A/B/C family of 32-bit AVR32s. + +endchoice + +config ARCH_FAMILY_AVR + bool + default n + select ARCH_HAVE_STACKCHECK + +config ARCH_FAMILY_AVR32 + bool + default n + +config ARCH_FAMILY + string + default "avr" if ARCH_FAMILY_AVR + default "avr32" if ARCH_FAMILY_AVR32 + +config ARCH_CHIP + string + default "atmega" if ARCH_CHIP_ATMEGA + default "at90usb" if ARCH_CHIP_AT90USB + default "at32uc3" if ARCH_CHIP_AT32UC3 + +source arch/avr/src/common/Kconfig + +if ARCH_FAMILY_AVR +source arch/avr/src/avr/Kconfig +source arch/avr/src/at90usb/Kconfig +source arch/avr/src/atmega/Kconfig +endif + +if ARCH_FAMILY_AVR32 +source arch/avr/src/avr32/Kconfig +source arch/avr/src/at32uc3/Kconfig +endif + +endif # ARCH_AVR diff --git a/arch/avr/include/.gitignore b/arch/avr/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6460c4a67846d5801c3600ce961277e3644f647 --- /dev/null +++ b/arch/avr/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/avr/include/arch.h b/arch/avr/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..ecf79ea276acd2151a4651c699845155d4897e49 --- /dev/null +++ b/arch/avr/include/arch.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/avr/include/arch.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_AVR_INCLUDE_ARCH_H +#define __ARCH_AVR_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_AVR_INCLUDE_ARCH_H */ + diff --git a/arch/avr/include/at32uc3/irq.h b/arch/avr/include/at32uc3/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b5395b1b7b8e46556ba48fcdd569ce4d73886394 --- /dev/null +++ b/arch/avr/include/at32uc3/irq.h @@ -0,0 +1,636 @@ +/**************************************************************************** + * arch/avr/include/at32uc3/irq.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AT32UC3_IRQ_H +#define __ARCH_AVR_INCLUDE_AT32UC3_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* Configuration CONFIG_AVR32_GPIOIRQ must be selected to enable the overall + * GPIO IRQ feature and CONFIG_AVR32_GPIOIRQSETA and/or + * CONFIG_AVR32_GPIOIRQSETB must be enabled to select GPIOs to support + * interrupts on. + */ + +#ifndef CONFIG_AVR32_GPIOIRQ +# undef CONFIG_AVR32_GPIOIRQSETA +# undef CONFIG_AVR32_GPIOIRQSETB +#endif + +/* IRQ numbers **************************************************************/ +/* Events. These exclude: + * + * - The Reset event which vectors directly either to 0x8000:0000 (uc3a) or + * to 0xa000:0000 (uc3b). + * - The OCD stop from the OSD system + * - Autovectored interrupt requests + * + * Others vector relative to the contents of the EVBA register. + */ + +#define AVR32_IRQ_UNREC 0 /* EVBA+0x00 Unrecoverable exception */ +#define AVR32_IRQ_TLBMULT 1 /* EVBA+0x04 TLB multiple hit */ +#define AVR32_IRQ_BUSDATA 2 /* EVBA+0x08 Bus error data fetch */ +#define AVR32_IRQ_BUSINST 3 /* EVBA+0x0c Bus error instruction fetch */ +#define AVR32_IRQ_NMI 4 /* EVBA+0x10 NMI */ +#define AVR32_IRQ_INSTADDR 5 /* EVBA+0x14 Instruction Address */ +#define AVR32_IRQ_ITLBPROT 6 /* EVBA+0x18 ITLB Protection */ +#define AVR32_IRQ_BP 7 /* EVBA+0x1c Breakpoint */ +#define AVR32_IRQ_INVINST 8 /* EVBA+0x20 Illegal Opcode */ +#define AVR32_IRQ_UNIMPINST 9 /* EVBA+0x24 Unimplemented instruction */ +#define AVR32_IRQ_PRIV 10 /* EVBA+0x28 Privilege violation */ +#define AVR32_IRQ_FP 11 /* EVBA+0x2c Floating-point */ +#define AVR32_IRQ_COP 12 /* EVBA+0x30 Coprocessor absent */ +#define AVR32_IRQ_RDDATA 13 /* EVBA+0x34 Data Address (Read) */ +#define AVR32_IRQ_WRDATA 14 /* EVBA+0x38 Data Address (Write) */ +#define AVR32_IRQ_RDDTLBPROT 15 /* EVBA+0x3c DTLB Protection (Read) */ +#define AVR32_IRQ_WRDTLBPROT 16 /* EVBA+0x40 DTLB Protection (Write) */ +#define AVR32_IRQ_DLTBMOD 17 /* EVBA+0x44 DTLB Modified */ +#define AVR32_IRQ_ITLBMISS 18 /* EVBA+0x50 ITLB Miss */ +#define AVR32_IRQ_RDDTLB 19 /* EVBA+0x60 DTLB Miss (Read) */ +#define AVR32_IRQ_WRDTLB 20 /* EVBA+0x70 DTLB Miss (Write) */ +#define AVR32_IRQ_SUPER 21 /* EVBA+0x100 Supervisor call */ +#define AVR32_IRQ_NEVENTS 22 + +/* "The INTC collects interrupt requests from the peripherals, prioritizes + * them, and delivers an interrupt request and an autovector to the CPU. The + * AVR32 architecture supports 4 priority levels for regular, maskable + * interrupts, and a Non-Maskable Interrupt (NMI)." + * + * "The INTC supports up to 64 groups of interrupts. Each group can have up + * to 32 interrupt request lines, these lines are connected to the peripherals. + * Each group has an Interrupt Priority Register (IPR) and an Interrupt Request + * Register (IRR). The IPRs are used to assign a priority level and an autovector + * to each group, and the IRRs are used to identify the active interrupt request + * within each group. If a group has only one interrupt request line, an active + * interrupt group uniquely identifies the active interrupt request line, and + * the corresponding IRR is not needed. The INTC also provides one Interrupt + * Cause Register (ICR) per priority level. These registers identify the group + * that has a pending interrupt of the corresponding priority level. If several + * groups have a pending interrupt of the same level, the group with the lowest + * number takes priority." + */ + +/* Only 19 groups (0-18) are used with the AT32UC3A/B: */ + +#define AVR32_IRQ_INTPRIOS 4 /* 4 interrupt priorities */ +#define AVR32_IRQ_MAXGROUPS 64 /* Architecture supports up to 64 groups */ +#define AVR32_IRQ_NGROUPS 19 /* UC3 A/B support only 19 */ + +/* Group 0 */ + +#define AVR32_IRQ_BASEIRQGRP0 22 +#define AVR32_IRQ_NREQGRP0 1 + +#define AVR32_IRQ_UC 22 /* 0 AVR32 UC CPU */ + +/* Group 1 */ + +#define AVR32_IRQ_BASEIRQGRP1 23 +#define AVR32_IRQ_NREQGRP1 10 + +#define AVR32_IRQ_EIC0 23 /* 0 External Interrupt Controller 0 */ +#define AVR32_IRQ_EIC1 24 /* 1 External Interrupt Controller 1 */ +#define AVR32_IRQ_EIC2 25 /* 2 External Interrupt Controller 2 */ +#define AVR32_IRQ_EIC3 26 /* 3 External Interrupt Controller 3 */ +#define AVR32_IRQ_EIC4 27 /* 4 External Interrupt Controller 4 */ +#define AVR32_IRQ_EIC5 28 /* 5 External Interrupt Controller 5 */ +#define AVR32_IRQ_EIC6 29 /* 6 External Interrupt Controller 6 */ +#define AVR32_IRQ_EIC7 30 /* 7 External Interrupt Controller 7 */ +#define AVR32_IRQ_RTC 31 /* 8 Real Time Counter RTC */ +#define AVR32_IRQ_PM 32 /* 9 Power Manager PM */ + +/* Group 2 */ + +#define AVR32_IRQ_BASEIRQGRP2 33 +#define AVR32_IRQ_NREQGRP2 6 + +#define AVR32_IRQ_GPIO0 33 /* 0 General Purpose Input/Output Controller 0 */ +#define AVR32_IRQ_GPIO1 34 /* 1 General Purpose Input/Output Controller 1 */ +#define AVR32_IRQ_GPIO2 35 /* 2 General Purpose Input/Output Controller 2 */ +#define AVR32_IRQ_GPIO3 36 /* 3 General Purpose Input/Output Controller 3 */ +#define AVR32_IRQ_GPIO4 37 /* 4 General Purpose Input/Output Controller 4 */ +#define AVR32_IRQ_GPIO5 38 /* 5 General Purpose Input/Output Controller 5 */ + +/* Group 3 */ + +#define AVR32_IRQ_BASEIRQGRP3 39 +#define AVR32_IRQ_NREQGRP3 7 + +#define AVR32_IRQ_PDCA0 39 /* 0 Peripheral DMA Controller 0 */ +#define AVR32_IRQ_PDCA1 40 /* 1 Peripheral DMA Controller 1 */ +#define AVR32_IRQ_PDCA2 41 /* 2 Peripheral DMA Controller 2 */ +#define AVR32_IRQ_PDCA3 42 /* 3 Peripheral DMA Controller 3 */ +#define AVR32_IRQ_PDCA4 43 /* 4 Peripheral DMA Controller 4 */ +#define AVR32_IRQ_PDCA5 44 /* 5 Peripheral DMA Controller 5 */ +#define AVR32_IRQ_PDCA6 45 /* 6 Peripheral DMA Controller 6 */ + +/* Group 4 */ + +#define AVR32_IRQ_BASEIRQGRP4 46 +#define AVR32_IRQ_NREQGRP4 1 + +#define AVR32_IRQ_FLASHC 46 /* 0 Flash Controller */ + +/* Group 5 */ + +#define AVR32_IRQ_BASEIRQGRP5 47 +#define AVR32_IRQ_NREQGRP5 1 + +#define AVR32_IRQ_USART0 47 /* 0 Universal Synchronous/Asynchronous + * Receiver/Transmitter 0 */ +/* Group 6 */ + +#define AVR32_IRQ_BASEIRQGRP6 48 +#define AVR32_IRQ_NREQGRP6 1 + +#define AVR32_IRQ_USART1 48 /* 0 Universal Synchronous/Asynchronous + * Receiver/Transmitter 1 */ +/* Group 7 */ + +#define AVR32_IRQ_BASEIRQGRP7 49 +#define AVR32_IRQ_NREQGRP7 1 + +#define AVR32_IRQ_USART2 49 /* 0 Universal Synchronous/Asynchronous + * Receiver/Transmitter 2 */ + +#define AVR32_IRQ_BASEIRQGRP8 50 +#define AVR32_IRQ_NREQGRP8 0 + +/* Group 9 */ + +#define AVR32_IRQ_BASEIRQGRP9 50 +#define AVR32_IRQ_NREQGRP9 1 + +#define AVR32_IRQ_SPI 50 /* 0 Serial Peripheral Interface */ + +#define AVR32_IRQ_BASEIRQGRP10 51 +#define AVR32_IRQ_NREQGRP10 0 + +/* Group 11 */ + +#define AVR32_IRQ_BASEIRQGRP11 51 +#define AVR32_IRQ_NREQGRP11 1 + +#define AVR32_IRQ_TWI 51 /* 0 Two-wire Interface TWI */ + +/* Group 12 */ + +#define AVR32_IRQ_BASEIRQGRP12 52 +#define AVR32_IRQ_NREQGRP12 1 + +#define AVR32_IRQ_PWM 52 /* 0 Pulse Width Modulation Controller */ + +/* Group 13 */ + +#define AVR32_IRQ_BASEIRQGRP13 53 +#define AVR32_IRQ_NREQGRP13 1 + +#define AVR32_IRQ_SSC 53 /* 0 Synchronous Serial Controller */ + +/* Group 14 */ + +#define AVR32_IRQ_BASEIRQGRP14 54 +#define AVR32_IRQ_NREQGRP14 3 + +#define AVR32_IRQ_TC0 54 /* 0 Timer/Counter 0 */ +#define AVR32_IRQ_TC1 55 /* 1 Timer/Counter 1 */ +#define AVR32_IRQ_TC2 56 /* 2 Timer/Counter 2 */ + +/* Group 15 */ + +#define AVR32_IRQ_BASEIRQGRP15 57 +#define AVR32_IRQ_NREQGRP15 1 + +#define AVR32_IRQ_ADC 57 /* 0 Analog to Digital Converter */ + +#define AVR32_IRQ_BASEIRQGRP16 58 +#define AVR32_IRQ_NREQGRP16 0 + +/* Group 17 */ + +#define AVR32_IRQ_BASEIRQGRP17 58 +#define AVR32_IRQ_NREQGRP17 1 + +#define AVR32_IRQ_USBB 58 /* 0 USB 2.0 Interface USBB */ + +/* Group 18 */ + +#define AVR32_IRQ_BASEIRQGRP18 59 +#define AVR32_IRQ_NREQGRP18 1 + +#define AVR32_IRQ_ABDAC 59 /* 0 Audio Bitstream DAC */ + +/* Total number of IRQ numbers */ + +#define AVR32_IRQ_BADVECTOR 60 /* Not a real IRQ number */ +#define NR_IRQS 60 + +/* GPIO IRQ Numbers *********************************************************/ +/* These numbers correspond to GPIO port numbers that have interrupts + * enabled. These are all decoded by the AVR32_IRQ_GPIO interrupt handler. + * A lot of effort was made here to keep the number of IRQs to a minimum + * since it will correspond to various, internal table sizes. + */ + +/* Up to 32 GPIO interrupts in PORTA0-31 */ + +#define __IRQ_GPPIO_PA0 0 + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000001) != 0 +# define AVR32_IRQ_GPIO_PA0 __IRQ_GPPIO_PA0 +# define __IRQ_GPIO_PA1 (__IRQ_GPPIO_PA0+1) +#else +# define __IRQ_GPIO_PA1 __IRQ_GPPIO_PA0 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000002) != 0 +# define AVR32_IRQ_GPIO_PA1 __IRQ_GPIO_PA1 +# define __IRQ_GPIO_PA2 (__IRQ_GPIO_PA1+1) +#else +# define __IRQ_GPIO_PA2 __IRQ_GPIO_PA1 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000004) != 0 +# define AVR32_IRQ_GPIO_PA2 __IRQ_GPIO_PA2 +# define __IRQ_GPIO_PA3 (__IRQ_GPIO_PA2+1) +#else +# define __IRQ_GPIO_PA3 __IRQ_GPIO_PA2 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000008) != 0 +# define AVR32_IRQ_GPIO_PA3 __IRQ_GPIO_PA3 +# define __IRQ_GPIO_PA4 (__IRQ_GPIO_PA3+1) +#else +# define __IRQ_GPIO_PA4 __IRQ_GPIO_PA3 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000010) != 0 +# define AVR32_IRQ_GPIO_PA4 __IRQ_GPIO_PA4 +# define __IRQ_GPIO_PA5 (__IRQ_GPIO_PA4+1) +#else +# define __IRQ_GPIO_PA5 __IRQ_GPIO_PA4 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000020) != 0 +# define AVR32_IRQ_GPIO_PA5 __IRQ_GPIO_PA5 +# define __IRQ_GPIO_PA6 (__IRQ_GPIO_PA5+1) +#else +# define __IRQ_GPIO_PA6 __IRQ_GPIO_PA5 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000040) != 0 +# define AVR32_IRQ_GPIO_PA6 __IRQ_GPIO_PA6 +# define __IRQ_GPIO_PA7 (__IRQ_GPIO_PA6+1) +#else +# define __IRQ_GPIO_PA7 __IRQ_GPIO_PA6 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000080) != 0 +# define AVR32_IRQ_GPIO_PA7 __IRQ_GPIO_PA7 +# define __IRQ_GPIO_PA8 (__IRQ_GPIO_PA7+1) +#else +# define __IRQ_GPIO_PA8 __IRQ_GPIO_PA7 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000100) != 0 +# define AVR32_IRQ_GPIO_PA8 __IRQ_GPIO_PA8 +# define __IRQ_GPIO_PA9 (__IRQ_GPIO_PA8+1) +#else +# define __IRQ_GPIO_PA9 __IRQ_GPIO_PA8 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000200) != 0 +# define AVR32_IRQ_GPIO_PA9 __IRQ_GPIO_PA9 +# define __IRQ_GPIO_PA10 (__IRQ_GPIO_PA9+1) +#else +# define __IRQ_GPIO_PA10 __IRQ_GPIO_PA9 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000400) != 0 +# define AVR32_IRQ_GPIO_PA10 __IRQ_GPIO_PA10 +# define __IRQ_GPIO_PA11 (__IRQ_GPIO_PA10+1) +#else +# define __IRQ_GPIO_PA11 __IRQ_GPIO_PA10 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00000800) != 0 +# define AVR32_IRQ_GPIO_PA11 __IRQ_GPIO_PA11 +# define __IRQ_GPIO_PA12 (__IRQ_GPIO_PA11+1) +#else +# define __IRQ_GPIO_PA12 __IRQ_GPIO_PA11 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00001000) != 0 +# define AVR32_IRQ_GPIO_PA12 __IRQ_GPIO_PA12 +# define __IRQ_GPIO_PA13 (__IRQ_GPIO_PA12+1) +#else +# define __IRQ_GPIO_PA13 __IRQ_GPIO_PA12 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00002000) != 0 +# define AVR32_IRQ_GPIO_PA13 __IRQ_GPIO_PA13 +# define __IRQ_GPIO_PA14 (__IRQ_GPIO_PA13+1) +#else +# define __IRQ_GPIO_PA14 __IRQ_GPIO_PA13 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00004000) != 0 +# define AVR32_IRQ_GPIO_PA14 __IRQ_GPIO_PA14 +# define __IRQ_GPIO_PA15 (__IRQ_GPIO_PA14+1) +#else +# define __IRQ_GPIO_PA15 __IRQ_GPIO_PA14 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00008000) != 0 +# define AVR32_IRQ_GPIO_PA15 __IRQ_GPIO_PA15 +# define __IRQ_GPIO_PA16 (__IRQ_GPIO_PA15+1) +#else +# define __IRQ_GPIO_PA16 __IRQ_GPIO_PA15 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00010000) != 0 +# define AVR32_IRQ_GPIO_PA16 __IRQ_GPIO_PA16 +# define __IRQ_GPIO_PA17 (__IRQ_GPIO_PA16+1) +#else +# define __IRQ_GPIO_PA17 __IRQ_GPIO_PA16 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00020000) != 0 +# define AVR32_IRQ_GPIO_PA17 __IRQ_GPIO_PA17 +# define __IRQ_GPIO_PA18 (__IRQ_GPIO_PA17+1) +#else +# define __IRQ_GPIO_PA18 __IRQ_GPIO_PA17 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00040000) != 0 +# define AVR32_IRQ_GPIO_PA18 __IRQ_GPIO_PA18 +# define __IRQ_GPIO_PA19 (__IRQ_GPIO_PA18+1) +#else +# define __IRQ_GPIO_PA19 __IRQ_GPIO_PA18 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00080000) != 0 +# define AVR32_IRQ_GPIO_PA19 __IRQ_GPIO_PA19 +# define __IRQ_GPIO_PA20 (__IRQ_GPIO_PA19+1) +#else +# define __IRQ_GPIO_PA20 __IRQ_GPIO_PA19 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00100000) != 0 +# define AVR32_IRQ_GPIO_PA20 __IRQ_GPIO_PA20 +# define __IRQ_GPIO_PA21 (__IRQ_GPIO_PA20+1) +#else +# define __IRQ_GPIO_PA21 __IRQ_GPIO_PA20 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00200000) != 0 +# define AVR32_IRQ_GPIO_PA21 __IRQ_GPIO_PA21 +# define __IRQ_GPIO_PA22 (__IRQ_GPIO_PA21+1) +#else +# define __IRQ_GPIO_PA22 __IRQ_GPIO_PA21 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00400000) != 0 +# define AVR32_IRQ_GPIO_PA22 __IRQ_GPIO_PA22 +# define __IRQ_GPIO_PA23 (__IRQ_GPIO_PA22+1) +#else +# define __IRQ_GPIO_PA23 __IRQ_GPIO_PA22 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x00800000) != 0 +# define AVR32_IRQ_GPIO_PA23 __IRQ_GPIO_PA23 +# define __IRQ_GPIO_PA24 (__IRQ_GPIO_PA23+1) +#else +# define __IRQ_GPIO_PA24 __IRQ_GPIO_PA23 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x01000000) != 0 +# define AVR32_IRQ_GPIO_PA24 __IRQ_GPIO_PA24 +# define __IRQ_GPIO_PA25 (__IRQ_GPIO_PA24+1) +#else +# define __IRQ_GPIO_PA25 __IRQ_GPIO_PA24 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x02000000) != 0 +# define AVR32_IRQ_GPIO_PA25 __IRQ_GPIO_PA25 +# define __IRQ_GPIO_PA26 (__IRQ_GPIO_PA25+1) +#else +# define __IRQ_GPIO_PA26 __IRQ_GPIO_PA25 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x04000000) != 0 +# define AVR32_IRQ_GPIO_PA26 __IRQ_GPIO_PA26 +# define __IRQ_GPIO_PA27 (__IRQ_GPIO_PA26+1) +#else +# define __IRQ_GPIO_PA27 __IRQ_GPIO_PA26 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x08000000) != 0 +# define AVR32_IRQ_GPIO_PA27 __IRQ_GPIO_PA27 +# define __IRQ_GPIO_PA28 (__IRQ_GPIO_PA27+1) +#else +# define __IRQ_GPIO_PA28 __IRQ_GPIO_PA27 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x10000000) != 0 +# define AVR32_IRQ_GPIO_PA28 __IRQ_GPIO_PA28 +# define __IRQ_GPIO_PA29 (__IRQ_GPIO_PA28+1) +#else +# define __IRQ_GPIO_PA29 __IRQ_GPIO_PA28 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x20000000) != 0 +# define AVR32_IRQ_GPIO_PA29 __IRQ_GPIO_PA29 +# define __IRQ_GPIO_PA30 (__IRQ_GPIO_PA29+1) +#else +# define __IRQ_GPIO_PA30 __IRQ_GPIO_PA29 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x40000000) != 0 +# define AVR32_IRQ_GPIO_PA30 __IRQ_GPIO_PA30 +# define __IRQ_GPIO_PA31 (__IRQ_GPIO_PA30+1) +#else +# define __IRQ_GPIO_PA31 __IRQ_GPIO_PA30 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETA & 0x80000000) != 0 +# define AVR32_IRQ_GPIO_PA31 __IRQ_GPIO_PA31 +# define __IRQ_GPIO_PB0 (__IRQ_GPIO_PA31+1) +#else +# define __IRQ_GPIO_PB0 __IRQ_GPIO_PA31 +#endif + + +/* Up to 12 GPIO interrupts in PORTB0-11 */ + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000001) != 0 +# define AVR32_IRQ_GPIO_PB0 __IRQ_GPIO_pb0 +# define __IRQ_GPIO_PB1 (__IRQ_GPIO_PB0+1) +#else +# define __IRQ_GPIO_PB1 __IRQ_GPIO_PB0 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000002) != 0 +# define AVR32_IRQ_GPIO_PB1 __IRQ_GPIO_PB1 +# define __IRQ_GPIO_PB2 (__IRQ_GPIO_PB1+1) +#else +# define __IRQ_GPIO_PB2 __IRQ_GPIO_PB1 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000004) != 0 +# define AVR32_IRQ_GPIO_PB2 __IRQ_GPIO_PB2 +# define __IRQ_GPIO_PB3 (__IRQ_GPIO_PB2+1) +#else +# define __IRQ_GPIO_PB3 __IRQ_GPIO_PB2 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000008) != 0 +# define AVR32_IRQ_GPIO_PB3 __IRQ_GPIO_PB3 +# define __IRQ_GPIO_PB4 (__IRQ_GPIO_PB3+1) +#else +# define __IRQ_GPIO_PB4 __IRQ_GPIO_PB3 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000010) != 0 +# define AVR32_IRQ_GPIO_PB4 __IRQ_GPIO_PB4 +# define __IRQ_GPIO_PB5 (__IRQ_GPIO_PB4+1) +#else +# define __IRQ_GPIO_PB5 __IRQ_GPIO_PB4 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000020) != 0 +# define AVR32_IRQ_GPIO_PB5 __IRQ_GPIO_PB5 +# define __IRQ_GPIO_PB6 (__IRQ_GPIO_PB5+1) +#else +# define __IRQ_GPIO_PB6 __IRQ_GPIO_PB5 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000040) != 0 +# define AVR32_IRQ_GPIO_PB6 __IRQ_GPIO_PB6 +# define __IRQ_GPIO_PB7 (__IRQ_GPIO_PB6+1) +#else +# define __IRQ_GPIO_PB7 __IRQ_GPIO_PB6 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000080) != 0 +# define AVR32_IRQ_GPIO_PB7 __IRQ_GPIO_PB7 +# define __IRQ_GPIO_PB8 (__IRQ_GPIO_PB7+1) +#else +# define __IRQ_GPIO_PB8 __IRQ_GPIO_PB7 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000100) != 0 +# define AVR32_IRQ_GPIO_PB8 __IRQ_GPIO_PB8 +# define __IRQ_GPIO_PB9 (__IRQ_GPIO_PB8+1) +#else +# define __IRQ_GPIO_PB9 __IRQ_GPIO_PB8 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000200) != 0 +# define AVR32_IRQ_GPIO_PB9 __IRQ_GPIO_PB9 +# define __IRQ_GPIO_PB10 (__IRQ_GPIO_PB9+1) +#else +# define __IRQ_GPIO_PB10 __IRQ_GPIO_PB9 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000400) != 0 +# define AVR32_IRQ_GPIO_PB10 __IRQ_GPIO_PB10 +# define __IRQ_GPIO_PB11 (__IRQ_GPIO_PB10+1) +#else +# define __IRQ_GPIO_PB11 __IRQ_GPIO_PB10 +#endif + +#if (CONFIG_AVR32_GPIOIRQSETB & 0x00000800) != 0 +# define AVR32_IRQ_GPIO_PB11 __IRQ_GPIO_PB11 +# define __IRQ_GPIO_PB12 (__IRQ_GPIO_PB11+1) +#else +# define __IRQ_GPIO_PB12 __IRQ_GPIO_PB11 +#endif + +#ifdef CONFIG_AVR32_GPIOIRQ +# define NR_GPIO_IRQS __IRQ_GPIO_PB12 +#else +# define NR_GPIO_IRQS 0 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AT32UC3_IRQ_H */ + diff --git a/arch/avr/include/at90usb/irq.h b/arch/avr/include/at90usb/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b93228963225cee91ed546b45c6bb1ac49a51404 --- /dev/null +++ b/arch/avr/include/at90usb/irq.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/avr/include/avr/at90usb/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AT90USB_IRQ_H +#define __ARCH_AVR_INCLUDE_AT90USB_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The AT90USB has 38 interrupt vectors including vector 0, the reset + * vector. The remaining 37 are assigned IRQ numbers here: + */ + +#define AT90USB_IRQ_INT0 0 /* 0x0002 External Interrupt Request 0 */ +#define AT90USB_IRQ_INT1 1 /* 0x0004 External Interrupt Request 1 */ +#define AT90USB_IRQ_INT2 2 /* 0x0006 External Interrupt Request 2 */ +#define AT90USB_IRQ_INT3 3 /* 0x0008 External Interrupt Request 3 */ +#define AT90USB_IRQ_INT4 4 /* 0x000a External Interrupt Request 4 */ +#define AT90USB_IRQ_INT5 5 /* 0x000c External Interrupt Request 5 */ +#define AT90USB_IRQ_INT6 6 /* 0x000e External Interrupt Request 6 */ +#define AT90USB_IRQ_INT7 7 /* 0x0010 External Interrupt Request 7 */ +#define AT90USB_IRQ_PCINT0 8 /* 0x0012 Pin Change Interrupt Request 0 */ +#define AT90USB_IRQ_USBGEN 9 /* 0x0014 USB General USB General Interrupt request */ +#define AT90USB_IRQ_USBEP 10 /* 0x0016 USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ +#define AT90USB_IRQ_WDT 11 /* 0x0018 Watchdog Time-out Interrupt */ +#define AT90USB_IRQ_T2COMPA 12 /* 0x001a TIMER2 COMPA Timer/Counter2 Compare Match A */ +#define AT90USB_IRQ_T2COMPB 13 /* 0x001c TIMER2 COMPB Timer/Counter2 Compare Match B */ +#define AT90USB_IRQ_T2OVF 14 /* 0x001e TIMER2 OVF Timer/Counter2 Overflow */ +#define AT90USB_IRQ_T1CAPT 15 /* 0x0020 TIMER1 CAPT Timer/Counter1 Capture Event */ +#define AT90USB_IRQ_T1COMPA 16 /* 0x0022 TIMER1 COMPA Timer/Counter1 Compare Match A */ +#define AT90USB_IRQ_T1COMPB 17 /* 0x0024 TIMER1 COMPB Timer/Counter1 Compare Match B */ +#define AT90USB_IRQ_T1COMPC 18 /* 0x0026 TIMER1 COMPC Timer/Counter1 Compare Match c */ +#define AT90USB_IRQ_T1OVF 19 /* 0x0028 TIMER1 OVF Timer/Counter1 Overflow */ +#define AT90USB_IRQ_T0COMPA 20 /* 0x002a TIMER0 COMPA Timer/Counter0 Compare Match A */ +#define AT90USB_IRQ_T0COMPB 21 /* 0x002c TIMER0 COMPB Timer/Counter0 Compare Match B */ +#define AT90USB_IRQ_T0OVF 22 /* 0x002e TIMER0 OVF Timer/Counter0 Overflow */ +#define AT90USB_IRQ_SPI 23 /* 0x0030 STC SPI Serial Transfer Complete */ +#define AT90USB_IRQ_U1RX 24 /* 0x0032 USART1 Rx Complete */ +#define AT90USB_IRQ_U1DRE 25 /* 0x0034 USART1 Data Register Empty */ +#define AT90USB_IRQ_U1TX 26 /* 0x0036 USART1 Tx Complete */ +#define AT90USB_IRQ_ANACOMP 27 /* 0x0038 ANALOG COMP Analog Comparator */ +#define AT90USB_IRQ_ADC 28 /* 0x003a ADC Conversion Complete */ +#define AT90USB_IRQ_EE 29 /* 0x003c EEPROM Ready */ +#define AT90USB_IRQ_T3CAPT 30 /* 0x003e TIMER3 CAPT Timer/Counter3 Capture Event */ +#define AT90USB_IRQ_T3COMPA 31 /* 0x0034 TIMER3 COMPA Timer/Counter3 Compare Match A */ +#define AT90USB_IRQ_T3COMPB 32 /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ +#define AT90USB_IRQ_T3COMPC 33 /* 0x0044 TIMER3 COMPC Timer/Counter3 Compare Match C */ +#define AT90USB_IRQ_T3OVF 34 /* 0x0046 TIMER3 OVF Timer/Counter3 Overflow */ +#define AT90USB_IRQ_TWI 35 /* 0x0048 TWI Two-wire Serial Interface */ +#define AT90USB_IRQ_SPMRDY 36 /* 0x004a Store Program Memory Ready */ + +#define NR_IRQS 37 +#define AVR_PC_SIZE 16 +#define XCPTCONTEXT_REGS 37 /* Size of the register state save array (in bytes) */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AT90USB_IRQ_H */ + diff --git a/arch/avr/include/atmega/irq.h b/arch/avr/include/atmega/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ba44c8b43a160e9fba902f31338b2bdbaa23f8f3 --- /dev/null +++ b/arch/avr/include/atmega/irq.h @@ -0,0 +1,241 @@ +/**************************************************************************** + * arch/avr/include/atmega/irq.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_ATMEGA_IRQ_H +#define __ARCH_AVR_INCLUDE_ATMEGA_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ATmega interrupt vectors other than vector 0, the reset vector, are + * assigned here: + */ + +#if defined(CONFIG_ARCH_CHIP_ATMEGA128) + +# define ATMEGA_IRQ_INT0 0 /* 0x0002 External Interrupt Request 0 */ +# define ATMEGA_IRQ_INT1 1 /* 0x0004 External Interrupt Request 1 */ +# define ATMEGA_IRQ_INT2 2 /* 0x0006 External Interrupt Request 2 */ +# define ATMEGA_IRQ_INT3 3 /* 0x0008 External Interrupt Request 3 */ +# define ATMEGA_IRQ_INT4 4 /* 0x000a External Interrupt Request 4 */ +# define ATMEGA_IRQ_INT5 5 /* 0x000c External Interrupt Request 5 */ +# define ATMEGA_IRQ_INT6 6 /* 0x000e External Interrupt Request 6 */ +# define ATMEGA_IRQ_INT7 7 /* 0x0010 External Interrupt Request 7 */ +# define ATMEGA_IRQ_T2COMP 8 /* 0x0012 TIMER2 COMP Timer/Counter2 Compare Match */ +# define ATMEGA_IRQ_T2OVF 9 /* 0x0014 TIMER2 OVF Timer/Counter2 Overflow */ +# define ATMEGA_IRQ_T1CAPT 10 /* 0x0016 TIMER1 CAPT Timer/Counter1 Capture Event */ +# define ATMEGA_IRQ_T1COMPA 11 /* 0x0018 TIMER1 COMPA Timer/Counter1 Compare Match A */ +# define ATMEGA_IRQ_T1COMPB 12 /* 0x001a TIMER1 COMPB Timer/Counter1 Compare Match B */ +# define ATMEGA_IRQ_T1OVF 13 /* 0x001c TIMER1 OVF Timer/Counter1 Overflow */ +# define ATMEGA_IRQ_T0COMP 14 /* 0x001e TIMER0 COMP Timer/Counter0 Compare Match */ +# define ATMEGA_IRQ_T0OVF 15 /* 0x0020 TIMER0 OVF Timer/Counter0 Overflow */ +# define ATMEGA_IRQ_SPI 16 /* 0x0022 STC SPI Serial Transfer Complete */ +# define ATMEGA_IRQ_U0RX 17 /* 0x0024 USART0 Rx Complete */ +# define ATMEGA_IRQ_U0DRE 18 /* 0x0026 USART0 Data Register Empty */ +# define ATMEGA_IRQ_U0TX 19 /* 0x0028 USART0 Tx Complete */ +# define ATMEGA_IRQ_ADC 20 /* 0x002a ADC Conversion Complete */ +# define ATMEGA_IRQ_EE 21 /* 0x002c EEPROM Ready */ +# define ATMEGA_IRQ_ANACOMP 22 /* 0x002e ANALOG COMP Analog Comparator */ +# define ATMEGA_IRQ_T1COMPC 23 /* 0x0030 TIMER1 COMPC Timer/Countre1 Compare Match C */ +# define ATMEGA_IRQ_T3CAPT 24 /* 0x0032 TIMER3 CAPT Timer/Counter3 Capture Event */ +# define ATMEGA_IRQ_T3COMPA 25 /* 0x0034 TIMER3 COMPA Timer/Counter3 Compare Match A */ +# define ATMEGA_IRQ_T3COMPB 26 /* 0x0036 TIMER3 COMPB Timer/Counter3 Compare Match B */ +# define ATMEGA_IRQ_T3COMPC 27 /* 0x0038 TIMER3 COMPC Timer/Counter3 Compare Match C */ +# define ATMEGA_IRQ_T3OVF 28 /* 0x003a TIMER3 OVF Timer/Counter3 Overflow */ +# define ATMEGA_IRQ_U1RX 29 /* 0x003c USART1 Rx Complete */ +# define ATMEGA_IRQ_U1DRE 30 /* 0x003e USART1 Data Register Empty */ +# define ATMEGA_IRQ_U1TX 31 /* 0x0040 USART1 Tx Complete */ +# define ATMEGA_IRQ_TWI 32 /* 0x0042 TWI Two-wire Serial Interface */ +# define ATMEGA_IRQ_SPMRDY 33 /* 0x0044 Store Program Memory Ready */ + +# define NR_IRQS 34 +# define AVR_PC_SIZE 16 +# define XCPTCONTEXT_REGS 37 /* Size of the register state save array (in bytes) */ + +#elif defined(CONFIG_ARCH_CHIP_ATMEGA1284P) + +# define ATMEGA_IRQ_INT0 0 /* 0x0002 External Interrupt Request 0 */ +# define ATMEGA_IRQ_INT1 1 /* 0x0004 External Interrupt Request 1 */ +# define ATMEGA_IRQ_INT2 2 /* 0x0006 External Interrupt Request 2 */ +# define ATMEGA_IRQ_PCINT0 3 /* 0x0008 Pin Change Interrupt Request 0 */ +# define ATMEGA_IRQ_PCINT1 4 /* 0x000a Pin Change Interrupt Request 1 */ +# define ATMEGA_IRQ_PCINT2 5 /* 0x000c Pin Change Interrupt Request 2 */ +# define ATMEGA_IRQ_PCINT3 6 /* 0x000e Pin Change Interrupt Request 3 */ +# define ATMEGA_IRQ_WDT 7 /* 0x0010 Watchdog Time-Out Interrupt */ +# define ATMEGA_IRQ_T2COMPA 8 /* 0x0012 TIMER2 COMPA Timer/Counter2 Compare Match */ +# define ATMEGA_IRQ_T2COMPB 9 /* 0x0014 TIMER2 COMPB Timer/Counter2 Compare Match */ +# define ATMEGA_IRQ_T2OVF 10 /* 0x0016 TIMER2 OVF Timer/Counter2 Overflow */ +# define ATMEGA_IRQ_T1CAPT 11 /* 0x0018 TIMER1 CAPT Timer/Counter1 Capture Event */ +# define ATMEGA_IRQ_T1COMPA 12 /* 0x001a TIMER1 COMPA Timer/Counter1 Compare Match A */ +# define ATMEGA_IRQ_T1COMPB 13 /* 0x001c TIMER1 COMPB Timer/Counter1 Compare Match B */ +# define ATMEGA_IRQ_T1OVF 14 /* 0x001e TIMER1 OVF Timer/Counter1 Overflow */ +# define ATMEGA_IRQ_T0COMPA 15 /* 0x0020 TIMER0 COMP Timer/Counter0 Compare Match */ +# define ATMEGA_IRQ_T0COMPB 16 /* 0x0022 TIMER0 COMP Timer/Counter0 Compare Match */ +# define ATMEGA_IRQ_T0OVF 17 /* 0x0024 TIMER0 OVF Timer/Counter0 Overflow */ +# define ATMEGA_IRQ_SPI 18 /* 0x0026 STC SPI Serial Transfer Complete */ +# define ATMEGA_IRQ_U0RX 19 /* 0x0028 USART0 Rx Complete */ +# define ATMEGA_IRQ_U0DRE 20 /* 0x002a USART0 Data Register Empty */ +# define ATMEGA_IRQ_U0TX 21 /* 0x002c USART0 Tx Complete */ +# define ATMEGA_IRQ_ANACOMP 22 /* 0x002e ANALOG COMP Analog Comparator */ +# define ATMEGA_IRQ_ADC 23 /* 0x0030 ADC Conversion Complete */ +# define ATMEGA_IRQ_EE 24 /* 0x0032 EEPROM Ready */ +# define ATMEGA_IRQ_TWI 25 /* 0x0034 TWI Two-wire Serial Interface */ +# define ATMEGA_IRQ_SPMRDY 26 /* 0x0036 Store Program Memory Ready */ +# define ATMEGA_IRQ_U1RX 27 /* 0x0038 USART1 Rx Complete */ +# define ATMEGA_IRQ_U1DRE 28 /* 0x003a USART1 Data Register Empty */ +# define ATMEGA_IRQ_U1TX 29 /* 0x003c USART1 Tx Complete */ +# define ATMEGA_IRQ_T3CAPT 30 /* 0x003e TIMER3 CAPT Timer/Counter3 Capture Event */ +# define ATMEGA_IRQ_T3COMPA 31 /* 0x0040 TIMER3 COMPA Timer/Counter3 Compare Match A */ +# define ATMEGA_IRQ_T3COMPB 32 /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ +# define ATMEGA_IRQ_T3OVF 33 /* 0x0044 TIMER3 OVF Timer/Counter3 Overflow */ + +# define NR_IRQS 34 +# define AVR_PC_SIZE 16 +# define XCPTCONTEXT_REGS 37 /* Size of the register state save array (in bytes) */ + +#elif defined(CONFIG_ARCH_CHIP_ATMEGA2560) + +# define ATMEGA_IRQ_INT0 2 /* 0x0002 INT0 External Interrupt Request 0 */ +# define ATMEGA_IRQ_INT1 3 /* 0x0004 INT1 External Interrupt Request 1 */ +# define ATMEGA_IRQ_INT2 4 /* 0x0006 INT2 External Interrupt Request 2 */ +# define ATMEGA_IRQ_INT3 5 /* 0x0008 INT3 External Interrupt Request 3 */ +# define ATMEGA_IRQ_INT4 6 /* 0x000A INT4 External Interrupt Request 4 */ +# define ATMEGA_IRQ_INT5 7 /* 0x000C INT5 External Interrupt Request 5 */ +# define ATMEGA_IRQ_INT6 8 /* 0x000E INT6 External Interrupt Request 6 */ +# define ATMEGA_IRQ_INT7 9 /* 0x0010 INT7 External Interrupt Request 7 */ +# define ATMEGA_IRQ_PCINT0 10 /* 0x0012 PCINT0 Pin Change Interrupt Req 0 */ +# define ATMEGA_IRQ_PCINT1 11 /* 0x0014 PCINT1 Pin Change Interrupt Req 1 */ +# define ATMEGA_IRQ_PCINT2 12 /* 0x0016 PCINT2 Pin Change Interrupt Req 2 */ +# define ATMEGA_IRQ_WDT 13 /* 0x0018 WDT Watchdog Time-out Interrupt */ +# define ATMEGA_IRQ_TIM2_COMPA 14 /* 0x001A TIMER2 COMPA Timer/Counter2 Compare Match A */ +# define ATMEGA_IRQ_TIM2_COMPB 15 /* 0x001C TIMER2 COMPB Timer/Counter2 Compare Match B */ +# define ATMEGA_IRQ_TIM2_OVF 16 /* 0x001E TIMER2 OVF Timer/Counter2 Overflow */ +# define ATMEGA_IRQ_TIM1_CAPT 17 /* 0x0020 TIMER1 CAPT Timer/Counter1 Capture Event */ +# define ATMEGA_IRQ_TIM1_COMPA 18 /* 0x0022 TIMER1 COMPA Timer/Counter1 Compare Match A */ +# define ATMEGA_IRQ_TIM1_COMPB 19 /* 0x0024 TIMER1 COMPB Timer/Counter1 Compare Match B */ +# define ATMEGA_IRQ_TIM1_COMPC 20 /* 0x0026 TIMER1 COMPC Timer/Counter1 Compare Match C */ +# define ATMEGA_IRQ_TIM1_OVF 21 /* 0x0028 TIMER1 OVF Timer/Counter1 Overflow */ +# define ATMEGA_IRQ_TIM0_COMPA 22 /* 0x002A TIMER0 COMPA Timer/Counter0 Compare Match A */ +# define ATMEGA_IRQ_TIM0_COMPB 23 /* 0x002C TIMER0 COMPB Timer/Counter0 Compare match B */ +# define ATMEGA_IRQ_TIM0_OVF 24 /* 0x002E TIMER0 OVF Timer/Counter0 Overflow */ +# define ATMEGA_IRQ_SPI_STC 25 /* 0x0030 SPI, STC SPI Serial Transfer Complete */ +# define ATMEGA_IRQ_U0RX 26 /* 0x0032 USART0 RX USART0 Rx Complete */ +# define ATMEGA_IRQ_U0DRE 27 /* 0x0034 USART0 UDRE USART0 Data Register Empty */ +# define ATMEGA_IRQ_U0TX 28 /* 0x0036 USART0 TX USART0 Tx Complete */ +# define ATMEGA_IRQ_ANA_COMP 29 /* 0x0038 ANALOG COMP Analog Comparator */ +# define ATMEGA_IRQ_ADC 30 /* 0x003A ADC ADC Conversion Complete */ +# define ATMEGA_IRQ_EE_RDY 31 /* 0x003C EE READY EEPROM Ready */ +# define ATMEGA_IRQ_TIM3_CAPT 32 /* 0x003E TIMER3 CAPT Timer/Counter3 Capture Event */ +# define ATMEGA_IRQ_TIM3_COMPA 33 /* 0x0040 TIMER3 COMPA Timer/Counter3 Compare Match A */ +# define ATMEGA_IRQ_TIM3_COMPB 34 /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ +# define ATMEGA_IRQ_TIM3_COMPC 35 /* 0x0044 TIMER3 COMPC Timer/Counter3 Compare Match C */ +# define ATMEGA_IRQ_TIM3_OVF 36 /* 0x0046 TIMER3 OVF Timer/Counter3 Overflow */ +# define ATMEGA_IRQ_U1RX 37 /* 0x0048 USART1 RX USART1 Rx Complete */ +# define ATMEGA_IRQ_U1DRE 38 /* 0x004A USART1 UDRE USART1 Data Register Empty */ +# define ATMEGA_IRQ_U1TX 39 /* 0x004C USART1 TX USART1 Tx Complete */ +# define ATMEGA_IRQ_TWI 40 /* 0x004E TWI 2-wire Serial Interface */ +# define ATMEGA_IRQ_SPM_RDY 41 /* 0x0050 SPM READY Store Program Memory Ready */ +# define ATMEGA_IRQ_TIM4_CAPT 42 /* 0x0052 TIMER4 CAPT Timer/Counter4 Capture Event */ +# define ATMEGA_IRQ_TIM4_COMPA 43 /* 0x0054 TIMER4 COMPA Timer/Counter4 Compare Match A */ +# define ATMEGA_IRQ_TIM4_COMPB 44 /* 0x0056 TIMER4 COMPB Timer/Counter4 Compare Match B */ +# define ATMEGA_IRQ_TIM4_COMPC 45 /* 0x0058 TIMER4 COMPC Timer/Counter4 Compare Match C */ +# define ATMEGA_IRQ_TIM4_OVF 46 /* 0x005A TIMER4 OVF Timer/Counter4 Overflow */ +# define ATMEGA_IRQ_TIM5_CAPT 47 /* 0x005C TIMER5 CAPT Timer/Counter5 Capture Event */ +# define ATMEGA_IRQ_TIM5_COMPA 48 /* 0x005E TIMER5 COMPA Timer/Counter5 Compare Match A */ +# define ATMEGA_IRQ_TIM5_COMPB 49 /* 0x0060 TIMER5 COMPB Timer/Counter5 Compare Match B */ +# define ATMEGA_IRQ_TIM5_COMPC 50 /* 0x0062 TIMER5 COMPC Timer/Counter5 Compare Match C */ +# define ATMEGA_IRQ_TIM5_OVF 51 /* 0x0064 TIMER5 OVF Timer/Counter5 Overflow */ +# define ATMEGA_IRQ_U2RX 52 /* 0x0066 USART2 RX USART2 Rx Complete */ +# define ATMEGA_IRQ_U2DRE 53 /* 0x0068 USART2 UDRE USART2 Data Register Empty */ +# define ATMEGA_IRQ_U2TX 54 /* 0x006A USART2 TX USART2 Tx Complete */ +# define ATMEGA_IRQ_U3RX 55 /* 0x006C USART3 RX USART3 Rx Complete */ +# define ATMEGA_IRQ_U3DRE 56 /* 0x006E USART3 UDRE USART3 Data Register Empty */ +# define ATMEGA_IRQ_U3TX 57 /* 0x0070 USART3 TX USART3 Tx Complete */ + +# define NR_IRQS 58 +# define AVR_PC_SIZE 24 +# define XCPTCONTEXT_REGS 38 /* Size of the register state save array (in bytes) */ + +#else + #error "Unrecognized chip" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_ATMEGA_IRQ_H */ diff --git a/arch/avr/include/avr/avr.h b/arch/avr/include/avr/avr.h new file mode 100644 index 0000000000000000000000000000000000000000..fc3e82bb4bb190ed017c7736b005fdb9202ef5f7 --- /dev/null +++ b/arch/avr/include/avr/avr.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/avr/include/avr/avr.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_AVR_AVR_H +#define __ARCH_AVR_INCLUDE_AVR_AVR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_INCLUDE_AVR_AVR_H */ + diff --git a/arch/avr/include/avr/irq.h b/arch/avr/include/avr/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..e25928751016292ab424f03438f11307311e1faf --- /dev/null +++ b/arch/avr/include/avr/irq.h @@ -0,0 +1,218 @@ +/**************************************************************************** + * arch/avr/include/avr/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h. + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR_IRQ_H +#define __ARCH_AVR_INCLUDE_AVR_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register state save array indices */ + +#define REG_SPH 0 /* Stack pointer on exception entry */ +#define REG_SPL 1 +#define REG_R27 2 /* r26-r27 */ +#define REG_R26 3 +#define REG_R31 4 /* r18-r31 */ +#define REG_R30 5 +#define REG_R29 6 +#define REG_R28 7 +#define REG_R23 8 /* r2-r23 */ +#define REG_R22 9 +#define REG_R21 10 +#define REG_R20 11 +#define REG_R19 12 +#define REG_R18 13 +#define REG_R17 14 +#define REG_R16 15 +#define REG_R15 16 +#define REG_R14 17 +#define REG_R13 18 +#define REG_R12 19 +#define REG_R11 20 +#define REG_R10 21 +#define REG_R9 22 +#define REG_R8 23 +#define REG_R7 24 +#define REG_R6 25 +#define REG_R5 26 +#define REG_R4 27 +#define REG_R3 28 +#define REG_R2 29 +#define REG_R1 30 /* r1 - the "zero" register */ +#define REG_R0 31 /* r0 */ +#define REG_SREG 32 /* Status register */ +#define REG_R25 33 /* r24-r25 */ +#define REG_R24 34 + +/* The program counter is automatically pushed when the interrupt occurs */ + +#define REG_PC0 35 /* PC */ +#define REG_PC1 36 +#if AVR_PC_SIZE > 16 +# define REG_PC2 37 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This struct defines the way the registers are stored. */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of PC and SR used during signal processing.*/ + + uint8_t saved_pc1; + uint8_t saved_pc0; +# if defined(REG_PC2) + uint8_t saved_pc2; +# endif + uint8_t saved_sreg; +#endif + + /* Register save area */ + + uint8_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Read/write the SREG */ + +static inline irqstate_t getsreg(void) +{ + irqstate_t sreg; + asm volatile ("in %0, __SREG__" : "=r" (sreg) :: ); + return sreg; +} + +static inline void putsreg(irqstate_t sreg) +{ + asm volatile ("out __SREG__, %s" : : "r" (sreg) : ); +} + +/* Interrupt enable/disable */ + +static inline void up_irq_enable() +{ + asm volatile ("sei" ::); +} + +static inline void up_irq_disabled() +{ + asm volatile ("cli" ::); +} + +/* Save the current interrupt enable state & disable all interrupts */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t sreg; + asm volatile + ( + "\tin %0, __SREG__\n" + "\tcli\n" + : "=&r" (sreg) :: + ); + return sreg; +} + +/* Restore saved interrupt state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + asm volatile ("out __SREG__, %0" : : "r" (flags) : ); +} +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AVR_IRQ_H */ diff --git a/arch/avr/include/avr/limits.h b/arch/avr/include/avr/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..0f25032c92e5223ba2dd2ad348dffbca345c5812 --- /dev/null +++ b/arch/avr/include/avr/limits.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/avr/include/avr/limits.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_AVR_LIMITS_H +#define __ARCH_AVR_INCLUDE_AVR_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* Integer is two bytes */ + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 32767 +#define UINT_MAX 65535U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is two bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_AVR_INCLUDE_AVR_LIMITS_H */ + diff --git a/arch/avr/include/avr/syscall.h b/arch/avr/include/avr/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..0f758fba45a52f99b8ced5cc2e4992dbc8fc2fa6 --- /dev/null +++ b/arch/avr/include/avr/syscall.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/avr/include/avr/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR_SYSCALL_H +#define __ARCH_AVR_INCLUDE_AVR_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x80 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* SWI with SYS_ call number and six parameters */ +#warning "REVISIT" +uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6); + +/* SWI with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + return sys_call6(nbr, 0, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + return sys_call6(nbr, parm1, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + return sys_call6(nbr, parm1, parm2, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + return sys_call6(nbr, parm1, parm2, parm3, 0, 0, 0); +} + +/* SWI with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, 0, 0); +} + +/* SWI with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, parm5, 0); +} + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AVR_SYSCALL_H */ + diff --git a/arch/avr/include/avr/types.h b/arch/avr/include/avr/types.h new file mode 100644 index 0000000000000000000000000000000000000000..d256a85a765f866d1880c609e3f7aab03b13dac6 --- /dev/null +++ b/arch/avr/include/avr/types.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/avr/include/avr/types.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR_TYPES_H +#define __ARCH_AVR_INCLUDE_AVR_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; /* char is 8-bits */ +typedef unsigned char _uint8_t; + +typedef signed int _int16_t; /* int is 16-bits */ +typedef unsigned int _uint16_t; + +typedef signed long _int32_t; /* long is 32-bits */ +typedef unsigned long _uint32_t; + +typedef signed long long _int64_t; /* long long is 64-bits */ +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A (near) pointer is 2 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* A FAR pointer is 4 bytes */ + +typedef signed long _int_farptr_t; +typedef unsigned long _uint_farptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned char irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_AVR_INCLUDE_AVR_TYPES_H */ + diff --git a/arch/avr/include/avr32/avr32.h b/arch/avr/include/avr32/avr32.h new file mode 100644 index 0000000000000000000000000000000000000000..2488516ca2bf0dec443f7cb182c2fce2bb71a806 --- /dev/null +++ b/arch/avr/include/avr32/avr32.h @@ -0,0 +1,206 @@ +/************************************************************************************ + * arch/avr/include/avr32/avr32.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_AVR32_AVR32_H +#define __ARCH_AVR_INCLUDE_AVR32_AVR32_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* AVR32 System Registers */ + +#define AVR32_SR 0x000 /* Status Register */ +#define AVR32_EVBA 0x004 /* Exception Vector Base Address */ +#define AVR32_ACBA 0x008 /* Application Call Base Address */ +#define AVR32_CPUCR 0x00c /* CPU Control Register */ +#define AVR32_ECR 0x010 /* Exception Cause Register */ +#define AVR32_RSR_SUP 0x014 /* Return Status Register for Supervisor context */ +#define AVR32_RSR_INT0 0x018 /* Return Status Register for INT 0 context */ +#define AVR32_RSR_INT1 0x01c /* Return Status Register for INT 1 context */ +#define AVR32_RSR_INT2 0x020 /* Return Status Register for INT 2 context */ +#define AVR32_RSR_INT3 0x024 /* Return Status Register for INT 3 context */ +#define AVR32_RSR_EX 0x028 /* Return Status Register for Exception context */ +#define AVR32_RSR_NMI 0x02c /* Return Status Register for NMI context */ +#define AVR32_RSR_DBG 0x030 /* Return Status Register for Debug Mode */ +#define AVR32_RAR_SUP 0x034 /* Return Address Register for Supervisor context */ +#define AVR32_RAR_INT0 0x038 /* Return Address Register for INT 0 context */ +#define AVR32_RAR_INT1 0x03c /* Return Address Register for INT 1 context */ +#define AVR32_RAR_INT2 0x040 /* Return Address Register for INT 2 context */ +#define AVR32_RAR_INT3 0x044 /* Return Address Register for INT 3 context */ +#define AVR32_RAR_EX 0x048 /* Return Address Register for Exception context */ +#define AVR32_RAR_NMI 0x04c /* Return Status Register for NMI context */ +#define AVR32_RAR_DBG 0x050 /* Return Status Register for Debug Mode */ +#define AVR32_JECR 0x054 /* Java Exception Cause Register */ +#define AVR32_JOSP 0x058 /* Java Operand Stack Pointer */ +#define AVR32_JAVA_LV0 0x05c /* Java Local Variable 0 */ +#define AVR32_JAVA_LV1 0x060 /* Java Local Variable 1 */ +#define AVR32_JAVA_LV2 0x064 /* Java Local Variable 2 */ +#define AVR32_JAVA_LV3 0x068 /* Java Local Variable 3 */ +#define AVR32_JAVA_LV4 0x06c /* Java Local Variable 4 */ +#define AVR32_JAVA_LV5 0x070 /* Java Local Variable 5 */ +#define AVR32_JAVA_LV6 0x074 /* Java Local Variable 6 */ +#define AVR32_JAVA_LV7 0x078 /* Java Local Variable 7 */ +#define AVR32_JTBA 0x07c /* Java Trap Base Address */ +#define AVR32_JBCR 0x080 /* Java Trap Base Address */ + /* 0x084-0x0fc: Reserved for future use */ +#define AVR32_CONFIG0 0x100 /* Configuration Register 0 */ +#define AVR32_CONFIG1 0x104 /* Configuration Register 1 */ +#define AVR32_COUNT 0x108 /* Cycle Counter Register */ +#define AVR32_COMPARE 0x10c /* Compare register */ +#define AVR32_TLBEHI 0x110 /* MMU TLB Entry High */ +#define AVR32_TLBELO 0x114 /* MMU TLB Entry Low */ +#define AVR32_PTBR 0x118 /* MMU Page Table Base Register */ +#define AVR32_TLBEAR 0x11c /* MMU TLB Exception Address Register */ +#define AVR32_MMUCR 0x120 /* MMU Control Register */ +#define AVR32_TLBARLO 0x124 /* MMU TLB Accessed Register Low */ +#define AVR32_TLBARHI 0x128 /* MMU TLB Accessed Register High */ +#define AVR32_PCCNT 0x12c /* Performance Clock Counter */ +#define AVR32_PCNT0 0x130 /* Performance Counter 0 */ +#define AVR32_PCNT1 0x134 /* Performance Counter 1 */ +#define AVR32_PCCR 0x138 /* Performance Counter Control Register */ +#define AVR32_BEAR 0x13c /* Bus Error Address */ +#define AVR32_MPUARI0 0x140 /* MPU Address Register Instruction region 0 */ +#define AVR32_MPUARI1 0x144 /* MPU Address Register Instruction region 1 */ +#define AVR32_MPUARI2 0x148 /* MPU Address Register Instruction region 2 */ +#define AVR32_MPUARI3 0x14c /* MPU Address Register Instruction region 3 */ +#define AVR32_MPUARI4 0x150 /* MPU Address Register Instruction region 4 */ +#define AVR32_MPUARI5 0x154 /* MPU Address Register Instruction region 5 */ +#define AVR32_MPUARI6 0x158 /* MPU Address Register Instruction region 6 */ +#define AVR32_MPUARI7 0x15c /* MPU Address Register Instruction region 7 */ +#define AVR32_MPUARD0 0x160 /* MPU Address Register Data region 0 */ +#define AVR32_MPUARD1 0x164 /* MPU Address Register Data region 1 */ +#define AVR32_MPUARD2 0x168 /* MPU Address Register Data region 2 */ +#define AVR32_MPUARD3 0x16c /* MPU Address Register Data region 3 */ +#define AVR32_MPUARD4 0x170 /* MPU Address Register Data region 4 */ +#define AVR32_MPUARD5 0x174 /* MPU Address Register Data region 5 */ +#define AVR32_MPUARD6 0x178 /* MPU Address Register Data region 6 */ +#define AVR32_MPUARD7 0x17c /* MPU Address Register Data region 7 */ +#define AVR32_MPUCRI 0x180 /* MPU Cacheable Register Instruction regions */ +#define AVR32_MPUCRD 0x184 /* MPU Cacheable Register Data regions */ +#define AVR32_MPUBRD 0x188 /* MPU Bufferable Register Data regions */ +#define AVR32_MPUAPRI 0x18c /* MPU Access Permission Register Instruction regions */ +#define AVR32_MPUAPRD 0x190 /* MPU Access Permission Register Data regions */ +#define AVR32_MPUCR 0x194 /* MPU Control Register */ + /* 0x198-0x2fc: Reserved for future use */ +#define AVR32_IMPL 0x300 /* 0x300-0x3fc: Implementation defined */ + +/* Status register bit definitions */ + +#define AVR32_SR_C_SHIFT 0 +#define AVR32_SR_C_MASK (1 << AVR32_SR_C_SHIFT) + +#define AVR32_SR_Z_SHIFT 1 +#define AVR32_SR_Z_MASK (1 << AVR32_SR_Z_SHIFT) + +#define AVR32_SR_N_SHIFT 2 +#define AVR32_SR_N_MASK (1 << AVR32_SR_N_SHIFT) + +#define AVR32_SR_V_SHIFT 3 +#define AVR32_SR_V_MASK (1 << AVR32_SR_V_SHIFT) + +#define AVR32_SR_Q_SHIFT 4 +#define AVR32_SR_Q_MASK (1 << AVR32_SR_Q_SHIFT) + +#define AVR32_SR_L_SHIFT 5 +#define AVR32_SR_L_MASK (1 << AVR32_SR_L_SHIFT) + +#define AVR32_SR_T_SHIFT 14 +#define AVR32_SR_T_MASK (1 << AVR32_SR_T_SHIFT) + +#define AVR32_SR_R_SHIFT 15 +#define AVR32_SR_R_MASK (1 << AVR32_SR_R_SHIFT) + +#define AVR32_SR_GM_SHIFT 16 +#define AVR32_SR_GM_MASK (1 << AVR32_SR_GM_SHIFT) + +#define AVR32_SR_I0M_SHIFT 17 +#define AVR32_SR_I0M_MASK (1 << AVR32_SR_I0M_SHIFT) + +#define AVR32_SR_I1M_SHIFT 18 +#define AVR32_SR_I1M_MASK (1 << AVR32_SR_I1M_SHIFT) + +#define AVR32_SR_I2M_SHIFT 19 +#define AVR32_SR_I2M_MASK (1 << AVR32_SR_I2M_SHIFT) + +#define AVR32_SR_I3M_SHIFT 20 +#define AVR32_SR_I3M_MASK (1 << AVR32_SR_I3M_SHIFT) + +#define AVR32_SR_EM_SHIFT 21 +#define AVR32_SR_EM_MASK (1 << AVR32_SR_EM_SHIFT) + +#define AVR32_SR_M_SHIFT 22 +#define AVR32_SR_M_MASK (7 << AVR32_SR_M_SHIFT) +# define AVR32_SR_M_APP (0 << AVR32_SR_M_SHIFT) /* Application */ +# define AVR32_SR_M_SUPER (1 << AVR32_SR_M_SHIFT) /* Supervisor */ +# define AVR32_SR_M_INT0 (2 << AVR32_SR_M_SHIFT) /* Interrupt level 0 */ +# define AVR32_SR_M_INT1 (3 << AVR32_SR_M_SHIFT) /* Interrupt level 1 */ +# define AVR32_SR_M_INT2 (4 << AVR32_SR_M_SHIFT) /* Interrupt level 2 */ +# define AVR32_SR_M_INT3 (5 << AVR32_SR_M_SHIFT) /* Interrupt level 3 */ +# define AVR32_SR_M_EX (6 << AVR32_SR_M_SHIFT) /* Exception */ +# define AVR32_SR_M_NMI (7 << AVR32_SR_M_SHIFT) /* Non Maskable Interrupt */ + +#define AVR32_SR_D_SHIFT 26 +#define AVR32_SR_D_MASK (1 << AVR32_SR_D_SHIFT) + +#define AVR32_SR_DM_SHIFT 27 +#define AVR32_SR_DM_MASK (1 << AVR32_SR_DM_SHIFT) + +#define AVR32_SR_J_SHIFT 28 +#define AVR32_SR_J_MASK (1 << AVR32_SR_J_SHIFT) + +#define AVR32_SR_H_SHIFT 29 +#define AVR32_SR_H_MASK (1 << AVR32_SR_H_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_INCLUDE_AVR32_AVR32_H */ + diff --git a/arch/avr/include/avr32/irq.h b/arch/avr/include/avr32/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b08a8ce431f6d64f87ea23cebaa8c32eadcee39e --- /dev/null +++ b/arch/avr/include/avr32/irq.h @@ -0,0 +1,227 @@ +/**************************************************************************** + * arch/avr/include/avr32/irq.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR32_IRQ_H +#define __ARCH_AVR_INCLUDE_AVR32_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* General notes about the AVR32 ABI: + * + * Scratch/Volatile Registers: r8-r12 + * Preserved/Static Registers: r0-r7 + * Parameter Passing: r12-R8 (in that order) + */ + +/* Register state save array indices. + * + * The following registers are saved by the AVR32 hardware (for the case of + * interrupts only). Note the registers are order in the opposite order the + * they appear in memory (i.e., in the order of increasing address) because + * this makes it easier to following the ordering of pushing on a push-down + * stack. + */ + +#define REG_R8 16 +#define REG_R9 15 +#define REG_R10 14 +#define REG_R11 13 +#define REG_R12 12 +#define REG_R14 11 +#define REG_R15 10 +#define REG_SR 9 + +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* Additional registers saved in order have the full CPU context */ + +#define REG_R13 8 +#define REG_SP REG_R13 + +#define REG_R0 7 +#define REG_R1 6 +#define REG_R2 5 +#define REG_R3 4 +#define REG_R4 3 +#define REG_R5 2 +#define REG_R6 1 +#define REG_R7 0 + +/* Size of the register state save array (in 32-bit words) */ + +#define INTCONTEXT_REGS 8 /* r8-r12, lr, pc, sr */ +#define XCPTCONTEXT_REGS 17 /* Plus r0-r7, sp */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This struct defines the way the registers are stored. */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of PC and SR used during signal processing.*/ + + uint32_t saved_pc; + uint32_t saved_sr; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Read the AVR32 status register */ + +static inline uint32_t avr32_sr(void) +{ + uint32_t sr; + __asm__ __volatile__ ( + "mfsr\t%0,%1\n\t" + : "=r" (sr) + : "i" (AVR32_SR) + ); + return sr; +} + +/* Read the interrupt vector base address */ + +static inline uint32_t avr32_evba(void) +{ + uint32_t evba; + __asm__ __volatile__ ( + "mfsr\t%0,%1\n\t" + : "=r" (evba) + : "i" (AVR32_EVBA) + ); + return evba; +} + +/* Save the current interrupt enable state & disable all interrupts */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t sr = (irqstate_t)avr32_sr(); + __asm__ __volatile__ ( + "ssrf\t%0\n\t" + "nop\n\t" + "nop" + : + : "i" (AVR32_SR_GM_SHIFT) + ); + return sr; +} + +/* Restore saved interrupt state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + if ((flags & AVR32_SR_GM_MASK) == 0) + { + __asm__ __volatile__ ( + "csrf\t%0\n\t" + "nop\n\t" + "nop" + : + : "i" (AVR32_SR_GM_SHIFT) + ); + } +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AVR32_IRQ_H */ + diff --git a/arch/avr/include/avr32/limits.h b/arch/avr/include/avr32/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..51cef4e44852c2de5b43f8f111add831972ef212 --- /dev/null +++ b/arch/avr/include/avr32/limits.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/avr/include/avr32/limits.h + * + * Copyright (C) 2010, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_AVR32_LIMITS_H +#define __ARCH_AVR_INCLUDE_AVR32_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* Integer is four bytes */ + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is four bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_AVR_INCLUDE_AVR32_LIMITS_H */ + diff --git a/arch/avr/include/avr32/syscall.h b/arch/avr/include/avr32/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..cab4e8af46d34ca7298b1add8345ec48d65be354 --- /dev/null +++ b/arch/avr/include/avr32/syscall.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/avr/include/avr32/syscall.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR32_SYSCALL_H +#define __ARCH_AVR_INCLUDE_AVR32_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x80 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* SWI with SYS_ call number and six parameters */ + +uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6); + +/* SWI with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + return sys_call6(nbr, 0, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + return sys_call6(nbr, parm1, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + return sys_call6(nbr, parm1, parm2, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + return sys_call6(nbr, parm1, parm2, parm3, 0, 0, 0); +} + +/* SWI with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, 0, 0); +} + +/* SWI with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, parm5, 0); +} + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_AVR32_SYSCALL_H */ + diff --git a/arch/avr/include/avr32/types.h b/arch/avr/include/avr32/types.h new file mode 100644 index 0000000000000000000000000000000000000000..d3182876c945c5ed718a6d1f73075ba9e4cf6d17 --- /dev/null +++ b/arch/avr/include/avr32/types.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/avr/include/avr32/types.h + * + * Copyright (C) 2010, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_AVR_INCLUDE_AVR32_TYPES_H +#define __ARCH_AVR_INCLUDE_AVR32_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_AVR_INCLUDE_AVR32_TYPES_H */ + diff --git a/arch/avr/include/debug.h b/arch/avr/include/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..b95e9b9322a0e0486150c508e868da8940f4f19b --- /dev/null +++ b/arch/avr/include/debug.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/avr/include/debug.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_ARCH_AVR_DEBUG_H +#define __INCLUDE_ARCH_AVR_DEBUG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#ifdef CONFIG_AVR_HAS_MEMX_PTR + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Since format string that is passed to __arch_syslog() can be a + * comma-separated list, we need some cpp trickery to handle it + * + * __dbg_first() helper macro accepts the format (that is potentially + * a comma-separated) and substitutes to its first element. + * + * __dbg_subst() helper macro substitutes first element in the format + * with prefix. + */ + +#define __dbg_first(format, ...) format +#define __dbg_subst(prefix, format, ...) prefix, ##__VA_ARGS__ + +#define __dbg_expand(logger, prio, format, ...) \ + do \ + { \ + static const IOBJ char dbg_s[] = __dbg_first(format); \ + logger(prio, __dbg_subst(dbg_s, format), ##__VA_ARGS__); \ + } \ + while(0) + +/* __arch_syslog() and __arch_lowsyslog() override behavior of NuttX + * dbg macros. They put the format string into program memory and + * utilize IPTR (__memx) parameter of syslog to take the format + * directly from program memory. This reduces amount of RAM held by + * the format strings used in debug statements. + */ + +#define __arch_syslog(...) \ + __dbg_expand(syslog, ##__VA_ARGS__) + +#define __arch_lowsyslog(...) \ + __dbg_expand(lowsyslog, ##__VA_ARGS__) + +#endif /* CONFIG_AVR_HAS_MEMX_PTR */ + +#endif /* __INCLUDE_ARCH_DEBUG_H */ diff --git a/arch/avr/include/irq.h b/arch/avr/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..3a8ecc632ef7874793e5799823b245b7e807a1e0 --- /dev/null +++ b/arch/avr/include/irq.h @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/avr/include/irq.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_IRQ_H +#define __ARCH_AVR_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/* Include AVR architecture-specific IRQ definitions (including register + * save structure and up_irq_save()/up_irq_restore() functions). + */ + +#ifdef CONFIG_ARCH_FAMILY_AVR32 +# include +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_IRQ_H */ + diff --git a/arch/avr/include/limits.h b/arch/avr/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..15cc59ddc13e04595cac4e9ab90c1ff7d5777432 --- /dev/null +++ b/arch/avr/include/limits.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * arch/avr/include/limits.h + * + * Copyright (C) 2010, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_LIMITS_H +#define __ARCH_AVR_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Include AVR architecture-specific limits */ + +#ifdef CONFIG_ARCH_FAMILY_AVR32 +# include +#else +# include +#endif + +#endif /* __ARCH_AVR_INCLUDE_LIMITS_H */ + diff --git a/arch/avr/include/syscall.h b/arch/avr/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..c1f5b85a59bc5a89ede23604f8132cbd13457889 --- /dev/null +++ b/arch/avr/include/syscall.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/avr/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_AVR_INCLUDE_SYSCALL_H +#define __ARCH_AVR_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include AVR architecture-specific syscall macros */ + +#ifdef CONFIG_ARCH_FAMILY_AVR32 +# include +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_SYSCALL_H */ + diff --git a/arch/avr/include/types.h b/arch/avr/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..bd7af18cf6de49671e5d962c2f1e0596496e9fd7 --- /dev/null +++ b/arch/avr/include/types.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/avr/include/types.h + * + * Copyright (C) 2010, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_AVR_INCLUDE_TYPES_H +#define __ARCH_AVR_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include AVR architecture-specific types definitions */ + +#ifdef CONFIG_ARCH_FAMILY_AVR32 +# include +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_AVR_INCLUDE_TYPES_H */ + diff --git a/arch/avr/include/xmega/chip.h b/arch/avr/include/xmega/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..819ce13b78380ca747fd842f6e8103b28b27eda9 --- /dev/null +++ b/arch/avr/include/xmega/chip.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/avr/include/xmega/chip.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_XMEGA_CHIP_H +#define __ARCH_AVR_INCLUDE_XMEGA_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Eventually, we will provide characteristics of the various supported + * XMega chips here. + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_XMEGA_CHIP_H */ + diff --git a/arch/avr/include/xmega/irq.h b/arch/avr/include/xmega/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..221c43b1eaf225246ae796aeb46bb5d11b262aa1 --- /dev/null +++ b/arch/avr/include/xmega/irq.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/avr/include/xmega/irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_INCLUDE_XMEGA_IRQ_H +#define __ARCH_AVR_INCLUDE_XMEGA_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/* Eventually, we will include IRQ definition files for each of the supported + * XMega chips here. For now, only the ATXmegaXXXcX is supported. + */ + +#include + + /**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_XMEGA_IRQ_H */ + diff --git a/arch/avr/include/xmega/xmegac_irq.h b/arch/avr/include/xmega/xmegac_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..77813e04d66ff8255d265ab1a64b5f852272c7c2 --- /dev/null +++ b/arch/avr/include/xmega/xmegac_irq.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/avr/include/xmega/xmegac_irq.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_AVR_INCLUDE_XMEGA_XMEGAC_IRQ_H +#define __ARCH_AVR_INCLUDE_XMEGA_XMEGAC_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The ATmegaXXXc has 64 interrupt vectors including vector 0, the reset + * vector. Many of these are unused. The remaining, valid interrupt vectors + * are assigned IRQ numbers here: + */ + +#define XMEGA_IRQ_OSCF xx /* 0x0002 Crystal oscillator failure interrupt vector (NMI) */ +#define XMEGA_IRQ_PORTC xx /* 0x0004 Port C interrupt base */ +#define XMEGA_IRQ_PORTR xx /* 0x0008 Port R interrupt base */ +#define XMEGA_IRQ_DMA xx /* 0x000c DMA controller interrupt base */ +#define XMEGA_IRQ_RTC xx /* 0x0014 Real Time Counter Interrupt base */ +#define XMEGA_IRQ_TWIC xx /* 0x0018 Two-Wire Interface on Port C Interrupt base */ +#define XMEGA_IRQ_TCC0 xx /* 0x001c Timer/Counter 0 on port C Interrupt base */ +#define XMEGA_IRQ_TCC1 xx /* 0x0028 Timer/Counter 1 on port C Interrupt base */ +#define XMEGA_IRQ_SPIC xx /* 0x0030 SPI on port C Interrupt vector */ +#define XMEGA_IRQ_USARTC0 xx /* 0x0032 USART 0 on port C Interrupt base */ +#define XMEGA_IRQ_AES xx /* 0x003e AES Interrupt vector */ +#define XMEGA_IRQ_NVM xx /* 0x0040 Non-Volatile Memory Interrupt base */ +#define XMEGA_IRQ_PORTB xx /* 0x0044 Port B Interrupt base */ +#define XMEGA_IRQ_PORTE xx /* 0x0056 Port E INT base */ +#define XMEGA_IRQ_TWIE xx /* 0x005a Two-Wire Interface on Port E Interrupt base */ +#define XMEGA_IRQ_TCE0 xx /* 0x005e Timer/Counter 0 on port E Interrupt base */ +#define XMEGA_IRQ_USARTE0 xx /* 0x0074 USART 0 on port E Interrupt base */ +#define XMEGA_IRQ_PORTD xx /* 0x0080 Port D Interrupt base */ +#define XMEGA_IRQ_PORTA xx /* 0x0084 Port A Interrupt base */ +#define XMEGA_IRQ_ACA xx /* 0x0088 Analog Comparator on Port A Interrupt base */ +#define XMEGA_IRQ_ADCA xx /* 0x008e Analog to Digital Converter on Port A Interrupt base */ +#define XMEGA_IRQ_TCD0 xx /* 0x009a Timer/Counter 0 on port D Interrupt base */ +#define XMEGA_IRQ_SPID xx /* 0x00ae SPI D Interrupt vector */ +#define XMEGA_IRQ_ xx /* 0x00b0 USARTD0 USART 0 on port D Interrupt base */ +#define XMEGA_IRQ_USARTD1 xx /* 0x00b6 USART 1 on port D Interrupt base */ +#define XMEGA_IRQ_PORTF xx /* 0x00d0 Port F Interrupt base */ +#define XMEGA_IRQ_TCF0 xx /* 0x00d8 Timer/Counter 0 on port F Interrupt base */ +#define XMEGA_IRQ_USB xx /* 0x00fa USB on port D Interrupt base */ + +#define NR_IRQS xx +#define AVR_PC_SIZE xx + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_AVR_INCLUDE_XMEGA_XMEGAC_IRQ_H */ + diff --git a/arch/avr/src/.gitignore b/arch/avr/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dfdfc935431ac8f4a525420ed96ee4f631196522 --- /dev/null +++ b/arch/avr/src/.gitignore @@ -0,0 +1,5 @@ +/.depend +/Make.dep +/locked.r +/board +/chip diff --git a/arch/avr/src/Makefile b/arch/avr/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2905a755652406c136d653fd2be200cd42e20076 --- /dev/null +++ b/arch/avr/src/Makefile @@ -0,0 +1,185 @@ +############################################################################ +# arch/avr/src/Makefile +# +# Copyright (C) 2010-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +ifeq ($(CONFIG_ARCH_FAMILY_AVR32),y) +ARCH_SUBDIR = avr32 +else ifeq ($(CONFIG_ARCH_FAMILY_AVR),y) +ARCH_SUBDIR = avr +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)" + INCLUDES += -I "$(ARCH_SRCDIR)\chip" + INCLUDES += -I "$(ARCH_SRCDIR)\common" + INCLUDES += -I "$(ARCH_SRCDIR)\$(ARCH_SUBDIR)" + INCLUDES += -I "$(TOPDIR)\sched" +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + INCLUDES += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)" + INCLUDES += -I "$(ARCH_SRCDIR)/chip" + INCLUDES += -I "$(ARCH_SRCDIR)/common" + INCLUDES += -I "$(ARCH_SRCDIR)/$(ARCH_SUBDIR)" + INCLUDES += -I "$(TOPDIR)/sched" +endif +endif + +CPPFLAGS += $(INCLUDES) $(EXTRADEFINES) +CFLAGS += $(INCLUDES) $(EXTRADEFINES) +CXXFLAGS += $(INCLUDES) $(EXTRADEFINES) +AFLAGS += $(INCLUDES) $(EXTRADEFINES) + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +VPATH = chip:common:$(ARCH_SUBDIR) + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + @echo "LD: nuttx" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/avr/src/at32uc3/Kconfig b/arch/avr/src/at32uc3/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d12c0ad17de3978c89e8d50cc0110842eb2d4c77 --- /dev/null +++ b/arch/avr/src/at32uc3/Kconfig @@ -0,0 +1,202 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_AT32UC3 +comment "AT32U3 Configuration Options" + +choice + prompt "AT32U3 Processor Selection" + default ARCH_CHIP_AT32UC3B0256 + +config ARCH_CHIP_AT32UC3B064 + bool "AT32UC3B064" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B0 + +config ARCH_CHIP_AT32UC3B0128 + bool "AT32UC3B0128" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B0 + +config ARCH_CHIP_AT32UC3B0256 + bool "AT32UC3B0256" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B0 + +config ARCH_CHIP_AT32UC3B0512 + bool "AT32UC3B0512" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B0 + +config ARCH_CHIP_AT32UC3B164 + bool "AT32UC3B164" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B1 + +config ARCH_CHIP_AT32UC3B1128 + bool "AT32UC3B1128" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B1 + +config ARCH_CHIP_AT32UC3B1256 + bool "AT32UC3B1256" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B1 + +config ARCH_CHIP_AT32UC3B1512 + bool "AT32UC3B1512" + select ARCH_CHIP_AT32UC3B + select ARCH_CHIP_AT32UC3B1 + +endchoice # AT32U3 Processor Selection + +config ARCH_CHIP_AT32UC3A + bool + default n + +config ARCH_CHIP_AT32UC3B + bool + default n + +config ARCH_CHIP_AT32UC3B0 + bool + default n + +config ARCH_CHIP_AT32UC3B1 + bool + default n + +menu "AT32U3 Peripheral Selections" + +config AVR32_USART0 + bool "USART0" + default n + select ARCH_HAVE_USART0 + +config AVR32_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + +config AVR32_USART2 + bool "USART2" + default n + depends on ARCH_CHIP_AT32UC3B0 + select ARCH_HAVE_USART2 + +endmenu # AT32U3 Peripheral Selections + +if AVR32_USART0 + +choice + prompt "USART0 Function" + default AVR32_USART0_RS232 + +config AVR32_USART0_IRDA + bool "USART0 is IRDA" + +config AVR32_USART0_ISO786 + bool "USART0 is ISO786" + +config AVR32_USART0_MAN + bool "USART0 is Manchester" + +config AVR32_USART0_MODEM + bool "USART0 is Modem" + +config AVR32_USART0_RS232 + bool "USART0 is RS-232" + select USART0_ISUART + +config AVR32_USART0_RS485 + bool "USART0 is RS-485" + +config AVR32_USART0_SPI + bool "USART0 is SPI" + select SPI + +endchoice # USART0 Function +endif # AVR32_USART0 + +if AVR32_USART1 + +choice + prompt "USART1 Function" + default AVR32_USART1_RS232 + +config AVR32_USART1_IRDA + bool "USART1 is IRDA" + +config AVR32_USART1_ISO786 + bool "USART1 is ISO786" + +config AVR32_USART1_MAN + bool "USART1 is Manchester" + +config AVR32_USART1_MODEM + bool "USART1 is Modem" + +config AVR32_USART1_RS232 + bool "USART1 is RS-232" + select USART1_ISUART + +config AVR32_USART1_RS485 + bool "USART1 is RS-485" + +config AVR32_USART1_SPI + bool "USART1 is SPI" + select SPI + +endchoice # USART1 Function +endif # AVR32_USART1 + +if AVR32_USART2 + +choice + prompt "USART2 Function" + default AVR32_USART2_RS232 + +config AVR32_USART2_IRDA + bool "USART2 is IRDA" + +config AVR32_USART2_ISO786 + bool "USART2 is ISO786" + +config AVR32_USART2_MAN + bool "USART2 is Manchester" + +config AVR32_USART2_MODEM + bool "USART2 is Modem" + +config AVR32_USART2_RS232 + bool "USART2 is RS-232" + select USART2_ISUART + +config AVR32_USART2_RS485 + bool "USART2 is RS-485" + +config AVR32_USART2_SPI + bool "USART2 is SPI" + select SPI + +endchoice # USART2 Function +endif # AVR32_USART2 + +config AVR32_GPIOIRQ + bool "GPIO IRQ support" + default n + +if AVR32_GPIOIRQ + +config AVR32_GPIOIRQSETA + hex "GPIO IRQ set A" + default 0x0 + +config AVR32_GPIOIRQSETB + hex "GPIO IRQ set B" + default 0x0 + +endif # AVR32_GPIOIRQ +endif # ARCH_CHIP_AT32UC3 diff --git a/arch/avr/src/at32uc3/Make.defs b/arch/avr/src/at32uc3/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..0e1a98e2ae77676c1ffb62a1704c3a6021b193ab --- /dev/null +++ b/arch/avr/src/at32uc3/Make.defs @@ -0,0 +1,71 @@ +############################################################################ +# arch/avr/src/at32uc3/Make.defs +# +# Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = up_nommuhead.S + +# Common AVR/AVR32 files + +CMN_ASRCS = up_exceptions.S up_fullcontextrestore.S up_switchcontext.S +CMN_CSRCS = up_assert.c up_allocateheap.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c up_idle.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARCH_STACKDUMP),y) +CMN_CSRCS += up_dumpstate.c +endif + +# Required AT32UC3 files + +CHIP_ASRCS = +CHIP_CSRCS = at32uc3_clkinit.c at32uc3_gpio.c at32uc3_irq.c +CHIP_CSRCS += at32uc3_lowconsole.c at32uc3_lowinit.c at32uc3_serial.c + +# Configuration-dependent AT32UC3 files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += at32uc3_timerisr.c +endif + +ifeq ($(CONFIG_AVR32_GPIOIRQ),y) +CHIP_CSRCS += at32uc3_gpioirq.c +endif diff --git a/arch/avr/src/at32uc3/at32uc3.h b/arch/avr/src/at32uc3/at32uc3.h new file mode 100644 index 0000000000000000000000000000000000000000..47ecb3ad0333b6cfcffc65a0d72b47b7387dc066 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3.h @@ -0,0 +1,345 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3.h + * + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at32uc3_config.h" + +#ifdef CONFIG_AVR32_GPIOIRQ +# include +#endif + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bit-encoded input to at32uc3_configgpio() ********************************/ + +/* 16-bit Encoding: + * PERIPHERAL: FMMI UXXG PPPB BBBB with G=0 + * GPIO: FMMI UVOG PPPB BBBB with G=1 + */ + +/* Glitch Filter Enable: + * F... .... .... .... + */ + +#define GPIO_GLITCH (1 << 15) /* Bit 15: Glitch filter enable */ + +/* Interrupt modes (valid only if GPIO_INTR==1) + * .MM. .... .... .... + */ + +#define GPIO_INTMODE_SHIFT (13) /* Bits 13-14: Interrupt mode */ +#define GPIO_INTMODE_MASK (3 << GPIO_INTMODE_SHIFT) +# define GPIO_INTMODE_BOTH (0 << GPIO_INTMODE_SHIFT) +# define GPIO_INTMODE_RISING (1 << GPIO_INTMODE_SHIFT) +# define GPIO_INTMODE_FALLING (2 << GPIO_INTMODE_SHIFT) + +# define GPIO_IMR0 (1 << GPIO_INTMODE_SHIFT) +# define GPIO_IMR1 (2 << GPIO_INTMODE_SHIFT) + +/* Interrupt enable + * ...I .... .... .... + */ + +#define GPIO_INTR (1 << 12) /* Bit 12: Interrupt enable */ + +/* Pull-up enable + * .... U... .... .... + */ + +#define GPIO_PULLUP (1 << 11) /* Bit 11: Pull-up enable */ + +/* Output value (Valid only if GPIO_ENABLE and GPIO_OUTPUT) + * .... .V.. .... .... + */ + +#define GPIO_VALUE (1 << 10) /* Bit 10: Output value */ +#define GPIO_HIGH GPIO_VALUE +#define GPIO_LOW (0) + +/* Input/Ouptut (Valid only if GPIO_ENABLE) + * .... ..O. .... .... + */ + +#define GPIO_OUTPUT (1 << 9) /* Bit 9: Output driver enable */ +#define GPIO_INPUT (0) + +/* Peripheral MUX setting (valid only if GPIO_PERIPH) + * .... .XX. .... .... + */ + +#define GPIO_FUNC_SHIFT (9) /* Bits 9-10: Peripheral MUX */ +#define GPIO_FUNC_MASK (3 << GPIO_FUNC_SHIFT) +# define GPIO_FUNCA (0 << GPIO_FUNC_SHIFT) /* PMR0=0 PMR1=0 */ +# define GPIO_FUNCB (1 << GPIO_FUNC_SHIFT) /* PMR0=1 PMR1=0 */ +# define GPIO_FUNCC (2 << GPIO_FUNC_SHIFT) /* PMR0=0 PMR1=1 */ +# define GPIO_FUNCD (3 << GPIO_FUNC_SHIFT) /* PMR0=1 PMR1=1 */ + +# define GPIO_PMR0 (1 << GPIO_FUNC_SHIFT) +# define GPIO_PMR1 (2 << GPIO_FUNC_SHIFT) + +/* GPIO Enable (1) or Peripheral Enable (0) + * .... .... .... .... .... ...G .... .... + */ + +#define GPIO_ENABLE (1 << 8) /* Bit 8: GPIO enable */ +#define GPIO_PERIPH (0) + + +/* Port Number + * .... .... .... .... .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bits 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) + +/* Pin number: + * .... .... .... .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: Port number */ +#define GPIO_PIN_MASK (0x1f << GPIO_PIN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_clkinit + * + * Description: + * Initialiaze clock/PLL settings per the definitions in the board.h file. + * + ****************************************************************************/ + +void up_clkinitialize(void); + +/**************************************************************************** + * Name: usart_reset + * + * Description: + * Reset a USART. + * + ****************************************************************************/ + +void usart_reset(uintptr_t usart_base); + +/**************************************************************************** + * Name: usart_configure + * + * Description: + * Configure a USART as a RS-232 UART. + * + ****************************************************************************/ + +void usart_configure(uintptr_t usart_base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2); + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initializeation sequence to configure the serial console + * uart (only). + * + ****************************************************************************/ + +void up_consoleinit(void); + +/**************************************************************************** + * Name: at32uc3_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the + * directory configs//src. + * + ****************************************************************************/ + +void at32uc3_boardinitialize(void); + +/**************************************************************************** + * Name: at32uc3_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int at32uc3_configgpio(uint16_t cfgset); + +/**************************************************************************** + * Name: at32uc3_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void at32uc3_gpiowrite(uint16_t pinset, bool value); + +/**************************************************************************** + * Name: at32uc3_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool at32uc3_gpioread(uint16_t pinset); + +/**************************************************************************** + * Name: gpio_irqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler + * + * Configuration Notes: + * Configuration CONFIG_AVR32_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature and CONFIG_AVR32_GPIOIRQSETA and/or + * CONFIG_AVR32_GPIOIRQSETB must be enabled to select GPIOs to support + * interrupts on. + * + * Assumptions: + * Called during the early boot sequence before global interrupts have + * been enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR32_GPIOIRQ +void weak_function gpio_irqinitialize(void); +#endif + +/**************************************************************************** + * Name: gpio_irqattach + * + * Description: + * Attach in GPIO interrupt to the provide 'isr' + * + * Configuration Notes: + * Configuration CONFIG_AVR32_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature and CONFIG_AVR32_GPIOIRQSETA and/or + * CONFIG_AVR32_GPIOIRQSETB must be enabled to select GPIOs to support + * interrupts on. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR32_GPIOIRQ +int gpio_irqattach(int irq, xcpt_t newisr, xcpt_t *oldisr); +#endif + +/**************************************************************************** + * Name: gpio_irqenable + * + * Description: + * Enable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR32_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature and CONFIG_AVR32_GPIOIRQSETA and/or + * CONFIG_AVR32_GPIOIRQSETB must be enabled to select GPIOs to support + * interrupts on. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR32_GPIOIRQ +void gpio_irqenable(int irq); +#endif + +/**************************************************************************** + * Name: gpio_irqdisable + * + * Description: + * Disable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR32_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature and CONFIG_AVR32_GPIOIRQSETA and/or + * CONFIG_AVR32_GPIOIRQSETB must be enabled to select GPIOs to support + * interrupts on. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR32_GPIOIRQ +void gpio_irqdisable(int irq); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_abdac.h b/arch/avr/src/at32uc3/at32uc3_abdac.h new file mode 100644 index 0000000000000000000000000000000000000000..b2f01e30c80f3d231b954011703e3dbdc9777d3e --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_abdac.h @@ -0,0 +1,101 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_abdac.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_ABDAC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_ABDAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_ABDAC_SDR_OFFSET 0x00 /* Sample Data Register */ +#define AVR32_ABDAC_CR_OFFSET 0x08 /* Control Register */ +#define AVR32_ABDAC_IMR_OFFSET 0x0c /* Interrupt Mask Register */ +#define AVR32_ABDAC_IER_OFFSET 0x10 /* Interrupt Enable Register */ +#define AVR32_ABDAC_IDR_OFFSET 0x14 /* Interrupt Disable Register */ +#define AVR32_ABDAC_ICR_OFFSET 0x18 /* Interrupt Clear Register */ +#define AVR32_ABDAC_ISR_OFFSET 0x1c /* Interrupt Status Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_ABDAC_SDR (AVR32_ABDAC_BASE+AVR32_ABDAC_SDR_OFFSET) +#define AVR32_ABDAC_CR (AVR32_ABDAC_BASE+AVR32_ABDAC_CR_OFFSET) +#define AVR32_ABDAC_IMR (AVR32_ABDAC_BASE+AVR32_ABDAC_IMR_OFFSET) +#define AVR32_ABDAC_IER (AVR32_ABDAC_BASE+AVR32_ABDAC_IER_OFFSET) +#define AVR32_ABDAC_IDR (AVR32_ABDAC_BASE+AVR32_ABDAC_IDR_OFFSET) +#define AVR32_ABDAC_ICR (AVR32_ABDAC_BASE+AVR32_ABDAC_ICR_OFFSET) +#define AVR32_ABDAC_ISR (AVR32_ABDAC_BASE+AVR32_ABDAC_ISR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Sample Data Register Bit-field Definitions */ +/* This register contains a 32-bit data and, hence, has no bit-fiels */ + +/* Control Register Bit-field Definitions */ + +#define ABDAC_CR_SWAP (1 << 30) /* Bit 30: Swap Channels */ +#define ABDAC_CR_EN (1 << 31) /* Bit 31: Enable Audio Bitstream DAC */ + +/* Interrupt Mask Register Bit-field Definitions */ +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Clear Register Bit-field Definitions */ +/* Interrupt Status Register Bit-field Definitions */ + +#define ABDAC_INT_UNDERRUN (1 << 28) /* Bit 28: Underrun Interrupt Status */ +#define ABDAC_INT_TXREADY (1 << 29) /* Bit 29 TX Ready Interrupt Status */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_ABDAC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_adc.h b/arch/avr/src/at32uc3/at32uc3_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..37b1456b49768421878f16827c50a03cfc8ddf8a --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_adc.h @@ -0,0 +1,195 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_adc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_ADC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_ADC_CR_OFFSET 0x000 /* Control Register */ +#define AVR32_ADC_MR_OFFSET 0x004 /* Mode Register */ +#define AVR32_ADC_CHER_OFFSET 0x010 /* Channel Enable Register */ +#define AVR32_ADC_CHDR_OFFSET 0x014 /* Channel Disable Register */ +#define AVR32_ADC_CHSR_OFFSET 0x018 /* Channel Status Register */ +#define AVR32_ADC_SR_OFFSET 0x01c /* Status Register */ +#define AVR32_ADC_LCDR_OFFSET 0x020 /* Last Converted Data Register */ +#define AVR32_ADC_IER_OFFSET 0x024 /* Interrupt Enable Register */ +#define AVR32_ADC_IDR_OFFSET 0x028 /* Interrupt Disable Register */ +#define AVR32_ADC_IMR_OFFSET 0x02c /* Interrupt Mask Register */ +#define AVR32_ADC_CDR_OFFSET(n) (0x030+((n)<<2)) +#define AVR32_ADC_CDR0_OFFSET 0x030 /* Channel Data Register 0 */ +#define AVR32_ADC_CDR1_OFFSET 0x034 /* Channel Data Register 1 */ +#define AVR32_ADC_CDR2_OFFSET 0x038 /* Channel Data Register 2 */ +#define AVR32_ADC_CDR3_OFFSET 0x03c /* Channel Data Register 3 */ +#define AVR32_ADC_CDR4_OFFSET 0x040 /* Channel Data Register 4 */ +#define AVR32_ADC_CDR5_OFFSET 0x044 /* Channel Data Register 5 */ +#define AVR32_ADC_CDR6_OFFSET 0x048 /* Channel Data Register 6 */ +#define AVR32_ADC_CDR7_OFFSET 0x04c /* Channel Data Register 7 */ +#define AVR32_ADC_VERSION_OFFSET 0x0fc /* Version Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_ADC_CR (AVR32_ADC_BASE+AVR32_ADC_CR_OFFSET) +#define AVR32_ADC_MR (AVR32_ADC_BASE+AVR32_ADC_MR_OFFSET) +#define AVR32_ADC_CHER (AVR32_ADC_BASE+AVR32_ADC_CHER_OFFSET) +#define AVR32_ADC_CHDR (AVR32_ADC_BASE+AVR32_ADC_CHDR_OFFSET) +#define AVR32_ADC_CHSR (AVR32_ADC_BASE+AVR32_ADC_CHSR_OFFSET) +#define AVR32_ADC_SR (AVR32_ADC_BASE+AVR32_ADC_SR_OFFSET) +#define AVR32_ADC_LCDR (AVR32_ADC_BASE+AVR32_ADC_LCDR_OFFSET) +#define AVR32_ADC_IER (AVR32_ADC_BASE+AVR32_ADC_IER_OFFSET) +#define AVR32_ADC_IDR (AVR32_ADC_BASE+AVR32_ADC_IDR_OFFSET) +#define AVR32_ADC_IMR (AVR32_ADC_BASE+AVR32_ADC_IMR_OFFSET) +#define AVR32_ADC_CDR(n) (AVR32_ADC_BASE+AVR32_ADC_CDR_OFFSET(n)) +#define AVR32_ADC_CDR0 (AVR32_ADC_BASE+AVR32_ADC_CDR0_OFFSET) +#define AVR32_ADC_CDR1 (AVR32_ADC_BASE+AVR32_ADC_CDR1_OFFSET) +#define AVR32_ADC_CDR2 (AVR32_ADC_BASE+AVR32_ADC_CDR2_OFFSET) +#define AVR32_ADC_CDR3 (AVR32_ADC_BASE+AVR32_ADC_CDR3_OFFSET) +#define AVR32_ADC_CDR4 (AVR32_ADC_BASE+AVR32_ADC_CDR4_OFFSET) +#define AVR32_ADC_CDR5 (AVR32_ADC_BASE+AVR32_ADC_CDR5_OFFSET) +#define AVR32_ADC_CDR6 (AVR32_ADC_BASE+AVR32_ADC_CDR6_OFFSET) +#define AVR32_ADC_CDR7 (AVR32_ADC_BASE+AVR32_ADC_CDR7_OFFSET) +#define AVR32_ADC_VERSION (AVR32_ADC_BASE+AVR32_ADC_VERSION_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register Bit-field Definitions */ + +#define ADC_CR_SWRST (1 << 0) /* Bit 0: Software Reset */ +#define ADC_CR_START (1 << 1) /* Bit 1: Start Conversion */ + +/* Mode Register Bit-field Definitions */ + +#define ADC_MR_TRGEN (1 << 0) /* Bit 0: Trigger Enable */ +#define ADC_MR_TRGSEL_SHIFT (1) /* Bits 1-3: Trigger Selection */ +#define ADC_MR_TRGSEL_MASK (7 << ADC_MR_TRGSEL_SHIFT) +# define ADC_MR_TRGSEL_TRIG(n) ((n) << ADC_MR_TRGSEL_SHIFT) /* Internal trigger n */ +# define ADC_MR_TRGSEL_TRIG0 (0 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 0 */ +# define ADC_MR_TRGSEL_TRIG1 (1 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 1 */ +# define ADC_MR_TRGSEL_TRIG2 (2 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 2 */ +# define ADC_MR_TRGSEL_TRIG3 (3 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 3 */ +# define ADC_MR_TRGSEL_TRIG4 (4 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 4 */ +# define ADC_MR_TRGSEL_TRIG5 (5 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 5 */ +# define ADC_MR_TRGSEL_TRIG6 (6 << ADC_MR_TRGSEL_SHIFT) /* Internal trigger 6 */ +# define ADC_MR_TRGSEL_EXT (7 << ADC_MR_TRGSEL_SHIFT) /* External trigger */ +#define ADC_MR_LOWRES (1 << 4) /* Bit 4: Resolution */ +#define ADC_MR_SLEEP (1 << 5) /* Bit 5: Sleep Mode */ +#define ADC_MR_PRESCAL_SHIFT (8) /* Bits 8-15: Prescaler Rate Selection */ +#define ADC_MR_PRESCAL_MASK (0xff << ADC_MR_PRESCAL_SHIFT) +#define ADC_MR_STARTUP_SHIFT (16) /* Bits 16-22: Start Up Time */ +#define ADC_MR_STARTUP_MASK (0x7f << ADC_MR_STARTUP_SHIFT) +#define ADC_MR_SHTIM_SHIFT (24) /* Bits 24-27 Sample & Hold Time */ +#define ADC_MR_SHTIM_MASK (15 << ADC_MR_SHTIM_SHIFT) + +/* Channel Enable Register Bit-field Definitions */ +/* Channel Disable Register Bit-field Definitions */ +/* Channel Status Register Bit-field Definitions */ + +#define ADC_CHAN(n) (1 << (n)) +#define ADC_CHAN0 (1 << 0) +#define ADC_CHAN1 (1 << 1) +#define ADC_CHAN2 (1 << 2) +#define ADC_CHAN3 (1 << 3) +#define ADC_CHAN4 (1 << 4) +#define ADC_CHAN5 (1 << 5) +#define ADC_CHAN6 (1 << 6) +#define ADC_CHAN7 (1 << 7) + +/* Status Register Bit-field Definitions */ +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ + +#define ADC_INT_EOC(n) (1 << (n)) +#define ADC_INT_EOC0 (1 << 0) /* Bit 0: End of Conversion 0 */ +#define ADC_INT_EOC1 (1 << 1) /* Bit 1: End of Conversion 1 */ +#define ADC_INT_EOC2 (1 << 2) /* Bit 2: End of Conversion 2 */ +#define ADC_INT_EOC3 (1 << 3) /* Bit 3: End of Conversion 3 */ +#define ADC_INT_EOC4 (1 << 4) /* Bit 4: End of Conversion 4 */ +#define ADC_INT_EOC5 (1 << 5) /* Bit 5: End of Conversion 5 */ +#define ADC_INT_EOC6 (1 << 6) /* Bit 6: End of Conversion 6 */ +#define ADC_INT_EOC7 (1 << 7) /* Bit 7: End of Conversion 7 */ +#define ADC_INT_OVRE(n) (1 << ((n)+8)) +#define ADC_INT_OVRE0 (1 << 8) /* Bit 8: Overrun Error 0 */ +#define ADC_INT_OVRE1 (1 << 9) /* Bit 9: Overrun Error 1 */ +#define ADC_INT_OVRE2 (1 << 10) /* Bit 10: Overrun Error 2 */ +#define ADC_INT_OVRE3 (1 << 11) /* Bit 11: Overrun Error 3 */ +#define ADC_INT_OVRE4 (1 << 12) /* Bit 12: Overrun Error 4 */ +#define ADC_INT_OVRE5 (1 << 13) /* Bit 13: Overrun Error 5 */ +#define ADC_INT_OVRE6 (1 << 14) /* Bit 14: Overrun Error 6 */ +#define ADC_INT_OVRE7 (1 << 15) /* Bit 15: Overrun Error 7 */ +#define ADC_INT_DRDY (1 << 16) /* Bit 16: Data Ready */ +#define ADC_INT_GOVRE (1 << 17) /* Bit 17: General Overrun Error */ +#define ADC_INT_ENDRX (1 << 18) /* Bit 18: End of RX Buffer */ +#define ADC_INT_RXBUFF (1 << 19) /* Bit 19: RX Buffer Full */ + +/* Last Converted Data Register Bit-field Definitions */ + +#define ADC_LCDR_MASK (0x3ff) + +/* Channel Data Registers 0-7 Bit-field Definitions */ + +#define ADC_CDR_MASK (0x3ff) + +/* Version Register Bit-field Definitions */ + +#define ADC_VERSION_SHIFT (0) /* Bits 0-11: Version Number */ +#define ADC_VERSION_MASK (0xfff << ADC_VERSION_SHIFT) +#define ADC_VERSION_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define ADC_VERSION_VARIANT_MASK (15 << ADC_VERSION_VARIANT_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_ADC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_clkinit.c b/arch/avr/src/at32uc3/at32uc3_clkinit.c new file mode 100644 index 0000000000000000000000000000000000000000..7ee14cdc6c38a29a04d7d503f792e0c98f6a5b1a --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_clkinit.c @@ -0,0 +1,505 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_clkinit.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_arch.h" + +#include "at32uc3_config.h" +#include "up_internal.h" +#include "at32uc3.h" +#include "at32uc3_pm.h" +#include "at32uc3_flashc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(AVR32_CLOCK_OSC0) || \ + (defined (AVR32_CLOCK_PLL0) && defined(AVR32_CLOCK_PLL0_OSC0)) || \ + (defined (AVR32_CLOCK_PLL1) && defined(AVR32_CLOCK_PLL1_OSC0)) +# define NEED_OSC0 +#endif + +#if defined(AVR32_CLOCK_OSC1) || \ + (defined (AVR32_CLOCK_PLL0) && defined(AVR32_CLOCK_PLL0_OSC1)) || \ + (defined (AVR32_CLOCK_PLL1) && defined(AVR32_CLOCK_PLL1_OSC1)) +# define NEED_OSC1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_enableosc32 + * + * Description: + * Initialiaze the 32KHz oscillaor. This oscillaor is used by the RTC + * logic to provide the sysem timer. + * + ****************************************************************************/ + +#ifdef AVR32_CLOCK_OSC32 +static inline void up_enableosc32(void) +{ + uint32_t regval; + + /* Select the 32KHz oscillator crystal */ + + regval = getreg32(AVR32_PM_OSCCTRL32); + regval &= ~PM_OSCCTRL32_MODE_MASK; + regval |= PM_OSCCTRL32_MODE_XTAL; + putreg32(regval, AVR32_PM_OSCCTRL32); + + /* Enable the 32-kHz clock */ + + regval = getreg32(AVR32_PM_OSCCTRL32); + regval &= ~PM_OSCCTRL32_STARTUP_MASK; + regval |= PM_OSCCTRL32_EN | (AVR32_OSC32STARTUP << PM_OSCCTRL32_STARTUP_SHIFT); + putreg32(regval, AVR32_PM_OSCCTRL32); +} +#endif + +/**************************************************************************** + * Name: up_enableosc0 + * + * Description: + * Initialiaze OSC0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef NEED_OSC0 +static inline void up_enableosc0(void) +{ + uint32_t regval; + + /* Enable OSC0 in the correct crystal mode by setting the mode value in OSCCTRL0 */ + + regval = getreg32(AVR32_PM_OSCCTRL0); + regval &= ~PM_OSCCTRL_MODE_MASK; +#if AVR32_FOSC0 < 900000 + regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */ +#elif AVR32_FOSC0 < 3000000 + regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */ +#elif AVR32_FOSC0 < 8000000 + regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */ +#else + regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */ +#endif + putreg32(regval, AVR32_PM_OSCCTRL0); + + /* Enable OSC0 using the startup time provided in board.h. This startup time + * is critical and depends on the characteristics of the crystal. + */ + + regval = getreg32(AVR32_PM_OSCCTRL0); + regval &= ~PM_OSCCTRL_STARTUP_MASK; + regval |= (AVR32_OSC0STARTUP << PM_OSCCTRL_STARTUP_SHIFT); + putreg32(regval, AVR32_PM_OSCCTRL0); + + /* Enable OSC0 */ + + regval = getreg32(AVR32_PM_MCCTRL); + regval |= PM_MCCTRL_OSC0EN; + putreg32(regval, AVR32_PM_MCCTRL); + + /* Wait for OSC0 to be ready */ + + while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_OSC0RDY) == 0); +} +#endif + +/**************************************************************************** + * Name: up_enableosc1 + * + * Description: + * Initialiaze OSC0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef NEED_OSC1 +static inline void up_enableosc1(void) +{ + uint32_t regval; + + /* Enable OSC1 in the correct crystal mode by setting the mode value in OSCCTRL1 */ + + regval = getreg32(AVR32_PM_OSCCTRL1); + regval &= ~PM_OSCCTRL_MODE_MASK; +#if AVR32_FOSC1 < 900000 + regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */ +#elif AVR32_FOSC1 < 3000000 + regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */ +#elif AVR32_FOSC1 < 8000000 + regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */ +#else + regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */ +#endif + putreg32(regval, AVR32_PM_OSCCTRL1); + + /* Enable OSC1 using the startup time provided in board.h. This startup time + * is critical and depends on the characteristics of the crystal. + */ + + regval = getreg32(AVR32_PM_OSCCTRL1); + regval &= ~PM_OSCCTRL_STARTUP_MASK; + regval |= (AVR32_OSC1STARTUP << PM_OSCCTRL_STARTUP_SHIFT); + putreg32(regval, AVR32_PM_OSCCTRL1); + + /* Enable OSC1 */ + + regval = getreg32(AVR32_PM_MCCTRL); + regval |= PM_MCCTRL_OSC1EN; + putreg32(regval, AVR32_PM_MCCTRL); + + /* Wait for OSC1 to be ready */ + + while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_OSC1RDY) == 0); +} +#endif + +/**************************************************************************** + * Name: up_enablepll0 + * + * Description: + * Initialiaze PLL0 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef AVR32_CLOCK_PLL0 +static inline void up_enablepll0(void) +{ + /* Setup PLL0 */ + + regval = (AVR32_PLL0_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL0_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT) + + /* Select PLL0/1 oscillator */ + +#ifdef AVR32_CLOCK_PLL0_OSC1 + regval |= PM_PLL_PLLOSC; +#endif + + putreg32(regval, AVR32_PM_PLL0); + + /* Set PLL0 options */ + + regval = getreg32(AVR32_PM_PLL0); + regval &= ~PM_PLL_PLLOPT_MASK +#if AVR32_PLL0_FREQ < 160000000 + regval |= PM_PLL_PLLOPT_VCO; +#endif +#if AVR32_PLL0_DIV2 != 0 + regval |= PM_PLL_PLLOPT_XTRADIV; +#endif +#if AVR32_PLL0_WBWM != 0 + regval |= PM_PLL_PLLOPT_WBWDIS; +#endif + putreg32(regval, AVR32_PM_PLL0) + + /* Enable PLL0 */ + + regval = getreg32(AVR32_PM_PLL0); + regval |= PM_PLL_PLLEN; + putreg32(regval, AVR32_PM_PLL0) + + /* Wait for PLL0 locked. */ + + while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_LOCK0) == 0); +} +#endif + +/**************************************************************************** + * Name: up_enablepll1 + * + * Description: + * Initialiaze PLL1 settings per the definitions in the board.h file. + * + ****************************************************************************/ + +#ifdef AVR32_CLOCK_PLL1 +static inline void up_enablepll1(void) +{ + /* Setup PLL1 */ + + regval = (AVR32_PLL1_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL1_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT) + + /* Select PLL0/1 oscillator */ + +#ifdef AVR32_CLOCK_PLL1_OSC1 + regval |= PM_PLL_PLLOSC; +#endif + + putreg32(regval, AVR32_PM_PLL1); + + /* Set PLL1 options */ + + regval = getreg32(AVR32_PM_PLL1); + regval &= ~PM_PLL_PLLOPT_MASK +#if AVR32_PLL1_FREQ < 160000000 + regval |= PM_PLL_PLLOPT_VCO; +#endif +#if AVR32_PLL1_DIV2 != 0 + regval |= PM_PLL_PLLOPT_XTRADIV; +#endif +#if AVR32_PLL1_WBWM != 0 + regval |= PM_PLL_PLLOPT_WBWDIS; +#endif + putreg32(regval, AVR32_PM_PLL1) + + /* Enable PLL1 */ + + regval = getreg32(AVR32_PM_PLL1); + regval |= PM_PLL_PLLEN; + putreg32(regval, AVR32_PM_PLL1) + + /* Wait for PLL1 locked. */ + + while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_LOCK1) == 0); +} +#endif + +/**************************************************************************** + * Name: up_clksel + * + * Description: + * Configure derived clocks. + * + ****************************************************************************/ + +static inline void up_clksel(void) +{ + uint32_t regval = 0; + +#if AVR32_CKSEL_CPUDIV != 0 + regval |= PM_CKSEL_CPUDIV; + regval |= (AVR32_CKSEL_CPUDIV << PM_CKSEL_CPUSEL_SHIFT) +#endif + +#if AVR32_CKSEL_HSBDIV != 0 + regval |= PM_CKSEL_HSBDIV; + regval |= (AVR32_CKSEL_HSBDIV << PM_CKSEL_HSBSEL_SHIFT) +#endif + +#if AVR32_CKSEL_PBADIV != 0 + regval |= PM_CKSEL_PBADIV; + regval |= (AVR32_CKSEL_PBADIV << PM_CKSEL_PBASEL_SHIFT) +#endif + +#if AVR32_CKSEL_PBBDIV != 0 + regval |= PM_CKSEL_PBBDIV; + regval |= (AVR32_CKSEL_PBBDIV << PM_CKSEL_PBBSEL_SHIFT) +#endif + + putreg32(regval, AVR32_PM_CKSEL); + + /* Wait for CLKRDY */ + + while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_CKRDY) == 0); +} + +/**************************************************************************** + * Name: up_fws + * + * Description: + * Setup FLASH wait states. + * + ****************************************************************************/ + +static void up_fws(uint32_t cpuclock) +{ + uint32_t regval; + + regval = getreg32(AVR32_FLASHC_FCR); + if (cpuclock > AVR32_FLASHC_FWS0_MAXFREQ) + { + regval |= FLASHC_FCR_FWS; + } + else + { + regval &= ~FLASHC_FCR_FWS; + } + putreg32(regval, AVR32_FLASHC_FCR); +} + +/**************************************************************************** + * Name: up_mainclk + * + * Description: + * Select the main clock. + * + ****************************************************************************/ + +static inline void up_mainclk(uint32_t mcsel) +{ + uint32_t regval; + + regval = getreg32(AVR32_PM_MCCTRL); + regval &= ~PM_MCCTRL_MCSEL_MASK; + regval |= mcsel; + putreg32(regval, AVR32_PM_MCCTRL); +} + +/**************************************************************************** + * Name: up_usbclock + * + * Description: + * Setup the USBB GCLK. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV +static inline void up_usbclock(void) +{ + uint32_t regval = 0; + +#if defined(AVR32_CLOCK_USB_PLL0) || defined(AVR32_CLOCK_USB_PLL1) + regval |= PM_GCCTRL_PLLSEL; +#endif +#if defined(AVR32_CLOCK_USB_OSC1) || defined(AVR32_CLOCK_USB_PLL1) + regval |= PM_GCCTRL_OSCSEL; +#endif +#if AVR32_CLOCK_USB_DIV > 0 + + + u_avr32_pm_gcctrl.GCCTRL.diven = diven; + u_avr32_pm_gcctrl.GCCTRL.div = div; +#endif + putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB)) + + /* Enable USB GCLK */ + + regval = getreg32(AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB)) + regval |= PM_GCCTRL_CEN; + putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB)) +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_clkinit + * + * Description: + * Initialiaze clock/PLL settings per the definitions in the board.h + * file. + * + ****************************************************************************/ + +void up_clkinitialize(void) +{ +#ifdef AVR32_CLOCK_OSC32 + /* Enable the 32KHz oscillator (need by the RTC module) */ + + up_enableosc32(); +#endif + +#ifdef NEED_OSC0 + /* Enable OSC0 using the settings in board.h */ + + up_enableosc0(); + + /* Set up FLASH wait states */ + + up_fws(AVR32_FOSC0); + + /* Then switch the main clock to OSC0 */ + + up_mainclk(PM_MCCTRL_MCSEL_OSC0); +#endif + +#ifdef NEED_OSC1 + /* Enable OSC1 using the settings in board.h */ + + up_enableosc1(); +#endif + +#ifdef AVR32_CLOCK_PLL0 + /* Enable PLL0 using the settings in board.h */ + + up_enablepll0(); + + /* Set up FLASH wait states */ + + up_fws(AVR32_CPU_CLOCK); + + /* Then switch the main clock to PLL0 */ + + up_mainclk(PM_MCCTRL_MCSEL_PLL0); +#endif + +#ifdef AVR32_CLOCK_PLL1 + /* Enable PLL1 using the settings in board.h */ + + up_enablepll1(); +#endif + + /* Configure derived clocks */ + + up_clksel(); + + /* Set up the USBB GCLK */ + +#ifdef CONFIG_USBDEV + void up_usbclock(); +#endif +} + + + diff --git a/arch/avr/src/at32uc3/at32uc3_config.h b/arch/avr/src/at32uc3/at32uc3_config.h new file mode 100644 index 0000000000000000000000000000000000000000..8867fae8694fde919916dc149f27fdd50d85549f --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_config.h @@ -0,0 +1,210 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_config.h + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_CONFIG_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* USART can be configured as a number of different devices (Only UART is supported + * here now, that will be extended). Check for consistency between USART enable + * options. + */ + +#if AVR32_NUSART < 1 +# undef CONFIG_AVR32_USART0 +# undef CONFIG_AVR32_USART1 +# undef CONFIG_AVR32_USART2 +#endif +#if AVR32_NUSART < 2 +# undef CONFIG_AVR32_USART1 +# undef CONFIG_AVR32_USART2 +#endif +#if AVR32_NUSART < 3 +# undef CONFIG_AVR32_USART2 +#endif + +/* Not all USART features are supported on all chips or all USARTS */ + +#ifdef CONFIG_ARCH_CHIP_AT32UC3B +# undef CONFIG_AVR32_USART0_RS485 +# undef CONFIG_AVR32_USART0_MAN +# undef CONFIG_AVR32_USART0_MODEM +# undef CONFIG_AVR32_USART0_IRDA +# undef CONFIG_AVR32_USART0_ISO786 +# undef CONFIG_AVR32_USART1_RS485 +# undef CONFIG_AVR32_USART2_RS485 +# undef CONFIG_AVR32_USART2_MAN +# undef CONFIG_AVR32_USART2_MODEM +# undef CONFIG_AVR32_USART2_IRDA +# undef CONFIG_AVR32_USART2_ISO786 +#endif + +/* Disable configurations if USART not selected in configuration file */ + +#ifndef CONFIG_AVR32_USART0 +# undef CONFIG_AVR32_USART0_RS232 +# undef CONFIG_AVR32_USART0_SPI +# undef CONFIG_AVR32_USART0_RS485 +# undef CONFIG_AVR32_USART0_MAN +# undef CONFIG_AVR32_USART0_MODEM +# undef CONFIG_AVR32_USART0_IRDA +# undef CONFIG_AVR32_USART0_ISO786 +#endif + +#ifndef CONFIG_AVR32_USART1 +# undef CONFIG_AVR32_USART1_RS232 +# undef CONFIG_AVR32_USART1_SPI +# undef CONFIG_AVR32_USART1_RS485 +# undef CONFIG_AVR32_USART1_MAN +# undef CONFIG_AVR32_USART1_MODEM +# undef CONFIG_AVR32_USART1_IRDA +# undef CONFIG_AVR32_USART1_ISO786 +#endif + +#ifndef CONFIG_AVR32_USART2 +# undef CONFIG_AVR32_USART2_RS232 +# undef CONFIG_AVR32_USART2_SPI +# undef CONFIG_AVR32_USART2_RS485 +# undef CONFIG_AVR32_USART2_MAN +# undef CONFIG_AVR32_USART2_MODEM +# undef CONFIG_AVR32_USART2_IRDA +# undef CONFIG_AVR32_USART2_ISO786 +#endif + +/* Is any UART configured? */ + +#if defined(CONFIG_AVR32_USART0_RS232) || \ + defined(CONFIG_AVR32_USART1_RS232) || \ + defined(CONFIG_AVR32_USART2_RS232) +# define HAVE_RS232_DEVICE +#else +# undef HAVE_RS232_DEVICE +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_AVR32_USART0_RS232) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_AVR32_USART1_RS232) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_AVR32_USART2_RS232) +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(HAVE_RS232_DEVICE) +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# else +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* If GPIO IRQ support is defined, then a set of GPIOs must all be included */ + +#if CONFIG_AVR32_GPIOIRQSETA == 0 && CONFIG_AVR32_GPIOIRQSETB == 0 +# undef CONFIG_AVR32_GPIOIRQ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_CONFIG_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_eic.h b/arch/avr/src/at32uc3/at32uc3_eic.h new file mode 100644 index 0000000000000000000000000000000000000000..44c050b2b47400a655ef3bc0caa5197a0ac552df --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_eic.h @@ -0,0 +1,133 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_eic.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_EIC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_EIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_EIC_IER_OFFSET 0x000 /* Interrupt Enable Register */ +#define AVR32_EIC_IDR_OFFSET 0x004 /* Interrupt Disable Register */ +#define AVR32_EIC_IMR_OFFSET 0x008 /* Interrupt Mask Register */ +#define AVR32_EIC_ISR_OFFSET 0x00c /* Interrupt Status Register */ +#define AVR32_EIC_ICR_OFFSET 0x010 /* Interrupt Clear Register */ +#define AVR32_EIC_MODE_OFFSET 0x014 /* Mode Register */ +#define AVR32_EIC_EDGE_OFFSET 0x018 /* Edge Register */ +#define AVR32_EIC_LEVEL_OFFSET 0x01c /* Level Register */ +#define AVR32_EIC_FILTER_OFFSET 0x020 /* Filter Register */ +#define AVR32_EIC_TEST_OFFSET 0x024 /* Test Register */ +#define AVR32_EIC_ASYNC_OFFSET 0x028 /* Asynchronous Register */ +#define AVR32_EIC_SCAN_OFFSET 0x02c /* Scan Register */ +#define AVR32_EIC_EN_OFFSET 0x030 /* Enable Register */ +#define AVR32_EIC_DIS_OFFSET 0x034 /* Disable Register */ +#define AVR32_EIC_CTRL_OFFSET 0x038 /* Control Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_EIC_IER (AVR32_EIC_BASE+AVR32_EIC_IER_OFFSET) +#define AVR32_EIC_IDR (AVR32_EIC_BASE+AVR32_EIC_IDR_OFFSET) +#define AVR32_EIC_IMR (AVR32_EIC_BASE+AVR32_EIC_IMR_OFFSET) +#define AVR32_EIC_ISR (AVR32_EIC_BASE+AVR32_EIC_ISR_OFFSET) +#define AVR32_EIC_ICR (AVR32_EIC_BASE+AVR32_EIC_ICR_OFFSET) +#define AVR32_EIC_MODE (AVR32_EIC_BASE+AVR32_EIC_MODE_OFFSET) +#define AVR32_EIC_EDGE (AVR32_EIC_BASE+AVR32_EIC_EDGE_OFFSET) +#define AVR32_EIC_LEVEL (AVR32_EIC_BASE+AVR32_EIC_LEVEL_OFFSET) +#define AVR32_EIC_FILTER (AVR32_EIC_BASE+AVR32_EIC_FILTER_OFFSET) +#define AVR32_EIC_TEST (AVR32_EIC_BASE+AVR32_EIC_TEST_OFFSET) +#define AVR32_EIC_ASYNC (AVR32_EIC_BASE+AVR32_EIC_ASYNC_OFFSET) +#define AVR32_EIC_SCAN (AVR32_EIC_BASE+AVR32_EIC_SCAN_OFFSET) +#define AVR32_EIC_EN (AVR32_EIC_BASE+AVR32_EIC_EN_OFFSET) +#define AVR32_EIC_DIS (AVR32_EIC_BASE+AVR32_EIC_DIS_OFFSET) +#define AVR32_EIC_CTRL (AVR32_EIC_BASE+AVR32_EIC_CTRL_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ +/* Interrupt Status Register Bit-field Definitions */ +/* Interrupt Clear Register Bit-field Definitions */ +/* Mode Register Bit-field Definitions */ +/* Edge Register Bit-field Definitions */ +/* Level Register Bit-field Definitions */ +/* Filter Register Bit-field Definitions */ +/* Test Register Bit-field Definitions */ +/* Asynchronous Register Bit-field Definitions */ +/* Enable Register Bit-field Definitions */ +/* Disable Register Bit-field Definitions */ +/* Control Register Bit-field Definitions */ + +#define EIC_INT0 (1 << 0) /* Bit 0: External interrupt 0 */ +#define EIC_INT1 (1 << 1) /* Bit 1: External interrupt 1 */ +#define EIC_INT2 (1 << 2) /* Bit 2: External interrupt 2 */ +#define EIC_INT3 (1 << 3) /* Bit 3: External interrupt 3 */ +#define EIC_INT4 (1 << 4) /* Bit 4: External interrupt 4 */ +#define EIC_INT5 (1 << 5) /* Bit 5: External interrupt 5 */ +#define EIC_INT6 (1 << 6) /* Bit 6: External interrupt 6 */ +#define EIC_INT7 (1 << 7) /* Bit 7: External interrupt 7 */ +#define EIC_NMI (1 << 8) /* Bit 8: NMI */ + +/* Scan Register Bit-field Definitions */ + +#define EIC_SCAN_PIN_SHIFT (24) /* Bit 24-26: Currently active scan pin */ +#define EIC_SCAN_PIN_MASK (7 << EIC_SCAN_PIN_SHIFT) +#define EIC_SCAN_PRESC_SHIFT (8) /* Bit 8-12: Prescale select for keypad scan rate */ +#define EIC_SCAN_PRESC_MASK (0x1f << EIC_SCAN_PRESC_SHIFT) +#define EIC_SCAN_EN (1 << 0) /* Bit 0: Enable keypad scanning */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_EIC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_flashc.h b/arch/avr/src/at32uc3/at32uc3_flashc.h new file mode 100644 index 0000000000000000000000000000000000000000..c05f5ac18a37c5a3aca6eccc92169cea5872eeaa --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_flashc.h @@ -0,0 +1,229 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_flashc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_FLASHC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_FLASHC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_FLASHC_FCR_OFFSET 0x00 /* Flash Control Register */ +#define AVR32_FLASHC_FCMD_OFFSET 0x04 /* Flash Command Register */ +#define AVR32_FLASHC_FSR_OFFSET 0x08 /* Flash Status Register */ +#define AVR32_FLASHC_FGPFRHI_OFFSET 0x0c /* Flash General Purpose Fuse Register Hi */ +#define AVR32_FLASHC_FGPFRLO_OFFSET 0x10 /* Flash General Purpose Fuse Register Lo */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_FLASHC_FCR (AVR32_HFLASHC_BASE+AVR32_FLASHC_FCR_OFFSET) +#define AVR32_FLASHC_FCMD (AVR32_HFLASHC_BASE+AVR32_FLASHC_FCMD_OFFSET) +#define AVR32_FLASHC_FSR (AVR32_HFLASHC_BASE+AVR32_FLASHC_FSR_OFFSET) +#define AVR32_FLASHC_FGPFRHI (AVR32_HFLASHC_BASE+AVR32_FLASHC_FGPFRHI_OFFSET) +#define AVR32_FLASHC_FGPFRLO (AVR32_HFLASHC_BASE+AVR32_FLASHC_FGPFRLO_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Flash Control Register */ + +#define FLASHC_FCR_FRDY (1 << 0) /* Bit 0: Flash Ready Interrupt Enable */ +#define FLASHC_FCR_LOCKE (1 << 2) /* Bit 2: Lock Error Interrupt Enable */ +#define FLASHC_FCR_PROGE (1 << 3) /* Bit 3: Programming Error Interrupt Enable */ +#define FLASHC_FCR_FWS (1 << 6) /* Bit 6: Flash Wait State */ + +/* Flash Command Register */ + +#define FLASHC_FCMD_CMD_SHIFT (0) /* Bits 0-5: Command */ +#define FLASHC_FCMD_CMD_MASK (0x3f << FLASHC_FCMD_CMD_SHIFT) +#define FLASHC_FCMD_PAGEN_SHIFT (8) /* Bits 8-23: Page number */ +#define FLASHC_FCMD_PAGEN_MASK (0xffff << FLASHC_FCMD_PAGEN_SHIFT) +#define FLASHC_FCMD_KEY_SHIFT (14) /* Bits 24-31: Write protection key */ +#define FLASHC_FCMD_KEY_MASK (0xff << FLASHC_FCMD_KEY_SHIFT) + +/* Flash Status Register */ + +#define FLASHC_FSR_FRDY (1 << 0) /* Bit 0: Flash Ready Status */ +#define FLASHC_FSR_LOCKE (1 << 2) /* Bit 2: Lock Error Status */ +#define FLASHC_FSR_PROGE (1 << 3) /* Bit 3: Programming Error Status */ +#define FLASHC_FSR_SECURITY (1 << 4) /* Bit 4: Security Bit Status */ +#define FLASHC_FSR_QPRR (1 << 5) /* Bit 5: Quick Page Read Result */ +#define FLASHC_FSR_FSZ_SHIFT (13) /* Bits 13-15: Flash Size */ +#define FLASHC_FSR_FSZ_MASK (7 << FLASHC_FSR_FSZ_SHIFT) +# define FLASHC_FSR_FSZ_32KB (0 << FLASHC_FSR_FSZ_SHIFT) /* 32 Kbytes */ +# define FLASHC_FSR_FSZ_64KB (1 << FLASHC_FSR_FSZ_SHIFT) /* 64 Kbytes */ +# define FLASHC_FSR_FSZ_128KB (2 << FLASHC_FSR_FSZ_SHIFT) /* 128 Kbytes */ +# define FLASHC_FSR_FSZ_256KB (3 << FLASHC_FSR_FSZ_SHIFT) /* 256 Kbytes */ +# define FLASHC_FSR_FSZ_384KB (4 << FLASHC_FSR_FSZ_SHIFT) /* 384 Kbytes */ +# define FLASHC_FSR_FSZ_512KB (5 << FLASHC_FSR_FSZ_SHIFT) /* 512 Kbytes */ +# define FLASHC_FSR_FSZ_768KB (6 << FLASHC_FSR_FSZ_SHIFT) /* 768 Kbytes */ +# define FLASHC_FSR_FSZ_1MB (7 << FLASHC_FSR_FSZ_SHIFT) /* 1024 Kbytes */ +#define FLASHC_FSR_LOCK(n) (1 << ((n)+16) +#define FLASHC_FSR_LOCK0 (1 << 16) /* Bit 16: Lock Region 0 Lock Status */ +#define FLASHC_FSR_LOCK1 (1 << 17) /* Bit 17: Lock Region 1 Lock Status */ +#define FLASHC_FSR_LOCK2 (1 << 18) /* Bit 18: Lock Region 2 Lock Status */ +#define FLASHC_FSR_LOCK3 (1 << 19) /* Bit 19: Lock Region 3 Lock Status */ +#define FLASHC_FSR_LOCK4 (1 << 20) /* Bit 20: Lock Region 4 Lock Status */ +#define FLASHC_FSR_LOCK5 (1 << 21) /* Bit 21: Lock Region 5 Lock Status */ +#define FLASHC_FSR_LOCK6 (1 << 22) /* Bit 22: Lock Region 6 Lock Status */ +#define FLASHC_FSR_LOCK7 (1 << 23) /* Bit 23: Lock Region 7 Lock Status */ +#define FLASHC_FSR_LOCK8 (1 << 24) /* Bit 24: Lock Region 8 Lock Status */ +#define FLASHC_FSR_LOCK9 (1 << 25) /* Bit 25: Lock Region 9 Lock Status */ +#define FLASHC_FSR_LOCK10 (1 << 26) /* Bit 26: Lock Region 10 Lock Status */ +#define FLASHC_FSR_LOCK11 (1 << 27) /* Bit 27: Lock Region 11 Lock Status */ +#define FLASHC_FSR_LOCK12 (1 << 28) /* Bit 28: Lock Region 12 Lock Status */ +#define FLASHC_FSR_LOCK13 (1 << 29) /* Bit 29: Lock Region 13 Lock Status */ +#define FLASHC_FSR_LOCK14 (1 << 30) /* Bit 30: Lock Region 14 Lock Status */ +#define FLASHC_FSR_LOCK15 (1 << 31) /* Bit 31: Lock Region 15 Lock Status */ + +/* Flash General Purpose Fuse Register Hi */ + +#define FLASHC_FGPFRHI(n) (1 << ((n)-32)) +#define FLASHC_FGPFRHI32 (1 << 0) /* Bit 0: General Purpose Fuse 32 */ +#define FLASHC_FGPFRHI33 (1 << 1) /* Bit 1: General Purpose Fuse 33 */ +#define FLASHC_FGPFRHI34 (1 << 2) /* Bit 2: General Purpose Fuse 34 */ +#define FLASHC_FGPFRHI35 (1 << 3) /* Bit 3: General Purpose Fuse 35 */ +#define FLASHC_FGPFRHI36 (1 << 4) /* Bit 4: General Purpose Fuse 36 */ +#define FLASHC_FGPFRHI37 (1 << 5) /* Bit 5: General Purpose Fuse 37 */ +#define FLASHC_FGPFRHI38 (1 << 6) /* Bit 6: General Purpose Fuse 38 */ +#define FLASHC_FGPFRHI39 (1 << 7) /* Bit 7: General Purpose Fuse 39 */ +#define FLASHC_FGPFRHI40 (1 << 8) /* Bit 8: General Purpose Fuse 40 */ +#define FLASHC_FGPFRHI41 (1 << 9) /* Bit 9: General Purpose Fuse 41 */ +#define FLASHC_FGPFRHI42 (1 << 10) /* Bit 10: General Purpose Fuse 42 */ +#define FLASHC_FGPFRHI43 (1 << 11) /* Bit 11: General Purpose Fuse 43 */ +#define FLASHC_FGPFRHI44 (1 << 12) /* Bit 12: General Purpose Fuse 44 */ +#define FLASHC_FGPFRHI45 (1 << 13) /* Bit 13: General Purpose Fuse 45 */ +#define FLASHC_FGPFRHI46 (1 << 14) /* Bit 14: General Purpose Fuse 46 */ +#define FLASHC_FGPFRHI47 (1 << 15) /* Bit 15: General Purpose Fuse 47 */ +#define FLASHC_FGPFRHI48 (1 << 16) /* Bit 16: General Purpose Fuse 48 */ +#define FLASHC_FGPFRHI49 (1 << 17) /* Bit 17: General Purpose Fuse 49 */ +#define FLASHC_FGPFRHI50 (1 << 18) /* Bit 18: General Purpose Fuse 50 */ +#define FLASHC_FGPFRHI51 (1 << 19) /* Bit 19: General Purpose Fuse 51 */ +#define FLASHC_FGPFRHI52 (1 << 20) /* Bit 20: General Purpose Fuse 52 */ +#define FLASHC_FGPFRHI53 (1 << 21) /* Bit 21: General Purpose Fuse 53 */ +#define FLASHC_FGPFRHI54 (1 << 22) /* Bit 22: General Purpose Fuse 54 */ +#define FLASHC_FGPFRHI55 (1 << 23) /* Bit 23: General Purpose Fuse 55 */ +#define FLASHC_FGPFRHI56 (1 << 24) /* Bit 24: General Purpose Fuse 56 */ +#define FLASHC_FGPFRHI57 (1 << 25) /* Bit 25: General Purpose Fuse 57 */ +#define FLASHC_FGPFRHI58 (1 << 26) /* Bit 26: General Purpose Fuse 58 */ +#define FLASHC_FGPFRHI59 (1 << 27) /* Bit 27: General Purpose Fuse 59 */ +#define FLASHC_FGPFRHI60 (1 << 28) /* Bit 28: General Purpose Fuse 60 */ +#define FLASHC_FGPFRHI61 (1 << 29) /* Bit 29: General Purpose Fuse 61 */ +#define FLASHC_FGPFRHI62 (1 << 30) /* Bit 30: General Purpose Fuse 62 */ +#define FLASHC_FGPFRHI63 (1 << 31) /* Bit 31: General Purpose Fuse 63 */ + +/* Flash General Purpose Fuse Register Lo */ + +#define FLASHC_FGPFRLO(n) (1 << (n)) +#define FLASHC_FGPFRLO00 (1 << 0) /* Bit 0: General Purpose Fuse 00 */ +#define FLASHC_FGPFRLO01 (1 << 1) /* Bit 1: General Purpose Fuse 01 */ +#define FLASHC_FGPFRLO02 (1 << 2) /* Bit 2: General Purpose Fuse 02 */ +#define FLASHC_FGPFRLO03 (1 << 3) /* Bit 3: General Purpose Fuse 03 */ +#define FLASHC_FGPFRLO04 (1 << 4) /* Bit 4: General Purpose Fuse 04 */ +#define FLASHC_FGPFRLO05 (1 << 5) /* Bit 5: General Purpose Fuse 05 */ +#define FLASHC_FGPFRLO06 (1 << 6) /* Bit 6: General Purpose Fuse 06 */ +#define FLASHC_FGPFRLO07 (1 << 7) /* Bit 7: General Purpose Fuse 07 */ +#define FLASHC_FGPFRLO08 (1 << 8) /* Bit 8: General Purpose Fuse 08 */ +#define FLASHC_FGPFRLO09 (1 << 9) /* Bit 9: General Purpose Fuse 09 */ +#define FLASHC_FGPFRLO10 (1 << 10) /* Bit 10: General Purpose Fuse 10 */ +#define FLASHC_FGPFRLO11 (1 << 11) /* Bit 11: General Purpose Fuse 11 */ +#define FLASHC_FGPFRLO12 (1 << 12) /* Bit 12: General Purpose Fuse 12 */ +#define FLASHC_FGPFRLO13 (1 << 13) /* Bit 13: General Purpose Fuse 13 */ +#define FLASHC_FGPFRLO14 (1 << 14) /* Bit 14: General Purpose Fuse 14 */ +#define FLASHC_FGPFRLO15 (1 << 15) /* Bit 15: General Purpose Fuse 15 */ +#define FLASHC_FGPFRLO16 (1 << 16) /* Bit 16: General Purpose Fuse 16 */ +#define FLASHC_FGPFRLO17 (1 << 17) /* Bit 17: General Purpose Fuse 17 */ +#define FLASHC_FGPFRLO18 (1 << 18) /* Bit 18: General Purpose Fuse 18 */ +#define FLASHC_FGPFRLO19 (1 << 19) /* Bit 19: General Purpose Fuse 19 */ +#define FLASHC_FGPFRLO20 (1 << 20) /* Bit 20: General Purpose Fuse 20 */ +#define FLASHC_FGPFRLO21 (1 << 21) /* Bit 21: General Purpose Fuse 21 */ +#define FLASHC_FGPFRLO22 (1 << 22) /* Bit 22: General Purpose Fuse 22 */ +#define FLASHC_FGPFRLO23 (1 << 23) /* Bit 23: General Purpose Fuse 23 */ +#define FLASHC_FGPFRLO24 (1 << 24) /* Bit 24: General Purpose Fuse 24 */ +#define FLASHC_FGPFRLO25 (1 << 25) /* Bit 25: General Purpose Fuse 25 */ +#define FLASHC_FGPFRLO26 (1 << 26) /* Bit 26: General Purpose Fuse 26 */ +#define FLASHC_FGPFRLO27 (1 << 27) /* Bit 27: General Purpose Fuse 27 */ +#define FLASHC_FGPFRLO28 (1 << 28) /* Bit 28: General Purpose Fuse 28 */ +#define FLASHC_FGPFRLO29 (1 << 29) /* Bit 29: General Purpose Fuse 29 */ +#define FLASHC_FGPFRLO30 (1 << 30) /* Bit 30: General Purpose Fuse 30 */ +#define FLASHC_FGPFRLO31 (1 << 31) /* Bit 31: General Purpose Fuse 31 */ + +/* Flash Command Set ****************************************************************/ + +#define FLASH_CMD_NOP 0 /* No operation */ +#define FLASH_CMD_WP 1 /* Write Page */ +#define FLASH_CMD_EP 2 /* Erase Page */ +#define FLASH_CMD_CPB 3 /* Clear Page Buffer */ +#define FLASH_CMD_LP 4 /* Lock region containing given page */ +#define FLASH_CMD_UP 5 /* Unlock region containing given page */ +#define FLASH_CMD_EA 6 /* Erase All */ +#define FLASH_CMD_WGPB 7 /* Write General-Purpose Fuse Bit */ +#define FLASH_CMD_EGPB 8 /* Erase General-Purpose Fuse Bit */ +#define FLASH_CMD_SSB 9 /* Set Security Bit */ +#define FLASH_CMD_PGPFB 10 /* Program GP Fuse Byte */ +#define FLASH_CMD_EAGP 11 /* Erase All GPFuses */ +#define FLASH_CMD_QPR 12 /* Quick Page Read */ +#define FLASH_CMD_WUP 13 /* Write User Page */ +#define FLASH_CMD_EUP 14 /* Erase User Page */ +#define FLASH_CMD_QPRUP 15 /* Quick Page Read User Page */ + +/* Other constants ******************************************************************/ + +/* Maximum CPU frequency for 0 and 1 FLASH wait states */ + +#define AVR32_FLASHC_FWS0_MAXFREQ 33000000 +#define AVR32_FLASHC_FWS1_MAXFREQ 66000000 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_FLASHC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_gpio.c b/arch/avr/src/at32uc3/at32uc3_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..256f75e6d647ed8a6493114b51503b40bee4797e --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_gpio.c @@ -0,0 +1,296 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_gpio.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "at32uc3_config.h" +#include "up_internal.h" +#include "at32uc3.h" + +#include "up_arch.h" +#include "chip.h" +#include "at32uc3_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* How many GPIO ports are supported? There are 32-pins per port and we + * know he number of GPIO pins supported by the architecture: + */ + +#define AVR32_NGPIO_PORTS ((AVR32_NGPIO+31) >> 5) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t g_portmap[AVR32_NGPIO_PORTS] = +{ +#if AVR32_NGPIO > 0 + AVR32_GPIO0_BASE +#endif +#if AVR32_NGPIO > 32 + , AVR32_GPIO1_BASE, +#endif +#if AVR32_NGPIO > 64 + , AVR32_GPIO2_BASE, +#endif +#if AVR32_NGPIO > 96 + , AVR32_GPIO3_BASE, +#endif +#if AVR32_NGPIO > 128 + , AVR32_GPIO4_BASE, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: at32uc3_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int at32uc3_configgpio(uint16_t cfgset) +{ + unsigned int port; + unsigned int pin; + uint32_t pinmask; + uint32_t base; + + /* Extract then port number and the pin number from the configuration */ + + port = ((unsigned int)cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = ((unsigned int)cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + DEBUGASSERT(port < AVR32_NGPIO_PORTS); + + /* Get pin mask and the GPIO base address */ + + pinmask = (1 << pin); + base = g_portmap[port]; + + /* First, just to be safe, disable the output driver, give GPIO control of + * the pin, rese the peripheral mux, set the output low, remove the pull-up, + * disable GPIO interrupts, reset the interrupt mode, and disable glitch + * filtering, while we reconfigure the pin. + */ + + putreg32(pinmask, base + AVR32_GPIO_ODERC_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_GPERS_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_PMR0C_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_PMR1C_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_OVRC_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_PUERC_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_IERC_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_IMR0C_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_IMR1C_OFFSET); + putreg32(pinmask, base + AVR32_GPIO_GFERC_OFFSET); + + /* Is this a GPIO? Or a peripheral */ + + if ((cfgset & GPIO_ENABLE) != 0) + { + /* Its a GPIO. Input or output? */ + + if ((cfgset & GPIO_OUTPUT) != 0) + { + /* Its a GPIO output. Set up the initial output value and enable + * the output driver. + */ + + if ((cfgset & GPIO_VALUE) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_OVRS_OFFSET); + } + putreg32(pinmask, base + AVR32_GPIO_ODERS_OFFSET); + } + else + { + /* Its a GPIO input. There is nothing more to do here. */ + } + } + else + { + /* Its a peripheral. Set the peripheral mux */ + + if ((cfgset & GPIO_PMR0) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_PMR0S_OFFSET); + } + + if ((cfgset & GPIO_PMR1) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_PMR1S_OFFSET); + } + + /* And enable peripheral control of the pin */ + + putreg32(pinmask, base + AVR32_GPIO_GPERC_OFFSET); + } + + /* Then the "ornaments" tha do not depend on gpio/peripheral mode: + * Pull-ups and glitch filering. + */ + + if ((cfgset & GPIO_PULLUP) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_PUERS_OFFSET); + } + + if ((cfgset & GPIO_PULLUP) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_GFERS_OFFSET); + } + + /* Check for GPIO interrupt */ + + if ((cfgset & GPIO_INTR) != 0) + { + /* Set up the interrupt mode */ + + if ((cfgset & GPIO_IMR0) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_IMR0S_OFFSET); + } + + if ((cfgset & GPIO_IMR1) != 0) + { + putreg32(pinmask, base + AVR32_GPIO_IMR1S_OFFSET); + } + + /* Then enable the GPIO interrupt */ + + putreg32(pinmask, base + AVR32_GPIO_IERS_OFFSET); + } + + return OK; +} + +/************************************************************************************ + * Name: at32uc3_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void at32uc3_gpiowrite(uint16_t pinset, bool value) +{ + unsigned int port; + unsigned int pin; + uint32_t pinmask; + uint32_t base; + + /* Extract then port number and the pin number from the configuration */ + + port = ((unsigned int)pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = ((unsigned int)pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + DEBUGASSERT(port < AVR32_NGPIO_PORTS); + + /* Get pin mask and the GPIO base address */ + + pinmask = (1 << pin); + base = g_portmap[port]; + + /* Now, set or clear the pin ouput value */ + + if (value) + { + putreg32(pinmask, base + AVR32_GPIO_OVRS_OFFSET); + } + else + { + putreg32(pinmask, base + AVR32_GPIO_OVRC_OFFSET); + } +} + +/************************************************************************************ + * Name: at32uc3_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool at32uc3_gpioread(uint16_t pinset) +{ + unsigned int port; + unsigned int pin; + uint32_t pinmask; + uint32_t base; + + /* Extract then port number and the pin number from the configuration */ + + port = ((unsigned int)pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = ((unsigned int)pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + DEBUGASSERT(port < AVR32_NGPIO_PORTS); + + /* Get pin mask and the GPIO base address */ + + pinmask = (1 << pin); + base = g_portmap[port]; + + /* Now, return the current pin value */ + + return (getreg32(base + AVR32_GPIO_PVR_OFFSET) & pinmask) != 0; +} diff --git a/arch/avr/src/at32uc3/at32uc3_gpio.h b/arch/avr/src/at32uc3/at32uc3_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..6467ef7c14e5d79608d2eee93acb14aa39df3c44 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_gpio.h @@ -0,0 +1,465 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_gpio.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_GPIO_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Port Identifiers *****************************************************************/ + +#define AVR32_GPIO0 0 /* General Purpose Input/Output Port 0 */ +#define AVR32_GPIO1 1 /* General Purpose Input/Output Port 1 */ +#define AVR32_GPIO2 2 /* General Purpose Input/Output Port 2 */ +#define AVR32_GPIO3 3 /* General Purpose Input/Output Port 3 */ +#define AVR32_GPIO4 4 /* General Purpose Input/Output Port 4 */ + +/* Port Offsets *********************************************************************/ + +#define AVR32_GPIOn_OFFSET(n) ((n) << 8) +#define AVR32_GPIO0_OFFSET 0x0000 /* General Purpose Input/Output Port 0 */ +#define AVR32_GPIO1_OFFSET 0x0100 /* General Purpose Input/Output Port 1 */ +#define AVR32_GPIO2_OFFSET 0x0200 /* General Purpose Input/Output Port 2 */ +#define AVR32_GPIO3_OFFSET 0x0300 /* General Purpose Input/Output Port 3 */ +#define AVR32_GPIO4_OFFSET 0x0400 /* General Purpose Input/Output Port 4 */ + +/* Register offsets *****************************************************************/ + +#define AVR32_GPIO_GPER_OFFSET 0x00 /* GPIO Enable Register */ +#define AVR32_GPIO_GPERS_OFFSET 0x04 /* GPIO Enable Register Set */ +#define AVR32_GPIO_GPERC_OFFSET 0x08 /* GPIO Enable Register Clear */ +#define AVR32_GPIO_GPERT_OFFSET 0x0c /* GPIO Enable Register Toggle */ +#define AVR32_GPIO_PMR0_OFFSET 0x10 /* Peripheral Mux Register 0 */ +#define AVR32_GPIO_PMR0S_OFFSET 0x14 /* Peripheral Mux Register 0 Set */ +#define AVR32_GPIO_PMR0C_OFFSET 0x18 /* Peripheral Mux Register 0 Clear */ +#define AVR32_GPIO_PMR0T_OFFSET 0x1c /* Peripheral Mux Register 0 Toggle */ +#define AVR32_GPIO_PMR1_OFFSET 0x20 /* Peripheral Mux Register 1 */ +#define AVR32_GPIO_PMR1S_OFFSET 0x24 /* Peripheral Mux Register 1 Set */ +#define AVR32_GPIO_PMR1C_OFFSET 0x28 /* Peripheral Mux Register 1 Clear */ +#define AVR32_GPIO_PMR1T_OFFSET 0x2c /* Peripheral Mux Register 1 Toggle */ +#define AVR32_GPIO_ODER_OFFSET 0x40 /* Output Driver Enable Register */ +#define AVR32_GPIO_ODERS_OFFSET 0x44 /* Output Driver Enable Register Set */ +#define AVR32_GPIO_ODERC_OFFSET 0x48 /* Output Driver Enable Register Clear */ +#define AVR32_GPIO_ODERT_OFFSET 0x4c /* Output Driver Enable Register Toggle */ +#define AVR32_GPIO_OVR_OFFSET 0x50 /* Output Value Register */ +#define AVR32_GPIO_OVRS_OFFSET 0x54 /* Output Value Register Set */ +#define AVR32_GPIO_OVRC_OFFSET 0x58 /* Output Value Register Clear */ +#define AVR32_GPIO_OVRT_OFFSET 0x5c /* Output Value Register Toggle */ +#define AVR32_GPIO_PVR_OFFSET 0x60 /* Pin Value Register Read */ +#define AVR32_GPIO_PUER_OFFSET 0x70 /* Pull-up Enable Register */ +#define AVR32_GPIO_PUERS_OFFSET 0x74 /* Pull-up Enable Register Set */ +#define AVR32_GPIO_PUERC_OFFSET 0x78 /* Pull-up Enable Register Clear */ +#define AVR32_GPIO_PUERT_OFFSET 0x7c /* Pull-up Enable Register Toggle */ +#define AVR32_GPIO_IER_OFFSET 0x90 /* Interrupt Enable Register */ +#define AVR32_GPIO_IERS_OFFSET 0x94 /* Interrupt Enable Register Set */ +#define AVR32_GPIO_IERC_OFFSET 0x98 /* Interrupt Enable Register Clear */ +#define AVR32_GPIO_IERT_OFFSET 0x9c /* Interrupt Enable Register Toggle */ +#define AVR32_GPIO_IMR0_OFFSET 0xa0 /* Interrupt Mode Register 0 */ +#define AVR32_GPIO_IMR0S_OFFSET 0xa4 /* Interrupt Mode Register 0 Set */ +#define AVR32_GPIO_IMR0C_OFFSET 0xa8 /* Interrupt Mode Register 0 Clear */ +#define AVR32_GPIO_IMR0T_OFFSET 0xac /* Interrupt Mode Register 0 Toggle */ +#define AVR32_GPIO_IMR1_OFFSET 0xb0 /* Interrupt Mode Register 1 */ +#define AVR32_GPIO_IMR1S_OFFSET 0xb4 /* Interrupt Mode Register 1 Set */ +#define AVR32_GPIO_IMR1C_OFFSET 0xb8 /* Interrupt Mode Register 1 Clear */ +#define AVR32_GPIO_IMR1T_OFFSET 0xbc /* Interrupt Mode Register 1 Toggle */ +#define AVR32_GPIO_GFER_OFFSET 0xc0 /* Glitch Filter Enable Register */ +#define AVR32_GPIO_GFERS_OFFSET 0xc4 /* Glitch Filter Enable Register Set */ +#define AVR32_GPIO_GFERC_OFFSET 0xc8 /* Glitch Filter Enable Register Clear */ +#define AVR32_GPIO_GFERT_OFFSET 0xcc /* Glitch Filter Enable Register Toggle */ +#define AVR32_GPIO_IFR_OFFSET 0xd0 /* Interrupt Flag Register Read */ +#define AVR32_GPIO_IFRC_OFFSET 0xd8 /* Interrupt Flag Register Clear */ + +/* Port Base Addresses **************************************************************/ + +#define AVR32_GPIOn_BASE(n) (AVR32_GPIO_BASE+AVR32_GPIO_OFFSET(n)) +#define AVR32_GPIO0_BASE (AVR32_GPIO_BASE+AVR32_GPIO0_OFFSET) +#define AVR32_GPIO1_BASE (AVR32_GPIO_BASE+AVR32_GPIO1_OFFSET) +#define AVR32_GPIO2_BASE (AVR32_GPIO_BASE+AVR32_GPIO2_OFFSET) +#define AVR32_GPIO3_BASE (AVR32_GPIO_BASE+AVR32_GPIO3_OFFSET) +#define AVR32_GPIO4_BASE (AVR32_GPIO_BASE+AVR32_GPIO4_OFFSET) + +/* Local bus mapped GPIO ports */ + +#define AVR32_GPIOn_LBUS_BASE(n) (AVR32_GPIO_LBUS_BASE+AVR32_GPIO_OFFSET(n)) +#define AVR32_GPIO0_LBUS_BASE (AVR32_GPIO_LBUS_BASE+AVR32_GPIO0_OFFSET) +#define AVR32_GPIO1_LBUS_BASE (AVR32_GPIO_LBUS_BASE+AVR32_GPIO1_OFFSET) + +/* Register Addresses ***************************************************************/ + +#define AVR32_GPIO_GPER(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO_GPERS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO_GPERC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO_GPERT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO_PMR0(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO_PMR0S(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO_PMR0C(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO_PMR0T(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO_PMR1(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO_PMR1S(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO_PMR1C(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO_PMR1T(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO_ODER(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO_ODERS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO_ODERC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO_ODERT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO_OVR(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO_OVRS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO_OVRC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO_OVRT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO_PVR(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO_PUER(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO_PUERS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO_PUERC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO_PUERT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO_IER(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO_IERS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO_IERC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO_IERT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO_IMR0(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO_IMR0S(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO_IMR0C(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO_IMR0T(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO_IMR1(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO_IMR1S(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO_IMR1C(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO_IMR1T(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO_GFER(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO_GFERS(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO_GFERC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO_GFERT(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO_IFR(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO_IFRC(n) (AVR32_GPIOn_BASE(n)+AVR32_GPIO_IFRC_OFFSET) + +#define AVR32_GPIO0_GPER (AVR32_GPIO0_BASE+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO0_GPERS (AVR32_GPIO0_BASE+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO0_GPERC (AVR32_GPIO0_BASE+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO0_GPERT (AVR32_GPIO0_BASE+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO0_PMR0 (AVR32_GPIO0_BASE+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO0_PMR0S (AVR32_GPIO0_BASE+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO0_PMR0C (AVR32_GPIO0_BASE+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO0_PMR0T (AVR32_GPIO0_BASE+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO0_PMR1 (AVR32_GPIO0_BASE+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO0_PMR1S (AVR32_GPIO0_BASE+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO0_PMR1C (AVR32_GPIO0_BASE+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO0_PMR1T (AVR32_GPIO0_BASE+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO0_ODER (AVR32_GPIO0_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO0_ODERS (AVR32_GPIO0_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO0_ODERC (AVR32_GPIO0_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO0_ODERT (AVR32_GPIO0_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO0_OVR (AVR32_GPIO0_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO0_OVRS (AVR32_GPIO0_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO0_OVRC (AVR32_GPIO0_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO0_OVRT (AVR32_GPIO0_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO0_PVR (AVR32_GPIO0_BASE+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO0_PUER (AVR32_GPIO0_BASE+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO0_PUERS (AVR32_GPIO0_BASE+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO0_PUERC (AVR32_GPIO0_BASE+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO0_PUERT (AVR32_GPIO0_BASE+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO0_IER (AVR32_GPIO0_BASE+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO0_IERS (AVR32_GPIO0_BASE+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO0_IERC (AVR32_GPIO0_BASE+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO0_IERT (AVR32_GPIO0_BASE+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO0_IMR0 (AVR32_GPIO0_BASE+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO0_IMR0S (AVR32_GPIO0_BASE+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO0_IMR0C (AVR32_GPIO0_BASE+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO0_IMR0T (AVR32_GPIO0_BASE+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO0_IMR1 (AVR32_GPIO0_BASE+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO0_IMR1S (AVR32_GPIO0_BASE+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO0_IMR1C (AVR32_GPIO0_BASE+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO0_IMR1T (AVR32_GPIO0_BASE+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO0_GFER (AVR32_GPIO0_BASE+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO0_GFERS (AVR32_GPIO0_BASE+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO0_GFERC (AVR32_GPIO0_BASE+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO0_GFERT (AVR32_GPIO0_BASE+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO0_IFR (AVR32_GPIO0_BASE+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO0_IFRC (AVR32_GPIO0_BASE+AVR32_GPIO_IFRC_OFFSET) + +#define AVR32_GPIO1_GPER (AVR32_GPIO1_BASE+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO1_GPERS (AVR32_GPIO1_BASE+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO1_GPERC (AVR32_GPIO1_BASE+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO1_GPERT (AVR32_GPIO1_BASE+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO1_PMR0 (AVR32_GPIO1_BASE+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO1_PMR0S (AVR32_GPIO1_BASE+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO1_PMR0C (AVR32_GPIO1_BASE+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO1_PMR0T (AVR32_GPIO1_BASE+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO1_PMR1 (AVR32_GPIO1_BASE+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO1_PMR1S (AVR32_GPIO1_BASE+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO1_PMR1C (AVR32_GPIO1_BASE+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO1_PMR1T (AVR32_GPIO1_BASE+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO1_ODER (AVR32_GPIO1_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO1_ODERS (AVR32_GPIO1_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO1_ODERC (AVR32_GPIO1_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO1_ODERT (AVR32_GPIO1_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO1_OVR (AVR32_GPIO1_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO1_OVRS (AVR32_GPIO1_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO1_OVRC (AVR32_GPIO1_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO1_OVRT (AVR32_GPIO1_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO1_PVR (AVR32_GPIO1_BASE+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO1_PUER (AVR32_GPIO1_BASE+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO1_PUERS (AVR32_GPIO1_BASE+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO1_PUERC (AVR32_GPIO1_BASE+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO1_PUERT (AVR32_GPIO1_BASE+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO1_IER (AVR32_GPIO1_BASE+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO1_IERS (AVR32_GPIO1_BASE+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO1_IERC (AVR32_GPIO1_BASE+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO1_IERT (AVR32_GPIO1_BASE+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO1_IMR0 (AVR32_GPIO1_BASE+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO1_IMR0S (AVR32_GPIO1_BASE+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO1_IMR0C (AVR32_GPIO1_BASE+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO1_IMR0T (AVR32_GPIO1_BASE+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO1_IMR1 (AVR32_GPIO1_BASE+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO1_IMR1S (AVR32_GPIO1_BASE+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO1_IMR1C (AVR32_GPIO1_BASE+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO1_IMR1T (AVR32_GPIO1_BASE+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO1_GFER (AVR32_GPIO1_BASE+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO1_GFERS (AVR32_GPIO1_BASE+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO1_GFERC (AVR32_GPIO1_BASE+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO1_GFERT (AVR32_GPIO1_BASE+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO1_IFR (AVR32_GPIO1_BASE+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO1_IFRC (AVR32_GPIO1_BASE+AVR32_GPIO_IFRC_OFFSET) + +#define AVR32_GPIO2_GPER (AVR32_GPIO2_BASE+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO2_GPERS (AVR32_GPIO2_BASE+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO2_GPERC (AVR32_GPIO2_BASE+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO2_GPERT (AVR32_GPIO2_BASE+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO2_PMR0 (AVR32_GPIO2_BASE+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO2_PMR0S (AVR32_GPIO2_BASE+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO2_PMR0C (AVR32_GPIO2_BASE+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO2_PMR0T (AVR32_GPIO2_BASE+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO2_PMR1 (AVR32_GPIO2_BASE+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO2_PMR1S (AVR32_GPIO2_BASE+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO2_PMR1C (AVR32_GPIO2_BASE+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO2_PMR1T (AVR32_GPIO2_BASE+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO2_ODER (AVR32_GPIO2_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO2_ODERS (AVR32_GPIO2_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO2_ODERC (AVR32_GPIO2_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO2_ODERT (AVR32_GPIO2_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO2_OVR (AVR32_GPIO2_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO2_OVRS (AVR32_GPIO2_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO2_OVRC (AVR32_GPIO2_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO2_OVRT (AVR32_GPIO2_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO2_PVR (AVR32_GPIO2_BASE+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO2_PUER (AVR32_GPIO2_BASE+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO2_PUERS (AVR32_GPIO2_BASE+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO2_PUERC (AVR32_GPIO2_BASE+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO2_PUERT (AVR32_GPIO2_BASE+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO2_IER (AVR32_GPIO2_BASE+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO2_IERS (AVR32_GPIO2_BASE+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO2_IERC (AVR32_GPIO2_BASE+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO2_IERT (AVR32_GPIO2_BASE+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO2_IMR0 (AVR32_GPIO2_BASE+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO2_IMR0S (AVR32_GPIO2_BASE+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO2_IMR0C (AVR32_GPIO2_BASE+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO2_IMR0T (AVR32_GPIO2_BASE+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO2_IMR1 (AVR32_GPIO2_BASE+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO2_IMR1S (AVR32_GPIO2_BASE+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO2_IMR1C (AVR32_GPIO2_BASE+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO2_IMR1T (AVR32_GPIO2_BASE+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO2_GFER (AVR32_GPIO2_BASE+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO2_GFERS (AVR32_GPIO2_BASE+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO2_GFERC (AVR32_GPIO2_BASE+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO2_GFERT (AVR32_GPIO2_BASE+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO2_IFR (AVR32_GPIO2_BASE+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO2_IFRC (AVR32_GPIO2_BASE+AVR32_GPIO_IFRC_OFFSET) + +#define AVR32_GPIO3_GPER (AVR32_GPIO3_BASE+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO3_GPERS (AVR32_GPIO3_BASE+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO3_GPERC (AVR32_GPIO3_BASE+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO3_GPERT (AVR32_GPIO3_BASE+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO3_PMR0 (AVR32_GPIO3_BASE+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO3_PMR0S (AVR32_GPIO3_BASE+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO3_PMR0C (AVR32_GPIO3_BASE+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO3_PMR0T (AVR32_GPIO3_BASE+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO3_PMR1 (AVR32_GPIO3_BASE+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO3_PMR1S (AVR32_GPIO3_BASE+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO3_PMR1C (AVR32_GPIO3_BASE+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO3_PMR1T (AVR32_GPIO3_BASE+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO3_ODER (AVR32_GPIO3_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO3_ODERS (AVR32_GPIO3_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO3_ODERC (AVR32_GPIO3_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO3_ODERT (AVR32_GPIO3_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO3_OVR (AVR32_GPIO3_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO3_OVRS (AVR32_GPIO3_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO3_OVRC (AVR32_GPIO3_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO3_OVRT (AVR32_GPIO3_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO3_PVR (AVR32_GPIO3_BASE+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO3_PUER (AVR32_GPIO3_BASE+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO3_PUERS (AVR32_GPIO3_BASE+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO3_PUERC (AVR32_GPIO3_BASE+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO3_PUERT (AVR32_GPIO3_BASE+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO3_IER (AVR32_GPIO3_BASE+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO3_IERS (AVR32_GPIO3_BASE+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO3_IERC (AVR32_GPIO3_BASE+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO3_IERT (AVR32_GPIO3_BASE+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO3_IMR0 (AVR32_GPIO3_BASE+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO3_IMR0S (AVR32_GPIO3_BASE+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO3_IMR0C (AVR32_GPIO3_BASE+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO3_IMR0T (AVR32_GPIO3_BASE+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO3_IMR1 (AVR32_GPIO3_BASE+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO3_IMR1S (AVR32_GPIO3_BASE+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO3_IMR1C (AVR32_GPIO3_BASE+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO3_IMR1T (AVR32_GPIO3_BASE+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO3_GFER (AVR32_GPIO3_BASE+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO3_GFERS (AVR32_GPIO3_BASE+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO3_GFERC (AVR32_GPIO3_BASE+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO3_GFERT (AVR32_GPIO3_BASE+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO3_IFR (AVR32_GPIO3_BASE+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO3_IFRC (AVR32_GPIO3_BASE+AVR32_GPIO_IFRC_OFFSET) + +#define AVR32_GPIO4_GPER (AVR32_GPIO4_BASE+AVR32_GPIO_GPER_OFFSET) +#define AVR32_GPIO4_GPERS (AVR32_GPIO4_BASE+AVR32_GPIO_GPERS_OFFSET) +#define AVR32_GPIO4_GPERC (AVR32_GPIO4_BASE+AVR32_GPIO_GPERC_OFFSET) +#define AVR32_GPIO4_GPERT (AVR32_GPIO4_BASE+AVR32_GPIO_GPERT_OFFSET) +#define AVR32_GPIO4_PMR0 (AVR32_GPIO4_BASE+AVR32_GPIO_PMR0_OFFSET) +#define AVR32_GPIO4_PMR0S (AVR32_GPIO4_BASE+AVR32_GPIO_PMR0S_OFFSET) +#define AVR32_GPIO4_PMR0C (AVR32_GPIO4_BASE+AVR32_GPIO_PMR0C_OFFSET) +#define AVR32_GPIO4_PMR0T (AVR32_GPIO4_BASE+AVR32_GPIO_PMR0T_OFFSET) +#define AVR32_GPIO4_PMR1 (AVR32_GPIO4_BASE+AVR32_GPIO_PMR1_OFFSET) +#define AVR32_GPIO4_PMR1S (AVR32_GPIO4_BASE+AVR32_GPIO_PMR1S_OFFSET) +#define AVR32_GPIO4_PMR1C (AVR32_GPIO4_BASE+AVR32_GPIO_PMR1C_OFFSET) +#define AVR32_GPIO4_PMR1T (AVR32_GPIO4_BASE+AVR32_GPIO_PMR1T_OFFSET) +#define AVR32_GPIO4_ODER (AVR32_GPIO4_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO4_ODERS (AVR32_GPIO4_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO4_ODERC (AVR32_GPIO4_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO4_ODERT (AVR32_GPIO4_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO4_OVR (AVR32_GPIO4_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO4_OVRS (AVR32_GPIO4_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO4_OVRC (AVR32_GPIO4_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO4_OVRT (AVR32_GPIO4_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO4_PVR (AVR32_GPIO4_BASE+AVR32_GPIO_PVR_OFFSET) +#define AVR32_GPIO4_PUER (AVR32_GPIO4_BASE+AVR32_GPIO_PUER_OFFSET) +#define AVR32_GPIO4_PUERS (AVR32_GPIO4_BASE+AVR32_GPIO_PUERS_OFFSET) +#define AVR32_GPIO4_PUERC (AVR32_GPIO4_BASE+AVR32_GPIO_PUERC_OFFSET) +#define AVR32_GPIO4_PUERT (AVR32_GPIO4_BASE+AVR32_GPIO_PUERT_OFFSET) +#define AVR32_GPIO4_IER (AVR32_GPIO4_BASE+AVR32_GPIO_IER_OFFSET) +#define AVR32_GPIO4_IERS (AVR32_GPIO4_BASE+AVR32_GPIO_IERS_OFFSET) +#define AVR32_GPIO4_IERC (AVR32_GPIO4_BASE+AVR32_GPIO_IERC_OFFSET) +#define AVR32_GPIO4_IERT (AVR32_GPIO4_BASE+AVR32_GPIO_IERT_OFFSET) +#define AVR32_GPIO4_IMR0 (AVR32_GPIO4_BASE+AVR32_GPIO_IMR0_OFFSET) +#define AVR32_GPIO4_IMR0S (AVR32_GPIO4_BASE+AVR32_GPIO_IMR0S_OFFSET) +#define AVR32_GPIO4_IMR0C (AVR32_GPIO4_BASE+AVR32_GPIO_IMR0C_OFFSET) +#define AVR32_GPIO4_IMR0T (AVR32_GPIO4_BASE+AVR32_GPIO_IMR0T_OFFSET) +#define AVR32_GPIO4_IMR1 (AVR32_GPIO4_BASE+AVR32_GPIO_IMR1_OFFSET) +#define AVR32_GPIO4_IMR1S (AVR32_GPIO4_BASE+AVR32_GPIO_IMR1S_OFFSET) +#define AVR32_GPIO4_IMR1C (AVR32_GPIO4_BASE+AVR32_GPIO_IMR1C_OFFSET) +#define AVR32_GPIO4_IMR1T (AVR32_GPIO4_BASE+AVR32_GPIO_IMR1T_OFFSET) +#define AVR32_GPIO4_GFER (AVR32_GPIO4_BASE+AVR32_GPIO_GFER_OFFSET) +#define AVR32_GPIO4_GFERS (AVR32_GPIO4_BASE+AVR32_GPIO_GFERS_OFFSET) +#define AVR32_GPIO4_GFERC (AVR32_GPIO4_BASE+AVR32_GPIO_GFERC_OFFSET) +#define AVR32_GPIO4_GFERT (AVR32_GPIO4_BASE+AVR32_GPIO_GFERT_OFFSET) +#define AVR32_GPIO4_IFR (AVR32_GPIO4_BASE+AVR32_GPIO_IFR_OFFSET) +#define AVR32_GPIO4_IFRC (AVR32_GPIO4_BASE+AVR32_GPIO_IFRC_OFFSET) + +/* Local bus mapped GPIO registers */ + +#define AVR32_GPIO0_LBUS_ODER (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO0_LBUS_ODERS (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO0_LBUS_ODERC (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO0_LBUS_ODERT (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO0_LBUS_OVR (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO0_LBUS_OVRS (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO0_LBUS_OVRC (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO0_LBUS_OVRT (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO0_LBUS_PVR (AVR32_GPIO0_LBUS_BASE+AVR32_GPIO_PVR_OFFSET) + +#define AVR32_GPIO1_LBUS_ODER (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_ODER_OFFSET) +#define AVR32_GPIO1_LBUS_ODERS (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_ODERS_OFFSET) +#define AVR32_GPIO1_LBUS_ODERC (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_ODERC_OFFSET) +#define AVR32_GPIO1_LBUS_ODERT (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_ODERT_OFFSET) +#define AVR32_GPIO1_LBUS_OVR (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_OVR_OFFSET) +#define AVR32_GPIO1_LBUS_OVRS (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_OVRS_OFFSET) +#define AVR32_GPIO1_LBUS_OVRC (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_OVRC_OFFSET) +#define AVR32_GPIO1_LBUS_OVRT (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_OVRT_OFFSET) +#define AVR32_GPIO1_LBUS_PVR (AVR32_GPIO1_LBUS_BASE+AVR32_GPIO_PVR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* For all registers, there are 32 bits, each associated with one pin on the port. */ + +#define GPIO_PIN(n) (1 << (n)) +#define GPIO_PIN0 (1 << 0) +#define GPIO_PIN1 (1 << 1) +#define GPIO_PIN2 (1 << 2) +#define GPIO_PIN3 (1 << 3) +#define GPIO_PIN4 (1 << 4) +#define GPIO_PIN5 (1 << 5) +#define GPIO_PIN6 (1 << 6) +#define GPIO_PIN7 (1 << 7) +#define GPIO_PIN8 (1 << 8) +#define GPIO_PIN9 (1 << 9) +#define GPIO_PIN10 (1 << 10) +#define GPIO_PIN11 (1 << 11) +#define GPIO_PIN12 (1 << 12) +#define GPIO_PIN13 (1 << 13) +#define GPIO_PIN14 (1 << 14) +#define GPIO_PIN15 (1 << 15) +#define GPIO_PIN16 (1 << 16) +#define GPIO_PIN17 (1 << 17) +#define GPIO_PIN18 (1 << 18) +#define GPIO_PIN19 (1 << 19) +#define GPIO_PIN20 (1 << 20) +#define GPIO_PIN21 (1 << 21) +#define GPIO_PIN22 (1 << 22) +#define GPIO_PIN23 (1 << 23) +#define GPIO_PIN24 (1 << 24) +#define GPIO_PIN25 (1 << 25) +#define GPIO_PIN26 (1 << 26) +#define GPIO_PIN27 (1 << 27) +#define GPIO_PIN28 (1 << 28) +#define GPIO_PIN29 (1 << 29) +#define GPIO_PIN30 (1 << 30) +#define GPIO_PIN31 (1 << 31) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_GPIO_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_gpioirq.c b/arch/avr/src/at32uc3/at32uc3_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..231af1026d900316b52d77e78c2cd12bccd242e4 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_gpioirq.c @@ -0,0 +1,427 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_gpioirq.c + * arch/avr/src/chip/at32uc3_gpioirq.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at32uc3_config.h" + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "irq/irq.h" +#include "at32uc3.h" +#include "at32uc3_gpio.h" + +#ifdef CONFIG_AVR32_GPIOIRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* A table of handlers for each GPIO interrupt */ + +static FAR xcpt_t g_gpiohandler[NR_GPIO_IRQS]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gpio_baseaddress + * + * Input: + * irq - A IRQ number in the range of 0 to NR_GPIO_IRQS. + * + * Description: + * Given a IRQ number, return the base address of the associated GPIO + * registers. + * + ****************************************************************************/ + +static inline uint32_t gpio_baseaddress(unsigned int irq) +{ +#if CONFIG_AVR32_GPIOIRQSETA != 0 + if (irq < __IRQ_GPIO_PB0) + { + return AVR32_GPIO0_BASE; + } + else +#endif +#if CONFIG_AVR32_GPIOIRQSETB != 0 + if (irq < NR_GPIO_IRQS) + { + return AVR32_GPIO1_BASE; + } + else +#endif + { + return 0; + } +} + +/**************************************************************************** + * Name: gpio_pin + * + * Input: + * irq - A IRQ number in the range of 0 to NR_GPIO_IRQS. + * + * Description: + * Given a GPIO number, return the pin number in the range of 0-31 on the + * corresponding port + * + ****************************************************************************/ + +static inline int gpio_pin(unsigned int irq) +{ + uint32_t pinset; + int pinirq; + int pin; + +#if CONFIG_AVR32_GPIOIRQSETA != 0 + if (irq < __IRQ_GPIO_PB0) + { + pinset = CONFIG_AVR32_GPIOIRQSETA; + pinirq = __IRQ_GPIO_PA0; + } + else +#endif +#if CONFIG_AVR32_GPIOIRQSETB != 0 + if (irq < NR_GPIO_IRQS) + { + pinset = CONFIG_AVR32_GPIOIRQSETB; + pinirq = __IRQ_GPIO_PB0; + } + else +#endif + { + return -EINVAL; + } + + /* Now we have to search for the pin with matching IRQ. Yech! We made + * life difficult here by choosing a sparse representation of IRQs on + * GPIO pins. + */ + + for (pin = 0; pin < 32 && pinset != 0; pin++) + { + /* Is this pin at bit 0 configured for interrupt support? */ + + if ((pinset & 1) != 0) + { + /* Is it the on IRQ we are looking for? */ + + if (pinirq == irq) + { + /* Yes, return the associated pin number */ + + return pin; + } + + /* No.. Increment the IRQ number for the next configured pin */ + + pinirq++; + } + + /* Shift the next pin to position bit 0 */ + + pinset >>= 1; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: gpio_porthandler + * + * Description: + * Dispatch GPIO interrupts on a specific GPIO port + * + ****************************************************************************/ + +static void gpio_porthandler(uint32_t regbase, int irqbase, uint32_t irqset, void *context) +{ + uint32_t ifr; + int irq; + int pin; + + /* Check each bit and dispatch each pending interrupt in the interrupt flag + * register for this port. + */ + + ifr = getreg32(regbase + AVR32_GPIO_IFR_OFFSET); + + /* Dispatch each pending interrupt */ + + irq = irqbase; + for (pin = 0; pin < 32 && ifr != 0; pin++) + { + /* Is this pin configured for interrupt support? */ + + uint32_t bit = (1 << pin); + if ((irqset & bit) != 0) + { + /* Is an interrupt pending on this pin? */ + + if ((ifr & bit) != 0) + { + /* Yes.. Clear the pending interrupt */ + + putreg32(bit, regbase + AVR32_GPIO_IFRC_OFFSET); + ifr &= ~bit; + + /* Dispatch handling for this pin */ + + xcpt_t handler = g_gpiohandler[irq]; + if (handler) + { + handler(irq, context); + } + else + { + lldbg("No handler: pin=%d ifr=%08x irqset=%08x", + pin, ifr, irqset); + } + } + + /* Increment the IRQ number on all configured pins */ + + irq++; + } + + /* Not configured. An interrupt on this pin would be an error. */ + + else if ((ifr & bit) != 0) + { + /* Clear the pending interrupt */ + + putreg32(bit, regbase + AVR32_GPIO_IFRC_OFFSET); + ifr &= ~bit; + + lldbg("IRQ on unconfigured pin: pin=%d ifr=%08x irqset=%08x", + pin, ifr, irqset); + } + } +} + +/**************************************************************************** + * Name: gpio0/1_interrupt + * + * Description: + * Handle GPIO0/1 interrupts + * + ****************************************************************************/ + +#if CONFIG_AVR32_GPIOIRQSETA != 0 +static int gpio0_interrupt(int irq, FAR void *context) +{ + gpio_porthandler(AVR32_GPIO0_BASE, __IRQ_GPIO_PA0, + CONFIG_AVR32_GPIOIRQSETA, context); + return 0; +} +#endif + +#if CONFIG_AVR32_GPIOIRQSETB != 0 +static int gpio1_interrupt(int irq, FAR void *context) +{ + gpio_porthandler(AVR32_GPIO1_BASE, __IRQ_GPIO_PB0, + CONFIG_AVR32_GPIOIRQSETB, context); + + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gpio_irqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler. + * + * Assumptions: + * Called during the early boot sequence before global interrupts have + * been enabled. + * + ****************************************************************************/ + +void gpio_irqinitialize(void) +{ + int i; + + /* Point all interrupt vectors to the unexpected interrupt */ + + for (i = 0; i < NR_GPIO_IRQS; i++) + { + g_gpiohandler[i] = irq_unexpected_isr; + } + + /* Then attach the GPIO interrupt handlers */ + +#if CONFIG_AVR32_GPIOIRQSETA != 0 + irq_attach(AVR32_IRQ_GPIO0, gpio0_interrupt); +#endif +#if CONFIG_AVR32_GPIOIRQSETB != 0 + irq_attach(AVR32_IRQ_GPIO1, gpio1_interrupt); +#endif +} + +/**************************************************************************** + * Name: gpio_irqattach + * + * Description: + * Attach in GPIO interrupt to the provide 'isr' + * + ****************************************************************************/ + +int gpio_irqattach(int irq, xcpt_t newisr, xcpt_t *oldisr) +{ + irqstate_t flags; + int ret = -EINVAL; + + if ((unsigned)irq < NR_GPIO_IRQS) + { + /* If the new ISR is NULL, then the ISR is being detached. In this + * case, disable the ISR and direct any interrupts + * to the unexpected interrupt handler. + */ + + flags = enter_critical_section(); + if (newisr == NULL) + { + gpio_irqdisable(irq); + newisr = irq_unexpected_isr; + } + + /* Return the old ISR (in case the caller ever wants to restore it) */ + + if (oldisr) + { + *oldisr = g_gpiohandler[irq]; + } + + /* Then save the new ISR in the table. */ + + g_gpiohandler[irq] = newisr; + leave_critical_section(flags); + ret = OK; + } + return ret; +} + +/**************************************************************************** + * Name: gpio_irqenable + * + * Description: + * Enable the GPIO IRQ specified by 'irq' + * + ****************************************************************************/ + +void gpio_irqenable(int irq) +{ + uint32_t base; + int pin; + + if ((unsigned)irq < NR_GPIO_IRQS) + { + /* Get the base address of the GPIO module associated with this IRQ */ + + base = gpio_baseaddress(irq); + + /* Get the pin number associated with this IRQ. We made life difficult + * here by choosing a sparse representation of IRQs on GPIO pins. + */ + + pin = gpio_pin(irq); + DEBUGASSERT(pin >= 0); + + /* Enable the GPIO interrupt. */ + + putreg32((1 << pin), base + AVR32_GPIO_IERS_OFFSET); + } +} + +/**************************************************************************** + * Name: gpio_irqdisable + * + * Description: + * Disable the GPIO IRQ specified by 'irq' + * + ****************************************************************************/ + +void gpio_irqdisable(int irq) +{ + uint32_t base; + int pin; + + if ((unsigned)irq < NR_GPIO_IRQS) + { + /* Get the base address of the GPIO module associated with this IRQ */ + + base = gpio_baseaddress(irq); + + /* Get the pin number associated with this IRQ. We made life difficult + * here by choosing a sparse representation of IRQs on GPIO pins. + */ + + pin = gpio_pin(irq); + DEBUGASSERT(pin >= 0); + + /* Disable the GPIO interrupt. */ + + putreg32((1 << pin), base + AVR32_GPIO_IERC_OFFSET); + } +} + +#endif /* CONFIG_AVR32_GPIOIRQ */ diff --git a/arch/avr/src/at32uc3/at32uc3_hmatrix.h b/arch/avr/src/at32uc3/at32uc3_hmatrix.h new file mode 100644 index 0000000000000000000000000000000000000000..40708fc1f162269c755518c00943117132de4cf3 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_hmatrix.h @@ -0,0 +1,314 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_hmatrix.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_HMATRIX_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_HMATRIX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_HMATRIX_MCFG_OFFSET(n) (0x0000+((n)<<2)) +#define AVR32_HMATRIX_MCFG0_OFFSET 0x0000 /* Master Configuration Register 0 */ +#define AVR32_HMATRIX_MCFG1_OFFSET 0x0004 /* Master Configuration Register 1 */ +#define AVR32_HMATRIX_MCFG2_OFFSET 0x0008 /* Master Configuration Register 2 */ +#define AVR32_HMATRIX_MCFG3_OFFSET 0x000c /* Master Configuration Register 3 */ +#define AVR32_HMATRIX_MCFG4_OFFSET 0x0010 /* Master Configuration Register 4 */ +#define AVR32_HMATRIX_MCFG5_OFFSET 0x0014 /* Master Configuration Register 5 */ +#define AVR32_HMATRIX_MCFG6_OFFSET 0x0018 /* Master Configuration Register 6 */ +#define AVR32_HMATRIX_MCFG7_OFFSET 0x001c /* Master Configuration Register 7 */ +#define AVR32_HMATRIX_MCFG8_OFFSET 0x0020 /* Master Configuration Register 8 */ +#define AVR32_HMATRIX_MCFG9_OFFSET 0x0024 /* Master Configuration Register 9 */ +#define AVR32_HMATRIX_MCFG10_OFFSET 0x0028 /* Master Configuration Register 10 */ +#define AVR32_HMATRIX_MCFG11_OFFSET 0x002c /* Master Configuration Register 11 */ +#define AVR32_HMATRIX_MCFG12_OFFSET 0x0030 /* Master Configuration Register 12 */ +#define AVR32_HMATRIX_MCFG13_OFFSET 0x0034 /* Master Configuration Register 13 */ +#define AVR32_HMATRIX_MCFG14_OFFSET 0x0038 /* Master Configuration Register 14 */ +#define AVR32_HMATRIX_MCFG15_OFFSET 0x003c /* Master Configuration Register 15 */ + +#define AVR32_HMATRIX_SCFG_OFFSET(n) (0x0040+((n)<<2)) +#define AVR32_HMATRIX_SCFG0_OFFSET 0x0040 /* Slave Configuration Register 0 */ +#define AVR32_HMATRIX_SCFG1_OFFSET 0x0044 /* Slave Configuration Register 1 */ +#define AVR32_HMATRIX_SCFG2_OFFSET 0x0048 /* Slave Configuration Register 2 */ +#define AVR32_HMATRIX_SCFG3_OFFSET 0x004c /* Slave Configuration Register 3 */ +#define AVR32_HMATRIX_SCFG4_OFFSET 0x0050 /* Slave Configuration Register 4 */ +#define AVR32_HMATRIX_SCFG5_OFFSET 0x0054 /* Slave Configuration Register 5 */ +#define AVR32_HMATRIX_SCFG6_OFFSET 0x0058 /* Slave Configuration Register 6 */ +#define AVR32_HMATRIX_SCFG7_OFFSET 0x005c /* Slave Configuration Register 7 */ +#define AVR32_HMATRIX_SCFG8_OFFSET 0x0060 /* Slave Configuration Register 8 */ +#define AVR32_HMATRIX_SCFG9_OFFSET 0x0064 /* Slave Configuration Register 9 */ +#define AVR32_HMATRIX_SCFG10_OFFSET 0x0068 /* Slave Configuration Register 10 */ +#define AVR32_HMATRIX_SCFG11_OFFSET 0x006c /* Slave Configuration Register 11 */ +#define AVR32_HMATRIX_SCFG12_OFFSET 0x0070 /* Slave Configuration Register 12 */ +#define AVR32_HMATRIX_SCFG13_OFFSET 0x0074 /* Slave Configuration Register 13 */ +#define AVR32_HMATRIX_SCFG14_OFFSET 0x0078 /* Slave Configuration Register 14 */ +#define AVR32_HMATRIX_SCFG15_OFFSET 0x007c /* Slave Configuration Register 15 */ + +#define AVR32_HMATRIX_PRAS_OFFSET(n) (0x0080+((n)<<3)) +#define AVR32_HMATRIX_PRBS_OFFSET(n) (0x0084+((n)<<3)) +#define AVR32_HMATRIX_PRAS0_OFFSET 0x0080 /* Priority Register A for Slave 0 */ +#define AVR32_HMATRIX_PRBS0_OFFSET 0x0084 /* Priority Register B for Slave 0 */ +#define AVR32_HMATRIX_PRAS1_OFFSET 0x0088 /* Priority Register A for Slave 1 */ +#define AVR32_HMATRIX_PRBS1_OFFSET 0x008c /* Priority Register B for Slave 1 */ +#define AVR32_HMATRIX_PRAS2_OFFSET 0x0090 /* Priority Register A for Slave 2 */ +#define AVR32_HMATRIX_PRBS2_OFFSET 0x0094 /* Priority Register B for Slave 2 */ +#define AVR32_HMATRIX_PRAS3_OFFSET 0x0098 /* Priority Register A for Slave 3 */ +#define AVR32_HMATRIX_PRBS3_OFFSET 0x009c /* Priority Register B for Slave 3 */ +#define AVR32_HMATRIX_PRAS4_OFFSET 0x00a0 /* Priority Register A for Slave 4 */ +#define AVR32_HMATRIX_PRBS4_OFFSET 0x00a4 /* Priority Register B for Slave 4 */ +#define AVR32_HMATRIX_PRAS5_OFFSET 0x00a8 /* Priority Register A for Slave 5 */ +#define AVR32_HMATRIX_PRBS5_OFFSET 0x00ac /* Priority Register B for Slave 5 */ +#define AVR32_HMATRIX_PRAS6_OFFSET 0x00b0 /* Priority Register A for Slave 6 */ +#define AVR32_HMATRIX_PRBS6_OFFSET 0x00b4 /* Priority Register B for Slave 6 */ +#define AVR32_HMATRIX_PRAS7_OFFSET 0x00b8 /* Priority Register A for Slave 7 */ +#define AVR32_HMATRIX_PRBS7_OFFSET 0x00bc /* Priority Register B for Slave 7 */ +#define AVR32_HMATRIX_PRAS8_OFFSET 0x00c0 /* Priority Register A for Slave 8 */ +#define AVR32_HMATRIX_PRBS8_OFFSET 0x00c4 /* Priority Register B for Slave 8 */ +#define AVR32_HMATRIX_PRAS9_OFFSET 0x00c8 /* Priority Register A for Slave 9 */ +#define AVR32_HMATRIX_PRBS9_OFFSET 0x00cc /* Priority Register B for Slave 9 */ +#define AVR32_HMATRIX_PRAS10_OFFSET 0x00d0 /* Priority Register A for Slave 10 */ +#define AVR32_HMATRIX_PRBS10_OFFSET 0x00d4 /* Priority Register B for Slave 10 */ +#define AVR32_HMATRIX_PRAS11_OFFSET 0x00d8 /* Priority Register A for Slave 11 */ +#define AVR32_HMATRIX_PRBS11_OFFSET 0x00dc /* Priority Register B for Slave 11 */ +#define AVR32_HMATRIX_PRAS12_OFFSET 0x00e0 /* Priority Register A for Slave 12 */ +#define AVR32_HMATRIX_PRBS12_OFFSET 0x00e4 /* Priority Register B for Slave 12 */ +#define AVR32_HMATRIX_PRAS13_OFFSET 0x00e8 /* Priority Register A for Slave 13 */ +#define AVR32_HMATRIX_PRBS13_OFFSET 0x00ec /* Priority Register B for Slave 13 */ +#define AVR32_HMATRIX_PRAS14_OFFSET 0x00f0 /* Priority Register A for Slave 14 */ +#define AVR32_HMATRIX_PRBS14_OFFSET 0x00f4 /* Priority Register B for Slave 14 */ +#define AVR32_HMATRIX_PRAS15_OFFSET 0x00f8 /* Priority Register A for Slave 15 */ +#define AVR32_HMATRIX_PRBS15_OFFSET 0x00fc /* Priority Register B for Slave 15 */ + +#define AVR32_HMATRIX_SFR_OFFSET(n) (0x0110+((n)<<2)) +#define AVR32_HMATRIX_SFR0_OFFSET 0x0110 /* Special Function Register 0 */ +#define AVR32_HMATRIX_SFR1_OFFSET 0x0114 /* Special Function Register 1 */ +#define AVR32_HMATRIX_SFR2_OFFSET 0x0118 /* Special Function Register 2 */ +#define AVR32_HMATRIX_SFR3_OFFSET 0x011c /* Special Function Register 3 */ +#define AVR32_HMATRIX_SFR4_OFFSET 0x0120 /* Special Function Register 4 */ +#define AVR32_HMATRIX_SFR5_OFFSET 0x0124 /* Special Function Register 5 */ +#define AVR32_HMATRIX_SFR6_OFFSET 0x0128 /* Special Function Register 6 */ +#define AVR32_HMATRIX_SFR7_OFFSET 0x012c /* Special Function Register 7 */ +#define AVR32_HMATRIX_SFR8_OFFSET 0x0130 /* Special Function Register 8 */ +#define AVR32_HMATRIX_SFR9_OFFSET 0x0134 /* Special Function Register 9 */ +#define AVR32_HMATRIX_SFR10_OFFSET 0x0138 /* Special Function Register 10 */ +#define AVR32_HMATRIX_SFR11_OFFSET 0x013c /* Special Function Register 11 */ +#define AVR32_HMATRIX_SFR12_OFFSET 0x0140 /* Special Function Register 12 */ +#define AVR32_HMATRIX_SFR13_OFFSET 0x0144 /* Special Function Register 13 */ +#define AVR32_HMATRIX_SFR14_OFFSET 0x0148 /* Special Function Register 14 */ +#define AVR32_HMATRIX_SFR15_OFFSET 0x014c /* Special Function Register 15 */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_HMATRIX_MCFG(n) (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG_OFFSET(n)) +#define AVR32_HMATRIX_MCFG0 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG0_OFFSET) +#define AVR32_HMATRIX_MCFG1 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG1_OFFSET) +#define AVR32_HMATRIX_MCFG2 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG2_OFFSET) +#define AVR32_HMATRIX_MCFG3 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG3_OFFSET) +#define AVR32_HMATRIX_MCFG4 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG4_OFFSET) +#define AVR32_HMATRIX_MCFG5 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG5_OFFSET) +#define AVR32_HMATRIX_MCFG6 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG6_OFFSET) +#define AVR32_HMATRIX_MCFG7 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG7_OFFSET) +#define AVR32_HMATRIX_MCFG8 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG8_OFFSET) +#define AVR32_HMATRIX_MCFG9 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG9_OFFSET) +#define AVR32_HMATRIX_MCFG10 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG10_OFFSET) +#define AVR32_HMATRIX_MCFG11 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG11_OFFSET) +#define AVR32_HMATRIX_MCFG12 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG12_OFFSET) +#define AVR32_HMATRIX_MCFG13 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG13_OFFSET) +#define AVR32_HMATRIX_MCFG14 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG14_OFFSET) +#define AVR32_HMATRIX_MCFG15 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_MCFG15_OFFSET) + +#define AVR32_HMATRIX_SCFG(n) (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG_OFFSET(n)) +#define AVR32_HMATRIX_SCFG0 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG0_OFFSET) +#define AVR32_HMATRIX_SCFG1 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG1_OFFSET) +#define AVR32_HMATRIX_SCFG2 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG2_OFFSET) +#define AVR32_HMATRIX_SCFG3 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG3_OFFSET) +#define AVR32_HMATRIX_SCFG4 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG4_OFFSET) +#define AVR32_HMATRIX_SCFG5 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG5_OFFSET) +#define AVR32_HMATRIX_SCFG6 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG6_OFFSET) +#define AVR32_HMATRIX_SCFG7 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG7_OFFSET) +#define AVR32_HMATRIX_SCFG8 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG8_OFFSET) +#define AVR32_HMATRIX_SCFG9 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG9_OFFSET) +#define AVR32_HMATRIX_SCFG10 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG10_OFFSET) +#define AVR32_HMATRIX_SCFG11 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG11_OFFSET) +#define AVR32_HMATRIX_SCFG12 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG12_OFFSET) +#define AVR32_HMATRIX_SCFG13 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG13_OFFSET) +#define AVR32_HMATRIX_SCFG14 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG14_OFFSET) +#define AVR32_HMATRIX_SCFG15 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SCFG15_OFFSET) + +#define AVR32_HMATRIX_PRAS(n) (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS_OFFSET(n)) +#define AVR32_HMATRIX_PRBS(n) (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS_OFFSET(n)) +#define AVR32_HMATRIX_PRAS0 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS0_OFFSET) +#define AVR32_HMATRIX_PRBS0 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS0_OFFSET) +#define AVR32_HMATRIX_PRAS1 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS1_OFFSET) +#define AVR32_HMATRIX_PRBS1 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS1_OFFSET) +#define AVR32_HMATRIX_PRAS2 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS2_OFFSET) +#define AVR32_HMATRIX_PRBS2 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS2_OFFSET) +#define AVR32_HMATRIX_PRAS3 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS3_OFFSET) +#define AVR32_HMATRIX_PRBS3 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS3_OFFSET) +#define AVR32_HMATRIX_PRAS4 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS4_OFFSET) +#define AVR32_HMATRIX_PRBS4 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS4_OFFSET) +#define AVR32_HMATRIX_PRAS5 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS5_OFFSET) +#define AVR32_HMATRIX_PRBS5 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS5_OFFSET) +#define AVR32_HMATRIX_PRAS6 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS6_OFFSET) +#define AVR32_HMATRIX_PRBS6 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS6_OFFSET) +#define AVR32_HMATRIX_PRAS7 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS7_OFFSET) +#define AVR32_HMATRIX_PRBS7 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS7_OFFSET) +#define AVR32_HMATRIX_PRAS8 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS8_OFFSET) +#define AVR32_HMATRIX_PRBS8 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS8_OFFSET) +#define AVR32_HMATRIX_PRAS9 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS9_OFFSET) +#define AVR32_HMATRIX_PRBS9 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS9_OFFSET) +#define AVR32_HMATRIX_PRAS10 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS10_OFFSET) +#define AVR32_HMATRIX_PRBS10 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS10_OFFSET) +#define AVR32_HMATRIX_PRAS11 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS11_OFFSET) +#define AVR32_HMATRIX_PRBS11 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS11_OFFSET) +#define AVR32_HMATRIX_PRAS12 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS12_OFFSET) +#define AVR32_HMATRIX_PRBS12 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS12_OFFSET) +#define AVR32_HMATRIX_PRAS13 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS13_OFFSET) +#define AVR32_HMATRIX_PRBS13 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS13_OFFSET) +#define AVR32_HMATRIX_PRAS14 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS14_OFFSET) +#define AVR32_HMATRIX_PRBS14 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS14_OFFSET) +#define AVR32_HMATRIX_PRAS15 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRAS15_OFFSET) +#define AVR32_HMATRIX_PRBS15 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_PRBS15_OFFSET) + +#define AVR32_HMATRIX_SFR(n) (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR_OFFSET(n)) +#define AVR32_HMATRIX_SFR0 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR0_OFFSET) +#define AVR32_HMATRIX_SFR1 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR1_OFFSET) +#define AVR32_HMATRIX_SFR2 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR2_OFFSET) +#define AVR32_HMATRIX_SFR3 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR3_OFFSET) +#define AVR32_HMATRIX_SFR4 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR4_OFFSET) +#define AVR32_HMATRIX_SFR5 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR5_OFFSET) +#define AVR32_HMATRIX_SFR6 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR6_OFFSET) +#define AVR32_HMATRIX_SFR7 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR7_OFFSET) +#define AVR32_HMATRIX_SFR8 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR8_OFFSET) +#define AVR32_HMATRIX_SFR9 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR9_OFFSET) +#define AVR32_HMATRIX_SFR10 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR10_OFFSET) +#define AVR32_HMATRIX_SFR11 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR11_OFFSET) +#define AVR32_HMATRIX_SFR12 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR12_OFFSET) +#define AVR32_HMATRIX_SFR13 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR13_OFFSET) +#define AVR32_HMATRIX_SFR14 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR14_OFFSET) +#define AVR32_HMATRIX_SFR15 (AVR32_HMATRIX_BASE+AVR32_HMATRIX_SFR15_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Master Configuration Register Bit-field Definitions */ + +#define HMATRIX_MCFG_UBLT_SHIFT (0) /* Bits 0-2: Undefined Length Burst Type */ +#define HMATRIX_MCFG_UBLT_MASK (7 << HMATRIX_MCFG_UBLT_SHIFT) +# define HMATRIX_MCFG_UBLT_INF (0 << HMATRIX_MCFG_UBLT_SHIFT) /* Infinite Length Burst */ +# define HMATRIX_MCFG_UBLT_SINGLE (1 << HMATRIX_MCFG_UBLT_SHIFT) /* Single Access */ +# define HMATRIX_MCFG_UBLT_4BEAT (2 << HMATRIX_MCFG_UBLT_SHIFT) /* Four Beat Burst */ +# define HMATRIX_MCFG_UBLT_8BEAT (3 << HMATRIX_MCFG_UBLT_SHIFT) /* Eight Beat Burst */ +# define HMATRIX_MCFG_UBLT_16BEAT (4 << HMATRIX_MCFG_UBLT_SHIFT) /* Sixteen Beat Burst */ + +/* Slave Configuration Register Bit-field Definitions */ + +#define HMATRIX_SCFG_SLOTCYCLE_SHIFT (0) /* Bits 0-7: Maximum Number of Allowed Cycles for a Burst +#define HMATRIX_SCFG_SLOTCYCLE_MASK (0xff << HMATRIX_SCFG_SLOTCYCLE_SHIFT) +#define HMATRIX_SCFG_DEFMSTRTYPE_SHIFT (16) /* Bits 16-17: Default Master Type +#define HMATRIX_SCFG_DEFMSTRTYPE_MASK (3 << HMATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define HMATRIX_SCFG_DEFMSTRTYPE_NONE (0 << HMATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define HMATRIX_SCFG_DEFMSTRTYPE_LAST (1 << HMATRIX_SCFG_DEFMSTRTYPE_SHIFT) +# define HMATRIX_SCFG_DEFMSTRTYPE_FIXED (2 << HMATRIX_SCFG_DEFMSTRTYPE_SHIFT) +#define HMATRIX_SCFG_FIXEDDEFMSTR_SHIFT (18) /* Bits 18-21: Fixed Default Master +#define HMATRIX_SCFG_FIXEDDEFMSTR_MASK (15 << HMATRIX_SCFG_FIXEDDEFMSTR_SHIFT) +#define HMATRIX_SCFG_ARBT (1 << 24) /* Bit 24: Arbitration Type */ + +/* Priority Register A for Slave Bit-field Definitions */ + +#define HMATRIX_PRAS_MPR_SHIFT(n) ((n) << 2) +#define HMATRIX_PRAS_MPR_MASK(n) (3 << HMATRIX_PRAS_MPR_SHIFT(n)) +#define HMATRIX_PRAS_M0PR_SHIFT (0) +#define HMATRIX_PRAS_M0PR_MASK (3 << HMATRIX_PRAS_M0PR_SHIFT) +#define HMATRIX_PRAS_M1PR_SHIFT (4) +#define HMATRIX_PRAS_M1PR_MASK (3 << HMATRIX_PRAS_M1PR_SHIFT) +#define HMATRIX_PRAS_M2PR_SHIFT (8) +#define HMATRIX_PRAS_M2PR_MASK (3 << HMATRIX_PRAS_M2PR_SHIFT) +#define HMATRIX_PRAS_M3PR_SHIFT (12) +#define HMATRIX_PRAS_M3PR_MASK (3 << HMATRIX_PRAS_M3PR_SHIFT) +#define HMATRIX_PRAS_M4PR_SHIFT (16) +#define HMATRIX_PRAS_M4PR_MASK (3 << HMATRIX_PRAS_M4PR_SHIFT) +#define HMATRIX_PRAS_M5PR_SHIFT (20) +#define HMATRIX_PRAS_M5PR_MASK (3 << HMATRIX_PRAS_M5PR_SHIFT) +#define HMATRIX_PRAS_M6PR_SHIFT (24) +#define HMATRIX_PRAS_M6PR_MASK (3 << HMATRIX_PRAS_M6PR_SHIFT) +#define HMATRIX_PRAS_M7PR_SHIFT (28) +#define HMATRIX_PRAS_M7PR_MASK (3 << HMATRIX_PRAS_M7PR_SHIFT) + +/* Priority Register B for Slave Bit-field Definitions */ + +#define HMATRIX_PRBS_MPR_SHIFT(n) (((n)-8) << 2) +#define HMATRIX_PRBS_MPR_MASK(n) (3 << HMATRIX_PRBS_MPR_SHIFT(n)) +#define HMATRIX_PRBS_M8PR_SHIFT (0) +#define HMATRIX_PRBS_M8PR_MASK (3 << HMATRIX_PRBS_M8PR_SHIFT) +#define HMATRIX_PRBS_M9PR_SHIFT (4) +#define HMATRIX_PRBS_M9PR_MASK (3 << HMATRIX_PRBS_M9PR_SHIFT) +#define HMATRIX_PRBS_M10PR_SHIFT (8) +#define HMATRIX_PRBS_M10PR_MASK (3 << HMATRIX_PRBS_M10PR_SHIFT) +#define HMATRIX_PRBS_M11PR_SHIFT (12) +#define HMATRIX_PRBS_M11PR_MASK (3 << HMATRIX_PRBS_M11PR_SHIFT) +#define HMATRIX_PRBS_M12PR_SHIFT (16) +#define HMATRIX_PRBS_M12PR_MASK (3 << HMATRIX_PRBS_M12PR_SHIFT) +#define HMATRIX_PRBS_M13PR_SHIFT (20) +#define HMATRIX_PRBS_M13PR_MASK (3 << HMATRIX_PRBS_M13PR_SHIFT) +#define HMATRIX_PRBS_M14PR_SHIFT (24) +#define HMATRIX_PRBS_M14PR_MASK (3 << HMATRIX_PRBS_M14PR_SHIFT) +#define HMATRIX_PRBS_M15PR_SHIFT (28) +#define HMATRIX_PRBS_M15PR_MASK (3 << HMATRIX_PRBS_M15PR_SHIFT) + +/* Special Function Register Bit-field Definitions */ +/* This register contains only the 32-bit SFR value and has no bit-fields */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_HMATRIX_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_intc.h b/arch/avr/src/at32uc3/at32uc3_intc.h new file mode 100644 index 0000000000000000000000000000000000000000..25aedd275b59bf3bfa0fa4a28d5c1b9b942a654c --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_intc.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_intc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_INTC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_INTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_INTC_IPR_OFFSET(n) ((n) << 2) /* Interrupt priority registers */ +#define AVR32_INTC_IRR_OFFSET(n) (0x100 + ((n) << 2)) /* Interrupt request registers */ +#define AVR32_INTC_ICR_OFFSET(n) (0x20c - ((n) << 2)) /* Interrupt cause registers */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_INTC_IPR(n) (AVR32_INTC_BASE+AVR32_INTC_IPR_OFFSET(n)) +#define AVR32_INTC_IRR(n) (AVR32_INTC_BASE+AVR32_INTC_IRR_OFFSET(n)) +#define AVR32_INTC_ICR(n) (AVR32_INTC_BASE+AVR32_INTC_ICR_OFFSET(n)) + +/* Register Bit-field Definitions ***************************************************/ + +/* Interrupt priority register bit-field definitions */ + +#define INTC_IPR_AUTOVECTOR_SHIFT (0) /* Bits 0-13: Autovector address */ +#define INTC_IPR_AUTOVECTOR_MASK (0x3fff << INTC_IPR_AUTOVECTOR_SHIFT) +#define INTC_IPR_INTLEVEL_SHIFT (30) /* Bits 30-31: Interrupt Level */ +#define INTC_IPR_INTLEVEL_MASK (3 << INTC_IPR_INTLEVEL_SHIFT) +# define INTC_IPR_INTLEVEL_INT0 (0 << INTC_IPR_INTLEVEL_SHIFT) /* Lowest priority */ +# define INTC_IPR_INTLEVEL_INT1 (1 << INTC_IPR_INTLEVEL_SHIFT) +# define INTC_IPR_INTLEVEL_INT2 (2 << INTC_IPR_INTLEVEL_SHIFT) +# define INTC_IPR_INTLEVEL_INT3 (3 << INTC_IPR_INTLEVEL_SHIFT) /* Highest priority */ + +/* Interrupt request register bit-field definitions */ + +#define INTC_IRR_REG(n) (AVR32_INTC_IPR((n) >> 5)) +#define INTC_IRR_SHIFT(n) (1 << ((n) & 0x1f)) +#define INTC_IRR_MASK(n) (1 << NTC_IRR_SHIFT(n)) + +/* Interrupt cause register bit-field definitions */ + +#define INTC_ICR_CAUSE_SHIFT (0) /* Bits 0-5: Interrupt Group Causing Interrupt of Priority n */ +#define INTC_ICR_CAUSE_MASK (0x3f << INTC_ICR_CAUSE_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_INTC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_irq.c b/arch/avr/src/at32uc3/at32uc3_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..6df9cdf4a6ceb5ee9051a2b0f5bb56e84971e653 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_irq.c @@ -0,0 +1,333 @@ +/**************************************************************************** + * arch/avr/src/at32uc3_/at32uc3_irq.c + * arch/avr/src/chip/at32uc3_irq.c + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at32uc3_config.h" + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "at32uc3.h" + +#include "chip.h" +#include "at32uc3_intc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* These symbols are exported from up_exceptions.S: + */ + +extern uint32_t vectortab; +extern uint32_t avr32_int0; +extern uint32_t avr32_int1; +extern uint32_t avr32_int2; +extern uint32_t avr32_int3; + +/* The provide interrupt handling offsets relative to the EVBA + * address (which should be vectortab). + */ + +#define AVR32_INT0_RADDR ((uint32_t)&avr32_int0 - (uint32_t)&vectortab) +#define AVR32_INT1_RADDR ((uint32_t)&avr32_int1 - (uint32_t)&vectortab) +#define AVR32_INT2_RADDR ((uint32_t)&avr32_int2 - (uint32_t)&vectortab) +#define AVR32_INT3_RADDR ((uint32_t)&avr32_int3 - (uint32_t)&vectortab) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct irq_groups_s +{ + uint8_t baseirq; /* IRQ number associated with bit 0 */ + uint8_t nirqs; /* Number of IRQs in this group */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This table maps groups into (1) the base IRQ number for the group and (2) + * the number of valid interrupts in the group. + */ + +static const struct irq_groups_s g_grpirqs[AVR32_IRQ_NGROUPS] = +{ + {AVR32_IRQ_BASEIRQGRP0, AVR32_IRQ_NREQGRP0 }, /* Group 0 */ + {AVR32_IRQ_BASEIRQGRP1, AVR32_IRQ_NREQGRP1 }, /* Group 1 */ + {AVR32_IRQ_BASEIRQGRP2, AVR32_IRQ_NREQGRP2 }, /* Group 2 */ + {AVR32_IRQ_BASEIRQGRP3, AVR32_IRQ_NREQGRP3 }, /* Group 3 */ + {AVR32_IRQ_BASEIRQGRP4, AVR32_IRQ_NREQGRP4 }, /* Group 4 */ + {AVR32_IRQ_BASEIRQGRP5, AVR32_IRQ_NREQGRP5 }, /* Group 5 */ + {AVR32_IRQ_BASEIRQGRP6, AVR32_IRQ_NREQGRP6 }, /* Group 6 */ + {AVR32_IRQ_BASEIRQGRP7, AVR32_IRQ_NREQGRP7 }, /* Group 7 */ + {AVR32_IRQ_BASEIRQGRP8, AVR32_IRQ_NREQGRP8 }, /* Group 8 */ + {AVR32_IRQ_BASEIRQGRP9, AVR32_IRQ_NREQGRP9 }, /* Group 9 */ + {AVR32_IRQ_BASEIRQGRP10, AVR32_IRQ_NREQGRP10}, /* Group 10 */ + {AVR32_IRQ_BASEIRQGRP11, AVR32_IRQ_NREQGRP11}, /* Group 11 */ + {AVR32_IRQ_BASEIRQGRP12, AVR32_IRQ_NREQGRP12}, /* Group 12 */ + {AVR32_IRQ_BASEIRQGRP13, AVR32_IRQ_NREQGRP13}, /* Group 13 */ + {AVR32_IRQ_BASEIRQGRP14, AVR32_IRQ_NREQGRP14}, /* Group 14 */ + {AVR32_IRQ_BASEIRQGRP15, AVR32_IRQ_NREQGRP15}, /* Group 15 */ + {AVR32_IRQ_BASEIRQGRP16, AVR32_IRQ_NREQGRP16}, /* Group 16 */ + {AVR32_IRQ_BASEIRQGRP17, AVR32_IRQ_NREQGRP17}, /* Group 17 */ + {AVR32_IRQ_BASEIRQGRP18, AVR32_IRQ_NREQGRP18}, /* Group 18 */ +}; + +/* The following table provides the value of the IPR register to + * use to assign a group to different interrupt priorities. + */ + +#if 0 /* REVISIT -- Can we come up with a way to statically initialize? */ +static const uint32_t g_ipr[AVR32_IRQ_INTPRIOS] = +{ + ((AVR32_INT0_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT0), + ((AVR32_INT1_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT1), + ((AVR32_INT2_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT2), + ((AVR32_INT3_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT3), +}; +#else +static uint32_t g_ipr[AVR32_IRQ_INTPRIOS]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getgrp + ****************************************************************************/ + +static int up_getgrp(unsigned int irq) +{ + int i; + + if (irq >= AVR32_IRQ_BASEIRQGRP0) + { + for (i = 0; i < AVR32_IRQ_NGROUPS; i++) + { + if (irq < g_grpirqs[i].baseirq + g_grpirqs[i].nirqs) + { + return i; + } + } + } + return -EINVAL; +} + +/**************************************************************************** + * Name: avr32_xcptn + * + * Description: + * Handlers for unexpected execptions. All are fatal error conditions. + * + ****************************************************************************/ + +static int avr32_xcptn(int irq, FAR void *context) +{ + (void)up_irq_save(); + lldbg("PANIC!!! Exception IRQ: %d\n", irq); + PANIC(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int group; + int irq; + + /* Initialize the table that provides the value of the IPR register to + * use to assign a group to different interrupt priorities. + */ + +#if 1 /* REVISIT -- Can we come up with a way to statically initialize? */ + g_ipr[0] = ((AVR32_INT0_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT0); + g_ipr[1] = ((AVR32_INT1_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT1); + g_ipr[2] = ((AVR32_INT2_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT2); + g_ipr[3] = ((AVR32_INT3_RADDR << INTC_IPR_AUTOVECTOR_SHIFT) | INTC_IPR_INTLEVEL_INT3); +#endif + + /* Set the interrupt group priority to a default value. All are linked to + * interrupt priority level 0 and to interrupt vector INT0. + */ + + for (group = 0; group < AVR32_IRQ_MAXGROUPS; group++) + { + putreg32(g_ipr[0], AVR32_INTC_IPR(group)); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Attach the exception handlers */ + + for (irq = 0; irq < AVR32_IRQ_NEVENTS; irq++) + { + irq_attach(irq, avr32_xcptn); + } + + /* Initialize GPIO interrupt facilities */ + +#ifdef CONFIG_AVR32_GPIOIRQ +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (gpio_irqinitialize != NULL) +#endif + { + gpio_irqinitialize(); + } +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(0); +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + if (priority >= 0 && priority < AVR32_IRQ_INTPRIOS) + { + int group = up_getgrp(irq); + if (group >= 0) + { + putreg32(g_ipr[priority], AVR32_INTC_IPR(group)); + return OK; + } + } + + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: avr32_intirqno + * + * Description: + * Return the highest priority pending INTn interrupt (hwere n=level). + * This is called directly from interrupt handling logic. This should be + * save since the UC3B will save all C scratch/volatile registers (and + * this function should not alter the perserved/static registers). + * + ****************************************************************************/ + +unsigned int avr32_intirqno(unsigned int level) +{ + /* Get the group that caused the interrupt: "ICRn identifies the group with + * the highest priority that has a pending interrupt of level n. This value + * is only defined when at least one interrupt of level n is pending. + */ + + uint32_t group = getreg32(AVR32_INTC_ICR(level)) & INTC_ICR_CAUSE_MASK; + if (group < AVR32_IRQ_NGROUPS) + { + /* Now get the set of pending interrupt requests for this group. + * Note that we may get spurious interrupts due to races conditions + */ + + uint32_t irr = getreg32(AVR32_INTC_IRR(group)); + unsigned irq = g_grpirqs[group].baseirq; + uint32_t mask = 1; + int i; + + /* Check each interrupt source for this group */ + + for (i = 0; i < g_grpirqs[group].nirqs; i++) + { + /* Is there an interrupt pending? */ + + if ((irr & mask) != 0) + { + /* Yes.. return its IRQ number */ + + return irq; + } + + /* No.. this is interrupt is not pending */ + + irq++; + mask <<= 1; + } + + lldbg("Spurious interrupt: group=%d IRR=%08x\n", group, irr); + return -ENODEV; + } + + lldbg("Bad group: %d\n", group); + return AVR32_IRQ_BADVECTOR; +} + + + diff --git a/arch/avr/src/at32uc3/at32uc3_lowconsole.c b/arch/avr/src/at32uc3/at32uc3_lowconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..8731ada4c0a60472fb4400c8037394fec72052b1 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_lowconsole.c @@ -0,0 +1,392 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_lowconsole.c + * + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at32uc3_config.h" + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "at32uc3.h" +#include "at32uc3_pm.h" +#include "at32uc3_usart.h" +#include "at32uc3_pinmux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define AVR32_CONSOLE_BASE AVR32_USART0_BASE +# define AVR32_CONSOLE_BAUD CONFIG_USART0_BAUD +# define AVR32_CONSOLE_BITS CONFIG_USART0_BITS +# define AVR32_CONSOLE_PARITY CONFIG_USART0_PARITY +# define AVR32_CONSOLE_2STOP CONFIG_USART0_2STOP +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define AVR32_CONSOLE_BASE AVR32_USART1_BASE +# define AVR32_CONSOLE_BAUD CONFIG_USART1_BAUD +# define AVR32_CONSOLE_BITS CONFIG_USART1_BITS +# define AVR32_CONSOLE_PARITY CONFIG_USART1_PARITY +# define AVR32_CONSOLE_2STOP CONFIG_USART1_2STOP +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define AVR32_CONSOLE_BASE AVR32_USART2_BASE +# define AVR32_CONSOLE_BAUD CONFIG_USART2_BAUD +# define AVR32_CONSOLE_BITS CONFIG_USART2_BITS +# define AVR32_CONSOLE_PARITY CONFIG_USART2_PARITY +# define AVR32_CONSOLE_2STOP CONFIG_USART2_2STOP +#else +# error "No CONFIG_USARTn_SERIAL_CONSOLE Setting" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart_putreg + * + * Description: + * Write a value to a USART register + * + ****************************************************************************/ + +#ifdef HAVE_RS232_DEVICE +static inline void usart_putreg(uintptr_t usart_base, unsigned int offset, uint32_t value) +{ + putreg32(value, usart_base + offset); +} +#endif + +/**************************************************************************** + * Name: usart_getreg + * + * Description: + * Get a value from a USART register + * + ****************************************************************************/ + +#ifdef HAVE_RS232_DEVICE +static inline uint32_t usart_getreg(uintptr_t usart_base, unsigned int offset) +{ + return getreg32(usart_base + offset); +} +#endif + +/**************************************************************************** + * Name: usart_setbaudrate + * + * Description: + * Configure the UART baud rate. + * + ****************************************************************************/ + +#ifdef HAVE_RS232_DEVICE +static void usart_setbaudrate(uintptr_t usart_base, uint32_t baudrate) +{ + uint32_t cd; + uint32_t mr; + + /* Select 16x or 8x oversampling mode or go to synchronous mode */ + + mr = usart_getreg(usart_base, AVR32_USART_MR_OFFSET); + if (baudrate < AVR32_PBA_CLOCK / 16) + { + /* Select 16x oversampling mode and clear the SYNC mode bit */ + + mr &= ~(USART_MR_OVER | USART_MR_SYNC); + + /* Calculate the clock divider assuming 16x oversampling */ + + cd = (AVR32_PBA_CLOCK + (baudrate << 3)) / (baudrate << 4); + } + else if (baudrate < AVR32_PBA_CLOCK / 8) + { + /* Select 8x oversampling mode and clear the SYNC mode bit */ + + mr &= ~USART_MR_SYNC; + mr |= USART_MR_OVER; + + /* Calculate the clock divider assuming 16x oversampling */ + + cd = (AVR32_PBA_CLOCK + (baudrate << 2)) / (baudrate << 3); + } + else + { + /* Set the SYNC mode bit */ + + mr |= USART_MR_SYNC; + + /* Use the undivided PBA clock */ + + cd = AVR32_PBA_CLOCK / baudrate; + } + + DEBUGASSERT(cd > 0 && cd < 65536); + usart_putreg(usart_base, AVR32_USART_MR_OFFSET, mr); + usart_putreg(usart_base, AVR32_USART_BRGR_OFFSET, cd); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart_reset + * + * Description: + * Reset a USART. + * + ****************************************************************************/ + +#ifdef HAVE_RS232_DEVICE +void usart_reset(uintptr_t usart_base) +{ + irqstate_t flags; + + /* Disable all USART interrupts */ + + flags = enter_critical_section(); + usart_putreg(usart_base, AVR32_USART_IDR_OFFSET, 0xffffffff); + leave_critical_section(flags); + + /* Reset mode and other registers */ + + usart_putreg(usart_base, AVR32_USART_MR_OFFSET, 0); /* Reset mode register */ + usart_putreg(usart_base, AVR32_USART_RTOR_OFFSET, 0); /* Reset receiver timeout register */ + usart_putreg(usart_base, AVR32_USART_TTGR_OFFSET, 0); /* Reset transmitter timeguard reg */ + + /* Disable RX and TX, put USART in reset, disable handshaking signals */ + + usart_putreg(usart_base, AVR32_USART_CR_OFFSET, + USART_CR_RSTRX | USART_CR_RSTTX | USART_CR_RSTSTA | + USART_CR_RSTIT | USART_CR_RSTNACK | USART_CR_DTRDIS | + USART_CR_RTSDIS); +} +#endif + +/**************************************************************************** + * Name: usart_configure + * + * Description: + * Configure a USART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_RS232_DEVICE +void usart_configure(uintptr_t usart_base, uint32_t baud, unsigned int parity, + unsigned int nbits, bool stop2) +{ + uint32_t regval; + + /* Reset the USART and disable RX and TX */ + + usart_reset(usart_base); + + /* Configure STOP bits */ + + regval = USART_MR_MODE_NORMAL | USART_MR_CHMODE_NORMAL; /* Normal RS-232 mode */ + regval |= stop2 ? USART_MR_NBSTOP_2 : USART_MR_NBSTOP_1; + + /* Configure parity */ + + switch (parity) + { + case 0: + default: + regval |= USART_MR_PAR_NONE; + break; + + case 1: + regval |= USART_MR_PAR_ODD; + break; + + case 2: + regval |= USART_MR_PAR_EVEN; + break; + } + + /* Configure the number of bits per word */ + + DEBUGASSERT(nbits >= 5 && nbits <= 9); + if (nbits == 9) + { + regval |= USART_MR_MODE9; + } + else + { + regval |= USART_MR_CHRL_BITS(nbits); + } + + usart_putreg(usart_base, AVR32_USART_MR_OFFSET, regval); + + /* Set the baud rate generation register */ + + usart_setbaudrate(usart_base, baud); + + /* Enable RX and TX */ + + regval = usart_getreg(usart_base, AVR32_USART_CR_OFFSET); + regval |= (USART_CR_RXEN | USART_CR_TXEN); + usart_putreg(usart_base, AVR32_USART_CR_OFFSET, regval); +} +#endif + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initialization sequence to configure the serial console uart + * (only). + * + ****************************************************************************/ + +void up_consoleinit(void) +{ + uint32_t pbamask = 0; + uint32_t regval; + + /* Setup GPIO pins fand enable module clocking or each configured USART/UART */ + +#ifdef CONFIG_AVR32_USART0_RS232 + /* PINMUX_USART0_RXD and PINMUX_USART0_TXD must be defined in board.h. It + * must define them be be one of {PINMUX_USART0_RXD_1, PINMUX_USART0_RXD_2} + * and {PINMUX_USART_0TXD_1, PINMUX_USART0_TXD_2}, respectively. + */ + + at32uc3_configgpio(PINMUX_USART0_RXD); + at32uc3_configgpio(PINMUX_USART0_TXD); + + /* Enable clocking to USART0 (This should be the default state after reset) */ + + pbamask |= PM_PBAMASK_USART0; + +#endif +#ifdef CONFIG_AVR32_USART1_RS232 + /* PINMUX_USART1_RXD and PINMUX_USART1_TXD must be defined in board.h. It + * must define them be be one of {PINMUX_USART1_RXD_1, PINMUX_USART1_RXD_2, + * PINMUX_USART1_RXD_3} and {PINMUX_USART1_TXD_1, PINMUX_USART1_TXD_2, + * PINMUX_USART1_TXD_3}, respectively. + */ + + at32uc3_configgpio(PINMUX_USART1_RXD); + at32uc3_configgpio(PINMUX_USART1_TXD); + + /* Enable clocking to USART1 (This should be the default state after reset) */ + + pbamask |= PM_PBAMASK_USART1; + +#endif +#ifdef CONFIG_AVR32_USART2_RS232 + /* PINMUX_USART2_RXD and PINMUX_USART2_TXD must be defined in board.h. It + * must define them be be one of {PINMUX_USART2_RXD_1, PINMUX_USART2_RXD_2} + * and {PINMUX_USART2_TXD_1, PINMUX_USART2_TXD_2}, respectively. + */ + + at32uc3_configgpio(PINMUX_USART2_RXD); + at32uc3_configgpio(PINMUX_USART2_TXD); + + /* Enable clocking to USART2 (This should be the default state after reset) */ + + pbamask |= PM_PBAMASK_USART2; + +#endif + + /* Enable selected clocks (and disabled unselected clocks) */ + + regval = getreg32(AVR32_PM_PBAMASK); + regval &= ~(PM_PBAMASK_USART0 | PM_PBAMASK_USART1 | PM_PBAMASK_USART2); + regval |= pbamask; + putreg32(regval, AVR32_PM_PBAMASK); + + /* Then configure the console here (if it is not going to be configured + * by up_earlyserialinit()). + */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(USE_EARLYSERIALINIT) + usart_configure(AVR32_CONSOLE_BASE, AVR32_CONSOLE_BAUD, AVR32_CONSOLE_PARITY, + AVR32_CONSOLE_BITS, (bool)AVR32_CONSOLE_2STOP); +#endif +} + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait until the TX to become ready */ + + while ((usart_getreg(AVR32_CONSOLE_BASE, AVR32_USART_CSR_OFFSET) & USART_CSR_TXRDY) == 0); + + /* Then send the character */ + + usart_putreg(AVR32_CONSOLE_BASE, AVR32_USART_THR_OFFSET, (uint32_t)ch); +#endif +} + diff --git a/arch/avr/src/at32uc3/at32uc3_lowinit.c b/arch/avr/src/at32uc3/at32uc3_lowinit.c new file mode 100644 index 0000000000000000000000000000000000000000..3f11a8755e2b93ac5764a9efbf0d28b1296bf598 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_lowinit.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_lowinit.c + * + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "at32uc3_config.h" +#include "up_internal.h" +#include "at32uc3.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowinit + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowinit(void) +{ + /* Initialize MCU clocking */ + + up_clkinitialize(); + + /* Initialize a console (probably a serial console) */ + + up_consoleinit(); + + /* Perform early serial initialization (so that we will have debug output + * available as soon as possible). + */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-level initialization */ + + at32uc3_boardinitialize(); +} + + diff --git a/arch/avr/src/at32uc3/at32uc3_memorymap.h b/arch/avr/src/at32uc3/at32uc3_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..8df5183f79d6bcaad61bb14fb1788cfe61b49895 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_memorymap.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_memorymap.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_MEMORYMAP_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Physical memory map */ + +#define AVR32_ONCHIP_SRAM_BASE 0x00000000 /* 16-64Kb SRAM */ +#define AVR32_GPIO_LBUS_BASE 0x40000000 /* Local bus mapped GPIO registers */ +#define AVR32_ONCHIP_FLASH_BASE 0x80000000 /* 64-512Kb Flash Array */ +# define AVR32_APPL_BASE 0x80002000 /* 8Kb offset to application w/bootloader */ +# define AVR32_USER_FLASH_BASE 0x80800000 /* Flash User Page */ +# define AVR32_BTLDR_CONFIG 0x808001fc /* Bootloader configuration word */ +#define AVR32_USBDATA_BASE 0xd0000000 /* USB data (64Kb) */ +#define AVR32_HSBPB_BRIDGEB 0xfffe0000 /* HSB-PB Bridge B (64Kb) */ +#define AVR32_HSBPB_BRIDGEA 0xffff0000 /* HSB-PB Bridge A (64Kb) */ + +/* Memory map for systems without an MMU */ + +#define AVR32_P1_BASE 0x80000000 /* 512MB non-translated space, cacheable */ +#define AVR32_P2_BASE 0xa0000000 /* 512MB non-translated space, non-cacheable */ +#define AVR32_P3_BASE 0xc0000000 /* 512MB translated space, cacheable */ +#define AVR32_P4_BASE 0xe0000000 /* 512MB system space, non-cacheable */ + +/* Reset vector addess */ + +#if defined(CONFIG_ARCH_CHIP_AT32UC3A) +# define AVR32_VECTOR_BASE AVR32_P1_BASE +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B) +# define AVR32_VECTOR_BASE AVR32_P2_BASE +#else +# warning "Unknown vector base address" +#endif + +/* Peripheral Address Map */ + +#define AVR32_USB_BASE 0xfffe0000 /* USB 2.0 Interface */ +#define AVR32_HMATRIX_BASE 0xfffe1000 /* HSB Matrix */ +#define AVR32_HFLASHC_BASE 0xfffe1400 /* Flash Controller */ +#define AVR32_PDCA_BASE 0xffff0000 /* Peripheral DMA Controller */ +#define AVR32_INTC_BASE 0xffff0800 /* Interrupt controller */ +#define AVR32_PM_BASE 0xffff0c00 /* Power Manager */ +#define AVR32_RTC_BASE 0xffff0d00 /* Real Time Counter */ +#define AVR32_WDT_BASE 0xffff0d30 /* Watchdog Timer */ +#define AVR32_EIM_BASE 0xffff0d80 /* External Interrupt Controller */ +#define AVR32_GPIO_BASE 0xffff1000 /* General Purpose Input/Output */ +#define AVR32_USART0_BASE 0xffff1400 /* USART0 */ +#define AVR32_USART1_BASE 0xffff1800 /* USART1 */ +#define AVR32_USART2_BASE 0xffff1c00 /* USART2 */ +#define AVR32_SPI0_BASE 0xffff2400 /* Serial Peripheral Interface 0 */ +#define AVR32_TWI_BASE 0xffff2c00 /* Two-wire Interface */ +#define AVR32_PWM_BASE 0xffff3000 /* Pulse Width Modulation Controller */ +#define AVR32_SSC_BASE 0xffff3400 /* Synchronous Serial Controller */ +#define AVR32_TC_BASE 0xffff3800 /* Timer/Counter */ +#define AVR32_ADC_BASE 0xffff3c00 /* Analog to Digital Converter */ +#define AVR32_ABDAC_BASE 0xffff4000 /* Audio Bitstream DAC */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_MEMORYMAP_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_pdca.h b/arch/avr/src/at32uc3/at32uc3_pdca.h new file mode 100644 index 0000000000000000000000000000000000000000..ee84f8f09080a242e819c349573dffeeb7d72d32 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_pdca.h @@ -0,0 +1,277 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_pdca.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_PDCA_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_PDCA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* DMA Channel Offsets **************************************************************/ + +#define AVR32_PDCA_CHAN_OFFSET(n) ((n) << 6) +#define AVR32_PDCA_CHAN0_OFFSET 0x000 +#define AVR32_PDCA_CHAN1_OFFSET 0x040 +#define AVR32_PDCA_CHAN2_OFFSET 0x080 +#define AVR32_PDCA_CHAN3_OFFSET 0x0c0 +#define AVR32_PDCA_CHAN4_OFFSET 0x100 +#define AVR32_PDCA_CHAN5_OFFSET 0x140 +#define AVR32_PDCA_CHAN6_OFFSET 0x180 +#define AVR32_PDCA_CHAN7_OFFSET 0x1c0 + +/* Channel Register Offsets *********************************************************/ + +#define AVR32_PDCA_MAR_OFFSET 0x000 /* Memory Address Register */ +#define AVR32_PDCA_PSR_OFFSET 0x004 /* Peripheral Select Register */ +#define AVR32_PDCA_TCR_OFFSET 0x008 /* Transfer Counter Register */ +#define AVR32_PDCA_MARR_OFFSET 0x00C /* Memory Address Reload Register */ +#define AVR32_PDCA_TCRR_OFFSET 0x010 /* Transfer Counter Reload Register */ +#define AVR32_PDCA_CR_OFFSET 0x014 /* Control Register */ +#define AVR32_PDCA_MR_OFFSET 0x018 /* Mode Register */ +#define AVR32_PDCA_SR_OFFSET 0x01C /* Status Register */ +#define AVR32_PDCA_IER_OFFSET 0x020 /* Interrupt Enable Register */ +#define AVR32_PDCA_IDR_OFFSET 0x024 /* Interrupt Disable Register */ +#define AVR32_PDCA_IMR_OFFSET 0x028 /* Interrupt Mask Register */ +#define AVR32_PDCA_ISR_OFFSET 0x02C /* Interrupt Status Register */ + +/* DMA Channel Base Addresses *******************************************************/ + +#define AVR32_PDCA_CHAN_BASE(n) (AVR32_PDCA_BASE+AVR32_PDCA_CHAN_OFFSET(n)) +#define AVR32_PDCA_CHAN0_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN0_OFFSET) +#define AVR32_PDCA_CHAN1_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN1_OFFSET) +#define AVR32_PDCA_CHAN2_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN2_OFFSET) +#define AVR32_PDCA_CHAN3_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN3_OFFSET) +#define AVR32_PDCA_CHAN4_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN4_OFFSET) +#define AVR32_PDCA_CHAN5_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN5_OFFSET) +#define AVR32_PDCA_CHAN6_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN6_OFFSET) +#define AVR32_PDCA_CHAN7_BASE (AVR32_PDCA_BASE+AVR32_PDCA_CHAN7_OFFSET) + +/* Channel Register Addresses *******************************************************/ + +#define AVR32_PDCA_MAR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_PSR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_TCR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_MARR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_TCRR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_MR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_SR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_IER(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_IDR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_IMR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_ISR(n) (AVR32_PDCA_CHAN_BASE(n)+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN0_MAR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN0_PSR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN0_TCR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN0_MARR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN0_TCRR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN0_CR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN0_MR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN0_SR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN0_IER (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN0_IDR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN0_IMR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN0_ISR (AVR32_PDCA_CHAN0_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN1_MAR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN1_PSR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN1_TCR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN1_MARR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN1_TCRR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN1_CR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN1_MR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN1_SR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN1_IER (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN1_IDR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN1_IMR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN1_ISR (AVR32_PDCA_CHAN1_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN2_MAR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN2_PSR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN2_TCR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN2_MARR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN2_TCRR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN2_CR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN2_MR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN2_SR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN2_IER (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN2_IDR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN2_IMR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN2_ISR (AVR32_PDCA_CHAN2_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN3_MAR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN3_PSR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN3_TCR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN3_MARR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN3_TCRR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN3_CR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN3_MR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN3_SR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN3_IER (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN3_IDR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN3_IMR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN3_ISR (AVR32_PDCA_CHAN3_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN4_MAR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN4_PSR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN4_TCR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN4_MARR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN4_TCRR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN4_CR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN4_MR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN4_SR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN4_IER (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN4_IDR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN4_IMR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN4_ISR (AVR32_PDCA_CHAN4_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN5_MAR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN5_PSR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN5_TCR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN5_MARR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN5_TCRR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN5_CR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN5_MR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN5_SR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN5_IER (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN5_IDR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN5_IMR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN5_ISR (AVR32_PDCA_CHAN5_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN6_MAR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN6_PSR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN6_TCR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN6_MARR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN6_TCRR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN6_CR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN6_MR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN6_SR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN6_IER (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN6_IDR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN6_IMR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN6_ISR (AVR32_PDCA_CHAN6_BASE+AVR32_PDCA_ISR_OFFSET) + +#define AVR32_PDCA_CHAN7_MAR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_MAR_OFFSET) +#define AVR32_PDCA_CHAN7_PSR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_PSR_OFFSET) +#define AVR32_PDCA_CHAN7_TCR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_TCR_OFFSET) +#define AVR32_PDCA_CHAN7_MARR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_MARR_OFFSET) +#define AVR32_PDCA_CHAN7_TCRR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_TCRR_OFFSET) +#define AVR32_PDCA_CHAN7_CR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_CR_OFFSET) +#define AVR32_PDCA_CHAN7_MR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_MR_OFFSET) +#define AVR32_PDCA_CHAN7_SR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_SR_OFFSET) +#define AVR32_PDCA_CHAN7_IER (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_IER_OFFSET) +#define AVR32_PDCA_CHAN7_IDR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_IDR_OFFSET) +#define AVR32_PDCA_CHAN7_IMR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_IMR_OFFSET) +#define AVR32_PDCA_CHAN7_ISR (AVR32_PDCA_CHAN7_BASE+AVR32_PDCA_ISR_OFFSET) + +/* Channel Register Bit-field Definitions *******************************************/ + +/* Memory Address Register Bit-field Definitions */ +/* Memory Address Reload Register Bit-field Definitions */ +/* These registers hold a 32-bit address and contain no bit-fields */ + +/* Peripheral Select Register Bit-field Definitions */ + +#define PDCA_PSR_PID_SHIFT (0) /* Bits 0-7: Peripheral Identifier */ +#define PDCA_PSR_PID_MASK (0xff << PDCA_PSR_PID_SHIFT) +# define PDCA_PSR_PID_ADC (0 << PDCA_PSR_PID_SHIFT) /* ADC */ +# define PDCA_PSR_PID_SSCRX (1 << PDCA_PSR_PID_SHIFT) /* SSC - RX */ +# define PDCA_PSR_PID_USART0RX (2 << PDCA_PSR_PID_SHIFT) /* USART0 - RX */ +# define PDCA_PSR_PID_USART1RX (3 << PDCA_PSR_PID_SHIFT) /* USART1 - RX */ +# define PDCA_PSR_PID_USART2RX (4 << PDCA_PSR_PID_SHIFT) /* USART2 - RX */ +# define PDCA_PSR_PID_TWIRX (5 << PDCA_PSR_PID_SHIFT) /* TWI - RX */ +# define PDCA_PSR_PID_SPI0RX (6 << PDCA_PSR_PID_SHIFT) /* SPI0 - RX */ +# define PDCA_PSR_PID_SSCTX (7 << PDCA_PSR_PID_SHIFT) /* SSC - TX */ +# define PDCA_PSR_PID_USART0TX (8 << PDCA_PSR_PID_SHIFT) /* USART0 - TX */ +# define PDCA_PSR_PID_USART1TX (9 << PDCA_PSR_PID_SHIFT) /* USART1 - TX */ +# define PDCA_PSR_PID_USART2TX (10 << PDCA_PSR_PID_SHIFT) /* USART2 - TX */ +# define PDCA_PSR_PID_TWITX (11 << PDCA_PSR_PID_SHIFT) /* TWI - TX */ +# define PDCA_PSR_PID_SPI0TX (12 << PDCA_PSR_PID_SHIFT) /* SPI0 - TX */ +# define PDCA_PSR_PID_ABDACTX (13 << PDCA_PSR_PID_SHIFT) /* ABDAC - TX */ + +/* Transfer Counter Register Bit-field Definitions */ +/* Transfer Counter Reload Register Bit-field Definitions */ + +#define PDCA_TCV_SHIFT (0) /* Bits 0-15: Transfer Counter Value */ +#define PDCA_TCV_MASK (0xffff << PDCA_TCV_SHIFT) + +/* Control Register Bit-field Definitions */ + +#define PDCA_CR_TEN (1 << 0) /* Bit 0: Transfer Enable */ +#define PDCA_CR_TDIS (1 << 1) /* Bit 1: Transfer Disable */ +#define PDCA_CR_ECLR (1 << 8) /* Bit 8: Transfer Error Clear */ + +/* Mode Register Bit-field Definitions */ + +#define PDCA_MR_SIZE_SHIFT (0) /* Bits 0-1: Prescale Select */ +#define PDCA_MR_SIZE_MASK (3 << PDCA_MR_SIZE_SHIFT) +# define PDCA_MR_SIZE_ BYTE (0 << PDCA_MR_SIZE_SHIFT) /* Byte */ +# define PDCA_MR_SIZE_ HWORD (1 << PDCA_MR_SIZE_SHIFT) /* Halfword */ +# define PDCA_MR_SIZE_ WORD (2 << PDCA_MR_SIZE_SHIFT) /* Word */ + +/* Status Register Bit-field Definitions */ + +#define PDCA_SR_TEN (1 << 0) /* Bit 0: Transfer Enabled */ + +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ +/* Interrupt Status Register Bit-field Definitions */ + +#define PDCA_INT_RCZ (1 << 0) /* Bit 0: Reload Counter Zero */ +#define PDCA_INT_TRC (1 << 1) /* Bit 1: Transfer Complete */ +#define PDCA_INT_TERR (1 << 2) /* Bit 2: Transfer Error */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_PDCA_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_pinmux.h b/arch/avr/src/at32uc3/at32uc3_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..e5c7e71436b3cc26d75417994b88cb076808725e --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_pinmux.h @@ -0,0 +1,71 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_pinmux.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_PINMUX_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_PINMUX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_ARCH_CHIP_AT32UC3B) +# include "at32uc3b_pinmux.h" +#elif defined(CONFIG_ARCH_CHIP_AT32UC3A) +# include "at32uc3a_pinmux.h" +#else +# error "Unknown AVR32 chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_PINMUX_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_pm.h b/arch/avr/src/at32uc3/at32uc3_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..964d839ee0072fdf97014d26f8de3e3f39f27508 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_pm.h @@ -0,0 +1,335 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_pm.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_PM_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_PM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_PM_MCCTRL_OFFSET 0x0000 /* Main Clock Control Register */ +#define AVR32_PM_CKSEL_OFFSET 0x0004 /* Clock Select Register */ +#define AVR32_PM_CPUMASK_OFFSET 0x0008 /* CPU Mask Register */ +#define AVR32_PM_HSBMASK_OFFSET 0x000c /* HSB Mask Register */ +#define AVR32_PM_PBAMASK_OFFSET 0x0010 /* PBA Mask Register */ +#define AVR32_PM_PBBMASK_OFFSET 0x0014 /* PBB Mask Register */ +#define AVR32_PM_PLL0_OFFSET 0x0020 /* PLL0 Control Register */ +#define AVR32_PM_PLL1_OFFSET 0x0024 /* PLL1 Control Register */ +#define AVR32_PM_OSCCTRL0_OFFSET 0x0028 /* Oscillator 0 Control Register */ +#define AVR32_PM_OSCCTRL1_OFFSET 0x002c /* Oscillator 1 Control Register */ +#define AVR32_PM_OSCCTRL32_OFFSET 0x0030 /* Oscillator 32 Control Register */ +#define AVR32_PM_IER_OFFSET 0x0040 /* Interrupt Enable Register */ +#define AVR32_PM_IDR_OFFSET 0x0044 /* Interrupt Disable Register */ +#define AVR32_PM_IMR_OFFSET 0x0048 /* Interrupt Mask Register */ +#define AVR32_PM_ISR_OFFSET 0x004c /* Interrupt Status Register */ +#define AVR32_PM_ICR_OFFSET 0x0050 /* Interrupt Clear Register */ +#define AVR32_PM_POSCSR_OFFSET 0x0054 /* Power and Oscillators Status Register */ +#define AVR32_PM_GCCTRL_OFFSET(n) (0x0060+((n)<<2)) /* 0x0060-0x070 Generic Clock Control Register */ +#define AVR32_PM_RCCR_OFFSET 0x00c0 /* RC Oscillator Calibration Register */ +#define AVR32_PM_BGCR_OFFSET 0x00c4 /* Bandgap Calibration Register */ +#define AVR32_PM_VREGCR_OFFSET 0x00c8 /* Linear Regulator Calibration Register */ +#define AVR32_PM_BOD_OFFSET 0x00d0 /* BOD Level Register BOD Read/Write */ +#define AVR32_PM_RCAUSE_OFFSET 0x0140 /* Reset Cause Register */ +#define AVR32_PM_AWEN_OFFSET 0x0144 /* Asynchronous Wake Up Enable Register */ +#define AVR32_PM_GPLP0_OFFSET 0x0200 /* General Purpose Low-Power Register 0 */ +#define AVR32_PM_GPLP1_OFFSET 0x0204 /* General Purpose Low-Power Register 1 */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_PM_MCCTRL (AVR32_PM_BASE+AVR32_PM_MCCTRL_OFFSET) +#define AVR32_PM_CKSEL (AVR32_PM_BASE+AVR32_PM_CKSEL_OFFSET) +#define AVR32_PM_CPUMASK (AVR32_PM_BASE+AVR32_PM_CPUMASK_OFFSET) +#define AVR32_PM_HSBMASK (AVR32_PM_BASE+AVR32_PM_HSBMASK_OFFSET) +#define AVR32_PM_PBAMASK (AVR32_PM_BASE+AVR32_PM_PBAMASK_OFFSET) +#define AVR32_PM_PBBMASK (AVR32_PM_BASE+AVR32_PM_PBBMASK_OFFSET) +#define AVR32_PM_PLL0 (AVR32_PM_BASE+AVR32_PM_PLL0_OFFSET) +#define AVR32_PM_PLL1 (AVR32_PM_BASE+AVR32_PM_PLL1_OFFSET) +#define AVR32_PM_OSCCTRL0 (AVR32_PM_BASE+AVR32_PM_OSCCTRL0_OFFSET) +#define AVR32_PM_OSCCTRL1 (AVR32_PM_BASE+AVR32_PM_OSCCTRL1_OFFSET) +#define AVR32_PM_OSCCTRL32 (AVR32_PM_BASE+AVR32_PM_OSCCTRL32_OFFSET) +#define AVR32_PM_IER (AVR32_PM_BASE+AVR32_PM_IER_OFFSET) +#define AVR32_PM_IDR (AVR32_PM_BASE+AVR32_PM_IDR_OFFSET) +#define AVR32_PM_IMR (AVR32_PM_BASE+AVR32_PM_IMR_OFFSET) +#define AVR32_PM_ISR (AVR32_PM_BASE+AVR32_PM_ISR_OFFSET) +#define AVR32_PM_ICR (AVR32_PM_BASE+AVR32_PM_ICR_OFFSET) +#define AVR32_PM_POSCSR (AVR32_PM_BASE+AVR32_PM_POSCSR_OFFSET) +#define AVR32_PM_GCCTRL(n) (AVR32_PM_BASE+AVR32_PM_GCCTRL_OFFSET(n)) +#define AVR32_PM_RCCR (AVR32_PM_BASE+AVR32_PM_RCCR_OFFSET) +#define AVR32_PM_BGCR (AVR32_PM_BASE+AVR32_PM_BGCR_OFFSET) +#define AVR32_PM_VREGCR (AVR32_PM_BASE+AVR32_PM_VREGCR_OFFSET) +#define AVR32_PM_BOD (AVR32_PM_BASE+AVR32_PM_BOD_OFFSET) +#define AVR32_PM_RCAUSE (AVR32_PM_BASE+AVR32_PM_RCAUSE_OFFSET) +#define AVR32_PM_AWEN (AVR32_PM_BASE+AVR32_PM_AWEN_OFFSET) +#define AVR32_PM_GPLP0 (AVR32_PM_BASE+AVR32_PM_GPLP0_OFFSET) +#define AVR32_PM_GPLP1 (AVR32_PM_BASE+AVR32_PM_GPLP1_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Main Clock Control Register Bit-field Definitions */ + +#define PM_MCCTRL_MCSEL_SHIFT (0) /* Bits 0-1: Main Clock Select */ +#define PM_MCCTRL_MCSEL_MASK (3 << PM_MCCTRL_MCSEL_SHIFT) +# define PM_MCCTRL_MCSEL_SLOW (0 << PM_MCCTRL_MCSEL_SHIFT) /* slow clock is source */ +# define PM_MCCTRL_MCSEL_OSC0 (1 << PM_MCCTRL_MCSEL_SHIFT) /* Oscillator 0 is source */ +# define PM_MCCTRL_MCSEL_PLL0 (2 << PM_MCCTRL_MCSEL_SHIFT) /* PLL0 is source */ +#define PM_MCCTRL_OSC0EN (1 << 2) /* Bit 2: Oscillator 0 Enable */ +#define PM_MCCTRL_OSC1EN (1 << 3) /* Bit 3: Oscillator 1 Enable */ + +/* Clock Select Register Bit-field Definitions */ + +#define PM_CKSEL_CPUSEL_SHIFT (0) /* Bits 0-2: CPU Clock Select */ +#define PM_CKSEL_CPUSEL_MASK (7 << PM_CKSEL_CPUSEL_SHIFT) +#define PM_CKSEL_CPUDIV (1 << 7) /* Bit 7: CPU Division */ +#define PM_CKSEL_HSBSEL_SHIFT (8) /* Bits 8-10: HSB Clock Select */ +#define PM_CKSEL_HSBSEL_MASK (7 << PM_CKSEL_HSBSEL_SHIFT) +#define PM_CKSEL_HSBDIV (1 << 15) /* Bit 15: HSB Division */ +#define PM_CKSEL_PBASEL_SHIFT (16) /* Bits 16-28: BA Clock Select */ +#define PM_CKSEL_PBASEL_MASK (7 << PM_CKSEL_PBASEL_SHIFT) +#define PM_CKSEL_PBADIV (1 << 23) /* Bit 23: PBA Division */ +#define PM_CKSEL_PBBSEL_SHIFT (24) /* Bits 24-26: PBB Clock Select */ +#define PM_CKSEL_PBBSEL_MASK (7 << PM_CKSEL_PBBSEL_SHIFT) +#define PM_CKSEL_PBBDIV (1 << 31) /* Bit 31: PBB Division */ + +/* CPU Mask Register Bit-field Definitions */ + +#define PM_CPUMASK_OCD (1 << 1) /* Bit 1: OCD */ + +/* HSB Mask Register Bit-field Definitions */ + +#define PM_HSBMASK_FLASHC (1 << 0) /* Bit 0: FLASHC */ +#define PM_HSBMASK_PBA (1 << 1) /* Bit 1: PBA bridge */ +#define PM_HSBMASK_PBB (1 << 2) /* Bit 2: PBB bridge */ +#define PM_HSBMASK_USBB (1 << 3) /* Bit 3: USBB */ +#define PM_HSBMASK_PDCA (1 << 4) /* Bit 4: PDCA */ + +/* PBA Mask Register Bit-field Definitions */ + +#define PM_PBAMASK_INTC (1 << 0) /* Bit 0: INTC */ +#define PM_PBAMASK_GPIO (1 << 1) /* Bit 1: GPIO */ +#define PM_PBAMASK_PDCA (1 << 2) /* Bit 2: PDCA */ +#define PM_PBAMASK_PMRTCEIC (1 << 3) /* Bit 3: PM/RTC/EIC */ +#define PM_PBAMASK_ADC (1 << 4) /* Bit 4: ADC */ +#define PM_PBAMASK_SPI (1 << 5) /* Bit 5: SPI */ +#define PM_PBAMASK_TWI (1 << 6) /* Bit 6: TWI */ +#define PM_PBAMASK_USART0 (1 << 7) /* Bit 7: USART0 */ +#define PM_PBAMASK_USART1 (1 << 8) /* Bit 8: USART1 */ +#define PM_PBAMASK_USART2 (1 << 9) /* Bit 9: USART2 */ +#define PM_PBAMASK_PWM (1 << 10) /* Bit 10: PWM */ +#define PM_PBAMASK_SSC (1 << 11) /* Bit 11: SSC */ +#define PM_PBAMASK_TC (1 << 12) /* Bit 12: TC */ +#define PM_PBAMASK_ABDAC (1 << 13) /* Bit 13: ABDAC */ + +/* PBB Mask Register Bit-field Definitions */ + +#define PM_PBBMASK_HMATRIX (1 << 0) /* Bit 0: HMATRIX */ +#define PM_PBBMASK_USBB (1 << 2) /* Bit 2: USBB */ +#define PM_PBBMASK_FLASHC (1 << 3) /* Bit 3: FLASHC */ + +/* PLL0/1 Control Register Bit-field Definitions */ + +#define PM_PLL_PLLEN (1 << 0) /* Bit 0: PLL Enable */ +#define PM_PLL_PLLOSC (1 << 1) /* Bit 1: PLL Oscillator Select */ +#define PM_PLL_PLLOPT_SHIFT (2) /* Bits 2-3: PLL Option */ +#define PM_PLL_PLLOPT_MASK (7 << PM_PLL_PLLOPT_SHIFT) +# define PM_PLL_PLLOPT_VCO (1 << PM_PLL_PLLOPT_SHIFT) /* Select the VCO frequency range */ +# define PM_PLL_PLLOPT_XTRADIV (2 << PM_PLL_PLLOPT_SHIFT) /* Enable the extra output divider */ +# define PM_PLL_PLLOPT_WBWDIS (4 << PM_PLL_PLLOPT_SHIFT) /* Disable the Wide-Bandwidth mode */ +#define PM_PLL_PLLDIV_SHIFT (8) /* Bits 8-11: PLL Division Factor */ +#define PM_PLL_PLLDIV_MASK (15 << PM_PLL_PLLDIV_SHIFT) +#define PM_PLL_PLLMUL_SHIFT (16) /* Bits 16-19: PLL Multiply Factor */ +#define PM_PLL_PLLMUL_MASK (15 << PM_PLL_PLLMUL_SHIFT) +#define PM_PLL_PLLCOUNT_SHIFT (24) /* Bits 24-29: PLL Count */ +#define PM_PLL_PLLCOUNT_MASK (0x3f << PM_PLL_PLLCOUNT_SHIFT) + +/* Oscillator 0/1 Control Register Bit-field Definitions */ + +#define PM_OSCCTRL_MODE_SHIFT (0) /* Bits 0-2: Oscillator Mode */ +#define PM_OSCCTRL_MODE_MASK (7 << PM_OSCCTRL_MODE_SHIFT) +# define PM_OSCCTRL_MODE_EXT (0 << PM_OSCCTRL_MODE_SHIFT) /* External clock */ +# define PM_OSCCTRL_MODE_XTALp9 (4 << PM_OSCCTRL_MODE_SHIFT) /* Crystal XIN 0.4-0.9MHz */ +# define PM_OSCCTRL_MODE_XTAL3 (5 << PM_OSCCTRL_MODE_SHIFT) /* Crystal XIN 0.9-3.0MHz */ +# define PM_OSCCTRL_MODE_XTAL8 (6 << PM_OSCCTRL_MODE_SHIFT) /* Crystal XIN 3.0-8.0MHz */ +# define PM_OSCCTRL_MODE_XTALHI (7 << PM_OSCCTRL_MODE_SHIFT) /* Crystal XIN above 8.0MHz */ +#define PM_OSCCTRL_STARTUP_SHIFT (8) /* Bits 8-10: Oscillator Startup Time */ +#define PM_OSCCTRL_STARTUP_MASK (7 << PM_OSCCTRL_STARTUP_SHIFT) +# define PM_OSCCTRL_STARTUP_0 (0 << PM_OSCCTRL_STARTUP_SHIFT) /* Num RCOsc cycles */ +# define PM_OSCCTRL_STARTUP_64 (1 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL_STARTUP_128 (2 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL_STARTUP_2K (3 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL_STARTUP_4K (4 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL_STARTUP_8K (5 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL_STARTUP_16K (6 << PM_OSCCTRL_STARTUP_SHIFT) /* " " " " " " */ + +/* Oscillator 32 Control Register Bit-field Definitions */ + +#define PM_OSCCTRL32_EN (1 << 0) /* Bit 0: Enable the 32KHz oscillator */ +#define PM_OSCCTRL32_MODE_SHIFT (8) /* Bits 8-10: Oscillator Mode */ +#define PM_OSCCTRL32_MODE_MASK (7 << PM_OSCCTRL32_MODE_SHIFT) +# define PM_OSCCTRL32_MODE_EXT (0 << PM_OSCCTRL32_MODE_SHIFT) /* External clock */ +# define PM_OSCCTRL32_MODE_XTAL (1 << PM_OSCCTRL32_MODE_SHIFT) /* Crystal */ +#define PM_OSCCTRL32_STARTUP_SHIFT (16) /* Bits 16-18: Oscillator Startup Time */ +#define PM_OSCCTRL32_STARTUP_MASK (7 << PM_OSCCTRL32_STARTUP_SHIFT) +# define PM_OSCCTRL32_STARTUP_0 (0 << PM_OSCCTRL32_STARTUP_SHIFT) /* Num RCOsc cycles */ +# define PM_OSCCTRL32_STARTUP_128 (1 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL32_STARTUP_8K (2 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL32_STARTUP_16K (3 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL32_STARTUP_64K (4 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL32_STARTUP_128K (5 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ +# define PM_OSCCTRL32_STARTUP_512K (6 << PM_OSCCTRL32_STARTUP_SHIFT) /* " " " " " " */ + +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ +/* Interrupt Status Register Bit-field Definitions */ +/* Interrupt Clear Register Bit-field Definitions */ + +#define PM_INT_LOCK0 (1 << 0) /* Bit 0: PLL0 locked */ +#define PM_INT_LOCK1 (1 << 1) /* Bit 1: PLL1 locked */ +#define PM_INT_CKRDY (1 << 5) /* Bit 5: Clock Ready */ +#define PM_INT_MSKRDY (1 << 6) /* Bit 6: Mask Ready */ +#define PM_INT_OSC0RDY (1 << 7) /* Bit 7: Oscillator 0 Ready */ +#define PM_INT_OSC1RDY (1 << 8) /* Bit 8: Oscillator 1 Ready */ +#define PM_INT_OSC32RDY (1 << 9) /* Bit 9: 32 KHz oscillator Ready */ +#define PM_INT_BODDET (1 << 16) /* Bit 16: Brown out detection */ + +/* Power and Oscillators Status Register Bit-field Definitions */ + +#define PM_POSCSR_LOCK0 (1 << 0) /* Bit 0: PLL0 locked */ +#define PM_POSCSR_LOCK1 (1 << 1) /* Bit 1: PLL1 locked */ +#define PM_POSCSR_WAKE (1 << 2) /* Bit 1: PLL1 locked */ +#define PM_POSCSR_CKRDY (1 << 5) /* Bit 5: Clock Ready */ +#define PM_POSCSR_MSKRDY (1 << 6) /* Bit 6: Mask Ready */ +#define PM_POSCSR_OSC0RDY (1 << 7) /* Bit 7: Oscillator 0 Ready */ +#define PM_POSCSR_OSC1RDY (1 << 8) /* Bit 8: Oscillator 1 Ready */ +#define PM_POSCSR_OSC32RDY (1 << 9) /* Bit 9: 32 KHz oscillator Ready */ +#define PM_POSCSR_BODDET (1 << 16) /* Bit 16: Brown out detection */ + +/* 0x0060-0x070 Generic Clock Control Register Bit-field Definitions */ + +#define PM_GCCTRL_OSCSEL (1 << 0) /* Bit 0: Oscillator Select */ +#define PM_GCCTRL_PLLSEL (1 << 1) /* Bit 1: PLL Select */ +#define PM_GCCTRL_CEN (1 << 2) /* Bit 2: Clock Enable */ +#define PM_GCCTRL_DIVEN (1 << 4) /* Bit 4: Divide Enable */ +#define PM_GCCTRL_DIV_SHIFT (8) /* Bits 8-15: Division Factor */ +#define PM_GCCTRL_DIV_MASK (0xff << PM_GCCTRL_DIV_SHIFT) + +/* RC Oscillator Calibration Register Bit-field Definitions */ + +#define PM_RCCR_CALIB_SHIFT (0) /* Bits 0-9: Calibration Value */ +#define PM_RCCR_CALIB_MASK (0x3ff << PM_RCCR_CALIB_SHIFT) +#define PM_RCCR_FCD (1 << 16) /* Bit 16: Flash Calibration Done */ +#define PM_RCCR_KEY_SHIFT (24) /* Bits 24-31: Register Write protection */ +#define PM_RCCR_KEY_MASK (0xff << PM_RCCR_KEY_SHIFT) + +/* Bandgap Calibration Register Bit-field Definitions */ + +#define PM_BGCR_CALIB_SHIFT (0) /* Bits 0-3: Calibration Value */ +#define PM_BGCR_CALIB_MASK (7 << PM_BGCR_CALIB_SHIFT) +#define PM_BGCR_FCD (1 << 16) /* Bit 16: Flash Calibration Done */ +#define PM_BGCR_KEY_SHIFT (24) /* Bits 24-31: Register Write protection */ +#define PM_BGCR_KEY_MASK (0xff << PM_BGCR_KEY_SHIFT) + +/* Linear Regulator Calibration Register Bit-field Definitions */ + +#define PM_VREGCR_CALIB_SHIFT (0) /* Bits 0-3: Calibration Value */ +#define PM_VREGCR_CALIB_MASK (7 << PM_VREGCR_CALIB_SHIFT) +#define PM_VREGCR_FCD (1 << 16) /* Bit 16: Flash Calibration Done */ +#define PM_VREGCR_KEY_SHIFT (24) /* Bits 24-31: Register Write protection */ +#define PM_VREGCR_KEY_MASK (0xff << PM_VREGCR_KEY_SHIFT) + +/* BOD Level Register BOD Read/Write Bit-field Definitions */ + +#define PM_BOD_LEVEL_SHIFT (0) /* Bits 0-5: BOD Level */ +#define PM_BOD_LEVEL_MASK (0x3f << PM_BOD_LEVEL_SHIFT) +#define PM_BOD_HYST (1 << 6) /* Bit 6: BOD Hysteresis */ +#define PM_BOD_CTRL_SHIFT (8) /* Bits 8-9: BOD Control */ +#define PM_BOD_CTRL_MASK (3 << PM_BOD_CTRL_SHIFT) +# define PM_BOD_CTRL_OFF (xxx << PM_BOD_CTRL_SHIFT) /* BOD is off */ +# define PM_BOD_CTRL_RESET (xxx << PM_BOD_CTRL_SHIFT) /* BOD enabled/can reset */ +# define PM_BOD_CTRL_NORESET (xxx << PM_BOD_CTRL_SHIFT) /* BOD enabled/cannot reset */ +#define PM_BOD_FCD (1 << 16) /* Bit 16: BOD Fuse calibration done */ +#define PM_BOD_KEY_SHIFT (24) /* Bits 24-31: Register Write protection */ +#define PM_BOD_KEY_MASK (0xff << PM_BOD_KEY_SHIFT) + +/* Reset Cause Register */ + +#define PM_RCAUSE_POR (1 << 0) /* Bit 0: Power-on Reset */ +#define PM_RCAUSE_BOD (1 << 1) /* Bit 1: Brown-out Reset */ +#define PM_RCAUSE_EXT (1 << 2) /* Bit 2: External Reset Pin */ +#define PM_RCAUSE_WDT (1 << 3) /* Bit 3: Watchdog Reset */ +#define PM_RCAUSE_JTAG (1 << 4) /* Bit 4: JTAG reset */ +#define PM_RCAUSE_SLEEP (1 << 6) /* Bit 6: Sleep */ +#define PM_RCAUSE_CPUERR (1 << 7) /* Bit 7: CPU Error */ +#define PM_RCAUSE_OCDRST (1 << 8) /* Bit 8: OCD Reset */ + +/* Asynchronous Wake Up Enable Register Bit-field Definitions */ + +#define PM_AWEN_USBWAKEN (1 << 0) /* Bit 0: USB Wake Up Enable */ + +/* General Purpose Low-Power Register 0/1 Bit-field Definitions */ + +/* These registers contain a 32-bit value with no smaller bit-field */ + +/* GCLK Allocation ******************************************************************/ + +#define AVR32_PM_GCLK0 (0) /* GCLK0 pin */ +#define AVR32_PM_GCLK1 (1) /* GCLK2 pin */ +#define AVR32_PM_GCLK2 (2) /* GCLK2 pin */ +#define AVR32_PM_GCLK_USBB (3) /* USBB */ +#define AVR32_PM_GCLK_ABDAC (4) /* ABDAC */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_PM_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_pwm.h b/arch/avr/src/at32uc3/at32uc3_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..5aedf7d601acbdfaf954587ea47c0132bd326b73 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_pwm.h @@ -0,0 +1,222 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_pwm.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_PWM_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* PWM Channel Offsets **************************************************************/ + +#define AVR32_PWM_CHAN_OFFSET(n) (0x200+((n)<<5)) +#define AVR32_PWM_CHAN0_OFFSET (0x200) +#define AVR32_PWM_CHAN1_OFFSET (0x220) + +/* Register offsets *****************************************************************/ + +#define AVR32_PWM_MR_OFFSET 0x000 /* PWM Mode Register */ +#define AVR32_PWM_ENA_OFFSET 0x004 /* PWM Enable Register */ +#define AVR32_PWM_DIS_OFFSET 0x008 /* PWM Disable Register */ +#define AVR32_PWM_SR_OFFSET 0x00c /* PWM Status Register */ +#define AVR32_PWM_IER_OFFSET 0x010 /* PWM Interrupt Enable Register */ +#define AVR32_PWM_IDR_OFFSET 0x014 /* PWM Interrupt Disable Register */ +#define AVR32_PWM_IMR_OFFSET 0x018 /* PWM Interrupt Mask Register */ +#define AVR32_PWM_ISR_OFFSET 0x01c /* PWM Interrupt Status Register */ + +#define AVR32_PWM_CMR_OFFSET 0x000 /* Channel Mode Register */ +#define AVR32_PWM_CDTY_OFFSET 0x004 /* Channel Duty Cycle Register */ +#define AVR32_PWM_CPRD_OFFSET 0x008 /* Channel Period Register */ +#define AVR32_PWM_CCNT_OFFSET 0x00c /* Channel Counter Register */ +#define AVR32_PWM_CUPD_OFFSET 0x010 /* Channel Update Register */ + +#define AVR32_PWMCH_CMR_OFFSET(n) (AVR32_PWM_CHAN_OFFSET(n)+PWM_CMR_OFFSET) +#define AVR32_PWMCH_CDTY_OFFSET(n) (AVR32_PWM_CHAN_OFFSET(n)+PWM_CDTY_OFFSET) +#define AVR32_PWMCH_CPRD_OFFSET(n) (AVR32_PWM_CHAN_OFFSET(n)+PWM_CPRD_OFFSET) +#define AVR32_PWMCH_CCNT_OFFSET(n) (AVR32_PWM_CHAN_OFFSET(n)+PWM_CCNT_OFFSET) +#define AVR32_PWMCH_CUPD_OFFSET(n) (AVR32_PWM_CHAN_OFFSET(n)+PWM_CUPD_OFFSET) + +#define AVR32_PWMCH0_CMR_OFFSET (AVR32_PWM_CHAN0_OFFSET+PWM_CMR_OFFSET) +#define AVR32_PWMCH0_CDTY_OFFSET (AVR32_PWM_CHAN0_OFFSET+PWM_CDTY_OFFSET) +#define AVR32_PWMCH0_CPRD_OFFSET (AVR32_PWM_CHAN0_OFFSET+PWM_CPRD_OFFSET) +#define AVR32_PWMCH0_CCNT_OFFSET (AVR32_PWM_CHAN0_OFFSET+PWM_CCNT_OFFSET) +#define AVR32_PWMCH0_CUPD_OFFSET (AVR32_PWM_CHAN0_OFFSET+PWM_CUPD_OFFSET) + +#define AVR32_PWMCH1_CMR_OFFSET (AVR32_PWM_CHAN1_OFFSET+PWM_CMR_OFFSET) +#define AVR32_PWMCH1_CDTY_OFFSET (AVR32_PWM_CHAN1_OFFSET+PWM_CDTY_OFFSET) +#define AVR32_PWMCH1_CPRD_OFFSET (AVR32_PWM_CHAN1_OFFSET+PWM_CPRD_OFFSET) +#define AVR32_PWMCH1_CCNT_OFFSET (AVR32_PWM_CHAN1_OFFSET+PWM_CCNT_OFFSET) +#define AVR32_PWMCH1_CUPD_OFFSET (AVR32_PWM_CHAN1_OFFSET+PWM_CUPD_OFFSET) + +/* PWM Channel Base Addresses *******************************************************/ + +#define AVR32_PWM_CHAN_BASE(n) (AVR32_PWM_BASE+PWM_CHAN_OFFSET(n)) +#define AVR32_PWM_CHAN0_BASE (AVR32_PWM_BASE+PWM_CHAN0_OFFSET) +#define AVR32_PWM_CHAN1_BASE (AVR32_PWM_BASE+PWM_CHAN1_OFFSET) + +/* Register Addresses ***************************************************************/ + +#define AVR32_PWM_MR (AVR32_PWM_BASE+AVR32_PWM_MR_OFFSET) +#define AVR32_PWM_ENA (AVR32_PWM_BASE+AVR32_PWM_ENA_OFFSET) +#define AVR32_PWM_DIS (AVR32_PWM_BASE+AVR32_PWM_DIS_OFFSET) +#define AVR32_PWM_SR (AVR32_PWM_BASE+AVR32_PWM_SR_OFFSET) +#define AVR32_PWM_IER (AVR32_PWM_BASE+AVR32_PWM_IER_OFFSET) +#define AVR32_PWM_IDR (AVR32_PWM_BASE+AVR32_PWM_IDR_OFFSET) +#define AVR32_PWM_IMR (AVR32_PWM_BASE+AVR32_PWM_IMR_OFFSET) +#define AVR32_PWM_ISR (AVR32_PWM_BASE+AVR32_PWM_ISR_OFFSET) + +#define AVR32_PWMCH_CMR(n) (AVR32_PWM_CHAN_BASE(n)+PWM_CMR_OFFSET) +#define AVR32_PWMCH_CDTY(n) (AVR32_PWM_CHAN_BASE(n)+PWM_CDTY_OFFSET) +#define AVR32_PWMCH_CPRD(n) (AVR32_PWM_CHAN_BASE(n)+PWM_CPRD_OFFSET) +#define AVR32_PWMCH_CCNT(n) (AVR32_PWM_CHAN_BASE(n)+PWM_CCNT_OFFSET) +#define AVR32_PWMCH_CUPD(n) (AVR32_PWM_CHAN_BASE(n)+PWM_CUPD_OFFSET) + +#define AVR32_PWMCH0_CMR (AVR32_PWM_CHAN0_BASE+PWM_CMR_OFFSET) +#define AVR32_PWMCH0_CDTY (AVR32_PWM_CHAN0_BASE+PWM_CDTY_OFFSET) +#define AVR32_PWMCH0_CPRD (AVR32_PWM_CHAN0_BASE+PWM_CPRD_OFFSET) +#define AVR32_PWMCH0_CCNT (AVR32_PWM_CHAN0_BASE+PWM_CCNT_OFFSET) +#define AVR32_PWMCH0_CUPD (AVR32_PWM_CHAN0_BASE+PWM_CUPD_OFFSET) + +#define AVR32_PWMCH1_CMR (AVR32_PWM_CHAN1_BASE+PWM_CMR_OFFSET) +#define AVR32_PWMCH1_CDTY (AVR32_PWM_CHAN1_BASE+PWM_CDTY_OFFSET) +#define AVR32_PWMCH1_CPRD (AVR32_PWM_CHAN1_BASE+PWM_CPRD_OFFSET) +#define AVR32_PWMCH1_CCNT (AVR32_PWM_CHAN1_BASE+PWM_CCNT_OFFSET) +#define AVR32_PWMCH1_CUPD (AVR32_PWM_CHAN1_BASE+PWM_CUPD_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* PWM Mode Register Bit-field Definitions */ + +#define PWM_MR_DIVA_SHIFT (0) /* Bits 0-7: CLKA Divide Factor */ +#define PWM_MR_DIVA_MASK (0xff << PWM_MR_DIVA_SHIFT) +# define PWM_MR_DIVA_OFF (0 << PWM_MR_DIVA_SHIFT) +# define PWM_MR_DIVA(n) ((n) << PWM_MR_DIVA_SHIFT) +#define PWM_MR_PREA_SHIFT (8) /* Bits 8-11 */ +#define PWM_MR_PREA_MASK (15 << PWM_MR_PREA_SHIFT) +# define PWM_MR_PREA_MCK (0 << PWM_MR_PREA_SHIFT) /* MCK */ +# define PWM_MR_PREA_MCKDIV2 (1 << PWM_MR_PREA_SHIFT) /* MCK/2 */ +# define PWM_MR_PREA_MCKDIV4 (2 << PWM_MR_PREA_SHIFT) /* MCK/4 */ +# define PWM_MR_PREA_MCKDIV8 (3 << PWM_MR_PREA_SHIFT) /* MCK/8 */ +# define PWM_MR_PREA_MCKDIV16 (4 << PWM_MR_PREA_SHIFT) /* MCK/16 */ +# define PWM_MR_PREA_MCKDIV32 (5 << PWM_MR_PREA_SHIFT) /* MCK/32 */ +# define PWM_MR_PREA_MCKDIV64 (6 << PWM_MR_PREA_SHIFT) /* MCK/64 */ +# define PWM_MR_PREA_MCKDIV128 (7 << PWM_MR_PREA_SHIFT) /* MCK/128 */ +# define PWM_MR_PREA_MCKDIV256 (8 << PWM_MR_PREA_SHIFT) /* MCK/256 */ +# define PWM_MR_PREA_MCKDIV512 (9 << PWM_MR_PREA_SHIFT) /* MCK/512 */ +# define PWM_MR_PREA_MCKDIV1024 (10 << PWM_MR_PREA_SHIFT) /* MCK/1024 */ +#define PWM_MR_DIVB_SHIFT (16) /* Bits 16-23: CLKB Divide Factor */ +#define PWM_MR_DIVB_MASK (0xff << PWM_MR_DIVB_SHIFT) +# define PWM_MR_DIVB_OFF (0 << PWM_MR_DIVB_SHIFT) +# define PWM_MR_DIVB(n) ((n) << PWM_MR_DIVB_SHIFT) +#define PWM_MR_PREB_SHIFT (24) /* Bits 24-27 */ +#define PWM_MR_PREB_MASK (15 << PWM_MR_PREB_SHIFT) +# define PWM_MR_PREB_MCK (0 << PWM_MR_PREB_SHIFT) /* MCK */ +# define PWM_MR_PREB_MCKDIV2 (1 << PWM_MR_PREB_SHIFT) /* MCK/2 */ +# define PWM_MR_PREB_MCKDIV4 (2 << PWM_MR_PREB_SHIFT) /* MCK/4 */ +# define PWM_MR_PREB_MCKDIV8 (3 << PWM_MR_PREB_SHIFT) /* MCK/8 */ +# define PWM_MR_PREB_MCKDIV16 (4 << PWM_MR_PREB_SHIFT) /* MCK/16 */ +# define PWM_MR_PREB_MCKDIV32 (5 << PWM_MR_PREB_SHIFT) /* MCK/32 */ +# define PWM_MR_PREB_MCKDIV64 (6 << PWM_MR_PREB_SHIFT) /* MCK/64 */ +# define PWM_MR_PREB_MCKDIV128 (7 << PWM_MR_PREB_SHIFT) /* MCK/128 */ +# define PWM_MR_PREB_MCKDIV256 (8 << PWM_MR_PREB_SHIFT) /* MCK/256 */ +# define PWM_MR_PREB_MCKDIV512 (9 << PWM_MR_PREB_SHIFT) /* MCK/512 */ +# define PWM_MR_PREB_MCKDIV1024 (10 << PWM_MR_PREB_SHIFT) /* MCK/1024 */ + +/* PWM Enable Register Bit-field Definitions */ +/* PWM Disable Register Bit-field Definitions */ +/* PWM Status Register Bit-field Definitions */ +/* PWM Interrupt Enable Register Bit-field Definitions */ +/* PWM Interrupt Disable Register Bit-field Definitions */ +/* PWM Interrupt Mask Register Bit-field Definitions */ +/* PWM Interrupt Status Register Bit-field Definitions */ + +#define PWM_CHID(n) (1 << (n)) /* Bit n: Channel ID n */ +#define PWM_CHID0 (1 << 0) /* Bit 0: Channel ID 0 */ +#define PWM_CHID1 (1 << 1) /* Bit 1: Channel ID 1 */ +#define PWM_CHID2 (1 << 2) /* Bit 2: Channel ID 2 */ +#define PWM_CHID3 (1 << 3) /* Bit 3: Channel ID 3 */ +#define PWM_CHID4 (1 << 4) /* Bit 4: Channel ID 4 */ +#define PWM_CHID5 (1 << 5) /* Bit 5: Channel ID 5 */ +#define PWM_CHID6 (1 << 6) /* Bit 6: Channel ID 6 */ + +/* Channel Mode Register Bit-field Definitions */ + +#define PWM_CMR_CPRE_SHIFT (0) /* Bits 0-3: CLKA Divide FactorChannel Pre-scaler */ +#define PWM_CMR_CPRE_MASK (15 << PWM_CMR_CPRE_SHIFT) +# define PWM_CMR_CPRE_MCK (0 << PWM_CMR_CPRE_SHIFT) /* MCK */ +# define PWM_CMR_CPRE_MCKDIV2 (1 << PWM_CMR_CPRE_SHIFT) /* MCK/2 */ +# define PWM_CMR_CPRE_MCKDIV4 (2 << PWM_CMR_CPRE_SHIFT) /* MCK/4 */ +# define PWM_CMR_CPRE_MCKDIV8 (3 << PWM_CMR_CPRE_SHIFT) /* MCK/8 */ +# define PWM_CMR_CPRE_MCKDIV16 (4 << PWM_CMR_CPRE_SHIFT) /* MCK/16 */ +# define PWM_CMR_CPRE_MCKDIV32 (5 << PWM_CMR_CPRE_SHIFT) /* MCK/32 */ +# define PWM_CMR_CPRE_MCKDIV64 (6 << PWM_CMR_CPRE_SHIFT) /* MCK/64 */ +# define PWM_CMR_CPRE_MCKDIV128 (7 << PWM_CMR_CPRE_SHIFT) /* MCK/128 */ +# define PWM_CMR_CPRE_MCKDIV256 (8 << PWM_CMR_CPRE_SHIFT) /* MCK/256 */ +# define PWM_CMR_CPRE_MCKDIV512 (9 << PWM_CMR_CPRE_SHIFT) /* MCK/512 */ +# define PWM_CMR_CPRE_MCKDIV1024 (10 << PWM_CMR_CPRE_SHIFT) /* MCK/1024 */ +# define PWM_CMR_CPRE_CLKA (11 << PWM_CMR_CPRE_SHIFT) /* CLKA */ +# define PWM_CMR_CPRE_CLKB (12 << PWM_CMR_CPRE_SHIFT) /* CLB */ +#define PWM_CMR_CALG (1 << 8) /* Bit 8: Channel Alignment */ +#define PWM_CMR_CPOL (1 << 9) /* Bit 9: Channel Polarity */ +#define PWM_CMR_CPD (1 << 10) /* Bit 10: Channel Update Period */ + +/* Channel Duty Cycle Register Bit-field Definitions */ +/* Channel Period Register Bit-field Definitions */ +/* Channel Counter Register Bit-field Definitions */ +/* Channel Update Register Bit-field Definitions */ + +/* These registers hold a 32-bit value with bit-fiels */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_PWM_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_rtc.h b/arch/avr/src/at32uc3/at32uc3_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..aa762065cb5ffcaacfb39de75def4354f47cf644 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_rtc.h @@ -0,0 +1,112 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_rtc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_RTC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_RTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_RTC_CTRL_OFFSET 0x00 /* Control Register */ +#define AVR32_RTC_VAL_OFFSET 0x04 /* Value Register */ +#define AVR32_RTC_TOP_OFFSET 0x08 /* Top Register */ +#define AVR32_RTC_IER_OFFSET 0x10 /* Interrupt Enable Register */ +#define AVR32_RTC_IDR_OFFSET 0x14 /* Interrupt Disable Register */ +#define AVR32_RTC_IMR_OFFSET 0x18 /* Interrupt Mask Register */ +#define AVR32_RTC_ISR_OFFSET 0x1c /* Interrupt Status Register */ +#define AVR32_RTC_ICR_OFFSET 0x20 /* Interrupt Clear Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_RTC_CTRL (AVR32_RTC_BASE+AVR32_RTC_CTRL_OFFSET) +#define AVR32_RTC_VAL (AVR32_RTC_BASE+AVR32_RTC_VAL_OFFSET) +#define AVR32_RTC_TOP (AVR32_RTC_BASE+AVR32_RTC_TOP_OFFSET) +#define AVR32_RTC_IER (AVR32_RTC_BASE+AVR32_RTC_IER_OFFSET) +#define AVR32_RTC_IDR (AVR32_RTC_BASE+AVR32_RTC_IDR_OFFSET) +#define AVR32_RTC_IMR (AVR32_RTC_BASE+AVR32_RTC_IMR_OFFSET) +#define AVR32_RTC_ISR (AVR32_RTC_BASE+AVR32_RTC_ISR_OFFSET) +#define AVR32_RTC_ICR (AVR32_RTC_BASE+AVR32_RTC_ICR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register Bit-field Definitions */ + +#define RTC_CTRL_EN (1 << 0) /* Bit 0: Enable */ +#define RTC_CTRL_PCLR (1 << 1) /* Bit 1: Prescaler Clear */ +#define RTC_CTRL_WAKEN (1 << 2) /* Bit 2: Wakeup Enable */ +#define RTC_CTRL_CLK32 (1 << 3) /* Bit 3: 32 KHz Oscillator Select */ +#define RTC_CTRL_BUSY (1 << 4) /* Bit 4: RTC Busy */ +#define RTC_CTRL_PSEL_SHIFT (8) /* Bits 8-11: Prescale Select */ +#define RTC_CTRL_PSEL_MASK (15 << RTC_CTRL_PSEL_SHIFT) +#define RTC_CTRL_CLKEN (1 << 16) /* Bit 16: Clock Enable */ + +/* Value Register Bit-field Definitions */ +/* This is a 32-bit data register and, hence, has no bit field */ + +/* Top Register Bit-field Definitions */ +/* This is a 32-bit data register and, hence, has no bit field */ + +/* Interrupt Enable Register Bit-field Definitions + * Interrupt Disable Register Bit-field Definitions + * Interrupt Mask Register Bit-field Definitions + * Interrupt Status Register Bit-field Definitions + * Interrupt Clear Register Bit-field Definitions + */ + +#define RTC_INT_TOPI (1 << 0) /* Bit 0: Top interrupt */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_RTC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_serial.c b/arch/avr/src/at32uc3/at32uc3_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..f01dcc6ac7bcdc8d6739e87fccac93a73df9bd75 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_serial.c @@ -0,0 +1,842 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_serial.c + * + * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "at32uc3_config.h" +#include "chip.h" +#include "at32uc3_usart.h" +#include "up_arch.h" +#include "up_internal.h" +#include "at32uc3.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Is there at least one USART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_RS232_DEVICE +# warning "No USARTs enabled as RS-232 devices" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which USART with be tty0/console and which tty1? */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# ifdef CONFIG_AVR32_USART1_RS232 +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# ifdef CONFIG_AVR32_USART2_RS232 +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# else +# undef TTYS2_DEV /* No ttyS2 */ +# endif +# else +# ifdef CONFIG_AVR32_USART2_RS232 +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# endif +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# ifdef CONFIG_AVR32_USART0_RS232 +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# ifdef CONFIG_AVR32_USART2_RS232 +# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */ +# else +# undef TTYS2_DEV /* No ttyS2 */ +# endif +# else +# ifdef CONFIG_AVR32_USART2_RS232 +# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# endif +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart2port /* USART2 is console */ +# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */ +# ifdef CONFIG_AVR32_USART0_RS232 +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# ifdef CONFIG_AVR32_USART1_RS232 +# define TTYS2_DEV g_usart1port /* USART1 is ttyS2 */ +# else +# undef TTYS2_DEV /* No ttyS2 */ +# endif +# else +# ifdef CONFIG_AVR32_USART1_RS232 +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +# undef TTYS2_DEV /* No ttyS2 */ +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t usartbase; /* Base address of USART registers */ + uint32_t baud; /* Configured baud */ + uint32_t csr; /* Saved channel status register contents */ + uint8_t irq; /* IRQ associated with this USART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5, 6, 7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; + +/* I/O buffers */ + +#ifdef CONFIG_AVR32_USART0_RS232 +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_AVR32_USART1_RS232 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_AVR32_USART2_RS232 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +#endif + +/* This describes the state of the AVR32 USART0 ports. */ + +#ifdef CONFIG_AVR32_USART0_RS232 +static struct up_dev_s g_usart0priv = +{ + .usartbase = AVR32_USART0_BASE, + .baud = CONFIG_USART0_BAUD, + .irq = AVR32_IRQ_USART0, + .parity = CONFIG_USART0_PARITY, + .bits = CONFIG_USART0_BITS, + .stopbits2 = CONFIG_USART0_2STOP, +}; + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart0priv, +}; +#endif + +/* This describes the state of the AVR32 USART1 port. */ + +#ifdef CONFIG_AVR32_USART1_RS232 +static struct up_dev_s g_usart1priv = +{ + .usartbase = AVR32_USART1_BASE, + .baud = CONFIG_USART1_BAUD, + .irq = AVR32_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, +}; + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, +}; +#endif + +/* This describes the state of the AVR32 USART2 port. */ + +#ifdef CONFIG_AVR32_USART2_RS232 +static struct up_dev_s g_usart2priv = +{ + .usartbase = AVR32_USART2_BASE, + .baud = CONFIG_USART2_BAUD, + .irq = AVR32_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, +}; + +static uart_dev_t g_usart2port = +{ + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static void up_restoreusartint(struct up_dev_s *priv, uint32_t imr) +{ + /* Re-enable interrupts as for each "1" bit in imr */ + + up_serialout(priv, AVR32_USART_IER_OFFSET, imr); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static inline void up_disableusartint(struct up_dev_s *priv, uint32_t *imr) +{ + if (imr) + { + *imr = up_serialin(priv, AVR32_USART_IMR_OFFSET); + } + + /* Disable all interrupts */ + + up_serialout(priv, AVR32_USART_IDR_OFFSET, USART_INT_ALL); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Configure the USART as an RS-232 UART */ + + usart_configure(priv->usartbase, priv->baud, priv->parity, + priv->bits, priv->stopbits2); +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Reset, disable interrupts, and disable Rx and Tx */ + + usart_reset(priv->usartbase); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Attach the IRQ */ + + return irq_attach(priv->irq, up_interrupt); +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, AVR32_USART_IDR_OFFSET, 0xffffffff); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + uint32_t csr; + int passes; + bool handled; + +#ifdef CONFIG_AVR32_USART0_RS232 + if (g_usart0priv.irq == irq) + { + dev = &g_usart0port; + } + else +#endif +#ifdef CONFIG_AVR32_USART1_RS232 + if (g_usart1priv.irq == irq) + { + dev = &g_usart1port; + } + else +#endif +#ifdef CONFIG_AVR32_USART2_RS232 + if (g_usart2priv.irq == irq) + { + dev = &g_usart2port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv); + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the USART channel status register contents. */ + + csr = up_serialin(priv, AVR32_USART_CSR_OFFSET); + priv->csr = csr; + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((csr & (USART_CSR_RXRDY | USART_CSR_TIMEOUT)) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + if ((csr & USART_CSR_TXRDY) != 0) + { + /* Transmit data regiser empty ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + struct inode *inode; + struct uart_dev_s *dev; + struct up_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct up_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rhr; + + /* Get the Rx byte. The USART Rx interrupt flag is cleared by side effect + * when reading the received character. + */ + + rhr = up_serialin(priv, AVR32_USART_RHR_OFFSET); + + /* Return status information */ + + if (status) + { + *status = priv->csr; + } + priv->csr = 0; + + /* Then return the actual received byte */ + + return rhr & USART_RHR_RXCHR_MASK; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +# ifdef CONFIG_USART_ERRINTS + up_serialout(priv, AVR32_USART_IER_OFFSET, + USART_INT_RXRDY | USART_INT_TIMEOUT | USART_INT_OVRE | + USART_INT_FRAME | USART_INT_PARE); +# else + up_serialout(priv, AVR32_USART_IER_OFFSET, + USART_INT_RXRDY | USART_INT_TIMEOUT); +# endif +#endif + } + else + { + up_serialout(priv, AVR32_USART_IDR_OFFSET, + USART_INT_RXRDY | USART_INT_TIMEOUT | USART_INT_OVRE | + USART_INT_FRAME | USART_INT_PARE); + } +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Read the channel status register and check if character is available to + * be read from the RHR. + */ + + regval = up_serialin(priv, AVR32_USART_CSR_OFFSET); + return (regval & USART_CSR_RXRDY) != 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the USART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, AVR32_USART_THR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_serialout(priv, AVR32_USART_IER_OFFSET, USART_INT_TXRDY); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_serialout(priv, AVR32_USART_IDR_OFFSET, USART_INT_TXRDY); + } + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Read the channel status register and check if THR is ready to accept + * another character. + */ + + regval = up_serialin(priv, AVR32_USART_CSR_OFFSET); + return (regval & USART_CSR_TXRDY) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable all USARTS */ + + up_disableusartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableusartint(TTYS1_DEV.priv, NULL); +#endif +#ifdef TTYS2_DEV + up_disableusartint(TTYS2_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t imr; + + up_disableusartint(priv, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreusartint(priv, imr); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/avr/src/at32uc3/at32uc3_spi.h b/arch/avr/src/at32uc3/at32uc3_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..1c1a804504dd84af57d468bc3b4a266a2ac76ed0 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_spi.h @@ -0,0 +1,166 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_spi.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_SPI_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_SPI_CR_OFFSET 0x000 /* Control Register */ +#define AVR32_SPI_MR_OFFSET 0x004 /* Mode Register */ +#define AVR32_SPI_RDR_OFFSET 0x008 /* Receive Data Register */ +#define AVR32_SPI_TDR_OFFSET 0x00c /* Transmit Data Register */ +#define AVR32_SPI_SR_OFFSET 0x010 /* Status Register */ +#define AVR32_SPI_IER_OFFSET 0x014 /* Interrupt Enable Register */ +#define AVR32_SPI_IDR_OFFSET 0x018 /* Interrupt Disable Register */ +#define AVR32_SPI_IMR_OFFSET 0x01c /* Interrupt Mask Register */ +#define AVR32_SPI_CSR0_OFFSET 0x030 /* Chip Select Register 0 */ +#define AVR32_SPI_CSR1_OFFSET 0x034 /* Chip Select Register 1 */ +#define AVR32_SPI_CSR2_OFFSET 0x038 /* Chip Select Register 2 */ +#define AVR32_SPI_CSR3_OFFSET 0x03c /* Chip Select Register 3 */ +#define AVR32_SPI_VERSION_OFFSET 0x0fc /* Version Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_SPI0_CR (AVR32_SPI0_BASE+AVR32_SPI_CR_OFFSET) +#define AVR32_SPI0_MR (AVR32_SPI0_BASE+AVR32_SPI_MR_OFFSET) +#define AVR32_SPI0_RDR (AVR32_SPI0_BASE+AVR32_SPI_RDR_OFFSET) +#define AVR32_SPI0_TDR (AVR32_SPI0_BASE+AVR32_SPI_TDR_OFFSET) +#define AVR32_SPI0_SR (AVR32_SPI0_BASE+AVR32_SPI_SR_OFFSET) +#define AVR32_SPI0_IER (AVR32_SPI0_BASE+AVR32_SPI_IER_OFFSET) +#define AVR32_SPI0_IDR (AVR32_SPI0_BASE+AVR32_SPI_IDR_OFFSET) +#define AVR32_SPI0_IMR (AVR32_SPI0_BASE+AVR32_SPI_IMR_OFFSET) +#define AVR32_SPI0_CSR0 (AVR32_SPI0_BASE+AVR32_SPI_CSR0_OFFSET) +#define AVR32_SPI0_CSR1 (AVR32_SPI0_BASE+AVR32_SPI_CSR1_OFFSET) +#define AVR32_SPI0_CSR2 (AVR32_SPI0_BASE+AVR32_SPI_CSR2_OFFSET) +#define AVR32_SPI0_CSR3 (AVR32_SPI0_BASE+AVR32_SPI_CSR3_OFFSET) +#define AVR32_SPI0_VERSION (AVR32_SPI0_BASE+AVR32_SPI_VERSION_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register */ + +#define SPI_CR_SPIEN (1 << 0) /* Bit 0: SPI Enable */ +#define SPI_CR_SPIDIS (1 << 1) /* Bit 1: SPI Disable */ +#define SPI_CR_SWRST (1 << 7) /* Bit 7: SPI Software Reset */ +#define SPI_CR_LASTXFER (1 << 24) /* Bit 24: Last Transfer */ + +/* Mode Register */ + + +#define SPI_MR_MSTR (1 << 0) /* Bit 0: Master/Slave Mode */ +#define SPI_MR_PS (1 << 1) /* Bit 1: Peripheral Select */ +#define SPI_MR_PCSDEC (1 << 2) /* Bit 2: Chip Select Decode */ +#define SPI_MR_MODFDIS (1 << 4) /* Bit 4: Mode Fault Detection */ +#define SPI_MR_LLB (1 << 7) /* Bit 7: Local Loopback Enable */ +#define SPI_MR_PCS_SHIFT (16) /* Bits 16-19: Peripheral Chip Select */ +#define SPI_MR_PCS_MASK (15 << SPI_MR_PCS_SHIFT) +#define SPI_MR_DLYBCS_SHIFT (24) /* Bits 24-31: Delay Between Chip Selects */ +#define SPI_MR_DLYBCS:_MASK (0xff << SPI_MR_DLYBCS_SHIFT) + +/* Receive Data Register */ + +#define SPI_RDR_MASK (0xffff) + +/* Transmit Data Register */ + +#define SPI_TDR_MASK (0xffff) + +/* Status Register */ +/* Interrupt Enable Register */ +/* Interrupt Disable Register */ +/* Interrupt Mask Register */ + +#define SPI_INT_DRF (1 << 0) /* Bit 0: Receive Data Register Full */ +#define SPI_INT_TDRE (1 << 1) /* Bit 1: Transmit Data Register Empty */ +#define SPI_INT_MODF (1 << 2) /* Bit 2: Mode Fault Error */ +#define SPI_INT_OVRES (1 << 3) /* Bit 3: Overrun Error Status */ +#define SPI_INT_NSSR (1 << 8) /* Bit 8: NSS Rising */ +#define SPI_INT_TXEMPTY (1 << 9) /* Bit 9: Transmission Registers Empty */ +#define SPI_SR_SPIENS (1 << 16) /* Bit 16: SPI Enable Status (SR only) */ + +/* Chip Select Register 0-3 */ + +#define SPI_CSR_CPOL (1 << 0) /* Bit 0: Clock Polarity */ +#define SPI_CSR_NCPHA (1 << 1) /* Bit 1: Clock Phase */ +#define SPI_CSR_CSNAAT (1 << 2) /* Bit 2: Chip Select Not Active After Transfer */ +#define SPI_CSR_CSAAT (1 << 3) /* Bit 3: Chip Select Active After Transfer */ +#define SPI_CSR_BITS_SHIFT (4) /* Bits 4-7: Bits Per Transfer */ +#define SPI_CSR_BITS_MASK (15 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_BITS(n) (((n)-8) << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_8BITS (0 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_9BITS (1 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_10BITS (2 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_11BITS (3 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_12BITS (4 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_13BITS (5 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_14BITS (6 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_15BITS (7 << SPI_CSR_BITS_SHIFT) +# define SPI_CSR_16BITS (8 << SPI_CSR_BITS_SHIFT) +#define SPI_CSR_SCBR_SHIFT (8) /* Bits 8-15: Serial Clock Baud Rate */ +#define SPI_CSR_SCBR_MASK (0xff << SPI_CSR_SCBR_SHIFT) +#define SPI_CSR_DLYBS_SHIFT (16) /* Bits 16-23: Delay Before SPCK */ +#define SPI_CSR_DLYBS_MASK (0xff << SPI_CSR_DLYBS_SHIFT) +#define SPI_CSR_DLYBCT_SHIFT (24) /* Bits 24-31: Delay Between Consecutive Transfers */ +#define SPI_CSR_DLYBCT_MASK (0xff << SPI_CSR_DLYBCT_SHIFT) + +/* Version Register (Values in the Version Register vary with the version of the IP + * block implementation.) + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_SPI_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_ssc.h b/arch/avr/src/at32uc3/at32uc3_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..e5c1df3c6248d8bdab2a292504271783b2adbcd8 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_ssc.h @@ -0,0 +1,267 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_ssc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_SSC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_SSC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_SSC_CR_OFFSET 0x00 /* Control Register */ +#define AVR32_SSC_CMR_OFFSET 0x04 /* Clock Mode Register */ +#define AVR32_SSC_RCMR_OFFSET 0x10 /* Receive Clock Mode Register */ +#define AVR32_SSC_RFMR_OFFSET 0x14 /* Receive Frame Mode Register */ +#define AVR32_SSC_TCMR_OFFSET 0x18 /* Transmit Clock Mode Register */ +#define AVR32_SSC_TFMR_OFFSET 0x1c /* Transmit Frame Mode Register */ +#define AVR32_SSC_RHR_OFFSET 0x20 /* Receive Holding Register */ +#define AVR32_SSC_THR_OFFSET 0x24 /* Transmit Holding Register */ +#define AVR32_SSC_RSHR_OFFSET 0x30 /* Receive Synchronization Holding Register */ +#define AVR32_SSC_TSHR_OFFSET 0x34 /* Transmit Synchronization Holding Register */ +#define AVR32_SSC_RC0R_OFFSET 0x38 /* Receive Compare 0 Register */ +#define AVR32_SSC_RC1R_OFFSET 0x3c /* Receive Compare 1 Register */ +#define AVR32_SSC_SR_OFFSET 0x40 /* Status Register */ +#define AVR32_SSC_IER_OFFSET 0x44 /* Interrupt Enable Register */ +#define AVR32_SSC_IDR_OFFSET 0x48 /* Interrupt Disable Register */ +#define AVR32_SSC_IMR_OFFSET 0x4c /* Interrupt Mask Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_SSC_CR (AVR32_SSC_BASE+AVR32_SSC_CR_OFFSET) +#define AVR32_SSC_CMR (AVR32_SSC_BASE+AVR32_SSC_CMR_OFFSET) +#define AVR32_SSC_RCMR (AVR32_SSC_BASE+AVR32_SSC_RCMR_OFFSET) +#define AVR32_SSC_RFMR (AVR32_SSC_BASE+AVR32_SSC_RFMR_OFFSET) +#define AVR32_SSC_TCMR (AVR32_SSC_BASE+AVR32_SSC_TCMR_OFFSET) +#define AVR32_SSC_TFMR (AVR32_SSC_BASE+AVR32_SSC_TFMR_OFFSET) +#define AVR32_SSC_RHR (AVR32_SSC_BASE+AVR32_SSC_RHR_OFFSET) +#define AVR32_SSC_THR (AVR32_SSC_BASE+AVR32_SSC_THR_OFFSET) +#define AVR32_SSC_RSHR (AVR32_SSC_BASE+AVR32_SSC_RSHR_OFFSET) +#define AVR32_SSC_TSHR (AVR32_SSC_BASE+AVR32_SSC_TSHR_OFFSET) +#define AVR32_SSC_RC0R (AVR32_SSC_BASE+AVR32_SSC_RC0R_OFFSET) +#define AVR32_SSC_RC1R (AVR32_SSC_BASE+AVR32_SSC_RC1R_OFFSET) +#define AVR32_SSC_SR (AVR32_SSC_BASE+AVR32_SSC_SR_OFFSET) +#define AVR32_SSC_IER (AVR32_SSC_BASE+AVR32_SSC_IER_OFFSET) +#define AVR32_SSC_IDR (AVR32_SSC_BASE+AVR32_SSC_IDR_OFFSET) +#define AVR32_SSC_IMR (AVR32_SSC_BASE+AVR32_SSC_IMR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register Bit-field Definitions */ + +#define SSC_CR_RXEN (1 << 0) /* Bit 0: Receive Enable */ +#define SSC_CR_RXDIS (1 << 1) /* Bit 1: Receive Disable */ +#define SSC_CR_TXEN (1 << 8) /* Bit 8: Transmit Enable */ +#define SSC_CR_TXDIS (1 << 9) /* Bit 9: Transmit Disable */ +#define SSC_CR_SWRST (1 << 15) /* Bit 15: Software Reset */ + +/* Clock Mode Register Bit-field Definitions */ + +#define SSC_CMR_DIV_SHIFT (0) /* Bits 0-11: Clock Divider */ +#define SSC_CMR_DIV_MASK (0xfff << SSC_CMR_DIV_SHIFT) + +/* Receive Clock Mode Register Bit-field Definitions */ + +#define SSC_RCMR_CKS_SHIFT (0) /* Bits 0-1: Receive Clock Selection */ +#define SSC_RCMR_CKS_MASK (3 << SSC_RCMR_CKS_SHIFT) +# define SSC_RCMR_CKS_DIVCLK (0 << SSC_RCMR_CKS_SHIFT) /* Divided clock */ +# define SSC_RCMR_CKS_TXCLK (1 << SSC_RCMR_CKS_SHIFT) /* TX_CLOCK clock signal */ +# define SSC_RCMR_CKS_RXCLK (2 << SSC_RCMR_CKS_SHIFT) /* RX_CLOCK pin */ +#define SSC_RCMR_CKO_SHIFT (2) /* Bits 2-4: Receive Clock Output Mode Selection */ +#define SSC_RCMR_CKO_MASK (7 << SSC_RCMR_CKO_SHIFT) +# define SSC_RCMR_CKO_NONE (0 << SSC_RCMR_CKO_SHIFT) /* None (Input-only) */ +# define SSC_RCMR_CKO_CONT (1 << SSC_RCMR_CKO_SHIFT) /* Continuous receive clock */ +# define SSC_RCMR_CKO_XFR (2 << SSC_RCMR_CKO_SHIFT) /* Receive clock only during data transfers */ +#define SSC_RCMR_CKI (1 << 5) /* Bit 5: Receive Clock Inversion */ +#define SSC_RCMR_CKG_SHIFT (6) /* Bits 6-7: Receive Clock Gating Selection */ +#define SSC_RCMR_CKG_MASK (3 << SSC_RCMR_CKG_SHIFT) +# define SSC_RCMR_CKG_NONE (0 << SSC_RCMR_CKG_SHIFT) /* None, continuous clock */ +# define SSC_RCMR_CKG_LOW (1 << SSC_RCMR_CKG_SHIFT) /* Enable if RX_FRAME_SYNC low */ +# define SSC_RCMR_CKG_HIGH (2 << SSC_RCMR_CKG_SHIFT) /* Enable if RX_FRAME_SYNC high */ +#define SSC_RCMR_START_SHIFT (8) /* Bits 8-11: Receive Start Selection */ +#define SSC_RCMR_START_MASK (15 << SSC_RCMR_START_SHIFT) +# define SSC_RCMR_START_CONT (0 << SSC_RCMR_START_SHIFT) /* Continuous */ +# define SSC_RCMR_START_XMTSTART (1 << SSC_RCMR_START_SHIFT) /* Transmit start */ +# define SSC_RCMR_START_LOW (2 << SSC_RCMR_START_SHIFT) /* RX_FRAME_SYNC low */ +# define SSC_RCMR_START_HIGH (3 << SSC_RCMR_START_SHIFT) /* RX_FRAME_SYNC high */ +# define SSC_RCMR_START_FALLING (4 << SSC_RCMR_START_SHIFT) /* Falling RX_FRAME_SYNC */ +# define SSC_RCMR_START_RISING (5 << SSC_RCMR_START_SHIFT) /* Rising RX_FRAME_SYNC */ +# define SSC_RCMR_START_CHANGE (6 << SSC_RCMR_START_SHIFT) /* RX_FRAME_SYNC change */ +# define SSC_RCMR_START_BOTH (7 << SSC_RCMR_START_SHIFT) /* Any edge RX_FRAME_SYNC */ +# define SSC_RCMR_START_CMP0 (8 << SSC_RCMR_START_SHIFT) /* Compare 0 */ +#define SSC_RCMR_STOP (1 << 12) /* Bit 12: Receive Stop Selection */ +#define SSC_RCMR_STTDLY_SHIFT (16) /* Bits 16-23: Receive Start Delay */ +#define SSC_RCMR_STTDLY_MASK (0xff << SSC_RCMR_STTDLY_SHIFT) +#define SSC_RCMR_PERIOD_SHIFT (24) /* Bits 24-31: Receive Period Divider Selection */ +#define SSC_RCMR_PERIOD_MASK (0xff << SSC_RCMR_PERIOD_SHIFT) + +/* Receive Frame Mode Register Bit-field Definitions */ + +#define SSC_RFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_RFMR_DATLEN_MASK (0x1f << SSC_RFMR_DATLEN_SHIFT) +#define SSC_RFMR_LOOP (1 << 5) /* Bit 5: Loop Mode */ +#define SSC_RFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_RFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per Frame */ +#define SSC_RFMR_DATNB_MASK (15 << SSC_RFMR_DATNB_SHIFT) +#define SSC_RFMR_FSLEN_SHIFT (16) /* Bits 16-19: Receive Frame Sync Length */ +#define SSC_RFMR_FSLEN_MASK (15 << SSC_RFMR_FSLEN_SHIFT) +#define SSC_RFMR_FSOS_SHIFT (20) /* Bits 20-22: Receive Frame Sync Output Selection */ +#define SSC_RFMR_FSOS_MASK (7 << SSC_RFMR_FSOS_SHIFT) +# define SSC_RFMR_FSOS_NONE (0 << SSC_RFMR_FSOS_SHIFT) /* None (Input-only )*/ +# define SSC_RFMR_FSOS_NEGP (1 << SSC_RFMR_FSOS_SHIFT) /* Negative Pulse */ +# define SSC_RFMR_FSOS_POSP (2 << SSC_RFMR_FSOS_SHIFT) /* Positive Pulse */ +# define SSC_RFMR_FSOS_LOW (3 << SSC_RFMR_FSOS_SHIFT) /* Driven Low during data transfer */ +# define SSC_RFMR_FSOS_HIGH (4 << SSC_RFMR_FSOS_SHIFT) /* Driven High during data transfer */ +# define SSC_RFMR_FSOS_TOGGLE (5 << SSC_RFMR_FSOS_SHIFT) /* Toggling at each start of data transfer */ +#define SSC_RFMR_FSEDGE (1 << 24) /* Bit 24: Receive Frame Sync Edge Detection */ +#define SSC_RFMR_FSLENHI_SHIFT (28) /* Bits 28-31: Receive Frame Sync Length High Part */ +#define SSC_RFMR_FSLENHI_MASK (15 << SSC_RFMR_FSLENHI_SHIFT) + +/* Transmit Clock Mode Register Bit-field Definitions */ + +#define SSC_TCMR_CKS_SHIFT (0) /* Bits 0-1: Transmit Clock Selection */ +#define SSC_TCMR_CKS_MASK (3 << SSC_TCMR_CKS_SHIFT) +# define SSC_TCMR_CKS_DIVCLK (0 << SSC_TCMR_CKS_SHIFT) /* Divided clock */ +# define SSC_TCMR_CKS_TXCLK (1 << SSC_TCMR_CKS_SHIFT) /* RX_CLOCK clock signal */ +# define SSC_TCMR_CKS_RXCLK (2 << SSC_TCMR_CKS_SHIFT) /* TX_CLOCK pin */ +#define SSC_TCMR_CKO_SHIFT (2) /* Bits 2-4: Transmit Clock Output Mode Selection */ +#define SSC_TCMR_CKO_MASK (7 << SSC_TCMR_CKO_SHIFT) +# define SSC_TCMR_CKO_NONE (0 << SSC_TCMR_CKO_SHIFT) /* None (Input-only) */ +# define SSC_TCMR_CKO_CONT (1 << SSC_TCMR_CKO_SHIFT) /* Continuous transmit clock Output */ +# define SSC_TCMR_CKO_XFR (2 << SSC_TCMR_CKO_SHIFT) /* Transmit clock only during data transfers Output */ +#define SSC_TCMR_CKI (1 << 5) /* Bit 5: Transmit Clock Inversion */ +#define SSC_TCMR_CKG_SHIFT (6) /* Bits 6-7: Transmit Clock Gating Selection */ +#define SSC_TCMR_CKG_MASK (3 << SSC_TCMR_CKG_SHIFT) +# define SSC_TCMR_CKG_NONE (0 << SSC_TCMR_CKG_SHIFT) /* None, continuous clock */ +# define SSC_TCMR_CKG_LOW (1 << SSC_TCMR_CKG_SHIFT) /* Enable if TX_FRAME_SYNC low */ +# define SSC_TCMR_CKG_HIGH (2 << SSC_TCMR_CKG_SHIFT) /* Enable if TX_FRAME_SYNC high */ +#define SSC_TCMR_START_SHIFT (8) /* Bits 8-11: Transmit Start Selection */ +#define SSC_TCMR_START_MASK (15 << SSC_TCMR_START_SHIFT) +# define SSC_TCMR_START_CONT (0 << SSC_TCMR_START_SHIFT) /* Continuous */ +# define SSC_TCMR_START_XMTSTART (1 << SSC_TCMR_START_SHIFT) /* Receive start */ +# define SSC_TCMR_START_LOW (2 << SSC_TCMR_START_SHIFT) /* TX_FRAME_SYNC low */ +# define SSC_TCMR_START_HIGH (3 << SSC_TCMR_START_SHIFT) /* TX_FRAME_SYNC high */ +# define SSC_TCMR_START_FALLING (4 << SSC_TCMR_START_SHIFT) /* Falling TX_FRAME_SYNC */ +# define SSC_TCMR_START_RISING (5 << SSC_TCMR_START_SHIFT) /* Rising TX_FRAME_SYNC */ +# define SSC_TCMR_START_CHANGE (6 << SSC_TCMR_START_SHIFT) /* TX_FRAME_SYNC change */ +# define SSC_TCMR_START_BOTH (7 << SSC_TCMR_START_SHIFT) /* Any edge TX_FRAME_SYNC */ +#define SSC_TCMR_STTDLY_SHIFT (16) /* Bits 16-23: Transmit Start Delay */ +#define SSC_TCMR_STTDLY_MASK (0xff << SSC_TCMR_STTDLY_SHIFT) +#define SSC_TCMR_PERIOD_SHIFT (24) /* Bits 24-31: Transmit Period Divider Selection */ +#define SSC_TCMR_PERIOD_MASK (0xff << SSC_TCMR_PERIOD_SHIFT) + +/* Transmit Frame Mode Register Bit-field Definitions */ + +#define SSC_TFMR_DATLEN_SHIFT (0) /* Bits 0-4: Data Length */ +#define SSC_TFMR_DATLEN_MASK (0x1f << SSC_TFMR_DATLEN_SHIFT) +#define SSC_TFMR_DATDEF (1 << 5) /* Bit 5: Data Default Value */ +#define SSC_TFMR_MSBF (1 << 7) /* Bit 7: Most Significant Bit First */ +#define SSC_TFMR_DATNB_SHIFT (8) /* Bits 8-11: Data Number per Frame */ +#define SSC_TFMR_DATNB_MASK (15 << SSC_TFMR_DATNB_SHIFT) +#define SSC_TFMR_FSLEN_SHIFT (16) /* Bits 16-19: Transmit Frame Sync Length */ +#define SSC_TFMR_FSLEN_MASK (15 << SSC_TFMR_FSLEN_SHIFT) +#define SSC_TFMR_FSOS_SHIFT (20) /* Bits 20-22: Transmit Frame Sync Data Enable */ +#define SSC_TFMR_FSOS_MASK (7 << SSC_TFMR_FSOS_SHIFT) +# define SSC_TFMR_FSOS_NONE (0 << SSC_TFMR_FSOS_SHIFT) /* None (Input-only )*/ +# define SSC_TFMR_FSOS_NEGP (1 << SSC_TFMR_FSOS_SHIFT) /* Negative Pulse */ +# define SSC_TFMR_FSOS_POSP (2 << SSC_TFMR_FSOS_SHIFT) /* Positive Pulse */ +# define SSC_TFMR_FSOS_LOW (3 << SSC_TFMR_FSOS_SHIFT) /* Driven Low during data transfer */ +# define SSC_TFMR_FSOS_HIGH (4 << SSC_TFMR_FSOS_SHIFT) /* Driven High during data transfer */ +# define SSC_TFMR_FSOS_TOGGLE (5 << SSC_TFMR_FSOS_SHIFT) /* Toggling at each start of data transfer */ +#define SSC_TFMR_FSDEN (1 << 23) /* Bit 23: Transmit Frame Sync Data Enable */ +#define SSC_TFMR_FSEDGE (1 << 24) /* Bit 24: Transmit Frame Sync Edge Detection */ +#define SSC_TFMR_FSLENHI_SHIFT (28) /* Bits 28-31: Transmit Frame Sync Length High Part */ +#define SSC_TFMR_FSLENHI_MASK (15 << SSC_TFMR_FSLENHI_SHIFT) + +/* Receive Holding Register Bit-field Definitions */ +/* Transmit Holding Register Bit-field Definitions */ + +/* These register hold 32-bit values with no bit-fields */ + +/* Receive Synchronization Holding Register Bit-field Definitions */ + +#define SSC_RSHR_MASK (0xffff) + +/* Transmit Synchronization Holding Register Bit-field Definitions */ + +#define SSC_TSHR_MASK (0xffff) + +/* Receive Compare 0 Register Bit-field Definitions */ + +#define SSC_RC0R_MASK (0xffff) + +/* Receive Compare 1 Register Bit-field Definitions */ + +#define SSC_RC1R_MASK (0xffff) + +/* Interrupt Enable Register Bit-field Definitions */ +/* Interrupt Disable Register Bit-field Definitions */ +/* Interrupt Mask Register Bit-field Definitions */ + +#define SSC_INT_TXRDY (1 << 0) /* Bit 0: Transmit Ready */ +#define SSC_INT_TXEMPTY (1 << 1) /* Bit 1: Transmit Empty */ +#define SSC_INT_RXRDY (1 << 4) /* Bit 4: Receive Ready */ +#define SSC_INT_OVRUN (1 << 5) /* Bit 5: Receive Overrun */ +#define SSC_INT_CP0 (1 << 8) /* Bit 8: Compare 0 */ +#define SSC_INT_CP1 (1 << 9) /* Bit 9: Compare 1 */ +#define SSC_INT_TXSYN (1 << 10) /* Bit 10: Transmit Sync */ +#define SSC_INT_RXSYN (1 << 11) /* Bit 11: Receive Sync */ + +/* Status Register Bit-field Definitions (Only) */ + +#define SSC_SR_TXEN (1 << 16) /* Bit 16: Transmit Enable */ +#define SSC_SR_RXEN (1 << 17) /* Bit 17: Receive Enable */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_SSC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_tc.h b/arch/avr/src/at32uc3/at32uc3_tc.h new file mode 100644 index 0000000000000000000000000000000000000000..f3773c161e5a1bef49b690ea410b3cdc12cedb47 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_tc.h @@ -0,0 +1,372 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_tc.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_TC_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_TC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Timer Channel Offset *************************************************************/ + +#define AVR32_TC_CHAN_OFFSET(n) ((n) << 6) +#define AVR32_TC_CHAN0_OFFSET (0x000) +#define AVR32_TC_CHAN1_OFFSET (0x040) +#define AVR32_TC_CHAN2_OFFSET (0x080) + +/* Register offsets *****************************************************************/ + +#define AVR32_TC_CCR_OFFSET 0x000 /* Channel Control Register */ +#define AVR32_TC_CMR_OFFSET 0x004 /* Channel Mode Register */ +#define AVR32_TC_CV_OFFSET 0x010 /* Channel Counter Value */ +#define AVR32_TC_RA_OFFSET 0x014 /* Channel Register A */ +#define AVR32_TC_RB_OFFSET 0x018 /* Channel Register B */ +#define AVR32_TC_RC_OFFSET 0x01c /* Channel Register C */ +#define AVR32_TC_SR_OFFSET 0x020 /* Channel Status Register */ +#define AVR32_TC_IER_OFFSET 0x024 /* Interrupt Enable Register */ +#define AVR32_TC_IDR_OFFSET 0x028 /* Channel Interrupt Disable Register */ +#define AVR32_TC_IMR_OFFSET 0x02c /* Channel Interrupt Mask Register */ + +#define AVR32_TC_CCRn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMRn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CVn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RAn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RBn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RCn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SRn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IERn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDRn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMRn_OFFSET(n) (AVR32_TC_CHAN0_OFFSET(n)+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR0_OFFSET (AVR32_TC_CHAN0_OFFSET+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR1_OFFSET (AVR32_TC_CHAN1_OFFSET+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR2_OFFSET (AVR32_TC_CHAN2_OFFSET+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_BCR_OFFSET 0x0c0 /* Block Control Register */ +#define AVR32_TC_BMR_OFFSET 0x0c4 /* Block Mode Register */ + +/* Timer Channel Base Addresses *****************************************************/ + +#define AVR32_TC_CHAN_BASE(n) (AVR32_TC_BASE+AVR32_TC_CHAN_OFFSET(n)) +#define AVR32_TC_CHAN0_BASE (AVR32_TC_BASE+AVR32_TC_CHAN0_OFFSET) +#define AVR32_TC_CHAN1_BASE (AVR32_TC_BASE+AVR32_TC_CHAN1_OFFSET) +#define AVR32_TC_CHAN2_BASE (AVR32_TC_BASE+AVR32_TC_CHAN2_OFFSET) + +/* Register Addresses ***************************************************************/ + +#define AVR32_TC_CCR(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMRn(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR(n) (AVR32_TC_CHAN0_BASE(n)+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR0 (AVR32_TC_CHAN0_BASE+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR0 (AVR32_TC_CHAN0_BASE+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV0 (AVR32_TC_CHAN0_BASE+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA0 (AVR32_TC_CHAN0_BASE+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB0 (AVR32_TC_CHAN0_BASE+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC0 (AVR32_TC_CHAN0_BASE+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR0 (AVR32_TC_CHAN0_BASE+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER0 (AVR32_TC_CHAN0_BASE+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR0 (AVR32_TC_CHAN0_BASE+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR0 (AVR32_TC_CHAN0_BASE+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR1 (AVR32_TC_CHAN1_BASE+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR1 (AVR32_TC_CHAN1_BASE+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV1 (AVR32_TC_CHAN1_BASE+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA1 (AVR32_TC_CHAN1_BASE+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB1 (AVR32_TC_CHAN1_BASE+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC1 (AVR32_TC_CHAN1_BASE+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR1 (AVR32_TC_CHAN1_BASE+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER1 (AVR32_TC_CHAN1_BASE+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR1 (AVR32_TC_CHAN1_BASE+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR1 (AVR32_TC_CHAN1_BASE+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_CCR2 (AVR32_TC_CHAN2_BASE+AVR32_TC_CCR_OFFSET) +#define AVR32_TC_CMR2 (AVR32_TC_CHAN2_BASE+AVR32_TC_CMR_OFFSET) +#define AVR32_TC_CV2 (AVR32_TC_CHAN2_BASE+AVR32_TC_CV_OFFSET) +#define AVR32_TC_RA2 (AVR32_TC_CHAN2_BASE+AVR32_TC_RA_OFFSET) +#define AVR32_TC_RB2 (AVR32_TC_CHAN2_BASE+AVR32_TC_RB_OFFSET) +#define AVR32_TC_RC2 (AVR32_TC_CHAN2_BASE+AVR32_TC_RC_OFFSET) +#define AVR32_TC_SR2 (AVR32_TC_CHAN2_BASE+AVR32_TC_SR_OFFSET) +#define AVR32_TC_IER2 (AVR32_TC_CHAN2_BASE+AVR32_TC_IER_OFFSET) +#define AVR32_TC_IDR2 (AVR32_TC_CHAN2_BASE+AVR32_TC_IDR_OFFSET) +#define AVR32_TC_IMR2 (AVR32_TC_CHAN2_BASE+AVR32_TC_IMR_OFFSET) + +#define AVR32_TC_BCR (AVR32_TC_BASE+AVR32_TC_BCR_OFFSET) +#define AVR32_TC_BMR (AVR32_TC_BASE+AVR32_TC_BMR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Channel Control Register */ + +#define TC_CCR_CLKEN (1 << 0) /* Bit 0: Counter Clock Enable Command */ +#define TC_CCR_CLKDIS (1 << 1) /* Bit 3: Counter Clock Disable Command */ +#define TC_CCR_SWTRG (1 << 2) /* Bit 2: Software Trigger Command */ + +/* Channel Mode Register -- All Modes */ + +#define TC_CMR_TCCLKS_SHIFT (0) /* Bits 0-2: Clock Selection */ +#define TC_CMR_TCCLKS_MASK (7 << TC_CMR_TCCLKS_SHIFT) +# define TC_CMR_TCCLKS_TMRCLK1 (0 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK1 */ +# define TC_CMR_TCCLKS_TMRCLK2 (1 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK2 */ +# define TC_CMR_TCCLKS_TMRCLK3 (2 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK3 */ +# define TC_CMR_TCCLKS_TMRCLK4 (3 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK4 */ +# define TC_CMR_TCCLKS_TMRCLK5 (4 << TC_CMR_TCCLKS_SHIFT) /* TIMER_CLOCK5 */ +# define TC_CMR_TCCLKS_XC0 (5 << TC_CMR_TCCLKS_SHIFT) /* XC0 */ +# define TC_CMR_TCCLKS_XC1 (6 << TC_CMR_TCCLKS_SHIFT) /* XC1 */ +# define TC_CMR_TCCLKS_XC2 (7 << TC_CMR_TCCLKS_SHIFT) /* XC2 */ +#define TC_CMR_CLKI (1 << 3) /* Bit 3: Clock Invert */ +#define TC_CMR_BURST_SHIFT (4) /* Bits 4-5: Burst Signal Selection */ +#define TC_CMR_BURST_MASK (3 << TC_CMR_BURST_SHIFT) +# define TC_CMR_BURST_NONE (0 << TC_CMR_BURST_SHIFT) /* Clock not gated by External signal */ +# define TC_CMR_BURST_XC0 (1 << TC_CMR_BURST_SHIFT) /* XC0 ANDed with selected clock */ +# define TC_CMR_BURST_XC1 (2 << TC_CMR_BURST_SHIFT) /* XC1 ANDed with selected clock */ +# define TC_CMR_BURST_XC2 (3 << TC_CMR_BURST_SHIFT) /* XC2 ANDed with selected clock */ + +#define TC_CMR_WAVE (1 << 15) /* Bit 15: Enable waveform mode */ + +/* Channel Mode Register -- Capture Mode */ + +#define TC_CMR_LDBSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RB Loading */ +#define TC_CMR_LDBDIS (1 << 7) /* Bit 7: Counter Clock Disable with RB Loading */ +#define TC_CMR_ETRGEDG_SHIFT (8) /* Bits 8-9: External Trigger Edge Selection */ +#define TC_CMR_ETRGEDG_MASK (3 << TC_CMR_ETRGEDG_SHIFT) +# define TC_CMR_ETRGEDG_NONE (0 << TC_CMR_ETRGEDG_SHIFT) /* None */ +# define TC_CMR_ETRGEDG_RISING (1 << TC_CMR_ETRGEDG_SHIFT) /* Rising edge */ +# define TC_CMR_ETRGEDG_FALLING (2 << TC_CMR_ETRGEDG_SHIFT) /* Falling edge */ +# define TC_CMR_ETRGEDG_BOTH (3 << TC_CMR_ETRGEDG_SHIFT) /* Each edge */ +#define TC_CMR_ABETRG (1 << 10) /* Bit 10: TIOA or TIOB External Trigger Selection */ +#define TC_CMR_CPCTRG (1 << 14) /* Bit 14: RC Compare Trigger Enable */ +#define TC_CMR_LDRA_SHIFT (16) /* Bits 16-17: A Loading Selection */ +#define TC_CMR_LDRA_MASK (3 << TC_CMR_LDRA_SHIFT) +# define TC_CMR_LDRA_NONE (0 << TC_CMR_LDRA_SHIFT) /* None */ +# define TC_CMR_LDRA_RISING (1 << TC_CMR_LDRA_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRA_FALLING (2 << TC_CMR_LDRA_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRA_BOTH (3 << TC_CMR_LDRA_SHIFT) /* Each edge of TIOA */ +#define TC_CMR_LDRB_SHIFT (18) /* Bits 18-19: RB Loading Selection */ +#define TC_CMR_LDRB_MASK (3 << TC_CMR_LDRB_SHIFT) +# define TC_CMR_LDRB_NONE (0 << TC_CMR_LDRB_SHIFT) /* None */ +# define TC_CMR_LDRB_RISING (1 << TC_CMR_LDRB_SHIFT) /* Rising edge of TIOA */ +# define TC_CMR_LDRB_FALLING (2 << TC_CMR_LDRB_SHIFT) /* Falling edge of TIOA */ +# define TC_CMR_LDRB_BOTH (3 << TC_CMR_LDRB_SHIFT) /* Each edge of TIOA */ + +/* Channel Mode Register -- Waveform Mode */ + +#define TC_CMR_CPCSTOP (1 << 6) /* Bit 6: Counter Clock Stopped with RC Compare */ +#define TC_CMR_CPCDIS (1 << 7) /* Bit 7: Counter Clock Disable with RC Compare */ +#define TC_CMR_EEVTEDG_SHIFT (8) /* Bits 8-9: External Event Edge Selection */ +#define TC_CMR_EEVTEDG_MASK (3 << TC_CMR_EEVTEDG_SHIFT) +# define TC_CMR_EEVTEDG_NONE (0 << TC_CMR_EEVTEDG_SHIFT) /* None */ +# define TC_CMR_EEVTEDG_RISING (1 << TC_CMR_EEVTEDG_SHIFT) /* Rising edge */ +# define TC_CMR_EEVTEDG_FALLING (2 << TC_CMR_EEVTEDG_SHIFT) /* Falling edge */ +# define TC_CMR_EEVTEDG_BOTH (3 << TC_CMR_EEVTEDG_SHIFT) /* Each edge */ +#define TC_CMR_EEVT_SHIFT (10) /* Bits 10-11: External Event Selection */ +#define TC_CMR_EEVT_MASK (3 << TC_CMR_EEVT_SHIFT) +# define TC_CMR_EEVT_TIOB (0 << TC_CMR_EEVT_SHIFT) /* TIOB Input */ +# define TC_CMR_EEVT_XC0 (1 << TC_CMR_EEVT_SHIFT) /* XC0 Output */ +# define TC_CMR_EEVT_XC1 (2 << TC_CMR_EEVT_SHIFT) /* XC1 Output */ +# define TC_CMR_EEVT_XC2 (3 << TC_CMR_EEVT_SHIFT) /* XC2 Output */ +#define TC_CMR_ENETRG (1 << 12) /* Bit 12: External Event Trigger Enable */ +#define TC_CMR_WAVSEL_SHIFT (13) /* Bits 13-14: Waveform Selection */ +#define TC_CMR_WAVSEL_MASK (3 << TC_CMR_WAVSEL_SHIFT) +# define TC_CMR_WAVSEL_UPNOT (0 << TC_CMR_WAVSEL_SHIFT) /* UP mode no trigger on RC compare */ +# define TC_CMR_WAVSEL_UPDWNNOT (1 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode no trigger on RC compare */ +# define TC_CMR_WAVSEL_UPT (2 << TC_CMR_WAVSEL_SHIFT) /* UP mode with trigger on RC compare */ +# define TC_CMR_WAVSEL_UPDWNT (3 << TC_CMR_WAVSEL_SHIFT) /* UPDOWN mode with trigger on RC compare */ +#define TC_CMR_ACPA_SHIFT (16) /* Bits 16-17: RA Compare Effect on TIOA */ +#define TC_CMR_ACPA_MASK (3 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_NONE (0 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_SET (1 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_CLEAR (2 << TC_CMR_ACPA_SHIFT) +# define TC_CMR_ACPA_TOGGLE (3 << TC_CMR_ACPA_SHIFT) +#define TC_CMR_ACPC_SHIFT (18) /* Bits 18-19: RC Compare Effect on TIOA */ +#define TC_CMR_ACPC_MASK (3 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_NONE (0 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_SET (1 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_CLEAR (2 << TC_CMR_ACPC_SHIFT) +# define TC_CMR_ACPC_TOGGLE (3 << TC_CMR_ACPC_SHIFT) +#define TC_CMR_AEEVT_SHIFT (20) /* Bits 20-21: External Event Effect on TIOA */ +#define TC_CMR_AEEVT_MASK (3 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_NONE (0 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_SET (1 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_CLEAR (2 << TC_CMR_AEEVT_SHIFT) +# define TC_CMR_AEEVT_TOGGLE (3 << TC_CMR_AEEVT_SHIFT) +#define TC_CMR_ASWTRG_SHIFT (22) /* Bits 22-23: Software Trigger Effect on TIOA */ +#define TC_CMR_ASWTRG_MASK (3 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_NONE (0 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_SET (1 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_CLEAR (2 << TC_CMR_ASWTRG_SHIFT) +# define TC_CMR_ASWTRG_TOGGLE (3 << TC_CMR_ASWTRG_SHIFT) +#define TC_CMR_BCPB_SHIFT (24) /* Bits 24-25: RB Compare Effect on TIOB */ +#define TC_CMR_BCPB_MASK (3 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_NONE (0 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_SET (1 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_CLEAR (2 << TC_CMR_BCPB_SHIFT) +# define TC_CMR_BCPB_TOGGLE (3 << TC_CMR_BCPB_SHIFT) +#define TC_CMR_BCPC_SHIFT (26) /* Bits 26-27: RC Compare Effect on TIOB */ +#define TC_CMR_BCPC_MASK (3 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_NONE (0 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_SET (1 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_CLEAR (2 << TC_CMR_BCPC_SHIFT) +# define TC_CMR_BCPC_TOGGLE (3 << TC_CMR_BCPC_SHIFT) +#define TC_CMR_BEEVT_SHIFT (28) /* Bits 28-29: External Event Effect on TIOB */ +#define TC_CMR_BEEVT_MASK (3 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_NONE (0 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_SET (1 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_CLEAR (2 << TC_CMR_BEEVT_SHIFT) +# define TC_CMR_BEEVT_TOGGLE (3 << TC_CMR_BEEVT_SHIFT) +#define TC_CMR_BSWTRG_SHIFT (30) /* Bits 30-31: Software Trigger Effect on TIOB */ +#define TC_CMR_BSWTRG_MASK (3 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_NONE (0 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_SET (1 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_CLEAR (2 << TC_CMR_BSWTRG_SHIFT) +# define TC_CMR_BSWTRG_TOGGLE (3 << TC_CMR_BSWTRG_SHIFT) + +/* Channel Counter Value */ + +#define TC_CV_MASK (0xffff) + +/* Channel Register A */ + +#define TC_RA_MASK (0xffff) + +/* Channel Register B */ + +#define TC_RB_MASK (0xffff) + +/* Channel Register C */ + +#define TC_RC_MASK (0xffff) + +/* Channel Status Register (common) */ +/* Interrupt Enable Register */ +/* Channel Interrupt Disable Register */ +/* Channel Interrupt Mask Register */ + +#define TC_INT_COVFS (1 << 0) /* Bit 0: Counter Overflow Status/Int */ +#define TC_INT_LOVRS (1 << 1) /* Bit 1: Load Overrun Status/Int */ +#define TC_INT_CPAS (1 << 2) /* Bit 2: RA Compare Status/Int */ +#define TC_INT_CPBS (1 << 3) /* Bit 3: RB Compare Status/Int */ +#define TC_INT_CPCS (1 << 4) /* Bit 4: RC Compare Status/Int */ +#define TC_INT_LDRAS (1 << 5) /* Bit 5: RA Loading Status/Int */ +#define TC_INT_LDRBS (1 << 6) /* Bit 6: RB Loading Status/Int */ +#define TC_INT_ETRGS (1 << 7) /* Bit 7: External Trigger Status/Int */ + +/* Channel Status Register (only) */ + +#define TC_SR_CLKSTA (1 << 16) /* Bit 16: Clock Enabling Status */ +#define TC_SR_MTIOA (1 << 17) /* Bit 17: TIOA Mirror */ +#define TC_SR_MTIOB (1 << 18) /* Bit 18: TIOB Mirror */ + +/* Block Control Register */ + +#define TC_BCR_SYNC (1 << 0) /* Bit 0: Synchro Command */ + +/* Block Mode Register */ + +#define TC_BMR_TC0XC0S_SHIFT (0) /* Bits 0-1: External Clock Signal 0 Selection */ +#define TC_BMR_TC0XC0S_MASK (3 << TC_BMR_TC0XC0S_SHIFT) +# define TC_BMR_TC2XC0S_TCLK0 (0 << TC_BMR_TC2XC0S_SHIFT) /* TCLK0 */ +# define TC_BMR_TC2XC0S_NONE (1 << TC_BMR_TC2XC0S_SHIFT) /* None */ +# define TC_BMR_TC2XC0S_TIOA1 (2 << TC_BMR_TC2XC0S_SHIFT) /* TIOA1 */ +# define TC_BMR_TC2XC0S_TIOA2 (3 << TC_BMR_TC2XC0S_SHIFT) /* TIOA2 */ +#define TC_BMR_TC1XC1S_SHIFT (2) /* Bits 2-3: External Clock Signal 1 Selection */ +#define TC_BMR_TC1XC1S_MASK (3 << TC_BMR_TC1XC1S_SHIFT) +# define TC_BMR_TC2XC1S_TCLK1 (0 << TC_BMR_TC2XC1S_SHIFT) /* TCLK1 */ +# define TC_BMR_TC2XC1S_NONE (1 << TC_BMR_TC2XC1S_SHIFT) /* None */ +# define TC_BMR_TC2XC1S_TIOA0 (2 << TC_BMR_TC2XC1S_SHIFT) /* TIOA0 */ +# define TC_BMR_TC2XC1S_TIOA2 (3 << TC_BMR_TC2XC1S_SHIFT) /* TIOA2 */ +#define TC_BMR_TC2XC2S_SHIFT (3) /* Bits 4-5: External Clock Signal 2 Selection */ +#define TC_BMR_TC2XC2S_MASK (3 << TC_BMR_TC2XC2S_SHIFT) +# define TC_BMR_TC2XC2S_TCLK2 (0 << TC_BMR_TC2XC2S_SHIFT) /* TCLK2 */ +# define TC_BMR_TC2XC2S_NONE (1 << TC_BMR_TC2XC2S_SHIFT) /* None */ +# define TC_BMR_TC2XC2S_TIOA0 (2 << TC_BMR_TC2XC2S_SHIFT) /* TIOA0 */ +# define TC_BMR_TC2XC2S_TIOA1 (3 << TC_BMR_TC2XC2S_SHIFT) /* TIOA1 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_TC_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_timerisr.c b/arch/avr/src/at32uc3/at32uc3_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..e0d6cc6c351da44b308a97e5f4cec115e8f06b67 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_timerisr.c @@ -0,0 +1,238 @@ +/**************************************************************************** + * arch/avr/src/at32uc3/at32uc3_timerisr.c + * + * Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "up_arch.h" + +#include "chip.h" +#include "at32uc3.h" +#include "at32uc3_pm.h" +#include "at32uc3_rtc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is normally provided by the + * definition CLK_TCK (see include/time.h). CLK_TCK defines the desired + * number of system clock ticks per second. That value is a user configurable + * setting that defaults to 100 (100 ticks per second = 10 MS interval). + * + * However, the AVR RTC does not support that default value well and so, we + * will insist that default is over-ridden by CONFIG_USEC_PER_TICK in the + * configuration file. Further, we will insist that CONFIG_USEC_PER_TICK + * have the value 10000 (see reasoning below). + */ + +#if defined(CONFIG_USEC_PER_TICK) && CONFIG_USEC_PER_TICK != 10000 +# error "Only a 100KHz system clock is supported" +#endif + +/* The frequency of the RTC is given by: + * + * fRTC = fINPUT / 2**(PSEL + 1) + * + * Using the 32KHz (actually 32786Hz) clock, various RTC counting can + * be obtained: + * + * fRTC = 32768 / 2**16 = 32768/65536 = 0.5Hz -> 2000 ms per tick + * fRTC = 32768 / 2**15 = 32768/32768 = 1.0Hz -> 1000 ms per tick + * fRTC = 32768 / 2**14 = 32768/16384 = 2.0Hz -> 500 ms per tick + * fRTC = 32768 / 2**13 = 32768/8192 = 4.0Hz -> 250 ms per tick + * fRTC = 32768 / 2**12 = 32768/4096 = 8.0Hz -> 125 ms per tick + * fRTC = 32768 / 2**11 = 32768/2048 = 16.0Hz -> 62.5 ms per tick + * fRTC = 32768 / 2**10 = 32768/1024 = 32.0Hz -> 31.25 ms per tick + * fRTC = 32768 / 2**9 = 32768/512 = 64.0Hz -> 15.63 ms per tick + * fRTC = 32768 / 2**8 = 32768/256 = 125Hz -> 7.81 ms per tick + * fRTC = 32768 / 2**7 = 32768/128 = 250Hz -> 3.91 ms per tick + * fRTC = 32768 / 2**6 = 32768/64 = 500Hz -> 1.95 ms per tick + * fRTC = 32768 / 2**5 = 32768/32 = 1KHz -> 0.98 ms per tick + * fRTC = 32768 / 2**4 = 32768/16 = 2KHz -> 488.28 us per tick + * fRTC = 32768 / 2**3 = 32768/8 = 4KHz -> 244.14 us per tick + * fRTC = 32768 / 2**2 = 32768/4 = 8KHz -> 122.07 us per tick + * fRTC = 32768 / 2 = 16KHz -> 61.03 us per tick + * + * We'll use PSEL == 1 (fRTC == 122.07us) and we will set TOP to 81. + * Therefore, the TOP interrupt should occur after 81+1=82 counts + * at a rate of 122.07us x 82 = 10.01 ms + * + * Using the RCOSC at a nominal 115KHz, we can do he following: + * + * fRTC = 115000 / 2**16 = 115000/65536 = 1.754Hz -> 569.9 ms per tick + * fRTC = 115000 / 2**15 = 115000/32768 = 3.509Hz -> 284.9 ms per tick + * fRTC = 115000 / 2**14 = 115000/16384 = 7.019Hz -> 142.47 ms per tick + * fRTC = 115000 / 2**13 = 115000/8192 = 14.04Hz -> 71.23 ms per tick + * fRTC = 115000 / 2**12 = 115000/4096 = 28.08Hz -> 35.62 ms per tick + * fRTC = 115000 / 2**11 = 115000/2048 = 56.15Hz -> 17.81 ms per tick + * fRTC = 115000 / 2**10 = 115000/1024 = 112.3Hz -> 8.904 ms per tick + * fRTC = 115000 / 2**9 = 115000/512 = 224.6Hz -> 4.452 ms per tick + * fRTC = 115000 / 2**8 = 115000/256 = 449.2Hz -> 2.227 ms per tick + * fRTC = 115000 / 2**7 = 115000/128 = 898.4Hz -> 1.113 ms per tick + * fRTC = 115000 / 2**6 = 115000/64 = 1.796KHz -> 556.5 us per tick + * fRTC = 115000 / 2**5 = 115000/32 = 3.594KHz -> 278.3 us per tick + * fRTC = 115000 / 2**4 = 115000/16 = 7.188KHz -> 139.1 us per tick + * fRTC = 115000 / 2**3 = 115000/8 = 14.38KHz -> 69.57 us per tick + * fRTC = 115000 / 2**2 = 115000/4 = 28.75KHz -> 34.78 us per tick + * fRTC = 115000 / 2 = 57.50KHz -> 17l.39 us per tick + * + * We'll use PSEL == 3 (fRTC == 69.57ns) and we will set TOP to 79. + * Therefore, the TOP interrupt should occur after 143+1=144 counts + * at a rate of 69.57us x 144 = 10.02 ms + */ + +#ifdef AVR32_CLOCK_OSC32 +# define AV32_PSEL 1 +# define AV32_TOP (82-1) +#else +# define AV32_PSEL 2 +# define AV32_TOP (144-1) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: rtc_busy + * + * Description: + * Make sure that the RTC is no busy before trying to operate on it. If + * the RTC is busy, it will discard writes to TOP, VAL, and CTRL. + * + ****************************************************************************/ + +static void rtc_waitnotbusy(void) +{ + while ((getreg32(AVR32_RTC_CTRL) & RTC_CTRL_BUSY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Clear the pending timer interrupt */ + + putreg32(RTC_INT_TOPI, AVR32_RTC_ICR); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. NOTE: This function depends on setup of OSC32 by + * up_clkinitialize(). + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Enable clocking: "The clock for the RTC bus interface (CLK_RTC) is generated + * by the Power Manager. This clock is enabled at reset, and can be disabled + * in the Power Manager. It is recommended to disable the RTC before disabling + * the clock, to avoid freezing the RTC in an undefined state." + */ + +#if 0 + regval = getreg32(AVR32_PM_PBAMASK); + regval |= PM_PBAMASK_PMRTCEIC; + putreg32(regval, AVR32_PM_PBAMASK); +#endif + + /* Configure the RTC. Source == 32KHz OSC32 or RC OSC */ + + rtc_waitnotbusy(); +#ifdef AVR32_CLOCK_OSC32 + putreg32((RTC_CTRL_CLK32 | (AV32_PSEL << RTC_CTRL_PSEL_SHIFT) | RTC_CTRL_CLKEN), + AVR32_RTC_CTRL); +#else + putreg32(((AV32_PSEL << RTC_CTRL_PSEL_SHIFT) | RTC_CTRL_CLKEN), + AVR32_RTC_CTRL); +#endif + + /* Set the counter value to zero and the TOP value to AVR32_TOP (see above) */ + + rtc_waitnotbusy(); + putreg32(AV32_TOP, AVR32_RTC_TOP); + rtc_waitnotbusy(); + putreg32(0, AVR32_RTC_VAL); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(AVR32_IRQ_RTC, (xcpt_t)up_timerisr); + + /* Enable RTC interrupts */ + + putreg32(RTC_INT_TOPI, AVR32_RTC_IER); + + /* Enable the RTC */ + + rtc_waitnotbusy(); + regval = getreg32(AVR32_RTC_CTRL); + regval |= RTC_CTRL_EN; + putreg32(regval, AVR32_RTC_CTRL); +} diff --git a/arch/avr/src/at32uc3/at32uc3_twi.h b/arch/avr/src/at32uc3/at32uc3_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..3a82b733a631defa0fbf7768c8bfec7b7eda478f --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_twi.h @@ -0,0 +1,161 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_twi.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_TWI_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_TWI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_TWI_CR_OFFSET 0x00 /* Control Register */ +#define AVR32_TWI_MMR_OFFSET 0x04 /* Master Mode Register */ +#define AVR32_TWI_SMR_OFFSET 0x08 /* Slave Mode Register */ +#define AVR32_TWI_IADR_OFFSET 0x0c /* Internal Address Register */ +#define AVR32_TWI_CWGR_OFFSET 0x10 /* Clock Waveform Generator Register */ +#define AVR32_TWI_SR_OFFSET 0x20 /* Status Register */ +#define AVR32_TWI_IER_OFFSET 0x24 /* Interrupt Enable Register */ +#define AVR32_TWI_IDR_OFFSET 0x28 /* Interrupt Disable Register */ +#define AVR32_TWI_IMR_OFFSET 0x2c /* Interrupt Mask Register */ +#define AVR32_TWI_RHR_OFFSET 0x30 /* Receive Holding Register */ +#define AVR32_TWI_THR_OFFSET 0x34 /* Transmit Holding Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_TWI_CR (AVR32_TWI_BASE+AVR32_TWI_CR_OFFSET) +#define AVR32_TWI_MMR (AVR32_TWI_BASE+AVR32_TWI_MMR_OFFSET) +#define AVR32_TWI_SMR (AVR32_TWI_BASE+AVR32_TWI_SMR_OFFSET) +#define AVR32_TWI_IADR (AVR32_TWI_BASE+AVR32_TWI_IADR_OFFSET) +#define AVR32_TWI_CWGR (AVR32_TWI_BASE+AVR32_TWI_CWGR_OFFSET) +#define AVR32_TWI_SR (AVR32_TWI_BASE+AVR32_TWI_SR_OFFSET) +#define AVR32_TWI_IER (AVR32_TWI_BASE+AVR32_TWI_IER_OFFSET) +#define AVR32_TWI_IDR (AVR32_TWI_BASE+AVR32_TWI_IDR_OFFSET) +#define AVR32_TWI_IMR (AVR32_TWI_BASE+AVR32_TWI_IMR_OFFSET) +#define AVR32_TWI_RHR (AVR32_TWI_BASE+AVR32_TWI_RHR_OFFSET) +#define AVR32_TWI_THR (AVR32_TWI_BASE+AVR32_TWI_THR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register Bit-field Definitions */ + +#define TWI_CR_START (1 << 0) /* Bit 0: Send a START Condition */ +#define TWI_CR_STOP (1 << 1) /* Bit 1: Send a STOP Condition */ +#define TWI_CR_MSEN (1 << 2) /* Bit 2: TWI Master Mode Enabled */ +#define TWI_CR_MSDIS (1 << 3) /* Bit 3: TWI Master Mode Disabled */ +#define TWI_CR_SVEN (1 << 4) /* Bit 4: TWI Slave Mode Enabled */ +#define TWI_CR_SVDIS (1 << 5) /* Bit 5: TWI Slave Mode Disabled */ +#define TWI_CR_SWRST (1 << 7) /* Bit 6: Software Reset */ + +/* Master Mode Register Bit-field Definitions */ + +#define TWI_MMR_IADRSZ_SHIFT (8) /* Bits 8-9: Internal Device Address Size */ +#define TWI_MMR_IADRSZ_MASK (3 << TWI_MMR_IADRSZ_SHIFT) +# define TWI_MMR_IADRSZ_ NONE (0 << TWI_MMR_IADRSZ_SHIFT) /* No internal device address */ +# define TWI_MMR_IADRSZ_1BYTE (1 << TWI_MMR_IADRSZ_SHIFT) /* One-byte internal device address */ +# define TWI_MMR_IADRSZ_2BYTES (2 << TWI_MMR_IADRSZ_SHIFT) /* Two-byte internal device address */ +# define TWI_MMR_IADRSZ_3BYTES (3 << TWI_MMR_IADRSZ_SHIFT) /* Three-byte internal device address */ +#define TWI_MMR_MREAD (1 << 12) /* Bit 12: Master Read Direction */ +#define TWI_MMR_DADR_SHIFT (16) /* Bits 16-22: Device Address */ +#define TWI_MMR_DADR:_MASK (0x7f << TWI_MMR_DADR_SHIFT) + +/* Slave Mode Register Bit-field Definitions */ + +#define TWI_SMR_SADR_SHIFT (16) /* Bits 16-22: Slave Address */ +#define TWI_SMR_SADR_MASK (0x7f << TWI_SMR_SADR_SHIFT) + +/* Internal Address Register Bit-field Definitions */ + +#define TWI_IADR_MASK (0x00ffffff) + +/* Clock Waveform Generator Register Bit-field Definitions */ + +#define TWI_CWGR_CLDIV_SHIFT (0) /* Bits 0-7: Clock Low Divider */ +#define TWI_CWGR_CLDIV_MASK (0xff < + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_USART_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_USART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_USART_CR_OFFSET 0x0000 /* Control Register */ +#define AVR32_USART_MR_OFFSET 0x0004 /* Mode Register */ +#define AVR32_USART_IER_OFFSET 0x0008 /* Interrupt Enable Register */ +#define AVR32_USART_IDR_OFFSET 0x000c /* Interrupt Disable Register */ +#define AVR32_USART_IMR_OFFSET 0x0010 /* Interrupt Mask Register */ +#define AVR32_USART_CSR_OFFSET 0x0014 /* Channel Status Register */ +#define AVR32_USART_RHR_OFFSET 0x0018 /* Receiver Holding Register */ +#define AVR32_USART_THR_OFFSET 0x001c /* Transmitter Holding Register */ +#define AVR32_USART_BRGR_OFFSET 0x0020 /* Baud Rate Generator Register */ +#define AVR32_USART_RTOR_OFFSET 0x0024 /* Receiver Time-out Register */ +#define AVR32_USART_TTGR_OFFSET 0x0028 /* Transmitter Timeguard Register */ +#define AVR32_USART_FIDI_OFFSET 0x0040 /* FI DI Ratio Register */ +#define AVR32_USART_NER_OFFSET 0x0044 /* Number of Errors Register */ +#define AVR32_USART_IFR_OFFSET 0x004c /* IrDA Filter Register */ +#define AVR32_USART_MAN_OFFSET 0x0050 /* Manchester Encoder Decoder Register */ +#define AVR32_USART_VERSION_OFFSET 0x00fc /* Version Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_USART0_CR (AVR32_USART0_BASE+AVR32_USART_CR_OFFSET) +#define AVR32_USART0_MR (AVR32_USART0_BASE+AVR32_USART_MR_OFFSET) +#define AVR32_USART0_IER (AVR32_USART0_BASE+AVR32_USART_IER_OFFSET) +#define AVR32_USART0_IDR (AVR32_USART0_BASE+AVR32_USART_IDR_OFFSET) +#define AVR32_USART0_IMR (AVR32_USART0_BASE+AVR32_USART_IMR_OFFSET) +#define AVR32_USART0_CSR (AVR32_USART0_BASE+AVR32_USART_CSR_OFFSET) +#define AVR32_USART0_RHR (AVR32_USART0_BASE+AVR32_USART_RHR_OFFSET) +#define AVR32_USART0_THR (AVR32_USART0_BASE+AVR32_USART_THR_OFFSET) +#define AVR32_USART0_BRGR (AVR32_USART0_BASE+AVR32_USART_BRGR_OFFSET) +#define AVR32_USART0_RTOR (AVR32_USART0_BASE+AVR32_USART_RTOR_OFFSET) +#define AVR32_USART0_TTGR (AVR32_USART0_BASE+AVR32_USART_TTGR_OFFSET) +#define AVR32_USART0_FIDI (AVR32_USART0_BASE+AVR32_USART_FIDI_OFFSET) +#define AVR32_USART0_NER (AVR32_USART0_BASE+AVR32_USART_NER_OFFSET) +#define AVR32_USART0_IFR (AVR32_USART0_BASE+AVR32_USART_IFR_OFFSET) +#define AVR32_USART0_MAN (AVR32_USART0_BASE+AVR32_USART_MAN_OFFSET) +#define AVR32_USART0_VERSION (AVR32_USART0_BASE+AVR32_USART_VERSION_OFFSET) + +#define AVR32_USART1_CR (AVR32_USART1_BASE+AVR32_USART_CR_OFFSET) +#define AVR32_USART1_MR (AVR32_USART1_BASE+AVR32_USART_MR_OFFSET) +#define AVR32_USART1_IER (AVR32_USART1_BASE+AVR32_USART_IER_OFFSET) +#define AVR32_USART1_IDR (AVR32_USART1_BASE+AVR32_USART_IDR_OFFSET) +#define AVR32_USART1_IMR (AVR32_USART1_BASE+AVR32_USART_IMR_OFFSET) +#define AVR32_USART1_CSR (AVR32_USART1_BASE+AVR32_USART_CSR_OFFSET) +#define AVR32_USART1_RHR (AVR32_USART1_BASE+AVR32_USART_RHR_OFFSET) +#define AVR32_USART1_THR (AVR32_USART1_BASE+AVR32_USART_THR_OFFSET) +#define AVR32_USART1_BRGR (AVR32_USART1_BASE+AVR32_USART_BRGR_OFFSET) +#define AVR32_USART1_RTOR (AVR32_USART1_BASE+AVR32_USART_RTOR_OFFSET) +#define AVR32_USART1_TTGR (AVR32_USART1_BASE+AVR32_USART_TTGR_OFFSET) +#define AVR32_USART1_FIDI (AVR32_USART1_BASE+AVR32_USART_FIDI_OFFSET) +#define AVR32_USART1_NER (AVR32_USART1_BASE+AVR32_USART_NER_OFFSET) +#define AVR32_USART1_IFR (AVR32_USART1_BASE+AVR32_USART_IFR_OFFSET) +#define AVR32_USART1_MAN (AVR32_USART1_BASE+AVR32_USART_MAN_OFFSET) +#define AVR32_USART1_VERSION (AVR32_USART1_BASE+AVR32_USART_VERSION_OFFSET) + +#define AVR32_USART2_CR (AVR32_USART2_BASE+AVR32_USART_CR_OFFSET) +#define AVR32_USART2_MR (AVR32_USART2_BASE+AVR32_USART_MR_OFFSET) +#define AVR32_USART2_IER (AVR32_USART2_BASE+AVR32_USART_IER_OFFSET) +#define AVR32_USART2_IDR (AVR32_USART2_BASE+AVR32_USART_IDR_OFFSET) +#define AVR32_USART2_IMR (AVR32_USART2_BASE+AVR32_USART_IMR_OFFSET) +#define AVR32_USART2_CSR (AVR32_USART2_BASE+AVR32_USART_CSR_OFFSET) +#define AVR32_USART2_RHR (AVR32_USART2_BASE+AVR32_USART_RHR_OFFSET) +#define AVR32_USART2_THR (AVR32_USART2_BASE+AVR32_USART_THR_OFFSET) +#define AVR32_USART2_BRGR (AVR32_USART2_BASE+AVR32_USART_BRGR_OFFSET) +#define AVR32_USART2_RTOR (AVR32_USART2_BASE+AVR32_USART_RTOR_OFFSET) +#define AVR32_USART2_TTGR (AVR32_USART2_BASE+AVR32_USART_TTGR_OFFSET) +#define AVR32_USART2_FIDI (AVR32_USART2_BASE+AVR32_USART_FIDI_OFFSET) +#define AVR32_USART2_NER (AVR32_USART2_BASE+AVR32_USART_NER_OFFSET) +#define AVR32_USART2_IFR (AVR32_USART2_BASE+AVR32_USART_IFR_OFFSET) +#define AVR32_USART2_MAN (AVR32_USART2_BASE+AVR32_USART_MAN_OFFSET) +#define AVR32_USART2_VERSION (AVR32_USART2_BASE+AVR32_USART_VERSION_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* CR Register Bit-field Definitions */ + +#define USART_CR_RSTRX (1 << 2) /* Bit 2: Reset Receiver */ +#define USART_CR_RSTTX (1 << 3) /* Bit 3: Reset Transmitter */ +#define USART_CR_RXEN (1 << 4) /* Bit 4: Receiver Enable */ +#define USART_CR_RXDIS (1 << 5) /* Bit 5: Receiver Disable */ +#define USART_CR_TXEN (1 << 6) /* Bit 6: Transmitter Enable */ +#define USART_CR_TXDIS (1 << 7) /* Bit 7: Transmitter Disable */ +#define USART_CR_RSTSTA (1 << 8) /* Bit 8: Reset Status Bits */ +#define USART_CR_STTBRK (1 << 9) /* Bit 9: Start Break */ +#define USART_CR_STPBRK (1 << 10) /* Bit 10: Stop Break */ +#define USART_CR_STTTO (1 << 11) /* Bit 11: Start Time-out */ +#define USART_CR_SENDA (1 << 12) /* Bit 12: Send Address */ +#define USART_CR_RSTIT (1 << 13) /* Bit 13: Reset Iterations */ +#define USART_CR_RSTNACK (1 << 14) /* Bit 14: Reset Non Acknowledge */ +#define USART_CR_RETTO (1 << 15) /* Bit 15: Rearm Time-out */ +#define USART_CR_DTREN (1 << 16) /* Bit 16: Data Terminal Ready Enable */ +#define USART_CR_DTRDIS (1 << 17) /* Bit 17: Data Terminal Ready Disable */ +#define USART_CR_RTSEN (1 << 18) /* Bit 18: Request to Send Enable */ +#define USART_CR_FCS (1 << 18) /* Bit 18: Force SPI Chip Select */ +#define USART_CR_RTSDIS (1 << 19) /* Bit 19: Request to Send Disable */ +#define USART_CR_RCS (1 << 19) /* Bit 19: Release SPI Chip Select */ + +/* MR Register Bit-field Definitions */ + +#define USART_MR_MODE_SHIFT (0) +#define USART_MR_MODE_MASK (15 << USART_MR_MODE_SHIFT) +# define USART_MR_MODE_NORMAL (0 << USART_MR_MODE_SHIFT) /* Normal */ +# define USART_MR_MODE_RS485 (1 << USART_MR_MODE_SHIFT) /* RS485 */ +# define USART_MR_MODE_HW (2 << USART_MR_MODE_SHIFT) /* Hardware Handshaking */ +# define USART_MR_MODE_MODEM (3 << USART_MR_MODE_SHIFT) /* Modem */ +# define USART_MR_MODE_T0 (4 << USART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 0 */ +# define USART_MR_MODE_T1 (6 << USART_MR_MODE_SHIFT) /* IS07816 Protocol: T = 1 */ +# define USART_MR_MODE_IRDA (8 << USART_MR_MODE_SHIFT) /* IrDA */ +# define USART_MR_MODE_MASTER (14 << USART_MR_MODE_SHIFT) /* SPI Master */ +# define USART_MR_MODE_SLAVE (15 << USART_MR_MODE_SHIFT) /* SPI Slave */ +#define USART_MR_USCLKS_SHIFT (4) /* Bits 4-5: Clock Selection */ +#define USART_MR_USCLKS_MASK (3 << USART_MR_USCLKS_SHIFT) +# define USART_MR_USCLKS_CLKUSART (0 << USART_MR_USCLKS_SHIFT) /* CLK_USART */ +# define USART_MR_USCLKS_DIV (1 << USART_MR_USCLKS_SHIFT) /* CLK_USART/DIV */ +# define USART_MR_USCLKS_CLK (3 << USART_MR_USCLKS_SHIFT) /* CLK */ +#define USART_MR_CHRL_SHIFT (6) /* Bit 6-7: Character Length */ +#define USART_MR_CHRL_MASK (3 << USART_MR_CHRL_SHIFT) +# define USART_MR_CHRL_BITS(n) (((n) - 5) << USART_MR_CHRL_SHIFT) +# define USART_MR_CHRL_5BITS (0 << USART_MR_CHRL_SHIFT) /* 5 bits */ +# define USART_MR_CHRL_6BITS (1 << USART_MR_CHRL_SHIFT) /* 6 bits */ +# define USART_MR_CHRL_7BITS (2 << USART_MR_CHRL_SHIFT) /* 7 bits */ +# define USART_MR_CHRL_8BITS (3 << USART_MR_CHRL_SHIFT) /* 8 bits */ +#define USART_MR_SYNC (1 << 8) /* Bit 8: Synchronous Mode Select */ +#define USART_MR_CPHA (1 << 8) /* Bit 8: SPI Clock Phase */ +#define USART_MR_PAR_SHIFT (9) /* Bits 9-11: Parity Type */ +#define USART_MR_PAR_MASK (7 << USART_MR_PAR_SHIFT) +# define USART_MR_PAR_EVEN (0 << USART_MR_PAR_SHIFT) /* Even parity */ +# define USART_MR_PAR_ODD (1 << USART_MR_PAR_SHIFT) /* Odd parity */ +# define USART_MR_PAR_SPACE (2 << USART_MR_PAR_SHIFT) /* Parity forced to 0 (Space) */ +# define USART_MR_PAR_MARK (3 << USART_MR_PAR_SHIFT) /* Parity forced to 1 (Mark) */ +# define USART_MR_PAR_NONE (4 << USART_MR_PAR_SHIFT) /* No parity */ +# define USART_MR_PAR_MULTIDROP (6 << USART_MR_PAR_SHIFT) /* Multidrop mode */ +#define USART_MR_NBSTOP_SHIFT (12) /* Bits 12-13: Number of Stop Bits */ +#define USART_MR_NBSTOP_MASK (3 << USART_MR_NBSTOP_SHIFT) +# define USART_MR_NBSTOP_1 (0 << USART_MR_NBSTOP_SHIFT) /* 1 stop bit */ +# define USART_MR_NBSTOP_1p5 (1 << USART_MR_NBSTOP_SHIFT) /* 1.5 stop bits */ +# define USART_MR_NBSTOP_2 (2 << USART_MR_NBSTOP_SHIFT) /* 2 stop bits */ +#define USART_MR_CHMODE_SHIFT (14) /* Bits 14-15: Channel Mode */ +#define USART_MR_CHMODE_MASK (3 << USART_MR_CHMODE_SHIFT) +# define USART_MR_CHMODE_NORMAL (0 << USART_MR_CHMODE_SHIFT) /* Normal Mode */ +# define USART_MR_CHMODE_AUTO (1 << USART_MR_CHMODE_SHIFT) /* Automatic Echo */ +# define USART_MR_CHMODE_LLPBK (2 << USART_MR_CHMODE_SHIFT) /* Local Loopback */ +# define USART_MR_CHMODE_RLPBK (3 << USART_MR_CHMODE_SHIFT) /* Remote Loopback */ +#define USART_MR_MSBF (1 << 16) /* Bit 16: Bit Order */ +#define USART_MR_CPOL (1 << 16) /* Bit 16: SPI Clock Polarity */ +#define USART_MR_MODE9 (1 << 17) /* Bit 17: 9-bit Character Length */ +#define USART_MR_CLKO (1 << 18) /* Bit 18: Clock Output Select */ +#define USART_MR_OVER (1 << 19) /* Bit 19: Oversampling Mode */ +#define USART_MR_INACK (1 << 20) /* Bit 20: Inhibit Non Acknowledge */ +#define USART_MR_DSNACK (1 << 21) /* Bit 21: Disable Successive NACK */ +#define USART_MR_VAR_SYNC (1 << 22) /* Bit 22: Variable Synchronization */ +#define USART_MR_MAXITER_SHIFT (24) /* Bits 24-26: Maximum iterations */ +#define USART_MR_MAXITER_MASK (7 << USART_MR_MAXITER_SHIFT) +#define USART_MR_FILTER (1 << 28) /* Bit 28: Infrared Receive Line Filter */ +#define USART_MR_MAN (1 << 29) /* Bit 29: Manchester Encoder/Decoder Enable */ +#define USART_MR_MODSYNC (1 << 30) /* Bit 30: Manchester Synchronization Mode */ +#define USART_MR_ONEBIT (1 << 31) /* Bit 31: Start Frame Delimiter Selector */ + +/* IER, IDR, and IMR (and CSR) Register Bit-field Definitions */ + +#define USART_INT_RXRDY (1 << 0) /* Bit 0: */ +#define USART_INT_TXRDY (1 << 1) /* Bit 1: */ +#define USART_INT_RXBRK (1 << 2) /* Bit 2: */ +#define USART_INT_OVRE (1 << 5) /* Bit 5: */ +#define USART_INT_FRAME (1 << 6) /* Bit 6: */ +#define USART_INT_PARE (1 << 7) /* Bit 7: */ +#define USART_INT_TIMEOUT (1 << 8) /* Bit 8: */ +#define USART_INT_TXEMPTY (1 << 9) /* Bit 9: */ +#define USART_INT_ITER (1 << 10) /* Bit 10: */ +#define USART_INT_UNRE (1 << 10) /* Bit 10: */ +#define USART_INT_RXBUFF (1 << 12) /* Bit 12: */ +#define USART_INT_NACK (1 << 13) /* Bit 13: */ +#define USART_INT_RIIC (1 << 16) /* Bit 16: */ +#define USART_INT_DSRIC (1 << 17) /* Bit 17: */ +#define USART_INT_DCDIC (1 << 18) /* Bit 18: */ +#define USART_INT_CTSIC (1 << 19) /* Bit 19: */ +#define USART_INT_MANE (1 << 20) /* Bit 20: */ +#define USART_INT_MANEA (1 << 24) /* Bit 24: */ +#define USART_INT_ALL 0x011f37e7 + +/* CSR Register Bit-field Definitions */ + +#define USART_CSR_RXRDY (1 << 0) /* Bit 0: */ +#define USART_CSR_TXRDY (1 << 1) /* Bit 1: */ +#define USART_CSR_RXBRK (1 << 2) /* Bit 2: */ +#define USART_CSR_OVRE (1 << 5) /* Bit 5: */ +#define USART_CSR_FRAME (1 << 6) /* Bit 6: */ +#define USART_CSR_PARE (1 << 7) /* Bit 7: */ +#define USART_CSR_TIMEOUT (1 << 8) /* Bit 8: */ +#define USART_CSR_TXEMPTY (1 << 9) /* Bit 9: */ +#define USART_CSR_ITER (1 << 10) /* Bit 10: */ +#define USART_CSR_UNRE (1 << 10) /* Bit 10: */ +#define USART_CSR_RXBUFF (1 << 12) /* Bit 12: */ +#define USART_CSR_NACK (1 << 13) /* Bit 13: */ +#define USART_CSR_RIIC (1 << 16) /* Bit 16: */ +#define USART_CSR_DSRIC (1 << 17) /* Bit 17: */ +#define USART_CSR_DCDIC (1 << 18) /* Bit 18: */ +#define USART_CSR_CTSIC (1 << 19) /* Bit 19: */ +#define USART_CSR_RI (1 << 20) /* Bit 20: */ +#define USART_CSR_DSR (1 << 21) /* Bit 21: Image of DSR Input */ +#define USART_CSR_DCD (1 << 22) /* Bit 22: Image of DCD Input*/ +#define USART_CSR_CTS (1 << 23) /* Bit 23: Image of CTS Input */ +#define USART_CSR_MANERR (1 << 24) /* Bit 24: Manchester Error */ + +/* RHR Register Bit-field Definitions */ + +#define USART_RHR_RXCHR_SHIFT (0) /* Bits 0-8: Received Character */ +#define USART_RHR_RXCHR_MASK (0x1ff << USART_RHR_RXCHR_SHIFT) +#define USART_RHR_RXSYNH (1 << 15) /* Bit 15: Received Sync */ + +/* THR Register Bit-field Definitions */ + +#define USART_THR_TXCHR_SHIFT (0) /* Bits 0-8: Character to be Transmitted */ +#define USART_THR_TXCHR_MASK (0x1ff << USART_RHR_RXCHR_SHIFT) +#define USART_THR_TXSYNH (1 << 15) /* Bit 15: Sync Field to be transmitted */ + +/* BRGR Register Bit-field Definitions */ + +#define USART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divider */ +#define USART_BRGR_CD_MASK (0xffff << USART_BRGR_CD_SHIFT) +#define USART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part */ +#define USART_BRGR_FP_MASK (7 << USART_BRGR_FP_SHIFT) + +/* RTOR Register Bit-field Definitions */ + +#define USART_RTOR_SHIFT (0) /* Bits0-15: Time-out Value */ +#define USART_RTOR_MASK (0xffff << USART_RTOR_SHIFT) + +/* TTGR Register Bit-field Definitions */ + +#define USART_TTGR_SHIFT (0) /* Bits 0-7: Timeguard Value */ +#define USART_TTGR_MASK (0xff << USART_TTGR_SHIFT) + +/* FIDI Register Bit-field Definitions */ + +#define USART_FIDI_SHIFT (0) /* Bits 0-10: FI Over DI Ratio Value */ +#define USART_FIDI_MASK (0x7ff<< USART_FIDI_SHIFT) + +/* NER Register Bit-field Definitions */ + +#define USART_NER_SHIFT (0) /* Bits 0-7: Number of Errors */ +#define USART_NER_MASK (0xff << USART_NER_SHIFT) + +/* IFR Register Bit-field Definitions */ + +#define USART_IFR_SHIFT (0) /* Bits 0-7: IrDA Filter */ +#define USART_IFR_MASK (0xff << USART_IFR_SHIFT) + +/* MAN Register Bit-field Definitions */ + +#define USART_MAN_TXPL_SHIFT (0) /* Bits 0-3: Transmitter Preamble Length */ +#define USART_MAN_TXPL_MASK (15 << USART_MAN_TXPL_SHIFT) +#define USART_MAN_TXPP_SHIFT (8) /* Bits 8-9: Transmitter Preamble Pattern */ +#define USART_MAN_TXPP_MASK (3 << USART_MAN_TXPP_SHIFT) +# define USART_MAN_TXPP_ALLONE (0 << USART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define USART_MAN_TXPP_ALLZERO (1 << USART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define USART_MAN_TXPP_ZER0ONE (2 << USART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define USART_MAN_TXPP_ONEZERO (3 << USART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define USART_MAN_TXMPOL (1 << 12) /* Bit 12: Transmitter Manchester Polarity */ +#define USART_MAN_RXPL_SHIFT (16) /* Bits 16-19: Receiver Preamble Length */ +#define USART_MAN_RXPL_MASK (15 << USART_MAN_RXPL_SHIFT) +#define USART_MAN_RXPP_SHIFT (24) /* Bits 24-25: Receiver Preamble Pattern detected */ +#define USART_MAN_RXPP_MASK (3 << USART_MAN_RXPP_SHIFT) +# define USART_MAN_RXPP_ALLONE (0 << USART_MAN_TXPP_SHIFT) /* ALL_ONE */ +# define USART_MAN_RXPP_ALLZERO (1 << USART_MAN_TXPP_SHIFT) /* ALL_ZERO */ +# define USART_MAN_RXPP_ZER0ONE (2 << USART_MAN_TXPP_SHIFT) /* ZERO_ONE */ +# define USART_MAN_RXPP_ONEZERO (3 << USART_MAN_TXPP_SHIFT) /* ONE_ZERO */ +#define USART_MAN_RXMPOL (1 << 28) /* Bit 28: Receiver Manchester Polarity */ +#define USART_MAN_DRIFT (1 << 30) /* Bit 30: Drift compensation */ + +/* VERSION Register Bit-field Definitions */ + +#define USART_VERSION_SHIFT (0) /* Bits 0-12: Version of the module */ +#define USART_VERSION_MASK (0xfff << USART_VERSION_SHIFT) +#define USART_VARIANT_SHIFT (16) /* Bits 16-19: (Reserved) */ +#define USART_VARIANT_MASK (15 << USART_VARIANT_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_USART_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_usbb.h b/arch/avr/src/at32uc3/at32uc3_usbb.h new file mode 100644 index 0000000000000000000000000000000000000000..247f7d5f0f371d11bad808a33980014dc71e10f3 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_usbb.h @@ -0,0 +1,1098 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_usbb.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_USBB_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_USBB_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +/* USB Device Registers */ + +#define AVR32_USBB_UDCON_OFFSET 0x0000 /* Device General Control Register */ +#define AVR32_USBB_UDINT_OFFSET 0x0004 /* Device Global Interrupt Register */ +#define AVR32_USBB_UDINTCLR_OFFSET 0x0008 /* Device Global Interrupt Clear Register */ +#define AVR32_USBB_UDINTSET_OFFSET 0x000c /* Device Global Interrupt Set Register */ +#define AVR32_USBB_UDINTE_OFFSET 0x0010 /* Device Global Interrupt Enable Register */ +#define AVR32_USBB_UDINTECLR_OFFSET 0x0014 /* Device Global Interrupt Enable Clear Register */ +#define AVR32_USBB_UDINTESET_OFFSET 0x0018 /* Device Global Interrupt Enable Set Register */ +#define AVR32_USBB_UERST_OFFSET 0x001c /* Endpoint Enable/Reset Register */ +#define AVR32_USBB_UDFNUM_OFFSET 0x0020 /* Device Frame Number Register */ + +#define AVR32_USBB_UECFG_OFFSET(n) (0x0100+((n)<<2)) +#define AVR32_USBB_UECFG0_OFFSET 0x0100 /* Endpoint 0 Configuration Register */ +#define AVR32_USBB_UECFG1_OFFSET 0x0104 /* Endpoint 1 Configuration Register */ +#define AVR32_USBB_UECFG2_OFFSET 0x0108 /* Endpoint 2 Configuration Register */ +#define AVR32_USBB_UECFG3_OFFSET 0x010c /* Endpoint 3 Configuration Register */ +#define AVR32_USBB_UECFG4_OFFSET 0x0110 /* Endpoint 4 Configuration Register */ +#define AVR32_USBB_UECFG5_OFFSET 0x0114 /* Endpoint 5 Configuration Register */ +#define AVR32_USBB_UECFG6_OFFSET 0x0118 /* Endpoint 6 Configuration Register */ + +#define AVR32_USBB_UESTA_OFFSET(n) (0x0130+((n)<<2)) +#define AVR32_USBB_UESTA0_OFFSET 0x0130 /* Endpoint 0 Status Register */ +#define AVR32_USBB_UESTA1_OFFSET 0x0134 /* Endpoint 1 Status Register */ +#define AVR32_USBB_UESTA2_OFFSET 0x0138 /* Endpoint 2 Status Register */ +#define AVR32_USBB_UESTA3_OFFSET 0x013c /* Endpoint 3 Status Register */ +#define AVR32_USBB_UESTA4_OFFSET 0x0140 /* Endpoint 4 Status Register */ +#define AVR32_USBB_UESTA5_OFFSET 0x0144 /* Endpoint 5 Status Register */ +#define AVR32_USBB_UESTA6_OFFSET 0x0148 /* Endpoint 6 Status Register */ + +#define AVR32_USBB_UESTACLR_OFFSET(n) (0x0160+((n)<<2)) +#define AVR32_USBB_UESTA0CLR_OFFSET 0x0160 /* Endpoint 0 Status Clear Register */ +#define AVR32_USBB_UESTA1CLR_OFFSET 0x0164 /* Endpoint 1 Status Clear Register */ +#define AVR32_USBB_UESTA2CLR_OFFSET 0x0168 /* Endpoint 2 Status Clear Register */ +#define AVR32_USBB_UESTA3CLR_OFFSET 0x016c /* Endpoint 3 Status Clear Register */ +#define AVR32_USBB_UESTA4CLR_OFFSET 0x0170 /* Endpoint 4 Status Clear Register */ +#define AVR32_USBB_UESTA5CLR_OFFSET 0x0174 /* Endpoint 5 Status Clear Register */ +#define AVR32_USBB_UESTA6CLR_OFFSET 0x0178 /* Endpoint 6 Status Clear Register */ + +#define AVR32_USBB_UESTASET_OFFSET(n) (0x0190+((n)<<2)) +#define AVR32_USBB_UESTA0SET_OFFSET 0x0190 /* Endpoint 0 Status Set Register */ +#define AVR32_USBB_UESTA1SET_OFFSET 0x0194 /* Endpoint 1 Status Set Register */ +#define AVR32_USBB_UESTA2SET_OFFSET 0x0198 /* Endpoint 2 Status Set Register */ +#define AVR32_USBB_UESTA3SET_OFFSET 0x019c /* Endpoint 3 Status Set Register */ +#define AVR32_USBB_UESTA4SET_OFFSET 0x01a0 /* Endpoint 4 Status Set Register */ +#define AVR32_USBB_UESTA5SET_OFFSET 0x01a4 /* Endpoint 5 Status Set Register */ +#define AVR32_USBB_UESTA6SET_OFFSET 0x01a8 /* Endpoint 6 Status Set Register */ + +#define AVR32_USBB_UECON_OFFSET(n) (0x01c0+((n)<<2)) +#define AVR32_USBB_UECON0_OFFSET 0x01c0 /* Endpoint 0 Control Register */ +#define AVR32_USBB_UECON1_OFFSET 0x01c4 /* Endpoint 1 Control Register */ +#define AVR32_USBB_UECON2_OFFSET 0x01c8 /* Endpoint 2 Control Register */ +#define AVR32_USBB_UECON3_OFFSET 0x01cc /* Endpoint 3 Control Register */ +#define AVR32_USBB_UECON4_OFFSET 0x01d0 /* Endpoint 4 Control Register */ +#define AVR32_USBB_UECON5_OFFSET 0x01d4 /* Endpoint 5 Control Register */ +#define AVR32_USBB_UECON6_OFFSET 0x01d8 /* Endpoint 7 Control Register */ + +#define AVR32_USBB_UECONSET_OFFSET(n) (0x01f0+((n)<<2)) +#define AVR32_USBB_UECON0SET_OFFSET 0x01f0 /* Endpoint 0 Control Set Register */ +#define AVR32_USBB_UECON1SET_OFFSET 0x01f4 /* Endpoint 1 Control Set Register */ +#define AVR32_USBB_UECON2SET_OFFSET 0x01f8 /* Endpoint 2 Control Set Register */ +#define AVR32_USBB_UECON3SET_OFFSET 0x01fc /* Endpoint 3 Control Set Register */ +#define AVR32_USBB_UECON4SET_OFFSET 0x0200 /* Endpoint 4 Control Set Register */ +#define AVR32_USBB_UECON5SET_OFFSET 0x0204 /* Endpoint 5 Control Set Register */ +#define AVR32_USBB_UECON6SET_OFFSET 0x0208 /* Endpoint 6 Control Set Register */ + +#define AVR32_USBB_UECONCLR_OFFSET(n) (0x0220+((n)<<2)) +#define AVR32_USBB_UECON0CLR_OFFSET 0x0220 /* Endpoint 0 Control Clear Register */ +#define AVR32_USBB_UECON1CLR_OFFSET 0x0224 /* Endpoint 1 Control Clear Register */ +#define AVR32_USBB_UECON2CLR_OFFSET 0x0228 /* Endpoint 2 Control Clear Register */ +#define AVR32_USBB_UECON3CLR_OFFSET 0x022c /* Endpoint 3 Control Clear Register */ +#define AVR32_USBB_UECON4CLR_OFFSET 0x0230 /* Endpoint 4 Control Clear Register */ +#define AVR32_USBB_UECON5CLR_OFFSET 0x0234 /* Endpoint 5 Control Clear Register */ +#define AVR32_USBB_UECON6CLR_OFFSET 0x0238 /* Endpoint 6 Control Clear Register */ + +#define AVR32_UDDMA_OFFSET(n) (0x0300+((n)<<4)) +#define AVR32_UDDMA_NEXTDESC_OFFSET 0x0000 /* Device DMA Channel Next Descriptor Address Register */ +#define AVR32_UDDMA_ADDR_OFFSET 0x0004 /* Device DMA Channel HSB Address Register */ +#define AVR32_UDDMA_CTRL_OFFSET 0x0008 /* Device DMA Channel Control Register */ +#define AVR32_UDDMA_STATUS_OFFSET 0x000c /* Device DMA Channel Status Register */ + +#define AVR32_UDDMA1_NEXTDESC_OFFSET 0x0310 /* Device DMA Channel 1 Next Descriptor Address Register */ +#define AVR32_UDDMA1_ADDR_OFFSET 0x0314 /* Device DMA Channel 1 HSB Address Register */ +#define AVR32_UDDMA1_CTRL_OFFSET 0x0318 /* Device DMA Channel 1 Control Register */ +#define AVR32_UDDMA1_STATUS_OFFSET 0x031c /* Device DMA Channel 1 Status Register */ + +#define AVR32_UDDMA1_NEXTDESC_OFFSET 0x0310 /* Device DMA Channel 1 Next Descriptor Address Register */ +#define AVR32_UDDMA1_ADDR_OFFSET 0x0314 /* Device DMA Channel 1 HSB Address Register */ +#define AVR32_UDDMA1_CTRL_OFFSET 0x0318 /* Device DMA Channel 1 Control Register */ +#define AVR32_UDDMA1_STATUS_OFFSET 0x031c /* Device DMA Channel 1 Status Register */ + +#define AVR32_UDDMA2_NEXTDESC_OFFSET 0x0320 /* Device DMA Channel 2 Next Descriptor Address Register */ +#define AVR32_UDDMA2_ADDR_OFFSET 0x0324 /* Device DMA Channel 2 HSB Address Register */ +#define AVR32_UDDMA2_CTRL_OFFSET 0x0328 /* Device DMA Channel 2 Control Register */ +#define AVR32_UDDMA2_STATUS_OFFSET 0x032c /* Device DMA Channel 2 Status Register */ + +#define AVR32_UDDMA3_NEXTDESC_OFFSET 0x0330 /* Device DMA Channel 3 Next Descriptor Address Register */ +#define AVR32_UDDMA3_ADDR_OFFSET 0x0334 /* Device DMA Channel 3 HSB Address Register */ +#define AVR32_UDDMA3_CTRL_OFFSET 0x0338 /* Device DMA Channel 3 Control Register */ +#define AVR32_UDDMA3_STATUS_OFFSET 0x033c /* Device DMA Channel 3 Status Register */ + +#define AVR32_UDDMA4_NEXTDESC_OFFSET 0x0340 /* Device DMA Channel 4 Next Descriptor Address Register */ +#define AVR32_UDDMA4_ADDR_OFFSET 0x0344 /* Device DMA Channel 4 HSB Address Register */ +#define AVR32_UDDMA4_CTRL_OFFSET 0x0348 /* Device DMA Channel 4 Control Register */ +#define AVR32_UDDMA4_STATUS_OFFSET 0x034c /* Device DMA Channel 4 Status Register */ + +#define AVR32_UDDMA5_NEXTDESC_OFFSET 0x0350 /* Device DMA Channel 5 Next Descriptor Address Register */ +#define AVR32_UDDMA5_ADDR_OFFSET 0x0354 /* Device DMA Channel 5 HSB Address Register */ +#define AVR32_UDDMA5_CTRL_OFFSET 0x0358 /* Device DMA Channel 5 Control Register */ +#define AVR32_UDDMA5_STATUS_OFFSET 0x035c /* Device DMA Channel 5 Status Register */ + +#define AVR32_UDDMA6_NEXTDESC_OFFSET 0x0360 /* Device DMA Channel 6 Next Descriptor Address Register */ +#define AVR32_UDDMA6_ADDR_OFFSET 0x0364 /* Device DMA Channel 6 HSB Address Register */ +#define AVR32_UDDMA6_CTRL_OFFSET 0x0368 /* Device DMA Channel 6 Control Register */ +#define AVR32_UDDMA6_STATUS_OFFSET 0x036c /* Device DMA Channel 6 Status Register */ + +/* USB Host Registers */ + +#define AVR32_USBB_UHCON_OFFSET 0x0400 /* Host General Control Register */ +#define AVR32_USBB_UHINT_OFFSET 0x0404 /* Host Global Interrupt Register */ +#define AVR32_USBB_UHINTCLR_OFFSET 0x0408 /* Host Global Interrupt Clear Register */ +#define AVR32_USBB_UHINTSET_OFFSET 0x040c /* Host Global Interrupt Set Register */ +#define AVR32_USBB_UHINTE_OFFSET 0x0410 /* Host Global Interrupt Enable Register */ +#define AVR32_USBB_UHINTECLR_OFFSET 0x0414 /* Host Global Interrupt Enable Clear Register */ +#define AVR32_USBB_UHINTESET_OFFSET 0x0418 /* Host Global Interrupt Enable Set Register */ +#define AVR32_USBB_UPRST_OFFSET 0x041c /* Pipe Enable/Reset Register */ +#define AVR32_USBB_UHFNUM_OFFSET 0x0420 /* Host Frame Number Register */ +#define AVR32_USBB_UHADDR1_OFFSET 0x0424 /* Host Address 1 Register */ +#define AVR32_USBB_UHADDR2_OFFSET 0x0428 /* Host Address 2 Register */ + +#define AVR32_USBB_UPCFG_OFFSET(n) (0x0500+((n)<<2)) +#define AVR32_USBB_UPCFG0_OFFSET 0x0500 /* Pipe 0 Configuration Register */ +#define AVR32_USBB_UPCFG1_OFFSET 0x0504 /* Pipe 1 Configuration Register */ +#define AVR32_USBB_UPCFG2_OFFSET 0x0508 /* Pipe 2 Configuration Register */ +#define AVR32_USBB_UPCFG3_OFFSET 0x050c /* Pipe 3 Configuration Register */ +#define AVR32_USBB_UPCFG4_OFFSET 0x0510 /* Pipe 4 Configuration Register */ +#define AVR32_USBB_UPCFG5_OFFSET 0x0514 /* Pipe 5 Configuration Register */ +#define AVR32_USBB_UPCFG6_OFFSET 0x0518 /* Pipe 6 Configuration Register */ + +#define AVR32_USBB_UPSTA_OFFSET(n) (0x0530+((n)<<2)) +#define AVR32_USBB_UPSTA0_OFFSET 0x0530 /* Pipe 0 Status Register */ +#define AVR32_USBB_UPSTA1_OFFSET 0x0534 /* Pipe 1 Status Register */ +#define AVR32_USBB_UPSTA2_OFFSET 0x0538 /* Pipe 2 Status Register */ +#define AVR32_USBB_UPSTA3_OFFSET 0x053c /* Pipe 3 Status Register */ +#define AVR32_USBB_UPSTA4_OFFSET 0x0540 /* Pipe 4 Status Register */ +#define AVR32_USBB_UPSTA5_OFFSET 0x0544 /* Pipe 5 Status Register */ +#define AVR32_USBB_UPSTA6_OFFSET 0x0548 /* Pipe 6 Status Register */ + +#define AVR32_USBB_UPSTACLR_OFFSET(n) (0x0560+((n)<<2)) +#define AVR32_USBB_UPSTA0CLR_OFFSET 0x0560 /* Pipe 0 Status Clear Register */ +#define AVR32_USBB_UPSTA1CLR_OFFSET 0x0564 /* Pipe 1 Status Clear Register */ +#define AVR32_USBB_UPSTA2CLR_OFFSET 0x0568 /* Pipe 2 Status Clear Register */ +#define AVR32_USBB_UPSTA3CLR_OFFSET 0x056c /* Pipe 3 Status Clear Register */ +#define AVR32_USBB_UPSTA4CLR_OFFSET 0x0570 /* Pipe 4 Status Clear Register */ +#define AVR32_USBB_UPSTA5CLR_OFFSET 0x0574 /* Pipe 5 Status Clear Register */ +#define AVR32_USBB_UPSTA6CLR_OFFSET 0x0578 /* Pipe 6 Status Clear Register */ + +#define AVR32_USBB_UPSTASET_OFFSET(n) (0x0590+((n)<<2)) +#define AVR32_USBB_UPSTA0SET_OFFSET 0x0590 /* Pipe 0 Status Set Register */ +#define AVR32_USBB_UPSTA1SET_OFFSET 0x0594 /* Pipe 1 Status Set Register */ +#define AVR32_USBB_UPSTA2SET_OFFSET 0x0598 /* Pipe 2 Status Set Register */ +#define AVR32_USBB_UPSTA3SET_OFFSET 0x059c /* Pipe 3 Status Set Register */ +#define AVR32_USBB_UPSTA4SET_OFFSET 0x05a0 /* Pipe 4 Status Set Register */ +#define AVR32_USBB_UPSTA5SET_OFFSET 0x05a4 /* Pipe 5 Status Set Register */ +#define AVR32_USBB_UPSTA6SET_OFFSET 0x05a8 /* Pipe 6 Status Set Register */ + +#define AVR32_USBB_UPCON_OFFSET(n) (0x05c0+((n)<<2)) +#define AVR32_USBB_UPCON0_OFFSET 0x05c0 /* Pipe 0 Control Register */ +#define AVR32_USBB_UPCON1_OFFSET 0x05c4 /* Pipe 1 Control Register */ +#define AVR32_USBB_UPCON2_OFFSET 0x05c8 /* Pipe 2 Control Register */ +#define AVR32_USBB_UPCON3_OFFSET 0x05cc /* Pipe 3 Control Register */ +#define AVR32_USBB_UPCON4_OFFSET 0x05d0 /* Pipe 4 Control Register */ +#define AVR32_USBB_UPCON5_OFFSET 0x05d4 /* Pipe 5 Control Register */ +#define AVR32_USBB_UPCON6_OFFSET 0x05d8 /* Pipe 6 Control Register */ + +#define AVR32_USBB_UPCONSET_OFFSET(n) (0x05f0+((n)<<2)) +#define AVR32_USBB_UPCON0SET_OFFSET 0x05f0 /* Pipe 0 Control Set Register */ +#define AVR32_USBB_UPCON1SET_OFFSET 0x05f4 /* Pipe 1 Control Set Register */ +#define AVR32_USBB_UPCON2SET_OFFSET 0x05f8 /* Pipe 2 Control Set Register */ +#define AVR32_USBB_UPCON3SET_OFFSET 0x05fc /* Pipe 3 Control Set Register */ +#define AVR32_USBB_UPCON4SET_OFFSET 0x0600 /* Pipe 4 Control Set Register */ +#define AVR32_USBB_UPCON5SET_OFFSET 0x0604 /* Pipe 5 Control Set Register */ +#define AVR32_USBB_UPCON6SET_OFFSET 0x0608 /* Pipe 6 Control Set Register */ + +#define AVR32_USBB_UPCONCLR_OFFSET(n) (0x0620+((n)<<2)) +#define AVR32_USBB_UPCON0CLR_OFFSET 0x0620 /* Pipe 0 Control Clear Register */ +#define AVR32_USBB_UPCON1CLR_OFFSET 0x0624 /* Pipe 1 Control Clear Register */ +#define AVR32_USBB_UPCON2CLR_OFFSET 0x0628 /* Pipe 2 Control Clear Register */ +#define AVR32_USBB_UPCON3CLR_OFFSET 0x062c /* Pipe 3 Control Clear Register */ +#define AVR32_USBB_UPCON4CLR_OFFSET 0x0630 /* Pipe 4 Control Clear Register */ +#define AVR32_USBB_UPCON5CLR_OFFSET 0x0634 /* Pipe 5 Control Clear Register */ +#define AVR32_USBB_UPCON6CLR_OFFSET 0x0638 /* Pipe 6 Control Clear Register */ + +#define AVR32_USBB_UPINRQ_OFFSET(n) (0x0650+((n)<<2)) +#define AVR32_USBB_UPINRQ0_OFFSET 0x0650 /* Pipe 0 IN Request Register */ +#define AVR32_USBB_UPINRQ1_OFFSET 0x0654 /* Pipe 1 IN Request Register */ +#define AVR32_USBB_UPINRQ2_OFFSET 0x0658 /* Pipe 2 IN Request Register */ +#define AVR32_USBB_UPINRQ3_OFFSET 0x065c /* Pipe 3 IN Request Register */ +#define AVR32_USBB_UPINRQ4_OFFSET 0x0660 /* Pipe 4 IN Request Register */ +#define AVR32_USBB_UPINRQ5_OFFSET 0x0664 /* Pipe 5 IN Request Register */ +#define AVR32_USBB_UPINRQ6_OFFSET 0x0668 /* Pipe 6 IN Request Register */ + +#define AVR32_USBB_UPERR_OFFSET(n) (0x0680+((n)<<2)) +#define AVR32_USBB_UPERR0_OFFSET 0x0680 /* Pipe 0 Error Register */ +#define AVR32_USBB_UPERR1_OFFSET 0x0684 /* Pipe 1 Error Register */ +#define AVR32_USBB_UPERR2_OFFSET 0x0688 /* Pipe 2 Error Register */ +#define AVR32_USBB_UPERR3_OFFSET 0x068c /* Pipe 3 Error Register */ +#define AVR32_USBB_UPERR4_OFFSET 0x0690 /* Pipe 4 Error Register */ +#define AVR32_USBB_UPERR5_OFFSET 0x0694 /* Pipe 5 Error Register */ +#define AVR32_USBB_UPERR6_OFFSET 0x0698 /* Pipe 6 Error Register */ + +#define AVR32_UHDMA_OFFSET(n) (0x0700+((n)<<4)) +#define AVR32_UHDMA_NEXTDESC_OFFSET 0x0000 /* Host DMA Channel Next Descriptor Address Register */ +#define AVR32_UHDMA_ADDR_OFFSET 0x0004 /* Host DMA Channel HSB Address Register */ +#define AVR32_UHDMA_CTRL_OFFSET 0x0008 /* Host DMA Channel Control Register */ +#define AVR32_UHDMA_STATUS_OFFSET 0x000c /* Host DMA Channel Status Register */ + +#define AVR32_UHDMA1_NEXTDESC_OFFSET 0x0710 /* Host DMA Channel 1 Next Descriptor Address Register */ +#define AVR32_UHDMA1_ADDR_OFFSET 0x0714 /* Host DMA Channel 1 HSB Address Register */ +#define AVR32_UHDMA1_CTRL_OFFSET 0x0718 /* Host DMA Channel 1 Control Register */ +#define AVR32_UHDMA1_STATUS_OFFSET 0x071c /* Host DMA Channel 1 Status Register */ + +#define AVR32_UHDMA2_NEXTDESC_OFFSET 0x0720 /* Host DMA Channel 2 Next Descriptor Address Register */ +#define AVR32_UHDMA2_ADDR_OFFSET 0x0724 /* Host DMA Channel 2 HSB Address Register */ +#define AVR32_UHDMA2_CTRL_OFFSET 0x0728 /* Host DMA Channel 2 Control Register */ +#define AVR32_UHDMA2_STATUS_OFFSET 0x072c /* Host DMA Channel 2 Status Register */ + +#define AVR32_UHDMA3_NEXTDESC_OFFSET 0x0730 /* Host DMA Channel 3 Next Descriptor Address Register */ +#define AVR32_UHDMA3_ADDR_OFFSET 0x0734 /* Host DMA Channel 3 HSB Address Register */ +#define AVR32_UHDMA3_CTRL_OFFSET 0x0738 /* Host DMA Channel 3 Control Register */ +#define AVR32_UHDMA3_STATUS_OFFSET 0x073c /* Host DMA Channel 3 Status Register */ + +#define AVR32_UHDMA4_NEXTDESC_OFFSET 0x0740 /* Host DMA Channel 4 Next Descriptor Address Register */ +#define AVR32_UHDMA4_ADDR_OFFSET 0x0744 /* Host DMA Channel 4 HSB Address Register */ +#define AVR32_UHDMA4_CTRL_OFFSET 0x0748 /* Host DMA Channel 4 Control Register */ +#define AVR32_UHDMA4_STATUS_OFFSET 0x074c /* Host DMA Channel 4 Status Register */ + +#define AVR32_UHDMA5_NEXTDESC_OFFSET 0x0750 /* Host DMA Channel 5 Next Descriptor Address Register */ +#define AVR32_UHDMA5_ADDR_OFFSET 0x0754 /* Host DMA Channel 5 HSB Address Register */ +#define AVR32_UHDMA5_CTRL_OFFSET 0x0758 /* Host DMA Channel 5 Control Register */ +#define AVR32_UHDMA5_STATUS_OFFSET 0x075c /* Host DMA Channel 5 Status Register */ + +#define AVR32_UHDMA6_NEXTDESC_OFFSET 0x0760 /* Host DMA Channel 6 Next Descriptor Address Register */ +#define AVR32_UHDMA6_ADDR_OFFSET 0x0764 /* Host DMA Channel 6 HSB Address Register */ +#define AVR32_UHDMA6_CTRL_OFFSET 0x0768 /* Host DMA Channel 6 Control Register */ +#define AVR32_UHDMA6_STATUS_OFFSET 0x076c /* Host DMA Channel 6 Status Register */ + +/* USB General Registers */ + +#define AVR32_USBB_USBCON_OFFSET 0x0800 /* General Control Register */ +#define AVR32_USBB_USBSTA_OFFSET 0x0804 /* General Status Register */ +#define AVR32_USBB_USBSTACLR_OFFSET 0x0808 /* General Status Clear Register */ +#define AVR32_USBB_USBSTASET_OFFSET 0x080c /* General Status Set Register */ +#define AVR32_USBB_UVERS_OFFSET 0x0818 /* IP Version Register */ +#define AVR32_USBB_UFEATURES_OFFSET 0x081c /* IP Features Register */ +#define AVR32_USBB_UADDRSIZE_OFFSET 0x0820 /* IP PB Address Size Register */ +#define AVR32_USBB_UNAME1_OFFSET 0x0824 /* IP Name Register 1 */ +#define AVR32_USBB_UNAME2_OFFSET 0x0828 /* IP Name Register 2 */ +#define AVR32_USBB_USBFSM_OFFSET 0x082c /* USB Finite State Machine Status Register */ + +/* Register Addresses ***************************************************************/ + +/* USB Device Registers */ + +#define AVR32_USBB_UDCON (AVR32_USB_BASE+AVR32_USBB_UDCON_OFFSET) +#define AVR32_USBB_UDINT (AVR32_USB_BASE+AVR32_USBB_UDINT_OFFSET) +#define AVR32_USBB_UDINTCLR (AVR32_USB_BASE+AVR32_USBB_UDINTCLR_OFFSET) +#define AVR32_USBB_UDINTSET (AVR32_USB_BASE+AVR32_USBB_UDINTSET_OFFSET) +#define AVR32_USBB_UDINTE (AVR32_USB_BASE+AVR32_USBB_UDINTE_OFFSET) +#define AVR32_USBB_UDINTECLR (AVR32_USB_BASE+AVR32_USBB_UDINTECLR_OFFSET) +#define AVR32_USBB_UDINTESET (AVR32_USB_BASE+AVR32_USBB_UDINTESET_OFFSET) +#define AVR32_USBB_UERST (AVR32_USB_BASE+AVR32_USBB_UERST_OFFSET) +#define AVR32_USBB_UDFNUM (AVR32_USB_BASE+AVR32_USBB_UDFNUM_OFFSET) + +#define AVR32_USBB_UECFG(n) (AVR32_USB_BASE+AVR32_USBB_UECFG_OFFSET(n)) +#define AVR32_USBB_UECFG0 (AVR32_USB_BASE+AVR32_USBB_UECFG0_OFFSET) +#define AVR32_USBB_UECFG1 (AVR32_USB_BASE+AVR32_USBB_UECFG1_OFFSET) +#define AVR32_USBB_UECFG2 (AVR32_USB_BASE+AVR32_USBB_UECFG2_OFFSET) +#define AVR32_USBB_UECFG3 (AVR32_USB_BASE+AVR32_USBB_UECFG3_OFFSET) +#define AVR32_USBB_UECFG4 (AVR32_USB_BASE+AVR32_USBB_UECFG4_OFFSET) +#define AVR32_USBB_UECFG5 (AVR32_USB_BASE+AVR32_USBB_UECFG5_OFFSET) +#define AVR32_USBB_UECFG6 (AVR32_USB_BASE+AVR32_USBB_UECFG6_OFFSET) + +#define AVR32_USBB_UESTA(n) (AVR32_USB_BASE+AVR32_USBB_UESTA_OFFSET(n)) +#define AVR32_USBB_UESTA0 (AVR32_USB_BASE+AVR32_USBB_UESTA0_OFFSET) +#define AVR32_USBB_UESTA1 (AVR32_USB_BASE+AVR32_USBB_UESTA1_OFFSET) +#define AVR32_USBB_UESTA2 (AVR32_USB_BASE+AVR32_USBB_UESTA2_OFFSET) +#define AVR32_USBB_UESTA3 (AVR32_USB_BASE+AVR32_USBB_UESTA3_OFFSET) +#define AVR32_USBB_UESTA4 (AVR32_USB_BASE+AVR32_USBB_UESTA4_OFFSET) +#define AVR32_USBB_UESTA5 (AVR32_USB_BASE+AVR32_USBB_UESTA5_OFFSET) +#define AVR32_USBB_UESTA6 (AVR32_USB_BASE+AVR32_USBB_UESTA6_OFFSET) + +#define AVR32_USBB_UESTACLR(n) (AVR32_USB_BASE+AVR32_USBB_UESTACLR_OFFSET(n)) +#define AVR32_USBB_UESTA0CLR (AVR32_USB_BASE+AVR32_USBB_UESTA0CLR_OFFSET) +#define AVR32_USBB_UESTA1CLR (AVR32_USB_BASE+AVR32_USBB_UESTA1CLR_OFFSET) +#define AVR32_USBB_UESTA2CLR (AVR32_USB_BASE+AVR32_USBB_UESTA2CLR_OFFSET) +#define AVR32_USBB_UESTA3CLR (AVR32_USB_BASE+AVR32_USBB_UESTA3CLR_OFFSET) +#define AVR32_USBB_UESTA4CLR (AVR32_USB_BASE+AVR32_USBB_UESTA4CLR_OFFSET) +#define AVR32_USBB_UESTA5CLR (AVR32_USB_BASE+AVR32_USBB_UESTA5CLR_OFFSET) +#define AVR32_USBB_UESTA6CLR (AVR32_USB_BASE+AVR32_USBB_UESTA6CLR_OFFSET) + +#define AVR32_USBB_UESTASET(n) (AVR32_USB_BASE+AVR32_USBB_UESTASET_OFFSET(n)) +#define AVR32_USBB_UESTA0SET (AVR32_USB_BASE+AVR32_USBB_UESTA0SET_OFFSET) +#define AVR32_USBB_UESTA1SET (AVR32_USB_BASE+AVR32_USBB_UESTA1SET_OFFSET) +#define AVR32_USBB_UESTA2SET (AVR32_USB_BASE+AVR32_USBB_UESTA2SET_OFFSET) +#define AVR32_USBB_UESTA3SET (AVR32_USB_BASE+AVR32_USBB_UESTA3SET_OFFSET) +#define AVR32_USBB_UESTA4SET (AVR32_USB_BASE+AVR32_USBB_UESTA4SET_OFFSET) +#define AVR32_USBB_UESTA5SET (AVR32_USB_BASE+AVR32_USBB_UESTA5SET_OFFSET) +#define AVR32_USBB_UESTA6SET (AVR32_USB_BASE+AVR32_USBB_UESTA6SET_OFFSET) + +#define AVR32_USBB_UECON(n) (AVR32_USB_BASE+AVR32_USBB_UECON_OFFSET(n)) +#define AVR32_USBB_UECON0 (AVR32_USB_BASE+AVR32_USBB_UECON0_OFFSET) +#define AVR32_USBB_UECON1 (AVR32_USB_BASE+AVR32_USBB_UECON1_OFFSET) +#define AVR32_USBB_UECON2 (AVR32_USB_BASE+AVR32_USBB_UECON2_OFFSET) +#define AVR32_USBB_UECON3 (AVR32_USB_BASE+AVR32_USBB_UECON3_OFFSET) +#define AVR32_USBB_UECON4 (AVR32_USB_BASE+AVR32_USBB_UECON4_OFFSET) +#define AVR32_USBB_UECON5 (AVR32_USB_BASE+AVR32_USBB_UECON5_OFFSET) +#define AVR32_USBB_UECON6 (AVR32_USB_BASE+AVR32_USBB_UECON6_OFFSET) + +#define AVR32_USBB_UECONSET(n) (AVR32_USB_BASE+AVR32_USBB_UECONSET_OFFSET(n)) +#define AVR32_USBB_UECON0SET (AVR32_USB_BASE+AVR32_USBB_UECON0SET_OFFSET) +#define AVR32_USBB_UECON1SET (AVR32_USB_BASE+AVR32_USBB_UECON1SET_OFFSET) +#define AVR32_USBB_UECON2SET (AVR32_USB_BASE+AVR32_USBB_UECON2SET_OFFSET) +#define AVR32_USBB_UECON3SET (AVR32_USB_BASE+AVR32_USBB_UECON3SET_OFFSET) +#define AVR32_USBB_UECON4SET (AVR32_USB_BASE+AVR32_USBB_UECON4SET_OFFSET) +#define AVR32_USBB_UECON5SET (AVR32_USB_BASE+AVR32_USBB_UECON5SET_OFFSET) +#define AVR32_USBB_UECON6SET (AVR32_USB_BASE+AVR32_USBB_UECON6SET_OFFSET) + +#define AVR32_USBB_UECONCLR(n) (AVR32_USB_BASE+AVR32_USBB_UECONCLR_OFFSET(n)) +#define AVR32_USBB_UECON0CLR (AVR32_USB_BASE+AVR32_USBB_UECON0CLR_OFFSET) +#define AVR32_USBB_UECON1CLR (AVR32_USB_BASE+AVR32_USBB_UECON1CLR_OFFSET) +#define AVR32_USBB_UECON2CLR (AVR32_USB_BASE+AVR32_USBB_UECON2CLR_OFFSET) +#define AVR32_USBB_UECON3CLR (AVR32_USB_BASE+AVR32_USBB_UECON3CLR_OFFSET) +#define AVR32_USBB_UECON4CLR (AVR32_USB_BASE+AVR32_USBB_UECON4CLR_OFFSET) +#define AVR32_USBB_UECON5CLR (AVR32_USB_BASE+AVR32_USBB_UECON5CLR_OFFSET) +#define AVR32_USBB_UECON6CLR (AVR32_USB_BASE+AVR32_USBB_UECON6CLR_OFFSET) + +#define AVR32_UDDMA_BASE(n) (AVR32_USB_BASE+AVR32_UDDMA_OFFSET(n)) +#define AVR32_UDDMA_NEXTDESC(n) (AVR32_UDDMA_BASE(n)+AVR32_UDDMA_NEXTDESC_OFFSET) +#define AVR32_UDDMA_ADDR(n) (AVR32_UDDMA_BASE(n)+AVR32_UDDMA_ADDR_OFFSET) +#define AVR32_UDDMA_CTRL(n) (AVR32_UDDMA_BASE(n)+AVR32_UDDMA_CTRL_OFFSET) +#define AVR32_UDDMA_STATUS(n) (AVR32_UDDMA_BASE(n)+AVR32_UDDMA_STATUS_OFFSET) + +#define AVR32_UDDMA1_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA1_NEXTDESC_OFFSET) +#define AVR32_UDDMA1_ADDR (AVR32_USB_BASE+AVR32_UDDMA1_ADDR_OFFSET) +#define AVR32_UDDMA1_CTRL (AVR32_USB_BASE+AVR32_UDDMA1_CTRL_OFFSET) +#define AVR32_UDDMA1_STATUS (AVR32_USB_BASE+AVR32_UDDMA1_STATUS_OFFSET) + +#define AVR32_UDDMA2_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA2_NEXTDESC_OFFSET) +#define AVR32_UDDMA2_ADDR (AVR32_USB_BASE+AVR32_UDDMA2_ADDR_OFFSET) +#define AVR32_UDDMA2_CTRL (AVR32_USB_BASE+AVR32_UDDMA2_CTRL_OFFSET) +#define AVR32_UDDMA2_STATUS (AVR32_USB_BASE+AVR32_UDDMA2_STATUS_OFFSET) + +#define AVR32_UDDMA3_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA3_NEXTDESC_OFFSET) +#define AVR32_UDDMA3_ADDR (AVR32_USB_BASE+AVR32_UDDMA3_ADDR_OFFSET) +#define AVR32_UDDMA3_CTRL (AVR32_USB_BASE+AVR32_UDDMA3_CTRL_OFFSET) +#define AVR32_UDDMA3_STATUS (AVR32_USB_BASE+AVR32_UDDMA3_STATUS_OFFSET) + +#define AVR32_UDDMA4_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA4_NEXTDESC_OFFSET) +#define AVR32_UDDMA4_ADDR (AVR32_USB_BASE+AVR32_UDDMA4_ADDR_OFFSET ) +#define AVR32_UDDMA4_CTRL (AVR32_USB_BASE+AVR32_UDDMA4_CTRL_OFFSET) +#define AVR32_UDDMA4_STATUS (AVR32_USB_BASE+AVR32_UDDMA4_STATUS_OFFSET) + +#define AVR32_UDDMA5_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA5_NEXTDESC_OFFSET) +#define AVR32_UDDMA5_ADDR (AVR32_USB_BASE+AVR32_UDDMA5_ADDR_OFFSET) +#define AVR32_UDDMA5_CTRL (AVR32_USB_BASE+AVR32_UDDMA5_CTRL_OFFSET) +#define AVR32_UDDMA5_STATUS (AVR32_USB_BASE+AVR32_UDDMA5_STATUS_OFFSET) + +#define AVR32_UDDMA6_NEXTDESC (AVR32_USB_BASE+AVR32_UDDMA6_NEXTDESC_OFFSET) +#define AVR32_UDDMA6_ADDR (AVR32_USB_BASE+AVR32_UDDMA6_ADDR_OFFSET) +#define AVR32_UDDMA6_CTRL (AVR32_USB_BASE+AVR32_UDDMA6_CTRL_OFFSET) +#define AVR32_UDDMA6_STATUS (AVR32_USB_BASE+AVR32_UDDMA6_STATUS_OFFSET) + +/* USB Host Registers */ + +#define AVR32_USBB_UHCON (AVR32_USB_BASE+AVR32_USBB_UHCON_OFFSET) +#define AVR32_USBB_UHINT (AVR32_USB_BASE+AVR32_USBB_UHINT_OFFSET) +#define AVR32_USBB_UHINTCLR (AVR32_USB_BASE+AVR32_USBB_UHINTCLR_OFFSET) +#define AVR32_USBB_UHINTSET (AVR32_USB_BASE+AVR32_USBB_UHINTSET_OFFSET) +#define AVR32_USBB_UHINTE (AVR32_USB_BASE+AVR32_USBB_UHINTE_OFFSET) +#define AVR32_USBB_UHINTECLR (AVR32_USB_BASE+AVR32_USBB_UHINTECLR_OFFSET) +#define AVR32_USBB_UHINTESET (AVR32_USB_BASE+AVR32_USBB_UHINTESET_OFFSET) +#define AVR32_USBB_UPRST (AVR32_USB_BASE+AVR32_USBB_UPRST_OFFSET) +#define AVR32_USBB_UHFNUM (AVR32_USB_BASE+AVR32_USBB_UHFNUM_OFFSET) +#define AVR32_USBB_UHADDR1 (AVR32_USB_BASE+AVR32_USBB_UHADDR1_OFFSET) +#define AVR32_USBB_UHADDR2 (AVR32_USB_BASE+AVR32_USBB_UHADDR2_OFFSET) + +#define AVR32_USBB_UPCFG(n) (AVR32_USB_BASE+AVR32_USBB_UPCFG_OFFSET(n)) +#define AVR32_USBB_UPCFG0 (AVR32_USB_BASE+AVR32_USBB_UPCFG0_OFFSET) +#define AVR32_USBB_UPCFG1 (AVR32_USB_BASE+AVR32_USBB_UPCFG1_OFFSET) +#define AVR32_USBB_UPCFG2 (AVR32_USB_BASE+AVR32_USBB_UPCFG2_OFFSET) +#define AVR32_USBB_UPCFG3 (AVR32_USB_BASE+AVR32_USBB_UPCFG3_OFFSET) +#define AVR32_USBB_UPCFG4 (AVR32_USB_BASE+AVR32_USBB_UPCFG4_OFFSET) +#define AVR32_USBB_UPCFG5 (AVR32_USB_BASE+AVR32_USBB_UPCFG5_OFFSET) +#define AVR32_USBB_UPCFG6 (AVR32_USB_BASE+AVR32_USBB_UPCFG6_OFFSET) + +#define AVR32_USBB_UPSTA(n) (AVR32_USB_BASE+AVR32_USBB_UPSTA_OFFSET(n)) +#define AVR32_USBB_UPSTA0 (AVR32_USB_BASE+AVR32_USBB_UPSTA0_OFFSET) +#define AVR32_USBB_UPSTA1 (AVR32_USB_BASE+AVR32_USBB_UPSTA1_OFFSET) +#define AVR32_USBB_UPSTA2 (AVR32_USB_BASE+AVR32_USBB_UPSTA2_OFFSET) +#define AVR32_USBB_UPSTA3 (AVR32_USB_BASE+AVR32_USBB_UPSTA3_OFFSET) +#define AVR32_USBB_UPSTA4 (AVR32_USB_BASE+AVR32_USBB_UPSTA4_OFFSET) +#define AVR32_USBB_UPSTA5 (AVR32_USB_BASE+AVR32_USBB_UPSTA5_OFFSET) +#define AVR32_USBB_UPSTA6 (AVR32_USB_BASE+AVR32_USBB_UPSTA6_OFFSET) + +#define AVR32_USBB_UPSTACLR(n) (AVR32_USB_BASE+AVR32_USBB_UPSTACLR_OFFSET(n)) +#define AVR32_USBB_UPSTA0CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA0CLR_OFFSET) +#define AVR32_USBB_UPSTA1CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA1CLR_OFFSET) +#define AVR32_USBB_UPSTA2CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA2CLR_OFFSET) +#define AVR32_USBB_UPSTA3CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA3CLR_OFFSET) +#define AVR32_USBB_UPSTA4CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA4CLR_OFFSET) +#define AVR32_USBB_UPSTA5CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA5CLR_OFFSET) +#define AVR32_USBB_UPSTA6CLR (AVR32_USB_BASE+AVR32_USBB_UPSTA6CLR_OFFSET) + +#define AVR32_USBB_UPSTASET(n) (AVR32_USB_BASE+AVR32_USBB_UPSTASET_OFFSET(n)) +#define AVR32_USBB_UPSTA0SET (AVR32_USB_BASE+AVR32_USBB_UPSTA0SET_OFFSET) +#define AVR32_USBB_UPSTA1SET (AVR32_USB_BASE+AVR32_USBB_UPSTA1SET_OFFSET) +#define AVR32_USBB_UPSTA2SET (AVR32_USB_BASE+AVR32_USBB_UPSTA2SET_OFFSET) +#define AVR32_USBB_UPSTA3SET (AVR32_USB_BASE+AVR32_USBB_UPSTA3SET_OFFSET) +#define AVR32_USBB_UPSTA4SET (AVR32_USB_BASE+AVR32_USBB_UPSTA4SET_OFFSET) +#define AVR32_USBB_UPSTA5SET (AVR32_USB_BASE+AVR32_USBB_UPSTA5SET_OFFSET) +#define AVR32_USBB_UPSTA6SET (AVR32_USB_BASE+AVR32_USBB_UPSTA6SET_OFFSET) + +#define AVR32_USBB_UPCON(n) (AVR32_USB_BASE+AVR32_USBB_UPCON_OFFSET(n)) +#define AVR32_USBB_UPCON0 (AVR32_USB_BASE+AVR32_USBB_UPCON0_OFFSET) +#define AVR32_USBB_UPCON1 (AVR32_USB_BASE+AVR32_USBB_UPCON1_OFFSET) +#define AVR32_USBB_UPCON2 (AVR32_USB_BASE+AVR32_USBB_UPCON2_OFFSET) +#define AVR32_USBB_UPCON3 (AVR32_USB_BASE+AVR32_USBB_UPCON3_OFFSET) +#define AVR32_USBB_UPCON4 (AVR32_USB_BASE+AVR32_USBB_UPCON4_OFFSET) +#define AVR32_USBB_UPCON5 (AVR32_USB_BASE+AVR32_USBB_UPCON5_OFFSET) +#define AVR32_USBB_UPCON6 (AVR32_USB_BASE+AVR32_USBB_UPCON6_OFFSET) + +#define AVR32_USBB_UPCONSET(n) (AVR32_USB_BASE+AVR32_USBB_UPCONSET_OFFSET(n)) +#define AVR32_USBB_UPCON0SET (AVR32_USB_BASE+AVR32_USBB_UPCON0SET_OFFSET) +#define AVR32_USBB_UPCON1SET (AVR32_USB_BASE+AVR32_USBB_UPCON1SET_OFFSET) +#define AVR32_USBB_UPCON2SET (AVR32_USB_BASE+AVR32_USBB_UPCON2SET_OFFSET) +#define AVR32_USBB_UPCON3SET (AVR32_USB_BASE+AVR32_USBB_UPCON3SET_OFFSET) +#define AVR32_USBB_UPCON4SET (AVR32_USB_BASE+AVR32_USBB_UPCON4SET_OFFSET) +#define AVR32_USBB_UPCON5SET (AVR32_USB_BASE+AVR32_USBB_UPCON5SET_OFFSET) +#define AVR32_USBB_UPCON6SET (AVR32_USB_BASE+AVR32_USBB_UPCON6SET_OFFSET) + +#define AVR32_USBB_UPCONCLR(n) (AVR32_USB_BASE+AVR32_USBB_UPCONCLR_OFFSET(n)) +#define AVR32_USBB_UPCON0CLR (AVR32_USB_BASE+AVR32_USBB_UPCON0CLR_OFFSET) +#define AVR32_USBB_UPCON1CLR (AVR32_USB_BASE+AVR32_USBB_UPCON1CLR_OFFSET) +#define AVR32_USBB_UPCON2CLR (AVR32_USB_BASE+AVR32_USBB_UPCON2CLR_OFFSET) +#define AVR32_USBB_UPCON3CLR (AVR32_USB_BASE+AVR32_USBB_UPCON3CLR_OFFSET) +#define AVR32_USBB_UPCON4CLR (AVR32_USB_BASE+AVR32_USBB_UPCON4CLR_OFFSET) +#define AVR32_USBB_UPCON5CLR (AVR32_USB_BASE+AVR32_USBB_UPCON5CLR_OFFSET) +#define AVR32_USBB_UPCON6CLR (AVR32_USB_BASE+AVR32_USBB_UPCON6CLR_OFFSET) + +#define AVR32_USBB_UPINRQ(n) (AVR32_USB_BASE+AVR32_USBB_UPINRQ_OFFSET(n)) +#define AVR32_USBB_UPINRQ0 (AVR32_USB_BASE+AVR32_USBB_UPINRQ0_OFFSET) +#define AVR32_USBB_UPINRQ1 (AVR32_USB_BASE+AVR32_USBB_UPINRQ1_OFFSET) +#define AVR32_USBB_UPINRQ2 (AVR32_USB_BASE+AVR32_USBB_UPINRQ2_OFFSET) +#define AVR32_USBB_UPINRQ3 (AVR32_USB_BASE+AVR32_USBB_UPINRQ3_OFFSET) +#define AVR32_USBB_UPINRQ4 (AVR32_USB_BASE+AVR32_USBB_UPINRQ4_OFFSET) +#define AVR32_USBB_UPINRQ5 (AVR32_USB_BASE+AVR32_USBB_UPINRQ5_OFFSET) +#define AVR32_USBB_UPINRQ6 (AVR32_USB_BASE+AVR32_USBB_UPINRQ6_OFFSET) + +#define AVR32_USBB_UPERR(n) (AVR32_USB_BASE+AVR32_USBB_UPERR_OFFSET(n)) +#define AVR32_USBB_UPERR0 (AVR32_USB_BASE+AVR32_USBB_UPERR0_OFFSET) +#define AVR32_USBB_UPERR1 (AVR32_USB_BASE+AVR32_USBB_UPERR1_OFFSET) +#define AVR32_USBB_UPERR2 (AVR32_USB_BASE+AVR32_USBB_UPERR2_OFFSET) +#define AVR32_USBB_UPERR3 (AVR32_USB_BASE+AVR32_USBB_UPERR3_OFFSET) +#define AVR32_USBB_UPERR4 (AVR32_USB_BASE+AVR32_USBB_UPERR4_OFFSET) +#define AVR32_USBB_UPERR5 (AVR32_USB_BASE+AVR32_USBB_UPERR5_OFFSET) +#define AVR32_USBB_UPERR6 (AVR32_USB_BASE+AVR32_USBB_UPERR6_OFFSET) + +#define AVR32_UHDMA_BASE(n) (AVR32_USB_BASE+AVR32_UHDMA_OFFSET(n)) +#define AVR32_UHDMA_NEXTDESC(n) (AVR32_UHDMA_BASE(n)+AVR32_UHDMA_NEXTDESC_OFFSET) +#define AVR32_UHDMA_ADDR(n) (AVR32_UHDMA_BASE(n)+AVR32_UHDMA_ADDR_OFFSET) +#define AVR32_UHDMA_CTRL(n) (AVR32_UHDMA_BASE(n)+AVR32_UHDMA_CTRL_OFFSET) +#define AVR32_UHDMA_STATUS(n) (AVR32_UHDMA_BASE(n)+AVR32_UHDMA_STATUS_OFFSET) + +#define AVR32_UHDMA1_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA1_NEXTDESC_OFFSET) +#define AVR32_UHDMA1_ADDR (AVR32_USB_BASE+AVR32_UHDMA1_ADDR_OFFSET) +#define AVR32_UHDMA1_CTRL (AVR32_USB_BASE+AVR32_UHDMA1_CTRL_OFFSET) +#define AVR32_UHDMA1_STATUS (AVR32_USB_BASE+AVR32_UHDMA1_STATUS_OFFSET) + +#define AVR32_UHDMA2_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA2_NEXTDESC_OFFSET) +#define AVR32_UHDMA2_ADDR (AVR32_USB_BASE+AVR32_UHDMA2_ADDR_OFFSET) +#define AVR32_UHDMA2_CTRL (AVR32_USB_BASE+AVR32_UHDMA2_CTRL_OFFSET) +#define AVR32_UHDMA2_STATUS (AVR32_USB_BASE+AVR32_UHDMA2_STATUS_OFFSET) + +#define AVR32_UHDMA3_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA3_NEXTDESC_OFFSET) +#define AVR32_UHDMA3_ADDR (AVR32_USB_BASE+AVR32_UHDMA3_ADDR_OFFSET) +#define AVR32_UHDMA3_CTRL (AVR32_USB_BASE+AVR32_UHDMA3_CTRL_OFFSET) +#define AVR32_UHDMA3_STATUS (AVR32_USB_BASE+AVR32_UHDMA3_STATUS_OFFSET) + +#define AVR32_UHDMA4_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA4_NEXTDESC_OFFSET) +#define AVR32_UHDMA4_ADDR (AVR32_USB_BASE+AVR32_UHDMA4_ADDR_OFFSET) +#define AVR32_UHDMA4_CTRL (AVR32_USB_BASE+AVR32_UHDMA4_CTRL_OFFSET) +#define AVR32_UHDMA4_STATUS (AVR32_USB_BASE+AVR32_UHDMA4_STATUS_OFFSET) + +#define AVR32_UHDMA5_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA5_NEXTDESC_OFFSET) +#define AVR32_UHDMA5_ADDR (AVR32_USB_BASE+AVR32_UHDMA5_ADDR_OFFSET) +#define AVR32_UHDMA5_CTRL (AVR32_USB_BASE+AVR32_UHDMA5_CTRL_OFFSET) +#define AVR32_UHDMA5_STATUS (AVR32_USB_BASE+AVR32_UHDMA5_STATUS_OFFSET) + +#define AVR32_UHDMA6_NEXTDESC (AVR32_USB_BASE+AVR32_UHDMA6_NEXTDESC_OFFSET) +#define AVR32_UHDMA6_ADDR (AVR32_USB_BASE+AVR32_UHDMA6_ADDR_OFFSET) +#define AVR32_UHDMA6_CTRL (AVR32_USB_BASE+AVR32_UHDMA6_CTRL_OFFSET) +#define AVR32_UHDMA6_STATUS (AVR32_USB_BASE+AVR32_UHDMA6_STATUS_OFFSET) + +/* USB General Registers */ + +#define AVR32_USBB_USBCON (AVR32_USB_BASE+AVR32_USBB_USBCON_OFFSET) +#define AVR32_USBB_USBSTA (AVR32_USB_BASE+AVR32_USBB_USBSTA_OFFSET) +#define AVR32_USBB_USBSTACLR (AVR32_USB_BASE+AVR32_USBB_USBSTACLR_OFFSET) +#define AVR32_USBB_USBSTASET (AVR32_USB_BASE+AVR32_USBB_USBSTASET_OFFSET) +#define AVR32_USBB_UVERS (AVR32_USB_BASE+AVR32_USBB_UVERS_OFFSET) +#define AVR32_USBB_UFEATURES (AVR32_USB_BASE+AVR32_USBB_UFEATURES_OFFSET) +#define AVR32_USBB_UADDRSIZE (AVR32_USB_BASE+AVR32_USBB_UADDRSIZE_OFFSET) +#define AVR32_USBB_UNAME1 (AVR32_USB_BASE+AVR32_USBB_UNAME1_OFFSET) +#define AVR32_USBB_UNAME2 (AVR32_USB_BASE+AVR32_USBB_UNAME2_OFFSET) +#define AVR32_USBB_USBFSM (AVR32_USB_BASE+AVR32_USBB_USBFSM_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ +/* USB Device Registers Bit-field Definitions ***************************************/ +/* Device General Control Register Bit-field Definitions */ + +#define USBB_UDCON_UADD_SHIFT (0) /* Bits 0-6: USB Address */ +#define USBB_UDCON_UADD_MASK (0x7f << USBB_UDCON_UADD_SHIFT) +#define USBB_UDCON_ADDEN: (1 << 7) /* Bit 7: Address Enable */ +#define USBB_UDCON_DETACH (1 << 8) /* Bit 8: Detach */ +#define USBB_UDCON_RMWKUP (1 << 9) /* Bit 9: Remote Wake-Up */ +#define USBB_UDCON_LS (1 << 12) /* Bit 12: Low-Speed Mode Force */ + +/* Device Global Interrupt Register Bit-field Definitions */ +/* Device Global Interrupt Clear Register Bit-field Definitions */ +/* Device Global Interrupt Set Register Bit-field Definitions */ +/* Device Global Interrupt Enable Register Bit-field Definitions */ +/* Device Global Interrupt Enable Clear Register Bit-field Definitions */ +/* Device Global Interrupt Enable Set Register Bit-field Definitions */ + +#define USBB_UDINT_SUSP (1 << 0) /* Bit 0: Suspend Interrupt */ +#define USBB_UDINT_SOF (1 << 2) /* Bit 2: Start of Frame Interrupt */ +#define USBB_UDINT_EORST (1 << 3) /* Bit 3: End of Reset Interrupt */ +#define USBB_UDINT_WAKEUP (1 << 4) /* Bit 4: Wake-Up Interrupt */ +#define USBB_UDINT_EORSM (1 << 5) /* Bit 5: End of Resume Interrupt */ +#define USBB_UDINT_UPRSM (1 << 6) /* Bit 6: Upstream Resume Interrupt */ +#define USBB_UDINT_EPINT(n) (1 << ((n)+12)) /* Endpoint n Interrupt */ +#define USBB_UDINT_EP0INT (1 << 12) /* Bit 12: Endpoint n Interrupt */ +#define USBB_UDINT_EP1INT (1 << 13) /* Bit 13: Endpoint n Interrupt */ +#define USBB_UDINT_EP2INT (1 << 14) /* Bit 14: Endpoint n Interrupt */ +#define USBB_UDINT_EP3INT (1 << 15) /* Bit 15: Endpoint n Interrupt */ +#define USBB_UDINT_EP4INT (1 << 16) /* Bit 16: Endpoint n Interrupt */ +#define USBB_UDINT_EP5INT (1 << 17) /* Bit 17: Endpoint n Interrupt */ +#define USBB_UDINT_EP6INT (1 << 18) /* Bit 18: Endpoint n Interrupt */ +#define USBB_UDINT_DMAINT(n) (1 << ((n)+24)) /* DMA Channel n Interrupt */ +#define USBB_UDINT_DMA1INT (1 << 25) /* Bit 25: DMA Channel n Interrupt */ +#define USBB_UDINT_DMA2INT (1 << 26) /* Bit 26: DMA Channel 1 Interrupt */ +#define USBB_UDINT_DMA3INT (1 << 27) /* Bit 27: DMA Channel 2 Interrupt */ +#define USBB_UDINT_DMA4INT (1 << 28) /* Bit 28: DMA Channel 3 Interrupt */ +#define USBB_UDINT_DMA5INT (1 << 29) /* Bit 29: DMA Channel 4 Interrupt */ +#define USBB_UDINT_DMA6INT (1 << 30) /* Bit 30: DMA Channel 5 Interrupt */ + +/* Endpoint Enable/Reset Register Bit-field Definitions */ + +#define USBB_UERST_EPRST(n) (1 << ((n)+16)) /* Endpoint n Reset */ +#define USBB_UERST_EPRST0 (1 << 16) /* Bit 16: Endpoint 0 Reset */ +#define USBB_UERST_EPRST1 (1 << 17) /* Bit 17: Endpoint 1 Reset */ +#define USBB_UERST_EPRST2 (1 << 18) /* Bit 18: Endpoint 2 Reset */ +#define USBB_UERST_EPRST3 (1 << 19) /* Bit 19: Endpoint 3 Reset */ +#define USBB_UERST_EPRST4 (1 << 20) /* Bit 20: Endpoint 4 Reset */ +#define USBB_UERST_EPRST5 (1 << 21) /* Bit 21: Endpoint 5 Reset */ +#define USBB_UERST_EPRST6 (1 << 22) /* Bit 22: Endpoint 6 Reset */ +#define USBB_UERST_EPEN(n) (1 << n) /* Endpoint n Enable */ +#define USBB_UERST_EPEN0 (1 << 0) /* Bit 0: Endpoint 0 Enable */ +#define USBB_UERST_EPEN1 (1 << 1) /* Bit 1: Endpoint 1 Enable */ +#define USBB_UERST_EPEN2 (1 << 2) /* Bit 2: Endpoint 2 Enable */ +#define USBB_UERST_EPEN3 (1 << 3) /* Bit 3: Endpoint 3 Enable */ +#define USBB_UERST_EPEN4 (1 << 4) /* Bit 4: Endpoint 4 Enable */ +#define USBB_UERST_EPEN5 (1 << 5) /* Bit 5: Endpoint 5 Enable */ +#define USBB_UERST_EPEN6 (1 << 6) /* Bit 5: Endpoint 6 Enable */ + +/* Device Frame Number Register Bit-field Definitions */ + +#define USBB_UDFNUM_FNUM_SHIFT (3) /* Bits 3-13: Frame Number */ +#define USBB_UDFNUM_FNUM_MASK (0x7ff << USBB_UDFNUM_FNUM_SHIFT) +#define USBB_UDFNUM_FNCERR (1 << 15) /* Bit 15: Frame Number CRC Error */ + +/* Endpoint Configuration Register Bit-field Definitions */ + +#define USBB_UECFG_ALLOC (1 << 1) /* Bit 1: Endpoint Memory Allocate */ +#define USBB_UECFG_EPBK_SHIFT (2) /* Bits 2-3: Endpoint Banks */ +#define USBB_UECFG_EPBK_MASK (3 << USBB_UECFG_EPBK_SHIFT) +# define USBB_UECFG_EPBK_1 (0 << USBB_UECFG_EPBK_SHIFT) /* 1 (single-bank endpoint) */ +# define USBB_UECFG_EPBK_2 (1 << USBB_UECFG_EPBK_SHIFT) /* 2 (double-bank endpoint) */ +# define USBB_UECFG_EPBK_3 (2 << USBB_UECFG_EPBK_SHIFT) /* 3 (triple-bank endpoint) */ +#define USBB_UECFG_EPSIZE_SHIFT (4) /* Bits 4-6: Endpoint Size */ +#define USBB_UECFG_EPSIZE_MASK (7 << USBB_UECFG_EPSIZE_SHIFT) +# define USBB_UECFG_EPSIZE_8 (0 << USBB_UECFG_EPSIZE_SHIFT) /* 8 bytes */ +# define USBB_UECFG_EPSIZE_16 (1 << USBB_UECFG_EPSIZE_SHIFT) /* 16 bytes */ +# define USBB_UECFG_EPSIZE_32 (2 << USBB_UECFG_EPSIZE_SHIFT) /* 32 bytes */ +# define USBB_UECFG_EPSIZE_64 (3 << USBB_UECFG_EPSIZE_SHIFT) /* 64 bytes */ +# define USBB_UECFG_EPSIZE_128 (4 << USBB_UECFG_EPSIZE_SHIFT) /* 128 bytes */ +# define USBB_UECFG_EPSIZE_256 (5 << USBB_UECFG_EPSIZE_SHIFT) /* 256 bytes */ +# define USBB_UECFG_EPSIZE_512 (6 << USBB_UECFG_EPSIZE_SHIFT) /* 512 bytes */ +# define USBB_UECFG_EPSIZE_1024 (7 << USBB_UECFG_EPSIZE_SHIFT) /* 1024 bytes */ +#define USBB_UECFG_EPDIR (1 << 8) /* Bit 8: Endpoint Direction */ +#define USBB_UECFG_AUTOSW (1 << 9) /* Bit 9: Automatic Switch */ +#define USBB_UECFG_EPTYPE_SHIFT (11) /* Bits 11-12: Endpoint Type */ +#define USBB_UECFG_EPTYPE_MASK (3 << USBB_UECFG_EPTYPE_SHIFT) +# define USBB_UECFG_EPTYPE_CTRL (0 << USBB_UECFG_EPTYPE_SHIFT) /* Control */ +# define USBB_UECFG_EPTYPE_ISOC (1 << USBB_UECFG_EPTYPE_SHIFT) /* Isochronous */ +# define USBB_UECFG_EPTYPE_BULK (2 << USBB_UECFG_EPTYPE_SHIFT) /* Bulk */ +# define USBB_UECFG_EPTYPE_INTR (3 << USBB_UECFG_EPTYPE_SHIFT) /* Interrupt */ + +/* Endpoint Status Register Bit-field Definitions (common fields) */ +/* Endpoint Status Clear Register Bit-field Definitions */ +/* Endpoint Status Set Register Bit-field Definitions (common fields) */ + +#define USBB_UESTA_TXINI (1 << 0) /* Bit 0: Transmitted IN Data Interrupt */ +#define USBB_UESTA_RXOUTI (1 << 1) /* Bit 1: Received OUT Data Interrupt */ +#define USBB_UESTA_UNDERFI (1 << 2) /* Bit 2: Underflow Interrupt */ +#define USBB_UESTA_RXSTPI (1 << 2) /* Bit 2: Received SETUP Interrupt */ +#define USBB_UESTA_NAKOUTI (1 << 3) /* Bit 3: NAKed OUT Interrupt */ +#define USBB_UESTA_NAKINI (1 << 4) /* Bit 4: NAKed IN Interrupt */ +#define USBB_UESTA_OVERFI (1 << 5) /* Bit 5: Overflow Interrupt */ +#define USBB_UESTA_STALLEDI (1 << 6) /* Bit 6: STALLed Interrupt */ +#define USBB_UESTA_CRCERRI (1 << 6) /* Bit 6: CRC Error Interrupt */ +#define USBB_UESTA_SHORTPACKET (1 << 7) /* Bit 7: Short Packet Interrupt */ + +/* Endpoint Status Register Bit-field Definitions (only in UESTA) */ + +#define USBB_UESTA_DTSEQ_SHIFT (8) /* Bits 8-9: Data Toggle Sequence */ +#define USBB_UESTA_DTSEQ_MASK (3 << USBB_UESTA_DTSEQ_SHIFT) +# define USBB_UESTA_DTSEQ_DATA0 (0 << USBB_UESTA_DTSEQ_SHIFT) /* Data0 */ +# define USBB_UESTA_DTSEQ_DATA1 (1 << USBB_UESTA_DTSEQ_SHIFT) /* Data1 */ +#define USBB_UESTA_NBUSYBK_SHIFT (12) /* Bits 12-13: Number of Busy Banks */ +#define USBB_UESTA_NBUSYBK_MASK (3 << USBB_UESTA_NBUSYBK_SHIFT) +# define USBB_UESTA_NBUSYBK_NONE (0 << USBB_UESTA_NBUSYBK_SHIFT) /* 0 (all banks free) */ +# define USBB_UESTA_NBUSYBK_1BANK (1 << USBB_UESTA_NBUSYBK_SHIFT) /* 1 */ +# define USBB_UESTA_NBUSYBK_2BANKS (2 << USBB_UESTA_NBUSYBK_SHIFT) /* 2 */ +# define USBB_UESTA_NBUSYBK_3BANKS (3 << USBB_UESTA_NBUSYBK_SHIFT) /* 3 */ +#define USBB_UESTA_CURRBK_SHIFT (14) /* Bits 14-15: Current Bank */ +#define USBB_UESTA_CURRBK_MASK (3 << USBB_UESTA_CURRBK_SHIFT) +# define USBB_UESTA_CURRBK_BANK0 (0 << USBB_UESTA_CURRBK_SHIFT) /* Bank0 */ +# define USBB_UESTA_CURRBK_BANK1 (1 << USBB_UESTA_CURRBK_SHIFT) /* Bank1 */ +# define USBB_UESTA_CURRBK_BANK2 (2 << USBB_UESTA_CURRBK_SHIFT) /* Bank2 */ +#define USBB_UESTA_RWALL (1 << 16) /* Bit 16: Read/Write Allowed */ +#define USBB_UESTA_CTRLDIR (1 << 17) /* Bit 17: Control Direction */ +#define USBB_UESTA_CFGOK (1 << 18) /* Bit 18: Configuration OK Status */ +#define USBB_UESTA_BYCT_SHIFT (20) /* Bits 20-30: Byte Count */ +#define USBB_UESTA_BYCT_MASK (0x7ff << USBB_UESTA_BYCT_SHIFT) + +/* Endpoint Status Set Register Bit-field Definitions (only in UESTASET) */ + +#define USBB_UESTASET_NBUSYBKS (1 << 12) /* Bit 12 */ + +/* Endpoint Control Register Bit-field Definitions */ +/* Endpoint Control Set Register Bit-field Definitions */ +/* Endpoint Control Clear Register Bit-field Definitions */ + +#define USBB_UECON_TXINE (1 << 0) /* Bit 0: Transmitted IN Data Interrupt Enable */ +#define USBB_UECON_RXOUTE (1 << 1) /* Bit 1: Received OUT Data Interrupt Enable */ +#define USBB_UECON_RXSTPE (1 << 2) /* Bit 2: Received SETUP Interrupt Enable */ +#define USBB_UECON_UNDERFE (1 << 2) /* Bit 2: Underflow Interrupt Enable */ +#define USBB_UECON_NAKOUTE (1 << 3) /* Bit 3: NAKed OUT Interrupt Enable */ +#define USBB_UECON_NAKINE (1 << 4) /* Bit 4: NAKed IN Interrupt Enable */ +#define USBB_UECON_OVERFE (1 << 5) /* Bit 5: Overflow Interrupt Enable */ +#define USBB_UECON_STALLEDE (1 << 6) /* Bit 6: STALLed Interrupt Enable */ +#define USBB_UECON_CRCERRE (1 << 6) /* Bit 6: CRC Error Interrupt Enable */ +#define USBB_UECON_SHORTPACKETE (1 << 7) /* Bit 7: Short Packet Interrupt Enable */ +#define USBB_UECON_NBUSYBKE (1 << 12) /* Bit 12: Number of Busy Banks Interrupt Enable */ +#define USBB_UECON_KILLBK (1 << 13) /* Bit 13: Kill IN Bank (SET only) */ +#define USBB_UECON_FIFOCON (1 << 14) /* Bit 14: FIFO Control (CLR only) */ +#define USBB_UECON_EPDISHDMA (1 << 16) /* Bit 16: Endpoint Interrupts Disable HDMA Request Enable */ +#define USBB_UECON_RSTDT (1 << 18) /* Bit 18: Reset Data Toggle (SET only) */ +#define USBB_UECON_STALLRQ (1 << 19) /* Bit 19: STALL Request */ + +/* Device DMA Channel Next Descriptor Address Register Bit-field Definitions */ + +#define UDDMA_NEXTDESC_MASK (0xfffffff0) + +/* Device DMA Channel HSB Address Register Bit-field Definitions */ +/* This register holds a 32-bit address with internal bit fields */ + +/* Device DMA Channel Control Register Bit-field Definitions */ + +#define UDDMA_CTRL_CHEN (1 << 0) /* Bit 0: Channel Enable */ +#define UDDMA_CTRL_LDNXTCHDESCEN (1 << 1) /* Bit 1: Load Next Channel Descriptor Enable */ +#define UDDMA_CTRL_BUFFCLOSEINEN (1 << 2) /* Bit 2: Buffer Close Input Enable */ +#define UDDMA_CTRL_DMAENDEN (1 << 3) /* Bit 3: End of DMA Buffer Output Enable */ +#define UDDMA_CTRL_EOTIRQEN (1 << 4) /* Bit 4: End of USB Transfer Interrupt Enable */ +#define UDDMA_CTRL_EOBUFFIRQEN (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define UDDMA_CTRL_DESCLDIRQEN (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enable */ +#define UDDMA_CTRL_BURSTLOCKEN (1 << 7) /* Bit 7: Burst Lock Enable */ +#define UDDMA_CTRL_CHBYTELENGTH_SHIFT (16) /* Bits 16-31: Channel Byte Length */ +#define UDDMA_CTRL_CHBYTELENGTH_MASK (0xffff << UDDMA_CTRL_CHBYTELENGTH_SHIFT) + +/* Device DMA Channel Status Register Bit-field Definitions */ + +#define UDDMA_STATUS_CHEN (1 << 0) /* Bit 0: Channel Enabled */ +#define UDDMA_STATUS_CHACTIVE (1 << 1) /* Bit 1: Channel Active */ +#define UDDMA_STATUS_EOTSTA (1 << 4) /* Bit 4: End of USB Transfer Status */ +#define UDDMA_STATUS_EOCHBUFFSTA (1 << 5) /* Bit 5: End of Channel Buffer Status */ +#define UDDMA_STATUS_DESCLDSTA (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define UDDMA_STATUS_CHBYTECNT_SHIFT (16) /* Bits 16-31: Channel Byte Count */ +#define UDDMA_STATUS_CHBYTECNT_MASK (0xffff << UDDMA_STATUS_CHBYTECNT_SHIFT) + +/* USB Host Registers Bit-field Definitions *********************************/ + +/* Host General Control Register Bit-field Definitions */ + +#define USBB_UHCON_SOFE (1 << 8) /* Bit 8: Start of Frame Generation Enable */ +#define USBB_UHCON_RESET (1 << 9) /* Bit 9: Send USB Reset */ +#define USBB_UHCON_RESUME (1 << 10) /* Bit 10: Send USB Resume */ + +/* Host Global Interrupt Register Bit-field Definitions */ +/* Host Global Interrupt Clear Register Bit-field Definitions (Except as noted 1) */ +/* Host Global Interrupt Set Register Bit-field Definitions (Except as noted 2) */ +/* Host Global Interrupt Enable Register Bit-field Definitions */ +/* Host Global Interrupt Enable Clear Register Bit-field Definitions */ +/* Host Global Interrupt Enable Set Register Bit-field Definitions */ + +#define USBB_UHINT_DCONNI (1 << 0) /* Bit 0: Device Connection Interrupt (1) */ +#define USBB_UHINT_DDISCI (1 << 1) /* Bit 1: Device Disconnection Interrupt (1) */ +#define USBB_UHINT_RSTI (1 << 2) /* Bit 2: USB Reset Sent Interrupt (1) */ +#define USBB_UHINT_RSMEDI (1 << 3) /* Bit 3: Downstream Resume Sent Interrupt (1) */ +#define USBB_UHINT_RXRSMI (1 << 4) /* Bit 4: Upstream Resume Received Interrupt (1) */ +#define USBB_UHINT_HSOFI (1 << 5) /* Bit 5: Host Start of Frame Interrupt (1) */ +#define USBB_UHINT_HWUPI (1 << 6) /* Bit 6: Host Wake-Up Interrupt (1) */ +#define USBB_UHINT_PINT(n) (1 << ((n)+8)) +#define USBB_UHINT_P0INT (1 << 8) /* Bit 8: Pipe 0 Interrupt (1,2) */ +#define USBB_UHINT_P1INT (1 << 9) /* Bit 9: Pipe 1 Interrupt (1,2) */ +#define USBB_UHINT_P2INT (1 << 10) /* Bit 10: Pipe 2 Interrupt (1,2) */ +#define USBB_UHINT_P3INT (1 << 11) /* Bit 11: Pipe 3 Interrupt (1,2) */ +#define USBB_UHINT_P4INT (1 << 12) /* Bit 12: Pipe 4 Interrupt (1,2) */ +#define USBB_UHINT_P5INT (1 << 13) /* Bit 13: Pipe 5 Interrupt (1,2) */ +#define USBB_UHINT_P6INT (1 << 14) /* Bit 14: Pipe 6 Interrupt (1,2) */ +#define USBB_UHINT_DMAINT(n) (1 << ((n)+24)) +#define USBB_UHINT_DMAINT1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt */ +#define USBB_UHINT_DMAINT2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt */ +#define USBB_UHINT_DMAINT3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt */ +#define USBB_UHINT_DMAINT4 (1 << 28) /* Bit 28: DMA Channel 4 Interrupt */ +#define USBB_UHINT_DMAINT5 (1 << 29) /* Bit 29: DMA Channel 5 Interrupt */ +#define USBB_UHINT_DMAINT6 (1 << 30) /* Bit 30: DMA Channel 6 Interrupt */ + +/* Pipe Enable/Reset Register Bit-field Definitions */ + +#define USBB_UPRST_PEN(n) (1 << (n)) +#define USBB_UPRST_PEN0 (1 << 0) /* Bit 0: Pipe 0 Enable */ +#define USBB_UPRST_PEN1 (1 << 1) /* Bit 1: Pipe 1 Enable */ +#define USBB_UPRST_PEN2 (1 << 2) /* Bit 2: Pipe 2 Enable */ +#define USBB_UPRST_PEN3 (1 << 3) /* Bit 3: Pipe 3 Enable */ +#define USBB_UPRST_PEN4 (1 << 4) /* Bit 4: Pipe 4 Enable */ +#define USBB_UPRST_PEN5 (1 << 5) /* Bit 5: Pipe 5 Enable */ +#define USBB_UPRST_PEN6 (1 << 6) /* Bit 6: Pipe 6 Enable */ +#define USBB_UPRST_PRST(n) (1 << ((n)+16)) +#define USBB_UPRST_PRST0 (1 << 16) /* Bit 16: Pipe 0 Reset */ +#define USBB_UPRST_PRST1 (1 << 17) /* Bit 17: Pipe 1 Reset */ +#define USBB_UPRST_PRST2 (1 << 18) /* Bit 18: Pipe 2 Reset */ +#define USBB_UPRST_PRST3 (1 << 19) /* Bit 19: Pipe 3 Reset */ +#define USBB_UPRST_PRST4 (1 << 20) /* Bit 20: Pipe 4 Reset */ +#define USBB_UPRST_PRST5 (1 << 21) /* Bit 21: Pipe 5 Reset */ +#define USBB_UPRST_PRST6 (1 << 22) /* Bit 22: Pipe 6 Reset */ + +/* Host Frame Number Register Bit-field Definitions */ + +#define USBB_UHFNUM_FNUM_SHIFT (3) /* Bits 3-13: Frame Number */ +#define USBB_UHFNUM_FNUM_MASK (0x7ff << USBB_UHFNUM_FNUM_SHIFT) +#define USBB_UHFNUM_FLENHIGH_SHIFT (16) /* Bits 16-23: Frame Length */ +#define USBB_UHFNUM_FLENHIGH_MASK (0xff << USBB_UHFNUM_FLENHIGH_SHIFT) + +/* Host Address 1 Register Bit-field Definitions */ + +#define USBB_UHADDR1_UHADDRP0_SHIFT (0) /* Bits 0-6: USB Host Address (Pipe 0) */ +#define USBB_UHADDR1_UHADDRP0_MASK (0x7f << USBB_UHADDR1_UHADDRP0_SHIFT) +#define USBB_UHADDR1_UHADDRP1_SHIFT (8) /* Bits 8-14: USB Host Address (Pipe 1) */ +#define USBB_UHADDR1_UHADDRP1_MASK (0x7f << USBB_UHADDR1_UHADDRP1_SHIFT) +#define USBB_UHADDR1_UHADDRP2_SHIFT (16) /* Bits 16-22: USB Host Address (Pipe 2) */ +#define USBB_UHADDR1_UHADDRP2_MASK (0x7f << USBB_UHADDR1_UHADDRP2_SHIFT) +#define USBB_UHADDR1_UHADDRP3_SHIFT (24) /* Bits 24-30: USB Host Address (Pipe 3) */ +#define USBB_UHADDR1_UHADDRP3_MASK (0x7f << USBB_UHADDR1_UHADDRP3_SHIFT) + +/* Host Address 2 Register Bit-field Definitions */ + +#define USBB_UHADDR2_UHADDRP4_SHIFT (0) /* Bits 0-6: USB Host Address (Pipe 4) */ +#define USBB_UHADDR2_UHADDRP4_MASK (0x7f << USBB_UHADDR1_UHADDRP4_SHIFT) +#define USBB_UHADDR2_UHADDRP5_SHIFT (8) /* Bits 8-14: USB Host Address (Pipe 5) */ +#define USBB_UHADDR2_UHADDRP5_MASK (0x7f << USBB_UHADDR1_UHADDRP5_SHIFT) +#define USBB_UHADDR2_UHADDRP6_SHIFT (16) /* Bits 16-22: USB Host Address (Pipe 6) */ +#define USBB_UHADDR2_UHADDRP6_MASK (0x7f << USBB_UHADDR1_UHADDRP6_SHIFT) +# +/* Pipe Configuration Register Bit-field Definitions */ + +#define USBB_UPCFG_ALLOC (1 << 1) /* Bit 1: Pipe Memory Allocate */ +#define USBB_UPCFG_PBK_SHIFT (2) /* Bits 2-3: Pipe Banks */ +#define USBB_UPCFG_PBK_MASK (3 << USBB_UPCFG_PBK_SHIFT) +# define USBB_UPCFG_PBK_1 (0 << USBB_UPCFG_PBK_SHIFT) /* 1 (single-bank pipe) */ +# define USBB_UPCFG_PBK_2 (1 << USBB_UPCFG_PBK_SHIFT) /* 2 (double-bank pipe) */ +# define USBB_UPCFG_PBK_3 (2 << USBB_UPCFG_PBK_SHIFT) /* 3 (triple-bank pipe) */ +#define USBB_UPCFG_PSIZE_SHIFT (4) /* Bits 4-6: Pipe Size */ +#define USBB_UPCFG_PSIZE_MASK (7 << USBB_UPCFG_PSIZE_SHIFT) +# define USBB_UPCFG_PSIZE_8 (0 << USBB_UPCFG_PSIZE_SHIFT) /* 8 bytes */ +# define USBB_UPCFG_PSIZE_16 (1 << USBB_UPCFG_PSIZE_SHIFT) /* 16 bytes */ +# define USBB_UPCFG_PSIZE_32 (2 << USBB_UPCFG_PSIZE_SHIFT) /* 32 bytes */ +# define USBB_UPCFG_PSIZE_64 (3 << USBB_UPCFG_PSIZE_SHIFT) /* 64 bytes */ +# define USBB_UPCFG_PSIZE_128 (4 << USBB_UPCFG_PSIZE_SHIFT) /* 128 bytes */ +# define USBB_UPCFG_PSIZE_256 (5 << USBB_UPCFG_PSIZE_SHIFT) /* 256 bytes */ +# define USBB_UPCFG_PSIZE_512 (6 << USBB_UPCFG_PSIZE_SHIFT) /* 512 bytes */ +# define USBB_UPCFG_PSIZE_1024 (7 << USBB_UPCFG_PSIZE_SHIFT) /* 1024 bytes */ +#define USBB_UPCFG_PTOKEN_SHIFT (8) /* Bits 8-9: Pipe Token */ +#define USBB_UPCFG_PTOKEN_MASK (3 << USBB_UPCFG_PTOKEN_SHIFT) +# define USBB_UPCFG_PTOKEN_SETUP (0 << USBB_UPCFG_PTOKEN_SHIFT) /* SETUP */ +# define USBB_UPCFG_PTOKEN_IN (1 << USBB_UPCFG_PTOKEN_SHIFT) /* IN */ +# define USBB_UPCFG_PTOKEN_OUT (2 << USBB_UPCFG_PTOKEN_SHIFT) /* OUT */ +#define USBB_UPCFG_AUTOSW (1 << 10) /* Bit 10: Automatic Switch */ +#define USBB_UPCFG_PTYPE_SHIFT (11) /* Bits 11-12: Pipe Type */ +#define USBB_UPCFG_PTYPE_MASK (3 << USBB_UPCFG_PTYPE_SHIFT) +# define USBB_UPCFG_PTYPE_CTRL (0 << USBB_UPCFG_PTYPE_SHIFT) /* Control */ +# define USBB_UPCFG_PTYPE_ISOC (1 << USBB_UPCFG_PTYPE_SHIFT) /* Isochronous */ +# define USBB_UPCFG_PTYPE_BULK (2 << USBB_UPCFG_PTYPE_SHIFT) /* Bulk */ +# define USBB_UPCFG_PTYPE_INTR (3 << USBB_UPCFG_PTYPE_SHIFT) /* Interrupt */ +#define USBB_UPCFG_PEPNUM_SHIFT (16) /* Bits 16-19: Pipe Endpoint Number */ +#define USBB_UPCFG_PEPNUM_MASK (15 << USBB_UPCFG_PEPNUM_SHIFT) +#define USBB_UPCFG_INTFRQ_SHIFT (24) /* Bits 24-31: Pipe Interrupt Request Frequency */ +#define USBB_UPCFG_INTFRQ_MASK (0xff << USBB_UPCFG_INTFRQ_SHIFT) + +/* Pipe Status Register Bit-field Definitions (common) */ +/* Pipe Status Clear Register Bit-field Definitions (common) */ +/* Pipe Status Set Register Bit-field Definitions (common) */ + +#define USBB_UPSTA_RXINI (1 << 0) /* Bit 0: Received IN Data Interrupt */ +#define USBB_UPSTA_TXOUTI (1 << 1) /* Bit 1: Transmitted OUT Data Interrupt */ +#define USBB_UPSTA_TXSTPI (1 << 2) /* Bit 2: Transmitted SETUP Interrupt */ +#define USBB_UPSTA_UNDERFI (1 << 2) /* Bit 2: Underflow Interrupt */ +#define USBB_UPSTA_PERRI (1 << 3) /* Bit 3: Pipe Error Interrupt */ +#define USBB_UPSTA_NAKEDI (1 << 4) /* Bit 4: NAKed Interrupt */ +#define USBB_UPSTA_OVERFI (1 << 5) /* Bit 5: Overflow Interrupt */ +#define USBB_UPSTA_RXSTALLDI (1 << 6) /* Bit 6: Received STALLed Interrupt */ +#define USBB_UPSTA_CRCERRI (1 << 6) /* Bit 6: CRC Error Interrupt */ +#define USBB_UPSTA_SHORTPACKET (1 << 7) /* Bit 7: Short Packet Interrupt */ + +/* Pipe Status Register Bit-field Definitions (only in UPSTA) */ + +#define USBB_UPSTA_DTSEQ_SHIFT (8) /* Bits 8-9: Data Toggle Sequence */ +#define USBB_UPSTA_DTSEQ_MASK (3 << USBB_UPSTA_DTSEQ_SHIFT) +# define USBB_UPSTA_DTSEQ_DATA0 (0 << USBB_UPSTA_DTSEQ_SHIFT) /* Data0 */ +# define USBB_UPSTA_DTSEQ_DATA1 (1 << USBB_UPSTA_DTSEQ_SHIFT) /* Data1 */ +#define USBB_UPSTA_NBUSYBK_SHIFT (12) /* Bits 12-13: Number of Busy Banks */ +#define USBB_UPSTA_NBUSYBK_MASK (3 << USBB_UPSTA_NBUSYBK_SHIFT) +# define USBB_UPSTA_NBUSYBK_NONE (0 << USBB_UPSTA_NBUSYBK_SHIFT) /* 0 (all banks free) */ +# define USBB_UPSTA_NBUSYBK_1BANK (1 << USBB_UPSTA_NBUSYBK_SHIFT) /* 1 */ +# define USBB_UPSTA_NBUSYBK_2BANKS (2 << USBB_UPSTA_NBUSYBK_SHIFT) /* 2 */ +#define USBB_UPSTA_CURRBK_SHIFT (14) /* Bits 14-15: Current Bank */ +#define USBB_UPSTA_CURRBK_MASK (3 << USBB_UPSTA_CURRBK_SHIFT) +# define USBB_UPSTA_CURRBK_BANK0 (0 << USBB_UPSTA_CURRBK_SHIFT) /* Bank0 */ +# define USBB_UPSTA_CURRBK_BANK1 (1 << USBB_UPSTA_CURRBK_SHIFT) /* Bank1 */ +# define USBB_UPSTA_CURRBK_BANK2 (2 << USBB_UPSTA_CURRBK_SHIFT) /* Bank2 */ +#define USBB_UPSTA_RWALL (1 << 16) /* Bit 16: Read/Write Allowed */ +#define USBB_UPSTA_CFGOK (1 << 18) /* Bit 18: Configuration OK Status */ +#define USBB_UPSTA_PBYCT_SHIFT (20) /* Bits 20-30: Pipe Byte Count */ +#define USBB_UPSTA_PBYCT_MASK (0x7ff << USBB_UPSTA_BYCT_SHIFT) + +/* Pipe Status Set Register Bit-field Definitions (only in UPSTASET) */ + +#define USBB_UPSTASET_NBUSYBKS (1 << 12) /* Bit 12 */ + +/* Pipe Control Register Bit-field Definitions */ +/* Pipe Control Clear Register Bit-field Definitions (except as noted 1) */ +/* Pipe Control Set Register Bit-field Definitions (except as noted 2) */ + +#define USBB_UPCON_RXINE (1 << 0) /* Bit 0: Received IN Data Interrupt Enable */ +#define USBB_UPCON_TXOUTE (1 << 1) /* Bit 1: Transmitted OUT Data Interrupt Enable */ +#define USBB_UPCON_TXSTPE (1 << 2) /* Bit 2: Transmitted SETUP Interrupt Enable */ +#define USBB_UPCON_UNDERFIE (1 << 2) /* Bit 2: Underflow Interrupt Enable */ +#define USBB_UPCON_PERRE (1 << 3) /* Bit 3: Pipe Error Interrupt Enable */ +#define USBB_UPCON_NAKEDE (1 << 4) /* Bit 4: NAKed Interrupt Enable */ +#define USBB_UPCON_OVERFIE (1 << 5) /* Bit 5: Overflow Interrupt Enable */ +#define USBB_UPCON_RXSTALLDE (1 << 6) /* Bit 6: Received STALLed Interrupt Enable */ +#define USBB_UPCON_CRCERRE (1 << 6) /* Bit 6: CRC Error Interrupt Enable */ +#define USBB_UPCON_SHORTPACKETIE (1 << 7) /* Bit 7: Short Packet Interrupt Enable */ +#define USBB_UPCON_NBUSYBKE (1 << 12) /* Bit 12: Number of Busy Banks Interrupt Enable */ +#define USBB_UPCON_FIFOCON (1 << 14) /* Bit 14: FIFO Control (2) */ +#define USBB_UPCON_PDISHDMA (1 << 16) /* Bit 16: Pipe Interrupts Disable HDMA Request Enable */ +#define USBB_UPCON_PFREEZE (1 << 17) /* Bit 17: Pipe Freeze */ +#define USBB_UPCON_RSTDT (1 << 18) /* Bit 18: Reset Data Toggle (1) */ + +/* Pipe IN Request Register Bit-field Definitions */ + +#define USBB_UPINRQ_INRQ_SHIFT (0) /* Bits 0-7: IN Request Number before Freeze */ +#define USBB_UPINRQ_INRQ_MASK (0xff << USBB_UPINRQ_INRQ_SHIFT) +#define USBB_UPINRQ_INMODE (1 << 8) /* Bit 8: IN Request Mode */ + +/* Pipe Error Register Bit-field Definitions */ + +#define USBB_UPERR_DATATGL (1 << 0) /* Bit 0: Data Toggle Error */ +#define USBB_UPERR_DATAPID (1 << 1) /* Bit 1: Data PID Error */ +#define USBB_UPERR_PID (1 << 2) /* Bit 2: PID Error */ +#define USBB_UPERR_TIMEOUT (1 << 3) /* Bit 3: Time-Out Error */ +#define USBB_UPERR_CRC16 (1 << 4) /* Bit 4: CRC16 Error */ +#define USBB_UPERR_COUNTER_SHIFT (5) /* Bits 5-6: Error Counter */ +#define USBB_UPERR_COUNTER_MASK (3 << USBB_UPERR_COUNTER_SHIFT) + +/* Host DMA Channel Next Descriptor Address Register Bit-field Definitions */ + +#define UHDMA_NEXTDESC_MASK (0xfffffff0) + +/* Host DMA Channel HSB Address Register Bit-field Definitions */ +/* This register holds a 32-bit address with internal bit fields */ + +/* Host DMA Channel Control Register Bit-field Definitions */ + +#define UHDMA_CTRL_CHEN (1 << 0) /* Bit 0: Channel Enable */ +#define UHDMA_CTRL_LDNXTCHDESCEN (1 << 1) /* Bit 1: Load Next Channel Descriptor Enable */ +#define UHDMA_CTRL_BUFFCLOSEINEN (1 << 2) /* Bit 2: Buffer Close Input Enable */ +#define UHDMA_CTRL_DMAENDEN (1 << 3) /* Bit 3: End of DMA Buffer Output Enable */ +#define UHDMA_CTRL_EOTIRQEN (1 << 4) /* Bit 4: End of USB Transfer Interrupt Enable */ +#define UHDMA_CTRL_EOBUFFIRQEN (1 << 5) /* Bit 5: End of Buffer Interrupt Enable */ +#define UHDMA_CTRL_DESCLDIRQEN (1 << 6) /* Bit 6: Descriptor Loaded Interrupt Enable */ +#define UHDMA_CTRL_BURSTLOCKEN (1 << 7) /* Bit 7: Burst Lock Enable */ +#define UHDMA_CTRL_CHBYTELENGTH_SHIFT (16) /* Bits 16-31: Channel Byte Length */ +#define UHDMA_CTRL_CHBYTELENGTH_MASK (0xffff << UHDMA_CTRL_CHBYTELENGTH_SHIFT) + +/* Host DMA Channel Status Register Bit-field Definitions */ + +#define UHDMA_STATUS_CHEN (1 << 0) /* Bit 0: Channel Enabled */ +#define UHDMA_STATUS_CHACTIVE (1 << 1) /* Bit 1: Channel Active */ +#define UHDMA_STATUS_EOTSTA (1 << 4) /* Bit 4: End of USB Transfer Status */ +#define UHDMA_STATUS_EOCHBUFFSTA (1 << 5) /* Bit 5: End of Channel Buffer Status */ +#define UHDMA_STATUS_DESCLDSTA (1 << 6) /* Bit 6: Descriptor Loaded Status */ +#define UHDMA_STATUS_CHBYTECNT_SHIFT (16) /* Bits 16-31: Channel Byte Count */ +#define UHDMA_STATUS_CHBYTECNT_MASK (0xffff << UHDMA_STATUS_CHBYTECNT_SHIFT) + +/* USB General Registers Bit-field Definitions ******************************/ + +/* General Control Register Bit-field Definitions */ + +#define USBB_USBCON_IDTE (1 << 0) /* Bit 0: ID Transition Interrupt Enable */ +#define USBB_USBCON_VBUSTE (1 << 1) /* Bit 1: VBus Transition Interrupt Enable */ +#define USBB_USBCON_VBERRE (1 << 3) /* Bit 3: VBus Error Interrupt Enable */ +#define USBB_USBCON_BCERRE (1 << 4) /* Bit 4: B-Connection Error Interrupt Enable */ +#define USBB_USBCON_ROLEEXE (1 << 5) /* Bit 5: Role Exchange Interrupt Enable */ +#define USBB_USBCON_STOE (1 << 7) /* Bit 7: Suspend Time-Out Interrupt Enable */ +#define USBB_USBCON_VBUSHWC (1 << 8) /* Bit 8: VBus Hardware Control */ +#define USBB_USBCON_OTGPADE (1 << 12) /* Bit 12: OTG Pad Enable */ +#define USBB_USBCON_VBUSPO (1 << 13) /* Bit 13: VBus Polarity */ +#define USBB_USBCON_FRZCLK (1 << 14) /* Bit 14: Freeze USB Clock */ +#define USBB_USBCON_USBE (1 << 15) /* Bit 15: USBB Enable */ +#define USBB_USBCON_TIMVALUE_SHIFT (16) /* Bits 16-17: Timmer Value */ +#define USBB_USBCON_TIMVALUE_MASK (3 << USBB_USBCON_TIMVALUE_SHIFT) +#define USBB_USBCON_TIMPAGE_SHIFT (20) /* Bits 20-21: Timer Page */ +#define USBB_USBCON_TIMPAGE_MASK (3 << USBB_USBCON_TIMPAGE_SHIFT) +#define USBB_USBCON_UNLOCK (1 << 22) /* Bit 22: Timer Access Unlock */ +#define USBB_USBCON_UIDE (1 << 24) /* Bit 24: USB_ID Pin Enable */ +#define USBB_USBCON_UIMOD (1 << 25) /* Bit 25: USBB Mode */ + +/* General Status Register Bit-field Definitions */ +/* General Status Clear Register Bit-field Definitions */ +/* General Status Set Register Bit-field Definitions */ + +#define USBB_USBSTA_IDTI (1 << 0) /* Bit 0: ID Transition Interrupt */ +#define USBB_USBSTA_VBUSTI (1 << 1) /* Bit 1: VBus Transition Interrupt */ +#define USBB_USBSTA_VBERRI (1 << 3) /* Bit 3: VBus Error Interrupt */ +#define USBB_USBSTA_BCERRI (1 << 4) /* Bit 4: B-Connection Error Interrupt */ +#define USBB_USBSTA_ROLEEXI (1 << 5) /* Bit 5: Role Exchange Interrupt */ +#define USBB_USBSTA_STOI (1 << 7) /* Bit 7: Suspend Time-Out Interrupt */ +#define USBB_USBSTA_VBUSRQ (1 << 9) /* Bit 8: VBus Request */ +#define USBB_USBSTA_ID (1 << 10) /* Bit 10: USB_ID Pin State (read-only) */ +#define USBB_USBSTA_VBUS (1 << 11) /* Bit 11: VBus Level (read-only) */ +#define USBB_USBSTA_SPEED_SHIFT (12) /* Bits 12-13: Speed Status (read-only) */ +#define USBB_USBSTA_SPEED_MASK (3 << USBB_USBSTA_SPEED_SHIFT) +# define USBB_USBSTA_SPEED_FULL (0 << USBB_USBSTA_SPEED_SHIFT) /* Full-Speed mode */ +# define USBB_USBSTA_SPEED_LOW (2 << USBB_USBSTA_SPEED_SHIFT) /* Low-Speed mode */ + +/* IP Version Register Bit-field Definitions */ + +#define USBB_UVERS_SHIFT (0) /* Bits 0-11: Version Number */ +#define USBB_UVERS_MASK (0xfff << USBB_UVERS_SHIFT) +#define USBB_UVERS_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */ +#define USBB_UVERS_VARIANT_MASK (15 << USBB_UVERS_VARIANT_SHIFT) + +/* IP Features Register Bit-field Definitions */ + +#define USBB_UFEAT_EPTNBRMAX_SHIFT (0) /* Bits 0-3: Maximal Number of Pipes/Endpoints */ +#define USBB_UFEAT_EPTNBRMAX_MASK (15 << USBB_UFEAT_EPTNBRMAX_SHIFT) +# define USBB_UFEAT_EPTNBRMAX_16 (0 << USBB_UFEAT_EPTNBRMAX_SHIFT) /* 16 is a special case */ +#define USBB_UFEAT_DMACHANNBR_SHIFT (4) /* Bits 4-6: Number of DMA Channels */ +#define USBB_UFEAT_DMACHANNBR_MASK (7 << USBB_UFEAT_DMACHANNBR_SHIFT) +#define USBB_UFEAT_DMABUFFERSZ (1 << 7) /* Bit 7: DMA Buffer Size */ +#define USBB_UFEAT_DMAWDDEPTH_SHIFT (8) /* Bits 8-11: DMA FIFO Depth in Words */ +#define USBB_UFEAT_DMAWDDEPTH_MASK (15 << USBB_UFEAT_DMAWDDEPTH_SHIFT) +# define USBB_UFEAT_DMAWDDEPTH_16 (0 << USBB_UFEAT_DMAWDDEPTH_SHIFT) /* 16 is a special case */ +#define USBB_UFEAT_FIFOMAXSZ_SHIFT (12) /* Bits 12-14: Maximal FIFO Size */ +#define USBB_UFEAT_FIFOMAXSZ_MASK (7 << USBB_UFEAT_FIFOMAXSZ_SHIFT) +# define USBB_UFEAT_FIFOMAXSZ_LT256 (0 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 256 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT512 (1 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 512 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT1K (2 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 1024 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT2K (3 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 2048 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT4K (4 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 4096 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT8K (5 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 8192 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_LT16K (6 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* < 16384 bytes */ +# define USBB_UFEAT_FIFOMAXSZ_GE16K (7 << USBB_UFEAT_FIFOMAXSZ_SHIFT) /* >= 16384 bytes */ +#define USBB_UFEAT_BWRDPRAM (1 << 15) /* Bit 15: DPRAM Byte-Write Capability */ + +/* IP PB Address Size Register Bit-field Definitions */ +/* IP Name Register 1 Bit-field Definitions */ +/* IP Name Register 2 Bit-field Definitions */ + +/* These registers contain a 32-value and, hence, have no bit fields */ + +/* USB Finite State Machine Status Register Bit-field Definitions */ + +#define USBB_USBFSM_MASK (15) +# define USBB_USBFSM_A_IDLESTATE (0) +# define USBB_USBFSM_A_WAITVRISE (1) +# define USBB_USBFSM_A_WAITBCON (2) +# define USBB_USBFSM_A_HOST (3) +# define USBB_USBFSM_A_SUSPEND (4) +# define USBB_USBFSM_A_PERIPHERAL (5) +# define USBB_USBFSM_A_WAITVFALL (6) +# define USBB_USBFSM_A_VBUSERR (7) +# define USBB_USBFSM_A_WAITDISCHARGE (8) +# define USBB_USBFSM_B_IDLE (9) +# define USBB_USBFSM_B_PERIPHERAL (10) +# define USBB_USBFSM_B_WAITBEGINHNP (11) +# define USBB_USBFSM_B_WAITDISCHARGE (12) +# define USBB_USBFSM_B_WAITACON (13) +# define USBB_USBFSM_B_HOST (14) +# define USBB_USBFSM_B_SRPINIT (15) + +/* USB HSB Memory Map ***************************************************************/ + +#define USB_FIFO0_DATA_OFFSET 0x00000 /* Pipe/Endpoint 0 FIFO Data Register */ +#define USB_FIFO1_DATA_OFFSET 0x10000 /* Pipe/Endpoint 1 FIFO Data Register */ +#define USB_FIFO2_DATA_OFFSET 0x20000 /* Pipe/Endpoint 2 FIFO Data Register */ +#define USB_FIFO3_DATA_OFFSET 0x30000 /* Pipe/Endpoint 3 FIFO Data Register */ +#define USB_FIFO4_DATA_OFFSET 0x40000 /* Pipe/Endpoint 4 FIFO Data Register */ +#define USB_FIFO5_DATA_OFFSET 0x50000 /* Pipe/Endpoint 5 FIFO Data Register */ +#define USB_FIFO6_DATA_OFFSET 0x60000 /* Pipe/Endpoint 6 FIFO Data Register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_USBB_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3_wdt.h b/arch/avr/src/at32uc3/at32uc3_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..b3bfde6a93daaf1922621fe58e23966b70566485 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3_wdt.h @@ -0,0 +1,87 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3_wdt.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3_WDT_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3_WDT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register offsets *****************************************************************/ + +#define AVR32_WDT_CTRL_OFFSET 0x00 /* Control Register */ +#define AVR32_WDT_CLR_OFFSET 0x04 /* Clear Register */ + +/* Register Addresses ***************************************************************/ + +#define AVR32_WDT_CTRL (AVR32_WDT_BASE+AVR32_WDT_CTRL_OFFSET) +#define AVR32_WDT_CLR (AVR32_WDT_BASE+AVR32_WDT_CLR_OFFSET) + +/* Register Bit-field Definitions ***************************************************/ + +/* Control Register Bit-field Definitions */ + +#define WDT_CTRL_EN (1 << 0) /* Bit 0: WDT Enable */ +#define WDT_CTRL_PSEL_SHIFT (18) /* Bits 8-12: Prescale Select */ +#define WDT_CTRL_PSEL_MASK (0x1f << WDT_CTRL_PSEL_SHIFT) +#define WDT_CTRL_KEY_SHIFT (24) /* Bits 24-31: Write protection key */ +#define WDT_CTRL_KEY_MASK (0xff << WDT_CTRL_KEY_SHIFT) + +/* Clear Register Bit-field Definitions. These registers have no bit fields: "Writing + * periodically any value to this field when the WDT is enabled, within the watchdog + * time-out period, will prevent a watchdog reset." + */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_WDT_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3a_pinmux.h b/arch/avr/src/at32uc3/at32uc3a_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..695db47b58e30151f676873e24ae5097ea9046d4 --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3a_pinmux.h @@ -0,0 +1,64 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3a_pinmux.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3A_PINMUX_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3A_PINMUX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#warning "Not Implemented" + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3_PINMUX_H */ + diff --git a/arch/avr/src/at32uc3/at32uc3b_pinmux.h b/arch/avr/src/at32uc3/at32uc3b_pinmux.h new file mode 100644 index 0000000000000000000000000000000000000000..d5758745da12f995c6a57685422ad3e267eaf2df --- /dev/null +++ b/arch/avr/src/at32uc3/at32uc3b_pinmux.h @@ -0,0 +1,263 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/at32uc3b_pinmux.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_AT32UC3B_PINMUX_H +#define __ARCH_AVR_SRC_AT32UC3_AT32UC3B_PINMUX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* NOTES: + * 1. No external pins for PA28-PA31, PB0-PB11 on 48-pin packages (UC3B1). + * 2. Function D is available only on UC3Bx12. + * 3. In the cases where there are multiple alternatives (such as PINMUX_USART0_RXD_1 + * and PINMUX_USART0_RXD_2) the correct multiplexing must be selected in the board.h + * file (by defining PINMUX_USART0_RXD to be INMUX_USART0_RXD_1, for example). + */ + +#define PINMUX_GPIO0 (GPIO_ENABLE | GPIO_PORTA | 0) +#define PINMUX_GPIO1 (GPIO_ENABLE | GPIO_PORTA | 1) +#define PINMUX_GPIO2 (GPIO_ENABLE | GPIO_PORTA | 2) +#define PINMUX_GPIO3 (GPIO_ENABLE | GPIO_PORTA | 3) +#define PINMUX_ADC_AD0 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 3) +#define PINMUX_PM_GCLK0 U (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 3) +#define PINMUX_SBB_USB_ID (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 3) +#define PINMUX_ABDAC_DATA0_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 3) +#define PINMUX_GPIO4 (GPIO_ENABLE | GPIO_PORTA | 4) +#define PINMUX_ADC_AD1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 4) +#define PINMUX_M_GCLK1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 4) +#define PINMUX_USBB_USB_VBOF_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 4) +#define PINMUX_ABDAC_DATAN0_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 4) +#define PINMUX_GPIO5 (GPIO_ENABLE | GPIO_PORTA | 5) +#define PINMUX_EIC_EXTINT0 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 5) +#define PINMUX_ADC_AD2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 5) +#define PINMUX_USART1_DCD_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 5) +#define PINMUX_ABDAC_DATA1_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 5) +#define PINMUX_GPIO6 (GPIO_ENABLE | GPIO_PORTA | 6) +#define PINMUX_EIC_EXTINT1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 6) +#define PINMUX_ADC_AD3 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 6) +#define PINMUX_USART1_DSR_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 6) +#define PINMUX_ABDAC_DATAN1_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 6) +#define PINMUX_GPIO7 (GPIO_ENABLE | GPIO_PORTA | 7) +#define PINMUX_PM_PWM0 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 7) +#define PINMUX_ADC_AD4 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 7) +#define PINMUX_USART1_DTR_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 7) +#define PINMUX_SSC_RX_FRAME_SYNC (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 7) +#define PINMUX_GPIO8 (GPIO_ENABLE | GPIO_PORTA | 8) +#define PINMUX_PWM_PWM1_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 8) +#define PINMUX_ADC_AD5 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 8) +#define PINMUX_USART1_RI_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 8) +#define PINMUX_SSC_RX_CLOCK_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 8) +#define PINMUX_GPIO9 (GPIO_ENABLE | GPIO_PORTA | 9) +#define PINMUX_TWI_SCL (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 9) +#define PINMUX_SPI0_NPCS2_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 9) +#define PINMUX_USART1_CTS_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 9) +#define PINMUX_GPIO10 (GPIO_ENABLE | GPIO_PORTA | 10) +#define PINMUX_TWI_SDA (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 10) +#define PINMUX_SPI0_NPCS3_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 10) +#define PINMUX_USART1_RTS_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 10) +#define PINMUX_GPIO11 (GPIO_ENABLE | GPIO_PORTA | 11) +#define PINMUX_USART0_RTS (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 11) +#define PINMUX_TC_A2_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 11) +#define PINMUX_PWM_PWM0_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 11) +#define PINMUX_SSC_RX_DATA_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 11) +#define PINMUX_GPIO12 (GPIO_ENABLE | GPIO_PORTA | 12) +#define PINMUX_USART0_CTS (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 12) +#define PINMUX_TC_B2_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 12) +#define PINMUX_PWM_PWM1_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 12) +#define PINMUX_USART1_TXD_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 12) +#define PINMUX_GPIO13 (GPIO_ENABLE | GPIO_PORTA | 13) +#define PINMUX_EIC_NMI (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 13) +#define PINMUX_PWM_PWM2_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 13) +#define PINMUX_USART0_CLK_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 13) +#define PINMUX_SSC_RX_CLOCK_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 13) +#define PINMUX_GPIO14 (GPIO_ENABLE | GPIO_PORTA | 14) +#define PINMUX_SPI0_MOSI_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 14) +#define PINMUX_PWM_PWM3 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 14) +#define PINMUX_EIC_EXTINT2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 14) +#define PINMUX_PM_GCLK2_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 14) +#define PINMUX_GPIO15 (GPIO_ENABLE | GPIO_PORTA | 15) +#define PINMUX_SPI0_SCK_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 15) +#define PINMUX_PWM_PWM4_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 15) +#define PINMUX_USART2_CLK (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 15) +#define PINMUX_GPIO16 (GPIO_ENABLE | GPIO_PORTA | 16) +#define PINMUX_SPI0_NPCS0_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 16) +#define PINMUX_TC_CLK1_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 16) +#define PINMUX_PWM_PWM4_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 16) +#define PINMUX_GPIO17 (GPIO_ENABLE | GPIO_PORTA | 17) +#define PINMUX_SPI0_NPCS1_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 17) +#define PINMUX_TC_CLK2_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 17) +#define PINMUX_SPI0_SCK_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 17) +#define PINMUX_USART1_RXD_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 17) +#define PINMUX_GPIO18 (GPIO_ENABLE | GPIO_PORTA | 18) +#define PINMUX_USART0_RXD_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 18) +#define PINMUX_PWM_PWM5 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 18) +#define PINMUX_SPI0_MISO_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 18) +#define PINMUX_SSC_RX_FRAME_SYNC_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 18) +#define PINMUX_GPIO19 (GPIO_ENABLE | GPIO_PORTA | 19) +#define PINMUX_USART0_TXD_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 19) +#define PINMUX_PWM_PWM6_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 19) +#define PINMUX_SPI0_MOSI_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 19) +#define PINMUX_SSC_TX_CLOCK_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 19) +#define PINMUX_GPIO20 (GPIO_ENABLE | GPIO_PORTA | 20) +#define PINMUX_USART1_CLK (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 20) +#define PINMUX_TC_CLK0_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 20) +#define PINMUX_USART2_RXD_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 20) +#define PINMUX_SSC_TX_DATA_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 20) +#define PINMUX_GPIO21 (GPIO_ENABLE | GPIO_PORTA | 21) +#define PINMUX_PWM_PWM2_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 21) +#define PINMUX_TC_A1_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 21) +#define PINMUX_USART2_TXD_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 21) +#define PINMUX_SSC_TX_FRAME_SYNC_1 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 21) +#define PINMUX_GPIO22 (GPIO_ENABLE | GPIO_PORTA | 22) +#define PINMUX_PWM_PWM6_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 22) +#define PINMUX_TC_B1_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 22) +#define PINMUX_ADC_TRIGGER (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 22) +#define PINMUX_ABDAC_DATA0_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 22) +#define PINMUX_GPIO23 (GPIO_ENABLE | GPIO_PORTA | 23) +#define PINMUX_USART1_TXD_1 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 23) +#define PINMUX_SPI0_NPCS1_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 23) +#define PINMUX_EIC_EXTINT3 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 23) +#define PINMUX_PWM_PWM0_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 23) +#define PINMUX_GPIO24 (GPIO_ENABLE | GPIO_PORTA | 24) +#define PINMUX_USART1_RXD_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 24) +#define PINMUX_SPI0_NPCS0_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 24) +#define PINMUX_EIC_EXTINT4 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 24) +#define PINMUX_PWM_PWM1_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 24) +#define PINMUX_GPIO25 (GPIO_ENABLE | GPIO_PORTA | 25) +#define PINMUX_SPI0_MISO_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 25) +#define PINMUX_WM_PWM3 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 25) +#define PINMUX_EIC_EXTINT5 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 25) +#define PINMUX_GPIO26 (GPIO_ENABLE | GPIO_PORTA | 26) +#define PINMUX_USBB_USB_ID (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 26) +#define PINMUX_USART2_TXD_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 26) +#define PINMUX_TC_A0_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 26) +#define PINMUX_ABDAC_DATA1_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 26) +#define PINMUX_GPIO27 (GPIO_ENABLE | GPIO_PORTA | 27) +#define PINMUX_USBB_USB_VBOF_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 27) +#define PINMUX_USART2_RXD_1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 27) +#define PINMUX_TC_B0_1 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 27) +#define PINMUX_ABDAC_DATAN1_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 27) +#define PINMUX_GPIO28 (GPIO_ENABLE | GPIO_PORTA | 28) +#define PINMUX_USART0_CLK_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 28) +#define PINMUX_PWM_PWM4_3 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 28) +#define PINMUX_SPI0_MISO_3 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 28) +#define PINMUX_ABDAC_DATAN0_2 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTA | 28) +#define PINMUX_GPIO29 (GPIO_ENABLE | GPIO_PORTA | 29) +#define PINMUX_TC_CLK0_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 29) +#define PINMUX_TC_CLK1_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 29) +#define PINMUX_SPI0_MOSI_3 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 29) +#define PINMUX_GPIO30 (GPIO_ENABLE | GPIO_PORTA | 30) +#define PINMUX_ADC_AD6 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 30) +#define PINMUX_EIC_SCAN0 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 30) +#define PINMUX_PM_GCLK2_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 30) +#define PINMUX_GPIO31 (GPIO_ENABLE | GPIO_PORTA | 31) +#define PINMUX_ADC_AD7 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTA | 31) +#define PINMUX_EIC_SCAN1 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTA | 31) +#define PINMUX_PWM_PWM6_3 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTA | 31) +#define PINMUX_GPIO32 (GPIO_ENABLE | GPIO_PORTB | 0) +#define PINMUX_TC_A0_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 0) +#define PINMUX_EIC_SCAN2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 0) +#define PINMUX_USART2_CTS (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 0) +#define PINMUX_GPIO33 (GPIO_ENABLE | GPIO_PORTB | 1) +#define PINMUX_TC_B0_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 1) +#define PINMUX_EIC_SCAN3 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 1) +#define PINMUX_USART2_RTS (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 1) +#define PINMUX_GPIO34 (GPIO_ENABLE | GPIO_PORTB | 2) +#define PINMUX_EIC_EXTINT6 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 2) +#define PINMUX_TC_A1_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 2) +#define PINMUX_USART1_TXD_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 2) +#define PINMUX_GPIO35 (GPIO_ENABLE | GPIO_PORTB | 3) +#define PINMUX_EIC_EXTINT7 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 3) +#define PINMUX_TC_B1_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 3) +#define PINMUX_USART1_RXD_3 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 3) +#define PINMUX_GPIO36 (GPIO_ENABLE | GPIO_PORTB | 4) +#define PINMUX_USART1_CTS_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 4) +#define PINMUX_SPI0_NPCS3_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 4) +#define PINMUX_TC_CLK2_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 4) +#define PINMUX_GPIO37 (GPIO_ENABLE | GPIO_PORTB | 5) +#define PINMUX_USART1_RTS_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 5) +#define PINMUX_SPI0_NPCS2_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 5) +#define PINMUX_WM_PWM5 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 5) +#define PINMUX_GPIO38 (GPIO_ENABLE | GPIO_PORTB | 6) +#define PINMUX_SSC_RX_CLOCK_3 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 6) +#define PINMUX_USART1_DCD_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 6) +#define PINMUX_EIC_SCAN4 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 6) +#define PINMUX_ABDAC_DATA0_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTB | 6) +#define PINMUX_GPIO39 (GPIO_ENABLE | GPIO_PORTB | 7) +#define PINMUX_SSC_RX_DATA_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 7) +#define PINMUX_USART1_DSR_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 7) +#define PINMUX_EIC_SCAN5 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 7) +#define PINMUX_ABDAC_DATAN0_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTB | 7) +#define PINMUX_GPIO40 (GPIO_ENABLE | GPIO_PORTB | 8) +#define PINMUX_SSC_RX_FRAME_SYNC_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 8) +#define PINMUX_USART1_DTR_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 8) +#define PINMUX_EIC_SCAN6 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 8) +#define PINMUX_ABDAC_DATA1_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTB | 8) +#define PINMUX_GPIO41 (GPIO_ENABLE | GPIO_PORTB | 9) +#define PINMUX_SSC_TX_CLOCK_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 9) +#define PINMUX_USART1_RI_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 9) +#define PINMUX_EIC_SCAN7 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 9) +#define PINMUX_ABDAC_DATAN1_3 (GPIO_PERIPH | GPIO_FUNCD | GPIO_PORTB | 9) +#define PINMUX_GPIO42 (GPIO_ENABLE | GPIO_PORTB | 10) +#define PINMUX_SSC_TX_DATA_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 10) +#define PINMUX_TC_A2_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 10) +#define PINMUX_USART0_RXD_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 10) +#define PINMUX_GPIO43 (GPIO_ENABLE | GPIO_PORTB | 11) +#define PINMUX_SSC_TX_FRAME_SYNC_2 (GPIO_PERIPH | GPIO_FUNCA | GPIO_PORTB | 11) +#define PINMUX_TC_B2_2 (GPIO_PERIPH | GPIO_FUNCB | GPIO_PORTB | 11) +#define PINMUX_USART0_TXD_2 (GPIO_PERIPH | GPIO_FUNCC | GPIO_PORTB | 11) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_AT32UC3B_PINMUX_H */ + diff --git a/arch/avr/src/at32uc3/chip.h b/arch/avr/src/at32uc3/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..99fad31eb9cf54f0b53793d16ceff5016d231ee7 --- /dev/null +++ b/arch/avr/src/at32uc3/chip.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/avr/src/at32uc3/chip.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AT32UC3_CHIP_H +#define __ARCH_AVR_SRC_AT32UC3_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported chip */ + +/* UC3 A0/A1 Series */ +/* UC3 A2/A3 Series */ + +/* UC3 B0 (64-pin) / B1 (48-pin, no USB host) Series */ + +#ifdef CONFIG_ARCH_CHIP_AT32UC3B064 +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B0 1 /* UC3 B0 (64-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (64*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (16*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# define AVR32_USB_HOST 1 /* USB host support (OTG) */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 3 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 1 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 44 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 2 /* Number of crystal oscillators */ +# define AVR32_NADC10 8 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B0128) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B0 1 /* UC3 B0 (64-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (128*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (32*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# define AVR32_USB_HOST 1 /* USB host support (OTG) */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 3 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 1 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 44 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 2 /* Number of crystal oscillators */ +# define AVR32_NADC10 8 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B0256) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B0 1 /* UC3 B0 (64-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (256*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (32*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# define AVR32_USB_HOST 1 /* USB host support (OTG) */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 3 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 1 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 44 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 2 /* Number of crystal oscillators */ +# define AVR32_NADC10 8 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B0512) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B0 1 /* UC3 B0 (64-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (512*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (96*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# define AVR32_USB_HOST 1 /* USB host support (OTG) */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 3 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 1 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 44 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 2 /* Number of crystal oscillators */ +# define AVR32_NADC10 8 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B164) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B1 1 /* UC3 B0 (48-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (64*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (16*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# undef AVR32_USB_HOST /* No USB host support */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 2 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 0 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 28 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 1 /* Number of crystal oscillators */ +# define AVR32_NADC10 6 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B1128) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B1 1 /* UC3 B0 (48-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (128*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (32*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# undef AVR32_USB_HOST /* No USB host support */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 2 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 0 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 28 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 1 /* Number of crystal oscillators */ +# define AVR32_NADC10 6 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B1256) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B1 1 /* UC3 B0 (48-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (256*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (32*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# undef AVR32_USB_HOST /* No USB host support */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 2 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 0 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 28 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 1 /* Number of crystal oscillators */ +# define AVR32_NADC10 6 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#elif defined(CONFIG_ARCH_CHIP_AT32UC3B1512) +# define CONFIG_ARCH_CHIP_AT32UC3B 1 /* UC3 B series */ +# define CONFIG_ARCH_CHIP_AT32UC3B1 1 /* UC3 B0 (48-pin) series */ +# define AVR32_ONCHIP_FLASH_SIZE (512*1024) /* Size of on-chip FLASH (bytes) */ +# define AVR32_ONCHIP_SRAM_SIZE (96*1024) /* Size of on-chip SRAM (bytes) */ +# define AVR32_USB_FULLSPEED 1 /* USB full-speed support */ +# undef AVR32_USB_HOST /* No USB host support */ +# define AVR32_USB_DEVICE 1 /* USB device support */ +# define AVR32_NUSART 2 /* Number of USARTs */ +# define AVR32_NSPI 2 /* Number of SPI */ +# define AVR32_NTWI 1 /* Number of TWI (I2C) */ +# define AVR32_NSSC 0 /* Number of SSC (I2S audio) */ +# define AVR32_NGPIO 28 /* Number of GPIO pins */ +# define AVR32_NTIMER 3 /* Number of Timers */ +# define AVR32_NPWM 13 /* Number of PWM channels */ +# define AVR32_NOSC 1 /* Number of crystal oscillators */ +# define AVR32_NADC10 6 /* Number of 10-bit A/D channels */ +# define AVR32_NDMAC 7 /* Number of DMA channels */ +#else +# error "Unsupported AVR32 chip" +#endif + +/* Include only the memory map. Other chip hardware files should then include this + * file for the proper setup + */ + +#include "at32uc3_memorymap.h" + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_AT32UC3_CHIP_H */ + diff --git a/arch/avr/src/at90usb/Kconfig b/arch/avr/src/at90usb/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..6481e6973f063b4ecc578ee674ad457c92cf38a9 --- /dev/null +++ b/arch/avr/src/at90usb/Kconfig @@ -0,0 +1,62 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_AT90USB +comment "AT90USB Configuration Options" + +choice + prompt "Atmel ATmega chip selection" + default ARCH_CHIP_AT90USB646 + +config ARCH_CHIP_AT90USB646 + bool "AT90USB646" + ---help--- + Atmel AT90USB646 8-bit AVR. + +config ARCH_CHIP_AT90USB647 + bool "AT90USB647" + ---help--- + Atmel AT90USB647 8-bit AVR. + +config ARCH_CHIP_AT90USB1286 + bool "AT90USB1286" + ---help--- + Atmel AT90USB1286 8-bit AVR. + +config ARCH_CHIP_AT90USB1287 + bool "AT90USB1287" + ---help--- + Atmel AT90USB1287 8-bit AVR. + +endchoice # Atmel ATmega chip selection + +menu "AT90USB Peripheral Selections" + +config AVR_SPI + bool "SPI" + default n + +config AVR_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + +config AVR_USBDEV + bool "USB device" + default n + +config AVR_WDT + bool "Watchdog" + default n + +endmenu # AT90USB Peripheral Selections + +config AVR_GPIOIRQ + bool "GPIO pin interrupts" + default n + ---help--- + Enable support for interrupting GPIO pins + +endif # ARCH_CHIP_AT90USB diff --git a/arch/avr/src/at90usb/Make.defs b/arch/avr/src/at90usb/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..50245c338a981130077cbe546afe0da42a3e483d --- /dev/null +++ b/arch/avr/src/at90usb/Make.defs @@ -0,0 +1,82 @@ +############################################################################ +# arch/avr/src/at90usb/Make.defs +# +# Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = at90usb_head.S + +# Common AVR files + +CMN_ASRCS = up_switchcontext.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_irq.c up_lowputs.c +CMN_CSRCS += up_mdelay.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_puts.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_sigdeliver.c +CMN_CSRCS += up_stackframe.c up_udelay.c up_unblocktask.c up_usestack.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARCH_STACKDUMP),y) +CMN_CSRCS += up_dumpstate.c +endif + +ifeq ($(CONFIG_AVR_SPI),y) +CMN_CSRCS += up_spi.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ARCH_ROMGETC),y) +CMN_CSRCS += up_romgetc.c +endif + +# Required AT90USB files + +CHIP_ASRCS = at90usb_exceptions.S +CHIP_CSRCS = at90usb_lowconsole.c at90usb_lowinit.c at90usb_serial.c + +# Configuration-dependent aT90USB files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += at90usb_timerisr.c +endif + +ifeq ($(CONFIG_AVR_USBDEV),y) +CHIP_CSRCS += at90usb_usbdev.c +endif diff --git a/arch/avr/src/at90usb/at90usb.h b/arch/avr/src/at90usb/at90usb.h new file mode 100644 index 0000000000000000000000000000000000000000..2f2fc208e714c1b4ed13e7bb09854c5c979b32db --- /dev/null +++ b/arch/avr/src/at90usb/at90usb.h @@ -0,0 +1,212 @@ +/**************************************************************************** + * arch/avr/src/at90usb/at90usb.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at90usb_config.h" + +#ifdef CONFIG_AVR_GPIOIRQ +# include +#endif + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_clkinit + * + * Description: + * Initialize clock/PLL settings per the definitions in the board.h file. + * + ****************************************************************************/ + +void up_clkinitialize(void); + +/**************************************************************************** + * Name: usart1_reset + * + * Description: + * Reset USART1. + * + ****************************************************************************/ + +void usart1_reset(void); + +/**************************************************************************** + * Name: usart1_configure + * + * Description: + * Configure USART1. + * + ****************************************************************************/ + +void usart1_configure(void); + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initialization sequence to configure the serial console + * UART (only). + * + ****************************************************************************/ + +void up_consoleinit(void); + +/**************************************************************************** + * Name: at90usb_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the + * directory configs//src/. + * + ****************************************************************************/ + +void at90usb_boardinitialize(void); + +/**************************************************************************** + * Name: gpio_irqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + * Assumptions: + * Called during the early boot sequence before global interrupts have + * been enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void weak_function gpio_irqinitialize(void); +#endif + +/**************************************************************************** + * Name: gpio_irqattach + * + * Description: + * Attach in GPIO interrupt to the provide 'isr' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +int gpio_irqattach(int irq, xcpt_t newisr, xcpt_t *oldisr); +#endif + +/**************************************************************************** + * Name: gpio_irqenable + * + * Description: + * Enable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void gpio_irqenable(int irq); +#endif + +/**************************************************************************** + * Name: gpio_irqdisable + * + * Description: + * Disable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void gpio_irqdisable(int irq); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_H */ + diff --git a/arch/avr/src/at90usb/at90usb_config.h b/arch/avr/src/at90usb/at90usb_config.h new file mode 100644 index 0000000000000000000000000000000000000000..3f0d80a19d8a819b3a0e2a61d97995536e928bd4 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_config.h @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/avr/src/at90usb/at90usb_config.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* USARTs ***************************************************************************/ + +#undef HAVE_USART_DEVICE +#if defined(CONFIG_AVR_USART1) +# define HAVE_USART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It + * could be on any USARTn (but n=1 only for the AT90USB). + */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_AVR_USART1) +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(HAVE_USART_DEVICE) +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# else +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H */ + diff --git a/arch/avr/src/at90usb/at90usb_exceptions.S b/arch/avr/src/at90usb/at90usb_exceptions.S new file mode 100644 index 0000000000000000000000000000000000000000..542ad7f74f69ac570b1e23a1955308aea3337513 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_exceptions.S @@ -0,0 +1,177 @@ +/******************************************************************************************** + * arch/avr/src/at90usb/at90usb_exceptions.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include + +#include "excptmacros.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * External Symbols + ********************************************************************************************/ + + .file "at90usb_exceptions.S" + .global up_doirq + .global up_fullcontextrestore + +/******************************************************************************************** + * Macros + ********************************************************************************************/ + +/******************************************************************************************** + * Exception Vector Handlers + ********************************************************************************************/ + + .section .handlers, "ax", @progbits + + HANDLER at90usb_int0, AT90USB_IRQ_INT0, excpt_common /* External interrupt request 0 */ + HANDLER at90usb_int1, AT90USB_IRQ_INT1, excpt_common /* External interrupt request 1 */ + HANDLER at90usb_int2, AT90USB_IRQ_INT2, excpt_common /* External interrupt request 2 */ + HANDLER at90usb_int3, AT90USB_IRQ_INT3, excpt_common /* External interrupt request 3 */ + HANDLER at90usb_int4, AT90USB_IRQ_INT4, excpt_common /* External interrupt request 4 */ + HANDLER at90usb_int5, AT90USB_IRQ_INT5, excpt_common /* External interrupt request 5 */ + HANDLER at90usb_int6, AT90USB_IRQ_INT6, excpt_common /* External interrupt request 6 */ + HANDLER at90usb_int7, AT90USB_IRQ_INT7, excpt_common /* External interrupt request 7 */ + HANDLER at90usb_pcint0, AT90USB_IRQ_PCINT0, excpt_common /* Pin Change Interrupt Request 0 */ + HANDLER at90usb_usbgen, AT90USB_IRQ_USBGEN, excpt_common /* USB General USB General Interrupt request */ + HANDLER at90usb_usbep, AT90USB_IRQ_USBEP, excpt_common /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + HANDLER at90usb_wdt, AT90USB_IRQ_WDT, excpt_common /* Watchdog Time-out Interrupt */ + HANDLER at90usb_t2compa, AT90USB_IRQ_T2COMPA, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match A */ + HANDLER at90usb_t2compb, AT90USB_IRQ_T2COMPB, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match B */ + HANDLER at90usb_t2ovf, AT90USB_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ + HANDLER at90usb_t1capt, AT90USB_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ + HANDLER at90usb_t1compa, AT90USB_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match A */ + HANDLER at90usb_t1compb, AT90USB_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match B */ + HANDLER at90usb_t1compc, AT90USB_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/counter1 compare match C */ + HANDLER at90usb_t1ovf, AT90USB_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ + HANDLER at90usb_t0compa, AT90USB_IRQ_T0COMPA, excpt_common /* TIMER0 COMPA Timer/Counter0 Compare Match A */ + HANDLER at90usb_t0compb, AT90USB_IRQ_T0COMPB, excpt_common /* TIMER0 COMPB Timer/Counter0 Compare Match B */ + HANDLER at90usb_t0ovf, AT90USB_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ + HANDLER at90usb_spi, AT90USB_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ + HANDLER at90usb_u1rx, AT90USB_IRQ_U1RX, excpt_common /* USART1 RX complete */ + HANDLER at90usb_u1dre, AT90USB_IRQ_U1DRE, excpt_common /* USART1 data register empty */ + HANDLER at90usb_u1tx, AT90USB_IRQ_U1TX, excpt_common /* USART1 TX complete */ + HANDLER at90usb_anacomp, AT90USB_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ + HANDLER at90usb_adc, AT90USB_IRQ_ADC, excpt_common /* ADC conversion complete */ + HANDLER at90usb_ee, AT90USB_IRQ_EE, excpt_common /* EEPROM ready */ + HANDLER at90usb_t3capt, AT90USB_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ + HANDLER at90usb_t3compa, AT90USB_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ + HANDLER at90usb_t3compb, AT90USB_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ + HANDLER at90usb_t3compc, AT90USB_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ + HANDLER at90usb_t3ovf, AT90USB_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ + HANDLER at90usb_twi, AT90USB_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ + HANDLER at90usb_spmrdy, AT90USB_IRQ_SPMRDY, excpt_common /* Store program memory ready */ + +/******************************************************************************************** + * Name: excpt_common + * + * Description: + * Exception Vector Handlers + * + * On Entry: + * The return PC and the saved r24 is on the stack, r24 now contains the IRQ number + * + * PC1 + * PC0 + * R0 + * --- <- SP + * + ********************************************************************************************/ + +excpt_common: + /* Save the remaining registers on the stack, preserving the IRQ number in r14 */ + + EXCPT_PROLOGUE + + /* Call up_doirq with r24 = IRQ number, r22-23 = Pointer to the save structure. The stack + * pointer currently points to the save structure (or maybe the save struture -1 since + * the push operation post-decrements -- need to REVISIT this). + */ + + in r28, _SFR_IO_ADDR(SPL) /* Get the save structure pointer in a Call-saved register pair */ + in r29, _SFR_IO_ADDR(SPH) /* Pointer can be obtained from the stack pointer */ + adiw r28, 1 /* Remembering that push post-decrements */ + movw r22, r28 /* Pass register save structure as the parameter 2 */ + USE_INTSTACK rx, ry, rz /* Switch to the interrupt stack */ + call up_doirq /* Dispatch the interrupt */ + RESTORE_STACK rx, ry /* Undo the operations of USE_INTSTACK */ + + /* up_doiq returns with r24-r25 equal to the new save structure. If no context + * switch occurred, this will be the same as the value passed to it in r22-23. + * But if a context switch occurs, then the returned value will point not at a + * stack frame, but at a register save area inside of the new task's TCB. + */ + + cp r28, r24 + cpc r29, r25 + breq .Lnoswitch + + /* A context switch has occurred, jump to up_fullcontextrestore with r24, r25 + * equal to the address of the new register save area. + */ + + jmp up_fullcontextrestore + + /* No context switch occurred.. just return off the stack */ + +.Lnoswitch: + EXCPT_EPILOGUE + reti + +/**************************************************************************************************** + * Name: up_interruptstack + ****************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip CONFIG_ARCH_INTERRUPTSTACK +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/avr/src/at90usb/at90usb_head.S b/arch/avr/src/at90usb/at90usb_head.S new file mode 100644 index 0000000000000000000000000000000000000000..6d850b7f27d2f9cf561b6cb96112916ea2c41dcc --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_head.S @@ -0,0 +1,279 @@ +/**************************************************************************** + * arch/avr32/src/at90usb/at90usb_head.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* Stack is allocated just after uninitialized data and just before the heap */ + +#define STACKBASE (_enoinit+CONFIG_IDLETHREAD_STACKSIZE-1) + +/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. + * Only the AT90USB646, 647, 1286, and 1287 are supported by this file. + * + * - Support for the EPLMX instructions is assumed if RAMPZ is present + * - If RAMPZ is not present, support for LPMX is assumed + */ + +#if defined(CONFIG_ARCH_CHIP_AT90USB1286) || defined(CONFIG_ARCH_CHIP_AT90USB1286) +# define HAVE_RAMPZ 1 +#endif + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_nommuhead.S" + .global __start /* Entry point */ + .global _sbss /* Start of .bss. Defined by ld.script */ + .global _ebss /* End of .bss. Defined by ld.script */ + .global _sdata /* Start of .data section in RAM */ + .global _edata /* End of .data section in RAM */ + .global _eronly /* Start of .data section in FLASH */ + .global _enoinit /* End of uninitialized data. Defined by ld.script */ + .global up_lowinit /* Perform low level initialization */ + .global os_start /* NuttX entry point */ + + .global vectortab + .global at90usb_int0 /* External interrupt request 0 */ + .global at90usb_int1 /* External interrupt request 1 */ + .global at90usb_int2 /* External interrupt request 2 */ + .global at90usb_int3 /* External interrupt request 3 */ + .global at90usb_int4 /* External interrupt request 4 */ + .global at90usb_int5 /* External interrupt request 5 */ + .global at90usb_int6 /* External interrupt request 6 */ + .global at90usb_int7 /* External interrupt request 7 */ + .global at90usb_pcint0 /* Pin Change Interrupt Request 0 */ + .global at90usb_usbgen /* USB General USB General Interrupt request */ + .global at90usb_usbep /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + .global at90usb_wdt /* Watchdog Time-out Interrupt */ + .global at90usb_t2compa /* TIMER2 COMPA Timer/Counter2 Compare Match A */ + .global at90usb_t2compb /* TIMER2 COMPB Timer/Counter2 Compare Match B */ + .global at90usb_t2ovf /* TIMER2 OVF Timer/Counter2 Overflow */ + .global at90usb_t1capt /* TIMER1 CAPT Timer/Counter1 Capture Event */ + .global at90usb_t1compa /* TIMER1 COMPA Timer/Counter1 Compare Match A */ + .global at90usb_t1compb /* TIMER1 COMPB Timer/Counter1 Compare Match B */ + .global at90usb_t1compc /* TIMER1 COMPC Timer/Counter1 Compare Match c */ + .global at90usb_t1ovf /* TIMER1 OVF Timer/Counter1 Overflow */ + .global at90usb_t0compa /* TIMER0 COMPA Timer/Counter0 Compare Match A */ + .global at90usb_t0compb /* TIMER0 COMPB Timer/Counter0 Compare Match B */ + .global at90usb_t0ovf /* TIMER0 OVF Timer/Counter0 Overflow */ + .global at90usb_spi /* STC SPI Serial Transfer Complete */ + .global at90usb_u1rx /* USART1 Rx Complete */ + .global at90usb_u1dre /* USART1 Data Register Empty */ + .global at90usb_u1tx /* USART1 Tx Complete */ + .global at90usb_anacomp /* ANALOG COMP Analog Comparator */ + .global at90usb_adc /* ADC Conversion Complete */ + .global at90usb_ee /* EEPROM Ready */ + .global at90usb_t3capt /* TIMER3 CAPT Timer/Counter3 Capture Event */ + .global at90usb_t3compa /* TIMER3 COMPA Timer/Counter3 Compare Match A */ + .global at90usb_t3compb /* TIMER3 COMPB Timer/Counter3 Compare Match B */ + .global at90usb_t3compc /* TIMER3 COMPC Timer/Counter3 Compare Match C */ + .global at90usb_t3ovf /* TIMER3 OVF Timer/Counter3 Overflow */ + .global at90usb_twi /* TWI Two-wire Serial Interface */ + .global at90usb_spmrdy /* Store Program Memory Ready */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + + .macro vector name + jmp \name + .endm + +/**************************************************************************** + * Vector Table + ****************************************************************************/ + +/* The AT90USB has 38 interrupt vectors including vector 0, the reset + * vector. + */ + + .section .vectors, "ax", @progbits + .func vectortab +vectortab: + jmp __start /* 0: Vector 0 is the reset vector */ + vector at90usb_int0 /* 1: External interrupt request 0 */ + vector at90usb_int1 /* 2: External interrupt request 1 */ + vector at90usb_int2 /* 3: External interrupt request 2 */ + vector at90usb_int3 /* 4: External interrupt request 3 */ + vector at90usb_int4 /* 5: External interrupt request 4 */ + vector at90usb_int5 /* 6: External interrupt request 5 */ + vector at90usb_int6 /* 7: External interrupt request 6 */ + vector at90usb_int7 /* 8: External interrupt request 7 */ + vector at90usb_pcint0 /* 9: PCINT0 Pin Change Interrupt Request 0 */ + vector at90usb_usbgen /* 10: USB General USB General Interrupt request */ + vector at90usb_usbep /* 11: USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + vector at90usb_wdt /* 12: Watchdog Time-out Interrupt */ + vector at90usb_t2compa /* 13: TIMER2 COMPA Timer/Counter2 Compare Match A */ + vector at90usb_t2compb /* 14: TIMER2 COMPB Timer/Counter2 Compare Match B */ + vector at90usb_t2ovf /* 15: TIMER2 OVF Timer/Counter2 Overflow */ + vector at90usb_t1capt /* 16: TIMER1 CAPT Timer/Counter1 Capture Event */ + vector at90usb_t1compa /* 17: TIMER1 COMPA Timer/Counter1 Compare Match A */ + vector at90usb_t1compb /* 18: TIMER1 COMPB Timer/Counter1 Compare Match B */ + vector at90usb_t1compc /* 19: TIMER1 COMPC Timer/Counter1 Compare Match c */ + vector at90usb_t1ovf /* 20: TIMER1 OVF Timer/Counter1 Overflow */ + vector at90usb_t0compa /* 21: TIMER0 COMPA Timer/Counter0 Compare Match A */ + vector at90usb_t0compb /* 22: TIMER0 COMPB Timer/Counter0 Compare Match B */ + vector at90usb_t0ovf /* 23: TIMER0 OVF Timer/Counter0 Overflow */ + vector at90usb_spi /* 24: STC SPI Serial Transfer Complete */ + vector at90usb_u1rx /* 25: USART1 Rx Complete */ + vector at90usb_u1dre /* 26: USART1 Data Register Empty */ + vector at90usb_u1tx /* 27: USART1 Tx Complete */ + vector at90usb_anacomp /* 28: ANALOG COMP Analog Comparator */ + vector at90usb_adc /* 29: ADC Conversion Complete */ + vector at90usb_ee /* 30: EEPROM Ready */ + vector at90usb_t3capt /* 31: TIMER3 CAPT Timer/Counter3 Capture Event */ + vector at90usb_t3compa /* 32: TIMER3 COMPA Timer/Counter3 Compare Match A */ + vector at90usb_t3compb /* 33: TIMER3 COMPB Timer/Counter3 Compare Match B */ + vector at90usb_t3compc /* 34: TIMER3 COMPC Timer/Counter3 Compare Match C */ + vector at90usb_t3ovf /* 35: TIMER3 OVF Timer/Counter3 Overflow */ + vector at90usb_twi /* 36: TWI Two-wire Serial Interface */ + vector at90usb_spmrdy /* 37: Store Program Memory Ready */ + .endfunc + +/**************************************************************************** + * Reset Entry Point + ****************************************************************************/ + + .section .init, "ax", @progbits + .func __start +__start: + + /* Clear the zero register, clear the status register and initialize the + * IDLE thread stack + */ + + clr r1 + out _SFR_IO_ADDR(SREG), r1 + ldi r28, lo8(STACKBASE) + ldi r29, hi8(STACKBASE) + out _SFR_IO_ADDR(SPH), r29 + out _SFR_IO_ADDR(SPL), r28 + + /* Copy initial global data values from FLASH into RAM */ + + .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ +__do_copy_data: + +#ifdef HAVE_RAMPZ + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + ldi r16, hh8(_eronly) + out _SFR_IO_ADDR(RAMPZ), r16 + rjmp .Lcopystart + +.Lcopyloop: + elpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#else + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + rjmp .Lcopystart + +.Lcopyloop: + lpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#endif + + /* Clear uninitialized data */ + + .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ +__do_clear_bss: + + ldi r17, hi8(_ebss) + ldi r26, lo8(_sbss) + ldi r27, hi8(_sbss) + rjmp .Lclearstart + +.Lclearloop: + st X+, r1 + +.Lclearstart: + cpi r26, lo8(_ebss) + cpc r27, r17 + brne .Lclearloop + + /* Perform any low-level initialization */ + + call up_lowinit + + /* Now start NuttX */ + + call os_start + jmp exit + .endfunc + +/**************************************************************************** + * Heap Base + ****************************************************************************/ + + /* This global variable is unsigned long g_idle_topstack and is exported from + * here only because of its coupling to other uses of _enoinit in this file + */ + + .data + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word _enoinit+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/avr/src/at90usb/at90usb_lowconsole.c b/arch/avr/src/at90usb/at90usb_lowconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..7ddc2d8e9f008badb71f67ce09fd867a0b13e312 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_lowconsole.c @@ -0,0 +1,284 @@ +/**************************************************************************** + * arch/avr/src/at90usb/at90usb_lowconsole.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at90usb_config.h" + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "at90usb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Baud rate settings for normal and double speed modes */ + +#define AVR_NORMAL_UBRR1 \ + ((((BOARD_CPU_CLOCK / 16) + (CONFIG_USART1_BAUD / 2)) / (CONFIG_USART1_BAUD)) - 1) + +#define AVR_DBLSPEED_UBRR1 \ + ((((BOARD_CPU_CLOCK / 8) + (CONFIG_USART1_BAUD / 2)) / (CONFIG_USART1_BAUD)) - 1) + +/* Select normal or double speed baud settings. This is a trade-off between the + * sampling rate and the accuracy of the divisor for high baud rates. + * + * As examples, consider: + * + * BOARD_CPU_CLOCK=8MHz and BAUD=115200: + * AVR_NORMAL_UBRR1 = 4 (rounded), actual baud = 125,000 + * AVR_DBLSPEED_UBRR1 = 9 (rounded), actual baud = 111,111 + * + * BOARD_CPU_CLOCK=8MHz and BAUD=9600: + * AVR_NORMAL_UBRR1 = 52 (rounded), actual baud = 9615 + * AVR_DBLSPEED_UBRR1 = 104 (rounded), actual baud = 9615 + */ + +#undef UART1_DOUBLE_SPEED +#if BOARD_CPU_CLOCK <= 4000000 +# if CONFIG_USART1_BAUD <= 9600 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define UART1_DOUBLE_SPEED 1 +# endif +#elif BOARD_CPU_CLOCK <= 8000000 +# if CONFIG_USART1_BAUD <= 19200 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define UART1_DOUBLE_SPEED 1 +# endif +#elif BOARD_CPU_CLOCK <= 12000000 +# if CONFIG_USART1_BAUD <= 28800 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define UART1_DOUBLE_SPEED 1 +# endif +#elif BOARD_CPU_CLOCK <= 16000000 +# if CONFIG_USART1_BAUD <= 38400 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define UART1_DOUBLE_SPEED 1 +# endif +#else +# if CONFIG_USART1_BAUD <= 57600 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define UART1_DOUBLE_SPEED 1 +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart1_reset + * + * Description: + * Reset a USART. + * + ****************************************************************************/ + +#ifdef HAVE_USART_DEVICE +void usart1_reset(void) +{ + /* Clear USART configuration */ + + UCSR1A = 0; + UCSR1B = 0; + UCSR1C = 0; + + /* Unconfigure pins */ + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 2); + + /* Unconfigure BAUD divisor */ + + UBRR1 = 0; +} +#endif + +/**************************************************************************** + * Name: usart1_configure + * + * Description: + * Configure USART1. + * + ****************************************************************************/ + +#ifdef HAVE_USART_DEVICE +void usart1_configure(void) +{ + uint8_t ucsr1b; + uint8_t ucsr1c; + + /* Select normal or double speed. */ + +#ifdef UART1_DOUBLE_SPEED + UCSR1A = (1 << U2X1); +#else + UCSR1A = 0; +#endif + + /* Select baud, parity, nubmer of bits, stop bits, etc. */ + + ucsr1b = ((1 << TXEN1) | (1 << RXEN1)); + ucsr1c = 0; + + /* Select parity */ + +#if CONFIG_USART1_PARITY == 1 + ucsr1c |= ((1 << UPM11) | (1 << UPM10)); /* Odd parity */ +#elif CONFIG_USART1_PARITY == 2 + ucsr1c |= (1 << UPM11); /* Even parity */ +#endif + + /* 1 or 2 stop bits */ + +#if defined(CONFIG_USART1_2STOP) && CONFIG_USART1_2STOP > 0 + ucsr1c |= (1 << USBS1); /* Two stop bits */ +#endif + + /* Word size */ + +#if CONFIG_USART1_BITS == 5 +#elif CONFIG_USART1_BITS == 6 + ucsr1c |= (1 << UCSZ10); +#elif CONFIG_USART1_BITS == 7 + ucsr1c |= (1 << UCSZ11); +#elif CONFIG_USART1_BITS == 8 + ucsr1c |= ((1 << UCSZ10) | (1 << UCSZ11)); +#elif CONFIG_USART1_BITS == 9 + ucsr1c |= ((1 << UCSZ10) | (1 << UCSZ11)); + ucsr1b |= (1 << UCSZ12); +#else +# error "Unsupported word size" +#endif + + UCSR1B = ucsr1b; + UCSR1C = ucsr1c; + + /* Pin Configuration: None necessary, Port D bits 2&3 are automatically + * configured: + * + * Port D, Bit 2: RXD1, Receive Data (Data input pin for the USART1). When + * the USART1 receiver is enabled this pin is configured as an input + * regardless of the value of DDD2. When the USART forces this pin to + * be an input, the pull-up can still be controlled by the PORTD2 bit. + * Port D, Bit 3: TXD1, Transmit Data (Data output pin for the USART1). + * When the USART1 Transmitter is enabled, this pin is configured as + * an output regardless of the value of DDD3. + */ + + DDRD |= (1 << 3); /* Force Port D pin 3 to be an output -- Shouldn't be necessary */ + PORTD |= (1 << 2); /* Set pull-up on port D pin 2 */ + + /* Set the baud rate divisor */ + + UBRR1 = AVR_UBRR1; +} +#endif + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initialization sequence to configure the serial console uart + * (only). + * + ****************************************************************************/ + +void up_consoleinit(void) +{ +#ifdef HAVE_SERIAL_CONSOLE + usart1_configure(); +#endif +} + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + while ((UCSR1A & (1 << UDRE1)) == 0); + UDR1 = ch; +#endif +} + diff --git a/arch/avr/src/at90usb/at90usb_lowinit.c b/arch/avr/src/at90usb/at90usb_lowinit.c new file mode 100644 index 0000000000000000000000000000000000000000..9a416f568005e7d3359d4d3869c1b89b3bb31c13 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_lowinit.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/avr/src/at90usb/at90usb_lowinit.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "at90usb_config.h" +#include "up_internal.h" +#include "at90usb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_WDTO_15MS) +# define WDTO_VALUE WDTO_15MS +#elif defined(CONFIG_WDTO_30MS) +# define WDTO_VALUE WDTO_30MS +#elif defined(CONFIG_WDTO_60MS) +# define WDTO_VALUE WDTO_60MS +#elif defined(CONFIG_WDTO_120MS) +# define WDTO_VALUE WDTO_120MS +#elif defined(CONFIG_WDTO_1250MS) +# define WDTO_VALUE WDTO_250MS +#elif defined(CONFIG_WDTO_500MS) +# define WDTO_VALUE WDTO_500MS +#elif defined(CONFIG_WDTO_1S) +# define WDTO_VALUE WDTO_1S +#elif defined(CONFIG_WDTO_2S) +# define WDTO_VALUE WDTO_2S +#elif defined(CONFIG_WDTO_4S) +# define WDTO_VALUE WDTO_4S +#else /* if defined(CONFIG_WDTO_8S) */ +# define WDTO_VALUE WDTO_8S +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdtinit + * + * Description: + * Initialize the watchdog per the NuttX configuration. + * + ****************************************************************************/ + +static inline void up_wdtinit(void) +{ +#ifdef CONFIG_AVR_WDT + wdt_enable(WDTO_VALUE); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowinit + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowinit(void) +{ + /* Disable the watchdog timer */ + + wdt_disable(); + + /* Set the system clock divider to 1 */ + + clock_prescale_set(clock_div_1); + + /* Initialize the watchdog timer */ + + up_wdtinit(); + + /* Initialize a console (probably a serial console) */ + + up_consoleinit(); + + /* Perform early serial initialization (so that we will have debug output + * available as soon as possible). + */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-level initialization */ + + at90usb_boardinitialize(); +} diff --git a/arch/avr/src/at90usb/at90usb_memorymap.h b/arch/avr/src/at90usb/at90usb_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..a40bd3d36f9f22793c4432419603e84989804820 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_memorymap.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/avr/src/at90usb/at90usb_memorymap.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H */ + diff --git a/arch/avr/src/at90usb/at90usb_serial.c b/arch/avr/src/at90usb/at90usb_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..25077f5743145f212754cc82bd029266fbae9cef --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_serial.c @@ -0,0 +1,621 @@ +/**************************************************************************** + * arch/avr/src/at90usb/at90usb_serial.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "at90usb_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "at90usb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Is there at least one USART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_USART_DEVICE +# warning "No USARTs enabled as RS-232 devices" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int usart1_setup(struct uart_dev_s *dev); +static void usart1_shutdown(struct uart_dev_s *dev); +static int usart1_attach(struct uart_dev_s *dev); +static void usart1_detach(struct uart_dev_s *dev); +static int usart1_rxinterrupt(int irq, void *context); +static int usart1_txinterrupt(int irq, void *context); +static int usart1_ioctl(struct file *filep, int cmd, unsigned long arg); +static int usart1_receive(struct uart_dev_s *dev, FAR unsigned int *status); +static void usart1_rxint(struct uart_dev_s *dev, bool enable); +static bool usart1_rxavailable(struct uart_dev_s *dev); +static void usart1_send(struct uart_dev_s *dev, int ch); +static void usart1_txint(struct uart_dev_s *dev, bool enable); +static bool usart1_txready(struct uart_dev_s *dev); +static bool usart1_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct uart_ops_s g_uart1_ops = +{ + .setup = usart1_setup, + .shutdown = usart1_shutdown, + .attach = usart1_attach, + .detach = usart1_detach, + .ioctl = usart1_ioctl, + .receive = usart1_receive, + .rxint = usart1_rxint, + .rxavailable = usart1_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = usart1_send, + .txint = usart1_txint, + .txready = usart1_txready, + .txempty = usart1_txempty, +}; + +/* I/O buffers */ + +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; + +/* This describes the state of the AT90USB USART1 port. */ + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart1_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart1_restoreusartint + ****************************************************************************/ + +static void usart1_restoreusartint(uint8_t imr) +{ + uint8_t regval; + + regval = UCSR1B; + regval &= ~((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + imr &= ((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + regval |= imr; + UCSR1B = regval; +} + +/**************************************************************************** + * Name: usart1_disableusartint + ****************************************************************************/ + +static inline void usart1_disableusartint(uint8_t *imr) +{ + uint8_t regval; + + regval = UCSR1B; + *imr = regval; + regval &= ~((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + UCSR1B = regval; +} + +/**************************************************************************** + * Name: usart1_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int usart1_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + + /* Configure the USART1 */ + + usart1_configure(); +#endif + + return OK; +} + +/**************************************************************************** + * Name: usart1_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void usart1_shutdown(struct uart_dev_s *dev) +{ + /* Reset, disable interrupts, and disable Rx and Tx */ + + usart1_reset(); +} + +/**************************************************************************** + * Name: usart1_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int usart1_attach(struct uart_dev_s *dev) +{ + /* Attach the USART1 IRQs: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + (void)irq_attach(AT90USB_IRQ_U1RX, usart1_rxinterrupt); + (void)irq_attach(AT90USB_IRQ_U1DRE, usart1_txinterrupt); +//(void)irq_attach(AT90USB_IRQ_U1TX, usart1_txinterrupt); + return OK; +} + +/**************************************************************************** + * Name: usart1_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void usart1_detach(struct uart_dev_s *dev) +{ + /* Disable USART1 interrupts */ + + usart1_disableusartint(NULL); + + /* Detach USART1 interrupts */ + + (void)irq_detach(AT90USB_IRQ_U1RX); + (void)irq_detach(AT90USB_IRQ_U1DRE); +//(void)irq_detach(AT90USB_IRQ_U1TX); +} + +/**************************************************************************** + * Name: usart1_rxinterrupt + * + * Description: + * This is the USART RX interrupt handler. It will be invoked when an + * RX interrupt received. It will call uart_receivechar to perform the RX + * data transfers. + * + ****************************************************************************/ + +static int usart1_rxinterrupt(int irq, void *context) +{ + uint8_t ucsr1a = UCSR1A; + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((ucsr1a & (1 << RXC1)) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(&g_usart1port); + } + + return OK; +} + +/**************************************************************************** + * Name: usart1_txinterrupt + * + * Description: + * This is the USART TX interrupt handler. It will be invoked when an + * TX or DRE interrupt received. It will call uart_xmitchars to perform + * the TXdata transfers. + * + ****************************************************************************/ + +static int usart1_txinterrupt(int irq, void *context) +{ + uint8_t ucsr1a = UCSR1A; + + /* Handle outgoing, transmit bytes when the transmit data buffer is empty. + * (There may still be data in the shift register). + */ + + if ((ucsr1a & (1 << UDRE1)) != 0) + { + /* Transmit data regiser empty ... process outgoing bytes */ + + uart_xmitchars(&g_usart1port); + } + + return OK; +} + +/**************************************************************************** + * Name: usart1_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int usart1_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + int ret = OK; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: usart1_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int usart1_receive(struct uart_dev_s *dev, FAR unsigned int *status) +{ + /* Return status information (error bits will be cleared after reading UDR1) */ + + if (status) + { + *status = (FAR unsigned int)UCSR1A; + } + + /* Then return the actual received byte */ + + return UDR1; +} + +/**************************************************************************** + * Name: usart1_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void usart1_rxint(struct uart_dev_s *dev, bool enable) +{ + /* Enable/disable RX interrupts: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR1B |= (1 << RXCIE1); +#endif + } + else + { + UCSR1B &= ~(1 << RXCIE1); + } +} + +/**************************************************************************** + * Name: usart1_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool usart1_rxavailable(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << RXC1)) != 0; +} + +/**************************************************************************** + * Name: usart1_send + * + * Description: + * This method will send one byte on the USART. + * + ****************************************************************************/ + +static void usart1_send(struct uart_dev_s *dev, int ch) +{ + UDR1 = ch; +} + +/**************************************************************************** + * Name: usart1_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void usart1_txint(struct uart_dev_s *dev, bool enable) +{ + irqstate_t flags; + + /* Enable/disable TX interrupts: + * + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR1B |= (1 << UDRIE1); +// UCSR1B |= (1 << TXCIE1); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(&g_usart1port); +#endif + } + else + { + /* Disable the TX interrupt */ + + UCSR1B &= ~((1 << UDRIE1) | (1 << TXCIE1)); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usart1_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool usart1_txready(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << UDRE1)) != 0; +} + +/**************************************************************************** + * Name: usart1_txempty + * + * Description: + * Return true if the tranmsit data register and shift register are both + * empty + * + ****************************************************************************/ + +static bool usart1_txempty(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << TXC1)) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable all USARTS */ + + usart1_disableusartint(NULL); + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + g_usart1port.isconsole = true; + usart1_setup(&g_usart1port); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &g_usart1port); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &g_usart1port); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + uint8_t imr; + + usart1_disableusartint(&imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + usart1_restoreusartint(imr); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/avr/src/at90usb/at90usb_timerisr.c b/arch/avr/src/at90usb/at90usb_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..0c53d2386c75daf5407e8bdd91f90c442a95094f --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_timerisr.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/avr/src/at90usb/at90usb_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "at90usb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The CPU frequency is given by BOARD_CPU_CLOCK (defined in board.h). The + * desired interrupt frequency is given by CONFIG_USEC_PER_TICK. An unscaled + * ideal match is given by: + * + * CLOCK = CPU_CLOCK / DIVISOR # CPU clocks/sec + * MATCH = CLOCK / CLOCKS_PER_SEC # CPU clocks/timer tick + * MATCH = CPU_CLOCK / DIVISOR / CLOCKS_PER_SEC # CPU clocks/timer tick + * + * But we only have 16-bits of accuracy so we need to pick the smallest + * divisor using the following brute force calculation: + */ + +#define MATCH1 (( BOARD_CPU_CLOCK + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH8 ((((BOARD_CPU_CLOCK + 4) / 8) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH64 ((((BOARD_CPU_CLOCK + 8) / 64) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH256 ((((BOARD_CPU_CLOCK + 128) / 256) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH1024 ((((BOARD_CPU_CLOCK + 512) / 1024) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) + +#if MATCH1 <= 65536 +# define MATCH (MATCH1-1) +# define PRESCALE 1 +#elif MATCH8 <= 65536 +# define MATCH (MATCH8-1) +# define PRESCALE 2 +#elif MATCH64 <= 65536 +# define MATCH (MATCH64-1) +# define PRESCALE 3 +#elif MATCH256 <= 65536 +# define MATCH (MATCH256-1) +# define PRESCALE 4 +#elif MATCH1024 <= 65536 +# define MATCH (MATCH1024-1) +# define PRESCALE 5 +#else +# error "Cannot represent this timer frequency" +#endif + +/* Eg. CPU_CLOCK = 8MHz, CLOCKS_PER_SEC = 100 + * + * MATCH1 ((8000000 + 50) / 100) = 80,000 FREQ=100.0Hz + * MATCH8 ((1000000 + 50) / 100) = 10,000 FREQ=100.0Hz <-- this one + * MATCH64 (( 125000 + 50) / 100) = 1,250 FREQ=100.0Hz + * MATCH256 (( 31250 + 50) / 100) = 313 FREQ=99.8Hz + * MATCH1024 (( 7804 + 50) / 100) = 78 FREQ=100.1Hz + */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. NOTE: This function depends on setup of OSC32 by + * up_clkinitialize(). + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Setup timer 1 compare match A to generate a tick interrupt. + * + * First, setup the match value for compare match A. + */ + + OCR1AH = (uint8_t)((uint16_t)MATCH >> 8); + OCR1AL = (uint8_t)((uint16_t)MATCH & 0xff); + + /* Setup clock source and compare match behaviour. + * + * TCRR1A: + * COM1A 0:1 = 00 -> Normal port operation + * COM1B 0:1 = 00 -> Normal port operation + * COM1C 0:1 = 00 -> Normal port operation + * WGM1 0:1 = 00 -> Clear Timer on Compare (CTC) modes of operation + */ + + TCCR1A = 0; + + /* TCCR1B: + * ICNC1 = 0 -> Input Capture Noise Canceler disabled + * ICES1 = 0 -> Input Capture Edge Select + * WGM 2:3 = 01 -> Clear Timer on Compare (CTC) modes of operation + * CS1 0:2 = xxx ->Selected pre-scaler. + */ + + TCCR1B = (1 << WGM12) | PRESCALE; + + /* Attach the timer interrupt vector */ + + (void)irq_attach(AT90USB_IRQ_T1COMPA, (xcpt_t)up_timerisr); + + /* Enable the interrupt on compare match A */ + + TIMSK1 |= (1 << OCIE1A); +} diff --git a/arch/avr/src/at90usb/at90usb_usbdev.c b/arch/avr/src/at90usb/at90usb_usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..7bfe6639b4cd435442038aba446fadb9796bdc37 --- /dev/null +++ b/arch/avr/src/at90usb/at90usb_usbdev.c @@ -0,0 +1,2970 @@ +/**************************************************************************** + * arch/arm/src/at90usb/at90usb_usbdev.c + * + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ***************************************************************/ +/* PLL Settings are based on F_CPU frequency which is defined in the board.h file */ + +#if (BOARD_CPU_CLOCK == 8000000) +# define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0)) +#elif (BOARD_CPU_CLOCK == 16000000) +# if defined(__AVR_AT90USB647__) +# define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP1)) +# else +# define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP0)) +# endif +#else +# error "Unsuppored CPU clock" +#endif + +/* Debug ***********************************************************************/ + +/* Trace error codes */ + +#define AVR_TRACEERR_ALLOCFAIL 0x0001 +#define AVR_TRACEERR_BADCLREPFEATURE 0x0002 +#define AVR_TRACEERR_BADCLRDEVFEATURE 0x0003 +#define AVR_TRACEERR_BADDEVGETSTATUS 0x0004 +#define AVR_TRACEERR_BADEPNO 0x0005 +#define AVR_TRACEERR_BADEPGETSTATUS 0x0006 +#define AVR_TRACEERR_BADGETCONFIG 0x0007 +#define AVR_TRACEERR_BADGETSETDESC 0x0008 +#define AVR_TRACEERR_BADGETSTATUS 0x0009 +#define AVR_TRACEERR_BADSETADDRESS 0x000a +#define AVR_TRACEERR_BADSETCONFIG 0x000b +#define AVR_TRACEERR_BADSETEPFEATURE 0x000c +#define AVR_TRACEERR_BADSETDEVFEATURE 0x000d +#define AVR_TRACEERR_BINDFAILED 0x000e +#define AVR_TRACEERR_DRIVER 0x000f +#define AVR_TRACEERR_DISPATCHSTALL 0x0010 +#define AVR_TRACEERR_DRIVERREGISTERED 0x0011 +#define AVR_TRACEERR_EPNULLPACKET 0x0012 +#define AVR_TRACEERR_XFERTYPE 0x0013 +#define AVR_TRACEERR_PKTSIZE 0x0014 +#define AVR_TRACEERR_EPCFGBAD 0x0015 +#define AVR_TRACEERR_EP0CFGBAD 0x0016 +#define AVR_TRACEERR_EP0SETUPSTALLED 0x0017 +#define AVR_TRACEERR_EP0RXOUTI 0x0018 +#define AVR_TRACEERR_EP0FIFOFULL 0x0019 +#define AVR_TRACEERR_EP0FIFONOTREADY 0x001a +#define AVR_TRACEERR_INFIFO 0x001b +#define AVR_TRACEERR_INVALIDCTRLREQ 0x001c +#define AVR_TRACEERR_INVALIDPARMS 0x001d +#define AVR_TRACEERR_IRQREGISTRATION 0x001e +#define AVR_TRACEERR_NOEP 0x001f +#define AVR_TRACEERR_NOTCONFIGURED 0x0020 + +/* Trace interrupt codes */ + +#define AVR_TRACEINTID_GENINT 0x0001 +#define AVR_TRACEINTID_EPINT 0x0002 +#define AVR_TRACEINTID_VBUS 0x0003 +#define AVR_TRACEINTID_SUSPEND 0x0004 +#define AVR_TRACEINTID_WAKEUP 0x0005 +#define AVR_TRACEINTID_EOR 0x0006 +#define AVR_TRACEINTID_CLEARFEATURE 0x0007 +#define AVR_TRACEINTID_DEVGETSTATUS 0x0008 +#define AVR_TRACEINTID_DISPATCH 0x0009 +#define AVR_TRACEINTID_EP0SETUP 0x000a +#define AVR_TRACEINTID_EPGETSTATUS 0x000b +#define AVR_TRACEINTID_EPIN 0x000c +#define AVR_TRACEINTID_EPOUT 0x000d +#define AVR_TRACEINTID_EP0SETUPSETADDRESS 0x000e +#define AVR_TRACEINTID_GETCONFIG 0x000f +#define AVR_TRACEINTID_GETSETDESC 0x0010 +#define AVR_TRACEINTID_GETSETIF 0x0011 +#define AVR_TRACEINTID_GETSTATUS 0x0012 +#define AVR_TRACEINTID_IFGETSTATUS 0x0013 +#define AVR_TRACEINTID_SETCONFIG 0x0014 +#define AVR_TRACEINTID_SETFEATURE 0x0015 +#define AVR_TRACEINTID_SYNCHFRAME 0x0016 + +/* Hardware interface **********************************************************/ + +/* Endpoints ******************************************************************/ + +/* Number of endpoints */ + +#define AVR_NENDPOINTS (7) /* ep0-6 */ + +/* Endpoint 0 is special... */ + +#define AVR_EP0 (0) +#define AVR_CTRLEP_SIZE (8) + +/* Bit encoded ep0-6 */ + +#define AVR_ALL_EPS (0x7f) + +/* Endpoint configuration definitions */ + +#define AVR_EPTYPE_CTRL (0 << EPTYPE0) +#define AVR_EPTYPE_ISOC (1 << EPTYPE0) +#define AVR_EPTYPE_BULK (2 << EPTYPE0) +#define AVR_EPTYPE_INTR (3 << EPTYPE0) + +#define AVR_DIR_OUT (0 << EPDIR) +#define AVR_DIR_IN (1 << EPDIR) + +#define AVR_SINGLE_BANK (0 << EPBK0) +#define AVR_DOUBLE_BANK (1 << EPBK0) + +#define AVR_EPSIZE_8 (0 << EPSIZE0) +#define AVR_EPSIZE_16 (1 << EPSIZE0) +#define AVR_EPSIZE_32 (2 << EPSIZE0) +#define AVR_EPSIZE_64 (3 << EPSIZE0) +#define AVR_EPSIZE_128 (4 << EPSIZE0) +#define AVR_EPSIZE_256 (5 << EPSIZE0) + +/* General endpoint defintions */ + +#define AVR_EP0 (0) +#define AVR_NENDPOINTS (7) +#define AVR_EPNO_MASK (3) + +#define AVR_TIMEOUT_LONG (100) +#define AVR_TIMEOUT_SHORT (32) +#define AVR_TIMEOUT_NONE (0) + +/* Request queue operations ****************************************************/ + +#define avr_rqempty(ep) ((ep)->head == NULL) +#define avr_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request may be retained in a list */ + +struct avr_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct avr_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct avr_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct avr_ep_s. */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* AVR-specific fields */ + + struct avr_req_s *head; /* Request list for this endpoint */ + struct avr_req_s *tail; + struct avr_req_s *pending; /* Pending IN request */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t epin:1; /* 1: IN endpoint */ +}; + +/* This structure retains the state of the USB device controller */ + +struct avr_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s to + * struct avr_usbdev_s. */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* AVR-specific fields */ + + uint8_t ep0buf[64]; /* buffer for EP0 short transfers */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t epavail; /* Bitset of available (unconfigured) endpoints */ + uint8_t epinset; /* The set of all configured IN endpoints */ + uint8_t epoutset; /* The set of all configured OUT endpoints */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ +#ifdef CONFIG_USBDEV_SELFPOWERED + uint8_t wkupen:1; /* 1: Wake-up enabled */ +#endif + volatile bool connected; /* Device is connected */ + + /* The endpoint list */ + + struct avr_ep_s eplist[AVR_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Request queue operations ****************************************************/ + +static FAR struct avr_req_s *avr_rqdequeue(FAR struct avr_ep_s *privep); +static inline void avr_rqenqueue(FAR struct avr_ep_s *privep, + FAR struct avr_req_s *req); + +/* Low level data transfers and request operations *****************************/ + +static void avr_txready(void); +static int avr_fifoready(int timeout); +static void avr_ep0send(FAR const uint8_t *buffer, uint16_t buflen); +static inline int avr_epNsend(FAR struct avr_ep_s *privep, + FAR struct avr_req_s *privreq); +static inline int avr_epNrecv(FAR struct avr_ep_s *privep, + FAR struct usbdev_req_s *req); +static int avr_epINqueue(FAR struct avr_ep_s *privep); +static int avr_epOUTqueue(FAR struct avr_ep_s *privep); +static void avr_reqcomplete(FAR struct avr_ep_s *privep, FAR struct avr_req_s *privreq, + int result); +static void avr_cancelrequests(FAR struct avr_ep_s *privep, int status); +static void avr_cancelall(int status); + +/* Endpoint interrupt handling *************************************************/ + +static struct avr_ep_s *avr_epfindbyaddr(uint8_t epno); +static void avr_dispatchrequest(FAR const struct usb_ctrlreq_s *ctrl); +static int avr_ep0configure(void); +static void avr_setaddress(uint8_t address); +static void avr_ep0setup(void); +static int avr_epinterrupt(int irq, FAR void *context); + +/* General interrupt handling **************************************************/ + +static void avr_epreset(FAR struct avr_ep_s *privep, int status); +static void avr_usbreset(void); +static void avr_genvbus(void); +static inline void avr_gensuspend(void); +static void avr_genwakeup(void); +static inline void avr_geneor(void); +static int avr_geninterrupt(int irq, FAR void *context); + +/* USB device controller operations ********************************************/ + +static int avr_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int avr_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *avr_epallocreq(FAR struct usbdev_ep_s *ep); +static void avr_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *avr_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void avr_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif +static int avr_epsubmit(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req); +static int avr_epcancel(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req); +static int avr_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +static FAR struct usbdev_ep_s *avr_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, + uint8_t eptype); +static void avr_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep); +static int avr_getframe(struct usbdev_s *dev); +static int avr_wakeup(struct usbdev_s *dev); +static int avr_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int avr_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct avr_usbdev_s g_usbdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = avr_epconfigure, + .disable = avr_epdisable, + .allocreq = avr_epallocreq, + .freereq = avr_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = avr_epallocbuffer, + .freebuffer = avr_epfreebuffer, +#endif + .submit = avr_epsubmit, + .cancel = avr_epcancel, + .stall = avr_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = avr_allocep, + .freeep = avr_freeep, + .getframe = avr_getframe, + .wakeup = avr_wakeup, + .selfpowered = avr_selfpowered, + .pullup = avr_pullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: avr_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct avr_req_s *avr_rqdequeue(FAR struct avr_ep_s *privep) +{ + FAR struct avr_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: avr_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static inline void avr_rqenqueue(FAR struct avr_ep_s *privep, + FAR struct avr_req_s *req) +{ + req->flink = NULL; + if (!privep->head) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } +} + +/**************************************************************************** + * Name: avr_txready + * + * Description: + * Wait for the selected endpoint to be ready for an IN (TX) transfer + * + ****************************************************************************/ + +static void avr_txready(void) +{ + int retries = 10000; + while (((UEINTX & (1 << TXINI)) == 0) && retries-- > 0); +} + +/**************************************************************************** + * Name: avr_fifoready + * + * Description: + * Wait for the selected endpoint FIFO to be ready + * + ****************************************************************************/ + +static int avr_fifoready(int timeout) +{ + UDINT &= ~(1 << SOFI); + + for (; ; ) + { + /* Check if the FIFO is ready by testing RWAL (read/write allowed). The + * meaning of this bigtdepends on the direction of the endpoint: For an + * OUT endpoint, the RWAL bit is set if the firmware can read data from + * the bank, and cleared by hardware when the bank is empty; For an IN + * endpoint, the RWAL bit is set if the firmware can write data to the + * bank, and cleared by hardware when the bank is full. + */ + + if ((UEINTX & (1 << RWAL)) != 0) + { + return OK; + } + + /* Check if we are still connected and not stalled */ + + if (!(g_usbdev.connected)) + { + return -ENODEV; + } + else if ((UECONX & (1 << STALLRQ)) != 0) + { + return -EAGAIN; + } + + /* Timeing is driven by the start of frame (SOF) interrupt which we + * assume here to be at a one millisecond rate. */ + + if ((UDINT & (1 << SOFI)) != 0) + { + /* Clear the SOF interrupt decrement the count of elapsed + * milliseconds */ + + UDINT &= ~(1 << SOFI); + + if ((timeout--) > 0) + { + /* The timeout has elapsed... return a failure */ + + return -ETIME; + } + } + } +} + +/**************************************************************************** + * Name: avr_ep0send + * + * Description: + * Schedule a short TX transfer for Endpoint 0 + * + * Assumptions: + * - Endpoint 0 is already selected. + * + ****************************************************************************/ + +static void avr_ep0send(FAR const uint8_t *buffer, uint16_t buflen) +{ + FAR const uint8_t *ptr = buffer; + uint8_t regval; + + /* Loop while there are more bytes to send and RXOUTI is clear. RXOUTI is + * set when a new OUT data is received + */ + + while (buflen) + { + /* Verify that RXOUTI is clear. RXOUTI is set when a new OUT data is + * received. In this case, we have not option but to abort the transfer. + */ + + regval = UEINTX; + if ((regval & (1 << RXOUTI)) != 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0RXOUTI), regval); + return; + } + + /* Okay... wait for the selected endpoint to be ready for an TX transfer */ + + avr_txready(); + + /* Now send as many bytes as possible */ + + while (buflen > 0) + { + /* Break out of the loop if the FIFO is full */ + + if (UEBCX == AVR_CTRLEP_SIZE) + { + /* Clearing FIFOCON frees the current bank and switches to the + * following bank. TXINI must be cleared to acknowledge the + * interrupt. + */ + + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0FIFOFULL), regval); + + /* TXINI must always be cleared BEFORE clearing FIFOCON */ + + regval = UEINTX; + regval &= ~(1 << TXINI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + break; + } + + /* Not full, transfer another byte */ + + UEDATX = *ptr++; + buflen--; + } + + /* Clearing FIFOCON frees the current bank and switches to the following + * bank. TXINI must be cleared to acknowledge the interrupt. TXINI must + * always be cleared BEFORE clearing FIFOCON. + */ + + regval = UEINTX; + regval &= ~(1 << TXINI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + } +} + +/**************************************************************************** + * Name: avr_epNsend + * + * Description: + * Perform a TX transfer for Endpoint N + * + ****************************************************************************/ + +static inline int avr_epNsend(FAR struct avr_ep_s *privep, + FAR struct avr_req_s *privreq) +{ + FAR struct usbdev_req_s *req; + FAR const uint8_t *buffer; + uint16_t buflen; + uint16_t len; + uint16_t pktmask; + uint8_t ret; + uint8_t more; + uint8_t regval; + bool zlp; + + /* Check if endpoint is ready for read/write operations */ + + DEBUGASSERT((UEINTX & (1 << RWAL)) != 0); + + /* Setup pointers and counts for this transfer */ + + req = &privreq->req; + buffer = &req->buf[req->xfrd]; + buflen = req->len - req->xfrd; + zlp = ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + pktmask = privep->ep.maxpacket - 1; + + /* Select the endpoint */ + + UENUM = privep->ep.eplog; + + /* This function should not be called if we are not ready to write! */ + + ret = avr_fifoready(AVR_TIMEOUT_LONG); + if (ret != OK) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0FIFOFULL), regval); + return -EAGAIN; + } + + /* Send the USB data. The outer loop handles for each packet of data + * (including zero-length packets) + */ + + do + { + /* Then loop, putting each outgoing byte into the transmit FIFO until + * either (1) all of the data has been sent (len == buflen) or + * (2) the transmit FIFO is full + */ + + len = 0; + while (len < buflen && (UEINTX & (1 << RWAL)) != 0) + { + /* Add another byte to the transmit FIFO */ + + UEDATX = *buffer++; + len++; + } + + /* We now have one complete packet in the transmit FIFO(or maybe two + * packets if dual buffering is enabled). + * + * Clear any pending TXINI interrupts + */ + + UEINT &= ~(1 << privep->ep.eplog); + + /* Clear TXINI and send what is in the transmit FIFO (could be a zero + * length packet). TXINI must always be cleared BEFORE clearing FIFOCON. + */ + + regval = UEINTX; + regval &= ~(1 << TXINI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + + /* Adjust the remaining number of bytes to transfer. */ + + req->xfrd += len; + buffer += len; + buflen -= len; + + usbtrace(TRACE_WRITE(privep->ep.eplog), privreq->req.xfrd); + + /* Check if we need to send a zero length packet (ZLP); We need to send + * a ZLP if the last packet sent was exactly equal to the packet length + * AND if the endpoint is configuration to send ZLPs. However, in dual + * buffer mode, we may have actually just sent two packets so the actual + * check is for a non-zero, transfer of a multiple of the packet + */ + + if (buflen > 0) + { + /* There is more data to be sent */ + + more = true; + } + else if (zlp) + { + /* All of the data has been sent. A ZLP might be needed if the last + * transfer was an exact multiple of the packet size. + */ + + if (len && (len & pktmask) == 0) + { + /* The last packet was not a ZLP and was an example multiple of + * the packet size. A ZLP is needed. + */ + + more = true; + } + else + { + /* The last packet was a ZLP or was a partial packet. We are + * finished with this request. + */ + + more = false; + } + } + else + { + /* No more data to be sent and a ZLP is not needed */ + + more = false; + } + + /* RWAL will be de-asserted when there is no more space in the transmit + * FIFO. We care only if we have more data (or a zero-length-packet) to + * send. Try a short inline wait to see if the FIFO becomes write ready. + * This saves handling an interrupt most of the time (really depends on + * how fast the host takes the data from the transmit FIFO). + */ + + if (more && (ret = avr_fifoready(AVR_TIMEOUT_SHORT))) + { + /* If the endpoint simply did not become ready within the timeout, + * then handle the remainder of the transfer asynchronously in the + * TXINI interrupt handler. */ + + if (ret == -ETIME) + { + /* Enable the endpoint IN interrupt ISR. */ + + UEIENX |= (1 << TXINE); + } + + /* A fatal error occurred while waiting for the IN FIFO to become + * available. + */ + + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INFIFO), regval); + return ret; + } + } + while (more); + return OK; +} + +/**************************************************************************** + * Name: avr_epNrecv + * + * Description: + * Perform an RX transfer for Endpoint N + * + ****************************************************************************/ + +static inline int avr_epNrecv(FAR struct avr_ep_s *privep, + FAR struct usbdev_req_s *req) +{ + FAR uint8_t *buffer; + uint8_t regval; + int ret; + + /* Setup pointers and counts for this transfer */ + + buffer = req->buf; + req->xfrd = 0; + + /* This function should not be called if we are not ready to read! */ + + ret = avr_fifoready(AVR_TIMEOUT_LONG); + if (ret != OK) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0FIFONOTREADY), ret); + return ret; + } + + /* Loop until the requested number of bytes have been read */ + + while (req->xfrd < req->len) + { + /* RWAL will be de-asserted when everything has been read from the + * receive FIFO */ + + if (((UEINTX & (1 << RWAL)) == 0)) + { + /* The FIFO is empty.. Acknowledge receipt of the packet. RXOUTI must + * always be cleared BEFORE clearing FIFOCON. + */ + + regval = UEINTX; + regval &= ~(1 << RXOUTI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + + /* Return success */ + + usbtrace(TRACE_READ(privep->ep.eplog), req->xfrd); + return OK; + } + else + { + /* Receive the next byte */ + + *buffer++ = UEDATX; + + /* Increment the number of bytes received and try again */ + + req->xfrd++; + } + } + + /* We get here if the request buffer is full. There could be more bytes + * pending in the FIFO? + * + * Finalize the OUT stream transfer. RXOUTI must always be cleared BEFORE + * clearing FIFOCON. + */ + + regval = UEINTX; + regval &= ~(1 << RXOUTI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + + usbtrace(TRACE_READ(privep->ep.eplog), req->xfrd); + return OK; +} + +/**************************************************************************** + * Name: avr_epINqueue + * + * Description: + * This is part of the IN endpoint interrupt handling logic. It is called + * from interrupt handling logic for an endpoint when the TXIN endpoint + * interrupt occurs. Thus function is also called from the requeust enqueuing + * logic BUT with interrupts disabled. + * + ****************************************************************************/ + +static int avr_epINqueue(FAR struct avr_ep_s *privep) +{ + FAR struct avr_req_s *privreq; + int ret = OK; + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_EPIN), 0); + + /* First, check if there is already pending IN transfer */ + + if (privep->pending) + { + /* Yes.. use this request to continue the transfer */ + + privreq = privep->pending; + } + else + { + /* No.. remove the next request from the queue of IN requests */ + + privreq = avr_rqdequeue(privep); + privep->pending = privreq; + } + + /* Is there an IN request */ + + if (privreq) + { + /* Yes.. perform the IN transfer */ + + ret = avr_epNsend(privep, privreq); + + /* The return value of -ETIME means that the transfer was not + * finished within this interrupt. We just need to exit with the + * pending transfer in place. + */ + + if (ret == OK || ret != -ETIME) + { + /* The transfer has completed, perhaps with an error. Return the request + * to the class driver. + */ + + usbtrace(TRACE_COMPLETE(privep->ep.eplog), privreq->req.xfrd); + privep->pending = NULL; + avr_reqcomplete(privep, privreq, ret); + } + } + return ret; +} + +/**************************************************************************** + * Name: avr_epOUTqueue + * + * Description: + * This is part of the OUT endpointeinterrupt handling logic. It is called + * from interrupt handling logic for an endpoint when the RXOUT endpoint + * interrupt occurs. + * + ****************************************************************************/ + +static int avr_epOUTqueue(FAR struct avr_ep_s *privep) +{ + FAR struct avr_req_s *privreq; + int ret = OK; + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_EPOUT), 0); + + /* Remove the next request from the queue of OUT requests */ + + privreq = avr_rqdequeue(privep); + + /* Is there an OUT request */ + + if (privreq) + { + /* Yes.. perform the OUT transfer */ + + ret = avr_epNrecv(privep, &privreq->req); + + /* The transfer has completed, perhaps with an error. Return the request + * to the class driver. + */ + + usbtrace(TRACE_COMPLETE(privep->ep.eplog), privreq->req.xfrd); + avr_reqcomplete(privep, privreq, ret); + } + return ret; +} + +/**************************************************************************** + * Name: avr_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void avr_reqcomplete(FAR struct avr_ep_s *privep, FAR struct avr_req_s *privreq, + int result) +{ + /* If endpoint 0, temporarily reflect the state of protocol stalled in the + * callback. */ + + bool stalled = privep->stalled; + if (privep->ep.eplog == AVR_EP0) + { + privep->stalled = g_usbdev.stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: avr_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void avr_cancelrequests(FAR struct avr_ep_s *privep, int status) +{ + /* Is there a pending, active IN transfer? */ + + if (privep->pending) + { + /* Remove the pending request */ + + FAR struct avr_req_s *privreq = privep->pending; + privep->pending = NULL; + + /* Make sure that the endpoint IN interrupt is disabled. */ + + UENUM = privep->ep.eplog; + UEIENX &= ~(1 << TXINE); + + /* Complete the request with the provided status */ + + usbtrace(TRACE_COMPLETE(privep->ep.eplog), privreq->req.xfrd); + avr_reqcomplete(privep, privreq, status); + } + + /* Then complete any queue requests. None of these should be active. */ + + while (!avr_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->ep.eplog), (avr_rqpeek(privep))->req.xfrd); + avr_reqcomplete(privep, avr_rqdequeue(privep), status); + } +} + +/**************************************************************************** + * Name: avr_cancelall + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void avr_cancelall(int status) +{ + struct avr_ep_s *privep; + int i; + + for (i = 1; i < AVR_NENDPOINTS; i++) + { + privep = &g_usbdev.eplist[i]; + if (privep) + { + avr_cancelrequests(privep, status); + } + } +} + +/**************************************************************************** + * Name: avr_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct avr_ep_s *avr_epfindbyaddr(uint8_t epno) +{ + struct avr_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (epno == AVR_EP0) + { + return &g_usbdev.eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < AVR_NENDPOINTS; i++) + { + privep = &g_usbdev.eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (epno == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: avr_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static void avr_dispatchrequest(FAR const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_DISPATCH), 0); + if (g_usbdev.driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(g_usbdev.driver, &g_usbdev.usbdev, ctrl, NULL, 0); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_DISPATCHSTALL), 0); + g_usbdev.stalled = true; + } +} + +/**************************************************************************** + * Name: avr_ep0configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static int avr_ep0configure(void) +{ + FAR struct avr_ep_s *privep = &g_usbdev.eplist[AVR_EP0]; + uint8_t regval; + + /* Configure endpoint 0 */ + + UENUM = AVR_EP0; + UECONX |= (1 << EPEN); + UECFG1X = 0; + UECFG0X = AVR_EPTYPE_CTRL; + UECFG1X = (1 << ALLOC) | AVR_EPSIZE_8; + + /* Check for configuration failure */ + + regval = UESTA0X; + if ((regval & (1 << CFGOK)) == 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0CFGBAD), regval); + return -EINVAL; + } + + /* Initialize the endpoint data structure. Mark EP0 as an IN endpoint so + * that the submit() logic will know that any enqueue packets are to be + * sent. + */ + + memset(privep, 0, sizeof(struct avr_ep_s)); + privep->ep.ops = &g_epops; + privep->ep.maxpacket = AVR_CTRLEP_SIZE; + privep->epin = 1; + + /* Enable OUT interrupts */ + + UEIENX |= (1 << RXOUTE); + return OK; +} + +/**************************************************************************** + * Name: avr_epreset + * + * Description: + * Reset the specified endpoint + * + * Input Parameters: + * epno - The endpoint to be reset + * + ****************************************************************************/ + +static void avr_epreset(FAR struct avr_ep_s *privep, int status) +{ + uint8_t epno = privep->ep.eplog; + + /* Reset the endpoint hardware */ + + UEINT &= ~(1 << epno); + UENUM = epno; + UEIENX = 0; + UEINTX = 0; + UECFG1X &= ~(1 << ALLOC); + UECONX &= ~(1 << EPEN); + + /* Cancel all requests */ + + avr_cancelrequests(privep, status); + + /* Reset endpoint status */ + + privep->stalled = false; +} + +/**************************************************************************** + * Name: avr_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void avr_usbreset(void) +{ + uint8_t epno; + uint8_t regval; + + /* Disable all interrupts */ + + USBCON &= ~((1 << VBUSTE) | (1 << IDTE)); + UDIEN = 0; + + /* Clear all pending interrupts */ + + USBINT = 0; + UDINT = 0; + + /* Reset selected state variables */ + + g_usbdev.connected = false; +#ifdef CONFIG_USBDEV_SELFPOWERED + g_usbdev.wkupen = false; +#endif + + /* Reset endpoints */ + + for (epno = 0; epno < AVR_NENDPOINTS; epno++) + { + struct avr_ep_s *privep = &g_usbdev.eplist[epno]; + avr_epreset(privep, -ESHUTDOWN); + } + + /* Tell the class driver that we are disconnected. The class driver should + * then accept any new configurations. */ + + if (g_usbdev.driver) + { + CLASS_DISCONNECT(g_usbdev.driver, &g_usbdev.usbdev); + } + + /* Enable the PLL */ + + PLLCSR = USB_PLL_PSC; + PLLCSR |= (1 << PLLE); + while ((PLLCSR & (1 << PLOCK)) == 0); + + /* Reset the USB interface */ + + regval = USBCON; + USBCON = (regval & ~(1 << USBE)); + USBCON = (regval | (1 << USBE)); + +#ifndef CONFIG_USB_DISABLE_PADREGULATOR + /* Enable the USB pad regulator */ + + UHWCON |= (1 << UVREGE); +#endif + + /* Enable USB clock inputs */ + + USBCON &= ~(1 << FRZCLK); + + /* Select low or high speed */ + +#ifdef CONFIG_USB_LOWSPEED + UDCON |= (1 << LSM); +#else + UDCON &= ~(1 << LSM); +#endif + + /* Set USB address to 0 */ + + avr_setaddress(0); + + /* EndPoint 0 initialization */ + + (void)avr_ep0configure(); + + /* Enable VBUS interrupts */ + + USBCON |= (1 << VBUSTE); + + /* Attach the device to the USB bus. This announces the device's presence to + * any attached USB host, starting the enumeration process. If no host is + * present, attaching the device will allow for enumeration once a host is + * connected to the device. + */ + + UDCON &= ~(1 << DETACH); + + /* Enable Suspend and reset interrupts */ + + UDIEN |= ((1 << SUSPE) | (1 << EORSTE)); +} + +/**************************************************************************** + * Name: avr_usbshutdown + * + * Description: + * Shutdown the USB interface and put the hardare in a known state + * + ****************************************************************************/ + +void avr_usbshutdown(void) +{ + /* Inform the class driver of the disconnection */ + + if (g_usbdev.driver) + { + CLASS_DISCONNECT(g_usbdev.driver, &g_usbdev.usbdev); + } + + /* Detach the device from the USB bus, terminating communications */ + + UDCON |= (1 << DETACH); + + /* Disable all interrupts */ + + USBCON &= ~((1 << VBUSTE) | (1 << IDTE)); + UDIEN = 0; + + /* Clear all pending interrupts */ + + USBINT = 0; + UDINT = 0; + + g_usbdev.connected = false; +#ifdef CONFIG_USBDEV_REMOTEWAKEUP + g_usbdev.wkupen = false; +#endif + + /* Disable the USB interface */ + + USBCON &= ~(1 << USBE); + + /* Shut down the USB PLL */ + + PLLCSR = 0; + + /* Turn off the VBUS pad */ + + USBCON &= ~(1 << OTGPADE); +} + +/**************************************************************************** + * Name: avr_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static inline void avr_setaddress(uint8_t address) +{ + uint8_t regval; + + g_usbdev.paddr = address; + g_usbdev.paddrset = (address != 0); + + UEINTX &= ~(1 << RXSTPI); + + /* TXINI must always be cleared BEFORE clearing FIFOCON. */ + + regval = UEINTX; + regval &= ~(1 << TXINI); + UEINTX = regval; + regval &= ~(1 << FIFOCON); + UEINTX = regval; + regval = UEINTX; + + avr_txready(); + UDADDR = ((1 << ADDEN) | address); +} + +/**************************************************************************** + * Name: avr_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void avr_ep0setup(void) +{ + struct avr_ep_s *privep; + struct usb_ctrlreq_s ctrl; + uint8_t *ptr; + uint16_t value; + uint16_t index; + uint16_t len; + uint8_t i; + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_EP0SETUP), 0); + + /* Terminate any pending requests */ + + avr_cancelrequests(&g_usbdev.eplist[AVR_EP0], -EPROTO); + avr_cancelrequests(&g_usbdev.eplist[AVR_EP0], -EPROTO); + + /* Assume NOT stalled */ + + g_usbdev.eplist[AVR_EP0].stalled = false; + g_usbdev.eplist[AVR_EP0].stalled = false; + g_usbdev.stalled = false; + + /* Read EP0 setup data -- Read the setup data from the hardware. */ + + ptr = (uint8_t *)&ctrl; + for (i = 0; i < USB_SIZEOF_CTRLREQ; i++) + { + *ptr++ = UEDATX; + } + + /* Extract the little-endian 16-bit values to host order */ + + value = GETUINT16(ctrl.value); + index = GETUINT16(ctrl.index); + len = GETUINT16(ctrl.len); + + ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl.type, ctrl.req, value, index, len); + + /* Dispatch any non-standard requests */ + + if ((ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + avr_dispatchrequest(&ctrl); + } + else + { + /* Handle standard request. Pick off the things of interest to the USB + * device controller driver; pass what is left to the class driver. + */ + + switch (ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 index: zero interface endpoint len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_GETSTATUS), 0); + if (!g_usbdev.paddrset || len != 2 || + (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0) + { + g_usbdev.stalled = true; + } + else + { + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_EPGETSTATUS), 0); + privep = avr_epfindbyaddr(index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADEPGETSTATUS), 0); + g_usbdev.stalled = true; + } + else + { + /* Return endpoint stalled status */ + + if (privep->stalled) + { + g_usbdev.ep0buf[0] = (1 << USB_FEATURE_ENDPOINTHALT); /* Stalled */ + } + else + { + g_usbdev.ep0buf[0] = 0; /* Not stalled */ + } + g_usbdev.ep0buf[1] = 0; + + /* And send the response */ + + avr_ep0send(g_usbdev.ep0buf, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + /* Return self-powered status */ + +#ifdef CONFIG_USBDEV_SELFPOWERED + g_usbdev.ep0buf[0] = (1 << USB_FEATURE_SELFPOWERED); +#else + g_usbdev.ep0buf[0] = 0; +#endif + /* Return remote wake-up enabled status */ + +#ifdef CONFIG_USBDEV_REMOTEWAKEUP + if (g_usbdev.wkupen) + { + status |= (1 << USB_FEATURE_REMOTEWAKEUP); + } +#endif + g_usbdev.ep0buf[1] = 0; + + /* And send the response */ + + avr_ep0send(g_usbdev.ep0buf, 2); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADDEVGETSTATUS), 0); + g_usbdev.stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_IFGETSTATUS), 0); + g_usbdev.ep0buf[0] = 0; + g_usbdev.ep0buf[1] = 0; + + avr_ep0send(g_usbdev.ep0buf, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADGETSTATUS), 0); + g_usbdev.stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector index: zero interface endpoint; len: + * zero, data = none + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_CLEARFEATURE), 0); + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + if (g_usbdev.paddrset != 0 && + value == USB_FEATURE_ENDPOINTHALT && + len == 0 && + (privep = avr_epfindbyaddr(index)) != NULL) + { + avr_epstall(&privep->ep, false); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADCLREPFEATURE), value); + g_usbdev.stalled = true; + } + break; + + case USB_REQ_RECIPIENT_DEVICE: +#ifdef CONFIG_USBDEV_SELFPOWERED + if (g_usbdev.paddrset != 0 && + value == USB_FEATURE_REMOTEWAKEUP && + len == 0) + { + g_usbdev.wkupen = 0; + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADCLRDEVFEATURE), value); + g_usbdev.stalled = true; + } + break; +#endif + + default: + avr_dispatchrequest(&ctrl); + break; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector index: zero interface endpoint; len: 0; + * data = none + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_SETFEATURE), 0); + switch (ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + if (g_usbdev.paddrset != 0 && + value == USB_FEATURE_ENDPOINTHALT && + len == 0 && + (privep = avr_epfindbyaddr(index)) != NULL) + { + avr_epstall(&privep->ep, true); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADSETEPFEATURE), value); + g_usbdev.stalled = true; + } + break; + + case USB_REQ_RECIPIENT_DEVICE: +#ifdef CONFIG_USBDEV_SELFPOWERED + if (value == USB_FEATURE_TESTMODE) + { + ullvdbg("test mode: %d\n", index); + } + else if (value == USB_FEATURE_REMOTEWAKEUP) + { + g_usbdev.wkupen = 1; + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADSETDEVFEATURE), value); + g_usbdev.stalled = true; + } + break; +#endif + + default: + avr_dispatchrequest(&ctrl); + break; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device value: device address + * index: 0 len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_EP0SETUPSETADDRESS), value); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && + len == 0 && + value < 128) + { + /* Save the address */ + + avr_setaddress(ctrl.value[0]); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADSETADDRESS), 0); + g_usbdev.stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device value: descriptor type + * and index index: 0 or language ID; len: descriptor len; data = + * descriptor. + */ + + case USB_REQ_SETDESCRIPTOR: + { + /* type: host-to-device; recipient = device value: descriptor type + * and index index: 0 or language ID; len: descriptor len; data = + * descriptor + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_GETSETDESC), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + avr_dispatchrequest(&ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADGETSETDESC), 0); + g_usbdev.stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + { + /* type: device-to-host; recipient = device value: 0; index: 0; len: + * 1; data = configuration value + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_GETCONFIG), 0); + if (g_usbdev.paddrset && + (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value == 0 && + index == 0 && + len == 1) + { + avr_dispatchrequest(&ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADGETCONFIG), 0); + g_usbdev.stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + { + /* type: host-to-device; recipient = device value: configuration + * value index: 0; len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_SETCONFIG), 0); + if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index == 0 && + len == 0) + { + avr_dispatchrequest(&ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADSETCONFIG), 0); + g_usbdev.stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface value: 0 index: + * interface; len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + { + /* type: host-to-device; recipient = interface value: alternate + * setting index: interface; len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_GETSETIF), 0); + avr_dispatchrequest(&ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + { + /* type: device-to-host; recipient = endpoint value: 0 index: + * endpoint; len: 2; data = frame number + */ + + usbtrace(TRACE_INTDECODE(AVR_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDCTRLREQ), 0); + g_usbdev.stalled = true; + } + break; + } + } + + if (g_usbdev.stalled) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EP0SETUPSTALLED), 0); + avr_epstall(&g_usbdev.eplist[AVR_EP0].ep, false); + avr_epstall(&g_usbdev.eplist[AVR_EP0].ep, false); + } + + if ((UEINTX & (1 << RXSTPI)) != 0) + { + UECONX |= (1 << STALLRQ); + UEINTX &= ~(1 << RXSTPI); + } +} + +/**************************************************************************** + * Name: avr_ep0interrupt + * + * Description: + * USB endpoint/pipe IN interrupt handler + * + ****************************************************************************/ + +static inline void avr_ep0interrupt(void) +{ + /* Check if the control endpoint endpoint is pending */ + + if ((UEINT & (1 << AVR_EP0)) != 0) + { + /* Clear the endpoint interrupt */ + + UEINT &= ~(1 << AVR_EP0); + + /* Select the control endpoint */ + + UENUM = AVR_EP0; + + /* Check if the control endpoint has received a setup packet */ + + if ((UEINTX & (1 << RXSTPI)) != 0) + { + /* It has... process the control packet */ + + avr_ep0setup(); + } + + /* Handshake the endpoint setup interrupt */ + + UEINTX &= ~(1 << RXSTPI); + } +} + +/**************************************************************************** + * Name: avr_epNinterrupt + * + * Description: + * USB endpoint/pipe IN interrupt handler + * + ****************************************************************************/ + +static inline void avr_epNinterrupt(void) +{ + struct avr_ep_s *privep; + uint8_t ueint = UEINT & (g_usbdev.epoutset | g_usbdev.epinset); + uint8_t epno; + uint8_t mask; + + /* Check if any endpoint interrupt is pending */ + + for (epno = 1, mask = 2; epno < AVR_NENDPOINTS && ueint != 0; epno++, mask <<= 1) + { + /* Is there an interrupt pending on this endpoint? */ + + if ((ueint & mask) != 0) + { + ueint &= ~mask; + + /* Select the endpoint */ + + UENUM = epno; + privep = &g_usbdev.eplist[epno]; + + /* Is this an IN or an OUT interrupt? */ + + if (privep->epin) + { + /* Clear the endpoint IN interrupt flag (TXINI) */ + + UEINTX &= ~(1 << TXINI); + + /* Are IN endpoint interrupts enabled? */ + + if ((UEIENX & (1 << TXINE)) != 0) + { + /* Clear the endpoint interrupt */ + + UEINT &= ~(1 << epno); + + /* Handle the IN request queue */ + + (void)avr_epINqueue(privep); + } + } + else + { + /* Is is an OUT endpoint interrupt. Are OUT endpoint + * interrupts enabled? + */ + + if ((UEIENX & (1 << RXOUTE)) != 0) + { + /* Clear the endpoint interrupt */ + + UEINT &= ~(1 << epno); + + /* Handle the OUT request queue */ + + (void)avr_epOUTqueue(privep); + } + } + } + } +} + +/**************************************************************************** + * Name: avr_epinterrupt + * + * Description: + * USB endpoint/pipe interrupt handler + * + ****************************************************************************/ + +static int avr_epinterrupt(int irq, FAR void *context) +{ + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_EPINT), irq); + + /* Handle control endpoint interrupts */ + + avr_ep0interrupt(); + + /* Handle opther endpoint interrupts (N=1,2,..6 */ + + avr_epNinterrupt(); + + usbtrace(TRACE_INTEXIT(AVR_TRACEINTID_EPINT), irq); + return OK; +} + +/**************************************************************************** + * Name: avr_genvbus + * + * Description: + * A change in VBUS has been detected. Check if the device has been + * connected to or disconnected from a host. + * + ****************************************************************************/ + +static void avr_genvbus(void) +{ + bool vbus; + + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_VBUS), USBSTA); + + /* How has the VSUS signal changed? */ + + vbus = ((USBSTA & (1 << VBUS)) != 0); + if (!g_usbdev.connected && vbus) + { + /* We were not connected, but now we are */ + + avr_usbreset(); + g_usbdev.connected = true; + } + else if (g_usbdev.connected && !vbus) + { + /* We were connected, but now we are not */ + /* Cancel all pending and queue requests */ + + avr_cancelall(-ENODEV); + + /* Detach the device from the USB bus, terminating communications */ + + UDCON |= (1 << DETACH); + + /* Disable the clock inputs (the ”Resume Detection” is still active). + * This reduces the power consumption. Clear to enable the clock inputs. */ + + USBCON |= (1 << FRZCLK); + + /* Shut down the USB PLL */ + + PLLCSR = 0; + + /* Disable the USB pad regulator */ + + UHWCON &= ~(1 << UVREGE); + g_usbdev.connected = false; + } +} + +/**************************************************************************** + * Name: avr_gensuspend + * + * Description: + * The USB controller has been put in suspend mode. + * + ****************************************************************************/ + +static inline void avr_gensuspend(void) +{ + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_SUSPEND), UDIEN); + + /* Notify the class driver of the suspend event */ + + if (g_usbdev.driver) + { + CLASS_SUSPEND(g_usbdev.driver, &g_usbdev.usbdev); + } + + /* Disable suspend event interrupts; enable wakeup event interrupt */ + + UDIEN &= ~(1 << SUSPE); + UDIEN |= (1 << WAKEUPE); + + /* Disable the clock inputs to reduce power consumption. (wakeup + * detection is still active). + */ + + USBCON |= (1 << FRZCLK); + + /* And shut down the USB PLL */ + + PLLCSR = 0; +} + +/**************************************************************************** + * Name: avr_genwakeup + * + * Description: + * Resume from suspend mode. + * + ****************************************************************************/ + +static void avr_genwakeup(void) +{ + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_WAKEUP), UDIEN); + + /* Re-enable the PLL */ + + PLLCSR = USB_PLL_PSC; + PLLCSR |= (1 << PLLE); + while ((PLLCSR & (1 << PLOCK)) == 0); + + /* Re-enable USB clock inputs */ + + USBCON &= ~(1 << FRZCLK); + UDIEN &= ~(1 << WAKEUPE); + UDIEN |= (1 << SUSPE); + + /* Notify the class driver of the resume event */ + + if (g_usbdev.driver) + { + CLASS_RESUME(g_usbdev.driver, &g_usbdev.usbdev); + } +} + +/**************************************************************************** + * Name: avr_geneor + * + * Description: + * Handle an end-of-reset interrupt + * + ****************************************************************************/ + +static inline void avr_geneor(void) +{ + uint8_t epno; + + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_EOR), UDIEN); + + UDIEN &= ~(1 << SUSPE); + UDIEN |= (1 << WAKEUPE); + + /* Reset all endpoints and reconfigure endpoint 0 */ + + UEINT = 0; + for (epno = 0; epno < AVR_NENDPOINTS; epno++) + { + struct avr_ep_s *privep = &g_usbdev.eplist[epno]; + avr_epreset(privep, -EAGAIN); + } + + usbtrace(TRACE_EPCONFIGURE, AVR_EP0); + + /* Configure endpoint 0 */ + + (void)avr_ep0configure(); + + /* Reset endpoint status */ + + g_usbdev.stalled = false; + + /* Enable the endpoint SETUP interrupt ISR for the control endpoint */ + + UEIENX |= (1 << RXSTPE); +} + +/**************************************************************************** + * Name: avr_geninterrupt + * + * Description: + * USB general interrupt handler + * + ****************************************************************************/ + +static int avr_geninterrupt(int irq, FAR void *context) +{ + usbtrace(TRACE_INTENTRY(AVR_TRACEINTID_GENINT), irq); + + /* Check for a change in VBUS state detected */ + + if ((USBINT & (1 << VBUSTI)) != 0 && (USBCON & (1 << VBUSTE)) != 0) + { + USBINT &= ~(1 << VBUSTI); + avr_genvbus(); + } + + /* Check for a suspend event */ + + if ((UDINT & (1 << SUSPI)) != 0 && (UDIEN & (1 << SUSPE)) != 0) + { + UDINT &= ~(1 << SUSPI); + avr_gensuspend(); + } + + /* Check for a wake-up event */ + + if ((UDINT & (1 << WAKEUPI)) != 0 && (UDIEN & (1 << WAKEUPE)) != 0) + { + UDINT &= ~(1 << WAKEUPI); + avr_genwakeup(); + } + + /* Check for an end-of-reset, speed identification interrupt */ + + if ((UDINT & (1 << EORSTI)) != 0 && (UDIEN & (1 << EORSTE)) != 0) + { + UDINT &= ~(1 << EORSTI); + avr_geneor(); + } + + usbtrace(TRACE_INTEXIT(AVR_TRACEINTID_GENINT), irq); + return OK; +} + +/**************************************************************************** + * Name: avr_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int avr_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, bool last) +{ + FAR struct avr_ep_s *privep = (FAR struct avr_ep_s *)ep; + uint16_t maxpacket = GETUINT16(desc->mxpacketsize); + uint8_t uecfg0x; + uint8_t uecfg1x; + uint8_t ueienx = 0; + uint8_t regval; + + usbtrace(TRACE_EPCONFIGURE, ep->eplog); + DEBUGASSERT(ep->eplog != 0 && desc->addr == ep->eplog); + + /* Configure the endpoint */ + + uecfg0x = 0; + uecfg1x = (1 << ALLOC); + + /* Handle the endpoint type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: + uecfg0x |= AVR_EPTYPE_CTRL; + break; + + case USB_EP_ATTR_XFER_ISOC: + uecfg0x |= AVR_EPTYPE_ISOC; + break; + + case USB_EP_ATTR_XFER_BULK: + uecfg0x |= AVR_EPTYPE_BULK; + break; + + case USB_EP_ATTR_XFER_INT: + uecfg0x |= AVR_EPTYPE_INTR; + break; + + default: + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_XFERTYPE), desc->attr); + return -EINVAL; + } + + /* Handle the endpoint direction */ + + if (USB_ISEPIN(desc->addr)) + { + DEBUGASSERT(privep->epin != 0); + uecfg0x |= AVR_DIR_IN; + ueienx = (1 << RXOUTE); + } + else + { + DEBUGASSERT(privep->epin == 0); + } + + /* Handle banking (this needs to be revisited... Always double bank?) */ + + uecfg1x |= AVR_DOUBLE_BANK; + + /* Handle the maximum packet size */ + + switch (maxpacket) + { + case 8: + uecfg1x |= AVR_EPSIZE_8; + break; + case 16: + uecfg1x |= AVR_EPSIZE_16; + break; + case 32: + uecfg1x |= AVR_EPSIZE_32; + break; + case 64: + uecfg1x |= AVR_EPSIZE_64; + break; + case 128: + uecfg1x |= AVR_EPSIZE_128; + break; + case 256: + if (ep->eplog == 1) + { + uecfg1x |= AVR_EPSIZE_8; + break; + } + default: + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_PKTSIZE), maxpacket); + return -EINVAL; + } + + /* Instantiate the configuration */ + + UENUM = ep->eplog; + UECONX |= (1 << EPEN); + UECFG1X = 0; + UECFG0X = uecfg0x; + UECFG1X = uecfg1x; + + /* Check for configuration failure */ + + regval = UESTA0X; + if ((regval & (1 << CFGOK)) == 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EPCFGBAD), regval); + return -EINVAL; + } + + /* Save the new max packet size and reset endpoint status */ + + privep->ep.maxpacket = maxpacket; + privep->stalled = 0; + + /* Enable interrupts as appropriate for this endpoint */ + + UEIENX |= ueienx; + return OK; +} + +/**************************************************************************** + * Name: avr_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int avr_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct avr_ep_s *privep = (FAR struct avr_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + usbtrace(TRACE_EPDISABLE, privep->ep.eplog); + + flags = enter_critical_section(); + + /* Disable the endpoint */ + + avr_epreset(privep, -ESHUTDOWN); + g_usbdev.stalled = true; + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: avr_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *avr_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct avr_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, ((FAR struct avr_ep_s *)ep)->ep.eplog); + + privreq = (FAR struct avr_req_s *)kmm_malloc(sizeof(struct avr_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct avr_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: avr_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void avr_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct avr_req_s *privreq = (FAR struct avr_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct avr_ep_s *)ep)->ep.eplog); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: avr_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *avr_epallocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->ep.eplog); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: avr_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void avr_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->ep.eplog); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: avr_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int avr_epsubmit(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct avr_req_s *privreq = (FAR struct avr_req_s *)req; + FAR struct avr_ep_s *privep = (FAR struct avr_ep_s *)ep; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + ullvdbg("req=%p callback=%p buf=%p ep=%p\n", + req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->ep.eplog); + + if (!g_usbdev.driver || g_usbdev.usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_NOTCONFIGURED), g_usbdev.usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (g_usbdev.stalled) + { + ret = -EBUSY; + } + + /* Ignore any attempt to enqueue a zero length packet */ + + else if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_EPNULLPACKET), 0); + ret = -EINVAL; + } + else + { + /* Add the new request to the request queue for the endpoint */ + + avr_rqenqueue(privep, privreq); + + /* Some special operations have to be performed for IN requests. For + * these, we may have to initiate the next transfer. + */ + + if (privep->epin) + { + /* It is an IN transfer */ + + usbtrace(TRACE_INREQQUEUED(privep->ep.eplog), privreq->req.len); + + /* Is there an IN transfer in progress (waiting for the FIFO)? If + * not and if the FIFO is available now, then start the next + * IN transfer. + */ + + if (!privep->pending && avr_fifoready(AVR_TIMEOUT_NONE) == OK) + { + /* No, then start the next IN transfer */ + + ret = avr_epINqueue(privep); + } + } + else + { + /* It is an OUT transfer */ + + usbtrace(TRACE_OUTREQQUEUED(privep->ep.eplog), privreq->req.len); + + /* If there is something avaible in the fifo now, then go get it */ + + if (avr_fifoready(AVR_TIMEOUT_NONE) == OK); + { + ret = avr_epOUTqueue(privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: avr_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int avr_epcancel(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct avr_ep_s *privep = (FAR struct avr_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->ep.eplog); + + /* FIXME: if the request is the first, then we need to flush the EP otherwise + * just remove it from the list but ... all other implementations cancel all + * requests ... */ + + flags = enter_critical_section(); + avr_cancelrequests(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: avr_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int avr_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + if (resume) + { + /* Clear stall and reset the data toggle */ + + UECONX |= (1 << STALLRQC); + UERST = (1 << ep->eplog); + UERST = 0; + UECONX |= (1 << RSTDT); + g_usbdev.stalled = false; + } + else + { + UECONX |= (1 << STALLRQ); + g_usbdev.stalled = true; + } + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: avr_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *avr_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, + uint8_t eptype) +{ + FAR struct avr_ep_s *privep; + irqstate_t flags; + uint8_t epset = g_usbdev.epavail; + uint8_t epmask; + uint8_t epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, epno); + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the + * requested 'logical' endpoint. + */ + +#ifdef CONFIG_DEBUG + if (epno >= AVR_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } +#endif + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. */ + + epset &= (1 << epno); + } + + /* Are any endpoints available? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + + /* Select the lowest bit in the set of matching, available endpoints */ + + for (epndx = 1; epndx < AVR_NENDPOINTS; epndx++) + { + epmask = 1 << epndx; + if ((epset & epmask) != 0) + { + /* Initialize the endpoint structure */ + + privep = &g_usbdev.eplist[epndx]; + memset(privep, 0, sizeof(struct avr_ep_s)); + + privep->ep.ops = &g_epops; + privep->ep.eplog = epndx; + privep->ep.maxpacket = (epndx == 1) ? 256 : 64; + + /* Mark the IN/OUT endpoint no longer available */ + + g_usbdev.epavail &= ~epmask; + if (in) + { + g_usbdev.epinset |= epmask; + privep->epin = 1; + } + else + { + g_usbdev.epoutset |= epmask; + privep->epin = 0; + } + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return &privep->ep; + } + } + + /* Shouldn't get here */ + + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_NOEP), (uint16_t) epno); + return NULL; +} + +/**************************************************************************** + * Name: avr_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void avr_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct avr_ep_s *privep = (FAR struct avr_ep_s *)ep; + irqstate_t flags; + uint8_t epmask; + + usbtrace(TRACE_DEVFREEEP, (uint16_t) privep->ep.eplog); + + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + epmask = (1 << privep->ep.eplog); + g_usbdev.epavail |= epmask; + g_usbdev.epinset &= ~epmask; + g_usbdev.epoutset &= ~epmask; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: avr_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int avr_getframe(struct usbdev_s *dev) +{ + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, 0); + return (int)UDFNUMH << 8 | (int)UDFNUML; +} + +/**************************************************************************** + * Name: avr_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int avr_wakeup(struct usbdev_s *dev) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + flags = enter_critical_section(); + avr_genwakeup(); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: avr_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int avr_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t) selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + g_usbdev.selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: avr_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int avr_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t) enable); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + usbtrace(TRACE_DEVINIT, 0); + + /* Initialize the device state structure */ + + memset(&g_usbdev, 0, sizeof(struct avr_usbdev_s)); + g_usbdev.usbdev.ops = &g_devops; + g_usbdev.usbdev.ep0 = &g_usbdev.eplist[AVR_EP0].ep; + g_usbdev.epavail = AVR_ALL_EPS & ~(1 << AVR_EP0); + + /* Attach USB controller general interrupt handler */ + + if (irq_attach(AT90USB_IRQ_USBGEN, avr_geninterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_IRQREGISTRATION), AT90USB_IRQ_USBGEN); + goto errout; + } + + /* Attach USB controller endpoint/pipe interrupt handler */ + + if (irq_attach(AT90USB_IRQ_USBEP, avr_epinterrupt) != 0) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_IRQREGISTRATION), AT90USB_IRQ_USBEP); + goto errout; + } + + /* Shutdown the USB interface to put it in a known initial state */ + + avr_usbshutdown(); + + /* Select USB device mode */ + + UHWCON |= (1 << UIMOD); + + /* Reset the interface to force re-enumeration (the reset operation + * enables interrupts. + */ + + avr_usbreset(); + + /* Set the VBUS pad */ + + USBCON |= (1 << OTGPADE); + + /* Disconnect device */ + + avr_pullup(&g_usbdev.usbdev, false); + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(g_usbdev.driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + avr_pullup(&g_usbdev.usbdev, false); + g_usbdev.usbdev.speed = USB_SPEED_UNKNOWN; + + /* Detach IRQs */ + + irq_detach(AT90USB_IRQ_USBGEN); + irq_detach(AT90USB_IRQ_USBEP); + + /* Shutdown the USB controller hardware */ + + avr_usbshutdown(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_BINDFAILED), (uint16_t) - ret); + g_usbdev.driver = NULL; + } + else + { + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set the RS + * bit to enable the controller. It kind of makes sense to do this + * after the class has bound to us... GEN: This bug is really in the + * class driver. It should make the soft connect when it is ready to be + * enumerated. I have added that logic to the class drivers but left + * this logic here. */ + + avr_pullup(&g_usbdev.usbdev, true); + } + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(AVR_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} + +/**************************************************************************** + * Name: avr_pollvbus + * + * Description: + * Sample VBUS to see if there are changes in our connection status. There + * is actually an interrupt to signal this case so it should not be necessary + * to poll our connection status. However, on certain "noisy" systems, VBUS + * may bounce and provide inaccurate information in the interrupt handler + * (especially if a relay is used to switch VBUS!). This poll is, then, + * simply a failsafe to assure that VBUS connection events are never missed. + * + ****************************************************************************/ + +#ifdef CONFIG_USB_NOISYVBUS +void avr_pollvbus(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + avr_genvbus(); + leave_critical_section(flags); +} +#endif \ No newline at end of file diff --git a/arch/avr/src/at90usb/chip.h b/arch/avr/src/at90usb/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..4e3ec8297b1de4cdffc4a9b94c52cb859ede8c56 --- /dev/null +++ b/arch/avr/src/at90usb/chip.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/avr/src/at90usb/chip.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_CHIP_H +#define __ARCH_AVR_SRC_ATMEGA_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Define features for supported chip in the ATMEGA family */ + +#if defined(CONFIG_ARCH_CHIP_AT90USB646) +# define AVR_FLASH_SIZE (64*1024) +# define AVR_SRAM_SIZE (4*1024) +# define AVR_EEPROM_SIZE (2*1024) +# define HAVE_USBDEV 1 +# undef HAVE_USBHOST +# undef HAVE_RAMPZ +#elif defined(CONFIG_ARCH_CHIP_AT90USB647) +# define AVR_FLASH_SIZE (64*1024) +# define AVR_SRAM_SIZE (4*1024) +# define AVR_EEPROM_SIZE (2*1024) +# define HAVE_USBDEV 1 +# define HAVE_USBHOST 1 +# undef HAVE_RAMPZ +#elif defined(CONFIG_ARCH_CHIP_AT90USB1286) +# define AVR_FLASH_SIZE (128*1024) +# define AVR_SRAM_SIZE (8*1024) +# define AVR_EEPROM_SIZE (4*1024) +# define HAVE_USBDEV 1 +# undef HAVE_USBHOST +# define HAVE_RAMPZ 1 +#elif defined(CONFIG_ARCH_CHIP_AT90USB1287) +# define AVR_FLASH_SIZE (128*1024) +# define AVR_SRAM_SIZE (8*1024) +# define AVR_EEPROM_SIZE (4*1024) +# define HAVE_USBDEV 1 +# define HAVE_USBHOST 1 +# define HAVE_RAMPZ 1 +#else +# error "Unsupported AVR chip" +#endif + +/* Include only the memory map. Other chip hardware files should then include this + * file for the proper setup + */ + +#include "at90usb_memorymap.h" + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_CHIP_H */ + diff --git a/arch/avr/src/atmega/Kconfig b/arch/avr/src/atmega/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..8c3d6c014561acef8be3029dcbfd6faca182d5c2 --- /dev/null +++ b/arch/avr/src/atmega/Kconfig @@ -0,0 +1,55 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_ATMEGA +comment "ATMega Configuration Options" + +choice + prompt "Atmel ATmega chip selection" + default ARCH_CHIP_ATMEGA128 + +config ARCH_CHIP_ATMEGA128 + bool "ATMega128" + ---help--- + Atmel ATMega128 8-bit AVR. + +config ARCH_CHIP_ATMEGA1284P + bool "ATMega1284P" + ---help--- + Atmel ATMega1284P 8-bit AVR. + +config ARCH_CHIP_ATMEGA2560 + bool "ATMega2560" + ---help--- + Atmel ATMega2560 8-bit AVR. + +endchoice # ATMega Configuration Options + +menu "ATMega Peripheral Selections" + +config AVR_USART0 + bool "USART0" + select ARCH_HAVE_USART0 + +config AVR_USART1 + bool "USART1" + select ARCH_HAVE_USART1 + +endmenu # ATMega Peripheral Selections + +menu "Low level USART driver options" + depends on AVR_USART0 || AVR_USART1 + +config SERIAL_TERMIOS + bool "Serial driver TERMIOS supported" + depends on AVR_USART0 || AVR_USART1 + default n + ---help--- + Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). + If this is not defined, then the terminal settings (baud, parity, etc). + are not configurable at runtime; serial streams cannot be flushed, etc.. + +endmenu +endif diff --git a/arch/avr/src/atmega/Make.defs b/arch/avr/src/atmega/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..c2d679b7db779c2fcc98b93cc7f235e48f42e536 --- /dev/null +++ b/arch/avr/src/atmega/Make.defs @@ -0,0 +1,82 @@ +############################################################################ +# arch/avr/src/atmega/Make.defs +# +# Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = atmega_head.S + +# Common AVR files + +CMN_ASRCS = up_switchcontext.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_irq.c up_lowputs.c +CMN_CSRCS += up_mdelay.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_puts.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_sigdeliver.c +CMN_CSRCS += up_stackframe.c up_udelay.c up_unblocktask.c up_usestack.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARCH_STACKDUMP),y) +CMN_CSRCS += up_dumpstate.c +endif + +ifeq ($(CONFIG_AVR_SPI),y) +CMN_CSRCS += up_spi.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ARCH_ROMGETC),y) +CMN_CSRCS += up_romgetc.c +endif + +# Required ATMEGA files + +CHIP_ASRCS = atmega_exceptions.S +CHIP_CSRCS = atmega_lowconsole.c atmega_lowinit.c atmega_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += atmega_timerisr.c +endif + +# Configuration-dependent ATMEGA files + +ifeq ($(CONFIG_AVR_GPIOIRQ),y) +CHIP_CSRCS += +endif diff --git a/arch/avr/src/atmega/atmega.h b/arch/avr/src/atmega/atmega.h new file mode 100644 index 0000000000000000000000000000000000000000..621e6f335ef09449f10e0a9e545a1a2b5763cb31 --- /dev/null +++ b/arch/avr/src/atmega/atmega.h @@ -0,0 +1,214 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "atmega_config.h" + +#ifdef CONFIG_AVR_GPIOIRQ +# include +#endif + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_clkinit + * + * Description: + * Initialiaze clock/PLL settings per the definitions in the board.h file. + * + ****************************************************************************/ + +void up_clkinitialize(void); + +/**************************************************************************** + * Name: usart0_reset and usart1_reset + * + * Description: + * Reset USART0 or USART1. + * + ****************************************************************************/ + +void usart0_reset(void); +void usart1_reset(void); + +/**************************************************************************** + * Name: usart0_configure and usart1_configure + * + * Description: + * Configure USART0 or USART1. + * + ****************************************************************************/ + +void usart0_configure(void); +void usart1_configure(void); + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initializeation sequence to configure the serial console + * uart (only). + * + ****************************************************************************/ + +void up_consoleinit(void); + +/**************************************************************************** + * Name: atmega_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the + * directory configs//src. + * + ****************************************************************************/ + +void atmega_boardinitialize(void); + +/**************************************************************************** + * Name: gpio_irqinitialize + * + * Description: + * Initialize all vectors to the unexpected interrupt handler + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + * Assumptions: + * Called during the early boot sequence before global interrupts have + * been enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void weak_function gpio_irqinitialize(void); +#endif + +/**************************************************************************** + * Name: gpio_irqattach + * + * Description: + * Attach in GPIO interrupt to the provide 'isr' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +int gpio_irqattach(int irq, xcpt_t newisr, xcpt_t *oldisr); +#endif + +/**************************************************************************** + * Name: gpio_irqenable + * + * Description: + * Enable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void gpio_irqenable(int irq); +#endif + +/**************************************************************************** + * Name: gpio_irqdisable + * + * Description: + * Disable the GPIO IRQ specified by 'irq' + * + * Configuration Notes: + * Configuration CONFIG_AVR_GPIOIRQ must be selected to enable the + * overall GPIO IRQ feature. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_GPIOIRQ +void gpio_irqdisable(int irq); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_H */ + diff --git a/arch/avr/src/atmega/atmega_config.h b/arch/avr/src/atmega/atmega_config.h new file mode 100644 index 0000000000000000000000000000000000000000..0390f1c129fb05e8bd41bbe3cc13a79c2dc2f0eb --- /dev/null +++ b/arch/avr/src/atmega/atmega_config.h @@ -0,0 +1,129 @@ +/************************************************************************************ + * arch/avr/src/atmega/atmega_config.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* USARTs ***************************************************************************/ +/* Check if any USART is selected */ + +#undef HAVE_USART_DEVICE +#if defined(CONFIG_AVR_USART0) || defined(CONFIG_AVR_USART1) +# define HAVE_USART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It + * could be on any USARTn, n=0,1 + */ + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_AVR_USART0) +# undef CONFIG_USART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_AVR_USART1) +# undef CONFIG_USART0_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_USART0_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# elif defined(HAVE_USART_DEVICE) +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# else +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_CONFIG_H */ + diff --git a/arch/avr/src/atmega/atmega_exceptions.S b/arch/avr/src/atmega/atmega_exceptions.S new file mode 100644 index 0000000000000000000000000000000000000000..468ae9ac72047e8627729b2a1e952eb3ab5d67f4 --- /dev/null +++ b/arch/avr/src/atmega/atmega_exceptions.S @@ -0,0 +1,265 @@ +/******************************************************************************************** + * arch/avr/src/atmega/atmega_exceptions.S + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include + +#include "excptmacros.h" + +/******************************************************************************************** + * External Symbols + ********************************************************************************************/ + + .file "atmega_exceptions.S" + .global up_doirq + .global up_fullcontextrestore + +/******************************************************************************************** + * Macros + ********************************************************************************************/ + +/******************************************************************************************** + * Exception Vector Handlers + ********************************************************************************************/ + + .section .handlers, "ax", @progbits + +#if defined(CONFIG_ARCH_CHIP_ATMEGA128) + HANDLER atmega_int0, ATMEGA_IRQ_INT0, excpt_common /* External interrupt request 0 */ + HANDLER atmega_int1, ATMEGA_IRQ_INT1, excpt_common /* External interrupt request 1 */ + HANDLER atmega_int2, ATMEGA_IRQ_INT2, excpt_common /* External interrupt request 2 */ + HANDLER atmega_int3, ATMEGA_IRQ_INT3, excpt_common /* External interrupt request 3 */ + HANDLER atmega_int4, ATMEGA_IRQ_INT4, excpt_common /* External interrupt request 4 */ + HANDLER atmega_int5, ATMEGA_IRQ_INT5, excpt_common /* External interrupt request 5 */ + HANDLER atmega_int6, ATMEGA_IRQ_INT6, excpt_common /* External interrupt request 6 */ + HANDLER atmega_int7, ATMEGA_IRQ_INT7, excpt_common /* External interrupt request 7 */ + HANDLER atmega_t2comp, ATMEGA_IRQ_T2COMP, excpt_common /* TIMER2 COMP timer/counter2 compare match */ + HANDLER atmega_t2ovf, ATMEGA_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ + HANDLER atmega_t1capt, ATMEGA_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ + HANDLER atmega_t1compa, ATMEGA_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match a */ + HANDLER atmega_t1compb, ATMEGA_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match b */ + HANDLER atmega_t1ovf, ATMEGA_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ + HANDLER atmega_t0comp, ATMEGA_IRQ_T0COMP, excpt_common /* TIMER0 COMP timer/counter0 compare match */ + HANDLER atmega_t0ovf, ATMEGA_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ + HANDLER atmega_spi, ATMEGA_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ + HANDLER atmega_u0rx, ATMEGA_IRQ_U0RX, excpt_common /* USART0 RX complete */ + HANDLER atmega_u0dre, ATMEGA_IRQ_U0DRE, excpt_common /* USART0 data register empty */ + HANDLER atmega_u0tx, ATMEGA_IRQ_U0TX, excpt_common /* USART0 TX complete */ + HANDLER atmega_adc, ATMEGA_IRQ_ADC, excpt_common /* ADC conversion complete */ + HANDLER atmega_ee, ATMEGA_IRQ_EE, excpt_common /* EEPROM ready */ + HANDLER atmega_anacomp, ATMEGA_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ + HANDLER atmega_t1compc, ATMEGA_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/countre1 compare match c */ + HANDLER atmega_t3capt, ATMEGA_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ + HANDLER atmega_t3compa, ATMEGA_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ + HANDLER atmega_t3compb, ATMEGA_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ + HANDLER atmega_t3compc, ATMEGA_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ + HANDLER atmega_t3ovf, ATMEGA_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ + HANDLER atmega_u1rx, ATMEGA_IRQ_U1RX, excpt_common /* USART1 RX complete */ + HANDLER atmega_u1dre, ATMEGA_IRQ_U1DRE, excpt_common /* USART1 data register empty */ + HANDLER atmega_u1tx, ATMEGA_IRQ_U1TX, excpt_common /* USART1 TX complete */ + HANDLER atmega_twi, ATMEGA_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ + HANDLER atmega_spmrdy, ATMEGA_IRQ_SPMRDY, excpt_common /* Store program memory ready */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA1284P) + HANDLER atmega_int0, ATMEGA_IRQ_INT0, excpt_common /* External interrupt request 0 */ + HANDLER atmega_int1, ATMEGA_IRQ_INT1, excpt_common /* External interrupt request 1 */ + HANDLER atmega_int2, ATMEGA_IRQ_INT2, excpt_common /* External interrupt request 2 */ + HANDLER atmega_pcint0, ATMEGA_IRQ_PCINT0, excpt_common /* Pin change interrupt request 0 */ + HANDLER atmega_pcint1, ATMEGA_IRQ_PCINT1, excpt_common /* Pin change interrupt request 1 */ + HANDLER atmega_pcint2, ATMEGA_IRQ_PCINT2, excpt_common /* Pin change interrupt request 2 */ + HANDLER atmega_pcint3, ATMEGA_IRQ_PCINT3, excpt_common /* Pin change interrupt request 3 */ + HANDLER atmega_wdt, ATMEGA_IRQ_WDT, excpt_common /* Watchdog time-out interrupt */ + HANDLER atmega_t2compa, ATMEGA_IRQ_T2COMPA, excpt_common /* TIMER2 COMPA timer/counter2 compare match */ + HANDLER atmega_t2compb, ATMEGA_IRQ_T2COMPB, excpt_common /* TIMER2 COMPB timer/counter2 compare match */ + HANDLER atmega_t2ovf, ATMEGA_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ + HANDLER atmega_t1capt, ATMEGA_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ + HANDLER atmega_t1compa, ATMEGA_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match a */ + HANDLER atmega_t1compb, ATMEGA_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match b */ + HANDLER atmega_t1ovf, ATMEGA_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ + HANDLER atmega_t0compa, ATMEGA_IRQ_T0COMPA, excpt_common /* TIMER0 COMPA timer/counter0 compare match */ + HANDLER atmega_t0compb, ATMEGA_IRQ_T0COMPB, excpt_common /* TIMER0 COMPB timer/counter0 compare match */ + HANDLER atmega_t0ovf, ATMEGA_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ + HANDLER atmega_spi, ATMEGA_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ + HANDLER atmega_u0rx, ATMEGA_IRQ_U0RX, excpt_common /* USART0 RX complete */ + HANDLER atmega_u0dre, ATMEGA_IRQ_U0DRE, excpt_common /* USART0 data register empty */ + HANDLER atmega_u0tx, ATMEGA_IRQ_U0TX, excpt_common /* USART0 TX complete */ + HANDLER atmega_anacomp, ATMEGA_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ + HANDLER atmega_adc, ATMEGA_IRQ_ADC, excpt_common /* ADC conversion complete */ + HANDLER atmega_ee, ATMEGA_IRQ_EE, excpt_common /* EEPROM ready */ + HANDLER atmega_twi , ATMEGA_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ + HANDLER atmega_spmrdy, ATMEGA_IRQ_SPMRDY, excpt_common /* Store program memory ready */ + HANDLER atmega_u1rx, ATMEGA_IRQ_U1RX, excpt_common /* USART1 RX complete */ + HANDLER atmega_u1dre, ATMEGA_IRQ_U1DRE, excpt_common /* USART1 data register empty */ + HANDLER atmega_u1tx, ATMEGA_IRQ_U1TX, excpt_common /* USART1 TX complete */ + HANDLER atmega_t3capt, ATMEGA_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ + HANDLER atmega_t3compa, ATMEGA_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ + HANDLER atmega_t3compb, ATMEGA_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ + HANDLER atmega_t3ovf, ATMEGA_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA2560) + HANDLER atmega_int0, ATMEGA_IRQ_INT0, excpt_common /* 0x0002 INT0 External Interrupt Request 0 */ + HANDLER atmega_int1, ATMEGA_IRQ_INT1, excpt_common /* 0x0004 INT1 External Interrupt Request 1 */ + HANDLER atmega_int2, ATMEGA_IRQ_INT2, excpt_common /* 0x0006 INT2 External Interrupt Request 2 */ + HANDLER atmega_int3, ATMEGA_IRQ_INT3, excpt_common /* 0x0008 INT3 External Interrupt Request 3 */ + HANDLER atmega_int4, ATMEGA_IRQ_INT4, excpt_common /* 0x000A INT4 External Interrupt Request 4 */ + HANDLER atmega_int5, ATMEGA_IRQ_INT5, excpt_common /* 0x000C INT5 External Interrupt Request 5 */ + HANDLER atmega_int6, ATMEGA_IRQ_INT6, excpt_common /* 0x000E INT6 External Interrupt Request 6 */ + HANDLER atmega_int7, ATMEGA_IRQ_INT7, excpt_common /* 0x0010 INT7 External Interrupt Request 7 */ + HANDLER atmega_pcint0, ATMEGA_IRQ_PCINT0, excpt_common /* 0x0012 PCINT0 Pin Change Interrupt Req 0 */ + HANDLER atmega_pcint1, ATMEGA_IRQ_PCINT1, excpt_common /* 0x0014 PCINT1 Pin Change Interrupt Req 1 */ + HANDLER atmega_pcint2, ATMEGA_IRQ_PCINT2, excpt_common /* 0x0016 PCINT2 Pin Change Interrupt Req 2 */ + HANDLER atmega_wdt, ATMEGA_IRQ_WDT, excpt_common /* 0x0018 WDT Watchdog Time-out Interrupt */ + HANDLER atmega_tim2_compa, ATMEGA_IRQ_TIM2_COMPA, excpt_common /* 0x001A TIMER2 COMPA Timer/Counter2 Compare Match A */ + HANDLER atmega_tim2_compb, ATMEGA_IRQ_TIM2_COMPB, excpt_common /* 0x001C TIMER2 COMPB Timer/Counter2 Compare Match B */ + HANDLER atmega_tim2_ovf, ATMEGA_IRQ_TIM2_OVF, excpt_common /* 0x001E TIMER2 OVF Timer/Counter2 Overflow */ + HANDLER atmega_tim1_capt, ATMEGA_IRQ_TIM1_CAPT, excpt_common /* 0x0020 TIMER1 CAPT Timer/Counter1 Capture Event */ + HANDLER atmega_tim1_compa, ATMEGA_IRQ_TIM1_COMPA, excpt_common /* 0x0022 TIMER1 COMPA Timer/Counter1 Compare Match A */ + HANDLER atmega_tim1_compb, ATMEGA_IRQ_TIM1_COMPB, excpt_common /* 0x0024 TIMER1 COMPB Timer/Counter1 Compare Match B */ + HANDLER atmega_tim1_compc, ATMEGA_IRQ_TIM1_COMPC, excpt_common /* 0x0026 TIMER1 COMPC Timer/Counter1 Compare Match C */ + HANDLER atmega_tim1_ovf, ATMEGA_IRQ_TIM1_OVF, excpt_common /* 0x0028 TIMER1 OVF Timer/Counter1 Overflow */ + HANDLER atmega_tim0_compa, ATMEGA_IRQ_TIM0_COMPA, excpt_common /* 0x002A TIMER0 COMPA Timer/Counter0 Compare Match A */ + HANDLER atmega_tim0_compb, ATMEGA_IRQ_TIM0_COMPB, excpt_common /* 0x002C TIMER0 COMPB Timer/Counter0 Compare match B */ + HANDLER atmega_tim0_ovf, ATMEGA_IRQ_TIM0_OVF, excpt_common /* 0x002E TIMER0 OVF Timer/Counter0 Overflow */ + HANDLER atmega_spi_stc, ATMEGA_IRQ_SPI_STC, excpt_common /* 0x0030 SPI, STC SPI Serial Transfer Complete */ + HANDLER atmega_u0rx, ATMEGA_IRQ_U0RX, excpt_common /* 0x0032 USART0 RX USART0 Rx Complete */ + HANDLER atmega_u0dre, ATMEGA_IRQ_U0DRE, excpt_common /* 0x0034 USART0 UDRE USART0 Data Register Empty */ + HANDLER atmega_u0tx, ATMEGA_IRQ_U0TX, excpt_common /* 0x0036 USART0 TX USART0 Tx Complete */ + HANDLER atmega_ana_comp, ATMEGA_IRQ_ANA_COMP, excpt_common /* 0x0038 ANALOG COMP Analog Comparator */ + HANDLER atmega_adc, ATMEGA_IRQ_ADC, excpt_common /* 0x003A ADC ADC Conversion Complete */ + HANDLER atmega_ee_rdy, ATMEGA_IRQ_EE_RDY, excpt_common /* 0x003C EE READY EEPROM Ready */ + HANDLER atmega_tim3_capt, ATMEGA_IRQ_TIM3_CAPT, excpt_common /* 0x003E TIMER3 CAPT Timer/Counter3 Capture Event */ + HANDLER atmega_tim3_compa, ATMEGA_IRQ_TIM3_COMPA, excpt_common /* 0x0040 TIMER3 COMPA Timer/Counter3 Compare Match A */ + HANDLER atmega_tim3_compb, ATMEGA_IRQ_TIM3_COMPB, excpt_common /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ + HANDLER atmega_tim3_compc, ATMEGA_IRQ_TIM3_COMPC, excpt_common /* 0x0044 TIMER3 COMPC Timer/Counter3 Compare Match C */ + HANDLER atmega_tim3_ovf, ATMEGA_IRQ_TIM3_OVF, excpt_common /* 0x0046 TIMER3 OVF Timer/Counter3 Overflow */ + HANDLER atmega_u1rx, ATMEGA_IRQ_U1RX, excpt_common /* 0x0048 USART1 RX USART1 Rx Complete */ + HANDLER atmega_u1dre, ATMEGA_IRQ_U1DRE, excpt_common /* 0x004A USART1 UDRE USART1 Data Register Empty */ + HANDLER atmega_u1tx, ATMEGA_IRQ_U1TX, excpt_common /* 0x004C USART1 TX USART1 Tx Complete */ + HANDLER atmega_twi, ATMEGA_IRQ_TWI, excpt_common /* 0x004E TWI 2-wire Serial Interface */ + HANDLER atmega_spm_rdy, ATMEGA_IRQ_SPM_RDY, excpt_common /* 0x0050 SPM READY Store Program Memory Ready */ + HANDLER atmega_tim4_capt, ATMEGA_IRQ_TIM4_CAPT, excpt_common /* 0x0052 TIMER4 CAPT Timer/Counter4 Capture Event */ + HANDLER atmega_tim4_compa, ATMEGA_IRQ_TIM4_COMPA, excpt_common /* 0x0054 TIMER4 COMPA Timer/Counter4 Compare Match A */ + HANDLER atmega_tim4_compb, ATMEGA_IRQ_TIM4_COMPB, excpt_common /* 0x0056 TIMER4 COMPB Timer/Counter4 Compare Match B */ + HANDLER atmega_tim4_compc, ATMEGA_IRQ_TIM4_COMPC, excpt_common /* 0x0058 TIMER4 COMPC Timer/Counter4 Compare Match C */ + HANDLER atmega_tim4_ovf, ATMEGA_IRQ_TIM4_OVF, excpt_common /* 0x005A TIMER4 OVF Timer/Counter4 Overflow */ + HANDLER atmega_tim5_capt, ATMEGA_IRQ_TIM5_CAPT, excpt_common /* 0x005C TIMER5 CAPT Timer/Counter5 Capture Event */ + HANDLER atmega_tim5_compa, ATMEGA_IRQ_TIM5_COMPA, excpt_common /* 0x005E TIMER5 COMPA Timer/Counter5 Compare Match A */ + HANDLER atmega_tim5_compb, ATMEGA_IRQ_TIM5_COMPB, excpt_common /* 0x0060 TIMER5 COMPB Timer/Counter5 Compare Match B */ + HANDLER atmega_tim5_compc, ATMEGA_IRQ_TIM5_COMPC, excpt_common /* 0x0062 TIMER5 COMPC Timer/Counter5 Compare Match C */ + HANDLER atmega_tim5_ovf, ATMEGA_IRQ_TIM5_OVF, excpt_common /* 0x0064 TIMER5 OVF Timer/Counter5 Overflow */ + HANDLER atmega_u2rx, ATMEGA_IRQ_U2RX, excpt_common /* 0x0066 USART1 RX USART2 Rx Complete */ + HANDLER atmega_u2dre, ATMEGA_IRQ_U2DRE, excpt_common /* 0x0068 USART1 UDRE USART2 Data Register Empty */ + HANDLER atmega_u2tx, ATMEGA_IRQ_U2TX, excpt_common /* 0x006A USART1 TX USART2 Tx Complete */ + HANDLER atmega_u3rx, ATMEGA_IRQ_U3RX, excpt_common /* 0x006C USART1 RX USART3 Rx Complete */ + HANDLER atmega_u3dre, ATMEGA_IRQ_U3DRE, excpt_common /* 0x006E USART1 UDRE USART3 Data Register Empty */ + HANDLER atmega_u3tx, ATMEGA_IRQ_U3TX, excpt_common /* 0x0070 USART1 TX USART3 Tx Complete */ +#else +# error "Unrecognized chip" +#endif + +/******************************************************************************************** + * Name: excpt_common + * + * Description: + * Exception Vector Handlers + * + * On Entry: + * The return PC and the saved r24 is on the stack, r24 now contains the IRQ number + * + * PC1 + * PC0 + * R0 + * --- <- SP + * + ********************************************************************************************/ + +excpt_common: + /* Save the remaining registers on the stack, preserving the IRQ number in r14 */ + + EXCPT_PROLOGUE + + /* Call up_doirq with r24 = IRQ number, r22-23 = Pointer to the save structure. The stack + * pointer currently points to the save structure (or maybe the save struture -1 since + * the push operation post-decrements -- need to REVISIT this). + */ + + in r28, _SFR_IO_ADDR(SPL) /* Get the save structure pointer in a Call-saved register pair */ + in r29, _SFR_IO_ADDR(SPH) /* Pointer can be obtained from the stack pointer */ + adiw r28, 1 /* Remembering that push post-decrements */ + movw r22, r28 /* Pass register save structure as the parameter 2 */ + USE_INTSTACK rx, ry, rz /* Switch to the interrupt stack */ + call up_doirq /* Dispatch the interrupt */ + RESTORE_STACK rx, ry /* Undo the operations of USE_INTSTACK */ + + /* up_doiq returns with r24-r25 equal to the new save structure. If no context + * switch occurred, this will be the same as the value passed to it in r22-23. + * But if a context switch occurs, then the returned value will point not at a + * stack frame, but at a register save area inside of the new task's TCB. + */ + + cp r28, r24 + cpc r29, r25 + breq .Lnoswitch + + /* A context switch has occurred, jump to up_fullcontextrestore with r24, r25 + * equal to the address of the new register save ared. + */ + + jmp up_fullcontextrestore + + /* No context switch occurred.. just return off the stack */ + +.Lnoswitch: + EXCPT_EPILOGUE + reti + +/**************************************************************************************************** + * Name: up_interruptstack + ****************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip CONFIG_ARCH_INTERRUPTSTACK +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end diff --git a/arch/avr/src/atmega/atmega_head.S b/arch/avr/src/atmega/atmega_head.S new file mode 100644 index 0000000000000000000000000000000000000000..c7804801cc38179a16a92656616c076fa0000873 --- /dev/null +++ b/arch/avr/src/atmega/atmega_head.S @@ -0,0 +1,475 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega_head.S + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* Stack is allocated just after uninitialized data and just before the heap */ + +#define STACKBASE (_enoinit+CONFIG_IDLETHREAD_STACKSIZE-1) + +/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. + * At present, only the ATMega128 is supported so RAMPZ should always be + * available. + * + * - Support for the EPLMX instructions is assumed if RAMPZ is present + * - If RAMPZ is not present, support for LPMX is assumed + */ + +#define HAVE_RAMPZ 1 + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_nommuhead.S" + .global __start /* Entry point */ + .global _sbss /* Start of .bss. Defined by ld.script */ + .global _ebss /* End of .bss. Defined by ld.script */ + .global _sdata /* Start of .data section in RAM */ + .global _edata /* End of .data section in RAM */ + .global _eronly /* Start of .data section in FLASH */ + .global _enoinit /* End of uninitilized data. Defined by ld.script */ + .global up_lowinit /* Perform low level initialization */ + .global os_start /* NuttX entry point */ + + .global vectortab +#if defined(CONFIG_ARCH_CHIP_ATMEGA128) + .global atmega_int0 /* External interrupt request 0 */ + .global atmega_int1 /* External interrupt request 1 */ + .global atmega_int2 /* External interrupt request 2 */ + .global atmega_int3 /* External interrupt request 3 */ + .global atmega_int4 /* External interrupt request 4 */ + .global atmega_int5 /* External interrupt request 5 */ + .global atmega_int6 /* External interrupt request 6 */ + .global atmega_int7 /* External interrupt request 7 */ + .global atmega_t2comp /* TIMER2 COMP timer/counter2 compare match */ + .global atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */ + .global atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */ + .global atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */ + .global atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */ + .global atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */ + .global atmega_t0comp /* TIMER0 COMP timer/counter0 compare match */ + .global atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */ + .global atmega_spi /* STC SPI serial transfer complete */ + .global atmega_u0rx /* USART0 RX complete */ + .global atmega_u0dre /* USART0 data register empty */ + .global atmega_u0tx /* USART0 TX complete */ + .global atmega_adc /* ADC conversion complete */ + .global atmega_ee /* EEPROM ready */ + .global atmega_anacomp /* ANALOG COMP analog comparator */ + .global atmega_t1compc /* TIMER1 COMPC timer/countre1 compare match c */ + .global atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */ + .global atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */ + .global atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */ + .global atmega_t3compc /* TIMER3 COMPC timer/counter3 compare match c */ + .global atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */ + .global atmega_u1rx /* USART1 RX complete */ + .global atmega_u1dre /* USART1 data register empty */ + .global atmega_u1tx /* USART1 TX complete */ + .global atmega_twi /* TWI two-wire serial interface */ + .global atmega_spmrdy /* Store program memory ready */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA1284P) + .global atmega_int0 /* External interrupt request 0 */ + .global atmega_int1 /* External interrupt request 1 */ + .global atmega_int2 /* External interrupt request 2 */ + .global atmega_pcint0 /* Pin change interrupt request 0 */ + .global atmega_pcint1 /* Pin change interrupt request 1 */ + .global atmega_pcint2 /* Pin change interrupt request 2 */ + .global atmega_pcint3 /* Pin change interrupt request 3 */ + .global atmega_wdt /* Watchdog time-out interrupt */ + .global atmega_t2compa /* TIMER2 COMPA timer/counter2 compare match */ + .global atmega_t2compb /* TIMER2 COMPB timer/counter2 compare match */ + .global atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */ + .global atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */ + .global atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */ + .global atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */ + .global atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */ + .global atmega_t0compa /* TIMER0 COMPA timer/counter0 compare match */ + .global atmega_t0compb /* TIMER0 COMPB timer/counter0 compare match */ + .global atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */ + .global atmega_spi /* STC SPI serial transfer complete */ + .global atmega_u0rx /* USART0 RX complete */ + .global atmega_u0dre /* USART0 data register empty */ + .global atmega_u0tx /* USART0 TX complete */ + .global atmega_anacomp /* ANALOG COMP analog comparator */ + .global atmega_adc /* ADC conversion complete */ + .global atmega_ee /* EEPROM ready */ + .global atmega_twi /* TWI two-wire serial interface */ + .global atmega_spmrdy /* Store program memory ready */ + .global atmega_u1rx /* USART1 RX complete */ + .global atmega_u1dre /* USART1 data register empty */ + .global atmega_u1tx /* USART1 TX complete */ + .global atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */ + .global atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */ + .global atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */ + .global atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA2560) + .global atmega_int0 /* 0x0002 INT0 External Interrupt Request 0 */ + .global atmega_int1 /* 0x0004 INT1 External Interrupt Request 1 */ + .global atmega_int2 /* 0x0006 INT2 External Interrupt Request 2 */ + .global atmega_int3 /* 0x0008 INT3 External Interrupt Request 3 */ + .global atmega_int4 /* 0x000A INT4 External Interrupt Request 4 */ + .global atmega_int5 /* 0x000C INT5 External Interrupt Request 5 */ + .global atmega_int6 /* 0x000E INT6 External Interrupt Request 6 */ + .global atmega_int7 /* 0x0010 INT7 External Interrupt Request 7 */ + .global atmega_pcint0 /* 0x0012 PCINT0 Pin Change Interrupt Req 0 */ + .global atmega_pcint1 /* 0x0014 PCINT1 Pin Change Interrupt Req 1 */ + .global atmega_pcint2 /* 0x0016 PCINT2 Pin Change Interrupt Req 2 */ + .global atmega_wdt /* 0x0018 WDT Watchdog Time-out Interrupt */ + .global atmega_tim2_compa /* 0x001A TIMER2 COMPA Timer/Counter2 Compare Match A */ + .global atmega_tim2_compb /* 0x001C TIMER2 COMPB Timer/Counter2 Compare Match B */ + .global atmega_tim2_ovf /* 0x001E TIMER2 OVF Timer/Counter2 Overflow */ + .global atmega_tim1_capt /* 0x0020 TIMER1 CAPT Timer/Counter1 Capture Event */ + .global atmega_tim1_compa /* 0x0022 TIMER1 COMPA Timer/Counter1 Compare Match A */ + .global atmega_tim1_compb /* 0x0024 TIMER1 COMPB Timer/Counter1 Compare Match B */ + .global atmega_tim1_compc /* 0x0026 TIMER1 COMPC Timer/Counter1 Compare Match C */ + .global atmega_tim1_ovf /* 0x0028 TIMER1 OVF Timer/Counter1 Overflow */ + .global atmega_tim0_compa /* 0x002A TIMER0 COMPA Timer/Counter0 Compare Match A */ + .global atmega_tim0_compb /* 0x002C TIMER0 COMPB Timer/Counter0 Compare match B */ + .global atmega_tim0_ovf /* 0x002E TIMER0 OVF Timer/Counter0 Overflow */ + .global atmega_spi_stc /* 0x0030 SPI, STC SPI Serial Transfer Complete */ + .global atmega_u0rx /* 0x0032 USART0 RX USART0 Rx Complete */ + .global atmega_u0dre /* 0x0034 USART0 UDRE USART0 Data Register Empty */ + .global atmega_u0tx /* 0x0036 USART0 TX USART0 Tx Complete */ + .global atmega_ana_comp /* 0x0038 ANALOG COMP Analog Comparator */ + .global atmega_adc /* 0x003A ADC ADC Conversion Complete */ + .global atmega_ee_rdy /* 0x003C EE READY EEPROM Ready */ + .global atmega_tim3_capt /* 0x003E TIMER3 CAPT Timer/Counter3 Capture Event */ + .global atmega_tim3_compa /* 0x0040 TIMER3 COMPA Timer/Counter3 Compare Match A */ + .global atmega_tim3_compb /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ + .global atmega_tim3_compc /* 0x0044 TIMER3 COMPC Timer/Counter3 Compare Match C */ + .global atmega_tim3_ovf /* 0x0046 TIMER3 OVF Timer/Counter3 Overflow */ + .global atmega_u1rx /* 0x0048 USART1 RX USART1 Rx Complete */ + .global atmega_u1dre /* 0x004A USART1 UDRE USART1 Data Register Empty */ + .global atmega_u1tx /* 0x004C USART1 TX USART1 Tx Complete */ + .global atmega_twi /* 0x004E TWI 2-wire Serial Interface */ + .global atmega_spm_rdy /* 0x0050 SPM READY Store Program Memory Ready */ + .global atmega_tim4_capt /* 0x0052 TIMER4 CAPT Timer/Counter4 Capture Event */ + .global atmega_tim4_compa /* 0x0054 TIMER4 COMPA Timer/Counter4 Compare Match A */ + .global atmega_tim4_compb /* 0x0056 TIMER4 COMPB Timer/Counter4 Compare Match B */ + .global atmega_tim4_compc /* 0x0058 TIMER4 COMPC Timer/Counter4 Compare Match C */ + .global atmega_tim4_ovf /* 0x005A TIMER4 OVF Timer/Counter4 Overflow */ + .global atmega_tim5_capt /* 0x005C TIMER5 CAPT Timer/Counter5 Capture Event */ + .global atmega_tim5_compa /* 0x005E TIMER5 COMPA Timer/Counter5 Compare Match A */ + .global atmega_tim5_compb /* 0x0060 TIMER5 COMPB Timer/Counter5 Compare Match B */ + .global atmega_tim5_compc /* 0x0062 TIMER5 COMPC Timer/Counter5 Compare Match C */ + .global atmega_tim5_ovf /* 0x0064 TIMER5 OVF Timer/Counter5 Overflow */ + .global atmega_u2rx /* 0x0066 USART2 RX USART2 Rx Complete */ + .global atmega_u2dre /* 0x0068 USART2 UDRE USART2 Data Register Empty */ + .global atmega_u2tx /* 0x006A USART2 TX USART2 Tx Complete */ + .global atmega_u3rx /* 0x006C USART3 RX USART3 Rx Complete */ + .global atmega_u3dre /* 0x006E USART3 UDRE USART3 Data Register Empty */ + .global atmega_u3tx /* 0x0070 USART3 TX USART3 Tx Complete */ +#else +#error "Unrecognized chip" +#endif + +/**************************************************************************** + * Macros + ****************************************************************************/ + + .macro vector name + jmp \name + .endm + +/**************************************************************************** + * Vector Table + ****************************************************************************/ + +/* The ATmega128 has 35 interrupt vectors including vector 0, the reset + * vector. + */ + + .section .vectors, "ax", @progbits + .func vectortab +vectortab: + jmp __start /* 0: Vector 0 is the reset vector */ +#if defined(CONFIG_ARCH_CHIP_ATMEGA128) + vector atmega_int0 /* 1: External interrupt request 0 */ + vector atmega_int1 /* 2: External interrupt request 1 */ + vector atmega_int2 /* 3: External interrupt request 2 */ + vector atmega_int3 /* 4: External interrupt request 3 */ + vector atmega_int4 /* 5: External interrupt request 4 */ + vector atmega_int5 /* 6 : External interrupt request 5 */ + vector atmega_int6 /* 7: External interrupt request 6 */ + vector atmega_int7 /* 8: External interrupt request 7 */ + vector atmega_t2comp /* 9: TIMER2 COMP timer/counter2 compare match */ + vector atmega_t2ovf /* 10: TIMER2 OVF timer/counter2 overflow */ + vector atmega_t1capt /* 11: TIMER1 CAPT timer/counter1 capture event */ + vector atmega_t1compa /* 12: TIMER1 COMPA timer/counter1 compare match a */ + vector atmega_t1compb /* 13: TIMER1 COMPB timer/counter1 compare match b */ + vector atmega_t1ovf /* 14: TIMER1 OVF timer/counter1 overflow */ + vector atmega_t0comp /* 15: TIMER0 COMP timer/counter0 compare match */ + vector atmega_t0ovf /* 16: TIMER0 OVF timer/counter0 overflow */ + vector atmega_spi /* 17: STC SPI serial transfer complete */ + vector atmega_u0rx /* 18: USART0 RX complete */ + vector atmega_u0dre /* 19: USART0 data register empty */ + vector atmega_u0tx /* 20: USART0 TX complete */ + vector atmega_adc /* 21: ADC conversion complete */ + vector atmega_ee /* 22: EEPROM ready */ + vector atmega_anacomp /* 23: ANALOG COMP analog comparator */ + vector atmega_t1compc /* 24: TIMER1 COMPC timer/countre1 compare match c */ + vector atmega_t3capt /* 25: TIMER3 CAPT timer/counter3 capture event */ + vector atmega_t3compa /* 26: TIMER3 COMPA timer/counter3 compare match a */ + vector atmega_t3compb /* 27: TIMER3 COMPB timer/counter3 compare match b */ + vector atmega_t3compc /* 28: TIMER3 COMPC timer/counter3 compare match c */ + vector atmega_t3ovf /* 29: TIMER3 OVF timer/counter3 overflow */ + vector atmega_u1rx /* 30: USART1 RX complete */ + vector atmega_u1dre /* 31: USART1 data register empty */ + vector atmega_u1tx /* 32: USART1 TX complete */ + vector atmega_twi /* 33: TWI two-wire serial interface */ + vector atmega_spmrdy /* 34: Store program memory ready */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA1284P) + vector atmega_int0 /* External interrupt request 0 */ + vector atmega_int1 /* External interrupt request 1 */ + vector atmega_int2 /* External interrupt request 2 */ + vector atmega_pcint0 /* Pin change interrupt request 0 */ + vector atmega_pcint1 /* Pin change interrupt request 1 */ + vector atmega_pcint2 /* Pin change interrupt request 2 */ + vector atmega_pcint3 /* Pin change interrupt request 3 */ + vector atmega_wdt /* Watchdog time-out interrupt */ + vector atmega_t2compa /* TIMER2 COMPA timer/counter2 compare match */ + vector atmega_t2compb /* TIMER2 COMPB timer/counter2 compare match */ + vector atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */ + vector atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */ + vector atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */ + vector atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */ + vector atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */ + vector atmega_t0compa /* TIMER0 COMPA timer/counter0 compare match */ + vector atmega_t0compb /* TIMER0 COMPB timer/counter0 compare match */ + vector atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */ + vector atmega_spi /* STC SPI serial transfer complete */ + vector atmega_u0rx /* USART0 RX complete */ + vector atmega_u0dre /* USART0 data register empty */ + vector atmega_u0tx /* USART0 TX complete */ + vector atmega_anacomp /* ANALOG COMP analog comparator */ + vector atmega_adc /* ADC conversion complete */ + vector atmega_ee /* EEPROM ready */ + vector atmega_twi /* TWI two-wire serial interface */ + vector atmega_spmrdy /* Store program memory ready */ + vector atmega_u1rx /* USART1 RX complete */ + vector atmega_u1dre /* USART1 data register empty */ + vector atmega_u1tx /* USART1 TX complete */ + vector atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */ + vector atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */ + vector atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */ + vector atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */ +#elif defined(CONFIG_ARCH_CHIP_ATMEGA2560) + vector atmega_int0 /* 0x0002 INT0 External Interrupt Request 0 */ + vector atmega_int1 /* 0x0004 INT1 External Interrupt Request 1 */ + vector atmega_int2 /* 0x0006 INT2 External Interrupt Request 2 */ + vector atmega_int3 /* 0x0008 INT3 External Interrupt Request 3 */ + vector atmega_int4 /* 0x000A INT4 External Interrupt Request 4 */ + vector atmega_int5 /* 0x000C INT5 External Interrupt Request 5 */ + vector atmega_int6 /* 0x000E INT6 External Interrupt Request 6 */ + vector atmega_int7 /* 0x0010 INT7 External Interrupt Request 7 */ + vector atmega_pcint0 /* 0x0012 PCINT0 Pin Change Interrupt Req 0 */ + vector atmega_pcint1 /* 0x0014 PCINT1 Pin Change Interrupt Req 1 */ + vector atmega_pcint2 /* 0x0016 PCINT2 Pin Change Interrupt Req 2 */ + vector atmega_wdt /* 0x0018 WDT Watchdog Time-out Interrupt */ + vector atmega_tim2_compa /* 0x001A TIMER2 COMPA Timer/Counter2 Compare Match A */ + vector atmega_tim2_compb /* 0x001C TIMER2 COMPB Timer/Counter2 Compare Match B */ + vector atmega_tim2_ovf /* 0x001E TIMER2 OVF Timer/Counter2 Overflow */ + vector atmega_tim1_capt /* 0x0020 TIMER1 CAPT Timer/Counter1 Capture Event */ + vector atmega_tim1_compa /* 0x0022 TIMER1 COMPA Timer/Counter1 Compare Match A */ + vector atmega_tim1_compb /* 0x0024 TIMER1 COMPB Timer/Counter1 Compare Match B */ + vector atmega_tim1_compc /* 0x0026 TIMER1 COMPC Timer/Counter1 Compare Match C */ + vector atmega_tim1_ovf /* 0x0028 TIMER1 OVF Timer/Counter1 Overflow */ + vector atmega_tim0_compa /* 0x002A TIMER0 COMPA Timer/Counter0 Compare Match A */ + vector atmega_tim0_compb /* 0x002C TIMER0 COMPB Timer/Counter0 Compare match B */ + vector atmega_tim0_ovf /* 0x002E TIMER0 OVF Timer/Counter0 Overflow */ + vector atmega_spi_stc /* 0x0030 SPI, STC SPI Serial Transfer Complete */ + vector atmega_u0rx /* 0x0032 USART0 RX USART0 Rx Complete */ + vector atmega_u0dre /* 0x0034 USART0 UDRE USART0 Data Register Empty */ + vector atmega_u0tx /* 0x0036 USART0 TX USART0 Tx Complete */ + vector atmega_ana_comp /* 0x0038 ANALOG COMP Analog Comparator */ + vector atmega_adc /* 0x003A ADC ADC Conversion Complete */ + vector atmega_ee_rdy /* 0x003C EE READY EEPROM Ready */ + vector atmega_tim3_capt /* 0x003E TIMER3 CAPT Timer/Counter3 Capture Event */ + vector atmega_tim3_compa /* 0x0040 TIMER3 COMPA Timer/Counter3 Compare Match A */ + vector atmega_tim3_compb /* 0x0042 TIMER3 COMPB Timer/Counter3 Compare Match B */ + vector atmega_tim3_compc /* 0x0044 TIMER3 COMPC Timer/Counter3 Compare Match C */ + vector atmega_tim3_ovf /* 0x0046 TIMER3 OVF Timer/Counter3 Overflow */ + vector atmega_u1rx /* 0x0048 USART1 RX USART1 Rx Complete */ + vector atmega_u1dre /* 0x004A USART1 UDRE USART1 Data Register Empty */ + vector atmega_u1tx /* 0x004C USART1 TX USART1 Tx Complete */ + vector atmega_twi /* 0x004E TWI 2-wire Serial Interface */ + vector atmega_spm_rdy /* 0x0050 SPM READY Store Program Memory Ready */ + vector atmega_tim4_capt /* 0x0052 TIMER4 CAPT Timer/Counter4 Capture Event */ + vector atmega_tim4_compa /* 0x0054 TIMER4 COMPA Timer/Counter4 Compare Match A */ + vector atmega_tim4_compb /* 0x0056 TIMER4 COMPB Timer/Counter4 Compare Match B */ + vector atmega_tim4_compc /* 0x0058 TIMER4 COMPC Timer/Counter4 Compare Match C */ + vector atmega_tim4_ovf /* 0x005A TIMER4 OVF Timer/Counter4 Overflow */ + vector atmega_tim5_capt /* 0x005C TIMER5 CAPT Timer/Counter5 Capture Event */ + vector atmega_tim5_compa /* 0x005E TIMER5 COMPA Timer/Counter5 Compare Match A */ + vector atmega_tim5_compb /* 0x0060 TIMER5 COMPB Timer/Counter5 Compare Match B */ + vector atmega_tim5_compc /* 0x0062 TIMER5 COMPC Timer/Counter5 Compare Match C */ + vector atmega_tim5_ovf /* 0x0064 TIMER5 OVF Timer/Counter5 Overflow */ + vector atmega_u2rx /* 0x0066 USART2 RX USART2 Rx Complete */ + vector atmega_u2dre /* 0x0068 USART2 UDRE USART2 Data Register Empty */ + vector atmega_u2tx /* 0x006A USART2 TX USART2 Tx Complete */ + vector atmega_u3rx /* 0x006C USART3 RX USART3 Rx Complete */ + vector atmega_u3dre /* 0x006E USART3 UDRE USART3 Data Register Empty */ + vector atmega_u3tx /* 0x0070 USART3 TX USART3 Tx Complete */ +#else +#error "Unrecognized chip" +#endif + .endfunc + +/**************************************************************************** + * Reset Entry Point + ****************************************************************************/ + + .section .init, "ax", @progbits + .func __start +__start: + + /* no interrupts! Useful for software reset by jumping to address 0 */ + cli + +#if defined(EIND) + /* set EIND to 0, just to be sure we are sane */ + out _SFR_IO_ADDR(EIND), 0 // EIND = 0x3c +#endif /* EIND */ + + /* Clear the zero register, clear the status register and initialize the + * IDLE thread stack + */ + + clr r1 + out _SFR_IO_ADDR(SREG), r1 + ldi r28, lo8(STACKBASE) + ldi r29, hi8(STACKBASE) + out _SFR_IO_ADDR(SPH), r29 + out _SFR_IO_ADDR(SPL), r28 + + /* Copy initial global data values from FLASH into RAM */ + + .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ +__do_copy_data: + +#ifdef HAVE_RAMPZ + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + ldi r16, hh8(_eronly) + out _SFR_IO_ADDR(RAMPZ), r16 + rjmp .Lcopystart + +.Lcopyloop: + elpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#else + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + rjmp .Lcopystart + +.Lcopyloop: + lpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#endif + + /* Clear uninitialized data */ + + .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ +__do_clear_bss: + + ldi r17, hi8(_ebss) + ldi r26, lo8(_sbss) + ldi r27, hi8(_sbss) + rjmp .Lclearstart + +.Lclearloop: + st X+, r1 + +.Lclearstart: + cpi r26, lo8(_ebss) + cpc r27, r17 + brne .Lclearloop + + /* Perform any low-level initialization */ + + call up_lowinit + + /* Now start NuttX */ + + call os_start + jmp exit + .endfunc + +/**************************************************************************** + * Heap Base + ****************************************************************************/ + + /* This global variable is unsigned long g_idle_topstack and is exported from + * here only because of its coupling to other uses of _enoinit in this file + */ + + .data + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .word _enoinit+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/avr/src/atmega/atmega_lowconsole.c b/arch/avr/src/atmega/atmega_lowconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..2592e28027d2d3f0a867d1fa22115e5519c5585f --- /dev/null +++ b/arch/avr/src/atmega/atmega_lowconsole.c @@ -0,0 +1,478 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega_lowconsole.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "atmega_config.h" + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "atmega.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USART0 Baud rate settings for normal and double speed modes */ + +#define AVR_NORMAL_UBRR0 \ + ((((BOARD_CPU_CLOCK / 16) + (CONFIG_USART0_BAUD / 2)) / (CONFIG_USART0_BAUD)) - 1) + +#define AVR_DBLSPEED_UBRR0 \ + ((((BOARD_CPU_CLOCK / 8) + (CONFIG_USART0_BAUD / 2)) / (CONFIG_USART0_BAUD)) - 1) + +/* Select normal or double speed baud settings. This is a trade-off between the + * sampling rate and the accuracy of the divisor for high baud rates. + * + * As examples, consider: + * + * BOARD_CPU_CLOCK=8MHz and BAUD=115200: + * AVR_NORMAL_UBRR1 = 4 (rounded), actual baud = 125,000 + * AVR_DBLSPEED_UBRR1 = 9 (rounded), actual baud = 111,111 + * + * BOARD_CPU_CLOCK=8MHz and BAUD=9600: + * AVR_NORMAL_UBRR1 = 52 (rounded), actual baud = 9615 + * AVR_DBLSPEED_UBRR1 = 104 (rounded), actual baud = 9615 + */ + +#undef USART0_DOUBLE_SPEED +#ifdef CONFIG_AVR_USART0 +# if BOARD_CPU_CLOCK <= 4000000 +# if CONFIG_USART0_BAUD <= 9600 +# define AVR_UBRR0 AVR_NORMAL_UBRR0 +# else +# define AVR_UBRR0 AVR_DBLSPEED_UBRR0 +# define USART0_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 8000000 +# if CONFIG_USART0_BAUD <= 19200 +# define AVR_UBRR0 AVR_NORMAL_UBRR0 +# else +# define AVR_UBRR0 AVR_DBLSPEED_UBRR0 +# define USART0_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 12000000 +# if CONFIG_USART0_BAUD <= 28800 +# define AVR_UBRR0 AVR_NORMAL_UBRR0 +# else +# define AVR_UBRR0 AVR_DBLSPEED_UBRR0 +# define USART0_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 16000000 +# if CONFIG_USART0_BAUD <= 38400 +# define AVR_UBRR0 AVR_NORMAL_UBRR0 +# else +# define AVR_UBRR0 AVR_DBLSPEED_UBRR0 +# define USART0_DOUBLE_SPEED 1 +# endif +# else +# if CONFIG_USART0_BAUD <= 57600 +# define AVR_UBRR0 AVR_NORMAL_UBRR0 +# else +# define AVR_UBRR0 AVR_DBLSPEED_UBRR0 +# define USART0_DOUBLE_SPEED 1 +# endif +# endif +#endif + +/* USART1 Baud rate settings for normal and double speed modes */ + +#define AVR_NORMAL_UBRR1 \ + ((((BOARD_CPU_CLOCK / 16) + (CONFIG_USART1_BAUD / 2)) / (CONFIG_USART1_BAUD)) - 1) + +#define AVR_DBLSPEED_UBRR1 \ + ((((BOARD_CPU_CLOCK / 8) + (CONFIG_USART1_BAUD / 2)) / (CONFIG_USART1_BAUD)) - 1) + +/* Select normal or double speed baud settings. This is a trade-off between the + * sampling rate and the accuracy of the divisor for high baud rates. + * + * As examples, consider: + * + * BOARD_CPU_CLOCK=8MHz and BAUD=115200: + * AVR_NORMAL_UBRR1 = 4 (rounded), actual baud = 125,000 + * AVR_DBLSPEED_UBRR1 = 9 (rounded), actual baud = 111,111 + * + * BOARD_CPU_CLOCK=8MHz and BAUD=9600: + * AVR_NORMAL_UBRR1 = 52 (rounded), actual baud = 9615 + * AVR_DBLSPEED_UBRR1 = 104 (rounded), actual baud = 9615 + */ + +#undef USART1_DOUBLE_SPEED +#ifdef CONFIG_AVR_USART1 +# if BOARD_CPU_CLOCK <= 4000000 +# if CONFIG_USART1_BAUD <= 9600 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define USART1_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 8000000 +# if CONFIG_USART1_BAUD <= 19200 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define USART1_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 12000000 +# if CONFIG_USART1_BAUD <= 28800 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define USART1_DOUBLE_SPEED 1 +# endif +# elif BOARD_CPU_CLOCK <= 16000000 +# if CONFIG_USART1_BAUD <= 38400 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define USART1_DOUBLE_SPEED 1 +# endif +# else +# if CONFIG_USART1_BAUD <= 57600 +# define AVR_UBRR1 AVR_NORMAL_UBRR1 +# else +# define AVR_UBRR1 AVR_DBLSPEED_UBRR1 +# define USART1_DOUBLE_SPEED 1 +# endif +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart0_reset and usart1_reset + * + * Description: + * Reset USART0 or USART1. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +void usart0_reset(void) +{ + /* Clear USART configuration */ + + UCSR0A = 0; + UCSR0B = 0; + UCSR0C = 0; + + /* Unconfigure pins (no action needed */ + +#ifdef CONFIG_ARCH_CHIP_ATMEGA1284P + DDRD &= ~(1 << 1); + PORTD &= ~(1 << 0); +#else + DDRE &= ~(1 << 1); + PORTE &= ~(1 << 0); +#endif + + /* Unconfigure BAUD divisor */ + + UBRR0H = 0; + UBRR0L = 0; +} +#endif + +#ifdef CONFIG_AVR_USART1 +void usart1_reset(void) +{ + /* Clear USART configuration */ + + UCSR1A = 0; + UCSR1B = 0; + UCSR1C = 0; + + /* Unconfigure pins */ + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 2); + + /* Unconfigure BAUD divisor */ + + UBRR1H = 0; + UBRR1L = 0; +} +#endif + +/**************************************************************************** + * Name: usart0_configure and usart1_configure + * + * Description: + * Configure USART0 or USART1. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +void usart0_configure(void) +{ + uint8_t ucsr0b; + uint8_t ucsr0c; + + /* Select normal or double speed. */ + +#ifdef USART0_DOUBLE_SPEED + UCSR0A = (1 << U2X0); +#else + UCSR0A = 0; +#endif + + /* Select baud, parity, nubmer of bits, stop bits, etc. */ + + ucsr0b = ((1 << TXEN0) | (1 << RXEN0)); + ucsr0c = 0; + + /* Select parity */ + +#if CONFIG_USART0_PARITY == 1 + ucsr0c |= ((1 << UPM01) | (1 << UPM00)); /* Odd parity */ +#elif CONFIG_USART0_PARITY == 2 + ucsr0c |= (1 << UPM00); /* Even parity */ +#endif + + /* 1 or 2 stop bits */ + +#if defined(CONFIG_USART0_2STOP) && CONFIG_USART0_2STOP > 0 + ucsr0c |= (1 << USBS0); /* Two stop bits */ +#endif + + /* Word size */ + +#if CONFIG_USART0_BITS == 5 +#elif CONFIG_USART0_BITS == 6 + ucsr0c |= (1 << UCSZ00); +#elif CONFIG_USART0_BITS == 7 + ucsr0c |= (1 << UCSZ01); +#elif CONFIG_USART0_BITS == 8 + ucsr0c |= ((1 << UCSZ00) | (1 << UCSZ01)); +#elif CONFIG_USART0_BITS == 9 + ucsr0c |= ((1 << UCSZ0) | (1 << UCSZ01)); + ucsr0b |= (1 << UCSZ02); +#else +# error "Unsupported word size" +#endif + + UCSR0B = ucsr0b; + UCSR0C = ucsr0c; + +#ifdef CONFIG_ARCH_CHIP_ATMEGA1284P + /* Pin Configuration: None necessary, Port D bits 0&1 are automatically + * configured: + * + * Port D, Bit 0: RXD0, USART0 Receive Pin. Receive Data (Data input pin + * for the USART0). When the USART0 receiver is enabled this pin is + * configured as an input regardless of the value of DDRD0. When the + * USART0 forces this pin to be an input, a logical one in PORTD0 will + * turn on the internal pull-up. + * + * Port D, Bit 1: TXD0, USART0 Transmit pin. + */ + + DDRD |= (1 << 1); /* Force Port D pin 1 to be an output -- should not be necessary */ + PORTD |= (1 << 0); /* Set pull-up on Port D pin 0 */ + +#else + /* Pin Configuration: None necessary, Port E bits 0&1 are automatically + * configured: + * + * Port E, Bit 0: RXD0, USART0 Receive Pin. Receive Data (Data input pin + * for the USART0). When the USART0 receiver is enabled this pin is + * configured as an input regardless of the value of DDRE0. When the + * USART0 forces this pin to be an input, a logical one in PORTE0 will + * turn on the internal pull-up. + * + * Port E, Bit 1: TXD0, USART0 Transmit pin. + * + * REVISIT: According to table 41, TXD0 is also automatically configured. + * However, this is not explicitly stated in the text. + */ + + DDRE |= (1 << 1); /* Force Port E pin 1 to be an output -- might not be necessary */ + PORTE |= (1 << 0); /* Set pull-up on Port E pin 0 */ +#endif + + /* Set the baud rate divisor */ + + UBRR0H = AVR_UBRR0 >> 8; + UBRR0L = AVR_UBRR0 & 0xff; +} +#endif + +#ifdef CONFIG_AVR_USART1 +void usart1_configure(void) +{ + uint8_t ucsr1b; + uint8_t ucsr1c; + + /* Select normal or double speed. */ + +#ifdef USART1_DOUBLE_SPEED + UCSR1A = (1 << U2X1); +#else + UCSR1A = 0; +#endif + + /* Select baud, parity, nubmer of bits, stop bits, etc. */ + + ucsr1b = ((1 << TXEN1) | (1 << RXEN1)); + ucsr1c = 0; + + /* Select parity */ + +#if CONFIG_USART1_PARITY == 1 + ucsr1c |= ((1 << UPM11) | (1 << UPM10)); /* Odd parity */ +#elif CONFIG_USART1_PARITY == 2 + ucsr1c |= (1 << UPM11); /* Even parity */ +#endif + + /* 1 or 2 stop bits */ + +#if defined(CONFIG_USART1_2STOP) && CONFIG_USART1_2STOP > 0 + ucsr1c |= (1 << USBS1); /* Two stop bits */ +#endif + + /* Word size */ + +#if CONFIG_USART1_BITS == 5 +#elif CONFIG_USART1_BITS == 6 + ucsr1c |= (1 << UCSZ10); +#elif CONFIG_USART1_BITS == 7 + ucsr1c |= (1 << UCSZ11); +#elif CONFIG_USART1_BITS == 8 + ucsr1c |= ((1 << UCSZ10) | (1 << UCSZ11)); +#elif CONFIG_USART1_BITS == 9 + ucsr1c |= ((1 << CSZ10) | (1 << UCSZ11)); + ucsr1b |= (1 << UCSZ12); +#else +# error "Unsupported word size" +#endif + + UCSR1B = ucsr1b; + UCSR1C = ucsr1c; + + /* Pin Configuration: None necessary, Port D bits 2&3 are automatically + * configured: + * + * Port D, Bit 2: RXD1, Receive Data (Data input pin for the USART1). When + * the USART1 receiver is enabled this pin is configured as an input + * regardless of the value of DDD2. When the USART forces this pin to + * be an input, the pull-up can still be controlled by the PORTD2 bit. + * Port D, Bit 3: TXD1, Transmit Data (Data output pin for the USART1). + * When the USART1 Transmitter is enabled, this pin is configured as + * an output regardless of the value of DDD3. + */ + + DDRD |= (1 << 3); /* Force Port D pin 3 to be an output -- should not be necessary */ + PORTD |= (1 << 2); /* Set pull-up on port D pin 2 */ + + /* Set the baud rate divisor */ + + UBRR1H = AVR_UBRR1 >> 8; + UBRR1L = AVR_UBRR1 & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Initialize a console for debug output. This function is called very + * early in the initialization sequence to configure the serial console uart + * (only). + * + ****************************************************************************/ + +void up_consoleinit(void) +{ +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_USART0_SERIAL_CONSOLE) + usart0_configure(); +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) + usart1_configure(); +# endif +#endif +} + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_USART0_SERIAL_CONSOLE) + while ((UCSR0A & (1 << UDRE0)) == 0); + UDR0 = ch; +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) + while ((UCSR1A & (1 << UDRE1)) == 0); + UDR1 = ch; +# endif +#endif +} diff --git a/arch/avr/src/atmega/atmega_lowinit.c b/arch/avr/src/atmega/atmega_lowinit.c new file mode 100644 index 0000000000000000000000000000000000000000..50cf88f888812342f0247f12e926da4300d307e2 --- /dev/null +++ b/arch/avr/src/atmega/atmega_lowinit.c @@ -0,0 +1,157 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega_lowinit.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "atmega_config.h" +#include "up_internal.h" +#include "atmega.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_WDTO_15MS) +# define WDTO_VALUE WDTO_15MS +#elif defined(CONFIG_WDTO_30MS) +# define WDTO_VALUE WDTO_30MS +#elif defined(CONFIG_WDTO_60MS) +# define WDTO_VALUE WDTO_60MS +#elif defined(CONFIG_WDTO_120MS) +# define WDTO_VALUE WDTO_120MS +#elif defined(CONFIG_WDTO_1250MS) +# define WDTO_VALUE WDTO_250MS +#elif defined(CONFIG_WDTO_500MS) +# define WDTO_VALUE WDTO_500MS +#elif defined(CONFIG_WDTO_1S) +# define WDTO_VALUE WDTO_1S +#elif defined(CONFIG_WDTO_2S) +# define WDTO_VALUE WDTO_2S +#elif defined(CONFIG_WDTO_4S) +# define WDTO_VALUE WDTO_4S +#else /* if defined(CONFIG_WDTO_8S) */ +# define WDTO_VALUE WDTO_8S +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_wdtinit + * + * Description: + * Initialize the watchdog per the NuttX configuration. + * + ****************************************************************************/ + +static inline void up_wdtinit(void) +{ +#ifdef CONFIG_AVR_WDT + wdt_enable(WDTO_VALUE); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowinit + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowinit(void) +{ + /* Disable the watchdog timer */ + + wdt_disable(); + + /* Set the system clock divider to 1 */ + +#ifdef CONFIG_ARCH_CHIP_ATMEGA1284P + CLKPR = 0x80; + CLKPR = 0; +#elif defined(XDIV) + XDIV = 0; +#endif + + /* Initialize the watchdog timer */ + + up_wdtinit(); + + /* Initialize a console (probably a serial console) */ + + up_consoleinit(); + + /* Perform early serial initialization (so that we will have debug output + * available as soon as possible). + */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-level initialization */ + + atmega_boardinitialize(); +} diff --git a/arch/avr/src/atmega/atmega_memorymap.h b/arch/avr/src/atmega/atmega_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..d957247d5c36ac010cf3e2bfbbf6fd1ef073a677 --- /dev/null +++ b/arch/avr/src/atmega/atmega_memorymap.h @@ -0,0 +1,62 @@ +/************************************************************************************ + * arch/avr/src/atmega/atmega_memorymap.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H +#define __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_ATMEGA_MEMORYMAP_H */ + diff --git a/arch/avr/src/atmega/atmega_serial.c b/arch/avr/src/atmega/atmega_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..9f770363a1db72501b30bfceb081a7339449a472 --- /dev/null +++ b/arch/avr/src/atmega/atmega_serial.c @@ -0,0 +1,1017 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega_serial.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "atmega_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "atmega.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Is there at least one USART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_USART_DEVICE +# warning "No USARTs enabled as RS-232 devices" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which USART with be tty0/console and which tty1? */ + +#undef CONSOLE_DEV +#undef TTYS0_DEV +#undef TTYS1_DEV + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart0port /* USART0 is console */ +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# ifdef CONFIG_AVR_USART1 +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# endif +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_usart1port /* USART1 is console */ +# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */ +# ifdef CONFIG_AVR_USART0 +# define TTYS1_DEV g_usart0port /* USART0 is ttyS1 */ +# endif +#elif defined(CONFIG_AVR_USART0) +# define TTYS0_DEV g_usart0port /* USART0 is ttyS0 */ +# ifdef CONFIG_AVR_USART1 +# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */ +# endif +#elif defined(CONFIG_AVR_USART1) +# define TTYS0_DEV g_usart1port /* USART1 is ttyS1 */ +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_setup(struct uart_dev_s *dev); +static void usart0_shutdown(struct uart_dev_s *dev); +static int usart0_attach(struct uart_dev_s *dev); +static void usart0_detach(struct uart_dev_s *dev); +static int usart0_rxinterrupt(int irq, void *context); +static int usart0_txinterrupt(int irq, void *context); +static int usart0_ioctl(struct file *filep, int cmd, unsigned long arg); +static int usart0_receive(struct uart_dev_s *dev, FAR unsigned int *status); +static void usart0_rxint(struct uart_dev_s *dev, bool enable); +static bool usart0_rxavailable(struct uart_dev_s *dev); +static void usart0_send(struct uart_dev_s *dev, int ch); +static void usart0_txint(struct uart_dev_s *dev, bool enable); +static bool usart0_txready(struct uart_dev_s *dev); +static bool usart0_txempty(struct uart_dev_s *dev); +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_setup(struct uart_dev_s *dev); +static void usart1_shutdown(struct uart_dev_s *dev); +static int usart1_attach(struct uart_dev_s *dev); +static void usart1_detach(struct uart_dev_s *dev); +static int usart1_rxinterrupt(int irq, void *context); +static int usart1_txinterrupt(int irq, void *context); +static int usart1_ioctl(struct file *filep, int cmd, unsigned long arg); +static int usart1_receive(struct uart_dev_s *dev, FAR unsigned int *status); +static void usart1_rxint(struct uart_dev_s *dev, bool enable); +static bool usart1_rxavailable(struct uart_dev_s *dev); +static void usart1_send(struct uart_dev_s *dev, int ch); +static void usart1_txint(struct uart_dev_s *dev, bool enable); +static bool usart1_txready(struct uart_dev_s *dev); +static bool usart1_txempty(struct uart_dev_s *dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* USART0 operations */ + +#ifdef CONFIG_AVR_USART0 +struct uart_ops_s g_usart0_ops = +{ + .setup = usart0_setup, + .shutdown = usart0_shutdown, + .attach = usart0_attach, + .detach = usart0_detach, + .ioctl = usart0_ioctl, + .receive = usart0_receive, + .rxint = usart0_rxint, + .rxavailable = usart0_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = usart0_send, + .txint = usart0_txint, + .txready = usart0_txready, + .txempty = usart0_txempty, +}; + +/* USART0 I/O buffers */ + +static char g_usart0rxbuffer[CONFIG_USART0_RXBUFSIZE]; +static char g_usart0txbuffer[CONFIG_USART0_TXBUFSIZE]; + +/* This describes the state of the ATMega USART0 port. */ + +static uart_dev_t g_usart0port = +{ + .recv = + { + .size = CONFIG_USART0_RXBUFSIZE, + .buffer = g_usart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART0_TXBUFSIZE, + .buffer = g_usart0txbuffer, + }, + .ops = &g_usart0_ops, +}; +#endif + +/* USART1 operations */ + +#ifdef CONFIG_AVR_USART1 +struct uart_ops_s g_usart1_ops = +{ + .setup = usart1_setup, + .shutdown = usart1_shutdown, + .attach = usart1_attach, + .detach = usart1_detach, + .ioctl = usart1_ioctl, + .receive = usart1_receive, + .rxint = usart1_rxint, + .rxavailable = usart1_rxavailable, + .send = usart1_send, + .txint = usart1_txint, + .txready = usart1_txready, + .txempty = usart1_txempty, +}; + +/* USART 1 I/O buffers */ + +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; + +/* This describes the state of the ATMega USART1 port. */ + +static uart_dev_t g_usart1port = +{ + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_usart1_ops, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usart0/1_restoreusartint + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_restoreusartint(uint8_t imr) +{ + uint8_t regval; + + regval = UCSR0B; + regval &= ~((1 << RXCIE0) | (1 << TXCIE0) | (1 << UDRIE0)); + imr &= ((1 << RXCIE0) | (1 << TXCIE0) | (1 << UDRIE0)); + regval |= imr; + UCSR0B = regval; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_restoreusartint(uint8_t imr) +{ + uint8_t regval; + + regval = UCSR1B; + regval &= ~((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + imr &= ((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + regval |= imr; + UCSR1B = regval; +} +#endif + +/**************************************************************************** + * Name: usart0/1_disableusartint + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static inline void usart0_disableusartint(uint8_t *imr) +{ + uint8_t regval; + + regval = UCSR0B; + *imr = regval; + regval &= ~((1 << RXCIE0) | (1 << TXCIE0) | (1 << UDRIE0)); + UCSR0B = regval; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static inline void usart1_disableusartint(uint8_t *imr) +{ + uint8_t regval; + + regval = UCSR1B; + *imr = regval; + regval &= ~((1 << RXCIE1) | (1 << TXCIE1) | (1 << UDRIE1)); + UCSR0B = regval; +} +#endif + +/**************************************************************************** + * Name: usart0/1_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + /* Configure the USART as an RS-232 UART */ + + usart0_configure(); +#endif + + return OK; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + /* Configure the USART as an RS-232 UART */ + + usart1_configure(); +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Name: usart0/1_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_shutdown(struct uart_dev_s *dev) +{ + /* Reset, disable interrupts, and disable Rx and Tx */ + + usart0_reset(); +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_shutdown(struct uart_dev_s *dev) +{ + /* Reset, disable interrupts, and disable Rx and Tx */ + + usart1_reset(); +} +#endif + +/**************************************************************************** + * Name: usart0/1_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_attach(struct uart_dev_s *dev) +{ + /* Attach the USART0 IRQs: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + (void)irq_attach(ATMEGA_IRQ_U0RX, usart0_rxinterrupt); + (void)irq_attach(ATMEGA_IRQ_U0DRE, usart0_txinterrupt); +//(void)irq_attach(ATMEGA_IRQ_U0TX, usart0_txinterrupt); + return OK; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_attach(struct uart_dev_s *dev) +{ + /* Attach the USART1 IRQs: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + (void)irq_attach(ATMEGA_IRQ_U1RX, usart1_rxinterrupt); + (void)irq_attach(ATMEGA_IRQ_U1DRE, usart1_txinterrupt); +//(void)irq_attach(ATMEGA_IRQ_U1TX, usart1_txinterrupt); + return OK; +} +#endif + +/**************************************************************************** + * Name: usart0/1_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_detach(struct uart_dev_s *dev) +{ + /* Disable all USART0 interrupts */ + + usart0_disableusartint(NULL); + + /* Detach the USART0 IRQs */ + + (void)irq_detach(ATMEGA_IRQ_U0RX); + (void)irq_detach(ATMEGA_IRQ_U0DRE); +// (void)irq_detach(ATMEGA_IRQ_U0TX); +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_detach(struct uart_dev_s *dev) +{ + /* Disable all USART1 interrupts */ + + usart1_disableusartint(NULL); + + /* Detach the USART1 IRQs */ + + (void)irq_detach(ATMEGA_IRQ_U1RX); + (void)irq_detach(ATMEGA_IRQ_U1DRE); +//(void)irq_detach(ATMEGA_IRQ_U1TX); +} +#endif + +/**************************************************************************** + * Name: usart0/1_rxinterrupt + * + * Description: + * This is the USART RX interrupt handler. It will be invoked when an + * RX interrupt received. It will call uart_receivechar to perform the RX + * data transfers. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_rxinterrupt(int irq, void *context) +{ + uint8_t ucsr0a = UCSR0A; + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((ucsr0a & (1 << RXC0)) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(&g_usart0port); + } + + return OK; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_rxinterrupt(int irq, void *context) +{ + uint8_t ucsr1a = UCSR1A; + + /* Handle incoming, receive bytes (with or without timeout) */ + + if ((ucsr1a & (1 << RXC1)) != 0) + { + /* Received data ready... process incoming bytes */ + + uart_recvchars(&g_usart1port); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: usart0/1_txinterrupt + * + * Description: + * This is the USART TX interrupt handler. It will be invoked when an + * TX or DRE interrupt received. It will call uart_xmitchars to perform + * the TXdata transfers. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_txinterrupt(int irq, void *context) +{ + uint8_t ucsr0a = UCSR0A; + + /* Handle outgoing, transmit bytes when the transmit data buffer is empty. + * (There may still be data in the shift register). + */ + + if ((ucsr0a & (1 << UDRE0)) != 0) + { + /* Transmit data regiser empty ... process outgoing bytes */ + + uart_xmitchars(&g_usart0port); + } + + return OK; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_txinterrupt(int irq, void *context) +{ + uint8_t ucsr1a = UCSR1A; + + /* Handle outgoing, transmit bytes when the transmit data buffer is empty. + * (There may still be data in the shift register). + */ + + if ((ucsr1a & (1 << UDRE1)) != 0) + { + /* Transmit data regiser empty ... process outgoing bytes */ + + uart_xmitchars(&g_usart1port); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: usart0/1_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + int ret = OK; + + switch (cmd) + { + case TCGETS: + case TCSETS: + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + int ret = OK; + + switch (cmd) + { + case TCGETS: + case TCSETS: + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} +#endif + +/**************************************************************************** + * Name: usart0/1_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static int usart0_receive(struct uart_dev_s *dev, FAR unsigned int *status) +{ + /* Return status information */ + + if (status) + { + *status = (FAR unsigned int)UCSR0A; + } + + /* Then return the actual received byte */ + + return UDR0; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static int usart1_receive(struct uart_dev_s *dev, FAR unsigned int *status) +{ + /* Return status information */ + + if (status) + { + *status = (FAR unsigned int)UCSR1A; + } + + /* Then return the actual received byte */ + + return UDR1; +} +#endif + +/**************************************************************************** + * Name: usart0/1_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_rxint(struct uart_dev_s *dev, bool enable) +{ + /* Enable/disable RX interrupts: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR0B |= (1 << RXCIE0); +#endif + } + else + { + UCSR0B &= ~(1 << RXCIE0); + } +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_rxint(struct uart_dev_s *dev, bool enable) +{ + /* Enable/disable RX interrupts: + * + * RX: USART Receive Complete. Set when are unread data in the receive + * buffer and cleared when the receive buffer is empty. + */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR1B |= (1 << RXCIE1); +#endif + } + else + { + UCSR1B &= ~(1 << RXCIE1); + } +} +#endif + +/**************************************************************************** + * Name: usart0/1_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static bool usart0_rxavailable(struct uart_dev_s *dev) +{ + return (UCSR0A & (1 << RXC0)) != 0; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static bool usart1_rxavailable(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << RXC1)) != 0; +} +#endif + +/**************************************************************************** + * Name: usart0/1_send + * + * Description: + * This method will send one byte on the USART. + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_send(struct uart_dev_s *dev, int ch) +{ + UDR0 = ch; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_send(struct uart_dev_s *dev, int ch) +{ + UDR1 = ch; +} +#endif + +/**************************************************************************** + * Name: usart0/1_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static void usart0_txint(struct uart_dev_s *dev, bool enable) +{ + irqstate_t flags; + + /* Enable/disable TX interrupts: + * + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR0B |= (1 << UDRIE0); +// UCSR0B |= (1 << TXCIE0); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(&g_usart0port); +#endif + } + else + { + /* Disable the TX interrupt */ + + UCSR0B &= ~((1 << UDRIE0) | (1 << TXCIE0)); + } + + leave_critical_section(flags); +} +#endif + +#ifdef CONFIG_AVR_USART1 +static void usart1_txint(struct uart_dev_s *dev, bool enable) +{ + irqstate_t flags; + + /* Enable/disable TX interrupts: + * + * TX: USART Transmit Complete. Set when the entire frame in the Transmit + * Shift Register has been shifted out and there are no new data + * currently present in the transmit buffer. + * DRE: USART Data Register Empty. Indicates if the transmit buffer is ready + * to receive new data: The buffer is empty, and therefore ready to be + * written. + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + UCSR1B |= (1 << UDRIE1); +// UCSR1B |= (1 << TXCIE1); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(&g_usart1port); +#endif + } + else + { + /* Disable the TX interrupt */ + + UCSR1B &= ~((1 << UDRIE1) | (1 << TXCIE1)); + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: usart0/1_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static bool usart0_txready(struct uart_dev_s *dev) +{ + return (UCSR0A & (1 << UDRE0)) != 0; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static bool usart1_txready(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << UDRE1)) != 0; +} +#endif + +/**************************************************************************** + * Name: usart0/1_txempty + * + * Description: + * Return true if the tranmsit data register and shift reqister are both + * empty + * + ****************************************************************************/ + +#ifdef CONFIG_AVR_USART0 +static bool usart0_txempty(struct uart_dev_s *dev) +{ + return (UCSR0A & (1 << TXC0)) != 0; +} +#endif + +#ifdef CONFIG_AVR_USART1 +static bool usart1_txempty(struct uart_dev_s *dev) +{ + return (UCSR1A & (1 << TXC1)) != 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable all USARTS */ + +#ifdef CONFIG_AVR_USART0 + usart0_disableusartint(NULL); +#endif +#ifdef CONFIG_AVR_USART1 + usart1_disableusartint(NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; +# if defined(CONFIG_USART0_SERIAL_CONSOLE) + usart0_setup(&g_usart0port); +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) + usart1_setup(&g_usart1port); +# endif +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all USARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + uint8_t imr; + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) + usart0_disableusartint(&imr); +#else + usart1_disableusartint(&imr); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + +#if defined(CONFIG_USART0_SERIAL_CONSOLE) + usart0_restoreusartint(imr); +#else + usart1_restoreusartint(imr); +#endif +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/avr/src/atmega/atmega_timerisr.c b/arch/avr/src/atmega/atmega_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..c0572b030a578b6eeb756d5f77c82c1b38db0145 --- /dev/null +++ b/arch/avr/src/atmega/atmega_timerisr.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/avr/src/atmega/atmega_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "atmega.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The CPU frequency is given by BOARD_CPU_CLOCK (defined in board.h). The + * desired interrupt frequency is given by CONFIG_USEC_PER_TICK. An unscaled + * ideal match is given by: + * + * CLOCK = CPU_CLOCK / DIVISOR # CPU clocks/sec + * MATCH = CLOCK / CLOCKS_PER_SEC # CPU clocks/timer tick + * MATCH = CPU_CLOCK / DIVISOR / CLOCKS_PER_SEC # CPU clocks/timer tick + * + * But we only have 16-bits of accuracy so we need to pick the smallest + * divisor using the following brute force calculation: + */ + +#define MATCH1 (( BOARD_CPU_CLOCK + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH8 ((((BOARD_CPU_CLOCK + 4) / 8) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH64 ((((BOARD_CPU_CLOCK + 8) / 64) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH256 ((((BOARD_CPU_CLOCK + 128) / 256) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) +#define MATCH1024 ((((BOARD_CPU_CLOCK + 512) / 1024) + CLOCKS_PER_SEC/2) / CLOCKS_PER_SEC) + +#if MATCH1 <= 65536 +# define MATCH (MATCH1-1) +# define PRESCALE 1 +#elif MATCH8 <= 65536 +# define MATCH (MATCH8-1) +# define PRESCALE 2 +#elif MATCH64 <= 65536 +# define MATCH (MATCH64-1) +# define PRESCALE 3 +#elif MATCH256 <= 65536 +# define MATCH (MATCH256-1) +# define PRESCALE 4 +#elif MATCH1024 <= 65536 +# define MATCH (MATCH1024-1) +# define PRESCALE 5 +#else +# error "Cannot represent this timer frequency" +#endif + +/* Eg. CPU_CLOCK = 8MHz, CLOCKS_PER_SEC = 100 + * + * MATCH1 ((8000000 + 50) / 100) = 80,000 FREQ=100.0Hz + * MATCH8 ((1000000 + 50) / 100) = 10,000 FREQ=100.0Hz <-- this one + * MATCH64 (( 125000 + 50) / 100) = 1,250 FREQ=100.0Hz + * MATCH256 (( 31250 + 50) / 100) = 313 FREQ=99.8Hz + * MATCH1024 (( 7804 + 50) / 100) = 78 FREQ=100.1Hz + */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. NOTE: This function depends on setup of OSC32 by + * up_clkinitialize(). + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Setup timer 1 compare match A to generate a tick interrupt. + * + * First, setup the match value for compare match A. + */ + + OCR1AH = (uint8_t)((uint16_t)MATCH >> 8); + OCR1AL = (uint8_t)((uint16_t)MATCH & 0xff); + + /* Setup clock source and compare match behaviour. + * + * TCRR1A: + * COM1A 0:1 = 00 -> Normal port operation + * COM1B 0:1 = 00 -> Normal port operation + * COM1C 0:1 = 00 -> Normal port operation + * WGM1 0:1 = 00 -> Clear Timer on Compare (CTC) modes of operation + */ + + TCCR1A = 0; + + /* TCCR1B: + * ICNC1 = 0 -> Input Capture Noise Canceler disabled + * ICES1 = 0 -> Input Capture Edge Select + * WGM 2:3 = 01 -> Clear Timer on Compare (CTC) modes of operation + * CS1 0:2 = xxx ->Selected pre-scaler. + */ + + TCCR1B = (1 << WGM12) | PRESCALE; + + /* Attach the timer interrupt vector */ + +#if defined(ATMEGA_IRQ_T1COMPA) + (void)irq_attach(ATMEGA_IRQ_T1COMPA, (xcpt_t)up_timerisr); +#elif defined(ATMEGA_IRQ_TIM1_COMPA) + (void)irq_attach(ATMEGA_IRQ_TIM1_COMPA, (xcpt_t)up_timerisr); +#else +# error "Unable to find IRQ for timer" +#endif + + /* Enable the interrupt on compare match A */ + +#if defined(TIMSK1) + TIMSK1 |= (1 << OCIE1A); +#else + TIMSK |= (1 << OCIE1A); +#endif +} diff --git a/arch/avr/src/atmega/chip.h b/arch/avr/src/atmega/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..43f54df3134203e3981b75e2823b130f2481f9b1 --- /dev/null +++ b/arch/avr/src/atmega/chip.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * arch/avr/src/atmega/chip.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_ATMEGA_CHIP_H +#define __ARCH_AVR_SRC_ATMEGA_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Define features for supported chip in the ATMEGA family */ + +#if 1 +#else +# error "Unsupported AVR chip" +#endif + +/* Include only the memory map. Other chip hardware files should then include this + * file for the proper setup + */ + +#include "atmega_memorymap.h" + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_AVR_SRC_ATMEGA_CHIP_H */ + diff --git a/arch/avr/src/avr/Kconfig b/arch/avr/src/avr/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..496529f32c8a9bffb8b30c1ae6672c397a0b5679 --- /dev/null +++ b/arch/avr/src/avr/Kconfig @@ -0,0 +1,86 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_FAMILY_AVR +comment "AVR Configuration Options" + +choice + prompt "Toolchain" + default AVR_WINAVR_TOOLCHAIN if HOST_WINDOWS + default AVR_BUILDROOT_TOOLCHAIN if HOST_LINUX + default AVR_CROSSPACK_TOOLCHAIN if HOST_OSX + +config AVR_WINAVR_TOOLCHAIN + bool "WinAVR" + depends on HOST_WINDOWS + ---help--- + For Cygwin development environment on Windows machines, you + can use WinAVR: http://sourceforge.net/projects/winavr/files/ + + It is assumed in some places that WinAVR is installed at + C:/WinAVR. Edit the setenv.sh file if this is not the case. + + WARNING: There is an incompatible version of cygwin.dll in + the WinAVR/bin directory! Make sure that the path to the + correct cygwin.dll file precedes the path to the WinAVR + binaries! + +config AVR_ATMEL_AVR_TOOLCHAIN + bool "Atmel AVR Toolchain" + depends on HOST_WINDOWS + ---help--- + Atmel provides GNU Toolchain for AVR development. It can + be obtained by installing Atmel Studio 6 and later or + as standalone package from Atmel. + +config AVR_LINUXGCC_TOOLCHAIN + bool "Linux GCC" + depends on HOST_LINUX + ---help--- + For Linux, there are widely available avr-gcc packages. On + Ubuntu, use: sudo apt-get install gcc-avr gdb-avr avr-libc + +config AVR_CROSSPACK_TOOLCHAIN + bool "CrossPack-AVR" + depends on HOST_OSX + ---help--- + For OS X, the AVR CrossPack toolchain is supported: + http://www.obdev.at/products/crosspack/index.html + + It is assumed that /usr/local/CrossPack-AVR/bin is on the + user's path. Edit the setenv.sh file if this is not the + case. + +config AVR_BUILDROOT_TOOLCHAIN + bool "Buildroot" + depends on HOST_LINUX || HOST_WINDOWS + ---help--- + There is a DIY buildroot version for the AVR boards here: + http://sourceforge.net/projects/nuttx/files/buildroot/. See + the following section for details on building this toolchain. + + It is assumed in some places that buildroot toolchain is + available at ../buildroot/build_avr. Edit the setenv.sh + file if this is not the case. + +endchoice # Toolchain + +menu "Atmel AVR Toolchain options" + depends on AVR_ATMEL_AVR_TOOLCHAIN + +config AVR_HAS_MEMX_PTR + bool "Enable in-flash static const stings" + depends on AVR_ATMEL_AVR_TOOLCHAIN + select ARCH_DEBUG_H + default y + ---help--- + Enabling this option (recommended) will place all constant + strings used for debugging and assertion in program memory + and allow the corresponding routines to get the strings + directly from there. This will dramatically decrease amount + of RAM needed to hold this static data. + +endmenu # Atmel AVR Toolchain options +endif # ARCH_FAMILY_AVR diff --git a/arch/avr/src/avr/Toolchain.defs b/arch/avr/src/avr/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..7503086fb07d90a4fab716fdf25a394aadbd7c9e --- /dev/null +++ b/arch/avr/src/avr/Toolchain.defs @@ -0,0 +1,140 @@ +############################################################################ +# arch/avr/src/avr/Toolchain.defs +# +# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Handle old-style chip-specific toolchain names in the absence of +# a new-style toolchain specification, force the selection of a single +# toolchain and allow the selected toolchain to be overridden by a +# command-line selection. +# + +ifeq ($(filter y, \ + $(CONFIG_AVR_BUILDROOT_TOOLCHAIN) \ + ),y) + CONFIG_AVR_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_AVR_CROSSPACK_TOOLCHAIN) \ + ),y) + CONFIG_AVR_TOOLCHAIN ?= CROSSPACK +endif + +ifeq ($(filter y, \ + $(CONFIG_AVR_LINUXGCC_TOOLCHAIN) \ + ),y) + CONFIG_AVR_TOOLCHAIN ?= LINUXGCC +endif + +ifeq ($(filter y, \ + $(CONFIG_AVR_WINAVR_TOOLCHAIN) \ + ),y) + CONFIG_AVR_TOOLCHAIN ?= WINAVR +endif + +ifeq ($(filter y, \ + $(CONFIG_AVR_ATMEL_AVR_TOOLCHAIN) \ + ),y) + CONFIG_AVR_TOOLCHAIN ?= ATMEL +endif + +# Chip-specific CPU flags + +ifeq ($(CONFIG_ARCH_CHIP_ATMEGA128),y) + ARCHCPUFLAGS += -mmcu=atmega128 +else ifeq ($(CONFIG_ARCH_CHIP_ATMEGA1284P),y) + ARCHCPUFLAGS += -mmcu=atmega1284p +else ifeq ($(CONFIG_ARCH_CHIP_AT90USB646),y) + ARCHCPUFLAGS += -mmcu=at90usb646 +else ifeq ($(CONFIG_ARCH_CHIP_AT90USB647),y) + ARCHCPUFLAGS += -mmcu=at90usb647 +else ifeq ($(CONFIG_ARCH_CHIP_AT90USB1286),y) + ARCHCPUFLAGS += -mmcu=at90usb1286 +else ifeq ($(CONFIG_ARCH_CHIP_AT90USB1287),y) + ARCHCPUFLAGS += -mmcu=at90usb1287 +else ifeq ($(CONFIG_ARCH_CHIP_ATMEGA2560),y) + ARCHCPUFLAGS += -mmcu=atmega2560 +else + $(error "No valid CONFIG_ARCH_CHIP_ set in the configuration") +endif + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# NuttX buildroot GCC toolchain under Linux or Cygwin + +ifeq ($(CONFIG_AVR_TOOLCHAIN),BUILDROOT) + CROSSDEV ?= avr-nuttx-elf- + MAXOPTIMIZATION ?= -O2 + LDFLAGS += -nostartfiles -nodefaultlibs +endif + +# AVR CrossPack under OS X + +ifeq ($(CONFIG_AVR_TOOLCHAIN),CROSSPACK) + CROSSDEV ?= avr- + MAXOPTIMIZATION ?= -O2 + LDFLAGS += -nostartfiles -nodefaultlibs +endif + +# GCC toolchain under Linux + +ifeq ($(CONFIG_AVR_TOOLCHAIN),LINUXGCC) + CROSSDEV ?= avr- + MAXOPTIMIZATION ?= -O2 + LDFLAGS += -nostartfiles -nodefaultlibs +endif + +# WinAVR or Atmel toolchain under Windows/Cygwin + +_WINAVR = 0 +ifeq ($(CONFIG_AVR_TOOLCHAIN),WINAVR) +_WINAVR = 1 +endif +ifeq ($(CONFIG_AVR_TOOLCHAIN),ATMEL) +_WINAVR = 1 +endif + +ifeq ($(_WINAVR),1) + CROSSDEV ?= avr- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + MAXOPTIMIZATION ?= -O2 + LDFLAGS += -nostartfiles -nodefaultlibs +endif diff --git a/arch/avr/src/avr/avr.h b/arch/avr/src/avr/avr.h new file mode 100644 index 0000000000000000000000000000000000000000..b1b37befe60715b22a29955cbf4db336877f7061 --- /dev/null +++ b/arch/avr/src/avr/avr.h @@ -0,0 +1,195 @@ +/**************************************************************************** + * arch/avr/src/avr/avr.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AVR_AVR_H +#define __ARCH_AVR_SRC_AVR_AVR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Macros to handle saving and restore interrupt state. The state is copied + * from the stack to the TCB, but only a referenced is passed to get the + * state from the TCB. + */ + +#define up_savestate(regs) up_copystate(regs, (uint8_t*)g_current_regs) +#define up_restorestate(regs) (g_current_regs = regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +extern volatile uint8_t *g_current_regs; + +/* This is the beginning of heap as provided from up_head.S. This is the first + * address in DRAM after the loaded program+bss+idle stack. The end of the + * heap is CONFIG_RAM_END + */ + +extern uint16_t g_idle_topstack; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: up_copystate + * + * Description: + * Copy the contents of a register state save structure from one location to + * another. + * + ************************************************************************************/ + +void up_copystate(uint8_t *dest, uint8_t *src); + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Restore the full context of a saved thread/task. + * + ************************************************************************************/ + +void up_fullcontextrestore(uint8_t *restoreregs) noreturn_function; + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Switch from one thread/task context to another. + * + ************************************************************************************/ + +void up_switchcontext(uint8_t *saveregs, uint8_t *restoreregs); + +/************************************************************************************ + * Name: up_doirq + * + * Description: + * Dispatch an interrupt. + * + ************************************************************************************/ + +uint8_t *up_doirq(uint8_t irq, uint8_t *regs); + +/**************************************************************************** + * Name: avr_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s; /* Forward references */ +enum spi_dev_e; /* Forward references */ + +FAR struct spi_dev_s *avr_spibus_initialize(int port); + +/************************************************************************************ + * Name: avr_spiselect, avr_spitatus, and avr_spicmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including avr_spibus_initialize()) are provided by common LPC17xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in _boardinitialize() to configure SPI chip select + * pins. + * 2. Provide avr_spiselect() and avr_spistatus() functions in your board-specific + * logic. These functions will perform chip selection and status operations + * using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide the + * avr_spicmddata() function in your board-specific logic. This functions will + * perform cmd/data selection operations using GPIOs in the way your board is + * configured. + * 3. Add a call to at90usb_spiinitialize() in your low level application + * initialization logic + * 4. The handle returned by avr_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_AVR_SPI +void avr_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t avr_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int avr_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_AVR_AVR_H */ + diff --git a/arch/avr/src/avr/excptmacros.h b/arch/avr/src/avr/excptmacros.h new file mode 100644 index 0000000000000000000000000000000000000000..2af838560dc3550147c0cdc6a799202660fbedb7 --- /dev/null +++ b/arch/avr/src/avr/excptmacros.h @@ -0,0 +1,641 @@ +/******************************************************************************************** + * arch/avr/src/avr/excptmacros.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AVR_EXCPTMACROS_H +#define __ARCH_AVR_SRC_AVR_EXCPTMACROS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#ifdef __ASSEMBLY__ + +#include + +#include +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Symbols + ********************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase + .global g_nestlevel +#endif + +/******************************************************************************************** + * Assembly Language Macros + ********************************************************************************************/ + +/******************************************************************************************** + * General Exception Handling Example: + * + * HANDLER IRQ_X, my_exception + * ... + * my_exception: + * EXCPT_PROLOGUE - Save registers on stack + * in r22, _SFR_IO_ADDR(SPL) - Pass register save structure as the parameter 2 + * in r23, _SFR_IO_ADDR(SPH) - (Careful, push post-decrements) + * USE_INTSTACK rx, ry, rz - Switch to the interrupt stack + * call handler - Handle the exception IN=old regs OUT=new regs + * RESTORE_STACK rx, ry - Undo the operations of USE_INTSTACK + * EXCPT_EPILOGUE - Return to the context returned by handler() + * reti - Return from interrupt + * + ********************************************************************************************/ + +/******************************************************************************************** + * Name: HANDLER + * + * Description: + * This macro provides the exception entry logic. It is called with the PC already on the + * stack. It simply saves one register on the stack (r24) and passes the IRQ number to + * common logic (see EXCPT_PROLOGUE). + * + * On Entry: + * sp - Points to the top of the stack. The PC is already on the stack. + * Only the stack is available for storage + * + * PC1 + * PC0 + * --- <- SP + * + * At completion: + * Stack pointer is incremented by one, the saved r24 is on the stack, r24 now contains the + * IRQ number + * + * PC1 + * PC0 + * R0 + * --- <- SP + * + ********************************************************************************************/ + + .macro HANDLER, label, irqno, common + .global \label +\label: + push r24 + ldi r24, \irqno + rjmp \common + .endm + +/******************************************************************************************** + * Name: EXCPT_PROLOGUE + * + * Description: + * Provides the common "prologue" logic that should appear at the beginning of the exception + * handler. + * + * On Entry: + * r24 - has already been pushed onto the stack and now holds the IRQ number + * sp - Points to the top of the stack + * Only the stack is available for storage + * + * PC1 + * PC0 + * R24 + * --- <- SP + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp and + * r24 which still contains the IRQ number as set by the HANDLER macro. + * + ********************************************************************************************/ + + .macro EXCPT_PROLOGUE + + /* Save R25 */ + + push r25 + + /* Save the status register on the stack */ + + in r25, _SFR_IO_ADDR(SREG) /* Save the status register */ + cli /* Disable interrupts (not necessary) */ + ori r25, (1 << SREG_I) /* Interrupts re-enabled on restore */ + push r25 + + /* Save R0 -- the scratch register and the zero register (which may not be zero). R1 + * must be zero for our purposes + */ + + push r0 + push r1 + clr r1 + + /* Save r2-r17 - Call-saved, "static" registers */ + + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + + /* Save r18-r27 - Call-used, "volatile" registers (r24 was saved by + * HANDLER, r15 was saved above, and r26-r27 saved later, out of sequence) + */ + + push r18 + push r19 + push r20 + push r21 + push r22 + push r23 + + /* Save r28-r29 - Call-saved, "static" registers */ + + push r28 + push r29 + + /* Save r30-r31 - Call-used, "volatile" registers */ + + push r30 + push r31 + + /* Now save r26-r27 */ + + push r26 + push r27 + + /* Finally, save the stack pointer. BUT we want the value of the stack pointer as + * it was just BEFORE the exception. We'll have to add to get that value. + * The value to add is the size of the register save area including the bytes + * pushed by the interrupt handler (2), by the HANDLER macro (1), and the 32 + * registers pushed above. That is, the entire size of the register save structure + * MINUS two bytes for the stack pointer which has not yet been saved. + */ + + in r26, _SFR_IO_ADDR(SPL) + in r27, _SFR_IO_ADDR(SPH) + adiw r26, XCPTCONTEXT_REGS-2 + + push r26 /* SPL then SPH */ + push r27 + .endm + +/******************************************************************************************** + * Name: EXCPT_EPILOGUE + * + * Description: + * Provides the "epilogue" logic that should appear at the end of every exception handler. + * + * On input: + * sp points to the address of the register save area (just as left by EXCPT_PROLOGUE). + * All registers are available for use. + * Interrupts are disabled. + * + * On completion: + * All registers restored except the PC which remains on the stack so that a return + * via reti can be performed. + * + ********************************************************************************************/ + + .macro EXCPT_EPILOGUE, regs + + /* We don't need to restore the stack pointer */ + + pop r27 /* Discard SPH */ + pop r26 /* Discard SPL */ + + /* Restore r26-r27 */ + + pop r27 + pop r26 + + /* Restore r30-r31 - Call-used, "volatile" registers */ + + pop r31 + pop r30 + + /* Restore r28-r29 - Call-saved, "static" registers */ + + pop r29 + pop r28 + + /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 already + * restored, r24 and r25 will be restored later) + */ + + pop r23 + pop r22 + pop r21 + pop r20 + pop r19 + pop r18 + + /* Restore r2-r17 - Call-saved, "static" registers */ + + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + + /* Restore r0 - the scratch register and r1- the "zero" register (that may not be zero) */ + + pop r1 + pop r0 + + /* Restore the status register (probably enabling interrupts) */ + + pop r24 /* Restore the status register */ + andi r24, ~(1 << SREG_I) /* but keeping interrupts disabled until the reti */ + out _SFR_IO_ADDR(SREG), r24 + + /* Finally, restore r24-r25 - the temporary and IRQ number registers */ + + pop r25 + pop r24 + .endm + +/******************************************************************************************** + * Name: USER_SAVE + * + * Description: + * Similar to EXPCT_PROLOGUE except that (1) this saves values into a register save + * data structure instead of on the stack, (2) the pointer is in r26;r27, and (3) + * Call-used registers are not saved. + * + * On Entry: + * X [r26:r27] - Points to the register save structure. + * Return address is already on the stack (due to CALL or RCALL instruction)/. + * Interrupts are disabled. + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp. + * + ********************************************************************************************/ + + .macro USER_SAVE + + /* Pop the return address from the stack (PC0 then PC1). R18:19 are Call-used */ + +#if AVR_PC_SIZE > 16 + pop r20 +#endif /* AVR_PC_SIZE */ + pop r19 + pop r18 + + /* Save the current stack pointer as it would be after the return(SPH then SPL). */ + + in r25, _SFR_IO_ADDR(SPH) + st x+, r25 + in r24, _SFR_IO_ADDR(SPL) + st x+, r24 + + /* Skip over r26-r27 and r30-r31 - Call-used, "volatile" registers */ + + adiw r26, 4 /* Four registers: r26-r27 and r30-r31*/ + + /* Save r28-r29 - Call-saved, "static" registers */ + + st x+, r29 + st x+, r28 + + /* Skip over r18-r27 - Call-used, "volatile" registers (r26-r27 have + * already been skipped, r24 and r25 are saved elsewhere) + */ + + adiw r26, 6 /* Seven registers: r18-23 */ + + /* Save r2-r17 - Call-saved, "static" registers */ + + st x+, r17 + st x+, r16 + st x+, r15 + st x+, r14 + st x+, r13 + st x+, r12 + st x+, r11 + st x+, r10 + st x+, r9 + st x+, r8 + st x+, r7 + st x+, r6 + st x+, r5 + st x+, r4 + st x+, r3 + st x+, r2 + + /* Set r1 to zero - Function calls must return with r1=0 */ + + clr r1 + st x+, r1 + + /* Skip over r0 -- the scratch register */ + + adiw r26, 1 + + /* Save the status register (probably not necessary since interrupts are disabled) */ + + in r0, _SFR_IO_ADDR(SREG) + st x+, r0 + + /* Skip r24-r25 - These are scratch register and Call-used, "volatile" registers */ + + adiw r26, 2 /* Two registers: r24-r25 */ + + /* Save the return address that we have saved in r18:19*/ + +#if AVR_PC_SIZE > 16 + st x+, r20 +#endif /* AVR_PC_SIZE */ + st x+, r19 + st x+, r18 + .endm + +/******************************************************************************************** + * Name: TCB_RESTORE + * + * Description: + * Functionally equivalent to EXCPT_EPILOGUE excetp that register save area is not on the + * stack but is held in a data structure. + * + * On input: + * X [r26:r27] points to the data structure. + * All registers are available for use. + * Interrupts are disabled. + * + * On completion: + * All registers restored except for the PC with now resides at the top of the new stack + * so that ret can be used to switch to the new context. (ret, not reti, becaue ret + * will preserve the restored interrupt state). + * + ********************************************************************************************/ + + .macro TCB_RESTORE, regs + + /* X [r26:27] points to the register save block. Get an offset pointer to the PC in + * Y [r28:29] + */ + + movw r28, r26 /* Get a pointer to the PC0/PC1 storage location */ +#if AVR_PC_SIZE <= 16 + adiw r28, REG_PC0 +#else + adiw r28, REG_PC2 +#endif + + /* Fetch and set the new stack pointer */ + + ld r25, x+ /* Fetch stack pointer (post-incrementing) */ + out _SFR_IO_ADDR(SPH), r25 /* (SPH then SPL) */ + ld r24, x+ + out _SFR_IO_ADDR(SPL), r24 + + /* Fetch the return address and save it at the bottom of the new stack so + * that we can iret to switch contexts. The new stack is now: + * + * PC2 (for 24-bit PC arch) + * PC1 + * PC0 + * --- <- SP + */ + +#if AVR_PC_SIZE <= 16 + ld r25, y+ /* Load PC0 (r25) then PC1 (r24) */ + ld r24, y+ + push r24 /* Push PC0 and PC1 on the stack (PC1 then PC0) */ + push r25 +#else + ld r25, y /* Load PC2 (r25) */ + subi r28,1 + push r25 + ld r25, y /* Load PC1 (r25) */ + subi r28,1 + push r25 + ld r25, y /* Load PC0 (r25) */ + subi r28,1 + push r25 +#endif + + /* Then get value of X [r26:r27]. Save X on the new stack where we can + * recover it later. The new stack is now: + * + * PC2 (for 24-bit PC arch) + * PC1 + * PC0 + * R26 + * R27 + * --- <- SP + */ + + ld r25, x+ /* Fetch r26-r27 and save to the new stack */ + ld r24, x+ + push r24 /* r26 then r27 */ + push r25 + + /* Restore r30-r31 - Call-used, "volatile" registers */ + + ld r31, x+ + ld r30, x+ + + /* Restore r28-r29 - Call-saved, "static" registers */ + + ld r29, x+ + ld r28, x+ + + /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 have been + * moved and r24-r25 will be restore later) + */ + + ld r23, x+ + ld r22, x+ + ld r21, x+ + ld r20, x+ + ld r19, x+ + ld r18, x+ + + /* Restore r2-r17 - Call-saved, "static" registers */ + + ld r17, x+ + ld r16, x+ + ld r15, x+ + ld r14, x+ + ld r13, x+ + ld r12, x+ + ld r11, x+ + ld r10, x+ + ld r9, x+ + ld r8, x+ + ld r7, x+ + ld r6, x+ + ld r5, x+ + ld r4, x+ + ld r3, x+ + ld r2, x+ + + /* Restore r1 - zero register (which may not be zero) */ + + ld r1, x+ + + /* Restore r0 - the scratch register */ + + ld r0, x+ + + /* The following control flow split is required to eliminate non-atomic + * interrupt_enable - return sequence. + * + * NOTE: since actual returning is handled by this macro it has been removed + * from up_fullcontextrestore function (up_switchcontext.S) + */ + + /* If interrupts shall be enabled go to 'restore remaining and reti' code + * otherwise just do 'restore remaining and ret' + */ + + ld r24, x+ + bst r24, SREG_I + brts go_reti + + /* Restore the status register, interrupts are disabled */ + + out _SFR_IO_ADDR(SREG), r24 + + /* Restore r24-r25 - The temporary and IRQ number registers */ + + ld r25, x+ + ld r24, x+ + + /* Finally, recover X [r26-r27] from the new stack. The PC remains on the new + * stack so that the user of this macro can return with ret (not reti, ret will + * preserve the restored interrupt state). + */ + + pop r27 /* R27 then R26 */ + pop r26 + ret + +go_reti: + /* restore the Status Register with interrupts disabled + * and exit with reti (that will set the Interrupt Enable) + */ + + andi r24, ~(1 << SREG_I) + out _SFR_IO_ADDR(SREG), r24 + + ld r25, x+ + ld r24, x+ + + pop r27 + pop r26 + + reti + + .endm + +/******************************************************************************************** + * Name: USE_INTSTACK + * + * Description: + * Switch to the interrupt stack (if enabled in the configuration) and if the nesting level + * is equal to 0. Increment the nesting level in any event. + * + * On Entry: + * sp - Current value of the user stack pointer + * tmp1, tmp2, and tmp3 are registers that can be used temporarily. + * All interrupts should still be disabled. + * + * At completion: + * If the nesting level is 0, then (1) the user stack pointer is saved at the base of the + * interrupt stack and sp points to the interrupt stack. + * The values of tmp1, tmp2, tmp3, and sp have been altered + * + ********************************************************************************************/ + + .macro USE_INTSTACK, tmp1, tmp2, tmp3 +#if CONFIG_ARCH_INTERRUPTSTACK > 0 +# warning "Not implemented" +#endif + .endm + +/******************************************************************************************** + * Name: RESTORE_STACK + * + * Description: + * Restore the user stack. Not really.. actually only decrements the nesting level. We + * always get the new stack pointer for the register save array. + * + * On Entry: + * tmp1 and tmp2 are registers that can be used temporarily. + * All interrupts must be disabled. + * + * At completion: + * Current nesting level is decremented + * The values of tmp1 and tmp2 have been altered + * + ********************************************************************************************/ + + .macro RESTORE_STACK, tmp1, tmp2 +#if CONFIG_ARCH_INTERRUPTSTACK > 0 +# warning "Not implemented" +#endif + .endm + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_AVR_EXCPTMACROS_H */ diff --git a/arch/avr/src/avr/up_blocktask.c b/arch/avr/src/avr/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..b03b967badadebafc3e5fb5ef845bb3d238e5730 --- /dev/null +++ b/arch/avr/src/avr/up_blocktask.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/avr/src/avr/up_blocktask.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr/up_checkstack.c b/arch/avr/src/avr/up_checkstack.c new file mode 100644 index 0000000000000000000000000000000000000000..725a234d1a3f482626d927192f4fbf2aa533911d --- /dev/null +++ b/arch/avr/src/avr/up_checkstack.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * arch/avr/src/avr/up_checkstack.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" +#include "sched/sched.h" + +#ifdef CONFIG_STACK_COLORATION + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static size_t do_stackcheck(uintptr_t alloc, size_t size); + +/**************************************************************************** + * Name: do_stackcheck + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * alloc - Allocation base address of the stack + * size - The size of the stack in bytes + * + * Returned value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +static size_t do_stackcheck(uintptr_t alloc, size_t size) +{ + FAR uint8_t *ptr; + size_t mark; +#if 0 + int i; + int j; +#endif + + /* The AVR uses a push-down stack: the stack grows toward lower addresses + * in memory. We need to start at the lowest address in the stack memory + * allocation and search to higher addresses. The first byte we encounter + * that does not have the magic value is the high water mark. + */ + + for (ptr = (FAR uint8_t *)alloc, mark = size; + *ptr == STACK_COLOR && mark > 0; + ptr++, mark--); + + /* If the stack is completely used, then this might mean that the stack + * overflowed from above (meaning that the stack is too small), or may + * have been overwritten from below meaning that some other stack or data + * structure overflowed. + * + * If you see returned values saying that the entire stack is being used + * then enable the following logic to see it there are unused areas in the + * middle of the stack. + */ + +#if 0 + if (mark + 16 > size) + { + ptr = (FAR uint8_t *)alloc; + for (i = 0; i < size; i += 64) + { + for (j = 0; j < 64; j++) + { + int ch; + if (*ptr++ == STACK_COLOR) + { + ch = '.'; + } + else + { + ch = 'X'; + } + + up_putc(ch); + } + + up_putc('\n'); + } + } +#endif + + /* Return our guess about how much stack space was used */ + + return mark; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_check_stack and friends + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * None + * + * Returned value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +size_t up_check_tcbstack(FAR struct tcb_s *tcb) +{ + return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size); +} + +ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) +{ + return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); +} + +size_t up_check_stack(void) +{ + return up_check_tcbstack(this_task()); +} + +ssize_t up_check_stack_remain(void) +{ + return up_check_tcbstack_remain(this_task()); +} + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +size_t up_check_intstack(void) +{ + uintptr_t start = (uintptr_t)g_intstackbase - (CONFIG_ARCH_INTERRUPTSTACK & ~3); + return do_stackcheck(start, (CONFIG_ARCH_INTERRUPTSTACK & ~3)); +} + +size_t up_check_intstack_remain(void) +{ + return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack(); +} +#endif + +#endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/avr/src/avr/up_copystate.c b/arch/avr/src/avr/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..4c9c13bf8338586cf3044bddf6407344f185fe64 --- /dev/null +++ b/arch/avr/src/avr/up_copystate.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/avr/src/avr/up_copystate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copystate + ****************************************************************************/ + +/* Really just a memcpy */ + +void up_copystate(uint8_t *dest, uint8_t *src) +{ + int i; + + /* The state is copied from the stack to the TCB, but only a reference is + * passed to get the state from the TCB. So the following check avoids + * copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..c2dda4d271d97de33e06569c49afc78907867f2c --- /dev/null +++ b/arch/avr/src/avr/up_createstack.c @@ -0,0 +1,170 @@ +/**************************************************************************** + * arch/avr/src/avr/up_createstack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); +#endif + + /* The AVR uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on the + * stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size - 1; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->adj_stack_size = stack_size; + +#if defined(ARCH_HAVE_LEDS) + board_autoled_on(LED_STACKCREATED); +#endif + return OK; + } + + return ERROR; +} diff --git a/arch/avr/src/avr/up_doirq.c b/arch/avr/src/avr/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..1d8ce9c3d9d747877951b789b6e07121568b15c2 --- /dev/null +++ b/arch/avr/src/avr/up_doirq.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/avr/src/avr/up_doirq.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint8_t *up_doirq(uint8_t irq, uint8_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + uint8_t *savestate; + + /* Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to (1) change the way that + * g_current_regs is handled and (2) the design associated with + * CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + */ + + savestate = (uint8_t *)g_current_regs; /* Cast removes volatile attribute */ + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch((int)irq, (uint32_t *)regs); + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint8_t *)g_current_regs; /* Cast removes volatile attribute */ + + /* Restore the previous value of g_current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + g_current_regs = savestate; +#endif + board_autoled_off(LED_INIRQ); + return regs; +} + diff --git a/arch/avr/src/avr/up_dumpstate.c b/arch/avr/src/avr/up_dumpstate.c new file mode 100644 index 0000000000000000000000000000000000000000..a82b682d35366ea4c392d02cb05842f0404b2d95 --- /dev/null +++ b/arch/avr/src/avr/up_dumpstate.c @@ -0,0 +1,272 @@ +/**************************************************************************** + * arch/avr/src/avr/up_dumpstate.c + * + * Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* There may be a built-in to do this, but I don't know if it is enabled */ + +static inline uint16_t up_getsp(void) +{ + uint8_t spl; + uint8_t sph; + + __asm__ __volatile__ + ( + "in %0, __SP_L__\n\t" + "in %1, __SP_H__\n" + : "=r" (spl), "=r" (sph) + : + ); + return (uint16_t)sph << 8 | spl; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(uint16_t sp, uint16_t stack_base) +{ + uint16_t stack ; + + for (stack = sp & ~3; stack < stack_base; stack += 12) + { + uint8_t *ptr = (uint8_t *)stack; + lldbg("%04x: %02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x\n", + stack, + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], + ptr[8], ptr[9], ptr[10], ptr[11]); + } +} + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + lldbg("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 0, + g_current_regs[REG_R0], g_current_regs[REG_R1], + g_current_regs[REG_R2], g_current_regs[REG_R3], + g_current_regs[REG_R4], g_current_regs[REG_R5], + g_current_regs[REG_R6], g_current_regs[REG_R7]); + + lldbg("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 8, + g_current_regs[REG_R8], g_current_regs[REG_R9], + g_current_regs[REG_R10], g_current_regs[REG_R11], + g_current_regs[REG_R12], g_current_regs[REG_R13], + g_current_regs[REG_R14], g_current_regs[REG_R15]); + + lldbg("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 16, + g_current_regs[REG_R16], g_current_regs[REG_R17], + g_current_regs[REG_R18], g_current_regs[REG_R19], + g_current_regs[REG_R20], g_current_regs[REG_R21], + g_current_regs[REG_R22], g_current_regs[REG_R23]); + + lldbg("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 24, + g_current_regs[REG_R24], g_current_regs[REG_R25], + g_current_regs[REG_R26], g_current_regs[REG_R27], + g_current_regs[REG_R28], g_current_regs[REG_R29], + g_current_regs[REG_R30], g_current_regs[REG_R31]); + +#if !defined(REG_PC2) + lldbg("PC: %02x%02x SP: %02x%02x SREG: %02x\n", + g_current_regs[REG_PC0], g_current_regs[REG_PC1], + g_current_regs[REG_SPH], g_current_regs[REG_SPL], + g_current_regs[REG_SREG]); +#else + lldbg("PC: %02x%02x%02x SP: %02x%02x SREG: %02x\n", + g_current_regs[REG_PC0], g_current_regs[REG_PC1], + g_current_regs[REG_PC2], g_current_regs[REG_SPH], + g_current_regs[REG_SPL], g_current_regs[REG_SREG]); +#endif + } +} + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint16_t sp = up_getsp(); + uint16_t ustackbase; + uint16_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + uint16_t istackbase; + uint16_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 1; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustacksize = (uint16_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + istackbase = (uint16_t)&g_intstackbase - 1; + istacksize = CONFIG_ARCH_INTERRUPTSTACK; + + /* Show interrupt stack info */ + + lldbg("sp: %04x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %04x\n", istackbase); + lldbg(" size: %04x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + } + + /* Extract the user stack pointer if we are in an interrupt handler. + * If we are not in an interrupt handler. Then sp is the user stack + * pointer (and the above range check should have failed). + */ + + if (g_current_regs) + { + sp = g_current_regs[REG_R13]; + lldbg("sp: %04x\n", sp); + } + + lldbg("User stack:\n"); + lldbg(" base: %04x\n", ustackbase); + lldbg(" size: %04x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp <= ustackbase && sp > ustackbase - ustacksize) + { + up_stackdump(sp, ustackbase); + } +#else + lldbg("sp: %04x\n", sp); + lldbg("stack base: %04x\n", ustackbase); + lldbg("stack size: %04x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg("stack used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { + lldbg("ERROR: Stack pointer is not within allocated stack\n"); + } + else + { + up_stackdump(sp, ustackbase); + } +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/avr/src/avr/up_initialstate.c b/arch/avr/src/avr/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..506b28c6200bd38c5d1f24de80c9c335aa461dd5 --- /dev/null +++ b/arch/avr/src/avr/up_initialstate.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/avr/src/avr/up_initialstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of the + * new TCB. + * + * This function must setup the intial architecture registers and/or stack + * so that execution will begin at tcb->start on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure. Zeroing + * all registers is a good debug helper, but should not be necessary. + */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Set the initial stack pointer to the "base" of the allocated stack */ + + xcp->regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8); + xcp->regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff); + + /* Save the task entry point */ + +#if !defined(REG_PC2) + xcp->regs[REG_PC0] = (uint8_t)((uint16_t)tcb->start >> 8); + xcp->regs[REG_PC1] = (uint8_t)((uint16_t)tcb->start & 0xff); +#else + xcp->regs[REG_PC0] = (uint8_t)((uint32_t)tcb->start >> 16); + xcp->regs[REG_PC1] = (uint8_t)((uint32_t)tcb->start >> 8); + xcp->regs[REG_PC2] = (uint8_t)((uint32_t)tcb->start & 0xff); +#endif + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_SREG] = getsreg() & ~(1 << SREG_I); +#else + xcp->regs[REG_SREG] = getsreg() | (1 << SREG_I); +#endif +} diff --git a/arch/avr/src/avr/up_irq.c b/arch/avr/src/avr/up_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..34f956280494a2c99f094eb2fc647277475214e5 --- /dev/null +++ b/arch/avr/src/avr/up_irq.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/avr/src/avr/up_irq.c + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint8_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Initialize GPIO interrupt facilities */ + +#ifdef CONFIG_AVR32_GPIOIRQ +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (gpio_irqinitialize != NULL) +#endif + { + gpio_irqinitialize(); + } +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(getsreg() | (1 << SREG_I)); +#endif +} diff --git a/arch/avr/src/avr/up_releasepending.c b/arch/avr/src/avr/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..80789fee51dfeb8e2e91d9d1dd9f9fe4de6197db --- /dev/null +++ b/arch/avr/src/avr/up_releasepending.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/avr/src/avr/up_releasepending.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr/up_reprioritizertr.c b/arch/avr/src/avr/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..28978a19dabe78cf792553af78e9b0d011e22e9f --- /dev/null +++ b/arch/avr/src/avr/up_reprioritizertr.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/avr/src/avr/up_reprioritizertr.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} + diff --git a/arch/avr/src/avr/up_romgetc.c b/arch/avr/src/avr/up_romgetc.c new file mode 100644 index 0000000000000000000000000000000000000000..d78db9ee5af69606146e051c2a572843df0c90c6 --- /dev/null +++ b/arch/avr/src/avr/up_romgetc.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/avr/src/avr/up_romgetc.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifdef CONFIG_ARCH_ROMGETC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_romgetc + * + * Description: + * In Harvard architectures, data accesses and instruction accesses occur + * on different busses, perhaps concurrently. All data accesses are + * performed on the data bus unless special machine instructions are + * used to read data from the instruction address space. Also, in the + * typical MCU, the available SRAM data memory is much smaller that the + * non-volatile FLASH instruction memory. So if the application requires + * many constant strings, the only practical solution may be to store + * those constant strings in FLASH memory where they can only be accessed + * using architecture-specific machine instructions. + * + * A similar case is where strings are retained in "external" memory such + * as EEPROM or serial FLASH. This case is similar only in that again + * special operations are required to obtain the string data; it cannot + * be accessed directly from a string pointer. + * + * If CONFIG_ARCH_ROMGETC is defined, then the architecture logic must + * export the function up_romgetc(). up_romgetc() will simply read one + * byte of data from the instruction space. + * + * If CONFIG_ARCH_ROMGETC, certain C stdio functions are effected: (1) + * All format strings in printf, fprintf, sprintf, etc. are assumed to + * lie in FLASH (string arguments for %s are still assumed to reside in + * SRAM). And (2), the string argument to puts and fputs is assumed to + * reside in FLASH. Clearly, these assumptions may have to modified for + * the particular needs of your environment. There is no "one-size-fits-all" + * solution for this problem. + * + * Additional AVR Assumptions: + * + * - This version of up_romgetc obtains string data from FLASH memory. + * - Since the passed pointer is 16-bits, the strings must lie in the first + * 64Kb of FLASH. + * + ****************************************************************************/ + +char up_romgetc(FAR const char *ptr) +{ + return pgm_read_byte_near(ptr); +} +#endif diff --git a/arch/avr/src/avr/up_schedulesigaction.c b/arch/avr/src/avr/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..5c6cbf52eee68272e7d17d6c5cfce079a25f5705 --- /dev/null +++ b/arch/avr/src/avr/up_schedulesigaction.c @@ -0,0 +1,215 @@ +/**************************************************************************** + * arch/avr/src/avr/up_schedulesigaction.c + * + * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * g_current_regs does not refer to the thread of this_task()! + */ + + else + { + /* Save registers that must be protected while the signal handler + * runs. These will be restored by the signal trampoline after + * the signal(s) have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc0 = g_current_regs[REG_PC0]; + tcb->xcp.saved_pc1 = g_current_regs[REG_PC1]; +#if defined(REG_PC2) + tcb->xcp.saved_pc2 = g_current_regs[REG_PC2]; +#endif + tcb->xcp.saved_sreg = g_current_regs[REG_SREG]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ +#if !defined(REG_PC2) + g_current_regs[REG_PC0] = (uint16_t)up_sigdeliver >> 8; + g_current_regs[REG_PC1] = (uint16_t)up_sigdeliver & 0xff; +#else + g_current_regs[REG_PC0] = (uint32_t)up_sigdeliver >> 16; + g_current_regs[REG_PC1] = (uint32_t)up_sigdeliver >> 8; + g_current_regs[REG_PC2] = (uint32_t)up_sigdeliver & 0xff; +#endif + g_current_regs[REG_SREG] &= ~(1 << SREG_I); + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save registers that must be protected while the signal handler + * runs. These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc0 = tcb->xcp.regs[REG_PC0]; + tcb->xcp.saved_pc1 = tcb->xcp.regs[REG_PC1]; +#if defined(REG_PC2) + tcb->xcp.saved_pc2 = tcb->xcp.regs[REG_PC2]; +#endif + tcb->xcp.saved_sreg = tcb->xcp.regs[REG_SREG]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + +#if !defined(REG_PC2) + tcb->xcp.regs[REG_PC0] = (uint16_t)up_sigdeliver >> 8; + tcb->xcp.regs[REG_PC1] = (uint16_t)up_sigdeliver & 0xff; +#else + tcb->xcp.regs[REG_PC0] = (uint32_t)up_sigdeliver >> 16; + tcb->xcp.regs[REG_PC1] = (uint32_t)up_sigdeliver >> 8; + tcb->xcp.regs[REG_PC2] = (uint32_t)up_sigdeliver & 0xff; + +#endif + tcb->xcp.regs[REG_SREG] &= ~(1 << SREG_I); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/avr/src/avr/up_sigdeliver.c b/arch/avr/src/avr/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..e786cba00c6c8edeb9a5429f3324398af182a26a --- /dev/null +++ b/arch/avr/src/avr/up_sigdeliver.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/avr/src/avr/up_sigdeliver.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint8_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_PC0] = rtcb->xcp.saved_pc0; + regs[REG_PC1] = rtcb->xcp.saved_pc1; +#if defined(REG_PC2) + regs[REG_PC2] = rtcb->xcp.saved_pc2; +#endif + regs[REG_SREG] = rtcb->xcp.saved_sreg; + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_SREG]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. This is an + * unusual case that must be handled by up_fullcontextresore. This case is + * unusal in two ways: + * + * 1. It is not a context switch between threads. Rather, up_fullcontextrestore + * must behave more it more like a longjmp within the same task, using + * he same stack. + * 2. In this case, up_fullcontextrestore is called with r12 pointing to + * a register save area on the stack to be destroyed. This is + * dangerous because there is the very real possibility that the new + * stack pointer might overlap with the register save area and hat stack + * usage in up_fullcontextrestore might corrupt the register save data + * before the state is restored. At present, there does not appear to + * be any stack overlap problems. If there were, then adding 3 words + * to the size of register save structure size will protect its contents. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/avr/src/avr/up_spi.c b/arch/avr/src/avr/up_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..94de828c1582948d5aa832cf9818890c7dfae54c --- /dev/null +++ b/arch/avr/src/avr/up_spi.c @@ -0,0 +1,522 @@ +/**************************************************************************** + * arch/arm/src/avr/up_spi.c + * + * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "avr.h" + +#ifdef CONFIG_AVR_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Enables debug output from this file (needs CONFIG_DEBUG too) */ + +#undef SPI_DEBUG /* Define to enable debug */ +#undef SPI_VERBOSE /* Define to enable verbose debug */ + +#ifdef SPI_DEBUG +# define spidbg lldbg +# ifdef SPI_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# undef SPI_VERBOSE +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct avr_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spi_lock, + .select = avr_spiselect, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = avr_spistatus, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = avr_spicmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, + .registercallback = 0, /* Not implemented */ +}; + +static struct avr_spidev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct avr_spidev_s *priv = (FAR struct avr_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct avr_spidev_s *priv = (FAR struct avr_spidev_s *)dev; + uint32_t actual; + + /* Has the request frequency changed? */ + + if (frequency != priv->frequency) + { + /* Read the SPI status and control registers, clearing all divider bits */ + + uint8_t spcr = SPCR & ~((1 << SPR0) | (1 << SPR1)); + uint8_t spsr = SPSR & ~(1 << SPI2X); + + /* Select the best divider bits */ + + if (frequency >= BOARD_CPU_CLOCK / 2) + { + spsr |= (1 << SPI2X); + actual = BOARD_CPU_CLOCK / 2; + } + else if (frequency >= BOARD_CPU_CLOCK / 4) + { + actual = BOARD_CPU_CLOCK / 4; + } + else if (frequency >= BOARD_CPU_CLOCK / 8) + { + spcr |= (1 << SPR0); + spsr |= (1 << SPI2X); + actual = BOARD_CPU_CLOCK / 8; + } + else if (frequency >= BOARD_CPU_CLOCK / 16) + { + spcr |= (1 << SPR0); + actual = BOARD_CPU_CLOCK / 16; + } + else if (frequency >= BOARD_CPU_CLOCK / 32) + { + spcr |= (1 << SPR1); + spsr |= (1 << SPI2X); + actual = BOARD_CPU_CLOCK / 32; + } + else if (frequency >= BOARD_CPU_CLOCK / 64) + { + spcr |= (1 << SPR1); + actual = BOARD_CPU_CLOCK / 64; + } + else /* if (frequency >= BOARD_CPU_CLOCK / 128) */ + { + spcr |= (1 << SPR0) | (1 << SPR1); + actual = BOARD_CPU_CLOCK / 128; + } + +#warning REVISIT: spcr/spsr are never used + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + } + else + { + actual = priv->actual; + } + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct avr_spidev_s *priv = (FAR struct avr_spidev_s *)dev; + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + uint8_t regval; + + /* Yes... Set SPI CR appropriately */ + + regval = SPCR; + regval &= ~((1 << CPOL) | (1 << CPHA)); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= (1 << CPHA); + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= (1 << CPOL); + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= ((1 << CPOL) | (1 << CPHA)); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + SPSR = regval; + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests (only nbits == 8 is supported) + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + DEBUGASSERT(dev && nbits == 8); +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + /* Write the data to transmitted to the SPI Data Register */ + + SPDR = (uint8_t)wd; + + /* Wait for transmission to complete */ + + while (!(SPSR & (1 << SPIF))); + + /* Then return the received value */ + + return (uint16_t)SPDR; +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords-- > 0) + { + (void)spi_send(dev, (uint16_t)*ptr++); + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits- + * per-wordselected for the SPI interface. If nbits <= 8, the + * data is packed into uint8_t's; if nbits >8, the data is packed + * into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spidbg("nwords: %d\n", nwords); + while (nwords-- > 0) + { + *ptr++ = spi_send(dev, (uint16_t)0xff); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: avr_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *avr_spibus_initialize(int port) +{ + FAR struct avr_spidev_s *priv = &g_spidev; + irqstate_t flags; + uint8_t regval; + + /* Make sure that clocks are provided to the SPI module */ + + flags = enter_critical_section(); + power_spi_enable(); + + /* Set MOSI and SCK as outputs, all others are inputs (default on reset): + * + * PB3: PDO/MISO/PCINT3 + * PB2: PDI/MOSI/PCINT2 + * PB1: SCK/PCINT1 + * PB0: SS/PCINT0 + */ + + DDRB |= (1 << 2) | (1 << 1); + + /* - Enable SPI + * - Set Master + * - Set clock rate oscillator/4 + * - Set CPOL for SPI clock mode 0 + */ + + SPCR = (1 << SPE) | (1 << MSTR); + + /* Set clock rate to f(osc)/8 */ + /* SPSR |= (1 << 0); */ + + /* Clear status flags by reading them */ + + regval = SPSR; + UNUSED(regval); + regval = SPDR; + UNUSED(regval); + + /* Set the initial SPI configuration */ + + priv->frequency = 0; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + + leave_critical_section(flags); + return &priv->spidev; +} +#endif /* CONFIG_AVR_SPI */ diff --git a/arch/avr/src/avr/up_stackframe.c b/arch/avr/src/avr/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..0f7d3a87463e1148abbd400b557edd8843fc142f --- /dev/null +++ b/arch/avr/src/avr/up_stackframe.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/avr/src/avr/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Set the initial stack pointer to the "base" of the allocated stack */ + + tcb->xcp.regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8); + tcb->xcp.regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff); + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint8_t)); +} + diff --git a/arch/avr/src/avr/up_switchcontext.S b/arch/avr/src/avr/up_switchcontext.S new file mode 100644 index 0000000000000000000000000000000000000000..913cbfb39a861f0c5cfcb8322fe371881d2b439c --- /dev/null +++ b/arch/avr/src/avr/up_switchcontext.S @@ -0,0 +1,138 @@ +/************************************************************************************ + * arch/avr/src/avr/up_switchcontext.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "excptmacros.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .file "up_switchcontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. The full + * C function prototype is: + * + * void up_switchcontext(uint8_t *saveregs, uint8_t *restoreregs); + * + * On Entry: + * r24-r25: savregs + * r22-r23: restoreregs + * + * Return: + * up_switchcontext forces a context switch to the task "canned" in restoreregs. + * It does not 'return' in the normal sense, rather, it will context switch back + * to the function point. When it does 'return,' it is because the blocked + * task hat was "pickeled" in the saveregs "can" is again ready to run and has + * execution priority. + * + * Assumptions: + * global interrupts disabled by the caller. + * + ************************************************************************************/ + + .text + .globl up_switchcontext + .func up_switchcontext +up_switchcontext: + /* Use X [r26:r27] to reference the save structure. (X is Call-used) */ + + movw r26, r24 + + /* Save the context to saveregs */ + + USER_SAVE + + /* Then fall through to do the full context restore with r24-r5 = restoreregs */ + + movw r24, r22 + .endfunc + +/**************************************************************************** + * Name: up_fullcontextrestore + * + * Descripion: + * Restore the full-running context of a thread. + * + * Input Parameters: + * r24-r25 = A pointer to the register save area of the thread to be restored. + * + * C Prototype: + * void up_fullcontextrestore(uint8_t *regs); + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + + .text + .global up_fullcontextrestore + .func up_fullcontextrestore +up_fullcontextrestore: + /* Use X [r26:r27] to reference the restore structure. */ + + movw r26, r24 + + /* Restore the context from the TCB saved registers */ + + TCB_RESTORE + + /* Returning from the function is handled in TCB_RESTORE */ + + .endfunc + .end diff --git a/arch/avr/src/avr/up_unblocktask.c b/arch/avr/src/avr/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..d70b65405cd2af723ba9e307ab329776c5f5b120 --- /dev/null +++ b/arch/avr/src/avr/up_unblocktask.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/avr/src/avr/up_unblocktask.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + struct tcb_s *nexttcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..0546d8c770ad85b02b724717dfb79d93919349f0 --- /dev/null +++ b/arch/avr/src/avr/up_usestack.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/avr/src/avr/up_usestack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* If stack debug is enabled, then fill the stack with a recognizable value + * that we can use later to test for high water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); +#endif + + /* The AVR uses a push-down stack: the stack grows toward loweraddresses in + * memory. The stack pointer register, points to the lowest, valid work + * address (the "top" of the stack). Items on the stack are referenced as + * positive word offsets from sp. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size - 1; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->adj_stack_size = stack_size; + + return OK; +} + diff --git a/arch/avr/src/avr32/Kconfig b/arch/avr/src/avr32/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..14d5c0f33b48365e846075fe2e1b1c7e31fae657 --- /dev/null +++ b/arch/avr/src/avr32/Kconfig @@ -0,0 +1,23 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_FAMILY_AVR32 +comment "AVR32 Configuration Options" + +choice + prompt "Toolchain" + default AVR32_AVRTOOLSW if HOST_WINDOWS + default AVR32_AVRTOOLSL if HOST_LINUX + +config AVR32_AVRTOOLSW + bool "AVR tools for Windows" + depends on HOST_WINDOWS + +config AVR32_AVRTOOLSL + bool "AVR tools for Linux" + depends on HOST_LINUX + +endchoice # Toolchain +endif diff --git a/arch/avr/src/avr32/Toolchain.defs b/arch/avr/src/avr32/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..b0a40e34b309c335032d2f7713f2f4bd25245ac2 --- /dev/null +++ b/arch/avr/src/avr32/Toolchain.defs @@ -0,0 +1,69 @@ +############################################################################ +# arch/avr/src/avr32/Toolchain.defs +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Since all of the supported toolchains are variants of the Atmel-patched +# GCC, the only interesting question to answer here is whether or not +# the build is hosted on Windows, and how to override the configuration. +# +# NOTE: There is a logic error in the following: CONFIG_HOST_WINDOWS means +# that we are operating on a Windows platform. But in the case where we +# have an AVR32 toolchain built under Cygwin, the correct setting would be +# GNU, not AVRTOOLSW. +# + +CROSSDEV = avr32- +ARCHCPUFLAGS = -mpart=uc3b0256 + +ifeq ($(filter y, \ + $(CONFIG_AVR32_AVRTOOLSW) \ + $(CONFIG_HOST_WINDOWS) \ + ),y) + # AVR Tools under Windows + CONFIG_AVR32_TOOLCHAIN ?= AVRTOOLSW +else + CONFIG_AVR32_TOOLCHAIN ?= GNU +endif + +ifeq ($(CONFIG_AVR32_TOOLCHAIN),AVRTOOLSW) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +else + # AVR Tools or avr32-toolchain from https://github.com/jsnyder/avr32-toolchain +endif + diff --git a/arch/avr/src/avr32/avr32.h b/arch/avr/src/avr32/avr32.h new file mode 100644 index 0000000000000000000000000000000000000000..e24abd7fc9bf80590899b1f136b9517cc93dc8c0 --- /dev/null +++ b/arch/avr/src/avr32/avr32.h @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/avr/src/avr32/avr32.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AVR32_AVR32_H +#define __ARCH_AVR_SRC_AVR32_AVR32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Macros to handle saving and restore interrupt state. The state is copied + * from the stack to the TCB, but only a referenced is passed to get the + * state from the TCB. + */ + +#define up_savestate(regs) up_copystate(regs, (uint32_t*)g_current_regs) +#define up_restorestate(regs) (g_current_regs = regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +extern volatile uint32_t *g_current_regs; + +/* This is the beginning of heap as provided from up_head.S. This is the first + * address in DRAM after the loaded program+bss+idle stack. The end of the + * heap is CONFIG_RAM_END + */ + +extern uint32_t g_idle_topstack; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: up_copystate + * + * Description: + * Copy the contents of a register state save structure from one location to + * another. + * + ************************************************************************************/ + +void up_copystate(uint32_t *dest, uint32_t *src); + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Restore the full context of a saved thread/task. + * + ************************************************************************************/ + +void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Switch from one thread/task context to another. + * + ************************************************************************************/ + +void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + +/************************************************************************************ + * Name: up_doirq + * + * Description: + * Dispatch an interrupt. + * + ************************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs); + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_AVR32_AVR32_H */ + diff --git a/arch/avr/src/avr32/up_blocktask.c b/arch/avr/src/avr32/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..8449d82cbe0e49331f09abae60b32b7530dcffe0 --- /dev/null +++ b/arch/avr/src/avr32/up_blocktask.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_blocktask.c + * + * Copyright (C) 2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any new address environment needed by + * the new thread will be instantiated before the return from + * interrupt. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Get the context of the task at the head of the ready to + * run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr32/up_copystate.c b/arch/avr/src/avr32/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..fa69f8cdd50ffaa486697f5d16c00dffa238323b --- /dev/null +++ b/arch/avr/src/avr32/up_copystate.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_copystate.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* The state is copied from the stack to the TCB, but only a reference is + * passed to get the state from the TCB. So the following check avoids + * copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..db76abc38d9d21f88a75ccb8d56c37c84d9c7d20 --- /dev/null +++ b/arch/avr/src/avr32/up_createstack.c @@ -0,0 +1,194 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_createstack.c + * + * Copyright (C) 2010-2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); +#endif + + /* The AVR32 uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The AVR32 stack must be aligned at word (4 byte) boundaries. If + * necessary top_of_stack must be rounded down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/avr/src/avr32/up_doirq.c b/arch/avr/src/avr32/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..db84ded148c3a4053bc024001cd6d8bec5e7ebaa --- /dev/null +++ b/arch/avr/src/avr32/up_doirq.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_doirq.c + * + * Copyright (C) 2010-2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. + * If an interrupt level context switch has occurred, then restore + * the floating point state and the establish the correct address + * environment before returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in + * an interrupt handler. + */ + + g_current_regs = NULL; +#endif + board_autoled_off(LED_INIRQ); + return regs; +} + diff --git a/arch/avr/src/avr32/up_dumpstate.c b/arch/avr/src/avr32/up_dumpstate.c new file mode 100644 index 0000000000000000000000000000000000000000..31daafdedb78ca8e40223dd46ced62291c453ba8 --- /dev/null +++ b/arch/avr/src/avr32/up_dumpstate.c @@ -0,0 +1,237 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_dumpstate.c + * + * Copyright (C) 2010-2011, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + uint32_t retval; + __asm__ __volatile__ ( + "mov\t%0,sp\n\t" + : "=r" (retval) + : + ); + return retval; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 0, + g_current_regs[REG_R0], g_current_regs[REG_R1], + g_current_regs[REG_R2], g_current_regs[REG_R3], + g_current_regs[REG_R4], g_current_regs[REG_R5], + g_current_regs[REG_R6], g_current_regs[REG_R7]); + + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 8, + g_current_regs[REG_R8], g_current_regs[REG_R9], + g_current_regs[REG_R10], g_current_regs[REG_R11], + g_current_regs[REG_R12], g_current_regs[REG_R13], + g_current_regs[REG_R14], g_current_regs[REG_R15]); + + lldbg("SR: %08x\n", g_current_regs[REG_SR]); + } +} + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_intstack()); +#endif + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + } + + /* Extract the user stack pointer if we are in an interrupt handler. + * If we are not in an interrupt handler. Then sp is the user stack + * pointer (and the above range check should have failed). + */ + + if (g_current_regs) + { + sp = g_current_regs[REG_R13]; + lldbg("sp: %08x\n", sp); + } + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg(" used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp <= ustackbase && sp > ustackbase - ustacksize) + { + up_stackdump(sp, ustackbase); + } +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#ifdef CONFIG_STACK_COLORATION + lldbg("stack used: %08x\n", up_check_tcbstack(rtcb)); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { + lldbg("ERROR: Stack pointer is not within allocated stack\n"); + } + else + { + up_stackdump(sp, ustackbase); + } +#endif + + /* Then dump the registers (if available) */ + + up_registerdump(); +} +#endif diff --git a/arch/avr/src/avr32/up_exceptions.S b/arch/avr/src/avr32/up_exceptions.S new file mode 100644 index 0000000000000000000000000000000000000000..361be60df3112217dc9331b20905741283bd0f74 --- /dev/null +++ b/arch/avr/src/avr32/up_exceptions.S @@ -0,0 +1,373 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_exceptions.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .global avr32_int0irqno /* Returns IRQ number of INT0 event */ + .global avr32_int1irqno /* Returns IRQ number of INT1 event */ + .global avr32_int2irqno /* Returns IRQ number of INT2 event */ + .global avr32_int3irqno /* Returns IRQ number of INT3 event */ + .global up_doirq /* Dispatch an IRQ */ + .global up_fullcontextrestore /* Restore new task contex */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Exception entry logic. On entry, thee context save area looks like: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ +/* Upon joining common logic, the context save are will look like: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ +/* ^ ^+3*4 */ +/* and r10 will hold the exception's IRQ number */ + + .macro HANDLER, label, irqno +\label: + st.w --sp, r10 + mov r10, \irqno + rjmp avr32_xcptcommon /* FIXME!!! Need IRQ in a register */ + .endm + +/**************************************************************************** + * Exception Vector Table + ****************************************************************************/ + +/* The Exception Vector Base Address (EVBA) register will contain "a */ +/* pointer to the exception routines. All exception routines start at this */ +/* address, or at a defined offset relative to the address. Special */ +/* alignment requirements may apply for EVBA, depending on the */ +/* implementation of the interrupt controller." */ + +/* REVISIT: This alignment requirement may be different on other AVR32s */ + + .text + .balign 0x200 + + .global vectortab + .type vectortab, @function +vectortab: + lda.w pc, avr32_unrec /* EVBA+0x00 Unrecoverable exception */ + lda.w pc, avr32_tlbmult /* EVBA+0x04 TLB multiple hit */ + lda.w pc, avr32_busdata /* EVBA+0x08 Bus error data fetch */ + lda.w pc, avr32_businst /* EVBA+0x0c Bus error instr fetch */ + lda.w pc, avr32_nmi /* EVBA+0x10 NMI */ + lda.w pc, avr32_instaddr /* EVBA+0x14 Instruction Address */ + lda.w pc, avr32_itlbrot /* EVBA+0x18 ITLB Protection */ + lda.w pc, avr32_bp /* EVBA+0x1c Breakpoint */ + lda.w pc, avr32_invinst /* EVBA+0x20 Illegal Opcode */ + lda.w pc, avr32_unimpinst /* EVBA+0x24 Unimplemented instruction */ + lda.w pc, avr32_priv /* EVBA+0x28 Privilege violation */ + lda.w pc, avr32_fp /* EVBA+0x2c Floating-point */ + lda.w pc, avr32_cop /* EVBA+0x30 Coprocessor absent */ + lda.w pc, avr32_rddata /* EVBA+0x34 Data Address (Read) */ + lda.w pc, avr32_wrdata /* EVBA+0x38 Data Address (Write) */ + lda.w pc, avr32_tddtlbprot /* EVBA+0x3c DTLB Protection (Read) */ + lda.w pc, avr32_wrdtlbprot /* EVBA+0x40 DTLB Protection (Write) */ + lda.w pc, avr32_dltbmod /* EVBA+0x44 DTLB Modified */ + .rept 2 + lda.w pc, avr32_badvector /* EVBA+0x48-0x4c No such vector */ + .endr + lda.w pc, avr32_itlbmiss /* EVBA+0x50 ITLB Miss */ + .rept 3 + lda.w pc, avr32_badvector /* EVBA+0x54-0x5c No such vector */ + .endr + lda.w pc, avr32_rddtlb /* EVBA+0x60 DTLB Miss (Read) */ + .rept 3 + lda.w pc, avr32_badvector /* EVBA+0x64-0x6c No such vector */ + .endr + lda.w pc, avr32_wrdtlb /* EVBA+0x70 DTLB Miss (Write) */ + .rept (3+4*8) + lda.w pc, avr32_badvector /* EVBA+0x74-0xfc No such vector */ + .endr + lda.w pc, avr32_super /* EVBA+0x100 Supervisor call */ + +/**************************************************************************** + * Interrupts + ****************************************************************************/ + +/* The interrupt controller must provide an address that is relative to the */ +/* the EVBA so it is natural to define these interrupt vectors just after */ +/* the exception table. On entry to each interrupt handler, R8-R12, LR, PC */ +/* and SR have already been pushed onto the system stack by the MCU. */ +/* */ +/* An interrupt may disappear while it is being fetched by the CPU and, */ +/* hence spurious interrupt may result. */ + + .balign 4 + .global avr32_int0 +avr32_int0: + mov r12, 0 /* r12=interrupt level 0 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int1 +avr32_int1: + mov r12, 1 /* r12=interrupt level 1 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int2 +avr32_int2: + mov r12, 2 /* r12=interrupt level 2 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int3 +avr32_int3: + mov r12, 3 /* r12=interrupt level 3 */ + +/* Common interrupt handling logic. R12 holds the interrupt level index */ + +avr32_intcommon: + mcall .Lavr32_intirqno /* Get the IRQ number of the int0 event */ + cp.w r12, 0 /* Negative returned if spurious interrupt */ + brge avr32_common /* Jump to the common xcptn handling logic */ + rete /* Ignore spurious interrupt */ + +.Lavr32_intirqno: + .word avr32_intirqno + +/**************************************************************************** + * Exception Vector Handlers + ****************************************************************************/ + +/* Exception Handlers: */ +/* On entry to each, the context save area looks like this: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ + + HANDLER avr32_unrec, AVR32_IRQ_UNREC /* Unrecoverable xcptn */ + HANDLER avr32_tlbmult, AVR32_IRQ_TLBMULT /* TLB multiple hit */ + HANDLER avr32_busdata, AVR32_IRQ_BUSDATA /* Bus error data fetch */ + HANDLER avr32_businst, AVR32_IRQ_BUSINST /* Bus err instr fetch */ + HANDLER avr32_nmi, AVR32_IRQ_NMI /* NMI */ + HANDLER avr32_instaddr, AVR32_IRQ_INSTADDR /* Instruction Address */ + HANDLER avr32_itlbrot, AVR32_IRQ_ITLBPROT /* ITLB Protection */ + HANDLER avr32_bp, AVR32_IRQ_BP /* Breakpoint */ + HANDLER avr32_invinst, AVR32_IRQ_INVINST /* Illegal Opcode */ + HANDLER avr32_unimpinst, AVR32_IRQ_UNIMPINST /* Unimplemented intsr */ + HANDLER avr32_priv, AVR32_IRQ_PRIV /* Privilege violation */ + HANDLER avr32_fp, AVR32_IRQ_FP /* Floating-point */ + HANDLER avr32_cop, AVR32_IRQ_COP /* Coprocessor absent */ + HANDLER avr32_rddata, AVR32_IRQ_RDDATA /* Data Address (RD) */ + HANDLER avr32_wrdata, AVR32_IRQ_WRDATA /* Data Address (WR) */ + HANDLER avr32_tddtlbprot, AVR32_IRQ_RDDTLBPROT /* DTLB Protection (RD) */ + HANDLER avr32_wrdtlbprot, AVR32_IRQ_WRDTLBPROT /* DTLB Protection (WR) */ + HANDLER avr32_dltbmod, AVR32_IRQ_DLTBMOD /* DTLB Modified */ + HANDLER avr32_itlbmiss, AVR32_IRQ_ITLBMISS /* ITLB Miss */ + HANDLER avr32_rddtlb, AVR32_IRQ_RDDTLB /* DTLB Miss (RD) */ + HANDLER avr32_wrdtlb, AVR32_IRQ_WRDTLB /* DTLB Miss (WR) */ + HANDLER avr32_super, AVR32_IRQ_SUPER /* Supervisor call */ + HANDLER avr32_badvector, AVR32_IRQ_BADVECTOR /* No such vector */ + +/* Common exception handling logic. Unlike the interrupt handlers, the */ +/* exception handlers do not save R8-R12, and LR on the stack. Only the PC */ +/* and SR have been pushed onto the system stack by the MCU. The following */ +/* logic creates a common stack frame for exception handlers prior to */ +/* joining to the common interrupt/exception logic below. */ +/* */ +/* The context save area looks like this on entry to the HANDLER above. */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ +/* Upon joining common logic here, the context save are will loke: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ +/* ^ ^+3*4 */ +/* and r10 will hold the exception's IRQ number */ +/* */ +/* either (1) non-time-critical, or (2) fatal. Obvious, that would not be */ +/* the case if TLB missing handling is required. Such time-critical vector */ +/* handling should be handled differently. */ + +avr32_xcptcommon: +/* Save r10-r12, lr on the stack: */ +/* xx xx xx xx xx xx xx xx xx xx xx LR 12 11 10 SR PC */ +/* ^ ^+4*4 ^+6*4 */ + + stm --sp, r11-r12, lr + +/* Move SR and PC into the expected position: */ +/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ +/* ^ ^+8*4 */ + + ld.w r12, sp[4*4] + ld.w r11, sp[5*4] + stm --sp, r11-r12 + +/* Save r8 and r8: */ +/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ +/* ^ ^+6*4 ^+8*4 */ + + st.w sp[6*4], r9 + st.w sp[7*4], r8 + +/* Move the IRQ number in r12 and fall through to the common event handling */ +/* logic. */ + + mov r12, r10 + +/**************************************************************************** + * Common Event Handling Logic + ****************************************************************************/ + +/* After this point, logic to manage interrupts and exceptions is */ +/* equivalent. Here we have: */ +/* */ +/* R8-R12, LR, SR, and the PC on the stack. */ +/* R12 holds the IRQ number to be dispatched. */ +/* */ +/* The context save area looks like this: */ +/* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ +/* ^ ^+8*4 */ +/* This function will finish construction of the register save structure */ +/* and call the IRQ dispatching logic. */ + +avr32_common: + /* Disable interrupts in the current SR. This is necessary because the */ + /* AVR32 permits nested interrupts (if they are of higher priority). */ + /* We can support nested interrupts without some effort because: */ + /* - The global variable g_current_regs permits only one interrupt, */ + /* - If CONFIG_ARCH_INTERRUPTSTACK is defined, then there is a single */ + /* interrupt stack, and */ + /* - Probably other things. */ + + ssrf AVR32_SR_GM_SHIFT + + /* Save the SP (as it was before the interrupt) in the conext save */ + /* structure. */ + /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + mov r8, sp + sub r8, -8*4 + st.w --sp, r8 + + /* Saving R0-R7 is all that is left to complete the context save. */ + /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + stm --sp, r0-r7 + + /* Now call up_doirq passing the IRQ number in r12 and the base address */ + /* of the register context save area in r11. */ + + mov r11, sp + + /* Switch to the interrupt stack if so configured. Move the current */ + /* stack pointer into a preserved register (r7) and set the interrupt */ + /* stack pointer. */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + mov r7, sp + lddpc sp, .Linstackbaseptr +#endif + + /* Call up_doirq with r12=IRQ number and r11=register save area */ + + mcall .Ldoirqptr + + /* Restore the user stack pointer. */ + /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + mov sp, r7 +#endif + + /* On return, r12 will hold the new address of the register context */ + /* save area. On an interrupt contex switch, this will (1) not be the */ + /* same as the value of r12 passed to up_doirq(), and (2) may not */ + /* reside on a stack. */ + + cp.w sp, r12 + brne 1f + + /* No context switch... do the simple return. First, restore r0-r7. */ + /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + ldm sp++, r0-r7 + + /* Skip over the saved stack pointer and return from the interrupt. */ + /* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + sub sp, -4 + rete + + /* Context switch... jump to up_fullcontestrestor with r12=address of */ + /* the task context to restore. */ + +1: + lddpc pc, .Lfullcontextrestoreptr + +.Ldoirqptr: + .word up_doirq +.Lfullcontextrestoreptr: + .word up_fullcontextrestore + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Linstackbaseptr: + .word .Lintstackbase +#endif + .size vectortab, .-vectortab + +/************************************************************************************ + * Name: up_interruptstack + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3) +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/avr/src/avr32/up_fullcontextrestore.S b/arch/avr/src/avr32/up_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..8b0910998347d03e07e228a86879143577ddf3c5 --- /dev/null +++ b/arch/avr/src/avr32/up_fullcontextrestore.S @@ -0,0 +1,158 @@ +/**************************************************************************** + * arch/avr32/src/avr32/up_fullcontextrestore.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_fullcontextrestore.S" + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fullcontextrestore + * + * Descripion: + * Restore the full-running contex of a thread. + * + * NOTE: Thus function must handle one very strange case. That is when + * this function is called with up_sigdeliver(). That case is strange in + * two ways: + * + * 1. It is not a context switch between threads. Rather, up_fullcontextrestore + * must behave more it more like a longjmp within the same task, using the + * same stack. + * 2. In this case, this function is called with r12 pointing to a register + * save area on the stack to be destroyed. This is dangerous for two + * reasons: (a) there is a period of time where the stack contents still + * contain valid data, but are outside of range protected by the stack + * pointer (hence, interrupts must be disabled), and (b) there is the + * very real possibility that the new stack pointer might overlap with + * the register save area and stack usage in this function might corrupt + * the register save data before the state is restored. It turns that + * an extra 3 words in the register save structure size will protect its + * contents (because that is the number of temporaries pushed onto the + * stack). + * + * Input Parameters: + * r12 = A pointer to the register save area of the thread to be restored. + * + * C Prototype: + * void up_fullcontextrestore(uint32_t *regs); + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + + .text + .global up_fullcontextrestore + .type up_fullcontextrestore, @function +up_fullcontextrestore: + + /* Initially, r12 points to the r7 save area. Restore r0-r7. */ + /* regs: 07 06 05 04 03 02 01 00 xx xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + ldm r12++, r0-r7 + + /* Now, r12 points to the SP (r13) save area. Recover the value of */ + /* the stack pointer (r13). We will need to save some temporaries on */ + /* the final stack. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + ld.w sp, r12++ + + /* Now r12 points to the SR save area. Skip over the SR for now. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + sub r12, -1*4 + + /* Get the pc, lr, and r12 (in r10, r9, and r8) and move them to the */ + /* stack. We can now use r12 and lr as scratch registers. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 xx xx xx xx */ + /* ^r12 */ + /* stack: lr, r12, pc */ + /* ^sp */ + + ldm r12++, r8-r10 /* Get r10=pc, r9=lr, r8=r12 */ + +#if 0 /* See comments below */ + stm --sp, r8-r10 /* Save r12, lr, and pc from the stack */ +#else + st.w --sp, r10 /* Save R10=PC on the stack */ + st.w --sp, r8 /* Save R8=r12 on the stack */ + st.w --sp, r9 /* Save R9=lr on the stack */ +#endif + + /* Now r12 now points to the r11 save area. Restore r8-r11. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 11 10 09 08 */ + /* ^r12 */ + + ldm r12++, r8-r11 + + /* r12 now points +4 beyond the end of the register save area. Restore */ + /* SR. NOTE: This may enable interrupts! */ + /* regs: 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^r12-4*8 ^r12 */ + + ld.w lr, r12[-4*8] + mtsr AVR32_SR, lr + + /* Restore PC, LR and r12. Hmmm.. I need to study the behaviour of ldm */ + /* when r12,lr, and pc on in ldm reglist16. I'm not sure that I want */ + /* that behavior. */ + /* stack: lr, r12, pc */ + /* ^sp */ + +#if 0 + ldm sp++, r12, lr, pc /* Restore r12, lr, and pc from the stack */ +#else + ld.w lr, sp++ /* Recover lr from the stack */ + ld.w r12, sp++ /* Recover r12 from the stack */ + ld.w pc, sp++ /* Jump to the address on the stack */ +#endif + .end diff --git a/arch/avr/src/avr32/up_initialstate.c b/arch/avr/src/avr32/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..821637423ae757dcaf60ca481c0650fac0d001a7 --- /dev/null +++ b/arch/avr/src/avr32/up_initialstate.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_initialstate.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of the + * new TCB. + * + * This function must setup the intial architecture registers and/or stack + * so that execution will begin at tcb->start on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure. Zeroing + * all registers is a good debug helper, but should not be necessary. + */ + +#ifdef CONFIG_DEBUG + memset(xcp, 0, sizeof(struct xcptcontext)); +#else + /* No pending signal delivery */ + + xcp->sigdeliver = NULL; + + /* Clear the frame pointer and link register since this is the outermost + * frame. + */ + + xcp->regs[REG_R7] = 0; + xcp->regs[REG_LR] = 0; +#endif + + /* Set the initial stack pointer to the "base" of the allocated stack */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start; + + /* Set supervisor- or user-mode, depending on how NuttX is configured and + * what kind of thread is being started. Disable FIQs in any event + * + * If the kernel build is not selected, then all threads run in + * supervisor-mode. + */ + +#ifdef CONFIG_BUILD_KERNEL +# error "Missing logic for the CONFIG_BUILD_KERNEL build" +#endif + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_SR] = avr32_sr() | AVR32_SR_GM_MASK; +#else + xcp->regs[REG_SR] = avr32_sr() & ~AVR32_SR_GM_MASK; +#endif +} + diff --git a/arch/avr/src/avr32/up_nommuhead.S b/arch/avr/src/avr32/up_nommuhead.S new file mode 100644 index 0000000000000000000000000000000000000000..149b1f26fdc3e1f76d56adfde7c2144389dc133b --- /dev/null +++ b/arch/avr/src/avr32/up_nommuhead.S @@ -0,0 +1,157 @@ +/**************************************************************************** + * arch/avr32/src/avr32/up_nommuhead.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_nommuhead.S" + .global _sbss /* Start of .bss. Defined by ld.script */ + .global _ebss /* End of .bss. Defined by ld.script */ +#ifdef CONFIG_BOOT_RUNFROMFLASH + .global _sdata /* Start of .data section in RAM */ + .global _edata /* End of .data section in RAM */ + .global _eronly /* Start of .data section in FLASH */ +#endif + .global up_lowinit /* Perform low level initialization */ + .global os_start /* NuttX entry point */ + .global vectortab /* Vector base address */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/**************************************************************************** + * OS Entry Point + ****************************************************************************/ + +/* The following entry point must be linked to execute at 0x80000000 if it + * is to execute upon reset. + */ + .text + .global __start + .type __start, @function +__start: + + /* Set the IDLE thread stack pointer. This stack will be used + * through NuttX initialization and will, eventually, be inherited + * by the IDLE thread when threading is enabled. + */ + + lddpc sp, .Lstackbase + + /* Set up the vector base address so interrupts can be enabled. */ + + lda.w r0, vectortab + mtsr AVR32_EVBA, r0 + + /* Enable exception processing */ + + csrf AVR32_SR_EM_SHIFT + + /* Clear system BSS section */ + + lda.w r0, _sbss /* R =Start of .bss */ + lda.w r1, _ebss /* r1=End of .bss */ + mov r2, 0 /* Value to write to .bss */ + rjmp 2f /* Start at the bottom of the loop */ +1: + st.d r0++, r2 /* Zero .bss */ +2: + cp r0, r1 /* Finished? */ + brlo 1b /* No... keep looping */ + + /* Copy system .data sections to new home in RAM. */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + + lda.w r0, _sdata /* r0=Start of .data section in RAM */ + lda.w r1, _edata /* r1=End of .data section in RAM */ + lda.w r2, _eronly /* r2=Start of .data in FLASH */ + rjmp 4f /* Start at the bottom of the loop */ +3: + ld.d r4, r2++ /* Fetch the next data value */ + st.d r0++, r4 /* Write it to the .data section */ +4: + cp r0, r1 /* Finished? */ + brlo 3b /* No... keep looping */ + +#endif + + /* Clear the frame pointer and link register since this is the outermost + * frame. + */ + + mov r7, 0 + mov lr, 0 + + /* Perform low-level initialization */ + + mcall .Lup_lowinit + + /* Then jump to OS entry (will not return) */ + + lda.w pc, os_start + +.Lstackbase: + .word _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +.Lup_lowinit: + .word up_lowinit + .size __start, .-__start + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to other + * uses of _ebss in this file + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end + diff --git a/arch/avr/src/avr32/up_releasepending.c b/arch/avr/src/avr32/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..aaae06b59e480c1318a9ee3d660bbdf943ca3274 --- /dev/null +++ b/arch/avr/src/avr32/up_releasepending.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_releasepending.c + * + * Copyright (C) 2010, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexs */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr32/up_reprioritizertr.c b/arch/avr/src/avr32/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..88732c2b06e167907d86bd72cb128aaacea2632c --- /dev/null +++ b/arch/avr/src/avr32/up_reprioritizertr.c @@ -0,0 +1,202 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_reprioritizertr.c + * + * Copyright (C) 2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} + diff --git a/arch/avr/src/avr32/up_schedulesigaction.c b/arch/avr/src/avr32/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..838c1382c2d643fbc566a7710ad65d25d6e66d6f --- /dev/null +++ b/arch/avr/src/avr32/up_schedulesigaction.c @@ -0,0 +1,194 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_schedulesigaction.c + * + * Copyright (C) 2010, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * g_current_regs does not refer to the thread of this_task()! + */ + + else + { + /* Save registers that must be protected while the signal handler + * runs. These will be restored by the signal trampoline after + * the signal(s) have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = g_current_regs[REG_PC]; + tcb->xcp.saved_sr = g_current_regs[REG_SR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_PC] = (uint32_t)up_sigdeliver; + g_current_regs[REG_SR] |= AVR32_SR_GM_MASK; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save registers that must be protected while the signal handler + * runs. These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_sr = tcb->xcp.regs[REG_SR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_SR] |= AVR32_SR_GM_MASK; + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/avr/src/avr32/up_sigdeliver.c b/arch/avr/src/avr32/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..883bec974204ca75e07f15a245fe76353354f9f7 --- /dev/null +++ b/arch/avr/src/avr32/up_sigdeliver.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_sigdeliver.c + * + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); +#if 0 + uint32_t regs[XCPTCONTEXT_REGS+3]; /* Why +3? See below */ +#else + uint32_t regs[XCPTCONTEXT_REGS]; +#endif + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_SR] = rtcb->xcp.saved_sr; + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_SR]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. This is an + * unusual case that must be handled by up_fullcontextresore. This case is + * unusal in two ways: + * + * 1. It is not a context switch between threads. Rather, up_fullcontextrestore + * must behave more it more like a longjmp within the same task, using + * he same stack. + * 2. In this case, up_fullcontextrestore is called with r12 pointing to + * a register save area on the stack to be destroyed. This is + * dangerous because there is the very real possibility that the new + * stack pointer might overlap with the register save area and hat stack + * usage in up_fullcontextrestore might corrupt the register save data + * before the state is restored. At present, there does not appear to + * be any stack overlap problems. If there were, then adding 3 words + * to the size of register save structure size will protect its contents. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/avr/src/avr32/up_stackframe.c b/arch/avr/src/avr32/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..acd10d9216f658b7fcab260564d8fc01f6bb7c57 --- /dev/null +++ b/arch/avr/src/avr32/up_stackframe.c @@ -0,0 +1,141 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* The AVR32 stack must be aligned at word (4 byte) boundaries. If necessary + * frame_size must be rounded up to the next boundary + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/avr/src/avr32/up_switchcontext.S b/arch/avr/src/avr32/up_switchcontext.S new file mode 100644 index 0000000000000000000000000000000000000000..8820427e69ba999e7464345e88633e981d5271a2 --- /dev/null +++ b/arch/avr/src/avr32/up_switchcontext.S @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/avr/src/avr32/up_switchcontext.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .file "up_switchcontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. The full + * C function prototype is: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * Return: + * up_switchcontext forces a context switch to the task "canned" in restoreregs. + * It does not 'return' in the normal sense, rather, it will context switch back + * to the function point. When it does 'return,' it is because the blocked + * task hat was "pickeled" in the saveregs "can" is again ready to run and has + * execution priority. + * + * Assumptions: + * global interrupts disabled by the caller. + * + ************************************************************************************/ + + .text + .globl up_switchcontext + .type up_switchcontext, @function +up_switchcontext: + /* "Pickle" the current thread context in the saveregs "can." r12=saveregs. */ + /* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx */ + /* ^r12 */ + /* Sample SR and set r12 to just after the LR storage location. */ + /* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + mfsr r10, AVR32_SR + sub r12, -4*(REG_LR+1) + + /* Then "push" PC=LR, LR, SR, and SP as they are on entry. */ + /* xx xx xx xx xx xx xx xx SP SR PC LR xx xx xx xx xx */ + /* ^r12 */ + + st.w --r12, lr + st.w --r12, lr + st.w --r12, r10 + st.w --r12, sp + + /* Save the preserved/static registers, r0-r7. There is no reason to save the */ + /* scratch/volatile registers, r8-r12, in this context. */ + /* 07 06 05 04 03 02 01 00 SP SR PC LR xx xx xx xx xx */ + /* ^r12 */ + + stm --r12, r0-r7 + + /* Finally, let up_fullcontextrestore handling the re-instatement of the thread */ + /* "canned" in restoregs. */ + + mov r12, r11 + lddpc pc, .Lup_fullcontextrestore + +.Lup_fullcontextrestore: + .word up_fullcontextrestore + .size up_switchcontext, .-up_switchcontext + .end + diff --git a/arch/avr/src/avr32/up_syscall6.S b/arch/avr/src/avr32/up_syscall6.S new file mode 100644 index 0000000000000000000000000000000000000000..a0fdf0c163b69cdeb85b7ca07005e86aff99e743 --- /dev/null +++ b/arch/avr/src/avr32/up_syscall6.S @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_syscall6.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .file "up_syscall6.S" + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: sys_call6 + * + * C Prototype: + * uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + * uintptr_t parm2, uintptr_t parm3, + * uintptr_t parm4, uintptr_t parm5, + * uintptr_t parm6); + * + ****************************************************************************/ + + .global sys_call6 + .type sys_call6, @function + .align 2 + +sys_call6: + stm --sp, r3, r5, r6, lr + sub lr, sp, -16 + mov r8, r12 + ldm lr, r3, r5, r9-r12 + scall + ldm sp++, r3, r5, r6, pc + + .size sys_call6, . - sys_call6 diff --git a/arch/avr/src/avr32/up_unblocktask.c b/arch/avr/src/avr32/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..d8181344fdd56291cc6839f0a3766c6af357e6e5 --- /dev/null +++ b/arch/avr/src/avr32/up_unblocktask.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_unblocktask.c + * + * Copyright (C) 2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any new address environment needed by + * the new thread will be instantiated before the return from + * interrupt. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} + diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..533c82a16ca887849b6563fccf87bd328697d4d0 --- /dev/null +++ b/arch/avr/src/avr32/up_usestack.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/avr/src/avr32/up_usestack.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* If stack debug is enabled, then fill the stack with a recognizable value + * that we can use later to test for high water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); +#endif + + /* The AVR32 uses a push-down stack: the stack grows + * toward loweraddresses in memory. The stack pointer + * register, points to the lowest, valid work address + * (the "top" of the stack). Items on the stack are + * referenced as positive word offsets from sp. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The AVR32 stack must be aligned at word (4 byte) + * boundaries. If necessary top_of_stack must be rounded + * down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} + diff --git a/arch/avr/src/common/Kconfig b/arch/avr/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..a88c61ad5ce30d82bce637e999e5de531b5f3afe --- /dev/null +++ b/arch/avr/src/common/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_AVR +endif diff --git a/arch/avr/src/common/up_allocateheap.c b/arch/avr/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..052876f6740b880e5868afa5a1f66def23bb91c5 --- /dev/null +++ b/arch/avr/src/common/up_allocateheap.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/avr/src/common/up_allocateheap.c + * + * Copyright (C) 2010, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} diff --git a/arch/avr/src/common/up_arch.h b/arch/avr/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..80d8a75c5c69a7492d0fcea6e007404e40131559 --- /dev/null +++ b/arch/avr/src/common/up_arch.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/avr/src/common/up_arch.h + * + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_COMMON_UP_ARCH_H +#define __ARCH_AVR_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(a) (*(volatile uint8_t *)(a)) +# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +# define getreg16(a) (*(volatile uint16_t *)(a)) +# define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +# define getreg32(a) (*(volatile uint32_t *)(a)) +# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Atomic modification of registers */ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_COMMON_UP_ARCH_H */ + diff --git a/arch/avr/src/common/up_assert.c b/arch/avr/src/common/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..8ea84f017bc3dd454a3984a328ee0b47f84e8847 --- /dev/null +++ b/arch/avr/src/common/up_assert.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/avr/src/common/up_assert.c + * + * Copyright (C) 2010-2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP)) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/avr/src/common/up_exit.c b/arch/avr/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..936a79d2331c7c58f54b5789ed2ef5c985e5cc27 --- /dev/null +++ b/arch/avr/src/common/up_exit.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * arch/avr/src/common/up_exit.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s *tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} + diff --git a/arch/avr/src/common/up_idle.c b/arch/avr/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..7221a36e75f824d0e2824c2c551516970d09fb54 --- /dev/null +++ b/arch/avr/src/common/up_idle.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/avr/src/common/up_idle.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their + * is no other ready-to-run task. This is processor idle + * time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be + * performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, + * then process "fake" timer interrupts. Hopefully, something + * will wake up. + */ + + sched_process_timer(); +#endif +} + diff --git a/arch/avr/src/common/up_initialize.c b/arch/avr/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..5c36cd08144fad14026b9f3e948f6587b3a54068 --- /dev/null +++ b/arch/avr/src/common/up_initialize.c @@ -0,0 +1,308 @@ +/**************************************************************************** + * arch/avr/src/common/up_initialize.c + * + * Copyright (C) 2010, 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determine which (if any) console driver to use. This will probably cause + * up_serialinit to be incorrectly called if there is no USART configured to + * be an RS-232 device (see as an example arch/avr/src/at32uc23/at32uc3_config.h) + * This will probably have to be revisited someday. + * + * If a console is enabled and no other console device is specified, then a + * serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Name: up_color_intstack + * + * Description: + * Set the interrupt stack to a value so that later we can determine how + * much stack space was used by interrupt handling logic + * + ****************************************************************************/ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 +static inline void up_color_intstack(void) +{ + uint8_t *ptr = (uint8_t *)&g_intstackalloc; + ssize_t size; + + for (size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + size > 0; + size -= sizeof(uint8_t)) + { + *ptr++ = INTSTACK_COLOR; + } +} +#else +# define up_color_intstack() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Colorize the interrupt stack */ + + up_color_intstack(); + + /* Add any extra memory fragments to the memory manager */ + + up_addregion(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been + * brought into the build + */ + +#ifdef CONFIG_ARCH_DMA +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_dmainitialize) +#endif + { + up_dmainitialize(); + } +#endif + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB */ + + up_usbinitialize(); + +#if defined(ARCH_HAVE_LEDS) + board_autoled_on(LED_IRQSENABLED); +#endif +} diff --git a/arch/avr/src/common/up_internal.h b/arch/avr/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..bc6a7ebf257c1812bd3f090e343278d9737ca02e --- /dev/null +++ b/arch/avr/src/common/up_internal.h @@ -0,0 +1,206 @@ +/**************************************************************************** + * arch/avr/src/common/up_internal.h + * + * Copyright (C) 2010-2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __UP_INTERNAL_H +#define __UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#ifdef CONFIG_ARCH_FAMILY_AVR32 +# include "avr32.h" +#else +# include "avr.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/* This is the value used to mark the stack for subsequent stack monitoring + * logic. + */ + +#define STACK_COLOR 's' +#define INTSTACK_COLOR 's' +#define HEAP_COLOR 'h' + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +extern void g_intstackbase; +#endif + +/* These 'addresses' of these values are setup by the linker script. They are + * not actual uint32_t storage locations! They are only used meaningfully in the + * following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declareion extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data (it is + * not!). + * - We can recoved the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +extern uint32_t _stext; /* Start of .text */ +extern uint32_t _etext; /* End_1 of .text + .rodata */ +extern const uint32_t _eronly; /* End+1 of read only section (.text + .rodata) */ +extern uint32_t _sdata; /* Start of .data */ +extern uint32_t _edata; /* End+1 of .data */ +extern uint32_t _sbss; /* Start of .bss */ +extern uint32_t _ebss; /* End+1 of .bss */ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Defined in files with the same name as the function */ + +void up_boot(void); +void up_irqinitialize(void); +#ifdef CONFIG_ARCH_DMA +void weak_function up_dmainitialize(void); +#endif +void up_sigdeliver(void); +int up_timerisr(int irq, uint32_t *regs); +void up_lowputc(char ch); +void up_puts(const char *str); +void up_lowputs(const char *str); +void up_dumpstate(void); + +/* Defined in common/up_allocateheap.c or chip/xxx_allocateheap.c */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#else +# define up_addregion() +#endif + +/* Defined in chip/xxx_lowinit.c. This function is called from the + * head.S file just before jumping to os_start(). This function + * performs whatever very low level initialization that is needed + * before the OS gets started (clocks, console, LEDs, etc.) + */ + +void up_lowinit(void); + +/* Defined in chip/xxx_serial.c */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +void up_earlyserialinit(void); +void up_serialinit(void); +#else +# define up_earlyserialinit() +# define up_serialinit() +#endif + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* Defined in chip/xxx_timerisr.c */ + +void up_timer_initialize(void); + +/* Defined in chip/xxx_ethernet.c */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +/* Defined in chip/xxx_usbdev.c */ + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __UP_INTERNAL_H */ diff --git a/arch/avr/src/common/up_interruptcontext.c b/arch/avr/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..1607bc52a4c898fd278288c1b653ed8a28a9f567 --- /dev/null +++ b/arch/avr/src/common/up_interruptcontext.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/avr/src/common/up_interruptcontext.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/avr/src/common/up_lowputs.c b/arch/avr/src/common/up_lowputs.c new file mode 100644 index 0000000000000000000000000000000000000000..de4b4ff169e10b05a72f263e0fbeb57e7dbf02e5 --- /dev/null +++ b/arch/avr/src/common/up_lowputs.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/avr/src/common/up_lowputs.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} + diff --git a/arch/avr/src/common/up_mdelay.c b/arch/avr/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..bf594a3b088c4c29b423b5b9af7556416cfa2334 --- /dev/null +++ b/arch/avr/src/common/up_mdelay.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/avr/src/common/up_mdelay.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} + diff --git a/arch/avr/src/common/up_modifyreg16.c b/arch/avr/src/common/up_modifyreg16.c new file mode 100644 index 0000000000000000000000000000000000000000..4e97cc95fcc3656fb15914dedfad0f85c9e76a2a --- /dev/null +++ b/arch/avr/src/common/up_modifyreg16.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/avr/src/common/up_modifyreg16.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16(addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, addr); + leave_critical_section(flags); +} + diff --git a/arch/avr/src/common/up_modifyreg32.c b/arch/avr/src/common/up_modifyreg32.c new file mode 100644 index 0000000000000000000000000000000000000000..b6fc00fbb619b1084854bbb69e994bdbd99bff67 --- /dev/null +++ b/arch/avr/src/common/up_modifyreg32.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/avr/src/common/up_modifyreg32.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32(addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, addr); + leave_critical_section(flags); +} + diff --git a/arch/avr/src/common/up_modifyreg8.c b/arch/avr/src/common/up_modifyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..d954b2ca65df6dce112d8fdb365a9d569f33e9ee --- /dev/null +++ b/arch/avr/src/common/up_modifyreg8.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/avr/src/common/up_modifyreg8.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8(addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, addr); + leave_critical_section(flags); +} + diff --git a/arch/avr/src/common/up_puts.c b/arch/avr/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..e9b4171b98961ab51749c5c5adb9b392a4ae0b3d --- /dev/null +++ b/arch/avr/src/common/up_puts.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/avr/src/common/up_puts.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} + diff --git a/arch/avr/src/common/up_releasestack.c b/arch/avr/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..9cda128cabf0d7ebe85e959e80e7d89af68046c7 --- /dev/null +++ b/arch/avr/src/common/up_releasestack.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/avr/src/common/up_releasestack.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} + diff --git a/arch/avr/src/common/up_udelay.c b/arch/avr/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..f71d5ee6b20b58902781f4f73552cad311f66680 --- /dev/null +++ b/arch/avr/src/common/up_udelay.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/avr/src/common/up_udelay.c + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} + diff --git a/arch/avr/src/xmega/chip/xmegac_memorymap.h b/arch/avr/src/xmega/chip/xmegac_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..0a015c0a5a872f6f147ddb3e338f6fced7767394 --- /dev/null +++ b/arch/avr/src/xmega/chip/xmegac_memorymap.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/avr/src/xmega/chip/xmegac_memorymap.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_AVR_SRC_XMEGA_CHIP_XMEGAC_MEMORYMAP_H +#define __ARCH_AVR_SRC_XMEGA_CHIP_XMEGAC_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* XMega C data memory map */ + +#define XMEGA_IOMEM_BASE 0x0000 /* I/O Memory (Up to 4 KB) */ +#define XMEGA_EEPROM_BASE 0x1000 /* EEPROM (Up to 4 KB) */ +#define XMEGA_ISRAM_BASE 0x2000 /* Internal SRAM */ + +#define XMEGA_GPIO_BASE 0x0000 /* General Purpose IO Registers */ +#define XMEGA_VPORT0_BASE 0x0010 /* Virtual Port 0 */ +#define XMEGA_VPORT1_BASE 0x0014 /* Virtual Port 1 */ +#define XMEGA_VPORT2_BASE 0x0018 /* Virtual Port 2 */ +#define XMEGA_VPORT3_BASE 0x001c /* Virtual Port 3 */ +#define XMEGA_CPU_BASE 0x0030 /* CPU */ +#define XMEGA_CLK_BASE 0x0040 /* Clock Control */ +#define XMEGA_SLEEP_BASE 0x0048 /* Sleep Controller */ +#define XMEGA_OSC_BASE 0x0050 /* Oscillator Control */ +#define XMEGA_DFLLRC32M_BASE 0x0060 /* DFLL for the 32 MHz Internal RC Oscillator */ +#define XMEGA_DFLLRC2M_BASE 0x0068 /* DFLL for the 2 MHz RC Oscillator */ +#define XMEGA_PR_BASE 0x0070 /* Power Reduction */ +#define XMEGA_RST_BASE 0x0078 /* Reset Controller */ +#define XMEGA_WDT_BASE 0x0080 /* Watch-Dog Timer */ +#define XMEGA_MCU_BASE 0x0090 /* MCU Control */ +#define XMEGA_PMIC_BASE 0x00a0 /* Programmable Multilevel Interrupt Controller */ +#define XMEGA_PORTCFG_BASE 0x00b0 /* Port Configuration */ +#define XMEGA_AES_BASE 0x00c0 /* AES Module */ +#define XMEGA_DMA_BASE 0x0100 /* DMA Controller */ +#define XMEGA_EVSYS_BASE 0x0180 /* Event System */ +#define XMEGA_NVM_BASE 0x01C0 /* Non Volatile Memory (NVM) Controller */ +#define XMEGA_ADCA_BASE 0x0200 /* Analog to Digital Converter on port A */ +#define XMEGA_ACA_BASE 0x0380 /* Analog Comparator pair on port A */ +#define XMEGA_RTC_BASE 0x0400 /* Real Time Counter */ +#define XMEGA_TWIC_BASE 0x0480 /* Two Wire Interface on port C */ +#define XMEGA_TWIE_BASE 0x04a0 /* Two Wire Interface on port E */ +#define XMEGA_PORTA_BASE 0x0600 /* Port A */ +#define XMEGA_PORTB_BASE 0x0620 /* Port B */ +#define XMEGA_PORTC_BASE 0x0640 /* Port C */ +#define XMEGA_PORTD_BASE 0x0660 /* Port D */ +#define XMEGA_PORTE_BASE 0x0680 /* Port E */ +#define XMEGA_PORTF_BASE 0x06a0 /* Port F */ +#define XMEGA_PORTR_BASE 0x07e0 /* Port R */ +#define XMEGA_TCC0_BASE 0x0800 /* Timer/Counter 0 on port C */ +#define XMEGA_TCC1_BASE 0x0840 /* Timer/Counter 1 on port C */ +#define XMEGA_AWEXC_BASE 0x0880 /* Advanced Waveform Extension on port C */ +#define XMEGA_HIRESC_BASE 0x0890 /* High Resolution Extension on port C */ +#define XMEGA_USARTC0_BASE 0x08a0 /* USART 0 on port C */ +#define XMEGA_USARTC1_BASE 0x08b0 /* USART 1 on port C */ +#define XMEGA_SPIC_BASE 0x08c0 /* Serial Peripheral Interface on port C */ +#define XMEGA_IRCOM_BASE 0x08f0 /* Infrared Communication Module */ +#define XMEGA_TCD0_BASE 0x0900 /* Timer/Counter 0 on port D */ +#define XMEGA_USARTD0_BASE 0x09a0 /* USART 0 on port D */ +#define XMEGA_SPID_BASE 0x09c0 /* Serial Peripheral Interface on port D */ +#define XMEGA_TCE0_BASE 0x0a00 /* Timer/Counter 0 on port E */ +#define XMEGA_USARTE0_BASE 0x0aa0 /* USART 0 on port E */ +#define XMEGA_TCF0_BASE 0x0b00 /* Timer/Counter 0 on port F */ +#define XMEGA_USARTF0_BASE 0x0ba0 /* USART 0 on port F */ + +#endif /* __ARCH_AVR_SRC_XMEGA_CHIP_XMEGAC_MEMORYMAP_H */ diff --git a/arch/hc/Kconfig b/arch/hc/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..dedfeead2d1d2b602344048545e7ea58b7e47448 --- /dev/null +++ b/arch/hc/Kconfig @@ -0,0 +1,31 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_HC + +choice + prompt "HC chip selection" + default ARCH_CHIP_MCS92S12NEC64 + +config ARCH_CHIP_MCS92S12NEC64 + bool "MCS92S12NEC64" + select ARCH_HSC12 + select MM_SMALL + ---help--- + Motorola/Freescale MCS92S12NEC64 (M9S12) + +endchoice + +config ARCH_HSC12 + bool + default n + +config ARCH_CHIP + string + default "m9s12" if ARCH_CHIP_MCS92S12NEC64 + +source arch/hc/src/m9s12/Kconfig + +endif # ARCH_HC diff --git a/arch/hc/include/.gitignore b/arch/hc/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8b8a2b105cef1a882b2b510bc9eb3c0f28ee2e8f --- /dev/null +++ b/arch/hc/include/.gitignore @@ -0,0 +1,3 @@ +/chip +/board + diff --git a/arch/hc/include/arch.h b/arch/hc/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..8c1db80697359ff396e68010425a545ada3ec33f --- /dev/null +++ b/arch/hc/include/arch.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/hc/include/arch.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_HC_INCLUDE_ARCH_H +#define __ARCH_HC_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_HC_INCLUDE_ARCH_H */ diff --git a/arch/hc/include/hc12/irq.h b/arch/hc/include/hc12/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..209a34cdd6df87fe4c2e0f68cf8053641e214048 --- /dev/null +++ b/arch/hc/include/hc12/irq.h @@ -0,0 +1,121 @@ +/************************************************************************************ + * arch/hc/include/hc12/irq.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_HC_INCLUDE_HC12_IRQ_H +#define __ARCH_HC_INCLUDE_HC12_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* This structure defines the way the registers are stored. */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + int dummy; /* For now */ +}; + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Save the current interrupt enable state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) +{ + /* To be provided */ +} + +/* Restore saved IRQ & FIQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + /* To be provided */ +} + +static inline void system_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + /* To be provided */ +} + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_HC_INCLUDE_HC12_IRQ_H */ diff --git a/arch/hc/include/hc12/limits.h b/arch/hc/include/hc12/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..bc38b928b652a2f2e71a1527eec0ffb28136a339 --- /dev/null +++ b/arch/hc/include/hc12/limits.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/hc/include/hc12/limits.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_HC_INCLUDE_HC12_LIMITS_H +#define __ARCH_HC_INCLUDE_HC12_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* The size of an integer is controlled with the -mshort or -mnoshort GCC + * options. GCC will set the pre-defined symbol __INT__ to indicate the size + * of an integer + */ + +#define INT_MIN (-INT_MAX - 1) +#if __INT__ == 32 +# define INT_MAX 2147483647 +# define UINT_MAX 4294967295 +#else +# define INT_MAX 32767 +# define UINT_MAX 65535U +#endif + +/* Long is 4-bytes and long long is 8 bytes in any case */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_HC_INCLUDE_HC12_LIMITS_H */ diff --git a/arch/hc/include/hc12/types.h b/arch/hc/include/hc12/types.h new file mode 100644 index 0000000000000000000000000000000000000000..bfc49935417769592356c5b703a595f3f24fb806 --- /dev/null +++ b/arch/hc/include/hc12/types.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/hc/include/hc12/types.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_HC_INCLUDE_HC12_TYPES_H +#define __ARCH_HC_INCLUDE_HC12_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +/* Normally, mc68hc1x code is compiled with the -mshort option + * which results in a 16-bit integer. If -mnoshort is defined + * then an integer is 32-bits. GCC will defined __INT__ accordingly: + */ + +# if __INT__ == 16 +typedef signed long _int32_t; +typedef unsigned long _uint32_t; +#else +typedef signed int _int32_t; +typedef unsigned int _uint32_t; +#endif + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is two bytes */ + +typedef signed short _intptr_t; +typedef unsigned short _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save()*/ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_HC_INCLUDE_HC12_TYPES_H */ diff --git a/arch/hc/include/hcs12/irq.h b/arch/hc/include/hcs12/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..2095544eb440fbd8e7e0aa814a5473ac1e44e270 --- /dev/null +++ b/arch/hc/include/hcs12/irq.h @@ -0,0 +1,284 @@ +/************************************************************************************ + * arch/hc/include/hcs12/irq.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_HC_INCLUDE_HCS12_IRQ_H +#define __ARCH_HC_INCLUDE_HCS12_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* CCR bit definitions */ + +#define HCS12_CCR_C (1 << 0) /* Bit 0: Carry/Borrow status bit */ +#define HCS12_CCR_V (1 << 1) /* Bit 1: Two’s complement overflow status bit */ +#define HCS12_CCR_Z (1 << 2) /* Bit 2: Zero status bit */ +#define HCS12_CCR_N (1 << 3) /* Bit 3: Negative status bit */ +#define HCS12_CCR_I (1 << 4) /* Bit 4: Maskable interrupt control bit */ +#define HCS12_CCR_H (1 << 5) /* Bit 5: Half-carry status bit */ +#define HCS12_CCR_X (1 << 6) /* Bit 6: Non-maskable interrupt control bit */ +#define HCS12_CCR_S (1 << 7) /* Bit 7: STOP instruction control bit */ + +/************************************************************************************ + * Register state save strucure + * Low Address <-- SP after state save + * [PPAGE] + * [soft regisers] + * XYH + * XYL + * ZH + * ZL + * TMPH + * TMPL + * FRAMEH + * FRAMEL + * SP <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL <-- SP before interrupt + * + ************************************************************************************/ + +/* Byte offsets */ +/* PPAGE register (only in banked mode) */ + +#ifndef CONFIG_HCS12_NONBANKED +# define REG_PPAGE 0 +# define REG_FIRST_SOFTREG 1 +#else +# define REG_FIRST_SOFTREG 0 +#endif + +/* Soft registers (as configured) */ + +#if CONFIG_HCS12_MSOFTREGS > 2 +# error "Need to save more registers" +#elif CONFIG_HCS12_MSOFTREGS == 2 +# define REG_SOFTREG1 REG_FIRST_SOFTREG +# define REG_SOFTREG2 (REG_FIRST_SOFTREG+2) +# define REG_FIRST_HARDREG (REG_FIRST_SOFTREG+4) +#elif CONFIG_HCS12_MSOFTREGS == 1 +# define REG_SOFTREG1 REG_FIRST_SOFTREG +# define REG_FIRST_HARDREG (REG_FIRST_SOFTREG+2) +#else +# define REG_FIRST_HARDREG REG_FIRST_SOFTREG +#endif + +#define REG_XY REG_FIRST_HARDREG +#define REG_Z (REG_FIRST_HARDREG+2) +# define REG_ZH (REG_FIRST_HARDREG+2) +# define REG_ZL (REG_FIRST_HARDREG+3) +#define REG_TMP (REG_FIRST_HARDREG+4) +# define REG_TMPH (REG_FIRST_HARDREG+4) +# define REG_TMPL (REG_FIRST_HARDREG+5) +#define REG_FRAME (REG_FIRST_HARDREG+6) +# define REG_FRAMEH (REG_FIRST_HARDREG+6) +# define REG_FRAMEL (REG_FIRST_HARDREG+7) + +/* Stack pointer before the interrupt */ + +#define REG_SP (REG_FIRST_HARDREG+8) +# define REG_SPH (REG_FIRST_HARDREG+8) +# define REG_SPL (REG_FIRST_HARDREG+9) + +/* On entry into an I- or X-interrupt, into an SWI, or into an undefined instruction + * interrupt, the stack frame created by hardware looks like: + * + * Low Address <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL <-- SP before interrupt + */ + +#define REG_CCR (REG_FIRST_HARDREG+10) +#define REG_BA (REG_FIRST_HARDREG+11) +# define REG_B (REG_FIRST_HARDREG+11) +# define REG_A (REG_FIRST_HARDREG+12) +#define REG_X (REG_FIRST_HARDREG+13) +# define REG_XH (REG_FIRST_HARDREG+13) +# define REG_XL (REG_FIRST_HARDREG+14) +#define REG_Y (REG_FIRST_HARDREG+15) +# define REG_YH (REG_FIRST_HARDREG+15) +# define REG_YL (REG_FIRST_HARDREG+16) +#define REG_PC (REG_FIRST_HARDREG+17) +# define REG_PCH (REG_FIRST_HARDREG+17) +# define REG_PCL (REG_FIRST_HARDREG+18) + +#define TOTALFRAME_SIZE (REG_FIRST_HARDREG+17) +#define INTFRAME_SIZE 9 +#define XCPTCONTEXT_REGS TOTALFRAME_SIZE + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* This structure defines the way the registers are stored. */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + uint8_t regs[XCPTCONTEXT_REGS]; +}; + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Enable/Disable interrupts */ + +#define ienable() __asm("cli"); +#define idisable() __asm("orcc #0x10") +#define xenable() __asm("andcc #0xbf") +#define xdisable() __asm("orcc #0x40") + +/* Get the current value of the stack pointer */ + +static inline uint16_t up_getsp(void) +{ + uint16_t ret; + __asm__ + ( + "\tsts %0\n" + : "=m"(ret) : + ); + return ret; +} + +/* Get the current value of the CCR */ + +static inline irqstate_t up_getccr(void) +{ + irqstate_t ccr; + __asm__ + ( + "\ttpa\n" + "\tstaa %0\n" + : "=m"(ccr) : + ); + return ccr; +} + +/* Save the current interrupt enable state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t ccr; + __asm__ + ( + "\ttpa\n" + "\tstaa %0\n" + "\torcc #0x50\n" + : "=m"(ccr) : + ); + return ccr; +} + +/* Restore saved interrupt state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + /* Should interrupts be enabled? */ + + if ((flags & HCS12_CCR_I) == 0) + { + /* Yes.. unmask I- and Z-interrupts */ + + __asm("andcc #0xaf"); + } +} + +/* System call */ + +static inline void system_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + /* To be provided */ + /* __asm("swi") */ +} + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_HC_INCLUDE_HCS12_IRQ_H */ diff --git a/arch/hc/include/hcs12/limits.h b/arch/hc/include/hcs12/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f2865cb5b8b8480af460200b45181571c77052 --- /dev/null +++ b/arch/hc/include/hcs12/limits.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/hc/include/hcs12/limits.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_HC_INCLUDE_HCS12_LIMITS_H +#define __ARCH_HC_INCLUDE_HCS12_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* The size of an integer is controlled with the -mshort or -mnoshort GCC + * options. GCC will set the pre-defined symbol __INT__ to indicate the size + * of an integer + */ + +#define INT_MIN (-INT_MAX - 1) +#if __INT__ == 32 +# define INT_MAX 2147483647 +# define UINT_MAX 4294967295 +#else +# define INT_MAX 32767 +# define UINT_MAX 65535U +#endif + +/* Long is 4-bytes and long long is 8 bytes in any case */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_HC_INCLUDE_HCS12_LIMITS_H */ diff --git a/arch/hc/include/hcs12/types.h b/arch/hc/include/hcs12/types.h new file mode 100644 index 0000000000000000000000000000000000000000..87762c204008439c91b63e7d30721bb3b09e8bf5 --- /dev/null +++ b/arch/hc/include/hcs12/types.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/hc/include/hcs12/types.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_HC_INCLUDE_HCS12_TYPES_H +#define __ARCH_HC_INCLUDE_HCS12_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +/* Normally, mc68hc1x code is compiled with the -mshort option + * which results in a 16-bit integer. If -mnoshort is defined + * then an integer is 32-bits. GCC will defined __INT__ accordingly: + */ + +# if __INT__ == 16 +typedef signed long _int32_t; +typedef unsigned long _uint32_t; +#else +typedef signed int _int32_t; +typedef unsigned int _uint32_t; +#endif + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is two bytes */ + +typedef signed short _intptr_t; +typedef unsigned short _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save()*/ + +typedef unsigned char irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_HC_INCLUDE_HCS12_TYPES_H */ diff --git a/arch/hc/include/irq.h b/arch/hc/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..55c8622c927caad08bf3b9090ad1e2c8fbfa8c58 --- /dev/null +++ b/arch/hc/include/irq.h @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/hc/include/irq.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_HC_INCLUDE_IRQ_H +#define __ARCH_HC_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/* Include architecture-specific IRQ definitions (including register + * save structure and up_irq_save()/up_irq_restore() macros + */ + +#if defined(CONFIG_ARCH_HC12) +# include +#elif defined(CONFIG_ARCH_HCS12) +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_HC_INCLUDE_IRQ_H */ + diff --git a/arch/hc/include/limits.h b/arch/hc/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..c89d387f4956c31be4c7efa419f885238429edcc --- /dev/null +++ b/arch/hc/include/limits.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/hc/include/limits.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_HC_INCLUDE_LIMITS_H +#define __ARCH_HC_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include architecture-specific limits definitions */ + +#if defined(CONFIG_ARCH_HC12) +# include +#elif defined(CONFIG_ARCH_HCS12) +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_HC_INCLUDE_LIMITS_H */ diff --git a/arch/hc/include/m9s12/irq.h b/arch/hc/include/m9s12/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..63ab556b8e4d658e69ad8940e8e56145de45893a --- /dev/null +++ b/arch/hc/include/m9s12/irq.h @@ -0,0 +1,191 @@ +/************************************************************************************ + * arch/hc/include/m9s12/irq.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_HC_INCLUDE_M9S12_IRQ_H +#define __ARCH_HC_INCLUDE_M9S12_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ Numbers */ + +#define HCS12_IRQ_VRESET 0 /* fffe: External reset, power on reset orlow voltage reset */ +#define HCS12_IRQ_VCLKMON 1 /* fffc: Clock monitor fail reset */ +#define HCS12_IRQ_VCOP 2 /* fffa: COP failure reset*/ +#define HCS12_IRQ_VTRAP 3 /* fff8: Unimplemented instruction trap */ +#define HCS12_IRQ_VSWI 4 /* fff6: SWI */ +#define HCS12_IRQ_VXIRQ 5 /* fff4: XIRQ */ +#define HCS12_IRQ_VIRQ 6 /* fff2: IRQ */ +#define HCS12_IRQ_VRTI 7 /* fff0: Real-time interrupt */ + /* ffe8-ffef: Reserved */ +#define HCS12_IRQ_VTIMCH4 8 /* ffe6: Standard timer channel 4 */ +#define HCS12_IRQ_VTIMCH5 9 /* ffe4: Standard timer channel 5 */ +#define HCS12_IRQ_VTIMCH6 10 /* ffe2: Standard timer channel 6 */ +#define HCS12_IRQ_VTIMCH7 11 /* ffe0: Standard timer channel 7 */ +#define HCS12_IRQ_VTIMOVF 12 /* ffde: Standard timer overflow */ +#define HCS12_IRQ_VTIMPAOVF 13 /* ffdc: Pulse accumulator overflow */ +#define HCS12_IRQ_VTIMPAIE 14 /* ffda: Pulse accumulator input edge */ +#define HCS12_IRQ_VSPI 15 /* ffd8: SPI */ +#define HCS12_IRQ_VSCI0 16 /* ffd6: SCI0 */ +#define HCS12_IRQ_VSCI1 17 /* ffd4: SCI1 */ +#define HCS12_IRQ_VATD 18 /* ffd2: ATD */ + /* ffd0: Reserved */ +#define HCS12_IRQ_VPORTJ 19 /* ffce: Port J */ +#define HCS12_IRQ_VPORTH 20 /* ffcc: Port H */ +#define HCS12_IRQ_VPORTG 21 /* ffca: Port G */ + /* ffc8: Reserved */ +#define HCS12_IRQ_VCRGPLLLCK 22 /* ffc6: CRG PLL lock */ +#define HCS12_IRQ_VCRGSCM 23 /* ffc4: CRG self clock mode */ + /* ffc2: Reserved */ +#define HCS12_IRQ_VIIC 24 /* ffc0: IIC bus */ + /* ffba-ffbf: Reserved */ +#define HCS12_IRQ_VFLASH 25 /* ffb8: FLASH */ +#define HCS12_IRQ_VEPHY 26 /* ffb6: EPHY interrupt */ +#define HCS12_IRQ_VEMACCRXBAC 27 /* ffb4: EMAC receive buffer A complete */ +#define HCS12_IRQ_VEMACCRXBBC 28 /* ffb2: EMAC receive buffer B complete */ +#define HCS12_IRQ_VEMACTXC 29 /* ffb0: EMAC frame transmission complete */ +#define HCS12_IRQ_VEMACRXFC 30 /* ffae: EMAC receive flow control */ +#define HCS12_IRQ_VEMACMII 31 /* ffac: EMAC MII management transfer complete */ +#define HCS12_IRQ_VEMACRXERR 32 /* ffaa: EMAC receive error */ +#define HCS12_IRQ_VEMACRXBAO 33 /* ffa8: EMAC receive buffer A overrun */ +#define HCS12_IRQ_VEMACRXBBO 34 /* ffa6: EMAC receive buffer B overrun */ +#define HCS12_IRQ_VEMACBRXERR 35 /* ffa4: EMAC babbling receive error */ +#define HCS12_IRQ_VEMACLC 36 /* ffa2: EMAC late collision */ +#define HCS12_IRQ_VEMACEC 37 /* ffa0: EMAC excessive collision */ + /* ff80-ff9f: Reserved */ +#define HCS12_IRQ_NVECTORS 38 + +/* GPIO interrupts. The m9s12x supports several interrupts on PIM ports G, H, + * and J. We go through some special efforts to keep the number of IRQs + * to a minimum in this sparse interrupt case. + * + * Port G: Pins 0-7 + * Port H: Pins 0-6 + * Port J: Pins 0-3 and 6-7 + */ + +#ifdef CONFIG_GPIO_IRQ + +/* To conserve space, interrupts must also be configured, port by port */ + +# define HCC12_IRQ_PGFIRST HCS12_IRQ_NVECTORS +# ifdef CONFIG_HCS12_PORTG_INTS +# define HCS12_IRQ_PGSET 0xff +# define HCS12_IRQ_PG0 (HCC12_IRQ_PGFIRST+0) +# define HCS12_IRQ_PG1 (HCC12_IRQ_PGFIRST+1) +# define HCS12_IRQ_PG2 (HCC12_IRQ_PGFIRST+2) +# define HCS12_IRQ_PG3 (HCC12_IRQ_PGFIRST+3) +# define HCS12_IRQ_PG4 (HCC12_IRQ_PGFIRST+4) +# define HCS12_IRQ_PG5 (HCC12_IRQ_PGFIRST+5) +# define HCS12_IRQ_PG6 (HCC12_IRQ_PGFIRST+6) +# define HCS12_IRQ_PG7 (HCC12_IRQ_PGFIRST+7) +# define HCC12_IRQ_PHFIRST (HCC12_IRQ_PGFIRST+8) +# else +# define HCC12_IRQ_PHFIRST HCC12_IRQ_PGFIRST +# endif + +# ifdef CONFIG_HCS12_PORTH_INTS +# define HCS12_IRQ_PHSET 0x7f +# define HCS12_IRQ_PH0 (HCC12_IRQ_PHFIRST+0) +# define HCS12_IRQ_PH1 (HCC12_IRQ_PHFIRST+1) +# define HCS12_IRQ_PH2 (HCC12_IRQ_PHFIRST+2) +# define HCS12_IRQ_PH3 (HCC12_IRQ_PHFIRST+3) +# define HCS12_IRQ_PH4 (HCC12_IRQ_PHFIRST+4) +# define HCS12_IRQ_PH5 (HCC12_IRQ_PHFIRST+5) +# define HCS12_IRQ_PH6 (HCC12_IRQ_PHFIRST+6) +# define HCC12_IRQ_PJFIRST (HCC12_IRQ_PHFIRST+7) +# else +# define HCC12_IRQ_PJFIRST HCC12_IRQ_PHFIRST +# endif + +# ifdef CONFIG_HCS12_PORTJ_INTS +# define HCS12_IRQ_PJSET 0xcf +# define HCS12_IRQ_PJ0 (HCC12_IRQ_PJFIRST+0) +# define HCS12_IRQ_PJ1 (HCC12_IRQ_PJFIRST+1) +# define HCS12_IRQ_PJ2 (HCC12_IRQ_PJFIRST+2) +# define HCS12_IRQ_PJ3 (HCC12_IRQ_PJFIRST+3) +# define HCS12_IRQ_PJ6 (HCC12_IRQ_PJFIRST+4) +# define HCS12_IRQ_PJ7 (HCC12_IRQ_PJFIRST+5) +# define HCS12_IRQ_NIRQS (HCC12_IRQ_PJFIRST+6) +# else +# define HCS12_IRQ_NIRQS HCC12_IRQ_PJFIRST +# endif +#else +# define HCS12_IRQ_NIRQS HCS12_IRQ_NVECTORS +#endif /* CONFIG_GPIO_IRQ */ + +#define HCS12_IRQ_VILLEGAL HCS12_IRQ_NIRQS /* Any reserved vector */ +#define NR_IRQS (HCS12_IRQ_NIRQS+1) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_HC_INCLUDE_M9S12_IRQ_H */ diff --git a/arch/hc/include/syscall.h b/arch/hc/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..a9d1b5ce83c66b190cb97b789afa820948e7ad4e --- /dev/null +++ b/arch/hc/include/syscall.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/hc/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef _ARCH_HC_INCLUDE_SYSCALL_H +#define _ARCH_HC_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* _ARCH_HC_INCLUDE_SYSCALL_H */ + diff --git a/arch/hc/include/types.h b/arch/hc/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..e7b133b9640f3c44a6fa7dcc02fd7051ea625600 --- /dev/null +++ b/arch/hc/include/types.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/hc/include/types.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_HC_INCLUDE_TYPES_H +#define __ARCH_HC_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Include architecture-specific limits definitions */ + +#if defined(CONFIG_ARCH_HC12) +# include +#elif defined(CONFIG_ARCH_HCS12) +# include +#endif + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_HC_INCLUDE_TYPES_H */ diff --git a/arch/hc/src/.gitignore b/arch/hc/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..716af76fed4a56dbb3e35c13044da19949c9bd24 --- /dev/null +++ b/arch/hc/src/.gitignore @@ -0,0 +1,5 @@ +/.depend +/Make.dep +/board +/chip +/*.r diff --git a/arch/hc/src/Makefile b/arch/hc/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..fb165188fe1e19465a32b120ceaf05fd159d1360 --- /dev/null +++ b/arch/hc/src/Makefile @@ -0,0 +1,184 @@ +############################################################################ +# arch/hc/src/Makefile +# +# Copyright (C) 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +ifeq ($(CONFIG_ARCH_HC12),y) +ARCH_SUBDIR = hc12 +endif +ifeq ($(CONFIG_ARCH_HCS12),y) +ARCH_SUBDIR = hcs12 +endif + +CPPFLAGS += $(EXTRADEFINES) +CFLAGS += $(EXTRADEFINES) +CXXFLAGS += $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)" + CFLAGS += -I$(ARCH_SRCDIR)\chip + CFLAGS += -I$(ARCH_SRCDIR)\common + CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)\sched +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)" + CFLAGS += -I$(ARCH_SRCDIR)/chip + CFLAGS += -I$(ARCH_SRCDIR)/common + CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)/sched +endif +endif + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +VPATH = chip:common:$(ARCH_SUBDIR) + +all: $(HEAD_OBJ) libarch$(LIBEXT) +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + $(Q) echo "LD: nuttx" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_OBJ) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX)$(EXEEXT) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/hc/src/common/up_allocateheap.c b/arch/hc/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..946fbf69ec1337a2db99c92a2aba61c48c5b14aa --- /dev/null +++ b/arch/hc/src/common/up_allocateheap.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/hc/src/common/up_allocateheap.c + * + * Copyright (C) 2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void*)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} diff --git a/arch/hc/src/common/up_arch.h b/arch/hc/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..b788ecdf29c1d687aa6d736de8b2e7610dbb4c94 --- /dev/null +++ b/arch/hc/src/common/up_arch.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/hc/src/common/up_arch.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_HC_SRC_COMMON_UP_ARCH_H +#define ___ARCH_HC_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(a) (*(volatile uint8_t *)(a)) +# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +# define getreg16(a) (*(volatile uint16_t *)(a)) +# define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +# define getreg32(a) (*(volatile uint32_t *)(a)) +# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Atomic modification of registers */ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* ___ARCH_HC_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/hc/src/common/up_blocktask.c b/arch/hc/src/common/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..f6308cb729056e30f3eae9666ef392e2e4f968fa --- /dev/null +++ b/arch/hc/src/common/up_blocktask.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/hc/src/common/up_blocktask.c + * + * Copyright (C) 2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/hc/src/common/up_copystate.c b/arch/hc/src/common/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..c9fe24b34e858494bf5efea45c6bf88ed0b9930a --- /dev/null +++ b/arch/hc/src/common/up_copystate.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/hc/src/common/up_copystate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_undefinedinsn + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint8_t *dest, uint8_t *src) +{ + int i; + + /* In the current ARM model, the state is always copied to and from the + * stack and TCB. + */ + + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..9afb471e470f9a9f5402040bd2577edb26a496cd --- /dev/null +++ b/arch/hc/src/common/up_createstack.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/hc/src/common/up_createstack.c + * + * Copyright (C) 2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* The CPU12 uses a push-down stack: the stack grows + * toward lower addresses in memory. Because the CPU12 stack + * operates as a decrement then store stack, the value assigned + * to the initial stack pointer is one more than the last valid + * stack address. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + + /* The CPU12 stack should be aligned at half-word (2 byte) + * boundaries. If necessary top_of_stack must be rounded + * down to the next boundary + */ + + top_of_stack &= ~1; + size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/hc/src/common/up_doirq.c b/arch/hc/src/common/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..c72964ea96f9fc3a9e97912fad19171fa06cc4f4 --- /dev/null +++ b/arch/hc/src/common/up_doirq.c @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/hc/src/common/up_doirq.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint8_t *up_doirq(int irq, uint8_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t*)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint8_t*)g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; +#endif + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/hc/src/common/up_exit.c b/arch/hc/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..f80a4c3b0e00850c7de1f5c5d9a813d6c06f2f92 --- /dev/null +++ b/arch/hc/src/common/up_exit.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/hc/src/common/up_exit.c + * + * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s* tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} + diff --git a/arch/hc/src/common/up_idle.c b/arch/hc/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..e2222cf4aa044036f9cb16a63d16e208e714f2e6 --- /dev/null +++ b/arch/hc/src/common/up_idle.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/hc/src/common/up_idle.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, + * then process "fake" timer interrupts. Hopefully, something + * will wake up. + */ + + sched_process_timer(); +#endif +} + diff --git a/arch/hc/src/common/up_initialize.c b/arch/hc/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..30daa39ea29ba63289d2e6cdad8aa92006bd9507 --- /dev/null +++ b/arch/hc/src/common/up_initialize.c @@ -0,0 +1,225 @@ +/**************************************************************************** + * arch/hc/src/common/up_initialize.c + * + * Copyright (C) 2009-2010, 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Add any extra memory fragments to the memory manager */ + + up_addregion(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been + * brought into the build + */ + +#ifdef CONFIG_ARCH_DMA +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_dmainitialize) +#endif + { + up_dmainitialize(); + } +#endif + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB */ + + up_usbinitialize(); + + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/hc/src/common/up_internal.h b/arch/hc/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..a2d443415513cf4da0b84cd9c57532d163a320c0 --- /dev/null +++ b/arch/hc/src/common/up_internal.h @@ -0,0 +1,238 @@ +/**************************************************************************** + * arch/hc/src/common/up_internal.h + * + * Copyright (C) 2009, 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __UP_INTERNAL_H +#define __UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/* Macros to handle saving and restore interrupt state. In the current CPU12 + * model, the state is copied from the stack to the TCB, but only + * a referenced is passed to get the state from the TCB. + */ + +#define up_savestate(regs) up_copystate(regs, (uint8_t*)g_current_regs) +#define up_restorestate(regs) (g_current_regs = regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +extern volatile uint8_t *g_current_regs; + +/* This is the beginning of heap as provided from processor-specific logic. + * This is the first address in RAM after the loaded program+bss+idle stack. + * The end of the heap is CONFIG_RAM_END + */ + +extern uint16_t g_idle_topstack; + +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 1 +extern uint32_t g_intstackbase; +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Start-up functions */ + +void up_boot(void); + +/* Context switching functions */ + +void up_copystate(uint8_t *dest, uint8_t *src); +void up_decodeirq(uint8_t *regs); +void up_irqinitialize(void); +int up_saveusercontext(uint8_t *saveregs); +void up_fullcontextrestore(uint8_t *restoreregs) noreturn_function; +void up_switchcontext(uint8_t *saveregs, uint8_t *restoreregs); + +/* Interrupt handling */ + +uint8_t *up_doirq(int irq, uint8_t *regs); + +/* Signal handling */ + +void up_sigdeliver(void); + +/* System timer initialization */ + +void up_timer_initialize(void); +int up_timerisr(int irq, uint32_t *regs); + +/* Debug output */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +void up_earlyserialinit(void); +void up_serialinit(void); +#else +# define up_earlyserialinit() +# define up_serialinit() +#endif + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +void up_lowputc(char ch); +void up_puts(const char *str); +void up_lowputs(const char *str); + +/* Memory configuration */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#else +# define up_addregion() +#endif + +/* Sub-system/driver initialization */ + +#ifdef CONFIG_ARCH_DMA +void weak_function up_dmainitialize(void); +#endif + +void up_wdtinit(void); + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __UP_INTERNAL_H */ diff --git a/arch/hc/src/common/up_interruptcontext.c b/arch/hc/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..62c4e1c37d9cc8c41f735ea5c6e2025cd49100a7 --- /dev/null +++ b/arch/hc/src/common/up_interruptcontext.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/hc/src/common/up_interruptcontext.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in the interrupt + * handler context. + * + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/hc/src/common/up_mdelay.c b/arch/hc/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..9472dc3d93c60ddb9442c203b719e97e73e99ebb --- /dev/null +++ b/arch/hc/src/common/up_mdelay.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/hc/src/common/up_mdelay.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/hc/src/common/up_modifyreg16.c b/arch/hc/src/common/up_modifyreg16.c new file mode 100644 index 0000000000000000000000000000000000000000..443eedf5595978f1090dea068e25f54d858e04fb --- /dev/null +++ b/arch/hc/src/common/up_modifyreg16.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/hc/src/common/up_modifyreg16.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16(addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/hc/src/common/up_modifyreg32.c b/arch/hc/src/common/up_modifyreg32.c new file mode 100644 index 0000000000000000000000000000000000000000..0768e78c7408da7bacb9f178b5cc34ebfdea5073 --- /dev/null +++ b/arch/hc/src/common/up_modifyreg32.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/hc/src/common/up_modifyreg32.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32(addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/hc/src/common/up_modifyreg8.c b/arch/hc/src/common/up_modifyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..6d37541a7c0a5c659153a517d18a02db1f6e09c1 --- /dev/null +++ b/arch/hc/src/common/up_modifyreg8.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/hc/src/common/up_modifyreg8.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8(addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/hc/src/common/up_puts.c b/arch/hc/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..6e3ae8f631721b3ddf8e1da6ce2860b94cfa3c78 --- /dev/null +++ b/arch/hc/src/common/up_puts.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/hc/src/common/up_puts.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} diff --git a/arch/hc/src/common/up_releasepending.c b/arch/hc/src/common/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..d9a209c343765022ac61114163dd75ec94336fc8 --- /dev/null +++ b/arch/hc/src/common/up_releasepending.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/hc/src/common/up_releasepending.c + * + * Copyright (C) 2010, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have collected in the pending task + * list. This can call a context switch if a new task is placed at the + * head of the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/hc/src/common/up_releasestack.c b/arch/hc/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..03d50098e12dd80ebc952bbb4d952600b22314a2 --- /dev/null +++ b/arch/hc/src/common/up_releasestack.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/hc/src/common/up_releasestack.c + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/hc/src/common/up_reprioritizertr.c b/arch/hc/src/common/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..efdde667389c5d8490a1ed9e49dd33c2955e37cd --- /dev/null +++ b/arch/hc/src/common/up_reprioritizertr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/hc/src/common/up_reprioritizertr.c + * + * Copyright (C) 2010, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/hc/src/common/up_stackframe.c b/arch/hc/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..d712bb7d3b473ef1ade1db3ffa5e602906c0dc09 --- /dev/null +++ b/arch/hc/src/common/up_stackframe.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/hc/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* The CPU12 stack should be aligned at half-word (2 byte) boundaries. If + * necessary frame_size must be rounded up to the next boundary + */ + +#define STACK_ALIGNMENT 2 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8; + tcb->xcp.regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint16_t)); +} + diff --git a/arch/hc/src/common/up_udelay.c b/arch/hc/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..d4b2d3aad87e5d56f0154b4682c12da82cc84006 --- /dev/null +++ b/arch/hc/src/common/up_udelay.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/hc/src/common/up_udelay.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} diff --git a/arch/hc/src/common/up_unblocktask.c b/arch/hc/src/common/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..c2ed818ac3092f90c73d7e605b5d6cafb5abea86 --- /dev/null +++ b/arch/hc/src/common/up_unblocktask.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/hc/src/common/up_unblocktask.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..6160e92b5eb1d2ce6cb23d393347c9c22582a7c2 --- /dev/null +++ b/arch/hc/src/common/up_usestack.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/hc/src/common/up_usestack.c + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The CPU12 uses a push-down stack: the stack grows + * toward lower addresses in memory. Because the CPU12 stack + * operates as a decrement then store stack, the value assigned + * to the initial stack pointer is one more than the last valid + * stack address. + */ + + top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + + /* The CPU12 stack should be aligned at half-word (2 byte) + * boundaries. If necessary top_of_stack must be rounded + * down to the next boundary + */ + + top_of_stack &= ~1; + size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + return OK; +} diff --git a/arch/hc/src/m9s12/Kconfig b/arch/hc/src/m9s12/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..cd70fc9814ae0e50cbdef6cbc40fa5e51e1214bd --- /dev/null +++ b/arch/hc/src/m9s12/Kconfig @@ -0,0 +1,43 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_HSC12 +comment "M9S12 Configuration Options" + +menu "M9S12 Peripheral Selection" + +config HCS12_SCI0 + bool "SCI0" + default n + select ARCH_HAVE_SCI0 + +config HCS12_SCI1 + bool "SCI1" + default n + select ARCH_HAVE_SCI1 + +endmenu # M9S12 Peripheral Selection + +menu "HSC12 Build Options" + +config HCS12_SERIALMON + bool "Freescale serial bootloader" + default n + ---help--- + Indicates that the target systems uses the Freescale serial + bootloader. + +config HCS12_NONBANKED + bool "Non-banked" + default n + ---help--- + Indicates that the target systems does not support banking. + Only short calls are made; one fixed page is presented in the + paging window. Only 48Kb of FLASH is usable in this configuration: + pages 3e, 3d, then 3f will appear as a contiguous address space + in memory. + +endmenu # HSC12 Build Options +endif # ARCH_HSC12 diff --git a/arch/hc/src/m9s12/Make.defs b/arch/hc/src/m9s12/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..809a0696c338b44501fdbf1833119c228ee295df --- /dev/null +++ b/arch/hc/src/m9s12/Make.defs @@ -0,0 +1,55 @@ +############################################################################ +# arch/arm/src/m9s12/Make.defs +# +# Copyright (C) 2009, 2011, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = m9s12_vectors.S + +CMN_ASRCS = +CMN_CSRCS = up_allocateheap.c up_blocktask.c up_copystate.c up_createstack.c +CMN_CSRCS += up_doirq.c up_exit.c up_idle.c up_initialize.c up_interruptcontext.c +CMN_CSRCS += up_mdelay.c up_modifyreg16.c up_modifyreg32.c up_modifyreg8.c +CMN_CSRCS += up_puts.c up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_stackframe.c up_udelay.c up_unblocktask.c up_usestack.c + +CHIP_ASRCS = m9s12_start.S m9s12_lowputc.S m9s12_saveusercontext.S +CHIP_CSRCS = m9s12_assert.c m9s12_gpio.c m9s12_gpioirq.c m9s12_initialstate.c +CHIP_CSRCS += m9s12_irq.c m9s12_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += m9s12_timerisr.c +endif + +ifeq ($(CONFIG_DEBUG_GPIO),y) +CHIP_CSRCS+= m9s12_dumpgpio.c +endif diff --git a/arch/hc/src/m9s12/chip.h b/arch/hc/src/m9s12/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..630a0b375ced8138492b66223ef8e82392e4801a --- /dev/null +++ b/arch/hc/src/m9s12/chip.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/hc/src/m9s12/chip.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_HC_SRC_M9S12_CHIP_H +#define __ARCH_HC_SRC_M9S12_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map. + * + * At reset: + * 0x0000–0x03ff: register space + * 0x0000–0x1fff: 7K RAM (1K RAM hidden behind register space) + */ + +#define HCS12_REG_BASE 0x0000 /* 0x0000-0x03ff: Mapped Register base address */ +#define HCS12_EEPROM_BASE 0x0800 /* 0x0800: Mapped EEPROM base address */ +#define HCS12_SRAM_BASE 0x2000 /* 0x2000-0x3fff: Mapped SRAM base address */ +#define HCS12_FFLASH1_BASE 0x4000 /* 0x4000-0x7fff: 16Kb Fixed FLASH EEPROM */ +#define HCS12_PPAGE_BASE 0x8000 /* 0x8000-0xbfff: 16Kb Page window */ +#define HCS12_FFLASH2_BASE 0xc000 /* 0xc000-0xffff: 16Kb Fixed FLASH EEPROM */ + +/* Device Register Map Overview (all relative to HCS12_REG_BASE) */ + +#define HCS12_CORE1_BASE 0x0000 /* 0x0000–0x0017: Ports A, B, E, Modes, Inits (MMC, INT, MEBI) */ + /* 0x0018–0x0019: Reserved */ +#define HCS12_DEVID_BASE 0x001a /* 0x001a-0x001b: Device ID register (PARTID) */ +#define HCS12_CORE2_BASE 0x001c /* 0x001c–0x001f: MEMSIZ, IRQ, HPRIO (INT, MMC) */ +#define HCS12_CORE3_BASE 0x0020 /* 0x0020-0x002f: DBG */ +#define HCS12_CORE4_BASE 0x0030 /* 0x0030–0x0033: PPAGE, Port K (MEBI, MMC) */ +#define HCS12_CRG_BASE 0x0034 /* 0x0034–0x003f: Clock and Reset Generator (PLL, RTI, COP) */ +#define HCS12_TIM_BASE 0x0040 /* 0x0040–0x006f: Standard Timer 16-bit 4 channels (TIM) */ + /* 0x0070–0x007f: Reserved */ +#define HCS12_ATD_BASE 0x0080 /* 0x0080–0x009f: Analog-to-Digital Converter 10-bit, 8-channel (ATD) */ + /* 0x00a0–0x00c7: Reserved */ +#define HCS12_SCI0_BASE 0x00c8 /* 0x00c8–0x00cf: Serial Communications Interface 0 (SCI0) */ +#define HCS12_SCI1_BASE 0x00d0 /* 0x00d0–0x00d7: Serial Communications Interface 1 (SCI1) */o +#define HCS12_SPI_BASE 0x00d8 /* 0x00d8–0x00df: Serial Peripheral Interface (SPI) */ +#define HCS12_IIC_BASE 0x00e0 /* 0x00e0–0x00e7: Inter IC Bus (IIC) */ + /* 0x00e8–0x00ff: Reserved */ +#define HCS12_FLASH_BASE 0x0100 /* 0x0100–0x010f: FLASH Control Register */ + /* 0x0110–0x011f: Reserved */ +#define HCS12_EPHY_BASE 0x0120 /* 0x0120–0x0123: Ethernet Physical Interface (EPHY) */ + /* 0x0124–0x013f: Reserved */ +#define HCS12_EMAC_BASE 0x0140 /* 0x0140–0x016f: Ethernet Media Access Controller (EMAC) */ + /* 0x0170–0x023f: Reserved */ +#define HCS12_PIM_BASE 0x0240 /* 0x0240–0x026f: Port Integration Module (PIM) */ + /* 0x0270–0x03ff: Reserved */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_HC_SRC_M9S12_CHIP_H */ diff --git a/arch/hc/src/m9s12/m9s12.h b/arch/hc/src/m9s12/m9s12.h new file mode 100644 index 0000000000000000000000000000000000000000..e6c98244deda20b850e49e986ba5c71a5cd5cc2f --- /dev/null +++ b/arch/hc/src/m9s12/m9s12.h @@ -0,0 +1,379 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_HC_SRC_M9S12_M9S12_H +#define __ARCH_HC_SRC_M9S12_M9S12_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* GPIO management macros: + * + * The GPIO configuration is represented by a 16-bit value encoded as follows: + * + * xIIO UURV DMGG GPPP + * ||| |||| ||| `-Pin number + * ||| |||| || `- Port number + * ||| |||| | `- PIM Ports + * ||| |||| `- Direction + * ||| |||`- Initial value of output + * ||| ||`- Reduced drive + * ||| |`- Polarity + * ||| `- Pull up (or down) + * ||`- Wired OR open drain + * |`- Interrupt or rising/falling (polarity) + * `- Interrupt + * + * NOTE: MEBI ports E and K can have special configurations as controlled by + * the PEAR and MODE registers. Those special configurations are not managed + * by the logic below; that logic is only intended to support general GPIO + * pin usage. + */ + +/* Interrupts: + * + * xIIx xxxx xxxx xxxx + * + * For PIM ports G, H, and J. NOTE: If pull up/down is also selected, then + * it must be consistent with the selected interrupt edge (because both are + * controlled by the same polarity register): + * + * Rising edge <-> Pull down + * Falling Edge <-> Pull up + * + * Selecting input also selects direction == input (it is unless to specify + * GPIO_INPUT and an error if GPIO_OUTPUT is also specified) + */ + +#define GPIO_INT_SHIFT (13) +#define GPIO_INT_MASK (3 << GPIO_PULLUP_SHIFT) +# define GPIO_INT_POLARITY (1 << GPIO_PULLUP_SHIFT) +# define GPIO_INT_ENABLE (2 << GPIO_PULLUP_SHIFT) +# define GPIO_INT_FALLING (2 << GPIO_PULLUP_SHIFT) +# define GPIO_INT_RISING (3 << GPIO_PULLUP_SHIFT) + +/* Wired OR open-drain: + * + * xxxO xxxx xxxx xxxx + * + * Only PIM ports S and L + */ + +#define GPIO_OPENDRAIN (1 << 12) + +/* Pull up (or down): + * + * xxxx UUxx xxxx xxxx + * + * For PIM ports (T,S,G,H,J,L), selection is per-pin + * For MEBI ports (A,B,E,K), selection is per-port, polarity is ignored + */ + +#define GPIO_PULLUP_SHIFT (10) +#define GPIO_PULLUP_MASK (3 << GPIO_PULLUP_SHIFT) +# define GPIO_PULL_POLARITY (1 << GPIO_PULLUP_SHIFT) +# define GPIO_PULL_ENABLE (2 << GPIO_PULLUP_SHIFT) +# define GPIO_PULLUP (2 << GPIO_PULLUP_SHIFT) +# define GPIO_PULLDOWN (3 << GPIO_PULLUP_SHIFT) + +/* Reduced drive: + * + * xxxx xxRx xxxx xxxx + * + * For PIM ports (T,S,G,H,J,L), selection is per-pin + * For MEBI ports (A,B,E,K), selection is per-port + */ + +#define GPIO_REDUCED (1 << 9) + +/* Initial value of output: + * + * xxxx xxxV xxxx xxxx + * + * For PIM ports (T,S,G,H,J,L), selection is per-pin + * For MEBI ports (A,B,E,K), selection is per-port + */ + +#define GPIO_OUTPUT_VALUE (1 << 8) +#define GPIO_OUTPUT_LOW (0) +#define GPIO_OUTPUT_HIGH GPIO_OUTPUT_VALUE + +/* Data direction (All ports -- A,B,E,K,T,S,G,H,J,L) + * + * xxxx xxxx Dxxx xxxx + * + */ + +#define GPIO_DIRECTION (1 << 7) +# define GPIO_INPUT (0) +# define GPIO_OUTPUT GPIO_DIRECTION + +/* Port selection + * + * xxxx xxxx xGGG Gxxx + * + * Ports A, B, E, and K reside in the MEBI block + * Ports T,S,G,H,J, and L reside in the PIM block. + */ + +#define GPIO_PORT_SHIFT 3 +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORT_A (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_B (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_E (2 << GPIO_PORT_SHIFT) +# define GPIO_PORT_K (3 << GPIO_PORT_SHIFT) + +# define GPIO_PORT_PIM (8 << GPIO_PORT_SHIFT) +# define GPIO_PORT_T (8 << GPIO_PORT_SHIFT) +# define GPIO_PORT_S (9 << GPIO_PORT_SHIFT +# define GPIO_PORT_G (10 << GPIO_PORT_SHIFT) +# define GPIO_PORT_H (11 << GPIO_PORT_SHIFT) +# define GPIO_PORT_J (12 << GPIO_PORT_SHIFT) +# define GPIO_PORT_L (13 << GPIO_PORT_SHIFT) + +/* Pin numbers + * + * xxxx xxxx xxxx xPPP + */ + +#define GPIO_PIN_SHIFT (0) +#define GPIO_PIN_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PIN_0 (0 << GPIO_PORT_SHIFT) +# define GPIO_PIN_1 (1 << GPIO_PORT_SHIFT) +# define GPIO_PIN_2 (2 << GPIO_PORT_SHIFT) +# define GPIO_PIN_3 (3 << GPIO_PORT_SHIFT) +# define GPIO_PIN_4 (4 << GPIO_PORT_SHIFT) +# define GPIO_PIN_5 (5 << GPIO_PORT_SHIFT) +# define GPIO_PIN_6 (6 << GPIO_PORT_SHIFT) +# define GPIO_PIN_7 (7 << GPIO_PORT_SHIFT) + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: hcs12_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +void hcs12_gpioirqinitialize(void); + +/************************************************************************************ + * Name: hcs12_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int hcs12_configgpio(uint16_t cfgset); + +/************************************************************************************ + * Name: hcs12_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void hcs12_gpiowrite(uint16_t pinset, bool value); + +/************************************************************************************ + * Name: hcs12_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool hcs12_gpioread(uint16_t pinset); + +/************************************************************************************ + * Name: hcs12_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void hcs12_gpioirqenable(int irq); +#else +# define hcs12_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: hcs12_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void hcs12_gpioirqdisable(int irq); +#else +# define hcs12_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: hcs12_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int hcs12_dumpgpio(uint16_t pinset, const char *msg); +#else +# define hcs12_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Function: hcs12_ethinitialize + * + * Description: + * Initialize the Ethernet driver for one interface. If the STM32 chip + * supports multiple Ethernet controllers, then bould specific logic + * must implement up_netinitialize() and call this function to initialize + * the desiresed interfaces. + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ************************************************************************************/ + +#if STM32_NTHERNET > 1 +int hcs12_ethinitialize(int intf); +#endif + +/**************************************************************************** + * Name: hcs12_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +FAR struct spi_dev_s *hcs12_spibus_initialize(int port); + +/************************************************************************************ + * Name: hcs12_spiselect and hcs12_spistatus + * + * Description: + * The external functions, hcs12_spiselect and hcs12_spistatus must be + * provided by board-specific logic. They are implementations of the select + * and status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including mps12_spibus_initialize()) + * are provided by common STM32 logic. To use this common SPI logic on your + * board: + * + * 1. Provide logic in hcs12_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide hcs12_spiselect() and hcs12_spistatus() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. Add a calls to mps12_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by mps12_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +void hcs12_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t hcs12_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_HC_SRC_M9S12_M9S12_H */ diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..1eab6eb4e340eb853404673bb306161d1494a1f7 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_assert.c @@ -0,0 +1,346 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_assert.c + * + * Copyright (C) 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint16_t sp, uint16_t stack_base) +{ + uint16_t stack; + + for (stack = sp; stack < stack_base; stack += 16) + { + uint8_t *ptr = (uint8_t*)stack; + lldbg("%04x: %02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], + ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]); + } +} +#else +# define up_stackdump() +#endif + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + lldbg("A:%02x B:%02x X:%02x%02x Y:%02x%02x PC:%02x%02x CCR:%02x\n", + g_current_regs[REG_A], g_current_regs[REG_B], g_current_regs[REG_XH], + g_current_regs[REG_XL], g_current_regs[REG_YH], g_current_regs[REG_YL], + g_current_regs[REG_PCH], g_current_regs[REG_PCL], g_current_regs[REG_CCR]); + lldbg("SP:%02x%02x FRAME:%02x%02x TMP:%02x%02x Z:%02x%02x XY:%02x\n", + g_current_regs[REG_SPH], g_current_regs[REG_SPL], + g_current_regs[REG_FRAMEH], g_current_regs[REG_FRAMEL], + g_current_regs[REG_TMPL], g_current_regs[REG_TMPH], g_current_regs[REG_ZL], + g_current_regs[REG_ZH], g_current_regs[REG_XY], g_current_regs[REG_XY+1]); + +#if CONFIG_HCS12_MSOFTREGS > 2 +# error "Need to save more registers" +#elif CONFIG_HCS12_MSOFTREGS == 2 + lldbg("SOFTREGS: %02x%02x :%02x%02x\n", + g_current_regs[REG_SOFTREG1], g_current_regs[REG_SOFTREG1+1], + g_current_regs[REG_SOFTREG2], g_current_regs[REG_SOFTREG2+1]); +#elif CONFIG_HCS12_MSOFTREGS == 1 + lldbg("SOFTREGS: %02x%02x\n", g_current_regs[REG_SOFTREG1], + g_current_regs[REG_SOFTREG1+1]); +#endif + +#ifndef CONFIG_HCS12_NONBANKED + lldbg("PPAGE: %02x\n", g_current_regs[REG_PPAGE],); +#endif + } +} +#else +# define up_registerdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint16_t sp = up_getsp(); + uint16_t ustackbase; + uint16_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint16_t istackbase; + uint16_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustacksize = (uint16_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint16_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + lldbg("sp: %04x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %04x\n", istackbase); + lldbg(" size: %04x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("sp: %04x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %04x\n", ustackbase); + lldbg(" size: %04x\n", ustacksize); +#else + lldbg("sp: %04x\n", sp); + lldbg("stack base: %04x\n", ustackbase); + lldbg("stack size: %04x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + up_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + up_registerdump(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || (this_task())->pid == 0) + { + (void)up_irq_save(); + for (;;) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/hc/src/m9s12/m9s12_atd.h b/arch/hc/src/m9s12/m9s12_atd.h new file mode 100644 index 0000000000000000000000000000000000000000..6c6946bceb66319ca895b49b619a25a54b64650c --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_atd.h @@ -0,0 +1,323 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_atd.h + * Defintions for ATD10b8c v3 + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_ATD_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_ATD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_ATD_CTL0_OFFSET 0x0000 /* ATD control register 0 */ +#define HCS12_ATD_CTL1_OFFSET 0x0001 /* ATD control register 1 */ +#define HCS12_ATD_CTL2_OFFSET 0x0002 /* ATD control register 2 */ +#define HCS12_ATD_CTL3_OFFSET 0x0003 /* ATD control register 3 */ +#define HCS12_ATD_CTL4_OFFSET 0x0004 /* ATD control register 4 */ +#define HCS12_ATD_CTL5_OFFSET 0x0005 /* ATD control register 5 */ +#define HCS12_ATD_STAT0_OFFSET 0x0006 /* ATD status register 0 */ +#define HCS12_ATD_TEST0_OFFSET 0x0008 /* ATD test register 0 */ +#define HCS12_ATD_TEST1_OFFSET 0x0009 /* ATD test register 1 */ +#define HCS12_ATD_STAT1_OFFSET 0x000b /* ATD status register 1 */ +#define HCS12_ATD_IEN_OFFSET 0x000d /* ATD Input enable register */ +#define HCS12_ATD_PORTAD_OFFSET 0x000f /* Port data register */ + /* Left justified data */ +#define HCS12_ATD_DLH_OFFSET(n) (0x0010+(n)) +#define HCS12_ATD_DLL_OFFSET(n) (0x0011+(n)) +#define HCS12_ATD_DL0H_OFFSET 0x0010 /* ATD conversion result register 0 (high) */ +#define HCS12_ATD_DL0L_OFFSET 0x0011 /* ATD conversion result register 0 (low) */ +#define HCS12_ATD_DL1H_OFFSET 0x0012 /* ATD conversion result register 1 (high) */ +#define HCS12_ATD_DL1L_OFFSET 0x0013 /* ATD conversion result register 1 (low) */ +#define HCS12_ATD_DL2H_OFFSET 0x0014 /* ATD conversion result register 2 (high) */ +#define HCS12_ATD_DL2L_OFFSET 0x0015 /* ATD conversion result register 2 (low) */ +#define HCS12_ATD_DL3H_OFFSET 0x0016 /* ATD conversion result register 3 (high) */ +#define HCS12_ATD_DL3L_OFFSET 0x0017 /* ATD conversion result register 3 (low) */ +#define HCS12_ATD_DL4H_OFFSET 0x0018 /* ATD conversion result register 4 (high) */ +#define HCS12_ATD_DL4L_OFFSET 0x0019 /* ATD conversion result register 4 (low) */ +#define HCS12_ATD_DL5H_OFFSET 0x001a /* ATD conversion result register 5 (high) */ +#define HCS12_ATD_DL5L_OFFSET 0x001b /* ATD conversion result register 5 (low) */ +#define HCS12_ATD_DL6H_OFFSET 0x001c /* ATD conversion result register 6 (high) */ +#define HCS12_ATD_DL6L_OFFSET 0x001d /* ATD conversion result register 6 (low) */ +#define HCS12_ATD_DL7H_OFFSET 0x001e /* ATD conversion result register 7 (high) */ +#define HCS12_ATD_DL7L_OFFSET 0x001f /* ATD conversion result register 7 (low) */ + /* Right justified data */ +#define HCS12_ATD_DRH_OFFSET(n) (0x0020+(n)) +#define HCS12_ATD_DRL_OFFSET(n) (0x0021+(n)) +#define HCS12_ATD_DR0H_OFFSET 0x0020 /* ATD conversion result register 0 (high) */ +#define HCS12_ATD_DR0L_OFFSET 0x0021 /* ATD conversion result register 0 (low) */ +#define HCS12_ATD_DR1H_OFFSET 0x0022 /* ATD conversion result register 1 (high) */ +#define HCS12_ATD_DR1L_OFFSET 0x0023 /* ATD conversion result register 1 (low) */ +#define HCS12_ATD_DR2H_OFFSET 0x0024 /* ATD conversion result register 2 (high) */ +#define HCS12_ATD_DR2L_OFFSET 0x0025 /* ATD conversion result register 2 (low) */ +#define HCS12_ATD_DR3H_OFFSET 0x0026 /* ATD conversion result register 3 (high) */ +#define HCS12_ATD_DR3L_OFFSET 0x0027 /* ATD conversion result register 3 (low) */ +#define HCS12_ATD_DR4H_OFFSET 0x0028 /* ATD conversion result register 4 (high) */ +#define HCS12_ATD_DR4L_OFFSET 0x0029 /* ATD conversion result register 4 (low) */ +#define HCS12_ATD_DR5H_OFFSET 0x002a /* ATD conversion result register 5 (high) */ +#define HCS12_ATD_DR5L_OFFSET 0x002b /* ATD conversion result register 5 (low) */ +#define HCS12_ATD_DR6H_OFFSET 0x002c /* ATD conversion result register 6 (high) */ +#define HCS12_ATD_DR6L_OFFSET 0x002d /* ATD conversion result register 6 (low) */ +#define HCS12_ATD_DR7H_OFFSET 0x002e /* ATD conversion result register 7 (high) */ +#define HCS12_ATD_DR7L_OFFSET 0x002f /* ATD conversion result register 7 (low) */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_ATD_CTL0 (HCS12_ATD_BASE+HCS12_ATD_CTL0_OFFSET) +#define HCS12_ATD_CTL1 (HCS12_ATD_BASE+HCS12_ATD_CTL1_OFFSET) +#define HCS12_ATD_CTL2 (HCS12_ATD_BASE+HCS12_ATD_CTL2_OFFSET) +#define HCS12_ATD_CTL3 (HCS12_ATD_BASE+HCS12_ATD_CTL3_OFFSET) +#define HCS12_ATD_CTL4 (HCS12_ATD_BASE+HCS12_ATD_CTL4_OFFSET) +#define HCS12_ATD_CTL5 (HCS12_ATD_BASE+HCS12_ATD_CTL5_OFFSET) +#define HCS12_ATD_STAT0 (HCS12_ATD_BASE+HCS12_ATD_STAT0_OFFSET) +#define HCS12_ATD_TEST0 (HCS12_ATD_BASE+HCS12_ATD_TEST0_OFFSET) +#define HCS12_ATD_TEST1 (HCS12_ATD_BASE+HCS12_ATD_TEST1_OFFSET) +#define HCS12_ATD_STAT1 (HCS12_ATD_BASE+HCS12_ATD_STAT1_OFFSET) +#define HCS12_ATD_IEN (HCS12_ATD_BASE+HCS12_ATD_IEN_OFFSET) +#define HCS12_ATD_PORTAD (HCS12_ATD_BASE+HCS12_ATD_PORTAD_OFFSET) +#define HCS12_ATD_DLH(n) (HCS12_ATD_BASE+HCS12_ATD_DLH_OFFSET(n)) +#define HCS12_ATD_DLL(n) (HCS12_ATD_BASE+HCS12_ATD_DLL_OFFSET(n)) +#define HCS12_ATD_DL0H (HCS12_ATD_BASE+HCS12_ATD_DL0H_OFFSET) +#define HCS12_ATD_DL0L (HCS12_ATD_BASE+HCS12_ATD_DL0L_OFFSET) +#define HCS12_ATD_DL1H (HCS12_ATD_BASE+HCS12_ATD_DL1H_OFFSET) +#define HCS12_ATD_DL1L (HCS12_ATD_BASE+HCS12_ATD_DL1L_OFFSET) +#define HCS12_ATD_DL2H (HCS12_ATD_BASE+HCS12_ATD_DL2H_OFFSET) +#define HCS12_ATD_DL2L (HCS12_ATD_BASE+HCS12_ATD_DL2L_OFFSET) +#define HCS12_ATD_DL3H (HCS12_ATD_BASE+HCS12_ATD_DL3H_OFFSET) +#define HCS12_ATD_DL3L (HCS12_ATD_BASE+HCS12_ATD_DL3L_OFFSET) +#define HCS12_ATD_DL4H (HCS12_ATD_BASE+HCS12_ATD_DL4H_OFFSET) +#define HCS12_ATD_DL4L (HCS12_ATD_BASE+HCS12_ATD_DL4L_OFFSET) +#define HCS12_ATD_DL5H (HCS12_ATD_BASE+HCS12_ATD_DL5H_OFFSET) +#define HCS12_ATD_DL5L (HCS12_ATD_BASE+HCS12_ATD_DL5L_OFFSET) +#define HCS12_ATD_DL6H (HCS12_ATD_BASE+HCS12_ATD_DL6H_OFFSET) +#define HCS12_ATD_DL6L (HCS12_ATD_BASE+HCS12_ATD_DL6L_OFFSET) +#define HCS12_ATD_DL7H (HCS12_ATD_BASE+HCS12_ATD_DL7H_OFFSET) +#define HCS12_ATD_DL7L (HCS12_ATD_BASE+HCS12_ATD_DL7L_OFFSET) +#define HCS12_ATD_DRH(n) (HCS12_ATD_BASE+HCS12_ATD_DRH_OFFSET(n)) +#define HCS12_ATD_DRL(n) (HCS12_ATD_BASE+HCS12_ATD_DRL_OFFSET(n)) +#define HCS12_ATD_DR0H (HCS12_ATD_BASE+HCS12_ATD_DR0H_OFFSET) +#define HCS12_ATD_DR0L (HCS12_ATD_BASE+HCS12_ATD_DR0L_OFFSET) +#define HCS12_ATD_DR1H (HCS12_ATD_BASE+HCS12_ATD_DR1H_OFFSET) +#define HCS12_ATD_DR1L (HCS12_ATD_BASE+HCS12_ATD_DR1L_OFFSET) +#define HCS12_ATD_DR2H (HCS12_ATD_BASE+HCS12_ATD_DR2H_OFFSET) +#define HCS12_ATD_DR2L (HCS12_ATD_BASE+HCS12_ATD_DR2L_OFFSET) +#define HCS12_ATD_DR3H (HCS12_ATD_BASE+HCS12_ATD_DR3H_OFFSET) +#define HCS12_ATD_DR3L (HCS12_ATD_BASE+HCS12_ATD_DR3L_OFFSET) +#define HCS12_ATD_DR4H (HCS12_ATD_BASE+HCS12_ATD_DR4H_OFFSET) +#define HCS12_ATD_DR4L (HCS12_ATD_BASE+HCS12_ATD_DR4L_OFFSET) +#define HCS12_ATD_DR5H (HCS12_ATD_BASE+HCS12_ATD_DR5H_OFFSET) +#define HCS12_ATD_DR5L (HCS12_ATD_BASE+HCS12_ATD_DR5L_OFFSET) +#define HCS12_ATD_DR6H (HCS12_ATD_BASE+HCS12_ATD_DR6H_OFFSET) +#define HCS12_ATD_DR6L (HCS12_ATD_BASE+HCS12_ATD_DR6L_OFFSET) +#define HCS12_ATD_DR7H (HCS12_ATD_BASE+HCS12_ATD_DR7H_OFFSET) +#define HCS12_ATD_DR7L (HCS12_ATD_BASE+HCS12_ATD_DR7L_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* ATD control register 0 */ + +#define ATD_CTL0_WRAP_SHIFT (0) /* Bits 0-2: Wrap around channel select */ +#define ATD_CTL0_WRAP_MASK (7) +# define ATD_CTL0_WRAP_AN(n) (n) +# define ATD_CTL0_WRAP_AN1 (1) +# define ATD_CTL0_WRAP_AN2 (2) +# define ATD_CTL0_WRAP_AN3 (3) +# define ATD_CTL0_WRAP_AN4 (4) +# define ATD_CTL0_WRAP_AN5 (5) +# define ATD_CTL0_WRAP_AN6 (6) +# define ATD_CTL0_WRAP_AN7 (7) + +/* ATD control register 1 */ + +#define ATD_CTL1_ETRIGCH_SHIFT (0) /* Bits 0-2: External channel select */ +#define ATD_CTL1_ETRIGCH_MASK (7) +# define ATD_CTL2_ETRIGCH_AN(n) (n) +# define ATD_CTL2_ETRIGCH_AN0 (0) +# define ATD_CTL2_ETRIGCH_AN1 (1) +# define ATD_CTL2_ETRIGCH_AN2 (2) +# define ATD_CTL2_ETRIGCH_AN3 (3) +# define ATD_CTL2_ETRIGCH_AN4 (4) +# define ATD_CTL2_ETRIGCH_AN5 (5) +# define ATD_CTL2_ETRIGCH_AN6 (6) +# define ATD_CTL2_ETRIGCH_AN7 (7) +# define ATD_CTL2_ETRIGCH_ETRIG(n) (n) +# define ATD_CTL2_ETRIGCH_ETRIG0 (0) +# define ATD_CTL2_ETRIGCH_ETRIG1 (1) +# define ATD_CTL2_ETRIGCH_ETRIG2 (2) +# define ATD_CTL2_ETRIGCH_ETRIG3 (3) +#define ATD_CTL1_ETRIGSEL (1 << 7) /* Bit 7: External trigger source select */ + +/* ATD control register 2 */ + +#define ATD_CTL2_ASCIF (1 << 0) /* Bit 0: ATD Sequence Complete Interrup */ +#define ATD_CTL2_ASCIE (1 << 1) /* Bit 1: ATD Sequence Complete Interrupt Enable */ +#define ATD_CTL2_ETRIG (1 << 1) /* Bit 2: External Trigger Mode Enable */ +#define ATD_CTL2_ETRIG_SHIFT (3) /* Bits 3-4: External Trigger Mode */ +#define ATD_CTL2_ETRIG_MASK (0 << ATD_CTL2_ETRIG_SHIFT) +# define ATD_CTL2_ETRIG_FALLING (0 << ATD_CTL2_ETRIG_SHIFT) +# define ATD_CTL2_ETRIG_RISING (1 << ATD_CTL2_ETRIG_SHIFT) +# define ATD_CTL2_ETRIG_LOW (2 << ATD_CTL2_ETRIG_SHIFT) +# define ATD_CTL2_ETRIG_HIGH (3 << ATD_CTL2_ETRIG_SHIFT) +#define ATD_CTL2_AWAI (1 << 5) /* Bit 5: ATD Power Down inWait Mode */ +#define ATD_CTL2_AFFC (1 << 6) /* Bit 6: ATD Fast Flag Clear All */ +#define ATD_CTL2_ADPU (1 << 7) /* Bit 7: ATD Power Up */ + +/* ATD control register 3 */ + +#define ATD_CTL3_FRZ_SHIFT (0) /* Bits 0-1: Background Debug Freeze Enable */ +#define ATD_CTL3_FRZ_MASK (3) +# define ATD_CTL3_FRZ_CONTINUE (0) /* Continue conversion */ +# define ATD_CTL3_FRZ_FINISH (2) /* Finish current conversion, then freeze */ +# define ATD_CTL3_FRZ_IMMEDIATE (3) /* Freeze Immediately */ +#define ATD_CTL3_FIFO (1 << 2) /* Bit 2: Result Register FIFO Mode */ +#define ATD_CTL3_SC_SHIFT (3) /* Bits 3-6: Conversion Sequence Length */ +#define ATD_CTL3_SC_MASK (15 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC(n) ((n) << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC1 (1 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC2 (2 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC3 (3 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC4 (4 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC5 (5 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC6 (6 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC7 (7 << ATD_CTL3_SC_SHIFT) +# define ATD_CTL3_SC8 (8 << ATD_CTL3_SC_SHIFT) + +/* ATD control register 4 */ + +#define ATD_CTL4_PRS_SHIFT (0) /* Bits 0-4: ATD Clock Prescaler */ +#define ATD_CTL4_PRS_MASK (31 << ATD_CTL4_PRS_SHIFT) +# define ATD_CTL4_PRS_DIV(n) ((((n)-2) >> 1) << ATD_CTL4_PRS_SHIFT) /* Divide by n={2,4,6,...,64} */ +#define ATD_CTL4_SMP_SHIFT (5) /* Bits 5-6: Sample Time Select */ +#define ATD_CTL4_SMP_MASK (3 << ATD_CTL4_SMP_SHIFT) +# define ATD_CTL4_SMP2 (0 << ATD_CTL4_SMP_SHIFT) /* 2 A/D conversion clock periods */ +# define ATD_CTL4_SMP4 (1 << ATD_CTL4_SMP_SHIFT) /* 4 A/D conversion clock periods */ +# define ATD_CTL4_SMP8 (2 << ATD_CTL4_SMP_SHIFT) /* 8 A/D conversion clock periods */ +# define ATD_CTL4_SMP16 (3 << ATD_CTL4_SMP_SHIFT) /* 16 A/D conversion clock periods */ +#define ATD_CTL4_SRES8 (1 << 7) /* Bit 7: A/D Resolution Select */ + +/* ATD control register 5 */ + +#define ATD_CTL5_C_SHIFT (0) /* Bits 0-2: Analog Input Channel Select Code */ +#define ATD_CTL5_C_MASK (7 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN(n) ((n) << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN0 (0 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN1 (1 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN2 (2 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN3 (3 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN4 (4 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN5 (5 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN6 (6 << ATD_CTL5_C_SHIFT) +# define ATD_CTL5_C_AN7 (7 << ATD_CTL5_C_SHIFT) +#define ATD_CTL5_MULT (1 << 4) /* Bit 4: Multi-Channel Sample Mode */ +#define ATD_CTL5_SCAN (1 << 5) /* Bit 5: Continuous Conversion Sequence Mode */ +#define ATD_CTL5_DSGN (1 << 6) /* Bit 6: Result Register Data Signed or Unsigned Representation */ +#define ATD_CTL5_DJM (1 << 7) /* Bit 7: Result Register Data Justification */ + +/* ATD status register 0 */ + +#define ATD_STAT0_CC_SHIFT (0) /* Bits 0-2: Conversion counter */ +#define ATD_STAT0_CC_MASK (7) +#define ATD_STAT0_FIFOR (1 << 4) /* Bit 4: FIFO Over Run Flag */ +#define ATD_STAT0_ETORF (1 << 5) /* Bit 5: External Trigger Overrun Flag */ +#define ATD_STAT0_SCF (1 << 7) /* Bit 7: Sequence Complete Flag */ + +/* ATD test register 0 -- 8 MS bits of data written in special mode */ +/* ATD test register 1 */ + +#define ATD_TEST1_SC (1 << 0) /* Bit 0: Enable special conversions */ +#define ATD_TEST1_LSU_MASK 0xc0 /* Bits 6-7: 2 LS bits of special mode data */ + +/* ATD status register 1 */ + +#define ATD_STAT1_CCF(n) (1 << (n)) /* Bit n: Conversion complete flag channel n */ +#define ATD_STAT1_CCF0 (1 << 0) /* Bit 0: Conversion complete flag channel 0 */ +#define ATD_STAT1_CCF1 (1 << 1) /* Bit 1: Conversion complete flag channel 1 */ +#define ATD_STAT1_CCF2 (1 << 2) /* Bit 2: Conversion complete flag channel 2 */ +#define ATD_STAT1_CCF3 (1 << 3) /* Bit 3: Conversion complete flag channel 3 */ +#define ATD_STAT1_CCF4 (1 << 4) /* Bit 4: Conversion complete flag channel 4 */ +#define ATD_STAT1_CCF5 (1 << 5) /* Bit 5: Conversion complete flag channel 5 */ +#define ATD_STAT1_CCF6 (1 << 6) /* Bit 6: Conversion complete flag channel 6 */ +#define ATD_STAT1_CCF7 (1 << 7) /* Bit 7: Conversion complete flag channel 7 */ + +/* ATD Input enable register */ + +#define ATD_IEN(n) (1 << (n)) /* Bit n: ATD Digital Input Enable on channel n */ +#define ATD_IEN0 (1 << 0) /* Bit 0: ATD Digital Input Enable on channel 0 */ +#define ATD_IEN1 (1 << 1) /* Bit 1: ATD Digital Input Enable on channel 1 */ +#define ATD_IEN2 (1 << 2) /* Bit 2: ATD Digital Input Enable on channel 2 */ +#define ATD_IEN3 (1 << 3) /* Bit 3: ATD Digital Input Enable on channel 3 */ +#define ATD_IEN4 (1 << 4) /* Bit 4: ATD Digital Input Enable on channel 4 */ +#define ATD_IEN5 (1 << 5) /* Bit 5: ATD Digital Input Enable on channel 5 */ +#define ATD_IEN6 (1 << 6) /* Bit 6: ATD Digital Input Enable on channel 6 */ +#define ATD_IEN7 (1 << 7) /* Bit 7: ATD Digital Input Enable on channel 7 */ + +/* Port data register */ + +#define ATD_PORTAD(n) (1 << (n)) /* Bit n: A/D Channel n (ANn) Digital Input */ +#define ATD_PORTAD0 (1 << 0) /* Bit 0: A/D Channel 0 (AN0) Digital Input */ +#define ATD_PORTAD1 (1 << 1) /* Bit 1: A/D Channel 1 (AN1) Digital Input */ +#define ATD_PORTAD2 (1 << 2) /* Bit 2: A/D Channel 2 (AN2) Digital Input */ +#define ATD_PORTAD3 (1 << 3) /* Bit 3: A/D Channel 3 (AN3) Digital Input */ +#define ATD_PORTAD4 (1 << 4) /* Bit 4: A/D Channel 4 (AN4) Digital Input */ +#define ATD_PORTAD5 (1 << 5) /* Bit 5: A/D Channel 5 (AN5) Digital Input */ +#define ATD_PORTAD6 (1 << 6) /* Bit 6: A/D Channel 6 (AN6) Digital Input */ +#define ATD_PORTAD7 (1 << 7) /* Bit 7: A/D Channel 7 (AN7) Digital Input */ + +/* ATD conversion result register 0-7 (high/l;ow) */ + +#define ATD_DLL_MASK 0xc0 /* Bits 6-7: LS bits of left justified data */ +#define ATD_DRH_MASK 0x03 /* Bits 0-1: MS bits of right justified data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_ATD_H */ diff --git a/arch/hc/src/m9s12/m9s12_crg.h b/arch/hc/src/m9s12/m9s12_crg.h new file mode 100644 index 0000000000000000000000000000000000000000..ca166bde9e0fed5040af3707d206d6eb77cfd218 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_crg.h @@ -0,0 +1,140 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_crg.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_CRG_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_CRG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* CRG Module Register Offsets */ + +#define HCS12_CRG_SYNR_OFFSET (HCS12_CRG_BASE+0x00) /* CRG Synthesizer Register */ +#define HCS12_CRG_REFDV_OFFSET (HCS12_CRG_BASE+0x01) /* CRG Reference Divider Register */ +#define HCS12_CRG_CTFLG_OFFSET (HCS12_CRG_BASE+0x02) /* CRG Test Flags Register */ +#define HCS12_CRG_CRGFLG_OFFSET (HCS12_CRG_BASE+0x03) /* CRG Flags Register */ +#define HCS12_CRG_CRGINT_OFFSET (HCS12_CRG_BASE+0x04) /* CRG Interrupt Enable Register */ +#define HCS12_CRG_CLKSEL_OFFSET (HCS12_CRG_BASE+0x05) /* CRG Clock Select Register */ +#define HCS12_CRG_PLLCTL_OFFSET (HCS12_CRG_BASE+0x06) /* CRG PLL Control Register */ +#define HCS12_CRG_RTICTL_OFFSET (HCS12_CRG_BASE+0x07) /* CRG RTI Control Register */ +#define HCS12_CRG_COPCTL_OFFSET (HCS12_CRG_BASE+0x08) /* CRG COP Control Register */ +#define HCS12_CRG_FORBYP_OFFSET (HCS12_CRG_BASE+0x09) /* CRG Force and Bypass Test Register */ +#define HCS12_CRG_CTCTL_OFFSET (HCS12_CRG_BASE+0x0a) /* CRG Test Control Register */ +#define HCS12_CRG_ARMCOP_OFFSET (HCS12_CRG_BASE+0x0b) /* CRG COP Arm/Timer Reset */ + +/* CRG Module Register Addresses */ + +#define HCS12_CRG_SYNR (HCS12_REG_BASE+HCS12_CRG_SYNR_OFFSET) +#define HCS12_CRG_REFDV (HCS12_REG_BASE+HCS12_CRG_REFDV_OFFSET) +#define HCS12_CRG_CTFLG (HCS12_REG_BASE+HCS12_CRG_CTFLG_OFFSET) +#define HCS12_CRG_CRGFLG (HCS12_REG_BASE+HCS12_CRG_CRGFLG_OFFSET) +#define HCS12_CRG_CRGINT (HCS12_REG_BASE+HCS12_CRG_CRGINT_OFFSET) +#define HCS12_CRG_CLKSEL (HCS12_REG_BASE+HCS12_CRG_CLKSEL_OFFSET) +#define HCS12_CRG_PLLCTL (HCS12_REG_BASE+HCS12_CRG_PLLCTL_OFFSET) +#define HCS12_CRG_RTICTL (HCS12_REG_BASE+HCS12_CRG_RTICTL_OFFSET) +#define HCS12_CRG_COPCTL (HCS12_REG_BASE+HCS12_CRG_COPCTL_OFFSET) +#define HCS12_CRG_FORBYP (HCS12_REG_BASE+HCS12_CRG_FORBYP_OFFSET) +#define HCS12_CRG_CTCTL (HCS12_REG_BASE+HCS12_CRG_CTCTL_OFFSET) +#define HCS12_CRG_ARMCOP (HCS12_REG_BASE+HCS12_CRG_ARMCOP_OFFSET) + +/* CRG Module Register Bit Definitions */ + +#define CRG_SYNR_SHIFT (0) /* Bits 0-5: CRG synthesizer value */ +#define CRG_SYNR_MASK (0x3f << CRG_SYNR_SHIFT) + +#define CRG_REFDV_SHIFT (0) /* Bit 0-3: Reference divider */ +#define CRG_REFDV_MASK (15 << CRG_REFDV_SHIFT) + +#define CRG_CRGFLG_SCM (1 << 0) /* Bit 0: Self-Clock Mode Status Bit */ +#define CRG_CRGFLG_SCMIF (1 << 1) /* Bit 1: Self-Clock Mode Interrupt Flag */ +#define CRG_CRGFLG_TRACK (1 << 2) /* Bit 2: Track Status Bit */ +#define CRG_CRGFLG_LOCK (1 << 3) /* Bit 3: Lock Status Bit */ +#define CRG_CRGFLG_LOCKIF (1 << 4) /* Bit 4: PLL Lock Interrupt Flag */ +#define CRG_CRGFLG_LVRF (1 << 5) /* Bit 5: Low Voltage Reset Flag */ +#define CRG_CRGFLG_PORF (1 << 6) /* Bit 6: Power-on Reset Flag */ +#define CRG_CRGFLG_RTIF (1 << 7) /* Bit 7: Real-Time Interrupt Flag */ + +#define CRG_CRGINT_SCMIE (1 << 1) /* Bit 1: Self-Clock Mode Status Bit */ +#define CRG_CRGINT_LOCKIE (1 << 4) /* Bit 4: Lock Interrupt Enable Bit */ +#define CRG_CRGINT_RTIE (1 << 7) /* Bit 7: Lock Interrupt Enable Bit */ + +#define CRG_CLKSEL_COPWAI (1 << 0) /* Bit 0: COP stops in Wait Mode Bit */ +#define CRG_CLKSEL_RTIWAI (1 << 1) /* Bit 1: RTI stops in Wait Mode Bit */ +#define CRG_CLKSEL_CWAI (1 << 2) /* Bit 2: Core stops in Wait Mode Bit */ +#define CRG_CLKSEL_PLLWAI (1 << 3) /* Bit 3: PLL stops in Wait Mode Bit */ +#define CRG_CLKSEL_ROAWAI (1 << 4) /* Bit 4: Reduced Oscillator Amplitude in Wait Mode Bit */ +#define CRG_CLKSEL_SYSWAI (1 << 5) /* Bit 5: System clocks stop in wait mode bit */ +#define CRG_CLKSEL_PSTP (1 << 6) /* Bit 6: Pseudo-Stop Bit */ +#define CRG_CLKSEL_PLLSEL (1 << 7) /* Bit 7: PLL Select Bit */ + +#define CRG_PLLCTL_SCME (1 << 0) /* Bit 0: Self-Clock Mode Enable Bit */ +#define CRG_PLLCTL_PCE (1 << 1) /* Bit 1: COP Enable during Pseudo-Stop Bit */ +#define CRG_PLLCTL_PRE (1 << 2) /* Bit 2: RTI Enable during Pseudo-Stop Bit */ +#define CRG_PLLCTL_ACQ (1 << 4) /* Bit 4: Acquisition Bit */ +#define CRG_PLLCTL_AUTO (1 << 5) /* Bit 5: Automatic Bandwidth Control Bit */ +#define CRG_PLLCTL_PLLON (1 << 6) /* Bit 6: Phase Lock Loop On Bit */ +#define CRG_PLLCTL_CME (1 << 7) /* Bit 7: Clock Monitor Enable Bit */ + +#define CRG_RTICTL_MODCNT_SHIFT (0) /* Bits 0-3: Real-Time Interrupt Modulus Counter Select Bits */ +#define CRG_RTICTL_MODCNT_MASK (15 << CRG_RTICTL_MODCNT_SHIFT) +#define CRG_RTICTL_PRER_SHIFT (4) /* Bits 4-6: Real-Time Interrupt Prescale Rate Select Bits */ +#define CRG_RTICTL_PRER_MASK (7 << CRG_RTICTL_PRE_SHIFT) + +#define CRG_COPCTL_CR_SHIFT (0) /* Bits 0-2: COP Watchdog Timer Rate select */ +#define CRG_COPCTL_CR_MASK (7 << CRG_COPCTL_CR_SHIFT) +#define CRG_COPCTL_RSBCK (1 << 6) /* Bit 6: COP and RTI stop in Active BDM mode B */ +#define CRG_COPCTL_WCOP (1 << 7) /* Bit 7: Window COP Mode Bit */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_CRG_H */ diff --git a/arch/hc/src/m9s12/m9s12_dumpgpio.c b/arch/hc/src/m9s12/m9s12_dumpgpio.c new file mode 100644 index 0000000000000000000000000000000000000000..db4261256ba2ca623b2a7dae76dab0dd62c7edcd --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_dumpgpio.c @@ -0,0 +1,287 @@ +/**************************************************************************** + * arch/arm/src/m9s12/m9s12_dumpgpio.c + * arch/arm/src/chip/m9s12_dumpgpio.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" +#include "m9s12.h" +#include "m9s12_pim.h" +#include "m9s12_mebi.h" + +#ifdef CONFIG_DEBUG_GPIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* PIM ports (T,S,G,H,J,L) */ + +#define HCS12_PIM_NPORTS 6 + +/* MEBI ports (A,B,E,K) */ + +#define HCS12_MEBI_NPORTS 4 + +/* Decoding helper macros */ + +#define HCS12_PIN(cfg) (((cfg) & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT) +#define HCS12_PORTNDX(cfg) (((cfg) >> GPIO_PORT_SHIFT) & 7) +#define HCS12_PIMPORT(cfg) (((cfg) & GPIO_PORT_PIM) != 0) +#define HCS12_MEBIPORT(cfg) (((cfg) & GPIO_PORT_PIM) == 0) + +#define HCS12_PULL(cfg) (((cfg) & GPIO_PULLUP_MASK) >> GPIO_PULLUP_SHIFT) +# define HCS12_PULL_NONE 0 +# define HCS12_PULL_POLARITY 1 +# define HCS12_PULL_ENABLE 2 +# define HCS12_PULL_UP 2 +# define HCS12_PULL_DOWN 3 + +#define HCS12_INTERRUPT(cfg) (((cfg) & GPIO_INT_MASK) >> GPIO_INT_SHIFT) +# define HCS12_INT_NONE 0 +# define HCS12_INT_POLARITY 1 +# define HCS12_INT_ENABLE 2 +# define HCS12_INT_FALLING 2 +# define HCS12_INT_RISING 3 + +/* PIM ports have the following forms: + * + * FORM 1: IO INPUT DDR RDR PER PS Port T + * FORM 2: IO INPUT DDR RDR PER PS WOM Port S,L + * FORM 3: IO INPUT DDR RDR PER PS IE IF Port G,H,J + */ + +#define PIMPORT_FORM1 0 +#define PIMPORT_FORM2 1 +#define PIMPORT_FORM3 2 + +/* MEBI ports are pretty strange. Most look the same, but E and K can have + * some special attributes. + */ + +#define MEBIPORT_AB 0 +#define MEBIPORT_E 1 +#define MEBIPORT_K 2 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct gpio_piminfo_s +{ + uint16_t base; /* PIM GPIO block base address */ + char name; /* Port name */ + uint8_t form; /* Form of the PIM GPIO block registers */ +}; + +struct gpio_mebiinfo_s +{ + uint16_t data; /* MEBI data register address */ + uint16_t ddr; /* MEBI ddr register address */ + char name; /* Port name */ + uint8_t form; /* Form of the MEBI port */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +static const struct gpio_piminfo_s piminfo[HCS12_PIM_NPORTS] = +{ + {HCS12_PIM_PORTT_BASE, 'T', PIMPORT_FORM1}, /* Port T */ + {HCS12_PIM_PORTS_BASE, 'S', PIMPORT_FORM2}, /* Port S */ + {HCS12_PIM_PORTG_BASE, 'G', PIMPORT_FORM3}, /* Port G */ + {HCS12_PIM_PORTH_BASE, 'H', PIMPORT_FORM3}, /* Port H */ + {HCS12_PIM_PORTJ_BASE, 'J', PIMPORT_FORM3}, /* Port J */ + {HCS12_PIM_PORTL_BASE, 'L', PIMPORT_FORM2} /* Port L */ +}; + +static const struct gpio_mebiinfo_s mebiinfo[HCS12_MEBI_NPORTS] = +{ + {HCS12_MEBI_PORTA, HCS12_MEBI_DDRA, 'A', MEBIPORT_AB}, /* Port A */ + {HCS12_MEBI_PORTB, HCS12_MEBI_DDRB, 'B', MEBIPORT_AB}, /* Port B */ + {HCS12_MEBI_PORTE, HCS12_MEBI_DDRE, 'E', MEBIPORT_E}, /* Port E */ + {HCS12_MEBI_PORTK, HCS12_MEBI_DDRK, 'K', MEBIPORT_K} /* Port K */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hcs12_pimdump + * + * Description: + * PIM GPIO register block dump + * + ****************************************************************************/ + +static inline void hcs12_pimdump(uint8_t portndx) +{ + const struct gpio_piminfo_s *ptr; + + if (portndx >= HCS12_PIM_NPORTS) + { + lldbg(" Illegal PIM port index: %d\n", portndx); + return; + } + + ptr = &piminfo[portndx]; + lldbg(" PIM Port%c:\n", ptr->name); + lldbg(" IO:%02x INP:%02x DDR:%02x RDR:%02x\n", + getreg8(ptr->base+HCS12_PIM_IO_OFFSET), + getreg8(ptr->base+HCS12_PIM_INPUT_OFFSET), + getreg8(ptr->base+HCS12_PIM_DDR_OFFSET), + getreg8(ptr->base+HCS12_PIM_RDR_OFFSET)); + + switch (ptr->form) + { + case PIMPORT_FORM1: + lldbg(" PER:%02x PS:%02x\n", + getreg8(ptr->base+HCS12_PIM_PER_OFFSET), + getreg8(ptr->base+HCS12_PIM_PS_OFFSET)); + break; + + case PIMPORT_FORM2: + lldbg(" PER:%02x PS:%02x WOM:%02x\n", + getreg8(ptr->base+HCS12_PIM_PER_OFFSET), + getreg8(ptr->base+HCS12_PIM_PS_OFFSET), + getreg8(ptr->base+HCS12_PIM_WOM_OFFSET)); + break; + + case PIMPORT_FORM3: + lldbg(" PER:%02x PS:%02x IE:%02x IF:%02x\n", + getreg8(ptr->base+HCS12_PIM_PER_OFFSET), + getreg8(ptr->base+HCS12_PIM_PS_OFFSET), + getreg8(ptr->base+HCS12_PIM_IE_OFFSET), + getreg8(ptr->base+HCS12_PIM_IF_OFFSET)); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: hcs12_mebidump + * + * Description: + * PIM GPIO register block dump + * + ****************************************************************************/ + +static inline void hcs12_mebidump(uint8_t portndx) +{ + const struct gpio_mebiinfo_s *ptr; + + if (portndx >= HCS12_MEBI_NPORTS) + { + lldbg(" Illegal MEBI port index: %d\n", portndx); + return; + } + + ptr = &mebiinfo[portndx]; + lldbg(" MEBI Port%c:\n", ptr->name); + + switch (ptr->form) + { + case MEBIPORT_AB: + lldbg(" DATA:%02x DDR:%02x\n", + getreg8(ptr->data), getreg8(ptr->ddr)); + break; + + case MEBIPORT_E: + lldbg(" DATA:%02x DDR:%02x MODE:%02x PEAR:%02x\n", + getreg8(ptr->data), getreg8(ptr->ddr), + getreg8(HCS12_MEBI_MODE), getreg8(HCS12_MEBI_PEAR)); + break; + + case MEBIPORT_K: + lldbg(" DATA:%02x DDR:%02x MODE:%02x\n", + getreg8(ptr->data), getreg8(ptr->ddr), + getreg8(HCS12_MEBI_MODE)); + break; + + default: + break; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Function: hcs12_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +int hcs12_dumpgpio(uint16_t pinset, const char *msg) +{ + uint8_t portndx = HCS12_PORTNDX(pinset); + irqstate_t flags = enter_critical_section(); + + lldbg("pinset: %08x -- %s\n", pinset, msg); + + if (HCS12_PIMPORT(pinset)) + { + hcs12_pimdump(portndx); + } + else + { + hcs12_mebidump(portndx); + } + + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_DEBUG_GPIO */ + diff --git a/arch/hc/src/m9s12/m9s12_emac.h b/arch/hc/src/m9s12/m9s12_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..ad2637d39c033b5ffd1ca15864a89a650ccefc2a --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_emac.h @@ -0,0 +1,248 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_emac.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_EMAC_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_EMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_EMAC_NETCTL_OFFSET 0x0000 /* Network Control (8-bit) */ +#define HCS12_EMAC_RXCTS_OFFSET 0x0003 /* Receive Control and Status (8-bit) */ +#define HCS12_EMAC_TXCTS_OFFSET 0x0004 /* Transmit Control and Status (8-bit) */ +#define HCS12_EMAC_ETCTL_OFFSET 0x0005 /* Ethertype Control (8-bit) */ +#define HCS12_EMAC_ETYPE_OFFSET 0x0006 /* Programmable Ethertype (16-bit) */ +#define HCS12_EMAC_PTIME_OFFSET 0x0008 /* PAUSE Timer Value and Counter (16-bit) */ +#define HCS12_EMAC_IEVENT_OFFSET 0x000a /* Interrupt Event (16-bit) */ +#define HCS12_EMAC_IMASK_OFFSET 0x000c /* Interrupt Mask (16-bit) */ +#define HCS12_EMAC_SWRST_OFFSET 0x000e /* Software Reset (8-bit) */ +#define HCS12_EMAC_MPADR_OFFSET 0x0010 /* MII Management PHY Address (8-bit) */ +#define HCS12_EMAC_MRADR_OFFSET 0x0011 /* MII Management Register Address (8-bit) */ +#define HCS12_EMAC_MWDATA_OFFSET 0x0012 /* MII Management Write Data (16-bit) */ +#define HCS12_EMAC_MRDATA_OFFSET 0x0014 /* MII Management Read Data (16-bit) */ +#define HCS12_EMAC_MCMST_OFFSET 0x0016 /* MII Management Command and Status (8-bit) */ +#define HCS12_EMAC_BUFCFG_OFFSET 0x0018 /* Ethernet Buffer Configuration (16-bit) */ +#define HCS12_EMAC_RXAEFP_OFFSET 0x001a /* Receive A End-of-Frame Pointer (16-bit) */ +#define HCS12_EMAC_RXBEFP_OFFSET 0x001c /* Receive B End-of-Frame Pointer (16-bit) */ +#define HCS12_EMAC_TXEFP_OFFSET 0x001e /* Transmit End-of-Frame Pointer (16-bit) */ +#define HCS12_EMAC_MCHASH48_OFFSET 0x0020 /* Multicast Hash Table 48-63 (16-bit) */ +#define HCS12_EMAC_MCHASH32_OFFSET 0x0022 /* Multicast Hash Table 32-47 (16-bit) */ +#define HCS12_EMAC_MCHASH16_OFFSET 0x0024 /* Multicast Hash Table 16-31 (16-bit) */ +#define HCS12_EMAC_MCHASH0_OFFSET 0x0026 /* Multicast Hash Table 0:15 (16-bit) */ +#define HCS12_EMAC_MACAD32_OFFSET 0x0028 /* MAC Unicast AAddress 32-47 (16-bit) */ +#define HCS12_EMAC_MACAD16_OFFSET 0x002a /* MAC Unicast AAddress 16-31 (16-bit) */ +#define HCS12_EMAC_MACAD0_OFFSET 0x002c /* MAC Unicast AAddress 0-15 (16-bit) */ +#define HCS12_EMAC_EMISC _OFFSET 0x002e /* Miscellaneous (16-bit) */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_EMAC_NETCTL (HCS12_EMAC_BASE+HCS12_EMAC_NETCTL_OFFSET) +#define HCS12_EMAC_RXCTS (HCS12_EMAC_BASE+HCS12_EMAC_RXCTS_OFFSET) +#define HCS12_EMAC_TXCTS (HCS12_EMAC_BASE+HCS12_EMAC_TXCTS_OFFSET) +#define HCS12_EMAC_ETCTL (HCS12_EMAC_BASE+HCS12_EMAC_ETCTL_OFFSET) +#define HCS12_EMAC_ETYPE (HCS12_EMAC_BASE+HCS12_EMAC_ETYPE_OFFSET) +#define HCS12_EMAC_PTIME (HCS12_EMAC_BASE+HCS12_EMAC_PTIME_OFFSET) +#define HCS12_EMAC_IEVENT (HCS12_EMAC_BASE+HCS12_EMAC_IEVENT_OFFSET) +#define HCS12_EMAC_IMASK (HCS12_EMAC_BASE+HCS12_EMAC_IMASK_OFFSET) +#define HCS12_EMAC_SWRST (HCS12_EMAC_BASE+HCS12_EMAC_SWRST_OFFSET) +#define HCS12_EMAC_MPADR (HCS12_EMAC_BASE+HCS12_EMAC_MPADR_OFFSET) +#define HCS12_EMAC_MRADR (HCS12_EMAC_BASE+HCS12_EMAC_MRADR_OFFSET) +#define HCS12_EMAC_MWDATA (HCS12_EMAC_BASE+HCS12_EMAC_MWDATA_OFFSET) +#define HCS12_EMAC_MRDATA (HCS12_EMAC_BASE+HCS12_EMAC_MRDATA_OFFSET) +#define HCS12_EMAC_MCMST (HCS12_EMAC_BASE+HCS12_EMAC_MCMST_OFFSET) +#define HCS12_EMAC_BUFCFG (HCS12_EMAC_BASE+HCS12_EMAC_BUFCFG_OFFSET) +#define HCS12_EMAC_RXAEFP (HCS12_EMAC_BASE+HCS12_EMAC_RXAEFP_OFFSET) +#define HCS12_EMAC_RXBEFP (HCS12_EMAC_BASE+HCS12_EMAC_RXBEFP_OFFSET) +#define HCS12_EMAC_TXEFP (HCS12_EMAC_BASE+HCS12_EMAC_TXEFP_OFFSET) +#define HCS12_EMAC_MCHASH48 (HCS12_EMAC_BASE+HCS12_EMAC_MCHASH48_OFFSET) +#define HCS12_EMAC_MCHASH32 (HCS12_EMAC_BASE+HCS12_EMAC_MCHASH32_OFFSET) +#define HCS12_EMAC_MCHASH16 (HCS12_EMAC_BASE+HCS12_EMAC_MCHASH16_OFFSET) +#define HCS12_EMAC_MCHASH0 (HCS12_EMAC_BASE+HCS12_EMAC_MCHASH0_OFFSET) +#define HCS12_EMAC_MACAD32 (HCS12_EMAC_BASE+HCS12_EMAC_MACAD32_OFFSET) +#define HCS12_EMAC_MACAD16 (HCS12_EMAC_BASE+HCS12_EMAC_MACAD16_OFFSET) +#define HCS12_EMAC_MACAD0 (HCS12_EMAC_BASE+HCS12_EMAC_MACAD0_OFFSET) +#define HCS12_EMAC_EMISC (HCS12_EMAC_BASE+HCS12_EMAC_EMISC_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Network Control (8-bit) */ + +#define EMAC_NETCTL_FDX (1 << 1) /* Bit 1: Full Duplex */ +#define EMAC_NETCTL_MLB (1 << 2) /* Bit 2: MAC Loopback */ +#define EMAC_NETCTL_EXTPHY (1 << 3) /* Bit 3: External PHY */ +#define EMAC_NETCTL_ESWAI (1 << 4) /* Bit 4: EMAC Disabled during Wait Mode */ +#define EMAC_NETCTL_EMACE (1 << 7) /* Bit 7: EMAC Enable */ + +/* Receive Control and Status (8-bit) */ + +#define EMAC_RXCTS_BCREJ (1 << 0) /* Bit 0: Broadcast Reject */ +#define EMAC_RXCTS_CONMC (1 << 1) /* Bit 1: Conditional Multicast */ +#define EMAC_RXCTS_PROM (1 << 2) /* Bit 2: Promiscuous Mode */ +#define EMAC_RXCTS_RFCE (1 << 4) /* Bit 4: Reception Flow Control Enable */ +#define EMAC_RXCTS_RXACT (1 << 7) /* Bit 7: Receiver Active Status */ + +/* Transmit Control and Status (8-bit) */ + +#define EMAC_TXCTS_TCMD_SHIFT (0) /* Bits 0-1: Transmit Command */ +#define EMAC_TXCTS_TCMD_MASK (3) +# define EMAC_TXCTS_TCMD_START (1) /* Transmit buffer frame */ +# define EMAC_TXCTS_TCMD_PAUSE (2) /* Transmit PAUSE frame (full-duplex mode only) */ +# define EMAC_TXCTS_TCMD_ABORT (3) /* Abort transmission */ +#define EMAC_TXCTS_SSB (1 << 3) /* Bit 3: Single Slot Backoff */ +#define EMAC_TXCTS_PTRC (1 << 4) /* Bit 4: PAUSE Timer Register Control */ +#define EMAC_TXCTS_CSLF (1 << 5) /* Bit 5: Carrier Sense Lost Flag */ +#define EMAC_TXCTS_TXACT (1 << 7) /* Bit 7: Transmitter Active Status */ + +/* Ethertype Control (8-bit) */ + +#define EMAC_ETCTL_FIEEE (1 << 0) /* Bit 0: IEEE802.3 Length Field Ethertype */ +#define EMAC_ETCTL_FIPV4 (1 << 1) /* Bit 1: Internet Protocol Version 4 (IPv4) Ethertype */ +#define EMAC_ETCTL_FARP (1 << 2) /* Bit 2: Address Resolution Protocol (ARP) Ethertype */ +#define EMAC_ETCTL_FIPV6 (1 << 3) /* Bit 3: Internet Protocol Version 6 (IPv6) Ethertype */ +#define EMAC_ETCTL_FEMW (1 << 4) /* Bit 4: Emware Ethertype */ +#define EMAC_ETCTL_FPET (1 << 7) /* Bit 7: Programmable Ethertype */ + +/* Programmable Ethertype (16-bit) -- 16-bit Ethernet type data */ +/* PAUSE Timer Value and Counter (16-bit) -- 16-bit PAUSER timer value */ + +/* Interrupt Event (16-bit) */ +/* Interrupt Mask (16-bit) */ + +#define EMAC_INT_TXCI (1 << 1) /* Bit 1: Frame Transmission Complete Interrupt */ +#define EMAC_INT_ECI (1 << 4) /* Bit 4: Excessive Collision Interrupt */ +#define EMAC_INT_LCI (1 << 5) /* Bit 5: Late Collision Interrupt */ +#define EMAC_INT_MMCI (1 << 7) /* Bit 7: MII Management Transfer Complete Interrupt */ +#define EMAC_INT_RXBCI (1 << 8) /* Bit 8: Valid Frame Reception to Receive Buffer B Complete Interrupt */ +#define EMAC_INT_RXACI (1 << 9) /* Bit 9: Valid Frame Reception to Receive Buffer A Complete Interrupt */ +#define EMAC_INT_RXBOI (1 << 10) /* Bit 10: Receive Buffer B Overrun Interrupt */ +#define EMAC_INT_RXAOI (1 << 11) /* Bit 11: Receive Buffer A Overrun Interrupt */ +#define EMAC_INT_RXEI (1 << 12) /* Bit 12: Receive Error Interrupt */ +#define EMAC_INT_BREI (1 << 13) /* Bit 13: Babbling Receive Error Interrupt */ +#define EMAC_INT_RFCI (1 << 15) /* Bit 15: Receive Flow Control Interrupt */ + +/* Software Reset (8-bit) */ + +#define EMAC_SWRST_MACRST (1 << 7) /* Bit 7: EMAC is reset */ + +/* MII Management PHY Address (8-bit) */ + +#define EMAC_MPADR_MASK (0x1f) + +/* MII Management Register Address (8-bit) */ + +#define EMAC_MRADR_MASK (0x1f) + +/* MII Management Write Data (16-bit) -- 16-bit write data */ +/* MII Management Read Data (16-bit) -- 16-bit read data */ + +/* MII Management Command and Status (8-bit) */ + +#define EMAC_MCMST_MDCSEL_SHIFT (0) /* Bits 0-3: Management Clock Rate Sel */ +#define EMAC_MCMST_MDCSEL_MASK (15) /* MDC frequency = Bus clock frequency / (2 * MDCSEL) */ +#define EMAC_MCMST_NOPRE (1 << 4) /* Bit 4: No Preamble */ +#define EMAC_MCMST_BUSY (1 << 5) /* Bit 5: Operation in Progress */ +#define EMAC_MCMST_OP_SHIFT (6) /* Bits 6-7: Operation Code */ +#define EMAC_MCMST_OP_MASK (3 << EMAC_MCMST_OP_SHIFT) +# define EMAC_MCMST_OP_IGNORE (0 << EMAC_MCMST_OP_SHIFT) +# define EMAC_MCMST_OP_WRITE (1 << EMAC_MCMST_OP_SHIFT) +# define EMAC_MCMST_OP_READ (2 << EMAC_MCMST_OP_SHIFT) + +/* Ethernet Buffer Configuration (16-bit) */ + +#define EMAC_BUFCFG_MAXFL_SHIFT (0) /* Bits 0-10 Receive Maximum Frame Length */ +#define EMAC_BUFCFG_MAXFL_MASK (0x07ff) +#define EMAC_BUFCFG_BUFMAP_SHIFT (12) /* Bits 12-14: Buffer Size and Starting Address Mapping */ +#define EMAC_BUFCFG_BUFMAP_SHIFT (7 << EMAC_BUFCFG_BUFMAP_SHIFT) +# define EMAC_BUFCFG_BUFMAP_128 (0 << EMAC_BUFCFG_BUFMAP_SHIFT) /* Rx/Tx = 128 bytes */ +# define EMAC_BUFCFG_BUFMAP_256 (1 << EMAC_BUFCFG_BUFMAP_SHIFT) /* Rx/Tx = 256 bytes */ +# define EMAC_BUFCFG_BUFMAP_512 (2 << EMAC_BUFCFG_BUFMAP_SHIFT) /* Rx/Tx = 512 bytes */ +# define EMAC_BUFCFG_BUFMAP_1024 (3 << EMAC_BUFCFG_BUFMAP_SHIFT) /* Rx/Tx = 1Kb */ +# define EMAC_BUFCFG_BUFMAP_1536 (4 << EMAC_BUFCFG_BUFMAP_SHIFT) /* Rx/Tx = 1.5Kb */ + +/* Receive A End-of-Frame Pointer (16-bit) */ + +#define EMAC_RXAEFP_MASK (0x07ff) + +/* Receive B End-of-Frame Pointer (16-bit) */ + +#define EMAC_RXBEFP_MASK (0x07ff) + +/* Transmit End-of-Frame Pointer (16-bit) */ + +#define EMAC_TXEFP_MASK (0x07ff) + +/* Multicast Hash Table 48-63 (16-bit) -- 16-bits of MAC address */ +/* Multicast Hash Table 32-47 (16-bit) -- 16-bits of MAC address */ +/* Multicast Hash Table 16-31 (16-bit) -- 16-bits of MAC address */ +/* Multicast Hash Table 0:15 (16-bit) -- 16-bits of MAC address */ + +/* MAC Unicast Address 32-47 (16-bit) -- 16-bits of address */ +/* MAC Unicast AAddress 16-31 (16-bit) -- 16-bits of address */ +/* MAC Unicast AAddress 0-15 (16-bit) -- 16-bits of address */ + +/* Miscellaneous (16-bit) */ + +#define EMAC_EMISC_SHIFT (0) /* Bits 0-10: Misc data */ +#define EMAC_EMISC_MASK (0x07ff) +#define EMAC_EMISC_INDEX_SHIFT (13) /* Bits 13-15: Miscellaneous Index */ +#define EMAC_EMISC_INDEX_MASK (7 << EMAC_EMISC_INDEX_SHIFT) +# define EMAC_EMISC_INDEX_TXBYT (3 << EMAC_EMISC_INDEX_SHIFT) /* Transmit Frame Byte Counter */ +# define EMAC_EMISC_INDEX_BSLOT (4 << EMAC_EMISC_INDEX_SHIFT) /* Backoff Slot Time Counter */ +# define EMAC_EMISC_INDEX_RETX (5 << EMAC_EMISC_INDEX_SHIFT) /* Retransmission Counter */ +# define EMAC_EMISC_INDEX_RANDOM (6 << EMAC_EMISC_INDEX_SHIFT) /* Backoff Random Number */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_EMAC_H */ diff --git a/arch/hc/src/m9s12/m9s12_ethernet.c b/arch/hc/src/m9s12/m9s12_ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..0f02c88aedd45060e57410eb546dc099f06ab1fd --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_ethernet.c @@ -0,0 +1,784 @@ +/**************************************************************************** + * drivers/net/m9s12_ethernet.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_HCS12_EMAC) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIG_HCS12_NINTERFACES determines the number of physical interfaces + * that will be supported. + */ + +#ifndef CONFIG_HCS12_NINTERFACES +# define CONFIG_HCS12_NINTERFACES 1 +#endif + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define HCS12_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define HCS12_TXTIMEOUT (60*CLK_TCK) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->d_dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The emac_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct emac_driver_s +{ + bool d_bifup; /* true:ifup false:ifdown */ + WDOG_ID d_txpoll; /* TX poll timer */ + WDOG_ID d_txtimeout; /* TX timeout timer */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s d_dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct emac_driver_s g_emac[CONFIG_HCS12_NINTERFACES]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Common TX logic */ + +static int emac_transmit(FAR struct emac_driver_s *priv); +static int emac_txpoll(struct net_driver_s *dev); + +/* Interrupt handling */ + +static void emac_receive(FAR struct emac_driver_s *priv); +static void emac_txdone(FAR struct emac_driver_s *priv); +static int emac_interrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static void emac_polltimer(int argc, uint32_t arg, ...); +static void emac_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int emac_ifup(struct net_driver_s *dev); +static int emac_ifdown(struct net_driver_s *dev); +static int emac_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int emac_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int emac_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: emac_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int emac_transmit(FAR struct emac_driver_s *priv) +{ + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is not transmission in progress. + */ + + /* Increment statistics */ + + /* Send the packet: address=priv->d_dev.d_buf, length=priv->d_dev.d_len */ + + /* Enable Tx interrupts */ + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->d_txtimeout, HCS12_TXTIMEOUT, emac_txtimeout, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: emac_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int emac_txpoll(struct net_driver_s *dev) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->d_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->d_dev.d_flags)) +#endif + { + arp_out(&priv->d_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->d_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + emac_transmit(priv); + + /* Check if there is room in the device to hold another packet. If not, + * return a non-zero value to terminate the poll. + */ + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Function: emac_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void emac_receive(FAR struct emac_driver_s *priv) +{ + do + { + /* Check for errors and update statistics */ + + /* Check if the packet is a valid size for the uIP buffer configuration */ + + /* Copy the data data from the hardware to priv->d_dev.d_buf. Set + * amount of data in priv->d_dev.d_len + */ + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->d_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->d_dev); + ipv4_input(&priv->d_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->d_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->d_dev.d_flags)) +#endif + { + arp_out(&priv->d_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->d_dev); + } +#endif + + /* And send the packet */ + + emac_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->d_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->d_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->d_dev.d_flags)) + { + arp_out(&priv->d_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->d_dev); + } +#endif + + /* And send the packet */ + + emac_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + arp_arpin(&priv->d_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->d_dev.d_len > 0) + { + emac_transmit(priv); + } + } +#endif + } + while (true); /* While there are more packets to be processed */ +} + +/**************************************************************************** + * Function: emac_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void emac_txdone(FAR struct emac_driver_s *priv) +{ + /* Check for errors and update statistics */ + + /* If no further xmits are pending, then cancel the TX timeout and + * disable further Tx interrupts. + */ + + wd_cancel(priv->d_txtimeout); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->d_dev, emac_txpoll); +} + +/**************************************************************************** + * Function: emac_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int emac_interrupt(int irq, FAR void *context) +{ + register FAR struct emac_driver_s *priv = &g_emac[0]; + + /* Get and clear interrupt status bits */ + + /* Handle interrupts according to status bit settings */ + + /* Check if we received an incoming packet, if so, call emac_receive() */ + + emac_receive(priv); + + /* Check is a packet transmission just completed. If so, call emac_txdone. + * This may disable further Tx interrupts if there are no pending + * tansmissions. + */ + + emac_txdone(priv); + + return OK; +} + +/**************************************************************************** + * Function: emac_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void emac_txtimeout(int argc, uint32_t arg, ...) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)arg; + + /* Increment statistics and dump debug info */ + + /* Then reset the hardware */ + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->d_dev, emac_txpoll); +} + +/**************************************************************************** + * Function: emac_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void emac_polltimer(int argc, uint32_t arg, ...) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)arg; + + /* Check if there is room in the send another TX packet. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ + + /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. + * might be bug here. Does this mean if there is a transmit in progress, + * we will missing TCP time state updates? + */ + + (void)devif_timer(&priv->d_dev, emac_txpoll); + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->d_txpoll, HCS12_WDDELAY, emac_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: emac_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int emac_ifup(struct net_driver_s *dev) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + + /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */ + + /* Set and activate a timer process */ + + (void)wd_start(priv->d_txpoll, HCS12_WDDELAY, emac_polltimer, 1, (uint32_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->d_bifup = true; + up_enable_irq(CONFIG_HCS12_IRQ); + return OK; +} + +/**************************************************************************** + * Function: emac_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int emac_ifdown(struct net_driver_s *dev) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(CONFIG_HCS12_IRQ); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->d_txpoll); + wd_cancel(priv->d_txtimeout); + + /* Put the EMAC is its reset, non-operational state. This should be + * a known configuration that will guarantee the emac_ifup() always + * successfully brings the interface back up. + */ + + /* Mark the device "down" */ + + priv->d_bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: emac_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int emac_txavail(struct net_driver_s *dev) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->d_bifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ + + /* If so, then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->d_dev, emac_txpoll); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: emac_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int emac_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + + return OK; +} +#endif + +/**************************************************************************** + * Function: emac_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int emac_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct emac_driver_s *priv = (FAR struct emac_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: emac_initialize + * + * Description: + * Initialize the Ethernet controller and driver + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int emac_initialize(int intf) +{ + struct lpc17_driver_s *priv; + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(inf < CONFIG_HCS12_NINTERFACES); + priv = &g_ethdrvr[intf]; + + /* Check if a Ethernet chip is recognized at its I/O base */ + + /* Attach the IRQ to the driver */ + + if (irq_attach(CONFIG_HCS12_IRQ, emac_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct emac_driver_s)); + priv->d_dev.d_ifup = emac_ifup; /* I/F down callback */ + priv->d_dev.d_ifdown = emac_ifdown; /* I/F up (new IP address) callback */ + priv->d_dev.d_txavail = emac_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->d_dev.d_addmac = emac_addmac; /* Add multicast MAC address */ + priv->d_dev.d_rmmac = emac_rmmac; /* Remove multicast MAC address */ +#endif + priv->d_dev.d_private = (void*)g_emac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->d_txpoll = wd_create(); /* Create periodic poll timer */ + priv->d_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Put the interface in the down state. This usually amounts to resetting + * the device and/or calling emac_ifdown(). + */ + + /* Read the MAC address from the hardware into priv->d_dev.d_mac.ether_addr_octet */ + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->d_dev, NET_LL_ETHERNET); + return OK; +} + +#endif /* CONFIG_NET && CONFIG_HCS12_EMAC */ diff --git a/arch/hc/src/m9s12/m9s12_flash.h b/arch/hc/src/m9s12/m9s12_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..32e35d5790aa5f66c373eaa3306d23e20c099754 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_flash.h @@ -0,0 +1,209 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_flash.h + * + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_FLASH_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_FLASH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Flash memory map ***************************************************************** + * + * 0x4000-0x7fff: 16Kb Fixed FLASH EEPROM (Page 3e) + * 0x8000-0xbfff: 16Kb Page window + * 0xc000-0xffff: 16Kb Fixed FLASH EEPROM (Page 3f) + * (see chip.h) + * + * The M9S12 implements 6 bits of the PPAGE register which gives it a + * 1 Mbyte program memory address space that is accessed through the PPAGE + * window. The lower 768K portion of the address space, accessed with PPAGE + * values $00 through $2F, is reserved for external memory when the part is + * operated in expanded mode. The upper 256K of the address space, accessed + * with PPAGE values $30 through $3F. + */ + +#define HCS12_BTLDR_BASE 0xf800 /* 0xf800-0xffff: 2Kb Protected bootloader FLASH */ + +/* User-Accessible utility subroutines provided by the serial monitor: + * + * PutChar - Sends the character in A out SCI0 + * + * PutChar: brclr SCI0SR1,TDRE,PutChar ;wait for Tx ready + * staa SCI0DRL ;send character from A + * rts + * + * GetChar - Wait indefinitely for a character to be received via SCI. + * Return received character in A. + * + * GetChar: brset SCI0SR1,RDRF,RxReady ;exit loop when RDRF=1 + * bra GetChar ;loop till RDRF set + * RxReady: ldaa SCI0DRL ;read character into A + * rts ;return + * EraseAllCmd - Use repeated page erase commands to erase all flash + * except bootloader in protected block at the end of flash, and mass + * erase all EEPROM locations + * DoOnStack - Copy to stack and execute from RAM + * WriteD2IX - Write the data in D (word) to the address in IX + * The location may be RAM, FLASH, EEPROM, or a register + * if FLASH or EEPROM, the operation is completed before return + * IX and A preserved, returns Z=1 (.EQ.) if OK + */ + +#ifdef CONFIG_HCS12_SERIALMON +# define PutChar 0xfee6 /* Sends the character in A out SCI0 */ +# define GetChar 0xfee9 /* Return character received from SCIO in A */ +# define EraseAllCmd 0xfeec /* Erase all flash (except bootloader) */ +# define DoOnStack 0xfeef /* Copy to stack and execute from RAM */ +# define WriteD2IX 0xfef2 /* Write the data in D (word) to the address in IX. + * The location may be RAM, FLASH, EEPROM, or a register */ + +/* Serial monitor version */ + +# define SWID_DEVID 0xfef8 +# define SWID_DATE 0xfefa +# define SWID_YEAR 0xfefc +# define SWID_VER 0xfefe + +/* Interrupts */ + +# define HCS12_UVECTOR_BASE 0xf780 /* 0xf780–0xf7fe: User vector base */ +#endif + +/* FLASH interface */ + +#define HCS12_BACKDOOR_KEY 0xff00 /* 0xff00-0xff07: Backdoor comparison keys */ + /* 0xff08-0xff0c: Reserved */ +#define HCS12_FLASH_PROT 0xff0d /* 0xff0d: Flash protection byte */ + /* 0xff0e: Reserved */ +#define HCS12_FLASH_OPT 0xff0f /* 0xff0f: Flash options/security byte */ + +/* Interrupts */ + +#define HCS12_VECTOR_BASE 0xff80 /* 0xff80–0xfffe: Actual vector base */ + +/* Register Offsets *****************************************************************/ + +#define HCS12_FLASH_FCLKDIV_OFFSET (HCS12_FLASH_BASE+0x00) /* Flash Clock Divider Register */ +#define HCS12_FLASH_FSEC_OFFSET (HCS12_FLASH_BASE+0x03) /* Flash Security Register */ +#define HCS12_FLASH_FCNFG_OFFSET (HCS12_FLASH_BASE+0x03) /* Flash Configuration Register */ +#define HCS12_FLASH_FPROT_OFFSET (HCS12_FLASH_BASE+0x04) /* Flash Protection Register */ +#define HCS12_FLASH_FSTAT_OFFSET (HCS12_FLASH_BASE+0x05) /* Flash Status Register */ +#define HCS12_FLASH_FCMD_OFFSET (HCS12_FLASH_BASE+0x06) /* Flash Command Register */ +#define HCS12_FLASH_FADDRHI_OFFSET (HCS12_FLASH_BASE+0x08) /* Flash High Address Register */ +#define HCS12_FLASH_FADDRLO_OFFSET (HCS12_FLASH_BASE+0x09) /* Flash Low Address Register */ +#define HCS12_FLASH_FDATAHI_OFFSET (HCS12_FLASH_BASE+0x0a) /* Flash High Data Register */ +#define HCS12_FLASH_FDATALO_OFFSET (HCS12_FLASH_BASE+0x0b) /* Flash Low Data Register (*/ + +/* Register Addresses ***************************************************************/ + +#define HCS12_FLASH_FCLKDIV (HCS12_REG_BASE+HCS12_FLASH_FCLKDIV_OFFSET) +#define HCS12_FLASH_FSEC (HCS12_REG_BASE+HCS12_FLASH_FSEC_OFFSET) +#define HCS12_FLASH_FCNFG (HCS12_REG_BASE+HCS12_FLASH_FCNFG_OFFSET) +#define HCS12_FLASH_FPROT (HCS12_REG_BASE+HCS12_FLASH_FPROT_OFFSET) +#define HCS12_FLASH_FSTAT (HCS12_REG_BASE+HCS12_FLASH_FSTAT_OFFSET) +#define HCS12_FLASH_FCMD (HCS12_REG_BASE+HCS12_FLASH_FCMD_OFFSET) +#define HCS12_FLASH_FADDRHI (HCS12_REG_BASE+HCS12_FLASH_FADDRHI_OFFSET) +#define HCS12_FLASH_FADDRLO (HCS12_REG_BASE+HCS12_FLASH_FADDRLO_OFFSET) +#define HCS12_FLASH_FDATAHI (HCS12_REG_BASE+HCS12_FLASH_FDATAHI_OFFSET) +#define HCS12_FLASH_FDATALO (HCS12_REG_BASE+HCS12_FLASH_FDATALO_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +#define FLASH_FCLKDIV_FDIV_SHIFT (0) /* Bits 0-5: Clock Divider Bits */ +#define FLASH_FCLKDIV_FDIV_MASK (0x3f << FLASH_FCLKDIV_FDIV_SHIFT) +#define FLASH_FCLKDIV_PRDIV8 (1 << 6) /* Bit 6: Enable Prescaler by 8 */ +#define FLASH_FCLKDIV_FDIVLD (1 << 7) /* Bit 7: Clock Divider Loaded */ + +#define FLASH_FSET_SEC_SHIFT (0) /* Bits 0-1: Memory Security Bits */ +#define FLASH_FSET_SEC_MASK (3 << FLASH_FSET_SEC_SHIFT) +# define FLASH_FSET_SEC_UNSECURED (2 << FLASH_FSET_SEC_SHIFT) +#define FLASH_FSET_KEYEN (1 << 7) /* Bit 7: Backdoor Key Enable */ +#define FLASH_FSET_NV_SHIFT (2) /* Bits 2-6: Nonvolatile Flag Bits */ +#define FLASH_FSET_NV_MASK (0x1f << FLASH_FSET_NV_SHIFT) + +#define FLASH_FCNG_KEYACC (1 << 5) /* Bit 5: Enable Security Key Writing */ +#define FLASH_FCNG_CCIE (1 << 6) /* Bit 6: Command Complete Interrupt Enable */ +#define FLASH_FCNG_CBEIE (1 << 7) /* Bit 7: Command Buffer Empty Interrupt Enable */ + +#define FLASH_FPROT_FPLS_SHIFT (0) /* Bits 0-1: Flash Protection Lower Address Size */ +#define FLASH_FPROT_FPLS_MASK (3 << FLASH_FPROT_FPLS_SHIFT) +# define FLASH_FPROT_FPLS_512B (0 << FLASH_FPROT_FPLS_SHIFT) +# define FLASH_FPROT_FPLS_1KB (1 << FLASH_FPROT_FPLS_SHIFT) +# define FLASH_FPROT_FPLS_2KB (2 << FLASH_FPROT_FPLS_SHIFT) +# define FLASH_FPROT_FPLS_4KB (3 << FLASH_FPROT_FPLS_SHIFT) +#define FLASH_FPROT_FPLDIS (1 << 2) /* Bit 2: Flash Protection Lower address range Disable */ +#define FLASH_FPROT_FPHS_SHIFT (3) /* Bits 3-4: Flash Protection Higher Address Size */ +#define FLASH_FPROT_FPHS_MASK (3 << FLASH_FPROT_FPHS_SHIFT) +# define FLASH_FPROT_FPHS_2KB (0 << FLASH_FPROT_FPHS_SHIFT) +# define FLASH_FPROT_FPHS_4KB (1 << FLASH_FPROT_FPHS_SHIFT) +# define FLASH_FPROT_FPHS_8KB (2 << FLASH_FPROT_FPHS_SHIFT) +# define FLASH_FPROT_FPHS_16KB (3 << FLASH_FPROT_FPHS_SHIFT) +#define FLASH_FPROT_FPHDIS (1 << 5) /* Bit 5: Flash Protection Higher address range disable */ +#define FLASH_FPROT_FPOPEN (1 << 7) /* Bit 7: Opens the Flash block for program or erase */ + +#define FLASH_FSTAT_BLANK (1 << 2) /* Bit 2: Array has been verified as erased */ +#define FLASH_FSTAT_ACCERR (1 << 4) /* Bit 4: Flash access error */ +#define FLASH_FSTAT_PVIOL (1 << 5) /* Bit 5: Protection violation */ +#define FLASH_FSTAT_CCIF (1 << 6) /* Bit 6: Command complete interrupt flag */ +#define FLASH_FSTAT_CBEIF (1 << 7) /* Bit 7: Command buffer empty interrupt flag */ + +#define FLASH_FCMD_ERASEVERIFY 0x05 /* Erase Verify */ +#define FLASH_FCMD_WORDPROGRM 0x20 /* Word Program */ +#define FLASH_FCMD_SECTORERASE 0x40 /* Sector Erase */ +#define FLASH_FCMD_MASSERASE 0x41 /* Mass Erase */ + +#define FLASH_FADDRHI_MASK 0x7f + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_FLASH_H */ diff --git a/arch/hc/src/m9s12/m9s12_gpio.c b/arch/hc/src/m9s12/m9s12_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..7d43f0a3d8a6fef99dc18f81e75648d6379315f6 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_gpio.c @@ -0,0 +1,484 @@ +/**************************************************************************** + * arch/arm/src/m9s12/m9s12_gpio.c + * + * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "m9s12.h" +#include "m9s12_pim.h" +#include "m9s12_mebi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* GPIO management macros: + * + * The GPIO configuration is represented by a 16-bit value encoded as follows: + * + * xIIO UURV DMGG GPPP + * ||| |||| ||| `-Pin number + * ||| |||| || `- Port number + * ||| |||| | `- PIM Ports + * ||| |||| `- Direction + * ||| |||`- Initial value of output + * ||| ||`- Reduced drive + * ||| |`- Polarity + * ||| `- Pull up (or down) + * ||`- Wired OR open drain + * |`- Interrupt or rising/falling (polarity) + * `- Interrupt + * + * NOTE: MEBI ports E and K can have special configurations as controlled by + * the PEAR and MODE registers. Those special configurations are not managed + * by the logic below; that logic is only intended to support general GPIO + * pin usage. + */ + +/* PIM ports (T,S,G,H,J,L) */ + +#define HCS12_PIM_NPORTS 6 + +/* MEBI ports (A,B,E,K) */ + +#define HCS12_MEBI_NPORTS 4 + +/* Which ports have which registers? */ + +#define HCS12_PORT_T (1 << 0) +#define HCS12_PORT_S (1 << 1) +#define HCS12_PORT_G (1 << 2) +#define HCS12_PORT_H (1 << 3) +#define HCS12_PORT_J (1 << 4) +#define HCS12_PORT_L (1 << 5) +#define HCS12_PORT_ALL 0x3f + +#define HCS12_IO_PORTS HCS12_PORT_ALL +#define HCS12_INPUT_PORTS HCS12_PORT_ALL +#define HCS12_DDR_PORTS HCS12_PORT_ALL +#define HCS12_RDR_PORTS HCS12_PORT_ALL +#define HCS12_PER_PORTS HCS12_PORT_ALL +#define HCS12_PS_PORTS HCS12_PORT_ALL +#define HCS12_WOM_PORTS (HCS12_PORT_S|HCS12_PORT_L) +#define HCS12_IE_PORTS (HCS12_PORT_G|HCS12_PORT_H|HCS12_PORT_J) +#define HCS12_IF_PORTS (HCS12_PORT_G|HCS12_PORT_H|HCS12_PORT_J) + +/* Decoding helper macros */ + +#define HCS12_PIN(cfg) (((cfg) & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT) +#define HCS12_PORTNDX(cfg) (((cfg) >> GPIO_PORT_SHIFT) & 7) +#define HCS12_PIMPORT(cfg) (((cfg) & GPIO_PORT_PIM) != 0) +#define HCS12_MEBIPORT(cfg) (((cfg) & GPIO_PORT_PIM) == 0) +#define HCS12_OUTPUT(cfg) (((cfg) & GPIO_DIRECTION) == GPIO_OUTPUT) + +#define HCS12_PULL(cfg) (((cfg) & GPIO_PULLUP_MASK) >> GPIO_PULLUP_SHIFT) +# define HCS12_PULL_NONE 0 +# define HCS12_PULL_POLARITY 1 +# define HCS12_PULL_ENABLE 2 +# define HCS12_PULL_UP 2 +# define HCS12_PULL_DOWN 3 + +#define HCS12_INTERRUPT(cfg) (((cfg) & GPIO_INT_MASK) >> GPIO_INT_SHIFT) +# define HCS12_INT_NONE 0 +# define HCS12_INT_POLARITY 1 +# define HCS12_INT_ENABLE 2 +# define HCS12_INT_FALLING 2 +# define HCS12_INT_RISING 3 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mebi_portaddr_s +{ + uint16_t data; /* Data register */ + uint16_t ddr; /* Direction register */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct mebi_portaddr_s mebi_portaddr[HCS12_MEBI_NPORTS] = +{ + {HCS12_MEBI_PORTA, HCS12_MEBI_DDRA}, /* Port A */ + {HCS12_MEBI_PORTB, HCS12_MEBI_DDRB}, /* Port B */ + {HCS12_MEBI_PORTE, HCS12_MEBI_DDRE}, /* Port E */ + {HCS12_MEBI_PORTK, HCS12_MEBI_DDRK} /* Port K */ +}; + +static uint8_t mebi_bits[HCS12_MEBI_NPORTS] = +{ + (1 << 0), (1 << 1), (1 << 4), (1 << 7) +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Misc. Low-Level, Inline Helper Functions + ****************************************************************************/ + +/* Set or clear a bit in a register */ + +static inline void gpio_writebit(uint16_t regaddr, uint8_t pin, bool set) +{ + uint8_t regval = getreg8(regaddr); + if (set) + { + regval |= (1 << pin); + } + else + { + regval &= ~(1 << pin); + } + putreg8(regval, regaddr); +} + +/* Return the value of a bit in a register */ + +static inline bool gpio_readbit(uint16_t regaddr, uint8_t pin) +{ + uint8_t regval = getreg8(regaddr); + return ((regval & (1 << pin)) != 0); +} + +/* Set the direction of a PIM port */ + +static inline void pim_direction(uint8_t portndx, uint8_t pin, bool output) +{ + gpio_writebit(HCS12_PIM_PORT_DDR(portndx), pin, output); +} + +/* Set the direction of a MEBI port */ + +static inline void mebi_direction(uint8_t portndx, uint8_t pin, bool output) +{ + gpio_writebit(mebi_portaddr[portndx].ddr, pin, output); +} + +/* Write to the Wired-OR register of a PIM port */ + +static inline void pim_opendrain(uint8_t portndx, uint8_t pin, bool opendrain) +{ + DEBUGASSERT(!opendrain || (HCS12_WOM_PORTS & (1 << pin)) != 0); + gpio_writebit(HCS12_PIM_PORT_WOM(portndx), pin, opendrain); +} + +/* Configure pull up resisters on on a PIM port pin */ + +static inline void pim_pullpin(uint8_t portndx, uint8_t pin, uint8_t pull) +{ + bool enable = false; + bool polarity = false; + + if ((pull & HCS12_PULL_ENABLE) != 0) + { + enable = true; + if ((pull & HCS12_PULL_POLARITY) != 0) + { + polarity = true; + } + } + + gpio_writebit(HCS12_PIM_PORT_PER(portndx), pin, enable); + gpio_writebit(HCS12_PIM_PORT_PS(portndx), pin, polarity); +} + +/* Configure pull up resisters on on a while PIM port */ + +static inline void mebi_pullport(uint8_t portndx, uint8_t pull) +{ + uint8_t regval = getreg8(HCS12_MEBI_PUCR); + if (pull == HCS12_PULL_UP) + { + regval |= mebi_bits[portndx]; + } + else + { + regval &= ~mebi_bits[portndx]; + } + putreg8(regval, HCS12_MEBI_PUCR); +} + +/* Select/deselect reduced drive for a PIM port pin */ + +static inline void pim_rdpin(uint8_t portndx, uint8_t pin, bool rdenable) +{ + gpio_writebit(HCS12_PIM_PORT_RDR(portndx), pin, rdenable); +} + +/* Select/deselect reduced drive for a whole MEBI port */ + +static inline void mebi_rdport(uint8_t portndx, bool rdenable) +{ + uint8_t regval = getreg8(HCS12_MEBI_RDRIV); + if (rdenable) + { + regval |= mebi_bits[portndx]; + } + else + { + regval &= ~mebi_bits[portndx]; + } + putreg8(regval, HCS12_MEBI_RDRIV); +} + +/* Configure the PIM port pin as a interrupt */ + +static inline void pim_interrupt(uint8_t portndx, unsigned pin, uint8_t type) +{ + if (type != HCS12_INT_NONE) + { + DEBUGASSERT((HCS12_IE_PORTS & (1 << pin)) != 0); + gpio_writebit(HCS12_PIM_PORT_IE(portndx), pin, false); + gpio_writebit(HCS12_PIM_PORT_PS(portndx), pin, ((type & GPIO_INT_POLARITY) != 0)); + } + else if ((HCS12_IE_PORTS & (1 << pin)) != 0) + { + gpio_writebit(HCS12_PIM_PORT_IE(portndx), pin, false); + } +} + +/**************************************************************************** + * Name: pim_configgpio + * + * Description: + * Configure a PIM pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline void pim_configgpio(uint16_t cfgset, uint8_t portndx, uint8_t pin) +{ + /* Sanity checking -- Check if the pin will be enabled as an interrupt + * (later) + */ + + DEBUGASSERT(portndx < HCS12_PIM_NPORTS); + +#ifdef CONFIG_DEBUG + if ((cfgset & GPIO_INT_ENABLE) != 0) + { + /* Yes.. then it must not be tagged as an output */ + + ASSERT((cfgset & GPIO_DIRECTION) != GPIO_OUTPUT); + + /* If the pull-driver is also enabled, it must be enabled with a + * compatible priority. + */ + + if ((cfgset & GPIO_PULL_ENABLE) != 0) + { + if ((cfgset & GPIO_INT_POLARITY) != 0) + { + ASSERT((cfgset & GPIO_PULL_POLARITY) != 0); + } + else + { + ASSERT((cfgset & GPIO_PULL_POLARITY) == 0); + } + } + } +#endif + + pim_direction(portndx, pin, ((cfgset & GPIO_DIRECTION) == GPIO_OUTPUT)); + pim_opendrain(portndx, pin, ((cfgset & GPIO_OPENDRAIN) != 0)); + pim_pullpin(portndx, pin, HCS12_PULL(cfgset)); + pim_rdpin(portndx, pin, ((cfgset & GPIO_REDUCED) != 0)); + pim_interrupt(portndx, pin, HCS12_INTERRUPT(cfgset)); +} + +/**************************************************************************** + * Name: mebi_configgpio + * + * Description: + * Configure a MEBI pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +static inline void mebi_configgpio(uint16_t cfgset, uint8_t portndx, uint8_t pin) +{ + DEBUGASSERT(portndx < HCS12_MEBI_NPORTS); + mebi_direction(portndx, pin, ((cfgset & GPIO_DIRECTION) == GPIO_OUTPUT)); + mebi_pullport(portndx, HCS12_PULL(cfgset)); + mebi_rdport(portndx, ((cfgset & GPIO_REDUCED) != 0)); +} + +/**************************************************************************** + * Read/Write Helpers + ****************************************************************************/ + +/* Set the output state of a PIM port pin */ + +static inline void pim_gpiowrite(uint8_t portndx, uint8_t pin, bool value) +{ + uint16_t regaddr = HCS12_PIM_PORT_IO(portndx); + DEBUGASSERT(portndx < HCS12_PIM_NPORTS); + gpio_writebit(regaddr, pin, value); +} + +/* Set the output state of a MEBI port pin */ + +static inline void mebi_gpiowrite(uint8_t portndx, uint8_t pin, bool value) +{ + uint16_t regaddr; + DEBUGASSERT(portndx < HCS12_MEBI_NPORTS); + regaddr = mebi_portaddr[portndx].data; + gpio_writebit(regaddr, pin, value); +} + +/* Get the current state of a PIM port pin */ + +static inline bool pim_gpioread(uint8_t portndx, uint8_t pin) +{ + uint16_t regaddr = HCS12_PIM_PORT_INPUT(portndx); + DEBUGASSERT(portndx < HCS12_PIM_NPORTS); + return gpio_readbit(regaddr, pin); +} + +/* Get the current state of a MEBI port pin */ + +static inline bool mebi_gpioread(uint8_t portndx, uint8_t pin) +{ + uint16_t regaddr; + DEBUGASSERT(portndx < HCS12_MEBI_NPORTS); + regaddr = mebi_portaddr[portndx].data; + return gpio_readbit(regaddr, pin); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hcs12_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int hcs12_configgpio(uint16_t cfgset) +{ + /* Get the port index and pin number */ + + uint8_t portndx = HCS12_PORTNDX(cfgset); + uint8_t pin = HCS12_PIN(cfgset); + + /* Configure the pin */ + + if (HCS12_PIMPORT(cfgset)) + { + pim_configgpio(cfgset, portndx, pin); + } + else + { + mebi_configgpio(cfgset, portndx, pin); + } + + /* If the pin is an output, then set the initial value of the output */ + + if (HCS12_OUTPUT(cfgset)) + { + hcs12_gpiowrite(cfgset, (cfgset & GPIO_OUTPUT_VALUE) == GPIO_OUTPUT_HIGH); + } + return OK; +} + +/**************************************************************************** + * Name: hcs12_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void hcs12_gpiowrite(uint16_t pinset, bool value) +{ + uint8_t portndx = HCS12_PORTNDX(pinset); + uint8_t pin = HCS12_PIN(pinset); + irqstate_t flags = enter_critical_section(); + + DEBUGASSERT((pinset & GPIO_DIRECTION) == GPIO_OUTPUT); + if (HCS12_PIMPORT(pinset)) + { + pim_gpiowrite(portndx, pin, value); + } + else + { + mebi_gpiowrite(portndx, pin, value); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: hcs12_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool hcs12_gpioread(uint16_t pinset) +{ + uint8_t portndx = HCS12_PORTNDX(pinset); + uint8_t pin = HCS12_PIN(pinset); + + if (HCS12_PIMPORT(pinset)) + { + return pim_gpioread(portndx, pin); + } + else + { + return mebi_gpioread(portndx, pin); + } +} diff --git a/arch/hc/src/m9s12/m9s12_gpioirq.c b/arch/hc/src/m9s12/m9s12_gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..4dae0551244d4077256ba7b1240e8269b5d7d4de --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_gpioirq.c @@ -0,0 +1,294 @@ +/**************************************************************************** + * arch/arm/src/m9s12/m9s12_gpioirq.c + * arch/arm/src/chip/m9s12_gpioirq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "m9s12.h" +#include "m9s12_pim.h" +#include "m9s12_mebi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hcs12_gpioirqinitialize + * + * Description: + * Map an IRQ number to a port address and a bit number. + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +static int hcs12_mapirq(int irq, uint16_t *regaddr, uint8_t *pin) +{ + if (irq >= HCC12_IRQ_PGFIRST) + { + /* Port G: Pins 0-7 */ + +#ifdef CONFIG_HCS12_PORTG_INTS + if (irq < HCC12_IRQ_PHFIRST) + { + *regaddr = HCS12_PIM_PORTG_IE; + *pin = irq - HCC12_IRQ_PGFIRST; + return OK; + } +#endif + + /* Port H: Pins 0-6 */ + +#ifdef CONFIG_HCS12_PORTH_INTS + if (irq < HCC12_IRQ_PJFIRST) + { + *regaddr = HCS12_PIM_PORTH_IE; + *pin = irq - HCC12_IRQ_PHFIRST; + return OK; + } +#endif + + /* Port J: Pins 0-3 and 6-7 */ + +#ifdef CONFIG_HCS12_PORTJ_INTS + if (irq < HCC12_IRQ_PJFIRST) + { + uint8_t pjpin = irq - HCC12_IRQ_PJFIRST; + if (irq >= HCS12_IRQ_PJ6) + { + pjpin += 2; + } + + *regaddr = HCS12_PIM_PORTJ_IE; + *pin = pjpin; + return OK; + } +#endif + } + return -EINVAL; +} +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Name: up_gpioa/b/cinterrupt + * + * Description: + * Receive GPIOA/B/C interrupts + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +static int hcs12_interrupt(uint16_t base, int irq0, uint8_t valid, void *context) +{ + uint8_t pending; + uint8_t bit; + int irq; + + /* Get the set of enabled (unmasked) interrupts pending on this port */ + + pending = getreg8(base+HCS12_PIM_IF_OFFSET) && getreg8(base+HCS12_PIM_IE_OFFSET); + + /* Then check each bit in the set of interrupts */ + + for (bit = 1, irq = irq0; pending != 0; bit <<= 1) + { + /* We may need to skip over some bits in the interrupt register (without + * incrementing the irq value. + */ + + if ((valid & bit) != 0) + { + /* This is a real interrupt bit -- Check if an unmasked interrupt + * is pending. + */ + + if ((pending & bit) != 0) + { + /* Yes.. clear the pending interrupt by writing '1' to the + * flags registers. + */ + + putreg8(bit, base+HCS12_PIM_IF_OFFSET); + + /* Re-deliver the IRQ (recurses! We got here from irq_dispatch!) */ + + irq_dispatch(irq, context); + + /* Remove this from the set of pending interrupts */ + + pending &= ~bit; + } + + /* Bump up the IRQ number for the next pass through the loop */ + + irq++; + } + } + return OK; +} + +#ifdef CONFIG_HCS12_PORTG_INTS +static int hcs12_pginterrupt(int irq, void *context) +{ + return hcs12_interrupt(HCS12_PIM_PORTG_BASE, HCS12_IRQ_PG0, + HCS12_IRQ_PGSET, context); +} +#endif + +#ifdef CONFIG_HCS12_PORTH_INTS +static int hcs12_phinterrupt(int irq, void *context) +{ + return hcs12_interrupt(HCS12_PIM_PORTH_BASE, HCS12_IRQ_PH0, + HCS12_IRQ_PHSET, context); +} +#endif + +#ifdef CONFIG_HCS12_PORTJ_INTS +static int hcs12_pjinterrupt(int irq, void *context) +{ + return hcs12_interrupt(HCS12_PIM_PORTJ_BASE, HCS12_IRQ_PJ0, + HCS12_IRQ_PJSET, context); +} +#endif +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hcs12_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + * + ****************************************************************************/ + +void hcs12_gpioirqinitialize(void) +{ + /* Disable all GPIO IRQs -- Ports G, H, and J */ + + putreg8(0, HCS12_PIM_PORTG_IE); + putreg8(0, HCS12_PIM_PORTH_IE); + putreg8(0, HCS12_PIM_PORTJ_IE); + + /* Attach GPIO IRQ interrupt handlers */ + +#ifdef CONFIG_GPIO_IRQ +# ifdef CONFIG_HCS12_PORTG_INTS + irq_attach(HCS12_IRQ_VPORTG, hcs12_pginterrupt); +# endif +# ifdef CONFIG_HCS12_PORTH_INTS + irq_attach(HCS12_IRQ_VPORTH, hcs12_phinterrupt); +# endif +# ifdef CONFIG_HCS12_PORTJ_INTS + irq_attach(HCS12_IRQ_VPORTJ, hcs12_pjinterrupt); +# endif +#endif /* CONFIG_GPIO_IRQ */ +} + +/**************************************************************************** + * Name: hcs12_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void hcs12_gpioirqenable(int irq) +{ + uint16_t regaddr; + uint8_t pin; + + if (hcs12_mapirq(irq, ®addr, &pin) == OK) + { + irqstate_t flags = enter_critical_section(); + uint8_t regval = getreg8(regaddr); + regval |= (1 << pin); + putreg8(regval, regaddr); + leave_critical_section(flags); + } +} +#endif /* CONFIG_GPIO_IRQ */ + +/**************************************************************************** + * Name: hcs12_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void hcs12_gpioirqdisable(int irq) +{ + uint16_t regaddr; + uint8_t pin; + + if (hcs12_mapirq(irq, ®addr, &pin) == OK) + { + irqstate_t flags = enter_critical_section(); + uint8_t regval = getreg8(regaddr); + regval &= ~(1 << pin); + putreg8(regval, regaddr); + leave_critical_section(flags); + } +} +#endif /* CONFIG_GPIO_IRQ */ + diff --git a/arch/hc/src/m9s12/m9s12_iic.h b/arch/hc/src/m9s12/m9s12_iic.h new file mode 100644 index 0000000000000000000000000000000000000000..710bb309279101fd1774d26c5846007e9ff6a9f3 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_iic.h @@ -0,0 +1,108 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_iic.h (v2) + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S124_M9S124_IIC_H +#define __ARCH_ARM_HC_SRC_M9S124_M9S124_IIC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_IIC_IBAD_OFFSET 0x0000 /* IIC Address Register */ +#define HCS12_IIC_IBFD_OFFSET 0x0001 /* IIC Frequency Divider Register */ +#define HCS12_IIC_IBCR_OFFSET 0x0002 /* IIC Control Register */ +#define HCS12_IIC_IBSR_OFFSET 0x0003 /* IIC Status Register */ +#define HCS12_IIC_IBDR_OFFSET 0x0004 /* IIC Data I/O Register */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_IIC_IBAD (HCS12_IIC_BASE+HCS12_IIC_IBAD_OFFSET) +#define HCS12_IIC_IBFD (HCS12_IIC_BASE+HCS12_IIC_IBFD_OFFSET) +#define HCS12_IIC_IBCR (HCS12_IIC_BASE+HCS12_IIC_IBCR_OFFSET) +#define HCS12_IIC_IBSR (HCS12_IIC_BASE+HCS12_IIC_IBSR_OFFSET) +#define HCS12_IIC_IBDR (HCS12_IIC_BASE+HCS12_IIC_IBDR_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* IIC Address Register */ + +#define IIC_IBAD_MASK (0xfe) + +/* IIC Frequency Divider Register -- 8-bit bus clock rate value */ + +/* IIC Control Register */ + +#define IIC_IBCR_IBSWAI (1 << 0) /* Bit 0: I Bus Interface Stop in Wait Mode */ +#define IIC_IBCR_RSTA (1 << 2) /* Bit 2: Repeat Start */ +#define IIC_IBCR_TXAK (1 << 3) /* Bit 3: Transmit Acknowledge Enable— */ +#define IIC_IBCR_TX (1 << 4) /* Bit 4: Transmit/Receive Mode Select Bit */ +#define IIC_IBCR_MSSL (1 << 5) /* Bit 5: Master/Slave Mode Select Bit— */ +#define IIC_IBCR_IBIE (1 << 6) /* Bit 6: I-Bus Interrupt Enable */ +#define IIC_IBCR_IBEN (1 << 7) /* Bit 7: I-Bus Enable */ + +/* IIC Status Register */ + +#define IIC_IBSR_RXAK (1 << 0) /* Bit 0: Received Acknowledge */ +#define IIC_IBSR_IBIF (1 << 1) /* Bit 1: I-Bus Interrupt */ +#define IIC_IBSR_SRW (1 << 2) /* Bit 2: Slave Read/Write */ +#define IIC_IBSR_AL (1 << 4) /* Bit 4: Arbitration Lost */ +#define IIC_IBSR_BB (1 << 5) /* Bit 5: Bus Busy Bit */ +#define IIC_IBSR_AAS (1 << 6) /* Bit 6: Addressed as a Slave Bit */ +#define IIC_IBSR_TCF (1 << 7) /* Bit 7: Data Transferring Bit */ + +/* IIC Data I/O Register -- 8-Bit data value */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S124_M9S124_IIC_H */ diff --git a/arch/hc/src/m9s12/m9s12_initialstate.c b/arch/hc/src/m9s12/m9s12_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..678b26c902d7be2b927595c9a91ae58739f0690f --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_initialstate.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_initialstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer */ + + xcp->regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8; + xcp->regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff; + + /* Save the task entry point */ + + xcp->regs[REG_PCH] = (uint16_t)tcb->start >> 8; + xcp->regs[REG_PCL] = (uint16_t)tcb->start & 0xff; + +#ifndef CONFIG_HCS12_NONBANKED + /* Can only directly start in PPAGE 0x30 */ + + xcp->regs[REG_PPAGE] = 0x30; +#endif + + /* Condition code register: + * + * Bit 0: C — Carry/Borrow status bit + * Bit 1: V — Two’s complement overflow status bit + * Bit 2: Z — Zero status bit + * Bit 3: N — Negative status bit + * Bit 4: I — Maskable interrupt control bit + * Bit 5: H — Half-carry status bit + * Bit 6: X — Non-maskable interrupt control bit + * Bit 7: S — STOP instruction control bit + */ + +# ifdef CONFIG_SUPPRESS_INTERRUPTS + /* Disable STOP, Mask I- and Z- interrupts */ + + xcp->regs[REG_CCR] = HCS12_CCR_S|HCS12_CCR_X|HCS12_CCR_I; +# else + /* Disable STOP, Enable I- and Z-interrupts */ + + xcp->regs[REG_CCR] = HCS12_CCR_S; +# endif +} + diff --git a/arch/hc/src/m9s12/m9s12_int.h b/arch/hc/src/m9s12/m9s12_int.h new file mode 100644 index 0000000000000000000000000000000000000000..b0110f7a6ad6ec71980fe82f2a5c3305cd68064e --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_int.h @@ -0,0 +1,103 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_int.h (v1) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_INT_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_INT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ +/* Offsets relative to CORE1 */ + +#define HCS12_INT_ITCR_OFFSET 0x0015 /* Interrupt Test Control Register */ +#define HCS12_INT_ITEST_OFFSET 0x0016 /* Interrupt Test Registers */ + +/* Offsets relative to CORE2 */ + +#define HCS12_INT_HPRIO_OFFSET 0x0003 /* Highest Priority Interrupt */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_INT_ITCR (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_INT_ITCR_OFFSET) +#define HCS12_INT_ITEST (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_INT_ITEST_OFFSET) +#define HCS12_INT_HPRIO (HCS12_REG_BASE+HCS12_CORE2_BASE+HCS12_INT_HPRIO_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Interrupt Test Control Register Bit-Field Definitions */ + +#define INT_ITCR_ADR_SHIFT (0) /* Bits 0-3: Test register select */ +#define INT_ITCR_ADR_MASK (15 << INT_ITCR_ADR_SHIFT) +#define INT_ITCR_WRTINT (1 << 4) /* Bit 4: Write to the Interrupt Test Registers */ + +/* Interrupt Test Registers Bit-Field Definitions */ + +#define INT_ITEST_INT(n) (1 << ((n) >> 1)) +#define INT_ITEST_INT0 (1 << 0) /* Bit 0: Test vector 0xffx0 */ +#define INT_ITEST_INT2 (1 << 1) /* Bit 1: Test vector 0xffx2 */ +#define INT_ITEST_INT4 (1 << 2) /* Bit 2: Test vector 0xffx4 */ +#define INT_ITEST_INT6 (1 << 3) /* Bit 3: Test vector 0xffx6 */ +#define INT_ITEST_INT8 (1 << 4) /* Bit 4: Test vector 0xffx8 */ +#define INT_ITEST_INTA (1 << 5) /* Bit 5: Test vector 0xffxa */ +#define INT_ITEST_INTC (1 << 6) /* Bit 6: Test vector 0xffxc */ +#define INT_ITEST_INTE (1 << 7) /* Bit 7: Test vector 0xffxe */ + +/* Highest Priority Interrupt Bit-Field Definitions */ +/* Holds the least of the highest priority interrupt vector address */ + +#define INT_HPRIO_MASK (0xfe) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_INT_H */ diff --git a/arch/hc/src/m9s12/m9s12_irq.c b/arch/hc/src/m9s12/m9s12_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..a91c270f099f2927e1b1d2eac477011f93458119 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_irq.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/m9s12/m9s12_irq.c + * arch/arm/src/chip/m9s12_irq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "m9s12.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint8_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_GPIO_IRQ + hcs12_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(0); +#endif +} diff --git a/arch/hc/src/m9s12/m9s12_lowputc.S b/arch/hc/src/m9s12/m9s12_lowputc.S new file mode 100644 index 0000000000000000000000000000000000000000..1b363435e9ac2b8ef2ffe8fad2b9d1941717f45f --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_lowputc.S @@ -0,0 +1,225 @@ +/************************************************************************** + * arch/arm/src/m9s12/m9s12_lowputc.S + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include "up_internal.h" +#include "m9s12.h" +#include "m9s12_sci.h" +#include "m9s12_serial.h" + +#ifdef CONFIG_HCS12_SERIALMON +# include "m9s12_flash.h" +#endif + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +#ifdef CONFIG_HCS12_NONBANKED +# define CALL jsr +# define RETURN rts +#else +# define CALL call +# define RETURN rtc +#endif + +/* Select SCI parameters for the selected console */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) +# define HCS12_CONSOLE_BASE HCS12_SCI0_BASE +# define HCS12_CONSOLE_BAUD CONFIG_SCI0_BAUD +# define HCS12_CONSOLE_BITS CONFIG_SCI0_BITS +# define HCS12_CONSOLE_PARITY CONFIG_SCI0_PARITY +# define HCS12_CONSOLE_2STOP CONFIG_SCI0_2STOP +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) +# define HCS12_CONSOLE_BASE HCS12_SCI1_BASE +# define HCS12_CONSOLE_BAUD CONFIG_SCI1_BAUD +# define HCS12_CONSOLE_BITS CONFIG_SCI1_BITS +# define HCS12_CONSOLE_PARITY CONFIG_SCI1_PARITY +# define HCS12_CONSOLE_2STOP CONFIG_SCI1_2STOP +#else +# warning "No CONFIG_SCIn_SERIAL_CONSOLE Setting" +#endif + +/* Selete the SCIBR register value */ + +#define CONSOLE_SCIBR_VALUE SCIBR_VALUE(HCS12_CONSOLE_BAUD) + +/* Select the SCICR1 register settings */ + +#if HCS12_CONSOLE_BITS == 9 +# define UART_SCICR1_NBITS SCI_CR1_M +#elif HCS12_CONSOLE_BITS == 8 +# define UART_SCICR1_NBITS 0 +#else +# warning "Number of bits not supported" +#endif + +#if HCS12_CONSOLE_PARITY == 0 +# define UART_SCICR1_PARITY 0 +#elif HCS12_CONSOLE_PARITY == 1 +# define UART_SCICR1_PARITY SCI_CR1_PE +#elif HCS12_CONSOLE_PARITY == 2 +# define UART_SCICR1_PARITY (SCI_CR1_PE|SCI_CR1_PT) +#else +# error "ERROR: Invalid parity selection" +#endif + +#if HCS12_CONSOLE_2STOP != 0 +# warning "Only a single stop bit supported" +#endif + +#define CONSOLE_SCICR_VALUE (UART_SCICR1_NBITS|UART_SCICR1_PARITY) + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_lowsetup + * + * Note: This function is called from the boot logic very early in the + * initialization sequence: After the stack pointer has been setup, but + * before .bss has been cleared and .data initialized. + * + **************************************************************************/ + + .text + .globl up_lowsetup + .type up_lowsetup, function +up_lowsetup: +#ifdef HAVE_SERIAL_CONSOLE +#ifndef CONFIG_HCS12_SERIALMON + + /* Disable the console */ + + ldab #0 + stab (HCS12_CONSOLE_BASE+HCS12_SCI_CR1_OFFSET) + stab (HCS12_CONSOLE_BASE+HCS12_SCI_CR2_OFFSET) + + /* Set the BAUD pre-scaler value */ + + ldab #(CONSOLE_SCIBR_VALUE >> 8) + stab (HCS12_CONSOLE_BASE+HCS12_SCI_BDH_OFFSET) + + ldab #(CONSOLE_SCIBR_VALUE & 0xff) + stab (HCS12_CONSOLE_BASE+HCS12_SCI_BDL_OFFSET) + + /* Set number of bits, parity, stop bits, etc. */ + + ldab #CONSOLE_SCICR_VALUE + stab (HCS12_CONSOLE_BASE+HCS12_SCI_CR1_OFFSET) + + /* Enable transmitter and receiver */ + + ldab #(SCI_CR2_RE|SCI_CR2_TE) + stab (HCS12_CONSOLE_BASE+HCS12_SCI_CR2_OFFSET) + +#endif /* CONFIG_HCS12_SERIALMON */ +#endif /* HAVE_SERIAL_CONSOLE */ + RETURN + .size up_lowsetup, . - up_lowsetup + +/************************************************************************** + * Name: up_lowputc + **************************************************************************/ + + .text + .global up_lowputc + .type up_lowputc, function +up_lowputc: +#ifdef HAVE_SERIAL_CONSOLE +#ifdef CONFIG_HCS12_SERIALMON + jmp PutChar +#else +#if HCS12_CONSOLE_BITS == 9 + staa 1, -sp +#endif /* HCS12_CONSOLE_BITS == 9 */ + + /* Wait for the transmit data register to be available (TRDE==1) */ + +.Lwait: + ldaa (HCS12_CONSOLE_BASE+HCS12_SCI_SR1_OFFSET) + bita #SCI_SR1_TDRE + bne .Lwait + + /* Then write the byte to the transmit data register */ + +#if HCS12_CONSOLE_BITS == 9 + ldaa 1, sp+ + bita #(0x01) + bne .L8bit + ldaa #SCI_DRH_T8 + bra .Lwrdrh +.L8bit: + ldaa #0 +.Lwrdrh: + staa (HCS12_CONSOLE_BASE+HCS12_SCI_DRH_OFFSET) +#endif /* HCS12_CONSOLE_BITS == 9 */ + + stab (HCS12_CONSOLE_BASE+HCS12_SCI_DRL_OFFSET) + RETURN + +#endif /* !CONFIG_HCS12_SERIALMON */ +#else + RETURN +#endif /* HAVE_SERIAL_CONSOLE */ + .size up_lowputc, . - up_lowputc + .end diff --git a/arch/hc/src/m9s12/m9s12_mebi.h b/arch/hc/src/m9s12/m9s12_mebi.h new file mode 100644 index 0000000000000000000000000000000000000000..34d251ded133fff8902bb08ef8091a9d3fd09c56 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_mebi.h @@ -0,0 +1,166 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_mebi.h (v3) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_MEBI_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_MEBI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ +/* Offsets relative to CORE1 */ + +#define HCS12_MEBI_PORTA_OFFSET 0x0000 /* Port A Data Register */ +#define HCS12_MEBI_PORTB_OFFSET 0x0001 /* Port B Data Register */ +#define HCS12_MEBI_DDRA_OFFSET 0x0002 /* Data Direction Register A */ +#define HCS12_MEBI_DDRB_OFFSET 0x0003 /* Data Direction Register B */ +#define HCS12_MEBI_PORTE_OFFSET 0x0008 /* Port E Data Register */ +#define HCS12_MEBI_DDRE_OFFSET 0x0009 /* Data Direction Register E */ +#define HCS12_MEBI_PEAR_OFFSET 0x000a /* Port E Assignment Register */ +#define HCS12_MEBI_MODE_OFFSET 0x000b /* Mode Register */ +#define HCS12_MEBI_PUCR_OFFSET 0x000c /* Pull Control Register */ +#define HCS12_MEBI_RDRIV_OFFSET 0x000d /* Reduced Drive Register */ +#define HCS12_MEBI_EBICTL_OFFSET 0x000e /* External Bus Interface Control Register */ + +/* Offsets relative to CORE2 */ + +#define HCS12_MEBI_IRQCR_OFFSET 0x0002 /* IRQ Control Register */ + +/* Offsets relative to CORE4 */ + +#define HCS12_MEBI_PORTK_OFFSET 0x0002 /* Port K Data Register */ +#define HCS12_MEBI_DDRK_OFFSET 0x0003 /* Data Direction Register K */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_MEBI_PORTA (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_PORTA_OFFSET) +#define HCS12_MEBI_PORTB (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_PORTB_OFFSET) +#define HCS12_MEBI_DDRA (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_DDRA_OFFSET) +#define HCS12_MEBI_DDRB (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_DDRB_OFFSET) +#define HCS12_MEBI_PORTE (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_PORTE_OFFSET) +#define HCS12_MEBI_DDRE (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_DDRE_OFFSET) +#define HCS12_MEBI_PEAR (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_PEAR_OFFSET) +#define HCS12_MEBI_MODE (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_MODE_OFFSET) +#define HCS12_MEBI_PUCR (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_PUCR_OFFSET) +#define HCS12_MEBI_RDRIV (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_RDRIV_OFFSET) +#define HCS12_MEBI_EBICTL (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MEBI_EBICTL_OFFSET) +#define HCS12_MEBI_IRQCR (HCS12_REG_BASE+HCS12_CORE2_BASE+HCS12_MEBI_IRQCR_OFFSET) +#define HCS12_MEBI_PORTK (HCS12_REG_BASE+HCS12_CORE4_BASE+HCS12_MEBI_PORTK_OFFSET) +#define HCS12_MEBI_DDRK (HCS12_REG_BASE+HCS12_CORE4_BASE+HCS12_MEBI_DDRK_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Port A Data Register Bit-Field Definitions */ +/* Port B Data Register Bit-Field Definitions */ +/* Data Direction Register A Bit-Field Definitions */ +/* Data Direction Register B Bit-Field Definitions */ +/* Port E Data Register Bit-Field Definitions */ +/* Data Direction Register E Bit-Field Definitions */ +/* Port K Data Register Bit-Field Definitions */ +/* Data Direction Register K Bit-Field Definitions */ + +#define MEBI_PIN(n) (1 << (n)) +#define MEBI_PIN0 (1 << 0) +#define MEBI_PIN1 (1 << 1) +#define MEBI_PIN2 (1 << 2) +#define MEBI_PIN3 (1 << 3) +#define MEBI_PIN4 (1 << 4) +#define MEBI_PIN5 (1 << 5) +#define MEBI_PIN6 (1 << 6) +#define MEBI_PIN7 (1 << 7) + +/* Port E Assignment Register Bit-Field Definitions */ + +#define MEBI_PEAR_RDWE (1 << 2) /* Bit 2: Read/Write Enable */ +#define MEBI_PEAR_LSTRE (1 << 3) /* Bit 3: Low Strobe (~LSTRB) Enable */ +#define MEBI_PEAR_NECLK (1 << 4) /* Bit 4: No External E Clock */ +#define MEBI_PEAR_PIPOE (1 << 5) /* Bit 5: Pipe Status Signal Output Enable */ +#define MEBI_PEAR_NOACCE (1 << 7) /* Bit 7: CPU No Access Output Enable */ + +/* Mode Register Bit-Field Definitions */ + +#define MEBI_MODE_EME (1 << 0) /* Bit 0: Emulate Port E */ +#define MEBI_MODE_EMK (1 << 1) /* Bit 1: Emulate Port K */ +#define MEBI_MODE_IVIS (1 << 3) /* Bit 3: Internal Visibility */ +#define MEBI_MODE_MOD_SHIFT (5) /* Bits 5-7: Mode Select */ +#define MEBI_MODE_MOD_MASK (7 << MEBI_MODE_MOD_SHIFT) +# define MEBI_MODE_MODA (1 << MEBI_MODE_MOD_SHIFT) +# define MEBI_MODE_MODB (2 << MEBI_MODE_MOD_SHIFT) +# define MEBI_MODE_MODC (4 << MEBI_MODE_MOD_SHIFT) + +/* Pull Control Register Bit-Field Definitions */ + +#define MEBI_PUCR_PUPAE (1 << 0) /* Bit 0: Pull resistors Port A Enable */ +#define MEBI_PUCR_PUPBE (1 << 1) /* Bit 1: Pull resistors Port B Enable */ +#define MEBI_PUCR_PUPEE (1 << 4) /* Bit 4: Pull resistors Port E Enable */ +#define MEBI_PUCR_PUPKE (1 << 7) /* Bit 7: Pull resistors Port K Enable */ + +/* Reduced Drive Register Bit-Field Definitions */ + +#define MEBI_RDRIV_RDPA (1 << 0) /* Bit 0: Reduced Drive of Port A */ +#define MEBI_RDRIV_RDPB (1 << 1) /* Bit 1: Reduced Drive of Port B */ +#define MEBI_RDRIV_RDPE (1 << 4) /* Bit 4: Reduced Drive of Port E */ +#define MEBI_RDRIV_RDRK (1 << 7) /* Bit 7: Reduced Drive of Port K */ + +/* External Bus Interface Control Register Bit-Field Definitions */ + +#define MEBI_EBICTL_ESTR (1 << 0) /* Bit 0: E Clock Stretches */ + +/* IRQ Control Register Bit-Field Definitions */ + +#define MEBI_IRQCR_IRQEN (1 << 6) /* Bit 6: External IRQ Enable */ +#define MEBI_IRQCR_IRQE (1 << 7) /* Bit 7: IRQ Select Edge Sensitive Only */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_MEBI_H */ diff --git a/arch/hc/src/m9s12/m9s12_mmc.h b/arch/hc/src/m9s12/m9s12_mmc.h new file mode 100644 index 0000000000000000000000000000000000000000..0e4b050b85667b9533d790f53591f534e559f19b --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_mmc.h @@ -0,0 +1,168 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_mmcv4.h (v4) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_MMC_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_MMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ +/* Offsets relative to CORE1 */ + +#define HCS12_MMC_INITRM_OFFSET 0x0010 /* Internal RAM Position Register */ +#define HCS12_MMC_INITRG_OFFSET 0x0011 /* Internal Registers Position Register */ +#define HCS12_MMC_INITEE_OFFSET 0x0012 /* Internal EEPROM Position Register */ +#define HCS12_MMC_MISC_OFFSET 0x0013 /* Miscellaneous System Control Register */ +#define HCS12_MMC_MTST0_OFFSET 0x0014 /* Reserved Test Register 0 */ +#define HCS12_MMC_MTST1_OFFSET 0x0017 /* Reserved Test Register 1 */ + +/* Offsets relative to CORE2 */ + +#define HCS12_MMC_MEMSIZ0_OFFSET 0x0000 /* Memory Size Register 0 */ +#define HCS12_MMC_MEMSIZ1_OFFSET 0x0001 /* Memory Size Register 1 */ + +/* Offsets relative to CORE4 */ + +#define HCS12_MMC_PPAGE_OFFSET 0x0000 /* Program Page Index Register */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_MMC_INITRM (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_INITRM_OFFSET) +#define HCS12_MMC_INITRG (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_INITRG_OFFSET) +#define HCS12_MMC_INITEE (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_INITEE_OFFSET) +#define HCS12_MMC_MISC (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_MISC_OFFSET) +#define HCS12_MMC_MTST0 (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_MTST0_OFFSET) +#define HCS12_MMC_MTST1 (HCS12_REG_BASE+HCS12_CORE1_BASE+HCS12_MMC_MTST1_OFFSET) +#define HCS12_MMC_MEMSIZ0 (HCS12_REG_BASE+HCS12_CORE2_BASE+HCS12_MMC_MEMSIZ0_OFFSET) +#define HCS12_MMC_MEMSIZ1 (HCS12_REG_BASE+HCS12_CORE2_BASE+HCS12_MMC_MEMSIZ1_OFFSET) +#define HCS12_MMC_PPAGE (HCS12_REG_BASE+HCS12_CORE4_BASE+HCS12_MMC_PPAGE_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Internal RAM Position Register Bit-Field Definitions */ + +#define MMC_INITRM_RAMHAL (1 << 0) /* Bit 0: RAM High-Align */ +#define MMC_INITRM_RAM_SHIFT (3) /* Bits 3-7: Internal RAM Map Position */ +#define MMC_INITRM_RAM_MASK (0x1f << MMC_INITRM_RAM_SHIFT) +#define MMC_INITRM_RAM(addr) (((addr) >> (11-MMC_INITRM_RAM_SHIFT)) & MMC_INITRM_RAM_MASK) + +/* Internal Registers Position Register Bit-Field Definitions */ + +#define MMC_INITRG_REG_SHIFT (3) /* Bits 3-6: Internal RAM Map Position */ +#define MMC_INITRG_REG_MASK (0x0f << MMC_INITRG_REG_SHIFT) +#define MMC_INITRG_REG(addr) (((addr) >> (11-MMC_INITRG_REG_SHIFT)) & MMC_INITRG_REG_SHIFT) + +/* Internal EEPROM Position Register Bit-Field Definitions */ + +#define MMC_INITEE_EEON (1 << 0) /* Bit 0: Enable EEPROM */ +#define MMC_INITEE_EE_SHIFT (3) /* Bits 3-7: Internal EEPROM Map Position */ +#define MMC_INITEE_EE_MASK (0x1f << MMC_INITEE_EE_SHIFT) +#define MMC_INITEE_EE(addr) (((addr) >> (11-MMC_INITRG_REG_SHIFT)) & MMC_INITRG_REG_SHIFT) + +/* Miscellaneous System Control Register Bit-Field Definitions */ + +#define MMC_MISC_ROMON (1 << 0) /* Bit 0: Enable FLASH EEPROM or ROM */ +#define MMC_MISC_ROMHM (1 << 1) /* Bit 1: FLASH EEPROM or ROM Only in Second Half of Memory Map */ +#define MMC_MISC_EXSTR_SHIFT (2) /* Bits 2-3: External Access Stretch Bits */ +#define MMC_MISC_EXSTR_MASK (3 << MMC_MISC_EXSTR_SHIFT) +# define MISC_EXSTR_CLKS0 (0 << MMC_MISC_EXSTR_SHIFT) +# define MISC_EXSTR_CLKS1 (1 << MMC_MISC_EXSTR_SHIFT) +# define MISC_EXSTR_CLKS2 (2 << MMC_MISC_EXSTR_SHIFT) +# define MISC_EXSTR_CLKS3 (3 << MMC_MISC_EXSTR_SHIFT) + +/* Reserved Test Register 0/1 Bit-Field Definitions -- Not documented */ + +/* Memory Size Register 0 Bit-Field Definitions */ + +#define MMC_MEMSIZ0_RAMSW_SHIFT (0) /* Bits 0-2: Allocated System RAM Memory Space */ +#define MMC_MEMSIZ0_RAMSW_MASK (7 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_2KB (0 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_4KB (1 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_6KB (2 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_8KB (3 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_10KB (4 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_12KB (5 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_14KB (6 << MMC_MEMSIZ0_RAMSW_SHIFT) +# define MEMSIZ0_RAMSW_16KB (7 << MMC_MEMSIZ0_RAMSW_SHIFT) +#define MMC_MEMSIZ0_EEPSW_SHIFT (4) /* Bits 4-5: Allocated EEPROM Memory Space */ +#define MMC_MEMSIZ0_EEPSW_MASK (3 << MMC_MEMSIZ0_EEPSW_SHIFT) +# define MEMSIZ0_EEPSW_OKB (0 << MMC_MEMSIZ0_EEPSW_MASK) +# define MEMSIZ0_EEPSW_2KB (1 << MMC_MEMSIZ0_EEPSW_MASK) +# define MEMSIZ0_EEPSW_4KB (2 << MMC_MEMSIZ0_EEPSW_MASK) +# define MEMSIZ0_EEPSW_5KB (3 << MMC_MEMSIZ0_EEPSW_MASK) +#define MMC_MEMSIZ0_REGSW (1 << 7) /* Bits 7: Allocated System Register Space */ + +/* Memory Size Register 1 Bit-Field Definitions */ + +#define MMC_MEMSIZ1_PAGSW_SHIFT (0) /* Bits 0-1: Allocated System RAM Memory Space */ +#define MMC_MEMSIZ1_PAGSW_MASK (3 << MMC_MEMSIZ1_PAGSW_SHIFT) +# define MEMSIZ1_PAGSW_128KB (0 << MMC_MEMSIZ1_PAGSW_SHIFT) +# define MEMSIZ1_PAGSW_256KB (1 << MMC_MEMSIZ1_PAGSW_SHIFT) +# define MEMSIZ1_PAGSW_512KB (2 << MMC_MEMSIZ1_PAGSW_SHIFT) +# define MEMSIZ1_PAGSW_1MB (3 << MMC_MEMSIZ1_PAGSW_SHIFT) +#define MMC_MEMSIZ1_ROMSW_SHIFT (6) /* Bits 6-7: Allocated System RAM Memory Space */ +#define MMC_MEMSIZ1_ROMSW_MASK (3 << MMC_MEMSIZ1_ROMSW_SHIFT) +# define MEMSIZ1_ROMSW_0KB (0 << MMC_MEMSIZ1_ROMSW_SHIFT) +# define MEMSIZ1_ROMSW_16KB (1 << MMC_MEMSIZ1_ROMSW_SHIFT) +# define MEMSIZ1_ROMSW_48KB (2 << MMC_MEMSIZ1_ROMSW_SHIFT) +# define MEMSIZ1_ROMSW_64KB (3 << MMC_MEMSIZ1_ROMSW_SHIFT) + +/* Program Page Index Register Bit-Field Definitions */ + +#define MMC_PPAGE_PIX_SHIFT (0) /* Bits 0-5 Program Page Index Bits 5–0 */ +#define MMC_PPAGE_PIX_MASK (0x3f << MMC_PPAGE_PIX_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_MMC_H */ diff --git a/arch/hc/src/m9s12/m9s12_phy.h b/arch/hc/src/m9s12/m9s12_phy.h new file mode 100644 index 0000000000000000000000000000000000000000..f6a142b1f70ec22addccde2a73a155606269f36e --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_phy.h @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_phyv2.h (v2) + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_PHY_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_PHY_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_PHY_EPHYCTL0_OFFSET 0x0000 /* Ethernet Physical Transceiver Control Register 0 */ +#define HCS12_PHY_EPHYCTL1_OFFSET 0x0001 /* Ethernet Physical Transceiver Control Register 1 */ +#define HCS12_PHY_EPHYSR_OFFSET 0x0002 /* Ethernet Physical Transceiver Status Register */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_PHY_EPHYCTL0 (HCS12_EPHY_BASE+HCS12_PHY_EPHYCTL0_OFFSET) +#define HCS12_PHY_EPHYCTL1 (HCS12_EPHY_BASE+HCS12_PHY_EPHYCTL1_OFFSET) +#define HCS12_PHY_EPHYSR (HCS12_EPHY_BASE+HCS12_PHY_EPHYSR_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Ethernet Physical Transceiver Control Register 0 */ + +#define PHY_EPHYCTL0_EPHYIEN (1 << 0) /* Bit 0: EPHY Interrupt Enable */ +#define PHY_EPHYCTL0_EPHYWAI (1 << 2) /* Bit 2: EPHY Module Stops While in Wait */ +#define PHY_EPHYCTL0_LEDEN (1 << 3) /* Bit 3: LED Drive Enable */ +#define PHY_EPHYCTL0_DIS10 (1 << 4) /* Bit 4: Disable 10BASE-T PLL */ +#define PHY_EPHYCTL0_DIS100 (1 << 5) /* Bit 5: Disable 100 BASE-TX PLL */ +#define PHY_EPHYCTL0_ANDIS (1 << 6) /* Bit 6: Auto Negotiation Disable */ +#define PHY_EPHYCTL0_EPHYEN (1 << 7) /* Bit 7: EPHY Enable */ + +/* Ethernet Physical Transceiver Control Register 1 */ + +#define PHY_EPHYCTL1_PHYADD_SHIFT (0) /* Bits 0-4: EPHY Address for MII Requests */ +#define PHY_EPHYCTL1_PHYADD_MASK (0x1f) + +/* Ethernet Physical Transceiver Status Register */ + +#define PHY_EPHYSR_EPHYI (1 << 0) /* Bit 0: EPHY Interrupt Flag */ +#define PHY_EPHYSR_10DIS (1 << 4) /* Bit 4: EPHY Port 10BASE-T mode status */ +#define PHY_EPHYSR_100DIS (1 << 5) /* Bit 5: EPHY Port 100BASE-TX mode status */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_PHY_H */ diff --git a/arch/hc/src/m9s12/m9s12_pim.h b/arch/hc/src/m9s12/m9s12_pim.h new file mode 100644 index 0000000000000000000000000000000000000000..1424a67fdbe5732ac31561b9582b2fd1bd006156 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_pim.h @@ -0,0 +1,248 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_pim.h + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_PIM_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_PIM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ +/* Friendly names for ports */ + +#define PIM_PORTT (0) +#define PIM_PORTS (1) +#define PIM_PORTG (2) +#define PIM_PORTH (3) +#define PIM_PORTJ (4) +#define PIM_PORTL (5) + +/* Port register block offsets */ + +#define HCS12_PIM_PORT_OFFSET(n) (HCS12_PIM_BASE + ((n) << 3)) +#define HCS12_PIM_PORTT_OFFSET (0x0000) +#define HCS12_PIM_PORTS_OFFSET (0x0008) +#define HCS12_PIM_PORTG_OFFSET (0x0010) +#define HCS12_PIM_PORTH_OFFSET (0x0018) +#define HCS12_PIM_PORTJ_OFFSET (0x0020) +#define HCS12_PIM_PORTL_OFFSET (0x0028) + +/* Register offsets within a port register block */ + +#define HCS12_PIM_IO_OFFSET (0x0000) /* I/O Register (ALL) */ +#define HCS12_PIM_INPUT_OFFSET (0x0001) /* Input Register (ALL) */ +#define HCS12_PIM_DDR_OFFSET (0x0002) /* Data Direction Register (ALL) */ +#define HCS12_PIM_RDR_OFFSET (0x0003) /* Reduced Drive Register (ALL) */ +#define HCS12_PIM_PER_OFFSET (0x0004) /* Pull Device Enable Register (ALL) */ +#define HCS12_PIM_PS_OFFSET (0x0005) /* Polarity Select Register (ALL) */ +#define HCS12_PIM_WOM_OFFSET (0x0006) /* Wired OR Mode Register (PORT S and L) */ +#define HCS12_PIM_IE_OFFSET (0x0006) /* Interrupt Enable Register (PORT G, H, and J) */ +#define HCS12_PIM_IF_OFFSET (0x0007) /* Interrupt Flag Register (PORT G, H, and J) */ + +/* Register Addresses ***************************************************************/ +/* Port register block addresses */ + +#define HCS12_PIM_PORT_BASE(n) (HCS12_PIM_BASE + HCS12_PIM_PORT_OFFSET(n)) +#define HCS12_PIM_PORTT_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTT_OFFSET) +#define HCS12_PIM_PORTS_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTS_OFFSET) +#define HCS12_PIM_PORTG_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTG_OFFSET) +#define HCS12_PIM_PORTH_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTH_OFFSET) +#define HCS12_PIM_PORTJ_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTJ_OFFSET) +#define HCS12_PIM_PORTL_BASE (HCS12_PIM_BASE + HCS12_PIM_PORTL_OFFSET) + +/* Port register addresses */ + +#define HCS12_PIM_PORT_IO(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORT_INPUT(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORT_DDR(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORT_RDR(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORT_PER(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORT_PS(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORT_WOM(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_WOM_OFFSET) +#define HCS12_PIM_PORT_IE(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_IE_OFFSET) +#define HCS12_PIM_PORT_IF(n) (HCS12_PIM_PORT_BASE(n) + HCS12_PIM_IF_OFFSET) + +/* Port T register addresses */ + +#define HCS12_PIM_PORTT_IO (HCS12_PIM_PORTT_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTT_INPUT (HCS12_PIM_PORTT_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTT_DDR (HCS12_PIM_PORTT_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTT_RDR (HCS12_PIM_PORTT_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTT_PER (HCS12_PIM_PORTT_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTT_PS (HCS12_PIM_PORTT_BASE + HCS12_PIM_PS_OFFSET) + +/* Port S register addresses */ + +#define HCS12_PIM_PORTS_IO (HCS12_PIM_PORTS_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTS_INPUT (HCS12_PIM_PORTS_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTS_DDR (HCS12_PIM_PORTS_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTS_RDR (HCS12_PIM_PORTS_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTS_PER (HCS12_PIM_PORTS_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTS_PS (HCS12_PIM_PORTS_BASE + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORTS_WOM (HCS12_PIM_PORTS_BASE + HCS12_PIM_WOM_OFFSET) + +/* Port G register addresses */ + +#define HCS12_PIM_PORTG_IO (HCS12_PIM_PORTG_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTG_INPUT (HCS12_PIM_PORTG_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTG_DDR (HCS12_PIM_PORTG_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTG_RDR (HCS12_PIM_PORTG_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTG_PER (HCS12_PIM_PORTG_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTG_PS (HCS12_PIM_PORTG_BASE + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORTG_IE (HCS12_PIM_PORTG_BASE + HCS12_PIM_IE_OFFSET) +#define HCS12_PIM_PORTG_IF (HCS12_PIM_PORTG_BASE + HCS12_PIM_IF_OFFSET) + +/* Port H register addresses */ + +#define HCS12_PIM_PORTH_IO (HCS12_PIM_PORTH_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTH_INPUT (HCS12_PIM_PORTH_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTH_DDR (HCS12_PIM_PORTH_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTH_RDR (HCS12_PIM_PORTH_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTH_PER (HCS12_PIM_PORTH_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTH_PS (HCS12_PIM_PORTH_BASE + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORTH_IE (HCS12_PIM_PORTH_BASE + HCS12_PIM_IE_OFFSET) +#define HCS12_PIM_PORTH_IF (HCS12_PIM_PORTH_BASE + HCS12_PIM_IF_OFFSET) + +/* Port J register addresses */ + +#define HCS12_PIM_PORTJ_IO (HCS12_PIM_PORTJ_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTJ_INPUT (HCS12_PIM_PORTJ_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTJ_DDR (HCS12_PIM_PORTJ_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTJ_RDR (HCS12_PIM_PORTJ_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTJ_PER (HCS12_PIM_PORTJ_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTJ_PS (HCS12_PIM_PORTJ_BASE + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORTJ_IE (HCS12_PIM_PORTJ_BASE + HCS12_PIM_IE_OFFSET) +#define HCS12_PIM_PORTJ_IF (HCS12_PIM_PORTJ_BASE + HCS12_PIM_IF_OFFSET) + +/* Port L register addresses */ + +#define HCS12_PIM_PORTL_IO (HCS12_PIM_PORTL_BASE + HCS12_PIM_IO_OFFSET) +#define HCS12_PIM_PORTL_INPUT (HCS12_PIM_PORTL_BASE + HCS12_PIM_INPUT_OFFSET) +#define HCS12_PIM_PORTL_DDR (HCS12_PIM_PORTL_BASE + HCS12_PIM_DDR_OFFSET) +#define HCS12_PIM_PORTL_RDR (HCS12_PIM_PORTL_BASE + HCS12_PIM_RDR_OFFSET) +#define HCS12_PIM_PORTL_PER (HCS12_PIM_PORTL_BASE + HCS12_PIM_PER_OFFSET) +#define HCS12_PIM_PORTL_PS (HCS12_PIM_PORTL_BASE + HCS12_PIM_PS_OFFSET) +#define HCS12_PIM_PORTL_WOM (HCS12_PIM_PORTL_BASE + HCS12_PIM_WOM_OFFSET) + +/* Register Bit Definitions *********************************************************/ + +/* Port register bits (all ports) */ + +#define PIM_PIN(n) (1 << (n)) +#define PIM_PIN0 (1 << 0) +#define PIM_PIN1 (1 << 1) +#define PIM_PIN2 (1 << 2) +#define PIM_PIN3 (1 << 3) +#define PIM_PIN4 (1 << 4) +#define PIM_PIN5 (1 << 5) +#define PIM_PIN6 (1 << 6) +#define PIM_PIN7 (1 << 7) + +/* Port T I/O register aliases */ + +#define TIM_IOC4 PIM_PIN4 +#define TIM_IOC5 PIM_PIN5 +#define TIM_IOC6 PIM_PIN6 +#define TIM_IOC7 PIM_PIN7 + +/* Port S I/O register aliases */ + +#define SCI0_RXD PIM_PIN0 +#define SCI0_TXD PIM_PIN1 +#define SCI1_RXD PIM_PIN2 +#define SCI1_TXD PIM_PIN3 +#define SPI_MISO PIM_PIN4 +#define SPI_MOSI PIM_PIN5 +#define SPI_SCK PIM_PIN6 +#define SPI_SS PIM_PIN7 + +/* Port G I/O register aliases */ + +#define MII_RXD0 PIM_PIN0 +#define MII_RXD1 PIM_PIN1 +#define MII_RXD2 PIM_PIN2 +#define MII_RXD3 PIM_PIN3 +#define MII_RXCLK PIM_PIN4 +#define MII_RXDV PIM_PIN5 +#define MII_RXER PIM_PIN6 + +/* Port H I/O register aliases */ + +#define MII_TXD0 PIM_PIN0 +#define MII_TXD1 PIM_PIN1 +#define MII_TXD2 PIM_PIN2 +#define MII_TXD3 PIM_PIN3 +#define MII_TXCLK PIM_PIN4 +#define MII_TXEN PIM_PIN5 +#define MII_TXER PIM_PIN6 + +/* Port J I/O register aliases */ + +#define MII_MDC PIM_PIN0 +#define MII_MDIO PIM_PIN1 +#define MII_CRS PIM_PIN2 +#define MII_COL PIM_PIN3 +#define IIC_SDA PIM_PIN5 +#define IIC_SCL PIM_PIN6 + +/* Port L I/O register aliases */ + +#define PHY_ACTLED PIM_PIN0 +#define PHY_LNKLED PIM_PIN1 +#define PHY_SPDLED PIM_PIN2 +#define PHY_DUPLED PIM_PIN3 +#define PHY_COLLED PIM_PIN4 + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_PIM_H */ diff --git a/arch/hc/src/m9s12/m9s12_saveusercontext.S b/arch/hc/src/m9s12/m9s12_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..8538cc1f063ba41deb31010baa6741211f40bbf2 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_saveusercontext.S @@ -0,0 +1,189 @@ +/************************************************************************** + * arch/arm/src/m9s12/m9s12_saveusercontext.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include + +#include + +#include "up_internal.h" +#include "m9s12.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +#ifdef CONFIG_HCS12_NONBANKED +# define CALL jsr +# define RETURN rts +#else +# define CALL call +# define RETURN rtc +#endif + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_saveusercontext + * + * Description: + * Create this state save strucure: + * Low Address [PPAGE] + * [soft regisers] + * XYH + * XYL + * ZH + * ZL + * TMPH + * TMPL + * FRAMEH + * FRAMEL + * SP <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL + * + * On entry: + * D=Pointer to save save structure + * TOS=return address + * + **************************************************************************/ + + .text + .globl up_saveusercontext + .type up_saveusercontext, function +up_saveusercontext: + /* Exchange D with X. Now X points to the save structure. */ + + xgdx + + /* Save the PPAGE register */ + +#ifndef CONFIG_HCS12_NONBANKED + movb HCS12_MMC_PPAGE, 1, x+ +#endif + + /* Save the soft registers */ + +#if CONFIG_HCS12_MSOFTREGS > 2 +# error "Need to save more registers" +#endif +#if CONFIG_HCS12_MSOFTREGS > 1 + movw _.d2, 2, x+ +#endif +#if CONFIG_HCS12_MSOFTREGS > 0 + movw _.d1, 2, x+ +#endif + + /* It is not necessary to save the value of _.tmp, _.z, or _.xy */ + + ldd #0 + std 2, x+ /* Save _.xy = 0 */ + std 2, x+ /* Save _.z = 0 */ + std 2, x+ /* Save _.tmp = 0 */ + + /* Save _.frame */ + + movw _.frame, 2, x+ + + /* Save the value of the stack "before" this function was called */ + + tfr sp, d /* D = current SP */ + addd #(TOTALFRAME_SIZE-INTFRAME_SIZE) + std 2, x+ /* Save the value of SP on entry */ + + /* Save the CCR */ + + tpa /* A = CCR */ + staa 1, x+ /* Save CCR in the structure */ + + /* D (A:B) is the return value. Save 1 as the new return value as it + * will appear after a context switch back to the current thread. + */ + + ldd #1 + std 2, x+ /* Save D = 1 */ + + /* X, Y do not need to be preserved. Write zeros to these locations */ + + ldd #0 + std 2, x+ /* Save X = 0 */ + std 2, x+ /* Save Y = 0 */ + + /* Fetch the 2-byte return address from the stack and save it at the + * end of the state save area + */ + + movw 0, sp, 2, x+ /* Save PCH and PCL */ + +#if __INT__ == 32 /* 32-bit ABI */ + ldx #0 +#endif + clra + clrb + RETURN + .size up_saveusercontext, . - up_saveusercontext + .end diff --git a/arch/hc/src/m9s12/m9s12_sci.h b/arch/hc/src/m9s12/m9s12_sci.h new file mode 100644 index 0000000000000000000000000000000000000000..87b8b62c4154634a2b6dd8867cf871e96caf494b --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_sci.h @@ -0,0 +1,157 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_sci.h (v3) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_SCI_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_SCI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_SCI_BDH_OFFSET 0x00 /* SCI Baud Rate Register High */ +#define HCS12_SCI_BDL_OFFSET 0x01 /* SCI Baud Rate Register Low */ +#define HCS12_SCI_CR1_OFFSET 0x02 /* SCI Control Register 1 */ +#define HCS12_SCI_CR2_OFFSET 0x03 /* SCI Control Register 2 */ +#define HCS12_SCI_SR1_OFFSET 0x04 /* SCI Status Register 1 */ +#define HCS12_SCI_SR2_OFFSET 0x05 /* SCI Status Register 2 */ +#define HCS12_SCI_DRH_OFFSET 0x06 /* SCI Data Register High */ +#define HCS12_SCI_DRL_OFFSET 0x07 /* SCI Data Register Low */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_SCI0_BDH (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_BDH_OFFSET) +#define HCS12_SCI0_BDL (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_BDL_OFFSET) +#define HCS12_SCI0_CR1 (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_CR1_OFFSET) +#define HCS12_SCI0_CR2 (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_CR2_OFFSET) +#define HCS12_SCI0_SR1 (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_SR1_OFFSET) +#define HCS12_SCI0_SR2 (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_SR2_OFFSET) +#define HCS12_SCI0_DRH (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_DRH_OFFSET) +#define HCS12_SCI0_DRL (HCS12_REG_BASE+HCS12_SCI0_BASE+HCS12_SCI_DRL_OFFSET) + +#define HCS12_SCI1_BDH (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_BDH_OFFSET) +#define HCS12_SCI1_BDL (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_BDL_OFFSET) +#define HCS12_SCI1_CR1 (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_CR1_OFFSET) +#define HCS12_SCI1_CR2 (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_CR2_OFFSET) +#define HCS12_SCI1_SR1 (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_SR1_OFFSET) +#define HCS12_SCI1_SR2 (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_SR2_OFFSET) +#define HCS12_SCI1_DRH (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_DRH_OFFSET) +#define HCS12_SCI1_DRL (HCS12_REG_BASE+HCS12_SCI1_BASE+HCS12_SCI_DRL_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* SCI Baud Rate Register High Bit-Field Definitions */ + +#define SCI_BDH_SBR_SHIFT (0) /* Bits 0-4: SBR[11:8] */ +#define SCI_BDH_SBR_MASK (0x1f << SCI_BDH_SBR_SHIFT) +#define SCI_BDH_TNP_SHIFT (5) /* Bits 5-6: IRSCI Transmit Pulse Width */ +#define SCI_BDH_TNP_MASK (3 << SCI_BDH_TNP_SHIFT) +# define SCI_BDH_TNP_132 (0 << SCI_BDH_TNP_SHIFT) /* 1/32 */ +# define SCI_BDH_TNP_116 (1 << SCI_BDH_TNP_SHIFT) /* 1/16 */ +# define SCI_BDH_TNP_316 (2 << SCI_BDH_TNP_SHIFT) /* 3/16 */ +#define SCI_BDH_IREN (1 << 7) /* Bit 7: Infrared Enable */ + +/* SCI Baud Rate Register Low Bit-Field Definitions */ +/* This register holds the low 7 bits of the baud bits SBR[7:0] */ + +/* SCI Control Register 1 Bit-Field Definitions */ + +#define SCI_CR1_PT (1 << 0) /* Bit 0: Parity Type */ +#define SCI_CR1_PE (1 << 1) /* Bit 1: Parity Enable */ +#define SCI_CR1_ILT (1 << 2) /* Bit 2: Idle Line Type */ +#define SCI_CR1_WAKE (1 << 3) /* Bit 3: Wakeup Condition */ +#define SCI_CR1_M (1 << 4) /* Bit 4: Data Format Mode */ +#define SCI_CR1_RSRC (1 << 5) /* Bit 5: Receiver Source */ +#define SCI_CR1_SCISWAI (1 << 6) /* Bit 6: SCI Stop in Wait Mode */ +#define SCI_CR1_LOOPS (1 << 7) /* Bit 7: Enables loop operation */ + +/* SCI Control Register 2 Bit-Field Definitions */ + +#define SCI_CR2_SBK (1 << 0) /* Bit 0: Send Break */ +#define SCI_CR2_RWU (1 << 1) /* Bit 1: Receiver Wakeup */ +#define SCI_CR2_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define SCI_CR2_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define SCI_CR2_ILIE (1 << 4) /* Bit 4: Idle Line Interrupt Enable */ +#define SCI_CR2_RIE (1 << 5) /* Bit 5: Receiver Full Interrupt Enable Bit */ +#define SCI_CR2_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define SCI_CR2_TIE (1 << 7) /* Bit 7: Transmitter Interrupt Enable */ +#define SCI_CR2_ALLINTS 0xf0 + +/* SCI Status Register 1 Bit-Field Definitions */ + +#define SCI_SR1_PF (1 << 0) /* Bit 0: Parity Error */ +#define SCI_SR1_FE (1 << 1) /* Bit 1: Framing Error */ +#define SCI_SR1_NF (1 << 2) /* Bit 2: Noise */ +#define SCI_SR1_OR (1 << 3) /* Bit 3: Overrun */ +#define SCI_SR1_IDLE (1 << 4) /* Bit 4: Idle Line */ +#define SCI_SR1_RDRF (1 << 5) /* Bit 5: Receive Data Register Full */ +#define SCI_SR1_TC (1 << 6) /* Bit 6: Transmit Complete */ +#define SCI_SR1_TDRE (1 << 7) /* Bit 7: Transmit Data Register Empty */ + +/* SCI Status Register 2 Bit-Field Definitions */ + +#define SCI_SR2_BRK13 (1 << 2) /* Bit 2: Break Transmit Character Length */ +#define SCI_SR2_TXDIR (1 << 1) /* Bit 1: Transmitter Pin Data Direction in Single-Wire */ +#define SCI_SR2_RAF (1 << 0) /* Bit 0: Receiver Active */ + +/* SCI Data Register High Bit-Field Definitions */ + +#define SCI_DRH_T8 (1 << 6) /* Bit 6: Transmit Bit 8 */ +#define SCI_DRH_R8 (1 << 7) /* Bit 7: Received Bit 8 */ + +/* SCI Data Register Low Bit-Field Definitions */ +/* Receive/Transmit bits 0-7 */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_SCI_H */ diff --git a/arch/hc/src/m9s12/m9s12_serial.c b/arch/hc/src/m9s12/m9s12_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..1bc0091395be3a002deb2a0f584cbdb7b1b78057 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_serial.c @@ -0,0 +1,849 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_serial.c + * + * Copyright (C) 2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" +#include "m9s12_serial.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Is there a serial console? Need to have (1) at least SCI enabled, (2) + * a serial console defined on an enabled SCI, and (3) serial console and + * file descriptors selected in the configuration. This driver is also + * disabled if we are using ROM-resident serial I/O + */ + +#if !defined(HAVE_SERIAL_CONSOLE) || !defined(USE_SERIALDRIVER) || \ + defined(CONFIG_HCS12_SERIALMON) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +#endif + +#ifdef USE_SERIALDRIVER + +/* Yes, which is ttyS0 and which is ttyS1 */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci0port /* SCI0 is console */ +# define TTYS0_DEV g_sci0port /* SCI0 is ttyS0 */ +# ifndef CONFIG_SCI1_DISABLE +# define TTYS1_DEV g_sci1port /* SCI1 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci1port /* SCI1 is console */ +# define TTYS0_DEV g_sci1port /* SCI1 is ttyS0 */ +# ifndef CONFIG_SCI0_DISABLE +# define TTYS1_DEV g_sci0port /* SCI0 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +#elif !defined(CONFIG_SCI0_DISABLE) +# undef CONSOLE_DEV /* No console device */ +# define TTYS0_DEV g_sci1port /* SCI1 is ttyS0 */ +# ifndef CONFIG_SCI1_DISABLE +# define TTYS1_DEV g_sci1port /* SCI1 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +#elif !defined(CONFIG_SCI1_DISABLE) +# undef CONSOLE_DEV /* No console device */ +# define TTYS0_DEV g_sci1port /* SCI1 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +#else +# error "No valid TTY devices" +# undef CONSOLE_DEV /* No console device */ +# undef TTYS0_DEV /* No ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t baud; /* Configured baud */ + uint16_t scibase; /* Base address of SCI registers */ + uint8_t im; /* Saved CR1 interrupt enables */ + uint8_t sr1; /* Saved error status flags */ + uint8_t irq; /* IRQ associated with this SCI */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct uart_ops_s g_sci_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifndef CONFIG_SCI0_DISABLE +static char g_sci0rxbuffer[CONFIG_SCI0_RXBUFSIZE]; +static char g_sci0txbuffer[CONFIG_SCI0_TXBUFSIZE]; +#endif +#ifndef CONFIG_SCI1_DISABLE +static char g_sci1rxbuffer[CONFIG_SCI1_RXBUFSIZE]; +static char g_sci1txbuffer[CONFIG_SCI1_TXBUFSIZE]; +#endif + +/* This describes the state of the sci0 port. */ + +#ifndef CONFIG_SCI0_DISABLE +static struct up_dev_s g_sci0priv = +{ + .baud = CONFIG_SCI0_BAUD, + .uartbase = HCS12_SCI0_BASE, + .irq = HCS12_IRQ_VSCI0, + .parity = CONFIG_SCI0_PARITY, + .bits = CONFIG_SCI0_BITS, +}; + +static uart_dev_t g_sci0port = +{ + .recv = + { + .size = CONFIG_SCI0_RXBUFSIZE, + .buffer = g_sci0rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI0_TXBUFSIZE, + .buffer = g_sci0txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci0priv, +}; +#endif + +/* This describes the state of the sci1 port. */ + +#ifndef CONFIG_SCI1_DISABLE +static struct up_dev_s g_sci1priv = +{ + .baud = CONFIG_SCI1_BAUD, + .uartbase = HCS12_SCI1_BASE, + .irq = HCS12_IRQ_VSCI1, + .parity = CONFIG_SCI1_PARITY, + .bits = CONFIG_SCI1_BITS, +}; + +static uart_dev_t g_sci1port = +{ + .recv = + { + .size = CONFIG_SCI1_RXBUFSIZE, + .buffer = g_sci1rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI1_TXBUFSIZE, + .buffer = g_sci1txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci1priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_setsciint + ****************************************************************************/ + +static inline void up_setsciint(struct up_dev_s *priv) +{ + uint8_t regval; + + regval = up_serialin(priv, HCS12_SCI_CR2_OFFSET); + regval &= ~SCI_CR2_ALLINTS; + regval |= priv->im; + up_serialout(priv, HCS12_SCI_CR2_OFFSET, regval); +} + +/**************************************************************************** + * Name: up_disablesciint + ****************************************************************************/ + +static inline void up_disablesciint(struct up_dev_s *priv, uint8_t *im) +{ + uint8_t regval; + + /* Return the current interrupt mask value */ + + if (im) + { + *im = priv->im; + } + + /* Disable all interrupts */ + + priv->im = 0; + up_setsciint(priv); +} + +/**************************************************************************** + * Name: up_restoresciint + ****************************************************************************/ + +static inline void up_restoresciint(struct up_dev_s *priv, uint32_t im) +{ + priv->im = im & SCI_CR2_ALLINTS; + up_setsciint(priv); +} + +/**************************************************************************** + * Name: up_waittxnotfull + ****************************************************************************/ + +#ifdef HAVE_CONSOLE +static inline void up_waittxnotfull(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TX available condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check Tx data register is empty */ + + if ((up_serialin(priv, HCS12_SCI_SR1_OFFSET) & SCI_SR1_TDRE) != 0) + { + /* The Tx is empty... return */ + + break; + } + } + + /* If we get here, then the wait has timed out and the Tx data register + * remains full. + */ +} +#endif + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the SCI baud, bits, parity, fifos, etc. This method is called + * the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; +#ifndef CONFIG_SUPPRESS_SCI_CONFIG + uint8_t cr1; +#endif + +#ifndef CONFIG_SUPPRESS_SCI_CONFIG + /* Calculate the BAUD divisor */ + + tmp = SCIBR_VALUE(priv->baud); + DEBUGASSERT(tmp < 0xff); + + /* Disable the SCI */ + + up_serialout(priv, HCS12_SCI_CR1_OFFSET, 0); + up_serialout(priv, HCS12_SCI_CR2_OFFSET, 0); + + /* Set the BAUD divisor */ + + up_serialout(priv, HCS12_SCI_BDH_OFFSET, (uint8_t)(tmp >> 8)); + up_serialout(priv, HCS12_SCI_BDL_OFFSET, (uint8_t)(tmp & 0xff)); + + /* Set up the SCICR1 register */ + + cr1 = 0; + if (priv->bits == 9) + { + cr1 |= SCI_CR1_M; + } + + switch (priv->parity) + { + case 0: + default: + break; + case 1: + cr1 |= SCI_CR1_PE|SCI_CR1_PT; + break; + case 2: + cr1 |= SCI_CR1_PE; + break; + } + + up_serialout(priv, HCS12_SCI_CR1_OFFSET, cr1); +#endif + + /* Enable Rx and Tx, keeping all interrupts disabled. We don't want + * interrupts until the interrupt vector is attached. + */ + + priv->im = 0; + up_serialout(priv, HCS12_SCI_CR2_OFFSET, (SCI_CR2_TE|SCI_CR2_RE)); + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the SCI. This method is called when the serial port is closed. + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + up_disablesciint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the SCI to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt); + if (ret == OK) + { + /* Enable the Rx interrupt (the TX interrupt is still disabled + * until we have something to send). + */ + + priv->im = SCI_CR2_RIE; + up_setsciint(priv); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach SCI interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + up_disablesciint(priv, NULL); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the SCI interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + int passes; + bool handled; + +#ifndef CONFIG_SCI0_DISABLE + if (g_sci0priv.irq == irq) + { + dev = &g_sci0port; + } + else +#endif +#ifndef CONFIG_SCI1_DISABLE + if (g_sci1priv.irq == irq) + { + dev = &g_sci1port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s*)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked SCI status and clear the pending interrupts. */ + + priv->sr1 = up_serialin(priv, HCS12_SCI_SR1_OFFSET); + + /* Handle incoming, receive bytes */ + + if ((mis & SCI_SR1_RDRF) != 0) + { + /* Rx buffer not empty ... process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + if ((mis & SCI_SR1_TDRE) != 0) + { + /* Tx FIFO not full ... process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + int ret = OK; + + switch (cmd) + { + /* Add IOCTL command support here */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the SCI. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + int rxd; + + /* Return the error indications */ + + *status = (uint32_t)(priv->sr1 & ~SCI_CR2_ALLINTS); + + /* Get the Rx data */ + + rxd = (int)up_serialin(priv, HCS12_SCI_DRL_OFFSET); + if (priv->bits == 9) + { + if ((up_serialin(priv, HCS12_SCI_DRH_OFFSET) & SCI_DRH_R8) != 0) + { + rxd |= 0x0100; + } + } + + return rxd; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + if (enable) + { + /* Receive an interrupt when their is anything in the Rx FIFO (or an Rx + * timeout occurs. + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= SCI_CR2_RIE; +#endif + } + else + { + priv->im &= ~SCI_CR2_RIE; + } + + up_setsciint(priv); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return ((up_serialin(priv, HCS12_SCI_SR1_OFFSET) & SCI_SR1_RDRF) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the SCI + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint8_t regval; + + if (priv->bits == 9) + { + regval = up_serialin(priv, HCS12_SCI_DRH_OFFSET); + if ((ch & 0x0100) == 0) + { + regval &= ~SCI_DRH_T8; + } + else + { + regval |= SCI_DRH_T8; + } + up_serialout(priv, HCS12_SCI_DRH_OFFSET, regval); + } + + up_serialout(priv, HCS12_SCI_DRL_OFFSET, (uint8_t)(ch & 0xff)); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= SCI_CR2_TIE; + up_setsciint(priv); + + /* Fake a TX interrupt */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->im &= ~SCI_CR2_TIE; + up_setsciint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return ((up_serialin(priv, HCS12_SCI_SR1_OFFSET) & SCI_SR1_TDRE) != 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return ((up_serialin(priv, HCS12_SCI_SR1_OFFSET) & SCI_SR1_TC) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level SCI initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* Disable all UARTS */ + + up_disablesciint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disablesciint(TTYS1_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; + uint32_t im; + + up_disablesciint(priv, &im); + up_waittxnotfull(priv); + up_send(CONSOLE_DEV, ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxnotfull(priv); + up_send(CONSOLE_DEV, '\r'); + } + + up_waittxnotfull(priv); + up_restoresciint(priv, im); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef CONFIG_ARCH_LOWPUTC + up_lowputc(ch); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/hc/src/m9s12/m9s12_serial.h b/arch/hc/src/m9s12/m9s12_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..0c5f70041ade47475a831c2a96c3fd16c0088538 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_serial.h @@ -0,0 +1,135 @@ +/************************************************************************************ + * arch/hc/src/m9s12/serial.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_HC_SRC_M9S12_CHIP_H +#define __ARCH_HC_SRC_M9S12_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +/* Is there a SCI enabled? */ + +#if defined(CONFIG_SCI0_DISABLE) && defined(CONFIG_SCI1_DISABLE) +# undef HAVE_SERIAL_DEVICE +# warning "No SCIs enabled" +#else +# define HAVE_SERIAL_DEVICE 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) && !defined(CONFIG_SCI0_DISABLE) +# undef CONFIG_SCI1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) && !defined(CONFIG_SCI1_DISABLE) +# undef CONFIG_SCI0_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# warning "No valid CONFIG_SCIn_SERIAL_CONSOLE Setting" +# undef CONFIG_SCI0_SERIAL_CONSOLE +# undef CONFIG_SCI1_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Sanity checking */ + +#ifndef CONFIG_SCI0_DISABLE +# ifndef CONFIG_SCI0_PARITY +# warning "CONFIG_SCI0_PARITY not defined -- Assuming none" +# define CONFIG_SCI0_PARITY 0 +# elif CONFIG_SCI0_PARITY != 0 && CONFIG_SCI0_PARITY != 2 && CONFIG_SCI0_PARITY != 2 +# error "CONFIG_SCI0_PARITY value not recognized" +# endif +# ifndef CONFIG_SCI0_BITS +# warning "CONFIG_SCI0_BITS not defined -- Assuming 8" +# define CONFIG_SCI0_BITS 8 +# elif CONFIG_SCI0_BITS != 8 && CONFIG_SCI0_BITS != 9 +# error "CONFIG_SCI0_BITS value not supported" +# endif +# if defined(CONFIG_SCI0_2STOP) && CONFIG_SCI0_2STOP != 0 +# error "Only a single stop bit is supported" +# endif +#endif + +#ifndef CONFIG_SCI1_DISABLE +# ifndef CONFIG_SCI1_PARITY +# warning "CONFIG_SCI1_PARITY not defined -- Assuming none" +# define CONFIG_SCI1_PARITY 0 +# elif CONFIG_SCI1_PARITY != 0 && CONFIG_SCI1_PARITY != 2 && CONFIG_SCI1_PARITY != 2 +# error "CONFIG_SCI1_PARITY value not recognized" +# endif +# ifndef CONFIG_SCI1_BITS +# warning "CONFIG_SCI1_BITS not defined -- Assuming 8" +# define CONFIG_SCI1_BITS 8 +# elif CONFIG_SCI1_BITS != 8 && CONFIG_SCI1_BITS != 9 +# error "CONFIG_SCI1_BITS value not supported" +# endif +# if defined(CONFIG_SCI1_2STOP) && CONFIG_SCI1_2STOP != 0 +# error "Only a single stop bit is supported" +# endif +#endif + +/* BAUD *****************************************************************************/ +/* Baud calculations. The SCI module is driven by the BUSCLK. The SCIBR + * register value divides down the BUSCLK to accomplish the required BAUD. + * + * BAUD = HCS12_BUSCLK / (16 * SCIBR) + * SCIBR = HCS12_BUSCLK / (16 * BAUD) + */ + +#define SCIBR_VALUE(b) ((HCS12_BUSCLK * (b) + ((b) << 3))/((b) << 4)) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_HC_SRC_M9S12_CHIP_H */ diff --git a/arch/hc/src/m9s12/m9s12_spi.h b/arch/hc/src/m9s12/m9s12_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..7009535a9d72ad03e0eaac0bc4da2d42f1d66dff --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_spi.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_spi.h (v3) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_SPI_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_SPI_CR1_OFFSET 0x00 /* SPI Control Register 1 */ +#define HCS12_SPI_CR2_OFFSET 0x01 /* SPI Control Register 2 */ +#define HCS12_SPI_BR_OFFSET 0x02 /* SPI Baud Rate Register */ +#define HCS12_SPI_SR_OFFSET 0x03 /* SPI Status Register */ +#define HCS12_SPI_DR_OFFSET 0x05 /* SPI Data Register */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_SPI_CR1 (HCS12_REG_BASE+HCS12_SPI_BASE+HCS12_SPI_CR1_OFFSET) +#define HCS12_SPI_CR2 (HCS12_REG_BASE+HCS12_SPI_BASE+HCS12_SPI_CR2_OFFSET) +#define HCS12_SPI_BR (HCS12_REG_BASE+HCS12_SPI_BASE+HCS12_SPI_BR_OFFSET) +#define HCS12_SPI_SR (HCS12_REG_BASE+HCS12_SPI_BASE+HCS12_SPI_SR_OFFSET) +#define HCS12_SPI_DR (HCS12_REG_BASE+HCS12_SPI_BASE+HCS12_SPI_DR_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* SPI Control Register 1 Bit-Field Definitions */ + +#define SPI_CR1_LSBFE (1 << 0) /* Bit 0: LSB-First Enable */ +#define SPI_CR1_SSOE (1 << 1) /* Bit 1: Slave Select Output Enable */ +#define SPI_CR1_CPHA (1 << 2) /* Bit 2: SPI Clock Phase */ +#define SPI_CR1_CPOL (1 << 3) /* Bit 3: SPI Clock Polarity */ +#define SPI_CR1_MSTR (1 << 4) /* Bit 4: SPI Master/Slave Mode Select */ +#define SPI_CR1_SPTIE (1 << 5) /* Bit 5: SPI Transmit Interrupt Enable */ +#define SPI_CR1_SPE (1 << 6) /* Bit 6: SPI System Enable */ +#define SPI_CR1_SPIE (1 << 7) /* Bit 7: SPI Interrupt Enable */ + +/* SPI Control Register 2 Bit-Field Definitions */ + +#define SPI_CR2_SPC0 (1 << 0) /* Bit 0: Serial Pin Control Bit 0 */ +#define SPI_CR2_SPISWAI (1 << 1) /* Bit 1: SPI Stop in Wait Mode */ +#define SPI_CR2_BIDIROE (1 << 3) /* Bit 3: Output Enable in the Bidirectional */ +#define SPI_CR2_MODFEN (1 << 4) /* Bit 4: Mode Fault Enable */ + +/* SPI Baud Rate Register Bit-Field Definitions */ + +#define SPI_BR_SPR_SHIFT (0) /* Bits 0-2: SPI Baud Rate Selection */ +#define SPI_BR_SPR_MASK (7 << SPI_BR_SPR_SHIFT) +#define SPI_BR_SPPR_SHIFT (4) /* Bits 4-6: SPI Baud Rate Preselection */ +#define SPI_BR_SPPR_MASK (7 << SPI_BR_SPPR_SHIFT) + +/* SPI Status Register Bit-Field Definitions */ + +#define SPI_SR_MODF (1 << 4) /* Bit 4: Mode Fault */ +#define SPI_SR_SPTEF (1 << 5) /* Bit 5: SPI Transmit Empty Interrupt */ +#define SPI_SR_SPIF (1 << 7) /* Bit 7: SPIF Interrupt */ + +/* SPI Data Register Bit-Field Definitions */ +/* 8-bit SPI data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_SPI_H */ diff --git a/arch/hc/src/m9s12/m9s12_start.S b/arch/hc/src/m9s12/m9s12_start.S new file mode 100644 index 0000000000000000000000000000000000000000..49d31b4e1dde018cda7dabf6c5d5e17904aa228b --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_start.S @@ -0,0 +1,273 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_start.S + * arch/hc/src/chip/m9s12_start.S + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "m9s12.h" +#include "m9s12_mmc.h" +#include "m9s12_crg.h" +#include "m9s12_flash.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_HCS12_NONBANKED +# define CALL jsr +# define RETURN rts +#else +# define CALL call +# define RETURN rtc +#endif + +#define INITRG_REG (MMC_INITRG_REG(HCS12_REG_BASE)) +#define INITRM_MAP (MMC_INITRM_RAM(HCS12_SRAM_BASE)|MMC_INITRM_RAMHAL) +#define INITEE_EE (MMC_INITEE_EE(HCS12_EEPROM_BASE)|MMC_INITEE_EEON) + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "m9s12_start.S" + .globl __start + .globl os_start + .globl up_lowsetup + .globl hcs12_boardinitialize + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Print a character on the UART to show boot status. This macro will + * modify r0, r1, r2 and r14 + */ + + .macro showprogress, code +#ifdef CONFIG_DEBUG + ldab \code +#ifdef CONFIG_HCS12_SERIALMON + jsr #PutChar +#else + CALL up_lowputc +#endif +#endif + .endm + +/* Memory map initialization. + * + * The MC9S12NE64 has 64K bytes of FLASH EEPROM and 8K bytes of RAM. + */ + + .macro MMCINIT + /* Registers are always positioned at address 0x0000 */ + + movb #INITRG_REG, HCS12_MMC_INITRG /* Set the register map position to 0x0000*/ + nop + + /* Position SRAM so that is ends at address 0x3fff. This is required + * because the Freescale serial monitor initializes its stack to the + * end+1 of SRAM which it expects to be at address 0x4000 + */ + + movb #INITRM_MAP, HCS12_MMC_INITRM /* Set RAM position to 0x2000-0x3fff */ + movb #INITEE_EE, HCS12_MMC_INITEE /* Set EEPROM position to 0x0800 */ + + /* In the non-banked mode, PPAGE is set to 0x3d to create a (non-contiguous), + * fixed, 48Kb .text address space. + */ + +#ifdef CONFIG_HCS12_NONBANKED + movb #0x3d, HCS12_MMC_PPAGE +#endif + + movb #MMC_MISC_ROMON, HCS12_MMC_MISC /* MISC: EXSTR1=0 EXSTR0=0 ROMHM=0 ROMON=1 */ + .endm + +/* System clock initialization. If the serial monitor is used, then clocking will have + * already been configured at 24 MHz + */ + + .macro PLLINIT +#ifndef CONFIG_HCS12_SERIALMON + /* Select the clock source from crystal */ + + clr HCS12_CRG_CLKSEL + + /* Set the multipler and divider and enable the PLL */ + + bclr *HCS12_CRG_PLLCTL #CRG_PLLCTL_PLLON + ldab #HCS12_SYNR_VALUE + stab HCS12_CRG_SYNR + ldab #HCS12_REFDV_VALUE + stab HCS12_CRG_REFDV + bset *HCS12_CRG_PLLCTL #CRG_PLLCTL_PLLON + + /* Wait for the PLL to lock on */ + +.Lpll_lock: + brclr *HCS12_CRG_CRGFLG #CRG_CRGFLG_LOCK .Lpll_lock + + /* Then select the PLL clock source */ + + bset *HCS12_CRG_CLKSEL #CRG_CLKSEL_PLLSEL +#endif + .endm + + +/**************************************************************************** + * .text + ****************************************************************************/ + + .section nonbanked, "x" + +/**************************************************************************** + * Name: __start + * + * Description: + * Power-up reset entry point + * + ****************************************************************************/ + +__start: + /* Hardware setup */ + + MMCINIT /* Initialize the MMC */ + PLLINIT /* Initialize the PLL */ + + /* Setup the stack pointer */ + + lds .Lstackbase + + /* Perform early, low-level initialization */ + +#ifndef CONFIG_HCS12_SERIALMON + CALL up_lowsetup +#endif + showprogress 'A' + + /* Clear BSS */ + + ldx .Lsbss /* Start of .BSS */ + ldd .Lebss /* End+1 of .BSS */ + +.Lclearbss: + pshd + cpx 2,sp+ /* Check if all BSS has been cleared */ + beq .Lbsscleared /* If so, exit the loop */ + + clr 0,x /* Clear this byte */ + inx /* Address the next byte */ + bra .Lclearbss /* And loop until all cleared */ +.Lbsscleared: + showprogress 'B' + + /* Initialize the data section */ + + ldx .Lsdata /* Start of .DATA (destination) */ + movw .Ledata, 0, sp /* End of .DATA (destination) */ + ldy .Leronly /* Start of .DATA (source) */ + +.Linitdata: + cpx 0, sp /* Check if all .DATA has been initialized */ + beq .Ldatainitialized /* If so, exit the loop */ + ldab 0, y /* Fetch the next byte from the source */ + iny /* Increment the source address */ + stab 0, x /* Store the byte to the destination */ + inx /* Increment the destination address */ + bra .Linitdata /* And loop until all of .DATA is initialized */ +.Ldatainitialized: + showprogress 'C' + + /* Perform early board-level initialization */ + + CALL hcs12_boardinitialize + showprogress 'D' + + /* Now, start the OS */ + + showprogress '\n' + CALL os_start + bra __start + + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_IDLETHREAD_STACKSIZE. The heap continues + * from there until the end of memory. See g_idle_topstack + * below. + */ + +.Lsbss: + .hword _sbss +.Lebss: + .hword _ebss +.Lstackbase: + .hword _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +.Leronly: + .hword _eronly /* Where .data defaults are stored in FLASH */ +.Lsdata: + .hword _sdata /* Where .data needs to reside in SDRAM */ +.Ledata: + .hword _edata + .size __start, .-__start + +/************************************************************************************ + * .rodata + ************************************************************************************/ + + .section .rodata, "a" + +/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end + * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS + * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that + * the system boots on and, eventually, becomes the idle, do nothing task that runs + * only when there is nothing else to run. The heap continues from there until the + * end of memory. See g_idle_topstack below. + */ + + .globl g_idle_topstack + .type g_idle_topstack, object +g_idle_topstack: + .hword _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end diff --git a/arch/hc/src/m9s12/m9s12_tim.h b/arch/hc/src/m9s12/m9s12_tim.h new file mode 100644 index 0000000000000000000000000000000000000000..d2a3c602404b94c327aa11c947c5ba26a0fa93d0 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_tim.h @@ -0,0 +1,246 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_tim.h (TIM16b4c v1) + * + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_HC_SRC_M9S12_M9S12_TIM_H +#define __ARCH_ARM_HC_SRC_M9S12_M9S12_TIM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define HCS12_TIM_TIOS_OFFSET 0x0000 /* Timer Input Capture/Output Compare Select */ +#define HCS12_TIM_CFORC_OFFSET 0x0001 /* Timer Compare Force Register */ +#define HCS12_TIM_OC7M_OFFSET 0x0002 /* Output Compare 7 Mask Register */ +#define HCS12_TIM_OC7D_OFFSET 0x0003 /* Output Compare 7 Data Register */ +#define HCS12_TIM_TCNTHI2_OFFSET 0x0004 /* Timer Count Register */ +#define HCS12_TIM_TCNTLO2_OFFSET 0x0005 /* Timer Count Register */ +#define HCS12_TIM_TSCR1_OFFSET 0x0006 /* Timer System Control Register 1 */ +#define HCS12_TIM_TTOV_OFFSET 0x0007 /* Timer Toggle Overflow Register */ +#define HCS12_TIM_TCTL1_OFFSET 0x0008 /* Timer Control Register1 */ +#define HCS12_TIM_TCTL3_OFFSET 0x000a /* Timer Control Register3 */ +#define HCS12_TIM_TIE_OFFSET 0x000c /* Timer Interrupt Enable Register */ +#define HCS12_TIM_TSCR2_OFFSET 0x000d /* Timer System Control Register 2 */ +#define HCS12_TIM_TFLG1_OFFSET 0x000e /* Main Timer Interrupt Flag 1 */ +#define HCS12_TIM_TFLG2_OFFSET 0x000f /* Main Timer Interrupt Flag 2 */ +#define HCS12_TIM_TC4HI_OFFSET 0x0018 /* Timer Input Capture/Output Compare Register 4 */ +#define HCS12_TIM_TC4LO_OFFSET 0x0019 /* Timer Input Capture/Output Compare Register 4 */ +#define HCS12_TIM_TC5HI_OFFSET 0x001a /* Timer Input Capture/Output Compare Register 5 */ +#define HCS12_TIM_TC5LO_OFFSET 0x001b /* Timer Input Capture/Output Compare Register 5 */ +#define HCS12_TIM_TC6HI_OFFSET 0x001c /* Timer Input Capture/Output Compare Register 6 */ +#define HCS12_TIM_TC6LO_OFFSET 0x001d /* Timer Input Capture/Output Compare Register 6 */ +#define HCS12_TIM_TC7HI_OFFSET 0x001e /* Timer Input Capture/Output Compare Register 7 */ +#define HCS12_TIM_TC7LO_OFFSET 0x001f /* Timer Input Capture/Output Compare Register 7 */ +#define HCS12_TIM_PACTL_OFFSET 0x0020 /* 16-Bit Pulse Accumulator Control Register */ +#define HCS12_TIM_PAFLG_OFFSET 0x0021 /* Pulse Accumulator Flag Register */ +#define HCS12_TIM_PACNTHI_OFFSET 0x0022 /* Pulse Accumulator Count Register */ +#define HCS12_TIM_PACNTLO_OFFSET 0x0023 /* Pulse Accumulator Count Register */ +#define HCS12_TIM_TIMTST2_OFFSET 0x002d /* Timer Test Register */ + +/* Register Addresses ***************************************************************/ + +#define HCS12_TIM_TIOS (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TIOS_OFFSET) +#define HCS12_TIM_CFORC (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_CFORC_OFFSET) +#define HCS12_TIM_OC7M (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_OC7M_OFFSET) +#define HCS12_TIM_OC7D (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_OC7D_OFFSET) +#define HCS12_TIM_TCNTHI2 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TCNTHI2_OFFSET) +#define HCS12_TIM_TCNTLO2 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TCNTLO2_OFFSET) +#define HCS12_TIM_TSCR1 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TSCR1_OFFSET) +#define HCS12_TIM_TTOV (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TTOV_OFFSET) +#define HCS12_TIM_TCTL1 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TCTL1_OFFSET) +#define HCS12_TIM_TCTL3 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TCTL3_OFFSET) +#define HCS12_TIM_TIE (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TIE_OFFSET) +#define HCS12_TIM_TSCR2 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TSCR2_OFFSET) +#define HCS12_TIM_TFLG1 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TFLG1_OFFSET) +#define HCS12_TIM_TFLG2 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TFLG2_OFFSET) +#define HCS12_TIM_TC4HI (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC4HI_OFFSET) +#define HCS12_TIM_TC4LO (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC4LO_OFFSET) +#define HCS12_TIM_TC5HI (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC5HI_OFFSET) +#define HCS12_TIM_TC5LO (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC6HI_OFFSET) +#define HCS12_TIM_TC6HI (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC6LO_OFFSET) +#define HCS12_TIM_TC6LO (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC7HI_OFFSET) +#define HCS12_TIM_TC7HI (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TC7LO_OFFSET) +#define HCS12_TIM_TC7LO (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_PACTL_OFFSET) +#define HCS12_TIM_PACTL (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_PAFLG_OFFSET) +#define HCS12_TIM_PAFLG (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_PACNTHI_OFFSET) +#define HCS12_TIM_PACNTHI (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_PACNTLO_OFFSET) +#define HCS12_TIM_PACNTLO (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TIMTST2_OFFSET) +#define HCS12_TIM_TIMTST2 (HCS12_REG_BASE+HCS12_TIM_BASE+HCS12_TIM_TIMTST2_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Timer Input Capture/Output Compare Select Bit-Field Definitions */ + +#define TIM_TIOS(n) (1 << (n)) /* 0:Input capture, 1:Output compare */ + +/* Timer Compare Force Register Bit-Field Definitions */ + +#define TIM_CFORC(n) (1 << (n)) /* Force Output Compare Action */ + +/* Output Compare 7 Mask Register Bit-Field Definitions */ + +#define TIM_OC7M(n) (1 << (n)) /* Output Compare 7 Mask */ + +/* Output Compare 7 Data Register Bit-Field Definitions */ + +#define TIM_OC7D(n) (1 << (n)) /* Output Compare 7 Data */ + +/* Timer Count HI/LO Register Bit-Field Definitions */ +/* These two registers form a 16-bit timer up counter and have no internal bit-fields */ + +/* Timer System Control Register 1 Bit-Field Definitions */ + +#define TIM_TSCR1_TFFCA (1 << 4) /* Timer Fast Flag Clear All */ +#define TIM_TSCR1_TSFRA (1 << 5) /* Timer Stops While in Freeze Mode */ +#define TIM_TSCR1_TSWAI (1 << 6) /* Timer Module Stops While in Wait */ +#define TIM_TSCR1_TEN (1 << 7) /* Timer Enable */ + +/* Timer Toggle Overflow Register Bit-Field Definitions */ + +#define TIM_TTOV(n) (1 << (n)) /* Toggle On Overflow Bits */ + +/* Timer Control Register1 Bit-Field Definitions */ + +#define TIM_TCTL1_SHIFT(n) (((n)-4) << 1) +#define TIM_TCTL1_MASK (n) (3 << TIM_TCTL1_SHIFT(n)) + +# define TIM_TCTL1_OL(n) (1 << TIM_TCTL1_SHIFT(n)) /* Output Level */ +# define TIM_TCTL1_OM(n) (2 << TIM_TCTL1_SHIFT(n)) /* Output Mode */ + +# define TIM_TCTL1_DISABLED(n) (0 << TIM_TCTL1_SHIFT(n)) /* Timer disconnected from output pin logic */ +# define TIM_TCTL1_TOGGLE(n) (1 << TIM_TCTL1_SHIFT(n)) /* Toggle OCx output line */ +# define TIM_TCTL1_CLEAR(n) (2 << TIM_TCTL1_SHIFT(n)) /* Clear OCx output line to zero */ +# define TIM_TCTL1_SET(n) (3 << TIM_TCTL1_SHIFT(n)) /* Set OCx output line to one */ + +/* Timer Control Register3 Bit-Field Definitions */ + +#define TIM_TCTL3_EDG_SHIFT(n) (((n)-4) << 1) /* Input Capture Edge Control */ +#define TIM_TCTL3_EDG_MASK (n) (3 << TIM_TCTL3_EDG_SHIFT(n)) + +# define TIM_TCTL3_EDGA(n) (1 << TIM_TCTL3_EDG_SHIFT(n)) +# define TIM_TCTL3_EDGB(n) (2 << TIM_TCTL3_EDG_SHIFT(n)) + +# define TIM_TCTL3_DISABLED(n) (0 << TIM_TCTL3_EDG_SHIFT(n)) /* Capture disabled */ +# define TIM_TCTL3_RISING(n) (1 << TIM_TCTL3_EDG_SHIFT(n)) /* Capture on rising edges only */ +# define TIM_TCTL3_FALLING(n) (2 << TIM_TCTL3_EDG_SHIFT(n)) /* Capture on falling edges only */ +# define TIM_TCTL3_BOTH(n) (3 << TIM_TCTL3_EDG_SHIFT(n)) /* Capture on any edge */ + +/* Timer Interrupt Enable Register Bit-Field Definitions */ + +#define TIM_TIE(n) (1 << (n)) /* Input Capture/Output Compare n Interrupt Enable */ + +/* Timer System Control Register 2 Bit-Field Definitions */ + +#define TIM_TSCR2_PR_SHIFT (0) /* Timer Prescaler Select */ +#define TIM_TSCR2_PR_MASK (7 << TIM_TSCR2_PR_SHIFT) +# define TIM_TSCR2_PR0 (1 << TIM_TSCR2_PR_SHIFT) +# define TIM_TSCR2_PR1 (2 << TIM_TSCR2_PR_SHIFT) +# define TIM_TSCR2_PR2 (4 << TIM_TSCR2_PR_SHIFT) +# define TIM_TSCR2_PR_DIV1 (0 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/1 */ +# define TIM_TSCR2_PR_DIV2 (1 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/2 */ +# define TIM_TSCR2_PR_DIV4 (2 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/4 */ +# define TIM_TSCR2_PR_DIV8 (3 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/8 */ +# define TIM_TSCR2_PR_DIV16 (4 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/16 */ +# define TIM_TSCR2_PR_DIV32 (5 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/32 */ +# define TIM_TSCR2_PR_DIV64 (6 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/64 */ +# define TIM_TSCR2_PR_DIV128 (7 << TIM_TSCR2_PR_SHIFT) /* Bus Clock/128 */ +#define TIM_TSCR2_TCRE (1 << 3) /* Timer Counter Reset Enable */ +#define TIM_TSCR2_TOI (1 << 7) /* Timer Overflow Interrupt Enable */ + +/* Main Timer Interrupt Flag 1 Bit-Field Definitions */ + +#define TIM_TFLG1(n) (1 << (n)) /* Input Capture/Output Compare Channel n Flag */ + +/* Main Timer Interrupt Flag 2 Bit-Field Definitions */ + +#define TIM_TFLG2_TOF (1 << 7) /* Timer Overflow Flag */ + +/* Timer Input Capture/Output Compare HI/LO Register 4-7 Bit-Field Definitions */ +/* These register pairs form a 16-bit timer compare values and have no internal bit-fields */ + +/* 16-Bit Pulse Accumulator Control Register Bit-Field Definitions */ + +#define TIM_PACTL_PAI (1 << 0) /* Pulse Accumulator Input Interrupt Enable*/ +#define TIM_PACTL_PAOVI (1 << 1) /* Pulse Accumulator Overflow Interrupt Enable */ +#define TIM_PACTL_CLK_SHIFT (2) /* Clock Select Bits */ +#define TIM_PACTL_CLK_MASK (3 << TIM_PACTL_CLK_SHIFT) +# define TIM_PACTL_CLK0 (1 << TIM_PACTL_CLK_SHIFT) +# define TIM_PACTL_CLK1 (1 << TIM_PACTL_CLK_SHIFT) +# define TIM_PACTL_PRESCAL (0 << TIM_PACTL_CLK_SHIFT) /* Use timer prescaler clock as timer counter clock */ +# define TIM_PACTL_PACLK (1 << TIM_PACTL_CLK_SHIFT) /* Use PACLK as input to timer counter clock */ +# define TIM_PACTL_DIV256 (2 << TIM_PACTL_CLK_SHIFT) /* Use PACLK/256 as timer counter clock frequency */ +# define TIM_PACTL_DIV64K (3 << TIM_PACTL_CLK_SHIFT) /* Use PACLK/65536 as timer counter clock frequency */ +#define TIM_PACTL_PIN_SHIFT (4) /* Pin action */ +#define TIM_PACTL_PIN_MASK (3 << TIM_PACTL_PIN_SHIFT) +# define TIM_PACTL_PEDGE (1 << TIM_PACTL_PIN_SHIFT) /* Pulse Accumulator Edge Control */ +# define TIM_PACTL_PAMOD (2 << TIM_PACTL_PIN_SHIFT) /* Pulse Accumulator Mode */ +# define TIM_PACTL_FALLING (0 << TIM_PACTL_PIN_SHIFT) /* Falling edge */ +# define TIM_PACTL_RISING (1 << TIM_PACTL_PIN_SHIFT) /* Rising edge */ +# define TIM_PACTL_DIV64HI (2 << TIM_PACTL_PIN_SHIFT) /* Div. by 64 clock enabled with pin high level */ +# define TIM_PACTL_DIV64LO (3 << TIM_PACTL_PIN_SHIFT) /* Div. by 64 clock enabled with pin low level */ +#define TIM_PACTL_PAEN (1 << 6) /* Pulse Accumulator System Enable */ + +/* Pulse Accumulator Flag Register Bit-Field Definitions */ + +#define TIM_PAFLG_PAIF (1 << 0) /* Pulse Accumulator Input edge Flag */ +#define TIM_PAFLG_PAOVF (1 << 1) /* Pulse Accumulator Overflow Flag */ + +/* Pulse Accumulator Count HI/LO Register Bit-Field Definitions */ +/* This register pair forms a 16-bit pulse accumulator value with no internal bit-fields */ + +/* Timer Test Register Bit-Field Definitions */ +/* Not documented */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_HC_SRC_M9S12_M9S12_TIM_H */ diff --git a/arch/hc/src/m9s12/m9s12_timerisr.c b/arch/hc/src/m9s12/m9s12_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..c0c74697ff1012e0db6a0a2ce2548a45eaec6c6b --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_timerisr.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "m9s12.h" +#include "m9s12_crg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + */ + +/* The timer frequency is the OSCCLK divided down. The divisor is + * (A+1)*(2**(B+9)) where: + * + * A = MODCNT RTR[0:3] + * B = PREP RTR[4:6] + * + * Maximum and minimum values: + */ + +#define MIN_PRER 1024 /* 2**10, B=1 */ +#define MAX_PRER 65536 /* 2**16, B=7 */ + +#define MIN_MODCNT 1 /* A=0 */ +#define MAX_MODCNT 16 /* A=15 */ + +/* Pick the smallest value of B for which: + * + * OSCCLK/(MAX_MODCNT*(2**(B+9))) >= CLK_TCK >= OSCCLK/(MIN_MODCNT*(2**(B+9))) + */ + +#if CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*1024) && HCS12_OSCCLK/(MIN_MODCNT*1024) +# define PRER_VALUE 1 +# define PRER_DIV 1024 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*2048) && HCS12_OSCCLK/(MIN_MODCNT*2048) +# define PRER_VALUE 2 +# define PRER_DIV 2048 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*4096) && HCS12_OSCCLK/(MIN_MODCNT*4096) +# define PRER_VALUE 3 +# define PRER_DIV 4096 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*8192) && HCS12_OSCCLK/(MIN_MODCNT*8192) +# define PRER_VALUE 4 +# define PRER_DIV 8192 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*16384) && HCS12_OSCCLK/(MIN_MODCNT*16384) +# define PRER_VALUE 5 +# define PRER_DIV 16384 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*32768) && HCS12_OSCCLK/(MIN_MODCNT*32768) +# define PRER_VALUE 6 +# define PRER_DIV 32768 +#elif CLK_TCK >= HCS12_OSCCLK/(MAX_MODCNT*65536) && HCS12_OSCCLK/(MIN_MODCNT*65536) +# define PRER_VALUE 7 +# define PRER_DIV 65536 +#else +# error "Cannot generate CLK_TCK from HCSCLK_OSCCLK" +#endif + +/* Now we can simply calculate A from: + * + * CLK_TCK = OSCCLK/((A+1)*PRER_DIV) + * OSCCLK / (CLK_TCK * PRER_DIV) - 1 + */ + +#define MODCNT_DENOM ((uint32_t)CLK_TCK * (uint32_t)PRER_DIV) +#define MODCNT_VALUE ((((uint32_t)HCS12_OSCCLK + (MODCNT_DENOM/2))/ MODCNT_DENOM) - 1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Clear real time interrupt flag */ + + putreg8(CRG_CRGFLG_RTIF, HCS12_CRG_CRGFLG); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the system timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t tmp; + uint8_t regval; + + /* Configure hardware RTI timer (with a hack to avoid and integer overflow + * error at compile time.. hopefully the optimizer will eliminate these + * uint32_t operations). + */ + + tmp = MODCNT_VALUE << CRG_RTICTL_MODCNT_SHIFT | PRER_VALUE << CRG_RTICTL_PRER_SHIFT; + putreg8((uint8_t)tmp, HCS12_CRG_RTICTL); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(HCS12_IRQ_VRTI, (xcpt_t)up_timerisr); + + /* Enable RTI interrupt by setting the RTIE bit */ + + regval = getreg8(HCS12_CRG_CRGINT); + regval |= CRG_CRGINT_RTIE; + putreg8(regval, HCS12_CRG_CRGINT); +} diff --git a/arch/hc/src/m9s12/m9s12_vectors.S b/arch/hc/src/m9s12/m9s12_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..fbe4d69f0a7d14a6ea75c89d9f4e5e28bb0b9bf8 --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_vectors.S @@ -0,0 +1,450 @@ +/************************************************************************************ + * arch/hc/src/m9s12/m9s12_vectors.S + * arch/hc/src/chip/m9s12_vectors.S + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifdef CONFIG_HCS12_NONBANKED +# define CALL jsr +# define RETURN rts +#else +# define CALL call +# define RETURN rtc +#endif + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl __start + .globl up_doirq + .globl up_fullcontextrestore + .file "m9s12_vectors.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/* On entry into an I- or X-interrupt, into an SWI, or into an undefined instruction + * interrupt, the stack frame created by hardware looks like: + * + * Low Address <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL <-- SP before interrupt + */ + + .macro HANDLER, label, irqno +\label: + ldab #\irqno /* Load B=IRQ number */ + bra vcommon /* Jump to common logic */ + .endm + +/************************************************************************************ + * Vectors + ************************************************************************************/ + + .section vectors, "x" + .align 2 + .globl hcs12_vectors + .type hcs12_vectors, function + +hcs12_vectors: + /* ff80-ff9f: Reserved */ + .hword villegal /* ff80: Reserved*/ + .hword villegal /* ff82: Reserved */ + .hword villegal /* ff84: Reserved */ + .hword villegal /* ff86: Reserved */ + .hword villegal /* ff88: Reserved */ + .hword villegal /* ff8a: Reserved */ + .hword villegal /* ff8c: Reserved */ + .hword villegal /* ff9e: Reserved */ + .hword villegal /* ff90: Reserved */ + .hword villegal /* ff92: Reserved */ + .hword villegal /* ff94: Reserved */ + .hword villegal /* ff96: Reserved */ + .hword villegal /* ff98: Reserved */ + .hword villegal /* ff9a: Reserved */ + .hword villegal /* ff9c: Reserved */ + .hword villegal /* ff9e: Reserved */ + .hword vemacec /* ffa0: EMAC excessive collision */ + .hword vemaclc /* ffa2: EMAC late collision*/ + .hword vemacbrxerr /* ffa4: MAC babbling receive error*/ + .hword vemacrxbbo /* ffa6: EMAC receive buffer B overrun */ + .hword vemacrxbao /* ffa8: EMAC receive buffer A overrun */ + .hword vemacrxerr /* ffaa: EMAC receive error */ + .hword vemacmii /* ffac: EMAC MII management transfer complete */ + .hword vemacrxfc /* ffae: EMAC receive flow control */ + .hword vemactxc /* ffb0: EMAC frame transmission complete */ + .hword vemaccrxbbc /* ffb2: EMAC receive buffer B complete */ + .hword vemaccrxbac /* ffb4: EMAC receive buffer A complete */ + .hword vephy /* ffb6: EPHY interrupt */ + .hword vflash /* ffb8: FLASH */ + .hword villegal /* ffba: Reserved */ + .hword villegal /* ffbc: Reserved */ + .hword villegal /* ffbe: Reserved */ + .hword viic /* ffc0: IIC bus */ + .hword villegal /* ffc2: Reserved */ + .hword vcrgscm /* ffc4: CRG self clock mode */ + .hword vcrgplllck /* ffc6: CRG PLL lock */ + .hword villegal /* ffc8: Reserved */ + .hword vportg /* ffca: Port G */ + .hword vporth /* ffcc: Port H */ + .hword vportj /* ffcd: Port J */ + .hword villegal /* ffd0: Reserved */ + .hword vatd /* ffd2: ATD */ + .hword vsci1 /* ffd4: SCI1 */ + .hword vsci0 /* ffd6: SCI0 */ + .hword vspi /* ffd8: SPI */ + .hword vtimpaie /* ffda: Pulse accumulator input edge */ + .hword vtimpaovf /* ffdc: Pulse accumulator overflow */ + .hword vtimovf /* ffde: Standard timer overflow */ + .hword vtimch7 /* ffe0: Standard timer channel 7 */ + .hword vtimch6 /* ffe2: Standard timer channel 6 */ + .hword vtimch5 /* ffe4: Standard timer channel 5 */ + .hword vtimch4 /* ffe6: Standard timer channel 4 */ + .hword villegal /* ffe8: Reserved */ + .hword villegal /* ffea: Reserved */ + .hword villegal /* ffec: Reserved */ + .hword villegal /* ffee: Reserved */ + .hword vrti /* fff0: Real-time interrupt */ + .hword virq /* fff2: IRQ */ + .hword vxirq /* fff4: XIRQ */ + .hword vswi /* fff6: SWI */ + .hword vtrap /* fff8: Unimplemented instruction trap */ + .hword vcop /* fffa: COP failure reset */ + .hword vclkmon /* fffc: Clock monitor fail reset */ + .hword __start /* fffe: Reset vector */ + + .size hcs12_vectors, .-hcs12_vectors + +/************************************************************************************ + * .text + ************************************************************************************/ + + .section nonbanked, "x" + .type handlers, function +handlers: + + HANDLER vemacec, HCS12_IRQ_VEMACEC /* EMAC excessive collision */ + HANDLER vemaclc, HCS12_IRQ_VEMACLC /* EMAC late collision */ + HANDLER vemacbrxerr, HCS12_IRQ_VEMACBRXERR /* EMAC babbling receive error */ + HANDLER vemacrxbbo, HCS12_IRQ_VEMACRXBBO /* EMAC receive buffer B overrun */ + HANDLER vemacrxbao, HCS12_IRQ_VEMACRXBAO /* EMAC receive buffer A overrun */ + HANDLER vemacrxerr, HCS12_IRQ_VEMACRXERR /* EMAC receive error */ + HANDLER vemacmii, HCS12_IRQ_VEMACMII /* EMAC MII management transfer complete */ + HANDLER vemacrxfc, HCS12_IRQ_VEMACRXFC /* EMAC receive flow control */ + HANDLER vemactxc, HCS12_IRQ_VEMACTXC /* EMAC frame transmission complete */ + HANDLER vemaccrxbbc, HCS12_IRQ_VEMACCRXBBC /* EMAC receive buffer B complete */ + HANDLER vemaccrxbac, HCS12_IRQ_VEMACCRXBAC /* EMAC receive buffer A complete */ + HANDLER vephy, HCS12_IRQ_VEPHY /* EPHY interrupt */ + HANDLER vflash, HCS12_IRQ_VFLASH /* FLASH */ + HANDLER viic, HCS12_IRQ_VIIC /* IIC bus */ + HANDLER vcrgscm, HCS12_IRQ_VCRGSCM /* CRG self clock mode */ + HANDLER vcrgplllck, HCS12_IRQ_VCRGPLLLCK /* CRG PLL lock */ + HANDLER vportg, HCS12_IRQ_VPORTG /* Port G */ + HANDLER vporth, HCS12_IRQ_VPORTH /* Port H */ + HANDLER vportj, HCS12_IRQ_VPORTJ /* Port J */ + HANDLER vatd, HCS12_IRQ_VATD /* ATD */ + HANDLER vsci1, HCS12_IRQ_VSCI1 /* SCI1 */ + HANDLER vsci0, HCS12_IRQ_VSCI0 /* SCI0 */ + HANDLER vspi, HCS12_IRQ_VSPI /* SPI */ + HANDLER vtimpaie, HCS12_IRQ_VTIMPAIE /* Pulse accumulator input edge */ + HANDLER vtimpaovf, HCS12_IRQ_VTIMPAOVF /* Pulse accumulator overflow */ + HANDLER vtimovf, HCS12_IRQ_VTIMOVF /* Standard timer overflow */ + HANDLER vtimch7, HCS12_IRQ_VTIMCH7 /* Standard timer channel 7 */ + HANDLER vtimch6, HCS12_IRQ_VTIMCH6 /* Standard timer channel 6 */ + HANDLER vtimch5, HCS12_IRQ_VTIMCH5 /* Standard timer channel 5 */ + HANDLER vtimch4, HCS12_IRQ_VTIMCH4 /* Standard timer channel 4 */ + HANDLER vrti, HCS12_IRQ_VRTI /* Real-time interrupt */ + HANDLER virq, HCS12_IRQ_VIRQ /* IRQ */ + HANDLER vxirq, HCS12_IRQ_VXIRQ /* XIRQ */ + HANDLER vswi, HCS12_IRQ_VSWI /* SWI */ + HANDLER vtrap, HCS12_IRQ_VTRAP /* Unimplemented instruction trap */ + HANDLER vcop, HCS12_IRQ_VCOP /* COP failure reset*/ + HANDLER vclkmon, HCS12_IRQ_VCLKMON /* Clock monitor fail reset */ + HANDLER villegal, HCS12_IRQ_VILLEGAL /* Any reserved vector */ + +/************************************************************************************ + * Name: vcommon + * + * Description: + * Common IRQ handling logic + * + * On entry in to vcommon: (1) The interrupt stack fram is in place, and (2) the + * IRQ number is in B. + * + * On entry into an I- or X-interrupt, into an SWI, or into an undefined + * instruction interrupt, the stack frame created by hardware looks like: + * + * Low Address <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL <-- SP before interrupt + * + * This function will create the following stack frame and will call up_doirq(): + * + * Low Address <-- SP after state save + * [PPAGE] + * [soft regisers] + * XYH + * XYL + * ZH + * ZL + * TMPH + * TMPL + * FRAMEH + * FRAMEL + * SP <-- SP after interrupt + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL <-- SP before interrupt + * + ************************************************************************************/ + +vcommon: + /* Save the IRQ number currently in B */ + + stab .Lbsave + + /* Save the SP at the time of the interrupt */ + + tfr sp, d + addd #INTFRAME_SIZE + staa 1, -sp + stab 1, -sp + + /* Save the rest of the frame */ + + movw _.frame, 2, -sp + movw _.tmp, 2, -sp + movw _.z, 2, -sp + movw _.xy, 2, -sp + + /* Save the soft registers */ + +#if CONFIG_HCS12_MSOFTREGS > 2 +# error "Need to save more registers" +#endif +#if CONFIG_HCS12_MSOFTREGS > 1 + movw _.d2, 2, -sp +#endif +#if CONFIG_HCS12_MSOFTREGS > 0 + movw _.d1, 2, -sp +#endif + + /* Save the PPAGE register */ + +#ifndef CONFIG_HCS12_NONBANKED + movb HCS12_MMC_PPAGE, 1, -sp +#endif + + /* Handle the IRQ: AB=irqno, TOS=register save structure. Return value in d */ + /* SP now points o the bottom of the frame - 1 */ + + tfr sp, x + inx + std .Lspsave + std 2, -sp + + /* Recover the IRQ number and call up_doirq() */ + + ldab .Lbsave + CALL up_doirq + leas 2, sp + + /* Check if the return value in d is the same as regs parameter passed in the TOS */ + + cpd .Lspsave + bne up_fullcontextrestore + + /* Restore registers and return */ + + /* Restore the PPAGE register */ + +#ifndef CONFIG_HCS12_NONBANKED + movb 1, sp+, HCS12_MMC_PPAGE +#endif + + /* Restore the soft registers */ + +#if CONFIG_HCS12_MSOFTREGS > 0 + movw 2, sp+, _.d1 +#endif +#if CONFIG_HCS12_MSOFTREGS > 1 + movw 2, sp+, _.d2 +#endif + + /* Skip over the saved stack pointer */ + + ins + ins + + movw 2, sp+, _.xy + movw 2, sp+, _.z + movw 2, sp+, _.tmp + movw 2, sp+, _.frame + rti + .size handlers, .-handlers + +/************************************************************************************ + * Name: up_fullcontextrestore + * + * Description: + * Given a pointer to a register save block that was previously created by either + * interrupt handler or by up_saveusercontext(), restore the context of the saved + * thread, thereby completing a context switch. + * + * Low Address [PPAGE] + * [soft regisers] + * XYH + * XYL + * ZH + * ZL + * TMPH + * TMPL + * FRAMEH + * FRAMEL + * SP + * CCR + * B + * A + * XH + * XL + * YH + * YL + * PCH + * High Address PCL + * + * On entry: + * D = Address of the context switch save block + * + ************************************************************************************/ + +up_fullcontextrestore: + /* Make sure that interrupts are dissabled */ + + orcc #0x50 + + /* Exchange D with X. Now X points to the save structure. */ + + xgdx + + /* Recover PPAGE */ + +#ifndef CONFIG_HCS12_NONBANKED + movb 1, x+, HCS12_MMC_PPAGE +#endif + + /* Recover _.xy, _.z, _.tmp, _.frame */ + + movw 2, x+, _.xy + movw 2, x+, _.z + movw 2, x+, _.tmp + movw 2, x+, _.frame + + /* Recover SP "before" the interrupt occurred */ + + ldd 2, x+ + tfr d, sp + + /* Now, create a new interrupt return frame */ + + ldab #(INTFRAME_SIZE-1) /* Offset to PCL */ + abx /* X now points to last byte */ + + /* Copy the interrupt frame onto the stack */ + + movw 2, -sp, 2, -x /* Copy the PC */ + movw 2, -sp, 2, -x /* Copy Y */ + movw 2, -sp, 2, -x /* Copy X */ + movw 2, -sp, 2, -x /* Copy A:B */ + movw 1, -sp, 1, -x /* Copy CCR */ + rti /* And return from interrupt */ + .size up_fullcontextrestore, .-up_fullcontextrestore + +/************************************************************************************ + * .bss + ************************************************************************************/ +/************************************************************************************ + * Name: Temporaries used within vcommon + ************************************************************************************/ + + .comm .Lbsave, 1, 1 + .comm .Lspsave, 2, 1 + +/************************************************************************************ + * Name: up_interruptstack/g_intstackbase + * + * Description: + * If CONFIG_ARCH_INTERRUPTSTACK is defined, this sets aside memory for the + * interrupt stack. + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 1 + .comm .up_interruptstack:, CONFIG_ARCH_INTERRUPTSTACK, 1 +up_interruptstack_base: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..616125b34e64245936cfed0390b7531e6b767723 --- /dev/null +++ b/arch/mips/Kconfig @@ -0,0 +1,74 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_MIPS +choice + prompt "MIPS chip selection" + default ARCH_CHIP_PIC32MX + +config ARCH_CHIP_PIC32MX + bool "PIC32MX" + select ARCH_MIPS32 + select ARCH_HAVE_IRQPRIO + select ARCH_VECNOTIRQ + select ARCH_HAVE_RAMFUNCS + select ARCH_HAVE_SERIAL_TERMIOS + ---help--- + Microchip PIC32MX (MIPS32) + +config ARCH_CHIP_PIC32MZ + bool "PIC32MZ" + select ARCH_MIPS32 + select ARCH_HAVE_IRQPRIO + select ARCH_VECNOTIRQ + select ARCH_HAVE_RAMFUNCS + select ARCH_HAVE_SERIAL_TERMIOS + ---help--- + Microchip PIC32MZ (MIPS32) + +endchoice + +config ARCH_MIPS32 + bool + default n + select ARCH_HAVE_VFORK + +config ARCH_MIPS_24KC + bool + default n + +config ARCH_MIPS_M14K + bool + default n + select ARCH_HAVE_MICROMIPS + +config ARCH_HAVE_MICROMIPS + bool + default n + +config MIPS_MICROMIPS + bool "Use microMIPS ISA" + default n + depends on ARCH_HAVE_MICROMIPS + ---help--- + The processor supports both the MIPS32 ISA and the microMIPS ISA. + If this option is selected, the microMIPS ISA will be used. + Otherwise, the MIPS32 ISA will be used. + +config ARCH_FAMILY + string + default "mips32" if ARCH_MIPS32 + +config ARCH_CHIP + string + default "pic32mx" if ARCH_CHIP_PIC32MX + default "pic32mz" if ARCH_CHIP_PIC32MZ + +source arch/mips/src/common/Kconfig +source arch/mips/src/mips32/Kconfig +source arch/mips/src/pic32mx/Kconfig +source arch/mips/src/pic32mz/Kconfig + +endif diff --git a/arch/mips/include/.gitignore b/arch/mips/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6460c4a67846d5801c3600ce961277e3644f647 --- /dev/null +++ b/arch/mips/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/mips/include/arch.h b/arch/mips/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..04eb2a9d74c798c5508292090fa2f7f7ef1bceaa --- /dev/null +++ b/arch/mips/include/arch.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/mips/include/arch.h + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_ARCH_H +#define __ARCH_MIPS_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_MIPS_INCLUDE_ARCH_H */ + diff --git a/arch/mips/include/irq.h b/arch/mips/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..3ce95be7477de9c2bef9b401c971f9236ac05afe --- /dev/null +++ b/arch/mips/include/irq.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/mips/include/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_IRQ_H +#define __ARCH_MIPS_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/* Include AVR architecture-specific IRQ definitions (including register + * save structure and up_irq_save()/up_irq_restore() macros + */ + +#ifdef CONFIG_ARCH_MIPS32 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_IRQ_H */ + diff --git a/arch/mips/include/limits.h b/arch/mips/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..3b3ddb222437faeca91228359aef1e10576c02df --- /dev/null +++ b/arch/mips/include/limits.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/mips/include/limits.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_LIMITS_H +#define __ARCH_MIPS_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_MIPS_INCLUDE_LIMITS_H */ + diff --git a/arch/mips/include/mips32/cp0.h b/arch/mips/include/mips32/cp0.h new file mode 100644 index 0000000000000000000000000000000000000000..e6668fa8e3defb602057e794a6b47453014876d9 --- /dev/null +++ b/arch/mips/include/mips32/cp0.h @@ -0,0 +1,576 @@ +/******************************************************************************************** + * arch/mips/include/mips32/cp0.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_MIPS32_CP0_H +#define __ARCH_MIPS_INCLUDE_MIPS32_CP0_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* CP0 Register Addresses *******************************************************************/ + +#ifdef __ASSEMBLY__ +# define MIPS32_CP0_INDEX1 $0,0 /* Index into the TLB array */ +# define MIPS32_CP0_RANDOM1 $1,0 /* Randomly generated index into the TLB array */ +# define MIPS32_CP0_ENTRYLO01 $2,0 /* LS TLB entry for even-numbered pages */ +# define MIPS32_CP0_ENTRYLO11 $3,0 /* LS TLB entry for odd-numbered pages */ +# define MIPS32_CP0_CONTEXT2 $4,0 /* Page table address */ +# define MIPS32_CP0_PAGEMASK1 $5,0 /* Variable page sizes in TLB entries */ +# define MIPS32_CP0_WIRED1 $6,0 /* umber of fixed (“wired”) TLB entries */ +# define MIPS32_CP0_BADVADDR $8,0 /* Address of most recent exception */ +# define MIPS32_CP0_COUNT $9,0 /* Processor cycle count */ +# define MIPS32_CP0_ENTRYHI1 $10,0 /* High-order portion of the TLB entry */ +# define MIPS32_CP0_COMPARE $11,0 /* Timer interrupt control */ +# define MIPS32_CP0_STATUS $12,0 /* Processor status and control */ +# define MIPS32_CP0_CAUSE $13,0 /* Cause of last general exception */ +# define MIPS32_CP0_EPC $14,0 /* Program counter at last exception */ +# define MIPS32_CP0_PRID $15,0 /* Processor identification and revision */ +# define MIPS32_CP0_CONFIG $16,0 /* Configuration register */ +# define MIPS32_CP0_CONFIG1 $16,1 /* Configuration register 1 */ +# define MIPS32_CP0_CONFIG2 $16,2 /* Configuration register 3 */ +# define MIPS32_CP0_CONFIG3 $16,2 /* Configuration register 3 */ +# define MIPS32_CP0_LLADDR $17,0 /* Load linked address */ +# define MIPS32_CP0_WATCHLO2 $18,0 /* LS Watchpoint address */ +# define MIPS32_CP0_WATCHHI2 $19,0 /* MS Watchpoint address and mask */ +# define MIPS32_CP0_DEBUG3 $23,0 /* Debug control and exception status */ +# define MIPS32_CP0_DEPC3 $24,0 /* Program counter at last debug exception */ +# define MIPS32_CP0_ERRCTL $26,0 /* Controls access data CACHE instruction */ +# define MIPS32_CP0_TAGLO $28,0 /* LS portion of cache tag interface */ +# define MIPS32_CP0_DATALO $28,1 /* LS portion of cache tag interface */ +# define MIPS32_CP0_TAGHI $29,0 /* MS portion of cache tag interface */ +# define MIPS32_CP0_DATAHI $29,1 /* MS portion of cache tag interface */ +# define MIPS32_CP0_ERROREPC2 $30,0 /* Program counter at last error */ +# define MIPS32_CP0_DESAVE3 $31,0 /* Debug handler scratchpad register */ +#endif + +/* CP0 Registers ****************************************************************************/ + +/* Register Number: 0 Sel: 0 Name: Index + * Function: Index into the TLB array + * Compliance Level: Required for TLB-based MMUs; Optional otherwise. + */ + +#define CP0_INDEX_SHIFT (0) /* Bits 0-(n-1): TLB Index */ +#define CP0_INDEX_MASK (0x7fffffff) +#define CP0_INDEX_P (1 << 31) /* Bit 31: Probe failure */ + +/* Register Number: 1 Sel: 0 Name: Random + * Function: Randomly generated index into the TLB array + * Compliance Level: Required for TLB-based MMUs; Optional otherwise. + * + * This is a 32-bit register containing a random TLB index. The valid width is some fixed + * number, 'n', but the upper bits are padded so that no fields need be defined for this + * register. + */ + +/* Register Number: 2 Sel: 0 Name: EntryLo0 + * Function: Low-order portion of the TLB entry for even-numbered virtual pages + * Compliance Level: EntryLo0 is Required for a TLB-based MMU; Optional + * otherwise. + * + * Register Number: 3 Sel: 0 Name: EntryLo1 + * Function: Low-order portion of the TLB entry for odd-numbered virtual pages + * Compliance Level: EntryLo1 is Required for a TLB-based MMU; Optional otherwise. + */ + +#define CP0_ENTRYLO_G (1 << 0) /* Bit 0: Global bit */ +#define CP0_ENTRYLO_V (1 << 1) /* Bit 1: Valild bit */ +#define CP0_ENTRYLO_D (1 << 2) /* Bit 2: Dirty bit */ +#define CP0_ENTRYLO_C_SHIFT (3) /* Bits 3-5: Coherency attribute */ +#define CP0_ENTRYLO_C_MASK (7 << CP0_ENTRYLO_CSHIFT) +# define CP0_ENTRYLO_UNCACHED (2 << CP0_ENTRYLO_CSHIFT) +# define CP0_ENTRYLO_CACHEABLE (3 << CP0_ENTRYLO_CSHIFT) +#define CP0_ENTRYLO_PFN_SHIFT (6) /* Bits 6-29: Page frame number */ +#define CP0_ENTRYLO_PFN_MASK (0x00ffffff << CP0_ENTRYLO_CSHIFT) + +/* Register Number: 4 Sel: 0 Name: Context + * Function: Pointer to page table entry in memory + * Compliance Level: Required for TLB-based MMUs; Optional otherwise. + */ + +#define CP0_CONTEXT_BADVPN2_SHIFT (4) /* Bits 4-22: Virtual address that cause an excpetion */ +#define CP0_CONTEXT_BADVPN2_MASK (0x0007ffff << CP0_CONTEXT_BADVPN2_SHIFT) +#define CP0_CONTEXT_PTEBASE_SHIFT (23) /* Bits 23-31: Page table base address */ +#define CP0_CONTEXT_PTEBASE_MASK (0x000001ff << CP0_CONTEXT_PTEBASE_SHIFT) + +/* Register Number: 5 Sel: 0 Name: PageMask + * Function: Control for variable page size in TLB entries. + * Compliance Level: Required for TLB-based MMUs; Optional otherwise. + */ + +#define CP0_PAGEMASK_SHIFT (13) /* Bits 13-28: Page mask */ +#define CP0_PAGEMASK_MASK (0xffff << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_4KB (0x0000 << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_16KB (0x0003 << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_64KB (0x000f << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_256KB (0x003f << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_1MB (0x00ff << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_4MB (0x03ff << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_16MB (0x0fff << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_64MB (0x3fff << CP0_PAGEMASK_SHIFT) +# define CP0_PAGEMASK_256MB (0xffff << CP0_PAGEMASK_SHIFT) + +/* Register Number: 6 Sel: 0 Name: Wired + * Function: Controls the number of fixed (“wired”) TLB entries + * Compliance Level: Required for TLB-based MMUs; Optional otherwise. + * + * This is a 32-bit register containing the TLB wired boundary. The valid width is some + * fixed number, 'n', but the upper bits are padded so that no fields need be defined for + * this register. + * + * Register Number: 7 Sel: all (Reserved for future extensions) + * + * Register Number: 8 Sel: 0 Name: BadVAddr + * Function: Reports the address for the most recent address-related exception + * Compliance Level: Required. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + * + * Register Number: 9 Sel: 0 Name: Count + * Function: Processor cycle count + * Compliance Level: Required. + * + * This register contains a 32-bit count value; No fields need be defined for this + * register. + * + * Register Number: 9 Sel: 6-7 (Available for implementation dependent user) + */ + +/* Register Number: 10 Sel: 0 Name: EntryHi + * Function: High-order portion of the TLB entry + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + */ + +#define CP0_ENTRYHI_ASID_SHIFT (0) /* Bits 0-7: Address space identifier */ +#define CP0_ENTRYHI_ASID_MASK (0xff << CP0_ENTRYHI_ASID_SHIFT) +#define CP0_ENTRYHI_VPN2_SHIFT (13) /* Bits 13-31: Virtual address */ +#define CP0_ENTRYHI_VPN2_MASK (0x0007ffff << CP0_ENTRYHI_VPN2_SHIFT) + +/* Register Number: 11 Sel: 0 Name: Compare + * Function: Timer interrupt control + * Compliance Level: Required. + * + * This register contains a 32-bit compare value; No fields need be defined for this + * register. + * + * Register Number: 11 Sel: 6-7 (Available for implementation dependent user) + */ + +/* Register Number: 12 Sel: 0 Name: Status + * Function: Processor status and control + * Compliance Level: Required. + */ + +#define CP0_STATUS_IE (1 << 0) /* Bit 0: Interrupt Enable */ +#define CP0_STATUS_EXL (1 << 1) /* Bit 1: Exception Level */ +#define CP0_STATUS_ERL (1 << 2) /* Bit 2: Error Level */ +#define CP0_STATUS_KSU_SHIFT (3) /* Bits 3-4: Operating mode (with supervisor mode) */ +#define CP0_STATUS_KSU_MASK (3 << CP0_STATUS_KSU_SHIFT) +# define CP0_STATUS_KSU_KERNEL (0 << CP0_STATUS_KSU_SHIFT) +# define CP0_STATUS_KSU_SUPER (1 << CP0_STATUS_KSU_SHIFT) +# define CP0_STATUS_KSU_USER (2 << CP0_STATUS_KSU_SHIFT) +#define CP0_STATUS_UM (1 << 4) /* Bit 4: Operating mode == USER (No supervisor mode) */ +#define CP0_STATUS_UX (1 << 5) /* Bit 5: Enables 64-bit user address space (Not MIPS32) */ +#define CP0_STATUS_SX (1 << 6) /* Bit 6: Enables 64-bit supervisor address space (Not MIPS32) */ +#define CP0_STATUS_KX (1 << 7) /* Bit 7: Enables 64-bit kernel address space (Not MIPS32) */ +#define CP0_STATUS_IM_SHIFT (8) /* Bits 8-15: Interrupt Mask */ +#define CP0_STATUS_IM_MASK (0xff << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM_SWINTS (0x03 << CP0_STATUS_IM_SHIFT) /* IM0-1 = Software interrupts */ +# define CP0_STATUS_IM0 (0x01 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM1 (0x02 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM_HWINTS (0x7c << CP0_STATUS_IM_SHIFT) /* IM2-6 = Hardware interrupts */ +# define CP0_STATUS_IM2 (0x04 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM3 (0x08 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM4 (0x10 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM5 (0x20 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM6 (0x40 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM_TIMER (0x80 << CP0_STATUS_IM_SHIFT) /* IM7 = Hardware/Timer/Perf interrupts */ +# define CP0_STATUS_IM7 (0x80 << CP0_STATUS_IM_SHIFT) +# define CP0_STATUS_IM_ALL (0xff << CP0_STATUS_IM_SHIFT) +#define CP0_STATUS_IMPL_SHIFT (16) /* Bits 16-17: Implementation dependent */ +#define CP0_STATUS_IMPL_MASK (3 << CP0_STATUS_IMPL_SHIFT) +#define CP0_STATUS_NMI (1 << 19) /* Bit 19: Reset exception due to an NMI */ +#define CP0_STATUS_SR (1 << 20) /* Bit 20: Reset exception due to a Soft Reset */ +#define CP0_STATUS_TS (1 << 21) /* Bit 21: TLB detected match on multiple entries */ +#define CP0_STATUS_BEV (1 << 22) /* Bit 22: Location of exception vectors 1->Bootstrap */ +#define CP0_STATUS_PX (1 << 23) /* Bit 23: Enables 64-bit operations (Not MIPS32) */ +#define CP0_STATUS_MX (1 << 24) /* Bit 24: Enables MDMX™ (Not MIPS32) */ +#define CP0_STATUS_RE (1 << 25) /* Bit 25: Enable reverse-endian memory in user mode */ +#define CP0_STATUS_FR (1 << 26) /* Bit 26: Controls the floating point register mode (Not MIPS32) */ +#define CP0_STATUS_RP (1 << 27) /* Bit 27: Enables reduced power mode */ +#define CP0_STATUS_CU0 (1 << 28) /* Bit 28: Controls access to coprocessor 0 */ +#define CP0_STATUS_CU1 (1 << 29) /* Bit 29: Controls access to coprocessor 1 */ +#define CP0_STATUS_CU2 (1 << 30) /* Bit 30: Controls access to coprocessor 2 */ +#define CP0_STATUS_CU3 (1 << 31) /* Bit 31: Controls access to coprocessor 3 */ + +/* Register Number: 13 Sel: 0 Name: Cause + * Function: Cause of last general exception + * Compliance Level: Required. + */ + +#define CP0_CAUSE_EXCCODE_SHIFT (2) /* Bits 2-6: Exception code */ +#define CP0_CAUSE_EXCCODE_MASK (31 << CP0_CAUSE_EXCCODE_SHIFT) +# define CP0_CAUSE_EXCCODE_INT (0 << CP0_CAUSE_EXCCODE_SHIFT) /* Interrupt */ +# define CP0_CAUSE_EXCCODE_TLBL (2 << CP0_CAUSE_EXCCODE_SHIFT) /* TLB exception (load or instruction fetch) */ +# define CP0_CAUSE_EXCCODE_TLBS (3 << CP0_CAUSE_EXCCODE_SHIFT) /* TLB exception (store) */ +# define CP0_CAUSE_EXCCODE_ADEL (4 << CP0_CAUSE_EXCCODE_SHIFT) /* Address error exception (load or instruction fetch) */ +# define CP0_CAUSE_EXCCODE_ADES (5 << CP0_CAUSE_EXCCODE_SHIFT) /* Address error exception (store) */ +# define CP0_CAUSE_EXCCODE_IBE (6 << CP0_CAUSE_EXCCODE_SHIFT) /* Bus error exception (instruction fetch) */ +# define CP0_CAUSE_EXCCODE_DBE (7 << CP0_CAUSE_EXCCODE_SHIFT) /* Bus error exception (data reference: load or store) */ +# define CP0_CAUSE_EXCCODE_SYS (8 << CP0_CAUSE_EXCCODE_SHIFT) /* Syscall exception */ +# define CP0_CAUSE_EXCCODE_BP (9 << CP0_CAUSE_EXCCODE_SHIFT) /* Breakpoint exception */ +# define CP0_CAUSE_EXCCODE_RI (10 << CP0_CAUSE_EXCCODE_SHIFT) /* Reserved instruction exception */ +# define CP0_CAUSE_EXCCODE_CPU (11 << CP0_CAUSE_EXCCODE_SHIFT) /* Coprocessor Unusable exception */ +# define CP0_CAUSE_EXCCODE_OV (12 << CP0_CAUSE_EXCCODE_SHIFT) /* Arithmetic Overflow exception */ +# define CP0_CAUSE_EXCCODE_TR (13 << CP0_CAUSE_EXCCODE_SHIFT) /* Trap exception */ +# define CP0_CAUSE_EXCCODE_FPE (15 << CP0_CAUSE_EXCCODE_SHIFT) /* Floating point exception */ +# define CP0_CAUSE_EXCCODE_C2E (18 << CP0_CAUSE_EXCCODE_SHIFT) /* Precise Coprocessor 2 exceptions */ +# define CP0_CAUSE_EXCCODE_MDMX (22 << CP0_CAUSE_EXCCODE_SHIFT) /* MDMX Unusable (MIPS64) */ +# define CP0_CAUSE_EXCCODE_WATCH (23 << CP0_CAUSE_EXCCODE_SHIFT) /* WatchHi/WatchLo address */ +# define CP0_CAUSE_EXCCODE_MCHECK (24 << CP0_CAUSE_EXCCODE_SHIFT) /* Machine check */ +# define CP0_CAUSE_EXCCODE_CACHEERR (30 << CP0_CAUSE_EXCCODE_SHIFT) /* Cache error */ +#define CP0_CAUSE_IP0 (1 << 8) /* Bit 8: Controls request for software interrupt 0 */ +#define CP0_CAUSE_IP1 (1 << 9) /* Bit 9: Controls request for software interrupt 1 */ +#define CP0_CAUSE_IP_SHIFT (10) /* Bits 10-15: Pending external interrupts */ +#define CP0_CAUSE_IP_MASK (0x3f << CP0_CAUSE_IP_SHIFT) +# define CP0_CAUSE_IP2 (0x10 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 0 */ +# define CP0_CAUSE_IP3 (0x11 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 1 */ +# define CP0_CAUSE_IP4 (0x12 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 2 */ +# define CP0_CAUSE_IP5 (0x13 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 3 */ +# define CP0_CAUSE_IP6 (0x14 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 4 */ +# define CP0_CAUSE_IP7 (0x15 << CP0_CAUSE_IP_SHIFT) /* Hardware interrupt 5, timer or performance counter interrupt */ +#define CP0_CAUSE_WP (1 << 22) /* Watch exception was deferred */ +#define CP0_CAUSE_IV (1 << 23) /* Bit 23: Interrupt exception uses special interrupt vector */ +#define CP0_CAUSE_CE_SHIFT (28) /* Bits 28-29: Coprocessor unit number fo Coprocessor Unusable exception */ +#define CP0_CAUSE_CE_MASK (3 << CP0_CAUSE_CE_SHIFT) +#define CP0_CAUSE_BD (1 << 31) /* Bit 31: Last exception occurred in a branch delay slot */ + +/* Register Number: 14 Sel: 0 Name: EPC + * Function: Program counter at last exception + * Compliance Level: Required. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + */ + +/* Register Number: 15 Sel: 0 Name: PRId + * Function: Processor identification and revision + * Compliance Level: Required. + */ + +#define CP0_PRID_REV_SHIFT (0) /* Bits 0-7: Revision number of the processor */ +#define CP0_PRID_REV_MASK (0xff << CP0_PRID_REV_SHIFT) +#define CP0_PRID_PROCID_SHIFT (8) /* Bits 8-15: Type of processor */ +#define CP0_PRID_PROCID_MASK (0xff << CP0_PRID_PROCID_SHIFT) +#define CP0_PRID_COMPANY_SHIFT (16) /* Bits 16-23: Company ID */ +#define CP0_PRID_COMPANY_MASK (0xff << CP0_PRID_COMPANY_SHIFT) +#define CP0_PRID_OPTIONS_SHIFT (24) /* Bits 24-31: Company-dependent options */ +#define CP0_PRID_OPTIONS_MASK (0xff << CP0_PRID_OPTIONS_SHIFT) + +/* Register Number: 16 Sel: 0 Name: Config + * Function: Configuration register + * Compliance Level: Required. + */ + +#define CP0_CONFIG_K0_SHIFT (0) /* Bits 0-2: KSEG0 coherency algorithm */ +#define CP0_CONFIG_K0_MASK (7 << CP0_CONFIG_K0_SHIFT) +# define CP0_CONFIG_K0_UNCACHED (2 << CP0_CONFIG_K0_SHIFT) +# define CP0_CONFIG_K0_CACHEABLE (3 << CP0_CONFIG_K0_SHIFT) +#define CP0_CONFIG_MT_SHIFT (7) /* Bits 7-9: MMU Type */ +#define CP0_CONFIG_MT_MASK (7 << CP0_CONFIG_MT_SHIFT) +# define CP0_CONFIG_MT_NONE (0 << CP0_CONFIG_MT_SHIFT) /* None */ +# define CP0_CONFIG_MT_TLB (1 << CP0_CONFIG_MT_SHIFT) /* Standard TLB */ +# define CP0_CONFIG_MT_BAT (2 << CP0_CONFIG_MT_SHIFT) /* Standard BAT */ +# define CP0_CONFIG_MT_FIXED (3 << CP0_CONFIG_MT_SHIFT) /* Standard fixed mapping */ +#define CP0_CONFIG_AR_SHIFT (10) /* Bits 10-12: Architecture revision level */ +#define CP0_CONFIG_AR_MASK (7 << CP0_CONFIG_AR_SHIFT) +# define CP0_CONFIG_AR_REV1 (0 << CP0_CONFIG_AR_SHIFT) +# define CP0_CONFIG_AR_REV2 (1 << CP0_CONFIG_AR_SHIFT) +#define CP0_CONFIG_AT_SHIFT (13) /* Bits 13-14: Architecture type implemented by the processor */ +#define CP0_CONFIG_AT_MASK (3 << CP0_CONFIG_AT_SHIFT) +# define CP0_CONFIG_AT_MIPS32 (0 << CP0_CONFIG_AT_SHIFT) /* MIPS32 */ +# define CP0_CONFIG_AT_MIPS64CMP (0 << CP0_CONFIG_AT_SHIFT) /* MIPS64 with 32-bit compatibility segments */ +# define CP0_CONFIG_AT_MIPS64 (1 << CP0_CONFIG_AT_SHIFT) /* MIPS64 with access to all address segments */ +#define CP0_CONFIG_BE (1 << 15) /* Bit 15: Processor is running in big-endian mode */ +#define CP0_CONFIG_IMPL_SHIFT (16) /* Bits 16-30: Implementation dependent */ +#define CP0_CONFIG_IMPL_MASK (0x7fff << CP0_CONFIG_IMPL_SHIFT) +#define CP0_CONFIG_M (1 << 31) /* Bit 31: Config1 register is implemented at select=1 */ + +/* Register Number: 16 Sel: 1 Name: Config1 + * Function: Configuration register 1 + * Compliance Level: Required. + */ + +#define CP0_CONFIG1_FP (1 << 0 FPU implemented +#define CP0_CONFIG1_EP (1 << 1 EJTAG implemented +#define CP0_CONFIG1_CA (1 << 2 Code compression (MIPS16) implemented +#define CP0_CONFIG1_WR (1 << 3 Watch registers implemented +#define CP0_CONFIG1_PC (1 << 4 Performance Counter registers implemented +#define CP0_CONFIG1_MD (1 << 5 MDMX ASE implemented (MIPS64) +#define CP0_CONFIG1_C2 (1 << 6 Coprocessor 2 implemented +#define CP0_CONFIG1_DA_SHIFT (7) /* Bits 7-9: Dcache associativity */ +#define CP0_CONFIG1_DA_MASK (7 << CP0_CONFIG1_DA_SHIFT) +# define CP0_CONFIG1_DA_DIRECT (0 << CP0_CONFIG1_DA_SHIFT) /* Direct mapped */ +# define CP0_CONFIG1_DA_2WAY (1 << CP0_CONFIG1_DA_SHIFT) /* 2-way */ +# define CP0_CONFIG1_DA_3WAY (2 << CP0_CONFIG1_DA_SHIFT) /* 3-way */ +# define CP0_CONFIG1_DA_4WAY (3 << CP0_CONFIG1_DA_SHIFT) /* 4-way */ +# define CP0_CONFIG1_DA_5WAY (4 << CP0_CONFIG1_DA_SHIFT) /* 5-way */ +# define CP0_CONFIG1_DA_6WAY (5 << CP0_CONFIG1_DA_SHIFT) /* 6-way */ +# define CP0_CONFIG1_DA_7WAY (6 << CP0_CONFIG1_DA_SHIFT) /* 7-way */ +# define CP0_CONFIG1_DA_8WAY (7 << CP0_CONFIG1_DA_SHIFT) /* 8-way */ +#define CP0_CONFIG1_DL_SHIFT (10) /* Bits 10-12: Dcache line size */ +#define CP0_CONFIG1_DL_MASK (7 << CP0_CONFIG1_DL_SHIFT) +# define CP0_CONFIG1_DL_NONE (0 << CP0_CONFIG1_DL_SHIFT) /* No Dcache present */ +# define CP0_CONFIG1_DL_4BYTES (1 << CP0_CONFIG1_DL_SHIFT) /* 4 bytes */ +# define CP0_CONFIG1_DL_8BYTES (2 << CP0_CONFIG1_DL_SHIFT) /* 8 bytes */ +# define CP0_CONFIG1_DL_16BYTES (3 << CP0_CONFIG1_DL_SHIFT) /* 16 bytes */ +# define CP0_CONFIG1_DL_32BYTES (4 << CP0_CONFIG1_DL_SHIFT) /* 32 bytes */ +# define CP0_CONFIG1_DL_64BYTES (5 << CP0_CONFIG1_DL_SHIFT) /* 64 bytes */ +# define CP0_CONFIG1_DL_128BYTES (6 << CP0_CONFIG1_DL_SHIFT) /* 128 bytes */ +#define CP0_CONFIG1_DS_SHIFT (13) /* Bits 13-15: Dcache sets per way */ +#define CP0_CONFIG1_DS_MASK (7 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_64SETS (0 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_128SETS (1 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_256SETS (2 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_512SETS (3 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_1024SETS (4 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_2048SETS (5 << CP0_CONFIG1_DS_SHIFT) +# define CP0_CONFIG1_DS_4096SETS (6 << CP0_CONFIG1_DS_SHIFT) +#define CP0_CONFIG1_IA_SHIFT (16) /* Bits 16-18: Icache associativity */ +#define CP0_CONFIG1_IA_MASK (7 << CP0_CONFIG1_IA_SHIFT) +# define CP0_CONFIG1_IA_DIRECT (0 << CP0_CONFIG1_IA_SHIFT) /* Direct mapped */ +# define CP0_CONFIG1_IA_2WAY (1 << CP0_CONFIG1_IA_SHIFT) /* 2-way */ +# define CP0_CONFIG1_IA_3WAY (2 << CP0_CONFIG1_IA_SHIFT) /* 3-way */ +# define CP0_CONFIG1_IA_4WAY (3 << CP0_CONFIG1_IA_SHIFT) /* 4-way */ +# define CP0_CONFIG1_IA_5WAY (4 << CP0_CONFIG1_IA_SHIFT) /* 5-way */ +# define CP0_CONFIG1_IA_6WAY (5 << CP0_CONFIG1_IA_SHIFT) /* 6-way */ +# define CP0_CONFIG1_IA_7WAY (6 << CP0_CONFIG1_IA_SHIFT) /* 7-way */ +# define CP0_CONFIG1_IA_8WAY (7 << CP0_CONFIG1_IA_SHIFT) /* 8-way */ +#define CP0_CONFIG1_IL_SHIFT (19) /* Bits 19-21: Icache line size */ +#define CP0_CONFIG1_IL_MASK (7 << CP0_CONFIG1_IL_SHIFT) +# define CP0_CONFIG1_IL_NONE (0 << CP0_CONFIG1_IL_SHIFT) /* No Dcache present */ +# define CP0_CONFIG1_IL_4BYTES (1 << CP0_CONFIG1_IL_SHIFT) /* 4 bytes */ +# define CP0_CONFIG1_IL_8BYTES (2 << CP0_CONFIG1_IL_SHIFT) /* 8 bytes */ +# define CP0_CONFIG1_IL_16BYTES (3 << CP0_CONFIG1_IL_SHIFT) /* 16 bytes */ +# define CP0_CONFIG1_IL_32BYTES (4 << CP0_CONFIG1_IL_SHIFT) /* 32 bytes */ +# define CP0_CONFIG1_IL_64BYTES (5 << CP0_CONFIG1_IL_SHIFT) /* 64 bytes */ +# define CP0_CONFIG1_IL_128BYTES (6 << CP0_CONFIG1_IL_SHIFT) /* 128 bytes */ +#define CP0_CONFIG1_IS_SHIFT (22) /* Bits 22-24: Icache sets per way */ +#define CP0_CONFIG1_IS_MASK (7 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_64SETS (0 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_128SETS (1 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_256SETS (2 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_512SETS (3 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_1024SETS (4 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_2048SETS (5 << CP0_CONFIG1_IS_SHIFT) +# define CP0_CONFIG1_IS_4096SETS (6 << CP0_CONFIG1_IS_SHIFT) +#define CP0_CONFIG1_MMUSIZE_SHIFT (25) /* Bits 25-30: Number of entries in the TLB minus one */ +#define CP0_CONFIG1_MMUSIZE_MASK (0x3f << CP0_CONFIG1_MMUSIZE_SHIFT) +#define CP0_CONFIG1_M (1 << 31) /* Bit 31: Config2 register is present */ + +/* Register Number: 16 Sel: 2 Name: Config2 + * Function: Configuration register 2 + * Compliance Level: Optional. + */ + +#define CP0_CONFIG2_TBS_SHIFT (0) /* Bits 0-30: Configuration of the level 2 and level 3 caches */ +#define CP0_CONFIG2_TBS_MASK (0x7fffffff << CP0_CONFIG2_TBS_SHIFT) +#define CP0_CONFIG2_M (1 << 31) /* Bit 31: Config3 register is present */ + +/* Register Number: 16 Sel: 3 Name: Config3 + * Function: Configuration register 3 + * Compliance Level: Optional. + */ +#define CP0_CONFIG3_TL (1 << 0) /* Bit 0: Trace Logic implemented */ +#define CP0_CONFIG3_SM (1 << 1) /* Bit 1: SmartMIPS™ ASE implemented */ +#define CP0_CONFIG3_M (1 << 31) /* Bit 31: Config4 register is present */ + +/* Register Number: 16 Sel: 6-7 (Available for implementation dependent use) */ + +/* Register Number: 17 Sel: 0 Name: LLAddr + * Function: Load linked address + * Compliance Level: Optional. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + */ + +/* Register Number: 18 Sel: 0-n Name: WatchLo + * Function: Watchpoint address + * Compliance Level: Optional. + */ + +#define CP0_WATCHLO_W (1 << 0) /* Bit 0: Exceptions are enabled for stores */ +#define CP0_WATCHLO_R (1 << 1) /* Bit 0: Exceptions are enabled for loads */ +#define CP0_WATCHLO_I (1 << 2) /* Bit 0: Exceptions are enabled for instructions */ +#define CP0_WATCHLO_VADDR_SHIFT (3) /* Bits 3-31: Virtual address to match */ +#define CP0_WATCHLO_VADDR_MASK (0x1fffffff << CP0_WATCHLO_VADDR_SHIFT) + +/* Register Number: 19 Sel: 0-n Name: WatchHi + * Function: Watchpoint control + * Compliance Level: Optional. + */ + +#define CP0_WATCHHI_MASK_SHIFT (3) /* Bits 3-11: Mask that qualifies the WatchLo address */ +#define CP0_WATCHHI_MASK_MASK (0x1ff << CP0_WATCHHI_MASK_SHIFT) +#define CP0_WATCHHI_ASID_SHIFT (16) /* Bits 16-23: ASID value which to match that in the EntryHi register */ +#define CP0_WATCHHI_ASID_MASK (0xff << CP0_WATCHHI_ASID_SHIFT) +#define CP0_WATCHHI_G (1 << 30) /* Bit 30: Any address matcing the WatchLo addr will cause an exception */ +#define CP0_WATCHHI_M (1 << 31) /* Bit 30: Another pair of WatchHi/WatchLo registers at select n+1 */ + +/* Register Number: 20 Sel: 0 Name: XContext + * Function: in 64-bit implementations + * + * Register Number: 21 Sel: all (Reserved for future extensions) + * + * Register Number: 22 Sel: all Available for implementation dependent use) + * + * Register Number: 23 Sel: 0 Name: Debug + * Function: EJTAG Debug register + * Compliance Level: Optional, part of the EJTAG specification. + * + * Register Number: 24 Sel: 0 Name: DEPC + * Function: Program counter at last EJTAG debug exception + * Compliance Level: Optional, part of the EJTAG specification. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + */ + +/* Register Number: 25 Sel: 0-n Name: PerfCnt + * Function: Performance counter interface + * Compliance Level: Recommended. + */ + +#define CP0_PERFCNT_EXL (1 << 0) /* Bit 0: Enables event counting when STATUS EXL=1 ERL=0 */ +#define CP0_PERFCNT_K (1 << 1) /* Bit 1: Enables event counting in Kernel Mode (EXL=0 ERL=0) */ +#define CP0_PERFCNT_S (1 << 2) /* Bit 2: Enables event counting in Supervisor Mode */ +#define CP0_PERFCNT_U (1 << 3) /* Bit 3: Enables event counting in User Mode */ +#define CP0_PERFCNT_IE (1 << 4) /* Bit 4: Interrupt Enable */ +#define CP0_PERFCNT_EVENT_SHIFT (5) /* Bits 5-10: Event to be counted */ +#define CP0_PERFCNT_EVENT_MASK (0xffff << CP0_PERFCNT_EVENT_SHIFT) +#define CP0_PERFCNT_M (1 << 31) /* Bit 31: Another pair of performance registers at n+2 and n+3 */ + +/* Register Number: 26 Sel: 0 Name: ErrCtl + * Function: Parity/ECC error control and status + * Compliance Level: Optional. + * + * The bit definitions within the ErrCtl register are implementation dependent. + * + * Register Number: 27 Sel: 0-3 Name: CacheErr + * Function: Cache parity error control and status + * Compliance Level: Optional. + * + * The bit definitions within the CacheErr register are implementation dependent. + * + * Register Number: 28 Sel: 0 Name: TagLo + * Function: Low-order portion of cache tag interface + * Compliance Level: Required if a cache is implemented; Optional otherwise. + * + * The bit definitions within the TagLo register are implementation dependent. + * + * Register Number: 28 Sel: 1, 3 Name: DataLo + * Function: The DataLo and DataHi registers are read-only registers that + * act as the interface to the cache data array and are intended for + * diagnostic operation only. + * Compliance Level: Optional. + * + * The bit definitions within the DataLo register are implementation dependent. + * + * Register Number: 29 Sel: 0 Name: TagHi + * Function: High-order portion of cache tag interface + * Compliance Level: Required if a cache is implemented; Optional otherwise. + * + * The bit definitions within the TagHi register are implementation dependent. + * + * Register Number: 29 Sel: 1, 3 Name: DataHi + * Function: The DataLo and DataHi registers are read-only registers that + * act as the interface to the cache data array and are intended for + * diagnostic operation only. + * Compliance Level: Optional. + * + * The bit definitions within the DataHi register are implementation dependent. + * + * Register Number: 30 Sel: 0 Name: ErrorEPC + * Function: Program counter at last error + * Compliance Level: Required. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + * + * Register Number: 31 Sel: 0 Name: DESAVE + * Function: EJTAG debug exception save register + * Compliance Level: Optional, part of the EJTAG specification. + * + * This register contains a 32-bit address value; No fields need be defined for this + * register. + */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_MIPS32_CP0_H */ diff --git a/arch/mips/include/mips32/irq.h b/arch/mips/include/mips32/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..143387fc06a70bd097510f3417bb82afbbdc4ed3 --- /dev/null +++ b/arch/mips/include/mips32/irq.h @@ -0,0 +1,567 @@ +/**************************************************************************** + * arch/mips/include/mips32/irq.h + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_MIPS32_IRQ_H +#define __ARCH_MIPS_INCLUDE_MIPS32_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* The global pointer (GP) does not need to be saved in the "normal," flat + * NuttX build. However, it would be necessary to save the GP if this is + * a KERNEL build or if NXFLAT is supported. + */ + +#undef MIPS32_SAVE_GP +#if defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NXFLAT) +# define MIPS32_SAVE_GP 1 +#endif + +/* If this is a kernel build, how many nested system calls should we support? */ + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +/* Register save state structure ********************************************/ +/* Co processor registers */ + +#define REG_MFLO_NDX 0 +#define REG_MFHI_NDX 1 +#define REG_EPC_NDX 2 +#define REG_STATUS_NDX 3 + +/* General pupose registers */ +/* $0: Zero register does not need to be saved */ +/* $1: at_reg, assembler temporary */ + +#define REG_R1_NDX 4 + +/* $2-$3 = v0-v1: Return value registers */ + +#define REG_R2_NDX 5 +#define REG_R3_NDX 6 + +/* $4-$7 = a0-a3: Argument registers */ + +#define REG_R4_NDX 7 +#define REG_R5_NDX 8 +#define REG_R6_NDX 9 +#define REG_R7_NDX 10 + +/* $8-$15 = t0-t7: Volatile registers */ + +#define REG_R8_NDX 11 +#define REG_R9_NDX 12 +#define REG_R10_NDX 13 +#define REG_R11_NDX 14 +#define REG_R12_NDX 15 +#define REG_R13_NDX 16 +#define REG_R14_NDX 17 +#define REG_R15_NDX 18 + +/* $16-$23 = s0-s7: Static registers */ + +#define REG_R16_NDX 19 +#define REG_R17_NDX 20 +#define REG_R18_NDX 21 +#define REG_R19_NDX 22 +#define REG_R20_NDX 23 +#define REG_R21_NDX 24 +#define REG_R22_NDX 25 +#define REG_R23_NDX 26 + +/* $24-25 = t8-t9: More Volatile registers */ + +#define REG_R24_NDX 27 +#define REG_R25_NDX 28 + +/* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need + * to be saved. + */ + +/* $28 = gp: Only needs to be saved under conditions where there are + * multiple, per-thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP + +# define REG_R28_NDX 29 + +/* $29 = sp: The value of the stack pointer on return from the exception */ + +# define REG_R29_NDX 30 + +/* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + +# define REG_R30_NDX 31 + +/* $31 = ra: Return address */ + +# define REG_R31_NDX 32 +# define XCPTCONTEXT_REGS 33 +#else + +/* $29 = sp: The value of the stack pointer on return from the exception */ + +# define REG_R29_NDX 29 + +/* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + +# define REG_R30_NDX 30 + +/* $31 = ra: Return address */ + +# define REG_R31_NDX 31 +# define XCPTCONTEXT_REGS 32 +#endif +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* In assembly language, values have to be referenced as byte address + * offsets. But in C, it is more convenient to reference registers as + * register save table offsets. + */ + +#ifdef __ASSEMBLY__ +# define REG_MFLO (4*REG_MFLO_NDX) +# define REG_MFHI (4*REG_MFHI_NDX) +# define REG_EPC (4*REG_EPC_NDX) +# define REG_STATUS (4*REG_STATUS_NDX) +# define REG_R1 (4*REG_R1_NDX) +# define REG_R2 (4*REG_R2_NDX) +# define REG_R3 (4*REG_R3_NDX) +# define REG_R4 (4*REG_R4_NDX) +# define REG_R5 (4*REG_R5_NDX) +# define REG_R6 (4*REG_R6_NDX) +# define REG_R7 (4*REG_R7_NDX) +# define REG_R8 (4*REG_R8_NDX) +# define REG_R9 (4*REG_R9_NDX) +# define REG_R10 (4*REG_R10_NDX) +# define REG_R11 (4*REG_R11_NDX) +# define REG_R12 (4*REG_R12_NDX) +# define REG_R13 (4*REG_R13_NDX) +# define REG_R14 (4*REG_R14_NDX) +# define REG_R15 (4*REG_R15_NDX) +# define REG_R16 (4*REG_R16_NDX) +# define REG_R17 (4*REG_R17_NDX) +# define REG_R18 (4*REG_R18_NDX) +# define REG_R19 (4*REG_R19_NDX) +# define REG_R20 (4*REG_R20_NDX) +# define REG_R21 (4*REG_R21_NDX) +# define REG_R22 (4*REG_R22_NDX) +# define REG_R23 (4*REG_R23_NDX) +# define REG_R24 (4*REG_R24_NDX) +# define REG_R25 (4*REG_R25_NDX) +# ifdef MIPS32_SAVE_GP +# define REG_R28 (4*REG_R28_NDX) +# endif +# define REG_R29 (4*REG_R29_NDX) +# define REG_R30 (4*REG_R30_NDX) +# define REG_R31 (4*REG_R31_NDX) +#else +# define REG_MFLO REG_MFLO_NDX +# define REG_MFHI REG_MFHI_NDX +# define REG_EPC REG_EPC_NDX +# define REG_STATUS REG_STATUS_NDX +# define REG_R1 REG_R1_NDX +# define REG_R2 REG_R2_NDX +# define REG_R3 REG_R3_NDX +# define REG_R4 REG_R4_NDX +# define REG_R5 REG_R5_NDX +# define REG_R6 REG_R6_NDX +# define REG_R7 REG_R7_NDX +# define REG_R8 REG_R8_NDX +# define REG_R9 REG_R9_NDX +# define REG_R10 REG_R10_NDX +# define REG_R11 REG_R11_NDX +# define REG_R12 REG_R12_NDX +# define REG_R13 REG_R13_NDX +# define REG_R14 REG_R14_NDX +# define REG_R15 REG_R15_NDX +# define REG_R16 REG_R16_NDX +# define REG_R17 REG_R17_NDX +# define REG_R18 REG_R18_NDX +# define REG_R19 REG_R19_NDX +# define REG_R20 REG_R20_NDX +# define REG_R21 REG_R21_NDX +# define REG_R22 REG_R22_NDX +# define REG_R23 REG_R23_NDX +# define REG_R24 REG_R24_NDX +# define REG_R25 REG_R25_NDX +# ifdef MIPS32_SAVE_GP +# define REG_R28 REG_R28_NDX +# endif +# define REG_R29 REG_R29_NDX +# define REG_R30 REG_R30_NDX +# define REG_R31 REG_R31_NDX +#endif + +/* Now define more user friendly alternative name that can be used either + * in assembly or C contexts. + */ + +/* $1: at_reg, assembler temporary */ + +#define REG_AT REG_R1 + +/* $2-$3 = v0-v1: Return value registers */ + +#define REG_V0 REG_R2 +#define REG_V1 REG_R3 + +/* $4-$7 = a0-a3: Argument registers */ + +#define REG_A0 REG_R4 +#define REG_A1 REG_R5 +#define REG_A2 REG_R6 +#define REG_A3 REG_R7 + +/* $8-$15 = t0-t7: Volatile registers */ + +#define REG_T0 REG_R8 +#define REG_T1 REG_R9 +#define REG_T2 REG_R10 +#define REG_T3 REG_R11 +#define REG_T4 REG_R12 +#define REG_T5 REG_R13 +#define REG_T6 REG_R14 +#define REG_T7 REG_R15 + +/* $16-$23 = s0-s7: Static registers */ + +#define REG_S0 REG_R16 +#define REG_S1 REG_R17 +#define REG_S2 REG_R18 +#define REG_S3 REG_R19 +#define REG_S4 REG_R20 +#define REG_S5 REG_R21 +#define REG_S6 REG_R22 +#define REG_S7 REG_R23 + +/* $24-25 = t8-t9: More Volatile registers */ + +#define REG_T8 REG_R24 +#define REG_T9 REG_R25 + +/* $28 = gp: Only needs to be saved under conditions where there are + * multiple, per-thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP +# define REG_GP REG_R28 +#endif + +/* $29 = sp: The value of the stack pointer on return from the exception */ + +#define REG_SP REG_R29 + +/* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + +#define REG_S8 REG_R30 +#define REG_FP REG_R30 + +/* $31 = ra: Return address */ + +#define REG_RA REG_R31 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_BUILD_KERNEL +struct xcpt_syscall_s +{ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ +#ifndef CONFIG_DISABLE_SIGNALS + /* The following function pointer is non-NULL if there are pending signals + * to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These additional register save locations are used to implement the + * signal delivery trampoline. + */ + + uint32_t saved_epc; /* Trampoline PC */ + uint32_t saved_status; /* Status with interrupts disabled. */ + +# ifdef CONFIG_BUILD_KERNEL + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; + +# endif +#endif + +#ifdef CONFIG_BUILD_KERNEL + /* The following array holds information needed to return from each nested + * system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; + +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cp0_getstatus + * + * Description: + * Read the CP0 STATUS register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline irqstate_t cp0_getstatus(void) +{ + register irqstate_t status; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $12, 0\n" /* Get CP0 status register */ + "\t.set pop\n" + : "=r" (status) + : + : "memory" + ); + + return status; +} + +/**************************************************************************** + * Name: cp0_putstatus + * + * Description: + * Write the CP0 STATUS register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putstatus(irqstate_t status) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $12, 0\n" /* Set the status to the provided value */ + "\tnop\n" /* MTC0 status hazard: */ + "\tnop\n" /* Recommended spacing: 3 */ + "\tnop\n" + "\tnop\n" /* Plus one for good measure */ + "\t.set pop\n" + : + : "r" (status) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp0_getcause + * + * Description: + * Get the CP0 CAUSE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getcause(void) +{ + register uint32_t cause; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $13, 0\n" /* Get CP0 cause register */ + "\t.set pop\n" + : "=r" (cause) + : + : "memory" + ); + + return cause; +} + +/**************************************************************************** + * Name: cp0_putcause + * + * Description: + * Write the CP0 CAUSE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putcause(uint32_t cause) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $13, 0\n" /* Set the cause to the provided value */ + "\t.set pop\n" + : + : "r" (cause) + : "memory" + ); +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Save the current interrupt state and disable interrupts. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() is probably + * what you really want. + * + * Input Parameters: + * None + * + * Returned Value: + * Interrupt state prior to disabling interrupts. + * + ****************************************************************************/ + +irqstate_t up_irq_save(void); + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore the previous interrupt state (i.e., the one previously returned + * by up_irq_save()) + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, leave_critical_section() is probably + * what you really want. + * + * Input Parameters: + * state - The interrupt state to be restored. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t irqtate); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY */ +#endif /* __ARCH_MIPS_INCLUDE_MIPS32_IRQ_H */ + diff --git a/arch/mips/include/mips32/registers.h b/arch/mips/include/mips32/registers.h new file mode 100644 index 0000000000000000000000000000000000000000..016d1278ba0a278fb4e5e4cc6d3a083e7d80f9ac --- /dev/null +++ b/arch/mips/include/mips32/registers.h @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/mips/include/mips32/registers.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_MIPS32_REGISTERS_H +#define __ARCH_MIPS_INCLUDE_MIPS32_REGISTERS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Standard synonmyms for MIPS registers */ + +#ifdef __ASSEMBLY__ +/* Zero register: Always returns 0 */ + +#define zero $0 + +/* Assembler temporary register: Reserved for use by the assembler */ + +#define at_reg $1 + +/* Return value registers: Value returned by function */ + +#define v0 $2 +#define v1 $3 + +/* Argument registers: First four parameters to a function */ + +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 + +/* Volatile registers: Registers that can be used without saving */ + +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define t8 $24 +#define t9 $25 + +/* Static registers: Registers that must be saved and restored if used */ + +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 + +/* Reserved for use by interrupt/trap handling logic */ + +#define k0 $26 +#define k1 $27 + +/* Global pointer register */ + +#define gp $28 + +/* Stack pointer register: Stack pointer */ + +#define sp $29 + +/* Register 30 may be either an additional static register or a frame pointer */ + +#define s8 $30 +#define fp $30 + +/* Return address register: Contains the function return address */ + +#define ra $31 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_MIPS_INCLUDE_MIPS32_REGISTERS_H */ + diff --git a/arch/mips/include/mips32/syscall.h b/arch/mips/include/mips32/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..4661145d46eb07e1f21bbbb9a95130e8dd84e68b --- /dev/null +++ b/arch/mips/include/mips32/syscall.h @@ -0,0 +1,259 @@ +/**************************************************************************** + * arch/mips/include/mips32/syscall.h + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_MIPS32_SYSCALL_H +#define __ARCH_MIPS_INCLUDE_MIPS32_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x00 + +/* Configuration ********************************************************************/ +/* SYS call 1 and 2 are defined for internal use by the PIC32MX port (see + * arch/mips/include/mips32/syscall.h). In addition, SYS call 3 is the return from + * a SYS call in kernel mode. The first four syscall values must, therefore, be + * reserved (0 is not used). + */ + +#ifdef CONFIG_BUILD_KERNEL +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to the value 4" +# elif CONFIG_SYS_RESERVED != 4 +# error "CONFIG_SYS_RESERVED must have the value 4" +# endif +#endif + +/* sys_call macros ******************************************************************/ +/* System calls with 3 parameters and fewer are handled by sys_call0 (sys_call1, + * sys_call2, and sys_call3 are aliases for sys_call0). This is because the + * parmeters are passed in a0-a3. a0 is reserved for the syscall number leaving + * up to thre additional parameters that can be passed in registers. The remainder + * would have to be pushed onto the stack. + * + * Instead, these macros are provided which handle parameters four, five and six in + * a non-standard way: The use s0 ($7), s1 ($8), and s2 ($9) to pass the additional + * parameters. + */ + +#ifndef __ASSEMBLY__ + +/* System call SYS_ argument and four additional parameters. */ + +#define sys_call4(nbr,parm1,parm2,parm3,parm4) __extension__({ \ + uintptr_t __result; \ + __asm__ __volatile__ (\ + "\tmove $4, %0\n" \ + "\tmove $5, %1\n" \ + "\tmove $6, %2\n" \ + "\tmove $7, %3\n" \ + "\tmove $8, %4\n" \ + "\la $12, sys_call3\n" \ + "\jalr $12, $31\n" \ + "\tmove %5, $r2\n" \ + : "=r" (nbr) "=r" (parm1) "=r" (parm2) "=r" (parm3) "=r" (parm4) \ + : " "r"(__result)\ + : "memory"\ + ); \ + __result; \ +}) + +/* System call SYS_ argument and five additional parameters. */ + +#define sys_call5(nbr,parm1,parm2,parm3,parm4,parm5) __extension__({ \ + uintptr_t __result; \ + __asm__ __volatile__ (\ + "\tmove $4, %0\n" \ + "\tmove $5, %1\n" \ + "\tmove $6, %2\n" \ + "\tmove $7, %3\n" \ + "\tmove $8, %4\n" \ + "\tmove $9, %5\n" \ + "\la $12, sys_call3\n" \ + "\jalr $12, $31\n" \ + "\tmove %6, $r2\n" \ + : "=r" (nbr) "=r" (parm1) "=r" (parm2) "=r" (parm3) "=r" (parm4) "=r" (parm5) \ + : " "r"(__result)\ + : "memory"\ + ); \ + __result; \ +}) + +/* System call SYS_ argument and six additional parameters. */ + +#define sys_call5(nbr,parm1,parm2,parm3,parm4,parm5,parm6) __extension__({ \ + uintptr_t __result; \ + __asm__ __volatile__ (\ + "\tmove $4, %0\n" \ + "\tmove $5, %1\n" \ + "\tmove $6, %2\n" \ + "\tmove $7, %3\n" \ + "\tmove $8, %4\n" \ + "\tmove $9, %5\n" \ + "\tmove $10, %5\n" \ + "\la $12, sys_call3\n" \ + "\jalr $12, $31\n" \ + "\tmove %6, $r2\n" \ + : "=r" (nbr) "=r" (parm1) "=r" (parm2) "=r" (parm3) "=r" (parm4) "=r" (parm5) \ + : " "r"(__result)\ + : "memory"\ + ); \ + __result; \ +}) + +/* Context switching system calls ***************************************************/ + +/* SYS call 0: (not used) */ + +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) +#define up_fullcontextrestore(restoreregs) \ + (void)sys_call1(SYS_restore_context, (uintptr_t)restoreregs) + +/* SYS call 2: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) +#define up_switchcontext(saveregs, restoreregs) \ + (void)sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs) + +#ifdef CONFIG_BUILD_KERNEL +/* SYS call 3: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (3) +#define up_syscall_return() (void)sys_call0(SYS_syscall_return) + +#endif +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: up_syscall0 + * + * Description: + * System call SYS_ argument and no additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call0(unsigned int nbr); + +/**************************************************************************** + * Name: up_syscall1 + * + * Description: + * System call SYS_ argument and one additional parameter. + * + ****************************************************************************/ + +uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1); + +/**************************************************************************** + * Name: up_syscall2 + * + * Description: + * System call SYS_ argument and two additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2); + +/**************************************************************************** + * Name: up_syscall3 + * + * Description: + * System call SYS_ argument and three additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_MIPS32_SYSCALL_H */ + diff --git a/arch/mips/include/pic32mx/chip.h b/arch/mips/include/pic32mx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..1b3266d435d694427b8ea4fb0c479af8cf180210 --- /dev/null +++ b/arch/mips/include/pic32mx/chip.h @@ -0,0 +1,2431 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/chip.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_CHIP_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_PIC32MX110F016B) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 10 /* 10 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX110F016C) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX110F016D) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX120F032B) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 10 /* 10 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX120F032C) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX120F032D) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX130F064B) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 10 /* 10 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX130F064C) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX130F064D) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX150F128B) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 10 /* 10 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX150F128C) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX150F128D) +# define CHIP_PIC32MX1 1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 /* No dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 0 /* No USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX210F016B) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 9 /* 9 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX210F016C) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX210F016D) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 16 /* 16Kb program FLASH */ +# define CHIP_DATAMEM_KB 4 /* 4Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX220F032B) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 9 /* 9 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX220F032C) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX220F032D) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX230F064B) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 9 /* 9 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX230F064C) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX230F064D) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX250F128B) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 28 /* Package SOIC, SSOP, SPDIP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 9 /* 9 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX250F128C) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 36 /* Package VTLA */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 12 /* 12 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX250F128D) +# undef CHIP_PIC32MX1 +# define CHIP_PIC32MX2 1 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 44 /* Package VTLA, TQFP, QFN */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 3 /* 3Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# undef CHIP_CHE /* No pre-fetch cache controller */ +# define CHIP_NPORTS 3 /* 3 ports (A, B, C) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 /* 2 dedicated DMA channels */ +# define CHIP_CTMU 1 /* Has CTMU */ +# define CHIP_VRFSEL 1 /* Comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI/I2S interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 13 /* 13 10-bit ADC channels */ +# define CHIP_NCM 3 /* 3 Analog comparators */ +# define CHIP_USBOTG 1 /* Has USB OTG */ +# define CHIP_RTCC 1 /* Has RTCC */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 0 /* No parallel slave port (?) */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG 1 /* Has JTAG */ +#elif defined(CONFIG_ARCH_CHIP_PIC32MX320F032H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 0 /* No programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX320F064H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 0 /* No programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX320F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 0 /* No programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX340F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX340F256H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX340F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX320F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# define CHIP_PIC32MX3 1 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 0 /* No programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX340F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX360F256L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX360F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 0 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX420F032H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 32 /* 32Kb program FLASH */ +# define CHIP_DATAMEM_KB 8 /* 8Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 0 /* No programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 1 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX440F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 40 /* 40MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 1 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX440F256H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 1 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX440F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT, MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 1 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX440F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX460F256L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX460F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# define CHIP_PIC32MX4 1 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT=100 BG=121 */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 2 +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 2 /* 2 UARTS */ +# define CHIP_UARTFIFOD 8 /* 4 level deep UART FIFOs */ +# define CHIP_NSPI 2 /* 2 SPI interfaces */ +# define CHIP_NI2C 2 /* 2 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX534F064H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX564F064H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX564F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX575F256H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX575F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX534F064L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 16 /* 16Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX564F064L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX564F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX575F256L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX575F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# define CHIP_PIC32MX5 1 +# undef CHIP_PIC32MX6 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 0 /* No Ethernet */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX664F064H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX664F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX675F256H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX675F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX695F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 128 /* 128Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX664F064L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 64 /* 64Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX664F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX675F256L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX675F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX695F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# define CHIP_PIC32MX6 1 +# undef CHIP_PIC32MX7 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 128 /* 128Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* xx programmable DMA channels (4 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 0 /* No CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX764F128H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (6 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX775F256H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX775F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX795F512H) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 64 /* Package PT,MR */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 128 /* 128Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# undef CHIP_TRACE /* No trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 3 /* 3 SPI interfaces */ +# define CHIP_NI2C 4 /* 4 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX764F128L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 128 /* 128Kb program FLASH */ +# define CHIP_DATAMEM_KB 32 /* 32Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 4 /* 4 programmable DMA channels (6 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 1 /* 1 CAN interface */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX775F256L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 256 /* 256Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX775F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 64 /* 64Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# undef CHIP_VRFSEL /* No comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#elif defined(CONFIG_ARCH_CHIP_PIC32MX795F512L) +# undef CHIP_PIC32MX1 +# undef CHIP_PIC32MX2 +# undef CHIP_PIC32MX3 +# undef CHIP_PIC32MX4 +# undef CHIP_PIC32MX5 +# undef CHIP_PIC32MX6 +# define CHIP_PIC32MX7 1 +# define CHIP_NPINS 100 /* Package PT,PF,BG */ +# define CHIP_MHZ 80 /* 80MHz maximum frequency */ +# define CHIP_BOOTFLASH_KB 12 /* 12Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 512 /* 512Kb program FLASH */ +# define CHIP_DATAMEM_KB 128 /* 128Kb data memory */ +# define CHIP_CHE 1 /* Has pre-fetch cache controller */ +# define CHIP_NPORTS 7 /* 7 ports (A, B, C, D, E, F, G) */ +# define CHIP_NTIMERS 5 /* 5 timers */ +# define CHIP_NIC 5 /* 5 input capture */ +# define CHIP_NOC 5 /* 5 output compare */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels (8 dedicated) */ +# define CHIP_NUSBDMACHAN tbd +# define CHIP_VRFSEL 1 /* Have comparator voltage reference selection */ +# define CHIP_TRACE 1 /* Have trace capability */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 4 /* 4 SPI interfaces */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NADC10 16 /* 16 10-bit ADC channels */ +# define CHIP_NCM 2 /* 2 Comparators */ +# define CHIP_PMP 1 /* Have parallel master port */ +# define CHIP_PSP 1 /* Have parallel slave port */ +# define CHIP_NETHERNET 1 /* 1 Ethernet interface */ +# define CHIP_JTAG +#else +# error "Unrecognized PIC32 device +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_CHIP_H */ diff --git a/arch/mips/include/pic32mx/cp0.h b/arch/mips/include/pic32mx/cp0.h new file mode 100644 index 0000000000000000000000000000000000000000..81e542cd07a49fca110845d8708bca06a8d40fef --- /dev/null +++ b/arch/mips/include/pic32mx/cp0.h @@ -0,0 +1,396 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/cp0.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_CP0_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_CP0_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* CP0 Register Addresses ***************************************************/ + +#ifdef __ASSEMBLY__ +# define PIC32MX_CP0_HWRENA $7,0 /* Enables access via RDHWR hardware registers */ +# define PIC32MX_CP0_BADVADDR $8,0 /* Address of most recent exception */ +# define PIC32MX_CP0_COUNT $9,0 /* Processor cycle count */ +# define PIC32MX_CP0_COMPARE $11,0 /* Timer interrupt control */ +# define PIC32MX_CP0_STATUS $12,0 /* Processor status and control */ +# define PIC32MX_CP0_INTCTL $12,1 /* Interrupt system status and control */ +# define PIC32MX_CP0_SRSCTL $12,2 /* Shadow register set status and control */ +# define PIC32MX_CP0_SRSMAP $12,3 /* Maps from vectored interrupt to a shadow set */ +# define PIC32MX_CP0_CAUSE $13,0 /* Cause of last general exception */ +# define PIC32MX_CP0_EPC $14,0 /* Program counter at last exception */ +# define PIC32MX_CP0_PRID $15,0 /* Processor identification and revision */ +# define PIC32MX_CP0_EBASE $15,1 /* Exception vector base register */ +# define PIC32MX_CP0_CONFIG $16,0 /* Configuration register */ +# define PIC32MX_CP0_CONFIG1 $16,1 /* Configuration register 1 */ +# define PIC32MX_CP0_CONFIG2 $16,2 /* Configuration register 3 */ +# define PIC32MX_CP0_CONFIG3 $16,3 /* Configuration register 3 */ +# define PIC32MX_CP0_DEBUG $23,0 /* Debug control and exception status */ +# define PIC32MX_CP0_DEPC $24,0 /* Program counter at last debug exception */ +# define PIC32MX_CP0_ERREPC $30,0 /* Program counter at last error */ +# define PIC32MX_CP0_DESAVE $31,0 /* Debug handler scratchpad register */ +#endif + +/* CP0 Registers ************************************************************/ + +/* Register Number: 0-6: Reserved + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + */ + +/* Register Number: 7 Sel: 0 Name: HWREna + * Function: Enables access via the RDHWR instruction to selected hardware + * registers in non-privileged mode. + * Compliance Level: (Reserved for future extensions) + */ + +#define CP0_HWRENA_SHIFT (0) /* Bits 0-3: Enable access to a hardware resource */ +#define CP0_HWRENA_MASK (15 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT0 (1 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT1 (2 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT2 (4 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT3 (8 << CP0_HWRENA_SHIFT) + +/* Register Number: 8 Sel: 0 Name: BadVAddr + * Function: Reports the address for the most recent address-related + * exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 9 Sel: 0 Name: Count + * Function: Processor cycle count + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 10 Reserved. + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * + * Register Number: 11 Sel: 0 Name: Compare + * Function: Timer interrupt control + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 12 Sel: 0 Name: Status + * Function: Processor status and control + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTES: + * 1. The following are reserved bits in the PIC32: + * CP0_STATUS_UX Bit 5: Enables 64-bit user address space (Not MIPS32) + * CP0_STATUS_SX Bit 6: Enables 64-bit supervisor address space (Not MIPS32) + * CP0_STATUS_KX Bit 7: Enables 64-bit kernel address space (Not MIPS32) + * CP0_STATUS_IMPL Bits 16-17: Implementation dependent + * CP0_STATUS_TS Bit 21: TLB detected match on multiple entries + * CP0_STATUS_PX Bit 23: Enables 64-bit operations (Not MIPS32) + * CP0_STATUS_MX Bit 24: Enables MDMX™ (Not MIPS32) + */ + +#undef CP0_STATUS_UX +#undef CP0_STATUS_SX +#undef CP0_STATUS_KX +#undef CP0_STATUS_IMPL +#undef CP0_STATUS_IMPL_SHIFT +#undef CP0_STATUS_IMPL_MASK +#undef CP0_STATUS_TS +#undef CP0_STATUS_PX +#undef CP0_STATUS_MX + +/* 2. The following field is of a different width. Apparently, it + * excludes the software interrupt bits. + * + * CP0_STATUS_IM Bits 8-15: Interrupt Mask + * Vs. + * CP0_STATUS_IPL Bits 10-15: Interrupt priority level + * Bitss 8-9 reserved + */ + +#define CP0_STATUS_IPL_SHIFT (10) /* Bits 10-15: Interrupt priority level */ +#define CP0_STATUS_IPL_MASK (0x3f << CP0_STATUS_IPL_SHIFT) + +/* 3. Supervisor mode not supported + * CP0_STATUS_KSU Bits 3-4: Operating mode (with supervisor mode) + */ + +#undef CP0_STATUS_KSU_SHIFT +#undef CP0_STATUS_KSU_MASK +#undef CP0_STATUS_KSU_KERNEL +#undef CP0_STATUS_KSU_SUPER +#undef CP0_STATUS_KSU_USER + +/* Register Number: 12 Sel: 1 Name: IntCtl */ + +#define CP0_INTCTL_VS_SHIFT (5) /* Bits 5-9: Vector spacing bits */ +#define CP0_INTCTL_VS_MASK (0x1f << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_0BYTES (0x00 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_32BYTES (0x01 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_64BYTES (0x02 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_128BYTES (0x04 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_256BYTES (0x08 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_512BYTES (0x10 << CP0_INTCTL_VS_SHIFT) + +/* Register Number: 12 Sel: 2 Name: SRSCtl */ + +#define CP0_SRSCTL_CSS_SHIFT (0) /* Bits 0-3: Current shadow bit set */ +#define CP0_SRSCTL_CSS_MASK (15 << CP0_SRSCTL_CSS_SHIFT) +#define CP0_SRSCTL_PSS_SHIFT (6) /* Bits 6-9: Previous shadow set */ +#define CP0_SRSCTL_PSS_MASK (15 << CP0_SRSCTL_PSS_SHIFT) +#define CP0_SRSCTL_ESS_SHIFT (12) /* Bits 12-15: Exception shadow sets */ +#define CP0_SRSCTL_ESS_MASK (15 << CP0_SRSCTL_ESS_SHIFT) +#define CP0_SRSCTL_EICSS_SHIFT (18) /* Bits 18-21: External interrupt controller shadow sets */ +#define CP0_SRSCTL_EICSS_MASK (15 << CP0_SRSCTL_EICSS_SHIFT) +#define CP0_SRSCTL_HSS_SHIFT (26) /* Bits 26-29: High shadow sets */ +#define CP0_SRSCTL_HSS_MASK (15 << CP0_SRSCTL_HSS_SHIFT) +# define CP0_SRSCTL_HSS_1SET (0 << CP0_SRSCTL_HSS_SHIFT) /* One shadow set (normal GPR set) */ +# define CP0_SRSCTL_HSS_2SETS (1 << CP0_SRSCTL_HSS_SHIFT) /* Two shadow sets */ +# define CP0_SRSCTL_HSS_4SETS (3 << CP0_SRSCTL_HSS_SHIFT) /* Four shadow sets */ + +/* Register Number: 12 Sel: 3 Name: SRSMap */ + +#define CP0_SRSMAP_SSV0_SHIFT (0) /* Bits 0-3: Shadow set vector 0 */ +#define CP0_SRSMAP_SSV0_MASK (15 << CP0_SRSMAP_SSV0_SHIFT) +#define CP0_SRSMAP_SSV1_SHIFT (4) /* Bits 4-7: Shadow set vector 1 */ +#define CP0_SRSMAP_SSV1_MASK (15 << CP0_SRSMAP_SSV1_SHIFT) +#define CP0_SRSMAP_SSV2_SHIFT (8) /* Bits 8-11: Shadow set vector 2 */ +#define CP0_SRSMAP_SSV2_MASK (15 << CP0_SRSMAP_SSV2_SHIFT) +#define CP0_SRSMAP_SSV3_SHIFT (12) /* Bits 12-15: Shadow set vector 3 */ +#define CP0_SRSMAP_SSV3_MASK (15 << CP0_SRSMAP_SSV3_SHIFT) +#define CP0_SRSMAP_SSV4_SHIFT (16) /* Bits 16-19: Shadow set vector 4 */ +#define CP0_SRSMAP_SSV4_MASK (15 << CP0_SRSMAP_SSV4_SHIFT) +#define CP0_SRSMAP_SSV5_SHIFT (20) /* Bits 20-23: Shadow set vector 5 */ +#define CP0_SRSMAP_SSV5_MASK (15 << CP0_SRSMAP_SSV5_SHIFT) +#define CP0_SRSMAP_SSV6_SHIFT (24) /* Bits 24-27: Shadow set vector 6 */ +#define CP0_SRSMAP_SSV6_MASK (15 << CP0_SRSMAP_SSV6_SHIFT) +#define CP0_SRSMAP_SSV7_SHIFT (28) /* Bits 28-31: Shadow set vector 7 */ +#define CP0_SRSMAP_SSV7_MASK (15 << CP0_SRSMAP_SSV7_SHIFT) + +/* Register Number: 13 Sel: 0 Name: Cause + * Function: Cause of last general exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTES: The following bits are added in the PIC32: + */ + +#define CP0_CAUSE_R (1 << 26) /* Bit 26: R bit */ +#define CP0_CAUSE_DC (1 << 27) /* Bit 27: Disable count */ +#define CP0_CAUSE_TI (1 << 30) /* Bit 30: Timer interrupt bit *. + +/* Register Number: 14 Sel: 0 Name: EPC + * Function: Program counter at last exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 15 Sel: 0 Name: PRId + * Function: Processor identification and revision + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTE: Slightly different bit interpretations of some fields: + */ + +#define CP0_PRID_PATCH_SHIFT (5) /* Bits 0-1: Patch level */ +#define CP0_PRID_PATCH_MASK (3 << CP0_PRID_PATCH_SHIFT) +#define CP0_PRID_MINOR_SHIFT (2) /* Bits 2-4: Minor revision number */ +#define CP0_PRID_MINOR_MASK (7 << CP0_PRID_MINOR_SHIFT) +#define CP0_PRID_MAJOR_SHIFT (5) /* Bits 5-7: Major revision number */ +#define CP0_PRID_MAJOR_MASK (7 << CP0_PRID_MAJOR_SHIFT) + +#undef CP0_PRID_OPTIONS_SHIFT +#undef CP0_PRID_OPTIONS_MASK + +/* Register Number: 15 Sel: 1 Name: EBASE */ + +#define CP_EBASE_CPUNUM_SHIFT (0) /* Bits 0-9: CPU number */ +#define CP_EBASE_CPUNUM_MASK (0x3ff << CP_EBASE_CPUNUM_SHIFT) +#define CP_EBASE_SHIFT (12) /* Bits 30-31=10, Bits 12-29: Exception base */ +#define CP_EBASE_MASK (0x3ffff << CP_EBASE_SHIFT) + +/* Register Number: 16 Sel: 0 Name: Config + * Function: Configuration register + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * 1. PIC32MX is always little-endian. + * 2. Implementation specific bits defined. + */ + +#undef CP0_CONFIG_IMPL_SHIFT +#undef CP0_CONFIG_IMPL_MASK + +#define CP0_CONFIG_DS (1 << 16) /* Dual SRAM bit */ +#define CP0_CONFIG_SB (1 << 21) /* Bit 32: Simple BE bus mode bit */ +#define CP0_CONFIG_UDI (1 << 22) /* Bit 22: User defined bit */ +#define CP0_CONFIG_KU_SHIFT (25) /* Bits 25-27: KUSEG and USEG cacheability */ +#define CP0_CONFIG_KU_MASK (7 << CP0_CONFIG_KU_SHIFT) +# define CP0_CONFIG_KU_UNCACHED (2 << CP0_CONFIG_KU_SHIFT) +# define CP0_CONFIG_KU_CACHEABLE (3 << CP0_CONFIG_KU_SHIFT) +#define CP0_CONFIG_K23_SHIFT (28) /* Bits 28-30: KSEG2 and KSEG3 cacheability */ +#define CP0_CONFIG_K23_MASK (7 << CP0_CONFIG_K23_SHIFT) +# define CP0_CONFIG_K23_UNCACHED (2 << CP0_CONFIG_K23_SHIFT) +# define CP0_CONFIG_K23_CACHEABLE (3 << CP0_CONFIG_K23_SHIFT) + +/* Register Number: 16 Sel: 1 Name: Config1 + * Function: Configuration register 1 + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 16 Sel: 2 Name: Config2 + * Function: Configuration register 2 + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +#undef CP0_CONFIG2_TBS_SHIFT +#undef CP0_CONFIG2_TBS_MASK + +/* Register Number: 16 Sel: 3 Name: Config3 + * Function: Configuration register 3 + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +#define CP0_CONFIG3_SP (1 << 4) /* Bit 4: Support page bit */ +#define CP0_CONFIG3_VINT (1 << 5) /* Bit 5: Vector interrupt bit */ +#define CP0_CONFIG3_VEIC (1 << 6) /* Bit 6: External interrupt controller supported */ + +/* Register Number: 17-22 Reserved + * Compliance Level: Optional. + */ + +/* Register Number: 23 Sel: 0 Name: Debug + * Function: EJTAG Debug register + * Compliance Level: Optional. + */ + +#define CP0_DEBUG_DSS (1 << 0) /* Bit 0: Debug single-step exception */ +#define CP0_DEBUG_DBP (1 << 1) /* Bit 1: Debug software breakpoint exception */ +#define CP0_DEBUG_DDBL (1 << 2) /* Bit 2: Debug data break exception on load */ +#define CP0_DEBUG_DDBS (1 << 3) /* Bit 3: Debug data break exception on store */ +#define CP0_DEBUG_DIB (1 << 4) /* Bit 4: Debug instruction break exception */ +#define CP0_DEBUG_DINT (1 << 5) /* Bit 5: Debug interrupt exception */ +#define CP0_DEBUG_SST (1 << 8) /* Bit 6: Enable debug single step exception */ +#define CP0_DEBUG_NOSST (1 << 9) /* Bit 7: No single step feature available */ +#define CP0_DEBUG_DEXCCODE_SHIFT (10) /* Bits 10-14: Cause of latest exception in DEBUG mode */ +#define CP0_DEBUG_DEXCCODE_MASK (31 << CP0_DEBUG_DEXCCODE_SHIFT) +#define CP0_DEBUG_VER_SHIFT (15) /* Bits 15-17: EJTAG version */ +#define CP0_DEBUG_VER_MASK (7 << CP0_DEBUG_VER_SHIFT) +#define CP0_DEBUG_DDBLIMPR (1 << 18) /* Bit 18: Imprecise debug data break load instruction */ +#define CP0_DEBUG_DDBSIMPR (1 << 19) /* Bit 19: Imprecise debug data break store instruction */ +#define CP0_DEBUG_IEXI (1 << 20) /* Bit 20: Imprecise error exception inhibit */ +#define CP0_DEBUG_DBUSEP (1 << 21) /* Bit 21: Data access bus error exception pending */ +#define CP0_DEBUG_CACHEEP (1 << 22) /* Bit 22: Imprecise cache error exception is pending */ +#define CP0_DEBUG_MCHECKP (1 << 23) /* Bit 23: Imprecise machine check exception is pending */ +#define CP0_DEBUG_IBUSEP (1 << 24) /* Bit 24: Bus error exception pending */ +#define CP0_DEBUG_COUNTDM (1 << 25) /* Bit 25: Count register behavior (1=running) */ +#define CP0_DEBUG_HALT (1 << 26) /* Bit 26: Internal system bus clock stopped */ +#define CP0_DEBUG_DOZE (1 << 27) /* Bit 27: Processor in low power mode */ +#define CP0_DEBUG_LSNM (1 << 28) /* Bit 28: Load/store in DSEG goes to main memory */ +#define CP0_DEBUG_NODCR (1 << 29) /* Bit 29: No DSEG preset */ +#define CP0_DEBUG_DM (1 << 30) /* Bit 30: Processor is operating in DEBUG mode */ +#define CP0_DEBUG_DBD (1 << 31) /* Bit 31: Last debug exception occurred in a dely slot */ + +/* Register Number: 23 Sel: ? Name: Debug2 + * Is this documented anywhere? + */ + +/* Register Number: 24 Sel: 0 Name: DEPC + * Function: Program counter at last EJTAG debug exception + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 25-29 Reserved + * Compliance Level: Recommended/Optional. + * + * Register Number: 30 Sel: 0 Name: ErrorEPC + * Function: Program counter at last error + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 31 Sel: 0 Name: DeSAVE + * Function: EJTAG debug exception save register + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_CP0_H */ diff --git a/arch/mips/include/pic32mx/irq.h b/arch/mips/include/pic32mx/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..25d4c6f5cd0e200fae5611bbb1253d9894670136 --- /dev/null +++ b/arch/mips/include/pic32mx/irq.h @@ -0,0 +1,215 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/irq.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# include +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) +# include +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# include +#else +# error "Unknown PIC32MX family +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cp0_getintctl + * + * Description: + * Get the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getintctl(void) +{ + register uint32_t intctl; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $12, 1\n" /* Get CP0 IntCtl register */ + "\t.set pop\n" + : "=r" (intctl) + : + : "memory" + ); + + return intctl; +} + +/**************************************************************************** + * Name: cp0_putintctl + * + * Description: + * Write the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putintctl(uint32_t intctl) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $12, 1\n" /* Set the IntCtl to the provided value */ + "\t.set pop\n" + : + : "r" (intctl) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp0_getebase + * + * Description: + * Get the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getebase(void) +{ + register uint32_t ebase; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $15, 1\n" /* Get CP0 EBASE register */ + "\t.set pop\n" + : "=r" (ebase) + : + : "memory" + ); + + return ebase; +} + +/**************************************************************************** + * Name: cp0_putebase + * + * Description: + * Write the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putebase(uint32_t ebase) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $15, 1\n" /* Set the EBASE to the provided value */ + "\t.set pop\n" + : + : "r" (ebase) + : "memory" + ); +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_H */ + diff --git a/arch/mips/include/pic32mx/irq_1xx2xx.h b/arch/mips/include/pic32mx/irq_1xx2xx.h new file mode 100644 index 0000000000000000000000000000000000000000..0bd739c44a3c7084adb47d0776a44d3e6b005cff --- /dev/null +++ b/arch/mips/include/pic32mx/irq_1xx2xx.h @@ -0,0 +1,216 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/irq_1xx2xx.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_1XX2XX_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_1XX2XX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt vector numbers. These should be used to attach to interrupts + * and to change interrupt priorities. + */ + +#define PIC32MX_IRQ_CT 0 /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQ_CS0 1 /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQ_CS1 2 /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQ_INT0 3 /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQ_T1 4 /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQ_IC1 5 /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQ_OC1 6 /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQ_INT1 7 /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQ_T2 8 /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQ_IC2 9 /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQ_OC2 10 /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQ_INT2 11 /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQ_T3 12 /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQ_IC3 13 /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQ_OC3 14 /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQ_INT3 15 /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQ_T4 16 /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQ_IC4 17 /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQ_OC4 18 /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQ_INT4 19 /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQ_T5 20 /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQ_IC5 21 /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQ_OC5 22 /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQ_AD1 23 /* Vector: 23, ADC1 Convert Done */ +#define PIC32MX_IRQ_FSCM 24 /* Vector: 24, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQ_RTCC 25 /* Vector: 25, Real-Time Clock and Calendar */ +#define PIC32MX_IRQ_FCE 26 /* Vector: 26, Flash Control Event */ +#define PIC32MX_IRQ_CMP1 27 /* Vector: 27, Comparator 1 */ +#define PIC32MX_IRQ_CMP2 28 /* Vector: 28, Comparator 2 */ +#define PIC32MX_IRQ_CMP3 29 /* Vector: 29, Comparator 3 */ +#define PIC32MX_IRQ_USB 30 /* Vector: 30, USB */ +#define PIC32MX_IRQ_SPI1 31 /* Vector: 31, SPI1 */ +#define PIC32MX_IRQ_U1 32 /* Vector: 32, UART1 */ +#define PIC32MX_IRQ_I2C1 33 /* Vector: 33, I2C1 */ +#define PIC32MX_IRQ_CN 34 /* Vector: 34, Input Change */ +#define PIC32MX_IRQ_PMP 35 /* Vector: 35, Parallel Master Port */ +#define PIC32MX_IRQ_SPI2 36 /* Vector: 36, SPI2 */ +#define PIC32MX_IRQ_U2 37 /* Vector: 37, UART2 */ +#define PIC32MX_IRQ_I2C2 38 /* Vector: 38, I2C2 */ +#define PIC32MX_IRQ_CTMU 39 /* Vector: 39, CTMU */ +#define PIC32MX_IRQ_DMA0 40 /* Vector: 40, DMA Channel 0 */ +#define PIC32MX_IRQ_DMA1 41 /* Vector: 41, DMA Channel 1 */ +#define PIC32MX_IRQ_DMA2 42 /* Vector: 42, DMA Channel 2 */ +#define PIC32MX_IRQ_DMA3 43 /* Vector: 43, DMA Channel 3 */ + +#define PIC32MX_IRQ_BAD 44 /* Not a real IRQ number */ +#define NR_IRQS 44 + +/* Interrupt numbers. These should be used for enabling and disabling + * interrupt sources. Note that there are more interrupt sources than + * interrupt vectors and interrupt priorities. An offset of 128 is + * used so that there is no overlap with the IRQ numbers and to avoid + * errors due to misuse. + */ + +#define PIC32MX_IRQSRC0_FIRST (128+0) +#define PIC32MX_IRQSRC_CT (128+0) /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQSRC_CS0 (128+1) /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQSRC_CS1 (128+2) /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQSRC_INT0 (128+3) /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQSRC_T1 (128+4) /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQSRC_IC1E (128+5) /* Vector: 5, Input Capture 1 Error */ +#define PIC32MX_IRQSRC_IC1 (128+6) /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQSRC_OC1 (128+7) /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQSRC_INT1 (128+8) /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQSRC_T2 (128+9) /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQSRC_IC2E (128+10) /* Vector: 9, Input Capture 2 Error */ +#define PIC32MX_IRQSRC_IC2 (128+11) /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQSRC_OC2 (128+12) /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQSRC_INT2 (128+13) /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQSRC_T3 (128+14) /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQSRC_IC3E (128+15) /* Vector: 13, Input Capture 3 Error */ +#define PIC32MX_IRQSRC_IC3 (128+16) /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQSRC_OC3 (128+17) /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQSRC_INT3 (128+18) /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQSRC_T4 (128+19) /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQSRC_IC4E (128+20) /* Vector: 17, Input Capture 4 Error */ +#define PIC32MX_IRQSRC_IC4 (128+21) /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQSRC_OC4 (128+22) /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQSRC_INT4 (128+23) /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQSRC_T5 (128+24) /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQSRC_IC5E (128+25) /* Vector: 21, Input Capture 5 Error */ +#define PIC32MX_IRQSRC_IC5 (128+26) /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQSRC_OC5 (128+27) /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQSRC_AD1 (128+28) /* Vector: 23, ADC1 Convert Done */ +#define PIC32MX_IRQSRC_FSCM (128+29) /* Vector: 24, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQSRC_RTCC (128+30) /* Vector: 25, Real-Time Clock and Calendar */ +#define PIC32MX_IRQSRC_FCE (128+31) /* Vector: 26, Flash Control Event */ +#define PIC32MX_IRQSRC0_LAST (128+31) + +#define PIC32MX_IRQSRC1_FIRST (128+32) +#define PIC32MX_IRQSRC_CMP1 (128+32) /* Vector: 27, Comparator 1 Interrupt */ +#define PIC32MX_IRQSRC_CMP2 (128+33) /* Vector: 28, Comparator 2 Interrupt */ +#define PIC32MX_IRQSRC_CMP2 (128+34) /* Vector: 29, Comparator 3 Interrupt */ +#define PIC32MX_IRQSRC_USB (128+35) /* Vector: 30, USB */ +#define PIC32MX_IRQSRC_SPI1E (128+36) /* Vector: 31, SPI1 */ +#define PIC32MX_IRQSRC_SPI1TX (128+37) /* Vector: 31, " " */ +#define PIC32MX_IRQSRC_SPI1RX (128+38) /* Vector: 31, " " */ +#define PIC32MX_IRQSRC_U1E (128+39) /* Vector: 32, UART1 */ +#define PIC32MX_IRQSRC_U1RX (128+40) /* Vector: 32, " " */ +#define PIC32MX_IRQSRC_U1TX (128+41) /* Vector: 32, " " */ +#define PIC32MX_IRQSRC_I2C1B (128+42) /* Vector: 33, I2C1 */ +#define PIC32MX_IRQSRC_I2C1S (128+43) /* Vector: 33, " " */ +#define PIC32MX_IRQSRC_I2C1M (128+44) /* Vector: 33, " " */ +#define PIC32MX_IRQSRC_CNA (128+45) /* Vector: 34, Input Change Interrupt */ +#define PIC32MX_IRQSRC_CNB (128+46) /* Vector: 34, Input Change Interrupt */ +#define PIC32MX_IRQSRC_CNC (128+47) /* Vector: 34, Input Change Interrupt */ +#define PIC32MX_IRQSRC_PMP (128+48) /* Vector: 35, Parallel Master Port */ +#define PIC32MX_IRQSRC_PMPE (128+49) /* Vector: 35, Parallel Master Port */ +#define PIC32MX_IRQSRC_SPI2E (128+50) /* Vector: 36, SPI2 */ +#define PIC32MX_IRQSRC_SPI2TX (128+51) /* Vector: 36, " " */ +#define PIC32MX_IRQSRC_SPI2RX (128+52) /* Vector: 36, " " */ +#define PIC32MX_IRQSRC_U2E (128+53) /* Vector: 37, UART2 */ +#define PIC32MX_IRQSRC_U2RX (128+54) /* Vector: 37, " " */ +#define PIC32MX_IRQSRC_U2TX (128+55) /* Vector: 37, " " */ +#define PIC32MX_IRQSRC_I2C2B (128+56) /* Vector: 38, I2C2 */ +#define PIC32MX_IRQSRC_I2C2S (128+57) /* Vector: 38, " " */ +#define PIC32MX_IRQSRC_I2C2M (128+58) /* Vector: 38, " " */ +#define PIC32MX_IRQSRC_CTMU (128+59) /* Vector: 39, CTMU */ +#define PIC32MX_IRQSRC_DMA0 (128+60) /* Vector: 40, DMA Channel 0 */ +#define PIC32MX_IRQSRC_DMA1 (128+61) /* Vector: 41, DMA Channel 1 */ +#define PIC32MX_IRQSRC_DMA2 (128+62) /* Vector: 42, DMA Channel 2 */ +#define PIC32MX_IRQSRC_DMA3 (128+63) /* Vector: 43, DMA Channel 3 */ +#define PIC32MX_IRQSRC1_LAST (128+63) + +#define PIC32MX_IRQSRC_FIRST PIC32MX_IRQSRC0_FIRST +#define PIC32MX_IRQSRC_LAST PIC32MX_IRQSRC1_LAST + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_1XX2XX_H */ + diff --git a/arch/mips/include/pic32mx/irq_3xx4xx.h b/arch/mips/include/pic32mx/irq_3xx4xx.h new file mode 100644 index 0000000000000000000000000000000000000000..3b404db33fd8fea54d30b752d52b835b8089fb68 --- /dev/null +++ b/arch/mips/include/pic32mx/irq_3xx4xx.h @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/irq_3xx4xx.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_3XX4XX_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_3XX4XX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt vector numbers. These should be used to attach to interrupts + * and to change interrupt priorities. + */ + +#define PIC32MX_IRQ_CT 0 /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQ_CS0 1 /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQ_CS1 2 /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQ_INT0 3 /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQ_T1 4 /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQ_IC1 5 /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQ_OC1 6 /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQ_INT1 7 /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQ_T2 8 /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQ_IC2 9 /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQ_OC2 10 /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQ_INT2 11 /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQ_T3 12 /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQ_IC3 13 /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQ_OC3 14 /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQ_INT3 15 /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQ_T4 16 /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQ_IC4 17 /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQ_OC4 18 /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQ_INT4 19 /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQ_T5 20 /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQ_IC5 21 /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQ_OC5 22 /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQ_SPI1 23 /* Vector: 23, SPI1 */ +#define PIC32MX_IRQ_U1 24 /* Vector: 24, UART1 */ +#define PIC32MX_IRQ_I2C1 25 /* Vector: 25, I2C1 */ +#define PIC32MX_IRQ_CN 26 /* Vector: 26, Input Change Interrupt */ +#define PIC32MX_IRQ_AD1 27 /* Vector: 27, ADC1 Convert Done */ +#define PIC32MX_IRQ_PMP 28 /* Vector: 28, Parallel Master Port */ +#define PIC32MX_IRQ_CMP1 29 /* Vector: 29, Comparator Interrupt */ +#define PIC32MX_IRQ_CMP2 30 /* Vector: 30, Comparator Interrupt */ +#define PIC32MX_IRQ_SPI2 31 /* Vector: 31, SPI2 */ +#define PIC32MX_IRQ_U2 32 /* Vector: 32, UART2 */ +#define PIC32MX_IRQ_I2C2 33 /* Vector: 33, I2C2 */ +#define PIC32MX_IRQ_FSCM 34 /* Vector: 34, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQ_RTCC 35 /* Vector: 35, Real-Time Clock and Calendar */ +#define PIC32MX_IRQ_DMA0 36 /* Vector: 36, DMA Channel 0 */ +#define PIC32MX_IRQ_DMA1 37 /* Vector: 37, DMA Channel 1 */ +#define PIC32MX_IRQ_DMA2 38 /* Vector: 38, DMA Channel 2 */ +#define PIC32MX_IRQ_DMA3 39 /* Vector: 39, DMA Channel 3 */ + /* Vectors 40-43: Not used */ +#define PIC32MX_IRQ_FCE 44 /* Vector: 44, Flash Control Event */ +#define PIC32MX_IRQ_USB 45 /* Vector: 45, USB */ + +#define PIC32MX_IRQ_BAD 46 /* Not a real IRQ number */ +#define NR_IRQS 46 + +/* Interrupt numbers. These should be used for enabling and disabling + * interrupt sources. Note that there are more interrupt sources than + * interrupt vectors and interrupt priorities. An offset of 128 is + * used so that there is no overlap with the IRQ numbers and to avoid + * errors due to misuse. + */ + +#define PIC32MX_IRQSRC0_FIRST (128+0) +#define PIC32MX_IRQSRC_CT (128+0) /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQSRC_CS0 (128+1) /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQSRC_CS1 (128+2) /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQSRC_INT0 (128+3) /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQSRC_T1 (128+4) /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQSRC_IC1 (128+5) /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQSRC_OC1 (128+6) /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQSRC_INT1 (128+7) /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQSRC_T2 (128+8) /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQSRC_IC2 (128+9) /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQSRC_OC2 (128+10) /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQSRC_INT2 (128+11) /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQSRC_T3 (128+12) /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQSRC_IC3 (128+13) /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQSRC_OC3 (128+14) /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQSRC_INT3 (128+15) /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQSRC_T4 (128+16) /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQSRC_IC4 (128+17) /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQSRC_OC4 (128+18) /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQSRC_INT4 (128+19) /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQSRC_T5 (128+20) /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQSRC_IC5 (128+21) /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQSRC_OC5 (128+22) /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQSRC_SPI1E (128+23) /* Vector: 23, SPI1 */ +#define PIC32MX_IRQSRC_SPI1TX (128+24) /* Vector: 23, " " */ +#define PIC32MX_IRQSRC_SPI1RX (128+25) /* Vector: 23, " " */ +#define PIC32MX_IRQSRC_U1E (128+26) /* Vector: 24, UART1 */ +#define PIC32MX_IRQSRC_U1RX (128+27) /* Vector: 24, " " */ +#define PIC32MX_IRQSRC_U1TX (128+28) /* Vector: 24, " " */ +#define PIC32MX_IRQSRC_I2C1B (128+29) /* Vector: 25, I2C1 */ +#define PIC32MX_IRQSRC_I2C1S (128+30) /* Vector: 25, " " */ +#define PIC32MX_IRQSRC_I2C1M (128+31) /* Vector: 25, " " */ +#define PIC32MX_IRQSRC0_LAST (128+31) + +#define PIC32MX_IRQSRC1_FIRST (128+32) +#define PIC32MX_IRQSRC_CN (128+32) /* Vector: 26, Input Change Interrupt */ +#define PIC32MX_IRQSRC_AD1 (128+33) /* Vector: 27, ADC1 Convert Done */ +#define PIC32MX_IRQSRC_PMP (128+34) /* Vector: 28, Parallel Master Port */ +#define PIC32MX_IRQSRC_CMP1 (128+35) /* Vector: 29, Comparator Interrupt */ +#define PIC32MX_IRQSRC_CMP2 (128+36) /* Vector: 30, Comparator Interrupt */ +#define PIC32MX_IRQSRC_SPI2E (128+37) /* Vector: 31, SPI2 */ +#define PIC32MX_IRQSRC_SPI2TX (128+38) /* Vector: 31, " " */ +#define PIC32MX_IRQSRC_SPI2RX (128+39) /* Vector: 31, " " */ +#define PIC32MX_IRQSRC_U2E (128+40) /* Vector: 32, UART2 */ +#define PIC32MX_IRQSRC_U2RX (128+41) /* Vector: 32, " " */ +#define PIC32MX_IRQSRC_U2TX (128+42) /* Vector: 32, " " */ +#define PIC32MX_IRQSRC_I2C2B (128+43) /* Vector: 33, I2C2 */ +#define PIC32MX_IRQSRC_I2C2S (128+44) /* Vector: 33, " " */ +#define PIC32MX_IRQSRC_I2C2M (128+45) /* Vector: 33, " " */ +#define PIC32MX_IRQSRC_FSCM (128+46) /* Vector: 34, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQSRC_RTCC (128+47) /* Vector: 35, Real-Time Clock and Calendar */ +#define PIC32MX_IRQSRC_DMA0 (128+48) /* Vector: 36, DMA Channel 0 */ +#define PIC32MX_IRQSRC_DMA1 (128+49) /* Vector: 37, DMA Channel 1 */ +#define PIC32MX_IRQSRC_DMA2 (128+50) /* Vector: 38, DMA Channel 2 */ +#define PIC32MX_IRQSRC_DMA3 (128+51) /* Vector: 39, DMA Channel 3 */ +#define PIC32MX_IRQSRC_FCE (128+56) /* Vector: 44, Flash Control Event */ +#define PIC32MX_IRQSRC_USB (128+57) /* Vector: 45, USB */ +#define PIC32MX_IRQSRC1_LAST (128+57) + +#define PIC32MX_IRQSRC_FIRST PIC32MX_IRQSRC0_FIRST +#define PIC32MX_IRQSRC_LAST PIC32MX_IRQSRC1_LAST + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_3XX4XX_H */ + diff --git a/arch/mips/include/pic32mx/irq_5xx6xx7xx.h b/arch/mips/include/pic32mx/irq_5xx6xx7xx.h new file mode 100644 index 0000000000000000000000000000000000000000..f9f98027929fb6602b05766b1ef63cd11ef75836 --- /dev/null +++ b/arch/mips/include/pic32mx/irq_5xx6xx7xx.h @@ -0,0 +1,274 @@ +/**************************************************************************** + * arch/mips/include/pic32mx/irq_5xx6xx7xx.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_5XX6XX7XX_H +#define __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_5XX6XX7XX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt vector numbers. These should be used to attach to interrupts + * and to change interrupt priorities. + */ + +#define PIC32MX_IRQ_CT 0 /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQ_CS0 1 /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQ_CS1 2 /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQ_INT0 3 /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQ_T1 4 /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQ_IC1 5 /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQ_OC1 6 /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQ_INT1 7 /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQ_T2 8 /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQ_IC2 9 /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQ_OC2 10 /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQ_INT2 11 /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQ_T3 12 /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQ_IC3 13 /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQ_OC3 14 /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQ_INT3 15 /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQ_T4 16 /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQ_IC4 17 /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQ_OC4 18 /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQ_INT4 19 /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQ_T5 20 /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQ_IC5 21 /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQ_OC5 22 /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQ_SPI1 23 /* Vector: 23, SPI1 */ +#define PIC32MX_IRQ_VEC24 24 /* Vector: 24, UART1, SPI3, I2C3 */ +# define PIC32MX_IRQ_U1 24 /* Vector: 24, UART1 */ +# define PIC32MX_IRQ_SPI3 24 /* Vector: 24, SPI3 */ +# define PIC32MX_IRQ_I2C3 24 /* Vector: 24, I2C3 */ +#define PIC32MX_IRQ_I2C1 25 /* Vector: 25, I2C1 */ +#define PIC32MX_IRQ_CN 26 /* Vector: 26, Input Change Interrupt */ +#define PIC32MX_IRQ_AD1 27 /* Vector: 27, ADC1 Convert Done */ +#define PIC32MX_IRQ_PMP 28 /* Vector: 28, Parallel Master Port */ +#define PIC32MX_IRQ_CMP1 29 /* Vector: 29, Comparator Interrupt */ +#define PIC32MX_IRQ_CMP2 30 /* Vector: 30, Comparator Interrupt */ +#define PIC32MX_IRQ_VEC31 31 /* Vector: 31, UART3, SPI2, I2C4 */ +# define PIC32MX_IRQ_U3 31 /* Vector: 31, UART3 */ +# define PIC32MX_IRQ_SPI2 31 /* Vector: 31, SPI2 */ +# define PIC32MX_IRQ_I2C4 31 /* Vector: 31, I2C4 */ +#define PIC32MX_IRQ_VEC31 32 /* Vector: 32, UART2, SPI4, I2C5 */ +# define PIC32MX_IRQ_U2 32 /* Vector: 32, UART2 */ +# define PIC32MX_IRQ_SPI4 32 /* Vector: 32, SPI4 */ +# define PIC32MX_IRQ_I2C5 32 /* Vector: 32, I2C5 */ +#define PIC32MX_IRQ_I2C2 33 /* Vector: 33, I2C2 */ +#define PIC32MX_IRQ_FSCM 34 /* Vector: 34, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQ_RTCC 35 /* Vector: 35, Real-Time Clock and Calendar */ +#define PIC32MX_IRQ_DMA0 36 /* Vector: 36, DMA Channel 0 */ +#define PIC32MX_IRQ_DMA1 37 /* Vector: 37, DMA Channel 1 */ +#define PIC32MX_IRQ_DMA2 38 /* Vector: 38, DMA Channel 2 */ +#define PIC32MX_IRQ_DMA3 39 /* Vector: 39, DMA Channel 3 */ +#define PIC32MX_IRQ_DMA4 40 /* Vector: 40, DMA Channel 3 */ +#define PIC32MX_IRQ_DMA5 41 /* Vector: 41, DMA Channel 3 */ +#define PIC32MX_IRQ_DMA6 42 /* Vector: 42, DMA Channel 3 */ +#define PIC32MX_IRQ_DMA7 43 /* Vector: 43, DMA Channel 3 */ +#define PIC32MX_IRQ_FCE 44 /* Vector: 44, Flash Control Event */ +#define PIC32MX_IRQ_USB 45 /* Vector: 45, USB Interrupt */ +#define PIC32MX_IRQ_CAN1 46 /* Vector: 46, Control Area Network 1 */ +#define PIC32MX_IRQ_CAN2 47 /* Vector: 47, Control Area Network 2 */ +#define PIC32MX_IRQ_ETH 48 /* Vector: 48, Ethernet interrupt */ +#define PIC32MX_IRQ_U4 49 /* Vector: 49, UART4 */ +#define PIC32MX_IRQ_U6 50 /* Vector: 50, UART6 */ +#define PIC32MX_IRQ_U5 51 /* Vector: 51, UART5 */ +#define PIC32MX_IRQ_BAD 52 /* Not a real IRQ number */ +#define NR_IRQS 52 + +/* Interrupt numbers. These should be used for enabling and disabling + * interrupt sources. Note that there are more interrupt sources than + * interrupt vectors and interrupt priorities. An offset of 128 is + * used so that there is no overlap with the IRQ numbers and to avoid + * errors due to misuse. + */ + +#define PIC32MX_IRQSRC0_FIRST (128+0) +#define PIC32MX_IRQSRC_CT (128+0) /* Vector: 0, Core Timer Interrupt */ +#define PIC32MX_IRQSRC_CS0 (128+1) /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MX_IRQSRC_CS1 (128+2) /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MX_IRQSRC_INT0 (128+3) /* Vector: 3, External Interrupt 0 */ +#define PIC32MX_IRQSRC_T1 (128+4) /* Vector: 4, Timer 1 */ +#define PIC32MX_IRQSRC_IC1 (128+5) /* Vector: 5, Input Capture 1 */ +#define PIC32MX_IRQSRC_OC1 (128+6) /* Vector: 6, Output Compare 1 */ +#define PIC32MX_IRQSRC_INT1 (128+7) /* Vector: 7, External Interrupt 1 */ +#define PIC32MX_IRQSRC_T2 (128+8) /* Vector: 8, Timer 2 */ +#define PIC32MX_IRQSRC_IC2 (128+9) /* Vector: 9, Input Capture 2 */ +#define PIC32MX_IRQSRC_OC2 (128+10) /* Vector: 10, Output Compare 2 */ +#define PIC32MX_IRQSRC_INT2 (128+11) /* Vector: 11, External Interrupt 2 */ +#define PIC32MX_IRQSRC_T3 (128+12) /* Vector: 12, Timer 3 */ +#define PIC32MX_IRQSRC_IC3 (128+13) /* Vector: 13, Input Capture 3 */ +#define PIC32MX_IRQSRC_OC3 (128+14) /* Vector: 14, Output Compare 3 */ +#define PIC32MX_IRQSRC_INT3 (128+15) /* Vector: 15, External Interrupt 3 */ +#define PIC32MX_IRQSRC_T4 (128+16) /* Vector: 16, Timer 4 */ +#define PIC32MX_IRQSRC_IC4 (128+17) /* Vector: 17, Input Capture 4 */ +#define PIC32MX_IRQSRC_OC4 (128+18) /* Vector: 18, Output Compare 4 */ +#define PIC32MX_IRQSRC_INT4 (128+19) /* Vector: 19, External Interrupt 4 */ +#define PIC32MX_IRQSRC_T5 (128+20) /* Vector: 20, Timer 5 */ +#define PIC32MX_IRQSRC_IC5 (128+21) /* Vector: 21, Input Capture 5 */ +#define PIC32MX_IRQSRC_OC5 (128+22) /* Vector: 22, Output Compare 5 */ +#define PIC32MX_IRQSRC_SPI1E (128+23) /* Vector: 23, SPI1 Fault */ +#define PIC32MX_IRQSRC_SPI1RX (128+24) /* Vector: 23, " " Receive done */ +#define PIC32MX_IRQSRC_SPI1TX (128+25) /* Vector: 23, " " Transfer done */ +#define PIC32MX_IRQSRC_26 (128+26) /* Vector: 24, UART1, SPI3, I2C3 */ +# define PIC32MX_IRQSRC_U1E (128+26) /* Vector: 24, UART1 Error */ +# define PIC32MX_IRQSRC_SPI3E (128+26) /* Vector: 24, SPI3 Fault */ +# define PIC32MX_IRQSRC_I2C3B (128+26) /* Vector: 24, I2C3 Bus collision event */ +#define PIC32MX_IRQSRC_27 (128+27) /* Vector: 24, UART1, SPI3, I2C3 */ +# define PIC32MX_IRQSRC_U1RX (128+27) /* Vector: 24, UART1 Receiver */ +# define PIC32MX_IRQSRC_SPI3RX (128+27) /* Vector: 24, SPI3 Receive done */ +# define PIC32MX_IRQSRC_I2C3S (128+27) /* Vector: 24, I2C3 Slave event */ +#define PIC32MX_IRQSRC_28 (128+27) /* Vector: 24, UART1, SPI3, I2C3 */ +# define PIC32MX_IRQSRC_U1TX (128+28) /* Vector: 24, UART1 Transmitter */ +# define PIC32MX_IRQSRC_SPI3TX (128+28) /* Vector: 24, SPI3 Transfer done */ +# define PIC32MX_IRQSRC_I2C3M (128+28) /* Vector: 24, I2C3 Master event */ +#define PIC32MX_IRQSRC_I2C1B (128+29) /* Vector: 25, I2C1 Bus collision event*/ +#define PIC32MX_IRQSRC_I2C1S (128+30) /* Vector: 25, " " Slave event */ +#define PIC32MX_IRQSRC_I2C1M (128+31) /* Vector: 25, " " Master event */ +#define PIC32MX_IRQSRC0_LAST (128+31) + +#define PIC32MX_IRQSRC1_FIRST (128+32) +#define PIC32MX_IRQSRC_CN (128+32) /* Vector: 26, Input Change Interrupt */ +#define PIC32MX_IRQSRC_AD1 (128+33) /* Vector: 27, ADC1 Convert Done */ +#define PIC32MX_IRQSRC_PMP (128+34) /* Vector: 28, Parallel Master Port */ +#define PIC32MX_IRQSRC_CMP1 (128+35) /* Vector: 29, Comparator Interrupt */ +#define PIC32MX_IRQSRC_CMP2 (128+36) /* Vector: 30, Comparator Interrupt */ +#define PIC32MX_IRQSRC_37 (128+37) /* Vector: 31, UART3, SPI2, I2C4 */ +# define PIC32MX_IRQSRC_U3E (128+37) /* Vector: 31, UART3 Error */ +# define PIC32MX_IRQSRC_SPI2E (128+37) /* Vector: 31, SPI2 Fault */ +# define PIC32MX_IRQSRC_I2C4B (128+37) /* Vector: 31, I2C4 Bus collision event */ +#define PIC32MX_IRQSRC_38 (128+38) /* Vector: 31, UART3, SPI2, I2C4 */ +# define PIC32MX_IRQSRC_U3RX (128+38) /* Vector: 31, UART3 Receiver */ +# define PIC32MX_IRQSRC_SPI2RX (128+38) /* Vector: 31, SPI2 Receive done */ +# define PIC32MX_IRQSRC_I2C4S (128+38) /* Vector: 31, I2C4 Slave event */ +#define PIC32MX_IRQSRC_39 (128+39) /* Vector: 31, UART3, SPI2, I2C4 */ +# define PIC32MX_IRQSRC_U3TX (128+39) /* Vector: 31, UART3 Transmitter */ +# define PIC32MX_IRQSRC_SPI2TX (128+39) /* Vector: 31, SPI2 Transfer done */ +# define PIC32MX_IRQSRC_I2C4M (128+39) /* Vector: 31, I2C4 Master event */ +#define PIC32MX_IRQSRC_40 (128+40) /* Vector: 32, UART2, SPI4, I2C5 */ +# define PIC32MX_IRQSRC_U2E (128+40) /* Vector: 32, UART2 Error */ +# define PIC32MX_IRQSRC_SPI4E (128+40) /* Vector: 32, SPI4 Fault */ +# define PIC32MX_IRQSRC_I2C5B (128+40) /* Vector: 32, I2C5 Bus collision event */ +#define PIC32MX_IRQSRC_41 (128+41) /* Vector: 32, UART2, SPI4, I2C5 */ +# define PIC32MX_IRQSRC_U2RX (128+41) /* Vector: 32, UART2 Receiver */ +# define PIC32MX_IRQSRC_SPI4RX (128+41) /* Vector: 32, SPI4 Receive done */ +# define PIC32MX_IRQSRC_I2C5S (128+41) /* Vector: 32, I2C5 Slave event */ +#define PIC32MX_IRQSRC_42 (128+42) /* Vector: 32, UART2, SPI4, I2C5 */ +# define PIC32MX_IRQSRC_U2TX (128+42) /* Vector: 32, UART2 Transmitter */ +# define PIC32MX_IRQSRC_SPI4TX (128+42) /* Vector: 32, SPI4 Transfer done */ +# define PIC32MX_IRQSRC_I2C5M (128+42) /* Vector: 32, I2C5 Master event */ +#define PIC32MX_IRQSRC_I2C2B (128+43) /* Vector: 33, I2C2 Bus collision event */ +#define PIC32MX_IRQSRC_I2C2S (128+44) /* Vector: 33, " " Slave event */ +#define PIC32MX_IRQSRC_I2C2M (128+45) /* Vector: 33, " " Master event */ +#define PIC32MX_IRQSRC_FSCM (128+46) /* Vector: 34, Fail-Safe Clock Monitor */ +#define PIC32MX_IRQSRC_RTCC (128+47) /* Vector: 35, Real-Time Clock and Calendar */ +#define PIC32MX_IRQSRC_DMA0 (128+48) /* Vector: 36, DMA Channel 0 */ +#define PIC32MX_IRQSRC_DMA1 (128+49) /* Vector: 37, DMA Channel 1 */ +#define PIC32MX_IRQSRC_DMA2 (128+50) /* Vector: 38, DMA Channel 2 */ +#define PIC32MX_IRQSRC_DMA3 (128+51) /* Vector: 39, DMA Channel 3 */ +#define PIC32MX_IRQSRC_DMA4 (128+52) /* Vector: 40, DMA Channel 3 */ +#define PIC32MX_IRQSRC_DMA5 (128+53) /* Vector: 41, DMA Channel 3 */ +#define PIC32MX_IRQSRC_DMA6 (128+54) /* Vector: 42, DMA Channel 3 */ +#define PIC32MX_IRQSRC_DMA7 (128+55) /* Vector: 43, DMA Channel 3 */ +#define PIC32MX_IRQSRC_FCE (128+56) /* Vector: 44, Flash Control Event */ +#define PIC32MX_IRQSRC_USB (128+57) /* Vector: 45, USB Interrupt */ +#define PIC32MX_IRQSRC_CAN1 (128+58) /* Vector: 46, Control Area Network 1 */ +#define PIC32MX_IRQSRC_CAN2 (128+59) /* Vector: 47, Control Area Network 2 */ +#define PIC32MX_IRQSRC_ETH (128+60) /* Vector: 48, Ethernet interrupt */ +#define PIC32MX_IRQSRC_IC1E (128+61) /* Vector: 5, Input capture 1 error */ +#define PIC32MX_IRQSRC_IC2E (128+62) /* Vector: 9, Input capture 1 error */ +#define PIC32MX_IRQSRC_IC3E (128+63) /* Vector: 13, Input capture 1 error */ +#define PIC32MX_IRQSRC1_LAST (128+63) + +#define PIC32MX_IRQSRC2_FIRST (128+64) +#define PIC32MX_IRQSRC_IC4E (128+64) /* Vector: 17, Input capture 1 error */ +#define PIC32MX_IRQSRC_IC5E (128+65) /* Vector: 21, Input capture 1 error */ +#define PIC32MX_IRQSRC_PMPE (128+66) /* Vector: 28, Parallel master port error */ +#define PIC32MX_IRQSRC_U4E (128+67) /* Vector: 49, UART4 Error */ +#define PIC32MX_IRQSRC_U4RX (128+68) /* Vector: 49, UART4 Receiver */ +#define PIC32MX_IRQSRC_U4TX (128+69) /* Vector: 49, UART4 Transmitter */ +#define PIC32MX_IRQSRC_U6E (128+70) /* Vector: 50, UART6 Error */ +#define PIC32MX_IRQSRC_U6RX (128+71) /* Vector: 50, UART6 Receiver */ +#define PIC32MX_IRQSRC_U6TX (128+72) /* Vector: 50, UART6 Transmitter */ +#define PIC32MX_IRQSRC_U5E (128+73) /* Vector: 51, UART5 Error */ +#define PIC32MX_IRQSRC_U5RX (128+74) /* Vector: 51, UART5 Receiver */ +#define PIC32MX_IRQSRC_U5TX (128+75) /* Vector: 51, UART5 Transmitter */ +#define PIC32MX_IRQSRC2_LAST (128+75) + +#define PIC32MX_IRQSRC_FIRST PIC32MX_IRQSRC0_FIRST +#define PIC32MX_IRQSRC_LAST PIC32MX_IRQSRC2_LAST + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MX_IRQ_5XX6XX7XX_H */ + diff --git a/arch/mips/include/pic32mz/chip.h b/arch/mips/include/pic32mz/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..a96fb6ca707a8eaf64c655fdde5d398525995417 --- /dev/null +++ b/arch/mips/include/pic32mz/chip.h @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/mips/include/pic32mz/chip.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MZ_CHIP_H +#define __ARCH_MIPS_INCLUDE_PIC32MZ_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Available in 64/100/124/144 pin packages. Description here is specifically + * for the 144 pin package (PIC32MZ2048ECH144) and should be reviewed for + * other parts. + */ + +#if defined(CONFIG_ARCH_CHIP_PIC32MZ2048ECH) +# define CHIP_PIC32MZEC 1 +# define CHIP_BOOTFLASH_KB 160 /* 160Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 2048 /* 2048Kb program FLASH */ +# define CHIP_DATAMEM_KB 512 /* 512Kb data memory */ +# define CHIP_NTIMERS 9 /* 5 timers */ +# define CHIP_NIC 9 /* 5 input capture */ +# define CHIP_NOC 9 /* 5 output compare */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 6 /* 6 SPI/I2S interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NCRTYPO 0 /* No crtypo support */ +# define CHIP_RNG 1 /* 1 Random number generator */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 16 /* 16 dedicated DMA channels */ +# define CHIP_NADC10 48 /* 48 ADC channels */ +# define CHIP_NCM 2 /* 2 Analog comparators */ +# define CHIP_USBHSOTG 1 /* 1 USB 2.0 HSOTG */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NPMP 1 /* Have parallel master port */ +# define CHIP_NEBI 1 /* Have eternal bus interface */ +# define CHIP_NSQI 1 /* 1 Serial quad interface */ +# define CHIP_NRTCC 1 /* Has RTCC */ +# define CHIP_NETHERNET 1 /* 1 Ethernet MAC */ +# define CHIP_NPORTS 10 /* 10 ports (A-H, J-K) */ +# define CHIP_NJTAG 1 /* Has JTAG */ +# define CHIP_NTRACE 1 /* Has trace capability */ + +/* Available in 64/100/124/144 pin packages. Description here is specifically + * for the 144 pin package (PIC32MZ2048ECM144) and should be reviewed for + * other parts. + */ + +#elif defined(CONFIG_ARCH_CHIP_PIC32MZ2048ECM) +# define CHIP_PIC32MZEC 1 +# define CHIP_BOOTFLASH_KB 160 /* 160Kb boot FLASH */ +# define CHIP_PROGFLASH_KB 2048 /* 2048Kb program FLASH */ +# define CHIP_DATAMEM_KB 512 /* 512Kb data memory */ +# define CHIP_NTIMERS 9 /* 5 timers */ +# define CHIP_NIC 9 /* 5 input capture */ +# define CHIP_NOC 9 /* 5 output compare */ +# define CHIP_NUARTS 6 /* 6 UARTS */ +# define CHIP_UARTFIFOD 8 /* 8 level deep UART FIFOs */ +# define CHIP_NSPI 6 /* 6 SPI/I2S interfaces */ +# define CHIP_NCAN 2 /* 2 CAN interfaces */ +# define CHIP_NCRTYPO 1 /* Has crtypo support */ +# define CHIP_RNG 1 /* 1 Random number generator */ +# define CHIP_NDMACH 8 /* 8 programmable DMA channels */ +# define CHIP_NUSBDMACHAN 18 /* 18 dedicated DMA channels */ +# define CHIP_NADC10 48 /* 48 ADC channels */ +# define CHIP_NCM 2 /* 2 Analog comparators */ +# define CHIP_USBHSOTG 1 /* 1 USB 2.0 HSOTG */ +# define CHIP_NI2C 5 /* 5 I2C interfaces */ +# define CHIP_NPMP 1 /* Have parallel master port */ +# define CHIP_NEBI 1 /* Have eternal bus interface */ +# define CHIP_NSQI 1 /* 1 Serial quad interface */ +# define CHIP_NRTCC 1 /* Has RTCC */ +# define CHIP_NETHERNET 1 /* 1 Ethernet MAC */ +# define CHIP_NPORTS 10 /* 10 ports (A-H, J-K) */ +# define CHIP_NJTAG 1 /* Has JTAG */ +# define CHIP_NTRACE 1 /* Has trace capability */ + +#else +# error "Unrecognized PIC32MZ device +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MZ_CHIP_H */ diff --git a/arch/mips/include/pic32mz/cp0.h b/arch/mips/include/pic32mz/cp0.h new file mode 100644 index 0000000000000000000000000000000000000000..c5cee281492a783ad550a03338a25dbc253949a5 --- /dev/null +++ b/arch/mips/include/pic32mz/cp0.h @@ -0,0 +1,625 @@ +/**************************************************************************** + * arch/mips/include/pic32mz/cp0.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MZ_CP0_H +#define __ARCH_MIPS_INCLUDE_PIC32MZ_CP0_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* CP0 Register Addresses ***************************************************/ + +#ifdef __ASSEMBLY__ + +# define PIC32MZ_CP0_INDEX $0,0 /* Index into TLB array */ +# define PIC32MZ_CP0_RANDOM $1,0 /* Randomly index into TLB array */ +# define PIC32MZ_CP0_ENTRYLO0 $2,0 /* Lower TLB entry, even pages */ +# define PIC32MZ_CP0_ENTRYLO1 $3,0 /* Lower TLB entry, odd pages */ +# define PIC32MZ_CP0_CONTEXT $4,0 /* Address of page table entry in memory */ +# define PIC32MZ_CP0_USERLOCAL $4,2 /* User read/write register */ +# define PIC32MZ_CP0_PAGEMASK $5,0 /* Controls the variable page sizes */ +# define PIC32MZ_CP0_PAGEGRAIN $5,1 /* Enables support of 1 KB pages */ +# define PIC32MZ_CP0_WIRED $6,0 /* Number of fixed TLB entries */ +# define PIC32MZ_CP0_HWRENA $7,0 /* Enables access via RDHWR hardware registers */ +# define PIC32MZ_CP0_BADVADDR $8,0 /* Address of most recent exception */ +# define PIC32MZ_CP0_COUNT $9,0 /* Processor cycle count */ +# define PIC32MZ_CP0_ENTRYHI $10,0 /* Upper TLB entry */ +# define PIC32MZ_CP0_COMPARE $11,0 /* Timer interrupt control */ +# define PIC32MZ_CP0_STATUS $12,0 /* Processor status and control */ +# define PIC32MZ_CP0_INTCTL $12,1 /* Interrupt system status and control */ +# define PIC32MZ_CP0_SRSCTL $12,2 /* Shadow register set status and control */ +# define PIC32MZ_CP0_SRSMAP $12,3 /* Maps from vectored interrupt to a shadow set */ +# define PIC32MZ_CP0_VIEWIPL $12,4 /* Priority level access */ +# define PIC32MZ_CP0_SRSMAP2 $12,5 /* Vector number to shadow set mapping */ +# define PIC32MZ_CP0_CAUSE $13,0 /* Cause of last general exception */ +# define PIC32MZ_CP0_VIEWRIPL $13,4 /* RIPL accesss */ +# define PIC32MZ_CP0_NESTEDEXC $13,5 /* Prior error and exception level */ +# define PIC32MZ_CP0_EPC $14,0 /* Program counter at last exception */ +# define PIC32MZ_CP0_NESTEDEPC $14,2 /* Prior EPC */ +# define PIC32MZ_CP0_PRID $15,0 /* Processor identification and revision */ +# define PIC32MZ_CP0_EBASE $15,1 /* Exception vector base register */ +# define PIC32MZ_CP0_CDMMBASE $15,2 /* Common device memory map base */ +# define PIC32MZ_CP0_CONFIG $16,0 /* Configuration register */ +# define PIC32MZ_CP0_CONFIG1 $16,1 /* Configuration register 1 */ +# define PIC32MZ_CP0_CONFIG2 $16,2 /* Configuration register 3 */ +# define PIC32MZ_CP0_CONFIG3 $16,3 /* Configuration register 3 */ +# define PIC32MZ_CP0_CONFIG4 $16,4 /* Configuration register 4 */ +# define PIC32MZ_CP0_CONFIG5 $16,5 /* Configuration register 5 */ +# define PIC32MZ_CP0_CONFIG7 $16,7 /* Configuration register 7 */ +# define PIC32MZ_CP0_LLADDR $17,0 /* Load link address */ +# define PIC32MZ_CP0_WATCHLO $18,0 /* Low-order watchpoint address */ +# define PIC32MZ_CP0_WATCHHI $19,0 /* High-order watchpoint address */ +# define PIC32MZ_CP0_DEBUG $23,0 /* Debug control and exception status */ +# define PIC32MZ_CP0_TRACECTRL $23,1 /* EJTAG trace control */ +# define PIC32MZ_CP0_TRACECTRL2 $23,2 /* EJTAG trace control 2 */ +# define PIC32MZ_CP0_TRACEDATA1 $23,3 /* EJTAG user trace data 1 register */ +# define PIC32MZ_CP0_TRACEBPC $23,4 /* EJTAG trace breakpoint register */ +# define PIC32MZ_CP0_DEBUG2 $23,5 /* Debug control/exception status 2 */ +# define PIC32MZ_CP0_DEPC $24,0 /* Program counter at last debug exception */ +# define PIC32MZ_CP0_TRACEDATA2 $24,3 /* EJTAG user trace data 2 register */ +# define PIC32MZ_CP0_PERFCTL0 $25,0 /* Performance counter 0 control */ +# define PIC32MZ_CP0_PERFCNT0 $25,1 /* Performance counter 0 */ +# define PIC32MZ_CP0_PERFCTL1 $25,2 /* Performance counter 1 control */ +# define PIC32MZ_CP0_PERFCNT1 $25,3 /* Performance counter 1 */ +# define PIC32MZ_CP0_ERRCTL $26,0 /* Test enable for cache RAM arrays */ +# define PIC32MZ_CP0_TAGLO $28,0 /* Low-order portion of cache tag interface */ +# define PIC32MZ_CP0_DATALO $28,1 /* Low-order portion of cache tag interface */ +# define PIC32MZ_CP0_ERREPC $30,0 /* Program counter at last error */ +# define PIC32MZ_CP0_DESAVE $31,0 /* Debug handler scratchpad register */ +#endif + +/* CP0 Registers ************************************************************/ + +/* Register Number: 0 Sel: 0 Name: Index + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 1 Sel: 0 Name: Random + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 2 Sel: 0 Name: EntryLo0 + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 3 Sel: 0 Name: EntryLo1 + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 4 Sel: 0 Name: Context + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 4 Sel: 2 Name: UserLocal + * Function: User read/write register + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 5 Sel: 0 Name: PageMask + * Function: Used for reading from and writing to the TLB + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 5 Sel: 1 Name: PageGrain + * Function: Enable or disable the read and execute inhibit bits in the + * EntryLo0 and EntryLo1 registers. + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 6 Sel: 0 Name: Wired + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + * To be provided + */ + +/* Register Number: 7 Sel: 0 Name: HWREna + * Function: Enables access via the RDHWR instruction to selected hardware + * registers in non-privileged mode. + * Compliance Level: (Reserved for future extensions) + */ + +#define CP0_HWRENA_SHIFT (0) /* Bits 0-3: Enable access to a hardware resource */ +#define CP0_HWRENA_MASK (15 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT0 (1 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT1 (2 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT2 (4 << CP0_HWRENA_SHIFT) +# define CP0_HWRENA_BIT3 (8 << CP0_HWRENA_SHIFT) +#define CP0_HWRENA_ULR (1 << 29) /* Bit 29: User Local Register bit */ + +/* Register Number: 8 Sel: 0 Name: BadVAddr + * Function: Reports the address for the most recent address-related + * exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 9 Sel: 0 Name: Count + * Function: Processor cycle count + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 10 Sel: 0 Name: EntryHi + * Compliance Level: Required for TLB-based MMU; Optional otherwise. + */ + +/* Register Number: 11 Sel: 0 Name: Compare + * Function: Timer interrupt control + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 12 Sel: 0 Name: Status + * Function: Processor status and control + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTES: + * 1. The following are reserved bits in the PIC32MZ: + * CP0_STATUS_UX Bit 5: Enables 64-bit user address space (Not MIPS32) + * CP0_STATUS_SX Bit 6: Enables 64-bit supervisor address space (Not MIPS32) + * CP0_STATUS_KX Bit 7: Enables 64-bit kernel address space (Not MIPS32) + * CP0_STATUS_IMPL Bits 16-17: Implementation dependent + * CP0_STATUS_PX Bit 23: Enables 64-bit operations (Not MIPS32) + * CP0_STATUS_FR Bit 26: Controls the floating point register mode (Not MIPS32) + * CP0_STATUS_MX Bit 24: Enables MDMX™ (Not MIPS32) + * CP0_STATUS_CU1 Bit 29: Controls access to coprocessor 1 + * CP0_STATUS_CU2 Bit 30: Controls access to coprocessor 2 + * CP0_STATUS_CU3 Bit 31: Controls access to coprocessor 3 + */ + +#undef CP0_STATUS_UX +#undef CP0_STATUS_SX +#undef CP0_STATUS_KX +#undef CP0_STATUS_IMPL +#undef CP0_STATUS_IMPL_SHIFT +#undef CP0_STATUS_IMPL_MASK +#undef CP0_STATUS_PX +#undef CP0_STATUS_FR +#undef CP0_STATUS_CU1 +#undef CP0_STATUS_CU2 +#undef CP0_STATUS_CU3 + +/* 2. The following field is of a different width. Apparently, it + * excludes the software interrupt bits. + * + * CP0_STATUS_IM Bits 8-15: Interrupt Mask + * Vs. + * CP0_STATUS_IPL Bits 10-16+18: Interrupt priority level + * Bits 8-9 reserved + */ + +#define CP0_STATUS_IPL_SHIFT (10) /* Bits 10-16+18: Interrupt priority level */ +#define CP0_STATUS_IPL_MASK (0x17f << CP0_STATUS_IPL_SHIFT) + +/* 3. Supervisor mode not supported + * CP0_STATUS_KSU Bits 3-4: Operating mode (with supervisor mode) + */ + +#undef CP0_STATUS_KSU_SUPER + +/* Register Number: 12 Sel: 1 Name: IntCtl */ + +#define CP0_INTCTL_VS_SHIFT (5) /* Bits 5-9: Vector spacing bits */ +#define CP0_INTCTL_VS_MASK (0x1f << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_0BYTES (0x00 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_32BYTES (0x01 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_64BYTES (0x02 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_128BYTES (0x04 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_256BYTES (0x08 << CP0_INTCTL_VS_SHIFT) +# define CP0_INTCTL_VS_512BYTES (0x10 << CP0_INTCTL_VS_SHIFT) + +/* Register Number: 12 Sel: 2 Name: SRSCtl */ + +#define CP0_SRSCTL_CSS_SHIFT (0) /* Bits 0-3: Current shadow bit set */ +#define CP0_SRSCTL_CSS_MASK (15 << CP0_SRSCTL_CSS_SHIFT) +#define CP0_SRSCTL_PSS_SHIFT (6) /* Bits 6-9: Previous shadow set */ +#define CP0_SRSCTL_PSS_MASK (15 << CP0_SRSCTL_PSS_SHIFT) +#define CP0_SRSCTL_ESS_SHIFT (12) /* Bits 12-15: Exception shadow sets */ +#define CP0_SRSCTL_ESS_MASK (15 << CP0_SRSCTL_ESS_SHIFT) +#define CP0_SRSCTL_EICSS_SHIFT (18) /* Bits 18-21: External interrupt controller shadow sets */ +#define CP0_SRSCTL_EICSS_MASK (15 << CP0_SRSCTL_EICSS_SHIFT) +#define CP0_SRSCTL_HSS_SHIFT (26) /* Bits 26-29: High shadow sets */ +#define CP0_SRSCTL_HSS_MASK (15 << CP0_SRSCTL_HSS_SHIFT) +# define CP0_SRSCTL_HSS_1SET (0 << CP0_SRSCTL_HSS_SHIFT) /* One shadow set (normal GPR set) */ +# define CP0_SRSCTL_HSS_2SETS (1 << CP0_SRSCTL_HSS_SHIFT) /* Two shadow sets */ +# define CP0_SRSCTL_HSS_4SETS (3 << CP0_SRSCTL_HSS_SHIFT) /* Four shadow sets */ + +/* Register Number: 12 Sel: 3 Name: SRSMap */ + +#define CP0_SRSMAP_SSV0_SHIFT (0) /* Bits 0-3: Shadow set vector 0 */ +#define CP0_SRSMAP_SSV0_MASK (15 << CP0_SRSMAP_SSV0_SHIFT) +#define CP0_SRSMAP_SSV1_SHIFT (4) /* Bits 4-7: Shadow set vector 1 */ +#define CP0_SRSMAP_SSV1_MASK (15 << CP0_SRSMAP_SSV1_SHIFT) +#define CP0_SRSMAP_SSV2_SHIFT (8) /* Bits 8-11: Shadow set vector 2 */ +#define CP0_SRSMAP_SSV2_MASK (15 << CP0_SRSMAP_SSV2_SHIFT) +#define CP0_SRSMAP_SSV3_SHIFT (12) /* Bits 12-15: Shadow set vector 3 */ +#define CP0_SRSMAP_SSV3_MASK (15 << CP0_SRSMAP_SSV3_SHIFT) +#define CP0_SRSMAP_SSV4_SHIFT (16) /* Bits 16-19: Shadow set vector 4 */ +#define CP0_SRSMAP_SSV4_MASK (15 << CP0_SRSMAP_SSV4_SHIFT) +#define CP0_SRSMAP_SSV5_SHIFT (20) /* Bits 20-23: Shadow set vector 5 */ +#define CP0_SRSMAP_SSV5_MASK (15 << CP0_SRSMAP_SSV5_SHIFT) +#define CP0_SRSMAP_SSV6_SHIFT (24) /* Bits 24-27: Shadow set vector 6 */ +#define CP0_SRSMAP_SSV6_MASK (15 << CP0_SRSMAP_SSV6_SHIFT) +#define CP0_SRSMAP_SSV7_SHIFT (28) /* Bits 28-31: Shadow set vector 7 */ +#define CP0_SRSMAP_SSV7_MASK (15 << CP0_SRSMAP_SSV7_SHIFT) + +/* Register Number: 12 Sel: 4 Name: View_Ipl + * To be provided + */ + +/* Register Number: 12 Sel: 5 Name: SRSMap2 + * To be provided + */ + +/* Register Number: 13 Sel: 0 Name: Cause + * Function: Cause of last general exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTES: The following bits are added in the PIC32: + */ + +#define CP0_CAUSE_R (1 << 26) /* Bit 26: R bit */ +#define CP0_CAUSE_DC (1 << 27) /* Bit 27: Disable count */ +#define CP0_CAUSE_TI (1 << 30) /* Bit 30: Timer interrupt bit */ + +/* Register Number: 13 Sel: 4 Name: View_RIPL + * To be provided + */ + +/* Register Number: 13 Sel: 5 Name: NestedExc + * To be provided + */ + +/* Register Number: 14 Sel: 0 Name: EPC + * Function: Program counter at last exception + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 14 Sel: 2 Name: NestedEPC + * To be provided + */ + +/* Register Number: 15 Sel: 0 Name: PRId + * Function: Processor identification and revision + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * NOTE: Slightly different bit interpretations of some fields: + */ + +#define CP0_PRID_PATCH_SHIFT (5) /* Bits 0-1: Patch level */ +#define CP0_PRID_PATCH_MASK (3 << CP0_PRID_PATCH_SHIFT) +#define CP0_PRID_MINOR_SHIFT (2) /* Bits 2-4: Minor revision number */ +#define CP0_PRID_MINOR_MASK (7 << CP0_PRID_MINOR_SHIFT) +#define CP0_PRID_MAJOR_SHIFT (5) /* Bits 5-7: Major revision number */ +#define CP0_PRID_MAJOR_MASK (7 << CP0_PRID_MAJOR_SHIFT) + +#undef CP0_PRID_OPTIONS_SHIFT +#undef CP0_PRID_OPTIONS_MASK + +/* Register Number: 15 Sel: 1 Name: EBASE */ + +#define CP_EBASE_CPUNUM_SHIFT (0) /* Bits 0-9: CPU number */ +#define CP_EBASE_CPUNUM_MASK (0x3ff << CP_EBASE_CPUNUM_SHIFT) +#define CP_EBASE_SHIFT (12) /* Bits 30-31=10, Bits 12-29: Exception base */ +#define CP_EBASE_MASK (0x3ffff << CP_EBASE_SHIFT) + +/* Register Number: 15 Sel: 2 Name: CDMMBase + * To be provided + */ + +/* Register Number: 16 Sel: 0 Name: Config + * Function: Configuration register + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * 1. PIC32MZ is always little-endian. + * 2. Implementation specific bits defined. + */ + +#undef CP0_CONFIG_MT_NONE +#undef CP0_CONFIG_MT_TLB +#undef CP0_CONFIG_MT_BAT + +#undef CP0_CONFIG_IMPL_SHIFT +#undef CP0_CONFIG_IMPL_MASK + +#define CP0_CONFIG_DS (1 << 16) /* Dual SRAM bit */ +#define CP0_CONFIG_BM (1 << 16) /* Burst Mode bit */ +#define CP0_CONFIG_MM_SHIFT (17) /* Bits 17-18: Merge Mode bits */ +#define CP0_CONFIG_MM_MASK (3 << CP0_CONFIG_MM_SHIFT) +# define CP0_CONFIG_MM_PROHIBITED (0 << CP0_CONFIG_MM_SHIFT) /* Merging is not allowed */ +# define CP0_CONFIG_MM_ALLOWED (2 << CP0_CONFIG_MM_SHIFT) /* Merging is allowed */ +#define CP0_CONFIG_MDU (1 << 20) /* Multipley/Divide unit bit */ +#define CP0_CONFIG_SB (1 << 21) /* Bit 32: Simple BE bus mode bit */ +#define CP0_CONFIG_UDI (1 << 22) /* Bit 22: User defined bit */ +#define CPO_CONFIG_DSP (1 << 23) /* Bit 24: Data Scratchpad RAM bit */ +#define CPO_CONFIG_ISP (1 << 24) /* Bit 24: Instruction Scratchpad RAM bit */ +#define CP0_CONFIG_KU_SHIFT (25) /* Bits 25-27: KUSEG and USEG cacheability */ +#define CP0_CONFIG_KU_MASK (7 << CP0_CONFIG_KU_SHIFT) +# define CP0_CONFIG_KU_UNCACHED (2 << CP0_CONFIG_KU_SHIFT) +# define CP0_CONFIG_KU_CACHEABLE (3 << CP0_CONFIG_KU_SHIFT) +#define CP0_CONFIG_K23_SHIFT (28) /* Bits 28-30: KSEG2 and KSEG3 cacheability */ +#define CP0_CONFIG_K23_MASK (7 << CP0_CONFIG_K23_SHIFT) +# define CP0_CONFIG_K23_UNCACHED (2 << CP0_CONFIG_K23_SHIFT) +# define CP0_CONFIG_K23_CACHEABLE (3 << CP0_CONFIG_K23_SHIFT) + +/* Register Number: 16 Sel: 1 Name: Config1 + * Function: Configuration register 1 + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 16 Sel: 2 Name: Config2 + * Function: Configuration register 2 + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +#undef CP0_CONFIG2_TBS_SHIFT +#undef CP0_CONFIG2_TBS_MASK + +/* Register Number: 16 Sel: 3 Name: Config3 + * Function: Configuration register 3 + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +#define CP0_CONFIG3_SP (1 << 4) /* Bit 4: Support page bit */ +#define CP0_CONFIG3_VINT (1 << 5) /* Bit 5: Vector interrupt bit */ +#define CP0_CONFIG3_VEIC (1 << 6) /* Bit 6: External interrupt controller supported */ + +/* Register Number: 16 Sel: 4 Name: Config4 + * To be provided + */ + +/* Register Number: 16 Sel: 5 Name: Config5 + * To be provided + */ + +/* Register Number: 16 Sel: 7 Name: Config7 + * To be provided + */ + +/* Register Number: 17 Sel: 0 Name: LLAddr + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 18 Sel: 0 Name: WatchLo + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 19 Sel: 0 Name: WatchHi + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 20-22 Reserved + * Compliance Level: Optional. + */ + +/* Register Number: 23 Sel: 0 Name: Debug + * Function: EJTAG Debug register + * Compliance Level: Optional. + */ + +#define CP0_DEBUG_DSS (1 << 0) /* Bit 0: Debug single-step exception */ +#define CP0_DEBUG_DBP (1 << 1) /* Bit 1: Debug software breakpoint exception */ +#define CP0_DEBUG_DDBL (1 << 2) /* Bit 2: Debug data break exception on load */ +#define CP0_DEBUG_DDBS (1 << 3) /* Bit 3: Debug data break exception on store */ +#define CP0_DEBUG_DIB (1 << 4) /* Bit 4: Debug instruction break exception */ +#define CP0_DEBUG_DINT (1 << 5) /* Bit 5: Debug interrupt exception */ +#define CP0_DEBUG_SST (1 << 8) /* Bit 6: Enable debug single step exception */ +#define CP0_DEBUG_NOSST (1 << 9) /* Bit 7: No single step feature available */ +#define CP0_DEBUG_DEXCCODE_SHIFT (10) /* Bits 10-14: Cause of latest exception in DEBUG mode */ +#define CP0_DEBUG_DEXCCODE_MASK (31 << CP0_DEBUG_DEXCCODE_SHIFT) +#define CP0_DEBUG_VER_SHIFT (15) /* Bits 15-17: EJTAG version */ +#define CP0_DEBUG_VER_MASK (7 << CP0_DEBUG_VER_SHIFT) +#define CP0_DEBUG_DDBLIMPR (1 << 18) /* Bit 18: Imprecise debug data break load instruction */ +#define CP0_DEBUG_DDBSIMPR (1 << 19) /* Bit 19: Imprecise debug data break store instruction */ +#define CP0_DEBUG_IEXI (1 << 20) /* Bit 20: Imprecise error exception inhibit */ +#define CP0_DEBUG_DBUSEP (1 << 21) /* Bit 21: Data access bus error exception pending */ +#define CP0_DEBUG_CACHEEP (1 << 22) /* Bit 22: Imprecise cache error exception is pending */ +#define CP0_DEBUG_MCHECKP (1 << 23) /* Bit 23: Imprecise machine check exception is pending */ +#define CP0_DEBUG_IBUSEP (1 << 24) /* Bit 24: Bus error exception pending */ +#define CP0_DEBUG_COUNTDM (1 << 25) /* Bit 25: Count register behavior (1=running) */ +#define CP0_DEBUG_HALT (1 << 26) /* Bit 26: Internal system bus clock stopped */ +#define CP0_DEBUG_DOZE (1 << 27) /* Bit 27: Processor in low power mode */ +#define CP0_DEBUG_LSNM (1 << 28) /* Bit 28: Load/store in DSEG goes to main memory */ +#define CP0_DEBUG_NODCR (1 << 29) /* Bit 29: No DSEG preset */ +#define CP0_DEBUG_DM (1 << 30) /* Bit 30: Processor is operating in DEBUG mode */ +#define CP0_DEBUG_DBD (1 << 31) /* Bit 31: Last debug exception occurred in a dely slot */ + +/* Register Number: 23 Sel: 1 Name: TraceControl + * Function: EJTAG Debug register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 23 Sel: 2 Name: TraceControl2 + * Function: EJTAG Debug register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 23 Sel: 3 Name: UserTraceData1 + * Function: EJTAG Debug register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 23 Sel: 4 Name: TraceBPC + * Function: EJTAG Debug register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 23 Sel: 5 Name: Debug2 + * Function: EJTAG Debug register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 24 Sel: 0 Name: DEPC + * Function: Program counter at last EJTAG debug exception + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +/* Register Number: 24 Sel: 3 Name: UserTraceData2 + * Function: EJTAG user trace data 2 register + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 25 Sel: 0 Name: PerfCtl0 + * Function: Performance counter 0 control + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 25 Sel: 1 Name: PerfCnt0 + * Function: Performance counter 0 + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 25 Sel: 2 Name: PerfCtl1 + * Function: Performance counter 1 control + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 25 Sel: 3 Name: PerfCnt1 + * Function: Performance counter 1 + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 26 Sel: 0 Name: ErrCtl + * Function: Software test enable of way-select and data RAM arrays for + * I-Cache and D-Cache + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 27 Reserved + * Compliance Level: Recommended/Optional. + */ + +/* Register Number: 28 Sel: 0 Name: TagLo + * Function: Low-order portion of cache tag interface + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 28 Sel: 1 Name: DataLo + * Function: Low-order portion of cache tag interface + * Compliance Level: Optional. + * To be provided + */ + +/* Register Number: 29 Reserved + * Compliance Level: Recommended/Optional. + */ + +/* Register Number: 30 Sel: 0 Name: ErrorEPC + * Function: Program counter at last error + * Compliance Level: Required. + * + * See arch/mips/include/mips32/cp0.h + * + * Register Number: 31 Sel: 0 Name: DeSAVE + * Function: EJTAG debug exception save register + * Compliance Level: Optional. + * + * See arch/mips/include/mips32/cp0.h + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MZ_CP0_H */ diff --git a/arch/mips/include/pic32mz/irq.h b/arch/mips/include/pic32mz/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..f00dc0bebaf79bcd078a1ce16060cabd99a0cb88 --- /dev/null +++ b/arch/mips/include/pic32mz/irq.h @@ -0,0 +1,213 @@ +/**************************************************************************** + * arch/mips/include/pic32mz/irq.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_H +#define __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CHIP_PIC32MZEC) +# include +#else +# error "Unknown PIC32MZ family +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cp0_getintctl + * + * Description: + * Get the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getintctl(void) +{ + register uint32_t intctl; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $12, 1\n" /* Get CP0 IntCtl register */ + "\t.set pop\n" + : "=r" (intctl) + : + : "memory" + ); + + return intctl; +} + +/**************************************************************************** + * Name: cp0_putintctl + * + * Description: + * Write the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putintctl(uint32_t intctl) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $12, 1\n" /* Set the IntCtl to the provided value */ + "\t.set pop\n" + : + : "r" (intctl) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp0_getebase + * + * Description: + * Get the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getebase(void) +{ + register uint32_t ebase; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $15, 1\n" /* Get CP0 EBASE register */ + "\t.set pop\n" + : "=r" (ebase) + : + : "memory" + ); + + return ebase; +} + +/**************************************************************************** + * Name: cp0_putebase + * + * Description: + * Write the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putebase(uint32_t ebase) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $15, 1\n" /* Set the EBASE to the provided value */ + "\t.set pop\n" + : + : "r" (ebase) + : "memory" + ); +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_H */ + diff --git a/arch/mips/include/pic32mz/irq_pic32mzxxxec.h b/arch/mips/include/pic32mz/irq_pic32mzxxxec.h new file mode 100644 index 0000000000000000000000000000000000000000..64c0727c4dc1b90c01c02dd8d3d1c82812422a4f --- /dev/null +++ b/arch/mips/include/pic32mz/irq_pic32mzxxxec.h @@ -0,0 +1,283 @@ +/**************************************************************************** + * arch/mips/include/pic32mz/irq_pic32mzxxxec.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_PIC32MZXXXEC_H +#define __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_PIC32MZXXXEC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt vector numbers. These should be used to attach to interrupts + * and to change interrupt priorities. + */ + +#define PIC32MZ_IRQ_CT 0 /* Vector: 0, Core Timer Interrupt */ +#define PIC32MZ_IRQ_CS0 1 /* Vector: 1, Core Software Interrupt 0 */ +#define PIC32MZ_IRQ_CS1 2 /* Vector: 2, Core Software Interrupt 1 */ +#define PIC32MZ_IRQ_INT0 3 /* Vector: 3, External Interrupt 0 */ +#define PIC32MZ_IRQ_T1 4 /* Vector: 4, Timer 1 */ +#define PIC32MZ_IRQ_ICE1 5 /* Vector: 5, Input Capture 1 Error */ +#define PIC32MZ_IRQ_IC1 6 /* Vector: 6, Input Capture 1 */ +#define PIC32MZ_IRQ_OC1 7 /* Vector: 7, Output Compare 1 */ +#define PIC32MZ_IRQ_INT1 8 /* Vector: 8, External Interrupt 1 */ +#define PIC32MZ_IRQ_T2 9 /* Vector: 9, Timer 2 */ +#define PIC32MZ_IRQ_ICE2 10 /* Vector: 10, Input Capture 2 Error */ +#define PIC32MZ_IRQ_IC2 11 /* Vector: 11, Input Capture 2 */ +#define PIC32MZ_IRQ_OC2 12 /* Vector: 12, Output Compare 2 */ +#define PIC32MZ_IRQ_INT2 13 /* Vector: 13, External Interrupt 2 */ +#define PIC32MZ_IRQ_T3 14 /* Vector: 14, Timer 3 */ +#define PIC32MZ_IRQ_ICE3 15 /* Vector: 15, Input Capture 3 Error */ +#define PIC32MZ_IRQ_IC3 16 /* Vector: 16, Input Capture 3 */ +#define PIC32MZ_IRQ_OC3 17 /* Vector: 17, Output Compare 3 */ +#define PIC32MZ_IRQ_INT3 18 /* Vector: 18, External Interrupt 3 */ +#define PIC32MZ_IRQ_T4 19 /* Vector: 19, Timer 4 */ +#define PIC32MZ_IRQ_ICE4 20 /* Vector: 20, Input Capture 4 Error */ +#define PIC32MZ_IRQ_IC4 21 /* Vector: 21, Input Capture 4 */ +#define PIC32MZ_IRQ_OC4 22 /* Vector: 22, Output Compare 4 */ +#define PIC32MZ_IRQ_INT4 23 /* Vector: 23, External Interrupt 4 */ +#define PIC32MZ_IRQ_T5 24 /* Vector: 24, Timer 5 */ +#define PIC32MZ_IRQ_ICE5 25 /* Vector: 25, Input Capture 5 Error */ +#define PIC32MZ_IRQ_IC5 26 /* Vector: 26, Input Capture 5 */ +#define PIC32MZ_IRQ_OC5 27 /* Vector: 27, Output Compare 5 */ +#define PIC32MZ_IRQ_T6 28 /* Vector: 28, Timer 6 */ +#define PIC32MZ_IRQ_ICE6 29 /* Vector: 29, Input Capture 6 Error */ +#define PIC32MZ_IRQ_IC6 30 /* Vector: 30, Input Capture 6 */ +#define PIC32MZ_IRQ_OC6 31 /* Vector: 31, Output Compare 6 */ +#define PIC32MZ_IRQ_T7 32 /* Vector: 32, Timer 7 */ +#define PIC32MZ_IRQ_ICE7 33 /* Vector: 33, Input Capture 7 Error */ +#define PIC32MZ_IRQ_IC7 34 /* Vector: 34, Input Capture 7 */ +#define PIC32MZ_IRQ_OC7 35 /* Vector: 35, Output Compare 7 */ +#define PIC32MZ_IRQ_T8 36 /* Vector: 36, Timer 8 */ +#define PIC32MZ_IRQ_ICE8 37 /* Vector: 37, Input Capture 8 Error */ +#define PIC32MZ_IRQ_IC8 38 /* Vector: 38, Input Capture 8 */ +#define PIC32MZ_IRQ_OC8 39 /* Vector: 39, Output Compare 8 */ +#define PIC32MZ_IRQ_T9 40 /* Vector: 40, Timer 9 */ +#define PIC32MZ_IRQ_ICE9 41 /* Vector: 41, Input Capture 9 Error */ +#define PIC32MZ_IRQ_IC9 42 /* Vector: 42, Input Capture 9 */ +#define PIC32MZ_IRQ_OC9 43 /* Vector: 43, Output Compare 9 */ +#define PIC32MZ_IRQ_AD1 44 /* Vector: 44, ADC1 Global Interrupt */ + /* Vector: 45, Reserved */ +#define PIC32MZ_IRQ_AD1CMP1 46 /* Vector: 46, ADC1 Digital Comparator 1 */ +#define PIC32MZ_IRQ_AD1CMP2 47 /* Vector: 47, ADC1 Digital Comparator 2 */ +#define PIC32MZ_IRQ_AD1CMP3 48 /* Vector: 48, ADC1 Digital Comparator 3 */ +#define PIC32MZ_IRQ_AD1CMP4 49 /* Vector: 49, ADC1 Digital Comparator 4 */ +#define PIC32MZ_IRQ_AD1CMP5 50 /* Vector: 50, ADC1 Digital Comparator 5 */ +#define PIC32MZ_IRQ_AD1CMP6 51 /* Vector: 51, ADC1 Digital Comparator 6 */ +#define PIC32MZ_IRQ_AD1FLT1 52 /* Vector: 52, ADC1 Digital Filter 1 */ +#define PIC32MZ_IRQ_AD1FLT2 53 /* Vector: 53, ADC1 Digital Filter 2 */ +#define PIC32MZ_IRQ_AD1FLT3 54 /* Vector: 54, ADC1 Digital Filter 3 */ +#define PIC32MZ_IRQ_AD1FLT4 55 /* Vector: 55, ADC1 Digital Filter 4 */ +#define PIC32MZ_IRQ_AD1FLT5 56 /* Vector: 56, ADC1 Digital Filter 5 */ +#define PIC32MZ_IRQ_AD1FLT6 57 /* Vector: 57, ADC1 Digital Filter 6 */ + /* Vector: 58, Reserved */ +#define PIC32MZ_IRQ_AD1DAT0 59 /* Vector: 59, ADC1 Data 0 */ +#define PIC32MZ_IRQ_AD1DAT1 60 /* Vector: 60, ADC1 Data 1 */ +#define PIC32MZ_IRQ_AD1DAT2 61 /* Vector: 61, ADC1 Data 2 */ +#define PIC32MZ_IRQ_AD1DAT3 62 /* Vector: 62, ADC1 Data 3 */ +#define PIC32MZ_IRQ_AD1DAT4 63 /* Vector: 63, ADC1 Data 4 */ +#define PIC32MZ_IRQ_AD1DAT5 64 /* Vector: 64, ADC1 Data 5 */ +#define PIC32MZ_IRQ_AD1DAT6 65 /* Vector: 65, ADC1 Data 6 */ +#define PIC32MZ_IRQ_AD1DAT7 66 /* Vector: 66, ADC1 Data 7 */ +#define PIC32MZ_IRQ_AD1DAT8 67 /* Vector: 67, ADC1 Data 8 */ +#define PIC32MZ_IRQ_AD1DAT9 68 /* Vector: 68, ADC1 Data 9 */ +#define PIC32MZ_IRQ_AD1DAT10 69 /* Vector: 69, ADC1 Data 10 */ +#define PIC32MZ_IRQ_AD1DAT11 70 /* Vector: 70, ADC1 Data 11 */ +#define PIC32MZ_IRQ_AD1DAT12 71 /* Vector: 71, ADC1 Data 12 */ +#define PIC32MZ_IRQ_AD1DAT13 72 /* Vector: 72, ADC1 Data 13 */ +#define PIC32MZ_IRQ_AD1DAT14 73 /* Vector: 73, ADC1 Data 14 */ +#define PIC32MZ_IRQ_AD1DAT15 74 /* Vector: 74, ADC1 Data 15 */ +#define PIC32MZ_IRQ_AD1DAT16 75 /* Vector: 75, ADC1 Data 16 */ +#define PIC32MZ_IRQ_AD1DAT17 76 /* Vector: 76, ADC1 Data 17 */ +#define PIC32MZ_IRQ_AD1DAT18 77 /* Vector: 77, ADC1 Data 18 */ +#define PIC32MZ_IRQ_AD1DAT19 78 /* Vector: 78, ADC1 Data 19 */ +#define PIC32MZ_IRQ_AD1DAT20 79 /* Vector: 79, ADC1 Data 20 */ +#define PIC32MZ_IRQ_AD1DAT21 80 /* Vector: 80, ADC1 Data 21 */ +#define PIC32MZ_IRQ_AD1DAT22 81 /* Vector: 81, ADC1 Data 22 */ +#define PIC32MZ_IRQ_AD1DAT23 82 /* Vector: 82, ADC1 Data 23 */ +#define PIC32MZ_IRQ_AD1DAT24 83 /* Vector: 83, ADC1 Data 24 */ +#define PIC32MZ_IRQ_AD1DAT25 84 /* Vector: 84, ADC1 Data 25 */ +#define PIC32MZ_IRQ_AD1DAT26 85 /* Vector: 85, ADC1 Data 26 */ +#define PIC32MZ_IRQ_AD1DAT27 86 /* Vector: 86, ADC1 Data 27 */ +#define PIC32MZ_IRQ_AD1DAT28 87 /* Vector: 87, ADC1 Data 28 */ +#define PIC32MZ_IRQ_AD1DAT29 88 /* Vector: 88, ADC1 Data 29 */ +#define PIC32MZ_IRQ_AD1DAT30 89 /* Vector: 89, ADC1 Data 30 */ +#define PIC32MZ_IRQ_AD1DAT31 90 /* Vector: 90, ADC1 Data 31 */ +#define PIC32MZ_IRQ_AD1DAT32 91 /* Vector: 91, ADC1 Data 32 */ +#define PIC32MZ_IRQ_AD1DAT33 92 /* Vector: 92, ADC1 Data 33 */ +#define PIC32MZ_IRQ_AD1DAT34 93 /* Vector: 93, ADC1 Data 34 */ +#define PIC32MZ_IRQ_AD1DAT35 94 /* Vector: 94, ADC1 Data 35 */ +#define PIC32MZ_IRQ_AD1DAT36 95 /* Vector: 95, ADC1 Data 36 */ +#define PIC32MZ_IRQ_AD1DAT37 96 /* Vector: 96, ADC1 Data 37 */ +#define PIC32MZ_IRQ_AD1DAT38 97 /* Vector: 97, ADC1 Data 38 */ +#define PIC32MZ_IRQ_AD1DAT39 98 /* Vector: 98, ADC1 Data 39 */ +#define PIC32MZ_IRQ_AD1DAT40 99 /* Vector: 99, ADC1 Data 40 */ +#define PIC32MZ_IRQ_AD1DAT41 100 /* Vector: 100, ADC1 Data 41 */ +#define PIC32MZ_IRQ_AD1DAT42 101 /* Vector: 101, ADC1 Data 42 */ +#define PIC32MZ_IRQ_AD1DAT43 102 /* Vector: 102, ADC1 Data 43 */ +#define PIC32MZ_IRQ_AD1DAT44 103 /* Vector: 103, ADC1 Data 44 */ +#define PIC32MZ_IRQ_COREPERF 104 /* Vector: 104, Core Performance Counter Interrupt */ +#define PIC32MZ_IRQ_COREFDBG 105 /* Vector: 105, Core Fast Debug Channel Interrupt */ +#define PIC32MZ_IRQ_BUSPROT 106 /* Vector: 106, System Bus Protection Violation */ +#define PIC32MZ_IRQ_CTYPTO 107 /* Vector: 107, Crypto Engine Event */ + /* Vector: 108, Reserved */ +#define PIC32MZ_IRQ_SPI1F 109 /* Vector: 109, SPI1 Fault */ +#define PIC32MZ_IRQ_SPI1RX 110 /* Vector: 110, SPI1 Receive Done */ +#define PIC32MZ_IRQ_SPI1TX 111 /* Vector: 111, SPI1 Transfer Done */ +#define PIC32MZ_IRQ_U1E 112 /* Vector: 112, UART1 Fault */ +#define PIC32MZ_IRQ_U1RX 113 /* Vector: 113, UART1 Receive Done */ +#define PIC32MZ_IRQ_U1TX 114 /* Vector: 114, UART1 Transfer Done */ +#define PIC32MZ_IRQ_I2C1COL 115 /* Vector: 115, I2C1 Bus Collision Event */ +#define PIC32MZ_IRQ_I2C1S 116 /* Vector: 116, I2C1 Slave Event */ +#define PIC32MZ_IRQ_I2C1M 117 /* Vector: 117, I2C1 Master Event */ +#define PIC32MZ_IRQ_PORTA 118 /* Vector: 118, PORTA Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTB 119 /* Vector: 119, PORTB Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTC 120 /* Vector: 120, PORTC Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTD 121 /* Vector: 121, PORTD Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTE 122 /* Vector: 122, PORTE Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTF 123 /* Vector: 123, PORTF Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTG 124 /* Vector: 124, PORTG Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTH 125 /* Vector: 125, PORTH Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTJ 126 /* Vector: 126, PORTJ Input Change Interrupt */ +#define PIC32MZ_IRQ_PORTK 127 /* Vector: 127, PORTK Input Change Interrupt */ +#define PIC32MZ_IRQ_PMP 128 /* Vector: 128, Parallel Master Port */ +#define PIC32MZ_IRQ_PMPE 129 /* Vector: 129, Parallel Master Port Error */ +#define PIC32MZ_IRQ_CMP1 130 /* Vector: 130, Comparator 1 Interrupt */ +#define PIC32MZ_IRQ_CMP2 131 /* Vector: 131, Comparator 2 Interrupt */ +#define PIC32MZ_IRQ_USBGEN 132 /* Vector: 132, USB General Event */ +#define PIC32MZ_IRQ_USBDMA 133 /* Vector: 133, USB DMA Event */ +#define PIC32MZ_IRQ_DMA0 134 /* Vector: 134, DMA Channel 0 */ +#define PIC32MZ_IRQ_DMA1 135 /* Vector: 135, DMA Channel 1 */ +#define PIC32MZ_IRQ_DMA2 136 /* Vector: 136, DMA Channel 2 */ +#define PIC32MZ_IRQ_DMA3 137 /* Vector: 137, DMA Channel 3 */ +#define PIC32MZ_IRQ_DMA4 138 /* Vector: 138, DMA Channel 4 */ +#define PIC32MZ_IRQ_DMA5 139 /* Vector: 139, DMA Channel 5 */ +#define PIC32MZ_IRQ_DMA6 140 /* Vector: 140, DMA Channel 6 */ +#define PIC32MZ_IRQ_DMA7 141 /* Vector: 141, DMA Channel 7 */ +#define PIC32MZ_IRQ_SPI2F 142 /* Vector: 142, SPI2 Fault */ +#define PIC32MZ_IRQ_SPI2RX 143 /* Vector: 143, SPI2 Receive Done */ +#define PIC32MZ_IRQ_SPI2TX 144 /* Vector: 144, SPI2 Transfer Done */ +#define PIC32MZ_IRQ_U2E 145 /* Vector: 145, UART2 Fault */ +#define PIC32MZ_IRQ_U2RX 146 /* Vector: 146, UART2 Receive Done */ +#define PIC32MZ_IRQ_U2TX 147 /* Vector: 147, UART2 Transfer Done */ +#define PIC32MZ_IRQ_I2C2COL 148 /* Vector: 148, I2C2 Bus Collision Event */ +#define PIC32MZ_IRQ_I2C2S 149 /* Vector: 149, I2C2 Slave Event */ +#define PIC32MZ_IRQ_I2C2M 150 /* Vector: 150, I2C2 Master Event */ +#define PIC32MZ_IRQ_CAN1 151 /* Vector: 151, Control Area Network 1 */ +#define PIC32MZ_IRQ_CAN2 152 /* Vector: 152, Control Area Network 2 */ +#define PIC32MZ_IRQ_ETH 153 /* Vector: 153, Ethernet interrupt */ +#define PIC32MZ_IRQ_SPI3F 154 /* Vector: 154, SPI3 Fault */ +#define PIC32MZ_IRQ_SPI3RX 155 /* Vector: 155, SPI3 Receive Done */ +#define PIC32MZ_IRQ_SPI3TX 156 /* Vector: 156, SPI3 Transfer Done */ +#define PIC32MZ_IRQ_U3E 157 /* Vector: 157, UART3 Fault */ +#define PIC32MZ_IRQ_U3RX 158 /* Vector: 158, UART3 Receive Done */ +#define PIC32MZ_IRQ_U3TX 159 /* Vector: 159, UART3 Transfer Done */ +#define PIC32MZ_IRQ_I2C3COL 160 /* Vector: 160, I2C3 Bus Collision Event */ +#define PIC32MZ_IRQ_I2C3S 161 /* Vector: 161, I2C3 Slave Event */ +#define PIC32MZ_IRQ_I2C3M 162 /* Vector: 162, I2C3 Master Event */ +#define PIC32MZ_IRQ_SPI4F 163 /* Vector: 163, SPI4 Fault */ +#define PIC32MZ_IRQ_SPI4RX 164 /* Vector: 164, SPI4 Receive Done */ +#define PIC32MZ_IRQ_SPI4TX 165 /* Vector: 165, SPI4 Transfer Done */ +#define PIC32MZ_IRQ_RTCC 166 /* Vector: 166, Real-Time Clock and Calendar */ +#define PIC32MZ_IRQ_FCE 167 /* Vector: 167, Flash Control Event */ +#define PIC32MZ_IRQ_PMSEC 168 /* Vector: 168, Prefetch Module SEC Event */ +#define PIC32MZ_IRQ_SQI1 169 /* Vector: 169, SQI1 Event */ +#define PIC32MZ_IRQ_U4E 170 /* Vector: 170, UART4 Fault */ +#define PIC32MZ_IRQ_U4RX 171 /* Vector: 171, UART4 Receive Done */ +#define PIC32MZ_IRQ_U4TX 172 /* Vector: 172, UART4 Transfer Done */ +#define PIC32MZ_IRQ_I2C4COL 173 /* Vector: 173, I2C4 Bus Collision Event */ +#define PIC32MZ_IRQ_I2C4S 174 /* Vector: 174, I2C4 Slave Event */ +#define PIC32MZ_IRQ_I2C4M 175 /* Vector: 175, I2C4 Master Event */ +#define PIC32MZ_IRQ_SPI5F 176 /* Vector: 176, SPI5 Fault */ +#define PIC32MZ_IRQ_SPI5RX 177 /* Vector: 177, SPI5 Receive Done */ +#define PIC32MZ_IRQ_SPI5TX 178 /* Vector: 178, SPI5 Transfer Done */ +#define PIC32MZ_IRQ_U5E 179 /* Vector: 179, UART5 Fault */ +#define PIC32MZ_IRQ_U5RX 180 /* Vector: 180, UART5 Receive Done */ +#define PIC32MZ_IRQ_U5TX 181 /* Vector: 181, UART5 Transfer Done */ +#define PIC32MZ_IRQ_I2C5COL 182 /* Vector: 182, I2C5 Bus Collision Event */ +#define PIC32MZ_IRQ_I2C5S 183 /* Vector: 183, I2C5 Slave Event */ +#define PIC32MZ_IRQ_I2C5M 184 /* Vector: 184, I2C5 Master Event */ +#define PIC32MZ_IRQ_SPI6F 185 /* Vector: 185, SPI6 Fault */ +#define PIC32MZ_IRQ_SPI6RX 186 /* Vector: 186, SPI6 Receive Done */ +#define PIC32MZ_IRQ_SPI6TX 187 /* Vector: 187, SPI6 Transfer Done */ +#define PIC32MZ_IRQ_U6E 188 /* Vector: 188, UART6 Fault */ +#define PIC32MZ_IRQ_U6RX 189 /* Vector: 189, UART6 Receive Done */ +#define PIC32MZ_IRQ_U6TX 190 /* Vector: 190, UART6 Transfer Done */ + +#define PIC32MZ_IRQ_BAD 191 /* Not a real IRQ number */ +#define NR_IRQS 191 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_INCLUDE_PIC32MZ_IRQ_PIC32MZXXXEC_H */ + diff --git a/arch/mips/include/syscall.h b/arch/mips/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..b4f9a7b95a4f61a1962b6f74acd97d02ecab67b6 --- /dev/null +++ b/arch/mips/include/syscall.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/mips/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_SYSCALL_H +#define __ARCH_MIPS_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include ARM architecture-specific syscall macros */ + +#ifdef CONFIG_ARCH_MIPS32 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_MIPS_INCLUDE_SYSCALL_H */ + diff --git a/arch/mips/include/types.h b/arch/mips/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..26ee3434ef5bde7874e9d9a11399dcc90a3db531 --- /dev/null +++ b/arch/mips/include/types.h @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/mips/include/types.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_MIPS_INCLUDE_TYPES_H +#define __ARCH_MIPS_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_MIPS_INCLUDE_TYPES_H */ diff --git a/arch/mips/src/.gitignore b/arch/mips/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8d209f76a44efca7364cb9ee0735d799d36f432f --- /dev/null +++ b/arch/mips/src/.gitignore @@ -0,0 +1,4 @@ +/.depend +/Make.dep +/board +/chip diff --git a/arch/mips/src/Makefile b/arch/mips/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a746fd22301dac1cef8517d9766a25a28c4eb8f7 --- /dev/null +++ b/arch/mips/src/Makefile @@ -0,0 +1,182 @@ +############################################################################ +# arch/mips/src/Makefile +# +# Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +ifeq ($(CONFIG_ARCH_MIPS),y) +ARCH_SUBDIR = mips32 +endif + +CPPFLAGS += $(EXTRADEFINES) +CFLAGS += $(EXTRADEFINES) +CXXFLAGS += $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = $(TOPDIR)\nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)\chip + CFLAGS += -I$(ARCH_SRCDIR)\common + CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)\sched +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = $(TOPDIR)/nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)/chip + CFLAGS += -I$(ARCH_SRCDIR)/common + CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)/sched +endif +endif + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +VPATH = chip:common:$(ARCH_SUBDIR) + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + @echo "LD: nuttx" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_OBJ) $(EXTRA_OBJS) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX)$(EXEEXT) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/mips/src/common/Kconfig b/arch/mips/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..47e1378225f7394bfc119edde878176277cc617d --- /dev/null +++ b/arch/mips/src/common/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_MIPS +endif diff --git a/arch/mips/src/common/up_allocateheap.c b/arch/mips/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..7bcb04de7389440c0031e50f1f0151f84bc72c58 --- /dev/null +++ b/arch/mips/src/common/up_allocateheap.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/mips/src/common/up_allocateheap.c + * + * Copyright (C) 2010, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} diff --git a/arch/mips/src/common/up_arch.h b/arch/mips/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..8b1ee01e81b26ae2479b63b24184a0dbe5d60cc9 --- /dev/null +++ b/arch/mips/src/common/up_arch.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/mips/src/common/up_arch.h + * + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_MIPS_SRC_COMMON_UP_ARCH_H +#define ___ARCH_MIPS_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(a) (*(volatile uint8_t *)(a)) +# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +# define getreg16(a) (*(volatile uint16_t *)(a)) +# define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +# define getreg32(a) (*(volatile uint32_t *)(a)) +# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Atomic modification of registers */ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* ___ARCH_MIPS_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/mips/src/common/up_createstack.c b/arch/mips/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..5540b8bc4f8fde821587e2e4d1d15a8545c0f9b1 --- /dev/null +++ b/arch/mips/src/common/up_createstack.c @@ -0,0 +1,214 @@ +/**************************************************************************** + * arch/mips/src/common/up_createstack.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* MIPS requires at least a 4-byte stack alignment. For floating point use, + * however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* MIPS uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The MIPS stack must be aligned at word (4 byte) boundaries; for + * floating point use, the stack must be aligned to 8-byte addresses. + * If necessary top_of_stack must be rounded down to the next + * boundary to meet these alignment requirements. + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/mips/src/common/up_etherstub.c b/arch/mips/src/common/up_etherstub.c new file mode 100644 index 0000000000000000000000000000000000000000..7a42d703e70edd686b95ee494859f2f8d106686f --- /dev/null +++ b/arch/mips/src/common/up_etherstub.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/mips/src/common/up_etherstub.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_netinitialize (stub) + * + * Description: + * This is a stub version os up_netinitialize. Normally, up_netinitialize + * is defined in board/xyz_network.c for board-specific Ethernet + * implementations, or chip/xyx_ethernet.c for chip-specific Ethernet + * implementations. The stub version here is used in the corner case where + * the network is enable yet there is no Ethernet driver to be initialized. + * In this case, up_initialize will still try to call up_netinitialize() + * when one does not exist. This corner case would occur if, for example, + * only a USB network interface is being used or perhaps if a SLIP is + * being used). + * + * Use of this stub is deprecated. The preferred mechanism is to use + * CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in + * up_initialize(). Then this stub would not be needed. + * + ****************************************************************************/ + +void up_netinitialize(void) +{ +} diff --git a/arch/mips/src/common/up_exit.c b/arch/mips/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..36a1d2b1704dafae3e1cc0d12bf9b07382d3795e --- /dev/null +++ b/arch/mips/src/common/up_exit.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * arch/mips/src/common/up_exit.c + * + * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s *tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); + + /* up_fullcontextrestore() should not return but could if the software + * interrupts are disabled. + */ + + PANIC(); +} + diff --git a/arch/mips/src/common/up_idle.c b/arch/mips/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..bee134392f85ca6953786c5766daddd268bf86c3 --- /dev/null +++ b/arch/mips/src/common/up_idle.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/mips/src/common/up_idle.c + * + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + /* This is a kludge that I still don't understand. The call to kmm_trysemaphore() + * in the os_start.c IDLE loop seems necessary for the good health of the IDLE + * loop. When the work queue is enabled, this logic is removed from the IDLE + * loop and it appears that we are somehow left idling with interrupts non- + * functional. The following should be no-op, it just disables then re-enables + * interrupts. But it fixes the problem and will stay here until I understand + * the problem/fix better. + * + * And no, the contents of the CP0 status register are not incorrect. But for + * some reason the status register needs to be re-written again on this thread + * for it to take effect. This might be a PIC32-only issue? + */ + +#ifdef CONFIG_SCHED_WORKQUEUE + irqstate_t flags = enter_critical_section(); + leave_critical_section(flags); +#endif +#endif +} diff --git a/arch/mips/src/common/up_initialize.c b/arch/mips/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..b7df229f2f04c9a6c52b3a38a6a1c8f8541fc5ca --- /dev/null +++ b/arch/mips/src/common/up_initialize.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * arch/mips/src/common/up_initialize.c + * + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Add any extra memory fragments to the memory manager */ + + up_addregion(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been + * brought into the build + */ + +#ifdef CONFIG_ARCH_DMA +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_dmainitialize) +#endif + { + up_dmainitialize(); + } +#endif + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB -- device and/or host */ + + up_usbinitialize(); + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/mips/src/common/up_internal.h b/arch/mips/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..3b2ca4ccbc396da08c566563de56c1d908ad24e7 --- /dev/null +++ b/arch/mips/src/common/up_internal.h @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/mips/common/up_internal.h + * + * Copyright (C) 2011, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_COMMON_UP_INTERNAL_H +#define __ARCH_MIPS_SRC_COMMON_UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/* In the MIPS model, the state is copied from the stack to the TCB, but + * only a referenced is passed to get the state from the TCB. + */ + +#define up_savestate(regs) up_copystate(regs, (uint32_t*)g_current_regs) +#define up_restorestate(regs) (g_current_regs = regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +extern volatile uint32_t *g_current_regs; + +/* This is the beginning of heap as provided from up_head.S. This is the + * first address in DRAM after the loaded program+bss+idle stack. The end + * of the heap is CONFIG_RAM_END + */ + +extern uint32_t g_idle_topstack; + +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +extern void g_intstackbase; +#endif + +/* These 'addresses' of these values are setup by the linker script. They are + * not actual uint32_t storage locations! They are only used meaningfully in the + * following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declaration extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data (it is + * not!). + * - We can recoved the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +extern uint32_t _stext; /* Start of .text */ +extern uint32_t _etext; /* End+1 of .text + .rodata */ +extern const uint32_t _data_loaddr; /* Start of .data in FLASH */ +extern uint32_t _sdata; /* Start of .data */ +extern uint32_t _edata; /* End+1 of .data */ +extern uint32_t _sbss; /* Start of .bss */ +extern uint32_t _ebss; /* End+1 of .bss */ +#ifdef CONFIG_ARCH_RAMFUNCS +extern uint32_t _sramfunc; /* Start of ramfuncs */ +extern uint32_t _eramfunc; /* End+1 of ramfuncs */ +extern uint32_t _ramfunc_loadaddr; /* Start of ramfuncs in FLASH */ +extern uint32_t _ramfunc_sizeof; /* Size of ramfuncs */ +extern uint32_t _bmxdkpba_address; /* BMX register setting */ +extern uint32_t _bmxdudba_address; /* BMX register setting */ +extern uint32_t _bmxdupba_address; /* BMX register setting */ +#endif /* CONFIG_ARCH_RAMFUNCS */ +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* Common Functions *********************************************************/ +/* Common functions define in arch/mips/src/common. These may be replaced + * with chip-specific functions of the same name if needed. See also + * functions prototyped in include/nuttx/arch.h. + */ + +/* Context switching */ + +void up_copystate(uint32_t *dest, uint32_t *src); + +/* Serial output */ + +void up_puts(const char *str); +void up_lowputs(const char *str); + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* Debug */ + +#ifdef CONFIG_ARCH_STACKDUMP +void up_dumpstate(void); +#else +# define up_dumpstate() +#endif + +/* Common MIPS32 functions defined in arch/mips/src/MIPS32 */ +/* IRQs */ + +uint32_t *up_doirq(int irq, uint32_t *regs); + +/* Software interrupt 0 handler */ + +int up_swint0(int irq, FAR void *context); + +/* Signals */ + +void up_sigdeliver(void); + +/* Chip-specific functions **************************************************/ +/* Chip specific functions defined in arch/mips/src/ */ +/* IRQs */ + +void up_irqinitialize(void); +bool up_pending_irq(int irq); +void up_clrpend_irq(int irq); + +/* DMA */ + +#ifdef CONFIG_ARCH_DMA +void weak_function up_dmainitialize(void); +#endif + +/* Memory management */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#else +# define up_addregion() +#endif + +/* Serial output */ + +void up_lowputc(char ch); +#if CONFIG_NFILE_DESCRIPTORS > 0 +void up_earlyserialinit(void); +void up_serialinit(void); +#else +# define up_earlyserialinit() +# define up_serialinit() +#endif + +/* System timer */ + +void up_timer_initialize(void); + +/* Network */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +/* USB */ + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/mips/src/common/up_interruptcontext.c b/arch/mips/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..837238ec30d36be1192c2cecb7a68289119f3177 --- /dev/null +++ b/arch/mips/src/common/up_interruptcontext.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/mips/src/common/up_interruptcontext.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/mips/src/common/up_lowputs.c b/arch/mips/src/common/up_lowputs.c new file mode 100644 index 0000000000000000000000000000000000000000..396edeb1bd4601f7af525408b16acabff6409453 --- /dev/null +++ b/arch/mips/src/common/up_lowputs.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/mips/src/common/up_lowputs.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} diff --git a/arch/mips/src/common/up_mdelay.c b/arch/mips/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..d2cb5d05b38bde2cfef80bc04b3b31666bdb357c --- /dev/null +++ b/arch/mips/src/common/up_mdelay.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/mips/src/common/up_mdelay.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/mips/src/common/up_modifyreg16.c b/arch/mips/src/common/up_modifyreg16.c new file mode 100644 index 0000000000000000000000000000000000000000..6dfe1c2a49f0eee46e51eceba54907a383d31995 --- /dev/null +++ b/arch/mips/src/common/up_modifyreg16.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/mips/src/common/up_modifyreg16.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16(addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/mips/src/common/up_modifyreg32.c b/arch/mips/src/common/up_modifyreg32.c new file mode 100644 index 0000000000000000000000000000000000000000..af680343dfdaacf3a81f4981a3045f0db10a87fb --- /dev/null +++ b/arch/mips/src/common/up_modifyreg32.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/mips/src/common/up_modifyreg32.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32(addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/mips/src/common/up_modifyreg8.c b/arch/mips/src/common/up_modifyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..7f63a580b80bcd3b4b78835cef9bc16fd4549b24 --- /dev/null +++ b/arch/mips/src/common/up_modifyreg8.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/mips/src/common/up_modifyreg8.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8(addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/mips/src/common/up_puts.c b/arch/mips/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..1b9f31f84e315f40af15166424c02353d2bf5252 --- /dev/null +++ b/arch/mips/src/common/up_puts.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/mips/src/common/up_puts.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} diff --git a/arch/mips/src/common/up_releasestack.c b/arch/mips/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..a322f4c24c8dddfa34b8aed60bbb43794546011e --- /dev/null +++ b/arch/mips/src/common/up_releasestack.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/mips/src/common/up_releasestack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/mips/src/common/up_stackframe.c b/arch/mips/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..6c631f3e1fc383b8b45b93baa1941d36a92e5fe1 --- /dev/null +++ b/arch/mips/src/common/up_stackframe.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/mips/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ +/* MIPS requires at least a 4-byte stack alignment. For floating point use, + * however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/mips/src/common/up_udelay.c b/arch/mips/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..496811cd7981c60d49757f3741599b1a375ccd86 --- /dev/null +++ b/arch/mips/src/common/up_udelay.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/mips/src/common/up_udelay.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} diff --git a/arch/mips/src/common/up_usestack.c b/arch/mips/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..b4e3098fc47af5dcd9cba7649d1746352dc0b87a --- /dev/null +++ b/arch/mips/src/common/up_usestack.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/mips/src/common/up_usestack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MIPS requires at least a 4-byte stack alignment. For floating point use, + * however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* MIPS uses a push-down stack: the stack grows toward loweraddresses in + * memory. The stack pointer register, points to the lowest, valid work + * address (the "top" of the stack). Items on the stack are referenced + * as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The MIPS stack must be aligned at word (4 byte) or double word (8 byte) + * boundaries. If necessary top_of_stack must be rounded down to the + * next boundary + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} diff --git a/arch/mips/src/mips32/Kconfig b/arch/mips/src/mips32/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..228c28557f4b78eb970ab0da071940fff0fdac3c --- /dev/null +++ b/arch/mips/src/mips32/Kconfig @@ -0,0 +1,76 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_MIPS32 +comment "MIPS32 Configuration Options" + +choice + prompt "Toolchain Selection" + default MIPS32_TOOLCHAIN_MICROCHIPW_LITE if HOST_WINDOWS + default MIPS32_TOOLCHAIN_GNU_ELF if !HOST_WINDOWS + +config MIPS32_TOOLCHAIN_GNU_ELF + bool "Generic GNU ELF toolchain" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for mips32-elf. + +config MIPS32_TOOLCHAIN_MICROCHIPL_XC32 + bool "Microchip XC32 toolchain under Linux" + depends on HOST_LINUX + +config MIPS32_TOOLCHAIN_MICROCHIPL + bool "Microchip C32 toolchain under Linux" + depends on HOST_LINUX + +config MIPS32_TOOLCHAIN_MICROCHIPL_LITE + bool "Microchip C32 toolchain under Linux (Lite edition)" + depends on HOST_LINUX + +config MIPS32_TOOLCHAIN_MICROCHIPW_XC32 + bool "Microchip XC32 toolchain under Windows" + depends on HOST_WINDOWS + +config MIPS32_TOOLCHAIN_MICROCHIPW + bool "Microchip C32 toolchain under Windows" + depends on HOST_WINDOWS + +config MIPS32_TOOLCHAIN_MICROCHIPW_LITE + bool "Microchip C32 toolchain under Windows (Lite edition)" + depends on HOST_WINDOWS + +config MIPS32_TOOLCHAIN_MICROCHIPOPENL + bool "microchipOpen toolchain under Linux" + depends on HOST_LINUX + +config MIPS32_TOOLCHAIN_PINGUINOW + bool "Pinguino mips-elf toolchain under Windows" + depends on HOST_WINDOWS + +config MIPS32_TOOLCHAIN_PINGUINOL + bool "Pinguino mips-elf toolchain under OS X or Linux" + depends on HOST_LINUX || HOST_OSX + +endchoice + +config MIPS32_TOOLCHAIN_MICROCHIP_XC32_LICENSED + bool "Licensed Microchip XC32 toolchain" + default n + depends on MIPS32_TOOLCHAIN_MICROCHIPL_XC32 || MIPS32_TOOLCHAIN_MICROCHIPW_XC32 + ---help--- + The free, unlicensed XC32 compiler will not support either + optimization or the microMIPs ISA. If you are using a licensed, + XC32 compiler then select this option so that the build system will + suppport higher levels of optimization. + +config MIPS32_FRAMEPOINTER + bool "ABI Uses Frame Pointer" + default n + depends on ARCH_HAVE_VFORK + ---help--- + Register r30 may be a frame pointer in some ABIs. Or may just be + saved register s8. It makes a difference for vfork handling. + +endif diff --git a/arch/mips/src/mips32/Toolchain.defs b/arch/mips/src/mips32/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..cee45311d8e89750024e85b947b3621f44379d5e --- /dev/null +++ b/arch/mips/src/mips32/Toolchain.defs @@ -0,0 +1,254 @@ +############################################################################ +# arch/mips/src/mips32/Toolchain.defs +# +# Copyright (C) 2012-2013, 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Handle old-style chip-specific toolchain names in the absence of +# a new-style toolchain specification, force the selection of a single +# toolchain and allow the selected toolchain to be overridden by a +# command-line selection. +# + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_PINGUINOL) \ + $(CONFIG_MIPS32_TOOLCHAIN_GNU_ELF) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= GNU_ELF +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPL_XC32 +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPL +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_LITE) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPL_LITE +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPW_XC32) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPW_XC32 +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPW) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPW +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPW_LITE) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPW_LITE +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPOPENL) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= MICROCHIPOPENL +endif + +ifeq ($(filter y, \ + $(CONFIG_MIPS32_TOOLCHAIN_PINGUINOW) \ + ),y) + CONFIG_MIPS32_TOOLCHAIN ?= PINGUINOW +endif + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# Pick correct MIPS architecture selection + +ifeq ($(CONFIG_ARCH_MIPS_M14K),y) + MIPS_MARCH = m14k + MIPS_MPROCESSOR = elf32pic32mz +else + MIPS_MARCH = 24kc + MIPS_MPROCESSOR = elf32pic32mx +endif + +# Handle builds for the microMIPS ISA. Interlinking may be +# necessary to integrate with MIPS32 ISA libraries. + +ifeq ($(CONFIG_MIPS_MICROMIPS),y) +# MIPS_MICROMIPS = -mmicromips +# MIPS_MICROMIPS = -mmicromips -minterlink-mips16 -mno-jals + MIPS_MICROMIPS = -mmicromips -minterlink-compressed +else + MIPS_MICROMIPS = +endif + +# Generic GNU mip32 toolchain on OS X or Linux +# including Pinguino mips-elf toolchain + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),GNU_ELF) + CROSSDEV ?= mips-elf- + MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mlong32 -membedded-data -msoft-float -march=$(MIPS_MARCH) $(MIPS_MICROMIPS) -EL + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = mips-elf-debug.ld +endif + +# Microchip XC32 toolchain under Linux + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPL_XC32) + CROSSDEV ?= xc32- +ifeq ($(CONFIG_MIPS32_TOOLCHAIN_MICROCHIP_XC32_LICENSED),y) + MAXOPTIMIZATION ?= -O2 +endif + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) -march=$(MIPS_MARCH) -EL $(MIPS_MICROMIPS) -msmart-io=0 + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = xc32-debug.ld +endif + +# Microchip C32 toolchain under Linux + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPL) + CROSSDEV ?= pic32- + # CROSSDEV ?= xc32- + MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) $(MIPS_MICROMIPS) -mno-float -mlong32 -membedded-data + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = xc32-debug.ld +endif + +# Microchip XC32 toolchain under Windows + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPW_XC32) + CROSSDEV ?= xc32- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +ifeq ($(CONFIG_MIPS32_TOOLCHAIN_MICROCHIP_XC32_LICENSED),y) + MAXOPTIMIZATION ?= -O2 +endif + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) -march=$(MIPS_MARCH) -EL $(MIPS_MICROMIPS) -msmart-io=0 + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = xc32-debug.ld +endif + +# Microchip C32 toolchain under Windows + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPW) + CROSSDEV ?= pic32- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) $(MIPS_MICROMIPS) -mno-float -mlong32 -membedded-data + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = c32-debug.ld +endif + +# Microchip C32 toolchain under Linux + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPL_LITE) + CROSSDEV ?= pic32- + # MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) $(MIPS_MICROMIPS) -mno-float -mlong32 -membedded-data + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = xc32-debug.ld +endif + +# Microchip C32 toolchain under Windows + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPW_LITE) + CROSSDEV ?= pic32- + # CROSSDEV ?= xc32- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + # MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) $(MIPS_MICROMIPS) -mno-float -mlong32 -membedded-data + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = c32-debug.ld +endif + +# microchipOpen toolchain under Linux + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),MICROCHIPOPENL) + CROSSDEV ?= mypic32- + # MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mprocessor=$(MIPS_MPROCESSOR) $(MIPS_MICROMIPS) -mno-float -mlong32 -membedded-data + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = c32-debug.ld +endif + +# Pinguino mips-elf toolchain under Windows + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN),PINGUINOW) + #CROSSDEV ?= mips- + CROSSDEV ?= p32- + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif + MAXOPTIMIZATION ?= -O2 + ARCHCPUFLAGS = -mlong32 -membedded-data -msoft-float -march=$(MIPS_MARCH) $(MIPS_MICROMIPS) -EL + ARCHPICFLAGS = -fpic -membedded-pic + LDFLAGS += -nostartfiles -nodefaultlibs + LDSCRIPT = mips-elf-debug.ld +endif diff --git a/arch/mips/src/mips32/mips32-memorymap.h b/arch/mips/src/mips32/mips32-memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..103ca6e2be6bfb58871a7194332770b3f689f976 --- /dev/null +++ b/arch/mips/src/mips32/mips32-memorymap.h @@ -0,0 +1,97 @@ +/******************************************************************************************** + * arch/mips/src/mips32/mips32-memorymap.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_MIPS32_MIPS32_MEMORYMAP_H +#define __ARCH_MIPS_SRC_MIPS32_MIPS32_MEMORYMAP_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/* MIPS32 address space organization */ + +#define USEG_BASE 0x00000000 +#define USEG_SIZE 0x80000000 + +#define KSEG0_BASE 0x80000000 +#define KSEG0_SIZE 0x20000000 + +#define KSEG1_BASE 0xa0000000 +#define KSEG1_SIZE 0x20000000 + +#define KSEG2_BASE 0xc0000000 +#define KSEG2_SIZE 0x20000000 + +#define KSEG3_BASE 0xe0000000 +#define KSEG3_SIZE 0x20000000 + +#define DSEG_BASE 0xff200000 +#define DSEG_SIZE 0x00200000 + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_MIPS32_MIPS32_MEMORYMAP_H */ diff --git a/arch/mips/src/mips32/up_assert.c b/arch/mips/src/mips32/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..8b4ae3e50aba8d7164bc42bd96ee7f1fa44166ad --- /dev/null +++ b/arch/mips/src/mips32/up_assert.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_assert.c + * + * Copyright (C) 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/mips/src/mips32/up_blocktask.c b/arch/mips/src/mips32/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..1ad66ce9db6ef2b3eb266560e84c4b37d6c44604 --- /dev/null +++ b/arch/mips/src/mips32/up_blocktask.c @@ -0,0 +1,179 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_blocktask.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Get the context of the task at the head of the ready to + * run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/mips/src/mips32/up_copystate.c b/arch/mips/src/mips32/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..17ec401a47dfa02547d8b00f559521b33951167c --- /dev/null +++ b/arch/mips/src/mips32/up_copystate.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_copystate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the MIPS model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + diff --git a/arch/mips/src/mips32/up_doirq.c b/arch/mips/src/mips32/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..61599eb99e098aa89b87c95621419457066cce38 --- /dev/null +++ b/arch/mips/src/mips32/up_doirq.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_doirq.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Disable further occurrences of this interrupt (until the interrupt sources + * have been clear by the driver). + */ + + up_disable_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + + /* Unmask the last interrupt (global interrupts are still disabled) */ + + up_enable_irq(irq); +#endif + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/mips/src/mips32/up_dumpstate.c b/arch/mips/src/mips32/up_dumpstate.c new file mode 100644 index 0000000000000000000000000000000000000000..b56d7f2419b298e5a117b8b0cc3d6f713c4a5139 --- /dev/null +++ b/arch/mips/src/mips32/up_dumpstate.c @@ -0,0 +1,241 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_dumpstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +/* I don't know if the builtin to get SP is enabled */ + +static inline uint32_t up_getsp(void) +{ + register uint32_t sp; + __asm__ + ( + "\tadd %0, $0, $29\n" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static inline void up_registerdump(void) +{ + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + lldbg("MFLO:%08x MFHI:%08x EPC:%08x STATUS:%08x\n", + g_current_regs[REG_MFLO], g_current_regs[REG_MFHI], g_current_regs[REG_EPC], + g_current_regs[REG_STATUS]); + lldbg("AT:%08x V0:%08x V1:%08x A0:%08x A1:%08x A2:%08x A3:%08x\n", + g_current_regs[REG_AT], g_current_regs[REG_V0], g_current_regs[REG_V1], + g_current_regs[REG_A0], g_current_regs[REG_A1], g_current_regs[REG_A2], + g_current_regs[REG_A3]); + lldbg("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x T7:%08x\n", + g_current_regs[REG_T0], g_current_regs[REG_T1], g_current_regs[REG_T2], + g_current_regs[REG_T3], g_current_regs[REG_T4], g_current_regs[REG_T5], + g_current_regs[REG_T6], g_current_regs[REG_T7]); + lldbg("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + g_current_regs[REG_S0], g_current_regs[REG_S1], g_current_regs[REG_S2], + g_current_regs[REG_S3], g_current_regs[REG_S4], g_current_regs[REG_S5], + g_current_regs[REG_S6], g_current_regs[REG_S7]); +#ifdef MIPS32_SAVE_GP + lldbg("T8:%08x T9:%08x GP:%08x SP:%08x FP:%08x RA:%08x\n", + g_current_regs[REG_T8], g_current_regs[REG_T9], g_current_regs[REG_GP], + g_current_regs[REG_SP], g_current_regs[REG_FP], g_current_regs[REG_RA]); +#else + lldbg("T8:%08x T9:%08x SP:%08x FP:%08x RA:%08x\n", + g_current_regs[REG_T8], g_current_regs[REG_T9], g_current_regs[REG_SP], + g_current_regs[REG_FP], g_current_regs[REG_RA]); +#endif + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("sp: %08x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + up_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + up_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/mips/src/mips32/up_initialstate.c b/arch/mips/src/mips32/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..7a9b629fbdaa574a544db5b3e6c09a2d4081f41c --- /dev/null +++ b/arch/mips/src/mips32/up_initialstate.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_initialstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + uint32_t regval; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer. Hmmm.. the stack is set to the very + * beginning of the stack region. Some functions may want to store data on + * the caller's stack and it might be good to reserve some space. However, + * only the start function would do that and we have control over that one + */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_EPC] = (uint32_t)tcb->start; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC +# warning "Missing logic" +#endif + + /* Set privileged- or unprivileged-mode, depending on how NuttX is + * configured and what kind of thread is being started. + * + * If the kernel build is not selected, then all threads run in + * privileged thread mode. + */ + +#ifdef CONFIG_BUILD_KERNEL +# warning "Missing logic" +#endif + + /* Set the initial value of the status register. It will be the same + * as the current status register with some changes: + * + * 1. Make sure the IE is set + * 2. Clear the BEV bit (This bit should already be clear) + * 3. Clear the UM bit so that the new task executes in kernel mode + * (This bit should already be clear) + * 4. Set the interrupt mask bits (depending on configuration) + * 5. Set the EXL bit (This will not be set) + * + * The EXL bit is set because this new STATUS register will be + * instantiated in kernel mode inside of an interrupt handler. EXL + * will be automatically cleared by the eret instruction. + */ + + regval = cp0_getstatus(); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + regval &= ~(CP0_STATUS_IM_ALL | CP0_STATUS_BEV | CP0_STATUS_UM); + regval |= (CP0_STATUS_IE | CP0_STATUS_EXL | CP0_STATUS_IM_SWINTS); +#else + regval &= ~(CP0_STATUS_BEV | CP0_STATUS_UM); + regval |= (CP0_STATUS_IE | CP0_STATUS_EXL | CP0_STATUS_IM_ALL); +#endif + xcp->regs[REG_STATUS] = regval; +} + diff --git a/arch/mips/src/mips32/up_irq.c b/arch/mips/src/mips32/up_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..47ae02084d9886dee030111bef561e7fb9c960e1 --- /dev/null +++ b/arch/mips/src/mips32/up_irq.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_irq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Save the current interrupt state and disable interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * Interrupt state prior to disabling interrupts. + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) +{ + register irqstate_t status; + register irqstate_t ret; + + status = cp0_getstatus(); /* Get CP0 status */ + ret = status; /* Save the status */ + status &= ~CP0_STATUS_IM_MASK; /* Clear all interrupt mask bits */ + status |= CP0_STATUS_IM_SWINTS; /* Keep S/W interrupts enabled */ + cp0_putstatus(status); /* Disable interrupts */ + return ret; /* Return status before interrupts disabled */ +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore the previous interrutp state (i.e., the one previously returned + * by up_irq_save()) + * + * Input Parameters: + * state - The interrupt state to be restored. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t irqstate) +{ + register irqstate_t status; + + status = cp0_getstatus(); /* Get CP0 status */ + status &= ~CP0_STATUS_IM_MASK; /* Clear all interrupt mask bits */ + irqstate &= CP0_STATUS_IM_MASK; /* Retain interrupt mask bits only */ + status |= irqstate; /* Set new interrupt mask bits */ + status |= CP0_STATUS_IM_SWINTS; /* Make sure that S/W interrupts enabled */ + cp0_putstatus(status); /* Restore interrupt state */ +} diff --git a/arch/mips/src/mips32/up_releasepending.c b/arch/mips/src/mips32/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..0d4522ba8d8896c4ca9d7304b5074cf1063fa25e --- /dev/null +++ b/arch/mips/src/mips32/up_releasepending.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_releasepending.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/mips/src/mips32/up_reprioritizertr.c b/arch/mips/src/mips32/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..3365f8862e23d529c580e296abfe3b74c5b87429 --- /dev/null +++ b/arch/mips/src/mips32/up_reprioritizertr.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_reprioritizertr.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/mips/src/mips32/up_schedulesigaction.c b/arch/mips/src/mips32/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..1c8612ffd9396f65996b06d3c750d395dfc12bf6 --- /dev/null +++ b/arch/mips/src/mips32/up_schedulesigaction.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_schedulesigaction.c + * + * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + uint32_t status; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following + * logic would fail in the strange case where we are in an + * interrupt handler, the thread is signalling itself, but + * a context switch to another task has occurred so that + * g_current_regs does not refer to the thread of this_task()! + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = g_current_regs[REG_EPC]; + tcb->xcp.saved_status = g_current_regs[REG_STATUS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_EPC] = (uint32_t)up_sigdeliver; + status = g_current_regs[REG_STATUS]; + status &= ~CP0_STATUS_IM_MASK; + status |= CP0_STATUS_IM_SWINTS; + g_current_regs[REG_STATUS] = status; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + + svdbg("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_status, + g_current_regs[REG_EPC], g_current_regs[REG_STATUS]); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return EPC and STATUS registers. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC]; + tcb->xcp.saved_status = tcb->xcp.regs[REG_STATUS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_EPC] = (uint32_t)up_sigdeliver; + status = tcb->xcp.regs[REG_STATUS]; + status &= ~CP0_STATUS_IM_MASK; + status |= CP0_STATUS_IM_SWINTS; + tcb->xcp.regs[REG_STATUS] = status; + + svdbg("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n", + tcb->xcp.saved_epc, tcb->xcp.saved_status, + tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_STATUS]); + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/mips/src/mips32/up_sigdeliver.c b/arch/mips/src/mips32/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..a841a941b812b54fd562a541c20d124e1248f868 --- /dev/null +++ b/arch/mips/src/mips32/up_sigdeliver.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_sigdeliver.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_EPC] = rtcb->xcp.saved_epc; + regs[REG_STATUS] = rtcb->xcp.saved_status; + + /* Get a local copy of the sigdeliver function pointer. We do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore((irqstate_t)regs[REG_STATUS]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + svdbg("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]); + + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); + + /* up_fullcontextrestore() should not return but could if the software + * interrupts are disabled. + */ + + PANIC(); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/mips/src/mips32/up_swint0.c b/arch/mips/src/mips32/up_swint0.c new file mode 100644 index 0000000000000000000000000000000000000000..1d335b179241a209162fd9d5f65c2146c223067c --- /dev/null +++ b/arch/mips/src/mips32/up_swint0.c @@ -0,0 +1,329 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_swint0.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Debug ********************************************************************/ +/* Debug output from this file may interfere with context switching! To get + * debug output you must enabled the following in your NuttX configuration: + * + * CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL + */ + +#ifdef CONFIG_DEBUG_SYSCALL +# define swidbg(format, ...) lldbg(format, ##__VA_ARGS__) +#else +# define swidbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SYSCALL +static void up_registerdump(const uint32_t *regs) +{ + swidbg("MFLO:%08x MFHI:%08x EPC:%08x STATUS:%08x\n", + regs[REG_MFLO], regs[REG_MFHI], regs[REG_EPC], regs[REG_STATUS]); + swidbg("AT:%08x V0:%08x V1:%08x A0:%08x A1:%08x A2:%08x A3:%08x\n", + regs[REG_AT], regs[REG_V0], regs[REG_V1], regs[REG_A0], + regs[REG_A1], regs[REG_A2], regs[REG_A3]); + swidbg("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x T7:%08x\n", + regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], + regs[REG_T4], regs[REG_T5], regs[REG_T6], regs[REG_T7]); + swidbg("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], + regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); +#ifdef MIPS32_SAVE_GP + swidbg("T8:%08x T9:%08x GP:%08x SP:%08x FP:%08x RA:%08x\n", + regs[REG_T8], regs[REG_T9], regs[REG_GP], regs[REG_SP], + regs[REG_FP], regs[REG_RA]); +#else + swidbg("T8:%08x T9:%08x SP:%08x FP:%08x RA:%08x\n", + regs[REG_T8], regs[REG_T9], regs[REG_SP], regs[REG_FP], + regs[REG_RA]); +#endif +} +#else +# define up_registerdump(regs) +#endif + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ +# error "Missing logic" + +/* Refer to arch/arm/src/armv7-m/up_svcall.h for how this is done for ARM */ +/* __asm__ __volatile__ */ +/* ( */ +/* Save registers */ +/* Get the base of the stub lookup table */ +/* Get the offset of the stub for this syscall */ +/* Load the entry of the stub for this syscall */ +/* Call the stub */ +/* Restore regsisters */ +/* Return from the syscall */ +/* ); */ +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_swint0 + * + * Description: + * This is software interrupt 0 exception handler that performs context + * switching and manages system calls + * + ****************************************************************************/ + +int up_swint0(int irq, FAR void *context) +{ + uint32_t *regs = (uint32_t *)context; + uint32_t cause; + + DEBUGASSERT(regs && regs == g_current_regs); + + /* Software interrupt 0 is invoked with REG_A0 (REG_R4) = system call + * command and REG_A1-3 and REG_T0-2 (REG_R5-10) = variable number of + * arguments depending on the system call. + */ + +#ifdef CONFIG_DEBUG_SYSCALL + swidbg("Entry: regs: %p cmd: %d\n", regs, regs[REG_R4]); + up_registerdump(regs); +#endif + + /* Handle the SWInt according to the command in $4 */ + + switch (regs[REG_R4]) + { + /* R4=SYS_restore_context: This a restore context command: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * R4 = SYS_restore_context + * R5 = restoreregs + * + * In this case, we simply need to set g_current_regs to restore register + * area referenced in the saved R1. context == g_current_regs is the normal + * exception return. By setting g_current_regs = context[R1], we force + * the return to the saved context referenced in R1. + */ + + case SYS_restore_context: + { + DEBUGASSERT(regs[REG_A1] != 0); + g_current_regs = (uint32_t *)regs[REG_A1]; + } + break; + + /* R4=SYS_switch_context: This a switch context command: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * At this point, the following values are saved in context: + * + * R4 = SYS_switch_context + * R5 = saveregs + * R6 = restoreregs + * + * In this case, we save the context registers to the save register + * area reference by the saved contents of R5 and then set + * g_current_regs to to the save register area referenced by the saved + * contents of R6. + */ + + case SYS_switch_context: + { + DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0); + up_copystate((uint32_t *)regs[REG_A1], regs); + g_current_regs = (uint32_t *)regs[REG_A2]; + } + break; + + /* R0=SYS_syscall_return: This a switch context command: + * + * void up_sycall_return(void); + * + * At this point, the following values are saved in context: + * + * R0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + +#ifdef CONFIG_BUILD_KERNEL + case SYS_syscall_return: + { + struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved syscall return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved syscall return address in + * the original mode. + */ + + g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn; +#error "Missing logic -- need to restore the original mode" + rtcb->xcp.nsyscalls = index; + } + break; +#endif + + /* This is not an architecture-specify system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_BUILD_KERNEL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall); + + /* Make sure that we got here that there is a no saved syscall + * return address. We cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC]; +#error "Missing logic -- Need to save mode" + rtcb->xcp.nsyscalls = index + 1; + + regs[REG_EPC] = (uint32_t)dispatch_syscall; +#error "Missing logic -- Need to set privileged mode" + + /* Offset R0 to account for the reserved values */ + + g_current_regs[REG_R0] -= CONFIG_SYS_RESERVED; +#else + slldbg("ERROR: Bad SYS call: %d\n", regs[REG_A0]); +#endif + } + break; + } + + /* Report what happened. That might difficult in the case of a context switch */ + +#ifdef CONFIG_DEBUG_SYSCALL + if (regs != g_current_regs) + { + swidbg("SWInt Return: Context switch!\n"); + up_registerdump((const uint32_t *)g_current_regs); + } + else + { + swidbg("SWInt Return: %d\n", regs[REG_V0]); + } +#endif + + /* Clear the pending software interrupt 0 in the PIC32 interrupt block. + * REVISIT: Does this PIC32 logic really have to be in the MIPS32 code? + */ + +#if defined(CONFIG_ARCH_CHIP_PIC32MX) + up_clrpend_irq(PIC32MX_IRQSRC_CS0); +#elif defined(CONFIG_ARCH_CHIP_PIC32MZ) + up_clrpend_irq(PIC32MZ_IRQ_CS0); +#endif + + /* And reset the software interrupt bit in the MIPS CAUSE register */ + + cause = cp0_getcause(); + cause &= ~CP0_CAUSE_IP0; + cp0_putcause(cause); + + return OK; +} diff --git a/arch/mips/src/mips32/up_syscall0.S b/arch/mips/src/mips32/up_syscall0.S new file mode 100644 index 0000000000000000000000000000000000000000..35fa3639a454cac0c30a1ecf2016af696ee5db8d --- /dev/null +++ b/arch/mips/src/mips32/up_syscall0.S @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_syscall0.S + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "up_syscall0.S" + .global sys_call0 + .global sys_call1 + .global sys_call2 + .global sys_call3 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3 + * + * Description: + * up_syscall0 - System call SYS_ argument and no additional parameters. + * up_syscall1 - System call SYS_ argument and one additional parameter. + * up_syscall2 - System call SYS_ argument and two additional parameters. + * up_syscall3 - System call SYS_ argument and three additional parameters. + * + * Assumption: + * All interrupts are disabled except for the software interrupts. + * + ****************************************************************************/ + + .text + .set noreorder + .set nomips16 +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent sys_call0 + +sys_call0: /* r4 holds the syscall number */ +sys_call1: /* r4 holds the syscall number, argument in r5 */ +sys_call2: /* r4 holds the syscall number, arguments in r5 and r6 */ +sys_call3: /* r4 holds the syscall number, arguments in r5, r6, and r7 */ + + .set push + .set noat + + /* Set Bit 8 to request the software interrupt */ + + mfc0 t3, MIPS32_CP0_CAUSE /* t3 = CP0 cause register */ + ori t3, (1 << 8) /* Bit 8: Request software interrupt 0 */ + .set noreorder + mtc0 t3, MIPS32_CP0_CAUSE /* Trigger the software interrupt */ + + /* The actual interrupt will not a occur for a few more cycles. Let's + * put a few nop's here in hope that the SW interrupt occurs during + * the sequence of nops. + */ + + nop + nop + nop + nop + + /* Then return with the result of the software interrupt in v0 */ + + j ra + nop + .end sys_call0 diff --git a/arch/mips/src/mips32/up_unblocktask.c b/arch/mips/src/mips32/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..9e72ef17a6a811d2019248bce4fe03dae586cb2b --- /dev/null +++ b/arch/mips/src/mips32/up_unblocktask.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_unblocktask.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/mips/src/mips32/up_vfork.c b/arch/mips/src/mips32/up_vfork.c new file mode 100644 index 0000000000000000000000000000000000000000..dda54ae1799ccceb613dcdbbb787e45463d04edf --- /dev/null +++ b/arch/mips/src/mips32/up_vfork.c @@ -0,0 +1,255 @@ +/**************************************************************************** + * arch/mips/src/mips32/up_vfork.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_vfork.h" +#include "sched/sched.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_STACK_ALIGNMENT +# define CONFIG_STACK_ALIGNMENT 4 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the + * behavior is undefined if the process created by vfork() either modifies + * any data other than a variable of type pid_t used to store the return + * value from vfork(), or returns from the function in which vfork() was + * called, or calls any other function before successfully calling _exit() + * or one of the exec family of functions. + * + * The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * task_vforkabort() may be called if an error occurs between steps 3 and 6. + * + * Input Paremeters: + * context - Caller context information saved by vfork() + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and + * returns the process ID of the child process to the parent process. + * Otherwise, -1 is returned to the parent, no child process is created, + * and errno is set to indicate the error. + * + ****************************************************************************/ + +pid_t up_vfork(const struct vfork_s *context) +{ + struct tcb_s *parent = this_task(); + struct task_tcb_s *child; + size_t stacksize; + uint32_t newsp; +#ifdef CONFIG_MIPS32_FRAMEPOINTER + uint32_t newfp; +#endif + uint32_t stackutil; + int ret; + + svdbg("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n", + context->s0, context->s1, context->s2, context->s3, context->s4); +#ifdef CONFIG_MIPS32_FRAMEPOINTER + svdbg("s5:%08x s6:%08x s7:%08x\n", + context->s5, context->s6, context->s7); +#ifdef MIPS32_SAVE_GP + svdbg("fp:%08x sp:%08x ra:%08x gp:%08x\n", + context->fp, context->sp, context->ra, context->gp); +#else + svdbg("fp:%08x sp:%08x ra:%08x\n", + context->fp context->sp, context->ra); +#endif +#else + svdbg("s5:%08x s6:%08x s7:%08x s8:%08x\n", + context->s5, context->s6, context->s7, context->s8); +#ifdef MIPS32_SAVE_GP + svdbg("sp:%08x ra:%08x gp:%08x\n", + context->sp, context->ra, context->gp); +#else + svdbg("sp:%08x ra:%08x\n", + context->sp, context->ra); +#endif +#endif + + /* Allocate and initialize a TCB for the child task. */ + + child = task_vforksetup((start_t)context->ra); + if (!child) + { + sdbg("task_vforksetup failed\n"); + return (pid_t)ERROR; + } + + svdbg("Parent=%p Child=%p\n", parent, child); + + /* Get the size of the parent task's stack. Due to alignment operations, + * the adjusted stack size may be smaller than the stack size originally + * requrested. + */ + + stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1; + + /* Allocate the stack for the TCB */ + + ret = up_create_stack((FAR struct tcb_s *)child, stacksize, + parent->flags & TCB_FLAG_TTYPE_MASK); + if (ret != OK) + { + sdbg("up_create_stack failed: %d\n", ret); + task_vforkabort(child, -ret); + return (pid_t)ERROR; + } + + /* How much of the parent's stack was utilized? The MIPS uses + * a push-down stack so that the current stack pointer should + * be lower than the initial, adjusted stack pointer. The + * stack usage should be the difference between those two. + */ + + DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); + stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; + + svdbg("stacksize:%d stackutil:%d\n", stacksize, stackutil); + + /* Make some feeble effort to perserve the stack contents. This is + * feeble because the stack surely contains invalid pointers and other + * content that will not work in the child context. However, if the + * user follows all of the caveats of vfork() usage, even this feeble + * effort is overkill. + */ + + newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; + memcpy((void *)newsp, (const void *)context->sp, stackutil); + + /* Was there a frame pointer in place before? */ + +#ifdef CONFIG_MIPS32_FRAMEPOINTER + if (context->fp <= (uint32_t)parent->adj_stack_ptr && + context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) + { + uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; + newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; + } + else + { + newfp = context->fp; + } + + svdbg("Old stack base:%08x SP:%08x FP:%08x\n", + parent->adj_stack_ptr, context->sp, context->fp); + svdbg("New stack base:%08x SP:%08x FP:%08x\n", + child->cmn.adj_stack_ptr, newsp, newfp); +#else + svdbg("Old stack base:%08x SP:%08x\n", + parent->adj_stack_ptr, context->sp); + svdbg("New stack base:%08x SP:%08x\n", + child->cmn.adj_stack_ptr, newsp); +#endif + + /* Update the stack pointer, frame pointer, global pointer and saved + * registers. When the child TCB was initialized, all of the values + * were set to zero. up_initial_state() altered a few values, but the + * return value in v0 should be cleared to zero, providing the + * indication to the newly started child thread. + */ + + child->cmn.xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ + child->cmn.xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ + child->cmn.xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ + child->cmn.xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */ + child->cmn.xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */ + child->cmn.xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */ + child->cmn.xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */ + child->cmn.xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */ +#ifdef CONFIG_MIPS32_FRAMEPOINTER + child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ +#else + child->cmn.xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */ +#endif + child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ +#ifdef MIPS32_SAVE_GP + child->cmn.xcp.regs[REG_GP] = newsp; /* Global pointer */ +#endif + + /* And, finally, start the child task. On a failure, task_vforkstart() + * will discard the TCB by calling task_vforkabort(). + */ + + return task_vforkstart(child); +} diff --git a/arch/mips/src/mips32/up_vfork.h b/arch/mips/src/mips32/up_vfork.h new file mode 100644 index 0000000000000000000000000000000000000000..079a744c83058f4b0c59f01b5d4909e423164eba --- /dev/null +++ b/arch/mips/src/mips32/up_vfork.h @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/mips/src/mips/up_vfork.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_MIPS32_VFORK_H +#define __ARCH_MIPS_SRC_MIPS32_VFORK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register r30 may be a frame pointer in some ABIs. Or may just be saved + * register s8. It makes a difference for vfork handling. + */ + +#undef VFORK_HAVE_FP + +/* r0 zero Always has the value 0. + * r1 at Temporary generally used by assembler. + * r2-r3 v0-v1 Used for expression evaluations and to hold the integer and + * pointer type function return values. + * r4-r7 a0-a3 Used for passing arguments to functions; values are not + * preserved across function calls. + * r8-r15 t0-t7 Temporary registers used for expression evaluation; values + * are not preserved across function calls. + * r16-r23 s0-s7 Saved registers; values are preserved across function calls. + * r24-r25 t8-t9 Temporary registers used for expression evaluations; values + * are not preserved across function calls. When calling + * position independent functions r25 must contain the address + * of the called function. + * r26-r27 k0-k1 Used only by the operating system. + * r28 gp Global pointer and context pointer. + * r29 sp Stack pointer. + * r30 s8 Saved register (like s0-s7). If a frame pointer is used, + * then this is the frame pointer. + * r31 ra Return address. + */ + +#define VFORK_S0_OFFSET (0*4) /* Saved register s0 */ +#define VFORK_S1_OFFSET (1*4) /* Saved register s1 */ +#define VFORK_S2_OFFSET (2*4) /* Saved register s2 */ +#define VFORK_S3_OFFSET (3*4) /* Saved register s3 */ +#define VFORK_S4_OFFSET (4*4) /* Saved register s4 */ +#define VFORK_S5_OFFSET (5*4) /* Saved register s5 */ +#define VFORK_S6_OFFSET (6*4) /* Saved register s6 */ +#define VFORK_S7_OFFSET (7*4) /* Saved register s7 */ + +#ifdef CONFIG_MIPS32_FRAMEPOINTER +# define VFORK_FP_OFFSET (8*4) /* Frame pointer */ +#else +# define VFORK_S8_OFFSET (8*4) /* Saved register s8 */ +#endif + +#define VFORK_SP_OFFSET (9*4) /* Stack pointer*/ +#define VFORK_RA_OFFSET (10*4) /* Return address*/ +#ifdef MIPS32_SAVE_GP +# define VFORK_GP_OFFSET (11*4) /* Global pointer */ +# define VFORK_SIZEOF (12*4) +#else +# define VFORK_SIZEOF (11*4) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +struct vfork_s +{ + /* CPU registers */ + + uint32_t s0; /* Saved register s0 */ + uint32_t s1; /* Saved register s1 */ + uint32_t s2; /* Saved register s2 */ + uint32_t s3; /* Saved register s3 */ + uint32_t s4; /* Saved register s4 */ + uint32_t s5; /* Saved register s5 */ + uint32_t s6; /* Saved register s6 */ + uint32_t s7; /* Saved register s7 */ +#ifdef CONFIG_MIPS32_FRAMEPOINTER + uint32_t fp; /* Frame pointer */ +#else + uint32_t s8; /* Saved register s8 */ +#endif + uint32_t sp; /* Stack pointer*/ + uint32_t ra; /* Return address*/ +#ifdef MIPS32_SAVE_GP + uint32_t gp; /* Global pointer */ +#endif + + /* Floating point registers (not yet) */ +}; +#endif + +#endif /* __ARCH_MIPS_SRC_MIPS32_VFORK_H */ diff --git a/arch/mips/src/mips32/vfork.S b/arch/mips/src/mips32/vfork.S new file mode 100644 index 0000000000000000000000000000000000000000..7012b45a41d53c4dc297ddbd0385c46232571343 --- /dev/null +++ b/arch/mips/src/mips32/vfork.S @@ -0,0 +1,157 @@ +/************************************************************************************ + * arch/mips/src/mips32/vfork.S + * + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_vfork.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .file "vfork.S" + .globl up_vfork + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: vfork + * + * Description: + * The vfork() function has the same effect as fork(), except that the behavior is + * undefined if the process created by vfork() either modifies any data other than + * a variable of type pid_t used to store the return value from vfork(), or returns + * from the function in which vfork() was called, or calls any other function before + * successfully calling _exit() or one of the exec family of functions. + * + * This thin layer implements vfork by simply calling up_vfork() with the vfork() + * context as an argument. The overall sequence is: + * + * 1) User code calls vfork(). vfork() collects context information and + * transfers control up up_vfork(). + * 2) up_vfork()and calls task_vforksetup(). + * 3) task_vforksetup() allocates and configures the child task's TCB. This + * consists of: + * - Allocation of the child task's TCB. + * - Initialization of file descriptors and streams + * - Configuration of environment variables + * - Setup the intput parameters for the task. + * - Initialization of the TCB (including call to up_initial_state() + * 4) up_vfork() provides any additional operating context. up_vfork must: + * - Allocate and initialize the stack + * - Initialize special values in any CPU registers that were not + * already configured by up_initial_state() + * 5) up_vfork() then calls task_vforkstart() + * 6) task_vforkstart() then executes the child thread. + * + * Input Paremeters: + * None + * + * Return: + * Upon successful completion, vfork() returns 0 to the child process and returns + * the process ID of the child process to the parent process. Otherwise, -1 is + * returned to the parent, no child process is created, and errno is set to + * indicate the error. + * + ************************************************************************************/ + + .text + .align 2 + .globl vfork + .type vfork, function + .set nomips16 +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent vfork + +vfork: + /* Create a stack frame */ + + move $t0, $sp /* Save the value of the stack on entry */ + addiu $sp, $sp, -VFORK_SIZEOF /* Allocate the structure on the stack */ + + /* CPU registers */ + /* Save the saved registers */ + + sw $s0, VFORK_S0_OFFSET($sp) + sw $s1, VFORK_S1_OFFSET($sp) + sw $s2, VFORK_S2_OFFSET($sp) + sw $s3, VFORK_S3_OFFSET($sp) + sw $s4, VFORK_S4_OFFSET($sp) + sw $s5, VFORK_S5_OFFSET($sp) + sw $s6, VFORK_S6_OFFSET($sp) + sw $s7, VFORK_S7_OFFSET($sp) + +#ifdef CONFIG_MIPS32_FRAMEPOINTER + sw $fp, VFORK_FP_OFFSET($sp) +#else + sw $s8, VFORK_S8_OFFSET($sp) +#endif + + /* Save the global pointer, stack pointer, and return address */ + + sw $t0, VFORK_SP_OFFSET($sp) + sw $ra, VFORK_RA_OFFSET($sp) +#ifdef MIPS32_SAVE_GP + sw $gp, VFORK_GP_OFFSET($sp) +#endif + + /* Floating point registers (not yet) */ + + /* Then, call up_vfork(), passing it a pointer to the stack structure */ + + move $a0, $sp + jal up_vfork + nop + + /* Release the stack data and return the value returned by up_vfork */ + + lw $ra, VFORK_RA_OFFSET($sp) + addiu $sp, $sp, VFORK_SIZEOF + j $ra + + .end vfork + .size vfork, .-vfork diff --git a/arch/mips/src/pic32mx/Kconfig b/arch/mips/src/pic32mx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..6d8894bf6248251c8c0b6b558e660ebc3b28def7 --- /dev/null +++ b/arch/mips/src/pic32mx/Kconfig @@ -0,0 +1,1212 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_PIC32MX +comment "PIC32MX Configuration Options" + +choice + prompt "PIC32MX chip selection" + default ARCH_CHIP_PIC32MX460F512L + +config ARCH_CHIP_PIC32MX110F016B + bool "PIC32MX110F016B" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX110F016B (MPS32 24KC) + ARCH_CHIP_PIC32MX1 + +config ARCH_CHIP_PIC32MX110F016C + bool "PIC32MX110F016C" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX110F016C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX110F016D + bool "PIC32MX110F016D" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX110F016D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX120F032B + bool "PIC32MX120F032B" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX120F032B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX120F032C + bool "PIC32MX120F032C" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX120F032C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX120F032D + bool "PIC32MX120F032D" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX120F032D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX130F064B + bool "PIC32MX130F064B" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX130F064B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX130F064C + bool "PIC32MX130F064C" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX130F064C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX130F064D + bool "PIC32MX130F064D" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX130F064D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX150F128B + bool "PIC32MX150F128B" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX150F128B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX150F128C + bool "PIC32MX150F128C" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX150F128C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX150F128D + bool "PIC32MX150F128D" + select ARCH_CHIP_PIC32MX1 + ---help--- + Microchip PIC32MX150F128D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX210F016B + bool "PIC32MX210F016B" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX210F016B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX210F016C + bool "PIC32MX210F016C" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX210F016C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX210F016D + bool "PIC32MX210F016D" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX210F016D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX220F032B + bool "PIC32MX220F032B" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX220F032B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX220F032C + bool "PIC32MX220F032C" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX220F032C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX220F032D + bool "PIC32MX220F032D" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX220F032D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX230F064B + bool "PIC32MX230F064B" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX230F064B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX230F064C + bool "PIC32MX230F064C" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX230F064C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX230F064D + bool "PIC32MX230F064D" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX230F064D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX250F128B + bool "PIC32MX250F128B" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX250F128B (MPS32 24KC) + +config ARCH_CHIP_PIC32MX250F128C + bool "PIC32MX250F128C" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX250F128C (MPS32 24KC) + +config ARCH_CHIP_PIC32MX250F128D + bool "PIC32MX250F128D" + select ARCH_CHIP_PIC32MX2 + ---help--- + Microchip PIC32MX250F128D (MPS32 24KC) + +config ARCH_CHIP_PIC32MX320F032H + bool "PIC32MX320F032H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX320F032H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX320F064H + bool "PIC32MX320F064H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX320F064H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX320F128H + bool "PIC32MX320F128H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX320F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX320F128L + bool "PIC32MX320F128L" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX320F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX340F128H + bool "PIC32MX340F128H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX340F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX340F256H + bool "PIC32MX340F256H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX340F256H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX340F512H + bool "PIC32MX340F512H" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX340F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX340F128L + bool "PIC32MX340F128L" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX340F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX360F256L + bool "PIC32MX360F256L" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX360F256L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX360F512L + bool "PIC32MX360F512L" + select ARCH_CHIP_PIC32MX3 + ---help--- + Microchip PIC32MX360F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX420F032H + bool "PIC32MX420F032H" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX420F032H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX440F128H + bool "PIC32MX440F128H" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX440F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX440F128L + bool "PIC32MX440F128L" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX440F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX440F256H + bool "PIC32MX440F256H" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX440F256H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX440F512H + bool "PIC32MX440F512H" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX440F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX460F256L + bool "PIC32MX460F256L" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX460F256L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX460F512L + bool "PIC32MX460F512L" + select ARCH_CHIP_PIC32MX4 + ---help--- + Microchip PIC32MX460F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX534F064H + bool "PIC32MX534F064H" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX534F064H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX534F064L + bool "PIC32MX534F064L" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX534F064L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX564F064H + bool "PIC32MX564F064H" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX564F064H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX564F064L + bool "PIC32MX564F064L" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX564F064L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX564F128H + bool "PIC32MX564F128H" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX564F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX564F128L + bool "PIC32MX564F128L" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX564F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX575F256H + bool "PIC32MX575F256H" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX575F256H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX575F256L + bool "PIC32MX575F256L" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX575F256L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX575F512H + bool "PIC32MX575F512H" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX575F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX575F512L + bool "PIC32MX575F512L" + select ARCH_CHIP_PIC32MX5 + ---help--- + Microchip PIC32MX575F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX664F064H + bool "PIC32MX664F064H" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX664F064H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX664F064L + bool "PIC32MX664F064L" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX664F064L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX664F128H + bool "PIC32MX664F128H" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX664F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX664F128L + bool "PIC32MX664F128L" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX664F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX675F256H + bool "PIC32MX675F256H" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX675F256H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX675F256L + bool "PIC32MX675F256L" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX675F256L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX675F512H + bool "PIC32MX675F512H" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX675F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX675F512L + bool "PIC32MX675F512L" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX675F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX695F512H + bool "PIC32MX695F512H" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX695F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX695F512L + bool "PIC32MX695F512L" + select ARCH_CHIP_PIC32MX6 + ---help--- + Microchip PIC32MX695F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX764F128H + bool "PIC32MX764F128H" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX764F128H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX764F128L + bool "PIC32MX764F128L" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX764F128L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX775F256H + bool "PIC32MX775F256H" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX775F256H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX775F256L + bool "PIC32MX775F256L" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX775F256L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX775F512H + bool "PIC32MX775F512H" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX775F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX775F512L + bool "PIC32MX775F512L" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX775F512L (MPS32 24KC) + +config ARCH_CHIP_PIC32MX795F512H + bool "PIC32MX795F512H" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX795F512H (MPS32 24KC) + +config ARCH_CHIP_PIC32MX795F512L + bool "PIC32MX795F512L" + select ARCH_CHIP_PIC32MX7 + ---help--- + Microchip PIC32MX795F512L (MPS32 24KC) + +endchoice + +config ARCH_CHIP_PIC32MX1 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX2 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX3 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX4 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX5 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX6 + bool + default n + select ARCH_MIPS_24KC + +config ARCH_CHIP_PIC32MX7 + bool + default n + select ARCH_MIPS_24KC + +config PIC32MX_MVEC + bool + default n + +config PIC32MX_SPI + bool + default n + +config PIC32MX_T1 + bool + default y + +menu "PIC32MX Peripheral Support" + +config PIC32MX_WDT + bool "Watchdog timer (WDT)" + default n + +config PIC32MX_T2 + bool "Timer 2 (T2)" + default n + +config PIC32MX_T3 + bool "Timer 3 (T3)" + default n + +config PIC32MX_T4 + bool "Timer 4 (T4)" + default n + +config PIC32MX_T5 + bool "Timer 5 (T5)" + default n + +config PIC32MX_IC1 + bool "Input Capture 1 (IC1)" + default n + +config PIC32MX_IC2 + bool "Input Capture 2 (IC2)" + default n + +config PIC32MX_IC3 + bool "Input Capture 3 (IC3)" + default n + +config PIC32MX_IC4 + bool "Input Capture 4 (IC4)" + default n + +config PIC32MX_IC5 + bool "Input Capture 5 (IC5)" + default n + +config PIC32MX_OC1 + bool "Output Compare 1 (OC1)" + default n + +config PIC32MX_OC2 + bool "Output Compare 2 (OC2)" + default n + +config PIC32MX_OC3 + bool "Output Compare 3 (OC3)" + default n + +config PIC32MX_OC4 + bool "Output Compare 4 (OC4)" + default n + +config PIC32MX_OC5 + bool "Output Compare 5 (OC5)" + default n + +config PIC32MX_I2C1 + bool "I2C1" + default n + +config PIC32MX_I2C2 + bool "I2C2" + default n + +config PIC32MX_I2C3 + bool "I2C3" + default n + +config PIC32MX_I2C4 + bool "I2C4" + default n + +config PIC32MX_I2C5 + bool "I2C5" + default n + +config PIC32MX_SPI1 + bool "SPI1" + default n + select PIC32MX_SPI + +config PIC32MX_SPI2 + bool "SPI2" + default n + select PIC32MX_SPI + +config PIC32MX_SPI3 + bool "SPI3" + default n + select PIC32MX_SPI + +config PIC32MX_SPI4 + bool "SPI4" + default n + select PIC32MX_SPI + +config PIC32MX_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_UART4 + bool "UART4" + default n + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_UART5 + bool "UART5" + default n + select ARCH_HAVE_UART5 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_UART6 + bool "UART6" + default n + select ARCH_HAVE_UART6 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MX_ADC + bool "ADC1" + default n + +config PIC32MX_PMP + bool "Parallel Master Port (PMP)" + default n + +config PIC32MX_CM1 + bool "Comparator 1 (CM1)" + default n + +config PIC32MX_CM2 + bool "Comparator 2 (CM2)" + default n + +config PIC32MX_CM3 + bool "Comparator 3 (CM3)" + default n + +config PIC32MX_RTCC + bool "Real-Time Clock and Calendar (RTCC)" + default n + +config PIC32MX_DMA + bool "DMA" + default n + select ARCH_DMA + +config PIC32MX_FLASH + bool "FLASH" + default n + +config PIC32MX_USBDEV + bool "USB device" + default n + +config PIC32MX_USBHOST + bool "USB host" + default n + +config PIC32MX_CAN1 + bool "Controller area network 1 (CAN1)" + default n + +config PIC32MX_CAN2 + bool "Controller area network 2 (CAN2)" + default n + +config PIC32MX_ETHERNET + bool "Ethernet" + default n + select NETDEVICES + select ARCH_HAVE_PHY + select ARCH_HAVE_NETDEV_STATISTICS + +config PIC32MX_CTMU + bool "Charge Time Measurement Unit (CMTU)" + default n + +endmenu + +menu "PIC32MX Peripheral Interrupt Priorities" + +config PIC32MX_CTPRIO + int "Core Timer Interrupt (CT)" + default 16 + ---help--- + Core Timer Interrupt. Range 4-31, Default 16. + +config PIC32MX_CS0PRIO + int "Core Software Interrupt 0 (CS0)" + default 16 + ---help--- + Core Software Interrupt 0. Range 4-31, Default 16. + +config PIC32MX_CS1PRIO + int "Core Software Interrupt 1 (CS1)" + default 16 + ---help--- + Core Software Interrupt 1. Range 4-31, Default 16. + +config PIC32MX_INT0PRIO + int "External Interrupt 0 (INT0)" + default 16 + ---help--- + External Interrupt 0. Range 4-31, Default 16. + +config PIC32MX_INT1PRIO + int "External Interrupt 1 (INT1)" + default 16 + ---help--- + External Interrupt 1. Range 4-31, Default 16. + +config PIC32MX_INT2PRIO + int "External Interrupt 2 (INT2)" + default 16 + ---help--- + External Interrupt 2. Range 4-31, Default 16. + +config PIC32MX_INT3PRIO + int "External Interrupt 3 (INT3)" + default 16 + ---help--- + External Interrupt 3. Range 4-31, Default 16. + +config PIC32MX_INT4PRIO + int "External Interrupt 4 (INT4)" + default 16 + ---help--- + External Interrupt 4. Range 4-31, Default 16. + +config PIC32MX_FSCMPRIO + int "Fail-Safe Clock Monitor (FSCM)" + default 16 + depends on PIC32MX_ + ---help--- + Fail-Safe Clock Monitor. Range 4-31, Default 16. + +config PIC32MX_T1PRIO + int "Timer 1 (T1)" + default 16 + ---help--- + Timer 1 (System timer) priority. Range 4-31, Default 16. + +config PIC32MX_T2PRIO + int "Timer 2 (T2)" + default 16 + depends on PIC32MX_T2 + ---help--- + Timer 2 priority. Range 4-31, Default 16. + +config PIC32MX_T3PRIO + int "Timer 3 (T3)" + default 16 + depends on PIC32MX_T3 + ---help--- + Timer 3 priority. Range 4-31, Default 16. + +config PIC32MX_T4PRIO + int "Timer 4 (T4)" + default 16 + depends on PIC32MX_T4 + ---help--- + Timer 4 priority. Range 4-31, Default 16. + +config PIC32MX_T5PRIO + int "Timer 5 (T5)" + default 16 + depends on PIC32MX_ + ---help--- + Timer 5 priority. Range 4-31, Default 16. + +config PIC32MX_IC1PRIO + int "Input Capture 1 (IC1)" + default 16 + depends on PIC32MX_IC1 + ---help--- + Input Capture 1. Range 4-31, Default 16. + +config PIC32MX_IC2PRIO + int "Input Capture 2 (IC2)" + default 16 + depends on PIC32MX_IC2 + ---help--- + Input Capture 2. Range 4-31, Default 16. + +config PIC32MX_IC3PRIO + int "Input Capture 3 (IC3)" + default 16 + depends on PIC32MX_IC3 + ---help--- + Input Capture 3. Range 4-31, Default 16. + +config PIC32MX_IC4PRIO + int "Input Capture 4 (IC4)" + default 16 + depends on PIC32MX_IC4 + ---help--- + Input Capture 4. Range 4-31, Default 16. + +config PIC32MX_IC5PRIO + int "Input Capture 5 (IC5)" + default 16 + depends on PIC32MX_IC5 + ---help--- + Input Capture 5. Range 4-31, Default 16. + +config PIC32MX_OC1PRIO + int "Output Compare 1 (OC1)" + default 16 + depends on PIC32MX_OC1 + ---help--- + Output Compare 1. Range 4-31, Default 16. + +config PIC32MX_OC2PRIO + int "Output Compare 2 (OC2)" + default 16 + depends on PIC32MX_OC2 + ---help--- + Output Compare 2. Range 4-31, Default 16. + +config PIC32MX_OC3PRIO + int "Output Compare 3 (OC3)" + default 16 + depends on PIC32MX_OC3 + ---help--- + Output Compare 3. Range 4-31, Default 16. + +config PIC32MX_OC4PRIO + int "Output Compare 4 (OC4)" + default 16 + depends on PIC32MX_OC4 + ---help--- + Output Compare 4. Range 4-31, Default 16. + +config PIC32MX_OC5PRIO + int "Output Compare 5 (OC5)" + default 16 + depends on PIC32MX_OC5 + ---help--- + Output Compare 5. Range 4-31, Default 16. + +config PIC32MX_I2C1PRIO + int "I2C1" + default 16 + depends on PIC32MX_I2C1 + ---help--- + I2C 1. Range 4-31, Default 16. + +config PIC32MX_I2C2PRIO + int "I2C2" + default 16 + depends on PIC32MX_I2C3 + ---help--- + I2C 2. Range 4-31, Default 16. + +config PIC32MX_I2C3PRIO + int "I2C3" + default 16 + depends on PIC32MX_I2C3 + ---help--- + I2C 3. Range 4-31, Default 16. + +config PIC32MX_I2C4PRIO + int "I2C4" + default 16 + depends on PIC32MX_I2C4 + ---help--- + I2C 4. Range 4-31, Default 16. + +config PIC32MX_I2C5PRIO + int "I2C5" + default 16 + depends on PIC32MX_I2C5 + ---help--- + I2C 5. Range 4-31, Default 16. + +config PIC32MX_SPI1PRIO + int "SPI1" + default 16 + depends on PIC32MX_SPI1 + ---help--- + SPI 2 + +config PIC32MX_SPI2PRIO + int "SPI2" + default 16 + depends on PIC32MX_SPI2 + ---help--- + SPI 2 + +config PIC32MX_UART1PRIO + int "UART1" + default 16 + depends on PIC32MX_UART1 + ---help--- + UART 1. Range 4-31, Default 16. + +config PIC32MX_UART2PRIO + int "UART2" + default 16 + depends on PIC32MX_UART2 + ---help--- + UART 2. Range 4-31, Default 16. + +config PIC32MX_CNPRIO + int "CN" + default 16 + depends on PIC32MX_CN + ---help--- + Input Change Interrupt. Range 4-31, Default 16. + +config PIC32MX_ADCPRIO + int "ADC1" + default 16 + depends on PIC32MX_ADC1 + ---help--- + ADC1 Convert Done. Range 4-31, Default 16. + +config PIC32MX_PMPPRIO + int "Parallel Master Port (PMP)" + default 16 + depends on PIC32MX_PMP + ---help--- + Parallel Master Port. Range 4-31, Default 16. + +config PIC32MX_CM1PRIO + int "Comparator 1 (CM1)" + default 16 + depends on PIC32MX_CM1 + ---help--- + Comparator 1. Range 4-31, Default 16. + +config PIC32MX_CM2PRIO + int "Comparator 2 (CM2)" + default 16 + depends on PIC32MX_CM2 + ---help--- + Comparator 2. Range 4-31, Default 16. + +config PIC32MX_RTCCPRIO + int "Real-Time Clock and Calendar (RTCC)" + default 16 + depends on PIC32MX_RTCC + ---help--- + Real-Time Clock and Calendar. Range 4-31, Default 16. + +config PIC32MX_DMA0PRIO + int "DMA0" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 0. Range 4-31, Default 16. + +config PIC32MX_DMA1PRIO + int "DMA1" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 1. Range 4-31, Default 16. + +config PIC32MX_DMA2PRIO + int "DMA2" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 2. Range 4-31, Default 16. + +config PIC32MX_DMA3PRIO + int "DMA3" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 3. Range 4-31, Default 16. + +config PIC32MX_DMA4PRIO + int "DMA4" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 4. Range 4-31, Default 16. + +config PIC32MX_DMA5PRIO + int "DMA5" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 5. Range 4-31, Default 16. + +config PIC32MX_DMA6PRIO + int "DMA6" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 6. Range 4-31, Default 16. + +config PIC32MX_DMA7PRIO + int "DMA7" + default 16 + depends on PIC32MX_DMA + ---help--- + DMA Channel 7. Range 4-31, Default 16. + +config PIC32MX_FCEPRIO + int "FCE" + default 16 + depends on PIC32MX_FLASH + ---help--- + Flash Control Event. Range 4-31, Default 16. + +config PIC32MX_USBPRIO + int "USB" + default 16 + depends on PIC32MX_USBDEV || PIC32MX_USBHOST + ---help--- + USB. Range 4-31, Default 16. + +endmenu + +config PIC32MX_GPIOIRQ + bool "GPIO Interrupt" + default n + depends on EXPERIMENTAL + ---help--- + Build in support for interrupts based on GPIO inputs from IOPorts + +menu "SPI Driver Configuration" + depends on PIC32MX_SPI + +config PIC32MX_SPI_INTERRUPTS + bool "SPI Interrupt Driven" + default n + depends on EXPERIMENTAL + +config PIC32MX_SPI_ENHBUF + bool "SPI Enhanced Buffer Mode" + default n + depends on EXPERIMENTAL + +config PIC32MX_SPI_REGDEBUG + bool "SPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. + Requires also DEBUG. + +endmenu # SPI Driver Configuration + +menu "PIC32MX PHY/Ethernet device driver settings" + depends on PIC32MX_ETHERNET + +config PHY_AUTONEG + bool "Auto-negotion" + default y + depends on PIC32MX_ETHERNET + ---help--- + Enable auto-negotion + +config PHY_SPEED100 + bool "100Mbps spped" + default n + depends on PIC32MX_ETHERNET && !PHY_AUTONEG + ---help--- + Select 100Mbit vs. 10Mbit speed. + +config PHY_FDUPLEX + bool "Full duplex" + default n + depends on PIC32MX_ETHERNET && !PHY_AUTONEG + ---help--- + Select full (vs. half) duplex + +config NET_NTXDESC + int "Number Tx descriptors" + default 2 + depends on PIC32MX_ETHERNET + ---help--- + Configured number of Tx descriptors. Default: 2 + +config NET_NRXDESC + int "Number Rx descriptors" + default 4 + depends on PIC32MX_ETHERNET + ---help--- + Configured number of Rx descriptors. Default: 4 + +config NET_PRIORITY + int "" + default 28 + depends on PIC32MX_ETHERNET + ---help--- + Ethernet interrupt priority. The is default is the higest priority. + +config NET_WOL + bool "Wake-up on LAN" + default n + depends on PIC32MX_ETHERNET + ---help--- + Enable Wake-up on LAN (not fully implemented). + +config NET_REGDEBUG + bool "Register level debug" + default n + depends on PIC32MX_ETHERNET && DEBUG + ---help--- + Enabled low level register debug. Also needs DEBUG. + +config NET_HASH + bool "Hash" + default n + depends on PIC32MX_ETHERNET + ---help--- + Enable receipt of near-perfect match frames. + +config PIC32MX_MULTICAST + bool "Multicast" + default y if NET_IGMP + depends on PIC32MX_ETHERNET + ---help--- + Enable receipt of multicast (and unicast) frames. Automatically set if + NET_IGMP is selected. + +endmenu + +menu "Device Configuration 0 (DEVCFG0)" + +config PIC32MX_DEBUGGER + int "Debugger" + default 3 + ---help--- + Background Debugger Enable. Default 3 (disabled). The value 2 enables. + +config PIC32MX_ICESEL + int "ICE channel" + default 1 + ---help--- + In-Circuit Emulator/Debugger Communication Channel Select. Default 1 (PG2) + +config PIC32MX_PROGFLASHWP + hex "Program FLASH write protect" + default 0x3ff if ARCH_CHIP_PIC32MX1 || ARCH_CHIP_PIC32MX2 + default 0xff if !ARCH_CHIP_PIC32MX1 && !ARCH_CHIP_PIC32MX2 + ---help--- + Program FLASH write protect. Default 0xff (disabled) + +config PIC32MX_BOOTFLASHWP + int "Boot FLASH write protect" + default 1 + ---help--- + Default 1 (disabled) + +config PIC32MX_CODEWP + int "Code write protect" + default 1 + ---help--- + Default 1 (disabled) + +endmenu + +menu "Device Configuration 1 (DEVCFG1)" + +config PIC32MX_OSCOUT + int "USB ID" + default 0 + depends on ARCH_CHIP_PIC32MX1 || ARCH_CHIP_PIC32MX2 + ---help--- + USB USBID Selection. Default 1 if USB enabled (USBID pin is controlled by the USB + module), but 0 (GPIO) otherwise. + +endmenu + +menu "Device Configuration 3 (DEVCFG3)" + +config PIC32MX_USBIDO + int "USB ID" + default 1 if PIC32MX_USB + default 0 if !PIC32MX_USB + ---help--- + USB USBID Selection. Default 1 if USB enabled (USBID pin is controlled by the USB + module), but 0 (GPIO) otherwise. + +config PIC32MX_VBUSIO + int "USB VBUSON" + default 1 if PIC32MX_USB + default 0 if !PIC32MX_USB + ---help--- + USB VBUSON Selection (Default 1 if USB enabled (VBUSON pin is controlled by the USB + module, but 0 (GPIO) otherwise. + +config PIC32MX_WDENABLE + bool "Watchdog enable" + default 0 + ---help--- + Enabled watchdog on power up. Default 0 (watchdog can be enabled later by software). + +config PIC32MX_FETHIO + int "Ethernet I/O pins" + default 1 + ---help--- + Ethernet I/O Pin Selection bit: + + 1 = Default Ethernet I/O Pins + 0 = Alternate Ethernet I/O Pins + +config PIC32MX_FMIIEN + int "Ethernet MII" + default 1 + ---help--- + Ethernet MII Enable bit + + 1 = MII enabled + 0 = RMII enabled + +endmenu + +endif diff --git a/arch/mips/src/pic32mx/Make.defs b/arch/mips/src/pic32mx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..02025839017150b29ed1a79f30d2b979b64cce18 --- /dev/null +++ b/arch/mips/src/pic32mx/Make.defs @@ -0,0 +1,91 @@ +############################################################################ +# arch/mips/src/pic32mx/Make.defs +# +# Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = pic32mx-head.S + +# Common MIPS files + +CMN_ASRCS = up_syscall0.S vfork.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_irq.c up_lowputs.c +CMN_CSRCS += up_mdelay.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_puts.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_sigdeliver.c +CMN_CSRCS += up_stackframe.c up_swint0.c up_udelay.c up_unblocktask.c +CMN_CSRCS += up_usestack.c up_vfork.c + +# Configuration dependent common files + +# Use of common/up_etherstub.c is deprecated. The preferred mechanism is to +# use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in +# up_initialize(). Then this stub would not be needed. + +ifneq ($(CONFIG_PIC32MX_ETHERNET),y) +ifeq ($(CONFIG_NET),y) +CMN_CSRCS += up_etherstub.c +endif +endif + +ifeq ($(CONFIG_ARCH_STACKDUMP),y) +CMN_CSRCS += up_dumpstate.c +endif + +# Required PIC32MX files + +CHIP_ASRCS = +CHIP_CSRCS = pic32mx-irq.c pic32mx-decodeirq.c pic32mx-exception.c +CHIP_CSRCS += pic32mx-gpio.c pic32mx-lowconsole.c pic32mx-lowinit.c +CHIP_CSRCS += pic32mx-serial.c pic32mx-spi.c + +# Configuration-dependent PIC32MX files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += pic32mx-timerisr.c +endif + +ifeq ($(CONFIG_PIC32MX_GPIOIRQ),y) +CHIP_CSRCS += pic32mx_gpioirq.c +endif + +ifeq ($(CONFIG_PIC32MX_USBDEV),y) +CHIP_CSRCS += pic32mx-usbdev.c +endif + +ifeq ($(CONFIG_PIC32MX_ETHERNET),y) +CHIP_CSRCS += pic32mx-ethernet.c +endif diff --git a/arch/mips/src/pic32mx/chip.h b/arch/mips/src/pic32mx/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..90c037c43889d741929c072c28135c2955c02f03 --- /dev/null +++ b/arch/mips/src/pic32mx/chip.h @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/chip.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_CHIP_H +#define __ARCH_MIPS_SRC_PIC32MX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_CHIP_H */ diff --git a/arch/mips/src/pic32mx/excptmacros.h b/arch/mips/src/pic32mx/excptmacros.h new file mode 100644 index 0000000000000000000000000000000000000000..4fdc8afaf557d259d6c3fad1fe4335dba2b185d0 --- /dev/null +++ b/arch/mips/src/pic32mx/excptmacros.h @@ -0,0 +1,449 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/excptmacros.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H +#define __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include +#include + +#ifdef __ASSEMBLY__ + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Symbols + ********************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + .global g_nestlevel +#endif +#endif + +/******************************************************************************************** + * Assembly Language Macros + ********************************************************************************************/ + +/******************************************************************************************** + * General Usage Example: + * + * my_exception: + * EXCPT_PROLOGUE t0 - Save registers on stack, enable nested interrupts + * move a0, sp - Pass register save structure as the parameter 1 + * USE_INTSTACK t0, t1, t2, t3 - Switch to the interrupt stack + * jal handler - Handle the exception IN=old regs OUT=new regs + * di - Disable interrupts + * RESTORE_STACK t0, t1 - Undo the operations of USE_STACK + * EXCPT_EPILOGUE v0 - Return to the context returned by handler() + * + ********************************************************************************************/ +/******************************************************************************************** + * Name: EXCPT_PROLOGUE + * + * Description: + * Provides the "prologue" logic that should appear at the beginning of every exception + * handler. + * + * On Entry: + * sp - Points to the top of the stack + * tmp - Is a register the can be modified for scratch usage (after it has been saved) + * k0 and k1 - Since we are in an exception handler, these are available for use + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp + * and k1: + * + * - sp points the beginning of the register save area + * - k1 holds the value of the STATUS register + * + * The following registers are modified: k0, k1, sp, a0 + * + ********************************************************************************************/ + + .macro EXCPT_PROLOGUE, tmp + .set noat + + /* Get the SP from the previous shadow set */ + +#if 0 + rdpgpr sp, sp +#endif + + /* "When entering the interrupt handler routine, the interrupt controller must first + * save the current priority and exception PC counter from Interrupt Priority (IPL) + * bits (Status<15:10>) and the ErrorEPC register, respectively, on the stack. ..." + */ + +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS // Does not work! + mfc0 k0, MIPS32_CP0_CAUSE + mfc0 k1, MIPS32_CP0_EPC + + /* Isolate the pending interrupt level in bits 0-5 of k0 */ + + srl k0, k0, CP0_CAUSE_IP_SHIFT + + /* Create the register context stack frame large enough to hold the entire register save + * array. + */ + + addiu sp, sp, -XCPTCONTEXT_SIZE + + /* Save the EPC and STATUS in the register context array */ + + sw k1, REG_EPC(sp) + mfc0 k1, MIPS32_CP0_STATUS + sw k1, REG_STATUS(sp) + + /* Then insert pending interrupt level as the current mask level in the CP0 status + * register. Also clear bits 1-4 in new value of the status register: + * + * Bit 1: Exception Level + * Bit 2: Error Level + * Bit 3: (not used in PIC32MX) + * Bit 4: Operating mode == USER + */ + + ins k1, k0, CP0_STATUS_IPL_SHIFT, 6 + ins k1, zero, 1, 4 + + /* And Enable interrupts */ + + mtc0 k1, MIPS32_CP0_STATUS +#else + /* Get the EPC and STATUS register (Don't bother with the CAUSE register if we are + * not supporting nested interrupts) + */ + + mfc0 k0, MIPS32_CP0_EPC + mfc0 k1, MIPS32_CP0_STATUS + + /* Create the register context stack frame large enough to hold the entire register + * save array. + */ + + addiu sp, sp, -XCPTCONTEXT_SIZE + + /* Save the EPC and STATUS in the register context array */ + + sw k0, REG_EPC(sp) + sw k1, REG_STATUS(sp) +#endif + + /* Save floating point registers */ + + mfhi k0 + sw k0, REG_MFHI(sp) + mflo k0 + sw k0, REG_MFLO(sp) + + /* Save general purpose registers */ + /* $1: at_reg, assembler temporary */ + + sw $1, REG_AT(sp) + + /* $2-$3 = v0-v1: Return value registers */ + + sw v0, REG_V0(sp) + sw v1, REG_V1(sp) + + /* $4-$7 = a0-a3: Argument registers */ + + sw a0, REG_A0(sp) + sw a1, REG_A1(sp) + sw a2, REG_A2(sp) + sw a3, REG_A3(sp) + + /* $8-$15 = t0-t7: Volatile registers */ + + sw t0, REG_T0(sp) + sw t1, REG_T1(sp) + sw t2, REG_T2(sp) + sw t3, REG_T3(sp) + sw t4, REG_T4(sp) + sw t5, REG_T5(sp) + sw t6, REG_T6(sp) + sw t7, REG_T7(sp) + + /* $16-$23 = s0-s7: Static registers */ + + sw s0, REG_S0(sp) + sw s1, REG_S1(sp) + sw s2, REG_S2(sp) + sw s3, REG_S3(sp) + sw s4, REG_S4(sp) + sw s5, REG_S5(sp) + sw s6, REG_S6(sp) + sw s7, REG_S7(sp) + + /* $24-25 = t8-t9: More Volatile registers */ + + sw t8, REG_T8(sp) + sw t9, REG_T9(sp) + + /* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be + * saved. + * + * $28 = gp: Only needs to be saved under conditions where there are multiple, per- + * thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP + sw gp, REG_GP(sp) +#endif + + /* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + + sw s8, REG_S8(sp) + + /* $31 = ra: Return address */ + + sw ra, REG_RA(sp) + + /* $29 = sp: The value of the stack pointer on return from the exception. a0 is + * used as a temporary + */ + + addiu \tmp, sp, XCPTCONTEXT_SIZE + sw \tmp, REG_SP(sp) + .endm + +/******************************************************************************************** + * Name: EXCPT_EPILOGUE + * + * Description: + * Provides the "epilogue" logic that should appear at the end of every exception handler. + * + * On input: + * regs - points to the register save structure. NOTE: This *may not* be an address + * lying in a stack! It might be an address in a TCB! + * Interrupts are disabled (via 'di') + * + * On completion: + * All registers restored + * eret is executed to return from the exception + * + ********************************************************************************************/ + + .macro EXCPT_EPILOGUE, regs + .set noat + + /* Since interrupts are disabled via di can now use k0 and k1 again. Use k1 as the + * pointer to the register save array. + */ + + move k1, \regs + + /* Restore the floating point register state */ + + lw k0, REG_MFLO(k1) + mtlo k0 + lw k0, REG_MFHI(k1) + mthi k0 + + /* Restore general purpose registers */ + /* $1: at_reg, assembler temporary */ + + lw $1, REG_AT(k1) + + /* $2-$3 = v0-v1: Return value registers */ + + lw v0, REG_V0(k1) + lw v1, REG_V1(k1) + + /* $4-$7 = a0-a3: Argument registers */ + + lw a0, REG_A0(k1) + lw a1, REG_A1(k1) + lw a2, REG_A2(k1) + lw a3, REG_A3(k1) + + /* $8-$15 = t0-t7: Volatile registers */ + + lw t0, REG_T0(k1) + lw t1, REG_T1(k1) + lw t2, REG_T2(k1) + lw t3, REG_T3(k1) + lw t4, REG_T4(k1) + lw t5, REG_T5(k1) + lw t6, REG_T6(k1) + lw t7, REG_T7(k1) + + /* $16-$23 = s0-s7: Static registers */ + + lw s0, REG_S0(k1) + lw s1, REG_S1(k1) + lw s2, REG_S2(k1) + lw s3, REG_S3(k1) + lw s4, REG_S4(k1) + lw s5, REG_S5(k1) + lw s6, REG_S6(k1) + lw s7, REG_S7(k1) + + /* $24-25 = t8-t9: More Volatile registers */ + + lw t8, REG_T8(k1) + lw t9, REG_T9(k1) + + /* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be + * saved. + * + * $28 = gp: Only needs to be saved under conditions where there are multiple, per- + * thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP + lw gp, REG_GP(k1) +#endif + + /* $29 = sp: Stack pointer */ + + lw sp, REG_SP(k1) + + /* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + + lw s8, REG_S8(k1) + + /* $31 = ra: Return address */ + + lw ra, REG_RA(k1) + + /* Finally, restore CP status and the EPC */ + + lw k0, REG_STATUS(k1) + lw k1, REG_EPC(k1) + mtc0 k0, MIPS32_CP0_STATUS + ehb + mtc0 k1, MIPS32_CP0_EPC + eret + nop + .endm + +/******************************************************************************************** + * Name: USE_INTSTACK + * + * Description: + * Switch to the interrupt stack (if enabled in the configuration). + * + * On Entry: + * sp - Current value of the user stack pointer + * tmp1, tmp2, tmp3, and tmp4 are registers that can be used temporarily. + * All interrupts should still be disabled. + * + * At completion: + * If the nesting level is 0, then (1) the user stack pointer is saved at the base of the + * interrupt stack and sp points to the interrupt stack. + * The values of tmp1, tmp2, tmp3, and sp have been altered + * + ********************************************************************************************/ + + .macro USE_INTSTACK, tmp1, tmp2, tmp3, tmp4 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + + /* Check the nesting level. If there are no nested interrupts, then we can + * claim the interrupt stack. + */ + + la \tmp1, g_nestlevel + lw \tmp2, (\tmp1) + bne 1f + nop +#endif + + /* Use the interrupt stack, pushing the user stack pointer onto the interrupt + * stack first. + */ + + la \tmp3, g_intstackbase + lw \tmp4, (\tmp3) + sw sp, (\tmp4) + move sp, \tmp4 + +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS +1: + /* Increment the interrupt nesting level */ + + addiu \tmp2, \tmp2, 1 + sw \tmp2, 0(\tmp1) +#endif +#endif + .endm + +/******************************************************************************************** + * Name: RESTORE_STACK + * + * Description: + * Restore the user stack. Not really.. actually only decrements the nesting level. We + * always get the new stack pointer for the register save array. + * + * On Entry: + * tmp1 and tmp2 are registers that can be used temporarily. + * All interrupts must be disabled. + * + * At completion: + * Current nesting level is decremented + * The values of tmp1 and tmp2 have been altered + * + ********************************************************************************************/ + + .macro RESTORE_STACK, tmp1, tmp2 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + + /* Decrement the nesting level */ + + la \tmp1, g_nestlevel + lw \tmp2, (\tmp1) + addiu \tmp2, \tmp2, -1 + sw \tmp2, 0(\tmp1) + +#endif +#endif + .endm + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-adc.h b/arch/mips/src/pic32mx/pic32mx-adc.h new file mode 100644 index 0000000000000000000000000000000000000000..1a29d3af62f4136dbc09826ab925624dad17dbd8 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-adc.h @@ -0,0 +1,244 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-adc.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ADC_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_ADC_CON1_OFFSET 0x0000 /* ADC control register 1 */ +#define PIC32MX_ADC_CON1CLR_OFFSET 0x0004 /* ADC control clear register 1 */ +#define PIC32MX_ADC_CON1SET_OFFSET 0x0008 /* ADC control set register 1 */ +#define PIC32MX_ADC_CON1INV_OFFSET 0x000c /* ADC control invert register 1 */ +#define PIC32MX_ADC_CON2_OFFSET 0x0010 /* ADC control register 2 */ +#define PIC32MX_ADC_CON2CLR_OFFSET 0x0014 /* ADC control clear register 2 */ +#define PIC32MX_ADC_CON2SET_OFFSET 0x0018 /* ADC control set register 2 */ +#define PIC32MX_ADC_CON2INV_OFFSET 0x001c /* ADC control invert register 2 */ +#define PIC32MX_ADC_CON3_OFFSET 0x0020 /* ADC control register 3 */ +#define PIC32MX_ADC_CON3CLR_OFFSET 0x0024 /* ADC control clear register 3 */ +#define PIC32MX_ADC_CON3SET_OFFSET 0x0028 /* ADC control set register 3 */ +#define PIC32MX_ADC_CON3INV_OFFSET 0x002c /* ADC control invert register 3 */ +#define PIC32MX_ADC_CHS_OFFSET 0x0040 /* ADC input pin selection register */ +#define PIC32MX_ADC_CHSCLR_OFFSET 0x0044 /* ADC input pin selection clear register */ +#define PIC32MX_ADC_CHSSET_OFFSET 0x0048 /* ADC input pin selection set register */ +#define PIC32MX_ADC_CHSINV_OFFSET 0x004c /* ADC input pin selection invert register */ +#define PIC32MX_ADC_CSSL_OFFSET 0x0050 /* ADC sequentially scanned input register */ +#define PIC32MX_ADC_CSSLCLR_OFFSET 0x0054 /* ADC sequentially scanned input clear register */ +#define PIC32MX_ADC_CSSLSET_OFFSET 0x0058 /* ADC sequentially scanned input set register */ +#define PIC32MX_ADC_CSSLINV_OFFSET 0x005c /* ADC sequentially scanned input invert register */ +#define PIC32MX_ADC_CFG_OFFSET 0x0060 /* ADC input pin configuration register */ +#define PIC32MX_ADC_CFGCLR_OFFSET 0x0064 /* ADC input pin configuration clear register */ +#define PIC32MX_ADC_CFGSET_OFFSET 0x0068 /* ADC input pin configuration set register */ +#define PIC32MX_ADC_CFGINV_OFFSET 0x006c /* ADC input pin configuration invert register */ + +#define PIC32MX_ADC_BUF_OFFSET(n) (0x0070 + ((n) << 4)) +#define PIC32MX_ADC_BUF0_OFFSET 0x0070 /* ADC result word 0 */ +#define PIC32MX_ADC_BUF1_OFFSET 0x0080 /* ADC result word 1 */ +#define PIC32MX_ADC_BUF2_OFFSET 0x0090 /* ADC result word 2 */ +#define PIC32MX_ADC_BUF3_OFFSET 0x00a0 /* ADC result word 3 */ +#define PIC32MX_ADC_BUF4_OFFSET 0x00b0 /* ADC result word 4 */ +#define PIC32MX_ADC_BUF5_OFFSET 0x00c0 /* ADC result word 5 */ +#define PIC32MX_ADC_BUF6_OFFSET 0x00d0 /* ADC result word 6 */ +#define PIC32MX_ADC_BUF7_OFFSET 0x00e0 /* ADC result word 7 */ +#define PIC32MX_ADC_BUF8_OFFSET 0x00f0 /* ADC result word 8 */ +#define PIC32MX_ADC_BUF9_OFFSET 0x0100 /* ADC result word 9 */ +#define PIC32MX_ADC_BUF10_OFFSET 0x0110 /* ADC result word 10 */ +#define PIC32MX_ADC_BUF11_OFFSET 0x0120 /* ADC result word 11 */ +#define PIC32MX_ADC_BUF12_OFFSET 0x0130 /* ADC result word 12 */ +#define PIC32MX_ADC_BUF13_OFFSET 0x0140 /* ADC result word 13 */ +#define PIC32MX_ADC_BUF14_OFFSET 0x0150 /* ADC result word 14 */ +#define PIC32MX_ADC_BUF15_OFFSET 0x0160 /* ADC result word 15 */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_ADC_CON1 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON1_OFFSET) +#define PIC32MX_ADC_CON1CLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON1CLR_OFFSET) +#define PIC32MX_ADC_CON1SET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON1SET_OFFSET) +#define PIC32MX_ADC_CON1INV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON1INV_OFFSET) +#define PIC32MX_ADC_CON2 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON2_OFFSET) +#define PIC32MX_ADC_CON2CLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON2CLR_OFFSET) +#define PIC32MX_ADC_CON2SET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON2SET_OFFSET) +#define PIC32MX_ADC_CON2INV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON2INV_OFFSET) +#define PIC32MX_ADC_CON3 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON3_OFFSET) +#define PIC32MX_ADC_CON3CLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON3CLR_OFFSET) +#define PIC32MX_ADC_CON3SET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON3SET_OFFSET) +#define PIC32MX_ADC_CON3INV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CON3INV_OFFSET) +#define PIC32MX_ADC_CHS (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CHS_OFFSET) +#define PIC32MX_ADC_CHSCLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CHSCLR_OFFSET) +#define PIC32MX_ADC_CHSSET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CHSSET_OFFSET) +#define PIC32MX_ADC_CHSINV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CHSINV_OFFSET) +#define PIC32MX_ADC_CSSL (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CSSL_OFFSET) +#define PIC32MX_ADC_CSSLCLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CSSLCLR_OFFSET) +#define PIC32MX_ADC_CSSLSET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CSSLSET_OFFSET) +#define PIC32MX_ADC_CSSLINV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CSSLINV_OFFSET) +#define PIC32MX_ADC_CFG (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CFG_OFFSET) +#define PIC32MX_ADC_CFGCLR (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CFGCLR_OFFSET) +#define PIC32MX_ADC_CFGSET (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CFGSET_OFFSET) +#define PIC32MX_ADC_CFGINV (PIC32MX_ADC_K1BASE+PIC32MX_ADC_CFGINV_OFFSET) + +#define PIC32MX_ADC_BUF(n) (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF_OFFSET(n)) +#define PIC32MX_ADC_BUF0 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF0_OFFSET) +#define PIC32MX_ADC_BUF1 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF1_OFFSET) +#define PIC32MX_ADC_BUF2 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF2_OFFSET) +#define PIC32MX_ADC_BUF3 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF3_OFFSET) +#define PIC32MX_ADC_BUF4 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF4_OFFSET) +#define PIC32MX_ADC_BUF5 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF5_OFFSET) +#define PIC32MX_ADC_BUF6 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF6_OFFSET) +#define PIC32MX_ADC_BUF7 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF7_OFFSET) +#define PIC32MX_ADC_BUF8 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF8_OFFSET) +#define PIC32MX_ADC_BUF9 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF9_OFFSET) +#define PIC32MX_ADC_BUF10 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF10_OFFSET) +#define PIC32MX_ADC_BUF11 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF11_OFFSET) +#define PIC32MX_ADC_BUF12 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF12_OFFSET) +#define PIC32MX_ADC_BUF13 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF13_OFFSET) +#define PIC32MX_ADC_BUF14 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF14_OFFSET) +#define PIC32MX_ADC_BUF15 (PIC32MX_ADC_K1BASE+PIC32MX_ADC_BUF15_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* ADC control register 1 */ + +#define ADC_CON1_DONE (1 << 0) /* Bit 0: A/D conversion status */ +#define ADC_CON1_SAMP (1 << 1) /* Bit 1: ADC sample enable */ +#define ADC_CON1_ASAM (1 << 2) /* Bit 2: ADC sample auto start */ +#define ADC_CON1_CLRASAM (1 << 4) /* Bit 4: Stop conversion sequence */ +#define ADC_CON1_SSRC_SHIFT (5) /* Bits 5-7: Conversion trigger source select */ +#define ADC_CON1_SSRC_MASK (7 << ADC_CON1_SSRC_SHIFT) +# define ADC_CON1_SSRC_SAMP (0 << ADC_CON1_SSRC_SHIFT) /* Clearing SAMP starts */ +# define ADC_CON1_SSRC_INT0 (1 << ADC_CON1_SSRC_SHIFT) /* INT0 transition starts */ +# define ADC_CON1_SSRC_TIMER3 (2 << ADC_CON1_SSRC_SHIFT) /* Timer3 match starts */ +# define ADC_CON1_SSRC_COUNT (7 << ADC_CON1_SSRC_SHIFT) /* Internal counter starts */ +#define ADC_CON1_FORM_SHIFT (8) /* Bits 8-10: Data output format */ +#define ADC_CON1_FORM_MASK (7 << ADC_CON1_FORM_SHIFT) +# define ADC_CON1_FORM_UINT16 (0 << ADC_CON1_FORM_SHIFT) /* Integer 16-bit */ +# define ADC_CON1_FORM_SINT16 (1 << ADC_CON1_FORM_SHIFT) /* Signed integer 16-bit */ +# define ADC_CON1_FORM_FRAC16 (2 << ADC_CON1_FORM_SHIFT) /* Fractional 16-bit */ +# define ADC_CON1_FORM_SFRAC16 (3 << ADC_CON1_FORM_SHIFT) /* Signed fractional 16-bit */ +# define ADC_CON1_FORM_UINT32 (4 << ADC_CON1_FORM_SHIFT) /* Integer 32-bit */ +# define ADC_CON1_FORM_SINT32 (5 << ADC_CON1_FORM_SHIFT) /* Signed integer 32-bit */ +# define ADC_CON1_FORM_FRAC32 (6 << ADC_CON1_FORM_SHIFT) /* Fractional 32-bit */ +# define ADC_CON1_FORM_SFRAC32 (7 << ADC_CON1_FORM_SHIFT) /* Signed fractional 32-bit */ +#define ADC_CON1_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define ADC_CON1_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +#define ADC_CON1_ON (1 << 15) /* Bit 14: ADC operating mode */ + +/* ADC control register 2 */ + +#define ADC_CON2_ALTS (1 << 0) /* Bit 0: Alternate input sample mode select */ +#define ADC_CON2_BUFM (1 << 1) /* Bit 1: ADC result buffer mode select */ +#define ADC_CON2_SMPI_SHIFT (2) /* Bits 2-5: Sample/sequences per interrupt */ +#define ADC_CON2_SMPI_MASK (15 << ADC_CON2_SMPI_SHIFT) +# define ADC_CON2_SMPI(n) ((n-1) << ADC_CON2_SMPI_SHIFT) /* Interrupt after nth conversion */ +#define ADC_CON2_BUFS (1 << 7) /* Bit 7: Buffer fill status */ +#define ADC_CON2_CSCNA (1 << 10) /* Bit 10: Scan input selections */ +#define ADC_CON2_OFFCAL (1 << 12) /* Bit 12: Input offset calibration mode select */ +#define ADC_CON2_VCFG_SHIFT (13) /* Bits 13-15: Voltage reference configuation */ +#define ADC_CON2_VCFG_MASK (15 << ADC_CON2_VCFG_SHIFT) +# define ADC_CON2_VCFG_AVDDAVSS (0 << ADC_CON2_VCFG_SHIFT) /* VR+=AVdd VR-=AVss */ +# define ADC_CON2_VCFG_VREFAVSS (1 << ADC_CON2_VCFG_SHIFT) /* VR+=VREF+ VR-=AVss */ +# define ADC_CON2_VCFG_AVDDVREF (2 << ADC_CON2_VCFG_SHIFT) /* VR+=AVdd VR-=VREF- */ +# define ADC_CON2_VCFG_VREFVREF (3 << ADC_CON2_VCFG_SHIFT) /* VR+=VREF+ VR-=VREF- */ + +/* ADC control register 3 */ + +#define ADC_CON3_ADCS_SHIFT (0) /* Bits 0-7: ADC conversion clock select */ +#define ADC_CON3_ADCS_MASK (0xff << ADC_CON3_ADCS_SHIFT) +# define ADC_CON3_ADCS(n) ((((n)>>1)-1) << ADC_CON3_ADCS_SHIFT) /* n*Tpb = Tad, n=2,4,..,512 */ +#define ADC_CON3_SAMC_SHIFT (8) /* Bits 8-12: Auto-sample time bits */ +#define ADC_CON3_SAMC_MASK (31 << ADC_CON3_SAMC_SHIFT) +# define ADC_CON3_SAMC(n) ((n) << ADC_CON3_SAMC_SHIFT) /* Tad = n, n=1..15 */ +#define ADC_CON3_ADRC (1 << 15) /* Bit 15: ADC conversion clock source */ + +/* ADC input pin selection register */ + +#define ADC_CHS_CH0SA_SHIFT (16) /* Bits 16-19: MUX A positive input select */ +#define ADC_CHS_CH0SA_MASK (15 << ADC_CHS_CH0SA_SHIFT) +# define ADC_CHS_CH0SA(n) ((n) << ADC_CHS_CH0SA_SHIFT) /* Channel 0 positive input ANn, n=0..15 */ +#define ADC_CHS_CH0NA (1 << 23) /* Bit 23: MUX A negative input select */ +#define ADC_CHS_CH0SB_SHIFT (24) /* Bits 24-27: MUX B positive input select */ +#define ADC_CHS_CH0SB_MASK (15 << ADC_CHS_CH0SB_SHIFT) +# define ADC_CHS_CH0SB(n) ((n) << ADC_CHS_CH0SB_SHIFT) /* Channel 0 positive input ANn, n=0..15 */ +#define ADC_CHS_CH0NB (1 << 31) /* Bit 31: MUX B negative input select */ + +/* ADC sequentially scanned input register */ + +#define ADC_CSSL(n) (1 << (n)) /* Bit n: xx n, n=0..15 */ + +/* ADC input pin configuration register */ + +#define ADC_CFG(n) (1 << (n)) /* Bit n: xx n, n=0..15 */ + +/* ADC result word 0-15 -- 32-bits of ADC result data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ADC_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-bmx.h b/arch/mips/src/pic32mx/pic32mx-bmx.h new file mode 100644 index 0000000000000000000000000000000000000000..fc46cd81581292eb621fdf29bc8d1421e2bd274b --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-bmx.h @@ -0,0 +1,167 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-bmx.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_BMX_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_BMX_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +#define PIC32MX_BMX_CON_OFFSET 0x0000 /* Configuration Register */ +#define PIC32MX_BMX_CONCLR_OFFSET 0x0004 /* Configuration Clear Register */ +#define PIC32MX_BMX_CONSET_OFFSET 0x0008 /* Configuration Set Register */ +#define PIC32MX_BMX_CONINV_OFFSET 0x000c /* Configuration Invert Register */ +#define PIC32MX_BMX_DKPBA_OFFSET 0x0010 /* Data RAM Kernel Program Base Address Register */ +#define PIC32MX_BMX_DKPBACLR_OFFSET 0x0014 /* Data RAM Kernel Program Base Address Clear Register */ +#define PIC32MX_BMX_DKPBASET_OFFSET 0x0018 /* Data RAM Kernel Program Base Address Set Register */ +#define PIC32MX_BMX_DKPBAINV_OFFSET 0x001c /* Data RAM Kernel Program Base Address Invert Register */ +#define PIC32MX_BMX_DUDBA_OFFSET 0x0020 /* Data RAM User Data Base Address Register */ +#define PIC32MX_BMX_DUDBACLR_OFFSET 0x0024 /* Data RAM User Data Base Address Clear Register */ +#define PIC32MX_BMX_DUDBASET_OFFSET 0x0028 /* Data RAM User Data Base Address Set Register */ +#define PIC32MX_BMX_DUDBAINV_OFFSET 0x002c /* Data RAM User Data Base Address Invert Register */ +#define PIC32MX_BMX_DUPBA_OFFSET 0x0030 /* Data RAM User Program Base Address Register */ +#define PIC32MX_BMX_DUPBACLR_OFFSET 0x0034 /* Data RAM User Program Base Address Clear Register */ +#define PIC32MX_BMX_DUPBASET_OFFSET 0x0038 /* Data RAM User Program Base Address Set Register */ +#define PIC32MX_BMX_DUPBAINV_OFFSET 0x003c /* Data RAM User Program Base Address Invert Register */ +#define PIC32MX_BMX_DRMSZ_OFFSET 0x0040 /* Data RAM Size Register */ +#define PIC32MX_BMX_PUPBA_OFFSET 0x0050 /* Program Flash (PFM) User Program Base Address Register */ +#define PIC32MX_BMX_PUPBACLR_OFFSET 0x0054 /* Program Flash (PFM) User Program Base Address Clear Register */ +#define PIC32MX_BMX_PUPBASET_OFFSET 0x0058 /* Program Flash (PFM) User Program Base Address Set Register */ +#define PIC32MX_BMX_PUPBINVA_OFFSET 0x005c /* Program Flash (PFM) User Program Base Address Invert Register */ +#define PIC32MX_BMX_PFMSZ_OFFSET 0x0060 /* Program Flash Size Register */ +#define PIC32MX_BMX_BOOTSZ_OFFSET 0x0070 /* Boot Flash Size Register */ + +/* Register Addresses ***********************************************************************/ + +#define PIC32MX_BMX_CON (PIC32MX_BMX_K1BASE+PIC32MX_BMX_CON_OFFSET) +#define PIC32MX_BMX_CONCLR (PIC32MX_BMX_K1BASE+PIC32MX_BMX_CONCLR_OFFSET) +#define PIC32MX_BMX_CONSET (PIC32MX_BMX_K1BASE+PIC32MX_BMX_CONSET_OFFSET) +#define PIC32MX_BMX_CONINV (PIC32MX_BMX_K1BASE+PIC32MX_BMX_CONINV_OFFSET) +#define PIC32MX_BMX_DKPBA (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DKPBA_OFFSET) +#define PIC32MX_BMX_DKPBACLR (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DKPBACLR_OFFSET) +#define PIC32MX_BMX_DKPBASET (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DKPBASET_OFFSET) +#define PIC32MX_BMX_DKPBAINV (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DKPBAINV_OFFSET) +#define PIC32MX_BMX_DUDBA (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUDBA_OFFSET) +#define PIC32MX_BMX_DUDBACLR (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUDBACLR_OFFSET) +#define PIC32MX_BMX_DUDBASET (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUDBASET_OFFSET) +#define PIC32MX_BMX_DUDBAINV (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUDBAINV_OFFSET) +#define PIC32MX_BMX_DUPBA (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUPBA_OFFSET) +#define PIC32MX_BMX_DUPBACLR (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUPBACLR_OFFSET) +#define PIC32MX_BMX_DUPBASET (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUPBASET_OFFSET) +#define PIC32MX_BMX_DUPBAINV (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DUPBAINV_OFFSET) +#define PIC32MX_BMX_DRMSZ (PIC32MX_BMX_K1BASE+PIC32MX_BMX_DRMSZ_OFFSET) +#define PIC32MX_BMX_PUPBA (PIC32MX_BMX_K1BASE+PIC32MX_BMX_PUPBA_OFFSET) +#define PIC32MX_BMX_PUPBACLR (PIC32MX_BMX_K1BASE+PIC32MX_BMX_PUPBACLR_OFFSET) +#define PIC32MX_BMX_PUPBASET (PIC32MX_BMX_K1BASE+PIC32MX_BMX_PUPBASET_OFFSET) +#define PIC32MX_BMX_PUPBINVA (PIC32MX_BMX_K1BASE+PIC32MX_BMX_PUPBINVA_OFFSET) +#define PIC32MX_BMX_PFMSZ (PIC32MX_BMX_K1BASE+PIC32MX_BMX_PFMSZ_OFFSET) +#define PIC32MX_BMX_BOOTSZ (PIC32MX_BMX_K1BASE+PIC32MX_BMX_BOOTSZ_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Configuration Register */ + +#define BMX_CON_BMXARB_SHIFT (0) /* Bits 0-2: : Bus matrix arbitration mode */ +#define BMX_CON_BMXARB_MASK (7 << BMX_CON_BMXARB_SHIFT) +# define BMX_CON_BMXARB(n) ((n) << BMX_CON_BMXARB_SHIFT) /* Mode n, n=0,1,2 */ +#define BMX_CON_BMXWSDRM (1 << 6) /* Bit 6: CPU Instruction or data access from data RAM wait state */ +#define BMX_CON_BMXERRIS (1 << 16) /* Bit 16: Bus error from CPU instruction access */ +#define BMX_CON_BMXERRDS (1 << 17) /* Bit 17: Bus error from CPU data access */ +#define BMX_CON_BMXERRDMA (1 << 18) /* Bit 18: Bus error from DMA */ +#define BMX_CON_BMXERRICD (1 << 19) /* Bit 19: Enable bus error from ICD debug unit */ +#define BMX_CON_BMXERRIXI (1 << 20) /* Bit 20: Enable bus error from IXI */ +#define BMX_CON_BMXCHEDMA (1 << 26) /* Bit 26: BMX PFM cacheability for DMA accesses */ + +/* Data RAM Kernel Program Base Address Register */ + +#define BMX_DKPBA_MASK 0x0000ffff /* Bits 0-15 */ + +/* Data RAM User Data Base Address Register */ + +#define BMX_DUDBA_MASK 0x0000ffff /* Bits 0-15 */ + +/* Data RAM User Program Base Address Register */ + +#define BMX_DUPBA_MASK 0x0000ffff /* Bits 0-15 */ + +/* Data RAM Size Register -- 32-bit size value */ + +/* Program Flash (PFM) User Program Base Address Register */ + +#define BMX_PUPBA_MASK 0x000fffff /* Bits 0-19 */ + +/* Program Flash Size Register -- 32-bit size value */ + +/* Boot Flash Size Register -- 32-bit size value */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_BMX_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-can.h b/arch/mips/src/pic32mx/pic32mx-can.h new file mode 100644 index 0000000000000000000000000000000000000000..edc8d1e6b9d176d98f435d17d0a00b8f6c1b6a3d --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-can.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-can.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CAN_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#warning "To be provided" + +/* Register Addresses *******************************************************/ + +#warning "To be provided" + +/* Register Bit-Field Definitions *******************************************/ + +#warning "To be provided" + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CAN_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-che.h b/arch/mips/src/pic32mx/pic32mx-che.h new file mode 100644 index 0000000000000000000000000000000000000000..3ea57056bc547bd49ce411c7d8db5e069822f153 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-che.h @@ -0,0 +1,186 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-che.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CHE_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CHE_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +#define PIC32MX_CHE_CON_OFFSET 0x0000 /* Pre-fetch cache control register */ +#define PIC32MX_CHE_CONCLR_OFFSET 0x0004 /* Pre-fetch cache control clear register */ +#define PIC32MX_CHE_CONSET_OFFSET 0x0008 /* Pre-fetch cache control set register */ +#define PIC32MX_CHE_CONINV_OFFSET 0x000c /* Pre-fetch cache control invert register */ +#define PIC32MX_CHE_ACC_OFFSET 0x0010 /* Pre-fetch cache access register */ +#define PIC32MX_CHE_ACCCLR_OFFSET 0x0014 /* Pre-fetch cache access clear register */ +#define PIC32MX_CHE_ACCSET_OFFSET 0x0018 /* Pre-fetch cache access set register */ +#define PIC32MX_CHE_ACCINV_OFFSET 0x001c /* Pre-fetch cache access invert register */ +#define PIC32MX_CHE_TAG_OFFSET 0x0020 /* Pre-fetch cache tag register */ +#define PIC32MX_CHE_TAGCLR_OFFSET 0x0024 /* Pre-fetch cache tag clear register */ +#define PIC32MX_CHE_TAGSET_OFFSET 0x0028 /* Pre-fetch cache tag set register */ +#define PIC32MX_CHE_TAGINV_OFFSET 0x002c /* Pre-fetch cache tag invert register */ +#define PIC32MX_CHE_MSK_OFFSET 0x0030 /* Pre-fetch cache tag mask register */ +#define PIC32MX_CHE_MSKCLR_OFFSET 0x0034 /* Pre-fetch cache tag mask clear register */ +#define PIC32MX_CHE_MSKSET_OFFSET 0x0038 /* Pre-fetch cache tag mask set register */ +#define PIC32MX_CHE_MSKINV_OFFSET 0x003c /* Pre-fetch cache tag mask invert register */ +#define PIC32MX_CHE_W0_OFFSET 0x0040 /* Cache word 0 register */ +#define PIC32MX_CHE_W1_OFFSET 0x0050 /* Cache word 1 register */ +#define PIC32MX_CHE_W2_OFFSET 0x0060 /* Cache word 2 register */ +#define PIC32MX_CHE_W3_OFFSET 0x0070 /* Cache word 3 register */ +#define PIC32MX_CHE_LRU_OFFSET 0x0080 /* Cache LRU register */ +#define PIC32MX_CHE_HIT_OFFSET 0x0090 /* Cache hit statistics register */ +#define PIC32MX_CHE_MIS_OFFSET 0x00a0 /* Cache miss statistics register */ +#define PIC32MX_CHE_PFABT_OFFSET 0x00c0 /* Pre-fetch cache abort statistics register */ + +/* Register Addresses ***********************************************************************/ + +#define PIC32MX_CHE_CON (PIC32MX_CHE_K1BASE+PIC32MX_CHE_CON_OFFSET) +#define PIC32MX_CHE_CONCLR (PIC32MX_CHE_K1BASE+PIC32MX_CHE_CONCLR_OFFSET) +#define PIC32MX_CHE_CONSET (PIC32MX_CHE_K1BASE+PIC32MX_CHE_CONSET_OFFSET) +#define PIC32MX_CHE_CONINV (PIC32MX_CHE_K1BASE+PIC32MX_CHE_CONINV_OFFSET) +#define PIC32MX_CHE_ACC (PIC32MX_CHE_K1BASE+PIC32MX_CHE_ACC_OFFSET) +#define PIC32MX_CHE_ACCCLR (PIC32MX_CHE_K1BASE+PIC32MX_CHE_ACCCLR_OFFSET) +#define PIC32MX_CHE_ACCSET (PIC32MX_CHE_K1BASE+PIC32MX_CHE_ACCSET_OFFSET) +#define PIC32MX_CHE_ACCINV (PIC32MX_CHE_K1BASE+PIC32MX_CHE_ACCINV_OFFSET) +#define PIC32MX_CHE_TAG (PIC32MX_CHE_K1BASE+PIC32MX_CHE_TAG_OFFSET) +#define PIC32MX_CHE_TAGCLR (PIC32MX_CHE_K1BASE+PIC32MX_CHE_TAGCLR_OFFSET) +#define PIC32MX_CHE_TAGSET (PIC32MX_CHE_K1BASE+PIC32MX_CHE_TAGSET_OFFSET) +#define PIC32MX_CHE_TAGINV (PIC32MX_CHE_K1BASE+PIC32MX_CHE_TAGINV_OFFSET) +#define PIC32MX_CHE_MSK (PIC32MX_CHE_K1BASE+PIC32MX_CHE_MSK_OFFSET) +#define PIC32MX_CHE_MSKCLR (PIC32MX_CHE_K1BASE+PIC32MX_CHE_MSKCLR_OFFSET) +#define PIC32MX_CHE_MSKSET (PIC32MX_CHE_K1BASE+PIC32MX_CHE_MSKSET_OFFSET) +#define PIC32MX_CHE_MSKINV (PIC32MX_CHE_K1BASE+PIC32MX_CHE_MSKINV_OFFSET) +#define PIC32MX_CHE_W0 (PIC32MX_CHE_K1BASE+PIC32MX_CHE_W0_OFFSET) +#define PIC32MX_CHE_W1 (PIC32MX_CHE_K1BASE+PIC32MX_CHE_W1_OFFSET) +#define PIC32MX_CHE_W2 (PIC32MX_CHE_K1BASE+PIC32MX_CHE_W2_OFFSET) +#define PIC32MX_CHE_W3 (PIC32MX_CHE_K1BASE+PIC32MX_CHE_W3_OFFSET) +#define PIC32MX_CHE_LRU (PIC32MX_CHE_K1BASE+PIC32MX_CHE_LRU_OFFSET) +#define PIC32MX_CHE_HIT (PIC32MX_CHE_K1BASE+PIC32MX_CHE_HIT_OFFSET) +#define PIC32MX_CHE_MIS (PIC32MX_CHE_K1BASE+PIC32MX_CHE_MIS_OFFSET) +#define PIC32MX_CHE_PFABT (PIC32MX_CHE_K1BASE+PIC32MX_CHE_PFABT_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Pre-fetch cache control register */ + + +#define CHE_CON_PFMWS_SHIFT (0) /* Bits 0-2: PFM access time (SYSCLK wait states) */ +#define CHE_CON_PFMWS_MASK (7 << CHE_CON_PFMWS_SHIFT) +# define CHE_CON_PFMWS(n) ((n) << CHE_CON_PFMWS_SHIFT) /* n wait states, n=0-7 */ +#define CHE_CON_PREFEN_SHIFT (4) /* Bits 4-5: Predictive pre-fetch cache enable */ +#define CHE_CON_PREFEN_MASK (3 << CHE_CON_PREFEN_SHIFT) +# define CHE_CON_PREFEN_DISABLE (0 << CHE_CON_PREFEN_SHIFT) /* Disable predictive pre-fetch cache */ +# define CHE_CON_PREFEN_CACHE (1 << CHE_CON_PREFEN_SHIFT) /* Enable for cacheable regions only */ +# define CHE_CON_PREFEN_NONCACHE (2 << CHE_CON_PREFEN_SHIFT) /* Enable for non-cacheable regions only */ +# define CHE_CON_PREFEN_ALL (3 << CHE_CON_PREFEN_SHIFT) /* Enable for both regions */ +#define CHE_CON_DCSZ_SHIFT (8) /* Bits 8-9: Data cache size (lines) */ +#define CHE_CON_DCSZ_MASK (3 << CHE_CON_DCSZ_SHIFT) +# define CHE_CON_DCSZ_DISABLE (0 << CHE_CON_DCSZ_SHIFT) /* Disable data caching */ +# define CHE_CON_DCSZ_1LINE (1 << CHE_CON_DCSZ_SHIFT) /* Enable with size of 1 line */ +# define CHE_CON_DCSZ_2LINES (2 << CHE_CON_DCSZ_SHIFT) /* Enable with size of 2 lines */ +# define CHE_CON_DCSZ_4LINES (3 << CHE_CON_DCSZ_SHIFT) /* Enable with size of 4 lines */ +#define CHE_CON_CHECOH (1 << 16) /* Bit 16: Cache coherency setting */ + +/* Pre-fetch cache access register */ + +#define CHE_ACC_CHEIDX_SHIFT (0) /* Bits 0-3: Cache line index */ +#define CHE_ACC_CHEIDX_MASK (15 << CHE_ACC_CHEIDX_SHIFT) +#define CHE_ACC_CHEWEN (1 << 31) /* Bit 31: Cache access enable */ + +/* Pre-fetch cache tag register */ + +#define CHE_TAG_LTYPE (1 << 1) /* Bit 1: Line type */ +#define CHE_TAG_LLOCK (1 << 2) /* Bit 2: Line lock */ +#define CHE_TAG_LVALID (1 << 3) /* Bit 3: Line valid */ +#define CHE_TAG_LTAG_SHIFT (4) /* Bits 4-23: Line tag address */ +#define CHE_TAG_LTAG_MASK (0x000fffff << CHE_TAG_LTAG_SHIFT) +#define CHE_TAG_LTAGBOOT (1 << 31) /* Bit 31: Line tag address boot */ + +/* Pre-fetch cache tag mask register */ + +#define CHE_MSK_SHIFT (5) /* Bits 5-15: Line mask */ +#define CHE_MSK_MASK (0x7ff << CHE_MSK_SHIFT) + +/* Cache word 0-3 register -- 32-bit cache line data */ + +/* Cache LRU register */ + +#define CHE_LRU_MASK 0x01ffffff /* Bits 0-24 */ + +/* Cache hit statistics register -- 32 bit counter value */ + +/* Cache miss statistics register -- 32 bit counter value */ + +/* Pre-fetch cache abort statistics register -- 32 bit counter value */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CHE_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-cm.h b/arch/mips/src/pic32mx/pic32mx-cm.h new file mode 100644 index 0000000000000000000000000000000000000000..7346761e525467bc6df01d1d1a6da6395abc849e --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-cm.h @@ -0,0 +1,141 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-cm.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CM_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +#if CHIP_NCM > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_CM_CON_OFFSET 0x0000 /* Comparator control register */ +#define PIC32MX_CM_CONCLR_OFFSET 0x0004 /* Comparator control clear register */ +#define PIC32MX_CM_CONSET_OFFSET 0x0008 /* Comparator control set register */ +#define PIC32MX_CM_CONINV_OFFSET 0x000c /* Comparator control invert register */ +#define PIC32MX_CM_STAT_OFFSET 0x0060 /* Comparator status register */ +#define PIC32MX_CM_STATCLR_OFFSET 0x0064 /* Comparator status clear register */ +#define PIC32MX_CM_STATSET_OFFSET 0x0068 /* Comparator status set register */ +#define PIC32MX_CM_STATINV_OFFSET 0x006c /* Comparator status invert register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_CM1_CON (PIC32MX_CM1_K1BASE+PIC32MX_CM_CON_OFFSET) +#define PIC32MX_CM1_CONCLR (PIC32MX_CM1_K1BASE+PIC32MX_CM_CONCLR_OFFSET) +#define PIC32MX_CM1_CONSET (PIC32MX_CM1_K1BASE+PIC32MX_CM_CONSET_OFFSET) +#define PIC32MX_CM1_CONINV (PIC32MX_CM1_K1BASE+PIC32MX_CM_CONINV_OFFSET) + +#if CHIP_NCM > 0 +# define PIC32MX_CM2_CON (PIC32MX_CM2_K1BASE+PIC32MX_CM_CON_OFFSET) +# define PIC32MX_CM2_CONCLR (PIC32MX_CM2_K1BASE+PIC32MX_CM_CONCLR_OFFSET) +# define PIC32MX_CM2_CONSET (PIC32MX_CM2_K1BASE+PIC32MX_CM_CONSET_OFFSET) +# define PIC32MX_CM2_CONINV (PIC32MX_CM2_K1BASE+PIC32MX_CM_CONINV_OFFSET) +#endif + +#define PIC32MX_CM_STAT (PIC32MX_CM_K1BASE+PIC32MX_CM_STAT_OFFSET) +#define PIC32MX_CM_STATCLR (PIC32MX_CM1_K1BASE+PIC32MX_CM_STATCLR_OFFSET) +#define PIC32MX_CM_STATSET (PIC32MX_CM1_K1BASE+PIC32MX_CM_STATSET_OFFSET) +#define PIC32MX_CM_STATINV (PIC32MX_CM1_K1BASE+PIC32MX_CM_STATINV_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Comparator control register */ + +#define CM_CON_CCH_SHIFT (0) /* Bits 0-1: Comparator negative input select */ +#define CM_CON_CCH_MASK (3 << CM_CON_CCH_SHIFT) +# define CM_CON_CCH_CXINM (0 << CM_CON_CCH_SHIFT) /* Inverting input connected to CxIN- */ +# define CM_CON_CCH_CXINP (1 << CM_CON_CCH_SHIFT) /* Inverting input connected to CxIN+ */ +# define CM_CON_CCH_CYINP (2 << CM_CON_CCH_SHIFT) /* Inverting input connected to CyIN+ */ +# define CM_CON_CCH_IVREF (3 << CM_CON_CCH_SHIFT) /* Inverting input connected to IVREF */ +#define CM_CON_CREF (1 << 4) /* Bit 4: Comparator positive input configure */ +#define CM_CON_EVPOL_SHIFT (6) /* Bits 6-7: Interrupt event polarity select */ +#define CM_CON_EVPOL_MASK (3 << CM_CON_EVPOL_SHIFT) +# define CM_CON_EVPOL_DISABLED (0 << CM_CON_EVPOL_SHIFT) /* Interrupt disabled */ +# define CM_CON_EVPOL_RISING (1 << CM_CON_EVPOL_SHIFT) /* Interrupt on low-to-high transition */ +# define CM_CON_EVPOL_FALLING (2 << CM_CON_EVPOL_SHIFT) /* Interrupt on high-to-low transition */ +# define CM_CON_EVPOL_BOTH (3 << CM_CON_EVPOL_SHIFT) /* Interrupt on a both transitions */ +#define CM_CON_COUT (1 << 8) /* Bit 8: Comparator output */ +#define CM_CON_CPOL (1 << 13) /* Bit 13: Comparator output inversion */ +#define CM_CON_COE (1 << 14) /* Bit 14: Comparator output enable */ +#define CM_CON_ON (1 << 15) /* Bit 15: Comparator ON */ + +/* Comparator status register */ + +#define CM_STAT_C1OUT (1 << 0) /* Bit 0: Comparator 1 output */ +#define CM_STAT_C2OUT (1 << 1) /* Bit 1: Comparator 2 output */ +#define CM_STAT_SIDL (1 << 13) /* Bit 13: Stop in idle control */ +#define CM_STAT_FRZ (1 << 14) /* Bit 14: Freeze control */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NCM > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CM_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-config.h b/arch/mips/src/pic32mx/pic32mx-config.h new file mode 100644 index 0000000000000000000000000000000000000000..a2cc140ae9ff8ab80e8d1ae7da2cf0ad91eef596 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-config.h @@ -0,0 +1,922 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-config.h + * + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PIC32_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PIC32_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" +#include "pic32mx-uart.h" +#include "pic32mx-int.h" +#include "pic32mx-devcfg.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Interrupt Priorities *************************************************************/ + +#ifndef CONFIG_PIC32MX_CTPRIO /* Core Timer Interrupt */ +# define CONFIG_PIC32MX_CTPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CTPRIO < 4 +# error "CONFIG_PIC32MX_CTPRIO is too small" +#endif +#if CONFIG_PIC32MX_CTPRIO > 31 +# error "CONFIG_PIC32MX_CTPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_CS0PRIO /* Core Software Interrupt 0 */ +# define CONFIG_PIC32MX_CS0PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CS0PRIO < 4 +# error "CONFIG_PIC32MX_CS0PRIO is too small" +#endif +#if CONFIG_PIC32MX_CS0PRIO > 31 +# error "CONFIG_PIC32MX_CS0PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_CS1PRIO /* Core Software Interrupt 1 */ +# define CONFIG_PIC32MX_CS1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CS1PRIO < 4 +# error "CONFIG_PIC32MX_CS1PRIO is too small" +#endif +#if CONFIG_PIC32MX_CS1PRIO > 31 +# error "CONFIG_PIC32MX_CS1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_INT0PRIO /* External interrupt 0 */ +# define CONFIG_PIC32MX_INT0PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_INT0PRIO < 4 +# error "CONFIG_PIC32MX_INT0PRIO is too small" +#endif +#if CONFIG_PIC32MX_INT0PRIO > 31 +# error "CONFIG_PIC32MX_INT0PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_INT1PRIO /* External interrupt 1 */ +# define CONFIG_PIC32MX_INT1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_INT1PRIO < 4 +# error "CONFIG_PIC32MX_INT1PRIO is too small" +#endif +#if CONFIG_PIC32MX_INT1PRIO > 31 +# error "CONFIG_PIC32MX_INT1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_INT2PRIO /* External interrupt 2 */ +# define CONFIG_PIC32MX_INT2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_INT2PRIO < 4 +# error "CONFIG_PIC32MX_INT2PRIO is too small" +#endif +#if CONFIG_PIC32MX_INT2PRIO > 31 +# error "CONFIG_PIC32MX_INT2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_INT3PRIO /* External interrupt 3 */ +# define CONFIG_PIC32MX_INT3PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_INT3PRIO < 4 +# error "CONFIG_PIC32MX_INT3PRIO is too small" +#endif +#if CONFIG_PIC32MX_INT3PRIO > 31 +# error "CONFIG_PIC32MX_INT3PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_INT4PRIO /* External interrupt 4 */ +# define CONFIG_PIC32MX_INT4PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_INT4PRIO < 4 +# error "CONFIG_PIC32MX_INT4PRIO is too small" +#endif +#if CONFIG_PIC32MX_INT4PRIO > 31 +# error "CONFIG_PIC32MX_INT4PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_FSCMPRIO /* Fail-Safe Clock Monitor */ +# define CONFIG_PIC32MX_FSCMPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_FSCMPRIO < 4 +# error "CONFIG_PIC32MX_FSCMPRIO is too small" +#endif +#if CONFIG_PIC32MX_FSCMPRIO > 31 +# error "CONFIG_PIC32MX_FSCMPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_T1PRIO /* Timer 1 (System timer) priority */ +# define CONFIG_PIC32MX_T1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_T1PRIO < 4 +# error "CONFIG_PIC32MX_T1PRIO is too small" +#endif +#if CONFIG_PIC32MX_T1PRIO > 31 +# error "CONFIG_PIC32MX_T1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_T2PRIO /* Timer 2 priority */ +# define CONFIG_PIC32MX_T2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_T2PRIO < 4 +# error "CONFIG_PIC32MX_T2PRIO is too small" +#endif +#if CONFIG_PIC32MX_T2PRIO > 31 +# error "CONFIG_PIC32MX_T2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_T3PRIO /* Timer 3 priority */ +# define CONFIG_PIC32MX_T3PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_T3PRIO < 4 +# error "CONFIG_PIC32MX_T3PRIO is too small" +#endif +#if CONFIG_PIC32MX_T3PRIO > 31 +# error "CONFIG_PIC32MX_T3PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_T4PRIO /* Timer 4 priority */ +# define CONFIG_PIC32MX_T4PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_T4PRIO < 4 +# error "CONFIG_PIC32MX_T4PRIO is too small" +#endif +#if CONFIG_PIC32MX_T4PRIO > 31 +# error "CONFIG_PIC32MX_T4PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_T5PRIO /* Timer 5 priority */ +# define CONFIG_PIC32MX_T5PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_T5PRIO < 4 +# error "CONFIG_PIC32MX_T5PRIO is too small" +#endif +#if CONFIG_PIC32MX_T5PRIO > 31 +# error "CONFIG_PIC32MX_T5PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_IC1PRIO /* Input Capture 1 */ +# define CONFIG_PIC32MX_IC1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_IC1PRIO < 4 +# error "CONFIG_PIC32MX_IC1PRIO is too small" +#endif +#if CONFIG_PIC32MX_IC1PRIO > 31 +# error "CONFIG_PIC32MX_IC1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_IC2PRIO /* Input Capture 2 */ +# define CONFIG_PIC32MX_IC2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_IC2PRIO < 4 +# error "CONFIG_PIC32MX_IC2PRIO is too small" +#endif +#if CONFIG_PIC32MX_IC2PRIO > 31 +# error "CONFIG_PIC32MX_IC2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_IC3PRIO /* Input Capture 3 */ +# define CONFIG_PIC32MX_IC3PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_IC3PRIO < 4 +# error "CONFIG_PIC32MX_IC3PRIO is too small" +#endif +#if CONFIG_PIC32MX_IC3PRIO > 31 +# error "CONFIG_PIC32MX_IC3PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_IC4PRIO /* Input Capture 4 */ +# define CONFIG_PIC32MX_IC4PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_IC4PRIO < 4 +# error "CONFIG_PIC32MX_IC4PRIO is too small" +#endif +#if CONFIG_PIC32MX_IC4PRIO > 31 +# error "CONFIG_PIC32MX_IC4PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_IC5PRIO /* Input Capture 5 */ +# define CONFIG_PIC32MX_IC5PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_IC5PRIO < 4 +# error "CONFIG_PIC32MX_IC5PRIO is too small" +#endif +#if CONFIG_PIC32MX_IC5PRIO > 31 +# error "CONFIG_PIC32MX_IC5PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_OC1PRIO /* Output Compare 1 */ +# define CONFIG_PIC32MX_OC1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_OC1PRIO < 4 +# error "CONFIG_PIC32MX_OC1PRIO is too small" +#endif +#if CONFIG_PIC32MX_OC1PRIO > 31 +# error "CONFIG_PIC32MX_OC1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_OC2PRIO /* Output Compare 2 */ +# define CONFIG_PIC32MX_OC2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_OC2PRIO < 4 +# error "CONFIG_PIC32MX_OC2PRIO is too small" +#endif +#if CONFIG_PIC32MX_OC2PRIO > 31 +# error "CONFIG_PIC32MX_OC2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_OC3PRIO /* Output Compare 3 */ +# define CONFIG_PIC32MX_OC3PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_OC3PRIO < 4 +# error "CONFIG_PIC32MX_OC3PRIO is too small" +#endif +#if CONFIG_PIC32MX_OC3PRIO > 31 +# error "CONFIG_PIC32MX_OC3PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_OC4PRIO /* Output Compare 4 */ +# define CONFIG_PIC32MX_OC4PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_OC4PRIO < 4 +# error "CONFIG_PIC32MX_OC4PRIO is too small" +#endif +#if CONFIG_PIC32MX_OC4PRIO > 31 +# error "CONFIG_PIC32MX_OC4PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_OC5PRIO /* Output Compare 5 */ +# define CONFIG_PIC32MX_OC5PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_OC5PRIO < 4 +# error "CONFIG_PIC32MX_OC5PRIO is too small" +#endif +#if CONFIG_PIC32MX_OC5PRIO > 31 +# error "CONFIG_PIC32MX_OC5PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_I2C1PRIO /* I2C 1 */ +# define CONFIG_PIC32MX_I2C1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_I2C1PRIO < 4 +# error "CONFIG_PIC32MX_I2C1PRIO is too small" +#endif +#if CONFIG_PIC32MX_I2C1PRIO > 31 +# error "CONFIG_PIC32MX_I2C1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_I2C2PRIO /* I2C 2 */ +# define CONFIG_PIC32MX_I2C2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_I2C2PRIO < 4 +# error "CONFIG_PIC32MX_I2C2PRIO is too small" +#endif +#if CONFIG_PIC32MX_I2C2PRIO > 31 +# error "CONFIG_PIC32MX_I2C2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_SPI1PRIO /* SPI 1 */ +# define CONFIG_PIC32MX_SPI1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_SPI1PRIO < 4 +# error "CONFIG_PIC32MX_SPI1PRIO is too small" +#endif +#if CONFIG_PIC32MX_SPI1PRIO > 31 +# error "CONFIG_PIC32MX_SPI1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_SPI2PRIO /* SPI 2 */ +# define CONFIG_PIC32MX_SPI2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_SPI2PRIO < 4 +# error "CONFIG_PIC32MX_SPI2PRIO is too small" +#endif +#if CONFIG_PIC32MX_SPI2PRIO > 31 +# error "CONFIG_PIC32MX_SPI2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_UART1PRIO /* UART 1 */ +# define CONFIG_PIC32MX_UART1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_UART1PRIO < 4 +# error "CONFIG_PIC32MX_UART1PRIO is too small" +#endif +#if CONFIG_PIC32MX_UART1PRIO > 31 +# error "CONFIG_PIC32MX_UART1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_UART2PRIO /* UART 2 */ +# define CONFIG_PIC32MX_UART2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_UART2PRIO < 4 +# error "CONFIG_PIC32MX_UART2PRIO is too small" +#endif +#if CONFIG_PIC32MX_UART2PRIO > 31 +# error "CONFIG_PIC32MX_UART2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_CNPRIO /* Input Change Interrupt */ +# define CONFIG_PIC32MX_CNPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CNPRIO < 4 +# error "CONFIG_PIC32MX_CNPRIO is too small" +#endif +#if CONFIG_PIC32MX_CNPRIO > 31 +# error "CONFIG_PIC32MX_CNPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_ADCPRIO /* ADC1 Convert Done */ +# define CONFIG_PIC32MX_ADCPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_ADCPRIO < 4 +# error "CONFIG_PIC32MX_ADCPRIO is too small" +#endif +#if CONFIG_PIC32MX_ADCPRIO > 31 +# error "CONFIG_PIC32MX_ADCPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_PMPPRIO /* Parallel Master Port */ +# define CONFIG_PIC32MX_PMPPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_PMPPRIO < 4 +# error "CONFIG_PIC32MX_PMPPRIO is too small" +#endif +#if CONFIG_PIC32MX_PMPPRIO > 31 +# error "CONFIG_PIC32MX_PMPPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_CM1PRIO /* Comparator 1 */ +# define CONFIG_PIC32MX_CM1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CM1PRIO < 4 +# error "CONFIG_PIC32MX_CM1PRIO is too small" +#endif +#if CONFIG_PIC32MX_CM1PRIO > 31 +# error "CONFIG_PIC32MX_CM1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_CM2PRIO /* Comparator 2 */ +# define CONFIG_PIC32MX_CM2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_CM2PRIO < 4 +# error "CONFIG_PIC32MX_CM2PRIO is too small" +#endif +#if CONFIG_PIC32MX_CM2PRIO > 31 +# error "CONFIG_PIC32MX_CM2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_FSCMPRIO /* Fail-Safe Clock Monitor */ +# define CONFIG_PIC32MX_FSCMPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_FSCMPRIO < 4 +# error "CONFIG_PIC32MX_FSCMPRIO is too small" +#endif +#if CONFIG_PIC32MX_FSCMPRIO > 31 +# error "CONFIG_PIC32MX_FSCMPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_RTCCPRIO /* Real-Time Clock and Calendar */ +# define CONFIG_PIC32MX_RTCCPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_RTCCPRIO < 4 +# error "CONFIG_PIC32MX_RTCCPRIO is too small" +#endif +#if CONFIG_PIC32MX_RTCCPRIO > 31 +# error "CONFIG_PIC32MX_RTCCPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_DMA0PRIO /* DMA Channel 0 */ +# define CONFIG_PIC32MX_DMA0PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_DMA0PRIO < 4 +# error "CONFIG_PIC32MX_DMA0PRIO is too small" +#endif +#if CONFIG_PIC32MX_DMA0PRIO > 31 +# error "CONFIG_PIC32MX_DMA0PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_DMA1PRIO /* DMA Channel 1 */ +# define CONFIG_PIC32MX_DMA1PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_DMA1PRIO < 4 +# error "CONFIG_PIC32MX_DMA1PRIO is too small" +#endif +#if CONFIG_PIC32MX_DMA1PRIO > 31 +# error "CONFIG_PIC32MX_DMA1PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_DMA2PRIO /* DMA Channel 2 */ +# define CONFIG_PIC32MX_DMA2PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_DMA2PRIO < 4 +# error "CONFIG_PIC32MX_DMA2PRIO is too small" +#endif +#if CONFIG_PIC32MX_DMA2PRIO > 31 +# error "CONFIG_PIC32MX_DMA2PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_DMA3PRIO /* DMA Channel 3 */ +# define CONFIG_PIC32MX_DMA3PRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_DMA3PRIO < 4 +# error "CONFIG_PIC32MX_DMA3PRIO is too small" +#endif +#if CONFIG_PIC32MX_DMA3PRIO > 31 +# error "CONFIG_PIC32MX_DMA3PRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_FCEPRIO /* Flash Control Event */ +# define CONFIG_PIC32MX_FCEPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_FCEPRIO < 4 +# error "CONFIG_PIC32MX_FCEPRIO is too small" +#endif +#if CONFIG_PIC32MX_FCEPRIO > 31 +# error "CONFIG_PIC32MX_FCEPRIO is too large" +#endif + +#ifndef CONFIG_PIC32MX_USBPRIO /* USB */ +# define CONFIG_PIC32MX_USBPRIO (INT_IPC_MID_PRIORITY << 2) +#endif +#if CONFIG_PIC32MX_USBPRIO < 4 +# error "CONFIG_PIC32MX_USBPRIO is too small" +#endif +#if CONFIG_PIC32MX_USBPRIO > 31 +# error "CONFIG_PIC32MX_USBPRIO is too large" +#endif + +/* SYS calls ************************************************************************/ +/* SYS call 1 and 2 are defined for internal use by the PIC32MX port (see + * arch/mips/include/mips32/syscall.h). In addition, SYS call 3 is the return from + * a SYS call in kernel mode. The first four syscall values must, therefore, be + * reserved (0 is not used). + */ + +#ifdef CONFIG_BUILD_KERNEL +# if !defined(CONFIG_SYS_RESERVED) || CONFIG_SYS_RESERVED < 4 +# error "CONFIG_SYS_RESERVED must be defined to be 4 for a kernel build" +# elif CONFIG_SYS_RESERVED > 4 +# warning "CONFIG_SYS_RESERVED should be defined to be 4 for a kernel build" +# endif +#endif + +/* UARTs ****************************************************************************/ +/* Don't enable UARTs not supported by the chip. */ + +#if CHIP_NUARTS < 1 +# undef CONFIG_PIC32MX_UART1 +# undef CONFIG_PIC32MX_UART2 +# undef CONFIG_PIC32MX_UART3 +# undef CONFIG_PIC32MX_UART4 +# undef CONFIG_PIC32MX_UART5 +# undef CONFIG_PIC32MX_UART6 +#elif CHIP_NUARTS < 2 +# undef CONFIG_PIC32MX_UART2 +# undef CONFIG_PIC32MX_UART3 +# undef CONFIG_PIC32MX_UART4 +# undef CONFIG_PIC32MX_UART5 +# undef CONFIG_PIC32MX_UART6 +#elif CHIP_NUARTS < 3 +# undef CONFIG_PIC32MX_UART3 +# undef CONFIG_PIC32MX_UART4 +# undef CONFIG_PIC32MX_UART5 +# undef CONFIG_PIC32MX_UART6 +#elif CHIP_NUARTS < 4 +# undef CONFIG_PIC32MX_UART4 +# undef CONFIG_PIC32MX_UART5 +# undef CONFIG_PIC32MX_UART6 +#elif CHIP_NUARTS < 5 +# undef CONFIG_PIC32MX_UART5 +# undef CONFIG_PIC32MX_UART6 +#elif CHIP_NUARTS < 6 +# undef CONFIG_PIC32MX_UART6 +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_PIC32MX_UART1) || defined(CONFIG_PIC32MX_UART2) || \ + defined(CONFIG_PIC32MX_UART4) || defined(CONFIG_PIC32MX_UART4) || \ + defined(CONFIG_PIC32MX_UART5) || defined(CONFIG_PIC32MX_UART6) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,.. CHIP_NUARTS + */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART3) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART4) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART5) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) && defined(CONFIG_PIC32MX_UART6) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* Device Configuration *************************************************************/ +/* DEVCFG3 */ + +#ifndef CONFIG_PIC32MX_USERID /* User ID */ +# define CONFIG_PIC32MX_USERID 0x584e /* "NX" */ +#endif + +#ifndef CONFIG_PIC32MX_PMDL1WAY /* Peripheral module disable configuration */ +# define CONFIG_PIC32MX_PMDL1WAY 0 +#endif + +#ifndef CONFIG_PIC32MX_IOL1WAY /* Peripheral pin select configuration */ +# define CONFIG_PIC32MX_IOL1WAY 0 +#endif + +#ifndef CONFIG_PIC32MX_SRSSEL /* Shadow register interrupt priority */ +# define CONFIG_PIC32MX_SRSSEL INT_IPC_MIN_PRIORITY +#endif + +/* Unless overridden in the .config file, all pins are in the default setting */ + +#ifndef CONFIG_PIC32MX_FMIIEN /* Ethernet MII enable: 0=RMII 1=MII */ +# define CONFIG_PIC32MX_FMIIEN 1 /* MII enabled */ +#endif + +#ifndef CONFIG_PIC32MX_FETHIO /* Ethernet I/O Pins 0=alternate 1=default */ +# define CONFIG_PIC32MX_FETHIO 1 /* Default Ethernet I/O Pins */ +#endif + +#ifndef CONFIG_PIC32MX_FCANIO /* SCM1 pin C selection */ +# define CONFIG_PIC32MX_FCANIO 1 /* Default CAN I/O Pins */ +#endif + +#ifndef CONFIG_PIC32MX_FSCM1IO /* SCM1 pin C selection */ +# define CONFIG_PIC32MX_FSCM1IO 1 /* Default pin for SCM1C */ +#endif + +/* USB or Ports? */ + +#ifdef CONFIG_PIC32MX_USB +# ifndef CONFIG_PIC32MX_USBIDO /* USB USBID Selection */ +# define CONFIG_PIC32MX_USBIDO 1 /* USBID pin is controlled by the USB module */ +# endif +# ifndef CONFIG_PIC32MX_VBUSIO /* USB VBUSON Selection */ +# define CONFIG_PIC32MX_VBUSIO 1 /* VBUSON pin is controlled by the USB module */ +# endif +#else +# ifndef CONFIG_PIC32MX_USBIDO /* USB USBID Selection */ +# define CONFIG_PIC32MX_USBIDO 0 /* USBID pin is controlled by the Port function */ +# endif +# ifndef CONFIG_PIC32MX_VBUSIO /* USB VBUSON Selection */ +# define CONFIG_PIC32MX_VBUSIO 0 /* VBUSON pin is controlled by the Port function */ +# endif +#endif + +/* DEVCFG2 */ + +#undef CONFIG_PIC32MX_PLLIDIV +#if BOARD_PLL_IDIV == 1 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV1 +#elif BOARD_PLL_IDIV == 2 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV2 +#elif BOARD_PLL_IDIV == 3 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV3 +#elif BOARD_PLL_IDIV == 4 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV4 +#elif BOARD_PLL_IDIV == 5 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV5 +#elif BOARD_PLL_IDIV == 6 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV6 +#elif BOARD_PLL_IDIV == 10 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV10 +#elif BOARD_PLL_IDIV == 12 +# define CONFIG_PIC32MX_PLLIDIV DEVCFG2_FPLLIDIV_DIV12 +#else +# error "Unsupported BOARD_PLL_IDIV" +#endif + +#undef CONFIG_PIC32MX_PLLMULT +#if BOARD_PLL_MULT == 15 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL15 +#elif BOARD_PLL_MULT == 16 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL16 +#elif BOARD_PLL_MULT == 17 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL17 +#elif BOARD_PLL_MULT == 18 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL18 +#elif BOARD_PLL_MULT == 19 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL19 +#elif BOARD_PLL_MULT == 20 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL20 +#elif BOARD_PLL_MULT == 21 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL21 +#elif BOARD_PLL_MULT == 24 +# define CONFIG_PIC32MX_PLLMULT DEVCFG2_FPLLMULT_MUL24 +#else +# error "Unsupported BOARD_PLL_MULT" +#endif + +#undef CONFIG_PIC32MX_UPLLIDIV +#if BOARD_UPLL_IDIV == 1 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV1 +#elif BOARD_UPLL_IDIV == 2 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV2 +#elif BOARD_UPLL_IDIV == 3 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV3 +#elif BOARD_UPLL_IDIV == 4 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV4 +#elif BOARD_UPLL_IDIV == 5 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV5 +#elif BOARD_UPLL_IDIV == 6 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV6 +#elif BOARD_UPLL_IDIV == 10 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV10 +#elif BOARD_UPLL_IDIV == 12 +# define CONFIG_PIC32MX_UPLLIDIV DEVCFG2_FUPLLIDIV_DIV12 +#else +# error "Unsupported BOARD_UPLL_IDIV" +#endif + +#ifndef CONFIG_PIC32MX_FUPLLEN +# if defined(CONFIG_PIC32MX_USBDEV) || defined(CONFIG_PIC32MX_USBHOST) +# define CONFIG_PIC32MX_FUPLLEN 0 /* Enable */ +# else +# define CONFIG_PIC32MX_FUPLLEN 1 /* Bypass and disable */ +# endif +#endif + +#undef CONFIG_PIC32MX_PLLODIV +#if BOARD_PLL_ODIV == 1 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV1 +#elif BOARD_PLL_ODIV == 2 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 4 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 8 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 16 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 32 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 64 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#elif BOARD_PLL_ODIV == 128 +# define CONFIG_PIC32MX_PLLODIV DEVCFG2_FPLLODIV_DIV2 +#else +# error "Unsupported BOARD_PLL_ODIV" +#endif + +/* DEVCFG1 */ + +#ifdef BOARD_SOSC_ENABLE +# define CONFIG_PIC32MX_FSOSCEN DEVCFG1_FSOSCEN +#else +# define CONFIG_PIC32MX_FSOSCEN 0 +#endif + +#ifdef BOARD_SOSC_IESO +# define CONFIG_PIC32MX_IESO DEVCFG1_IESO +#else +# define CONFIG_PIC32MX_IESO 0 +#endif + +#undef CONFIG_PIC32MX_PBDIV +#if BOARD_PBDIV == 1 +# define CONFIG_PIC32MX_PBDIV DEVCFG1_FPBDIV_DIV1 +#elif BOARD_PBDIV == 2 +# define CONFIG_PIC32MX_PBDIV DEVCFG1_FPBDIV_DIV2 +#elif BOARD_PBDIV == 4 +# define CONFIG_PIC32MX_PBDIV DEVCFG1_FPBDIV_DIV4 +#elif BOARD_PBDIV == 8 +# define CONFIG_PIC32MX_PBDIV DEVCFG1_FPBDIV_DIV8 +#else +# error "Unsupported BOARD_PBDIV" +#endif + +#undef CONFIG_PIC32MX_POSCMOD +#if defined(BOARD_POSC_ECMODE) +# define CONFIG_PIC32MX_POSCMOD DEVCFG1_POSCMOD_EC +#elif defined(BOARD_POSC_XTMODE) +# define CONFIG_PIC32MX_POSCMOD DEVCFG1_POSCMOD_XT +#elif defined(BOARD_POSC_HSMODE) +# define CONFIG_PIC32MX_POSCMOD DEVCFG1_POSCMOD_HS +#elif defined(BOARD_POSC_DISABLED) +# define CONFIG_PIC32MX_POSCMOD DEVCFG1_POSCMOD_DIS +#else +# error "Unknown board POSC mode" +#endif + +#undef CONFIG_PIC32MX_FNOSC +#if defined(BOARD_FNOSC_FRC) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_FRC +#elif defined(BOARD_FNOSC_FRCPLL) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_FRCPLL +#elif defined(BOARD_FNOSC_POSC) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_POSC +#elif defined(BOARD_FNOSC_POSCPLL) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_POSCPLL +#elif defined(BOARD_FNOSC_SOSC) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_SOSC +#elif defined(BOARD_FNOSC_LPRC) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_LPRC +#elif defined(BOARD_FNOSC_FRCDIV) +# define CONFIG_PIC32MX_FNOSC DEVCFG1_FNOSC_FRCDIV +#else +# error "Unknown board FNOSC selection" +#endif + +#undef CONFIG_PIC32MX_FCKSM +#if defined(BOARD_POSC_SWITCH) +# if defined(BOARD_POSC_FSCM) +# define CONFIG_PIC32MX_FCKSM DEVCFG1_FCKSM_BOTH +# else +# define CONFIG_PIC32MX_FCKSM DEVCFG1_FCKSM_CSONLY +# endif +#else +# define CONFIG_PIC32MX_FCKSM DEVCFG1_FCKSM_NONE +#endif + +#ifndef CONFIG_PIC32MX_OSCOUT +# define CONFIG_PIC32MX_OSCOUT 0 +#endif + +#undef CONFIG_PIC32MX_WDPS +#if BOARD_WD_PRESCALER == 1 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_1 +#elif BOARD_WD_PRESCALER == 2 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_2 +#elif BOARD_WD_PRESCALER == 4 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_4 +#elif BOARD_WD_PRESCALER == 8 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_8 +#elif BOARD_WD_PRESCALER == 16 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_16 +#elif BOARD_WD_PRESCALER == 32 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_32 +#elif BOARD_WD_PRESCALER == 64 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_64 +#elif BOARD_WD_PRESCALER == 128 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_128 +#elif BOARD_WD_PRESCALER == 256 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_256 +#elif BOARD_WD_PRESCALER == 512 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_512 +#elif BOARD_WD_PRESCALER == 1024 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_1024 +#elif BOARD_WD_PRESCALER == 2048 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_2048 +#elif BOARD_WD_PRESCALER == 4096 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_4096 +#elif BOARD_WD_PRESCALER == 8192 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_8192 +#elif BOARD_WD_PRESCALER == 16384 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_16384 +#elif BOARD_WD_PRESCALER == 32768 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_32768 +#elif BOARD_WD_PRESCALER == 65536 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_65536 +#elif BOARD_WD_PRESCALER == 131072 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_131072 +#elif BOARD_WD_PRESCALER == 262144 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_262144 +#elif BOARD_WD_PRESCALER == 524288 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_524288 +#elif BOARD_WD_PRESCALER == 1048576 +# define CONFIG_PIC32MX_WDPS DEVCFG1_WDTPS_1048576 +#else +# error "Unsupported BOARD_WD_PRESCALER" +#endif + +#undef CONFIG_PIC32MX_WDENABLE +#if BOARD_WD_ENABLE +# define CONFIG_PIC32MX_WDENABLE DEVCFG1_FWDTEN +#else +# define CONFIG_PIC32MX_WDENABLE 0 +#endif + +/* DEVCFG0 */ + +#ifndef CONFIG_PIC32MX_DEBUGGER /* Background Debugger Enable */ +# define CONFIG_PIC32MX_DEBUGGER 3 /* disabled */ +#endif + +#ifndef CONFIG_PIC32MX_ICESEL /* In-Circuit Emulator/Debugger Communication Channel Select */ +# if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define CONFIG_PIC32MX_ICESEL 3 /* Default PGEC1/PGED1 */ +# else +# define CONFIG_PIC32MX_ICESEL 1 /* Default PGEC1/PGED1 */ +# endif +#endif + +#ifndef CONFIG_PIC32MX_PROGFLASHWP /* Program FLASH write protect */ +# if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define CONFIG_PIC32MX_PROGFLASHWP 0x3ff /* Disabled */ +# else +# define CONFIG_PIC32MX_PROGFLASHWP 0xff /* Disabled */ +# endif +#endif + +#ifndef CONFIG_PIC32MX_BOOTFLASHWP +# define CONFIG_PIC32MX_BOOTFLASHWP 1 /* Disabled */ +#endif + +#ifndef CONFIG_PIC32MX_CODEWP +# define CONFIG_PIC32MX_CODEWP 1 /* Disabled */ +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PIC32_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-cvr.h b/arch/mips/src/pic32mx/pic32mx-cvr.h new file mode 100644 index 0000000000000000000000000000000000000000..51ef90d49f81dd3863ea216a00c7aa180b125306 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-cvr.h @@ -0,0 +1,114 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-cvr.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CVR_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CVR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_CVR_CON_OFFSET 0x0000 /* Comparator voltage reference control register */ +#define PIC32MX_CVR_CONCLR_OFFSET 0x0004 /* Comparator voltage reference control clear register */ +#define PIC32MX_CVR_CONSET_OFFSET 0x0008 /* Comparator voltage reference control set register */ +#define PIC32MX_CVR_CONINV_OFFSET 0x000c /* Comparator voltage reference control invert register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_CVR_CON (PIC32MX_CVR_K1BASE+PIC32MX_CVR_CON_OFFSET) +#define PIC32MX_CVR_CONCLR (PIC32MX_CVR_K1BASE+PIC32MX_CVR_CONCLR_OFFSET) +#define PIC32MX_CVR_CONSET (PIC32MX_CVR_K1BASE+PIC32MX_CVR_CONSET_OFFSET) +#define PIC32MX_CVR_CONINV (PIC32MX_CVR_K1BASE+PIC32MX_CVR_CONINV_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Comparator voltage reference control register */ + +#define CVR_CON_CVR_SHIFT (0) /* Bits 0-3: CVREF value selection */ +#define CVR_CON_CVR_MASK (15 << CVR_CON_CVR_SHIFT) +# define CVR_CON_CVR(n) ((n) << CVR_CON_CVR_SHIFT) +#define CVR_CON_CVRSS (1 << 4) /* Bit 4: CVREF source selection */ +#define CVR_CON_CVRR (1 << 5) /* Bit 5: CVREF range selection */ +#define CVR_CON_CVROE (1 << 6) /* Bit 6: CVREFOUT enable */ +#ifdef CHIP_VRFSEL +# define CVR_CON_BGSEL_SHIFT (8) /* Bits 8-9: Band gap reference source */ +# define CVR_CON_BGSEL_MASK (3 << CVR_CON_CVR_SHIFT) +# define CVR_CON_BGSEL_1p2V (0 << CVR_CON_CVR_SHIFT) /* IVREF = 1.2V (nominal) */ +# define CVR_CON_BGSEL_0p6V (1 << CVR_CON_CVR_SHIFT) /* IVREF = 0.6V (nominal) */ +# define CVR_CON_BGSEL_0p2V (2 << CVR_CON_CVR_SHIFT) /* IVREF = 0.2V (nominal) */ +# define CVR_CON_BGSEL_VREF (3 << CVR_CON_CVR_SHIFT) /* VREF = VREF+ */ +# define CVR_CON_VREFSEL (1 << 10) /* Bit 10: Voltage reference select */ +#endif +#define CVR_CON_ON (1 << 15) /* Bit 15: Comparator voltage reference on */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_CVR_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-ddp.h b/arch/mips/src/pic32mx/pic32mx-ddp.h new file mode 100644 index 0000000000000000000000000000000000000000..d7ba7c73186de5e2a3c8430b371e2cc0c16a2760 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-ddp.h @@ -0,0 +1,95 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-ddp.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DDP_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DDP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_DDP_CON_OFFSET 0x0000 /* Control Register for the Diagnostic Module */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_DDP_CON (PIC32MX_DDP_K1BASE+PIC32MX_DDP_CON_OFFSET) + +/* See also the ICESEL, DEBUG, and DEBUG0 in the DEVCFG0 register */ + +/* Register Bit-Field Definitions ***************************************************/ + +/* Control Register for the Diagnostic Module */ + +#define DDP_CON_TROEN (1 << 2) /* Bit 2: Trace output enable */ +#define DDP_CON_JTAGEN (1 << 3) /* Bit 3: JTAG port enable */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DDP_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-decodeirq.c b/arch/mips/src/pic32mx/pic32mx-decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..a9fd338cf6a6d6121874e0e81934890df887ec52 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-decodeirq.c @@ -0,0 +1,200 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-decodeirq.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" + +#include "pic32mx-int.h" +#include "pic32mx.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_decodeirq + * + * Description: + * Called from assembly language logic when an interrupt exception occurs. + * This function decodes and dispatches the interrupt. + * + ****************************************************************************/ + +uint32_t *pic32mx_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + uint32_t *savestate; +#endif + uint32_t regval; + int irq; + + /* If the board supports LEDs, turn on an LED now to indicate that we are + * processing an interrupt. + */ + + board_autoled_on(LED_INIRQ); + + /* Save the current value of g_current_regs (to support nested interrupt + * handling). Then set g_current_regs to regs, indicating that this is + * the interrupted context that is being processed now. + */ + +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + savestate = (uint32_t *)g_current_regs; +#else + DEBUGASSERT(g_current_regs == NULL); +#endif + g_current_regs = regs; + + /* Loop while there are pending interrupts with priority greater than zero */ + + for (; ; ) + { + /* Read the INTSTAT register. This register contains both the priority + * and the interrupt vector number. + */ + + regval = getreg32(PIC32MX_INT_INTSTAT); + if ((regval & INT_INTSTAT_RIPL_MASK) == 0) + { + /* Break out of the loop when the priority is zero meaning that + * there are no further pending interrupts. + */ + + break; + } + + /* Get the vector number. The IRQ numbers have been arranged so that + * vector numbers and NuttX IRQ numbers are the same value. + */ + + irq = ((regval) & INT_INTSTAT_VEC_MASK) >> INT_INTSTAT_VEC_SHIFT; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + } + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + /* Restore the previous value of g_current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + * + * REVISIT: There are task switching issues! You should not enable + * nested interrupts unless you are ready to deal with the complexities + * of fixing nested context switching. The logic here is insufficient. + */ + + g_current_regs = savestate; + if (g_current_regs == NULL) + { + board_autoled_off(LED_INIRQ); + } +#else + g_current_regs = NULL; + board_autoled_off(LED_INIRQ); +#endif + + return regs; +} diff --git a/arch/mips/src/pic32mx/pic32mx-devcfg.h b/arch/mips/src/pic32mx/pic32mx-devcfg.h new file mode 100644 index 0000000000000000000000000000000000000000..506a77ad5e4e7edf860153e4fe4aa35e6efbcae2 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-devcfg.h @@ -0,0 +1,283 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-devcfg.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DEVCFG_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DEVCFG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MX_DEVCFG3_OFFSET 0x0000 /* Device configuration word 3 */ +#define PIC32MX_DEVCFG2_OFFSET 0x0004 /* Device configuration word 2 */ +#define PIC32MX_DEVCFG1_OFFSET 0x0008 /* Device configuration word 1 */ +#define PIC32MX_DEVCFG0_OFFSET 0x000c /* Device configuration word 0 */ + +/* Register Addresses *******************************************************/ + +#define PIC32MX_DEVCFG3 (PIC32MX_DEVCFG_K1BASE+PIC32MX_DEVCFG3_OFFSET) +#define PIC32MX_DEVCFG2 (PIC32MX_DEVCFG_K1BASE+PIC32MX_DEVCFG2_OFFSET) +#define PIC32MX_DEVCFG1 (PIC32MX_DEVCFG_K1BASE+PIC32MX_DEVCFG1_OFFSET) +#define PIC32MX_DEVCFG0 (PIC32MX_DEVCFG_K1BASE+PIC32MX_DEVCFG0_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ + +/* Device configuration word 3 */ + +#define DEVCFG3_USERID_SHIFT (0) /* Bits 0-15: User-defined, readable via ICSP™ and JTAG */ +#define DEVCFG3_USERID_MASK (0xffff << DEVCFG3_USERID_SHIFT) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define DEVCFG3_PMDL1WAY (1 << 28) /* Bit 28: Peripheral Module Disable Configuration */ +# define DEVCFG3_IOL1WAY (1 << 29) /* Bit 29: Peripheral Pin Select Configuration */ +# define DEVCFG3_FUSBIDIO (1 << 30) /* Bit 30: USB USBID selection */ +# define DEVCFG3_FVBUSIO (1 << 31) /* Bit 31: USB VBUSON selection */ +# define DEVCFG3_UNUSED 0x0fff0000 /* Bits 16-28 */ + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define DEVCFG3_UNUSED 0xffff0000 /* Bits 16-31 */ + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define DEVCFG3_FSRSSEL_SHIFT (16) /* Bits 16-18: SRS select */ +# define DEVCFG3_FSRSSEL_MASK (7 << DEVCFG3_FSRSSEL_SHIFT) +# define DEVCFG3_FMIIEN (1 << 24) /* Bit 24: Ethernet MII enable */ +# define DEVCFG3_FETHIO (1 << 25) /* Bit 25: Ethernet I/O pin selection */ +# define DEVCFG3_FCANIO (1 << 26) /* Bit 26: CAN I/O pin selection */ +# define DEVCFG3_FSCM1IO (1 << 29) /* Bit 29: SCM1 pin C selection */ +# define DEVCFG3_FUSBIDIO (1 << 30) /* Bit 30: USB USBID selection */ +# define DEVCFG3_FVBUSIO (1 << 31) /* Bit 31: USB VBUSON selection */ +# define DEVCFG3_UNUSED 0x18f80000 /* Bits 19-23, 27-28 */ + +#endif + +/* Device configuration word 2 */ + +#define DEVCFG2_FPLLIDIV_SHIFT (0) /* Bits 0-2: PLL input divider value */ +#define DEVCFG2_FPLLIDIV_MASK (7 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV1 (0 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV2 (1 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV3 (2 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV4 (3 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV5 (4 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV6 (5 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV10 (6 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV_DIV12 (7 << DEVCFG2_FPLLIDIV_SHIFT) +#define DEVCFG2_FPLLMULT_SHIFT (4) /* Bits 4-6: Initial PLL multiplier value */ +#define DEVCFG2_FPLLMULT_MASK (7 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL15 (0 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL16 (1 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL17 (2 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL18 (3 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL19 (4 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL20 (5 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL21 (6 << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT_MUL24 (7 << DEVCFG2_FPLLMULT_SHIFT) +#define DEVCFG2_FUPLLIDIV_SHIFT (8) /* Bits 8-10: PLL input divider */ +#define DEVCFG2_FUPLLIDIV_MASK (7 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV1 (0 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV2 (1 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV3 (2 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV4 (3 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV5 (4 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV6 (5 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV10 (6 << DEVCFG2_FUPLLIDIV_SHIFT) +# define DEVCFG2_FUPLLIDIV_DIV12 (7 << DEVCFG2_FUPLLIDIV_SHIFT) +#define DEVCFG2_FUPLLEN (1 << 15) /* Bit 15: USB PLL enable */ +#define DEVCFG2_FPLLODIV_SHIFT (16) /* Bits 16-18: Default postscaler for PLL bits */ +#define DEVCFG2_FPLLODIV_MASK (7 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV1 (0 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV2 (1 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV4 (2 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV8 (3 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV16 (4 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV32 (5 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV64 (6 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_DIV256 (7 << DEVCFG2_FPLLODIV_SHIFT) +#define DEVCFG2_UNUSED 0xfff87888 /* Bits 3, 7, 11-14, 19-31 */ + +/* Device configuration word 1 */ + +#define DEVCFG1_FNOSC_SHIFT (0) /* Bits 0-2: Oscillator selection */ +#define DEVCFG1_FNOSC_MASK (7 << DEVCFG1_FNOSC_SHIFT) +# define DEVCFG1_FNOSC_FRC (0 << DEVCFG1_FNOSC_SHIFT) /* FRC oscillator */ +# define DEVCFG1_FNOSC_FRCPLL (1 << DEVCFG1_FNOSC_SHIFT) /* FRC w/PLL module */ +# define DEVCFG1_FNOSC_POSC (2 << DEVCFG1_FNOSC_SHIFT) /* Primary oscillator */ +# define DEVCFG1_FNOSC_POSCPLL (3 << DEVCFG1_FNOSC_SHIFT) /* Primary oscillator w/PLL */ +# define DEVCFG1_FNOSC_SOSC (4 << DEVCFG1_FNOSC_SHIFT) /* Secondary oscillator */ +# define DEVCFG1_FNOSC_LPRC (5 << DEVCFG1_FNOSC_SHIFT) /* Low power RC oscillator */ +# define DEVCFG1_FNOSC_FRCDIV (7 << DEVCFG1_FNOSC_SHIFT) /* FRC oscillator with FRCDIV */ +#define DEVCFG1_FSOSCEN (1 << 5) /* Bit 5: Secondary oscillator (sosc) enable bit */ +#define DEVCFG1_IESO (1 << 7) /* Bit 7: Internal external switch over */ +#define DEVCFG1_POSCMOD_SHIFT (8) /* Bits 8-9: Primary oscillator (posc) configuration */ +#define DEVCFG1_POSCMOD_MASK (3 << DEVCFG1_POSCMOD_SHIFT) +# define DEVCFG1_POSCMOD_EC (0 << DEVCFG1_POSCMOD_SHIFT) /* EC mode */ +# define DEVCFG1_POSCMOD_XT (1 << DEVCFG1_POSCMOD_SHIFT) /* XT mode */ +# define DEVCFG1_POSCMOD_HS (2 << DEVCFG1_POSCMOD_SHIFT) /* HS mode */ +# define DEVCFG1_POSCMOD_DIS (3 << DEVCFG1_POSCMOD_SHIFT) /* Primary Oscillator disabled */ +#define DEVCFG1_OSCIOFNC (1 << 10) /* Bit 10: CLKO (clock-out) enable configuration */ +#define DEVCFG1_FPBDIV_SHIFT (12) /* Bits 12-13: Peripheral bus clock divisor default value */ +#define DEVCFG1_FPBDIV_MASK (3 << DEVCFG1_FPBDIV_SHIFT) +# define DEVCFG1_FPBDIV_DIV1 (0 << DEVCFG1_FPBDIV_SHIFT) /* PBCLK is SYSCLK/1 */ +# define DEVCFG1_FPBDIV_DIV2 (1 << DEVCFG1_FPBDIV_SHIFT) /* PBCLK is SYSCLK/2 */ +# define DEVCFG1_FPBDIV_DIV4 (2 << DEVCFG1_FPBDIV_SHIFT) /* PBCLK is SYSCLK/4 */ +# define DEVCFG1_FPBDIV_DIV8 (3 << DEVCFG1_FPBDIV_SHIFT) /* PBCLK is SYSCLK /8 */ +#define DEVCFG1_FCKSM_SHIFT (14) /* Bits 14-15: Clock switching and monitor selection configuration */ +#define DEVCFG1_FCKSM_MASK (3 << DEVCFG1_FCKSM_SHIFT) +# define DEVCFG1_FCKSM_BOTH (0 << DEVCFG1_FCKSM_SHIFT) /* Clock switching and FSCM are enabled */ +# define DEVCFG1_FCKSM_CSONLY (1 << DEVCFG1_FCKSM_SHIFT) /* Clock switching is enabled, FSCM is disabled */ +# define DEVCFG1_FCKSM_NONE (3 << DEVCFG1_FCKSM_SHIFT) /* Clock switching and FSCM are disabled */ +#define DEVCFG1_WDTPS_SHIFT (16) /* Bits 16-20: WDT postscaler select */ +#define DEVCFG1_WDTPS_MASK (31 << DEVCFG1_WDTPS_SHIFT) +# define DEVCFG1_WDTPS_1 (0 << DEVCFG1_WDTPS_SHIFT) /* 1:1 */ +# define DEVCFG1_WDTPS_2 (1 << DEVCFG1_WDTPS_SHIFT) /* 1:2 */ +# define DEVCFG1_WDTPS_4 (2 << DEVCFG1_WDTPS_SHIFT) /* 1:4 */ +# define DEVCFG1_WDTPS_8 (3 << DEVCFG1_WDTPS_SHIFT) /* 1:8 */ +# define DEVCFG1_WDTPS_16 (4 << DEVCFG1_WDTPS_SHIFT) /* 1:16 */ +# define DEVCFG1_WDTPS_32 (5 << DEVCFG1_WDTPS_SHIFT) /* 1:32 */ +# define DEVCFG1_WDTPS_64 (6 << DEVCFG1_WDTPS_SHIFT) /* 1:64 */ +# define DEVCFG1_WDTPS_128 (7 << DEVCFG1_WDTPS_SHIFT) /* 1:128 */ +# define DEVCFG1_WDTPS_256 (8 << DEVCFG1_WDTPS_SHIFT) /* 1:256 */ +# define DEVCFG1_WDTPS_512 (9 << DEVCFG1_WDTPS_SHIFT) /* 1:512 */ +# define DEVCFG1_WDTPS_1024 (10 << DEVCFG1_WDTPS_SHIFT) /* 1:1024 */ +# define DEVCFG1_WDTPS_2048 (11 << DEVCFG1_WDTPS_SHIFT) /* 1:2048 */ +# define DEVCFG1_WDTPS_4096 (12 << DEVCFG1_WDTPS_SHIFT) /* 1:4096 */ +# define DEVCFG1_WDTPS_8192 (13 << DEVCFG1_WDTPS_SHIFT) /* 1:8192 */ +# define DEVCFG1_WDTPS_16384 (14 << DEVCFG1_WDTPS_SHIFT) /* 1:16384 */ +# define DEVCFG1_WDTPS_32768 (15 << DEVCFG1_WDTPS_SHIFT) /* 1:32768 */ +# define DEVCFG1_WDTPS_65536 (16 << DEVCFG1_WDTPS_SHIFT) /* 1:65536 */ +# define DEVCFG1_WDTPS_131072 (17 << DEVCFG1_WDTPS_SHIFT) /* 1:131072 */ +# define DEVCFG1_WDTPS_262144 (18 << DEVCFG1_WDTPS_SHIFT) /* 1:262144 */ +# define DEVCFG1_WDTPS_524288 (19 << DEVCFG1_WDTPS_SHIFT) /* 1:524288 */ +# define DEVCFG1_WDTPS_1048576 (20 << DEVCFG1_WDTPS_SHIFT) /* 1:1048576 */ +#define DEVCFG1_FWDTEN (1 << 23) /* Bit 23: WDT enable */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define DEVCFG1_WINDIS (1 << 22) /* Bit 22: Windowed watchdog timer enable */ +# define DEVCFG1_FWDTWINSZ_SHIFT (24) /* Bits 24-25: Watchdog Timer Window Size bits */ +# define DEVCFG1_FWDTWINSZ_MASK (3 << DEVCFG1_FWDTWINSZ_SHIFT) +# define DEVCFG1_FWDTWINSZ_25 (0 << DEVCFG1_FWDTWINSZ_SHIFT) /* 25% */ +# define DEVCFG1_FWDTWINSZ_37p5 (1 << DEVCFG1_FWDTWINSZ_SHIFT) /* 37.5% */ +# define DEVCFG1_FWDTWINSZ_50 (2 << DEVCFG1_FWDTWINSZ_SHIFT) /* 50% */ +# define DEVCFG1_FWDTWINSZ_75 (3 << DEVCFG1_FWDTWINSZ_SHIFT) /* 75% */ +# define DEVCFG1_UNUSED 0xfc200858 /* Bits 3-4, 6, 11, 21, 26-31 */ +#else +# define DEVCFG1_UNUSED 0xff600858 /* Bits 3-4, 6, 11, 21-22, 24-31 */ +#endif + +/* Device configuration word 0 */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PWP_CODE(a) REVISIT (((~((a) >> 12)) - 1) & 0x3ff) + +# define DEVCFG0_DEBUG_SHIFT (0) /* Bits 0-1: Background debugger enable */ +# define DEVCFG0_DEBUG_MASK (3 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_DEBUG_ENABLED (1 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_DEBUG_DISABLED (3 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_JTAGEN (1 << 2) /* Bit 2: JTAG enable */ +# define DEVCFG0_ICESEL_SHIFT (3) /* Bits 3-4: Background debugger enable */ +# define DEVCFG0_ICESEL_MASK (3 << DEVCFG0_ICESEL_SHIFT) +# define DEVCFG0_ICESEL_CHAN4 (0 << DEVCFG0_ICESEL_SHIFT) /* PGEC4/PGED4 pair is used */ +# define DEVCFG0_ICESEL_CHAN3 (1 << DEVCFG0_ICESEL_SHIFT) /* PGEC3/PGED3 pair is used */ +# define DEVCFG0_ICESEL_CHAN2 (2 << DEVCFG0_ICESEL_SHIFT) /* PGEC2/PGED2 pair is used */ +# define DEVCFG0_ICESEL_CHAN1 (3 << DEVCFG0_ICESEL_SHIFT) /* PGEC1/PGED1 pair is used */ +# define DEVCFG0_PWP_SHIFT (10) /* Bits 10-15: Program flash write-protect */ +# define DEVCFG0_PWP_MASK (0x3ff << DEVCFG0_PWP_SHIFT) +# define DEVCFG0_PWP_DISABLE (0x3ff << DEVCFG0_PWP_SHIFT) +# define DEVCFG0_PWP(code) ((code) << DEVCFG0_PWP_SHIFT) /* See PWP_CODE above */ +# define DEVCFG0_BWP (1 << 24) /* Bit 24: Boot flash write-protect */ +# define DEVCFG0_CP (1 << 28) /* Bit 28: Code-protect */ +# define DEVCFG0_SIGN (1 << 31) /* Bit 31: Signature */ + +# define DEVCFG0_UNUSED 0x6eff03e0 /* Bits 5-9, 16-23, 25-27, 29-30 */ +#else +# define PWP_CODE(a) (((~((a) >> 12)) - 1) & 0xff) + +# define DEVCFG0_DEBUG_SHIFT (0) /* Bits 0-1: Background debugger enable */ +# define DEVCFG0_DEBUG_MASK (3 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_DEBUG_ENABLED (2 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_DEBUG_DISABLED (3 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_ICESEL (1 << 3) /* Bit 3: ICE/debugger channel select */ +# define DEVCFG0_PWP_SHIFT (12) /* Bits 12-19: Program flash write-protect */ +# define DEVCFG0_PWP_MASK (0xff << DEVCFG0_PWP_SHIFT) +# define DEVCFG0_PWP_DISABLE (0xff << DEVCFG0_PWP_SHIFT) +# define DEVCFG0_PWP(code) ((code) << DEVCFG0_PWP_SHIFT) /* See PWP_CODE above */ +# define DEVCFG0_BWP (1 << 24) /* Bit 24: Boot flash write-protect */ +# define DEVCFG0_CP (1 << 28) /* Bit 28: Code-protect */ +# define DEVCFG0_SIGN (1 << 31) /* Bit 31: Signature */ + +# define DEVCFG0_UNUSED 0x6ef00ff4 /* Bits 4-11, 20-23, 25-27, 29-30 */ +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DEVCFG_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-dma.h b/arch/mips/src/pic32mx/pic32mx-dma.h new file mode 100644 index 0000000000000000000000000000000000000000..e41c80f810610ceddee73d022180808f48f9c8dd --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-dma.h @@ -0,0 +1,697 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-dma.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DMA_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DMA_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +#if CHIP_NDMACH > 0 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ +/* Global DMA Registers */ + +#define PIC32MX_DMA_CON_OFFSET 0x0000 /* DMA Controller Control Register */ +#define PIC32MX_DMA_CONCLR_OFFSET 0x0004 /* DMA Controller Control Clear Register */ +#define PIC32MX_DMA_CONSET_OFFSET 0x0008 /* DMA Controller Control Set Register */ +#define PIC32MX_DMA_CONINV_OFFSET 0x000c /* DMA Controller Control Invert Register */ +#define PIC32MX_DMA_STAT_OFFSET 0x0010 /* DMA Status Register */ +#define PIC32MX_DMA_ADDR_OFFSET 0x0020 /* DMA Address Register */ +#define PIC32MX_DMA_CRCCON_OFFSET 0x0030 /* DMA CRC Control Register */ +#define PIC32MX_DMA_CRCCONCLR_OFFSET 0x0034 /* DMA CRC Control Clear Register */ +#define PIC32MX_DMA_CRCCONSET_OFFSET 0x0038 /* DMA CRC Control Set Register */ +#define PIC32MX_DMA_CRCCONINV_OFFSET 0x003c /* DMA CRC Control Invert Register */ +#define PIC32MX_DMA_CRCDATA_OFFSET 0x0040 /* DMA CRC Data Register */ +#define PIC32MX_DMA_CRCDATACLR_OFFSET 0x0044 /* DMA CRC Data Clear Register */ +#define PIC32MX_DMA_CRCDATASET_OFFSET 0x0048 /* DMA CRC Data Set Register */ +#define PIC32MX_DMA_CRCDATAINV_OFFSET 0x004c /* DMA CRC Data Invert Register */ +#define PIC32MX_DMA_CRCXOR_OFFSET 0x0050 /* DMA CRCXOR Enable Register */ +#define PIC32MX_DMA_CRCXORCLR_OFFSET 0x0054 /* DMA CRCXOR Enable Clear Register */ +#define PIC32MX_DMA_CRCXORSET_OFFSET 0x0058 /* DMA CRCXOR Enable Set Register */ +#define PIC32MX_DMA_CRCXORINV_OFFSET 0x005c /* DMA CRCXOR Enable Invert Register */ + +/* Per-Channel DMA Registers */ + +#define PIC32MX_DMACH_CON_OFFSET 0x0000 /* DMA Channel Control Register */ +#define PIC32MX_DMACH_CONCLR_OFFSET 0x0004 /* DMA Channel Control Clear Register */ +#define PIC32MX_DMACH_CONSET_OFFSET 0x0008 /* DMA Channel Control Set Register */ +#define PIC32MX_DMACH_CONINV_OFFSET 0x000c /* DMA Channel Control Invert Register */ +#define PIC32MX_DMACH_ECON_OFFSET 0x0010 /* DMA Channel Event Control Register */ +#define PIC32MX_DMACH_ECONCLR_OFFSET 0x0014 /* DMA Channel Event Control Clear Register */ +#define PIC32MX_DMACH_ECONSET_OFFSET 0x0018 /* DMA Channel Event Control Set Register */ +#define PIC32MX_DMACH_ECONINV_OFFSET 0x001c /* DMA Channel Event Control Invert Register */ +#define PIC32MX_DMACH_INT_OFFSET 0x0020 /* DMA Channel Interrupt Control Register */ +#define PIC32MX_DMACH_INTCLR_OFFSET 0x0024 /* DMA Channel Interrupt Control Clear Register */ +#define PIC32MX_DMACH_INTSET_OFFSET 0x0028 /* DMA Channel Interrupt Control Set Register */ +#define PIC32MX_DMACH_INTINV_OFFSET 0x002c /* DMA Channel Interrupt Control Invert Register */ +#define PIC32MX_DMACH_SSA_OFFSET 0x0030 /* DMA Channel Source Start Address Register */ +#define PIC32MX_DMACH_SSACLR_OFFSET 0x0034 /* DMA Channel Source Start Address Clear Register */ +#define PIC32MX_DMACH_SSASET_OFFSET 0x0038 /* DMA Channel Source Start Address Set Register */ +#define PIC32MX_DMACH_SSAINV_OFFSET 0x003c /* DMA Channel Source Start Address Invert Register */ +#define PIC32MX_DMACH_DSA_OFFSET 0x0040 /* DMA Channel Destination Start Address Register */ +#define PIC32MX_DMACH_DSACLR_OFFSET 0x0044 /* DMA Channel Destination Start Address Clear Register */ +#define PIC32MX_DMACH_DSASET_OFFSET 0x0048 /* DMA Channel Destination Start Address Set Register */ +#define PIC32MX_DMACH_DSAINV_OFFSET 0x004c /* DMA Channel Destination Start Address Invert Register */ +#define PIC32MX_DMACH_SSIZ_OFFSET 0x0050 /* DMA Channel Source Size Register */ +#define PIC32MX_DMACH_SSIZCLR_OFFSET 0x0054 /* DMA Channel Source Size Clear Register */ +#define PIC32MX_DMACH_SSIZSET_OFFSET 0x0058 /* DMA Channel Source Size Set Register */ +#define PIC32MX_DMACH_SSIZINV_OFFSET 0x005c /* DMA Channel Source Size Invert Register */ +#define PIC32MX_DMACH_DSIZ_OFFSET 0x0060 /* DMA Channel Destination Size Register */ +#define PIC32MX_DMACH_DSIZCLR_OFFSET 0x0064 /* DMA Channel Destination Size Clear Register */ +#define PIC32MX_DMACH_DSIZSET_OFFSET 0x0068 /* DMA Channel Destination Size Set Register */ +#define PIC32MX_DMACH_DSIZINV_OFFSET 0x006c /* DMA Channel Destination Size Invert Register */ +#define PIC32MX_DMACH_SPTR_OFFSET 0x0070 /* DMA Channel Source Pointer Register */ +#define PIC32MX_DMACH_DPTR_OFFSET 0x0080 /* DMA Channel Destination Pointer Register */ +#define PIC32MX_DMACH_CSIZ_OFFSET 0x0090 /* DMA Channel Cell-Size Register */ +#define PIC32MX_DMACH_CSIZCLR_OFFSET 0x0094 /* DMA Channel Cell-Size Clear Register */ +#define PIC32MX_DMACH_CSIZSET_OFFSET 0x0098 /* DMA Channel Cell-Size Set Register */ +#define PIC32MX_DMACH_CSIZINV_OFFSET 0x009c /* DMA Channel Cell-Size Invert Register */ +#define PIC32MX_DMACH_CPTR_OFFSET 0x00a0 /* DMA Channel Cell Pointer Register */ +#define PIC32MX_DMACH_DAT_OFFSET 0x00b0 /* DMA Channel Pattern Data Register */ +#define PIC32MX_DMACH_DATCLR_OFFSET 0x00b4 /* DMA Channel Pattern Data Clear Register */ +#define PIC32MX_DMACH_DATSET_OFFSET 0x00b8 /* DMA Channel Pattern Data Set Register */ +#define PIC32MX_DMACH_DATINV_OFFSET 0x00bc /* DMA Channel Pattern Data Invert Register */ + +/* Register Addresses ***********************************************************************/ +/* Global DMA Registers */ + +#define PIC32MX_DMA_CON (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CON_OFFSET) +#define PIC32MX_DMA_CONCLR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CONCLR_OFFSET) +#define PIC32MX_DMA_CONSET (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CONSET_OFFSET) +#define PIC32MX_DMA_CONINV (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CONINV_OFFSET) +#define PIC32MX_DMA_STAT (PIC32MX_DMA_K1BASE+PIC32MX_DMA_STAT_OFFSET) +#define PIC32MX_DMA_ADDR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_ADDR_OFFSET) +#define PIC32MX_DMA_CRCCON (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCCON_OFFSET) +#define PIC32MX_DMA_CRCCONCLR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCCONCLR_OFFSET) +#define PIC32MX_DMA_CRCCONSET (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCCONSET_OFFSET) +#define PIC32MX_DMA_CRCCONINV (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCCONINV_OFFSET) +#define PIC32MX_DMA_CRCDATA (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCDATA_OFFSET) +#define PIC32MX_DMA_CRCDATACLR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCDATACLR_OFFSET) +#define PIC32MX_DMA_CRCDATASET (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCDATASET_OFFSET) +#define PIC32MX_DMA_CRCDATAINV (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCDATAINV_OFFSET) +#define PIC32MX_DMA_CRCXOR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCXOR_OFFSET) +#define PIC32MX_DMA_CRCXORCLR (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCXORCLR_OFFSET) +#define PIC32MX_DMA_CRCXORSET (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCXORSET_OFFSET) +#define PIC32MX_DMA_CRCXORINV (PIC32MX_DMA_K1BASE+PIC32MX_DMA_CRCXORINV_OFFSET) + +/* Per-Channel DMA Registers */ + +#define PIC32MX_DMACH_CON(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CON_OFFSET) +#define PIC32MX_DMACH_CONCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CONCLR_OFFSET) +#define PIC32MX_DMACH_CONSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CONSET_OFFSET) +#define PIC32MX_DMACH_CONINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CONINV_OFFSET) +#define PIC32MX_DMACH_ECON(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_ECON_OFFSET) +#define PIC32MX_DMACH_ECONCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_ECONCLR_OFFSET) +#define PIC32MX_DMACH_ECONSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_ECONSET_OFFSET) +#define PIC32MX_DMACH_ECONINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_ECONINV_OFFSET) +#define PIC32MX_DMACH_INT(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_INT_OFFSET) +#define PIC32MX_DMACH_INTCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_INTCLR_OFFSET) +#define PIC32MX_DMACH_INTSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_INTSET_OFFSET) +#define PIC32MX_DMACH_INTINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_INTINV_OFFSET) +#define PIC32MX_DMACH_SSA(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSA_OFFSET) +#define PIC32MX_DMACH_SSACLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSACLR_OFFSET) +#define PIC32MX_DMACH_SSASET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSASET_OFFSET) +#define PIC32MX_DMACH_SSAINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSAINV_OFFSET) +#define PIC32MX_DMACH_DSA(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSA_OFFSET) +#define PIC32MX_DMACH_DSACLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSACLR_OFFSET) +#define PIC32MX_DMACH_DSASET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSASET_OFFSET) +#define PIC32MX_DMACH_DSAINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSAINV_OFFSET) +#define PIC32MX_DMACH_SSIZ(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSIZ_OFFSET) +#define PIC32MX_DMACH_SSIZCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSIZCLR_OFFSET) +#define PIC32MX_DMACH_SSIZSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSIZSET_OFFSET) +#define PIC32MX_DMACH_SSIZINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SSIZINV_OFFSET) +#define PIC32MX_DMACH_DSIZ(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSIZ_OFFSET) +#define PIC32MX_DMACH_DSIZCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSIZCLR_OFFSET) +#define PIC32MX_DMACH_DSIZSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSIZSET_OFFSET) +#define PIC32MX_DMACH_DSIZINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DSIZINV_OFFSET) +#define PIC32MX_DMACH_SPTR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_SPTR_OFFSET) +#define PIC32MX_DMACH_DPTR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DPTR_OFFSET) +#define PIC32MX_DMACH_CSIZ(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CSIZ_OFFSET) +#define PIC32MX_DMACH_CSIZCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CSIZCLR_OFFSET) +#define PIC32MX_DMACH_CSIZSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CSIZSET_OFFSET) +#define PIC32MX_DMACH_CSIZINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CSIZINV_OFFSET) +#define PIC32MX_DMACH_CPTR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_CPTR_OFFSET) +#define PIC32MX_DMACH_DAT(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DAT_OFFSET) +#define PIC32MX_DMACH_DATCLR(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DATCLR_OFFSET) +#define PIC32MX_DMACH_DATSET(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DATSET_OFFSET) +#define PIC32MX_DMACH_DATINV(n) (PIC32MX_DMACH_K1BASE(n)+PIC32MX_DMACH_DATINV_OFFSET) + +#if CHIP_NDMACH > 0 +# define PIC32MX_DMACH0_CON (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH0_CONCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH0_CONSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH0_CONINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH0_ECON (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH0_ECONCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH0_ECONSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH0_ECONINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH0_INT (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH0_INTCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH0_INTSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH0_INTINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH0_SSA (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH0_SSACLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH0_SSASET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH0_SSAINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH0_DSA (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH0_DSACLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH0_DSASET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH0_DSAINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH0_SSIZ (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH0_SSIZCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH0_SSIZSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH0_SSIZINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH0_DSIZ (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH0_DSIZCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH0_DSIZSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH0_DSIZINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH0_SPTR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH0_DPTR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH0_CSIZ (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH0_CSIZCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH0_CSIZSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH0_CSIZINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH0_CPTR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH0_DAT (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH0_DATCLR (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH0_DATSET (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH0_DATINV (PIC32MX_DMACH0_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 1 +# define PIC32MX_DMACH1_CON (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH1_CONCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH1_CONSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH1_CONINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH1_ECON (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH1_ECONCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH1_ECONSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH1_ECONINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH1_INT (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH1_INTCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH1_INTSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH1_INTINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH1_SSA (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH1_SSACLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH1_SSASET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH1_SSAINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH1_DSA (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH1_DSACLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH1_DSASET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH1_DSAINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH1_SSIZ (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH1_SSIZCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH1_SSIZSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH1_SSIZINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH1_DSIZ (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH1_DSIZCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH1_DSIZSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH1_DSIZINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH1_SPTR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH1_DPTR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH1_CSIZ (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH1_CSIZCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH1_CSIZSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH1_CSIZINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH1_CPTR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH1_DAT (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH1_DATCLR (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH1_DATSET (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH1_DATINV (PIC32MX_DMACH1_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 2 +# define PIC32MX_DMACH2_CON (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH2_CONCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH2_CONSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH2_CONINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH2_ECON (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH2_ECONCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH2_ECONSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH2_ECONINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH2_INT (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH2_INTCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH2_INTSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH2_INTINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH2_SSA (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH2_SSACLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH2_SSASET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH2_SSAINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH2_DSA (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH2_DSACLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH2_DSASET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH2_DSAINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH2_SSIZ (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH2_SSIZCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH2_SSIZSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH2_SSIZINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH2_DSIZ (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH2_DSIZCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH2_DSIZSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH2_DSIZINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH2_SPTR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH2_DPTR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH2_CSIZ (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH2_CSIZCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH2_CSIZSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH2_CSIZINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH2_CPTR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH2_DAT (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH2_DATCLR (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH2_DATSET (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH2_DATINV (PIC32MX_DMACH2_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) + +#if CHIP_NDMACH > 3 +# define PIC32MX_DMACH3_CON (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH3_CONCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH3_CONSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH3_CONINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH3_ECON (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH3_ECONCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH3_ECONSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH3_ECONINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH3_INT (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH3_INTCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH3_INTSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH3_INTINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH3_SSA (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH3_SSACLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH3_SSASET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH3_SSAINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH3_DSA (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH3_DSACLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH3_DSASET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH3_DSAINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH3_SSIZ (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH3_SSIZCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH3_SSIZSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH3_SSIZINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH3_DSIZ (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH3_DSIZCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH3_DSIZSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH3_DSIZINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH3_SPTR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH3_DPTR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH3_CSIZ (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH3_CSIZCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH3_CSIZSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH3_CSIZINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH3_CPTR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH3_DAT (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH3_DATCLR (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH3_DATSET (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH3_DATINV (PIC32MX_DMACH3_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 4 +# define PIC32MX_DMACH4_CON (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH4_CONCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH4_CONSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH4_CONINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH4_ECON (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH4_ECONCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH4_ECONSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH4_ECONINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH4_INT (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH4_INTCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH4_INTSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH4_INTINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH4_SSA (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH4_SSACLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH4_SSASET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH4_SSAINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH4_DSA (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH4_DSACLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH4_DSASET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH4_DSAINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH4_SSIZ (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH4_SSIZCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH4_SSIZSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH4_SSIZINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH4_DSIZ (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH4_DSIZCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH4_DSIZSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH4_DSIZINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH4_SPTR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH4_DPTR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH4_CSIZ (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH4_CSIZCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH4_CSIZSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH4_CSIZINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH4_CPTR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH4_DAT (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH4_DATCLR (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH4_DATSET (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH4_DATINV (PIC32MX_DMACH4_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 5 +# define PIC32MX_DMACH5_CON (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH5_CONCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH5_CONSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH5_CONINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH5_ECON (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH5_ECONCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH5_ECONSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH5_ECONINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH5_INT (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH5_INTCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH5_INTSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH5_INTINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH5_SSA (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH5_SSACLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH5_SSASET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH5_SSAINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH5_DSA (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH5_DSACLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH5_DSASET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH5_DSAINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH5_SSIZ (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH5_SSIZCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH5_SSIZSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH5_SSIZINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH5_DSIZ (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH5_DSIZCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH5_DSIZSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH5_DSIZINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH5_SPTR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH5_DPTR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH5_CSIZ (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH5_CSIZCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH5_CSIZSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH5_CSIZINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH5_CPTR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH5_DAT (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH5_DATCLR (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH5_DATSET (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH5_DATINV (PIC32MX_DMACH5_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 6 +# define PIC32MX_DMACH6_CON (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH6_CONCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH6_CONSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH6_CONINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH6_ECON (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH6_ECONCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH6_ECONSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH6_ECONINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH6_INT (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH6_INTCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH6_INTSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH6_INTINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH6_SSA (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH6_SSACLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH6_SSASET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH6_SSAINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH6_DSA (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH6_DSACLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH6_DSASET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH6_DSAINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH6_SSIZ (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH6_SSIZCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH6_SSIZSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH6_SSIZINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH6_DSIZ (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH6_DSIZCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH6_DSIZSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH6_DSIZINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH6_SPTR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH6_DPTR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH6_CSIZ (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH6_CSIZCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH6_CSIZSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH6_CSIZINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH6_CPTR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH6_DAT (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH6_DATCLR (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH6_DATSET (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH6_DATINV (PIC32MX_DMACH6_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 7 +# define PIC32MX_DMACH7_CON (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CON_OFFSET) +# define PIC32MX_DMACH7_CONCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CONCLR_OFFSET) +# define PIC32MX_DMACH7_CONSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CONSET_OFFSET) +# define PIC32MX_DMACH7_CONINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CONINV_OFFSET) +# define PIC32MX_DMACH7_ECON (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_ECON_OFFSET) +# define PIC32MX_DMACH7_ECONCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_ECONCLR_OFFSET) +# define PIC32MX_DMACH7_ECONSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_ECONSET_OFFSET) +# define PIC32MX_DMACH7_ECONINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_ECONINV_OFFSET) +# define PIC32MX_DMACH7_INT (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_INT_OFFSET) +# define PIC32MX_DMACH7_INTCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_INTCLR_OFFSET) +# define PIC32MX_DMACH7_INTSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_INTSET_OFFSET) +# define PIC32MX_DMACH7_INTINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_INTINV_OFFSET) +# define PIC32MX_DMACH7_SSA (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSA_OFFSET) +# define PIC32MX_DMACH7_SSACLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSACLR_OFFSET) +# define PIC32MX_DMACH7_SSASET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSASET_OFFSET) +# define PIC32MX_DMACH7_SSAINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSAINV_OFFSET) +# define PIC32MX_DMACH7_DSA (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSA_OFFSET) +# define PIC32MX_DMACH7_DSACLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSACLR_OFFSET) +# define PIC32MX_DMACH7_DSASET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSASET_OFFSET) +# define PIC32MX_DMACH7_DSAINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSAINV_OFFSET) +# define PIC32MX_DMACH7_SSIZ (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSIZ_OFFSET) +# define PIC32MX_DMACH7_SSIZCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSIZCLR_OFFSET) +# define PIC32MX_DMACH7_SSIZSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSIZSET_OFFSET) +# define PIC32MX_DMACH7_SSIZINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SSIZINV_OFFSET) +# define PIC32MX_DMACH7_DSIZ (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSIZ_OFFSET) +# define PIC32MX_DMACH7_DSIZCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSIZCLR_OFFSET) +# define PIC32MX_DMACH7_DSIZSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSIZSET_OFFSET) +# define PIC32MX_DMACH7_DSIZINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DSIZINV_OFFSET) +# define PIC32MX_DMACH7_SPTR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_SPTR_OFFSET) +# define PIC32MX_DMACH7_DPTR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DPTR_OFFSET) +# define PIC32MX_DMACH7_CSIZ (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CSIZ_OFFSET) +# define PIC32MX_DMACH7_CSIZCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CSIZCLR_OFFSET) +# define PIC32MX_DMACH7_CSIZSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CSIZSET_OFFSET) +# define PIC32MX_DMACH7_CSIZINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CSIZINV_OFFSET) +# define PIC32MX_DMACH7_CPTR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_CPTR_OFFSET) +# define PIC32MX_DMACH7_DAT (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DAT_OFFSET) +# define PIC32MX_DMACH7_DATCLR (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DATCLR_OFFSET) +# define PIC32MX_DMACH7_DATSET (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DATSET_OFFSET) +# define PIC32MX_DMACH7_DATINV (PIC32MX_DMACH7_K1BASE+PIC32MX_DMACH_DATINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***********************************************************/ +/* Global DMA Registers */ +/* DMA Controller Control Register */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define DMA_CON_DMABUSY (1 << 11) /* Bit 15: DMA module busy */ +# define DMA_CON_SUSPEND (1 << 12) /* Bit 12: DMA suspend */ +# define DMA_CON_ON (1 << 15) /* Bit 15: DMA on */ + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define DMA_CON_SUSPEND (1 << 12) /* Bit 12: DMA suspend */ +# define DMA_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +# define DMA_CON_FRZ (1 << 14) /* Bit 14: DMA freeze */ +# define DMA_CON_ON (1 << 15) /* Bit 15: DMA on */ + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define DMA_CON_DMABUSY (1 << 11) /* Bit 15: DMA module busy */ +# define DMA_CON_SUSPEND (1 << 12) /* Bit 12: DMA suspend */ +# define DMA_CON_FRZ (1 << 14) /* Bit 14: DMA freeze */ +# define DMA_CON_ON (1 << 15) /* Bit 15: DMA on */ + +#endif + +/* DMA Status Register */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX3) || \ + defined(CHIP_PIC32MX4) + +# define DMA_STAT_DMACH_SHIFT (0) /* Bits 0-1: DMA channel */ +# define DMA_STAT_DMACH_MASK (3 << DMA_STAT_DMACH_SHIFT) +# define DMA_STAT_RDWR (1 << 3) /* Bit 3: Read/write status */ + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define DMA_STAT_DMACH_SHIFT (0) /* Bits 0-2: DMA channel */ +# define DMA_STAT_DMACH_MASK (7 << DMA_STAT_DMACH_SHIFT) +# define DMA_STAT_RDWR (1 << 3) /* Bit 3: Read/write status */ + +#endif + +/* DMA Address Register -- This register contains a 32-bit address value */ + +/* DMA CRC Control Register */ + +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define DMA_CRCCON_CRCCH_SHIFT (0) /* Bits 0-1: CRC channel select */ +# define DMA_CRCCON_CRCCH_MASK (3 << DMA_CRCCON_CRCCH_SHIFT) +# define DMA_CRCCON_CRCAPP (1 << 6) /* Bit 6: CRC append mode */ +# define DMA_CRCCON_CRCEN (1 << 7) /* Bit 7: CRC enable */ +# define DMA_CRCCON_PLEN_SHIFT (8) /* Bits 8-11: Polynomial length */ +# define DMA_CRCCON_PLEN_MASK (15 << DMA_CRCCON_PLEN_SHIFT) + +#elif defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define DMA_CRCCON_CRCCH_SHIFT (0) /* Bits 0-2: CRC channel select */ +# define DMA_CRCCON_CRCCH_MASK (7 << DMA_CRCCON_CRCCH_SHIFT) +# define DMA_CRCCON_CRCTYP (1 << 5) /* Bit 5: CRC type selection */ +# define DMA_CRCCON_CRCAPP (1 << 6) /* Bit 6: CRC append mode */ +# define DMA_CRCCON_CRCEN (1 << 7) /* Bit 7: CRC enable */ +# define DMA_CRCCON_PLEN_SHIFT (8) /* Bits 8-12: Polynomial length */ +# define DMA_CRCCON_PLEN_MASK (31 << DMA_CRCCON_PLEN_SHIFT) +# define DMA_CRCCON_BITO (1 << 24) /* Bit 24: CRC bit order selection */ +# define DMA_CRCCON_WBO (1 << 27) /* Bit 27: CRC write byte order selection */ +# define DMA_CRCCON_BYTO_SHIFT (28) /* Bits 28-29: CRC byte order selection */ +# define DMA_CRCCON_BYTO_MASK (3 << DMA_CRCCON_BYTO_SHIFT) +# define DMA_CRCCON_BYTO_SRCORDER (0 << DMA_CRCCON_BYTO_SHIFT) /* No swapping (i.e., source byte order) */ +# define DMA_CRCCON_BYTO_SWAP32 (1 << DMA_CRCCON_BYTO_SHIFT) /* Endian byte swap on word boundaries */ +# define DMA_CRCCON_BYTO_SWAP32H (2 << DMA_CRCCON_BYTO_SHIFT) /* Swap half-words on word boundaries */ +# define DMA_CRCCON_BYTO_SWAP16 (3 << DMA_CRCCON_BYTO_SHIFT) /* Endian byte swap on half-word boundaries */ + +#endif + +/* DMA CRC Data Register -- 16 or 32-bits of data */ + +/* DMA CRCXOR Enable Register -- 16 or 32-bits of data */ + +/* Per-Channel DMA Registers */ +/* DMA Channel Control Register */ + +#define DMACH_CON_CHPRI_SHIFT (0) /* Bits 0-1: Channel priority */ +#define DMACH_CON_CHPRI_MASK (3 << DMACH_CON_CHPRI_SHIFT) +# define DMACH_CON_CHPRI(n) ((n) << DMACH_CON_CHPRI_SHIFT) +#define DMACH_CON_CHEDET (1 << 2) /* Bit 2: Channel event detected */ +#define DMACH_CON_CHAEN (1 << 4) /* Bit 4: Channel automatic enable */ +#define DMACH_CON_CHCHN (1 << 5) /* Bit 5: Channel chain enable */ +#define DMACH_CON_CHAED (1 << 6) /* Bit 6: Channel allow events if disabled */ +#define DMACH_CON_CHEN (1 << 7) /* Bit 7: Channel enable */ +#define DMACH_CON_CHCHNS (1 << 8) /* Bit 8: Chain channel selection */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define DMACH_CON_CHBUSY (1 << 15) /* Bit 15: Channel busy */ +#endif + +/* DMA Channel Event Control Register */ + +#define DMACH_ECON_AIRQEN (1 << 3) /* Bit 3: Channel abort IRQ enable */ +#define DMACH_ECON_SIRQEN (1 << 4) /* Bit 4: Channel start IRQ enable */ +#define DMACH_ECON_PATEN (1 << 5) /* Bit 5: Channel pattern match abort enable */ +#define DMACH_ECON_CABORT (1 << 6) /* Bit 6: DMA abort transfer */ +#define DMACH_ECON_CFORCE (1 << 7) /* Bit 7: DMA forced transfer */ +#define DMACH_ECON_CHSIRQ_SHIFT (8) /* Bits 8-15: Channel Transfer Start IRQ */ +#define DMACH_ECON_CHSIRQ_MASK (0xff << DMACH_ECON_CHSIRQ_SHIFT) +# define DMACH_ECON_CHSIRQ(n) ((n) << DMACH_ECON_CHSIRQ_SHIFT) /* Interrupt n will initiate a DMA transfer */ +#define DMACH_ECON_CHAIRQ_SHIFT (16) /* Bits 16-23: Channel transfer abort irq */ +#define DMACH_ECON_CHAIRQ_MASK (0xff << DMACH_ECON_CHAIRQ_SHIFT) +# define DMACH_ECON_CHAIRQ(n) ((n) << DMACH_ECON_CHAIRQ_SHIFT) /* Interrupt n will abort any transfers in progress and set CHAIF */ + +/* DMA Channel Interrupt Control Register */ + +#define DMACH_INT_CHERIF (1 << 0) /* Bit 0: Channel address error interrupt flag */ +#define DMACH_INT_CHTAIF (1 << 1) /* Bit 1: Channel transfer abort interrupt flag */ +#define DMACH_INT_CHCCIF (1 << 2) /* Bit 2: Channel cell transfer complete interrupt flag */ +#define DMACH_INT_CHBCIF (1 << 3) /* Bit 3: Channel block transfer complete interrupt flag */ +#define DMACH_INT_CHDHIF (1 << 4) /* Bit 4: Channel destination half full interrupt flag */ +#define DMACH_INT_CHDDIF (1 << 5) /* Bit 5: Channel destination done interrupt flag */ +#define DMACH_INT_CHSHIF (1 << 6) /* Bit 6: Channel source half empty interrupt flag */ +#define DMACH_INT_CHSDIF (1 << 7) /* Bit 7: Channel source done interrupt flag */ +#define DMACH_INT_CHERIE (1 << 16) /* Bit 16: Channel address error interrupt enable */ +#define DMACH_INT_CHTAIE (1 << 17) /* Bit 17: Channel transfer abort interrupt enable */ +#define DMACH_INT_CHCCIE (1 << 18) /* Bit 18: Channel cell transfer complete interrupt enable */ +#define DMACH_INT_CHBCIE (1 << 19) /* Bit 19: Channel block transfer complete interrupt enable */ +#define DMACH_INT_CHDHIE (1 << 20) /* Bit 20: Channel destination half full interrupt enable */ +#define DMACH_INT_CHDDIE (1 << 21) /* Bit 21: Channel destination done interrupt enable */ +#define DMACH_INT_CHSHIE (1 << 22) /* Bit 22: Channel source half empty interrupt enable */ +#define DMACH_INT_CHSDIE (1 << 23) /* Bit 23: Channel source done interrupt enable */ + +/* DMA Channel Source Start Address Register -- This register contains a 32-bit address value */ + +/* DMA Channel Destination Start Address Register -- This register contains a 32-bit address value */ + +/* DMA Channel Source Size Register -- 8 or 16 bits of byte size data */ + +/* DMA Channel Destination Size Register -- 8 or 16 bits of byte size data */ + +/* DMA Channel Source Pointer Register -- 8 or 16 bits of byte index data */ + +/* DMA Channel Destination Pointer Register -- 8 or 16 bits of byte index data */ + +/* DMA Channel Cell-Size Register -- 8 or 16 bits of byte transferred data */ + +/* DMA Channel Cell Pointer Register -- 8 or 16 bits of byte transferred data */ + +/* DMA Channel Pattern Data Register -- 8-bits of pattern data */ + +#define DMACH_DAT_MASK 0xff + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NDMACH > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_DMA_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-ethernet.c b/arch/mips/src/pic32mx/pic32mx-ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..eae7719bd41b0c9f2c9e0e36805b3b502ac56aad --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-ethernet.c @@ -0,0 +1,3218 @@ +/**************************************************************************** + * arch/arm/src/pic32mx/pic32mx_ethernet.c + * + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This driver derives from the PIC32MX Ethernet Driver + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_PIC32MX_ETHERNET) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "pic32mx-config.h" +#include "pic32mx-ethernet.h" +#include "pic32mx.h" + +/* Does this chip have and Ethernet controller? */ + +#if CHIP_NETHERNET > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* CONFIG_PIC32MX_NINTERFACES determines the number of physical interfaces + * that will be supported -- unless it is more than actually supported by the + * hardware! + */ + +#if !defined(CONFIG_PIC32MX_NINTERFACES) || CONFIG_PIC32MX_NINTERFACES > CHIP_NETHERNET +# undef CONFIG_PIC32MX_NINTERFACES +# define CONFIG_PIC32MX_NINTERFACES CHIP_NETHERNET +#endif + +/* The logic here has a few hooks for support for multiple interfaces, but + * that capability is not yet in place (and I won't worry about it until I get + * the first multi-interface PIC32MX). + */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# warning "Only a single ethernet controller is supported" +# undef CONFIG_PIC32MX_NINTERFACES +# define CONFIG_PIC32MX_NINTERFACES 1 +#endif + +/* CONFIG_NET_MULTIBUFFER is required */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER=y is required" +#endif + +/* If IGMP is enabled, then accept multi-cast frames. */ + +#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_PIC32MX_MULTICAST) +# define CONFIG_PIC32MX_MULTICAST 1 +#endif + +/* Use defaults if the number of discriptors is not provided */ + +#ifndef CONFIG_NET_NTXDESC +# define CONFIG_NET_NTXDESC 2 +#endif + +#if CONFIG_NET_NTXDESC > 255 +# error "The number of TX descriptors exceeds the range of a uint8_t index" +#endif + +#ifndef CONFIG_NET_NRXDESC +# define CONFIG_NET_NRXDESC 4 +#endif + +/* Make sure that the size of each buffer is a multiple of 4 bytes. This + * will force alignment of all buffers to 4-byte boundaries (this is needed + * by the queuing logic which will cast each buffer address to a pointer + * type). + */ + +#define PIC32MX_ALIGNED_BUFSIZE ((CONFIG_NET_ETH_MTU + 3) & ~3) + +/* The number of buffers will, then, be one for each descriptor plus one extra */ + +#define PIC32MX_NBUFFERS (CONFIG_NET_NRXDESC + CONFIG_NET_NTXDESC + 1) + +/* Debug Configuration *****************************************************/ +/* Register/Descriptor debug -- can only happen of CONFIG_DEBUG is selected. + * This will probably generate much more output than you care to see. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_REGDEBUG +# undef CONFIG_NET_DESCDEBUG +#endif + +/* CONFIG_NET_DUMPPACKET will dump the contents of each packet to the + * console. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_DUMPPACKET +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define pic32mx_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define pic32mx_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define PIC32MX_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define PIC32MX_TXTIMEOUT (60*CLK_TCK) + +/* PHY timout = 1 minute */ + +#define PIC32MX_MIITIMEOUT (666666) + +/* Ethernet MII clocking. + * + * The clock divider used to create the MII Management Clock (MDC). The MIIM + * module uses the SYSCLK as an input clock. According to the IEEE 802.3 + * Specification this should be no faster than 2.5 MHz. However, some PHYs + * support clock rates up to 12.5 MHz. + * + * The board.h file provides the "ideal" divisor as BOARD_EMAC_MIIM_DIV. We + * pick the closest, actual divisor greater than or equal to this. + */ + +#if BOARD_EMAC_MIIM_DIV <= 4 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV4 +#elif BOARD_EMAC_MIIM_DIV <= 6 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV6 +#elif BOARD_EMAC_MIIM_DIV <= 8 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV8 +#elif BOARD_EMAC_MIIM_DIV <= 10 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV10 +#elif BOARD_EMAC_MIIM_DIV <= 14 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV14 +#elif BOARD_EMAC_MIIM_DIV <= 20 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV20 +#elif BOARD_EMAC_MIIM_DIV <= 40 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV40 +#else +# error "MIIM divider cannot be realized" +#endif + +/* Interrupts ***************************************************************/ + +#define ETH_RXINTS (ETH_INT_RXOVFLW | ETH_INT_RXBUFNA | ETH_INT_RXDONE | ETH_INT_RXBUSE) +#define ETH_TXINTS (ETH_INT_TXABORT | ETH_INT_TXDONE | ETH_INT_TXBUSE) + +/* Misc. Helpers ***********************************************************/ + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->pd_dev.d_buf) + +/* PHYs *********************************************************************/ +/* Select PHY-specific values. Add more PHYs as needed. */ + +#if defined(CONFIG_ETH0_PHY_KS8721) +# define PIC32MX_PHYNAME "KS8721" +# define PIC32MX_PHYID1 MII_PHYID1_KS8721 +# define PIC32MX_PHYID2 MII_PHYID2_KS8721 +# define PIC32MX_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_DP83848C) +# define PIC32MX_PHYNAME "DP83848C" +# define PIC32MX_PHYID1 MII_PHYID1_DP83848C +# define PIC32MX_PHYID2 MII_PHYID2_DP83848C +# define PIC32MX_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_LAN8720) +# define PIC32MX_PHYNAME "LAN8720" +# define PIC32MX_PHYID1 MII_PHYID1_LAN8720 +# define PIC32MX_PHYID2 MII_PHYID2_LAN8720 +# define PIC32MX_HAVE_PHY 1 +#else +# warning "No PHY specified!" +# undef PIC32MX_HAVE_PHY +#endif + +/* These definitions are used to remember the speed/duplex settings */ + +#define PIC32MX_SPEED_MASK 0x01 +#define PIC32MX_SPEED_100 0x01 +#define PIC32MX_SPEED_10 0x00 + +#define PIC32MX_DUPLEX_MASK 0x02 +#define PIC32MX_DUPLEX_FULL 0x02 +#define PIC32MX_DUPLEX_HALF 0x00 + +#define PIC32MX_10BASET_HD (PIC32MX_SPEED_10 | PIC32MX_DUPLEX_HALF) +#define PIC32MX_10BASET_FD (PIC32MX_SPEED_10 | PIC32MX_DUPLEX_FULL) +#define PIC32MX_100BASET_HD (PIC32MX_SPEED_100 | PIC32MX_DUPLEX_HALF) +#define PIC32MX_100BASET_FD (PIC32MX_SPEED_100 | PIC32MX_DUPLEX_FULL) + +#ifdef CONFIG_PHY_SPEED100 +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MX_MODE_DEFLT PIC32MX_100BASET_FD +# else +# define PIC32MX_MODE_DEFLT PIC32MX_100BASET_HD +# endif +#else +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MX_MODE_DEFLT PIC32MX_10BASET_FD +# else +# define PIC32MX_MODE_DEFLT PIC32MX_10BASET_HD +# endif +#endif + +/* Misc Helper Macros *******************************************************/ + +#define PHYS_ADDR(va) ((uint32_t)(va) & 0x1fffffff) +#define VIRT_ADDR(pa) (KSEG1_BASE | (uint32_t)(pa)) + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The pic32mx_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct pic32mx_driver_s +{ + /* The following fields would only be necessary on chips that support + * multiple Ethernet controllers. + */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + uint32_t pd_base; /* Ethernet controller base address */ + int pd_irq; /* Ethernet controller IRQ vector number */ + int pd_irqsrc; /* Ethernet controller IRQ source number */ +#endif + + bool pd_ifup; /* true:ifup false:ifdown */ + bool pd_txpending; /* There is a pending Tx in pd_dev */ + bool pd_polling; /* Avoid concurrent attempts to poll */ + uint8_t pd_mode; /* Speed/duplex */ +#ifdef PIC32MX_HAVE_PHY + uint8_t pd_phyaddr; /* PHY device address */ +#endif + uint8_t pd_txnext; /* Index to the next Tx descriptor */ + uint32_t pd_inten; /* Shadow copy of INTEN register */ + WDOG_ID pd_txpoll; /* TX poll timer */ + WDOG_ID pd_txtimeout; /* TX timeout timer */ + + sq_queue_t pd_freebuffers; /* The free buffer list */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s pd_dev; /* Interface understood by uIP */ + + /* Descriptors and packet buffers */ + + struct pic32mx_rxdesc_s pd_rxdesc[CONFIG_NET_NRXDESC]; + struct pic32mx_txdesc_s pd_txdesc[CONFIG_NET_NTXDESC]; + uint8_t pd_buffers[PIC32MX_NBUFFERS * PIC32MX_ALIGNED_BUFSIZE]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Array of ethernet driver status structures */ + +static struct pic32mx_driver_s g_ethdrvr[CONFIG_PIC32MX_NINTERFACES]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations */ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void pic32mx_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t pic32mx_getreg(uint32_t addr); +static void pic32mx_putreg(uint32_t val, uint32_t addr); +#else +# define pic32mx_getreg(addr) getreg32(addr) +# define pic32mx_putreg(val,addr) putreg32(val,addr) +#endif + +/* Buffer and descriptor management */ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mx_dumptxdesc(struct pic32mx_txdesc_s *txdesc, const char *msg); +static void pic32mx_dumprxdesc(struct pic32mx_rxdesc_s *rxdesc, const char *msg); +#else +# define pic32mx_dumptxdesc(txdesc,msg) +# define pic32mx_dumprxdesc(rxdesc,msg) +#endif + +static inline void pic32mx_bufferinit(struct pic32mx_driver_s *priv); +static uint8_t *pic32mx_allocbuffer(struct pic32mx_driver_s *priv); +static void pic32mx_freebuffer(struct pic32mx_driver_s *priv, uint8_t *buffer); + +static inline void pic32mx_txdescinit(struct pic32mx_driver_s *priv); +static inline void pic32mx_rxdescinit(struct pic32mx_driver_s *priv); +static inline struct pic32mx_txdesc_s *pic32mx_txdesc(struct pic32mx_driver_s *priv); +static inline void pic32mx_txnext(struct pic32mx_driver_s *priv); +static inline void pic32mx_rxreturn(struct pic32mx_rxdesc_s *rxdesc); +static struct pic32mx_rxdesc_s *pic32mx_rxdesc(struct pic32mx_driver_s *priv); + +/* Common TX logic */ + +static int pic32mx_transmit(struct pic32mx_driver_s *priv); +static int pic32mx_txpoll(struct net_driver_s *dev); +static void pic32mx_poll(struct pic32mx_driver_s *priv); +static void pic32mx_timerpoll(struct pic32mx_driver_s *priv); + +/* Interrupt handling */ + +static void pic32mx_response(struct pic32mx_driver_s *priv); +static void pic32mx_rxdone(struct pic32mx_driver_s *priv); +static void pic32mx_txdone(struct pic32mx_driver_s *priv); +static int pic32mx_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void pic32mx_polltimer(int argc, uint32_t arg, ...); +static void pic32mx_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int pic32mx_ifup(struct net_driver_s *dev); +static int pic32mx_ifdown(struct net_driver_s *dev); +static int pic32mx_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int pic32mx_addmac(struct net_driver_s *dev, const uint8_t *mac); +static int pic32mx_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +/* PHY initialization functions */ + +#ifdef PIC32MX_HAVE_PHY +# ifdef CONFIG_NET_REGDEBUG +static void pic32mx_showmii(uint8_t phyaddr, const char *msg); +# else +# define pic32mx_showmii(phyaddr,msg) +# endif + +static void pic32mx_phybusywait(void); +static void pic32mx_phywrite(uint8_t phyaddr, uint8_t regaddr, + uint16_t phydata); +static uint16_t pic32mx_phyread(uint8_t phyaddr, uint8_t regaddr); +static inline int pic32mx_phyreset(uint8_t phyaddr); +# ifdef CONFIG_PHY_AUTONEG +static inline int pic32mx_phyautoneg(uint8_t phyaddr); +# endif +static int pic32mx_phymode(uint8_t phyaddr, uint8_t mode); +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv); +#else +# define pic32mx_phyinit(priv) +#endif + +/* EMAC Initialization functions */ + +static void pic32mx_macmode(uint8_t mode); +static void pic32mx_ethreset(struct pic32mx_driver_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_printreg + * + * Description: + * Print the contents of an PIC32MX register operation + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: pic32mx_checkreg + * + * Description: + * Get the contents of an PIC32MX register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + pic32mx_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + pic32mx_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: pic32mx_getreg + * + * Description: + * Get the contents of an PIC32MX register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static uint32_t pic32mx_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + pic32mx_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: pic32mx_putreg + * + * Description: + * Set the contents of an PIC32MX register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + pic32mx_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Function: pic32mx_dumptxdesc + * + * Description: + * Dump the contents of the specified TX descriptor + * + * Parameters: + * txdesc - Pointer to the TX descriptor to dump + * msg - Annotation for the TX descriptor + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mx_dumptxdesc(struct pic32mx_txdesc_s *txdesc, const char *msg) +{ + lldbg("TX Descriptor [%p]: %s\n", txdesc, msg); + lldbg(" status: %08x\n", txdesc->status); + lldbg(" address: %08x [%08x]\n", txdesc->address, VIRT_ADDR(txdesc->address)); + lldbg(" tsv1: %08x\n", txdesc->tsv1); + lldbg(" tsv2: %08x\n", txdesc->tsv2); + lldbg(" nexted: %08x [%08x]\n", txdesc->nexted, VIRT_ADDR(txdesc->nexted)); +} +#endif + +/**************************************************************************** + * Function: pic32mx_dumprxdesc + * + * Description: + * Dump the contents of the specified RX descriptor + * + * Parameters: + * txdesc - Pointer to the RX descriptor to dump + * msg - Annotation for the RX descriptor + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mx_dumprxdesc(struct pic32mx_rxdesc_s *rxdesc, const char *msg) +{ + lldbg("RX Descriptor [%p]: %s\n", rxdesc, msg); + lldbg(" status: %08x\n", rxdesc->status); + lldbg(" address: %08x [%08x]\n", rxdesc->address, VIRT_ADDR(rxdesc->address)); + lldbg(" rsv1: %08x\n", rxdesc->rsv1); + lldbg(" rsv2: %08x\n", rxdesc->rsv2); + lldbg(" nexted: %08x [%08x]\n", rxdesc->nexted, VIRT_ADDR(rxdesc->nexted)); +} +#endif + +/**************************************************************************** + * Function: pic32mx_bufferinit + * + * Description: + * Initialize the buffers by placing them all in a free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void pic32mx_bufferinit(struct pic32mx_driver_s *priv) +{ + uint8_t *buffer; + int i; + + for (i = 0, buffer = priv->pd_buffers; i < PIC32MX_NBUFFERS; i++) + { + /* Add the buffer to the end of the list of free buffers */ + + sq_addlast((sq_entry_t *)buffer, &priv->pd_freebuffers); + + /* Get the address of the next buffer */ + + buffer += PIC32MX_ALIGNED_BUFSIZE; + } +} + +/**************************************************************************** + * Function: pic32mx_allocbuffer + * + * Description: + * Allocate one buffer by removing it from the free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * Pointer to the allocated buffer (or NULL on failure) + * + ****************************************************************************/ + +static uint8_t *pic32mx_allocbuffer(struct pic32mx_driver_s *priv) +{ + /* Return the next free buffer from the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->pd_freebuffers); +} + +/**************************************************************************** + * Function: pic32mx_freebuffer + * + * Description: + * Free one buffer by returning it to the free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * Pointer to the allocated buffer (or NULL on failure) + * + ****************************************************************************/ + +static void pic32mx_freebuffer(struct pic32mx_driver_s *priv, uint8_t *buffer) +{ + /* Add the buffer to the end of the free buffer list */ + + sq_addlast((sq_entry_t *)buffer, &priv->pd_freebuffers); +} + +/**************************************************************************** + * Function: pic32mx_txdescinit + * + * Description: + * Initialize the EMAC Tx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mx_txdescinit(struct pic32mx_driver_s *priv) +{ + struct pic32mx_txdesc_s *txdesc; + int i; + + /* Assign a buffer to each TX descriptor. For now, just mark each TX + * descriptor as owned by softare andnot linked. + */ + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + /* Point to the next entry */ + + txdesc = &priv->pd_txdesc[i]; + + /* Initialize the buffer. It is idle, owned by software and has + * no buffer assigned to it. + */ + + txdesc->status = TXDESC_STATUS_SOWN | TXDESC_STATUS_NPV; + txdesc->address = 0; + txdesc->tsv1 = 0; + txdesc->tsv2 = 0; + + /* Set the NEXTED pointer. If this is the last descriptor in the + * list, then set the NEXTED pointer back to the first entry, + * creating a ring. + */ + + if (i == (CONFIG_NET_NRXDESC-1)) + { + txdesc->nexted = PHYS_ADDR(priv->pd_txdesc); + } + else + { + txdesc->nexted = PHYS_ADDR(&priv->pd_txdesc[i+1]); + } + + pic32mx_dumptxdesc(txdesc, "Initial"); + } + + /* Position the Tx index to the first descriptor in the ring */ + + priv->pd_txnext = 0; + + /* Update the ETHTXST register with the physical address of the head of + * the TX descriptors list. + */ + + pic32mx_putreg(PHYS_ADDR(priv->pd_txdesc), PIC32MX_ETH_TXST); +} + +/**************************************************************************** + * Function: pic32mx_rxdescinit + * + * Description: + * Initialize the EMAC Rx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mx_rxdescinit(struct pic32mx_driver_s *priv) +{ + struct pic32mx_rxdesc_s *rxdesc; + int i; + + /* Prepare a list of RX descriptors populated with valid buffers for + * messages to be received. Properly update the NPV, EOWN = 1 and + * DATA_BUFFER_ADDRESS fields in the RX descriptors. The + * DATA_BUFFER_ADDRESS should contain the physical address of the + * corresponding RX buffer. + */ + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + /* Point to the next entry */ + + rxdesc = &priv->pd_rxdesc[i]; + + /* Initialize the descriptor. Assign it a buffer and make it ready + * for reception. + */ + + rxdesc->rsv1 = 0; + rxdesc->rsv2 = 0; + rxdesc->address = PHYS_ADDR(pic32mx_allocbuffer(priv)); + rxdesc->status = RXDESC_STATUS_EOWN | TXDESC_STATUS_NPV; + + /* Set the NEXTED pointer. If this is the last descriptor in the + * list, then set the NEXTED pointer back to the first entry, + * creating a ring. + */ + + if (i == (CONFIG_NET_NRXDESC-1)) + { + rxdesc->nexted = PHYS_ADDR(priv->pd_rxdesc); + } + else + { + rxdesc->nexted = PHYS_ADDR(&priv->pd_rxdesc[i+1]); + } + + pic32mx_dumprxdesc(rxdesc, "Initial"); + } + + /* Update the ETHRXST register with the physical address of the head of the + * RX descriptors list. + */ + + pic32mx_putreg(PHYS_ADDR(priv->pd_rxdesc), PIC32MX_ETH_RXST); +} + +/**************************************************************************** + * Function: pic32mx_txdesc + * + * Description: + * Check if the next Tx descriptor is available. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * A pointer to the next available Tx descriptor on success; NULL if the + * next Tx dscriptor is not available. + * + ****************************************************************************/ + +static inline struct pic32mx_txdesc_s *pic32mx_txdesc(struct pic32mx_driver_s *priv) +{ + struct pic32mx_txdesc_s *txdesc; + + /* Get a reference to the next Tx descriptor in the ring */ + + txdesc = &priv->pd_txdesc[priv->pd_txnext]; + + /* Check if the EOWN bit is cleared. If it is, this descriptor is now under + * software control and the message has been transmitted. + * + * Also check that the buffer address is NULL. There is a race condition + * in that the hardware may have completed the transfer, but there may + * still be a valid buffer attached to the Tx descriptor because we have + * not yet processed the Tx done condition. We will know that the Tx + * done condition has been processed when the buffer has been freed and + * reset to zero. + */ + + if ((txdesc->status & TXDESC_STATUS_EOWN) == 0 && txdesc->address == 0) + { + /* Yes.. return a pointer to the descriptor */ + + return txdesc; + } + + /* The next Tx descriptor is still owned by the Ethernet controller.. the + * Tx ring if full and cannot be used now. Return NULL. + */ + + return NULL; +} + +/**************************************************************************** + * Function: pic32mx_txnext + * + * Description: + * After the next Tx descriptor has been given to the hardware, update the + * index to the next Tx descriptor in the ring. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void pic32mx_txnext(struct pic32mx_driver_s *priv) +{ + /* Increment the index to the next Tx descriptor in the ring */ + + int txnext = priv->pd_txnext + 1; + + /* If the new index would go beyond the end of the allocated descriptors + * for the Tx ring, then reset to first descriptor. + */ + + if (txnext >= CONFIG_NET_NTXDESC) + { + txnext = 0; + } + + /* Save the index to the next Tx descriptor */ + + priv->pd_txnext = txnext; +} + +/**************************************************************************** + * Function: pic32mx_rxreturn + * + * Description: + * Return an RX descriptor to the hardware. + * + * Parameters: + * rxdesc - Reference to the RX descriptor to be returned + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mx_rxreturn(struct pic32mx_rxdesc_s *rxdesc) +{ + rxdesc->rsv1 = 0; + rxdesc->rsv2 = 0; + rxdesc->status = RXDESC_STATUS_EOWN | TXDESC_STATUS_NPV; + pic32mx_dumprxdesc(rxdesc, "Returned to hardware"); +} + +/**************************************************************************** + * Function: pic32mx_rxdesc + * + * Description: + * Check if a RX descriptor is owned by the software. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * A pointer to the RX descriptor on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static struct pic32mx_rxdesc_s *pic32mx_rxdesc(struct pic32mx_driver_s *priv) +{ + struct pic32mx_rxdesc_s *rxdesc; + int i; + + /* Inspect the list of RX descriptors to see if the EOWN bit is cleared. + * If it is, this descriptor is now under software control and a message was + * received. Use SOP and EOP to extract the message, use BYTE_COUNT, RXF_RSV, + * RSV and PKT_CHECKSUM to get the message characteristics. + */ + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + /* Check if software owns this descriptor */ + + rxdesc = &priv->pd_rxdesc[i]; + if ((rxdesc->status & RXDESC_STATUS_EOWN) == 0) + { + /* Yes.. return a pointer to the descriptor */ + + return rxdesc; + } + } + + /* All descriptors are owned by the Ethernet controller.. return NULL */ + + return NULL; +} + +/**************************************************************************** + * Function: pic32mx_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mx_transmit(struct pic32mx_driver_s *priv) +{ + struct pic32mx_txdesc_s *txdesc; + uint32_t status; + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + DEBUGASSERT(priv->pd_dev.d_buf != NULL && + priv->pd_dev.d_len < CONFIG_NET_ETH_MTU); + + /* Increment statistics and dump the packet (if so configured) */ + + NETDEV_TXPACKETS(&priv->pd_dev); + pic32mx_dumppacket("Transmit packet", priv->pd_dev.d_buf, priv->pd_dev.d_len); + + /* In order to transmit a message: + * + * The SOP, EOP, DATA_BUFFER_ADDRESS and BYTE_COUNT will be updated when a + * particular message has to be transmitted. The DATA_BUFFER_ADDRESS will + * contain the physical address of the message, the BYTE_COUNT message size. + * SOP and EOP are set depending on how many packets are needed to transmit + * the message. + */ + + /* Find the next available TX descriptor. We are guaranteed that is will + * not fail by upstream logic that assures that a TX packet is available + * before polling uIP. + */ + + txdesc = pic32mx_txdesc(priv); + DEBUGASSERT(txdesc != NULL); + pic32mx_dumptxdesc(txdesc, "Before transmit setup"); + + /* Remove the transmit buffer from the device structure and assign it to + * the TX descriptor. + */ + + txdesc->address = PHYS_ADDR(priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + + /* Set the BYTE_COUNT for in the TX descriptor with the number of bytes + * contained in the buffer. + */ + + status = ((uint32_t)priv->pd_dev.d_len << TXDESC_STATUS_BYTECOUNT_SHIFT); + priv->pd_dev.d_len = 0; + + /* Set EOWN = 1 to indicate that the packet belongs to Ethernet and set both + * SOP and EOP to indicate that the packet both begins and ends with this + * frame. + */ + + status |= (TXDESC_STATUS_EOWN | TXDESC_STATUS_NPV | + TXDESC_STATUS_EOP | TXDESC_STATUS_SOP); + txdesc->status = status; + pic32mx_dumptxdesc(txdesc, "After transmit setup"); + + /* Update the index to the next descriptor to use in the Tx ring */ + + pic32mx_txnext(priv); + + /* Enable the transmission of the message by setting the TXRTS bit (ETHCON1:9). */ + + pic32mx_putreg(ETH_CON1_TXRTS | ETH_CON1_ON, PIC32MX_ETH_CON1SET); + + /* Enable Tx interrupts */ + + priv->pd_inten |= ETH_TXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_IEN); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->pd_txtimeout, PIC32MX_TXTIMEOUT, pic32mx_txtimeout, + 1, (uint32_t)priv); + + return OK; +} + +/**************************************************************************** + * Function: pic32mx_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mx_txpoll(struct net_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + int ret = OK; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) +#endif + { + arp_out(&priv->pd_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->pd_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send this packet. In this context, we know that there is space for + * at least one more packet in the descriptor list. + */ + + pic32mx_transmit(priv); + + /* Check if the next TX descriptor is available. If not, return a + * non-zero value to terminate the poll. + */ + + if (pic32mx_txdesc(priv) == NULL) + { + /* There are no more TX descriptors/buffers available.. stop the poll */ + + return -EAGAIN; + } + + /* Get the next Tx buffer needed in order to continue the poll */ + + priv->pd_dev.d_buf = pic32mx_allocbuffer(priv); + if (priv->pd_dev.d_buf == NULL) + { + /* We have no more buffers available for the nex Tx.. stop the poll */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: pic32mx_poll + * + * Description: + * Perform the uIP poll. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pic32mx_poll(struct pic32mx_driver_s *priv) +{ + /* Is there already a poll in progress. This happens, for example, when + * debugging output is enabled. Interrupts may be re-enabled while debug + * output is performed and a timer expiration could attempt a concurrent + * poll. + */ + + if (!priv->pd_polling) + { + /* Assign a buffer for the poll */ + + DEBUGASSERT(priv->pd_dev.d_buf == NULL); + priv->pd_dev.d_buf = pic32mx_allocbuffer(priv); + if (priv->pd_dev.d_buf != NULL) + { + /* And perform the poll */ + + priv->pd_polling = true; + (void)devif_poll(&priv->pd_dev, pic32mx_txpoll); + + /* Free any buffer left attached after the poll */ + + if (priv->pd_dev.d_buf != NULL) + { + pic32mx_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + priv->pd_polling = false; + } + } + +} + +/**************************************************************************** + * Function: pic32mx_timerpoll + * + * Description: + * Perform the uIP timer poll. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pic32mx_timerpoll(struct pic32mx_driver_s *priv) +{ + /* Is there already a poll in progress. This happens, for example, when + * debugging output is enabled. Interrupts may be re-enabled while debug + * output is performed and a timer expiration could attempt a concurrent + * poll. + */ + + if (!priv->pd_polling) + { + DEBUGASSERT(priv->pd_dev.d_buf == NULL); + priv->pd_dev.d_buf = pic32mx_allocbuffer(priv); + if (priv->pd_dev.d_buf != NULL) + { + /* And perform the poll */ + + priv->pd_polling = true; + (void)devif_timer(&priv->pd_dev, pic32mx_txpoll); + + /* Free any buffer left attached after the poll */ + + if (priv->pd_dev.d_buf != NULL) + { + pic32mx_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + priv->pd_polling = false; + } + } +} + +/**************************************************************************** + * Function: pic32mx_response + * + * Description: + * While processing an RxDone event, higher logic decides to send a packet, + * possibly a response to the incoming packet (but probably not, in reality). + * However, since the Rx and Tx operations are decoupled, there is no + * guarantee that there will be a Tx descriptor available at that time. + * This function will perform that check and, if no Tx descriptor is + * available, this function will (1) stop incoming Rx processing (bad), and + * (2) hold the outgoing packet in a pending state until the next Tx + * interrupt occurs. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_response(struct pic32mx_driver_s *priv) +{ + struct pic32mx_txdesc_s *txdesc; + + /* Check if the next TX descriptor is available. */ + + txdesc = pic32mx_txdesc(priv); + if (txdesc != NULL) + { + /* Yes.. queue the packet now. */ + + pic32mx_transmit(priv); + } + else + { + /* No.. mark the Tx as pending and halt further Rx interrupts */ + + DEBUGASSERT((priv->pd_inten & ETH_INT_TXDONE) != 0); + + priv->pd_txpending = true; + priv->pd_inten &= ~ETH_RXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_IEN); + } +} + +/**************************************************************************** + * Function: pic32mx_rxdone + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_rxdone(struct pic32mx_driver_s *priv) +{ + struct pic32mx_rxdesc_s *rxdesc; + + /* Loop while there are incoming packets to be processed, that is, while + * the producer index is not equal to the consumer index. + */ + + for (; ; ) + { + /* Check if any RX descriptor has the EOWN bit cleared meaning that the + * this descriptor is now under software control and a message was + * received. + */ + + rxdesc = pic32mx_rxdesc(priv); + if (rxdesc == NULL) + { + /* All RX descriptors are owned by the Ethernet controller... we + * are finished here. + */ + + return; + } + pic32mx_dumprxdesc(rxdesc, "RX Complete"); + + /* Update statistics */ + + NETDEV_RXPACKETS(&priv->pd_dev); + + /* Get the packet length */ + + priv->pd_dev.d_len = (rxdesc->rsv2 & RXDESC_RSV2_BYTECOUNT_MASK) >> RXDESC_RSV2_BYTECOUNT_SHIFT; + + /* Check for errors */ + + if ((rxdesc->rsv2 & RXDESC_RSV2_OK) == 0) + { + nlldbg("ERROR. rsv1: %08x rsv2: %08x\n", rxdesc->rsv1, rxdesc->rsv2); + NETDEV_RXERRORS(&priv->pd_dev); + pic32mx_rxreturn(rxdesc); + } + + /* If the packet length is greater then the buffer, then we cannot accept + * the packet. Also, since the DMA packet buffers are set up to + * be the same size as our max packet size, any fragments also + * imply that the packet is too big. + */ + + else if (priv->pd_dev.d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("Too big. packet length: %d rxdesc: %08x\n", + priv->pd_dev.d_len, rxdesc->status); + NETDEV_RXERRORS(&priv->pd_dev); + pic32mx_rxreturn(rxdesc); + } + + /* We don't have any logic here for reassembling packets from fragments. */ + + else if ((rxdesc->status & (RXDESC_STATUS_EOP | RXDESC_STATUS_SOP)) != + (RXDESC_STATUS_EOP | RXDESC_STATUS_SOP)) + { + nlldbg("Fragment. packet length: %d rxdesc: %08x\n", priv->pd_dev.d_len, rxdesc->status); + NETDEV_RXFRAGMENTS(&priv->pd_dev); + pic32mx_rxreturn(rxdesc); + } + else + { + uint8_t *rxbuffer; + + /* Get the Rx buffer address from the Rx descriptor */ + + priv->pd_dev.d_buf = (uint8_t *)VIRT_ADDR(rxdesc->address); + DEBUGASSERT(priv->pd_dev.d_buf != NULL); + + /* Replace the buffer in the RX descriptor with a new one */ + + rxbuffer = pic32mx_allocbuffer(priv); + DEBUGASSERT(rxbuffer != NULL); + rxdesc->address = PHYS_ADDR(rxbuffer); + + /* And give the RX descriptor back to the hardware */ + + pic32mx_rxreturn(rxdesc); + pic32mx_dumppacket("Received packet", + priv->pd_dev.d_buf, priv->pd_dev.d_len); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet + * tap. + */ + + pkt_input(&priv->pd_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->pd_dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->pd_dev); + ipv4_input(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) +#endif + { + arp_out(&priv->pd_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->pd_dev); + } +#endif + + /* And send the packet */ + + pic32mx_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->pd_dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) + { + arp_out(&priv->pd_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->pd_dev); + } +#endif + + /* And send the packet */ + + pic32mx_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + /* Handle the incoming ARP packet */ + + NETDEV_RXARP(&priv->pd_dev); + arp_arpin(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + pic32mx_response(priv); + } + } + else +#endif + { + /* Unrecognized... drop it. */ + + nlldbg("Unrecognized packet type dropped: %04x\n", ntohs(BUF->type)); + NETDEV_RXDROPPED(&priv->pd_dev); + } + + /* Discard any buffers still attached to the device structure */ + + priv->pd_dev.d_len = 0; + if (priv->pd_dev.d_buf) + { + pic32mx_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: pic32mx_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_txdone(struct pic32mx_driver_s *priv) +{ + struct pic32mx_txdesc_s *txdesc; + int i; + + /* Cancel the pending Tx timeout */ + + wd_cancel(priv->pd_txtimeout); + + /* Disable further Tx interrupts. Tx interrupts may be re-enabled again + * depending upon the result of the poll. + */ + + priv->pd_inten &= ~ETH_TXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_IEN); + + /* Verify that the hardware is ready to send another packet. Since a Tx + * just completed, this must be the case. + */ + + DEBUGASSERT(pic32mx_txdesc(priv) != NULL); + + /* Inspect the list of TX descriptors to see if the EOWN bit is cleared. If it + * is, this descriptor is now under software control and the message was + * transmitted. Use TSV to check for the transmission result. + */ + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + txdesc = &priv->pd_txdesc[i]; + + /* Check if software owns this descriptor */ + + if ((txdesc->status & TXDESC_STATUS_EOWN) == 0) + { + /* Yes.. Check if there is a buffer attached? */ + + if (txdesc->address != 0) + { + pic32mx_dumptxdesc(txdesc, "Freeing TX buffer"); + + /* Free the TX buffer */ + + pic32mx_freebuffer(priv, (uint8_t *)VIRT_ADDR(txdesc->address)); + txdesc->address = 0; + + /* Reset status */ + + txdesc->tsv1 = 0; + txdesc->tsv2 = 0; + txdesc->status = TXDESC_STATUS_SOWN | TXDESC_STATUS_NPV; + pic32mx_dumptxdesc(txdesc, "TX buffer freed"); + } + } + } + + /* Check if there is a pending Tx transfer that was deferred by Rx handling + * because there were no available Tx descriptors. If so, process that + * pending Tx now. + */ + + if (priv->pd_txpending) + { + /* Clear the pending condition, send the packet, and restore Rx interrupts */ + + priv->pd_txpending = false; + + pic32mx_transmit(priv); + + priv->pd_inten |= ETH_RXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_IEN); + } + + /* Otherwise poll uIP for new XMIT data */ + + else + { + /* Perform the uIP poll */ + + pic32mx_poll(priv); + } +} + +/**************************************************************************** + * Function: pic32mx_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_interrupt(int irq, void *context) +{ + register struct pic32mx_driver_s *priv; + uint32_t status; + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# error "A mechanism to associate and interface with an IRQ is needed" +#else + priv = &g_ethdrvr[0]; +#endif + + /* Get the interrupt status (zero means no interrupts pending). */ + + status = pic32mx_getreg(PIC32MX_ETH_IRQ); + if (status != 0) + { + /* Clear all pending interrupts */ + + pic32mx_putreg(status, PIC32MX_ETH_IRQCLR); + + /* Handle each pending interrupt **************************************/ + /* Receive Errors *****************************************************/ + /* RXOVFLW: Receive FIFO Over Flow Error. RXOVFLW is set by the RXBM + * Logic for an RX FIFO Overflow condition. It is cleared by either a + * Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXOVFLW) != 0) + { + nlldbg("RX Overrun. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* RXBUFNA: Receive Buffer Not Available Interrupt. This bit is set by + * a RX Buffer Descriptor Overrun condition. It is cleared by either a + * Reset or a CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXBUFNA) != 0) + { + nlldbg("RX buffer descriptor overrun. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* RXBUSE: Receive BVCI Bus Error Interrupt. This bit is set when the + * RX DMA encounters a BVCI Bus error during a memory access. It is + * cleared by either a Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXBUSE) != 0) + { + nlldbg("RX BVCI bus error. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* Receive Normal Events **********************************************/ + /* RXACT: Receive Activity Interrupt. This bit is set whenever RX packet + * data is stored in the RXBM FIFO. It is cleared by either a Reset or CPU + * write of a ‘1’ to the CLR register. + */ + + /* PKTPEND: Packet Pending Interrupt. This bit is set when the BUFCNT + * counter has a value other than ‘0’. It is cleared by either a Reset + * or by writing the BUFCDEC bit to decrement the BUFCNT counter. + * Writing a ‘0’ or a ‘1’ has no effect. + */ + + /* RXDONE: Receive Done Interrupt. This bit is set whenever an RX packet + * is successfully received. It is cleared by either a Reset or CPU + * write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXDONE) != 0) + { + /* We have received at least one new incoming packet. */ + + pic32mx_rxdone(priv); + } + + /* Transmit Errors ****************************************************/ + /* TXABORT: Transmit Abort Condition Interrupt. This bit is set when + * the MAC aborts the transmission of a TX packet for one of the + * following reasons: + * - Jumbo TX packet abort + * - Underrun abort + * - Excessive defer abort + * - Late collision abort + * - Excessive collisions abort + * This bit is cleared by either a Reset or CPU write of a ‘1’ to the + * CLR register. + */ + + if ((status & ETH_INT_TXABORT) != 0) + { + nlldbg("TX abort. status: %08x\n", status); + NETDEV_TXERRORS(&priv->pd_dev); + } + + /* TXBUSE: Transmit BVCI Bus Error Interrupt. This bit is set when the + * TX DMA encounters a BVCI Bus error during a memory access. It is + * cleared by either a Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_TXBUSE) != 0) + { + nlldbg("TX BVCI bus error. status: %08x\n", status); + NETDEV_TXERRORS(&priv->pd_dev); + } + + /* TXDONE: Transmit Done Interrupt. This bit is set when the currently + * transmitted TX packet completes transmission, and the Transmit + * Status Vector is loaded into the first descriptor used for the + * packet. It is cleared by either a Reset or CPU write of a ‘1’ to + * the CLR register. + */ + + if ((status & ETH_INT_TXDONE) != 0) + { + NETDEV_TXDONE(&priv->pd_dev); + + /* A packet transmission just completed */ + + pic32mx_txdone(priv); + } + + /* Watermark Events ***************************************************/ + /* EWMARK: Empty Watermark Interrupt. This bit is set when the RX + * Descriptor Buffer Count is less than or equal to the value in the + * RXEWM bit (ETHRXWM:0-7) value. It is cleared by BUFCNT bit + * (ETHSTAT:16-23) being incremented by hardware. Writing a ‘0’ or a ‘1’ + * has no effect. + */ + + /* FWMARK: Full Watermark Interrupt. This bit is set when the RX + * escriptor Buffer Count is greater than or equal to the value in the + * RXFWM bit (ETHRXWM:16-23) field. It is cleared by writing the BUFCDEC + * (ETHCON1:0) bit to decrement the BUFCNT counter. Writing a ‘0’ or a + * ‘1’ has no effect. + */ + + } + + /* Clear the pending interrupt */ + +# if CONFIG_PIC32MX_NINTERFACES > 1 + up_clrpend_irq(priv->pd_irqsrc); +# else + up_clrpend_irq(PIC32MX_IRQSRC_ETH); +# endif + + return OK; +} + +/**************************************************************************** + * Function: pic32mx_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mx_txtimeout(int argc, uint32_t arg, ...) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg; + + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(&priv->pd_dev); + if (priv->pd_ifup) + { + /* Then reset the hardware. ifup() will reset the interface, then bring + * it back up. + */ + + (void)pic32mx_ifup(&priv->pd_dev); + + /* Then poll uIP for new XMIT data (We are guaranteed to have a free + * buffer here). + */ + + pic32mx_poll(priv); + } +} + +/**************************************************************************** + * Function: pic32mx_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mx_polltimer(int argc, uint32_t arg, ...) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg; + + /* Check if the next Tx descriptor is available. We cannot perform the Tx + * poll if we are unable to accept another packet for transmission. + */ + + if (pic32mx_txdesc(priv) != NULL) + { + /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. + * might be bug here. Does this mean if there is a transmit in progress, + * we will missing TCP time state updates? + */ + + pic32mx_timerpoll(priv); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: pic32mx_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_ifup(struct net_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + uint32_t regval; + int ret; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Reset the Ethernet controller (again) */ + + pic32mx_ethreset(priv); + + /* MAC Initialization *****************************************************/ + /* Configuration: + * - Use the configuration fuse setting FETHIO bit (DEVCFG3:25) to detect + * the alternate/default I/O configuration + * - Use the configuration fuse setting FMIIEN (DEVCFG3:24) to detect the + * MII/RMII operation mode. + */ + + /* Pin Configuration: + * + * No GPIO pin configuration is required. Enabling the Ethernet Controller + * will configure the I/O pin direction as defined by the Ethernet Controller + * control bits. The port TRIS and LATCH registers will be overridden. + * + * I/O Pin MII RMII Pin Description + * Name Required Required Type + * EMDC Yes Yes O Ethernet MII Management Clock + * EMDIO Yes Yes I/O Ethernet MII Management IO + * ETXCLK Yes No I Ethernet MII TX Clock + * ETXEN Yes Yes O Ethernet Transmit Enable + * ETXD0 Yes Yes O Ethernet Data Transmit 0 + * ETXD1 Yes Yes O Ethernet Data Transmit 1 + * ETXD2 Yes No O Ethernet Data Transmit 2 + * ETXD3 Yes No O Ethernet Data Transmit 3 + * ETXERR Yes No O Ethernet Transmit Error + * ERXCLK Yes No I Ethernet MII RX Clock + * EREF_CLK No Yes I Ethernet RMII Ref Clock + * ERXDV Yes No I Ethernet MII Receive Data Valid + * ECRS_DV No Yes I Ethernet RMII Carrier Sense/Receive Data Valid + * ERXD0 Yes Yes I Ethernet Data Receive 0 + * ERXD1 Yes Yes I Ethernet Data Receive 1 + * ERXD2 Yes No I Ethernet Data Receive 2 + * ERXD3 Yes No I Ethernet Data Receive 3 + * ERXERR Yes Yes I Ethernet Receive Error + * ECRS Yes No I Ethernet Carrier Sense + * ECOL Yes No I Ethernet Collision Detected + * + * All that is required is to assure that the pins are initialized as + * digital (normally only those pins that have shared analog functionality + * need to be configured). + */ + + /* Initialize the MIIM interface + * + * If the RMII operation is selected, reset the RMII module by using the + * RESETRMII (EMAC1SUPP:11) bit and set the proper speed in the SPEEDRMII + * bit (EMAC1SUPP:8) bit. + */ + +#if CONFIG_PIC32MX_FMIIEN == 0 + pic32mx_putreg(EMAC1_SUPP_RESETRMII, PIC32MX_EMAC1_SUPPSET); + pic32mx_putreg((EMAC1_SUPP_RESETRMII | EMAC1_SUPP_SPEEDRMII), PIC32MX_EMAC1_SUPPCLR); +#endif + + /* Issue an MIIM block reset, by setting the RESETMGMT (EMAC1MCFG:15) bit, + * and then clear the reset bit. + */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_MCFG); + pic32mx_putreg(EMAC1_MCFG_MGMTRST, PIC32MX_EMAC1_MCFGSET); + + regval &= ~EMAC1_MCFG_MGMTRST; + pic32mx_putreg(regval, PIC32MX_EMAC1_MCFG); + + /* Select a proper divider in the CLKSEL bit (EMAC1CFG:2-5) for the MIIM + * PHY communication based on the system running clock frequency and the + * external PHY supported clock. + * + * MII configuration: host clocked divider per board.h, no suppress + * preamble, no scan increment. + */ + + regval &= ~(EMAC1_MCFG_CLKSEL_MASK | EMAC1_MCFG_NOPRE | EMAC1_MCFG_SCANINC); + regval |= EMAC1_MCFG_CLKSEL_DIV; + pic32mx_putreg(regval, PIC32MX_EMAC1_MCFG); + + /* PHY Initialization *****************************************************/ + /* Initialize the PHY and wait for the link to be established */ + + ret = pic32mx_phyinit(priv); + if (ret != 0) + { + ndbg("pic32mx_phyinit failed: %d\n", ret); + return ret; + } + + /* MAC Configuration ******************************************************/ + /* Set other misc configuration-related registers to default values */ + + pic32mx_putreg(0, PIC32MX_EMAC1_CFG2); + pic32mx_putreg(0, PIC32MX_EMAC1_TEST); + + /* Having available the Duplex and Speed settings, configure the MAC + * accordingly, using the following steps: + * + * Enable the RXENABLE bit (EMAC1CFG1:0), selecting both the TXPAUSE and + * RXPAUSE bit (EMAC1CFG1:2-3) (the PIC32 MAC supports both). + */ + + pic32mx_putreg(EMAC1_CFG1_RXEN | EMAC1_CFG1_RXPAUSE | EMAC1_CFG1_TXPAUSE, + PIC32MX_EMAC1_CFG1SET); + + /* Select the desired auto-padding and CRC capabilities, and the enabling + * of the huge frames and the Duplex type in the EMAC1CFG2 register. + * (This was done in the PHY initialization logic). + */ + + /* Program EMAC1IPGT with the back-to-back inter-packet gap */ + /* Use EMAC1IPGR for setting the non back-to-back inter-packet gap */ + + pic32mx_putreg(((12 << EMAC1_IPGR_GAP1_SHIFT) | (12 << EMAC1_IPGR_GAP2_SHIFT)), + PIC32MX_EMAC1_IPGR); + + /* Set the collision window and the maximum number of retransmissions in + * EMAC1CLRT. + */ + + pic32mx_putreg(((15 << EMAC1_CLRT_RETX_SHIFT) | (55 << EMAC1_CLRT_CWINDOW_SHIFT)), + PIC32MX_EMAC1_CLRT); + + /* Set the maximum frame length in EMAC1MAXF. "This field resets to + * 0x05EE, which represents a maximum receive frame of 1518 octets. An + * untagged maximum size Ethernet frame is 1518 octets. A tagged frame adds + * four octets for a total of 1522 octets. If a shorter/longer maximum + * length restriction is desired, program this 16-bit field. + */ + + pic32mx_putreg(CONFIG_NET_ETH_MTU, PIC32MX_EMAC1_MAXF); + + /* Configure the MAC station address in the EMAC1SA0, EMAC1SA1 and + * EMAC1SA2 registers (these registers are loaded at reset from the + * factory preprogrammed station address). + */ + +#if 0 + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[5] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[4]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA0); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[3] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[2]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA1); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[1] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[0]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA2); +#else + regval = pic32mx_getreg(PIC32MX_EMAC1_SA0); + priv->pd_dev.d_mac.ether_addr_octet[4] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[5] = (uint32_t)((regval >> 8) & 0xff); + + regval = pic32mx_getreg(PIC32MX_EMAC1_SA1); + priv->pd_dev.d_mac.ether_addr_octet[2] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[3] = (uint32_t)((regval >> 8) & 0xff); + + regval = pic32mx_getreg(PIC32MX_EMAC1_SA2); + priv->pd_dev.d_mac.ether_addr_octet[0] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[1] = (uint32_t)((regval >> 8) & 0xff); +#endif + + /* Continue Ethernet Controller Initialization ****************************/ + /* If planning to turn on the flow control, update the PTV value + * (ETHCON1:16-31). + */ + + /* If using the auto-flow control, set the full and empty watermarks: RXFWM + * and RXEWM (ETHRXWM:16-23 and ETHRXWM:0-7). + */ + + /* If needed, enable the auto-flow control by setting AUTOFC (ETHCON1:7). */ + + /* Set the RX filters by updating the ETHHT0, ETHHT1, ETHPMM0, ETHPMM1, + * ETHPMCS and ETHRXFC registers. + * + * Set up RX filter and configure to accept broadcast addresses and multicast + * addresses (if so configured). NOTE: There is a selection + * CONFIG_NET_BROADCAST, but this enables receipt of UDP broadcast packets + * inside of the stack. + */ + + regval = ETH_RXFC_BCEN | ETH_RXFC_UCEN | ETH_RXFC_PMMODE_DISABLED; +#ifdef CONFIG_PIC32MX_MULTICAST + regval |= ETH_RXFC_MCEN; +#endif + pic32mx_putreg(regval, PIC32MX_ETH_RXFC); + + /* Set the size of the RX buffers in the RXBUFSZ bit (ETHCON2:4-10) (all + * receive descriptors use the same buffer size). Keep in mind that using + * packets that are too small leads to packet fragmentation and has a + * noticeable impact on the performance. + */ + + pic32mx_putreg(ETH_CON2_RXBUFSZ(CONFIG_NET_ETH_MTU), PIC32MX_ETH_CON2); + + /* Reset state varialbes */ + + priv->pd_polling = false; + priv->pd_txpending = false; + + /* Initialize the buffer list */ + + pic32mx_bufferinit(priv); + + /* Initialize the TX descriptor list */ + + pic32mx_txdescinit(priv); + + /* Initialize the RX descriptor list */ + + pic32mx_rxdescinit(priv); + + /* Enable the Ethernet Controller by setting the ON bit (ETHCON1:15). + * Enable the receiving of messages by setting the RXEN bit (ETHCON1:8). + */ + + pic32mx_putreg(ETH_CON1_RXEN | ETH_CON1_ON, PIC32MX_ETH_CON1SET); + + /* Initialize Ethernet interface for the PHY setup */ + + pic32mx_macmode(priv->pd_mode); + + /* Configure to pass all received frames */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_CFG1); + regval |= EMAC1_CFG1_PASSALL; + pic32mx_putreg(regval, PIC32MX_EMAC1_CFG1); + + /* Clear any pending interrupts (shouldn't be any) */ + + pic32mx_putreg(0xffffffff, PIC32MX_ETH_IRQCLR); + + /* Configure interrupts. The Ethernet interrupt was attached during one-time + * initialization, so we only need to set the interrupt priority, configure + * interrupts, and enable them. + */ + + /* If the user provided an interrupt priority, then set the interrupt to that + * priority + */ + +#if defined(CONFIG_NET_PRIORITY) && defined(CONFIG_ARCH_IRQPRIO) +#if CONFIG_PIC32MX_NINTERFACES > 1 + (void)up_prioritize_irq(priv->pd_irq, CONFIG_NET_PRIORITY); +#else + (void)up_prioritize_irq(PIC32MX_IRQ_ETH, CONFIG_NET_PRIORITY); +#endif +#endif + + /* Otherwise, enable all Rx interrupts. Tx interrupts, SOFTINT and WoL are + * excluded. Tx interrupts will not be enabled until there is data to be + * sent. + */ + + priv->pd_inten = ETH_RXINTS; + pic32mx_putreg(ETH_RXINTS, PIC32MX_ETH_IENSET); + + /* Set and activate a timer process */ + + (void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_polltimer, 1, + (uint32_t)priv); + + /* Finally, enable the Ethernet interrupt at the interrupt controller */ + + priv->pd_ifup = true; +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_enable_irq(priv->pd_irqsrc); +#else + up_enable_irq(PIC32MX_IRQSRC_ETH); +#endif + return OK; +} + +/**************************************************************************** + * Function: pic32mx_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_ifdown(struct net_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_disable_irq(priv->pd_irqsrc); +#else + up_disable_irq(PIC32MX_IRQSRC_ETH); +#endif + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->pd_txpoll); + wd_cancel(priv->pd_txtimeout); + + /* Reset the device and mark it as down. */ + + pic32mx_ethreset(priv); + priv->pd_ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mx_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int pic32mx_txavail(struct net_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->pd_ifup) + { + /* Check if the next Tx descriptor is available. */ + + if (pic32mx_txdesc(priv) != NULL) + { + /* If so, then poll uIP for new XMIT data. First allocate a buffer + * to perform the poll + */ + + pic32mx_poll(priv); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mx_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mx_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mx_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mx_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Name: pic32mx_showmii + * + * Description: + * Dump PHY MII registers + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(PIC32MX_HAVE_PHY) +static void pic32mx_showmii(uint8_t phyaddr, const char *msg) +{ + dbg("PHY " PIC32MX_PHYNAME ": %s\n", msg); + dbg(" MCR: %04x\n", pic32mx_phyread(phyaddr, MII_MCR)); + dbg(" MSR: %04x\n", pic32mx_phyread(phyaddr, MII_MSR)); + dbg(" ADVERTISE: %04x\n", pic32mx_phyread(phyaddr, MII_ADVERTISE)); + dbg(" LPA: %04x\n", pic32mx_phyread(phyaddr, MII_LPA)); + dbg(" EXPANSION: %04x\n", pic32mx_phyread(phyaddr, MII_EXPANSION)); +#ifdef CONFIG_ETH0_PHY_KS8721 + dbg(" 10BTCR: %04x\n", pic32mx_phyread(phyaddr, MII_KS8721_10BTCR)); +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mx_phybusywait + * + * Description: + * Wait until the PHY is no longer busy + * + * Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void pic32mx_phybusywait(void) +{ + while ((pic32mx_getreg(PIC32MX_EMAC1_MIND) & EMAC1_MIND_MIIMBUSY) != 0); +} + +/**************************************************************************** + * Function: pic32mx_phywrite + * + * Description: + * Write a value to an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * phydata - The data to write to the PHY register + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static void pic32mx_phywrite(uint8_t phyaddr, uint8_t regaddr, uint16_t phydata) +{ + uint32_t regval; + + /* Make sure that the PHY is not still busy from the last command */ + + pic32mx_phybusywait(); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mx_putreg(regval, PIC32MX_EMAC1_MADR); + + /* Write the register data to the PHY */ + + pic32mx_putreg((uint32_t)phydata, PIC32MX_EMAC1_MWTD); + + /* Two clock cycles until busy is set from the write operation */ + + __asm__ __volatile__ ("nop; nop;"); +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyread + * + * Description: + * Read a value from an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * + * Returned Value: + * Data read from the PHY register + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static uint16_t pic32mx_phyread(uint8_t phyaddr, uint8_t regaddr) +{ + uint32_t regval; + + /* Make sure that the PHY is not still busy from the last command */ + + pic32mx_phybusywait(); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mx_putreg(regval, PIC32MX_EMAC1_MADR); + + /* Set up to read */ + + pic32mx_putreg(EMAC1_MCMD_READ, PIC32MX_EMAC1_MCMD); + + /* Four clock cycles until busy is set from the write operation */ + + __asm__ __volatile__ ("nop; nop; nop; nop;"); + + /* Wait for the PHY command to complete */ + + pic32mx_phybusywait(); + pic32mx_putreg(0, PIC32MX_EMAC1_MCMD); + + /* Return the PHY register data */ + + return (uint16_t)(pic32mx_getreg(PIC32MX_EMAC1_MRDD) & EMAC1_MRDD_MASK); +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static inline int pic32mx_phyreset(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Reset the PHY. Needs a minimal 50uS delay after reset. */ + + pic32mx_phywrite(phyaddr, MII_MCR, MII_MCR_RESET); + + /* Wait for a minimum of 50uS no matter what */ + + up_udelay(50); + + /* The MCR reset bit is self-clearing. Wait for it to be clear indicating + * that the reset is complete. + */ + + for (timeout = PIC32MX_MIITIMEOUT; timeout > 0; timeout--) + { + phyreg = pic32mx_phyread(phyaddr, MII_MCR); + if ((phyreg & MII_MCR_RESET) == 0) + { + return OK; + } + } + + ndbg("Reset failed. MCR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyautoneg + * + * Description: + * Enable auto-negotiation. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * The adverisement regiser has already been configured. + * + ****************************************************************************/ + +#if defined(PIC32MX_HAVE_PHY) && defined(CONFIG_PHY_AUTONEG) +static inline int pic32mx_phyautoneg(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Start auto-negotiation */ + + pic32mx_phywrite(phyaddr, MII_MCR, MII_MCR_ANENABLE | MII_MCR_ANRESTART); + + /* Wait for autonegotiation to complete */ + + for (timeout = PIC32MX_MIITIMEOUT; timeout > 0; timeout--) + { + /* Check if auto-negotiation has completed */ + + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. return success */ + + return OK; + } + } + + ndbg("Auto-negotiation failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phymode + * + * Description: + * Set the PHY to operate at a selected speed/duplex mode. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static int pic32mx_phymode(uint8_t phyaddr, uint8_t mode) +{ + int32_t timeout; + uint16_t phyreg; + + /* Disable auto-negotiation and set fixed Speed and Duplex settings: + * + * MII_MCR_UNIDIR 0=Disable unidirectional enable + * MII_MCR_SPEED1000 0=Reserved on 10/100 + * MII_MCR_CTST 0=Disable collision test + * MII_MCR_FULLDPLX ?=Full duplex + * MII_MCR_ANRESTART 0=Don't restart auto negotiation + * MII_MCR_ISOLATE 0=Don't electronically isolate PHY from MII + * MII_MCR_PDOWN 0=Don't powerdown the PHY + * MII_MCR_ANENABLE 0=Disable auto negotiation + * MII_MCR_SPEED100 ?=Select 100Mbps + * MII_MCR_LOOPBACK 0=Disable loopback mode + * MII_MCR_RESET 0=No PHY reset + */ + + phyreg = 0; + if ((mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100) + { + phyreg = MII_MCR_SPEED100; + } + + if ((mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL) + { + phyreg |= MII_MCR_FULLDPLX; + } + + pic32mx_phywrite(phyaddr, MII_MCR, phyreg); + + /* Then wait for the link to be established */ + + for (timeout = PIC32MX_MIITIMEOUT; timeout > 0; timeout--) + { +#ifdef CONFIG_ETH0_PHY_DP83848C + phyreg = pic32mx_phyread(phyaddr, MII_DP83848C_STS); + if ((phyreg & 0x0001) != 0) + { + /* Yes.. return success */ + + return OK; + } +#else + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_LINKSTATUS) != 0) + { + /* Yes.. return success */ + + return OK; + } +#endif + } + + ndbg("Link failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyinit + * + * Description: + * Initialize the PHY + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directly. As a side-effect, it will initialize priv->pd_phyaddr + * and priv->pd_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv) +{ + unsigned int phyaddr; + uint16_t phyreg; + uint32_t regval; + int ret; + +#if CONFIG_PIC32MX_FMIIEN == 0 + /* Set the RMII operation mode. This usually requires access to a vendor + * specific control register. + */ + +#ifdef CONFIG_ETH0_PHY_DP83848C + /* The RMII/MII of operation can be selected by strap options or register + * control (using the RBR register). For RMII mode, it is required to use the + * strap option, since it requires a 50 MHz clock instead of the normal 25 MHz. + */ +#endif + +#else + /* Set the MII/ operation mode. This usually requires access to a vendor- + * specific control register. + */ + +#ifdef CONFIG_ETH0_PHY_DP83848C +# warning "Missing logic" +#endif + +#endif + + /* Find PHY Address. Because the controller has a pull-up and the + * PHY has pull-down resistors on RXD lines some times the PHY + * latches different at different addresses. + */ + + for (phyaddr = 0; phyaddr < 32; phyaddr++) + { + /* Clear any ongoing PHY command bits */ + + pic32mx_putreg(0, PIC32MX_EMAC1_MCMD); + + /* Reset the PHY (use Control Register 0). */ + + ret = pic32mx_phyreset(phyaddr); + if (ret < 0) + { + ndbg("Failed to reset PHY at address %d\n", phyaddr); + continue; + } + + /* Set the normal, swapped or auto (preferred) MDIX. This usually + * requires access to a vendor-specific control register. + */ + + /* Check if we can see the selected device ID at this + * PHY address. + */ + + phyreg = (unsigned int)pic32mx_phyread(phyaddr, MII_PHYID1); + nvdbg("Addr: %d PHY ID1: %04x\n", phyaddr, phyreg); + + if (phyreg == PIC32MX_PHYID1) + { + phyreg = pic32mx_phyread(phyaddr, MII_PHYID2); + nvdbg("Addr: %d PHY ID2: %04x\n", phyaddr, phyreg); + + if (phyreg == PIC32MX_PHYID2) + { + break; + } + } + } + + /* Check if the PHY device address was found */ + + if (phyaddr > 31) + { + /* Failed to find PHY at any location */ + + ndbg("No PHY detected\n"); + return -ENODEV; + } + nvdbg("phyaddr: %d\n", phyaddr); + + /* Save the discovered PHY device address */ + + priv->pd_phyaddr = phyaddr; + + /* Reset the PHY */ + + ret = pic32mx_phyreset(phyaddr); + if (ret < 0) + { + return ret; + } + pic32mx_showmii(phyaddr, "After reset"); + + /* Set the MII/RMII operation mode. This usually requires access to a + * vendor-specific control register. + */ + + /* Set the normal, swapped or auto (preferred) MDIX. This usually requires + * access to a vendor-specific control register. + */ + + /* Check the PHY capabilities by investigating the Status Register 1. */ + + /* Check for preamble suppression support */ + + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_MFRAMESUPPRESS) != 0) + { + /* The PHY supports preamble suppression */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_MCFG); + regval |= EMAC1_MCFG_NOPRE; + pic32mx_putreg(regval, PIC32MX_EMAC1_MCFG); + } + + /* Are we configured to do auto-negotiation? + * + * Preferably the auto-negotiation should be selected if the PHY supports + * it. Expose the supported capabilities: Half/Full Duplex, 10BaseT/100Base + * TX, etc. (Extended Register 4). Start the negotiation (Control Register + * 0) and wait for the negotiation complete and get the link partner + * capabilities (Extended Register 5) and negotiation result (vendor- + * specific register). + */ + +#ifdef CONFIG_PHY_AUTONEG + /* Setup the Auto-negotiation advertisement: 100 or 10, and HD or FD */ + + pic32mx_phywrite(phyaddr, MII_ADVERTISE, + (MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_CSMA)); + + /* Then perform the auto-negotiation */ + + ret = pic32mx_phyautoneg(phyaddr); + if (ret < 0) + { + return ret; + } +#else + /* Set up the fixed PHY configuration + * + * If auto-negotiation is not supported/selected, update the PHY Duplex and + * Speed settings directly (use Control Register 0 and possibly some vendor- + * pecific registers). + */ + + ret = pic32mx_phymode(phyaddr, PIC32MX_MODE_DEFLT); + if (ret < 0) + { + return ret; + } +#endif + + /* The link is established */ + + pic32mx_showmii(phyaddr, "After link established"); + + /* Check configuration */ + +#if defined(CONFIG_ETH0_PHY_KS8721) + phyreg = pic32mx_phyread(phyaddr, MII_KS8721_10BTCR); + + switch (phyreg & KS8721_10BTCR_MODE_MASK) + { + case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */ + priv->pd_mode = PIC32MX_10BASET_HD; + break; + case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */ + priv->pd_mode = PIC32MX_100BASET_HD; + break; + case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */ + priv->pd_mode = PIC32MX_10BASET_FD; + break; + case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */ + priv->pd_mode = PIC32MX_100BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_ETH0_PHY_DP83848C) + phyreg = pic32mx_phyread(phyaddr, MII_DP83848C_STS); + + /* Configure for full/half duplex mode and speed */ + + switch (phyreg & 0x0006) + { + case 0x0000: + priv->pd_mode = PIC32MX_100BASET_HD; + break; + case 0x0002: + priv->pd_mode = PIC32MX_10BASET_HD; + break; + case 0x0004: + priv->pd_mode = PIC32MX_100BASET_FD; + break; + case 0x0006: + priv->pd_mode = PIC32MX_10BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_ETH0_PHY_LAN8720) + { + uint16_t advertise; + uint16_t lpa; + + up_udelay(500); + advertise = pic32mx_phyread(phyaddr, MII_ADVERTISE); + lpa = pic32mx_phyread(phyaddr, MII_LPA); + + /* Check for 100BASETX full duplex */ + + if ((advertise & MII_ADVERTISE_100BASETXFULL) != 0 && + (lpa & MII_LPA_100BASETXFULL) != 0) + { + priv->pd_mode = PIC32MX_100BASET_FD; + } + + /* Check for 100BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_100BASETXHALF) != 0 && + (lpa & MII_LPA_100BASETXHALF) != 0) + { + priv->pd_mode = PIC32MX_100BASET_HD; + } + + /* Check for 10BASETX full duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXFULL) != 0 && + (lpa & MII_LPA_10BASETXFULL) != 0) + { + priv->pd_mode = PIC32MX_10BASET_FD; + } + + /* Check for 10BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXHALF) != 0 && + (lpa & MII_LPA_10BASETXHALF) != 0) + { + priv->pd_mode = PIC32MX_10BASET_HD; + } + else + { + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + } +#else +# warning "PHY Unknown: speed and duplex are bogus" +#endif + + ndbg("%dBase-T %s duplex\n", + (priv->pd_mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100 ? 100 : 10, + (priv->pd_mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL ?"full" : "half"); + + /* Disable auto-configuration. Set the fixed speed/duplex mode. + * (probably more than little redundant). + */ + + ret = pic32mx_phymode(phyaddr, priv->pd_mode); + pic32mx_showmii(phyaddr, "After final configuration"); + return ret; +} +#else +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv) +{ + priv->pd_mode = PIC32MX_MODE_DEFLT; + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mx_macmode + * + * Description: + * Set the MAC to operate at a selected speed/duplex mode. + * + * Parameters: + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static void pic32mx_macmode(uint8_t mode) +{ + /* Set up for full or half duplex operation */ + + if ((mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL) + { + /* Set the back-to-back inter-packet gap */ + + pic32mx_putreg(21, PIC32MX_EMAC1_IPGT); + + /* Set MAC to operate in full duplex mode with CRC and Pad enabled */ + + pic32mx_putreg((EMAC1_CFG2_FULLDPLX | EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN), + PIC32MX_EMAC1_CFG2SET); + } + else + { + /* Set the back-to-back inter-packet gap */ + + pic32mx_putreg(18, PIC32MX_EMAC1_IPGT); + + /* Set MAC to operate in half duplex mode with CRC and Pad enabled */ + + pic32mx_putreg(EMAC1_CFG2_FULLDPLX, PIC32MX_EMAC1_CFG2CLR); + pic32mx_putreg((EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN), PIC32MX_EMAC1_CFG2SET); + } + + /* Set the RMII MAC speed. */ + +#if CONFIG_PIC32MX_FMIIEN == 0 + if ((mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100) + { + pic32mx_putreg(EMAC1_SUPP_SPEEDRMII, PIC32MX_EMAC1_SUPPSET); + } + else + { + pic32mx_putreg(EMAC1_SUPP_SPEEDRMII, PIC32MX_EMAC1_SUPPCLR); + } +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mx_ethreset + * + * Description: + * Configure and reset the Ethernet module, leaving it in a disabled state. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static void pic32mx_ethreset(struct pic32mx_driver_s *priv) +{ + irqstate_t flags; + + /* Reset the MAC */ + + flags = enter_critical_section(); + + /* Ethernet Controller Initialization *************************************/ + /* Disable Ethernet interrupts in the EVIC */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_disable_irq(priv->pd_irqsrc); +#else + up_disable_irq(PIC32MX_IRQSRC_ETH); +#endif + + /* Turn the Ethernet Controller off: Clear the ON, RXEN and TXRTS bits */ + + pic32mx_putreg(ETH_CON1_RXEN | ETH_CON1_TXRTS | ETH_CON1_ON, PIC32MX_ETH_CON1CLR); + + /* Wait activity abort by polling the ETHBUSY bit */ + + while ((pic32mx_getreg(PIC32MX_ETH_STAT) & ETH_STAT_ETHBUSY) != 0); + + /* Turn the Ethernet controller on. */ + + pic32mx_putreg(ETH_CON1_ON, PIC32MX_ETH_CON1SET); + + /* Clear the Ethernet STAT BUFCNT */ + + while ((pic32mx_getreg(PIC32MX_ETH_STAT) & ETH_STAT_BUFCNT_MASK) != 0) + { + pic32mx_putreg(ETH_CON1_BUFCDEC, PIC32MX_ETH_CON1SET); + } + + /* Clear the Ethernet Interrupt Flag (ETHIF) bit in the Interrupts module */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_pending_irq(priv->pd_irqsrc); +#else + up_pending_irq(PIC32MX_IRQSRC_ETH); +#endif + + /* Disable any Ethernet Controller interrupt generation by clearing the IEN + * register. + */ + + pic32mx_putreg(ETH_INT_ALLINTS, PIC32MX_ETH_IENCLR); + + /* Clear the TX and RX start addresses by using ETHTXSTCLR and ETHRXSTCLR */ + + pic32mx_putreg(0xffffffff, PIC32MX_ETH_TXSTCLR); + pic32mx_putreg(0xffffffff, PIC32MX_ETH_RXSTCLR); + + /* MAC Initialization *****************************************************/ + /* Put the MAC into the reset state */ + + pic32mx_putreg((EMAC1_CFG1_TXRST | EMAC1_CFG1_MCSTXRST | EMAC1_CFG1_RXRST | + EMAC1_CFG1_MCSRXRST | EMAC1_CFG1_SIMRST | EMAC1_CFG1_SOFTRST), + PIC32MX_EMAC1_CFG1); + + /* Take the MAC out of the reset state */ + + up_udelay(50); + pic32mx_putreg(0, PIC32MX_EMAC1_CFG1); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pic32mx_ethinitialize + * + * Description: + * Initialize one Ethernet controller and driver structure. + * + * Parameters: + * intf - Selects the interface to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +int pic32mx_ethinitialize(int intf) +#else +static inline int pic32mx_ethinitialize(int intf) +#endif +{ + struct pic32mx_driver_s *priv; + int ret; + + DEBUGASSERT(intf < CONFIG_PIC32MX_NINTERFACES); + priv = &g_ethdrvr[intf]; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct pic32mx_driver_s)); + priv->pd_dev.d_ifup = pic32mx_ifup; /* I/F down callback */ + priv->pd_dev.d_ifdown = pic32mx_ifdown; /* I/F up (new IP address) callback */ + priv->pd_dev.d_txavail = pic32mx_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->pd_dev.d_addmac = pic32mx_addmac; /* Add multicast MAC address */ + priv->pd_dev.d_rmmac = pic32mx_rmmac; /* Remove multicast MAC address */ +#endif + priv->pd_dev.d_private = (void *)priv; /* Used to recover private state from dev */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# error "A mechanism to associate base address an IRQ with an interface is needed" + priv->pd_base = ??; /* Ethernet controller base address */ + priv->pd_irq = ??; /* Ethernet controller IRQ vector number */ + priv->pd_irqsrc = ??; /* Ethernet controller IRQ source number */ +#endif + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->pd_txpoll = wd_create(); /* Create periodic poll timer */ + priv->pd_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Reset the Ethernet controller and leave in the ifdown state. The + * Ethernet controller will be properly re-initialized each time + * pic32mx_ifup() is called. + */ + + pic32mx_ifdown(&priv->pd_dev); + + /* Attach the IRQ to the driver */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + ret = irq_attach(priv->pd_irq, pic32mx_interrupt); +#else + ret = irq_attach(PIC32MX_IRQ_ETH, pic32mx_interrupt); +#endif + if (ret != 0) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->pd_dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one + * interface in the chip, then board-specific logic will have to provide + * this function to determine which, if any, Ethernet controllers should + * be initialized. + * + ****************************************************************************/ + +#if CONFIG_PIC32MX_NINTERFACES == 1 +void up_netinitialize(void) +{ + (void)pic32mx_ethinitialize(0); +} +#endif +#endif /* CHIP_NETHERNET > 0 */ +#endif /* CONFIG_NET && CONFIG_PIC32MX_ETHERNET */ diff --git a/arch/mips/src/pic32mx/pic32mx-ethernet.h b/arch/mips/src/pic32mx/pic32mx-ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..fa85b782ce40a7aaca78767e4f7db8f68bc9b37e --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-ethernet.h @@ -0,0 +1,931 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-ethernet.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MX_ETH_CON1_OFFSET 0x0000 /* Ethernet Controller Control 1 Register */ +#define PIC32MX_ETH_CON1CLR_OFFSET 0x0004 +#define PIC32MX_ETH_CON1SET_OFFSET 0x0008 +#define PIC32MX_ETH_CON1INV_OFFSET 0x000c +#define PIC32MX_ETH_CON2_OFFSET 0x0010 /* Ethernet Controller Control 2 Register */ +#define PIC32MX_ETH_CON2CLR_OFFSET 0x0014 +#define PIC32MX_ETH_CON2SET_OFFSET 0x0018 +#define PIC32MX_ETH_CON2INV_OFFSET 0x001c +#define PIC32MX_ETH_TXST_OFFSET 0x0020 /* Ethernet Controller TX Packet Descriptor Start Address Register */ +#define PIC32MX_ETH_TXSTCLR_OFFSET 0x0024 +#define PIC32MX_ETH_TXSTSET_OFFSET 0x0028 +#define PIC32MX_ETH_TXSTINV_OFFSET 0x002c +#define PIC32MX_ETH_RXST_OFFSET 0x0030 /* Ethernet Controller RX Packet Descriptor Start Address Register */ +#define PIC32MX_ETH_RXSTCLR_OFFSET 0x0034 +#define PIC32MX_ETH_RXSTSET_OFFSET 0x0038 +#define PIC32MX_ETH_RXSTINV_OFFSET 0x003c + +#define PIC32MX_ETH_IEN_OFFSET 0x00c0 /* Ethernet Controller Interrupt Enable Register */ +#define PIC32MX_ETH_IENCLR_OFFSET 0x00c4 +#define PIC32MX_ETH_IENSET_OFFSET 0x00c8 +#define PIC32MX_ETH_IENINV_OFFSET 0x00cc +#define PIC32MX_ETH_IRQ_OFFSET 0x00d0 /* Ethernet Controller Interrupt Request Register */ +#define PIC32MX_ETH_IRQCLR_OFFSET 0x00d4 +#define PIC32MX_ETH_IRQSET_OFFSET 0x00d8 +#define PIC32MX_ETH_IRQINV_OFFSET 0x00dc +#define PIC32MX_ETH_STAT_OFFSET 0x00e0 /* Ethernet Controller Status Register */ + +/* RX Filtering Configuration Registers */ + +#define PIC32MX_ETH_RXFC_OFFSET 0x00a0 /* Ethernet Controller Receive Filter Configuration Register */ +#define PIC32MX_ETH_RXFCCLR_OFFSET 0x00a4 +#define PIC32MX_ETH_RXFCSET_OFFSET 0x00a8 +#define PIC32MX_ETH_RXFCINV_OFFSET 0x00ac + +#define PIC32MX_ETH_HT0_OFFSET 0x0040 /* Ethernet Controller Hash Table 0 Register */ +#define PIC32MX_ETH_HT0CLR_OFFSET 0x0044 +#define PIC32MX_ETH_HT0SET_OFFSET 0x0048 +#define PIC32MX_ETH_HT0INV_OFFSET 0x004c +#define PIC32MX_ETH_HT1_OFFSET 0x0050 /* Ethernet Controller Hash Table 1 Register */ +#define PIC32MX_ETH_HT1CLR_OFFSET 0x0054 +#define PIC32MX_ETH_HT1SET_OFFSET 0x0058 +#define PIC32MX_ETH_HT1INV_OFFSET 0x005c +#define PIC32MX_ETH_PMM0_OFFSET 0x0060 /* Ethernet Controller Pattern Match Mask 0 Register */ +#define PIC32MX_ETH_PMM0CLR_OFFSET 0x0064 +#define PIC32MX_ETH_PMM0SET_OFFSET 0x0068 +#define PIC32MX_ETH_PMM0INV_OFFSET 0x006c +#define PIC32MX_ETH_PMM1_OFFSET 0x0070 /* Ethernet Controller Pattern Match Mask 1 Register */ +#define PIC32MX_ETH_PMM1CLR_OFFSET 0x0074 +#define PIC32MX_ETH_PMM1SET_OFFSET 0x0078 +#define PIC32MX_ETH_PMM1INV_OFFSET 0x007c +#define PIC32MX_ETH_PMCS_OFFSET 0x0080 /* Ethernet Controller Pattern Match Checksum Register */ +#define PIC32MX_ETH_PMCSCLR_OFFSET 0x0084 +#define PIC32MX_ETH_PMCSSET_OFFSET 0x0088 +#define PIC32MX_ETH_PMCSINV_OFFSET 0x008c +#define PIC32MX_ETH_PMO_OFFSET 0x0090 /* Ethernet Controller Pattern Match Offset Register */ +#define PIC32MX_ETH_PMOCLR_OFFSET 0x0094 +#define PIC32MX_ETH_PMOSET_OFFSET 0x0098 +#define PIC32MX_ETH_PMOINV_OFFSET 0x009c + +/* Flow Control Configuring Register */ + +#define PIC32MX_ETH_RXWM_OFFSET 0x00b0 /* Ethernet Controller Receive Watermarks Register */ +#define PIC32MX_ETH_RXWMCLR_OFFSET 0x00b4 +#define PIC32MX_ETH_RXWMSET_OFFSET 0x00b8 +#define PIC32MX_ETH_RXWMINV_OFFSET 0x00bc + +/* Ethernet Statistics Registers */ + +#define PIC32MX_ETH_RXOVFLOW_OFFSET 0x0100 /* Ethernet Controller Receive Overflow Statistics Register */ +#define PIC32MX_ETH_RXOVFLOWCLR_OFFSET 0x0104 +#define PIC32MX_ETH_RXOVFLOWSET_OFFSET 0x0108 +#define PIC32MX_ETH_RXOVFLOWINV_OFFSET 0x010c +#define PIC32MX_ETH_FRMTXOK_OFFSET 0x0110 /* Ethernet Controller Frames Transmitted OK Statistics Register */ +#define PIC32MX_ETH_FRMTXOKCLR_OFFSET 0x0114 +#define PIC32MX_ETH_FRMTXOKSET_OFFSET 0x0118 +#define PIC32MX_ETH_FRMTXOKINV_OFFSET 0x011c +#define PIC32MX_ETH_SCOLFRM_OFFSET 0x0120 /* Ethernet Controller Single Collision Frames Statistics Register */ +#define PIC32MX_ETH_SCOLFRMCLR_OFFSET 0x0124 +#define PIC32MX_ETH_SCOLFRMSET_OFFSET 0x0128 +#define PIC32MX_ETH_SCOLFRMINV_OFFSET 0x012c +#define PIC32MX_ETH_MCOLFRM_OFFSET 0x0130 /* Ethernet Controller Multiple Collision Frames Statistics Register */ +#define PIC32MX_ETH_MCOLFRMCLR_OFFSET 0x0134 +#define PIC32MX_ETH_MCOLFRMSET_OFFSET 0x0138 +#define PIC32MX_ETH_MCOLFRMINV_OFFSET 0x013c +#define PIC32MX_ETH_FRMRXOK_OFFSET 0x0140 /* Ethernet Controller Frames Received OK Statistics Register */ +#define PIC32MX_ETH_FRMRXOKCLR_OFFSET 0x0144 +#define PIC32MX_ETH_FRMRXOKSET_OFFSET 0x0148 +#define PIC32MX_ETH_FRMRXOKINV_OFFSET 0x014c +#define PIC32MX_ETH_FCSERR_OFFSET 0x0150 /* Ethernet Controller Frame Check Sequence Error Statistics Register */ +#define PIC32MX_ETH_FCSERRCLR_OFFSET 0x0154 +#define PIC32MX_ETH_FCSERRSET_OFFSET 0x0158 +#define PIC32MX_ETH_FCSERRINV_OFFSET 0x015c +#define PIC32MX_ETH_ALGNERR_OFFSET 0x0160 /* Ethernet Controller Alignment Errors Statistics Register */ +#define PIC32MX_ETH_ALGNERRCLR_OFFSET 0x0164 +#define PIC32MX_ETH_ALGNERRSET_OFFSET 0x0168 +#define PIC32MX_ETH_ALGNERRINV_OFFSET 0x016c + +/* MAC Configuration Registers */ + +#define PIC32MX_EMAC1_CFG1_OFFSET 0x0200 /* Ethernet Controller MAC Configuration 1 Register */ +#define PIC32MX_EMAC1_CFG1CLR_OFFSET 0x0204 +#define PIC32MX_EMAC1_CFG1SET_OFFSET 0x0208 +#define PIC32MX_EMAC1_CFG1INV_OFFSET 0x020c +#define PIC32MX_EMAC1_CFG2_OFFSET 0x0210 /* Ethernet Controller MAC Configuration 2 Register */ +#define PIC32MX_EMAC1_CFG2CLR_OFFSET 0x0214 +#define PIC32MX_EMAC1_CFG2SET_OFFSET 0x0218 +#define PIC32MX_EMAC1_CFG2INV_OFFSET 0x021c +#define PIC32MX_EMAC1_IPGT_OFFSET 0x0220 /* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ +#define PIC32MX_EMAC1_IPGTCLR_OFFSET 0x0224 +#define PIC32MX_EMAC1_IPGTSET_OFFSET 0x0228 +#define PIC32MX_EMAC1_IPGTINV_OFFSET 0x022c +#define PIC32MX_EMAC1_IPGR_OFFSET 0x0230 /* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ +#define PIC32MX_EMAC1_IPGRCLR_OFFSET 0x0234 +#define PIC32MX_EMAC1_IPGRSET_OFFSET 0x0238 +#define PIC32MX_EMAC1_IPGRINV_OFFSET 0x023c +#define PIC32MX_EMAC1_CLRT_OFFSET 0x0240 /* Ethernet Controller MAC Collision Window/Retry Limit Register */ +#define PIC32MX_EMAC1_CLRTCLR_OFFSET 0x0244 +#define PIC32MX_EMAC1_CLRTSET_OFFSET 0x0248 +#define PIC32MX_EMAC1_CLRTINV_OFFSET 0x024c +#define PIC32MX_EMAC1_MAXF_OFFSET 0x0250 /* Ethernet Controller MAC Maximum Frame Length Register */ +#define PIC32MX_EMAC1_MAXFCLR_OFFSET 0x0254 +#define PIC32MX_EMAC1_MAXFSET_OFFSET 0x0258 +#define PIC32MX_EMAC1_MAXFINV_OFFSET 0x025c +#define PIC32MX_EMAC1_SUPP_OFFSET 0x0260 /* Ethernet Controller MAC PHY Support Register */ +#define PIC32MX_EMAC1_SUPPCLR_OFFSET 0x0264 +#define PIC32MX_EMAC1_SUPPSET_OFFSET 0x0268 +#define PIC32MX_EMAC1_SUPPINV_OFFSET 0x026c +#define PIC32MX_EMAC1_TEST_OFFSET 0x0270 /* Ethernet Controller MAC Test Register */ +#define PIC32MX_EMAC1_TESTCLR_OFFSET 0x0274 +#define PIC32MX_EMAC1_TESTSET_OFFSET 0x0278 +#define PIC32MX_EMAC1_TESTINV_OFFSET 0x027c + +#define PIC32MX_EMAC1_SA0_OFFSET 0x0300 /* Ethernet Controller MAC Station Address 0 Register */ +#define PIC32MX_EMAC1_SA0CLR_OFFSET 0x0304 +#define PIC32MX_EMAC1_SA0SET_OFFSET 0x0308 +#define PIC32MX_EMAC1_SA0INV_OFFSET 0x030c +#define PIC32MX_EMAC1_SA1_OFFSET 0x0310 /* Ethernet Controller MAC Station Address 1 Register */ +#define PIC32MX_EMAC1_SA1CLR_OFFSET 0x0314 +#define PIC32MX_EMAC1_SA1SET_OFFSET 0x0318 +#define PIC32MX_EMAC1_SA1INV_OFFSET 0x031c +#define PIC32MX_EMAC1_SA2_OFFSET 0x0320 /* Ethernet Controller MAC Station Address 2 Register */ +#define PIC32MX_EMAC1_SA2CLR_OFFSET 0x0324 +#define PIC32MX_EMAC1_SA2SET_OFFSET 0x0328 +#define PIC32MX_EMAC1_SA2INV_OFFSET 0x032c + +/* MII Management Registers */ + +#define PIC32MX_EMAC1_MCFG_OFFSET 0x0280 /* Ethernet Controller MAC MII Management Configuration Register */ +#define PIC32MX_EMAC1_MCFGCLR_OFFSET 0x0284 +#define PIC32MX_EMAC1_MCFGSET_OFFSET 0x0288 +#define PIC32MX_EMAC1_MCFGINV_OFFSET 0x028c +#define PIC32MX_EMAC1_MCMD_OFFSET 0x0290 /* Ethernet Controller MAC MII Management Command Register */ +#define PIC32MX_EMAC1_MCMDCLR_OFFSET 0x0294 +#define PIC32MX_EMAC1_MCMDSET_OFFSET 0x0298 +#define PIC32MX_EMAC1_MCMDINV_OFFSET 0x029c +#define PIC32MX_EMAC1_MADR_OFFSET 0x02a0 /* Ethernet Controller MAC MII Management Address Register */ +#define PIC32MX_EMAC1_MADRCLR_OFFSET 0x02a4 +#define PIC32MX_EMAC1_MADRSET_OFFSET 0x02a8 +#define PIC32MX_EMAC1_MADRINV_OFFSET 0x02ac +#define PIC32MX_EMAC1_MWTD_OFFSET 0x02b0 /* Ethernet Controller MAC MII Management Write Data Register */ +#define PIC32MX_EMAC1_MWTDCLR_OFFSET 0x02b4 +#define PIC32MX_EMAC1_MWTDSET_OFFSET 0x02b8 +#define PIC32MX_EMAC1_MWTDINV_OFFSET 0x02bc +#define PIC32MX_EMAC1_MRDD_OFFSET 0x02c0 /* Ethernet Controller MAC MII Management Read Data Register */ +#define PIC32MX_EMAC1_MRDDCLR_OFFSET 0x02c4 +#define PIC32MX_EMAC1_MRDDSET_OFFSET 0x02c8 +#define PIC32MX_EMAC1_MRDDINV_OFFSET 0x02cc +#define PIC32MX_EMAC1_MIND_OFFSET 0x02d0 /* Ethernet Controller MAC MII Management Indicators Register */ +#define PIC32MX_EMAC1_MINDCLR_OFFSET 0x02d4 +#define PIC32MX_EMAC1_MINDSET_OFFSET 0x02d8 +#define PIC32MX_EMAC1_MINDINV_OFFSET 0x02dc + +/* Register Addresses ***********************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MX_ETH_CON1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1_OFFSET) +#define PIC32MX_ETH_CON1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1CLR_OFFSET) +#define PIC32MX_ETH_CON1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1SET_OFFSET) +#define PIC32MX_ETH_CON1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1INV_OFFSET) +#define PIC32MX_ETH_CON2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2_OFFSET) +#define PIC32MX_ETH_CON2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2CLR_OFFSET) +#define PIC32MX_ETH_CON2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2SET_OFFSET) +#define PIC32MX_ETH_CON2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2INV_OFFSET) +#define PIC32MX_ETH_TXST (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXST_OFFSET) +#define PIC32MX_ETH_TXSTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTCLR_OFFSET) +#define PIC32MX_ETH_TXSTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTSET_OFFSET) +#define PIC32MX_ETH_TXSTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTINV_OFFSET) +#define PIC32MX_ETH_RXST (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXST_OFFSET) +#define PIC32MX_ETH_RXSTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTCLR_OFFSET) +#define PIC32MX_ETH_RXSTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTSET_OFFSET) +#define PIC32MX_ETH_RXSTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTINV_OFFSET) +#define PIC32MX_ETH_IEN (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IEN_OFFSET) +#define PIC32MX_ETH_IENCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENCLR_OFFSET) +#define PIC32MX_ETH_IENSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENSET_OFFSET) +#define PIC32MX_ETH_IENINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENINV_OFFSET) +#define PIC32MX_ETH_IRQ (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IRQ_OFFSET) +#define PIC32MX_ETH_IRQCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IRQCLR_OFFSET) +#define PIC32MX_ETH_IRQSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IRQSET_OFFSET) +#define PIC32MX_ETH_IRQINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IRQINV_OFFSET) +#define PIC32MX_ETH_STAT (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_STAT_OFFSET) + +/* RX Filtering Configuration Registers */ + +#define PIC32MX_ETH_RXFC (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFC_OFFSET) +#define PIC32MX_ETH_RXFCCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCCLR_OFFSET) +#define PIC32MX_ETH_RXFCSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCSET_OFFSET) +#define PIC32MX_ETH_RXFCINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCINV_OFFSET) +#define PIC32MX_ETH_HT0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0_OFFSET) +#define PIC32MX_ETH_HT0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0CLR_OFFSET) +#define PIC32MX_ETH_HT0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0SET_OFFSET) +#define PIC32MX_ETH_HT0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0INV_OFFSET) +#define PIC32MX_ETH_HT1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1_OFFSET) +#define PIC32MX_ETH_HT1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1CLR_OFFSET) +#define PIC32MX_ETH_HT1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1SET_OFFSET) +#define PIC32MX_ETH_HT1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1INV_OFFSET) +#define PIC32MX_ETH_PMM0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0_OFFSET) +#define PIC32MX_ETH_PMM0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0CLR_OFFSET) +#define PIC32MX_ETH_PMM0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0SET_OFFSET) +#define PIC32MX_ETH_PMM0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0INV_OFFSET) +#define PIC32MX_ETH_PMM1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1_OFFSET) +#define PIC32MX_ETH_PMM1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1CLR_OFFSET) +#define PIC32MX_ETH_PMM1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1SET_OFFSET) +#define PIC32MX_ETH_PMM1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1INV_OFFSET) +#define PIC32MX_ETH_PMCS (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCS_OFFSET) +#define PIC32MX_ETH_PMCSCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSCLR_OFFSET) +#define PIC32MX_ETH_PMCSSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSSET_OFFSET) +#define PIC32MX_ETH_PMCSINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSINV_OFFSET) +#define PIC32MX_ETH_PMO (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMO_OFFSET) +#define PIC32MX_ETH_PMOCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOCLR_OFFSET) +#define PIC32MX_ETH_PMOSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOSET_OFFSET) +#define PIC32MX_ETH_PMOINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOINV_OFFSET) + +/* Flow Control Configuring Register */ + +#define PIC32MX_ETH_RXWM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWM_OFFSET) +#define PIC32MX_ETH_RXWMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMCLR_OFFSET) +#define PIC32MX_ETH_RXWMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMSET_OFFSET) +#define PIC32MX_ETH_RXWMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMINV_OFFSET) + +/* Ethernet Statistics Registers */ + +#define PIC32MX_ETH_RXOVFLOW (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOW_OFFSET) +#define PIC32MX_ETH_RXOVFLOWCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWCLR_OFFSET) +#define PIC32MX_ETH_RXOVFLOWSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWSET_OFFSET) +#define PIC32MX_ETH_RXOVFLOWINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWINV_OFFSET) +#define PIC32MX_ETH_FRMTXOK (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOK_OFFSET) +#define PIC32MX_ETH_FRMTXOKCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKCLR_OFFSET) +#define PIC32MX_ETH_FRMTXOKSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKSET_OFFSET) +#define PIC32MX_ETH_FRMTXOKINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKINV_OFFSET) +#define PIC32MX_ETH_SCOLFRM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRM_OFFSET) +#define PIC32MX_ETH_SCOLFRMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMCLR_OFFSET) +#define PIC32MX_ETH_SCOLFRMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMSET_OFFSET) +#define PIC32MX_ETH_SCOLFRMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMINV_OFFSET) +#define PIC32MX_ETH_MCOLFRM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRM_OFFSET) +#define PIC32MX_ETH_MCOLFRMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMCLR_OFFSET) +#define PIC32MX_ETH_MCOLFRMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMSET_OFFSET) +#define PIC32MX_ETH_MCOLFRMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMINV_OFFSET) +#define PIC32MX_ETH_FRMRXOK (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOK_OFFSET) +#define PIC32MX_ETH_FRMRXOKCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKCLR_OFFSET) +#define PIC32MX_ETH_FRMRXOKSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKSET_OFFSET) +#define PIC32MX_ETH_FRMRXOKINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKINV_OFFSET) +#define PIC32MX_ETH_FCSERR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERR_OFFSET) +#define PIC32MX_ETH_FCSERRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRCLR_OFFSET) +#define PIC32MX_ETH_FCSERRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRSET_OFFSET) +#define PIC32MX_ETH_FCSERRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRINV_OFFSET) +#define PIC32MX_ETH_ALGNERR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERR_OFFSET) +#define PIC32MX_ETH_ALGNERRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRCLR_OFFSET) +#define PIC32MX_ETH_ALGNERRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRSET_OFFSET) +#define PIC32MX_ETH_ALGNERRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRINV_OFFSET) + +/* MAC Configuration Registers */ + +#define PIC32MX_EMAC1_CFG1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1_OFFSET) +#define PIC32MX_EMAC1_CFG1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1CLR_OFFSET) +#define PIC32MX_EMAC1_CFG1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1SET_OFFSET) +#define PIC32MX_EMAC1_CFG1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1INV_OFFSET) +#define PIC32MX_EMAC1_CFG2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2_OFFSET) +#define PIC32MX_EMAC1_CFG2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2CLR_OFFSET) +#define PIC32MX_EMAC1_CFG2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2SET_OFFSET) +#define PIC32MX_EMAC1_CFG2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2INV_OFFSET) +#define PIC32MX_EMAC1_IPGT (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGT_OFFSET) +#define PIC32MX_EMAC1_IPGTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTCLR_OFFSET) +#define PIC32MX_EMAC1_IPGTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTSET_OFFSET) +#define PIC32MX_EMAC1_IPGTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTINV_OFFSET) +#define PIC32MX_EMAC1_IPGR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGR_OFFSET) +#define PIC32MX_EMAC1_IPGRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRCLR_OFFSET) +#define PIC32MX_EMAC1_IPGRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRSET_OFFSET) +#define PIC32MX_EMAC1_IPGRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRINV_OFFSET) +#define PIC32MX_EMAC1_CLRT (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRT_OFFSET) +#define PIC32MX_EMAC1_CLRTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTCLR_OFFSET) +#define PIC32MX_EMAC1_CLRTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTSET_OFFSET) +#define PIC32MX_EMAC1_CLRTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTINV_OFFSET) +#define PIC32MX_EMAC1_MAXF (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXF_OFFSET) +#define PIC32MX_EMAC1_MAXFCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFCLR_OFFSET) +#define PIC32MX_EMAC1_MAXFSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFSET_OFFSET) +#define PIC32MX_EMAC1_MAXFINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFINV_OFFSET) +#define PIC32MX_EMAC1_SUPP (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPP_OFFSET) +#define PIC32MX_EMAC1_SUPPCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPCLR_OFFSET) +#define PIC32MX_EMAC1_SUPPSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPSET_OFFSET) +#define PIC32MX_EMAC1_SUPPINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPINV_OFFSET) +#define PIC32MX_EMAC1_TEST (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TEST_OFFSET) +#define PIC32MX_EMAC1_TESTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTCLR_OFFSET) +#define PIC32MX_EMAC1_TESTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTSET_OFFSET) +#define PIC32MX_EMAC1_TESTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTINV_OFFSET) +#define PIC32MX_EMAC1_SA0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0_OFFSET) +#define PIC32MX_EMAC1_SA0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0CLR_OFFSET) +#define PIC32MX_EMAC1_SA0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0SET_OFFSET) +#define PIC32MX_EMAC1_SA0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0INV_OFFSET) +#define PIC32MX_EMAC1_SA1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1_OFFSET) +#define PIC32MX_EMAC1_SA1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1CLR_OFFSET) +#define PIC32MX_EMAC1_SA1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1SET_OFFSET) +#define PIC32MX_EMAC1_SA1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1INV_OFFSET) +#define PIC32MX_EMAC1_SA2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2_OFFSET) +#define PIC32MX_EMAC1_SA2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2CLR_OFFSET) +#define PIC32MX_EMAC1_SA2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2SET_OFFSET) +#define PIC32MX_EMAC1_SA2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2INV_OFFSET) + +/* MII Management Registers */ + +#define PIC32MX_EMAC1_MCFG (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFG_OFFSET) +#define PIC32MX_EMAC1_MCFGCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGCLR_OFFSET) +#define PIC32MX_EMAC1_MCFGSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGSET_OFFSET) +#define PIC32MX_EMAC1_MCFGINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGINV_OFFSET) +#define PIC32MX_EMAC1_MCMD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMD_OFFSET) +#define PIC32MX_EMAC1_MCMDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDCLR_OFFSET) +#define PIC32MX_EMAC1_MCMDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDSET_OFFSET) +#define PIC32MX_EMAC1_MCMDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDINV_OFFSET) +#define PIC32MX_EMAC1_MADR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADR_OFFSET) +#define PIC32MX_EMAC1_MADRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRCLR_OFFSET) +#define PIC32MX_EMAC1_MADRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRSET_OFFSET) +#define PIC32MX_EMAC1_MADRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRINV_OFFSET) +#define PIC32MX_EMAC1_MWTD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTD_OFFSET) +#define PIC32MX_EMAC1_MWTDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDCLR_OFFSET) +#define PIC32MX_EMAC1_MWTDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDSET_OFFSET) +#define PIC32MX_EMAC1_MWTDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDINV_OFFSET) +#define PIC32MX_EMAC1_MRDD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDD_OFFSET) +#define PIC32MX_EMAC1_MRDDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDCLR_OFFSET) +#define PIC32MX_EMAC1_MRDDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDSET_OFFSET) +#define PIC32MX_EMAC1_MRDDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDINV_OFFSET ) +#define PIC32MX_EMAC1_MIND (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MIND_OFFSET) +#define PIC32MX_EMAC1_MINDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDCLR_OFFSET) +#define PIC32MX_EMAC1_MINDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDSET_OFFSET) +#define PIC32MX_EMAC1_MINDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDINV_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ +/* Ethernet Controller Control 1 Register */ + +#define ETH_CON1_BUFCDEC (1 << 0) /* Bit 0: : Descriptor Buffer Count Decrement bit */ + /* Bit 1-3: Reserved */ +#define ETH_CON1_MANFC (1 << 4) /* Bit 4: Manual Flow Control bit */ + /* Bit 5-6: Reserved */ +#define ETH_CON1_AUTOFC (1 << 7) /* Bit 7: Automatic Flow Control bit */ +#define ETH_CON1_RXEN (1 << 8) /* Bit 8: Receive Enable bit */ +#define ETH_CON1_TXRTS (1 << 9) /* Bit 9: Transmit Request to Send bit */ + /* Bit 10-12: Reserved */ +#define ETH_CON1_SIDL (1 << 13) /* Bit 13: Ethernet Stop in Idle Mode bit */ + /* Bit 14: Reserved */ +#define ETH_CON1_ON (1 << 15) /* Bit 15: Ethernet ON bit */ +#define ETH_CON1_PTV_SHIFT (16) /* Bits 16-31: PAUSE Timer Value bits */ +#define ETH_CON1_PTV_MASK (0xffff << ETH_CON1_PTV_SHIFT) + +/* Ethernet Controller Control 2 Register */ + /* Bits 0-3: Reserved */ +#define ETH_CON2_RXBUFSZ_SHIFT (4) /* Bits 4-10: RX Data Buffer Size for All RX Descriptors */ +#define ETH_CON2_RXBUFSZ_MASK (0x7f << ETH_CON2_RXBUFSZ_SHIFT) +# define ETH_CON2_RXBUFSZ(n) (((n) >> 4) << ETH_CON2_RXBUFSZ_SHIFT) /* n=16, 32, 48, ... 2032 */ + /* Bits 11-31: Reserved */ + +/* Ethernet Controller TX Packet Descriptor Start Address Register (32-bit address) */ +/* Ethernet Controller RX Packet Descriptor Start Address Register (32-bit address) */ + +/* Ethernet Controller Interrupt Enable Register */ +/* Ethernet Controller Interrupt Request Register */ + +#define ETH_INT_RXOVFLW (1 << 0) /* Bit 0: Receive FIFO overflow interrupt */ +#define ETH_INT_RXBUFNA (1 << 1) /* Bit 1: Receive buffer not available interrupt */ +#define ETH_INT_TXABORT (1 << 2) /* Bit 2: Transmitter abort interrupt */ +#define ETH_INT_TXDONE (1 << 3) /* Bit 3: Transmitter done interrupt */ + /* Bit 4: Reserved */ +#define ETH_INT_RXACT (1 << 5) /* Bit 5: RX activity interrupt */ +#define ETH_INT_PKTPEND (1 << 6) /* Bit 6: Packet pending interrupt */ +#define ETH_INT_RXDONE (1 << 7) /* Bit 7: Receiver done interrupt */ +#define ETH_INT_FWMARK (1 << 8) /* Bit 8: Full watermark interrupt */ +#define ETH_INT_EWMARK (1 << 9) /* Bit 9: Empty watermark interrupt */ + /* Bits 10-12: Reserved */ +#define ETH_INT_RXBUSE (1 << 13) /* Bit 13: Receive BVCI bus error interrupt */ +#define ETH_INT_TXBUSE (1 << 14) /* Bit 14: Transmit BVCI bus error interrupt */ + /* Bits 15-31: Reserved */ +#define ETH_INT_ALLINTS (0x000063ef) + +/* Ethernet Controller Status Register */ + + /* Bits 0-4: Reserved */ +#define ETH_STAT_RXBUSY (1 << 5) /* Bit 5: Receive busy */ +#define ETH_STAT_TXBUSY (1 << 6) /* Bit 6: Transmit busy */ +#define ETH_STAT_ETHBUSY (1 << 7) /* Bit 7: Ethernet module busy */ + /* Bits 8-15: Reserved */ +#define ETH_STAT_BUFCNT_SHIFT (18) /* Bits 16-23: Packet buffer count */ +#define ETH_STAT_BUFCNT_MASK (0xff << ETH_STAT_BUFCNT_SHIFT) + /* Bits 24-31: Reserved */ + +/* RX Filtering Configuration Registers */ +/* Ethernet Controller Receive Filter Configuration Register */ + +#define ETH_RXFC_BCEN (1 << 0) /* Bit 0: Broadcast filter enable */ +#define ETH_RXFC_MCEN (1 << 1) /* Bit 1: Multicast filter enable */ +#define ETH_RXFC_NOTMEEN (1 << 2) /* Bit 2: Not Me unicast filter enable */ +#define ETH_RXFC_UCEN (1 << 3) /* Bit 3: Unicast filter enable */ +#define ETH_RXFC_RUNTEN (1 << 4) /* Bit 4: Runt enable */ +#define ETH_RXFC_RUNTERREN (1 << 5) /* Bit 5: Runt error collection enable */ +#define ETH_RXFC_CRCOKEN (1 << 6) /* Bit 6: CRC OK enable enable */ +#define ETH_RXFC_CRCERREN (1 << 7) /* Bit 7: CRC error collection enable */ +#define ETH_RXFC_PMMODE_SHIFT (8) /* Bits 8-11: Pattern match mode */ +#define ETH_RXFC_PMMODE_MASK (15 << ETH_RXFC_PMMODE_SHIFT) +# define ETH_RXFC_PMMODE_DISABLED (0 << ETH_RXFC_PMMODE_SHIFT) /* Pattern match is always unsuccessful */ +# define ETH_RXFC_PMMODE_PMCKSUM (1 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches */ +# define ETH_RXFC_PMMODE_DASTA (2 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==STA */ +/* #define ETH_RXFC_PMMODE_DASTA (3 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==STA */ +# define ETH_RXFC_PMMODE_DAUCAST (4 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==Unicast address */ +/* #define ETH_RXFC_PMMODE_DAUCAST (5 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==Unicast address */ +# define ETH_RXFC_PMMODE_DABCAST (6 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==Broadcast address */ +/* #define ETH_RXFC_PMMODE_DABCAST (7 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==Broadcast address */ +# define ETH_RXFC_PMMODE_HASH (8 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & Hash Table Filter match */ +# define ETH_RXFC_PMMODE_MAGIC (9 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & Packet = Magic Packet */ +#define ETH_RXFC_NOTPM (1 << 12) /* Bit 12: Pattern match inversion */ + /* Bit 13: Reserved */ +#define ETH_RXFC_MPEN (1 << 14) /* Bit 14: Magic packet enable */ +#define ETH_RXFC_HTEN (1 << 15) /* Bit 15: Hash table filtering enable */ + /* Bits 16-31: Reserved */ +/* Ethernet Controller Hash Table 0 Register */ + +#define ETH_HT0_BYTE0_SHIFT (0) /* Bits 0-7: Hash table byte 0, HT[0-7] */ +#define ETH_HT0_BYTE0_MASK (0xff << ETH_HT0_BYTE0_SHIFT) +#define ETH_HT0_BYTE1_SHIFT (8) /* Bits 8-15: Hash table byte 1, HT[8-15] */ +#define ETH_HT0_BYTE1_MASK (0xff << ETH_HT0_BYTE1_SHIFT) +#define ETH_HT0_BYTE2_SHIFT (16) /* Bits 16-23: Hash table byte 2, HT[16-23] */ +#define ETH_HT0_BYTE2_MASK (0xff << ETH_HT0_BYTE2_SHIFT) +#define ETH_HT0_BYTE3_SHIFT (24) /* Bits 24-31: Hash table byte 3, HT[24-31] */ +#define ETH_HT0_BYTE3_MASK (0xff << ETH_HT0_BYTE3_SHIFT) + +/* Ethernet Controller Hash Table 1 Register */ + +#define ETH_HT1_BYTE4_SHIFT (0) /* Bits 0-7: Hash table byte 4, HT[32-39] */ +#define ETH_HT1_BYTE4_MASK (0xff << ETH_HT1_BYTE4_SHIFT) +#define ETH_HT1_BYTE5_SHIFT (8) /* Bits 8-15: Hash table byte 5, HT[40-47] */ +#define ETH_HT1_BYTE5_MASK (0xff << ETH_HT1_BYTE5_SHIFT) +#define ETH_HT1_BYTE6_SHIFT (16) /* Bits 16-23: Hash table byte 6, HT[48-55] */ +#define ETH_HT1_BYTE6_MASK (0xff << ETH_HT1_BYTE6_SHIFT) +#define ETH_HT1_BYTE7_SHIFT (24) /* Bits 24-31: Hash table byte 7, HT[56-63] */ +#define ETH_HT1_BYTE7_MASK (0xff << ETH_HT1_BYTE7_SHIFT) + +/* Ethernet Controller Pattern Match Mask 0 Register */ + +#define ETH_PMM0_MASK0_SHIFT (0) /* Bits 0-7: Patch mask 0, PMM[0-7] */ +#define ETH_PMM0_MASK0_MASK (0xff << ETH_PMM0_MASK0_SHIFT) +#define ETH_PMM0_MASK1_SHIFT (8) /* Bits 8-15: Patch mask 1, PMM[8-15] */ +#define ETH_PMM0_MASK1_MASK (0xff << ETH_PMM0_MASK1_SHIFT) +#define ETH_PMM0_MASK2_SHIFT (16) /* Bits 16-23: Patch mask 2, PMM[16-23] */ +#define ETH_PMM0_MASK2_MASK (0xff << ETH_PMM0_MASK2_SHIFT) +#define ETH_PMM0_MASK3_SHIFT (24) /* Bits 24-31: Patch mask 3, PMM[24-31] */ +#define ETH_PMM0_MASK3_MASK (0xff << ETH_PMM0_MASK3_SHIFT) + +/* Ethernet Controller Pattern Match Mask 1 Register */ + +#define ETH_PMM1_MASK4_SHIFT (0) /* Bits 0-7: Patch mask 4, PMM[32-39] */ +#define ETH_PMM1_MASK4_MASK (0xff << ETH_PMM1_MASK4_SHIFT) +#define ETH_PMM1_MASK5_SHIFT (8) /* Bits 8-15: Patch mask 5, PMM[40-47] */ +#define ETH_PMM1_MASK5_MASK (0xff << ETH_PMM1_MASK5_SHIFT) +#define ETH_PMM1_MASK6_SHIFT (16) /* Bits 16-23: Patch mask 6, PMM[48-55] */ +#define ETH_PMM1_MASK6_MASK (0xff << ETH_PMM1_MASK6_SHIFT) +#define ETH_PMM1_MASK7_SHIFT (24) /* Bits 24-31: Patch mask 7, PMM[56-63] */ +#define ETH_PMM1_MASK7_MASK (0xff << ETH_PMM1_MASK7_SHIFT) + +/* Ethernet Controller Pattern Match Checksum Register */ + +#define ETH_PMCS_CKSM0_SHIFT (0) /* Bits 0-7: Pattern match checksum 0 bits, PMCS[0-7] */ +#define ETH_PMCS_CKSM0_MASK (0xff << ETH_PMCS_CKSM0_SHIFT) +#define ETH_PMCS_CKSM1_SHIFT (8) /* Bits 8-15: Pattern match checksum 1 bits, PMCS[8-15] */ +#define ETH_PMCS_CKSM1_MASK (0xff << ETH_PMCS_CKSM1_SHIFT) + +/* Ethernet Controller Pattern Match Offset Register */ + +#define ETH_PMO_MASK (0xffff) + +/* Flow Control Configuring Register */ +/* Ethernet Controller Receive Watermarks Register */ + +#define ETH_RXWM_RXEWM_SHIFT (0) /* Bits 0-7: Receive empty watermark bits */ +#define ETH_RXWM_RXEWM_MASK (0xff << ETH_RXWM_RXEWM_SHIFT) +#define ETH_RXWM_RXFWM_SHIFT (8) /* Bits 8-15: Receive full watermark bits */ +#define ETH_RXWM_RXFWM_MASK (0xff << ETH_RXWM_RXFWM_SHIFT) + +/* Ethernet Statistics Registers */ +/* Ethernet Controller Receive Overflow Statistics Register */ + +#define ETH_RXOVFLOW_MASK (0xffff) + +/* Ethernet Controller Frames Transmitted OK Statistics Register */ + +#define ETH_FRMTXOK_MASK (0xffff) + +/* Ethernet Controller Single Collision Frames Statistics Register */ + +#define ETH_SCOLFRM_MASK (0xffff) + +/* Ethernet Controller Multiple Collision Frames Statistics Register */ + +#define ETH_MCOLFRM_MASK (0xffff) + +/* Ethernet Controller Frames Received OK Statistics Register */ + +#define ETH_FRMRXOK_MASK (0xffff) + +/* Ethernet Controller Frame Check Sequence Error Statistics Register */ + +#define ETH_FCSERR_MASK (0xffff) + +/* Ethernet Controller Alignment Errors Statistics Register */ + +#define ETH_ALGNERR_MASK (0xffff) + +/* MAC Configuration Registers */ +/* Ethernet Controller MAC Configuration 1 Register */ + +#define EMAC1_CFG1_RXEN (1 << 0) /* Bit 0: MAC Receive enable */ +#define EMAC1_CFG1_PASSALL (1 << 1) /* Bit 1: MAC Pass all all receive frames */ +#define EMAC1_CFG1_RXPAUSE (1 << 2) /* Bit 2: MAC RX flow control bit */ +#define EMAC1_CFG1_TXPAUSE (1 << 3) /* Bit 3: MAC TX flow control */ +#define EMAC1_CFG1_LOOPBACK (1 << 4) /* Bit 4: MAC loopback mode */ + /* Bits 5-7: Reserved */ +#define EMAC1_CFG1_TXRST (1 << 8) /* Bit 8: Reset TX function */ +#define EMAC1_CFG1_MCSTXRST (1 << 9) /* Bit 9: Reset MCS/TX */ +#define EMAC1_CFG1_RXRST (1 << 10) /* Bit 10: Reset RX */ +#define EMAC1_CFG1_MCSRXRST (1 << 11) /* Bit 11: Reset MCS/RX */ + /* Bits 12-13: Reserved */ +#define EMAC1_CFG1_SIMRST (1 << 14) /* Bit 14: Simulation reset */ +#define EMAC1_CFG1_SOFTRST (1 << 15) /* Bit 15: Soft reset */ + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Configuration 2 Register */ + +#define EMAC1_CFG2_FULLDPLX (1 << 0) /* Bit 0: Full duplex operation */ +#define EMAC1_CFG2_LENGTHCK (1 << 1) /* Bit 1: Frame length checking */ +#define EMAC1_CFG2_HUGEFRM (1 << 2) /* Bit 2: Huge frame enable */ +#define EMAC1_CFG2_DELAYCRC (1 << 3) /* Bit 3: Delayed CRC */ +#define EMAC1_CFG2_CRCEN (1 << 4) /* Bit 4: CRC enable */ +#define EMAC1_CFG2_PADCRCEN (1 << 5) /* Bit 5: Pad/CRC enable */ +#define EMAC1_CFG2_VLANPADEN (1 << 6) /* Bit 6: VLAN pad enable */ +#define EMAC1_CFG2_AUTOPADEN (1 << 7) /* Bit 7: Auto detect pad enable */ +#define EMAC1_CFG2_PUREPRE (1 << 8) /* Bit 8: Pure preamble enforcement */ +#define EMAC1_CFG2_LONGPRE (1 << 9) /* Bit 9: Long preamble enforcement */ + /* Bits 10-11: Reserved */ +#define EMAC1_CFG2_NOBKOFF (1 << 12) /* Bit 12: No backoff */ +#define EMAC1_CFG2_BPNOBKOFF (1 << 13) /* Bit 13: Back pressure/no backoff */ +#define EMAC1_CFG2_EXCESSDFR (1 << 14) /* Bit 14: Excess defer */ + /* Bits 15-31: Reserved */ +/* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGT_SHIFT (0) /* Bits 0-6 */ +#define EMAC1_IPGT_MASK (0x7f << EMAC1_IPGT_SHIFT) + /* Bits 7-31: Reserved */ +/* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGR_GAP2_SHIFT (0) /* Bits 0-6: Gap part 2 */ +#define EMAC1_IPGR_GAP2_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bit 7: Reserved */ +#define EMAC1_IPGR_GAP1_SHIFT (8) /* Bits 8-18: Gap part 1 */ +#define EMAC1_IPGR_GAP1_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bits 15-31: Reserved */ +/* Ethernet Controller MAC Collision Window/Retry Limit Register */ + +#define EMAC1_CLRT_RETX_SHIFT (0) /* Bits 0-3: Retransmission maximum */ +#define EMAC1_CLRT_RETX_MASK (15 << EMAC1_CLRT_RETX_SHIFT) + /* Bits 4-7: Reserved */ +#define EMAC1_CLRT_CWINDOW_SHIFT (8) /* Bits 8-13: Collision window */ +#define EMAC1_CLRT_CWINDOW_MASK (0x3f << EMAC1_CLRT_CWINDOW_SHIFT) + /* Bits 14-31: Reserved */ +/* Ethernet Controller MAC Maximum Frame Length Register */ + +#define EMAC1_MAXF_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MAXF_MASK (0xffff << EMAC1_MAXF_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC PHY Support Register */ + /* Bits 0-7: Reserved */ +#define EMAC1_SUPP_SPEEDRMII (1 << 8) /* Bit 8: RMII Speed0=10Bps 1=100Bps */ + /* Bits 9-10: Reserved */ +#define EMAC1_SUPP_RESETRMII (1 << 11) /* Bit 11: Reset RMII Logic */ + /* Bits 12-31: Reserved */ +/* Ethernet Controller MAC Test Register */ + +#define EMAC1_TEST_SHRTQNTA (1 << 0) /* Bit 0: Shortcut pause quanta */ +#define EMAC1_TEST_TESTPAUSE (1 << 1) /* Bit 1: Test pause */ +#define EMAC1_TEST_TESTBP (1 << 2) /* Bit 2: Test packpressure */ + /* Bits 3-31: Reserved */ +/* Ethernet Controller MAC Station Address 0 Register */ + +#define EMAC1_SA0_STNADDR6_SHIFT (0) /* Bits 0-7: Station address 5th octet */ +#define EMAC1_SA0_STNADDR6_MASK (0xff << EMAC1_SA0_STNADDR6_SHIFT) +#define EMAC1_SA0_STNADDR5_SHIFT (8) /* Bits 8-15: Station address 6th octet */ +#define EMAC1_SA0_STNADDR5_MASK (0xff << EMAC1_SA0_STNADDR5_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 1 Register */ + +#define EMAC1_SA1_STNADDR4_SHIFT (0) /* Bits 0-7: Station address 4th octet */ +#define EMAC1_SA1_STNADDR4_MASK (0xff << EMAC1_SA0_STNADDR4_SHIFT) +#define EMAC1_SA1_STNADDR3_SHIFT (8) /* Bits 8-15: Station address 3rd octet */ +#define EMAC1_SA1_STNADDR3_MASK (0xff << EMAC1_SA0_STNADDR3_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 2 Register */ + +#define EMAC1_SA2_STNADDR2_SHIFT (0) /* Bits 0-7: Station address 2nd octet */ +#define EMAC1_SA2_STNADDR2_MASK (0xff << EMAC1_SA2_STNADDR2_SHIFT) +#define EMAC1_SA2_STNADDR1_SHIFT (8) /* Bits 8-15: Station address 1st octet */ +#define EMAC1_SA2_STNADDR1_MASK (0xff << EMAC1_SA2_STNADDR1_SHIFT) + /* Bits 16-31: Reserved */ +/* MII Management Registers */ + +/* Ethernet Controller MAC MII Management Configuration Register */ + +#define EMAC1_MCFG_SCANINC (1 << 0) /* Bit 0: Scan increment */ +#define EMAC1_MCFG_NOPRE (1 << 1) /* Bit 1: Suppress preamble */ +#define EMAC1_MCFG_CLKSEL_SHIFT (2) /* Bits 2-5: Clock select */ +#define EMAC1_MCFG_CLKSEL_MASK (15 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV4 (0 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV6 (2 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV8 (3 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV10 (4 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV14 (5 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV20 (6 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV40 (8 << EMAC1_MCFG_CLKSEL_SHIFT) + /* Bits 6-14: Reserved */ +#define EMAC1_MCFG_MGMTRST (1 << 15) /* Bit 15: Reset MII mgmt */ + /* Bits 16-31: Reserved */ + +/* Ethernet Controller MAC MII Management Command Register */ + +#define EMAC1_MCMD_READ (1 << 0) /* Bit 0: Single read cycle */ +#define EMAC1_MCMD_SCAN (1 << 1) /* Bit 1: Continuous read cycles */ + /* Bits 2-31: Reserved */ +#define EMAC1_MCMD_WRITE (0) + +/* Ethernet Controller MAC MII Management Address Register */ + +#define EMAC1_MADR_REGADDR_SHIFT (0) /* Bits 0-4: Register address */ +#define EMAC1_MADR_REGADDR_MASK (31 << EMAC1_MADR_REGADDR_SHIFT) + /* Bits 7-5: Reserved */ +#define EMAC1_MADR_PHYADDR_SHIFT (8) /* Bits 8-12: PHY address */ +#define EMAC1_MADR_PHYADDR_MASK (31 << EMAC1_MADR_PHYADDR_SHIFT) + /* Bits 13-31: Reserved */ +/* Ethernet Controller MAC MII Management Write Data Register */ + +#define EMAC1_MWTD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MWTD_MASK (0xffff << EMAC1_MWTD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Read Data Register */ + +#define EMAC1_MRDD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MRDD_MASK (0xffff << EMAC1_MRDD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Indicators Register */ + +#define EMAC1_MIND_MIIMBUSY (1 << 0) /* Bit 0: Busy */ +#define EMAC1_MIND_SCAN (1 << 1) /* Bit 1: Scanning */ +#define EMAC1_MIND_NOTVALID (1 << 2) /* Bit 2: Not valid */ +#define EMAC1_MIND_LINKFAIL (1 << 3) /* Bit 3: MII link fail */ + /* Bits 4-31: Reserved */ + +/* Descriptors Offsets **********************************************************************/ + +/* Tx descriptor offsets. The NEXTED field is only present if NPV=1 */ + +#define PIC32MX_TXDESC_STATUS 0x00 /* Various status bits (32-bits) */ +#define PIC32MX_TXDESC_ADDRESS 0x04 /* Data buffer address (32-bits) */ +#define PIC32MX_TXDESC_TSV1 0x08 /* Transmit filter status vector 1 (32-bits) */ +#define PIC32MX_TXDESC_TSV2 0x0c /* Transmit filter status vector 2 (32-bits) */ +#define PIC32MX_TXLINEAR_SIZE 0x10 /* Size in bytes of one linear Tx descriptor */ + +#define PIC32MX_TXDESC_NEXTED 0x10 /* Next Ethernet Descriptor (ED) */ +#define PIC32MX_TXLINKED_SIZE 0x14 /* Size in bytes of one linked Tx descriptor */ + +/* Tx descriptor uint32_t* indices */ + +#define TXDESC_STATUS 0 /* Various status bits (32-bits) */ +#define TXDESC_ADDRESS 1 /* Data buffer address (32-bits) */ +#define TXDESC_TSV1 2 /* Transmit filter status vector 1 (32-bits) */ +#define TXDESC_TSV2 3 /* Transmit filter status vector 2 (32-bits) */ +#define TXLINEAR_SIZE 4 /* Size in 32-bit words of one linear Tx descriptor */ + +#define TXDESC_NEXTED 4 /* Next Ethernet Descriptor (ED) */ +#define TXLINKED_SIZE 5 /* Size in 32-bit words of one linked Tx descriptor */ + +/* Rx descriptor offsets. The NEXTED field is only present if NPV=1 */ + +#define PIC32MX_RXDESC_STATUS 0x00 /* Various status bits (32-bits) */ +#define PIC32MX_RXDESC_ADDRESS 0x04 /* Data buffer address (32-bits) */ +#define PIC32MX_RXDESC_RSV1 0x08 /* Receive filter status vector 1 and checksum (32-bits) */ +#define PIC32MX_RXDESC_RSV2 0x0c /* Receive filter status vector 2 (32-bits) */ +#define PIC32MX_RXLINEAR_SIZE 0x10 /* Size in bytes of one linear Rx descriptor */ + +#define PIC32MX_RXDESC_NEXTED 0x10 /* Next Ethernet Descriptor (ED) */ +#define PIC32MX_RXLINKED_SIZE 0x14 /* Size in bytes of one linked Rx descriptor */ + +/* Rx descriptor offsets uint32_t* indices */ + +#define RXDESC_STATUS 0 /* Various status bits (32-bits) */ +#define RXDESC_ADDRESS 1 /* Data buffer address (32-bits) */ +#define RXDESC_RSV1 2 /* Receive filter status vector 1 and checksum (32-bits) */ +#define RXDESC_RSV2 3 /* Receive filter status vector 2 (32-bits) */ +#define RXLINEAR_SIZE 4 /* Size in 32-bit words of one linear Rx descriptor */ + +#define RXDESC_NEXTED 4 /* Next Ethernet Descriptor (ED) */ +#define RXLINKED_SIZE 5 /* Size in 32-bit words of one linked Rx descriptor */ + +/* Descriptor Bit Definitions ***************************************************************/ +/* Tx descriptor status bit definitions */ + /* Bits 0-6: Reserved */ +#define TXDESC_STATUS_EOWN (1 << 7) /* Bit 7: 1=Ethernet controller owns */ +#define TXDESC_STATUS_SOWN (0) /* 0=Software owns */ +#define TXDESC_STATUS_NPV (1 << 8) /* Bit 8: Next ED pointer valid enable */ +#define TXDESC_STATUS_USER1_SHIFT (9) /* Bits 9-15: User-defined */ +#define TXDESC_STATUS_USER1_MASK (0x7f << TXDESC_STATUS_USER2_SHIFT) +#define TXDESC_STATUS_BYTECOUNT_SHIFT (16) /* Bits 16-26: Byte Count */ +#define TXDESC_STATUS_BYTECOUNT_MASK (0x7ff << TXDESC_STATUS_BYTECOUNT_SHIFT) +#define TXDESC_STATUS_USER2_SHIFT (27) /* Bits 27-29: User-defined */ +#define TXDESC_STATUS_USER2_MASK (7 << TXDESC_STATUS_USER1_SHIFT) +#define TXDESC_STATUS_EOP (1 << 30) /* Bit 30: End of packet enable */ +#define TXDESC_STATUS_SOP (1 << 31) /* Bit 31: Start of packet enable */ + +/* Tx descriptor Transmit filter status vector bit definitions */ + +#define TXDESC_TSV1_BYTECOUNT_SHIFT (0) /* Bits 0-15: TSV[32-47] Total bytes transmitted */ +#define TXDESC_TSV1_BYTECOUNT_MASK (0xffff << TXDESC_TSV1_BYTECOUNT_SHIFT) +#define TXDESC_TSV1_CONTROL (1 << 16) /* Bit 16: TSV48 Transmit Control Frame */ +#define TXDESC_TSV1_PAUSE (1 << 17) /* Bit 17: TSV49 Transmit PAUSE Control Frame */ +#define TXDESC_TSV1_BPAPPLIED (1 << 18) /* Bit 18: TSV50 Transmit Backpressure Applied */ +#define TXDESC_TSV1_VLAN (1 << 19) /* Bit 19: TSV51 Transmit VLAN Tagged Frame */ + /* Bits 20-23: Reserved */ +#define TXDESC_TSV1_USER_SHIFT (24) /* Bits 24-31: User-defined */ +#define TXDESC_TSV1_USER_MASK (0xff << TXDESC_STATUS_USER1_SHIFT) + +#define TXDESC_TSV2_BYTECOUNT_SHIFT (0) /* Bits 0-15: TSV15:0 Transmit Byte Count */ +#define TXDESC_TSV2_BYTECOUNT_MASK (0xffff << TXDESC_TSV2_BYTECOUNT_SHIFT) +#define TXDESC_TSV2_COLCOUNT_SHIFT (0) /* Bits 16-19: TSV16-19 Transmit Collision Count */ +#define TXDESC_TSV2_COLCOUNT_MASK (15 << TXDESC_TSV2_COLCOUNT_SHIFT) +#define TXDESC_TSV2_TXCRCE (1 << 20) /* Bit 20: TSV20 Transmit CRC Error */ +#define TXDESC_TSV2_TXLCE (1 << 21) /* Bit 21: TSV21 Transmit Length Check Error */ +#define TXDESC_TSV2_TXOOR (1 << 22) /* Bit 22: TSV22 Transmit Length Out Of Range */ +#define TXDESC_TSV2_TXDONE (1 << 23) /* Bit 23: TSV23 Transmit Done */ +#define TXDESC_TSV2_MCAST (1 << 24) /* Bit 24: TSV24 Transmit Multicast */ +#define TXDESC_TSV2_BCAST (1 << 25) /* Bit 25: TSV25 Transmit Broadcast */ +#define TXDESC_TSV2_PKTDFR (1 << 26) /* Bit 26: TSV26 Transmit Packet Defer */ +#define TXDESC_TSV2_EXCESSDFR (1 << 27) /* Bit 27: TSV27 Transmit Excessive Defer */ +#define TXDESC_TSV2_MAXOL (1 << 28) /* Bit 28: TSV28 Transmit Maximum Collision */ +#define TXDESC_TSV2_TXLC (1 << 29) /* Bit 29: TSV29 Transmit Late Collision */ +#define TXDESC_TSV2_TXGIANT (1 << 30) /* Bit 30: TSV30 Transmit Giant */ +#define TXDESC_TSV2_TXUR (1 << 31) /* Bit 31: TSV31 Transmit Under-run */ + +/* Rx descriptor status bit definitions */ + /* Bits 0-6: Reserved */ +#define RXDESC_STATUS_EOWN (1 << 7) /* Bit 7: 1=Ethernet controller owns */ +#define RXDESC_STATUS_SOWN (0) /* 0=Software owns */ +#define RXDESC_STATUS_NPV (1 << 8) /* Bit 8: Next ED pointer valid enable */ + /* Bits 9-15: Reserved */ +#define RXDESC_STATUS_BYTECOUNT_SHIFT (16) /* Bits 16-26: Byte Count */ +#define RXDESC_STATUS_BYTECOUNT_MASK (0x7ff << RXDESC_STATUS_BYTECOUNT_SHIFT) + /* Bits 27-29: Reserved */ +#define RXDESC_STATUS_EOP (1 << 30) /* Bit 30: End of packet enable */ +#define RXDESC_STATUS_SOP (1 << 31) /* Bit 31: Start of packet enable */ + +/* Rx descriptor receive filter status vector bit definitions */ + +#define RXDESC_RSV1_CHECKSUM_SHIFT (0) /* Bits 0-15: RX Packet Payload Checksum */ +#define RXDESC_RSV1_CHECKSUM_MASK (0xffff << RXDESC_RSV1_CHECKSUM_SHIFT) +#define RXDESC_RSV1_USER_SHIFT (16) /* Bits 16-23: User defined */ +#define RXDESC_RSV1_USER_MASK (0xff << RXDESC_RSV1_USER_SHIFT) +#define RXDESC_RSV1_RUNT (1 << 24) /* Bit 24: RXF_RSV0 Runt packet */ +#define RXDESC_RSV1_NOTANDNOT (1 << 25) /* Bit 25: RXF_RSV1 NOT (Unicast match) AND NOT (Multicast Match) */ +#define RXDESC_RSV1_HTMATCH (1 << 26) /* Bit 26: RXF_RSV2 Hash Table match */ +#define RXDESC_RSV1_MAGIC (1 << 27) /* Bit 27: RXF_RSV3 Magic Packet match */ +#define RXDESC_RSV1_PATMATCH (1 << 28) /* Bit 28: RXF_RSV4 Pattern Match match */ +#define RXDESC_RSV1_UCASTMATCH (1 << 29) /* Bit 29: RXF_RSV5 Unicast match */ +#define RXDESC_RSV1_BCASTMATCH (1 << 30) /* Bit 30: RXF_RSV6 Broadcast match */ +#define RXDESC_RSV1_MCASTMATCH (1 << 31) /* Bit 31: RXF_RSV7 Multicast match */ + +#define RXDESC_RSV2_BYTECOUNT_SHIFT (0) /* Bits 0-15: RSV0-15 Received Byte Count */ +#define RXDESC_RSV2_BYTECOUNT_MASK (0xffff << RXDESC_RSV2_BYTECOUNT_SHIFT) +#define RXDESC_RSV2_LONGDROP (1 << 16) /* Bit 16: RSV16 Long Event/Drop Event */ +#define RXDESC_RSV2_RXDVSEEN (1 << 17) /* Bit 17: RSV17 RXDV Event Previously Seen */ +#define RXDESC_RSV2_CARSEEN (1 << 18) /* Bit 18: RSV18 Carrier Event Previously Seen */ +#define RXDESC_RSV2_CODE (1 << 19) /* Bit 19: RSV19 Receive Code Violation */ +#define RXDESC_RSV2_CRCERR (1 << 20) /* Bit 20: RSV20 CRC Error */ +#define RXDESC_RSV2_LENCHK (1 << 21) /* Bit 21: RSV21 Length Check Error */ +#define RXDESC_RSV2_OOR (1 << 22) /* Bit 22: RSV22 Length Out of Range */ +#define RXDESC_RSV2_OK (1 << 23) /* Bit 23: RSV23 Received Ok */ +#define RXDESC_RSV2_MCAST (1 << 24) /* Bit 24: RSV24 Receive Multicast Packet */ +#define RXDESC_RSV2_BCAST (1 << 25) /* Bit 25: RSV25 Receive Broadcast Packet */ +#define RXDESC_RSV2_DRIBBLE (1 << 26) /* Bit 26: RSV26 Dribble Nibble */ +#define RXDESC_RSV2_CONTROL (1 << 27) /* Bit 27: RSV27 Receive Control Frame */ +#define RXDESC_RSV2_PAUSE (1 << 28) /* Bit 28: RSV28 Receive Pause Control Frame */ +#define RXDESC_RSV2_UNKNOWNOP (1 << 29) /* Bit 29: RSV29 Receive Unknown Op code */ +#define RXDESC_RSV2_VLAN (1 << 30) /* Bit 30: RSV30 Receive VLAN Type Detected */ + /* Bit 31: RSV31 Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Descriptors as structures */ + +/* Tx descriptor with NPV=0 */ + +struct pic32mx_txlinear_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t tsv1; /* Transmit filter status vector 1 (32-bits) */ + uint32_t tsv2; /* Transmit filter status vector 2 (32-bits) */ +}; + +/* Tx descriptor with NPV=1 */ + +struct pic32mx_txdesc_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t tsv1; /* Transmit filter status vector 1 (32-bits) */ + uint32_t tsv2; /* Transmit filter status vector 2 (32-bits) */ + uint32_t nexted; /* Next Ethernet Descriptor (ED) */ +}; + +/* Rx descriptor with NPV=0 */ + +struct pic32mx_rxlinear_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t rsv1; /* Receive filter status vector 1 and checksum (32-bits) */ + uint32_t rsv2; /* Receive filter status vector 2 (32-bits) */ +}; + +/* Rx descriptor with NPV=1 */ + +struct pic32mx_rxdesc_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t rsv1; /* Receive filter status vector 1 and checksum (32-bits) */ + uint32_t rsv2; /* Receive filter status vector 2 (32-bits) */ + uint32_t nexted; /* Next Ethernet Descriptor (ED) */ +}; + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-exception.c b/arch/mips/src/pic32mx/pic32mx-exception.c new file mode 100644 index 0000000000000000000000000000000000000000..b5a058f3a6f4da1b0cb36e7e36e3ba0a21f8a828 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-exception.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-exception.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" + +#include "pic32mx-int.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: pic32mx_exception + * + * Description: + * Called from assembly language logic on all other exceptions. + * + ************************************************************************************/ + +uint32_t *pic32mx_exception(uint32_t *regs) +{ +#ifdef CONFIG_DEBUG + uint32_t cause; + uint32_t epc; +#endif + + /* If the board supports LEDs, turn on an LED now to indicate that we are + * processing an interrupt. + */ + + board_autoled_on(LED_INIRQ); + +#ifdef CONFIG_DEBUG + /* Get the cause of the exception from the CAUSE register */ + + asm volatile("\tmfc0 %0,$13,0\n" : "=r"(cause)); + asm volatile("\tmfc0 %0,$14,0\n" : "=r"(epc)); + +#ifdef CONFIG_DEBUG_VERBOSE + switch (cause & CP0_CAUSE_EXCCODE_MASK) + { + case CP0_CAUSE_EXCCODE_INT: /* Interrupt */ + llvdbg("EXCEPTION: Interrupt" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TLBL: /* TLB exception (load or instruction fetch) */ + llvdbg("EXCEPTION: TLB exception (load or instruction fetch)" + " CAUSE: %08x EPC:%08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TLBS: /* TLB exception (store) */ + llvdbg("EXCEPTION: TLB exception (store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_ADEL: /* Address error exception (load or instruction fetch) */ + llvdbg("EXCEPTION: Address error exception (load or instruction fetch)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_ADES: /* Address error exception (store) */ + llvdbg("EXCEPTION: Address error exception (store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_IBE: /* Bus error exception (instruction fetch) */ + llvdbg("EXCEPTION: Bus error exception (instruction fetch)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_DBE: /* Bus error exception (data reference: load or store) */ + llvdbg("EXCEPTION: Bus error exception (data reference: load or store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_SYS: /* Syscall exception */ + llvdbg("EXCEPTION: Syscall exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_BP: /* Breakpoint exception */ + llvdbg("EXCEPTION: Breakpoint exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_RI: /* Reserved instruction exception */ + llvdbg("EXCEPTION: Reserved instruction exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_CPU: /* Coprocessor Unusable exception */ + llvdbg("EXCEPTION: Coprocessor Unusable exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_OV: /* Arithmetic Overflow exception */ + llvdbg("EXCEPTION: Arithmetic Overflow exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TR: /* Trap exception */ + llvdbg("EXCEPTION: Trap exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_FPE: /* Floating point exception */ + llvdbg("EXCEPTION: Floating point exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_C2E: /* Precise Coprocessor 2 exceptions */ + llvdbg("EXCEPTION: Precise Coprocessor 2 exceptions" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_MDMX: /* MDMX Unusable (MIPS64) */ + llvdbg("EXCEPTION: MDMX Unusable (MIPS64)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_WATCH: /* WatchHi/WatchLo address */ + llvdbg("EXCEPTION: WatchHi/WatchLo address" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_MCHECK: /* Machine check */ + llvdbg("EXCEPTION: Machine check" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_CACHEERR: /* Cache error */ + llvdbg("EXCEPTION: Cache error" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + default: + llvdbg("EXCEPTION: Unknown" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + } +#else + lldbg("EXCEPTION: CAUSE: %08x EPC: %08x\n", cause, epc); +#endif +#endif + + /* Crash with currents_regs set so that we can dump the register contents. */ + + g_current_regs = regs; + PANIC(); + return regs; /* Won't get here */ +} diff --git a/arch/mips/src/pic32mx/pic32mx-flash.h b/arch/mips/src/pic32mx/pic32mx-flash.h new file mode 100644 index 0000000000000000000000000000000000000000..852ad5439d883ad32aebb661b5c5c85765815e41 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-flash.h @@ -0,0 +1,131 @@ + /******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-flash.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_FLASH_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_FLASH_H + + /******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + + /******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +#define PIC32MX_FLASH_NVMCON_OFFSET 0x0000 /* Programming Control Register */ +#define PIC32MX_FLASH_NVMCONCLR_OFFSET 0x0004 /* Programming Control Clear Register */ +#define PIC32MX_FLASH_NVMCONSET_OFFSET 0x0008 /* Programming Control Set Register */ +#define PIC32MX_FLASH_NVMCONINV_OFFSET 0x000c /* Programming Control Invert Register */ +#define PIC32MX_FLASH_NVMKEY_OFFSET 0x0010 /* Programming Unlock Register */ +#define PIC32MX_FLASH_NVMADDR_OFFSET 0x0020 /* Flash Address Register */ +#define PIC32MX_FLASH_NVMADDRCLR_OFFSET 0x0024 /* Flash Address Clear Register */ +#define PIC32MX_FLASH_NVMADDRSET_OFFSET 0x0028 /* Flash Address Set Register */ +#define PIC32MX_FLASH_NVMADDRINV_OFFSET 0x002c /* Flash Address Invert Register */ +#define PIC32MX_FLASH_NVMDATA_OFFSET 0x0030 /* Flash Program Data Register */ +#define PIC32MX_FLASH_NVMSRCADDR_OFFSET 0x0040 /* Source Data Address Register */ + +/* Register Addresses ***********************************************************************/ + +#define PIC32MX_FLASH_NVMCON (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMCON_OFFSET) +#define PIC32MX_FLASH_NVMCONCLR (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMCONCLR_OFFSET) +#define PIC32MX_FLASH_NVMCONSET (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMCONSET_OFFSET) +#define PIC32MX_FLASH_NVMCONINV (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMCONINV_OFFSET) +#define PIC32MX_FLASH_NVMKEY (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMKEY_OFFSET) +#define PIC32MX_FLASH_NVMADDRCLR (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMADDRCLR_OFFSET) +#define PIC32MX_FLASH_NVMADDRSET (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMADDRSET_OFFSET) +#define PIC32MX_FLASH_NVMADDRINV (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMADDRINV_OFFSET) +#define PIC32MX_FLASH_NVMADDR (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMADDR_OFFSET) +#define PIC32MX_FLASH_NVMDATA (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMDATA_OFFSET) +#define PIC32MX_FLASH_NVMSRCADDR (PIC32MX_FLASH_K1BASE+PIC32MX_FLASH_NVMSRCADDR_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Programming Control Register */ + +#define FLASH_NVMCON_NVMOP_SHIFT (0) /* Bits 0-3: NVM operation */ +#define FLASH_NVMCON_NVMOP_MASK (15 << FLASH_NVMCON_NVMOP_SHIFT) +# define FLASH_NVMCON_NVMOP_NOP (0 << FLASH_NVMCON_NVMOP_SHIFT) /* No operation */ +# define FLASH_NVMCON_NVMOP_WDPROG (1 << FLASH_NVMCON_NVMOP_SHIFT) /* Word program operation */ +# define FLASH_NVMCON_NVMOP_ROWPROG (3 << FLASH_NVMCON_NVMOP_SHIFT) /* Row program operation */ +# define FLASH_NVMCON_NVMOP_PFMERASE (4 << FLASH_NVMCON_NVMOP_SHIFT) /* Page erase operation */ +# define FLASH_NVMCON_NVMOP_PFMERASE (5 << FLASH_NVMCON_NVMOP_SHIFT) /* PFM erase operationxx */ +#define FLASH_NVMCON_LVDSTAT (1 << 11) /* Bit nn: Low-voltage detect status */ +#define FLASH_NVMCON_LVDERR (1 << 12) /* Bit nn: Low-voltage detect error */ +#define FLASH_NVMCON_WRERR (1 << 13) /* Bit nn: Write error */ +#define FLASH_NVMCON_WREN (1 << 14) /* Bit nn: Write enable */ +#define FLASH_NVMCON_WR (1 << 15) /* Bit nn: Write control */ + +/* Programming Unlock Register -- 32 Bits of data */ + +/* Flash Address Register -- 32 Bits of data */ + +/* Flash Program Data Register -- 32 Bits of data */ + +/* Source Data Address Register -- 32 Bits of data */ + + /******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + + /******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + + /******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_FLASH_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-gpio.c b/arch/mips/src/pic32mx/pic32mx-gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..78d9acca22a2536ae0d7814e7ba987fd0189b5ef --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-gpio.c @@ -0,0 +1,339 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-gpio.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "pic32mx-ioport.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uintptr_t g_gpiobase[CHIP_NPORTS] = +{ + PIC32MX_IOPORTA_K1BASE +#if CHIP_NPORTS > 1 + , PIC32MX_IOPORTB_K1BASE +#endif +#if CHIP_NPORTS > 2 + , PIC32MX_IOPORTC_K1BASE +#endif +#if CHIP_NPORTS > 3 + , PIC32MX_IOPORTD_K1BASE +#endif +#if CHIP_NPORTS > 4 + , PIC32MX_IOPORTE_K1BASE +#endif +#if CHIP_NPORTS > 5 + , PIC32MX_IOPORTF_K1BASE +#endif +#if CHIP_NPORTS > 6 + , PIC32MX_IOPORTG_K1BASE +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mx_output(uint16_t pinset) +{ + return ((pinset & GPIO_OUTPUT) != 0); +} + +static inline bool pic32mx_opendrain(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAN); +} + +static inline bool pic32mx_outputhigh(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != 0); +} + +static inline bool pic32mx_value(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO); +} + +static inline unsigned int pic32mx_portno(uint16_t pinset) +{ + return ((pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +static inline unsigned int pic32mx_pinno(uint16_t pinset) +{ + return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +static inline unsigned int pic32mx_analog(uint16_t pinset) +{ + return ((pinset & GPIO_ANALOG_MASK) != 0); +} +#else +# define pic32mx_analog(pinset) (false) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the + * interrupt will be configured when pic32mx_attach() is called. + * + * Returned Value: + * OK on success; negated errno on failure. + * + ****************************************************************************/ + +int pic32mx_configgpio(uint16_t cfgset) +{ + unsigned int port = pic32mx_portno(cfgset); + unsigned int pin = pic32mx_pinno(cfgset); + uint32_t mask = (1 << pin); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Is this an input or an output? */ + + sched_lock(); + if (pic32mx_output(cfgset)) + { + /* Not analog */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + putreg32(mask, base + PIC32MX_IOPORT_ANSELCLR_OFFSET); +#endif + /* It is an output; clear the corresponding bit in the TRIS register */ + + putreg32(mask, base + PIC32MX_IOPORT_TRISCLR_OFFSET); + + /* Is it an open drain output? */ + + if (pic32mx_opendrain(cfgset)) + { + /* It is an open drain output. Set the corresponding bit in + * the ODC register. + */ + + putreg32(mask, base + PIC32MX_IOPORT_ODCSET_OFFSET); + } + else + { + /* Is is a normal output. Clear the corresponding bit in the + * ODC register. + */ + + putreg32(mask, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + } + + /* Set the initial output value */ + + pic32mx_gpiowrite(cfgset, pic32mx_outputhigh(cfgset)); + } + else + { + /* It is an input; set the corresponding bit in the TRIS register. */ + + putreg32(mask, base + PIC32MX_IOPORT_TRISSET_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + + /* Is it an analog input? */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + if (pic32mx_analog(cfgset)) + { + putreg32(mask, base + PIC32MX_IOPORT_ANSELSET_OFFSET); + } + else + { + putreg32(mask, base + PIC32MX_IOPORT_ANSELCLR_OFFSET); + } +#endif + } + + sched_unlock(); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pic32mx_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void pic32mx_gpiowrite(uint16_t pinset, bool value) +{ + unsigned int port = pic32mx_portno(pinset); + unsigned int pin = pic32mx_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Set or clear the output */ + + if (value) + { + putreg32(1 << pin, base + PIC32MX_IOPORT_PORTSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MX_IOPORT_PORTCLR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: pic32mx_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool pic32mx_gpioread(uint16_t pinset) +{ + unsigned int port = pic32mx_portno(pinset); + unsigned int pin = pic32mx_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Get ane return the input value */ + + return (getreg32(base + PIC32MX_IOPORT_PORT_OFFSET) & (1 << pin)) != 0; + } + + return false; +} + +/**************************************************************************** + * Function: pic32mx_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_GPIO) +void pic32mx_dumpgpio(uint32_t pinset, const char *msg) +{ + unsigned int port = pic32mx_portno(pinset); + irqstate_t flags; + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + sched_lock(); + lldbg("IOPORT%c pinset: %04x base: %08x -- %s\n", + 'A'+port, pinset, base, msg); + lldbg(" TRIS: %08x PORT: %08x LAT: %08x ODC: %08x\n", + getreg32(base + PIC32MX_IOPORT_TRIS_OFFSET), + getreg32(base + PIC32MX_IOPORT_PORT_OFFSET), + getreg32(base + PIC32MX_IOPORT_LAT_OFFSET), + getreg32(base + PIC32MX_IOPORT_ODC_OFFSET)); + lldbg(" CNCON: %08x CNEN: %08x CNPUE: %08x\n", + getreg32(PIC32MX_IOPORT_CNCON), + getreg32(PIC32MX_IOPORT_CNEN), + getreg32(PIC32MX_IOPORT_CNPUE)); + sched_unlock(); + } +} +#endif + diff --git a/arch/mips/src/pic32mx/pic32mx-gpioirq.c b/arch/mips/src/pic32mx/pic32mx-gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..ce96403da8cc22a5046b52052dbddf6d4f3c1454 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-gpioirq.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-gpio.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "pic32mx-gpio.h" +#include "pic32mx.h" + +#ifdef CONFIG_PIC32MX_GPIOIRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static xcpt_t g_cnisrs[IOPORT_NUMCN]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mx_input(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) != GPIO_INPUT); +} + +static inline bool pic32mx_interrupt(uint16_t pinset) +{ + return ((pinset & GPIO_INTERRUPT) != 0); +} + +static inline bool pic32mx_pullup(uint16_t pinset) +{ + return ((pinset & GPIO_INT_MASK) == GPIO_PUINT); +} + +/**************************************************************************** + * Name: pic32mx_cninterrupt + * + * Description: + * Change notification interrupt handler. + * + ****************************************************************************/ + +static int pic32mx_cninterrupt(int irq, FAR void *context) +{ + int status; + int ret = OK; + int i; + + /* Call all attached handlers */ + + for (i = 0; i < IOPORT_NUMCN; i++) + { + /* Is this one attached */ + + if (g_cnisrs[i]) + { + /* Call the attached handler */ + + status = g_cnisrs[i](irq, context); + + /* Keep track of the status of the last handler that failed */ + + if (status < 0) + { + ret = status; + } + } + + /* Clear the pending interrupt */ + + up_clrpend_irq(PIC32MX_IRQ_CN); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. + * This function is called internally by the system on power up and should + * not be called again. + * + ****************************************************************************/ + +void pic32mx_gpioirqinitialize(void) +{ + int ret; + + /* Attach the change notice interrupt handler */ + + ret = irqattach(PIC32MX_IRQ_CN, pic32mx_cninterrupt); + DEBUGASSERT(ret == OK); + + /* Set the interrupt priority */ + +#ifdef CONFIG_ARCH_IRQPRIO + ret = up_prioritize_irq(PIC32MX_IRQ_CN, CONFIG_PIC32MX_CNPRIO); + DEBUGASSERT(ret == OK); +#endif + + /* Reset all registers and enable the CN module */ + + putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNENCLR); + putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNPUECLR); + putreg32(IOPORT_CNCON_ON, PIC32MX_IOPORT_CNCON); + + /* And enable the GPIO interrupt */ + + ret = up_enable_irq(PIC32MX_IRQSRC_CN); + DEBUGASSERT(ret == OK); +} + +/**************************************************************************** + * Name: pic32mx_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will + * also reconfigure the pin as an interrupting input. The change + * notification number is associated with all interrupt-capabile GPIO pins. + * The association could, however, differ from part to part and must be + * provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. + * In that case, all attached handlers will be called. Each handler must + * maintain state and determine if the unlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - cn: The change notification number associated with the pin. + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler) +{ + xcpt_t oldhandler = NULL; + irqstate_t flags; + + DEBUGASSERT(cn < IOPORT_NUMCN); + + /* First verify that the pinset is configured as an interrupting input */ + + if (pic32mx_input(pinset) && pic32mx_interrupt(pinset)) + { + /* Get the previously attached handler as the return value */ + + flags = enter_critical_section(); + oldhandler = g_cnisrs[cn]; + + /* Are we attaching or detaching? */ + + if (handler != NULL) + { + /* Attaching... Make sure that the GPIO is properly configured as + * an input + */ + + pic32mx_configgpio(pinset); + + /* Pull-up requested? */ + + if (pic32mx_pullup(pinset)) + { + putreg32(1 << cn, PIC32MX_IOPORT_CNPUESET); + } + else + { + putreg32(1 << cn, PIC32MX_IOPORT_CNPUECLR); + } + } + else + { + /* Make sure that any further interrupts are disabled. + * (disable the pull-up as well). + */ + + putreg32(1 << cn, PIC32MX_IOPORT_CNENCLR); + putreg32(1 << cn, PIC32MX_IOPORT_CNPUECLR); + } + + /* Set the new handler (perhaps NULLifying the current handler) */ + + g_cnisrs[cn] = handler; + leave_critical_section(flags); + } + + return oldhandler; +} + +/**************************************************************************** + * Name: pic32mx_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mx_gpioirqenable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MX_IOPORT_CNENSET); +} + +/**************************************************************************** + * Name: pic32mx_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mx_gpioirqdisable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MX_IOPORT_CNENCLR); +} + +#endif /* CONFIG_PIC32MX_GPIOIRQ */ diff --git a/arch/mips/src/pic32mx/pic32mx-head.S b/arch/mips/src/pic32mx/pic32mx-head.S new file mode 100644 index 0000000000000000000000000000000000000000..b5e19f39d80ab2f3c0385692772a3d0818e0121e --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-head.S @@ -0,0 +1,710 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-head.S + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "pic32mx-config.h" +#include "pic32mx-bmx.h" +#include "excptmacros.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_PIC32MX_MVEC +# error "Multi-vectors not supported" +# ifndef CONFIG_PIC32MX_EBASE +# error "EBASE address provided" /* Should come from the linker script */ +# endif +# ifndef CONFIG_PIC32MX_VECTORSPACING +# error "No vector spacing provided" +# endif +#endif + +/* Linker memory organization ***********************************************/ +/* Data memory is organized as follows: + * + * 1) Possible space reserved for debug data + * 2) Ram functions: (.data): + * Start: _sramfunc + * End(+1): _eramfunc + * 3) Initialized data (.data): + * Start: _sdata + * End(+1): _edata + * 4) Uninitialized data (.bss): + * Start: _sbss + * End(+1): _ebss + * + * The following are placed outside of the "normal" memory segments -- mostly + * so that they do not have to be cleared on power up. + * + * 5) Idle thread stack: + * Start: _ebss + * End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE + * 6) Optional interrupt stack + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE + * End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE+(CONFIG_ARCH_INTERRUPTSTACK & ~3) + * 6a) Heap (without interrupt stack) + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE + * End(+1): to the end of memory + * 6b) Heap (with interrupt stack) + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE+(CONFIG_ARCH_INTERRUPTSTACK & ~3) + * End(+1): to the end of memory + */ + +#define PIC32MX_STACK_BASE _ebss +#define PIC32MX_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +# define PIC32MX_INTSTACK_BASE PIC32MX_STACK_TOP +# define PIC32MX_INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~3) +# define PIC32MX_INTSTACK_TOP PIC32MX_STACK_TOP+PIC32MX_INTSTACK_SIZE +# define PIC32MX_HEAP_BASE PIC32MX_INTSTACK_TOP +#else +# define PIC32MX_HEAP_BASE PIC32MX_STACK_TOP +#endif + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "pic32mx-head.S" + + /* Exported symbols */ + + .globl __reset + .global __start + .global halt + .global devconfig +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + .global g_nestlevel +#endif +#endif + .global g_idle_topstack + + /* Imported symbols */ + + .global os_start + .global pic32mx_exception + .global pic32mx_decodeirq +#ifdef CONFIG_PIC32MX_NMIHANDLER + .global pic32mx_donmi +#endif + +/**************************************************************************** + * Name: __reset + * + * Description: + * Reset entry point. This function is positioned at the beginning of + * the boot FLASH by the linker in KSEG1. Simply jumps to the __start + * logic in KSEG0 (also in the boot FLASH). + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .reset, "ax", @progbits + .set noreorder + .ent __reset +__reset: + la k0, __start /* Just jump to the startup initialization code */ + jr k0 + nop + .end __reset + +/**************************************************************************** + * Name: _gen_exception + * + * Description: + * General Exception Vector Handler. Jumps to _exception_handler. This + * vector will be positioned at 0xbfc00180 by the linker script. NOTE: + * If we set the BEV bit in the status register so all interrupt vectors + * should go through the _bev_exception. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .gen_excpt,"ax",@progbits + .set noreorder + .ent _gen_exception +_gen_exception: + la k0, _exception_handler + jr k0 + nop + .end _gen_exception + +/**************************************************************************** + * Name: _ebase_exception + * + * Description: + * Interrupt Exception Vector Handler. Jumps to _int_handler. This + * vector will be positioned at 0xbfc00200 by the linker script. NOTE: + * Several vectors (JTAG, TLB fills, etc.) could come through this vector. + * However, this is intended to serve vectors in PIC32MX single vector + * mode: The EBASE register will be set to 0xbfc00000 and the vector + * should go to EBASE + 0x0200. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .ebase_excpt,"ax",@progbits + .set noreorder + .ent _ebase_exception +_ebase_exception: + la k0, _int_handler + jr k0 + nop + .end _ebase_exception + +/**************************************************************************** + * Name: _bev_exception + * + * Description: + * Boot Exception Vector Handler. Jumps to _exception_handler. This + * vector will be positioned at 0xbfc00380 by the linker script. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .bev_excpt,"ax",@progbits + .set noreorder + .ent _bev_exception +_bev_exception: + la k0, _exception_handler + jr k0 + nop + .end _bev_exception + +/**************************************************************************** + * Name: _int_exception + * + * Description: + * Interrupt Exception Vector Handler. Jumps to _int_handler. This + * vector will be positioned at 0xbfc00400 by the linker script. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .int_excpt,"ax",@progbits + .set noreorder + .ent _int_exception +_int_exception: + la k0, _int_handler + jr k0 + nop + .end _int_exception + +/**************************************************************************** + * Name: __start + * + * Description: + * This is the KSEG0 startup code. It receives control from the reset + * entry point. This lgic This prepares the processor to execute + * C code, performs some very low-level initialization, then starts NuttX + * (via __start_nuttx + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .start, "ax", @progbits + .set noreorder + .ent __start +__start: + + /* If this function was entered because of an NMI, then turn processing + * over to the NMI handler. + */ + +#ifdef CONFIG_PIC32MX_NMIHANDLER + mfc0 k0, $12 /* Load CP0 status register */ + ext k0, k0, 19, 1 /* Extract NMI bit */ + beqz k0, .Lnotnmi + nop + la k0, _nmi_handler + jr k0 + nop + + /* This is not an NMI */ + +.Lnotnmi: +#endif + + /* Initialize the stack pointer */ + + la sp, PIC32MX_STACK_TOP + + /* Initialize the globl pointer (gp). _gp is initialized by the linker + * script to point to the "middle" of the small variables region. + */ + + la gp, _gp + + /* Initialize Global Pointer in Shadow Set. The SRSCtl PSS field must + * be set to the shadow set in which to initialize the global pointer. + * Since we only have a single shadow set, we will initialize + * SRSCtl PSS to SRSCtl HSS. We then write the global pointer to the + * previous shadow set to ensure that on interrupt, the global pointer + * has been initialized. + */ + + mfc0 t1, PIC32MX_CP0_SRSCTL /* Read SRSCtl register */ + add t3, t1, zero /* Save off current SRSCtl */ + ext t2, t1, 26, 4 /* to obtain HSS field */ + ins t1, t2, 6, 4 /* Put HSS field */ + mtc0 t1, PIC32MX_CP0_SRSCTL /* into SRSCtl PSS */ + wrpgpr gp, gp /* Set global pointer in PSS */ + mtc0 t3, PIC32MX_CP0_SRSCTL /* Restore SRSCtl */ + + /* Clear uninitialized data sections */ + + la t0, _sbss + la t1, _ebss + b .Lbsscheck + nop + +.Lbssloop: + sw zero, 0x0(t0) + sw zero, 0x4(t0) + sw zero, 0x8(t0) + sw zero, 0xc(t0) + addu t0, 16 + +.Lbsscheck: + bltu t0, t1, .Lbssloop + nop + + /* Copy initialized data from program flash to data memory */ + + la t0, _data_loaddr + la t1, _sdata + la t2, _edata + b .Ldatacheck + nop + +.Ldataloop: + lw t3, (t0) + sw t3, (t1) + addu t0, 4 + addu t1, 4 + +.Ldatacheck: + bltu t1, t2, .Ldataloop + nop + + /* If there are no RAM functions, skip the next two sections -- + * copying RAM functions from program flash to data memory and + * initializing bus matrix registers. + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + la t1, _ramfunc_sizeof + beqz t1, .Lnoramfuncs + nop + + /* Copy RAM functions from program flash to data memory */ + + la t0, _ramfunc_loadaddr + la t1, _sramfunc + la t2, _eramfunc + +.Lramfuncloop: + lw t3,(t0) + sw t3,(t1) + addu t0,4 + addu t1,4 + + bltu t1, t2, .Lramfuncloop + nop + + /* Initialize bus matrix registers if RAM functions exist in the + * application + */ + + la t1, _bmxdkpba_address + la t2, PIC32MX_BMX_DKPBA + sw t1, 0(t2) + la t1, _bmxdudba_address + la t2, PIC32MX_BMX_DUDBA + sw t1, 0(t2) + la t1, _bmxdupba_address + la t2, PIC32MX_BMX_DUPBA + sw t1, 0(t2) +.Lnoramfuncs: +#endif + + /* Initialize CP0 Count register */ + + mtc0 zero, PIC32MX_CP0_COUNT + + /* Initialize Compare register */ + + li t2, -1 + mtc0 t2, PIC32MX_CP0_COMPARE + + /* Initialize EBase register */ + +#ifdef CONFIG_PIC32MX_MVEC + la t1, CONFIG_PIC32MX_EBASE + mtc0 t1, PIC32MX_CP0_EBASE + + /* Initialize IntCtl register */ + + li t1, CONFIG_PIC32MX_VECTORSPACING + li t2, 0 + ins t2, t1, CP0_INTCTL_VS_SHIFT, 5 + mtc0 t2, PIC32MX_CP0_INTCTL +#endif + + /* Initialize CAUSE registers + * - Enable counting of Count register (DC = 0) + * - Use special exception vector (IV = 1) + * - Clear pending software interrupts (IP1:IP0 = 0) + */ + + li t1, CP0_CAUSE_IV + mtc0 t1, PIC32MX_CP0_CAUSE + + /* Initialize STATUS register + * - Access to Coprocessor 0 not allowed in user mode (CU0 = 0) + * - User mode uses configured endianness (RE = 0) + * - Preserve Bootstrap Exception vectors (BEV) + * - Preserve soft reset (SR) and non-maskable interrupt (NMI) + * - CorExtend enabled based on whether CorExtend User Defined + * Instructions have been implemented (CEE = Config(UDI)) + * - Disable any pending interrups (IM7..IM2 = 0, IM1..IM0 = 0) + * - Disable hardware interrupts (IPL7:IPL2 = 0) + * - Base mode is Kernel mode (UM = 0) + * - Error level is normal (ERL = 0) + * - Exception level is normal (EXL = 0) + * - Interrupts are disabled (IE = 0) + */ + + mfc0 t0, PIC32MX_CP0_CONFIG + ext t1, t0, 22,1 /* Extract UDI from Config register */ + sll t1, t1, 17 /* Move UDI to Status.CEE location */ + mfc0 t0, PIC32MX_CP0_STATUS + and t0, t0, 0x00580000 /* Preserve SR, NMI, and BEV */ + or t0, t1, t0 /* Include Status.CEE (from UDI) */ + mtc0 t0, PIC32MX_CP0_STATUS + + /* Initialize Status BEV for normal exception vectors */ + + mfc0 t0, PIC32MX_CP0_STATUS + and t0, t0, ~CP0_STATUS_BEV /* Clear BEV */ + mtc0 t0, PIC32MX_CP0_STATUS + + /* Start NuttX. We do this via a thunk in the text section so that + * a normal jump and link can be used, enabling the startup code + * to work properly whether main is written in MIPS16 or MIPS32 + * code. I.e., the linker will correctly adjust the JAL to JALX if + * necessary + */ + + la t0, __start_nuttx + jr t0 + nop + .end __start + +/**************************************************************************** + * Name: _exception_handler + * + * Description: + * BEV/General exception handler. Calls pic32mx_exception() + * + ****************************************************************************/ + + .section .bev_handler, "ax", @progbits + .set noreorder + .ent _exception_handler +_exception_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mx_exception /* Call pic32mx_exception(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_exception() */ + .end _exception_handler + +/**************************************************************************** + * Name: _int_handler + * + * Description: + * Interrupt exception handler. Calls up_decodeirq() + * + ****************************************************************************/ + + .section .int_handler, "ax", @progbits + .set noreorder + .ent _int_handler +_int_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mx_decodeirq /* Call pic32mx_decodeirq(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_decodeirq() */ + .end _int_handler + +/**************************************************************************** + * Name: _nmi_handler + * + * Description: + * NMI exception handler. Calls pic32mx_donmi + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_NMIHANDLER + .section .nmi_handler, "ax", @progbits + .set noreorder + .ent _nmi_handler +_nmi_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mx_donmi /* Call up_donmi(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_donmi() */ + .end _nmi_handler +#endif + +/**************************************************************************** + * Name: __start_nuttx + * + * Description: + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .text + .ent __start_nuttx +__start_nuttx: + /* Perform low level initialization */ + + la t0, pic32mx_lowinit + jalr ra, t0 + nop + + /* Call os_start */ + + la t0, os_start + jalr ra, t0 + nop + + /* Just in case main returns, go into an infinite loop */ + +halt: +1: + b 1b + nop + .end __start_nuttx + +/**************************************************************************** + * Device Configuration + ****************************************************************************/ + + .section .devcfg, "a" + .type devconfig, object +devconfig: +devconfig3: +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + + .long CONFIG_PIC32MX_USERID << DEVCFG3_USERID_SHIFT | \ + CONFIG_PIC32MX_PMDL1WAY << 28 | CONFIG_PIC32MX_IOL1WAY << 29 | \ + CONFIG_PIC32MX_USBIDO << 30 | CONFIG_PIC32MX_VBUSIO << 31 | \ + DEVCFG3_UNUSED + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + + .long CONFIG_PIC32MX_USERID << DEVCFG3_USERID_SHIFT | \ + DEVCFG3_UNUSED + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + + .long CONFIG_PIC32MX_USERID << DEVCFG3_USERID_SHIFT | \ + CONFIG_PIC32MX_SRSSEL << DEVCFG3_FSRSSEL_SHIFT | \ + CONFIG_PIC32MX_FMIIEN << 24 | CONFIG_PIC32MX_FETHIO << 25 | \ + CONFIG_PIC32MX_FCANIO << 26 | CONFIG_PIC32MX_FSCM1IO << 29 | \ + CONFIG_PIC32MX_USBIDO << 30 | CONFIG_PIC32MX_VBUSIO << 31 | \ + DEVCFG3_UNUSED + +#endif + +devconfig2: + .long CONFIG_PIC32MX_PLLIDIV | CONFIG_PIC32MX_PLLMULT | \ + CONFIG_PIC32MX_UPLLIDIV | CONFIG_PIC32MX_PLLODIV | \ + CONFIG_PIC32MX_FUPLLEN << 15 | DEVCFG2_UNUSED + +devconfig1: +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + + .long CONFIG_PIC32MX_FNOSC | CONFIG_PIC32MX_FSOSCEN | \ + CONFIG_PIC32MX_IESO | CONFIG_PIC32MX_POSCMOD | \ + CONFIG_PIC32MX_OSCOUT << 10 | \ + CONFIG_PIC32MX_PBDIV | CONFIG_PIC32MX_FCKSM | \ + DEVCFG1_WINDIS | CONFIG_PIC32MX_WDENABLE | \ + DEVCFG1_FWDTWINSZ_75 | DEVCFG1_UNUSED + +#else + + .long CONFIG_PIC32MX_FNOSC | CONFIG_PIC32MX_FSOSCEN | \ + CONFIG_PIC32MX_IESO | CONFIG_PIC32MX_POSCMOD | \ + CONFIG_PIC32MX_OSCOUT << 10 | \ + CONFIG_PIC32MX_PBDIV | CONFIG_PIC32MX_FCKSM | \ + CONFIG_PIC32MX_WDENABLE | DEVCFG1_UNUSED + +#endif + +devconfig0: +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + + .long CONFIG_PIC32MX_DEBUGGER << DEVCFG0_DEBUG_SHIFT | \ + DEVCFG0_JTAGEN | \ + CONFIG_PIC32MX_ICESEL << DEVCFG0_ICESEL_SHIFT | \ + CONFIG_PIC32MX_PROGFLASHWP << DEVCFG0_PWP_SHIFT | \ + CONFIG_PIC32MX_BOOTFLASHWP << 24 | \ + CONFIG_PIC32MX_CODEWP << 28 | \ + DEVCFG0_UNUSED + +#else + + .long CONFIG_PIC32MX_DEBUGGER << DEVCFG0_DEBUG_SHIFT | \ + CONFIG_PIC32MX_ICESEL << 3 | \ + CONFIG_PIC32MX_PROGFLASHWP << DEVCFG0_PWP_SHIFT | \ + CONFIG_PIC32MX_BOOTFLASHWP << 24 | \ + CONFIG_PIC32MX_CODEWP << 28 | \ + DEVCFG0_UNUSED + +#endif + .size devconfig, .-devconfig + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Interrupt stack variables */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + +/* g_instackbase is a pointer to the final, aligned word of the interrupt + * stack. + */ + + .sdata + .type g_intstackbase, object +g_intstackbase: + .long PIC32MX_INTSTACK_TOP-4 + .size g_intstackbase, .-g_intstackbase + +/* g_nextlevel is the exception nesting level... the interrupt stack is not + * available to nested exceptions. + */ + +#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS + .sbss + .type g_nestlevel, object +g_nestlevel: + .skip 4 +#endif +#endif + +/* This global variable is unsigned int g_idle_topstack and is exported here only + * because of its coupling to idle thread stack. + */ + + .sdata + .type g_idle_topstack, object +g_idle_topstack: + .long PIC32MX_HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack + diff --git a/arch/mips/src/pic32mx/pic32mx-i2c.h b/arch/mips/src/pic32mx/pic32mx-i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..6475caba49445cd246ccb00f23ab29697565141c --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-i2c.h @@ -0,0 +1,306 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-i2c.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_I2C_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_I2C_CON_OFFSET 0x0000 /* I2C control register */ +#define PIC32MX_I2C_CONCLR_OFFSET 0x0004 /* I2C control clear register */ +#define PIC32MX_I2C_CONSET_OFFSET 0x0008 /* I2C control set register */ +#define PIC32MX_I2C_CONINV_OFFSET 0x000c /* I2C control invert register */ +#define PIC32MX_I2C_STAT_OFFSET 0x0010 /* I2C status register */ +#define PIC32MX_I2C_STATCLR_OFFSET 0x0014 /* I2C status clear register */ +#define PIC32MX_I2C_STATSET_OFFSET 0x0018 /* I2C status set register */ +#define PIC32MX_I2C_STATINV_OFFSET 0x001c /* I2C status invert register */ +#define PIC32MX_I2C_ADD_OFFSET 0x0020 /* I2C address register */ +#define PIC32MX_I2C_ADDCLR_OFFSET 0x0024 /* I2C address clear register */ +#define PIC32MX_I2C_ADDSET_OFFSET 0x0028 /* I2C address set register */ +#define PIC32MX_I2C_ADDINV_OFFSET 0x002c /* I2C address invert register */ +#define PIC32MX_I2C_MSK_OFFSET 0x0030 /* I2C address mask register */ +#define PIC32MX_I2C_MSKCLR_OFFSET 0x0034 /* I2C address mask clear register */ +#define PIC32MX_I2C_MSKSET_OFFSET 0x0038 /* I2C address mask set register */ +#define PIC32MX_I2C_MSKINV_OFFSET 0x003c /* I2C address mask invert register */ +#define PIC32MX_I2C_BRG_OFFSET 0x0040 /* Baud rate generator reload register */ +#define PIC32MX_I2C_BRGCLR_OFFSET 0x0044 /* Baud rate generator reload set register */ +#define PIC32MX_I2C_BRGSET_OFFSET 0x0048 /* Baud rate generator reload clear register */ +#define PIC32MX_I2C_BRGINV_OFFSET 0x004c /* Baud rate generator reload invert register */ +#define PIC32MX_I2C_TRN_OFFSET 0x0050 /* I2C transmit register */ +#define PIC32MX_I2C_TRNCLR_OFFSET 0x0054 /* I2C transmit clear register */ +#define PIC32MX_I2C_TRNSET_OFFSET 0x0058 /* I2C transmit set register */ +#define PIC32MX_I2C_TRNINV_OFFSET 0x005c /* I2C transmit invert register */ +#define PIC32MX_I2C_RCV_OFFSET 0x0060 /* I2C receive buffer register */ + +/* Register Addresses ***************************************************************/ + +#if CHIP_NI2C > 0 +# define PIC32MX_I2C1_CON (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_CON_OFFSET) +# define PIC32MX_I2C1_CONCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_CONCLR_OFFSET) +# define PIC32MX_I2C1_CONSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_CONSET_OFFSET) +# define PIC32MX_I2C1_CONINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_CONINV_OFFSET) +# define PIC32MX_I2C1_STAT (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_STAT_OFFSET) +# define PIC32MX_I2C1_STATCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_STATCLR_OFFSET) +# define PIC32MX_I2C1_STATSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_STATSET_OFFSET) +# define PIC32MX_I2C1_STATINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_STATINV_OFFSET) +# define PIC32MX_I2C1_ADD (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_ADD_OFFSET) +# define PIC32MX_I2C1_ADDCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_ADDCLR_OFFSET) +# define PIC32MX_I2C1_ADDSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_ADDSET_OFFSET) +# define PIC32MX_I2C1_ADDINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_ADDINV_OFFSET) +# define PIC32MX_I2C1_MSK (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_MSK_OFFSET) +# define PIC32MX_I2C1_MSKCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_MSKCLR_OFFSET) +# define PIC32MX_I2C1_MSKSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_MSKSET_OFFSET) +# define PIC32MX_I2C1_MSKINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_MSKINV_OFFSET) +# define PIC32MX_I2C1_BRG (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_BRG_OFFSET) +# define PIC32MX_I2C1_BRGSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_BRGSET_OFFSET) +# define PIC32MX_I2C1_BRGCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_BRGCLR_OFFSET) +# define PIC32MX_I2C1_BRGINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_BRGINV_OFFSET) +# define PIC32MX_I2C1_TRN (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_TRN_OFFSET) +# define PIC32MX_I2C1_TRNCLR (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_TRNCLR_OFFSET) +# define PIC32MX_I2C1_TRNSET (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_TRNSET_OFFSET) +# define PIC32MX_I2C1_TRNINV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_TRNINV_OFFSET) +# define PIC32MX_I2C1_RCV (PIC32MX_I2C1_K1BASE+PIC32MX_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 1 +# define PIC32MX_I2C2_CON (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_CON_OFFSET) +# define PIC32MX_I2C2_CONCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_CONCLR_OFFSET) +# define PIC32MX_I2C2_CONSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_CONSET_OFFSET) +# define PIC32MX_I2C2_CONINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_CONINV_OFFSET) +# define PIC32MX_I2C2_STAT (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_STAT_OFFSET) +# define PIC32MX_I2C2_STATCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_STATCLR_OFFSET) +# define PIC32MX_I2C2_STATSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_STATSET_OFFSET) +# define PIC32MX_I2C2_STATINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_STATINV_OFFSET) +# define PIC32MX_I2C2_ADD (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_ADD_OFFSET) +# define PIC32MX_I2C2_ADDCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_ADDCLR_OFFSET) +# define PIC32MX_I2C2_ADDSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_ADDSET_OFFSET) +# define PIC32MX_I2C2_ADDINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_ADDINV_OFFSET) +# define PIC32MX_I2C2_MSK (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_MSK_OFFSET) +# define PIC32MX_I2C2_MSKCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_MSKCLR_OFFSET) +# define PIC32MX_I2C2_MSKSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_MSKSET_OFFSET) +# define PIC32MX_I2C2_MSKINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_MSKINV_OFFSET) +# define PIC32MX_I2C2_BRG (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_BRG_OFFSET) +# define PIC32MX_I2C2_BRGSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_BRGSET_OFFSET) +# define PIC32MX_I2C2_BRGCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_BRGCLR_OFFSET) +# define PIC32MX_I2C2_BRGINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_BRGINV_OFFSET) +# define PIC32MX_I2C2_TRN (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_TRN_OFFSET) +# define PIC32MX_I2C2_TRNCLR (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_TRNCLR_OFFSET) +# define PIC32MX_I2C2_TRNSET (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_TRNSET_OFFSET) +# define PIC32MX_I2C2_TRNINV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_TRNINV_OFFSET) +# define PIC32MX_I2C2_RCV (PIC32MX_I2C2_K1BASE+PIC32MX_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 2 +# define PIC32MX_I2C3_CON (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_CON_OFFSET) +# define PIC32MX_I2C3_CONCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_CONCLR_OFFSET) +# define PIC32MX_I2C3_CONSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_CONSET_OFFSET) +# define PIC32MX_I2C3_CONINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_CONINV_OFFSET) +# define PIC32MX_I2C3_STAT (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_STAT_OFFSET) +# define PIC32MX_I2C3_STATCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_STATCLR_OFFSET) +# define PIC32MX_I2C3_STATSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_STATSET_OFFSET) +# define PIC32MX_I2C3_STATINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_STATINV_OFFSET) +# define PIC32MX_I2C3_ADD (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_ADD_OFFSET) +# define PIC32MX_I2C3_ADDCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_ADDCLR_OFFSET) +# define PIC32MX_I2C3_ADDSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_ADDSET_OFFSET) +# define PIC32MX_I2C3_ADDINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_ADDINV_OFFSET) +# define PIC32MX_I2C3_MSK (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_MSK_OFFSET) +# define PIC32MX_I2C3_MSKCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_MSKCLR_OFFSET) +# define PIC32MX_I2C3_MSKSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_MSKSET_OFFSET) +# define PIC32MX_I2C3_MSKINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_MSKINV_OFFSET) +# define PIC32MX_I2C3_BRG (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_BRG_OFFSET) +# define PIC32MX_I2C3_BRGSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_BRGSET_OFFSET) +# define PIC32MX_I2C3_BRGCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_BRGCLR_OFFSET) +# define PIC32MX_I2C3_BRGINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_BRGINV_OFFSET) +# define PIC32MX_I2C3_TRN (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_TRN_OFFSET) +# define PIC32MX_I2C3_TRNCLR (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_TRNCLR_OFFSET) +# define PIC32MX_I2C3_TRNSET (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_TRNSET_OFFSET) +# define PIC32MX_I2C3_TRNINV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_TRNINV_OFFSET) +# define PIC32MX_I2C3_RCV (PIC32MX_I2C3_K1BASE+PIC32MX_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 3 +# define PIC32MX_I2C4_CON (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_CON_OFFSET) +# define PIC32MX_I2C4_CONCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_CONCLR_OFFSET) +# define PIC32MX_I2C4_CONSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_CONSET_OFFSET) +# define PIC32MX_I2C4_CONINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_CONINV_OFFSET) +# define PIC32MX_I2C4_STAT (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_STAT_OFFSET) +# define PIC32MX_I2C4_STATCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_STATCLR_OFFSET) +# define PIC32MX_I2C4_STATSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_STATSET_OFFSET) +# define PIC32MX_I2C4_STATINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_STATINV_OFFSET) +# define PIC32MX_I2C4_ADD (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_ADD_OFFSET) +# define PIC32MX_I2C4_ADDCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_ADDCLR_OFFSET) +# define PIC32MX_I2C4_ADDSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_ADDSET_OFFSET) +# define PIC32MX_I2C4_ADDINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_ADDINV_OFFSET) +# define PIC32MX_I2C4_MSK (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_MSK_OFFSET) +# define PIC32MX_I2C4_MSKCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_MSKCLR_OFFSET) +# define PIC32MX_I2C4_MSKSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_MSKSET_OFFSET) +# define PIC32MX_I2C4_MSKINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_MSKINV_OFFSET) +# define PIC32MX_I2C4_BRG (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_BRG_OFFSET) +# define PIC32MX_I2C4_BRGSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_BRGSET_OFFSET) +# define PIC32MX_I2C4_BRGCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_BRGCLR_OFFSET) +# define PIC32MX_I2C4_BRGINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_BRGINV_OFFSET) +# define PIC32MX_I2C4_TRN (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_TRN_OFFSET) +# define PIC32MX_I2C4_TRNCLR (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_TRNCLR_OFFSET) +# define PIC32MX_I2C4_TRNSET (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_TRNSET_OFFSET) +# define PIC32MX_I2C4_TRNINV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_TRNINV_OFFSET) +# define PIC32MX_I2C4_RCV (PIC32MX_I2C4_K1BASE+PIC32MX_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 4 +# define PIC32MX_I2C5_CON (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_CON_OFFSET) +# define PIC32MX_I2C5_CONCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_CONCLR_OFFSET) +# define PIC32MX_I2C5_CONSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_CONSET_OFFSET) +# define PIC32MX_I2C5_CONINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_CONINV_OFFSET) +# define PIC32MX_I2C5_STAT (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_STAT_OFFSET) +# define PIC32MX_I2C5_STATCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_STATCLR_OFFSET) +# define PIC32MX_I2C5_STATSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_STATSET_OFFSET) +# define PIC32MX_I2C5_STATINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_STATINV_OFFSET) +# define PIC32MX_I2C5_ADD (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_ADD_OFFSET) +# define PIC32MX_I2C5_ADDCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_ADDCLR_OFFSET) +# define PIC32MX_I2C5_ADDSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_ADDSET_OFFSET) +# define PIC32MX_I2C5_ADDINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_ADDINV_OFFSET) +# define PIC32MX_I2C5_MSK (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_MSK_OFFSET) +# define PIC32MX_I2C5_MSKCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_MSKCLR_OFFSET) +# define PIC32MX_I2C5_MSKSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_MSKSET_OFFSET) +# define PIC32MX_I2C5_MSKINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_MSKINV_OFFSET) +# define PIC32MX_I2C5_BRG (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_BRG_OFFSET) +# define PIC32MX_I2C5_BRGSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_BRGSET_OFFSET) +# define PIC32MX_I2C5_BRGCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_BRGCLR_OFFSET) +# define PIC32MX_I2C5_BRGINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_BRGINV_OFFSET) +# define PIC32MX_I2C5_TRN (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_TRN_OFFSET) +# define PIC32MX_I2C5_TRNCLR (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_TRNCLR_OFFSET) +# define PIC32MX_I2C5_TRNSET (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_TRNSET_OFFSET) +# define PIC32MX_I2C5_TRNINV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_TRNINV_OFFSET) +# define PIC32MX_I2C5_RCV (PIC32MX_I2C5_K1BASE+PIC32MX_I2C_RCV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***************************************************/ + +/* I2C control register */ + +#define I2C_CON_SEN (1 << 0) /* Bit 0: Start condition enable */ +#define I2C_CON_RSEN (1 << 1) /* Bit 1: Restart condition enable */ +#define I2C_CON_PEN (1 << 2) /* Bit 2: Stop condition enable */ +#define I2C_CON_RCEN (1 << 3) /* Bit 3: Receive enable */ +#define I2C_CON_ACKEN (1 << 4) /* Bit 4: Acknowledge sequence enable */ +#define I2C_CON_ACKDT (1 << 5) /* Bit 5: Acknowledge data */ +#define I2C_CON_STREN (1 << 6) /* Bit 6: SCL clock stretch enable */ +#define I2C_CON_GCEN (1 << 7) /* Bit 7: General call enable */ +#define I2C_CON_SMEN (1 << 8) /* Bit 8: SMBus input levels disable */ +#define I2C_CON_DISSLW (1 << 9) /* Bit 9: Slew rate control disable */ +#define I2C_CON_A10M (1 << 10) /* Bit 10: 10-bit slave addrewss flag */ +#define I2C_CON_STRICT (1 << 11) /* Bit 11: Strict I2C reserved address rules enable */ +#define I2C_CON_SCLREL (1 << 12) /* Bit 12: SCL release control */ +#define I2C_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define I2C_CON_FRZ (1 << 14) /* Bit 14: Freeze in debug mode control */ +#define I2C_CON_ON (1 << 15) /* Bit 15: I2C enable */ + +/* I2C status register */ + +#define I2C_STAT_TBF (1 << 0) /* Bit 0: Transmit buffer full */ +#define I2C_STAT_RBF (1 << 1) /* Bit 1: Receive buffer full */ +#define I2C_STAT_RW (1 << 2) /* Bit 2: Read/write information */ +#define I2C_STAT_S (1 << 3) /* Bit 3: Start */ +#define I2C_STAT_P (1 << 4) /* Bit 4: Stop */ +#define I2C_STAT_DA (1 << 5) /* Bit 5: Data/address */ +#define I2C_STAT_I2COV (1 << 6) /* Bit 6: I2C overflow status */ +#define I2C_STAT_IWCOL (1 << 7) /* Bit 7: Write collision detect */ +#define I2C_STAT_ADD10 (1 << 8) /* Bit 8: 10-bit address status */ +#define I2C_STAT_GCSTAT (1 << 9) /* Bit 9: General call status */ +#define I2C_STAT_BCL (1 << 10) /* Bit 10: Master bus collision detect */ +#define I2C_STAT_TRSTAT (1 << 14) /* Bit 14: Transmit status */ +#define I2C_STAT_ACKSTAT (1 << 15) /* Bit 15: Acknowledge status */ + +/* I2C address register */ + +#define I2C_ADD_MASK 0x3ff /* 10-bit I2C address */ + +/* I2C address mask register */ + +#define I2C_MSK_MASK 0x3ff /* 10-bit I2C address mask */ + +/* Baud rate generator reload register */ + +#define I2C_BRG_MASK 0xfff /* 12-bit I2C BRG value */ + +/* I2C transmit register */ + +#define I2C_TRN_MASK 0xff /* 8-bit transmit data */ + +/* I2C receive buffer register */ + +#define I2C_RCV_MASK 0xff /* 8-bit receive data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_I2C_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-ic.h b/arch/mips/src/pic32mx/pic32mx-ic.h new file mode 100644 index 0000000000000000000000000000000000000000..d1b3070f52f7ac611d57164637a3b07e352f816e --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-ic.h @@ -0,0 +1,167 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-ic.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IC_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +#if CHIP_NIC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_IC_CON_OFFSET 0x0000 /* Input Capture X Control Register */ +#define PIC32MX_IC_CONCLR_OFFSET 0x0004 /* Input Capture X Control Set Register */ +#define PIC32MX_IC_CONSET_OFFSET 0x0008 /* Input Capture X Control Clear Register */ +#define PIC32MX_IC_CONINV_OFFSET 0x000c /* Input Capture X Control Invert Register */ +#define PIC32MX_IC_BUF_OFFSET 0x0010 /* Input Capture X Buffer Register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_IC_CON(n) (PIC32MX_IC_K1BASE(n)+PIC32MX_IC_CON_OFFSET) +#define PIC32MX_IC_CONCLR(n) (PIC32MX_IC_K1BASE(n)+PIC32MX_IC_CONCLR_OFFSET) +#define PIC32MX_IC_CONSET(n) (PIC32MX_IC_K1BASE(n)+PIC32MX_IC_CONSET_OFFSET) +#define PIC32MX_IC_CONINV(n) (PIC32MX_IC_K1BASE(n)+PIC32MX_IC_CONINV_OFFSET) +#define PIC32MX_IC_BUF(n) (PIC32MX_IC_K1BASE(n)+PIC32MX_IC_BUF_OFFSET) + +#define PIC32MX_IC1_CON (PIC32MX_IC1_K1BASE+PIC32MX_IC_CON_OFFSET) +#define PIC32MX_IC1_CONCLR (PIC32MX_IC1_K1BASE+PIC32MX_IC_CONCLR_OFFSET) +#define PIC32MX_IC1_CONSET (PIC32MX_IC1_K1BASE+PIC32MX_IC_CONSET_OFFSET) +#define PIC32MX_IC1_CONINV (PIC32MX_IC1_K1BASE+PIC32MX_IC_CONINV_OFFSET) +#define PIC32MX_IC1_BUF (PIC32MX_IC1_K1BASE+PIC32MX_IC_BUF_OFFSET) + +#if CHIP_NIC > 1 +# define PIC32MX_IC2_CON (PIC32MX_IC2_K1BASE+PIC32MX_IC_CON_OFFSET) +# define PIC32MX_IC2_CONCLR (PIC32MX_IC2_K1BASE+PIC32MX_IC_CONCLR_OFFSET) +# define PIC32MX_IC2_CONSET (PIC32MX_IC2_K1BASE+PIC32MX_IC_CONSET_OFFSET) +# define PIC32MX_IC2_CONINV (PIC32MX_IC2_K1BASE+PIC32MX_IC_CONINV_OFFSET) +# define PIC32MX_IC2_BUF (PIC32MX_IC2_K1BASE+PIC32MX_IC_BUF_OFFSET) +#endif + +#if CHIP_NIC > 2 +# define PIC32MX_IC3_CON (PIC32MX_IC3_K1BASE+PIC32MX_IC_CON_OFFSET) +# define PIC32MX_IC3_CONCLR (PIC32MX_IC3_K1BASE+PIC32MX_IC_CONCLR_OFFSET) +# define PIC32MX_IC3_CONSET (PIC32MX_IC3_K1BASE+PIC32MX_IC_CONSET_OFFSET) +# define PIC32MX_IC3_CONINV (PIC32MX_IC3_K1BASE+PIC32MX_IC_CONINV_OFFSET) +# define PIC32MX_IC3_BUF (PIC32MX_IC3_K1BASE+PIC32MX_IC_BUF_OFFSET) +#endif + +#if CHIP_NIC > 3 +# define PIC32MX_IC4_CON (PIC32MX_IC4_K1BASE+PIC32MX_IC_CON_OFFSET) +# define PIC32MX_IC4_CONCLR (PIC32MX_IC4_K1BASE+PIC32MX_IC_CONCLR_OFFSET) +# define PIC32MX_IC4_CONSET (PIC32MX_IC4_K1BASE+PIC32MX_IC_CONSET_OFFSET) +# define PIC32MX_IC4_CONINV (PIC32MX_IC4_K1BASE+PIC32MX_IC_CONINV_OFFSET) +# define PIC32MX_IC4_BUF (PIC32MX_IC4_K1BASE+PIC32MX_IC_BUF_OFFSET) +#endif + +#if CHIP_NIC > 4 +# define PIC32MX_IC5_CON (PIC32MX_IC5_K1BASE+PIC32MX_IC_CON_OFFSET) +# define PIC32MX_IC5_CONCLR (PIC32MX_IC5_K1BASE+PIC32MX_IC_CONCLR_OFFSET) +# define PIC32MX_IC5_CONSET (PIC32MX_IC5_K1BASE+PIC32MX_IC_CONSET_OFFSET) +# define PIC32MX_IC5_CONINV (PIC32MX_IC5_K1BASE+PIC32MX_IC_CONINV_OFFSET) +# define PIC32MX_IC5_BUF (PIC32MX_IC5_K1BASE+PIC32MX_IC_BUF_OFFSET) +#endif + +/* Register Bit-Field Definitions ***************************************************/ + +/* Input Capture X Control Register */ + +#define IC_CON_ICM_SHIFT (0) /* Bits 0-2: Input Capture Mode Select */ +#define IC_CON_ICM_MASK (7 << IC_CON_ICM_SHIFT) +# define IC_CON_ICM_DISABLE (0 << IC_CON_ICM_SHIFT) /* Capture disable mode */ +# define IC_CON_ICM_EDGE (1 << IC_CON_ICM_SHIFT) /* Edge detect mode */ +# define IC_CON_ICM_FALLING (2 << IC_CON_ICM_SHIFT) /* Every falling edge */ +# define IC_CON_ICM_RISING (3 << IC_CON_ICM_SHIFT) /* Every rising edge */ +# define IC_CON_ICM_4th (4 << IC_CON_ICM_SHIFT) /* Every fourth rising edge */ +# define IC_CON_ICM_16th (5 << IC_CON_ICM_SHIFT) /* Every sixteenth rising edge */ +# define IC_CON_ICM_TRIGGER (6 << IC_CON_ICM_SHIFT) /* Specified edge first and every edge thereafter */ +# define IC_CON_ICM_INTERRUPT (7 << IC_CON_ICM_SHIFT) /* Interrupt-only mode */ +#define IC_CON_ICBNE (1 << 3) /* Bit 3: Input Capture Buffer Not Empty Status */ +#define IC_CON_ICOV (1 << 4) /* Bit 4: Input Capture */ +#define IC_CON_ICI_SHIFT (5) /* Bits 5-6: Interrupt Control */ +#define IC_CON_ICI_MASK (3 << IC_CON_ICI_SHIFT) +# define IC_CON_ICI_EVERY (0 << IC_CON_ICI_SHIFT) /* Interrupt every capture event */ +# define IC_CON_ICI_2ND (1 << IC_CON_ICI_SHIFT) /* Interrupt every 2nd capture event */ +# define IC_CON_ICI_3RD (2 << IC_CON_ICI_SHIFT) /* Interrupt every 3rd capture event */ +# define IC_CON_ICI_4TH (3 << IC_CON_ICI_SHIFT) /* Interrupt every 4th capture event */ +#define IC_CON_ICTMR (1 << 7) /* Bit 7: Timer Select */ +#define IC_CON_C32 (1 << 8) /* Bit 8: 32-bit Capture Select */ +#define IC_CON_FEDGE (1 << 9) /* Bit 9: First Capture Edge Select */ +#define IC_CON_SIDL (1 << 13) /* Bit 13: Stop in Idle Control */ +#define IC_CON_FRZ (1 << 14) /* Bit 14: Freeze in Debug Mode Control */ +#define IC_CON_ON (1 << 15) /* Bit 15: Input Capture Module Enable */ + +/* Input Capture X Buffer Register -- 32-bit capture value */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NIC > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IC_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-int.h b/arch/mips/src/pic32mx/pic32mx-int.h new file mode 100644 index 0000000000000000000000000000000000000000..3443640c91fcaae6a985fa8929fafb404ee9687a --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-int.h @@ -0,0 +1,1085 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-int.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_INT_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_INT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MX_INT_INTCON_OFFSET 0x0000 /* Interrupt control register */ +#define PIC32MX_INT_INTCONCLR_OFFSET 0x0004 /* Interrupt control clear register */ +#define PIC32MX_INT_INTCONSET_OFFSET 0x0008 /* Interrupt control set register */ +#define PIC32MX_INT_INTCONINV_OFFSET 0x000c /* Interrupt control invert register */ +#define PIC32MX_INT_INTSTAT_OFFSET 0x0010 /* Interrupt status register */ +#define PIC32MX_INT_INTSTATCLR_OFFSET 0x0014 /* Interrupt status clear register */ +#define PIC32MX_INT_INTSTATSET_OFFSET 0x0018 /* Interrupt status set register */ +#define PIC32MX_INT_INTSTATINV_OFFSET 0x001c /* Interrupt status invert register */ +#define PIC32MX_INT_TPTMR_OFFSET 0x0020 /* Temporal proximity timer register */ +#define PIC32MX_INT_TPTMRCLR_OFFSET 0x0024 /* Temporal proximity timer clear register */ +#define PIC32MX_INT_TPTMRSET_OFFSET 0x0028 /* Temporal proximity timer set register */ +#define PIC32MX_INT_TPTMRINV_OFFSET 0x002c /* Temporal proximity timer invert register */ +#define PIC32MX_INT_IFS_OFFSET(n) (0x0030 + ((n) << 4)) +#define PIC32MX_INT_IFSCLR_OFFSET(n) (0x0034 + ((n) << 4)) +#define PIC32MX_INT_IFSSET_OFFSET(n) (0x0038 + ((n) << 4)) +#define PIC32MX_INT_IFSINV_OFFSET(n) (0x003c + ((n) << 4)) +#define PIC32MX_INT_IFS0_OFFSET 0x0030 /* Interrupt flag status register 0 */ +#define PIC32MX_INT_IFS0CLR_OFFSET 0x0034 /* Interrupt flag status clear register 0 */ +#define PIC32MX_INT_IFS0SET_OFFSET 0x0038 /* Interrupt flag status set register 0 */ +#define PIC32MX_INT_IFS0INV_OFFSET 0x003c /* Interrupt flag status invert register 0 */ +#define PIC32MX_INT_IFS1_OFFSET 0x0040 /* Interrupt flag status register 1 */ +#define PIC32MX_INT_IFS1CLR_OFFSET 0x0044 /* Interrupt flag status clear register 1 */ +#define PIC32MX_INT_IFS1SET_OFFSET 0x0048 /* Interrupt flag status set register 1 */ +#define PIC32MX_INT_IFS1INV_OFFSET 0x004c /* Interrupt flag status invert register 1 */ +#define PIC32MX_INT_IFS2_OFFSET 0x0050 /* Interrupt flag status register 2 */ + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IFS2CLR_OFFSET 0x0054 /* Interrupt flag status clear register 2 */ +# define PIC32MX_INT_IFS2SET_OFFSET 0x0058 /* Interrupt flag status set register 2 */ +# define PIC32MX_INT_IFS2INV_OFFSET 0x005c /* Interrupt flag status invert register 2 */ +#endif + +#define PIC32MX_INT_IEC_OFFSET(n) (0x0060 + ((n) << 4)) +#define PIC32MX_INT_IECCLR_OFFSET(n) (0x0064 + ((n) << 4)) +#define PIC32MX_INT_IECSET_OFFSET(n) (0x0068 + ((n) << 4)) +#define PIC32MX_INT_IECINV_OFFSET(n) (0x006c + ((n) << 4)) +#define PIC32MX_INT_IEC0_OFFSET 0x0060 /* Interrupt enable control register 0 */ +#define PIC32MX_INT_IEC0CLR_OFFSET 0x0064 /* Interrupt enable control clear register 0 */ +#define PIC32MX_INT_IEC0SET_OFFSET 0x0068 /* Interrupt enable control set register 0 */ +#define PIC32MX_INT_IEC0INV_OFFSET 0x006c /* Interrupt enable control invert register 0 */ +#define PIC32MX_INT_IEC1_OFFSET 0x0070 /* Interrupt enable control register 1 */ +#define PIC32MX_INT_IEC1CLR_OFFSET 0x0074 /* Interrupt enable control clear register 1 */ +#define PIC32MX_INT_IEC1SET_OFFSET 0x0078 /* Interrupt enable control set register 1 */ +#define PIC32MX_INT_IEC1INV_OFFSET 0x007c /* Interrupt enable control invert register 1 */ + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IEC2_OFFSET 0x0080 /* Interrupt enable control register 2 */ +# define PIC32MX_INT_IEC2CLR_OFFSET 0x0084 /* Interrupt enable control clear register 2 */ +# define PIC32MX_INT_IEC2SET_OFFSET 0x0088 /* Interrupt enable control set register 2 */ +# define PIC32MX_INT_IEC2INV_OFFSET 0x008c /* Interrupt enable control invert register 2 */ +#endif + +#define PIC32MX_INT_IPC_OFFSET(n) (0x0090 + ((n) << 4)) +#define PIC32MX_INT_IPCCLR_OFFSET(n) (0x0094 + ((n) << 4)) +#define PIC32MX_INT_IPCSET_OFFSET(n) (0x0098 + ((n) << 4)) +#define PIC32MX_INT_IPCINV_OFFSET(n) (0x009c + ((n) << 4)) +#define PIC32MX_INT_IPC0_OFFSET 0x0090 /* Interrupt priority control register 0 */ +#define PIC32MX_INT_IPC0CLR_OFFSET 0x0094 /* Interrupt priority control clear register 0 */ +#define PIC32MX_INT_IPC0SET_OFFSET 0x0098 /* Interrupt priority control set register 0 */ +#define PIC32MX_INT_IPC0INV_OFFSET 0x009c /* Interrupt priority control invert register 0 */ +#define PIC32MX_INT_IPC1_OFFSET 0x00a0 /* Interrupt priority control register 1 */ +#define PIC32MX_INT_IPC1CLR_OFFSET 0x00a4 /* Interrupt priority control clear register 1 */ +#define PIC32MX_INT_IPC1SET_OFFSET 0x00a8 /* Interrupt priority control set register 1 */ +#define PIC32MX_INT_IPC1INV_OFFSET 0x00ac /* Interrupt priority control invert register 1 */ +#define PIC32MX_INT_IPC2_OFFSET 0x00b0 /* Interrupt priority control register 2 */ +#define PIC32MX_INT_IPC2CLR_OFFSET 0x00b4 /* Interrupt priority control clear register 2 */ +#define PIC32MX_INT_IPC2SET_OFFSET 0x00b8 /* Interrupt priority control set register 2 */ +#define PIC32MX_INT_IPC2INV_OFFSET 0x00bc /* Interrupt priority control invert register 2 */ +#define PIC32MX_INT_IPC3_OFFSET 0x00c0 /* Interrupt priority control register 3 */ +#define PIC32MX_INT_IPC3CLR_OFFSET 0x00c4 /* Interrupt priority control clear register 3 */ +#define PIC32MX_INT_IPC3SET_OFFSET 0x00c8 /* Interrupt priority control set register 3 */ +#define PIC32MX_INT_IPC3INV_OFFSET 0x00cc /* Interrupt priority control invert register 3 */ +#define PIC32MX_INT_IPC4_OFFSET 0x00d0 /* Interrupt priority control register 4 */ +#define PIC32MX_INT_IPC4CLR_OFFSET 0x00d4 /* Interrupt priority control clear register 4 */ +#define PIC32MX_INT_IPC4SET_OFFSET 0x00d8 /* Interrupt priority control set register 4 */ +#define PIC32MX_INT_IPC4INV_OFFSET 0x00dc /* Interrupt priority control invert register 4 */ +#define PIC32MX_INT_IPC5_OFFSET 0x00e0 /* Interrupt priority control register 5 */ +#define PIC32MX_INT_IPC5CLR_OFFSET 0x00e4 /* Interrupt priority control clear register 5 */ +#define PIC32MX_INT_IPC5SET_OFFSET 0x00e8 /* Interrupt priority control set register 5 */ +#define PIC32MX_INT_IPC5INV_OFFSET 0x00ec /* Interrupt priority control invert register 5 */ +#define PIC32MX_INT_IPC6_OFFSET 0x00f0 /* Interrupt priority control register 6 */ +#define PIC32MX_INT_IPC6CLR_OFFSET 0x00f4 /* Interrupt priority control clear register 6 */ +#define PIC32MX_INT_IPC6SET_OFFSET 0x00f8 /* Interrupt priority control set register 6 */ +#define PIC32MX_INT_IPC6INV_OFFSET 0x00fc /* Interrupt priority control invert register 6 */ +#define PIC32MX_INT_IPC7_OFFSET 0x0100 /* Interrupt priority control register 7 */ +#define PIC32MX_INT_IPC7CLR_OFFSET 0x0104 /* Interrupt priority control clear register 7 */ +#define PIC32MX_INT_IPC7SET_OFFSET 0x0108 /* Interrupt priority control set register 7 */ +#define PIC32MX_INT_IPC7INV_OFFSET 0x010c /* Interrupt priority control invert register 7 */ +#define PIC32MX_INT_IPC8_OFFSET 0x0110 /* Interrupt priority control register 8 */ +#define PIC32MX_INT_IPC8CLR_OFFSET 0x0114 /* Interrupt priority control clear register 8 */ +#define PIC32MX_INT_IPC8SET_OFFSET 0x0118 /* Interrupt priority control set register 8 */ +#define PIC32MX_INT_IPC8INV_OFFSET 0x011c /* Interrupt priority control invert register 8 */ +#define PIC32MX_INT_IPC9_OFFSET 0x0120 /* Interrupt priority control register 9 */ +#define PIC32MX_INT_IPC9CLR_OFFSET 0x0124 /* Interrupt priority control clear register 9 */ +#define PIC32MX_INT_IPC9SET_OFFSET 0x0128 /* Interrupt priority control set register 9 */ +#define PIC32MX_INT_IPC9INV_OFFSET 0x012c /* Interrupt priority control invert register 9 */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC10_OFFSET 0x0130 /* Interrupt priority control register 10 */ +# define PIC32MX_INT_IPC10CLR_OFFSET 0x0134 /* Interrupt priority control clear register 10 */ +# define PIC32MX_INT_IPC10SET_OFFSET 0x0138 /* Interrupt priority control set register 10 */ +# define PIC32MX_INT_IPC10INV_OFFSET 0x013c /* Interrupt priority control invert register 10 */ +#endif + +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC11_OFFSET 0x0140 /* Interrupt priority control register 11 */ +# define PIC32MX_INT_IPC11CLR_OFFSET 0x0144 /* Interrupt priority control clear register 11 */ +# define PIC32MX_INT_IPC11SET_OFFSET 0x0148 /* Interrupt priority control set register 11 */ +# define PIC32MX_INT_IPC11INV_OFFSET 0x014c /* Interrupt priority control invert register 11 */ +#endif + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC12_OFFSET 0x0150 /* Interrupt priority control register 12 */ +# define PIC32MX_INT_IPC12CLR_OFFSET 0x0154 /* Interrupt priority control clear register 12 */ +# define PIC32MX_INT_IPC12SET_OFFSET 0x0158 /* Interrupt priority control set register 12 */ +# define PIC32MX_INT_IPC12INV_OFFSET 0x015c /* Interrupt priority control invert register 12 */ +#endif + +/* Register Addresses *******************************************************/ + +#define PIC32MX_INT_INTCON (PIC32MX_INT_K1BASE+PIC32MX_INT_INTCON_OFFSET) +#define PIC32MX_INT_INTCONCLR (PIC32MX_INT_K1BASE+PIC32MX_INT_INTCONCLR_OFFSET) +#define PIC32MX_INT_INTCONSET (PIC32MX_INT_K1BASE+PIC32MX_INT_INTCONSET_OFFSET) +#define PIC32MX_INT_INTCONINV (PIC32MX_INT_K1BASE+PIC32MX_INT_INTCONINV_OFFSET) +#define PIC32MX_INT_INTSTAT (PIC32MX_INT_K1BASE+PIC32MX_INT_INTSTAT_OFFSET) +#define PIC32MX_INT_INTSTATCLR (PIC32MX_INT_K1BASE+PIC32MX_INT_INTSTATCLR_OFFSET) +#define PIC32MX_INT_INTSTATSET (PIC32MX_INT_K1BASE+PIC32MX_INT_INTSTATSET_OFFSET) +#define PIC32MX_INT_INTSTATINV (PIC32MX_INT_K1BASE+PIC32MX_INT_INTSTATINV_OFFSET) +#define PIC32MX_INT_TPTMR (PIC32MX_INT_K1BASE+PIC32MX_INT_TPTMR_OFFSET) +#define PIC32MX_INT_TPTMRCLR (PIC32MX_INT_K1BASE+PIC32MX_INT_TPTMRCLR_OFFSET) +#define PIC32MX_INT_TPTMRSET (PIC32MX_INT_K1BASE+PIC32MX_INT_TPTMRSET_OFFSET) +#define PIC32MX_INT_TPTMRINV (PIC32MX_INT_K1BASE+PIC32MX_INT_TPTMRINV_OFFSET) +#define PIC32MX_INT_IFS(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS_OFFSET(n)) +#define PIC32MX_INT_IFSCLR(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IFSCLR_OFFSET(n)) +#define PIC32MX_INT_IFSSET(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IFSSET_OFFSET(n)) +#define PIC32MX_INT_IFSINV(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IFSINV_OFFSET(n)) +#define PIC32MX_INT_IFS0 (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS0_OFFSET) +#define PIC32MX_INT_IFS0CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS0CLR_OFFSET) +#define PIC32MX_INT_IFS0SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS0SET_OFFSET) +#define PIC32MX_INT_IFS0INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS0INV_OFFSET) +#define PIC32MX_INT_IFS1 (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS1_OFFSET) +#define PIC32MX_INT_IFS1CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS1CLR_OFFSET) +#define PIC32MX_INT_IFS1SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS1SET_OFFSET) +#define PIC32MX_INT_IFS1INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS1INV_OFFSET) + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IFS2 (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS2_OFFSET) +# define PIC32MX_INT_IFS2CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS2CLR_OFFSET) +# define PIC32MX_INT_IFS2SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS2SET_OFFSET) +# define PIC32MX_INT_IFS2INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IFS2INV_OFFSET) +#endif + +#define PIC32MX_INT_IEC(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC_OFFSET(n)) +#define PIC32MX_INT_IECCLR(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IECCLR_OFFSET(n)) +#define PIC32MX_INT_IECSET(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IECSET_OFFSET(n)) +#define PIC32MX_INT_IECINV(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IECINV_OFFSET(n)) +#define PIC32MX_INT_IEC0 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0_OFFSET) +#define PIC32MX_INT_IEC0CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0CLR_OFFSET) +#define PIC32MX_INT_IEC0SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0SET_OFFSET) +#define PIC32MX_INT_IEC0INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0_OFFSET) +#define PIC32MX_INT_IEC1 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1_OFFSET) +#define PIC32MX_INT_IEC1CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1CLR_OFFSET) +#define PIC32MX_INT_IEC1SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1SET_OFFSET) +#define PIC32MX_INT_IEC1INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1INV_OFFSET) + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IEC2 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC2_OFFSET) +# define PIC32MX_INT_IEC2CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC2CLR_OFFSET) +# define PIC32MX_INT_IEC2SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC2SET_OFFSET) +# define PIC32MX_INT_IEC2INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC2INV_OFFSET) +#endif + +#define PIC32MX_INT_IPC(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC_OFFSET(n)) +#define PIC32MX_INT_IPCCLR(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IPCCLR_OFFSET(n)) +#define PIC32MX_INT_IPCSET(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IPCSET_OFFSET(n)) +#define PIC32MX_INT_IPCINV(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IPCINV_OFFSET(n)) +#define PIC32MX_INT_IPC0 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC0_OFFSET) +#define PIC32MX_INT_IPC0CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC0CLR_OFFSET) +#define PIC32MX_INT_IPC0SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC0SET_OFFSET) +#define PIC32MX_INT_IPC0INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC0INV_OFFSET) +#define PIC32MX_INT_IPC1 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC1_OFFSET) +#define PIC32MX_INT_IPC1CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC1CLR_OFFSET) +#define PIC32MX_INT_IPC1SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC1SET_OFFSET) +#define PIC32MX_INT_IPC1INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC1INV_OFFSET) +#define PIC32MX_INT_IPC2 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC2_OFFSET) +#define PIC32MX_INT_IPC2CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC2CLR_OFFSET) +#define PIC32MX_INT_IPC2SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC2SET_OFFSET) +#define PIC32MX_INT_IPC2INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC2INV_OFFSET) +#define PIC32MX_INT_IPC3 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC3_OFFSET) +#define PIC32MX_INT_IPC3CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC3CLR_OFFSET) +#define PIC32MX_INT_IPC3SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC3SET_OFFSET) +#define PIC32MX_INT_IPC3INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC3INV_OFFSET) +#define PIC32MX_INT_IPC4 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC4_OFFSET) +#define PIC32MX_INT_IPC4CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC4CLR_OFFSET) +#define PIC32MX_INT_IPC4SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC4SET_OFFSET) +#define PIC32MX_INT_IPC4INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC4INV_OFFSET) +#define PIC32MX_INT_IPC5 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC5_OFFSET) +#define PIC32MX_INT_IPC5CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC5CLR_OFFSET) +#define PIC32MX_INT_IPC5SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC5SET_OFFSET) +#define PIC32MX_INT_IPC5INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC5INV_OFFSET) +#define PIC32MX_INT_IPC6 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC6_OFFSET) +#define PIC32MX_INT_IPC6CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC6CLR_OFFSET) +#define PIC32MX_INT_IPC6SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC6SET_OFFSET) +#define PIC32MX_INT_IPC6INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC6INV_OFFSET) +#define PIC32MX_INT_IPC7 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC7_OFFSET) +#define PIC32MX_INT_IPC7CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC7CLR_OFFSET) +#define PIC32MX_INT_IPC7SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC7SET_OFFSET) +#define PIC32MX_INT_IPC7INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC7INV_OFFSET) +#define PIC32MX_INT_IPC8 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC8_OFFSET) +#define PIC32MX_INT_IPC8CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC8CLR_OFFSET) +#define PIC32MX_INT_IPC8SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC8SET_OFFSET) +#define PIC32MX_INT_IPC8INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC8INV_OFFSET) +#define PIC32MX_INT_IPC9 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC9_OFFSET) +#define PIC32MX_INT_IPC9CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC9CLR_OFFSET) +#define PIC32MX_INT_IPC9SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC9SET_OFFSET) +#define PIC32MX_INT_IPC9INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC9INV_OFFSET) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC10 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC10_OFFSET) +# define PIC32MX_INT_IPC10CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC10CLR_OFFSET) +# define PIC32MX_INT_IPC10SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC10SET_OFFSET) +# define PIC32MX_INT_IPC10INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC10INV_OFFSET) +#endif + +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC11 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC11_OFFSET) +# define PIC32MX_INT_IPC11CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC11CLR_OFFSET) +# define PIC32MX_INT_IPC11SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC11SET_OFFSET) +# define PIC32MX_INT_IPC11INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC11INV_OFFSET) +#endif + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define PIC32MX_INT_IPC12 (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC12_OFFSET) +# define PIC32MX_INT_IPC12CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC12CLR_OFFSET) +# define PIC32MX_INT_IPC12SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC12SET_OFFSET) +# define PIC32MX_INT_IPC12INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC12INV_OFFSET) +#endif + +/* Register Bit-Field Definitions *******************************************/ + +/* Interrupt control register */ + +#define INT_INTCON_INT0EP (1 << 0) /* Bit 0: External interrupt 0 edge polarity control */ +#define INT_INTCON_INT1EP (1 << 1) /* Bit 1: External interrupt 1 edge polarity control */ +#define INT_INTCON_INT2EP (1 << 2) /* Bit 2: External interrupt 2 edge polarity control */ +#define INT_INTCON_INT3EP (1 << 3) /* Bit 3: External interrupt 3 edge polarity control */ +#define INT_INTCON_INT4EP (1 << 4) /* Bit 4: External interrupt 4 edge polarity control */ +#define INT_INTCON_TPC_SHIFT (8) /* Bits 8-10: Temporal proximity control */ +#define INT_INTCON_TPC_MASK (7 << INT_INTCON_TPC_SHIFT) +# define INT_INTCON_TPC_DIS (0 << INT_INTCON_TPC_SHIFT) /* Disables proximity timer */ +# define INT_INTCON_TPC_PRIO1 (1 << INT_INTCON_TPC_SHIFT) /* Int group priority 1 start IP timer */ +# define INT_INTCON_TPC_PRIO2 (2 << INT_INTCON_TPC_SHIFT) /* Int group priority <=2 start TP timer */ +# define INT_INTCON_TPC_PRIO3 (3 << INT_INTCON_TPC_SHIFT) /* Int group priority <=3 start TP timer */ +# define INT_INTCON_TPC_PRIO4 (4 << INT_INTCON_TPC_SHIFT) /* Int group priority <=4 start TP timer */ +# define INT_INTCON_TPC_PRIO5 (5 << INT_INTCON_TPC_SHIFT) /* Int group priority <=5 start TP timer */ +# define INT_INTCON_TPC_PRIO6 (6 << INT_INTCON_TPC_SHIFT) /* Int group priority <=6 start TP timer */ +# define INT_INTCON_TPC_PRIO7 (7 << INT_INTCON_TPC_SHIFT) /* Int group priority <=7 start TP timer */ +#define INT_INTCON_MVEC (1 << 12) /* Bit 12: Multi vector configuration */ + +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define INT_INTCON_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +#endif + +#define INT_INTCON_SS0 (1 << 16) /* Bit 16: Single vector shadow register set */ + +/* Interrupt status register */ + +#define INT_INTSTAT_VEC_SHIFT (0) /* Bits 0-5: Interrupt vector */ +#define INT_INTSTAT_VEC_MASK (0x3f << INT_INTSTAT_VEC_SHIFT) +#define INT_INTSTAT_RIPL_SHIFT (8) /* Bits 8-10: Requested priority level */ +#define INT_INTSTAT_RIPL_MASK (7 << INT_INTSTAT_RIPL_SHIFT) + +/* Temporal proximity timer register -- This register contains a 32-bit value + * with no field definitions. + */ + +/* Interrupt flag status register 0 and Interrupt enable control register 0 */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +#define INT_CT (1 << 0) /* Vector: 0, Core Timer Interrupt */ +#define INT_CS0 (1 << 1) /* Vector: 1, Core Software Interrupt 0 */ +#define INT_CS1 (1 << 2) /* Vector: 2, Core Software Interrupt 1 */ +#define INT_INT0 (1 << 3) /* Vector: 3, External Interrupt 0 */ +#define INT_T1 (1 << 4) /* Vector: 4, Timer 1 */ +#define INT_IC1E (1 << 5) /* Vector: 5, Input Capture 1 Error */ +#define INT_IC1 (1 << 6) /* Vector: 5, Input Capture 1 */ +#define INT_OC1 (1 << 7) /* Vector: 6, Output Compare 1 */ +#define INT_INT1 (1 << 8) /* Vector: 7, External Interrupt 1 */ +#define INT_T2 (1 << 9) /* Vector: 8, Timer 2 */ +#define INT_IC2E (1 << 10) /* Vector: 9, Input Capture 2 Error */ +#define INT_IC2 (1 << 11) /* Vector: 9, Input Capture 2 */ +#define INT_OC2 (1 << 12) /* Vector: 10, Output Compare 2 */ +#define INT_INT2 (1 << 13) /* Vector: 11, External Interrupt 2 */ +#define INT_T3 (1 << 14) /* Vector: 12, Timer 3 */ +#define INT_IC3E (1 << 15) /* Vector: 13, Input Capture 3 Error */ +#define INT_IC3 (1 << 16) /* Vector: 13, Input Capture 3 */ +#define INT_OC3 (1 << 17) /* Vector: 14, Output Compare 3 */ +#define INT_INT3 (1 << 18) /* Vector: 15, External Interrupt 3 */ +#define INT_T4 (1 << 19) /* Vector: 16, Timer 4 */ +#define INT_IC4E (1 << 20) /* Vector: 17, Input Capture 4 Error */ +#define INT_IC4 (1 << 21) /* Vector: 17, Input Capture 4 */ +#define INT_OC4 (1 << 22) /* Vector: 18, Output Compare 4 */ +#define INT_INT4 (1 << 23) /* Vector: 19, External Interrupt 4 */ +#define INT_T5 (1 << 24) /* Vector: 20, Timer 5 */ +#define INT_IC5E (1 << 25) /* Vector: 21, Input Capture 5 Error */ +#define INT_IC5 (1 << 26) /* Vector: 21, Input Capture 5 */ +#define INT_OC5 (1 << 27) /* Vector: 22, Output Compare 5 */ +#define INT_AD1 (1 << 28) /* Vector: 23, ADC1 Convert Done */ +#define INT_FSCM (1 << 29) /* Vector: 24, Fail-Safe Clock Monitor */ +#define INT_RTCC (1 << 30) /* Vector: 25, Real-Time Clock and Calendar */ +#define INT_FCE (1 << 31) /* Vector: 26, Flash Control Event */ + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define INT_CT (1 << 0) /* Vector: 0, Core Timer Interrupt */ +# define INT_CS0 (1 << 1) /* Vector: 1, Core Software Interrupt 0 */ +# define INT_CS1 (1 << 2) /* Vector: 2, Core Software Interrupt 1 */ +# define INT_INT0 (1 << 3) /* Vector: 3, External Interrupt 0 */ +# define INT_T1 (1 << 4) /* Vector: 4, Timer 1 */ +# define INT_IC1 (1 << 5) /* Vector: 5, Input Capture 1 */ +# define INT_OC1 (1 << 6) /* Vector: 6, Output Compare 1 */ +# define INT_INT1 (1 << 7) /* Vector: 7, External Interrupt 1 */ +# define INT_T2 (1 << 8) /* Vector: 8, Timer 2 */ +# define INT_IC2 (1 << 9) /* Vector: 9, Input Capture 2 */ +# define INT_OC2 (1 << 10) /* Vector: 10, Output Compare 2 */ +# define INT_INT2 (1 << 11) /* Vector: 11, External Interrupt 2 */ +# define INT_T3 (1 << 12) /* Vector: 12, Timer 3 */ +# define INT_IC3 (1 << 13) /* Vector: 13, Input Capture 3 */ +# define INT_OC3 (1 << 14) /* Vector: 14, Output Compare 3 */ +# define INT_INT3 (1 << 15) /* Vector: 15, External Interrupt 3 */ +# define INT_T4 (1 << 16) /* Vector: 16, Timer 4 */ +# define INT_IC4 (1 << 17) /* Vector: 17, Input Capture 4 */ +# define INT_OC4 (1 << 18) /* Vector: 18, Output Compare 4 */ +# define INT_INT4 (1 << 19) /* Vector: 19, External Interrupt 4 */ +# define INT_T5 (1 << 20) /* Vector: 20, Timer 5 */ +# define INT_IC5 (1 << 21) /* Vector: 21, Input Capture 5 */ +# define INT_OC5 (1 << 22) /* Vector: 22, Output Compare 5 */ +# define INT_SPI1E (1 << 23) /* Vector: 23, SPI1 Error */ +# define INT_SPI1TX (1 << 24) /* Vector: 23, " " Transfer done */ +# define INT_SPI1RX (1 << 25) /* Vector: 23, " " Receive done */ +# define INT_U1E (1 << 26) /* Vector: 24, UART1 Error */ +# define INT_U1RX (1 << 27) /* Vector: 24, " " Receiver */ +# define INT_U1TX (1 << 28) /* Vector: 24, " " Transmitter */ +# define INT_I2C1B (1 << 29) /* Vector: 25, I2C1 Bus collision event */ +# define INT_I2C1S (1 << 30) /* Vector: 25, " " Slave event */ +# define INT_I2C1M (1 << 31) /* Vector: 25, " " Master event */ + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define INT_CT (1 << 0) /* Vector: 0, Core Timer Interrupt */ +# define INT_CS0 (1 << 1) /* Vector: 1, Core Software Interrupt 0 */ +# define INT_CS1 (1 << 2) /* Vector: 2, Core Software Interrupt 1 */ +# define INT_INT0 (1 << 3) /* Vector: 3, External Interrupt 0 */ +# define INT_T1 (1 << 4) /* Vector: 4, Timer 1 */ +# define INT_IC1 (1 << 5) /* Vector: 5, Input Capture 1 */ +# define INT_OC1 (1 << 6) /* Vector: 6, Output Compare 1 */ +# define INT_INT1 (1 << 7) /* Vector: 7, External Interrupt 1 */ +# define INT_T2 (1 << 8) /* Vector: 8, Timer 2 */ +# define INT_IC2 (1 << 9) /* Vector: 9, Input Capture 2 */ +# define INT_OC2 (1 << 10) /* Vector: 10, Output Compare 2 */ +# define INT_INT2 (1 << 11) /* Vector: 11, External Interrupt 2 */ +# define INT_T3 (1 << 12) /* Vector: 12, Timer 3 */ +# define INT_IC3 (1 << 13) /* Vector: 13, Input Capture 3 */ +# define INT_OC3 (1 << 14) /* Vector: 14, Output Compare 3 */ +# define INT_INT3 (1 << 15) /* Vector: 15, External Interrupt 3 */ +# define INT_T4 (1 << 16) /* Vector: 16, Timer 4 */ +# define INT_IC4 (1 << 17) /* Vector: 17, Input Capture 4 */ +# define INT_OC4 (1 << 18) /* Vector: 18, Output Compare 4 */ +# define INT_INT4 (1 << 19) /* Vector: 19, External Interrupt 4 */ +# define INT_T5 (1 << 20) /* Vector: 20, Timer 5 */ +# define INT_IC5 (1 << 21) /* Vector: 21, Input Capture 5 */ +# define INT_OC5 (1 << 22) /* Vector: 22, Output Compare 5 */ +# define INT_SPI1E (1 << 23) /* Vector: 23, SPI1 Error */ +# define INT_SPI1TX (1 << 24) /* Vector: 23, " " Transfer done */ +# define INT_SPI1RX (1 << 25) /* Vector: 23, " " Receive done */ +# define INT_26 (1 << 26) /* Vector: 24, UART1, SPI3, I2C3 */ +# define INT_U1E (1 << 26) /* Vector: 24, UART1 Error */ +# define INT_SPI3E (1 << 26) /* Vector: 24, SPI3 Fault */ +# define INT_I2C3B (1 << 26) /* Vector: 24, I2C3 Bus collision event */ +# define INT_27 (1 << 27) /* Vector: 24, UART1, SPI3, I2C3 */ +# define INT_U1RX (1 << 27) /* Vector: 24, UART1 Receiver */ +# define INT_SPI3RX (1 << 27) /* Vector: 24, SPI3 Receive done */ +# define INT_I2C3S (1 << 27) /* Vector: 24, I2C3 Slave event */ +# define INT_28 (1 << 28) /* Vector: 24, UART1, SPI3, I2C3 */ +# define INT_U1TX (1 << 28) /* Vector: 24, UART1 Transmitter */ +# define INT_SPI3TX (1 << 28) /* Vector: 24, SPI3 Transfer done */ +# define INT_I2C3M (1 << 28) /* Vector: 24, I2C3 Master event */ +# define INT_I2C1B (1 << 29) /* Vector: 25, I2C1 Bus collision event */ +# define INT_I2C1S (1 << 30) /* Vector: 25, " " Slave event */ +# define INT_I2C1M (1 << 31) /* Vector: 25, " " Master event */ + +#else +# error "Unknown PIC32MX family" +#endif + +/* Interrupt flag status register 1 and Interrupt enable control register 1 */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define INT_CMP1 (1 << 0) /* Vector: 27, Comparator 1 Interrupt */ +# define INT_CMP2 (1 << 1) /* Vector: 28, Comparator 2 Interrupt */ +# define INT_CMP3 (1 << 2) /* Vector: 29, Comparator 3 Interrupt */ +# define INT_USB (1 << 3) /* Vector: 30, USB */ +# define INT_SPI1E (1 << 4) /* Vector: 31, SPI1 */ +# define INT_SPI1TX (1 << 5) /* Vector: 31, " " */ +# define INT_SPI1RX (1 << 6) /* Vector: 31, " " */ +# define INT_U1E (1 << 7) /* Vector: 32, UART1 */ +# define INT_U1RX (1 << 8) /* Vector: 32, " " */ +# define INT_U1TX (1 << 9) /* Vector: 32, " " */ +# define INT_I2C1B (1 << 10) /* Vector: 33, I2C1 */ +# define INT_I2C1S (1 << 11) /* Vector: 33, " " */ +# define INT_I2C1M (1 << 12) /* Vector: 33, " " */ +# define INT_CNA (1 << 13) /* Vector: 34, Input Change Interrupt */ +# define INT_CNB (1 << 14) /* Vector: 34, Input Change Interrupt */ +# define INT_CNC (1 << 15) /* Vector: 34, Input Change Interrupt */ +# define INT_PMP (1 << 16) /* Vector: 35, Parallel Master Port */ +# define INT_PMPE (1 << 17) /* Vector: 35, Parallel Master Port */ +# define INT_SPI2E (1 << 18) /* Vector: 36, SPI2 */ +# define INT_SPI2TX (1 << 19) /* Vector: 36, " " */ +# define INT_SPI2RX (1 << 20) /* Vector: 36, " " */ +# define INT_U2E (1 << 21) /* Vector: 37, UART2 */ +# define INT_U2RX (1 << 22) /* Vector: 37, " " */ +# define INT_U2TX (1 << 23) /* Vector: 37, " " */ +# define INT_I2C2B (1 << 24) /* Vector: 38, I2C2 */ +# define INT_I2C2S (1 << 25) /* Vector: 38, " " */ +# define INT_I2C2M (1 << 26) /* Vector: 38, " " */ +# define INT_CTMU (1 << 27) /* Vector: 39, CTMU */ +# define INT_DMA0 (1 << 28) /* Vector: 40, DMA Channel 0 */ +# define INT_DMA1 (1 << 29) /* Vector: 41, DMA Channel 1 */ +# define INT_DMA2 (1 << 30) /* Vector: 42, DMA Channel 2 */ +# define INT_DMA3 (1 << 31) /* Vector: 43, DMA Channel 3 */ + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define INT_CN (1 << 0) /* Vector: 26, Input Change Interrupt */ +# define INT_AD1 (1 << 1) /* Vector: 27, ADC1 Convert Done */ +# define INT_PMP (1 << 2) /* Vector: 28, Parallel Master Port */ +# define INT_CMP1 (1 << 3) /* Vector: 29, Comparator Interrupt */ +# define INT_CMP2 (1 << 4) /* Vector: 30, Comparator Interrupt */ +# define INT_SPI2E (1 << 5) /* Vector: 31, SPI2 Error */ +# define INT_SPI2TX (1 << 6) /* Vector: 31, " " Transfer done */ +# define INT_SPI2RX (1 << 7) /* Vector: 31, " " Receive done*/ +# define INT_U2E (1 << 8) /* Vector: 32, UART2 Error */ +# define INT_U2RX (1 << 9) /* Vector: 32, " " Receiver */ +# define INT_U2TX (1 << 10) /* Vector: 32, " " Transmitter */ +# define INT_I2C2B (1 << 11) /* Vector: 33, I2C2 Bus collision event */ +# define INT_I2C2S (1 << 12) /* Vector: 33, " " Master event */ +# define INT_I2C2M (1 << 13) /* Vector: 33, " " Slave event */ +# define INT_FSCM (1 << 14) /* Vector: 34, Fail-Safe Clock Monitor */ +# define INT_RTCC (1 << 15) /* Vector: 35, Real-Time Clock and Calendar */ +# define INT_DMA0 (1 << 16) /* Vector: 36, DMA Channel 0 */ +# define INT_DMA1 (1 << 17) /* Vector: 37, DMA Channel 1 */ +# define INT_DMA2 (1 << 18) /* Vector: 38, DMA Channel 2 */ +# define INT_DMA3 (1 << 19) /* Vector: 39, DMA Channel 3 */ +# define INT_FCE (1 << 24) /* Vector: 44, Flash Control Event */ +# define INT_USB (1 << 25) /* Vector: 45, USB Interrupt */ + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define INT_CN (1 << 0) /* Vector: 26, Input Change Interrupt */ +# define INT_AD1 (1 << 1) /* Vector: 27, ADC1 Convert Done */ +# define INT_PMP (1 << 2) /* Vector: 28, Parallel Master Port */ +# define INT_CMP1 (1 << 3) /* Vector: 29, Comparator Interrupt */ +# define INT_CMP2 (1 << 4) /* Vector: 30, Comparator Interrupt */ +# define INT_37 (1 << 5) /* Vector: 31, UART3, SPI2, I2C4 */ +# define INT_U3E (1 << 5) /* Vector: 31, UART3 Error */ +# define INT_SPI2E (1 << 5) /* Vector: 31, SPI2 Fault */ +# define INT_I2C4B (1 << 5) /* Vector: 31, I2C4 Bus collision event */ +# define INT_38 (1 << 6) /* Vector: 31, UART3, SPI2, I2C4 */ +# define INT_U3RX (1 << 6) /* Vector: 31, UART3 Receiver */ +# define INT_SPI2RX (1 << 6) /* Vector: 31, SPI2 Receive done */ +# define INT_I2C4S (1 << 6) /* Vector: 31, I2C4 Slave event */ +# define INT_39 (1 << 7) /* Vector: 31, UART3, SPI2, I2C4 */ +# define INT_U3TX (1 << 7) /* Vector: 31, UART3 Transmitter */ +# define INT_SPI2TX (1 << 7) /* Vector: 31, SPI2 Transfer done */ +# define INT_I2C4M (1 << 7) /* Vector: 31, I2C4 Master event */ +# define INT_40 (1 << 8) /* Vector: 32, UART2, SPI4, I2C5 */ +# define INT_U2E (1 << 8) /* Vector: 32, UART2 Error */ +# define INT_SPI4E (1 << 8) /* Vector: 32, SPI4 Fault */ +# define INT_I2C5B (1 << 8) /* Vector: 32, I2C5 Bus collision event */ +# define INT_41 (1 << 9) /* Vector: 32, UART2, SPI4, I2C5 */ +# define INT_U2RX (1 << 9) /* Vector: 32, UART2 Receiver */ +# define INT_SPI4RX (1 << 9) /* Vector: 32, SPI4 Receive done */ +# define INT_I2C5S (1 << 9) /* Vector: 32, I2C5 Slave event */ +# define INT_42 (1 << 10) /* Vector: 32, UART2, SPI4, I2C5 */ +# define INT_U2TX (1 << 10) /* Vector: 32, UART2 Transmitter */ +# define INT_SPI4TX (1 << 10) /* Vector: 32, SPI4 Transfer done */ +# define INT_I2C5M (1 << 10) /* Vector: 32, I2C5 Master event */ +# define INT_I2C2B (1 << 11) /* Vector: 33, I2C2 Bus collision event */ +# define INT_I2C2S (1 << 12) /* Vector: 33, " " Master event */ +# define INT_I2C2M (1 << 13) /* Vector: 33, " " Slave event */ +# define INT_FSCM (1 << 14) /* Vector: 34, Fail-Safe Clock Monitor */ +# define INT_RTCC (1 << 15) /* Vector: 35, Real-Time Clock and Calendar */ +# define INT_DMA0 (1 << 16) /* Vector: 36, DMA Channel 0 */ +# define INT_DMA1 (1 << 17) /* Vector: 37, DMA Channel 1 */ +# define INT_DMA2 (1 << 18) /* Vector: 38, DMA Channel 2 */ +# define INT_DMA3 (1 << 19) /* Vector: 39, DMA Channel 3 */ +# define INT_DMA4 (1 << 20) /* Vector: 40, DMA Channel 3 */ +# define INT_DMA5 (1 << 21) /* Vector: 41, DMA Channel 3 */ +# define INT_DMA6 (1 << 22) /* Vector: 42, DMA Channel 3 */ +# define INT_DMA7 (1 << 23) /* Vector: 43, DMA Channel 3 */ +# define INT_FCE (1 << 24) /* Vector: 44, Flash Control Event */ +# define INT_USB (1 << 25) /* Vector: 45, USB Interrupt */ +# define INT_CAN1 (1 << 26) /* Vector: 46, Control Area Network 1 */ +# define INT_CAN2 (1 << 27) /* Vector: 47, Control Area Network 2 */ +# define INT_ETH (1 << 28) /* Vector: 48, Ethernet interrupt */ +# define INT_IC1E (1 << 29) /* Vector: 5, Input capture 1 error */ +# define INT_IC2E (1 << 30) /* Vector: 9, Input capture 1 error */ +# define INT_IC3E (1 << 31) /* Vector: 13, Input capture 1 error */ + +#else +# error "Unknown PIC32MX family" +#endif + +/* Interrupt flag status register 2 and Interrupt enable control register 2 */ + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define INT_IC4E (1 << 0) /* Vector: 17, Input capture 1 error */ +# define INT_IC5E (1 << 1) /* Vector: 21, Input capture 1 error */ +# define INT_PMPE (1 << 2) /* Vector: 28, Parallel master port error */ +# define INT_U4E (1 << 3) /* Vector: 49, UART4 Error */ +# define INT_U4RX (1 << 4) /* Vector: 49, UART4 Receiver */ +# define INT_U4TX (1 << 5) /* Vector: 49, UART4 Transmitter */ +# define INT_U6E (1 << 6) /* Vector: 50, UART6 Error */ +# define INT_U6RX (1 << 7) /* Vector: 50, UART6 Receiver */ +# define INT_U6TX (1 << 8) /* Vector: 50, UART6 Transmitter */ +# define INT_U5E (1 << 9) /* Vector: 51, UART5 Error */ +# define INT_U5RX (1 << 10) /* Vector: 51, UART5 Receiver */ +# define INT_U5TX (1 << 11) /* Vector: 51, UART5 Transmitter */ + +#endif + +/* Interrupt priority control register 0-11 */ + +#define INT_IPC_DISABLED 0 /* Disabled! */ +#define INT_IPC_MIN_PRIORITY 1 /* Minimum (enabled) priority */ +#define INT_IPC_MID_PRIORITY 4 /* Can be used as the default */ +#define INT_IPC_MAX_PRIORITY 7 /* Maximum priority */ +#define INT_IPC_MIN_SUBPRIORITY 0 /* Minimum sub-priority */ +#define INT_IPC_MAX_SUBPRIORITY 0 /* Maximum sub-priority */ + +#define INT_IPC0_CTIS_SHIFT (0) /* Bits 0-1, Vector: 0, Core Timer Interrupt */ +#define INT_IPC0_CTIS_MASK (3 << INT_IPC0_CTIS_SHIFT) +#define INT_IPC0_CTIP_SHIFT (2) /* Bits 2-4, Vector: 0, Core Timer Interrupt */ +#define INT_IPC0_CTIP_MASK (7 << INT_IPC0_CTIP_SHIFT) +#define INT_IPC0_CS0IS_SHIFT (8) /* Bits 8-9, Vector: 1, Core Software Interrupt 0 */ +#define INT_IPC0_CS0IS_MASK (3 << INT_IPC0_CS0IS_SHIFT) +#define INT_IPC0_CS0IP_SHIFT (10) /* Bits 10-12, Vector: 1, Core Software Interrupt 0 */ +#define INT_IPC0_CS0IP_MASK (7 << INT_IPC0_CS0IP_SHIFT) +#define INT_IPC0_CS1IS_SHIFT (16) /* Bits 16-17, Vector: 2, Core Software Interrupt 1 */ +#define INT_IPC0_CS1IS_MASK (3 << INT_IPC0_CS1IS_SHIFT) +#define INT_IPC0_CS1IP_SHIFT (18) /* Bits 18-20, Vector: 2, Core Software Interrupt 1 */ +#define INT_IPC0_CS1IP_MASK (7 << INT_IPC0_CS1IP_SHIFT) +#define INT_IPC0_INT0IS_SHIFT (24) /* Bits 24-25, Vector: 3, External Interrupt 0 */ +#define INT_IPC0_INT0IS_MASK (3 << INT_IPC0_INT0IS_SHIFT) +#define INT_IPC0_INT0IP_SHIFT (26) /* Bits 26-28, Vector: 3, External Interrupt 0 */ +#define INT_IPC0_INT0IP_MASK (7 << INT_IPC0_INT0IP_SHIFT) + +#define INT_IPC1_T1IS_SHIFT (0) /* Bits 0-1, Vector: 4, Timer 1 */ +#define INT_IPC1_T1IS_MASK (3 << INT_IPC1_T1IS_SHIFT) +#define INT_IPC1_T1IP_SHIFT (2) /* Bits 2-4, Vector: 4, Timer 1 */ +#define INT_IPC1_T1IP_MASK (7 << INT_IPC1_T1IP_SHIFT) +#define INT_IPC1_IC1IS_SHIFT (8) /* Bits 8-9, Vector: 5, Input Capture 1 */ +#define INT_IPC1_IC1IS_MASK (3 << INT_IPC1_IC1IS_SHIFT) +#define INT_IPC1_IC1IP_SHIFT (10) /* Bits 10-12, Vector: 5, Input Capture 1 */ +#define INT_IPC1_IC1IP_MASK (7 << INT_IPC1_IC1IP_SHIFT) +#define INT_IPC1_OC1IS_SHIFT (16) /* Bits 16-17, Vector: 6, Output Compare 1 */ +#define INT_IPC1_OC1IS_MASK (3 << INT_IPC1_OC1IS_SHIFT) +#define INT_IPC1_OC1IP_SHIFT (18) /* Bits 18-20, Vector: 6, Output Compare 1 */ +#define INT_IPC1_OC1IP_MASK (7 << INT_IPC1_OC1IP_SHIFT) +#define INT_IPC1_INT1IS_SHIFT (24) /* Bits 24-25, Vector: 7, External Interrupt 1 */ +#define INT_IPC1_INT1IS_MASK (3 << INT_IPC1_INT1IS_SHIFT) +#define INT_IPC1_INT1IP_SHIFT (26) /* Bits 26-28, Vector: 7, External Interrupt 1 */ +#define INT_IPC1_INT1IP_MASK (7 << INT_IPC1_INT1IP_SHIFT) + +#define INT_IPC2_T2IS_SHIFT (0) /* Bits 0-1, Vector: 8, Timer 2 */ +#define INT_IPC2_T2IS_MASK (3 << INT_IPC2_T2IS_SHIFT) +#define INT_IPC2_T2IP_SHIFT (2) /* Bits 2-4, Vector: 8, Timer 2 */ +#define INT_IPC2_T2IP_MASK (7 << INT_IPC2_T2IP_SHIFT) +#define INT_IPC2_IC2IS_SHIFT (8) /* Bits 8-9, Vector: 9, Input Capture 2 */ +#define INT_IPC2_IC2IS_MASK (3 << INT_IPC2_IC2IS_SHIFT) +#define INT_IPC2_IC2IP_SHIFT (10) /* Bits 10-12, Vector: 9, Input Capture 2 */ +#define INT_IPC2_IC2IP_MASK (7 << INT_IPC2_IC2IP_SHIFT) +#define INT_IPC2_OC2IS_SHIFT (16) /* Bits 16-17, Vector: 10, Output Compare 2 */ +#define INT_IPC2_OC2IS_MASK (3 << INT_IPC2_OC2IS_SHIFT) +#define INT_IPC2_OC2IP_SHIFT (18) /* Bits 18-20, Vector: 10, Output Compare 2 */ +#define INT_IPC2_OC2IP_MASK (7 << INT_IPC2_OC2IP_SHIFT) +#define INT_IPC2_INT2IS_SHIFT (24) /* Bits 24-25, Vector: 11, External Interrupt 2 */ +#define INT_IPC2_INT2IS_MASK (3 << INT_IPC2_INT2IS_SHIFT) +#define INT_IPC2_INT2IP_SHIFT (26) /* Bits 26-28, Vector: 11, External Interrupt 2 */ +#define INT_IPC2_INT2IP_MASK (7 << INT_IPC2_INT2IP_SHIFT) + +#define INT_IPC3_T3IS_SHIFT (0) /* Bits 0-1, Vector: 12, Timer 3 */ +#define INT_IPC3_T3IS_MASK (3 << INT_IPC3_T3IS_SHIFT) +#define INT_IPC3_T3IP_SHIFT (2) /* Bits 2-4, Vector: 12, Timer 3 */ +#define INT_IPC3_T3IP_MASK (7 << INT_IPC3_T3IP_SHIFT) +#define INT_IPC3_IC3IS_SHIFT (8) /* Bits 8-9, Vector: 13, Input Capture 3 */ +#define INT_IPC3_IC3IS_MASK (3 << INT_IPC3_IC3IS_SHIFT) +#define INT_IPC3_IC3IP_SHIFT (10) /* Bits 10-12, Vector: 13, Input Capture 3 */ +#define INT_IPC3_IC3IP_MASK (7 << INT_IPC3_IC3IP_SHIFT) +#define INT_IPC3_OC3IS_SHIFT (16) /* Bits 16-17, Vector: 14, Output Compare 3 */ +#define INT_IPC3_OC3IS_MASK (3 << INT_IPC3_OC3IS_SHIFT) +#define INT_IPC3_OC3IP_SHIFT (18) /* Bits 18-20, Vector: 14, Output Compare 3 */ +#define INT_IPC3_OC3IP_MASK (7 << INT_IPC3_OC3IP_SHIFT) +#define INT_IPC3_INT3IS_SHIFT (24) /* Bits 24-25, Vector: 15, External Interrupt 3 */ +#define INT_IPC3_INT3IS_MASK (3 << INT_IPC3_INT3IS_SHIFT) +#define INT_IPC3_INT3IP_SHIFT (26) /* Bits 26-28, Vector: 15, External Interrupt 3 */ +#define INT_IPC3_INT3IP_MASK (7 << INT_IPC3_INT3IP_SHIFT) + +#define INT_IPC4_T4IS_SHIFT (0) /* Bits 0-1, Vector: 16, Timer 4 */ +#define INT_IPC4_T4IS_MASK (3 << INT_IPC4_T4IS_SHIFT) +#define INT_IPC4_T4IP_SHIFT (2) /* Bits 2-4, Vector: 16, Timer 4 */ +#define INT_IPC4_T4IP_MASK (7 << INT_IPC4_T4IP_SHIFT) +#define INT_IPC4_IC4IS_SHIFT (8) /* Bits 8-9, Vector: 17, Input Capture 4 */ +#define INT_IPC4_IC4IS_MASK (3 << INT_IPC4_IC4IS_SHIFT) +#define INT_IPC4_IC4IP_SHIFT (10) /* Bits 10-12, Vector: 17, Input Capture 4 */ +#define INT_IPC4_IC4IP_MASK (7 << INT_IPC4_IC4IP_SHIFT) +#define INT_IPC4_OC4IS_SHIFT (16) /* Bits 16-17, Vector: 18, Output Compare 4 */ +#define INT_IPC4_OC4IS_MASK (3 << INT_IPC4_OC4IS_SHIFT) +#define INT_IPC4_OC4IP_SHIFT (18) /* Bits 18-20, Vector: 18, Output Compare 4 */ +#define INT_IPC4_OC4IP_MASK (7 << INT_IPC4_OC4IP_SHIFT) +#define INT_IPC4_INT4IS_SHIFT (24) /* Bits 24-25, Vector: 19, External Interrupt 4 */ +#define INT_IPC4_INT4IS_MASK (3 << INT_IPC4_INT4IS_SHIFT) +#define INT_IPC4_INT4IP_SHIFT (26) /* Bits 26-28, Vector: 19, External Interrupt 4 */ +#define INT_IPC4_INT4IP_MASK (7 << INT_IPC4_INT4IP_SHIFT) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define INT_IPC5_T5IS_SHIFT (0) /* Bits 0-1, Vector: 20, Timer 5 */ +# define INT_IPC5_T5IS_MASK (3 << INT_IPC5_T5IS_SHIFT) +# define INT_IPC5_T5IP_SHIFT (2) /* Bits 2-4, Vector: 20, Timer 5 */ +# define INT_IPC5_T5IP_MASK (7 << INT_IPC5_T5IP_SHIFT) +# define INT_IPC5_IC5IS_SHIFT (8) /* Bits 8-9, Vector: 21, Input Capture 5 */ +# define INT_IPC5_IC5IS_MASK (3 << INT_IPC5_IC5IS_SHIFT) +# define INT_IPC5_IC5IP_SHIFT (10) /* Bits 10-12, Vector: 21, Input Capture 5 */ +# define INT_IPC5_IC5IP_MASK (7 << INT_IPC5_IC5IP_SHIFT) +# define INT_IPC5_OC5IS_SHIFT (16) /* Bits 16-17, Vector: 22, Output Compare 5 */ +# define INT_IPC5_OC5IS_MASK (3 << INT_IPC5_OC5IS_SHIFT) +# define INT_IPC5_OC5IP_SHIFT (18) /* Bits 18-20, Vector: 22, Output Compare 5 */ +# define INT_IPC5_OC5IP_MASK (7 << INT_IPC5_OC5IP_SHIFT) +# define INT_IPC5_SPI1IS_SHIFT (24) /* Bits 24-25, Vector: 23, SPI1 */ +# define INT_IPC5_SPI1IS_MASK (3 << INT_IPC5_SPI1IS_SHIFT) +# define INT_IPC5_SPI1IP_SHIFT (26) /* Bits 26-28, Vector: 23, SPI1 */ +# define INT_IPC5_SPI1IP_MASK (7 << INT_IPC5_SPI1IP_SHIFT) +# define INT_IPC6_AD1IS_SHIFT (24) /* Bits 24-25, Vector: 23, ADC1 Convert Done */ +# define INT_IPC6_AD1IS_MASK (3 << INT_IPC6_AD1IS_SHIFT) +# define INT_IPC6_AD1IP_SHIFT (26) /* Bits 26-28, Vector: 23, ADC1 Convert Done */ +# define INT_IPC6_AD1IP_MASK (7 << INT_IPC6_AD1IP_SHIFT) + +#else + +# define INT_IPC5_T5IS_SHIFT (0) /* Bits 0-1, Vector: 20, Timer 5 */ +# define INT_IPC5_T5IS_MASK (3 << INT_IPC5_T5IS_SHIFT) +# define INT_IPC5_T5IP_SHIFT (2) /* Bits 2-4, Vector: 20, Timer 5 */ +# define INT_IPC5_T5IP_MASK (7 << INT_IPC5_T5IP_SHIFT) +# define INT_IPC5_IC5IS_SHIFT (8) /* Bits 8-9, Vector: 21, Input Capture 5 */ +# define INT_IPC5_IC5IS_MASK (3 << INT_IPC5_IC5IS_SHIFT) +# define INT_IPC5_IC5IP_SHIFT (10) /* Bits 10-12, Vector: 21, Input Capture 5 */ +# define INT_IPC5_IC5IP_MASK (7 << INT_IPC5_IC5IP_SHIFT) +# define INT_IPC5_OC5IS_SHIFT (16) /* Bits 16-17, Vector: 22, Output Compare 5 */ +# define INT_IPC5_OC5IS_MASK (3 << INT_IPC5_OC5IS_SHIFT) +# define INT_IPC5_OC5IP_SHIFT (18) /* Bits 18-20, Vector: 22, Output Compare 5 */ +# define INT_IPC5_OC5IP_MASK (7 << INT_IPC5_OC5IP_SHIFT) +# define INT_IPC5_SPI1IS_SHIFT (24) /* Bits 24-25, Vector: 23, SPI1 */ +# define INT_IPC5_SPI1IS_MASK (3 << INT_IPC5_SPI1IS_SHIFT) +# define INT_IPC5_SPI1IP_SHIFT (26) /* Bits 26-28, Vector: 23, SPI1 */ +# define INT_IPC5_SPI1IP_MASK (7 << INT_IPC5_SPI1IP_SHIFT) + +#endif + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define INT_IPC6_FSCMIS_SHIFT (0) /* Bits 0-1, Vector: 24, Fail-Safe Clock Monitor */ +# define INT_IPC6_FSCMIS_MASK (3 << INT_IPC6_FSCMIS_SHIFT) +# define INT_IPC6_FSCMIP_SHIFT (2) /* Bits 2-4, Vector: 24, Fail-Safe Clock Monitor */ +# define INT_IPC6_FSCMIP_MASK (7 << INT_IPC6_FSCMIP_SHIFT) +# define INT_IPC6_RTCCIS_SHIFT (8) /* Bits 8-9, Vector: 25, Real-Time Clock and Calendar */ +# define INT_IPC6_RTCCIS_MASK (3 << INT_IPC6_RTCCIS_SHIFT) +# define INT_IPC6_RTCCIP_SHIFT (10) /* Bits 10-12, Vector: 25, Real-Time Clock and Calendar */ +# define INT_IPC6_RTCCIP_MASK (7 << INT_IPC6_RTCCIP_SHIFT) +# define INT_IPC6_FCEIS_SHIFT (16) /* Bits 16-17, Vector: 26, Flash Control Event */ +# define INT_IPC6_FCEIS_MASK (3 << INT_IPC6_FCEIS_SHIFT) +# define INT_IPC6_FCEIP_SHIFT (18) /* Bits 18-20, Vector: 26, Flash Control Event */ +# define INT_IPC6_FCEIP_MASK (7 << INT_IPC6_FCEIP_SHIFT) +# define INT_IPC6_CMP1IS_SHIFT (24) /* Bits 24-25, Vector: 27, Comparator 1 */ +# define INT_IPC6_CMP1IS_MASK (3 << INT_IPC6_CMP1IS_SHIFT) +# define INT_IPC6_CMP1IP_SHIFT (26) /* Bits 26-28, Vector: 27, Comparator 1 */ +# define INT_IPC6_CMP1IP_MASK (7 << INT_IPC6_CMP1IP_SHIFT) + +# define INT_IPC7_CMP2IS_SHIFT (0) /* Bits 0-1, Vector: 28, Comparator 2 */ +# define INT_IPC7_CMP2IS_MASK (3 << INT_IPC7_CMP2IS_SHIFT) +# define INT_IPC7_CMP2IP_SHIFT (2) /* Bits 2-4, Vector: 28, Comparator 2 */ +# define INT_IPC7_CMP2IP_MASK (7 << INT_IPC7_CMP2IP_SHIFT) +# define INT_IPC7_CMP3IS_SHIFT (8) /* Bits 8-9, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP3IS_MASK (3 << INT_IPC7_CMP3IS_SHIFT) +# define INT_IPC7_CMP3IP_SHIFT (10) /* Bits 10-12, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP3IP_MASK (7 << INT_IPC7_CMP3IP_SHIFT) +# define INT_IPC7_USBIS_SHIFT (16) /* Bits 16-17, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_USBIS_MASK (3 << INT_IPC7_USBIS_SHIFT) +# define INT_IPC7_USBIP_SHIFT (18) /* Bits 18-20, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_USBIP_MASK (7 << INT_IPC7_USBIP_SHIFT) +# define INT_IPC7_SPI1IS_SHIFT (24) /* Bits 24-25, Vector: 31, SPI1 */ +# define INT_IPC7_SPI1IS_MASK (3 << INT_IPC7_SPI1IS_SHIFT) +# define INT_IPC7_SPI1IP_SHIFT (26) /* Bits 26-28, Vector: 31, SPI1 */ +# define INT_IPC7_SPI1IP_MASK (7 << INT_IPC7_SPI1IP_SHIFT) + +# define INT_IPC8_U1IS_SHIFT (0) /* Bits 0-1, Vector: 32, UART1 */ +# define INT_IPC8_U1IS_MASK (3 << INT_IPC8_U1IS_SHIFT) +# define INT_IPC8_U1IP_SHIFT (2) /* Bits 2-4, Vector: 32, UART1 */ +# define INT_IPC8_U1IP_MASK (7 << INT_IPC8_U1IP_SHIFT) +# define INT_IPC8_I2C1IS_SHIFT (8) /* Bits 8-9, Vector: 33, I2C1 */ +# define INT_IPC8_I2C1IS_MASK (3 << INT_IPC8_I2C1IS_SHIFT) +# define INT_IPC8_I2C1IP_SHIFT (10) /* Bits 10-12, Vector: 33, I2C1 */ +# define INT_IPC8_I2C1IP_MASK (7 << INT_IPC8_I2C1IP_SHIFT) +# define INT_IPC8_CNIS_SHIFT (16) /* Bits 16-17, Vector: 34, Input Change */ +# define INT_IPC8_CNIS_MASK (3 << INT_IPC8_CNIS_SHIFT) +# define INT_IPC8_CNIP_SHIFT (18) /* Bits 18-20, Vector: 34, Input Change */ +# define INT_IPC8_CNIP_MASK (7 << INT_IPC8_CNIP_SHIFT) +# define INT_IPC8_PMPIS_SHIFT (24) /* Bits 24-25, Vector: 35, Parallel Master Port */ +# define INT_IPC8_PMPIS_MASK (3 << INT_IPC8_PMPIS_SHIFT) +# define INT_IPC8_PMPIP_SHIFT (26) /* Bits 26-28, Vector: 35, RParallel Master Port */ +# define INT_IPC8_PMPIP_MASK (7 << INT_IPC8_PMPIP_SHIFT) + +# define INT_IPC9_SPI2IS_SHIFT (0) /* Bits 0-1, Vector: 36, SPI2 */ +# define INT_IPC9_SPI2IS_MASK (3 << INT_IPC9_SPI2IS_SHIFT) +# define INT_IPC9_SPI2IP_SHIFT (2) /* Bits 2-4, Vector: 36, SPI2 */ +# define INT_IPC9_SPI2IP_MASK (7 << INT_IPC9_SPI2IP_SHIFT) +# define INT_IPC9_U2IS_SHIFT (8) /* Bits 8-9, Vector: 37, UART2 */ +# define INT_IPC9_U2IS_MASK (3 << INT_IPC9_U2IS_SHIFT) +# define INT_IPC9_U2IP_SHIFT (10) /* Bits 10-12, Vector: 37, UART2 */ +# define INT_IPC9_U2IP_MASK (7 << INT_IPC9_U2IP_SHIFT) +# define INT_IPC9_I2C2IS_SHIFT (16) /* Bits 16-17, Vector: 38, I2C2 */ +# define INT_IPC9_I2C2IS_MASK (3 << INT_IPC9_I2C2IS_SHIFT) +# define INT_IPC9_I2C2IP_SHIFT (18) /* Bits 18-20, Vector: 38, I2C2 */ +# define INT_IPC9_I2C2IP_MASK (7 << INT_IPC9_I2C2IP_SHIFT) +# define INT_IPC9_CTMUIS_SHIFT (24) /* Bits 24-25, Vector: 39, CTMU */ +# define INT_IPC9_CTMUIS_MASK (3 << INT_IPC9_CTMUIS_SHIFT) +# define INT_IPC9_CTMUIP_SHIFT (26) /* Bits 26-28, Vector: 39, CTMU */ +# define INT_IPC9_CTMUIP_MASK (7 << INT_IPC9_CTMUIP_SHIFT) + +# define INT_IPC10_DMA0IS_SHIFT (0) /* Bits 0-1, Vector: 40, DMA Channel 0 */ +# define INT_IPC10_DMA0IS_MASK (3 << INT_IPC10_DMA0IS_SHIFT) +# define INT_IPC10_DMA0IP_SHIFT (2) /* Bits 2-4, Vector: 40, DMA Channel 0 */ +# define INT_IPC10_DMA0IP_MASK (7 << INT_IPC10_DMA0IP_SHIFT) +# define INT_IPC10_DMA1IS_SHIFT (8) /* Bits 8-10, Vector: 41, DMA Channel 1 */ +# define INT_IPC10_DMA1IS_MASK (3 << INT_IPC10_DMA1IS_SHIFT) +# define INT_IPC10_DMA1IP_SHIFT (10) /* Bits 10-12, Vector: 41, DMA Channel 1 */ +# define INT_IPC10_DMA1IP_MASK (7 << INT_IPC10_DMA1IP_SHIFT) +# define INT_IPC10_DMA2IS_SHIFT (16) /* Bits 16-17, Vector: 42, DMA Channel 2 */ +# define INT_IPC10_DMA2IS_MASK (3 << INT_IPC10_DMA2IS_SHIFT) +# define INT_IPC10_DMA2IP_SHIFT (18) /* Bits 18-20, Vector: 42, DMA Channel 2 */ +# define INT_IPC10_DMA2IP_MASK (7 << INT_IPC10_DMA2IP_SHIFT) +# define INT_IPC10_DMA3IS_SHIFT (24) /* Bits 24-25, Vector: 43, DMA Channel 3 */ +# define INT_IPC10_DMA3IS_MASK (3 << INT_IPC10_DMA3IS_SHIFT) +# define INT_IPC10_DMA3IP_SHIFT (26) /* Bits 26-28, Vector: 43, DMA Channel 3 */ +# define INT_IPC10_DMA3IP_MASK (7 << INT_IPC10_DMA3IP_SHIFT) + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +# define INT_IPC6_U1IS_SHIFT (0) /* Bits 0-1, Vector: 24, UART1 */ +# define INT_IPC6_U1IS_MASK (3 << INT_IPC6_U1IS_SHIFT) +# define INT_IPC6_U1IP_SHIFT (2) /* Bits 2-4, Vector: 24, UART1 */ +# define INT_IPC6_U1IP_MASK (7 << INT_IPC6_U1IP_SHIFT) +# define INT_IPC6_I2C1IS_SHIFT (8) /* Bits 8-9, Vector: 25, I2C1 */ +# define INT_IPC6_I2C1IS_MASK (3 << INT_IPC6_I2C1IS_SHIFT) +# define INT_IPC6_I2C1IP_SHIFT (10) /* Bits 10-12, Vector: 25, I2C1 */ +# define INT_IPC6_I2C1IP_MASK (7 << INT_IPC6_I2C1IP_SHIFT) +# define INT_IPC6_CNIS_SHIFT (16) /* Bits 16-17, Vector: 26, Input Change Interrupt */ +# define INT_IPC6_CNIS_MASK (3 << INT_IPC6_CNIS_SHIFT) +# define INT_IPC6_CNIP_SHIFT (18) /* Bits 18-20, Vector: 26, Input Change Interrupt */ +# define INT_IPC6_CNIP_MASK (7 << INT_IPC6_CNIP_SHIFT) +# define INT_IPC6_AD1IS_SHIFT (24) /* Bits 24-25, Vector: 27, ADC1 Convert Done */ +# define INT_IPC6_AD1IS_MASK (3 << INT_IPC6_AD1IS_SHIFT) +# define INT_IPC6_AD1IP_SHIFT (26) /* Bits 26-28, Vector: 27, ADC1 Convert Done */ +# define INT_IPC6_AD1IP_MASK (7 << INT_IPC6_AD1IP_SHIFT) + +# define INT_IPC7_PMPIS_SHIFT (0) /* Bits 0-1, Vector: 28, Parallel Master Port */ +# define INT_IPC7_PMPIS_MASK (3 << INT_IPC7_PMPIS_SHIFT) +# define INT_IPC7_PMPIP_SHIFT (2) /* Bits 2-4, Vector: 28, Parallel Master Port */ +# define INT_IPC7_PMPIP_MASK (7 << INT_IPC7_PMPIP_SHIFT) +# define INT_IPC7_CMP1IS_SHIFT (8) /* Bits 8-9, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP1IS_MASK (3 << INT_IPC7_CMP1IS_SHIFT) +# define INT_IPC7_CMP1IP_SHIFT (10) /* Bits 10-12, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP1IP_MASK (7 << INT_IPC7_CMP1IP_SHIFT) +# define INT_IPC7_CMP2IS_SHIFT (16) /* Bits 16-17, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_CMP2IS_MASK (3 << INT_IPC7_CMP2IS_SHIFT) +# define INT_IPC7_CMP2IP_SHIFT (18) /* Bits 18-20, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_CMP2IP_MASK (7 << INT_IPC7_CMP2IP_SHIFT) +# define INT_IPC7_SPI2IS_SHIFT (24) /* Bits 24-25, Vector: 31, SPI2 */ +# define INT_IPC7_SPI2IS_MASK (3 << INT_IPC7_SPI2IS_SHIFT) +# define INT_IPC7_SPI2IP_SHIFT (26) /* Bits 26-28, Vector: 31, SPI2 */ +# define INT_IPC7_SPI2IP_MASK (7 << INT_IPC7_SPI2IP_SHIFT) + +# define INT_IPC8_U2IS_SHIFT (0) /* Bits 0-1, Vector: 32, UART2 */ +# define INT_IPC8_U2IS_MASK (3 << INT_IPC8_U2IS_SHIFT) +# define INT_IPC8_U2IP_SHIFT (2) /* Bits 2-4, Vector: 32, UART2 */ +# define INT_IPC8_U2IP_MASK (7 << INT_IPC8_U2IP_SHIFT) +# define INT_IPC8_I2C2IS_SHIFT (8) /* Bits 8-9, Vector: 33, I2C2 */ +# define INT_IPC8_I2C2IS_MASK (3 << INT_IPC8_I2C2IS_SHIFT) +# define INT_IPC8_I2C2IP_SHIFT (10) /* Bits 10-12, Vector: 33, I2C2 */ +# define INT_IPC8_I2C2IP_MASK (7 << INT_IPC8_I2C2IP_SHIFT) +# define INT_IPC8_FSCMIS_SHIFT (16) /* Bits 16-17, Vector: 34, Fail-Safe Clock Monitor */ +# define INT_IPC8_FSCMIS_MASK (3 << INT_IPC8_FSCMIS_SHIFT) +# define INT_IPC8_FSCMIP_SHIFT (18) /* Bits 18-20, Vector: 34, Fail-Safe Clock Monitor */ +# define INT_IPC8_FSCMIP_MASK (7 << INT_IPC8_FSCMIP_SHIFT) +# define INT_IPC8_RTCCIS_SHIFT (24) /* Bits 24-25, Vector: 35, Real-Time Clock and Calendar */ +# define INT_IPC8_RTCCIS_MASK (3 << INT_IPC8_RTCCIS_SHIFT) +# define INT_IPC8_RTCCIP_SHIFT (26) /* Bits 26-28, Vector: 35, Real-Time Clock and Calendar */ +# define INT_IPC8_RTCCIP_MASK (7 << INT_IPC8_RTCCIP_SHIFT) + +# define INT_IPC9_DMA0IS_SHIFT (0) /* Bits 0-1, Vector: 36, DMA Channel 0 */ +# define INT_IPC9_DMA0IS_MASK (3 << INT_IPC9_DMA0IS_SHIFT) +# define INT_IPC9_DMA0IP_SHIFT (2) /* Bits 2-4, Vector: 36, DMA Channel 0 */ +# define INT_IPC9_DMA0IP_MASK (7 << INT_IPC9_DMA0IP_SHIFT) +# define INT_IPC9_DMA1IS_SHIFT (8) /* Bits 8-9, Vector: 37, DMA Channel 1 */ +# define INT_IPC9_DMA1IS_MASK (3 << INT_IPC9_DMA1IS_SHIFT) +# define INT_IPC9_DMA1IP_SHIFT (10) /* Bits 10-12, Vector: 37, DMA Channel 1 */ +# define INT_IPC9_DMA1IP_MASK (7 << INT_IPC9_DMA1IP_SHIFT) +# define INT_IPC9_DMA2IS_SHIFT (16) /* Bits 16-17, Vector: 38, DMA Channel 2 */ +# define INT_IPC9_DMA2IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT) +# define INT_IPC9_DMA2IP_SHIFT (18) /* Bits 18-20, Vector: 38, DMA Channel 2 */ +# define INT_IPC9_DMA2IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT) +# define INT_IPC9_DMA3IS_SHIFT (24) /* Bits 24-25, Vector: 39, DMA Channel 3 */ +# define INT_IPC9_DMA3IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT) +# define INT_IPC9_DMA3IP_SHIFT (26) /* Bits 26-28, Vector: 39, DMA Channel 3 */ +# define INT_IPC9_DMA3IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT) + +# define INT_IPC11_FCEIS_SHIFT (0) /* Bits 0-1, Vector: 44, Flash Control Event */ +# define INT_IPC11_FCEIS_MASK (3 << INT_IPC11_FCEIS_SHIFT) +# define INT_IPC11_FCEIP_SHIFT (2) /* Bits 2-4, Vector: 44, Flash Control Event */ +# define INT_IPC11_FCEIP_MASK (7 << INT_IPC11_FCEIP_SHIFT) +# define INT_IPC11_USBIS_SHIFT (8) /* Bits 8-9, Vector: 45, USB */ +# define INT_IPC11_USBIS_MASK (3 << INT_IPC11_USBIS_SHIFT) +# define INT_IPC11_USBIP_SHIFT (10) /* Bits 10-12, Vector: 45, USB */ +# define INT_IPC11_USBIP_MASK (7 << INT_IPC11_USBIP_SHIFT) + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define INT_IPC6_VEC24IS_SHIFT (0) /* Bits 0-1, Vector: 24, UART1, SPI3, I2C3 */ +# define INT_IPC6_VEC24IS_MASK (3 << INT_IPC6_INT26IS_SHIFT) +# define INT_IPC6_U1IS_SHIFT (0) /* Bits 0-1, Vector: 24, UART1 */ +# define INT_IPC6_U1IS_MASK (3 << INT_IPC6_U1IS_SHIFT) +# define INT_IPC6_SPI3IS_SHIFT (0) /* Bits 0-1, Vector: 24, SPI3 */ +# define INT_IPC6_SPI3IS_MASK (3 << INT_IPC6_SPI3IS_SHIFT) +# define INT_IPC6_I2C3IS_SHIFT (0) /* Bits 0-1, Vector: 24, I2C3 */ +# define INT_IPC6_I2C3IS_MASK (3 << INT_IPC6_I2C3IS_SHIFT) +# define INT_IPC6_VEC24IP_SHIFT (0) /* Bits 2-4, Vector: 24, UART1, SPI3, I2C3 */ +# define INT_IPC6_VEC24IP_MASK (7 << INT_IPC6_INT26IP_SHIFT) +# define INT_IPC6_U1IP_SHIFT (2) /* Bits 2-4, Vector: 24, UART1 */ +# define INT_IPC6_U1IP_MASK (7 << INT_IPC6_U1IP_SHIFT) +# define INT_IPC6_SPI3IP_SHIFT (2) /* Bits 2-4, Vector: 24, SPI3 */ +# define INT_IPC6_SPI3IP_MASK (7 << INT_IPC6_SPI3IP_SHIFT) +# define INT_IPC6_I2C3IP_SHIFT (2) /* Bits 2-4, Vector: 24, I2C3 */ +# define INT_IPC6_I2C3IP_MASK (7 << INT_IPC6_I2C3IP_SHIFT) +# define INT_IPC6_I2C1IS_SHIFT (8) /* Bits 8-9, Vector: 25, I2C1 */ +# define INT_IPC6_I2C1IS_MASK (3 << INT_IPC6_I2C1IS_SHIFT) +# define INT_IPC6_I2C1IP_SHIFT (10) /* Bits 10-12, Vector: 25, I2C1 */ +# define INT_IPC6_I2C1IP_MASK (7 << INT_IPC6_I2C1IP_SHIFT) +# define INT_IPC6_CNIS_SHIFT (16) /* Bits 16-17, Vector: 26, Input Change Interrupt */ +# define INT_IPC6_CNIS_MASK (3 << INT_IPC6_CNIS_SHIFT) +# define INT_IPC6_CNIP_SHIFT (18) /* Bits 18-20, Vector: 26, Input Change Interrupt */ +# define INT_IPC6_CNIP_MASK (7 << INT_IPC6_CNIP_SHIFT) +# define INT_IPC6_AD1IS_SHIFT (24) /* Bits 24-25, Vector: 27, ADC1 Convert Done */ +# define INT_IPC6_AD1IS_MASK (3 << INT_IPC6_AD1IS_SHIFT) +# define INT_IPC6_AD1IP_SHIFT (26) /* Bits 26-28, Vector: 27, ADC1 Convert Done */ +# define INT_IPC6_AD1IP_MASK (7 << INT_IPC6_AD1IP_SHIFT) + +# define INT_IPC7_PMPIS_SHIFT (0) /* Bits 0-1, Vector: 28, Parallel Master Port */ +# define INT_IPC7_PMPIS_MASK (3 << INT_IPC7_PMPIS_SHIFT) +# define INT_IPC7_PMPIP_SHIFT (2) /* Bits 2-4, Vector: 28, Parallel Master Port */ +# define INT_IPC7_PMPIP_MASK (7 << INT_IPC7_PMPIP_SHIFT) +# define INT_IPC7_CMP1IS_SHIFT (8) /* Bits 8-9, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP1IS_MASK (3 << INT_IPC7_CMP1IS_SHIFT) +# define INT_IPC7_CMP1IP_SHIFT (10) /* Bits 10-12, Vector: 29, Comparator Interrupt */ +# define INT_IPC7_CMP1IP_MASK (7 << INT_IPC7_CMP1IP_SHIFT) +# define INT_IPC7_CMP2IS_SHIFT (16) /* Bits 16-17, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_CMP2IS_MASK (3 << INT_IPC7_CMP2IS_SHIFT) +# define INT_IPC7_CMP2IP_SHIFT (18) /* Bits 18-20, Vector: 30, Comparator Interrupt */ +# define INT_IPC7_CMP2IP_MASK (7 << INT_IPC7_CMP2IP_SHIFT) +# define INT_IPC6_VEC31IS_SHIFT (24) /* Bits 24-25, Vector: 31, UART3, SPI2, I2C4 */ +# define INT_IPC6_VEC31IS_MASK (3 << INT_IPC6_INT26IS_SHIFT) +# define INT_IPC6_U3IS_SHIFT (24) /* Bits 24-25, Vector: 31, UART3 */ +# define INT_IPC6_U3IS_MASK (3 << INT_IPC6_U1IS_SHIFT) +# define INT_IPC6_SPI2IS_SHIFT (24) /* Bits 24-25, Vector: 31, SPI2 */ +# define INT_IPC6_SPI2IS_MASK (3 << INT_IPC6_SPI3IS_SHIFT) +# define INT_IPC6_I2C4IS_SHIFT (24) /* Bits 24-25, Vector: 31, I2C4 */ +# define INT_IPC6_I2C4IS_MASK (3 << INT_IPC6_I2C3IS_SHIFT) +# define INT_IPC6_VEC31IP_SHIFT (26) /* Bits 26-28, Vector: 31, UART3, SPI2, I2C4 */ +# define INT_IPC6_VEC31IP_MASK (7 << INT_IPC6_INT26IP_SHIFT) +# define INT_IPC6_U3IP_SHIFT (26) /* Bits 26-28, Vector: 31, UART3 */ +# define INT_IPC6_U3IP_MASK (7 << INT_IPC6_U1IP_SHIFT) +# define INT_IPC6_SPI2IP_SHIFT (26) /* Bits 26-28, Vector: 31, SPI2 */ +# define INT_IPC6_SPI2IP_MASK (7 << INT_IPC6_SPI3IP_SHIFT) +# define INT_IPC6_I2C4IP_SHIFT (26) /* Bits 26-28, Vector: 31, I2C4 */ +# define INT_IPC6_I2C4IP_MASK (7 << INT_IPC6_I2C3IP_SHIFT) + +# define INT_IPC6_VEC32IS_SHIFT (0) /* Bits 0-1, Vector: 32, UART2, SPI4, I2C5 */ +# define INT_IPC6_VEC32IS_MASK (3 << INT_IPC6_INT26IS_SHIFT) +# define INT_IPC6_U2IS_SHIFT (0) /* Bits 0-1, Vector: 32, UART2 */ +# define INT_IPC6_U2IS_MASK (3 << INT_IPC6_U1IS_SHIFT) +# define INT_IPC6_SPI4IS_SHIFT (0) /* Bits 0-1, Vector: 32, SPI4 */ +# define INT_IPC6_SPI4IS_MASK (3 << INT_IPC6_SPI3IS_SHIFT) +# define INT_IPC6_I2C5IS_SHIFT (0) /* Bits 0-1, Vector: 32, I2C5 */ +# define INT_IPC6_I2C5IS_MASK (3 << INT_IPC6_I2C3IS_SHIFT) +# define INT_IPC6_VEC32IP_SHIFT (0) /* Bits 2-4, Vector: 32, UART2, SPI4, I2C5 */ +# define INT_IPC6_VEC32IP_MASK (7 << INT_IPC6_INT26IP_SHIFT) +# define INT_IPC6_U2IP_SHIFT (2) /* Bits 2-4, Vector: 32, UART2 */ +# define INT_IPC6_U2IP_MASK (7 << INT_IPC6_U1IP_SHIFT) +# define INT_IPC6_SPI4IP_SHIFT (2) /* Bits 2-4, Vector: 32, SPI4 */ +# define INT_IPC6_SPI4IP_MASK (7 << INT_IPC6_SPI3IP_SHIFT) +# define INT_IPC6_I2C5IP_SHIFT (2) /* Bits 2-4, Vector: 32, I2C5 */ +# define INT_IPC6_I2C5IP_MASK (7 << INT_IPC6_I2C3IP_SHIFT) +# define INT_IPC8_I2C2IS_SHIFT (8) /* Bits 8-9, Vector: 33, I2C2 */ +# define INT_IPC8_I2C2IS_MASK (3 << INT_IPC8_I2C2IS_SHIFT) +# define INT_IPC8_I2C2IP_SHIFT (10) /* Bits 10-12, Vector: 33, I2C2 */ +# define INT_IPC8_I2C2IP_MASK (7 << INT_IPC8_I2C2IP_SHIFT) +# define INT_IPC8_FSCMIS_SHIFT (16) /* Bits 16-17, Vector: 34, Fail-Safe Clock Monitor */ +# define INT_IPC8_FSCMIS_MASK (3 << INT_IPC8_FSCMIS_SHIFT) +# define INT_IPC8_FSCMIP_SHIFT (18) /* Bits 18-20, Vector: 34, Fail-Safe Clock Monitor */ +# define INT_IPC8_FSCMIP_MASK (7 << INT_IPC8_FSCMIP_SHIFT) +# define INT_IPC8_RTCCIS_SHIFT (24) /* Bits 24-25, Vector: 35, Real-Time Clock and Calendar */ +# define INT_IPC8_RTCCIS_MASK (3 << INT_IPC8_RTCCIS_SHIFT) +# define INT_IPC8_RTCCIP_SHIFT (26) /* Bits 26-28, Vector: 35, Real-Time Clock and Calendar */ +# define INT_IPC8_RTCCIP_MASK (7 << INT_IPC8_RTCCIP_SHIFT) + +# define INT_IPC9_DMA0IS_SHIFT (0) /* Bits 0-1, Vector: 36, DMA Channel 0 */ +# define INT_IPC9_DMA0IS_MASK (3 << INT_IPC9_DMA0IS_SHIFT) +# define INT_IPC9_DMA0IP_SHIFT (2) /* Bits 2-4, Vector: 36, DMA Channel 0 */ +# define INT_IPC9_DMA0IP_MASK (7 << INT_IPC9_DMA0IP_SHIFT) +# define INT_IPC9_DMA1IS_SHIFT (8) /* Bits 8-9, Vector: 37, DMA Channel 1 */ +# define INT_IPC9_DMA1IS_MASK (3 << INT_IPC9_DMA1IS_SHIFT) +# define INT_IPC9_DMA1IP_SHIFT (10) /* Bits 10-12, Vector: 37, DMA Channel 1 */ +# define INT_IPC9_DMA1IP_MASK (7 << INT_IPC9_DMA1IP_SHIFT) +# define INT_IPC9_DMA2IS_SHIFT (16) /* Bits 16-17, Vector: 38, DMA Channel 2 */ +# define INT_IPC9_DMA2IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT) +# define INT_IPC9_DMA2IP_SHIFT (18) /* Bits 18-20, Vector: 38, DMA Channel 2 */ +# define INT_IPC9_DMA2IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT) +# define INT_IPC9_DMA3IS_SHIFT (24) /* Bits 24-25, Vector: 39, DMA Channel 3 */ +# define INT_IPC9_DMA3IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT) +# define INT_IPC9_DMA3IP_SHIFT (26) /* Bits 26-28, Vector: 39, DMA Channel 3 */ +# define INT_IPC9_DMA3IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT) + +# define INT_IPC10_DMA4IS_SHIFT (0) /* Bits 0-1, Vector: 40, DMA Channel 4 */ +# define INT_IPC10_DMA4IS_MASK (3 << INT_IPC9_DMA0IS_SHIFT) +# define INT_IPC10_DMA4IP_SHIFT (2) /* Bits 2-4, Vector: 40, DMA Channel 4 */ +# define INT_IPC10_DMA4IP_MASK (7 << INT_IPC9_DMA0IP_SHIFT) +# define INT_IPC10_DMA5IS_SHIFT (8) /* Bits 8-9, Vector: 41, DMA Channel 5 */ +# define INT_IPC10_DMA5IS_MASK (3 << INT_IPC9_DMA1IS_SHIFT) +# define INT_IPC10_DMA5IP_SHIFT (10) /* Bits 10-12, Vector: 41, DMA Channel 5 */ +# define INT_IPC10_DMA5IP_MASK (7 << INT_IPC9_DMA1IP_SHIFT) +# define INT_IPC10_DMA6IS_SHIFT (16) /* Bits 16-17, Vector: 42, DMA Channel 6 */ +# define INT_IPC10_DMA6IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT) +# define INT_IPC10_DMA6IP_SHIFT (18) /* Bits 18-20, Vector: 42, DMA Channel 6 */ +# define INT_IPC10_DMA6IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT) +# define INT_IPC10_DMA7IS_SHIFT (24) /* Bits 24-25, Vector: 43, DMA Channel 7 */ +# define INT_IPC10_DMA7IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT) +# define INT_IPC10_DMA7IP_SHIFT (26) /* Bits 26-28, Vector: 43, DMA Channel 7 */ +# define INT_IPC10_DMA7IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT) + +# define INT_IPC11_FCEIS_SHIFT (0) /* Bits 0-1, Vector: 44, Flash Control Event */ +# define INT_IPC11_FCEIS_MASK (3 << INT_IPC11_FCEIS_SHIFT) +# define INT_IPC11_FCEIP_SHIFT (2) /* Bits 2-4, Vector: 44, Flash Control Event */ +# define INT_IPC11_FCEIP_MASK (7 << INT_IPC11_FCEIP_SHIFT) +# define INT_IPC11_USBIS_SHIFT (8) /* Bits 8-9, Vector: 45, USB */ +# define INT_IPC11_USBIS_MASK (3 << INT_IPC11_USBIS_SHIFT) +# define INT_IPC11_USBIP_SHIFT (10) /* Bits 10-12, Vector: 45, USB */ +# define INT_IPC11_USBIP_MASK (7 << INT_IPC11_USBIP_SHIFT) +# define INT_IPC11_CAN1IS_SHIFT (16) /* Bits 16-17, Vector: 46, Controller area network 1 */ +# define INT_IPC11_CAN1IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT) +# define INT_IPC11_CAN1IP_SHIFT (18) /* Bits 18-20, Vector: 46, Controller area network 1 */ +# define INT_IPC11_CAN1IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT) +# define INT_IPC11_CAN2IS_SHIFT (24) /* Bits 24-25, Vector: 47, Controller area network 2 */ +# define INT_IPC11_CAN2IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT) +# define INT_IPC11_CAN2IP_SHIFT (26) /* Bits 26-28, Vector: 47, Controller area network 2 */ +# define INT_IPC11_CAN2IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT) + +# define INT_IPC12_ETHIS_SHIFT (0) /* Bits 0-1, Vector: 48, Ethernet interrupt */ +# define INT_IPC12_ETHIS_MASK (3 << INT_IPC11_FCEIS_SHIFT) +# define INT_IPC12_ETHIP_SHIFT (2) /* Bits 2-4, Vector: 48, Ethernet interrupt */ +# define INT_IPC12_ETHIP_MASK (7 << INT_IPC11_FCEIP_SHIFT) +# define INT_IPC12_U4IS_SHIFT (8) /* Bits 8-9, Vector: 49, UART4 */ +# define INT_IPC12_U4IS_MASK (3 << INT_IPC11_USBIS_SHIFT) +# define INT_IPC12_U4IP_SHIFT (10) /* Bits 10-12, Vector: 49, UART4 */ +# define INT_IPC12_U4IP_MASK (7 << INT_IPC11_USBIP_SHIFT) +# define INT_IPC12_U6IS_SHIFT (16) /* Bits 16-17, Vector: 50, UART6 */ +# define INT_IPC12_U6IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT) +# define INT_IPC12_U6IP_SHIFT (18) /* Bits 18-20, Vector: 50, UART6 */ +# define INT_IPC12_U6IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT) +# define INT_IPC12_U5IS_SHIFT (24) /* Bits 24-25, Vector: 51, UART5 */ +# define INT_IPC12_U5IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT) +# define INT_IPC12_U5IP_SHIFT (26) /* Bits 26-28, Vector: 51, UART5 */ +# define INT_IPC12_U5IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT) + +#else +# error "Unknown PIC32MX family" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_INT_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-ioport.h b/arch/mips/src/pic32mx/pic32mx-ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..07dc1b88c00901c96ddfe3b4653ab09580a61b3a --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-ioport.h @@ -0,0 +1,481 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-ioport.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IOPORT_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IOPORT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +/* Offsets relative to PIC32MX_IOPORTn_K1BASE */ + +# define PIC32MX_IOPORT_ANSEL_OFFSET 0x0000 /* Analog select register */ +# define PIC32MX_IOPORT_ANSELCLR_OFFSET 0x0004 /* Analog select clear register */ +# define PIC32MX_IOPORT_ANSELSET_OFFSET 0x0008 /* Analog select set register */ +# define PIC32MX_IOPORT_ANSELINV_OFFSET 0x000c /* Analog select invert register */ +# define PIC32MX_IOPORT_TRIS_OFFSET 0x0010 /* Tri-state register */ +# define PIC32MX_IOPORT_TRISCLR_OFFSET 0x0014 /* Tri-state clear register */ +# define PIC32MX_IOPORT_TRISSET_OFFSET 0x0018 /* Tri-state set register */ +# define PIC32MX_IOPORT_TRISINV_OFFSET 0x001c /* Tri-state invert register */ +# define PIC32MX_IOPORT_PORT_OFFSET 0x0020 /* Port register */ +# define PIC32MX_IOPORT_PORTCLR_OFFSET 0x0024 /* Port clear register */ +# define PIC32MX_IOPORT_PORTSET_OFFSET 0x0028 /* Port set register */ +# define PIC32MX_IOPORT_PORTINV_OFFSET 0x002c /* Port invert register */ +# define PIC32MX_IOPORT_LAT_OFFSET 0x0030 /* Port data latch register */ +# define PIC32MX_IOPORT_LATCLR_OFFSET 0x0034 /* Port data latch clear register */ +# define PIC32MX_IOPORT_LATSET_OFFSET 0x0038 /* Port data latch set register */ +# define PIC32MX_IOPORT_LATINV_OFFSET 0x003c /* Port data latch invert register */ +# define PIC32MX_IOPORT_ODC_OFFSET 0x0040 /* Open drain control register */ +# define PIC32MX_IOPORT_ODCCLR_OFFSET 0x0044 /* Open drain control clear register */ +# define PIC32MX_IOPORT_ODCSET_OFFSET 0x0048 /* Open drain control set register */ +# define PIC32MX_IOPORT_ODCINV_OFFSET 0x004c /* Open drain control invert register */ + +# define PIC32MX_IOPORT_CNPU_OFFSET 0x0050 /* Change Notification Pull-up register */ +# define PIC32MX_IOPORT_CNPUCLR_OFFSET 0x0054 /* Change Notification Pull-up clear register */ +# define PIC32MX_IOPORT_CNPUSET_OFFSET 0x0058 /* Change Notification Pull-up set register */ +# define PIC32MX_IOPORT_CNPUINV_OFFSET 0x005c /* Change Notification Pull-up invert register */ +# define PIC32MX_IOPORT_CNPD_OFFSET 0x0060 /* Change Notification Pull-down register */ +# define PIC32MX_IOPORT_CNPDCLR_OFFSET 0x0064 /* Change Notification Pull-down clear register */ +# define PIC32MX_IOPORT_CNPDSET_OFFSET 0x0068 /* Change Notification Pull-down set register */ +# define PIC32MX_IOPORT_CNPDINV_OFFSET 0x006c /* Change Notification Pull-down invert register */ +# define PIC32MX_IOPORT_CNCON_OFFSET 0x0070 /* Change Notification Control register */ +# define PIC32MX_IOPORT_CNCONCLR_OFFSET 0x0074 /* Change Notification Control clear register */ +# define PIC32MX_IOPORT_CNCONSET_OFFSET 0x0078 /* Change Notification Control set register */ +# define PIC32MX_IOPORT_CNCONINV_OFFSET 0x007c /* Change Notification Control invert register */ +# define PIC32MX_IOPORT_CNEN_OFFSET 0x0080 /* Change Notification Interrupt Enable register */ +# define PIC32MX_IOPORT_CNENCLR_OFFSET 0x0084 /* Change Notification Interrupt Enable clear register */ +# define PIC32MX_IOPORT_CNENSET_OFFSET 0x0088 /* Change Notification Interrupt Enable set register */ +# define PIC32MX_IOPORT_CNENINV_OFFSET 0x008c /* Change Notification Interrupt Enable *invert register */ + +#else +/* Offsets relative to PIC32MX_IOPORTn_K1BASE */ + +# define PIC32MX_IOPORT_TRIS_OFFSET 0x0000 /* Tri-state register */ +# define PIC32MX_IOPORT_TRISCLR_OFFSET 0x0004 /* Tri-state clear register */ +# define PIC32MX_IOPORT_TRISSET_OFFSET 0x0008 /* Tri-state set register */ +# define PIC32MX_IOPORT_TRISINV_OFFSET 0x000c /* Tri-state invert register */ +# define PIC32MX_IOPORT_PORT_OFFSET 0x0010 /* Port register */ +# define PIC32MX_IOPORT_PORTCLR_OFFSET 0x0014 /* Port clear register */ +# define PIC32MX_IOPORT_PORTSET_OFFSET 0x0018 /* Port set register */ +# define PIC32MX_IOPORT_PORTINV_OFFSET 0x001c /* Port invert register */ +# define PIC32MX_IOPORT_LAT_OFFSET 0x0020 /* Port data latch register */ +# define PIC32MX_IOPORT_LATCLR_OFFSET 0x0024 /* Port data latch clear register */ +# define PIC32MX_IOPORT_LATSET_OFFSET 0x0028 /* Port data latch set register */ +# define PIC32MX_IOPORT_LATINV_OFFSET 0x002c /* Port data latch invert register */ +# define PIC32MX_IOPORT_ODC_OFFSET 0x0030 /* Open drain control register */ +# define PIC32MX_IOPORT_ODCCLR_OFFSET 0x0034 /* Open drain control clear register */ +# define PIC32MX_IOPORT_ODCSET_OFFSET 0x0038 /* Open drain control set register */ +# define PIC32MX_IOPORT_ODCINV_OFFSET 0x003c /* Open drain control invert register */ + +/* Offsets relative to PIC32MX_IOPORTCN_K1BASE */ + +# define PIC32MX_IOPORT_CNCON_OFFSET 0x0000 /* Interrupt-on-change control register */ +# define PIC32MX_IOPORT_CNCONCLR_OFFSET 0x0004 /* Interrupt-on-change control clear register */ +# define PIC32MX_IOPORT_CNCONSET_OFFSET 0x0008 /* Interrupt-on-change control set register */ +# define PIC32MX_IOPORT_CNCONINV_OFFSET 0x000c /* Interrupt-on-change control invert register */ +# define PIC32MX_IOPORT_CNEN_OFFSET 0x0010 /* Input change notification interrupt enable */ +# define PIC32MX_IOPORT_CNENCLR_OFFSET 0x0014 /* Input change notification interrupt enable clear */ +# define PIC32MX_IOPORT_CNENSET_OFFSET 0x0018 /* Input change notification interrupt enable set */ +# define PIC32MX_IOPORT_CNENINV_OFFSET 0x001c /* Input change notification interrupt enable invert */ +# define PIC32MX_IOPORT_CNPUE_OFFSET 0x0020 /* Input change notification pull-up enable */ +# define PIC32MX_IOPORT_CNPUECLR_OFFSET 0x0024 /* Input change notification pull-up enable clear */ +# define PIC32MX_IOPORT_CNPUESET_OFFSET 0x0028 /* Input change notification pull-up enable set */ +# define PIC32MX_IOPORT_CNPUEINV_OFFSET 0x002c /* Input change notification pull-up enable invert */ +#endif + +/* Register Addresses ***********************************************************************/ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORT_ANSEL(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ANSEL_OFFSET) +# define PIC32MX_IOPORT_ANSELCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ANSELCLR_OFFSET) +# define PIC32MX_IOPORT_ANSELSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ANSELSET_OFFSET) +# define PIC32MX_IOPORT_ANSELINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ANSELINV_OFFSET) +#endif + +#define PIC32MX_IOPORT_TRIS(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORT_TRISCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORT_TRISSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORT_TRISINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORT_PORT(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORT_PORTCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORT_PORTSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORT_PORTINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORT_LAT(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORT_LATCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORT_LATSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORT_LATINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORT_ODC(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORT_ODCCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORT_ODCSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORT_ODCINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_ODCINV_OFFSET) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORT_CNPU(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPU_OFFSET) +# define PIC32MX_IOPORT_CNPUCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPUCLR_OFFSET) +# define PIC32MX_IOPORT_CNPUSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPUSET_OFFSET) +# define PIC32MX_IOPORT_CNPUINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPUINV_OFFSET) +# define PIC32MX_IOPORT_CNPD(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPD_OFFSET) +# define PIC32MX_IOPORT_CNPDCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPDCLR_OFFSET) +# define PIC32MX_IOPORT_CNPDSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPDSET_OFFSET) +# define PIC32MX_IOPORT_CNPDINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNPDINV_OFFSET) +# define PIC32MX_IOPORT_CNCON(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNCON_OFFSET) +# define PIC32MX_IOPORT_CNCONCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNCONCLR_OFFSET) +# define PIC32MX_IOPORT_CNCONSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNCONSET_OFFSET) +# define PIC32MX_IOPORT_CNCONINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNCONINV_OFFSET) +# define PIC32MX_IOPORT_CNEN(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNEN_OFFSET) +# define PIC32MX_IOPORT_CNENCLR(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNENCLR_OFFSET) +# define PIC32MX_IOPORT_CNENSET(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNENSET_OFFSET) +# define PIC32MX_IOPORT_CNENINV(n) (PIC32MX_IOPORT_K1BASE(n)+PIC32MX_IOPORT_CNENINV_OFFSET) +#endif + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTA_ANSEL (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ANSEL_OFFSET) +# define PIC32MX_IOPORTA_ANSELCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ANSELCLR_OFFSET) +# define PIC32MX_IOPORTA_ANSELSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ANSELSET_OFFSET) +# define PIC32MX_IOPORTA_ANSELINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ANSELINV_OFFSET) +#endif + +#define PIC32MX_IOPORTA_TRIS (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTA_TRISCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTA_TRISSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTA_TRISINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTA_PORT (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTA_PORTCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTA_PORTSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTA_PORTINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTA_LAT (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTA_LATCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTA_LATSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTA_LATINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTA_ODC (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTA_ODCCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTA_ODCSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTA_ODCINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTA_CNPU (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPU_OFFSET) +# define PIC32MX_IOPORTA_CNPUCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPUCLR_OFFSET) +# define PIC32MX_IOPORTA_CNPUSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPUSET_OFFSET) +# define PIC32MX_IOPORTA_CNPUINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPUINV_OFFSET) +# define PIC32MX_IOPORTA_CNPD (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPD_OFFSET) +# define PIC32MX_IOPORTA_CNPDCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPDCLR_OFFSET) +# define PIC32MX_IOPORTA_CNPDSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPDSET_OFFSET) +# define PIC32MX_IOPORTA_CNPDINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNPDINV_OFFSET) +# define PIC32MX_IOPORTA_CNCON (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNCON_OFFSET) +# define PIC32MX_IOPORTA_CNCONCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNCONCLR_OFFSET) +# define PIC32MX_IOPORTA_CNCONSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNCONSET_OFFSET) +# define PIC32MX_IOPORTA_CNCONINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNCONINV_OFFSET) +# define PIC32MX_IOPORTA_CNEN (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNEN_OFFSET) +# define PIC32MX_IOPORTA_CNENCLR (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNENCLR_OFFSET) +# define PIC32MX_IOPORTA_CNENSET (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNENSET_OFFSET) +# define PIC32MX_IOPORTA_CNENINV (PIC32MX_IOPORTA_K1BASE+PIC32MX_IOPORT_CNENINV_OFFSET) +#endif + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTB_ANSEL (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ANSEL_OFFSET) +# define PIC32MX_IOPORTB_ANSELCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ANSELCLR_OFFSET) +# define PIC32MX_IOPORTB_ANSELSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ANSELSET_OFFSET) +# define PIC32MX_IOPORTB_ANSELINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ANSELINV_OFFSET) +#endif + +#define PIC32MX_IOPORTB_TRIS (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTB_TRISCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTB_TRISSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTB_TRISINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTB_PORT (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTB_PORTCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTB_PORTSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTB_PORTINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTB_LAT (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTB_LATCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTB_LATSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTB_LATINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTB_ODC (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTB_ODCCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTB_ODCSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTB_ODCINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTB_CNPU (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPU_OFFSET) +# define PIC32MX_IOPORTB_CNPUCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPUCLR_OFFSET) +# define PIC32MX_IOPORTB_CNPUSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPUSET_OFFSET) +# define PIC32MX_IOPORTB_CNPUINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPUINV_OFFSET) +# define PIC32MX_IOPORTB_CNPD (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPD_OFFSET) +# define PIC32MX_IOPORTB_CNPDCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPDCLR_OFFSET) +# define PIC32MX_IOPORTB_CNPDSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPDSET_OFFSET) +# define PIC32MX_IOPORTB_CNPDINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNPDINV_OFFSET) +# define PIC32MX_IOPORTB_CNCON (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNCON_OFFSET) +# define PIC32MX_IOPORTB_CNCONCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNCONCLR_OFFSET) +# define PIC32MX_IOPORTB_CNCONSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNCONSET_OFFSET) +# define PIC32MX_IOPORTB_CNCONINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNCONINV_OFFSET) +# define PIC32MX_IOPORTB_CNEN (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNEN_OFFSET) +# define PIC32MX_IOPORTB_CNENCLR (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNENCLR_OFFSET) +# define PIC32MX_IOPORTB_CNENSET (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNENSET_OFFSET) +# define PIC32MX_IOPORTB_CNENINV (PIC32MX_IOPORTB_K1BASE+PIC32MX_IOPORT_CNENINV_OFFSET) +#endif + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTC_ANSEL (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ANSEL_OFFSET) +# define PIC32MX_IOPORTC_ANSELCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ANSELCLR_OFFSET) +# define PIC32MX_IOPORTC_ANSELSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ANSELSET_OFFSET) +# define PIC32MX_IOPORTC_ANSELINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ANSELINV_OFFSET) +#endif + +#define PIC32MX_IOPORTC_TRIS (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTC_TRISCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTC_TRISSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTC_TRISINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTC_PORT (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTC_PORTCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTC_PORTSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTC_PORTINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTC_LAT (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTC_LATCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTC_LATSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTC_LATINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTC_ODC (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTC_ODCCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTC_ODCSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTC_ODCINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORTC_CNPU (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPU_OFFSET) +# define PIC32MX_IOPORTC_CNPUCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPUCLR_OFFSET) +# define PIC32MX_IOPORTC_CNPUSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPUSET_OFFSET) +# define PIC32MX_IOPORTC_CNPUINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPUINV_OFFSET) +# define PIC32MX_IOPORTC_CNPD (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPD_OFFSET) +# define PIC32MX_IOPORTC_CNPDCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPDCLR_OFFSET) +# define PIC32MX_IOPORTC_CNPDSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPDSET_OFFSET) +# define PIC32MX_IOPORTC_CNPDINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNPDINV_OFFSET) +# define PIC32MX_IOPORTC_CNCON (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNCON_OFFSET) +# define PIC32MX_IOPORTC_CNCONCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNCONCLR_OFFSET) +# define PIC32MX_IOPORTC_CNCONSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNCONSET_OFFSET) +# define PIC32MX_IOPORTC_CNCONINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNCONINV_OFFSET) +# define PIC32MX_IOPORTC_CNEN (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNEN_OFFSET) +# define PIC32MX_IOPORTC_CNENCLR (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNENCLR_OFFSET) +# define PIC32MX_IOPORTC_CNENSET (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNENSET_OFFSET) +# define PIC32MX_IOPORTC_CNENINV (PIC32MX_IOPORTC_K1BASE+PIC32MX_IOPORT_CNENINV_OFFSET) +#endif + +#define PIC32MX_IOPORTD_TRIS (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTD_TRISCLR (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTD_TRISSET (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTD_TRISINV (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTD_PORT (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTD_PORTCLR (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTD_PORTSET (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTD_PORTINV (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTD_LAT (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTD_LATCLR (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTD_LATSET (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTD_LATINV (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTD_ODC (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTD_ODCCLR (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTD_ODCSET (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTD_ODCINV (PIC32MX_IOPORTD_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#define PIC32MX_IOPORTE_TRIS (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTE_TRISCLR (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTE_TRISSET (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTE_TRISINV (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTE_PORT (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTE_PORTCLR (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTE_PORTSET (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTE_PORTINV (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTE_LAT (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTE_LATCLR (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTE_LATSET (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTE_LATINV (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTE_ODC (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTE_ODCCLR (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTE_ODCSET (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTE_ODCINV (PIC32MX_IOPORTE_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#define PIC32MX_IOPORTF_TRIS (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTF_TRISCLR (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTF_TRISSET (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTF_TRISINV (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTF_PORT (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTF_PORTCLR (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTF_PORTSET (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTF_PORTINV (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTF_LAT (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTF_LATCLR (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTF_LATSET (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTF_LATINV (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTF_ODC (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTF_ODCCLR (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTF_ODCSET (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTF_ODCINV (PIC32MX_IOPORTF_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#define PIC32MX_IOPORTG_TRIS (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_TRIS_OFFSET) +#define PIC32MX_IOPORTG_TRISCLR (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_TRISCLR_OFFSET) +#define PIC32MX_IOPORTG_TRISSET (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_TRISSET_OFFSET) +#define PIC32MX_IOPORTG_TRISINV (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_TRISINV_OFFSET) +#define PIC32MX_IOPORTG_PORT (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_PORT_OFFSET) +#define PIC32MX_IOPORTG_PORTCLR (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_PORTCLR_OFFSET) +#define PIC32MX_IOPORTG_PORTSET (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_PORTSET_OFFSET) +#define PIC32MX_IOPORTG_PORTINV (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_PORTINV_OFFSET) +#define PIC32MX_IOPORTG_LAT (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_LAT_OFFSET) +#define PIC32MX_IOPORTG_LATCLR (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_LATCLR_OFFSET) +#define PIC32MX_IOPORTG_LATSET (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_LATSET_OFFSET) +#define PIC32MX_IOPORTG_LATINV (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_LATINV_OFFSET) +#define PIC32MX_IOPORTG_ODC (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_ODC_OFFSET) +#define PIC32MX_IOPORTG_ODCCLR (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_ODCCLR_OFFSET) +#define PIC32MX_IOPORTG_ODCSET (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_ODCSET_OFFSET) +#define PIC32MX_IOPORTG_ODCINV (PIC32MX_IOPORTG_K1BASE+PIC32MX_IOPORT_ODCINV_OFFSET) + +#if !defined(CHIP_PIC32MX1) && !defined(CHIP_PIC32MX2) +# define PIC32MX_IOPORT_CNCON (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNCON_OFFSET) +# define PIC32MX_IOPORT_CNCONCLR (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNCONCLR_OFFSET) +# define PIC32MX_IOPORT_CNCONSET (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNCONSET_OFFSET) +# define PIC32MX_IOPORT_CNCONINV (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNCONINV_OFFSET) +# define PIC32MX_IOPORT_CNEN (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNEN_OFFSET) +# define PIC32MX_IOPORT_CNENCLR (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNENCLR_OFFSET) +# define PIC32MX_IOPORT_CNENSET (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNENSET_OFFSET) +# define PIC32MX_IOPORT_CNENINV (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNENINV_OFFSET) +# define PIC32MX_IOPORT_CNPUE (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNPUE_OFFSET) +# define PIC32MX_IOPORT_CNPUECLR (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNPUECLR_OFFSET) +# define PIC32MX_IOPORT_CNPUESET (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNPUESET_OFFSET) +# define PIC32MX_IOPORT_CNPUEINV (PIC32MX_IOPORTCN_K1BASE+PIC32MX_IOPORT_CNPUEINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Analog select register */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define IOPORT_ANSEL(n) (1 << (n)) /* Bits 0-15: Analog select */ +#endif + +/* Tri-state register */ + +#define IOPORT_TRIS(n) (1 << (n)) /* Bits 0-15: 1: Input 0: Output */ + +/* Port register */ + +#define IOPORT_PORT(n) (1 << (n)) /* Bits 0-15: Pin value */ + +/* Port data latch register */ + +#define IOPORT_LAT(n) (1 << (n)) /* Bits 0-15: Port latch value */ + +/* Open drain control register */ + +#define IOPORT_ODC(n) (1 << (n)) /* Bits 0-15: 1: OD output enabled, 0: Disabled */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +/* Change Notification Pull-up register */ + +# define IOPORT_CNPU(n) (1 << (n)) /* Bits 0:15: 1=Pull-up enabled */ + +/* Change Notification Pull-down register */ + +# define IOPORT_CNPD(n) (1 << (n)) /* Bits 0:15: 1=Pull-down enabled */ + +/* Change Notification Control register */ + +# define IOPORT_CNCON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +# define IOPORT_CNCON_ON (1 << 15) /* Bit 15: Change notice module enable */ + +/* Change Notification Interrupt Enable register */ + +# define IOPORT_CNEN(n) (1 << (n)) /* Bits 0:15: 1=Interrupt enabled */ + +#else + /* Interrupt-on-change control register */ + +# define IOPORT_CNCON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +# define IOPORT_CNCON_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +# define IOPORT_CNCON_ON (1 << 15) /* Bit 15: Change notice module enable */ + + /* Input change notification interrupt enable */ + +# define IOPORT_CNEN(n) (1 << (n)) /* Bits 0-18/21: Port pin input change notice enabled */ + + /* Input change notification pull-up enable */ + +# define IOPORT_CNPUE(n) (1 << (n)) /* Bits 0-18/21: Port pin pull-up enabled */ + +# if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) +# define IOPORT_CN_ALL 0x0007ffff /* Bits 0-18 */ +# define IOPORT_NUMCN 19 +# elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define IOPORT_CN_ALL 0x003fffff /* Bits 0-21 */ +# define IOPORT_NUMCN 22 +# endif +#endif + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_IOPORT_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-irq.c b/arch/mips/src/pic32mx/pic32mx-irq.c new file mode 100644 index 0000000000000000000000000000000000000000..ded512f6e1ddeb00c052dd62b76bf4f206c55361 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-irq.c @@ -0,0 +1,473 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-irq.c + * arch/mips/src/chip/pic32mx-irq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mx-int.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_PIC32MX_MVEC +# error "Multi-vectors not supported" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +static int up_prioritize_irq(int irq, int priority); +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regval; + int irq; + + /* Disable all interrupts */ + + putreg32(0xffff, PIC32MX_INT_IEC0CLR); + putreg32(0xffff, PIC32MX_INT_IEC1CLR); +#ifdef PIC32MX_INT_IEC2CLR + putreg32(0xffff, PIC32MX_INT_IEC2CLR); +#endif + + /* Set all interrupts to the default (middle) priority */ + + for (irq = 0; irq < NR_IRQS; irq++) + { + (void)up_prioritize_irq(irq, (INT_IPC_MID_PRIORITY << 2)); + } + + /* Set the BEV bit in the STATUS register */ + + regval = cp0_getstatus(); + regval |= CP0_STATUS_BEV; + cp0_putstatus(regval); + + /* Set the EBASE value to the beginning of boot FLASH. In single-vector + * mode, interrupt vectors should go to EBASE + 0x0200 0r 0xbfc00200. + */ + + cp0_putebase(0xbfc00000); + + /* Set the INTCTL vector spacing to non-zero */ + + cp0_putintctl(0x00000020); + + /* Set the IV bit in the CAUSE register */ + + regval = cp0_getcause(); + regval |= CP0_CAUSE_IV; + cp0_putcause(regval); + + /* Clear the EXL and BEV bits in the STATUS register */ + + regval = cp0_getstatus(); + regval &= ~(CP0_STATUS_EXL | CP0_STATUS_BEV); + cp0_putstatus(regval); + + /* Configure multi- or single- vector interrupts */ + +#ifdef CONFIG_PIC32MX_MVEC + putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONSET); +#else + putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONCLR); +#endif + + /* Initialize GPIO change notification handling */ + +#ifdef CONFIG_PIC32MX_GPIOIRQ + pic32mx_gpioirqinitialize(); +#endif + + /* Attach and enable software interrupts */ + + irq_attach(PIC32MX_IRQ_CS0, up_swint0); + up_enable_irq(PIC32MX_IRQSRC_CS0); + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* And finally, enable interrupts */ + + /* Interrupts are enabled by setting the IE bit in the CP0 status register */ + + regval = 0; + asm volatile("ei %0" : "=r"(regval)); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Then enable all interrupt levels */ + + up_irq_restore(CP0_STATUS_IM_ALL); +#else + /* Enable only software interrupts */ + + up_irq_restore(CP0_STATUS_IM_SWINTS); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Disable the interrupt by clearing the associated bit in the IEC register */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC_FIRST && irq <= PIC32MX_IRQSRC_LAST); + if (irq >= PIC32MX_IRQSRC_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IEC0 */ + + regaddr = PIC32MX_INT_IEC0CLR; + bitno = irq - PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IEC1 */ + + regaddr = PIC32MX_INT_IEC1CLR; + bitno = irq - PIC32MX_IRQSRC1_FIRST; + } +#ifdef PIC32MX_IRQSRC2_FIRST + else if (irq <= PIC32MX_IRQSRC2_LAST) + { + /* Use IEC2 */ + + regaddr = PIC32MX_INT_IEC2CLR; + bitno = irq - PIC32MX_IRQSRC2_FIRST; + } +#endif + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Enable the interrupt by setting the associated bit in the IEC register */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC_FIRST && irq <= PIC32MX_IRQSRC_LAST); + if (irq >= PIC32MX_IRQSRC_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IEC0 */ + + regaddr = PIC32MX_INT_IEC0SET; + bitno = irq - PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IEC1 */ + + regaddr = PIC32MX_INT_IEC1SET; + bitno = irq - PIC32MX_IRQSRC1_FIRST; + } +#ifdef PIC32MX_IRQSRC2_FIRST + else if (irq <= PIC32MX_IRQSRC2_LAST) + { + /* Use IEC2 */ + + regaddr = PIC32MX_INT_IEC2SET; + bitno = irq - PIC32MX_IRQSRC2_FIRST; + } +#endif + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_pending_irq + * + * Description: + * Return true if the interrupt is pending and unmasked. + * + ****************************************************************************/ + +bool up_pending_irq(int irq) +{ + uint32_t ifsaddr; + uint32_t iecaddr; + uint32_t regval; + int bitno; + + /* Test if the interrupt is pending by reading both the IEC and IFS + * register. Return true if the bit associated with the irq is both pending + * the IFs and enabled in the IEC. + */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC_FIRST && irq <= PIC32MX_IRQSRC_LAST); + if (irq >= PIC32MX_IRQSRC_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IFS0 */ + + ifsaddr = PIC32MX_INT_IFS0; + iecaddr = PIC32MX_INT_IEC0; + bitno = irq - PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IFS1 */ + + ifsaddr = PIC32MX_INT_IFS1; + iecaddr = PIC32MX_INT_IEC1; + bitno = irq - PIC32MX_IRQSRC1_FIRST; + } +#ifdef PIC32MX_IRQSRC2_FIRST + else if (irq <= PIC32MX_IRQSRC2_LAST) + { + /* Use IFS2 */ + + ifsaddr = PIC32MX_INT_IFS2; + iecaddr = PIC32MX_INT_IEC2; + bitno = irq - PIC32MX_IRQSRC2_FIRST; + } +#endif + else + { + /* Value out of range.. just ignore */ + + return false; + } + + /* Get the set of unmasked, pending interrupts. Return true if the + * interrupt is pending and unmask. + */ + + regval = getreg32(ifsaddr) & getreg32(iecaddr); + return (regval & (1 << bitno)) != 0; + } + + return false; +} + +/**************************************************************************** + * Name: up_clrpend_irq + * + * Description: + * Clear any pending interrupt + * + ****************************************************************************/ + +void up_clrpend_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Acknowledge the interrupt by clearing the associated bit in the IFS + * register. It is necessary to do this BEFORE lowering the interrupt + * priority level otherwise recursive interrupts would occur. + */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC_FIRST && irq <= PIC32MX_IRQSRC_LAST); + if (irq >= PIC32MX_IRQSRC_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IFS0 */ + + regaddr = PIC32MX_INT_IFS0CLR; + bitno = irq - PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IFS1 */ + + regaddr = PIC32MX_INT_IFS1CLR; + bitno = irq - PIC32MX_IRQSRC1_FIRST; + } +#ifdef PIC32MX_IRQSRC2_FIRST + else if (irq <= PIC32MX_IRQSRC2_LAST) + { + /* Use IFS2 */ + + regaddr = PIC32MX_INT_IFS2CLR; + bitno = irq - PIC32MX_IRQSRC2_FIRST; + } +#endif + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Acknowledge the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ by setting the priority and sub-priority + * fields in the PIC32MX IPC registers. There are 12 IPC registers, IPC0 + * through IPC11. Each has sub-priority fields for 8 interrupts for a + * total of 96 interrupts max. + * + * Each interrupt priority is represent by a group of 5 bits: a 3-bit + * priority and a 2-bit sub-priority. These have different meanings to + * the hardware. The priority is the priority level that is enabled + * or masked by the IPL field of the CAUSE register. The sub-priority + * only mediates ties when two interrupts with the same priority pend + * simultaneously. + * + * In this function, we just treat this as a single 5-bit priority. + * (MS 3-bits=priority; LS 2-bits=sub-priority). + * + * The 5-bit priority/sub-priority fields are arranged at byte boundaries + * within each IPC register: + * + * xxxP PPSS xxxP PPSS xxxP PPSS xxxP PPSS + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +static +#endif +int up_prioritize_irq(int irq, int priority) +{ + int regndx; + int shift; + + /* Don't allow this function to be used for disabling interrupts. There is + * no good reason for this restriction other than I want to make sure that + * the 5-bit priority values passed to this function are *not* confused with + * the 3-bit hardware priority values. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS && (unsigned)(priority >> 2) > 0); + if (irq < NR_IRQS) + { + /* Get the index to the IPC register and the shift to the 5-bit priority + * field for this IRQ. + */ + + regndx = irq >> 2; /* Range: 0-11 */ + shift = (irq & 3) << 3; /* {0, 8, 16, 24 } */ + + /* Set the new interrupt priority (momentarily disabling interrupts) */ + + putreg32(0x1f << shift, PIC32MX_INT_IPCCLR(regndx)); + putreg32(priority << shift, PIC32MX_INT_IPCSET(regndx)); + return OK; + } + + return -EINVAL; +} diff --git a/arch/mips/src/pic32mx/pic32mx-lowconsole.c b/arch/mips/src/pic32mx/pic32mx-lowconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..5c3f2b4116e818fb19e746dec43176907bddb973 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-lowconsole.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-lowconsole.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mx-config.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART1_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART1_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART1_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART1_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART2_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART2_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART2_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART2_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART3_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART3_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART3_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART3_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART3_2STOP +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART4_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART4_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART4_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART4_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART4_2STOP +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART5_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART5_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART5_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART5_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART5_2STOP +# elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define PIC32MX_CONSOLE_BASE PIC32MX_UART6_K1BASE +# define PIC32MX_CONSOLE_BAUD CONFIG_UART6_BAUD +# define PIC32MX_CONSOLE_BITS CONFIG_UART6_BITS +# define PIC32MX_CONSOLE_PARITY CONFIG_UART6_PARITY +# define PIC32MX_CONSOLE_2STOP CONFIG_UART6_2STOP +# else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_putreg + * + * Description: + * Write a value to a UART register + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline void pic32mx_putreg(uintptr_t uart_base, unsigned int offset, + uint32_t value) +{ + putreg32(value, uart_base + offset); +} +#endif + +/**************************************************************************** + * Name: pic32mx_getreg + * + * Description: + * Get a value from a UART register + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline uint32_t pic32mx_getreg(uintptr_t uart_base, + unsigned int offset) +{ + return getreg32(uart_base + offset); +} +#endif + +/**************************************************************************** + * Name: pic32mx_uartsetbaud + * + * Description: + * Configure the UART baud rate. + * + * With BRGH=0 + * BAUD = PBCLK / 16 / (BRG+1) + * BRG = PBCLK / 16 / BAUD - 1 + * With BRGH=1 + * BAUD = PBCLK / 4 / (BRG+1) + * BRG = PBCLK / 4 / BAUD - 1 + * + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static void pic32mx_uartsetbaud(uintptr_t uart_base, uint32_t baudrate) +{ + uint32_t tmp; + uint32_t brg; + unsigned int mode; + + /* We want the largest value of BRG divisor possible (for the best accuracy). + * Subject to BRG <= 65536. + */ + + tmp = BOARD_PBCLOCK / baudrate; + + /* Try BRGH=1 first. This will select the 4x divisor and will produce the + * larger BRG divisor, given all other things equal. + */ + + brg = (tmp + 2) >> 2; + mode = PIC32MX_UART_MODESET_OFFSET; + + if (brg > 65536) + { + /* Nope, too big.. try BRGH=0 */ + + brg = (tmp + 8) >> 4; + mode = PIC32MX_UART_MODECLR_OFFSET; + } + DEBUGASSERT(brg <= 65536); + + /* Set the BRG divisor */ + + pic32mx_putreg(uart_base, mode, UART_MODE_BRGH); + pic32mx_putreg(uart_base, PIC32MX_UART_BRG_OFFSET, brg); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_uartreset + * + * Description: + * Reset hardware and disable Rx and Tx. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mx_uartreset(uintptr_t uart_base) +{ + /* Doesn't reset the hardware... just shuts it down */ + + pic32mx_putreg(uart_base, PIC32MX_UART_STACLR_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mx_putreg(uart_base, PIC32MX_UART_MODECLR_OFFSET, UART_MODE_ON); +} +#endif + +/**************************************************************************** + * Name: pic32mx_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baudrate, + unsigned int parity, unsigned int nbits, bool stop2) +{ + /* Clear mode and sta bits */ + + pic32mx_putreg(uart_base, PIC32MX_UART_MODECLR_OFFSET, + UART_MODE_STSEL | UART_MODE_PDSEL_MASK | UART_MODE_BRGH | + UART_MODE_RXINV | UART_MODE_WAKE | UART_MODE_LPBACK | + UART_MODE_UEN_MASK | UART_MODE_RTSMD | UART_MODE_IREN | + UART_MODE_SIDL | UART_MODE_ON); + + /* Configure the FIFOs: + * + * RX: Interrupt at 6 of 8 (for 8-deep FIFO) or 3 o 4 (4-deep FIFO) + * TX: Interrupt on FIFO empty + * Invert transmit polarity. + * + * NOTE that there are not many options on trigger TX interrupts. The FIFO not + * full might generate better through-put but with a higher interrupt rate. FIFO + * empty should lower the interrupt rate but result in a burstier output. If + * you change this, please read the comment for acknowledging the interrupt in + * pic32mx-serial.c + */ + +#ifdef UART_STA_URXISEL_RXB6 + pic32mx_putreg(uart_base, PIC32MX_UART_STACLR_OFFSET, + UART_STA_UTXINV | UART_STA_UTXISEL_TXBE | UART_STA_URXISEL_RXB6); +#else + pic32mx_putreg(uart_base, PIC32MX_UART_STACLR_OFFSET, + UART_STA_UTXINV | UART_STA_UTXISEL_TXBE | UART_STA_URXISEL_RXB3); +#endif + + /* Configure the FIFO interrupts */ + + pic32mx_putreg(uart_base, PIC32MX_UART_STASET_OFFSET, + UART_STA_UTXISEL_TXBNF | UART_STA_URXISEL_RECVD); + + /* Configure word size and parity */ + + if (nbits == 9) + { + DEBUGASSERT(parity == 0); + pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET, + UART_MODE_PDSEL_9NONE); + } + else + { + DEBUGASSERT(nbits == 8); + if (parity == 1) + { + pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8ODD); + } + else if (parity == 2) + { + pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8EVEN); + } + } + + /* Configure 1 or 2 stop bits */ + + if (stop2) + { + pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET, + UART_MODE_STSEL); + } + + /* Set the BRG divisor */ + + pic32mx_uartsetbaud(uart_base, baudrate); + + /* Enable the UART */ + + pic32mx_putreg(uart_base, PIC32MX_UART_STASET_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mx_putreg(uart_base, PIC32MX_UART_MODESET_OFFSET, + UART_MODE_ON); +} +#endif + +/**************************************************************************** + * Name: pic32mx_consoleinit + * + * Description: + * Initialize a low-level console for debug output. This function is called + * very early in the initialization sequence to configure the serial console + * UART (only). + * + ****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void pic32mx_consoleinit(void) +{ + pic32mx_uartconfigure(PIC32MX_CONSOLE_BASE, PIC32MX_CONSOLE_BAUD, + PIC32MX_CONSOLE_PARITY, PIC32MX_CONSOLE_BITS, + PIC32MX_CONSOLE_2STOP); +} +#endif + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console. + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait for the transmit buffer not full */ + + while ((pic32mx_getreg(PIC32MX_CONSOLE_BASE, PIC32MX_UART_STA_OFFSET) & UART_STA_UTXBF) != 0); + + /* Then write the character to the TX data register */ + + pic32mx_putreg(PIC32MX_CONSOLE_BASE, PIC32MX_UART_TXREG_OFFSET, (uint32_t)ch); +#endif +} + diff --git a/arch/mips/src/pic32mx/pic32mx-lowinit.c b/arch/mips/src/pic32mx/pic32mx-lowinit.c new file mode 100644 index 0000000000000000000000000000000000000000..544baa36cf592568b327da8126c04760dfc5f777 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-lowinit.c @@ -0,0 +1,215 @@ +/**************************************************************************** + * arch/mips/src/pic32/pic32mx-lowinit.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "pic32mx.h" +#include "pic32mx-bmx.h" +#include "pic32mx-che.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Maximum Frequencies ******************************************************/ + +#define MAX_FLASH_HZ 30000000 /* Maximum FLASH speed (Hz) */ +#define MAX_PBCLOCK 80000000 /* Max peripheral bus speed (Hz) */ + +/* Sanity checks ************************************************************/ + +/* Make sure that the selected clock parameters are sane */ + +#define CALC_SYSCLOCK (((BOARD_PLL_INPUT / BOARD_PLL_IDIV) * BOARD_PLL_MULT) / BOARD_PLL_ODIV) +#if CALC_SYSCLOCK != BOARD_CPU_CLOCK +# error "Bad BOARD_CPU_CLOCK calculcation in board.h" +#endif + +#define CALC_PBCLOCK (CALC_SYSCLOCK / BOARD_PBDIV) +#if CALC_PBCLOCK != BOARD_PBCLOCK +# error "Bad BOARD_PBCLOCK calculcation in board.h" +#endif + +#if CALC_PBCLOCK > MAX_PBCLOCK +# error "PBCLOCK exceeds maximum value" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_waitstates + * + * Description: + * Configure the optimal number of FLASH wait states. + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +static inline void pic32mx_waitstates(void) +{ +#ifdef CHIP_CHE + unsigned int nwaits; + unsigned int residual; +#endif + + /* Disable DRM wait states */ + + putreg32(BMX_CON_BMXWSDRM, PIC32MX_BMX_CONCLR); + +#ifdef CHIP_CHE + /* Configure pre-fetch cache FLASH wait states */ + + residual = BOARD_CPU_CLOCK; + nwaits = 0; + + while (residual > MAX_FLASH_HZ) + { + nwaits++; + residual -= MAX_FLASH_HZ; + } + + DEBUGASSERT(nwaits < 8); + + /* Set the FLASH wait states -- clearing all other bits! */ + + putreg32(nwaits, PIC32MX_CHE_CON); +#endif +} + +/**************************************************************************** + * Name: pic32mx_cache + * + * Description: + * Enable caching. + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +static inline void pic32mx_cache(void) +{ + register uint32_t regval; + + /* Enable prefetch on all regions */ + +#ifdef CHIP_CHE + regval = getreg32(PIC32MX_CHE_CON); + regval |= CHE_CON_PREFEN_ALL; + putreg32(regval, PIC32MX_CHE_CON); +#endif + + /* Enable cache on KSEG 0 in the CP0 CONFIG register */ + + asm("\tmfc0 %0,$16,0\n" : "=r"(regval)); + regval &= ~CP0_CONFIG_K23_MASK; + regval |= CP0_CONFIG_K23_CACHEABLE; + asm("\tmtc0 %0,$16,0\n" : : "r" (regval)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_lowinit + * + * Description: + * This performs basic low-level initialization of the system. + * + * Assumptions: + * Interrupts have not yet been enabled. + * + ****************************************************************************/ + +void pic32mx_lowinit(void) +{ + /* Initialize FLASH wait states */ + + pic32mx_waitstates(); + + /* Enable caching */ + + pic32mx_cache(); + + /* Initialize a console (probably a serial console) */ + + pic32mx_consoleinit(); + + /* Perform early serial initialization (so that we will have debug output + * available as soon as possible). + */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-level initialization */ + + pic32mx_boardinitialize(); +} + + diff --git a/arch/mips/src/pic32mx/pic32mx-memorymap.h b/arch/mips/src/pic32mx/pic32mx-memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..5b5ce8020b64502f624f2d771fa69928d0867832 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-memorymap.h @@ -0,0 +1,535 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-memorymap.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + **** + // *********************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_MEMORYMAP_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "mips32-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Physical Memory Map **************************************************************/ + +/* This top-level memory map is valid for the PIC32MX1xx/2xx families. */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define PIC32MX_DATAMEM_PBASE 0x00000000 /* Size depends on CHIP_DATAMEM_KB */ +# define PIC32MX_PROGFLASH_PBASE 0x1d000000 /* Size depends on CHIP_PROGFLASH_KB */ +# define PIC32MX_SFR_PBASE 0x1f800000 /* Special function registers */ +# define PIC32MX_BOOTFLASH_PBASE 0x1fc00000 /* Size depends on CHIP_BOOTFLASH_KB */ +# define PIC32MX_DEVCFG_PBASE 0x1fc00bf0 /* Device configuration registers */ + +/* This top-level memory map is valid for the PIC32MX3xx/4xx as well as the + * PIC32MX5xx/6xx/7xx families. + */ + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +# define PIC32MX_DATAMEM_PBASE 0x00000000 /* Size depends on CHIP_DATAMEM_KB */ +# define PIC32MX_PROGFLASH_PBASE 0x1d000000 /* Size depends on CHIP_PROGFLASH_KB */ +# define PIC32MX_SFR_PBASE 0x1f800000 /* Special function registers */ +# define PIC32MX_BOOTFLASH_PBASE 0x1fc00000 /* Size depends on CHIP_BOOTFLASH_KB */ +# define PIC32MX_DEVCFG_PBASE 0x1fc02ff0 /* Device configuration registers */ + +#else +# error "Memory map unknown for this PIC32 chip" +#endif + +/* Virtual Memory Map ***************************************************************/ + +#define PIC32MX_DATAMEM_K0BASE (KSEG0_BASE + PIC32MX_DATAMEM_PBASE) +#define PIC32MX_PROGFLASH_K0BASE (KSEG0_BASE + PIC32MX_PROGFLASH_PBASE) +#define PIC32MX_BOOTFLASH_K0BASE (KSEG0_BASE + PIC32MX_BOOTFLASH_PBASE) +#define PIC32MX_DEVCFG_K0BASE (KSEG0_BASE + PIC32MX_DEVCFG_PBASE) + +#define PIC32MX_DATAMEM_K1BASE (KSEG1_BASE + PIC32MX_DATAMEM_PBASE) +#define PIC32MX_PROGFLASH_K1BASE (KSEG1_BASE + PIC32MX_PROGFLASH_PBASE) +#define PIC32MX_SFR_K1BASE (KSEG1_BASE + PIC32MX_SFR_PBASE) +#define PIC32MX_BOOTFLASH_K1BASE (KSEG1_BASE + PIC32MX_BOOTFLASH_PBASE) +#define PIC32MX_DEVCFG_K1BASE (KSEG1_BASE + PIC32MX_DEVCFG_PBASE) + +/* Register Base Addresses **********************************************************/ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +/* Watchdog Register Base Address */ + +# define PIC32MX_WDT_K1BASE (PIC32MX_SFR_K1BASE + 0x00000000) + +/* RTCC Register Base Address */ + +# define PIC32MX_RTCC_K1BASE (PIC32MX_SFR_K1BASE + 0x00000200) + +/* Timer 1-5 Register Base Addresses */ + +# define PIC32MX_TIMER_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00000600 + 0x200*(n-1)) +# define PIC32MX_TIMER1_K1BASE (PIC32MX_SFR_K1BASE + 0x00000600) +# define PIC32MX_TIMER2_K1BASE (PIC32MX_SFR_K1BASE + 0x00000800) +# define PIC32MX_TIMER3_K1BASE (PIC32MX_SFR_K1BASE + 0x00000a00) +# define PIC32MX_TIMER4_K1BASE (PIC32MX_SFR_K1BASE + 0x00000c00) +# define PIC32MX_TIMER5_K1BASE (PIC32MX_SFR_K1BASE + 0x00000e00) + +/* Input Capture 1-5 Register Base Addresses */ + +# define PIC32MX_IC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00002000 + 0x200*(n-1)) +# define PIC32MX_IC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00002000) +# define PIC32MX_IC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00002200) +# define PIC32MX_IC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00002400) +# define PIC32MX_IC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00002600) +# define PIC32MX_IC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00002800) + +/* Output Compare 1-5 Register Base Addresses */ + +# define PIC32MX_OC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00003000 + 0x200*(n-1)) +# define PIC32MX_OC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00003000) +# define PIC32MX_OC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00003200) +# define PIC32MX_OC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00003400) +# define PIC32MX_OC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00003600) +# define PIC32MX_OC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00003800) + +/* I2C 1-2 Register Base Addresses */ + +# define PIC32MX_I2C1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005000) +# define PIC32MX_I2C2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005100) + +/* SPI 1-2 Register Base Addresses */ + +# define PIC32MX_SPI1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005800) +# define PIC32MX_SPI2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005a00) + +/* UART 1-2 Register Base Addresses */ + +# define PIC32MX_UART1_K1BASE (PIC32MX_SFR_K1BASE + 0x00006000) +# define PIC32MX_UART2_K1BASE (PIC32MX_SFR_K1BASE + 0x00006200) + +/* Parallel Master Register Base Address */ + +# define PIC32MX_PMP_K1BASE (PIC32MX_SFR_K1BASE + 0x00007000) + +/* ADC Register Base Addresses */ + +# define PIC32MX_ADC_K1BASE (PIC32MX_SFR_K1BASE + 0x00009000) + +/* Comparator Voltage Reference Register Base Addresses */ + +# define PIC32MX_CVR_K1BASE (PIC32MX_SFR_K1BASE + 0x00009800) + +/* Comparator Register Base Addresses */ + +# define PIC32MX_CM_K1BASE (PIC32MX_SFR_K1BASE + 0x0000a000) + +/* CTMU Register Base Addresses */ + +# define PIC32MX_CTMU_K1BASE (PIC32MX_SFR_K1BASE + 0x0000a200) + +/* Oscillator Control Register Base Addresses */ + +# define PIC32MX_OSC_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f000) + +/* Configuration Control Register Base Addresses */ + +# define PIC32MX_CFG_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f200) + +/* FLASH Controller Register Base Addresses */ + +# define PIC32MX_FLASH_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f400) + +/* Reset Control Register Base Address */ + +# define PIC32MX_RESET_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f600) + +/* Peripheral Pin Select Input/Ouput Register Base Address */ + +# define PIC32MX_INSEL_K1BASE (PIC32MX_SFR_K1BASE + 0x0000fa00) +# define PIC32MX_OUTSEL_K1BASE (PIC32MX_SFR_K1BASE + 0x0000fb00) + +/* Interrupt Register Base Address */ + +# define PIC32MX_INT_K1BASE (PIC32MX_SFR_K1BASE + 0x00081000) + +/* Bus Matrix Register Base Address */ + +# define PIC32MX_BMX_K1BASE (PIC32MX_SFR_K1BASE + 0x00082000) + +/* DMA Register Base Address */ + +# define PIC32MX_DMA_K1BASE (PIC32MX_SFR_K1BASE + 0x00083000) +# define PIC32MX_DMACH_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00083060 + 0xc0*(n)) +# define PIC32MX_DMACH0_K1BASE (PIC32MX_SFR_K1BASE + 0x00083060) +# define PIC32MX_DMACH1_K1BASE (PIC32MX_SFR_K1BASE + 0x00083120) +# define PIC32MX_DMACH2_K1BASE (PIC32MX_SFR_K1BASE + 0x000831e0) +# define PIC32MX_DMACH3_K1BASE (PIC32MX_SFR_K1BASE + 0x000832a0) + +/* USBOTG Register Base Addresses */ + +# define PIC32MX_USB_K1BASE (PIC32MX_SFR_K1BASE + 0x00085000) + +/* Port Register Base Addresses */ + +# define PIC32MX_IOPORTA 0 +# define PIC32MX_IOPORTB 1 +# define PIC32MX_IOPORTC 2 + +# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x100*(n)) + +# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) +# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) +# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086200) + +#elif defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) + +/* Watchdog Register Base Address */ + +# define PIC32MX_WDT_K1BASE (PIC32MX_SFR_K1BASE + 0x00000000) + +/* RTCC Register Base Address */ + +# define PIC32MX_RTCC_K1BASE (PIC32MX_SFR_K1BASE + 0x00000200) + +/* Timer 1-5 Register Base Addresses */ + +# define PIC32MX_TIMER_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00000600 + 0x200*(n-1)) +# define PIC32MX_TIMER1_K1BASE (PIC32MX_SFR_K1BASE + 0x00000600) +# define PIC32MX_TIMER2_K1BASE (PIC32MX_SFR_K1BASE + 0x00000800) +# define PIC32MX_TIMER3_K1BASE (PIC32MX_SFR_K1BASE + 0x00000a00) +# define PIC32MX_TIMER4_K1BASE (PIC32MX_SFR_K1BASE + 0x00000c00) +# define PIC32MX_TIMER5_K1BASE (PIC32MX_SFR_K1BASE + 0x00000e00) + +/* Input Capture 1-5 Register Base Addresses */ + +# define PIC32MX_IC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00002000 + 0x200*(n-1)) +# define PIC32MX_IC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00002000) +# define PIC32MX_IC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00002200) +# define PIC32MX_IC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00002400) +# define PIC32MX_IC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00002600) +# define PIC32MX_IC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00002800) + +/* Output Compare 1-5 Register Base Addresses */ + +# define PIC32MX_OC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00003000 + 0x200*(n-1)) +# define PIC32MX_OC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00003000) +# define PIC32MX_OC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00003200) +# define PIC32MX_OC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00003400) +# define PIC32MX_OC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00003600) +# define PIC32MX_OC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00003800) + +/* I2C 1-2 Register Base Addresses */ + +# define PIC32MX_I2C1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005000) +# define PIC32MX_I2C2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005200) + +/* SPI 1-2 Register Base Addresses */ + +# define PIC32MX_SPI1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005800) +# define PIC32MX_SPI2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005a00) + +/* UART 1-2 Register Base Addresses */ + +# define PIC32MX_UART1_K1BASE (PIC32MX_SFR_K1BASE + 0x00006000) +# define PIC32MX_UART2_K1BASE (PIC32MX_SFR_K1BASE + 0x00006200) + +/* Parallel Master Register Base Address */ + +# define PIC32MX_PMP_K1BASE (PIC32MX_SFR_K1BASE + 0x00007000) + +/* ADC Register Base Addresses */ + +# define PIC32MX_ADC_K1BASE (PIC32MX_SFR_K1BASE + 0x00009000) + +/* Comparator Voltage Reference Register Base Addresses */ + +# define PIC32MX_CVR_K1BASE (PIC32MX_SFR_K1BASE + 0x00009800) + +/* Comparator Register Base Addresses */ + +# define PIC32MX_CM_K1BASE (PIC32MX_SFR_K1BASE + 0x0000a000) + +/* Oscillator Control Register Base Addresses */ + +# define PIC32MX_OSC_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f000) + +/* Programming and Diagnostics Register Base Addresses */ + +# define PIC32MX_DDP_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f200) + +/* FLASH Controller Register Base Addresses */ + +# define PIC32MX_FLASH_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f400) + +/* Reset Control Register Base Address */ + +# define PIC32MX_RESET_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f600) + +/* Interrupt Register Base Address */ + +# define PIC32MX_INT_K1BASE (PIC32MX_SFR_K1BASE + 0x00081000) + +/* Bus Matrix Register Base Address */ + +# define PIC32MX_BMX_K1BASE (PIC32MX_SFR_K1BASE + 0x00082000) + +/* DMA Register Base Address */ + +# define PIC32MX_DMA_K1BASE (PIC32MX_SFR_K1BASE + 0x00083000) +# define PIC32MX_DMACH_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00083060 + 0xc0*(n)) +# define PIC32MX_DMACH0_K1BASE (PIC32MX_SFR_K1BASE + 0x00083060) +# define PIC32MX_DMACH1_K1BASE (PIC32MX_SFR_K1BASE + 0x00083120) +# define PIC32MX_DMACH2_K1BASE (PIC32MX_SFR_K1BASE + 0x000831e0) +# define PIC32MX_DMACH3_K1BASE (PIC32MX_SFR_K1BASE + 0x000832a0) + +/* Prefetch Cache Register Base Address */ + +# define PIC32MX_CHE_K1BASE (PIC32MX_SFR_K1BASE + 0x00084000) + +/* USBOTG Register Base Addresses */ + +# define PIC32MX_USB_K1BASE (PIC32MX_SFR_K1BASE + 0x00085000) + +/* Port Register Base Addresses */ + +# define PIC32MX_IOPORTA 0 +# define PIC32MX_IOPORTB 1 +# define PIC32MX_IOPORTC 2 +# define PIC32MX_IOPORTD 3 +# define PIC32MX_IOPORTE 4 +# define PIC32MX_IOPORTF 5 +# define PIC32MX_IOPORTG 6 +# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) + +# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) +# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) +# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) +# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) +# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) +# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) +# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) + +# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) + +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) + +/* Watchdog Register Base Address */ + +# define PIC32MX_WDT_K1BASE (PIC32MX_SFR_K1BASE + 0x00000000) + +/* RTCC Register Base Address */ + +# define PIC32MX_RTCC_K1BASE (PIC32MX_SFR_K1BASE + 0x00000200) + +/* Timer 1-5 Register Base Addresses */ + +# define PIC32MX_TIMER_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00000600 + 0x200*(n-1)) +# define PIC32MX_TIMER1_K1BASE (PIC32MX_SFR_K1BASE + 0x00000600) +# define PIC32MX_TIMER2_K1BASE (PIC32MX_SFR_K1BASE + 0x00000800) +# define PIC32MX_TIMER3_K1BASE (PIC32MX_SFR_K1BASE + 0x00000a00) +# define PIC32MX_TIMER4_K1BASE (PIC32MX_SFR_K1BASE + 0x00000c00) +# define PIC32MX_TIMER5_K1BASE (PIC32MX_SFR_K1BASE + 0x00000e00) + +/* Input Capture 1-5 Register Base Addresses */ + +# define PIC32MX_IC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00002000 + 0x200*(n-1)) +# define PIC32MX_IC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00002000) +# define PIC32MX_IC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00002200) +# define PIC32MX_IC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00002400) +# define PIC32MX_IC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00002600) +# define PIC32MX_IC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00002800) + +/* Output Compare 1-5 Register Base Addresses */ + +# define PIC32MX_OC_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00003000 + 0x200*(n-1)) +# define PIC32MX_OC1_K1BASE (PIC32MX_SFR_K1BASE + 0x00003000) +# define PIC32MX_OC2_K1BASE (PIC32MX_SFR_K1BASE + 0x00003200) +# define PIC32MX_OC3_K1BASE (PIC32MX_SFR_K1BASE + 0x00003400) +# define PIC32MX_OC4_K1BASE (PIC32MX_SFR_K1BASE + 0x00003600) +# define PIC32MX_OC5_K1BASE (PIC32MX_SFR_K1BASE + 0x00003800) + +/* I2C 1-5 Register Base Addresses */ + +# define PIC32MX_I2C3_K1BASE (PIC32MX_SFR_K1BASE + 0x00005000) +# define PIC32MX_I2C4_K1BASE (PIC32MX_SFR_K1BASE + 0x00005100) +# define PIC32MX_I2C5_K1BASE (PIC32MX_SFR_K1BASE + 0x00005200) +# define PIC32MX_I2C1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005300) +# define PIC32MX_I2C2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005400) + +/* SPI 1-2 Register Base Addresses */ + +# define PIC32MX_SPI3_K1BASE (PIC32MX_SFR_K1BASE + 0x00005800) +# define PIC32MX_SPI2_K1BASE (PIC32MX_SFR_K1BASE + 0x00005a00) +# define PIC32MX_SPI4_K1BASE (PIC32MX_SFR_K1BASE + 0x00005c00) +# define PIC32MX_SPI1_K1BASE (PIC32MX_SFR_K1BASE + 0x00005e00) + +/* UART 1-6 Register Base Addresses */ + +# define PIC32MX_UART1_K1BASE (PIC32MX_SFR_K1BASE + 0x00006000) +# define PIC32MX_UART4_K1BASE (PIC32MX_SFR_K1BASE + 0x00006200) +# define PIC32MX_UART3_K1BASE (PIC32MX_SFR_K1BASE + 0x00006400) +# define PIC32MX_UART6_K1BASE (PIC32MX_SFR_K1BASE + 0x00006600) +# define PIC32MX_UART2_K1BASE (PIC32MX_SFR_K1BASE + 0x00006800) +# define PIC32MX_UART5_K1BASE (PIC32MX_SFR_K1BASE + 0x00006a00) + +/* Parallel Master Register Base Address */ + +# define PIC32MX_PMP_K1BASE (PIC32MX_SFR_K1BASE + 0x00007000) + +/* ADC Register Base Addresses */ + +# define PIC32MX_ADC_K1BASE (PIC32MX_SFR_K1BASE + 0x00009000) + +/* Comparator Voltage Reference Register Base Addresses */ + +# define PIC32MX_CVR_K1BASE (PIC32MX_SFR_K1BASE + 0x00009800) + +/* Comparator Register Base Addresses */ + +# define PIC32MX_CM_K1BASE (PIC32MX_SFR_K1BASE + 0x0000a000) + +/* Oscillator Control Register Base Addresses */ + +# define PIC32MX_OSC_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f000) + +/* Programming and Diagnostics Register Base Addresses */ + +# define PIC32MX_DDP_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f200) + +/* FLASH Controller Register Base Addresses */ + +# define PIC32MX_FLASH_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f400) + +/* Reset Control Register Base Address */ + +# define PIC32MX_RESET_K1BASE (PIC32MX_SFR_K1BASE + 0x0000f600) + +/* Interrupt Register Base Address */ + +# define PIC32MX_INT_K1BASE (PIC32MX_SFR_K1BASE + 0x00081000) + +/* Bus Matrix Register Base Address */ + +# define PIC32MX_BMX_K1BASE (PIC32MX_SFR_K1BASE + 0x00082000) + +/* DMA Register Base Address */ + +# define PIC32MX_DMA_K1BASE (PIC32MX_SFR_K1BASE + 0x00083000) +# define PIC32MX_DMACH_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00083060 + 0xc0*(n)) +# define PIC32MX_DMACH0_K1BASE (PIC32MX_SFR_K1BASE + 0x00083060) +# define PIC32MX_DMACH1_K1BASE (PIC32MX_SFR_K1BASE + 0x00083120) +# define PIC32MX_DMACH2_K1BASE (PIC32MX_SFR_K1BASE + 0x000831e0) +# define PIC32MX_DMACH3_K1BASE (PIC32MX_SFR_K1BASE + 0x000832a0) +# define PIC32MX_DMACH4_K1BASE (PIC32MX_SFR_K1BASE + 0x00083360) +# define PIC32MX_DMACH5_K1BASE (PIC32MX_SFR_K1BASE + 0x00083420) +# define PIC32MX_DMACH6_K1BASE (PIC32MX_SFR_K1BASE + 0x000834e0) +# define PIC32MX_DMACH7_K1BASE (PIC32MX_SFR_K1BASE + 0x000835a0) + +/* Prefetch Cache Register Base Address */ + +# define PIC32MX_CHE_K1BASE (PIC32MX_SFR_K1BASE + 0x00084000) + +/* USBOTG Register Base Addresses */ + +# define PIC32MX_USB_K1BASE (PIC32MX_SFR_K1BASE + 0x00085000) + +/* Port Register Base Addresses */ + +# define PIC32MX_IOPORTA 0 +# define PIC32MX_IOPORTB 1 +# define PIC32MX_IOPORTC 2 +# define PIC32MX_IOPORTD 3 +# define PIC32MX_IOPORTE 4 +# define PIC32MX_IOPORTF 5 +# define PIC32MX_IOPORTG 6 +# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) + +# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) +# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) +# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) +# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) +# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) +# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) +# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) + +# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) + +/* Ethernet Controller Register Base Addresses */ + +# define PIC32MX_ETHERNET_K1BASE (PIC32MX_SFR_K1BASE + 0x00089000) + +/* CAN1/2 Register Base Addresses */ + +# define PIC32MX_CAN1_K1BASE (PIC32MX_SFR_K1BASE + 0x0008b000) +# define PIC32MX_CAN2_K1BASE (PIC32MX_SFR_K1BASE + 0x0008c000) + +#else +# error "Memory map unknown for this PIC32 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_MEMORYMAP_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-oc.h b/arch/mips/src/pic32mx/pic32mx-oc.h new file mode 100644 index 0000000000000000000000000000000000000000..3e77f9630f260299cfa14ef978a5accb88df403d --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-oc.h @@ -0,0 +1,212 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-oc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OC_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +#if CHIP_NOC > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_OC_CON_OFFSET 0x0000 /* Output compare control register */ +#define PIC32MX_OC_CONCLR_OFFSET 0x0004 /* Output compare control clear register */ +#define PIC32MX_OC_CONSET_OFFSET 0x0008 /* Output compare control set register */ +#define PIC32MX_OC_CONINV_OFFSET 0x000c /* Output compare control invert register */ +#define PIC32MX_OC_R_OFFSET 0x0010 /* Output compare data register */ +#define PIC32MX_OC_RCLR_OFFSET 0x0014 /* Output compare data clear register */ +#define PIC32MX_OC_RSET_OFFSET 0x0018 /* Output compare data set register */ +#define PIC32MX_OC_RINV_OFFSET 0x001c /* Output compare data invert register */ +#define PIC32MX_OC_RS_OFFSET 0x0020 /* Output compare secondary data register */ +#define PIC32MX_OC_RSCLR_OFFSET 0x0024 /* Output compare secondary data clear register */ +#define PIC32MX_OC_RSSET_OFFSET 0x0028 /* Output compare secondary data set register */ +#define PIC32MX_OC_RSINV_OFFSET 0x002c /* Output compare secondary data invert register */ + +/* See also TIMER2 and TIMER3 registers */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_OC_CON(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_CON_OFFSET) +#define PIC32MX_OC_CONCLR(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_CONCLR_OFFSET) +#define PIC32MX_OC_CONSET(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_CONSET_OFFSET) +#define PIC32MX_OC_CONINV(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_CONINV_OFFSET) +#define PIC32MX_OC_R(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_R_OFFSET) +#define PIC32MX_OC_RCLR(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RCLR_OFFSET) +#define PIC32MX_OC_RSET(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RSET_OFFSET) +#define PIC32MX_OC_RINV(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RINV_OFFSET) +#define PIC32MX_OC_RS(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RS_OFFSET) +#define PIC32MX_OC_RSCLR(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RSCLR_OFFSET) +#define PIC32MX_OC_RSSET(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RSSET_OFFSET) +#define PIC32MX_OC_RSINV(n) (PIC32MX_OC_K1BASE(n)+PIC32MX_OC_RSINV_OFFSET) + +#define PIC32MX_OC1_CON (PIC32MX_OC1_K1BASE+PIC32MX_OC_CON_OFFSET) +#define PIC32MX_OC1_CONCLR (PIC32MX_OC1_K1BASE+PIC32MX_OC_CONCLR_OFFSET) +#define PIC32MX_OC1_CONSET (PIC32MX_OC1_K1BASE+PIC32MX_OC_CONSET_OFFSET) +#define PIC32MX_OC1_CONINV (PIC32MX_OC1_K1BASE+PIC32MX_OC_CONINV_OFFSET) +#define PIC32MX_OC1_R (PIC32MX_OC1_K1BASE+PIC32MX_OC_R_OFFSET) +#define PIC32MX_OC1_RCLR (PIC32MX_OC1_K1BASE+PIC32MX_OC_RCLR_OFFSET) +#define PIC32MX_OC1_RSET (PIC32MX_OC1_K1BASE+PIC32MX_OC_RSET_OFFSET) +#define PIC32MX_OC1_RINV (PIC32MX_OC1_K1BASE+PIC32MX_OC_RINV_OFFSET) +#define PIC32MX_OC1_RS (PIC32MX_OC1_K1BASE+PIC32MX_OC_RS_OFFSET) +#define PIC32MX_OC1_RSCLR (PIC32MX_OC1_K1BASE+PIC32MX_OC_RSCLR_OFFSET) +#define PIC32MX_OC1_RSSET (PIC32MX_OC1_K1BASE+PIC32MX_OC_RSSET_OFFSET) +#define PIC32MX_OC1_RSINV (PIC32MX_OC1_K1BASE+PIC32MX_OC_RSINV_OFFSET) + +#if CHIP_NOC > 1 +# define PIC32MX_OC2_CON (PIC32MX_OC2_K1BASE+PIC32MX_OC_CON_OFFSET) +# define PIC32MX_OC2_CONCLR (PIC32MX_OC2_K1BASE+PIC32MX_OC_CONCLR_OFFSET) +# define PIC32MX_OC2_CONSET (PIC32MX_OC2_K1BASE+PIC32MX_OC_CONSET_OFFSET) +# define PIC32MX_OC2_CONINV (PIC32MX_OC2_K1BASE+PIC32MX_OC_CONINV_OFFSET) +# define PIC32MX_OC2_R (PIC32MX_OC2_K1BASE+PIC32MX_OC_R_OFFSET) +# define PIC32MX_OC2_RCLR (PIC32MX_OC2_K1BASE+PIC32MX_OC_RCLR_OFFSET) +# define PIC32MX_OC2_RSET (PIC32MX_OC2_K1BASE+PIC32MX_OC_RSET_OFFSET) +# define PIC32MX_OC2_RINV (PIC32MX_OC2_K1BASE+PIC32MX_OC_RINV_OFFSET) +# define PIC32MX_OC2_RS (PIC32MX_OC2_K1BASE+PIC32MX_OC_RS_OFFSET) +# define PIC32MX_OC2_RSCLR (PIC32MX_OC2_K1BASE+PIC32MX_OC_RSCLR_OFFSET) +# define PIC32MX_OC2_RSSET (PIC32MX_OC2_K1BASE+PIC32MX_OC_RSSET_OFFSET) +# define PIC32MX_OC2_RSINV (PIC32MX_OC2_K1BASE+PIC32MX_OC_RSINV_OFFSET) +#endif + +#if CHIP_NOC > 2 +# define PIC32MX_OC3_CON (PIC32MX_OC3_K1BASE+PIC32MX_OC_CON_OFFSET) +# define PIC32MX_OC3_CONCLR (PIC32MX_OC3_K1BASE+PIC32MX_OC_CONCLR_OFFSET) +# define PIC32MX_OC3_CONSET (PIC32MX_OC3_K1BASE+PIC32MX_OC_CONSET_OFFSET) +# define PIC32MX_OC3_CONINV (PIC32MX_OC3_K1BASE+PIC32MX_OC_CONINV_OFFSET) +# define PIC32MX_OC3_R (PIC32MX_OC3_K1BASE+PIC32MX_OC_R_OFFSET) +# define PIC32MX_OC3_RCLR (PIC32MX_OC3_K1BASE+PIC32MX_OC_RCLR_OFFSET) +# define PIC32MX_OC3_RSET (PIC32MX_OC3_K1BASE+PIC32MX_OC_RSET_OFFSET) +# define PIC32MX_OC3_RINV (PIC32MX_OC3_K1BASE+PIC32MX_OC_RINV_OFFSET) +# define PIC32MX_OC3_RS (PIC32MX_OC3_K1BASE+PIC32MX_OC_RS_OFFSET) +# define PIC32MX_OC3_RSCLR (PIC32MX_OC3_K1BASE+PIC32MX_OC_RSCLR_OFFSET) +# define PIC32MX_OC3_RSSET (PIC32MX_OC3_K1BASE+PIC32MX_OC_RSSET_OFFSET) +# define PIC32MX_OC3_RSINV (PIC32MX_OC3_K1BASE+PIC32MX_OC_RSINV_OFFSET) +#endif + +#if CHIP_NOC > 3 +# define PIC32MX_OC4_CON (PIC32MX_OC4_K1BASE+PIC32MX_OC_CON_OFFSET) +# define PIC32MX_OC4_CONCLR (PIC32MX_OC4_K1BASE+PIC32MX_OC_CONCLR_OFFSET) +# define PIC32MX_OC4_CONSET (PIC32MX_OC4_K1BASE+PIC32MX_OC_CONSET_OFFSET) +# define PIC32MX_OC4_CONINV (PIC32MX_OC4_K1BASE+PIC32MX_OC_CONINV_OFFSET) +# define PIC32MX_OC4_R (PIC32MX_OC4_K1BASE+PIC32MX_OC_R_OFFSET) +# define PIC32MX_OC4_RCLR (PIC32MX_OC4_K1BASE+PIC32MX_OC_RCLR_OFFSET) +# define PIC32MX_OC4_RSET (PIC32MX_OC4_K1BASE+PIC32MX_OC_RSET_OFFSET) +# define PIC32MX_OC4_RINV (PIC32MX_OC4_K1BASE+PIC32MX_OC_RINV_OFFSET) +# define PIC32MX_OC4_RS (PIC32MX_OC4_K1BASE+PIC32MX_OC_RS_OFFSET) +# define PIC32MX_OC4_RSCLR (PIC32MX_OC4_K1BASE+PIC32MX_OC_RSCLR_OFFSET) +# define PIC32MX_OC4_RSSET (PIC32MX_OC4_K1BASE+PIC32MX_OC_RSSET_OFFSET) +# define PIC32MX_OC4_RSINV (PIC32MX_OC4_K1BASE+PIC32MX_OC_RSINV_OFFSET) +#endif + +#if CHIP_NOC > 4 +# define PIC32MX_OC5_CON (PIC32MX_OC5_K1BASE+PIC32MX_OC_CON_OFFSET) +# define PIC32MX_OC5_CONCLR (PIC32MX_OC5_K1BASE+PIC32MX_OC_CONCLR_OFFSET) +# define PIC32MX_OC5_CONSET (PIC32MX_OC5_K1BASE+PIC32MX_OC_CONSET_OFFSET) +# define PIC32MX_OC5_CONINV (PIC32MX_OC5_K1BASE+PIC32MX_OC_CONINV_OFFSET) +# define PIC32MX_OC5_R (PIC32MX_OC5_K1BASE+PIC32MX_OC_R_OFFSET) +# define PIC32MX_OC5_RCLR (PIC32MX_OC5_K1BASE+PIC32MX_OC_RCLR_OFFSET) +# define PIC32MX_OC5_RSET (PIC32MX_OC5_K1BASE+PIC32MX_OC_RSET_OFFSET) +# define PIC32MX_OC5_RINV (PIC32MX_OC5_K1BASE+PIC32MX_OC_RINV_OFFSET) +# define PIC32MX_OC5_RS (PIC32MX_OC5_K1BASE+PIC32MX_OC_RS_OFFSET) +# define PIC32MX_OC5_RSCLR (PIC32MX_OC5_K1BASE+PIC32MX_OC_RSCLR_OFFSET) +# define PIC32MX_OC5_RSSET (PIC32MX_OC5_K1BASE+PIC32MX_OC_RSSET_OFFSET) +# define PIC32MX_OC5_RSINV (PIC32MX_OC5_K1BASE+PIC32MX_OC_RSINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***************************************************/ + +/* Output compare control register */ + +#define OC_CON_OCM_SHIFT (0) /* Bits 0-2: Output compare mode select */ +#define OC_CON_OCM_MASK (7 << OC_CON_OCM_SHIFT) +# define OC_CON_OCM_DISABLE (0 << OC_CON_OCM_SHIFT) /* Output compare peripheral disabled */ +# define OC_CON_OCM_LOW2HI (1 << OC_CON_OCM_SHIFT) /* OCx low; compare forces high */ +# define OC_CON_OCM_HITOLOW (2 << OC_CON_OCM_SHIFT) /* OCx high; compare forces low */ +# define OC_CON_OCM_TOGGLE (3 << OC_CON_OCM_SHIFT) /* Compare event toggles OCx */ +# define OC_CON_OCM_LOWPULSE (4 << OC_CON_OCM_SHIFT) /* OCx low; output pulse on OCx*/ +# define OC_CON_OCM_HIPULSE (5 << OC_CON_OCM_SHIFT) /* OCx high; output pulse on OCx */ +# define OC_CON_OCM_PWM (6 << OC_CON_OCM_SHIFT) /* PWM mode on OCx; fault disabled */ +# define OC_CON_OCM_PWMFAULT (7 << OC_CON_OCM_SHIFT) /* PWM mode on OCx; fault enabled */ +#define OC_CON_OCTSEL (1 << 3) /* Bit 3: Output compare timer select */ +#define OC_CON_OCFLT (1 << 4) /* Bit 4: PWM fault condition status */ +#define OC_CON_OC32 (1 << 5) /* Bit 5: 32-bit compare more */ +#define OC_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define OC_CON_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +#define OC_CON_ON (1 << 15) /* Bit 15: Output compare periperal on */ + +/* Output compare data register -- 32-bit data register */ + +/* Output compare secondary data register -- 32-bit data register */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NOC > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OC_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-osc.h b/arch/mips/src/pic32mx/pic32mx-osc.h new file mode 100644 index 0000000000000000000000000000000000000000..b81d75744278981467d94759977a9c07572fa332 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-osc.h @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-osc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OSC_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OSC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MX_OSCCON_OFFSET 0x0000 /* Oscillator control register offset */ +#define PIC32MX_OSCTUN_OFFSET 0x0010 /* FRC tuning register offset */ + +/* Register Addresses *******************************************************/ + +#define PIC32MX_OSCCON (PIC32MX_OSC_K1BASE+PIC32MX_OSCCON_OFFSET) +#define PIC32MX_OSCTUN (PIC32MX_OSC_K1BASE+PIC32MX_OSCTUN_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ + +/* Oscillator control register offset */ + +#define OSCCON_OSWEN (1 << 0) /* Bit 0: Oscillator switch enable */ +#define OSCCON_SOSCEN (1 << 1) /* Bit 1: 32.768kHz secondary oscillator enable */ +#define OSCCON_UFRCEN (1 << 2) /* Bit 2: USB FRC clock enable */ +#define OSCCON_CF (1 << 3) /* Bit 3: Clock fail detect */ +#define OSCCON_SLPEN (1 << 4) /* Bit 4: Sleep mode enable */ +#define OSCCON_SLOCK (1 << 5) /* Bit 5: PLL lock status */ +#define OSCCON_ULOCK (1 << 6) /* Bit 6: USB PLL lock status */ +#define OSCCON_CLKLOCK (1 << 7) /* Bit 7: Clock selection lock enable */ +#define OSCCON_NOSC_SHIFT (8) /* Bits 8-10: New oscillator selection */ +#define OSCCON_NOSC_MASK (7 << OSCCON_NOSC_SHIFT) +# define OSCCON_NOSC_FRC (0 << OSCCON_NOSC_SHIFT) /* FRC oscillator */ +# define OSCCON_NOSC_FRCPLL (1 << OSCCON_NOSC_SHIFT) /* FRC w/PLL postscaler */ +# define OSCCON_NOSC_POSC (2 << OSCCON_NOSC_SHIFT) /* Primary oscillator */ +# define OSCCON_NOSC_POSCPLL (3 << OSCCON_NOSC_SHIFT) /* Primary oscillator with PLL */ +# define OSCCON_NOSC_SOSC (4 << OSCCON_NOSC_SHIFT) /* Secondary oscillator */ +# define OSCCON_NOSC_LPRC (5 << OSCCON_NOSC_SHIFT) /* Low power RC oscillator */ +# define OSCCON_NOSC_FRCDIV16 (6 << OSCCON_NOSC_SHIFT) /* FRC divided by 16 */ +# define OSCCON_NOSC_FRCDIV (7 << OSCCON_NOSC_SHIFT) /* FRC dived by FRCDIV */ +#define OSCCON_COSC_SHIFT (12) /* Bits 12-14: Current oscillator selection */ +#define OSCCON_COSC_MASK (7 << OSCCON_COSC_SHIFT) +# define OSCCON_COSC_FRC (0 << OSCCON_COSC_SHIFT) /* FRC oscillator */ +# define OSCCON_COSC_FRCPLL (1 << OSCCON_COSC_SHIFT) /* FRC w/PLL postscaler */ +# define OSCCON_COSC_POSC (2 << OSCCON_COSC_SHIFT) /* Primary oscillator */ +# define OSCCON_COSC_POSCPLL (3 << OSCCON_COSC_SHIFT) /* Primary oscillator with PLL */ +# define OSCCON_COSC_SOSC (4 << OSCCON_COSC_SHIFT) /* Secondary oscillator */ +# define OSCCON_COSC_LPRC (5 << OSCCON_COSC_SHIFT) /* Low power RC oscillator */ +# define OSCCON_COSC_FRCDIV16 (6 << OSCCON_COSC_SHIFT) /* FRC divided by 16 */ +# define OSCCON_COSC_FRCDIV (7 << OSCCON_COSC_SHIFT) /* FRC dived by FRCDIV */ +#define OSCCON_PLLMULT_SHIFT (16) /* Bits 16-18: PLL multiplier */ +#define OSCCON_PLLMULT_MASK (7 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL15 (0 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL16 (1 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL17 (2 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL18 (3 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL19 (4 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL20 (5 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL21 (6 << OSCCON_PLLMULT_SHIFT) +# define OSCCON_PLLMULT_MUL24 (7 << OSCCON_PLLMULT_SHIFT) +#define OSCCON_PBDIV_SHIFT (19) /* Bits 19-20: PBVLK divisor */ +#define OSCCON_PBDIV_SMASK (3 << OSCCON_PBDIV_SHIFT) +# define OSCCON_PBDIV_DIV1 (0 << OSCCON_PBDIV_SHIFT) +# define OSCCON_PBDIV_DIV2 (1 << OSCCON_PBDIV_SHIFT) +# define OSCCON_PBDIV_DIV4 (2 << OSCCON_PBDIV_SHIFT) +# define OSCCON_PBDIV_DIV8 (3 << OSCCON_PBDIV_SHIFT) +#define OSCCON_SOSCRDY (1 << 22) /* Bit 22: Secondary oscillator ready */ +#define OSCCON_FRCDIV_SHIFT (24) /* Bits 24-26: FRC oscillator divider */ +#define OSCCON_FRCDIV_MASK (7 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV1 (0 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV2 (1 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV4 (2 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV8 (3 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV16 (4 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV32 (5 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV64 (6 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV256 (7 << OSCCON_FRCDIV_SHIFT) +#define OSCCON_PLL0DIV_SHIFT (27) /* Bits 27-29: Output divider for PLL */ +#define OSCCON_PLL0DIV_MASK (7 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV1 (0 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV2 (1 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV4 (2 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV8 (3 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV16 (4 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV32 (5 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV64 (6 << OSCCON_PLL0DIV_SHIFT) +# define OSCCON_PLL0DIV_DIV256 (7 << OSCCON_PLL0DIV_SHIFT) + +/* FRC tuning register offset (6-bit, signed twos complement) */ + +#define OSCTUN_SHIFT (0) /* Bits 0-5: FRC tuning bits */ +#define OSCTUN_MASK (0x3f << OSCTUN_SHIFT) +# define OSCTUN_MIN (0x20 << OSCTUN_SHIFT) +# define OSCTUN_CENTER (0x00 << OSCTUN_SHIFT) +# define OSCTUN_MAX (0x1f << OSCTUN_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_OSC_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-pmp.h b/arch/mips/src/pic32mx/pic32mx-pmp.h new file mode 100644 index 0000000000000000000000000000000000000000..637480e549120f97fa816172c87884e6f37bec9f --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-pmp.h @@ -0,0 +1,240 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-pmp.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PMP_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PMP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_PMP_CON_OFFSET 0x0000 /* Parallel Port Control Register */ +#define PIC32MX_PMP_CONCLR_OFFSET 0x0004 /* Parallel Port Control Clear Register */ +#define PIC32MX_PMP_CONSET_OFFSET 0x0008 /* Parallel Port Control Set Register */ +#define PIC32MX_PMP_CONINV_OFFSET 0x000c /* Parallel Port Control Invert Register */ +#define PIC32MX_PMP_MODE_OFFSET 0x0010 /* Parallel Port Mode Register */ +#define PIC32MX_PMP_MODECLR_OFFSET 0x0014 /* Parallel Port Mode Clear Register */ +#define PIC32MX_PMP_MODESET_OFFSET 0x0018 /* Parallel Port Mode Set Register */ +#define PIC32MX_PMP_MODEINV_OFFSET 0x001c /* Parallel Port Mode Invert Register */ +#define PIC32MX_PMP_ADDR_OFFSET 0x0020 /* Parallel Port Address Register */ +#define PIC32MX_PMP_ADDRCLR_OFFSET 0x0024 /* Parallel Port Address Clear Register */ +#define PIC32MX_PMP_ADDRSET_OFFSET 0x0028 /* Parallel Port Address Set Register */ +#define PIC32MX_PMP_ADDRINV_OFFSET 0x002c /* Parallel Port Address Invert Register */ +#define PIC32MX_PMP_DOUT_OFFSET 0x0030 /* Parallel Port Data Output Register */ +#define PIC32MX_PMP_DOUTCLR_OFFSET 0x0034 /* Parallel Port Data Output Clear Register */ +#define PIC32MX_PMP_DOUTSET_OFFSET 0x0038 /* Parallel Port Data Output Set Register */ +#define PIC32MX_PMP_DOUTINV_OFFSET 0x003c /* Parallel Port Data Output Invert Register */ +#define PIC32MX_PMP_DIN_OFFSET 0x0040 /* Parallel Port Data Input Register */ +#define PIC32MX_PMP_DINCLR_OFFSET 0x0044 /* Parallel Port Data Input Clear Register */ +#define PIC32MX_PMP_DINSET_OFFSET 0x0048 /* Parallel Port Data Input Set Register */ +#define PIC32MX_PMP_DININV_OFFSET 0x004c /* Parallel Port Data Input Invert Register */ +#define PIC32MX_PMP_AEN_OFFSET 0x0050 /* Parallel Port Pin Enable Register */ +#define PIC32MX_PMP_AENCLR_OFFSET 0x0054 /* Parallel Port Pin Enable Clear Register */ +#define PIC32MX_PMP_AENSET_OFFSET 0x0058 /* Parallel Port Pin Enable Set Register */ +#define PIC32MX_PMP_AENINV_OFFSET 0x005c /* Parallel Port Pin Enable Invert Register */ +#define PIC32MX_PMP_STAT_OFFSET 0x0060 /* Parallel Port Status Register */ +#define PIC32MX_PMP_STATCLR_OFFSET 0x0064 /* Parallel Port Status Clear Register */ +#define PIC32MX_PMP_STATSET_OFFSET 0x0068 /* Parallel Port Status Set Register */ +#define PIC32MX_PMP_STATINV_OFFSET 0x006c /* Parallel Port Status Invert Register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_PMP_CON (PIC32MX_PMP_K1BASE+PIC32MX_PMP_CON_OFFSET) +#define PIC32MX_PMP_CONCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_CONCLR_OFFSET) +#define PIC32MX_PMP_CONSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_CONSET_OFFSET) +#define PIC32MX_PMP_CONINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_CONINV_OFFSET) +#define PIC32MX_PMP_MODE (PIC32MX_PMP_K1BASE+PIC32MX_PMP_MODE_OFFSET) +#define PIC32MX_PMP_MODECLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_MODECLR_OFFSET) +#define PIC32MX_PMP_MODESET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_MODESET_OFFSET) +#define PIC32MX_PMP_MODEINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_MODEINV_OFFSET) +#define PIC32MX_PMP_ADDR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_ADDR_OFFSET) +#define PIC32MX_PMP_ADDRCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_ADDRCLR_OFFSET) +#define PIC32MX_PMP_ADDRSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_ADDRSET_OFFSET) +#define PIC32MX_PMP_ADDRINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_ADDRINV_OFFSET) +#define PIC32MX_PMP_DOUT (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DOUT_OFFSET) +#define PIC32MX_PMP_DOUTCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DOUTCLR_OFFSET) +#define PIC32MX_PMP_DOUTSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DOUTSET_OFFSET) +#define PIC32MX_PMP_DOUTINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DOUTINV_OFFSET) +#define PIC32MX_PMP_DIN (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DIN_OFFSET) +#define PIC32MX_PMP_DINCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DINCLR_OFFSET) +#define PIC32MX_PMP_DINSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DINSET_OFFSET) +#define PIC32MX_PMP_DININV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_DININV_OFFSET) +#define PIC32MX_PMP_AEN (PIC32MX_PMP_K1BASE+PIC32MX_PMP_AEN_OFFSET) +#define PIC32MX_PMP_AENCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_AENCLR_OFFSET) +#define PIC32MX_PMP_AENSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_AENSET_OFFSET) +#define PIC32MX_PMP_AENINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_AENINV_OFFSET) +#define PIC32MX_PMP_STAT (PIC32MX_PMP_K1BASE+PIC32MX_PMP_STAT_OFFSET) +#define PIC32MX_PMP_STATCLR (PIC32MX_PMP_K1BASE+PIC32MX_PMP_STATCLR_OFFSET) +#define PIC32MX_PMP_STATSET (PIC32MX_PMP_K1BASE+PIC32MX_PMP_STATSET_OFFSET) +#define PIC32MX_PMP_STATINV (PIC32MX_PMP_K1BASE+PIC32MX_PMP_STATINV_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Parallel Port Control Register */ + +#define PMP_CON_RDSP (1 << 0) /* Bit 0: Read strobe polarity */ +#define PMP_CON_WRSP (1 << 1) /* Bit 1: Write strobe polarity */ +#define PMP_CON_CS1P (1 << 3) /* Bit 3: Chip select 0 polarity */ +#define PMP_CON_CS2P (1 << 4) /* Bit 4: Chip select 1 polarity */ +#define PMP_CON_ALP (1 << 5) /* Bit 5: Address latch polarity */ +#define PMP_CON_CSF_SHIFT (6) /* Bits 6-7: Chip select function */ +#define PMP_CON_CSF_MASK (3 << PMP_CON_CSF_SHIFT) +# define PMP_CON_CSF_ADDR1415 (0 << PMP_CON_CSF_SHIFT) /* PMCS2/PMCS1 = address bits 15 and 14 */ +# define PMP_CON_CSF_CS2ADDR14 (1 << PMP_CON_CSF_SHIFT) /* PMCS2 = Chip Select, PMCS1 = address bit 14 */ +# define PMP_CON_CSF_CS12 (2 << PMP_CON_CSF_SHIFT) /* PMCS2/PMCS1 = Chip Select */ +#define PMP_CON_PTRDEN (1 << 8) /* Bit 8: Read/write strobe port enable */ +#define PMP_CON_PTWREN (1 << 9) /* Bit 9: Write enable strobe port enable */ +#define PMP_CON_PMPTTL (1 << 10) /* Bit 10: PMP module TTL input buffer select */ +#define PMP_CON_ADRMUX_SHIFT (11) /* Bits 11-12: Address/data multiplexing selection */ +#define PMP_CON_ADRMUX_MASK (3 << PMP_CON_ADRMUX_SHIFT) +# define PMP_CON_ADRMUX_NONE (0 << PMP_CON_ADRMUX_SHIFT) /* Address and data appear separate */ +# define PMP_CON_ADRMUX_BYTE (1 << PMP_CON_ADRMUX_SHIFT) /* LS address are mux'ed on PMD 7:0 MS on PMA 15:8 */ +# define PMP_CON_ADRMUX_MUX8 (2 << PMP_CON_ADRMUX_SHIFT) /* Address mux'ed on PMD 7:0 */ +# define PMP_CON_ADRMUX_MUX16 (3 << PMP_CON_ADRMUX_SHIFT) /* Address mux'ed on PMD 15:0 */ +#define PMP_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define PMP_CON_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +#define PMP_CON_ON (1 << 15) /* Bit 15: Parallel master port enable */ + +/* Parallel Port Mode Register */ + +#define PMP_MODE_WAITE_SHIFT (0) /* Bits 0-1: Data hold after R/W strobe wait states */ +#define PMP_MODE_WAITE_MASK (3 << PMP_MODE_WAITE_SHIFT) +# define PMP_MODE_WAITE_WR(n) ((n-1) << PMP_MODE_WAITE_SHIFT) /* Wait of n TPB n=1..4 */ +# define PMP_MODE_WAITE_RD(n) ((n) << PMP_MODE_WAITE_SHIFT) /* Wait of n TPB n=0..3 */ +#define PMP_MODE_WAITM_SHIFT (2) /* Bits 2-5: Data R/W strobe wait states */ +#define PMP_MODE_WAITM_MASK (15 << PMP_MODE_WAITM_SHIFT) +# define PMP_MODE_WAITM(n) ((n-1) << PMP_MODE_WAITM_SHIFT) /* Wait of n TPB n=1..16 */ +#define PMP_MODE_WAITB_SHIFT (6) /* Bits 6-7: Data setup to R/W strobe wait states */ +#define PMP_MODE_WAITB_MASK (3 << PMP_MODE_WAITB_SHIFT) +# define PMP_MODE_WAITB_1TPB (0 << PMP_MODE_WAITB_SHIFT) /* Data wait of 1 TPB */ +# define PMP_MODE_WAITB_2TPB (1 << PMP_MODE_WAITB_SHIFT) /* Data wait of 2 TPB */ +# define PMP_MODE_WAITB_3TPB (2 << PMP_MODE_WAITB_SHIFT) /* Data wait of 3 TPB */ +# define PMP_MODE_WAITB_4TPB (3 << PMP_MODE_WAITB_SHIFT) /* Data wait of 4 TPB */ +#define PMP_MODE_MODE_SHIFT (8) /* Bits 8-9: Parallel port mode select */ +#define PMP_MODE_MODE_MASK (3 << PMP_MODE_MODE_SHIFT) +# define PMP_MODE_MODE_LEGACY (0 << PMP_MODE_MODE_SHIFT) /* Legacy parallel slave port */ +# define PMP_MODE_MODE_SLAVE (1 << PMP_MODE_MODE_SHIFT) /* Enhanced slave mode */ +# define PMP_MODE_MODE_MODE2 (2 << PMP_MODE_MODE_SHIFT) /* Master mode 2 */ +# define PMP_MODE_MODE_MODE1 (3 << PMP_MODE_MODE_SHIFT) /* Master mode 1 */ +#define PMP_MODE_MODE16 (1 << 10) /* Bit 10: 1=16-bit mode */ +#define PMP_MODE_MODE8 (0) /* 0=8-bit mode */ +#define PMP_MODE_INCM_SHIFT (11) /* Bits 11-12: Increment Mode */ +#define PMP_MODE_INCM_MASK (3 << PMP_MODE_INCM_SHIFT) +# define PMP_MODE_INCM_NONE (0 << PMP_MODE_INCM_SHIFT) /* No incr or decr of addr */ +# define PMP_MODE_INCM_INCR (1 << PMP_MODE_INCM_SHIFT) /* Incr addr on R/W cycle */ +# define PMP_MODE_INCM_DECR (2 << PMP_MODE_INCM_SHIFT) /* Decr addr on R/Wcycle */ +# define PMP_MODE_INCM_SLAVE (3 << PMP_MODE_INCM_SHIFT) /* Slave mode auto-increment */ +#define PMP_MODE_IRQM_SHIFT (13) /* Bits 13-14: Interrupt request mode */ +#define PMP_MODE_IRQM_MASK (3 << PMP_MODE_IRQM_SHIFT) +# define PMP_MODE_IRQM_NONE (0 << PMP_MODE_IRQM_SHIFT) /* No Interrupt generated */ +# define PMP_MODE_IRQM_RW (1 << PMP_MODE_IRQM_SHIFT) /* Interrupt at end of R/W cycle */ +# define PMP_MODE_IRQM_BUFFER (2 << PMP_MODE_IRQM_SHIFT) /* R/W buffer 3 or write PMA=11 */ +#define PMP_MODE_BUSY (1 << 15) /* Bit 15: Busy (master mode only) */ + +/* Parallel Port Address Register */ + +#define PMP_ADDR_ADDR_SHIFT (0) /* Bits 0-13: Destination address */ +#define PMP_ADDR_ADDR_MASK (0x3fff << PMP_ADDR_ADDR_SHIFT) +#define PMP_ADDR_CS1EN (1 << 14) /* Bit 14: Chip select 1 */ +#define PMP_ADDR_CS2EN (1 << 15) /* Bit 15: Chip select 2 */ + +/* Parallel Port Data Output Register -- 32-bit data register */ + +/* Parallel Port Data Input Register -- 32-bit data register */ + +/* Parallel Port Pin Enable Register */ + +#define PMP_AEN_PMALEN_SHIFT (0) /* PTEN 0-1: PMALH/PMALL strobe enable */ +#define PMP_AEN_PMALEN_MASK (3 << PMP_AEN_STROBEN_SHIFT) +#define PMP_AEN_ADDR_SHIFT (2) /* PTEN 2-13: PMP address port enable */ +#define PMP_AEN_ADDR_MASK (0xfff << PMP_AEN_STROBEN_SHIFT) +#define PMP_AEN_PMCSEN_SHIFT (14) /* PTEN 14-15: PMCSx Strobe enable */ +#define PMP_AEN_PMCSEN_MASK (3 << PMP_AEN_STROBEN_SHIFT) + +/* Parallel Port Status Register */ + +#define PMP_STAT_OBNE(n) (1 << (n)) +#define PMP_STAT_OB0E (1 << 0) /* Bit 0: Output buffer 0 status empty bits */ +#define PMP_STAT_OB1E (1 << 1) /* Bit 1: Output buffer 1 status empty bits */ +#define PMP_STAT_OB2E (1 << 2) /* Bit 2: Output buffer 2 status empty bits */ +#define PMP_STAT_OB3E (1 << 3) /* Bit 3: Output buffer 3 status empty bits */ +#define PMP_STAT_OBUF (1 << 6) /* Bit 6: Output buffer underflow status */ +#define PMP_STAT_OBE (1 << 7) /* Bit 7: Output buffer empty status */ +#define PMP_STAT_IBNF(n) (1 << (n+8)) +#define PMP_STAT_IB0F (1 << 8) /* Bit 8: Input buffer 0 status full */ +#define PMP_STAT_IB1F (1 << 9) /* Bit 9: Input buffer 1 status full */ +#define PMP_STAT_IB2F (1 << 10) /* Bit 10: Input buffer 2 status full */ +#define PMP_STAT_IB3F (1 << 11) /* Bit 11: Input buffer 3 status full */ +#define PMP_STAT_IBOV (1 << 14) /* Bit 14: Input buffer overflow status */ +#define PMP_STAT_IBF (1 << 15) /* Bit 15: Input buffer full status */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PMP_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-pps.h b/arch/mips/src/pic32mx/pic32mx-pps.h new file mode 100644 index 0000000000000000000000000000000000000000..950792702faf20d637cf147a17ca3af43cb56ecb --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-pps.h @@ -0,0 +1,276 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-pps.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PPS_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PPS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ +/* Peripheral pin select input registers */ + +#define PIC32MX_PPS_INT1R_OFFSET 0x0004 +#define PIC32MX_PPS_INT2R_OFFSET 0x0008 +#define PIC32MX_PPS_INT3R_OFFSET 0x000c +#define PIC32MX_PPS_INT4R_OFFSET 0x0010 +#define PIC32MX_PPS_T2CKR_OFFSET 0x0018 +#define PIC32MX_PPS_T3CKR_OFFSET 0x001c +#define PIC32MX_PPS_T4CKR_OFFSET 0x0020 +#define PIC32MX_PPS_T5CKR_OFFSET 0x0024 +#define PIC32MX_PPS_IC1R_OFFSET 0x0028 +#define PIC32MX_PPS_IC2R_OFFSET 0x002c +#define PIC32MX_PPS_IC3R_OFFSET 0x0030 +#define PIC32MX_PPS_IC4R_OFFSET 0x0034 +#define PIC32MX_PPS_IC5R_OFFSET 0x0038 +#define PIC32MX_PPS_OCFAR_OFFSET 0x0048 +#define PIC32MX_PPS_OCFBR_OFFSET 0x004c +#define PIC32MX_PPS_U1RXR_OFFSET 0x0050 +#define PIC32MX_PPS_U1CTSR_OFFSET 0x0054 +#define PIC32MX_PPS_U2RXR_OFFSET 0x0058 +#define PIC32MX_PPS_U2CTSR_OFFSET 0x005c +#define PIC32MX_PPS_SDI1R_OFFSET 0x0084 +#define PIC32MX_PPS_SS1R_OFFSET 0x0088 +#define PIC32MX_PPS_SDI2R_OFFSET 0x0090 +#define PIC32MX_PPS_SS2R_OFFSET 0x0094 +#define PIC32MX_PPS_REFCLKIR_OFFSET 0x00b8 + +/* Peripheral pin select output registers */ + +#define PIC32MX_PPS_RPA0R_OFFSET 0x0000 +#define PIC32MX_PPS_RPA1R_OFFSET 0x0004 +#define PIC32MX_PPS_RPA2R_OFFSET 0x0008 +#define PIC32MX_PPS_RPA3R_OFFSET 0x000c +#define PIC32MX_PPS_RPA4R_OFFSET 0x0010 +#define PIC32MX_PPS_RPA8R_OFFSET 0x0020 +#define PIC32MX_PPS_RPA9R_OFFSET 0x0024 +#define PIC32MX_PPS_RPB0R_OFFSET 0x002c +#define PIC32MX_PPS_RPB1R_OFFSET 0x0030 +#define PIC32MX_PPS_RPB2R_OFFSET 0x0034 +#define PIC32MX_PPS_RPB3R_OFFSET 0x0038 +#define PIC32MX_PPS_RPB4R_OFFSET 0x003c +#define PIC32MX_PPS_RPB5R_OFFSET 0x0040 +#define PIC32MX_PPS_RPB6R_OFFSET 0x0044 +#define PIC32MX_PPS_RPB7R_OFFSET 0x0048 +#define PIC32MX_PPS_RPB8R_OFFSET 0x004c +#define PIC32MX_PPS_RPB9R_OFFSET 0x0050 +#define PIC32MX_PPS_RPB10R_OFFSET 0x0054 +#define PIC32MX_PPS_RPB11R_OFFSET 0x0058 +#define PIC32MX_PPS_RPB13R_OFFSET 0x0060 +#define PIC32MX_PPS_RPB14R_OFFSET 0x0064 +#define PIC32MX_PPS_RPB15R_OFFSET 0x0068 +#define PIC32MX_PPS_RPC0R_OFFSET 0x006c +#define PIC32MX_PPS_RPC1R_OFFSET 0x0070 +#define PIC32MX_PPS_RPC2R_OFFSET 0x0074 +#define PIC32MX_PPS_RPC3R_OFFSET 0x0078 +#define PIC32MX_PPS_RPC4R_OFFSET 0x007c +#define PIC32MX_PPS_RPC5R_OFFSET 0x0080 +#define PIC32MX_PPS_RPC6R_OFFSET 0x0084 +#define PIC32MX_PPS_RPC7R_OFFSET 0x0088 +#define PIC32MX_PPS_RPC8R_OFFSET 0x008c +#define PIC32MX_PPS_RPC9R_OFFSET 0x0090 + +/* Register Addresses *******************************************************/ +/* Peripheral pin select input registers */ + +#define PIC32MX_PPS_INT1R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_INT1R_OFFSET) +#define PIC32MX_PPS_INT2R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_INT2R_OFFSET) +#define PIC32MX_PPS_INT3R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_INT3R_OFFSET) +#define PIC32MX_PPS_INT4R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_INT4R_OFFSET) +#define PIC32MX_PPS_T2CKR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_T2CKR_OFFSET) +#define PIC32MX_PPS_T3CKR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_T3CKR_OFFSET) +#define PIC32MX_PPS_T4CKR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_T4CKR_OFFSET) +#define PIC32MX_PPS_T5CKR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_T5CKR_OFFSET) +#define PIC32MX_PPS_IC1R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_IC1R_OFFSET) +#define PIC32MX_PPS_IC2R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_IC2R_OFFSET) +#define PIC32MX_PPS_IC3R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_IC3R_OFFSET) +#define PIC32MX_PPS_IC4R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_IC4R_OFFSET) +#define PIC32MX_PPS_IC5R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_IC5R_OFFSET) +#define PIC32MX_PPS_OCFAR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_OCFAR_OFFSET) +#define PIC32MX_PPS_OCFBR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_OCFBR_OFFSET) +#define PIC32MX_PPS_U1RXR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_U1RXR_OFFSET) +#define PIC32MX_PPS_U1CTSR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_U1CTSR_OFFSET) +#define PIC32MX_PPS_U2RXR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_U2RXR_OFFSET) +#define PIC32MX_PPS_U2CTSR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_U2CTSR_OFFSET) +#define PIC32MX_PPS_SDI1R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_SDI1R_OFFSET) +#define PIC32MX_PPS_SS1R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_SS1R_OFFSET) +#define PIC32MX_PPS_SDI2R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_SDI2R_OFFSET) +#define PIC32MX_PPS_SS2R (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_SS2R_OFFSET) +#define PIC32MX_PPS_REFCLKIR (PIC32MX_INSEL_K1BASE+PIC32MX_PPS_REFCLKIR_OFFSET) + +/* Peripheral pin select output registers */ + +#define PIC32MX_PPS_RPA0R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA0R_OFFSET) +#define PIC32MX_PPS_RPA1R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA1R_OFFSET) +#define PIC32MX_PPS_RPA2R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA2R_OFFSET) +#define PIC32MX_PPS_RPA3R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA3R_OFFSET) +#define PIC32MX_PPS_RPA4R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA4R_OFFSET) +#define PIC32MX_PPS_RPA8R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA8R_OFFSET) +#define PIC32MX_PPS_RPA9R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPA9R_OFFSET) +#define PIC32MX_PPS_RPB0R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB0R_OFFSET) +#define PIC32MX_PPS_RPB1R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB1R_OFFSET) +#define PIC32MX_PPS_RPB2R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB2R_OFFSET) +#define PIC32MX_PPS_RPB3R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB3R_OFFSET) +#define PIC32MX_PPS_RPB4R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB4R_OFFSET) +#define PIC32MX_PPS_RPB5R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB5R_OFFSET) +#define PIC32MX_PPS_RPB6R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB6R_OFFSET) +#define PIC32MX_PPS_RPB7R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB7R_OFFSET) +#define PIC32MX_PPS_RPB8R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB8R_OFFSET) +#define PIC32MX_PPS_RPB9R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB9R_OFFSET) +#define PIC32MX_PPS_RPB10R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB10R_OFFSET) +#define PIC32MX_PPS_RPB11R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB11R_OFFSET) +#define PIC32MX_PPS_RPB13R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB13R_OFFSET) +#define PIC32MX_PPS_RPB14R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB14R_OFFSET) +#define PIC32MX_PPS_RPB15R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPB15R_OFFSET) +#define PIC32MX_PPS_RPC0R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC0R_OFFSET) +#define PIC32MX_PPS_RPC1R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC1R_OFFSET) +#define PIC32MX_PPS_RPC2R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC2R_OFFSET) +#define PIC32MX_PPS_RPC3R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC3R_OFFSET) +#define PIC32MX_PPS_RPC4R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC4R_OFFSET) +#define PIC32MX_PPS_RPC5R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC5R_OFFSET) +#define PIC32MX_PPS_RPC6R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC6R_OFFSET) +#define PIC32MX_PPS_RPC7R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC7R_OFFSET) +#define PIC32MX_PPS_RPC8R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC8R_OFFSET) +#define PIC32MX_PPS_RPC9R (PIC32MX_OUTSEL_K1BASE+PIC32MX_PPS_RPC9R_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ +/* Peripheral pin select input registers */ + +#define PPS_INSEL_MASK 0x0000000f + +#define PPS_INSEL_RPA0 0 +#define PPS_INSEL_RPB3 1 +#define PPS_INSEL_RPB4 2 +#define PPS_INSEL_RPB15 3 +#define PPS_INSEL_RPB7 4 +#define PPS_INSEL_RPC7 5 +#define PPS_INSEL_RPC0 6 +#define PPS_INSEL_RPC5 7 + +#define PPS_INSEL_RPA1 0 +#define PPS_INSEL_RPB5 1 +#define PPS_INSEL_RPB1 2 +#define PPS_INSEL_RPB11 3 +#define PPS_INSEL_RPB8 4 +#define PPS_INSEL_RPA8 5 +#define PPS_INSEL_RPC8 6 +#define PPS_INSEL_RPA9 7 + +#define PPS_INSEL_RPA2 0 +#define PPS_INSEL_RPB6 1 +#define PPS_INSEL_RPA4 2 +#define PPS_INSEL_RPB13 3 +#define PPS_INSEL_RPB2 4 +#define PPS_INSEL_RPC6 5 +#define PPS_INSEL_RPC1 6 +#define PPS_INSEL_RPC3 7 + +#define PPS_INSEL_RPA3 0 +#define PPS_INSEL_RPB14 1 +#define PPS_INSEL_RPB0 2 +#define PPS_INSEL_RPB10 3 +#define PPS_INSEL_RPB9 4 +#define PPS_INSEL_RPC9 5 +#define PPS_INSEL_RPC2 6 +#define PPS_INSEL_RPC4 7 + +/* Peripheral pin select output registers */ + +#define PPS_OUTSEL_MASK 0x0000000f + +#define PPS_OUTSEL_NOCONNECT 0 + +#define PPS_OUTSEL_U1TX 1 +#define PPS_OUTSEL_U2RTS 2 +#define PPS_OUTSEL_SS1 3 +#define PPS_OUTSEL_OC1 5 +#define PPS_OUTSEL_C2OUT 7 + +#define PPS_OUTSEL_SDO1 3 +#define PPS_OUTSEL_SDO2 4 +#define PPS_OUTSEL_OC2 5 + +//#define PPS_OUTSEL_SDO1 3 +//#define PPS_OUTSEL_SDO2 4 +#define PPS_OUTSEL_OC4 5 +#define PPS_OUTSEL_OC5 6 +#define PPS_OUTSEL_REFCLKO 7 + +#define PPS_OUTSEL_U1RTS 1 +#define PPS_OUTSEL_U2TX 2 +#define PPS_OUTSEL_SS2 4 +#define PPS_OUTSEL_OC3 5 +#define PPS_OUTSEL_C1OUT 7 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_PIC32MX1 || CHIP_PIC32MX2 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_PPS_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-reset.h b/arch/mips/src/pic32mx/pic32mx-reset.h new file mode 100644 index 0000000000000000000000000000000000000000..5cddd8bfc3907763393b8e7ce020636d613d0797 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-reset.h @@ -0,0 +1,118 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-reset.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RESET_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RESET_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_RESET_RCON_OFFSET 0x0000 /* Reset control register */ +#define PIC32MX_RESET_RCONCLR_OFFSET 0x0004 /* RCON clear register */ +#define PIC32MX_RESET_RCONSET_OFFSET 0x0008 /* RCON set register */ +#define PIC32MX_RESET_RCONINV_OFFSET 0x000c /* RCON invert register */ +#define PIC32MX_RESET_RSWRST_OFFSET 0x0010 /* Software reset register */ +#define PIC32MX_RESET_RSWRSTCLR_OFFSET 0x0014 /* RSWRST clear register */ +#define PIC32MX_RESET_RSWRSTSET_OFFSET 0x0018 /* RSWRST set register */ +#define PIC32MX_RESET_RSWRSTINV_OFFSET 0x001c /* RSWRST invert register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_RESET_RCON (PIC32MX_RESET_K1BASE+PIC32MX_RCON_OFFSET) +#define PIC32MX_RESET_RCONCLR (PIC32MX_RESET_K1BASE+PIC32MX_RCONCLR_OFFSET) +#define PIC32MX_RESET_RCONSET (PIC32MX_RESET_K1BASE+PIC32MX_RCONSET_OFFSET) +#define PIC32MX_RESET_RCONINV (PIC32MX_RESET_K1BASE+PIC32MX_RCONINV_OFFSET) +#define PIC32MX_RESET_RSWRST (PIC32MX_RESET_K1BASE+PIC32MX_RSWRST_OFFSET) +#define PIC32MX_RESET_RSWRSTCLR (PIC32MX_RESET_K1BASE+PIC32MX_RSWRSTCLR_OFFSET) +#define PIC32MX_RESET_RSWRSTSET (PIC32MX_RESET_K1BASE+PIC32MX_RSWRSTSET_OFFSET) +#define PIC32MX_RESET_RSWRSTINV (PIC32MX_RESET_K1BASE+PIC32MX_RSWRSTINV_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* Reset control register */ + +#define RESET_RCON_POR (1 << 0) /* Bit 0: Power on reset */ +#define RESET_RCON_BOR (1 << 1) /* Bit 1: Brown out reset */ +#define RESET_RCON_IDLE (1 << 2) /* Bit 2: Wake from idle */ +#define RESET_RCON_SLEEP (1 << 3) /* Bit 3: Wake from sleep */ +#define RESET_RCON_WDTO (1 << 4) /* Bit 4: Watchdog timer time-out */ +#define RESET_RCON_SWR (1 << 6) /* Bit 6: Software reset */ +#define RESET_RCON_EXTR (1 << 7) /* Bit 7: External reset pin */ +#define RESET_RCON_VREGS (1 << 8) /* Bit 8: Voltage regulator standby enable */ +#define RESET_RCON_CMR (1 << 9) /* Bit 9: Configuration mismatch reset */ + +/* Software reset register */ + +#define RESET_RSWRST_TRIGGER (1 << 0) /* Bit 0: Software reset trigger */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RESET_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-rtcc.h b/arch/mips/src/pic32mx/pic32mx-rtcc.h new file mode 100644 index 0000000000000000000000000000000000000000..93618ce7d2630acbf3c30bff8c090b7338e6d780 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-rtcc.h @@ -0,0 +1,220 @@ +/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-rtcc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RTCC_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RTCC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +#define PIC32MX_RTCC_CON_OFFSET 0x0000 /* RTC Control Register */ +#define PIC32MX_RTCC_CONCLR_OFFSET 0x0004 /* RTC Control Clear Register */ +#define PIC32MX_RTCC_CONSET_OFFSET 0x0008 /* RTC Control Set Register */ +#define PIC32MX_RTCC_CONINV_OFFSET 0x000c /* RTC Control Invert Register */ +#define PIC32MX_RTCC_ALRM_OFFSET 0x0010 /* RTC ALARM Control Register */ +#define PIC32MX_RTCC_ALRMCLR_OFFSET 0x0014 /* RTC ALARM Control Clear Register */ +#define PIC32MX_RTCC_ALRMSET_OFFSET 0x0018 /* RTC ALARM Control Set Register */ +#define PIC32MX_RTCC_ALRMINV_OFFSET 0x001c /* RTC ALARM Control Invert Register */ +#define PIC32MX_RTCC_TIME_OFFSET 0x0020 /* RTC Time Value Register */ +#define PIC32MX_RTCC_TIMECLR_OFFSET 0x0024 /* RTC Time Value Clear Register */ +#define PIC32MX_RTCC_TIMESET_OFFSET 0x0028 /* RTC Time Value Set Register */ +#define PIC32MX_RTCC_TIMEINV_OFFSET 0x002c /* RTC Time Value Invert Register */ +#define PIC32MX_RTCC_DATE_OFFSET 0x0030 /* RTC Date Value Register */ +#define PIC32MX_RTCC_DATECLR_OFFSET 0x0034 /* RTC Date Value Clear Register */ +#define PIC32MX_RTCC_DATESET_OFFSET 0x0038 /* RTC Date Value Set Register */ +#define PIC32MX_RTCC_DATEINV_OFFSET 0x003c /* RTC Date Value Invert Register */ +#define PIC32MX_RTCC_ALRMTIME_OFFSET 0x0040 /* Alarm Time Value Register */ +#define PIC32MX_RTCC_ALRMTIMECLR_OFFSET 0x0044 /* Alarm Time Value Clear Register */ +#define PIC32MX_RTCC_ALRMTIMESET_OFFSET 0x0048 /* Alarm Time Value Set Register */ +#define PIC32MX_RTCC_ALRMTIMEINV_OFFSET 0x004c /* Alarm Time Value Invert Register */ +#define PIC32MX_RTCC_ALRMDATE_OFFSET 0x0050 /* Alarm Date Value Register */ +#define PIC32MX_RTCC_ALRMDATECLR_OFFSET 0x0054 /* Alarm Date Value Clear Register */ +#define PIC32MX_RTCC_ALRMDATESET_OFFSET 0x0058 /* Alarm Date Value Set Register */ +#define PIC32MX_RTCC_ALRMDATEINV_OFFSET 0x005c /* Alarm Date Value Invert Register */ + +/* Register Addresses ***********************************************************************/ + +#define PIC32MX_RTCC_CON (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_CON_OFFSET) +#define PIC32MX_RTCC_CONCLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_CONCLR_OFFSET) +#define PIC32MX_RTCC_CONSET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_CONSET_OFFSET) +#define PIC32MX_RTCC_CONINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_CONINV_OFFSET) +#define PIC32MX_RTCC_ALRM (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRM_OFFSET) +#define PIC32MX_RTCC_ALRMCLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMCLR_OFFSET) +#define PIC32MX_RTCC_ALRMSET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMSET_OFFSET) +#define PIC32MX_RTCC_ALRMINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMINV_OFFSET) +#define PIC32MX_RTCC_TIME (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_TIME_OFFSET) +#define PIC32MX_RTCC_TIMECLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_TIMECLR_OFFSET) +#define PIC32MX_RTCC_TIMESET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_TIMESET_OFFSET) +#define PIC32MX_RTCC_TIMEINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_TIMEINV_OFFSET) +#define PIC32MX_RTCC_DATE (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_DATE_OFFSET) +#define PIC32MX_RTCC_DATECLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_DATECLR_OFFSET) +#define PIC32MX_RTCC_DATESET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_DATESET_OFFSET) +#define PIC32MX_RTCC_DATEINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_DATEINV_OFFSET) +#define PIC32MX_RTCC_ALRMTIME (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMTIME_OFFSET) +#define PIC32MX_RTCC_ALRMTIMECLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMTIMECLR_OFFSET) +#define PIC32MX_RTCC_ALRMTIMESET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMTIMESET_OFFSET) +#define PIC32MX_RTCC_ALRMTIMEINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMTIMEINV_OFFSET) +#define PIC32MX_RTCC_ALRMDATE (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMDATE_OFFSET) +#define PIC32MX_RTCC_ALRMDATECLR (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMDATECLR_OFFSET) +#define PIC32MX_RTCC_ALRMDATESET (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMDATESET_OFFSET) +#define PIC32MX_RTCC_ALRMDATEINV (PIC32MX_RTCC_K1BASE+PIC32MX_RTCC_ALRMDATEINV_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* RTC Control Register */ + +#define RTCC_CON_CAL_SHIFT (16) /* Bits 16-25: RTC drift calibration */ +#define RTCC_CON_CAL_MASK (0x3ff << RTCC_CON_CAL_SHIFT) /* 10-bit 2's complement */ +# define RTCC_CON_CAL_MAX (0x1ff << RTCC_CON_CAL_SHIFT) +# define RTCC_CON_CAL_CENTER (0x000 << RTCC_CON_CAL_SHIFT) +# define RTCC_CON_CAL_MIN (0x200 << RTCC_CON_CAL_SHIFT) +#define RTCC_CON_ON (1 << 15) /* Bit 15: RTCC on */ +#define RTCC_CON_FRZ (1 << 14) /* Bit 14: Freeze in debug mode */ +#define RTCC_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define RTCC_CON_RTSECSEL (1 << 9) /* Bit 7: RTCC seconds clock output select */ +#define RTCC_CON_RTCCLKON (1 << 8) /* Bit 6: RTCC clock enable status */ +#define RTCC_CON_RTCWREN (1 << 3) /* Bit 3: RTC value registers write enable */ +#define RTCC_CON_RTCSYNC (1 << 2) /* Bit 2: RTCC value registers read synchronization */ +#define RTCC_CON_HALFSEC (1 << 1) /* Bit 1: Half-second status */ +#define RTCC_CON_RTCOE (1 << 0) /* Bit 0: RTCC output enable */ + +/* RTC ALARM Control Register */ + +#define RTCC_ALRM_ARPT_SHIFT (0) /* Bits 0-7: Alarm repeat counter value */ +#define RTCC_ALRM_ARPT_MASK (0xff << RTCC_ALRM_ARPT_SHIFT) +#define RTCC_ALRM_AMASK_SHIFT (8) /* Bits 8-11: Alarm mask configuration */ +#define RTCC_ALRM_AMASK_MASK (15 << RTCC_ALRM_AMASK_SHIFT) +#define RTCC_ALRM_ALRMSYNC (1 << 12) /* Bit 12: Alarm sync */ +#define RTCC_ALRM_PIV (1 << 13) /* Bit 13: Alarm pulse initial value */ +#define RTCC_ALRM_CHIME (1 << 14) /* Bit 14: Chime enable */ +#define RTCC_ALRM_ALRMEN (1 << 15) /* Bit 15: Alarm enable */ + +/* RTC Time Value Register */ + +#define RTCC_TIME_SEC01_SHIFT (8) /* Bits 8-11: BCD seconds, 1 digit */ +#define RTCC_TIME_SEC01_MASK (15 << RTCC_TIME_SEC01_SHIFT) +#define RTCC_TIME_SEC10_SHIFT (12) /* Bits 12-14: BCD seconds, 10 digits */ +#define RTCC_TIME_SEC10_MASK (7 << RTCC_TIME_SEC10_SHIFT) +#define RTCC_TIME_MIN01_SHIFT (16) /* Bits 16-19: BCD minutes, 1 digit */ +#define RTCC_TIME_MIN01_MASK (15 << RTCC_TIME_MIN01_SHIFT) +#define RTCC_TIME_MIN10_SHIFT (20) /* Bits 20-22: BCD minutes, 10 digits */ +#define RTCC_TIME_MIN10_MASK (7 << RTCC_TIME_MIN10_SHIFT) +#define RTCC_TIME_HR01_SHIFT (24) /* Bits 24-27: BCD hours, 1 digit */ +#define RTCC_TIME_HR01_MASK (15 << RTCC_TIME_HR01_SHIFT) +#define RTCC_TIME_HR10_SHIFT (28) /* Bits 28-29: BCD hours, 10 digits */ +#define RTCC_TIME_HR10_MASK (3 << RTCC_TIME_HR10_SHIFT) + +/* RTC Date Value Register */ + +#define RTCC_DATE_WDAY01_SHIFT (0) /* Bits 0-2: BCD weekday, 1 digit */ +#define RTCC_DATE_WDAY01_MASK (7 << RTCC_DATE_WDAY01_SHIFT) +#define RTCC_DATE_DAY01_SHIFT (8) /* Bits 8-11: BCD day, 1 digit */ +#define RTCC_DATE_DAY01_MASK (15 << RTCC_DATE_DAY01_SHIFT) +#define RTCC_DATE_DAY10_SHIFT (12) /* Bits 12-13: BCD day, 10 digits */ +#define RTCC_DATE_DAY10_MASK (3 << RTCC_DATE_DAY10_SHIFT) +#define RTCC_DATE_MONTH01_SHIFT (16) /* Bits 16-19: BCD month, 1 digit */ +#define RTCC_DATE_MONTH01_MASK (15 << RTCC_DATE_MONTH01_SHIFT) +#define RTCC_DATE_MONTH10 (1 << 20) /* Bit 20: BCD month, 10 digits */ +#define RTCC_DATE_YEAR01_SHIFT (24) /* Bits 24-27: BCD year, 1 digit */ +#define RTCC_DATE_YEAR01_MASK (15 << RTCC_DATE_YEAR01_SHIFT) +#define RTCC_DATE_YEAR10_SHIFT (28) /* Bits 28-31: BCD year, 10 digits */ +#define RTCC_DATE_YEAR10_MASK (15 << RTCC_DATE_YEAR10_SHIFT) + +/* Alarm Time Value Register */ + +#define RTCC_ALRMTIME_SEC01_SHIFT (8) /* Bits 8-11: BCD seconds, 1 digit */ +#define RTCC_ALRMTIME_SEC01_MASK (15 << RTCC_ALRMTIME_SEC01_SHIFT) +#define RTCC_ALRMTIME_SEC10_SHIFT (12) /* Bits 12-14: BCD seconds, 1 digit */ +#define RTCC_ALRMTIME_SEC10_MASK (7 << RTCC_ALRMTIME_SEC10_SHIFT) +#define RTCC_ALRMTIME_MIN01_SHIFT (16) /* Bits 16-19: BCD minutes, 1 digit */ +#define RTCC_ALRMTIME_MIN01_MASK (15 << RTCC_ALRMTIME_MIN01_SHIFT) +#define RTCC_ALRMTIME_MIN10_SHIFT (20) /* Bits 20-22: BCD minutes, 1 digit */ +#define RTCC_ALRMTIME_MIN10_MASK (7 << RTCC_ALRMTIME_MIN10_SHIFT) +#define RTCC_ALRMTIME_HR01_SHIFT (24) /* Bits 24-27: BCD hours, 1 digit */ +#define RTCC_ALRMTIME_HR01_MASK (15 << RTCC_ALRMTIME_HR01_SHIFT) +#define RTCC_ALRMTIME_HR10_SHIFT (28) /* Bits 28-29: BCD hours, 1 digit */ +#define RTCC_ALRMTIME_HR10_MASK (3 << RTCC_ALRMTIME_HR10_SHIFT) + +/* Alarm Date Value Register */ + +#define RTCC_ALRMDATE_WDAY01_SHIFT (0) /* Bits 0-2: BCD weekday, 1 digit */ +#define RTCC_ALRMDATE_WDAY01_MASK (7 << RTCC_ALRMDATE_WDAY01_SHIFT) +#define RTCC_ALRMDATE_DAY01_SHIFT (8) /* Bits 8-11: BCD days, 1 digit */ +#define RTCC_ALRMDATE_DAY01_MASK (15 << RTCC_ALRMDATE_DAY01_SHIFT) +#define RTCC_ALRMDATE_DAY10_SHIFT (12) /* Bits 12-13: BCD days, 1 digit */ +#define RTCC_ALRMDATE_DAY10_MASK (3 << RTCC_ALRMDATE_DAY10_SHIFT) +#define RTCC_ALRMDATE_MONTH01_SHIFT (16) /* Bits 16-19: BCD month, 1 digit */ +#define RTCC_ALRMDATE_MONTH01_MASK (15 << RTCC_ALRMDATE_MONTH01_SHIFT) +#define RTCC_DATE_MONTH10 (1 << 20) /* Bit 20: BCD month, 10 digits */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_RTCC_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-serial.c b/arch/mips/src/pic32mx/pic32mx-serial.c new file mode 100644 index 0000000000000000000000000000000000000000..590c5998a159fd0a664fb7769cafe5594d9af799 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-serial.c @@ -0,0 +1,974 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-serial.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mx-config.h" +#include "chip.h" +#include "pic32mx-uart.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# ifdef CONFIG_PIC32MX_UART2 +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# if defined(CONFIG_PIC32MX_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# ifdef CONFIG_PIC32MX_UART2 +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# else +# undef TTYS1_DEV /* No ttyS1 */ +# endif +# elif defined(CONFIG_PIC32MX_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# else +# undef TTYS0_DEV +# undef TTYS0_DEV +# endif +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of up_earlyserialinit(), up_serialinit(), and + * up_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/* These values describe the set of enabled interrupts */ + +#define IE_RX (1 << 0) +#define IE_TX (1 << 1) + +#define RX_ENABLED(im) (((im) & IE_RX) != 0) +#define TX_ENABLED(im) (((im) & IE_TX) != 0) + +#define ENABLE_RX(im) do { (im) |= IE_RX; } while (0) +#define ENABLE_TX(im) do { (im) |= IE_TX; } while (0) + +#define DISABLE_RX(im) do { (im) &= ~IE_RX; } while (0) +#define DISABLE_TX(im) do { (im) &= ~IE_TX; } while (0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART (for attachment) */ + uint8_t irqe; /* Error IRQ associated with this UART (for enable) */ + uint8_t irqrx; /* RX IRQ associated with this UART (for enable) */ + uint8_t irqtx; /* TX IRQ associated with this UART (for enable) */ + uint8_t irqprio; /* Interrupt priority */ + uint8_t im; /* Interrupt mask state */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5, 6, 7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset); +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im); +static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im); + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_PIC32MX_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MX_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +/* This describes the state of the PIC32MX UART1 port. */ + +#ifdef CONFIG_PIC32MX_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = PIC32MX_UART1_K1BASE, + .baud = CONFIG_UART1_BAUD, + .irq = PIC32MX_IRQ_U1, + .irqe = PIC32MX_IRQSRC_U1E, + .irqrx = PIC32MX_IRQSRC_U1RX, + .irqtx = PIC32MX_IRQSRC_U1TX, + .irqprio = CONFIG_PIC32MX_UART1PRIO, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the PIC32MX UART2 port. */ + +#ifdef CONFIG_PIC32MX_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = PIC32MX_UART2_K1BASE, + .baud = CONFIG_UART2_BAUD, + .irq = PIC32MX_IRQ_U2, + .irqe = PIC32MX_IRQSRC_U2E, + .irqrx = PIC32MX_IRQSRC_U2RX, + .irqtx = PIC32MX_IRQSRC_U2TX, + .irqprio = CONFIG_PIC32MX_UART2PRIO, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in im */ + + flags = enter_critical_section(); + up_rxint(dev, RX_ENABLED(im)); + up_txint(dev, TX_ENABLED(im)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (im) + { + *im = priv->im; + } + up_restoreuartint(dev, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Configure the UART as an RS-232 UART */ + + pic32mx_uartconfigure(priv->uartbase, priv->baud, priv->parity, + priv->bits, priv->stopbits2); +#endif + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set up the interrupt priority */ + + up_prioritize_irq(priv->irq, priv->irqprio); +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(dev, NULL); + + /* Reset hardware and disable Rx and Tx */ + + pic32mx_uartreset(priv->uartbase); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Attach the IRQ */ + + return irq_attach(priv->irq, up_interrupt); +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(dev, NULL); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + int passes; + bool handled; + +#ifdef CONFIG_PIC32MX_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_PIC32MX_UART2 + if (g_uart2priv.irq == irq) + { + dev = &g_uart2port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s *)dev->priv; + DEBUGASSERT(priv); + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Handle error interrupts. This interrupt occurs when any of the + * following error conditions take place: + * - Parity error PERR (UxSTA bit 3) is detected + * - Framing Error FERR (UxSTA bit 2) is detected + * - Overflow condition for the receive buffer OERR (UxSTA bit 1) occurs + */ + +#ifdef CONFIG_DEBUG + if (up_pending_irq(priv->irqe)) + { + /* Clear the pending error interrupt */ + + up_clrpend_irq(priv->irqe); + lldbg("ERROR: interrupt STA: %08x\n", + up_serialin(priv, PIC32MX_UART_STA_OFFSET)); + handled = true; + } +#endif + + /* Handle incoming, received bytes. The RX FIFO is configured to + * interrupt when the RX FIFO is 75% full (that is 6 of 8 for 8-deep + * FIFOs or 3 of 4 for 4-deep FIFOS. + */ + + if (up_pending_irq(priv->irqrx)) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + handled = true; + + /* Clear the pending RX interrupt if the receive buffer is empty. + * Note that interrupts can be lost if the interrupt condition is + * still true when the interrupt is cleared. Keeping the RX + * interrupt pending too long is not a problem because the + * upper half driver will disable RX interrupts if it no + * longer has space to buffer the serial data. + */ + + if ((up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_URXDA) == 0) + { + up_clrpend_irq(priv->irqrx); + } + } + + /* Handle outgoing, transmit bytes The RT FIFO is configured to + * interrupt only when the TX FIFO is empty. There are not many + * options on trigger TX interrupts. The FIFO-not-full might generate + * better through-put but with a higher interrupt rate. FIFO-empty should + * lower the interrupt rate but result in a burstier output. If + * you change this, You will probably need to change the conditions for + * clearing the pending TX interrupt below. + * + * NOTE: When I tried using the FIFO-not-full interrupt trigger, I + * had either lost interrupts, or else a window where I might get + * infinite interrupts. The problem is that there is a race condition + * with trying to clearing the pending interrupt based on the FIFO + * full condition. + */ + + if (up_pending_irq(priv->irqtx)) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + + /* Clear the pending TX interrupt if the TX FIFO is empty. + * Note that interrupts can be lost if the interrupt condition is + * still true when the interrupt is cleared. Keeping the TX + * interrupt pending too long is not a problem: Upper level logic + * will disable the TX interrupt when there is no longer anything + * to be sent. + */ + + if ((up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_UTRMT) != 0) + { + up_clrpend_irq(priv->irqtx); + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + struct inode *inode; + struct uart_dev_s *dev; + struct up_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct up_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that only cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used besued we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + pic32mx_uartconfigure(priv->uartbase, priv->baud, priv->parity, + priv->bits, priv->stopbits2); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Then return the actual received byte */ + + return (int)(up_serialin(priv, PIC32MX_UART_RXREG_OFFSET) & UART_RXREG_MASK); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint8_t im; + + flags = enter_critical_section(); + im = priv->im; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_DEBUG + up_enable_irq(priv->irqe); +#endif + up_enable_irq(priv->irqrx); + ENABLE_RX(im); +#endif + } + else + { +#ifdef CONFIG_DEBUG + up_disable_irq(priv->irqe); +#endif + up_disable_irq(priv->irqrx); + DISABLE_RX(im); + } + priv->im = im; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_URXDA) != 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, PIC32MX_UART_TXREG_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint8_t im; + + flags = enter_critical_section(); + im = priv->im; + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->irqtx); + ENABLE_TX(im); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_disable_irq(priv->irqtx); + DISABLE_TX(im); + } + + priv->im = im; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the Transmit buffer register is not full */ + + return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_UTXBF) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the Transmit shift register is empty */ + + return (up_serialin(priv, PIC32MX_UART_STA_OFFSET) & UART_STA_UTRMT) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit(). + */ + + up_disableuartint(&TTYS0_DEV, NULL); +#ifdef TTYS1_DEV + up_disableuartint(&TTYS1_DEV, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct uart_dev_s *dev = (struct uart_dev_s *)&CONSOLE_DEV; + uint8_t imr; + + up_disableuartint(dev, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreuartint(dev, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: up_earlyserialinit, up_serialinit, and up_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/up_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ +#else /* HAVE_UART_DEVICE */ +void up_earlyserialinit(void) +{ +} + +void up_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/mips/src/pic32mx/pic32mx-spi.c b/arch/mips/src/pic32mx/pic32mx-spi.c new file mode 100644 index 0000000000000000000000000000000000000000..44e79d6b48492d3ebdfb922e037690ff0538aa4d --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-spi.c @@ -0,0 +1,998 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-spi.c + * + * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "pic32mx.h" +#include "pic32mx-spi.h" + +#if defined(CONFIG_PIC32MX_SPI1) || defined(CONFIG_PIC32MX_SPI2) || \ + defined(CONFIG_PIC32MX_SPI3) || defined(CONFIG_PIC32MX_SPI4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration */ + +#ifdef CONFIG_SPI_EXCHANGE + /* See arch/mips/src/pic32mz/pic32mz-spi.c for an implementation */ + +# error CONFIG_SPI_EXCHANGE not supported by this driver +#endif + +/* Debug */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of the SSP driver */ + +struct pic32mx_dev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t base; /* SPI register base address */ +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + uint8_t vector; /* Interrupt vector number(for attaching) */ + uint8_t eirq; /* SPI fault interrupt number */ + uint8_t rxirq; /* SPI receive done interrupt number */ + uint8_t txirq; /* SPI transfer done interrupt number */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Low-level register access */ + +static uint32_t spi_getreg(FAR struct pic32mx_dev_s *priv, + unsigned int offset); +static void spi_putreg(FAR struct pic32mx_dev_s *priv, + unsigned int offset, uint32_t value); + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_SPI1 + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = pic32mx_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = pic32mx_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mx_spi1cmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mx_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct pic32mx_dev_s g_spi1dev = +{ + .spidev = { &g_spi1ops }, + .base = PIC32MX_SPI1_K1BASE, +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + .vector = PIC32MX_IRQ_SPI1, + .eirq = PIC32MX_IRQSRC_SPI1E, + .rxirq = PIC32MX_IRQSRC_SPI1RX, + .txirq = PIC32MX_IRQSRC_SPI1TX, +#endif +}; +#endif + +#ifdef CONFIG_PIC32MX_SPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = pic32mx_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mx_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mx_spi2cmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mx_spi2register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct pic32mx_dev_s g_spi2dev = +{ + .spidev = { &g_spi2ops }, + .base = PIC32MX_SPI2_K1BASE, +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + .vector = PIC32MX_IRQ_SPI2, + .eirq = PIC32MX_IRQSRC_SPI2E, + .rxirq = PIC32MX_IRQSRC_SPI2RX, + .txirq = PIC32MX_IRQSRC_SPI2TX, +#endif +}; +#endif + +#ifdef CONFIG_PIC32MX_SPI3 +static const struct spi_ops_s g_spi3ops = +{ + .lock = spi_lock, + .select = pic32mx_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mx_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mx_spi3cmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mx_spi3register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct pic32mx_dev_s g_spi3dev = +{ + .spidev = { &g_spi3ops }, + .base = PIC32MX_SPI3_K1BASE, +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + .vector = PIC32MX_IRQ_SPI4, + .eirq = PIC32MX_IRQSRC_SPI3E, + .rxirq = PIC32MX_IRQSRC_SPI3RX, + .txirq = PIC32MX_IRQSRC_SPI3TX, +#endif +}; +#endif + +#ifdef CONFIG_PIC32MX_SPI4 +static const struct spi_ops_s g_spi4ops = +{ + .lock = spi_lock, + .select = pic32mx_spi4select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mx_spi4status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mx_spi4cmddata, +#endif + .send = spi_send, + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mx_spi4register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct pic32mx_dev_s g_spi4dev = +{ + .spidev = { &g_spi4ops }, + .base = PIC32MX_SPI4_K1BASE, +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + .vector = PIC32MX_IRQ_SPI4, + .eirq = PIC32MX_IRQSRC_SPI4E, + .rxirq = PIC32MX_IRQSRC_SPI4RX, + .txirq = PIC32MX_IRQSRC_SPI4TX, +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Return the contents of one, 32-bit SPI register + * + * Input Parameters: + * priv - A pointer to a PIC32MX SPI state structure + * offset - Offset from the SPI base address to the register of interest + * + * Returned Value: + * The current contents of the register + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_SPI_REGDEBUG +static uint32_t spi_getreg(FAR struct pic32mx_dev_s *priv, unsigned int offset) +{ + /* Last address, value, and count */ + + static uint32_t prevaddr = 0; + static uint32_t prevalue = 0; + static uint32_t count = 0; + + /* New address and value */ + + uint32_t addr; + uint32_t value; + + /* Read the value from the register */ + + addr = priv->base + offset; + value = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && value == prevalue) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + return value; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + prevalue = value; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%08x\n", addr, value); + return value; +} +#else +static uint32_t spi_getreg(FAR struct pic32mx_dev_s *priv, unsigned int offset) +{ + return getreg32(priv->base + offset); +} +#endif + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to one, 32-bit SPI register + * + * Input Parameters: + * priv - A pointer to a PIC32MX SPI state structure + * offset - Offset from the SPI base address to the register of interest + * value - The value to write to the SPI register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_SPI_REGDEBUG +static void spi_putreg(FAR struct pic32mx_dev_s *priv, unsigned int offset, + uint32_t value) +{ + uint32_t addr; + + /* Get the address to write to */ + + addr = priv->base + offset; + + /* Show the register value being written */ + + lldbg("%08x<-%08x\n", addr, value); + + /* Then do the write */ + + putreg32(value, addr); +} +#else +static void spi_putreg(FAR struct pic32mx_dev_s *priv, unsigned int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + uint32_t divisor; + uint32_t actual; + uint32_t regval; + + spivdbg("Old frequency: %d actual: %d New frequency: %d\n", + priv->frequency, priv->actual, frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* Calculate the divisor + * + * frequency = BOARD_PBCLOCK / (2 * divisor), or + * divisor = (BOARD_PBCLOCK / 2) / frequency + */ + + divisor = (BOARD_PBCLOCK / 2) / frequency; + + /* The a BRG register value is that divisor minus one + * + * frequency = BOARD_PBCLOCK /(2 * (BRG + 1)), or + * BRG = (BOARD_PBCLOCK / 2) / frequency - 1 + */ + + regval = divisor; + if (regval > 0) + { + regval--; + } + + /* Save the new BRG value */ + + spi_putreg(priv, PIC32MX_SPI_BRG_OFFSET, regval); + spivdbg("PBCLOCK: %d frequency: %d divisor: %d BRG: %d\n", + BOARD_PBCLOCK, frequency, divisor, regval); + + /* Calculate the new actual frequency. + * + * frequency = BOARD_PBCLOCK / (2 * divisor) + */ + + actual = (BOARD_PBCLOCK / 2) / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("New frequency: %d Actual: %d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + uint32_t regval; + + spivdbg("Old mode: %d New mode: %d\n", priv->mode, mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CON register appropriately. + * + * Standard terminology is as follows: + * + * Mode CPOL CPHA + * 0 0 0 + * 1 0 1 + * 2 1 0 + * 3 1 1 + * + * CPOL=0: The inactive value of the clock is zero + * CPOL=1: The inactive value of the clock is one + * CPHA=0: Data is captured on the clock's inactive-to-active edge and + * data is propagated on a active-to-inactive edge. + * CPHA=1: Data is captured on the clock's active-to-inactive edge and + * data is propagated on a active-to-inactive edge. + * + * CON Register mapping: + * CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1 + * CPHA=0 corresponds to CON:CKE=1; CPHA=1 corresponds to CON:CKE=1 + * + * In addition, the CON register supports SMP: SPI Data Input Sample + * Phase bit: + * + * 1 = Input data sampled at end of data output time + * 0 = Input data sampled at middle of data output time + * + * Which is hardcoded to 1. + */ + + regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET); + regval &= ~(SPI_CON_CKP | SPI_CON_CKE); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CON_CKE; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CON_CKP; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CON_CKP | SPI_CON_CKE); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(priv, PIC32MX_SPI_CON_OFFSET, regval); + spivdbg("CON: %08x\n", regval); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + uint32_t setting; + uint32_t regval; + + spivdbg("Old nbits: %d New nbits: %d\n", priv->nbits, nbits); + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + + if (nbits != priv->nbits) + { + /* Yes... Set the CON register appropriately */ + + if (nbits == 8) + { + setting = SPI_CON_MODE_8BIT; + } + else if (nbits == 16) + { + setting = SPI_CON_MODE_8BIT; + } + else if (nbits == 32) + { + setting = SPI_CON_MODE_8BIT; + } + else + { + spidbg("Unsupported nbits: %d\n", nbits); + return; + } + + regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET); + regval &= ~SPI_CON_MODE_MASK; + regval |= setting; + regval = spi_getreg(priv, PIC32MX_SPI_CON_OFFSET); + spivdbg("CON: %08x\n", regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + + spivdbg("wd: %04x\n", wd); + + /* Write the data to transmitted to the SPI Data Register */ + + spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)wd); + +#ifdef CONFIG_PIC32MX_SPI_ENHBUF + /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In + * enhanced buffer mode, the SPIRBE bit will be cleared in when the + * receive buffer is not empty. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0); + +#else + /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In + * normal mode, the SPIRBF bit will be set when receive data is available. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0); +#endif + + /* Return the SPI data */ + + return (uint16_t)spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + uint32_t regval; + uint8_t data; + + spivdbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + data = *ptr++; + spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)data); + +#ifdef CONFIG_PIC32MX_SPI_ENHBUF + /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In + * enhanced buffer mode, the SPIRBE bit will be cleared in when the + * receive buffer is not empty. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0); +#else + /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In + * normal mode, the SPIRBF bit will be set when receive data is available. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0); +#endif + + /* Read from the buffer register to clear the status bit */ + + regval = spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET); + UNUSED(regval); + nwords--; + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) +{ + FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev; + FAR uint8_t *ptr = (FAR uint8_t *)buffer; + + spivdbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write some dummy data to the SPI Data Register in order to clock the + * read data. + */ + + spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, 0xff); + +#ifdef CONFIG_PIC32MX_SPI_ENHBUF + /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In + * enhanced buffer mode, the SPIRBE bit will be cleared in when the + * receive buffer is not empty. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0); +#else + /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In + * normal mode, the SPIRBF bit will be set when receive data is available. + */ + + while ((spi_getreg(priv, PIC32MX_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0); +#endif + + /* Read the received data from the SPI Data Register */ + + *ptr++ = (uint8_t)spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET); + nwords--; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *pic32mx_spibus_initialize(int port) +{ + FAR struct pic32mx_dev_s *priv; + irqstate_t flags; + uint32_t regval; + + spivdbg("port: %d\n", port); + + /* Select the SPI state structure for this port */ + +#ifdef CONFIG_PIC32MX_SPI1 + if (port == 1) + { + priv = &g_spi1dev; + } + else +#endif +#ifdef CONFIG_PIC32MX_SPI2 + if (port == 2) + { + priv = &g_spi2dev; + } + else +#endif +#ifdef CONFIG_PIC32MX_SPI3 + if (port == 3) + { + priv = &g_spi3dev; + } + else +#endif +#ifdef CONFIG_PIC32MX_SPI4 + if (port == 4) + { + priv = &g_spi4dev; + } + else +#endif + { + spidbg("Unsuppport port: %d\n", port); + return NULL; + } + + /* Disable SPI interrupts */ + + flags = enter_critical_section(); +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + up_disable_irq(priv->eirq); + up_disable_irq(priv->txirq); + up_disable_irq(priv->rxirq); +#endif + + /* Stop and reset the SPI module by clearing the ON bit in the CON register. */ + + spi_putreg(priv, PIC32MX_SPI_CON_OFFSET, 0); + + /* Clear the receive buffer by reading from the BUF register */ + + regval = spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET); + +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + /* Attach the interrupt vector. We do this early to make sure that the + * resource is available. + */ + + ret = irq_attach(priv->vector, spi_interrupt); + if (ret < 0) + { + spidbg("Failed to attach vector: %d port: %d\n", priv->vector, port); + goto errout; + } +#endif + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Clear the SPIROV overflow bit (SPIxSTAT:6). */ + + spi_putreg(priv, PIC32MX_SPI_STATCLR_OFFSET, SPI_STAT_SPIROV); + + /* Initial settings 8 bit + master mode + mode 0. NOTE that MSSEN + * not set: The slave select pin must be driven manually via the + * board-specific pic32mx_spiNselect() interface. + */ + + regval = (SPI_CON_MSTEN | SPI_CON_SMP | SPI_CON_MODE_8BIT | SPI_CON_ON); + + /* Set the ENHBUF bit if using Enhanced Buffer mode. */ + +#ifdef CONFIG_PIC32MX_SPI_ENHBUF + regval |= (SPI_CON_ENHBUF | SPI_CON_RTXISEL_HALF | SPI_CON_STXISEL_HALF); +#endif + spi_putreg(priv, PIC32MX_SPI_CON_OFFSET, regval); + spivdbg("CON: %08x\n", regval); + + /* Set the initial SPI configuration */ + + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS + /* Enable interrupts at the SPI controller */ + + up_enable_irq(priv->eirq); + up_enable_irq(priv->txirq); + up_enable_irq(priv->rxirq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the SPI interrupt priority */ + + ret = up_prioritize_irq(priv->vector, CONFIG_PIC32MX_SPI_PRIORITY) + if (ret < 0) + { + spidbg("up_prioritize_irq failed: %d\n", ret); + goto errout; + } +#endif +#endif + + /* Enable interrupts at the interrupt controller */ + + leave_critical_section(flags); + return &priv->spidev; + +#ifdef CONFIG_PIC32MX_SPI_INTERRUPTS +errout: + leave_critical_section(flags); + return NULL; +#endif +} + +#endif /* CONFIG_PIC32MX_SPI */ + diff --git a/arch/mips/src/pic32mx/pic32mx-spi.h b/arch/mips/src/pic32mx/pic32mx-spi.h new file mode 100644 index 0000000000000000000000000000000000000000..cccafd5eddd2d403bb476369b780415f89411533 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-spi.h @@ -0,0 +1,291 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-spi.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_SPI_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MX_SPI_CON_OFFSET 0x0000 /* SPI control register */ +#define PIC32MX_SPI_CONCLR_OFFSET 0x0004 /* SPI control clear register */ +#define PIC32MX_SPI_CONSET_OFFSET 0x0008 /* SPI control set register */ +#define PIC32MX_SPI_CONINV_OFFSET 0x000c /* SPI control invert register */ +#define PIC32MX_SPI_STAT_OFFSET 0x0010 /* SPI status register */ +#define PIC32MX_SPI_STATCLR_OFFSET 0x0014 /* SPI status clear register */ +#define PIC32MX_SPI_BUF_OFFSET 0x0020 /* SPI buffer register */ +#define PIC32MX_SPI_BRG_OFFSET 0x0030 /* SPI baud rate register */ +#define PIC32MX_SPI_BRGCLR_OFFSET 0x0034 /* SPI baud rate clear register */ +#define PIC32MX_SPI_BRGSET_OFFSET 0x0038 /* SPI baud rate set register */ +#define PIC32MX_SPI_BRGINV_OFFSET 0x003c /* SPI baud rate invert register */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +#define PIC32MX_SPI_CON2_OFFSET 0x0040 /* SPI control register 2*/ +#endif + +/* Register Addresses *******************************************************/ + +#ifdef PIC32MX_SPI1_K1BASE +# define PIC32MX_SPI1_CON (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_CON_OFFSET) +# define PIC32MX_SPI1_CONCLR (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_CONCLR_OFFSET) +# define PIC32MX_SPI1_CONSET (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_CONSET_OFFSET) +# define PIC32MX_SPI1_CONINV (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_CONINV_OFFSET) +# define PIC32MX_SPI1_STAT (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_STAT_OFFSET) +# define PIC32MX_SPI1_STATCLR (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_STATCLR_OFFSET) +# define PIC32MX_SPI1_BUF (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_BUF_OFFSET) +# define PIC32MX_SPI1_BRG (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_BRG_OFFSET) +# define PIC32MX_SPI1_BRGCLR (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_BRGCLR_OFFSET) +# define PIC32MX_SPI1_BRGSET (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_BRGSET_OFFSET) +# define PIC32MX_SPI1_BRGINV (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_BRGINV_OFFSET) +# if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_SPI1_CON2 (PIC32MX_SPI1_K1BASE+PIC32MX_SPI_CON2_OFFSET) +# endif +#endif + +#ifdef PIC32MX_SPI2_K1BASE +# define PIC32MX_SPI2_CON (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_CON_OFFSET) +# define PIC32MX_SPI2_CONCLR (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_CONCLR_OFFSET) +# define PIC32MX_SPI2_CONSET (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_CONSET_OFFSET) +# define PIC32MX_SPI2_CONINV (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_CONINV_OFFSET) +# define PIC32MX_SPI2_STAT (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_STAT_OFFSET) +# define PIC32MX_SPI2_STATCLR (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_STATCLR_OFFSET) +# define PIC32MX_SPI2_BUF (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_BUF_OFFSET) +# define PIC32MX_SPI2_BRG (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_BRG_OFFSET) +# define PIC32MX_SPI2_BRGCLR (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_BRGCLR_OFFSET) +# define PIC32MX_SPI2_BRGSET (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_BRGSET_OFFSET) +# define PIC32MX_SPI2_BRGINV (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_BRGINV_OFFSET) +# if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define PIC32MX_SPI2_CON2 (PIC32MX_SPI2_K1BASE+PIC32MX_SPI_CON2_OFFSET) +# endif +#endif + +#ifdef PIC32MX_SPI3_K1BASE +# define PIC32MX_SPI3_CON (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_CON_OFFSET) +# define PIC32MX_SPI3_CONCLR (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_CONCLR_OFFSET) +# define PIC32MX_SPI3_CONSET (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_CONSET_OFFSET) +# define PIC32MX_SPI3_CONINV (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_CONINV_OFFSET) +# define PIC32MX_SPI3_STAT (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_STAT_OFFSET) +# define PIC32MX_SPI3_STATCLR (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_STATCLR_OFFSET) +# define PIC32MX_SPI3_BUF (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_BUF_OFFSET) +# define PIC32MX_SPI3_BRG (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_BRG_OFFSET) +# define PIC32MX_SPI3_BRGCLR (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_BRGCLR_OFFSET) +# define PIC32MX_SPI3_BRGSET (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_BRGSET_OFFSET) +# define PIC32MX_SPI3_BRGINV (PIC32MX_SPI3_K1BASE+PIC32MX_SPI_BRGINV_OFFSET) +#endif + +#ifdef PIC32MX_SPI4_K1BASE +# define PIC32MX_SPI4_CON (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_CON_OFFSET) +# define PIC32MX_SPI4_CONCLR (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_CONCLR_OFFSET) +# define PIC32MX_SPI4_CONSET (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_CONSET_OFFSET) +# define PIC32MX_SPI4_CONINV (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_CONINV_OFFSET) +# define PIC32MX_SPI4_STAT (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_STAT_OFFSET) +# define PIC32MX_SPI4_STATCLR (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_STATCLR_OFFSET) +# define PIC32MX_SPI4_BUF (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_BUF_OFFSET) +# define PIC32MX_SPI4_BRG (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_BRG_OFFSET) +# define PIC32MX_SPI4_BRGCLR (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_BRGCLR_OFFSET) +# define PIC32MX_SPI4_BRGSET (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_BRGSET_OFFSET) +# define PIC32MX_SPI4_BRGINV (PIC32MX_SPI4_K1BASE+PIC32MX_SPI_BRGINV_OFFSET) +#endif + +/* Register Bit-Field Definitions *******************************************/ + +/* SPI control register */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define SPI_CON_RTXISEL_SHIFT (0) /* Bits 0-1: SPI Receive Buffer Full Interrupt Mode */ +# define SPI_CON_RTXISEL_MASK (3 << SPI_CON_RTXISEL_SHIFT) +# define SPI_CON_RTXISEL_EMPTY (0 << SPI_CON_RTXISEL_SHIFT) /* Buffer empty */ +# define SPI_CON_RTXISEL_NEMPTY (1 << SPI_CON_RTXISEL_SHIFT) /* Buffer not empty */ +# define SPI_CON_RTXISEL_HALF (2 << SPI_CON_RTXISEL_SHIFT) /* Buffer half full or more */ +# define SPI_CON_RTXISEL_FULL (3 << SPI_CON_RTXISEL_SHIFT) /* Buffer full */ +# define SPI_CON_STXISEL_SHIFT (2) /* Bits 2-3: SPI Transmit Buffer Empty Interrupt Mode */ +# define SPI_CON_STXISEL_MASK (3 << SPI_CON_STXISEL_SHIFT) +# define SPI_CON_STXISEL_DONE (0 << SPI_CON_STXISEL_SHIFT) /* Buffer empty (and data shifted out) */ +# define SPI_CON_STXISEL_EMPTY (1 << SPI_CON_STXISEL_SHIFT) /* Buffer empty */ +# define SPI_CON_STXISEL_HALF (2 << SPI_CON_STXISEL_SHIFT) /* Buffer half empty or more */ +# define SPI_CON_STXISEL_NFULL (3 << SPI_CON_STXISEL_SHIFT) /* Buffer not full */ +#endif + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define SPI_CON_DISSDI (1 << 4) /* Bit 4: Disable SDI */ +#else + /* Bit 4: Reserved */ +#endif + +#define SPI_CON_MSTEN (1 << 5) /* Bits 5: Master mode enable */ +#define SPI_CON_CKP (1 << 6) /* Bits 6: Clock polarity select */ +#define SPI_CON_SSEN (1 << 7) /* Bits 7: Slave select enable (slave mode) */ +#define SPI_CON_CKE (1 << 8) /* Bits 8: SPI clock edge select */ +#define SPI_CON_SMP (1 << 9) /* Bits 9: SPI data input sample phase */ +#define SPI_CON_MODE_SHIFT (10) /* Bits 10-11: 32/16-Bit Communication Select */ +#define SPI_CON_MODE_MASK (3 << SPI_CON_MODE_SHIFT) +# define SPI_CON_MODE_8BIT (0 << SPI_CON_MODE_SHIFT) /* 8-bit data width */ +# define SPI_CON_MODE_16BIT (1 << SPI_CON_MODE_SHIFT) /* 16-bit data width */ +# define SPI_CON_MODE_32BIT (2 << SPI_CON_MODE_SHIFT) /* 32-bit data width */ +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + /* With AUDEN=1: */ +# define SPI_CON_MODE_161616 (0 << SPI_CON_MODE_SHIFT) /* 16-bit data, 16-bit FIFO, 16-bit channel */ +# define SPI_CON_MODE_161632 (1 << SPI_CON_MODE_SHIFT) /* 16-bit data, 16-bit FIFO, 32-bit channel */ +# define SPI_CON_MODE_323232 (2 << SPI_CON_MODE_SHIFT) /* 32-bit data, 32-bit FIFO, 32-bit channel */ +# define SPI_CON_MODE_243232 (3 << SPI_CON_MODE_SHIFT) /* 24-bit data, 32-bit FIFO, 32-bit channel */ +#endif +#define SPI_CON_DISSDO (1 << 12) /* Bits 12: Disable SDOx pin */ +#define SPI_CON_SIDL (1 << 13) /* Bits 13: Stop in idle mode */ +#if !defined(CHIP_PIC32MX1) && !defined(CHIP_PIC32MX2) +# define SPI_CON_FRZ (1 << 14) /* Bits 14: Freeze in debug exception */ +#endif +#define SPI_CON_ON (1 << 15) /* Bits 15: SPI peripheral on */ +#define SPI_CON_ENHBUF (1 << 16) /* Bits 16: Enhanced buffer enable */ +#define SPI_CON_SPIFE (1 << 17) /* Bits 17: Frame sync pulse edge select */ +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + /* Bits 18-22: Reserved */ +# define SPI_CON_MCLKSEL (1 << 18) /* Master clock enable */ +#else + /* Bits 18-23: Reserved */ +#endif +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define SPI_CON_FRMCNT_SHIFT (24) /* Bits 24-26: Frame Sync Pulse Counter bits */ +# define SPI_CON_FRMCNT_MASK (7 << SPI_CON_FRMCNT_SHIFT) +# define SPI_CON_FRMCNT_CHAR1 (0 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse each char */ +# define SPI_CON_FRMCNT_CHAR2 (1 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 2 chars */ +# define SPI_CON_FRMCNT_CHAR4 (2 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 4 chars */ +# define SPI_CON_FRMCNT_CHAR8 (3 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 8 chars */ +# define SPI_CON_FRMCNT_CHAR16 (4 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 16 chars */ +# define SPI_CON_FRMCNT_CHAR32 (5 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 32 chars */ +# define SPI_CON_FRMSYPW (1 << 27) /* Bits 27: Frame sync pulse width */ +# define SPI_CON_MSSEN (1 << 28) /* Bits 28: Master mode slave select enable */ +#endif +#define SPI_CON_FRMPOL (1 << 29) /* Bits 29: Frame sync polarity */ +#define SPI_CON_FRMSYNC (1 << 30) /* Bits 30: Frame sync pulse direction control on SSx pin */ +#define SPI_CON_FRMEN (1 << 31) /* Bits 31: Framed SPI support */ + +/* SPI control register 2 */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + +# define SPI2_CON2_AUDMOD_SHIFT (0) /* Bits 0-1: Audio Protocol Mode */ +# define SPI2_CON2_AUDMOD_MASK (3 << SPI2_CON2_AUDMOD_SHIFT) +# define SPI2_CON2_AUDMOD_I2S (0 << SPI2_CON2_AUDMOD_SHIFT) /* I2S mode */ +# define SPI2_CON2_AUDMOD_LJ (1 << SPI2_CON2_AUDMOD_SHIFT) /* Left Justified mode */ +# define SPI2_CON2_AUDMOD_RJ (2 << SPI2_CON2_AUDMOD_SHIFT) /* Right Justified mode */ +# define SPI2_CON2_AUDMOD_PCM (3 << SPI2_CON2_AUDMOD_SHIFT) /* PCM/DSP mode */ + /* Bit 2: Reserved */ +# define SPI2_CON2_AUDMONO (1 << 3) /* Bit 3: Transmit Audio Data Format */ + /* Bits 5-6: Reserved */ +# define SPI2_CON2_AUDEN (1 << 7) /* Bit 7: Enable Audio CODEC Support */ +# define SPI2_CON2_IGNTUR (1 << 8) /* Bit 8: Ignore Transmit Underrun bit */ +# define SPI2_CON2_IGNROV (1 << 9) /* Bit 9: Ignore Receive Overflow */ +# define SPI2_CON2_SPITUREN (1 << 10) /* Bit 10: Enable Interrupt Events via SPITUR */ +# define SPI2_CON2_SPIROVEN (1 << 11) /* Bit 11: Enable Interrupt Events via SPIROV */ +# define SPI2_CON2_FRMERREN (1 << 12) /* Bit 12: Enable Interrupt Events via FRMERR */ + /* Bits 13-14: Reserved */ +# define SPI2_CON2_SPISGNEXT (1 << 15) /* Bit 15 : Sign Extend Read Data from the RX FIFO */ + /* Bits 16-31: Reserved */ +#endif + +/* SPI status register */ + +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) +# define SPI_STAT_SPIRBF (1 << 0) /* Bit 0: SPI receive buffer full status */ +# define SPI_STAT_SPITBE (1 << 3) /* Bit 3: SPI transmit buffer empty status */ +# define SPI_STAT_SPIROV (1 << 6) /* Bit 6: Receive overflow flag */ +# define SPI_STAT_SPIBUSY (1 << 11) /* Bit 11: SPI activity status */ +#elif defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) || defined(CHIP_PIC32MX5) || \ + defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define SPI_STAT_SPIRBF (1 << 0) /* Bit 0: SPI receive buffer full status */ +# define SPI_STAT_SPITBF (1 << 1) /* Bit 1: SPI transmit buffer full status */ +# define SPI_STAT_SPITBE (1 << 3) /* Bit 3: SPI transmit buffer empty status */ +# define SPI_STAT_SPIRBE (1 << 5) /* Bit 5: RX FIFO Empty */ +# define SPI_STAT_SPIROV (1 << 6) /* Bit 6: Receive overflow flag */ +# define SPI_STAT_SRMT (1 << 7) /* Bit 6: Shift Register Empty */ +# define SPI_STAT_SPITUR (1 << 8) /* Bit 8: Transmit under run */ +# define SPI_STAT_SPIBUSY (1 << 11) /* Bit 11: SPI activity status */ +# if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define SPI_STAT_FRMERR (1 << 12) /* Bit 12: SPI Frame Error status */ +# endif +# define SPI_STAT_TXBUFELM_SHIFT (16) /* Bits 16-20: Transmit Buffer Element Count bits */ +# define SPI_STAT_TXBUFELM_MASK (31 << SPI_STAT_TXBUFELM_SHIFT) +# define SPI_STAT_RXBUFELM_SHIFT (24) /* Bits 24-28: Receive Buffer Element Count bits */ +# define SPI_STAT_RXBUFELM_MASK (31 << SPI_STAT_RXBUFELM_SHIFT) +#endif + +/* SPI buffer register (32-bits wide) */ + +/* SPI baud rate register */ + +#define SPI_BRG_MASK 0x1ff + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_SPI_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-timer.h b/arch/mips/src/pic32mx/pic32mx-timer.h new file mode 100644 index 0000000000000000000000000000000000000000..47c78f1138963a09c0dcc12c079c3eb703437658 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-timer.h @@ -0,0 +1,223 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-timer.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_TIMER_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +#if CHIP_NTIMERS > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_TIMER_CON_OFFSET 0x0000 /* Timer control register */ +#define PIC32MX_TIMER_CONCLR_OFFSET 0x0004 /* Timer control clear register */ +#define PIC32MX_TIMER_CONSET_OFFSET 0x0008 /* Timer control set register */ +#define PIC32MX_TIMER_CONINV_OFFSET 0x000c /* Timer control invert register */ +#define PIC32MX_TIMER_CNT_OFFSET 0x0010 /* Timer count register */ +#define PIC32MX_TIMER_CNTCLR_OFFSET 0x0014 /* Timer count clear register */ +#define PIC32MX_TIMER_CNTSET_OFFSET 0x0018 /* Timer count set register */ +#define PIC32MX_TIMER_CNTINV_OFFSET 0x001c /* Timer count invert register */ +#define PIC32MX_TIMER_PR_OFFSET 0x0020 /* Timer period register */ +#define PIC32MX_TIMER_PRCLR_OFFSET 0x0024 /* Timer period clear register */ +#define PIC32MX_TIMER_PRSET_OFFSET 0x0028 /* Timer period set register */ +#define PIC32MX_TIMER_PRINV_OFFSET 0x002c /* Timer period invert register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_TIMER_CON(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CON_OFFSET) +#define PIC32MX_TIMER_CONCLR(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CONCLR_OFFSET) +#define PIC32MX_TIMER_CONSET(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CONSET_OFFSET) +#define PIC32MX_TIMER_CONINV(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CONINV_OFFSET) +#define PIC32MX_TIMER_CNT(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CNT_OFFSET) +#define PIC32MX_TIMER_CNTCLR(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CNTCLR_OFFSET) +#define PIC32MX_TIMER_CNTSET(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CNTSET_OFFSET) +#define PIC32MX_TIMER_CNTINV(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_CNTINV_OFFSET) +#define PIC32MX_TIMER_PR(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_PR_OFFSET) +#define PIC32MX_TIMER_PRCLR(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_PRCLR_OFFSET) +#define PIC32MX_TIMER_PRSET(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_PRSET_OFFSET) +#define PIC32MX_TIMER_PRINV(n) (PIC32MX_TIMER_K1BASE(n)+PIC32MX_TIMER_PRINV_OFFSET) + +#define PIC32MX_TIMER1_CON (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CON_OFFSET) +#define PIC32MX_TIMER1_CONCLR (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CONCLR_OFFSET) +#define PIC32MX_TIMER1_CONSET (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CONSET_OFFSET) +#define PIC32MX_TIMER1_CONINV (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CONINV_OFFSET) +#define PIC32MX_TIMER1_CNT (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CNT_OFFSET) +#define PIC32MX_TIMER1_CNTCLR (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CNTCLR_OFFSET) +#define PIC32MX_TIMER1_CNTSET (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CNTSET_OFFSET) +#define PIC32MX_TIMER1_CNTINV (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_CNTINV_OFFSET) +#define PIC32MX_TIMER1_PR (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_PR_OFFSET) +#define PIC32MX_TIMER1_PRCLR (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_PRCLR_OFFSET) +#define PIC32MX_TIMER1_PRSET (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_PRSET_OFFSET) +#define PIC32MX_TIMER1_PRINV (PIC32MX_TIMER1_K1BASE+PIC32MX_TIMER_PRINV_OFFSET) + +#if CHIP_NTIMERS > 1 +# define PIC32MX_TIMER2_CON (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CON_OFFSET) +# define PIC32MX_TIMER2_CONCLR (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CONCLR_OFFSET) +# define PIC32MX_TIMER2_CONSET (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CONSET_OFFSET) +# define PIC32MX_TIMER2_CONINV (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CONINV_OFFSET) +# define PIC32MX_TIMER2_CNT (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CNT_OFFSET) +# define PIC32MX_TIMER2_CNTCLR (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CNTCLR_OFFSET) +# define PIC32MX_TIMER2_CNTSET (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CNTSET_OFFSET) +# define PIC32MX_TIMER2_CNTINV (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_CNTINV_OFFSET) +# define PIC32MX_TIMER2_PR (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_PR_OFFSET) +# define PIC32MX_TIMER2_PRCLR (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_PRCLR_OFFSET) +# define PIC32MX_TIMER2_PRSET (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_PRSET_OFFSET) +# define PIC32MX_TIMER2_PRINV (PIC32MX_TIMER2_K1BASE+PIC32MX_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 2 +# define PIC32MX_TIMER3_CON (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CON_OFFSET) +# define PIC32MX_TIMER3_CONCLR (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CONCLR_OFFSET) +# define PIC32MX_TIMER3_CONSET (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CONSET_OFFSET) +# define PIC32MX_TIMER3_CONINV (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CONINV_OFFSET) +# define PIC32MX_TIMER3_CNT (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CNT_OFFSET) +# define PIC32MX_TIMER3_CNTCLR (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CNTCLR_OFFSET) +# define PIC32MX_TIMER3_CNTSET (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CNTSET_OFFSET) +# define PIC32MX_TIMER3_CNTINV (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_CNTINV_OFFSET) +# define PIC32MX_TIMER3_PR (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_PR_OFFSET) +# define PIC32MX_TIMER3_PRCLR (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_PRCLR_OFFSET) +# define PIC32MX_TIMER3_PRSET (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_PRSET_OFFSET) +# define PIC32MX_TIMER3_PRINV (PIC32MX_TIMER3_K1BASE+PIC32MX_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 3 +# define PIC32MX_TIMER4_CON (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CON_OFFSET) +# define PIC32MX_TIMER4_CONCLR (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CONCLR_OFFSET) +# define PIC32MX_TIMER4_CONSET (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CONSET_OFFSET) +# define PIC32MX_TIMER4_CONINV (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CONINV_OFFSET) +# define PIC32MX_TIMER4_CNT (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CNT_OFFSET) +# define PIC32MX_TIMER4_CNTCLR (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CNTCLR_OFFSET) +# define PIC32MX_TIMER4_CNTSET (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CNTSET_OFFSET) +# define PIC32MX_TIMER4_CNTINV (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_CNTINV_OFFSET) +# define PIC32MX_TIMER4_PR (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_PR_OFFSET) +# define PIC32MX_TIMER4_PRCLR (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_PRCLR_OFFSET) +# define PIC32MX_TIMER4_PRSET (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_PRSET_OFFSET) +# define PIC32MX_TIMER4_PRINV (PIC32MX_TIMER4_K1BASE+PIC32MX_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 4 +# define PIC32MX_TIMER5_CON (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CON_OFFSET) +# define PIC32MX_TIMER5_CONCLR (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CONCLR_OFFSET) +# define PIC32MX_TIMER5_CONSET (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CONSET_OFFSET) +# define PIC32MX_TIMER5_CONINV (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CONINV_OFFSET) +# define PIC32MX_TIMER5_CNT (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CNT_OFFSET) +# define PIC32MX_TIMER5_CNTCLR (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CNTCLR_OFFSET) +# define PIC32MX_TIMER5_CNTSET (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CNTSET_OFFSET) +# define PIC32MX_TIMER5_CNTINV (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_CNTINV_OFFSET) +# define PIC32MX_TIMER5_PR (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_PR_OFFSET) +# define PIC32MX_TIMER5_PRCLR (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_PRCLR_OFFSET) +# define PIC32MX_TIMER5_PRSET (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_PRSET_OFFSET) +# define PIC32MX_TIMER5_PRINV (PIC32MX_TIMER5_K1BASE+PIC32MX_TIMER_PRINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***************************************************/ + +/* Timer control register */ + +#define TIMER_CON_TCS (1 << 1) /* Bit 1: Timer clock source select (all) */ +#define TIMER1_CON_TSYNC (1 << 2) /* Bit 2: Timer external clock input synchronization selection (timer 1 only) */ +#define TIMER_CON_T32 (1 << 3) /* Bit 2: 32-bit timer mode select (even timers only) */ +#define TIMER_CON_TCKPS_SHIFT (4) /* Bits 4-6: Timer input clock prescale select (all except timer 1) */ +#define TIMER_CON_TCKPS_MASK (7 << TIMER_CON_TCKPS_SHIFT) +# define TIMER_CON_TCKPS_1 (0 << TIMER_CON_TCKPS_SHIFT) /* 1:1 prescale value */ +# define TIMER_CON_TCKPS_2 (1 << TIMER_CON_TCKPS_SHIFT) /* 1:2 prescale value */ +# define TIMER_CON_TCKPS_4 (2 << TIMER_CON_TCKPS_SHIFT) /* 1:4 prescale value */ +# define TIMER_CON_TCKPS_8 (3 << TIMER_CON_TCKPS_SHIFT) /* 1:8 prescale value */ +# define TIMER_CON_TCKPS_16 (4 << TIMER_CON_TCKPS_SHIFT) /* 1:16 prescale value */ +# define TIMER_CON_TCKPS_32 (5 << TIMER_CON_TCKPS_SHIFT) /* 1:32 prescale value */ +# define TIMER_CON_TCKPS_64 (6 << TIMER_CON_TCKPS_SHIFT) /* 1:64 prescale value */ +# define TIMER_CON_TCKPS_256 (7 << TIMER_CON_TCKPS_SHIFT) /* 1:256 prescale value */ +#define TIMER1_CON_TCKPS_SHIFT (4) /* Bits 4-5: Timer input clock prescale select (timer 1 only) */ +#define TIMER1_CON_TCKPS_MASK (3 << TIMER1_CON_TCKPS_SHIFT) +# define TIMER1_CON_TCKPS_1 (0 << TIMER1_CON_TCKPS_SHIFT) /* 1:1 prescale value */ +# define TIMER1_CON_TCKPS_8 (1 << TIMER1_CON_TCKPS_SHIFT) /* 1:8 prescale value */ +# define TIMER1_CON_TCKPS_64 (2 << TIMER1_CON_TCKPS_SHIFT) /* 1:64 prescale value */ +# define TIMER1_CON_TCKPS_256 (3 << TIMER1_CON_TCKPS_SHIFT) /* 1:256 prescale value */ +#define TIMER_CON_TGATE (1 << 7) /* Bit 7: Timer gated time accumulation enable (all) */ +#define TIMER1_CON_TWIP (1 << 11) /* Bit 11: Asynchronous timer write in progress (timer 1 only) */ +#define TIMER1_CON_TWDIS (1 << 12) /* Bit 12: Asynchronous timer write disable (timer 1 only) */ +#define TIMER_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode (all) */ +#define TIMER_CON_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode (all) */ +#define TIMER_CON_ON (1 << 15) /* Bit 15: Timer on (all) */ + +/* Timer count register */ + +#define TIMER_CNT_MASK 0xffff /* 16-bit timer counter value */ + +/* Timer period register */ + +#define TIMER_PR_MASK 0xffff /* 16-bit timer period value */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NTIMERS > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_TIMER_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-timerisr.c b/arch/mips/src/pic32mx/pic32mx-timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..4543c638e4be959c8df91bfd57e2228300ea462f --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-timerisr.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "pic32mx-config.h" +#include "pic32mx-timer.h" +#include "pic32mx-int.h" +#include "pic32mx.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Timer Setup **************************************************************/ +/* Timer 1 is a type A timer. Setting the TCS bit in the timer control + * register will select the SOSC as the clock source. Otherwise, PBCLOCK + * is the clock source. + */ + +#ifdef BOARD_TIMER1_SOSC +# define TIMER1_SRC_FREQ BOARD_SOSC_FREQ +# define TIMER1_CON_TCS TIMER_CON_TCS +#else +# define TIMER1_SRC_FREQ BOARD_PBCLOCK +# define TIMER1_CON_TCS (0) +#endif + +/* Select a timer 1 prescale value. Our goal is to select the timer MATCH + * register value given the timer 1 input clock frequency and the desired + * system timer frequency: + * + * TIMER1_MATCH = TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC + * + * We want the largest possible value for MATCH that is less than 65,535, the + * maximum value for the 16-bit timer register: + * + * TIMER1_PRESCALE >= TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535 + * + * Timer 1 does not have very many options for the prescaler value. So we + * can pick the best by brute force. Example: + * + * Example 1. Given: + * BOARD_TIMER1_SOSC = Defined + * BOARD_SOSC_FREQ = 32768 + * CLOCKS_PER_SEC = 100 + * Then: + * OPTIMAL_PRESCALE = 1 + * TIMER1_PRESCALE = 1 + * TIMER1_MATCH = 327 -> 100.3 ticks/sec + * + * Example 2. Given: + * BOARD_TIMER1_SOSC = Not defined + * BOARD_PBCLOCK = 60000000 + * CLOCKS_PER_SEC = 100 + * Then: + * OPTIMAL_PRESCALE = 9.2 + * TIMER1_PRESCALE = 64 + * TIMER1_MATCH = 9375 -> 100.0 ticks/sec + */ + +#define OPTIMAL_PRESCALE (TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535) +#if OPTIMAL_PRESCALE <= 1 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1 +# define TIMER1_PRESCALE 1 +#elif OPTIMAL_PRESCALE <= 8 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_8 +# define TIMER1_PRESCALE 8 +#elif OPTIMAL_PRESCALE <= 64 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_64 +# define TIMER1_PRESCALE 64 +#elif OPTIMAL_PRESCALE <= 256 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_256 +# define TIMER1_PRESCALE 256 +#else +# error "This timer frequency cannot be represented" +#endif + +#define TIMER1_MATCH (TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Clear the pending timer interrupt */ + + putreg32(INT_T1, PIC32MX_INT_IFS0CLR); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Configure and enable TIMER1. Used the computed TCKPS divider and timer + * match value. The source will be either the internal PBCLOCK (TCS=0) or + * the external SOSC (TCS=1) + */ + + putreg32((TIMER1_CON_TCKPS | TIMER1_CON_TCS), PIC32MX_TIMER1_CON); + putreg32(0, PIC32MX_TIMER1_CNT); + putreg32(TIMER1_MATCH-1, PIC32MX_TIMER1_PR); + putreg32(TIMER_CON_ON, PIC32MX_TIMER1_CONSET); + + /* Configure the timer interrupt */ + + up_clrpend_irq(PIC32MX_IRQSRC_T1); +#ifdef CONFIG_ARCH_IRQPRIO + (void)up_prioritize_irq(PIC32MX_IRQ_T1, CONFIG_PIC32MX_T1PRIO); +#endif + + /* Attach the timer interrupt vector */ + + (void)irq_attach(PIC32MX_IRQ_T1, (xcpt_t)up_timerisr); + + /* And enable the timer interrupt */ + + up_enable_irq(PIC32MX_IRQSRC_T1); +} diff --git a/arch/mips/src/pic32mx/pic32mx-uart.h b/arch/mips/src/pic32mx/pic32mx-uart.h new file mode 100644 index 0000000000000000000000000000000000000000..c348c6c10ae26efeefaf9993d454b203cb62482f --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-uart.h @@ -0,0 +1,278 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-uart.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_UART_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_UART_MODE_OFFSET 0x0000 /* UARTx mode register */ +#define PIC32MX_UART_MODECLR_OFFSET 0x0004 /* UARTx mode clear register */ +#define PIC32MX_UART_MODESET_OFFSET 0x0008 /* UARTx mode set register */ +#define PIC32MX_UART_MODEINV_OFFSET 0x000c /* UARTx mode invert register */ +#define PIC32MX_UART_STA_OFFSET 0x0010 /* UARTx status and control register */ +#define PIC32MX_UART_STACLR_OFFSET 0x0014 /* UARTx status and control clear register */ +#define PIC32MX_UART_STASET_OFFSET 0x0018 /* UARTx status and control set register */ +#define PIC32MX_UART_STAINV_OFFSET 0x001c /* UARTx status and control invert register */ +#define PIC32MX_UART_TXREG_OFFSET 0x0020 /* UARTx transmit register */ +#define PIC32MX_UART_RXREG_OFFSET 0x0030 /* UARTx receive register */ +#define PIC32MX_UART_BRG_OFFSET 0x0040 /* UARTx baud rate register */ +#define PIC32MX_UART_BRGCLR_OFFSET 0x0044 /* UARTx baud rate clear register */ +#define PIC32MX_UART_BRGSET_OFFSET 0x0048 /* UARTx baud rate set register */ +#define PIC32MX_UART_BRGINV_OFFSET 0x004c /* UARTx baud rate invert register */ + +/* Register Addresses ****************************************************************/ + +#if CHIP_NUARTS > 0 +# define PIC32MX_UART1_MODE (PIC32MX_UART1_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART1_MODECLR (PIC32MX_UART1_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART1_MODESET (PIC32MX_UART1_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART1_MODEINV (PIC32MX_UART1_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART1_STA (PIC32MX_UART1_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART1_STACLR (PIC32MX_UART1_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART1_STASET (PIC32MX_UART1_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART1_STAINV (PIC32MX_UART1_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART1_TXREG (PIC32MX_UART1_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART1_RXREG (PIC32MX_UART1_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART1_BRG (PIC32MX_UART1_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART1_BRGCLR (PIC32MX_UART1_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART1_BRGSET (PIC32MX_UART1_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART1_BRGINV (PIC32MX_UART1_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 1 +# define PIC32MX_UART2_MODE (PIC32MX_UART2_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART2_MODECLR (PIC32MX_UART2_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART2_MODESET (PIC32MX_UART2_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART2_MODEINV (PIC32MX_UART2_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART2_STA (PIC32MX_UART2_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART2_STACLR (PIC32MX_UART2_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART2_STASET (PIC32MX_UART2_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART2_STAINV (PIC32MX_UART2_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART2_TXREG (PIC32MX_UART2_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART2_RXREG (PIC32MX_UART2_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART2_BRG (PIC32MX_UART2_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART2_BRGCLR (PIC32MX_UART2_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART2_BRGSET (PIC32MX_UART2_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART2_BRGINV (PIC32MX_UART2_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 2 +# define PIC32MX_UART3_MODE (PIC32MX_UART3_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART3_MODECLR (PIC32MX_UART3_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART3_MODESET (PIC32MX_UART3_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART3_MODEINV (PIC32MX_UART3_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART3_STA (PIC32MX_UART3_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART3_STACLR (PIC32MX_UART3_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART3_STASET (PIC32MX_UART3_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART3_STAINV (PIC32MX_UART3_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART3_TXREG (PIC32MX_UART3_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART3_RXREG (PIC32MX_UART3_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART3_BRG (PIC32MX_UART3_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART3_BRGCLR (PIC32MX_UART3_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART3_BRGSET (PIC32MX_UART3_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART3_BRGINV (PIC32MX_UART3_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 3 +# define PIC32MX_UART4_MODE (PIC32MX_UART4_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART4_MODECLR (PIC32MX_UART4_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART4_MODESET (PIC32MX_UART4_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART4_MODEINV (PIC32MX_UART4_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART4_STA (PIC32MX_UART4_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART4_STACLR (PIC32MX_UART4_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART4_STASET (PIC32MX_UART4_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART4_STAINV (PIC32MX_UART4_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART4_TXREG (PIC32MX_UART4_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART4_RXREG (PIC32MX_UART4_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART4_BRG (PIC32MX_UART4_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART4_BRGCLR (PIC32MX_UART4_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART4_BRGSET (PIC32MX_UART4_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART4_BRGINV (PIC32MX_UART4_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 4 +# define PIC32MX_UART5_MODE (PIC32MX_UART5_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART5_MODECLR (PIC32MX_UART5_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART5_MODESET (PIC32MX_UART5_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART5_MODEINV (PIC32MX_UART5_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART5_STA (PIC32MX_UART5_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART5_STACLR (PIC32MX_UART5_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART5_STASET (PIC32MX_UART5_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART5_STAINV (PIC32MX_UART5_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART5_TXREG (PIC32MX_UART5_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART5_RXREG (PIC32MX_UART5_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART5_BRG (PIC32MX_UART5_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART5_BRGCLR (PIC32MX_UART5_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART5_BRGSET (PIC32MX_UART5_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART5_BRGINV (PIC32MX_UART5_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 5 +# define PIC32MX_UART6_MODE (PIC32MX_UART6_K1BASE+PIC32MX_UART_MODE_OFFSET) +# define PIC32MX_UART6_MODECLR (PIC32MX_UART6_K1BASE+PIC32MX_UART_MODECLR_OFFSET) +# define PIC32MX_UART6_MODESET (PIC32MX_UART6_K1BASE+PIC32MX_UART_MODESET_OFFSET) +# define PIC32MX_UART6_MODEINV (PIC32MX_UART6_K1BASE+PIC32MX_UART_MODEINV_OFFSET) +# define PIC32MX_UART6_STA (PIC32MX_UART6_K1BASE+PIC32MX_UART_STA_OFFSET) +# define PIC32MX_UART6_STACLR (PIC32MX_UART6_K1BASE+PIC32MX_UART_STACLR_OFFSET) +# define PIC32MX_UART6_STASET (PIC32MX_UART6_K1BASE+PIC32MX_UART_STASET_OFFSET) +# define PIC32MX_UART6_STAINV (PIC32MX_UART6_K1BASE+PIC32MX_UART_STAINV_OFFSET) +# define PIC32MX_UART6_TXREG (PIC32MX_UART6_K1BASE+PIC32MX_UART_TXREG_OFFSET) +# define PIC32MX_UART6_RXREG (PIC32MX_UART6_K1BASE+PIC32MX_UART_RXREG_OFFSET) +# define PIC32MX_UART6_BRG (PIC32MX_UART6_K1BASE+PIC32MX_UART_BRG_OFFSET) +# define PIC32MX_UART6_BRGCLR (PIC32MX_UART6_K1BASE+PIC32MX_UART_BRGCLR_OFFSET) +# define PIC32MX_UART6_BRGSET (PIC32MX_UART6_K1BASE+PIC32MX_UART_BRGSET_OFFSET) +# define PIC32MX_UART6_BRGINV (PIC32MX_UART6_K1BASE+PIC32MX_UART_BRGINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ****************************************************/ + +/* UARTx mode register */ + +#define UART_MODE_STSEL (1 << 0) /* Bit 0: Stop selection 1=2 stop bits */ +#define UART_MODE_PDSEL_SHIFT (1) /* Bits: 1-2: Parity and data selection */ +#define UART_MODE_PDSEL_MASK (3 << UART_MODE_PDSEL_SHIFT) +# define UART_MODE_PDSEL_8NONE (0 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, no parity */ +# define UART_MODE_PDSEL_8EVEN (1 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, even parity */ +# define UART_MODE_PDSEL_8ODD (2 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, odd parity */ +# define UART_MODE_PDSEL_9NONE (3 << UART_MODE_PDSEL_SHIFT) /* 9-bit data, no parity */ +#define UART_MODE_BRGH (1 << 3) /* Bit 3: High baud rate enable */ +#define UART_MODE_RXINV (1 << 4) /* Bit 4: Receive polarity inversion */ +#define UART_MODE_ABAUD (1 << 5) /* Bit 5: Auto-baud enable */ +#define UART_MODE_LPBACK (1 << 6) /* Bit 6: UARTx loopback mode select */ +#define UART_MODE_WAKE (1 << 7) /* Bit 7: Enable wake-up on start bit detect during sleep mode */ +#define UART_MODE_UEN_SHIFT (8) /* Bits: 8-9: UARTx enable */ +#define UART_MODE_UEN_MASK (3 << UART_MODE_UEN_SHIFT) +# define UART_MODE_UEN_PORT (0 << UART_MODE_UEN_SHIFT) /* UxCTS+UxRTS/UxBCLK=PORTx register */ +# define UART_MODE_UEN_ENR_CPORT (1 << UART_MODE_UEN_SHIFT) /* UxRTS=enabled; UxCTS=PORTx register */ +# define UART_MODE_UEN_ENCR (2 << UART_MODE_UEN_SHIFT) /* UxCTS+UxRTS=enabled */ +# define UART_MODE_UEN_CPORT (3 << UART_MODE_UEN_SHIFT) /* UxCTS=PORTx register */ +#define UART_MODE_RTSMD (1 << 11) /* Bit 11: Mode selection for ~UxRTS pin */ +#define UART_MODE_IREN (1 << 12) /* Bit 12: IrDA encoder and decoder enable */ +#define UART_MODE_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ + +#if !defined(CHIP_PIC32MX1) && !defined(CHIP_PIC32MX2) +# define UART_MODE_FRZ (1 << 14) /* Bit 14: Freeze in debug exception mode */ +#endif + +#define UART_MODE_ON (1 << 15) /* Bit 15: UARTx enable */ + +/* UARTx status and control register */ + +#define UART_STA_URXDA (1 << 0) /* Bit 0: Receive buffer data available */ +#define UART_STA_OERR (1 << 1) /* Bit 1: Receive buffer overrun error status */ +#define UART_STA_FERR (1 << 2) /* Bit 2: Framing error status */ +#define UART_STA_PERR (1 << 3) /* Bit 3: Parity error status */ +#define UART_STA_RIDLE (1 << 4) /* Bit 4: Receiver idle */ +#define UART_STA_ADDEN (1 << 5) /* Bit 5: Address character detect */ +#define UART_STA_URXISEL_SHIFT (6) /* Bits: 6-7: Receive interrupt mode selection */ +#define UART_STA_URXISEL_MASK (3 << UART_STA_URXISEL_SHIFT) +#if CHIP_UARTFIFOD == 4 +# define UART_STA_URXISEL_RECVD (0 << UART_STA_URXISEL_SHIFT) /* Character received */ +# define UART_STA_URXISEL_RXB3 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 */ +# define UART_STA_URXISEL_RXBF (3 << UART_STA_URXISEL_SHIFT) /* RX buffer full */ +#elif CHIP_UARTFIFOD == 8 +# define UART_STA_URXISEL_RECVD (0 << UART_STA_URXISEL_SHIFT) /* Character received */ +# define UART_STA_URXISEL_RXB4 (1 << UART_STA_URXISEL_SHIFT) /* RX buffer 1/2 */ +# define UART_STA_URXISEL_RXB6 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 */ +#endif +#define UART_STA_UTRMT (1 << 8) /* Bit 8: Transmit shift register is empty */ +#define UART_STA_UTXBF (1 << 9) /* Bit 9: Transmit buffer full status */ +#define UART_STA_UTXEN (1 << 10) /* Bit 10: Transmit enable */ +#define UART_STA_UTXBRK (1 << 11) /* Bit 11: Transmit break */ +#define UART_STA_URXEN (1 << 12) /* Bit 12: Receiver enable */ +#define UART_STA_UTXINV (1 << 13) /* Bit 13: Transmit polarity inversion */ +#define UART_STA_UTXISEL_SHIFT (14) /* Bits: 14-15: TX interrupt mode selection bi */ +#define UART_STA_UTXISEL_MASK (3 << UART_STA_UTXISEL_SHIFT) +# define UART_STA_UTXISEL_TXBNF (0 << UART_STA_UTXISEL_SHIFT) /* TX buffer not full */ +# define UART_STA_UTXISEL_DRAINED (1 << UART_STA_UTXISEL_SHIFT) /* All characters sent */ +# define UART_STA_UTXISEL_TXBE (2 << UART_STA_UTXISEL_SHIFT) /* TX buffer empty */ +#define UART_STA_ADDR_SHIFT (16) /* Bits:16-23: Automatic address mask */ +#define UART_STA_ADDR_MASK (0xff << UART_STA_ADDR_SHIFT) +#define UART_STA_ADM_EN (1 << 24) /* Bit 24: Automatic address detect mode enable */ + +/* UARTx transmit register */ + +#define UART_TXREG_MASK 0x1ff + +/* UARTx receive register */ + +#define UART_RXREG_MASK 0x1ff + +/* UARTx baud rate register */ + +#define UART_BRG_MASK 0xffff + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_UART_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-usbdev.c b/arch/mips/src/pic32mx/pic32mx-usbdev.c new file mode 100644 index 0000000000000000000000000000000000000000..00d9f240930d8cfdfe8883500ff9cbce4616d712 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-usbdev.c @@ -0,0 +1,4532 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx_usbdev.c + * + * Copyright (C) 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * This file derives from the STM32 USB device driver with modifications + * based on additional information from: + * + * - "USB On-The-Go (OTG)", DS61126E, Microchip Technology Inc., 2009 + * - Sample code provided with the Sure Electronics PIC32 board + * (which seems to have derived from Microchip PICDEM PIC18 code). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "pic32mx.h" +#include "pic32mx-usbotg.h" + +#if defined(CONFIG_USBDEV) && defined(CONFIG_PIC32MX_USBDEV) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +/* Extremely detailed register/BDT debug that you would normally never want + * enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_PIC32MX_USBDEV_REGDEBUG +# undef CONFIG_PIC32MX_USBDEV_BDTDEBUG +#endif + +/* Disable this logic because it is buggy. It works most of the time but + * has some lurking issues that keep this higher performance solution from + * being usable. + */ + +#undef CONFIG_USBDEV_NOREADAHEAD /* Makes no difference */ + +#undef CONFIG_USBDEV_NOWRITEAHEAD +#define CONFIG_USBDEV_NOWRITEAHEAD 1 /* Fixes some problems with IN transfers */ + +/* Interrupts ***************************************************************/ +/* Initial interrupt sets */ + +#ifdef CONFIG_USB_SOFINTS +# define USB_SOF_INTERRUPT USB_INT_SOF +#else +# define USB_SOF_INTERRUPT 0 +#endif + +#define ERROR_INTERRUPTS (USB_EINT_PID | USB_EINT_CRC5 | USB_EINT_EOF | \ + USB_EINT_CRC16 | USB_EINT_DFN8 | USB_EINT_BTO | \ + USB_EINT_BTS) +#define NORMAL_INTERRUPTS (USB_INT_URST | USB_INT_UERR | USB_SOF_INTERRUPT | \ + USB_INT_TRN | USB_INT_IDLE | USB_INT_STALL) + +/* Endpoints ****************************************************************/ +/* Endpoint identifiers. The PIC32MX supports up to 16 mono-directional or 8 + * bidirectional endpoints. However, when you take into account PMA buffer + * usage (see below) and the fact that EP0 is bidirectional, then there is + * a functional limitation of EP0 + 5 mono-directional endpoints = 6. We'll + * define PIC32MX_NENDPOINTS to be 8, however, because that is how many + * endpoint register sets there are. + */ + +#define PIC32MX_NENDPOINTS (16) +#define EP0 (0) + +#define PIC32MX_ENDP_BIT(ep) (1 << (ep)) +#define PIC32MX_ENDP_ALLSET 0xffff + +/* BDT Table Indexing. The BDT is addressed in the hardware as follows: + * + * Bits 9-31: These come the BDT address bits written into the BDTP3, + * BDTP2, and BDTP1 registers + * Bits 5-8: The endpoint number + * Bit 4: Direction: + * 1 = Transmit: SETUP/OUT for host, IN for function + * 0 = Receive: IN for host, SETUP/OUT for function + * Bit 3: PPBI, the ping point buffer index bit (0=EVEN, 1=ODD) + * Bits 0-2: Supports 8-byte BDT entries + */ + +#define EP0_OUT_EVEN (0) +#define EP0_OUT_ODD (1) +#define EP0_IN_EVEN (2) +#define EP0_IN_ODD (3) +#define EP_OUT_EVEN(ep) ((int)(ep) << 2) +#define EP_OUT_ODD(ep) (((int)(ep) << 2) + 1) +#define EP_IN_EVEN(ep) (((int)(ep) << 2) + 2) +#define EP_IN_ODD(ep) (((int)(ep) << 2) + 3) + +#define EP(ep,dir,pp) (((int)(ep) << 2) + ((int)(dir) << 1) + (int)(pp)) +#define EP_DIR_OUT 0 +#define EP_DIR_IN 1 +#define EP_PP_EVEN 0 +#define EP_PP_ODD 1 + +/* Packet sizes. We use a fixed 64 max packet size for all endpoint types */ + +#define PIC32MX_MAXPACKET_SHIFT (6) +#define PIC32MX_MAXPACKET_SIZE (1 << (PIC32MX_MAXPACKET_SHIFT)) + +#define PIC32MX_EP0MAXPACKET PIC32MX_MAXPACKET_SIZE + +/* Endpoint register initialization parameters */ + +#define PIC32MX_EP_CONTROL (USB_EP_EPHSHK|USB_EP_EPTXEN|USB_EP_EPRXEN) +#define PIC32MX_EP_BULKIN (USB_EP_EPTXEN|USB_EP_EPCONDIS|USB_EP_EPHSHK) +#define PIC32MX_EP_BULKOUT (USB_EP_EPRXEN|USB_EP_EPCONDIS|USB_EP_EPHSHK) +#define PIC32MX_EP_INTIN (USB_EP_EPTXEN|USB_EP_EPCONDIS|USB_EP_EPHSHK) +#define PIC32MX_EP_INTOUT (USB_EP_EPRXEN|USB_EP_EPCONDIS|USB_EP_EPHSHK) +#define PIC32MX_EP_ISOCIN (USB_EP_EPTXEN|USB_EP_EPCONDIS) +#define PIC32MX_EP_ISOCOUT (USB_EP_EPRXEN|USB_EP_EPCONDIS) + +/* USB-related masks */ + +#define REQRECIPIENT_MASK (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK) + +/* Request queue operations *************************************************/ + +#define pic32mx_rqempty(q) ((q)->head == NULL) +#define pic32mx_rqhead(q) ((q)->head) +#define pic32mx_rqtail(q) ((q)->tail) + +#define RESTART_DELAY (150 * CLOCKS_PER_SEC / 1000) + +/* USB trace ****************************************************************/ +/* Trace error codes */ + +#define PIC32MX_TRACEERR_ALLOCFAIL 0x0001 +#define PIC32MX_TRACEERR_BADCLEARFEATURE 0x0002 +#define PIC32MX_TRACEERR_BADDEVGETSTATUS 0x0003 +#define PIC32MX_TRACEERR_BADEPGETSTATUS 0x0004 +#define PIC32MX_TRACEERR_BADEPNO 0x0005 +#define PIC32MX_TRACEERR_BADEPTYPE 0x0006 +#define PIC32MX_TRACEERR_BADGETCONFIG 0x0007 +#define PIC32MX_TRACEERR_BADGETSETDESC 0x0008 +#define PIC32MX_TRACEERR_BADGETSTATUS 0x0009 +#define PIC32MX_TRACEERR_BADSETADDRESS 0x000a +#define PIC32MX_TRACEERR_BADSETCONFIG 0x000b +#define PIC32MX_TRACEERR_BADSETFEATURE 0x000c +#define PIC32MX_TRACEERR_BINDFAILED 0x000d +#define PIC32MX_TRACEERR_DISPATCHSTALL 0x000e +#define PIC32MX_TRACEERR_DRIVER 0x000f +#define PIC32MX_TRACEERR_DRIVERREGISTERED 0x0010 +#define PIC32MX_TRACEERR_EP0SETUPSTALLED 0x0011 +#define PIC32MX_TRACEERR_EPDISABLED 0x0012 +#define PIC32MX_TRACEERR_EPOUTNULLPACKET 0x0013 +#define PIC32MX_TRACEERR_EPRESERVE 0x0014 +#define PIC32MX_TRACEERR_INVALIDCTRLREQ 0x0015 +#define PIC32MX_TRACEERR_INVALIDPARMS 0x0016 +#define PIC32MX_TRACEERR_IRQREGISTRATION 0x0017 +#define PIC32MX_TRACEERR_NOTCONFIGURED 0x0018 +#define PIC32MX_TRACEERR_REQABORTED 0x0019 +#define PIC32MX_TRACEERR_INVALIDSTATE 0x001a + +/* Trace interrupt codes */ + +#define PIC32MX_TRACEINTID_CLEARFEATURE 0x0001 +#define PIC32MX_TRACEINTID_DEVGETSTATUS 0x0002 +#define PIC32MX_TRACEINTID_DISPATCH 0x0003 +#define PIC32MX_TRACEINTID_EP0IN 0x0004 +#define PIC32MX_TRACEINTID_EP0INDONE 0x0005 +#define PIC32MX_TRACEINTID_EP0OUTDONE 0x0006 +#define PIC32MX_TRACEINTID_EP0SETUPDONE 0x0007 +#define PIC32MX_TRACEINTID_EP0SETUPSETADDRESS 0x0008 +#define PIC32MX_TRACEINTID_EP0ADDRESSSET 0x0009 +#define PIC32MX_TRACEINTID_EPGETSTATUS 0x000a +#define PIC32MX_TRACEINTID_EPINDONE 0x000b +#define PIC32MX_TRACEINTID_EPINQEMPTY 0x000c +#define PIC32MX_TRACEINTID_EPOUTDONE 0x000d +#define PIC32MX_TRACEINTID_EPOUTQEMPTY 0x000e +#define PIC32MX_TRACEINTID_SOF 0x000f +#define PIC32MX_TRACEINTID_GETCONFIG 0x0010 +#define PIC32MX_TRACEINTID_GETSETDESC 0x0011 +#define PIC32MX_TRACEINTID_GETSETIF 0x0012 +#define PIC32MX_TRACEINTID_GETSTATUS 0x0013 +#define PIC32MX_TRACEINTID_IFGETSTATUS 0x0014 +#define PIC32MX_TRACEINTID_TRNC 0x0015 +#define PIC32MX_TRACEINTID_TRNCS 0x0016 +#define PIC32MX_TRACEINTID_INTERRUPT 0x0017 +#define PIC32MX_TRACEINTID_NOSTDREQ 0x0018 +#define PIC32MX_TRACEINTID_RESET 0x0019 +#define PIC32MX_TRACEINTID_SETCONFIG 0x001a +#define PIC32MX_TRACEINTID_SETFEATURE 0x001b +#define PIC32MX_TRACEINTID_IDLE 0x001c +#define PIC32MX_TRACEINTID_SYNCHFRAME 0x001d +#define PIC32MX_TRACEINTID_WKUP 0x001e +#define PIC32MX_TRACEINTID_T1MSEC 0x001f +#define PIC32MX_TRACEINTID_OTGID 0x0020 +#define PIC32MX_TRACEINTID_STALL 0x0021 +#define PIC32MX_TRACEINTID_UERR 0x0022 +#define PIC32MX_TRACEINTID_SUSPENDED 0x0023 +#define PIC32MX_TRACEINTID_WAITRESET 0x0024 + +/* Misc Helper Macros *******************************************************/ + +#define PHYS_ADDR(va) ((uint32_t)(va) & 0x1fffffff) +#define VIRT_ADDR(pa) (KSEG1_BASE | (uint32_t)(pa)) + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/* Byte ordering in host-based values */ + +#ifdef CONFIG_ENDIAN_BIG +# define LSB 1 +# define MSB 0 +#else +# define LSB 0 +# define MSB 1 +#endif + +/* Debug ********************************************************************/ +/* CONFIG_PIC32MX_USBDEV_REGDEBUG enables dumping of all low-level register + * access and BDT accesses. Normally, this generates so much debug output + * that USB may not even be functional. + */ + +#ifdef CONFIG_PIC32MX_USBDEV_REGDEBUG + +# undef CONFIG_PIC32MX_USBDEV_BDTDEBUG +# define CONFIG_PIC32MX_USBDEV_BDTDEBUG 1 + +# define regdbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define regvdbg lldbg +# else +# define regvdbg(x...) +# endif + +#else + +# define pic32mx_getreg(addr) getreg16(addr) +# define pic32mx_putreg(val,addr) putreg16(val,addr) +# define regdbg(x...) +# define regvdbg(x...) + +#endif + +/* CONFIG_PIC32MX_USBDEV_BDTDEBUG dumps most BDT settings */ + +#ifdef CONFIG_PIC32MX_USBDEV_BDTDEBUG + +# define bdtdbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define bdtvdbg lldbg +# else +# define bdtvdbg(x...) +# endif + +#else + +# define bdtdbg(x...) +# define bdtvdbg(x...) + +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* Overvall device state */ + +enum pic32mx_devstate_e +{ + DEVSTATE_DETACHED = 0, /* Not connected to a host */ + DEVSTATE_ATTACHED, /* Connected to a host */ + DEVSTATE_POWERED, /* Powered */ + DEVSTATE_DEFAULT, /* Default state */ + DEVSTATE_ADDRPENDING, /* Waiting for an address */ + DEVSTATE_ADDRESS, /* Address received */ + DEVSTATE_CONFIGURED, /* Configuration received */ +}; + +/* The various states of the control pipe */ + +enum pic32mx_ctrlstate_e +{ + CTRLSTATE_WAITSETUP = 0, /* No request in progress, waiting for setup */ + CTRLSTATE_RDREQUEST, /* Read request (OUT) in progress */ + CTRLSTATE_WRREQUEST, /* Write request (IN) in progress */ + CTRLSTATE_STALL, /* EP0 stall requested */ + CTRLSTATE_STALLED /* EP0 is stalled */ +}; + +union wb_u +{ + uint16_t w; + uint8_t b[2]; +}; + +/* A container for a request so that the request make be retained in a + * singly-linked list. + */ + +struct pic32mx_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ +#ifdef CONFIG_USBDEV_NOWRITEAHEAD + uint16_t inflight[1]; /* The number of bytes "in-flight" */ +#else + uint16_t inflight[2]; /* The number of bytes "in-flight" */ +#endif + struct pic32mx_req_s *flink; /* Supports a singly linked list */ +}; + +/* This structure represents the 'head' of a singly linked list of requests */ + +struct pic32mx_queue_s +{ + struct pic32mx_req_s *head; /* Head of the request queue */ + struct pic32mx_req_s *tail; /* Tail of the request queue */ +}; + +/* This is the internal representation of an endpoint */ + +struct pic32mx_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct pic32mx_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* PIC32MX-specific fields */ + + struct pic32mx_usbdev_s *dev; /* Reference to private driver data */ + struct pic32mx_queue_s pend; /* List of pending (inactive) requests for this endpoint */ + struct pic32mx_queue_s active; /* List of active requests for this endpoint */ + uint8_t stalled:1; /* true: Endpoint is stalled */ + uint8_t halted:1; /* true: Endpoint feature halted */ + uint8_t txnullpkt:1; /* Null packet needed at end of TX transfer */ + uint8_t txdata1:1; /* Data0/1 of next TX transfer */ + uint8_t rxdata1:1; /* Data0/1 of next RX transfer */ + volatile struct usbotg_bdtentry_s *bdtin; /* BDT entry for the IN transaction */ + volatile struct usbotg_bdtentry_s *bdtout; /* BDT entry for the OUT transaction */ +}; + +struct pic32mx_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to structpic32mx_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* PIC32MX-specific fields */ + + struct usb_ctrlreq_s ctrl; /* Last EP0 request */ + uint8_t devstate; /* Driver state (see enum pic32mx_devstate_e) */ + uint8_t ctrlstate; /* Control EP state (see enum pic32mx_ctrlstate_e) */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t rwakeup:1; /* 1: Device supports remote wakeup */ + uint8_t attached:1; /* Device is attached to the host */ + uint8_t ep0done:1; /* EP0 OUT already prepared */ + uint8_t rxbusy:1; /* EP0 OUT data transfer in progress */ + uint16_t epavail; /* Bitset of available endpoints */ + uint16_t epstalled; /* Bitset of stalled endpoints */ + WDOG_ID wdog; /* Supports the restart delay */ + + /* The endpoint list */ + + struct pic32mx_ep_s eplist[PIC32MX_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV_REGDEBUG +static uint16_t pic32mx_getreg(uint32_t addr); +static void pic32mx_putreg(uint16_t val, uint32_t addr); +#endif + +/* Suspend/Resume Helpers ***************************************************/ + +static void pic32mx_suspend(struct pic32mx_usbdev_s *priv); +static void pic32mx_resume(struct pic32mx_usbdev_s *priv); + +/* Request Queue Management *************************************************/ + +static struct pic32mx_req_s *pic32mx_remfirst(struct pic32mx_queue_s *queue); +static struct pic32mx_req_s *pic32mx_remlast(struct pic32mx_queue_s *queue); +static void pic32mx_addlast(struct pic32mx_queue_s *queue, + struct pic32mx_req_s *req); +static void pic32mx_addfirst(struct pic32mx_queue_s *queue, + struct pic32mx_req_s *req); + +/* Request Helpers **********************************************************/ + +static void pic32mx_reqreturn(struct pic32mx_ep_s *privep, + struct pic32mx_req_s *privreq, int16_t result); +static void pic32mx_reqcomplete(struct pic32mx_ep_s *privep, + int16_t result); +static void pic32mx_epwrite(struct pic32mx_ep_s *privep, + volatile struct usbotg_bdtentry_s *bdt, + const uint8_t *src, uint32_t nbytes); +static void pic32mx_wrcomplete(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static void pic32mx_rqrestart(int argc, uint32_t arg1, ...); +static void pic32mx_delayedrestart(struct pic32mx_usbdev_s *priv, + uint8_t epno); +static void pic32mx_rqstop(struct pic32mx_ep_s *privep); +static int pic32mx_wrstart(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static int pic32mx_wrrequest(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv, + uint8_t *dest, int readlen); +static int pic32mx_rdsetup(struct pic32mx_ep_s *privep, uint8_t *dest, + int readlen); +static int pic32mx_rdrequest(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static void pic32mx_cancelrequests(struct pic32mx_ep_s *privep, + int16_t result); + +/* Interrupt level processing ***********************************************/ + +static void pic32mx_dispatchrequest(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0stall(struct pic32mx_usbdev_s *priv); +static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno, + uint16_t ustat); +static void pic32mx_ep0nextsetup(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0rdcomplete(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0outcomplete(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0incomplete(struct pic32mx_usbdev_s *priv); +static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, + uint16_t ustat); +static int pic32mx_interrupt(int irq, void *context); + +/* Endpoint helpers *********************************************************/ + +static inline struct pic32mx_ep_s * + pic32mx_epreserve(struct pic32mx_usbdev_s *priv, uint8_t epset); +static inline void + pic32mx_epunreserve(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep); +static inline bool + pic32mx_epreserved(struct pic32mx_usbdev_s *priv, int epno); +static void pic32mx_ep0configure(struct pic32mx_usbdev_s *priv); + +/* Endpoint operations ******************************************************/ + +static int pic32mx_epconfigure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int pic32mx_epdisable(struct usbdev_ep_s *ep); +static struct usbdev_req_s * + pic32mx_epallocreq(struct usbdev_ep_s *ep); +static void pic32mx_epfreereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); +static int pic32mx_epsubmit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int pic32mx_epcancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int pic32mx_epbdtstall(struct usbdev_ep_s *ep, bool resume, + bool epin); +static int pic32mx_epstall(struct usbdev_ep_s *ep, bool resume); + +/* USB device controller operations *****************************************/ + +static struct usbdev_ep_s * + pic32mx_allocep(struct usbdev_s *dev, uint8_t epno, bool in, + uint8_t eptype); +static void pic32mx_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep); +static int pic32mx_getframe(struct usbdev_s *dev); +static int pic32mx_wakeup(struct usbdev_s *dev); +static int pic32mx_selfpowered(struct usbdev_s *dev, bool selfpowered); + +/* Initialization/Reset *****************************************************/ + +static void pic32mx_reset(struct pic32mx_usbdev_s *priv); +static void pic32mx_attach(struct pic32mx_usbdev_s *priv); +static void pic32mx_detach(struct pic32mx_usbdev_s *priv); +static void pic32mx_swreset(struct pic32mx_usbdev_s *priv); +static void pic32mx_hwreset(struct pic32mx_usbdev_s *priv); +static void pic32mx_stateinit(struct pic32mx_usbdev_s *priv); +static void pic32mx_hwshutdown(struct pic32mx_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct pic32mx_usbdev_s g_usbdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = pic32mx_epconfigure, + .disable = pic32mx_epdisable, + .allocreq = pic32mx_epallocreq, + .freereq = pic32mx_epfreereq, + .submit = pic32mx_epsubmit, + .cancel = pic32mx_epcancel, + .stall = pic32mx_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = pic32mx_allocep, + .freeep = pic32mx_freeep, + .getframe = pic32mx_getframe, + .wakeup = pic32mx_wakeup, + .selfpowered = pic32mx_selfpowered, + .pullup = pic32mx_usbpullup, +}; + +/* Buffer Descriptor Table. Four BDT entries per + * + * The BDT is addressed in the hardware as follows: + * + * Bits 9-31: These come the BDT address bits written into the BDTP3, BDTP2 + * and BDTP1 registers + * Bits 5-8: The endpoint number + * Bit 4: Direction (0=IN/Tx, 1 = OUT/Rx) + * Bit 3: PPBI, the ping point buffer index bit. + * Bits 0-2: Supports 8-byte BDT entries + */ + +static volatile struct usbotg_bdtentry_s g_bdt[4*PIC32MX_NENDPOINTS] + __attribute__ ((aligned(512))); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Register Operations + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_getreg + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV_REGDEBUG +static uint16_t pic32mx_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint16_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint16_t val = getreg16(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + lldbg("...\n"); + } + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + lldbg("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + lldbg("%08x->%04x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: pic32mx_putreg + ****************************************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV_REGDEBUG +static void pic32mx_putreg(uint16_t val, uint32_t addr) +{ + /* Show the register value being written */ + + lldbg("%08x<-%04x\n", addr, val); + + /* Write the value */ + + putreg16(val, addr); +} +#endif + +/**************************************************************************** + * Request Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_remfirst + ****************************************************************************/ + +static struct pic32mx_req_s *pic32mx_remfirst(struct pic32mx_queue_s *queue) +{ + struct pic32mx_req_s *ret = queue->head; + + if (ret) + { + queue->head = ret->flink; + if (!queue->head) + { + queue->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + + +/**************************************************************************** + * Name: pic32mx_remlast + ****************************************************************************/ + +static struct pic32mx_req_s *pic32mx_remlast(struct pic32mx_queue_s *queue) +{ + struct pic32mx_req_s *prev; + struct pic32mx_req_s *ret = queue->tail; + + ret = queue->tail; + if (ret) + { + if (queue->head == queue->tail) + { + queue->head = NULL; + queue->tail = NULL; + } + else + { + for (prev = queue->head; + prev && prev->flink != ret; + prev = prev->flink); + + if (prev) + { + prev->flink = NULL; + queue->tail = prev; + } + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: pic32mx_addlast + ****************************************************************************/ + +static void pic32mx_addlast(struct pic32mx_queue_s *queue, struct pic32mx_req_s *req) +{ + req->flink = NULL; + if (!queue->head) + { + queue->head = req; + queue->tail = req; + } + else + { + queue->tail->flink = req; + queue->tail = req; + } +} + +/**************************************************************************** + * Name: pic32mx_addfirst + ****************************************************************************/ + +static void pic32mx_addfirst(struct pic32mx_queue_s *queue, struct pic32mx_req_s *req) +{ + req->flink = queue->head; + if (!queue->head) + { + queue->tail = req; + } + queue->head = req; +} + +/**************************************************************************** + * Name: pic32mx_reqreturn + ****************************************************************************/ + +static void pic32mx_reqreturn(struct pic32mx_ep_s *privep, + struct pic32mx_req_s *privreq, int16_t result) +{ + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (USB_EPNO(privep->ep.eplog) == EP0) + { + privep->stalled = (privep->dev->ctrlstate == CTRLSTATE_STALLED); + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->flink = NULL; + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: pic32mx_reqcomplete + ****************************************************************************/ + +static void pic32mx_reqcomplete(struct pic32mx_ep_s *privep, int16_t result) +{ + struct pic32mx_req_s *privreq; + irqstate_t flags; + + /* Remove the completed request at the head of the endpoint's active + * request list. + */ + + flags = enter_critical_section(); + privreq = pic32mx_remfirst(&privep->active); + leave_critical_section(flags); + + if (privreq) + { + /* Return the request to the class driver */ + + pic32mx_reqreturn(privep, privreq, result); + } +} + +/**************************************************************************** + * Name: pic32mx_epwrite + ****************************************************************************/ + +static void pic32mx_epwrite(struct pic32mx_ep_s *privep, + volatile struct usbotg_bdtentry_s *bdt, + const uint8_t *src, uint32_t nbytes) +{ + uint32_t status; + + usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes); + + /* Clear all bits in the status (assuring that we own the BDT) */ + + bdt->status = 0; + + /* Get the correct data toggle (as well as other BDT bits) */ + + if (privep->txdata1) + { + status = (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS); + privep->txdata1 = 0; + } + else + { + status = (USB_BDT_UOWN | USB_BDT_DATA0 | USB_BDT_DTS); + privep->txdata1 = 1; + } + + /* Set the data pointer and data length */ + + bdt->addr = (uint8_t *)PHYS_ADDR(src); + status |= (nbytes << USB_BDT_BYTECOUNT_SHIFT) | USB_BDT_DTS; + + /* And, finally, give the BDT to the USB */ + + bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", + USB_EPNO(privep->ep.eplog), bdt, status, bdt->addr); + + bdt->status = status; +} + +/**************************************************************************** + * Name: pic32mx_wrcomplete + ****************************************************************************/ + +static void pic32mx_wrcomplete(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep) +{ + volatile struct usbotg_bdtentry_s *bdtin; + struct pic32mx_req_s *privreq; + int bytesleft; + int epno; + + /* Check the request at the head of the endpoint's active request queue. + * Since we got here from a write completion event, the active request queue + * should not be empty. + */ + + privreq = pic32mx_rqhead(&privep->active); + DEBUGASSERT(privreq != NULL); + + /* An outgoing IN packet has completed. bdtin should point to the BDT + * that just completed. + */ + + bdtin = privep->bdtin; + epno = USB_EPNO(privep->ep.eplog); + +#ifdef CONFIG_USBDEV_NOWRITEAHEAD + ullvdbg("EP%d: len=%d xfrd=%d inflight=%d\n", + epno, privreq->req.len, privreq->req.xfrd, privreq->inflight[0]); +#else + ullvdbg("EP%d: len=%d xfrd=%d inflight={%d, %d}\n", + epno, privreq->req.len, privreq->req.xfrd, + privreq->inflight[0], privreq->inflight[1]); +#endif + bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", + epno, bdtin, bdtin->status, bdtin->addr); + + /* We should own the BDT that just completed. But NULLify the entire BDT IN. + * Why? So that we can tell later that the BDT available. No, it is not + * sufficient to look at the UOWN bit. If UOWN==0, then the transfer has + * been completed BUT it may not yet have been processed. But a completely + * NULLified BDT is a sure indication + */ + + DEBUGASSERT((bdtin->status & USB_BDT_UOWN) == USB_BDT_COWN); + bdtin->status = 0; + bdtin->addr = 0; + + /* Toggle bdtin to the other BDT. Is the current bdtin the EVEN bdt? */ + + privep->bdtin = &g_bdt[EP_IN_EVEN(epno)]; + if (bdtin == privep->bdtin) + { + /* Yes.. Then the other BDT is the ODD BDT */ + + privep->bdtin++; + } + + /* Update the number of bytes transferred. */ + + privreq->req.xfrd += privreq->inflight[0]; +#ifdef CONFIG_USBDEV_NOWRITEAHEAD + privreq->inflight[0] = 0; +#else + privreq->inflight[0] = privreq->inflight[1]; + privreq->inflight[1] = 0; +#endif + bytesleft = privreq->req.len - privreq->req.xfrd; + + /* If all of the bytes were sent (bytesleft == 0) and no NULL packet is + * needed (!txnullpkt), then we are finished with the transfer + */ + + if (bytesleft == 0 && !privep->txnullpkt) + { + /* The transfer is complete. Give the completed request back to + * the class driver. + */ + + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + pic32mx_reqcomplete(privep, OK); + + /* Special case writes to endpoint zero. If there is no transfer in + * progress, then we need to configure to received the next SETUP packet. + */ + + if (USB_EPNO(privep->ep.eplog) == 0) + { + priv->ctrlstate = CTRLSTATE_WAITSETUP; + } + } +} + +/**************************************************************************** + * Name: pic32mx_rqrestart + ****************************************************************************/ + +static void pic32mx_rqrestart(int argc, uint32_t arg1, ...) +{ + struct pic32mx_usbdev_s *priv; + struct pic32mx_ep_s *privep; + struct pic32mx_req_s *privreq; + uint16_t epstalled; + uint16_t mask; + int epno; + + /* Recover the pointer to the driver structure */ + + priv = (struct pic32mx_usbdev_s *)((uintptr_t)arg1); + DEBUGASSERT(priv != NULL); + + /* Sample and clear the set of endpoints that have recovered from a stall */ + + epstalled = priv->epstalled; + priv->epstalled = 0; + + /* Loop, checking each bit in the epstalled bit set */ + + for (epno = 0; epstalled && epno < PIC32MX_NENDPOINTS; epno++) + { + /* Has this encpoint recovered from a stall? */ + + mask = (1 << epno); + if ((epstalled & mask) != 0) + { + /* Yes, this endpoint needs to be restarteed */ + + epstalled &= ~mask; + privep = &priv->eplist[epno]; + + /* Reset some endpoint state variables */ + + privep->stalled = false; + privep->txnullpkt = false; + + /* Check the request at the head of the endpoint's pending request queue */ + + privreq = pic32mx_rqhead(&privep->pend); + if (privreq) + { + /* Restart transmission after we have recovered from a stall */ + + privreq->req.xfrd = 0; + privreq->inflight[0] = 0; +#ifndef CONFIG_USBDEV_NOWRITEAHEAD + privreq->inflight[1] = 0; +#endif + (void)pic32mx_wrrequest(priv, privep); + } + } + } +} + +/**************************************************************************** + * Name: pic32mx_delayedrestart + ****************************************************************************/ + +static void pic32mx_delayedrestart(struct pic32mx_usbdev_s *priv, uint8_t epno) +{ + /* Add endpoint to the set of endpoints that need to be restarted */ + + priv->epstalled |= (1 << epno); + + /* And start (or re-start) the watchdog timer */ + + wd_start(priv->wdog, RESTART_DELAY, pic32mx_rqrestart, 1, (uint32_t)priv); +} + +/**************************************************************************** + * Name: pic32mx_rqstop + ****************************************************************************/ + +static void pic32mx_rqstop(struct pic32mx_ep_s *privep) +{ + struct pic32mx_req_s *privreq; + + /* Move all of the active requests back to the pending request queue */ + + while ((privreq = pic32mx_remlast(&privep->active))) + { + /* Move the request back to the head of the pending list */ + + pic32mx_addfirst(&privep->pend, privreq); + } +} + +/**************************************************************************** + * Name: pic32mx_wrstart + ****************************************************************************/ + +static int pic32mx_wrstart(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep) +{ + volatile struct usbotg_bdtentry_s *bdt; + struct pic32mx_req_s *privreq; + uint8_t *buf; + uint8_t epno; + int nbytes; + int bytesleft; + int xfrd; + int index; + + /* We get here when either (1) an IN endpoint completion interrupt occurs, + * or (2) a new write request is reqeived from the class. + */ + + /* Get the endpoint number that we are servicing */ + + epno = USB_EPNO(privep->ep.eplog); + + /* Decide which BDT to use. bdtin points to the "current" BDT. That is, + * the one that either (1) available for next transfer, or (2) the one + * that is currently busy with the current transfer. If the current + * BDT is busy, we have the option of setting up the other BDT in advance + * in order to improve data transfer performance. + */ + + bdt = privep->bdtin; + index = 0; + + if (bdt->status || bdt->addr) + { +#ifdef CONFIG_USBDEV_NOWRITEAHEAD + /* The current BDT is not available and write ahead is disabled. There + * is nothing we can do now. Return -EBUSY to indicate this condition. + */ + + return -EBUSY; +#else + /* The current BDT is not available, check the other BDT */ + + volatile struct usbotg_bdtentry_s *otherbdt; + otherbdt = &g_bdt[EP(epno, EP_DIR_IN, EP_PP_EVEN)]; + if (otherbdt == bdt) + { + otherbdt++; + } + + /* Is it available? */ + + if (otherbdt->status || otherbdt->addr) + { + /* No, neither are available. We cannot perform the transfer now. + * Return -EBUSY to indicate this condition. + */ + + return -EBUSY; + } + + /* Yes... use the other BDT */ + + bdt = otherbdt; + index = 1; +#endif + } + + /* A BDT is available. Which request should we be operating on? The last + * incomplete, active request would be at the tail of the active list. + */ + + privreq = pic32mx_rqtail(&privep->active); + + /* This request would be NULL if there is no incomplete, active request. */ + + if (privreq) + { + /* Get the number of bytes left to be transferred in the request */ + + xfrd = privreq->req.xfrd; + bytesleft = privreq->req.len - xfrd; + + /* Even if the request is incomplete, transfer of all the requested + * bytes may already been started. NOTE: inflight[1] should be zero + * because we know that there is a BDT available. + */ + +#ifndef CONFIG_USBDEV_NOWRITEAHEAD + DEBUGASSERT(privreq->inflight[1] == 0); +#endif + /* Has the transfer been initiated for all of the bytes? */ + + if (bytesleft > privreq->inflight[0]) + { + /* No.. we have more work to do with this request */ + + xfrd += privreq->inflight[0]; + bytesleft -= privreq->inflight[0]; + } + + /* Do we need to send a null packet after this packet? */ + + else if (privep->txnullpkt) + { + /* Yes... set up for the NULL packet transfer */ + + xfrd = privreq->req.len; + bytesleft = 0; + } + else + { + /* No.. We are finished with this request. We need to get the + * next request from the head of the pending request list. + */ + + privreq = NULL; + } + } + + /* If privreq is NULL here then either (1) there is no active request, or + * (2) the (only) active request is fully queued. In either case, we need + * to get the next request from the head of the pending request list. + */ + + if (!privreq) + { + /* Remove the next request from the head of the pending request list */ + + privreq = pic32mx_remfirst(&privep->pend); + if (!privreq) + { + /* The pending request list is empty. There are no queued TX + * requests to be sent. + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPINQEMPTY), epno); + + /* Return -ENODATA to indicate that there are no further requests + * to be processed. + */ + + return -ENODATA; + } + + /* Add this request to the tail of the active request list */ + + pic32mx_addlast(&privep->active, privreq); + + /* Set up the first transfer for this request */ + + xfrd = 0; + bytesleft = privreq->req.len; + } + + ullvdbg("epno=%d req=%p: len=%d xfrd=%d index=%d nullpkt=%d\n", + epno, privreq, privreq->req.len, xfrd, index, privep->txnullpkt); + + /* Get the number of bytes left to be sent in the packet */ + + nbytes = bytesleft; + if (nbytes > 0 || privep->txnullpkt) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + privep->txnullpkt = 0; + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + privep->txnullpkt = 1; + } + } + } + + /* Send the packet (might be a null packet with nbytes == 0) */ + + buf = privreq->req.buf + xfrd; + + /* Setup the writes to the endpoints */ + + pic32mx_epwrite(privep, bdt, buf, nbytes); + + /* Special case endpoint 0 state information. The write request is in + * progress. + */ + + if (epno == 0) + { + priv->ctrlstate = CTRLSTATE_WRREQUEST; + } + + /* Update for the next data IN interrupt */ + + privreq->inflight[index] = nbytes; + return OK; +} + +/**************************************************************************** + * Name: pic32mx_wrrequest + ****************************************************************************/ + +static int pic32mx_wrrequest(struct pic32mx_usbdev_s *priv, struct pic32mx_ep_s *privep) +{ + int ret; + + /* Always try to start two transfers in order to take advantage of the + * PIC32MX's ping pong buffering. + */ + + ret = pic32mx_wrstart(priv, privep); +#ifndef CONFIG_USBDEV_NOWRITEAHEAD + if (ret == OK) + { + /* Note: We need to return the error condition only if nothing was + * queued + */ + + (void)pic32mx_wrstart(priv, privep); + } +#else + UNUSED(ret); +#endif + + /* We return OK to indicate that a write request is still in progress */ + + return pic32mx_rqhead(&privep->active) == NULL ? -ENODATA : OK; +} + +/**************************************************************************** + * Name: pic32mx_rdcomplete + ****************************************************************************/ + +static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep) +{ + volatile struct usbotg_bdtentry_s *bdtout; + struct pic32mx_req_s *privreq; + int epno; + + /* Check the request at the head of the endpoint's active request queue */ + + privreq = pic32mx_rqhead(&privep->active); + if (!privreq) + { + /* There is no active packet waiting to receive any data. Then why are + * we here? + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTQEMPTY), + USB_EPNO(privep->ep.eplog)); + return -EINVAL; + } + + /* bdtout should point to the BDT that just completed */ + + bdtout = privep->bdtout; + epno = USB_EPNO(privep->ep.eplog); + + ullvdbg("EP%d: len=%d xfrd=%d\n", + epno, privreq->req.len, privreq->req.xfrd); + bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", + epno, bdtout, bdtout->status, bdtout->addr); + + /* We should own the BDT that just completed */ + + DEBUGASSERT((bdtout->status & USB_BDT_UOWN) == USB_BDT_COWN); + + /* Get the length of the data received from the BDT. */ + + privreq->req.xfrd = (bdtout->status & USB_BDT_BYTECOUNT_MASK) >> USB_BDT_BYTECOUNT_SHIFT; + + /* Complete the transfer and return the request to the class driver. */ + + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + pic32mx_reqcomplete(privep, OK); + + /* Nullify the BDT entry that just completed. Why? So that we can tell later + * that the BDT has been processed. No, it is not sufficient to look at the + * UOWN bit. If UOWN==0, then the transfer has been completed BUT it may not + * yet have been processed. + */ + + bdtout->status = 0; + bdtout->addr = 0; + + /* Toggle bdtout to the other BDT. Is the current bdtout the EVEN bdt? */ + + privep->bdtout = &g_bdt[EP_OUT_EVEN(epno)]; + if (bdtout == privep->bdtout) + { + /* Yes.. Then the other BDT is the ODD BDT */ + + privep->bdtout++; + } + + /* Set up the next read operation */ + + return pic32mx_rdrequest(priv, privep); +} + +/**************************************************************************** + * Name: pic32mx_ep0rdsetup + ****************************************************************************/ + +static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv, uint8_t *dest, + int readlen) +{ + volatile struct usbotg_bdtentry_s *bdtout; + volatile struct usbotg_bdtentry_s *otherbdt; + struct pic32mx_ep_s *privep; + uint32_t status; + + /* bdtout refers to the next ping-pong BDT to use. */ + + privep = &priv->eplist[EP0]; + bdtout = privep->bdtout; + + /* Get the other BDT. Check if the current BDT the EVEN BDT? */ + + otherbdt = &g_bdt[EP_OUT_EVEN(EP0)]; + if (bdtout == otherbdt) + { + /* Yes.. then the other BDT is the ODD BDT. */ + + otherbdt++; + } + + /* If there is no RX transfer in progress, then the other BDT is setup + * to receive the next setup packet. There is a race condition here! + * Stop any setup packet. + */ + + if (!priv->rxbusy) + { + /* Nullify all BDT OUT entries. Why? So that we can tell later + * that the BDT available. No, it is not sufficient to look at the + * UOWN bit. If UOWN==0, then the transfer has been completed BUT + * it may not yet have been processed. But a completely NULLified + * BDT is a sure indication + */ + + bdtout->status = 0; + bdtout->addr = 0; + otherbdt->status = 0; + otherbdt->addr = 0; + + /* Reset the other BDT to zero... this will cause any attempted use + * of the other BDT to be NAKed. Set the first DATA0/1 value to 1. + */ + + privep->rxdata1 = 1; + } + + /* Otherwise, there are RX transfers in progress. bdtout may be + * unavailable now. In that case, we are free to setup the other BDT + * in order to improve performance. NOTE: That we check if the + * entire BDT has been NULLified. That is the only sure indication + * that the BDT is available (see above). + */ + + if (bdtout->status || bdtout->addr) + { +#ifdef CONFIG_USBDEV_NOREADAHEAD + /* We will not try to read ahead */ + + return -EBUSY; +#else + /* bdtout is not available. Is the other BDT available? */ + + if (otherbdt->status || otherbdt->addr) + { + /* Neither are available... we cannot accept the request now */ + + return -EBUSY; + } + + /* Use the other BDT */ + + bdtout = otherbdt; +#endif + } + + usbtrace(TRACE_READ(EP0), readlen); + + /* Get the correct data toggle (as well as other BDT bits) */ + + if (privep->rxdata1) + { + status = (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS); + privep->rxdata1 = 0; + } + else + { + status = (USB_BDT_UOWN | USB_BDT_DATA0 | USB_BDT_DTS); + privep->rxdata1 = 1; + } + + /* Set the data pointer, data length, and enable the endpoint */ + + bdtout->addr = (uint8_t *)PHYS_ADDR(dest); + status |= ((uint32_t)readlen << USB_BDT_BYTECOUNT_SHIFT); + + /* Then give the BDT to the USB */ + + bdtdbg("EP0 BDT OUT [%p] {%08x, %08x}\n", bdtout, status, bdtout->addr); + bdtout->status = status; + + priv->ctrlstate = CTRLSTATE_RDREQUEST; + priv->rxbusy = 1; + return OK; +} + +/**************************************************************************** + * Name: pic32mx_rdsetup + ****************************************************************************/ + +static int pic32mx_rdsetup(struct pic32mx_ep_s *privep, uint8_t *dest, int readlen) +{ + volatile struct usbotg_bdtentry_s *bdtout; + uint32_t status; + int epno; + + /* Select a BDT. Check both the even and the ODD BDT and use the first one + * that we own. + */ + + epno = USB_EPNO(privep->ep.eplog); + + /* bdtout refers to the next ping-pong BDT to use. However, bdtout may be + * unavailable now. But, in that case, we are free to setup the other BDT + * in order to improve performance. + * + * Note that we NULLify the BDT OUT entries. This is so that we can tell + * that the BDT readlly available. No, it is not sufficient to look at the + * UOWN bit. If UOWN==0, then the transfer has been completed BUT it may + * not yet have been processed. But a completely NULLified BDT is a sure + * indication + */ + + bdtout = privep->bdtout; + if (bdtout->status || bdtout->addr) + { +#ifdef CONFIG_USBDEV_NOREADAHEAD + /* We will not try to read-ahead */ + + return -EBUSY; +#else + volatile struct usbotg_bdtentry_s *otherbdt; + + /* Is the current BDT the EVEN BDT? */ + + otherbdt = &g_bdt[EP_OUT_EVEN(epno)]; + if (bdtout == otherbdt) + { + /* Yes.. select the ODD BDT */ + + otherbdt++; + } + + /* Is the other BDT available? */ + + if (otherbdt->status || otherbdt->addr) + { + /* Neither are available... we cannot accept the request now */ + + return -EBUSY; + } + + /* Use the other BDT */ + + bdtout = otherbdt; +#endif + } + + usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), readlen); + + /* Clear status bits (making sure that UOWN is cleared before doing anything + * else). + */ + + bdtout->status = 0; + + /* Set the data pointer, data length, and enable the endpoint */ + + bdtout->addr = (uint8_t *)PHYS_ADDR(dest); + + /* Get the correct data toggle. */ + + if (privep->rxdata1) + { + status = (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS); + privep->rxdata1 = 0; + } + else + { + status = (USB_BDT_UOWN | USB_BDT_DATA0 | USB_BDT_DTS); + privep->rxdata1 = 1; + } + + /* Set the data length (preserving the data toggle). */ + + status |= ((uint32_t)readlen << USB_BDT_BYTECOUNT_SHIFT); + + /* Then give the BDT to the USB */ + + bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdtout, status, bdtout->addr); + + bdtout->status = status; + return OK; +} + +/**************************************************************************** + * Name: pic32mx_rdrequest + ****************************************************************************/ + +static int pic32mx_rdrequest(struct pic32mx_usbdev_s *priv, + struct pic32mx_ep_s *privep) +{ + struct pic32mx_req_s *privreq; + int readlen; + int ret; + + /* Check the request at the head of the endpoint request queue */ + + privreq = pic32mx_rqhead(&privep->pend); + if (!privreq) + { + /* There is no packet to receive any data. */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTQEMPTY), + USB_EPNO(privep->ep.eplog)); + + /* Special case reads from to endpoint zero. If there is no transfer in + * progress, then we need to configure to received the next SETUP packet. + */ + + if (USB_EPNO(privep->ep.eplog) == 0 && + priv->ctrlstate == CTRLSTATE_RDREQUEST) + { + priv->ctrlstate = CTRLSTATE_WAITSETUP; + priv->rxbusy = 0; + } + + return OK; + } + + ullvdbg("EP%d: len=%d\n", USB_EPNO(privep->ep.eplog), privreq->req.len); + + /* Ignore any attempt to receive a zero length packet */ + + if (privreq->req.len == 0) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_EPOUTNULLPACKET), 0); + pic32mx_reqcomplete(privep, OK); + return OK; + } + + /* Limit the size of the transfer to either the buffer size or the max + * packet size of the endpoint. + */ + + readlen = MIN(privreq->req.len, privep->ep.maxpacket); + + /* Handle EP0 in a few special ways */ + + if (USB_EPNO(privep->ep.eplog) == EP0) + { + ret = pic32mx_ep0rdsetup(priv, privreq->req.buf, readlen); + } + else + { + ret = pic32mx_rdsetup(privep, privreq->req.buf, readlen); + } + + /* If the read request was successfully setup, then move the request from + * the head of the pending request queue to the tail of the active request + * queue. + */ + + if (ret == OK) + { + privreq = pic32mx_remfirst(&privep->pend); + DEBUGASSERT(privreq != NULL); + pic32mx_addlast(&privep->active, privreq); + } + + return ret; +} + +/**************************************************************************** + * Name: pic32mx_cancelrequests + ****************************************************************************/ + +static void pic32mx_cancelrequests(struct pic32mx_ep_s *privep, int16_t result) +{ + struct pic32mx_req_s *privreq; + + while ((privreq = pic32mx_remfirst(&privep->active))) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + pic32mx_reqreturn(privep, privreq, result); + } + + while ((privreq = pic32mx_remfirst(&privep->pend))) + { + usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); + pic32mx_reqreturn(privep, privreq, result); + } +} + +/**************************************************************************** + * Interrupt Level Processing + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_dispatchrequest + ****************************************************************************/ + +static void pic32mx_dispatchrequest(struct pic32mx_usbdev_s *priv) +{ + int ret; + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_DISPATCH), 0); + if (priv && priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, NULL, 0); + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_DISPATCHSTALL), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } +} + +/**************************************************************************** + * Name: pic32mx_ep0stall + ****************************************************************************/ + +static void pic32mx_ep0stall(struct pic32mx_usbdev_s *priv) +{ + uint16_t regval; + + /* Check if EP0 is stalled */ + + regval = pic32mx_getreg(PIC32MX_USB_EP0); + if ((regval & USB_EP_EPSTALL) != 0) + { + /* If so, clear the EP0 stall status */ + + regval &= ~USB_EP_EPSTALL; + pic32mx_putreg(regval, PIC32MX_USB_EP0); + } +} + +/**************************************************************************** + * Name: pic32mx_eptransfer + ****************************************************************************/ + +static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno, + uint16_t ustat) +{ + struct pic32mx_ep_s *privep; + int ret; + + /* Decode and service non control endpoints interrupt */ + + privep = &priv->eplist[epno]; + + /* Check if the last transaction was an EP0 OUT transaction */ + + if ((ustat & USB_STAT_DIR) == USB_STAT_DIR_OUT) + { + /* OUT: host-to-device */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTDONE), ustat); + + /* Handle read requests. Call pic32mx_rdcomplete() to complete the OUT + * transfer and setup the next out transfer. + */ + + ret = pic32mx_rdcomplete(priv, privep); +#ifdef CONFIG_USBDEV_NOREADAHEAD + if (ret == OK) + { + /* If that succeeds, then try to set up another OUT transfer. */ + + (void)pic32mx_rdrequest(priv, privep); + } +#else + UNUSED(ret); +#endif + } + else + { + /* IN: device-to-host */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPINDONE), ustat); + + /* An outgoing IN packet has completed. Update the number of bytes transferred + * and check for completion of the transfer. + */ + + pic32mx_wrcomplete(priv, privep); + + /* Handle additional queued write requests */ + + (void)pic32mx_wrrequest(priv, privep); + } +} + +/**************************************************************************** + * Name: pic32mx_ep0nextsetup + * + * Description: + * This function is called (1) after sucessful completion of an EP0 Setup + * command, or (2) after receipt of the OUT complete event (for simple + * transfers). It simply sets up the single BDT to accept the next + * SETUP commend. + * + ****************************************************************************/ + +static void pic32mx_ep0nextsetup(struct pic32mx_usbdev_s *priv) +{ + volatile struct usbotg_bdtentry_s *bdt = priv->eplist[EP0].bdtout; + uint32_t bytecount; + + /* This operation should be performed no more than once per OUT transaction. + * priv->ep0done is set to zero at the beginning of processing of each EP0 + * transfer. It is set the first time that this function runs after the EP0 + * transfer. + */ + + if (!priv->ep0done) + { + bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); + bdt->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); + bdt->status = (USB_BDT_UOWN | bytecount); + priv->ep0done = 1; + } +} + +/**************************************************************************** + * Name: pic32mx_ep0rdcomplete + * + * Description: + * This function is called after a sequence of read sequence. In this + * context, only one BDT is used. Both BDTs must be prepared to receive + * SETUP packets. + * + ****************************************************************************/ + +static void pic32mx_ep0rdcomplete(struct pic32mx_usbdev_s *priv) +{ + volatile struct usbotg_bdtentry_s *bdt; + struct pic32mx_ep_s *ep0; + uint32_t physaddr; + uint32_t bytecount; + + /* This operation should be performed no more than once per OUT transaction. + * priv->ep0done is set to zero at the beginning of processing of each EP0 + * transfer. It is set the first time that this function runs after the EP0 + * transfer. + */ + + if (!priv->ep0done) + { + bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); + physaddr = PHYS_ADDR(&priv->ctrl); + + bdt = &g_bdt[EP0_OUT_EVEN]; + bdt->addr = (uint8_t *)physaddr; + bdt->status = (USB_BDT_UOWN | bytecount); + + bdt = &g_bdt[EP0_OUT_ODD]; + bdt->addr = (uint8_t *)physaddr; + bdt->status = (USB_BDT_UOWN | bytecount); + + priv->ep0done = 1; + + /* Data toggling is not used on SETUP transfers. And IN transfer + * resulting from a SETUP command should begin with DATA1. + */ + + ep0 = &priv->eplist[EP0]; + ep0->rxdata1 = 0; + ep0->txdata1 = 1; + } +} + +/**************************************************************************** + * Name: pic32mx_ep0setup + ****************************************************************************/ + +static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv) +{ + volatile struct usbotg_bdtentry_s *bdt; + struct pic32mx_ep_s *ep0; + struct pic32mx_ep_s *privep; + union wb_u value; + union wb_u index; + union wb_u len; + union wb_u response; + uint16_t regval; + bool dispatched = false; + uint8_t epno; + int nbytes = 0; /* Assume zero-length packet */ + int ret; + + /* Cancel any pending requests. */ + + ep0 = &priv->eplist[EP0]; + pic32mx_cancelrequests(ep0, -EPROTO); + + /* Assume NOT stalled; no TX in progress; no RX overrun. Data 0/1 toggling + * is not used on SETUP packets, but any following EP0 IN transfer should + * beginning with DATA1. + */ + + ep0->stalled = false; + ep0->rxdata1 = 0; + ep0->txdata1 = 1; + + /* Initialize for the SETUP */ + + priv->ctrlstate = CTRLSTATE_WAITSETUP; + + /* And extract the little-endian 16-bit values to host order */ + + value.w = GETUINT16(priv->ctrl.value); + index.w = GETUINT16(priv->ctrl.index); + len.w = GETUINT16(priv->ctrl.len); + + ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + + /* Dispatch any non-standard requests */ + + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standar requests */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + goto resume_packet_processing; /* Sorry about the goto */ + } + + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADEPGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPGETSTATUS), epno); + if (epno >= PIC32MX_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADEPGETSTATUS), epno); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + privep = &priv->eplist[epno]; + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ + + if (USB_ISEPIN(index.b[LSB])) + { + /* IN endpoint */ + + bdt = privep->bdtin; + } + else + { + /* OUT endpoint */ + + bdt = privep->bdtout; + } + + /* BSTALL set if stalled */ + + if ((bdt->status & USB_BDT_BSTALL) != 0) + { + response.b[LSB] = 1; /* Stalled, set bit 0 */ + } + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (priv->rwakeup << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADDEVGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* Disable B device from performing HNP */ + +#ifdef CONFIG_USBOTG + if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) + { + /* Disable HNP */ +#warning Missing Logic + } + + /* Disable A device HNP support */ + + else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) + { + /* Disable HNP support */ +#warning Missing Logic + } + + /* Disable alternate HNP support */ + + else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) + { + /* Disable alternate HNP */ +#warning Missing Logic + } + else +#endif + /* Disable remote wakeup */ + + if (value.w == USB_FEATURE_REMOTEWAKEUP) + { + priv->rwakeup = 0; + } + else + { + /* Let the class implementation handle all other device features */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT) + { + epno = USB_EPNO(index.b[LSB]); + if (epno > 0 && epno < PIC32MX_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = false; + ret = pic32mx_epstall(&privep->ep, true); + UNUSED(ret); + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADCLEARFEATURE), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + else + { + /* Let the class implementation handle all other recipients. */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_SETFEATURE), priv->ctrl.type); + + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* Enable B device to perform HNP */ + +#ifdef CONFIG_USBOTG + if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) + { + /* Enable HNP */ +#warning "Missing logic" + } + + /* Enable A device HNP supports */ + + else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) + { + /* Enable HNP support */ +#warning "Missing logic" + } + + /* Another port on the A device supports HNP */ + + else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) + { + /* Enable alternate HNP */ +#warning "Missing logic" + } + else +#endif + + if (value.w == USB_FEATURE_REMOTEWAKEUP) + { + priv->rwakeup = 0; + } + else if (value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + ullvdbg("test mode: %d\n", index.w); + } + else + { + /* Let the class implementation handle all other device features */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT) + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < PIC32MX_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = true; + ret = pic32mx_epstall(&privep->ep, false); + UNUSED(ret); + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADSETFEATURE), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + else + { + /* The class driver handles all recipients except recipient=endpoint */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0SETUPSETADDRESS), value.w); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADSETADDRESS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + /* Note that setting of the device address will be deferred. A zero-length + * packet will be sent and the device address will be set when the zero- + * length packet transfer completes. + */ + + priv->devstate = DEVSTATE_ADDRPENDING; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADGETSETDESC), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADGETCONFIG), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + index.w == 0 && len.w == 0) + { + /* The request seems valid... let the class implementation handle it */ + + pic32mx_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADSETCONFIG), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_GETSETIF), priv->ctrl.type); + pic32mx_dispatchrequest(priv); + dispatched = true; + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); + priv->ctrlstate = CTRLSTATE_STALL; + } + break; + } + + /* PKTDIS bit is set when a Setup Transaction is received. Clear to resume + * packet processing. + */ + +resume_packet_processing: + regval = pic32mx_getreg(PIC32MX_USB_CON); + regval &= ~USB_CON_PKTDIS; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* At this point, the request has been handled and there are three possible + * outcomes: + * + * 1. The setup request was successfully handled above and a response packet + * must be sent (may be a zero length packet). + * 2. The request was successfully handled by the class implementation. In + * case, the EP0 IN response has already been queued and the local variable + * 'dispatched' will be set to true and ctrlstate != CTRLSTATE_STALL; + * 3. An error was detected in either the above logic or by the class implementation + * logic. In either case, priv->state will be set CTRLSTATE_STALL + * to indicate this case. + * + * NOTE: Non-standard requests are a special case. They are handled by the + * class implementation and this function returned early above, skipping this + * logic altogether. + */ + + if (!dispatched && (priv->ctrlstate != CTRLSTATE_STALL)) + { + /* The SETUP command was not dispatched to the class driver and the SETUP + * command did not cause a stall. We will respond. First, restrict the + * data length to the length requested in the setup packet + */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* Send the EP0 SETUP response (might be a zero-length packet) */ + + pic32mx_epwrite(ep0, ep0->bdtin, response.b, nbytes); + priv->ctrlstate = CTRLSTATE_WAITSETUP; + } + + /* Did we stall? This might have occurred from the above logic OR the stall + * condition may have been set less obviously in pic32mx_dispatchrequest(). + * In either case, we handle the stall condition the same. + * + * However, bad things happen if we try to stall a SETUP packet. So lets + * not. If we wait a bit, things will recover. Hmmm.. If we completed + * the data phase (perhaps by sending a NULL packet), then I think we + * could stall the endpoint and perhaps speed things up a bit???. + */ + + /* Set up the BDT to accept the next setup commend. */ + + pic32mx_ep0nextsetup(priv); + priv->ctrlstate = CTRLSTATE_WAITSETUP; +} + +/**************************************************************************** + * Name: pic32mx_ep0incomplete + ****************************************************************************/ + +static void pic32mx_ep0incomplete(struct pic32mx_usbdev_s *priv) +{ + struct pic32mx_ep_s *ep0 = &priv->eplist[EP0]; + volatile struct usbotg_bdtentry_s *bdtlast; + int ret; + + /* Get the last BDT and make sure that we own it. */ + + bdtlast = ep0->bdtin; + + /* Make sure that we own the last BDT. */ + + bdtlast->status = 0; + bdtlast->addr = 0; + + /* Are we processing the completion of one packet of an outgoing request + * from the class driver? + */ + + if (priv->ctrlstate == CTRLSTATE_WRREQUEST) + { + /* An outgoing EP0 transfer has completed. Update the byte count and + * check for the completion of the transfer. + * + * NOTE: pic32mx_wrcomplete() will toggle bdtin to the other buffer so + * we do not need to that for this case. + */ + + pic32mx_wrcomplete(priv, &priv->eplist[EP0]); + + /* Handle the next queue IN transfer. If there are no further queued + * IN transfers, pic32mx_wrrequest will return -ENODATA and that is the + * only expected error return value in this context. + */ + + ret = pic32mx_wrrequest(priv, &priv->eplist[EP0]); + if (ret < 0) + { + DEBUGASSERT(ret == -ENODATA); + + /* If there is nothing to be sent, then we need to configure to + * receive the next SETUP packet. + */ + + priv->ctrlstate = CTRLSTATE_WAITSETUP; + } + } + + /* No.. Are we processing the completion of a status response? */ + + else if (priv->ctrlstate == CTRLSTATE_WAITSETUP) + { + /* Get the next IN BDT */ + + if (bdtlast == &g_bdt[EP0_IN_EVEN]) + { + ep0->bdtin = &g_bdt[EP0_IN_ODD]; + } + else + { + DEBUGASSERT(bdtlast == &g_bdt[EP0_IN_ODD]); + ep0->bdtin = &g_bdt[EP0_IN_EVEN]; + } + + /* Look at the saved SETUP command. Was it a SET ADDRESS request? + * If so, then now is the time to set the address. + */ + + if (priv->devstate == DEVSTATE_ADDRPENDING) + { + uint16_t addr = GETUINT16(priv->ctrl.value); + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0ADDRESSSET), addr); + + /* This should be the equivalent state */ + + DEBUGASSERT(priv->ctrl.req == USB_REQ_SETADDRESS && + (priv->ctrl.type & REQRECIPIENT_MASK) == + (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_DEVICE)); + + /* Set (or clear) the address */ + + pic32mx_putreg(addr, PIC32MX_USB_ADDR); + if (addr > 0) + { + priv->devstate = DEVSTATE_ADDRESS; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + } + } + } + + /* No other state is expected in this context */ + + else + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDSTATE), priv->ctrlstate); + priv->ctrlstate = CTRLSTATE_STALL; + } +} + +/**************************************************************************** + * Name: pic32mx_ep0outcomplete + ****************************************************************************/ + +static void pic32mx_ep0outcomplete(struct pic32mx_usbdev_s *priv) +{ + struct pic32mx_ep_s *ep0 = &priv->eplist[EP0]; + + switch (priv->ctrlstate) + { + /* Read request in progress */ + + case CTRLSTATE_RDREQUEST: + + /* Process the next read request for EP0 */ + + pic32mx_rdcomplete(priv, ep0); + + /* Was this the end of the OUT transfer? */ + + if (priv->ctrlstate == CTRLSTATE_WAITSETUP) + { + /* Prepare EP0 OUT for the next SETUP transaction. */ + + pic32mx_ep0rdcomplete(priv); + } + break; + + /* No transfer in progress, waiting for SETUP */ + + case CTRLSTATE_WAITSETUP: + { + /* In this case the last OUT transaction must have been a status + * stage of a CTRLSTATE_WRREQUEST: Prepare EP0 OUT for the next SETUP + * transaction. + */ + + pic32mx_ep0nextsetup(priv); + } + break; + + /* Unexpected state OR host aborted the OUT transfer before it completed, + * STALL the endpoint in either case + */ + + default: + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDSTATE), priv->ctrlstate); + priv->ctrlstate = CTRLSTATE_STALL; + } + break; + } +} + +/**************************************************************************** + * Name: pic32mx_ep0transfer + ****************************************************************************/ + +static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t ustat) +{ + volatile struct usbotg_bdtentry_s *bdt; + + /* The following information is available in the status register : + * + * ENDPT - The 4 bit endpoint number that cause the interrupt. + * DIR - The direction of the endpoint. + * PPBI - The ping-pong buffer used in the transaction. + */ + + priv->ep0done = 0; + + /* Check if the last transaction was an EP0 OUT transaction */ + + if ((ustat & USB_STAT_DIR) == USB_STAT_DIR_OUT) + { + int index; + + /* It was an EP0 OUT transaction. Get the index to the BDT. */ + + index = ((ustat & USB_STAT_PPBI) == 0 ? EP0_OUT_EVEN : EP0_OUT_ODD); + bdt = &g_bdt[index]; + priv->eplist[0].bdtout = bdt; + + bdtdbg("EP0 BDT OUT [%p] {%08x, %08x}\n", bdt, bdt->status, bdt->addr); + + /* Check the current EP0 OUT buffer contains a SETUP packet */ + + if (((bdt->status & USB_BDT_PID_MASK) >> USB_BDT_PID_SHIFT) == USB_PID_SETUP_TOKEN) + { + /* Check if the SETUP transaction data went into the priv->ctrl + * buffer. If not, then we will need to copy it. + */ + + if (bdt->addr != (uint8_t *)PHYS_ADDR(&priv->ctrl)) + { + void *src = (void *)VIRT_ADDR(bdt->addr); + void *dest = &priv->ctrl; + + memcpy(dest, src, USB_SIZEOF_CTRLREQ); + bdt->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); + } + + /* Handle the control OUT transfer */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0SETUPDONE), bdt->status); + pic32mx_ep0setup(priv); + } + else + { + /* Handle the data OUT transfer */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0OUTDONE), ustat); + pic32mx_ep0outcomplete(priv); + } + } + + /* No.. it was an EP0 IN transfer */ + + else /* if ((status & USB_STAT_DIR) == USB_STAT_DIR_IN) */ + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0INDONE), ustat); + + /* Handle the IN transfer complete */ + + pic32mx_ep0incomplete(priv); + } + + /* Check for a request to stall EP0 */ + + if (priv->ctrlstate == CTRLSTATE_STALL) + { + /* Stall EP0 */ + + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_EP0SETUPSTALLED), priv->ctrlstate); + (void)pic32mx_epstall(&priv->eplist[EP0].ep, false); + } +} + +/**************************************************************************** + * Name: pic32mx_interrupt + ****************************************************************************/ + +static int pic32mx_interrupt(int irq, void *context) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + uint16_t usbir; + uint16_t otgir; + uint16_t regval; + int i; + + /* Get the set of pending USB and OTG interrupts interrupts */ + + usbir = pic32mx_getreg(PIC32MX_USB_IR) & pic32mx_getreg(PIC32MX_USB_IE); + otgir = pic32mx_getreg(PIC32MX_USBOTG_IR) & pic32mx_getreg(PIC32MX_USBOTG_IE); + usbtrace(TRACE_INTENTRY(PIC32MX_TRACEINTID_INTERRUPT), usbir | otgir); + +#ifdef CONFIG_USBOTG + /* Session Request Protocol (SRP) Time Out Check */ + + /* if USB OTG SRP is ready */ +# warning "Missing logic" + { + /* Check if the 1 millisecond timer has expired */ + + if (otgir & OTG_INT_T1MSEC) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_T1MSEC), otgir); + + /* Check for the USB OTG SRP timeout */ +# warning "Missing logic" + { + /* Handle OTG events of the SRP timeout has expired */ +# warning "Missing logic" + } + + /* Clear Interrupt 1 msec timer Flag */ + + pic32mx_putreg(USBOTG_INT_T1MSEC, PIC32MX_USBOTG_IR); + } + } +#endif + + /* Handle events while we are in the attached state */ + + if (priv->devstate == DEVSTATE_ATTACHED) + { + /* Clear all USB interrupts */ + + pic32mx_putreg(USB_INT_ALL, PIC32MX_USB_IR); + + /* Make sure that the USE reset and IDLE detect interrupts are enabled */ + + regval = pic32mx_getreg(PIC32MX_USB_IE); + regval |= (USB_INT_URST | USB_INT_IDLE); + pic32mx_putreg(regval, PIC32MX_USB_IE); + + /* Now were are in the powered state */ + + priv->devstate = DEVSTATE_POWERED; + } + +#ifdef CONFIG_USBOTG + /* Check if the ID Pin Changed State */ + + if (otgir & USBOTG_INT_ID) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_OTGID), otgir); + + /* Re-detect and re-initialize */ +#warning "Missing logic" + + pic32mx_putreg(USBOTG_INT_ID, PIC32MX_USBOTG_IR); + } +#endif + + /* Service the USB Activity Interrupt */ + + if ((otgir & USBOTG_INT_ACTV) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_WKUP), otgir); + + /* Wake-up from susepnd mode */ + + pic32mx_putreg(USBOTG_INT_ACTV, PIC32MX_USBOTG_IR); + pic32mx_resume(priv); + } + + /* It is pointless to continue servicing if the device is in suspend mode. */ + + if ((pic32mx_getreg(PIC32MX_USB_PWRC) & USB_PWRC_USUSPEND) != 0) + { + /* Just clear the interrupt and return */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_SUSPENDED), pic32mx_getreg(PIC32MX_USB_PWRC)); + goto interrupt_exit; + } + + /* Service USB Bus Reset Interrupt. When bus reset is received during + * suspend, ACTVIF will be set first, once the UCONbits.SUSPND is clear, + * then the URSTIF bit will be asserted. This is why URSTIF is checked + * after ACTVIF. The USB reset flag is masked when the USB state is in + * DEVSTATE_DETACHED or DEVSTATE_ATTACHED, and therefore cannot cause a + * USB reset event during these two states. + */ + + if ((usbir & USB_INT_URST) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_RESET), usbir); + + /* Reset interrupt received. Restore our initial state. NOTE: the + * hardware automatically resets the USB address, so we really just + * need reset any existing configuration/transfer states. + */ + + pic32mx_reset(priv); + priv->devstate = DEVSTATE_DEFAULT; + +#ifdef CONFIG_USBOTG + /* Disable and deactivate HNP */ +#warning Missing Logic +#endif + /* Acknowlege the reset interrupt */ + + pic32mx_putreg(USB_INT_URST, PIC32MX_USB_IR); + goto interrupt_exit; + } + + /* Service IDLE interrupts */ + + if ((usbir & USB_INT_IDLE) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_IDLE), usbir); + +#ifdef CONFIG_USBOTG + /* If Suspended, Try to switch to Host */ +#warning "Missing logic" +#else + pic32mx_suspend(priv); + +#endif + pic32mx_putreg(USB_INT_IDLE, PIC32MX_USB_IR); + } + + /* Service SOF interrupts */ + +#ifdef CONFIG_USB_SOFINTS + if ((usbir & USB_INT_SOF) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_SOF), 0); + + /* I am not sure why you would ever enable SOF interrupts */ + + pic32mx_putreg(USB_INT_SOF, PIC32MX_USB_IR); + } +#endif + + /* Service stall interrupts */ + + if ((usbir & USB_INT_STALL) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_STALL), usbir); + + pic32mx_ep0stall(priv); + + /* Clear the pending STALL interrupt */ + + pic32mx_putreg(USB_INT_STALL, PIC32MX_USB_IR); + } + + /* Service error interrupts */ + + if ((usbir & USB_INT_UERR) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_UERR), usbir); + ulldbg("Error: EIR=%04x\n", pic32mx_getreg(PIC32MX_USB_EIR)); + + /* Clear all pending USB error interrupts */ + + pic32mx_putreg(USB_EINT_ALL, PIC32MX_USB_EIR); + } + + /* There is no point in continuing if the host has not sent a bus reset. + * Once bus reset is received, the device transitions into the DEFAULT + * state and is ready for communication. + */ + + if (priv->devstate < DEVSTATE_DEFAULT) + { + /* Just clear the interrupt and return */ + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_WAITRESET), priv->devstate); + goto interrupt_exit; + } + + /* Service USB Transaction Complete Interrupt */ + + if ((usbir & USB_INT_TRN) != 0) + { + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_TRNC), usbir); + + /* Drain the USAT FIFO entries. If the USB FIFO ever gets full, USB + * bandwidth utilization can be compromised, and the device won't be + * able to receive SETUP packets. + */ + + for (i = 0; i < 4; i++) + { + uint8_t epno; + + /* Check the pending interrupt register. Is token processing complete. */ + + if ((pic32mx_getreg(PIC32MX_USB_IR) & USB_INT_TRN) != 0) + { + regval = pic32mx_getreg(PIC32MX_USB_STAT); + pic32mx_putreg(USB_INT_TRN, PIC32MX_USB_IR); + + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_TRNCS), regval); + + /* Handle the endpoint transfer complete event. */ + + epno = (regval & USB_STAT_ENDPT_MASK) >> USB_STAT_ENDPT_SHIFT; + if (epno == 0) + { + pic32mx_ep0transfer(priv, regval); + } + else + { + pic32mx_eptransfer(priv, epno, regval); + } + } + else + { + /* USTAT FIFO must be empty. */ + + break; + } + } + } + + /* Clear the pending USB interrupt. Goto is used in the above to assure + * that all interrupt exists pass through this logic. + */ + +interrupt_exit: + up_clrpend_irq(PIC32MX_IRQSRC_USB); + usbtrace(TRACE_INTEXIT(PIC32MX_TRACEINTID_INTERRUPT), usbir | otgir); + return OK; +} + +/**************************************************************************** + * Suspend/Resume Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_suspend + ****************************************************************************/ + +static void pic32mx_suspend(struct pic32mx_usbdev_s *priv) +{ + uint16_t regval; + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* Enable the ACTV interrupt. + * + * NOTE: Do not clear UIRbits.ACTVIF here! Reason: ACTVIF is only + * generated once an IDLEIF has been generated. This is a 1:1 ratio + * interrupt generation. For every IDLEIF, there will be only one ACTVIF + * regardless of the number of subsequent bus transitions. If the ACTIF + * is cleared here, a problem could occur. The driver services IDLEIF + * first because ACTIVIE=0. If this routine clears the only ACTIVIF, + * then it can never get out of the suspend mode. + */ + + regval = pic32mx_getreg(PIC32MX_USBOTG_IE); + regval |= USBOTG_INT_ACTV; + pic32mx_putreg(regval, PIC32MX_USBOTG_IE); + + /* Disable further IDLE interrupts. Once is enough. */ + + regval = pic32mx_getreg(PIC32MX_USB_IE); + regval &= ~USB_INT_IDLE; + pic32mx_putreg(regval, PIC32MX_USB_IE); + + /* Invoke a callback into board-specific logic. The board-specific logic + * may enter into sleep or idle modes or switch to a slower clock, etc. + */ + + pic32mx_usbsuspend((struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: pic32mx_resume + ****************************************************************************/ + +static void pic32mx_resume(struct pic32mx_usbdev_s *priv) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + + /* Start RESUME signaling */ + + regval = pic32mx_getreg(PIC32MX_USB_CON); + regval |= USB_CON_RESUME; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* Keep the RESUME line set for 1-13 ms */ + + up_mdelay(10); + + regval &= ~USB_CON_RESUME; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* This function is called when the USB activity interrupt occurs. + * If using clock switching, this is the place to call out to + * logic to restore the original MCU core clock frequency. + */ + + pic32mx_usbsuspend((struct usbdev_s *)priv, true); + + /* Disable further activity interrupts */ + + regval = pic32mx_getreg(PIC32MX_USBOTG_IE); + regval &= ~USBOTG_INT_ACTV; + pic32mx_putreg(regval, PIC32MX_USBOTG_IE); + + /* The ACTVIF bit cannot be cleared immediately after the USB module wakes + * up from Suspend or while the USB module is suspended. A few clock cycles + * are required to synchronize the internal hardware state machine before + * the ACTIVIF bit can be cleared by firmware. Clearing the ACTVIF bit + * before the internal hardware is synchronized may not have an effect on + * the value of ACTVIF. Additionally, if the USB module uses the clock from + * the 96 MHz PLL source, then after clearing the SUSPND bit, the USB + * module may not be immediately operational while waiting for the 96 MHz + * PLL to lock. + */ + + pic32mx_putreg(USB_INT_IDLE, PIC32MX_USBOTG_IR); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Endpoint Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_epreserve + ****************************************************************************/ + +static inline struct pic32mx_ep_s * +pic32mx_epreserve(struct pic32mx_usbdev_s *priv, uint8_t epset) +{ + struct pic32mx_ep_s *privep = NULL; + irqstate_t flags; + int epndx = 0; + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available endpoints + * (skipping EP0) + */ + + for (epndx = 1; epndx < PIC32MX_NENDPOINTS; epndx++) + { + uint8_t bit = PIC32MX_ENDP_BIT(epndx); + if ((epset & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail &= ~bit; + + /* And return the pointer to the standard endpoint structure */ + + privep = &priv->eplist[epndx]; + break; + } + } + } + + leave_critical_section(flags); + return privep; +} + +/**************************************************************************** + * Name: pic32mx_epunreserve + ****************************************************************************/ + +static inline void +pic32mx_epunreserve(struct pic32mx_usbdev_s *priv, struct pic32mx_ep_s *privep) +{ + irqstate_t flags = enter_critical_section(); + priv->epavail |= PIC32MX_ENDP_BIT(USB_EPNO(privep->ep.eplog)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: pic32mx_epreserved + ****************************************************************************/ + +static inline bool +pic32mx_epreserved(struct pic32mx_usbdev_s *priv, int epno) +{ + return ((priv->epavail & PIC32MX_ENDP_BIT(epno)) == 0); +} + +/**************************************************************************** + * Name: pic32mx_ep0configure + ****************************************************************************/ + +static void pic32mx_ep0configure(struct pic32mx_usbdev_s *priv) +{ + volatile struct usbotg_bdtentry_s *bdt; + struct pic32mx_ep_s *ep0; + uint32_t bytecount; + + /* Enable the EP0 endpoint */ + + pic32mx_putreg(PIC32MX_EP_CONTROL, PIC32MX_USB_EP0); + + /* Configure the OUT BDTs. We assume that the ping-poing buffer index has + * just been reset and we expect to receive on the EVEN BDT first. Data + * toggle synchronization is not needed for SETUP packets. + */ + + ep0 = &priv->eplist[EP0]; + bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); + + bdt = &g_bdt[EP0_OUT_EVEN]; + bdt->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); + bdt->status = (USB_BDT_UOWN | bytecount); + ep0->bdtout = bdt; + + bdt++; + bdt->status = (USB_BDT_UOWN | bytecount); + bdt->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); + + /* Configure the IN BDTs. */ + + bdt = &g_bdt[EP0_IN_EVEN]; + bdt->status = 0; + bdt->addr = 0; + ep0->bdtin = bdt; + + bdt++; + bdt->status = 0; + bdt->addr = 0; + + /* Data toggling is not used on SETUP transfers. And IN transfer resulting + * from a SETUP command should begin with DATA1. + */ + + ep0->rxdata1 = 0; + ep0->txdata1 = 1; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_epconfigure + ****************************************************************************/ + +static int pic32mx_epconfigure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct pic32mx_ep_s *privep = (struct pic32mx_ep_s *)ep; + volatile struct usbotg_bdtentry_s *bdt; + uint16_t maxpacket; + uint16_t regval; + uint8_t epno; + bool epin; + bool bidi; + int index; + +#ifdef CONFIG_DEBUG + if (!ep || !desc) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p desc=%p\n"); + return -EINVAL; + } +#endif + + /* Get the unadorned endpoint address */ + + epno = USB_EPNO(desc->addr); + epin = USB_ISEPIN(desc->addr); + + usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno); + DEBUGASSERT(epno == USB_EPNO(ep->eplog)); + + /* Set the requested type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + regval = epin ? PIC32MX_EP_INTIN : PIC32MX_EP_INTOUT; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + regval = epin ? PIC32MX_EP_BULKIN : PIC32MX_EP_BULKOUT; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + regval = epin ? PIC32MX_EP_ISOCIN : PIC32MX_EP_ISOCOUT; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint */ + regval = PIC32MX_EP_CONTROL; + bidi = true; + break; + + default: + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADEPTYPE), (uint16_t)desc->type); + return -EINVAL; + } + + /* Enable the endpoint */ + + pic32mx_putreg(regval, PIC32MX_USB_EP(epno)); + + /* Setup up buffer descriptor table (BDT) entry/ies for this endpoint */ + + if (epin || bidi) + { + /* Get the pointer to BDT entry */ + + index = EP(epno, EP_DIR_IN, EP_PP_EVEN); + bdt = &g_bdt[index]; + privep->bdtin = bdt; + + /* Mark that we own the entry */ + + bdt->status = 0; + bdt->addr = 0; + + bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr); + + /* Now do the same for the other buffer. */ + + bdt++; + bdt->status = 0; + bdt->addr = 0; + + bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr); + } + + if (!epin || bidi) + { + index = EP(epno, EP_DIR_OUT, EP_PP_EVEN); + bdt = &g_bdt[index]; + privep->bdtout = bdt; + + /* Mark that we own the entry */ + + bdt->status = 0; + bdt->addr = 0; + + bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr); + + /* Now do the same for the other buffer. */ + + bdt++; + bdt->status = 0; + bdt->addr = 0; + + bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr); + } + + /* Get the maxpacket size of the endpoint. */ + + maxpacket = GETUINT16(desc->mxpacketsize); + DEBUGASSERT(maxpacket <= PIC32MX_MAXPACKET_SIZE); + ep->maxpacket = maxpacket; + + /* Set the full, logic EP number (that includes direction encoded in bit 7) */ + + if (epin) + { + ep->eplog = USB_EPIN(epno); + } + else + { + ep->eplog = USB_EPOUT(epno); + } + + return OK; +} + +/**************************************************************************** + * Name: pic32mx_epdisable + ****************************************************************************/ + +static int pic32mx_epdisable(struct usbdev_ep_s *ep) +{ + struct pic32mx_ep_s *privep; + volatile uint32_t *ptr; + int epno; + int i; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: ep=%p\n", ep); + return -EINVAL; + } +#endif + + privep = (struct pic32mx_ep_s *)ep; + epno = USB_EPNO(ep->eplog); + usbtrace(TRACE_EPDISABLE, epno); + + /* Cancel any ongoing activity */ + + flags = enter_critical_section(); + pic32mx_cancelrequests(privep, -ESHUTDOWN); + + /* Disable the endpoint */ + + pic32mx_putreg(0, PIC32MX_USB_EP(epno)); + + /* Reset the BDTs for the endpoint. Four BDT entries per endpoint; Two + * 32-bit words per BDT. + */ + + ptr = (uint32_t *)&g_bdt[EP(epno, EP_DIR_OUT, EP_PP_EVEN)]; + for (i = 0; i < USB_BDT_WORD_SIZE * USB_NBDTS_PER_EP; i++) + { + *ptr++ = 0; + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: pic32mx_epallocreq + ****************************************************************************/ + +static struct usbdev_req_s *pic32mx_epallocreq(struct usbdev_ep_s *ep) +{ + struct pic32mx_req_s *privreq; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + usbtrace(TRACE_EPALLOCREQ, USB_EPNO(ep->eplog)); + + privreq = (struct pic32mx_req_s *)kmm_malloc(sizeof(struct pic32mx_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct pic32mx_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: pic32mx_epfreereq + ****************************************************************************/ + +static void pic32mx_epfreereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct pic32mx_req_s *privreq = (struct pic32mx_req_s *)req; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + usbtrace(TRACE_EPFREEREQ, USB_EPNO(ep->eplog)); + + kmm_free(privreq); +} + +/**************************************************************************** + * Name: pic32mx_epsubmit + ****************************************************************************/ + +static int pic32mx_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct pic32mx_req_s *privreq = (struct pic32mx_req_s *)req; + struct pic32mx_ep_s *privep = (struct pic32mx_ep_s *)ep; + struct pic32mx_usbdev_s *priv; + irqstate_t flags; + uint8_t epno; + int ret = OK; + +#ifdef CONFIG_DEBUG + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + ulldbg("ERROR: req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); + priv = privep->dev; + +#ifdef CONFIG_DEBUG + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + ulldbg("ERROR: driver=%p\n", priv->driver); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + epno = USB_EPNO(ep->eplog); + req->result = -EINPROGRESS; + req->xfrd = 0; + privreq->inflight[0] = 0; +#ifndef CONFIG_USBDEV_NOWRITEAHEAD + privreq->inflight[1] = 0; +#endif + flags = enter_critical_section(); + + /* Add the new request to the request queue for the OUT endpoint */ + + pic32mx_addlast(&privep->pend, privreq); + + /* Handle IN (device-to-host) requests. NOTE: If the class device is + * using the bi-directional EP0, then we assume that they intend the EP0 + * IN functionality. + */ + + if (USB_ISEPIN(ep->eplog) || epno == EP0) + { + usbtrace(TRACE_INREQQUEUED(epno), req->len); + + /* If the endpoint is not stalled and an IN endpoint BDT is available, + * then transfer the data now. + */ + + if (!privep->stalled) + { + (void)pic32mx_wrrequest(priv, privep); + } + } + + /* Handle OUT (host-to-device) requests */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(epno), req->len); + + /* Set up the read operation (unless the endpoint is stalled). Because + * the PIC32MX supports ping-pong* buffering. There may be two pending + * read requests. The following call will attempt to setup a read + * using this request for this endpoint. It is not harmful if this + * fails. + */ + + if (!privep->stalled) + { + (void)pic32mx_rdrequest(priv, privep); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: pic32mx_epcancel + ****************************************************************************/ + +static int pic32mx_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) +{ + struct pic32mx_ep_s *privep = (struct pic32mx_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); + + flags = enter_critical_section(); + pic32mx_cancelrequests(privep, -EAGAIN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: pic32mx_epbdtstall + ****************************************************************************/ + +static int pic32mx_epbdtstall(struct usbdev_ep_s *ep, bool resume, bool epin) +{ + struct pic32mx_ep_s *privep; + struct pic32mx_usbdev_s *priv; + volatile struct usbotg_bdtentry_s *bdt; + volatile struct usbotg_bdtentry_s *otherbdt; + uint32_t regaddr; + uint16_t regval; + uint8_t epno; + + /* Recover pointers */ + + privep = (struct pic32mx_ep_s *)ep; + priv = (struct pic32mx_usbdev_s *)privep->dev; + epno = USB_EPNO(ep->eplog); + + /* Check for an IN endpoint */ + + if (epin) + { + /* Get a pointer to the current IN BDT */ + + bdt = privep->bdtin; + + /* Get the other BDT */ + + otherbdt = &g_bdt[EP(epno, EP_DIR_IN, EP_PP_EVEN)]; + if (otherbdt == bdt) + { + otherbdt++; + } + + /* Reset the data toggle */ + + privep->txdata1 = false; + } + + /* Otherwise it is an an OUT endpoint. */ + + else + { + /* Get a pointer to the current OUT BDT */ + + bdt = privep->bdtout; + + /* Get a pointer to the other BDT */ + + otherbdt = &g_bdt[EP(epno, EP_DIR_OUT, EP_PP_EVEN)]; + if (otherbdt == bdt) + { + otherbdt++; + } + + /* Reset the data toggle */ + + privep->rxdata1 = false; + } + + /* Handle the resume condition */ + + if (resume) + { + /* Resuming a stalled endpoint */ + + usbtrace(TRACE_EPRESUME, epno); + + /* Point to the appropriate EP register */ + + regaddr = PIC32MX_USB_EP(epno); + + /* Clear the STALL bit in the UEP register */ + + regval = pic32mx_getreg(regaddr); + regval &= ~USB_EP_EPSTALL; + pic32mx_putreg(regval, regaddr); + + /* Check for the EP0 OUT endpoint. This is a special case because we + * need to set it up to receive the next setup packet (Hmmm... what + * if there are queued outgoing reponses. We need to revisit this.) + */ + + if (epno == 0 && !epin) + { + uint32_t bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); + uint32_t physaddr = PHYS_ADDR(&priv->ctrl); + + /* Configure the other BDT to receive a SETUP command. */ + + otherbdt->addr = (uint8_t *)physaddr; + otherbdt->status = (USB_BDT_UOWN | bytecount); + + /* Configure the current BDT to receive a SETUP command. */ + + bdt->addr = (uint8_t *)physaddr; + bdt->status = (USB_BDT_UOWN | bytecount); + + bdtdbg("EP0 BDT IN [%p] {%08x, %08x}\n", + bdt, bdt->status, bdt->addr); + bdtdbg("EP0 BDT IN [%p] {%08x, %08x}\n", + otherbdt, otherbdt->status, otherbdt->addr); + } + else + { + /* Return the other BDT to the CPU. */ + + otherbdt->addr = 0; + otherbdt->status = 0; + + /* Return the current BDT to the CPU. */ + + bdt->addr = 0; + bdt->status = 0; + + bdtdbg("EP%d BDT %s [%p] {%08x, %08x}\n", + epno, epin ? "IN" : "OUT", bdt, bdt->status, bdt->addr); + bdtdbg("EP%d BDT %s [%p] {%08x, %08x}\n", + epno, epin ? "IN" : "OUT", otherbdt, otherbdt->status, otherbdt->addr); + + /* Restart any queued requests (after a delay so that we can be assured + * that the hardware has recovered from the stall -- I don't know of any + * other way to assure this.). + */ + + pic32mx_delayedrestart(priv, epno); + } + } + + /* Handle the stall condition */ + + else + { + usbtrace(TRACE_EPSTALL, epno); + privep->stalled = true; + + /* Stall the other BDT. */ + + otherbdt->status = (USB_BDT_UOWN | USB_BDT_BSTALL); + otherbdt->addr = 0; + + /* Stall the current BDT. */ + + bdt->status = (USB_BDT_UOWN | USB_BDT_BSTALL); + bdt->addr = 0; + + /* Stop any queued requests. Hmmm.. is there a race condition here? */ + + pic32mx_rqstop(privep); + + bdtdbg("EP%d BDT %s [%p] {%08x, %08x}\n", + epno, epin ? "IN" : "OUT", bdt, bdt->status, bdt->addr); + bdtdbg("EP%d BDT %s [%p] {%08x, %08x}\n", + epno, epin ? "IN" : "OUT", otherbdt, otherbdt->status, otherbdt->addr); + } + + return OK; +} + +/**************************************************************************** + * Name: pic32mx_epstall + ****************************************************************************/ + +static int pic32mx_epstall(struct usbdev_ep_s *ep, bool resume) +{ + struct pic32mx_ep_s *privep; + irqstate_t flags; + int ret; + +#ifdef CONFIG_DEBUG + if (!ep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Recover pointers */ + + privep = (struct pic32mx_ep_s *)ep; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + + /* Special case EP0. When we stall EP0 we have to stall both the IN and + * OUT BDTs. + */ + + if (USB_EPNO(ep->eplog) == 0) + { + ret = pic32mx_epbdtstall(ep, resume, true); + if (ret == OK) + { + ret = pic32mx_epbdtstall(ep, resume, false); + } + + /* Set the EP0 control state appropriately */ + + privep->dev->ctrlstate = resume ? CTRLSTATE_WAITSETUP : CTRLSTATE_STALLED; + } + + /* Otherwise, select the BDT for the endpoint direction */ + + else + { + /* It is a unidirectional endpoint */ + + ret = pic32mx_epbdtstall(ep, resume, USB_ISEPIN(ep->eplog)); + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Device Controller Operations + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_allocep + ****************************************************************************/ + +static struct usbdev_ep_s *pic32mx_allocep(struct usbdev_s *dev, uint8_t epno, + bool epin, uint8_t eptype) +{ + struct pic32mx_usbdev_s *priv = (struct pic32mx_usbdev_s *)dev; + struct pic32mx_ep_s *privep = NULL; + uint16_t epset = PIC32MX_ENDP_ALLSET; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + /* Ignore any direction bits in the logical address */ + + epno = USB_EPNO(epno); + + /* A logical address of 0 means that any endpoint will do */ + + if (epno > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epno >= PIC32MX_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BADEPNO), (uint16_t)epno); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset = PIC32MX_ENDP_BIT(epno); + } + + /* Check if the selected endpoint number is available */ + + privep = pic32mx_epreserve(priv, epset); + if (!privep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_EPRESERVE), (uint16_t)epset); + return NULL; + } + + return &privep->ep; +} + +/**************************************************************************** + * Name: pic32mx_freeep + ****************************************************************************/ + +static void pic32mx_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) +{ + struct pic32mx_usbdev_s *priv; + struct pic32mx_ep_s *privep; + +#ifdef CONFIG_DEBUG + if (!dev || !ep) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + priv = (struct pic32mx_usbdev_s *)dev; + privep = (struct pic32mx_ep_s *)ep; + usbtrace(TRACE_DEVFREEEP, (uint16_t)USB_EPNO(ep->eplog)); + DEBUGASSERT(priv && privep); + + /* Disable the endpoint */ + + (void)pic32mx_epdisable(ep); + + /* Mark the endpoint as available */ + + pic32mx_epunreserve(priv, privep); +} + +/**************************************************************************** + * Name: pic32mx_getframe + ****************************************************************************/ + +static int pic32mx_getframe(struct usbdev_s *dev) +{ + uint16_t frml; + uint16_t frmh; + uint16_t tmp; + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Return the last frame number detected by the hardware. Thr FRMH/L + * registers are updated with the current frame number whenever a SOF + * TOKEN is received. + */ + + do + { + /* Loop until we can be sure that there was no wrap from the FRML + * to the FRMH register. + */ + + frmh = pic32mx_getreg(PIC32MX_USB_FRMH) & USB_FRMH_MASK; + frml = pic32mx_getreg(PIC32MX_USB_FRML) & USB_FRML_MASK; + tmp = pic32mx_getreg(PIC32MX_USB_FRMH) & USB_FRMH_MASK; + } + while (frmh != tmp); + + /* Combine to for the full 11-bit value */ + + tmp = (frmh) << 8 | frml; + usbtrace(TRACE_DEVGETFRAME, tmp); + return tmp; +} + +/**************************************************************************** + * Name: pic32mx_wakeup + ****************************************************************************/ + +static int pic32mx_wakeup(struct usbdev_s *dev) +{ + struct pic32mx_usbdev_s *priv = (struct pic32mx_usbdev_s *)dev; + + usbtrace(TRACE_DEVWAKEUP, 0); +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Resume normal operation. */ + + pic32mx_resume(priv); + return OK; +} + +/**************************************************************************** + * Name: pic32mx_selfpowered + ****************************************************************************/ + +static int pic32mx_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct pic32mx_usbdev_s *priv = (struct pic32mx_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG + if (!dev) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Initialization/Reset + ****************************************************************************/ +/**************************************************************************** + * Name: pic32mx_reset + * + * Description: + * Reset the software and hardware states. If the USB controller has been + * attached to a host, then connect to the bus as well. At the end of + * this reset, the hardware should be in the full up, ready-to-run state. + * + ****************************************************************************/ + +static void pic32mx_reset(struct pic32mx_usbdev_s *priv) +{ + /* Reset the software configuration */ + + pic32mx_swreset(priv); + + /* Re-configure the USB controller in its initial, unconnected state */ + + pic32mx_hwreset(priv); + + /* pic32mx_attach() was called, then the attach flag will be set and we + * should also attach to the USB bus. + */ + + if (priv->attached) + { + /* usbdev_attach() has already been called.. attach to the bus + * now + */ + + pic32mx_attach(priv); + } +} + +/**************************************************************************** + * Name: pic32mx_attach + ****************************************************************************/ + +static void pic32mx_attach(struct pic32mx_usbdev_s *priv) +{ + uint16_t regval; + + /* Check if we are in the detached state */ + + if (priv->devstate == DEVSTATE_DETACHED) + { + /* Disable USB interrupts at the interrupt controller */ + + up_disable_irq(PIC32MX_IRQSRC_USB); + + /* Initialize registers to known states. */ + + pic32mx_putreg(0, PIC32MX_USB_CON); + + /* Configure things like: pull ups, full/low-speed mode, + * set the ping pong mode, and set internal transceiver + */ + + pic32mx_putreg(0, PIC32MX_USB_CNFG1); + + /* Enable interrupts at the USB controller */ + + pic32mx_putreg(ERROR_INTERRUPTS, PIC32MX_USB_EIE); + pic32mx_putreg(NORMAL_INTERRUPTS, PIC32MX_USB_IE); + + /* Configure EP0 */ + + pic32mx_ep0configure(priv); + + /* Flush any pending transactions */ + + while ((pic32mx_getreg(PIC32MX_USB_IR) & USB_INT_TRN) != 0) + { + pic32mx_putreg(USB_INT_TRN, PIC32MX_USB_IR); + } + + /* Make sure packet processing is enabled */ + + regval = pic32mx_getreg(PIC32MX_USB_CON); + regval &= ~USB_CON_PKTDIS; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* Enable the USB module and attach to bus */ + + do + { + regval = pic32mx_getreg(PIC32MX_USB_CON); + if ((regval & USB_CON_USBEN) == 0) + { + pic32mx_putreg(regval | USB_CON_USBEN, PIC32MX_USB_CON); + } + } + while ((regval & USB_CON_USBEN) == 0); + + /* Enable OTG */ + +#ifdef CONFIG_USBOTG + regval = pic32mx_getreg(PIC32MX_USBOTG_CON); + regval |= (USBOTG_CON_DPPULUP | USBOTG_CON_OTGEN); + pic32mx_putreg(regval, PIC32MX_USBOTG_CON); +#endif + + /* Transition to the attached state */ + + priv->devstate = DEVSTATE_ATTACHED; + priv->usbdev.speed = USB_SPEED_FULL; + + /* Clear all pending USB interrupts */ + + pic32mx_putreg(USB_EINT_ALL, PIC32MX_USB_EIR); + pic32mx_putreg(USB_INT_ALL, PIC32MX_USB_IR); + + /* Enable USB interrupts at the interrupt controller */ + + up_enable_irq(PIC32MX_IRQSRC_USB); + + /* Enable pull-up to connect the device. The host should enumerate us + * some time after this + */ + + pic32mx_usbpullup(&priv->usbdev, true); + } +} + +/**************************************************************************** + * Name: pic32mx_detach + ****************************************************************************/ + +static void pic32mx_detach(struct pic32mx_usbdev_s *priv) +{ + /* Disable USB interrupts at the interrupt controller */ + + up_disable_irq(PIC32MX_IRQSRC_USB); + + /* Disable the USB controller and detach from the bus. */ + + pic32mx_putreg(0, PIC32MX_USB_CON); + + /* Mask all USB interrupts */ + + pic32mx_putreg(0, PIC32MX_USB_IE); + + /* We are now in the detached state */ + + priv->attached = 0; + priv->devstate = DEVSTATE_DETACHED; + +#ifdef CONFIG_USBOTG + /* Disable the D+ Pullup */ + + regval = pic32mx_getreg(PIC32MX_USBOTG_CON); + regval &= ~USBOTG_CON_DPPULUP; + pic32mx_putreg(regval, PIC32MX_USBOTG_CON); + + /* Disable and deactivate HNP */ +#warning Missing Logic + + /* Check if the ID Pin Changed State */ + + if ((pic32mx_getreg(PIC32MX_USBOTG_IR) & pic32mx_getreg(PIC32MX_USBOTG_IE) & USBOTG_INT_ID) != 0) + { + /* Re-detect & Initialize */ +#warning "Missing logic" + + /* Clear ID Interrupt Flag */ + + pic32mx_putreg(USBOTG_INT_ID, PIC32MX_USBOTG_IR); + } +#endif +} + +/**************************************************************************** + * Name: pic32mx_swreset + ****************************************************************************/ + +static void pic32mx_swreset(struct pic32mx_usbdev_s *priv) +{ + int epno; + + /* Tell the class driver that we are disconnected. The class driver + * should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Flush and reset endpoint states (except EP0) */ + + for (epno = 1; epno < PIC32MX_NENDPOINTS; epno++) + { + struct pic32mx_ep_s *privep = &priv->eplist[epno]; + + /* Cancel any queued requests. Since they are canceled + * with status -ESHUTDOWN, then will not be requeued + * until the configuration is reset. NOTE: This should + * not be necessary... the CLASS_DISCONNECT above should + * result in the class implementation calling pic32mx_epdisable + * for each of its configured endpoints. + */ + + pic32mx_cancelrequests(privep, -EAGAIN); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->halted = false; + privep->txnullpkt = false; + } + + /* Reset to the default address */ + + pic32mx_putreg(0, PIC32MX_USB_ADDR); + + /* Unconfigure each endpoint by clearing the endpoint control registers + * (except EP0) + */ + + for (epno = 1; epno < PIC32MX_NENDPOINTS; epno++) + { + pic32mx_putreg(0, PIC32MX_USB_EP(epno)); + } + + /* Reset the control state */ + + priv->ctrlstate = CTRLSTATE_WAITSETUP; + priv->rxbusy = 0; +} + +/**************************************************************************** + * Name: pic32mx_hwreset + * + * Description: + * Reset the hardware and leave it in a known, unready state. + * + ****************************************************************************/ + +static void pic32mx_hwreset(struct pic32mx_usbdev_s *priv) +{ + uint32_t physaddr; + uint16_t regval; + + /* Power down the USB module. This will reset all USB registers. */ + + regval = pic32mx_getreg(PIC32MX_USB_PWRC); + regval &= ~USB_PWRC_USBPWR; + pic32mx_putreg(regval, PIC32MX_USB_PWRC); + + /* Clear all of the buffer descriptor table (BDT) entries */ + + memset((void *)g_bdt, 0, sizeof(g_bdt)); + + /* Power up the USB module */ + + regval |= USB_PWRC_USBPWR; + pic32mx_putreg(regval, PIC32MX_USB_PWRC); + + /* Set the address of the buffer descriptor table (BDT) + * + * BDTP1: Bit 1-7: Bits 9-15 of the BDT base address + * BDTP2: Bit 0-7: Bits 16-23 of the BDT base address + * BDTP3: Bit 0-7: Bits 24-31 of the BDT base address + */ + + physaddr = PHYS_ADDR(g_bdt); + pic32mx_putreg((uint16_t)((physaddr >> 24) & USB_BDTP3_MASK), PIC32MX_USB_BDTP3); + pic32mx_putreg((uint16_t)((physaddr >> 16) & USB_BDTP2_MASK), PIC32MX_USB_BDTP2); + pic32mx_putreg((uint16_t)((physaddr >> 8) & USB_BDTP1_MASK), PIC32MX_USB_BDTP1); + + /* Assert reset request to all of the Ping Pong buffer pointers. This + * will reset all Even/Odd buffer pointers to the EVEN BD banks. + */ + + regval = pic32mx_getreg(PIC32MX_USB_CON); + regval |= USB_CON_PPBRST; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* Bring the ping pong buffer pointers out of reset */ + + regval &= ~USB_CON_PPBRST; + pic32mx_putreg(regval, PIC32MX_USB_CON); + + /* Indicate that we are now in the detached state */ + + priv->devstate = DEVSTATE_DETACHED; +} + +/**************************************************************************** + * Name: pic32mx_stateinit + ****************************************************************************/ + +static void pic32mx_stateinit(struct pic32mx_usbdev_s *priv) +{ + int epno; + + /* Disconnect the device / disable the pull-up. We don't want the + * host to enumerate us until the class driver is registered. + */ + + pic32mx_usbpullup(&priv->usbdev, false); + + /* Initialize the device state structure. NOTE: many fields + * have the initial value of zero and, hence, are not explicitly + * initialized here. + */ + + memset(priv, 0, sizeof(struct pic32mx_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[EP0].ep; + priv->epavail = PIC32MX_ENDP_ALLSET & ~PIC32MX_ENDP_BIT(EP0); + priv->rwakeup = 1; + + /* Initialize the endpoint list */ + + for (epno = 0; epno < PIC32MX_NENDPOINTS; epno++) + { + struct pic32mx_ep_s *privep = &priv->eplist[epno]; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the (physical) endpoint number which is just the index to the + * endpoint. + */ + + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->ep.eplog = epno; + + /* We will use a fixed maxpacket size for all endpoints (perhaps + * ISOC endpoints could have larger maxpacket???). A smaller + * packet size can be selected when the endpoint is configured. + */ + + privep->ep.maxpacket = PIC32MX_MAXPACKET_SIZE; + } + + /* Select a smaller endpoint size for EP0 */ + +#if PIC32MX_EP0MAXPACKET < PIC32MX_MAXPACKET_SIZE + priv->eplist[EP0].ep.maxpacket = PIC32MX_EP0MAXPACKET; +#endif +} + +/**************************************************************************** + * Name: pic32mx_hwshutdown + ****************************************************************************/ + +static void pic32mx_hwshutdown(struct pic32mx_usbdev_s *priv) +{ + uint16_t regval; + + /* Put the hardware and driver in its initial, unconnected state */ + + pic32mx_swreset(priv); + pic32mx_hwreset(priv); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable all interrupts and force the USB controller into reset */ + + pic32mx_putreg(0, PIC32MX_USB_EIE); + pic32mx_putreg(0, PIC32MX_USB_IE); + + /* Clear any pending interrupts */ + + pic32mx_putreg(USB_EINT_ALL, PIC32MX_USB_EIR); + pic32mx_putreg(USB_INT_ALL, PIC32MX_USB_IR); + + /* Disconnect the device / disable the pull-up */ + + pic32mx_usbpullup(&priv->usbdev, false); + + /* Power down the USB controller */ + + regval = pic32mx_getreg(PIC32MX_USB_PWRC); + regval &= ~USB_PWRC_USBPWR; + pic32mx_putreg(regval, PIC32MX_USB_PWRC); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize the USB driver + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + + usbtrace(TRACE_DEVINIT, 0); + + /* Initialize the driver state structure */ + + pic32mx_stateinit(priv); + + /* Then perform a few one-time initialization operstions. First, initialize + * the watchdog timer that is used to perform a delayed queue restart + * after recovering from a stall. + */ + + priv->epstalled = 0; + priv->wdog = wd_create(); + + /* Attach USB controller interrupt handler. The hardware will not be + * initialized and interrupts will not be enabled until the class device + * driver is bound. Getting the IRQs here only makes sure that we have + * them when we need them later. + */ + + if (irq_attach(PIC32MX_IRQ_USB, pic32mx_interrupt) != 0) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_IRQREGISTRATION), + (uint16_t)PIC32MX_IRQ_USB); + up_usbuninitialize(); + } +} + +/**************************************************************************** + * Name: up_usbuninitialize + * Description: + * Initialize the USB driver + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + flags = enter_critical_section(); + usbtrace(TRACE_DEVUNINIT, 0); + + /* Disable and detach the USB IRQs */ + + up_disable_irq(PIC32MX_IRQSRC_USB); + irq_detach(PIC32MX_IRQ_USB); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Put the hardware in an inactive state */ + + pic32mx_hwshutdown(priv); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method + * will be called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + + /* The class driver has been successfully bound. */ + + else + { + /* Setup the USB controller in it initial ready-to-run state (might + * be connected or unconnected, depending on usbdev_attach() has + * been called). + */ + + DEBUGASSERT(priv->devstate == DEVSTATE_DETACHED); + pic32mx_reset(priv); + } + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver. If the USB device is connected to a + * USB host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(PIC32MX_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. This will put + * the hardware back into its initial, unconnected state. + */ + + flags = enter_critical_section(); + pic32mx_swreset(priv); + pic32mx_hwreset(priv); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts (but keep them attached) */ + + up_disable_irq(PIC32MX_IRQSRC_USB); + + /* Put the hardware in an inactive state. Then bring the hardware back up + * in the reset state (this is probably not necessary, the pic32mx_hwreset() + * call above was probably sufficient). + */ + + pic32mx_hwshutdown(priv); + pic32mx_stateinit(priv); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: pic32mx_usbattach and pic32mx_usbdetach + * + * Description: + * The USB stack must be notified when the device is attached or detached + * by calling one of these functions. + * + ****************************************************************************/ + +void pic32mx_usbattach(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + + /* Mark that we are attached */ + + priv->attached = 1; + + /* This API may be called asynchronously from other initialization + * interfaces. In particular, we may not want to attach the bus yet... + * that should only be done when the class driver is attached. Has + * the class driver been attached? + */ + + if (priv->driver) + { + /* Yes.. then attach to the bus */ + + pic32mx_attach(priv); + } +} + +void pic32mx_usbdetach(void) +{ + /* For now there is only one USB controller, but we will always refer to + * it using a pointer to make any future ports to multiple USB controllers + * easier. + */ + + struct pic32mx_usbdev_s *priv = &g_usbdev; + + /* Detach from the bus */ + + pic32mx_detach(priv); +} + +#endif /* CONFIG_USBDEV && CONFIG_PIC32MX_USB */ diff --git a/arch/mips/src/pic32mx/pic32mx-usbotg.h b/arch/mips/src/pic32mx/pic32mx-usbotg.h new file mode 100644 index 0000000000000000000000000000000000000000..11b3231886c6ac9c587bbacb498783d093cb101d --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-usbotg.h @@ -0,0 +1,362 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-usbotg.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_USBOTG_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_USBOTG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register Offsets *****************************************************************/ + +#define PIC32MX_USBOTG_IR_OFFSET 0x0040 /* USB OTG Interrupt Flags Register */ +#define PIC32MX_USBOTG_IE_OFFSET 0x0050 /* USB OTG Interrupt Enable Register */ +#define PIC32MX_USBOTG_STAT_OFFSET 0x0060 /* USB Comparator and Pin Status Register */ +#define PIC32MX_USBOTG_CON_OFFSET 0x0070 /* USB Resistor and Pin Control Register */ +#define PIC32MX_USB_PWRC_OFFSET 0x0080 /* USB Power Control Register */ +#define PIC32MX_USB_IR_OFFSET 0x0200 /* USB Pending Interrupt Register */ +#define PIC32MX_USB_IE_OFFSET 0x0210 /* USB Interrupt Enable Register */ +#define PIC32MX_USB_EIR_OFFSET 0x0220 /* USB Pending Error Interrupt Register */ +#define PIC32MX_USB_EIE_OFFSET 0x0230 /* USB Interrupt Error Enable Register */ +#define PIC32MX_USB_STAT_OFFSET 0x0240 /* USB Status FIFO Register */ +#define PIC32MX_USB_CON_OFFSET 0x0250 /* USB Module Control Register */ +#define PIC32MX_USB_ADDR_OFFSET 0x0260 /* USB Address Register */ +#define PIC32MX_USB_FRMH_OFFSET 0x0290 /* USB Frame Counter Register (high) */ +#define PIC32MX_USB_FRML_OFFSET 0x0280 /* USB Frame Counter Register (low) */ +#define PIC32MX_USB_TOK_OFFSET 0x02a0 /* USB Host Control Register */ +#define PIC32MX_USB_SOF_OFFSET 0x02b0 /* USB SOF Counter Register */ +#define PIC32MX_USB_BDTP1_OFFSET 0x0270 /* USB Buffer Descriptor Table Pointer Register 1 */ +#define PIC32MX_USB_BDTP2_OFFSET 0x02c0 /* USB Buffer Descriptor Table Pointer Register 2 */ +#define PIC32MX_USB_BDTP3_OFFSET 0x02d0 /* USB Buffer Descriptor Table Pointer Register 3 */ +#define PIC32MX_USB_CNFG1_OFFSET 0x02e0 /* USB Debug and Idle Register */ + +#define PIC32MX_USB_EP_OFFSET(n) (0x0300+((n)<<4)) +#define PIC32MX_USB_EP0_OFFSET 0x0300 /* USB Endpoint 0 Control Register */ +#define PIC32MX_USB_EP1_OFFSET 0x0310 /* USB Endpoint 1 Control Register */ +#define PIC32MX_USB_EP2_OFFSET 0x0320 /* USB Endpoint 2 Control Register */ +#define PIC32MX_USB_EP3_OFFSET 0x0330 /* USB Endpoint 3 Control Register */ +#define PIC32MX_USB_EP4_OFFSET 0x0340 /* USB Endpoint 4 Control Register */ +#define PIC32MX_USB_EP5_OFFSET 0x0350 /* USB Endpoint 5 Control Register */ +#define PIC32MX_USB_EP6_OFFSET 0x0360 /* USB Endpoint 6 Control Register */ +#define PIC32MX_USB_EP7_OFFSET 0x0370 /* USB Endpoint 7 Control Register */ +#define PIC32MX_USB_EP8_OFFSET 0x0380 /* USB Endpoint 8 Control Register */ +#define PIC32MX_USB_EP9_OFFSET 0x0390 /* USB Endpoint 9 Control Register */ +#define PIC32MX_USB_EP10_OFFSET 0x03a0 /* USB Endpoint 10 Control Register */ +#define PIC32MX_USB_EP11_OFFSET 0x03b0 /* USB Endpoint 11 Control Register */ +#define PIC32MX_USB_EP12_OFFSET 0x03c0 /* USB Endpoint 12 Control Register */ +#define PIC32MX_USB_EP13_OFFSET 0x03d0 /* USB Endpoint 13 Control Register */ +#define PIC32MX_USB_EP14_OFFSET 0x03e0 /* USB Endpoint 14 Control Register */ +#define PIC32MX_USB_EP15_OFFSET 0x03f0 /* USB Endpoint 15 Control Register */ + +/* Register Addresses ***************************************************************/ + +#define PIC32MX_USBOTG_IR (PIC32MX_USB_K1BASE+PIC32MX_USBOTG_IR_OFFSET) +#define PIC32MX_USBOTG_IE (PIC32MX_USB_K1BASE+PIC32MX_USBOTG_IE_OFFSET) +#define PIC32MX_USBOTG_STAT (PIC32MX_USB_K1BASE+PIC32MX_USBOTG_STAT_OFFSET) +#define PIC32MX_USBOTG_CON (PIC32MX_USB_K1BASE+PIC32MX_USBOTG_CON_OFFSET) +#define PIC32MX_USB_PWRC (PIC32MX_USB_K1BASE+PIC32MX_USB_PWRC_OFFSET) +#define PIC32MX_USB_IR (PIC32MX_USB_K1BASE+PIC32MX_USB_IR_OFFSET) +#define PIC32MX_USB_IE (PIC32MX_USB_K1BASE+PIC32MX_USB_IE_OFFSET) +#define PIC32MX_USB_EIR (PIC32MX_USB_K1BASE+PIC32MX_USB_EIR_OFFSET) +#define PIC32MX_USB_EIE (PIC32MX_USB_K1BASE+PIC32MX_USB_EIE_OFFSET) +#define PIC32MX_USB_STAT (PIC32MX_USB_K1BASE+PIC32MX_USB_STAT_OFFSET) +#define PIC32MX_USB_CON (PIC32MX_USB_K1BASE+PIC32MX_USB_CON_OFFSET) +#define PIC32MX_USB_ADDR (PIC32MX_USB_K1BASE+PIC32MX_USB_ADDR_OFFSET) +#define PIC32MX_USB_FRMH (PIC32MX_USB_K1BASE+PIC32MX_USB_FRMH_OFFSET) +#define PIC32MX_USB_FRML (PIC32MX_USB_K1BASE+PIC32MX_USB_FRML_OFFSET) +#define PIC32MX_USB_TOK (PIC32MX_USB_K1BASE+PIC32MX_USB_TOK_OFFSET) +#define PIC32MX_USB_SOF (PIC32MX_USB_K1BASE+PIC32MX_USB_SOF_OFFSET) +#define PIC32MX_USB_BDTP1 (PIC32MX_USB_K1BASE+PIC32MX_USB_BDTP1_OFFSET) +#define PIC32MX_USB_BDTP2 (PIC32MX_USB_K1BASE+PIC32MX_USB_BDTP2_OFFSET) +#define PIC32MX_USB_BDTP3 (PIC32MX_USB_K1BASE+PIC32MX_USB_BDTP3_OFFSET) +#define PIC32MX_USB_CNFG1 (PIC32MX_USB_K1BASE+PIC32MX_USB_CNFG1_OFFSET) + +#define PIC32MX_USB_EP(n) (PIC32MX_USB_K1BASE+PIC32MX_USB_EP_OFFSET(n)) +#define PIC32MX_USB_EP0 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP0_OFFSET) +#define PIC32MX_USB_EP1 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP1_OFFSET) +#define PIC32MX_USB_EP2 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP2_OFFSET) +#define PIC32MX_USB_EP3 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP3_OFFSET) +#define PIC32MX_USB_EP4 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP4_OFFSET) +#define PIC32MX_USB_EP5 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP5_OFFSET) +#define PIC32MX_USB_EP6 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP6_OFFSET) +#define PIC32MX_USB_EP7 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP7_OFFSET) +#define PIC32MX_USB_EP8 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP8_OFFSET) +#define PIC32MX_USB_EP9 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP9_OFFSET) +#define PIC32MX_USB_EP10 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP10_OFFSET) +#define PIC32MX_USB_EP11 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP11_OFFSET) +#define PIC32MX_USB_EP12 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP12_OFFSET) +#define PIC32MX_USB_EP13 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP13_OFFSET) +#define PIC32MX_USB_EP14 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP14_OFFSET) +#define PIC32MX_USB_EP15 (PIC32MX_USB_K1BASE+PIC32MX_USB_EP15_OFFSET) + +/* Register Bit-Field Definitions ***************************************************/ + +/* USB OTG Interrupt Flags Register */ +/* USB OTG Interrupt Enable Register */ + +#define USBOTG_INT_VBUSVD (1 << 0) /* Bit 0: A-Device VBUS Change Indicator */ +#define USBOTG_INT_SESEND (1 << 2) /* Bit 2: B-Device VBUS Change Indicator */ +#define USBOTG_INT_ACTV (1 << 4) /* Bit 4: Bus Activity Indicator */ +#define USBOTG_INT_SESVD (1 << 3) /* Bit 3: Session Valid Change Indicator */ +#define USBOTG_INT_LSTATE (1 << 5) /* Bit 5: Line State Stable Indicator */ +#define USBOTG_INT_T1MSEC (1 << 6) /* Bit 6: 1 Millisecond Timer */ +#define USBOTG_INT_ID (1 << 7) /* Bit 7: ID State Change Indicator */ + +/* USB Comparator and Pin Status Register */ + +#define USBOTG_STAT_VBUSVD (1 << 0) /* Bit 0: A-VBUS Valid Indicator */ +#define USBOTG_STAT_SESEND (1 << 2) /* Bit 2: B-Session End Indicator */ +#define USBOTG_STAT_SESVD (1 << 3) /* Bit 3: Session Valid Indicator */ +#define USBOTG_STAT_LSTATE (1 << 5) /* Bit 5: Line State Stable Indicator */ +#define USBOTG_STAT_ID (1 << 7) /* Bit 7: ID Pin State Indicator */ + +/* USB Resistor and Pin Control Register */ + +#define USBOTG_CON_VBUSDIS (1 << 0) /* Bit 0: VBUS Discharge Enable */ +#define USBOTG_CON_VBUSCHG (1 << 1) /* Bit 1: VBUS Charge Enable */ +#define USBOTG_CON_OTGEN (1 << 2) /* Bit 2: OTG Functionality Enable */ +#define USBOTG_CON_VBUSON (1 << 3) /* Bit 3: VBUS Power-on */ +#define USBOTG_CON_DMPULDWN (1 << 4) /* Bit 4: D- Pull-Down Enable */ +#define USBOTG_CON_DPPULDWN (1 << 5) /* Bit 5: D+ Pull-Down Enable */ +#define USBOTG_CON_DMPULUP (1 << 6) /* Bit 6: D- Pull-Up Enable */ +#define USBOTG_CON_DPPULUP (1 << 7) /* Bit 7: D+ Pull-Up Enable */ + +/* USB Power Control Register */ + +#define USB_PWRC_USBPWR (1 << 0) /* Bit 0: USB Operation Enable */ +#define USB_PWRC_USUSPEND (1 << 1) /* Bit 1: USB Suspend Mode */ +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define USB_PWRC_USBBUSY (1 << 3) /* Bit 3: USB Module Busy */ +#endif +#define USB_PWRC_USLPGRD (1 << 4) /* Bit 4: USB Sleep Entry Guard */ +#define USB_PWRC_UACTPND (1 << 7) /* Bit 7: USB Activity Pending */ + +/* USB Pending Interrupt Register */ +/* USB Interrupt Enable Register */ + +#define USB_INT_URST (1 << 0) /* Bit 0: USB Reset Interrupt (Device mode) */ +#define USB_INT_DETACH (1 << 0) /* Bit 0: USB Detach Interrupt (Host mode) */ +#define USB_INT_UERR (1 << 1) /* Bit 1: USB Error Condition Interrupt */ +#define USB_INT_SOF (1 << 2) /* Bit 2: SOF Token Interrupt */ +#define USB_INT_TRN (1 << 3) /* Bit 3: Token Processing Complete Interrupt */ +#define USB_INT_IDLE (1 << 4) /* Bit 4: Idle Detect Interrupt */ +#define USB_INT_RESUME (1 << 5) /* Bit 5: Resume Interrupt */ +#define USB_INT_ATTACH (1 << 6) /* Bit 6: Peripheral Attach Interrupt */ +#define USB_INT_STALL (1 << 7) /* Bit 7: STALL Handshake Interrupt */ + +#define USB_INT_ALL 0xff + +/* USB Pending Error Interrupt Register */ +/* USB Interrupt Error Enable Register */ + +#define USB_EINT_PID (1 << 0) /* Bit 0: PID Check Failure Flag */ +#define USB_EINT_CRC5 (1 << 1) /* Bit 1: CRC5 Host Error Flag */ +#define USB_EINT_EOF (1 << 1) /* Bit 1: EOF Error Flag */ +#define USB_EINT_CRC16 (1 << 2) /* Bit 2: CRC16 Failure Flag */ +#define USB_EINT_DFN8 (1 << 3) /* Bit 3: Data Field Size Error Flag */ +#define USB_EINT_BTO (1 << 4) /* Bit 4: Bus Turnaround Time-Out Error Flag */ +#define USB_EINT_DMA (1 << 5) /* Bit 5: DMA Error Flag */ +#define USB_EINT_BMX (1 << 6) /* Bit 6: Bus Matrix Error Flag */ +#define USB_EINT_BTS (1 << 7) /* Bit 7: Bit Stuff Error Flag */ + +#define USB_EINT_ALL 0xff + +/* USB Status FIFO Register */ + +#define USB_STAT_PPBI (1 << 2) /* Bit 2: Ping-Pong BD Pointer Indicator */ +#define USB_STAT_DIR (1 << 3) /* Bit 3: Last BD Direction Indicator */ +#define USB_STAT_ENDPT_SHIFT (4) /* Bits 4-7: Encoded Endpoint Activity */ +#define USB_STAT_ENDPT_MASK (15 << USB_STAT_ENDPT_SHIFT) +# define USB_STAT_ENDPT(n) ((n) << USB_STAT_ENDPT_SHIFT) /* Endpoint n, n=0..15 */ + +#define USB_STAT_PPBI_ODD USB_STAT_PPBI /* The last transaction was to the ODD BD bank */ +#define USB_STAT_PPBI_EVEN 0 /* The last transaction was to the EVEN BD bank */ + +#define USB_STAT_DIR_IN USB_STAT_DIR /* Last transaction was a transmit transfer (TX) */ +#define USB_STAT_DIR_OUT 0 /* Last transaction was a receive transfer (RX) */ + +/* USB Module Control Register */ + +#define USB_CON_USBEN (1 << 0) /* Bit 0: USB Module Enable */ +#define USB_CON_SOFEN (1 << 0) /* Bit 0: SOF Enable */ +#define USB_CON_PPBRST (1 << 1) /* Bit 1: Ping-Pong Buffers Reset */ +#define USB_CON_RESUME (1 << 2) /* Bit 2: RESUME Signaling Enable */ +#define USB_CON_HOSTEN (1 << 3) /* Bit 3: Host Mode Enable */ +#define USB_CON_USBRST (1 << 4) /* Bit 4: Module Reset */ +#define USB_CON_PKTDIS (1 << 5) /* Bit 5: Packet Transfer Disable */ +#define USB_CON_TOKBUSY (1 << 5) /* Bit 5: Token Busy Indicator */ +#define USB_CON_SE0 (1 << 6) /* Bit 6: Live Single-Ended Zero flag */ +#define USB_CON_JSTATE (1 << 7) /* Bit 7: Live Differential Receiver JSTATE flag */ + +/* USB Address Register */ + +#define USB_ADDR_DEVADDR_SHIFT (0) /* Bit 0-6: 7-bit USB Device Address */ +#define USB_ADDR_DEVADDR_MASK (0x7f << USB_ADDR_DEVADDR_SHIFT) +#define USB_ADDR_LSPDEN (1 << 7) /* Bit 7: Low Speed Enable Indicator */ + +/* USB Frame Counter Register (high) */ + +#define USB_FRMH_MASK 0x07 /* Bits 0-2: 11-bit frame number upper 3 bits */ + +/* USB Frame Counter Register (low) */ + +#define USB_FRML_MASK 0xff /* Bits 0-7: 11-bit frame number lower 8 bits */ + +/* USB Host Control Register */ + +#define USB_TOK_PID_SHIFT (4) /* Bits 4-7: Token Type Indicator */ +#define USB_TOK_PID_MASK (15 << USB_TOK_PID_SHIFT) +# define USB_TOK_PID_OUT (1 << USB_TOK_PID_SHIFT) /* OUT (TX) token type transaction */ +# define USB_TOK_PID_IN (9 << USB_TOK_PID_SHIFT) /* IN (RX) token type transaction */ +# define USB_TOK_PID_SETUP (13 << USB_TOK_PID_SHIFT) /* SETUP (TX) token type transaction */ +#define USB_TOK_EP_SHIFT (0) /* Bits 0-3: Token Command Endpoint Address */ +#define USB_TOK_EP_MASK (15 << USB_TOK_EP_SHIFT) + +/* USB SOF Counter Register */ + +#define USB_SOF_SHIFT (0) /* Bits 0-7: SOF Threshold Value */ +#define USB_SOF_MASK (0xff << USB_SOF_SHIFT) +# define USB_SOF_8BTYE (0x12 << USB_SOF_SHIFT) /* 8-byte packet */ +# define USB_SOF_16BTYE (0x1a << USB_SOF_SHIFT) /* 16-byte packet */ +# define USB_SOF_32BTYE (0x2a << USB_SOF_SHIFT) /* 32-byte packet */ +# define USB_SOF_64BTYE (0x4a << USB_SOF_SHIFT) /* 64-byte packet */ + +/* USB Buffer Descriptor Table Pointer Register 1 */ + +#define USB_BDTP1_MASK 0x7e /* Bits 1-7: BDT Base Address bits 9-15 */ + +/* USB Buffer Descriptor Table Pointer Register 2 */ + +#define USB_BDTP2_MASK 0xff /* Bits 0-7: BDT Base Address bits 16-23 */ + +/* USB Buffer Descriptor Table Pointer Register 3 */ + +#define USB_BDTP3_MASK 0xff /* Bits 0-7: BDT Base Address bits 24-31 */ + +/* USB Debug and Idle Register */ + +#if defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define USB_CNFG1_UASUSPND (1 << 0) /* Bit 0: Automatic Suspend Enable */ +#endif +#define USB_CNFG1_USBSIDL (1 << 4) /* Bit 4: Stop in Idle Mode */ +#define USB_CNFG1_USBFRZ (1 << 5) /* Bit 5: Freeze in Debug Mode */ +#define USB_CNFG1_UOEMON (1 << 6) /* Bit 6: USB OE Monitor Enable */ +#define USB_CNFG1_UTEYE (1 << 7) /* Bit 7: USB Eye-Pattern Test Enable */ + +/* USB Endpoint Control Register */ + +#define USB_EP_EPHSHK (1 << 0) /* Bit 0: Endpoint Handshake Enable */ +#define USB_EP_EPSTALL (1 << 1) /* Bit 1: Endpoint Stall Status */ +#define USB_EP_EPTXEN (1 << 2) /* Bit 2: Endpoint Transmit Enable */ +#define USB_EP_EPRXEN (1 << 3) /* Bit 3: Endpoint Receive Enable */ +#define USB_EP_EPCONDIS (1 << 4) /* Bit 4: Bidirectional Endpoint Control */ +#define USB_EP_RETRYDIS (1 << 6) /* Bit 6: Retry Disable (Host mode and U1EP0 only) */ +#define USB_EP_LSPD (1 << 7) /* Bit 7: Low-Speed Direct Connection Enable */ + +/* Buffer Descriptor Table (BDT) ****************************************************/ +/* Offset 0: On write (software->hardware) */ + +#define USB_BDT_STATUS_MASK 0xfc /* Bits 2-7: Status bits */ +#define USB_BDT_BSTALL (1 << 2) /* Bit 2: Buffer Stall Enable bit */ +#define USB_BDT_DTS (1 << 3) /* Bit 3: Data Toggle Synchronization Enable bit */ +#define USB_BDT_NINC (1 << 4) /* Bit 4: DMA Address Increment Disable bit */ +#define USB_BDT_KEEP (1 << 5) /* Bit 5: BD Keep Enable bit */ +#define USB_BDT_DATA01 (1 << 6) /* Bit 6: Data Toggle Packet bit */ +#define USB_BDT_UOWN (1 << 7) /* Bit 7: USB Own bit */ +#define USB_BDT_BYTECOUNT_SHIFT (16) /* Bits 16-25: Byte Count bits */ +#define USB_BDT_BYTECOUNT_MASK (0x3ff << USB_BDT_BYTECOUNT_SHIFT) + +#define USB_BDT_DATA0 0 /* DATA0 packet expected next */ +#define USB_BDT_DATA1 USB_BDT_DATA01 /* DATA1 packet expected next */ +#define USB_BDT_COWN 0 /* CPU owns the descriptor */ + +/* Offset 0: On read (hardware->software) */ + +#define USB_BDT_PID_SHIFT (2) /* Bits 2-5: Packet Identifier bits */ +#define USB_BDT_PID_MASK (15 << USB_BDT_PID_SHIFT) + /* Bit 7: USB Own bit (same) */ + /* Bits 16-25: Byte Count bits (same) */ + +/* Offset 4: BUFFER_ADDRESS, 32-bit Buffer Address bits */ + +#define USB_BDT_BYTES_SIZE 8 /* Eight bytes per BDT */ +#define USB_BDT_WORD_SIZE 2 /* Two 32-bit words per BDT */ +#define USB_NBDTS_PER_EP 4 /* Number of BDTS per endpoint: IN/OUT and EVEN/ODD */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Buffer Descriptor Status Register layout. */ + +struct usbotg_bdtentry_s +{ + uint32_t status; /* Status, byte count, and PID */ + uint8_t *addr; /* Buffer address */ +}; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_USBOTG_H */ diff --git a/arch/mips/src/pic32mx/pic32mx-wdt.h b/arch/mips/src/pic32mx/pic32mx-wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..abbb49c98107d1a95f475fda637472388c4bccd0 --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-wdt.h @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-wdt.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_WDT_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mx-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MX_WDT_CON_OFFSET 0x0000 /* Watchdog timer control register */ + +/* See also the WDTO, SLEEP, and IDLE bits in the resets RCON register */ + +/* Register Addresses *******************************************************/ + +#define PIC32MX_WDT_CON (PIC32MX_WDT_K1BASE+PIC32MX_WDT_CON_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ + +/* Watchdog timer control register */ + +#define WDT_CON_WDTCLR (1 << 0) /* Bit 0: Watchdog timer reset */ +#define WDT_CON_SWDTPS_SHIFT (2) /* Bits 2-6: WDT postscaler value from DEVCFG1 */ +#define WDT_CON_SWDTPS_MASK (31 << WDT_CON_SWDTPS_SHIFT) +# define WDT_CON_SWDTPS_1 (0 << WDT_CON_SWDTPS_SHIFT) /* 1:1 */ +# define WDT_CON_SWDTPS_2 (1 << WDT_CON_SWDTPS_SHIFT) /* 1:2 */ +# define WDT_CON_SWDTPS_4 (2 << WDT_CON_SWDTPS_SHIFT) /* 1:4 */ +# define WDT_CON_SWDTPS_8 (3 << WDT_CON_SWDTPS_SHIFT) /* 1:8 */ +# define WDT_CON_SWDTPS_16 (4 << WDT_CON_SWDTPS_SHIFT) /* 1:16 */ +# define WDT_CON_SWDTPS_32 (5 << WDT_CON_SWDTPS_SHIFT) /* 1:32 */ +# define WDT_CON_SWDTPS_64 (6 << WDT_CON_SWDTPS_SHIFT) /* 1:64 */ +# define WDT_CON_SWDTPS_128 (7 << WDT_CON_SWDTPS_SHIFT) /* 1:128 */ +# define WDT_CON_SWDTPS_256 (8 << WDT_CON_SWDTPS_SHIFT) /* 1:256 */ +# define WDT_CON_SWDTPS_512 (9 << WDT_CON_SWDTPS_SHIFT) /* 1:512 */ +# define WDT_CON_SWDTPS_1024 (10 << WDT_CON_SWDTPS_SHIFT) /* 1:1024 */ +# define WDT_CON_SWDTPS_2048 (11 << WDT_CON_SWDTPS_SHIFT) /* 1:2048 */ +# define WDT_CON_SWDTPS_4096 (12 << WDT_CON_SWDTPS_SHIFT) /* 1:4096 */ +# define WDT_CON_SWDTPS_8192 (13 << WDT_CON_SWDTPS_SHIFT) /* 1:8192 */ +# define WDT_CON_SWDTPS_16384 (14 << WDT_CON_SWDTPS_SHIFT) /* 1:16384 */ +# define WDT_CON_SWDTPS_32768 (15 << WDT_CON_SWDTPS_SHIFT) /* 1:32768 */ +# define WDT_CON_SWDTPS_65536 (16 << WDT_CON_SWDTPS_SHIFT) /* 1:65536 */ +# define WDT_CON_SWDTPS_131072 (17 << WDT_CON_SWDTPS_SHIFT) /* 1:131072 */ +# define WDT_CON_SWDTPS_262144 (18 << WDT_CON_SWDTPS_SHIFT) /* 1:262144 */ +# define WDT_CON_SWDTPS_524288 (19 << WDT_CON_SWDTPS_SHIFT) /* 1:524288 */ +# define WDT_CON_SWDTPS_1048576 (20 << WDT_CON_SWDTPS_SHIFT) /* 1:1048576 */ +#define WDT_CON_ON (1 << 15 /* Bit 15: Watchdog timer enable */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_WDT_H */ diff --git a/arch/mips/src/pic32mx/pic32mx.h b/arch/mips/src/pic32mx/pic32mx.h new file mode 100644 index 0000000000000000000000000000000000000000..ab8e50b491a222eb77f90c0174561c10b39d7f4d --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx.h @@ -0,0 +1,644 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx.h + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "chip.h" +#include "pic32mx-config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO settings used in the configport, readport, writeport, etc. + * + * General encoding: + * MMAV IIDx RRRx PPPP + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: I/O mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* 00 Normal input */ +# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* 10 Normal output */ +# define GPIO_OPENDRAN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +#define GPIO_ANALOG_MASK (1 << 13) /* Bit 13: Analog */ +# define GPIO_ANALOG (1 << 13) +# define GPIO_DIGITAL (0) +#endif + +#define GPIO_VALUE_MASK (1 << 12) /* Bit 12: Initial output value */ +# define GPIO_VALUE_ONE (1 << 12) +# define GPIO_VALUE_ZERO (0) + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define GPIO_PULLUP (1 << 11) /* Bit 11: Change notification pull-up */ +#endif + +#define GPIO_INT_SHIFT (10) /* Bits 10-11: Interrupt mode */ +#define GPIO_INT_MASK (3 << GPIO_INT_SHIFT) +# define GPIO_INT_NONE (0 << GPIO_INT_SHIFT) /* Bit 00: No interrupt */ +# define GPIO_INT (1 << GPIO_INT_SHIFT) /* Bit 01: Change notification enable */ +# define GPIO_PUINT (3 << GPIO_INT_SHIFT) /* Bit 11: Pulled-up interrupt input */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +# define GPIO_PULLDOWN (1 << 9) /* Bit 11: Change notification pull-down */ +#endif + +#define GPIO_PORT_SHIFT (5) /* Bits 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct pic32mx_dmaglobalregs_s +{ + /* Global Registers */ +#warning "Missing definitions" +}; + +struct pic32mx_dmachanregs_s +{ + /* Channel Registers */ +#warning "Missing definitions" +}; + +struct pic32mx_dmaregs_s +{ + /* Global Registers */ + + struct pic32mx_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct pic32mx_dmachanregs_s ch; +}; +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mx_lowinit + * + * Description: + * This performs basic low-level initialization of the system. + * + ************************************************************************************/ + +void pic32mx_lowinit(void); + +/************************************************************************************ + * Name: pic32mx_consoleinit + * + * Description: + * Performs low level initialization of the console UART. This UART done early so + * that the serial console is available for debugging very early in the boot + * sequence. + * + ************************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void pic32mx_consoleinit(void); +#else +# define pic32mx_consoleinit() +#endif + +/**************************************************************************** + * Name: pic32mx_uartreset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mx_uartreset(uintptr_t uart_base); +#endif + +/**************************************************************************** + * Name: pic32mx_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mx_uartconfigure(uintptr_t uart_base, uint32_t baudrate, + unsigned int parity, unsigned int nbits, bool stop2); +#endif + +/************************************************************************************ + * Name: pic32mx_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the directory + * configs//up_boot.c. + * + ************************************************************************************/ + +void pic32mx_boardinitialize(void); + +/************************************************************************************ + * Name: pic32mx_decodeirq + * + * Description: + * Called from assembly language logic when an interrupt exception occurs. This + * function decodes and dispatches the interrupt. + * + ************************************************************************************/ + +uint32_t *pic32mx_decodeirq(uint32_t *regs); + +/************************************************************************************ + * Name: pic32mx_exception + * + * Description: + * Called from assembly language logic on all other exceptions. + * + ************************************************************************************/ + +uint32_t *pic32mx_exception(uint32_t *regs); + +/************************************************************************************ + * Name: pic32mx_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the interrupt + * will be configured when pic32mx_attach() is called). + * + * Returned Value: + * OK on success; negated errno on failure. + * + ************************************************************************************/ + +int pic32mx_configgpio(uint16_t cfgset); + +/************************************************************************************ + * Name: pic32mx_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void pic32mx_gpiowrite(uint16_t pinset, bool value); + +/************************************************************************************ + * Name: pic32mx_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool pic32mx_gpioread(uint16_t pinset); + +/************************************************************************************ + * Name: pic32mx_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. This + * function is called internally by the system on power up and should not be + * called again. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_GPIOIRQ +void pic32mx_gpioirqinitialize(void); +#else +# define pic32mx_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: pic32mx_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will also + * reconfigure the pin as an interrupting input. The change notification number is + * associated with all interrupt-capable GPIO pins. The association could, + * however, differ from part to part and must be provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. In that + * case, all attached handlers will be called. Each handler must maintain state + * and determine if the underlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - cn: The change notification number associated with the pin + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_GPIOIRQ +xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); +#else +# define pic32mx_gpioattach(p,f) (NULL) +#endif + +/************************************************************************************ + * Name: pic32mx_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_GPIOIRQ +void pic32mx_gpioirqenable(unsigned int cn); +#else +# define pic32mx_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: pic32mx_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_GPIOIRQ +void pic32mx_gpioirqdisable(unsigned int cn); +#else +# define pic32mx_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: pic32mx_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +void pic32mx_dumpgpio(uint32_t pinset, const char *msg); +#else +# define pic32mx_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Name: pic32mx_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +FAR struct spi_dev_s *pic32mx_spibus_initialize(int port); + +/************************************************************************************ + * Name: pic32mx_spiNselect, pic32mx_spiNstatus, and pic32mx_spiNcmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including pic32mx_spibus_initialize()) are provided by common PIC32MX logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in pic32mx_boardinitialize() to configure SPI/SSP chip select + * pins. + * 2. Provide pic32mx_spiNselect() and pic32mx_spiNstatus() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * pic32mx_spiNcmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to pic32mx_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by pic32mx_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_SPI1 +void pic32mx_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mx_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MX_SPI2 +void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mx_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mx_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MX_SPI3 +void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mx_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MX_SPI3 +void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mx_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mx_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/************************************************************************************ + * Name: pic32mx_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmainitilaize(void); +#endif + +/************************************************************************************ + * Name: pic32mx_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and gives the + * caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel handle. NULL + * is returned on any failure. This function can fail only if no DMA channel is + * available. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +DMA_HANDLE pic32mx_dmachannel(void); +#endif + +/************************************************************************************ + * Name: pic32mx_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be + * used again until pic32mx_dmachannel() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmafree(DMA_HANDLE handle); +#endif + +/************************************************************************************ + * Name: pic32mx_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +int pic32mx_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); +#endif + +/************************************************************************************ + * Name: pic32mx_dmastart + * + * Description: + * Start the DMA transfer + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +int pic32mx_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); +#endif + +/************************************************************************************ + * Name: pic32mx_dmastop + * + * Description: + * Cancel the DMA. After pic32mx_dmastop() is called, the DMA channel is reset + * and pic32mx_dmasetup() must be called before pic32mx_dmastart() can be called + * again + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmastop(DMA_HANDLE handle); +#endif + +/************************************************************************************ + * Name: pic32mx_dmasample + * + * Description: + * Sample DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +#ifdef CONFIG_DEBUG_DMA +void pic32mx_dmasample(DMA_HANDLE handle, struct pic32mx_dmaregs_s *regs); +#else +# define pic32mx_dmasample(handle,regs) +#endif +#endif + +/************************************************************************************ + * Name: pic32mx_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +#ifdef CONFIG_DEBUG_DMA +void pic32mx_dmadump(DMA_HANDLE handle, const struct pic32mx_dmaregs_s *regs, + const char *msg); +#else +# define pic32mx_dmadump(handle,regs,msg) +#endif +#endif + +/************************************************************************************ + * Name: pic32mx_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide pic32mx_pullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * Alternatively, if no pull-up GPIO the following can be redefined to be + * NULL. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV +struct usbdev_s; +int pic32mx_usbpullup(FAR struct usbdev_s *dev, bool enable); +#endif + +/************************************************************************************ + * Name: pic32mx_usbsuspend + * + * Description: + * Board logic must provide the pic32mx_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. while + * the USB is suspended. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV +void pic32mx_usbsuspend(FAR struct usbdev_s *dev, bool resume); +#endif + +/************************************************************************************ + + * Name: pic32mx_usbattach and pic32mx_usbdetach + * + * Description: + * The USB stack must be notified when the device is attached or detached by + * calling one of these functions. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_USBDEV +void pic32mx_usbattach(void); +void pic32mx_usbdetach(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_H */ diff --git a/arch/mips/src/pic32mz/Kconfig b/arch/mips/src/pic32mz/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bca6f2b76444da29bc23e72a84114eed6f8686dd --- /dev/null +++ b/arch/mips/src/pic32mz/Kconfig @@ -0,0 +1,542 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_PIC32MZ +comment "PIC32MZ Configuration Options" + +choice + prompt "PIC32MZ chip selection" + default ARCH_CHIP_PIC32MZ460F512L + +config ARCH_CHIP_PIC32MZ2048ECH + bool "PIC32MZ2048ECH" + select ARCH_CHIP_PIC32MZEC + ---help--- + Microchip PIC32MZ2048ECH (MIPS32 M14K) + +config ARCH_CHIP_PIC32MZ2048ECM + bool "PIC32MZ2048ECM" + select ARCH_CHIP_PIC32MZEC + ---help--- + Microchip PIC32MZ2048ECM with Crypto Engine (MIPS32 M14K) + +endchoice + +config ARCH_CHIP_PIC32MZEC + bool + default n + select ARCH_MIPS_M14K + +config PIC32MZ_MVEC + bool + default n + +config PIC32MZ_SPI + bool + default n + +config PIC32MZ_T1 + bool + default y + +menu "PIC32MZ Peripheral Support" + +config PIC32MZ_WDT + bool "Watchdog timer (WDT)" + default n + +config PIC32MZ_T2 + bool "Timer 2 (T2)" + default n + +config PIC32MZ_T3 + bool "Timer 3 (T3)" + default n + +config PIC32MZ_T4 + bool "Timer 4 (T4)" + default n + +config PIC32MZ_T5 + bool "Timer 5 (T5)" + default n + +config PIC32MZ_T6 + bool "Timer 6 (T6)" + default n + +config PIC32MZ_T7 + bool "Timer 7 (T7)" + default n + +config PIC32MZ_T8 + bool "Timer 8 (T8)" + default n + +config PIC32MZ_T9 + bool "Timer 9 (T9)" + default n + +config PIC32MZ_IC1 + bool "Input Capture 1 (IC1)" + default n + +config PIC32MZ_IC2 + bool "Input Capture 2 (IC2)" + default n + +config PIC32MZ_IC3 + bool "Input Capture 3 (IC3)" + default n + +config PIC32MZ_IC4 + bool "Input Capture 4 (IC4)" + default n + +config PIC32MZ_IC5 + bool "Input Capture 5 (IC5)" + default n + +config PIC32MZ_OC1 + bool "Output Compare 1 (OC1)" + default n + +config PIC32MZ_OC2 + bool "Output Compare 2 (OC2)" + default n + +config PIC32MZ_OC3 + bool "Output Compare 3 (OC3)" + default n + +config PIC32MZ_OC4 + bool "Output Compare 4 (OC4)" + default n + +config PIC32MZ_OC5 + bool "Output Compare 5 (OC5)" + default n + +config PIC32MZ_I2C1 + bool "I2C1" + default n + +config PIC32MZ_I2C2 + bool "I2C2" + default n + +config PIC32MZ_I2C3 + bool "I2C3" + default n + +config PIC32MZ_I2C4 + bool "I2C4" + default n + +config PIC32MZ_I2C5 + bool "I2C5" + default n + +config PIC32MZ_SPI1 + bool "SPI1" + default n + select PIC32MZ_SPI + +config PIC32MZ_SPI2 + bool "SPI2" + default n + select PIC32MZ_SPI + +config PIC32MZ_SPI3 + bool "SPI3" + default n + select PIC32MZ_SPI + +config PIC32MZ_SPI4 + bool "SPI4" + default n + select PIC32MZ_SPI + +config PIC32MZ_SPI5 + bool "SPI5" + default n + select PIC32MZ_SPI + +config PIC32MZ_SPI6 + bool "SPI6" + default n + select PIC32MZ_SPI + +config PIC32MZ_UART1 + bool "UART1" + default n + select ARCH_HAVE_UART1 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_UART2 + bool "UART2" + default n + select ARCH_HAVE_UART2 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_UART3 + bool "UART3" + default n + select ARCH_HAVE_UART3 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_UART4 + bool "UART4" + default n + select ARCH_HAVE_UART4 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_UART5 + bool "UART5" + default n + select ARCH_HAVE_UART5 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_UART6 + bool "UART6" + default n + select ARCH_HAVE_UART6 + select ARCH_HAVE_SERIAL_TERMIOS + +config PIC32MZ_ADC + bool "ADC1" + default n + +config PIC32MZ_PMP + bool "Parallel Master Port (PMP)" + default n + +config PIC32MZ_CM1 + bool "Comparator 1 (CM1)" + default n + +config PIC32MZ_CM2 + bool "Comparator 2 (CM2)" + default n + +config PIC32MZ_CM3 + bool "Comparator 3 (CM3)" + default n + +config PIC32MZ_RTCC + bool "Real-Time Clock and Calendar (RTCC)" + default n + +config PIC32MZ_DMA + bool "DMA" + default n + select ARCH_DMA + +config PIC32MZ_FLASH + bool "FLASH" + default n + +config PIC32MZ_USBDEV + bool "USB device" + default n + +config PIC32MZ_USBHOST + bool "USB host" + default n + +config PIC32MZ_CAN1 + bool "Controller area network 1 (CAN1)" + default n + +config PIC32MZ_CAN2 + bool "Controller area network 2 (CAN2)" + default n + +config PIC32MZ_ETHERNET + bool "Ethernet" + default n + select NETDEVICES + select ARCH_HAVE_PHY + select ARCH_HAVE_NETDEV_STATISTICS + +config PIC32MZ_CTMU + bool "Charge Time Measurement Unit (CMTU)" + default n + +endmenu # PIC32MX Peripheral Support + +menuconfig PIC32MZ_GPIOIRQ + bool "GPIO Interrupt Support" + default n + ---help--- + Build in support for interrupts based on GPIO inputs from IOPorts + +if PIC32MZ_GPIOIRQ + +config PIC32MZ_GPIOIRQ_PORTA + bool "I/O PORTA Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTB + bool "I/O PORTB Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTC + bool "I/O PORTC Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTD + bool "I/O PORTD Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTE + bool "I/O PORTE Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTF + bool "I/O PORTF Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTG + bool "I/O PORTG Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTH + bool "I/O PORTH Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTJ + bool "I/O PORTJ Interrupt Support" + default n + +config PIC32MZ_GPIOIRQ_PORTK + bool "I/O PORTK Interrupt Support" + default n + +endif # PIC32MZ_GPIOIRQ + +menu "SPI Driver Configuration" + depends on PIC32MZ_SPI + +config PIC32MZ_SPI_INTERRUPTS + bool "SPI Interrupt Driven" + default n + depends on EXPERIMENTAL + +config PIC32MZ_SPI_ENHBUF + bool "SPI Enhanced Buffer Mode" + default n + depends on EXPERIMENTAL + +config PIC32MZ_SPI_REGDEBUG + bool "SPI Register level debug" + depends on DEBUG + default n + ---help--- + Output detailed register-level SPI device debug information. + Requires also DEBUG. + +endmenu # SPI Driver Configuration + +config PIC32MZ_T1_SOSC + bool + default n + depends on PIC32MZ_T1 + +menu "PIC32MZ PHY/Ethernet device driver settings" + depends on PIC32MZ_ETHERNET + +config PHY_AUTONEG + bool "Auto-negotiation" + default y + depends on PIC32MZ_ETHERNET + ---help--- + Enable auto-negotiation + +config PHY_SPEED100 + bool "100Mbps speed" + default n + depends on PIC32MZ_ETHERNET && !PHY_AUTONEG + ---help--- + Select 100Mbit vs. 10Mbit speed. + +config PHY_FDUPLEX + bool "Full duplex" + default n + depends on PIC32MZ_ETHERNET && !PHY_AUTONEG + ---help--- + Select full (vs. half) duplex + +config NET_NTXDESC + int "Number Tx descriptors" + default 2 + depends on PIC32MZ_ETHERNET + ---help--- + Configured number of Tx descriptors. Default: 2 + +config NET_NRXDESC + int "Number Rx descriptors" + default 4 + depends on PIC32MZ_ETHERNET + ---help--- + Configured number of Rx descriptors. Default: 4 + +config NET_PRIORITY + int "" + default 28 + depends on PIC32MZ_ETHERNET + ---help--- + Ethernet interrupt priority. The is default is the higest priority. + +config NET_WOL + bool "Wake-up on LAN" + default n + depends on PIC32MZ_ETHERNET + ---help--- + Enable Wake-up on LAN (not fully implemented). + +config NET_REGDEBUG + bool "Register level debug" + default n + depends on PIC32MZ_ETHERNET && DEBUG + ---help--- + Enabled low level register debug. Also needs DEBUG. + +config NET_HASH + bool "Hash" + default n + depends on PIC32MZ_ETHERNET + ---help--- + Enable receipt of near-perfect match frames. + +config PIC32MZ_MULTICAST + bool "Multicast" + default y if NET_IGMP + depends on PIC32MZ_ETHERNET + ---help--- + Enable receipt of multicast (and unicast) frames. Automatically set if + NET_IGMP is selected. + +endmenu # PIC32MZ PHY/Ethernet device driver settings + +menu "Device Configuration 0 (DEVCFG0)" + +config PIC32MZ_DEBUGGER_ENABLE + bool "Background debugger enable" + default y if DEBUG + default n if !DEBUG + ---help--- + Background Debugger Enable + +config PIC32MZ_JTAG_ENABLE + bool "JTAG enable" + default n + ---help--- + JTAG Enable + +config PIC32MZ_ICESEL_CH2 + bool "ICE channel 2" + default n + ---help--- + In-Circuit Emulator/Debugger Communication Channel Select. Default: Channel (PG2) + +config PIC32MZ_TRACE_ENABLE + bool "Trace enable" + default y if DEBUG + default n if !DEBUG + ---help--- + Trace Enable + +config PIC32MZ_ECC_OPTION + int "PIC32 ECC control" + default 3 + range 0 3 + ---help--- + 0: Flash ECC enabled (locked) + 1: Dynamic Flash ECC enabled (locked) */ + 2: ECC / dynamic ECC disabled (locked) */ + 3: ECC / dynamic ECC disabled (writable) */ + +endmenu # Device configuration 0 (DEVCFG0) + +menu "Device Configuration 1 (DEVCFG1)" + +config PIC32MZ_OSCIOFNC + int "CLKO Enable" + default 1 + range 0 1 + ---help--- + Enable CLK0 output on power up. Options: + + 1: CLKO output disabled + 0: CLKO output signal active on the OSC2 pin + +config PIC32MZ_WDTENABLE + bool "Watchdog enable" + default 0 + ---help--- + Enabled watchdog on power up. + + 1: Watchdog enabled, cannot be disabled + 0: Watchdog disabled, can be enabled + +endmenu # Device Configuration 2 (DEVCFG2) + +menu "Device Configuration 3 (DEVCFG3)" + +config PIC32MZ_USERID + hex "User ID" + default 0x584e + ---help--- + User-provided ID visible in DEVCFG3 + +config PIC32MZ_FMIIEN + int "Ethernet MII" + default 1 + range 0 1 + ---help--- + Ethernet MII enable selection + + 0 = RMII enabled + 1 = MII enabled + +config PIC32MZ_PGL1WAY + int + default 0 + range 0 1 + +config PIC32MZ_PMDL1WAY + int + default 0 + range 0 1 + +config PIC32MZ_IOL1WAY + int + default 0 + range 0 1 + +config PIC32MZ_FETHIO + int "Ethernet I/O pins" + default 1 + range 0 1 + ---help--- + Ethernet I/O pin selection + + 0 = Alternate Ethernet I/O pins + 1 = Default Ethernet I/O pins + +config PIC32MZ_FUSBIDIO + int "USB USBID selection" + default 0 if !PIC32MZ_ETHERNET + default 1 if PIC32MZ_ETHERNET + range 0 1 + ---help--- + USB USBID selection + + 0 = USBID pin is controlled by the port function + 1 = USBID pin is controlled by the USB module + +endmenu # Device Configuration 3 (DEVCFG3) +endif diff --git a/arch/mips/src/pic32mz/Make.defs b/arch/mips/src/pic32mz/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..b9342179eb4cca991f8b766c1628fa010f5fc663 --- /dev/null +++ b/arch/mips/src/pic32mz/Make.defs @@ -0,0 +1,87 @@ +############################################################################ +# arch/mips/src/pic32mz/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = pic32mz-head.S + +# Common MIPS files + +CMN_ASRCS = up_syscall0.S vfork.S +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_irq.c up_lowputs.c +CMN_CSRCS += up_mdelay.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_puts.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_sigdeliver.c +CMN_CSRCS += up_stackframe.c up_swint0.c up_udelay.c up_unblocktask.c +CMN_CSRCS += up_usestack.c up_vfork.c + +# Configuration dependent common files + +# Use of common/up_etherstub.c is deprecated. The preferred mechanism is to +# use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in +# up_initialize(). Then this stub would not be needed. + +ifneq ($(CONFIG_PIC32MZ_ETHERNET),y) +ifeq ($(CONFIG_NET),y) +CMN_CSRCS += up_etherstub.c +endif +endif + +ifeq ($(CONFIG_ARCH_STACKDUMP),y) +CMN_CSRCS += up_dumpstate.c +endif + +# Required PIC32MZ files + +CHIP_ASRCS = +CHIP_CSRCS = pic32mz-lowinit.c pic32mz-exception.c pic32mz-decodeirq.c +CHIP_CSRCS += pic32mz-irq.c pic32mz-timerisr.c pic32mz-gpio.c +CHIP_CSRCS += pic32mz-lowconsole.c pic32mz-serial.c + +# Configuration-dependent PIC32MZ files + +ifeq ($(CONFIG_PIC32MZ_GPIOIRQ),y) +CHIP_CSRCS += pic32mz-gpioirq.c +endif + +ifeq ($(CONFIG_PIC32MZ_SPI),y) +CHIP_CSRCS += pic32mz-spi.c +endif + +ifeq ($(CONFIG_PIC32MZ_ETHERNET),y) +CHIP_CSRCS += pic32mz-ethernet.c +endif diff --git a/arch/mips/src/pic32mz/chip/pic32mz-dma.h b/arch/mips/src/pic32mz/chip/pic32mz-dma.h new file mode 100644 index 0000000000000000000000000000000000000000..cc6367b753226802fd5da4829b15732df3252cda --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-dma.h @@ -0,0 +1,800 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/pic32mz-dma.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_DMA_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_DMA_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include +#include + +#include "chip/pic32mz-memorymap.h" + +#if CHIP_NDMACH > 0 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* DMA Channel Offsets **********************************************************************/ + +#define PIC32MZ_DMACHn_OFFSET(n) (0x0060 + 00c0 *(n)) +# define PIC32MZ_DMACH0_OFFSET 0x0060 +# define PIC32MZ_DMACH1_OFFSET 0x0120 +# define PIC32MZ_DMACH2_OFFSET 0x01e0 +# define PIC32MZ_DMACH3_OFFSET 0x02a0 +# define PIC32MZ_DMACH4_OFFSET 0x0360 +# define PIC32MZ_DMACH5_OFFSET 0x0420 +# define PIC32MZ_DMACH6_OFFSET 0x04f0 +# define PIC32MZ_DMACH7_OFFSET 0x05b0 + +/* DMA Register Offsets *********************************************************************/ +/* Global DMA Registers (relative the DMA K1BASE) */ + +#define PIC32MZ_DMA_CON_OFFSET 0x0000 /* DMA Controller Control Register */ +#define PIC32MZ_DMA_CONCLR_OFFSET 0x0004 /* DMA Controller Control Clear Register */ +#define PIC32MZ_DMA_CONSET_OFFSET 0x0008 /* DMA Controller Control Set Register */ +#define PIC32MZ_DMA_CONINV_OFFSET 0x000c /* DMA Controller Control Invert Register */ + +#define PIC32MZ_DMA_STAT_OFFSET 0x0010 /* DMA Status Register */ + +#define PIC32MZ_DMA_ADDR_OFFSET 0x0020 /* DMA Address Register */ + +#define PIC32MZ_DMA_CRCCON_OFFSET 0x0030 /* DMA CRC Control Register */ +#define PIC32MZ_DMA_CRCCONCLR_OFFSET 0x0034 /* DMA CRC Control Clear Register */ +#define PIC32MZ_DMA_CRCCONSET_OFFSET 0x0038 /* DMA CRC Control Set Register */ +#define PIC32MZ_DMA_CRCCONINV_OFFSET 0x003c /* DMA CRC Control Invert Register */ + +#define PIC32MZ_DMA_CRCDATA_OFFSET 0x0040 /* DMA CRC Data Register */ +#define PIC32MZ_DMA_CRCDATACLR_OFFSET 0x0044 /* DMA CRC Data Clear Register */ +#define PIC32MZ_DMA_CRCDATASET_OFFSET 0x0048 /* DMA CRC Data Set Register */ +#define PIC32MZ_DMA_CRCDATAINV_OFFSET 0x004c /* DMA CRC Data Invert Register */ + +#define PIC32MZ_DMA_CRCXOR_OFFSET 0x0050 /* DMA CRCXOR Enable Register */ +#define PIC32MZ_DMA_CRCXORCLR_OFFSET 0x0054 /* DMA CRCXOR Enable Clear Register */ +#define PIC32MZ_DMA_CRCXORSET_OFFSET 0x0058 /* DMA CRCXOR Enable Set Register */ +#define PIC32MZ_DMA_CRCXORINV_OFFSET 0x005c /* DMA CRCXOR Enable Invert Register */ + +/* Per-Channel DMA Registers (relative to DMA channel base) */ + +#define PIC32MZ_DMACH_CON_OFFSET 0x0000 /* DMA Channel Control Register */ +#define PIC32MZ_DMACH_CONCLR_OFFSET 0x0004 /* DMA Channel Control Clear Register */ +#define PIC32MZ_DMACH_CONSET_OFFSET 0x0008 /* DMA Channel Control Set Register */ +#define PIC32MZ_DMACH_CONINV_OFFSET 0x000c /* DMA Channel Control Invert Register */ + +#define PIC32MZ_DMACH_ECON_OFFSET 0x0010 /* DMA Channel Event Control Register */ +#define PIC32MZ_DMACH_ECONCLR_OFFSET 0x0014 /* DMA Channel Event Control Clear Register */ +#define PIC32MZ_DMACH_ECONSET_OFFSET 0x0018 /* DMA Channel Event Control Set Register */ +#define PIC32MZ_DMACH_ECONINV_OFFSET 0x001c /* DMA Channel Event Control Invert Register */ + +#define PIC32MZ_DMACH_INT_OFFSET 0x0020 /* DMA Channel Interrupt Control Register */ +#define PIC32MZ_DMACH_INTCLR_OFFSET 0x0024 /* DMA Channel Interrupt Control Clear Register */ +#define PIC32MZ_DMACH_INTSET_OFFSET 0x0028 /* DMA Channel Interrupt Control Set Register */ +#define PIC32MZ_DMACH_INTINV_OFFSET 0x002c /* DMA Channel Interrupt Control Invert Register */ + +#define PIC32MZ_DMACH_SSA_OFFSET 0x0030 /* DMA Channel Source Start Address Register */ +#define PIC32MZ_DMACH_SSACLR_OFFSET 0x0034 /* DMA Channel Source Start Address Clear Register */ +#define PIC32MZ_DMACH_SSASET_OFFSET 0x0038 /* DMA Channel Source Start Address Set Register */ +#define PIC32MZ_DMACH_SSAINV_OFFSET 0x003c /* DMA Channel Source Start Address Invert Register */ + +#define PIC32MZ_DMACH_DSA_OFFSET 0x0040 /* DMA Channel Destination Start Address Register */ +#define PIC32MZ_DMACH_DSACLR_OFFSET 0x0044 /* DMA Channel Destination Start Address Clear Register */ +#define PIC32MZ_DMACH_DSASET_OFFSET 0x0048 /* DMA Channel Destination Start Address Set Register */ +#define PIC32MZ_DMACH_DSAINV_OFFSET 0x004c /* DMA Channel Destination Start Address Invert Register */ + +#define PIC32MZ_DMACH_SSIZ_OFFSET 0x0050 /* DMA Channel Source Size Register */ +#define PIC32MZ_DMACH_SSIZCLR_OFFSET 0x0054 /* DMA Channel Source Size Clear Register */ +#define PIC32MZ_DMACH_SSIZSET_OFFSET 0x0058 /* DMA Channel Source Size Set Register */ +#define PIC32MZ_DMACH_SSIZINV_OFFSET 0x005c /* DMA Channel Source Size Invert Register */ + +#define PIC32MZ_DMACH_DSIZ_OFFSET 0x0060 /* DMA Channel Destination Size Register */ +#define PIC32MZ_DMACH_DSIZCLR_OFFSET 0x0064 /* DMA Channel Destination Size Clear Register */ +#define PIC32MZ_DMACH_DSIZSET_OFFSET 0x0068 /* DMA Channel Destination Size Set Register */ +#define PIC32MZ_DMACH_DSIZINV_OFFSET 0x006c /* DMA Channel Destination Size Invert Register */ + +#define PIC32MZ_DMACH_SPTR_OFFSET 0x0070 /* DMA Channel Source Pointer Register */ +#define PIC32MZ_DMACH_DPTR_OFFSET 0x0080 /* DMA Channel Destination Pointer Register */ + +#define PIC32MZ_DMACH_CSIZ_OFFSET 0x0090 /* DMA Channel Cell-Size Register */ +#define PIC32MZ_DMACH_CSIZCLR_OFFSET 0x0094 /* DMA Channel Cell-Size Clear Register */ +#define PIC32MZ_DMACH_CSIZSET_OFFSET 0x0098 /* DMA Channel Cell-Size Set Register */ +#define PIC32MZ_DMACH_CSIZINV_OFFSET 0x009c /* DMA Channel Cell-Size Invert Register */ + +#define PIC32MZ_DMACH_CPTR_OFFSET 0x00a0 /* DMA Channel Cell Pointer Register */ + +#define PIC32MZ_DMACH_DAT_OFFSET 0x00b0 /* DMA Channel Pattern Data Register */ +#define PIC32MZ_DMACH_DATCLR_OFFSET 0x00b4 /* DMA Channel Pattern Data Clear Register */ +#define PIC32MZ_DMACH_DATSET_OFFSET 0x00b8 /* DMA Channel Pattern Data Set Register */ +#define PIC32MZ_DMACH_DATINV_OFFSET 0x00bc /* DMA Channel Pattern Data Invert Register */ + +/* DMA Channel Addresses ********************************************************************/ + +#define PIC32MZ_DMACHn_K1BASE(n) (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACHn_OFFSET(n)) +# define PIC32MZ_DMACH0_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH0_OFFSET) +# define PIC32MZ_DMACH1_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH1_OFFSET) +# define PIC32MZ_DMACH2_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH2_OFFSET) +# define PIC32MZ_DMACH3_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH3_OFFSET) +# define PIC32MZ_DMACH4_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH4_OFFSET) +# define PIC32MZ_DMACH5_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH5_OFFSET) +# define PIC32MZ_DMACH6_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH6_OFFSET) +# define PIC32MZ_DMACH7_K1BASE (PIC32MZ_DMA_K1BASE+PIC32MZ_DMACH7_OFFSET) + +/* DMA Register Addresses *******************************************************************/ +/* Global DMA Registers */ + +#define PIC32MZ_DMA_CON (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CON_OFFSET) +#define PIC32MZ_DMA_CONCLR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CONCLR_OFFSET) +#define PIC32MZ_DMA_CONSET (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CONSET_OFFSET) +#define PIC32MZ_DMA_CONINV (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CONINV_OFFSET) + +#define PIC32MZ_DMA_STAT (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_STAT_OFFSET) + +#define PIC32MZ_DMA_ADDR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_ADDR_OFFSET) +#define PIC32MZ_DMA_CRCCON (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCCON_OFFSET) +#define PIC32MZ_DMA_CRCCONCLR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCCONCLR_OFFSET) +#define PIC32MZ_DMA_CRCCONSET (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCCONSET_OFFSET) +#define PIC32MZ_DMA_CRCCONINV (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCCONINV_OFFSET) + +#define PIC32MZ_DMA_CRCDATA (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCDATA_OFFSET) +#define PIC32MZ_DMA_CRCDATACLR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCDATACLR_OFFSET) +#define PIC32MZ_DMA_CRCDATASET (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCDATASET_OFFSET) +#define PIC32MZ_DMA_CRCDATAINV (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCDATAINV_OFFSET) + +#define PIC32MZ_DMA_CRCXOR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCXOR_OFFSET) +#define PIC32MZ_DMA_CRCXORCLR (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCXORCLR_OFFSET) +#define PIC32MZ_DMA_CRCXORSET (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCXORSET_OFFSET) +#define PIC32MZ_DMA_CRCXORINV (PIC32MZ_DMA_K1BASE+PIC32MZ_DMA_CRCXORINV_OFFSET) + +/* Per-Channel DMA Registers */ + +#define PIC32MZ_DMACH_CON(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CON_OFFSET) +#define PIC32MZ_DMACH_CONCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CONCLR_OFFSET) +#define PIC32MZ_DMACH_CONSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CONSET_OFFSET) +#define PIC32MZ_DMACH_CONINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CONINV_OFFSET) + +#define PIC32MZ_DMACH_ECON(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_ECON_OFFSET) +#define PIC32MZ_DMACH_ECONCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_ECONCLR_OFFSET) +#define PIC32MZ_DMACH_ECONSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_ECONSET_OFFSET) +#define PIC32MZ_DMACH_ECONINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_ECONINV_OFFSET) + +#define PIC32MZ_DMACH_INT(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_INT_OFFSET) +#define PIC32MZ_DMACH_INTCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_INTCLR_OFFSET) +#define PIC32MZ_DMACH_INTSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_INTSET_OFFSET) +#define PIC32MZ_DMACH_INTINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_INTINV_OFFSET) + +#define PIC32MZ_DMACH_SSA(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSA_OFFSET) +#define PIC32MZ_DMACH_SSACLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSACLR_OFFSET) +#define PIC32MZ_DMACH_SSASET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSASET_OFFSET) +#define PIC32MZ_DMACH_SSAINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSAINV_OFFSET) + +#define PIC32MZ_DMACH_DSA(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSA_OFFSET) +#define PIC32MZ_DMACH_DSACLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSACLR_OFFSET) +#define PIC32MZ_DMACH_DSASET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSASET_OFFSET) +#define PIC32MZ_DMACH_DSAINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSAINV_OFFSET) + +#define PIC32MZ_DMACH_SSIZ(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSIZ_OFFSET) +#define PIC32MZ_DMACH_SSIZCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSIZCLR_OFFSET) +#define PIC32MZ_DMACH_SSIZSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSIZSET_OFFSET) +#define PIC32MZ_DMACH_SSIZINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SSIZINV_OFFSET) + +#define PIC32MZ_DMACH_DSIZ(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSIZ_OFFSET) +#define PIC32MZ_DMACH_DSIZCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSIZCLR_OFFSET) +#define PIC32MZ_DMACH_DSIZSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSIZSET_OFFSET) +#define PIC32MZ_DMACH_DSIZINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DSIZINV_OFFSET) + +#define PIC32MZ_DMACH_SPTR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_SPTR_OFFSET) + +#define PIC32MZ_DMACH_DPTR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DPTR_OFFSET) + +#define PIC32MZ_DMACH_CSIZ(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CSIZ_OFFSET) +#define PIC32MZ_DMACH_CSIZCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CSIZCLR_OFFSET) +#define PIC32MZ_DMACH_CSIZSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CSIZSET_OFFSET) +#define PIC32MZ_DMACH_CSIZINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CSIZINV_OFFSET) + +#define PIC32MZ_DMACH_CPTR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_CPTR_OFFSET) + +#define PIC32MZ_DMACH_DAT(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DAT_OFFSET) +#define PIC32MZ_DMACH_DATCLR(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DATCLR_OFFSET) +#define PIC32MZ_DMACH_DATSET(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DATSET_OFFSET) +#define PIC32MZ_DMACH_DATINV(n) (PIC32MZ_DMACHn_K1BASE(n)+PIC32MZ_DMACH_DATINV_OFFSET) + +#if CHIP_NDMACH > 0 +# define PIC32MZ_DMACH0_CON (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH0_CONCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH0_CONSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH0_CONINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH0_ECON (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH0_ECONCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH0_ECONSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH0_ECONINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH0_INT (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH0_INTCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH0_INTSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH0_INTINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH0_SSA (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH0_SSACLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH0_SSASET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH0_SSAINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH0_DSA (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH0_DSACLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH0_DSASET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH0_DSAINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH0_SSIZ (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH0_SSIZCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH0_SSIZSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH0_SSIZINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH0_DSIZ (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH0_DSIZCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH0_DSIZSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH0_DSIZINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH0_SPTR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH0_DPTR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH0_CSIZ (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH0_CSIZCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH0_CSIZSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH0_CSIZINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH0_CPTR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH0_DAT (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH0_DATCLR (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH0_DATSET (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH0_DATINV (PIC32MZ_DMACH0_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 1 +# define PIC32MZ_DMACH1_CON (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH1_CONCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH1_CONSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH1_CONINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH1_ECON (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH1_ECONCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH1_ECONSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH1_ECONINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH1_INT (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH1_INTCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH1_INTSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH1_INTINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH1_SSA (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH1_SSACLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH1_SSASET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH1_SSAINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH1_DSA (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH1_DSACLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH1_DSASET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH1_DSAINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH1_SSIZ (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH1_SSIZCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH1_SSIZSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH1_SSIZINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH1_DSIZ (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH1_DSIZCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH1_DSIZSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH1_DSIZINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH1_SPTR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH1_DPTR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH1_CSIZ (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH1_CSIZCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH1_CSIZSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH1_CSIZINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH1_CPTR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH1_DAT (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH1_DATCLR (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH1_DATSET (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH1_DATINV (PIC32MZ_DMACH1_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 2 +# define PIC32MZ_DMACH2_CON (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH2_CONCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH2_CONSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH2_CONINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH2_ECON (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH2_ECONCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH2_ECONSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH2_ECONINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH2_INT (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH2_INTCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH2_INTSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH2_INTINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH2_SSA (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH2_SSACLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH2_SSASET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH2_SSAINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH2_DSA (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH2_DSACLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH2_DSASET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH2_DSAINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH2_SSIZ (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH2_SSIZCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH2_SSIZSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH2_SSIZINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH2_DSIZ (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH2_DSIZCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH2_DSIZSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH2_DSIZINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH2_SPTR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH2_DPTR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH2_CSIZ (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH2_CSIZCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH2_CSIZSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH2_CSIZINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH2_CPTR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH2_DAT (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH2_DATCLR (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH2_DATSET (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH2_DATINV (PIC32MZ_DMACH2_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) + +#if CHIP_NDMACH > 3 +# define PIC32MZ_DMACH3_CON (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH3_CONCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH3_CONSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH3_CONINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH3_ECON (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH3_ECONCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH3_ECONSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH3_ECONINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH3_INT (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH3_INTCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH3_INTSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH3_INTINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH3_SSA (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH3_SSACLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH3_SSASET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH3_SSAINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH3_DSA (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH3_DSACLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH3_DSASET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH3_DSAINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH3_SSIZ (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH3_SSIZCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH3_SSIZSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH3_SSIZINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH3_DSIZ (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH3_DSIZCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH3_DSIZSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH3_DSIZINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH3_SPTR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH3_DPTR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH3_CSIZ (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH3_CSIZCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH3_CSIZSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH3_CSIZINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH3_CPTR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH3_DAT (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH3_DATCLR (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH3_DATSET (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH3_DATINV (PIC32MZ_DMACH3_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 4 +# define PIC32MZ_DMACH4_CON (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH4_CONCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH4_CONSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH4_CONINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH4_ECON (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH4_ECONCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH4_ECONSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH4_ECONINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH4_INT (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH4_INTCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH4_INTSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH4_INTINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH4_SSA (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH4_SSACLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH4_SSASET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH4_SSAINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH4_DSA (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH4_DSACLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH4_DSASET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH4_DSAINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH4_SSIZ (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH4_SSIZCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH4_SSIZSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH4_SSIZINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH4_DSIZ (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH4_DSIZCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH4_DSIZSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH4_DSIZINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH4_SPTR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH4_DPTR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH4_CSIZ (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH4_CSIZCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH4_CSIZSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH4_CSIZINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH4_CPTR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH4_DAT (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH4_DATCLR (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH4_DATSET (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH4_DATINV (PIC32MZ_DMACH4_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 5 +# define PIC32MZ_DMACH5_CON (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH5_CONCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH5_CONSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH5_CONINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH5_ECON (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH5_ECONCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH5_ECONSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH5_ECONINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH5_INT (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH5_INTCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH5_INTSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH5_INTINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH5_SSA (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH5_SSACLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH5_SSASET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH5_SSAINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH5_DSA (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH5_DSACLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH5_DSASET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH5_DSAINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH5_SSIZ (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH5_SSIZCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH5_SSIZSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH5_SSIZINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH5_DSIZ (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH5_DSIZCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH5_DSIZSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH5_DSIZINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH5_SPTR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH5_DPTR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH5_CSIZ (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH5_CSIZCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH5_CSIZSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH5_CSIZINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH5_CPTR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH5_DAT (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH5_DATCLR (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH5_DATSET (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH5_DATINV (PIC32MZ_DMACH5_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 6 +# define PIC32MZ_DMACH6_CON (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH6_CONCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH6_CONSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH6_CONINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH6_ECON (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH6_ECONCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH6_ECONSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH6_ECONINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH6_INT (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH6_INTCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH6_INTSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH6_INTINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH6_SSA (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH6_SSACLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH6_SSASET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH6_SSAINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH6_DSA (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH6_DSACLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH6_DSASET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH6_DSAINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH6_SSIZ (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH6_SSIZCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH6_SSIZSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH6_SSIZINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH6_DSIZ (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH6_DSIZCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH6_DSIZSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH6_DSIZINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH6_SPTR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH6_DPTR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH6_CSIZ (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH6_CSIZCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH6_CSIZSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH6_CSIZINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH6_CPTR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH6_DAT (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH6_DATCLR (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH6_DATSET (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH6_DATINV (PIC32MZ_DMACH6_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +#if CHIP_NDMACH > 7 +# define PIC32MZ_DMACH7_CON (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CON_OFFSET) +# define PIC32MZ_DMACH7_CONCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CONCLR_OFFSET) +# define PIC32MZ_DMACH7_CONSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CONSET_OFFSET) +# define PIC32MZ_DMACH7_CONINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CONINV_OFFSET) + +# define PIC32MZ_DMACH7_ECON (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_ECON_OFFSET) +# define PIC32MZ_DMACH7_ECONCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_ECONCLR_OFFSET) +# define PIC32MZ_DMACH7_ECONSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_ECONSET_OFFSET) +# define PIC32MZ_DMACH7_ECONINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_ECONINV_OFFSET) + +# define PIC32MZ_DMACH7_INT (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_INT_OFFSET) +# define PIC32MZ_DMACH7_INTCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_INTCLR_OFFSET) +# define PIC32MZ_DMACH7_INTSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_INTSET_OFFSET) +# define PIC32MZ_DMACH7_INTINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_INTINV_OFFSET) + +# define PIC32MZ_DMACH7_SSA (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSA_OFFSET) +# define PIC32MZ_DMACH7_SSACLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSACLR_OFFSET) +# define PIC32MZ_DMACH7_SSASET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSASET_OFFSET) +# define PIC32MZ_DMACH7_SSAINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSAINV_OFFSET) + +# define PIC32MZ_DMACH7_DSA (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSA_OFFSET) +# define PIC32MZ_DMACH7_DSACLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSACLR_OFFSET) +# define PIC32MZ_DMACH7_DSASET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSASET_OFFSET) +# define PIC32MZ_DMACH7_DSAINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSAINV_OFFSET) + +# define PIC32MZ_DMACH7_SSIZ (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSIZ_OFFSET) +# define PIC32MZ_DMACH7_SSIZCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSIZCLR_OFFSET) +# define PIC32MZ_DMACH7_SSIZSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSIZSET_OFFSET) +# define PIC32MZ_DMACH7_SSIZINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SSIZINV_OFFSET) + +# define PIC32MZ_DMACH7_DSIZ (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSIZ_OFFSET) +# define PIC32MZ_DMACH7_DSIZCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSIZCLR_OFFSET) +# define PIC32MZ_DMACH7_DSIZSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSIZSET_OFFSET) +# define PIC32MZ_DMACH7_DSIZINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DSIZINV_OFFSET) + +# define PIC32MZ_DMACH7_SPTR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_SPTR_OFFSET) +# define PIC32MZ_DMACH7_DPTR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DPTR_OFFSET) + +# define PIC32MZ_DMACH7_CSIZ (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CSIZ_OFFSET) +# define PIC32MZ_DMACH7_CSIZCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CSIZCLR_OFFSET) +# define PIC32MZ_DMACH7_CSIZSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CSIZSET_OFFSET) +# define PIC32MZ_DMACH7_CSIZINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CSIZINV_OFFSET) + +# define PIC32MZ_DMACH7_CPTR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_CPTR_OFFSET) + +# define PIC32MZ_DMACH7_DAT (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DAT_OFFSET) +# define PIC32MZ_DMACH7_DATCLR (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DATCLR_OFFSET) +# define PIC32MZ_DMACH7_DATSET (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DATSET_OFFSET) +# define PIC32MZ_DMACH7_DATINV (PIC32MZ_DMACH7_K1BASE+PIC32MZ_DMACH_DATINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***********************************************************/ +/* Global DMA Registers */ +/* DMA Controller Control Register */ + +#define DMA_CON_DMABUSY (1 << 11) /* Bit 15: DMA module busy */ +#define DMA_CON_SUSPEND (1 << 12) /* Bit 12: DMA suspend */ +#define DMA_CON_ON (1 << 15) /* Bit 15: DMA on */ + +/* DMA Status Register */ + +#define DMA_STAT_DMACH_SHIFT (0) /* Bits 0-1: DMA channel */ +#define DMA_STAT_DMACH_MASK (3 << DMA_STAT_DMACH_SHIFT) +#define DMA_STAT_RDWR (1 << 3) /* Bit 3: Read/write status */ + +/* DMA Address Register -- This register contains a 32-bit address value */ + +/* DMA CRC Control Register */ + +#define DMA_CRCCON_CRCCH_SHIFT (0) /* Bits 0-2: CRC channel select */ +#define DMA_CRCCON_CRCCH_MASK (7 << DMA_CRCCON_CRCCH_SHIFT) +# define DMA_CRCCON_CRCCH(n) ((uint32_t)(n) << DMA_CRCCON_CRCCH_SHIFT) +#define DMA_CRCCON_CRCTYP (1 << 5) /* Bit 5: CRC type selection */ +#define DMA_CRCCON_CRCAPP (1 << 6) /* Bit 6: CRC append mode */ +#define DMA_CRCCON_CRCEN (1 << 7) /* Bit 7: CRC enable */ +#define DMA_CRCCON_PLEN_SHIFT (8) /* Bits 8-12: Polynomial length */ +#define DMA_CRCCON_PLEN_MASK (31 << DMA_CRCCON_PLEN_SHIFT) +# define DMA_CRCCON_PLEN(n) ((uint32_t)(n) << DMA_CRCCON_PLEN_SHIFT) +#define DMA_CRCCON_BITO (1 << 24) /* Bit 24: CRC bit order selection */ +#define DMA_CRCCON_WBO (1 << 27) /* Bit 27: CRC write byte order selection */ +#define DMA_CRCCON_BYTO_SHIFT (28) /* Bits 28-29: CRC byte order selection */ +#define DMA_CRCCON_BYTO_MASK (3 << DMA_CRCCON_BYTO_SHIFT) +# define DMA_CRCCON_BYTO_SRCORDER (0 << DMA_CRCCON_BYTO_SHIFT) /* No swapping (i.e., source byte order) */ +# define DMA_CRCCON_BYTO_SWAP32 (1 << DMA_CRCCON_BYTO_SHIFT) /* Endian byte swap on word boundaries */ +# define DMA_CRCCON_BYTO_SWAP32H (2 << DMA_CRCCON_BYTO_SHIFT) /* Swap half-words on word boundaries */ +# define DMA_CRCCON_BYTO_SWAP16 (3 << DMA_CRCCON_BYTO_SHIFT) /* Endian byte swap on half-word boundaries */ + +/* DMA CRC Data Register -- 16 or 32-bits of data */ +/* DMA CRCXOR Enable Register -- 16 or 32-bits of data */ + +/* Per-Channel DMA Registers */ +/* DMA Channel Control Register */ + +#define DMACH_CON_CHPRI_SHIFT (0) /* Bits 0-1: Channel priority */ +#define DMACH_CON_CHPRI_MASK (3 << DMACH_CON_CHPRI_SHIFT) +# define DMACH_CON_CHPRI(n) ((n) << DMACH_CON_CHPRI_SHIFT) +#define DMACH_CON_CHEDET (1 << 2) /* Bit 2: Channel event detected */ +#define DMACH_CON_CHAEN (1 << 4) /* Bit 4: Channel automatic enable */ +#define DMACH_CON_CHCHN (1 << 5) /* Bit 5: Channel chain enable */ +#define DMACH_CON_CHAED (1 << 6) /* Bit 6: Channel allow events if disabled */ +#define DMACH_CON_CHEN (1 << 7) /* Bit 7: Channel enable */ +#define DMACH_CON_CHCHNS (1 << 8) /* Bit 8: Chain channel selection */ +#define DMACH_CON_CHPATLEN (1 << 11) /* Bit 11: Pattern Length bit */ +#define DMACH_CON_CHPIGNEN (1 << 13) /* Bit 13: Enable Pattern Ignore Byte bit */ +#define DMACH_CON_CHBUSY (1 << 15) /* Bit 15: Channel busy */ +#define DMACH_CON_CHPIGN_SHIFT (24) /* Bits 24-31: Channel Register Data bits */ +#define DMACH_CON_CHPIGN_MASK (0xff << DMACH_CON_CHPIGN_SHIFT) +# define DMACH_CON_CHPIGN(n) ((uint32_t)(n) << DMACH_CON_CHPIGN_SHIFT) + +/* DMA Channel Event Control Register */ + +#define DMACH_ECON_AIRQEN (1 << 3) /* Bit 3: Channel abort IRQ enable */ +#define DMACH_ECON_SIRQEN (1 << 4) /* Bit 4: Channel start IRQ enable */ +#define DMACH_ECON_PATEN (1 << 5) /* Bit 5: Channel pattern match abort enable */ +#define DMACH_ECON_CABORT (1 << 6) /* Bit 6: DMA abort transfer */ +#define DMACH_ECON_CFORCE (1 << 7) /* Bit 7: DMA forced transfer */ +#define DMACH_ECON_CHSIRQ_SHIFT (8) /* Bits 8-15: Channel Transfer Start IRQ */ +#define DMACH_ECON_CHSIRQ_MASK (0xff << DMACH_ECON_CHSIRQ_SHIFT) +# define DMACH_ECON_CHSIRQ(n) ((uint32_t)(n) << DMACH_ECON_CHSIRQ_SHIFT) +#define DMACH_ECON_CHAIRQ_SHIFT (16) /* Bits 16-23: Channel transfer abort irq */ +#define DMACH_ECON_CHAIRQ_MASK (0xff << DMACH_ECON_CHAIRQ_SHIFT) +# define DMACH_ECON_CHAIRQ(n) ((uint32_t)(n) << DMACH_ECON_CHAIRQ_SHIFT) + +/* DMA Channel Interrupt Control Register */ + +#define DMACH_INT_CHERIF (1 << 0) /* Bit 0: Channel address error interrupt flag */ +#define DMACH_INT_CHTAIF (1 << 1) /* Bit 1: Channel transfer abort interrupt flag */ +#define DMACH_INT_CHCCIF (1 << 2) /* Bit 2: Channel cell transfer complete interrupt flag */ +#define DMACH_INT_CHBCIF (1 << 3) /* Bit 3: Channel block transfer complete interrupt flag */ +#define DMACH_INT_CHDHIF (1 << 4) /* Bit 4: Channel destination half full interrupt flag */ +#define DMACH_INT_CHDDIF (1 << 5) /* Bit 5: Channel destination done interrupt flag */ +#define DMACH_INT_CHSHIF (1 << 6) /* Bit 6: Channel source half empty interrupt flag */ +#define DMACH_INT_CHSDIF (1 << 7) /* Bit 7: Channel source done interrupt flag */ +#define DMACH_INT_CHERIE (1 << 16) /* Bit 16: Channel address error interrupt enable */ +#define DMACH_INT_CHTAIE (1 << 17) /* Bit 17: Channel transfer abort interrupt enable */ +#define DMACH_INT_CHCCIE (1 << 18) /* Bit 18: Channel cell transfer complete interrupt enable */ +#define DMACH_INT_CHBCIE (1 << 19) /* Bit 19: Channel block transfer complete interrupt enable */ +#define DMACH_INT_CHDHIE (1 << 20) /* Bit 20: Channel destination half full interrupt enable */ +#define DMACH_INT_CHDDIE (1 << 21) /* Bit 21: Channel destination done interrupt enable */ +#define DMACH_INT_CHSHIE (1 << 22) /* Bit 22: Channel source half empty interrupt enable */ +#define DMACH_INT_CHSDIE (1 << 23) /* Bit 23: Channel source done interrupt enable */ + +/* DMA Channel Source Start Address Register -- This register contains a 32-bit address value */ +/* DMA Channel Destination Start Address Register -- This register contains a 32-bit address value */ +/* DMA Channel Source Size Register -- 16 bits of byte size data */ + +#define DMACH_SSIZ_MASK 0x0000ffff + +/* DMA Channel Destination Size Register -- 16 bits of byte size data */ + +#define DMACH_DSIZ_MASK 0x0000ffff + +/* DMA Channel Source Pointer Register -- 16 bits of byte index data */ + +#define DMACH_SPTR_MASK 0x0000ffff + +/* DMA Channel Destination Pointer Register -- 16 bits of byte index data */ + +#define DMACH_DPTR_MASK 0x0000ffff + +/* DMA Channel Cell-Size Register -- 16 bits of byte transferred data */ + +#define DMACH_CSIZ_MASK 0x0000ffff + +/* DMA Channel Cell Pointer Register -- 16 bits of byte transferred data */ + +#define DMACH_DPCR_MASK 0x0000ffff + +/* DMA Channel Pattern Data Register -- 16 bits of pattern data */ + +#define DMACH_DAT_MASK 0x0000ffff + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NDMACH > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_DMA_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-ethernet.h b/arch/mips/src/pic32mz/chip/pic32mz-ethernet.h new file mode 100644 index 0000000000000000000000000000000000000000..ae0836589b7dff2ac628442a4d91b8082dd17e2e --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-ethernet.h @@ -0,0 +1,1001 @@ +/**************************************************************************************************** + * arch/mips/src/pic32mz/chip/pic32mz-ethernet.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_ETHERNET_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_ETHERNET_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include + +#include "chip/pic32mz-memorymap.h" + +#if CHIP_NETHERNET > 0 + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* Register Offsets *********************************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MZ_ETH_CON1_OFFSET 0x0000 /* Ethernet Controller Control 1 Register */ +#define PIC32MZ_ETH_CON1CLR_OFFSET 0x0004 +#define PIC32MZ_ETH_CON1SET_OFFSET 0x0008 +#define PIC32MZ_ETH_CON1INV_OFFSET 0x000c + +#define PIC32MZ_ETH_CON2_OFFSET 0x0010 /* Ethernet Controller Control 2 Register */ +#define PIC32MZ_ETH_CON2CLR_OFFSET 0x0014 +#define PIC32MZ_ETH_CON2SET_OFFSET 0x0018 +#define PIC32MZ_ETH_CON2INV_OFFSET 0x001c + +#define PIC32MZ_ETH_TXST_OFFSET 0x0020 /* Ethernet Controller TX Packet Descriptor Start Address Register */ +#define PIC32MZ_ETH_TXSTCLR_OFFSET 0x0024 +#define PIC32MZ_ETH_TXSTSET_OFFSET 0x0028 +#define PIC32MZ_ETH_TXSTINV_OFFSET 0x002c + +#define PIC32MZ_ETH_RXST_OFFSET 0x0030 /* Ethernet Controller RX Packet Descriptor Start Address Register */ +#define PIC32MZ_ETH_RXSTCLR_OFFSET 0x0034 +#define PIC32MZ_ETH_RXSTSET_OFFSET 0x0038 +#define PIC32MZ_ETH_RXSTINV_OFFSET 0x003c + +#define PIC32MZ_ETH_IEN_OFFSET 0x00c0 /* Ethernet Controller Interrupt Enable Register */ +#define PIC32MZ_ETH_IENCLR_OFFSET 0x00c4 +#define PIC32MZ_ETH_IENSET_OFFSET 0x00c8 +#define PIC32MZ_ETH_IENINV_OFFSET 0x00cc + +#define PIC32MZ_ETH_IRQ_OFFSET 0x00d0 /* Ethernet Controller Interrupt Request Register */ +#define PIC32MZ_ETH_IRQCLR_OFFSET 0x00d4 +#define PIC32MZ_ETH_IRQSET_OFFSET 0x00d8 +#define PIC32MZ_ETH_IRQINV_OFFSET 0x00dc + +#define PIC32MZ_ETH_STAT_OFFSET 0x00e0 /* Ethernet Controller Status Register */ + +/* RX Filtering Configuration Registers */ + +#define PIC32MZ_ETH_RXFC_OFFSET 0x00a0 /* Ethernet Controller Receive Filter Configuration Register */ +#define PIC32MZ_ETH_RXFCCLR_OFFSET 0x00a4 +#define PIC32MZ_ETH_RXFCSET_OFFSET 0x00a8 +#define PIC32MZ_ETH_RXFCINV_OFFSET 0x00ac + +#define PIC32MZ_ETH_HT0_OFFSET 0x0040 /* Ethernet Controller Hash Table 0 Register */ +#define PIC32MZ_ETH_HT0CLR_OFFSET 0x0044 +#define PIC32MZ_ETH_HT0SET_OFFSET 0x0048 +#define PIC32MZ_ETH_HT0INV_OFFSET 0x004c + +#define PIC32MZ_ETH_HT1_OFFSET 0x0050 /* Ethernet Controller Hash Table 1 Register */ +#define PIC32MZ_ETH_HT1CLR_OFFSET 0x0054 +#define PIC32MZ_ETH_HT1SET_OFFSET 0x0058 +#define PIC32MZ_ETH_HT1INV_OFFSET 0x005c + +#define PIC32MZ_ETH_PMM0_OFFSET 0x0060 /* Ethernet Controller Pattern Match Mask 0 Register */ +#define PIC32MZ_ETH_PMM0CLR_OFFSET 0x0064 +#define PIC32MZ_ETH_PMM0SET_OFFSET 0x0068 +#define PIC32MZ_ETH_PMM0INV_OFFSET 0x006c + +#define PIC32MZ_ETH_PMM1_OFFSET 0x0070 /* Ethernet Controller Pattern Match Mask 1 Register */ +#define PIC32MZ_ETH_PMM1CLR_OFFSET 0x0074 +#define PIC32MZ_ETH_PMM1SET_OFFSET 0x0078 +#define PIC32MZ_ETH_PMM1INV_OFFSET 0x007c + +#define PIC32MZ_ETH_PMCS_OFFSET 0x0080 /* Ethernet Controller Pattern Match Checksum Register */ +#define PIC32MZ_ETH_PMCSCLR_OFFSET 0x0084 +#define PIC32MZ_ETH_PMCSSET_OFFSET 0x0088 +#define PIC32MZ_ETH_PMCSINV_OFFSET 0x008c + +#define PIC32MZ_ETH_PMO_OFFSET 0x0090 /* Ethernet Controller Pattern Match Offset Register */ +#define PIC32MZ_ETH_PMOCLR_OFFSET 0x0094 +#define PIC32MZ_ETH_PMOSET_OFFSET 0x0098 +#define PIC32MZ_ETH_PMOINV_OFFSET 0x009c + +/* Flow Control Configuring Register */ + +#define PIC32MZ_ETH_RXWM_OFFSET 0x00b0 /* Ethernet Controller Receive Watermarks Register */ +#define PIC32MZ_ETH_RXWMCLR_OFFSET 0x00b4 +#define PIC32MZ_ETH_RXWMSET_OFFSET 0x00b8 +#define PIC32MZ_ETH_RXWMINV_OFFSET 0x00bc + +/* Ethernet Statistics Registers */ + +#define PIC32MZ_ETH_RXOVFLOW_OFFSET 0x0100 /* Ethernet Controller Receive Overflow Statistics Register */ +#define PIC32MZ_ETH_RXOVFLOWCLR_OFFSET 0x0104 +#define PIC32MZ_ETH_RXOVFLOWSET_OFFSET 0x0108 +#define PIC32MZ_ETH_RXOVFLOWINV_OFFSET 0x010c + +#define PIC32MZ_ETH_FRMTXOK_OFFSET 0x0110 /* Ethernet Controller Frames Transmitted OK Statistics Register */ +#define PIC32MZ_ETH_FRMTXOKCLR_OFFSET 0x0114 +#define PIC32MZ_ETH_FRMTXOKSET_OFFSET 0x0118 +#define PIC32MZ_ETH_FRMTXOKINV_OFFSET 0x011c + +#define PIC32MZ_ETH_SCOLFRM_OFFSET 0x0120 /* Ethernet Controller Single Collision Frames Statistics Register */ +#define PIC32MZ_ETH_SCOLFRMCLR_OFFSET 0x0124 +#define PIC32MZ_ETH_SCOLFRMSET_OFFSET 0x0128 +#define PIC32MZ_ETH_SCOLFRMINV_OFFSET 0x012c + +#define PIC32MZ_ETH_MCOLFRM_OFFSET 0x0130 /* Ethernet Controller Multiple Collision Frames Statistics Register */ +#define PIC32MZ_ETH_MCOLFRMCLR_OFFSET 0x0134 +#define PIC32MZ_ETH_MCOLFRMSET_OFFSET 0x0138 +#define PIC32MZ_ETH_MCOLFRMINV_OFFSET 0x013c + +#define PIC32MZ_ETH_FRMRXOK_OFFSET 0x0140 /* Ethernet Controller Frames Received OK Statistics Register */ +#define PIC32MZ_ETH_FRMRXOKCLR_OFFSET 0x0144 +#define PIC32MZ_ETH_FRMRXOKSET_OFFSET 0x0148 +#define PIC32MZ_ETH_FRMRXOKINV_OFFSET 0x014c + +#define PIC32MZ_ETH_FCSERR_OFFSET 0x0150 /* Ethernet Controller Frame Check Sequence Error Statistics Register */ +#define PIC32MZ_ETH_FCSERRCLR_OFFSET 0x0154 +#define PIC32MZ_ETH_FCSERRSET_OFFSET 0x0158 +#define PIC32MZ_ETH_FCSERRINV_OFFSET 0x015c + +#define PIC32MZ_ETH_ALGNERR_OFFSET 0x0160 /* Ethernet Controller Alignment Errors Statistics Register */ +#define PIC32MZ_ETH_ALGNERRCLR_OFFSET 0x0164 +#define PIC32MZ_ETH_ALGNERRSET_OFFSET 0x0168 +#define PIC32MZ_ETH_ALGNERRINV_OFFSET 0x016c + +/* MAC Configuration Registers */ + +#define PIC32MZ_EMAC1_CFG1_OFFSET 0x0200 /* Ethernet Controller MAC Configuration 1 Register */ +#define PIC32MZ_EMAC1_CFG1CLR_OFFSET 0x0204 +#define PIC32MZ_EMAC1_CFG1SET_OFFSET 0x0208 +#define PIC32MZ_EMAC1_CFG1INV_OFFSET 0x020c + +#define PIC32MZ_EMAC1_CFG2_OFFSET 0x0210 /* Ethernet Controller MAC Configuration 2 Register */ +#define PIC32MZ_EMAC1_CFG2CLR_OFFSET 0x0214 +#define PIC32MZ_EMAC1_CFG2SET_OFFSET 0x0218 +#define PIC32MZ_EMAC1_CFG2INV_OFFSET 0x021c + +#define PIC32MZ_EMAC1_IPGT_OFFSET 0x0220 /* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ +#define PIC32MZ_EMAC1_IPGTCLR_OFFSET 0x0224 +#define PIC32MZ_EMAC1_IPGTSET_OFFSET 0x0228 +#define PIC32MZ_EMAC1_IPGTINV_OFFSET 0x022c + +#define PIC32MZ_EMAC1_IPGR_OFFSET 0x0230 /* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ +#define PIC32MZ_EMAC1_IPGRCLR_OFFSET 0x0234 +#define PIC32MZ_EMAC1_IPGRSET_OFFSET 0x0238 +#define PIC32MZ_EMAC1_IPGRINV_OFFSET 0x023c + +#define PIC32MZ_EMAC1_CLRT_OFFSET 0x0240 /* Ethernet Controller MAC Collision Window/Retry Limit Register */ +#define PIC32MZ_EMAC1_CLRTCLR_OFFSET 0x0244 +#define PIC32MZ_EMAC1_CLRTSET_OFFSET 0x0248 +#define PIC32MZ_EMAC1_CLRTINV_OFFSET 0x024c + +#define PIC32MZ_EMAC1_MAXF_OFFSET 0x0250 /* Ethernet Controller MAC Maximum Frame Length Register */ +#define PIC32MZ_EMAC1_MAXFCLR_OFFSET 0x0254 +#define PIC32MZ_EMAC1_MAXFSET_OFFSET 0x0258 +#define PIC32MZ_EMAC1_MAXFINV_OFFSET 0x025c + +#define PIC32MZ_EMAC1_SUPP_OFFSET 0x0260 /* Ethernet Controller MAC PHY Support Register */ +#define PIC32MZ_EMAC1_SUPPCLR_OFFSET 0x0264 +#define PIC32MZ_EMAC1_SUPPSET_OFFSET 0x0268 +#define PIC32MZ_EMAC1_SUPPINV_OFFSET 0x026c + +#define PIC32MZ_EMAC1_TEST_OFFSET 0x0270 /* Ethernet Controller MAC Test Register */ +#define PIC32MZ_EMAC1_TESTCLR_OFFSET 0x0274 +#define PIC32MZ_EMAC1_TESTSET_OFFSET 0x0278 +#define PIC32MZ_EMAC1_TESTINV_OFFSET 0x027c + +#define PIC32MZ_EMAC1_SA0_OFFSET 0x0300 /* Ethernet Controller MAC Station Address 0 Register */ +#define PIC32MZ_EMAC1_SA0CLR_OFFSET 0x0304 +#define PIC32MZ_EMAC1_SA0SET_OFFSET 0x0308 +#define PIC32MZ_EMAC1_SA0INV_OFFSET 0x030c + +#define PIC32MZ_EMAC1_SA1_OFFSET 0x0310 /* Ethernet Controller MAC Station Address 1 Register */ +#define PIC32MZ_EMAC1_SA1CLR_OFFSET 0x0314 +#define PIC32MZ_EMAC1_SA1SET_OFFSET 0x0318 +#define PIC32MZ_EMAC1_SA1INV_OFFSET 0x031c + +#define PIC32MZ_EMAC1_SA2_OFFSET 0x0320 /* Ethernet Controller MAC Station Address 2 Register */ +#define PIC32MZ_EMAC1_SA2CLR_OFFSET 0x0324 +#define PIC32MZ_EMAC1_SA2SET_OFFSET 0x0328 +#define PIC32MZ_EMAC1_SA2INV_OFFSET 0x032c + +/* MII Management Registers */ + +#define PIC32MZ_EMAC1_MCFG_OFFSET 0x0280 /* Ethernet Controller MAC MII Management Configuration Register */ +#define PIC32MZ_EMAC1_MCFGCLR_OFFSET 0x0284 +#define PIC32MZ_EMAC1_MCFGSET_OFFSET 0x0288 +#define PIC32MZ_EMAC1_MCFGINV_OFFSET 0x028c + +#define PIC32MZ_EMAC1_MCMD_OFFSET 0x0290 /* Ethernet Controller MAC MII Management Command Register */ +#define PIC32MZ_EMAC1_MCMDCLR_OFFSET 0x0294 +#define PIC32MZ_EMAC1_MCMDSET_OFFSET 0x0298 +#define PIC32MZ_EMAC1_MCMDINV_OFFSET 0x029c + +#define PIC32MZ_EMAC1_MADR_OFFSET 0x02a0 /* Ethernet Controller MAC MII Management Address Register */ +#define PIC32MZ_EMAC1_MADRCLR_OFFSET 0x02a4 +#define PIC32MZ_EMAC1_MADRSET_OFFSET 0x02a8 +#define PIC32MZ_EMAC1_MADRINV_OFFSET 0x02ac + +#define PIC32MZ_EMAC1_MWTD_OFFSET 0x02b0 /* Ethernet Controller MAC MII Management Write Data Register */ +#define PIC32MZ_EMAC1_MWTDCLR_OFFSET 0x02b4 +#define PIC32MZ_EMAC1_MWTDSET_OFFSET 0x02b8 +#define PIC32MZ_EMAC1_MWTDINV_OFFSET 0x02bc + +#define PIC32MZ_EMAC1_MRDD_OFFSET 0x02c0 /* Ethernet Controller MAC MII Management Read Data Register */ +#define PIC32MZ_EMAC1_MRDDCLR_OFFSET 0x02c4 +#define PIC32MZ_EMAC1_MRDDSET_OFFSET 0x02c8 +#define PIC32MZ_EMAC1_MRDDINV_OFFSET 0x02cc + +#define PIC32MZ_EMAC1_MIND_OFFSET 0x02d0 /* Ethernet Controller MAC MII Management Indicators Register */ +#define PIC32MZ_EMAC1_MINDCLR_OFFSET 0x02d4 +#define PIC32MZ_EMAC1_MINDSET_OFFSET 0x02d8 +#define PIC32MZ_EMAC1_MINDINV_OFFSET 0x02dc + +/* Register Addresses *******************************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MZ_ETH_CON1 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON1_OFFSET) +#define PIC32MZ_ETH_CON1CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON1CLR_OFFSET) +#define PIC32MZ_ETH_CON1SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON1SET_OFFSET) +#define PIC32MZ_ETH_CON1INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON1INV_OFFSET) + +#define PIC32MZ_ETH_CON2 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON2_OFFSET) +#define PIC32MZ_ETH_CON2CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON2CLR_OFFSET) +#define PIC32MZ_ETH_CON2SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON2SET_OFFSET) +#define PIC32MZ_ETH_CON2INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_CON2INV_OFFSET) + +#define PIC32MZ_ETH_TXST (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_TXST_OFFSET) +#define PIC32MZ_ETH_TXSTCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_TXSTCLR_OFFSET) +#define PIC32MZ_ETH_TXSTSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_TXSTSET_OFFSET) +#define PIC32MZ_ETH_TXSTINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_TXSTINV_OFFSET) + +#define PIC32MZ_ETH_RXST (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXST_OFFSET) +#define PIC32MZ_ETH_RXSTCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXSTCLR_OFFSET) +#define PIC32MZ_ETH_RXSTSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXSTSET_OFFSET) +#define PIC32MZ_ETH_RXSTINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXSTINV_OFFSET) + +#define PIC32MZ_ETH_IEN (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IEN_OFFSET) +#define PIC32MZ_ETH_IENCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IENCLR_OFFSET) +#define PIC32MZ_ETH_IENSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IENSET_OFFSET) +#define PIC32MZ_ETH_IENINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IENINV_OFFSET) + +#define PIC32MZ_ETH_IRQ (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IRQ_OFFSET) +#define PIC32MZ_ETH_IRQCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IRQCLR_OFFSET) +#define PIC32MZ_ETH_IRQSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IRQSET_OFFSET) +#define PIC32MZ_ETH_IRQINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_IRQINV_OFFSET) + +#define PIC32MZ_ETH_STAT (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_STAT_OFFSET) + +/* RX Filtering Configuration Registers */ + +#define PIC32MZ_ETH_RXFC (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXFC_OFFSET) +#define PIC32MZ_ETH_RXFCCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXFCCLR_OFFSET) +#define PIC32MZ_ETH_RXFCSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXFCSET_OFFSET) +#define PIC32MZ_ETH_RXFCINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXFCINV_OFFSET) + +#define PIC32MZ_ETH_HT0 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT0_OFFSET) +#define PIC32MZ_ETH_HT0CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT0CLR_OFFSET) +#define PIC32MZ_ETH_HT0SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT0SET_OFFSET) +#define PIC32MZ_ETH_HT0INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT0INV_OFFSET) + +#define PIC32MZ_ETH_HT1 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT1_OFFSET) +#define PIC32MZ_ETH_HT1CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT1CLR_OFFSET) +#define PIC32MZ_ETH_HT1SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT1SET_OFFSET) +#define PIC32MZ_ETH_HT1INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_HT1INV_OFFSET) + +#define PIC32MZ_ETH_PMM0 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM0_OFFSET) +#define PIC32MZ_ETH_PMM0CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM0CLR_OFFSET) +#define PIC32MZ_ETH_PMM0SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM0SET_OFFSET) +#define PIC32MZ_ETH_PMM0INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM0INV_OFFSET) + +#define PIC32MZ_ETH_PMM1 (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM1_OFFSET) +#define PIC32MZ_ETH_PMM1CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM1CLR_OFFSET) +#define PIC32MZ_ETH_PMM1SET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM1SET_OFFSET) +#define PIC32MZ_ETH_PMM1INV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMM1INV_OFFSET) + +#define PIC32MZ_ETH_PMCS (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMCS_OFFSET) +#define PIC32MZ_ETH_PMCSCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMCSCLR_OFFSET) +#define PIC32MZ_ETH_PMCSSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMCSSET_OFFSET) +#define PIC32MZ_ETH_PMCSINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMCSINV_OFFSET) + +#define PIC32MZ_ETH_PMO (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMO_OFFSET) +#define PIC32MZ_ETH_PMOCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMOCLR_OFFSET) +#define PIC32MZ_ETH_PMOSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMOSET_OFFSET) +#define PIC32MZ_ETH_PMOINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_PMOINV_OFFSET) + +/* Flow Control Configuring Register */ + +#define PIC32MZ_ETH_RXWM (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXWM_OFFSET) +#define PIC32MZ_ETH_RXWMCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXWMCLR_OFFSET) +#define PIC32MZ_ETH_RXWMSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXWMSET_OFFSET) +#define PIC32MZ_ETH_RXWMINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXWMINV_OFFSET) + +/* Ethernet Statistics Registers */ + +#define PIC32MZ_ETH_RXOVFLOW (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXOVFLOW_OFFSET) +#define PIC32MZ_ETH_RXOVFLOWCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXOVFLOWCLR_OFFSET) +#define PIC32MZ_ETH_RXOVFLOWSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXOVFLOWSET_OFFSET) +#define PIC32MZ_ETH_RXOVFLOWINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_RXOVFLOWINV_OFFSET) + +#define PIC32MZ_ETH_FRMTXOK (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMTXOK_OFFSET) +#define PIC32MZ_ETH_FRMTXOKCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMTXOKCLR_OFFSET) +#define PIC32MZ_ETH_FRMTXOKSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMTXOKSET_OFFSET) +#define PIC32MZ_ETH_FRMTXOKINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMTXOKINV_OFFSET) + +#define PIC32MZ_ETH_SCOLFRM (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_SCOLFRM_OFFSET) +#define PIC32MZ_ETH_SCOLFRMCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_SCOLFRMCLR_OFFSET) +#define PIC32MZ_ETH_SCOLFRMSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_SCOLFRMSET_OFFSET) +#define PIC32MZ_ETH_SCOLFRMINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_SCOLFRMINV_OFFSET) + +#define PIC32MZ_ETH_MCOLFRM (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_MCOLFRM_OFFSET) +#define PIC32MZ_ETH_MCOLFRMCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_MCOLFRMCLR_OFFSET) +#define PIC32MZ_ETH_MCOLFRMSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_MCOLFRMSET_OFFSET) +#define PIC32MZ_ETH_MCOLFRMINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_MCOLFRMINV_OFFSET) + +#define PIC32MZ_ETH_FRMRXOK (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMRXOK_OFFSET) +#define PIC32MZ_ETH_FRMRXOKCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMRXOKCLR_OFFSET) +#define PIC32MZ_ETH_FRMRXOKSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMRXOKSET_OFFSET) +#define PIC32MZ_ETH_FRMRXOKINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FRMRXOKINV_OFFSET) + +#define PIC32MZ_ETH_FCSERR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FCSERR_OFFSET) +#define PIC32MZ_ETH_FCSERRCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FCSERRCLR_OFFSET) +#define PIC32MZ_ETH_FCSERRSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FCSERRSET_OFFSET) +#define PIC32MZ_ETH_FCSERRINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_FCSERRINV_OFFSET) + +#define PIC32MZ_ETH_ALGNERR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_ALGNERR_OFFSET) +#define PIC32MZ_ETH_ALGNERRCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_ALGNERRCLR_OFFSET) +#define PIC32MZ_ETH_ALGNERRSET (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_ALGNERRSET_OFFSET) +#define PIC32MZ_ETH_ALGNERRINV (PIC32MZ_ETH_K1BASE+PIC32MZ_ETH_ALGNERRINV_OFFSET) + +/* MAC Configuration Registers */ + +#define PIC32MZ_EMAC1_CFG1 (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG1_OFFSET) +#define PIC32MZ_EMAC1_CFG1CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG1CLR_OFFSET) +#define PIC32MZ_EMAC1_CFG1SET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG1SET_OFFSET) +#define PIC32MZ_EMAC1_CFG1INV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG1INV_OFFSET) + +#define PIC32MZ_EMAC1_CFG2 (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG2_OFFSET) +#define PIC32MZ_EMAC1_CFG2CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG2CLR_OFFSET) +#define PIC32MZ_EMAC1_CFG2SET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG2SET_OFFSET) +#define PIC32MZ_EMAC1_CFG2INV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CFG2INV_OFFSET) + +#define PIC32MZ_EMAC1_IPGT (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGT_OFFSET) +#define PIC32MZ_EMAC1_IPGTCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGTCLR_OFFSET) +#define PIC32MZ_EMAC1_IPGTSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGTSET_OFFSET) +#define PIC32MZ_EMAC1_IPGTINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGTINV_OFFSET) + +#define PIC32MZ_EMAC1_IPGR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGR_OFFSET) +#define PIC32MZ_EMAC1_IPGRCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGRCLR_OFFSET) +#define PIC32MZ_EMAC1_IPGRSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGRSET_OFFSET) +#define PIC32MZ_EMAC1_IPGRINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_IPGRINV_OFFSET) + +#define PIC32MZ_EMAC1_CLRT (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CLRT_OFFSET) +#define PIC32MZ_EMAC1_CLRTCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CLRTCLR_OFFSET) +#define PIC32MZ_EMAC1_CLRTSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CLRTSET_OFFSET) +#define PIC32MZ_EMAC1_CLRTINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_CLRTINV_OFFSET) + +#define PIC32MZ_EMAC1_MAXF (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MAXF_OFFSET) +#define PIC32MZ_EMAC1_MAXFCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MAXFCLR_OFFSET) +#define PIC32MZ_EMAC1_MAXFSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MAXFSET_OFFSET) +#define PIC32MZ_EMAC1_MAXFINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MAXFINV_OFFSET) + +#define PIC32MZ_EMAC1_SUPP (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SUPP_OFFSET) +#define PIC32MZ_EMAC1_SUPPCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SUPPCLR_OFFSET) +#define PIC32MZ_EMAC1_SUPPSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SUPPSET_OFFSET) +#define PIC32MZ_EMAC1_SUPPINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SUPPINV_OFFSET) + +#define PIC32MZ_EMAC1_TEST (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_TEST_OFFSET) +#define PIC32MZ_EMAC1_TESTCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_TESTCLR_OFFSET) +#define PIC32MZ_EMAC1_TESTSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_TESTSET_OFFSET) +#define PIC32MZ_EMAC1_TESTINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_TESTINV_OFFSET) + +#define PIC32MZ_EMAC1_SA0 (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA0_OFFSET) +#define PIC32MZ_EMAC1_SA0CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA0CLR_OFFSET) +#define PIC32MZ_EMAC1_SA0SET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA0SET_OFFSET) +#define PIC32MZ_EMAC1_SA0INV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA0INV_OFFSET) + +#define PIC32MZ_EMAC1_SA1 (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA1_OFFSET) +#define PIC32MZ_EMAC1_SA1CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA1CLR_OFFSET) +#define PIC32MZ_EMAC1_SA1SET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA1SET_OFFSET) +#define PIC32MZ_EMAC1_SA1INV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA1INV_OFFSET) + +#define PIC32MZ_EMAC1_SA2 (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA2_OFFSET) +#define PIC32MZ_EMAC1_SA2CLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA2CLR_OFFSET) +#define PIC32MZ_EMAC1_SA2SET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA2SET_OFFSET) +#define PIC32MZ_EMAC1_SA2INV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_SA2INV_OFFSET) + +/* MII Management Registers */ + +#define PIC32MZ_EMAC1_MCFG (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCFG_OFFSET) +#define PIC32MZ_EMAC1_MCFGCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCFGCLR_OFFSET) +#define PIC32MZ_EMAC1_MCFGSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCFGSET_OFFSET) +#define PIC32MZ_EMAC1_MCFGINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCFGINV_OFFSET) + +#define PIC32MZ_EMAC1_MCMD (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCMD_OFFSET) +#define PIC32MZ_EMAC1_MCMDCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCMDCLR_OFFSET) +#define PIC32MZ_EMAC1_MCMDSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCMDSET_OFFSET) +#define PIC32MZ_EMAC1_MCMDINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MCMDINV_OFFSET) + +#define PIC32MZ_EMAC1_MADR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MADR_OFFSET) +#define PIC32MZ_EMAC1_MADRCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MADRCLR_OFFSET) +#define PIC32MZ_EMAC1_MADRSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MADRSET_OFFSET) +#define PIC32MZ_EMAC1_MADRINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MADRINV_OFFSET) + +#define PIC32MZ_EMAC1_MWTD (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MWTD_OFFSET) +#define PIC32MZ_EMAC1_MWTDCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MWTDCLR_OFFSET) +#define PIC32MZ_EMAC1_MWTDSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MWTDSET_OFFSET) +#define PIC32MZ_EMAC1_MWTDINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MWTDINV_OFFSET) + +#define PIC32MZ_EMAC1_MRDD (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MRDD_OFFSET) +#define PIC32MZ_EMAC1_MRDDCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MRDDCLR_OFFSET) +#define PIC32MZ_EMAC1_MRDDSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MRDDSET_OFFSET) +#define PIC32MZ_EMAC1_MRDDINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MRDDINV_OFFSET) + +#define PIC32MZ_EMAC1_MIND (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MIND_OFFSET) +#define PIC32MZ_EMAC1_MINDCLR (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MINDCLR_OFFSET) +#define PIC32MZ_EMAC1_MINDSET (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MINDSET_OFFSET) +#define PIC32MZ_EMAC1_MINDINV (PIC32MZ_ETH_K1BASE+PIC32MZ_EMAC1_MINDINV_OFFSET) + +/* Register Bit-Field Definitions *******************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ +/* Ethernet Controller Control 1 Register */ + +#define ETH_CON1_BUFCDEC (1 << 0) /* Bit 0: : Descriptor Buffer Count Decrement bit */ + /* Bit 1-3: Reserved */ +#define ETH_CON1_MANFC (1 << 4) /* Bit 4: Manual Flow Control bit */ + /* Bit 5-6: Reserved */ +#define ETH_CON1_AUTOFC (1 << 7) /* Bit 7: Automatic Flow Control bit */ +#define ETH_CON1_RXEN (1 << 8) /* Bit 8: Receive Enable bit */ +#define ETH_CON1_TXRTS (1 << 9) /* Bit 9: Transmit Request to Send bit */ + /* Bit 10-12: Reserved */ +#define ETH_CON1_SIDL (1 << 13) /* Bit 13: Ethernet Stop in Idle Mode bit */ + /* Bit 14: Reserved */ +#define ETH_CON1_ON (1 << 15) /* Bit 15: Ethernet ON bit */ +#define ETH_CON1_PTV_SHIFT (16) /* Bits 16-31: PAUSE Timer Value bits */ +#define ETH_CON1_PTV_MASK (0xffff << ETH_CON1_PTV_SHIFT) + +/* Ethernet Controller Control 2 Register */ + /* Bits 0-3: Reserved */ +#define ETH_CON2_RXBUFSZ_SHIFT (4) /* Bits 4-10: RX Data Buffer Size for All RX Descriptors */ +#define ETH_CON2_RXBUFSZ_MASK (0x7f << ETH_CON2_RXBUFSZ_SHIFT) +# define ETH_CON2_RXBUFSZ(n) (((n) >> 4) << ETH_CON2_RXBUFSZ_SHIFT) /* n=16, 32, 48, ... 2032 */ + /* Bits 11-31: Reserved */ + +/* Ethernet Controller TX Packet Descriptor Start Address Register (32-bit address) */ +/* Ethernet Controller RX Packet Descriptor Start Address Register (32-bit address) */ + +/* Ethernet Controller Interrupt Enable Register */ +/* Ethernet Controller Interrupt Request Register */ + +#define ETH_INT_RXOVFLW (1 << 0) /* Bit 0: Receive FIFO overflow interrupt */ +#define ETH_INT_RXBUFNA (1 << 1) /* Bit 1: Receive buffer not available interrupt */ +#define ETH_INT_TXABORT (1 << 2) /* Bit 2: Transmitter abort interrupt */ +#define ETH_INT_TXDONE (1 << 3) /* Bit 3: Transmitter done interrupt */ + /* Bit 4: Reserved */ +#define ETH_INT_RXACT (1 << 5) /* Bit 5: RX activity interrupt */ +#define ETH_INT_PKTPEND (1 << 6) /* Bit 6: Packet pending interrupt */ +#define ETH_INT_RXDONE (1 << 7) /* Bit 7: Receiver done interrupt */ +#define ETH_INT_FWMARK (1 << 8) /* Bit 8: Full watermark interrupt */ +#define ETH_INT_EWMARK (1 << 9) /* Bit 9: Empty watermark interrupt */ + /* Bits 10-12: Reserved */ +#define ETH_INT_RXBUSE (1 << 13) /* Bit 13: Receive BVCI bus error interrupt */ +#define ETH_INT_TXBUSE (1 << 14) /* Bit 14: Transmit BVCI bus error interrupt */ + /* Bits 15-31: Reserved */ +#define ETH_INT_ALLINTS (0x000063ef) + +/* Ethernet Controller Status Register */ + + /* Bits 0-4: Reserved */ +#define ETH_STAT_RXBUSY (1 << 5) /* Bit 5: Receive busy */ +#define ETH_STAT_TXBUSY (1 << 6) /* Bit 6: Transmit busy */ +#define ETH_STAT_ETHBUSY (1 << 7) /* Bit 7: Ethernet module busy */ + /* Bits 8-15: Reserved */ +#define ETH_STAT_BUFCNT_SHIFT (18) /* Bits 16-23: Packet buffer count */ +#define ETH_STAT_BUFCNT_MASK (0xff << ETH_STAT_BUFCNT_SHIFT) + /* Bits 24-31: Reserved */ + +/* RX Filtering Configuration Registers */ +/* Ethernet Controller Receive Filter Configuration Register */ + +#define ETH_RXFC_BCEN (1 << 0) /* Bit 0: Broadcast filter enable */ +#define ETH_RXFC_MCEN (1 << 1) /* Bit 1: Multicast filter enable */ +#define ETH_RXFC_NOTMEEN (1 << 2) /* Bit 2: Not Me unicast filter enable */ +#define ETH_RXFC_UCEN (1 << 3) /* Bit 3: Unicast filter enable */ +#define ETH_RXFC_RUNTEN (1 << 4) /* Bit 4: Runt enable */ +#define ETH_RXFC_RUNTERREN (1 << 5) /* Bit 5: Runt error collection enable */ +#define ETH_RXFC_CRCOKEN (1 << 6) /* Bit 6: CRC OK enable enable */ +#define ETH_RXFC_CRCERREN (1 << 7) /* Bit 7: CRC error collection enable */ +#define ETH_RXFC_PMMODE_SHIFT (8) /* Bits 8-11: Pattern match mode */ +#define ETH_RXFC_PMMODE_MASK (15 << ETH_RXFC_PMMODE_SHIFT) +# define ETH_RXFC_PMMODE_DISABLED (0 << ETH_RXFC_PMMODE_SHIFT) /* Pattern match is always unsuccessful */ +# define ETH_RXFC_PMMODE_PMCKSUM (1 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches */ +# define ETH_RXFC_PMMODE_DASTA (2 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==STA */ +/* #define ETH_RXFC_PMMODE_DASTA (3 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==STA */ +# define ETH_RXFC_PMMODE_DAUCAST (4 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==Unicast address */ +/* #define ETH_RXFC_PMMODE_DAUCAST (5 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==Unicast address */ +# define ETH_RXFC_PMMODE_DABCAST (6 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & DA==Broadcast address */ +/* #define ETH_RXFC_PMMODE_DABCAST (7 << ETH_RXFC_PMMODE_SHIFT) PM checksum matches & DA==Broadcast address */ +# define ETH_RXFC_PMMODE_HASH (8 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & Hash Table Filter match */ +# define ETH_RXFC_PMMODE_MAGIC (9 << ETH_RXFC_PMMODE_SHIFT) /* PM checksum matches & Packet = Magic Packet */ +#define ETH_RXFC_NOTPM (1 << 12) /* Bit 12: Pattern match inversion */ + /* Bit 13: Reserved */ +#define ETH_RXFC_MPEN (1 << 14) /* Bit 14: Magic packet enable */ +#define ETH_RXFC_HTEN (1 << 15) /* Bit 15: Hash table filtering enable */ + /* Bits 16-31: Reserved */ +/* Ethernet Controller Hash Table 0 Register */ + +#define ETH_HT0_BYTE0_SHIFT (0) /* Bits 0-7: Hash table byte 0, HT[0-7] */ +#define ETH_HT0_BYTE0_MASK (0xff << ETH_HT0_BYTE0_SHIFT) +#define ETH_HT0_BYTE1_SHIFT (8) /* Bits 8-15: Hash table byte 1, HT[8-15] */ +#define ETH_HT0_BYTE1_MASK (0xff << ETH_HT0_BYTE1_SHIFT) +#define ETH_HT0_BYTE2_SHIFT (16) /* Bits 16-23: Hash table byte 2, HT[16-23] */ +#define ETH_HT0_BYTE2_MASK (0xff << ETH_HT0_BYTE2_SHIFT) +#define ETH_HT0_BYTE3_SHIFT (24) /* Bits 24-31: Hash table byte 3, HT[24-31] */ +#define ETH_HT0_BYTE3_MASK (0xff << ETH_HT0_BYTE3_SHIFT) + +/* Ethernet Controller Hash Table 1 Register */ + +#define ETH_HT1_BYTE4_SHIFT (0) /* Bits 0-7: Hash table byte 4, HT[32-39] */ +#define ETH_HT1_BYTE4_MASK (0xff << ETH_HT1_BYTE4_SHIFT) +#define ETH_HT1_BYTE5_SHIFT (8) /* Bits 8-15: Hash table byte 5, HT[40-47] */ +#define ETH_HT1_BYTE5_MASK (0xff << ETH_HT1_BYTE5_SHIFT) +#define ETH_HT1_BYTE6_SHIFT (16) /* Bits 16-23: Hash table byte 6, HT[48-55] */ +#define ETH_HT1_BYTE6_MASK (0xff << ETH_HT1_BYTE6_SHIFT) +#define ETH_HT1_BYTE7_SHIFT (24) /* Bits 24-31: Hash table byte 7, HT[56-63] */ +#define ETH_HT1_BYTE7_MASK (0xff << ETH_HT1_BYTE7_SHIFT) + +/* Ethernet Controller Pattern Match Mask 0 Register */ + +#define ETH_PMM0_MASK0_SHIFT (0) /* Bits 0-7: Patch mask 0, PMM[0-7] */ +#define ETH_PMM0_MASK0_MASK (0xff << ETH_PMM0_MASK0_SHIFT) +#define ETH_PMM0_MASK1_SHIFT (8) /* Bits 8-15: Patch mask 1, PMM[8-15] */ +#define ETH_PMM0_MASK1_MASK (0xff << ETH_PMM0_MASK1_SHIFT) +#define ETH_PMM0_MASK2_SHIFT (16) /* Bits 16-23: Patch mask 2, PMM[16-23] */ +#define ETH_PMM0_MASK2_MASK (0xff << ETH_PMM0_MASK2_SHIFT) +#define ETH_PMM0_MASK3_SHIFT (24) /* Bits 24-31: Patch mask 3, PMM[24-31] */ +#define ETH_PMM0_MASK3_MASK (0xff << ETH_PMM0_MASK3_SHIFT) + +/* Ethernet Controller Pattern Match Mask 1 Register */ + +#define ETH_PMM1_MASK4_SHIFT (0) /* Bits 0-7: Patch mask 4, PMM[32-39] */ +#define ETH_PMM1_MASK4_MASK (0xff << ETH_PMM1_MASK4_SHIFT) +#define ETH_PMM1_MASK5_SHIFT (8) /* Bits 8-15: Patch mask 5, PMM[40-47] */ +#define ETH_PMM1_MASK5_MASK (0xff << ETH_PMM1_MASK5_SHIFT) +#define ETH_PMM1_MASK6_SHIFT (16) /* Bits 16-23: Patch mask 6, PMM[48-55] */ +#define ETH_PMM1_MASK6_MASK (0xff << ETH_PMM1_MASK6_SHIFT) +#define ETH_PMM1_MASK7_SHIFT (24) /* Bits 24-31: Patch mask 7, PMM[56-63] */ +#define ETH_PMM1_MASK7_MASK (0xff << ETH_PMM1_MASK7_SHIFT) + +/* Ethernet Controller Pattern Match Checksum Register */ + +#define ETH_PMCS_CKSM0_SHIFT (0) /* Bits 0-7: Pattern match checksum 0 bits, PMCS[0-7] */ +#define ETH_PMCS_CKSM0_MASK (0xff << ETH_PMCS_CKSM0_SHIFT) +#define ETH_PMCS_CKSM1_SHIFT (8) /* Bits 8-15: Pattern match checksum 1 bits, PMCS[8-15] */ +#define ETH_PMCS_CKSM1_MASK (0xff << ETH_PMCS_CKSM1_SHIFT) + +/* Ethernet Controller Pattern Match Offset Register */ + +#define ETH_PMO_MASK (0xffff) + +/* Flow Control Configuring Register */ +/* Ethernet Controller Receive Watermarks Register */ + +#define ETH_RXWM_RXEWM_SHIFT (0) /* Bits 0-7: Receive empty watermark bits */ +#define ETH_RXWM_RXEWM_MASK (0xff << ETH_RXWM_RXEWM_SHIFT) +#define ETH_RXWM_RXFWM_SHIFT (8) /* Bits 8-15: Receive full watermark bits */ +#define ETH_RXWM_RXFWM_MASK (0xff << ETH_RXWM_RXFWM_SHIFT) + +/* Ethernet Statistics Registers */ +/* Ethernet Controller Receive Overflow Statistics Register */ + +#define ETH_RXOVFLOW_MASK (0xffff) + +/* Ethernet Controller Frames Transmitted OK Statistics Register */ + +#define ETH_FRMTXOK_MASK (0xffff) + +/* Ethernet Controller Single Collision Frames Statistics Register */ + +#define ETH_SCOLFRM_MASK (0xffff) + +/* Ethernet Controller Multiple Collision Frames Statistics Register */ + +#define ETH_MCOLFRM_MASK (0xffff) + +/* Ethernet Controller Frames Received OK Statistics Register */ + +#define ETH_FRMRXOK_MASK (0xffff) + +/* Ethernet Controller Frame Check Sequence Error Statistics Register */ + +#define ETH_FCSERR_MASK (0xffff) + +/* Ethernet Controller Alignment Errors Statistics Register */ + +#define ETH_ALGNERR_MASK (0xffff) + +/* MAC Configuration Registers */ +/* Ethernet Controller MAC Configuration 1 Register */ + +#define EMAC1_CFG1_RXEN (1 << 0) /* Bit 0: MAC Receive enable */ +#define EMAC1_CFG1_PASSALL (1 << 1) /* Bit 1: MAC Pass all all receive frames */ +#define EMAC1_CFG1_RXPAUSE (1 << 2) /* Bit 2: MAC RX flow control bit */ +#define EMAC1_CFG1_TXPAUSE (1 << 3) /* Bit 3: MAC TX flow control */ +#define EMAC1_CFG1_LOOPBACK (1 << 4) /* Bit 4: MAC loopback mode */ + /* Bits 5-7: Reserved */ +#define EMAC1_CFG1_TXRST (1 << 8) /* Bit 8: Reset TX function */ +#define EMAC1_CFG1_MCSTXRST (1 << 9) /* Bit 9: Reset MCS/TX */ +#define EMAC1_CFG1_RXRST (1 << 10) /* Bit 10: Reset RX */ +#define EMAC1_CFG1_MCSRXRST (1 << 11) /* Bit 11: Reset MCS/RX */ + /* Bits 12-13: Reserved */ +#define EMAC1_CFG1_SIMRST (1 << 14) /* Bit 14: Simulation reset */ +#define EMAC1_CFG1_SOFTRST (1 << 15) /* Bit 15: Soft reset */ + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Configuration 2 Register */ + +#define EMAC1_CFG2_FULLDPLX (1 << 0) /* Bit 0: Full duplex operation */ +#define EMAC1_CFG2_LENGTHCK (1 << 1) /* Bit 1: Frame length checking */ +#define EMAC1_CFG2_HUGEFRM (1 << 2) /* Bit 2: Huge frame enable */ +#define EMAC1_CFG2_DELAYCRC (1 << 3) /* Bit 3: Delayed CRC */ +#define EMAC1_CFG2_CRCEN (1 << 4) /* Bit 4: CRC enable */ +#define EMAC1_CFG2_PADCRCEN (1 << 5) /* Bit 5: Pad/CRC enable */ +#define EMAC1_CFG2_VLANPADEN (1 << 6) /* Bit 6: VLAN pad enable */ +#define EMAC1_CFG2_AUTOPADEN (1 << 7) /* Bit 7: Auto detect pad enable */ +#define EMAC1_CFG2_PUREPRE (1 << 8) /* Bit 8: Pure preamble enforcement */ +#define EMAC1_CFG2_LONGPRE (1 << 9) /* Bit 9: Long preamble enforcement */ + /* Bits 10-11: Reserved */ +#define EMAC1_CFG2_NOBKOFF (1 << 12) /* Bit 12: No backoff */ +#define EMAC1_CFG2_BPNOBKOFF (1 << 13) /* Bit 13: Back pressure/no backoff */ +#define EMAC1_CFG2_EXCESSDFR (1 << 14) /* Bit 14: Excess defer */ + /* Bits 15-31: Reserved */ +/* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGT_SHIFT (0) /* Bits 0-6 */ +#define EMAC1_IPGT_MASK (0x7f << EMAC1_IPGT_SHIFT) + /* Bits 7-31: Reserved */ +/* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGR_GAP2_SHIFT (0) /* Bits 0-6: Gap part 2 */ +#define EMAC1_IPGR_GAP2_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bit 7: Reserved */ +#define EMAC1_IPGR_GAP1_SHIFT (8) /* Bits 8-18: Gap part 1 */ +#define EMAC1_IPGR_GAP1_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bits 15-31: Reserved */ +/* Ethernet Controller MAC Collision Window/Retry Limit Register */ + +#define EMAC1_CLRT_RETX_SHIFT (0) /* Bits 0-3: Retransmission maximum */ +#define EMAC1_CLRT_RETX_MASK (15 << EMAC1_CLRT_RETX_SHIFT) + /* Bits 4-7: Reserved */ +#define EMAC1_CLRT_CWINDOW_SHIFT (8) /* Bits 8-13: Collision window */ +#define EMAC1_CLRT_CWINDOW_MASK (0x3f << EMAC1_CLRT_CWINDOW_SHIFT) + /* Bits 14-31: Reserved */ +/* Ethernet Controller MAC Maximum Frame Length Register */ + +#define EMAC1_MAXF_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MAXF_MASK (0xffff << EMAC1_MAXF_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC PHY Support Register */ + /* Bits 0-7: Reserved */ +#define EMAC1_SUPP_SPEEDRMII (1 << 8) /* Bit 8: RMII Speed0=10Bps 1=100Bps */ + /* Bits 9-10: Reserved */ +#define EMAC1_SUPP_RESETRMII (1 << 11) /* Bit 11: Reset RMII Logic */ + /* Bits 12-31: Reserved */ +/* Ethernet Controller MAC Test Register */ + +#define EMAC1_TEST_SHRTQNTA (1 << 0) /* Bit 0: Shortcut pause quanta */ +#define EMAC1_TEST_TESTPAUSE (1 << 1) /* Bit 1: Test pause */ +#define EMAC1_TEST_TESTBP (1 << 2) /* Bit 2: Test packpressure */ + /* Bits 3-31: Reserved */ +/* Ethernet Controller MAC Station Address 0 Register */ + +#define EMAC1_SA0_STNADDR6_SHIFT (0) /* Bits 0-7: Station address 5th octet */ +#define EMAC1_SA0_STNADDR6_MASK (0xff << EMAC1_SA0_STNADDR6_SHIFT) +#define EMAC1_SA0_STNADDR5_SHIFT (8) /* Bits 8-15: Station address 6th octet */ +#define EMAC1_SA0_STNADDR5_MASK (0xff << EMAC1_SA0_STNADDR5_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 1 Register */ + +#define EMAC1_SA1_STNADDR4_SHIFT (0) /* Bits 0-7: Station address 4th octet */ +#define EMAC1_SA1_STNADDR4_MASK (0xff << EMAC1_SA0_STNADDR4_SHIFT) +#define EMAC1_SA1_STNADDR3_SHIFT (8) /* Bits 8-15: Station address 3rd octet */ +#define EMAC1_SA1_STNADDR3_MASK (0xff << EMAC1_SA0_STNADDR3_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 2 Register */ + +#define EMAC1_SA2_STNADDR2_SHIFT (0) /* Bits 0-7: Station address 2nd octet */ +#define EMAC1_SA2_STNADDR2_MASK (0xff << EMAC1_SA2_STNADDR2_SHIFT) +#define EMAC1_SA2_STNADDR1_SHIFT (8) /* Bits 8-15: Station address 1st octet */ +#define EMAC1_SA2_STNADDR1_MASK (0xff << EMAC1_SA2_STNADDR1_SHIFT) + /* Bits 16-31: Reserved */ +/* MII Management Registers */ + +/* Ethernet Controller MAC MII Management Configuration Register */ + +#define EMAC1_MCFG_SCANINC (1 << 0) /* Bit 0: Scan increment */ +#define EMAC1_MCFG_NOPRE (1 << 1) /* Bit 1: Suppress preamble */ +#define EMAC1_MCFG_CLKSEL_SHIFT (2) /* Bits 2-5: Clock select */ +#define EMAC1_MCFG_CLKSEL_MASK (15 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV4 (0 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 4 */ +# define EMAC1_MCFG_CLKSEL_DIV6 (2 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 6 */ +# define EMAC1_MCFG_CLKSEL_DIV8 (3 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 8 */ +# define EMAC1_MCFG_CLKSEL_DIV10 (4 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 10 */ +# define EMAC1_MCFG_CLKSEL_DIV14 (5 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 14 */ +# define EMAC1_MCFG_CLKSEL_DIV20 (6 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 20 */ +# define EMAC1_MCFG_CLKSEL_DIV28 (7 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 28 */ +# define EMAC1_MCFG_CLKSEL_DIV40 (8 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 40 */ +# define EMAC1_MCFG_CLKSEL_DIV48 (9 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 48 */ +# define EMAC1_MCFG_CLKSEL_DIV50 (10 << EMAC1_MCFG_CLKSEL_SHIFT) /* PBCLK5 divided by 50 */ + /* Bits 6-14: Reserved */ +#define EMAC1_MCFG_MGMTRST (1 << 15) /* Bit 15: Reset MII mgmt */ + /* Bits 16-31: Reserved */ + +/* Ethernet Controller MAC MII Management Command Register */ + +#define EMAC1_MCMD_READ (1 << 0) /* Bit 0: Single read cycle */ +#define EMAC1_MCMD_SCAN (1 << 1) /* Bit 1: Continuous read cycles */ + /* Bits 2-31: Reserved */ +#define EMAC1_MCMD_WRITE (0) + +/* Ethernet Controller MAC MII Management Address Register */ + +#define EMAC1_MADR_REGADDR_SHIFT (0) /* Bits 0-4: Register address */ +#define EMAC1_MADR_REGADDR_MASK (31 << EMAC1_MADR_REGADDR_SHIFT) + /* Bits 7-5: Reserved */ +#define EMAC1_MADR_PHYADDR_SHIFT (8) /* Bits 8-12: PHY address */ +#define EMAC1_MADR_PHYADDR_MASK (31 << EMAC1_MADR_PHYADDR_SHIFT) + /* Bits 13-31: Reserved */ +/* Ethernet Controller MAC MII Management Write Data Register */ + +#define EMAC1_MWTD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MWTD_MASK (0xffff << EMAC1_MWTD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Read Data Register */ + +#define EMAC1_MRDD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MRDD_MASK (0xffff << EMAC1_MRDD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Indicators Register */ + +#define EMAC1_MIND_MIIMBUSY (1 << 0) /* Bit 0: Busy */ +#define EMAC1_MIND_SCAN (1 << 1) /* Bit 1: Scanning */ +#define EMAC1_MIND_NOTVALID (1 << 2) /* Bit 2: Not valid */ +#define EMAC1_MIND_LINKFAIL (1 << 3) /* Bit 3: MII link fail */ + /* Bits 4-31: Reserved */ + +/* Descriptors Offsets ******************************************************************************/ + +/* Tx descriptor offsets. The NEXTED field is only present if NPV=1 */ + +#define PIC32MZ_TXDESC_STATUS 0x00 /* Various status bits (32-bits) */ +#define PIC32MZ_TXDESC_ADDRESS 0x04 /* Data buffer address (32-bits) */ +#define PIC32MZ_TXDESC_TSV1 0x08 /* Transmit filter status vector 1 (32-bits) */ +#define PIC32MZ_TXDESC_TSV2 0x0c /* Transmit filter status vector 2 (32-bits) */ +#define PIC32MZ_TXLINEAR_SIZE 0x10 /* Size in bytes of one linear Tx descriptor */ + +#define PIC32MZ_TXDESC_NEXTED 0x10 /* Next Ethernet Descriptor (ED) */ +#define PIC32MZ_TXLINKED_SIZE 0x14 /* Size in bytes of one linked Tx descriptor */ + +/* Tx descriptor uint32_t* indices */ + +#define TXDESC_STATUS 0 /* Various status bits (32-bits) */ +#define TXDESC_ADDRESS 1 /* Data buffer address (32-bits) */ +#define TXDESC_TSV1 2 /* Transmit filter status vector 1 (32-bits) */ +#define TXDESC_TSV2 3 /* Transmit filter status vector 2 (32-bits) */ +#define TXLINEAR_SIZE 4 /* Size in 32-bit words of one linear Tx descriptor */ + +#define TXDESC_NEXTED 4 /* Next Ethernet Descriptor (ED) */ +#define TXLINKED_SIZE 5 /* Size in 32-bit words of one linked Tx descriptor */ + +/* Rx descriptor offsets. The NEXTED field is only present if NPV=1 */ + +#define PIC32MZ_RXDESC_STATUS 0x00 /* Various status bits (32-bits) */ +#define PIC32MZ_RXDESC_ADDRESS 0x04 /* Data buffer address (32-bits) */ +#define PIC32MZ_RXDESC_RSV1 0x08 /* Receive filter status vector 1 and checksum (32-bits) */ +#define PIC32MZ_RXDESC_RSV2 0x0c /* Receive filter status vector 2 (32-bits) */ +#define PIC32MZ_RXLINEAR_SIZE 0x10 /* Size in bytes of one linear Rx descriptor */ + +#define PIC32MZ_RXDESC_NEXTED 0x10 /* Next Ethernet Descriptor (ED) */ +#define PIC32MZ_RXLINKED_SIZE 0x14 /* Size in bytes of one linked Rx descriptor */ + +/* Rx descriptor offsets uint32_t* indices */ + +#define RXDESC_STATUS 0 /* Various status bits (32-bits) */ +#define RXDESC_ADDRESS 1 /* Data buffer address (32-bits) */ +#define RXDESC_RSV1 2 /* Receive filter status vector 1 and checksum (32-bits) */ +#define RXDESC_RSV2 3 /* Receive filter status vector 2 (32-bits) */ +#define RXLINEAR_SIZE 4 /* Size in 32-bit words of one linear Rx descriptor */ + +#define RXDESC_NEXTED 4 /* Next Ethernet Descriptor (ED) */ +#define RXLINKED_SIZE 5 /* Size in 32-bit words of one linked Rx descriptor */ + +/* Descriptor Bit Definitions ***********************************************************************/ +/* Tx descriptor status bit definitions */ + /* Bits 0-6: Reserved */ +#define TXDESC_STATUS_EOWN (1 << 7) /* Bit 7: 1=Ethernet controller owns */ +#define TXDESC_STATUS_SOWN (0) /* 0=Software owns */ +#define TXDESC_STATUS_NPV (1 << 8) /* Bit 8: Next ED pointer valid enable */ +#define TXDESC_STATUS_USER1_SHIFT (9) /* Bits 9-15: User-defined */ +#define TXDESC_STATUS_USER1_MASK (0x7f << TXDESC_STATUS_USER2_SHIFT) +#define TXDESC_STATUS_BYTECOUNT_SHIFT (16) /* Bits 16-26: Byte Count */ +#define TXDESC_STATUS_BYTECOUNT_MASK (0x7ff << TXDESC_STATUS_BYTECOUNT_SHIFT) +#define TXDESC_STATUS_USER2_SHIFT (27) /* Bits 27-29: User-defined */ +#define TXDESC_STATUS_USER2_MASK (7 << TXDESC_STATUS_USER1_SHIFT) +#define TXDESC_STATUS_EOP (1 << 30) /* Bit 30: End of packet enable */ +#define TXDESC_STATUS_SOP (1 << 31) /* Bit 31: Start of packet enable */ + +/* Tx descriptor Transmit filter status vector bit definitions */ + +#define TXDESC_TSV1_BYTECOUNT_SHIFT (0) /* Bits 0-15: TSV[32-47] Total bytes transmitted */ +#define TXDESC_TSV1_BYTECOUNT_MASK (0xffff << TXDESC_TSV1_BYTECOUNT_SHIFT) +#define TXDESC_TSV1_CONTROL (1 << 16) /* Bit 16: TSV48 Transmit Control Frame */ +#define TXDESC_TSV1_PAUSE (1 << 17) /* Bit 17: TSV49 Transmit PAUSE Control Frame */ +#define TXDESC_TSV1_BPAPPLIED (1 << 18) /* Bit 18: TSV50 Transmit Backpressure Applied */ +#define TXDESC_TSV1_VLAN (1 << 19) /* Bit 19: TSV51 Transmit VLAN Tagged Frame */ + /* Bits 20-23: Reserved */ +#define TXDESC_TSV1_USER_SHIFT (24) /* Bits 24-31: User-defined */ +#define TXDESC_TSV1_USER_MASK (0xff << TXDESC_STATUS_USER1_SHIFT) + +#define TXDESC_TSV2_BYTECOUNT_SHIFT (0) /* Bits 0-15: TSV15:0 Transmit Byte Count */ +#define TXDESC_TSV2_BYTECOUNT_MASK (0xffff << TXDESC_TSV2_BYTECOUNT_SHIFT) +#define TXDESC_TSV2_COLCOUNT_SHIFT (0) /* Bits 16-19: TSV16-19 Transmit Collision Count */ +#define TXDESC_TSV2_COLCOUNT_MASK (15 << TXDESC_TSV2_COLCOUNT_SHIFT) +#define TXDESC_TSV2_TXCRCE (1 << 20) /* Bit 20: TSV20 Transmit CRC Error */ +#define TXDESC_TSV2_TXLCE (1 << 21) /* Bit 21: TSV21 Transmit Length Check Error */ +#define TXDESC_TSV2_TXOOR (1 << 22) /* Bit 22: TSV22 Transmit Length Out Of Range */ +#define TXDESC_TSV2_TXDONE (1 << 23) /* Bit 23: TSV23 Transmit Done */ +#define TXDESC_TSV2_MCAST (1 << 24) /* Bit 24: TSV24 Transmit Multicast */ +#define TXDESC_TSV2_BCAST (1 << 25) /* Bit 25: TSV25 Transmit Broadcast */ +#define TXDESC_TSV2_PKTDFR (1 << 26) /* Bit 26: TSV26 Transmit Packet Defer */ +#define TXDESC_TSV2_EXCESSDFR (1 << 27) /* Bit 27: TSV27 Transmit Excessive Defer */ +#define TXDESC_TSV2_MAXOL (1 << 28) /* Bit 28: TSV28 Transmit Maximum Collision */ +#define TXDESC_TSV2_TXLC (1 << 29) /* Bit 29: TSV29 Transmit Late Collision */ +#define TXDESC_TSV2_TXGIANT (1 << 30) /* Bit 30: TSV30 Transmit Giant */ +#define TXDESC_TSV2_TXUR (1 << 31) /* Bit 31: TSV31 Transmit Under-run */ + +/* Rx descriptor status bit definitions */ + /* Bits 0-6: Reserved */ +#define RXDESC_STATUS_EOWN (1 << 7) /* Bit 7: 1=Ethernet controller owns */ +#define RXDESC_STATUS_SOWN (0) /* 0=Software owns */ +#define RXDESC_STATUS_NPV (1 << 8) /* Bit 8: Next ED pointer valid enable */ + /* Bits 9-15: Reserved */ +#define RXDESC_STATUS_BYTECOUNT_SHIFT (16) /* Bits 16-26: Byte Count */ +#define RXDESC_STATUS_BYTECOUNT_MASK (0x7ff << RXDESC_STATUS_BYTECOUNT_SHIFT) + /* Bits 27-29: Reserved */ +#define RXDESC_STATUS_EOP (1 << 30) /* Bit 30: End of packet enable */ +#define RXDESC_STATUS_SOP (1 << 31) /* Bit 31: Start of packet enable */ + +/* Rx descriptor receive filter status vector bit definitions */ + +#define RXDESC_RSV1_CHECKSUM_SHIFT (0) /* Bits 0-15: RX Packet Payload Checksum */ +#define RXDESC_RSV1_CHECKSUM_MASK (0xffff << RXDESC_RSV1_CHECKSUM_SHIFT) +#define RXDESC_RSV1_USER_SHIFT (16) /* Bits 16-23: User defined */ +#define RXDESC_RSV1_USER_MASK (0xff << RXDESC_RSV1_USER_SHIFT) +#define RXDESC_RSV1_RUNT (1 << 24) /* Bit 24: RXF_RSV0 Runt packet */ +#define RXDESC_RSV1_NOTANDNOT (1 << 25) /* Bit 25: RXF_RSV1 NOT (Unicast match) AND NOT (Multicast Match) */ +#define RXDESC_RSV1_HTMATCH (1 << 26) /* Bit 26: RXF_RSV2 Hash Table match */ +#define RXDESC_RSV1_MAGIC (1 << 27) /* Bit 27: RXF_RSV3 Magic Packet match */ +#define RXDESC_RSV1_PATMATCH (1 << 28) /* Bit 28: RXF_RSV4 Pattern Match match */ +#define RXDESC_RSV1_UCASTMATCH (1 << 29) /* Bit 29: RXF_RSV5 Unicast match */ +#define RXDESC_RSV1_BCASTMATCH (1 << 30) /* Bit 30: RXF_RSV6 Broadcast match */ +#define RXDESC_RSV1_MCASTMATCH (1 << 31) /* Bit 31: RXF_RSV7 Multicast match */ + +#define RXDESC_RSV2_BYTECOUNT_SHIFT (0) /* Bits 0-15: RSV0-15 Received Byte Count */ +#define RXDESC_RSV2_BYTECOUNT_MASK (0xffff << RXDESC_RSV2_BYTECOUNT_SHIFT) +#define RXDESC_RSV2_LONGDROP (1 << 16) /* Bit 16: RSV16 Long Event/Drop Event */ +#define RXDESC_RSV2_RXDVSEEN (1 << 17) /* Bit 17: RSV17 RXDV Event Previously Seen */ +#define RXDESC_RSV2_CARSEEN (1 << 18) /* Bit 18: RSV18 Carrier Event Previously Seen */ +#define RXDESC_RSV2_CODE (1 << 19) /* Bit 19: RSV19 Receive Code Violation */ +#define RXDESC_RSV2_CRCERR (1 << 20) /* Bit 20: RSV20 CRC Error */ +#define RXDESC_RSV2_LENCHK (1 << 21) /* Bit 21: RSV21 Length Check Error */ +#define RXDESC_RSV2_OOR (1 << 22) /* Bit 22: RSV22 Length Out of Range */ +#define RXDESC_RSV2_OK (1 << 23) /* Bit 23: RSV23 Received Ok */ +#define RXDESC_RSV2_MCAST (1 << 24) /* Bit 24: RSV24 Receive Multicast Packet */ +#define RXDESC_RSV2_BCAST (1 << 25) /* Bit 25: RSV25 Receive Broadcast Packet */ +#define RXDESC_RSV2_DRIBBLE (1 << 26) /* Bit 26: RSV26 Dribble Nibble */ +#define RXDESC_RSV2_CONTROL (1 << 27) /* Bit 27: RSV27 Receive Control Frame */ +#define RXDESC_RSV2_PAUSE (1 << 28) /* Bit 28: RSV28 Receive Pause Control Frame */ +#define RXDESC_RSV2_UNKNOWNOP (1 << 29) /* Bit 29: RSV29 Receive Unknown Op code */ +#define RXDESC_RSV2_VLAN (1 << 30) /* Bit 30: RSV30 Receive VLAN Type Detected */ + /* Bit 31: RSV31 Reserved */ + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Descriptors as structures */ + +/* Tx descriptor with NPV=0 */ + +struct pic32mz_txlinear_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t tsv1; /* Transmit filter status vector 1 (32-bits) */ + uint32_t tsv2; /* Transmit filter status vector 2 (32-bits) */ +}; + +/* Tx descriptor with NPV=1 */ + +struct pic32mz_txdesc_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t tsv1; /* Transmit filter status vector 1 (32-bits) */ + uint32_t tsv2; /* Transmit filter status vector 2 (32-bits) */ + uint32_t nexted; /* Next Ethernet Descriptor (ED) */ +}; + +/* Rx descriptor with NPV=0 */ + +struct pic32mz_rxlinear_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t rsv1; /* Receive filter status vector 1 and checksum (32-bits) */ + uint32_t rsv2; /* Receive filter status vector 2 (32-bits) */ +}; + +/* Rx descriptor with NPV=1 */ + +struct pic32mz_rxdesc_s +{ + uint32_t status; /* Various status bits (32-bits) */ + uint32_t address; /* Data buffer address (32-bits) */ + uint32_t rsv1; /* Receive filter status vector 1 and checksum (32-bits) */ + uint32_t rsv2; /* Receive filter status vector 2 (32-bits) */ + uint32_t nexted; /* Next Ethernet Descriptor (ED) */ +}; + +/**************************************************************************************************** + * Inline Functions + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NETHERNET > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_ETHERNET_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-features.h b/arch/mips/src/pic32mz/chip/pic32mz-features.h new file mode 100644 index 0000000000000000000000000000000000000000..4bc21f258338662764f33663891f76abb083f3a9 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-features.h @@ -0,0 +1,51 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/chip/pic32mz-features.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_FEATURES_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_FEATURES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_PIC32MZEC) +# include +#else +# error Unknown PIC32MZ family +#endif + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_FEATURES_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-i2c.h b/arch/mips/src/pic32mz/chip/pic32mz-i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..aaa4621de20e73bcd84401248cc76f5dfecf0650 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-i2c.h @@ -0,0 +1,376 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-i2c.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_I2C_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip/pic32mz-memorymap.h" + +#if CHIP_NI2C > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* I2C Peripheral Offsets ***********************************************************/ + +#define PIC32MZ_I2Cn_OFFSET(n) ((n) << 9) +# define PIC32MZ_I2C1_OFFSET 0x0000 +# define PIC32MZ_I2C2_OFFSET 0x0200 +# define PIC32MZ_I2C3_OFFSET 0x0400 +# define PIC32MZ_I2C4_OFFSET 0x0600 +# define PIC32MZ_I2C5_OFFSET 0x0800 +# +/* I2C Register Offsets *************************************************************/ + +#define PIC32MZ_I2C_CON_OFFSET 0x0000 /* I2C control register */ +#define PIC32MZ_I2C_CONCLR_OFFSET 0x0004 /* I2C control clear register */ +#define PIC32MZ_I2C_CONSET_OFFSET 0x0008 /* I2C control set register */ +#define PIC32MZ_I2C_CONINV_OFFSET 0x000c /* I2C control invert register */ + +#define PIC32MZ_I2C_STAT_OFFSET 0x0010 /* I2C status register */ +#define PIC32MZ_I2C_STATCLR_OFFSET 0x0014 /* I2C status clear register */ +#define PIC32MZ_I2C_STATSET_OFFSET 0x0018 /* I2C status set register */ +#define PIC32MZ_I2C_STATINV_OFFSET 0x001c /* I2C status invert register */ + +#define PIC32MZ_I2C_ADD_OFFSET 0x0020 /* I2C address register */ +#define PIC32MZ_I2C_ADDCLR_OFFSET 0x0024 /* I2C address clear register */ +#define PIC32MZ_I2C_ADDSET_OFFSET 0x0028 /* I2C address set register */ +#define PIC32MZ_I2C_ADDINV_OFFSET 0x002c /* I2C address invert register */ + +#define PIC32MZ_I2C_MSK_OFFSET 0x0030 /* I2C address mask register */ +#define PIC32MZ_I2C_MSKCLR_OFFSET 0x0034 /* I2C address mask clear register */ +#define PIC32MZ_I2C_MSKSET_OFFSET 0x0038 /* I2C address mask set register */ +#define PIC32MZ_I2C_MSKINV_OFFSET 0x003c /* I2C address mask invert register */ + +#define PIC32MZ_I2C_BRG_OFFSET 0x0040 /* Baud rate generator reload register */ +#define PIC32MZ_I2C_BRGCLR_OFFSET 0x0044 /* Baud rate generator reload set register */ +#define PIC32MZ_I2C_BRGSET_OFFSET 0x0048 /* Baud rate generator reload clear register */ +#define PIC32MZ_I2C_BRGINV_OFFSET 0x004c /* Baud rate generator reload invert register */ + +#define PIC32MZ_I2C_TRN_OFFSET 0x0050 /* I2C transmit register */ +#define PIC32MZ_I2C_TRNCLR_OFFSET 0x0054 /* I2C transmit clear register */ +#define PIC32MZ_I2C_TRNSET_OFFSET 0x0058 /* I2C transmit set register */ +#define PIC32MZ_I2C_TRNINV_OFFSET 0x005c /* I2C transmit invert register */ + +#define PIC32MZ_I2C_RCV_OFFSET 0x0060 /* I2C receive buffer register */ + +/* I2C Peripheral Addresses *********************************************************/ + +#define PIC32MZ_I2Cn_K1BASE(n) (PIC32MZ_I2C_K1BASE+ +PIC32MZ_I2Cn_OFFSET(n)) +# define PIC32MZ_I2C1_K1BASE (PIC32MZ_I2C_K1BASE+ +PIC32MZ_I2C1_OFFSET) +# define PIC32MZ_I2C2_K1BASE (PIC32MZ_I2C_K1BASE+ +PIC32MZ_I2C2_OFFSET) +# define PIC32MZ_I2C3_K1BASE (PIC32MZ_I2C_K1BASE+ +PIC32MZ_I2C3_OFFSET) +# define PIC32MZ_I2C4_K1BASE (PIC32MZ_I2C_K1BASE+ +PIC32MZ_I2C4_OFFSET 0x0600 +# define PIC32MZ_I2C5_K1BASE) +PIC32MZ_I2C5_OFFSET 0x0800 + +/* I2C Register Addresses ***********************************************************/ + +#define PIC32MZ_I2C1_CON (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_CON_OFFSET) +#define PIC32MZ_I2C1_CONCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_CONCLR_OFFSET) +#define PIC32MZ_I2C1_CONSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_CONSET_OFFSET) +#define PIC32MZ_I2C1_CONINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_CONINV_OFFSET) + +#define PIC32MZ_I2C1_STAT (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_STAT_OFFSET) +#define PIC32MZ_I2C1_STATCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_STATCLR_OFFSET) +#define PIC32MZ_I2C1_STATSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_STATSET_OFFSET) +#define PIC32MZ_I2C1_STATINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_STATINV_OFFSET) + +#define PIC32MZ_I2C1_ADD (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_ADD_OFFSET) +#define PIC32MZ_I2C1_ADDCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_ADDCLR_OFFSET) +#define PIC32MZ_I2C1_ADDSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_ADDSET_OFFSET) +#define PIC32MZ_I2C1_ADDINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_ADDINV_OFFSET) + +#define PIC32MZ_I2C1_MSK (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_MSK_OFFSET) +#define PIC32MZ_I2C1_MSKCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_MSKCLR_OFFSET) +#define PIC32MZ_I2C1_MSKSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_MSKSET_OFFSET) +#define PIC32MZ_I2C1_MSKINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_MSKINV_OFFSET) + +#define PIC32MZ_I2C1_BRG (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_BRG_OFFSET) +#define PIC32MZ_I2C1_BRGSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_BRGSET_OFFSET) +#define PIC32MZ_I2C1_BRGCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_BRGCLR_OFFSET) +#define PIC32MZ_I2C1_BRGINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_BRGINV_OFFSET) + +#define PIC32MZ_I2C1_TRN (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_TRN_OFFSET) +#define PIC32MZ_I2C1_TRNCLR (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_TRNCLR_OFFSET) +#define PIC32MZ_I2C1_TRNSET (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_TRNSET_OFFSET) +#define PIC32MZ_I2C1_TRNINV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_TRNINV_OFFSET) + +#define PIC32MZ_I2C1_RCV (PIC32MZ_I2C1_K1BASE+PIC32MZ_I2C_RCV_OFFSET) + +#if CHIP_NI2C > 1 +# define PIC32MZ_I2C2_CON (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_CON_OFFSET) +# define PIC32MZ_I2C2_CONCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_CONCLR_OFFSET) +# define PIC32MZ_I2C2_CONSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_CONSET_OFFSET) +# define PIC32MZ_I2C2_CONINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_CONINV_OFFSET) + +# define PIC32MZ_I2C2_STAT (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_STAT_OFFSET) +# define PIC32MZ_I2C2_STATCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_STATCLR_OFFSET) +# define PIC32MZ_I2C2_STATSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_STATSET_OFFSET) +# define PIC32MZ_I2C2_STATINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_STATINV_OFFSET) + +# define PIC32MZ_I2C2_ADD (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_ADD_OFFSET) +# define PIC32MZ_I2C2_ADDCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_ADDCLR_OFFSET) +# define PIC32MZ_I2C2_ADDSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_ADDSET_OFFSET) +# define PIC32MZ_I2C2_ADDINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_ADDINV_OFFSET) + +# define PIC32MZ_I2C2_MSK (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_MSK_OFFSET) +# define PIC32MZ_I2C2_MSKCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_MSKCLR_OFFSET) +# define PIC32MZ_I2C2_MSKSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_MSKSET_OFFSET) +# define PIC32MZ_I2C2_MSKINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_MSKINV_OFFSET) + +# define PIC32MZ_I2C2_BRG (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_BRG_OFFSET) +# define PIC32MZ_I2C2_BRGSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_BRGSET_OFFSET) +# define PIC32MZ_I2C2_BRGCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_BRGCLR_OFFSET) +# define PIC32MZ_I2C2_BRGINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_BRGINV_OFFSET) + +# define PIC32MZ_I2C2_TRN (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_TRN_OFFSET) +# define PIC32MZ_I2C2_TRNCLR (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_TRNCLR_OFFSET) +# define PIC32MZ_I2C2_TRNSET (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_TRNSET_OFFSET) +# define PIC32MZ_I2C2_TRNINV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_TRNINV_OFFSET) + +# define PIC32MZ_I2C2_RCV (PIC32MZ_I2C2_K1BASE+PIC32MZ_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 2 +# define PIC32MZ_I2C3_CON (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_CON_OFFSET) +# define PIC32MZ_I2C3_CONCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_CONCLR_OFFSET) +# define PIC32MZ_I2C3_CONSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_CONSET_OFFSET) +# define PIC32MZ_I2C3_CONINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_CONINV_OFFSET) + +# define PIC32MZ_I2C3_STAT (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_STAT_OFFSET) +# define PIC32MZ_I2C3_STATCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_STATCLR_OFFSET) +# define PIC32MZ_I2C3_STATSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_STATSET_OFFSET) +# define PIC32MZ_I2C3_STATINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_STATINV_OFFSET) + +# define PIC32MZ_I2C3_ADD (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_ADD_OFFSET) +# define PIC32MZ_I2C3_ADDCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_ADDCLR_OFFSET) +# define PIC32MZ_I2C3_ADDSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_ADDSET_OFFSET) +# define PIC32MZ_I2C3_ADDINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_ADDINV_OFFSET) + +# define PIC32MZ_I2C3_MSK (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_MSK_OFFSET) +# define PIC32MZ_I2C3_MSKCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_MSKCLR_OFFSET) +# define PIC32MZ_I2C3_MSKSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_MSKSET_OFFSET) +# define PIC32MZ_I2C3_MSKINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_MSKINV_OFFSET) + +# define PIC32MZ_I2C3_BRG (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_BRG_OFFSET) +# define PIC32MZ_I2C3_BRGSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_BRGSET_OFFSET) +# define PIC32MZ_I2C3_BRGCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_BRGCLR_OFFSET) +# define PIC32MZ_I2C3_BRGINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_BRGINV_OFFSET) + +# define PIC32MZ_I2C3_TRN (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_TRN_OFFSET) +# define PIC32MZ_I2C3_TRNCLR (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_TRNCLR_OFFSET) +# define PIC32MZ_I2C3_TRNSET (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_TRNSET_OFFSET) +# define PIC32MZ_I2C3_TRNINV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_TRNINV_OFFSET) + +# define PIC32MZ_I2C3_RCV (PIC32MZ_I2C3_K1BASE+PIC32MZ_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 3 +# define PIC32MZ_I2C4_CON (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_CON_OFFSET) +# define PIC32MZ_I2C4_CONCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_CONCLR_OFFSET) +# define PIC32MZ_I2C4_CONSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_CONSET_OFFSET) +# define PIC32MZ_I2C4_CONINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_CONINV_OFFSET) + +# define PIC32MZ_I2C4_STAT (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_STAT_OFFSET) +# define PIC32MZ_I2C4_STATCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_STATCLR_OFFSET) +# define PIC32MZ_I2C4_STATSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_STATSET_OFFSET) +# define PIC32MZ_I2C4_STATINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_STATINV_OFFSET) + +# define PIC32MZ_I2C4_ADD (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_ADD_OFFSET) +# define PIC32MZ_I2C4_ADDCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_ADDCLR_OFFSET) +# define PIC32MZ_I2C4_ADDSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_ADDSET_OFFSET) +# define PIC32MZ_I2C4_ADDINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_ADDINV_OFFSET) + +# define PIC32MZ_I2C4_MSK (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_MSK_OFFSET) +# define PIC32MZ_I2C4_MSKCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_MSKCLR_OFFSET) +# define PIC32MZ_I2C4_MSKSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_MSKSET_OFFSET) +# define PIC32MZ_I2C4_MSKINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_MSKINV_OFFSET) + +# define PIC32MZ_I2C4_BRG (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_BRG_OFFSET) +# define PIC32MZ_I2C4_BRGSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_BRGSET_OFFSET) +# define PIC32MZ_I2C4_BRGCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_BRGCLR_OFFSET) +# define PIC32MZ_I2C4_BRGINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_BRGINV_OFFSET) + +# define PIC32MZ_I2C4_TRN (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_TRN_OFFSET) +# define PIC32MZ_I2C4_TRNCLR (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_TRNCLR_OFFSET) +# define PIC32MZ_I2C4_TRNSET (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_TRNSET_OFFSET) +# define PIC32MZ_I2C4_TRNINV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_TRNINV_OFFSET) + +# define PIC32MZ_I2C4_RCV (PIC32MZ_I2C4_K1BASE+PIC32MZ_I2C_RCV_OFFSET) +#endif + +#if CHIP_NI2C > 4 +# define PIC32MZ_I2C5_CON (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_CON_OFFSET) +# define PIC32MZ_I2C5_CONCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_CONCLR_OFFSET) +# define PIC32MZ_I2C5_CONSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_CONSET_OFFSET) +# define PIC32MZ_I2C5_CONINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_CONINV_OFFSET) + +# define PIC32MZ_I2C5_STAT (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_STAT_OFFSET) +# define PIC32MZ_I2C5_STATCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_STATCLR_OFFSET) +# define PIC32MZ_I2C5_STATSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_STATSET_OFFSET) +# define PIC32MZ_I2C5_STATINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_STATINV_OFFSET) + +# define PIC32MZ_I2C5_ADD (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_ADD_OFFSET) +# define PIC32MZ_I2C5_ADDCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_ADDCLR_OFFSET) +# define PIC32MZ_I2C5_ADDSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_ADDSET_OFFSET) +# define PIC32MZ_I2C5_ADDINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_ADDINV_OFFSET) + +# define PIC32MZ_I2C5_MSK (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_MSK_OFFSET) +# define PIC32MZ_I2C5_MSKCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_MSKCLR_OFFSET) +# define PIC32MZ_I2C5_MSKSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_MSKSET_OFFSET) +# define PIC32MZ_I2C5_MSKINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_MSKINV_OFFSET) + +# define PIC32MZ_I2C5_BRG (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_BRG_OFFSET) +# define PIC32MZ_I2C5_BRGSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_BRGSET_OFFSET) +# define PIC32MZ_I2C5_BRGCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_BRGCLR_OFFSET) +# define PIC32MZ_I2C5_BRGINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_BRGINV_OFFSET) + +# define PIC32MZ_I2C5_TRN (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_TRN_OFFSET) +# define PIC32MZ_I2C5_TRNCLR (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_TRNCLR_OFFSET) +# define PIC32MZ_I2C5_TRNSET (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_TRNSET_OFFSET) +# define PIC32MZ_I2C5_TRNINV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_TRNINV_OFFSET) + +# define PIC32MZ_I2C5_RCV (PIC32MZ_I2C5_K1BASE+PIC32MZ_I2C_RCV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***************************************************/ + +/* I2C control register */ + +#define I2C_CON_SEN (1 << 0) /* Bit 0: Start condition enable (Master mode) */ +#define I2C_CON_RSEN (1 << 1) /* Bit 1: Restart condition enable (Master mode) */ +#define I2C_CON_PEN (1 << 2) /* Bit 2: Stop condition enable (Master mode) */ +#define I2C_CON_RCEN (1 << 3) /* Bit 3: Receive enable (Master mode) */ +#define I2C_CON_ACKEN (1 << 4) /* Bit 4: Acknowledge sequence enable (Master mode) */ +#define I2C_CON_ACKDT (1 << 5) /* Bit 5: Acknowledge data (Master mode) */ +#define I2C_CON_STREN (1 << 6) /* Bit 6: SCL clock stretch enable (Slave mode) */ +#define I2C_CON_GCEN (1 << 7) /* Bit 7: General call enable (Slave mode) */ +#define I2C_CON_SMEN (1 << 8) /* Bit 8: SMBus input levels disable */ +#define I2C_CON_DISSLW (1 << 9) /* Bit 9: Slew rate control disable */ +#define I2C_CON_A10M (1 << 10) /* Bit 10: 10-bit slave addrewss flag */ +#define I2C_CON_STRICT (1 << 11) /* Bit 11: Strict I2C reserved address rules enable (Slave mode) */ +#define I2C_CON_SCLREL (1 << 12) /* Bit 12: SCL release control */ +#define I2C_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ + /* Bit 14: Reserved */ +#define I2C_CON_ON (1 << 15) /* Bit 15: I2C enable */ +#define I2C_CON_DHEN (1 << 16) /* Bit 16: Data Hold Enable bit (Slave mode) */ +#define I2C_CON_AHEN (1 << 17) /* Bit 17: Address Hold Enable bit (Slave mode) */ +#define I2C_CON_SBCDE (1 << 18) /* Bit 18: Slave Mode Bus Collision Detect Enable (Slave mode) */ +#define I2C_CON_SDAHT (1 << 19) /* Bit 19: SDA Hold Time Selection bit */ +#define I2C_CON_BOEN (1 << 20) /* Bit 20: Buffer Overwrite Enable bit (I2C Slave mode only) */ +#define I2C_CON_SCIE (1 << 21) /* Bit 21: Start Condition Interrupt Enable (Slave mode) */ +#define I2C_CON_PCIE (1 << 22) /* Bit 22: Stop Condition Interrupt Enable (Slave mode) */ + /* Bits 23-31: Reserved */ + +/* I2C status register */ + +#define I2C_STAT_TBF (1 << 0) /* Bit 0: Transmit buffer full */ +#define I2C_STAT_RBF (1 << 1) /* Bit 1: Receive buffer full */ +#define I2C_STAT_RW (1 << 2) /* Bit 2: Read/write information (Slave mode) */ +#define I2C_STAT_S (1 << 3) /* Bit 3: Start */ +#define I2C_STAT_P (1 << 4) /* Bit 4: Stop */ +#define I2C_STAT_DA (1 << 5) /* Bit 5: Data/address (Slave mode) */ +#define I2C_STAT_I2COV (1 << 6) /* Bit 6: I2C overflow status */ +#define I2C_STAT_IWCOL (1 << 7) /* Bit 7: Write collision detect */ +#define I2C_STAT_ADD10 (1 << 8) /* Bit 8: 10-bit address status */ +#define I2C_STAT_GCSTAT (1 << 9) /* Bit 9: General call status */ +#define I2C_STAT_BCL (1 << 10) /* Bit 10: Master bus collision detect */ + /* Bits 11-12 */ +#define I2C_STAT_ACKTIM: (1 << 13) /* Bit 13: Acknowledge Time Status bit (Slave mode) */ +#define I2C_STAT_TRSTAT (1 << 14) /* Bit 14: Transmit status (Master mode) */ +#define I2C_STAT_ACKSTAT (1 << 15) /* Bit 15: Acknowledge status (Master mode) */ + +/* I2C address register */ + +#define I2C_ADD_MASK 0x000003ff /* 10-bit I2C address */ + +/* I2C address mask register */ + +#define I2C_MSK_MASK 0x000003ff /* 10-bit I2C address mask */ + +/* Baud rate generator reload register */ + +#define I2C_BRG_MASK 0x0000ffff /* 16-bit I2C BRG value */ + +/* I2C transmit register */ + +#define I2C_TRN_MASK 00000x00ff /* 8-bit transmit data */ + +/* I2C receive buffer register */ + +#define I2C_RCV_MASK 0x000000ff /* 8-bit receive data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_I2C_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-int.h b/arch/mips/src/pic32mz/chip/pic32mz-int.h new file mode 100644 index 0000000000000000000000000000000000000000..9c07b5f6baab7d385418ebbaa89bacfff4e986b8 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-int.h @@ -0,0 +1,1263 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-int.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_INT_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_INT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mz-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MZ_INT_INTCON_OFFSET 0x0000 /* Interrupt control register */ +#define PIC32MZ_INT_INTCONCLR_OFFSET 0x0004 /* Interrupt control clear register */ +#define PIC32MZ_INT_INTCONSET_OFFSET 0x0008 /* Interrupt control set register */ +#define PIC32MZ_INT_INTCONINV_OFFSET 0x000c /* Interrupt control invert register */ + +#define PIC32MZ_INT_PRISS_OFFSET 0x0010 /* Priority shadow select register */ +#define PIC32MZ_INT_PRISSCLR_OFFSET 0x0010 /* Priority shadow clear register */ +#define PIC32MZ_INT_PRISSSET_OFFSET 0x0010 /* Priority shadow set register */ +#define PIC32MZ_INT_PRISSINV_OFFSET 0x0010 /* Priority shadow invert register */ + +#define PIC32MZ_INT_INTSTAT_OFFSET 0x0020 /* Interrupt status register */ +#define PIC32MZ_INT_INTSTATCLR_OFFSET 0x0024 /* Interrupt status clear register */ +#define PIC32MZ_INT_INTSTATSET_OFFSET 0x0028 /* Interrupt status set register */ +#define PIC32MZ_INT_INTSTATINV_OFFSET 0x002c /* Interrupt status invert register */ + +#define PIC32MZ_INT_IPTMR_OFFSET 0x0030 /* Interrupt proximity timer register */ +#define PIC32MZ_INT_IPTMRCLR_OFFSET 0x0034 /* Interrupt proximity timer clear register */ +#define PIC32MZ_INT_IPTMRSET_OFFSET 0x0038 /* Interrupt proximity timer set register */ +#define PIC32MZ_INT_IPTMRINV_OFFSET 0x003c /* Interrupt proximity timer invert register */ + +#define PIC32MZ_INT_IFS_OFFSET(n) (0x0040 + ((n) << 4)) +#define PIC32MZ_INT_IFSCLR_OFFSET(n) (0x0044 + ((n) << 4)) +#define PIC32MZ_INT_IFSSET_OFFSET(n) (0x0048 + ((n) << 4)) +#define PIC32MZ_INT_IFSINV_OFFSET(n) (0x004c + ((n) << 4)) + +#define PIC32MZ_INT_IFS0_OFFSET 0x0040 /* Interrupt flag status register 0 */ +#define PIC32MZ_INT_IFS0CLR_OFFSET 0x0044 /* Interrupt flag status clear register 0 */ +#define PIC32MZ_INT_IFS0SET_OFFSET 0x0048 /* Interrupt flag status set register 0 */ +#define PIC32MZ_INT_IFS0INV_OFFSET 0x004c /* Interrupt flag status invert register 0 */ + +#define PIC32MZ_INT_IFS1_OFFSET 0x0050 /* Interrupt flag status register 1 */ +#define PIC32MZ_INT_IFS1CLR_OFFSET 0x0054 /* Interrupt flag status clear register 1 */ +#define PIC32MZ_INT_IFS1SET_OFFSET 0x0058 /* Interrupt flag status set register 1 */ +#define PIC32MZ_INT_IFS1INV_OFFSET 0x005c /* Interrupt flag status invert register 1 */ + +#define PIC32MZ_INT_IFS2_OFFSET 0x0060 /* Interrupt flag status register 2 */ +#define PIC32MZ_INT_IFS2CLR_OFFSET 0x0064 /* Interrupt flag status clear register 2 */ +#define PIC32MZ_INT_IFS2SET_OFFSET 0x0068 /* Interrupt flag status set register 2 */ +#define PIC32MZ_INT_IFS2INV_OFFSET 0x006c /* Interrupt flag status invert register 2 */ + +#define PIC32MZ_INT_IFS3_OFFSET 0x0070 /* Interrupt flag status register 3 */ +#define PIC32MZ_INT_IFS3CLR_OFFSET 0x0074 /* Interrupt flag status clear register 3 */ +#define PIC32MZ_INT_IFS3SET_OFFSET 0x0078 /* Interrupt flag status set register 3 */ +#define PIC32MZ_INT_IFS3INV_OFFSET 0x007c /* Interrupt flag status invert register 3 */ + +#define PIC32MZ_INT_IFS4_OFFSET 0x0080 /* Interrupt flag status register 4 */ +#define PIC32MZ_INT_IFS4CLR_OFFSET 0x0084 /* Interrupt flag status clear register 4 */ +#define PIC32MZ_INT_IFS4SET_OFFSET 0x0088 /* Interrupt flag status set register 4 */ +#define PIC32MZ_INT_IFS4INV_OFFSET 0x008c /* Interrupt flag status invert register 4 */ + +#define PIC32MZ_INT_IFS5_OFFSET 0x0090 /* Interrupt flag status register 5 */ +#define PIC32MZ_INT_IFS5CLR_OFFSET 0x0094 /* Interrupt flag status clear register 5 */ +#define PIC32MZ_INT_IFS5SET_OFFSET 0x0098 /* Interrupt flag status set register 5 */ +#define PIC32MZ_INT_IFS5INV_OFFSET 0x009c /* Interrupt flag status invert register 5 */ + +#define PIC32MZ_INT_IEC_OFFSET(n) (0x00c0 + ((n) << 4)) +#define PIC32MZ_INT_IECCLR_OFFSET(n) (0x00c4 + ((n) << 4)) +#define PIC32MZ_INT_IECSET_OFFSET(n) (0x00c8 + ((n) << 4)) +#define PIC32MZ_INT_IECINV_OFFSET(n) (0x00cc + ((n) << 4)) + +#define PIC32MZ_INT_IEC0_OFFSET 0x00c0 /* Interrupt enable control register 0 */ +#define PIC32MZ_INT_IEC0CLR_OFFSET 0x00c4 /* Interrupt enable control clear register 0 */ +#define PIC32MZ_INT_IEC0SET_OFFSET 0x00c8 /* Interrupt enable control set register 0 */ +#define PIC32MZ_INT_IEC0INV_OFFSET 0x00cc /* Interrupt enable control invert register 0 */ + +#define PIC32MZ_INT_IEC1_OFFSET 0x00d0 /* Interrupt enable control register 1 */ +#define PIC32MZ_INT_IEC1CLR_OFFSET 0x00d4 /* Interrupt enable control clear register 1 */ +#define PIC32MZ_INT_IEC1SET_OFFSET 0x00d8 /* Interrupt enable control set register 1 */ +#define PIC32MZ_INT_IEC1INV_OFFSET 0x00dc /* Interrupt enable control invert register 1 */ + +#define PIC32MZ_INT_IEC2_OFFSET 0x00e0 /* Interrupt enable control register 2 */ +#define PIC32MZ_INT_IEC2CLR_OFFSET 0x00e4 /* Interrupt enable control clear register 2 */ +#define PIC32MZ_INT_IEC2SET_OFFSET 0x00e8 /* Interrupt enable control set register 2 */ +#define PIC32MZ_INT_IEC2INV_OFFSET 0x00ec /* Interrupt enable control invert register 2 */ + +#define PIC32MZ_INT_IEC3_OFFSET 0x00f0 /* Interrupt enable control register 3 */ +#define PIC32MZ_INT_IEC3CLR_OFFSET 0x00f4 /* Interrupt enable control clear register 3 */ +#define PIC32MZ_INT_IEC3SET_OFFSET 0x00f8 /* Interrupt enable control set register 3 */ +#define PIC32MZ_INT_IEC3INV_OFFSET 0x00fc /* Interrupt enable control invert register 3 */ + +#define PIC32MZ_INT_IEC4_OFFSET 0x0100 /* Interrupt enable control register 4 */ +#define PIC32MZ_INT_IEC4CLR_OFFSET 0x0104 /* Interrupt enable control clear register 4 */ +#define PIC32MZ_INT_IEC4SET_OFFSET 0x0108 /* Interrupt enable control set register 4 */ +#define PIC32MZ_INT_IEC4INV_OFFSET 0x010c /* Interrupt enable control invert register 4 */ + +#define PIC32MZ_INT_IEC5_OFFSET 0x0110 /* Interrupt enable control register 5 */ +#define PIC32MZ_INT_IEC5CLR_OFFSET 0x0114 /* Interrupt enable control clear register 5 */ +#define PIC32MZ_INT_IEC5SET_OFFSET 0x0118 /* Interrupt enable control set register 5 */ +#define PIC32MZ_INT_IEC5INV_OFFSET 0x011c /* Interrupt enable control invert register 5 */ + +#define PIC32MZ_INT_IPC_OFFSET(n) (0x0140 + ((n) << 4)) +#define PIC32MZ_INT_IPCCLR_OFFSET(n) (0x0144 + ((n) << 4)) +#define PIC32MZ_INT_IPCSET_OFFSET(n) (0x0148 + ((n) << 4)) +#define PIC32MZ_INT_IPCINV_OFFSET(n) (0x014c + ((n) << 4)) + +#define PIC32MZ_INT_IPC0_OFFSET 0x0140 /* Interrupt priority control register 0 */ +#define PIC32MZ_INT_IPC0CLR_OFFSET 0x0144 /* Interrupt priority control clear register 0 */ +#define PIC32MZ_INT_IPC0SET_OFFSET 0x0148 /* Interrupt priority control set register 0 */ +#define PIC32MZ_INT_IPC0INV_OFFSET 0x014c /* Interrupt priority control invert register 0 */ + +#define PIC32MZ_INT_IPC1_OFFSET 0x0150 /* Interrupt priority control register 1 */ +#define PIC32MZ_INT_IPC1CLR_OFFSET 0x0154 /* Interrupt priority control clear register 1 */ +#define PIC32MZ_INT_IPC1SET_OFFSET 0x0158 /* Interrupt priority control set register 1 */ +#define PIC32MZ_INT_IPC1INV_OFFSET 0x015c /* Interrupt priority control invert register 1 */ + +#define PIC32MZ_INT_IPC2_OFFSET 0x0160 /* Interrupt priority control register 2 */ +#define PIC32MZ_INT_IPC2CLR_OFFSET 0x0164 /* Interrupt priority control clear register 2 */ +#define PIC32MZ_INT_IPC2SET_OFFSET 0x0168 /* Interrupt priority control set register 2 */ +#define PIC32MZ_INT_IPC2INV_OFFSET 0x016c /* Interrupt priority control invert register 2 */ + +#define PIC32MZ_INT_IPC3_OFFSET 0x0170 /* Interrupt priority control register 3 */ +#define PIC32MZ_INT_IPC3CLR_OFFSET 0x0174 /* Interrupt priority control clear register 3 */ +#define PIC32MZ_INT_IPC3SET_OFFSET 0x0178 /* Interrupt priority control set register 3 */ +#define PIC32MZ_INT_IPC3INV_OFFSET 0x017c /* Interrupt priority control invert register 3 */ + +#define PIC32MZ_INT_IPC4_OFFSET 0x0180 /* Interrupt priority control register 4 */ +#define PIC32MZ_INT_IPC4CLR_OFFSET 0x0184 /* Interrupt priority control clear register 4 */ +#define PIC32MZ_INT_IPC4SET_OFFSET 0x0188 /* Interrupt priority control set register 4 */ +#define PIC32MZ_INT_IPC4INV_OFFSET 0x018c /* Interrupt priority control invert register 4 */ + +#define PIC32MZ_INT_IPC5_OFFSET 0x0190 /* Interrupt priority control register 5 */ +#define PIC32MZ_INT_IPC5CLR_OFFSET 0x0194 /* Interrupt priority control clear register 5 */ +#define PIC32MZ_INT_IPC5SET_OFFSET 0x0198 /* Interrupt priority control set register 5 */ +#define PIC32MZ_INT_IPC5INV_OFFSET 0x019c /* Interrupt priority control invert register 5 */ + +#define PIC32MZ_INT_IPC6_OFFSET 0x01a0 /* Interrupt priority control register 6 */ +#define PIC32MZ_INT_IPC6CLR_OFFSET 0x01a4 /* Interrupt priority control clear register 6 */ +#define PIC32MZ_INT_IPC6SET_OFFSET 0x01a8 /* Interrupt priority control set register 6 */ +#define PIC32MZ_INT_IPC6INV_OFFSET 0x01ac /* Interrupt priority control invert register 6 */ + +#define PIC32MZ_INT_IPC7_OFFSET 0x01b0 /* Interrupt priority control register 7 */ +#define PIC32MZ_INT_IPC7CLR_OFFSET 0x01b4 /* Interrupt priority control clear register 7 */ +#define PIC32MZ_INT_IPC7SET_OFFSET 0x01b8 /* Interrupt priority control set register 7 */ +#define PIC32MZ_INT_IPC7INV_OFFSET 0x01bc /* Interrupt priority control invert register 7 */ + +#define PIC32MZ_INT_IPC8_OFFSET 0x01c0 /* Interrupt priority control register 8 */ +#define PIC32MZ_INT_IPC8CLR_OFFSET 0x01c4 /* Interrupt priority control clear register 8 */ +#define PIC32MZ_INT_IPC8SET_OFFSET 0x01c8 /* Interrupt priority control set register 8 */ +#define PIC32MZ_INT_IPC8INV_OFFSET 0x01cc /* Interrupt priority control invert register 8 */ + +#define PIC32MZ_INT_IPC9_OFFSET 0x01d0 /* Interrupt priority control register 9 */ +#define PIC32MZ_INT_IPC9CLR_OFFSET 0x01d4 /* Interrupt priority control clear register 9 */ +#define PIC32MZ_INT_IPC9SET_OFFSET 0x01d8 /* Interrupt priority control set register 9 */ +#define PIC32MZ_INT_IPC9INV_OFFSET 0x01dc /* Interrupt priority control invert register 9 */ + +#define PIC32MZ_INT_IPC10_OFFSET 0x01e0 /* Interrupt priority control register 10 */ +#define PIC32MZ_INT_IPC10CLR_OFFSET 0x01e4 /* Interrupt priority control clear register 10 */ +#define PIC32MZ_INT_IPC10SET_OFFSET 0x01e8 /* Interrupt priority control set register 10 */ +#define PIC32MZ_INT_IPC10INV_OFFSET 0x01ec /* Interrupt priority control invert register 10 */ + +#define PIC32MZ_INT_IPC11_OFFSET 0x01f0 /* Interrupt priority control register 11 */ +#define PIC32MZ_INT_IPC11CLR_OFFSET 0x01f4 /* Interrupt priority control clear register 11 */ +#define PIC32MZ_INT_IPC11SET_OFFSET 0x01f8 /* Interrupt priority control set register 11 */ +#define PIC32MZ_INT_IPC11INV_OFFSET 0x01fc /* Interrupt priority control invert register 11 */ + +#define PIC32MZ_INT_IPC12_OFFSET 0x0200 /* Interrupt priority control register 12 */ +#define PIC32MZ_INT_IPC12CLR_OFFSET 0x0204 /* Interrupt priority control clear register 12 */ +#define PIC32MZ_INT_IPC12SET_OFFSET 0x0208 /* Interrupt priority control set register 12 */ +#define PIC32MZ_INT_IPC12INV_OFFSET 0x020c /* Interrupt priority control invert register 12 */ + +#define PIC32MZ_INT_IPC13_OFFSET 0x0210 /* Interrupt priority control register 13 */ +#define PIC32MZ_INT_IPC13CLR_OFFSET 0x0214 /* Interrupt priority control clear register 13 */ +#define PIC32MZ_INT_IPC13SET_OFFSET 0x0218 /* Interrupt priority control set register 13 */ +#define PIC32MZ_INT_IPC13INV_OFFSET 0x021c /* Interrupt priority control invert register 13 */ + +#define PIC32MZ_INT_IPC14_OFFSET 0x0220 /* Interrupt priority control register 14 */ +#define PIC32MZ_INT_IPC14CLR_OFFSET 0x0224 /* Interrupt priority control clear register 14 */ +#define PIC32MZ_INT_IPC14SET_OFFSET 0x0228 /* Interrupt priority control set register 14 */ +#define PIC32MZ_INT_IPC14INV_OFFSET 0x022c /* Interrupt priority control invert register 14 */ + +#define PIC32MZ_INT_IPC15_OFFSET 0x0230 /* Interrupt priority control register 15 */ +#define PIC32MZ_INT_IPC15CLR_OFFSET 0x0234 /* Interrupt priority control clear register 15 */ +#define PIC32MZ_INT_IPC15SET_OFFSET 0x0238 /* Interrupt priority control set register 15 */ +#define PIC32MZ_INT_IPC15INV_OFFSET 0x023c /* Interrupt priority control invert register 15 */ + +#define PIC32MZ_INT_IPC16_OFFSET 0x0240 /* Interrupt priority control register 16 */ +#define PIC32MZ_INT_IPC16CLR_OFFSET 0x0244 /* Interrupt priority control clear register 16 */ +#define PIC32MZ_INT_IPC16SET_OFFSET 0x0248 /* Interrupt priority control set register 16 */ +#define PIC32MZ_INT_IPC16INV_OFFSET 0x024c /* Interrupt priority control invert register 16 */ + +#define PIC32MZ_INT_IPC17_OFFSET 0x0250 /* Interrupt priority control register 17 */ +#define PIC32MZ_INT_IPC17CLR_OFFSET 0x0254 /* Interrupt priority control clear register 17 */ +#define PIC32MZ_INT_IPC17SET_OFFSET 0x0258 /* Interrupt priority control set register 17 */ +#define PIC32MZ_INT_IPC17INV_OFFSET 0x025c /* Interrupt priority control invert register 17 */ + +#define PIC32MZ_INT_IPC18_OFFSET 0x0260 /* Interrupt priority control register 18 */ +#define PIC32MZ_INT_IPC18CLR_OFFSET 0x0264 /* Interrupt priority control clear register 18 */ +#define PIC32MZ_INT_IPC18SET_OFFSET 0x0268 /* Interrupt priority control set register 18 */ +#define PIC32MZ_INT_IPC18INV_OFFSET 0x026c /* Interrupt priority control invert register 18 */ + +#define PIC32MZ_INT_IPC19_OFFSET 0x0270 /* Interrupt priority control register 19 */ +#define PIC32MZ_INT_IPC19CLR_OFFSET 0x0274 /* Interrupt priority control clear register 19 */ +#define PIC32MZ_INT_IPC19SET_OFFSET 0x0278 /* Interrupt priority control set register 19 */ +#define PIC32MZ_INT_IPC19INV_OFFSET 0x027c /* Interrupt priority control invert register 19 */ + +#define PIC32MZ_INT_IPC20_OFFSET 0x0280 /* Interrupt priority control register 20 */ +#define PIC32MZ_INT_IPC20CLR_OFFSET 0x0284 /* Interrupt priority control clear register 20 */ +#define PIC32MZ_INT_IPC20SET_OFFSET 0x0288 /* Interrupt priority control set register 20 */ +#define PIC32MZ_INT_IPC20INV_OFFSET 0x028c /* Interrupt priority control invert register 20 */ + +#define PIC32MZ_INT_IPC21_OFFSET 0x0290 /* Interrupt priority control register 21 */ +#define PIC32MZ_INT_IPC21CLR_OFFSET 0x0294 /* Interrupt priority control clear register 21 */ +#define PIC32MZ_INT_IPC21SET_OFFSET 0x0298 /* Interrupt priority control set register 21 */ +#define PIC32MZ_INT_IPC21INV_OFFSET 0x029c /* Interrupt priority control invert register 21 */ + +#define PIC32MZ_INT_IPC22_OFFSET 0x02a0 /* Interrupt priority control register 22 */ +#define PIC32MZ_INT_IPC22CLR_OFFSET 0x02a4 /* Interrupt priority control clear register 22 */ +#define PIC32MZ_INT_IPC22SET_OFFSET 0x02a8 /* Interrupt priority control set register 22 */ +#define PIC32MZ_INT_IPC22INV_OFFSET 0x02ac /* Interrupt priority control invert register 22 */ + +#define PIC32MZ_INT_IPC23_OFFSET 0x02b0 /* Interrupt priority control register 23 */ +#define PIC32MZ_INT_IPC23CLR_OFFSET 0x02b4 /* Interrupt priority control clear register 23 */ +#define PIC32MZ_INT_IPC23SET_OFFSET 0x02b8 /* Interrupt priority control set register 23 */ +#define PIC32MZ_INT_IPC23INV_OFFSET 0x02bc /* Interrupt priority control invert register 23 */ + +#define PIC32MZ_INT_IPC24_OFFSET 0x02c0 /* Interrupt priority control register 24 */ +#define PIC32MZ_INT_IPC24CLR_OFFSET 0x02c4 /* Interrupt priority control clear register 24 */ +#define PIC32MZ_INT_IPC24SET_OFFSET 0x02c8 /* Interrupt priority control set register 24 */ +#define PIC32MZ_INT_IPC24INV_OFFSET 0x02cc /* Interrupt priority control invert register 24 */ + +#define PIC32MZ_INT_IPC25_OFFSET 0x02d0 /* Interrupt priority control register 25 */ +#define PIC32MZ_INT_IPC25CLR_OFFSET 0x02d4 /* Interrupt priority control clear register 25 */ +#define PIC32MZ_INT_IPC25SET_OFFSET 0x02d8 /* Interrupt priority control set register 25 */ +#define PIC32MZ_INT_IPC25INV_OFFSET 0x02dc /* Interrupt priority control invert register 25 */ + +#define PIC32MZ_INT_IPC26_OFFSET 0x02e0 /* Interrupt priority control register 26 */ +#define PIC32MZ_INT_IPC26CLR_OFFSET 0x02e4 /* Interrupt priority control clear register 26 */ +#define PIC32MZ_INT_IPC26SET_OFFSET 0x02e8 /* Interrupt priority control set register 26 */ +#define PIC32MZ_INT_IPC26INV_OFFSET 0x02ec /* Interrupt priority control invert register 26 */ + +#define PIC32MZ_INT_IPC27_OFFSET 0x02f0 /* Interrupt priority control register 27 */ +#define PIC32MZ_INT_IPC27CLR_OFFSET 0x02f4 /* Interrupt priority control clear register 27 */ +#define PIC32MZ_INT_IPC27SET_OFFSET 0x02f8 /* Interrupt priority control set register 27 */ +#define PIC32MZ_INT_IPC27INV_OFFSET 0x02fc /* Interrupt priority control invert register 27 */ + +#define PIC32MZ_INT_IPC28_OFFSET 0x0300 /* Interrupt priority control register 28 */ +#define PIC32MZ_INT_IPC28CLR_OFFSET 0x0304 /* Interrupt priority control clear register 28 */ +#define PIC32MZ_INT_IPC28SET_OFFSET 0x0308 /* Interrupt priority control set register 28 */ +#define PIC32MZ_INT_IPC28INV_OFFSET 0x030c /* Interrupt priority control invert register 28 */ + +#define PIC32MZ_INT_IPC29_OFFSET 0x0310 /* Interrupt priority control register 29 */ +#define PIC32MZ_INT_IPC29CLR_OFFSET 0x0314 /* Interrupt priority control clear register 29 */ +#define PIC32MZ_INT_IPC29SET_OFFSET 0x0318 /* Interrupt priority control set register 29 */ +#define PIC32MZ_INT_IPC29INV_OFFSET 0x031c /* Interrupt priority control invert register 29 */ + +#define PIC32MZ_INT_IPC30_OFFSET 0x0320 /* Interrupt priority control register 30 */ +#define PIC32MZ_INT_IPC30CLR_OFFSET 0x0324 /* Interrupt priority control clear register 30 */ +#define PIC32MZ_INT_IPC30SET_OFFSET 0x0328 /* Interrupt priority control set register 30 */ +#define PIC32MZ_INT_IPC30INV_OFFSET 0x032c /* Interrupt priority control invert register 30 */ + +#define PIC32MZ_INT_IPC31_OFFSET 0x0330 /* Interrupt priority control register 31 */ +#define PIC32MZ_INT_IPC31CLR_OFFSET 0x0334 /* Interrupt priority control clear register 31 */ +#define PIC32MZ_INT_IPC31SET_OFFSET 0x0338 /* Interrupt priority control set register 31 */ +#define PIC32MZ_INT_IPC31INV_OFFSET 0x033c /* Interrupt priority control invert register 31 */ + +#define PIC32MZ_INT_IPC32_OFFSET 0x0340 /* Interrupt priority control register 32 */ +#define PIC32MZ_INT_IPC32CLR_OFFSET 0x0344 /* Interrupt priority control clear register 32 */ +#define PIC32MZ_INT_IPC32SET_OFFSET 0x0348 /* Interrupt priority control set register 32 */ +#define PIC32MZ_INT_IPC32INV_OFFSET 0x034c /* Interrupt priority control invert register 32 */ + +#define PIC32MZ_INT_IPC33_OFFSET 0x0350 /* Interrupt priority control register 33 */ +#define PIC32MZ_INT_IPC33CLR_OFFSET 0x0354 /* Interrupt priority control clear register 33 */ +#define PIC32MZ_INT_IPC33SET_OFFSET 0x0358 /* Interrupt priority control set register 33 */ +#define PIC32MZ_INT_IPC33INV_OFFSET 0x035c /* Interrupt priority control invert register 33 */ + +#define PIC32MZ_INT_IPC34_OFFSET 0x0360 /* Interrupt priority control register 34 */ +#define PIC32MZ_INT_IPC34CLR_OFFSET 0x0364 /* Interrupt priority control clear register 34 */ +#define PIC32MZ_INT_IPC34SET_OFFSET 0x0368 /* Interrupt priority control set register 34 */ +#define PIC32MZ_INT_IPC34INV_OFFSET 0x036c /* Interrupt priority control invert register 34 */ + +#define PIC32MZ_INT_IPC35_OFFSET 0x0370 /* Interrupt priority control register 35 */ +#define PIC32MZ_INT_IPC35CLR_OFFSET 0x0374 /* Interrupt priority control clear register 35 */ +#define PIC32MZ_INT_IPC35SET_OFFSET 0x0378 /* Interrupt priority control set register 35 */ +#define PIC32MZ_INT_IPC35INV_OFFSET 0x037c /* Interrupt priority control invert register 35 */ + +#define PIC32MZ_INT_IPC36_OFFSET 0x0380 /* Interrupt priority control register 36 */ +#define PIC32MZ_INT_IPC36CLR_OFFSET 0x0384 /* Interrupt priority control clear register 36 */ +#define PIC32MZ_INT_IPC36SET_OFFSET 0x0388 /* Interrupt priority control set register 36 */ +#define PIC32MZ_INT_IPC36INV_OFFSET 0x038c /* Interrupt priority control invert register 36 */ + +#define PIC32MZ_INT_IPC37_OFFSET 0x0390 /* Interrupt priority control register 37 */ +#define PIC32MZ_INT_IPC37CLR_OFFSET 0x0394 /* Interrupt priority control clear register 37 */ +#define PIC32MZ_INT_IPC37SET_OFFSET 0x0398 /* Interrupt priority control set register 37 */ +#define PIC32MZ_INT_IPC37INV_OFFSET 0x039c /* Interrupt priority control invert register 37 */ + +#define PIC32MZ_INT_IPC38_OFFSET 0x03a0 /* Interrupt priority control register 38 */ +#define PIC32MZ_INT_IPC38CLR_OFFSET 0x03a4 /* Interrupt priority control clear register 38 */ +#define PIC32MZ_INT_IPC38SET_OFFSET 0x03a8 /* Interrupt priority control set register 38 */ +#define PIC32MZ_INT_IPC38INV_OFFSET 0x03ac /* Interrupt priority control invert register 38 */ + +#define PIC32MZ_INT_IPC39_OFFSET 0x03b0 /* Interrupt priority control register 39 */ +#define PIC32MZ_INT_IPC39CLR_OFFSET 0x03b4 /* Interrupt priority control clear register 39 */ +#define PIC32MZ_INT_IPC39SET_OFFSET 0x03b8 /* Interrupt priority control set register 39 */ +#define PIC32MZ_INT_IPC39INV_OFFSET 0x03bc /* Interrupt priority control invert register 39 */ + +#define PIC32MZ_INT_IPC40_OFFSET 0x03c0 /* Interrupt priority control register 40 */ +#define PIC32MZ_INT_IPC40CLR_OFFSET 0x03c4 /* Interrupt priority control clear register 40 */ +#define PIC32MZ_INT_IPC40SET_OFFSET 0x03c8 /* Interrupt priority control set register 40 */ +#define PIC32MZ_INT_IPC40INV_OFFSET 0x03cc /* Interrupt priority control invert register 40 */ + +#define PIC32MZ_INT_IPC41_OFFSET 0x03d0 /* Interrupt priority control register 41 */ +#define PIC32MZ_INT_IPC41CLR_OFFSET 0x03d4 /* Interrupt priority control clear register 41 */ +#define PIC32MZ_INT_IPC41SET_OFFSET 0x03d8 /* Interrupt priority control set register 41 */ +#define PIC32MZ_INT_IPC41INV_OFFSET 0x03dc /* Interrupt priority control invert register 41 */ + +#define PIC32MZ_INT_IPC42_OFFSET 0x03e0 /* Interrupt priority control register 42 */ +#define PIC32MZ_INT_IPC42CLR_OFFSET 0x03e4 /* Interrupt priority control clear register 42 */ +#define PIC32MZ_INT_IPC42SET_OFFSET 0x03e8 /* Interrupt priority control set register 42 */ +#define PIC32MZ_INT_IPC42INV_OFFSET 0x03ec /* Interrupt priority control invert register 42 */ + +#define PIC32MZ_INT_IPC43_OFFSET 0x03f0 /* Interrupt priority control register 43 */ +#define PIC32MZ_INT_IPC43CLR_OFFSET 0x03f4 /* Interrupt priority control clear register 43 */ +#define PIC32MZ_INT_IPC43SET_OFFSET 0x03f8 /* Interrupt priority control set register 43 */ +#define PIC32MZ_INT_IPC43INV_OFFSET 0x03fc /* Interrupt priority control invert register 43 */ + +#define PIC32MZ_INT_IPC44_OFFSET 0x0400 /* Interrupt priority control register 44 */ +#define PIC32MZ_INT_IPC44CLR_OFFSET 0x0404 /* Interrupt priority control clear register 44 */ +#define PIC32MZ_INT_IPC44SET_OFFSET 0x0408 /* Interrupt priority control set register 44 */ +#define PIC32MZ_INT_IPC44INV_OFFSET 0x040c /* Interrupt priority control invert register 44 */ + +#define PIC32MZ_INT_IPC45_OFFSET 0x0410 /* Interrupt priority control register 45 */ +#define PIC32MZ_INT_IPC45CLR_OFFSET 0x0414 /* Interrupt priority control clear register 45 */ +#define PIC32MZ_INT_IPC45SET_OFFSET 0x0418 /* Interrupt priority control set register 45 */ +#define PIC32MZ_INT_IPC45INV_OFFSET 0x041c /* Interrupt priority control invert register 45 */ + +#define PIC32MZ_INT_IPC46_OFFSET 0x0420 /* Interrupt priority control register 46 */ +#define PIC32MZ_INT_IPC46CLR_OFFSET 0x0424 /* Interrupt priority control clear register 46 */ +#define PIC32MZ_INT_IPC46SET_OFFSET 0x0428 /* Interrupt priority control set register 46 */ +#define PIC32MZ_INT_IPC46INV_OFFSET 0x042c /* Interrupt priority control invert register 46 */ + +#define PIC32MZ_INT_IPC47_OFFSET 0x0430 /* Interrupt priority control register 47 */ +#define PIC32MZ_INT_IPC47CLR_OFFSET 0x0434 /* Interrupt priority control clear register 47 */ +#define PIC32MZ_INT_IPC47SET_OFFSET 0x0438 /* Interrupt priority control set register 47 */ +#define PIC32MZ_INT_IPC47INV_OFFSET 0x043c /* Interrupt priority control invert register 47 */ + +#define PIC32MZ_INT_OFF_OFFSET(n) (0x0540 + ((n) << 2) +#define PIC32MZ_INT_OFF000_OFFSET 0x0540 /* Interrupt vector 0 address offset */ +#define PIC32MZ_INT_OFF001_OFFSET 0x0544 /* Interrupt vector 1 address offset */ +#define PIC32MZ_INT_OFF002_OFFSET 0x0548 /* Interrupt vector 2 address offset */ +#define PIC32MZ_INT_OFF003_OFFSET 0x054c /* Interrupt vector 3 address offset */ +#define PIC32MZ_INT_OFF004_OFFSET 0x0550 /* Interrupt vector 4 address offset */ +#define PIC32MZ_INT_OFF005_OFFSET 0x0554 /* Interrupt vector 5 address offset */ +#define PIC32MZ_INT_OFF006_OFFSET 0x0558 /* Interrupt vector 6 address offset */ +#define PIC32MZ_INT_OFF007_OFFSET 0x055c /* Interrupt vector 7 address offset */ +#define PIC32MZ_INT_OFF008_OFFSET 0x0560 /* Interrupt vector 8 address offset */ +#define PIC32MZ_INT_OFF009_OFFSET 0x0564 /* Interrupt vector 9 address offset */ +#define PIC32MZ_INT_OFF010_OFFSET 0x0568 /* Interrupt vector 10 address offset */ +#define PIC32MZ_INT_OFF011_OFFSET 0x056c /* Interrupt vector 11 address offset */ +#define PIC32MZ_INT_OFF012_OFFSET 0x0570 /* Interrupt vector 12 address offset */ +#define PIC32MZ_INT_OFF013_OFFSET 0x0574 /* Interrupt vector 13 address offset */ +#define PIC32MZ_INT_OFF014_OFFSET 0x0578 /* Interrupt vector 14 address offset */ +#define PIC32MZ_INT_OFF015_OFFSET 0x057c /* Interrupt vector 15 address offset */ + +#define PIC32MZ_INT_OFF016_OFFSET 0x0580 /* Interrupt vector 16 address offset */ +#define PIC32MZ_INT_OFF017_OFFSET 0x0584 /* Interrupt vector 17 address offset */ +#define PIC32MZ_INT_OFF018_OFFSET 0x0588 /* Interrupt vector 18 address offset */ +#define PIC32MZ_INT_OFF019_OFFSET 0x058c /* Interrupt vector 19 address offset */ +#define PIC32MZ_INT_OFF020_OFFSET 0x0590 /* Interrupt vector 20 address offset */ +#define PIC32MZ_INT_OFF021_OFFSET 0x0594 /* Interrupt vector 21 address offset */ +#define PIC32MZ_INT_OFF022_OFFSET 0x0598 /* Interrupt vector 22 address offset */ +#define PIC32MZ_INT_OFF023_OFFSET 0x059c /* Interrupt vector 23 address offset */ +#define PIC32MZ_INT_OFF024_OFFSET 0x05a0 /* Interrupt vector 24 address offset */ +#define PIC32MZ_INT_OFF025_OFFSET 0x05a4 /* Interrupt vector 25 address offset */ +#define PIC32MZ_INT_OFF026_OFFSET 0x05a8 /* Interrupt vector 26 address offset */ +#define PIC32MZ_INT_OFF027_OFFSET 0x05ac /* Interrupt vector 27 address offset */ +#define PIC32MZ_INT_OFF028_OFFSET 0x05b0 /* Interrupt vector 28 address offset */ +#define PIC32MZ_INT_OFF029_OFFSET 0x05b4 /* Interrupt vector 29 address offset */ +#define PIC32MZ_INT_OFF030_OFFSET 0x05b8 /* Interrupt vector 30 address offset */ +#define PIC32MZ_INT_OFF031_OFFSET 0x05bc /* Interrupt vector 31 address offset */ + +#define PIC32MZ_INT_OFF032_OFFSET 0x05c0 /* Interrupt vector 32 address offset */ +#define PIC32MZ_INT_OFF033_OFFSET 0x05c4 /* Interrupt vector 33 address offset */ +#define PIC32MZ_INT_OFF034_OFFSET 0x05c8 /* Interrupt vector 34 address offset */ +#define PIC32MZ_INT_OFF035_OFFSET 0x05cc /* Interrupt vector 35 address offset */ +#define PIC32MZ_INT_OFF036_OFFSET 0x05d0 /* Interrupt vector 36 address offset */ +#define PIC32MZ_INT_OFF037_OFFSET 0x05d4 /* Interrupt vector 37 address offset */ +#define PIC32MZ_INT_OFF038_OFFSET 0x05d8 /* Interrupt vector 38 address offset */ +#define PIC32MZ_INT_OFF039_OFFSET 0x05dc /* Interrupt vector 39 address offset */ +#define PIC32MZ_INT_OFF040_OFFSET 0x05e0 /* Interrupt vector 40 address offset */ +#define PIC32MZ_INT_OFF041_OFFSET 0x05e4 /* Interrupt vector 41 address offset */ +#define PIC32MZ_INT_OFF042_OFFSET 0x05e8 /* Interrupt vector 42 address offset */ +#define PIC32MZ_INT_OFF043_OFFSET 0x05ec /* Interrupt vector 43 address offset */ +#define PIC32MZ_INT_OFF044_OFFSET 0x05f0 /* Interrupt vector 44 address offset */ +#define PIC32MZ_INT_OFF045_OFFSET 0x05f4 /* Interrupt vector 45 address offset */ +#define PIC32MZ_INT_OFF046_OFFSET 0x05f8 /* Interrupt vector 46 address offset */ +#define PIC32MZ_INT_OFF047_OFFSET 0x05fc /* Interrupt vector 47 address offset */ + +#define PIC32MZ_INT_OFF048_OFFSET 0x0600 /* Interrupt vector 48 address offset */ +#define PIC32MZ_INT_OFF049_OFFSET 0x0604 /* Interrupt vector 49 address offset */ +#define PIC32MZ_INT_OFF050_OFFSET 0x0608 /* Interrupt vector 50 address offset */ +#define PIC32MZ_INT_OFF051_OFFSET 0x060c /* Interrupt vector 51 address offset */ +#define PIC32MZ_INT_OFF052_OFFSET 0x0610 /* Interrupt vector 52 address offset */ +#define PIC32MZ_INT_OFF053_OFFSET 0x0614 /* Interrupt vector 53 address offset */ +#define PIC32MZ_INT_OFF054_OFFSET 0x0618 /* Interrupt vector 54 address offset */ +#define PIC32MZ_INT_OFF055_OFFSET 0x061c /* Interrupt vector 55 address offset */ +#define PIC32MZ_INT_OFF056_OFFSET 0x0620 /* Interrupt vector 56 address offset */ +#define PIC32MZ_INT_OFF057_OFFSET 0x0624 /* Interrupt vector 57 address offset */ +#define PIC32MZ_INT_OFF058_OFFSET 0x0628 /* Interrupt vector 58 address offset */ +#define PIC32MZ_INT_OFF059_OFFSET 0x062c /* Interrupt vector 59 address offset */ +#define PIC32MZ_INT_OFF060_OFFSET 0x0630 /* Interrupt vector 60 address offset */ +#define PIC32MZ_INT_OFF061_OFFSET 0x0634 /* Interrupt vector 61 address offset */ +#define PIC32MZ_INT_OFF062_OFFSET 0x0638 /* Interrupt vector 62 address offset */ +#define PIC32MZ_INT_OFF063_OFFSET 0x063c /* Interrupt vector 63 address offset */ + +#define PIC32MZ_INT_OFF064_OFFSET 0x0640 /* Interrupt vector 64 address offset */ +#define PIC32MZ_INT_OFF065_OFFSET 0x0644 /* Interrupt vector 65 address offset */ +#define PIC32MZ_INT_OFF066_OFFSET 0x0648 /* Interrupt vector 66 address offset */ +#define PIC32MZ_INT_OFF067_OFFSET 0x064c /* Interrupt vector 67 address offset */ +#define PIC32MZ_INT_OFF068_OFFSET 0x0650 /* Interrupt vector 68 address offset */ +#define PIC32MZ_INT_OFF069_OFFSET 0x0654 /* Interrupt vector 69 address offset */ +#define PIC32MZ_INT_OFF070_OFFSET 0x0658 /* Interrupt vector 70 address offset */ +#define PIC32MZ_INT_OFF071_OFFSET 0x065c /* Interrupt vector 71 address offset */ +#define PIC32MZ_INT_OFF072_OFFSET 0x0660 /* Interrupt vector 72 address offset */ +#define PIC32MZ_INT_OFF073_OFFSET 0x0664 /* Interrupt vector 73 address offset */ +#define PIC32MZ_INT_OFF074_OFFSET 0x0668 /* Interrupt vector 74 address offset */ +#define PIC32MZ_INT_OFF075_OFFSET 0x066c /* Interrupt vector 75 address offset */ +#define PIC32MZ_INT_OFF076_OFFSET 0x0670 /* Interrupt vector 76 address offset */ +#define PIC32MZ_INT_OFF077_OFFSET 0x0674 /* Interrupt vector 77 address offset */ +#define PIC32MZ_INT_OFF078_OFFSET 0x0678 /* Interrupt vector 78 address offset */ +#define PIC32MZ_INT_OFF079_OFFSET 0x067c /* Interrupt vector 79 address offset */ + +#define PIC32MZ_INT_OFF080_OFFSET 0x0680 /* Interrupt vector 80 address offset */ +#define PIC32MZ_INT_OFF081_OFFSET 0x0684 /* Interrupt vector 81 address offset */ +#define PIC32MZ_INT_OFF082_OFFSET 0x0688 /* Interrupt vector 82 address offset */ +#define PIC32MZ_INT_OFF083_OFFSET 0x068c /* Interrupt vector 83 address offset */ +#define PIC32MZ_INT_OFF084_OFFSET 0x0690 /* Interrupt vector 84 address offset */ +#define PIC32MZ_INT_OFF085_OFFSET 0x0694 /* Interrupt vector 85 address offset */ +#define PIC32MZ_INT_OFF086_OFFSET 0x0698 /* Interrupt vector 86 address offset */ +#define PIC32MZ_INT_OFF087_OFFSET 0x069c /* Interrupt vector 87 address offset */ +#define PIC32MZ_INT_OFF088_OFFSET 0x06a0 /* Interrupt vector 88 address offset */ +#define PIC32MZ_INT_OFF089_OFFSET 0x06a4 /* Interrupt vector 89 address offset */ +#define PIC32MZ_INT_OFF090_OFFSET 0x06a8 /* Interrupt vector 90 address offset */ +#define PIC32MZ_INT_OFF091_OFFSET 0x06ac /* Interrupt vector 91 address offset */ +#define PIC32MZ_INT_OFF092_OFFSET 0x06b0 /* Interrupt vector 92 address offset */ +#define PIC32MZ_INT_OFF093_OFFSET 0x06b4 /* Interrupt vector 93 address offset */ +#define PIC32MZ_INT_OFF094_OFFSET 0x06b8 /* Interrupt vector 94 address offset */ +#define PIC32MZ_INT_OFF095_OFFSET 0x06bc /* Interrupt vector 95 address offset */ + +#define PIC32MZ_INT_OFF096_OFFSET 0x06c0 /* Interrupt vector 96 address offset */ +#define PIC32MZ_INT_OFF097_OFFSET 0x06c4 /* Interrupt vector 97 address offset */ +#define PIC32MZ_INT_OFF098_OFFSET 0x06c8 /* Interrupt vector 98 address offset */ +#define PIC32MZ_INT_OFF099_OFFSET 0x06cc /* Interrupt vector 99 address offset */ +#define PIC32MZ_INT_OFF100_OFFSET 0x06d0 /* Interrupt vector 100 address offset */ +#define PIC32MZ_INT_OFF101_OFFSET 0x06d4 /* Interrupt vector 101 address offset */ +#define PIC32MZ_INT_OFF102_OFFSET 0x06d8 /* Interrupt vector 102 address offset */ +#define PIC32MZ_INT_OFF103_OFFSET 0x06dc /* Interrupt vector 103 address offset */ +#define PIC32MZ_INT_OFF104_OFFSET 0x06e0 /* Interrupt vector 104 address offset */ +#define PIC32MZ_INT_OFF105_OFFSET 0x06e4 /* Interrupt vector 105 address offset */ +#define PIC32MZ_INT_OFF106_OFFSET 0x06e8 /* Interrupt vector 106 address offset */ +#define PIC32MZ_INT_OFF107_OFFSET 0x06ec /* Interrupt vector 107 address offset */ +#define PIC32MZ_INT_OFF108_OFFSET 0x06f0 /* Interrupt vector 108 address offset */ +#define PIC32MZ_INT_OFF109_OFFSET 0x06f4 /* Interrupt vector 109 address offset */ +#define PIC32MZ_INT_OFF110_OFFSET 0x06f8 /* Interrupt vector 110 address offset */ +#define PIC32MZ_INT_OFF111_OFFSET 0x06fc /* Interrupt vector 111 address offset */ + +#define PIC32MZ_INT_OFF112_OFFSET 0x0700 /* Interrupt vector 112 address offset */ +#define PIC32MZ_INT_OFF113_OFFSET 0x0704 /* Interrupt vector 113 address offset */ +#define PIC32MZ_INT_OFF114_OFFSET 0x0708 /* Interrupt vector 114 address offset */ +#define PIC32MZ_INT_OFF115_OFFSET 0x070c /* Interrupt vector 115 address offset */ +#define PIC32MZ_INT_OFF116_OFFSET 0x0710 /* Interrupt vector 116 address offset */ +#define PIC32MZ_INT_OFF117_OFFSET 0x0714 /* Interrupt vector 117 address offset */ +#define PIC32MZ_INT_OFF118_OFFSET 0x0718 /* Interrupt vector 118 address offset */ +#define PIC32MZ_INT_OFF119_OFFSET 0x071c /* Interrupt vector 119 address offset */ +#define PIC32MZ_INT_OFF120_OFFSET 0x0720 /* Interrupt vector 120 address offset */ +#define PIC32MZ_INT_OFF121_OFFSET 0x0724 /* Interrupt vector 121 address offset */ +#define PIC32MZ_INT_OFF122_OFFSET 0x0728 /* Interrupt vector 122 address offset */ +#define PIC32MZ_INT_OFF123_OFFSET 0x072c /* Interrupt vector 123 address offset */ +#define PIC32MZ_INT_OFF124_OFFSET 0x0730 /* Interrupt vector 124 address offset */ +#define PIC32MZ_INT_OFF125_OFFSET 0x0734 /* Interrupt vector 125 address offset */ +#define PIC32MZ_INT_OFF126_OFFSET 0x0738 /* Interrupt vector 126 address offset */ +#define PIC32MZ_INT_OFF127_OFFSET 0x073c /* Interrupt vector 127 address offset */ + +#define PIC32MZ_INT_OFF128_OFFSET 0x0740 /* Interrupt vector 128 address offset */ +#define PIC32MZ_INT_OFF129_OFFSET 0x0744 /* Interrupt vector 129 address offset */ +#define PIC32MZ_INT_OFF130_OFFSET 0x0748 /* Interrupt vector 130 address offset */ +#define PIC32MZ_INT_OFF131_OFFSET 0x074c /* Interrupt vector 131 address offset */ +#define PIC32MZ_INT_OFF132_OFFSET 0x0750 /* Interrupt vector 132 address offset */ +#define PIC32MZ_INT_OFF133_OFFSET 0x0754 /* Interrupt vector 133 address offset */ +#define PIC32MZ_INT_OFF134_OFFSET 0x0758 /* Interrupt vector 134 address offset */ +#define PIC32MZ_INT_OFF135_OFFSET 0x075c /* Interrupt vector 135 address offset */ +#define PIC32MZ_INT_OFF136_OFFSET 0x0760 /* Interrupt vector 136 address offset */ +#define PIC32MZ_INT_OFF137_OFFSET 0x0764 /* Interrupt vector 137 address offset */ +#define PIC32MZ_INT_OFF138_OFFSET 0x0768 /* Interrupt vector 138 address offset */ +#define PIC32MZ_INT_OFF139_OFFSET 0x076c /* Interrupt vector 139 address offset */ +#define PIC32MZ_INT_OFF140_OFFSET 0x0770 /* Interrupt vector 140 address offset */ +#define PIC32MZ_INT_OFF141_OFFSET 0x0774 /* Interrupt vector 141 address offset */ +#define PIC32MZ_INT_OFF142_OFFSET 0x0778 /* Interrupt vector 142 address offset */ +#define PIC32MZ_INT_OFF143_OFFSET 0x077c /* Interrupt vector 143 address offset */ + +#define PIC32MZ_INT_OFF144_OFFSET 0x0780 /* Interrupt vector 144 address offset */ +#define PIC32MZ_INT_OFF145_OFFSET 0x0784 /* Interrupt vector 145 address offset */ +#define PIC32MZ_INT_OFF146_OFFSET 0x0788 /* Interrupt vector 146 address offset */ +#define PIC32MZ_INT_OFF147_OFFSET 0x078c /* Interrupt vector 147 address offset */ +#define PIC32MZ_INT_OFF148_OFFSET 0x0790 /* Interrupt vector 148 address offset */ +#define PIC32MZ_INT_OFF149_OFFSET 0x0794 /* Interrupt vector 149 address offset */ +#define PIC32MZ_INT_OFF150_OFFSET 0x0798 /* Interrupt vector 150 address offset */ +#define PIC32MZ_INT_OFF151_OFFSET 0x079c /* Interrupt vector 151 address offset */ +#define PIC32MZ_INT_OFF152_OFFSET 0x07a0 /* Interrupt vector 152 address offset */ +#define PIC32MZ_INT_OFF153_OFFSET 0x07a4 /* Interrupt vector 153 address offset */ +#define PIC32MZ_INT_OFF154_OFFSET 0x07a8 /* Interrupt vector 154 address offset */ +#define PIC32MZ_INT_OFF155_OFFSET 0x07ac /* Interrupt vector 155 address offset */ +#define PIC32MZ_INT_OFF156_OFFSET 0x07b0 /* Interrupt vector 156 address offset */ +#define PIC32MZ_INT_OFF157_OFFSET 0x07b4 /* Interrupt vector 157 address offset */ +#define PIC32MZ_INT_OFF158_OFFSET 0x07b8 /* Interrupt vector 158 address offset */ +#define PIC32MZ_INT_OFF159_OFFSET 0x07bc /* Interrupt vector 159 address offset */ + +#define PIC32MZ_INT_OFF160_OFFSET 0x07c0 /* Interrupt vector 160 address offset */ +#define PIC32MZ_INT_OFF161_OFFSET 0x07c4 /* Interrupt vector 161 address offset */ +#define PIC32MZ_INT_OFF162_OFFSET 0x07c8 /* Interrupt vector 162 address offset */ +#define PIC32MZ_INT_OFF163_OFFSET 0x07cc /* Interrupt vector 163 address offset */ +#define PIC32MZ_INT_OFF164_OFFSET 0x07d0 /* Interrupt vector 164 address offset */ +#define PIC32MZ_INT_OFF165_OFFSET 0x07d4 /* Interrupt vector 165 address offset */ +#define PIC32MZ_INT_OFF166_OFFSET 0x07d8 /* Interrupt vector 166 address offset */ +#define PIC32MZ_INT_OFF167_OFFSET 0x07dc /* Interrupt vector 167 address offset */ +#define PIC32MZ_INT_OFF168_OFFSET 0x07e0 /* Interrupt vector 168 address offset */ +#define PIC32MZ_INT_OFF169_OFFSET 0x07e4 /* Interrupt vector 169 address offset */ +#define PIC32MZ_INT_OFF170_OFFSET 0x07e8 /* Interrupt vector 170 address offset */ +#define PIC32MZ_INT_OFF171_OFFSET 0x07ec /* Interrupt vector 171 address offset */ +#define PIC32MZ_INT_OFF172_OFFSET 0x07f0 /* Interrupt vector 172 address offset */ +#define PIC32MZ_INT_OFF173_OFFSET 0x07f4 /* Interrupt vector 173 address offset */ +#define PIC32MZ_INT_OFF174_OFFSET 0x07f8 /* Interrupt vector 174 address offset */ +#define PIC32MZ_INT_OFF175_OFFSET 0x07fc /* Interrupt vector 175 address offset */ + +#define PIC32MZ_INT_OFF176_OFFSET 0x0800 /* Interrupt vector 176 address offset */ +#define PIC32MZ_INT_OFF177_OFFSET 0x0804 /* Interrupt vector 177 address offset */ +#define PIC32MZ_INT_OFF178_OFFSET 0x0808 /* Interrupt vector 178 address offset */ +#define PIC32MZ_INT_OFF179_OFFSET 0x080c /* Interrupt vector 179 address offset */ +#define PIC32MZ_INT_OFF180_OFFSET 0x0810 /* Interrupt vector 180 address offset */ +#define PIC32MZ_INT_OFF181_OFFSET 0x0814 /* Interrupt vector 181 address offset */ +#define PIC32MZ_INT_OFF182_OFFSET 0x0818 /* Interrupt vector 182 address offset */ +#define PIC32MZ_INT_OFF183_OFFSET 0x081c /* Interrupt vector 183 address offset */ +#define PIC32MZ_INT_OFF184_OFFSET 0x0820 /* Interrupt vector 184 address offset */ +#define PIC32MZ_INT_OFF185_OFFSET 0x0824 /* Interrupt vector 185 address offset */ +#define PIC32MZ_INT_OFF186_OFFSET 0x0828 /* Interrupt vector 186 address offset */ +#define PIC32MZ_INT_OFF187_OFFSET 0x082c /* Interrupt vector 187 address offset */ +#define PIC32MZ_INT_OFF188_OFFSET 0x0830 /* Interrupt vector 188 address offset */ +#define PIC32MZ_INT_OFF189_OFFSET 0x0834 /* Interrupt vector 189 address offset */ +#define PIC32MZ_INT_OFF190_OFFSET 0x0838 /* Interrupt vector 190 address offset */ + +/* Register Addresses *******************************************************/ + +#define PIC32MZ_INT_INTCON (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTCON_OFFSET) +#define PIC32MZ_INT_INTCONCLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTCONCLR_OFFSET) +#define PIC32MZ_INT_INTCONSET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTCONSET_OFFSET) +#define PIC32MZ_INT_INTCONINV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTCONINV_OFFSET) + +#define PIC32MZ_INT_PRISS (PIC32MZ_INT_K1BASE+PIC32MZ_INT_PRISS_OFFSET) +#define PIC32MZ_INT_PRISSCLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_PRISSCLR_OFFSET) +#define PIC32MZ_INT_PRISSSET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_PRISSSET_OFFSET) +#define PIC32MZ_INT_PRISSINV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_PRISSINV_OFFSET) + +#define PIC32MZ_INT_INTSTAT (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTSTAT_OFFSET) +#define PIC32MZ_INT_INTSTATCLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTSTATCLR_OFFSET) +#define PIC32MZ_INT_INTSTATSET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTSTATSET_OFFSET) +#define PIC32MZ_INT_INTSTATINV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_INTSTATINV_OFFSET) + +#define PIC32MZ_INT_IPTMR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPTMR_OFFSET) +#define PIC32MZ_INT_IPTMRCLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPTMRCLR_OFFSET) +#define PIC32MZ_INT_IPTMRSET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPTMRSET_OFFSET) +#define PIC32MZ_INT_IPTMRINV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPTMRINV_OFFSET) + +#define PIC32MZ_INT_IFS(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS_OFFSET(n)) +#define PIC32MZ_INT_IFSCLR(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFSCLR_OFFSET(n)) +#define PIC32MZ_INT_IFSSET(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFSSET_OFFSET(n)) +#define PIC32MZ_INT_IFSINV(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFSINV_OFFSET(n)) + +#define PIC32MZ_INT_IFS0 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS0_OFFSET) +#define PIC32MZ_INT_IFS0CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS0CLR_OFFSET) +#define PIC32MZ_INT_IFS0SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS0SET_OFFSET) +#define PIC32MZ_INT_IFS0INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS0INV_OFFSET) + +#define PIC32MZ_INT_IFS1 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS1_OFFSET) +#define PIC32MZ_INT_IFS1CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS1CLR_OFFSET) +#define PIC32MZ_INT_IFS1SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS1SET_OFFSET) +#define PIC32MZ_INT_IFS1INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS1INV_OFFSET) + +#define PIC32MZ_INT_IFS2 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS2_OFFSET) +#define PIC32MZ_INT_IFS2CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS2CLR_OFFSET) +#define PIC32MZ_INT_IFS2SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS2SET_OFFSET) +#define PIC32MZ_INT_IFS2INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS2INV_OFFSET) + +#define PIC32MZ_INT_IFS3 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS3_OFFSET) +#define PIC32MZ_INT_IFS3CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS3CLR_OFFSET) +#define PIC32MZ_INT_IFS3SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS3SET_OFFSET) +#define PIC32MZ_INT_IFS3INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS3INV_OFFSET) + +#define PIC32MZ_INT_IFS4 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS4_OFFSET) +#define PIC32MZ_INT_IFS4CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS4CLR_OFFSET) +#define PIC32MZ_INT_IFS4SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS4SET_OFFSET) +#define PIC32MZ_INT_IFS4INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS4INV_OFFSET) + +#define PIC32MZ_INT_IFS5 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS5_OFFSET) +#define PIC32MZ_INT_IFS5CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS5CLR_OFFSET) +#define PIC32MZ_INT_IFS5SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS5SET_OFFSET) +#define PIC32MZ_INT_IFS5INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IFS5INV_OFFSET) + +#define PIC32MZ_INT_IEC(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC_OFFSET(n)) +#define PIC32MZ_INT_IECCLR(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IECCLR_OFFSET(n)) +#define PIC32MZ_INT_IECSET(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IECSET_OFFSET(n)) +#define PIC32MZ_INT_IECINV(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IECINV_OFFSET(n)) + +#define PIC32MZ_INT_IEC0 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC0_OFFSET) +#define PIC32MZ_INT_IEC0CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC0CLR_OFFSET) +#define PIC32MZ_INT_IEC0SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC0SET_OFFSET) +#define PIC32MZ_INT_IEC0INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC0_OFFSET) + +#define PIC32MZ_INT_IEC1 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC1_OFFSET) +#define PIC32MZ_INT_IEC1CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC1CLR_OFFSET) +#define PIC32MZ_INT_IEC1SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC1SET_OFFSET) +#define PIC32MZ_INT_IEC1INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC1INV_OFFSET) + +#define PIC32MZ_INT_IEC2 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC2_OFFSET) +#define PIC32MZ_INT_IEC2CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC2CLR_OFFSET) +#define PIC32MZ_INT_IEC2SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC2SET_OFFSET) +#define PIC32MZ_INT_IEC2INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC2INV_OFFSET) + +#define PIC32MZ_INT_IEC3 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC3_OFFSET) +#define PIC32MZ_INT_IEC3CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC3CLR_OFFSET) +#define PIC32MZ_INT_IEC3SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC3SET_OFFSET) +#define PIC32MZ_INT_IEC3INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC3INV_OFFSET) + +#define PIC32MZ_INT_IEC4 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC4_OFFSET) +#define PIC32MZ_INT_IEC4CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC4CLR_OFFSET) +#define PIC32MZ_INT_IEC4SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC4SET_OFFSET) +#define PIC32MZ_INT_IEC4INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC4INV_OFFSET) + +#define PIC32MZ_INT_IEC5 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC5_OFFSET) +#define PIC32MZ_INT_IEC5CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC5CLR_OFFSET) +#define PIC32MZ_INT_IEC5SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC5SET_OFFSET) +#define PIC32MZ_INT_IEC5INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IEC5INV_OFFSET) + +#define PIC32MZ_INT_IPC(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC_OFFSET(n)) +#define PIC32MZ_INT_IPCCLR(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPCCLR_OFFSET(n)) +#define PIC32MZ_INT_IPCSET(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPCSET_OFFSET(n)) +#define PIC32MZ_INT_IPCINV(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPCINV_OFFSET(n)) + +#define PIC32MZ_INT_IPC0 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC0_OFFSET) +#define PIC32MZ_INT_IPC0CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC0CLR_OFFSET) +#define PIC32MZ_INT_IPC0SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC0SET_OFFSET) +#define PIC32MZ_INT_IPC0INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC0INV_OFFSET) + +#define PIC32MZ_INT_IPC1 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC1_OFFSET) +#define PIC32MZ_INT_IPC1CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC1CLR_OFFSET) +#define PIC32MZ_INT_IPC1SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC1SET_OFFSET) +#define PIC32MZ_INT_IPC1INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC1INV_OFFSET) + +#define PIC32MZ_INT_IPC2 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC2_OFFSET) +#define PIC32MZ_INT_IPC2CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC2CLR_OFFSET) +#define PIC32MZ_INT_IPC2SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC2SET_OFFSET) +#define PIC32MZ_INT_IPC2INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC2INV_OFFSET) + +#define PIC32MZ_INT_IPC3 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC3_OFFSET) +#define PIC32MZ_INT_IPC3CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC3CLR_OFFSET) +#define PIC32MZ_INT_IPC3SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC3SET_OFFSET) +#define PIC32MZ_INT_IPC3INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC3INV_OFFSET) + +#define PIC32MZ_INT_IPC4 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC4_OFFSET) +#define PIC32MZ_INT_IPC4CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC4CLR_OFFSET) +#define PIC32MZ_INT_IPC4SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC4SET_OFFSET) +#define PIC32MZ_INT_IPC4INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC4INV_OFFSET) + +#define PIC32MZ_INT_IPC5 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC5_OFFSET) +#define PIC32MZ_INT_IPC5CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC5CLR_OFFSET) +#define PIC32MZ_INT_IPC5SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC5SET_OFFSET) +#define PIC32MZ_INT_IPC5INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC5INV_OFFSET) + +#define PIC32MZ_INT_IPC6 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC6_OFFSET) +#define PIC32MZ_INT_IPC6CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC6CLR_OFFSET) +#define PIC32MZ_INT_IPC6SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC6SET_OFFSET) +#define PIC32MZ_INT_IPC6INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC6INV_OFFSET) + +#define PIC32MZ_INT_IPC7 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC7_OFFSET) +#define PIC32MZ_INT_IPC7CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC7CLR_OFFSET) +#define PIC32MZ_INT_IPC7SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC7SET_OFFSET) +#define PIC32MZ_INT_IPC7INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC7INV_OFFSET) + +#define PIC32MZ_INT_IPC8 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC8_OFFSET) +#define PIC32MZ_INT_IPC8CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC8CLR_OFFSET) +#define PIC32MZ_INT_IPC8SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC8SET_OFFSET) +#define PIC32MZ_INT_IPC8INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC8INV_OFFSET) + +#define PIC32MZ_INT_IPC9 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC9_OFFSET) +#define PIC32MZ_INT_IPC9CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC9CLR_OFFSET) +#define PIC32MZ_INT_IPC9SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC9SET_OFFSET) +#define PIC32MZ_INT_IPC9INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC9INV_OFFSET) + +#define PIC32MZ_INT_IPC10 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC10_OFFSET) +#define PIC32MZ_INT_IPC10CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC10CLR_OFFSET) +#define PIC32MZ_INT_IPC10SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC10SET_OFFSET) +#define PIC32MZ_INT_IPC10INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC10INV_OFFSET) + +#define PIC32MZ_INT_IPC11 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC11_OFFSET) +#define PIC32MZ_INT_IPC11CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC11CLR_OFFSET) +#define PIC32MZ_INT_IPC11SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC11SET_OFFSET) +#define PIC32MZ_INT_IPC11INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC11INV_OFFSET) + +#define PIC32MZ_INT_IPC12 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC12_OFFSET) +#define PIC32MZ_INT_IPC12CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC12CLR_OFFSET) +#define PIC32MZ_INT_IPC12SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC12SET_OFFSET) +#define PIC32MZ_INT_IPC12INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC12INV_OFFSET) + +#define PIC32MZ_INT_IPC13 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC13_OFFSET) +#define PIC32MZ_INT_IPC13CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC13CLR_OFFSET) +#define PIC32MZ_INT_IPC13SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC13SET_OFFSET) +#define PIC32MZ_INT_IPC13INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC13INV_OFFSET) + +#define PIC32MZ_INT_IPC14 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC14_OFFSET) +#define PIC32MZ_INT_IPC14CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC14CLR_OFFSET) +#define PIC32MZ_INT_IPC14SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC14SET_OFFSET) +#define PIC32MZ_INT_IPC14INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC14INV_OFFSET) + +#define PIC32MZ_INT_IPC15 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC15_OFFSET) +#define PIC32MZ_INT_IPC15CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC15CLR_OFFSET) +#define PIC32MZ_INT_IPC15SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC15SET_OFFSET) +#define PIC32MZ_INT_IPC15INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC15INV_OFFSET) + +#define PIC32MZ_INT_IPC16 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC16_OFFSET) +#define PIC32MZ_INT_IPC16CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC16CLR_OFFSET) +#define PIC32MZ_INT_IPC16SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC16SET_OFFSET) +#define PIC32MZ_INT_IPC16INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC16INV_OFFSET) + +#define PIC32MZ_INT_IPC17 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC17_OFFSET) +#define PIC32MZ_INT_IPC17CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC17CLR_OFFSET) +#define PIC32MZ_INT_IPC17SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC17SET_OFFSET) +#define PIC32MZ_INT_IPC17INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC17INV_OFFSET) + +#define PIC32MZ_INT_IPC18 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC18_OFFSET) +#define PIC32MZ_INT_IPC18CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC18CLR_OFFSET) +#define PIC32MZ_INT_IPC18SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC18SET_OFFSET) +#define PIC32MZ_INT_IPC18INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC18INV_OFFSET) + +#define PIC32MZ_INT_IPC19 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC19_OFFSET) +#define PIC32MZ_INT_IPC19CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC19CLR_OFFSET) +#define PIC32MZ_INT_IPC19SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC19SET_OFFSET) +#define PIC32MZ_INT_IPC19INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC19INV_OFFSET) + +#define PIC32MZ_INT_IPC20 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC20_OFFSET) +#define PIC32MZ_INT_IPC20CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC20CLR_OFFSET) +#define PIC32MZ_INT_IPC20SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC20SET_OFFSET) +#define PIC32MZ_INT_IPC20INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC20INV_OFFSET) + +#define PIC32MZ_INT_IPC21 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC21_OFFSET) +#define PIC32MZ_INT_IPC21CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC21CLR_OFFSET) +#define PIC32MZ_INT_IPC21SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC21SET_OFFSET) +#define PIC32MZ_INT_IPC21INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC21INV_OFFSET) + +#define PIC32MZ_INT_IPC22 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC22_OFFSET) +#define PIC32MZ_INT_IPC22CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC22CLR_OFFSET) +#define PIC32MZ_INT_IPC22SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC22SET_OFFSET) +#define PIC32MZ_INT_IPC22INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC22INV_OFFSET) + +#define PIC32MZ_INT_IPC23 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC23_OFFSET) +#define PIC32MZ_INT_IPC23CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC23CLR_OFFSET) +#define PIC32MZ_INT_IPC23SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC23SET_OFFSET) +#define PIC32MZ_INT_IPC23INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC23INV_OFFSET) + +#define PIC32MZ_INT_IPC24 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC24_OFFSET) +#define PIC32MZ_INT_IPC24CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC24CLR_OFFSET) +#define PIC32MZ_INT_IPC24SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC24SET_OFFSET) +#define PIC32MZ_INT_IPC24INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC24INV_OFFSET) + +#define PIC32MZ_INT_IPC25 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC25_OFFSET) +#define PIC32MZ_INT_IPC25CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC25CLR_OFFSET) +#define PIC32MZ_INT_IPC25SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC25SET_OFFSET) +#define PIC32MZ_INT_IPC25INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC25INV_OFFSET) + +#define PIC32MZ_INT_IPC26 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC26_OFFSET) +#define PIC32MZ_INT_IPC26CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC26CLR_OFFSET) +#define PIC32MZ_INT_IPC26SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC26SET_OFFSET) +#define PIC32MZ_INT_IPC26INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC26INV_OFFSET) + +#define PIC32MZ_INT_IPC27 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC27_OFFSET) +#define PIC32MZ_INT_IPC27CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC27CLR_OFFSET) +#define PIC32MZ_INT_IPC27SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC27SET_OFFSET) +#define PIC32MZ_INT_IPC27INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC27INV_OFFSET) + +#define PIC32MZ_INT_IPC28 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC28_OFFSET) +#define PIC32MZ_INT_IPC28CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC28CLR_OFFSET) +#define PIC32MZ_INT_IPC28SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC28SET_OFFSET) +#define PIC32MZ_INT_IPC28INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC28INV_OFFSET) + +#define PIC32MZ_INT_IPC29 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC29_OFFSET) +#define PIC32MZ_INT_IPC29CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC29CLR_OFFSET) +#define PIC32MZ_INT_IPC29SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC29SET_OFFSET) +#define PIC32MZ_INT_IPC29INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC29INV_OFFSET) + +#define PIC32MZ_INT_IPC30 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC30_OFFSET) +#define PIC32MZ_INT_IPC30CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC30CLR_OFFSET) +#define PIC32MZ_INT_IPC30SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC30SET_OFFSET) +#define PIC32MZ_INT_IPC30INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC30INV_OFFSET) + +#define PIC32MZ_INT_IPC31 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC31_OFFSET) +#define PIC32MZ_INT_IPC31CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC31CLR_OFFSET) +#define PIC32MZ_INT_IPC31SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC31SET_OFFSET) +#define PIC32MZ_INT_IPC31INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC31INV_OFFSET) + +#define PIC32MZ_INT_IPC32 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC32_OFFSET) +#define PIC32MZ_INT_IPC32CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC32CLR_OFFSET) +#define PIC32MZ_INT_IPC32SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC32SET_OFFSET) +#define PIC32MZ_INT_IPC32INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC32INV_OFFSET) + +#define PIC32MZ_INT_IPC33 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC33_OFFSET) +#define PIC32MZ_INT_IPC33CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC33CLR_OFFSET) +#define PIC32MZ_INT_IPC33SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC33SET_OFFSET) +#define PIC32MZ_INT_IPC33INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC33INV_OFFSET) + +#define PIC32MZ_INT_IPC34 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC34_OFFSET) +#define PIC32MZ_INT_IPC34CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC34CLR_OFFSET) +#define PIC32MZ_INT_IPC34SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC34SET_OFFSET) +#define PIC32MZ_INT_IPC34INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC34INV_OFFSET) + +#define PIC32MZ_INT_IPC35 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC35_OFFSET) +#define PIC32MZ_INT_IPC35CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC35CLR_OFFSET) +#define PIC32MZ_INT_IPC35SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC35SET_OFFSET) +#define PIC32MZ_INT_IPC35INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC35INV_OFFSET) + +#define PIC32MZ_INT_IPC36 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC36_OFFSET) +#define PIC32MZ_INT_IPC36CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC36CLR_OFFSET) +#define PIC32MZ_INT_IPC36SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC36SET_OFFSET) +#define PIC32MZ_INT_IPC36INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC36INV_OFFSET) + +#define PIC32MZ_INT_IPC37 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC37_OFFSET) +#define PIC32MZ_INT_IPC37CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC37CLR_OFFSET) +#define PIC32MZ_INT_IPC37SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC37SET_OFFSET) +#define PIC32MZ_INT_IPC37INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC37INV_OFFSET) + +#define PIC32MZ_INT_IPC38 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC38_OFFSET) +#define PIC32MZ_INT_IPC38CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC38CLR_OFFSET) +#define PIC32MZ_INT_IPC38SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC38SET_OFFSET) +#define PIC32MZ_INT_IPC38INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC38INV_OFFSET) + +#define PIC32MZ_INT_IPC39 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC39_OFFSET) +#define PIC32MZ_INT_IPC39CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC39CLR_OFFSET) +#define PIC32MZ_INT_IPC39SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC39SET_OFFSET) +#define PIC32MZ_INT_IPC39INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC39INV_OFFSET) + +#define PIC32MZ_INT_IPC40 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC40_OFFSET) +#define PIC32MZ_INT_IPC40CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC40CLR_OFFSET) +#define PIC32MZ_INT_IPC40SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC40SET_OFFSET) +#define PIC32MZ_INT_IPC40INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC40INV_OFFSET) + +#define PIC32MZ_INT_IPC41 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC41_OFFSET) +#define PIC32MZ_INT_IPC41CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC41CLR_OFFSET) +#define PIC32MZ_INT_IPC41SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC41SET_OFFSET) +#define PIC32MZ_INT_IPC41INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC41INV_OFFSET) + +#define PIC32MZ_INT_IPC42 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC42_OFFSET) +#define PIC32MZ_INT_IPC42CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC42CLR_OFFSET) +#define PIC32MZ_INT_IPC42SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC42SET_OFFSET) +#define PIC32MZ_INT_IPC42INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC42INV_OFFSET) + +#define PIC32MZ_INT_IPC43 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC43_OFFSET) +#define PIC32MZ_INT_IPC43CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC43CLR_OFFSET) +#define PIC32MZ_INT_IPC43SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC43SET_OFFSET) +#define PIC32MZ_INT_IPC43INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC43INV_OFFSET) + +#define PIC32MZ_INT_IPC44 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC44_OFFSET) +#define PIC32MZ_INT_IPC44CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC44CLR_OFFSET) +#define PIC32MZ_INT_IPC44SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC44SET_OFFSET) +#define PIC32MZ_INT_IPC44INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC44INV_OFFSET) + +#define PIC32MZ_INT_IPC45 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC45_OFFSET) +#define PIC32MZ_INT_IPC45CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC45CLR_OFFSET) +#define PIC32MZ_INT_IPC45SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC45SET_OFFSET) +#define PIC32MZ_INT_IPC45INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC45INV_OFFSET) + +#define PIC32MZ_INT_IPC46 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC46_OFFSET) +#define PIC32MZ_INT_IPC46CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC46CLR_OFFSET) +#define PIC32MZ_INT_IPC46SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC46SET_OFFSET) +#define PIC32MZ_INT_IPC46INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC46INV_OFFSET) + +#define PIC32MZ_INT_IPC47 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC47_OFFSET) +#define PIC32MZ_INT_IPC47CLR (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC47CLR_OFFSET) +#define PIC32MZ_INT_IPC47SET (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC47SET_OFFSET) +#define PIC32MZ_INT_IPC47INV (PIC32MZ_INT_K1BASE+PIC32MZ_INT_IPC47INV_OFFSET) + +#define PIC32MZ_INT_OFF(n) (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF_OFFSET(n) +#define PIC32MZ_INT_OFF000 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF000_OFFSET) +#define PIC32MZ_INT_OFF001 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF001_OFFSET) +#define PIC32MZ_INT_OFF002 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF002_OFFSET) +#define PIC32MZ_INT_OFF003 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF003_OFFSET) +#define PIC32MZ_INT_OFF004 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF004_OFFSET) +#define PIC32MZ_INT_OFF005 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF005_OFFSET) +#define PIC32MZ_INT_OFF006 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF006_OFFSET) +#define PIC32MZ_INT_OFF007 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF007_OFFSET) +#define PIC32MZ_INT_OFF008 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF008_OFFSET) +#define PIC32MZ_INT_OFF009 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF009_OFFSET) +#define PIC32MZ_INT_OFF010 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF010_OFFSET) +#define PIC32MZ_INT_OFF011 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF011_OFFSET) +#define PIC32MZ_INT_OFF012 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF012_OFFSET) +#define PIC32MZ_INT_OFF013 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF013_OFFSET) +#define PIC32MZ_INT_OFF014 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF014_OFFSET) +#define PIC32MZ_INT_OFF015 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF015_OFFSET) + +#define PIC32MZ_INT_OFF016 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF016_OFFSET) +#define PIC32MZ_INT_OFF017 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF017_OFFSET) +#define PIC32MZ_INT_OFF018 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF018_OFFSET) +#define PIC32MZ_INT_OFF019 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF019_OFFSET) +#define PIC32MZ_INT_OFF020 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF020_OFFSET) +#define PIC32MZ_INT_OFF021 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF021_OFFSET) +#define PIC32MZ_INT_OFF022 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF022_OFFSET) +#define PIC32MZ_INT_OFF023 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF023_OFFSET) +#define PIC32MZ_INT_OFF024 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF024_OFFSET) +#define PIC32MZ_INT_OFF025 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF025_OFFSET) +#define PIC32MZ_INT_OFF026 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF026_OFFSET) +#define PIC32MZ_INT_OFF027 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF027_OFFSET) +#define PIC32MZ_INT_OFF028 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF028_OFFSET) +#define PIC32MZ_INT_OFF029 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF029_OFFSET) +#define PIC32MZ_INT_OFF030 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF030_OFFSET) +#define PIC32MZ_INT_OFF031 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF031_OFFSET) + +#define PIC32MZ_INT_OFF032 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF032_OFFSET) +#define PIC32MZ_INT_OFF033 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF033_OFFSET) +#define PIC32MZ_INT_OFF034 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF034_OFFSET) +#define PIC32MZ_INT_OFF035 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF035_OFFSET) +#define PIC32MZ_INT_OFF036 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF036_OFFSET) +#define PIC32MZ_INT_OFF037 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF037_OFFSET) +#define PIC32MZ_INT_OFF038 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF038_OFFSET) +#define PIC32MZ_INT_OFF039 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF039_OFFSET) +#define PIC32MZ_INT_OFF040 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF040_OFFSET) +#define PIC32MZ_INT_OFF041 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF041_OFFSET) +#define PIC32MZ_INT_OFF042 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF042_OFFSET) +#define PIC32MZ_INT_OFF043 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF043_OFFSET) +#define PIC32MZ_INT_OFF044 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF044_OFFSET) +#define PIC32MZ_INT_OFF045 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF045_OFFSET) +#define PIC32MZ_INT_OFF046 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF046_OFFSET) +#define PIC32MZ_INT_OFF047 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF047_OFFSET) + +#define PIC32MZ_INT_OFF048 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF048_OFFSET) +#define PIC32MZ_INT_OFF049 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF049_OFFSET) +#define PIC32MZ_INT_OFF050 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF050_OFFSET) +#define PIC32MZ_INT_OFF051 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF051_OFFSET) +#define PIC32MZ_INT_OFF052 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF052_OFFSET) +#define PIC32MZ_INT_OFF053 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF053_OFFSET) +#define PIC32MZ_INT_OFF054 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF054_OFFSET) +#define PIC32MZ_INT_OFF055 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF055_OFFSET) +#define PIC32MZ_INT_OFF056 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF056_OFFSET) +#define PIC32MZ_INT_OFF057 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF057_OFFSET) +#define PIC32MZ_INT_OFF058 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF058_OFFSET) +#define PIC32MZ_INT_OFF059 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF059_OFFSET) +#define PIC32MZ_INT_OFF060 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF060_OFFSET) +#define PIC32MZ_INT_OFF061 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF061_OFFSET) +#define PIC32MZ_INT_OFF062 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF062_OFFSET) +#define PIC32MZ_INT_OFF063 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF063_OFFSET) + +#define PIC32MZ_INT_OFF064 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF064_OFFSET) +#define PIC32MZ_INT_OFF065 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF065_OFFSET) +#define PIC32MZ_INT_OFF066 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF066_OFFSET) +#define PIC32MZ_INT_OFF067 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF067_OFFSET) +#define PIC32MZ_INT_OFF068 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF068_OFFSET) +#define PIC32MZ_INT_OFF069 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF069_OFFSET) +#define PIC32MZ_INT_OFF070 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF070_OFFSET) +#define PIC32MZ_INT_OFF071 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF071_OFFSET) +#define PIC32MZ_INT_OFF072 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF072_OFFSET) +#define PIC32MZ_INT_OFF073 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF073_OFFSET) +#define PIC32MZ_INT_OFF074 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF074_OFFSET) +#define PIC32MZ_INT_OFF075 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF075_OFFSET) +#define PIC32MZ_INT_OFF076 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF076_OFFSET) +#define PIC32MZ_INT_OFF077 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF077_OFFSET) +#define PIC32MZ_INT_OFF078 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF078_OFFSET) +#define PIC32MZ_INT_OFF079 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF079_OFFSET) + +#define PIC32MZ_INT_OFF080 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF080_OFFSET) +#define PIC32MZ_INT_OFF081 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF081_OFFSET) +#define PIC32MZ_INT_OFF082 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF082_OFFSET) +#define PIC32MZ_INT_OFF083 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF083_OFFSET) +#define PIC32MZ_INT_OFF084 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF084_OFFSET) +#define PIC32MZ_INT_OFF085 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF085_OFFSET) +#define PIC32MZ_INT_OFF086 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF086_OFFSET) +#define PIC32MZ_INT_OFF087 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF087_OFFSET) +#define PIC32MZ_INT_OFF088 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF088_OFFSET) +#define PIC32MZ_INT_OFF089 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF089_OFFSET) +#define PIC32MZ_INT_OFF090 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF090_OFFSET) +#define PIC32MZ_INT_OFF091 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF091_OFFSET) +#define PIC32MZ_INT_OFF092 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF092_OFFSET) +#define PIC32MZ_INT_OFF093 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF093_OFFSET) +#define PIC32MZ_INT_OFF094 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF094_OFFSET) +#define PIC32MZ_INT_OFF095 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF095_OFFSET) + +#define PIC32MZ_INT_OFF096 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF096_OFFSET) +#define PIC32MZ_INT_OFF097 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF097_OFFSET) +#define PIC32MZ_INT_OFF098 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF098_OFFSET) +#define PIC32MZ_INT_OFF099 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF099_OFFSET) +#define PIC32MZ_INT_OFF100 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF100_OFFSET) +#define PIC32MZ_INT_OFF101 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF101_OFFSET) +#define PIC32MZ_INT_OFF102 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF102_OFFSET) +#define PIC32MZ_INT_OFF103 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF103_OFFSET) +#define PIC32MZ_INT_OFF104 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF104_OFFSET) +#define PIC32MZ_INT_OFF105 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF105_OFFSET) +#define PIC32MZ_INT_OFF106 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF106_OFFSET) +#define PIC32MZ_INT_OFF107 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF107_OFFSET) +#define PIC32MZ_INT_OFF108 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF108_OFFSET) +#define PIC32MZ_INT_OFF109 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF109_OFFSET) +#define PIC32MZ_INT_OFF110 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF110_OFFSET) +#define PIC32MZ_INT_OFF111 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF111_OFFSET) + +#define PIC32MZ_INT_OFF112 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF112_OFFSET) +#define PIC32MZ_INT_OFF113 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF113_OFFSET) +#define PIC32MZ_INT_OFF114 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF114_OFFSET) +#define PIC32MZ_INT_OFF115 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF115_OFFSET) +#define PIC32MZ_INT_OFF116 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF116_OFFSET) +#define PIC32MZ_INT_OFF117 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF117_OFFSET) +#define PIC32MZ_INT_OFF118 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF118_OFFSET) +#define PIC32MZ_INT_OFF119 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF119_OFFSET) +#define PIC32MZ_INT_OFF120 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF120_OFFSET) +#define PIC32MZ_INT_OFF121 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF121_OFFSET) +#define PIC32MZ_INT_OFF122 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF122_OFFSET) +#define PIC32MZ_INT_OFF123 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF123_OFFSET) +#define PIC32MZ_INT_OFF124 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF124_OFFSET) +#define PIC32MZ_INT_OFF125 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF125_OFFSET) +#define PIC32MZ_INT_OFF126 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF126_OFFSET) +#define PIC32MZ_INT_OFF127 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF127_OFFSET) + +#define PIC32MZ_INT_OFF128 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF128_OFFSET) +#define PIC32MZ_INT_OFF129 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF129_OFFSET) +#define PIC32MZ_INT_OFF130 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF130_OFFSET) +#define PIC32MZ_INT_OFF131 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF131_OFFSET) +#define PIC32MZ_INT_OFF132 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF132_OFFSET) +#define PIC32MZ_INT_OFF133 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF133_OFFSET) +#define PIC32MZ_INT_OFF134 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF134_OFFSET) +#define PIC32MZ_INT_OFF135 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF135_OFFSET) +#define PIC32MZ_INT_OFF136 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF136_OFFSET) +#define PIC32MZ_INT_OFF137 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF137_OFFSET) +#define PIC32MZ_INT_OFF138 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF138_OFFSET) +#define PIC32MZ_INT_OFF139 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF139_OFFSET) +#define PIC32MZ_INT_OFF140 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF140_OFFSET) +#define PIC32MZ_INT_OFF141 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF141_OFFSET) +#define PIC32MZ_INT_OFF142 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF142_OFFSET) +#define PIC32MZ_INT_OFF143 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF143_OFFSET) + +#define PIC32MZ_INT_OFF144 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF144_OFFSET) +#define PIC32MZ_INT_OFF145 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF145_OFFSET) +#define PIC32MZ_INT_OFF146 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF146_OFFSET) +#define PIC32MZ_INT_OFF147 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF147_OFFSET) +#define PIC32MZ_INT_OFF148 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF148_OFFSET) +#define PIC32MZ_INT_OFF149 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF149_OFFSET) +#define PIC32MZ_INT_OFF150 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF150_OFFSET) +#define PIC32MZ_INT_OFF151 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF151_OFFSET) +#define PIC32MZ_INT_OFF152 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF152_OFFSET) +#define PIC32MZ_INT_OFF153 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF153_OFFSET) +#define PIC32MZ_INT_OFF154 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF154_OFFSET) +#define PIC32MZ_INT_OFF155 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF155_OFFSET) +#define PIC32MZ_INT_OFF156 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF156_OFFSET) +#define PIC32MZ_INT_OFF157 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF157_OFFSET) +#define PIC32MZ_INT_OFF158 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF158_OFFSET) +#define PIC32MZ_INT_OFF159 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF159_OFFSET) + +#define PIC32MZ_INT_OFF160 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF160_OFFSET) +#define PIC32MZ_INT_OFF161 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF161_OFFSET) +#define PIC32MZ_INT_OFF162 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF162_OFFSET) +#define PIC32MZ_INT_OFF163 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF163_OFFSET) +#define PIC32MZ_INT_OFF164 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF164_OFFSET) +#define PIC32MZ_INT_OFF165 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF165_OFFSET) +#define PIC32MZ_INT_OFF166 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF166_OFFSET) +#define PIC32MZ_INT_OFF167 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF167_OFFSET) +#define PIC32MZ_INT_OFF168 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF168_OFFSET) +#define PIC32MZ_INT_OFF169 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF169_OFFSET) +#define PIC32MZ_INT_OFF170 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF170_OFFSET) +#define PIC32MZ_INT_OFF171 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF171_OFFSET) +#define PIC32MZ_INT_OFF172 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF172_OFFSET) +#define PIC32MZ_INT_OFF173 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF173_OFFSET) +#define PIC32MZ_INT_OFF174 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF174_OFFSET) +#define PIC32MZ_INT_OFF175 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF175_OFFSET) + +#define PIC32MZ_INT_OFF176 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF176_OFFSET) +#define PIC32MZ_INT_OFF177 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF177_OFFSET) +#define PIC32MZ_INT_OFF178 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF178_OFFSET) +#define PIC32MZ_INT_OFF179 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF179_OFFSET) +#define PIC32MZ_INT_OFF180 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF180_OFFSET) +#define PIC32MZ_INT_OFF181 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF181_OFFSET) +#define PIC32MZ_INT_OFF182 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF182_OFFSET) +#define PIC32MZ_INT_OFF183 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF183_OFFSET) +#define PIC32MZ_INT_OFF184 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF184_OFFSET) +#define PIC32MZ_INT_OFF185 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF185_OFFSET) +#define PIC32MZ_INT_OFF186 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF186_OFFSET) +#define PIC32MZ_INT_OFF187 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF187_OFFSET) +#define PIC32MZ_INT_OFF188 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF188_OFFSET) +#define PIC32MZ_INT_OFF189 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF189_OFFSET) +#define PIC32MZ_INT_OFF190 (PIC32MZ_INT_K1BASE+PIC32MZ_INT_OFF190_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ + +/* Interrupt control register */ + +#define INT_INTCON_INT0EP (1 << 0) /* Bit 0: External interrupt 0 edge polarity control */ +#define INT_INTCON_INT1EP (1 << 1) /* Bit 1: External interrupt 1 edge polarity control */ +#define INT_INTCON_INT2EP (1 << 2) /* Bit 2: External interrupt 2 edge polarity control */ +#define INT_INTCON_INT3EP (1 << 3) /* Bit 3: External interrupt 3 edge polarity control */ +#define INT_INTCON_INT4EP (1 << 4) /* Bit 4: External interrupt 4 edge polarity control */ +#define INT_INTCON_TPC_SHIFT (8) /* Bits 8-10: Interrupt proximity timer control */ +#define INT_INTCON_TPC_MASK (7 << INT_INTCON_TPC_SHIFT) +# define INT_INTCON_TPC_DIS (0 << INT_INTCON_TPC_SHIFT) /* Disables proximity timer */ +# define INT_INTCON_TPC_PRIO1 (1 << INT_INTCON_TPC_SHIFT) /* Int group priority 1 start IP timer */ +# define INT_INTCON_TPC_PRIO2 (2 << INT_INTCON_TPC_SHIFT) /* Int group priority <=2 start TP timer */ +# define INT_INTCON_TPC_PRIO3 (3 << INT_INTCON_TPC_SHIFT) /* Int group priority <=3 start TP timer */ +# define INT_INTCON_TPC_PRIO4 (4 << INT_INTCON_TPC_SHIFT) /* Int group priority <=4 start TP timer */ +# define INT_INTCON_TPC_PRIO5 (5 << INT_INTCON_TPC_SHIFT) /* Int group priority <=5 start TP timer */ +# define INT_INTCON_TPC_PRIO6 (6 << INT_INTCON_TPC_SHIFT) /* Int group priority <=6 start TP timer */ +# define INT_INTCON_TPC_PRIO7 (7 << INT_INTCON_TPC_SHIFT) /* Int group priority <=7 start TP timer */ +#define INT_INTCON_MVEC (1 << 12) /* Bit 12: Multi vector configuration */ + +/* Priority shadow select register */ + +#define INT_PRISS_SS0 (1 << 0) /* Bit 0: Single Vector Shadow Register Set bit */ +#define INT_PRISS_PRI1SS_SHIFT (4) /* Bits 4-7: Interrupt with Priority Level 1 Shadow Set bits */ +#define INT_PRISS_PRI1SS_MASK (15 << INT_PRISS_PRI1SS_SHIFT) +# define INT_PRISS_PRI1SS(n) ((uint32_t)(n) << INT_PRISS_PRI1SS_SHIFT) +#define INT_PRISS_PRI2SS_SHIFT (8) /* Bits 8-11: Interrupt with Priority Level 2 Shadow Set bits */ +#define INT_PRISS_PRI2SS_MASK (15 << INT_PRISS_PRI2SS_SHIFT) +# define INT_PRISS_PRI2SS(n) ((uint32_t)(n) << INT_PRISS_PRI2SS_SHIFT) +#define INT_PRISS_PRI3SS_SHIFT (12) /* Bits 12-15: Interrupt with Priority Level 3 Shadow Set bits */ +#define INT_PRISS_PRI3SS_MASK (15 << INT_PRISS_PRI3SS_SHIFT) +# define INT_PRISS_PRI3SS(n) ((uint32_t)(n) << INT_PRISS_PRI3SS_SHIFT) +#define INT_PRISS_PRI4SS_SHIFT (16) /* Bits 16-19: Interrupt with Priority Level 4 Shadow Set bits */ +#define INT_PRISS_PRI4SS_MASK (15 << INT_PRISS_PRI4SS_SHIFT) +# define INT_PRISS_PRI4SS(n) ((uint32_t)(n) << INT_PRISS_PRI4SS_SHIFT) +#define INT_PRISS_PRI5SS_SHIFT (20) /* Bits 20-23: Interrupt with Priority Level 5 Shadow Set bits */ +#define INT_PRISS_PRI5SS_MASK (15 << INT_PRISS_PRI5SS_SHIFT) +# define INT_PRISS_PRI5SS(n) ((uint32_t)(n) << INT_PRISS_PRI5SS_SHIFT) +#define INT_PRISS_PRI6SS_SHIFT (24) /* Bits 24-27: Interrupt with Priority Level 6 Shadow Set bits */ +#define INT_PRISS_PRI6SS_MASK (15 << INT_PRISS_PRI6SS_SHIFT) +# define INT_PRISS_PRI6SS(n) ((uint32_t)(n) << INT_PRISS_PRI6SS_SHIFT) +#define INT_PRISS_PRI7SS_SHIFT (28) /* Bits 28-31: Interrupt with Priority Level 7 Shadow Set bits */ +#define INT_PRISS_PRI7SS_MASK (15 << INT_PRISS_PRI7SS_SHIFT) +# define INT_PRISS_PRI7SS(n) ((uint32_t)(n) << INT_PRISS_PRI7SS_SHIFT) + +/* Interrupt status register */ + +#define INT_INTSTAT_SIRQ_SHIFT (0) /* Bits 0-7: Last Interrupt Request Serviced Status */ +#define INT_INTSTAT_SIRQ_MASK (0xff << INT_INTSTAT_SIRQ_SHIFT) +#define INT_INTSTAT_SRIPL_SHIFT (8) /* Bits 8-10: Requested Priority Level (Single Vector Mode) */ +#define INT_INTSTAT_SRIPL_MASK (7 << INT_INTSTAT_SRIPL_SHIFT) + +/* Interrupt proximity timer register -- This register contains a 32-bit + * reload value with no field definitions. + */ + +/* Interrupt flag status register 0-5 and Interrupt enable control register 0-5 + * Contains interrupt status/control bits, one for each interrupt: + * + * IFS0/IEC0 - Interrupts 0-31 + * IFS1/IEC1 - Interrupts 32-63 + * IFS2/IEC2 - Interrupts 64-95 + * IFS3/IEC3 - Interrupts 96-127 + * IFS4/IEC4 - Interrupts 128-159 + * IFS5/IEC5 - Interrupts 160-190 + */ + +/* Interrupt priority control register 0-47 */ + +#define INT_IPC_DISABLED 0 /* Disabled! */ +#define INT_IPC_MIN_PRIORITY 1 /* Minimum (enabled) priority */ +#define INT_IPC_MID_PRIORITY 4 /* Can be used as the default */ +#define INT_IPC_MAX_PRIORITY 7 /* Maximum priority */ + +/* Each of the 48 IPC register contains controls for 4 interrupts */ + +#define INT_IPC_REGNDX(n) ((n) >> 2) +#define INT_IPC_REGOFFSET(n) ((n) & 3) +#define INT_IOC_REGADDR(n) PIC32MZ_INT_IPC(INT_IPC_REGNDX(n)) + +/* Interrupt sub-priority (IS) field is aligned at bits 0, 8, 16, and 24 in + * each IPC register + */ + +#define INT_IPC_MIN_SUBPRIORITY 0 /* Minimum sub-priority */ +#define INT_IPC_MAX_SUBPRIORITY 0 /* Maximum sub-priority */ + +#define INT_IPC_IS_SHIFT(n) (INT_IPC_REGOFFSET(n) << 3) +#define INT_IPC_IS_MASK(n) (3 << INT_IPC_IS_SHIFT(n)) + +/* Interrupt priority (IP) field is aligned at bits 2, 10, 18, and 26 in + * each IPC register + */ + +#define INT_IPC_IP_SHIFT(n) (2 + (INT_IPC_REGOFFSET(n) << 3)) +#define INT_IPC_IP_MASK(n) (7 << INT_IPC_IP_SHIFT(n)) + +/* Interrupt vector n address address offset, n=0-190 */ + +#define INT_OFF_VOFF_SHIFT (0) /* Bits 1-17: Interrupt vector address offset */ +#define INT_OFF_VOFF_MASK (0x3fffe << INT_OFF_VOFF_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_INT_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-ioport.h b/arch/mips/src/pic32mz/chip/pic32mz-ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..43336e7df29462e66148cc03a6dfe58e52599334 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-ioport.h @@ -0,0 +1,868 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/pic32mz-ioport.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_IOPORT_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_IOPORT_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include +#include +#include "pic32mz-memorymap.h" + +#if CHIP_NPORTS > 0 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* IOPort Peripheral Offsets ****************************************************************/ + +#define PIC32MZ_IOPORTA 0 +#define PIC32MZ_IOPORTB 1 +#define PIC32MZ_IOPORTC 2 +#define PIC32MZ_IOPORTD 3 +#define PIC32MZ_IOPORTE 4 +#define PIC32MZ_IOPORTF 5 +#define PIC32MZ_IOPORTG 6 +#define PIC32MZ_IOPORTH 7 +#define PIC32MZ_IOPORTJ 8 +#define PIC32MZ_IOPORTK 9 + +#define PIC32MZ_IOPORTn_OFFSET(n) ((n)<<8) +# define PIC32MZ_IOPORTA_OFFSET 0x0000 +# define PIC32MZ_IOPORTB_OFFSET 0x0100 +# define PIC32MZ_IOPORTC_OFFSET 0x0200 +# define PIC32MZ_IOPORTD_OFFSET 0x0300 +# define PIC32MZ_IOPORTE_OFFSET 0x0400 +# define PIC32MZ_IOPORTF_OFFSET 0x0500 +# define PIC32MZ_IOPORTG_OFFSET 0x0600 +# define PIC32MZ_IOPORTH_OFFSET 0x0700 +# define PIC32MZ_IOPORTJ_OFFSET 0x0800 +# define PIC32MZ_IOPORTK_OFFSET 0x0900 + +/* Register Offsets *************************************************************************/ + +#define PIC32MZ_IOPORT_ANSEL_OFFSET 0x0000 /* Analog select register */ +#define PIC32MZ_IOPORT_ANSELCLR_OFFSET 0x0004 /* Analog select clear register */ +#define PIC32MZ_IOPORT_ANSELSET_OFFSET 0x0008 /* Analog select set register */ +#define PIC32MZ_IOPORT_ANSELINV_OFFSET 0x000c /* Analog select invert register */ + +#define PIC32MZ_IOPORT_TRIS_OFFSET 0x0010 /* Tri-state register */ +#define PIC32MZ_IOPORT_TRISCLR_OFFSET 0x0014 /* Tri-state clear register */ +#define PIC32MZ_IOPORT_TRISSET_OFFSET 0x0018 /* Tri-state set register */ +#define PIC32MZ_IOPORT_TRISINV_OFFSET 0x001c /* Tri-state invert register */ + +#define PIC32MZ_IOPORT_PORT_OFFSET 0x0020 /* Port register */ +#define PIC32MZ_IOPORT_PORTCLR_OFFSET 0x0024 /* Port clear register */ +#define PIC32MZ_IOPORT_PORTSET_OFFSET 0x0028 /* Port set register */ +#define PIC32MZ_IOPORT_PORTINV_OFFSET 0x002c /* Port invert register */ + +#define PIC32MZ_IOPORT_LAT_OFFSET 0x0030 /* Port data latch register */ +#define PIC32MZ_IOPORT_LATCLR_OFFSET 0x0034 /* Port data latch clear register */ +#define PIC32MZ_IOPORT_LATSET_OFFSET 0x0038 /* Port data latch set register */ +#define PIC32MZ_IOPORT_LATINV_OFFSET 0x003c /* Port data latch invert register */ + +#define PIC32MZ_IOPORT_ODC_OFFSET 0x0040 /* Open drain control register */ +#define PIC32MZ_IOPORT_ODCCLR_OFFSET 0x0044 /* Open drain control clear register */ +#define PIC32MZ_IOPORT_ODCSET_OFFSET 0x0048 /* Open drain control set register */ +#define PIC32MZ_IOPORT_ODCINV_OFFSET 0x004c /* Open drain control invert register */ + +#define PIC32MZ_IOPORT_CNPU_OFFSET 0x0050 /* Change Notice Pull-up register */ +#define PIC32MZ_IOPORT_CNPUCLR_OFFSET 0x0054 /* Change Notice Pull-up clear register */ +#define PIC32MZ_IOPORT_CNPUSET_OFFSET 0x0058 /* Change Notice Pull-up set register */ +#define PIC32MZ_IOPORT_CNPUINV_OFFSET 0x005c /* Change Notice Pull-up invert register */ + +#define PIC32MZ_IOPORT_CNPD_OFFSET 0x0060 /* Change Notice Pull-down register */ +#define PIC32MZ_IOPORT_CNPDCLR_OFFSET 0x0064 /* Change Notice Pull-down clear register */ +#define PIC32MZ_IOPORT_CNPDSET_OFFSET 0x0068 /* Change Notice Pull-down set register */ +#define PIC32MZ_IOPORT_CNPDINV_OFFSET 0x006c /* Change Notice Pull-down invert register */ + +#define PIC32MZ_IOPORT_CNCON_OFFSET 0x0070 /* Change Notice Control register */ +#define PIC32MZ_IOPORT_CNCONCLR_OFFSET 0x0074 /* Change Notice Control clear register */ +#define PIC32MZ_IOPORT_CNCONSET_OFFSET 0x0078 /* Change Notice Control set register */ +#define PIC32MZ_IOPORT_CNCONINV_OFFSET 0x007c /* Change Notice Control invert register */ + +#define PIC32MZ_IOPORT_CNEN_OFFSET 0x0080 /* Change Notice Interrupt Enable register */ +#define PIC32MZ_IOPORT_CNENCLR_OFFSET 0x0084 /* Change Notice Interrupt Enable clear register */ +#define PIC32MZ_IOPORT_CNENSET_OFFSET 0x0088 /* Change Notice Interrupt Enable set register */ +#define PIC32MZ_IOPORT_CNENINV_OFFSET 0x008c /* Change Notice Interrupt Enable invert register */ + +#define PIC32MZ_IOPORT_CNSTAT_OFFSET 0x0080 /* Change Notice Control register */ +#define PIC32MZ_IOPORT_CNSTATCLR_OFFSET 0x0084 /* Change Notice Control clear register*/ +#define PIC32MZ_IOPORT_CNSTATSET_OFFSET 0x0088 /* Change Notice Control set register */ +#define PIC32MZ_IOPORT_CNSTATINV_OFFSET 0x008c /* Change Notice Control invert register */ + +/* IOPort Peripheral Addresses **************************************************************/ + +#define PIC32MZ_IOPORTn_K1BASE(n) (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTn_OFFSET(n)) +# define PIC32MZ_IOPORTA_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTA_OFFSET) +# define PIC32MZ_IOPORTB_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTB_OFFSET) +# define PIC32MZ_IOPORTC_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTC_OFFSET) +# define PIC32MZ_IOPORTD_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTD_OFFSET) +# define PIC32MZ_IOPORTE_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTE_OFFSET) +# define PIC32MZ_IOPORTF_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTF_OFFSET) +# define PIC32MZ_IOPORTG_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTG_OFFSET) +# define PIC32MZ_IOPORTH_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTH_OFFSET) +# define PIC32MZ_IOPORTJ_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTJ_OFFSET) +# define PIC32MZ_IOPORTK_K1BASE (PIC32MZ_IOPORT_K1BASE+PIC32MZ_IOPORTK_OFFSET) + +/* Register Addresses ***********************************************************************/ + +#define PIC32MZ_IOPORT_ANSEL(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ANSEL_OFFSET) +#define PIC32MZ_IOPORT_ANSELCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +#define PIC32MZ_IOPORT_ANSELSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ANSELSET_OFFSET) +#define PIC32MZ_IOPORT_ANSELINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +#define PIC32MZ_IOPORT_TRIS(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_TRIS_OFFSET) +#define PIC32MZ_IOPORT_TRISCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_TRISCLR_OFFSET) +#define PIC32MZ_IOPORT_TRISSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_TRISSET_OFFSET) +#define PIC32MZ_IOPORT_TRISINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_TRISINV_OFFSET) + +#define PIC32MZ_IOPORT_PORT(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_PORT_OFFSET) +#define PIC32MZ_IOPORT_PORTCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_PORTCLR_OFFSET) +#define PIC32MZ_IOPORT_PORTSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_PORTSET_OFFSET) +#define PIC32MZ_IOPORT_PORTINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_PORTINV_OFFSET) + +#define PIC32MZ_IOPORT_LAT(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_LAT_OFFSET) +#define PIC32MZ_IOPORT_LATCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_LATCLR_OFFSET) +#define PIC32MZ_IOPORT_LATSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_LATSET_OFFSET) +#define PIC32MZ_IOPORT_LATINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_LATINV_OFFSET) + +#define PIC32MZ_IOPORT_ODC(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ODC_OFFSET) +#define PIC32MZ_IOPORT_ODCCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ODCCLR_OFFSET) +#define PIC32MZ_IOPORT_ODCSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ODCSET_OFFSET) +#define PIC32MZ_IOPORT_ODCINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_ODCINV_OFFSET) + +#define PIC32MZ_IOPORT_CNPU(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPU_OFFSET) +#define PIC32MZ_IOPORT_CNPUCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +#define PIC32MZ_IOPORT_CNPUSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPUSET_OFFSET) +#define PIC32MZ_IOPORT_CNPUINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +#define PIC32MZ_IOPORT_CNPD(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPD_OFFSET) +#define PIC32MZ_IOPORT_CNPDCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +#define PIC32MZ_IOPORT_CNPDSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPDSET_OFFSET) +#define PIC32MZ_IOPORT_CNPDINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +#define PIC32MZ_IOPORT_CNCON(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNCON_OFFSET) +#define PIC32MZ_IOPORT_CNCONCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +#define PIC32MZ_IOPORT_CNCONSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNCONSET_OFFSET) +#define PIC32MZ_IOPORT_CNCONINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +#define PIC32MZ_IOPORT_CNEN(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNEN_OFFSET) +#define PIC32MZ_IOPORT_CNENCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNENCLR_OFFSET) +#define PIC32MZ_IOPORT_CNENSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNENSET_OFFSET) +#define PIC32MZ_IOPORT_CNENINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNENINV_OFFSET) + +#define PIC32MZ_IOPORT_CNSTAT(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNSTAT_OFFSET) +#define PIC32MZ_IOPORT_CNSTATCLR(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +#define PIC32MZ_IOPORT_CNSTATSET(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +#define PIC32MZ_IOPORT_CNSTATINV(n) (PIC32MZ_IOPORTn_K1BASE(n)+PIC32MZ_IOPORT_CNSTATINV_OFFSET) + +/* Port A addresses */ + +#define PIC32MZ_IOPORTA_ANSEL (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +#define PIC32MZ_IOPORTA_ANSELCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +#define PIC32MZ_IOPORTA_ANSELSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +#define PIC32MZ_IOPORTA_ANSELINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +#define PIC32MZ_IOPORTA_TRIS (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +#define PIC32MZ_IOPORTA_TRISCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +#define PIC32MZ_IOPORTA_TRISSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +#define PIC32MZ_IOPORTA_TRISINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +#define PIC32MZ_IOPORTA_PORT (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +#define PIC32MZ_IOPORTA_PORTCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +#define PIC32MZ_IOPORTA_PORTSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +#define PIC32MZ_IOPORTA_PORTINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +#define PIC32MZ_IOPORTA_LAT (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +#define PIC32MZ_IOPORTA_LATCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +#define PIC32MZ_IOPORTA_LATSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +#define PIC32MZ_IOPORTA_LATINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +#define PIC32MZ_IOPORTA_ODC (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +#define PIC32MZ_IOPORTA_ODCCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +#define PIC32MZ_IOPORTA_ODCSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +#define PIC32MZ_IOPORTA_ODCINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +#define PIC32MZ_IOPORTA_CNPU (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +#define PIC32MZ_IOPORTA_CNPUCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +#define PIC32MZ_IOPORTA_CNPUSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +#define PIC32MZ_IOPORTA_CNPUINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +#define PIC32MZ_IOPORTA_CNPD (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +#define PIC32MZ_IOPORTA_CNPDCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +#define PIC32MZ_IOPORTA_CNPDSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +#define PIC32MZ_IOPORTA_CNPDINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +#define PIC32MZ_IOPORTA_CNCON (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +#define PIC32MZ_IOPORTA_CNCONCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +#define PIC32MZ_IOPORTA_CNCONSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +#define PIC32MZ_IOPORTA_CNCONINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +#define PIC32MZ_IOPORTA_CNEN (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +#define PIC32MZ_IOPORTA_CNENCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +#define PIC32MZ_IOPORTA_CNENSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +#define PIC32MZ_IOPORTA_CNENINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +#define PIC32MZ_IOPORTA_CNSTAT (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +#define PIC32MZ_IOPORTA_CNSTATCLR (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +#define PIC32MZ_IOPORTA_CNSTATSET (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +#define PIC32MZ_IOPORTA_CNSTATINV (PIC32MZ_IOPORTA_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) + +#if CHIP_NPORTS > 0 +/* Port B addresses */ + +# define PIC32MZ_IOPORTB_ANSEL (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTB_ANSELCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTB_ANSELSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTB_ANSELINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTB_TRIS (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTB_TRISCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTB_TRISSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTB_TRISINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTB_PORT (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTB_PORTCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTB_PORTSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTB_PORTINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTB_LAT (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTB_LATCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTB_LATSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTB_LATINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTB_ODC (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTB_ODCCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTB_ODCSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTB_ODCINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTB_CNPU (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTB_CNPUCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTB_CNPUSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTB_CNPUINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTB_CNPD (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTB_CNPDCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTB_CNPDSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTB_CNPDINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTB_CNCON (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTB_CNCONCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTB_CNCONSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTB_CNCONINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTB_CNEN (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTB_CNENCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTB_CNENSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTB_CNENINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTB_CNSTAT (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTB_CNSTATCLR (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTB_CNSTATSET (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTB_CNSTATINV (PIC32MZ_IOPORTB_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 1 +/* Port C addresses */ + +# define PIC32MZ_IOPORTC_ANSEL (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTC_ANSELCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTC_ANSELSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTC_ANSELINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTC_TRIS (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTC_TRISCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTC_TRISSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTC_TRISINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTC_PORT (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTC_PORTCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTC_PORTSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTC_PORTINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTC_LAT (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTC_LATCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTC_LATSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTC_LATINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTC_ODC (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTC_ODCCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTC_ODCSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTC_ODCINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTC_CNPU (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTC_CNPUCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTC_CNPUSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTC_CNPUINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTC_CNPD (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTC_CNPDCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTC_CNPDSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTC_CNPDINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTC_CNCON (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTC_CNCONCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTC_CNCONSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTC_CNCONINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTC_CNEN (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTC_CNENCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTC_CNENSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTC_CNENINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTC_CNSTAT (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTC_CNSTATCLR (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTC_CNSTATSET (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTC_CNSTATINV (PIC32MZ_IOPORTC_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 2 +/* Port D addresses */ + +# define PIC32MZ_IOPORTD_ANSEL (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTD_ANSELCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTD_ANSELSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTD_ANSELINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTD_TRIS (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTD_TRISCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTD_TRISSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTD_TRISINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTD_PORT (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTD_PORTCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTD_PORTSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTD_PORTINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTD_LAT (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTD_LATCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTD_LATSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTD_LATINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTD_ODC (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTD_ODCCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTD_ODCSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTD_ODCINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTD_CNPU (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTD_CNPUCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTD_CNPUSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTD_CNPUINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTD_CNPD (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTD_CNPDCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTD_CNPDSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTD_CNPDINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTD_CNCON (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTD_CNCONCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTD_CNCONSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTD_CNCONINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTD_CNEN (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTD_CNENCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTD_CNENSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTD_CNENINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTD_CNSTAT (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTD_CNSTATCLR (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTD_CNSTATSET (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTD_CNSTATINV (PIC32MZ_IOPORTD_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 3 +/* Port E addresses */ + +# define PIC32MZ_IOPORTE_ANSEL (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTE_ANSELCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTE_ANSELSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTE_ANSELINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTE_TRIS (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTE_TRISCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTE_TRISSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTE_TRISINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTE_PORT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTE_PORTCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTE_PORTSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTE_PORTINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTE_LAT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTE_LATCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTE_LATSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTE_LATINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTE_ODC (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTE_ODCCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTE_ODCSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTE_ODCINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNPU (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTE_CNPUCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNPUSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTE_CNPUINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNPD (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTE_CNPDCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNPDSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTE_CNPDINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNCON (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTE_CNCONCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNCONSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTE_CNCONINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNEN (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTE_CNENCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNENSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTE_CNENINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNSTAT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 4 +/* Port F addresses */ + +# define PIC32MZ_IOPORTE_ANSEL (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTE_ANSELCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTE_ANSELSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTE_ANSELINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTE_TRIS (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTE_TRISCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTE_TRISSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTE_TRISINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTE_PORT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTE_PORTCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTE_PORTSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTE_PORTINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTE_LAT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTE_LATCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTE_LATSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTE_LATINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTE_ODC (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTE_ODCCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTE_ODCSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTE_ODCINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNPU (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTE_CNPUCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNPUSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTE_CNPUINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNPD (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTE_CNPDCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNPDSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTE_CNPDINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNCON (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTE_CNCONCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNCONSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTE_CNCONINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNEN (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTE_CNENCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNENSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTE_CNENINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTE_CNSTAT (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATCLR (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATSET (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTE_CNSTATINV (PIC32MZ_IOPORTE_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 5 +/* Port F addresses */ + +# define PIC32MZ_IOPORTF_ANSEL (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTF_ANSELCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTF_ANSELSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTF_ANSELINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTF_TRIS (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTF_TRISCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTF_TRISSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTF_TRISINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTF_PORT (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTF_PORTCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTF_PORTSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTF_PORTINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTF_LAT (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTF_LATCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTF_LATSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTF_LATINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTF_ODC (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTF_ODCCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTF_ODCSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTF_ODCINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTF_CNPU (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTF_CNPUCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTF_CNPUSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTF_CNPUINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTF_CNPD (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTF_CNPDCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTF_CNPDSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTF_CNPDINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTF_CNCON (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTF_CNCONCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTF_CNCONSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTF_CNCONINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTF_CNEN (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTF_CNENCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTF_CNENSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTF_CNENINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTF_CNSTAT (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTF_CNSTATCLR (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTF_CNSTATSET (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTF_CNSTATINV (PIC32MZ_IOPORTF_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 6 +/* Port G addresses */ + +# define PIC32MZ_IOPORTG_ANSEL (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTG_ANSELCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTG_ANSELSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTG_ANSELINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTG_TRIS (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTG_TRISCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTG_TRISSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTG_TRISINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTG_PORT (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTG_PORTCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTG_PORTSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTG_PORTINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTG_LAT (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTG_LATCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTG_LATSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTG_LATINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTG_ODC (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTG_ODCCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTG_ODCSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTG_ODCINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTG_CNPU (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTG_CNPUCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTG_CNPUSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTG_CNPUINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTG_CNPD (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTG_CNPDCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTG_CNPDSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTG_CNPDINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTG_CNCON (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTG_CNCONCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTG_CNCONSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTG_CNCONINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTG_CNEN (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTG_CNENCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTG_CNENSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTG_CNENINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTG_CNSTAT (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTG_CNSTATCLR (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTG_CNSTATSET (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTG_CNSTATINV (PIC32MZ_IOPORTG_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 7 +/* Port H addresses */ + +# define PIC32MZ_IOPORTH_ANSEL (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTH_ANSELCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTH_ANSELSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTH_ANSELINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTH_TRIS (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTH_TRISCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTH_TRISSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTH_TRISINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTH_PORT (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTH_PORTCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTH_PORTSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTH_PORTINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTH_LAT (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTH_LATCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTH_LATSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTH_LATINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTH_ODC (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTH_ODCCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTH_ODCSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTH_ODCINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTH_CNPU (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTH_CNPUCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTH_CNPUSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTH_CNPUINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTH_CNPD (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTH_CNPDCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTH_CNPDSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTH_CNPDINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTH_CNCON (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTH_CNCONCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTH_CNCONSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTH_CNCONINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTH_CNEN (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTH_CNENCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTH_CNENSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTH_CNENINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTH_CNSTAT (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTH_CNSTATCLR (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTH_CNSTATSET (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTH_CNSTATINV (PIC32MZ_IOPORTH_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 8 +/* Port J addresses */ + +# define PIC32MZ_IOPORTJ_ANSEL (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTJ_ANSELCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTJ_ANSELSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTJ_ANSELINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTJ_TRIS (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTJ_TRISCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTJ_TRISSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTJ_TRISINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTJ_PORT (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTJ_PORTCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTJ_PORTSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTJ_PORTINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTJ_LAT (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTJ_LATCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTJ_LATSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTJ_LATINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTJ_ODC (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTJ_ODCCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTJ_ODCSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTJ_ODCINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTJ_CNPU (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTJ_CNPUCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTJ_CNPUSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTJ_CNPUINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTJ_CNPD (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTJ_CNPDCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTJ_CNPDSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTJ_CNPDINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTJ_CNCON (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTJ_CNCONCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTJ_CNCONSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTJ_CNCONINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTJ_CNEN (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTJ_CNENCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTJ_CNENSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTJ_CNENINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTJ_CNSTAT (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTJ_CNSTATCLR (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTJ_CNSTATSET (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTJ_CNSTATINV (PIC32MZ_IOPORTJ_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +#if CHIP_NPORTS > 9 +/* Port K addresses */ + +# define PIC32MZ_IOPORTK_ANSEL (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ANSEL_OFFSET) +# define PIC32MZ_IOPORTK_ANSELCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ANSELCLR_OFFSET) +# define PIC32MZ_IOPORTK_ANSELSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ANSELSET_OFFSET) +# define PIC32MZ_IOPORTK_ANSELINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ANSELINV_OFFSET) + +# define PIC32MZ_IOPORTK_TRIS (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_TRIS_OFFSET) +# define PIC32MZ_IOPORTK_TRISCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_TRISCLR_OFFSET) +# define PIC32MZ_IOPORTK_TRISSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_TRISSET_OFFSET) +# define PIC32MZ_IOPORTK_TRISINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_TRISINV_OFFSET) + +# define PIC32MZ_IOPORTK_PORT (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_PORT_OFFSET) +# define PIC32MZ_IOPORTK_PORTCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_PORTCLR_OFFSET) +# define PIC32MZ_IOPORTK_PORTSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_PORTSET_OFFSET) +# define PIC32MZ_IOPORTK_PORTINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_PORTINV_OFFSET) + +# define PIC32MZ_IOPORTK_LAT (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_LAT_OFFSET) +# define PIC32MZ_IOPORTK_LATCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_LATCLR_OFFSET) +# define PIC32MZ_IOPORTK_LATSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_LATSET_OFFSET) +# define PIC32MZ_IOPORTK_LATINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_LATINV_OFFSET) + +# define PIC32MZ_IOPORTK_ODC (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ODC_OFFSET) +# define PIC32MZ_IOPORTK_ODCCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ODCCLR_OFFSET) +# define PIC32MZ_IOPORTK_ODCSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ODCSET_OFFSET) +# define PIC32MZ_IOPORTK_ODCINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_ODCINV_OFFSET) + +# define PIC32MZ_IOPORTK_CNPU (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPU_OFFSET) +# define PIC32MZ_IOPORTK_CNPUCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPUCLR_OFFSET) +# define PIC32MZ_IOPORTK_CNPUSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPUSET_OFFSET) +# define PIC32MZ_IOPORTK_CNPUINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPUINV_OFFSET) + +# define PIC32MZ_IOPORTK_CNPD (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPD_OFFSET) +# define PIC32MZ_IOPORTK_CNPDCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPDCLR_OFFSET) +# define PIC32MZ_IOPORTK_CNPDSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPDSET_OFFSET) +# define PIC32MZ_IOPORTK_CNPDINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNPDINV_OFFSET) + +# define PIC32MZ_IOPORTK_CNCON (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNCON_OFFSET) +# define PIC32MZ_IOPORTK_CNCONCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNCONCLR_OFFSET) +# define PIC32MZ_IOPORTK_CNCONSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNCONSET_OFFSET) +# define PIC32MZ_IOPORTK_CNCONINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNCONINV_OFFSET) + +# define PIC32MZ_IOPORTK_CNEN (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNEN_OFFSET) +# define PIC32MZ_IOPORTK_CNENCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNENCLR_OFFSET) +# define PIC32MZ_IOPORTK_CNENSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNENSET_OFFSET) +# define PIC32MZ_IOPORTK_CNENINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNENINV_OFFSET) + +# define PIC32MZ_IOPORTK_CNSTAT (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNSTAT_OFFSET) +# define PIC32MZ_IOPORTK_CNSTATCLR (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNSTATCLR_OFFSET) +# define PIC32MZ_IOPORTK_CNSTATSET (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNSTATSET_OFFSET) +# define PIC32MZ_IOPORTK_CNSTATINV (PIC32MZ_IOPORTK_K1BASE+PIC32MZ_IOPORT_CNSTATINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Analog select register */ + +#define IOPORT_ANSEL(n) (1 << (n)) /* Bits 0-15: Analog select */ +#define IOPORT_ANSEL_ALL 0x0000ffff + +/* Tri-state register */ + +#define IOPORT_TRIS(n) (1 << (n)) /* Bits 0-15: 1: Input 0: Output */ +#define IOPORT_TRIS_ALL 0x0000ffff + +/* Port register */ + +#define IOPORT_PORT(n) (1 << (n)) /* Bits 0-15: Pin value */ +#define IOPORT_PORT_ALL 0x0000ffff + +/* Port data latch register */ + +#define IOPORT_LAT(n) (1 << (n)) /* Bits 0-15: Port latch value */ +#define IOPORT_LAT_ALL 0x0000ffff + +/* Open drain control register */ + +#define IOPORT_ODC(n) (1 << (n)) /* Bits 0-15: 1: OD output enabled, 0: Disabled */ +#define IOPORT_ODC_ALL 0x0000ffff + +/* Change Notice Pull-up register */ + +#define IOPORT_CNPU(n) (1 << (n)) /* Bits 0:15: 1=Pull-up enabled */ +#define IOPORT_CNPU_ALL 0x0000ffff + +/* Change Notice Pull-down register */ + +#define IOPORT_CNPD(n) (1 << (n)) /* Bits 0:15: 1=Pull-down enabled */ +#define IOPORT_CNPD_ALL 0x0000ffff + +/* Change Notice Control register */ + +#define IOPORT_CNCON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define IOPORT_CNCON_ON (1 << 15) /* Bit 15: Change notice module enable */ + +/* Change Notice Interrupt Enable register */ + +#define IOPORT_CNEN(n) (1 << (n)) /* Bits 0-15: 1=Interrupt enabled */ +#define IOPORT_CNEN_ALL 0x0000ffff + +/* Change Notice Status register */ + +#define IOPORT_CNSTAT(n) (1 << (n)) /* Bits 0-15: Change notice control pin n */ +#define IOPORT_CNSTAT_ALL 0x0000ffff + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NPORTS > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_IOPORT_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-memorymap.h b/arch/mips/src/pic32mz/chip/pic32mz-memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..a03adba1a86b31d89016aa7eb9953e420ff10d28 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-memorymap.h @@ -0,0 +1,51 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/chip/pic32mz-memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_MEMORYMAP_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_PIC32MZEC) +# include "chip/pic32mzec-memorymap.h" +#else +# error Unknown PIC32MZ family +#endif + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_MEMORYMAP_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-osc.h b/arch/mips/src/pic32mz/chip/pic32mz-osc.h new file mode 100644 index 0000000000000000000000000000000000000000..7e5668d90f488fc90acab14783ae4bf27259cc9f --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-osc.h @@ -0,0 +1,234 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/chip/pic32mz-osc.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_OSC_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_OSC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pic32mz-memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Register Offsets *********************************************************/ + +#define PIC32MZ_OSCCON_OFFSET 0x0000 /* Oscillator control register offset */ +#define PIC32MZ_OSCTUN_OFFSET 0x0010 /* FRC tuning register offset */ +#define PIC32MZ_SPLLCON_OFFSET 0x0020 /* System PLL control register */ +#define PIC32MZ_REFO1CON_OFFSET 0x0080 /* Reference oscillator control register 1 */ +#define PIC32MZ_REFO1TRIM_OFFSET 0x00a0 /* Reference oscillator trim register 1 */ +#define PIC32MZ_REFO2CON_OFFSET 0x00b0 /* Reference oscillator control register 2 */ +#define PIC32MZ_REFO2TRIM_OFFSET 0x00c0 /* Reference oscillator trim register 2 */ +#define PIC32MZ_REFO3CON_OFFSET 0x00d0 /* Reference oscillator control register 3 */ +#define PIC32MZ_REFO3TRIM_OFFSET 0x00e0 /* Reference oscillator trim register 3 */ +#define PIC32MZ_REFO4CON_OFFSET 0x00f0 /* Reference oscillator control register 4 */ +#define PIC32MZ_REFO4TRIM_OFFSET 0x0100 /* Reference oscillator trim register 4 */ +#define PIC32MZ_PB1DIV_OFFSET 0x0100 /* Peripheral bus 1 clock divisor control register */ +#define PIC32MZ_PB2DIV_OFFSET 0x0110 /* Peripheral bus 2 clock divisor control register */ +#define PIC32MZ_PB3DIV_OFFSET 0x0120 /* Peripheral bus 3 clock divisor control register */ +#define PIC32MZ_PB4DIV_OFFSET 0x0130 /* Peripheral bus 4 clock divisor control register */ +#define PIC32MZ_PB5DIV_OFFSET 0x0140 /* Peripheral bus 5 clock divisor control register */ +#define PIC32MZ_PB6DIV_OFFSET 0x0150 /* Peripheral bus 6 clock divisor control register */ +#define PIC32MZ_PB7DIV_OFFSET 0x0160 /* Peripheral bus 7 clock divisor control register */ +#define PIC32MZ_PB8DIV_OFFSET 0x0170 /* Peripheral bus 8 clock divisor control register */ + +/* Register Addresses *******************************************************/ + +#define PIC32MZ_OSCCON (PIC32MZ_OSC_K1BASE+PIC32MZ_OSCCON_OFFSET) +#define PIC32MZ_OSCTUN (PIC32MZ_OSC_K1BASE+PIC32MZ_OSCTUN_OFFSET) + +#define PIC32MZ_SPLLCON (PIC32MZ_OSC_K1BASE+PIC32MZ_SPLLCON_OFFSET) +#define PIC32MZ_REFO1CON (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO1CON_OFFSET) +#define PIC32MZ_REFO1TRIM (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO1TRIM_OFFSET) +#define PIC32MZ_REFO2CON (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO2CON_OFFSET) +#define PIC32MZ_REFO2TRIM (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO2TRIM_OFFSET) +#define PIC32MZ_REFO3CON (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO3CON_OFFSET) +#define PIC32MZ_REFO3TRIM (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO3TRIM_OFFSET) +#define PIC32MZ_REFO4CON (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO4CON_OFFSET) +#define PIC32MZ_REFO4TRIM (PIC32MZ_OSC_K1BASE+PIC32MZ_REFO4TRIM_OFFSET) +#define PIC32MZ_PB1DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB1DIV_OFFSET) +#define PIC32MZ_PB2DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB2DIV_OFFSET) +#define PIC32MZ_PB3DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB3DIV_OFFSET) +#define PIC32MZ_PB4DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB4DIV_OFFSET) +#define PIC32MZ_PB5DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB5DIV_OFFSET) +#define PIC32MZ_PB6DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB6DIV_OFFSET) +#define PIC32MZ_PB7DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB7DIV_OFFSET) +#define PIC32MZ_PB8DIV (PIC32MZ_OSC_K1BASE+PIC32MZ_PB8DIV_OFFSET) + +/* Register Bit-Field Definitions *******************************************/ + +/* Oscillator control register offset */ + +#define OSCCON_OSWEN (1 << 0) /* Bit 0: Oscillator switch enable */ +#define OSCCON_SOSCEN (1 << 1) /* Bit 1: 32.768kHz secondary oscillator enable */ +#define OSCCON_CF (1 << 3) /* Bit 3: Clock fail detect */ +#define OSCCON_SLPEN (1 << 4) /* Bit 4: Sleep mode enable */ +#define OSCCON_SLOCK (1 << 5) /* Bit 5: PLL lock status */ +#define OSCCON_ULOCK (1 << 6) /* Bit 6: USB PLL lock status */ +#define OSCCON_CLKLOCK (1 << 7) /* Bit 7: Clock selection lock enable */ +#define OSCCON_NOSC_SHIFT (8) /* Bits 8-10: New oscillator selection */ +#define OSCCON_NOSC_MASK (7 << OSCCON_NOSC_SHIFT) +# define OSCCON_NOSC_FRC (0 << OSCCON_NOSC_SHIFT) /* Internal fast RC oscillator / FRCDIV */ +# define OSCCON_NOSC_SPLL (1 << OSCCON_NOSC_SHIFT) /* System PLL */ +# define OSCCON_NOSC_POSC (2 << OSCCON_NOSC_SHIFT) /* Primary oscillator (HS or EC) */ +# define OSCCON_NOSC_SOSC (4 << OSCCON_NOSC_SHIFT) /* Secondary oscillator */ +# define OSCCON_NOSC_LPRC (5 << OSCCON_NOSC_SHIFT) /* Internal low power RC oscillator */ +# define OSCCON_NOSC_FRCDIV (7 << OSCCON_NOSC_SHIFT) /* Internal fast RC / FRCDIV */ +#define OSCCON_COSC_SHIFT (12) /* Bits 12-14: Current oscillator selection */ +#define OSCCON_COSC_MASK (7 << OSCCON_COSC_SHIFT) +# define OSCCON_COSC_FRC (0 << OSCCON_COSC_SHIFT) /* Internal fast RC oscillator / FRCDIV */ +# define OSCCON_COSC_SPLL (1 << OSCCON_COSC_SHIFT) /* System PLL */ +# define OSCCON_COSC_POSC (2 << OSCCON_COSC_SHIFT) /* Primary oscillator (HS or EC) */ +# define OSCCON_COSC_SOSC (4 << OSCCON_COSC_SHIFT) /* Secondary oscillator */ +# define OSCCON_COSC_LPRC (5 << OSCCON_COSC_SHIFT) /* Internal low power RC oscillator */ +# define OSCCON_COSC_BFRC (5 << OSCCON_COSC_SHIFT) /* Back-up Fast RC Oscillator */ +# define OSCCON_COSC_FRCDIV (7 << OSCCON_COSC_SHIFT) /* Internal fast RC / FRCDIV */ +#define OSCCON_SOSCRDY (1 << 22) /* Bit 22: Secondary oscillator ready */ +#define OSCCON_DRMEN (1 << 23) /* Bit 23: Dream mode enable */ +#define OSCCON_FRCDIV_SHIFT (24) /* Bits 24-26: FRC oscillator divider */ +#define OSCCON_FRCDIV_MASK (7 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV(n) ((uint32_t)((n)-1) << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV1 (0 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV2 (1 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV4 (2 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV8 (3 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV16 (4 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV32 (5 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV64 (6 << OSCCON_FRCDIV_SHIFT) +# define OSCCON_FRCDIV_DIV256 (7 << OSCCON_FRCDIV_SHIFT) + +/* FRC tuning register offset (6-bit, signed twos complement) */ + +#define OSCTUN_SHIFT (0) /* Bits 0-5: FRC tuning bits */ +#define OSCTUN_MASK (0x3f << OSCTUN_SHIFT) +# define OSCTUN_MIN (0x20 << OSCTUN_SHIFT) +# define OSCTUN_CENTER (0x00 << OSCTUN_SHIFT) +# define OSCTUN_MAX (0x1f << OSCTUN_SHIFT) + +/* System PLL control register */ + +#define SPLLCON_PLLRANGE_SHIFT (0) /* Bits 0-2: System PLL Frequency Range Selection bits */ +#define SPLLCON_PLLRANGE_MASK (7 << SPLLCON_PLLRANGE_SHIFT) +# define SPLLCON_PLLRANGE_BYPASS (0 << SPLLCON_PLLRANGE_SHIFT) /* Bypass */ +# define SPLLCON_PLLRANGE_5_10MHZ (1 << SPLLCON_PLLRANGE_SHIFT) /* 5-10 MHz */ +# define SPLLCON_PLLRANGE_8_16MHZ (2 << SPLLCON_PLLRANGE_SHIFT) /* 8-16 MHz */ +# define SPLLCON_PLLRANGE_13_26MHZ (3 << SPLLCON_PLLRANGE_SHIFT) /* 13-26 MHz */ +# define SPLLCON_PLLRANGE_21_42MHZ (4 << SPLLCON_PLLRANGE_SHIFT) /* 21-42 MHz */ +# define SPLLCON_PLLRANGE_34_64MHZ (5 << SPLLCON_PLLRANGE_SHIFT) /* 34-64 MHz */ +#define SPLLCON_PLLICLK (1 << 7) /* Bit 7: System PLL Input Clock Source bit */ +#define SPLLCON_PLLIDIV_SHIFT (8) /* Bits 8-10: System PLL Input Clock Divider bits */ +#define SPLLCON_PLLIDIV_MASK (7 << SPLLCON_PLLIDIV_SHIFT) +# define SPLLCON_PLLIDIV(n) ((uint32_t)((n)-1) << SPLLCON_PLLIDIV_SHIFT) /* Divide by n, n=1..8 */ +#define SPLLCON_PLLMULT_SHIFT (16) /* Bits 16-22 <6:0>: System PLL Multiplier bits */ +#define SPLLCON_PLLMULT_MASK (0x7f << SPLLCON_PLLMULT_SHIFT) +# define SPLLCON_PLLMULT(n) ((uint32_t)((n)-1) << SPLLCON_PLLMULT_SHIFT) /* Muliply by n, n=1..128 */ +#define SPLLCON_PLLODIV_SHIFT (24) /* Bits 24-26: System PLL Output Clock Divider bits */ +#define SPLLCON_PLLODIV_MASK (7 << SPLLCON_PLLODIV_SHIFT) +# define SPLLCON_PLLODIV_2 (1 << SPLLCON_PLLODIV_SHIFT) /* PLL Divide by 2 */ +# define SPLLCON_PLLODIV_4 (2 << SPLLCON_PLLODIV_SHIFT) /* PLL Divide by 4 */ +# define SPLLCON_PLLODIV_8 (3 << SPLLCON_PLLODIV_SHIFT) /* PLL Divide by 8 */ +# define SPLLCON_PLLODIV_16 (4 << SPLLCON_PLLODIV_SHIFT) /* PLL Divide by 16 */ +# define SPLLCON_PLLODIV_32 (5 << SPLLCON_PLLODIV_SHIFT) /* PLL Divide by 32 */ + +/* Reference oscillator control register n, n=1..4 */ + +#define REFOCON_ROSEL_SHIFT (0) /* Bits 0-3: Reference Clock Source Select bits */ +#define REFOCON_ROSEL_MASK (15 << REFOCON_ROSEL_SHIFT) +# define REFOCON_ROSEL_SYSCLK (0 << REFOCON_ROSEL_SHIFT) /* SYSCLK */ +# define REFOCON_ROSEL_PBCLK1 (1 << REFOCON_ROSEL_SHIFT) /* PBCLK1 */ +# define REFOCON_ROSEL_POSC (2 << REFOCON_ROSEL_SHIFT) /* POSC */ +# define REFOCON_ROSEL_FRC (3 << REFOCON_ROSEL_SHIFT) /* FRC */ +# define REFOCON_ROSEL_LPRC (4 << REFOCON_ROSEL_SHIFT) /* LPRC */ +# define REFOCON_ROSEL_SOSC (5 << REFOCON_ROSEL_SHIFT) /* SOSC */ +# define REFOCON_ROSEL_SPLL (7 << REFOCON_ROSEL_SHIFT) /* System PLL output */ +# define REFOCON_ROSEL_REFCLKI (8 << REFOCON_ROSEL_SHIFT) /* REFCLKIx */ +# define REFOCON_ROSEL_BFRC (9 << REFOCON_ROSEL_SHIFT) /* BFRC */ +#define REFOCON_ACTIVE (1 << 8) /* Bit 8: Reference Clock Request Status bit */ +#define REFOCON_DIVSWEN (1 << 9) /* Bit 9: Divider Switch Enable bit */ +#define REFOCON_RSLP (1 << 11) /* Bit 11: Reference Oscillator Module Run in Sleep bit */ +#define REFOCON_OE (1 << 12) /* Bit 12: Reference Clock Output Enable bit */ +#define REFOCON_SIDL (1 << 13) /* Bit 13: Peripheral Stop in Idle Mode bit */ +#define REFOCON_ON (1 << 15) /* Bit 15: Output Enable bit */ +#define REFOCON_RODIV_SHIFT (16) /* Bits 16-30: Reference Clock Divider bits */ +#define REFOCON_RODIV_MASK (0x7fff << REFOCON_RODIV_SHIFT) +# define REFOCON_RODIV(n) ((uint32_t)(n) << REFOCON_RODIV_SHIFT) + +/* Reference oscillator trim register n, n=1..4 */ + +#define REFOTRIM_SHIFT (23) /* Bits 23-31: Reference Oscillator Trim bits */ +#define REFOTRIM_MASK (0x1ff << REFOTRIM_SHIFT) + +/* Peripheral bus n clock divisor control register n=1..8 */ + +#define PBDIV_SHIFT (0) /* Bits 0-6: Peripheral Bus Clock Divisor Control bits */ +#define PBDIV_MASK (0x7f << PBDIV_SHIFT) +# define PBDIV(n) ((uint32_t)((n)-1) << PBDIV_SHIFT) /* PBCLK = SYSLCK/n, n=1..128 */ +#define PBDIV_PBDIVRDY (1 << 11) /* Bit 11: Peripheral Bus Clock Divisor Ready bit */ +#define PBDIV_ON (1 << 15) /* Bit 15: Peripheral Bus Output Clock Enable bit */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_OSC_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-pps.h b/arch/mips/src/pic32mz/chip/pic32mz-pps.h new file mode 100644 index 0000000000000000000000000000000000000000..c0fbd48fa58a7e321b0e6b10d42d7e8090cf2757 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-pps.h @@ -0,0 +1,115 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/pic32mz-pps.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PPS_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PPS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* PPS Register Offsets/Addresses ***********************************************************/ + +/* Depends on the peripherals supported by the particular device */ + +#if defined(CONFIG_ARCH_CHIP_PIC32MZEC) +# include "chip/pic32mzec-pps.h" +#else +# error Unknown PIC32MZ family +#endif + +/* PPS Register Bit Field Definitions *************************************(*****************/ +/* All registers contain a single 4 bit field (bits 0-3) holding the peripheral pin + * selection. + */ + +#define PPS_MASK 0x0000000f + +/* Pin Selection Helper Macros **************************************************************/ +/* The encoding of the input pin selection is simple. Since we know the devices, we also + * can infer the register address so we need only the value for the register which is + * exactly what is provided by macro definitions. + * + * The encoding of the output pin selection is a little more complex. Knowing the device + * does not provide sufficient information. The output pin definitions include both the + * register value and the register address and the following helper macros can be used + * extract one or the other. + * + * NOTE: These odd macro forms are used to work around a pre-processor issue. The argument + * to PPS_OUTPUT_REGADDR is defined to have the form nn,xxxx but the preprocessor would + * claim that only one parameter is passed. The following version takes only one parameter + * and keeps the pre-processor happy. + */ + +#define __PPS_OUTPUT_REGADDR(a,b) ((uintptr_t)(b)) +#define PPS_OUTPUT_REGADDR(a) __PPS_OUTPUT_REGADDR(a) + +#define __PPS_OUTPUT_REGVAL(a,b) ((uint32_t)(a)) +#define PPS_OUTPUT_REGVAL(a) __PPS_OUTPUT_REGVAL(a) + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PPS_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-prefetch.h b/arch/mips/src/pic32mz/chip/pic32mz-prefetch.h new file mode 100644 index 0000000000000000000000000000000000000000..1279451c7aa24cc90493e0fed09dd3931a595fa9 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-prefetch.h @@ -0,0 +1,82 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/chip/pic32mz-prefetch.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PREFETCH_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PREFETCH_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "pic32mz-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* Prefetch register offsets ****************************************************************/ + +#define PIC32MZ_PRECON_OFFSET 0x0000 /* Prefetch module control register */ +#define PIC32MZ_PRESTAT_OFFSET 0x0000 /* Prefetch module status register */ + +/* Prefetch register addresses **************************************************************/ + +#define PIC32MZ_PRECON (PIC32MZ_PREFETCH_K1BASE+PIC32MZ_PRECON_OFFSET) +#define PIC32MZ_PRESTAT (PIC32MZ_PREFETCH_K1BASE+PIC32MZ_PRESTAT_OFFSET) + +/* Prefetch register bit field definitions **************************************************/ + +/* Prefetch module control register */ + +#define PRECON_PFMWS_SHIFT (0) /* Bits 0-2: PFM Access Time */ +#define PRECON_PFMWS_MASK (7 << PRECON_PFMWS_SHIFT) +# define PRECON_PFMWS(n) ((uint32_t)(n) << PRECON_PFMWS_SHIFT) /* n wait states, n=0..7 */ +#define PRECON_PREFEN_SHIFT (4) /* Bit 4-5: Predictive Prefetch Enable */ +#define PRECON_PREFEN_MASK (3 << PRECON_PREFEN_SHIFT) +# define PRECON_PREFEN_DISABLE (0 << PRECON_PREFEN_SHIFT) /* Disable predictive prefetch */ +# define PRECON_PREFEN_CPUI (1 << PRECON_PREFEN_SHIFT) /* Predictive prefetch CPU instructions */ +# define PRECON_PREFEN_CPUID (2 << PRECON_PREFEN_SHIFT) /* Predictive prefetch CPU instructions and data */ +# define PRECON_PREFEN_ANY (3 << PRECON_PREFEN_SHIFT) /* Predictive prefetch any address */ +#define PRECON_PFMSECEN (1 << 26) /* Bit 26: Flash SEC Interrupt Enable */ + +/* Prefetch module status register */ + +#define PRESTAT_PFMSECCNT_SHIFT (0) /* Bits 0-7: Flash SEC Count bits */ +#define PRESTAT_PFMSECCNT_MASK (0xff << PRESTAT_PFMSECCNT_SHIFT) +#define PRESTAT_PFMSEC (1 << 26) /* Bit 26: Flash Single-bit Error Corrected Status */ +#define PRESTAT_PFMDED (1 << 27) /* Bit 27: Flash Double-bit Error Detected Status */ + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_PREFETCH_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-spi.h b/arch/mips/src/pic32mz/chip/pic32mz-spi.h new file mode 100644 index 0000000000000000000000000000000000000000..d4f5fe42a501d4fb96e099a7f2223e082cb92f39 --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-spi.h @@ -0,0 +1,331 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/chip/pic32mz-spi.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_SPI_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip/pic32mz-memorymap.h" + +#if CHIP_NSPI > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* SPI Peripheral Offsets ***************************************************/ + +#define PIC32MZ_SPIn_OFFSET(n) ((n) << 9) +# define PIC32MZ_SPI1_OFFSET 0x0000 +# define PIC32MZ_SPI2_OFFSET 0x0200 +# define PIC32MZ_SPI3_OFFSET 0x0400 +# define PIC32MZ_SPI4_OFFSET 0x0600 +# define PIC32MZ_SPI5_OFFSET 0x0800 +# define PIC32MZ_SPI6_OFFSET 0x0a00 + +/* SPI Register Offsets *****************************************************/ + +#define PIC32MZ_SPI_CON_OFFSET 0x0000 /* SPI control register */ +#define PIC32MZ_SPI_CONCLR_OFFSET 0x0004 /* SPI control clear register */ +#define PIC32MZ_SPI_CONSET_OFFSET 0x0008 /* SPI control set register */ +#define PIC32MZ_SPI_CONINV_OFFSET 0x000c /* SPI control invert register */ + +#define PIC32MZ_SPI_STAT_OFFSET 0x0010 /* SPI status register */ +#define PIC32MZ_SPI_STATCLR_OFFSET 0x0014 /* SPI status clear register */ + +#define PIC32MZ_SPI_BUF_OFFSET 0x0020 /* SPI buffer register */ + +#define PIC32MZ_SPI_BRG_OFFSET 0x0030 /* SPI baud rate register */ +#define PIC32MZ_SPI_BRGCLR_OFFSET 0x0034 /* SPI baud rate clear register */ +#define PIC32MZ_SPI_BRGSET_OFFSET 0x0038 /* SPI baud rate set register */ +#define PIC32MZ_SPI_BRGINV_OFFSET 0x003c /* SPI baud rate invert register */ + +#define PIC32MZ_SPI_CON2_OFFSET 0x0040 /* SPI control register 2*/ +#define PIC32MZ_SPI_CON2CLR_OFFSET 0x0040 /* SPI control register 2*/ +#define PIC32MZ_SPI_CON2SET_OFFSET 0x0040 /* SPI control register 2*/ +#define PIC32MZ_SPI_CON2INV_OFFSET 0x0040 /* SPI control register 2*/ + +/* SPI Peripheral Addresses *************************************************/ + +#define PIC32MZ_SPIn_K1BASE(n) (PIC32MZ_SPI_K1BASE + PIC32MZ_SPIn_OFFSET(n)) +# define PIC32MZ_SPI1_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI1_OFFSET) +# define PIC32MZ_SPI2_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI2_OFFSET) +# define PIC32MZ_SPI3_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI3_OFFSET) +# define PIC32MZ_SPI4_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI4_OFFSET) +# define PIC32MZ_SPI5_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI5_OFFSET) +# define PIC32MZ_SPI6_K1BASE (PIC32MZ_SPI_K1BASE + PIC32MZ_SPI6_OFFSET) + +/* SPI Register Addresses ***************************************************/ + +#define PIC32MZ_SPI1_CON (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CON_OFFSET) +#define PIC32MZ_SPI1_CONCLR (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +#define PIC32MZ_SPI1_CONSET (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +#define PIC32MZ_SPI1_CONINV (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +#define PIC32MZ_SPI1_STAT (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +#define PIC32MZ_SPI1_STATCLR (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +#define PIC32MZ_SPI1_BUF (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +#define PIC32MZ_SPI1_BRG (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +#define PIC32MZ_SPI1_BRGCLR (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +#define PIC32MZ_SPI1_BRGSET (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +#define PIC32MZ_SPI1_BRGINV (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +#define PIC32MZ_SPI1_CON2 (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CON2_OFFSET) +#define PIC32MZ_SPI1_CON2CLR (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +#define PIC32MZ_SPI1_CON2SET (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +#define PIC32MZ_SPI1_CON2INV (PIC32MZ_SPI1_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) + +#if PIC32MZ_NSPI > 1 +# define PIC32MZ_SPI2_CON (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CON_OFFSET) +# define PIC32MZ_SPI2_CONCLR (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +# define PIC32MZ_SPI2_CONSET (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +# define PIC32MZ_SPI2_CONINV (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +# define PIC32MZ_SPI2_STAT (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +# define PIC32MZ_SPI2_STATCLR (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +# define PIC32MZ_SPI2_BUF (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +# define PIC32MZ_SPI2_BRG (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +# define PIC32MZ_SPI2_BRGCLR (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +# define PIC32MZ_SPI2_BRGSET (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +# define PIC32MZ_SPI2_BRGINV (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +# define PIC32MZ_SPI2_CON2 (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CON2_OFFSET) +# define PIC32MZ_SPI2_CON2CLR (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +# define PIC32MZ_SPI2_CON2SET (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +# define PIC32MZ_SPI2_CON2INV (PIC32MZ_SPI2_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) +#endif + +#if PIC32MZ_NSPI > 2 +# define PIC32MZ_SPI3_CON (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CON_OFFSET) +# define PIC32MZ_SPI3_CONCLR (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +# define PIC32MZ_SPI3_CONSET (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +# define PIC32MZ_SPI3_CONINV (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +# define PIC32MZ_SPI3_STAT (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +# define PIC32MZ_SPI3_STATCLR (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +# define PIC32MZ_SPI3_BUF (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +# define PIC32MZ_SPI3_BRG (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +# define PIC32MZ_SPI3_BRGCLR (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +# define PIC32MZ_SPI3_BRGSET (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +# define PIC32MZ_SPI3_BRGINV (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +# define PIC32MZ_SPI3_CON2CLR (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +# define PIC32MZ_SPI3_CON2SET (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +# define PIC32MZ_SPI3_CON2INV (PIC32MZ_SPI3_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) +#endif + +#if PIC32MZ_NSPI > 3 +# define PIC32MZ_SPI4_CON (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CON_OFFSET) +# define PIC32MZ_SPI4_CONCLR (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +# define PIC32MZ_SPI4_CONSET (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +# define PIC32MZ_SPI4_CONINV (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +# define PIC32MZ_SPI4_STAT (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +# define PIC32MZ_SPI4_STATCLR (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +# define PIC32MZ_SPI4_BUF (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +# define PIC32MZ_SPI4_BRG (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +# define PIC32MZ_SPI4_BRGCLR (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +# define PIC32MZ_SPI4_BRGSET (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +# define PIC32MZ_SPI4_BRGINV (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +# define PIC32MZ_SPI4_CON2CLR (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +# define PIC32MZ_SPI4_CON2SET (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +# define PIC32MZ_SPI4_CON2INV (PIC32MZ_SPI4_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) +#endif + +#if PIC32MZ_NSPI > 4 +# define PIC32MZ_SPI5_CON (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CON_OFFSET) +# define PIC32MZ_SPI5_CONCLR (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +# define PIC32MZ_SPI5_CONSET (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +# define PIC32MZ_SPI5_CONINV (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +# define PIC32MZ_SPI5_STAT (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +# define PIC32MZ_SPI5_STATCLR (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +# define PIC32MZ_SPI5_BUF (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +# define PIC32MZ_SPI5_BRG (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +# define PIC32MZ_SPI5_BRGCLR (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +# define PIC32MZ_SPI5_BRGSET (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +# define PIC32MZ_SPI5_BRGINV (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +# define PIC32MZ_SPI5_CON2CLR (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +# define PIC32MZ_SPI5_CON2SET (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +# define PIC32MZ_SPI5_CON2INV (PIC32MZ_SPI5_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) +#endif + +#if PIC32MZ_NSPI > 5 +# define PIC32MZ_SPI6_CON (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CON_OFFSET) +# define PIC32MZ_SPI6_CONCLR (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CONCLR_OFFSET) +# define PIC32MZ_SPI6_CONSET (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CONSET_OFFSET) +# define PIC32MZ_SPI6_CONINV (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CONINV_OFFSET) +# define PIC32MZ_SPI6_STAT (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_STAT_OFFSET) +# define PIC32MZ_SPI6_STATCLR (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_STATCLR_OFFSET) +# define PIC32MZ_SPI6_BUF (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_BUF_OFFSET) +# define PIC32MZ_SPI6_BRG (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_BRG_OFFSET) +# define PIC32MZ_SPI6_BRGCLR (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_BRGCLR_OFFSET) +# define PIC32MZ_SPI6_BRGSET (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_BRGSET_OFFSET) +# define PIC32MZ_SPI6_BRGINV (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_BRGINV_OFFSET) +# define PIC32MZ_SPI6_CON2CLR (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CON2CLR_OFFSET) +# define PIC32MZ_SPI6_CON2SET (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CON2SET_OFFSET) +# define PIC32MZ_SPI6_CON2INV (PIC32MZ_SPI6_K1BASE+PIC32MZ_SPI_CON2INV_OFFSET) +#endif + +/* Register Bit-Field Definitions *******************************************/ + +/* SPI control register */ + +#define SPI_CON_SRXISEL_SHIFT (0) /* Bits 0-1: SPI Receive Buffer Full Interrupt Mode */ +#define SPI_CON_SRXISEL_MASK (3 << SPI_CON_SRXISEL_SHIFT) +# define SPI_CON_SRXISEL_EMPTY (0 << SPI_CON_SRXISEL_SHIFT) /* Buffer empty */ +# define SPI_CON_SRXISEL_NEMPTY (1 << SPI_CON_SRXISEL_SHIFT) /* Buffer not empty */ +# define SPI_CON_SRXISEL_HALF (2 << SPI_CON_SRXISEL_SHIFT) /* Buffer half full or more */ +# define SPI_CON_SRXISEL_FULL (3 << SPI_CON_SRXISEL_SHIFT) /* Buffer full */ +#define SPI_CON_STXISEL_SHIFT (2) /* Bits 2-3: SPI Transmit Buffer Empty Interrupt Mode */ +#define SPI_CON_STXISEL_MASK (3 << SPI_CON_STXISEL_SHIFT) +# define SPI_CON_STXISEL_DONE (0 << SPI_CON_STXISEL_SHIFT) /* Buffer empty (and data shifted out) */ +# define SPI_CON_STXISEL_EMPTY (1 << SPI_CON_STXISEL_SHIFT) /* Buffer empty */ +# define SPI_CON_STXISEL_HALF (2 << SPI_CON_STXISEL_SHIFT) /* Buffer half empty or more */ +# define SPI_CON_STXISEL_NFULL (3 << SPI_CON_STXISEL_SHIFT) /* Buffer not full */ +#define SPI_CON_DISSDI (1 << 4) /* Bit 4: Disable SDI */ +#define SPI_CON_MSTEN (1 << 5) /* Bit 5: Master mode enable */ +#define SPI_CON_CKP (1 << 6) /* Bit 6: Clock polarity select */ +#define SPI_CON_SSEN (1 << 7) /* Bit 7: Slave select enable (slave mode) */ +#define SPI_CON_CKE (1 << 8) /* Bit 8: SPI clock edge select */ +#define SPI_CON_SMP (1 << 9) /* Bit 9: SPI data input sample phase */ +#define SPI_CON_MODE_SHIFT (10) /* Bits 10-11: 32/16-Bit Communication Select */ +#define SPI_CON_MODE_MASK (3 << SPI_CON_MODE_SHIFT) + /* With AUDEN=0: */ +# define SPI_CON_MODE_8BIT (0 << SPI_CON_MODE_SHIFT) /* 8-bit data width */ +# define SPI_CON_MODE_16BIT (1 << SPI_CON_MODE_SHIFT) /* 16-bit data width */ +# define SPI_CON_MODE_32BIT (2 << SPI_CON_MODE_SHIFT) /* 32-bit data width */ + /* With AUDEN=1: */ +# define SPI_CON_MODE_161616 (0 << SPI_CON_MODE_SHIFT) /* 16-bit data, 16-bit FIFO, 16-bit channel */ +# define SPI_CON_MODE_161632 (1 << SPI_CON_MODE_SHIFT) /* 16-bit data, 16-bit FIFO, 32-bit channel */ +# define SPI_CON_MODE_323232 (2 << SPI_CON_MODE_SHIFT) /* 32-bit data, 32-bit FIFO, 32-bit channel */ +# define SPI_CON_MODE_243232 (3 << SPI_CON_MODE_SHIFT) /* 24-bit data, 32-bit FIFO, 32-bit channel */ +#define SPI_CON_DISSDO (1 << 12) /* Bit 12: Disable SDOx pin */ +#define SPI_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define SPI_CON_ON (1 << 15) /* Bit 15: SPI peripheral on */ +#define SPI_CON_ENHBUF (1 << 16) /* Bit 16: Enhanced buffer enable */ +#define SPI_CON_SPIFE (1 << 17) /* Bit 17: Frame sync pulse edge select */ + /* Bits 18-23: Reserved */ +#define SPI_CON_MCLKSEL (1 << 23) /* Bit 23: Master clock enable */ +#define SPI_CON_FRMCNT_SHIFT (24) /* Bits 24-26: Frame Sync Pulse Counter bits */ +#define SPI_CON_FRMCNT_MASK (7 << SPI_CON_FRMCNT_SHIFT) +# define SPI_CON_FRMCNT_CHAR1 (0 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse each char */ +# define SPI_CON_FRMCNT_CHAR2 (1 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 2 chars */ +# define SPI_CON_FRMCNT_CHAR4 (2 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 4 chars */ +# define SPI_CON_FRMCNT_CHAR8 (3 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 8 chars */ +# define SPI_CON_FRMCNT_CHAR16 (4 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 16 chars */ +# define SPI_CON_FRMCNT_CHAR32 (5 << SPI_CON_FRMCNT_SHIFT) /* Frame sync pulse every 32 chars */ +#define SPI_CON_FRMSYPW (1 << 27) /* Bits 27: Frame sync pulse width */ +#define SPI_CON_MSSEN (1 << 28) /* Bits 28: Master mode slave select enable */ +#define SPI_CON_FRMPOL (1 << 29) /* Bits 29: Frame sync polarity */ +#define SPI_CON_FRMSYNC (1 << 30) /* Bits 30: Frame sync pulse direction control on SSx pin */ +#define SPI_CON_FRMEN (1 << 31) /* Bits 31: Framed SPI support */ + +/* SPI control register 2 */ + +#define SPI2_CON2_AUDMOD_SHIFT (0) /* Bits 0-1: Audio Protocol Mode */ +#define SPI2_CON2_AUDMOD_MASK (3 << SPI2_CON2_AUDMOD_SHIFT) +# define SPI2_CON2_AUDMOD_I2S (0 << SPI2_CON2_AUDMOD_SHIFT) /* I2S mode */ +# define SPI2_CON2_AUDMOD_LJ (1 << SPI2_CON2_AUDMOD_SHIFT) /* Left Justified mode */ +# define SPI2_CON2_AUDMOD_RJ (2 << SPI2_CON2_AUDMOD_SHIFT) /* Right Justified mode */ +# define SPI2_CON2_AUDMOD_PCM (3 << SPI2_CON2_AUDMOD_SHIFT) /* PCM/DSP mode */ + /* Bit 2: Reserved */ +#define SPI2_CON2_AUDMONO (1 << 3) /* Bit 3: Transmit Audio Data Format */ + /* Bits 5-6: Reserved */ +#define SPI2_CON2_AUDEN (1 << 7) /* Bit 7: Enable Audio CODEC Support */ +#define SPI2_CON2_IGNTUR (1 << 8) /* Bit 8: Ignore Transmit Underrun bit */ +#define SPI2_CON2_IGNROV (1 << 9) /* Bit 9: Ignore Receive Overflow */ +#define SPI2_CON2_SPITUREN (1 << 10) /* Bit 10: Enable Interrupt Events via SPITUR */ +#define SPI2_CON2_SPIROVEN (1 << 11) /* Bit 11: Enable Interrupt Events via SPIROV */ +#define SPI2_CON2_FRMERREN (1 << 12) /* Bit 12: Enable Interrupt Events via FRMERR */ + /* Bits 13-14: Reserved */ +#define SPI2_CON2_SPISGNEXT (1 << 15) /* Bit 15 : Sign Extend Read Data from the RX FIFO */ + /* Bits 16-31: Reserved */ + +/* SPI status register */ + +#define SPI_STAT_SPIRBF (1 << 0) /* Bit 0: SPI receive buffer full status */ +#define SPI_STAT_SPITBF (1 << 1) /* Bit 1: SPI transmit buffer full status */ +#define SPI_STAT_SPITBE (1 << 3) /* Bit 3: SPI transmit buffer empty status */ + /* Bit 4: Reserved */ +#define SPI_STAT_SPIRBE (1 << 5) /* Bit 5: RX FIFO Empty */ +#define SPI_STAT_SPIROV (1 << 6) /* Bit 6: Receive overflow flag */ +#define SPI_STAT_SRMT (1 << 7) /* Bit 6: Shift Register Empty */ +#define SPI_STAT_SPITUR (1 << 8) /* Bit 8: Transmit under run */ + /* Bits 9-10: Reserved */ +#define SPI_STAT_SPIBUSY (1 << 11) /* Bit 11: SPI activity status */ +#define SPI_STAT_FRMERR (1 << 12) /* Bit 12: SPI Frame Error status */ + /* Bits 13-15: Reserved */ +#define SPI_STAT_TXBUFELM_SHIFT (16) /* Bits 16-20: Transmit Buffer Element Count bits */ +#define SPI_STAT_TXBUFELM_MASK (31 << SPI_STAT_TXBUFELM_SHIFT) +# define SPI_STAT_TXBUFELM(n) ((uint32_t)(n) << SPI_STAT_TXBUFELM_SHIFT) + /* Bits 21-23: Reserved */ +#define SPI_STAT_RXBUFELM_SHIFT (24) /* Bits 24-28: Receive Buffer Element Count bits */ +#define SPI_STAT_RXBUFELM_MASK (31 << SPI_STAT_RXBUFELM_SHIFT) +# define SPI_STAT_RXBUFELM(n) ((uint32_t)(n) << SPI_STAT_RXBUFELM_SHIFT) + +/* SPI buffer register (32-bits wide) */ + +/* SPI baud rate register */ + +#define SPI_BRG_MASK 0x00001fff + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NSPI > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZ_SPI_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-timer.h b/arch/mips/src/pic32mz/chip/pic32mz-timer.h new file mode 100644 index 0000000000000000000000000000000000000000..4cc12eacf0f6dad9bd61ee36cc85877fea0b358a --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-timer.h @@ -0,0 +1,311 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-timer.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "pic32mz-memorymap.h" + +#if CHIP_NTIMERS > 0 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Timer Peripheral Offsets *********************************************************/ + +#define PIC32MZ_TIMERn_OFFSET(n) ((n) << 9) +# define PIC32MZ_TIMER1_OFFSET 0x0000 +# define PIC32MZ_TIMER2_OFFSET 0x0200 +# define PIC32MZ_TIMER3_OFFSET 0x0400 +# define PIC32MZ_TIMER4_OFFSET 0x0600 +# define PIC32MZ_TIMER5_OFFSET 0x0800 +# define PIC32MZ_TIMER6_OFFSET 0x0a00 +# define PIC32MZ_TIMER7_OFFSET 0x0c00 +# define PIC32MZ_TIMER8_OFFSET 0x0e00 +# define PIC32MZ_TIMER9_OFFSET 0x1000 + +/* Register Offsets *****************************************************************/ + +#define PIC32MZ_TIMER_CON_OFFSET 0x0000 /* Timer control register */ +#define PIC32MZ_TIMER_CONCLR_OFFSET 0x0004 /* Timer control clear register */ +#define PIC32MZ_TIMER_CONSET_OFFSET 0x0008 /* Timer control set register */ +#define PIC32MZ_TIMER_CONINV_OFFSET 0x000c /* Timer control invert register */ + +#define PIC32MZ_TIMER_CNT_OFFSET 0x0010 /* Timer count register */ +#define PIC32MZ_TIMER_CNTCLR_OFFSET 0x0014 /* Timer count clear register */ +#define PIC32MZ_TIMER_CNTSET_OFFSET 0x0018 /* Timer count set register */ +#define PIC32MZ_TIMER_CNTINV_OFFSET 0x001c /* Timer count invert register */ + +#define PIC32MZ_TIMER_PR_OFFSET 0x0020 /* Timer period register */ +#define PIC32MZ_TIMER_PRCLR_OFFSET 0x0024 /* Timer period clear register */ +#define PIC32MZ_TIMER_PRSET_OFFSET 0x0028 /* Timer period set register */ +#define PIC32MZ_TIMER_PRINV_OFFSET 0x002c /* Timer period invert register */ + +/* Timer Peripheral Addresses *******************************************************/ + +#define PIC32MZ_TIMERn_K1BASE(n) (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMERn_OFFSET(n)) +# define PIC32MZ_TIMER1_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER1_OFFSET) +# define PIC32MZ_TIMER2_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER2_OFFSET) +# define PIC32MZ_TIMER3_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER3_OFFSET) +# define PIC32MZ_TIMER4_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER4_OFFSET) +# define PIC32MZ_TIMER5_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER5_OFFSET) +# define PIC32MZ_TIMER6_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER6_OFFSET) +# define PIC32MZ_TIMER7_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER7_OFFSET) +# define PIC32MZ_TIMER8_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER8_OFFSET) +# define PIC32MZ_TIMER9_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER9_OFFSET) + +/* Register Addresses ***************************************************************/ + +#define PIC32MZ_TIMER_CON(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CON_OFFSET) +#define PIC32MZ_TIMER_CONCLR(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CONCLR_OFFSET) +#define PIC32MZ_TIMER_CONSET(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CONSET_OFFSET) +#define PIC32MZ_TIMER_CONINV(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CONINV_OFFSET) +#define PIC32MZ_TIMER_CNT(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CNT_OFFSET) +#define PIC32MZ_TIMER_CNTCLR(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CNTCLR_OFFSET) +#define PIC32MZ_TIMER_CNTSET(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CNTSET_OFFSET) +#define PIC32MZ_TIMER_CNTINV(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_CNTINV_OFFSET) +#define PIC32MZ_TIMER_PR(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_PR_OFFSET) +#define PIC32MZ_TIMER_PRCLR(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_PRCLR_OFFSET) +#define PIC32MZ_TIMER_PRSET(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_PRSET_OFFSET) +#define PIC32MZ_TIMER_PRINV(n) (PIC32MZ_TIMERn_K1BASE(n)+PIC32MZ_TIMER_PRINV_OFFSET) + +#define PIC32MZ_TIMER1_CON (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +#define PIC32MZ_TIMER1_CONCLR (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +#define PIC32MZ_TIMER1_CONSET (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +#define PIC32MZ_TIMER1_CONINV (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +#define PIC32MZ_TIMER1_CNT (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +#define PIC32MZ_TIMER1_CNTCLR (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +#define PIC32MZ_TIMER1_CNTSET (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +#define PIC32MZ_TIMER1_CNTINV (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +#define PIC32MZ_TIMER1_PR (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +#define PIC32MZ_TIMER1_PRCLR (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +#define PIC32MZ_TIMER1_PRSET (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +#define PIC32MZ_TIMER1_PRINV (PIC32MZ_TIMER1_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) + +#if CHIP_NTIMERS > 1 +# define PIC32MZ_TIMER2_CON (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER2_CONCLR (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER2_CONSET (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER2_CONINV (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER2_CNT (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER2_CNTCLR (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER2_CNTSET (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER2_CNTINV (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER2_PR (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER2_PRCLR (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER2_PRSET (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER2_PRINV (PIC32MZ_TIMER2_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 2 +# define PIC32MZ_TIMER3_CON (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER3_CONCLR (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER3_CONSET (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER3_CONINV (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER3_CNT (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER3_CNTCLR (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER3_CNTSET (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER3_CNTINV (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER3_PR (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER3_PRCLR (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER3_PRSET (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER3_PRINV (PIC32MZ_TIMER3_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 3 +# define PIC32MZ_TIMER4_CON (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER4_CONCLR (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER4_CONSET (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER4_CONINV (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER4_CNT (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER4_CNTCLR (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER4_CNTSET (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER4_CNTINV (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER4_PR (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER4_PRCLR (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER4_PRSET (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER4_PRINV (PIC32MZ_TIMER4_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 4 +# define PIC32MZ_TIMER5_CON (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER5_CONCLR (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER5_CONSET (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER5_CONINV (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER5_CNT (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER5_CNTCLR (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER5_CNTSET (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER5_CNTINV (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER5_PR (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER5_PRCLR (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER5_PRSET (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER5_PRINV (PIC32MZ_TIMER5_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 5 +# define PIC32MZ_TIMER6_CON (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER6_CONCLR (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER6_CONSET (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER6_CONINV (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER6_CNT (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER6_CNTCLR (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER6_CNTSET (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER6_CNTINV (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER6_PR (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER6_PRCLR (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER6_PRSET (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER6_PRINV (PIC32MZ_TIMER6_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 6 +# define PIC32MZ_TIMER7_CON (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER7_CONCLR (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER7_CONSET (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER7_CONINV (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER7_CNT (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER7_CNTCLR (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER7_CNTSET (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER7_CNTINV (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER7_PR (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER7_PRCLR (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER7_PRSET (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER7_PRINV (PIC32MZ_TIMER7_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 7 +# define PIC32MZ_TIMER8_CON (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER8_CONCLR (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER8_CONSET (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER8_CONINV (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER8_CNT (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER8_CNTCLR (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER8_CNTSET (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER8_CNTINV (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER8_PR (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER8_PRCLR (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER8_PRSET (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER8_PRINV (PIC32MZ_TIMER8_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + +#if CHIP_NTIMERS > 8 +# define PIC32MZ_TIMER9_CON (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CON_OFFSET) +# define PIC32MZ_TIMER9_CONCLR (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CONCLR_OFFSET) +# define PIC32MZ_TIMER9_CONSET (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CONSET_OFFSET) +# define PIC32MZ_TIMER9_CONINV (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CONINV_OFFSET) +# define PIC32MZ_TIMER9_CNT (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CNT_OFFSET) +# define PIC32MZ_TIMER9_CNTCLR (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CNTCLR_OFFSET) +# define PIC32MZ_TIMER9_CNTSET (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CNTSET_OFFSET) +# define PIC32MZ_TIMER9_CNTINV (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_CNTINV_OFFSET) +# define PIC32MZ_TIMER9_PR (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_PR_OFFSET) +# define PIC32MZ_TIMER9_PRCLR (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_PRCLR_OFFSET) +# define PIC32MZ_TIMER9_PRSET (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_PRSET_OFFSET) +# define PIC32MZ_TIMER9_PRINV (PIC32MZ_TIMER9_K1BASE+PIC32MZ_TIMER_PRINV_OFFSET) +#endif + + +/* Register Bit-Field Definitions ***************************************************/ + +/* Timer control register */ + +#define TIMER_CON_TCS (1 << 1) /* Bit 1: Timer clock source select (all) */ +#define TIMER1_CON_TSYNC (1 << 2) /* Bit 2: Timer external clock input synchronization selection (timer 1 only) */ +#define TIMER_CON_T32 (1 << 3) /* Bit 3: 32-bit timer mode select (even timers only) */ +#define TIMER_CON_TCKPS_SHIFT (4) /* Bits 4-6: Timer input clock prescale select (all except timer 1) */ +#define TIMER_CON_TCKPS_MASK (7 << TIMER_CON_TCKPS_SHIFT) +# define TIMER_CON_TCKPS_1 (0 << TIMER_CON_TCKPS_SHIFT) /* 1:1 prescale value */ +# define TIMER_CON_TCKPS_2 (1 << TIMER_CON_TCKPS_SHIFT) /* 1:2 prescale value */ +# define TIMER_CON_TCKPS_4 (2 << TIMER_CON_TCKPS_SHIFT) /* 1:4 prescale value */ +# define TIMER_CON_TCKPS_8 (3 << TIMER_CON_TCKPS_SHIFT) /* 1:8 prescale value */ +# define TIMER_CON_TCKPS_16 (4 << TIMER_CON_TCKPS_SHIFT) /* 1:16 prescale value */ +# define TIMER_CON_TCKPS_32 (5 << TIMER_CON_TCKPS_SHIFT) /* 1:32 prescale value */ +# define TIMER_CON_TCKPS_64 (6 << TIMER_CON_TCKPS_SHIFT) /* 1:64 prescale value */ +# define TIMER_CON_TCKPS_256 (7 << TIMER_CON_TCKPS_SHIFT) /* 1:256 prescale value */ +#define TIMER1_CON_TCKPS_SHIFT (4) /* Bits 4-5: Timer input clock prescale select (timer 1 only) */ +#define TIMER1_CON_TCKPS_MASK (3 << TIMER1_CON_TCKPS_SHIFT) +# define TIMER1_CON_TCKPS_1 (0 << TIMER1_CON_TCKPS_SHIFT) /* 1:1 prescale value */ +# define TIMER1_CON_TCKPS_8 (1 << TIMER1_CON_TCKPS_SHIFT) /* 1:8 prescale value */ +# define TIMER1_CON_TCKPS_64 (2 << TIMER1_CON_TCKPS_SHIFT) /* 1:64 prescale value */ +# define TIMER1_CON_TCKPS_256 (3 << TIMER1_CON_TCKPS_SHIFT) /* 1:256 prescale value */ +#define TIMER_CON_TGATE (1 << 7) /* Bit 7: Timer gated time accumulation enable (all) */ +#define TIMER1_CON_TWIP (1 << 11) /* Bit 11: Asynchronous timer write in progress (timer 1 only) */ +#define TIMER1_CON_TWDIS (1 << 12) /* Bit 12: Asynchronous timer write disable (timer 1 only) */ +#define TIMER_CON_SIDL (1 << 13) /* Bit 13: Stop in idle mode (all) */ +#define TIMER_CON_ON (1 << 15) /* Bit 15: Timer on (all) */ + +/* Timer count register */ + +#define TIMER_CNT_MASK 0xffff /* 16-bit timer counter value */ + +/* Timer period register */ + +#define TIMER_PR_MASK 0xffff /* 16-bit timer period value */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CHIP_NTIMERS > 0 */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_TIMER_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-uart.h b/arch/mips/src/pic32mz/chip/pic32mz-uart.h new file mode 100644 index 0000000000000000000000000000000000000000..37affc2b89c1104a312321ef26a89a6029b6e76a --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mz-uart.h @@ -0,0 +1,293 @@ +/************************************************************************************ + * arch/mips/src/pic42mz/pic42mz-uart.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CHIP_UART_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CHIP_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "chip/pic32mz-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* UART Peripheral Offsets **********************************************************/ + +#define PIC32MZ_UARTn_OFFSET(n) ((n) << 9) +# define PIC32MZ_UART1_OFFSET 0x0000 +# define PIC32MZ_UART2_OFFSET 0x0200 +# define PIC32MZ_UART3_OFFSET 0x0400 +# define PIC32MZ_UART4_OFFSET 0x0600 +# define PIC32MZ_UART5_OFFSET 0x0800 +# define PIC32MZ_UART6_OFFSET 0x0a00 + +/* Register Offsets *****************************************************************/ + +#define PIC32MZ_UART_MODE_OFFSET 0x0000 /* UARTx mode register */ +#define PIC32MZ_UART_MODECLR_OFFSET 0x0004 /* UARTx mode clear register */ +#define PIC32MZ_UART_MODESET_OFFSET 0x0008 /* UARTx mode set register */ +#define PIC32MZ_UART_MODEINV_OFFSET 0x000c /* UARTx mode invert register */ + +#define PIC32MZ_UART_STA_OFFSET 0x0010 /* UARTx status and control register */ +#define PIC32MZ_UART_STACLR_OFFSET 0x0014 /* UARTx status and control clear register */ +#define PIC32MZ_UART_STASET_OFFSET 0x0018 /* UARTx status and control set register */ +#define PIC32MZ_UART_STAINV_OFFSET 0x001c /* UARTx status and control invert register */ + +#define PIC32MZ_UART_TXREG_OFFSET 0x0020 /* UARTx transmit register */ +#define PIC32MZ_UART_RXREG_OFFSET 0x0030 /* UARTx receive register */ + +#define PIC32MZ_UART_BRG_OFFSET 0x0040 /* UARTx baud rate register */ +#define PIC32MZ_UART_BRGCLR_OFFSET 0x0044 /* UARTx baud rate clear register */ +#define PIC32MZ_UART_BRGSET_OFFSET 0x0048 /* UARTx baud rate set register */ +#define PIC32MZ_UART_BRGINV_OFFSET 0x004c /* UARTx baud rate invert register */ + +/* Timer Peripheral Addresses *******************************************************/ + +#define PIC32MZ_UARTn_K1BASE(n) (PIC32MZ_UART_K1BASE+PIC32MZ_UARTn_OFFSET(n)) +# define PIC32MZ_UART1_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART1_OFFSET) +# define PIC32MZ_UART2_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART2_OFFSET) +# define PIC32MZ_UART3_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART3_OFFSET) +# define PIC32MZ_UART4_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART4_OFFSET) +# define PIC32MZ_UART5_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART5_OFFSET) +# define PIC32MZ_UART6_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART6_OFFSET) +# define PIC32MZ_UART7_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART7_OFFSET) +# define PIC32MZ_UART8_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART8_OFFSET) +# define PIC32MZ_UART9_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART9_OFFSET) + +/* Register Addresses ****************************************************************/ + +#if CHIP_NUARTS > 0 +# define PIC32MZ_UART1_MODE (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART1_MODECLR (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART1_MODESET (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART1_MODEINV (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART1_STA (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART1_STACLR (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART1_STASET (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART1_STAINV (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART1_TXREG (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART1_RXREG (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART1_BRG (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART1_BRGCLR (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART1_BRGSET (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART1_BRGINV (PIC32MZ_UART1_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 1 +# define PIC32MZ_UART2_MODE (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART2_MODECLR (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART2_MODESET (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART2_MODEINV (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART2_STA (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART2_STACLR (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART2_STASET (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART2_STAINV (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART2_TXREG (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART2_RXREG (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART2_BRG (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART2_BRGCLR (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART2_BRGSET (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART2_BRGINV (PIC32MZ_UART2_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 2 +# define PIC32MZ_UART3_MODE (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART3_MODECLR (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART3_MODESET (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART3_MODEINV (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART3_STA (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART3_STACLR (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART3_STASET (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART3_STAINV (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART3_TXREG (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART3_RXREG (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART3_BRG (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART3_BRGCLR (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART3_BRGSET (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART3_BRGINV (PIC32MZ_UART3_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 3 +# define PIC32MZ_UART4_MODE (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART4_MODECLR (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART4_MODESET (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART4_MODEINV (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART4_STA (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART4_STACLR (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART4_STASET (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART4_STAINV (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART4_TXREG (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART4_RXREG (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART4_BRG (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART4_BRGCLR (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART4_BRGSET (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART4_BRGINV (PIC32MZ_UART4_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 4 +# define PIC32MZ_UART5_MODE (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART5_MODECLR (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART5_MODESET (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART5_MODEINV (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART5_STA (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART5_STACLR (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART5_STASET (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART5_STAINV (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART5_TXREG (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART5_RXREG (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART5_BRG (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART5_BRGCLR (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART5_BRGSET (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART5_BRGINV (PIC32MZ_UART5_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +#if CHIP_NUARTS > 5 +# define PIC32MZ_UART6_MODE (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_MODE_OFFSET) +# define PIC32MZ_UART6_MODECLR (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_MODECLR_OFFSET) +# define PIC32MZ_UART6_MODESET (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_MODESET_OFFSET) +# define PIC32MZ_UART6_MODEINV (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_MODEINV_OFFSET) +# define PIC32MZ_UART6_STA (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_STA_OFFSET) +# define PIC32MZ_UART6_STACLR (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_STACLR_OFFSET) +# define PIC32MZ_UART6_STASET (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_STASET_OFFSET) +# define PIC32MZ_UART6_STAINV (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_STAINV_OFFSET) +# define PIC32MZ_UART6_TXREG (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_TXREG_OFFSET) +# define PIC32MZ_UART6_RXREG (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_RXREG_OFFSET) +# define PIC32MZ_UART6_BRG (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_BRG_OFFSET) +# define PIC32MZ_UART6_BRGCLR (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_BRGCLR_OFFSET) +# define PIC32MZ_UART6_BRGSET (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_BRGSET_OFFSET) +# define PIC32MZ_UART6_BRGINV (PIC32MZ_UART6_K1BASE+PIC32MZ_UART_BRGINV_OFFSET) +#endif + +/* Register Bit-Field Definitions ****************************************************/ + +/* UARTx mode register */ + +#define UART_MODE_STSEL (1 << 0) /* Bit 0: Stop selection 1=2 stop bits */ +#define UART_MODE_PDSEL_SHIFT (1) /* Bits: 1-2: Parity and data selection */ +#define UART_MODE_PDSEL_MASK (3 << UART_MODE_PDSEL_SHIFT) +# define UART_MODE_PDSEL_8NONE (0 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, no parity */ +# define UART_MODE_PDSEL_8EVEN (1 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, even parity */ +# define UART_MODE_PDSEL_8ODD (2 << UART_MODE_PDSEL_SHIFT) /* 8-bit data, odd parity */ +# define UART_MODE_PDSEL_9NONE (3 << UART_MODE_PDSEL_SHIFT) /* 9-bit data, no parity */ +#define UART_MODE_BRGH (1 << 3) /* Bit 3: High baud rate enable */ +#define UART_MODE_RXINV (1 << 4) /* Bit 4: Receive polarity inversion */ +#define UART_MODE_ABAUD (1 << 5) /* Bit 5: Auto-baud enable */ +#define UART_MODE_LPBACK (1 << 6) /* Bit 6: UARTx loopback mode select */ +#define UART_MODE_WAKE (1 << 7) /* Bit 7: Enable wake-up on start bit detect during sleep mode */ +#define UART_MODE_UEN_SHIFT (8) /* Bits: 8-9: UARTx enable */ +#define UART_MODE_UEN_MASK (3 << UART_MODE_UEN_SHIFT) +# define UART_MODE_UEN_PORT (0 << UART_MODE_UEN_SHIFT) /* UxCTS+UxRTS/UxBCLK=PORTx register */ +# define UART_MODE_UEN_ENR_CPORT (1 << UART_MODE_UEN_SHIFT) /* UxRTS=enabled; UxCTS=PORTx register */ +# define UART_MODE_UEN_ENCR (2 << UART_MODE_UEN_SHIFT) /* UxCTS+UxRTS=enabled */ +# define UART_MODE_UEN_CPORT (3 << UART_MODE_UEN_SHIFT) /* UxCTS=PORTx register */ +#define UART_MODE_RTSMD (1 << 11) /* Bit 11: Mode selection for ~UxRTS pin */ +#define UART_MODE_IREN (1 << 12) /* Bit 12: IrDA encoder and decoder enable */ +#define UART_MODE_SIDL (1 << 13) /* Bit 13: Stop in idle mode */ +#define UART_MODE_ON (1 << 15) /* Bit 15: UARTx enable */ + +/* UARTx status and control register */ + +#define UART_STA_URXDA (1 << 0) /* Bit 0: Receive buffer data available */ +#define UART_STA_OERR (1 << 1) /* Bit 1: Receive buffer overrun error status */ +#define UART_STA_FERR (1 << 2) /* Bit 2: Framing error status */ +#define UART_STA_PERR (1 << 3) /* Bit 3: Parity error status */ +#define UART_STA_RIDLE (1 << 4) /* Bit 4: Receiver idle */ +#define UART_STA_ADDEN (1 << 5) /* Bit 5: Address character detect */ +#define UART_STA_URXISEL_SHIFT (6) /* Bits: 6-7: Receive interrupt mode selection */ +#define UART_STA_URXISEL_MASK (3 << UART_STA_URXISEL_SHIFT) +# define UART_STA_URXISEL_RECVD (0 << UART_STA_URXISEL_SHIFT) /* Character received */ +# define UART_STA_URXISEL_RXB50 (1 << UART_STA_URXISEL_SHIFT) /* RX buffer 1/2 full */ +# define UART_STA_URXISEL_RXB75 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 full */ +#define UART_STA_UTRMT (1 << 8) /* Bit 8: Transmit shift register is empty */ +#define UART_STA_UTXBF (1 << 9) /* Bit 9: Transmit buffer full status */ +#define UART_STA_UTXEN (1 << 10) /* Bit 10: Transmit enable */ +#define UART_STA_UTXBRK (1 << 11) /* Bit 11: Transmit break */ +#define UART_STA_URXEN (1 << 12) /* Bit 12: Receiver enable */ +#define UART_STA_UTXINV (1 << 13) /* Bit 13: Transmit polarity inversion */ +#define UART_STA_UTXISEL_SHIFT (14) /* Bits: 14-15: TX interrupt mode selection bi */ +#define UART_STA_UTXISEL_MASK (3 << UART_STA_UTXISEL_SHIFT) +# define UART_STA_UTXISEL_TXBNF (0 << UART_STA_UTXISEL_SHIFT) /* TX buffer not full */ +# define UART_STA_UTXISEL_DRAINED (1 << UART_STA_UTXISEL_SHIFT) /* All characters sent */ +# define UART_STA_UTXISEL_TXBE (2 << UART_STA_UTXISEL_SHIFT) /* TX buffer empty */ +#define UART_STA_ADDR_SHIFT (16) /* Bits:16-23: Automatic address mask */ +#define UART_STA_ADDR_MASK (0xff << UART_STA_ADDR_SHIFT) +#define UART_STA_ADM_EN (1 << 24) /* Bit 24: Automatic address detect mode enable */ + +/* UARTx transmit register */ + +#define UART_TXREG_MASK 0x1ff + +/* UARTx receive register */ + +#define UART_RXREG_MASK 0x1ff + +/* UARTx baud rate register */ + +#define UART_BRG_MASK 0xffff + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CHIP_UART_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mzec-features.h b/arch/mips/src/pic32mz/chip/pic32mzec-features.h new file mode 100644 index 0000000000000000000000000000000000000000..3a676f887ebcc111e172de02eb34bef7e1422ccb --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mzec-features.h @@ -0,0 +1,514 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/chip/pic32mzec-features.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_FEATURES_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_FEATURES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Register/Flash Offsets ***********************************************************/ + +/* Device ID, Revision, and Configuration (SFR PIC32MZ_CONFIG_K1BASE) */ + +#define PIC32MZ_CFGCON_OFFSET 0x0000 /* Configuration control register */ +#define PIC32MZ_DEVID_OFFSET 0x0020 /* Device ID and revision register */ +#define PIC32MZ_SYSKEY_OFFSET 0x0030 /* System key register */ +#define PIC32MZ_CFGEBIA_OFFSET 0x00c0 /* External bus interface address pin configuration register */ +#define PIC32MZ_CFGEBIC_OFFSET 0x00d0 /* External bus interface address pin control register */ +#define PIC32MZ_CFGPG_OFFSET 0x00e0 /* Permission group configuration register */ + +/* Alternate Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ + +#define PIC32MZ_ADEVCFG3_OFFSET 0x0000 /* Alternate device configuration word 3 */ +#define PIC32MZ_ADEVCFG2_OFFSET 0x0004 /* Alternate device configuration word 2 */ +#define PIC32MZ_ADEVCFG1_OFFSET 0x0008 /* Alternate device configuration word 1 */ +#define PIC32MZ_ADEVCFG0_OFFSET 0x000c /* Alternate device configuration word 0 */ +#define PIC32MZ_ADEVCP3_OFFSET 0x0010 /* Alternate device code protect word 3 */ +#define PIC32MZ_ADEVCP2_OFFSET 0x0014 /* Alternate device code protect word 2 */ +#define PIC32MZ_ADEVCP1_OFFSET 0x0018 /* Alternate device code protect word 1 */ +#define PIC32MZ_ADEVCP0_OFFSET 0x001c /* Alternate device code protect word 0 */ +#define PIC32MZ_ADEVSIGN3_OFFSET 0x0020 /* Alternate device signature word 3 */ +#define PIC32MZ_ADEVSIGN2_OFFSET 0x0024 /* Alternate device signature word 2 */ +#define PIC32MZ_ADEVSIGN1_OFFSET 0x0028 /* Alternate device signature word 1 */ +#define PIC32MZ_ADEVSIGN0_OFFSET 0x002c /* Alternate device signature word 0 */ + +/* Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ + +#define PIC32MZ_DEVCFG3_OFFSET 0x0080 /* Device configuration word 3 */ +#define PIC32MZ_DEVCFG2_OFFSET 0x0084 /* Device configuration word 2 */ +#define PIC32MZ_DEVCFG1_OFFSET 0x0088 /* Device configuration word 1 */ +#define PIC32MZ_DEVCFG0_OFFSET 0x008c /* Device configuration word 0 */ +#define PIC32MZ_DEVCP3_OFFSET 0x0090 /* Device code protect word 3 */ +#define PIC32MZ_DEVCP2_OFFSET 0x0094 /* Device code protect word 2 */ +#define PIC32MZ_DEVCP1_OFFSET 0x0098 /* Device code protect word 1 */ +#define PIC32MZ_DEVCP0_OFFSET 0x009c /* Device code protect word 0 */ +#define PIC32MZ_DEVSIGN3_OFFSET 0x00a0 /* Device signature word 3 */ +#define PIC32MZ_DEVSIGN2_OFFSET 0x00a4 /* Device signature word 2 */ +#define PIC32MZ_DEVSIGN1_OFFSET 0x00a8 /* Device signature word 1 */ +#define PIC32MZ_DEVSIGN0_OFFSET 0x00ac /* Device signature word 0 */ + +/* Device ADC Calibration (Boot Flash PIC32MZ_ADCCALIB_K1BASE) */ + +#define PIC32MZ_DEVADC1_OFFSET 0x0000 /* ADC1 Calibration */ +#define PIC32MZ_DEVADC2_OFFSET 0x0004 /* ADC2 Calibration */ +#define PIC32MZ_DEVADC3_OFFSET 0x0008 /* ADC3 Calibration */ +#define PIC32MZ_DEVADC4_OFFSET 0x000c /* ADC4 Calibration */ +#define PIC32MZ_DEVADC5_OFFSET 0x0010 /* ADC5 Calibration */ + +/* Device Serial Number (Boot Flash PIC32MZ_DEVSN_K1BASE) */ + +#define PIC32MZ_DEVSN0_OFFSET 0x0000 /* Device serial number 0 */ +#define PIC32MZ_DEVSN1_OFFSET 0x0004 /* Device serial number 1 */ + +/* Register/Flash Addresses *********************************************************/ + +/* Device ID, Revision, and Configuration (SFR PIC32MZ_CONFIG_K1BASE) */ + +#define PIC32MZ_CFGCON (PIC32MZ_CONFIG_K1BASE+PIC32MZ_CFGCON_OFFSET) +#define PIC32MZ_DEVID (PIC32MZ_CONFIG_K1BASE+PIC32MZ_DEVID_OFFSET) +#define PIC32MZ_SYSKEY (PIC32MZ_CONFIG_K1BASE+PIC32MZ_SYSKEY_OFFSET) +#define PIC32MZ_CFGEBIA (PIC32MZ_CONFIG_K1BASE+PIC32MZ_CFGEBIA_OFFSET) +#define PIC32MZ_CFGEBIC (PIC32MZ_CONFIG_K1BASE+PIC32MZ_CFGEBIC_OFFSET) +#define PIC32MZ_CFGPG (PIC32MZ_CONFIG_K1BASE+PIC32MZ_CFGPG_OFFSET) + +/* Alternate Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ + +#define PIC32MZ_ADEVCFG3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCFG3_OFFSET) +#define PIC32MZ_ADEVCFG2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCFG2_OFFSET) +#define PIC32MZ_ADEVCFG1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCFG1_OFFSET) +#define PIC32MZ_ADEVCFG0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCFG0_OFFSET) +#define PIC32MZ_ADEVCP3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCP3_OFFSET) +#define PIC32MZ_ADEVCP2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCP2_OFFSET) +#define PIC32MZ_ADEVCP1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCP1_OFFSET) +#define PIC32MZ_ADEVCP0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVCP0_OFFSET) +#define PIC32MZ_ADEVSIGN3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVSIGN3_OFFSET) +#define PIC32MZ_ADEVSIGN2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVSIGN2_OFFSET) +#define PIC32MZ_ADEVSIGN1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVSIGN1_OFFSET) +#define PIC32MZ_ADEVSIGN0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_ADEVSIGN0_OFFSET) + +/* Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ + +#define PIC32MZ_DEVCFG3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCFG3_OFFSET) +#define PIC32MZ_DEVCFG2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCFG2_OFFSET) +#define PIC32MZ_DEVCFG1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCFG1_OFFSET) +#define PIC32MZ_DEVCFG0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCFG0_OFFSET) +#define PIC32MZ_DEVCP3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCP3_OFFSET) +#define PIC32MZ_DEVCP2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCP2_OFFSET) +#define PIC32MZ_DEVCP1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCP1_OFFSET) +#define PIC32MZ_DEVCP0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVCP0_OFFSET) +#define PIC32MZ_DEVSIGN3 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVSIGN3_OFFSET) +#define PIC32MZ_DEVSIGN2 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVSIGN2_OFFSET) +#define PIC32MZ_DEVSIGN1 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVSIGN1_OFFSET) +#define PIC32MZ_DEVSIGN0 (PIC32MZ_BOOTCFG_K1BASE+PIC32MZ_DEVSIGN0_OFFSET) + +/* Device ADC Calibration (Boot Flash PIC32MZ_ADCCALIB_K1BASE) */ + +#define PIC32MZ_DEVADC1 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVADC1_OFFSET) +#define PIC32MZ_DEVADC2 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVADC2_OFFSET) +#define PIC32MZ_DEVADC3 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVADC3_OFFSET) +#define PIC32MZ_DEVADC4 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVADC4_OFFSET) +#define PIC32MZ_DEVADC5 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVADC5_OFFSET) + +/* Device Serial Number (Boot Flash PIC32MZ_DEVSN_K1BASEPIC32MZ_DEVSN_K1BASE) */ + +#define PIC32MZ_DEVSN0 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVSN0_OFFSET) +#define PIC32MZ_DEVSN1 (PIC32MZ_ADCCALIB_K1BASE+PIC32MZ_DEVSN1_OFFSET) + +/* Register/Flash Bit Field Definitions *********************************************/ + +/* Device ID, Revision, and Configuration (SFR PIC32MZ_CONFIG_K1BASE) */ +/* Configuration control register + * + * NOTE: To change many of the bits in the register, the unlock sequence must first + * be performed. + */ + +#define CFGCON_TDOEN (1 << 0) /* Bit 0: TDO Enable for 2-Wire JTAG */ +#define CFGCON_TROEN (1 << 2) /* Bit 2: Trace Output Enable bit */ +#define CFGCON_JTAGEN (1 << 3) /* Bit 3: JTAG Port Enable bit */ +#define CFGCON_ECCCON_SHIFT (4) /* Bits 4-5: Flash ECC Configuration bits */ +#define CFGCON_ECCCON_MASK (7 << CFGCON_ECCCON_SHIFT) +# define CFGCON_ECCCON_ECC (0 << CFGCON_ECCCON_SHIFT) /* Flash ECC enabled */ +# define CFGCON_ECCCON_DYNECC (1 << CFGCON_ECCCON_SHIFT) /* Dynamic Flash ECC enabled */ +# define CFGCON_ECCCON_DISLCK (2 << CFGCON_ECCCON_SHIFT) /* ECC / dynamic ECC disabled (locked) */ +# define CFGCON_ECCCON_DISWR (3 << CFGCON_ECCCON_SHIFT) /* ECC / dynamic ECC disabled (writable) */ +#define CFGCON_USBSSEN (1 << 8) /* Bit 8: USB Suspend Sleep Enable bit */ +#define CFGCON_PGLOCK (1 << 11) /* Bit 11: Permission Group Lock bit */ +#define CFGCON_PMDLOCK (1 << 12) /* Bit 12: Peripheral Module Disable bit */ +#define CFGCON_IOLOCK (1 << 13) /* Bit 13: Peripheral Pin Select Lock bit */ +#define CFGCON_OCACLK (1 << 16) /* Bit 16: Output Compare Alternate Clock Selection bit */ +#define CFGCON_ICACLK (1 << 17) /* Bit 17: Input Capture Alternate Clock Selection bit */ +#define CFGCON_CPUPRI (1 << 24) /* Bit 24: CPU Arbitration Priority to SRAM */ +#define CFGCON_DMAPRI (1 << 25) /* Bit 25: DMA Read and DMA Write Arbitration Priority */ + +/* Device ID and revision register */ + +#define DEVID_SHIFT (0) /* Bits 0-27: Device ID */ +#define DEVID_MASK (0x0ffffff << DEVID_SHIFT) +#define DEVID_VER_SHIFT (28) /* Bits 28-31: Revision Identifier bits */ +#define DEVID_VER_MASK (15 << DEVID_VER_SHIFT) + +/* System key register: 32-bit key value */ + +#define UNLOCK_SYSKEY_0 (0xaa996655ul) +#define UNLOCK_SYSKEY_1 (0x556699aaul) + +/* External bus interface address pin configuration register */ + +#define CFGEBIA_EBIA0N_SHIFT (0) /* Bits 0-23: EBI address pin 0 enable */ +#define CFGEBIA_EBIA0N_MASK (0x00ffffff << CFGEBIA_EBIA0N_SHIFT) +# define CFGEBIA_EBIA0EN (1 << 0) /* Bit 0: EBI address pin 0 enable */ +# define CFGEBIA_EBIA1EN (1 << 1) /* Bit 1: EBI address pin 1 enable */ +# define CFGEBIA_EBIA2EN (1 << 2) /* Bit 2: EBI address pin 2 enable */ +# define CFGEBIA_EBIA3EN (1 << 3) /* Bit 3: EBI address pin 3 enable */ +# define CFGEBIA_EBIA4EN (1 << 4) /* Bit 4: EBI address pin 4 enable */ +# define CFGEBIA_EBIA5EN (1 << 5) /* Bit 5: EBI address pin 5 enable */ +# define CFGEBIA_EBIA6EN (1 << 6) /* Bit 6: EBI address pin 6 enable */ +# define CFGEBIA_EBIA7EN (1 << 7) /* Bit 7: EBI address pin 7 enable */ +# define CFGEBIA_EBIA8EN (1 << 8) /* Bit 8: EBI address pin 8 enable */ +# define CFGEBIA_EBIA9EN (1 << 9) /* Bit 9: EBI address pin 9 enable */ +# define CFGEBIA_EBIA10EN (1 << 10) /* Bit 10: EBI address pin 10 enable */ +# define CFGEBIA_EBIA11EN (1 << 11) /* Bit 11: EBI address pin 11 enable */ +# define CFGEBIA_EBIA12EN (1 << 12) /* Bit 12: EBI address pin 12 enable */ +# define CFGEBIA_EBIA13EN (1 << 13) /* Bit 13: EBI address pin 13 enable */ +# define CFGEBIA_EBIA14EN (1 << 14) /* Bit 14: EBI address pin 14 enable */ +# define CFGEBIA_EBIA15EN (1 << 15) /* Bit 15: EBI address pin 15 enable */ +# define CFGEBIA_EBIA16EN (1 << 16) /* Bit 16: EBI address pin 16 enable */ +# define CFGEBIA_EBIA17EN (1 << 17) /* Bit 17: EBI address pin 17 enable */ +# define CFGEBIA_EBIA18EN (1 << 18) /* Bit 18: EBI address pin 18 enable */ +# define CFGEBIA_EBIA19EN (1 << 19) /* Bit 19: EBI address pin 19 enable */ +# define CFGEBIA_EBIA20EN (1 << 20) /* Bit 20: EBI address pin 20 enable */ +# define CFGEBIA_EBIA21EN (1 << 21) /* Bit 21: EBI address pin 21 enable */ +# define CFGEBIA_EBIA22EN (1 << 22) /* Bit 22: EBI address pin 22 enable */ +# define CFGEBIA_EBIA23EN (1 << 23) /* Bit 23: EBI address pin 23 enable */ +#define CFGEBIA_EBIPINEN (1 << 31) /* Bit 31: EBI Pin Enable bit */ + +/* External bus interface address pin control register */ + +#define CFGEBIC_EBIRPEN (1 << 16) /* Bit 16: EBIRP Pin Sensitivity Control bit */ +#define CFGEBIC_EBIRDYLVL (1 << 17) /* Bit 17: EBIRDYx Pin Sensitivity Control bit */ +#define CFGEBIC_EBIRDYEN1 (1 << 24) /* Bit 24: EBIRDY1 Pin Enable bit */ +#define CFGEBIC_EBIRDYEN2 (1 << 25) /* Bit 25: EBIRDY2 Pin Enable bit */ +#define CFGEBIC_EBIRDYEN3 (1 << 26) /* Bit 26: EBIRDY3 Pin Enable bit */ +#define CFGEBIC_EBIRDYINV1 (1 << 28) /* Bit 28: EBIRDY1 Inversion Control bit */ +#define CFGEBIC_EBIRDYINV2 (1 << 29) /* Bit 29: EBIRDY2 Inversion Control bit */ +#define CFGEBIC_EBIRDYINV3 (1 << 30) /* Bit 30: EBIRDY3 Inversion Control bit */ + +/* Permission group configuration register */ + +#define CFGPG_GROUP0 0 /* Initiator is assigned to Permission Group 0 */ +#define CFGPG_GROUP1 1 /* Initiator is assigned to Permission Group 1 */ +#define CFGPG_GROUP2 2 /* Initiator is assigned to Permission Group 2 */ +#define CFGPG_GROUP3 3 /* Initiator is assigned to Permission Group 3 */ + +#define CFGPG_CPUPG_SHIFT (0) /* Bits 0-1: CPU Permission Group bits */ +#define CFGPG_CPUPG_MASK (3 << CFGPG_CPUPG_SHIFT) +# define CFGPG_CPUPG(n) ((uint32_t)(n) << CFGPG_CPUPG_SHIFT) +# define CFGPG_CPUPG_GROUP0 CFGPG_CPUPG(CFGPG_GROUP0) +# define CFGPG_CPUPG_GROUP1 CFGPG_CPUPG(CFGPG_GROUP1) +# define CFGPG_CPUPG_GROUP2 CFGPG_CPUPG(CFGPG_GROUP2) +# define CFGPG_CPUPG_GROUP3 CFGPG_CPUPG(CFGPG_GROUP3) +#define CFGPG_DMAPG_SHIFT (4) /* Bits 4-5: DMA Module Permission Group bits */ +#define CFGPG_DMAPG_MASK (3 << CFGPG_DMAPG_SHIFT) +# define CFGPG_DMAPG(n) ((uint32_t)(n) << CFGPG_DMAPG_SHIFT) +# define CFGPG_DMAPG_GROUP0 CFGPG_DMAPG(CFGPG_GROUP0) +# define CFGPG_DMAPG_GROUP1 CFGPG_DMAPG(CFGPG_GROUP1) +# define CFGPG_DMAPG_GROUP2 CFGPG_DMAPG(CFGPG_GROUP2) +# define CFGPG_DMAPG_GROUP3 CFGPG_DMAPG(CFGPG_GROUP3) +#define CFGPG_USBPG_SHIFT (8) /* Bits 8-9: USB Module Permission Group bits */ +#define CFGPG_USBPG_MASK (3 << CFGPG_USBPG_SHIFT) +# define CFGPG_USBPG(n) ((uint32_t)(n) << CFGPG_USBPG_SHIFT) +# define CFGPG_USBPG_GROUP0 CFGPG_USBPG(CFGPG_GROUP0) +# define CFGPG_USBPG_GROUP1 CFGPG_USBPG(CFGPG_GROUP1) +# define CFGPG_USBPG_GROUP2 CFGPG_USBPG(CFGPG_GROUP2) +# define CFGPG_USBPG_GROUP3 CFGPG_USBPG(CFGPG_GROUP3) +#define CFGPG_CAN1PG_SHIFT (12) /* Bits 12-13: CAN1 Module Permission Group bits */ +#define CFGPG_CAN1PG_MASK (3 << CFGPG_CAN1PG_SHIFT) +# define CFGPG_CAN1PG(n) ((uint32_t)(n) << CFGPG_CAN1PG_SHIFT) +# define CFGPG_CAN1PG_GROUP0 CFGPG_CAN1PG(CFGPG_GROUP0) +# define CFGPG_CAN1PG_GROUP1 CFGPG_CAN1PG(CFGPG_GROUP1) +# define CFGPG_CAN1PG_GROUP2 CFGPG_CAN1PG(CFGPG_GROUP2) +# define CFGPG_CAN1PG_GROUP3 CFGPG_CAN1PG(CFGPG_GROUP3) +#define CFGPG_CAN2PG_SHIFT (14) /* Bits 14-15: CAN2 Module Permission Group bits */ +#define CFGPG_CAN2PG_MASK (3 << CFGPG_CAN2PG_SHIFT) +# define CFGPG_CAN2PG(n) ((uint32_t)(n) << CFGPG_CAN2PG_SHIFT) +# define CFGPG_CAN2PG_GROUP0 CFGPG_CAN2PG(CFGPG_GROUP0) +# define CFGPG_CAN2PG_GROUP1 CFGPG_CAN2PG(CFGPG_GROUP1) +# define CFGPG_CAN2PG_GROUP2 CFGPG_CAN2PG(CFGPG_GROUP2) +# define CFGPG_CAN2PG_GROUP3 CFGPG_CAN2PG(CFGPG_GROUP3) +#define CFGPG_ETHPG_SHIFT (16) /* Bits 16-17: Ethernet Module Permission Group bits */ +#define CFGPG_ETHPG_MASK (3 << CFGPG_ETHPG_SHIFT) +# define CFGPG_ETHPG(n) ((uint32_t)(n) << CFGPG_ETHPG_SHIFT) +# define CFGPG_ETHPG_GROUP0 CFGPG_ETHPG(CFGPG_GROUP0) +# define CFGPG_ETHPG_GROUP1 CFGPG_ETHPG(CFGPG_GROUP1) +# define CFGPG_ETHPG_GROUP2 CFGPG_ETHPG(CFGPG_GROUP2) +# define CFGPG_ETHPG_GROUP3 CFGPG_ETHPG(CFGPG_GROUP3) +#define CFGPG_SQI1PG_SHIFT (20) /* Bits 20-21: SQI Module Permission Group bits */ +#define CFGPG_SQI1PG_MASK (3 << CFGPG_SQI1PG_SHIFT) +# define CFGPG_SQI1PG(n) ((uint32_t)(n) << CFGPG_SQI1PG_SHIFT) +# define CFGPG_SQI1PG_GROUP0 CFGPG_SQI1PG(CFGPG_GROUP0) +# define CFGPG_SQI1PG_GROUP1 CFGPG_SQI1PG(CFGPG_GROUP1) +# define CFGPG_SQI1PG_GROUP2 CFGPG_SQI1PG(CFGPG_GROUP2) +# define CFGPG_SQI1PG_GROUP3 CFGPG_SQI1PG(CFGPG_GROUP3) +#define CFGPG_FCPG_SHIFT (22) /* Bits 22-23: Flash Control Permission Group bits */ +#define CFGPG_FCPG_MASK (3 << CFGPG_FCPG_SHIFT) +# define CFGPG_FCPG(n) ((uint32_t)(n) << CFGPG_FCPG_SHIFT) +# define CFGPG_FCPG_GROUP0 CFGPG_FCPG(CFGPG_GROUP0) +# define CFGPG_FCPG_GROUP1 CFGPG_FCPG(CFGPG_GROUP1) +# define CFGPG_FCPG_GROUP2 CFGPG_FCPG(CFGPG_GROUP2) +# define CFGPG_FCPG_GROUP3 CFGPG_FCPG(CFGPG_GROUP3) +#define CFGPG_CRYPTPG_SHIFT (24) /* Bits 24-25: Crypto Engine Permission Group bits */ +#define CFGPG_CRYPTPG_MASK (3 << CFGPG_CRYPTPG_SHIFT) +# define CFGPG_CRYPTPG(n) ((uint32_t)(n) << CFGPG_CRYPTPG_SHIFT) +# define CFGPG_CRYPTPG_GROUP0 CFGPG_CRYPTPG(CFGPG_GROUP0) +# define CFGPG_CRYPTPG_GROUP1 CFGPG_CRYPTPG(CFGPG_GROUP1) +# define CFGPG_CRYPTPG_GROUP2 CFGPG_CRYPTPG(CFGPG_GROUP2) +# define CFGPG_CRYPTPG_GROUP3 CFGPG_CRYPTPG(CFGPG_GROUP3) + +/* Alternate Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ +/* Device Configuration (Boot Flash PIC32MZ_BOOTCFG_K1BASE) */ +/* Device configuration word 3 / Alternate device configuration word 3 */ + +#define DEVCFG3_USERID_SHIFT (0) /* Bit 0-15: 16-bit user defined value */ +#define DEVCFG3_USERID_MASK (0xffff << DEVCFG3_USERID_SHIFT) +# define DEVCFG3_USERID(n) ((uint32_t)(n) << DEVCFG3_USERID_SHIFT) +#define DEVCFG3_FMIIEN_SHIFT (24) /* Bit 24: Ethernet MII Enable Configuration bit */ +#define DEVCFG3_FMIIEN (1 << 24) /* Bit 24: Ethernet MII Enable Configuration bit */ +#define DEVCFG3_FETHIO_SHIFT (25) /* Bit 25: Ethernet I/O Pin Selection Configuration bit */ +#define DEVCFG3_FETHIO (1 << 25) /* Bit 25: Ethernet I/O Pin Selection Configuration bit */ +#define DEVCFG3_PGL1WAY_SHIFT (27) /* Bit 27: Permission Group Lock One Way Configuration bit */ +#define DEVCFG3_PGL1WAY (1 << 27) /* Bit 27: Permission Group Lock One Way Configuration bit */ +#define DEVCFG3_PMDL1WAY_SHIFT (28) /* Bit 28: Peripheral Module Disable Configuration bit */ +#define DEVCFG3_PMDL1WAY (1 << 28) /* Bit 28: Peripheral Module Disable Configuration bit */ +#define DEVCFG3_IOL1WAY_SHIFT (29) /* Bit 29: Peripheral Pin Select Configuration bit */ +#define DEVCFG3_IOL1WAY (1 << 29) /* Bit 29: Peripheral Pin Select Configuration bit */ +#define DEVCFG3_FUSBIDIO_SHIFT (30) /* Bit 30: USB USBID Selection bit */ +#define DEVCFG3_FUSBIDIO (1 << 30) /* Bit 30: USB USBID Selection bit */ + +#define DEVCFG3_RWO 0x84ff0000 /* Bits 16-23, 31: Reserved, write as one */ + +/* Device configuration word 2 / Alternate device configuration word 2 */ + +#define DEVCFG2_FPLLIDIV_SHIFT (0) /* Bits 0-2: PLL Input Divider bits */ +#define DEVCFG2_FPLLIDIV_MASK (7 << DEVCFG2_FPLLIDIV_SHIFT) +# define DEVCFG2_FPLLIDIV(n) ((uint32_t)((n)-1) << DEVCFG2_FPLLIDIV_SHIFT) /* n=1..8 */ +# define DEVCFG2_FPLLIDIV_1 (0 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 1 */ +# define DEVCFG2_FPLLIDIV_2 (1 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 2 */ +# define DEVCFG2_FPLLIDIV_3 (2 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 3 */ +# define DEVCFG2_FPLLIDIV_4 (3 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 4 */ +# define DEVCFG2_FPLLIDIV_5 (4 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 5 */ +# define DEVCFG2_FPLLIDIV_6 (5 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 6 */ +# define DEVCFG2_FPLLIDIV_7 (6 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 7 */ +# define DEVCFG2_FPLLIDIV_8 (7 << DEVCFG2_FPLLIDIV_SHIFT) /* Divide by 8 */ +#define DEVCFG2_FPLLRNG_SHIFT (4) /* Bits 4-6: System PLL Divided Input Clock Frequency Range bits */ +#define DEVCFG2_FPLLRNG_MASK (7 << DEVCFG2_FPLLRNG_SHIFT) +# define DEVCFG2_FPLLRNG_BYPASS (0 << DEVCFG2_FPLLRNG_SHIFT) /* Bypass */ +# define DEVCFG2_FPLLRNG_5_10MHZ (1 << DEVCFG2_FPLLRNG_SHIFT) /* 5-10 MHz */ +# define DEVCFG2_FPLLRNG_8_16MHZ (2 << DEVCFG2_FPLLRNG_SHIFT) /* 8-16 MHz */ +# define DEVCFG2_FPLLRNG_13_26MHZ (3 << DEVCFG2_FPLLRNG_SHIFT) /* 13-26 MHz */ +# define DEVCFG2_FPLLRNG_21_42MHZ (4 << DEVCFG2_FPLLRNG_SHIFT) /* 21-42 MHz */ +# define DEVCFG2_FPLLRNG_34_64MHZ (5 << DEVCFG2_FPLLRNG_SHIFT) /* 34-64 MHz */ +#define DEVCFG2_FPLLICLK (1 << 7) /* Bit 7: System PLL Input Clock Select bit */ +#define DEVCFG2_FPLLMULT_SHIFT (8) /* Bits 8-14: System PLL Feedback Divider bits */ +#define DEVCFG2_FPLLMULT_MASK (0x7f << DEVCFG2_FPLLMULT_SHIFT) +# define DEVCFG2_FPLLMULT(n) ((uint32_t)((n)-1) << DEVCFG2_FPLLMULT_SHIFT) /* n=1..128 */ +#define DEVCFG2_FPLLODIV_SHIFT (16) /* Bits 16-18: Default System PLL Output Divisor bits */ +#define DEVCFG2_FPLLODIV_MASK (7 << DEVCFG2_FPLLODIV_SHIFT) +# define DEVCFG2_FPLLODIV_2 (1 << DEVCFG2_FPLLODIV_SHIFT) /* PLL output divided by 2 */ +# define DEVCFG2_FPLLODIV_4 (2 << DEVCFG2_FPLLODIV_SHIFT) /* PLL output divided by 4 */ +# define DEVCFG2_FPLLODIV_8 (3 << DEVCFG2_FPLLODIV_SHIFT) /* PLL output divided by 8 */ +# define DEVCFG2_FPLLODIV_16 (4 << DEVCFG2_FPLLODIV_SHIFT) /* PLL output divided by 16 */ +# define DEVCFG2_FPLLODIV_32 (5 << DEVCFG2_FPLLODIV_SHIFT) /* PLL output divided by 32 */ +#define DEVCFG2_UPLLFSEL (1 << 30) /* Bit 30: USB PLL Input Frequency Select bit */ +# define DEVCFG2_UPLLFSEL_24MHZ (1 << 30) /* Bit 30=1: UPLL input clock is 24 MHz */ +# define DEVCFG2_UPLLFSEL_12MHZ (0 << 30) /* Bit 30=0: UPLL input clock is 12 MHz */ + +#define DEVCFG2_RWO 0xbff88008 /* Bits 3, 15, 19-29, 31: Reserved, write as one */ + +/* Device configuration word 1 / Alternate device configuration word 1 */ + +#define DEVCFG1_FNOSC_SHIFT (0) /* Bits 0-2: Oscillator Selection bits */ +#define DEVCFG1_FNOSC_MASK (7 << DEVCFG1_FNOSC_SHIFT) +# define DEVCFG1_FNOSC_FRC (0 << DEVCFG1_FNOSC_SHIFT) /* FRC divided by FRCDIV */ +# define DEVCFG1_FNOSC_SPLL (1 << DEVCFG1_FNOSC_SHIFT) /* SPLL */ +# define DEVCFG1_FNOSC_POSC (2 << DEVCFG1_FNOSC_SHIFT) /* POSC (HS, EC) */ +# define DEVCFG1_FNOSC_SOSC (4 << DEVCFG1_FNOSC_SHIFT) /* SOSC */ +# define DEVCFG1_FNOSC_LPRC (5 << DEVCFG1_FNOSC_SHIFT) /* LPRC */ +# define DEVCFG1_FNOSC_FRCDIV (7 << DEVCFG1_FNOSC_SHIFT) /* FRC divided by FRCDIV<2:0> */ +#define DEVCFG1_DMTINV_SHIFT (3) /* Bits 3-5: Deadman Timer Count Window Interval bits */ +#define DEVCFG1_DMTINV_MASK (7 << DEVCFG1_DMTINV_SHIFT) +# define DEVCFG1_DMTINV_0 (0 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value zero */ +# define DEVCFG1_DMTINV_1_2 (1 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 1/2 counter */ +# define DEVCFG1_DMTINV_3_4 (2 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 3/4 counter */ +# define DEVCFG1_DMTINV_7_8 (3 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 7/8 counter */ +# define DEVCFG1_DMTINV_15_16 (4 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 15/16 counter */ +# define DEVCFG1_DMTINV_31_32 (5 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 31/32 counter */ +# define DEVCFG1_DMTINV_63_64 (6 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 63/64 counter */ +# define DEVCFG1_DMTINV_127_128 (7 << DEVCFG1_DMTINV_SHIFT) /* Window/Interval value 127/128 counter */ +#define DEVCFG1_FSOSCEN (1 << 6) /* Bit 6: Secondary Oscillator Enable bit */ +#define DEVCFG1_IESO (1 << 7) /* Bit 7: Internal External Switchover bit */ +#define DEVCFG1_POSCMOD_SHIFT (8) /* Bits 8-9: Primary Oscillator Configuration bits */ +#define DEVCFG1_POSCMOD_MASK (3 << DEVCFG1_POSCMOD_SHIFT) +# define DEVCFG1_POSCMOD_EC (0 << DEVCFG1_POSCMOD_SHIFT) /* EC mode selected */ +# define DEVCFG1_POSCMOD_HS (2 << DEVCFG1_POSCMOD_SHIFT) /* HS Oscillator mode selected */ +# define DEVCFG1_POSCMOD_DIS (3 << DEVCFG1_POSCMOD_SHIFT) /* POSC disabled */ +#define DEVCFG1_OSCIOFNC (1 << 10) /* Bit 10: CLKO Enable Configuration bit */ +#define DEVCFG1_FCKSM_SHIFT (14) /* Bits 14-15: Clock Switching and Monitoring Selection */ +#define DEVCFG1_FCKSM_MASK (3 << DEVCFG1_FCKSM_SHIFT) +# define DEVCFG1_FCKSM_NONE (0 << DEVCFG1_FCKSM_SHIFT) /* Clock switching/monitoring disabled */ +# define DEVCFG1_FCKSM_SWITCH (1 << DEVCFG1_FCKSM_SHIFT) /* Clock switching enabled */ +# define DEVCFG1_FCKSM_MONITOR (2 << DEVCFG1_FCKSM_SHIFT) /* Clock monitoring enabled */ +# define DEVCFG1_FCKSM_BOTH (3 << DEVCFG1_FCKSM_SHIFT) /* Clock switching/monitoring enabled */ +#define DEVCFG1_WDTPS_SHIFT (16) /* Bits 16-20: Watchdog Timer Postscale Select bits */ +#define DEVCFG1_WDTPS_MASK (31 << DEVCFG1_WDTPS_SHIFT) +# define DEVCFG1_WDTPS_1 (0 << DEVCFG1_WDTPS_SHIFT) /* 1:1 */ +# define DEVCFG1_WDTPS_2 (1 << DEVCFG1_WDTPS_SHIFT) /* 1:2 */ +# define DEVCFG1_WDTPS_4 (2 << DEVCFG1_WDTPS_SHIFT) /* 1:4 */ +# define DEVCFG1_WDTPS_8 (3 << DEVCFG1_WDTPS_SHIFT) /* 1:8 */ +# define DEVCFG1_WDTPS_16 (4 << DEVCFG1_WDTPS_SHIFT) /* 1:16 */ +# define DEVCFG1_WDTPS_32 (5 << DEVCFG1_WDTPS_SHIFT) /* 1:32 */ +# define DEVCFG1_WDTPS_64 (6 << DEVCFG1_WDTPS_SHIFT) /* 1:64 */ +# define DEVCFG1_WDTPS_128 (7 << DEVCFG1_WDTPS_SHIFT) /* 1:128 */ +# define DEVCFG1_WDTPS_256 (8 << DEVCFG1_WDTPS_SHIFT) /* 1:256 */ +# define DEVCFG1_WDTPS_512 (9 << DEVCFG1_WDTPS_SHIFT) /* 1:512 */ +# define DEVCFG1_WDTPS_1024 (10 << DEVCFG1_WDTPS_SHIFT) /* 1:1024 */ +# define DEVCFG1_WDTPS_2048 (11 << DEVCFG1_WDTPS_SHIFT) /* 1:2048 */ +# define DEVCFG1_WDTPS_4096 (12 << DEVCFG1_WDTPS_SHIFT) /* 1:4096 */ +# define DEVCFG1_WDTPS_8192 (13 << DEVCFG1_WDTPS_SHIFT) /* 1:8192 */ +# define DEVCFG1_WDTPS_16384 (14 << DEVCFG1_WDTPS_SHIFT) /* 1:16384 */ +# define DEVCFG1_WDTPS_32768 (15 << DEVCFG1_WDTPS_SHIFT) /* 1:32768 */ +# define DEVCFG1_WDTPS_65536 (16 << DEVCFG1_WDTPS_SHIFT) /* 1:65536 */ +# define DEVCFG1_WDTPS_131072 (17 << DEVCFG1_WDTPS_SHIFT) /* 1:131072 */ +# define DEVCFG1_WDTPS_262144 (18 << DEVCFG1_WDTPS_SHIFT) /* 1:262144 */ +# define DEVCFG1_WDTPS_524288 (19 << DEVCFG1_WDTPS_SHIFT) /* 1:524288 */ +# define DEVCFG1_WDTPS_1048576 (20 << DEVCFG1_WDTPS_SHIFT) /* 1:1048576 */ +#define DEVCFG1_WDTSPGM (1 << 21) /* Bit 21: WDT stop/run during flash programming bit */ +# define DEVCFG1_WDTSPGM_STOP (1 << 21) /* Bit 21=1: WDT stops during flash programming */ +# define DEVCFG1_WDTSPGM_RUN (0 << 21) /* Bit 21=0: WDT runs during flash programming */ +#define DEVCFG1_WINDIS (1 << 22) /* Bit 22: Watchdog Timer Window Enable bit */ +# define DEVCFG1_WDT_NORMAL (1 << 22) /* Bit 22=1: Watchdog normal mode */ +# define DEVCFG1_WDT_WINDOW (0 << 22) /* Bit 22=0: Watchdog window mode */ +#define DEVCFG1_FWDTEN (1 << 23) /* Bit 23: Watchdog Timer Enable bit */ +# define DEVCFG1_FWDT_ENABLED (1 << 23) /* Bit 23=1: Watchdog enabled, cannot be disabled */ +# define DEVCFG1_FWDT_DISABLED (0 << 23) /* Bit 23=0: Watchdog disabled, can be enabled */ +#define DEVCFG1_FWDTWINSZ_SHIFT (24) /* Bits 24-25: Watchdog Timer Window Size bits */ +#define DEVCFG1_FWDTWINSZ_MASK (3 << DEVCFG1_FWDTWINSZ_SHIFT) +# define DEVCFG1_FWDTWINSZ_75 (0 << DEVCFG1_FWDTWINSZ_SHIFT) /* Window size is 75% */ +# define DEVCFG1_FWDTWINSZ_50 (1 << DEVCFG1_FWDTWINSZ_SHIFT) /* Window size is 50% */ +# define DEVCFG1_FWDTWINSZ_37p5 (2 << DEVCFG1_FWDTWINSZ_SHIFT) /* Window size is 37.5% */ +# define DEVCFG1_FWDTWINSZ_25 (3 << DEVCFG1_FWDTWINSZ_SHIFT) /* Window size is 25% */ +#define DEVCFG1_DMTCNT_SHIFT (26) /* Bits 26-30: Deadman Timer Count Select bits */ +#define DEVCFG1_DMTCNT_MASK (31 << DEVCFG1_DMTCNT_SHIFT) +# define DEVCFG1_DMTCNT(n) ((uint32_t)((n)-8) << DEVCFG1_DMTCNT_SHIFT) /* 2**n, n=8..31 */ +# define DEVCFG1_DMTCNT_MIN (0 << DEVCFG1_DMTCNT_SHIFT) /* 2**8 (256) */ +# define DEVCFG1_DMTCNT_MAX (23 << DEVCFG1_DMTCNT_SHIFT) /* 2**31 (2147483648) */ +#define DEVCFG1_FDMTEN (1 << 31) /* Bit 31: Deadman Timer enable bit */ + +#define DEVCFG1_RWO 0x00003800 /* Bits 11-13: Reserved, write as one */ + +/* Device configuration word 0 / Alternate device configuration word 0 */ + +#define DEVCFG0_DEBUG_SHIFT (0) /* Bits 0-1: Background Debugger Enable bits */ +#define DEVCFG0_DEBUG_MASK (3 << DEVCFG0_DEBUG_SHIFT) +# define DEVCFG0_DEBUG_ENABLED (2 << DEVCFG0_DEBUG_SHIFT) /* Debugger is enabled */ +# define DEVCFG0_DEBUG_DISABLED (3 << DEVCFG0_DEBUG_SHIFT) /* Debugger is disabled */ +#define DEVCFG0_JTAGEN (1 << 2) /* Bit 2: JTAG Enable bit(1) */ +#define DEVCFG0_ICESEL_SHIFT (3) /* Bits 3-4: ICE Communication Channel Select bits */ +#define DEVCFG0_ICESEL_MASK (3 << DEVCFG0_ICESEL_SHIFT) +# define DEVCFG0_ICESEL_1 (3 << DEVCFG0_ICESEL_SHIFT) /* PGEC1/PGED1 pair is used */ +# define DEVCFG0_ICESEL_2 (2 << DEVCFG0_ICESEL_SHIFT) /* PGEC2/PGED2 pair is used */ +#define DEVCFG0_TRCEN (1 << 5) /* Bit 5: Trace Enable bit */ +#define DEVCFG0_BOOTISA (1 << 6) /* Bit 6: Boot ISA Selection bit */ +# define DEVCFG0_BOOT_MIPS32 (1 << 6) /* Bit 6=1: Boot code and Exception code is MIPS32 */ +# define DEVCFG0_BOOT_MICROMIPS (0 << 6) /* Bit 6=0: Boot code and Exception code is microMIPS */ +#define DEVCFG0_FECCCON_SHIFT (8) /* Bit 8-9: Dynamic Flash ECC Configuration bits */ +#define DEVCFG0_FECCCON_MASK (3 << DEVCFG0_FECCCON_SHIFT) +# define DEVCFG0_FECCCON_ECC (0 << DEVCFG0_FECCCON_SHIFT) /* Flash ECC enabled (locked) */ +# define DEVCFG0_FECCCON_DYNECC (1 << DEVCFG0_FECCCON_SHIFT) /* Dynamic Flash ECC enabled (locked) */ +# define DEVCFG0_FECCCON_DISLCK (2 << DEVCFG0_FECCCON_SHIFT) /* ECC / dynamic ECC disabled (locked) */ +# define DEVCFG0_FECCCON_DISWR (3 << DEVCFG0_FECCCON_SHIFT) /* ECC / dynamic ECC disabled (writable) */ +#define DEVCFG0_FSLEEP (1 << 10) /* Bit 10: Flash Sleep Mode bit */ +# define DEVCFG0_FSLEEP_OFF (1 << 10) /* Bit 10=1: Flash powered down in sleep mode */ +# define DEVCFG0_FSLEEP_ON (0 << 10) /* Bit 10=0: Flash powerdown controlled by VREGS bit */ +#define DEVCFG0_DBGPER_SHIFT (12) /* Bits 12-14: Debug Mode CPU Access Permission bits */ +#define DEVCFG0_DBGPER_MASK (7 << DEVCFG0_DBGPER_SHIFT) +# define DEVCFG0_DBGPER_GROUP0 (1 << DEVCFG0_DBGPER_SHIFT) /* Allow/deny access to group 0 regions */ +# define DEVCFG0_DBGPER_GROUP1 (2 << DEVCFG0_DBGPER_SHIFT) /* Allow/deny access to group 1 regions */ +# define DEVCFG0_DBGPER_GROUP2 (4 << DEVCFG0_DBGPER_SHIFT) /* Allow/deny access to group 2 regions */ +# define DEVCFG0_DBGPER_ALL (7 << DEVCFG0_DBGPER_SHIFT) /* Allow/deny access to all regions */ +#define DEVCFG0_EJTAGBEN (1 << 30) /* Bit 30: EJTAG Boot Enable bit */ +# define DEVCFG0_EJTAG_NORMAL (1 << 30) /* Bit 30=1: Normal EJTAG functionality */ +# define DEVCFG0_EJTAG_REDUCED (0 << 30) /* Bit 30=0: Reduced EJTAG functionality */ + +#define DEVCFG0_RW0 0xbfff8880 /* Bits 7, 11, 15-29, 31: Reserved, write as one */ + +/* Device code protect words 1-3 / Alternate device code protect words 1-3 + * + * The DEVCP1 through DEVCP3 and ADEVCP1 through ADEVCP3 registers are used + * for Quad Word programming operation when programming the DEVCP0/ADEVCP0 + * registers, and do not contain any valid information. + */ + +/* Device code protect word 0 / Alternate device code protect word 0 */ + +#define DEVCP0_CP (1 << 28) /* Bit 28: Code-protect bit */ +#define DEVCP0_RWO 0xefffffff /* Bits 0-27, 28-31: Reserved, write as one */ + +/* Device signature words 1-3 / Alternate device signature words 1-3 + * + * The DEVSIGN1 through DEVSIGN3 and ADEVSIGN1 through ADEVSIGN3 registers + * are used for Quad Word programming operation when programming the + * DEVSIGN0/ADESIGN0 registers, and do not contain any valid information. + */ + +/* Device signature word 0 / Alternate device signature word 0 */ + +#define DEVSIGN0_RWZ 0x80000000 /* Bit 31: Reserved, write as zero */ +#define DEVSIGN0_RWO 0x7fffffff /* Bits 0-30: Reserved, write as one */ + +/* Device ADC Calibration (Boot Flash PIC32MZ_ADCCALIB_K1BASE) */ +/* ADC1-5 Calibration: 32-bit calibration values */ + +/* Device Serial Number (Boot Flash PIC32MZ_DEVSN_K1BASE) */ +/* Device serial number 0-1: 32-bit serial number data */ + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_FEATURES_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mzec-memorymap.h b/arch/mips/src/pic32mz/chip/pic32mzec-memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..dc878ea96dadd994181b75ebb8e358bbc8795aee --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mzec-memorymap.h @@ -0,0 +1,142 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/chip/pic32mzec-memorymap.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_MEMORYMAP_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "mips32-memorymap.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Physical Memory Map **************************************************************/ +/* Memory Regions */ + +#define PIC32MZ_DATAMEM_PBASE 0x00000000 /* Size depends on CHIP_DATAMEM_KB */ +#define PIC32MZ_PROGFLASH_PBASE 0x1d000000 /* Size depends on CHIP_PROGFLASH_KB */ +#define PIC32MZ_SFR_PBASE 0x1f800000 /* Special function registers */ +#define PIC32MZ_BOOTFLASH_PBASE 0x1fc00000 /* Size depends on CHIP_BOOTFLASH_KB */ +#define PIC32MZ_EBIMEM_PBASE 0x20000000 /* External memory via EBI */ +#define PIC32MZ_SQIMEM_PBASE 0x30000000 /* External memory via SQI */ + +/* Boot FLASH */ + +#define PIC32MZ_LOWERBOOT_PBASE 0x1fc00000 /* Lower boot alias */ +#define PIC32MZ_BOOTCFG_PBASE 0x1fc0ff40 /* Configuration space */ +#define PIC32MZ_UPPERBOOT_PBASE 0x1fc20000 /* Upper boot alias */ +#define PIC32MZ_BOOT1_PBASE 0x1fc40000 /* Boot flash 1 */ +#define PIC32MZ_SEQCFG1_PBASE 0x1fc4ff40 /* Sequence/configuration space 1 */ +#define PIC32MZ_ADCCALIB_PBASE 0x1fc54000 /* ADC calibration space */ +#define PIC32MZ_DEVSN_PBASE 0x1fc54020 /* Device serial number */ +#define PIC32MZ_BOOT2_PBASE 0x1fc60000 /* Boot flash 2 */ +#define PIC32MZ_SEQCFG2_PBASE 0x1fc6ff40 /* Sequence/configuration space 2 */ + +/* Virtual Memory Map ***************************************************************/ + +#define PIC32MZ_DATAMEM_K0BASE (KSEG0_BASE + PIC32MZ_DATAMEM_PBASE) +#define PIC32MZ_PROGFLASH_K0BASE (KSEG0_BASE + PIC32MZ_PROGFLASH_PBASE) +#define PIC32MZ_SFR_K0BASE (KSEG0_BASE + PIC32MZ_SFR_PBASE) +#define PIC32MZ_BOOTFLASH_K0BASE (KSEG0_BASE + PIC32MZ_BOOTFLASH_PBASE) +#define PIC32MZ_EBIMEM_K0BASE (KSEG0_BASE + PIC32MZ_EBIMEM_PBASE) +#define PIC32MZ_SQIMEM_K0BASE (KSEG0_BASE + PIC32MZ_SQIMEM_PBASE) + +#define PIC32MZ_DATAMEM_K1BASE (KSEG1_BASE + PIC32MZ_DATAMEM_PBASE) +#define PIC32MZ_PROGFLASH_K1BASE (KSEG1_BASE + PIC32MZ_PROGFLASH_PBASE) +#define PIC32MZ_SFR_K1BASE (KSEG1_BASE + PIC32MZ_SFR_PBASE) +#define PIC32MZ_BOOTFLASH_K1BASE (KSEG1_BASE + PIC32MZ_BOOTFLASH_PBASE) +#define PIC32MZ_EBIMEM_K1BASE (KSEG1_BASE + PIC32MZ_EBIMEM_PBASE) +#define PIC32MZ_SQIMEM_K1BASE (KSEG1_BASE + PIC32MZ_SQIMEM_PBASE) + +/* Boot FLASH */ + +#define PIC32MZ_LOWERBOOT_K0BASE (KSEG0_BASE + PIC32MZ_LOWERBOOT_PBASE) +#define PIC32MZ_BOOTCFG_K0BASE (KSEG0_BASE + PIC32MZ_BOOTCFG_PBASE) +#define PIC32MZ_UPPERBOOT_K0BASE (KSEG0_BASE + PIC32MZ_UPPERBOOT_PBASE) +#define PIC32MZ_BOOT1_K0BASE (KSEG0_BASE + PIC32MZ_BOOT1_PBASE) +#define PIC32MZ_SEQCFG1_K0BASE (KSEG0_BASE + PIC32MZ_SEQCFG1_PBASE) +#define PIC32MZ_ADCCALIB_K0BASE (KSEG0_BASE + PIC32MZ_ADCCALIB_PBASE) +#define PIC32MZ_DEVSN_K0BASE (KSEG0_BASE + PIC32MZ_DEVSN_PBASE) +#define PIC32MZ_BOOT2_K0BASE (KSEG0_BASE + PIC32MZ_BOOT2_PBASE) +#define PIC32MZ_SEQCFG2_K0BASE (KSEG0_BASE + PIC32MZ_SEQCFG2_PBASE) + +#define PIC32MZ_LOWERBOOT_K1BASE (KSEG1_BASE + PIC32MZ_LOWERBOOT_PBASE) +#define PIC32MZ_BOOTCFG_K1BASE (KSEG1_BASE + PIC32MZ_BOOTCFG_PBASE) +#define PIC32MZ_UPPERBOOT_K1BASE (KSEG1_BASE + PIC32MZ_UPPERBOOT_PBASE) +#define PIC32MZ_BOOT1_K1BASE (KSEG1_BASE + PIC32MZ_BOOT1_PBASE) +#define PIC32MZ_SEQCFG1_K1BASE (KSEG1_BASE + PIC32MZ_SEQCFG1_PBASE) +#define PIC32MZ_ADCCALIB_K1BASE (KSEG1_BASE + PIC32MZ_ADCCALIB_PBASE) +#define PIC32MZ_DEVSN_K1BASE (KSEG1_BASE + PIC32MZ_DEVSN_PBASE) +#define PIC32MZ_BOOT2_K1BASE (KSEG1_BASE + PIC32MZ_BOOT2_PBASE) +#define PIC32MZ_SEQCFG2_K1BASE (KSEG1_BASE + PIC32MZ_SEQCFG2_PBASE) + +/* Register Base Addresses **********************************************************/ + +#define PIC32MZ_CONFIG_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000000) /* Configuration */ +#define PIC32MZ_FLASHC_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000600) /* Flash Controller */ +#define PIC32MZ_WDT_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000800) /* Watchdog Timer */ +#define PIC32MZ_DMT_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000a00) /* Deadman Timer */ +#define PIC32MZ_RTCC_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000c00) /* RTCC */ +#define PIC32MZ_CVREF_K1BASE (PIC32MZ_SFR_K1BASE + 0x00000e00) /* CVREF */ +#define PIC32MZ_OSC_K1BASE (PIC32MZ_SFR_K1BASE + 0x00001200) /* Oscillator */ +#define PIC32MZ_PPS_K1BASE (PIC32MZ_SFR_K1BASE + 0x00001400) /* PPS */ +#define PIC32MZ_INT_K1BASE (PIC32MZ_SFR_K1BASE + 0x00010000) /* Interrupt Controller */ +#define PIC32MZ_DMA_K1BASE (PIC32MZ_SFR_K1BASE + 0x00011000) /* DMA */ +#define PIC32MZ_I2C_K1BASE (PIC32MZ_SFR_K1BASE + 0x00020000) /* I2C1-I2C5 */ +#define PIC32MZ_SPI_K1BASE (PIC32MZ_SFR_K1BASE + 0x00021000) /* SPI1-SPI6 */ +#define PIC32MZ_UART_K1BASE (PIC32MZ_SFR_K1BASE + 0x00022000) /* UART1-UART6 */ +#define PIC32MZ_PMP_K1BASE (PIC32MZ_SFR_K1BASE + 0x0002e000) /* PMP */ +#define PIC32MZ_TIMER_K1BASE (PIC32MZ_SFR_K1BASE + 0x00040000) /* Timer1-Timer9 */ +#define PIC32MZ_IC_K1BASE (PIC32MZ_SFR_K1BASE + 0x00042000) /* IC1-IC9 */ +#define PIC32MZ_OC_K1BASE (PIC32MZ_SFR_K1BASE + 0x00044000) /* OC1-OC9 */ +#define PIC32MZ_ADC1_K1BASE (PIC32MZ_SFR_K1BASE + 0x0004b000) /* ADC1 */ +#define PIC32MZ_CMP_K1BASE (PIC32MZ_SFR_K1BASE + 0x0004c000) /* Comparator 1, 2 */ +#define PIC32MZ_IOPORT_K1BASE (PIC32MZ_SFR_K1BASE + 0x00060000) /* PORTA-PORTK */ +#define PIC32MZ_CAN_K1BASE (PIC32MZ_SFR_K1BASE + 0x00080000) /* CAN1 and CAN2 */ +#define PIC32MZ_ETH_K1BASE (PIC32MZ_SFR_K1BASE + 0x00082000) /* Ethernet */ +#define PIC32MZ_PREFETCH_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e0000) /* Prefetch */ +#define PIC32MZ_EBI_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e1000) /* EBI */ +#define PIC32MZ_SQI1_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e2000) /* SQI1 */ +#define PIC32MZ_USB_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e3000) /* USB */ +#define PIC32MZ_CRYPTO_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e5000) /* Crypto */ +#define PIC32MZ_RNG_K1BASE (PIC32MZ_SFR_K1BASE + 0x000e6000) /* RNG */ +#define PIC32MZ_SYSBUS_K1BASE (PIC32MZ_SFR_K1BASE + 0x000f0000) /* System Bus */ + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_MEMORYMAP_H */ diff --git a/arch/mips/src/pic32mz/chip/pic32mzec-pps.h b/arch/mips/src/pic32mz/chip/pic32mzec-pps.h new file mode 100644 index 0000000000000000000000000000000000000000..04a88967729c2a2b96d43feebd50f0a66d1f001a --- /dev/null +++ b/arch/mips/src/pic32mz/chip/pic32mzec-pps.h @@ -0,0 +1,1709 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/pic32mzec-pps.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_PPS_H +#define __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_PPS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include "pic32mz-memorymap.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* PPS Register Offsets *********************************************************************/ + +#define PIC32MZ_INTnR_OFFSET(n) (0x1400 + ((n << 2)) /* n=1..4 */ +# define PIC32MZ_INT1R_OFFSET 0x1404 +# define PIC32MZ_INT2R_OFFSET 0x1408 +# define PIC32MZ_INT3R_OFFSET 0x140c +# define PIC32MZ_INT4R_OFFSET 0x1410 +#define PIC32MZ_TnCKR_OFFSET(n) (0x1410 + ((n << 2)) /* n=2..9 */ +# define PIC32MZ_I2TKR_OFFSET 0x1418 +# define PIC32MZ_I3TKR_OFFSET 0x141c +# define PIC32MZ_I4TKR_OFFSET 0x1420 +# define PIC32MZ_I5TKR_OFFSET 0x1424 +# define PIC32MZ_I6TKR_OFFSET 0x1428 +# define PIC32MZ_I7TKR_OFFSET 0x142c +# define PIC32MZ_I8TKR_OFFSET 0x1430 +# define PIC32MZ_I9TKR_OFFSET 0x1434 +#define PIC32MZ_ICnR_OFFSET(n) (0x1434 + ((n << 2)) /* n=1..9 */ +# define PIC32MZ_IC1R_OFFSET 0x1438 +# define PIC32MZ_IC2R_OFFSET 0x143c +# define PIC32MZ_IC3R_OFFSET 0x1440 +# define PIC32MZ_IC4R_OFFSET 0x1444 +# define PIC32MZ_IC5R_OFFSET 0x1448 +# define PIC32MZ_IC6R_OFFSET 0x144c +# define PIC32MZ_IC7R_OFFSET 0x1450 +# define PIC32MZ_IC8R_OFFSET 0x1454 +# define PIC32MZ_IC9R_OFFSET 0x1458 +#define PIC32MZ_OCFAR_OFFSET 0x1460 +#define PIC32MZ_UnRXR_OFFSET(n) (0x1460 + ((n << 3)) /* n=1..6 */ +# define PIC32MZ_U1RXR_OFFSET 0x1468 +# define PIC32MZ_U2RXR_OFFSET 0x1470 +# define PIC32MZ_U3RXR_OFFSET 0x1478 +# define PIC32MZ_U4RXR_OFFSET 0x1480 +# define PIC32MZ_U5RXR_OFFSET 0x1488 +# define PIC32MZ_U6RXR_OFFSET 0x1490 +#define PIC32MZ_UnCTSR_OFFSET(n) (0x1464 + ((n << 3)) /* n=1..6 */ +# define PIC32MZ_U1CTSR_OFFSET 0x146c +# define PIC32MZ_U2CTSR_OFFSET 0x1474 +# define PIC32MZ_U3CTSR_OFFSET 0x147c +# define PIC32MZ_U4CTSR_OFFSET 0x1484 +# define PIC32MZ_U5CTSR_OFFSET 0x148c +# define PIC32MZ_U6CTSR_OFFSET 0x1494 +#define PIC32MZ_SDInR_OFFSET(n) (0x1490 + 12*(n)) /* n=1..6 */ +# define PIC32MZ_SDI1R_OFFSET 0x149c +# define PIC32MZ_SDI2R_OFFSET 0x14a8 +# define PIC32MZ_SDI3R_OFFSET 0x14b4 +# define PIC32MZ_SDI4R_OFFSET 0x14c0 +# define PIC32MZ_SDI5R_OFFSET 0x14cc +# define PIC32MZ_SDI6R_OFFSET 0x14d8 +#define PIC32MZ_SSnR_OFFSET(n) (0x1490 + 12*(n)) /* n=1..6 */ +# define PIC32MZ_SS1R_OFFSET 0x14a0 +# define PIC32MZ_SS2R_OFFSET 0x14ac +# define PIC32MZ_SS3R_OFFSET 0x14b8 +# define PIC32MZ_SS4R_OFFSET 0x14c4 +# define PIC32MZ_SS5R_OFFSET 0x14d0 +# define PIC32MZ_SS6R_OFFSET 0x14dc +#define PIC32MZ_CnRXR_OFFSET(n) (0x14dc + ((n) << 2)) /* n=1..2 */ +# define PIC32MZ_C1RXR_OFFSET 0x14e0 +# define PIC32MZ_C2RXR_OFFSET 0x14e4 +#define PIC32MZ_REFCLKInR_OFFSET(n) (0x14e4 + ((n) << 2)) /* n=1,3,4 */ +# define PIC32MZ_REFCLKI1R_OFFSET 0x14e8 +# define PIC32MZ_REFCLKI3R_OFFSET 0x14f0 +# define PIC32MZ_REFCLKI4R_OFFSET 0x14f4 +#define PIC32MZ_RPAnR_OFFSET(n) (0x1500 + ((n) << 2)) /* n=14,15 */ +# define PIC32MZ_RPA14R_OFFSET 0x1538 +# define PIC32MZ_RPA15R_OFFSET 0x153c +#define PIC32MZ_RPBnR_OFFSET(n) (0x1540 + ((n) << 2)) /* n=0..,15 */ +# define PIC32MZ_RPB0R_OFFSET 0x1540 +# define PIC32MZ_RPB1R_OFFSET 0x1544 +# define PIC32MZ_RPB2R_OFFSET 0x1548 +# define PIC32MZ_RPB3R_OFFSET 0x154c +# define PIC32MZ_RPB4R_OFFSET 0x1550 +# define PIC32MZ_RPB5R_OFFSET 0x1554 +# define PIC32MZ_RPB6R_OFFSET 0x1558 +# define PIC32MZ_RPB7R_OFFSET 0x155c +# define PIC32MZ_RPB8R_OFFSET 0x1560 +# define PIC32MZ_RPB9R_OFFSET 0x1564 +# define PIC32MZ_RPB10R_OFFSET 0x1568 +# define PIC32MZ_RPB11R_OFFSET 0x156c +# define PIC32MZ_RPB12R_OFFSET 0x1570 +# define PIC32MZ_RPB13R_OFFSET 0x1574 +# define PIC32MZ_RPB14R_OFFSET 0x1578 +# define PIC32MZ_RPB15R_OFFSET 0x157c +#define PIC32MZ_RPCnR_OFFSET(n) (0x1580 + ((n) << 2)) /* n=1..4,13,14 */ +# define PIC32MZ_RPC1R_OFFSET 0x1584 +# define PIC32MZ_RPC2R_OFFSET 0x1588 +# define PIC32MZ_RPC3R_OFFSET 0x158c +# define PIC32MZ_RPC4R_OFFSET 0x1590 +# define PIC32MZ_RPC13R_OFFSET 0x15b4 +# define PIC32MZ_RPC14R_OFFSET 0x15b8 +#define PIC32MZ_RPDnR_OFFSET(n) (0x15c0 + ((n) << 2)) /* n=0..15 */ +# define PIC32MZ_RPD0R_OFFSET 0x15c0 +# define PIC32MZ_RPD1R_OFFSET 0x15c4 +# define PIC32MZ_RPD2R_OFFSET 0x15c8 +# define PIC32MZ_RPD3R_OFFSET 0x15cc +# define PIC32MZ_RPD4R_OFFSET 0x15d0 +# define PIC32MZ_RPD5R_OFFSET 0x15d4 +# define PIC32MZ_RPD6R_OFFSET 0x15d8 +# define PIC32MZ_RPD7R_OFFSET 0x15dc +# define PIC32MZ_RPD8R_OFFSET 0x15e0 +# define PIC32MZ_RPD9R_OFFSET 0x15e4 +# define PIC32MZ_RPD10R_OFFSET 0x15e8 +# define PIC32MZ_RPD11R_OFFSET 0x15ec +# define PIC32MZ_RPD12R_OFFSET 0x15f0 +# define PIC32MZ_RPD13R_OFFSET 0x15f4 +# define PIC32MZ_RPD14R_OFFSET 0x15f8 +# define PIC32MZ_RPD15R_OFFSET 0x15fc +#define PIC32MZ_RPEnR_OFFSET(n) (0x1600 + ((n) << 2)) /* n=3,5,8-9 */ +# define PIC32MZ_RPE3R_OFFSET 0x160c +# define PIC32MZ_RPE4R_OFFSET 0x1614 +# define PIC32MZ_RPE8R_OFFSET 0x1620 +# define PIC32MZ_RPE9R_OFFSET 0x1624 +#define PIC32MZ_RPFnR_OFFSET(n) (0x1640 + ((n) << 2)) /* n=0-5,8,12-13 */ +# define PIC32MZ_RPF0R_OFFSET 0x1640 +# define PIC32MZ_RPF1R_OFFSET 0x1644 +# define PIC32MZ_RPF2R_OFFSET 0x1648 +# define PIC32MZ_RPF3R_OFFSET 0x164c +# define PIC32MZ_RPF4R_OFFSET 0x1650 +# define PIC32MZ_RPF5R_OFFSET 0x1654 +# define PIC32MZ_RPF8R_OFFSET 0x1660 +# define PIC32MZ_RPF12R_OFFSET 0x1670 +# define PIC32MZ_RPF13R_OFFSET 0x1674 +#define PIC32MZ_RPGnR_OFFSET(n) (0x1680 + ((n) << 2)) /* n=0-1,6-8,9 */ +# define PIC32MZ_RPG0R_OFFSET 0x1680 +# define PIC32MZ_RPG1R_OFFSET 0x1684 +# define PIC32MZ_RPG6R_OFFSET 0x1698 +# define PIC32MZ_RPG7R_OFFSET 0x169c +# define PIC32MZ_RPG8R_OFFSET 0x16a0 +# define PIC32MZ_RPG9R_OFFSET 0x16a4 + +/* PPS Register Addresses *******************************************************************/ + +#define PIC32MZ_INTnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_INTnR_OFFSET(n)) +# define PIC32MZ_INT1R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT1R_OFFSET) +# define PIC32MZ_INT2R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT2R_OFFSET) +# define PIC32MZ_INT3R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT3R_OFFSET) +# define PIC32MZ_INT4R (PIC32MZ_SFR_K1BASE+PIC32MZ_INT4R_OFFSET) +#define PIC32MZ_TnCKR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_TnCKR_OFFSET(n)) +# define PIC32MZ_I2TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I2TKR_OFFSET) +# define PIC32MZ_I3TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I3TKR_OFFSET) +# define PIC32MZ_I4TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I4TKR_OFFSET) +# define PIC32MZ_I5TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I5TKR_OFFSET) +# define PIC32MZ_I6TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I6TKR_OFFSET) +# define PIC32MZ_I7TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I7TKR_OFFSET) +# define PIC32MZ_I8TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I8TKR_OFFSET) +# define PIC32MZ_I9TKR (PIC32MZ_SFR_K1BASE+PIC32MZ_I9TKR_OFFSET) +#define PIC32MZ_ICnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_ICnR_OFFSET(n)) +# define PIC32MZ_IC1R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC1R_OFFSET) +# define PIC32MZ_IC2R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC2R_OFFSET) +# define PIC32MZ_IC3R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC3R_OFFSET) +# define PIC32MZ_IC4R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC4R_OFFSET) +# define PIC32MZ_IC5R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC5R_OFFSET) +# define PIC32MZ_IC6R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC6R_OFFSET) +# define PIC32MZ_IC7R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC7R_OFFSET) +# define PIC32MZ_IC8R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC8R_OFFSET) +# define PIC32MZ_IC9R (PIC32MZ_SFR_K1BASE+PIC32MZ_IC9R_OFFSET) +#define PIC32MZ_OCFAR (PIC32MZ_SFR_K1BASE+PIC32MZ_OCFAR_OFFSET) +#define PIC32MZ_UnRXR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_UnRXR_OFFSET(n)) +# define PIC32MZ_U1RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U1RXR_OFFSET) +# define PIC32MZ_U2RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U2RXR_OFFSET) +# define PIC32MZ_U3RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U3RXR_OFFSET) +# define PIC32MZ_U4RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U4RXR_OFFSET) +# define PIC32MZ_U5RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U5RXR_OFFSET) +# define PIC32MZ_U6RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_U6RXR_OFFSET) +#define PIC32MZ_UnCTSR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_UnCTSR_OFFSET(n) +# define PIC32MZ_U1CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U1CTSR_OFFSET) +# define PIC32MZ_U2CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U2CTSR_OFFSET) +# define PIC32MZ_U3CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U3CTSR_OFFSET) +# define PIC32MZ_U4CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U4CTSR_OFFSET) +# define PIC32MZ_U5CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U5CTSR_OFFSET) +# define PIC32MZ_U6CTSR (PIC32MZ_SFR_K1BASE+PIC32MZ_U6CTSR_OFFSET) +#define PIC32MZ_SDInR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_SDInR_OFFSET(n)) +# define PIC32MZ_SDI1R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI1R_OFFSET) +# define PIC32MZ_SDI2R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI2R_OFFSET) +# define PIC32MZ_SDI3R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI3R_OFFSET) +# define PIC32MZ_SDI4R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI4R_OFFSET) +# define PIC32MZ_SDI5R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI5R_OFFSET) +# define PIC32MZ_SDI6R (PIC32MZ_SFR_K1BASE+PIC32MZ_SDI6R_OFFSET) +#define PIC32MZ_SSnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_SSnR_OFFSET(n)) +# define PIC32MZ_SS1R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS1R_OFFSET) +# define PIC32MZ_SS2R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS2R_OFFSET) +# define PIC32MZ_SS3R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS3R_OFFSET) +# define PIC32MZ_SS4R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS4R_OFFSET) +# define PIC32MZ_SS5R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS5R_OFFSET) +# define PIC32MZ_SS6R (PIC32MZ_SFR_K1BASE+PIC32MZ_SS6R_OFFSET) +#define PIC32MZ_CnRXR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_CnRXR_OFFSET(n)) +# define PIC32MZ_C1RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_C1RXR_OFFSET) +# define PIC32MZ_C2RXR (PIC32MZ_SFR_K1BASE+PIC32MZ_C2RXR_OFFSET) +#define PIC32MZ_REFCLKInR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_REFCLKInR_OFFSET(n)) +# define PIC32MZ_REFCLKI1R (PIC32MZ_SFR_K1BASE+PIC32MZ_REFCLKI1R_OFFSET) +# define PIC32MZ_REFCLKI3R (PIC32MZ_SFR_K1BASE+PIC32MZ_REFCLKI3R_OFFSET) +# define PIC32MZ_REFCLKI4R (PIC32MZ_SFR_K1BASE+PIC32MZ_REFCLKI4R_OFFSET) +#define PIC32MZ_RPAnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPAnR_OFFSET(n)) +# define PIC32MZ_RPA14R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPA14R_OFFSET) +# define PIC32MZ_RPA15R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPA15R_OFFSET) +#define PIC32MZ_RPBnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPBnR_OFFSET(n)) +# define PIC32MZ_RPB0R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB0R_OFFSET) +# define PIC32MZ_RPB1R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB1R_OFFSET) +# define PIC32MZ_RPB2R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB2R_OFFSET) +# define PIC32MZ_RPB3R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB3R_OFFSET) +# define PIC32MZ_RPB4R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB4R_OFFSET) +# define PIC32MZ_RPB5R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB5R_OFFSET) +# define PIC32MZ_RPB6R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB6R_OFFSET) +# define PIC32MZ_RPB7R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB7R_OFFSET) +# define PIC32MZ_RPB8R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB8R_OFFSET) +# define PIC32MZ_RPB9R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB9R_OFFSET) +# define PIC32MZ_RPB10R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB10R_OFFSET) +# define PIC32MZ_RPB11R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB11R_OFFSET) +# define PIC32MZ_RPB12R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB12R_OFFSET) +# define PIC32MZ_RPB13R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB13R_OFFSET) +# define PIC32MZ_RPB14R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB14R_OFFSET) +# define PIC32MZ_RPB15R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPB15R_OFFSET) +#define PIC32MZ_RPCnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPCnR_OFFSET(n)) +# define PIC32MZ_RPC1R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC1R_OFFSET) +# define PIC32MZ_RPC2R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC2R_OFFSET) +# define PIC32MZ_RPC3R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC3R_OFFSET) +# define PIC32MZ_RPC4R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC4R_OFFSET) +# define PIC32MZ_RPC13R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC13R_OFFSET) +# define PIC32MZ_RPC14R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPC14R_OFFSET) +#define PIC32MZ_RPDnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPDnR_OFFSET(n)) +# define PIC32MZ_RPD0R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD0R_OFFSET) +# define PIC32MZ_RPD1R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD1R_OFFSET) +# define PIC32MZ_RPD2R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD2R_OFFSET) +# define PIC32MZ_RPD3R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD3R_OFFSET) +# define PIC32MZ_RPD4R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD4R_OFFSET) +# define PIC32MZ_RPD5R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD5R_OFFSET) +# define PIC32MZ_RPD6R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD6R_OFFSET) +# define PIC32MZ_RPD7R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD7R_OFFSET) +# define PIC32MZ_RPD8R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD8R_OFFSET) +# define PIC32MZ_RPD9R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD9R_OFFSET) +# define PIC32MZ_RPD10R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD10R_OFFSET) +# define PIC32MZ_RPD11R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD11R_OFFSET) +# define PIC32MZ_RPD12R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD12R_OFFSET) +# define PIC32MZ_RPD13R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD13R_OFFSET) +# define PIC32MZ_RPD14R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD14R_OFFSET) +# define PIC32MZ_RPD15R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPD15R_OFFSET) +#define PIC32MZ_RPEnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPEnR_OFFSET(n)) +# define PIC32MZ_RPE3R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPE3R_OFFSET) +# define PIC32MZ_RPE4R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPE4R_OFFSET) +# define PIC32MZ_RPE8R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPE8R_OFFSET) +# define PIC32MZ_RPE9R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPE9R_OFFSET) +#define PIC32MZ_RPFnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPFnR_OFFSET(n)) +# define PIC32MZ_RPF0R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF0R_OFFSET) +# define PIC32MZ_RPF1R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF1R_OFFSET) +# define PIC32MZ_RPF2R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF2R_OFFSET) +# define PIC32MZ_RPF3R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF3R_OFFSET) +# define PIC32MZ_RPF4R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF4R_OFFSET) +# define PIC32MZ_RPF5R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF5R_OFFSET) +# define PIC32MZ_RPF8R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF8R_OFFSET) +# define PIC32MZ_RPF12R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF12R_OFFSET) +# define PIC32MZ_RPF13R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPF13R_OFFSET) +#define PIC32MZ_RPGnR(n) (PIC32MZ_SFR_K1BASE+PIC32MZ_RPGnR_OFFSET(n)) +# define PIC32MZ_RPG0R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG0R_OFFSET) +# define PIC32MZ_RPG1R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG1R_OFFSET) +# define PIC32MZ_RPG6R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG6R_OFFSET) +# define PIC32MZ_RPG7R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG7R_OFFSET) +# define PIC32MZ_RPG8R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG8R_OFFSET) +# define PIC32MZ_RPG9R (PIC32MZ_SFR_K1BASE+PIC32MZ_RPG9R_OFFSET) + +/* Input Pin Selection **********************************************************************/ +/* The encoding of the input pin selection is simple. Since we know the devices, we also + * can infer the register address so we need only the value for the register which is + * exactly what is provided by the following definitions. + */ + +#define C1RXR_RPA15 13 +#define C1RXR_RPB1 5 +#define C1RXR_RPB3 8 +#define C1RXR_RPC4 10 +#define C1RXR_RPC13 7 +#define C1RXR_RPD3 0 +#define C1RXR_RPD7 14 +#define C1RXR_RPD11 3 +#define C1RXR_RPD15 11 +#define C1RXR_RPE5 6 +#define C1RXR_RPF0 4 +#define C1RXR_RPF5 2 +#define C1RXR_RPG0 12 +#define C1RXR_RPG7 1 + +#define C2RXR_RPB0 5 +#define C2RXR_RPB7 7 +#define C2RXR_RPB8 2 +#define C2RXR_RPB15 3 +#define C2RXR_RPC3 12 +#define C2RXR_RPD4 4 +#define C2RXR_RPD9 0 +#define C2RXR_RPD12 10 +#define C2RXR_RPE3 6 +#define C2RXR_RPE9 13 +#define C2RXR_RPF8 11 +#define C2RXR_RPF12 9 +#define C2RXR_RPG6 1 + +#define IC1R_RPB2 7 +#define IC1R_RPB6 5 +#define IC1R_RPB14 2 +#define IC1R_RPC2 12 +#define IC1R_RPD0 3 +#define IC1R_RPD1 0 +#define IC1R_RPD5 6 +#define IC1R_RPE8 13 +#define IC1R_RPF2 11 +#define IC1R_RPF3 8 +#define IC1R_RPF13 9 +#define IC1R_RPG9 1 + +#define IC2R_RPB0 5 +#define IC2R_RPB7 7 +#define IC2R_RPB8 2 +#define IC2R_RPB15 3 +#define IC2R_RPC3 12 +#define IC2R_RPD4 4 +#define IC2R_RPD9 0 +#define IC2R_RPD12 10 +#define IC2R_RPE3 6 +#define IC2R_RPE9 13 +#define IC2R_RPF8 11 +#define IC2R_RPF12 9 +#define IC2R_RPG6 1 + +#define IC3R_RPA14 13 +#define IC3R_RPB5 8 +#define IC3R_RPB9 5 +#define IC3R_RPB10 6 +#define IC3R_RPC1 10 +#define IC3R_RPC14 7 +#define IC3R_RPD2 0 +#define IC3R_RPD6 14 +#define IC3R_RPD10 3 +#define IC3R_RPD14 11 +#define IC3R_RPF1 4 +#define IC3R_RPF4 2 +#define IC3R_RPG1 12 +#define IC3R_RPG8 1 + +#define IC4R_RPA15 13 +#define IC4R_RPB1 5 +#define IC4R_RPB3 8 +#define IC4R_RPC4 10 +#define IC4R_RPC13 7 +#define IC4R_RPD3 0 +#define IC4R_RPD7 14 +#define IC4R_RPD11 3 +#define IC4R_RPD15 11 +#define IC4R_RPE5 6 +#define IC4R_RPF0 4 +#define IC4R_RPF5 2 +#define IC4R_RPG0 12 +#define IC4R_RPG7 1 + +#define IC5R_RPB0 5 +#define IC5R_RPB7 7 +#define IC5R_RPB8 2 +#define IC5R_RPB15 3 +#define IC5R_RPC3 12 +#define IC5R_RPD4 4 +#define IC5R_RPD9 0 +#define IC5R_RPD12 10 +#define IC5R_RPE3 6 +#define IC5R_RPE9 13 +#define IC5R_RPF8 11 +#define IC5R_RPF12 9 +#define IC5R_RPG6 1 + +#define IC6R_RPB2 7 +#define IC6R_RPB6 5 +#define IC6R_RPB14 2 +#define IC6R_RPC2 12 +#define IC6R_RPD0 3 +#define IC6R_RPD1 0 +#define IC6R_RPD5 6 +#define IC6R_RPE8 13 +#define IC6R_RPF2 11 +#define IC6R_RPF3 8 +#define IC6R_RPF13 9 +#define IC6R_RPG9 1 + +#define IC7R_RPA14 13 +#define IC7R_RPB5 8 +#define IC7R_RPB9 5 +#define IC7R_RPB10 6 +#define IC7R_RPC1 10 +#define IC7R_RPC14 7 +#define IC7R_RPD2 0 +#define IC7R_RPD6 14 +#define IC7R_RPD10 3 +#define IC7R_RPD14 11 +#define IC7R_RPF1 4 +#define IC7R_RPF4 2 +#define IC7R_RPG1 12 +#define IC7R_RPG8 1 + +#define IC8R_RPA15 13 +#define IC8R_RPB1 5 +#define IC8R_RPB3 8 +#define IC8R_RPC4 10 +#define IC8R_RPC13 7 +#define IC8R_RPD3 0 +#define IC8R_RPD7 14 +#define IC8R_RPD11 3 +#define IC8R_RPD15 11 +#define IC8R_RPE5 6 +#define IC8R_RPF0 4 +#define IC8R_RPF5 2 +#define IC8R_RPG0 12 +#define IC8R_RPG7 1 + +#define IC9R_RPB0 5 +#define IC9R_RPB7 7 +#define IC9R_RPB8 2 +#define IC9R_RPB15 3 +#define IC9R_RPC3 12 +#define IC9R_RPD4 4 +#define IC9R_RPD9 0 +#define IC9R_RPD12 10 +#define IC9R_RPE3 6 +#define IC9R_RPE9 13 +#define IC9R_RPF8 11 +#define IC9R_RPF12 9 +#define IC9R_RPG6 1 + +#define INT1R_RPB2 7 +#define INT1R_RPB6 5 +#define INT1R_RPB14 2 +#define INT1R_RPC2 12 +#define INT1R_RPD0 3 +#define INT1R_RPD1 0 +#define INT1R_RPD5 6 +#define INT1R_RPE8 13 +#define INT1R_RPF2 11 +#define INT1R_RPF3 8 +#define INT1R_RPF13 9 +#define INT1R_RPG9 1 + +#define INT2R_RPB0 5 +#define INT2R_RPB7 7 +#define INT2R_RPB8 2 +#define INT2R_RPB15 3 +#define INT2R_RPC3 12 +#define INT2R_RPD4 4 +#define INT2R_RPD9 0 +#define INT2R_RPD12 10 +#define INT2R_RPE3 6 +#define INT2R_RPE9 13 +#define INT2R_RPF8 11 +#define INT2R_RPF12 9 +#define INT2R_RPG6 1 + +#define INT3R_RPA14 13 +#define INT3R_RPB5 8 +#define INT3R_RPB9 5 +#define INT3R_RPB10 6 +#define INT3R_RPC1 10 +#define INT3R_RPC14 7 +#define INT3R_RPD2 0 +#define INT3R_RPD6 14 +#define INT3R_RPD10 3 +#define INT3R_RPD14 11 +#define INT3R_RPF1 4 +#define INT3R_RPF4 2 +#define INT3R_RPG1 12 +#define INT3R_RPG8 1 + +#define INT4R_RPA15 13 +#define INT4R_RPB1 5 +#define INT4R_RPB3 8 +#define INT4R_RPC4 10 +#define INT4R_RPC13 7 +#define INT4R_RPD3 0 +#define INT4R_RPD7 14 +#define INT4R_RPD11 3 +#define INT4R_RPD15 11 +#define INT4R_RPE5 6 +#define INT4R_RPF0 4 +#define INT4R_RPF5 2 +#define INT4R_RPG0 12 +#define INT4R_RPG7 1 + +#define OCFAR_RPB2 7 +#define OCFAR_RPB6 5 +#define OCFAR_RPB14 2 +#define OCFAR_RPC2 12 +#define OCFAR_RPD0 3 +#define OCFAR_RPD1 0 +#define OCFAR_RPD5 6 +#define OCFAR_RPE8 13 +#define OCFAR_RPF2 11 +#define OCFAR_RPF3 8 +#define OCFAR_RPF13 9 +#define OCFAR_RPG9 1 + +#define REFCLKI1R_RPA14 13 +#define REFCLKI1R_RPB5 8 +#define REFCLKI1R_RPB9 5 +#define REFCLKI1R_RPB10 6 +#define REFCLKI1R_RPC1 10 +#define REFCLKI1R_RPC14 7 +#define REFCLKI1R_RPD2 0 +#define REFCLKI1R_RPD6 14 +#define REFCLKI1R_RPD10 3 +#define REFCLKI1R_RPD14 11 +#define REFCLKI1R_RPF1 4 +#define REFCLKI1R_RPF4 2 +#define REFCLKI1R_RPG1 12 +#define REFCLKI1R_RPG8 1 + +#define REFCLKI3R_RPB2 7 +#define REFCLKI3R_RPB6 5 +#define REFCLKI3R_RPB14 2 +#define REFCLKI3R_RPC2 12 +#define REFCLKI3R_RPD0 3 +#define REFCLKI3R_RPD1 0 +#define REFCLKI3R_RPD5 6 +#define REFCLKI3R_RPE8 13 +#define REFCLKI3R_RPF2 11 +#define REFCLKI3R_RPF3 8 +#define REFCLKI3R_RPF13 9 +#define REFCLKI3R_RPG9 1 + +#define REFCLKI4R_RPA15 13 +#define REFCLKI4R_RPB1 5 +#define REFCLKI4R_RPB3 8 +#define REFCLKI4R_RPC4 10 +#define REFCLKI4R_RPC13 7 +#define REFCLKI4R_RPD3 0 +#define REFCLKI4R_RPD7 14 +#define REFCLKI4R_RPD11 3 +#define REFCLKI4R_RPD15 11 +#define REFCLKI4R_RPE5 6 +#define REFCLKI4R_RPF0 4 +#define REFCLKI4R_RPF5 2 +#define REFCLKI4R_RPG0 12 +#define REFCLKI4R_RPG7 1 + +#define SDI1R_RPA14 13 +#define SDI1R_RPB5 8 +#define SDI1R_RPB9 5 +#define SDI1R_RPB10 6 +#define SDI1R_RPC1 10 +#define SDI1R_RPC14 7 +#define SDI1R_RPD2 0 +#define SDI1R_RPD6 14 +#define SDI1R_RPD10 3 +#define SDI1R_RPD14 11 +#define SDI1R_RPF1 4 +#define SDI1R_RPF4 2 +#define SDI1R_RPG1 12 +#define SDI1R_RPG8 1 + +#define SDI2R_RPA15 13 +#define SDI2R_RPB1 5 +#define SDI2R_RPB3 8 +#define SDI2R_RPC4 10 +#define SDI2R_RPC13 7 +#define SDI2R_RPD3 0 +#define SDI2R_RPD7 14 +#define SDI2R_RPD11 3 +#define SDI2R_RPD15 11 +#define SDI2R_RPE5 6 +#define SDI2R_RPF0 4 +#define SDI2R_RPF5 2 +#define SDI2R_RPG0 12 +#define SDI2R_RPG7 1 + +#define SDI3R_RPA14 13 +#define SDI3R_RPB5 8 +#define SDI3R_RPB9 5 +#define SDI3R_RPB10 6 +#define SDI3R_RPC1 10 +#define SDI3R_RPC14 7 +#define SDI3R_RPD2 0 +#define SDI3R_RPD10 3 +#define SDI3R_RPD14 11 +#define SDI3R_RPD6 14 +#define SDI3R_RPF1 4 +#define SDI3R_RPF4 2 +#define SDI3R_RPG1 12 +#define SDI3R_RPG8 1 + +#define SDI4R_RPA15 13 +#define SDI4R_RPB1 5 +#define SDI4R_RPB3 8 +#define SDI4R_RPC4 10 +#define SDI4R_RPC13 7 +#define SDI4R_RPD3 0 +#define SDI4R_RPD7 14 +#define SDI4R_RPD11 3 +#define SDI4R_RPD15 11 +#define SDI4R_RPE5 6 +#define SDI4R_RPF0 4 +#define SDI4R_RPF5 2 +#define SDI4R_RPG0 12 +#define SDI4R_RPG7 1 + +#define SDI5R_RPA14 13 +#define SDI5R_RPB5 8 +#define SDI5R_RPB9 5 +#define SDI5R_RPB10 6 +#define SDI5R_RPC1 10 +#define SDI5R_RPC14 7 +#define SDI5R_RPD2 0 +#define SDI5R_RPD6 14 +#define SDI5R_RPD10 3 +#define SDI5R_RPD14 11 +#define SDI5R_RPF1 4 +#define SDI5R_RPF4 2 +#define SDI5R_RPG1 12 +#define SDI5R_RPG8 1 + +#define SDI6R_RPB2 7 +#define SDI6R_RPB6 5 +#define SDI6R_RPB14 2 +#define SDI6R_RPC2 12 +#define SDI6R_RPD0 3 +#define SDI6R_RPD1 0 +#define SDI6R_RPD5 6 +#define SDI6R_RPE8 13 +#define SDI6R_RPF2 11 +#define SDI6R_RPF3 8 +#define SDI6R_RPF13 9 +#define SDI6R_RPG9 1 + +#define SS1R_RPB0 5 +#define SS1R_RPB15 3 +#define SS1R_RPB7 7 +#define SS1R_RPB8 2 +#define SS1R_RPC3 12 +#define SS1R_RPD4 4 +#define SS1R_RPD9 0 +#define SS1R_RPD12 10 +#define SS1R_RPE3 6 +#define SS1R_RPE9 13 +#define SS1R_RPF8 11 +#define SS1R_RPF12 9 +#define SS1R_RPG6 1 + +#define SS2R_RPB2 7 +#define SS2R_RPB6 5 +#define SS2R_RPB14 2 +#define SS2R_RPC2 12 +#define SS2R_RPD0 3 +#define SS2R_RPD1 0 +#define SS2R_RPD5 6 +#define SS2R_RPE8 13 +#define SS2R_RPF2 11 +#define SS2R_RPF3 8 +#define SS2R_RPF13 9 +#define SS2R_RPG9 1 + +#define SS3R_RPB0 5 +#define SS3R_RPB7 7 +#define SS3R_RPB8 2 +#define SS3R_RPB15 3 +#define SS3R_RPC3 12 +#define SS3R_RPD4 4 +#define SS3R_RPD9 0 +#define SS3R_RPD12 10 +#define SS3R_RPE3 6 +#define SS3R_RPE9 13 +#define SS3R_RPF8 11 +#define SS3R_RPF12 9 +#define SS3R_RPG6 1 + +#define SS4R_RPB0 5 +#define SS4R_RPB7 7 +#define SS4R_RPB8 2 +#define SS4R_RPB15 3 +#define SS4R_RPC3 12 +#define SS4R_RPD4 4 +#define SS4R_RPD9 0 +#define SS4R_RPD12 10 +#define SS4R_RPE3 6 +#define SS4R_RPE9 13 +#define SS4R_RPF8 11 +#define SS4R_RPF12 9 +#define SS4R_RPG6 1 + +#define SS5R_RPB0 5 +#define SS5R_RPB7 7 +#define SS5R_RPB8 2 +#define SS5R_RPB15 3 +#define SS5R_RPC3 12 +#define SS5R_RPD4 4 +#define SS5R_RPD9 0 +#define SS5R_RPD12 10 +#define SS5R_RPE3 6 +#define SS5R_RPE9 13 +#define SS5R_RPF12 9 +#define SS5R_RPF8 11 +#define SS5R_RPG6 1 + +#define SS6R_RPA14 13 +#define SS6R_RPB5 8 +#define SS6R_RPB9 5 +#define SS6R_RPB10 6 +#define SS6R_RPC1 10 +#define SS6R_RPC14 7 +#define SS6R_RPD2 0 +#define SS6R_RPD6 14 +#define SS6R_RPD10 3 +#define SS6R_RPD14 11 +#define SS6R_RPF1 4 +#define SS6R_RPF4 2 +#define SS6R_RPG1 12 +#define SS6R_RPG8 1 + +#define T2CKR_RPA14 13 +#define T2CKR_RPB5 8 +#define T2CKR_RPB9 5 +#define T2CKR_RPB10 6 +#define T2CKR_RPC1 10 +#define T2CKR_RPC14 7 +#define T2CKR_RPD2 0 +#define T2CKR_RPD6 14 +#define T2CKR_RPD10 3 +#define T2CKR_RPD14 11 +#define T2CKR_RPF1 4 +#define T2CKR_RPF4 2 +#define T2CKR_RPG1 12 + +#define T2CKR_RPG8 1 +#define T3CKR_RPB0 5 +#define T3CKR_RPB7 7 +#define T3CKR_RPB8 2 +#define T3CKR_RPB15 3 +#define T3CKR_RPC3 12 +#define T3CKR_RPD4 4 +#define T3CKR_RPD9 0 +#define T3CKR_RPD12 10 +#define T3CKR_RPE3 6 +#define T3CKR_RPE9 13 +#define T3CKR_RPF8 11 +#define T3CKR_RPF12 9 +#define T3CKR_RPG6 1 + +#define T4CKR_RPB2 7 +#define T4CKR_RPB6 5 +#define T4CKR_RPB14 2 +#define T4CKR_RPC2 12 +#define T4CKR_RPD0 3 +#define T4CKR_RPD1 0 +#define T4CKR_RPD5 6 +#define T4CKR_RPE8 13 +#define T4CKR_RPF2 11 +#define T4CKR_RPF3 8 +#define T4CKR_RPF13 9 +#define T4CKR_RPG9 1 + +#define T5CKR_RPA15 13 +#define T5CKR_RPB1 5 +#define T5CKR_RPB3 8 +#define T5CKR_RPC4 10 +#define T5CKR_RPC13 7 +#define T5CKR_RPD3 0 +#define T5CKR_RPD7 14 +#define T5CKR_RPD11 3 +#define T5CKR_RPD15 11 +#define T5CKR_RPE5 6 +#define T5CKR_RPF0 4 +#define T5CKR_RPF5 2 +#define T5CKR_RPG0 12 +#define T5CKR_RPG7 1 + +#define T6CKR_RPA14 13 +#define T6CKR_RPB5 8 +#define T6CKR_RPB9 5 +#define T6CKR_RPB10 6 +#define T6CKR_RPC1 10 +#define T6CKR_RPC14 7 +#define T6CKR_RPD2 0 +#define T6CKR_RPD6 14 +#define T6CKR_RPD10 3 +#define T6CKR_RPD14 11 +#define T6CKR_RPF1 4 +#define T6CKR_RPF4 2 +#define T6CKR_RPG1 12 +#define T6CKR_RPG8 1 + +#define T7CKR_RPA15 13 +#define T7CKR_RPB1 5 +#define T7CKR_RPB3 8 +#define T7CKR_RPC4 10 +#define T7CKR_RPC13 7 +#define T7CKR_RPD3 0 +#define T7CKR_RPD7 14 +#define T7CKR_RPD11 3 +#define T7CKR_RPD15 11 +#define T7CKR_RPE5 6 +#define T7CKR_RPF0 4 +#define T7CKR_RPF5 2 +#define T7CKR_RPG0 12 +#define T7CKR_RPG7 1 + +#define T8CKR_RPB0 5 +#define T8CKR_RPB7 7 +#define T8CKR_RPB8 2 +#define T8CKR_RPB15 3 +#define T8CKR_RPC3 12 +#define T8CKR_RPD4 4 +#define T8CKR_RPD9 0 +#define T8CKR_RPD12 10 +#define T8CKR_RPE3 6 +#define T8CKR_RPE9 13 +#define T8CKR_RPF8 11 +#define T8CKR_RPF12 9 +#define T8CKR_RPG6 1 + +#define T9CKR_RPB2 7 +#define T9CKR_RPB6 5 +#define T9CKR_RPB14 2 +#define T9CKR_RPC2 12 +#define T9CKR_RPD0 3 +#define T9CKR_RPD1 0 +#define T9CKR_RPD5 6 +#define T9CKR_RPE8 13 +#define T9CKR_RPF2 11 +#define T9CKR_RPF3 8 +#define T9CKR_RPF13 9 +#define T9CKR_RPG9 1 + +#define U1CTSR_RPB0 5 +#define U1CTSR_RPB7 7 +#define U1CTSR_RPB8 2 +#define U1CTSR_RPB15 3 +#define U1CTSR_RPC3 12 +#define U1CTSR_RPD4 4 +#define U1CTSR_RPD9 0 +#define U1CTSR_RPD12 10 +#define U1CTSR_RPE3 6 +#define U1CTSR_RPE9 13 +#define U1CTSR_RPF8 11 +#define U1CTSR_RPF12 9 +#define U1CTSR_RPG6 1 + +#define U1RXR_RPA14 13 +#define U1RXR_RPB5 8 +#define U1RXR_RPB9 5 +#define U1RXR_RPB10 6 +#define U1RXR_RPC1 10 +#define U1RXR_RPC14 7 +#define U1RXR_RPD2 0 +#define U1RXR_RPD6 14 +#define U1RXR_RPD10 3 +#define U1RXR_RPD14 11 +#define U1RXR_RPF1 4 +#define U1RXR_RPF4 2 +#define U1RXR_RPG1 12 +#define U1RXR_RPG8 1 + +#define U2CTSR_RPA14 13 +#define U2CTSR_RPB5 8 +#define U2CTSR_RPB9 5 +#define U2CTSR_RPB10 6 +#define U2CTSR_RPC1 10 +#define U2CTSR_RPC14 7 +#define U2CTSR_RPD2 0 +#define U2CTSR_RPD6 14 +#define U2CTSR_RPD10 3 +#define U2CTSR_RPD14 11 +#define U2CTSR_RPF1 4 +#define U2CTSR_RPF4 2 +#define U2CTSR_RPG1 12 +#define U2CTSR_RPG8 1 + +#define U2RXR_RPB0 5 +#define U2RXR_RPB7 7 +#define U2RXR_RPB8 2 +#define U2RXR_RPB15 3 +#define U2RXR_RPC3 12 +#define U2RXR_RPD4 4 +#define U2RXR_RPD9 0 +#define U2RXR_RPD12 10 +#define U2RXR_RPE3 6 +#define U2RXR_RPE9 13 +#define U2RXR_RPF8 11 +#define U2RXR_RPF12 9 +#define U2RXR_RPG6 1 + +#define U3CTSR_RPB2 7 +#define U3CTSR_RPB6 5 +#define U3CTSR_RPB14 2 +#define U3CTSR_RPC2 12 +#define U3CTSR_RPD0 3 +#define U3CTSR_RPD1 0 +#define U3CTSR_RPD5 6 +#define U3CTSR_RPE8 13 +#define U3CTSR_RPF2 11 +#define U3CTSR_RPF3 8 +#define U3CTSR_RPF13 9 +#define U3CTSR_RPG9 1 + +#define U3RXR_RPA15 13 +#define U3RXR_RPB1 5 +#define U3RXR_RPB3 8 +#define U3RXR_RPC4 10 +#define U3RXR_RPC13 7 +#define U3RXR_RPD3 0 +#define U3RXR_RPD7 14 +#define U3RXR_RPD11 3 +#define U3RXR_RPD15 11 +#define U3RXR_RPE5 6 +#define U3RXR_RPF0 4 +#define U3RXR_RPF5 2 +#define U3RXR_RPG0 12 +#define U3RXR_RPG7 1 + +#define U4CTSR_RPA15 13 +#define U4CTSR_RPB1 5 +#define U4CTSR_RPB3 8 +#define U4CTSR_RPC4 10 +#define U4CTSR_RPC13 7 +#define U4CTSR_RPD3 0 +#define U4CTSR_RPD7 14 +#define U4CTSR_RPD11 3 +#define U4CTSR_RPD15 11 +#define U4CTSR_RPE5 6 +#define U4CTSR_RPF0 4 +#define U4CTSR_RPF5 2 +#define U4CTSR_RPG0 12 +#define U4CTSR_RPG7 1 + +#define U4RXR_RPB2 7 +#define U4RXR_RPB6 5 +#define U4RXR_RPB14 2 +#define U4RXR_RPC2 12 +#define U4RXR_RPD0 3 +#define U4RXR_RPD1 0 +#define U4RXR_RPD5 6 +#define U4RXR_RPE8 13 +#define U4RXR_RPF2 11 +#define U4RXR_RPF3 8 +#define U4RXR_RPF13 9 +#define U4RXR_RPG9 1 + +#define U5CTSR_RPB0 5 +#define U5CTSR_RPB7 7 +#define U5CTSR_RPB8 2 +#define U5CTSR_RPB15 3 +#define U5CTSR_RPC3 12 +#define U5CTSR_RPD4 4 +#define U5CTSR_RPD9 0 +#define U5CTSR_RPD12 10 +#define U5CTSR_RPE3 6 +#define U5CTSR_RPE9 13 +#define U5CTSR_RPF8 11 +#define U5CTSR_RPF12 9 +#define U5CTSR_RPG6 1 + +#define U5RXR_RPA14 13 +#define U5RXR_RPB5 8 +#define U5RXR_RPB9 5 +#define U5RXR_RPB10 6 +#define U5RXR_RPC1 10 +#define U5RXR_RPC14 7 +#define U5RXR_RPD2 0 +#define U5RXR_RPD6 14 +#define U5RXR_RPD10 3 +#define U5RXR_RPD14 11 +#define U5RXR_RPF1 4 +#define U5RXR_RPF4 2 +#define U5RXR_RPG1 12 +#define U5RXR_RPG8 1 + +#define U6CTSR_RPA14 13 +#define U6CTSR_RPB5 8 +#define U6CTSR_RPB9 5 +#define U6CTSR_RPB10 6 +#define U6CTSR_RPC1 10 +#define U6CTSR_RPC14 7 +#define U6CTSR_RPD2 0 +#define U6CTSR_RPD6 14 +#define U6CTSR_RPD10 3 +#define U6CTSR_RPD14 11 +#define U6CTSR_RPF1 4 +#define U6CTSR_RPF4 2 +#define U6CTSR_RPG1 12 +#define U6CTSR_RPG8 1 + +#define U6RXR_RPB2 7 +#define U6RXR_RPB6 5 +#define U6RXR_RPB14 2 +#define U6RXR_RPC2 12 +#define U6RXR_RPD0 3 +#define U6RXR_RPD1 0 +#define U6RXR_RPD5 6 +#define U6RXR_RPE8 13 +#define U6RXR_RPF2 11 +#define U6RXR_RPF3 8 +#define U6RXR_RPF13 9 +#define U6RXR_RPG9 1 + +/* Output Pin Selection *********************************************************************/ +/* The encoding of the output pin selection is a little more complex. Knowing the device + * does not provide sufficient information. So the following definitions include both the + * register value and the register address. + */ + +#define C1OUT_RPB0R 14, PI32MZ_RPB0R +#define C1OUT_RPB7R 14, PI32MZ_RPB7R +#define C1OUT_RPB8R 14, PI32MZ_RPB8R +#define C1OUT_RPB15R 14, PI32MZ_RPB15R +#define C1OUT_RPC3R 14, PI32MZ_RPC3R +#define C1OUT_RPD4R 14, PI32MZ_RPD4R +#define C1OUT_RPD9R 14, PI32MZ_RPD9R +#define C1OUT_RPD12R 14, PI32MZ_RPD12R +#define C1OUT_RPE3R 14, PI32MZ_RPE3R +#define C1OUT_RPE9R 14, PI32MZ_RPE9R +#define C1OUT_RPF8R 14, PI32MZ_RPF8R +#define C1OUT_RPF12R 14, PI32MZ_RPF12R +#define C1OUT_RPG6R 14, PI32MZ_RPG6R + +#define C1TX_RPA14R 15, PI32MZ_RPA14R +#define C1TX_RPB5R 15, PI32MZ_RPB5R +#define C1TX_RPB9R 15, PI32MZ_RPB9R +#define C1TX_RPB10R 15, PI32MZ_RPB10R +#define C1TX_RPC1R 15, PI32MZ_RPC1R +#define C1TX_RPC14R 15, PI32MZ_RPC14R +#define C1TX_RPD2R 15, PI32MZ_RPD2R +#define C1TX_RPD6R 15, PI32MZ_RPD6R +#define C1TX_RPD10R 15, PI32MZ_RPD10R +#define C1TX_RPD14R 15, PI32MZ_RPD14R +#define C1TX_RPF1R 15, PI32MZ_RPF1R +#define C1TX_RPF4R 15, PI32MZ_RPF4R +#define C1TX_RPG1R 15, PI32MZ_RPG1R +#define C1TX_RPG8R 15, PI32MZ_RPG8R + +#define C2OUT_RPA14R 14, PI32MZ_RPA14R +#define C2OUT_RPB5R 14, PI32MZ_RPB5R +#define C2OUT_RPB9R 14, PI32MZ_RPB9R +#define C2OUT_RPB10R 14, PI32MZ_RPB10R +#define C2OUT_RPC1R 14, PI32MZ_RPC1R +#define C2OUT_RPC14R 14, PI32MZ_RPC14R +#define C2OUT_RPD2R 14, PI32MZ_RPD2R +#define C2OUT_RPD6R 14, PI32MZ_RPD6R +#define C2OUT_RPD10R 14, PI32MZ_RPD10R +#define C2OUT_RPD14R 14, PI32MZ_RPD14R +#define C2OUT_RPF1R 14, PI32MZ_RPF1R +#define C2OUT_RPF4R 14, PI32MZ_RPF4R +#define C2OUT_RPG1R 14, PI32MZ_RPG1R +#define C2OUT_RPG8R 14, PI32MZ_RPG8R + +#define C2TX_RPB2R 15, PI32MZ_RPB2R +#define C2TX_RPB6R 15, PI32MZ_RPB6R +#define C2TX_RPB14R 15, PI32MZ_RPB14R +#define C2TX_RPC2R 15, PI32MZ_RPC2R +#define C2TX_RPD0R 15, PI32MZ_RPD0R +#define C2TX_RPD1R 15, PI32MZ_RPD1R +#define C2TX_RPD5R 15, PI32MZ_RPD5R +#define C2TX_RPE8R 15, PI32MZ_RPE8R +#define C2TX_RPF2R 15, PI32MZ_RPF2R +#define C2TX_RPF3R 15, PI32MZ_RPF3R +#define C2TX_RPF13R 15, PI32MZ_RPF13R +#define C2TX_RPG9R 15, PI32MZ_RPG9R + +#define OC1_RPB2R 12, PI32MZ_RPB2R +#define OC1_RPB6R 12, PI32MZ_RPB6R +#define OC1_RPB14R 12, PI32MZ_RPB14R +#define OC1_RPC2R 12, PI32MZ_RPC2R +#define OC1_RPD0R 12, PI32MZ_RPD0R +#define OC1_RPD1R 12, PI32MZ_RPD1R +#define OC1_RPD5R 12, PI32MZ_RPD5R +#define OC1_RPE8R 12, PI32MZ_RPE8R +#define OC1_RPF2R 12, PI32MZ_RPF2R +#define OC1_RPF3R 12, PI32MZ_RPF3R +#define OC1_RPF13R 12, PI32MZ_RPF13R +#define OC1_RPG9R 12, PI32MZ_RPG9R + +#define OC2_RPB2R 11, PI32MZ_RPB2R +#define OC2_RPB6R 11, PI32MZ_RPB6R +#define OC2_RPB14R 11, PI32MZ_RPB14R +#define OC2_RPC2R 11, PI32MZ_RPC2R +#define OC2_RPD0R 11, PI32MZ_RPD0R +#define OC2_RPD1R 11, PI32MZ_RPD1R +#define OC2_RPD5R 11, PI32MZ_RPD5R +#define OC2_RPE8R 11, PI32MZ_RPE8R +#define OC2_RPF2R 11, PI32MZ_RPF2R +#define OC2_RPF3R 11, PI32MZ_RPF3R +#define OC2_RPF13R 11, PI32MZ_RPF13R +#define OC2_RPG9R 11, PI32MZ_RPG9R + +#define OC3_RPA14R 11, PI32MZ_RPA14R +#define OC3_RPB5R 11, PI32MZ_RPB5R +#define OC3_RPB9R 11, PI32MZ_RPB9R +#define OC3_RPB10R 11, PI32MZ_RPB10R +#define OC3_RPC1R 11, PI32MZ_RPC1R +#define OC3_RPC14R 11, PI32MZ_RPC14R +#define OC3_RPD2R 11, PI32MZ_RPD2R +#define OC3_RPD6R 11, PI32MZ_RPD6R +#define OC3_RPD10R 11, PI32MZ_RPD10R +#define OC3_RPD14R 11, PI32MZ_RPD14R +#define OC3_RPF1R 11, PI32MZ_RPF1R +#define OC3_RPF4R 11, PI32MZ_RPF4R +#define OC3_RPG1R 11, PI32MZ_RPG1R +#define OC3_RPG8R 11, PIC32MZ_RPG8R + +#define OC4_RPA15R 11, PIC32MZ_RPA15R +#define OC4_RPB1R 11, PIC32MZ_RPB1R +#define OC4_RPB3R 11, PIC32MZ_RPB3R +#define OC4_RPC4R 11, PIC32MZ_RPC4R +#define OC4_RPC13R 11, PIC32MZ_RPC13R +#define OC4_RPD3R 11, PIC32MZ_RPD3R +#define OC4_RPD7R 11, PIC32MZ_RPD7R +#define OC4_RPD11R 11, PIC32MZ_RPD11R +#define OC4_RPD15R 11, PIC32MZ_RPD15R +#define OC4_RPE5R 11, PIC32MZ_RPE5R +#define OC4_RPF0R 11, PIC32MZ_RPF0R +#define OC4_RPF5R 11, PIC32MZ_RPF5R +#define OC4_RPG0R 11, PIC32MZ_RPG0R +#define OC4_RPG7R 11, PIC32MZ_RPG7R + +#define OC5_RPB0R 11, PIC32MZ_RPB0R +#define OC5_RPB7R 11, PIC32MZ_RPB7R +#define OC5_RPB8R 11, PIC32MZ_RPB8R +#define OC5_RPB15R 11, PIC32MZ_RPB15R +#define OC5_RPC3R 11, PIC32MZ_RPC3R +#define OC5_RPD4R 11, PIC32MZ_RPD4R +#define OC5_RPD9R 11, PIC32MZ_RPD9R +#define OC5_RPD12R 11, PIC32MZ_RPD12R +#define OC5_RPE3R 11, PIC32MZ_RPE3R +#define OC5_RPE9R 11, PIC32MZ_RPE9R +#define OC5_RPF8R 11, PIC32MZ_RPF8R +#define OC5_RPF12R 11, PIC32MZ_RPF12R +#define OC5_RPG6R 11, PIC32MZ_RPG6R + +#define OC6_RPA14R 12, PIC32MZ_RPA14R +#define OC6_RPB5R 12, PIC32MZ_RPB5R +#define OC6_RPB9R 12, PIC32MZ_RPB9R +#define OC6_RPB10R 12, PIC32MZ_RPB10R +#define OC6_RPC1R 12, PIC32MZ_RPC1R +#define OC6_RPC14R 12, PIC32MZ_RPC14R +#define OC6_RPD2R 12, PIC32MZ_RPD2R +#define OC6_RPD6R 12, PIC32MZ_RPD6R +#define OC6_RPD10R 12, PIC32MZ_RPD10R +#define OC6_RPD14R 12, PIC32MZ_RPD14R +#define OC6_RPF1R 12, PIC32MZ_RPF1R +#define OC6_RPF4R 12, PIC32MZ_RPF4R +#define OC6_RPG1R 12, PIC32MZ_RPG1R +#define OC6_RPG8R 12, PIC32MZ_RPG8R + +#define OC7_RPA15R 12, PIC32MZ_RPA15R +#define OC7_RPB1R 12, PIC32MZ_RPB1R +#define OC7_RPB3R 12, PIC32MZ_RPB3R +#define OC7_RPC4R 12, PIC32MZ_RPC4R +#define OC7_RPC13R 12, PIC32MZ_RPC13R +#define OC7_RPD3R 12, PIC32MZ_RPD3R +#define OC7_RPD7R 12, PIC32MZ_RPD7R +#define OC7_RPD11R 12, PIC32MZ_RPD11R +#define OC7_RPD15R 12, PIC32MZ_RPD15R +#define OC7_RPE5R 12, PIC32MZ_RPE5R +#define OC7_RPF0R 12, PIC32MZ_RPF0R +#define OC7_RPF5R 12, PIC32MZ_RPF5R +#define OC7_RPG0R 12, PIC32MZ_RPG0R +#define OC7_RPG7R 12, PIC32MZ_RPG7R + +#define OC8_RPB0R 12, PIC32MZ_RPB0R +#define OC8_RPB7R 12, PIC32MZ_RPB7R +#define OC8_RPB8R 12, PIC32MZ_RPB8R +#define OC8_RPB15R 12, PIC32MZ_RPB15R +#define OC8_RPC3R 12, PIC32MZ_RPC3R +#define OC8_RPD4R 12, PIC32MZ_RPD4R +#define OC8_RPD9R 12, PIC32MZ_RPD9R +#define OC8_RPD12R 12, PIC32MZ_RPD12R +#define OC8_RPE3R 12, PIC32MZ_RPE3R +#define OC8_RPE9R 12, PIC32MZ_RPE9R +#define OC8_RPF8R 12, PIC32MZ_RPF8R +#define OC8_RPF12R 12, PIC32MZ_RPF12R +#define OC8_RPG6R 12, PIC32MZ_RPG6R + +#define OC9_RPB2R 13, PIC32MZ_RPB2R +#define OC9_RPB6R 13, PIC32MZ_RPB6R +#define OC9_RPB14R 13, PIC32MZ_RPB14R +#define OC9_RPC2R 13, PIC32MZ_RPC2R +#define OC9_RPD0R 13, PIC32MZ_RPD0R +#define OC9_RPD1R 13, PIC32MZ_RPD1R +#define OC9_RPD5R 13, PIC32MZ_RPD5R +#define OC9_RPE8R 13, PIC32MZ_RPE8R +#define OC9_RPF2R 13, PIC32MZ_RPF2R +#define OC9_RPF3R 13, PIC32MZ_RPF3R +#define OC9_RPF13R 13, PIC32MZ_RPF13R +#define OC9_RPG9R 13, PIC32MZ_RPG9R + +#define REFCLKO1_RPA15R 15, PIC32MZ_RPA15R +#define REFCLKO1_RPB1R 15, PIC32MZ_RPB1R +#define REFCLKO1_RPB3R 15, PIC32MZ_RPB3R +#define REFCLKO1_RPC4R 15, PIC32MZ_RPC4R +#define REFCLKO1_RPC13R 15, PIC32MZ_RPC13R +#define REFCLKO1_RPD3R 15, PIC32MZ_RPD3R +#define REFCLKO1_RPD7R 15, PIC32MZ_RPD7R +#define REFCLKO1_RPD11R 15, PIC32MZ_RPD11R +#define REFCLKO1_RPD15R 15, PIC32MZ_RPD15R +#define REFCLKO1_RPE5R 15, PIC32MZ_RPE5R +#define REFCLKO1_RPF0R 15, PIC32MZ_RPF0R +#define REFCLKO1_RPF5R 15, PIC32MZ_RPF5R +#define REFCLKO1_RPG0R 15, PIC32MZ_RPG0R +#define REFCLKO1_RPG7R 15, PIC32MZ_RPG7R + +#define REFCLKO3_RPG6R 15, PIC32MZ_RPG6R +#define REFCLKO3_RPB0R 15, PIC32MZ_RPB0R +#define REFCLKO3_RPB7R 15, PIC32MZ_RPB7R +#define REFCLKO3_RPB8R 15, PIC32MZ_RPB8R +#define REFCLKO3_RPB15R 15, PIC32MZ_RPB15R +#define REFCLKO3_RPC3R 15, PIC32MZ_RPC3R +#define REFCLKO3_RPD4R 15, PIC32MZ_RPD4R +#define REFCLKO3_RPD9R 15, PIC32MZ_RPD9R +#define REFCLKO3_RPD12R 15, PIC32MZ_RPD12R +#define REFCLKO3_RPE3R 15, PIC32MZ_RPE3R +#define REFCLKO3_RPE9R 15, PIC32MZ_RPE9R +#define REFCLKO3_RPF8R 15, PIC32MZ_RPF8R +#define REFCLKO3_RPF12R 15, PIC32MZ_RPF12R + +#define REFCLKO4_RPA14R 13, PIC32MZ_RPA14R +#define REFCLKO4_RPB5R 13, PIC32MZ_RPB5R +#define REFCLKO4_RPB9R 13, PIC32MZ_RPB9R +#define REFCLKO4_RPB10R 13, PIC32MZ_RPB10R +#define REFCLKO4_RPC1R 13, PIC32MZ_RPC1R +#define REFCLKO4_RPC14R 13, PIC32MZ_RPC14R +#define REFCLKO4_RPD2R 13, PIC32MZ_RPD2R +#define REFCLKO4_RPD6R 13, PIC32MZ_RPD6R +#define REFCLKO4_RPD10R 13, PIC32MZ_RPD10R +#define REFCLKO4_RPD14R 13, PIC32MZ_RPD14R +#define REFCLKO4_RPF1R 13, PIC32MZ_RPF1R +#define REFCLKO4_RPF4R 13, PIC32MZ_RPF4R +#define REFCLKO4_RPG1R 13, PIC32MZ_RPG1R +#define REFCLKO4_RPG8R 13, PIC32MZ_RPG8R + +#define SDO1_RPA14R 5, PIC32MZ_RPA14R +#define SDO1_RPA15R 5, PIC32MZ_RPA15R +#define SDO1_RPB1R 5, PIC32MZ_RPB1R +#define SDO1_RPB3R 5, PIC32MZ_RPB3R +#define SDO1_RPB5R 5, PIC32MZ_RPB5R +#define SDO1_RPB9R 5, PIC32MZ_RPB9R +#define SDO1_RPB10R 5, PIC32MZ_RPB10R +#define SDO1_RPC1R 5, PIC32MZ_RPC1R +#define SDO1_RPC4R 5, PIC32MZ_RPC4R +#define SDO1_RPC13R 5, PIC32MZ_RPC13R +#define SDO1_RPC14R 5, PIC32MZ_RPC14R +#define SDO1_RPD2R 5, PIC32MZ_RPD2R +#define SDO1_RPD3R 5, PIC32MZ_RPD3R +#define SDO1_RPD6R 5, PIC32MZ_RPD6R +#define SDO1_RPD7R 5, PIC32MZ_RPD7R +#define SDO1_RPD10R 5, PIC32MZ_RPD10R +#define SDO1_RPD11R 5, PIC32MZ_RPD11R +#define SDO1_RPD14R 5, PIC32MZ_RPD14R +#define SDO1_RPD15R 5, PIC32MZ_RPD15R +#define SDO1_RPE5R 5, PIC32MZ_RPE5R +#define SDO1_RPF0R 5, PIC32MZ_RPF0R +#define SDO1_RPF1R 5, PIC32MZ_RPF1R +#define SDO1_RPF4R 5, PIC32MZ_RPF4R +#define SDO1_RPF5R 5, PIC32MZ_RPF5R +#define SDO1_RPG0R 5, PIC32MZ_RPG0R +#define SDO1_RPG1R 5, PIC32MZ_RPG1R +#define SDO1_RPG7R 5, PIC32MZ_RPG7R +#define SDO1_RPG8R 5, PIC32MZ_RPG8R + +#define SDO2_RPA14R 6, PIC32MZ_RPA14R +#define SDO2_RPA15R 6, PIC32MZ_RPA15R +#define SDO2_RPB1R 6, PIC32MZ_RPB1R +#define SDO2_RPB3R 6, PIC32MZ_RPB3R +#define SDO2_RPB5R 6, PIC32MZ_RPB5R +#define SDO2_RPB9R 6, PIC32MZ_RPB9R +#define SDO2_RPB10R 6, PIC32MZ_RPB10R +#define SDO2_RPC1R 6, PIC32MZ_RPC1R +#define SDO2_RPC4R 6, PIC32MZ_RPC4R +#define SDO2_RPC13R 6, PIC32MZ_RPC13R +#define SDO2_RPC14R 6, PIC32MZ_RPC14R +#define SDO2_RPD2R 6, PIC32MZ_RPD2R +#define SDO2_RPD3R 6, PIC32MZ_RPD3R +#define SDO2_RPD6R 6, PIC32MZ_RPD6R +#define SDO2_RPD7R 6, PIC32MZ_RPD7R +#define SDO2_RPD10R 6, PIC32MZ_RPD10R +#define SDO2_RPD11R 6, PIC32MZ_RPD11R +#define SDO2_RPD14R 6, PIC32MZ_RPD14R +#define SDO2_RPD15R 6, PIC32MZ_RPD15R +#define SDO2_RPE5R 6, PIC32MZ_RPE5R +#define SDO2_RPF0R 6, PIC32MZ_RPF0R +#define SDO2_RPF1R 6, PIC32MZ_RPF1R +#define SDO2_RPF4R 6, PIC32MZ_RPF4R +#define SDO2_RPF5R 6, PIC32MZ_RPF5R +#define SDO2_RPG0R 6, PIC32MZ_RPG0R +#define SDO2_RPG1R 6, PIC32MZ_RPG1R +#define SDO2_RPG7R 6, PIC32MZ_RPG7R +#define SDO2_RPG8R 6, PIC32MZ_RPG8R + +#define SDO3_RPA14R 7, PIC32MZ_RPA14R +#define SDO3_RPA15R 7, PIC32MZ_RPA15R +#define SDO3_RPB1R 7, PIC32MZ_RPB1R +#define SDO3_RPB3R 7, PIC32MZ_RPB3R +#define SDO3_RPB5R 7, PIC32MZ_RPB5R +#define SDO3_RPB9R 7, PIC32MZ_RPB9R +#define SDO3_RPB10R 7, PIC32MZ_RPB10R +#define SDO3_RPC1R 7, PIC32MZ_RPC1R +#define SDO3_RPC4R 7, PIC32MZ_RPC4R +#define SDO3_RPC13R 7, PIC32MZ_RPC13R +#define SDO3_RPC14R 7, PIC32MZ_RPC14R +#define SDO3_RPD2R 7, PIC32MZ_RPD2R +#define SDO3_RPD3R 7, PIC32MZ_RPD3R +#define SDO3_RPD6R 7, PIC32MZ_RPD6R +#define SDO3_RPD7R 7, PIC32MZ_RPD7R +#define SDO3_RPD10R 7, PIC32MZ_RPD10R +#define SDO3_RPD11R 7, PIC32MZ_RPD11R +#define SDO3_RPD14R 7, PIC32MZ_RPD14R +#define SDO3_RPD15R 7, PIC32MZ_RPD15R +#define SDO3_RPE5R 7, PIC32MZ_RPE5R +#define SDO3_RPF0R 7, PIC32MZ_RPF0R +#define SDO3_RPF1R 7, PIC32MZ_RPF1R +#define SDO3_RPF4R 7, PIC32MZ_RPF4R +#define SDO3_RPF5R 7, PIC32MZ_RPF5R +#define SDO3_RPG0R 7, PIC32MZ_RPG0R +#define SDO3_RPG1R 7, PIC32MZ_RPG1R +#define SDO3_RPG7R 7, PIC32MZ_RPG7R +#define SDO3_RPG8R 7, PIC32MZ_RPG8R + +#define SDO4_RPA15R 8, PIC32MZ_RPA15R +#define SDO4_RPB1R 8, PIC32MZ_RPB1R +#define SDO4_RPB2R 8, PIC32MZ_RPB2R +#define SDO4_RPB3R 8, PIC32MZ_RPB3R +#define SDO4_RPB6R 8, PIC32MZ_RPB6R +#define SDO4_RPB14R 8, PIC32MZ_RPB14R +#define SDO4_RPC2R 8, PIC32MZ_RPC2R +#define SDO4_RPC4R 8, PIC32MZ_RPC4R +#define SDO4_RPC13R 8, PIC32MZ_RPC13R +#define SDO4_RPD0R 8, PIC32MZ_RPD0R +#define SDO4_RPD1R 8, PIC32MZ_RPD1R +#define SDO4_RPD3R 8, PIC32MZ_RPD3R +#define SDO4_RPD5R 8, PIC32MZ_RPD5R +#define SDO4_RPD7R 8, PIC32MZ_RPD7R +#define SDO4_RPD11R 8, PIC32MZ_RPD11R +#define SDO4_RPD15R 8, PIC32MZ_RPD15R +#define SDO4_RPE5R 8, PIC32MZ_RPE5R +#define SDO4_RPE8R 8, PIC32MZ_RPE8R +#define SDO4_RPF0R 8, PIC32MZ_RPF0R +#define SDO4_RPF2R 8, PIC32MZ_RPF2R +#define SDO4_RPF3R 8, PIC32MZ_RPF3R +#define SDO4_RPF5R 8, PIC32MZ_RPF5R +#define SDO4_RPF13R 8, PIC32MZ_RPF13R +#define SDO4_RPG0R 8, PIC32MZ_RPG0R +#define SDO4_RPG7R 8, PIC32MZ_RPG7R +#define SDO4_RPG9R 8, PIC32MZ_RPG9R + +#define SDO5_RPA14R 9, PIC32MZ_RPA14R +#define SDO5_RPA15R 9, PIC32MZ_RPA15R +#define SDO5_RPB1R 9, PIC32MZ_RPB1R +#define SDO5_RPB3R 9, PIC32MZ_RPB3R +#define SDO5_RPB5R 9, PIC32MZ_RPB5R +#define SDO5_RPB9R 9, PIC32MZ_RPB9R +#define SDO5_RPB10R 9, PIC32MZ_RPB10R +#define SDO5_RPC1R 9, PIC32MZ_RPC1R +#define SDO5_RPC4R 9, PIC32MZ_RPC4R +#define SDO5_RPC13R 9, PIC32MZ_RPC13R +#define SDO5_RPC14R 9, PIC32MZ_RPC14R +#define SDO5_RPD2R 9, PIC32MZ_RPD2R +#define SDO5_RPD3R 9, PIC32MZ_RPD3R +#define SDO5_RPD6R 9, PIC32MZ_RPD6R +#define SDO5_RPD7R 9, PIC32MZ_RPD7R +#define SDO5_RPD10R 9, PIC32MZ_RPD10R +#define SDO5_RPD11R 9, PIC32MZ_RPD11R +#define SDO5_RPD14R 9, PIC32MZ_RPD14R +#define SDO5_RPD15R 9, PIC32MZ_RPD15R +#define SDO5_RPE5R 9, PIC32MZ_RPE5R +#define SDO5_RPF0R 9, PIC32MZ_RPF0R +#define SDO5_RPF1R 9, PIC32MZ_RPF1R +#define SDO5_RPF4R 9, PIC32MZ_RPF4R +#define SDO5_RPF5R 9, PIC32MZ_RPF5R +#define SDO5_RPG0R 9, PIC32MZ_RPG0R +#define SDO5_RPG1R 9, PIC32MZ_RPG1R +#define SDO5_RPG7R 9, PIC32MZ_RPG7R +#define SDO5_RPG8R 9, PIC32MZ_RPG8R + +#define SDO6_RPB0R 10, PIC32MZ_RPB0R +#define SDO6_RPB2R 10, PIC32MZ_RPB2R +#define SDO6_RPB6R 10, PIC32MZ_RPB6R +#define SDO6_RPB7R 10, PIC32MZ_RPB7R +#define SDO6_RPB8R 10, PIC32MZ_RPB8R +#define SDO6_RPB14R 10, PIC32MZ_RPB14R +#define SDO6_RPB15R 10, PIC32MZ_RPB15R +#define SDO6_RPC2R 10, PIC32MZ_RPC2R +#define SDO6_RPC3R 10, PIC32MZ_RPC3R +#define SDO6_RPD0R 10, PIC32MZ_RPD0R +#define SDO6_RPD1R 10, PIC32MZ_RPD1R +#define SDO6_RPD4R 10, PIC32MZ_RPD4R +#define SDO6_RPD5R 10, PIC32MZ_RPD5R +#define SDO6_RPD9R 10, PIC32MZ_RPD9R +#define SDO6_RPD12R 10, PIC32MZ_RPD12R +#define SDO6_RPE3R 10, PIC32MZ_RPE3R +#define SDO6_RPE8R 10, PIC32MZ_RPE8R +#define SDO6_RPE9R 10, PIC32MZ_RPE9R +#define SDO6_RPF2R 10, PIC32MZ_RPF2R +#define SDO6_RPF3R 10, PIC32MZ_RPF3R +#define SDO6_RPF8R 10, PIC32MZ_RPF8R +#define SDO6_RPF12R 10, PIC32MZ_RPF12R +#define SDO6_RPF13R 10, PIC32MZ_RPF13R +#define SDO6_RPG6R 10, PIC32MZ_RPG6R +#define SDO6_RPG9R 10, PIC32MZ_RPG9R + +#define SS1_RPB0R 5, PIC32MZ_RPB0R +#define SS1_RPB7R 5, PIC32MZ_RPB7R +#define SS1_RPB8R 5, PIC32MZ_RPB8R +#define SS1_RPB15R 5, PIC32MZ_RPB15R +#define SS1_RPC3R 5, PIC32MZ_RPC3R +#define SS1_RPD4R 5, PIC32MZ_RPD4R +#define SS1_RPD9R 5, PIC32MZ_RPD9R +#define SS1_RPD12R 5, PIC32MZ_RPD12R +#define SS1_RPE3R 5, PIC32MZ_RPE3R +#define SS1_RPE9R 5, PIC32MZ_RPE9R +#define SS1_RPF8R 5, PIC32MZ_RPF8R +#define SS1_RPF12R 5, PIC32MZ_RPF12R +#define SS1_RPG6R 5, PIC32MZ_RPG6R + +#define SS2_RPB2R 6, PIC32MZ_RPB2R +#define SS2_RPB6R 6, PIC32MZ_RPB6R +#define SS2_RPB14R 6, PIC32MZ_RPB14R +#define SS2_RPC2R 6, PIC32MZ_RPC2R +#define SS2_RPD0R 6, PIC32MZ_RPD0R +#define SS2_RPD1R 6, PIC32MZ_RPD1R +#define SS2_RPD5R 6, PIC32MZ_RPD5R +#define SS2_RPE8R 6, PIC32MZ_RPE8R +#define SS2_RPF2R 6, PIC32MZ_RPF2R +#define SS2_RPF3R 6, PIC32MZ_RPF3R +#define SS2_RPF13R 6, PIC32MZ_RPF13R +#define SS2_RPG9R 6, PIC32MZ_RPG9R + +#define SS3_RPB0R 7, PIC32MZ_RPB0R +#define SS3_RPB7R 7, PIC32MZ_RPB7R +#define SS3_RPB8R 7, PIC32MZ_RPB8R +#define SS3_RPB15R 7, PIC32MZ_RPB15R +#define SS3_RPC3R 7, PIC32MZ_RPC3R +#define SS3_RPD4R 7, PIC32MZ_RPD4R +#define SS3_RPD9R 7, PIC32MZ_RPD9R +#define SS3_RPD12R 7, PIC32MZ_RPD12R +#define SS3_RPE3R 7, PIC32MZ_RPE3R +#define SS3_RPE9R 7, PIC32MZ_RPE9R +#define SS3_RPF8R 7, PIC32MZ_RPF8R +#define SS3_RPF12R 7, PIC32MZ_RPF12R +#define SS3_RPG6R 7, PIC32MZ_RPG6R + +#define SS4_RPB0R 8, PIC32MZ_RPB0R +#define SS4_RPB7R 8, PIC32MZ_RPB7R +#define SS4_RPB8R 8, PIC32MZ_RPB8R +#define SS4_RPB15R 8, PIC32MZ_RPB15R +#define SS4_RPC3R 8, PIC32MZ_RPC3R +#define SS4_RPD4R 8, PIC32MZ_RPD4R +#define SS4_RPD9R 8, PIC32MZ_RPD9R +#define SS4_RPD12R 8, PIC32MZ_RPD12R +#define SS4_RPE3R 8, PIC32MZ_RPE3R +#define SS4_RPE9R 8, PIC32MZ_RPE9R +#define SS4_RPF8R 8, PIC32MZ_RPF8R +#define SS4_RPF12R 8, PIC32MZ_RPF12R +#define SS4_RPG6R 8, PIC32MZ_RPG6R + +#define SS5_RPB0R 9, PIC32MZ_RPB0R +#define SS5_RPB7R 9, PIC32MZ_RPB7R +#define SS5_RPB8R 9, PIC32MZ_RPB8R +#define SS5_RPB15R 9, PIC32MZ_RPB15R +#define SS5_RPC3R 9, PIC32MZ_RPC3R +#define SS5_RPD4R 9, PIC32MZ_RPD4R +#define SS5_RPD9R 9, PIC32MZ_RPD9R +#define SS5_RPD12R 9, PIC32MZ_RPD12R +#define SS5_RPE3R 9, PIC32MZ_RPE3R +#define SS5_RPE9R 9, PIC32MZ_RPE9R +#define SS5_RPF8R 9, PIC32MZ_RPF8R +#define SS5_RPF12R 9, PIC32MZ_RPF12R +#define SS5_RPG6R 9, PIC32MZ_RPG6R + +#define SS6_RPA14R 10, PIC32MZ_RPA14R +#define SS6_RPB5R 10, PIC32MZ_RPB5R +#define SS6_RPB9R 10, PIC32MZ_RPB9R +#define SS6_RPB10R 10, PIC32MZ_RPB10R +#define SS6_RPC1R 10, PIC32MZ_RPC1R +#define SS6_RPC14R 10, PIC32MZ_RPC14R +#define SS6_RPD2R 10, PIC32MZ_RPD2R +#define SS6_RPD6R 10, PIC32MZ_RPD6R +#define SS6_RPD10R 10, PIC32MZ_RPD10R +#define SS6_RPD14R 10, PIC32MZ_RPD14R +#define SS6_RPF1R 10, PIC32MZ_RPF1R +#define SS6_RPF4R 10, PIC32MZ_RPF4R +#define SS6_RPG1R 10, PIC32MZ_RPG1R +#define SS6_RPG8R 10, PIC32MZ_RPG8R + +#define U1RTS_RPB2R 1, PIC32MZ_RPB2R +#define U1RTS_RPB6R 1, PIC32MZ_RPB6R +#define U1RTS_RPB14R 1, PIC32MZ_RPB14R +#define U1RTS_RPC2R 1, PIC32MZ_RPC2R +#define U1RTS_RPD0R 1, PIC32MZ_RPD0R +#define U1RTS_RPD1R 1, PIC32MZ_RPD1R +#define U1RTS_RPD5R 1, PIC32MZ_RPD5R +#define U1RTS_RPE8R 1, PIC32MZ_RPE8R +#define U1RTS_RPF2R 1, PIC32MZ_RPF2R +#define U1RTS_RPF3R 1, PIC32MZ_RPF3R +#define U1RTS_RPF13R 1, PIC32MZ_RPF13R +#define U1RTS_RPG9R 1, PIC32MZ_RPG9R + +#define U1TX_RPA15R 1, PIC32MZ_RPA15R +#define U1TX_RPB1R 1, PIC32MZ_RPB1R +#define U1TX_RPB3R 1, PIC32MZ_RPB3R +#define U1TX_RPC4R 1, PIC32MZ_RPC4R +#define U1TX_RPC13R 1, PIC32MZ_RPC13R +#define U1TX_RPD3R 1, PIC32MZ_RPD3R +#define U1TX_RPD7R 1, PIC32MZ_RPD7R +#define U1TX_RPD11R 1, PIC32MZ_RPD11R +#define U1TX_RPD15R 1, PIC32MZ_RPD15R +#define U1TX_RPE5R 1, PIC32MZ_RPE5R +#define U1TX_RPF0R 1, PIC32MZ_RPF0R +#define U1TX_RPF5R 1, PIC32MZ_RPF5R +#define U1TX_RPG0R 1, PIC32MZ_RPG0R +#define U1TX_RPG7R 1, PIC32MZ_RPG7R + +#define U2RTS_RPA15R 2, PIC32MZ_RPA15R +#define U2RTS_RPB1R 2, PIC32MZ_RPB1R +#define U2RTS_RPB3R 2, PIC32MZ_RPB3R +#define U2RTS_RPC4R 2, PIC32MZ_RPC4R +#define U2RTS_RPC13R 2, PIC32MZ_RPC13R +#define U2RTS_RPD3R 2, PIC32MZ_RPD3R +#define U2RTS_RPD7R 2, PIC32MZ_RPD7R +#define U2RTS_RPD11R 2, PIC32MZ_RPD11R +#define U2RTS_RPD15R 2, PIC32MZ_RPD15R +#define U2RTS_RPE5R 2, PIC32MZ_RPE5R +#define U2RTS_RPF0R 2, PIC32MZ_RPF0R +#define U2RTS_RPF5R 2, PIC32MZ_RPF5R +#define U2RTS_RPG0R 2, PIC32MZ_RPG0R +#define U2RTS_RPG7R 2, PIC32MZ_RPG7R + +#define U2TX_RPB2R 2, PIC32MZ_RPB2R +#define U2TX_RPB6R 2, PIC32MZ_RPB6R +#define U2TX_RPB14R 2, PIC32MZ_RPB14R +#define U2TX_RPC2R 2, PIC32MZ_RPC2R +#define U2TX_RPD0R 2, PIC32MZ_RPD0R +#define U2TX_RPD1R 2, PIC32MZ_RPD1R +#define U2TX_RPD5R 2, PIC32MZ_RPD5R +#define U2TX_RPE8R 2, PIC32MZ_RPE8R +#define U2TX_RPF2R 2, PIC32MZ_RPF2R +#define U2TX_RPF3R 2, PIC32MZ_RPF3R +#define U2TX_RPF13R 2, PIC32MZ_RPF13R +#define U2TX_RPG9R 2, PIC32MZ_RPG9R + +#define U3RTS_RPB0R 1, PIC32MZ_RPB0R +#define U3RTS_RPB7R 1, PIC32MZ_RPB7R +#define U3RTS_RPB8R 1, PIC32MZ_RPB8R +#define U3RTS_RPB15R 1, PIC32MZ_RPB15R +#define U3RTS_RPC3R 1, PIC32MZ_RPC3R +#define U3RTS_RPD4R 1, PIC32MZ_RPD4R +#define U3RTS_RPD9R 1, PIC32MZ_RPD9R +#define U3RTS_RPD12R 1, PIC32MZ_RPD12R +#define U3RTS_RPE3R 1, PIC32MZ_RPE3R +#define U3RTS_RPE9R 1, PIC32MZ_RPE9R +#define U3RTS_RPF8R 1, PIC32MZ_RPF8R +#define U3RTS_RPF12R 1, PIC32MZ_RPF12R +#define U3RTS_RPG6R 1, PIC32MZ_RPG6R + +#define U3TX_RPA14R 1, PIC32MZ_RPA14R +#define U3TX_RPB5R 1, PIC32MZ_RPB5R +#define U3TX_RPB9R 1, PIC32MZ_RPB9R +#define U3TX_RPB10R 1, PIC32MZ_RPB10R +#define U3TX_RPC1R 1, PIC32MZ_RPC1R +#define U3TX_RPC14R 1, PIC32MZ_RPC14R +#define U3TX_RPD2R 1, PIC32MZ_RPD2R +#define U3TX_RPD6R 1, PIC32MZ_RPD6R +#define U3TX_RPD10R 1, PIC32MZ_RPD10R +#define U3TX_RPD14R 1, PIC32MZ_RPD14R +#define U3TX_RPF1R 1, PIC32MZ_RPF1R +#define U3TX_RPF4R 1, PIC32MZ_RPF4R +#define U3TX_RPG1R 1, PIC32MZ_RPG1R +#define U3TX_RPG8R 1, PIC32MZ_RPG8R + +#define U4RTS_RPA14R 2, PIC32MZ_RPA14R +#define U4RTS_RPB5R 2, PIC32MZ_RPB5R +#define U4RTS_RPB9R 2, PIC32MZ_RPB9R +#define U4RTS_RPB10R 2, PIC32MZ_RPB10R +#define U4RTS_RPC1R 2, PIC32MZ_RPC1R +#define U4RTS_RPC14R 2, PIC32MZ_RPC14R +#define U4RTS_RPD2R 2, PIC32MZ_RPD2R +#define U4RTS_RPD6R 2, PIC32MZ_RPD6R +#define U4RTS_RPD10R 2, PIC32MZ_RPD10R +#define U4RTS_RPD14R 2, PIC32MZ_RPD14R +#define U4RTS_RPF1R 2, PIC32MZ_RPF1R +#define U4RTS_RPF4R 2, PIC32MZ_RPF4R +#define U4RTS_RPG1R 2, PIC32MZ_RPG1R +#define U4RTS_RPG8R 2, PIC32MZ_RPG8R + +#define U4TX_RPB0R 2, PIC32MZ_RPB0R +#define U4TX_RPB7R 2, PIC32MZ_RPB7R +#define U4TX_RPB8R 2, PIC32MZ_RPB8R +#define U4TX_RPB15R 2, PIC32MZ_RPB15R +#define U4TX_RPC3R 2, PIC32MZ_RPC3R +#define U4TX_RPD4R 2, PIC32MZ_RPD4R +#define U4TX_RPD9R 2, PIC32MZ_RPD9R +#define U4TX_RPD12R 2, PIC32MZ_RPD12R +#define U4TX_RPE3R 2, PIC32MZ_RPE3R +#define U4TX_RPE9R 2, PIC32MZ_RPE9R +#define U4TX_RPF8R 2, PIC32MZ_RPF8R +#define U4TX_RPF12R 2, PIC32MZ_RPF12R +#define U4TX_RPG6R 2, PIC32MZ_RPG6R + +#define U5RTS_RPB2R 3, PIC32MZ_RPB2R +#define U5RTS_RPB6R 3, PIC32MZ_RPB6R +#define U5RTS_RPB14R 3, PIC32MZ_RPB14R +#define U5RTS_RPC2R 3, PIC32MZ_RPC2R +#define U5RTS_RPD0R 3, PIC32MZ_RPD0R +#define U5RTS_RPD1R 3, PIC32MZ_RPD1R +#define U5RTS_RPD5R 3, PIC32MZ_RPD5R +#define U5RTS_RPE8R 3, PIC32MZ_RPE8R +#define U5RTS_RPF2R 3, PIC32MZ_RPF2R +#define U5RTS_RPF3R 3, PIC32MZ_RPF3R +#define U5RTS_RPF13R 3, PIC32MZ_RPF13R +#define U5RTS_RPG9R 3, PIC32MZ_RPG9R + +#define U5TX_RPA15R 3, PIC32MZ_RPA15R +#define U5TX_RPB1R 3, PIC32MZ_RPB1R +#define U5TX_RPB3R 3, PIC32MZ_RPB3R +#define U5TX_RPC4R 3, PIC32MZ_RPC4R +#define U5TX_RPC13R 3, PIC32MZ_RPC13R +#define U5TX_RPD3R 3, PIC32MZ_RPD3R +#define U5TX_RPD7R 3, PIC32MZ_RPD7R +#define U5TX_RPD11R 3, PIC32MZ_RPD11R +#define U5TX_RPD15R 3, PIC32MZ_RPD15R +#define U5TX_RPE5R 3, PIC32MZ_RPE5R +#define U5TX_RPF0R 3, PIC32MZ_RPF0R +#define U5TX_RPF5R 3, PIC32MZ_RPF5R +#define U5TX_RPG0R 3, PIC32MZ_RPG0R +#define U5TX_RPG7R 3, PIC32MZ_RPG7R + +#define U6RTS_RPA15R 4, PIC32MZ_RPA15R +#define U6RTS_RPB1R 4, PIC32MZ_RPB1R +#define U6RTS_RPB3R 4, PIC32MZ_RPB3R +#define U6RTS_RPC4R 4, PIC32MZ_RPC4R +#define U6RTS_RPC13R 4, PIC32MZ_RPC13R +#define U6RTS_RPD3R 4, PIC32MZ_RPD3R +#define U6RTS_RPD7R 4, PIC32MZ_RPD7R +#define U6RTS_RPD11R 4, PIC32MZ_RPD11R +#define U6RTS_RPD15R 4, PIC32MZ_RPD15R +#define U6RTS_RPE5R 4, PIC32MZ_RPE5R +#define U6RTS_RPF0R 4, PIC32MZ_RPF0R +#define U6RTS_RPF5R 4, PIC32MZ_RPF5R +#define U6RTS_RPG0R 4, PIC32MZ_RPG0R +#define U6RTS_RPG7R 4, PIC32MZ_RPG7R + +#define U6TX_RPB0R 4, PIC32MZ_RPB0R +#define U6TX_RPB2R 4, PIC32MZ_RPB2R +#define U6TX_RPB6R 4, PIC32MZ_RPB6R +#define U6TX_RPB7R 4, PIC32MZ_RPB7R +#define U6TX_RPB8R 4, PIC32MZ_RPB8R +#define U6TX_RPB14R 4, PIC32MZ_RPB14R +#define U6TX_RPB15R 4, PIC32MZ_RPB15R +#define U6TX_RPC2R 4, PIC32MZ_RPC2R +#define U6TX_RPC3R 4, PIC32MZ_RPC3R +#define U6TX_RPD0R 4, PIC32MZ_RPD0R +#define U6TX_RPD1R 4, PIC32MZ_RPD1R +#define U6TX_RPD4R 4, PIC32MZ_RPD4R +#define U6TX_RPD5R 4, PIC32MZ_RPD5R +#define U6TX_RPD9R 4, PIC32MZ_RPD9R +#define U6TX_RPD12R 4, PIC32MZ_RPD12R +#define U6TX_RPE3R 4, PIC32MZ_RPE3R +#define U6TX_RPE8R 4, PIC32MZ_RPE8R +#define U6TX_RPE9R 4, PIC32MZ_RPE9R +#define U6TX_RPF2R 4, PIC32MZ_RPF2R +#define U6TX_RPF3R 4, PIC32MZ_RPF3R +#define U6TX_RPF8R 4, PIC32MZ_RPF8R +#define U6TX_RPF12R 4, PIC32MZ_RPF12R +#define U6TX_RPF13R 4, PIC32MZ_RPF13R +#define U6TX_RPG6R 4, PIC32MZ_RPG6R +#define U6TX_RPG9R 4, PIC32MZ_RPG9R + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_CHIP_PIC32MZEC_PPS_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-config.h b/arch/mips/src/pic32mz/pic32mz-config.h new file mode 100644 index 0000000000000000000000000000000000000000..af150d4979eeefa38a1f2236d6624e97c16b8a31 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-config.h @@ -0,0 +1,560 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CONFIG_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO IRQs ************************************************************************/ + +#ifndef CONFIG_PIC32MZ_GPIOIRQ +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTA +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTB +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTC +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTD +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTE +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTF +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTG +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTH +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTJ +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTK +#endif + +#if CHIP_NPORTS < 1 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTA +#endif +#if CHIP_NPORTS < 2 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTB +#endif +#if CHIP_NPORTS < 3 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTC +#endif +#if CHIP_NPORTS < 4 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTD +#endif +#if CHIP_NPORTS < 5 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTE +#endif +#if CHIP_NPORTS < 6 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTF +#endif +#if CHIP_NPORTS < 7 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTG +#endif +#if CHIP_NPORTS < 8 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTH +#endif +#if CHIP_NPORTS < 9 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTJ +#endif +#if CHIP_NPORTS < 10 +# undef CONFIG_PIC32MZ_GPIOIRQ_PORTK +#endif + +/* UARTs ****************************************************************************/ +/* Don't enable UARTs not supported by the chip. */ + +#if CHIP_NUARTS < 1 +# undef CONFIG_PIC32MZ_UART1 +# undef CONFIG_PIC32MZ_UART2 +# undef CONFIG_PIC32MZ_UART3 +# undef CONFIG_PIC32MZ_UART4 +# undef CONFIG_PIC32MZ_UART5 +# undef CONFIG_PIC32MZ_UART6 +#elif CHIP_NUARTS < 2 +# undef CONFIG_PIC32MZ_UART2 +# undef CONFIG_PIC32MZ_UART3 +# undef CONFIG_PIC32MZ_UART4 +# undef CONFIG_PIC32MZ_UART5 +# undef CONFIG_PIC32MZ_UART6 +#elif CHIP_NUARTS < 3 +# undef CONFIG_PIC32MZ_UART3 +# undef CONFIG_PIC32MZ_UART4 +# undef CONFIG_PIC32MZ_UART5 +# undef CONFIG_PIC32MZ_UART6 +#elif CHIP_NUARTS < 4 +# undef CONFIG_PIC32MZ_UART4 +# undef CONFIG_PIC32MZ_UART5 +# undef CONFIG_PIC32MZ_UART6 +#elif CHIP_NUARTS < 5 +# undef CONFIG_PIC32MZ_UART5 +# undef CONFIG_PIC32MZ_UART6 +#elif CHIP_NUARTS < 6 +# undef CONFIG_PIC32MZ_UART6 +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_PIC32MZ_UART1) || defined(CONFIG_PIC32MZ_UART2) || \ + defined(CONFIG_PIC32MZ_UART3) || defined(CONFIG_PIC32MZ_UART4) || \ + defined(CONFIG_PIC32MZ_UART5) || defined(CONFIG_PIC32MZ_UART6) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,.. CHIP_NUARTS + */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART3) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART4) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART5) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) && defined(CONFIG_PIC32MZ_UART6) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART6_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* SPI ******************************************************************************/ +/* Don't enable SPI peripherals not supported by the chip. */ + +#if CHIP_NSPI < 1 +# undef CONFIG_PIC32MZ_SPI1 +# undef CONFIG_PIC32MZ_SPI2 +# undef CONFIG_PIC32MZ_SPI3 +# undef CONFIG_PIC32MZ_SPI4 +# undef CONFIG_PIC32MZ_SPI5 +# undef CONFIG_PIC32MZ_SPI6 +#elif CHIP_NSPI < 2 +# undef CONFIG_PIC32MZ_SPI2 +# undef CONFIG_PIC32MZ_SPI3 +# undef CONFIG_PIC32MZ_SPI4 +# undef CONFIG_PIC32MZ_SPI5 +# undef CONFIG_PIC32MZ_SPI6 +#elif CHIP_NSPI < 3 +# undef CONFIG_PIC32MZ_SPI3 +# undef CONFIG_PIC32MZ_SPI4 +# undef CONFIG_PIC32MZ_SPI5 +# undef CONFIG_PIC32MZ_SPI6 +#elif CHIP_NSPI < 4 +# undef CONFIG_PIC32MZ_SPI4 +# undef CONFIG_PIC32MZ_SPI5 +# undef CONFIG_PIC32MZ_SPI6 +#elif CHIP_NSPI < 5 +# undef CONFIG_PIC32MZ_SPI5 +# undef CONFIG_PIC32MZ_SPI6 +#elif CHIP_NSPI < 6 +# undef CONFIG_PIC32MZ_SPI6 +#endif + +/* Are any SPI peripherals enabled? */ + +#undef CONFIG_PIC32MZ_SPI +#if defined(CONFIG_PIC32MZ_SPI1) || defined(CONFIG_PIC32MZ_SPI2) || \ + defined(CONFIG_PIC32MZ_SPI4) || defined(CONFIG_PIC32MZ_SPI4) || \ + defined(CONFIG_PIC32MZ_SPI5) || defined(CONFIG_PIC32MZ_SPI6) +# define CONFIG_PIC32MZ_SPI 1 +#endif + +/* Device Configuration *************************************************************/ +/* DEVCFG3 */ +/* Configurable settings */ + +#ifndef CONFIG_PIC32MZ_USERID /* User ID */ +# define CONFIG_PIC32MZ_USERID 0x584e /* "NX" */ +#endif +#define ADEVCFG3_USERID 0x1234 + +#ifndef CONFIG_PIC32MZ_FMIIEN /* Ethernet MII enable: 0=RMII 1=MII */ +# define CONFIG_PIC32MZ_FMIIEN 1 /* MII enabled */ +#endif + +#ifndef CONFIG_PIC32MZ_PGL1WAY /* Permission group lock one way configuration */ +# define CONFIG_PIC32MZ_PGL1WAY 0 /* Allow multiple configurations */ +#endif + +#ifndef CONFIG_PIC32MZ_PMDL1WAY /* Peripheral module disable configuration */ +# define CONFIG_PIC32MZ_PMDL1WAY 0 /* Allow multiple reconfigurations */ +#endif + +#ifndef CONFIG_PIC32MZ_IOL1WAY /* Peripheral pin select configuration */ +# define CONFIG_PIC32MZ_IOL1WAY 0 /* Allow multiple reconfigurations */ +#endif + +#ifndef CONFIG_PIC32MZ_FETHIO /* Ethernet I/O Pins 0=alternate 1=default */ +# define CONFIG_PIC32MZ_FETHIO 1 /* Default Ethernet I/O Pins */ +#endif + +#ifndef CONFIG_PIC32MZ_FUSBIDIO /* USB USBID selection: 0=GPIO 1=USB */ +# ifdef CONFIG_PIC32MZ_USB +# define CONFIG_PIC32MZ_FUSBIDIO 1 /* USBID pin is controlled by the USB module */ +# else +# define CONFIG_PIC32MZ_FUSBIDIO 0 /* USBID pin is controlled by the IOPORT configuration */ +# endif +#endif + +/* DEVCFG2 */ +/* PLL Input Divider bits */ + +#undef CONFIG_PIC32MZ_PLLIDIV +#if BOARD_PLL_IDIV == 1 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_1 +#elif BOARD_PLL_IDIV == 2 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_2 +#elif BOARD_PLL_IDIV == 3 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_3 +#elif BOARD_PLL_IDIV == 4 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_4 +#elif BOARD_PLL_IDIV == 5 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_5 +#elif BOARD_PLL_IDIV == 6 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_6 +#elif BOARD_PLL_IDIV == 7 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_7 +#elif BOARD_PLL_IDIV == 8 +# define CONFIG_PIC32MZ_PLLIDIV DEVCFG2_FPLLIDIV_8 +#else +# error "Unsupported BOARD_PLL_IDIV" +#endif + +/* System PLL Divided Input Clock Frequency Range bits. + * REVISIT: Based on the name of this configuration value, the following + * comparisons do not seem correct (the input clock is not divided). + * These comparisons are used because this results in settings that match + * Microchip sample code. + */ + +#if BOARD_PLL_INPUT < 5000000 +# error BOARD_PLL_INPUT / BOARD_PLL_IDIV too low +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_BYPASS /* < 5 MHz */ +#elif BOARD_PLL_INPUT < 10000000 +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_5_10MHZ /* 5-10 MHz */ +#elif BOARD_PLL_INPUT < 16000000 +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_8_16MHZ /* 8-16 MHz */ +#elif BOARD_PLL_INPUT < 26000000 +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_13_26MHZ /* 13-26 MHz */ +#elif BOARD_PLL_INPUT < 42000000 +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_21_42MHZ /* 21-42 MHz */ +#elif BOARD_PLL_INPUT <= 64000000 +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_34_64MHZ /* 36-64 MHz */ +#else +# error BOARD_PLL_INPUT too high +# define CONFIG_PIC32MZ_FPLLRNG DEVCFG2_FPLLRNG_34_64MHZ /* > 64 MHz */ +#endif + +/* PLL multiplier */ + +#undef CONFIG_PIC32MZ_PLLMULT +#if BOARD_PLL_MULT >= 1 && BOARD_PLL_MULT <= 128 +# define CONFIG_PIC32MZ_PLLMULT ((BOARD_PLL_MULT-1) << DEVCFG2_FPLLMULT_SHIFT) +#else +# error "Unsupported BOARD_PLL_MULT" +#endif + +/* PLL output divider */ + +#undef CONFIG_PIC32MZ_PLLODIV +#if BOARD_PLL_ODIV == 2 +# define CONFIG_PIC32MZ_PLLODIV DEVCFG2_FPLLODIV_2 +#elif BOARD_PLL_ODIV == 4 +# define CONFIG_PIC32MZ_PLLODIV DEVCFG2_FPLLODIV_4 +#elif BOARD_PLL_ODIV == 8 +# define CONFIG_PIC32MZ_PLLODIV DEVCFG2_FPLLODIV_8 +#elif BOARD_PLL_ODIV == 16 +# define CONFIG_PIC32MZ_PLLODIV DEVCFG2_FPLLODIV_16 +#elif BOARD_PLL_ODIV == 32 +# define CONFIG_PIC32MZ_PLLODIV DEVCFG2_FPLLODIV_32 +#else +# error "Unsupported BOARD_PLL_ODIV" +#endif + +#if BOARD_POSC_FREQ == 12000000 +# define CONFIG_PIC32MZ_UPLLFSEL DEVCFG2_UPLLFSEL_12MHZ +#else +# define CONFIG_PIC32MZ_UPLLFSEL DEVCFG2_UPLLFSEL_24MHZ +#endif + +/* Not yet configurable settings (REVISIT) */ + + /* System PLL Input Clock Select bit */ +#define CONFIG_PIC32MZ_FPLLICLK 0 /* POSC is selected as input to the System PLL */ + /* USB PLL Input Frequency Select bit */ + +/* DEVCFG1 */ +/* Configurable settings */ + +#undef CONFIG_PIC32MZ_FNOSC +#if defined(BOARD_FNOSC_FRC) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_FRC +#elif defined(BOARD_FNOSC_SPLL) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_SPLL +#elif defined(BOARD_FNOSC_POSC) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_POSC +#elif defined(BOARD_FNOSC_SOSC) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_SOSC +#elif defined(BOARD_FNOSC_LPRC) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_LPRC +#elif defined(BOARD_FNOSC_FRCDIV) +# define CONFIG_PIC32MZ_FNOSC DEVCFG1_FNOSC_FRCDIV +#else +# error "Unknown board FNOSC selection" +#endif + +#undef CONFIG_PIC32MZ_FSOSCEN +#ifdef BOARD_SOSC_ENABLE +# define CONFIG_PIC32MZ_FSOSCEN DEVCFG1_FSOSCEN +#else +# define CONFIG_PIC32MZ_FSOSCEN 0 +#endif + +#undef CONFIG_PIC32MZ_IESO +#ifdef BOARD_SOSC_IESO +# define CONFIG_PIC32MZ_IESO DEVCFG1_IESO +#else +# define CONFIG_PIC32MZ_IESO 0 +#endif + +#undef CONFIG_PIC32MZ_POSCMOD +#if defined(BOARD_POSC_ECMODE) +# define CONFIG_PIC32MZ_POSCMOD DEVCFG1_POSCMOD_EC +#elif defined(BOARD_POSC_HSMODE) +# define CONFIG_PIC32MZ_POSCMOD DEVCFG1_POSCMOD_HS +#elif defined(BOARD_POSC_DISABLED) +# define CONFIG_PIC32MZ_POSCMOD DEVCFG1_POSCMOD_DIS +#else +# error "Unknown board POSC mode" +#endif + +#ifdef CONFIG_PIC32MZ_OSCIOFNC +# undef CONFIG_PIC32MZ_OSCIOFNC +# define CONFIG_PIC32MZ_OSCIOFNC DEVCFG1_OSCIOFNC +#else +# undef CONFIG_PIC32MZ_OSCIOFNC +# define CONFIG_PIC32MZ_OSCIOFNC 0 +#endif + +#undef CONFIG_PIC32MZ_FCKSM +#if defined(BOARD_POSC_SWITCH) +# if defined(BOARD_POSC_FSCM) +# define CONFIG_PIC32MZ_FCKSM DEVCFG1_FCKSM_BOTH +# else +# define CONFIG_PIC32MZ_FCKSM DEVCFG1_FCKSM_SWITCH +# endif +#else +# if defined(BOARD_POSC_FSCM) +# define CONFIG_PIC32MZ_FCKSM DEVCFG1_FCKSM_MONITOR +# else +# define CONFIG_PIC32MZ_FCKSM DEVCFG1_FCKSM_NONE +# endif +#endif + +#undef CONFIG_PIC32MZ_WDTPS +#if BOARD_WD_PRESCALER == 1 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_1 +#elif BOARD_WD_PRESCALER == 2 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_2 +#elif BOARD_WD_PRESCALER == 4 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_4 +#elif BOARD_WD_PRESCALER == 8 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_8 +#elif BOARD_WD_PRESCALER == 16 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_16 +#elif BOARD_WD_PRESCALER == 32 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_32 +#elif BOARD_WD_PRESCALER == 64 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_64 +#elif BOARD_WD_PRESCALER == 128 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_128 +#elif BOARD_WD_PRESCALER == 256 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_256 +#elif BOARD_WD_PRESCALER == 512 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_512 +#elif BOARD_WD_PRESCALER == 1024 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_1024 +#elif BOARD_WD_PRESCALER == 2048 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_2048 +#elif BOARD_WD_PRESCALER == 4096 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_4096 +#elif BOARD_WD_PRESCALER == 8192 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_8192 +#elif BOARD_WD_PRESCALER == 16384 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_16384 +#elif BOARD_WD_PRESCALER == 32768 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_32768 +#elif BOARD_WD_PRESCALER == 65536 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_65536 +#elif BOARD_WD_PRESCALER == 131072 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_131072 +#elif BOARD_WD_PRESCALER == 262144 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_262144 +#elif BOARD_WD_PRESCALER == 524288 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_524288 +#elif BOARD_WD_PRESCALER == 1048576 +# define CONFIG_PIC32MZ_WDTPS DEVCFG1_WDTPS_1048576 +#else +# error "Unsupported BOARD_WD_PRESCALER" +#endif + +#undef CONFIG_PIC32MZ_FWDTEN +#ifdef CONFIG_PIC32MZ_WDTENABLE +# define CONFIG_PIC32MZ_FWDTEN DEVCFG1_FWDT_ENSABLED +#else +# define CONFIG_PIC32MZ_FWDTEN DEVCFG1_FWDT_DISABLED +#endif +#define ADEVCFG1_FWDTEN DEVCFG1_FWDT_DISABLED + +/* Not yet configurable settings */ + +#define CONFIG_PIC32MZ_DMTINV DEVCFG1_DMTINV_127_128 +#define CONFIG_PIC32MZ_WDTSPGM DEVCFG1_WDTSPGM_STOP +#define CONFIG_PIC32MZ_WINDIS DEVCFG1_WDT_NORMAL +#define CONFIG_PIC32MZ_FWDTWINSZ DEVCFG1_FWDTWINSZ_25 +#define CONFIG_PIC32MZ_DMTCNT DEVCFG1_DMTCNT_MAX +#define CONFIG_PIC32MZ_FDMTEN 0 + +/* DEVCFG0 */ +/* Configurable settings */ + +#undef CONFIG_PIC32MZ_DEBUGGER +#ifdef CONFIG_PIC32MZ_DEBUGGER_ENABLE +# define CONFIG_PIC32MZ_DEBUGGER DEVCFG0_DEBUG_ENABLED +#else +# define CONFIG_PIC32MZ_DEBUGGER DEVCFG0_DEBUG_DISABLED +#endif + +#undef CONFIG_PIC32MZ_JTAGEN +#ifdef CONFIG_PIC32MZ_JTAG_ENABLE +# define CONFIG_PIC32MZ_JTAGEN DEVCFG0_JTAGEN +#else +# define CONFIG_PIC32MZ_JTAGEN 0 +#endif + +#undef CONFIG_PIC32MZ_ICESEL +#ifdef CONFIG_PIC32MZ_ICESEL_CH2 +# define CONFIG_PIC32MZ_ICESEL DEVCFG0_ICESEL_2 +#else +# define CONFIG_PIC32MZ_ICESEL DEVCFG0_ICESEL_1 +#endif + +#undef CONFIG_PIC32MZ_TRCEN +#ifdef CONFIG_PIC32MZ_TRACE_ENABLE +# define CONFIG_PIC32MZ_TRCEN DEVCFG0_TRCEN +#else +# define CONFIG_PIC32MZ_TRCEN 0 +#endif + +#ifdef CONFIG_MIPS_MICROMIPS +# define CONFIG_PIC32MZ_BOOTISA DEVCFG0_BOOT_MICROMIPS +#else +# define CONFIG_PIC32MZ_BOOTISA DEVCFG0_BOOT_MIPS32 +#endif + +#ifndef CONFIG_PIC32MZ_ECC_OPTION +# define CONFIG_PIC32MZ_ECC_OPTION 3 +#endif +#if CONFIG_PIC32MZ_ECC_OPTION < 0 || CONFIG_PIC32MZ_ECC_OPTION > 3 +# error Invalid CONFIG_PIC32MZ_ECC_OPTION Invalid +# undef CONFIG_PIC32MZ_ECC_OPTION +# define CONFIG_PIC32MZ_ECC_OPTION 3 +#endif +#define CONFIG_PIC32MZ_FECCCON (CONFIG_PIC32MZ_ECC_OPTION << DEVCFG0_FECCCON_SHIFT) + +/* Not yet configurable settings */ + +#define CONFIG_PIC32MZ_FSLEEP DEVCFG0_FSLEEP_OFF +#define CONFIG_PIC32MZ_DBGPER DEVCFG0_DBGPER_ALL +#define CONFIG_PIC32MZ_EJTAGBEN DEVCFG0_EJTAG_NORMAL + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_CONFIG_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-decodeirq.c b/arch/mips/src/pic32mz/pic32mz-decodeirq.c new file mode 100644 index 0000000000000000000000000000000000000000..14b980c3f56a1c32b6bb6c04ab45fa492d7ef47c --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-decodeirq.c @@ -0,0 +1,200 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-decodeirq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/pic32mz-int.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_decodeirq + * + * Description: + * Called from assembly language logic when an interrupt exception occurs. + * This function decodes and dispatches the interrupt. + * + ****************************************************************************/ + +uint32_t *pic32mz_decodeirq(uint32_t *regs) +{ +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + uint32_t *savestate; +#endif + uint32_t regval; + int irq; + + /* If the board supports LEDs, turn on an LED now to indicate that we are + * processing an interrupt. + */ + + board_autoled_on(LED_INIRQ); + + /* Save the current value of g_current_regs (to support nested interrupt + * handling). Then set g_current_regs to regs, indicating that this is + * the interrupted context that is being processed now. + */ + +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + savestate = (uint32_t *)g_current_regs; +#else + DEBUGASSERT(g_current_regs == NULL); +#endif + g_current_regs = regs; + + /* Loop while there are pending interrupts with priority greater than zero */ + + for (; ; ) + { + /* Read the INTSTAT register. This register contains both the priority + * and the interrupt vector number. + */ + + regval = getreg32(PIC32MZ_INT_INTSTAT); + if ((regval & INT_INTSTAT_SRIPL_MASK) == 0) + { + /* Break out of the loop when the priority is zero meaning that + * there are no further pending interrupts. + */ + + break; + } + + /* Get the vector number. The IRQ numbers have been arranged so that + * vector numbers and NuttX IRQ numbers are the same value. + */ + + irq = ((regval) & INT_INTSTAT_SIRQ_MASK) >> INT_INTSTAT_SIRQ_SHIFT; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + } + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + /* Restore the previous value of g_current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + * + * REVISIT: There are task switching issues! You should not enable + * nested interrupts unless you are ready to deal with the complexities + * of fixing nested context switching. The logic here is insufficient. + */ + + g_current_regs = savestate; + if (g_current_regs == NULL) + { + board_autoled_off(LED_INIRQ); + } +#else + g_current_regs = NULL; + board_autoled_off(LED_INIRQ); +#endif + + return regs; +} diff --git a/arch/mips/src/pic32mz/pic32mz-dma.h b/arch/mips/src/pic32mz/pic32mz-dma.h new file mode 100644 index 0000000000000000000000000000000000000000..99cc6c47c53846f7efbe94bb001a7e22354f1b18 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-dma.h @@ -0,0 +1,228 @@ +/************************************************************************************ + * arch/mips/src/pic32mx/pic32mx-dma.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_DMA_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct pic32mx_dmaglobalregs_s +{ + /* Global Registers */ +#warning "Missing definitions" +}; + +struct pic32mx_dmachanregs_s +{ + /* Channel Registers */ +#warning "Missing definitions" +}; + +struct pic32mx_dmaregs_s +{ + /* Global Registers */ + + struct pic32mx_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct pic32mx_dmachanregs_s ch; +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mx_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmainitilaize(void); +#endif + +/************************************************************************************ + * Name: pic32mx_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and gives the + * caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel handle. NULL + * is returned on any failure. This function can fail only if no DMA channel is + * available. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +DMA_HANDLE pic32mx_dmachannel(void); +#endif + +/************************************************************************************ + * Name: pic32mx_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be + * used again until pic32mx_dmachannel() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmafree(DMA_HANDLE handle); +#endif + +/************************************************************************************ + * Name: pic32mx_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +int pic32mx_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); +#endif + +/************************************************************************************ + * Name: pic32mx_dmastart + * + * Description: + * Start the DMA transfer + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +int pic32mx_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); +#endif + +/************************************************************************************ + * Name: pic32mx_dmastop + * + * Description: + * Cancel the DMA. After pic32mx_dmastop() is called, the DMA channel is reset + * and pic32mx_dmasetup() must be called before pic32mx_dmastart() can be called + * again + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +void pic32mx_dmastop(DMA_HANDLE handle); +#endif + +/************************************************************************************ + * Name: pic32mx_dmasample + * + * Description: + * Sample DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +#ifdef CONFIG_DEBUG_DMA +void pic32mx_dmasample(DMA_HANDLE handle, struct pic32mx_dmaregs_s *regs); +#else +# define pic32mx_dmasample(handle,regs) +#endif +#endif + +/************************************************************************************ + * Name: pic32mx_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MX_DMA +#ifdef CONFIG_DEBUG_DMA +void pic32mx_dmadump(DMA_HANDLE handle, const struct pic32mx_dmaregs_s *regs, + const char *msg); +#else +# define pic32mx_dmadump(handle,regs,msg) +#endif +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_DMA_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-ethernet.c b/arch/mips/src/pic32mz/pic32mz-ethernet.c new file mode 100644 index 0000000000000000000000000000000000000000..6b45f1ea023fff8d1d7b1f73a9ca362b0c94d2b9 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-ethernet.c @@ -0,0 +1,3245 @@ +/**************************************************************************** + * arch/arm/src/pic32mz/pic32mz_ethernet.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This driver derives from the PIC32MZ Ethernet Driver + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_PIC32MZ_ETHERNET) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mz-config.h" +#include "chip/pic32mz-ethernet.h" + +/* Does this chip have and Ethernet controller? */ + +#if CHIP_NETHERNET > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* CONFIG_PIC32MZ_NINTERFACES determines the number of physical interfaces + * that will be supported -- unless it is more than actually supported by the + * hardware! + */ + +#if !defined(CONFIG_PIC32MZ_NINTERFACES) || CONFIG_PIC32MZ_NINTERFACES > CHIP_NETHERNET +# undef CONFIG_PIC32MZ_NINTERFACES +# define CONFIG_PIC32MZ_NINTERFACES CHIP_NETHERNET +#endif + +/* The logic here has a few hooks for support for multiple interfaces, but + * that capability is not yet in place (and I won't worry about it until I get + * the first multi-interface PIC32MZ). + */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 +# warning "Only a single ethernet controller is supported" +# undef CONFIG_PIC32MZ_NINTERFACES +# define CONFIG_PIC32MZ_NINTERFACES 1 +#endif + +/* CONFIG_NET_MULTIBUFFER is required */ + +#ifndef CONFIG_NET_MULTIBUFFER +# error "CONFIG_NET_MULTIBUFFER=y is required" +#endif + +/* If IGMP is enabled, then accept multi-cast frames. */ + +#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_PIC32MZ_MULTICAST) +# define CONFIG_PIC32MZ_MULTICAST 1 +#endif + +/* Use defaults if the number of discriptors is not provided */ + +#ifndef CONFIG_NET_NTXDESC +# define CONFIG_NET_NTXDESC 2 +#endif + +#if CONFIG_NET_NTXDESC > 255 +# error "The number of TX descriptors exceeds the range of a uint8_t index" +#endif + +#ifndef CONFIG_NET_NRXDESC +# define CONFIG_NET_NRXDESC 4 +#endif + +/* Make sure that the size of each buffer is a multiple of 4 bytes. This + * will force alignment of all buffers to 4-byte boundaries (this is needed + * by the queuing logic which will cast each buffer address to a pointer + * type). + */ + +#define PIC32MZ_ALIGNED_BUFSIZE ((CONFIG_NET_ETH_MTU + 3) & ~3) + +/* The number of buffers will, then, be one for each descriptor plus one extra */ + +#define PIC32MZ_NBUFFERS (CONFIG_NET_NRXDESC + CONFIG_NET_NTXDESC + 1) + +/* Debug Configuration *****************************************************/ +/* Register/Descriptor debug -- can only happen of CONFIG_DEBUG is selected. + * This will probably generate much more output than you care to see. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_REGDEBUG +# undef CONFIG_NET_DESCDEBUG +#endif + +/* CONFIG_NET_DUMPPACKET will dump the contents of each packet to the + * console. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_DUMPPACKET +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define pic32mz_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define pic32mz_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define PIC32MZ_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define PIC32MZ_TXTIMEOUT (60*CLK_TCK) + +/* PHY timout = 1 minute */ + +#define PIC32MZ_MIITIMEOUT (666666) + +/* Ethernet MII clocking. + * + * The clock divider used to create the MII Management Clock (MDC). The MIIM + * module uses the SYSCLK as an input clock. According to the IEEE 802.3 + * Specification this should be no faster than 2.5 MHz. However, some PHYs + * support clock rates up to 12.5 MHz. + * + * The board.h file provides the "ideal" divisor as BOARD_EMAC_MIIM_DIV. We + * pick the closest, actual divisor greater than or equal to this. + */ + +#ifndef BOARD_EMAC_MIIM_DIV +# error "MIIM divider is not defined" +#elif BOARD_EMAC_MIIM_DIV <= 4 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV4 +#elif BOARD_EMAC_MIIM_DIV <= 6 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV6 +#elif BOARD_EMAC_MIIM_DIV <= 8 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV8 +#elif BOARD_EMAC_MIIM_DIV <= 10 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV10 +#elif BOARD_EMAC_MIIM_DIV <= 14 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV14 +#elif BOARD_EMAC_MIIM_DIV <= 20 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV20 +#elif BOARD_EMAC_MIIM_DIV <= 28 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV28 +#elif BOARD_EMAC_MIIM_DIV <= 40 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV40 +#elif BOARD_EMAC_MIIM_DIV <= 48 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV48 +#elif BOARD_EMAC_MIIM_DIV <= 50 +# define EMAC1_MCFG_CLKSEL_DIV EMAC1_MCFG_CLKSEL_DIV50 +#else +# error "MIIM divider cannot be realized" +#endif + +/* Interrupts ***************************************************************/ + +#define ETH_RXINTS (ETH_INT_RXOVFLW | ETH_INT_RXBUFNA | ETH_INT_RXDONE | ETH_INT_RXBUSE) +#define ETH_TXINTS (ETH_INT_TXABORT | ETH_INT_TXDONE | ETH_INT_TXBUSE) + +/* Misc. Helpers ***********************************************************/ + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->pd_dev.d_buf) + +/* PHYs *********************************************************************/ +/* Select PHY-specific values. Add more PHYs as needed. */ + +#if defined(CONFIG_ETH0_PHY_KS8721) +# define PIC32MZ_PHYNAME "KS8721" +# define PIC32MZ_PHYID1 MII_PHYID1_KS8721 +# define PIC32MZ_PHYID2 MII_PHYID2_KS8721 +# define PIC32MZ_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_DP83848C) +# define PIC32MZ_PHYNAME "DP83848C" +# define PIC32MZ_PHYID1 MII_PHYID1_DP83848C +# define PIC32MZ_PHYID2 MII_PHYID2_DP83848C +# define PIC32MZ_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_LAN8720) +# define PIC32MZ_PHYNAME "LAN8720" +# define PIC32MZ_PHYID1 MII_PHYID1_LAN8720 +# define PIC32MZ_PHYID2 MII_PHYID2_LAN8720 +# define PIC32MZ_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_LAN8740) +# define PIC32MZ_PHYNAME "LAN8740" +# define PIC32MZ_PHYID1 MII_PHYID1_LAN8740 +# define PIC32MZ_PHYID2 MII_PHYID2_LAN8740 +# define PIC32MZ_HAVE_PHY 1 +#elif defined(CONFIG_ETH0_PHY_LAN8740A) +# define PIC32MZ_PHYNAME "LAN8740A" +# define PIC32MZ_PHYID1 MII_PHYID1_LAN8740A +# define PIC32MZ_PHYID2 MII_PHYID2_LAN8740A +# define PIC32MZ_HAVE_PHY 1 +#else +# warning "No PHY specified!" +# undef PIC32MZ_HAVE_PHY +#endif + +/* These definitions are used to remember the speed/duplex settings */ + +#define PIC32MZ_SPEED_MASK 0x01 +#define PIC32MZ_SPEED_100 0x01 +#define PIC32MZ_SPEED_10 0x00 + +#define PIC32MZ_DUPLEX_MASK 0x02 +#define PIC32MZ_DUPLEX_FULL 0x02 +#define PIC32MZ_DUPLEX_HALF 0x00 + +#define PIC32MZ_10BASET_HD (PIC32MZ_SPEED_10 | PIC32MZ_DUPLEX_HALF) +#define PIC32MZ_10BASET_FD (PIC32MZ_SPEED_10 | PIC32MZ_DUPLEX_FULL) +#define PIC32MZ_100BASET_HD (PIC32MZ_SPEED_100 | PIC32MZ_DUPLEX_HALF) +#define PIC32MZ_100BASET_FD (PIC32MZ_SPEED_100 | PIC32MZ_DUPLEX_FULL) + +#ifdef CONFIG_PHY_SPEED100 +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MZ_MODE_DEFLT PIC32MZ_100BASET_FD +# else +# define PIC32MZ_MODE_DEFLT PIC32MZ_100BASET_HD +# endif +#else +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MZ_MODE_DEFLT PIC32MZ_10BASET_FD +# else +# define PIC32MZ_MODE_DEFLT PIC32MZ_10BASET_HD +# endif +#endif + +/* Misc Helper Macros *******************************************************/ + +#define PHYS_ADDR(va) ((uint32_t)(va) & 0x1fffffff) +#define VIRT_ADDR(pa) (KSEG1_BASE | (uint32_t)(pa)) + +/* Ever-present MIN and MAX macros */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The pic32mz_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct pic32mz_driver_s +{ + /* The following fields would only be necessary on chips that support + * multiple Ethernet controllers. + */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 + uint32_t pd_base; /* Ethernet controller base address */ + int pd_irq; /* Ethernet controller IRQ vector number */ + int pd_irqsrc; /* Ethernet controller IRQ source number */ +#endif + + bool pd_ifup; /* true:ifup false:ifdown */ + bool pd_txpending; /* There is a pending Tx in pd_dev */ + bool pd_polling; /* Avoid concurrent attempts to poll */ + uint8_t pd_mode; /* Speed/duplex */ +#ifdef PIC32MZ_HAVE_PHY + uint8_t pd_phyaddr; /* PHY device address */ +#endif + uint8_t pd_txnext; /* Index to the next Tx descriptor */ + uint32_t pd_inten; /* Shadow copy of INTEN register */ + WDOG_ID pd_txpoll; /* TX poll timer */ + WDOG_ID pd_txtimeout; /* TX timeout timer */ + + sq_queue_t pd_freebuffers; /* The free buffer list */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s pd_dev; /* Interface understood by uIP */ + + /* Descriptors and packet buffers */ + + struct pic32mz_rxdesc_s pd_rxdesc[CONFIG_NET_NRXDESC]; + struct pic32mz_txdesc_s pd_txdesc[CONFIG_NET_NTXDESC]; + uint8_t pd_buffers[PIC32MZ_NBUFFERS * PIC32MZ_ALIGNED_BUFSIZE]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Array of ethernet driver status structures */ + +static struct pic32mz_driver_s g_ethdrvr[CONFIG_PIC32MZ_NINTERFACES]; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations */ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mz_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void pic32mz_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t pic32mz_getreg(uint32_t addr); +static void pic32mz_putreg(uint32_t val, uint32_t addr); +#else +# define pic32mz_getreg(addr) getreg32(addr) +# define pic32mz_putreg(val,addr) putreg32(val,addr) +#endif + +/* Buffer and descriptor management */ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mz_dumptxdesc(struct pic32mz_txdesc_s *txdesc, const char *msg); +static void pic32mz_dumprxdesc(struct pic32mz_rxdesc_s *rxdesc, const char *msg); +#else +# define pic32mz_dumptxdesc(txdesc,msg) +# define pic32mz_dumprxdesc(rxdesc,msg) +#endif + +static inline void pic32mz_bufferinit(struct pic32mz_driver_s *priv); +static uint8_t *pic32mz_allocbuffer(struct pic32mz_driver_s *priv); +static void pic32mz_freebuffer(struct pic32mz_driver_s *priv, uint8_t *buffer); + +static inline void pic32mz_txdescinit(struct pic32mz_driver_s *priv); +static inline void pic32mz_rxdescinit(struct pic32mz_driver_s *priv); +static inline struct pic32mz_txdesc_s *pic32mz_txdesc(struct pic32mz_driver_s *priv); +static inline void pic32mz_txnext(struct pic32mz_driver_s *priv); +static inline void pic32mz_rxreturn(struct pic32mz_rxdesc_s *rxdesc); +static struct pic32mz_rxdesc_s *pic32mz_rxdesc(struct pic32mz_driver_s *priv); + +/* Common TX logic */ + +static int pic32mz_transmit(struct pic32mz_driver_s *priv); +static int pic32mz_txpoll(struct net_driver_s *dev); +static void pic32mz_poll(struct pic32mz_driver_s *priv); +static void pic32mz_timerpoll(struct pic32mz_driver_s *priv); + +/* Interrupt handling */ + +static void pic32mz_response(struct pic32mz_driver_s *priv); +static void pic32mz_rxdone(struct pic32mz_driver_s *priv); +static void pic32mz_txdone(struct pic32mz_driver_s *priv); +static int pic32mz_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void pic32mz_polltimer(int argc, uint32_t arg, ...); +static void pic32mz_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int pic32mz_ifup(struct net_driver_s *dev); +static int pic32mz_ifdown(struct net_driver_s *dev); +static int pic32mz_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int pic32mz_addmac(struct net_driver_s *dev, const uint8_t *mac); +static int pic32mz_rmmac(struct net_driver_s *dev, const uint8_t *mac); +#endif + +/* PHY initialization functions */ + +#ifdef PIC32MZ_HAVE_PHY +# ifdef CONFIG_NET_REGDEBUG +static void pic32mz_showmii(uint8_t phyaddr, const char *msg); +# else +# define pic32mz_showmii(phyaddr,msg) +# endif + +static void pic32mz_phybusywait(void); +static void pic32mz_phywrite(uint8_t phyaddr, uint8_t regaddr, + uint16_t phydata); +static uint16_t pic32mz_phyread(uint8_t phyaddr, uint8_t regaddr); +static inline int pic32mz_phyreset(uint8_t phyaddr); +# ifdef CONFIG_PHY_AUTONEG +static inline int pic32mz_phyautoneg(uint8_t phyaddr); +# endif +static int pic32mz_phymode(uint8_t phyaddr, uint8_t mode); +static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv); +#else +# define pic32mz_phyinit(priv) +#endif + +/* EMAC Initialization functions */ + +static void pic32mz_macmode(uint8_t mode); +static void pic32mz_ethreset(struct pic32mz_driver_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_printreg + * + * Description: + * Print the contents of an PIC32MZ register operation + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mz_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + lldbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: pic32mz_checkreg + * + * Description: + * Get the contents of an PIC32MZ register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mz_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + pic32mz_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + lldbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + pic32mz_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: pic32mz_getreg + * + * Description: + * Get the contents of an PIC32MZ register + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static uint32_t pic32mz_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + pic32mz_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: pic32mz_putreg + * + * Description: + * Set the contents of an PIC32MZ register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mz_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + pic32mz_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Function: pic32mz_dumptxdesc + * + * Description: + * Dump the contents of the specified TX descriptor + * + * Parameters: + * txdesc - Pointer to the TX descriptor to dump + * msg - Annotation for the TX descriptor + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mz_dumptxdesc(struct pic32mz_txdesc_s *txdesc, const char *msg) +{ + lldbg("TX Descriptor [%p]: %s\n", txdesc, msg); + lldbg(" status: %08x\n", txdesc->status); + lldbg(" address: %08x [%08x]\n", txdesc->address, VIRT_ADDR(txdesc->address)); + lldbg(" tsv1: %08x\n", txdesc->tsv1); + lldbg(" tsv2: %08x\n", txdesc->tsv2); + lldbg(" nexted: %08x [%08x]\n", txdesc->nexted, VIRT_ADDR(txdesc->nexted)); +} +#endif + +/**************************************************************************** + * Function: pic32mz_dumprxdesc + * + * Description: + * Dump the contents of the specified RX descriptor + * + * Parameters: + * txdesc - Pointer to the RX descriptor to dump + * msg - Annotation for the RX descriptor + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_DESCDEBUG +static void pic32mz_dumprxdesc(struct pic32mz_rxdesc_s *rxdesc, const char *msg) +{ + lldbg("RX Descriptor [%p]: %s\n", rxdesc, msg); + lldbg(" status: %08x\n", rxdesc->status); + lldbg(" address: %08x [%08x]\n", rxdesc->address, VIRT_ADDR(rxdesc->address)); + lldbg(" rsv1: %08x\n", rxdesc->rsv1); + lldbg(" rsv2: %08x\n", rxdesc->rsv2); + lldbg(" nexted: %08x [%08x]\n", rxdesc->nexted, VIRT_ADDR(rxdesc->nexted)); +} +#endif + +/**************************************************************************** + * Function: pic32mz_bufferinit + * + * Description: + * Initialize the buffers by placing them all in a free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void pic32mz_bufferinit(struct pic32mz_driver_s *priv) +{ + uint8_t *buffer; + int i; + + for (i = 0, buffer = priv->pd_buffers; i < PIC32MZ_NBUFFERS; i++) + { + /* Add the buffer to the end of the list of free buffers */ + + sq_addlast((sq_entry_t *)buffer, &priv->pd_freebuffers); + + /* Get the address of the next buffer */ + + buffer += PIC32MZ_ALIGNED_BUFSIZE; + } +} + +/**************************************************************************** + * Function: pic32mz_allocbuffer + * + * Description: + * Allocate one buffer by removing it from the free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * Pointer to the allocated buffer (or NULL on failure) + * + ****************************************************************************/ + +static uint8_t *pic32mz_allocbuffer(struct pic32mz_driver_s *priv) +{ + /* Return the next free buffer from the head of the free buffer list */ + + return (uint8_t *)sq_remfirst(&priv->pd_freebuffers); +} + +/**************************************************************************** + * Function: pic32mz_freebuffer + * + * Description: + * Free one buffer by returning it to the free list + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * Pointer to the allocated buffer (or NULL on failure) + * + ****************************************************************************/ + +static void pic32mz_freebuffer(struct pic32mz_driver_s *priv, uint8_t *buffer) +{ + /* Add the buffer to the end of the free buffer list */ + + sq_addlast((sq_entry_t *)buffer, &priv->pd_freebuffers); +} + +/**************************************************************************** + * Function: pic32mz_txdescinit + * + * Description: + * Initialize the EMAC Tx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mz_txdescinit(struct pic32mz_driver_s *priv) +{ + struct pic32mz_txdesc_s *txdesc; + int i; + + /* Assign a buffer to each TX descriptor. For now, just mark each TX + * descriptor as owned by softare andnot linked. + */ + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + /* Point to the next entry */ + + txdesc = &priv->pd_txdesc[i]; + + /* Initialize the buffer. It is idle, owned by software and has + * no buffer assigned to it. + */ + + txdesc->status = TXDESC_STATUS_SOWN | TXDESC_STATUS_NPV; + txdesc->address = 0; + txdesc->tsv1 = 0; + txdesc->tsv2 = 0; + + /* Set the NEXTED pointer. If this is the last descriptor in the + * list, then set the NEXTED pointer back to the first entry, + * creating a ring. + */ + + if (i == (CONFIG_NET_NRXDESC-1)) + { + txdesc->nexted = PHYS_ADDR(priv->pd_txdesc); + } + else + { + txdesc->nexted = PHYS_ADDR(&priv->pd_txdesc[i+1]); + } + + pic32mz_dumptxdesc(txdesc, "Initial"); + } + + /* Position the Tx index to the first descriptor in the ring */ + + priv->pd_txnext = 0; + + /* Update the ETHTXST register with the physical address of the head of + * the TX descriptors list. + */ + + pic32mz_putreg(PHYS_ADDR(priv->pd_txdesc), PIC32MZ_ETH_TXST); +} + +/**************************************************************************** + * Function: pic32mz_rxdescinit + * + * Description: + * Initialize the EMAC Rx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mz_rxdescinit(struct pic32mz_driver_s *priv) +{ + struct pic32mz_rxdesc_s *rxdesc; + int i; + + /* Prepare a list of RX descriptors populated with valid buffers for + * messages to be received. Properly update the NPV, EOWN = 1 and + * DATA_BUFFER_ADDRESS fields in the RX descriptors. The + * DATA_BUFFER_ADDRESS should contain the physical address of the + * corresponding RX buffer. + */ + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + /* Point to the next entry */ + + rxdesc = &priv->pd_rxdesc[i]; + + /* Initialize the descriptor. Assign it a buffer and make it ready + * for reception. + */ + + rxdesc->rsv1 = 0; + rxdesc->rsv2 = 0; + rxdesc->address = PHYS_ADDR(pic32mz_allocbuffer(priv)); + rxdesc->status = RXDESC_STATUS_EOWN | TXDESC_STATUS_NPV; + + /* Set the NEXTED pointer. If this is the last descriptor in the + * list, then set the NEXTED pointer back to the first entry, + * creating a ring. + */ + + if (i == (CONFIG_NET_NRXDESC-1)) + { + rxdesc->nexted = PHYS_ADDR(priv->pd_rxdesc); + } + else + { + rxdesc->nexted = PHYS_ADDR(&priv->pd_rxdesc[i+1]); + } + + pic32mz_dumprxdesc(rxdesc, "Initial"); + } + + /* Update the ETHRXST register with the physical address of the head of the + * RX descriptors list. + */ + + pic32mz_putreg(PHYS_ADDR(priv->pd_rxdesc), PIC32MZ_ETH_RXST); +} + +/**************************************************************************** + * Function: pic32mz_txdesc + * + * Description: + * Check if the next Tx descriptor is available. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * A pointer to the next available Tx descriptor on success; NULL if the + * next Tx dscriptor is not available. + * + ****************************************************************************/ + +static inline struct pic32mz_txdesc_s *pic32mz_txdesc(struct pic32mz_driver_s *priv) +{ + struct pic32mz_txdesc_s *txdesc; + + /* Get a reference to the next Tx descriptor in the ring */ + + txdesc = &priv->pd_txdesc[priv->pd_txnext]; + + /* Check if the EOWN bit is cleared. If it is, this descriptor is now under + * software control and the message has been transmitted. + * + * Also check that the buffer address is NULL. There is a race condition + * in that the hardware may have completed the transfer, but there may + * still be a valid buffer attached to the Tx descriptor because we have + * not yet processed the Tx done condition. We will know that the Tx + * done condition has been processed when the buffer has been freed and + * reset to zero. + */ + + if ((txdesc->status & TXDESC_STATUS_EOWN) == 0 && txdesc->address == 0) + { + /* Yes.. return a pointer to the descriptor */ + + return txdesc; + } + + /* The next Tx descriptor is still owned by the Ethernet controller.. the + * Tx ring if full and cannot be used now. Return NULL. + */ + + return NULL; +} + +/**************************************************************************** + * Function: pic32mz_txnext + * + * Description: + * After the next Tx descriptor has been given to the hardware, update the + * index to the next Tx descriptor in the ring. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void pic32mz_txnext(struct pic32mz_driver_s *priv) +{ + /* Increment the index to the next Tx descriptor in the ring */ + + int txnext = priv->pd_txnext + 1; + + /* If the new index would go beyond the end of the allocated descriptors + * for the Tx ring, then reset to first descriptor. + */ + + if (txnext >= CONFIG_NET_NTXDESC) + { + txnext = 0; + } + + /* Save the index to the next Tx descriptor */ + + priv->pd_txnext = txnext; +} + +/**************************************************************************** + * Function: pic32mz_rxreturn + * + * Description: + * Return an RX descriptor to the hardware. + * + * Parameters: + * rxdesc - Reference to the RX descriptor to be returned + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mz_rxreturn(struct pic32mz_rxdesc_s *rxdesc) +{ + rxdesc->rsv1 = 0; + rxdesc->rsv2 = 0; + rxdesc->status = RXDESC_STATUS_EOWN | TXDESC_STATUS_NPV; + pic32mz_dumprxdesc(rxdesc, "Returned to hardware"); +} + +/**************************************************************************** + * Function: pic32mz_rxdesc + * + * Description: + * Check if a RX descriptor is owned by the software. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * A pointer to the RX descriptor on success; NULL on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static struct pic32mz_rxdesc_s *pic32mz_rxdesc(struct pic32mz_driver_s *priv) +{ + struct pic32mz_rxdesc_s *rxdesc; + int i; + + /* Inspect the list of RX descriptors to see if the EOWN bit is cleared. + * If it is, this descriptor is now under software control and a message was + * received. Use SOP and EOP to extract the message, use BYTE_COUNT, RXF_RSV, + * RSV and PKT_CHECKSUM to get the message characteristics. + */ + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + /* Check if software owns this descriptor */ + + rxdesc = &priv->pd_rxdesc[i]; + if ((rxdesc->status & RXDESC_STATUS_EOWN) == 0) + { + /* Yes.. return a pointer to the descriptor */ + + return rxdesc; + } + } + + /* All descriptors are owned by the Ethernet controller.. return NULL */ + + return NULL; +} + +/**************************************************************************** + * Function: pic32mz_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mz_transmit(struct pic32mz_driver_s *priv) +{ + struct pic32mz_txdesc_s *txdesc; + uint32_t status; + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + DEBUGASSERT(priv->pd_dev.d_buf != NULL && + priv->pd_dev.d_len < CONFIG_NET_ETH_MTU); + + /* Increment statistics and dump the packet (if so configured) */ + + NETDEV_TXPACKETS(&priv->pd_dev); + pic32mz_dumppacket("Transmit packet", priv->pd_dev.d_buf, priv->pd_dev.d_len); + + /* In order to transmit a message: + * + * The SOP, EOP, DATA_BUFFER_ADDRESS and BYTE_COUNT will be updated when a + * particular message has to be transmitted. The DATA_BUFFER_ADDRESS will + * contain the physical address of the message, the BYTE_COUNT message size. + * SOP and EOP are set depending on how many packets are needed to transmit + * the message. + */ + + /* Find the next available TX descriptor. We are guaranteed that is will + * not fail by upstream logic that assures that a TX packet is available + * before polling uIP. + */ + + txdesc = pic32mz_txdesc(priv); + DEBUGASSERT(txdesc != NULL); + pic32mz_dumptxdesc(txdesc, "Before transmit setup"); + + /* Remove the transmit buffer from the device structure and assign it to + * the TX descriptor. + */ + + txdesc->address = PHYS_ADDR(priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + + /* Set the BYTE_COUNT for in the TX descriptor with the number of bytes + * contained in the buffer. + */ + + status = ((uint32_t)priv->pd_dev.d_len << TXDESC_STATUS_BYTECOUNT_SHIFT); + priv->pd_dev.d_len = 0; + + /* Set EOWN = 1 to indicate that the packet belongs to Ethernet and set both + * SOP and EOP to indicate that the packet both begins and ends with this + * frame. + */ + + status |= (TXDESC_STATUS_EOWN | TXDESC_STATUS_NPV | + TXDESC_STATUS_EOP | TXDESC_STATUS_SOP); + txdesc->status = status; + pic32mz_dumptxdesc(txdesc, "After transmit setup"); + + /* Update the index to the next descriptor to use in the Tx ring */ + + pic32mz_txnext(priv); + + /* Enable the transmission of the message by setting the TXRTS bit (ETHCON1:9). */ + + pic32mz_putreg(ETH_CON1_TXRTS | ETH_CON1_ON, PIC32MZ_ETH_CON1SET); + + /* Enable Tx interrupts */ + + priv->pd_inten |= ETH_TXINTS; + pic32mz_putreg(priv->pd_inten, PIC32MZ_ETH_IEN); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->pd_txtimeout, PIC32MZ_TXTIMEOUT, pic32mz_txtimeout, + 1, (uint32_t)priv); + + return OK; +} + +/**************************************************************************** + * Function: pic32mz_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mz_txpoll(struct net_driver_s *dev) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + int ret = OK; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) +#endif + { + arp_out(&priv->pd_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->pd_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send this packet. In this context, we know that there is space for + * at least one more packet in the descriptor list. + */ + + pic32mz_transmit(priv); + + /* Check if the next TX descriptor is available. If not, return a + * non-zero value to terminate the poll. + */ + + if (pic32mz_txdesc(priv) == NULL) + { + /* There are no more TX descriptors/buffers available.. stop the poll */ + + return -EAGAIN; + } + + /* Get the next Tx buffer needed in order to continue the poll */ + + priv->pd_dev.d_buf = pic32mz_allocbuffer(priv); + if (priv->pd_dev.d_buf == NULL) + { + /* We have no more buffers available for the nex Tx.. stop the poll */ + + return -ENOMEM; + } + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: pic32mz_poll + * + * Description: + * Perform the uIP poll. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pic32mz_poll(struct pic32mz_driver_s *priv) +{ + /* Is there already a poll in progress. This happens, for example, when + * debugging output is enabled. Interrupts may be re-enabled while debug + * output is performed and a timer expiration could attempt a concurrent + * poll. + */ + + if (!priv->pd_polling) + { + /* Assign a buffer for the poll */ + + DEBUGASSERT(priv->pd_dev.d_buf == NULL); + priv->pd_dev.d_buf = pic32mz_allocbuffer(priv); + if (priv->pd_dev.d_buf != NULL) + { + /* And perform the poll */ + + priv->pd_polling = true; + (void)devif_poll(&priv->pd_dev, pic32mz_txpoll); + + /* Free any buffer left attached after the poll */ + + if (priv->pd_dev.d_buf != NULL) + { + pic32mz_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + priv->pd_polling = false; + } + } + +} + +/**************************************************************************** + * Function: pic32mz_timerpoll + * + * Description: + * Perform the uIP timer poll. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pic32mz_timerpoll(struct pic32mz_driver_s *priv) +{ + /* Is there already a poll in progress. This happens, for example, when + * debugging output is enabled. Interrupts may be re-enabled while debug + * output is performed and a timer expiration could attempt a concurrent + * poll. + */ + + if (!priv->pd_polling) + { + DEBUGASSERT(priv->pd_dev.d_buf == NULL); + priv->pd_dev.d_buf = pic32mz_allocbuffer(priv); + if (priv->pd_dev.d_buf != NULL) + { + /* And perform the poll */ + + priv->pd_polling = true; + (void)devif_timer(&priv->pd_dev, pic32mz_txpoll); + + /* Free any buffer left attached after the poll */ + + if (priv->pd_dev.d_buf != NULL) + { + pic32mz_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + priv->pd_polling = false; + } + } +} + +/**************************************************************************** + * Function: pic32mz_response + * + * Description: + * While processing an RxDone event, higher logic decides to send a packet, + * possibly a response to the incoming packet (but probably not, in reality). + * However, since the Rx and Tx operations are decoupled, there is no + * guarantee that there will be a Tx descriptor available at that time. + * This function will perform that check and, if no Tx descriptor is + * available, this function will (1) stop incoming Rx processing (bad), and + * (2) hold the outgoing packet in a pending state until the next Tx + * interrupt occurs. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mz_response(struct pic32mz_driver_s *priv) +{ + struct pic32mz_txdesc_s *txdesc; + + /* Check if the next TX descriptor is available. */ + + txdesc = pic32mz_txdesc(priv); + if (txdesc != NULL) + { + /* Yes.. queue the packet now. */ + + pic32mz_transmit(priv); + } + else + { + /* No.. mark the Tx as pending and halt further Rx interrupts */ + + DEBUGASSERT((priv->pd_inten & ETH_INT_TXDONE) != 0); + + priv->pd_txpending = true; + priv->pd_inten &= ~ETH_RXINTS; + pic32mz_putreg(priv->pd_inten, PIC32MZ_ETH_IEN); + } +} + +/**************************************************************************** + * Function: pic32mz_rxdone + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mz_rxdone(struct pic32mz_driver_s *priv) +{ + struct pic32mz_rxdesc_s *rxdesc; + + /* Loop while there are incoming packets to be processed, that is, while + * the producer index is not equal to the consumer index. + */ + + for (; ; ) + { + /* Check if any RX descriptor has the EOWN bit cleared meaning that the + * this descriptor is now under software control and a message was + * received. + */ + + rxdesc = pic32mz_rxdesc(priv); + if (rxdesc == NULL) + { + /* All RX descriptors are owned by the Ethernet controller... we + * are finished here. + */ + + return; + } + pic32mz_dumprxdesc(rxdesc, "RX Complete"); + + /* Update statistics */ + + NETDEV_RXPACKETS(&priv->pd_dev); + + /* Get the packet length */ + + priv->pd_dev.d_len = (rxdesc->rsv2 & RXDESC_RSV2_BYTECOUNT_MASK) >> RXDESC_RSV2_BYTECOUNT_SHIFT; + + /* Check for errors */ + + if ((rxdesc->rsv2 & RXDESC_RSV2_OK) == 0) + { + nlldbg("ERROR. rsv1: %08x rsv2: %08x\n", rxdesc->rsv1, rxdesc->rsv2); + NETDEV_RXERRORS(&priv->pd_dev); + pic32mz_rxreturn(rxdesc); + } + + /* If the packet length is greater then the buffer, then we cannot accept + * the packet. Also, since the DMA packet buffers are set up to + * be the same size as our max packet size, any fragments also + * imply that the packet is too big. + */ + + else if (priv->pd_dev.d_len > CONFIG_NET_ETH_MTU) + { + nlldbg("Too big. packet length: %d rxdesc: %08x\n", priv->pd_dev.d_len, rxdesc->status); + NETDEV_RXERRORS(&priv->pd_dev); + pic32mz_rxreturn(rxdesc); + } + + /* We don't have any logic here for reassembling packets from fragments. */ + + else if ((rxdesc->status & (RXDESC_STATUS_EOP | RXDESC_STATUS_SOP)) != + (RXDESC_STATUS_EOP | RXDESC_STATUS_SOP)) + { + nlldbg("Fragment. packet length: %d rxdesc: %08x\n", priv->pd_dev.d_len, rxdesc->status); + NETDEV_RXFRAGMENTS(&priv->pd_dev); + pic32mz_rxreturn(rxdesc); + } + else + { + uint8_t *rxbuffer; + + /* Get the Rx buffer address from the Rx descriptor */ + + priv->pd_dev.d_buf = (uint8_t *)VIRT_ADDR(rxdesc->address); + DEBUGASSERT(priv->pd_dev.d_buf != NULL); + + /* Replace the buffer in the RX descriptor with a new one */ + + rxbuffer = pic32mz_allocbuffer(priv); + DEBUGASSERT(rxbuffer != NULL); + rxdesc->address = PHYS_ADDR(rxbuffer); + + /* And give the RX descriptor back to the hardware */ + + pic32mz_rxreturn(rxdesc); + pic32mz_dumppacket("Received packet", + priv->pd_dev.d_buf, priv->pd_dev.d_len); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet + * tap. + */ + + pkt_input(&priv->pd_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->pd_dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->pd_dev); + ipv4_input(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) +#endif + { + arp_out(&priv->pd_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->pd_dev); + } +#endif + + /* And send the packet */ + + pic32mz_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->pd_dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->pd_dev.d_flags)) + { + arp_out(&priv->pd_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->pd_dev); + } +#endif + + /* And send the packet */ + + pic32mz_response(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + /* Handle the incoming ARP packet */ + + NETDEV_RXARP(&priv->pd_dev); + arp_arpin(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + pic32mz_response(priv); + } + } + else +#endif + { + /* Unrecognized... drop it. */ + + nlldbg("Unrecognized packet type dropped: %04x\n", ntohs(BUF->type)); + NETDEV_RXDROPPED(&priv->pd_dev); + } + + /* Discard any buffers still attached to the device structure */ + + priv->pd_dev.d_len = 0; + if (priv->pd_dev.d_buf) + { + pic32mz_freebuffer(priv, priv->pd_dev.d_buf); + priv->pd_dev.d_buf = NULL; + } + } + } +} + +/**************************************************************************** + * Function: pic32mz_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mz_txdone(struct pic32mz_driver_s *priv) +{ + struct pic32mz_txdesc_s *txdesc; + int i; + + /* Cancel the pending Tx timeout */ + + wd_cancel(priv->pd_txtimeout); + + /* Disable further Tx interrupts. Tx interrupts may be re-enabled again + * depending upon the result of the poll. + */ + + priv->pd_inten &= ~ETH_TXINTS; + pic32mz_putreg(priv->pd_inten, PIC32MZ_ETH_IEN); + + /* Verify that the hardware is ready to send another packet. Since a Tx + * just completed, this must be the case. + */ + + DEBUGASSERT(pic32mz_txdesc(priv) != NULL); + + /* Inspect the list of TX descriptors to see if the EOWN bit is cleared. If it + * is, this descriptor is now under software control and the message was + * transmitted. Use TSV to check for the transmission result. + */ + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + txdesc = &priv->pd_txdesc[i]; + + /* Check if software owns this descriptor */ + + if ((txdesc->status & TXDESC_STATUS_EOWN) == 0) + { + /* Yes.. Check if there is a buffer attached? */ + + if (txdesc->address != 0) + { + pic32mz_dumptxdesc(txdesc, "Freeing TX buffer"); + + /* Free the TX buffer */ + + pic32mz_freebuffer(priv, (uint8_t *)VIRT_ADDR(txdesc->address)); + txdesc->address = 0; + + /* Reset status */ + + txdesc->tsv1 = 0; + txdesc->tsv2 = 0; + txdesc->status = TXDESC_STATUS_SOWN | TXDESC_STATUS_NPV; + pic32mz_dumptxdesc(txdesc, "TX buffer freed"); + } + } + } + + /* Check if there is a pending Tx transfer that was deferred by Rx handling + * because there were no available Tx descriptors. If so, process that + * pending Tx now. + */ + + if (priv->pd_txpending) + { + /* Clear the pending condition, send the packet, and restore Rx interrupts */ + + priv->pd_txpending = false; + + pic32mz_transmit(priv); + + priv->pd_inten |= ETH_RXINTS; + pic32mz_putreg(priv->pd_inten, PIC32MZ_ETH_IEN); + } + + /* Otherwise poll uIP for new XMIT data */ + + else + { + /* Perform the uIP poll */ + + pic32mz_poll(priv); + } +} + +/**************************************************************************** + * Function: pic32mz_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mz_interrupt(int irq, void *context) +{ + register struct pic32mz_driver_s *priv; + uint32_t status; + +#if CONFIG_PIC32MZ_NINTERFACES > 1 +# error "A mechanism to associate and interface with an IRQ is needed" +#else + priv = &g_ethdrvr[0]; +#endif + + /* Get the interrupt status (zero means no interrupts pending). */ + + status = pic32mz_getreg(PIC32MZ_ETH_IRQ); + if (status != 0) + { + /* Clear all pending interrupts */ + + pic32mz_putreg(status, PIC32MZ_ETH_IRQCLR); + + /* Handle each pending interrupt **************************************/ + /* Receive Errors *****************************************************/ + /* RXOVFLW: Receive FIFO Over Flow Error. RXOVFLW is set by the RXBM + * Logic for an RX FIFO Overflow condition. It is cleared by either a + * Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXOVFLW) != 0) + { + nlldbg("RX Overrun. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* RXBUFNA: Receive Buffer Not Available Interrupt. This bit is set by + * a RX Buffer Descriptor Overrun condition. It is cleared by either a + * Reset or a CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXBUFNA) != 0) + { + nlldbg("RX buffer descriptor overrun. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* RXBUSE: Receive BVCI Bus Error Interrupt. This bit is set when the + * RX DMA encounters a BVCI Bus error during a memory access. It is + * cleared by either a Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXBUSE) != 0) + { + nlldbg("RX BVCI bus error. status: %08x\n", status); + NETDEV_RXERRORS(&priv->pd_dev); + } + + /* Receive Normal Events **********************************************/ + /* RXACT: Receive Activity Interrupt. This bit is set whenever RX packet + * data is stored in the RXBM FIFO. It is cleared by either a Reset or CPU + * write of a ‘1’ to the CLR register. + */ + + /* PKTPEND: Packet Pending Interrupt. This bit is set when the BUFCNT + * counter has a value other than ‘0’. It is cleared by either a Reset + * or by writing the BUFCDEC bit to decrement the BUFCNT counter. + * Writing a ‘0’ or a ‘1’ has no effect. + */ + + /* RXDONE: Receive Done Interrupt. This bit is set whenever an RX packet + * is successfully received. It is cleared by either a Reset or CPU + * write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_RXDONE) != 0) + { + /* We have received at least one new incoming packet. */ + + pic32mz_rxdone(priv); + } + + /* Transmit Errors ****************************************************/ + /* TXABORT: Transmit Abort Condition Interrupt. This bit is set when + * the MAC aborts the transmission of a TX packet for one of the + * following reasons: + * - Jumbo TX packet abort + * - Underrun abort + * - Excessive defer abort + * - Late collision abort + * - Excessive collisions abort + * This bit is cleared by either a Reset or CPU write of a ‘1’ to the + * CLR register. + */ + + if ((status & ETH_INT_TXABORT) != 0) + { + nlldbg("TX abort. status: %08x\n", status); + NETDEV_TXERRORS(&priv->pd_dev); + } + + /* TXBUSE: Transmit BVCI Bus Error Interrupt. This bit is set when the + * TX DMA encounters a BVCI Bus error during a memory access. It is + * cleared by either a Reset or CPU write of a ‘1’ to the CLR register. + */ + + if ((status & ETH_INT_TXBUSE) != 0) + { + nlldbg("TX BVCI bus error. status: %08x\n", status); + NETDEV_TXERRORS(&priv->pd_dev); + } + + /* TXDONE: Transmit Done Interrupt. This bit is set when the currently + * transmitted TX packet completes transmission, and the Transmit + * Status Vector is loaded into the first descriptor used for the + * packet. It is cleared by either a Reset or CPU write of a ‘1’ to + * the CLR register. + */ + + if ((status & ETH_INT_TXDONE) != 0) + { + NETDEV_TXDONE(&priv->pd_dev); + + /* A packet transmission just completed */ + + pic32mz_txdone(priv); + } + + /* Watermark Events ***************************************************/ + /* EWMARK: Empty Watermark Interrupt. This bit is set when the RX + * Descriptor Buffer Count is less than or equal to the value in the + * RXEWM bit (ETHRXWM:0-7) value. It is cleared by BUFCNT bit + * (ETHSTAT:16-23) being incremented by hardware. Writing a ‘0’ or a ‘1’ + * has no effect. + */ + + /* FWMARK: Full Watermark Interrupt. This bit is set when the RX + * escriptor Buffer Count is greater than or equal to the value in the + * RXFWM bit (ETHRXWM:16-23) field. It is cleared by writing the BUFCDEC + * (ETHCON1:0) bit to decrement the BUFCNT counter. Writing a ‘0’ or a + * ‘1’ has no effect. + */ + + } + + /* Clear the pending interrupt */ + +# if CONFIG_PIC32MZ_NINTERFACES > 1 + up_clrpend_irq(priv->pd_irqsrc); +# else + up_clrpend_irq(PIC32MZ_IRQ_ETH); +# endif + + return OK; +} + +/**************************************************************************** + * Function: pic32mz_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mz_txtimeout(int argc, uint32_t arg, ...) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg; + + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(&priv->pd_dev); + if (priv->pd_ifup) + { + /* Then reset the hardware. ifup() will reset the interface, then bring + * it back up. + */ + + (void)pic32mz_ifup(&priv->pd_dev); + + /* Then poll uIP for new XMIT data (We are guaranteed to have a free + * buffer here). + */ + + pic32mz_poll(priv); + } +} + +/**************************************************************************** + * Function: pic32mz_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mz_polltimer(int argc, uint32_t arg, ...) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg; + + /* Check if the next Tx descriptor is available. We cannot perform the Tx + * poll if we are unable to accept another packet for transmission. + */ + + if (pic32mz_txdesc(priv) != NULL) + { + /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. + * might be bug here. Does this mean if there is a transmit in progress, + * we will missing TCP time state updates? + */ + + pic32mz_timerpoll(priv); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: pic32mz_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mz_ifup(struct net_driver_s *dev) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + uint32_t regval; + int ret; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Reset the Ethernet controller (again) */ + + pic32mz_ethreset(priv); + + /* MAC Initialization *****************************************************/ + /* Configuration: + * - Use the configuration fuse setting FETHIO bit (DEVCFG3:25) to detect + * the alternate/default I/O configuration + * - Use the configuration fuse setting FMIIEN (DEVCFG3:24) to detect the + * MII/RMII operation mode. + */ + + /* Pin Configuration: + * + * No GPIO pin configuration is required. Enabling the Ethernet Controller + * will configure the I/O pin direction as defined by the Ethernet Controller + * control bits. The port TRIS and LATCH registers will be overridden. + * + * I/O Pin MII RMII Pin Description + * Name Required Required Type + * EMDC Yes Yes O Ethernet MII Management Clock + * EMDIO Yes Yes I/O Ethernet MII Management IO + * ETXCLK Yes No I Ethernet MII TX Clock + * ETXEN Yes Yes O Ethernet Transmit Enable + * ETXD0 Yes Yes O Ethernet Data Transmit 0 + * ETXD1 Yes Yes O Ethernet Data Transmit 1 + * ETXD2 Yes No O Ethernet Data Transmit 2 + * ETXD3 Yes No O Ethernet Data Transmit 3 + * ETXERR Yes No O Ethernet Transmit Error + * ERXCLK Yes No I Ethernet MII RX Clock + * EREF_CLK No Yes I Ethernet RMII Ref Clock + * ERXDV Yes No I Ethernet MII Receive Data Valid + * ECRS_DV No Yes I Ethernet RMII Carrier Sense/Receive Data Valid + * ERXD0 Yes Yes I Ethernet Data Receive 0 + * ERXD1 Yes Yes I Ethernet Data Receive 1 + * ERXD2 Yes No I Ethernet Data Receive 2 + * ERXD3 Yes No I Ethernet Data Receive 3 + * ERXERR Yes Yes I Ethernet Receive Error + * ECRS Yes No I Ethernet Carrier Sense + * ECOL Yes No I Ethernet Collision Detected + * + * All that is required is to assure that the pins are initialized as + * digital (normally only those pins that have shared analog functionality + * need to be configured). + */ + + /* Initialize the MIIM interface + * + * If the RMII operation is selected, reset the RMII module by using the + * RESETRMII (EMAC1SUPP:11) bit and set the proper speed in the SPEEDRMII + * bit (EMAC1SUPP:8) bit. + */ + +#if CONFIG_PIC32MZ_FMIIEN == 0 + pic32mz_putreg(EMAC1_SUPP_RESETRMII, PIC32MZ_EMAC1_SUPPSET); + pic32mz_putreg((EMAC1_SUPP_RESETRMII | EMAC1_SUPP_SPEEDRMII), PIC32MZ_EMAC1_SUPPCLR); +#endif + + /* Issue an MIIM block reset, by setting the RESETMGMT (EMAC1MCFG:15) bit, + * and then clear the reset bit. + */ + + regval = pic32mz_getreg(PIC32MZ_EMAC1_MCFG); + pic32mz_putreg(EMAC1_MCFG_MGMTRST, PIC32MZ_EMAC1_MCFGSET); + + regval &= ~EMAC1_MCFG_MGMTRST; + pic32mz_putreg(regval, PIC32MZ_EMAC1_MCFG); + + /* Select a proper divider in the CLKSEL bit (EMAC1CFG:2-5) for the MIIM + * PHY communication based on the system running clock frequency and the + * external PHY supported clock. + * + * MII configuration: host clocked divider per board.h, no suppress + * preamble, no scan increment. + */ + + regval &= ~(EMAC1_MCFG_CLKSEL_MASK | EMAC1_MCFG_NOPRE | EMAC1_MCFG_SCANINC); + regval |= EMAC1_MCFG_CLKSEL_DIV; + pic32mz_putreg(regval, PIC32MZ_EMAC1_MCFG); + + /* PHY Initialization *****************************************************/ + /* Initialize the PHY and wait for the link to be established */ + + ret = pic32mz_phyinit(priv); + if (ret != 0) + { + ndbg("pic32mz_phyinit failed: %d\n", ret); + return ret; + } + + /* MAC Configuration ******************************************************/ + /* Set other misc configuration-related registers to default values */ + + pic32mz_putreg(0, PIC32MZ_EMAC1_CFG2); + pic32mz_putreg(0, PIC32MZ_EMAC1_TEST); + + /* Having available the Duplex and Speed settings, configure the MAC + * accordingly, using the following steps: + * + * Enable the RXENABLE bit (EMAC1CFG1:0), selecting both the TXPAUSE and + * RXPAUSE bit (EMAC1CFG1:2-3) (the PIC32 MAC supports both). + */ + + pic32mz_putreg(EMAC1_CFG1_RXEN | EMAC1_CFG1_RXPAUSE | EMAC1_CFG1_TXPAUSE, + PIC32MZ_EMAC1_CFG1SET); + + /* Select the desired auto-padding and CRC capabilities, and the enabling + * of the huge frames and the Duplex type in the EMAC1CFG2 register. + * (This was done in the PHY initialization logic). + */ + + /* Program EMAC1IPGT with the back-to-back inter-packet gap */ + /* Use EMAC1IPGR for setting the non back-to-back inter-packet gap */ + + pic32mz_putreg(((12 << EMAC1_IPGR_GAP1_SHIFT) | (12 << EMAC1_IPGR_GAP2_SHIFT)), + PIC32MZ_EMAC1_IPGR); + + /* Set the collision window and the maximum number of retransmissions in + * EMAC1CLRT. + */ + + pic32mz_putreg(((15 << EMAC1_CLRT_RETX_SHIFT) | (55 << EMAC1_CLRT_CWINDOW_SHIFT)), + PIC32MZ_EMAC1_CLRT); + + /* Set the maximum frame length in EMAC1MAXF. "This field resets to + * 0x05EE, which represents a maximum receive frame of 1518 octets. An + * untagged maximum size Ethernet frame is 1518 octets. A tagged frame adds + * four octets for a total of 1522 octets. If a shorter/longer maximum + * length restriction is desired, program this 16-bit field. + */ + + pic32mz_putreg(CONFIG_NET_ETH_MTU, PIC32MZ_EMAC1_MAXF); + + /* Configure the MAC station address in the EMAC1SA0, EMAC1SA1 and + * EMAC1SA2 registers (these registers are loaded at reset from the + * factory preprogrammed station address). + */ + +#if 0 + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[5] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[4]; + pic32mz_putreg(regval, PIC32MZ_EMAC1_SA0); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[3] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[2]; + pic32mz_putreg(regval, PIC32MZ_EMAC1_SA1); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[1] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[0]; + pic32mz_putreg(regval, PIC32MZ_EMAC1_SA2); +#else + regval = pic32mz_getreg(PIC32MZ_EMAC1_SA0); + priv->pd_dev.d_mac.ether_addr_octet[4] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[5] = (uint32_t)((regval >> 8) & 0xff); + + regval = pic32mz_getreg(PIC32MZ_EMAC1_SA1); + priv->pd_dev.d_mac.ether_addr_octet[2] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[3] = (uint32_t)((regval >> 8) & 0xff); + + regval = pic32mz_getreg(PIC32MZ_EMAC1_SA2); + priv->pd_dev.d_mac.ether_addr_octet[0] = (uint32_t)(regval & 0xff); + priv->pd_dev.d_mac.ether_addr_octet[1] = (uint32_t)((regval >> 8) & 0xff); + + ndbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + +#endif + + /* Continue Ethernet Controller Initialization ****************************/ + /* If planning to turn on the flow control, update the PTV value + * (ETHCON1:16-31). + */ + + /* If using the auto-flow control, set the full and empty watermarks: RXFWM + * and RXEWM (ETHRXWM:16-23 and ETHRXWM:0-7). + */ + + /* If needed, enable the auto-flow control by setting AUTOFC (ETHCON1:7). */ + + /* Set the RX filters by updating the ETHHT0, ETHHT1, ETHPMM0, ETHPMM1, + * ETHPMCS and ETHRXFC registers. + * + * Set up RX filter and configure to accept broadcast addresses and multicast + * addresses (if so configured). NOTE: There is a selection + * CONFIG_NET_BROADCAST, but this enables receipt of UDP broadcast packets + * inside of the stack. + */ + + regval = ETH_RXFC_BCEN | ETH_RXFC_UCEN | ETH_RXFC_PMMODE_DISABLED; +#ifdef CONFIG_PIC32MZ_MULTICAST + regval |= ETH_RXFC_MCEN; +#endif + pic32mz_putreg(regval, PIC32MZ_ETH_RXFC); + + /* Set the size of the RX buffers in the RXBUFSZ bit (ETHCON2:4-10) (all + * receive descriptors use the same buffer size). Keep in mind that using + * packets that are too small leads to packet fragmentation and has a + * noticeable impact on the performance. + */ + + pic32mz_putreg(ETH_CON2_RXBUFSZ(CONFIG_NET_ETH_MTU), PIC32MZ_ETH_CON2); + + /* Reset state varialbes */ + + priv->pd_polling = false; + priv->pd_txpending = false; + + /* Initialize the buffer list */ + + pic32mz_bufferinit(priv); + + /* Initialize the TX descriptor list */ + + pic32mz_txdescinit(priv); + + /* Initialize the RX descriptor list */ + + pic32mz_rxdescinit(priv); + + /* Enable the Ethernet Controller by setting the ON bit (ETHCON1:15). + * Enable the receiving of messages by setting the RXEN bit (ETHCON1:8). + */ + + pic32mz_putreg(ETH_CON1_RXEN | ETH_CON1_ON, PIC32MZ_ETH_CON1SET); + + /* Initialize Ethernet interface for the PHY setup */ + + pic32mz_macmode(priv->pd_mode); + + /* Configure to pass all received frames */ + + regval = pic32mz_getreg(PIC32MZ_EMAC1_CFG1); + regval |= EMAC1_CFG1_PASSALL; + pic32mz_putreg(regval, PIC32MZ_EMAC1_CFG1); + + /* Clear any pending interrupts (shouldn't be any) */ + + pic32mz_putreg(0xffffffff, PIC32MZ_ETH_IRQCLR); + + /* Configure interrupts. The Ethernet interrupt was attached during one-time + * initialization, so we only need to set the interrupt priority, configure + * interrupts, and enable them. + */ + + /* If the user provided an interrupt priority, then set the interrupt to that + * priority + */ + +#if defined(CONFIG_NET_PRIORITY) && defined(CONFIG_ARCH_IRQPRIO) +#if CONFIG_PIC32MZ_NINTERFACES > 1 + (void)up_prioritize_irq(priv->pd_irq, CONFIG_NET_PRIORITY); +#else + (void)up_prioritize_irq(PIC32MZ_IRQ_ETH, CONFIG_NET_PRIORITY); +#endif +#endif + + /* Otherwise, enable all Rx interrupts. Tx interrupts, SOFTINT and WoL are + * excluded. Tx interrupts will not be enabled until there is data to be + * sent. + */ + + priv->pd_inten = ETH_RXINTS; + pic32mz_putreg(ETH_RXINTS, PIC32MZ_ETH_IENSET); + + /* Set and activate a timer process */ + + (void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_polltimer, 1, + (uint32_t)priv); + + /* Finally, enable the Ethernet interrupt at the interrupt controller */ + + priv->pd_ifup = true; +#if CONFIG_PIC32MZ_NINTERFACES > 1 + up_enable_irq(priv->pd_irqsrc); +#else + up_enable_irq(PIC32MZ_IRQ_ETH); +#endif + return OK; +} + +/**************************************************************************** + * Function: pic32mz_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mz_ifdown(struct net_driver_s *dev) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); +#if CONFIG_PIC32MZ_NINTERFACES > 1 + up_disable_irq(priv->pd_irqsrc); +#else + up_disable_irq(PIC32MZ_IRQ_ETH); +#endif + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->pd_txpoll); + wd_cancel(priv->pd_txtimeout); + + /* Reset the device and mark it as down. */ + + pic32mz_ethreset(priv); + priv->pd_ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mz_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int pic32mz_txavail(struct net_driver_s *dev) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->pd_ifup) + { + /* Check if the next Tx descriptor is available. */ + + if (pic32mz_txdesc(priv) != NULL) + { + /* If so, then poll uIP for new XMIT data. First allocate a buffer + * to perform the poll + */ + + pic32mz_poll(priv); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mz_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mz_addmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mz_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mz_rmmac(struct net_driver_s *dev, const uint8_t *mac) +{ + struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Name: pic32mz_showmii + * + * Description: + * Dump PHY MII registers + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(PIC32MZ_HAVE_PHY) +static void pic32mz_showmii(uint8_t phyaddr, const char *msg) +{ + dbg("PHY " PIC32MZ_PHYNAME ": %s\n", msg); + dbg(" MCR: %04x\n", pic32mz_phyread(phyaddr, MII_MCR)); + dbg(" MSR: %04x\n", pic32mz_phyread(phyaddr, MII_MSR)); + dbg(" ADVERTISE: %04x\n", pic32mz_phyread(phyaddr, MII_ADVERTISE)); + dbg(" LPA: %04x\n", pic32mz_phyread(phyaddr, MII_LPA)); + dbg(" EXPANSION: %04x\n", pic32mz_phyread(phyaddr, MII_EXPANSION)); +#ifdef CONFIG_ETH0_PHY_KS8721 + dbg(" 10BTCR: %04x\n", pic32mz_phyread(phyaddr, MII_KS8721_10BTCR)); +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mz_phybusywait + * + * Description: + * Wait until the PHY is no longer busy + * + * Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void pic32mz_phybusywait(void) +{ + while ((pic32mz_getreg(PIC32MZ_EMAC1_MIND) & EMAC1_MIND_MIIMBUSY) != 0); +} + +/**************************************************************************** + * Function: pic32mz_phywrite + * + * Description: + * Write a value to an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * phydata - The data to write to the PHY register + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static void pic32mz_phywrite(uint8_t phyaddr, uint8_t regaddr, uint16_t phydata) +{ + uint32_t regval; + + /* Make sure that the PHY is not still busy from the last command */ + + pic32mz_phybusywait(); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mz_putreg(regval, PIC32MZ_EMAC1_MADR); + + /* Write the register data to the PHY */ + + pic32mz_putreg((uint32_t)phydata, PIC32MZ_EMAC1_MWTD); + + /* Two clock cycles until busy is set from the write operation */ + + __asm__ __volatile__ ("nop; nop;"); +} +#endif + +/**************************************************************************** + * Function: pic32mz_phyread + * + * Description: + * Read a value from an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * + * Returned Value: + * Data read from the PHY register + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static uint16_t pic32mz_phyread(uint8_t phyaddr, uint8_t regaddr) +{ + uint32_t regval; + + /* Make sure that the PHY is not still busy from the last command */ + + pic32mz_phybusywait(); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mz_putreg(regval, PIC32MZ_EMAC1_MADR); + + /* Set up to read */ + + pic32mz_putreg(EMAC1_MCMD_READ, PIC32MZ_EMAC1_MCMD); + + /* Four clock cycles until busy is set from the write operation */ + + __asm__ __volatile__ ("nop; nop; nop; nop;"); + + /* Wait for the PHY command to complete */ + + pic32mz_phybusywait(); + pic32mz_putreg(0, PIC32MZ_EMAC1_MCMD); + + /* Return the PHY register data */ + + return (uint16_t)(pic32mz_getreg(PIC32MZ_EMAC1_MRDD) & EMAC1_MRDD_MASK); +} +#endif + +/**************************************************************************** + * Function: pic32mz_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static inline int pic32mz_phyreset(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Reset the PHY. Needs a minimal 50uS delay after reset. */ + + pic32mz_phywrite(phyaddr, MII_MCR, MII_MCR_RESET); + + /* Wait for a minimum of 50uS no matter what */ + + up_udelay(50); + + /* The MCR reset bit is self-clearing. Wait for it to be clear indicating + * that the reset is complete. + */ + + for (timeout = PIC32MZ_MIITIMEOUT; timeout > 0; timeout--) + { + phyreg = pic32mz_phyread(phyaddr, MII_MCR); + if ((phyreg & MII_MCR_RESET) == 0) + { + return OK; + } + } + + ndbg("Reset failed. MCR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mz_phyautoneg + * + * Description: + * Enable auto-negotiation. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * The adverisement regiser has already been configured. + * + ****************************************************************************/ + +#if defined(PIC32MZ_HAVE_PHY) && defined(CONFIG_PHY_AUTONEG) +static inline int pic32mz_phyautoneg(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Start auto-negotiation */ + + pic32mz_phywrite(phyaddr, MII_MCR, MII_MCR_ANENABLE | MII_MCR_ANRESTART); + + /* Wait for autonegotiation to complete */ + + for (timeout = PIC32MZ_MIITIMEOUT; timeout > 0; timeout--) + { + /* Check if auto-negotiation has completed */ + + phyreg = pic32mz_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. return success */ + + return OK; + } + } + + ndbg("Auto-negotiation failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mz_phymode + * + * Description: + * Set the PHY to operate at a selected speed/duplex mode. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static int pic32mz_phymode(uint8_t phyaddr, uint8_t mode) +{ + int32_t timeout; + uint16_t phyreg; + + /* Disable auto-negotiation and set fixed Speed and Duplex settings: + * + * MII_MCR_UNIDIR 0=Disable unidirectional enable + * MII_MCR_SPEED1000 0=Reserved on 10/100 + * MII_MCR_CTST 0=Disable collision test + * MII_MCR_FULLDPLX ?=Full duplex + * MII_MCR_ANRESTART 0=Don't restart auto negotiation + * MII_MCR_ISOLATE 0=Don't electronically isolate PHY from MII + * MII_MCR_PDOWN 0=Don't powerdown the PHY + * MII_MCR_ANENABLE 0=Disable auto negotiation + * MII_MCR_SPEED100 ?=Select 100Mbps + * MII_MCR_LOOPBACK 0=Disable loopback mode + * MII_MCR_RESET 0=No PHY reset + */ + + phyreg = 0; + if ((mode & PIC32MZ_SPEED_MASK) == PIC32MZ_SPEED_100) + { + phyreg = MII_MCR_SPEED100; + } + + if ((mode & PIC32MZ_DUPLEX_MASK) == PIC32MZ_DUPLEX_FULL) + { + phyreg |= MII_MCR_FULLDPLX; + } + + pic32mz_phywrite(phyaddr, MII_MCR, phyreg); + + /* Then wait for the link to be established */ + + for (timeout = PIC32MZ_MIITIMEOUT; timeout > 0; timeout--) + { +#ifdef CONFIG_ETH0_PHY_DP83848C + phyreg = pic32mz_phyread(phyaddr, MII_DP83848C_STS); + if ((phyreg & 0x0001) != 0) + { + /* Yes.. return success */ + + return OK; + } +#else + phyreg = pic32mz_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_LINKSTATUS) != 0) + { + /* Yes.. return success */ + + return OK; + } +#endif + } + + ndbg("Link failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mz_phyinit + * + * Description: + * Initialize the PHY + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directly. As a side-effect, it will initialize priv->pd_phyaddr + * and priv->pd_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv) +{ + unsigned int phyaddr; + uint16_t phyreg; + uint32_t regval; + int ret; + +#if CONFIG_PIC32MZ_FMIIEN == 0 + /* Set the RMII operation mode. This usually requires access to a vendor + * specific control register. + */ + +#ifdef CONFIG_ETH0_PHY_DP83848C + /* The RMII/MII of operation can be selected by strap options or register + * control (using the RBR register). For RMII mode, it is required to use the + * strap option, since it requires a 50 MHz clock instead of the normal 25 MHz. + */ +#endif + +#else + /* Set the MII/ operation mode. This usually requires access to a vendor- + * specific control register. + */ + +#ifdef CONFIG_ETH0_PHY_DP83848C +# warning "Missing logic" +#endif + +#endif + + /* Find PHY Address. Because the controller has a pull-up and the + * PHY has pull-down resistors on RXD lines some times the PHY + * latches different at different addresses. + */ + + for (phyaddr = 0; phyaddr < 32; phyaddr++) + { + /* Clear any ongoing PHY command bits */ + + pic32mz_putreg(0, PIC32MZ_EMAC1_MCMD); + + /* Reset the PHY (use Control Register 0). */ + + ret = pic32mz_phyreset(phyaddr); + if (ret < 0) + { + ndbg("Failed to reset PHY at address %d\n", phyaddr); + continue; + } + + /* Set the normal, swapped or auto (preferred) MDIX. This usually + * requires access to a vendor-specific control register. + */ + + /* Check if we can see the selected device ID at this + * PHY address. + */ + + phyreg = (unsigned int)pic32mz_phyread(phyaddr, MII_PHYID1); + nvdbg("Addr: %d PHY ID1: %04x EXPECT: %04x\n", phyaddr, phyreg, PIC32MZ_PHYID1); + + if (phyreg == PIC32MZ_PHYID1) + { + phyreg = pic32mz_phyread(phyaddr, MII_PHYID2); + nvdbg("Addr: %d PHY ID2: %04x EXPECT: %04x\n", phyaddr, phyreg, PIC32MZ_PHYID2); + + if (phyreg == PIC32MZ_PHYID2) + { + break; + } + } + } + + /* Check if the PHY device address was found */ + + if (phyaddr > 31) + { + /* Failed to find PHY at any location */ + + ndbg("No PHY detected\n"); + return -ENODEV; + } + nvdbg("phyaddr: %d\n", phyaddr); + + /* Save the discovered PHY device address */ + + priv->pd_phyaddr = phyaddr; + + /* Reset the PHY */ + + ret = pic32mz_phyreset(phyaddr); + if (ret < 0) + { + return ret; + } + pic32mz_showmii(phyaddr, "After reset"); + + /* Set the MII/RMII operation mode. This usually requires access to a + * vendor-specific control register. + */ + + /* Set the normal, swapped or auto (preferred) MDIX. This usually requires + * access to a vendor-specific control register. + */ + + /* Check the PHY capabilities by investigating the Status Register 1. */ + + /* Check for preamble suppression support */ + + phyreg = pic32mz_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_MFRAMESUPPRESS) != 0) + { + /* The PHY supports preamble suppression */ + + regval = pic32mz_getreg(PIC32MZ_EMAC1_MCFG); + regval |= EMAC1_MCFG_NOPRE; + pic32mz_putreg(regval, PIC32MZ_EMAC1_MCFG); + } + + /* Are we configured to do auto-negotiation? + * + * Preferably the auto-negotiation should be selected if the PHY supports + * it. Expose the supported capabilities: Half/Full Duplex, 10BaseT/100Base + * TX, etc. (Extended Register 4). Start the negotiation (Control Register + * 0) and wait for the negotiation complete and get the link partner + * capabilities (Extended Register 5) and negotiation result (vendor- + * specific register). + */ + +#ifdef CONFIG_PHY_AUTONEG + /* Setup the Auto-negotiation advertisement: 100 or 10, and HD or FD */ + + pic32mz_phywrite(phyaddr, MII_ADVERTISE, + (MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_CSMA)); + + /* Then perform the auto-negotiation */ + + ret = pic32mz_phyautoneg(phyaddr); + if (ret < 0) + { + return ret; + } +#else + /* Set up the fixed PHY configuration + * + * If auto-negotiation is not supported/selected, update the PHY Duplex and + * Speed settings directly (use Control Register 0 and possibly some vendor- + * pecific registers). + */ + + ret = pic32mz_phymode(phyaddr, PIC32MZ_MODE_DEFLT); + if (ret < 0) + { + return ret; + } +#endif + + /* The link is established */ + + pic32mz_showmii(phyaddr, "After link established"); + + /* Check configuration */ + +#if defined(CONFIG_ETH0_PHY_KS8721) + phyreg = pic32mz_phyread(phyaddr, MII_KS8721_10BTCR); + + switch (phyreg & KS8721_10BTCR_MODE_MASK) + { + case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */ + priv->pd_mode = PIC32MZ_10BASET_HD; + break; + case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */ + priv->pd_mode = PIC32MZ_100BASET_HD; + break; + case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */ + priv->pd_mode = PIC32MZ_10BASET_FD; + break; + case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */ + priv->pd_mode = PIC32MZ_100BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_ETH0_PHY_DP83848C) + phyreg = pic32mz_phyread(phyaddr, MII_DP83848C_STS); + + /* Configure for full/half duplex mode and speed */ + + switch (phyreg & 0x0006) + { + case 0x0000: + priv->pd_mode = PIC32MZ_100BASET_HD; + break; + case 0x0002: + priv->pd_mode = PIC32MZ_10BASET_HD; + break; + case 0x0004: + priv->pd_mode = PIC32MZ_100BASET_FD; + break; + case 0x0006: + priv->pd_mode = PIC32MZ_10BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_ETH0_PHY_LAN8720) || defined(CONFIG_ETH0_PHY_LAN8740) || defined(CONFIG_ETH0_PHY_LAN8740A) + { + uint16_t advertise; + uint16_t lpa; + + up_udelay(500); + advertise = pic32mz_phyread(phyaddr, MII_ADVERTISE); + lpa = pic32mz_phyread(phyaddr, MII_LPA); + + /* Check for 100BASETX full duplex */ + + if ((advertise & MII_ADVERTISE_100BASETXFULL) != 0 && + (lpa & MII_LPA_100BASETXFULL) != 0) + { + priv->pd_mode = PIC32MZ_100BASET_FD; + } + + /* Check for 100BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_100BASETXHALF) != 0 && + (lpa & MII_LPA_100BASETXHALF) != 0) + { + priv->pd_mode = PIC32MZ_100BASET_HD; + } + + /* Check for 10BASETX full duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXFULL) != 0 && + (lpa & MII_LPA_10BASETXFULL) != 0) + { + priv->pd_mode = PIC32MZ_10BASET_FD; + } + + /* Check for 10BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXHALF) != 0 && + (lpa & MII_LPA_10BASETXHALF) != 0) + { + priv->pd_mode = PIC32MZ_10BASET_HD; + } + else + { + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + } +#else +# warning "PHY Unknown: speed and duplex are bogus" +#endif + + ndbg("%dBase-T %s duplex\n", + (priv->pd_mode & PIC32MZ_SPEED_MASK) == PIC32MZ_SPEED_100 ? 100 : 10, + (priv->pd_mode & PIC32MZ_DUPLEX_MASK) == PIC32MZ_DUPLEX_FULL ?"full" : "half"); + + /* Disable auto-configuration. Set the fixed speed/duplex mode. + * (probably more than little redundant). + */ + + ret = pic32mz_phymode(phyaddr, priv->pd_mode); + pic32mz_showmii(phyaddr, "After final configuration"); + return ret; +} +#else +static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv) +{ + priv->pd_mode = PIC32MZ_MODE_DEFLT; + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mz_macmode + * + * Description: + * Set the MAC to operate at a selected speed/duplex mode. + * + * Parameters: + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MZ_HAVE_PHY +static void pic32mz_macmode(uint8_t mode) +{ + /* Set up for full or half duplex operation */ + + if ((mode & PIC32MZ_DUPLEX_MASK) == PIC32MZ_DUPLEX_FULL) + { + /* Set the back-to-back inter-packet gap */ + + pic32mz_putreg(21, PIC32MZ_EMAC1_IPGT); + + /* Set MAC to operate in full duplex mode with CRC and Pad enabled */ + + pic32mz_putreg((EMAC1_CFG2_FULLDPLX | EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN), + PIC32MZ_EMAC1_CFG2SET); + } + else + { + /* Set the back-to-back inter-packet gap */ + + pic32mz_putreg(18, PIC32MZ_EMAC1_IPGT); + + /* Set MAC to operate in half duplex mode with CRC and Pad enabled */ + + pic32mz_putreg(EMAC1_CFG2_FULLDPLX, PIC32MZ_EMAC1_CFG2CLR); + pic32mz_putreg((EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN), PIC32MZ_EMAC1_CFG2SET); + } + + /* Set the RMII MAC speed. */ + +#if CONFIG_PIC32MZ_FMIIEN == 0 + if ((mode & PIC32MZ_SPEED_MASK) == PIC32MZ_SPEED_100) + { + pic32mz_putreg(EMAC1_SUPP_SPEEDRMII, PIC32MZ_EMAC1_SUPPSET); + } + else + { + pic32mz_putreg(EMAC1_SUPP_SPEEDRMII, PIC32MZ_EMAC1_SUPPCLR); + } +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mz_ethreset + * + * Description: + * Configure and reset the Ethernet module, leaving it in a disabled state. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static void pic32mz_ethreset(struct pic32mz_driver_s *priv) +{ + irqstate_t flags; + + /* Reset the MAC */ + + flags = enter_critical_section(); + + /* Ethernet Controller Initialization *************************************/ + /* Disable Ethernet interrupts in the EVIC */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 + up_disable_irq(priv->pd_irqsrc); +#else + up_disable_irq(PIC32MZ_IRQ_ETH); +#endif + + /* Turn the Ethernet Controller off: Clear the ON, RXEN and TXRTS bits */ + + pic32mz_putreg(ETH_CON1_RXEN | ETH_CON1_TXRTS | ETH_CON1_ON, PIC32MZ_ETH_CON1CLR); + + /* Wait activity abort by polling the ETHBUSY bit */ + + while ((pic32mz_getreg(PIC32MZ_ETH_STAT) & ETH_STAT_ETHBUSY) != 0) + continue; + + /* Turn the Ethernet controller on. */ + + pic32mz_putreg(ETH_CON1_ON, PIC32MZ_ETH_CON1SET); + + /* Clear the Ethernet STAT BUFCNT */ + + while ((pic32mz_getreg(PIC32MZ_ETH_STAT) & ETH_STAT_BUFCNT_MASK) != 0) + { + pic32mz_putreg(ETH_CON1_BUFCDEC, PIC32MZ_ETH_CON1SET); + } + + /* Clear the Ethernet Interrupt Flag (ETHIF) bit in the Interrupts module */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 + up_pending_irq(priv->pd_irqsrc); +#else + up_pending_irq(PIC32MZ_IRQ_ETH); +#endif + + /* Disable any Ethernet Controller interrupt generation by clearing the IEN + * register. + */ + + pic32mz_putreg(ETH_INT_ALLINTS, PIC32MZ_ETH_IENCLR); + + /* Clear the TX and RX start addresses by using ETHTXSTCLR and ETHRXSTCLR */ + + pic32mz_putreg(0xffffffff, PIC32MZ_ETH_TXSTCLR); + pic32mz_putreg(0xffffffff, PIC32MZ_ETH_RXSTCLR); + + /* MAC Initialization *****************************************************/ + /* Put the MAC into the reset state */ + + pic32mz_putreg((EMAC1_CFG1_TXRST | EMAC1_CFG1_MCSTXRST | EMAC1_CFG1_RXRST | + EMAC1_CFG1_MCSRXRST | EMAC1_CFG1_SIMRST | EMAC1_CFG1_SOFTRST), + PIC32MZ_EMAC1_CFG1); + + /* Take the MAC out of the reset state */ + + up_udelay(50); + pic32mz_putreg(0, PIC32MZ_EMAC1_CFG1); + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pic32mz_ethinitialize + * + * Description: + * Initialize one Ethernet controller and driver structure. + * + * Parameters: + * intf - Selects the interface to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 +int pic32mz_ethinitialize(int intf) +#else +static inline int pic32mz_ethinitialize(int intf) +#endif +{ + struct pic32mz_driver_s *priv; + int ret; + + DEBUGASSERT(intf < CONFIG_PIC32MZ_NINTERFACES); + priv = &g_ethdrvr[intf]; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct pic32mz_driver_s)); + priv->pd_dev.d_ifup = pic32mz_ifup; /* I/F down callback */ + priv->pd_dev.d_ifdown = pic32mz_ifdown; /* I/F up (new IP address) callback */ + priv->pd_dev.d_txavail = pic32mz_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->pd_dev.d_addmac = pic32mz_addmac; /* Add multicast MAC address */ + priv->pd_dev.d_rmmac = pic32mz_rmmac; /* Remove multicast MAC address */ +#endif + priv->pd_dev.d_private = (void *)priv; /* Used to recover private state from dev */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 +# error "A mechanism to associate base address an IRQ with an interface is needed" + priv->pd_base = ??; /* Ethernet controller base address */ + priv->pd_irq = ??; /* Ethernet controller IRQ vector number */ + priv->pd_irqsrc = ??; /* Ethernet controller IRQ source number */ +#endif + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->pd_txpoll = wd_create(); /* Create periodic poll timer */ + priv->pd_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Configure Ethernet peripheral pin selections */ + /* Controlled by DEVCFG FMIIEN and FETHIO settings */ + + /* Reset the Ethernet controller and leave in the ifdown state. The + * Ethernet controller will be properly re-initialized each time + * pic32mz_ifup() is called. + */ + + pic32mz_ifdown(&priv->pd_dev); + + /* Attach the IRQ to the driver */ + +#if CONFIG_PIC32MZ_NINTERFACES > 1 + ret = irq_attach(priv->pd_irq, pic32mz_interrupt); +#else + ret = irq_attach(PIC32MZ_IRQ_ETH, pic32mz_interrupt); +#endif + if (ret != 0) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->pd_dev, NET_LL_ETHERNET); + return OK; +} + +/**************************************************************************** + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one + * interface in the chip, then board-specific logic will have to provide + * this function to determine which, if any, Ethernet controllers should + * be initialized. + * + ****************************************************************************/ + +#if CONFIG_PIC32MZ_NINTERFACES == 1 +void up_netinitialize(void) +{ + (void)pic32mz_ethinitialize(0); +} +#endif +#endif /* CHIP_NETHERNET > 0 */ +#endif /* CONFIG_NET && CONFIG_PIC32MZ_ETHERNET */ diff --git a/arch/mips/src/pic32mz/pic32mz-exception.c b/arch/mips/src/pic32mz/pic32mz-exception.c new file mode 100644 index 0000000000000000000000000000000000000000..ec23ff8c3b54b9a176d44a1823e4f506a00f99c7 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-exception.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-exception.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/pic32mz-int.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: pic32mz_exception + * + * Description: + * Called from assembly language logic on all other exceptions. + * + ************************************************************************************/ + +uint32_t *pic32mz_exception(uint32_t *regs) +{ +#ifdef CONFIG_DEBUG + uint32_t cause; + uint32_t epc; +#endif + + /* If the board supports LEDs, turn on an LED now to indicate that we are + * processing an interrupt. + */ + + board_autoled_on(LED_INIRQ); + +#ifdef CONFIG_DEBUG + /* Get the cause of the exception from the CAUSE register */ + + asm volatile("\tmfc0 %0,$13,0\n" : "=r"(cause)); + asm volatile("\tmfc0 %0,$14,0\n" : "=r"(epc)); + +#ifdef CONFIG_DEBUG_VERBOSE + switch (cause & CP0_CAUSE_EXCCODE_MASK) + { + case CP0_CAUSE_EXCCODE_INT: /* Interrupt */ + llvdbg("EXCEPTION: Interrupt" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TLBL: /* TLB exception (load or instruction fetch) */ + llvdbg("EXCEPTION: TLB exception (load or instruction fetch)" + " CAUSE: %08x EPC:%08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TLBS: /* TLB exception (store) */ + llvdbg("EXCEPTION: TLB exception (store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_ADEL: /* Address error exception (load or instruction fetch) */ + llvdbg("EXCEPTION: Address error exception (load or instruction fetch)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_ADES: /* Address error exception (store) */ + llvdbg("EXCEPTION: Address error exception (store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_IBE: /* Bus error exception (instruction fetch) */ + llvdbg("EXCEPTION: Bus error exception (instruction fetch)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_DBE: /* Bus error exception (data reference: load or store) */ + llvdbg("EXCEPTION: Bus error exception (data reference: load or store)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_SYS: /* Syscall exception */ + llvdbg("EXCEPTION: Syscall exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_BP: /* Breakpoint exception */ + llvdbg("EXCEPTION: Breakpoint exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_RI: /* Reserved instruction exception */ + llvdbg("EXCEPTION: Reserved instruction exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_CPU: /* Coprocessor Unusable exception */ + llvdbg("EXCEPTION: Coprocessor Unusable exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_OV: /* Arithmetic Overflow exception */ + llvdbg("EXCEPTION: Arithmetic Overflow exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_TR: /* Trap exception */ + llvdbg("EXCEPTION: Trap exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_FPE: /* Floating point exception */ + llvdbg("EXCEPTION: Floating point exception" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_C2E: /* Precise Coprocessor 2 exceptions */ + llvdbg("EXCEPTION: Precise Coprocessor 2 exceptions" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_MDMX: /* MDMX Unusable (MIPS64) */ + llvdbg("EXCEPTION: MDMX Unusable (MIPS64)" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_WATCH: /* WatchHi/WatchLo address */ + llvdbg("EXCEPTION: WatchHi/WatchLo address" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_MCHECK: /* Machine check */ + llvdbg("EXCEPTION: Machine check" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + case CP0_CAUSE_EXCCODE_CACHEERR: /* Cache error */ + llvdbg("EXCEPTION: Cache error" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + default: + llvdbg("EXCEPTION: Unknown" + " CAUSE: %08x EPC: %08x\n", cause, epc); + break; + } +#else + lldbg("EXCEPTION: CAUSE: %08x EPC: %08x\n", cause, epc); +#endif +#endif + + /* Crash with currents_regs set so that we can dump the register contents. */ + + g_current_regs = regs; + PANIC(); + return regs; /* Won't get here */ +} diff --git a/arch/mips/src/pic32mz/pic32mz-excptmacros.h b/arch/mips/src/pic32mz/pic32mz-excptmacros.h new file mode 100644 index 0000000000000000000000000000000000000000..2ddb5b464f9450c808e3012745fe522b584fada0 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-excptmacros.h @@ -0,0 +1,449 @@ +/******************************************************************************************** + * arch/mips/src/pic32mz/pic32mz-excptmacros.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_EXCPTMACROS_H +#define __ARCH_MIPS_SRC_PIC32MZ_EXCPTMACROS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include +#include + +#ifdef __ASSEMBLY__ + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Symbols + ********************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + .global g_nestlevel +#endif +#endif + +/******************************************************************************************** + * Assembly Language Macros + ********************************************************************************************/ + +/******************************************************************************************** + * General Usage Example: + * + * my_exception: + * EXCPT_PROLOGUE t0 - Save registers on stack, enable nested interrupts + * move a0, sp - Pass register save structure as the parameter 1 + * USE_INTSTACK t0, t1, t2, t3 - Switch to the interrupt stack + * jal handler - Handle the exception IN=old regs OUT=new regs + * di - Disable interrupts + * RESTORE_STACK t0, t1 - Undo the operations of USE_STACK + * EXCPT_EPILOGUE v0 - Return to the context returned by handler() + * + ********************************************************************************************/ +/******************************************************************************************** + * Name: EXCPT_PROLOGUE + * + * Description: + * Provides the "prologue" logic that should appear at the beginning of every exception + * handler. + * + * On Entry: + * sp - Points to the top of the stack + * tmp - Is a register the can be modified for scratch usage (after it has been saved) + * k0 and k1 - Since we are in an exception handler, these are available for use + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp + * and k1: + * + * - sp points the beginning of the register save area + * - k1 holds the value of the STATUS register + * + * The following registers are modified: k0, k1, sp, a0 + * + ********************************************************************************************/ + + .macro EXCPT_PROLOGUE, tmp + .set noat + + /* Get the SP from the previous shadow set */ + +#if 0 + rdpgpr sp, sp +#endif + + /* "When entering the interrupt handler routine, the interrupt controller must first + * save the current priority and exception PC counter from Interrupt Priority (IPL) + * bits (Status<15:10>) and the ErrorEPC register, respectively, on the stack. ..." + */ + +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS // Does not work! + mfc0 k0, MIPS32_CP0_CAUSE + mfc0 k1, MIPS32_CP0_EPC + + /* Isolate the pending interrupt level in bits 0-5 of k0 */ + + srl k0, k0, CP0_CAUSE_IP_SHIFT + + /* Create the register context stack frame large enough to hold the entire register save + * array. + */ + + addiu sp, sp, -XCPTCONTEXT_SIZE + + /* Save the EPC and STATUS in the register context array */ + + sw k1, REG_EPC(sp) + mfc0 k1, MIPS32_CP0_STATUS + sw k1, REG_STATUS(sp) + + /* Then insert pending interrupt level as the current mask level in the CP0 status + * register. Also clear bits 1-4 in new value of the status register: + * + * Bit 1: Exception Level + * Bit 2: Error Level + * Bit 3: (not used in PIC32MZ) + * Bit 4: Operating mode == USER + */ + + ins k1, k0, CP0_STATUS_IPL_SHIFT, 6 + ins k1, zero, 1, 4 + + /* And Enable interrupts */ + + mtc0 k1, MIPS32_CP0_STATUS +#else + /* Get the EPC and STATUS register (Don't bother with the CAUSE register if we are + * not supporting nested interrupts) + */ + + mfc0 k0, MIPS32_CP0_EPC + mfc0 k1, MIPS32_CP0_STATUS + + /* Create the register context stack frame large enough to hold the entire register + * save array. + */ + + addiu sp, sp, -XCPTCONTEXT_SIZE + + /* Save the EPC and STATUS in the register context array */ + + sw k0, REG_EPC(sp) + sw k1, REG_STATUS(sp) +#endif + + /* Save floating point registers */ + + mfhi k0 + sw k0, REG_MFHI(sp) + mflo k0 + sw k0, REG_MFLO(sp) + + /* Save general purpose registers */ + /* $1: at_reg, assembler temporary */ + + sw $1, REG_AT(sp) + + /* $2-$3 = v0-v1: Return value registers */ + + sw v0, REG_V0(sp) + sw v1, REG_V1(sp) + + /* $4-$7 = a0-a3: Argument registers */ + + sw a0, REG_A0(sp) + sw a1, REG_A1(sp) + sw a2, REG_A2(sp) + sw a3, REG_A3(sp) + + /* $8-$15 = t0-t7: Volatile registers */ + + sw t0, REG_T0(sp) + sw t1, REG_T1(sp) + sw t2, REG_T2(sp) + sw t3, REG_T3(sp) + sw t4, REG_T4(sp) + sw t5, REG_T5(sp) + sw t6, REG_T6(sp) + sw t7, REG_T7(sp) + + /* $16-$23 = s0-s7: Static registers */ + + sw s0, REG_S0(sp) + sw s1, REG_S1(sp) + sw s2, REG_S2(sp) + sw s3, REG_S3(sp) + sw s4, REG_S4(sp) + sw s5, REG_S5(sp) + sw s6, REG_S6(sp) + sw s7, REG_S7(sp) + + /* $24-25 = t8-t9: More Volatile registers */ + + sw t8, REG_T8(sp) + sw t9, REG_T9(sp) + + /* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be + * saved. + * + * $28 = gp: Only needs to be saved under conditions where there are multiple, per- + * thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP + sw gp, REG_GP(sp) +#endif + + /* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + + sw s8, REG_S8(sp) + + /* $31 = ra: Return address */ + + sw ra, REG_RA(sp) + + /* $29 = sp: The value of the stack pointer on return from the exception. a0 is + * used as a temporary + */ + + addiu \tmp, sp, XCPTCONTEXT_SIZE + sw \tmp, REG_SP(sp) + .endm + +/******************************************************************************************** + * Name: EXCPT_EPILOGUE + * + * Description: + * Provides the "epilogue" logic that should appear at the end of every exception handler. + * + * On input: + * regs - points to the register save structure. NOTE: This *may not* be an address + * lying in a stack! It might be an address in a TCB! + * Interrupts are disabled (via 'di') + * + * On completion: + * All registers restored + * eret is executed to return from the exception + * + ********************************************************************************************/ + + .macro EXCPT_EPILOGUE, regs + .set noat + + /* Since interrupts are disabled via di can now use k0 and k1 again. Use k1 as the + * pointer to the register save array. + */ + + move k1, \regs + + /* Restore the floating point register state */ + + lw k0, REG_MFLO(k1) + mtlo k0 + lw k0, REG_MFHI(k1) + mthi k0 + + /* Restore general purpose registers */ + /* $1: at_reg, assembler temporary */ + + lw $1, REG_AT(k1) + + /* $2-$3 = v0-v1: Return value registers */ + + lw v0, REG_V0(k1) + lw v1, REG_V1(k1) + + /* $4-$7 = a0-a3: Argument registers */ + + lw a0, REG_A0(k1) + lw a1, REG_A1(k1) + lw a2, REG_A2(k1) + lw a3, REG_A3(k1) + + /* $8-$15 = t0-t7: Volatile registers */ + + lw t0, REG_T0(k1) + lw t1, REG_T1(k1) + lw t2, REG_T2(k1) + lw t3, REG_T3(k1) + lw t4, REG_T4(k1) + lw t5, REG_T5(k1) + lw t6, REG_T6(k1) + lw t7, REG_T7(k1) + + /* $16-$23 = s0-s7: Static registers */ + + lw s0, REG_S0(k1) + lw s1, REG_S1(k1) + lw s2, REG_S2(k1) + lw s3, REG_S3(k1) + lw s4, REG_S4(k1) + lw s5, REG_S5(k1) + lw s6, REG_S6(k1) + lw s7, REG_S7(k1) + + /* $24-25 = t8-t9: More Volatile registers */ + + lw t8, REG_T8(k1) + lw t9, REG_T9(k1) + + /* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be + * saved. + * + * $28 = gp: Only needs to be saved under conditions where there are multiple, per- + * thread values for the GP. + */ + +#ifdef MIPS32_SAVE_GP + lw gp, REG_GP(k1) +#endif + + /* $29 = sp: Stack pointer */ + + lw sp, REG_SP(k1) + + /* $30 = either s8 or fp: Depends if a frame pointer is used or not */ + + lw s8, REG_S8(k1) + + /* $31 = ra: Return address */ + + lw ra, REG_RA(k1) + + /* Finally, restore CP status and the EPC */ + + lw k0, REG_STATUS(k1) + lw k1, REG_EPC(k1) + mtc0 k0, MIPS32_CP0_STATUS + ehb + mtc0 k1, MIPS32_CP0_EPC + eret + nop + .endm + +/******************************************************************************************** + * Name: USE_INTSTACK + * + * Description: + * Switch to the interrupt stack (if enabled in the configuration). + * + * On Entry: + * sp - Current value of the user stack pointer + * tmp1, tmp2, tmp3, and tmp4 are registers that can be used temporarily. + * All interrupts should still be disabled. + * + * At completion: + * If the nesting level is 0, then (1) the user stack pointer is saved at the base of the + * interrupt stack and sp points to the interrupt stack. + * The values of tmp1, tmp2, tmp3, and sp have been altered + * + ********************************************************************************************/ + + .macro USE_INTSTACK, tmp1, tmp2, tmp3, tmp4 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + + /* Check the nesting level. If there are no nested interrupts, then we can + * claim the interrupt stack. + */ + + la \tmp1, g_nestlevel + lw \tmp2, (\tmp1) + bne 1f + nop +#endif + + /* Use the interrupt stack, pushing the user stack pointer onto the interrupt + * stack first. + */ + + la \tmp3, g_intstackbase + lw \tmp4, (\tmp3) + sw sp, (\tmp4) + move sp, \tmp4 + +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS +1: + /* Increment the interrupt nesting level */ + + addiu \tmp2, \tmp2, 1 + sw \tmp2, 0(\tmp1) +#endif +#endif + .endm + +/******************************************************************************************** + * Name: RESTORE_STACK + * + * Description: + * Restore the user stack. Not really.. actually only decrements the nesting level. We + * always get the new stack pointer for the register save array. + * + * On Entry: + * tmp1 and tmp2 are registers that can be used temporarily. + * All interrupts must be disabled. + * + * At completion: + * Current nesting level is decremented + * The values of tmp1 and tmp2 have been altered + * + ********************************************************************************************/ + + .macro RESTORE_STACK, tmp1, tmp2 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + + /* Decrement the nesting level */ + + la \tmp1, g_nestlevel + lw \tmp2, (\tmp1) + addiu \tmp2, \tmp2, -1 + sw \tmp2, 0(\tmp1) + +#endif +#endif + .endm + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_EXCPTMACROS_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-gpio.c b/arch/mips/src/pic32mz/pic32mz-gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..8bec67734365927778faa106a4826c1316bfeaff --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-gpio.c @@ -0,0 +1,344 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "chip/pic32mz-ioport.h" +#include "pic32mz-gpio.h" + +#if CHIP_NPORTS > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* This table can be used to map a port number to a IOPORT base address. For + * example, an index of zero would correspond to IOPORTA, one with IOPORTB, + * etc. + */ + +const uintptr_t g_gpiobase[CHIP_NPORTS] = +{ + PIC32MZ_IOPORTA_K1BASE +#if CHIP_NPORTS > 1 + , PIC32MZ_IOPORTB_K1BASE +#endif +#if CHIP_NPORTS > 2 + , PIC32MZ_IOPORTC_K1BASE +#endif +#if CHIP_NPORTS > 3 + , PIC32MZ_IOPORTD_K1BASE +#endif +#if CHIP_NPORTS > 4 + , PIC32MZ_IOPORTE_K1BASE +#endif +#if CHIP_NPORTS > 5 + , PIC32MZ_IOPORTF_K1BASE +#endif +#if CHIP_NPORTS > 6 + , PIC32MZ_IOPORTG_K1BASE +#endif +#if CHIP_NPORTS > 7 + , PIC32MZ_IOPORTH_K1BASE +#endif +#if CHIP_NPORTS > 8 + , PIC32MZ_IOPORTJ_K1BASE +#endif +#if CHIP_NPORTS > 9 + , PIC32MZ_IOPORTK_K1BASE +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mz_output(pinset_t pinset) +{ + return ((pinset & GPIO_OUTPUT) != 0); +} + +static inline bool pic32mz_opendrain(pinset_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAN); +} + +static inline bool pic32mz_outputhigh(pinset_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != 0); +} + +static inline bool pic32mz_value(pinset_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO); +} + +static inline unsigned int pic32mz_portno(pinset_t pinset) +{ + return ((pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +static inline unsigned int pic32mz_pinno(pinset_t pinset) +{ + return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +static inline unsigned int pic32mz_analog(pinset_t pinset) +{ + return ((pinset & GPIO_ANALOG_MASK) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the + * interrupt will be configured when pic32mz_attach() is called. + * + * Returned Value: + * OK on success; negated errno on failure. + * + ****************************************************************************/ + +int pic32mz_configgpio(pinset_t cfgset) +{ + unsigned int port = pic32mz_portno(cfgset); + unsigned int pin = pic32mz_pinno(cfgset); + uint32_t mask = (1 << pin); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Is this an input or an output? */ + + sched_lock(); + if (pic32mz_output(cfgset)) + { + /* Not analog */ + + putreg32(mask, base + PIC32MZ_IOPORT_ANSELCLR_OFFSET); + + /* It is an output; clear the corresponding bit in the TRIS register */ + + putreg32(mask, base + PIC32MZ_IOPORT_TRISCLR_OFFSET); + + /* Is it an open drain output? */ + + if (pic32mz_opendrain(cfgset)) + { + /* It is an open drain output. Set the corresponding bit in + * the ODC register. + */ + + putreg32(mask, base + PIC32MZ_IOPORT_ODCSET_OFFSET); + } + else + { + /* Is is a normal output. Clear the corresponding bit in the + * ODC register. + */ + + putreg32(mask, base + PIC32MZ_IOPORT_ODCCLR_OFFSET); + } + + /* Set the initial output value */ + + pic32mz_gpiowrite(cfgset, pic32mz_outputhigh(cfgset)); + } + else + { + /* It is an input; set the corresponding bit in the TRIS register. */ + + putreg32(mask, base + PIC32MZ_IOPORT_TRISSET_OFFSET); + putreg32(mask, base + PIC32MZ_IOPORT_ODCCLR_OFFSET); + + /* Is it an analog input? */ + + if (pic32mz_analog(cfgset)) + { + putreg32(mask, base + PIC32MZ_IOPORT_ANSELSET_OFFSET); + } + else + { + putreg32(mask, base + PIC32MZ_IOPORT_ANSELCLR_OFFSET); + } + } + + sched_unlock(); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pic32mz_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void pic32mz_gpiowrite(pinset_t pinset, bool value) +{ + unsigned int port = pic32mz_portno(pinset); + unsigned int pin = pic32mz_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Set or clear the output */ + + if (value) + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_PORTSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_PORTCLR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: pic32mz_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool pic32mz_gpioread(pinset_t pinset) +{ + unsigned int port = pic32mz_portno(pinset); + unsigned int pin = pic32mz_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Get ane return the input value */ + + return (getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET) & (1 << pin)) != 0; + } + + return false; +} + +/**************************************************************************** + * Function: pic32mz_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_GPIO) +void pic32mz_dumpgpio(uint32_t pinset, const char *msg) +{ + unsigned int port = pic32mz_portno(pinset); + irqstate_t flags; + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + sched_lock(); + lldbg("IOPORT%c pinset: %04x base: %08x -- %s\n", + 'A'+port, pinset, base, msg); + lldbg(" TRIS: %08x PORT: %08x LAT: %08x ODC: %08x\n", + getreg32(base + PIC32MZ_IOPORT_TRIS_OFFSET), + getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET), + getreg32(base + PIC32MZ_IOPORT_LAT_OFFSET), + getreg32(base + PIC32MZ_IOPORT_ODC_OFFSET)); + lldbg(" CNCON: %08x CNEN: %08x CNPUE: %08x\n", + getreg32(PIC32MZ_IOPORT_CNCON), + getreg32(PIC32MZ_IOPORT_CNEN), + getreg32(PIC32MZ_IOPORT_CNPUE)); + sched_unlock(); + } +} +#endif + +#endif /* CHIP_NPORTS > 0 */ diff --git a/arch/mips/src/pic32mz/pic32mz-gpio.h b/arch/mips/src/pic32mz/pic32mz-gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..1c967bc802ae72c3528afc806b311518f08ee716 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-gpio.h @@ -0,0 +1,268 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-gpio.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_GPIO_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* GPIO settings used in the configport, readport, writeport, etc. + * + * General encoding: + * MMAV IIDR RRRx PPPP + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: I/O mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* 00 Normal input */ +# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* 10 Normal output */ +# define GPIO_OPENDRAN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */ + +#define GPIO_ANALOG_MASK (1 << 13) /* Bit 13: Analog */ +# define GPIO_ANALOG (1 << 13) +# define GPIO_DIGITAL (0) + +#define GPIO_VALUE_MASK (1 << 12) /* Bit 12: Initial output value */ +# define GPIO_VALUE_ONE (1 << 12) +# define GPIO_VALUE_ZERO (0) + +#define GPIO_INTERRUPT (1 << 11) /* Bit 11: Change notification enable */ +#define GPIO_PULLUP (1 << 10) /* Bit 10: Change notification pull-up */ +#define GPIO_PULLDOWN (1 << 9) /* Bit 9: Change notification pull-down */ + +#define GPIO_PORT_SHIFT (5) /* Bits 5-8: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTJ (8 << GPIO_PORT_SHIFT) +# define GPIO_PORTK (9 << GPIO_PORT_SHIFT) + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +typedef uint16_t pinset_t; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* This table can be used to map a port number to a IOPORT base address. For + * example, an index of zero would correspond to IOPORTA, one with IOPORTB, + * etc. + */ + +EXTERN const uintptr_t g_gpiobase[CHIP_NPORTS]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mz_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the interrupt + * will be configured when pic32mz_attach() is called). + * + * Returned Value: + * OK on success; negated errno on failure. + * + ************************************************************************************/ + +int pic32mz_configgpio(pinset_t cfgset); + +/************************************************************************************ + * Name: pic32mz_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void pic32mz_gpiowrite(pinset_t pinset, bool value); + +/************************************************************************************ + * Name: pic32mz_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool pic32mz_gpioread(pinset_t pinset); + +/************************************************************************************ + * Name: pic32mz_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. This + * function is called internally by the system on power up and should not be + * called again. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ +void pic32mz_gpioirqinitialize(void); +#else +# define pic32mz_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: pic32mz_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will also + * reconfigure the pin as an interrupting input. The change notification number is + * associated with all interrupt-capable GPIO pins. The association could, + * however, differ from part to part and must be provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. In that + * case, all attached handlers will be called. Each handler must maintain state + * and determine if the underlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - cn: The change notification number associated with the pin + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ +xcpt_t pic32mz_gpioattach(pinset_t pinset, xcpt_t handler); +#else +# define pic32mz_gpioattach(p,f) (NULL) +#endif + +/************************************************************************************ + * Name: pic32mz_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ +void pic32mz_gpioirqenable(pinset_t pinset); +#else +# define pic32mz_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: pic32mz_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ +void pic32mz_gpioirqdisable(pinset_t pinset); +#else +# define pic32mz_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: pic32mz_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +void pic32mz_dumpgpio(uint32_t pinset, const char *msg); +#else +# define pic32mz_dumpgpio(p,m) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_GPIO_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-gpioirq.c b/arch/mips/src/pic32mz/pic32mz-gpioirq.c new file mode 100644 index 0000000000000000000000000000000000000000..9b7f8c6808396a753aacf5cea53c27104bc5bee7 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-gpioirq.c @@ -0,0 +1,548 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-gpio.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "chip/pic32mz-ioport.h" +#include "pic32mz-gpio.h" + +#ifdef CONFIG_PIC32MZ_GPIOIRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline unsigned int pic32mz_ioport(pinset_t pinset); +static inline unsigned int pic32mz_pin(pinset_t pinset); +static inline bool pic32mz_input(pinset_t pinset); +static inline bool pic32mz_interrupt(pinset_t pinset); +static inline bool pic32mz_pullup(pinset_t pinset); +static inline bool pic32mz_pulldown(pinset_t pinset); +static int pic32mz_cninterrupt(int irq, FAR void *context); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct ioport_level2_s +{ + xcpt_t handler[16]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Arrays of second level interrupt handlers for each pin of each enabled + * I/O port. + */ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTA +static struct ioport_level2_s g_ioporta_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTB +static struct ioport_level2_s g_ioportb_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTC +static struct ioport_level2_s g_ioportc_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTD +static struct ioport_level2_s g_ioportd_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTE +static struct ioport_level2_s g_ioporte_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTF +static struct ioport_level2_s g_ioportf_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTG +static struct ioport_level2_s g_ioportg_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTH +static struct ioport_level2_s g_ioporth_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTJ +static struct ioport_level2_s g_ioportj_cnisrs; +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTK +static struct ioport_level2_s g_ioportk_cnisrs; +#endif + +/* Look-up of port to interrupt handler array */ + +static struct ioport_level2_s * const g_level2_handlers[CHIP_NPORTS] = +{ +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTA + [PIC32MZ_IOPORTA] = &g_ioporta_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTB + [PIC32MZ_IOPORTB] = &g_ioportb_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTC + [PIC32MZ_IOPORTC] = &g_ioportc_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTD + [PIC32MZ_IOPORTD] = &g_ioportd_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTE + [PIC32MZ_IOPORTE] = &g_ioporte_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTF + [PIC32MZ_IOPORTF] = &g_ioportf_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTG + [PIC32MZ_IOPORTG] = &g_ioportg_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTH + [PIC32MZ_IOPORTH] = &g_ioporth_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTJ + [PIC32MZ_IOPORTJ] = &g_ioportj_cnisrs, +#endif +#ifdef CONFIG_PIC32MZ_GPIOIRQ_PORTK + [PIC32MZ_IOPORTK] = &g_ioportk_cnisrs, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mz_input(pinset_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) != GPIO_INPUT); +} + +static inline bool pic32mz_interrupt(pinset_t pinset) +{ + return ((pinset & GPIO_INTERRUPT) != 0); +} + +static inline bool pic32mz_pullup(pinset_t pinset) +{ + return ((pinset & GPIO_PULLUP) != 0); +} + +static inline bool pic32mz_pulldown(pinset_t pinset) +{ + return ((pinset & GPIO_PULLDOWN) != 0); +} + +static inline unsigned int pic32mz_ioport(pinset_t pinset) +{ + return ((pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +static inline unsigned int pic32mz_pin(pinset_t pinset) +{ + return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: pic32mz_cninterrupt + * + * Description: + * Common change notification interrupt handler. + * + ****************************************************************************/ + +static int pic32mz_cninterrupt(int irq, FAR void *context) +{ + struct ioport_level2_s *handlers; + xcpt_t handler; + uintptr_t base; + uint32_t cnstat; + uint32_t cnen; + uint32_t pending; + uint32_t regval; + int ioport; + int status; + int ret = OK; + int i; + + /* Get the IO port index from the IRQ number. This, of course, + * assumes that the irq numbers are consecutive beginning with + * IOPORTA. + */ + + ioport = irq - PIC32MZ_IRQ_PORTA; + DEBUGASSERT(ioport >= 0 && ioport < CHIP_NPORTS); + + /* If we got this interrupt, then there must also be an array + * of second level handlers (and a base address) for the IOPORT. + */ + + handlers = g_level2_handlers[ioport]; + base = g_gpiobase[ioport]; + DEBUGASSERT(handlers && base); + + if (handlers && base) + { + /* Get the interrupt status associated with this interrupt */ + + cnstat = getreg32(base + PIC32MZ_IOPORT_CNSTAT_OFFSET); + cnen = getreg32(base + PIC32MZ_IOPORT_CNSTAT_OFFSET); + pending = cnstat & cnen; + + /* Hmmm.. the data sheet implies that the status will pend + * until the corresponding PORTx registers is read? Clear + * pending status. + */ + + regval = getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET); + UNUSED(regval); + + /* Call all attached handlers for each pending interrupt */ + + for (i = 0; i < 16; i++) + { + /* Is this interrupt pending */ + + if ((pending & (1 << IOPORT_CNSTAT(i))) != 0) + { + /* Yes.. Has the user attached a handler? */ + + handler = handlers->handler[i]; + if (handler) + { + /* Yes.. call the attached handler */ + + status = handler(irq, context); + + /* Keep track of the status of the last handler that + * failed. + */ + + if (status < 0) + { + ret = status; + } + } + } + } + } + + /* Clear the pending interrupt */ + + up_clrpend_irq(irq); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. + * This function is called internally by the system on power up and should + * not be called again. + * + ****************************************************************************/ + +void pic32mz_gpioirqinitialize(void) +{ + uintptr_t base; + int ret; + int i; + + /* Perform initialization for each IO port that has interrupt support + * enabled. We can tell this because there will be an array of second + * level handlers for each enabled IO port. + */ + + for (i = 0; i < CHIP_NPORTS; i++) + { + /* Get the base address of this IO port peripheral */ + + base = g_gpiobase[i]; + DEBUGASSERT(base); + + /* Reset all registers and disable the CN module */ + + putreg32(IOPORT_CNEN_ALL, base + PIC32MZ_IOPORT_CNENCLR_OFFSET); + putreg32(IOPORT_CNPU_ALL, base + PIC32MZ_IOPORT_CNPUCLR_OFFSET); + putreg32(IOPORT_CNPD_ALL, base + PIC32MZ_IOPORT_CNPDCLR_OFFSET); + putreg32(0, base + PIC32MZ_IOPORT_CNCON_OFFSET); + + /* Is interrupt support selected for this IO port? */ + + if (g_level2_handlers[i] != NULL) + { + /* Yes.. Attach the common change notice interrupt handler + * to the IO port interrupt. Notice that this assumes that + * each IRQ number is consecutive beginning with IOPORTA. + */ + + ret = irq_attach(PIC32MZ_IRQ_PORTA + i, pic32mz_cninterrupt); + DEBUGASSERT(ret == OK); + UNUSED(ret); + + /* Enable the CN module. NOTE that the CN module is active when + * in sleep mode. + */ + + putreg32(IOPORT_CNCON_ON, base + PIC32MZ_IOPORT_CNCON_OFFSET); + + /* And enable the GPIO interrupt. Same assumption as above. */ + + up_enable_irq(PIC32MZ_IRQ_PORTA + i); + } + } +} + +/**************************************************************************** + * Name: pic32mz_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will + * also reconfigure the pin as an interrupting input. The change + * notification number is associated with all interrupt-capabile GPIO pins. + * The association could, however, differ from part to part and must be + * provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. + * In that case, all attached handlers will be called. Each handler must + * maintain state and determine if the underlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - pin: The change notification number associated with the pin. + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t pic32mz_gpioattach(pinset_t pinset, xcpt_t handler) +{ + struct ioport_level2_s *handlers; + xcpt_t oldhandler = NULL; + irqstate_t flags; + uintptr_t base; + int ioport; + int pin; + + DEBUGASSERT(pin < IOPORT_NUMCN); + + /* First verify that the pinset is configured as an interrupting input */ + + if (pic32mz_input(pinset) && pic32mz_interrupt(pinset)) + { + /* Get the ioport index and pin number from the pinset */ + + ioport = pic32mz_ioport(pinset); + pin = pic32mz_pin(pinset); + DEBUGASSERT(ioport >= 0 && ioport < CHIP_NPORTS); + + /* Get the register base address for this port */ + + base = g_gpiobase[ioport]; + DEBUGASSERT(base); + + /* If this IO port has been properly configured for interrupts, then + * there should be an array of second level interrupt handlers + * allocated for it. + */ + + handlers = g_level2_handlers[ioport]; + DEBUGASSERT(handlers); + if (handlers) + { + /* Get the previously attached handler as the return value */ + + flags = enter_critical_section(); + oldhandler = handlers->handler[pin]; + + /* Are we attaching or detaching? */ + + if (handler != NULL) + { + /* Attaching... Make sure that the GPIO is properly configured + * as an input + */ + + pic32mz_configgpio(pinset); + + /* Pull-up requested? */ + + if (pic32mz_pullup(pinset)) + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPUSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPUCLR_OFFSET); + } + + /* Pull-down requested? */ + + if (pic32mz_pulldown(pinset)) + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPDSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPDCLR_OFFSET); + } + } + else + { + /* Disable the pull-up/downs (just so things look better in + * the debugger). + */ + + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPUCLR_OFFSET); + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNPDCLR_OFFSET); + } + + /* Whether attaching or detaching, the next state of the interrupt + * should be disabled. + */ + + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENCLR_OFFSET); + + /* Set the new handler (perhaps NULLifying the current handler) */ + + handlers->handler[pin] = handler; + leave_critical_section(flags); + } + } + + return oldhandler; +} + +/**************************************************************************** + * Name: pic32mz_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mz_gpioirqenable(pinset_t pinset) +{ + uintptr_t base; + int ioport; + int pin; + + /* Get the ioport index and pin number from the pinset */ + + ioport = pic32mz_ioport(pinset); + pin = pic32mz_pin(pinset); + DEBUGASSERT(ioport >= 0 && ioport < CHIP_NPORTS); + + /* Get the register base address for this port */ + + base = g_gpiobase[ioport]; + DEBUGASSERT(base); + if (base) + { + /* And enable the interrupt. NOTE that we don't actually check if + * interrupts are configured for this IO port. If not, this operation + * should do nothing. + */ + + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENSET_OFFSET); + } +} + +/**************************************************************************** + * Name: pic32mz_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mz_gpioirqdisable(pinset_t pinset) +{ + uintptr_t base; + int ioport; + int pin; + + /* Get the ioport index and pin number from the pinset */ + + ioport = pic32mz_ioport(pinset); + pin = pic32mz_pin(pinset); + DEBUGASSERT(ioport >= 0 && ioport < CHIP_NPORTS); + + /* Get the register base address for this port */ + + base = g_gpiobase[ioport]; + DEBUGASSERT(base); + if (base) + { + /* And disable the interrupt. NOTE that we don't actually check if + * interrupts are configured for this IO port. If not, this operation + * should do nothing. + */ + + putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENCLR_OFFSET); + } +} + +#endif /* CONFIG_PIC32MZ_GPIOIRQ */ diff --git a/arch/mips/src/pic32mz/pic32mz-head.S b/arch/mips/src/pic32mz/pic32mz-head.S new file mode 100644 index 0000000000000000000000000000000000000000..b04ab231f1389997ef5a82243e13fcb8385587ef --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-head.S @@ -0,0 +1,801 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-head.S + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "pic32mz-config.h" +#include "chip/pic32mz-features.h" +#include "pic32mz-excptmacros.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_PIC32MZ_MVEC +# error "Multi-vectors not supported" +# ifndef CONFIG_PIC32MZ_EBASE +# error "EBASE address provided" /* Should come from the linker script */ +# endif +# ifndef CONFIG_PIC32MZ_VECTORSPACING +# error "No vector spacing provided" +# endif +#endif + +/* Linker memory organization ***********************************************/ +/* Data memory is organized as follows: + * + * 1) Possible space reserved for debug data + * 2) Ram functions: (.data): + * Start: _sramfunc + * End(+1): _eramfunc + * 3) Initialized data (.data): + * Start: _sdata + * End(+1): _edata + * 4) Uninitialized data (.bss): + * Start: _sbss + * End(+1): _ebss + * + * The following are placed outside of the "normal" memory segments -- mostly + * so that they do not have to be cleared on power up. + * + * 5) Idle thread stack: + * Start: _ebss + * End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE + * 6) Optional interrupt stack + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE + * End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE+(CONFIG_ARCH_INTERRUPTSTACK & ~3) + * 6a) Heap (without interrupt stack) + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE + * End(+1): to the end of memory + * 6b) Heap (with interrupt stack) + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE+(CONFIG_ARCH_INTERRUPTSTACK & ~3) + * End(+1): to the end of memory + */ + +#define PIC32MZ_STACK_BASE _ebss +#define PIC32MZ_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +# define PIC32MZ_INTSTACK_BASE PIC32MZ_STACK_TOP +# define PIC32MZ_INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~3) +# define PIC32MZ_INTSTACK_TOP PIC32MZ_STACK_TOP+PIC32MZ_INTSTACK_SIZE +# define PIC32MZ_HEAP_BASE PIC32MZ_INTSTACK_TOP +#else +# define PIC32MZ_HEAP_BASE PIC32MZ_STACK_TOP +#endif + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "pic32mz-head.S" + + /* Exported symbols */ + + .global __reset + .global __start + .global halt + .global devcfg +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + .global g_nestlevel +#endif +#endif + .global g_idle_topstack + + /* Imported symbols */ + + .global os_start + .global pic32mz_exception + .global pic32mz_decodeirq +#ifdef CONFIG_PIC32MZ_NMIHANDLER + .global pic32mz_donmi +#endif + + /* This file contains 32-bit assembly code */ + + .set nomips16 + +/**************************************************************************** + * Name: __reset + * + * Description: + * Reset entry point. This function is positioned at the beginning of + * the boot FLASH by the linker in KSEG1. Simply jumps to the __start + * logic in KSEG0 (also in the boot FLASH). + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .reset, "ax", @progbits + .align 2 + .set noreorder + .set nomips16 + .ent __reset + +__reset: + +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips + + .word 0x10000004 /* 0x0000 */ + /* MIPS32: Branch forward 0x14 bytes */ + /* MicroMIPS: ADDI32 $0, $0, 0x0007 (NOP) */ + .word 0x00000000 /* 0x0004 */ + /* MIPS32: NOP */ + /* MicroMIPS: NOP */ + + /* If we get here then we are in microMIPS mode. That is because the + * preceding instructions are all NOP in that case and we fall through + * to here. Otherwise, we branched to __reset_switch_isa + */ + +__reset_micromips: + + /* Just jump to the startup initialization code */ + + la k0, __start /* 0x0008 */ + jr k0 /* 0x0010 */ + nop /* 0x0012 */ + + /* Device not in proper ISA mode. If we are not in microMIPS mode then + * we get here from the first instruction at __reset which will get + * interpreted as a branch to this location. + */ + + .align 2 + .set nomicromips + +__reset_halt: + b __reset_halt /* 0x0014 <- Branch target */ + nop +#else + /* Just jump to the startup initialization code */ + + .set nomicromips + la k0, __start + jr k0 + nop +#endif + .end __reset + +/**************************************************************************** + * Name: _gen_exception + * + * Description: + * General Exception Vector Handler. Jumps to _exception_handler. This + * vector will be positioned at 0xbfc00180 by the linker script. NOTE: + * If we set the BEV bit in the status register so all interrupt vectors + * should go through the _bev_exception. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .gen_excpt,"ax",@progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _gen_exception + +_gen_exception: + la k0, _exception_handler + jr k0 + nop + .end _gen_exception + +/**************************************************************************** + * Name: _ebase_exception + * + * Description: + * Interrupt Exception Vector Handler. Jumps to _int_handler. This + * vector will be positioned at 0xbfc00200 by the linker script. NOTE: + * Several vectors (JTAG, TLB fills, etc.) could come through this vector. + * However, this is intended to serve vectors in PIC32MZ single vector + * mode: The EBASE register will be set to 0xbfc00000 and the vector + * should go to EBASE + 0x0200. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .ebase_excpt,"ax",@progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _ebase_exception + +_ebase_exception: + la k0, _int_handler + jr k0 + nop + .end _ebase_exception + +/**************************************************************************** + * Name: _bev_exception + * + * Description: + * Boot Exception Vector Handler. Jumps to _exception_handler. This + * vector will be positioned at 0xbfc00380 by the linker script. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .bev_excpt,"ax",@progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _bev_exception + +_bev_exception: + la k0, _exception_handler + jr k0 + nop + .end _bev_exception + +/**************************************************************************** + * Name: _int_exception + * + * Description: + * Interrupt Exception Vector Handler. Jumps to _int_handler. This + * vector will be positioned at 0xbfc00400 by the linker script. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .int_excpt,"ax",@progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _int_exception + +_int_exception: + la k0, _int_handler + jr k0 + nop + .end _int_exception + +/**************************************************************************** + * Name: __start + * + * Description: + * This is the KSEG0 startup code. It receives control from the reset + * entry point. This lgic This prepares the processor to execute + * C code, performs some very low-level initialization, then starts NuttX + * (via __start_nuttx + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .start, "ax", @progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent __start + +__start: + + /* If this function was entered because of an NMI, then turn processing + * over to the NMI handler. + */ + +#ifdef CONFIG_PIC32MZ_NMIHANDLER + mfc0 k0, $12 /* Load CP0 status register */ + ext k0, k0, 19, 1 /* Extract NMI bit */ + beqz k0, .Lnotnmi + nop + la k0, _nmi_handler + jr k0 + nop + + /* This is not an NMI */ + +.Lnotnmi: +#endif + + /* Initialize the stack pointer */ + + la sp, PIC32MZ_STACK_TOP + + /* Initialize the global pointer (gp). _gp is initialized by the linker + * script to point to the "middle" of the small variables region. + */ + + la gp, _gp + + /* Initialize Global Pointer in Shadow Set. The SRSCtl PSS field must + * be set to the shadow set in which to initialize the global pointer. + * Since we only have a single shadow set, we will initialize + * SRSCtl PSS to SRSCtl HSS. We then write the global pointer to the + * previous shadow set to ensure that on interrupt, the global pointer + * has been initialized. + */ + + mfc0 t1, PIC32MZ_CP0_SRSCTL /* Read SRSCtl register */ + add t3, t1, zero /* Save off current SRSCtl */ + ext t2, t1, 26, 4 /* to obtain HSS field */ + ins t1, t2, 6, 4 /* Put HSS field */ + mtc0 t1, PIC32MZ_CP0_SRSCTL /* into SRSCtl PSS */ + wrpgpr gp, gp /* Set global pointer in PSS */ + mtc0 t3, PIC32MZ_CP0_SRSCTL /* Restore SRSCtl */ + + /* Clear uninitialized data sections */ + + la t0, _sbss + la t1, _ebss + b .Lbsscheck + nop + +.Lbssloop: + sw zero, 0x0(t0) + sw zero, 0x4(t0) + sw zero, 0x8(t0) + sw zero, 0xc(t0) + addu t0, 16 + +.Lbsscheck: + bltu t0, t1, .Lbssloop + nop + + /* Copy initialized data from program flash to data memory */ + + la t0, _data_loaddr + la t1, _sdata + la t2, _edata + b .Ldatacheck + nop + +.Ldataloop: + lw t3, (t0) + sw t3, (t1) + addu t0, 4 + addu t1, 4 + +.Ldatacheck: + bltu t1, t2, .Ldataloop + nop + + /* If there are no RAM functions, skip the next two sections -- + * copying RAM functions from program flash to data memory and + * initializing bus matrix registers. + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + la t1, _ramfunc_sizeof + beqz t1, .Lnoramfuncs + nop + + /* Copy RAM functions from program flash to data memory */ + + la t0, _ramfunc_loadaddr + la t1, _sramfunc + la t2, _eramfunc + +.Lramfuncloop: + lw t3,(t0) + sw t3,(t1) + addu t0,4 + addu t1,4 + + bltu t1, t2, .Lramfuncloop + nop + + /* Initialize bus matrix registers if RAM functions exist in the + * application + */ + + la t1, _bmxdkpba_address + la t2, PIC32MZ_BMX_DKPBA + sw t1, 0(t2) + la t1, _bmxdudba_address + la t2, PIC32MZ_BMX_DUDBA + sw t1, 0(t2) + la t1, _bmxdupba_address + la t2, PIC32MZ_BMX_DUPBA + sw t1, 0(t2) +.Lnoramfuncs: +#endif + + /* Initialize CP0 Count register */ + + mtc0 zero, PIC32MZ_CP0_COUNT + + /* Initialize Compare register */ + + li t2, -1 + mtc0 t2, PIC32MZ_CP0_COMPARE + + /* Initialize EBase register */ + +#ifdef CONFIG_PIC32MZ_MVEC + la t1, CONFIG_PIC32MZ_EBASE + mtc0 t1, PIC32MZ_CP0_EBASE + + /* Initialize IntCtl register */ + + li t1, CONFIG_PIC32MZ_VECTORSPACING + li t2, 0 + ins t2, t1, CP0_INTCTL_VS_SHIFT, 5 + mtc0 t2, PIC32MZ_CP0_INTCTL +#endif + + /* Initialize CAUSE registers + * - Enable counting of Count register (DC = 0) + * - Use special exception vector (IV = 1) + * - Clear pending software interrupts (IP1:IP0 = 0) + */ + + li t1, CP0_CAUSE_IV + mtc0 t1, PIC32MZ_CP0_CAUSE + + /* Initialize STATUS register + * - Access to Coprocessor 0 not allowed in user mode (CU0 = 0) + * - User mode uses configured endianness (RE = 0) + * - Preserve Bootstrap Exception vectors (BEV) + * - Preserve soft reset (SR) and non-maskable interrupt (NMI) + * - CorExtend enabled based on whether CorExtend User Defined + * Instructions have been implemented (CEE = Config(UDI)) + * - Disable any pending interrups (IM7..IM2 = 0, IM1..IM0 = 0) + * - Disable hardware interrupts (IPL7:IPL2 = 0) + * - Base mode is Kernel mode (UM = 0) + * - Error level is normal (ERL = 0) + * - Exception level is normal (EXL = 0) + * - Interrupts are disabled (IE = 0) + */ + + mfc0 t0, PIC32MZ_CP0_CONFIG + ext t1, t0, 22,1 /* Extract UDI from Config register */ + sll t1, t1, 17 /* Move UDI to Status.CEE location */ + mfc0 t0, PIC32MZ_CP0_STATUS + and t0, t0, 0x00580000 /* Preserve SR, NMI, and BEV */ + or t0, t1, t0 /* Include Status.CEE (from UDI) */ + mtc0 t0, PIC32MZ_CP0_STATUS + + /* Initialize Status BEV for normal exception vectors */ + + mfc0 t0, PIC32MZ_CP0_STATUS + and t0, t0, ~CP0_STATUS_BEV /* Clear BEV */ + mtc0 t0, PIC32MZ_CP0_STATUS + + /* Start NuttX. We do this via a thunk in the text section so that + * a normal jump and link can be used, enabling the startup code + * to work properly whether main is written in MIPS16 or MIPS32 + * code. I.e., the linker will correctly adjust the JAL to JALX if + * necessary + */ + + la t0, __start_nuttx + jr t0 + nop + .end __start + +/**************************************************************************** + * Name: _exception_handler + * + * Description: + * BEV/General exception handler. Calls pic32mz_exception() + * + ****************************************************************************/ + + .section .bev_handler, "ax", @progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _exception_handler + +_exception_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mz_exception /* Call pic32mz_exception(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mz_exception() */ + .end _exception_handler + +/**************************************************************************** + * Name: _int_handler + * + * Description: + * Interrupt exception handler. Calls up_decodeirq() + * + ****************************************************************************/ + + .section .int_handler, "ax", @progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _int_handler + +_int_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mz_decodeirq /* Call pic32mz_decodeirq(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mz_decodeirq() */ + .end _int_handler + +/**************************************************************************** + * Name: _nmi_handler + * + * Description: + * NMI exception handler. Calls pic32mz_donmi + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_NMIHANDLER + .section .nmi_handler, "ax", @progbits + .set noreorder +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent _nmi_handler + +_nmi_handler: + EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ + move a0, sp /* Pass register save structure as the parameter 1 */ + USE_INTSTACK t0, t1, t2, t3 /* Switch to the interrupt stack */ + la t0, pic32mz_donmi /* Call up_donmi(regs) */ + jalr ra, t0 + nop +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + di /* Prohibit nested interrupts from here */ +#endif + RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mz_donmi() */ + .end _nmi_handler +#endif + +/**************************************************************************** + * Name: __start_nuttx + * + * Description: + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .text +#ifdef CONFIG_MIPS_MICROMIPS + .set micromips +#endif + .ent __start_nuttx + +__start_nuttx: + /* Perform low level initialization */ + + la t0, pic32mz_lowinit + jalr ra, t0 + nop + + /* Call os_start */ + + la t0, os_start + jalr ra, t0 + nop + + /* Just in case main returns, go into an infinite loop */ + +halt: +1: + b 1b + nop + .end __start_nuttx + +/**************************************************************************** + * Device Configuration + ****************************************************************************/ + + .section .devcfg, "a" + .type devcfg, object +devcfg: +devcfg3: + .long CONFIG_PIC32MZ_USERID << DEVCFG3_USERID_SHIFT | \ + CONFIG_PIC32MZ_FMIIEN << DEVCFG3_FMIIEN_SHIFT | \ + CONFIG_PIC32MZ_FETHIO << DEVCFG3_FETHIO_SHIFT | \ + CONFIG_PIC32MZ_PGL1WAY << DEVCFG3_PGL1WAY_SHIFT | \ + CONFIG_PIC32MZ_PMDL1WAY << DEVCFG3_PMDL1WAY_SHIFT | \ + CONFIG_PIC32MZ_IOL1WAY << DEVCFG3_IOL1WAY_SHIFT | \ + CONFIG_PIC32MZ_FUSBIDIO << DEVCFG3_FUSBIDIO_SHIFT | \ + DEVCFG3_RWO + +devcfg2: + .long CONFIG_PIC32MZ_PLLIDIV | CONFIG_PIC32MZ_FPLLRNG | \ + CONFIG_PIC32MZ_FPLLICLK | CONFIG_PIC32MZ_PLLMULT | \ + CONFIG_PIC32MZ_PLLODIV | CONFIG_PIC32MZ_UPLLFSEL | \ + DEVCFG2_RWO + +devcfg1: + .long CONFIG_PIC32MZ_FNOSC | CONFIG_PIC32MZ_DMTINV |\ + CONFIG_PIC32MZ_FSOSCEN | CONFIG_PIC32MZ_IESO | \ + CONFIG_PIC32MZ_POSCMOD | CONFIG_PIC32MZ_OSCIOFNC | \ + CONFIG_PIC32MZ_FCKSM | CONFIG_PIC32MZ_WDTPS | \ + CONFIG_PIC32MZ_WDTSPGM | CONFIG_PIC32MZ_WINDIS | \ + CONFIG_PIC32MZ_FWDTEN | CONFIG_PIC32MZ_FWDTWINSZ | \ + CONFIG_PIC32MZ_DMTCNT | CONFIG_PIC32MZ_FSOSCEN | \ + CONFIG_PIC32MZ_FSOSCEN | CONFIG_PIC32MZ_FDMTEN | \ + DEVCFG1_RWO + +devcfg0: + .long CONFIG_PIC32MZ_DEBUGGER | CONFIG_PIC32MZ_JTAGEN | \ + CONFIG_PIC32MZ_ICESEL | CONFIG_PIC32MZ_TRCEN | \ + CONFIG_PIC32MZ_BOOTISA | CONFIG_PIC32MZ_FECCCON | \ + CONFIG_PIC32MZ_FSLEEP | CONFIG_PIC32MZ_DBGPER | \ + CONFIG_PIC32MZ_EJTAGBEN | DEVCFG0_RW0 + + .size devcfg, .-devcfg + +/* Every word in the configuration space and sequence space has an + * associated alternate word. During device start-up, primary words are + * read and if uncorrectable ECC errors are found, the BCFGERR flag is set + * and alternate words are used. + */ + + .section .adevcfg, "a" + .type adevcfg, object +adevcfg: +adevcfg3: + .long ADEVCFG3_USERID << DEVCFG3_USERID_SHIFT | \ + CONFIG_PIC32MZ_FMIIEN << DEVCFG3_FMIIEN_SHIFT | \ + CONFIG_PIC32MZ_FETHIO << DEVCFG3_FETHIO_SHIFT | \ + CONFIG_PIC32MZ_PGL1WAY << DEVCFG3_PGL1WAY_SHIFT | \ + CONFIG_PIC32MZ_PMDL1WAY << DEVCFG3_PMDL1WAY_SHIFT | \ + CONFIG_PIC32MZ_IOL1WAY << DEVCFG3_IOL1WAY_SHIFT | \ + CONFIG_PIC32MZ_FUSBIDIO << DEVCFG3_FUSBIDIO_SHIFT | \ + DEVCFG3_RWO + +adevcfg2: + .long CONFIG_PIC32MZ_PLLIDIV | CONFIG_PIC32MZ_FPLLRNG | \ + CONFIG_PIC32MZ_FPLLICLK | CONFIG_PIC32MZ_PLLMULT | \ + CONFIG_PIC32MZ_PLLODIV | CONFIG_PIC32MZ_UPLLFSEL | \ + DEVCFG2_RWO + +adevcfg1: + .long CONFIG_PIC32MZ_FNOSC | CONFIG_PIC32MZ_DMTINV |\ + CONFIG_PIC32MZ_FSOSCEN | CONFIG_PIC32MZ_IESO | \ + CONFIG_PIC32MZ_POSCMOD | CONFIG_PIC32MZ_OSCIOFNC | \ + CONFIG_PIC32MZ_FCKSM | CONFIG_PIC32MZ_WDTPS | \ + CONFIG_PIC32MZ_WDTSPGM | CONFIG_PIC32MZ_WINDIS | \ + ADEVCFG1_FWDTEN | CONFIG_PIC32MZ_FWDTWINSZ | \ + CONFIG_PIC32MZ_DMTCNT | CONFIG_PIC32MZ_FSOSCEN | \ + CONFIG_PIC32MZ_FSOSCEN | CONFIG_PIC32MZ_FDMTEN | \ + DEVCFG1_RWO + +adevcfg0: + .long CONFIG_PIC32MZ_DEBUGGER | CONFIG_PIC32MZ_JTAGEN | \ + CONFIG_PIC32MZ_ICESEL | CONFIG_PIC32MZ_TRCEN | \ + CONFIG_PIC32MZ_BOOTISA | CONFIG_PIC32MZ_FECCCON | \ + CONFIG_PIC32MZ_FSLEEP | CONFIG_PIC32MZ_DBGPER | \ + CONFIG_PIC32MZ_EJTAGBEN | DEVCFG0_RW0 + + .size adevcfg, .-adevcfg + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Interrupt stack variables */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + +/* g_instackbase is a pointer to the final, aligned word of the interrupt + * stack. + */ + + .sdata + .type g_intstackbase, object +g_intstackbase: + .long PIC32MZ_INTSTACK_TOP-4 + .size g_intstackbase, .-g_intstackbase + +/* g_nextlevel is the exception nesting level... the interrupt stack is not + * available to nested exceptions. + */ + +#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS + .sbss + .type g_nestlevel, object +g_nestlevel: + .skip 4 +#endif +#endif + +/* This global variable is unsigned int g_idle_topstack and is exported here only + * because of its coupling to idle thread stack. + */ + + .sdata + .type g_idle_topstack, object +g_idle_topstack: + .long PIC32MZ_HEAP_BASE + .size g_idle_topstack, .-g_idle_topstack diff --git a/arch/mips/src/pic32mz/pic32mz-irq.c b/arch/mips/src/pic32mz/pic32mz-irq.c new file mode 100644 index 0000000000000000000000000000000000000000..4bb185939eccdda860bba404d095e06a117aa5a3 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-irq.c @@ -0,0 +1,449 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-irq.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/pic32mz-int.h" +#include "pic32mz-gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_PIC32MZ_MVEC +# error "Multi-vectors not supported" +#endif + +/* Interrupt controller definitions *****************************************/ +/* Number of interrupt enable/interrupt status registers */ + +#define INT_NREGS ((NR_IRQS + 31) >> 5) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_prioritize_irq + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +static int pic32mz_prioritize_irq(int irq, int priority); +#else +# define pic32mz_prioritize_irq(i,p) up_prioritize_irq(i,p) +#endif + +/**************************************************************************** + * Name: pic32mz_ifs + ****************************************************************************/ + +static uintptr_t pic32mz_ifs(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + return PIC32MZ_INT_IFS(irq >> 5); + } + + return 0; +} + +/**************************************************************************** + * Name: pic32mz_ifsclr + ****************************************************************************/ + +static uintptr_t pic32mz_ifsclr(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + return PIC32MZ_INT_IFSCLR(irq >> 5); + } + + return 0; +} + +/**************************************************************************** + * Name: pic32mz_iec + ****************************************************************************/ + +static uintptr_t pic32mz_iec(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + return PIC32MZ_INT_IEC(irq >> 5); + } + + return 0; +} + +/**************************************************************************** + * Name: pic32mz_iecset + ****************************************************************************/ + +static uintptr_t pic32mz_iecset(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + return PIC32MZ_INT_IECSET(irq >> 5); + } + + return 0; +} + +/**************************************************************************** + * Name: pic32mz_iecclr + ****************************************************************************/ + +static uintptr_t pic32mz_iecclr(int irq) +{ + if ((unsigned)irq < NR_IRQS) + { + return PIC32MZ_INT_IECCLR(irq >> 5); + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regval; + int irq; + + /* Disable all interrupts */ + + putreg32(0xffff, PIC32MZ_INT_IEC0CLR); /* Interrupts 0-31 */ + putreg32(0xffff, PIC32MZ_INT_IEC1CLR); /* Interrupts 32-63 */ + putreg32(0xffff, PIC32MZ_INT_IEC2CLR); /* Interrupts 64-95 */ + putreg32(0xffff, PIC32MZ_INT_IEC3CLR); /* Interrupts 96-127 */ + putreg32(0xffff, PIC32MZ_INT_IEC4CLR); /* Interrupts 128-159 */ + putreg32(0xffff, PIC32MZ_INT_IEC5CLR); /* Interrupts 160-191 */ + + /* Set all interrupts to the default (middle) priority */ + + for (irq = 0; irq < NR_IRQS; irq++) + { + (void)pic32mz_prioritize_irq(irq, (INT_IPC_MID_PRIORITY << 2)); + } + + /* Set the BEV bit in the STATUS register */ + + regval = cp0_getstatus(); + regval |= CP0_STATUS_BEV; + cp0_putstatus(regval); + + /* Set the EBASE value to the beginning of boot FLASH. In single-vector + * mode, interrupt vectors should go to EBASE + 0x0200 0r 0xbfc00200. + */ + + cp0_putebase(0xbfc00000); + + /* Set the INTCTL vector spacing to non-zero */ + + cp0_putintctl(0x00000020); + + /* Set the IV bit in the CAUSE register */ + + regval = cp0_getcause(); + regval |= CP0_CAUSE_IV; + cp0_putcause(regval); + + /* Clear the EXL and BEV bits in the STATUS register */ + + regval = cp0_getstatus(); + regval &= ~(CP0_STATUS_EXL | CP0_STATUS_BEV); + cp0_putstatus(regval); + + /* Configure multi- or single- vector interrupts */ + +#ifdef CONFIG_PIC32MZ_MVEC + putreg32(INT_INTCON_MVEC, PIC32MZ_INT_INTCONSET); +#else + putreg32(INT_INTCON_MVEC, PIC32MZ_INT_INTCONCLR); +#endif + + /* Initialize GPIO change notification handling */ + +#ifdef CONFIG_PIC32MZ_GPIOIRQ + pic32mz_gpioirqinitialize(); +#endif + + /* Attach and enable software interrupts */ + + irq_attach(PIC32MZ_IRQ_CS0, up_swint0); + up_enable_irq(PIC32MZ_IRQ_CS0); + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* And finally, enable interrupts */ + + /* Interrupts are enabled by setting the IE bit in the CP0 status register */ + + regval = 0; + asm volatile("ei %0" : "=r"(regval)); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Then enable all interrupt levels */ + + up_irq_restore(CP0_STATUS_IM_ALL); +#else + /* Enable only software interrupts */ + + up_irq_restore(CP0_STATUS_IM_SWINTS); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Disable the interrupt by clearing the associated bit in the IEC register */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + regaddr = pic32mz_iecclr(irq); + bitno = (unsigned)irq & 31; + + DEBUGASSERT(regaddr); + if (regaddr) + { + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Enable the interrupt by setting the associated bit in the IEC register */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + regaddr = pic32mz_iecset(irq); + bitno = (unsigned)irq & 31; + + DEBUGASSERT(regaddr); + if (regaddr) + { + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_pending_irq + * + * Description: + * Return true if the interrupt is pending and unmasked. + * + ****************************************************************************/ + +bool up_pending_irq(int irq) +{ + uintptr_t ifsaddr; + uintptr_t iecaddr; + uint32_t regval; + int bitno; + + /* Test if the interrupt is pending by reading both the IEC and IFS + * register. Return true if the bit associated with the irq is both pending + * the IFs and enabled in the IEC. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + ifsaddr = pic32mz_ifs(irq); + iecaddr = pic32mz_iec(irq); + bitno = (unsigned)irq & 31; + + DEBUGASSERT(ifsaddr && iecaddr); + if (ifsaddr && iecaddr) + { + /* Get the set of unmasked, pending interrupts. Return true if the + * interrupt is pending and unmask. + */ + + regval = getreg32(ifsaddr) & getreg32(iecaddr); + return (regval & (1 << bitno)) != 0; + } + + return false; +} + +/**************************************************************************** + * Name: up_clrpend_irq + * + * Description: + * Clear any pending interrupt + * + ****************************************************************************/ + +void up_clrpend_irq(int irq) +{ + uintptr_t regaddr; + int bitno; + + /* Acknowledge the interrupt by clearing the associated bit in the IFS + * register. It is necessary to do this BEFORE lowering the interrupt + * priority level otherwise recursive interrupts would occur. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + regaddr = pic32mz_ifsclr(irq); + bitno = (unsigned)irq & 31; + + DEBUGASSERT(regaddr); + if (regaddr) + { + /* Acknowledge the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ by setting the priority and sub-priority + * fields in the PIC32MZ IPC registers. There are 12 IPC registers, IPC0 + * through IPC11. Each has sub-priority fields for 8 interrupts for a + * total of 96 interrupts max. + * + * Each interrupt priority is represent by a group of 5 bits: a 3-bit + * priority and a 2-bit sub-priority. These have different meanings to + * the hardware. The priority is the priority level that is enabled + * or masked by the IPL field of the CAUSE register. The sub-priority + * only mediates ties when two interrupts with the same priority pend + * simultaneously. + * + * In this function, we just treat this as a single 5-bit priority. + * (MS 3-bits=priority; LS 2-bits=sub-priority). + * + * The 5-bit priority/sub-priority fields are arranged at byte boundaries + * within each IPC register: + * + * xxxP PPSS xxxP PPSS xxxP PPSS xxxP PPSS + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +static int pic32mz_prioritize_irq(int irq, int priority) +#else +int up_prioritize_irq(int irq, int priority) +#endif +{ + int regndx; + int shift; + + /* Don't allow this function to be used for disabling interrupts. There is + * no good reason for this restriction other than I want to make sure that + * the 5-bit priority values passed to this function are *not* confused with + * the 3-bit hardware priority values. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS && (unsigned)(priority >> 2) > 0); + if (irq < NR_IRQS) + { + /* Get the index to the IPC register and the shift to the 5-bit priority + * field for this IRQ. + */ + + regndx = irq >> 2; /* Range: 0-11 */ + shift = (irq & 3) << 3; /* {0, 8, 16, 24 } */ + + /* Set the new interrupt priority (momentarily disabling interrupts) */ + + putreg32(0x1f << shift, PIC32MZ_INT_IPCCLR(regndx)); + putreg32(priority << shift, PIC32MZ_INT_IPCSET(regndx)); + return OK; + } + + return -EINVAL; +} diff --git a/arch/mips/src/pic32mz/pic32mz-lowconsole.c b/arch/mips/src/pic32mz/pic32mz-lowconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..d16e81631ab4d248b888ed23a64930af31885bfd --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-lowconsole.c @@ -0,0 +1,491 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-lowconsole.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mz-config.h" +#include "chip/pic32mz-uart.h" +#include "chip/pic32mz-pps.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART1_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART1_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART1_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART1_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART2_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART2_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART2_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART2_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART3_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART3_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART3_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART3_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART3_2STOP +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART4_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART4_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART4_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART4_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART4_2STOP +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART5_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART5_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART5_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART5_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART5_2STOP +# elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART6_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART6_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART6_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART6_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART6_2STOP +# else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_putreg + * + * Description: + * Write a value to a UART register + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline void pic32mz_putreg(uintptr_t uart_base, unsigned int offset, + uint32_t value) +{ + putreg32(value, uart_base + offset); +} +#endif + +/**************************************************************************** + * Name: pic32mz_getreg + * + * Description: + * Get a value from a UART register + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline uint32_t pic32mz_getreg(uintptr_t uart_base, + unsigned int offset) +{ + return getreg32(uart_base + offset); +} +#endif + +/**************************************************************************** + * Name: pic32mz_uartsetbaud + * + * Description: + * Configure the UART baud rate. + * + * With BRGH=0 + * BAUD = PBCLK2 / 16 / (BRG+1) + * BRG = PBCLK2 / 16 / BAUD - 1 + * With BRGH=1 + * BAUD = PBCLK2 / 4 / (BRG+1) + * BRG = PBCLK2 / 4 / BAUD - 1 + * + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static void pic32mz_uartsetbaud(uintptr_t uart_base, uint32_t baudrate) +{ + uint32_t tmp; + uint32_t brg; + unsigned int mode; + + /* We want the largest value of BRG divisor possible (for the best accuracy). + * Subject to BRG <= 65536. + */ + + tmp = BOARD_PBCLK2 / baudrate; + + /* Try BRGH=1 first. This will select the 4x divisor and will produce the + * larger BRG divisor, given all other things equal. + */ + + brg = (tmp + 2) >> 2; + mode = PIC32MZ_UART_MODESET_OFFSET; + + if (brg > 65536) + { + /* Nope, too big.. try BRGH=0 */ + + brg = (tmp + 8) >> 4; + mode = PIC32MZ_UART_MODECLR_OFFSET; + } + DEBUGASSERT(brg <= 65536); + + /* Set the BRG divisor */ + + pic32mz_putreg(uart_base, mode, UART_MODE_BRGH); + pic32mz_putreg(uart_base, PIC32MZ_UART_BRG_OFFSET, brg); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_uartreset + * + * Description: + * Reset hardware and disable Rx and Tx. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartreset(uintptr_t uart_base) +{ + /* Doesn't reset the hardware... just shuts it down */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STACLR_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODECLR_OFFSET, UART_MODE_ON); +} +#endif + +/**************************************************************************** + * Name: pic32mz_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartconfigure(uintptr_t uart_base, uint32_t baudrate, + unsigned int parity, unsigned int nbits, bool stop2) +{ + /* Clear mode and sta bits */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_MODECLR_OFFSET, + UART_MODE_STSEL | UART_MODE_PDSEL_MASK | UART_MODE_BRGH | + UART_MODE_RXINV | UART_MODE_WAKE | UART_MODE_LPBACK | + UART_MODE_UEN_MASK | UART_MODE_RTSMD | UART_MODE_IREN | + UART_MODE_SIDL | UART_MODE_ON); + + /* Configure the FIFOs: + * + * RX: Interrupt at 75% FIFO full (6 of 8 for 8-deep FIFO) + * TX: Interrupt on FIFO empty + * Invert transmit polarity. + * + * NOTE that there are not many options on trigger TX interrupts. The FIFO not + * full might generate better through-put but with a higher interrupt rate. FIFO + * empty should lower the interrupt rate but result in a burstier output. If + * you change this, please read the comment for acknowledging the interrupt in + * pic32mz-serial.c + */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STACLR_OFFSET, + UART_STA_UTXINV | UART_STA_UTXISEL_TXBE | UART_STA_URXISEL_RXB75); + + /* Configure the FIFO interrupts */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STASET_OFFSET, + UART_STA_UTXISEL_TXBNF | UART_STA_URXISEL_RECVD); + + /* Configure word size and parity */ + + if (nbits == 9) + { + DEBUGASSERT(parity == 0); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_9NONE); + } + else + { + DEBUGASSERT(nbits == 8); + if (parity == 1) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8ODD); + } + else if (parity == 2) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8EVEN); + } + } + + /* Configure 1 or 2 stop bits */ + + if (stop2) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_STSEL); + } + + /* Set the BRG divisor */ + + pic32mz_uartsetbaud(uart_base, baudrate); + + /* Enable the UART */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STASET_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_ON); +} +#endif + +/**************************************************************************** + * Name: pic32mz_consoleinit + * + * Description: + * Initialize a low-level console for debug output. This function is called + * very early in the initialization sequence to configure the serial console + * UART (only). + * + ****************************************************************************/ + +void pic32mz_consoleinit(void) +{ +#ifdef HAVE_UART_DEVICE + + /* Setup up pin selection registers for all configured UARTs. The board.h + * header file must provide these definitions to select the correct pin + * configuration for each enabled UARt. + */ + +#ifdef CONFIG_PIC32MZ_UART1 + /* Configure UART1 RX (input) and TX (output) pins */ + + putreg32(BOARD_U1RX_PPS, PIC32MZ_U1RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U1TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U1TX_PPS)); + +#ifdef CONFIG_UART1_OFLOWCONTROL + /* Configure the UART1 CTS input pin */ + + putreg32(BOARD_U1CTS_PPS, PIC32MZ_U1CTSR); +#endif +#ifdef CONFIG_UART1_IFLOWCONTROL + /* Configure the UART1 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U1RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U1RTS_PPS)); + +#endif /* CONFIG_UART1_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART1 */ + +#ifdef CONFIG_PIC32MZ_UART2 + /* Configure UART2 RX (input) and TX (output) pins */ + + putreg32(BOARD_U2RX_PPS, PIC32MZ_U2RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U2TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U2TX_PPS)); + +#ifdef CONFIG_UART2_OFLOWCONTROL + /* Configure the UART2 CTS input pin */ + + putreg32(BOARD_U2CTS_PPS, PIC32MZ_U2CTSR); +#endif +#ifdef CONFIG_UART2_IFLOWCONTROL + /* Configure the UART2 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U2RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U2RTS_PPS)); + +#endif /* CONFIG_UART2_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART2 */ + +#ifdef CONFIG_PIC32MZ_UART3 + /* Configure UART3 RX (input) and TX (output) pins */ + + putreg32(BOARD_U3RX_PPS, PIC32MZ_U3RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U3TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U3TX_PPS)); + +#ifdef CONFIG_UART3_OFLOWCONTROL + /* Configure the UART3 CTS input pin */ + + putreg32(BOARD_U3CTS_PPS, PIC32MZ_U3CTSR); +#endif +#ifdef CONFIG_UART3_IFLOWCONTROL + /* Configure the UART3 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U3RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U3RTS_PPS)); + +#endif /* CONFIG_UART3_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART3 */ + +#ifdef CONFIG_PIC32MZ_UART4 + /* Configure UART4 RX (input) and TX (output) pins */ + + putreg32(BOARD_U4RX_PPS, PIC32MZ_U4RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U4TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U4TX_PPS)); + +#ifdef CONFIG_UART4_OFLOWCONTROL + /* Configure the UART4 CTS input pin */ + + putreg32(BOARD_U4CTS_PPS, PIC32MZ_U4CTSR); +#endif +#ifdef CONFIG_UART4_IFLOWCONTROL + /* Configure the UART4 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U4RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U4RTS_PPS)); + +#endif /* CONFIG_UART4_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART4 */ + +#ifdef CONFIG_PIC32MZ_UART5 + /* Configure UART5 RX (input) and TX (output) pins */ + + putreg32(BOARD_U5RX_PPS, PIC32MZ_U5RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U5TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U5TX_PPS)); + +#ifdef CONFIG_UART5_OFLOWCONTROL + /* Configure the UART5 CTS input pin */ + + putreg32(BOARD_U5CTS_PPS, PIC32MZ_U5CTSR); +#endif +#ifdef CONFIG_UART5_IFLOWCONTROL + /* Configure the UART5 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U5RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U5RTS_PPS)); + +#endif /* CONFIG_UART5_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART5 */ + +#ifdef CONFIG_PIC32MZ_UART6 + /* Configure UART6 RX (input) and TX (output) pins */ + + putreg32(BOARD_U6RX_PPS, PIC32MZ_U6RXR); + putreg32(PPS_OUTPUT_REGVAL(BOARD_U6TX_PPS), + PPS_OUTPUT_REGADDR(BOARD_U6TX_PPS)); + +#ifdef CONFIG_UART6_OFLOWCONTROL + /* Configure the UART6 CTS input pin */ + + putreg32(BOARD_U6CTS_PPS, PIC32MZ_U6CTSR); +#endif +#ifdef CONFIG_UART6_IFLOWCONTROL + /* Configure the UART6 RTS output pin */ + + putreg32(PPS_OUTPUT_REGVAL(BOARD_U6RTS_PPS), + PPS_OUTPUT_REGADDR(BOARD_U6RTS_PPS)); + +#endif /* CONFIG_UART6_IFLOWCONTROL */ +#endif /* CONFIG_PIC32MZ_UART6 */ + +#ifdef HAVE_SERIAL_CONSOLE + /* Configure the console uart */ + + pic32mz_uartconfigure(PIC32MZ_CONSOLE_BASE, PIC32MZ_CONSOLE_BAUD, + PIC32MZ_CONSOLE_PARITY, PIC32MZ_CONSOLE_BITS, + PIC32MZ_CONSOLE_2STOP); + +#endif /* HAVE_SERIAL_CONSOLE */ +#endif /* HAVE_UART_DEVICE */ +} + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console. + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait for the transmit buffer not full */ + + while ((pic32mz_getreg(PIC32MZ_CONSOLE_BASE, PIC32MZ_UART_STA_OFFSET) & UART_STA_UTXBF) != 0); + + /* Then write the character to the TX data register */ + + pic32mz_putreg(PIC32MZ_CONSOLE_BASE, PIC32MZ_UART_TXREG_OFFSET, (uint32_t)ch); +#endif +} diff --git a/arch/mips/src/pic32mz/pic32mz-lowconsole.h b/arch/mips/src/pic32mz/pic32mz-lowconsole.h new file mode 100644 index 0000000000000000000000000000000000000000..0fb267997712519b65d74f57757a3dde66554e8e --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-lowconsole.h @@ -0,0 +1,123 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-lowconsole.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWCONSOLE_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWCONSOLE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mz_consoleinit + * + * Description: + * Performs low level initialization of the console UART. This UART done early so + * that the serial console is available for debugging very early in the boot + * sequence. + * + ************************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void pic32mz_consoleinit(void); +#else +# define pic32mz_consoleinit() +#endif + +/**************************************************************************** + * Name: pic32mz_uartreset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartreset(uintptr_t uart_base); +#endif + +/**************************************************************************** + * Name: pic32mz_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartconfigure(uintptr_t uart_base, uint32_t baudrate, + unsigned int parity, unsigned int nbits, bool stop2); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWCONSOLE_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-lowinit.c b/arch/mips/src/pic32mz/pic32mz-lowinit.c new file mode 100644 index 0000000000000000000000000000000000000000..50306ca40c3d2d8849ee225807d209e31b6a854e --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-lowinit.c @@ -0,0 +1,422 @@ +/**************************************************************************** + * arch/mips/src/pic32/pic32mz-lowinit.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/pic32mz-features.h" +#include "chip/pic32mz-prefetch.h" +#include "chip/pic32mz-osc.h" + +#include "pic32mz-config.h" +#include "pic32mz-lowconsole.h" +#include "pic32mz-lowinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Maximum Frequencies ******************************************************/ + +#if CONFIG_PIC32MZ_ECC_OPTION == 3 +# define MAX_FLASH_HZ 83000000 /* Maximum FLASH speed (Hz) without ECC */ +#else +# define MAX_FLASH_HZ 66000000 /* Maximum FLASH speed (Hz) with ECC */ +#endif + +#define MAX_PBCLK 100000000 /* Max peripheral bus speed (Hz) */ +#define MAX_PBCLK7 200000000 /* Max peripheral bus speed (Hz) for PBCLK7 */ + +/* Sanity checks ************************************************************/ + +/* Make sure that the selected clock parameters are sane */ + +#define CALC_SYSCLOCK (((BOARD_PLL_INPUT / BOARD_PLL_IDIV) * BOARD_PLL_MULT) / BOARD_PLL_ODIV) +#if CALC_SYSCLOCK != BOARD_CPU_CLOCK +# error "Bad BOARD_CPU_CLOCK calculcation in board.h" +#endif + +#define CALC_PBCLK1 (CALC_SYSCLOCK / BOARD_PB1DIV) +#if CALC_PBCLK1 != BOARD_PBCLK1 +# error "Bad BOARD_PBCLK1 calculcation in board.h" +#endif + +#if CALC_PBCLK1 > MAX_PBCLK +# error "PBCLK1 exceeds maximum value" +#endif + +#ifdef BOARD_PBCLK2_ENABLE +# define CALC_PBCLK2 (CALC_SYSCLOCK / BOARD_PB2DIV) +# if CALC_PBCLK2 != BOARD_PBCLK2 +# error "Bad BOARD_PBCLK2 calculcation in board.h" +# endif + +# if CALC_PBCLK2 > MAX_PBCLK +# error "PBCLK2 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK3_ENABLE +# define CALC_PBCLK3 (CALC_SYSCLOCK / BOARD_PB3DIV) +# if CALC_PBCLK3 != BOARD_PBCLK3 +# error "Bad BOARD_PBCLK3 calculcation in board.h" +# endif + +# if CALC_PBCLK3 > MAX_PBCLK +# error "PBCLK3 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK4_ENABLE +# define CALC_PBCLK4 (CALC_SYSCLOCK / BOARD_PB4DIV) +# if CALC_PBCLK4 != BOARD_PBCLK4 +# error "Bad BOARD_PBCLK4 calculcation in board.h" +# endif + +# if CALC_PBCLK4 > MAX_PBCLK +# error "PBCLK4 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK5_ENABLE +# define CALC_PBCLK5 (CALC_SYSCLOCK / BOARD_PB5DIV) +# if CALC_PBCLK5 != BOARD_PBCLK5 +# error "Bad BOARD_PBCLK5 calculcation in board.h" +# endif + +# if CALC_PBCLK5 > MAX_PBCLK +# error "PBCLK5 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK6_ENABLE +# define CALC_PBCLK6 (CALC_SYSCLOCK / BOARD_PB6DIV) +# if CALC_PBCLK6 != BOARD_PBCLK6 +# error "Bad BOARD_PBCLK6 calculcation in board.h" +# endif + +# if CALC_PBCLK6 > MAX_PBCLK +# error "PBCLK6 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK7_ENABLE +# define CALC_PBCLK7 (CALC_SYSCLOCK / BOARD_PB7DIV) +# if CALC_PBCLK7 != BOARD_PBCLK7 +# error "Bad BOARD_PBCLK7 calculcation in board.h" +# endif + +# if CALC_PBCLK7 > MAX_PBCLK7 +# error "PBCLK7 exceeds maximum value" +# endif +#endif + +#ifdef BOARD_PBCLK8_ENABLE +# define CALC_PBCLK8 (CALC_SYSCLOCK / BOARD_PB8DIV) +# if CALC_PBCLK8 != BOARD_PBCLK8 +# error "Bad BOARD_PBCLK8 calculcation in board.h" +# endif + +# if CALC_PBCLK8 > MAX_PBCLK +# error "PBCLK8 exceeds maximum value" +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_prefetch + * + * Description: + * Configure the prefetch module setting: + * + * 1. The optimal number of FLASH wait states. + * 2. Enable prefetch on CPU instructions and data + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +static inline void pic32mz_prefetch(void) +{ + unsigned int nwaits; + unsigned int residual; + uint32_t regval; + + /* Configure pre-fetch cache FLASH wait states (assuming ECC is enabled). + * REVISIT: Is this calculation right? It seems like residual should be + * + * residual = BOARD_CPU_CLOCK / nwaits + * + * This logic uses: + * + * BOARD_CPU_CLOCK - nwaits * MAX_FLASH_HZ + */ + + residual = BOARD_CPU_CLOCK; + nwaits = 0; + + while (residual > MAX_FLASH_HZ) + { + nwaits++; + residual -= MAX_FLASH_HZ; + } + + DEBUGASSERT(nwaits < 8); + + /* Set the FLASH wait states and enabled prefetch on CPU instructions and + * data. + */ + + regval = (PRECON_PREFEN_CPUID | PRECON_PFMWS(nwaits)); + putreg32(regval, PIC32MZ_PRECON); +} + +/**************************************************************************** + * Name: pic32mz_k0cache + * + * Description: + * Enable caching in KSEG0. + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +static inline void pic32mz_k0cache(void) +{ + register uint32_t regval; + + /* Enable cache on KSEG 0 in the CP0 CONFIG register */ + + asm("\tmfc0 %0,$16,0\n" : "=r"(regval)); + regval &= ~CP0_CONFIG_K23_MASK; + regval |= CP0_CONFIG_K23_CACHEABLE; + asm("\tmtc0 %0,$16,0\n" : : "r" (regval)); + + UNUSED(regval); +} + +/**************************************************************************** + * Name: pic32mz_pbclk + * + * Description: + * Configure peripheral bus clocking + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +static inline void pic32mz_pbclk(void) +{ + uint32_t regval; + + /* Perform the unlock sequence */ + + putreg32(UNLOCK_SYSKEY_0, PIC32MZ_SYSKEY); + putreg32(UNLOCK_SYSKEY_1, PIC32MZ_SYSKEY); + + /* PBCLK1 + * Peripherals: OSC2 pin + * + * NOTES: + * - PBCLK1 is used by system modules and cannot be turned off + * - PBCLK1 divided by 2 is available on the OSC2 pin in certain clock + * modes. + */ + + regval = (PBDIV_ON | PBDIV(BOARD_PB1DIV)); + putreg32(regval, PIC32MZ_PB1DIV); + + /* PBCLK2 + * Peripherals: PMP, I2C, UART, SPI + */ + +#ifdef BOARD_PBCLK2_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB2DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB2DIV); + + /* PBCLK3 + * Peripherals: ADC, Comparator, Timers, Output Compare, Input Compare + * + * NOTES: + * - Timer 1 uses SOSC + */ + +#ifdef BOARD_PBCLK3_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB3DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB3DIV); + +/* PBCLK4 + * Peripherals: Ports + */ + +#ifdef BOARD_PBCLK4_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB4DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB4DIV); + +/* PBCLK5 + * Peripherals: Flash, Crypto, RND, USB, CAN, Ethernet, SQI + * + * NOTES: + * - PBCLK5 is used to fetch data from/to the Flash Controller, while the + * FRC clock is used for programming + */ + +#ifdef BOARD_PBCLK5_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB5DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB5DIV); + +/* PBCLK6 + * Peripherals: + */ + +#ifdef BOARD_PBCLK6_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB6DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB6DIV); + +/* PBCLK7 + * Peripherals: CPU, Deadman timer + */ + +#ifdef BOARD_PBCLK7_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB7DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB7DIV); + +/* PBCLK8 + * Peripherals: EBI + */ + +#ifdef BOARD_PBCLK8_ENABLE + regval = (PBDIV_ON | PBDIV(BOARD_PB8DIV)); +#else + regval = 0; +#endif + putreg32(regval, PIC32MZ_PB8DIV); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_lowinit + * + * Description: + * This performs basic low-level initialization of the system. + * + * Assumptions: + * Interrupts have not yet been enabled. + * + ****************************************************************************/ + +void pic32mz_lowinit(void) +{ + /* Initialize FLASH wait states */ + + pic32mz_prefetch(); + + /* Enable caching in KSEG0 */ + + pic32mz_k0cache(); + + /* Configure peripheral clocking */ + + pic32mz_pbclk(); + + /* Initialize a console (probably a serial console) */ + + pic32mz_consoleinit(); + + /* Perform early serial initialization (so that we will have debug output + * available as soon as possible). + */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Perform board-level initialization */ + + pic32mz_boardinitialize(); +} diff --git a/arch/mips/src/pic32mz/pic32mz-lowinit.h b/arch/mips/src/pic32mz/pic32mz-lowinit.h new file mode 100644 index 0000000000000000000000000000000000000000..369ef9ebb87501238f9eeb8ac9b7b433f1659bc6 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-lowinit.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-lowinit.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWINIT_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mz_lowinit + * + * Description: + * This performs basic low-level initialization of the system. + * + ************************************************************************************/ + +void pic32mz_lowinit(void); + +/************************************************************************************ + * Name: pic32mz_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the directory + * /configs//pic32mz_boot.c. + * + ************************************************************************************/ + +void pic32mz_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_LOWINIT_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-serial.c b/arch/mips/src/pic32mz/pic32mz-serial.c new file mode 100644 index 0000000000000000000000000000000000000000..6845ff50352ecbea62faddbf0122192b8a2d910c --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-serial.c @@ -0,0 +1,1312 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-serial.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mz-config.h" +#include "chip/pic32mz-uart.h" +#include "pic32mz-lowconsole.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART1-6 */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART4 is console */ +# define TTYS0_DEV g_uart5port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart6port /* UART6 is console */ +# define TTYS5_DEV g_uart6port /* UART6 is ttyS0 */ +# define UART6_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_PIC32MZ_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_PIC32MZ_UART2) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_PIC32MZ_UART3) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_PIC32MZ_UART4) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_PIC32MZ_UART4) +# define TTYS0_DEV g_uart5port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_PIC32MZ_UART6) +# define TTYS0_DEV g_uart6port /* UART6 is ttyS0 */ +# define UART6_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART1-5 excluding the console UART. */ + +#if defined(CONFIG_PIC32MZ_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART2) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART3) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART4) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART5) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART6) && !defined(UART6_ASSIGNED) +# define TTYS1_DEV g_uart6port /* UART6 is ttyS1 */ +# define UART6_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART2-6. It can't be UART1 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-6 could also be the + * console. + */ + +#if defined(CONFIG_PIC32MZ_UART2) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART3) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART4) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART5) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART6) && !defined(UART6_ASSIGNED) +# define TTYS2_DEV g_uart6port /* UART6 is ttyS2 */ +# define UART6_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART3-6. It can't be UART1-2 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-6 could also be the console. + */ + +#if defined(CONFIG_PIC32MZ_UART3) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART4) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART5) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART6) && !defined(UART6_ASSIGNED) +# define TTYS3_DEV g_uart6port /* UART6 is ttyS3 */ +# define UART6_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART4-6. It can't be UART1-2 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 3-6 could also be the console. + */ + +#if defined(CONFIG_PIC32MZ_UART4) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART5) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART6) && !defined(UART6_ASSIGNED) +# define TTYS4_DEV g_uart6port /* UART6 is ttyS4 */ +# define UART6_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART5-6. It can't be UART1-3 because + * those have already been assigned to ttsyS0, 1, 2, 3 or 4. One of + * UART 4-6 could also be the console. + */ + +#if defined(CONFIG_PIC32MZ_UART5) && !defined(UART5_ASSIGNED) +# define TTYS5_DEV g_uart5port /* UART5 is ttyS5 */ +# define UART5_ASSIGNED 1 +#elif defined(CONFIG_PIC32MZ_UART6) && !defined(UART6_ASSIGNED) +# define TTYS5_DEV g_uart6port /* UART6 is ttyS5 */ +# define UART6_ASSIGNED 1 +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of up_earlyserialinit(), up_serialinit(), and + * up_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/* These values describe the set of enabled interrupts */ + +#define IE_RX (1 << 0) +#define IE_TX (1 << 1) + +#define RX_ENABLED(im) (((im) & IE_RX) != 0) +#define TX_ENABLED(im) (((im) & IE_TX) != 0) + +#define ENABLE_RX(im) do { (im) |= IE_RX; } while (0) +#define ENABLE_TX(im) do { (im) |= IE_TX; } while (0) + +#define DISABLE_RX(im) do { (im) &= ~IE_RX; } while (0) +#define DISABLE_TX(im) do { (im) &= ~IE_TX; } while (0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + xcpt_t handler; /* UART interrupt handler */ + uint32_t baud; /* Configured baud */ + uint8_t irqe; /* Error IRQ associated with this UART (for enable) */ + uint8_t irqrx; /* RX IRQ associated with this UART (for enable) */ + uint8_t irqtx; /* TX IRQ associated with this UART (for enable) */ + uint8_t im; /* Interrupt mask state */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (5, 6, 7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset); +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im); +static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im); + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); + +static int up_interrupt(struct uart_dev_s *priv); +#ifdef CONFIG_PIC32MZ_UART1 +static int up_uart1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_PIC32MZ_UART2 +static int up_uart2_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_PIC32MZ_UART3 +static int up_uart3_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_PIC32MZ_UART4 +static int up_uart4_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_PIC32MZ_UART5 +static int up_uart5_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_PIC32MZ_UART6 +static int up_uart6_interrupt(int irq, void *context); +#endif + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_PIC32MZ_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MZ_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MZ_UART3 +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MZ_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MZ_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif +#ifdef CONFIG_PIC32MZ_UART6 +static char g_uart6rxbuffer[CONFIG_UART6_RXBUFSIZE]; +static char g_uart6txbuffer[CONFIG_UART6_TXBUFSIZE]; +#endif + +#ifdef CONFIG_PIC32MZ_UART1 +/* This describes the state of the PIC32MZ UART1 port. */ + +static struct up_dev_s g_uart1priv = +{ + .uartbase = PIC32MZ_UART1_K1BASE, + .handler = up_uart1_interrupt, + .baud = CONFIG_UART1_BAUD, + .irqe = PIC32MZ_IRQ_U1E, + .irqrx = PIC32MZ_IRQ_U1RX, + .irqtx = PIC32MZ_IRQ_U1TX, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +#ifdef CONFIG_PIC32MZ_UART2 +/* This describes the state of the PIC32MZ UART2 port. */ + +static struct up_dev_s g_uart2priv = +{ + .uartbase = PIC32MZ_UART2_K1BASE, + .handler = up_uart2_interrupt, + .baud = CONFIG_UART2_BAUD, + .irqe = PIC32MZ_IRQ_U2E, + .irqrx = PIC32MZ_IRQ_U2RX, + .irqtx = PIC32MZ_IRQ_U2TX, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +#ifdef CONFIG_PIC32MZ_UART3 +/* This describes the state of the PIC32MZ UART3 port. */ + +static struct up_dev_s g_uart3priv = +{ + .uartbase = PIC32MZ_UART3_K1BASE, + .handler = up_uart3_interrupt, + .baud = CONFIG_UART3_BAUD, + .irqe = PIC32MZ_IRQ_U3E, + .irqrx = PIC32MZ_IRQ_U3RX, + .irqtx = PIC32MZ_IRQ_U3TX, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stopbits2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +#ifdef CONFIG_PIC32MZ_UART4 +/* This describes the state of the PIC32MZ UART4 port. */ + +static struct up_dev_s g_uart4priv = +{ + .uartbase = PIC32MZ_UART4_K1BASE, + .handler = up_uart4_interrupt, + .baud = CONFIG_UART4_BAUD, + .irqe = PIC32MZ_IRQ_U4E, + .irqrx = PIC32MZ_IRQ_U4RX, + .irqtx = PIC32MZ_IRQ_U4TX, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +#ifdef CONFIG_PIC32MZ_UART5 +/* This describes the state of the PIC32MZ UART5 port. */ + +static struct up_dev_s g_uart5priv = +{ + .uartbase = PIC32MZ_UART5_K1BASE, + .handler = up_uart5_interrupt, + .baud = CONFIG_UART5_BAUD, + .irqe = PIC32MZ_IRQ_U5E, + .irqrx = PIC32MZ_IRQ_U5RX, + .irqtx = PIC32MZ_IRQ_U5TX, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +}; + +static uart_dev_t g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +#ifdef CONFIG_PIC32MZ_UART6 +/* This describes the state of the PIC32MZ UART6 port. */ + +static struct up_dev_s g_uart6priv = +{ + .uartbase = PIC32MZ_UART6_K1BASE, + .handler = up_uart6_interrupt, + .baud = CONFIG_UART6_BAUD, + .irqe = PIC32MZ_IRQ_U6E, + .irqrx = PIC32MZ_IRQ_U6RX, + .irqtx = PIC32MZ_IRQ_U6TX, + .parity = CONFIG_UART6_PARITY, + .bits = CONFIG_UART6_BITS, + .stopbits2 = CONFIG_UART6_2STOP, +}; + +static uart_dev_t g_uart6port = +{ + .recv = + { + .size = CONFIG_UART6_RXBUFSIZE, + .buffer = g_uart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART6_TXBUFSIZE, + .buffer = g_uart6txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart6priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in im */ + + flags = enter_critical_section(); + up_rxint(dev, RX_ENABLED(im)); + up_txint(dev, TX_ENABLED(im)); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (im) + { + *im = priv->im; + } + up_restoreuartint(dev, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Configure the UART as an RS-232 UART */ + + pic32mz_uartconfigure(priv->uartbase, priv->baud, priv->parity, + priv->bits, priv->stopbits2); +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(dev, NULL); + + /* Reset hardware and disable Rx and Tx */ + + pic32mz_uartreset(priv->uartbase); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach the IRQs */ + + ret = irq_attach(priv->irqrx, priv->handler); + if (ret == 0) + { + ret = irq_attach(priv->irqtx, priv->handler); + } + + if (ret == 0) + { + ret = irq_attach(priv->irqe, priv->handler); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(dev, NULL); + + /* Detach from the interrupt */ + + irq_detach(priv->irqrx); + irq_detach(priv->irqtx); + irq_detach(priv->irqe); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the common UART interrupt handler. It will be invoked when an + * interrupt received on a specific UART. It should call + * uart_transmitchars or uart_receivechar to perform the appropriate data + * transfers. + * + ****************************************************************************/ + +static int up_interrupt(struct uart_dev_s *dev) +{ + struct up_dev_s *priv; + int passes; + bool handled; + + DEBUGASSERT(dev && dev->priv); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Handle error interrupts. This interrupt occurs when any of the + * following error conditions take place: + * - Parity error PERR (UxSTA bit 3) is detected + * - Framing Error FERR (UxSTA bit 2) is detected + * - Overflow condition for the receive buffer OERR (UxSTA bit 1) occurs + */ + +#ifdef CONFIG_DEBUG + if (up_pending_irq(priv->irqe)) + { + /* Clear the pending error interrupt */ + + up_clrpend_irq(priv->irqe); + lldbg("ERROR: interrupt STA: %08x\n", + up_serialin(priv, PIC32MZ_UART_STA_OFFSET)); + handled = true; + } +#endif + + /* Handle incoming, received bytes. The RX FIFO is configured to + * interrupt when the RX FIFO is 75% full (that is 6 of 8 for 8-deep + * FIFOs or 3 of 4 for 4-deep FIFOS. + */ + + if (up_pending_irq(priv->irqrx)) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + handled = true; + + /* Clear the pending RX interrupt if the receive buffer is empty. + * Note that interrupts can be lost if the interrupt condition is + * still true when the interrupt is cleared. Keeping the RX + * interrupt pending too long is not a problem because the + * upper half driver will disable RX interrupts if it no + * longer has space to buffer the serial data. + */ + + if ((up_serialin(priv, PIC32MZ_UART_STA_OFFSET) & UART_STA_URXDA) == 0) + { + up_clrpend_irq(priv->irqrx); + } + } + + /* Handle outgoing, transmit bytes The RT FIFO is configured to + * interrupt only when the TX FIFO is empty. There are not many + * options on trigger TX interrupts. The FIFO-not-full might generate + * better through-put but with a higher interrupt rate. FIFO-empty should + * lower the interrupt rate but result in a burstier output. If + * you change this, You will probably need to change the conditions for + * clearing the pending TX interrupt below. + * + * NOTE: When I tried using the FIFO-not-full interrupt trigger, I + * had either lost interrupts, or else a window where I might get + * infinite interrupts. The problem is that there is a race condition + * with trying to clearing the pending interrupt based on the FIFO + * full condition. + */ + + if (up_pending_irq(priv->irqtx)) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + + /* Clear the pending TX interrupt if the TX FIFO is empty. + * Note that interrupts can be lost if the interrupt condition is + * still true when the interrupt is cleared. Keeping the TX + * interrupt pending too long is not a problem: Upper level logic + * will disable the TX interrupt when there is no longer anything + * to be sent. + */ + + if ((up_serialin(priv, PIC32MZ_UART_STA_OFFSET) & UART_STA_UTRMT) != 0) + { + up_clrpend_irq(priv->irqtx); + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_uartn_interrupt + * + * Description: + * These the UART-specific interrupt handlers. They simply invoke the + * common uart interrupt handler with the correct state data. + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_UART1 +static int up_uart1_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart1port); +} +#endif + +#ifdef CONFIG_PIC32MZ_UART2 +static int up_uart2_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart2port); +} +#endif + +#ifdef CONFIG_PIC32MZ_UART3 +static int up_uart3_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart3port); +} +#endif + +#ifdef CONFIG_PIC32MZ_UART4 +static int up_uart4_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart4port); +} +#endif + +#ifdef CONFIG_PIC32MZ_UART5 +static int up_uart5_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart5port); +} +#endif +#ifdef CONFIG_PIC32MZ_UART6 +static int up_uart6_interrupt(int irq, void *context) +{ + return up_interrupt(&g_uart6port); +} +#endif + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + struct inode *inode; + struct uart_dev_s *dev; + struct up_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct up_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that only cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used besued we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + pic32mz_uartconfigure(priv->uartbase, priv->baud, priv->parity, + priv->bits, priv->stopbits2); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Then return the actual received byte */ + + return (int)(up_serialin(priv, PIC32MZ_UART_RXREG_OFFSET) & UART_RXREG_MASK); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint8_t im; + + flags = enter_critical_section(); + im = priv->im; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_DEBUG + up_enable_irq(priv->irqe); +#endif + up_enable_irq(priv->irqrx); + ENABLE_RX(im); +#endif + } + else + { +#ifdef CONFIG_DEBUG + up_disable_irq(priv->irqe); +#endif + up_disable_irq(priv->irqrx); + DISABLE_RX(im); + } + priv->im = im; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + return (up_serialin(priv, PIC32MZ_UART_STA_OFFSET) & UART_STA_URXDA) != 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, PIC32MZ_UART_TXREG_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + uint8_t im; + + flags = enter_critical_section(); + im = priv->im; + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->irqtx); + ENABLE_TX(im); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_disable_irq(priv->irqtx); + DISABLE_TX(im); + } + + priv->im = im; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the Transmit buffer register is not full */ + + return (up_serialin(priv, PIC32MZ_UART_STA_OFFSET) & UART_STA_UTXBF) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the Transmit shift register is empty */ + + return (up_serialin(priv, PIC32MZ_UART_STA_OFFSET) & UART_STA_UTRMT) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mz_consoleinit(). + */ + + up_disableuartint(&TTYS0_DEV, NULL); +#ifdef TTYS1_DEV + up_disableuartint(&TTYS1_DEV, NULL); +#endif +#ifdef TTYS2_DEV + up_disableuartint(&TTYS2_DEV, NULL); +#endif +#ifdef TTYS3_DEV + up_disableuartint(&TTYS3_DEV, NULL); +#endif +#ifdef TTYS4_DEV + up_disableuartint(&TTYS4_DEV, NULL); +#endif +#ifdef TTYS5_DEV + up_disableuartint(&TTYS5_DEV, NULL); +#endif +#ifdef TTYS6_DEV + up_disableuartint(&TTYS6_DEV, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif +#ifdef TTYS6_DEV + (void)uart_register("/dev/ttyS6", &TTYS6_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct uart_dev_s *dev = (struct uart_dev_s *)&CONSOLE_DEV; + uint8_t imr; + + up_disableuartint(dev, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreuartint(dev, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: up_earlyserialinit, up_serialinit, and up_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/up_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ +#else /* HAVE_UART_DEVICE */ +void up_earlyserialinit(void) +{ +} + +void up_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ + diff --git a/arch/mips/src/pic32mz/pic32mz-spi.c b/arch/mips/src/pic32mz/pic32mz-spi.c new file mode 100644 index 0000000000000000000000000000000000000000..d2f83fb2927e562e56db396d78943f30a7af2408 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-spi.c @@ -0,0 +1,1392 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-spi.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip/pic32mz-spi.h" +#include "chip/pic32mz-pps.h" +#include "pic32mz-spi.h" + +#ifdef CONFIG_PIC32MZ_SPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* All SPI peripherals are clocked by PBCLK2 */ + +#define BOARD_PBCLOCK BOARD_PBCLK2 + +/* Debug */ + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure describes the fixed (ROM-able) configuration of the SPI + * peripheral. + */ + +struct pic32mz_config_s +{ + uint32_t base; /* SPI register base address */ +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + uint8_t firq; /* SPI fault interrupt number */ + uint8_t rxirq; /* SPI receive done interrupt number */ + uint8_t txirq; /* SPI transfer done interrupt number */ +#endif + uint8_t sdipps; /* SDI peripheral pin selection */ + uint8_t sdopps; /* SDO peripheral pin selection */ + uintptr_t sdoreg; /* SDO peripheral pin configuration register */ +}; + +/* This structure describes the state of the SPI driver */ + +struct pic32mz_dev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + FAR const struct pic32mz_config_s *config; + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t mode; /* Mode 0,1,2,3 */ + uint8_t nbits; /* Width of word in bits (8 to 16) */ + +#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Low-level register access */ + +#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG +static bool spi_checkreg(FAR struct pic32mz_dev_s *priv, + uintptr_t regaddr, uint32_t regvaql, bool wr); +static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset); +static void spi_putaddr(FAR struct pic32mz_dev_s *priv, + uintptr_t regaddr, uint32_t value); +#else +static inline uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset); +static inline void spi_putaddr(FAR struct pic32mz_dev_s *priv, + uintptr_t regaddr, uint32_t value); +#endif +static inline void spi_putreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset, uint32_t value); +static void spi_exchange16(FAR struct pic32mz_dev_s *priv, + FAR const uint16_t *txbuffer, FAR uint16_t *rxbuffer, + size_t nwords); +static void spi_exchange8(FAR struct pic32mz_dev_s *priv, + FAR const uint8_t *txbuffer, FAR uint8_t *rxbuffer, + size_t nbytes); + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI1 + +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = pic32mz_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = pic32mz_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi1config = +{ + .base = PIC32MZ_SPI1_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI1F, + .rxirq = PIC32MZ_IRQ_SPI1RX, + .txirq = PIC32MZ_IRQ_SPI1TX, +#endif + .sdipps = BOARD_SDI1_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO1_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO1_PPS), +}; + +static struct pic32mz_dev_s g_spi1dev = +{ + .spidev = { &g_spi1ops }, + .config = &g_spi1config, +}; +#endif + +#ifdef CONFIG_PIC32MZ_SPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = pic32mz_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mz_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi2register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi2config = +{ + .base = PIC32MZ_SPI2_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI2F, + .rxirq = PIC32MZ_IRQ_SPI2RX, + .txirq = PIC32MZ_IRQ_SPI2TX, +#endif + .sdipps = BOARD_SDI2_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO2_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO2_PPS), +}; + +static struct pic32mz_dev_s g_spi2dev = +{ + .spidev = { &g_spi2ops }, + .config = &g_spi2config, +}; +#endif + +#ifdef CONFIG_PIC32MZ_SPI3 +static const struct spi_ops_s g_spi3ops = +{ + .lock = spi_lock, + .select = pic32mz_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mz_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi3register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi3config = +{ + .base = PIC32MZ_SPI3_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI3F, + .rxirq = PIC32MZ_IRQ_SPI3RX, + .txirq = PIC32MZ_IRQ_SPI3TX, +#endif + .sdipps = BOARD_SDI3_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO3_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO3_PPS), +}; + +static struct pic32mz_dev_s g_spi3dev = +{ + .spidev = { &g_spi3ops }, + .config = &g_spi3config, +}; +#endif + +#ifdef CONFIG_PIC32MZ_SPI4 +static const struct spi_ops_s g_spi4ops = +{ + .lock = spi_lock, + .select = pic32mz_spi4select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mz_spi4status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi4cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi4register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi4config = +{ + .base = PIC32MZ_SPI4_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI4F, + .rxirq = PIC32MZ_IRQ_SPI4RX, + .txirq = PIC32MZ_IRQ_SPI4TX, +#endif + .sdipps = BOARD_SDI4_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO4_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO4_PPS), +}; + +static struct pic32mz_dev_s g_spi4dev = +{ + .spidev = { &g_spi4ops }, + .config = &g_spi4config, +}; +#endif + +#ifdef CONFIG_PIC32MZ_SPI5 +static const struct spi_ops_s g_spi5ops = +{ + .lock = spi_lock, + .select = pic32mz_spi5select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mz_spi5status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi5cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi5register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi5config = +{ + .base = PIC32MZ_SPI5_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI5F, + .rxirq = PIC32MZ_IRQ_SPI5RX, + .txirq = PIC32MZ_IRQ_SPI5TX, +#endif + .sdipps = BOARD_SDI5_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO5_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO5_PPS), +}; + +static struct pic32mz_dev_s g_spi5dev = +{ + .spidev = { &g_spi5ops }, + .config = &g_spi5config, +}; +#endif + +#ifdef CONFIG_PIC32MZ_SPI6 +static const struct spi_ops_s g_spi6ops = +{ + .lock = spi_lock, + .select = pic32mz_spi6select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = pic32mz_spi6status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = pic32mz_spi6cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = pic32mz_spi6register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static const struct pic32mz_config_s g_spi6config = +{ + .base = PIC32MZ_SPI6_K1BASE, +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + .firq = PIC32MZ_IRQ_SPI6F, + .rxirq = PIC32MZ_IRQ_SPI6RX, + .txirq = PIC32MZ_IRQ_SPI6TX, +#endif + .sdipps = BOARD_SDI6_PPS, + .sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO6_PPS), + .sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO6_PPS), +}; + +static struct pic32mz_dev_s g_spi6dev = +{ + .spidev = { &g_spi6ops }, + .config = &g_spi6config, +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * priv - SPI driver instance + * regaddr - The address of the register to write to + * regval - The value to be written + * wr - True: write access + * + * Returned Value: + * true: This is the first register access of this type. + * false: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG +static bool spi_checkreg(struct pic32mz_dev_s *priv, uintptr_t regaddr, + uint32_t regval, bool wr) +{ + if (wr == priv->wrlast && /* Same kind of access? */ + regval == priv->vallast && /* Same value? */ + regaddr == priv->addrlast) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wrlast = wr; + priv->vallast = regval; + priv->addrlast = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Return the contents of one, 32-bit SPI register + * + * Input Parameters: + * priv - A pointer to a PIC32MZ SPI state structure + * offset - Offset from the SPI base address to the register of interest + * + * Returned Value: + * The current contents of the register + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG +static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset) +{ + uintptr_t regaddr; + uint32_t regval; + + /* Read the register value */ + + regaddr = priv->config->base + offset; + regval = getreg32(regaddr); + + /* Should we print something? */ + + if (spi_checkreg(priv, regaddr, regval, false)) + { + /* Yes.. */ + + lldbg("%08lx->%08lx\n", + (unsigned long)regaddr, (unsigned long)regval); + } + + /* Return the value read */ + + return regval; +} +#else +static inline uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset) +{ + return getreg32(priv->config->base + offset); +} +#endif + +/**************************************************************************** + * Name: spi_putaddr + * + * Description: + * Write a 32-bit value value an absolute address + * + * Input Parameters: + * priv - A pointer to a PIC32MZ SPI state structure + * regaddr - Address to write to + * regval - The value to write to the SPI register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG +static void spi_putaddr(FAR struct pic32mz_dev_s *priv, uintptr_t regaddr, + uint32_t regval) +{ + /* Should we print something? */ + + if (spi_checkreg(priv, regaddr, regval, true)) + { + /* Yes.. */ + + lldbg("%08lx<-%08lx\n", + (unsigned long)regaddr, (unsigned long)regval); + } + + /* Write the value to the register */ + + putreg32(regval, regaddr); +} +#else +static inline void spi_putaddr(FAR struct pic32mz_dev_s *priv, + uintptr_t regaddr, uint32_t regval) +{ + /* Write the value to the register */ + + putreg32(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a value to one, 32-bit SPI register + * + * Input Parameters: + * priv - A pointer to a PIC32MZ SPI state structure + * offset - Offset from the SPI base address to the register of interest + * value - The value to write to the SPI register + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_putreg(FAR struct pic32mz_dev_s *priv, + unsigned int offset, uint32_t regval) +{ + spi_putaddr(priv, priv->config->base + offset, regval); +} + +/**************************************************************************** + * Name: spi_exchange8 + * + * Description: + * Exchange a block of 8-bit data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of byres that to be exchanged + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_exchange8(FAR struct pic32mz_dev_s *priv, + FAR const uint8_t *txbuffer, FAR uint8_t *rxbuffer, + size_t nbytes) +{ + uint32_t regval; + uint8_t data; + + spivdbg("nbytes: %d\n", nbytes); + while (nbytes) + { + /* Write the data to transmitted to the SPI Data Register */ + + if (txbuffer) + { + data = *txbuffer++; + } + else + { + data = 0xff; + } + + spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)data); + +#ifdef CONFIG_PIC32MZ_SPI_ENHBUF + /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In + * enhanced buffer mode, the SPIRBE bit will be cleared in when the + * receive buffer is not empty. + */ + + while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0); +#else + /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In + * normal mode, the SPIRBF bit will be set when receive data is available. + */ + + while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0); +#endif + + /* Read from the buffer register to clear the status bit */ + + regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET); + if (rxbuffer) + { + *rxbuffer++ = (uint8_t)regval; + } + else + { + UNUSED(regval); + } + + nbytes--; + } +} + +/**************************************************************************** + * Name: spi_exchange16 + * + * Description: + * Exchange a block of 16-bit data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_exchange16(FAR struct pic32mz_dev_s *priv, + FAR const uint16_t *txbuffer, + FAR uint16_t *rxbuffer, size_t nwords) +{ + uint32_t regval; + uint16_t data; + + spivdbg("nwords: %d\n", nwords); + while (nwords) + { + /* Write the data to transmitted to the SPI Data Register */ + + if (txbuffer) + { + data = *txbuffer++; + } + else + { + data = 0xffff; + } + + spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)data); + +#ifdef CONFIG_PIC32MZ_SPI_ENHBUF + /* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In + * enhanced buffer mode, the SPIRBE bit will be cleared in when the + * receive buffer is not empty. + */ + + while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0); +#else + /* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In + * normal mode, the SPIRBF bit will be set when receive data is available. + */ + + while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0); +#endif + + /* Read from the buffer register to clear the status bit */ + + regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET); + if (rxbuffer) + { + *rxbuffer++ = (uint16_t)regval; + } + else + { + UNUSED(regval); + } + + nwords--; + } +} + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + uint32_t divisor; + uint32_t actual; + uint32_t regval; + + spivdbg("Old frequency: %d actual: %d New frequency: %d\n", + priv->frequency, priv->actual, frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* Calculate the divisor + * + * frequency = BOARD_PBCLOCK / (2 * divisor), or + * divisor = (BOARD_PBCLOCK / 2) / frequency + */ + + divisor = (BOARD_PBCLOCK / 2) / frequency; + + /* The a BRG register value is that divisor minus one + * + * frequency = BOARD_PBCLOCK /(2 * (BRG + 1)), or + * BRG = (BOARD_PBCLOCK / 2) / frequency - 1 + */ + + regval = divisor; + if (regval > 0) + { + regval--; + } + + /* Save the new BRG value */ + + spi_putreg(priv, PIC32MZ_SPI_BRG_OFFSET, regval); + spivdbg("PBCLOCK: %d frequency: %d divisor: %d BRG: %d\n", + BOARD_PBCLOCK, frequency, divisor, regval); + + /* Calculate the new actual frequency. + * + * frequency = BOARD_PBCLOCK / (2 * divisor) + */ + + actual = (BOARD_PBCLOCK / 2) / divisor; + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("New frequency: %d Actual: %d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + uint32_t regval; + + spivdbg("Old mode: %d New mode: %d\n", priv->mode, mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CON register appropriately. + * + * Standard terminology is as follows: + * + * Mode CPOL CPHA + * 0 0 0 + * 1 0 1 + * 2 1 0 + * 3 1 1 + * + * CPOL=0: The inactive value of the clock is zero + * CPOL=1: The inactive value of the clock is one + * CPHA=0: Data is captured on the clock's inactive-to-active edge and + * data is propagated on a active-to-inactive edge. + * CPHA=1: Data is captured on the clock's active-to-inactive edge and + * data is propagated on a active-to-inactive edge. + * + * CON Register mapping: + * CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1 + * CPHA=0 corresponds to CON:CKE=1; CPHA=1 corresponds to CON:CKE=1 + * + * In addition, the CON register supports SMP: SPI Data Input Sample + * Phase bit: + * + * 1 = Input data sampled at end of data output time + * 0 = Input data sampled at middle of data output time + * + * Which is hardcoded to 1. + */ + + regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET); + regval &= ~(SPI_CON_CKP | SPI_CON_CKE); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + regval |= SPI_CON_CKE; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + regval |= SPI_CON_CKP; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + regval |= (SPI_CON_CKP | SPI_CON_CKE); + break; + + default: + DEBUGASSERT(FALSE); + return; + } + + spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval); + spivdbg("CON: %08x\n", regval); + + /* Save the mode so that subsequent re-configuratins will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + uint32_t setting; + uint32_t regval; + + spivdbg("Old nbits: %d New nbits: %d\n", priv->nbits, nbits); + + /* Has the number of bits changed? */ + + DEBUGASSERT(priv && nbits > 7 && nbits < 17); + if (nbits != priv->nbits) + { + /* Yes... Set the CON register appropriately */ + + if (nbits == 8) + { + setting = SPI_CON_MODE_8BIT; + } + else if (nbits == 16) + { + setting = SPI_CON_MODE_8BIT; + } + else if (nbits == 32) + { + setting = SPI_CON_MODE_8BIT; + } + else + { + spidbg("Unsupported nbits: %d\n", nbits); + return; + } + + regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET); + regval &= ~SPI_CON_MODE_MASK; + regval |= setting; + regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET); + spivdbg("CON: %08x\n", regval); + + /* Save the selection so the subsequence re-configurations will be + * faster + */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + + DEBUGASSERT(priv); + if (priv->nbits > 8) + { + uint16_t txword; + uint16_t rxword; + + /* spi_exchange16() can do this. */ + + txword = wd; + rxword = 0; + spi_exchange16(priv, &txword, &rxword, 1); + + spivdbg("Sent %04x received %04x\n", txword, rxword); + return rxword; + } + else + { + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange8() can do this. */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange8(priv, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; + } +} + +/**************************************************************************** + * Name: spi_exchange + * + * Description: + * Exchange a block of data from SPI.. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev; + + DEBUGASSERT(priv); + if (priv->nbits > 8) + { + /* spi_exchange16() can do this. */ + + spi_exchange16(priv, (FAR const uint16_t *)txbuffer, + (FAR uint16_t *)rxbuffer, nwords); + } + else + { + /* spi_exchange8() can do this. */ + + spi_exchange8(priv, (FAR const uint8_t *)txbuffer, + (FAR uint8_t *)rxbuffer, nwords); + } +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of + * words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + /* spi_exchange() can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + /* spi_exchange() can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *pic32mz_spibus_initialize(int port) +{ + FAR struct pic32mz_dev_s *priv; + uintptr_t regaddr; + irqstate_t flags; + uint32_t regval; + + spivdbg("port: %d\n", port); + + /* Select the SPI state structure and SDI PPS register for this port */ + +#ifdef CONFIG_PIC32MZ_SPI1 + if (port == 1) + { + priv = &g_spi1dev; + regaddr = PIC32MZ_SDI1R; + } + else +#endif +#ifdef CONFIG_PIC32MZ_SPI2 + if (port == 2) + { + priv = &g_spi2dev; + regaddr = PIC32MZ_SDI2R; + } + else +#endif +#ifdef CONFIG_PIC32MZ_SPI3 + if (port == 3) + { + priv = &g_spi3dev; + regaddr = PIC32MZ_SDI3R; + } + else +#endif +#ifdef CONFIG_PIC32MZ_SPI4 + if (port == 4) + { + priv = &g_spi4dev; + regaddr = PIC32MZ_SDI4R; + } + else +#endif +#ifdef CONFIG_PIC32MZ_SPI5 + if (port == 5) + { + priv = &g_spi5dev; + regaddr = PIC32MZ_SDI5R; + } + else +#endif +#ifdef CONFIG_PIC32MZ_SPI6 + if (port == 6) + { + priv = &g_spi6dev; + regaddr = PIC32MZ_SDI6R; + } + else +#endif + { + spidbg("Unsuppport port: %d\n", port); + return NULL; + } + + /* Disable SPI interrupts */ + + flags = enter_critical_section(); +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + up_disable_irq(priv->config->firq); + up_disable_irq(priv->config->rxirq); + up_disable_irq(priv->config->txirq); +#endif + + /* Stop and reset the SPI module by clearing the ON bit in the CON register. */ + + spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, 0); + + /* Clear the receive buffer by reading from the BUF register */ + + regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET); + + /* Configure SPI SDI (input) and SDO (output) pins. SS (output) pins are + * managed as GPIOs; CLK (output) pins are not selectable. + */ + + spi_putaddr(priv, regaddr, (uint32_t)priv->config->sdipps); + spi_putaddr(priv, priv->config->sdoreg, (uint32_t)priv->config->sdopps); + +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + /* Attach the interrupt handlers. We do this early to make sure that the + * resources are available. + */ + + ret = irq_attach(priv->config->rxirq, spi_interrupt); + if (ret < 0) + { + spidbg("Failed to attach RX interrupt: %d port: %d\n", + priv->config->rxirq, port); + goto errout; + } + + ret = irq_attach(priv->config->txirq, spi_interrupt); + if (ret < 0) + { + spidbg("Failed to attach TX interrupt: %d port: %d\n", + priv->tconfig->xirq, port); + goto errout_with_rxirq; + } + + ret = irq_attach(priv->config->firq, spi_interrupt); + if (ret < 0) + { + spidbg("Failed to attach fault interrupt: %d port: %d\n", + priv->config->firq, port); + goto errout_with_txirq; + } +#endif + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Clear the SPIROV overflow bit (SPIxSTAT:6). */ + + spi_putreg(priv, PIC32MZ_SPI_STATCLR_OFFSET, SPI_STAT_SPIROV); + + /* Initial settings 8 bit + master mode + mode 0. NOTE that MSSEN + * not set: The slave select pin must be driven manually via the + * board-specific pic32mz_spiNselect() interface. + */ + + regval = (SPI_CON_MSTEN | SPI_CON_SMP | SPI_CON_MODE_8BIT | SPI_CON_ON); + + /* Set the ENHBUF bit if using Enhanced Buffer mode. */ + +#ifdef CONFIG_PIC32MZ_SPI_ENHBUF + regval |= (SPI_CON_ENHBUF | SPI_CON_SRXISEL_HALF | SPI_CON_STXISEL_HALF); +#endif + spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval); + spivdbg("CON: %08x\n", regval); + + /* Set the initial SPI configuration */ + + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS + /* Enable interrupts at the SPI controller */ + + up_enable_irq(priv->config->firq); + up_enable_irq(priv->config->rxirq); + up_enable_irq(priv->config->txirq); +#endif + + /* Enable interrupts at the interrupt controller */ + + leave_critical_section(flags); + return &priv->spidev; + +#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS +errout_with_txirq: + irq_detatch(priv->config->txirq); +errout_with_rxirq: + irq_detatch(priv->config->rxirq); +errout: + leave_critical_section(flags); + return NULL; +#endif +} + +#endif /* CONFIG_PIC32MZ_SPI */ diff --git a/arch/mips/src/pic32mz/pic32mz-spi.h b/arch/mips/src/pic32mz/pic32mz-spi.h new file mode 100644 index 0000000000000000000000000000000000000000..f908f63b7c2ebe14b5870780fbdbaff3b57722b9 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-spi.h @@ -0,0 +1,180 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-spi.h + * + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_SPI_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/**************************************************************************** + * Name: pic32mz_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *pic32mz_spibus_initialize(int port); + +/************************************************************************************ + * Name: pic32mz_spiNselect, pic32mz_spiNstatus, and pic32mz_spiNcmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including pic32mz_spibus_initialize()) are provided by common PIC32MZ logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in pic32mz_boardinitialize() to configure SPI/SSP chip select + * pins. + * 2. Provide pic32mz_spiNselect() and pic32mz_spiNstatus() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * pic32mz_spiNcmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to pic32mz_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by pic32mz_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI1 +void pic32mz_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MZ_SPI2 +void pic32mz_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MZ_SPI3 +void pic32mz_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MZ_SPI4 +void pic32mz_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi4cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MZ_SPI5 +void pic32mz_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi5status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi5cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#ifdef CONFIG_PIC32MZ_SPI6 +void pic32mz_spi6select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +uint8_t pic32mz_spi6status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi6cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_SPI_H */ diff --git a/arch/mips/src/pic32mz/pic32mz-timerisr.c b/arch/mips/src/pic32mz/pic32mz-timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..cbbdf886caee5e349bc737da27f4c85510789367 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-timerisr.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz_timerisr.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "pic32mz-config.h" +#include "chip/pic32mz-timer.h" +#include "chip/pic32mz-int.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Timer Setup **************************************************************/ +/* Timer 1 is a type A timer. Setting the TCS bit in the timer control + * register will select the SOSC as the clock source. Otherwise, PBCLK3 + * is the clock source. + */ + +#ifdef CONFIG_PIC32MZ_T1_SOSC +# define TIMER1_SRC_FREQ BOARD_SOSC_FREQ +# define TIMER1_CON_TCS TIMER_CON_TCS +#else +# define TIMER1_SRC_FREQ BOARD_PBCLK3 +# define TIMER1_CON_TCS (0) +#endif + +/* Select a timer 1 prescale value. Our goal is to select the timer MATCH + * register value given the timer 1 input clock frequency and the desired + * system timer frequency: + * + * TIMER1_MATCH = TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC + * + * We want the largest possible value for MATCH that is less than 65,535, the + * maximum value for the 16-bit timer register: + * + * TIMER1_PRESCALE >= TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535 + * + * Timer 1 does not have very many options for the prescaler value. So we + * can pick the best by brute force. Example: + * + * Example 1. Given: + * BOARD_TIMER1_SOSC = Defined + * BOARD_SOSC_FREQ = 32768 + * CLOCKS_PER_SEC = 100 + * Then: + * OPTIMAL_PRESCALE = 1 + * TIMER1_PRESCALE = 1 + * TIMER1_MATCH = 327 -> 100.3 ticks/sec + * + * Example 2. Given: + * BOARD_TIMER1_SOSC = Not defined + * BOARD_PBCLK3 = 60000000 + * CLOCKS_PER_SEC = 100 + * Then: + * OPTIMAL_PRESCALE = 9.2 + * TIMER1_PRESCALE = 64 + * TIMER1_MATCH = 9375 -> 100.0 ticks/sec + */ + +#define OPTIMAL_PRESCALE (TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535) +#if OPTIMAL_PRESCALE <= 1 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1 +# define TIMER1_PRESCALE 1 +#elif OPTIMAL_PRESCALE <= 8 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_8 +# define TIMER1_PRESCALE 8 +#elif OPTIMAL_PRESCALE <= 64 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_64 +# define TIMER1_PRESCALE 64 +#elif OPTIMAL_PRESCALE <= 256 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_256 +# define TIMER1_PRESCALE 256 +#else +# error "This timer frequency cannot be represented" +#endif + +#define TIMER1_MATCH (TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Clear the pending timer interrupt */ + + up_clrpend_irq(PIC32MZ_IRQ_T1); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Configure and enable TIMER1. Used the computed TCKPS divider and timer + * match value. The source will be either the internal PBCLOCK (TCS=0) or + * the external SOSC (TCS=1) + */ + + putreg32((TIMER1_CON_TCKPS | TIMER1_CON_TCS), PIC32MZ_TIMER1_CON); + putreg32(0, PIC32MZ_TIMER1_CNT); + putreg32(TIMER1_MATCH-1, PIC32MZ_TIMER1_PR); + putreg32(TIMER_CON_ON, PIC32MZ_TIMER1_CONSET); + + /* Configure the timer interrupt */ + + up_clrpend_irq(PIC32MZ_IRQ_T1); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(PIC32MZ_IRQ_T1, (xcpt_t)up_timerisr); + + /* And enable the timer interrupt */ + + up_enable_irq(PIC32MZ_IRQ_T1); +} diff --git a/arch/mips/src/pic32mz/pic32mz-usbdev.h b/arch/mips/src/pic32mz/pic32mz-usbdev.h new file mode 100644 index 0000000000000000000000000000000000000000..575f5498c6509a1d94c6d6c115a80ed99b62cf26 --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-usbdev.h @@ -0,0 +1,128 @@ +/************************************************************************************ + * arch/mips/src/pic32mz/pic32mz-usbdev.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_USBDEV_H +#define __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_USBDEV_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: pic32mz_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide pic32mz_pullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * Alternatively, if no pull-up GPIO the following can be redefined to be + * NULL. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_USBDEV +struct usbdev_s; +int pic32mz_usbpullup(FAR struct usbdev_s *dev, bool enable); +#endif + +/************************************************************************************ + * Name: pic32mz_usbsuspend + * + * Description: + * Board logic must provide the pic32mz_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. while + * the USB is suspended. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_USBDEV +void pic32mz_usbsuspend(FAR struct usbdev_s *dev, bool resume); +#endif + +/************************************************************************************ + + * Name: pic32mz_usbattach and pic32mz_usbdetach + * + * Description: + * The USB stack must be notified when the device is attached or detached by + * calling one of these functions. + * + ************************************************************************************/ + +#ifdef CONFIG_PIC32MZ_USBDEV +void pic32mz_usbattach(void); +void pic32mz_usbdetach(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_USBDEV_H */ diff --git a/arch/rgmp/Kconfig b/arch/rgmp/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..690f88e6145f028ed9fcbefcbfeb5b61e4096021 --- /dev/null +++ b/arch/rgmp/Kconfig @@ -0,0 +1,46 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_RGMP +comment "RGMP Configuration Options" + +choice + prompt "RGMP Architecture" + default RGMP_SUBARCH_X86 + +config RGMP_SUBARCH_ARM + bool "ARM" + ---help--- + RGMP ARM architecture" + +config RGMP_SUBARCH_X86 + bool "x86" + ---help--- + RGMP x86 architecture" + +endchoice # RGMP Architecture + +config RGMP_SUBARCH + string + default "arm" if RGMP_SUBARCH_ARM + default "x86" if RGMP_SUBARCH_X86 + +menu "x86 Peripheral Selections" + depends on RGMP_SUBARCH_X86 + +config COM1 + bool "COM1" + +config COM2 + bool "COM1" + +config COM3 + bool "COM1" + +config COM4 + bool "COM1" + +endmenu # x86 Peripheral Selections +endif # ARCH_RGMP diff --git a/arch/rgmp/include/.gitignore b/arch/rgmp/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6460c4a67846d5801c3600ce961277e3644f647 --- /dev/null +++ b/arch/rgmp/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/rgmp/include/arch.h b/arch/rgmp/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..af99356ea16a79422950d68cc4cb4abd7f58e494 --- /dev/null +++ b/arch/rgmp/include/arch.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/rgmp/include/arch.h + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __RGMP_ARCH_ARCH_H +#define __RGMP_ARCH_ARCH_H + +#include + +#ifndef __ASSEMBLY__ + +#include + +struct up_wait { + struct up_wait *next; + struct tcb_s *task; +}; + +extern struct tcb_s *current_task; + +void up_sigentry(void); + +int up_register_bridge(char *name, int size); +int up_unregister_bridge(char *name); + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/arch/rgmp/include/arm/arch/subarch/arch.h b/arch/rgmp/include/arm/arch/subarch/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..e5f3fff10f93ad6892b0c744442d0956407c60cd --- /dev/null +++ b/arch/rgmp/include/arm/arch/subarch/arch.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/rgmp/include/arm/arch/subarch/arch.h + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __RGMP_ARCH_SUBARCH_ARCH_H +#define __RGMP_ARCH_SUBARCH_ARCH_H + +#ifndef __ASSEMBLY__ + + +static inline void up_mdelay(uint32_t msec) +{ + +} + +static inline void up_udelay(uint32_t usec) +{ + +} + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/arch/rgmp/include/irq.h b/arch/rgmp/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b4c4f37d2d03741bdfd1023b8c3ad35a0cbf6271 --- /dev/null +++ b/arch/rgmp/include/irq.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/rgmp/include/irq.h + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_IRQ_H +#define __ARCH_RGMP_INCLUDE_IRQ_H + +#define NR_IRQS 0 + +#ifndef __ASSEMBLY__ + +#include + +#include +#include + +struct xcptcontext +{ + struct rgmp_context ctx; + + /* For signal using */ + + unsigned int save_eip; + unsigned int save_eflags; + void *sigdeliver; +}; + +void push_xcptcontext(struct xcptcontext *xcp); +void pop_xcptcontext(struct xcptcontext *xcp); + +extern int nest_irq; + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +static inline irqstate_t up_irq_save(void) +{ + unsigned long flags; + local_irq_save(flags); + return flags; +} + +static inline void up_irq_restore(irqstate_t flags) +{ + local_irq_restore(flags); +} + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/arch/rgmp/include/limits.h b/arch/rgmp/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..a17af23d99c5f55eb18ca12686f5c21732fa3d3b --- /dev/null +++ b/arch/rgmp/include/limits.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/rgmp/include/limits.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_LIMITS_H +#define __ARCH_RGMP_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_RGMP_INCLUDE_LIMITS_H */ diff --git a/arch/rgmp/include/math.h b/arch/rgmp/include/math.h new file mode 100644 index 0000000000000000000000000000000000000000..e042ba4a3c50c30105d660229360df5c8f286dfe --- /dev/null +++ b/arch/rgmp/include/math.h @@ -0,0 +1,260 @@ +/**************************************************************************** + * arch/rgmp/include/math.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_MATH_H +#define __ARCH_RGMP_INCLUDE_MATH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#include + +// following functions are not implemented by RGMP math library +// don't use them +// declared here for cmath + +/* General Functions ********************************************************/ + +float ceilf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double ceil (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double ceill (long double x); +#endif + +float floorf(float x); +#ifdef CONFIG_HAVE_DOUBLE +//double floor (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double floorl(long double x); +#endif + +float fabsf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double fabs (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double fabsl (long double x); +#endif + +float modff (float x, float *iptr); +#ifdef CONFIG_HAVE_DOUBLE +//double modf (double x, double *iptr); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double modfl (long double x, long double *iptr); +#endif + +float fmodf (float x, float div); +#ifdef CONFIG_HAVE_DOUBLE +//double fmod (double x, double div); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double fmodl (long double x, long double div); +#endif + +/* Exponential and Logarithmic Functions ************************************/ + +float powf (float b, float e); +#ifdef CONFIG_HAVE_DOUBLE +//double pow (double b, double e); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double powl (long double b, long double e); +#endif + +float expf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double exp (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double expl (long double x); +#endif + +float logf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double log (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double logl (long double x); +#endif + +float log10f(float x); +#ifdef CONFIG_HAVE_DOUBLE +//double log10 (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double log10l(long double x); +#endif + +float log2f (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double log2 (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double log2l (long double x); +#endif + +float sqrtf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double sqrt (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double sqrtl (long double x); +#endif + +float ldexpf(float x, int n); +#ifdef CONFIG_HAVE_DOUBLE +double ldexp (double x, int n); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double ldexpl(long double x, int n); +#endif + +float frexpf(float x, int *exp); +#ifdef CONFIG_HAVE_DOUBLE +double frexp (double x, int *exp); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double frexpl(long double x, int *exp); +#endif + +/* Trigonometric Functions **************************************************/ + +float sinf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double sin (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double sinl (long double x); +#endif + +float cosf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double cos (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double cosl (long double x); +#endif + +float tanf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double tan (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double tanl (long double x); +#endif + +float asinf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double asin (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double asinl (long double x); +#endif + +float acosf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double acos (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double acosl (long double x); +#endif + +float atanf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double atan (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double atanl (long double x); +#endif + +float atan2f(float y, float x); +#ifdef CONFIG_HAVE_DOUBLE +//double atan2 (double y, double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double atan2l(long double y, long double x); +#endif + +float sinhf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double sinh (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double sinhl (long double x); +#endif + +float coshf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double cosh (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double coshl (long double x); +#endif + +float tanhf (float x); +#ifdef CONFIG_HAVE_DOUBLE +//double tanh (double x); +#endif +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double tanhl (long double x); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_RGMP_INCLUDE_MATH_H */ diff --git a/arch/rgmp/include/stdbool.h b/arch/rgmp/include/stdbool.h new file mode 100644 index 0000000000000000000000000000000000000000..eb1bee1adb82a3597c09bcc59eae33a02c534083 --- /dev/null +++ b/arch/rgmp/include/stdbool.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/rgmp/include/stdbool.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_STDBOOL_H +#define __ARCH_RGMP_INCLUDE_STDBOOL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* bool, true, and false must be provided as macros so that they can be + * redefined by the application if necessary. + * + * NOTE: Under C99 'bool' is required to be defined to be the intrinsic type + * _Bool. However, in this NuttX context, we need backward compatibility + * to pre-C99 standards where _Bool is not an intrinsic type. Hence, we + * use _Bool8 as the underlying type. + */ + +#define true 1 +#define false 0 + +#define __bool_true_false_are_defined 1 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* A byte is the smallest address memory element (at least in architectures + * that do not support bit banding). The requirement is only that type _Bool + * be large enough to hold the values 0 and 1. We select uint8_t to minimize + * the RAM footprint of the executable. + * + * NOTE: We can't actually define the type _Bool here. Under C99 _Bool is + * an intrinsic type and cannot be the target of a typedef. However, in this + * NuttX context, we also need backward compatibility to pre-C99 standards + * where _Bool is not an intrinsic type. We work around this by using _Bool8 + * as the underlying type. + */ + +typedef uint8_t _Bool8; + +#endif /* __ARCH_RGMP_INCLUDE_STDBOOL_H */ diff --git a/arch/rgmp/include/stdint.h b/arch/rgmp/include/stdint.h new file mode 100644 index 0000000000000000000000000000000000000000..07b9ffdeeb2d5d45e94daca6f34dc84ee1a27b33 --- /dev/null +++ b/arch/rgmp/include/stdint.h @@ -0,0 +1,277 @@ +/**************************************************************************** + * arch/rgmp/include/stdint.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_STDINTL_H +#define __ARCH_RGMP_INCLUDE_STDINTL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Limits of exact-width integer types */ + +#define INT8_MIN 0x80 +#define INT8_MAX 0x7f +#define UINT8_MAX 0xff + +#define INT16_MIN 0x8000 +#define INT16_MAX 0x7fff +#define UINT16_MAX 0xffff + +#ifdef __INT64_DEFINED +# define INT24_MIN 0x800000 +# define INT24_MAX 0x7fffff +# define UINT24_MAX 0xffffff +#endif + +#define INT32_MIN 0x80000000 +#define INT32_MAX 0x7fffffff +#define UINT32_MAX 0xffffffff + +#ifdef __INT64_DEFINED +# define INT64_MIN 0x8000000000000000 +# define INT64_MAX 0x7fffffffffffffff +# define UINT64_MAX 0xffffffffffffffff +#endif + +/* Limits of minimum-width integer types */ + +#define INT8_LEASTN_MIN 0x80 +#define INT8_LEASTN_MAX 0x7f +#define UINT8_LEASTN_MAX 0xff + +#define INT16_LEASTN_MIN 0x8000 +#define INT16_LEASTN_MAX 0x7fff +#define UINT16_LEASTN_MAX 0xffff + +#ifdef __INT64_DEFINED +# define INT24_LEASTN_MIN 0x800000 +# define INT24_LEASTN_MAX 0x7fffff +# define UINT24_LEASTN_MAX 0xffffff +#endif + +#define INT32_LEASTN_MIN 0x80000000 +#define INT32_LEASTN_MAX 0x7fffffff +#define UINT32_LEASTN_MAX 0xffffffff + +#ifdef __INT64_DEFINED +# define INT64_LEASTN_MIN 0x8000000000000000 +# define INT64_LEASTN_MAX 0x7fffffffffffffff +# define UINT64_LEASTN_MAX 0xffffffffffffffff +#endif + +/* Limits of fastest minimum-width integer types */ + +#define INT8_FASTN_MIN 0x80 +#define INT8_FASTN_MAX 0x7f +#define UINT8_FASTN_MAX 0xff + +#define INT16_FASTN_MIN 0x8000 +#define INT16_FASTN_MAX 0x7fff +#define UINT16_FASTN_MAX 0xffff + +#ifdef __INT64_DEFINED +# define INT24_FASTN_MIN 0x800000 +# define INT24_FASTN_MAX 0x7fffff +# define UINT24_FASTN_MAX 0xffffff +#endif + +#define INT32_FASTN_MIN 0x80000000 +#define INT32_FASTN_MAX 0x7fffffff +#define UINT32_FASTN_MAX 0xffffffff + +#ifdef __INT64_DEFINED +# define INT64_FASTN_MIN 0x8000000000000000 +# define INT64_FASTN_MAX 0x7fffffffffffffff +# define UINT64_FASTN_MAX 0xffffffffffffffff +#endif + +/* Limits of integer types capable of holding object pointers */ + +#define INTPTR_MIN PTR_MIN +#define INTPTR_MAX PTR_MIN +#define UINTPTR_MAX UPTR_MAX + +/* Limits of greatest-width integer types */ + +#ifdef __INT64_DEFINED +# define INTMAX_MIN INT64_MIN +# define INTMAX_MAX INT64_MAX + +# define UINTMAX_MIN UINT64_MIN +# define UINTMAX_MAX UINT64_MAX +#else +# define INTMAX_MIN INT32_MIN +# define INTMAX_MAX INT32_MAX + +# define UINTMAX_MIN UINT32_MIN +# define UINTMAX_MAX UINT32_MAX +#endif + +/* Macros for minimum-width integer constant expressions */ + +#if 0 /* REVISIT: Depends on architecture specific implementation */ +#define INT8_C(x) x +#define INT16_C(x) x +#define INT32_C(x) x ## L +#define INT64_C(x) x ## LL + +#define UINT8_C(x) x +#define UINT16_C(x) x +#define UINT32_C(x) x ## UL +#define UINT64_C(x) x ## ULL +#endif + +/* Macros for greatest-width integer constant expressions + +#ifdef CONFIG_HAVE_LONG_LONG +# define INTMAX_C(x) x ## LL +# define UINTMAX_C(x) x ## ULL +#else +# define INTMAX_C(x) x ## L +# define UINTMAX_C(x) x ## UL +#endif + +/* Limits of Other Integer Types */ + +#if 0 +# define PTRDIFF_MIN +# define PTRDIFF_MAX +#endif + +#ifdef CONFIG_SMALL_MEMORY +# define SIZE_MAX 0xffff +#else +# define SIZE_MAX 0xffffffff +#endif + +#if 0 +# define WCHAR_MIN +# define WCHAR_MAX + +# define WINT_MIN +# define WINT_MAX +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Exact-width integer types. NOTE that these types are defined in + * architecture-specific logic with leading underscore character. This file + * typedef's these to the final name without the underscore character. This + * roundabout way of doings things allows the stdint.h to be removed from the + * include/ directory in the event that the user prefers to use the definitions + * provided by their toolchain header files. + */ + +#include + +/* Minimum-width integer types */ + +typedef _int8_t int_least8_t; +typedef _uint8_t uint_least8_t; + +typedef _int16_t int_least16_t; +typedef _uint16_t uint_least16_t; + +#ifdef __INT24_DEFINED +typedef _int24_t int_least24_t; +typedef _uint24_t uint_least24_t; +#else +typedef _int32_t int_least24_t; +typedef _uint32_t uint_least24_t; +#endif + +typedef _int32_t int_least32_t; +typedef _uint32_t uint_least32_t; + +#ifdef __INT64_DEFINED +typedef _int64_t int_least64_t; +typedef _uint64_t uint_least64_t; +#endif + +/* Fastest minimum-width integer types */ + +typedef _int8_t int_fast8_t; +typedef _uint8_t uint_fast8_t; + +typedef int int_fast16_t; +typedef unsigned int uint_fast16_t; + +#ifdef __INT24_DEFINED +typedef _int24_t int_fast24_t; +typedef _uint24_t uint_fast24_t; +#else +typedef _int32_t int_fast24_t; +typedef _uint32_t uint_fast24_t; +#endif + +typedef _int32_t int_fast32_t; +typedef _uint32_t uint_fast32_t; + +#ifdef __INT64_DEFINED +typedef _int64_t int_fast64_t; +typedef _uint64_t uint_fast64_t; +#endif + +/* Integer types capable of holding object pointers */ + +#ifndef CONFIG_ARCH_RGMP +typedef _intptr_t intptr_t; +typedef _uintptr_t uintptr_t; +#endif + +/* Greatest-width integer types */ + +#ifdef __INT64_DEFINED +typedef _int64_t intmax_t; +typedef _uint64_t uintmax_t; +#else +typedef _int32_t intmax_t; +typedef _uint32_t uintmax_t; +#endif + +#endif /* __ARCH_RGMP_INCLUDE_STDINTL_H */ diff --git a/arch/rgmp/include/types.h b/arch/rgmp/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..1f515cb70c6ae4be41f911ed7f439f36cb5f96de --- /dev/null +++ b/arch/rgmp/include/types.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/rgmp/include/types.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through sys/types.h + */ + +#ifndef __ARCH_RGMP_INCLUDE_TYPES_H +#define __ARCH_RGMP_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef char _int8_t; +typedef unsigned char _uint8_t; + +typedef short _int16_t; +typedef unsigned short _uint16_t; + +typedef int _int32_t; +typedef unsigned int _uint32_t; + +typedef long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef unsigned int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_RGMP_INCLUDE_TYPES_H */ diff --git a/arch/rgmp/include/x86/arch/com.h b/arch/rgmp/include/x86/arch/com.h new file mode 100644 index 0000000000000000000000000000000000000000..89df901bb3cfd66737eb79d906488ad03c7f128f --- /dev/null +++ b/arch/rgmp/include/x86/arch/com.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/rgmp/include/com.h + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_RGMP_INCLUDE_COM_H +#define __ARCH_RGMP_INCLUDE_COM_H + +#define COM_SET_BAUD 1 +#define COM_SET_PARITY 2 +#define COM_NO_PARITY 0 +#define COM_ODD_PARITY 1 +#define COM_EVEN_PARITY 3 +#define COM_SET_STOPBITS 3 +#define COM_ONE_STOPBITS 0 +#define COM_TWO_STOPBITS 1 +#define COM_SET_BITS 4 +#define COM_8_BITS 3 +#define COM_7_BITS 2 +#define COM_6_BITS 1 +#define COM_5_BITS 0 + + +#endif diff --git a/arch/rgmp/include/x86/arch/subarch/arch.h b/arch/rgmp/include/x86/arch/subarch/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..b88cb34155c37963d22e366ecbcda86fdf525ae9 --- /dev/null +++ b/arch/rgmp/include/x86/arch/subarch/arch.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/rgmp/include/x86/arch/subarch/arch.h + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __RGMP_ARCH_SUBARCH_ARCH_H +#define __RGMP_ARCH_SUBARCH_ARCH_H + +#ifndef __ASSEMBLY__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +static inline void up_mdelay(uint32_t msec) +{ + hpet_ndelay(msec*1000000); +} + +static inline void up_udelay(uint32_t usec) +{ + hpet_ndelay(usec*1000); +} + +#ifdef __cplusplus +} +#endif + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/arch/rgmp/src/.gitignore b/arch/rgmp/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8d209f76a44efca7364cb9ee0735d799d36f432f --- /dev/null +++ b/arch/rgmp/src/.gitignore @@ -0,0 +1,4 @@ +/.depend +/Make.dep +/board +/chip diff --git a/arch/rgmp/src/Makefile b/arch/rgmp/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1fb3618d96f1db52a87252e70d0bad8454ddd51d --- /dev/null +++ b/arch/rgmp/src/Makefile @@ -0,0 +1,111 @@ +############################################################################ +# arch/rgmp/src/Makefile +# +# Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +include $(CONFIG_RGMP_SUBARCH)/Make.defs + +RGMP_ARCH_ASRCS := $(addprefix $(CONFIG_RGMP_SUBARCH)/,$(RGMP_ARCH_ASRCS)) +RGMP_ARCH_CSRCS := $(addprefix $(CONFIG_RGMP_SUBARCH)/,$(RGMP_ARCH_CSRCS)) + +CPPFLAGS += -I$(TOPDIR)/sched -I$(TOPDIR)/fs $(EXTRADEFINES) +CFLAGS += -I$(TOPDIR)/sched -I$(TOPDIR)/fs $(EXTRADEFINES) +CXXFLAGS += -I$(TOPDIR)/sched -I$(TOPDIR)/fs $(EXTRADEFINES) + +ASRCS = $(RGMP_ARCH_ASRCS) +CSRCS = nuttx.c cxx.c $(RGMP_ARCH_CSRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LINKSRCS = rgmp.c bridge.c +LINKOBJS = $(LINKSRCS:.c=$(OBJEXT)) + +LDFLAGS += -T$(RGMPLKSCPT) +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +LIBPATHS += -L"$(TOPDIR)/lib" -L$(RGMPLIBDIR) +LDLIBS += -lrgmp $(shell "$(CC)" -print-libgcc-file-name) + +all: libarch$(LIBEXT) + +.PHONY: clean distclean depend + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +# The architecture-specific library + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +# Generate the final NuttX binary by linking the host-specific objects with the NuttX +# specific objects (with munged names) + +nuttx$(EXEEXT): $(LINKOBJS) + @echo "LD: nuttx$(EXEEXT)" + @$(LD) $(LDFLAGS) $(LIBPATHS) $(LINKOBJS) --start-group $(LDLIBS) $(EXTRA_LIBS) --end-group -o $(TOPDIR)/$@ + @$(OBJDUMP) -S $(TOPDIR)/$@ > $(TOPDIR)/nuttx.asm + @$(NM) -n $(TOPDIR)/$@ > $(TOPDIR)/nuttx.sym + @$(OBJCOPY) -S -O binary $(TOPDIR)/$@ nuttx.img + @cp nuttx.img $(TOPDIR)/kernel.img + +# This is part of the top-level export target + +expport_startup: + +# Dependencies + +.depend: Makefile $(SRCS) $(LINKSRCS) + @$(MKDEP) "$(CC)" -- $(CFLAGS) -- $(SRCS) $(LINKSRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, "$(TOPDIR)/arch/rgmp/src/x86/*.o") + $(call DELFILE, "$(TOPDIR)/kernel.img") + $(call DELFILE, nuttx.img) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/rgmp/src/arm/Make.defs b/arch/rgmp/src/arm/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..e21b046e8933a4f20f3f43a1062c22871ca804aa --- /dev/null +++ b/arch/rgmp/src/arm/Make.defs @@ -0,0 +1,42 @@ +############################################################################ +# rgmp/arm/Make.defs +# +# Copyright (C) 2011 Yu Qiang. All rights reserved. +# Author: Yu Qiang +# +# This file is a part of NuttX: +# +# Copyright (C) 2011 Gregory Nutt. All rights reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +RGMP_ARCH_ASRCS = sigentry.S +RGMP_ARCH_CSRCS = arch_nuttx.c diff --git a/arch/rgmp/src/arm/arch_nuttx.c b/arch/rgmp/src/arm/arch_nuttx.c new file mode 100644 index 0000000000000000000000000000000000000000..dd737946d9d146ca883bd4c86141de358bcff6ad --- /dev/null +++ b/arch/rgmp/src/arm/arch_nuttx.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/rgmp/src/arm/arch_nuttx.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include + +void nuttx_arch_init(void) +{ +} + +void nuttx_arch_exit(void) +{ +} + +void up_initial_state(struct tcb_s *tcb) +{ + struct Trapframe *tf; + + if (tcb->pid != 0) + { + tf = (struct Trapframe *)tcb->adj_stack_ptr-1; + memset(tf, 0, sizeof(struct Trapframe)); + tf->tf_cpsr = SVC_MOD; + tf->tf_pc = (uint32_t)tcb->start; + tcb->xcp.tf = tf; + } +} + +void push_xcptcontext(struct xcptcontext *xcp) +{ + xcp->save_eip = xcp->tf->tf_pc; + xcp->save_eflags = xcp->tf->tf_cpsr; + + // set interrupts disabled + + xcp->tf->tf_pc = (uint32_t)up_sigentry; + xcp->tf->tf_cpsr |= CPSR_IF; +} + +void pop_xcptcontext(struct xcptcontext *xcp) +{ + xcp->tf->tf_pc = xcp->save_eip; + xcp->tf->tf_cpsr = xcp->save_eflags; +} + +void raise(void) +{ + +} + diff --git a/arch/rgmp/src/arm/sigentry.S b/arch/rgmp/src/arm/sigentry.S new file mode 100644 index 0000000000000000000000000000000000000000..1e413450bf6573c61f7215f23eb366fe0c38fa06 --- /dev/null +++ b/arch/rgmp/src/arm/sigentry.S @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/rgmp/src/arm/sigentry.S + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .globl up_sigentry +up_sigentry: + sub sp, sp, #68 @ 68 is the size of Trapframe + mov r0, sp + bl up_sigdeliver + add sp, sp, #4 @ skip current_task + pop {r0-r12, lr} + rfefd sp! + + \ No newline at end of file diff --git a/arch/rgmp/src/bridge.c b/arch/rgmp/src/bridge.c new file mode 100644 index 0000000000000000000000000000000000000000..46f45a8f59322934b1bdda5c3b91378f0b48d98d --- /dev/null +++ b/arch/rgmp/src/bridge.c @@ -0,0 +1,134 @@ +/**************************************************************************** + * arch/rgmp/src/bridge.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include "inode/inode.h" +#include +#include +#include +#include +#include +#include + +struct bridge +{ + struct rgmp_bridge *b; + sem_t rd_lock; + sem_t wr_lock; +}; + +static ssize_t up_bridge_read(struct file *filep, char *buffer, size_t len) +{ + ssize_t ret; + struct bridge *b = filep->f_inode->i_private; + + sem_wait(&b->rd_lock); + ret = rgmp_bridge_read(b->b, buffer, len, 0); + sem_post(&b->rd_lock); + return ret; +} + +static ssize_t up_bridge_write(struct file *filep, const char *buffer, size_t len) +{ + ssize_t ret; + struct bridge *b = filep->f_inode->i_private; + + sem_wait(&b->wr_lock); + ret = rgmp_bridge_write(b->b, (char *)buffer, len, 0); + sem_post(&b->wr_lock); + return ret; +} + +static int up_bridge_open(struct file *filep) +{ + return 0; +} + +static int up_bridge_close(struct file *filep) +{ + return 0; +} + +static const struct file_operations up_bridge_fops = +{ + .read = up_bridge_read, + .write = up_bridge_write, + .open = up_bridge_open, + .close = up_bridge_close, +}; + +int rtos_bridge_init(struct rgmp_bridge *b) +{ + int err; + struct bridge *bridge; + char path[30] = {'/', 'd', 'e', 'v', '/'}; + + if ((bridge = kmm_malloc(sizeof(*bridge))) == NULL) + goto err0; + + bridge->b = b; + if ((err = sem_init(&bridge->rd_lock, 0, 1)) == ERROR) + goto err1; + + if ((err = sem_init(&bridge->wr_lock, 0, 1)) == ERROR) + goto err1; + + // make rgmp_bridge0 to be the console + + if (strcmp(b->vdev->name, "rgmp_bridge0") == 0) + strlcpy(path + 5, "console", 25); + else + strlcpy(path + 5, b->vdev->name, 25); + + if ((err = register_driver(path, &up_bridge_fops, 0666, bridge)) == ERROR) + { + cprintf("NuttX: register bridge %s fail\n", b->vdev->name); + goto err1; + } + + return 0; + +err1: + kmm_free(bridge); +err0: + return -1; +} diff --git a/arch/rgmp/src/cxx.c b/arch/rgmp/src/cxx.c new file mode 100644 index 0000000000000000000000000000000000000000..8dfc6a697bf4803deec01fc204215644df02b259 --- /dev/null +++ b/arch/rgmp/src/cxx.c @@ -0,0 +1,19 @@ +#include +#include + +int stderr = 2; + +void __stack_chk_fail_local(void) +{ + panic("stack check fail\n"); +} + +int __sprintf_chk(char *str, int flag, size_t strlen, const char *format) +{ + return snprintf(str, strlen, format); +} + +int dl_iterate_phdr(void* arg1, void* arg2) +{ + return -1; +} diff --git a/arch/rgmp/src/nuttx.c b/arch/rgmp/src/nuttx.c new file mode 100644 index 0000000000000000000000000000000000000000..0832e8f9ec03f75860dd9e8f0001b7b2c5382329 --- /dev/null +++ b/arch/rgmp/src/nuttx.c @@ -0,0 +1,676 @@ +/**************************************************************************** + * arch/rgmp/src/nuttx.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" + +struct tcb_s *current_task = NULL; + +/* This function is called in non-interrupt context + * to switch tasks. + * Assumption: global interrupt is disabled. + */ + +static inline void up_switchcontext(struct tcb_s *ctcb, struct tcb_s *ntcb) +{ + // do nothing if two tasks are the same + + if (ctcb == ntcb) + return; + + // this function can not be called in interrupt + + if (up_interrupt_context()) { + panic("%s: try to switch context in interrupt\n", __func__); + } + + // start switch + + current_task = ntcb; + rgmp_context_switch(ctcb ? &ctcb->xcp.ctx : NULL, &ntcb->xcp.ctx); +} + +void up_initialize(void) +{ + extern pidhash_t g_pidhash[]; + extern void vdev_init(void); + extern void nuttx_arch_init(void); + + // initialize the current_task to g_idletcb + current_task = g_pidhash[PIDHASH(0)].tcb; + + // OS memory alloc system is ready + use_os_kmalloc = 1; + + // rgmp vdev init + vdev_init(); + + nuttx_arch_init(); + + // enable interrupt + local_irq_enable(); +} + +void up_idle(void) +{ + arch_hlt(); +} + +void up_allocate_heap(void **heap_start, size_t *heap_size) +{ + void *boot_freemem = boot_alloc(0, sizeof(int)); + *heap_start = boot_freemem; + *heap_size = KERNBASE + kmem_size - (uint32_t)boot_freemem; +} + +int up_create_stack(struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + uint32_t *stack_alloc_ptr; + int ret = ERROR; + size_t *adj_stack_ptr; + + /* Move up to next even word boundary if necessary */ + + size_t adj_stack_size = (stack_size + 3) & ~3; + size_t adj_stack_words = adj_stack_size >> 2; + + /* Allocate the memory for the stack */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) { + stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } else +#endif + { + stack_alloc_ptr = (uint32_t*)kumm_malloc(adj_stack_size); + } + if (stack_alloc_ptr) { + /* This is the address of the last word in the allocation */ + + adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1]; + + /* Save the values in the TCB */ + + tcb->adj_stack_size = adj_stack_size; + tcb->stack_alloc_ptr = stack_alloc_ptr; + tcb->adj_stack_ptr = (void *)((unsigned int)adj_stack_ptr & ~7); + ret = OK; + } + return ret; +} + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + /* Move up to next even word boundary if necessary */ + + size_t adj_stack_size = stack_size & ~3; + size_t adj_stack_words = adj_stack_size >> 2; + + /* This is the address of the last word in the allocation */ + + size_t *adj_stack_ptr = &((size_t*)stack)[adj_stack_words - 1]; + + /* Save the values in the TCB */ + + tcb->adj_stack_size = adj_stack_size; + tcb->stack_alloc_ptr = stack; + tcb->adj_stack_ptr = (void *)((unsigned int)adj_stack_ptr & ~7); + return OK; +} + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = (frame_size + 3) & ~3; + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial state */ + + up_initial_state(tcb); + + /* And return a pointer to the allocated memory region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + +void up_release_stack(struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) { + kmm_free(dtcb->stack_alloc_ptr); + } else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + kumm_free(dtcb->stack_alloc_ptr); + } + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + dtcb->adj_stack_size = 0; + dtcb->adj_stack_ptr = NULL; +} + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * This function is called only from the NuttX scheduling + * logic. Interrupts will always be disabled when this + * function is called. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + /* Verify that the context switch can be performed */ + + if ((tcb->task_state < FIRST_READY_TO_RUN_STATE) || + (tcb->task_state > LAST_READY_TO_RUN_STATE)) + { + warn("%s: task sched error\n", __func__); + return; + } + else + { + struct tcb_s *rtcb = current_task; + bool switch_needed; + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + struct tcb_s *nexttcb; + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* this part should not be executed in interrupt context */ + + if (up_interrupt_context()) + { + panic("%s: %d\n", __func__, __LINE__); + } + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now. It should be the up_realease_pending() called from + * sched_unlock() to do this for disable preemption. But it block + * itself, so it's OK. + */ + + if (g_pendingtasks.head) + { + warn("Disable preemption failed for task block itself\n"); + sched_mergepending(); + } + + nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* context switch */ + + up_switchcontext(rtcb, nexttcb); + } + } +} + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + /* Verify that the context switch can be performed */ + + if ((tcb->task_state < FIRST_BLOCKED_STATE) || + (tcb->task_state > LAST_BLOCKED_STATE)) + { + warn("%s: task sched error\n", __func__); + return; + } + else + { + struct tcb_s *rtcb = current_task; + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list. + */ + + if (sched_addreadytorun(tcb) && !up_interrupt_context()) + { + /* The currently active task has changed! */ + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* context switch */ + + up_switchcontext(rtcb, nexttcb); + } + } +} + +/* This function is called from sched_unlock() which will check not + * in interrupt context and disable interrupt. + */ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = current_task; + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + if (sched_mergepending()) + { + struct tcb_s *nexttcb = this_task(); + + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* context switch */ + + up_switchcontext(rtcb, nexttcb); + } +} + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > UINT8_MIN + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + warn("%s: task sched error\n", __func__); + return; + } + else + { + struct tcb_s *rtcb = current_task; + bool switch_needed; + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed && !up_interrupt_context()) + { + struct tcb_s *nexttcb; + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now. It should be the up_realease_pending() called from + * sched_unlock() to do this for disable preemption. But it block + * itself, so it's OK. + */ + + if (g_pendingtasks.head) + { + warn("Disable preemption failed for reprioritize task\n"); + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Get the TCB of the new task to run */ + + nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* context switch */ + + up_switchcontext(rtcb, nexttcb); + } + } +} + +void _exit(int status) +{ + struct tcb_s* tcb; + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_switchcontext(NULL, tcb); +} + +void up_assert(const uint8_t *filename, int line) +{ + fprintf(stderr, "Assertion failed at file:%s line: %d\n", filename, line); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, line); +#endif + + // in interrupt context or idle task means kernel error + // which will stop the OS + // if in user space just terminate the task + if (up_interrupt_context() || current_task->pid == 0) { + panic("%s: %d\n", __func__, __LINE__); + } + else { + exit(EXIT_FAILURE); + } +} + +#ifndef CONFIG_DISABLE_SIGNALS + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + /* Refuse to handle nested signal actions */ + if (!tcb->xcp.sigdeliver) { + int flags; + + /* Make sure that interrupts are disabled */ + local_irq_save(flags); + + // First, handle some special cases when the signal is + // being delivered to the currently executing task. + if (tcb == current_task) { + // CASE 1: We are not in an interrupt handler and + // a task is signalling itself for some reason. + if (!up_interrupt_context()) { + // In this case just deliver the signal now. + sigdeliver(tcb); + } + // CASE 2: We are in an interrupt handler AND the + // interrupted task is the same as the one that + // must receive the signal. + else { + tcb->xcp.sigdeliver = sigdeliver; + } + } + + // Otherwise, we are (1) signaling a task is not running + // from an interrupt handler or (2) we are not in an + // interrupt handler and the running task is signalling + // some non-running task. + else { + tcb->xcp.sigdeliver = sigdeliver; + push_xcptcontext(&tcb->xcp); + } + + local_irq_restore(flags); + } +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + + +bool up_interrupt_context(void) +{ + if (nest_irq) + return true; + return false; +} + +#ifndef CONFIG_ARCH_NOINTC +void up_disable_irq(int irq) +{ + +} + +void up_enable_irq(int irq) +{ + +} +#endif + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + +} +#endif + +void up_sigdeliver(struct Trapframe *tf) +{ + sig_deliver_t sigdeliver; + + pop_xcptcontext(¤t_task->xcp); + sigdeliver = current_task->xcp.sigdeliver; + current_task->xcp.sigdeliver = NULL; + local_irq_enable(); + sigdeliver(current_task); + local_irq_disable(); +} + +#if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) + +void up_cxxinitialize(void) +{ + rgmp_cxx_init(); +} + +#endif + + + + + + + + diff --git a/arch/rgmp/src/rgmp.c b/arch/rgmp/src/rgmp.c new file mode 100644 index 0000000000000000000000000000000000000000..40bbed971e056320ad5911cec4fa83a29d7eea2c --- /dev/null +++ b/arch/rgmp/src/rgmp.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * arch/rgmp/src/rgmp.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int nest_irq = 0; + +// the default time is 10ms +#ifdef MSEC_PER_TICK +const unsigned int rtos_tick_time = MSEC_PER_TICK; +#else +const unsigned int rtos_tick_time = 10; +#endif + +void rtos_entry(void) +{ + os_start(); +} + +void *rtos_get_page(void) +{ + return memalign(PTMEMSIZE, PTMEMSIZE); +} + +void rtos_free_page(void *page) +{ + free(page); +} + +void *rtos_kmalloc(int size) +{ + return kmm_malloc(size); +} + +void rtos_kfree(void *addr) +{ + kmm_free(addr); +} + +/* The interrupt can be nested. The pair of rtos_enter_interrupt() + * and rtos_exit_interrupt() make sure the context switch is + * performed only in the last IRQ exit. + */ + +void rtos_enter_interrupt(void) +{ + nest_irq++; +} + +void rtos_exit_interrupt(void) +{ + local_irq_disable(); + nest_irq--; + if (!nest_irq) + { + struct tcb_s *rtcb = current_task; + struct tcb_s *ntcb; + + if (rtcb->xcp.sigdeliver) + { + rtcb->xcp.ctx.tf = g_current_regs; + push_xcptcontext(&rtcb->xcp); + } + + ntcb = this_task(); + + /* Switch needed */ + + if (rtcb != ntcb) + { + rtcb->xcp.ctx.tf = g_current_regs; + current_task = ntcb; + rgmp_switch_to(&ntcb->xcp.ctx); + } + } +} + +void rtos_timer_isr(void *data) +{ + sched_process_timer(); +} + +/* RTOS semaphore operation */ + +int rtos_sem_init(struct semaphore *sem, int val) +{ + if ((sem->sem = kmm_malloc(sizeof(sem_t))) == NULL) + return -1; + return sem_init(sem->sem, 0, val); +} + +int rtos_sem_up(struct semaphore *sem) +{ + return sem_post(sem->sem); +} + +int rtos_sem_down(struct semaphore *sem) +{ + return sem_wait(sem->sem); +} + +void rtos_stop_running(void) +{ + extern void nuttx_arch_exit(void); + + local_irq_disable(); + + nuttx_arch_exit(); + + while (1) + { + arch_hlt(); + } +} + +int rtos_vnet_init(struct rgmp_vnet *vnet) +{ + extern int vnet_init(struct rgmp_vnet *vnet); + + return vnet_init(vnet); +} diff --git a/arch/rgmp/src/x86/Make.defs b/arch/rgmp/src/x86/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..fcf3180d82f1cbc0f6042224791040115dcb020d --- /dev/null +++ b/arch/rgmp/src/x86/Make.defs @@ -0,0 +1,42 @@ +############################################################################ +# rgmp/x86/Make.defs +# +# Copyright (C) 2011 Yu Qiang. All rights reserved. +# Author: Yu Qiang +# +# This file is a part of NuttX: +# +# Copyright (C) 2011 Gregory Nutt. All rights reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name Gregory Nutt 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +RGMP_ARCH_ASRCS = sigentry.S +RGMP_ARCH_CSRCS = com.c arch_nuttx.c diff --git a/arch/rgmp/src/x86/arch_nuttx.c b/arch/rgmp/src/x86/arch_nuttx.c new file mode 100644 index 0000000000000000000000000000000000000000..d5ae6916862eb64afdb85c12cc7d1db7dba22087 --- /dev/null +++ b/arch/rgmp/src/x86/arch_nuttx.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/rgmp/src/x86/arch_nuttx.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +#include +#include + + +void nuttx_arch_init(void) +{ + extern void e1000_mod_init(void); + extern void up_serialinit(void); + + // setup COM device + up_serialinit(); + +#ifdef CONFIG_NET_E1000 + // setup e1000 + e1000_mod_init(); +#endif + +} + +void nuttx_arch_exit(void) +{ + extern void e1000_mod_exit(void); + +#ifdef CONFIG_NET_E1000 + e1000_mod_exit(); +#endif +} + +void up_initial_state(struct tcb_s *tcb) +{ + struct Trapframe *tf; + + if (tcb->pid) + { + tf = (struct Trapframe *)tcb->adj_stack_ptr - 1; + rgmp_setup_context(&tcb->xcp.ctx, tf, tcb->start, 1); + } + else + { + rgmp_setup_context(&tcb->xcp.ctx, NULL, NULL, 0); + } +} + +void push_xcptcontext(struct xcptcontext *xcp) +{ + xcp->save_eip = xcp->ctx.tf->tf_eip; + xcp->save_eflags = xcp->ctx.tf->tf_eflags; + + // set up signal entry with interrupts disabled + + xcp->ctx.tf->tf_eip = (uint32_t)up_sigentry; + xcp->ctx.tf->tf_eflags = 0; +} + +void pop_xcptcontext(struct xcptcontext *xcp) +{ + xcp->ctx.tf->tf_eip = xcp->save_eip; + xcp->ctx.tf->tf_eflags = xcp->save_eflags; +} + diff --git a/arch/rgmp/src/x86/com.c b/arch/rgmp/src/x86/com.c new file mode 100644 index 0000000000000000000000000000000000000000..8a149bcadc0d50a3a08df7b87289f16983c1a8d6 --- /dev/null +++ b/arch/rgmp/src/x86/com.c @@ -0,0 +1,640 @@ +/**************************************************************************** + * arch/rgmp/src/x86/com.c + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Authors: Yu Qiang + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define COM1 0x3F8 +#define COM2 0x2f8 +#define COM3 0x3e8 +#define COM4 0x2e8 + +#define COM_RX 0 // In: Receive buffer (DLAB=0) +#define COM_DLL 0 // Out: Divisor Latch Low (DLAB=1) +#define COM_TX 0 // Out: Transmit buffer (DLAB=0) +#define COM_DLM 1 // Out: Divisor Latch High (DLAB=1) +#define COM_IER 1 // Out: Interrupt Enable Register +#define COM_IER_TEI 0x02 // Enable transmit buffer empty interrupt +#define COM_IER_RDI 0x01 // Enable receiver data interrupt +#define COM_IIR 2 // In: Interrupt ID Register +#define COM_FCR 2 // Out: FIFO Control Register +#define COM_LCR 3 // Out: Line Control Register +#define COM_LCR_DLAB 0x80 // Divisor latch access bit +#define COM_LCR_WLEN8 0x03 // Wordlength: 8 bits +#define COM_MCR 4 // Out: Modem Control Register +#define COM_MCR_RTS 0x02 // RTS complement +#define COM_MCR_DTR 0x01 // DTR complement +#define COM_MCR_OUT2 0x08 // Out2 complement +#define COM_LSR 5 // In: Line Status Register +#define COM_LSR_DATA 0x01 // Data available +#define COM_LSR_ETR 0x20 // buffer has space +#define COM_LSR_EDR 0x40 // buffer empty + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifndef CONFIG_COM_RXBUFSIZE +#define CONFIG_COM_RXBUFSIZE 64 +#endif + +#ifndef CONFIG_COM_TXBUFSIZE +#define CONFIG_COM_TXBUFSIZE 64 +#endif + +struct up_dev_s +{ + unsigned int base; /* Base address of COM registers */ + unsigned int baud; /* Configured baud */ + int irq; /* IRQ associated with this COM */ + struct irq_action action; + union { + uint8_t val; + struct { + unsigned bits : 2; /* 3=8 bits, 2=7 bits, 1=6 bits, 0=5 bits */ + unsigned stopbits : 1; /* 0=1 stop bit, 1=2 stop bits */ + unsigned parity : 3; /* xx0=none, 001=odd, 011=even */ + unsigned ebreak : 1; + unsigned dlab : 1; + } sep; + } lcr; + char rxbuff[CONFIG_COM_RXBUFSIZE]; /* receive buffer */ + char txbuff[CONFIG_COM_TXBUFSIZE]; /* transmit buffer */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static irqreturn_t up_com_int_handler(int irq, void *dev_id); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct uart_ops_s g_com_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_alloc_com + ****************************************************************************/ + +static uart_dev_t *up_alloc_com(unsigned int base, int irq) +{ + uart_dev_t *dev; + struct up_dev_s *priv; + + priv = kmm_zalloc(sizeof(struct up_dev_s)); + if (priv == NULL) + { + goto err0; + } + + dev = kmm_zalloc(sizeof(uart_dev_t)); + if (dev == NULL) + { + goto err1; + } + + priv->base = base; + priv->irq = irq; + priv->baud = 115200; + priv->lcr.val = 0; + priv->lcr.sep.parity = 0; + priv->lcr.sep.bits = 3; + priv->lcr.sep.stopbits = 0; + priv->action.handler = up_com_int_handler; + priv->action.dev_id = dev; + + dev->recv.size = CONFIG_COM_RXBUFSIZE; + dev->recv.buffer = priv->rxbuff; + dev->xmit.size = CONFIG_COM_TXBUFSIZE; + dev->xmit.buffer = priv->txbuff; + dev->ops = &g_com_ops; + dev->priv = priv; + + return dev; + +err1: + kmm_free(priv); +err0: + return NULL; +} + +/**************************************************************************** + * Name: up_alloc_com + ****************************************************************************/ + +static inline void up_free_com(uart_dev_t *com) +{ + kmm_free(com->priv); + kmm_free(com); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + uint16_t base = priv->base; + union { + uint16_t val; + struct { + uint8_t low; + uint8_t high; + } sep; + } data; + + // clear and disable FIFO + outb(base+COM_FCR, 1); + outb(base+COM_FCR, 3); + outb(base+COM_FCR, 0); + + // Clear any preexisting overrun indications and interrupts + // Serial port doesn't exist if COM_LSR returns 0xFF + inb(base+COM_LSR); + inb(base+COM_IIR); + inb(base+COM_RX); + if (inb(base+COM_LSR) == 0xff) { + dbg("COM %d does not exist\n", base); + return -1; + } + + // Set speed; requires DLAB latch + outb(base+COM_LCR, COM_LCR_DLAB); + data.val = 115200 / priv->baud; + outb(base+COM_DLL, data.sep.low); + outb(base+COM_DLM, data.sep.high); + + // set data bits, stop bit, parity; turn off DLAB latch + outb(base+COM_LCR, priv->lcr.val); + + // OUT2 must be set to enable interrupt + outb(base+COM_MCR, COM_MCR_OUT2); + + // setup FIFO + outb(base+COM_FCR, 1); + + // disable COM interrupts + outb(base+COM_IER, 0); + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + uint16_t base = priv->base; + + // disable COM interrupts + outb(base+COM_IER, 0); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + int err; + + err = rgmp_request_irq(priv->irq, &priv->action, 0); + + return err; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = dev->priv; + + rgmp_free_irq(priv->irq, &priv->action); +} + +/**************************************************************************** + * Name: up_com_int_handler + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static irqreturn_t up_com_int_handler(int irq, void *dev_id) +{ + struct uart_dev_s *dev = dev_id; + struct up_dev_s *priv = dev->priv; + uint16_t base = priv->base; + //uint8_t cause = inb(base+COM_IIR); + uint8_t state = inb(base+COM_LSR); + + if (state & COM_LSR_DATA) + uart_recvchars(dev); + + if (state & COM_LSR_ETR) + uart_xmitchars(dev); + + return IRQ_HANDLED; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + switch (cmd) { + case COM_SET_BAUD: + priv->baud = arg; + break; + case COM_SET_PARITY: + priv->lcr.sep.parity = arg; + break; + case COM_SET_STOPBITS: + priv->lcr.sep.stopbits = arg; + break; + case COM_SET_BITS: + priv->lcr.sep.bits = arg; + break; + default: + return ERROR; + } + + if (up_setup(dev) != OK) + return ERROR; + + up_rxint(dev, 1); + + return OK; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + + return inb(base+COM_RX); +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + uint8_t ier; + + ier = inb(base+COM_IER); + if (enable) + ier |= COM_IER_RDI; + else + ier &= ~COM_IER_RDI; + outb(base+COM_IER, ier); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + + return inb(base+COM_LSR) & COM_LSR_DATA; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + + outb(base+COM_TX, ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + irqstate_t flags; + uint8_t ier; + + flags = enter_critical_section(); + ier = inb(base+COM_IER); + if (enable) { + ier |= COM_IER_TEI; + outb(base+COM_IER, ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + } + else { + ier &= ~COM_IER_TEI; + outb(base+COM_IER, ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + + return inb(base+COM_LSR) & COM_LSR_ETR; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t base = priv->base; + + return inb(base+COM_LSR) & COM_LSR_EDR; +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + uart_dev_t *dev; + int err; + +#ifdef CONFIG_COM1 + dev = up_alloc_com(COM1, 4); + if (dev == NULL) + dbg("alloc com1 fail\n"); + else { + err = uart_register("/dev/ttyS0", dev); + if (err) + dbg("register com1 fail\n"); + } +#endif +#ifdef CONFIG_COM2 + dev = up_alloc_com(COM2, 3); + if (dev == NULL) + dbg("alloc com2 fail\n"); + else { + err = uart_register("/dev/ttyS1", dev); + if (err) + dbg("register com2 fail\n"); + } +#endif +#ifdef CONFIG_COM3 + dev = up_alloc_com(COM3, 4); + if (dev == NULL) + dbg("alloc com3 fail\n"); + else { + err = uart_register("/dev/ttyS2", dev); + if (err) + dbg("register com3 fail\n"); + } +#endif +#ifdef CONFIG_COM4 + dev = up_alloc_com(COM4, 3); + if (dev == NULL) + dbg("alloc com4 fail\n"); + else { + err = uart_register("/dev/ttyS3", dev); + if (err) + dbg("register com4 fail\n"); + } +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ +extern void cons_putc(int c); + +int up_putc(int ch) +{ + cons_putc(ch); + return ch; +} + diff --git a/arch/rgmp/src/x86/sigentry.S b/arch/rgmp/src/x86/sigentry.S new file mode 100644 index 0000000000000000000000000000000000000000..77214e8114a58a94fb22ba469d558e049b3e9245 --- /dev/null +++ b/arch/rgmp/src/x86/sigentry.S @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/rgmp/src/x86/sigentry.S + * + * Copyright (C) 2011 Yu Qiang. All rights reserved. + * Author: Yu Qiang + * + * This file is a part of NuttX: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .globl up_sigentry +up_sigentry: + subl $172, %esp # 172 is the size of Trapframe without cross ring part + pushl %esp + movl %esp, %eax + call up_sigdeliver + addl $8, %esp # skip parameter and tf_curregs + frstor 0(%esp) + addl $108, %esp + popal + popl %es + popl %ds + addl $0x8, %esp # trapno and errcode + iret + + \ No newline at end of file diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..48c76f3ca03da56f1578e092eb746f00b19ef35d --- /dev/null +++ b/arch/sh/Kconfig @@ -0,0 +1,44 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_SH + +choice + prompt "SH chip selection" + default ARCH_CHIP_SH7032 + +config ARCH_CHIP_SH7032 + bool "SH7032" + select ARCH_SH1 + ---help--- + Hitachi/Renesas SH7032 (SH1) + +config ARCH_CHIP_M30262F8 + bool "M30262F8" + select ARCH_M16C + select MM_SMALL + ---help--- + Renesas M30262F8 (M16C) + +endchoice + +config ARCH_SH1 + bool + default n + +config ARCH_M16C + bool + default n + +config ARCH_CHIP + string + default "sh1" if ARCH_SH1 + default "m16c" if ARCH_M16C + +source arch/sh/src/common/Kconfig +source arch/sh/src/m16c/Kconfig +source arch/sh/src/sh1/Kconfig + +endif # ARCH_SH diff --git a/arch/sh/include/README.txt b/arch/sh/include/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..c07708aeca4e8fc008d196cd0979968dd7a57c45 --- /dev/null +++ b/arch/sh/include/README.txt @@ -0,0 +1,5 @@ +This directory contains header files common to all SH architectures. +Sub-directories within this directory contain header files unique to +specific SH chip architectures. At configuration time, additional directories +will be linked here: 'build' will be a link to the configs/*/include +directory; 'chip' will be a link to the SH chip sub-directory. diff --git a/arch/sh/include/arch.h b/arch/sh/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..4b4c7e934d9e39d2b9a3775842d75d866fb4cd7b --- /dev/null +++ b/arch/sh/include/arch.h @@ -0,0 +1,80 @@ +/**************************************************************************** + * arch/sh/include/arch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_SH_INCLUDE_ARCH_H +#define __ARCH_SH_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_SH_INCLUDE_ARCH_H */ diff --git a/arch/sh/include/irq.h b/arch/sh/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..78617accce61722ad5a92ffdb8f4c898beb59ba6 --- /dev/null +++ b/arch/sh/include/irq.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/sh/include/irq.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_SH_INCLUDE_IRQ_H +#define __ARCH_SH_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_SH_INCLUDE_IRQ_H */ + diff --git a/arch/sh/include/limits.h b/arch/sh/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..feb02e5d6f38f9a7cfc9bcd2ee07b5827577ea94 --- /dev/null +++ b/arch/sh/include/limits.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/sh/include/limits.h + * + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SH_INCLUDE_LIMITS_H +#define __ARCH_SH_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_LIMITS_H */ diff --git a/arch/sh/include/m16c/irq.h b/arch/sh/include/m16c/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..2528e911eb73700f704d880b4cdb070335cab71e --- /dev/null +++ b/arch/sh/include/m16c/irq.h @@ -0,0 +1,332 @@ +/************************************************************************************ + * arch/sh/include/m16c/irq.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_SH_INCLUDE_M16C_IRQ_H +#define __ARCH_SH_INCLUDE_M16C_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers **********************************************************************/ + +/* Fixed vector table */ + +#define M16C_UNDEFINST_IRQ 0 /* fffdc: Undefined instruction */ +#define M16C_OVERFLOW_IRQ 1 /* fffe0: Overflow */ +#define M16C_BRK_IRQ 2 /* fffe4: BRK instruction */ +#define M16C_ADDRMATCH_IRQ 3 /* fffe8: Address match */ +#ifdef CONFIG_M16C_DEBUGGER +# define M16C_SSTEP_IRQ 4 /* fffec: Single step */ +# define M16C_WDOG_IRQ 5 /* ffff0: Watchdog timer */ +# define M16C_DBC_IRQ 6 /* ffff4: DBC */ +# define M16C_NMI_IRQ 7 /* ffff8: NMI */ +# define _LAST_FIXED 7 +#else +# define M16C_WDOG_IRQ 4 /* ffff0: Watchdog timer */ +# define M16C_NMI_IRQ 5 /* ffff8: NMI */ +# define _LAST_FIXED 5 +#endif + +/* Variable vector table (fixed at address 0xffd00) */ + +#ifdef CONFIG_M16C_SWINTS +# define M16C_BRK_IRQ (_LAST_FIXED+1) /* ffd00: BRK instruction */ +# define M16C_SWINT0_IRQ M16C_BRK_IRQ /* S/W interrupt 0 */ +# define M16C_INT3_IRQ (_LAST_FIXED+2) /* ffd10: INT3 */ +# define M16C_SWINT4_IRQ M16C_INT3_IRQ /* S/W interrupt 4 */ +# define M16C_CTXSV_SWINT (_LAST_FIXED+3) /* ffd14: Reserved -- used by NuttX */ +# define M16C_SWINT5_IRQ M16C_CTXSV_SWINT /* S/W interrupt 5 */ +# define M16C_SWINT6_IRQ (_LAST_FIXED+4) /* ffd18: Reserved / S/W interrupt 6 */ +# define M16C_SWINT7_IRQ (_LAST_FIXED+5) /* ffd1c: Reserved / S/W interrupt 7 */ +# define M16C_INT5_IRQ (_LAST_FIXED+6) /* ffd20: INT5 */ +# define M16C_SWINT8_IRQ M16C_INT5_IRQ /* S/W interrupt 8 */ +# define M16C_INT4_IRQ (_LAST_FIXED+7) /* ffd24: INT4 */ +# define M16C_SWINT9_IRQ M16C_INT4_IRQ /* S/W interrupt 9 */ +# define M16C_UART2BCD_IRQ (_LAST_FIXED+8) /* ffd28: UART2 bus collision detection */ +# define M16C_SWINT10_IRQ M16C_UART2BCD_IRQ /* S/W interrupt 10 */ +# define M16C_DMA0_IRQ (_LAST_FIXED+9) /* ffd2c: DMA0 */ +# define M16C_SWINT11_IRQ M16C_DMA0_IRQ /* S/W interrupt 11 */ +# define M16C_DMA1_IRQ (_LAST_FIXED+10) /* ffd30: DMA1 */ +# define M16C_SWINT12_IRQ M16C_DMA1_IRQ /* S/W interrupt 12 */ +# define M16C_KEYINP_IRQ (_LAST_FIXED+11) /* ffd34: Key input interrupt */ +# define M16C_SWINT13_IRQ M16C_KEYINP_IRQ /* S/W interrupt 13 */ +# define M16C_ADC_IRQ (_LAST_FIXED+12) /* ffd38: A-D */ +# define M16C_SWINT14_IRQ M16C_ADC_IRQ /* S/W interrupt 14 */ +# define M16C_UARTXNAK_IRQ (_LAST_FIXED+13) /* ffd3c UART2 transmit/NACK2 */ +# define M16C_SWINT15_IRQ M16C_UARTNAK_IRQ /* S/W interrupt 15 */ +# define M16C_UARTRACK_IRQ (_LAST_FIXED+14) /* ffd40: UART2 receive/ACK2 */ +# define M16C_SWINT16_IRQ M16C_UARTRACK_IRQ /* S/W interrupt 16 */ +# define M16C_UART0XMT_IRQ (_LAST_FIXED+15) /* ffd44: UART0 transmit */ +# define M16C_SWINT17_IRQ M16C_UART0XMT_IRQ /* S/W interrupt 17 */ +# define M16C_UART0RCV_IRQ (_LAST_FIXED+16) /* ffd48: UART0 receive */ +# define M16C_SWINT18_IRQ M16C_UART0RCV_IRQ /* S/W interrupt 18 */ +# define M16C_UART1XMT_IRQ (_LAST_FIXED+17) /* ffd4c: UART1 transmit */ +# define M16C_SWINT19_IRQ M16C_UART1XMT_IRQ /* S/W interrupt 19 */ +# define M16C_UART1RCV_IRQ (_LAST_FIXED+18) /* ffd50: UART1 receive */ +# define M16C_SWINT20_IRQ M16C_UART1RCV_IRQ /* S/W interrupt 20 */ +# define M16C_TMRA0_IRQ (_LAST_FIXED+19) /* ffd54: Timer A0 */ +# define M16C_SWINT21_IRQ M16C_TMRA0_IRQ /* S/W interrupt 21 */ +# define M16C_TMRA1_IRQ (_LAST_FIXED+20) /* ffd58: Timer A1 */ +# define M16C_SWINT22_IRQ M16C_TMRA1_IRQ /* S/W interrupt 22 */ +# define M16C_TMRA2_IRQ (_LAST_FIXED+21) /* ffd5c: Timer A2 */ +# define M16C_SWINT23_IRQ M16C_TMRA2_IRQ /* S/W interrupt 23 */ +# define M16C_TMRA3_IRQ (_LAST_FIXED+22) /* ffd60: Timer A3 */ +# define M16C_SWINT24_IRQ M16C_TMRA3_IRQ /* S/W interrupt 24 */ +# define M16C_TMRA4_IRQ (_LAST_FIXED+23) /* ffd64: Timer A4 */ +# define M16C_SWINT25_IRQ M16C_TMRA4_IRQ /* S/W interrupt 25 */ +# define M16C_TMRB0_IRQ (_LAST_FIXED+24) /* ffd68: Timer B0 */ +# define M16C_SWINT26_IRQ M16C_TMRB0_IRQ /* S/W interrupt 26 */ +# define M16C_TMRB1_IRQ (_LAST_FIXED+25) /* ffd6c: Timer B1 */ +# define M16C_SWINT27_IRQ M16C_TMRB1_IRQ /* S/W interrupt 27 */ +# define M16C_TMRB2_IRQ (_LAST_FIXED+26) /* ffd70: Timer B2 */ +# define M16C_SWINT28_IRQ M16C_TMRB2_IRQ /* S/W interrupt 28 */ +# define M16C_INT0_IRQ (_LAST_FIXED+27) /* ffd74: INT0 */ +# define M16C_SWINT29_IRQ M16C_INT0_IRQ /* S/W interrupt 29 */ +# define M16C_INT1_IRQ (_LAST_FIXED+28) /* ffd78: INT1 */ +# define M16C_SWINT30_IRQ M16C_INT1_IRQ /* S/W interrupt 30 */ +# define M16C_SWINT31_IRQ (_LAST_FIXED+29) /* ffd7c: Reserved / S/W interrupt 31 */ +# define M16C_CTXRSTR_SWINT (_LAST_FIXED+30) /* ffd80: Used by NuttX */ +# define M16C_SWINT32IRQ M16C_CTXRSTR_SWINT /* S/W interrupt 32 */ +# define M16C_SWINT33_IRQ (_LAST_FIXED+31) /* ffd84: S/W interrupt 33 */ +# define M16C_SWINT34_IRQ (_LAST_FIXED+32) /* ffd88: S/W interrupt 34 */ +# define M16C_SWINT35_IRQ (_LAST_FIXED+33) /* ffd8c: S/W interrupt 35 */ +# define M16C_SWINT36_IRQ (_LAST_FIXED+34) /* ffd90: S/W interrupt 36 */ +# define M16C_SWINT37_IRQ (_LAST_FIXED+35) /* ffd94: S/W interrupt 37 */ +# define M16C_SWINT38_IRQ (_LAST_FIXED+36) /* ffd98: S/W interrupt 38 */ +# define M16C_SWINT39_IRQ (_LAST_FIXED+37) /* ffd9c: S/W interrupt 39 */ +# define M16C_SWINT40_IRQ (_LAST_FIXED+38) /* ffda0: S/W interrupt 40 */ +# define M16C_SWINT41_IRQ (_LAST_FIXED+39) /* ffda4: S/W interrupt 41 */ +# define M16C_SWINT42_IRQ (_LAST_FIXED+40) /* ffda8: S/W interrupt 42 */ +# define M16C_SWINT43_IRQ (_LAST_FIXED+41) /* ffdac: S/W interrupt 43 */ +# define M16C_SWINT44_IRQ (_LAST_FIXED+42) /* ffdb0: S/W interrupt 44 */ +# define M16C_SWINT45_IRQ (_LAST_FIXED+43) /* ffdb4: S/W interrupt 45 */ +# define M16C_SWINT46_IRQ (_LAST_FIXED+44) /* ffdb8: S/W interrupt 46 */ +# define M16C_SWINT47_IRQ (_LAST_FIXED+45) /* ffdbc: S/W interrupt 47 */ +# define M16C_SWINT48_IRQ (_LAST_FIXED+46) /* ffdc0: S/W interrupt 48 */ +# define M16C_SWINT49_IRQ (_LAST_FIXED+47) /* ffdc4: S/W interrupt 49 */ +# define M16C_SWINT50_IRQ (_LAST_FIXED+48) /* ffdc8: S/W interrupt 50 */ +# define M16C_SWINT51_IRQ (_LAST_FIXED+49) /* ffdcc: S/W interrupt 51 */ +# define M16C_SWINT52_IRQ (_LAST_FIXED+50) /* ffdd0: S/W interrupt 52 */ +# define M16C_SWINT53_IRQ (_LAST_FIXED+51) /* ffdd4: S/W interrupt 53 */ +# define M16C_SWINT54_IRQ (_LAST_FIXED+52) /* ffdd8: S/W interrupt 54 */ +# define M16C_SWINT55_IRQ (_LAST_FIXED+53) /* ffddc: S/W interrupt 55 */ +# define M16C_SWINT56_IRQ (_LAST_FIXED+54) /* ffde0: S/W interrupt 56 */ +# define M16C_SWINT57_IRQ (_LAST_FIXED+55) /* ffde4: S/W interrupt 57 */ +# define M16C_SWINT58_IRQ (_LAST_FIXED+56) /* ffde8: S/W interrupt 58 */ +# define M16C_SWINT59_IRQ (_LAST_FIXED+57) /* ffdec: S/W interrupt 59 */ +# define M16C_SWINT60_IRQ (_LAST_FIXED+58) /* ffdf0: S/W interrupt 60 */ +# define M16C_SWINT61_IRQ (_LAST_FIXED+59) /* ffdf4: S/W interrupt 61 */ +# define M16C_SWINT62_IRQ (_LAST_FIXED+60) /* ffdf8: S/W interrupt 62 */ +# define M16C_SWINT63_IRQ (_LAST_FIXED+61) /* ffdfc: S/W interrupt 63 */ + +# define NR_IRQS (_LAST_FIXED+62) /* Total number of supported IRQs */ +#else +# define M16C_BRK_IRQ (_LAST_FIXED+1) /* ffd00: BRK instruction */ +# define M16C_INT3_IRQ (_LAST_FIXED+2) /* ffd10: INT3 */ +# define M16C_CTXSV_SWINT (_LAST_FIXED+3) /* ffd14: Reserved -- SWINT5 used by NuttX */ +# define M16C_INT5_IRQ (_LAST_FIXED+5) /* ffd20: INT5 */ +# define M16C_INT4_IRQ (_LAST_FIXED+6) /* ffd24: INT4 */ +# define M16C_UART2BCD_IRQ (_LAST_FIXED+7) /* ffd28: UART2 bus collision detection */ +# define M16C_DMA0_IRQ (_LAST_FIXED+8) /* ffd2c: DMA0 */ +# define M16C_DMA1_IRQ (_LAST_FIXED+9) /* ffd30: DMA1 */ +# define M16C_KEYINP_IRQ (_LAST_FIXED+10) /* ffd34: Key input interrupt */ +# define M16C_ADC_IRQ (_LAST_FIXED+11) /* ffd38: A-D */ +# define M16C_UARTXNAK_IRQ (_LAST_FIXED+12) /* ffd3c UART2 transmit/NACK2 */ +# define M16C_UARTRACK_IRQ (_LAST_FIXED+13) /* ffd40: UART2 receive/ACK2 */ +# define M16C_UART0XMT_IRQ (_LAST_FIXED+14) /* ffd44: UART0 transmit */ +# define M16C_UART0RCV_IRQ (_LAST_FIXED+15) /* ffd48: UART0 receive */ +# define M16C_UART1XMT_IRQ (_LAST_FIXED+16) /* ffd4c: UART1 transmit */ +# define M16C_UART1RCV_IRQ (_LAST_FIXED+17) /* ffd50: UART1 receive */ +# define M16C_TMRA0_IRQ (_LAST_FIXED+18) /* ffd54: Timer A0 */ +# define M16C_TMRA1_IRQ (_LAST_FIXED+19) /* ffd58: Timer A1 */ +# define M16C_TMRA2_IRQ (_LAST_FIXED+20) /* ffd5c: Timer A2 */ +# define M16C_TMRA3_IRQ (_LAST_FIXED+21) /* ffd60: Timer A3 */ +# define M16C_TMRA4_IRQ (_LAST_FIXED+22) /* ffd64: Timer A4 */ +# define M16C_TMRB0_IRQ (_LAST_FIXED+23) /* ffd68: Timer B0 */ +# define M16C_TMRB1_IRQ (_LAST_FIXED+24) /* ffd6c: Timer B1 */ +# define M16C_TMRB2_IRQ (_LAST_FIXED+25) /* ffd70: Timer B2 */ +# define M16C_INT0_IRQ (_LAST_FIXED+26) /* ffd74: INT0 */ +# define M16C_INT1_IRQ (_LAST_FIXED+27) /* ffd78: INT1 */ +# define M16C_CTXRSTR_SWINT (_LAST_FIXED+4) /* ffd80: S/W interrupt 32, used by NuttX */ + +# define NR_IRQS (_LAST_FIXED+28) /* Total number of supported IRQs */ +#endif + +/* Timer A0 is the system timer used by NuttX */ + +#define M16C_SYSTIMER_IRQ M16C_TMRA0_IRQ + +/* IRQ Stack Frame Format. The M16C has a push down stack. The CPU performs + * the following actions when an interrupt is taken: + * + * - Save FLG register + * - Clear I, D, and U flags in FLG register + * - Builds stack frame like: + * + * sp -> PC bits 0-7 + * sp+1 -> PC bits 8-15 + * sp+2 -> FLG bits 0-7 + * sp+3 -> FLG (Bits 12-14) + PC (bits 16-19) + * + * - Sets IPL + * - Vectors to interrupt handler + */ + +#define REG_FLGPCHI 0 /* 8-bit FLG (bits 12-14) + PC (bits 16-19) as would be + * presented by an interrupt */ +#define REG_FLG 1 /* 8-bit FLG register (bits 0-7) */ +#define REG_PC 2 /* 16-bit PC [0]:bits8-15 [1]:bits 0-7 */ +#define REG_FB 4 /* 16-bit FB register */ +#define REG_SB 6 /* 16-bit SB register */ +#define REG_A1 8 /* 16-bit A1 register */ +#define REG_A0 10 /* 16-bit A0 register */ +#define REG_R3 12 /* 16-bit R3 register */ +#define REG_R2 14 /* 16-bit R2 register */ +#define REG_R1 16 /* 16-bit R1 register */ +#define REG_R0 18 /* 16-bit R0 register */ +#define REG_SP 20 /* 16-bit user stack pointer */ + +#define XCPTCONTEXT_SIZE 22 + +/************************************************************************************ + * Public Types + ************************************************************************************/ +/* This struct defines the way the registers are stored. We need to save: */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR and SR used during signal processing. */ + + uint8_t saved_pc[2]; + uint8_t saved_flg; +#endif + + /* Register save area */ + + uint8_t regs[XCPTCONTEXT_SIZE]; +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Save the current interrupt enable state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t flags; + __asm__ __volatile__ + ( + "\tstc flg, %0\n" + "\tfclr I\n" + : "=r" (flags) + : + : "memory"); + return flags; +} + +/* Restore saved IRQ & FIQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + __asm__ __volatile__ + ( + "ldc %0, flg" + : + : "r" (flags) + : "memory"); +} + +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_SH_INCLUDE_M16C_IRQ_H */ + diff --git a/arch/sh/include/m16c/limits.h b/arch/sh/include/m16c/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..27723d99686748d6b2ce97b7d8389818df5c084f --- /dev/null +++ b/arch/sh/include/m16c/limits.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/sh/include/m16c/limits.h + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SH_INCLUDE_M16C_LIMITS_H +#define __ARCH_SH_INCLUDE_M16C_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* For M16C, type int is 16-bits, the same size as type 'short int' */ + +#define INT_MIN SHRT_MIN +#define INT_MAX SHRT_MAX +#define UINT_MAX USHRT_MAX + +/* For M16C, typle 'long int' is 32-bits */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_SH_INCLUDE_M16C_LIMITS_H */ diff --git a/arch/sh/include/m16c/types.h b/arch/sh/include/m16c/types.h new file mode 100644 index 0000000000000000000000000000000000000000..3211209e93f20e15630605ea9a856d015a1e0c9c --- /dev/null +++ b/arch/sh/include/m16c/types.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/sh/include/m16c/types.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly\ + * through sys/types.h + */ + +#ifndef __ARCH_SH_INCLUDE_M16C_TYPES_H +#define __ARCH_SH_INCLUDE_M16C_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + * + * int is 16-bits and long is 32-bits + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed int _int16_t; +typedef unsigned int _uint16_t; + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 2 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef _uint16_t irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_M16C_TYPES_H */ diff --git a/arch/sh/include/serial.h b/arch/sh/include/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..2ec4ac9054a47ad0918eb69951ea00280da4eec3 --- /dev/null +++ b/arch/sh/include/serial.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/sh/include/serial.h + * + * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SH_INCLUDE_SERIAL_H +#define __ARCH_SH_INCLUDE_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_SERIAL_H */ diff --git a/arch/sh/include/sh1/irq.h b/arch/sh/include/sh1/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..b4af921bdbbf280d66211ea7f9dc67e58d6f084d --- /dev/null +++ b/arch/sh/include/sh1/irq.h @@ -0,0 +1,567 @@ +/************************************************************************************ + * arch/sh/include/sh1/irq.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_SH_INCLUDE_SH1_IRQ_H +#define __ARCH_SH_INCLUDE_SH1_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ channels */ + +/* In the current implementation, CMON catches the following IRQ. + * Support for traps can be provided by simply enabling the following, adding + * vectors in sh1_head.S and adding handlers in sh1_vector.S + */ + +/* Illegal instructions / Address errors */ + +#if 0 /* Handled by CMON */ +# define SH1_INVINSTR_IRQ (0) /* General invalid instruction */ +# define SH1_INVSLOT_IRQ (1) /* Invalid slot instruction */ +# define SH1_BUSERR_IRQ (2) /* CPU bus error */ +# define SH1_DMAERR_IRQ (3) /* DMA bus error */ +# define SH1_NMI_IRQ (4) /* NMI */ +# define SH1_USRBRK_IRQ (6) /* User break */ +# define SH1_TRAP_IRQBASE (7) + +# define SH1_TRAP0_IRQ SH1_TRAP_IRQBASE /* TRAPA instruction (user break) */ +# define SH1_TRAP1_IRQ (SH1_TRAP_IRQBASE+1) /* " " " " " " " " */ +# define SH1_TRAP2_IRQ (SH1_TRAP_IRQBASE+2) /* " " " " " " " " */ +# define SH1_TRAP3_IRQ (SH1_TRAP_IRQBASE+3) /* " " " " " " " " */ +# define SH1_TRAP4_IRQ (SH1_TRAP_IRQBASE+4) /* " " " " " " " " */ +# define SH1_TRAP5_IRQ (SH1_TRAP_IRQBASE+5) /* " " " " " " " " */ +# define SH1_TRAP6_IRQ (SH1_TRAP_IRQBASE+6) /* " " " " " " " " */ +# define SH1_TRAP7_IRQ (SH1_TRAP_IRQBASE+7) /* " " " " " " " " */ +# define SH1_TRAP8_IRQ (SH1_TRAP_IRQBASE+8) /* " " " " " " " " */ +# define SH1_TRAP9_IRQ (SH1_TRAP_IRQBASE+9) /* " " " " " " " " */ +# define SH1_TRAP10_IRQ (SH1_TRAP_IRQBASE+10) /* " " " " " " " " */ +# define SH1_TRAP11_IRQ (SH1_TRAP_IRQBASE+11) /* " " " " " " " " */ +# define SH1_TRAP12_IRQ (SH1_TRAP_IRQBASE+12) /* " " " " " " " " */ +# define SH1_TRAP13_IRQ (SH1_TRAP_IRQBASE+13) /* " " " " " " " " */ +# define SH1_TRAP14_IRQ (SH1_TRAP_IRQBASE+14) /* " " " " " " " " */ +# define SH1_TRAP15_IRQ (SH1_TRAP_IRQBASE+15) /* " " " " " " " " */ +# define SH1_TRAP16_IRQ (SH1_TRAP_IRQBASE+16) /* " " " " " " " " */ +# define SH1_TRAP17_IRQ (SH1_TRAP_IRQBASE+17) /* " " " " " " " " */ +# define SH1_TRAP18_IRQ (SH1_TRAP_IRQBASE+18) /* " " " " " " " " */ +# define SH1_TRAP19_IRQ (SH1_TRAP_IRQBASE+19) /* " " " " " " " " */ +# define SH1_TRAP20_IRQ (SH1_TRAP_IRQBASE+20) /* " " " " " " " " */ +# define SH1_TRAP21_IRQ (SH1_TRAP_IRQBASE+21) /* " " " " " " " " */ +# define SH1_TRAP22_IRQ (SH1_TRAP_IRQBASE+22) /* " " " " " " " " */ +# define SH1_TRAP23_IRQ (SH1_TRAP_IRQBASE+23) /* " " " " " " " " */ +# define SH1_TRAP24_IRQ (SH1_TRAP_IRQBASE+24) /* " " " " " " " " */ +# define SH1_TRAP25_IRQ (SH1_TRAP_IRQBASE+25) /* " " " " " " " " */ +# define SH1_TRAP26_IRQ (SH1_TRAP_IRQBASE+26) /* " " " " " " " " */ +# define SH1_TRAP27_IRQ (SH1_TRAP_IRQBASE+27) /* " " " " " " " " */ +# define SH1_TRAP28_IRQ (SH1_TRAP_IRQBASE+28) /* " " " " " " " " */ +# define SH1_TRAP29_IRQ (SH1_TRAP_IRQBASE+29) /* " " " " " " " " */ +# define SH1_TRAP30_IRQ (SH1_TRAP_IRQBASE+30) /* " " " " " " " " */ +# define SH1_TRAP31_IRQ (SH1_TRAP_IRQBASE+31) /* " " " " " " " " */ +# define SH1_IRQ_IRQBASE (SH1_TRAP_IRQBASE+32) + +/* Interrupts */ + +# define SH1_IRQ0_IRQ SH1_IRQ_IRQBASE /* IRQ0 */ +# define SH1_IRQ1_IRQ (SH1_IRQ_IRQBASE+1) /* IRQ1 */ +# define SH1_IRQ2_IRQ (SH1_IRQ_IRQBASE+2) /* IRQ2 */ +# define SH1_IRQ3_IRQ (SH1_IRQ_IRQBASE+3) /* IRQ3 */ +# define SH1_IRQ4_IRQ (SH1_IRQ_IRQBASE+4) /* IRQ4 */ +# define SH1_IRQ5_IRQ (SH1_IRQ_IRQBASE+5) /* IRQ5 */ +# define SH1_IRQ6_IRQ (SH1_IRQ_IRQBASE+6) /* IRQ6 */ +# define SH1_IRQ7_IRQ (SH1_IRQ_IRQBASE+7) /* IRQ7 */ +# define SH1_CHIP_IRQBASE (SH1_IRQ_IRQBASE+8) +#else +# define SH1_CHIP_IRQBASE (0) +#endif + +/* On-chip modules -- The following may be unique to the 7032 */ + +#ifdef CONFIG_ARCH_CHIP_SH7032 + +/* DMAC */ + +#ifdef CONFIG_SH1_DMAC0 /* DMAC0 */ +# define SH1_DEI0_IRQ SH1_CHIP_IRQBASE /* DEI0 */ +# define SH1_DMAC1_IRQBASE (SH1_CHIP_IRQBASE+1) +#else +# define SH1_DMAC1_IRQBASE SH1_CHIP_IRQBASE +#endif + +#ifdef CONFIG_SH1_DMAC1 /* DMAC1 */ +# define SH1_DEI1_IRQ SH1_DMAC1_IRQBASE /* DEI1 */ +# define SH1_DMAC2_IRQBASE (SH1_DMAC1_IRQBASE+1) +#else +# define SH1_DMAC2_IRQBASE SH1_DMAC1_IRQBASE +#endif + +#ifdef CONFIG_SH1_DMAC2 /* DMAC2 */ +# define SH1_DEI2_IRQ SH1_DMAC2_IRQBASE /* DEI2 */ +# define SH1_DMAC3_IRQBASE (SH1_DMAC2_IRQBASE+1) +#else +# define SH1_DMAC3_IRQBASE SH1_DMAC2_IRQBASE +#endif + +#ifdef CONFIG_SH1_DMAC3 /* DMAC3 */ +# define SH1_DEI3_IRQ SH1_DMAC3_IRQBASE /* DEI3 */ +# define SH1_ITU0_IRQBASE (SH1_DMAC3_IRQBASE+1) +#else +# define SH1_ITU0_IRQBASE SH1_DMAC3_IRQBASE +#endif + +/* ITU */ + +/* ITU0 is the system clock and is always defined */ + +#define SH1_IMIA0_IRQ SH1_ITU0_IRQBASE /* IMIA0 */ +#define SH1_IMIB0_IRQ (SH1_ITU0_IRQBASE+1) /* IMIB0 */ +#define SH1_OVI0_IRQ (SH1_ITU0_IRQBASE+2) /* OVI0 */ +#define SH1_ITU1_IRQBASE (SH1_ITU0_IRQBASE+3) + +#ifdef CONFIG_SH1_ITU1 /* ITU1 */ +# define SH1_IMIA1_IRQ SH1_ITU1_IRQBASE /* IMIA1 */ +# define SH1_IMIB1_IRQ (SH1_ITU1_IRQBASE+1) /* IMIB1 */ +# define SH1_OVI1_IRQ (SH1_ITU1_IRQBASE+2) /* OVI1 */ +# define SH1_ITU2_IRQBASE (SH1_ITU1_IRQBASE+3) +#else +# define SH1_ITU2_IRQBASE SH1_ITU1_IRQBASE +#endif + +#ifdef CONFIG_SH1_ITU2 /* ITU2 */ +# define SH1_IMIA2_IRQ SH1_ITU2_IRQBASE /* IMIA2 */ +# define SH1_IMIB2_IRQ (SH1_ITU2_IRQBASE+1) /* IMIB2 */ +# define SH1_OVI2_IRQ (SH1_ITU2_IRQBASE+2) /* OVI2 */ +# define SH1_ITU3_IRQBASE (SH1_ITU2_IRQBASE+3) +#else +# define SH1_ITU3_IRQBASE SH1_ITU2_IRQBASE +#endif + +#ifdef CONFIG_SH1_ITU3 /* ITU3 */ +# define SH1_IMIA3_IRQ SH1_ITU3_IRQBASE /* IMIA3 */ +# define SH1_IMIB3_IRQ (SH1_ITU3_IRQBASE+1) /* IMIB3 */ +# define SH1_OVI3_IRQ (SH1_ITU3_IRQBASE+2) /* OVI3 */ +# define SH1_ITU4_IRQBASE (SH1_ITU3_IRQBASE+3) +#else +# define SH1_ITU4_IRQBASE SH1_ITU3_IRQBASE +#endif + +#ifdef CONFIG_SH1_ITU4 /* ITU4 */ +# define SH1_IMIA4_IRQ SH1_ITU4_IRQBASE /* IMIA4 */ +# define SH1_IMIB4_IRQ (SH1_ITU4_IRQBASE+1) /* IMIB4 */ +# define SH1_OVI4_IRQ (SH1_ITU4_IRQBASE+2) /* OVI4 */ +# define SH1_SCI0_IRQBASE (SH1_ITU4_IRQBASE+3) +#else +# define SH1_SCI0_IRQBASE SH1_ITU4_IRQBASE +#endif + +/* SCI */ + +#define SH1_ERI_IRQ_OFFSET (0) /* ERI0 */ +#define SH1_RXI_IRQ_OFFSET (1) /* RxI0 */ +#define SH1_TXI_IRQ_OFFSET (2) /* TxI0 */ +#define SH1_TEI_IRQ_OFFSET (3) /* TEI0 */ +#define SH1_SCI_NIRQS (4) + +#ifdef CONFIG_SH1_SCI0 /* SCI0 */ +# define SH1_ERI0_IRQ (SH1_SCI0_IRQBASE+SH1_ERI_IRQ_OFFSET) /* ERI0 */ +# define SH1_RXI0_IRQ (SH1_SCI0_IRQBASE+SH1_RXI_IRQ_OFFSET) /* RxI0 */ +# define SH1_TXI0_IRQ (SH1_SCI0_IRQBASE+SH1_TXI_IRQ_OFFSET) /* TxI0 */ +# define SH1_TEI0_IRQ (SH1_SCI0_IRQBASE+SH1_TEI_IRQ_OFFSET) /* TEI0 */ +# define SH1_SCI1_IRQBASE (SH1_SCI0_IRQBASE+SH1_SCI_NIRQS) +#else +# define SH1_SCI1_IRQBASE SH1_SCI0_IRQBASE +#endif + +#ifdef CONFIG_SH1_SCI1 /* SCI1 */ +# define SH1_ERI1_IRQ (SH1_SCI1_IRQBASE+SH1_ERI_IRQ_OFFSET) /* ERI1 */ +# define SH1_RXI1_IRQ (SH1_SCI1_IRQBASE+SH1_RXI_IRQ_OFFSET) /* RxI1 */ +# define SH1_TXI1_IRQ (SH1_SCI1_IRQBASE+SH1_TXI_IRQ_OFFSET) /* TxI1 */ +# define SH1_TEI1_IRQ (SH1_SCI1_IRQBASE+SH1_TEI_IRQ_OFFSET) /* TEI1 */ +# define SH1_PEI_IRQBASE (SH1_SCI1_IRQBASE+SH1_SCI_NIRQS) +#else +# define SH1_PEI_IRQBASE SH1_SCI1_IRQBASE +#endif + +#ifdef CONFIG_SH1_PCU +# define SH1_PEI_IRQ SH1_PEI_IRQBASE /* Parity control unit PEI */ +# define SH1_AD_IRQBASE (SH1_PEI_IRQBASE+1) +#else +# define SH1_AD_IRQBASE SH1_PEI_IRQBASE +#endif + +#ifdef CONFIG_SH1_AD +# define SH1_ADITI_IRQ SH1_AD_IRQBASE /* A/D ITI */ +# define SH1_WDT_IRQBASE (SH1_AD_IRQBASE+1) +#else +# define SH1_WDT_IRQBASE SH1_AD_IRQBASE +#endif + +#ifdef CONFIG_SH1_WDT +# define SH1_WDTITI_IRQ SH1_WDT_IRQBASE /* WDT ITI */ +# define SH1_CMI_IRQBASE (SH1_WDT_IRQBASE+1) +#else +# define SH1_CMI_IRQBASE SH1_WDT_IRQBASE +#endif + +#ifdef CONFIG_SH1_CMI +# define SH1_CMI_IRQ SH1_CMI_IRQBASE /* REF CMI */ +# define NR_IRQS (SH1_CMI_IRQBASE+1) /* Total number of supported IRQs */ +#else +# define NR_IRQS SH1_CMI_IRQBASE /* Total number of supported IRQs */ +#endif + +#define SH1_SYSTIMER_IRQ SH1_IMIA0_IRQ +#endif + +/* Vector table offets **************************************************************/ + +/* The following provides the vector numbers for each IRQ. The IRQ numbers (above) + * form the densely packet number space used by the system to identify IRQs. The + * following are the (relatively) loosely spaced offsets that identify the location + * of the corresponding vector in the vector table. + * + * These offsets are specified as a vector number (suitably for indexing an array + * of uint32_t) but would have to by multiplied by 4 to get an addressable, byte + * offset. + */ + +/* Resets */ + +#define SH1_PWRONPC_VNDX (0) /* 0: Power-on reset (hard, NMI high) PC*/ +#define SH1_PWRONSP_VNDX (1) /* 1: Power-on reset (hard, NMI high) SP */ +#define SH1_MRESETPC_VNDX (2) /* 2: Power-on reset (hard, NMI high) PC*/ +#define SH1_MRESETSP_VNDX (3) /* 3: Power-on reset (hard, NMI high) SP */ + +/* Illegal instructions / Address errors */ + +#define SH1_INVINSTR_VNDX (4) /* 4: General invalid instruction */ + /* 5: Reserved for system */ +#define SH1_INVSLOT_VNDX (6) /* 6: Invalid slot instruction */ + /* 7-8: Reserved for system */ +#define SH1_BUSERR_VNDX (9) /* 9: CPU bus error */ +#define SH1_DMAERR_VNDX (10) /* 10: DMA bus error */ + +/* NMI, user break */ + +#define SH1_NMI_VNDX (11) /* 11: NMI */ +#define SH1_USRBRK_VNDX (12) /* 12: User break */ + /* 13-31: Reserved for system */ +/* Trap instruction */ + +#define SH1_TRAP_VNDX (32) /* 32-63: TRAPA instruction (user break) */ +#define SH1_TRAP0_VNDX (32) /* 32: TRAPA instruction (user break) */ +#define SH1_TRAP1_VNDX (33) /* 33: " " " " " " " " */ +#define SH1_TRAP2_VNDX (34) /* 34: " " " " " " " " */ +#define SH1_TRAP3_VNDX (35) /* 35: " " " " " " " " */ +#define SH1_TRAP4_VNDX (36) /* 36: " " " " " " " " */ +#define SH1_TRAP5_VNDX (37) /* 37: " " " " " " " " */ +#define SH1_TRAP6_VNDX (38) /* 38: " " " " " " " " */ +#define SH1_TRAP7_VNDX (39) /* 39: " " " " " " " " */ +#define SH1_TRAP8_VNDX (40) /* 40: " " " " " " " " */ +#define SH1_TRAP9_VNDX (41) /* 41: " " " " " " " " */ +#define SH1_TRAP10_VNDX (42) /* 42: " " " " " " " " */ +#define SH1_TRAP11_VNDX (43) /* 43: " " " " " " " " */ +#define SH1_TRAP12_VNDX (44) /* 44: " " " " " " " " */ +#define SH1_TRAP13_VNDX (45) /* 45: " " " " " " " " */ +#define SH1_TRAP14_VNDX (46) /* 46: " " " " " " " " */ +#define SH1_TRAP15_VNDX (47) /* 47: " " " " " " " " */ +#define SH1_TRAP16_VNDX (48) /* 48: " " " " " " " " */ +#define SH1_TRAP17_VNDX (49) /* 49: " " " " " " " " */ +#define SH1_TRAP18_VNDX (50) /* 50: " " " " " " " " */ +#define SH1_TRAP19_VNDX (51) /* 51: " " " " " " " " */ +#define SH1_TRAP20_VNDX (52) /* 52: " " " " " " " " */ +#define SH1_TRAP21_VNDX (53) /* 53: " " " " " " " " */ +#define SH1_TRAP22_VNDX (54) /* 54: " " " " " " " " */ +#define SH1_TRAP23_VNDX (55) /* 55: " " " " " " " " */ +#define SH1_TRAP24_VNDX (56) /* 56: " " " " " " " " */ +#define SH1_TRAP25_VNDX (57) /* 57: " " " " " " " " */ +#define SH1_TRAP26_VNDX (58) /* 58: " " " " " " " " */ +#define SH1_TRAP27_VNDX (59) /* 59: " " " " " " " " */ +#define SH1_TRAP28_VNDX (60) /* 60: " " " " " " " " */ +#define SH1_TRAP29_VNDX (61) /* 61: " " " " " " " " */ +#define SH1_TRAP30_VNDX (62) /* 62: " " " " " " " " */ +#define SH1_TRAP31_VNDX (63) /* 63: " " " " " " " " */ + +/* Interrupts */ + +#define SH1_IRQ_VNDX (64) /* 64-71: IRQ0-7 */ +#define SH1_IRQ0_VNDX (64) /* 64: IRQ0 */ +#define SH1_IRQ1_VNDX (65) /* 65: IRQ1 */ +#define SH1_IRQ2_VNDX (66) /* 66: IRQ2 */ +#define SH1_IRQ3_VNDX (67) /* 67: IRQ3 */ +#define SH1_IRQ4_VNDX (68) /* 68: IRQ4 */ +#define SH1_IRQ5_VNDX (69) /* 69: IRQ5 */ +#define SH1_IRQ6_VNDX (70) /* 70: IRQ6 */ +#define SH1_IRQ7_VNDX (71) /* 71: IRQ7 */ + +#define SH1_LASTCMN_VNDX (71) +#define SH1_NCMN_VECTORS (72) + +/* On-chip modules -- The following may be unique to the 7032 */ + +#ifdef CONFIG_ARCH_CHIP_SH7032 + +/* DMAC */ + +#define SH1_DMAC0_VNDX (72) /* 72-73: DMAC0 */ +#define SH1_DEI0_VNDX (72) /* 72: DMAC0 DEI0 */ + /* 73: Reserved */ +#define SH1_DMAC1_VNDX (74) /* 74-75: DMAC1 */ +#define SH1_DEI1_VNDX (74) /* 74: DMAC1 DEI1 */ + /* 75: Reserved */ +#define SH1_DMAC2_VNDX (76) /* 76-77: DMAC2 */ +#define SH1_DEI2_VNDX (76) /* 76: DMAC2 DEI2 */ + /* 77: Reserved */ +#define SH1_DMAC3_VNDX (78) /* 78-79: DMAC3 */ +#define SH1_DEI3_VNDX (78) /* 78: DMAC3 DEI3 */ + /* 79: Reserved */ +/* ITU */ + +#define SH1_IMIA0_VNDX (80) /* 80: ITU0 IMIA0 */ +#define SH1_IMIB0_VNDX (81) /* 81: IMIB0 */ +#define SH1_OVI0_VNDX (82) /* 82: OVI0 */ + /* 83: Reserved */ +#define SH1_IMIA1_VNDX (84) /* 84: ITU1 IMIA1 */ +#define SH1_IMIB1_VNDX (85) /* 85: IMIB1 */ +#define SH1_OVI1_VNDX (86) /* 86: OVI1 */ + /* 87: Reserved */ +#define SH1_IMIA2_VNDX (88) /* 88: ITU2 IMIA2 */ +#define SH1_IMIB2_VNDX (89) /* 89: IMIB2 */ +#define SH1_OVI2_VNDX (90) /* 90: OVI2 */ + /* 91: Reserved */ +#define SH1_IMIA3_VNDX (92) /* 92: ITU3 IMIA3 */ +#define SH1_IMIB3_VNDX (93) /* 93: IMIB3 */ +#define SH1_OVI3_VNDX (94) /* 94: OVI3 */ + /* 95: Reserved */ +#define SH1_IMIA4_VNDX (96) /* 96: ITU4 IMIA4 */ +#define SH1_IMIB4_VNDX (97) /* 97: IMIB4 */ +#define SH1_OVI4_VNDX (98) /* 98: OVI4 */ + /* 99: Reserved */ +/* SCI */ + +#define SH1_ERI0_VNDX (100) /* 100: SCI0 ERI0 */ +#define SH1_RXI0_VNDX (101) /* 101: RxI0 */ +#define SH1_TXI0_VNDX (102) /* 102: TxI0 */ +#define SH1_TEI0_VNDX (103) /* 103: TEI0 */ + +#define SH1_ERI1_VNDX (104) /* 104: SCI1 ERI1 */ +#define SH1_RXI1_VNDX (105) /* 105: RxI1 */ +#define SH1_TXI1_VNDX (106) /* 106: TxI1 */ +#define SH1_TEI1_VNDX (107) /* 107: TEI1 */ + +#define SH1_PEI_VNDX (108) /* 108: Parity control unit PEI */ +#define SH1_ADITI_VNDX (109) /* 109: A/D ITI */ + /* 110-111: Reserved */ +#define SH1_WDTITI_VNDX (112) /* 112: WDT ITI */ +#define SH1_CMI_VNDX (113) /* 113: REF CMI */ + /* 114-115: Reserved */ +/* 116-255 reserved */ +#endif + +#define SH1_LAST_VNDX (255) +#define SH1_NVECTORS (256) + +/* IRQ Stack Frame Format. The SH-1 has a push down stack. The PC + * and SR are pushed by hardware at the time an IRQ is taken. + */ + +/* Saved to the stacked by up_vector */ + +#define REG_R8 (0) +#define REG_R9 (1) +#define REG_R10 (2) +#define REG_R11 (3) +#define REG_R12 (4) +#define REG_R13 (5) +#define REG_R14 (6) + +#define REG_PR (7) +#define REG_GBR (8) + +/* The value of the stack pointer *before* the interrupt occurred */ + +#define REG_R15 (9) +#define REG_SP REG_R15 + +/* These registers do not need to be preserved by up_saveusercontext */ + +#define REG_MACL (10) +#define REG_MACH (11) +#define REG_R0 (12) +#define REG_R1 (13) +#define REG_R2 (14) +#define REG_R3 (15) +#define REG_R5 (16) +#define REG_R6 (17) +#define REG_R7 (18) + +/* Saved to the stack by the trampoline logic */ + +#define REG_R4 (19) + +/* Pushed by hardware when the exception is taken */ + +#define REG_PC (20) +#define REG_SR (21) + +#define XCPTCONTEXT_REGS (22) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* This struct defines the way the registers are stored. We need to save: */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR and SR used during signal processing. */ + + uint32_t saved_pc; + uint32_t saved_sr; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Get the current value of the SR */ + +static inline irqstate_t __getsr(void) +{ + irqstate_t flags; + + __asm__ __volatile__ ("stc sr, %0" : "=r" (flags)); + return flags; +} + +/* Set the new value of the SR */ + +static inline void __setsr(irqstate_t sr) +{ + __asm__ __volatile__ ("ldc %0, sr" : : "r" (sr)); +} + +/* Return the current interrupt enable state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t flags = __getsr(); + __setsr(flags | 0x000000f0); + return flags; +} + +/* Disable IRQs */ + +static inline void up_irq_disable(void) +{ + uint32_t flags = __getsr(); + __setsr(flags | 0x000000f0); +} +/* Enable IRQs */ + +static inline void up_irq_enable(void) +{ + uint32_t flags = __getsr(); + __setsr(flags & ~0x000000f0); +} + +/* Restore saved IRQ state */ + +static inline void up_irq_restore(irqstate_t flags) +{ + if ((flags & 0x000000f0) != 0x000000f0) + { + up_irq_enable(); + } + else + { + up_irq_disable(); + } +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_SH_INCLUDE_SH1_IRQ_H */ + diff --git a/arch/sh/include/sh1/limits.h b/arch/sh/include/sh1/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..071189c4ec1afdf1a77634b6f221620a80be9cec --- /dev/null +++ b/arch/sh/include/sh1/limits.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/sh/include/sh1/limits.h + * + * Copyright (C) 2008, 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SH_INCLUDE_SH1_LIMITS_H +#define __ARCH_SH_INCLUDE_SH1_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* On SH-1, type 'int' is 32-bits */ + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* On SH-1, type 'long' is the same size as type 'int', 32-bits */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_SH_INCLUDE_SH1_LIMITS_H */ diff --git a/arch/sh/include/sh1/types.h b/arch/sh/include/sh1/types.h new file mode 100644 index 0000000000000000000000000000000000000000..aeafe71c3d6cc4eb08971ba29bc3ff8c1e6a152c --- /dev/null +++ b/arch/sh/include/sh1/types.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/sh/include/sh1/types.h + * + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly\ + * through sys/types.h + */ + +#ifndef __ARCH_SH_INCLUDE_SH1_TYPES_H +#define __ARCH_SH_INCLUDE_SH1_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef unsigned long irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_SH1_TYPES_H */ diff --git a/arch/sh/include/syscall.h b/arch/sh/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..b26dffcd39ca1b7d3c3c0597b037a143146f8ac4 --- /dev/null +++ b/arch/sh/include/syscall.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/sh/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_SH_INCLUDE_SYSCALL_H +#define __ARCH_SH_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_SH_INCLUDE_SYSCALL_H */ + diff --git a/arch/sh/include/types.h b/arch/sh/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..db6c6178ad30cc9b66fb14381d45d4edba009a1c --- /dev/null +++ b/arch/sh/include/types.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/sh/include/types.h + * + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_SH_INCLUDE_TYPES_H +#define __ARCH_SH_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_TYPES_H */ diff --git a/arch/sh/include/watchdog.h b/arch/sh/include/watchdog.h new file mode 100644 index 0000000000000000000000000000000000000000..091729833cd5c55b7639dc0e3339f83283df08f7 --- /dev/null +++ b/arch/sh/include/watchdog.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/sh/include/watchdog.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SH_INCLUDE_WATCHDOG_H +#define __ARCH_SH_INCLUDE_WATCHDOG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_SH_INCLUDE_WATCHDOG_H */ diff --git a/arch/sh/src/.gitignore b/arch/sh/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..726d936e1e3390cc875a1fa5681e3c3988fe3c8b --- /dev/null +++ b/arch/sh/src/.gitignore @@ -0,0 +1,2 @@ +/.depend +/Make.dep diff --git a/arch/sh/src/Makefile b/arch/sh/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..967818df2a8d2d7f8a101dda82d3cc8d2edc2524 --- /dev/null +++ b/arch/sh/src/Makefile @@ -0,0 +1,179 @@ +############################################################################ +# arch/sh/src/Makefile +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +CPPFLAGS += $(EXTRADEFINES) +CFLAGS += $(EXTRADEFINES) +CXXFLAGS += $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = $(TOPDIR)\nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)\chip + CFLAGS += -I$(ARCH_SRCDIR)\common + CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)\sched +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = $(TOPDIR)/nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)/chip + CFLAGS += -I$(ARCH_SRCDIR)/common + CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)/sched +endif +endif + +CFLAGS += -I$(ARCH_SRCDIR)/chip -I$(ARCH_SRCDIR)/common -I$(TOPDIR)/sched + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = ${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name} + +VPATH = chip:common + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + @echo "LD: nuttx" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(TOPDIR)/$@ $(HEAD_OBJ) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(TOPDIR)/$@ | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/sh/src/README.txt b/arch/sh/src/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cbd17c0fd886419e52664bf67e8b9899cdfb560 --- /dev/null +++ b/arch/sh/src/README.txt @@ -0,0 +1,7 @@ +This directory provides a build area for all SH architectures. +The 'common' subdirectory contains source files shared by all SH +architectures; Source files unique to a specific SH chip +architecture are contained in a subdirectory named after the chip. +At configuration time, additional directories will be linked here: +'build' will be a link to the configs/*/src directory; 'chip' will +be a link to the SH chip sub-directory. diff --git a/arch/sh/src/common/Kconfig b/arch/sh/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f6c044427debf10bca58f8bfa665ec29b9b44b2d --- /dev/null +++ b/arch/sh/src/common/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_SH +endif diff --git a/arch/sh/src/common/up_allocateheap.c b/arch/sh/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..ddf287983a19badb829b1994dc7c4542daf91abc --- /dev/null +++ b/arch/sh/src/common/up_allocateheap.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/sh/src/common/up_allocateheap.c + * + * Copyright (C) 2008, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void*)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} diff --git a/arch/sh/src/common/up_arch.h b/arch/sh/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..b624da189d5e2128f09c1043fdea0d69aa0efbc1 --- /dev/null +++ b/arch/sh/src/common/up_arch.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/sh/src/common/up_arch.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_SH_SRC_COMMON_UP_ARCH_H +#define ___ARCH_SH_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(a) (*(volatile uint8_t *)(a)) +# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +# define getreg16(a) (*(volatile uint16_t *)(a)) +# define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +# define getreg32(a) (*(volatile uint32_t *)(a)) +# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +#endif + +#endif /* ___ARCH_SH_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/sh/src/common/up_assert.c b/arch/sh/src/common/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..c8303f2995810c5b31acb47b2456ea0859730db6 --- /dev/null +++ b/arch/sh/src/common/up_assert.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * arch/sh/src/common/up_assert.c + * + * Copyright (C) 2008-2009, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || this_task()->pid == 0) + { + (void)up_irq_save(); + for (;;) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG) + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/sh/src/common/up_blocktask.c b/arch/sh/src/common/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..75ecdef5077c7f98b4f0804d5f46385514ab105e --- /dev/null +++ b/arch/sh/src/common/up_blocktask.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/sh/src/common/up_blocktask.c + * + * Copyright (C) 2008-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_copystate(rtcb->xcp.regs, g_current_regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + g_current_regs = rtcb->xcp.regs; + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/sh/src/common/up_createstack.c b/arch/sh/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..f52f03386ed13f260d4e6d48f56187b218d0d3ee --- /dev/null +++ b/arch/sh/src/common/up_createstack.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/sh/src/common/up_createstack.c + * + * Copyright (C) 2008-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* The SH family uses a push-down stack: the stack grows + * toward loweraddresses in memory. The stack pointer + * register, points to the lowest, valid work address + * (the "top" of the stack). Items on the stack are + * referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The SH stack must be aligned at word (4 byte) + * boundaries. If necessary top_of_stack must be rounded + * down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/sh/src/common/up_doirq.c b/arch/sh/src/common/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..a2996c9f4820e0cb073938b88fa7bd7944b6e92d --- /dev/null +++ b/arch/sh/src/common/up_doirq.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/sh/src/common/up_doirq.c + * + * Copyright (C) 2008-2009, 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t* regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + if ((unsigned)irq < NR_IRQS) + { + /* Current regs non-zero indicates that we are processing + * an interrupt; g_current_regs is also used to manage + * interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t*)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + /* Get the current value of regs... it may have changed because + * of a context switch performed during interrupt processing. + */ + + regs = g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + } + + board_autoled_off(LED_INIRQ); +#endif + return regs; +} diff --git a/arch/sh/src/common/up_exit.c b/arch/sh/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..84845556e983c96467843fd43f58e19ba7035633 --- /dev/null +++ b/arch/sh/src/common/up_exit.c @@ -0,0 +1,181 @@ +/**************************************************************************** + * common/up_exit.c + * + * Copyright (C) 2008-2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s* tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} + diff --git a/arch/sh/src/common/up_idle.c b/arch/sh/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..0333722347b2df15108151ac1c172bed63c84784 --- /dev/null +++ b/arch/sh/src/common/up_idle.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/sh/src/common/up_idle.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their + * is no other ready-to-run task. This is processor idle + * time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be + * performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, + * then process "fake" timer interrupts. Hopefully, something + * will wake up. + */ + + sched_process_timer(); +#endif +} + diff --git a/arch/sh/src/common/up_initialize.c b/arch/sh/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..98c6bf273d842474e4d91df99a1267975fb5d252 --- /dev/null +++ b/arch/sh/src/common/up_initialize.c @@ -0,0 +1,219 @@ +/**************************************************************************** + * arch/sh/src/common/up_initialize.c + * + * Copyright (C) 2008-2010, 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Define to enable timing loop calibration */ + +#undef CONFIG_ARCH_CALIBRATION + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) & defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + slldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + slldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). NOTE that the naming implies that the console is a serial + * driver. That is usually the case, however, if no UARTs are enabled, the + * console could als be provided through some other device, such as an LCD. + * Architecture-specific logic will have to detect that case. + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB */ + + up_usbinitialize(); + + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/sh/src/common/up_internal.h b/arch/sh/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..724efbca93fc63c37a7cf71a1d63bec5a3b66791 --- /dev/null +++ b/arch/sh/src/common/up_internal.h @@ -0,0 +1,248 @@ +/**************************************************************************** + * arch/sh/src/common/up_internal.h + * + * Copyright (C) 2008-2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_SH_SRC_COMMON_UP_INTERNAL_H +#define ___ARCH_SH_SRC_COMMON_UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_SCI_CONFIG /* DEFINED: Do not reconfig SCI */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Determine which (if any) console driver to use. NOTE that the naming + * implies that the console is a serial driver. That is usually the case, + * however, if no UARTs are enabled, the console could als be provided + * through some other device, such as an LCD. Architecture-specific logic + * will have to detect that case. + * + * If a console is enabled and no other console device is specified, then + * a serial console is assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level + * register storage structure. If is non-NULL only during + * interrupt processing. + */ + +extern volatile uint32_t *g_current_regs; + +/* This is the beginning of heap as provided from up_head.S. + * This is the first address in DRAM after the loaded + * program+bss+idle stack. The end of the heap is + * CONFIG_RAM_END + */ + +extern uint32_t g_idle_topstack; +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Defined in files with the same name as the function */ + +void up_boot(void); +void up_copystate(uint32_t *dest, uint32_t *src); +void up_dataabort(uint32_t *regs); +void up_decodeirq(uint32_t *regs); +uint32_t *up_doirq(int irq, uint32_t *regs); +void up_fullcontextrestore(uint32_t *regs) noreturn_function; +void up_irqinitialize(void); +void up_prefetchabort(uint32_t *regs); +int up_saveusercontext(uint32_t *regs); +void up_sigdeliver(void); +void up_syscall(uint32_t *regs); +int up_timerisr(int irq, uint32_t *regs); +void up_undefinedinsn(uint32_t *regs); +void up_lowputc(char ch); +void up_puts(const char *str); +void up_lowputs(const char *str); + +/* Defined in up_vectors.S */ + +void up_vectorundefinsn(void); +void up_vectorswi(void); +void up_vectorprefetch(void); +void up_vectordata(void); +void up_vectoraddrexcptn(void); +void up_vectorirq(void); +void up_vectorfiq(void); + +/* Defined in up_serial.c */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +void up_earlyconsoleinit(void); +void up_consoleinit(void); +#else +# define up_earlyconsoleinit() +# define up_consoleinit() +#endif + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* Defined in up_watchdog.c */ + +void up_wdtinit(void); + +/* Defined in up_timerisr.c */ + +void up_timer_initialize(void); + +/* Defined in board/up_lcd.c */ + +#ifdef CONFIG_LCD_CONSOLE +void up_lcdinit(void); +void up_lcdputc(char ch); +#else +# define up_lcdinit() +# define up_lcdputc(ch) +#endif + +/* Defined in board/up_network.c */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +/* USB */ + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +/* Defined in chip-specific logic */ + +#ifdef CONFIG_ARCH_STACKDUMP +void up_dumpstate(void); +#else +# define up_dumpstate() +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* ___ARCH_SH_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/sh/src/common/up_interruptcontext.c b/arch/sh/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..56e4f9478ea0becd6ab0614880abb60250b2e186 --- /dev/null +++ b/arch/sh/src/common/up_interruptcontext.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/sh/src/common/up_interruptcontext.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/sh/src/common/up_lowputs.c b/arch/sh/src/common/up_lowputs.c new file mode 100644 index 0000000000000000000000000000000000000000..592ea8177f70068b833d1c1690b8cb1e1c409f7d --- /dev/null +++ b/arch/sh/src/common/up_lowputs.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/sh/src/common/up_lowputs.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} diff --git a/arch/sh/src/common/up_mdelay.c b/arch/sh/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..e7ed4f9015626678a767ef762afc8f12b1469a61 --- /dev/null +++ b/arch/sh/src/common/up_mdelay.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/sh/src/common/up_mdelay.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/sh/src/common/up_puts.c b/arch/sh/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..24dccecbe404c3b7e9b9ac3af4955c9fa211ef56 --- /dev/null +++ b/arch/sh/src/common/up_puts.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/sh/src/common/up_puts.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} diff --git a/arch/sh/src/common/up_releasepending.c b/arch/sh/src/common/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..b91503cbe6a3f046514a8195a246a2a90b364ab9 --- /dev/null +++ b/arch/sh/src/common/up_releasepending.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/sh/src/common/up_releasepending.c + * + * Copyright (C) 2008-2009, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_copystate(rtcb->xcp.regs, g_current_regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + g_current_regs = rtcb->xcp.regs; + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/sh/src/common/up_releasestack.c b/arch/sh/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..8e01456fdbf7cb766b315081e1bbc795461be7fe --- /dev/null +++ b/arch/sh/src/common/up_releasestack.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/sh/src/common/up_releasestack.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/sh/src/common/up_reprioritizertr.c b/arch/sh/src/common/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..e838cff0bba8de83d17c6b920e30c5192a78df79 --- /dev/null +++ b/arch/sh/src/common/up_reprioritizertr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/sh/src/common/up_reprioritizertr.c + * + * Copyright (C) 2008-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_copystate(rtcb->xcp.regs, g_current_regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + g_current_regs = rtcb->xcp.regs; + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/sh/src/common/up_stackframe.c b/arch/sh/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..06d2c218a3464555c6b529e700cc148149cfdd24 --- /dev/null +++ b/arch/sh/src/common/up_stackframe.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/sh/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ +/* The SH stack must be aligned at word (4 byte) boundaries. If necessary + * frame_size must be rounded up to the next boundary + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial state */ + + up_initial_state(tcb); + + /* And return a pointer to allocated memory */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/sh/src/common/up_udelay.c b/arch/sh/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..6af5d2f76d471d175a748b7a5bd30d502b53418b --- /dev/null +++ b/arch/sh/src/common/up_udelay.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/sh/src/common/up_udelay.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} diff --git a/arch/sh/src/common/up_unblocktask.c b/arch/sh/src/common/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..d506d97d094cd6fb1408e90eb703336861849862 --- /dev/null +++ b/arch/sh/src/common/up_unblocktask.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * arch/sh/src/common/up_unblocktask.c + * + * Copyright (C) 2008-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_copystate(rtcb->xcp.regs, g_current_regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + g_current_regs = rtcb->xcp.regs; + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/sh/src/common/up_usestack.c b/arch/sh/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..2da654391ca22b8ac430e5af41d33793058e130c --- /dev/null +++ b/arch/sh/src/common/up_usestack.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/sh/src/common/up_usestack.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The SH family uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on the + * stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The SH stack must be aligned at word (4 byte) boundaries. If necessary + * top_of_stack must be rounded down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_size = top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} diff --git a/arch/sh/src/m16c/Kconfig b/arch/sh/src/m16c/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..e1f81d0727b0d7b31f30344422cfe8deda843afd --- /dev/null +++ b/arch/sh/src/m16c/Kconfig @@ -0,0 +1,23 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_M16C + +config M16C_UART0 + bool "UART0" + select ARCH_HAVE_UART0 + default n + +config M16C_UART1 + bool "UART1" + select ARCH_HAVE_UART1 + default n + +config M16C_UART2 + bool "UART2" + select ARCH_HAVE_UART2 + default n + +endif diff --git a/arch/sh/src/m16c/Make.defs b/arch/sh/src/m16c/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..6995d37b1e456dd320d2ecfb95f42d3e7360b513 --- /dev/null +++ b/arch/sh/src/m16c/Make.defs @@ -0,0 +1,55 @@ +############################################################################## +# arch/sh/src/m16c/Make.defs +# +# Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +HEAD_ASRC = m16c_head.S + +CMN_ASRCS = +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_interruptcontext.c up_lowputs.c up_mdelay.c up_puts.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_stackframe.c up_udelay.c up_unblocktask.c up_usestack.c + +CHIP_ASRCS = m16c_vectors.S +CHIP_CSRCS = m16c_initialstate.c m16c_copystate.c m16c_lowputc.c m16c_irq.c +CHIP_CSRCS += m16c_serial.c m16c_dumpstate.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += m16c_timerisr.c +endif + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CHIP_CSRCS += m16c_schedulesigaction.c m16c_sigdeliver.c +endif diff --git a/arch/sh/src/m16c/chip.h b/arch/sh/src/m16c/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..695814d4324cb87b47cb7d83a6647752480f12ad --- /dev/null +++ b/arch/sh/src/m16c/chip.h @@ -0,0 +1,281 @@ +/************************************************************************************ + * arch/sh/src/m16c/chip.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_SH_SRC_M16C_CHIP_H +#define __ARCH_SH_SRC_M16C_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* FLG register bits */ + +#define M16C_FLG_C 0x0001 /* Bit 0: Carry flag */ +#define M16C_FLG_D 0x0002 /* Bit 1: Debug flag */ +#define M16C_FLG_Z 0x0004 /* Bit 2: Zero flag */ +#define M16C_FLG_S 0x0008 /* Bit 3: Sign flag */ +#define M16C_FLG_B 0x0010 /* Bit 4: Register bank flag */ +#define M16C_FLG_O 0x0020 /* Bit 5: Overflow flag */ +#define M16C_FLG_I 0x0040 /* Bit 6: Interrupt enable flag */ +#define M16C_FLG_U 0x0080 /* Bit 7: Stack pointer select flag */ + /* Bits 8-11: Reserved */ +#define M16C_FLG_IPLMASK 0x7000 /* Bits 12:14: Processor interrupt priority level */ + /* Bit 15: Reserved */ +/* Memory Map */ + +/* Memory-mapped special function registers begin at address 0x00000 */ + +#define M16C_SFR_BASE 0x00000 /* 00000-003ff: Special Function Registers */ + +/* Internal, on-chip SRAM begins at address 0x00400 for all chips, regardless of the + * size of the on-chip SRAM. + */ + +#define M16C_IRAM_BASE 0x00400 /* 00400-00xxx: Internal RAM */ +#if defined(CONFIG_ARCH_CHIP_M30262F3) || defined(CONFIG_ARCH_CHIP_M30262F4) +# define M16C_IRAM_END 0x007ff /* End+1 address of internal RAM */ + /* 00800-0efff: Reserved */ +#elif defined(CONFIG_ARCH_CHIP_M30262F6) || defined(CONFIG_ARCH_CHIP_M30262F8) +# define M16C_IRAM_END 0x00bff /* End+1 address of internal RAM */ + /* 00c00-0efff: Reserved */ +#endif + +/* Two banks of virtual EEPROM (all parts) */ + +#define M16C_VEEPROM1_BASE 0x0f000 /* 0f000-0f7fff: Virtual EEPPROM block 1 */ +#define M16C_VEEPROM2_BASE 0x0f800 /* 0f800-0fffff: Virtual EEPPROM block 2 */ + +/* If there were external, "far" RAM, it would be begin at 0x10000. However, these + * specific chips do not support external RAM. + */ + +/* Each part has a different amount on on-chip FLASH. The ending FLASH address is + * 0xfffff for all chips, but the starting address varies depening on the amount + * of on-chip FLASH. + */ + +#if defined(CONFIG_ARCH_CHIP_M30262F3) + /* 10000-f9ffff: Reserved */ +# define M16C_FLASH_BASE 0xfa000 /* fa000-ffffff: Flash ROM (M30262F8) */ +#elif defined(CONFIG_ARCH_CHIP_M30262F4) + /* 10000-f7ffff: Reserved */ +# define M16C_FLASH_BASE 0xf8000 /* f8000-ffffff: Flash ROM (M30262F8) */ +#elif defined(CONFIG_ARCH_CHIP_M30262F6) + /* 10000-f3ffff: Reserved */ +# define M16C_FLASH_BASE 0xf4000 /* f4000-ffffff: Flash ROM (M30262F8) */ +#elif defined(CONFIG_ARCH_CHIP_M30262F8) + /* 10000-efffff: Reserved */ +# define M16C_FLASH_BASE 0xf0000 /* f0000-ffffff: Flash ROM (M30262F8) */ +#endif + +/* Special Function Register Addresses */ + +#define M16C_PM0 0x00004 /* Processor mode 0 */ +#define M16C_PM1 0x00005 /* Processor mode 1 */ +#define M16C_CM0 0x00006 /* System clock control 0 */ +#define M16C_CM1 0x00007 /* System clock control 1 */ +#define M16C_AIER 0x00009 /* Addrese match interrupt enable */ +#define M16C_PRCR 0x0000a /* Protect */ +#define M16C_CM2 0x0000c /* Oscillation stop detection */ +#define M16C_WDTS 0x0000e /* Watchdog timer start */ +#define M16C_WDC 0x0000f /* Watchdog timer control */ +#define M16C_RMAD0 0x00010 /* Address match interrupt 0 */ +#define M16C_RMAD1 0x00014 /* Address match interrupt 1 */ +#define M16C_VCR1 0x00019 /* Power supply detection 1 */ +#define M16C_VCR2 0x0001a /* Power supply detection 2 */ +#define M16C_PM2 0x0001e /* Processor mode 2 */ +#define M16C_D4INT 0x0001f /* Power supply 4V detection */ +#define M16C_SAR0 0x00020 /* DMA0 source pointer */ +#define M16C_DAR0 0x00024 /* DMA0 destination pointer */ +#define M16C_TCR0 0x00028 /* DMA0 transfer counter */ +#define M16C_DM0CON 0x0002c /* DMA0 control */ +#define M16C_SAR1 0x00030 /* DMA1 source pointer */ +#define M16C_DAR1 0x00034 /* DMA1 destination pointer */ +#define M16C_TCR1 0x00038 /* DMA1 transfer counter */ +#define M16C_DM1CON 0x0003c /* DMA1 control */ +#define M16C_INT3IC 0x00044 /* INT3 interrupt control */ +#define M16C_INT5IC 0x00048 /* INT5 interrupt control */ +#define M16C_INT4IC 0x00049 /* INT4 interrupt control */ +#define M16C_BCNIC 0x0004a /* Bus collision detection interrupt control */ +#define M16C_DM0IC 0x0004b /* DMA0 interrupt control */ +#define M16C_DM1IC 0x0004c /* DMA1 interrupt control */ +#define M16C_KUPIC 0x0004d /* Key input interrupt control */ +#define M16C_ADIC 0x0004e /* A-D conversion interrupt control */ +#define M16C_S2TIC 0x0004f /* UART2 transmit interrupt control */ +#define M16C_S2RIC 0x00050 /* UART2 receive interrupt control */ +#define M16C_S0TIC 0x00051 /* UART0 transmit interrupt control */ +#define M16C_S0RIC 0x00052 /* UART0 receive interrupt control */ +#define M16C_S1TIC 0x00053 /* UART1 transmit interrupt control */ +#define M16C_S1RIC 0x00054 /* UART1 receive interrupt control */ +#define M16C_TA0IC 0x00055 /* Timer A0 interrupt control */ +#define M16C_TA1IC 0x00056 /* Timer A1 interrupt control */ +#define M16C_TA2IC 0x00057 /* Timer A2 interrupt control */ +#define M16C_TA3IC 0x00058 /* Timer A3 interrupt control */ +#define M16C_TA4IC 0x00059 /* Timer A4 interrupt control */ +#define M16C_TB0IC 0x0005a /* Timer B0 interrupt control */ +#define M16C_TB1IC 0x0005b /* Timer B1 interrupt control */ +#define M16C_TB2IC 0x0005c /* Timer B2 interrupt control */ +#define M16C_INT0IC 0x0005d /* INT0 interrupt control */ +#define M16C_INT1IC 0x0005e /* INT1 interrupt control */ +#define M16C_FMR4 0x001b3 /* Flash Control 4 */ +#define M16C_FMR1 0x001b5 /* Flash Control 1 */ +#define M16C_FMR0 0x001b7 /* Flash Control 0 */ +#define M16C_PCLKR 0x0025e /* Peripheral Clock Select */ +#define M16C_TA11 0x00342 /* Timer A1-1 */ +#define M16C_TA21 0x00344 /* Timer A2-1 */ +#define M16C_TA41 0x00346 /* Timer A4-1 */ +#define M16C_INVC0 0x00348 /* Three-phase PWM control 0 */ +#define M16C_INVC1 0x00349 /* Three-phase PWM control 1 */ +#define M16C_IDB0 0x0034a /* Three-phase output buffer 0 */ +#define M16C_IDB1 0x0034b /* Three-phase output buffer 1 */ +#define M16C_DTT 0x0034c /* Dead time timer */ +#define M16C_ICTB2 0x0034d /* Timer B2 interrupt occurences frequency set counter */ +#define M16C_IFSR 0x0035f /* Interrupt request cause select */ +#define M16C_U2SMR4 0x00374 /* UART2 special mode register4 */ +#define M16C_U2SMR3 0x00375 /* UART2 special mode register3 */ +#define M16C_U2SMR2 0x00376 /* UART2 special mode register2 */ +#define M16C_U2SMR 0x00377 /* UART2 special mode */ +#define M16C_U2MR 0x00378 /* UART2 transmit/receive mode */ +#define M16C_U2BRG 0x00379 /* UART2 bit rate generator */ +#define M16C_U2TB 0x0037a /* UART2 transmit buffer */ +#define M16C_U2C0 0x0037c /* UART2 transmit/receive control 0 */ +#define M16C_U2C1 0x0037d /* UART2 transmit/receive control 1 */ +#define M16C_U2RB 0x0037e /* UART2 receive buffer */ +#define M16C_TABSR 0x00380 /* Count start flag */ +#define M16C_CPSRF 0x00381 /* Clock prescaler reset flag */ +#define M16C_ONSF 0x00382 /* One-shot start flag */ +#define M16C_TRGSR 0x00383 /* Trigger select */ +#define M16C_UDF 0x00384 /* Up-down flag */ +#define M16C_TA0 0x00386 /* Timer A0 */ +#define M16C_TA1 0x00388 /* Timer A1 */ +#define M16C_TA2 0x0038a /* Timer A2 */ +#define M16C_TA3 0x0038c /* Timer A3 */ +#define M16C_TA4 0x0038e /* Timer A4 */ +#define M16C_TB0 0x00390 /* Timer B0 */ +#define M16C_TB1 0x00392 /* Timer B1 */ +#define M16C_TB2 0x00394 /* Timer B2 */ +#define M16C_TA0MR 0x00396 /* Timer A0 mode */ +#define M16C_TA1MR 0x00397 /* Timer A1 mode */ +#define M16C_TA2MR 0x00398 /* Timer A2 mode */ +#define M16C_TA3MR 0x00399 /* Timer A3 mode */ +#define M16C_TA4MR 0x0039a /* Timer A4 mode */ +#define M16C_TB0MR 0x0039b /* Timer B0 mode */ +#define M16C_TB1MR 0x0039c /* Timer B1 mode */ +#define M16C_TB2MR 0x0039d /* Timer B2 mode */ +#define M16C_TB2SC 0x0039e /* Timer B2 special mode */ +#define M16C_U0MR 0x003a0 /* UART0 transmit/receive mode */ +#define M16C_U0BRG 0x003a1 /* UART0 bit rate generator */ +#define M16C_U0TB 0x003a2 /* UART0 transmit buffer */ +#define M16C_U0C0 0x003a4 /* UART0 transmit/receive control 0 */ +#define M16C_U0C1 0x003a5 /* UART0 transmit/receive control 1 */ +#define M16C_U0RB 0x003a6 /* UART0 receive buffer */ +#define M16C_U1MR 0x003a8 /* UART1 transmit/receive mode */ +#define M16C_U1BRG 0x003a9 /* UART1 bit rate generator */ +#define M16C_U1TB 0x003aa /* UART1 transmit buffer */ +#define M16C_U1C0 0x003ac /* UART1 transmit/receive control 0 */ +#define M16C_U1C1 0x003ad /* UART1 transmit/receive control 1 */ +#define M16C_U1RB 0x003ae /* UART1 receive buffer */ +#define M16C_UCON 0x003b0 /* UART2 transmit/receive control 2 */ +#define M16C_DM0SL 0x003b8 /* DMA0 cause select */ +#define M16C_DM1SL 0x003ba /* DMA1 cause select */ +#define M16C_AD0 0x003c0 /* A-D 0 */ +#define M16C_AD1 0x003c2 /* A-D 1 */ +#define M16C_AD2 0x003c4 /* A-D 2 */ +#define M16C_AD3 0x003c6 /* A-D 3 */ +#define M16C_AD4 0x003c8 /* A-D 4 */ +#define M16C_AD5 0x003ca /* A-D 5 */ +#define M16C_AD6 0x003cc /* A-D 6 */ +#define M16C_AD7 0x003ce /* A-D 7 */ +#define M16C_ADCON2 0x003d4 /* A-D control 2 */ +#define M16C_ADCON0 0x003d6 /* A-D control 0 */ +#define M16C_ADCON1 0x003d7 /* A-D control 1 */ +#define M16C_P1 0x003e1 /* Port P1 */ +#define M16C_PD1 0x003e3 /* Port P1 direction */ +#define M16C_P6 0x003ec /* Port P6 */ +#define M16C_P7 0x003ed /* Port P7 */ +#define M16C_PD6 0x003ee /* Port P6 direction */ +#define M16C_PD7 0x003ef /* Port P7 direction */ +#define M16C_P8 0x003f0 /* Port P8 */ +#define M16C_P9 0x003f1 /* Port P9 */ +#define M16C_PD8 0x003f2 /* Port P8 direction */ +#define M16C_PD9 0x003f3 /* Port P9 direction */ +#define M16C_P10 0x003f4 /* Port P10 */ +#define M16C_PD10 0x003f6 /* Port P10 direction */ +#define M16C_PUR0 0x003fc /* Pull-up control 0 */ +#define M16C_PUR1 0x003fd /* Pull-up control 1 */ +#define M16C_PUR2 0x003fe /* Pull-up control 2 */ +#define M16C_PCR 0x003ff /* Port control */ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +extern uint16_t g_snbss; /* Start of near .bss */ +extern uint16_t g_enbss; /* End+1 of near .bss */ +extern uint16_t g_sndata; /* Start of near .data */ +extern uint16_t g_endata; /* End+1 of near .data */ +extern uint32_t g_enronly; /* Start of relocated read-only data in FLASH */ +#ifdef CONFIG_M16C_HAVEFARRAM + extern uint32_t g_sfbss; /* Start of far .bss */ + extern uint32_t g_efbss; /* End+1 of far .bss */ + extern uint32_t g_sfdata; /* Start of far .data */ + extern uint32_t g_efdata; /* End_1 of far .data */ + extern uint32_t g_efronly; /* Start of relocated read-only data in FLASH */ +#endif +extern uint32_t g_svarvect; /* Start of variable vectors */ +extern uint32_t g_idle_topstack; /* Start of the heap */ + +/* Address of the saved user stack pointer */ + +#ifndef __ASSEMBLY__ +# if CONFIG_ARCH_INTERRUPTSTACK > 3 + extern uint16_t g_intstackbase; +# endif +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_SH_SRC_M16C_CHIP_H */ diff --git a/arch/sh/src/m16c/m16c_copystate.c b/arch/sh/src/m16c/m16c_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..2aa48d6c72a6b15d478e3d68410050f8ca5b949a --- /dev/null +++ b/arch/sh/src/m16c/m16c_copystate.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/sh/src/m16c/up_copystate.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint32_t *dest, uint32_t *src) +{ + memcpy(dest, src, XCPTCONTEXT_SIZE); +} + diff --git a/arch/sh/src/m16c/m16c_dumpstate.c b/arch/sh/src/m16c/m16c_dumpstate.c new file mode 100644 index 0000000000000000000000000000000000000000..e80fbcb9f57d62b5d11c63cd7add92cec5c1f0f3 --- /dev/null +++ b/arch/sh/src/m16c/m16c_dumpstate.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_assert.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: m16c_getsp + ****************************************************************************/ + +static inline uint16_t m16c_getsp(void) +{ + uint16_t sp; + + __asm__ __volatile__ + ( + "\tstc sp, %0\n\t" + : "=r" (sp) + : + : "memory" + ); + return sp; +} + +/**************************************************************************** + * Name: m16c_getusersp + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +static inline uint16_t m16c_getusersp(void) +{ + uint8_t *ptr = (uint8_t*) g_current_regs; + return (uint16_t)ptr[REG_SP] << 8 | ptr[REG_SP+1]; +} +#endif + +/**************************************************************************** + * Name: m16c_stackdump + ****************************************************************************/ + +static void m16c_stackdump(uint16_t sp, uint16_t stack_base) +{ + uint16_t stack; + + for (stack = sp & ~7; stack < stack_base; stack += 8) + { + uint8_t *ptr = (uint8_t*)stack; + lldbg("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: m16c_registerdump + ****************************************************************************/ + +static inline void m16c_registerdump(void) +{ + uint8_t *ptr = (uint8_t*) g_current_regs; + + /* Are user registers available from interrupt processing? */ + + if (ptr) + { + /* Yes.. dump the interrupt registers */ + + lldbg("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x SP: %02x%02x\n", + ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC+1], + ptr[REG_FLGPCHI] >> 8, ptr[REG_FLG], + ptr[REG_FB], ptr[REG_FB+1], + ptr[REG_SB], ptr[REG_SB+1], + ptr[REG_SP], ptr[REG_SP+1]); + + lldbg("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x A1: %02x%02x\n", + ptr[REG_R0], ptr[REG_R0+1], ptr[REG_R1], ptr[REG_R1+1], + ptr[REG_R2], ptr[REG_R2+1], ptr[REG_R3], ptr[REG_R3+1], + ptr[REG_A0], ptr[REG_A0+1], ptr[REG_A1], ptr[REG_A1+1]); + + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint16_t sp = m16c_getsp(); + uint16_t ustackbase; + uint16_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint16_t istackbase; + uint16_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 1; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustacksize = (uint16_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory. The near RAM memory map is as follows: + * + * 0x00400 - DATA Size: Determined by linker + * BSS Size: Determined by linker + * Interrupt stack Size: CONFIG_ARCH_INTERRUPTSTACK + * Idle stack Size: CONFIG_IDLETHREAD_STACKSIZE + * Heap Size: Everything remaining + * 0x00bff - (end+1) + */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = g_enbss; + istacksize = CONFIG_ARCH_INTERRUPTSTACK; + + /* Show interrupt stack info */ + + lldbg("sp: %04x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %04x\n", istackbase); + lldbg(" size: %04x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + m16c_stackdump(sp, istackbase); + + /* Extract the user stack pointer from the register area */ + + sp = m16c_getusersp(); + lldbg("sp: %04x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %04x\n", ustackbase); + lldbg(" size: %04x\n", ustacksize); +#else + lldbg("sp: %04x\n", sp); + lldbg("stack base: %04x\n", ustackbase); + lldbg("stack size: %04x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + m16c_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + m16c_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/sh/src/m16c/m16c_head.S b/arch/sh/src/m16c/m16c_head.S new file mode 100644 index 0000000000000000000000000000000000000000..f18da3fe3fe02581a8bd07ca3b8fe5b7635b99fd --- /dev/null +++ b/arch/sh/src/m16c/m16c_head.S @@ -0,0 +1,278 @@ +/************************************************************************************ + * arch/sh/src/m16c/m16c_head.S + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/***************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + *****************************************************************************/ + + .macro showprogress, code +#ifdef CONFIG_DEBUG + .globl _up_lowputc + mov.b r#\code1l /* Character to print */ + jsr.a _up_lowputc /* Print it */ +#endif + .endm + +/************************************************************************************ + * Data + ************************************************************************************/ + +/* The near RAM memory map is as follows: + * + * 0x00400 - DATA Size: Determined by linker + * BSS Size: Determined by linker + * Interrupt stack Size: CONFIG_ARCH_INTERRUPTSTACK + * Idle stack Size: CONFIG_IDLETHREAD_STACKSIZE + * Heap Size: Everything remaining + * 0x00bff - (end+1) + */ + + .section .rodata + .globl _g_snbss + .type _g_snbss, object +_g_snbss: + .word _g_snbss + .size _g_snbss, .-_g_snbss + + .globl _g_enbss + .type _g_enbss, object +_g_enbss: + .word _g_enbss + .size _g_enbss, .-_g_enbss + + .globl _g_sndata + .type _g_sndata, object +_g_sndata: + .word _g_sndata + .size _g_sndata, .-_g_sndata + + .globl _g_endata + .type _g_endata, object +_g_endata: + .word _g_endata + .size _g_endata, .-_g_endata + + .globl _g_enronly + .type _g_enronly, object +_g_enronly: + .long _g_enronly + .size _g_enronly, .-_g_efronly + +#ifdef CONFIG_M16C_HAVEFARRAM + .globl _g_sfbss + .type _g_sfbss, object +_g_sfbss: + .long _g_sfbss + .size _g_sfbss, .-_g_sfbss + + .globl _g_efbss + .type _g_efbss, object +_g_efbss: + .long _g_efbss + .size _g_efbss, .-_g_efbss + + .globl _g_sfdata + .type _g_sfdata, object +_g_sfdata: + .long _g_sfdata + .size _g_sfdata, .-_g_sfdata + + .globl _g_efdata + .type _g_efdata, object +_g_efdata: + .long _g_efdata + .size _g_efdata, .-_g_efdata + + .globl _g_efronly + .type _g_efronly, object +_g_efronly: + .long _g_efronly + .size _g_efronly, .-_g_efronly +#endif + .globl _g_svarvect + .type _g_svarvect, object +_g_svarvect: + .long _svarvect + .size _g_svarvect, .-_g_svarvect + + .globl _g_idle_topstack + .type _g_idle_topstack, object +_g_idle_topstack: + .long _enbss+CONFIG_ARCH_INTERRUPTSTACK+CONFIG_IDLETHREAD_STACKSIZE + .size _g_idle_topstack, .-_g_idle_topstack + +/************************************************************************************ + * Code + ************************************************************************************/ + +/************************************************************************************ + * Name: __start + * + * Description: + * After reset, program execution starts here. + * + ************************************************************************************/ + + .text + .globl __start + .globl _enbss + .type __start, #function +__start: + +/* Set the interrupt and user stack pointers */ + + mov.w #_enbss, R0 + ldc R0, isp /* Set the interrupt stack pointer to the end of BSS */ + add.w #CONFIG_IDLETHREAD_STACKSIZE, R0 + fset U /* Set bit 7 (U) to select the user stack pointer */ + ldc R0, sp /* Set the user stack pointer */ + +/* Set BCLK speed. At reset, the processor clock (BLCK) defaults to a divisor of 8. + * This sets clock to F1 (divide by 1) on XIN: BCLK = XIN frequency. + */ + + mov.b #0x01, M16C_PRCR /* Unprotect CM0 to change clock setting */ + mov.b #0x08, M16C_CM0 /* enable CM17 and CM16 to set BCLK to F1 + * CM17 & CM16 defaults to 0 after reset and + * so we only need to reset CM06 to 0 */ + mov.b #0x00,M16C_PRCR /* protect CM0 */ + +/* The two MS bits of the interrupt cause select register must be set to + * enable the use of INT4 and INT5 + */ + + mov.b #0xc0, M16C_IFSR /* Set b7 & b6 if application will use INT4 & INT5 */ + ldc #M16C_IRAM_BASE, sb /* Set sb register (to what?) */ + +/* Set up INTB to point to location of variable vector table */ + + mov.w _g_svarvect, r0 /* R0 = lower 16-bits */ + mov.w _g_svarvect+2, r1 /* R1 = upper 4-bits */ + ldc r1, intbh + ldc r0, intbl + +/* Configure the uart so that we can get debug output as soon as possible. */ + + .globl _up_lowsetup /* Early initialization of UART */ + jsr.a _up_lowsetup + showprogress 'A' + +/* Clear near .bss sections */ + + mov.b #0x00, r0l /* r0l: 0 */ + mov.w _g_snbss, a1 /* a1: start of near .bss */ + mov.w _g_enbss, r3 /* r3: end of near .bss */ + sub.w a1, r3 /* r3: size of near .bss */ + sstr.b /* Clear near .bss */ + +/* Clear far .bss sections */ + + showprogress 'B' + +#ifdef CONFIG_M16C_HAVEFARRAM +# warning "Far RAM support not implemented" +#endif + +/* Initialize near .data sections (.rodata is not moved) */ + + mov.w _g_enronly, a0 /* a0: Low 16 bits of source address */ + mov.b _g_enronly+2, r1h /* 4 MS of 20-bit source address */ + mov.w _g_sndata, a1 /* a1: start of near .data */ + mov.w _g_endata, r3 /* r3: end of near .data */ + sub.w a1, r3 /* r3: size of near .data */ + smovf.b /* Copy source to near .data */ + +/* Initialize far .data sections (.rodata is not moved) */ + + showprogress 'C' + +#ifdef CONFIG_M16C_HAVEFARRAM +# warning "Far RAM support not implemented" +#endif + +/* Perform early console initialization */ + +#ifdef USE_EARLYSERIALINIT + .globl _up_earlyconsoleinit /* Early initialization of console driver */ + jsr.a _up_earlyconsoleinit /* Call it */ + showprogress 'D' +#endif + +/* Call C++ constructors */ + +#ifdef CONFIG_CPLUSPLUS +# warning "No C++ support yet" + showprogress 'E' +#endif + +/* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + .globl _board_autoled_initialize /* Boot LED setup */ + jsr.a _board_autoled_initialize /* Call it */ +#endif + showprogress '\n' + +/* Pass control to NuttX */ + + .globl _os_start + jsr.a _os_start + +/* NuttX will not return, but just in case... */ + +_os_exit: + jmp.s _os_exit + .size __start, .-__start + .end diff --git a/arch/sh/src/m16c/m16c_initialstate.c b/arch/sh/src/m16c/m16c_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..cc913fde649e8eceac8f519a87b49d90a490b94e --- /dev/null +++ b/arch/sh/src/m16c/m16c_initialstate.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_initialstate.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of the + * new TCB. + * + * This function must setup the intial architecture registers and/or stack + * so that execution will begin at tcb->start on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(FAR struct tcb_s *tcb) +{ + FAR struct xcptcontext *xcp = &tcb->xcp; + FAR uint8_t *regs = xcp->regs; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Offset 0: FLG (bits 12-14) PC (bits 16-19) as would be present by an interrupt */ + + *regs++ = ((M16C_DEFAULT_IPL << 4) | ((uint32_t)tcb->start >> 16)); + + /* Offset 1: FLG (bits 0-7) */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + *regs++ = M16C_FLG_U; +#else + *regs++ = M16C_FLG_U | M16C_FLG_I; +#endif + + /* Offset 2-3: 16-bit PC [0]:bits8-15 [1]:bits 0-7 */ + + *regs++ = (uint32_t)tcb->start >> 8; /* Bits 8-15 of PC */ + *regs++ = (uint32_t)tcb->start; /* Bits 0-7 of PC */ + + /* Offset 18-20: User stack pointer */ + + regs = &xcp->regs[REG_SP]; + *regs++ = (uint32_t)tcb->adj_stack_ptr >> 8; /* Bits 8-15 of SP */ + *regs = (uint32_t)tcb->adj_stack_ptr; /* Bits 0-7 of SP */ +} diff --git a/arch/sh/src/m16c/m16c_irq.c b/arch/sh/src/m16c/m16c_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..2951033206e487d8a85fe3463ad160763be0d253 --- /dev/null +++ b/arch/sh/src/m16c/m16c_irq.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_irq.c + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +volatile uint32_t *g_current_regs; /* Actually a pointer to the beginning of a uint8_t array */ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + g_current_regs = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + asm("fset i"); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * On many architectures, there are three levels of interrupt enabling: (1) + * at the global level, (2) at the level of the interrupt controller, + * and (3) at the device level. In order to receive interrupts, they + * must be enabled at all three levels. + * + * This function implements disabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_NOINTC +void up_disable_irq(int irq) +{ + /* There are no ez80 interrupt controller settings to disable IRQs */ +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * This function implements enabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* There are no ez80 interrupt controller settings to enable IRQs */ +} + +#endif /* CONFIG_ARCH_NOINTC */ diff --git a/arch/sh/src/m16c/m16c_lowputc.c b/arch/sh/src/m16c/m16c_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..5ec641fbec605d7b09c2139a4e62a521d9101887 --- /dev/null +++ b/arch/sh/src/m16c/m16c_lowputc.c @@ -0,0 +1,341 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_lowputc.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "up_internal.h" +#include "m16c_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +#ifndef M16C_XIN_PRESCALER +# define M16C_XIN_PRESCALER 1 +#endif + +/* Is there any serial support? This might be the case if the board does + * not have serial ports but supports stdout through, say, an LCD. + */ + +#if defined(CONFIG_M16C_UART0) || defined(CONFIG_M16C_UART1) || defined(CONFIG_M16C_UART2) +# define HAVE_SERIAL +#else +# undef HAVE_SERIAL +#endif + +/* Is one of the serial ports a console? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART0) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART1) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART2) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +#else +# if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE)|| defined(CONFIG_UART2_SERIAL_CONSOLE) +# error "A serial console selected, but corresponding UART not enabled" +# endif +# undef HAVE_SERIALCONSOLE +#endif + +#if defined(HAVE_SERIALCONSOLE) && defined(CONFIG_LCD_CONSOLE) +# error "Both serial and LCD consoles are defined" +#elif !defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_LCD_CONSOLE) +# warning "No console is defined" +#endif + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIALCONSOLE +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define M16C_UART_BASE M16C_UART0_BASE +# define M16C_UART_BAUD CONFIG_UART0_BAUD +# define M16C_UART_BITS CONFIG_UART0_BITS +# define M16C_UART_PARITY CONFIG_UART0_PARITY +# define M16C_UART_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define M16C_UART_BASE M16C_UART1_BASE +# define M16C_UART_BAUD CONFIG_UART1_BAUD +# define M16C_UART_BITS CONFIG_UART1_BITS +# define M16C_UART_PARITY CONFIG_UART1_PARITY +# define M16C_UART_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define M16C_UART_BASE M16C_UART2_BASE +# define M16C_UART_BAUD CONFIG_UART2_BAUD +# define M16C_UART_BITS CONFIG_UART2_BITS +# define M16C_UART_PARITY CONFIG_UART2_PARITY +# define M16C_UART_2STOP CONFIG_UART2_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get mode setting */ + +#if M16C_UART_BITS == 7 +# define M16C_MR_SMDBITS UART_MR_SMD7BITS +#elif M16C_UART_BITS == 8 +# define M16C_MR_SMDBITS UART_MR_SMD8BITS +#elif M16C_UART_BITS == 8 +# define M16C_MR_SMDBITS UART_MR_SMD9BITS +#else +# error "Number of bits not supported" +#endif + +#if M16C_UART_PARITY == 0 +# define M16C_MR_PARITY (0) +#elif M16C_UART_PARITY == 1 +# define M16C_MR_PARITY UART_MR_PRYE +#elif M16C_UART_PARITY == 2 +# define M16C_MR_PARITY (UART_MR_PRYE|UART_MR_PRY) +#else +# error "Invalid parity selection" +#endif + +#if M16C_UART_2STOP != 0 +# define M16C_MR_STOPBITS UART_MR_STPS +#else +# define M16C_MR_STOPBITS (0) +#endif + +/* The full MR setting: */ + +#define M16C_MR_VALUE (M16C_MR_SMDBITS|M16C_MR_PARITY|M16C_MR_STOPBITS) + +/* Clocking ***************************************************************/ + +/* The Bit Rate Generator (BRG) value can be calculated by: + * + * BRG = source-frequency / prescaler / 16 / baud rate - 1 + * + * Example: + * source-frequency = 20,000,000 (20MHz) + * prescaler = 1 + * baud rate = 19200 + * BRG = 20,000,000/1/16/19200 - 1 = 64 + */ + +#define M16C_UART_BRG_VALUE \ + ((M16C_XIN_FREQ / (16 * M16C_XIN_PRESCALER * M16C_UART_BAUD)) - 1) + +#endif /* HAVE_SERIALCONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return TRUE of the Transmit Data Register is empty + * + ****************************************************************************/ + +#ifdef HAVE_SERIALCONSOLE +static inline int up_txready(void) +{ + /* Check the TI bit in the CI register. 1=Transmit buffer empty */ + + return ((getreg8(M16C_UART_BASE + M16C_UART_C1) & UART_C1_TI) != 0); +} +#endif /* HAVE_SERIALCONSOLE */ + +/**************************************************************************** + * Name: up_lowserialsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +#if defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) +static inline void up_lowserialsetup(void) +{ + uint8_t regval; + + /* Set the baud rate generator */ + + putreg8(M16C_UART_BRG_VALUE, M16C_UART_BASE + M16C_UART_BRG); + + /* Disable CTS/RTS */ + + putreg8(UART_C0_CRD, M16C_UART_BASE + M16C_UART_C0); + + /* Disable RX/TX interrupts */ + +#if 0 + putreg8(0, M16C_UCON); +#endif + +/* Set interrupt cause=TX complete and continuous receive mode */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + regval = getreg8(M16C_UCON); + regval |= (UART_CON_U0IRS|UART_CON_U0RRM); + putreg8(regval, M16C_UCON); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + regval = getreg8(M16C_UCON); + regval |= (UART_CON_U1IRS|UART_CON_U1RRM); + putreg8(regval, M16C_UCON); +#else + regval = getreg8(M16C_U2C1); + regval |= (UART_C1_U2IRS|UART_C1_U2RRM); + putreg8(regval, M16C_U2C1); +#endif + + /* Set UART transmit/receive control register 1 to enable transmit and receive */ + + putreg8(UART_C1_TE|UART_C1_RE, M16C_UART_BASE + M16C_UART_C1); + + /* Set UART transmit/receive mode register data bits, stop bits, parity */ + + putreg8(M16C_MR_VALUE, M16C_UART_BASE + M16C_UART_MR); + + /* Set port direction registers for Rx/TX pins */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) + regval = getreg8(M16C_PD6); + regval &= ~(1 << 2); /* PD6-2:RxD1 */ + regval |= (1 << 3); /* PD6-3:TxD1 */ + putreg8(regval, M16C_PD6); +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) + regval = getreg8(M16C_PD6); + regval &= ~(1 << 6); /* PD6-6:RxD1 */ + regval |= (1 << 7); /* PD6-7:TxD1 */ + putreg8(regval, M16C_PD6); +#else + regval = getreg8(M16C_PD7); + regval &= ~(1 << 1); /* PD7-1:RxD1 */ + regval &= (1 << 0); /* PD7-0:TxD1 */ + putreg8(regval, M16C_PD7); +#endif + + /* Read any data left in the RX fifo */ + + regval = (uint8_t)getreg16(M16C_UART_BASE + M16C_UART_RB); +} +#endif /* HAVE_SERIALCONFIG && !CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console. + * + ****************************************************************************/ + +#if defined(HAVE_SERIAL) && !defined(CONFIG_LCD_CONSOLE) +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIALCONSOLE + /* Wait until the transmit buffer is empty */ + + while (!up_txready()); + + /* Write the data to the transmit buffer */ + + putreg16((uint16_t)ch, M16C_UART_BASE + M16C_UART_TB); +#endif +} +#endif + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowsetup(void) +{ + /* Here we initialize the serial console early so that it can be used + * for bring-up debugging. + */ + +#if defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + up_lowserialsetup() +#endif + + /* The LCD is initialized here if the LCD is used for console output. */ + +#ifdef CONFIG_LCD_CONSOLE + up_lcdinit(); +#endif +} diff --git a/arch/sh/src/m16c/m16c_schedulesigaction.c b/arch/sh/src/m16c/m16c_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..682d3299875c8ebad2da16137073dad542efabf9 --- /dev/null +++ b/arch/sh/src/m16c/m16c_schedulesigaction.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_schedulesigaction.c + * + * Copyright (C) 2009-2010, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Funictions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + */ + + else + { + /* Save the return PC and SR and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc[0] = g_current_regs[REG_PC]; + tcb->xcp.saved_pc[1] = g_current_regs[REG_PC+1]; + tcb->xcp.saved_flg = g_current_regs[REG_FLG]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_PC] = (uint32_t)up_sigdeliver >> 8; + g_current_regs[REG_PC+1] = (uint32_t)up_sigdeliver; + g_current_regs[REG_FLG] &= ~M16C_FLG_I; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_copystate(tcb->xcp.regs, g_current_regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return PC and SR and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc[0] = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_pc[1] = tcb->xcp.regs[REG_PC+1]; + tcb->xcp.saved_flg = tcb->xcp.regs[REG_FLG]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver >> 8; + tcb->xcp.regs[REG_PC+1] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_FLG] &= ~M16C_FLG_I; + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/sh/src/m16c/m16c_serial.c b/arch/sh/src/m16c/m16c_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..6aeb973f751aeece55a41fde212ac165befdfc72 --- /dev/null +++ b/arch/sh/src/m16c/m16c_serial.c @@ -0,0 +1,1208 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_serial.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "m16c_uart.h" + +/* Is there any serial support? This might be the case if the board does + * not have serial ports but supports a console through, say, an LCD. + */ + +#if defined(CONFIG_M16C_UART0) || defined(CONFIG_M16C_UART1) || defined(CONFIG_M16C_UART2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +#ifndef M16C_XIN_PRESCALER +# define M16C_XIN_PRESCALER 1 +#endif + +/* Make sure interrupt priorities are defined. If not, use a default of 5 */ + +#ifndef M16C_S2T_PRIO +# define M16C_S2T_PRIO 5 /* UART2 transmit interrupt priority */ +#endif +#ifndef M16C_S2R_PRIO +# define M16C_S2R_PRIO 5 /* UART2 receive interrupt priority */ +#endif +#ifndef M16C_S0T_PRIO +# define M16C_S0T_PRIO 5 /* UART0 transmit interrupt priority */ +#endif +#ifndef M16C_S0R_PRIO +# define M16C_S0R_PRIO 5 /* UART0 receive interrupt priority */ +#endif +#ifndef M16C_S1T_PRIO +# define M16C_S1T_PRIO 5 /* UART1 transmit interrupt priority */ +#endif +#ifndef M16C_S1R_PRIO +# define M16C_S1R_PRIO 5 /* UART1 receive interrupt priority */ +#endif + +/* Some sanity checks *******************************************************/ + +/* Are there any UARTs? */ + +#if !defined(CONFIG_M16C_UART0) && !defined(CONFIG_M16C_UART1) && !defined(CONFIG_M16C_UART2) +# ifdef USE_SERIALDRIVER +# error "Serial driver selected, but No UARTs is enabled" +# undef USE_SERIALDRIVER +# endif +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART0) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART1) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_M16C_UART2) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +#else +# if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE)|| defined(CONFIG_UART2_SERIAL_CONSOLE) +# error "Serial console selected, but corresponding UART not enabled" +# endif +# undef HAVE_SERIALCONSOLE +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +#endif + +#if defined(HAVE_SERIALCONSOLE) && defined(CONFIG_LCD_CONSOLE) +# error "Both serial and LCD consoles are defined" +#elif !defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_LCD_CONSOLE) +# warning "No console is defined" +#endif + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1 and tty2? */ + +/* CONFIG_UART0_SERIAL_CONSOLE (implies CONFIG_M16C_UART0 also defined) */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is tty0 */ +# ifdef CONFIG_M16C_UART1 +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# ifdef CONFIG_M16C_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# endif +# else +# ifdef CONFIG_M16C_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif +# undef TTYS2_DEV /* No tty2 */ +# endif + +/* CONFIG_UART1_SERIAL_CONSOLE (implies CONFIG_M16C_UART1 also defined) */ + +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is tty0 */ +# ifdef CONFIG_M16C_UART0 +# define TTYS1_DEV g_uart0port /* UART0 is tty1 */ +# ifdef CONFIG_M16C_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# endif +# else +# ifdef CONFIG_M16C_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif +# undef TTYS2_DEV /* No tty2 */ +# endif + +/* CONFIG_UART2_SERIAL_CONSOLE (implies CONFIG_M16C_UART2 also defined) */ + +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is tty0 */ +# ifdef CONFIG_M16C_UART0 +# define TTYS1_DEV g_uart0port /* UART0 is tty1 */ +# ifdef CONFIG_M16C_UART1 +# define TTYS2_DEV g_uart1port /* UART1 is tty2 */ +# endif +# else +# ifdef CONFIG_M16C_UART1 +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif +# undef TTYS2_DEV /* No tty2 */ +# endif + +/* No console, at least one of CONFIG_M16C_UART0/1/2 defined */ + +#elif defined(CONFIG_M16C_UART0) +# undef CONSOLE_DEV /* No console */ +# define TTYS0_DEV g_uart0port /* UART0 is tty0 */ +# ifdef CONFIG_M16C_UART1 +# define TTYS1_DEV g_uart1port /* UART1 is tty1 */ +# ifdef CONFIG_M16C_UART2 +# define TTYS2_DEV g_uart2port /* UART2 is tty2 */ +# endif +# else +# ifdef CONFIG_M16C_UART2 +# define TTYS1_DEV g_uart1port /* UART2 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif +# undef TTYS2_DEV /* No tty2 */ +# endif + +elif defined(CONFIG_M16C_UART1) +# undef CONSOLE_DEV /* No console */ +# undef TTYS2_DEV /* No tty2 */ +# define TTYS0_DEV g_uart1port /* UART1 is tty0 */ +# ifdef CONFIG_M16C_UART2 +# define TTYS1_DEV g_uart2port /* UART2 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif + +/* Otherwise, there is no console and only CONFIG_M16C_UART2 is defined */ + +#else +# undef CONSOLE_DEV /* No console */ +# define TTYS0_DEV g_uart2port /* UART2 is tty0 */ +# undef TTYS1_DEV /* No tty1 */ +# undef TTYS1_DEV /* No tty2 */ +#endif + +/* Pre-processor Definitions for the enable field of the device structure */ + +#define M16C_RXENABLED 0x01 +#define M16C_TXENABLED 0x02 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t baud; /* Configured baud */ + uint16_t uartbase; /* Base address of UART registers */ + uint8_t uartno; /* UART number */ + volatile uint8_t ucon; /* Saved SCR value */ + volatile uint8_t ssr; /* Saved SR value (only used during interrupt processing) */ + uint8_t rcvirq; /* UART receive data available IRQ */ + uint8_t xmtirq; /* UART transmit complete IRQ */ + uint8_t enables; /* Bit 0: 1=RX enabled, Bit 1: 1=TX enabled */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_rcvinterrupt(int irq, void *context); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void m16c_rxint(struct up_dev_s *dev, bool enable); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static int up_xmtinterrupt(int irq, void *context); +static void up_send(struct uart_dev_s *dev, int ch); +static void m16c_txint(struct up_dev_s *dev, bool enable); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; + +/* I/O buffers */ + +#ifdef CONFIG_M16C_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_M16C_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_M16C_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +/* This describes the state of the M16C UART0 port. */ + +#ifdef CONFIG_M16C_UART0 +static struct up_dev_s g_uart0priv = +{ + .baud = CONFIG_UART0_BAUD, + .uartbase = M16C_UART0_BASE, + .uartno = 0, + .rcvirq = M16C_UART0RCV_IRQ, + .xmtirq = M16C_UART0XMT_IRQ, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stopbits2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the M16C UART1 port. */ + +#ifdef CONFIG_M16C_UART1 +static struct up_dev_s g_uart1priv = +{ + .baud = CONFIG_UART1_BAUD, + .uartbase = M16C_UART1_BASE, + .uartno = 1, + .rcvirq = M16C_UART1RCV_IRQ, + .xmtirq = M16C_UART1XMT_IRQ, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the M16C UART2 port. */ + +#ifdef CONFIG_M16C_UART2 +static struct up_dev_s g_uart2priv = +{ + .baud = CONFIG_UART2_BAUD, + .uartbase = M16C_UART2_BASE, + .uartno = 2, + .rcvirq = M16C_UART2RCV_IRQ, + .xmtirq = M16C_UART2XMT_IRQ, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialin16 + ****************************************************************************/ + +static inline uint16_t up_serialin16(struct up_dev_s *priv, int offset) +{ + return getreg16(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout16 + ****************************************************************************/ + +static inline void up_serialout16(struct up_dev_s *priv, int offset, uint16_t value) +{ + putreg16(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(struct up_dev_s *priv, uint8_t *penables) +{ + uint8_t enables = priv->enables; + m16c_txint(priv, false); + m16c_rxint(priv, false); + + if (enables) + { + *penables = enables; + } +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(struct up_dev_s *priv, uint8_t enables) +{ + m16c_rxint(priv, (enables & M16C_RXENABLED) != 0); + m16c_txint(priv, (enables & M16C_TXENABLED) != 0); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +#ifdef HAVE_SERIALCONSOLE +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TDR empty condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check the TI bit in the CI register. 1=Transmit buffer empty */ + + if ((up_serialin(priv, M16C_UART_C1) & UART_C1_TI) != 0); + { + /* The transmit buffer is empty... return */ + break; + } + } +} +#endif + +/**************************************************************************** + * Name: ub_setbrg + * + * Description: + * Calculate the correct value for the BRG given the configured frequency + * and the desired BAUD settings. + * + ****************************************************************************/ + +static inline void ub_setbrg(struct up_dev_s *priv, unsigned int baud) +{ + uint16_t brg; + + /* The Bit Rate Generator (BRG) value can be calculated by: + * + * BRG = source-frequency / prescaler / 16 / baud rate - 1 + * + * Example: + * source-frequency = 20,000,000 (20MHz) + * prescaler = 1 + * baud rate = 19200 + * BRG = 20,000,000/1/16/19200 - 1 = 64 + */ + + brg = (M16C_XIN_FREQ / (16L * M16C_XIN_PRESCALER * (uint32_t)baud)) - 1; + up_serialout(priv, M16C_UART_BRG, brg); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint8_t regval; + + /* Set the baud rate generator */ + + ub_setbrg(priv, priv->baud); + + /* Disable CTS/RTS */ + + up_serialout(priv, M16C_UART_C0, UART_C0_CRD); + + /* Disable RX/TX interrupts */ + + m16c_rxint(priv, false); + m16c_txint(priv, false); + +/* Set interrupt cause=TX complete and continuous receive mode */ + +#ifdef CONFIG_M16C_UART0 + if (priv->uartno == 0) + { + regval = getreg8(M16C_UCON); + regval |= (UART_CON_U0IRS|UART_CON_U0RRM); + putreg8(regval, M16C_UCON); + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (priv->uartno == 1) + { + regval = getreg8(M16C_UCON); + regval |= (UART_CON_U1IRS|UART_CON_U1RRM); + putreg8(regval, M16C_UCON); + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (priv->uartno == 2) + { + regval = getreg8(M16C_U2C1); + regval |= ((UART_C1_U2IRS|UART_C1_U2RRM); + putreg8(regval, M16C_U2C1); + } + else +#endif + { + dbg("Invalid UART #\n"); + } + + /* Set UART transmit/receive control register 1 to enable transmit and receive */ + + up_serialout(priv, M16C_UART_C1, UART_C1_TE|UART_C1_RE); + + /* Set UART transmit/receive mode register data bits, stop bits, parity */ + + regval = 0; + + if (priv->bits == 7) + { + regval |= UART_MR_SMD7BITS; + } + else if (priv->bits == 8) + { + regval |= UART_MR_SMD8BITS; + } + else if (priv->bits == 9) + { + regval |= UART_MR_SMD9BITS; + } + else + { + dbg("Invalid bits=%d\n", priv->bits); + } + + if (priv->parity != 0) + { + regval |= UART_MR_PRYE; + if (priv->parity == 2) + { + regval |= UART_MR_PRY; + } + } + + if (priv->stopbits2) + { + regval |= UART_MR_STPS; + } + + up_serialout(priv, M16C_UART_MR, regval); + + /* Set port direction registers for Rx/TX pins */ + +#ifdef CONFIG_M16C_UART0 + if (priv->uartno == 0) + { + regval = getreg8(M16C_PD6); + regval &= ~(1 << 2); /* PD6-2:RxD1 */ + regval |= (1 << 3); /* PD6-3:TxD1 */ + putreg8(regval, M16C_PD6); + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (priv->uartno == 1) + { + regval = getreg8(M16C_PD6); + regval &= ~(1 << 6); /* PD6-6:RxD1 */ + regval |= (1 << 7); /* PD6-7:TxD1 */ + putreg8(regval, M16C_PD6); + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (priv->uartno == 2) + { + regval = getreg8(M16C_PD7); + regval &= ~(1 << 1); /* PD7-1:RxD1 */ + regval &= (1 << 0); /* PD7-0:TxD1 */ + putreg8(regval, M16C_PD7); + } + else +#endif + { + dbg("Invalid UART #\n"); + } + + /* Read any data left in the RX fifo */ + + regval = (uint8_t)up_serialin16(priv, M16C_UART_RB); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + int ret; + + /* Attach the UART receive data available IRQ */ + + ret = irq_attach(priv->rcvirq, up_rcvinterrupt); + if (ret == OK) + { + /* Attach the UART transmit complete IRQ */ + + ret = irq_attach(priv->xmtirq, up_xmtinterrupt); + if (ret != OK) + { + /* Detach the ERI interrupt on failure */ + + (void)irq_detach(priv->rcvirq); + } + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + /* Disable all UART interrupts */ + + up_disableuartint(priv, NULL); + + /* Detach the UART interrupts */ + + (void)irq_detach(priv->rcvirq); + (void)irq_detach(priv->xmtirq); +} + +/**************************************************************************** + * Name: up_recvinterrupt + * + * Description: + * This is the UART receive interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_receivechar to + * perform the appropriate data transfer. The interrupt handling logic + * must be able to map the 'irq' number into the approprite up_dev_s + * structure in order to call these functions. + * + ****************************************************************************/ + +static int up_rcvinterrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + +#ifdef CONFIG_M16C_UART0 + if (irq == g_uart0priv.rcvirq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (irq == g_uart1priv.rcvirq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (irq = g_uart2priv.rcvirq) + { + dev = &g_uart2port; + } + else +#endif + { + PANIC(); + } + + /* Handle incoming, receive bytes (RDRF: Receive Data Register Full) */ + + uart_recvchars(dev); + return OK; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t rb; + + /* Read the character from the readbuffer */ + + rb = up_serialin16(priv, M16C_UART_RB); + + /* Return the received byte with the receive status */ + + *status = rb; + + /* Return the received character (up to 9 bits) */ + + return (int)(rb & 0x01ff); +} + +/**************************************************************************** + * Name: m16c_rxint, up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void m16c_rxint(struct up_dev_s *dev, bool enable) +{ + irqstate_t flags; + uint16_t regaddr; + uint8_t regvalue; + + /* Disable interrupts to prevent asynchronous accesses */ + + flags = enter_critical_section(); + + /* Pick the SxTIC register and enable interrupt priority */ + +#ifdef CONFIG_M16C_UART0 + if (dev->uartno == 0) + { + regaddr = M16C_S0RIC; + regvalue = M16C_S0R_PRIO; + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (dev->uartno == 1) + { + regaddr = M16C_S1RIC; + regvalue = M16C_S1R_PRIO; + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (dev->uartno == 2) + { + regaddr = M16C_S2RIC; + regvalue = M16C_S2R_PRIO; + } + else +#endif + { + dbg("Invalid UART #\n"); + return; + } + + /* Are we enabling or disabling? */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + putreg8(regvalue, regaddr); +#endif + dev->enables |= M16C_RXENABLED; + } + else + { + putreg8(0, regaddr); + dev->enables = ~M16C_RXENABLED; + } + + asm ("\tnop\n\tnop\n\tnop"); /* Three NOPs -- probably not necessary here */ + leave_critical_section(flags); +} + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + m16c_rxint((struct up_dev_s*)dev->priv, enable); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the RDR is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + /* Return true if there is data available in the read buffer */ + + return ((up_serialin(priv, M16C_UART_C1) & UART_C1_RI) != 0); +} + +/**************************************************************************** + * Name: up_xmtvinterrupt + * + * Description: + * This is the UART receive interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * up_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_xmtinterrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + +#ifdef CONFIG_M16C_UART0 + if (irq == g_uart0priv.xmtirq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (irq == g_uart1priv.xmtirq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (irq == g_uart2priv.xmtirq) + { + dev = &g_uart1port; + } + else +#endif + { + PANIC(); + } + + /* Handle outgoing, transmit bytes */ + + uart_xmitchars(dev); + return OK; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + /* Write the data to the transmit buffer */ + + up_serialout16(priv, M16C_UART_TB, (uint16_t)ch); +} + +/**************************************************************************** + * Name: m16c_txint, up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void m16c_txint(struct up_dev_s *dev, bool enable) +{ + irqstate_t flags; + uint16_t regaddr; + uint8_t regvalue; + + /* Disable interrupts to prevent asynchronous accesses */ + + flags = enter_critical_section(); + + /* Pick the SxTIC register and enable interrupt priority */ + +#ifdef CONFIG_M16C_UART0 + if (dev->uartno == 0) + { + regaddr = M16C_S0TIC; + regvalue = M16C_S0T_PRIO; + } + else +#endif +#ifdef CONFIG_M16C_UART1 + if (dev->uartno == 1) + { + regaddr = M16C_S1TIC; + regvalue = M16C_S1T_PRIO; + } + else +#endif +#ifdef CONFIG_M16C_UART2 + if (dev->uartno == 2) + { + regaddr = M16C_S2TIC; + regvalue = M16C_S2T_PRIO; + } + else +#endif + { + dbg("Invalid UART #\n"); + return; + } + + /* Are we enabling or disabling? */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + putreg8(regvalue, regaddr); +#endif + dev->enables |= M16C_TXENABLED; + } + else + { + putreg8(0, regaddr); + dev->enables = ~M16C_TXENABLED; + } + + asm ("\tnop\n\tnop\n\tnop"); /* Three NOPs -- probably not necessary here */ + leave_critical_section(flags); +} + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + m16c_txint((struct up_dev_s*)dev->priv, enable); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the TDR is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return ((up_serialin(priv, M16C_UART_C1) & UART_C1_TI) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyconsoleinit + * + * Description: + * Performs the low level UART initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_consoleinit. + * + ****************************************************************************/ + +void up_earlyconsoleinit(void) +{ + /* NOTE: All GPIO configuration for the UARTs was performed in + * up_lowsetup + */ + + /* Disable all UARTs */ + +#ifdef TTYS0_DEV + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#ifdef TTYS2_DEV + up_disableuartint(TTYS2_DEV.priv, NULL); +#endif +#endif +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIALCONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyconsoleinit was called previously. + * + ****************************************************************************/ + +void up_consoleinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIALCONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#endif +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIALCONSOLE + struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; + uint8_t ucon; + + up_disableuartint(priv, &ucon); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout16(priv, M16C_UART_TB, (uint16_t)'\r'); + } + + up_waittxready(priv); + up_serialout16(priv, M16C_UART_TB, (uint16_t)ch); + + up_waittxready(priv); + up_restoreuartint(priv, ucon); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIALCONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ +#elif defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE)|| defined(CONFIG_UART2_SERIAL_CONSOLE) +# error "A serial console selected, but corresponding UART not enabled" +#endif /* CONFIG_M16C_UART0 || CONFIG_M16C_UART1 || CONFIG_M16C_UART2 */ + diff --git a/arch/sh/src/m16c/m16c_sigdeliver.c b/arch/sh/src/m16c/m16c_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..3b595ed7ef7d94bc591ad2000f04e0d1770e2353 --- /dev/null +++ b/arch/sh/src/m16c/m16c_sigdeliver.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_sigdeliver.c + * + * Copyright (C) 2009-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + struct tcb_s *rtcb = this_task(); + uint8_t regs[XCPTCONTEXT_SIZE]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc[0]; + regs[REG_PC+1] = rtcb->xcp.saved_pc[1]; + regs[REG_FLG] = rtcb->xcp.saved_flg; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(rtcb->xcp.saved_flg); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +#endif +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/sh/src/m16c/m16c_timer.h b/arch/sh/src/m16c/m16c_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..ff542163222159572d398265906ddc2522a781a0 --- /dev/null +++ b/arch/sh/src/m16c/m16c_timer.h @@ -0,0 +1,226 @@ +/************************************************************************************ + * arch/sh/src/m16c/m16c_timer.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_SH_SRC_M16C_M16C_TIMER_H +#define __ARCH_SH_SRC_M16C_M16C_TIMER_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Bit Definitions *********************************************************/ + +#define M16C_TA0IC 0x00055 /* Timer A0 interrupt control */ +#define M16C_TA1IC 0x00056 /* Timer A1 interrupt control */ +#define M16C_TA2IC 0x00057 /* Timer A2 interrupt control */ +#define M16C_TA3IC 0x00058 /* Timer A3 interrupt control */ +#define M16C_TA4IC 0x00059 /* Timer A4 interrupt control */ + +/* Count Start Flag Register (8-bit access) Register */ + +#define TABSR_TA0S 0x01 /* Bit 0: Timer A0 count start */ +#define TABSR_TA1S 0x02 /* Bit 1: Timer A1 count start */ +#define TABSR_TA2S 0x04 /* Bit 2: Timer A2 count start */ +#define TABSR_TA3S 0x08 /* Bit 3: Timer A3 count start */ +#define TABSR_TA4S 0x10 /* Bit 4: Timer A4 count start */ +#define TABSR_TB0S 0x20 /* Bit 5: Timer B0 count start */ +#define TABSR_TB1S 0x40 /* Bit 6: Timer B1 count start */ +#define TABSR_TB2S 0x80 /* Bit 7: Timer B2 count start */ + +/* Clock Prescaler Reset Flag Register */ + /* Bits 0-6: Not used */ +#define CPSRF_CPSR 0x80 /* Bit 7: 1=Prescaler is reset */ + +/* On-Shot Start Flag Register (8-bit access) */ + +#define ONSF_TA0OS 0x01 /* Bit 0: Timer A0 one shot start */ +#define ONSF_TA1OS 0x02 /* Bit 1: Timer A1 one shot start */ +#define ONSF_TA2OS 0x04 /* Bit 2: Timer A2 one shot start */ +#define ONSF_TA3OS 0x08 /* Bit 3: Timer A3 one shot start */ +#define ONSF_TA4OS 0x10 /* Bit 4: Timer A4 one shot start */ + /* Bit 5: Reserved */ +#define ONSF_TA0TG_MASK 0xc0 /* Bit 6-7: Timer A0 event trigger select bits */ +#define ONSF_TAOTG_INTAON 0x00 /* 00 : Input on TA0IN is selected */ +#define ONSF_TAOTG_TB2OVF 0x40 /* 01 : TB2 overflow is selected */ +#define ONSF_TAOTG_TB4OVF 0x80 /* 10 : TB4 overflow is selected */ +#define ONSF_TAOTG_TB1OVF 0xc0 /* 11 : TB1 overflow is selected */ + +/* Trigger Select Register */ + +#define TRGSR_TA1TG_MASK 0x03 /* Bit 0-1: Timer A1 event trigger select bits */ +#define TRGSR_TA1TG_INTAON 0x00 /* 00 : Input on TA1IN is selected */ +#define TRGSR_TA1TG_TB2OVF 0x01 /* 01 : TB2 overflow is selected */ +#define TRGSR_TA1TG_TB4OVF 0x02 /* 10 : TB4 overflow is selected */ +#define TRGSR_TA1TG_TB1OVF 0x03 /* 11 : TB1 overflow is selected */ +#define TRGSR_TA2TG_MASK 0x0c /* Bit 2-3: Timer A2 event trigger select bits */ +#define TRGSR_TA2TG_INTAON 0x00 /* 00 : Input on TA2IN is selected */ +#define TRGSR_TA2TG_TB2OVF 0x04 /* 01 : TB2 overflow is selected */ +#define TRGSR_TA2TG_TB4OVF 0x08 /* 10 : TB4 overflow is selected */ +#define TRGSR_TA2TG_TB1OVF 0x0c /* 11 : TB1 overflow is selected */ +#define TRGSR_TA3TG_MASK 0x30 /* Bit 4-5: Timer A3 event trigger select bits */ +#define TRGSR_TA3TG_INTAON 0x00 /* 00 : Input on TA3IN is selected */ +#define TRGSR_TA3TG_TB2OVF 0x10 /* 01 : TB2 overflow is selected */ +#define TRGSR_TA3TG_TB4OVF 0x20 /* 10 : TB4 overflow is selected */ +#define TRGSR_TA3TG_TB1OVF 0x30 /* 11 : TB1 overflow is selected */ +#define TRGSR_TA4TG_MASK 0xc0 /* Bit 6-7: Timer A4 event trigger select bits */ +#define TRGSR_TA4TG_INTAON 0x00 /* 00 : Input on TA4IN is selected */ +#define TRGSR_TA4TG_TB2OVF 0x40 /* 01 : TB2 overflow is selected */ +#define TRGSR_TA4TG_TB4OVF 0x80 /* 10 : TB4 overflow is selected */ +#define TRGSR_TA4TG_TB1OVF 0xc0 /* 11 : TB1 overflow is selected */ + +/* Up-Down Flag Register */ + +#define UDF_TA0UD 0x01 /* Bit 0: 1=Timer A0 up count */ +#define UDF_TA1UD 0x02 /* Bit 1: 1=Timer A1 up count */ +#define UDF_TA2UD 0x04 /* Bit 2: 1=Timer A2 up count */ +#define UDF_TA3UD 0x08 /* Bit 3: 1=Timer A3 up count */ +#define UDF_TA4UD 0x10 /* Bit 4: 1=Timer A4 up count */ +#define UDF_TA2P 0x20 /* Bit 5: Timer A2 two-phase pulse signal processing select */ +#define UDF_TA3P 0x40 /* Bit 5: Timer A3 two-phase pulse signal processing select */ +#define UDF_TA4P 0x80 /* Bit 5: Timer A4 two-phase pulse signal processing select */ + +/* Timer A Registers (16-bit access), simple value range 0000-ffff + * (except in PWM mode) + */ + +/* Timer B Registers (16-bit access), simple value range 0000-ffff + * (except in Pulse period/pulse width measurement mode) + */ + +/* Timer A Mode Register (8-bit access) */ + +#define TAnMR_TMOD_MASK 0x03 /* Bits 0-1: Operation mode select */ +#define TAnMR_TMOD_TIMER 0x00 /* 00 : Timer mode */ +#define TAnMR_TMOD_EVENT 0x01 /* 01 : Event counter mode */ +#define TAnMR_TMOD_ONESHOT 0x02 /* 10 : One-shot timer mode */ +#define TAnMR_TMOD_PWM 0x03 /* 11 : Pulse width modulation (PWM) mode */ +#define TAnMR_MR_MASK 0x3c /* Bits 2-5: Mode function values */ + /* Timer Mode: */ +#define TAnMR_MR_TMNOOUT 0x00 /* 0xx0 : No output */ +#define TAnMR_MR_TMOUT 0x04 /* 0xx1 : Pulse is output */ +#define TAnMR_MR_TMNOGATE 0x00 /* 00xx : Gate function not available */ +#define TAnMR_MR_TMTAINLO 0x10 /* 010x : Timer counts when TAiIN pin is L */ +#define TAnMR_MR_TMTAINHI 0x18 /* 011x : Timer counts when TAiIN pin is H */ + /* Event Counter Mode: */ +#define TAnMR_MR_EC2PHASE 0x10 /* 0100 : Settings required for 2-phase mode */ +#define TAnMR_MR_ECNOOUT 0x00 /* 0xx0 : No output */ +#define TAnMR_MR_ECOUT 0x04 /* 0xx1 : 1=Pulse is output */ +#define TAnMR_MR_ECFALLING 0x00 /* 0x0x : Count polarity falling edge */ +#define TAnMR_MR_ECRISING 0x08 /* 0x1x : Count polarity rising edge */ +#define TAnMR_MR_ECUDC 0x00 /* 00xx : Up/down switching on up/down content */ +#define TAnMR_MR_ECINP 0x10 /* 01xx : Up/down switching on TAnOUT input signal */ + /* One Shot Mode: */ +#define TAnMR_MR_OSNOOUT 0x00 /* 0xx0 : No output */ +#define TAnMR_MR_OSOUT 0x04 /* 0xx1 : Pulse is output */ +#define TAnMR_MR_OSFALLING 0x00 /* 0x0x : TAin falling edge */ +#define TAnMR_MR_OSRISING 0x08 /* 0x1x : TAin rising edge */ +#define TAnMR_MR_OSSFLAG 0x00 /* 00xx : Trigger select one-shot start flag */ +#define TAnMR_MR_OSSTRIG 0x10 /* 01xx : Trigger Selected by event/trigger select bits */ + /* PWM Mode: */ +#define TAnMR_MR_PMFALLING 0x00 /* xx00 : TAin falling edge */ +#define TAnMR_MR_PMRISING 0x08 /* xx10 : TAin rising edge */ +#define TAnMR_MR_PMSFLAG 0x00 /* x0x0 : Trigger select one-shot start flag */ +#define TAnMR_MR_PMTRIG 0x10 /* x1x0 : Trigger Selected by event/trigger select bits */ +#define TAnMR_MR_PM16BIT 0x00 /* 0xx0 : Functions as a 16-bit pulse width modulator */ +#define TAnMR_MR_PM8BIT 0x20 /* 1xx0 : Functions as an 8-bit pulse width modul */ +#define TAnMR_TCK_MASK 0xc0 /* Bits 6-7: Count source select */ + /* Timer Mode: */ +#define TAnMR_TCK_TMF1 0x00 /* 00: f1 or f2 */ +#define TAnMR_TCK_TMF8 0x40 /* 01: f8 */ +#define TAnMR_TCK_TMF32 0x80 /* 10: f32 */ +#define TAnMR_TCK_TMFC32 0xc0 /* 11: fc32 */ + /* Event Counter Mode: */ +#define TAnMR_TCK_ECRELOAD 0x00 /* x0: Reload count operation*/ +#define TAnMR_TCK_ECFRUN 0x40 /* x1: Free run count operation*/ +#define TAnMR_TCK_ECNORMAL 0x00 /* 0x: Normal processing operation */ +#define TAnMR_TCK_ECMUL4 0x80 /* 1x: Multiply-by-4 processing operation */ + /* One Shot Mode: */ +#define TAnMR_TCK_OSF1 0x00 /* 00: f1 or f2 */ +#define TAnMR_TCK_OSF8 0x40 /* 01: f8 */ +#define TAnMR_TCK_OSF32 0x80 /* 10: f32 */ +#define TAnMR_TCK_OSFC32 0xc0 /* 11: fc32 */ + /* PWM Mode: */ +#define TAnMR_TCK_PMF1 0x00 /* 00: f1 or f2 */ +#define TAnMR_TCK_PMF8 0x40 /* 01: f8 */ +#define TAnMR_TCK_PMF32 0x80 /* 10: f32 */ +#define TAnMR_TCK_PMFC32 0xc0 /* 11: fc32 */ + +/* Timer B Mode Register (8-bit access) */ + +#define TBnMR_TMOD_MASK 0x03 /* Bits 0-1: Operation mode select */ +#define TBnMR_TMOD_TIMER 0x00 /* 00 : Timer mode */ +#define TBnMR_TMOD_EVENT 0x01 /* 01 : Event counter mode */ +#define TBnMR_TMOD_PWM 0x02 /* 10 : Pulse period/pulse width measurement mode */ +#define TBnMR_MR_MASK 0x3c /* Bits 2-5: Mode function values */ + /* Timer Mode: */ +#define TBnMR_MR_TM 0x00 /* 0000 : Required bit settings for timer mode */ + /* Event Counter Mode: */ +#define TBnMR_MR_ECFALLING 0x00 /* 0000 : Counts external signal's falling edges */ +#define TBnMR_MR_ECRISING 0x04 /* 0001 : Counts external signal's rising edges */ +#define TBnMR_MR_ECXTFALL 0x00 /* 0010 : Counts external signal's falling and rising edges */ + /* Pulse period/pulse width measurement mode: */ +#define TBnMR_MR_PMFALLING 0x00 /* 0000 : Period between falling edge to falling edge */ +#define TBnMR_MR_PMRISING 0x08 /* 0001 : Period between rising edge to rising edge */ +#define TBnMR_MR_PMSVAL 0x00 /* 0010 : Width between edge(s) to edge(s) */ +#define TBnMR_TCK_MASK 0xc0 /* Bits 6-7: Count source select */ + /* Timer Mode: */ +#define TBnMR_TCK_TMF1 0x00 /* 00: f1 or f2 */ +#define TBnMR_TCK_TMF8 0x40 /* 01: f8 */ +#define TBnMR_TCK_TMF32 0x80 /* 10: f32 */ +#define TBnMR_TCK_TMFC32 0xc0 /* 11: fc32 */ + /* Event Counter Mode: */ +#define TBnMR_TCK_ECTBIN 0x00 /* 00: Input from TBnIN pin */ +#define TBnMR_TCK_ECTBOVF 0x80 /* 10: TBj overflow */ + /* Pulse period/pulse width measurement mode: */ +#define TBnMR_TCK_PMF1 0x00 /* 00: f1 or f2 */ +#define TBnMR_TCK_PMF8 0x40 /* 01: f8 */ +#define TBnMR_TCK_PMF32 0x80 /* 10: f32 */ +#define TBnMR_TCK_PMFC32 0xc0 /* 11: fc32 */ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_SH_SRC_M16C_M16C_TIMER_H */ diff --git a/arch/sh/src/m16c/m16c_timerisr.c b/arch/sh/src/m16c/m16c_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..adaa18af022ba7270ea7310bd810400dd7ad94a1 --- /dev/null +++ b/arch/sh/src/m16c/m16c_timerisr.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "m16c_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration */ + +#ifndef M16C_TA0_PRIO /* Timer A0 interrupt priority */ +# define M16C_TA0_PRIO 5 +#endif + +/* Determine the ideal preload value for the timer. + * + * For example, given a 20MHz input frequency and a desired 100 Hz, clock, + * the ideal reload value would be: + * + * 20,000,000 / 100 = 200,000 + * + * The ideal prescaler value would be the one, then that drops this to exactly + * 66535: + * + * M16C_IDEAL_PRESCALER = 200,000 / 65535 = 3.05 + * + * And any value greater than 3.05 would also work with less and less precision. + * The following calculation will produce the ideal prescaler as the next integer + * value above any fractional values: + */ + +#define M16C_DIVISOR (65535 * CLK_TCK) +#define M16C_IDEAL_PRESCALER \ + ((M16C_XIN_FREQ + M16C_DIVISOR - 1) / M16C_DIVISOR) + +/* Now, given this idel prescaler value, pick between available choices: 1, 8, and 32 */ + +#if M16C_IDEAL_PRESCALER > 8 +# define M16C_PRESCALE_VALUE 32 +# define M16C_PRESCALE_BITS TAnMR_TCK_TMF32 +#elif M16C_IDEL_PRESCALER > 1 +# define M16C_PRESCALE_VALUE 8 +# define M16C_PRESCALE_BITS TAnMR_TCK_TMF8 +#else +# define M16C_PRESCALE_VALUE 1 +# define M16C_PRESCALE_BITS TAnMR_TCK_TMF1 +#endif + +/* Timer 0 Mode Settings */ + +#define M16C_TA0MODE_CONFIG \ + (TAnMR_TMOD_TIMER|TAnMR_MR_TMNOOUT|TAnMR_MR_TMNOGATE|M16C_PRESCALE_BITS) + +/* The actual reload value matching the selected prescaler value */ + +#define M16C_RELOAD_VALUE \ + ((M16C_XIN_FREQ / M16C_PRESCALE_VALUE / CLK_TCK) - 1) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* Make sure that no timers are running and that all timer interrupts are + * disabled. + */ + + putreg8(0, M16C_TABSR); + putreg8(0, M16C_TA0IC); + putreg8(0, M16C_TA1IC); + putreg8(0, M16C_TA2IC); + putreg8(0, M16C_TA3IC); + putreg8(0, M16C_TA4IC); + putreg8(0, M16C_TB0IC); + putreg8(0, M16C_TB1IC); + putreg8(0, M16C_TB2IC); + + /* Set up timer 0 mode register for timer mode with the calculated prescaler value */ + + putreg8(M16C_TA0MODE_CONFIG, M16C_TA0MR); + + /* Set the calculated reload value */ + + putreg16(M16C_RELOAD_VALUE, M16C_TA0); + + /* Attach the interrupt handler */ + + irq_attach(M16C_SYSTIMER_IRQ, (xcpt_t)up_timerisr); + + /* Enable timer interrupts */ + + putreg8(1, M16C_TA0IC); + + /* Set the interrupt priority */ + + putreg8(M16C_TA0_PRIO, M16C_TA0IC); + + /* Start the timer */ + + putreg8(TABSR_TA0S, M16C_TABSR); +} diff --git a/arch/sh/src/m16c/m16c_uart.h b/arch/sh/src/m16c/m16c_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..382411538d3be8f5845a051f9122f32a7a66d693 --- /dev/null +++ b/arch/sh/src/m16c/m16c_uart.h @@ -0,0 +1,145 @@ +/************************************************************************************ + * arch/sh/src/m16c/m16c_uart.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_SH_SRC_M16C_M16C_UART_H +#define __ARCH_SH_SRC_M16C_M16C_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* UART Register Block Base Addresses ***********************************************/ + +#define M16C_UART0_BASE 0x003a0 /* First UART0 register */ +#define M16C_UART1_BASE 0x003a8 /* First UART1 register */ +#define M16C_UART2_BASE 0x00378 /* First UART2 register (ignoring special regs) */ + +/* UART Register Offsets ************************************************************/ + +#define M16C_UART_MR 0x00 /* 8-bit UART transmit/receive mode */ +#define M16C_UART_BRG 0x01 /* 8-bit UART bit rate generator */ +#define M16C_UART_TB 0x02 /* 16-bit UART transmit buffer */ +#define M16C_UART_C0 0x04 /* 8-bit UART transmit/receive control 0 */ +#define M16C_UART_C1 0x05 /* 8-bit UART transmit/receive control 1 */ +#define M16C_UART_RB 0x06 /* 16-bit UART receive buffer */ + +/* UART Register Bit Definitions ****************************************************/ + +/* UART transmit/receive mode */ + +#define UART_MR_SMDMASK 0x07 /* Serial I/O mode select */ +#define UART_MR_SMDINVALID 0x00 /* 000: Serial I/O invalid */ +#define UART_MR_SMDSYNCH 0x01 /* 001: Required in Sync Mode (UART0/1) Serial I/O (UART2) */ +#define UART_MR_SMDINHIB1 0x02 /* 010: Inhibited (UART0/1) I2C mode (UART2) */ +#define UART_MR_SMDINHIB2 0x03 /* 011: Inhibited */ +#define UART_MR_SMD7BITS 0x04 /* 100: Transfer data 7 bits long */ +#define UART_MR_SMD8BITS 0x05 /* 101: Transfer data 8 bits long */ +#define UART_MR_SMD9BITS 0x06 /* 110: Transfer data 9 bits long */ +#define UART_MR_SMDINHIB3 0x07 /* 111: Inhibited */ +#define UART_MR_CKDIR 0x08 /* Bit 3: Internal/external clock select 1=external */ +#define UART_MR_STPS 0x10 /* Bit 4: Stop bit length select 1=2 stop bits */ +#define UART_MR_PRY 0x20 /* Bit 5: Odd/even parity select bit 1=Even parity */ +#define UART_MR_PRYE 0x40 /* Bit 6: Parity enable 1=enabled */ +#define UART_MR_IOPOL 0x80 /* Bit 7: Reserved (UART0/1) Tx/Rx polarity reverse (UART2) */ + +/* UART receive buffer register (16-bit) */ + +#define UART_RB_DATAMASK 0x01ff /* Bits 0-8: Receive data */ + /* Bits 9-10: Reserved */ +#define UART_RB_ABT 0x0800 /* Bit 11: Arbitration lost detecting flag */ +#define UART_RB_OER 0x1000 /* Bit 12: Overrun error flag */ +#define UART_RB_FER 0x2000 /* Bit 13: Framing error flag */ +#define UART_RB_PER 0x4000 /* Bit 14: Parity error flag */ +#define UART_RB_SUM 0x8000 /* Bit 15: Error sum flag */ + +/* UART Transmit/Receive Control 0 */ + +#define UART_C0_CLKMASK 0x02 /* Bits 0-1: BRG count source select */ +#define UART_C0_F1SIO 0x00 /* 00 : f1SIO or f2SIO is selected */ +#define UART_C0_F8SIO 0x01 /* 01 : f8SIO is selected */ +#define UART_C0_F32SIO 0x02 /* 10 : f32SIO is selected */ +#define UART_C0_INHIB 0x03 /* 11 : Inhibited */ +#define UART_C0_CRS 0x04 /* Bit 2: CTS/RTS function select 1=RTS */ +#define UART_C0_TXEPT 0x08 /* Bit 3: Transmit register empty 1=empty */ +#define UART_C0_CRD 0x10 /* Bit 4: CTS/RTS disable bit 1=CTS/RTS disabled */ +#define UART_C0_NCH 0x20 /* Bit 5: Data output select 1=TxDi is N-channel open drain output */ +#define UART_C0_CKPOL 0x40 /* Bit 6: CLK polarity select 1=XMT rising, recieve falling */ +#define UART_C0_UFORM 0x80 /* Bit 7: Transfer format select 1=MSB first */ + +/* UART Transmit/Receive Control 1 */ + +#define UART_C1_TE 0x01 /* Bit 0: Transmit enable 1=enable */ +#define UART_C1_TI 0x02 /* Bit 1: Transmit buffer empty 1=empty */ +#define UART_C1_RE 0x04 /* Bit 2: Receive enable 1=enable */ +#define UART_C1_RI 0x08 /* Bit 3: Receive complete 1=data in read buffer */ + /* The following are only defined for UART2: */ +#define UART_C1_U2IRS 0x10 /* Bit 4: UART2 transmit interrupt cause select */ +#define UART_C1_U2RRM 0x20 /* Bit 5: UART2 continuous receive mode enable */ +#define UART_C1_U2LCH 0x40 /* Bit 6: UART2 Data logic select */ +#define UART_C1_U2ERE 0x80 /* Bit 7: UART2 Error signal output enable */ + +/* UART2 Transmit/Receive Control 2 */ + +#define UART_CON_U0IRS 0x01 /* Bit 0: UART0 transmit interrupt cause select */ +#define UART_CON_U1IRS 0x02 /* Bit 1: UART1 transmit interrupt cause select */ +#define UART_CON_U0RRM 0x04 /* Bit 2: UART0 continuous receive mode enable */ +#define UART_CON_U1RRM 0x08 /* Bit 3: UART1 continuous receive mode enable */ +#define UART_CON_CLKMD0 0x10 /* Bit 4: CLK/CLKS select bit 0 */ +#define UART_CON_CLKMD1 0x20 /* Bit 5: CLK/CLKS select bit */ +#define UART_CON_RCSP 0x40 /* Bit 6: Separate CTS/RTS bit */ + /* Bit 7: Reserved */ +/* UART2 special mode register 1 (to be provided) */ + +/* UART2 special mode register 2 (to be provided) */ + +/* UART2 special mode register 3 (to be provided) */ + +/* UART2 special mode register 4 (to be provided) */ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_SH_SRC_M16C_M16C_UART_H */ diff --git a/arch/sh/src/m16c/m16c_vectors.S b/arch/sh/src/m16c/m16c_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..b59f179864f811adfe19d4402f19111a18fdaa4a --- /dev/null +++ b/arch/sh/src/m16c/m16c_vectors.S @@ -0,0 +1,523 @@ +/************************************************************************************ + * arch/sh/src/m16c/m16c_vectors.S + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Select register bank 1, and pass the IRQ number to _m16c_commonvector */ + + .macro m16c_vector, label, irqno +\label: + fset b + mov.w #\irqno, r1 + jmp.w _m16c_commonvector + .endm + +/* Special page vectors. This macro puts the jump address of + * functions defined as special page into the special page vector table. + * See example calls below and see the M16C Software Manual or NC30 + * manual for more information on special page vectors. + */ +#if 0 + .macro m16c_special, num + .org 0x0ffffe-(\num*2) + .globl __SPECIAL_\num + .word __SPECIAL_\num & 0x0ffff + .endm +#endif + +/************************************************************************************ + * Data + ************************************************************************************/ + +/************************************************************************************ + * Interrupt Vectors + ************************************************************************************/ + +/* Variable vector section */ + + .section varvects /* Variable vector table */ + .long _m16c_brk_isr /* ffd00: BRK instruction */ + .long 0xffffffff /* ffd04 */ + .long 0xffffffff /* ffd08 */ + .long 0xffffffff /* ffd0c */ + .long _m16c_int3_isr /* ffd10: INT3 */ + .long _m16c_contextsave /* ffd14: Reserved -- SWINT5 used by NuttX */ +#ifdef CONFIG_M16C_SWINTS + .long _m16c_swint6_isr /* ffd18: S/W interrupt 7 */ + .long _m16c_swint7_isr /* ffd1c: S/W interrupt 7 */ +#else + .long _m16c_unexpected_isr /* ffd1c: Reserved */ + .long _m16c_unexpected_isr /* ffd1c: Reserved */ +#endif + .long _m16c_int5_isr /* ffd20: INT5 */ + .long _m16c_int4_isr /* ffd24: INT4 */ + .long _m16c_uart2bcd_isr /* ffd28: UART2 bus collision detection */ + .long _m16c_dma0_isr /* ffd2c: DMA0 */ + .long _m16c_dma1_isr /* ffd30: DMA1 */ + .long _m16c_keyinp_isr /* ffd34: Key input interrupt */ + .long _m16c_adc_isr /* ffd38: A-D */ + .long _m16c_uart2xmitnack2_isr /* ffd3c UART2 transmit/NACK2 */ + .long _m16c_uart2rcvack2_isr /* ffd40: UART2 receive/ACK2 */ + .long _m16c_uart0xmit_isr /* ffd44: UART0 transmit */ + .long _m16c_uart0rcv_isr /* ffd48: UART0 receive */ + .long _m16c_uart1xmit_isr /* ffd4c: UART1 transmit */ + .long _m16c_uart1rcv_isr /* ffd50: UART1 receive */ + .long _m16c_tmra0_isr /* ffd54: Timer A0 */ + .long _m16c_tmra1_isr /* ffd58: Timer A1 */ + .long _m16c_tmra2_isr /* ffd5c: Timer A2 */ + .long _m16c_tmra3_isr /* ffd60: Timer A3 */ + .long _m16c_tmra4_isr /* ffd64: Timer A4 */ + .long _m16c_tmrb0_isr /* ffd68: Timer B0 */ + .long _m16c_tmrb1_isr /* ffd6c: Timer B1 */ + .long _m16c_tmrb2_isr /* ffd70: Timer B2 */ + .long _m16c_int0_isr /* ffd74: INT0 */ + .long _m16c_int1_isr /* ffd78: INT1 */ +#ifdef CONFIG_M16C_SWINTS + .long _m16c_swint31_isr /* ffd7c: S/W interrupt 31 */ + .long _m16c_contextrestore /* ffd80: S/W interrupt 32 by NuttX */ + .long _m16c_swint33_isr /* ffd84: S/W interrupt 33 */ + .long _m16c_swint34_isr /* ffd88: S/W interrupt 34 */ + .long _m16c_swint35_isr /* ffd8c: S/W interrupt 35 */ + .long _m16c_swint36_isr /* ffd90: S/W interrupt 36 */ + .long _m16c_swint37_isr /* ffd94: S/W interrupt 37 */ + .long _m16c_swint38_isr /* ffd98: S/W interrupt 38 */ + .long _m16c_swint39_isr /* ffd9c: S/W interrupt 39 */ + .long _m16c_swint40_isr /* ffda0: S/W interrupt 40 */ + .long _m16c_swint41_isr /* ffda4: S/W interrupt 41 */ + .long _m16c_swint42_isr /* ffda8: S/W interrupt 42 */ + .long _m16c_swint43_isr /* ffdac: S/W interrupt 43 */ + .long _m16c_swint44_isr /* ffdb0: S/W interrupt 44 */ + .long _m16c_swint45_isr /* ffdb4: S/W interrupt 45 */ + .long _m16c_swint46_isr /* ffdb8: S/W interrupt 46 */ + .long _m16c_swint47_isr /* ffdbc: S/W interrupt 47 */ + .long _m16c_swint48_isr /* ffdc0: S/W interrupt 48 */ + .long _m16c_swint49_isr /* ffdc4: S/W interrupt 49 */ + .long _m16c_swint50_isr /* ffdc8: S/W interrupt 50 */ + .long _m16c_swint51_isr /* ffdcc: S/W interrupt 51 */ + .long _m16c_swint52_isr /* ffdd0: S/W interrupt 52 */ + .long _m16c_swint53_isr /* ffdd4: S/W interrupt 53 */ + .long _m16c_swint54_isr /* ffdd8: S/W interrupt 54 */ + .long _m16c_swint55_isr /* ffddc: S/W interrupt 55 */ + .long _m16c_swint56_isr /* ffde0: S/W interrupt 56 */ + .long _m16c_swint57_isr /* ffde4: S/W interrupt 57 */ + .long _m16c_swint58_isr /* ffde8: S/W interrupt 58 */ + .long _m16c_swint59_isr /* ffdec: S/W interrupt 59 */ + .long _m16c_swint60_isr /* ffdf0: S/W interrupt 60 */ + .long _m16c_swint61_isr /* ffdf4: S/W interrupt 61 */ + .long _m16c_swint62_isr /* ffdf8: S/W interrupt 62 */ + .long _m16c_swint63_isr /* ffdfc: S/W interrupt 63 */ +#else + .long _m16c_unexpected_isr /* ffd7c: Reserved */ + .long _m16c_contextrestore /* ffd80: S/W interrupt 32 by NuttX */ + .long _m16c_unexpected_isr /* ffd84: Not supported */ + .long _m16c_unexpected_isr /* ffd88: Not supported */ + .long _m16c_unexpected_isr /* ffd8c: Not supported */ + .long _m16c_unexpected_isr /* ffd90: Not supported */ + .long _m16c_unexpected_isr /* ffd94: Not supported */ + .long _m16c_unexpected_isr /* ffd98: Not supported */ + .long _m16c_unexpected_isr /* ffd9c: Not supported */ + .long _m16c_unexpected_isr /* ffda0: Not supported */ + .long _m16c_unexpected_isr /* ffda4: Not supported1 */ + .long _m16c_unexpected_isr /* ffda8: Not supported */ + .long _m16c_unexpected_isr /* ffdac: Not supported */ + .long _m16c_unexpected_isr /* ffdb0: Not supported */ + .long _m16c_unexpected_isr /* ffdb4: Not supported */ + .long _m16c_unexpected_isr /* ffdb8: Not supported */ + .long _m16c_unexpected_isr /* ffdbc: Not supported */ + .long _m16c_unexpected_isr /* ffdc0: Not supported */ + .long _m16c_unexpected_isr /* ffdc4: Not supported */ + .long _m16c_unexpected_isr /* ffdc8: Not supported */ + .long _m16c_unexpected_isr /* ffdcc: Not supported */ + .long _m16c_unexpected_isr /* ffdd0: Not supported */ + .long _m16c_unexpected_isr /* ffdd4: Not supported */ + .long _m16c_unexpected_isr /* ffdd8: Not supported */ + .long _m16c_unexpected_isr /* ffddc: Not supported */ + .long _m16c_unexpected_isr /* ffde0: Not supported */ + .long _m16c_unexpected_isr /* ffde4: Not supported */ + .long _m16c_unexpected_isr /* ffde8: Not supported */ + .long _m16c_unexpected_isr /* ffdec: Not supported */ + .long _m16c_unexpected_isr /* ffdf0: Not supported */ + .long _m16c_unexpected_isr /* ffdf4: Not supported */ + .long _m16c_unexpected_isr /* ffdf8: Not supported */ + .long _m16c_unexpected_isr /* ffdfc: Not supported */ +#endif + +/* Fixed vector section + * + * The fixed vector table begins at address ffe00. The firt portion + * of the fixed vector table is the special page table. This table + * is not currently used. + */ + .section specpg /* Special page table */ + /* Nothing */ + .section fixvects /* Fixed vector table */ + .long _m16c_undefinst_irq /* fffdc: Undefined instruction */ + .long _m16c_overflow_irq /* fffe0: Overflow */ + .long _m16c_brkinst_irq /* fffe4: BRK instruction */ + .long _m16c_addrmatch_irq /* fffe8: Address match */ +#ifdef CONFIG_M16C_DEBUGGER + .long _m16c_sstep_irq /* fffec: Single step */ +#else + .long _m16c_unexpected_isr /* fffec: Not supported */ +#endif + .long _m16c_wdog_irq /* ffff0: Watchdog timer */ +#ifdef CONFIG_M16C_DEBUGGER + .long _m16c_dbc_irq /* ffff4: DBC */ +#else + .long _m16c_unexpected_isr /* ffff4: Not supported */ +#endif + .long _m16c_nmi_irq /* ffff8: NMI */ + .long __start /* ffffc: Reset */ + +/************************************************************************************ + * Code + ************************************************************************************/ +/************************************************************************************ + * Name: m16c_*isr + * + * Description: + * Handler interrupt events. The CPU performs the following actions when an + * interrupt is taken: + * + * - Save FLG register + * - Clear I, D, and U flags in FLG register + * - Builds stack frame like (on the push-down, interrupt stack): + * + * sp -> PC bits 0-7 + * sp+1 -> PC bits 8-15 + * sp+2 -> FLG bits 0-7 + * sp+3 -> FLG (Bits 12-14) + PC (bits 16-19) + * + * - Sets IPL + * - Vectors to interrupt handler + * + ************************************************************************************/ + + .text +/* The unexpected interrupt vector */ + + m16c_vector _m16c_unexpected_isr, NR_IRQS + + /* Variable vectors */ + + m16c_vector _m16c_brk_isr, M16C_BRK_IRQ + m16c_vector _m16c_int3_isr, M16C_INT3_IRQ + m16c_vector _m16c_int5_isr, M16C_INT5_IRQ + m16c_vector _m16c_int4_isr, M16C_INT4_IRQ + m16c_vector _m16c_uart2bcd_isr, M16C_UART2BCD_IRQ + m16c_vector _m16c_dma0_isr, M16C_DMA0_IRQ + m16c_vector _m16c_dma1_isr, M16C_DMA1_IRQ + m16c_vector _m16c_keyinp_isr, M16C_KEYINP_IRQ + m16c_vector _m16c_adc_isr, M16C_ADC_IRQ + m16c_vector _m16c_uart2xmitnack2_isr, M16C_UARTXNAK_IRQ + m16c_vector _m16c_uart2rcvack2_isr, M16C_UARTRACK_IRQ + m16c_vector _m16c_uart0xmit_isr, M16C_UART0XMT_IRQ + m16c_vector _m16c_uart0rcv_isr, M16C_UART0RCV_IRQ + m16c_vector _m16c_uart1xmit_isr, M16C_UART1XMT_IRQ + m16c_vector _m16c_uart1rcv_isr, M16C_UART1RCV_IRQ + m16c_vector _m16c_tmra0_isr, M16C_TMRA0_IRQ + m16c_vector _m16c_tmra1_isr, M16C_TMRA1_IRQ + m16c_vector _m16c_tmra2_isr, M16C_TMRA2_IRQ + m16c_vector _m16c_tmra3_isr, M16C_TMRA3_IRQ + m16c_vector _m16c_tmra4_isr, M16C_TMRA4_IRQ + m16c_vector _m16c_tmrb0_isr, M16C_TMRB0_IRQ + m16c_vector _m16c_tmrb1_isr, M16C_TMRB1_IRQ + m16c_vector _m16c_tmrb2_isr, M16C_TMRB2_IRQ + m16c_vector _m16c_int0_isr, M16C_INT0_IRQ + m16c_vector _m16c_int1_isr, M16C_INT1_IRQ + +#ifdef CONFIG_M16C_SWINTS + m16c_vector _m16c_swint5_isr, M16C_SWINT5_IRQ + m16c_vector _m16c_swint6_isr, M16C_SWINT6_IRQ + m16c_vector _m16c_swint7_isr, M16C_SWINT7_IRQ + m16c_vector _m16c_swint31_isr, M16C_SWINT31_IRQ + m16c_vector _m16c_swint32_isr, M16C_SWINT32_IRQ + m16c_vector _m16c_swint33_isr, M16C_SWINT33_IRQ + m16c_vector _m16c_swint34_isr, M16C_SWINT34_IRQ + m16c_vector _m16c_swint35_isr, M16C_SWINT35_IRQ + m16c_vector _m16c_swint36_isr, M16C_SWINT36_IRQ + m16c_vector _m16c_swint37_isr, M16C_SWINT37_IRQ + m16c_vector _m16c_swint38_isr, M16C_SWINT38_IRQ + m16c_vector _m16c_swint39_isr, M16C_SWINT39_IRQ + m16c_vector _m16c_swint40_isr, M16C_SWINT40_IRQ + m16c_vector _m16c_swint41_isr, M16C_SWINT41_IRQ + m16c_vector _m16c_swint42_isr, M16C_SWINT42_IRQ + m16c_vector _m16c_swint43_isr, M16C_SWINT43_IRQ + m16c_vector _m16c_swint44_isr, M16C_SWINT44_IRQ + m16c_vector _m16c_swint45_isr, M16C_SWINT45_IRQ + m16c_vector _m16c_swint46_isr, M16C_SWINT46_IRQ + m16c_vector _m16c_swint47_isr, M16C_SWINT47_IRQ + m16c_vector _m16c_swint48_isr, M16C_SWINT48_IRQ + m16c_vector _m16c_swint49_isr, M16C_SWINT49_IRQ + m16c_vector _m16c_swint50_isr, M16C_SWINT50_IRQ + m16c_vector _m16c_swint51_isr, M16C_SWINT51_IRQ + m16c_vector _m16c_swint52_isr, M16C_SWINT52_IRQ + m16c_vector _m16c_swint53_isr, M16C_SWINT53_IRQ + m16c_vector _m16c_swint54_isr, M16C_SWINT54_IRQ + m16c_vector _m16c_swint55_isr, M16C_SWINT55_IRQ + m16c_vector _m16c_swint56_isr, M16C_SWINT56_IRQ + m16c_vector _m16c_swint57_isr, M16C_SWINT57_IRQ + m16c_vector _m16c_swint58_isr, M16C_SWINT58_IRQ + m16c_vector _m16c_swint59_isr, M16C_SWINT59_IRQ + m16c_vector _m16c_swint60_isr, M16C_SWINT60_IRQ + m16c_vector _m16c_swint61_isr, M16C_SWINT61_IRQ + m16c_vector _m16c_swint62_isr, M16C_SWINT62_IRQ + m16c_vector _m16c_swint63_isr, M16C_SWINT63_IRQ +#endif + +/* Fixed vectors */ + + m16c_vector _m16c_undefinst_irq, M16C_UNDEFINST_IRQ + m16c_vector _m16c_overflow_irq, M16C_OVERFLOW_IRQ + m16c_vector _m16c_brkinst_irq, M16C_BRK_IRQ + m16c_vector _m16c_addrmatch_irq, M16C_ADDRMATCH_IRQ + m16c_vector _m16c_wdog_irq, M16C_WDOG_IRQ + m16c_vector _m16c_nmi_irq, M16C_NMI_IRQ +#ifdef CONFIG_M16C_DEBUGGER + m16c_vector _m16c_sstep_irq, M16C_SSTEP_IRQ + m16c_vector _m16c_dbc_irq, M16C_DBC_IRQ +#endif + +/* At this point, the stack remains as it was on interrupt. The interrupt + * stack is selected, register bank 1 is selected and r1 holds the IRQ + * number. + */ + +_m16c_commonvector: + +/* At this point, the interrupt stack has 4 bytes of info on it. */ + +/* Save all registers on the interrupt stack */ + + fclr b /* Switch back to Bank 0 */ + pushm fb,sb,a1,a0,r3,r2,r1,r0 /* Save on interrupt stack */ + fset b /* Bank to bank 1 */ + +/* Save the user stack pointer on the interrupt stack */ + + fset u /* Switch to User stack */ + stc sp, r0 /* R0 = user stack pointer */ + fclr u /* Back to interrupt stack */ + push.w r0 /* Save user sp on isp */ + +/* Allow nested interrupts */ + +#ifdef M16C_INTERRUPT_IPL + fset i /* Enable interrupts */ + ldipl #M16C_INTERRUPT_IPL /* Set interrupt level */ +#endif + +/* Then call _up_doirq with r1=IRQ number, r2=address of context info. At this + * point, the interrupt stack holds the address of the last byte of the context + * info array + */ + + stc isp, r2 /* R2 = address of base of context info */ + jsr.a _up_doirq + +#ifdef M16C_INTERRUPT_IPL + fclr i /* Disable interrupts */ +#endif + +/* Upon return, r0 will hold address of the base of the new context info structure + * use for return. Most of the time this will be the same as the address passed to + * to _up_doirg above, but will differ if a context switch occurs during interrupt + * processing. + * + * Of the ISP to the end of the context array: + */ + + ldc r0, isp /* ISP = address of base of new context info */ + + /* Restore the user stack pointer */ + + pop.w r0 /* R0 = saved user stack pointer */ + fset u /* Switch to User stack */ + ldc r0, sp /* Restore the user stack pointer */ + fclr u /* Back to interrupt stack */ + +/* Recover all registers and return */ + + fclr b /* Switch back to Bank 0 */ + popm fb,sb,a1,a0,r3,r2,r1,r0 /* Recover registers */ + reit /* Return from interrupt */ + +/************************************************************************************ + * Name: int up_saveusercontext(uint32_t *regs) + * + * Description: + * Save the context of the calling function at the point of the return from the + * call. This basically a setjmp. + * + * Input Parameters: + * R1 = Address of register save array + * + * Returned Value: + * R0 = 0 on normal call; 1 on context switch + * + ************************************************************************************/ + + .globl _up_saveusercontext + .type _up_saveusercontext, #function + +_up_saveusercontext: + int #5 /* Execute S/W interrupt 5 */ + rts /* Then return with the correct value in r0 */ + +/* This the logic executes in response to S/W interrupt 5. The 'int 5' instruction + * will cause the following actions: + * + * - Save FLG register + * - Clear I, D, and U flags in FLG register + * - Builds stack frame like (on the push-down, interrupt stack): + * + * sp -> PC bits 0-7 + * sp+1 -> PC bits 8-15 + * sp+2 -> FLG bits 0-7 + * sp+3 -> FLG (Bits 12-14) + PC (bits 16-19) + * + * - Set IPL + * - Vectors to this S/W interrupt handler: + */ + +_m16c_contextsave: + +/* Save all registers on the interrupt stack */ + + mov.w #1, r0 /* Return 1 on context switch */ + pushm fb,sb,a1,a0,r3,r2,r1,r0 /* Save on interrupt stack */ + +/* Save the user stack pointer on the interrupt stack */ + + fset u /* Switch to User stack */ + stc sp, r0 /* R0 = user stack pointer */ + fclr u /* Back to interrupt stack */ + push.w r0 /* Save user sp on isp */ + +/* Then copy the stack content to the register context array pointed to by r1 */ + + stc isp, a0 /* A0 = address of base of context info */ + mov.w r1, a1 /* A1 = address of register context array */ + mov.b #0, r1h /* R1H = 4 MS of 20-bit source address */ + mov.w #XCPTCONTEXT_SIZE, r3 /* R3 = Number of bytes to transfer */ + smovf.b /* Copy ISP to near context array */ + +/* Then return zero to indicate a normal function call return */ + + add.w #(XCPTCONTEXT_SIZE - 4), sp /* Remove stuff from stack */ + mov.w #0, r0 /* Return zero */ + reit /* Return from interrupt */ + .size _up_saveusercontext, .-_up_saveusercontext + +/************************************************************************************ + * Name: void up_fullcontextrestore(uint32_t *regs) + * + * Description: + * Restore the context of the using the provided register save array. + * + * Input Parameters: + * R1 = Address of register save array + * + * Returned Value: + * None + * + ************************************************************************************/ + + .globl _up_fullcontextrestore + .type _up_fullcontextrestore, #function + +_up_fullcontextrestore: + int #32 /* Execute S/W interrupt 32 */ + rts /* and return */ + +/* This the logic executes in response to S/W interrupt 32. The 'int 32' instruction + * will cause the following actions: + * + * - Save FLG register + * - Clear I and D flags in FLG register (U is preserved) + * - Builds stack frame like (on the push-down, interrupt stack): + * + * sp -> PC bits 0-7 + * sp+1 -> PC bits 8-15 + * sp+2 -> FLG bits 0-7 + * sp+3 -> FLG (Bits 12-14) + PC (bits 16-19) + * + * - Set IPL + * - Vectors to this S/W interrupt handler: + */ + +_m16c_contextrestore: + +/* Set the USP to the beginning of the context save area */ + + ldc r1, sp /* USP = address of base of new context info */ + + /* Restore the user stack pointer */ + + fset b /* Switch to bank 1 */ + pop.w r0 /* R0 = saved user stack pointer */ + fclr b /* Back to bank 0 */ + +/* Recover all registers */ + + popm fb,sb,a1,a0,r3,r2,r1,r0 /* Restore from registers from user stack */ + +/* Set the USP and return */ + + fset b /* Switch to bank 1 */ + popm r1,r0 /* Recover the PC and flags */ + stc sp, r0 /* Set the correct USP */ + pushm r1,r0 /* Put the PC and flags */ + fclr b /* Back to bank 0 */ + +/* The return from interrupt */ + + reit /* Return from interrupt */ + .size _up_fullcontextrestore, .-_up_fullcontextrestore + .end diff --git a/arch/sh/src/sh1/Kconfig b/arch/sh/src/sh1/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f3002c37370143a43ea1fb08f8a682c481978891 --- /dev/null +++ b/arch/sh/src/sh1/Kconfig @@ -0,0 +1,70 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_SH1 +comment "SH-1 Configuration Options" + +menu "SH-1 Peripheral Selections" + +config SH1_DMAC0 + bool "DMAC0" + default n + +config SH1_DMAC1 + bool "DMAC1" + default n + +config SH1_DMAC2 + bool "DMAC2" + default n + +config SH1_DMAC3 + bool "DMAC3" + default n + +config SH1_ITU1 + bool "ITU2" + default n + +config SH1_ITU2 + bool "ITU2" + default n + +config SH1_ITU3 + bool "ITU3" + default n + +config SH1_ITU4 + bool "ITU4" + default n + +config SH1_SCI0 + bool "SCI0" + default n + select ARCH_HAVE_SCI0 + +config SH1_SCI1 + bool "SCI1" + default n + select ARCH_HAVE_SCI1 + +config SH1_PCU + bool "PCU" + default n + +config SH1_AD + bool "AD" + default n + +config SH1_WDT + bool "WDT" + default n + +config SH1_CMI + bool "CMI" + default n + +endmenu # SH-1 Peripheral Selections +endif diff --git a/arch/sh/src/sh1/Make.defs b/arch/sh/src/sh1/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..180034a72d26bf124d90e0df7f28e2305b2d6f42 --- /dev/null +++ b/arch/sh/src/sh1/Make.defs @@ -0,0 +1,61 @@ +############################################################################## +# arch/sh/src/sh1/Make.defs +# +# Copyright (C) 2008, 2009, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +HEAD_ASRC = sh1_head.S + +CMN_ASRCS = +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_lowputs.c +CMN_CSRCS += up_mdelay.c up_puts.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_stackframe.c up_udelay.c +CMN_CSRCS += up_unblocktask.c up_usestack.c + +CHIP_ASRCS = sh1_vector.S sh1_saveusercontext.S +CHIP_CSRCS = sh1_lowputc.c sh1_irq.c sh1_serial.c sh1_initialstate.c +CHIP_CSRCS += sh1_copystate.c sh1_dumpstate.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += sh1_timerisr.c +endif + +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += sh1_schedulesigaction.c sh1_sigdeliver.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += +endif + diff --git a/arch/sh/src/sh1/chip.h b/arch/sh/src/sh1/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..490b20973e8d9b6864c08dec100d609f4480604b --- /dev/null +++ b/arch/sh/src/sh1/chip.h @@ -0,0 +1,74 @@ +/************************************************************************************ + * arch/sh/src/sh1/chip.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_SH_SRC_SH1_CHIP_H +#define __ARCH_SH_SRC_SH1_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#ifdef CONFIG_ARCH_CHIP_SH7032 +# include "sh1_703x.h" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* Address of the saved user stack pointer */ + +#ifndef __ASSEMBLY__ +# if CONFIG_ARCH_INTERRUPTSTACK > 3 + extern uint32_t g_intstackbase; +# endif +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_SH_SRC_SH1_CHIP_H */ diff --git a/arch/sh/src/sh1/sh1_703x.h b/arch/sh/src/sh1/sh1_703x.h new file mode 100644 index 0000000000000000000000000000000000000000..87f2c1bcd1749d16d2714c403a19c71ab8f9e42d --- /dev/null +++ b/arch/sh/src/sh1/sh1_703x.h @@ -0,0 +1,475 @@ +/************************************************************************************ + * arch/sh/src/sh1/sh1_703x.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_SH_SRC_SH1_703X_H +#define __ARCH_SH_SRC_SH1_703X_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory-mapped register addresses *************************************************/ + +/* Serial Communications interface (SCI) */ + +#define SH1_SCI0_BASE (0x05fffec0) +#define SH1_SCI1_BASE (0x05fffec8) + +#define SH1_SCI_SMR_OFFSET (0) /* Serial Mode Register (8-bits wide) */ +#define SH1_SCI_BRR_OFFSET (1) /* Bit Rate Register (8-bits wide) */ +#define SH1_SCI_SCR_OFFSET (2) /* Serial Control Register (8-bits wide) */ +#define SH1_SCI_TDR_OFFSET (3) /* Transmit Data Register (8-bits wide) */ +#define SH1_SCI_SSR_OFFSET (4) /* Serial Status Register (8-bits wide) */ +#define SH1_SCI_RDR_OFFSET (5) /* Receive Data Register (8-bits wide) */ + +#define SH1_SCI0_SMR (SH1_SCI0_BASE+SH1_SCI_SMR_OFFSET) +#define SH1_SCI0_BRR (SH1_SCI0_BASE+SH1_SCI_BRR_OFFSET) +#define SH1_SCI0_SCR (SH1_SCI0_BASE+SH1_SCI_SCR_OFFSET) +#define SH1_SCI0_TDR (SH1_SCI0_BASE+SH1_SCI_TDR_OFFSET) +#define SH1_SCI0_SSR (SH1_SCI0_BASE+SH1_SCI_SSR_OFFSET) +#define SH1_SCI0_RDR (SH1_SCI0_BASE+SH1_SCI_RDR_OFFSET) + +#define SH1_SCI1_SMR (SH1_SCI1_BASE+SH1_SCI_SMR_OFFSET) +#define SH1_SCI1_BRR (SH1_SCI1_BASE+SH1_SCI_BRR_OFFSET) +#define SH1_SCI1_SCR (SH1_SCI1_BASE+SH1_SCI_SCR_OFFSET) +#define SH1_SCI1_TDR (SH1_SCI1_BASE+SH1_SCI_TDR_OFFSET) +#define SH1_SCI1_SSR (SH1_SCI1_BASE+SH1_SCI_SSR_OFFSET) +#define SH1_SCI1_RDR (SH1_SCI1_BASE+SH1_SCI_RDR_OFFSET) + +/* A/D */ + +#define SH1_AD_ADDRA (0x05fffee0) /* 16-bits wide */ +#define SH1_AD_DRAH (0x05fffee0) /* 8-bits wide */ +#define SH1_AD_DRAL (0x05fffee1) /* 8-bits wide */ +#define SH1_AD_DRB (0x05fffee2) /* 16-bits wide */ +#define SH1_AD_DRBH (0x05fffee2) /* 8-bits wide */ +#define SH1_AD_DRBL (0x05fffee3) /* 8-bits wide */ +#define SH1_AD_DRC (0x05fffee4) /* 16-bits wide */ +#define SH1_AD_DRCH (0x05fffee4) /* 8-bits wide */ +#define SH1_AD_DRCL (0x05fffee5) /* 8-bits wide */ +#define SH1_AD_DRD (0x05fffee6) /* 16-bits wide */ +#define SH1_AD_DRDH (0x05fffee6) /* 8-bits wide */ +#define SH1_AD_DRDL (0x05fffee7) /* 8-bits wide */ +#define SH1_AD_CSR (0x05fffee8) /* 8-bits wide */ +#define SH1_AD_CR (0x05fffee9) /* 8-bits wide */ + +/* Integrated Timer/Pulse Unit (ITU) */ + +/* ITU shared */ + +#define SH1_ITU_TSTR (0x05ffff00) /* 8-bits wide */ +#define SH1_ITU_TSNC (0x05ffff01) /* 16-bits wide */ +#define SH1_ITU_TMDR (0x05ffff02) /* 16-bits wide */ +#define SH1_ITU_TFCR (0x05ffff03) /* 16-bits wide */ + +/* ITU channel 0 */ + +#define SH1_ITU0_TCR (0x05ffff04) /* 8-bits wide */ +#define SH1_ITU0_TIOR (0x05ffff05) /* 8-bits wide */ +#define SH1_ITU0_TIER (0x05ffff06) /* 8-bits wide */ +#define SH1_ITU0_TSR (0x05ffff07) /* 8-bits wide */ +#define SH1_ITU0_TCNT (0x05ffff08) /* 16-bits wide */ +#define SH1_ITU0_GRA (0x05ffff0a) /* 16-bits wide */ +#define SH1_ITU0_GRB (0x05ffff0c) /* 16-bits wide */ + +/* ITU channel 1 */ + +#define SH1_ITU1_TCR (0x05ffff0e) /* 8-bits wide */ +#define SH1_ITU1_TIOR (0x05ffff0f) /* 8-bits wide */ +#define SH1_ITU1_TIER (0x05ffff10) /* 8-bits wide */ +#define SH1_ITU1_TSR (0x05ffff11) /* 8-bits wide */ +#define SH1_ITU1_TCNT (0x05ffff12) /* 16-bits wide */ +#define SH1_ITU1_GRA (0x05ffff14) /* 16-bits wide */ +#define SH1_ITU1_GRB (0x05ffff16) /* 16-bits wide */ + +/* ITU channel 2 */ + +#define SH1_ITU2_TCR (0x05ffff18) /* 8-bits wide */ +#define SH1_ITU2_TIOR (0x05ffff19) /* 8-bits wide */ +#define SH1_ITU2_TIER (0x05ffff1a) /* 8-bits wide */ +#define SH1_ITU2_TSR (0x05ffff1b) /* 8-bits wide */ +#define SH1_ITU2_TCNT (0x05ffff1c) /* 16-bits wide */ +#define SH1_ITU2_GRA (0x05ffff1e) /* 16-bits wide */ +#define SH1_ITU2_GRB (0x05ffff20) /* 16-bits wide */ + +/* ITU channel 3 */ + +#define SH1_ITU3_TCR (0x05ffff22) /* 8-bits wide */ +#define SH1_ITU3_TIOR (0x05ffff23) /* 8-bits wide */ +#define SH1_ITU3_TIER (0x05ffff24) /* 8-bits wide */ +#define SH1_ITU3_TSR (0x05ffff25) /* 8-bits wide */ +#define SH1_ITU3_TCNT (0x05ffff26) /* 16-bits wide */ +#define SH1_ITU3_GRA (0x05ffff28) /* 16-bits wide */ +#define SH1_ITU3_GRB (0x05ffff2a) /* 16-bits wide */ +#define SH1_ITU3_BRA (0x05ffff2c) /* 16-bits wide */ +#define SH1_ITU3_BRB3 (0x05ffff2e) /* 16-bits wide */ + +/* ITU channels 0-4 shared */ + +#define SH1_ITU_TOCR (0x05ffff31) /* 8-bits wide */ + +/* ITU channel 4 */ + +#define SH1_ITU4_TCR (0x05ffff32) /* 8-bits wide */ +#define SH1_ITU4_TIOR (0x05ffff33) /* 8-bits wide */ +#define SH1_ITU4_TIER (0x05ffff34) /* 8-bits wide */ +#define SH1_ITU4_TSR (0x05ffff35) /* 8-bits wide */ +#define SH1_ITU4_TCNT (0x05ffff36) /* 16-bits wide */ +#define SH1_ITU4_GRA (0x05ffff38) /* 16-bits wide */ +#define SH1_ITU4_GRB (0x05ffff3a) /* 16-bits wide */ +#define SH1_ITU4_BRA (0x05ffff3c) /* 16-bits wide */ +#define SH1_ITU4_BRB (0x05ffff3e) /* 16-bits wide */ + +/* DMA controller (DMAC) */ + +/* DMAC channels 0-3 shared */ + +#define SH1_DMAOR (0x05ffff48) /* 16-bits wide */ + +/* DMAC channel 0 */ + +#define SH1_DMA0_SAR0 (0x05ffff40) /* 32-bits wide */ +#define SH1_DMA0_DAR0 (0x05ffff44) /* 32-bits wide */ +#define SH1_DMA0_TCR0 (0x05ffff4a) /* 16-bits wide */ +#define SH1_DMA0_CHCR0 (0x05ffff4e) /* 16-bits wide */ + +/* DMAC channel 1 */ + +#define SH1_DMA1_SAR (0x05ffff50) /* 32-bits wide */ +#define SH1_DMA1_DAR (0x05ffff54) /* 32-bits wide */ +#define SH1_DMA1_TCR (0x05fffF5a) /* 16-bits wide */ +#define SH1_DMA1_CHCR (0x05ffff5e) /* 16-bits wide */ + +/* DMAC channel 2 */ + +#define SH1_DMA2_SAR (0x05ffff60) /* 32-bits wide */ +#define SH1_DMA2_DAR (0x05ffff64) /* 32-bits wide */ +#define SH1_DMA2_TCR (0x05fffF6a) /* 16-bits wide */ +#define SH1_DMA2_CHCR (0x05ffff6e) /* 16-bits wide */ + +/* DMAC channel 3 */ + +#define SH1_DMA3_SAR (0x05ffff70) /* 32-bits wide */ +#define SH1_DMA3_DAR (0x05ffff74) /* 32-bits wide */ +#define SH1_DMA3_TCR (0x05fffF7a) /* 16-bits wide */ +#define SH1_DMA3_CHCR (0x05ffff7e) /* 16-bits wide */ + +/* Interrupt Controller (INTC) */ + +#define SH1_INTC_IPRA (0x05ffff84) /* Interrupt priority register A (16-bits wide) */ +#define SH1_INTC_IPRB (0x05ffff86) /* Interrupt priority register B (16-bits wide) */ +#define SH1_INTC_IPRC (0x05ffff88) /* Interrupt priority register C (16-bits wide) */ +#define SH1_INTC_IPRD (0x05ffff8a) /* Interrupt priority register D (16-bits wide) */ +#define SH1_INTC_IPRE (0x05ffff8c) /* Interrupt priority register E (16-bits wide) */ +#define SH1_INTC_ICR (0x05ffff8e) /* Interrupt control register (16-bits wide) */ + +/* User Break Controller (UBC) */ + +#define SH1_UBC_BARH (0x05ffff90) /* 16-bits wide */ +#define SH1_UBC_BARL (0x05ffff92) /* 16-bits wide */ +#define SH1_UBC_BAMRH (0x05ffff94) /* 16-bits wide */ +#define SH1_UBC_BAMRL (0x05ffff96) /* 16-bits wide */ +#define SH1_UBC_BBR (0x05ffff98) /* 16-bits wide */ + +/* Bus State Controller (BSC) */ + +#define SH1_BSC_BCR (0x05ffffa0) /* 16-bits wide */ +#define SH1_BSC_WCR1 (0x05ffffa2) /* 16-bits wide */ +#define SH1_BSC_WCR2 (0x05ffffa4) /* 16-bits wide */ +#define SH1_BSC_WCR3 (0x05ffffa6) /* 16-bits wide */ +#define SH1_BSC_DCR (0x05ffffa8) /* 16-bits wide */ +#define SH1_BSC_PCR (0x05ffffaa) /* 16-bits wide */ +#define SH1_BSC_RCR (0x05ffffac) /* 16-bits wide */ +#define SH1_BSC_RTCSR (0x05ffffae) /* 16-bits wide */ +#define SH1_BSC_RTCNT (0x05ffffb0) /* 16-bits wide */ +#define SH1_BSC_RTCOR (0x05ffffb2) /* 16-bits wide */ + +/* Watchdog Timer (WDT) */ + +#define SH1_WDT_TCSR (0x05ffffb8) /* 8-bits wide */ +#define SH1_WDT_TCNT (0x05ffffb9) /* 8-bits wide */ +#define SH1_WDT_RSTCSR (0x05ffffbb) /* 8-bits wide */ + +/* Power down state */ + +#define SH1_PDT_SBYCR (0x05ffffbc) /* 8-bits wide */ + +/* Port A */ + +#define SH1_PORTA_DR (0x05ffffc0) /* 16-bits wide */ + +/* Port B */ + +#define SH1_PORTB_DR (0x05ffffc2) /* 16-bits wide */ + +/* Pin Function Controller (PFC) */ + +#define SH1_PFC_PAIOR (0x05ffffc4) /* Port B I/O register (16-bits wide) */ +#define SH1_PFC_PBIOR (0x05ffffc6) /* Port B I/O register (16-bits wide) */ +#define SH1_PFC_PACR1 (0x05ffffc8) /* Port A control register 1 (16-bits wide) */ +#define SH1_PFC_PACR2 (0x05ffffca) /* Port A control register 2 (16-bits wide) */ +#define SH1_PFC_PBCR1 (0x05ffffcc) /* Port B control register 1 (16-bits wide) */ +#define SH1_PFC_PBCR2 (0x05ffffce) /* Port B control register 2 )16-bits wide) */ + +/* Port C */ + +#define SH1_PORTC_DR (0x05ffffd0) /* 16-bits wide */ + +/* Pin Function Controller (PFC, cont'd) */ + +#define SH1_PFC_CASCR (0x05ffffee) /* 16-bits wide */ + +/* Timing Pattern Controller (TPC) */ + +#define SH1_TPC_TPMR (0x05fffff0) /* 16-bits wide */ +#define SH1_TPC_TPCR (0x05fffff1) /* 16-bits wide */ +#define SH1_TPC_NDERH (0x05fffff2) /* 16-bits wide */ +#define SH1_TPC_NDERL (0x05fffff3) /* 16-bits wide */ +#define SH1_TPC_NDRB0 (0x05fffff4) /* 8-bits wide */ +#define SH1_TPC_NDRA0 (0x05fffff5) /* 8-bits wide */ +#define SH1_TPC_NDRB1 (0x05fffff6) /* 8-bits wide */ +#define SH1_TPC_NDRA1 (0x05fffff7) /* 8-bits wide */ + +/* Register bit definitions *********************************************************/ + +/* Serial Communications interface (SCI) */ + +#define SH1_SCISMR_CKSMASK (0x03) /* Bit 0-1: Internal clock source */ +#define SH1_SCISMR_DIV1 (0x00) /* System clock (phi) */ +#define SH1_SCISMR_DIV4 (0x01) /* phi/4 */ +#define SH1_SCISMR_DIV16 (0x02) /* phi/16 */ +#define SH1_SCISMR_DIV64 (0x03) /* phi/64 */ +#define SH1_SCISMR_MP (0x04) /* Bit 2: Multiprocessor select */ +#define SH1_SCISMR_STOP (0x08) /* Bit 3: 0:One stop bit, 1:Two stop bits */ +#define SH1_SCISMR_OE (0x10) /* Bit 4: 0:Even parity, 1:Odd parity */ +#define SH1_SCISMR_PE (0x20) /* Bit 5: Parity enable */ +#define SH1_SCISMR_CHR (0x40) /* Bit 6: 0:8-bit data, 1:7-bit data */ +#define SH1_SCISMR_CA (0x80) /* Bit 7: 0:Asynchronous, 1:clocked synchronous */ + +#define SH1_SCISCR_CKEMASK (0x03) /* Bit 0-1: Internal clock source */ + /* Asynchronous mode: */ +#define SH1_SCISCR_AISIN (0x00) /* Internal clock, SCK pin used for input pin */ +#define SH1_SCISCR_AISOUT (0x01) /* Internal clock, SCK pin used for clock output */ +#define SH1_SCISCR_AXSIN1 (0x02) /* External clock, SCK pin used for clock input */ +#define SH1_SCISCR_AXSIN2 (0x03) /* External clock, SCK pin used for clock input */ + /* Synchronous mode: */ +#define SH1_SCISCR_SISOUT1 (0x00) /* Internal clock, SCK pin used for input pin */ +#define SH1_SCISCR_SISOUT2 (0x01) /* Internal clock, SCK pin used for clock output */ +#define SH1_SCISCR_SXSIN1 (0x02) /* External clock, SCK pin used for clock input */ +#define SH1_SCISCR_SXSIN2 (0x03) /* External clock, SCK pin used for clock input */ +#define SH1_SCISCR_TEIE (0x04) /* Bit 2: 1=Transmit end interrupt enable */ +#define SH1_SCISCR_MPIE (0x08) /* Bit 3: 1=Multiprocessor interrupt enable */ +#define SH1_SCISCR_RE (0x10) /* Bit 4: 1=Receiver enable */ +#define SH1_SCISCR_TE (0x20) /* Bit 5: 1=Transmitter enable */ +#define SH1_SCISCR_RIE (0x40) /* Bit 6: 1=Recieve-data-full interrupt enable */ +#define SH1_SCISCR_TIE (0x80) /* Bit 7: 1=Transmit-data-empty interrupt enable */ +#define SH1_SCISCR_ALLINTS (0xcc) + +#define SH1_SCISSR_MPBT (0x01) /* Bit 0: Multi-processor Bit in Transmit data */ +#define SH1_SCISSR_MPB (0x02) /* Bit 1: Multi-processor Bit in receive data */ +#define SH1_SCISSR_TEND (0x04) /* Bit 2: End of transmission */ +#define SH1_SCISSR_PER (0x08) /* Bit 3: Receive parity error */ +#define SH1_SCISSR_FER (0x10) /* Bit 4: Receive framing error */ +#define SH1_SCISSR_ORER (0x20) /* Bit 5: Receive overrun error */ +#define SH1_SCISSR_RDRF (0x40) /* Bit 6: RDR contains valid received data */ +#define SH1_SCISSR_TDRE (0x80) /* Bit 7: TDR does not contain valid transmit data */ + +/* Integrated Timer unit (ITU) */ + +#define SH1_ITUTSTR_STR0 (0x01) /* Bit 0: TCNT0 is counting */ +#define SH1_ITUTSTR_STR1 (0x02) /* Bit 1: TCNT1 is counting */ +#define SH1_ITUTSTR_STR2 (0x04) /* Bit 2: TCNT2 is counting */ +#define SH1_ITUTSTR_STR3 (0x08) /* Bit 3: TCNT3 is counting */ +#define SH1_ITUTSTR_STR4 (0x10) /* Bit 4: TCNT4 is counting */ + +#define SH1_ITUTSNC_SYNC0 (0x01) /* Bit 0: Channel 0 operates synchronously */ +#define SH1_ITUTSNC_SYNC1 (0x02) /* Bit 1: Channel 1 operates synchronously */ +#define SH1_ITUTSNC_SYNC2 (0x04) /* Bit 2: Channel 2 operates synchronously */ +#define SH1_ITUTSNC_SYNC3 (0x08) /* Bit 3: Channel 3 operates synchronously */ +#define SH1_ITUTSNC_SYNC4 (0x10) /* Bit 4: Channel 4 operates synchronously */ + +#define SH1_ITUTMDR_PWM0 (0x01) /* Bit 0: Channel 0 operated in PWM mode */ +#define SH1_ITUTMDR_PWM1 (0x02) /* Bit 1: Channel 1 operated in PWM mode */ +#define SH1_ITUTMDR_PWM2 (0x04) /* Bit 2: Channel 2 operated in PWM mode */ +#define SH1_ITUTMDR_PWM3 (0x08) /* Bit 3: Channel 3 operated in PWM mode */ +#define SH1_ITUTMDR_PWM4 (0x10) /* Bit 4: Channel 4 operated in PWM mode */ +#define SH1_ITUTMDR_FDIR (0x20) /* Bit 5: OVF set when TCNT2 overflows */ +#define SH1_ITUTMDR_MDF (0x40) /* Bit 6: Channel 2 operates in phase counting mode */ + +#define SH1_ITUTFCR_BFA3 (0x01) /* Bit 0: GRA3 & BRA3 operate in mode in channel 4 */ +#define SH1_ITUTFCR_BFB3 (0x02) /* Bit 1: GRB3 & BRB3 operate in mode in channel 4 */ +#define SH1_ITUTFCR_BFA4 (0x04) /* Bit 2: GRA4 & BRA4 operate in mode in channel 4 */ +#define SH1_ITUTFCR_BFB4 (0x08) /* Bit 3: GRB4 & BRB4 operate in mode in channel 4 */ +#define SH1_ITUTFCR_CMDMASK (0x30) /* Bit 4-5: Command */ +#define SH1_ITUTFCR_34NDEF (0x00) /* Channels 3/4 normal (default) */ +#define SH1_ITUTFCR_34NORM (0x10) /* Channels 3/4 normal */ +#define SH1_ITUTFCR_34CPWM (0x20) /* Channels 3/4 in complementary PWM mode*/ +#define SH1_ITUTFCR_34RSPWN (0x30) /* Channels 3/4 in reset-synchronized PWM mode */ + +#define SH1_ITUTOCR_OLS3 (0x01) /* Bit 0: 1=TIOCA3, A4 & B4 not inverted */ +#define SH1_ITUTOCR_OLS4 (0x02) /* Bit 1: 1=TIOCB3, XA4 & XB4 not inverted */ + +#define SH1_ITUTCR_TPSCMSK (0x07) /* Bits 0-2: Clock setup, internal/external, divider */ +#define SH1_ITUTCR_DIV1 (0x00) /* Internal clock (phi) */ +#define SH1_ITUTCR_DIV2 (0x01) /* phi / 2 */ +#define SH1_ITUTCR_DIV4 (0x02) /* phi / 4 */ +#define SH1_ITUTCR_DIV8 (0x03) /* phi / 8 */ +#define SH1_ITUTCR_TCLKA (0x04) /* External clock A (TCLKA) */ +#define SH1_ITUTCR_TCLKB (0x05) /* External clock B (TCLKB) */ +#define SH1_ITUTCR_TCLKC (0x06) /* External clock C (TCLKC) */ +#define SH1_ITUTCR_TCLKD (0x07) /* External clock D (TCLKD) */ +#define SH1_ITUTCR_CKEGMSK (0x18) /* Bits 3-4: External clock input edge selection */ +#define SH1_ITUTCR_RISING (0x00) /* Count rising edges */ +#define SH1_ITUTCR_FALLING (0x08) /* Count falling edges */ +#define SH1_ITUTCR_BOTH (0x10) /* Count both */ +#define SH1_ITUTCR_CCLRMSK (0x60) /* Bits 5-6: TCNT clear controls */ +#define SH1_ITUTCR_NCLR (0x00) /* TCNT not cleared */ +#define SH1_ITUTCR_CGRA (0x20) /* TCNT cleared by GRA */ +#define SH1_ITUTCR_CGRB (0x40) /* TCNT cleared by GRB */ +#define SH1_ITUTCR_CSYNC (0x60) /* Synchronized clear */ + +#define SH1_ITUTIOR_IOAMSK (0x07) /* Bits 0-3: GRA function */ +#define SH1_ITUTIOR_OCGRAD (0x00) /* GRA output comparator, disabled */ +#define SH1_ITUTIOR_OCGRA0 (0x01) /* GRA output comparator, 0 output at match */ +#define SH1_ITUTIOR_OCGRA1 (0x02) /* GRA output comparator, 1 output at match */ +#define SH1_ITUTIOR_OCATOG (0x03) /* GRA output comparator, output toggles at match */ +#define SH1_ITUTIOR_ICGRAR (0x04) /* GRA input capture, rising edge */ +#define SH1_ITUTIOR_ICGRAF (0x05) /* GRA input capture, falling edge */ +#define SH1_ITUTIOR_ICGRAB (0x06) /* GRA input capture, both edges */ +#define SH1_ITUTIOR_IOBMSK (0x70) /* Bits 4-6: GRB function */ +#define SH1_ITUTIOR_OCGRBD (0x00) /* GRB output comparator, disabled */ +#define SH1_ITUTIOR_OCGRB0 (0x10) /* GRB output comparator, 0 output at match */ +#define SH1_ITUTIOR_OCGRB1 (0x20) /* GRB output comparator, 1 output at match */ +#define SH1_ITUTIOR_OCBTOG (0x30) /* GRB output comparator, output toggles at match */ +#define SH1_ITUTIOR_ICGRBR (0x40) /* GRB input capture, rising edge */ +#define SH1_ITUTIOR_ICGRBF (0x50) /* GRB input capture, falling edge */ +#define SH1_ITUTIOR_ICGRBB (0x60) /* GRB input capture, both edges */ + +#define SH1_ITUTSR_IMFA (0x01) /* Bit 0: 0=Clearing condition, 1=setting confition */ +#define SH1_ITUTSR_IMFB (0x02) /* Bit 1: 0=Clearing condition, 1=setting confition */ +#define SH1_ITUTSR_OVF (0x04) /* Bit 2: 0=Clearing condition, 1=setting confition */ + +#define SH1_ITUTIER_IMIEA (0x01) /* Bit 0: Enables interrupt request from IMFA */ +#define SH1_ITUTIER_IMIEB (0x02) /* Bit 1: Enables interrupt request from IMFB */ +#define SH1_ITUTIER_OVIE (0x04) /* Bit 2: Enables interrupt request from OVR */ + +/* Interrupt Controller (INTC) */ + +#define SH1_IPRA_IRQ3MASK (0x000f) /* Bits 0-3: IRQ3 */ +#define SH1_IPRA_IRQ3SHIFT (0) +#define SH1_IPRA_IRQ2MASK (0x00f0) /* Bits 4-7: IRQ2 */ +#define SH1_IPRA_IRQ2SHIFT (4) +#define SH1_IPRA_IRQ1MASK (0x0f00) /* Bits 8-11: IRQ1 */ +#define SH1_IPRA_IRQ1SHIFT (8) +#define SH1_IPRA_IRQ0MASK (0xf000) /* Bits 12-15: IRQ0 */ +#define SH1_IPRA_IRQ0SHIFT (12) + +#define SH1_IPRB_IRQ7MASK (0x000f) /* Bits 0-3: IRQ7 */ +#define SH1_IPRB_IRQ7SHIFT (0) +#define SH1_IPRB_IRQ6MASK (0x00f0) /* Bits 4-7: IRQ6 */ +#define SH1_IPRB_IRQ6SHIFT (4) +#define SH1_IPRB_IRQ5MASK (0x0f00) /* Bits 8-11: IRQ5 */ +#define SH1_IPRB_IRQ5SHIFT (8) +#define SH1_IPRB_IRQ4MASK (0xf000) /* Bits 12-15: IRQ4 */ +#define SH1_IPRB_IRQ4SHIFT (12) + +#define SH1_IPRC_ITU1MASK (0x000f) /* Bits 0-3: ITU1 */ +#define SH1_IPRC_ITU1SHIFT (0) +#define SH1_IPRC_ITU0MASK (0x00f0) /* Bits 4-7: ITU0 */ +#define SH1_IPRC_ITU0SHIFT (4) +#define SH1_IPRC_DM23MASK (0x0f00) /* Bits 8-11: DMAC2,3 */ +#define SH1_IPRC_DM23SHIFT (8) +#define SH1_IPRC_DM01MASK (0xf000) /* Bits 12-15: DMAC0,1 */ +#define SH1_IPRC_DM01SHIFT (12) + +#define SH1_IPRD_SCI0MASK (0x000f) /* Bits 0-3: SCI0 */ +#define SH1_IPRD_SCI0SHIFT (0) +#define SH1_IPRD_ITU4MASK (0x00f0) /* Bits 4-7: ITU4 */ +#define SH1_IPRD_ITU4SHIFT (4) +#define SH1_IPRD_ITU3MASK (0x0f00) /* Bits 8-11: ITU3 */ +#define SH1_IPRD_ITU3SHIFT (8) +#define SH1_IPRD_ITU2MASK (0xf000) /* Bits 12-15: ITU2 */ +#define SH1_IPRD_ITU2SHIFT (12) + +#define SH1_IPRE_WDRFMASK (0x00f0) /* Bits 4-7: WDT, REF */ +#define SH1_IPRE_WDRFSHIFT (4) +#define SH1_IPRE_PRADMASK (0x0f00) /* Bits 8-11: PRT, A/D */ +#define SH1_IPRE_PRADSHIFT (8) +#define SH1_IPRE_SCI1MASK (0xf000) /* Bits 12-15: SCI1 */ +#define SH1_IPRE_SCI1SHIFT (12) + +#define SH1_ICR_IRQ7S (0x0001) /* Bits 0: Interrupt on falling edge of IRQ7 input */ +#define SH1_ICR_IRQ6S (0x0002) /* Bits 1: Interrupt on falling edge of IRQ6 input */ +#define SH1_ICR_IRQ5S (0x0004) /* Bits 2: Interrupt on falling edge of IRQ5 input */ +#define SH1_ICR_IRQ4S (0x0008) /* Bits 3: Interrupt on falling edge of IRQ4 input */ +#define SH1_ICR_IRQ3S (0x0010) /* Bits 4: Interrupt on falling edge of IRQ3 input */ +#define SH1_ICR_IRQ2S (0x0020) /* Bits 5: Interrupt on falling edge of IRQ2 input */ +#define SH1_ICR_IRQ1S (0x0040) /* Bits 6: Interrupt on falling edge of IRQ1 input */ +#define SH1_ICR_IRQ0S (0x0080) /* Bits 7: Interrupt on falling edge of IRQ0 input */ +#define SH1_ICR_NMIE (0x0100) /* Bits 8: Interupt on rising edge of NMI input */ +#define SH1_ICR_NMIL (0x8000) /* Bits 15: NMI input level high */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_SH_SRC_SH1_703X_H */ + + + + + + + + + + + + + diff --git a/arch/sh/src/sh1/sh1_copystate.c b/arch/sh/src/sh1/sh1_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..57fa2d463869126e8733d03102c468488fd739e4 --- /dev/null +++ b/arch/sh/src/sh1/sh1_copystate.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/sh/src/sh1/up_copystate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint32_t *dest, uint32_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/sh/src/sh1/sh1_dumpstate.c b/arch/sh/src/sh1/sh1_dumpstate.c new file mode 100644 index 0000000000000000000000000000000000000000..ad165c4d2c87cecc85f400d2b45193e108cab261 --- /dev/null +++ b/arch/sh/src/sh1/sh1_dumpstate.c @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_assert.c + * + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sh1_getsp + ****************************************************************************/ + +static inline uint32_t sh1_getsp(void) +{ + uint32_t sp; + + __asm__ __volatile__ + ( + "mov r15, %0\n\t" + : "=&z" (sp) + : + : "memory" + ); + return sp; +} + +/**************************************************************************** + * Name: sh1_stackdump + ****************************************************************************/ + +static void sh1_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t*)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: sh1_registerdump + ****************************************************************************/ + +static inline void sh1_registerdump(void) +{ + uint32_t *ptr = (uint32_t*)g_current_regs; + + /* Are user registers available from interrupt processing? */ + + if (ptr) + { + /* Yes.. dump the interrupt registers */ + + lldbg("PC: %08x SR=%08x\n", + ptr[REG_PC], ptr[REG_SR]); + + lldbg("PR: %08x GBR: %08x MACH: %08x MACL: %08x\n", + ptr[REG_PR], ptr[REG_GBR], ptr[REG_MACH], ptr[REG_MACL]); + + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 0, + ptr[REG_R0], ptr[REG_R1], ptr[REG_R2], ptr[REG_R3], + ptr[REG_R4], ptr[REG_R5], ptr[REG_R6], ptr[REG_R7]); + + lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 8, + ptr[REG_R8], ptr[REG_R9], ptr[REG_R10], ptr[REG_R11], + ptr[REG_R12], ptr[REG_R13], ptr[REG_R14], ptr[REG_R15]); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = sh1_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + sh1_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("sp: %08x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + sh1_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + sh1_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/sh/src/sh1/sh1_head.S b/arch/sh/src/sh1/sh1_head.S new file mode 100644 index 0000000000000000000000000000000000000000..9bb4efb1f5e17e6c4618b4d6fbc5ffda76d60f2d --- /dev/null +++ b/arch/sh/src/sh1/sh1_head.S @@ -0,0 +1,524 @@ +/***************************************************************************** + * arch/sh/src/sh1/sh1_head.S + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include /* NuttX configuration settings */ +#include /* Board-specific settings */ +#include /* IRQ definitons */ + +#include "chip.h" /* Chip-specific settings */ +#include "up_internal.h" +#include "up_arch.h" + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +/* This file holds the NuttX start logic that runs when the SH-1/US7032EVB1 + * is reset. This logic must be located in SRAM at 0x0a00:2000. On that + * platform, the entire PROM and the first 8Kb of SRAM are reserved for CMON. + */ + +/***************************************************************************** + * External references + *****************************************************************************/ + +/* Called functions */ + + .globl _up_lowsetup /* Early initialization of UART */ +#ifdef USE_EARLYSERIALINIT + .globl _up_earlyconsoleinit /* Early initialization of console driver */ +#endif +#ifdef CONFIG_ARCH_LEDS + .globl _board_autoled_initialize /* Boot LED setup */ +#endif +#ifdef CONFIG_DEBUG + .globl _up_lowputc /* Low-level debug output */ +#endif + .globl _os_start /* NuttX entry point */ + +/* Variables set up by the linker script */ + + .globl _sbss /* Start of BSS */ + .globl _ebss /* End of BSS */ + .globl _svect /* Start of the new vector location */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + .globl _eronly /* Where .data defaults are stored in FLASH */ + .global _sdata /* Start of .data in RAM */ + .globl _edata /* End of .data in RAM */ +#endif + +/* Interrupt handlers */ + + .globl _up_invalid_handler +#ifdef CONFIG_SH1_DMAC0 + .globl _up_dmac0_handler +#endif +#ifdef CONFIG_SH1_DMAC1 + .globl _up_dmac1_handler +#endif +#ifdef CONFIG_SH1_DMAC2 + .globl _up_dmac2_handler +#endif +#ifdef CONFIG_SH1_DMAC3 + .globl _up_dmac3_handler +#endif + .globl _up_imia0_handler + .globl _up_imib0_handler + .globl _up_ovi0_handler +#ifdef CONFIG_SH1_ITU1 + .globl _up_imia1_handler + .globl _up_imib1_handler + .globl _up_ovi1_handler +#endif +#ifdef CONFIG_SH1_ITU2 + .globl _up_imia2_handler + .globl _up_imib2_handler + .globl _up_ovi2_handler +#endif +#ifdef CONFIG_SH1_ITU3 + .globl _up_imia3_handler + .globl _up_imib3_handler + .globl _up_ovi3_handler +#endif +#ifdef CONFIG_SH1_ITU4 + .globl _up_imia4_handler + .globl _up_imib4_handler + .globl _up_ovi4_handler +#endif +#ifdef CONFIG_SH1_SCI0 + .globl _up_eri0_handler + .globl _up_rxi0_handler + .globl _up_txi0_handler + .globl _up_tei0_handler +#endif +#ifdef CONFIG_SH1_SCI1 + .globl _up_eri1_handler + .globl _up_rxi1_handler + .globl _up_txi1_handler + .globl _up_tei1_handler +#endif +#ifdef CONFIG_SH1_PCU + .globl _up_pei_handler +#endif +#ifdef CONFIG_SH1_AD + .globl _up_aditi_handler +#endif +#ifdef CONFIG_SH1_WDT + .globl _up_wdt_handler +#endif +#ifdef CONFIG_SH1_CMI + .globl _up_cmi_handler +#endif + +/***************************************************************************** + * Macros + *****************************************************************************/ + +/***************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. This macro will + * modify r0, r1, r2 and r14 + * + *****************************************************************************/ + + .macro showprogress, code +#ifdef CONFIG_DEBUG + mov.l .Llowputc, r0 /* Address of up_earlyconsoleinit */ + jsr @r0 /* Call it */ + mov #\code, r4 /* Delay slot */ +#endif + .endm + +/***************************************************************************** + * Vectors + *****************************************************************************/ + + .section .vects + +/***************************************************************************** + * Name: __vector_table + * + * Description: + * Interrupt vector table. The actual vectors are managed by CMON. For + * any non-zero settings in the following table, CMON will redirect interrupt + * handling to that function. + * + *****************************************************************************/ + + .globl __vector_table + .type __vector_table, %object +__vector_table: + /* All of the SH-1 common vectors are copied from the CMON vector + * area to here. As a result, CMON will continue to intercept these + * vectors. + */ + + .long __start /* 0-1: Power-on reset (hard, NMI high) PC & SP */ + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + .long __start /* 2-3: Manual reset (soft, NMI low) PC & SP */ + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 + + .rept SH1_NCMN_VECTORS-4 + .long _up_invalid_handler + .endr + + /* The remaining vectors are unique to the SH-1 703x family */ + +#ifdef CONFIG_SH1_DMAC0 + .long _up_dmac0_handler /* 72: DMAC0 DEI0 */ +#else + .long _up_invalid_handler /* 72: DMAC0 DEI0 */ +#endif + .long _up_invalid_handler /* 73: Reserved */ +#ifdef CONFIG_SH1_DMAC1 + .long _up_dmac1_handler /* 74: DMAC1 DEI1 */ +#else + .long _up_invalid_handler /* 74: DMAC1 DEI1 */ +#endif + .long _up_invalid_handler /* 75: Reserved */ +#ifdef CONFIG_SH1_DMAC2 + .long _up_dmac2_handler /* 76: DMAC2 DEI2 */ +#else + .long _up_invalid_handler /* 76: DMAC2 DEI2 */ +#endif + .long _up_invalid_handler /* 77: Reserved */ +#ifdef CONFIG_SH1_DMAC3 + .long _up_dmac3_handler /* 78: DMAC3 DEI3 */ +#else + .long _up_invalid_handler /* 78: DMAC3 DEI3 */ +#endif + .long _up_invalid_handler /* 79: Reserved */ + .long _up_imia0_handler /* 80: ITU0 IMIA0 */ + .long _up_imib0_handler /* 81: IMIB0 */ + .long _up_ovi0_handler /* 82: OVI0 */ + .long _up_invalid_handler /* 83: Reserved */ +#ifdef CONFIG_SH1_ITU1 + .long _up_imia1_handler /* 84: ITU1 IMIA1 */ + .long _up_imib1_handler /* 85: IMIB1 */ + .long _up_ovi1_handler /* 86: OVI1 */ +#else + .long _up_invalid_handler /* 84: ITU1 IMIA1 */ + .long _up_invalid_handler /* 85: IMIB1 */ + .long _up_invalid_handler /* 86: OVI1 */ +#endif + .long _up_invalid_handler /* 87: Reserved */ +#ifdef CONFIG_SH1_ITU2 + .long _up_imia2_handler /* 88: ITU2 IMIA2 */ + .long _up_imib2_handler /* 89: IMIB2 */ + .long _up_ovi2_handler /* 90: OVI2 */ +#else + .long _up_invalid_handler /* 88: ITU2 IMIA2 */ + .long _up_invalid_handler /* 89: IMIB2 */ + .long _up_invalid_handler /* 90: OVI2 */ +#endif + .long _up_invalid_handler /* 91: Reserved */ +#ifdef CONFIG_SH1_ITU3 + .long _up_imia3_handler /* 92: ITU3 IMIA3 */ + .long _up_imib3_handler /* 93: IMIB3 */ + .long _up_ovi3_handler /* 94: OVI3 */ +#else + .long _up_invalid_handler /* 92: ITU3 IMIA3 */ + .long _up_invalid_handler /* 93: IMIB3 */ + .long _up_invalid_handler /* 94: OVI3 */ +#endif + .long _up_invalid_handler /* 95: Reserved */ +#ifdef CONFIG_SH1_ITU4 + .long _up_imia4_handler /* 96: ITU4 IMIA4 */ + .long _up_imib4_handler /* 97: IMIB4 */ + .long _up_ovi4_handler /* 98: OVI4 */ +#else + .long _up_invalid_handler /* 96: ITU4 IMIA4 */ + .long _up_invalid_handler /* 97: IMIB4 */ + .long _up_invalid_handler /* 98: OVI4 */ +#endif + .long _up_invalid_handler /* 99: Reserved */ +#ifdef CONFIG_SH1_SCI0 + .long _up_eri0_handler /* 100: SCI0 ERI0 */ + .long _up_rxi0_handler /* 101: RxI0 */ + .long _up_txi0_handler /* 102: TxI0 */ + .long _up_tei0_handler /* 103: TEI0 */ +#else + .long _up_invalid_handler /* 100: SCI0 ERI0 */ + .long _up_invalid_handler /* 101: RxI0 */ + .long _up_invalid_handler /* 102: TxI0 */ + .long _up_invalid_handler /* 103: TEI0 */ +#endif +#ifdef CONFIG_SH1_SCI1 + .long _up_eri1_handler /* 104: SCI1 ERI1 */ + .long _up_rxi1_handler /* 105: RxI1 */ + .long _up_txi1_handler /* 106: TxI1 */ + .long _up_tei1_handler /* 107: TEI1 */ +#else + .long _up_invalid_handler /* 104: SCI1 ERI1 */ + .long _up_invalid_handler /* 105: RxI1 */ + .long _up_invalid_handler /* 106: TxI1 */ + .long _up_invalid_handler /* 107: TEI1 */ +#endif +#ifdef CONFIG_SH1_PCU + .long _up_pei_handler /* 108: Parity control unit PEI */ +#else + .long _up_invalid_handler /* 108: Parity control unit PEI */ +#endif +#ifdef CONFIG_SH1_AD + .long _up_aditi_handler /* 109: A/D ITI */ +#else + .long _up_invalid_handler /* 109: A/D ITI */ +#endif + .long _up_invalid_handler /* 110: Reserved */ + .long _up_invalid_handler /* 111: Reserved */ +#ifdef CONFIG_SH1_WDT + .long _up_wdt_handler /* 112: WDT ITI */ +#else + .long _up_invalid_handler /* 112: WDT ITI */ +#endif +#ifdef CONFIG_SH1_CMI + .long _up_cmi_handler /* 113: REF CMI */ +#else + .long _up_invalid_handler /* 113: REF CMI */ +#endif + .rept (SH1_LAST_VNDX-SH1_CMI_VNDX) /* 114-255: Reserved */ + .long _up_invalid_handler + .endr + .size __vector_table, . - __vector_table + +/***************************************************************************** + * Text + *****************************************************************************/ + + .section .reset + +/***************************************************************************** + * Name: __start + * + * Description: + * Reset entry point. This is the first function to execute when the + * processor is reset. It initializes hardware and then gives control to + * NuttX. Nearly all SH-1 resources have already been setup by CMON so all + * that is necessary for us to do here is setup the stack pointer and BSS. + * + *****************************************************************************/ + + .global __start + .type __start, #function + +__start: + /* Initialize stack pointer to the preallocated stack */ + mov.l .Lstack, r15 + + /* set up the bus controller for the EVB */ + + mov.l .Lwcr1, r0 + sub r1,r1 + mov.w r1, @r0 + + /* Configure the BSR to use /LBS, /HBS, /WR */ + + mov.l .Lbcr, r0 + mov.w .Lbas, r1 + bra __start0 + mov.w r1, @r0 + + .align 2 +.Lstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +.Lwcr1: + .long 0x5ffffa2 +.Lbcr: + .long 0x5ffffa0 +.Lbas: + .word 0x0800 + +__start0: + /* Copy the monitor vectors to a002000-a00211f */ + + mov #0, r0 /* R0: Monitor vector table at address 0 in PROM */ + mov.l .Lsvect, r1 /* R1: Redirected vector table in SRAM */ + mov.l .Lvectend, r3 /* R3: Copy only up to external interrupts */ +1: + mov.l @r0, r2 /* R2: Value from mnitor monitor vector table */ + mov.l r2, @r1 /* Write into SRAM vector table */ + add #4, r0 /* R0: Address of next vector to read from monitor vector table */ + add #4, r1 /* R1: Address of next vector to write to SRAM vector table */ + cmp/gt r0, r3 /* Copy only only up to external interrupts at */ + bt 1b /* Continue looping until all copied */ + nop /* Delay slot */ + + /* Update the VBR to show new adddress of vector table */ + + mov.l .Lsvect, r0 /* R0: Address of SRAM vector table */ + ldc r0, vbr /* Set VBR to start of SRAM vector table */ + + /* Initialize data segement */ + +#ifdef CONFIG_BOOT_RUNFROMFLASH + mov.l .Lsdata, r0 /* R0: Start of .data segment */ + mov.l .Ledata, r1 /* R1: End+1 of .data segment */ + mov.l .Leronly, r2 /* R2: Start of FLASH .data segment copy */ +2: + mov.l @r2, r3 /* R3: Next byte from FLASH copy */ + mov.l r3, @r0 /* Copy to .data */ + add #4, r2 /* R2: Address of next byte to read from FLASH */ + add #4, r0 /* R0: Address to write next byte to .data */ + cmp/gt r0, r1 /* End of .data? */ + bt 2b /* Loop until end of data */ + nop /* Delay slot */ +#endif + + /* Clear BSS */ + + mov.l .Lsbss, r0 /* R0: Start of BSS segment */ + mov.l .Lebss, r1 /* R1: End+1 of BSS segment */ + mov #0, r2 /* R2: Value = 0 */ +3: + mov.l r2, @r0 /* Clear the next word in BSS */ + add #4, r0 /* R0: Address of next byte to clear in BSS */ + cmp/ge r0, r1 /* End of BSS? */ + bt 3b /* Loop until the end of BSS */ + nop /* Delay slot */ + + /* Configure the uart so that we can get debug output as soon + * as possible. + */ + + mov.l .Llowsetup, r0 /* Address of up_lowsetup */ + jsr @r0 /* Call it */ + or r0, r0 /* Delay slot */ + + showprogress 'A' + + /* Perform early console initialization */ + +#ifdef USE_EARLYSERIALINIT + mov.l .Learlyconsole, r0 /* Address of up_earlyconsoleinit */ + jsr @r0 /* Call it */ + or r0, r0 /* Delay slot */ +#endif + + showprogress 'B' + + /* Call C++ constructors */ + +#ifdef CONFIG_CPLUSPLUS +# warning "No C++ support yet" + showprogress 'C' +#endif + showprogress '\n' + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + mov.l .Lledinit, r0 /* Address of board_autoled_initialize */ + jsr @r0 /* Call it */ + or r0, r0 /* Delay slot */ +#endif + + /* Then jump to NuttX entry */ + + mov.l .Losstart,r0 + jsr @r0 + or r0, r0 + + /* Shouldn't get here */ + + /* Call destructors -- never get here */ + +#ifdef CONFIG_CPLUSPLUS +# warning "No C++ support yet" +#endif + +4: nop + bra 4b + nop + + .align 2 +#ifdef CONFIG_BOOT_RUNFROMFLASH +.Leronly: + .long _eronly +.Lsdata: + .long _sdata +.Ledata: + .long _edata +#endif +.Lsbss: + .long _sbss +.Lebss: + .long _ebss +#ifdef USE_EARLYSERIALINIT +.Learlyconsole: + .long _up_earlyconsoleinit +#endif +.Llowsetup: + .long _up_lowsetup +#ifdef CONFIG_DEBUG +.Llowputc: + .long _up_lowputc +#endif +.Lledinit: + .long _board_autoled_initialize +.Losstart: + .long _os_start +.Lsvect: + .long _svect +.Lvectend: + .long ((4*SH1_NCMN_VECTORS)-1) + .size __start, .-__start + +/***************************************************************************** + * DATA + *****************************************************************************/ + + .section .data + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to the stack + * above. + */ + + .data + .align 4 + .globl _g_idle_topstack + .type _g_idle_topstack, object +_g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size _g_idle_topstack, .-_g_idle_topstack + + .end diff --git a/arch/sh/src/sh1/sh1_initialstate.c b/arch/sh/src/sh1/sh1_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..984829a370d3fb8f34ba4209028dfe0ffc365cfa --- /dev/null +++ b/arch/sh/src/sh1/sh1_initialstate.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_initialstate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsr + ****************************************************************************/ + +static inline irqstate_t up_getsr(void) +{ + irqstate_t flags; + + __asm__ __volatile__ + ( + "stc sr, %0\n\t" + : "=&z" (flags) + : + : "memory" + ); + return flags; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Set the initial stack pointer to the "base" of the allocated stack */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32_t)tcb->start; + + /* Set supervisor- or user-mode, depending on how NuttX is configured and + * what kind of thread is being started. Disable FIQs in any event + * + * If the kernel build is not selected, then all threads run in + * supervisor-mode. + */ + +#ifdef CONFIG_BUILD_KERNEL +# error "Missing logic for the CONFIG_BUILD_KERNEL build" +#endif + + /* Enable or disable interrupts, based on user configuration */ + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_SR] = up_getsr() | 0x000000f0; +#else + xcp->regs[REG_SR] = up_getsr() & ~0x000000f0; +#endif +} diff --git a/arch/sh/src/sh1/sh1_irq.c b/arch/sh/src/sh1/sh1_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..58514a257444c385621964b5dea0d6997c56f5d6 --- /dev/null +++ b/arch/sh/src/sh1/sh1_irq.c @@ -0,0 +1,274 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_irq.c + * + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "chip.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * set interrupt priority + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +void up_prioritize_irq(int irq, int priority) +{ + uint16_t mask; + uint16_t reg16; + uint32_t reg; + int shift; + +#ifdef CONFIG_DEBUG + if ((unsigned) irq > NR_IRQS || (unsigned)priority > 15) + { + dbg("Invalid parameters\n"); + return; + } +#endif + + /* Get the register to set, the mask for the bits to be set, and + * the shift value to position the bits in the register. + */ + + switch (irq) + { +#if 0 /* Not yet supported */ + case SH1_IRQ0_IRQ: + mask = SH1_IPRA_IRQ0MASK; + shift = SH1_IPRA_IRQ0SHIFT; + goto ipra; + + case SH1_IRQ1_IRQ: + mask = SH1_IPRA_IRQ1MASK; + shift = SH1_IPRA_IRQ1SHIFT; + goto ipra; + + case SH1_IRQ2_IRQ: + mask = SH1_IPRA_IRQ2MASK; + shift = SH1_IPRA_IRQ2SHIFT; + goto ipra; + + case SH1_IRQ3_IRQ: + mask = SH1_IPRA_IRQ3MASK; + shift = SH1_IPRA_IRQ3SHIFT; + goto ipra; + ipra: + reg = SH1_INTC_IPRA; + break; + + case SH1_IRQ4_IRQ: + mask = SH1_IPRB_IRQ4MASK; + shift = SH1_IPRB_IRQ4SHIFT; + goto iprb; + + case SH1_IRQ5_IRQ: + mask = SH1_IPRB_IRQ5MASK; + shift = SH1_IPRB_IRQ5SHIFT; + goto iprb; + + case SH1_IRQ6_IRQ: + mask = SH1_IPRB_IRQ6MASK; + shift = SH1_IPRB_IRQ6SHIFT; + goto iprb; + + case SH1_IRQ7_IRQ: + mask = SH1_IPRB_IRQ7MASK; + shift = SH1_IPRB_IRQ7SHIFT; + goto iprb; + iprb: + reg = SH1_INTC_IPRB; + break; +#endif + +#if defined(CONFIG_SH1_DMAC0) || defined(CONFIG_SH1_DMAC1) + case SH1_DEI0_IRQ: + case SH1_DEI1_IRQ: + mask = SH1_IPRC_DM01MASK; + shift = SH1_IPRC_DM01SHIFT; + goto iprc; +#endif + +#if defined(CONFIG_SH1_DMAC2) || defined(CONFIG_SH1_DMAC3) + case SH1_DEI2_IRQ: + case SH1_DEI3_IRQ: + mask = SH1_IPRC_DM23MASK; + shift = SH1_IPRC_DM23SHIFT; + goto iprc; +#endif + +#ifdef CONFIG_SH1_ITU1 + case SH1_IMIA1_IRQ: + case SH1_IMIB1_IRQ: + case SH1_OVI1_IRQ: + mask = SH1_IPRC_ITU1MASK; + shift = SH1_IPRC_ITU1SHIFT; + goto iprc; +#endif + + case SH1_IMIA0_IRQ: + case SH1_IMIB0_IRQ: + case SH1_OVI0_IRQ: + mask = SH1_IPRC_ITU0MASK; + shift = SH1_IPRC_ITU0SHIFT; + goto iprc; + iprc: + reg = SH1_INTC_IPRC; + break; + +#if defined(CONFIG_SH1_ITU2) || defined(CONFIG_SH1_ITU3) || \ + defined(CONFIG_SH1_ITU4) || defined(CONFIG_SH1_SCI0) +#ifdef CONFIG_SH1_ITU2 + case SH1_IMIA2_IRQ: + case SH1_IMIB2_IRQ: + case SH1_OVI2_IRQ: + mask = SH1_IPRD_ITU2MASK; + shift = SH1_IPRD_ITU2SHIFT; + goto iprd; +#endif +#ifdef CONFIG_SH1_ITU3 + case SH1_IMIA3_IRQ: + case SH1_IMIB3_IRQ: + case SH1_OVI3_IRQ: + mask = SH1_IPRD_ITU3MASK; + shift = SH1_IPRD_ITU3SHIFT; + goto iprd; +#endif +#ifdef CONFIG_SH1_ITU4 + case SH1_IMIA4_IRQ: + case SH1_IMIB4_IRQ: + case SH1_OVI4_IRQ: + mask = SH1_IPRD_ITU4MASK; + shift = SH1_IPRD_ITU4SHIFT; + goto iprd; +#endif +#ifdef CONFIG_SH1_SCI0 + case SH1_ERI0_IRQ: + case SH1_RXI0_IRQ: + case SH1_TXI0_IRQ: + case SH1_TEI0_IRQ: + mask = SH1_IPRD_SCI0MASK; + shift = SH1_IPRD_SCI0SHIFT; + goto iprd; +#endif + iprd: + reg = SH1_INTC_IPRD; + break; +#endif + +#if defined(CONFIG_SH1_SCI1) || defined(CONFIG_SH1_PCU) || \ + defined(CONFIG_SH1_AD) || defined(CONFIG_SH1_WDT) || defined(CONFIG_SH1_CMI) +#ifdef CONFIG_SH1_SCI1 + case SH1_ERI1_IRQ: + case SH1_RXI1_IRQ: + case SH1_TXI1_IRQ: + case SH1_TEI1_IRQ: + mask = SH1_IPRE_SCI1MASK; + shift = SH1_IPRE_SCI1SHIFT; + goto ipre; +#endif +#if defined(CONFIG_SH1_PCU) || defined(CONFIG_SH1_AD) + case SH1_PEI_IRQ: + case SH1_ADITI_IRQ: + mask = SH1_IPRE_PRADMASK; + shift = SH1_IPRE_PRADSHIFT; + goto ipre; +#endif +#if defined(CONFIG_SH1_WDT) || defined(CONFIG_SH1_CMI) + case SH1_WDTITI_IRQ: + case SH1_CMI_IRQ: + mask = SH1_IPRE_WDRFMASK; + shift = SH1_IPRE_WDRFSHIFT; + goto ipre; +#endif + ipre: + reg = SH1_INTC_IPRE; + break; +#endif + + default: + dbg("Invalid irq=%d\n", irq); + return; + } + + /* Then set the priority bits */ + + reg16 = getreg16(reg); + reg16 &= ~mask; + reg16 |= (priority << shift); + putreg16(reg16, reg); +} +#endif /* CONFIG_ARCH_IRQPRIO */ diff --git a/arch/sh/src/sh1/sh1_lowputc.c b/arch/sh/src/sh1/sh1_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..8b423b75b8f0030ab6264e53e980c55d83662490 --- /dev/null +++ b/arch/sh/src/sh1/sh1_lowputc.c @@ -0,0 +1,265 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_lowputc.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration **********************************************************/ + +/* Is there a serial console? */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) && defined(CONFIG_SH1_SCI0) +# define HAVE_CONSOLE 1 +# undef CONFIG_SCI1_SERIAL_CONSOLE +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) && defined(CONFIG_SH1_SCI1) +# define HAVE_CONSOLE 1 +# undef CONFIG_SCI0_SERIAL_CONSOLE +#else +# if defined(CONFIG_SCI0_SERIAL_CONSOLE) || defined(CONFIG_SCI1_SERIAL_CONSOLE) +# error "Serial console selected, but corresponding SCI not enabled" +# endif +# undef HAVE_CONSOLE +#endif + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) +# define SH1_SCI_BASE SH1_SCI0_BASE +# define SH1_SCI_BAUD CONFIG_SCI0_BAUD +# define SH1_SCI_BITS CONFIG_SCI0_BITS +# define SH1_SCI_PARITY CONFIG_SCI0_PARITY +# define SH1_SCI_2STOP CONFIG_SCI0_2STOP +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) +# define SH1_SCI_BASE SH1_SCI1_BASE +# define SH1_SCI_BAUD CONFIG_SCI1_BAUD +# define SH1_SCI_BITS CONFIG_SCI1_BITS +# define SH1_SCI_PARITY CONFIG_SCI1_PARITY +# define SH1_SCI_2STOP CONFIG_SCI1_2STOP +#else +# error "No CONFIG_SCIn_SERIAL_CONSOLE Setting" +#endif + +/* Get mode setting */ + +#if SH1_SCI_BITS == 7 +# define SH1_SMR_MODE SH1_SCISMR_CHR +#elif SH1_SCI_BITS == 8 +# define SH1_SMR_MODE (0) +#else +# error "Number of bits not supported" +#endif + +#if SH1_SCI_PARITY == 0 +# define SH1_SMR_PARITY (0) +#elif SH1_SCI_PARITY == 1 +# define SH1_SMR_PARITY (SH1_SCISMR_PE|SH1_SCISMR_OE) +#elif SH1_SCI_PARITY == 2 +# define SH1_SMR_PARITY SH1_SCISMR_PE +#else +# error "Invalid parity selection" +#endif + +#if SH1_SCI_2STOP != 0 +# define SH1_SMR_STOP SH1_SCISMR_STOP +#else +# define SH1_SMR_STOP (0) +#endif + +/* The full SMR setting also includes internal clocking with no divisor, + * aysnchronous operation and multiprocessor disabled: + */ + +#define SH1_SMR_VALUE (SH1_SMR_MODE|SH1_SMR_PARITY|SH1_SMR_STOP) + +/* Clocking ***************************************************************/ + +/* The calculation of the BRR to achieve the desired BAUD is given by the + * following formula: + * + * brr = (f/(64*2**(2n-1)*b))-1 + * + * Where: + * + * b = bit rate + * f = frequency (Hz) + * n = divider setting (0, 1, 2, 3) + * + * For n == 0, this simplifies to: + * + * brr = (f/(32*b))-1 + * + * For example, if the processor is clocked at 10 MHz and 9600 is the + * desired BAUD: + * + * brr = 10,000,000 / (32 * 9600) - 1 = 31.552 (or 32 after rounding) + */ + +#define SH1_DIVISOR (32 * SH1_SCI_BAUD) +#define SH1_BRR (((SH1_CLOCK + (SH1_DIVISOR/2))/SH1_DIVISOR)-1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return TRUE of the Transmit Data Register is empty + * + ****************************************************************************/ + +#ifdef HAVE_CONSOLE +static inline int up_txready(void) +{ + /* Check the TDRE bit in the SSR. 1=TDR is empty */ + + return ((getreg8(SH1_SCI_BASE + SH1_SCI_SSR_OFFSET) & SH1_SCISSR_TDRE) != 0); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + uint8_t ssr; + + /* Wait until the TDR is avaible */ + + while (!up_txready()); + + /* Write the data to the TDR */ + + putreg8(ch, SH1_SCI_BASE + SH1_SCI_TDR_OFFSET); + + /* Clear the TDRE bit in the SSR */ + + ssr = getreg8(SH1_SCI_BASE + SH1_SCI_SSR_OFFSET); + ssr &= ~SH1_SCISSR_TDRE; + putreg8(ssr, SH1_SCI_BASE + SH1_SCI_SSR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void up_lowsetup(void) +{ +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_SCI_CONFIG) + uint8_t scr; + + /* Disable the transmitter and receiver */ + + scr = getreg8(SH1_SCI_BASE + SH1_SCI_SCR_OFFSET); + scr &= ~(SH1_SCISCR_TE | SH1_SCISCR_RE); + putreg8(scr, SH1_SCI_BASE + SH1_SCI_SCR_OFFSET); + + /* Set communication to be asynchronous with the configured number of data + * bits, parity, and stop bits. Use the internal clock (undivided) + */ + + putreg8(SH1_SMR_VALUE, SH1_SCI_BASE + SH1_SCI_SMR_OFFSET); + + /* Set the baud based on the configured console baud and configured + * system clock. + */ + + putreg8(SH1_BRR, SH1_SCI_BASE + SH1_SCI_BRR_OFFSET); + + /* Select the internal clock source as input */ + + scr &= ~SH1_SCISCR_CKEMASK; + putreg8(scr, SH1_SCI_BASE + SH1_SCI_SCR_OFFSET); + + /* Wait a bit for the clocking to settle */ + + up_udelay(100); + + /* Then enable the transmitter and reciever */ + + scr |= (SH1_SCISCR_TE | SH1_SCISCR_RE); + putreg8(scr, SH1_SCI_BASE + SH1_SCI_SCR_OFFSET); +#endif +} diff --git a/arch/sh/src/sh1/sh1_saveusercontext.S b/arch/sh/src/sh1/sh1_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..8084e5bd0d8ccee59ed364d93abfc767c5de2bdd --- /dev/null +++ b/arch/sh/src/sh1/sh1_saveusercontext.S @@ -0,0 +1,121 @@ +/************************************************************************** + * arch/sh/src/sh1/sh1_saveusercontext.S + * + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/************************************************************************** + * Private Data + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_saveusercontext + **************************************************************************/ + + .text + .globl _up_saveusercontext + .type _up_saveusercontext, function +_up_saveusercontext: + + /* On entry, R4 contains a reference to the register save structure + * to populate. + * + * Re-position to the end of the structure (+4_ so that we can use + * auto decrement + */ + + add #(XCPTCONTEXT_SIZE), r4 /* R4: Address of last entry + 4 */ + + /* Save the necessary registers */ + + stc sr, r0 /* Get and save the SR */ + mov.l r0, @-r4 + sts.l pr, @-r4 /* The return address is the restore PC */ + add #-(7*4), r4 /* Skip over r4, r7-r1. R4 points at R1 storage */ + + /* Save a nonzero value for R0 in the register save area. This will + * will be the apparent return value when a context switch back to + * this thread is performed. + */ + + mov #1, r0 /* Save R0=1 (return value) */ + mov.l r0, @-r4 + add #-(2*4), r4 /* Skip over mach and macl. R4 points at R15 storage. */ + mov.l r15, @-r4 /* SP */ + stc.l gbr, @-r4 /* GBR & PR */ + sts.l pr, @-r4 + + mov.l r14, @-r4 /* R14-R8 */ + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + + /* And return zero */ + + rts + mov #0, r0 + .size up_saveusercontext, . - up_saveusercontext + .end diff --git a/arch/sh/src/sh1/sh1_schedulesigaction.c b/arch/sh/src/sh1/sh1_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..4c6e7c16595cd8d5cba63d37dfac39ec7ef5566d --- /dev/null +++ b/arch/sh/src/sh1/sh1_schedulesigaction.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_schedulesigaction.c + * + * Copyright (C) 2008-2010, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Funictions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the + * interrupted task is the same as the one that + * must receive the signal, then we will have to modify + * the return state as well as the state in the TCB. + */ + + else + { + /* Save the return PC and SR and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = g_current_regs[REG_PC]; + tcb->xcp.saved_sr = g_current_regs[REG_SR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_PC] = (uint32_t)up_sigdeliver; + g_current_regs[REG_SR] |= 0x000000f0; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_copystate(tcb->xcp.regs, g_current_regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return PC and SR and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_sr = tcb->xcp.regs[REG_SR]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_SR] |= 0x000000f0 ; + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/sh/src/sh1/sh1_serial.c b/arch/sh/src/sh1/sh1_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..44c9cf8a93409e59f9a3dde7a5936f41646c8e8c --- /dev/null +++ b/arch/sh/src/sh1/sh1_serial.c @@ -0,0 +1,962 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_serial.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* Are there any SCIs? */ + +#if !defined(CONFIG_SH1_SCI0) && !defined(CONFIG_SH1_SCI1) +# ifdef USE_SERIALDRIVER +# error "Serial driver selected, but SCIs not enabled" +# undef USE_SERIALDRIVER +# endif +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) && defined(CONFIG_SH1_SCI0) +# define HAVE_CONSOLE 1 +# undef CONFIG_SCI1_SERIAL_CONSOLE +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) && defined(CONFIG_SH1_SCI1) +# define HAVE_CONSOLE 1 +# undef CONFIG_SCI0_SERIAL_CONSOLE +#else +# if defined(CONFIG_SCI0_SERIAL_CONSOLE) || defined(CONFIG_SCI1_SERIAL_CONSOLE) +# error "Serial console selected, but corresponding SCI not enabled" +# endif +# undef HAVE_CONSOLE +# undef CONFIG_SCI0_SERIAL_CONSOLE +# undef CONFIG_SCI1_SERIAL_CONSOLE +#endif + +#ifdef USE_SERIALDRIVER + +/* Which SCI with be tty0/console and which tty1? */ + +/* CONFIG_SCI0_SERIAL_CONSOLE (implies CONFIG_SH1_SCI0 also defined) */ + +#if defined(CONFIG_SCI0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci0port /* SCI0 is console */ +# define TTYS0_DEV g_sci0port /* SCI0 is tty0 */ +# ifdef CONFIG_SH1_SCI1 +# define TTYS1_DEV g_sci1port /* SCI1 is tty1 */ +# else +# undef TTYS1_DEV +# endif + +/* CONFIG_SCI1_SERIAL_CONSOLE (implies CONFIG_SH1_SCI1 also defined) */ + +#elif defined(CONFIG_SCI1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_sci1port /* SCI1 is console */ +# define TTYS0_DEV g_sci1port /* SCI1 is tty0 */ +# ifdef CONFIG_SH1_SCI0 +# define TTYS1_DEV g_sci0port /* SCI0 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif + +/* No console, at least one of CONFIG_SH1_SCI0 and CONFIG_SH1_SCI1 defined */ + +#elif defined(CONFIG_SH1_SCI0) +# undef CONSOLE_DEV /* No console */ +# define TTYS0_DEV g_sci0port /* SCI0 is tty0 */ +# ifdef CONFIG_SH1_SCI1 +# define TTYS1_DEV g_sci1port /* SCI1 is tty1 */ +# else +# undef TTYS1_DEV /* No tty1 */ +# endif + +/* Otherwise, there is no console and only CONFIG_SH1_SCI1 is defined */ + +#else +# undef CONSOLE_DEV /* No console */ +# define TTYS0_DEV g_sci1port /* SCI1 is tty0 */ +# undef TTYS1_DEV /* No tty1 */ +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uint32_t scibase; /* Base address of SCI registers */ + uint32_t baud; /* Configured baud */ + volatile uint8_t scr; /* Saved SCR value */ + volatile uint8_t ssr; /* Saved SR value (only used during interrupt processing) */ + uint8_t irq; /* Base IRQ associated with this SCI */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context); +static int up_receive(struct uart_dev_s *dev, uint32_t *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct uart_ops_s g_sci_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txready, +}; + +/* I/O buffers */ + +#ifdef CONFIG_SH1_SCI0 +static char g_sci0rxbuffer[CONFIG_SCI0_RXBUFSIZE]; +static char g_sci0txbuffer[CONFIG_SCI0_TXBUFSIZE]; +#endif +#ifdef CONFIG_SH1_SCI1 +static char g_sci1rxbuffer[CONFIG_SCI1_RXBUFSIZE]; +static char g_sci1txbuffer[CONFIG_SCI1_TXBUFSIZE]; +#endif + +/* This describes the state of the SH1 SCI0 port. */ + +#ifdef CONFIG_SH1_SCI0 +static struct up_dev_s g_sci0priv = +{ + .scibase = SH1_SCI0_BASE, + .baud = CONFIG_SCI0_BAUD, + .irq = SH1_SCI0_IRQBASE, + .parity = CONFIG_SCI0_PARITY, + .bits = CONFIG_SCI0_BITS, + .stopbits2 = CONFIG_SCI0_2STOP, +}; + +static uart_dev_t g_sci0port = +{ + .recv = + { + .size = CONFIG_SCI0_RXBUFSIZE, + .buffer = g_sci0rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI0_TXBUFSIZE, + .buffer = g_sci0txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci0priv, +}; +#endif + +/* This describes the state of the SH1 SCI1 port. */ + +#ifdef CONFIG_SH1_SCI1 +static struct up_dev_s g_sci1priv = +{ + .scibase = SH1_SCI1_BASE, + .baud = CONFIG_SCI1_BAUD, + .irq = SH1_SCI1_IRQBASE, + .parity = CONFIG_SCI1_PARITY, + .bits = CONFIG_SCI1_BITS, + .stopbits2 = CONFIG_SCI1_2STOP, +}; + +static uart_dev_t g_sci1port = +{ + .recv = + { + .size = CONFIG_SCI1_RXBUFSIZE, + .buffer = g_sci1rxbuffer, + }, + .xmit = + { + .size = CONFIG_SCI1_TXBUFSIZE, + .buffer = g_sci1txbuffer, + }, + .ops = &g_sci_ops, + .priv = &g_sci1priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg8(priv->scibase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->scibase + offset); +} + +/**************************************************************************** + * Name: up_disablesciint + ****************************************************************************/ + +static inline void up_disablesciint(struct up_dev_s *priv, uint8_t *scr) +{ + /* Return a copy of the current scr settings */ + + if (scr) + { + *scr = priv->scr; + } + + /* The disable all interrupts */ + + priv->scr &= ~SH1_SCISCR_ALLINTS; + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); +} + +/**************************************************************************** + * Name: up_restoresciint + ****************************************************************************/ + +static inline void up_restoresciint(struct up_dev_s *priv, uint8_t scr) +{ + /* Set the interrupt bits in the scr value */ + + priv->scr &= ~SH1_SCISCR_ALLINTS; + priv->scr |= (scr & SH1_SCISCR_ALLINTS); + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); +} + +/**************************************************************************** + * Name: up_waittxready + ****************************************************************************/ + +#ifdef HAVE_CONSOLE +static inline void up_waittxready(struct up_dev_s *priv) +{ + int tmp; + + /* Limit how long we will wait for the TDR empty condition */ + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + /* Check if the TDR is empty. The TDR becomes empty when: (1) the + * the chip is reset or enters standby mode, (2) the TE bit in the SCR + * is cleared, or (3) the current TDR contents are loaded in the TSR so + * that new data can be written in the TDR. + */ + + if ((up_serialin(priv, SH1_SCI_SSR_OFFSET) & SH1_SCISSR_TDRE) != 0) + { + /* The TDR is empty... return */ + break; + } + } +} +#endif + +/**************************************************************************** + * Name: up_setbrr + * + * Description: + * Calculate the correct value for the BRR given the configured frequency + * and the desired BAUD settings. + * + ****************************************************************************/ + +static inline void up_setbrr(struct up_dev_s *priv, unsigned int baud) +{ + /* The calculation of the BRR to achieve the desired BAUD is given by the + * following formula: + * + * brr = (f/(64*2**(2n-1)*b))-1 + * + * Where: + * + * b = bit rate + * f = frequency (Hz) + * n = divider setting (0, 1, 2, 3) + * + * For n == 0 and with rounding this becomes: + * + * brr = ((((f+16)/32) +(b/2)) / b) - 1 + * + * For example, if the processor is clocked at 10 MHz and 9600 is the + * desired BAUD: + * + * brr = ((10,000,016/32) + 4800) / 9600 -1 + * = 32 + */ + + uint32_t brr = ((((SH1_CLOCK + 16) / 32) + (baud >> 1)) / baud) - 1; + up_serialout(priv, SH1_SCI_BRR_OFFSET, (uint16_t)brr); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the SCI baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_SCI_CONFIG + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint8_t smr; + + /* Disable the transmitter and receiver */ + + priv->scr = up_serialin(priv, SH1_SCI_SCR_OFFSET); + priv->scr &= ~(SH1_SCISCR_TE | SH1_SCISCR_RE); + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); + + /* Set communication to be asynchronous with the configured number of data + * bits, parity, and stop bits. Use the internal clock (undivided) + */ + + smr = 0; + if (priv->bits == 7) + { + smr |= SH1_SCISMR_CHR; + } + + if (priv->parity == 1) + { + smr |= (SH1_SCISMR_PE|SH1_SCISMR_OE); + } + else if (priv->parity == 2) + { + smr |= SH1_SCISMR_PE; + } + + if (priv->stopbits2) + { + smr |= SH1_SCISMR_STOP; + } + + up_serialout(priv, SH1_SCI_SMR_OFFSET, smr); + + /* Set the baud based on the configured console baud and configured + * system clock. + */ + + up_setbrr(priv, priv->baud); + + /* Select the internal clock source as input */ + + priv->scr &= ~SH1_SCISCR_CKEMASK; + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); + + /* Wait a bit for the clocking to settle */ + + up_udelay(100); + + /* Then enable the transmitter and reciever */ + + priv->scr |= (SH1_SCISCR_TE | SH1_SCISCR_RE); + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); +#endif + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the SCI. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + up_disablesciint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the SCI to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + int ret; + + /* Attach the RDR full IRQ (RXI) that is enabled by the RIE SCR bit */ + + ret = irq_attach(priv->irq + SH1_RXI_IRQ_OFFSET, up_interrupt); + if (ret == OK) + { + /* The RIE interrupt enable also enables the receive error interrupt (ERI) */ + + ret = irq_attach(priv->irq + SH1_ERI_IRQ_OFFSET, up_interrupt); + if (ret == OK) + { + /* Attach the TDR empty IRQ (TXI) enabled by the TIE SCR bit */ + + ret = irq_attach(priv->irq + SH1_TXI_IRQ_OFFSET, up_interrupt); + if (ret == OK) + { +#ifdef CONFIG_ARCH_IRQPRIO + /* All SCI0 interrupts share the same prioritization */ + + up_prioritize_irq(priv->irq, 7); /* Set SCI priority midway */ +#endif + /* Return OK on success */ + + return OK; + } + + /* Detach the ERI interrupt on failure */ + + (void)irq_detach(priv->irq + SH1_ERI_IRQ_OFFSET); + } + + /* Detach the RXI interrupt on failure */ + + (void)irq_detach(priv->irq + SH1_RXI_IRQ_OFFSET); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach SCI interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + + /* Disable all SCI interrupts */ + + up_disablesciint(priv, NULL); + + /* Detach the SCI interrupts */ + + (void)irq_detach(priv->irq + SH1_RXI_IRQ_OFFSET); + (void)irq_detach(priv->irq + SH1_ERI_IRQ_OFFSET); + (void)irq_detach(priv->irq + SH1_RXI_IRQ_OFFSET); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority to zero (masking all SCI interrupts). NOTE + * that all SCI0 interrupts share the same prioritization. + */ + + up_prioritize_irq(priv->irq, 0); +#endif +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the SCI interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * up_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct up_dev_s *priv; + +#ifdef CONFIG_SH1_SCI0 + if ((irq >= g_sci0priv.irq) && + (irq <= g_sci0priv.irq + SH1_SCI_NIRQS)) + { + dev = &g_sci0port; + } + else +#endif +#ifdef CONFIG_SH1_SCI1 + if ((irq >= g_sci1priv.irq) && + (irq <= g_sci1priv.irq + SH1_SCI_NIRQS)) + { + dev = &g_sci1port; + } + else +#endif + { + PANIC(); + } + priv = (struct up_dev_s*)dev->priv; + + /* Get the current SCI status */ + + priv->ssr = up_serialin(priv, SH1_SCI_SSR_OFFSET); + + /* Handle receive-related events with RIE is enabled. RIE is enabled at + * times that driver is open EXCEPT when the driver is actively copying + * data from the circular buffer. In that case, the read events must + * pend until RIE is set + */ + + if ((priv->scr & SH1_SCISCR_RIE) != 0) + { + /* Handle incoming, receive bytes (RDRF: Receive Data Register Full) */ + + if ((priv->ssr & SH1_SCISSR_RDRF) != 0) + { + /* Rx data register not empty ... process incoming bytes */ + + uart_recvchars(dev); + } + + /* Clear all read related events (probably already done in up_receive)) */ + + priv->ssr &= ~(SH1_SCISSR_RDRF|SH1_SCISSR_ORER|SH1_SCISSR_FER|SH1_SCISSR_PER); + } + + /* Handle outgoing, transmit bytes (TDRE: Transmit Data Register Empty) + * when TIE is enabled. TIE is only enabled when the driver is waiting with + * buffered data. Since TDRE is usually true, + */ + + if ((priv->ssr & SH1_SCISSR_TDRE) != 0 && (priv->scr & SH1_SCISCR_TIE) != 0) + { + /* Tx data register empty ... process outgoing bytes */ + + uart_xmitchars(dev); + + /* Clear the TDR empty flag (Possibly done in up_send, will have not + * effect if the TDR is still empty) + */ + + priv->ssr &= ~SH1_SCISSR_TDRE; + } + + /* Clear all (clear-able) status flags. Note that that SH-1 requires + * that you read the bit in the "1" then write "0" to the bit in order + * to clear it. Any bits in the SSR that transitioned from 0->1 after + * we read the SR will not be effected by the following: + */ + + up_serialout(priv, SH1_SCI_SSR_OFFSET, priv->ssr); + return OK; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the SCI. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint8_t rdr; + uint8_t ssr; + + /* Read the character from the RDR port */ + + rdr = up_serialin(priv, SH1_SCI_RDR_OFFSET); + + /* Clear all read related status in real ssr (so that when when rxavailable + * is called again, it will return false. + */ + + ssr = up_serialin(priv, SH1_SCI_SSR_OFFSET); + ssr &= ~(SH1_SCISSR_RDRF|SH1_SCISSR_ORER|SH1_SCISSR_FER|SH1_SCISSR_PER); + up_serialout(priv, SH1_SCI_SSR_OFFSET, ssr); + + /* For status, return the SSR at the time that the interrupt was received */ + + *status = (uint32_t)priv->ssr << 8 | rdr; + + /* Return the received character */ + + return (int)rdr; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + irqstate_t flags; + + /* Disable interrupts to prevent asynchronous accesses */ + + flags = enter_critical_section(); + + /* Are we enabling or disabling? */ + + if (enable) + { + /* Enable the RDR full interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->scr |= SH1_SCISCR_RIE; +#endif + } + else + { + /* Disable the RDR full interrupt */ + + priv->scr &= ~SH1_SCISCR_RIE; + } + + /* Write the modified SCR value to hardware */ + + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the RDR is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + /* Return true if the RDR full bit is set in the SSR */ + + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return ((up_serialin(priv, SH1_SCI_SSR_OFFSET) & SH1_SCISSR_RDRF) != 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the SCI + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint8_t ssr; + + /* Write the data to the TDR */ + + up_serialout(priv, SH1_SCI_TDR_OFFSET, (uint8_t)ch); + + /* Clear the TDRE bit in the SSR */ + + ssr = up_serialin(priv, SH1_SCI_SSR_OFFSET); + ssr &= ~SH1_SCISSR_TDRE; + up_serialout(priv, SH1_SCI_SSR_OFFSET, ssr); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + irqstate_t flags; + + /* Disable interrupts to prevent asynchronous accesses */ + + flags = enter_critical_section(); + + /* Are we enabling or disabling? */ + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + /* Enable the TDR empty interrupt */ + + priv->scr |= SH1_SCISCR_TIE; + + /* If the TDR is already empty, then don't wait for the interrupt */ + +#if 1 + if (up_txready(dev)) + { + /* Tx data register empty ... process outgoing bytes. Note: + * this could call up_txint to be called recursively. However, + * in this event, priv->scr should hold the correct value upon + * return from uuart_xmitchars(). + */ + + uart_xmitchars(dev); + } +#endif +#endif + } + else + { + /* Disable the TDR empty interrupt */ + + priv->scr &= ~SH1_SCISCR_TIE; + } + + /* Write the modified SCR value to hardware */ + + up_serialout(priv, SH1_SCI_SCR_OFFSET, priv->scr); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the TDR is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + return (up_serialin(priv, SH1_SCI_SSR_OFFSET) & SH1_SCISSR_TDRE) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyconsoleinit + * + * Description: + * Performs the low level SCI initialization early in + * debug so that the serial console will be available + * during bootup. This must be called before up_consoleinit. + * + ****************************************************************************/ + +void up_earlyconsoleinit(void) +{ + /* NOTE: All GPIO configuration for the SCIs was performed in + * up_lowsetup + */ + + /* Disable all SCIs */ + +#ifdef TTYS0_DEV + up_disablesciint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disablesciint(TTYS1_DEV.priv, NULL); +#endif +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_consoleinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyconsoleinit was called previously. + * + ****************************************************************************/ + +void up_consoleinit(void) +{ + /* Register the console */ + +#ifdef HAVE_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all SCIs */ + +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; + uint8_t scr; + + up_disablesciint(priv, &scr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_waittxready(priv); + up_serialout(priv, SH1_SCI_TDR_OFFSET, '\r'); + } + + up_waittxready(priv); + up_serialout(priv, SH1_SCI_TDR_OFFSET, (uint8_t)ch); + + up_waittxready(priv); + up_restoresciint(priv, scr); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/sh/src/sh1/sh1_sigdeliver.c b/arch/sh/src/sh1/sh1_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..eead3c06f256866b088bdbe85d497cc3e0a1ab52 --- /dev/null +++ b/arch/sh/src/sh1/sh1_sigdeliver.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * common/up_sigdeliver.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_SR] = rtcb->xcp.saved_sr; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(regs[REG_SR] & 0x000000f0); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +#endif +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/sh/src/sh1/sh1_timerisr.c b/arch/sh/src/sh1/sh1_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..08647be112f7b77286142583c74b003f42fa2427 --- /dev/null +++ b/arch/sh/src/sh1/sh1_timerisr.c @@ -0,0 +1,207 @@ +/**************************************************************************** + * arch/sh/src/sh1/sh1_timerisr.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * ITU1 operates in periodic timer mode. TCNT counts up until it matches + * the value of GRA0, then an interrupt is generated. Two values must be + * computed: + * + * (1) The divider that determines the rate at which TCNT increments, and + * (2) The value of GRA0 that cause the interrupt to occur. + * + * These must be selected so that the frequency of interrupt generation is + * CLK_TCK. Ideally, we would like to use the full range of GRA0 for better + * timing acuracy: + */ + +#define DESIRED_GRA0 65535 + +/* The ideal divider would be one that generates exactly 65535 ticks in + * 1/CLK_TCK seconds. For example, if SH1_CLOCK is 10MHz and CLK_TCK is + * 100, then the ideal divider must be less greater than or equal to: + * + * (10,000,000 / CLK_TCK) / 65535 = 1.525 + * + * The actual selected divider would then have to be 2, resulting in a + * counting rate of 5,000,0000 and a GRA0 setting of 50,000. + */ + +#define SYSCLKS_PER_TICK ((SH1_CLOCK + (CLK_TCK-1))/ CLK_TCK) +#define DESIRED_DIVIDER ((SYSCLKS_PER_TICK + (DESIRED_GRA0-1))/ DESIRED_GRA0) + +#if (DESIRED_DIVIDER <= 1) +# define SYSCLK_DIVIDER 1 +# define SH1_ITUTCR_DIV SH1_ITUTCR_DIV1 +#elif (DESIRED_DIVIDER <= 2) +# define SYSCLK_DIVIDER 2 +# define SH1_ITUTCR_DIV SH1_ITUTCR_DIV2 +#elif (DESIRED_DIVIDER <= 4) +# define SYSCLK_DIVIDER 4 +# define SH1_ITUTCR_DIV SH1_ITUTCR_DIV4 +#elif (DESIRED_DIVIDER <= 8) +# define SYSCLK_DIVIDER 8 +# define SH1_ITUTCR_DIV SH1_ITUTCR_DIV8 +#else +# error "No divider is available for this system clock" +#endif + +/* The TCNT will then increment at the following rate: */ + +#define TCNT_CLOCK ((SH1_CLOCK + (SYSCLK_DIVIDER/2))/ SYSCLK_DIVIDER) + +/* And the value of GRA0 that generates at CLK_TCK ticks per second is: */ + +#define TCNT_PER_TICK ((TCNT_CLOCK + (CLK_TCK-1))/ CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + uint8_t reg8; + + /* Process timer interrupt */ + + sched_process_timer(); + + /* Clear ITU0 interrupt status flag */ + + reg8 = getreg8(SH1_ITU0_TSR); + reg8 &= ~SH1_ITUTSR_IMFA; + putreg8(reg8, SH1_ITU0_TSR); + + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint8_t reg8; + + /* Clear timer counter 0 */ + + putreg16(0, SH1_ITU0_TCNT); + + /* Set the GRA0 match value. The interrupt will be generated when TNCT + * increments to this value + */ + + putreg16(TCNT_PER_TICK, SH1_ITU0_GRA); + + /* Set the timer control register. TCNT cleared by FRA */ + + putreg8(SH1_ITUTCR_CGRA|SH1_ITUTCR_DIV, SH1_ITU0_TCR); + + /* Set the timer I/O control register */ + + putreg8(0, SH1_ITU0_TIOR); /* GRA used but with no inputs/output pins */ + + /* Make sure that all status flags are clear */ + + putreg8(0, SH1_ITU0_TSR); + + /* Attach the IMIA0 IRQ */ + + irq_attach(SH1_SYSTIMER_IRQ, (xcpt_t)up_timerisr); + + /* Enable interrupts on GRA compare match */ + + putreg8(SH1_ITUTIER_IMIEA, SH1_ITU0_TIER); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(SH1_SYSTIMER_IRQ, 7); /* Set ITU priority midway */ +#endif + + /* Start the timer */ + + reg8 = getreg8(SH1_ITU_TSTR); + reg8 |= SH1_ITUTSTR_STR0; /* Enable TCNT0 */ + putreg8(reg8, SH1_ITU_TSTR); /* TCNT0 is counting */ +} diff --git a/arch/sh/src/sh1/sh1_vector.S b/arch/sh/src/sh1/sh1_vector.S new file mode 100644 index 0000000000000000000000000000000000000000..396e33cd2761b95ae6e76172c391b87f7fc69c31 --- /dev/null +++ b/arch/sh/src/sh1/sh1_vector.S @@ -0,0 +1,526 @@ +/***************************************************************************** + * arch/sh/src/sh1/sh1_vector.S + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include /* NuttX configuration settings */ +#include /* Board-specific settings */ +#include /* IRQ definitons */ + +#include "chip.h" /* Chip-specific settings */ +#include "up_internal.h" + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +/***************************************************************************** + * External references + *****************************************************************************/ + +/* Called functions */ + + .globl _up_doirq /* C interrupt processing logic */ + +/***************************************************************************** + * Macros + *****************************************************************************/ + +/************************************************************************************ + * Macro: trampoline + * + * Description: + * Enter on exception with: + * + * SP -> PC + * SR + * + * Branch to up_vector with: + * + * R4 : IRQ vector number + * SP -> Saved R4 + * PC + * SR + * + ************************************************************************************/ + + .macro trampoline, irq, label + mov.l r4, @-r15 /* Save the value of R4 on the stack */ + mov.w .L\label, r4 /* R4=IRQ number */ + bra _up_vector /* Jump to the common vector handling logic */ + nop +.L\label: + .word \irq + .endm + +/***************************************************************************** + * Text + *****************************************************************************/ + + .section .reset + +/***************************************************************************** + * Name: _up_*_handler + * + * Description: + * Trampoline entry points for each, individual IRQ + * + * R4 : Points to a the register save structure + * + *****************************************************************************/ + + .globl _up_invalid_handler +_up_invalid_handler: + trampoline NR_IRQS, 1 + +#ifdef CONFIG_SH1_DMAC0 + .globl _up_dmac0_handler +_up_dmac0_handler: + trampoline SH1_DEI0_IRQ, 2 /* DEI0 */ +#endif + +#ifdef CONFIG_SH1_DMAC1 + .globl _up_dmac1_handler +_up_dmac1_handler: + trampoline SH1_DEI1_IRQ, 3 /* DEI1 */ +#endif + +#ifdef CONFIG_SH1_DMAC2 + .globl _up_dmac2_handler +_up_dmac2_handler: + trampoline SH1_DEI2_IRQ, 4 /* DEI2 */ +#endif + +#ifdef CONFIG_SH1_DMAC3 + .globl _up_dmac3_handler +_up_dmac4_handler: + trampoline SH1_DEI3_IRQ, 5 /* DEI3 */ +#endif + + .globl _up_imia0_handler + .globl _up_imib0_handler + .globl _up_ovi0_handler +_up_imia0_handler: + trampoline SH1_IMIA0_IRQ, 6 /* IMIA0 */ +_up_imib0_handler: + trampoline SH1_IMIB0_IRQ, 7 /* IMIB0 */ +_up_ovi0_handler: + trampoline SH1_OVI0_IRQ, 8 /* OVI0 */ + +#ifdef CONFIG_SH1_ITU1 + .globl _up_imia1_handler + .globl _up_imib1_handler + .globl _up_ovi1_handler +_up_imia1_handler: + trampoline SH1_IMIA1_IRQ, 9 /* IMIA1 */ +_up_imib1_handler: + trampoline SH1_IMIB1_IRQ, 10 /* IMIB1 */ +_up_ovi1_handler: + trampoline SH1_OVI1_IRQ, 11 /* OVI1 */ +#endif + +#ifdef CONFIG_SH1_ITU2 + .globl _up_imia2_handler + .globl _up_imib2_handler + .globl _up_ovi2_handler +_up_imia2_handler: + trampoline SH1_IMIA2_IRQ, 12 /* IMIA2 */ +_up_imib2_handler: + trampoline SH1_IMIB2_IRQ, 13 /* IMIB2 */ +_up_ovi2_handler: + trampoline SH1_OVI2_IRQ, 14 /* OVI2 */ +#endif + +#ifdef CONFIG_SH1_ITU3 + .globl _up_imia3_handler + .globl _up_imib3_handler + .globl _up_ovi3_handler +_up_imia3_handler: + trampoline SH1_IMIA3_IRQ, 15 /* IMIA3 */ +_up_imib3_handler: + trampoline SH1_IMIB3_IRQ, 16 /* IMIB3 */ +_up_ovi3_handler: + trampoline SH1_OVI3_IRQ, 17 /* OVI3 */ +#endif + +#ifdef CONFIG_SH1_ITU4 + .globl _up_imia4_handler + .globl _up_imib4_handler + .globl _up_ovi4_handler +_up_imia4_handler: + trampoline SH1_IMIA4_IRQ, 18 /* IMIA4 */ +_up_imib4_handler: + trampoline SH1_IMIB4_IRQ, 19 /* IMIB4 */ +_up_ovi4_handler: + trampoline SH1_OVI4_IRQ, 20 /* OVI4 */ +#endif + +#ifdef CONFIG_SH1_SCI0 + .globl _up_eri0_handler + .globl _up_rxi0_handler + .globl _up_txi0_handler + .globl _up_tei0_handler +_up_eri0_handler: + trampoline SH1_ERI0_IRQ, 21 /* ERI0 */ +_up_rxi0_handler: + trampoline SH1_RXI0_IRQ, 22 /* RxI0 */ +_up_txi0_handler: + trampoline SH1_TXI0_IRQ, 23 /* TxI0 */ +_up_tei0_handler: + trampoline SH1_TEI0_IRQ, 24 /* TEI0 */ +#endif + +#ifdef CONFIG_SH1_SCI1 + .globl _up_eri1_handler + .globl _up_rxi1_handler + .globl _up_txi1_handler + .globl _up_tei1_handler +_up_eri1_handler: + trampoline SH1_ERI1_IRQ, 25 /* ERI1 */ +_up_rxi1_handler: + trampoline SH1_RXI1_IRQ, 26 /* RxI1 */ +_up_txi1_handler: + trampoline SH1_TXI1_IRQ, 27 /* TxI1 */ +_up_tei1_handler: + trampoline SH1_TEI1_IRQ, 28 /* TEI1 */ +#endif + +#ifdef CONFIG_SH1_PCU + .globl _up_pei_handler +_up_pei_handler: + trampoline SH1_PEI_IRQ, 29 /* Parity control unit PEI */ +#endif + +#ifdef CONFIG_SH1_AD + .globl _up_aditi_handler +_up_aditi_handler: + trampoline SH1_ADITI_IRQ, 30 /* A/D ITI */ +#endif + +#ifdef CONFIG_SH1_WDT + .globl _up_wdt_handler +_up_wdt_handler: + trampoline SH1_WDTITI_IRQ, 31 /* WDT ITI */ +#endif + +#ifdef CONFIG_SH1_CMI + .globl _up_cmi_handler +_up_cmi_handler: + trampoline SH1_CMI_IRQ,32 /* REF CMI */ +#endif + +/***************************************************************************** + * Name: _up_vector + * + * Description: + * Execption entry point. Upon entry: + * + * R4 : Holds IRQ number + * SP -> Saved R4 (REG_R4=19) See irq.h + * PC (REG_PC=20) + * SR (REG_SR=21) + * + *****************************************************************************/ + + .global _up_vector + .type _up_vector, #function + +_up_vector: + /* Save r0-r3, r5-r7 on the stack so that we have a registers to work with. + * After this, the stack will look like: + * + * SP -> macl (REG_MACL=10) See irq.h + * mach (REG_MACH=11) + * r0 (REG_R0=12) + * r1 (REG_R1=13) + * r2 (REG_R2=14) + * r3 (REG_R3=15) + * r5 (REG_R5=16) + * r6 (REG_R6=17) + * r7 (REG_R7=18) + * R4 (REG_R4=19) + * ... + */ + + mov.l r7, @-r15 + mov.l r6, @-r15 + + stc sr, r6 /* Mask all interrupts */ + mov.l .Lintmask, r7 + or r7, r6 + ldc r6, sr + + mov.l r5, @-r15 + mov.l r3, @-r15 + mov.l r2, @-r15 + mov.l r1, @-r15 + mov.l r0, @-r15 + + sts.l mach, @-r15 + sts.l macl, @-r15 + + /* Then save the value of the SP *before* the interrupt ocurred + * + * SP -> SP (REG_SP=9) See irq.h + * macl (REG_MACL=10) + * mach (REG_MACH=11) + * ... + */ + + mov r15, r5 /* R5 = current SP */ + add #(12*4), r5 /* Account for sr, pc, r0-r7, mach, and macl */ + mov.l r5, @-r15 /* Save the SP before the interrupt */ + + /* Save the remaining registers on the stack: + * + * SP -> r8 (REG_R8=0) See irq.h + * r9 (REG_R9=1) + * r10 (REG_R10=2) + * r11 (REG_R11=3) + * r12 (REG_R12=4) + * r13 (REG_R13=5) + * r14 (REG_R14=6) + * pr (REG_PR=7) + * gbr (REG_GBR=8) + * SP (REG_SP=9) + * ... + */ + + stc.l gbr, @-r15 + sts.l pr, @-r15 + + mov.l r14, @-r15 + mov.l r13, @-r15 + mov.l r12, @-r15 + mov.l r11, @-r15 + mov.l r10, @-r15 + mov.l r9, @-r15 + mov.l r8, @-r15 + + /* Setup parameters: R4=IRQ number, R5=base of saved state */ + + mov r15, r5 + + /* Switch to the interrupt stack */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + mov.l .Lintstack, r15 /* SP = interrupt stack base */ + mov.l r5, @r15 /* Save the user stack pointer (pre-decremented) */ + + /* Dispatch the interrupt */ + + mov.l .Ldoirq, r0 + jsr @r0 + nop + + /* Recover the user stack point */ + + mov.l @15, r15 +#else + /* Dispatch the interrupt */ + + mov.l .Ldoirq, r0 + jsr @r0 + nop +#endif + /* On return, R0 holds the address of the base of the XCPTCONTEXT + * structure to use for the return -- may not be the same as the + * one that we passed in via r5. If the value is different, then + * we cannot assume that the values lie on the stack and we will + * need to execute some more complete logic. + */ + + cmp/eq r0, r15 + bf .Lcontextswitch + mov r0, r15 + + /* Restore registers from the stack. NOTE: We coudl improve interrupt + * performance by skipping the restore of r8-r14. These will not + * be modified by the called C code + */ + +#if 1 + /* Skip over static registers -- these will not be modified by the + * called C code (r8-r14) + */ + + add #(7*4), r15 /* 0-6: Skip over r8-r14 */ +#else + mov.l @r15+, r8 /* 0-6: r8-r14 */ + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 +#endif + + lds.l @r15+, pr /* 7-8: pr and gbr */ + ldc.l @r15+, gbr + + add #4, r15 /* 9: Skip SP restore */ + + lds.l @r15+, macl /* 10-11: mach and macl */ + lds.l @r15+, mach + + mov.l @r15+, r0 /* 12-18: r0-r3, r5-r7 */ + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r5 + mov.l @r15+, r6 + mov.l @r15+, r7 + + mov.l @r15+, r4 /* 19: r4 */ + rte /* 20-21: pc and sr */ + nop + .align 2 +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Lintstack: + .long _g_intstackbase +#endif +.Ldoirq: + .long _up_doirq + .size _up_vector, .-_up_vector + +/***************************************************************************** + * Name: _up_fullcontextrestore + * + * Description: + * restore context from a set of save registers + * + * R4 : Points to a the register save structure + * + *****************************************************************************/ + + .global _up_fullcontextrestore + .type _up_fullcontextrestore, #function + +_up_fullcontextrestore: + /* Mask all interrupts */ + + stc sr, r8 + mov.l .Lintmask, r9 + or r9, r8 + ldc r8, sr + + /* Replace stack pointer with the context save */ + + mov r4, r15 + + /* Restore registers from a context structure */ + +.Lcontextswitch: + mov.l @r15+, r8 /* 0-8: r8-r14, pr, and gbr */ + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + + lds.l @r15+, pr + ldc.l @r15+, gbr + + mov.l @r15+, r4 /* r4: Saved SP */ + + lds.l @r15+, macl /* 10-11: mach and macl */ + lds.l @r15+, mach + + mov.l @r15+, r0 /* 12-17: r0-r3, r5-r6 */ + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r5 + mov.l @r15+, r6 + + /* Copy the remainder of the stack context to the target stack. + * At this point r15 points to offset REG_R6. + */ + + add #-16, r4 /* R4 points to offset REG_R7 in the new stack */ + mov.l @r15+, r7 /* R7=Saved R7 value */ + mov.l r7, @r4 /* Save at offset REG_R7 in the new stack */ + mov.l @r15+, r7 /* R7=Save R4 value */ + mov.l r7, @(4,r4) /* Save at offset REG_R4 in the new stack */ + mov.l @r15+, r7 /* R7=Save PC value */ + mov.l r7, @(8,r4) /* Save at offset REG_PC in the new stack */ + mov.l @r15+, r7 /* R7=Save SR value */ + mov.l r7, @(12,r4) /* Save at offset REG_SR in the new stack */ + + /* Set the new stack pointer */ + + mov r4, r15 + + /* Then recover the final register values from the new stack */ + + mov.l @r15+, r7 + mov.l @r15+, r4 + + /* And return from interrupt */ + + rte + nop + .align 2 +.Lintmask: + .long 0x000000f0 + .size _up_fullcontextrestore, .-_up_fullcontextrestore + +/************************************************************************************ + * Name: g_intstackalloc/g_intstackbase + * + * Description: + * Shouldn't happen + * + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 2 + .globl _g_intstackalloc + .type _g_intstackalloc, object + .globl _g_intstackbase + .type _g_intstackbase, object +_g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) +_g_intstackbase: + .skip 2 + .size _g_intstackbase, 4 + .size _g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) +#endif + .end + diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..b0395968d79647465397150cd2d788dd9ee2f904 --- /dev/null +++ b/arch/sim/Kconfig @@ -0,0 +1,259 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_SIM +comment "Simulation Configuration Options" + +choice + prompt "Host CPU Type" + default HOST_X86_64 + +config HOST_X86_64 + bool "x86_64" + +config HOST_X86 + bool "x86" + +endchoice # Host CPU Type + +config SIM_M32 + bool "Build 32-bit simulation on 64-bit machine" + default n + depends on HOST_X86_64 + ---help--- + Simulation context switching is based on logic like setjmp and longjmp. This + context switching is only available for 32-bit targets. On 64-bit machines, + this context switching will fail. + + The workaround on 64-bit machines for now is to build for a 32-bit target on the + 64-bit machine. The workaround for this issue has been included in NuttX 6.15 and + beyond. For thoses versions, you must add SIM_M32=y to the .config file in + order to enable building a 32-bit image on a 64-bit platform. + +config SIM_CYGWIN_DECORATED + bool "Decorated Cygwin names" + default n + depends on WINDOWS_CYGWIN + ---help--- + Older versions of Cygwin toolsdecorated C symbol names by adding an + underscore to the beginning of the symbol name. Newer versions of + Cygwin do not seem to do this. + + How do you know if you need this option? You could look at the generated + symbol tables to see if there are underscore characters at the beginning + of the symbol names. Or, if you need this option, the simulation will not + run: It will crash early, probably in some function due to the failure to + allocate memory. + +choice + prompt "X64_64 ABI" + default SIM_X8664_SYSTEMV if HOST_LINUX + default SIM_X8664_MICROSOFT if HOST_WINDOWS + depends on HOST_X86_64 && !SIM_32 + +config SIM_X8664_SYSTEMV + bool "System V AMD64 ABI" + ---help--- + The calling convention of the System V AMD64 ABI is followed on Solaris, + Linux, FreeBSD, Mac OS X, and other UNIX-like or POSIX-compliant operating + systems. The first six integer or pointer arguments are passed in registers + RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, + XMM6 and XMM7 are used for floating point arguments. For system calls, R10 + is used instead of RCX. As in the Microsoft x64 calling convention, + additional arguments are passed on the stack and the return value is stored + in RAX. + + Registers RBP, RBX, and R12-R15 are callee-save registers; all others must + be saved by the caller if they wish to preserve their values. + + Unlike the Microsoft calling convention, a shadow space is not provided; on + function entry, the return address is adjacent to the seventh integer argument + on the stack. + +config SIM_X8664_MICROSOFT + bool "Microsoft x64 calling convention" + ---help--- + The Microsoft x64 calling convention is followed on Microsoft Windows and + pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8, + R9 for the first four integer or pointer arguments (in that order), and + XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional + arguments are pushed onto the stack (right to left). Integer return + values (similar to x86) are returned in RAX if 64 bits or less. Floating + point return values are returned in XMM0. Parameters less than 64 bits + long are not zero extended; the high bits are not zeroed. + +endchoice + +config SIM_WALLTIME + bool "Execution simulation in near real-time" + default n + ---help--- + NOTE: In order to facility fast testing, the sim target's IDLE loop, by default, + calls the system timer "interrupt handler" as fast as possible. As a result, there + really are no noticeable delays when a task sleeps. However, the task really does + sleep -- but the time scale is wrong. If you want behavior that is closer to + normal timing, then you can define SIM_WALLTIME=y in your configuration + file. This configuration setting will cause the sim target's IDLE loop to delay + on each call so that the system "timer interrupt" is called at a rate approximately + correct for the system timer tick rate. With this definition in the configuration, + sleep() behavior is more or less normal. + +config SIM_LCDDRIVER + bool "Build a simulated LCD driver" + default y + depends on NX && NX_LCDDRIVER + ---help--- + Build a simulated LCD driver" + +config SIM_FRAMEBUFFER + bool "Build a simulated frame buffer driver" + default n + depends on !NX_LCDDRIVER + ---help--- + Build a simulated frame buffer driver" + +if SIM_FRAMEBUFFER + +config SIM_X11FB + bool "Use X11 window" + default n + ---help--- + Use an X11 graphics window to simulate the graphics device" + +config SIM_X11NOSHM + bool "Don't use shared memory with X11" + default n + depends on SIM_X11FB + ---help--- + Don't use shared memory with the X11 graphics device emulation." + +config SIM_FBHEIGHT + int "Display height" + default 240 + ---help--- + Simulated display height. Default: 240 + +config SIM_FBWIDTH + int "Display width" + default 320 if SIM_LCDDRIVER + default 480 if SIM_FRAMEBUFFER + ---help--- + Simulated width of the display. Default: 320 or 480 + +config SIM_FBBPP + int "Pixel depth in bits" + default 8 + ---help--- + Pixel depth in bits. Valid choices are 4, 8, 16, 24, or 32. + If you use the X11 display emulation, the selected BPP must match the BPP + of your graphics hardware (probably 32 bits). Default: 8 + +endif # SIM_FRAMEBUFFER + +if SIM_X11FB && INPUT +choice + prompt "X11 Simulated Input Device" + default SIM_NOINPUT + +config SIM_TOUCHSCREEN + bool "X11 mouse-based touchscreen emulation" + ---help--- + Support an X11 mouse-based touchscreen emulation. Also needs INPUT=y + +config SIM_AJOYSTICK + bool "X11 mouse-based analog joystick emulation" + ---help--- + Support an X11 mouse-based anallog joystick emulation. Also needs INPUT=y` + +config SIM_NOINPUT + bool "No input device" + +endchoice # X11 Simulated Input Device +endif # SIM_X11FB && INPUT + +config SIM_TCNWAITERS + bool "Maximum number poll() waiters" + default 4 + depends on !POLL_DISABLE && SIM_TOUCHSCREEN + ---help--- + The maximum number of threads that can be waiting on poll() for a touchscreen event. + Default: 4 + +config SIM_SPIFLASH + bool "Simulated SPI FLASH with SMARTFS" + default n + select FS_SMARTFS + select MTD_SMART + ---help--- + Adds a simulated SPI FLASH that responds to standard M25 style + commands on the SPI bus. + +choice + prompt "Simulated SPI FLASH Size" + default SIM_SPIFLASH_1M + depends on SIM_SPIFLASH + +config SIM_SPIFLASH_1M + bool "1 MBit (128K Byte)" + +config SIM_SPIFLASH_8M + bool "8 MBit (1M Byte)" + +config SIM_SPIFLASH_32M + bool "32 MBit (4M Byte)" + +config SIM_SPIFLASH_64M + bool "64 MBit (8M Byte)" + +config SIM_SPIFLASH_128M + bool "128 MBit (16M Byte)" + +endchoice + +config SIM_SPIFLASH_MANUFACTURER + hex "Hex ID of the FLASH manufacturer code" + default 0x20 + depends on SIM_SPIFLASH + ---help--- + Allows the simulated FLASH Manufacturer ID to be set. + +config SIM_SPIFLASH_MEMORY_TYPE + hex "Hex ID of the FLASH Memory Type code" + default 0x20 + depends on SIM_SPIFLASH + ---help--- + Allows the simulated FLASH Memory Type code to be set. + +config SIM_SPIFLASH_SECTORSIZE + int "FLASH Sector Erase Size" + default 65536 + depends on SIM_SPIFLASH + ---help--- + Sets the large sector erase size that the part simulates. + This driver simulates SPI devices that have both a large + sector erase as well as a "sub-sector" (per the datasheet) + erase size (typically 4K bytes). + +config SIM_SPIFLASH_SUBSECTORSIZE + int "FLASH Sub-Sector Erase Size" + default 4096 + depends on SIM_SPIFLASH + ---help--- + Sets the smaller sub-sector erase size supported by the + FLASH emulation + +config SIM_SPIFLASH_PAGESIZE + int "FLASH Write / Program Page Size" + default 256 + depends on SIM_SPIFLASH + ---help--- + Sets the size of a page program operation. The page size + represents the maximum number of bytes that can be sent + for a program operation. If more bytes than this are + sent on a single Page Program, then the address will + "wrap" causing the initial data sent to be overwritten. + This is consistent with standard SPI FLASH operation. + +endif diff --git a/arch/sim/include/.gitignore b/arch/sim/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..12c22f4f28ae35faec71b131922f800ca8813bea --- /dev/null +++ b/arch/sim/include/.gitignore @@ -0,0 +1,2 @@ +/board + diff --git a/arch/sim/include/arch.h b/arch/sim/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..29cf6495fce21545af5132b51188e3110397e126 --- /dev/null +++ b/arch/sim/include/arch.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch.h + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_ARCH_H +#define __ARCH_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARCH_H */ + diff --git a/arch/sim/include/irq.h b/arch/sim/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..9a9781dda46afe2bac55e0502447704bea862c60 --- /dev/null +++ b/arch/sim/include/irq.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * irq.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_IRQ_H +#define __ARCH_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* No interrupts */ + +#define NR_IRQS 0 + +/* Number of registers saved in context switch */ + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + +# define XCPTCONTEXT_REGS 8 +#else + /* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */ + +# define XCPTCONTEXT_REGS 6 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* Number of registers saved in context switch */ + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) +typedef unsigned long xcpt_reg_t; +#else +typedef int xcpt_reg_t; +#endif + +/* This struct defines the way the registers are stored */ + +struct xcptcontext +{ + void *sigdeliver; /* Actual type is sig_deliver_t */ + + xcpt_reg_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +static inline irqstate_t up_irq_save(void) +{ + return 0; +} + +static inline void up_irq_restore(irqstate_t flags) +{ +} +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_IRQ_H */ + diff --git a/arch/sim/include/limits.h b/arch/sim/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..6a52c2c1b190574191d041e5f8918cad36935e9a --- /dev/null +++ b/arch/sim/include/limits.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/sim/include/limits.h + * + * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_INCLUDE_LIMITS_H +#define __ARCH_SIM_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 or 8 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#if !defined(CONFIG_HOST_X86_64) || defined(CONFIG_SIM_M32) +# define PTR_MAX 2147483647 +# define UPTR_MAX 4294967295U +#else +# define PTR_MAX 9223372036854775807LL +# define UPTR_MAX 18446744073709551615ULL +#endif + +#endif /* __ARCH_SIM_INCLUDE_LIMITS_H */ diff --git a/arch/sim/include/spinlock.h b/arch/sim/include/spinlock.h new file mode 100644 index 0000000000000000000000000000000000000000..3c20ffe22afbc2f034accbadd78c7daa89365161 --- /dev/null +++ b/arch/sim/include/spinlock.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/sim/include/spinlock.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_INCLUDE_SPINLOCK_H +#define __ARCH_SIM_INCLUDE_SPINLOCK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Must match definitions in up_testset.c */ + +#define SP_UNLOCKED false /* The Un-locked state */ +#define SP_LOCKED true /* The Locked state */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* Must match definitions in up_testset.c */ + +typedef bool spinlock_t; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + +/* See prototype in nuttx/include/nuttx/spinlock.h */ + +#endif /* __ARCH_SIM_INCLUDE_SPINLOCK_H */ diff --git a/arch/sim/include/syscall.h b/arch/sim/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..1e468e5ef0a40040d5873398b4b92450af969c8c --- /dev/null +++ b/arch/sim/include/syscall.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/sim/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_SIM_INCLUDE_SYSCALL_H +#define __ARCH_SIM_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_SIM_INCLUDE_SYSCALL_H */ + diff --git a/arch/sim/include/tls.h b/arch/sim/include/tls.h new file mode 100644 index 0000000000000000000000000000000000000000..ae2cf3b85a243b097a80396a0aeadf204903ae35 --- /dev/null +++ b/arch/sim/include/tls.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/sin/include/tls.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_INCLUDE_TLS_H +#define __ARCH_SIM_INCLUDE_TLS_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#ifdef CONFIG_TLS + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_tls_info + * + * Description: + * Return the TLS information structure for the currently executing thread. + * When TLS is enabled, up_createstack() will align allocated stacks to + * the TLS_STACK_ALIGN value. An instance of the following structure will + * be implicitly positioned at the "lower" end of the stack. Assuming a + * "push down" stack, this is at the "far" end of the stack (and can be + * clobbered if the stack overflows). + * + * If an MCU has a "push up" then that TLS structure will lie at the top + * of the stack and stack allocation and initialization logic must take + * care to preserve this structure content. + * + * The stack memory is fully accessible to user mode threads. + * + * Input Parameters: + * None + * + * Returned Value: + * A pointer to TLS info structure at the beginning of the STACK memory + * allocation. This is essentially an application of the TLS_INFO(sp) + * macro and has a platform dependency only in the manner in which the + * stack pointer (sp) is obtained and interpreted. + * + ****************************************************************************/ + +static inline FAR struct tls_info_s *up_tls_info(void) +{ + return TLS_INFO((uintptr_t)__builtin_frame_address(0)); +} + +#endif /* CONFIG_TLS */ +#endif /* __ARCH_SIM_INCLUDE_TLS_H */ diff --git a/arch/sim/include/types.h b/arch/sim/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..83669eac3e4ce7a9942da7188d20831201a5aa52 --- /dev/null +++ b/arch/sim/include/types.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/sim/include/types.h + * + * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through sys/types.h + */ + +#ifndef __ARCH_SIM_INCLUDE_TYPES_H +#define __ARCH_SIM_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) +/* 64-bit build on 64-bit machine: A pointer is 8 bytes */ + +typedef signed long long _intptr_t; +typedef unsigned long long _uintptr_t; + +#else +/* 32-bit build on 32- or 64-bit machine: A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; +#endif + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_SIM_INCLUDE_TYPES_H */ diff --git a/arch/sim/src/.gitignore b/arch/sim/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e0d861c651e69a980b4e1222dcca239a003bd20f --- /dev/null +++ b/arch/sim/src/.gitignore @@ -0,0 +1,9 @@ +/Make.dep +/.depend +/Cygwin-names.dat +/Linux-names.dat +/nuttx.rel +/hostfs.h +/GNU +/chip +/board diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f4f6270660eb403cdef003aa527d023d01331df9 --- /dev/null +++ b/arch/sim/src/Makefile @@ -0,0 +1,297 @@ +############################################################################ +# arch/sim/src/Makefile +# +# Copyright (C) 2007, 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +CPPFLAGS += -I$(TOPDIR)/sched $(EXTRADEFINES) +CFLAGS += -I$(TOPDIR)/sched $(EXTRADEFINES) +CXXFLAGS += -I$(TOPDIR)/sched $(EXTRADEFINES) + +ASRCS = + +ifeq ($(CONFIG_HOST_X86_64),y) +ifeq ($(CONFIG_SIM_M32),y) + ASRCS += up_setjmp32.S +else + ASRCS += up_setjmp64.S +endif +else + ASRCS += up_setjmp32.S +endif + +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c +CSRCS += up_createstack.c up_usestack.c up_releasestack.c up_stackframe.c +CSRCS += up_unblocktask.c up_blocktask.c up_releasepending.c +CSRCS += up_reprioritizertr.c up_exit.c up_schedulesigaction.c up_spiflash.c +CSRCS += up_allocateheap.c up_devconsole.c + +HOSTSRCS = up_hostusleep.c + +ifeq ($(CONFIG_SCHED_TICKLESS),y) + CSRCS += up_tickless.c +endif + +ifeq ($(CONFIG_SPINLOCK),y) + HOSTSRCS += up_testset.c +endif + +ifeq ($(CONFIG_SMP),y) + CSRCS += up_smpsignal.c up_smphook.c + HOSTSRCS += up_simsmp.c +endif + +ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y) +ifneq ($(CONFIG_SCHED_INSTRUMENTATION_BUFFER),y) + CSRCS += up_schednote.c +endif +endif + +ifeq ($(CONFIG_DEV_CONSOLE),y) + CSRCS += up_uartwait.c + HOSTSRCS += up_simuart.c +endif + +ifeq ($(CONFIG_NX_LCDDRIVER),y) + CSRCS += board_lcd.c +else + CSRCS += up_framebuffer.c +ifeq ($(CONFIG_SIM_X11FB),y) + HOSTSRCS += up_x11framebuffer.c +ifeq ($(CONFIG_SIM_TOUCHSCREEN),y) + CSRCS += up_touchscreen.c + HOSTSRCS += up_x11eventloop.c +else +ifeq ($(CONFIG_SIM_AJOYSTICK),y) + CSRCS += up_ajoystick.c + HOSTSRCS += up_x11eventloop.c +endif +endif +endif +endif + +ifeq ($(CONFIG_ELF),y) + CSRCS += up_elf.c +endif + +ifeq ($(CONFIG_FS_FAT),y) + CSRCS += up_blockdevice.c up_deviceimage.c +endif + +ifeq ($(CONFIG_ARCH_ROMGETC),y) + CSRCS += up_romgetc.c +endif + +ifeq ($(CONFIG_NET_ETHERNET),y) + CSRCS += up_netdriver.c + HOSTCFLAGS += -DNETDEV_BUFSIZE=$(CONFIG_NET_ETH_MTU) +ifneq ($(HOSTOS),Cygwin) + HOSTSRCS += up_tapdev.c up_netdev.c +else + HOSTSRCS += up_wpcap.c up_netdev.c + DRVLIB = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a +endif +endif + +ifeq ($(CONFIG_SMP),y) + HOSTCFLAGS += -DCONFIG_SMP=1 -DCONFIG_SMP_NCPUS=$(CONFIG_SMP_NCPUS) +endif + +ifeq ($(CONFIG_FS_HOSTFS),y) + HOSTSRCS += up_hostfs.c + +up_hostfs.c: hostfs.h + +hostfs.h: $(TOPDIR)/include/nuttx/fs/hostfs.h + @echo "CP: $<" + $(Q) cp $< $@ +endif + +COBJS = $(CSRCS:.c=$(OBJEXT)) + +NUTTXOBJS = $(AOBJS) $(COBJS) +HOSTOBJS = $(HOSTSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(HOSTSRCS) +OBJS = $(AOBJS) $(COBJS) $(HOSTOBJS) + +# Determine which standard libraries will need to be linked in + +ifeq ($(CONFIG_SIM_X11FB),y) + STDLIBS += -lX11 -lXext +endif + +EXTRA_LIBS ?= +EXTRA_LIBPATHS ?= + +ifeq ($(CONFIG_FS_FAT),y) +STDLIBS += -lz +endif + +STDLIBS += -lc +STDLIBS += -lpthread + +# Determine which objects are required in the link. The +# up_head object normally draws in all that is needed, but +# there are a fews that must be included because they +# are called only from the host OS-specific logic (HOSTOBJS) + +LINKOBJS = up_head$(OBJEXT) +REQUIREDOBJS = $(LINKOBJS) + +ifeq ($(CONFIG_DEV_CONSOLE),y) + REQUIREDOBJS += up_uartwait$(OBJEXT) +endif + +ifeq ($(CONFIG_SIM_X11FB),y) +ifeq ($(CONFIG_SIM_TOUCHSCREEN),y) + REQUIREDOBJS += up_touchscreen$(OBJEXT) +endif +endif + +ifeq ($(CONFIG_SMP),y) + REQUIREDOBJS += up_smpsignal$(OBJEXT) up_smphook$(OBJEXT) +endif + +# Determine which NuttX libraries will need to be linked in +# Most are provided by LINKLIBS on the MAKE command line + +LINKLIBS ?= +RELLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +RELPATHS += -L"$(TOPDIR)/lib" + +# Add the board-specific library and directory + +LIBPATHS += -L board +RELPATHS += -L board +RELLIBS += -lboard + +# Make targets begin here + +all: up_head$(OBJEXT) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) export_startup clean distclean cleanrel depend + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(HOSTOBJS): %$(OBJEXT): %.c + $(Q) echo "CC: $<" + $(Q) "$(CC)" -c $(HOSTCFLAGS) $< -o $@ + +# The architecture-specific library + +libarch$(LIBEXT): $(NUTTXOBJS) + $(call ARCHIVE, $@, $(NUTTXOBJS)) + +# The "board"-specific library. Of course, there really are no boards in +# the simulation. However, this is a good place to keep parts of the simulation +# that are not hardware-related. + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +# A partially linked object containing only NuttX code (no interface to host OS) +# Change the names of most symbols that conflict with libc symbols. + +GNU: + $(Q) mkdir ./GNU + +GNU/Linux-names.dat: GNU nuttx-names.dat + $(Q) cp nuttx-names.dat $@ + +Cygwin-names.dat: nuttx-names.dat +ifeq ($())CONFIG_SIM_CYGWIN_DECORATED),y) + $(Q) cat $^ | sed -e "s/^/_/g" >$@ +else + $(Q) cp nuttx-names.dat $@ +endif + +nuttx.rel : libarch$(LIBEXT) board/libboard$(LIBEXT) $(HOSTOS)-names.dat $(LINKOBJS) + $(Q) echo "LD: nuttx.rel" + $(Q) $(LD) -r $(LDLINKFLAGS) $(RELPATHS) $(EXTRA_LIBPATHS) -o $@ $(REQUIREDOBJS) --start-group $(RELLIBS) $(EXTRA_LIBS) --end-group + $(Q) $(OBJCOPY) --redefine-syms=$(HOSTOS)-names.dat $@ + +# Generate the final NuttX binary by linking the host-specific objects with the NuttX +# specific objects (with munged names) + +nuttx$(EXEEXT): cleanrel nuttx.rel $(HOSTOBJS) + $(Q) echo "LD: nuttx$(EXEEXT)" + $(Q) "$(CC)" $(CCLINKFLAGS) $(LIBPATHS) -o $(TOPDIR)/$@ nuttx.rel $(HOSTOBJS) $(DRVLIB) $(STDLIBS) + $(Q) $(NM) $(TOPDIR)/$@ | \ + grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map + $(Q) rm -f nuttx.rel + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) up_head.o $(HOSTOBJS) + cp up_head.o $(HOSTOBJS) ${EXPORT_DIR}/startup + cp nuttx-names.dat ${EXPORT_DIR}/libs + echo main NXmain >> ${EXPORT_DIR}/libs/nuttx-names.dat + +# Dependencies + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +cleanrel: + $(Q) rm -f nuttx.rel GNU/Linux-names.dat Cygwin-names.dat + +clean: cleanrel + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ; \ + fi + $(call DELFILE, nuttx.rel) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ; \ + fi + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + $(call DELFILE, hostfs.h) + $(Q) rm -rf GNU + +-include Make.dep diff --git a/arch/sim/src/board_lcd.c b/arch/sim/src/board_lcd.c new file mode 100644 index 0000000000000000000000000000000000000000..94d0d6af876e3a8d0fb577905900da0e10263844 --- /dev/null +++ b/arch/sim/src/board_lcd.c @@ -0,0 +1,428 @@ +/**************************************************************************** + * arch/sim/src/board_lcd.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* Check contrast selection */ + +#if !defined(CONFIG_LCD_MAXCONTRAST) +# define CONFIG_LCD_MAXCONTRAST 100 +#endif + +/* Check power setting */ + +#if !defined(CONFIG_LCD_MAXPOWER) +# define CONFIG_LCD_MAXPOWER 100 +#endif + +/* Simulated LCD geometry and color format */ + +#ifndef CONFIG_SIM_FBWIDTH +# define CONFIG_SIM_FBWIDTH 320 /* Framebuffer width in pixels */ +#endif + +#ifndef CONFIG_SIM_FBHEIGHT +# define CONFIG_SIM_FBHEIGHT 240 /* Framebuffer height in pixels */ +#endif + +#ifndef CONFIG_SIM_FBBPP +# define CONFIG_SIM_FBBPP 16 /* Framebuffer bytes per pixel (RGB) */ +#endif + +#define FB_STRIDE ((CONFIG_SIM_FBBPP * CONFIG_SIM_FBWIDTH + 7) >> 3) + +#undef FB_FMT +#if CONFIG_SIM_FBBPP == 1 +# define FB_FMT FB_FMT_RGB1 +#elif CONFIG_SIM_FBBPP == 4 +# define FB_FMT FB_FMT_RGB4 +#elif CONFIG_SIM_FBBPP == 8 +# define FB_FMT FB_FMT_RGB8 +#elif CONFIG_SIM_FBBPP == 16 +# define FB_FMT FB_FMT_RGB16_565 +#elif CONFIG_SIM_FBBPP == 24 +# define FB_FMT FB_FMT_RGB24 +#elif CONFIG_SIM_FBBPP == 32 +# define FB_FMT FB_FMT_RGB32 +#else +# error "Unsupported BPP" +#endif + +/* Debug ********************************************************************/ +/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must + * also be enabled. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_GRAPHICS +# undef CONFIG_DEBUG_LCD +#endif + +#ifndef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_LCD +#endif + +#ifdef CONFIG_DEBUG_LCD +# define lcddbg(format, ...) vdbg(format, ##__VA_ARGS__) +#else +# define lcddbg(x...) +#endif + +/**************************************************************************** + * Private Type Definition + ****************************************************************************/ + +/* This structure describes the state of this driver */ + +struct sim_dev_s +{ + /* Publically visible device structure */ + + struct lcd_dev_s dev; + + /* Private LCD-specific information follows */ + + uint8_t power; /* Current power setting */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* LCD Data Transfer Methods */ + +static int sim_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, + size_t npixels); +static int sim_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, + size_t npixels); + +/* LCD Configuration */ + +static int sim_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo); +static int sim_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo); + +/* LCD RGB Mapping */ + +#ifdef CONFIG_FB_CMAP +# error "RGB color mapping not supported by this driver" +#endif + +/* Cursor Controls */ + +#ifdef CONFIG_FB_HWCURSOR +# error "Cursor control not supported by this driver" +#endif + +/* LCD Specific Controls */ + +static int sim_getpower(struct lcd_dev_s *dev); +static int sim_setpower(struct lcd_dev_s *dev, int power); +static int sim_getcontrast(struct lcd_dev_s *dev); +static int sim_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is working memory allocated by the LCD driver for each LCD device + * and for each color plane. This memory will hold one raster line of data. + * The size of the allocated run buffer must therefore be at least + * (bpp * xres / 8). Actual alignment of the buffer must conform to the + * bitwidth of the underlying pixel type. + * + * If there are multiple planes, they may share the same working buffer + * because different planes will not be operate on concurrently. However, + * if there are multiple LCD devices, they must each have unique run buffers. + */ + +static uint8_t g_runbuffer[FB_STRIDE]; + +/* This structure describes the overall LCD video controller */ + +static const struct fb_videoinfo_s g_videoinfo = +{ + .fmt = FB_FMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ + .xres = CONFIG_SIM_FBWIDTH, /* Horizontal resolution in pixel columns */ + .yres = CONFIG_SIM_FBHEIGHT, /* Vertical resolution in pixel rows */ + .nplanes = 1, /* Number of color planes supported */ +}; + +/* This is the standard, NuttX Plane information object */ + +static const struct lcd_planeinfo_s g_planeinfo = +{ + .putrun = sim_putrun, /* Put a run into LCD memory */ + .getrun = sim_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = CONFIG_SIM_FBBPP, /* Bits-per-pixel */ +}; + +/* This is the standard, NuttX LCD driver object */ + +static struct sim_dev_s g_lcddev = +{ + .dev = + { + /* LCD Configuration */ + + .getvideoinfo = sim_getvideoinfo, + .getplaneinfo = sim_getplaneinfo, + + /* LCD RGB Mapping -- Not supported */ + /* Cursor Controls -- Not supported */ + + /* LCD Specific Controls */ + + .getpower = sim_getpower, + .setpower = sim_setpower, + .getcontrast = sim_getcontrast, + .setcontrast = sim_setcontrast, + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_putrun + * + * Description: + * This method can be used to write a partial raster line to the LCD: + * + * row - Starting row to write to (range: 0 <= row < yres) + * col - Starting column to write to (range: 0 <= col <= xres-npixels) + * buffer - The buffer containing the run to be written to the LCD + * npixels - The number of pixels to write to the LCD + * (range: 0 < npixels <= xres-col) + * + ****************************************************************************/ + +static int sim_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, + size_t npixels) +{ + lcddbg("row: %d col: %d npixels: %d\n", row, col, npixels); + return OK; +} + +/**************************************************************************** + * Name: sim_getrun + * + * Description: + * This method can be used to read a partial raster line from the LCD: + * + * row - Starting row to read from (range: 0 <= row < yres) + * col - Starting column to read read (range: 0 <= col <= xres-npixels) + * buffer - The buffer in which to return the run read from the LCD + * npixels - The number of pixels to read from the LCD + * (range: 0 < npixels <= xres-col) + * + ****************************************************************************/ + +static int sim_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, + size_t npixels) +{ + lcddbg("row: %d col: %d npixels: %d\n", row, col, npixels); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sim_getvideoinfo + * + * Description: + * Get information about the LCD video controller configuration. + * + ****************************************************************************/ + +static int sim_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo) +{ + DEBUGASSERT(dev && vinfo); + gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", + g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); + memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); + return OK; +} + +/**************************************************************************** + * Name: sim_getplaneinfo + * + * Description: + * Get information about the configuration of each LCD color plane. + * + ****************************************************************************/ + +static int sim_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo) +{ + DEBUGASSERT(dev && pinfo && planeno == 0); + gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); + memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); + return OK; +} + +/**************************************************************************** + * Name: sim_getpower + * + * Description: + * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: + * full on). On backlit LCDs, this setting may correspond to the backlight setting. + * + ****************************************************************************/ + +static int sim_getpower(struct lcd_dev_s *dev) +{ + gvdbg("power: %d\n", 0); + return g_lcddev.power; +} + +/**************************************************************************** + * Name: sim_setpower + * + * Description: + * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: + * full on). On backlit LCDs, this setting may correspond to the backlight + * setting. + * + ****************************************************************************/ + +static int sim_setpower(struct lcd_dev_s *dev, int power) +{ + gvdbg("power: %d\n", power); + DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER); + + /* Set new power level */ + + g_lcddev.power = power; + return OK; +} + +/**************************************************************************** + * Name: sim_getcontrast + * + * Description: + * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). + * + ****************************************************************************/ + +static int sim_getcontrast(struct lcd_dev_s *dev) +{ + gvdbg("Not implemented\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Name: sim_setcontrast + * + * Description: + * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). + * + ****************************************************************************/ + +static int sim_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) +{ + gvdbg("contrast: %d\n", contrast); + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_lcd_initialize + * + * Description: + * Initialize the LCD video hardware. The initial state of the LCD is + * fully initialized, display memory cleared, and the LCD ready to use, + * but with the power setting at 0 (full off). + * + ****************************************************************************/ + +int board_lcd_initialize(void) +{ + gvdbg("Initializing\n"); + return OK; +} + +/**************************************************************************** + * Name: board_lcd_getdev + * + * Description: + * Return a a reference to the LCD object for the specified LCD. This + * allows support for multiple LCD devices. + * + ****************************************************************************/ + +FAR struct lcd_dev_s *board_lcd_getdev(int lcddev) +{ + DEBUGASSERT(lcddev == 0); + return &g_lcddev.dev; +} + +/**************************************************************************** + * Name: board_lcd_uninitialize + * + * Description: + * Unitialize the LCD support + * + ****************************************************************************/ + +void board_lcd_uninitialize(void) +{ +} diff --git a/arch/sim/src/nuttx-names.dat b/arch/sim/src/nuttx-names.dat new file mode 100644 index 0000000000000000000000000000000000000000..698df01576456dcaff25f3eff6b718684281ae42 --- /dev/null +++ b/arch/sim/src/nuttx-names.dat @@ -0,0 +1,77 @@ +accept NXaccept +calloc NXcalloc +clock_gettime NXclock_gettime +close NXclose +closedir NXclosedir +dup NXdup +free NXfree +fclose NXfclose +fopen NXfopen +fputc NXfputc +fcntl NXfcntl +fputs NXfputs +fread NXfread +fwrite NXfwrite +fsync NXfsync +getenv NXgetenv +gettimeofday NXgettimeofday +ioctl NXioctl +isatty NXisatty +listen NXlisten +lseek NXlseek +malloc NXmalloc +malloc_init NXmalloc_init +mkdir NXmkdir +mount NXmount +open NXopen +opendir NXopendir +nanosleep NXnanosleep +poll NXpoll +printf NXprintf +pthread_create NXpthread_create +pthread_getspecific NXpthread_getspecific +pthread_key_create NXpthread_key_create +pthread_kill NXpthread_kill +pthread_join NXpthread_join +pthread_mutex_destroy NXpthread_mutex_destroy +pthread_mutex_init NXpthread_mutex_init +pthread_mutex_lock NXpthread_mutex_lock +pthread_mutex_unlock NXpthread_mutex_unlock +pthread_setspecific NXpthread_setspecific +pthread_sigmask NXpthread_sigmask +pthread_yield NXpthread_yield +puts NXputs +read NXread +readdir NXreaddir +realloc NXrealloc +recv NXrecv +recvfrom NXrecvfrom +rewinddir NXrewinddir +rmdir NXrmdir +sched_yield NXsched_yield +seekdir NXseekdir +select NXselect +sem_init NXsem_init +sem_post NXsem_post +sem_wait NXsem_wait +send NXsend +sendto NXsendto +setsockopt NXsetsockopt +sigaction NXsigaction +sighold NXsighold +sigprocmask NXsigprocmask +sigtimedwait NXsigtimedwait +sigrelse NXsigrelse +sleep NXsleep +socket NXsocket +stat NXstat +statfs NXstatfs +system NXsystem +tcgetattr NXtcgetattr +tcsetattr NXtcsetattr +umount2 NXumount2 +unlink NXunlink +usleep NXusleep +vfork NXvfork +write NXwrite +zmalloc NXzmalloc diff --git a/arch/sim/src/up_ajoystick.c b/arch/sim/src/up_ajoystick.c new file mode 100644 index 0000000000000000000000000000000000000000..6fc82c98a6944c182cda126c901beb5b3ff3869c --- /dev/null +++ b/arch/sim/src/up_ajoystick.c @@ -0,0 +1,257 @@ +/**************************************************************************** + * arch/sim/src/up_ajoystick.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_AJOYSTICK + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +# define AJOY_SUPPORTED (AJOY_BUTTON_1_BIT | AJOY_BUTTON_2_BIT | \ + AJOY_BUTTON_3_BIT) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ajoy_buttonset_t ajoy_supported(FAR const struct ajoy_lowerhalf_s *lower); +static int ajoy_sample(FAR const struct ajoy_lowerhalf_s *lower, + FAR struct ajoy_sample_s *sample); +static ajoy_buttonset_t ajoy_buttons(FAR const struct ajoy_lowerhalf_s *lower); +static void ajoy_enable(FAR const struct ajoy_lowerhalf_s *lower, + ajoy_buttonset_t press, ajoy_buttonset_t release, + ajoy_handler_t handler, FAR void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the button joystick lower half driver interface */ + +static const struct ajoy_lowerhalf_s g_ajoylower = +{ + .al_supported = ajoy_supported, + .al_sample = ajoy_sample, + .al_buttons = ajoy_buttons, + .al_enable = ajoy_enable, +}; + +/* Driver state data */ + +static bool g_ajoy_valid; /* True: Sample data is valid */ +static struct ajoy_sample_s g_ajoy_sample; /* Last sample data */ +static ajoy_buttonset_t g_ajoy_buttons; /* Last buttons set */ + +static ajoy_handler_t g_ajoy_handler; /* "Interrupt" handler */ +static void *g_ajoy_arg; /* Handler argument */ +static ajoy_buttonset_t g_ajoy_pset; /* Set of press waited for */ +static ajoy_buttonset_t g_ajoy_rset; /* Set of releases waited for */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ajoy_supported + * + * Description: + * Return the set of buttons supported on the button joystick device + * + ****************************************************************************/ + +static ajoy_buttonset_t ajoy_supported(FAR const struct ajoy_lowerhalf_s *lower) +{ + return (ajoy_buttonset_t)AJOY_SUPPORTED; +} + +/**************************************************************************** + * Name: ajoy_sample + * + * Description: + * Return the current state of all button joystick buttons + * + ****************************************************************************/ + +static int ajoy_sample(FAR const struct ajoy_lowerhalf_s *lower, + FAR struct ajoy_sample_s *sample) +{ + memcpy(sample, &g_ajoy_sample, sizeof(struct ajoy_sample_s)); + g_ajoy_buttons = g_ajoy_sample.as_buttons; + g_ajoy_valid = false; + return OK; +} + +/**************************************************************************** + * Name: ajoy_buttons + * + * Description: + * Return the current state of button data (only) + * + ****************************************************************************/ + +static ajoy_buttonset_t ajoy_buttons(FAR const struct ajoy_lowerhalf_s *lower) +{ + g_ajoy_valid = false; + g_ajoy_buttons = g_ajoy_sample.as_buttons; + return g_ajoy_buttons; +} + +/**************************************************************************** + * Name: ajoy_enable + * + * Description: + * Enable interrupts on the selected set of joystick buttons. And empty + * set will disable all interrupts. + * + ****************************************************************************/ + +static void ajoy_enable(FAR const struct ajoy_lowerhalf_s *lower, + ajoy_buttonset_t press, ajoy_buttonset_t release, + ajoy_handler_t handler, FAR void *arg) +{ + g_ajoy_handler = NULL; + g_ajoy_pset = press; + g_ajoy_rset = release; + g_ajoy_arg = arg; + g_ajoy_handler = handler; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_ajoy_initialize + * + * Description: + * Initialize and register the button joystick driver + * + ****************************************************************************/ + +int sim_ajoy_initialize(void) +{ + int ret; + + /* Register the joystick device as /dev/ajoy0 */ + + ret = ajoy_register("/dev/ajoy0", &g_ajoylower); + if (ret == OK) + { + /* Enable X11 event processing from the IDLE loop */ + + g_eventloop = 1; + } + + return ret; +} + +/**************************************************************************** + * Name: up_buttonevent + ****************************************************************************/ + +int up_buttonevent(int x, int y, int buttons) +{ + ajoy_buttonset_t changed; + ajoy_buttonset_t pressed; + ajoy_buttonset_t released; + + /* Same the positional data */ + + g_ajoy_sample.as_x = x; + g_ajoy_sample.as_y = y; + + /* Map X11 buttons to joystick buttons */ + + g_ajoy_sample.as_buttons = 0; + if ((buttons & 1) != 0) + { + g_ajoy_sample.as_buttons |= AJOY_BUTTON_1_BIT; + } + + if ((buttons & 2) != 0) + { + g_ajoy_sample.as_buttons |= AJOY_BUTTON_2_BIT; + } + + if ((buttons & 4) != 0) + { + g_ajoy_sample.as_buttons |= AJOY_BUTTON_3_BIT; + } + + /* Sample data is valid */ + + g_ajoy_valid = true; + + /* Is there an "interrupt" handler attached? */ + + if (g_ajoy_handler) + { + /* Check button presses */ + + changed = g_ajoy_buttons ^ g_ajoy_sample.as_buttons; + if (changed != 0) + { + pressed = changed & (AJOY_SUPPORTED & g_ajoy_pset); + released = changed & (AJOY_SUPPORTED & ~g_ajoy_rset); + if ((pressed & g_ajoy_pset) != 0 || (released & g_ajoy_rset) != 0) + { + /* Call the interrupt handler */ + + g_ajoy_handler(&g_ajoylower, g_ajoy_arg); + } + } + } + + return OK; +} + +#endif /* CONFIG_AJOYSTICK */ diff --git a/arch/sim/src/up_allocateheap.c b/arch/sim/src/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..108e74f4cf92eb553a69276e8be23ece3dde82b7 --- /dev/null +++ b/arch/sim/src/up_allocateheap.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * arch/sim/src/up_allocateheap.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t sim_heap[SIM_HEAP_SIZE]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(void **heap_start, size_t *heap_size) +{ + *heap_start = sim_heap; + *heap_size = SIM_HEAP_SIZE; +} diff --git a/arch/sim/src/up_blockdevice.c b/arch/sim/src/up_blockdevice.c new file mode 100644 index 0000000000000000000000000000000000000000..066df0a1dfef23d4eabab29ca1dcd3d659162632 --- /dev/null +++ b/arch/sim/src/up_blockdevice.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/sim/src/up_blockdevice.c + * + * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NSECTORS 2048 +#define LOGICAL_SECTOR_SIZE 512 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_registerblockdevice + * + * Description: Register the FAT ramdisk + * + ****************************************************************************/ + +void up_registerblockdevice(void) +{ + ramdisk_register(0, (FAR uint8_t *)up_deviceimage(), NSECTORS, + LOGICAL_SECTOR_SIZE, RDFLAG_WRENABLED | RDFLAG_FUNLINK); +} diff --git a/arch/sim/src/up_blocktask.c b/arch/sim/src/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..ccc39204896f78461f88f906752c6a8b3276406f --- /dev/null +++ b/arch/sim/src/up_blocktask.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/sim/src/up_blocktask.c + * + * Copyright (C) 2007-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + sdbg("Blocking TCB=%p\n", tcb); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_setjmp returns a non-zero + * value, then this is really the previously running task restarting! + */ + + if (!up_setjmp(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + sdbg("New Active Task TCB=%p\n", rtcb); + + /* The way that we handle signals in the simulation is kind of + * a kludge. This would be unsafe in a truly multi-threaded, interrupt + * driven environment. + */ + + if (rtcb->xcp.sigdeliver) + { + sdbg("Delivering signals TCB=%p\n", rtcb); + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + rtcb->xcp.sigdeliver = NULL; + } + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_longjmp(rtcb->xcp.regs, 1); + } + } +} diff --git a/arch/sim/src/up_createstack.c b/arch/sim/src/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..d7438e0edc239777b244f122aa3f92f62408f95e --- /dev/null +++ b/arch/sim/src/up_createstack.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * arch/sim/src/up_createstack.c + * + * Copyright (C) 2007-2009, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + uint32_t *stack_alloc_ptr; + int ret = ERROR; + +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif + + /* Move up to next even word boundary if necessary */ + + size_t adj_stack_size = (stack_size + 3) & ~3; + size_t adj_stack_words = adj_stack_size >> 2; + + /* Allocate the memory for the stack */ + +#ifdef CONFIG_TLS + stack_alloc_ptr = (FAR uint32_t *)kumm_memalign(TLS_STACK_ALIGN, adj_stack_size); +#else /* CONFIG_TLS */ + stack_alloc_ptr = (FAR uint32_t *)kumm_malloc(adj_stack_size); +#endif /* CONFIG_TLS */ + + /* Was the allocation successful? */ + + if (stack_alloc_ptr) + { + /* This is the address of the last word in the allocation */ + + FAR void *adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1]; + + /* Save the values in the TCB */ + + tcb->adj_stack_size = adj_stack_size; + tcb->stack_alloc_ptr = stack_alloc_ptr; + tcb->adj_stack_ptr = adj_stack_ptr; + +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + + ret = OK; + } + + return ret; +} diff --git a/arch/sim/src/up_devconsole.c b/arch/sim/src/up_devconsole.c new file mode 100644 index 0000000000000000000000000000000000000000..cc863a227ca7b5a59149b9b2f705b3ec6e3896e4 --- /dev/null +++ b/arch/sim/src/up_devconsole.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * arch/sim/src/up_devconsole.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t devconsole_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t devconsole_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen); +#ifndef CONFIG_DISABLE_POLL +static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations devconsole_fops = +{ + .read = devconsole_read, + .write = devconsole_write, +#ifndef CONFIG_DISABLE_POLL + .poll = devconsole_poll, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: devconsole_read + ****************************************************************************/ + +static ssize_t devconsole_read(struct file *filep, char *buffer, size_t len) +{ + size_t remaining = len; + ssize_t nread; + int ch; + + /* Loop until all requested bytes have been read. No error checking */ + + sched_lock(); + for (remaining = len, nread = 0; remaining > 0; remaining--) + { + /* Read the next character from the console, we should only wait + * on the first read. + */ + + ch = simuart_getc(); + if (ch < 0) + { + set_errno(EIO); + sched_unlock(); + return ERROR; + } + + *buffer++ = ch; + nread++; + + /* We have at least one character. Return now if no further + * characters are available without waiting. + */ + + if (!simuart_checkc()) + { + break; + } + } + + sched_unlock(); + return nread; +} + +/**************************************************************************** + * Name: devconsole_write + ****************************************************************************/ + +static ssize_t devconsole_write(struct file *filep, const char *buffer, size_t len) +{ + int remaining; + int ret = OK; + + for (remaining = len; remaining > 0 && ret >= 0; remaining--) + { + unsigned char ch = *buffer++; + ret = simuart_putc((int)ch); + } + + if (ret < 0) + { + set_errno(EIO); + return ERROR; + } + + return len; +} + +/**************************************************************************** + * Name: devconsole_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_devconsole + ****************************************************************************/ + +void up_devconsole(void) +{ + (void)register_driver("/dev/console", &devconsole_fops, 0666, NULL); +} + +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Just map to the host simuart_putc routine */ + + return simuart_putc(ch); +} + diff --git a/arch/sim/src/up_deviceimage.c b/arch/sim/src/up_deviceimage.c new file mode 100644 index 0000000000000000000000000000000000000000..f50944bd2e1e9772811fdd8ac7108e6c3060b31c --- /dev/null +++ b/arch/sim/src/up_deviceimage.c @@ -0,0 +1,368 @@ +/**************************************************************************** + * arch/sim/src/up_deviceimage.c + * + * Copyright (C) 2007, 2009, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifdef VFAT_STANDALONE +# include +# include +# include +#else +# include + +# include +# include +# include + +# include + +# include "up_internal.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef VFAT_STANDALONE +# define sdbg(format, ...) printf(format, ##__VA_ARGS__) +# define kmm_malloc(size) malloc(size) +# define kmm_free(mem) free(mem) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array holds a compressed VFAT file system created with: + * + * /sbin/mkdosfs -C -F 32 -I -n "NuttXTestVol" -S 512 -v nuttx-test.vfat 1024 + * sudo mkdir /mnt/loop + * sudo mount -o loop nuttx-test.vfat /mnt/loop + * mkdir /mnt/loop/TestDir + * echo "This is a test" >/mnt/loop/TestDir/TestFile.txt + * sudo umount /mnt/loop + * gzip nuttx-test.vfat + * xxd -g 1 nuttx-test.vfat.gz >some-file + * + * Then manually massaged from the gzip xxd output to zlib format. See + * http://www.faqs.org/rfcs/rfc1952.html. This amounts to: + * + * Remove all of the leading bytes through the null terminator of the file name + * Remove the last 8 bytes + * Add 0x08, 0x1d to the beginning. + */ + +static const unsigned char g_vfatdata[] = +{ + 0x08, 0x1d, 0xed, 0xdd, 0xcf, 0x6a, 0x13, 0x41, 0x18, 0x00, 0xf0, 0xa9, 0x16, 0x5b, 0x2a, 0x6d, + 0x73, 0x12, 0x3c, 0x39, 0x78, 0xf3, 0xb2, 0x87, 0x0a, 0x3d, 0x78, 0x32, 0xd0, 0x06, 0x0a, 0xa2, + 0xa5, 0xa6, 0xa5, 0x17, 0x95, 0x2d, 0xd9, 0x6a, 0x68, 0x4c, 0xda, 0xec, 0x8a, 0x2d, 0x78, 0xf3, + 0x01, 0xf4, 0x39, 0x8a, 0xb7, 0x7a, 0x13, 0xc5, 0x17, 0xe8, 0x5b, 0x78, 0xcb, 0xc5, 0x63, 0x4f, + 0xc6, 0x8d, 0x69, 0x8b, 0x45, 0xc4, 0x3f, 0x20, 0x51, 0xfc, 0xfd, 0xd8, 0xe1, 0xdb, 0xd9, 0x8f, + 0x81, 0x59, 0xe6, 0x63, 0x59, 0xd8, 0x85, 0xe9, 0xad, 0xbf, 0x7c, 0xbc, 0xd5, 0xe8, 0xe4, 0x9b, + 0x79, 0x08, 0xe7, 0xc6, 0x62, 0x38, 0x17, 0x42, 0x98, 0x3c, 0x0a, 0x21, 0x86, 0x9b, 0xe1, 0x44, + 0xe5, 0x38, 0x0e, 0x72, 0x63, 0xe1, 0x42, 0x38, 0xeb, 0xda, 0xf2, 0xbd, 0x3b, 0xb5, 0xdb, 0x4f, + 0x8a, 0x62, 0xbd, 0x9e, 0xe5, 0xc5, 0x5a, 0xa7, 0x56, 0xad, 0x5f, 0x9f, 0x8b, 0x31, 0xce, 0x5c, + 0x79, 0xf7, 0xf4, 0xd9, 0xab, 0xab, 0xef, 0x8b, 0x8b, 0x6b, 0xaf, 0x67, 0xde, 0x4c, 0x84, 0xc3, + 0xca, 0xfd, 0xde, 0xc7, 0xb9, 0x0f, 0x87, 0x97, 0x0e, 0x2f, 0xf7, 0x3e, 0xd5, 0x1f, 0x35, 0xf3, + 0x58, 0x1e, 0xed, 0x4e, 0x11, 0xd3, 0xb8, 0xd1, 0xe9, 0x14, 0xe9, 0x46, 0x2b, 0x8b, 0x8d, 0x66, + 0xbe, 0x95, 0xc4, 0xb8, 0xdc, 0xca, 0xd2, 0x3c, 0x8b, 0xcd, 0x76, 0x9e, 0x75, 0xcf, 0xe4, 0x37, + 0x5b, 0x9d, 0xed, 0xed, 0xbd, 0x98, 0xb6, 0x1b, 0xd3, 0x53, 0xdb, 0xdd, 0x2c, 0xcf, 0xcb, 0xd3, + 0xbd, 0xb8, 0x95, 0xed, 0xc5, 0xa2, 0x13, 0x8b, 0x6e, 0x99, 0x79, 0x98, 0x36, 0xdb, 0x31, 0x49, + 0x92, 0x38, 0x3d, 0x15, 0xf8, 0x91, 0xd5, 0xfd, 0x95, 0x95, 0xb4, 0x3a, 0xea, 0x59, 0xf0, 0x67, + 0x75, 0xbb, 0xd5, 0xf4, 0xed, 0x44, 0x08, 0xe3, 0xdf, 0x64, 0x56, 0xf7, 0x47, 0x30, 0x1d, 0x00, + 0x60, 0xc4, 0x7a, 0xde, 0xff, 0xff, 0x63, 0xde, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x76, 0x47, 0xfd, 0xfe, 0x6c, 0xbf, 0x6c, 0x27, 0x71, 0xd0, + 0x46, 0x3d, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xd7, 0xf8, 0xfe, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xbe, 0xaf, 0x36, 0xee, 0x9c, 0x0c, 0xe1, 0xc6, 0xf3, + 0x83, 0xf9, 0x83, 0xf9, 0x61, 0x1c, 0xe6, 0xab, 0xf5, 0x90, 0x85, 0x3c, 0x14, 0x61, 0x21, 0xcc, + 0x86, 0x07, 0xcd, 0xd0, 0x2d, 0xaf, 0xf5, 0xbf, 0x18, 0xc6, 0xfa, 0xe2, 0xdd, 0xfa, 0xc2, 0xd2, + 0x4a, 0x2c, 0x55, 0x42, 0xe3, 0xc5, 0xf1, 0xf8, 0x41, 0x3c, 0x3f, 0xd2, 0xfb, 0xe2, 0xe7, 0x24, + 0xf1, 0x54, 0x25, 0x84, 0x9d, 0xe3, 0xf5, 0xdb, 0x39, 0x5d, 0xbf, 0x24, 0xf9, 0x5e, 0x7e, 0x38, + 0xfe, 0xb4, 0x3e, 0x6a, 0x65, 0x7d, 0xec, 0x36, 0x43, 0xab, 0xec, 0x26, 0x65, 0x77, 0xb7, 0xcc, + 0x15, 0x65, 0x1b, 0xd4, 0x47, 0x6d, 0xe9, 0xd6, 0x62, 0x7d, 0xbd, 0x1e, 0xcf, 0xd6, 0xc7, 0x78, + 0xf0, 0xa3, 0xc9, 0xe8, 0x9d, 0x6c, 0xc4, 0x9b, 0xc6, 0xa2, 0x7c, 0x08, 0xd8, 0x33, 0x17, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x77, 0x7d, 0x06 +}; + + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_deviceimage + * + * Description: Return an allocated buffer representing an in-memory VFAT + * file system. + * + ****************************************************************************/ + +char *up_deviceimage(void) +{ + char *pbuffer; + int bufsize = 1024*1024; + int offset = 0; + z_stream strm; + int ret; + + /* Initialize inflate state */ + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + { + sdbg("inflateInit FAILED: ret=%d msg=\"%s\"\n", + ret, strm.msg ? strm.msg : "No message"); + return NULL; + } + + /* Allocate a buffer to hold the decompressed buffer. We may have to + * reallocate this a few times to get the size right. + */ + + pbuffer = (char *)kmm_malloc(bufsize); + + /* Set up the input buffer */ + + strm.avail_in = sizeof(g_vfatdata); + strm.next_in = (Bytef *)g_vfatdata; + + /* Run inflate() on input until output buffer not full */ + + do + { + /* Set up to catch the next output chunk in the output buffer */ + + strm.avail_out = bufsize - offset; + strm.next_out = (Bytef *)&pbuffer[offset]; + + /* inflate */ + + ret = inflate(&strm, Z_NO_FLUSH); + + /* Handle inflate() error return values */ + + switch (ret) + { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + case Z_STREAM_ERROR: + sdbg("inflate FAILED: ret=%d msg=\"%s\"\n", + ret, strm.msg ? strm.msg : "No message"); + (void)inflateEnd(&strm); + kmm_free(pbuffer); + return NULL; + } + + /* If avail_out is zero, then inflate() returned only because it is + * out of buffer space. In this case, we will have to reallocate + * the buffer and try again. + */ + + if (strm.avail_out == 0) + { + int newbufsize = bufsize + 128 * 1024; + char *newbuffer = kmm_realloc(pbuffer, newbufsize); + if (!newbuffer) + { + kmm_free(pbuffer); + return NULL; + } + else + { + pbuffer = newbuffer; + offset = bufsize; + bufsize = newbufsize; + } + } + else + { + /* There are unused bytes in the buffer, reallocate to + * correct size. + */ + + int newbufsize = bufsize - strm.avail_out; + char *newbuffer = kmm_realloc(pbuffer, newbufsize); + if (!newbuffer) + { + kmm_free(pbuffer); + return NULL; + } + else + { + pbuffer = newbuffer; + bufsize = newbufsize; + } + } + } + while (strm.avail_out == 0 && ret != Z_STREAM_END); + + (void)inflateEnd(&strm); + return pbuffer; +} + +/**************************************************************************** + * Name: main + * + * Description: Used to test decompression logic + * + * gcc -g -Wall -DVFAT_STANDALONE -lz -o vfat-test up_deviceimage.c + * + ****************************************************************************/ + +#ifdef VFAT_STANDALONE +int main(int argc, char **argv, char **envp) +{ + char *deviceimage; + int cmf; + int fdict; + int flg; + int check; + + cmf = g_vfatdata[0]; + printf("CMF=%02x: CM=%d CINFO=%d\n", cmf, cmf &0x0f, cmf >> 4); + + flg = g_vfatdata[1]; + fdict = (flg >> 5) & 1; + + printf("FLG=%02x: FCHECK=%d FDICT=%d FLEVEL=%d\n", + flg, flg &0x1f, fdict, flg >> 6); + + /* The FCHECK value must be such that CMF and FLG, when viewed as + * a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + * is a multiple of 31. + */ + + check = cmf*256 + flg; + if (check % 31 != 0) + { + printf("Fails check: %04x is not a multiple of 31\n", check); + } + + deviceimage = up_deviceimage(); + if (deviceimage) + { + printf("Inflate SUCCEEDED\n"); + kmm_free(deviceimage); + return 0; + } + else + { + printf("Inflate FAILED\n"); + return 1; + } +} +#endif diff --git a/arch/sim/src/up_elf.c b/arch/sim/src/up_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..ecc4f2d2fee18f22d11de17e5ad2c308ee4a5466 --- /dev/null +++ b/arch/sim/src/up_elf.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/sim/src/up_elf.c + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define R_386_32 1 +#define R_386_PC32 2 + +#define ELF_BITS 32 +#define ELF_ARCH EM_386 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *hdr) +{ + return hdr->e_machine == EM_386 || hdr->e_machine == EM_486; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + FAR uint32_t *ptr = (FAR uint32_t *)addr; + + /* All relocations depend upon having valid symbol information. */ + + if (sym == NULL) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (ELF32_R_TYPE(rel->r_info)) + { + case R_386_32: + *ptr += sym->st_value; + break; + + case R_386_PC32: + *ptr += sym->st_value - (uint32_t)ptr; + break; + + default: + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("Not supported\n"); + return -ENOSYS; +} + diff --git a/arch/sim/src/up_exit.c b/arch/sim/src/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..a022405d762deab1395f3804e2f65c425f427ebb --- /dev/null +++ b/arch/sim/src/up_exit.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/sim/src/up_exit.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "task/task.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + FAR struct tcb_s *tcb; + + sdbg("TCB=%p exiting\n", tcb); + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + sdbg("New Active Task TCB=%p\n", tcb); + + /* The way that we handle signals in the simulation is kind of + * a kludge. This would be unsafe in a truly multi-threaded, interrupt + * driven environment. + */ + + if (tcb->xcp.sigdeliver) + { + sdbg("Delivering signals TCB=%p\n", tcb); + ((sig_deliver_t)tcb->xcp.sigdeliver)(tcb); + tcb->xcp.sigdeliver = NULL; + } + + /* Then switch contexts */ + + up_longjmp(tcb->xcp.regs, 1); +} + diff --git a/arch/sim/src/up_framebuffer.c b/arch/sim/src/up_framebuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..15a8168e6d8183730bcca9137a1bb53413ff11d7 --- /dev/null +++ b/arch/sim/src/up_framebuffer.c @@ -0,0 +1,395 @@ +/**************************************************************************** + * arch/sim/src/up_framebuffer.c + * + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SIM_FBWIDTH +# define CONFIG_SIM_FBWIDTH 480 /* Framebuffer width in pixels */ +#endif + +#ifndef CONFIG_SIM_FBHEIGHT +# define CONFIG_SIM_FBHEIGHT 240 /* Framebuffer height in pixels */ +#endif + +#ifndef CONFIG_SIM_FBBPP +# define CONFIG_SIM_FBBPP 16 /* Framebuffer bytes per pixel (RGB) */ +#endif + +#undef FB_FMT +#if CONFIG_SIM_FBBPP == 1 +# define FB_FMT FB_FMT_RGB1 +#elif CONFIG_SIM_FBBPP == 4 +# define FB_FMT FB_FMT_RGB4 +#elif CONFIG_SIM_FBBPP == 8 +# define FB_FMT FB_FMT_RGB8 +#elif CONFIG_SIM_FBBPP == 16 +# define FB_FMT FB_FMT_RGB16_565 +#elif CONFIG_SIM_FBBPP == 24 +# define FB_FMT FB_FMT_RGB24 +#elif CONFIG_SIM_FBBPP == 32 +# define FB_FMT FB_FMT_RGB32 +#else +# error "Unsupported BPP" +#endif + +/* Framebuffer characteristics in bytes */ + +#define FB_WIDTH ((CONFIG_SIM_FBWIDTH * CONFIG_SIM_FBBPP + 7) / 8) +#define FB_SIZE (FB_WIDTH * CONFIG_SIM_FBHEIGHT) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + + /* Get information about the video controller configuration and the configuration + * of each color plane. + */ + +static int up_getvideoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo); +static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo); + + /* The following is provided only if the video hardware supports RGB color mapping */ + +#ifdef CONFIG_FB_CMAP +static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap); +static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap); +#endif + /* The following is provided only if the video hardware supports a hardware cursor */ + +#ifdef CONFIG_FB_HWCURSOR +static int up_getcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_cursorattrib_s *attrib); +static int up_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_s *setttings); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The simulated framebuffer memory */ + +#ifndef CONFIG_SIM_X11FB +static uint8_t g_fb[FB_SIZE]; +#endif + +/* This structure describes the simulated video controller */ + +static const struct fb_videoinfo_s g_videoinfo = +{ + .fmt = FB_FMT, + .xres = CONFIG_SIM_FBWIDTH, + .yres = CONFIG_SIM_FBHEIGHT, + .nplanes = 1, +}; + +#ifndef CONFIG_SIM_X11FB +/* This structure describes the single, simulated color plane */ + +static const struct fb_planeinfo_s g_planeinfo = +{ + .fbmem = (FAR void *)&g_fb, + .fblen = FB_SIZE, + .stride = FB_WIDTH, + .bpp = CONFIG_SIM_FBBPP, +}; +#else +/* This structure describes the single, X11 color plane */ + +static struct fb_planeinfo_s g_planeinfo; +#endif + +/* Current cursor position */ + +#ifdef CONFIG_FB_HWCURSOR +static struct fb_cursorpos_s g_cpos; + +/* Current cursor size */ + +#ifdef CONFIG_FB_HWCURSORSIZE +static struct fb_cursorsize_s g_csize; +#endif +#endif + +/* The framebuffer object -- There is no private state information in this simple + * framebuffer simulation. + */ + +struct fb_vtable_s g_fbobject = +{ + .getvideoinfo = up_getvideoinfo, + .getplaneinfo = up_getplaneinfo, +#ifdef CONFIG_FB_CMAP + .getcmap = up_getcmap, + .putcmap = up_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + .getcursor = up_getcursor, + .setcursor = up_setcursor, +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getvideoinfo + ****************************************************************************/ + +static int up_getvideoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ + dbg("vtable=%p vinfo=%p\n", vtable, vinfo); + if (vtable && vinfo) + { + memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: up_getplaneinfo + ****************************************************************************/ + +static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ + dbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo); + if (vtable && planeno == 0 && pinfo) + { + memcpy(pinfo, &g_planeinfo, sizeof(struct fb_planeinfo_s)); + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: up_getcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap) +{ + int len; + int i; + + dbg("vtable=%p cmap=%p len=%d\n", vtable, cmap, cmap->len); + if (vtable && cmap) + { + for (i = cmap->first, len = 0; i < 256 && len < cmap->len; i++, len++) + { + cmap->red[i] = i; + cmap->green[i] = i; + cmap->blue[i] = i; +#ifdef CONFIG_FB_TRANSPARENCY + cmap->transp[i] = i; +#endif + } + + cmap->len = len; + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: up_putcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap) +{ +#ifdef CONFIG_SIM_X11FB + return up_x11cmap(cmap->first, cmap->len, cmap->red, cmap->green, cmap->blue, NULL); +#else + dbg("vtable=%p cmap=%p len=%d\n", vtable, cmap, cmap->len); + if (vtable && cmap) + { + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +#endif +} +#endif + +/**************************************************************************** + * Name: up_getcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int up_getcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_cursorattrib_s *attrib) +{ + dbg("vtable=%p attrib=%p\n", vtable, attrib); + if (vtable && attrib) + { +#ifdef CONFIG_FB_HWCURSORIMAGE + attrib->fmt = FB_FMT; +#endif + dbg("pos: (x=%d, y=%d)\n", g_cpos.x, g_cpos.y); + attrib->pos = g_cpos; +#ifdef CONFIG_FB_HWCURSORSIZE + attrib->mxsize.h = CONFIG_SIM_FBHEIGHT; + attrib->mxsize.w = CONFIG_SIM_FBWIDTH; + dbg("size: (h=%d, w=%d)\n", g_csize.h, g_csize.w); + attrib->size = g_csize; +#endif + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int up_setcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_setcursor_s *setttings) +{ + dbg("vtable=%p setttings=%p\n", vtable, setttings); + if (vtable && setttings) + { + dbg("flags: %02x\n", settings->flags); + if ((flags & FB_CUR_SETPOSITION) != 0) + { + g_cpos = settings->pos; + dbg("pos: (h:%d, w:%d)\n", g_cpos.x, g_cpos.y); + } +#ifdef CONFIG_FB_HWCURSORSIZE + if ((flags & FB_CUR_SETSIZE) != 0) + { + g_csize = settings->size; + dbg("size: (h:%d, w:%d)\n", g_csize.h, g_csize.w); + } +#endif +#ifdef CONFIG_FB_HWCURSORIMAGE + if ((flags & FB_CUR_SETIMAGE) != 0) + { + dbg("image: (h:%d, w:%d) @ %p\n", + settings->img.height, settings->img.width, settings->img.image); + } +#endif + return OK; + } + dbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fbinitialize + * + * Description: + * Initialize the video hardware + * + ****************************************************************************/ + +int up_fbinitialize(void) +{ +#ifdef CONFIG_SIM_X11FB + return up_x11initialize(CONFIG_SIM_FBWIDTH, CONFIG_SIM_FBHEIGHT, + &g_planeinfo.fbmem, &g_planeinfo.fblen, + &g_planeinfo.bpp, &g_planeinfo.stride); +#else + return OK; +#endif +} + +/**************************************************************************** + * Name: up_fbgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video plane. + * + * Input parameters: + * None + * + * Returned value: + * Reference to the framebuffer object (NULL on failure) + * + ****************************************************************************/ + +FAR struct fb_vtable_s *up_fbgetvplane(int vplane) +{ + if (vplane == 0) + { + return &g_fbobject; + } + else + { + return NULL; + } +} + +/**************************************************************************** + * Name: up_fbteardown + ****************************************************************************/ + +void fb_uninitialize(void) +{ +} + diff --git a/arch/sim/src/up_head.c b/arch/sim/src/up_head.c new file mode 100644 index 0000000000000000000000000000000000000000..b57012ed6cd7f4b320b7845d8775a78133b1405b --- /dev/null +++ b/arch/sim/src/up_head.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/sim/src/up_head.c + * + * Copyright (C) 2007-2009, 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static jmp_buf g_simabort; +static int g_exitcode = EXIT_SUCCESS; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: main + * + * Description: + * This is the main entry point into the simulation. + * + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ +#ifdef CONFIG_SMP + /* In the SMP case, configure the main thread as CPU 0 */ + + sim_cpu0_initialize(); +#endif + +#ifdef CONFIG_PM + /* Power management should be initialized early in the (simulated) boot + * sequence. + */ + + pm_initialize(); +#endif + + /* Then start NuttX */ + + if (setjmp(g_simabort) == 0) + { +#ifdef CONFIG_SMP + /* Start the CPU0 emulation. This should not return. */ + + sim_cpu0_start(); +#else + /* Start the Nuttx emulation. This should not return. */ + + os_start(); +#endif + } + + /* Restore the original terminal mode and return the exit code */ + + simuart_terminate(); + return g_exitcode; +} + +/**************************************************************************** + * Name: up_assert + * + * Description: + * Called to terminate the simulation abnormally in the event of a failed + * assertion. + * + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int line) +{ + /* Show the location of the failed assertion */ + +#ifdef CONFIG_SMP + fprintf(stderr, "CPU%d: Assertion failed at file:%s line: %d\n", + up_cpu_index(), filename, line); +#else + fprintf(stderr, "Assertion failed at file:%s line: %d\n", + filename, line); +#endif + + /* Allow for any board/configuration specific crash information */ + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, line); +#endif + + /* Exit the simulation */ + + g_exitcode = EXIT_FAILURE; + longjmp(g_simabort, 1); +} + +/**************************************************************************** + * Name: board_power_off + * + * Description: + * Power off the board. This function may or may not be supported by a + * particular board architecture. + * + * Input Parameters: + * status - Status information provided with the power off event. + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_POWEROFF +int board_power_off(int status) +{ + /* Save the return code and exit the simulation */ + + g_exitcode = status; + longjmp(g_simabort, 1); +} +#endif diff --git a/arch/sim/src/up_hostfs.c b/arch/sim/src/up_hostfs.c new file mode 100644 index 0000000000000000000000000000000000000000..f0928ed0dac5f5f7fdff8483ea1cc4a47cb97351 --- /dev/null +++ b/arch/sim/src/up_hostfs.c @@ -0,0 +1,382 @@ +/**************************************************************************** + * arch/sim/src/up_hostfs.c + * + * Copyright (C) 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#define _BSD_SOURCE + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "hostfs.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_open(const char *pathname, int flags, int mode) +{ + int mapflags; + + /* Perform flag mapping */ + + if ((flags & (HOSTFS_FLAG_RDOK | HOSTFS_FLAG_WROK)) == + (HOSTFS_FLAG_RDOK | HOSTFS_FLAG_WROK)) + { + mapflags = O_RDWR; + } + else if (flags & HOSTFS_FLAG_RDOK) + { + mapflags = O_RDONLY; + } + else if (flags & HOSTFS_FLAG_WROK) + { + mapflags = O_WRONLY; + } + + if (flags & HOSTFS_FLAG_APPEND) + { + mapflags |= O_APPEND; + } + + if (flags & HOSTFS_FLAG_CREAT) + { + mapflags |= O_CREAT; + } + + if (flags & HOSTFS_FLAG_EXCL) + { + mapflags |= O_EXCL; + } + + if (flags & HOSTFS_FLAG_TRUNC) + { + mapflags |= O_TRUNC; + } + + return open(pathname, mapflags, mode); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_close(int fd) +{ + /* Just call the close routine */ + + return close(fd); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +ssize_t host_read(int fd, void* buf, size_t count) +{ + /* Just call the read routine */ + + return read(fd, buf, count); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +ssize_t host_write(int fd, const void *buf, size_t count) +{ + /* Just call the write routine */ + + return write(fd, buf, count); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +off_t host_lseek(int fd, off_t offset, int whence) +{ + /* Just call the lseek routine */ + + return lseek(fd, offset, whence); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_ioctl(int fd, int request, unsigned long arg) +{ + /* Just call the ioctl routine */ + + return ioctl(fd, request, arg); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void host_sync(int fd) +{ + /* Just call the sync routine */ + + sync(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_dup(int fd) +{ + return dup(fd); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void *host_opendir(const char *name) +{ + return (void *) opendir(name); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_readdir(void* dirp, struct host_dirent_s* entry) +{ + struct dirent *ent; + + /* Call the host's readdir routine */ + + ent = readdir(dirp); + + if (ent != NULL) + { + /* Copy the entry name */ + + strncpy(entry->d_name, ent->d_name, sizeof(entry->d_name)); + + /* Map the type */ + + entry->d_type = 0; + if (ent->d_type == DT_REG) + { + entry->d_type = HOSTFS_DTYPE_FILE; + } + else if (ent->d_type == DT_CHR) + { + entry->d_type = HOSTFS_DTYPE_CHR; + } + else if (ent->d_type == DT_BLK) + { + entry->d_type = HOSTFS_DTYPE_BLK; + } + else if (ent->d_type == DT_DIR) + { + entry->d_type = HOSTFS_DTYPE_DIRECTORY; + } + } + + if (ent) + { + return 0; + } + + return -ENOENT; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void host_rewinddir(void* dirp) +{ + /* Just call the rewinddir routine */ + + rewinddir(dirp); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_closedir(void* dirp) +{ + return closedir(dirp); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_statfs(const char *path, struct host_statfs_s *buf) +{ + int ret; + struct statfs host_buf; + + /* Call the host's statfs routine */ + + ret = statfs(path, &host_buf); + + /* Map the return values */ + + buf->f_type = host_buf.f_type; + buf->f_bsize = host_buf.f_bsize; + buf->f_blocks = host_buf.f_blocks; + buf->f_bfree = host_buf.f_bfree; + buf->f_bavail = host_buf.f_bavail; + buf->f_files = host_buf.f_files; + buf->f_ffree = host_buf.f_ffree; + buf->f_fsid = 0; + buf->f_namelen = host_buf.f_namelen; + buf->f_frsize = host_buf.f_frsize; + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_unlink(const char *pathname) +{ + return unlink(pathname); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_mkdir(const char *pathname, mode_t mode) +{ + /* Just call the host's mkdir routine */ + + return mkdir(pathname, mode); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_rmdir(const char *pathname) +{ + return rmdir(pathname); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_rename(const char *oldpath, const char *newpath) +{ + return rename(oldpath, newpath); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_stat(const char *path, struct host_stat_s *buf) +{ + struct stat host_buf; + int ret; + + /* Call the host's stat routine */ + + ret = stat(path, &host_buf); + + /* Now map the return values to the common struct */ + + buf->st_dev = host_buf.st_dev; /* ID of the device containing file */ + buf->st_ino = host_buf.st_ino;; /* inode number */ + buf->st_nlink = host_buf.st_nlink; /* number of hard links */ + buf->st_uid = host_buf.st_uid; /* user ID of owner */ + buf->st_gid = host_buf.st_gid; /* group ID of owner */ + buf->st_rdev = host_buf.st_rdev; /* device ID */ + buf->st_size = host_buf.st_size; /* total size, in bytes */ + buf->st_blksize = host_buf.st_blksize; /* blocksize for file system I/O */ + buf->st_blocks = host_buf.st_blocks; /* number of 512B blocks allocated */ + buf->st_atim = host_buf.st_atime; /* time of last access */ + buf->st_mtim = host_buf.st_mtime; /* time of last modification */ + buf->st_ctim = host_buf.st_ctime; /* time of last status change */ + + /* Map the mode bits */ + + buf->st_mode = host_buf.st_mode & 0xFFF; + if (S_ISREG(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_REG; + } + + if (S_ISDIR(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_DIR; + } + + if (S_ISCHR(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_CHR; + } + + if (S_ISBLK(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_BLK; + } + + if (S_ISFIFO(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_PIPE; + } + + if (S_ISLNK(host_buf.st_mode)) + { + buf->st_mode |= HOST_ST_MODE_LINK; + } + + return ret; +} diff --git a/arch/sim/src/up_hostusleep.c b/arch/sim/src/up_hostusleep.c new file mode 100644 index 0000000000000000000000000000000000000000..8fb09c8373bdb036c148de675b2f9c36c21e2b99 --- /dev/null +++ b/arch/sim/src/up_hostusleep.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/sim/src/up_hostusleep.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_hostusleep + ****************************************************************************/ + +int up_hostusleep(unsigned int usec) +{ + return usleep(usec); +} diff --git a/arch/sim/src/up_idle.c b/arch/sim/src/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..2e218b319dfece58e31cd42addc9a437fac0edef --- /dev/null +++ b/arch/sim/src/up_idle.c @@ -0,0 +1,210 @@ +/**************************************************************************** + * arch/sim/src/up_idle.c + * + * Copyright (C) 2007-2009, 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_PM +# include +#endif + +#ifdef CONFIG_SMP +# include +#endif + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PM_IDLE_DOMAIN 0 /* Revisit */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SIM_X11FB +static int g_x11refresh = 0; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB) +extern int up_hostusleep(unsigned int usec); +#ifdef CONFIG_SIM_X11FB +extern void up_x11update(void); +#endif +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their + * is no other ready-to-run task. This is processor idle + * time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be + * performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#ifdef CONFIG_SMP + /* In the SMP configuration, only one CPU should do these operations. It + * should not matter which, however. + */ + + static volatile spinlock_t lock = SP_UNLOCKED; + + /* The one that gets the lock is the one that executes the IDLE operations */ + + if (up_testset(&lock) != SP_UNLOCKED) + { + /* We didn't get it... Give other pthreads/CPUs a shot and try again + * later. + */ + + pthread_yield(); + return; + } +#endif + +#ifdef CONFIG_SCHED_TICKLESS + /* Driver the simulated interval timer */ + + up_timer_update(); +#else + /* If the system is idle, then process "fake" timer interrupts. + * Hopefully, something will wake up. + */ + + sched_process_timer(); +#endif + +#if defined(CONFIG_DEV_CONSOLE) && !defined(CONFIG_SIM_UART_DATAPOST) + /* Handle UART data availability */ + + if (g_uart_data_available) + { + g_uart_data_available = 0; + simuart_post(); + } +#endif + +#ifdef CONFIG_NET_ETHERNET + /* Run the network if enabled */ + + netdriver_loop(); +#endif + +#ifdef CONFIG_PM + /* Fake some power management stuff for testing purposes */ + + { + static enum pm_state_e state = PM_NORMAL; + enum pm_state_e newstate; + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + if (newstate != state) + { + if (pm_changestate(PM_IDLE_DOMAIN, newstate) == OK) + { + state = newstate; + } + } + } +#endif + +#if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB) + /* Wait a bit so that the sched_process_timer() is called close to the + * correct rate. + */ + + (void)up_hostusleep(1000000 / CLK_TCK); + + /* Handle X11-related events */ + +#ifdef CONFIG_SIM_X11FB + if (g_x11initialized) + { +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) + /* Drive the X11 event loop */ + + if (g_eventloop) + { + up_x11events(); + } +#endif + + /* Update the display periodically */ + + g_x11refresh += 1000000 / CLK_TCK; + if (g_x11refresh > 500000) + { + up_x11update(); + } + } +#endif +#endif + +#ifdef CONFIG_SMP + /* Release the spinlock */ + + lock = SP_UNLOCKED; + + /* Give other pthreads/CPUs a shot */ + + pthread_yield(); +#endif +} diff --git a/arch/sim/src/up_initialize.c b/arch/sim/src/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..7efcfb237382ea1ecb5b6189624fbc3d944c642a --- /dev/null +++ b/arch/sim/src/up_initialize.c @@ -0,0 +1,207 @@ +/**************************************************************************** + * arch/sim/src/up_initialize.c + * + * Copyright (C) 2007-2009, 2011-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_init_smartfs + * + * Description: + * Initialize a simulated SPI FLASH block device m25p MTD driver and bind + * it to a SMART Flash block device. + * + ****************************************************************************/ + +#if defined(CONFIG_FS_SMARTFS) && defined(CONFIG_SIM_SPIFLASH) +static void up_init_smartfs(void) +{ + FAR struct mtd_dev_s *mtd; + FAR struct spi_dev_s *spi; + +#ifdef CONFIG_MTD_M25P + /* Initialize a simulated SPI FLASH block device m25p MTD driver */ + + spi = up_spiflashinitialize(); + mtd = m25p_initialize(spi); + + /* Now initialize a SMART Flash block device and bind it to the MTD device */ + + smart_initialize(0, mtd, NULL); +#endif + +#ifdef CONFIG_MTD_W25 + /* Initialize a simulated SPI FLASH block device m25p MTD driver */ + + spi = up_spiflashinitialize(); + mtd = w25_initialize(spi); + + /* Now initialize a SMART Flash block device and bind it to the MTD device */ + + smart_initialize(0, mtd, NULL); +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS + * initialization after the basic OS services have been + * initialized. The architecture specific details of + * initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the + * clock, and registering device drivers are some of the + * things that are different for each processor and hardware + * platform. + * + * up_initialize is called after the OS initialized but + * before the init process has been started and before the + * libraries have been initialized. OS services and driver + * services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* The real purpose of the following is to make sure that syslog + * is drawn into the link. It is needed by up_tapdev which is linked + * separately. + */ + +#ifdef CONFIG_NET + syslog(LOG_INFO, "SIM: Initializing"); +#endif + +#if CONFIG_NFILE_DESCRIPTORS > 0 + /* Register devices */ + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + +#if defined(USE_DEVCONSOLE) + /* Start the sumulated UART device */ + + simuart_start(); + + /* Register a console (or not) */ + + up_devconsole(); /* Our private /dev/console */ +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); /* System logging device */ +#endif + +#if defined(CONFIG_FS_FAT) && !defined(CONFIG_DISABLE_MOUNTPOINT) + up_registerblockdevice(); /* Our FAT ramdisk at /dev/ram0 */ +#endif + +#ifdef CONFIG_NET_ETHERNET + netdriver_init(); /* Our "real" network driver */ +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + +#if defined(CONFIG_FS_SMARTFS) && defined(CONFIG_SIM_SPIFLASH) + up_init_smartfs(); +#endif +} diff --git a/arch/sim/src/up_initialstate.c b/arch/sim/src/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..2f879faccfe6b942f8edbf5a6cb15794c7a2784d --- /dev/null +++ b/arch/sim/src/up_initialstate.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * arch/sim/src/up_initialstate.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + memset(&tcb->xcp, 0, sizeof(struct xcptcontext)); + tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr; + tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start; +} diff --git a/arch/sim/src/up_internal.h b/arch/sim/src/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..e1e69dc25bdf6864ddf1cbe41d72dfef150a275d --- /dev/null +++ b/arch/sim/src/up_internal.h @@ -0,0 +1,343 @@ +/**************************************************************************** + * arch/sim/src/up_internal.h + * + * Copyright (C) 2007, 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_SRC_UP_INTERNAL_H +#define __ARCH_SIM_SRC_UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifndef __ASSEMBLY__ +# include +# include + +# include +# include +# ifdef CONFIG_SMP +# include +# include +# endif +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration **********************************************************/ + +#ifndef CONFIG_SIM_X11FB +# ifdef CONFIG_SIM_TOUCHSCREEN +# error "CONFIG_SIM_TOUCHSCREEN depends on CONFIG_SIM_X11FB" +# undef CONFIG_SIM_TOUCHSCREEN +# endif +# ifdef CONFIG_SIM_AJOYSTICK +# error "CONFIG_SIM_AJOYSTICK depends on CONFIG_SIM_X11FB" +# undef CONFIG_SIM_AJOYSTICK +# endif +#endif + +#ifndef CONFIG_INPUT +# ifdef CONFIG_SIM_TOUCHSCREEN +# error "CONFIG_SIM_TOUCHSCREEN depends on CONFIG_INPUT" +# undef CONFIG_SIM_TOUCHSCREEN +# endif +# ifdef CONFIG_SIM_AJOYSTICK +# error "CONFIG_SIM_AJOYSTICK depends on CONFIG_INPUT" +# undef CONFIG_SIM_AJOYSTICK +# endif +#endif + +/* Determine which (if any) console driver to use */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS == 0 +# undef USE_DEVCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_DEVCONSOLE +# else +# define USE_DEVCONSOLE 1 +# endif +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* The design for how we signal UART data availability is up in the air */ + +#undef CONFIG_SIM_UART_DATAPOST + +/* Context Switching Definitions ******************************************/ + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + +# ifdef __ASSEMBLY__ +# define JB_RBX (0*8) +# define JB_RSP (1*8) +# define JB_RBP (2*8) +# define JB_R12 (3*8) +# define JB_R13 (4*8) +# define JB_R14 (5*8) +# define JB_R15 (6*8) +# define JB_RSI (7*8) + +# else +# define JB_RBX (0) +# define JB_RSP (1) +# define JB_RBP (2) +# define JB_R12 (3) +# define JB_R13 (4) +# define JB_R14 (5) +# define JB_R15 (6) +# define JB_RSI (7) + +# endif /* __ASSEMBLY__ */ + +/* Compatibility definitions */ + +# define JB_SP JB_RSP +# define JB_PC JB_RSI + +#else +/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ + +# ifdef __ASSEMBLY__ +# define JB_EBX (0*4) +# define JB_ESI (1*4) +# define JB_EDI (2*4) +# define JB_EBP (3*4) +# define JB_SP (4*4) +# define JB_PC (5*4) + +# else +# define JB_EBX (0) +# define JB_ESI (1) +# define JB_EDI (2) +# define JB_EBP (3) +# define JB_SP (4) +# define JB_PC (5) + +# endif /* __ASSEMBLY__ */ +#endif /* CONFIG_HOST_X86_64 && !CONFIG_SIM_M32 */ + +/* Simulated Heap Definitions **********************************************/ +/* Size of the simulated heap */ + +#ifdef CONFIG_MM_SMALL +# define SIM_HEAP_SIZE (64*1024) +#else +# define SIM_HEAP_SIZE (4*1024*1024) +#endif + +/* File System Definitions **************************************************/ +/* These definitions characterize the compressed filesystem image */ + +#define BLOCK_COUNT 1024 +#define SECTOR_OF_BACKUPT 6 +#define NUMBER_OF_FATS 2 +#define FAT_SIZE 32 +#define NUM_HIDDEN_SECTORS 0 +#define VOLUME_NAME "NuttXTestVol" +#define USE_WHOLE_DEVICE 1 +#define ROOT_DIR_ENTRIES 512 +#define RESERVED_SECTORS 32 +#define SECTORS_PER_CLUSTER 4 +#define LOGICAL_SECTOR_SIZE 512 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_SIM_X11FB +extern int g_x11initialized; +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) +extern volatile int g_eventloop; +#endif +#endif + +#if defined(CONFIG_DEV_CONSOLE) && !defined(CONFIG_SIM_UART_DATAPOST) +extern volatile int g_uart_data_available; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* up_setjmp32.S **********************************************************/ + +int up_setjmp(xcpt_reg_t *jb); +void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function; + +/* up_simsmp.c ************************************************************/ + +#ifdef CONFIG_SMP +int sim_cpu0_initialize(void); +void sim_cpu0_start(void); +#endif + +/* up_smpsignal.c *********************************************************/ + +#ifdef CONFIG_SMP +void sim_cpu_pause(int cpu, FAR volatile spinlock_t *wait, + FAR volatile unsigned char *paused); +#endif + +/* up_smphook.c ***********************************************************/ + +#ifdef CONFIG_SMP +void sim_smp_hook(void); +#endif + +/* up_tickless.c **********************************************************/ + +#ifdef CONFIG_SCHED_TICKLESS +void up_timer_update(void); +#endif + +/* up_devconsole.c ********************************************************/ + +void up_devconsole(void); +void up_registerblockdevice(void); + +/* up_simuart.c ***********************************************************/ + +void simuart_start(void); +int simuart_putc(int ch); +int simuart_getc(void); +bool simuart_checkc(void); +void simuart_terminate(void); + +/* up_uartwait.c **********************************************************/ + +void simuart_initialize(void); +void simuart_post(void); +void simuart_wait(void); + +/* up_deviceimage.c *******************************************************/ + +char *up_deviceimage(void); + +/* up_netdev.c ************************************************************/ + +#ifdef CONFIG_NET +unsigned long up_getwalltime( void ); +#endif + +/* up_x11framebuffer.c ****************************************************/ + +#ifdef CONFIG_SIM_X11FB +int up_x11initialize(unsigned short width, unsigned short height, + void **fbmem, unsigned int *fblen, unsigned char *bpp, + unsigned short *stride); +#ifdef CONFIG_FB_CMAP +int up_x11cmap(unsigned short first, unsigned short len, + unsigned char *red, unsigned char *green, + unsigned char *blue, unsigned char *transp); +#endif +#endif + +/* up_eventloop.c *********************************************************/ + +#if defined(CONFIG_SIM_X11FB) && \ + (defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)) +void up_x11events(void); +#endif + +/* up_eventloop.c *********************************************************/ + +#if defined(CONFIG_SIM_X11FB) && \ + (defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK)) +int up_buttonevent(int x, int y, int buttons); +#endif + +/* up_ajoystick.c *********************************************************/ + +#ifdef CONFIG_SIM_AJOYSTICK +int sim_ajoy_initialize(void); +#endif + +/* up_tapdev.c ************************************************************/ + +#if defined(CONFIG_NET_ETHERNET) && !defined(__CYGWIN__) +void tapdev_init(void); +unsigned int tapdev_read(unsigned char *buf, unsigned int buflen); +void tapdev_send(unsigned char *buf, unsigned int buflen); + +#define netdev_init() tapdev_init() +#define netdev_read(buf,buflen) tapdev_read(buf,buflen) +#define netdev_send(buf,buflen) tapdev_send(buf,buflen) +#endif + +/* up_wpcap.c *************************************************************/ + +#if defined(CONFIG_NET_ETHERNET) && defined(__CYGWIN__) +void wpcap_init(void); +unsigned int wpcap_read(unsigned char *buf, unsigned int buflen); +void wpcap_send(unsigned char *buf, unsigned int buflen); + +#define netdev_init() wpcap_init() +#define netdev_read(buf,buflen) wpcap_read(buf,buflen) +#define netdev_send(buf,buflen) wpcap_send(buf,buflen) +#endif + +/* up_netdriver.c *********************************************************/ + +#ifdef CONFIG_NET_ETHERNET +int netdriver_init(void); +int netdriver_setmacaddr(unsigned char *macaddr); +void netdriver_loop(void); +#endif + +#ifdef CONFIG_SIM_SPIFLASH +struct spi_dev_s; +struct spi_dev_s *up_spiflashinitialize(void); +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_SIM_SRC_UP_INTERNAL_H */ diff --git a/arch/sim/src/up_interruptcontext.c b/arch/sim/src/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..446807b1dcb19292769570042eec98e326c771e7 --- /dev/null +++ b/arch/sim/src/up_interruptcontext.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/sim/src/up_interruptcontext.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: + * Return true is we are currently executing in the interrupt handler + * context. + * + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + /* The simulation is never in the interrupt state */ + return false; +} + diff --git a/arch/sim/src/up_netdev.c b/arch/sim/src/up_netdev.c new file mode 100644 index 0000000000000000000000000000000000000000..8346652180d8ec1978afb3cd89e381db3fb1bd4b --- /dev/null +++ b/arch/sim/src/up_netdev.c @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/sim/src/up_tapdev.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef NULL +# define NULL (void*)0 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +unsigned long up_getwalltime(void) +{ + struct timeval tm; + (void)gettimeofday(&tm, NULL); + return tm.tv_sec*1000 + tm.tv_usec/1000; +} diff --git a/arch/sim/src/up_netdriver.c b/arch/sim/src/up_netdriver.c new file mode 100644 index 0000000000000000000000000000000000000000..346159157f370c224d012476b2a195c305a3633c --- /dev/null +++ b/arch/sim/src/up_netdriver.c @@ -0,0 +1,330 @@ +/**************************************************************************** + * arch/sim/src/up_netdriver.c + * + * Copyright (C) 2007, 2009-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on code from uIP which also has a BSD-like license: + * + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_NET_ETHERNET + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BUF ((struct eth_hdr_s *)g_sim_dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct timer +{ + uint32_t interval; + uint32_t start; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct timer g_periodic_timer; +static struct net_driver_s g_sim_dev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void timer_set(struct timer *t, unsigned int interval) +{ + t->interval = interval; + t->start = up_getwalltime(); +} + +static bool timer_expired(struct timer *t) +{ + return (up_getwalltime() - t->start) >= t->interval; +} + +void timer_reset(struct timer *t) +{ + t->start += t->interval; +} + +#ifdef CONFIG_NET_PROMISCUOUS +# define up_comparemac(a,b) (0) +#else +static inline int up_comparemac(uint8_t *paddr1, struct ether_addr *paddr2) +{ + return memcmp(paddr1, paddr2->ether_addr_octet, ETHER_ADDR_LEN); +} +#endif + +static int sim_txpoll(struct net_driver_s *dev) +{ + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(&g_sim_dev)) +#endif + { + arp_out(&g_sim_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&g_sim_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void netdriver_loop(void) +{ + FAR struct eth_hdr_s *eth; + + /* netdev_read will return 0 on a timeout event and >0 on a data received event */ + + g_sim_dev.d_len = netdev_read((FAR unsigned char *)g_sim_dev.d_buf, + CONFIG_NET_ETH_MTU); + + /* Disable preemption through to the following so that it behaves a little more + * like an interrupt (otherwise, the following logic gets pre-empted an behaves + * oddly. + */ + + sched_lock(); + if (g_sim_dev.d_len > 0) + { + /* Data received event. Check for valid Ethernet header with destination == our + * MAC address + */ + + eth = BUF; + if (g_sim_dev.d_len > ETH_HDRLEN && + up_comparemac(eth->dest, &g_sim_dev.d_mac) == 0) + { +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet + * tap. + */ + + pkt_input(&g_sim_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (eth->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&g_sim_dev); + ipv4_input(&g_sim_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the global variable + * d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(g_sim_dev.d_flags)) +#endif + { + arp_out(&g_sim_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&g_sim_dev); + } +#endif + + /* And send the packet */ + + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (eth->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&g_sim_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the global variable + * d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(g_sim_dev.d_flags)) + { + arp_out(&g_sim_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&g_sim_dev); + } +#endif + + /* And send the packet */ + + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (eth->type == htons(ETHTYPE_ARP)) + { + arp_arpin(&g_sim_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the global variable + * d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } + } +#endif + } + } + + /* Otherwise, it must be a timeout event */ + + else if (timer_expired(&g_periodic_timer)) + { + timer_reset(&g_periodic_timer); + devif_timer(&g_sim_dev, sim_txpoll); + } + sched_unlock(); +} + +int netdriver_init(void) +{ + /* Internal initalization */ + + timer_set(&g_periodic_timer, 500); + netdev_init(); + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&g_sim_dev, NET_LL_ETHERNET); + return OK; +} + +int netdriver_setmacaddr(unsigned char *macaddr) +{ + (void)memcpy(g_sim_dev.d_mac.ether_addr_octet, macaddr, IFHWADDRLEN); + return 0; +} + +#endif /* CONFIG_NET_ETHERNET */ + diff --git a/arch/sim/src/up_releasepending.c b/arch/sim/src/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..386b58589a38143e6bd5bb24baf9c0e30c3fa70b --- /dev/null +++ b/arch/sim/src/up_releasepending.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/sim/src/up_releasepending.c + * + * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + FAR struct tcb_s *rtcb = this_task(); + + sdbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Copy the exception context into the TCB of the task that was + * currently active. if up_setjmp returns a non-zero value, then + * this is really the previously running task restarting! + */ + + if (!up_setjmp(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + sdbg("New Active Task TCB=%p\n", rtcb); + + /* The way that we handle signals in the simulation is kind of + * a kludge. This would be unsafe in a truly multi-threaded, interrupt + * driven environment. + */ + + if (rtcb->xcp.sigdeliver) + { + sdbg("Delivering signals TCB=%p\n", rtcb); + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + rtcb->xcp.sigdeliver = NULL; + } + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_longjmp(rtcb->xcp.regs, 1); + } + } +} diff --git a/arch/sim/src/up_releasestack.c b/arch/sim/src/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..e62cf2adf81123fdbc901945b48aec03bffcddf0 --- /dev/null +++ b/arch/sim/src/up_releasestack.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/sim/src/up_releasestack.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + dtcb->adj_stack_size = 0; + dtcb->adj_stack_ptr = NULL; +} diff --git a/arch/sim/src/up_reprioritizertr.c b/arch/sim/src/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..39c981c64838ee87872b0517939a4b040d05aa55 --- /dev/null +++ b/arch/sim/src/up_reprioritizertr.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/sim/src/up_reprioritizertr.c + * + * Copyright (C) 2007-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + sdbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_setjmp returns a non-zero + * value, then this is really the previously running task restarting! + */ + + if (!up_setjmp(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + sdbg("New Active Task TCB=%p\n", rtcb); + + /* The way that we handle signals in the simulation is kind of + * a kludge. This would be unsafe in a truly multi-threaded, interrupt + * driven environment. + */ + + if (rtcb->xcp.sigdeliver) + { + sdbg("Delivering signals TCB=%p\n", rtcb); + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + rtcb->xcp.sigdeliver = NULL; + } + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_longjmp(rtcb->xcp.regs, 1); + } + } + } +} diff --git a/arch/sim/src/up_romgetc.c b/arch/sim/src/up_romgetc.c new file mode 100644 index 0000000000000000000000000000000000000000..e5f6c6c90eff2788ab6d9f7f63bc60d6d8df1407 --- /dev/null +++ b/arch/sim/src/up_romgetc.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/sim/src/up_romgetc.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_ARCH_ROMGETC + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_romgetc + * + * Description: + * In Harvard architectures, data accesses and instruction accesses occur + * on different busses, perhaps concurrently. All data accesses are + * performed on the data bus unless special machine instructions are + * used to read data from the instruction address space. Also, in the + * typical MCU, the available SRAM data memory is much smaller that the + * non-volatile FLASH instruction memory. So if the application requires + * many constant strings, the only practical solution may be to store + * those constant strings in FLASH memory where they can only be accessed + * using architecture-specific machine instructions. + * + * A similar case is where strings are retained in "external" memory such + * as EEPROM or serial FLASH. This case is similar only in that again + * special operations are required to obtain the string data; it cannot + * be accessed directly from a string pointer. + * + * If CONFIG_ARCH_ROMGETC is defined, then the architecture logic must + * export the function up_romgetc(). up_romgetc() will simply read one + * byte of data from the instruction space. + * + * If CONFIG_ARCH_ROMGETC, certain C stdio functions are effected: (1) + * All format strings in printf, fprintf, sprintf, etc. are assumed to + * lie in FLASH (string arguments for %s are still assumed to reside in + * SRAM). And (2), the string argument to puts and fputs is assumed to + * reside in FLASH. Clearly, these assumptions may have to modified for + * the particular needs of your environment. There is no "one-size-fits-all" + * solution for this problem. + * + ****************************************************************************/ + +char up_romgetc(FAR const char *ptr) +{ + /* This is basically a No-Op if enabled in the simulation environment */ + + return *ptr; +} +#endif diff --git a/arch/sim/src/up_schednote.c b/arch/sim/src/up_schednote.c new file mode 100644 index 0000000000000000000000000000000000000000..41797969b2c3ae7680a4e1092a4a55f85dbcd152 --- /dev/null +++ b/arch/sim/src/up_schednote.c @@ -0,0 +1,211 @@ +/**************************************************************************** + * arch/sim/src/up_schednote.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#if defined(CONFIG_SCHED_INSTRUMENTATION) && \ + !defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_note_start, sched_note_stop, sched_note_switch, + * sched_note_premption + * + * Description: + * Hooks to scheduler monitor + * + * Input Parameters: + * Varies + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sched_note_start(FAR struct tcb_s *tcb) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Start %s, TCB@%p, state=%d\n", + tcb->cpu, tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "CPU%d: Start TCB@%p, state=%d\n" + tcb->cpu, tcb, tcb->task_state); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Start %s, TCB@%p, state=%d\n", + tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "Start TCB@%p, state=%d\n", + tcb, tcb->task_state); +#endif +#endif +} + +void sched_note_stop(FAR struct tcb_s *tcb) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Stop %s, TCB@%p, state=%d\n", + tcb->cpu, tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "CPU%d: Stop TCB@%p, state=%d\n", + tcb->cpu, tcb, tcb->task_state); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Stop %s, TCB@%p, state=%d\n", + tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "Stop TCB@%p, state=%d\n", + tcb, tcb->task_state); +#endif +#endif +} + +void sched_note_suspend(FAR struct tcb_s *tcb) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Suspend %s, TCB@%p, state=%d\n", + tcb->cpu, tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "CPU%d: Suspend TCB@%p, state=%d\n", + tcb->cpu, tcb, tcb->task_state); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Suspend %s, TCB@%p, state=%d\n", + tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "Suspend TCB@%p, state=%d\n", + tcb, tcb->task_state); +#endif +#endif +} + +void sched_note_resume(FAR struct tcb_s *tcb) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Resume %s, TCB@%p, state=%d\n", + tcb->cpu, tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "CPU%d: Resume TCB@%p, state=%d\n", + tcb->cpu, tcb, tcb->task_state); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Resume %s, TCB@%p, state=%d\n", + tcb->name, tcb, tcb->task_state); +#else + lowsyslog(LOG_INFO, "Resume TCB@%p, state=%d\n", + tcb, tcb->task_state); +#endif +#endif +} + +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION +/* This does not work well... it interferes with the operation of the + * simulated /dev/console device which, of course, does disable preemption + * and does use critical sections. + */ + +#warning CONFIG_SCHED_INSTRUMENTATION_PREEMPTION is a bad idea + +void sched_note_premption(FAR struct tcb_s *tcb, bool locked) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Task %s TCB@%p preemption %s\n", + tcb->cpu, tcb->name, tcb, locked ? "LOCKED" : "UNLOCKED"); +#else + lowsyslog(LOG_INFO, "CPU%d: TCB@%p preemption %s\n", + tcb->cpu, tcb, locked ? "LOCKED" : "UNLOCKED"); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Task %s, TCB@%p preemption %s\n", + tcb->name, tcb, locked ? "LOCKED" : "UNLOCKED"); +#else + lowsyslog(LOG_INFO, "TCB@%p preemption %s\n", + tcb, locked ? "LOCKED" : "UNLOCKED"); +#endif +#endif +} +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION +/* This does not work well... it interferes with the operation of the + * simulated /dev/console device which, of course, does disable preemption + * and does use critical sections. + */ + +#warning CONFIG_SCHED_INSTRUMENTATION_CSECTION is a bad idea + +void sched_note_csection(FAR struct tcb_s *tcb, bool enter) +{ +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "CPU%d: Task %s TCB@%p critical section %s\n", + tcb->cpu, tcb->name, tcb, enter ? "ENTER" : "LEAVE"); +#else + lowsyslog(LOG_INFO, "CPU%d: TCB@%p critical section %s\n", + tcb->cpu, tcb, enter ? "ENTER" : "LEAVE"); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lowsyslog(LOG_INFO, "Task %s, TCB@%p critical section %s\n", + tcb->name, tcb, enter ? "ENTER" : "LEAVE"); +#else + lowsyslog(LOG_INFO, "TCB@%p critical section %s\n", + tcb, enter ? "ENTER" : "LEAVE"); +#endif +#endif +} +#endif + +#endif /* CONFIG_SCHED_INSTRUMENTATION && !CONFIG_SCHED_INSTRUMENTATION_BUFFER */ diff --git a/arch/sim/src/up_schedulesigaction.c b/arch/sim/src/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..229bfa674685284c55ff79339bb0571b0d482734 --- /dev/null +++ b/arch/sim/src/up_schedulesigaction.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/sim/src/up_schedulesigaction.c + * + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + /* We don't have to anything complex for the simulated target */ + + if (tcb == this_task()) + { + sigdeliver(tcb); + } + else + { + tcb->xcp.sigdeliver = sigdeliver; + } +} diff --git a/arch/sim/src/up_setjmp32.S b/arch/sim/src/up_setjmp32.S new file mode 100644 index 0000000000000000000000000000000000000000..e223afbeab306abe028dc8ff9497c8a5141c8f0c --- /dev/null +++ b/arch/sim/src/up_setjmp32.S @@ -0,0 +1,118 @@ +/************************************************************************** + * arch/sim/src/up_setjmp32.S + * + * Copyright (C) 2007, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +#ifdef __CYGWIN__ +# define SYMBOL(s) _##s +#else +# define SYMBOL(s) s +#endif + +/************************************************************************** + * Public Functions + **************************************************************************/ + + .text + .globl SYMBOL(up_setjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_setjmp), @function +#endif +SYMBOL(up_setjmp): + + /* %ebx, %esi, %edi, and %ebp must be preserved. + * save %ebx, $esi, and %edi now... */ + + movl 4(%esp), %eax + movl %ebx, (JB_EBX)(%eax) + movl %esi, (JB_ESI)(%eax) + movl %edi, (JB_EDI)(%eax) + + /* Save the value of SP as will be after we return */ + + leal 4(%esp), %ecx + movl %ecx, (JB_SP)(%eax) + + /* Save the return PC */ + + movl 0(%esp), %ecx + movl %ecx, (JB_PC)(%eax) + + /* Save the framepointer */ + + movl %ebp, (JB_EBP)(%eax) + + /* And return 0 */ + + xorl %eax, %eax + ret +#ifndef __CYGWIN__ + .size SYMBOL(up_setjmp), . - SYMBOL(up_setjmp) +#endif + .globl SYMBOL(up_longjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_longjmp), @function +#endif +SYMBOL(up_longjmp): + movl 4(%esp), %ecx /* jmpbuf in %ecx. */ + movl 8(%esp), %eax /* Second argument is return value. */ + + /* Save the return address now. */ + + movl (JB_PC)(%ecx), %edx + + /* Restore registers. */ + + movl (JB_EBX)(%ecx), %ebx + movl (JB_ESI)(%ecx), %esi + movl (JB_EDI)(%ecx), %edi + movl (JB_EBP)(%ecx), %ebp + movl (JB_SP)(%ecx), %esp + + /* Jump to saved PC. */ + + jmp *%edx +#ifndef __CYGWIN__ + .size SYMBOL(up_longjmp), . - SYMBOL(up_longjmp) +#endif + diff --git a/arch/sim/src/up_setjmp64.S b/arch/sim/src/up_setjmp64.S new file mode 100644 index 0000000000000000000000000000000000000000..4045494b3174d7df3204d630c6800a3bdcc837e6 --- /dev/null +++ b/arch/sim/src/up_setjmp64.S @@ -0,0 +1,163 @@ +/************************************************************************** + * arch/sim/src/up_setjmp64.S + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/* The Microsoft x64 calling convention is followed on Microsoft Windows and + * pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8, + * R9 for the first four integer or pointer arguments (in that order), and + * XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional + * arguments are pushed onto the stack (right to left). Integer return + * values (similar to x86) are returned in RAX if 64 bits or less. Floating + * point return values are returned in XMM0. Parameters less than 64 bits + * long are not zero extended; the high bits are not zeroed. + */ + +#ifdef CONFIG_SIM_X8664_MICROSOFT +# define REGS %rcx + +/* The calling convention of the System V AMD64 ABI is followed on Solaris, + * Linux, FreeBSD, Mac OS X, and other UNIX-like or POSIX-compliant operating + * systems. The first six integer or pointer arguments are passed in registers + * RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, + * XMM6 and XMM7 are used for floating point arguments. For system calls, R10 + * is used instead of RCX. As in the Microsoft x64 calling convention, + * additional arguments are passed on the stack and the return value is stored + * in RAX. + * + * Registers RBP, RBX, and R12-R15 are callee-save registers; all others must + * be saved by the caller if they wish to preserve their values. + * + * Unlike the Microsoft calling convention, a shadow space is not provided; on + * function entry, the return address is adjacent to the seventh integer + * argument on the stack. + */ + +#else /* if defined(CONFIG_SIM_X8664_SYSTEMV) */ +# define REGS %rdi +#endif + +#ifdef __CYGWIN__ +//# define SYMBOL(s) _##s +# define SYMBOL(s) s +#else +# define SYMBOL(s) s +#endif + +/************************************************************************** + * Public Functions + **************************************************************************/ + + .text + .align 4 + .globl SYMBOL(up_setjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_setjmp), @function +#endif +SYMBOL(up_setjmp): + + /* Get the return address, adjusting the stack pointer */ + + pop %rsi + + /* Set up the return value */ + + xorl %eax,%eax + + /* Save 1: rbx */ + + movq %rbx, JB_RBX(REGS) + + /* Save 2: Value of the rsp *after* returning */ + + movq %rsp, JB_RSP(REGS) + + /* Fix up the return stack */ + + push %rsi + + /* Save registers */ + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + + movq %rbp, JB_RBP(REGS) /* Save 3: rbp */ + movq %r12, JB_R12(REGS) /* Save 4: r12 */ + movq %r13, JB_R13(REGS) /* Save 5: r13 */ + movq %r14, JB_R14(REGS) /* Save 6: r14 */ + movq %r15, JB_R15(REGS) /* Save 7: r15 */ + movq %rsi, JB_RSI(REGS) /* Save 8: Return address */ + + ret + +#ifndef __CYGWIN__ + .size SYMBOL(up_setjmp), . - SYMBOL(up_setjmp) +#endif + + .align 4 + .globl SYMBOL(up_longjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_longjmp), @function +#endif +SYMBOL(up_longjmp): + + /* Setup return value */ + + movl %esi,%eax + + /* Restore registers */ + + movq JB_RBX(REGS),%rbx /* Save 1: rbx */ + movq JB_RSP(REGS),%rsp /* Save 2: rsp */ + movq JB_RBP(REGS),%rbp /* Save 3: rdi */ + movq JB_R12(REGS),%r12 /* Save 4: r12 */ + movq JB_R13(REGS),%r13 /* Save 5: r13 */ + movq JB_R14(REGS),%r14 /* Save 6: r14 */ + movq JB_R15(REGS),%r15 /* Save 7: rbp */ + + /* And return */ + + jmp *JB_RSI(REGS) /* Save 8: rsi */ + +#ifndef __CYGWIN__ + .size SYMBOL(up_longjmp), . - SYMBOL(up_longjmp) +#endif + diff --git a/arch/sim/src/up_simsmp.c b/arch/sim/src/up_simsmp.c new file mode 100644 index 0000000000000000000000000000000000000000..7ff5cdb6d0d5e9e4956929bcda36a9ba00f1b9df --- /dev/null +++ b/arch/sim/src/up_simsmp.c @@ -0,0 +1,490 @@ +/**************************************************************************** + * arch/sim/src/up_simsmp.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define _GNU_SOURCE 1 + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Must match definitions in arch/sim/include/spinlock.h */ + +#define SP_UNLOCKED 0 /* The Un-locked state */ +#define SP_LOCKED 1 /* The Locked state */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* Must match definitions in arch/sim/include/spinlock.h. Assuming that + * bool and unsigned char are equivalent. + */ + +typedef unsigned char spinlock_t; + +/* Task entry point type */ + +typedef int (*main_t)(int argc, char **argv); + +struct sim_cpuinfo_s +{ + int cpu; /* CPU number */ + pthread_mutex_t mutex; /* For synchronization */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static pthread_key_t g_cpukey; +static pthread_t g_sim_cputhread[CONFIG_SMP_NCPUS]; +static volatile unsigned char g_sim_cpupaused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_sim_cpuwait[CONFIG_SMP_NCPUS]; + +/**************************************************************************** + * NuttX domain function prototypes + ****************************************************************************/ + +void os_start(void) __attribute__ ((noreturn)); +void sim_cpu_pause(int cpu, volatile spinlock_t *wait, + volatile unsigned char *paused); +void sim_smp_hook(void); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_cpu0_trampoline + * + * Description: + * This is a pthread task entry point. This (host) pthread is used to + * simulate a CPU0. It simply calls OS start. + * + * Input Parameters: + * arg - Standard pthread argument + * + * Returned Value: + * This function does not return + * + ****************************************************************************/ + +static void *sim_cpu0_trampoline(void *arg) +{ + sigset_t set; + int ret; + + /* Set the CPU number zero for the CPU thread */ + + ret = pthread_setspecific(g_cpukey, (const void *)0); + if (ret != 0) + { + return NULL; + } + + /* Make sure the SIGUSR1 is not masked */ + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + ret = pthread_sigmask(SIG_UNBLOCK, &set, NULL); + if (ret < 0) + { + return NULL; + } + + /* Give control to os_start() */ + + os_start(); + + /* os_start() should not return */ + + return NULL; +} + +/**************************************************************************** + * Name: sim_idle_trampoline + * + * Description: + * This is a pthread task entry point. A (host) pthread is used to + * simulate a CPU. Multiple pthreads is a good analog to tasks running on + * multiple CPUs + * + * This function is simply a wrapper that sets the pthread specific data + * that presents the CPU number and then calls into the IDLE task entry + * point. + * + * Input Parameters: + * arg - Standard pthread argument + * + * Returned Value: + * This function does not return + * + ****************************************************************************/ + +static void *sim_idle_trampoline(void *arg) +{ + struct sim_cpuinfo_s *cpuinfo = (struct sim_cpuinfo_s *)arg; + sigset_t set; + int ret; + + /* Set the CPU number zero for the CPU thread */ + + ret = pthread_setspecific(g_cpukey, (const void *)((uintptr_t)cpuinfo->cpu)); + if (ret != 0) + { + return NULL; + } + + /* Make sure the SIGUSR1 is not masked */ + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + ret = pthread_sigmask(SIG_UNBLOCK, &set, NULL); + if (ret < 0) + { + return NULL; + } + + /* Let up_cpu_start() continue */ + + (void)pthread_mutex_unlock(&cpuinfo->mutex); + + /* Give control to the IDLE task via the nasty little sim_smp_hook(). + * sim_smp_hook() is logically a part of this function but needs to be + * inserted in the path because in needs to access NuttX domain definitions. + */ + + sim_smp_hook(); + + /* The IDLE task will not return. This is just to keep the compiler happy */ + + return NULL; +} + +/**************************************************************************** + * Name: sim_handle_signal + * + * Description: + * This is the SIGUSR signal handler. It implements the core logic of + * up_cpu_pause() on the thread of execution the simulated CPU. + * + * Input Parameters: + * arg - Standard sigaction arguments + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sim_handle_signal(int signo, siginfo_t *info, void *context) +{ + int cpu = (int)((uintptr_t)pthread_getspecific(g_cpukey)); + + /* We need to perform the actual tasking operations in the NuttX domain */ + + sim_cpu_pause(cpu, &g_sim_cpuwait[cpu], &g_sim_cpupaused[cpu]); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_cpu0_initialize + * + * Description: + * Create the pthread-specific data key and set the indication of CPU0 + * the the main thread. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +int sim_cpu0_initialize(void) +{ + struct sigaction act; + sigset_t set; + int ret; + + /* Create the pthread key */ + + ret = pthread_key_create(&g_cpukey, NULL); + if (ret != 0) + { + return -ret; + } + + /* Register the common signal handler for all threads */ + + act.sa_sigaction = sim_handle_signal; + act.sa_flags = SA_SIGINFO; + sigemptyset(&act.sa_mask); + + ret = sigaction(SIGUSR1, &act, NULL); + if (ret < 0) + { + return -errno; + } + + /* Make sure the SIGUSR1 is not masked */ + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + ret = sigprocmask(SIG_UNBLOCK, &set, NULL); + if (ret < 0) + { + return -errno; + } + + return 0; +} + +/**************************************************************************** + * Name: sim_cpu0_start + * + * Description: + * Start CPU0 and initialize the operating system. + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + +void sim_cpu0_start(void) +{ + void *value; + int ret; + + /* Start the CPU0 emulation thread. This is analogous to power-up reset + * of CPU0 in a multi-CPU hardware model. + */ + + ret = pthread_create(&g_sim_cputhread[0], NULL, sim_cpu0_trampoline, NULL); + if (ret == 0) + { + /* The CPU0 emulation thread should never return, the main thread will + * wait just in case. + */ + + (void)pthread_join(g_sim_cputhread[0], &value); + } +} + +/**************************************************************************** + * Name: up_cpu_index + * + * Description: + * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +int up_cpu_index(void) +{ + void *value = pthread_getspecific(g_cpukey); + return (int)((uintptr_t)value); +} + +/**************************************************************************** + * Name: up_cpu_start + * + * Description: + * In an SMP configution, only one CPU is initially active (CPU 0). System + * initialization occurs on that single thread. At the completion of the + * initialization of the OS, just before beginning normal multitasking, + * the additional CPUs would be started by calling this function. + * + * Each CPU is provided the entry point to is IDLE task when started. A + * TCB for each CPU's IDLE task has been initialized and placed in the + * CPU's g_assignedtasks[cpu] list. Not stack has been alloced or + * initialized. + * + * The OS initialization logic calls this function repeatedly until each + * CPU has been started, 1 through (CONFIG_SMP_NCPUS-1). + * + * Input Parameters: + * cpu - The index of the CPU being started. This will be a numeric + * value in the range of from one to (CONFIG_SMP_NCPUS-1). (CPU + * 0 is already active) + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_start(int cpu) +{ + struct sim_cpuinfo_s cpuinfo; + int ret; + + /* Initialize the CPU info */ + + cpuinfo.cpu = cpu; + ret = pthread_mutex_init(&cpuinfo.mutex, NULL); + if (ret != 0) + { + return -ret; /* REVISIT: That is a host errno value. */ + } + + /* Lock the mutex */ + + ret = pthread_mutex_lock(&cpuinfo.mutex); + if (ret != 0) + { + ret = -ret; /* REVISIT: This is a host errno value. */ + goto errout_with_mutex; + } + + /* Start the CPU emulation thread. This is analogous to starting the CPU + * in a multi-CPU hardware model. + */ + + ret = pthread_create(&g_sim_cputhread[cpu], NULL, sim_idle_trampoline, &cpuinfo); + if (ret != 0) + { + ret = -ret; /* REVISIT: That is a host errno value. */ + goto errout_with_lock; + } + + /* Try to lock the mutex again. This will block until the pthread unlocks + * the mutex. + */ + + ret = pthread_mutex_lock(&cpuinfo.mutex); + if (ret != 0) + { + ret = -ret; /* REVISIT: That is a host errno value. */ + } + +errout_with_lock: + (void)pthread_mutex_unlock(&cpuinfo.mutex); + +errout_with_mutex: + (void)pthread_mutex_destroy(&cpuinfo.mutex); + return ret; +} + +/**************************************************************************** + * Name: up_cpu_pause + * + * Description: + * Save the state of the current task at the head of the + * g_assignedtasks[cpu] task list and then pause task execution on the + * CPU. + * + * This function is called by the OS when the logic executing on one CPU + * needs to modify the state of the g_assignedtasks[cpu] list for another + * CPU. + * + * Input Parameters: + * cpu - The index of the CPU to be stopped/ + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_pause(int cpu) +{ + /* Take the spinlock that will prevent the CPU thread from running */ + + g_sim_cpuwait[cpu] = SP_LOCKED; + + /* Signal the CPU thread */ + + pthread_kill(g_sim_cputhread[cpu], SIGUSR1); + + /* Spin, waiting for the thread to pause */ + + while (!g_sim_cpupaused[cpu]) + { + pthread_yield(); + } + + return 0; +} + +/**************************************************************************** + * Name: up_cpu_resume + * + * Description: + * Restart the cpu after it was paused via up_cpu_pause(), restoring the + * state of the task at the head of the g_assignedtasks[cpu] list, and + * resume normal tasking. + * + * This function is called after up_cpu_pause in order resume operation of + * the CPU after modifying its g_assignedtasks[cpu] list. + * + * Input Parameters: + * cpu - The index of the CPU being re-started. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_resume(int cpu) +{ + /* Release the spinlock that will alloc the CPU thread to continue */ + + g_sim_cpuwait[cpu] = SP_UNLOCKED; + return 0; +} diff --git a/arch/sim/src/up_simuart.c b/arch/sim/src/up_simuart.c new file mode 100644 index 0000000000000000000000000000000000000000..777dc32e15bd89fa9b4db1ef94c0872e229b3b39 --- /dev/null +++ b/arch/sim/src/up_simuart.c @@ -0,0 +1,328 @@ +/**************************************************************************** + * arch/sim/src/up_simuart.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Simulated console UART input buffer size */ +/* Must match the defintion in up_internal.h */ + +#define SIMUART_BUFSIZE 256 + +/* The design for how we signal UART data availability is up in the air */ + +#undef CONFIG_SIM_UART_DATAPOST + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char g_uartbuffer[SIMUART_BUFSIZE]; +static volatile int g_uarthead; +static volatile int g_uarttail; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef CONFIG_SIM_UART_DATAPOST +volatile int g_uart_data_available; +#endif + +/**************************************************************************** + * NuttX Domain Public Function Prototypes + ****************************************************************************/ + +void sched_lock(void); +void sched_unlock(void); + +void simuart_initialize(void); +void simuart_post(void); +void simuart_wait(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct termios g_cooked; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: setrawmode + ****************************************************************************/ + +static void setrawmode(void) +{ + struct termios raw; + + /* Get the current stdin terminal mode */ + + (void)tcgetattr(0, &g_cooked); + + /* Switch to raw mode */ + + memcpy(&raw, &g_cooked, sizeof(struct termios)); + + raw.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + raw.c_oflag &= ~OPOST; + raw.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + raw.c_cflag &= ~(CSIZE | PARENB); + raw.c_cflag |= CS8; + + (void)tcsetattr(0, TCSANOW, &raw); +} + +/**************************************************************************** + * Name: simuart_thread + ****************************************************************************/ + +static void *simuart_thread(void *arg) +{ + unsigned char ch; + ssize_t nread; + int next; + int prev; + + /* Now loop, collecting a buffering data from stdin forever */ + + for (; ; ) + { + /* Read one character from stdin */ + + nread = read(0, &ch, 1); + + /* Check for failures (but don't do anything) */ + + if (nread == 1) + { +#ifdef CONFIG_SIM_UART_DATAPOST + sched_lock(); +#endif + /* Get the index to the next slot in the UART buffer */ + + prev = g_uarthead; + next = prev + 1; + if (next >= SIMUART_BUFSIZE) + { + next = 0; + } + + /* Would adding this character cause an overflow? */ + + if (next != g_uarttail) + { + /* No.. Add the character to the UART buffer */ + + g_uartbuffer[prev] = ch; + + /* Update the head index (BEFORE posting) */ + + g_uarthead = next; + + /* Was the buffer previously empty? */ + + if (prev == g_uarttail) + { + /* Yes.. signal any (NuttX) threads waiting for serial + * input. + */ + +#ifdef CONFIG_SIM_UART_DATAPOST + simuart_post(); +#else + g_uart_data_available = 1; +#endif + } + } + +#ifdef CONFIG_SIM_UART_DATAPOST + /* REVISIT: This is very weird and scary here. When sched_unlock() + * is called, we may do a lonjmp() style context switch meaning + * that the logic will be run running on this thread! (but with a + * different stack). So we do not get back here until the task + * sleeps again. I can't help but believe that that is going to + * be a problem someday. + */ + + sched_unlock(); +#endif + } + } + + return NULL; +} + +/**************************************************************************** + * Name: simuart_putraw + ****************************************************************************/ + +int simuart_putraw(int ch) +{ + ssize_t nwritten; + + nwritten = write(1, &ch, 1); + if (nwritten != 1) + { + return -1; + } + + return ch; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: simuart_start + ****************************************************************************/ + +void simuart_start(void) +{ + pthread_t tid; + + /* This thread runs in the host domain */ + /* Perform the NuttX domain initialization */ + + simuart_initialize(); + + /* Put stdin into raw mode */ + + setrawmode(); + + /* Start the simulated UART thread -- all default settings; no error + * checking. + */ + + (void)pthread_create(&tid, NULL, simuart_thread, NULL); +} + +/**************************************************************************** + * Name: simuart_putc + ****************************************************************************/ + +int simuart_putc(int ch) +{ + int ret = ch; + + if (ch == '\n') + { + ret = simuart_putraw('\r'); + } + + if (ret >= 0) + { + ret = simuart_putraw(ch); + } + + return ret; +} + +/**************************************************************************** + * Name: simuart_getc + ****************************************************************************/ + +int simuart_getc(void) +{ + int index; + int ch; + + /* Locking the scheduler should eliminate the race conditions in the + * unlikely case of multiple reading threads. + */ + + sched_lock(); + for (; ; ) + { + /* Wait for a byte to become available */ + + while (g_uarthead == g_uarttail) + { + simuart_wait(); + } + + /* The UART buffer is non-empty... Take the next byte from the tail + * of the buffer. + */ + + index = g_uarttail; + ch = (int)g_uartbuffer[index]; + + /* Increment the tai index (with wrapping) */ + + if (++index >= SIMUART_BUFSIZE) + { + index = 0; + } + + g_uarttail = index; + sched_unlock(); + return ch; + } +} + +/**************************************************************************** + * Name: simuart_getc + ****************************************************************************/ + +bool simuart_checkc(void) +{ + return g_uarthead != g_uarttail; +} + +/**************************************************************************** + * Name: simuart_terminate + ****************************************************************************/ + +void simuart_terminate(void) +{ + /* Restore the original terminal mode */ + + (void)tcsetattr(0, TCSANOW, &g_cooked); +} diff --git a/arch/sim/src/up_smphook.c b/arch/sim/src/up_smphook.c new file mode 100644 index 0000000000000000000000000000000000000000..7c008a7d3d30ec2cea0998321a6ac2184d5fbd8a --- /dev/null +++ b/arch/sim/src/up_smphook.c @@ -0,0 +1,108 @@ +/**************************************************************************** + * arch/sim/src/up_simhook.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "sched/sched.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_cpu_initialize + * + * Description: + * After the CPU has been started (via up_cpu_start()) the system will + * call back into the architecture-specific code with this function on the + * thread of execution of the newly started CPU. This gives the + * architecture-specific a chance to perform ny initial, CPU-specific + * initialize on that thread. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_cpu_initialize(void) +{ + return OK; +} + +/**************************************************************************** + * Name: sim_smp_hook + * + * Description: + * This is a mindless little hook between sim_idle_trampoline() and the + * real IDLE task logic. This is only needed because we need to access + * elements of the TCB in the simulation domain but sim_idle_trampoline() + * lies in the host domain. + * + * Input Parameters: + * None + * + * Returned Value: + * None (should not return) + * + ****************************************************************************/ + +void sim_smp_hook(void) +{ + struct tcb_s *tcb = this_task(); + DEBUGASSERT(tcb != NULL && tcb->start != NULL); + + /* Transfer control to the "real" thread start-up routine */ + + tcb->start(); + + /* That function should not return. */ + + PANIC(); +} + +#endif /* CONFIG_SMP */ diff --git a/arch/sim/src/up_smpsignal.c b/arch/sim/src/up_smpsignal.c new file mode 100644 index 0000000000000000000000000000000000000000..58582d0df96bcef5f868fe56602a2fe1afbee8b3 --- /dev/null +++ b/arch/sim/src/up_smpsignal.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/sim/src/up_simsmp.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_cpu_pause + * + * Description: + * This is the SIGUSR1 signal handling logic. It implements the core + * logic of up_cpu_pause() on the thread of execution the simulated CPU. + * This is the part of the implementation that must be performed in the + * NuttX vs. the host domain. + * + * Input Parameters: + * cpu - The CPU being paused. + * wait - Spinlock to wait on to be un-paused + * paused - A boolean to set when we are in the paused state. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sim_cpu_pause(int cpu, volatile spinlock_t *wait, + volatile unsigned char *paused) +{ + struct tcb_s *rtcb = current_task(cpu); + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Copy the exception context into the TCB at the (old) head of the + * CPUs assigned task list. if up_setjmp returns a non-zero value, then + * this is really the previously running task restarting! + */ + + if (up_setjmp(rtcb->xcp.regs) == 0) + { + /* Indicate that we are in the paused state */ + + *paused = 1; + + /* Spin until we are asked to resume. When we resume, we need to + * inicate that we are not longer paused. + */ + + spin_lock(wait); + *paused = 0; + + /* While we were paused, logic on a different CPU probably changed + * the task as that head of the assigned task list. So now we need + * restore the exception context of the rtcb at the (new) head + * of the assigned list in order to instantiate the new task. + */ + + rtcb = current_task(cpu); + + /* The way that we handle signals in the simulation is kind of a + * kludge. This would be unsafe in a truly multi-threaded, + * interrupt driven environment. + */ + + if (rtcb->xcp.sigdeliver) + { + sdbg("CPU%d: Delivering signals TCB=%p\n", cpu, rtcb); + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + rtcb->xcp.sigdeliver = NULL; + } + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_longjmp(rtcb->xcp.regs, 1); + } +} + +#endif /* CONFIG_SMP */ + diff --git a/arch/sim/src/up_spiflash.c b/arch/sim/src/up_spiflash.c new file mode 100644 index 0000000000000000000000000000000000000000..9c516972f0bf666d620da525bd0c4e0bf4567146 --- /dev/null +++ b/arch/sim/src/up_spiflash.c @@ -0,0 +1,876 @@ +/************************************************************************************ + * arch/sim/src/up_spiflash.c + * + * Copyright (C) 2014 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_internal.h" + +#if defined(CONFIG_SIM_SPIFLASH) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +/* Debug ****************************************************************************/ +/* Check if (non-standard) SPI debug is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/* Define the FLASH SIZE in bytes */ + +#ifdef CONFIG_SIM_SPIFLASH_1M +# define CONFIG_SPIFLASH_SIZE (128 * 1024) +# define CONFIG_SPIFLASH_CAPACITY 0x11 + +#ifndef CONFIG_SIM_SPIFLASH_SECTORSIZE +# define CONFIG_SIM_SPIFLASH_SECTORSIZE 2048 +#endif + +#endif + +#ifdef CONFIG_SIM_SPIFLASH_8M +# define CONFIG_SPIFLASH_SIZE (1024 * 1024) +# define CONFIG_SPIFLASH_CAPACITY 0x14 +#endif + +#ifdef CONFIG_SIM_SPIFLASH_32M +# define CONFIG_SPIFLASH_SIZE (4 * 1024 * 1024) +# define CONFIG_SPIFLASH_CAPACITY 0x16 +#endif + +#ifdef CONFIG_SIM_SPIFLASH_64M +# define CONFIG_SPIFLASH_SIZE (8 * 1024 * 1024) +# define CONFIG_SPIFLASH_CAPACITY 0x17 +#endif + +#ifdef CONFIG_SIM_SPIFLASH_128M +# define CONFIG_SPIFLASH_SIZE (16 * 1024 * 1024) +# define CONFIG_SPIFLASH_CAPACITY 0x18 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_MANUFACTURER +# define CONFIG_SIM_SPIFLASH_MANUFACTURER 0x20 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_MEMORY_TYPE +# define CONFIG_SIM_SPIFLASH_MEMORY_TYPE 0x20 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_SECTORSIZE +# define CONFIG_SIM_SPIFLASH_SECTORSIZE 65536 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_SUBSECTORSIZE +# define CONFIG_SIM_SPIFLASH_SUBSECTORSIZE 4096 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_SECTORSIZE_MASK +# define CONFIG_SIM_SPIFLASH_SECTORSIZE_MASK (~(CONFIG_SIM_SPIFLASH_SECTORSIZE-1)) +#endif + +#ifndef CONFIG_SIM_SPIFLASH_SUBSECTORSIZE_MASK +# define CONFIG_SIM_SPIFLASH_SUBSECTORSIZE_MASK (~(CONFIG_SIM_SPIFLASH_SUBSECTORSIZE-1)) +#endif + +#ifndef CONFIG_SIM_SPIFLASH_PAGESIZE +# define CONFIG_SIM_SPIFLASH_PAGESIZE 256 +#endif + +#ifndef CONFIG_SIM_SPIFLASH_PAGESIZE_MASK +# define CONFIG_SIM_SPIFLASH_PAGESIZE_MASK (CONFIG_SIM_SPIFLASH_PAGESIZE-1) +#endif + +/* Define FLASH States */ + +#define SPIFLASH_STATE_IDLE 0 +#define SPIFLASH_STATE_RDID1 1 +#define SPIFLASH_STATE_RDID2 2 +#define SPIFLASH_STATE_RDID3 3 +#define SPIFLASH_STATE_WREN 4 +#define SPIFLASH_STATE_RDSR 5 +#define SPIFLASH_STATE_SE1 6 +#define SPIFLASH_STATE_SE2 7 +#define SPIFLASH_STATE_SE3 8 +#define SPIFLASH_STATE_PP1 9 +#define SPIFLASH_STATE_PP2 10 +#define SPIFLASH_STATE_PP3 11 +#define SPIFLASH_STATE_PP4 12 +#define SPIFLASH_STATE_READ1 13 +#define SPIFLASH_STATE_READ2 14 +#define SPIFLASH_STATE_READ3 15 +#define SPIFLASH_STATE_READ4 16 +#define SPIFLASH_STATE_FREAD_WAIT 17 + +/* Instructions */ +/* Command Value N Description Addr Dummy Data */ +#define SPIFLASH_WREN 0x06 /* 1 Write Enable 0 0 0 */ +#define SPIFLASH_WRDI 0x04 /* 1 Write Disable 0 0 0 */ +#define SPIFLASH_RDID 0x9f /* 1 Read Identification 0 0 1-3 */ +#define SPIFLASH_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */ +#define SPIFLASH_WRSR 0x01 /* 1 Write Status Register 0 0 1 */ +#define SPIFLASH_READ 0x03 /* 1 Read Data Bytes 3 0 >=1 */ +#define SPIFLASH_FAST_READ 0x0b /* 1 Higher speed read 3 1 >=1 */ +#define SPIFLASH_PP 0x02 /* 1 Page Program 3 0 1-256 */ +#define SPIFLASH_SE 0xd8 /* 1 Sector Erase 3 0 0 */ +#define SPIFLASH_BE 0xc7 /* 1 Bulk Erase 0 0 0 */ +#define SPIFLASH_DP 0xb9 /* 2 Deep power down 0 0 0 */ +#define SPIFLASH_RES 0xab /* 2 Read Electronic Signature 0 3 >=1 */ +#define SPIFLASH_SSE 0x20 /* 3 Sub-Sector Erase 0 0 0 */ + +#define SPIFLASH_DUMMY 0xa5 + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct sim_spiflashdev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t selected; /* SPIn base address */ + int wren; + int state; + uint16_t read_data; + uint8_t last_cmd; + unsigned long address; + unsigned char data[CONFIG_SPIFLASH_SIZE]; +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* SPI methods */ + +static int spiflash_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spiflash_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spiflash_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spiflash_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spiflash_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spiflash_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +static void spiflash_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); +static uint8_t spiflash_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +static int spiflash_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#ifndef CONFIG_SPI_EXCHANGE +static void spiflash_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spiflash_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + +static void spiflash_writeword(FAR struct sim_spiflashdev_s *priv, uint16_t data); +static uint16_t spiflash_readword(FAR struct sim_spiflashdev_s *priv); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + .lock = spiflash_lock, + .select = spiflash_select, + .setfrequency = spiflash_setfrequency, + .setmode = spiflash_setmode, + .setbits = spiflash_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = spiflash_status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = spiflash_cmddata, +#endif + .send = spiflash_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spiflash_exchange, +#else + .sndblock = spiflash_sndblock, + .recvblock = spiflash_recvblock, +#endif + .registercallback = 0, +}; + +struct sim_spiflashdev_s g_spidev = +{ + .spidev = { &g_spiops }, +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: spiflash_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ************************************************************************************/ + +static int spiflash_lock(FAR struct spi_dev_s *dev, bool lock) +{ + return OK; +} + +/************************************************************************************ + * Name: spiflash_select + * + * Description: + * Process select logic for the FLASH. + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spiflash_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected) +{ + FAR struct sim_spiflashdev_s *priv = (FAR struct sim_spiflashdev_s *)dev; + + if (devid == SPIDEV_FLASH) + { + priv->selected = selected; + + /* As part of an de-select, ensure the WREN bit is cleared */ + + if (!selected) + { + if (priv->last_cmd != SPIFLASH_WREN) + { + priv->wren = 0; + } + + priv->state = SPIFLASH_STATE_IDLE; + } + } +} + +/************************************************************************************ + * Name: spiflash_cmddata + * + * Description: + * Perform SPI Command operations + * + * Returned Value: + * Always returns zero + * + ************************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +static int spiflash_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) +{ + return 0; +} +#endif + +/************************************************************************************ + * Name: spiflash_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spiflash_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + return frequency; +} + +/************************************************************************************ + * Name: spiflash_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spiflash_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ +} + +/************************************************************************************ + * Name: spiflash_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spiflash_setbits(FAR struct spi_dev_s *dev, int nbits) +{ +} + +/************************************************************************************ + * Name: spiflash_status + * + * Description: + * Set the SPI bus status + * + * Returned Value: + * Always returns zero + * + ************************************************************************************/ + +static uint8_t spiflash_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) +{ + return 0; +} + +/************************************************************************************ + * Name: spiflash_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spiflash_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct sim_spiflashdev_s *priv = (FAR struct sim_spiflashdev_s *)dev; + uint16_t ret; + + if (priv->selected) + { + spiflash_writeword(priv, wd); + ret = spiflash_readword(priv); + } + else + { + ret = 0xff; + } + + return ret; +} + +/************************************************************************************ + * Name: spiflash_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spiflash_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* 8-bit mode */ + + FAR const uint8_t *src = (FAR const uint8_t *)txbuffer; + FAR uint8_t *dest = (FAR uint8_t *)rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t)spiflash_send(dev, (uint16_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } +} + +/************************************************************************************ + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spiflash_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spiflash_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spiflash_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spiflash_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/************************************************************************************ + * Name: spiflash_sectorerase + * + * Description: + * Erase one sector + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spiflash_sectorerase(FAR struct sim_spiflashdev_s *priv) +{ + uint32_t address; + uint32_t len; + + /* Ensure the WREN bit is set before any erase operation */ + + if (priv->wren) + { + address = priv->address; + if (priv->last_cmd == SPIFLASH_SE) + { + address &= CONFIG_SIM_SPIFLASH_SECTORSIZE_MASK; + len = CONFIG_SIM_SPIFLASH_SECTORSIZE; + } + else if (priv->last_cmd == SPIFLASH_SSE) + { + address &= CONFIG_SIM_SPIFLASH_SUBSECTORSIZE_MASK; + len = CONFIG_SIM_SPIFLASH_SUBSECTORSIZE; + } + + /* Now perform the erase */ + + memset(&priv->data[address], 0xFF, len); + } +} + +/************************************************************************************ + * Name: spiflash_writeword + * + * Description: + * Write a word (byte in our case) to the FLASH state machine. + * + * Input Parameters: + * dev - Device-specific state data + * data - the data to send to the simulated FLASH + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spiflash_writeword(FAR struct sim_spiflashdev_s *priv, uint16_t data) +{ + switch (priv->state) + { + case SPIFLASH_STATE_IDLE: + priv->last_cmd = data; + priv->read_data = 0xff; + switch (data) + { + case SPIFLASH_RDID: + priv->state = SPIFLASH_STATE_RDID1; + break; + + case SPIFLASH_WREN: + priv->wren = 1; + priv->state = SPIFLASH_STATE_WREN; + break; + + case SPIFLASH_RDSR: + priv->state = SPIFLASH_STATE_RDSR; + break; + + /* Sector / Subsector erase */ + + case SPIFLASH_SE: + case SPIFLASH_SSE: + priv->state = SPIFLASH_STATE_SE1; + break; + + /* Bulk Erase */ + + case SPIFLASH_BE: + priv->state = SPIFLASH_STATE_IDLE; + if (priv->wren) + { + memset(priv->data, 0xff, CONFIG_SPIFLASH_SIZE); + } + break; + + case SPIFLASH_PP: + priv->state = SPIFLASH_STATE_PP1; + break; + + case SPIFLASH_READ: + case SPIFLASH_FAST_READ: + priv->state = SPIFLASH_STATE_READ1; + break; + + default: + break; + } + break; + + /* Read ID States */ + + case SPIFLASH_STATE_RDID1: + priv->read_data = CONFIG_SIM_SPIFLASH_MANUFACTURER; + priv->state = SPIFLASH_STATE_RDID2; + break; + + case SPIFLASH_STATE_RDID2: + priv->read_data = CONFIG_SIM_SPIFLASH_MEMORY_TYPE; + priv->state = SPIFLASH_STATE_RDID3; + break; + + case SPIFLASH_STATE_RDID3: + priv->read_data = CONFIG_SPIFLASH_CAPACITY; + priv->state = SPIFLASH_STATE_IDLE; + break; + + /* WREN state - if we receive any bytes here, then we abort the WREN */ + + case SPIFLASH_STATE_WREN: + priv->wren = 0; + break; + + /* Read Status Register state */ + + case SPIFLASH_STATE_RDSR: + priv->read_data = 0; + priv->state = SPIFLASH_STATE_IDLE; + break; + + /* Sector and Sub-Sector erase states - Read the address */ + + case SPIFLASH_STATE_SE1: + priv->address = data << 16; + priv->state = SPIFLASH_STATE_SE2; + break; + + case SPIFLASH_STATE_SE2: + priv->address |= data << 8; + priv->state = SPIFLASH_STATE_SE3; + break; + + case SPIFLASH_STATE_SE3: + priv->address |= data; + + /* Now perform the sector or sub-sector erase. Really this should + * be done during the deselect, but this is just a simulation . + */ + + spiflash_sectorerase(priv); + break; + + /* Page Program. We could reuse the SE states, but let's keep it clean. */ + + case SPIFLASH_STATE_PP1: + priv->address = data << 16; + priv->state = SPIFLASH_STATE_PP2; + break; + + case SPIFLASH_STATE_PP2: + priv->address |= data << 8; + priv->state = SPIFLASH_STATE_PP3; + break; + + case SPIFLASH_STATE_PP3: + priv->address |= data; + priv->state = SPIFLASH_STATE_PP4; + break; + + case SPIFLASH_STATE_PP4: + /* In this state we actually write data (if WREN enabled) */ + + if (priv->wren) + { + priv->data[priv->address] = data; + } + + /* Now increment the address. We do a page wrap here to simulate + * the actual FLASH. + */ + + if ((priv->address & CONFIG_SIM_SPIFLASH_PAGESIZE_MASK) == + CONFIG_SIM_SPIFLASH_PAGESIZE_MASK) + { + priv->address &= !CONFIG_SIM_SPIFLASH_PAGESIZE_MASK; + } + else + { + priv->address++; + } + break; + + /* Read data */ + + case SPIFLASH_STATE_READ1: + priv->address = data << 16; + priv->state = SPIFLASH_STATE_READ2; + break; + + case SPIFLASH_STATE_READ2: + priv->address |= data << 8; + priv->state = SPIFLASH_STATE_READ3; + break; + + case SPIFLASH_STATE_READ3: + priv->address |= data; + if (priv->last_cmd == SPIFLASH_FAST_READ) + { + priv->state = SPIFLASH_STATE_FREAD_WAIT; + } + else + { + priv->state = SPIFLASH_STATE_READ4; + } + break; + + case SPIFLASH_STATE_FREAD_WAIT: + priv->read_data = 0xff; + priv->state = SPIFLASH_STATE_READ4; + break; + + case SPIFLASH_STATE_READ4: + /* In this state perform data reads until de-selected. */ + + priv->read_data = priv->data[priv->address++]; + if (priv->address == CONFIG_SPIFLASH_SIZE) + { + priv->address = 0; + } + break; + + default: + priv->state = SPIFLASH_STATE_IDLE; + priv->read_data = 0xFF; + break; + } +} + +/************************************************************************************ + * Name: spiflash_readword + * + * Description: + * Read a word (byte in our case) from the simulated FLASH. + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte read from the simulated FLASH device + * + ************************************************************************************/ + +static uint16_t spiflash_readword(FAR struct sim_spiflashdev_s *priv) +{ + return priv->read_data; +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_spiflashinitialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *up_spiflashinitialize() +{ + FAR struct sim_spiflashdev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); + + priv = &g_spidev; + priv->selected = 0; + priv->wren = 0; + priv->address = 0; + priv->state = SPIFLASH_STATE_IDLE; + priv->read_data = 0xFF; + priv->last_cmd = 0xFF; + memset(&priv->data[0], 0xFF, sizeof(priv->data)); + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_SIM_SPIFLASH */ diff --git a/arch/sim/src/up_stackframe.c b/arch/sim/src/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..dae90242ace72fa9b26056dfeeeced54685d7de6 --- /dev/null +++ b/arch/sim/src/up_stackframe.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/sim/src/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* Use a stack alignment of 4 bytes. If necessary frame_size must be rounded + * up to the next boundary + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial state */ + + tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr; + + /* And return a pointer to the allocated memory */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/sim/src/up_tapdev.c b/arch/sim/src/up_tapdev.c new file mode 100644 index 0000000000000000000000000000000000000000..4fc1394e377e49e911072d8a001481abb72896a8 --- /dev/null +++ b/arch/sim/src/up_tapdev.c @@ -0,0 +1,281 @@ +/**************************************************************************** + * arch/sim/src/up_tapdev.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on code from uIP which also has a BSD-like license: + * + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __CYGWIN__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TAPDEV_DEBUG 1 + +#define DEVTAP "/dev/net/tun" + +#ifndef CONFIG_EXAMPLES_WEBSERVER_DHCPC +# define TAP_IPADDR0 192 +# define TAP_IPADDR1 168 +# define TAP_IPADDR2 0 +# define TAP_IPADDR3 128 +#else +# define TAP_IPADDR0 0 +# define TAP_IPADDR1 0 +# define TAP_IPADDR2 0 +# define TAP_IPADDR3 0 +#endif + +/* Syslog priority (must match definitions in nuttx/include/syslog.h) */ + +#define LOG_INFO 1 /* Informational message */ +#define LOG_ERR 4 /* Error conditions */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Warning: This is very much Linux version specific! */ + +struct sel_arg_struct +{ + unsigned long n; + fd_set *inp; + fd_set *outp; + fd_set *exp; + struct timeval *tvp; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * NuttX Domain Public Function Prototypes + ****************************************************************************/ + +int syslog(int priority, const char *format, ...); +int netdriver_setmacaddr(unsigned char *macaddr); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef TAPDEV_DEBUG +static int gdrop = 0; +#endif +static int gtapdevfd; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef TAPDEV_DEBUG +static inline void dump_ethhdr(const char *msg, unsigned char *buf, int buflen) +{ + syslog(LOG_INFO, "TAPDEV: %s %d bytes\n", msg, buflen); + syslog(LOG_INFO, + " %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], +#ifdef CONFIG_ENDIAN_BIG + buf[13], buf[12]); +#else + buf[12], buf[13]); +#endif +} +#else +# define dump_ethhdr(m,b,l) +#endif + +static int up_setmacaddr(void) +{ + int sockfd; + int ret = -1; + + /* Get a socket (only so that we get access to the INET subsystem) */ + + sockfd = socket(PF_INET, SOCK_DGRAM, 0); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strncpy(req.ifr_name, "tap0", IFNAMSIZ); + + /* Perform the ioctl to get the MAC address */ + + ret = ioctl(sockfd, SIOCGIFHWADDR, (unsigned long)&req); + if (!ret) + { + /* Set the MAC address */ + + ret = netdriver_setmacaddr((unsigned char *)&req.ifr_hwaddr.sa_data); + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void tapdev_init(void) +{ + struct ifreq ifr; + char buf[1024]; + int ret; + + /* Open the tap device */ + + gtapdevfd = open(DEVTAP, O_RDWR, 0644); + if (gtapdevfd < 0) + { + syslog(LOG_ERR, "TAPDEV: open failed: %d\n", -gtapdevfd); + return; + } + + /* Configure the tap device */ + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + ret = ioctl(gtapdevfd, TUNSETIFF, (unsigned long) &ifr); + if (ret < 0) + { + syslog(LOG_ERR, "TAPDEV: ioctl failed: %d\n", -ret); + return; + } + + /* Assign an IPv4 address to the tap device */ + + snprintf(buf, sizeof(buf), "/sbin/ifconfig tap0 inet %d.%d.%d.%d\n", + TAP_IPADDR0, TAP_IPADDR1, TAP_IPADDR2, TAP_IPADDR3); + system(buf); + + /* Set the MAC address */ + + up_setmacaddr(); +} + +unsigned int tapdev_read(unsigned char *buf, unsigned int buflen) +{ + fd_set fdset; + struct timeval tv; + int ret; + + /* We can't do anything if we failed to open the tap device */ + + if (gtapdevfd < 0) + { + return 0; + } + + /* Wait for data on the tap device (or a timeout) */ + + tv.tv_sec = 0; + tv.tv_usec = 1000; + + FD_ZERO(&fdset); + FD_SET(gtapdevfd, &fdset); + + ret = select(gtapdevfd + 1, &fdset, NULL, NULL, &tv); + if (ret == 0) + { + return 0; + } + + ret = read(gtapdevfd, buf, buflen); + if (ret < 0) + { + syslog(LOG_ERR, "TAPDEV: read failed: %d\n", -ret); + return 0; + } + + dump_ethhdr("read", buf, ret); + return ret; +} + +void tapdev_send(unsigned char *buf, unsigned int buflen) +{ + int ret; +#ifdef TAPDEV_DEBUG + syslog(LOG_INFO, "tapdev_send: sending %d bytes\n", buflen); + + gdrop++; + if (gdrop % 8 == 7) + { + syslog(LOG_ERR, "TAPDEV: Dropped a packet!\n"); + return; + } +#endif + + ret = write(gtapdevfd, buf, buflen); + if (ret < 0) + { + syslog(LOG_ERR, "TAPDEV: write failed: %d", -ret); + exit(1); + } + dump_ethhdr("write", buf, buflen); +} + +#endif /* !__CYGWIN__ */ + + diff --git a/arch/sim/src/up_testset.c b/arch/sim/src/up_testset.c new file mode 100644 index 0000000000000000000000000000000000000000..30cb64c0ef5a5453c4d1cc08cd9c1065a86aaffa --- /dev/null +++ b/arch/sim/src/up_testset.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/sim/src/up_testset.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Must match definitions in arch/sim/include/spinlock.h */ + +#define SP_UNLOCKED 0 /* The Un-locked state */ +#define SP_LOCKED 1 /* The Locked state */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* Must match definitions in arch/sim/include/spinlock.h */ + +typedef uint8_t spinlock_t; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SMP +static pthread_mutex_t g_tsmutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + +spinlock_t up_testset(volatile spinlock_t *lock) +{ +#ifdef CONFIG_SMP + /* In the multi-CPU SMP case, we use a mutex to assure that the following + * test and set is atomic. + */ + + (void)pthread_mutex_lock(&g_tsmutex); +#endif + + /* In the non-SMP case, the simulation is implemented with a single thread + * the test-and-set operation is inherently atomic. + */ + + spinlock_t ret = *lock; + *lock = SP_LOCKED; + +#ifdef CONFIG_SMP + (void)pthread_mutex_unlock(&g_tsmutex); +#endif + return ret; +} diff --git a/arch/sim/src/up_tickless.c b/arch/sim/src/up_tickless.c new file mode 100644 index 0000000000000000000000000000000000000000..11177de5c55fdcf9967f75175e1a03fa743405f7 --- /dev/null +++ b/arch/sim/src/up_tickless.c @@ -0,0 +1,330 @@ +/**************************************************************************** + * arch/sim/src/up_tickless.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Tickless OS Support. + * + * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts + * is suppressed and the platform specific code is expected to provide the + * following custom functions. + * + * void up_timer_initialize(void): Initializes the timer facilities. Called + * early in the intialization sequence (by up_intialize()). + * int up_timer_gettime(FAR struct timespec *ts): Returns the current + * time from the platform specific time source. + * int up_timer_cancel(void): Cancels the interval timer. + * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts) + * the interval timer. + * + * The RTOS will provide the following interfaces for use by the platform- + * specific interval timer implementation: + * + * void sched_timer_expiration(void): Called by the platform-specific + * logic when the interval timer expires. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#ifdef CONFIG_SCHED_TICKLESS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_SIM_WALLTIME) || defined(CONFIG_SIM_X11FB) +# define TICK_USEC (USEC_PER_SEC / CLK_TCK) +# define TICK_SEC (TICK_USEC / USEC_PER_SEC) +# define TICK_NSEC ((TICK_USEC % NSEC_PER_USEC) * NSEC_PER_USEC) +#else +# define TICK_SEC 0 +# define TICK_NSEC NSEC_PER_TICK +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct timespec g_elapsed_time; +static struct timespec g_interval_delay; +static bool g_timer_active; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Initializes all platform-specific timer facilities. This function is + * called early in the initialization sequence by up_intialize(). + * On return, the current up-time should be available from + * up_timer_gettime() and the interval timer is ready for use (but not + * actively timing. + * + * Provided by platform-specific code and called from the architecture- + * specific logic. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * Called early in the initialization sequence before any special + * concurrency protections are required. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ +} + +/**************************************************************************** + * Name: up_timer_gettime + * + * Description: + * Return the elapsed time since power-up (or, more correctly, since + * up_timer_initialize() was called). This function is functionally + * equivalent to: + * + * int clock_gettime(clockid_t clockid, FAR struct timespec *ts); + * + * when clockid is CLOCK_MONOTONIC. + * + * This function provides the basis for reporting the current time and + * also is used to eliminate error build-up from small erros in interval + * time calculations. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the location in which to return the up-time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * Called from the the normal tasking context. The implementation must + * provide whatever mutual exclusion is necessary for correct operation. + * This can include disabling interrupts in order to assure atomic register + * operations. + * + ****************************************************************************/ + +int up_timer_gettime(FAR struct timespec *ts) +{ + ts->tv_sec = g_elapsed_time.tv_sec; + ts->tv_nsec = g_elapsed_time.tv_nsec; + return OK; +} + +/**************************************************************************** + * Name: up_timer_cancel + * + * Description: + * Cancel the interval timer and return the time remaining on the timer. + * These two steps need to be as nearly atomic as possible. + * sched_timer_expiration() will not be called unless the timer is + * restarted with up_timer_start(). + * + * If, as a race condition, the timer has already expired when this + * function is called, then that pending interrupt must be cleared so + * that up_timer_start() and the remaining time of zero should be + * returned. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Location to return the remaining time. Zero should be returned + * if the timer is not active. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_TICKLESS +int up_timer_cancel(FAR struct timespec *ts) +{ + /* Return the time remaining on the simulated timer */ + + if (g_timer_active) + { + ts->tv_sec = g_interval_delay.tv_sec; + ts->tv_nsec = g_interval_delay.tv_nsec; + } + else + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + /* Disable and reset the simulated timer */ + + g_interval_delay.tv_sec = 0; + g_interval_delay.tv_nsec = 0; + g_timer_active = false; +} +#endif + +/**************************************************************************** + * Name: up_timer_start + * + * Description: + * Start the interval timer. sched_timer_expiration() will be + * called at the completion of the timeout (unless up_timer_cancel + * is called to stop the timing. + * + * Provided by platform-specific code and called from the RTOS base code. + * + * Input Parameters: + * ts - Provides the time interval until sched_timer_expiration() is + * called. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * May be called from interrupt level handling or from the normal tasking + * level. Interrupts may need to be disabled internally to assure + * non-reentrancy. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_TICKLESS +int up_timer_start(FAR const struct timespec *ts) +{ + g_interval_delay.tv_sec = ts->tv_sec; + g_interval_delay.tv_nsec = ts->tv_nsec; + g_timer_active = true; +} +#endif + +/**************************************************************************** + * Name: up_timer_update + * + * Description: + * Called from the IDLE loop to fake one timer tick. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_timer_update(void) +{ + /* Increment the elapsed time */ + + g_elapsed_time.tv_nsec += TICK_NSEC; + if (g_elapsed_time.tv_nsec >= NSEC_PER_SEC) + { + g_elapsed_time.tv_sec++; + g_elapsed_time.tv_nsec -= NSEC_PER_SEC; + } + + g_elapsed_time.tv_sec += TICK_SEC; + + /* Is the interval timer active? */ + + if (g_timer_active) + { + /* Yes... decrement the interval timer */ + + if (g_interval_delay.tv_sec < TICK_SEC) + { + /* No more seconds left... the timer has expired */ + + g_timer_active = false; + sched_timer_expiration(); + } + else + { + /* Decrement seconds. May decrement to zero */ + + g_interval_delay.tv_sec -= TICK_SEC; + + /* Decrement nanoseconds */ + + if (g_interval_delay.tv_nsec >= TICK_NSEC) + { + g_interval_delay.tv_nsec -= TICK_NSEC; + } + + /* Handle borrow from seconds */ + + else if (g_interval_delay.tv_sec > 0) + { + g_interval_delay.tv_nsec += NSEC_PER_SEC; + g_interval_delay.tv_sec--; + + g_interval_delay.tv_nsec -= TICK_NSEC; + } + + /* Otherwise the timer has expired */ + + else + { + g_timer_active = false; + sched_timer_expiration(); + } + } + } +} + +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/sim/src/up_touchscreen.c b/arch/sim/src/up_touchscreen.c new file mode 100644 index 0000000000000000000000000000000000000000..4b4e598f45f741ccc98088cec22ee38c7785adb4 --- /dev/null +++ b/arch/sim/src/up_touchscreen.c @@ -0,0 +1,813 @@ +/**************************************************************************** + * arch/sim/src/up_touchscreen.c + * + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_DISABLE_POLL +# undef CONFIG_SIM_TCNWAITERS +#else +# ifndef CONFIG_SIM_TCNWAITERS +# define CONFIG_SIM_TCNWAITERS 4 +# endif +#endif + +/* Driver support ***********************************************************/ +/* This format is used to construct the /dev/input[n] device driver path. It + * defined here so that it will be used consistently in all places. + */ + +#define DEV_FORMAT "/dev/input%d" +#define DEV_NAMELEN 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This describes the state of one contact */ + +enum up_contact_3 +{ + CONTACT_NONE = 0, /* No contact */ + CONTACT_DOWN, /* First contact */ + CONTACT_MOVE, /* Same contact, possibly different position */ + CONTACT_UP, /* Contact lost */ +}; + +/* This structure describes the results of one touchscreen sample */ + +struct up_sample_s +{ + uint8_t id; /* Sampled touch point ID */ + uint8_t contact; /* Contact state (see enum up_contact_e) */ + uint16_t x; /* Measured X position */ + uint16_t y; /* Measured Y position */ +}; + +/* This structure describes the state of one touchscreen driver instance */ + +struct up_dev_s +{ + volatile uint8_t nwaiters; /* Number of threads waiting for touchscreen data */ + uint8_t id; /* Current touch point ID */ + uint8_t minor; /* Minor device number */ + volatile bool penchange; /* An unreported event is buffered */ + sem_t devsem; /* Manages exclusive access to this structure */ + sem_t waitsem; /* Used to wait for the availability of data */ + + struct up_sample_s sample; /* Last sampled touch point data */ + + /* The following is a list if poll structures of threads waiting for + * driver events. The 'struct pollfd' reference for each open is also + * retained in the f_priv field of the 'struct file'. + */ + +#ifndef CONFIG_DISABLE_POLL + struct pollfd *fds[CONFIG_SIM_TCNWAITERS]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void up_notify(FAR struct up_dev_s *priv); +static int up_sample(FAR struct up_dev_s *priv, + FAR struct up_sample_s *sample); +static int up_waitsample(FAR struct up_dev_s *priv, + FAR struct up_sample_s *sample); + +/* Character driver methods */ + +static int up_open(FAR struct file *filep); +static int up_close(FAR struct file *filep); +static ssize_t up_read(FAR struct file *filep, FAR char *buffer, size_t len); +static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +#ifndef CONFIG_DISABLE_POLL +static int up_poll(FAR struct file *filep, struct pollfd *fds, bool setup); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This the vtable that supports the character driver interface */ + +static const struct file_operations up_fops = +{ + up_open, /* open */ + up_close, /* close */ + up_read, /* read */ + 0, /* write */ + 0, /* seek */ + up_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , up_poll /* poll */ +#endif +}; + +/* Only one simulated touchscreen is supported so the driver state + * structure may as well be pre-allocated. + */ + +static struct up_dev_s g_simtouchscreen; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_notify + ****************************************************************************/ + +static void up_notify(FAR struct up_dev_s *priv) +{ +#ifndef CONFIG_DISABLE_POLL + int i; +#endif + + /* If there are threads waiting for read data, then signal one of them + * that the read data is available. + */ + + ivdbg("contact=%d nwaiters=%d\n", priv->sample.contact, priv->nwaiters); + if (priv->nwaiters > 0) + { + /* After posting this semaphore, we need to exit because the touchscreen + * is no longer avaialable. + */ + + sem_post(&priv->waitsem); + } + + /* If there are threads waiting on poll() for touchscreen data to become availabe, + * then wake them up now. NOTE: we wake up all waiting threads because we + * do not know that they are going to do. If they all try to read the data, + * then some make end up blocking after all. + */ + +#ifndef CONFIG_DISABLE_POLL + for (i = 0; i < CONFIG_SIM_TCNWAITERS; i++) + { + struct pollfd *fds = priv->fds[i]; + if (fds) + { + fds->revents |= POLLIN; + ivdbg("Report events: %02x\n", fds->revents); + sem_post(fds->sem); + } + } +#endif +} + +/**************************************************************************** + * Name: up_sample + ****************************************************************************/ + +static int up_sample(FAR struct up_dev_s *priv, + FAR struct up_sample_s *sample) +{ + int ret = -EAGAIN; + + /* Is there new touchscreen sample data available? */ + + ivdbg("penchange=%d contact=%d id=%d\n", + priv->penchange, sample->contact, priv->id); + + if (priv->penchange) + { + /* Yes.. the state has changed in some way. Return a copy of the + * sampled data. + */ + + memcpy(sample, &priv->sample, sizeof(struct up_sample_s)); + + /* Now manage state transitions */ + + if (sample->contact == CONTACT_UP) + { + /* Next.. no contract. Increment the ID so that next contact ID will be unique */ + + priv->sample.contact = CONTACT_NONE; + priv->id++; + } + else if (sample->contact == CONTACT_DOWN) + { + /* First report -- next report will be a movement */ + + priv->sample.contact = CONTACT_MOVE; + } + + priv->penchange = false; + ivdbg("penchange=%d contact=%d id=%d\n", + priv->penchange, priv->sample.contact, priv->id); + + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: up_waitsample + ****************************************************************************/ + +static int up_waitsample(FAR struct up_dev_s *priv, + FAR struct up_sample_s *sample) +{ + irqstate_t flags; + int ret; + + /* Interrupts me be disabled when this is called to (1) prevent posting + * of semphores from interrupt handlers, and (2) to prevent sampled data + * from changing until it has been reported. + * + * In addition, we will also disable pre-emption to prevent other threads + * from getting control while we muck with the semaphores. + */ + + sched_lock(); + flags = enter_critical_section(); + + /* Now release the semaphore that manages mutually exclusive access to + * the device structure. This may cause other tasks to become ready to + * run, but they cannot run yet because pre-emption is disabled. + */ + + sem_post(&priv->devsem); + + /* Try to get the a sample... if we cannot, then wait on the semaphore + * that is posted when new sample data is available. + */ + + while (up_sample(priv, sample) < 0) + { + /* Wait for a change in the touchscreen state */ + + ivdbg("Waiting...\n"); + priv->nwaiters++; + ret = sem_wait(&priv->waitsem); + priv->nwaiters--; + ivdbg("Awakened...\n"); + + if (ret < 0) + { + /* If we are awakened by a signal, then we need to return + * the failure now. + */ + + DEBUGASSERT(errno == EINTR); + ret = -EINTR; + goto errout; + } + } + + /* Re-acquire the semaphore that manages mutually exclusive access to + * the device structure. We may have to wait here. But we have our sample. + * Interrupts and pre-emption will be re-enabled while we wait. + */ + + ret = sem_wait(&priv->devsem); + +errout: + /* Then re-enable interrupts. We might get interrupt here and there + * could be a new sample. But no new threads will run because we still + * have pre-emption disabled. + */ + + leave_critical_section(flags); + + /* Restore pre-emption. We might get suspended here but that is okay + * because we already have our sample. Note: this means that if there + * were two threads reading from the touchscreen for some reason, the data + * might be read out of order. + */ + + sched_unlock(); + return ret; +} + +/**************************************************************************** + * Name: up_open + ****************************************************************************/ + +static int up_open(FAR struct file *filep) +{ + ivdbg("Opening...\n"); + return OK; +} + +/**************************************************************************** + * Name: up_close + ****************************************************************************/ + +static int up_close(FAR struct file *filep) +{ + ivdbg("Closing...\n"); + return OK; +} + +/**************************************************************************** + * Name: up_read + ****************************************************************************/ + +static ssize_t up_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + FAR struct inode *inode; + FAR struct up_dev_s *priv; + FAR struct touch_sample_s *report; + struct up_sample_s sample; + int ret; + + ivdbg("len=%d\n", len); + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct up_dev_s *)inode->i_private; + + /* Verify that the caller has provided a buffer large enough to receive + * the touch data. + */ + + if (len < SIZEOF_TOUCH_SAMPLE_S(1)) + { + /* We could provide logic to break up a touch report into segments and + * handle smaller reads... but why? + */ + + return -ENOSYS; + } + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + /* Try to read sample data. */ + + ret = up_sample(priv, &sample); + if (ret < 0) + { + /* Sample data is not available now. We would ave to wait to get + * receive sample data. If the user has specified the O_NONBLOCK + * option, then just return an error. + */ + + if (filep->f_oflags & O_NONBLOCK) + { + ret = -EAGAIN; + goto errout; + } + + /* Wait for sample data */ + + ret = up_waitsample(priv, &sample); + if (ret < 0) + { + /* We might have been awakened by a signal */ + + goto errout; + } + } + + /* In any event, we now have sampled touchscreen data that we can report + * to the caller. + */ + + report = (FAR struct touch_sample_s *)buffer; + memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1)); + report->npoints = 1; + report->point[0].id = priv->id; + report->point[0].x = sample.x; + report->point[0].y = sample.y; + report->point[0].h = 1; + report->point[0].w = 1; + report->point[0].pressure = 42; + + /* Report the appropriate flags */ + + if (sample.contact == CONTACT_UP) + { + /* Pen is now up */ + + report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID; + } + else if (sample.contact == CONTACT_DOWN) + { + /* First contact */ + + report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID | TOUCH_PRESSURE_VALID; + } + else /* if (sample->contact == CONTACT_MOVE) */ + { + /* Movement of the same contact */ + + report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID | TOUCH_PRESSURE_VALID; + } + + ret = SIZEOF_TOUCH_SAMPLE_S(1); + +errout: + ivdbg("Returning %d\n", ret); + sem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name:up_ioctl + ****************************************************************************/ + +static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct up_dev_s *priv; + int ret; + + ivdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct up_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + /* Process the IOCTL by command */ + + switch (cmd) + { + default: + ret = -ENOTTY; + break; + } + + sem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: up_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int up_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + FAR struct inode *inode; + FAR struct up_dev_s *priv; + int ret; + int i; + + ivdbg("setup: %d\n", (int)setup); + DEBUGASSERT(filep && fds); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct up_dev_s *)inode->i_private; + + /* Are we setting up the poll? Or tearing it down? */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + if (setup) + { + /* Ignore waits that do not include POLLIN */ + + if ((fds->revents & POLLIN) == 0) + { + ret = -EDEADLK; + goto errout; + } + + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference + */ + + for (i = 0; i < CONFIG_SIM_TCNWAITERS; i++) + { + /* Find an available slot */ + + if (!priv->fds[i]) + { + /* Bind the poll structure and this slot */ + + priv->fds[i] = fds; + fds->priv = &priv->fds[i]; + break; + } + } + + if (i >= CONFIG_SIM_TCNWAITERS) + { + fds->priv = NULL; + ret = -EBUSY; + goto errout; + } + + /* Should we immediately notify on any of the requested events? */ + + if (priv->penchange) + { + up_notify(priv); + } + } + else if (fds->priv) + { + /* This is a request to tear down the poll. */ + + struct pollfd **slot = (struct pollfd **)fds->priv; + DEBUGASSERT(slot != NULL); + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->priv = NULL; + } + +errout: + sem_post(&priv->devsem); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_tsc_setup + * + * Description: + * Configure the simulated touchscreen. This will register the driver as + * /dev/inputN where N is the minor device number + * + * Input Parameters: + * minor - The input device minor number + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_tsc_setup(int minor) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen; + char devname[DEV_NAMELEN]; + int ret; + + ivdbg("minor: %d\n", minor); + + /* Debug-only sanity checks */ + + DEBUGASSERT(minor >= 0 && minor < 100); + + /* Initialize the touchscreen device driver instance */ + + memset(priv, 0, sizeof(struct up_dev_s)); + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ + sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + + priv->minor = minor; + + /* Register the device as an input device */ + + (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); + ivdbg("Registering %s\n", devname); + + ret = register_driver(devname, &up_fops, 0666, priv); + if (ret < 0) + { + idbg("register_driver() failed: %d\n", ret); + goto errout_with_priv; + } + + /* Enable X11 event processing from the IDLE loop */ + + g_eventloop = 1; + + /* And return success */ + + return OK; + +errout_with_priv: + sem_destroy(&priv->waitsem); + sem_destroy(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: board_tsc_teardown + * + * Description: + * Uninitialized the simulated touchscreen + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void board_tsc_teardown(void) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen; + char devname[DEV_NAMELEN]; + int ret; + + /* Get exclusive access */ + + do + { + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + } + } + while (ret != OK); + + /* Stop the event loop (Hmm.. the caller must be sure that there are no + * open references to the touchscreen driver. This might better be + * done in close() using a reference count). + */ + + g_eventloop = 0; + + /* Un-register the device */ + + (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor); + ivdbg("Un-registering %s\n", devname); + + ret = unregister_driver(devname); + if (ret < 0) + { + idbg("uregister_driver() failed: %d\n", ret); + } + + /* Clean up any resources. Ouch! While we are holding the semaphore? */ + + sem_destroy(&priv->waitsem); + sem_destroy(&priv->devsem); +} + +/**************************************************************************** + * Name: up_buttonevent + ****************************************************************************/ + +int up_buttonevent(int x, int y, int buttons) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen; + bool pendown; /* true: pen is down */ + + ivdbg("x=%d y=%d buttons=%02x\n", x, y, buttons); + ivdbg("contact=%d nwaiters=%d\n", priv->sample.contact, priv->nwaiters); + + /* Any button press will count as pendown. */ + + pendown = (buttons != 0); + + /* Handle the change from pen down to pen up */ + + if (!pendown) + { + /* Ignore the pend up if the pen was already up (CONTACT_NONE == pen up and + * already reported. CONTACT_UP == pen up, but not reported) + */ + + if (priv->sample.contact == CONTACT_NONE) + { + return OK; + } + + /* Not yet reported */ + + priv->sample.contact = CONTACT_UP; + } + else + { + /* Save the measurements */ + + priv->sample.x = x; + priv->sample.y = y; + + /* Note the availability of new measurements */ + /* If this is the first (acknowledged) pen down report, then report + * this as the first contact. If contact == CONTACT_DOWN, it will be + * set to set to CONTACT_MOVE after the contact is first sampled. + */ + + if (priv->sample.contact != CONTACT_MOVE) + { + /* First contact */ + + priv->sample.contact = CONTACT_DOWN; + } + } + + /* Indicate the availability of new sample data for this ID */ + + priv->sample.id = priv->id; + priv->penchange = true; + + /* Notify any waiters that new touchscreen data is available */ + + up_notify(priv); + return OK; +} + diff --git a/arch/sim/src/up_uartwait.c b/arch/sim/src/up_uartwait.c new file mode 100644 index 0000000000000000000000000000000000000000..9f6971711693b46672d2308f1d2ee15e22090b94 --- /dev/null +++ b/arch/sim/src/up_uartwait.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/sim/src/up_uartwait.c + * + * Copyright (C) 20014Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_uartavail; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: simuart_initialize + ****************************************************************************/ + +void simuart_initialize(void) +{ + sem_init(&g_uartavail, 0, 0); +} + +/**************************************************************************** + * Name: simuart_post + ****************************************************************************/ + +void simuart_post(void) +{ + sem_post(&g_uartavail); +} + +/**************************************************************************** + * Name: simuart_wait + ****************************************************************************/ + +void simuart_wait(void) +{ + /* Should only fail if interrupted by a signal */ + + while (sem_wait(&g_uartavail) < 0); +} diff --git a/arch/sim/src/up_unblocktask.c b/arch/sim/src/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..148b551973bed735fa4302c10c50a87ebc830854 --- /dev/null +++ b/arch/sim/src/up_unblocktask.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/sim/src/up_unblocktask.c + * + * Copyright (C) 2007-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "clock/clock.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(FAR struct tcb_s *tcb) +{ + FAR struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + sdbg("Unblocking TCB=%p\n", tcb); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! */ + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Copy the exception context into the TCB of the task that was + * previously active. if up_setjmp returns a non-zero value, then + * this is really the previously running task restarting! + */ + + if (!up_setjmp(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + sdbg("New Active Task TCB=%p\n", rtcb); + + /* The way that we handle signals in the simulation is kind of + * a kludge. This would be unsafe in a truly multi-threaded, interrupt + * driven environment. + */ + + if (rtcb->xcp.sigdeliver) + { + sdbg("Delivering signals TCB=%p\n", rtcb); + ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); + rtcb->xcp.sigdeliver = NULL; + } + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_longjmp(rtcb->xcp.regs, 1); + } + } +} diff --git a/arch/sim/src/up_usestack.c b/arch/sim/src/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..2e55fed25749d279be8950fdc50e0e99d02d5805 --- /dev/null +++ b/arch/sim/src/up_usestack.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/sim/src/up_usestack.c + * + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) +{ + FAR size_t *adj_stack_ptr; + size_t adj_stack_size; + size_t adj_stack_words; + +#ifdef CONFIG_TLS + /* Make certain that the user provided stack is properly aligned */ + + DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); +#endif + /* Move up to next even word boundary if necessary */ + + adj_stack_size = stack_size & ~3; + adj_stack_words = adj_stack_size >> 2; + + /* This is the address of the last word in the allocation */ + + adj_stack_ptr = &((FAR size_t *)stack)[adj_stack_words - 1]; + + /* Save the values in the TCB */ + + tcb->adj_stack_size = adj_stack_size; + tcb->stack_alloc_ptr = stack; + tcb->adj_stack_ptr = adj_stack_ptr; + +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(stack, 0, sizeof(struct tls_info_s)); +#endif + + return OK; +} diff --git a/arch/sim/src/up_wpcap.c b/arch/sim/src/up_wpcap.c new file mode 100644 index 0000000000000000000000000000000000000000..69c808c532732572eb3eec0430d90c4972f5370d --- /dev/null +++ b/arch/sim/src/up_wpcap.c @@ -0,0 +1,314 @@ +/**************************************************************************** + * arch/sim/src/up_wcap.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on code from uIP which also has a BSD-like license: + * + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute 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 INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ****************************************************************************/ + +#ifdef __CYGWIN__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0501 +#include +#include +#include + +#include +#include +#include +#include + +#include + + +extern int netdriver_setmacaddr(unsigned char *macaddr); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_EXAMPLES_WEBSERVER_DHCPC +# define WCAP_IPADDR (10 << 24 | 0 << 16 | 0 << 8 | 1) +#else +# define WCAP_IPADDR (0) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +__attribute__ ((dllimport)) extern char **__argv[]; + +struct pcap; + +struct pcap_if +{ + struct pcap_if *next; + char *name; + char *description; + struct pcap_addr + { + struct pcap_addr *next; + struct sockaddr *addr; + struct sockaddr *netmask; + struct sockaddr *broadaddr; + struct sockaddr *dstaddr; + } *addresses; + DWORD flags; +}; + +struct pcap_pkthdr +{ + struct timeval ts; + DWORD caplen; + DWORD len; +}; + +/* DLL function types (for casting) */ + +typedef int (*pcap_findalldevs_t)(struct pcap_if **, char *); +typedef struct pcap *(*pcap_open_live_t)(char *, int, int, int, char *); +typedef int (*pcap_next_ex_t)(struct pcap *, struct pcap_pkthdr **, + unsigned char **); +typedef int (*pcap_sendpacket_t)(struct pcap *, unsigned char *, int); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +HMODULE wpcap; +static struct pcap *pcap; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static pcap_findalldevs_t pcap_findalldevs; +static pcap_open_live_t pcap_open_live; +static pcap_next_ex_t pcap_next_ex; +static pcap_sendpacket_t pcap_sendpacket; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void error_exit(char *message) +{ + printf("error_exit: %s", message); + exit(EXIT_FAILURE); +} + +static void init_pcap(struct in_addr addr) +{ + struct pcap_if *interfaces; + char error[256]; + + if (pcap_findalldevs(&interfaces, error) == -1) + { + error_exit(error); + } + + while (interfaces != NULL) + { + printf("init_pcap: found interface: %s\n", interfaces->description); + + if (interfaces->addresses != NULL && + interfaces->addresses->addr != NULL && + interfaces->addresses->addr->sa_family == AF_INET) + { + + struct in_addr interface_addr; + interface_addr = + ((struct sockaddr_in *)interfaces->addresses->addr)->sin_addr; + printf("init_pcap: with address: %s\n", inet_ntoa(interface_addr)); + + if (interface_addr.s_addr == addr.s_addr) + { + break; + } + } + interfaces = interfaces->next; + } + + if (interfaces == NULL) + { + error_exit("No interface found with IP address\n"); + } + + pcap = pcap_open_live(interfaces->name, NETDEV_BUFSIZE, 0, -1, error); + if (pcap == NULL) + { + error_exit(error); + } +} + +static void set_ethaddr(struct in_addr addr) +{ + PIP_ADAPTER_ADDRESSES adapters; + ULONG size = 0; + + if (GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER, + NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) + { + error_exit("error on access to adapter list size\n"); + } + adapters = alloca(size); + if (GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER, + NULL, adapters, &size) != ERROR_SUCCESS) + { + error_exit("error on access to adapter list\n"); + } + + while (adapters != NULL) + { + + char buffer[256]; + WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1, + buffer, sizeof(buffer), NULL, NULL); + printf("set_ethaddr: found adapter: %s\n", buffer); + + if (adapters->FirstUnicastAddress != NULL && + adapters->FirstUnicastAddress->Address.lpSockaddr != NULL && + adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == + AF_INET) + { + + struct in_addr adapter_addr; + adapter_addr = + ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address. + lpSockaddr)->sin_addr; + printf("set_ethaddr: with address: %s\n", inet_ntoa(adapter_addr)); + + if (adapter_addr.s_addr == addr.s_addr) + { + if (adapters->PhysicalAddressLength != 6) + { + error_exit + ("ip addr specified does not belong to an ethernet card\n"); + } + printf + ("set_ethaddr: ethernetaddr: %02X-%02X-%02X-%02X-%02X-%02X\n", + adapters->PhysicalAddress[0], adapters->PhysicalAddress[1], + adapters->PhysicalAddress[2], adapters->PhysicalAddress[3], + adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]); + + (void)netdriver_setmacaddr(adapters->PhysicalAddress); + break; + } + } + adapters = adapters->Next; + } + + if (adapters == NULL) + { + error_exit("No adaptor found with IP address\n"); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void wpcap_init(void) +{ + struct in_addr addr; + FARPROC dlladdr; + + addr.s_addr = htonl(WCAP_IPADDR); + printf("wpcap_init: IP address: %s\n", inet_ntoa(addr)); + + wpcap = LoadLibrary("wpcap.dll"); + dlladdr = GetProcAddress(wpcap, "pcap_findalldevs"); + pcap_findalldevs = (pcap_findalldevs_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_open_live"); + pcap_open_live = (pcap_open_live_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_next_ex"); + pcap_next_ex = (pcap_next_ex_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_sendpacket"); + pcap_sendpacket = (pcap_sendpacket_t)dlladdr; + + if (pcap_findalldevs == NULL || pcap_open_live == NULL || + pcap_next_ex == NULL || pcap_sendpacket == NULL) + { + error_exit("error on access to winpcap library\n"); + } + + init_pcap(addr); + set_ethaddr(addr); +} + +unsigned int wpcap_read(unsigned char *buf, unsigned int buflen) +{ + struct pcap_pkthdr *packet_header; + unsigned char *packet; + + switch (pcap_next_ex(pcap, &packet_header, &packet)) + { + case -1: + error_exit("error on read\n"); + case 0: + return 0; + } + + if (packet_header->caplen > buflen) + { + return 0; + } + + memcpy(buf, packet, packet_header->caplen); + return packet_header->caplen; +} + +void wpcap_send(unsigned char *buf, unsigned int buflen) +{ + if (pcap_sendpacket(pcap, buf, buflen) == -1) + { + error_exit("error on send\n"); + } +} + +#endif /* __CYGWIN__ */ diff --git a/arch/sim/src/up_x11eventloop.c b/arch/sim/src/up_x11eventloop.c new file mode 100644 index 0000000000000000000000000000000000000000..35199ff2ef4360deb9da98bebd5906d6b8137910 --- /dev/null +++ b/arch/sim/src/up_x11eventloop.c @@ -0,0 +1,141 @@ +/**************************************************************************** + * arch/sim/src/up_x11eventloop.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern int up_buttonevent(int x, int y, int buttons); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Defined in up_x11framebuffer.c */ + +extern Display *g_display; + +volatile int g_eventloop; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_buttonmap + ****************************************************************************/ + +static int up_buttonmap(int state) +{ + int buttons = 0; + + /* Remove any X11 dependencies. Just maps ButtonNMask to bit N. */ + + if ((state & Button1Mask) != 0) + { + buttons |= 1; + } + + if ((state & Button2Mask) != 0) + { + buttons |= 2; + } + + if ((state & Button3Mask) != 0) + { + buttons |= 4; + } + + return buttons; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_x11events + * + * Description: + * Called periodically from the IDLE loop to check for queued X11 events. + * + ****************************************************************************/ + +void up_x11events(void) +{ + XEvent event; + + /* Check if there are any pending, queue X11 events. */ + + if (XPending(g_display) > 0) + { + /* Yes, get the event (this should not block since we know there are + * pending events) + */ + + XNextEvent(g_display, &event); + + /* Then process the event */ + + switch (event.type) + { + case MotionNotify : /* Enabled by ButtonMotionMask */ + { + up_buttonevent(event.xmotion.x, event.xmotion.y, + up_buttonmap(event.xmotion.state)); + } + break; + + case ButtonPress : /* Enabled by ButtonPressMask */ + case ButtonRelease : /* Enabled by ButtonReleaseMask */ + { + up_buttonevent(event.xbutton.x, event.xbutton.y, + up_buttonmap(event.xbutton.state)); + } + break; + + default : + break; + } + } +} diff --git a/arch/sim/src/up_x11framebuffer.c b/arch/sim/src/up_x11framebuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..78487409bcfdc7813a602bbf0de77a24160b51e8 --- /dev/null +++ b/arch/sim/src/up_x11framebuffer.c @@ -0,0 +1,477 @@ +/**************************************************************************** + * arch/sim/src/up_x11framebuffer.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define CONFIG_SIM_X11NOSHM 1 + +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SIM_X11NOSHM +# include +# include +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Also used in up_x11eventloop */ + +Display *g_display; +int g_x11initialized; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int g_screen; +static Window g_window; +static GC g_gc; +#ifndef CONFIG_SIM_X11NOSHM +static XShmSegmentInfo g_xshminfo; +static int g_xerror; +#endif +static XImage *g_image; +static unsigned char *g_framebuffer; +static unsigned short g_fbpixelwidth; +static unsigned short g_fbpixelheight; +static int g_shmcheckpoint = 0; +static int b_useshm; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_x11createframe + ****************************************************************************/ + +static inline int up_x11createframe(void) +{ + XGCValues gcval; + char *argv[2] = { "nuttx", NULL }; + char *winName = "NuttX"; + char *iconName = "NX"; + XTextProperty winprop; + XTextProperty iconprop; + XSizeHints hints; + + g_display = XOpenDisplay(NULL); + if (g_display == NULL) + { + printf("Unable to open display.\n"); + return -1; + } + + g_screen = DefaultScreen(g_display); + g_window = XCreateSimpleWindow(g_display, DefaultRootWindow(g_display), + 0, 0, g_fbpixelwidth, g_fbpixelheight, 2, + BlackPixel(g_display, g_screen), + BlackPixel(g_display, g_screen)); + + XStringListToTextProperty(&winName, 1, &winprop); + XStringListToTextProperty(&iconName, 1, &iconprop); + + hints.flags = PSize | PMinSize | PMaxSize; + hints.width = hints.min_width = hints.max_width = g_fbpixelwidth; + hints.height = hints.min_height = hints.max_height = g_fbpixelheight; + + XSetWMProperties(g_display, g_window, &winprop, &iconprop, argv, 1, + &hints, NULL, NULL); + + XMapWindow(g_display, g_window); + + /* Select window input events */ + +#if defined(CONFIG_SIM_AJOYSTICK) + XSelectInput(g_display, g_window, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask); +#else + XSelectInput(g_display, g_window, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + KeyPressMask); +#endif + + /* Release queued events on the display */ + +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) + (void)XAllowEvents(g_display, AsyncBoth, CurrentTime); + + /* Grab mouse button 1, enabling mouse-related events */ + + (void)XGrabButton(g_display, Button1, AnyModifier, g_window, 1, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, None); +#endif + + gcval.graphics_exposures = 0; + g_gc = XCreateGC(g_display, g_window, GCGraphicsExposures, &gcval); + + return 0; +} + +/**************************************************************************** + * Name: up_x11errorhandler + ****************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static int up_x11errorhandler(Display *display, XErrorEvent *event) +{ + g_xerror = 1; + return 0; +} +#endif + +/**************************************************************************** + * Name: up_x11traperrors + ****************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static void up_x11traperrors(void) +{ + g_xerror = 0; + XSetErrorHandler(up_x11errorhandler); +} +#endif + +/**************************************************************************** + * Name: up_x11untraperrors + ****************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static int up_x11untraperrors(void) +{ + XSync(g_display, 0); + XSetErrorHandler(NULL); + return g_xerror; +} +#endif + +/**************************************************************************** + * Name: up_x11uninitX + ****************************************************************************/ + +static void up_x11uninitX(void) +{ + fprintf(stderr, "Uninitalizing X\n"); + if (g_x11initialized) + { +#ifndef CONFIG_SIM_X11NOSHM + if (g_shmcheckpoint > 4) + { + XShmDetach(g_display, &g_xshminfo); + } + + if (g_shmcheckpoint > 3) + { + shmdt(g_xshminfo.shmaddr); + } + + if (g_shmcheckpoint > 2) + { + shmctl(g_xshminfo.shmid, IPC_RMID, 0); + } +#endif + + if (g_shmcheckpoint > 1) + { + XDestroyImage(g_image); + } + + /* Un-grab the mouse buttons */ + +#if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) + XUngrabButton(g_display, Button1, AnyModifier, g_window); +#endif + g_x11initialized = 0; + } + + XCloseDisplay(g_display); +} + +/**************************************************************************** + * Name: up_x11uninitialize + ****************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static void up_x11uninitialize(void) +{ + fprintf(stderr, "Uninitalizing\n"); + if (g_shmcheckpoint > 1) + { + if (!b_useshm && g_framebuffer) + { + free(g_framebuffer); + g_framebuffer = 0; + } + } + + if (g_shmcheckpoint > 0) + { + g_shmcheckpoint = 1; + } +} +#endif + +/**************************************************************************** + * Name: up_x11mapsharedmem + ****************************************************************************/ + +static inline int up_x11mapsharedmem(int depth, unsigned int fblen) +{ +#ifndef CONFIG_SIM_X11NOSHM + Status result; +#endif + + atexit(up_x11uninitX); + g_shmcheckpoint = 1; + b_useshm = 0; + +#ifndef CONFIG_SIM_X11NOSHM + if (XShmQueryExtension(g_display)) + { + b_useshm = 1; + printf("Using shared memory.\n"); + + up_x11traperrors(); + g_image = XShmCreateImage(g_display, DefaultVisual(g_display, g_screen), + depth, ZPixmap, NULL, &g_xshminfo, + g_fbpixelwidth, g_fbpixelheight); + if (up_x11untraperrors()) + { + up_x11uninitialize(); + goto shmerror; + } + if (!g_image) + { + fprintf(stderr, "Unable to create g_image."); + return -1; + } + g_shmcheckpoint++; + + g_xshminfo.shmid = shmget(IPC_PRIVATE, + g_image->bytes_per_line * g_image->height, + IPC_CREAT | 0777); + if (g_xshminfo.shmid < 0) + { + up_x11uninitialize(); + goto shmerror; + } + g_shmcheckpoint++; + + g_image->data = (char *) shmat(g_xshminfo.shmid, 0, 0); + if (g_image->data == ((char *) -1)) + { + up_x11uninitialize(); + goto shmerror; + } + g_shmcheckpoint++; + + g_xshminfo.shmaddr = g_image->data; + g_xshminfo.readOnly = 0; + + up_x11traperrors(); + result = XShmAttach(g_display, &g_xshminfo); + if (up_x11untraperrors() || !result) + { + up_x11uninitialize(); + goto shmerror; + } + + g_shmcheckpoint++; + + } + else +#endif + if (!b_useshm) + { +#ifndef CONFIG_SIM_X11NOSHM +shmerror: +#endif + b_useshm = 0; + + g_framebuffer = (unsigned char *)malloc(fblen); + + g_image = XCreateImage(g_display, DefaultVisual(g_display, g_screen), depth, + ZPixmap, 0, (char *)g_framebuffer, g_fbpixelwidth, g_fbpixelheight, + 8, 0); + + if (g_image == NULL) + { + fprintf(stderr, "Unable to create g_image\n"); + return -1; + } + + g_shmcheckpoint++; + } + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_x11initialize + * + * Description: + * Make an X11 window look like a frame buffer. + * + ****************************************************************************/ + +int up_x11initialize(unsigned short width, unsigned short height, + void **fbmem, unsigned int *fblen, unsigned char *bpp, + unsigned short *stride) +{ + XWindowAttributes windowAttributes; + int depth; + int ret; + + /* Check if we are already initialized */ + + if (!g_x11initialized) + { + /* Save inputs */ + + g_fbpixelwidth = width; + g_fbpixelheight = height; + + /* Create the X11 window */ + + ret = up_x11createframe(); + if (ret < 0) + { + return ret; + } + + /* Determine the supported pixel bpp of the current window */ + + XGetWindowAttributes(g_display, DefaultRootWindow(g_display), &windowAttributes); + + /* Get the pixel depth. If the depth is 24-bits, use 32 because X expects + * 32-bit aligment anyway. + */ + + depth = windowAttributes.depth; + if (depth == 24) + { + depth = 32; + } + printf("Pixel bpp is %d bits (using %d)\n", windowAttributes.depth, depth); + + *bpp = depth; + *stride = (depth * width / 8); + *fblen = (*stride * height); + + /* Map the window to shared memory */ + + up_x11mapsharedmem(windowAttributes.depth, *fblen); + g_x11initialized = 1; + } + + *fbmem = (void *)g_framebuffer; + return 0; +} + +/**************************************************************************** + * Name: up_x11cmap + ****************************************************************************/ + +int up_x11cmap(unsigned short first, unsigned short len, + unsigned char *red, unsigned char *green, + unsigned char *blue, unsigned char *transp) +{ + Colormap cMap; + int ndx; + + printf("Creating Colormap\n"); + + /* Convert each color to X11 scaling */ + + cMap = DefaultColormap(g_display, g_screen); + for (ndx = first; ndx < first + len; ndx++) + { + XColor color; + + /* Convert to RGB. In the NuttX cmap, each component + * ranges from 0-255; for X11 the range is 0-65536 + */ + + color.red = (short)(*red++) << 8; + color.green = (short)(*green++) << 8; + color.blue = (short)(*blue++) << 8; + color.flags = DoRed | DoGreen | DoBlue; + + /* Then allocate a color for this selection */ + + if (!XAllocColor(g_display, cMap, &color)) + { + fprintf(stderr, "Failed to allocate color%d\n", ndx); + return -1; + } + } + + return 0; +} + +/**************************************************************************** + * Name: up_x11update + ****************************************************************************/ + +void up_x11update(void) +{ +#ifndef CONFIG_SIM_X11NOSHM + if (b_useshm) + { + XShmPutImage(g_display, g_window, g_gc, g_image, 0, 0, 0, 0, + g_fbpixelwidth, g_fbpixelheight, 0); + } + else +#endif + { + XPutImage(g_display, g_window, g_gc, g_image, 0, 0, 0, 0, + g_fbpixelwidth, g_fbpixelheight); + } + + XSync(g_display, 0); +} diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..60f37d7553ffd622e4879d8e8d22c95d4a2d6c11 --- /dev/null +++ b/arch/x86/Kconfig @@ -0,0 +1,52 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_X86 +comment "x86 Configuration Options" + +choice + prompt "x86 chip selection" + default ARCH_I486 + +config ARCH_I486 + bool "i486" + select ARCH_X86_HAVE_32BIT + ---help--- + Intel i486 architecture + +endchoice + +config ARCH_CHIP_QEMU + bool "Qemu x86 emulation" + default n + ---help--- + Intel i486 architecture + +config ARCH_CHIP + string + default "qemu" if ARCH_CHIP_QEMU + +config ARCH_X86_HAVE_32BIT + bool + default n + +config ARCH_X86_M32 + bool "Build 32-bit system with a 64-bit machine" + default n + depends on ARCH_X86_HAVE_32BIT + ---help--- + If you are building for a 32-bit target using a native 64-bit + toolchain, then you need to add compilation options to select the + 32-bit target. Selecting this option will add the -m32 option to + the compiler command line. + +source arch/x86/src/common/Kconfig +if ARCH_I486 +source arch/x86/src/i486/Kconfig +endif # ARCH_I486 +if ARCH_CHIP_QEMU +source arch/x86/src/qemu/Kconfig +endif # ARCH_CHIP_QEMU +endif # ARCH_X86 diff --git a/arch/x86/include/.gitignore b/arch/x86/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8b8a2b105cef1a882b2b510bc9eb3c0f28ee2e8f --- /dev/null +++ b/arch/x86/include/.gitignore @@ -0,0 +1,3 @@ +/chip +/board + diff --git a/arch/x86/include/README.txt b/arch/x86/include/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..7e21e947e018798f706f5e552a095e68e75de188 --- /dev/null +++ b/arch/x86/include/README.txt @@ -0,0 +1,31 @@ +arch/x86/include/README.txt +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This directory holds x86-specific header files. The top-level header files in +arch/x86/include simply include corresponding header files from lower lower- +level chip-specific and architecture-specific directories. + +Architecture-Specific Directories +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Architecture-specific directories hold common header files for specific x86 +architectures. Separating these header file makes it easy to manage such +things as differences in sizeof(long) on 32- and 64-bit x86 architectures. + +i486 + This directory holds definitions appropriate for any instantiation of the + 32-bit i486 architecture. + +Chip-Specific directories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The same x86 architecture may be realized in different chip implementations. +For SoC chips, in particular, on-chip devices and differing interrupt +structures may require special, chip-specific definitions in these chip- +specific directories. + +qemu + This is the implementation of NuttX on the QEMU x86 simulation. + + + diff --git a/arch/x86/include/arch.h b/arch/x86/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..cdd5f2f630a6828a6956734d7410a8c88a93d96f --- /dev/null +++ b/arch/x86/include/arch.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/x86/include/arch.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through arch/arch.h + */ + +#ifndef __ARCH_X86_INCLUDE_ARCH_H +#define __ARCH_X86_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Include chip-specific definitions */ + +# include + +/* Include architecture-specific definitions */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_X86_INCLUDE_ARCH_H */ diff --git a/arch/x86/include/i486/arch.h b/arch/x86/include/i486/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..1994e3fda3ceee6c394ded91216e600bbf06bb04 --- /dev/null +++ b/arch/x86/include/i486/arch.h @@ -0,0 +1,454 @@ +/**************************************************************************** + * arch/x86/include/i486/arch.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_X86_INCLUDE_I486_ARCH_H +#define __ARCH_X86_INCLUDE_I486_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* FLAGS bits */ + +#define X86_FLAGS_CF (1 << 0) /* Bit 0: Carry Flag */ + /* Bit 1: Reserved */ +#define X86_FLAGS_PF (1 << 2) /* Bit 2: Parity Flag */ + /* Bit 3: Reserved */ +#define X86_FLAGS_AF (1 << 4) /* Bit 4: Auxillary carry Flag */ + /* Bit 5: Reserved */ +#define X86_FLAGS_ZF (1 << 6) /* Bit 6: Zero Flag */ +#define X86_FLAGS_SF (1 << 7) /* Bit 7: Sign Flag */ +#define X86_FLAGS_TF (1 << 8) /* Bit 8: Trap Flag */ +#define X86_FLAGS_IF (1 << 9) /* Bit 9: Interrupt Flag */ +#define X86_FLAGS_DF (1 << 10) /* Bit 10: Direction Flag */ +#define X86_FLAGS_OF (1 << 11) /* Bit 11: Overflow Flag */ +#define X86_FLAGS_IOPL_SHIFT (12) /* Bits 12-13: IOPL mask (286+ only)*/ +#define X86_FLAGS_IOPL_MASK (3 << X86_FLAGS_IOPL_SHIFT) +#define X86_FLAGS_NT (1 << 14) /* Bit 14: Nested Task */ + /* Bit 15: Reserved */ + +/* EFLAGS bits (Extend the basic FLAGS bit definitions) */ + +#define X86_EFLAGS_RF (1 << 16) /* Bit 16: Resume Flag (386+ only) */ +#define X86_EFLAGS_VM (1 << 17) /* Bit 17: Virtual Mode (386+ only) */ +#define X86_EFLAGS_AC (1 << 18) /* Bit 18: Alignment Check (486SX+ only) */ +#define X86_EFLAGS_VIF (1 << 19) /* Bit 19: Virtual Interrupt Flag (Pentium+) */ +#define X86_EFLAGS_VIP (1 << 20) /* Bit 20: Virtual Interrupt Pending (Pentium+) */ +#define X86_EFLAGS_ID (1 << 21) /* Bit 21: CPUID detection flag (Pentium+) */ + +/* Programmable Interrupt Controller (PIC) */ + +/* Operational Control Words + * + * The first instruction the Operation Control Word 1 (OCW1) to set which + * IRQ's to mask and which IRQ's not to. + */ + +#define PIC1_OCW1 0x20 +#define PIC2_OCW1 0xa0 + +# define PIC1_OCW1_IRQ0 (1 << 0) /* IRQ0 System Timer */ +# define PIC1_OCW1_IRQ1 (1 << 1) /* IRQ1 Keyboard */ +# define PIC1_OCW1_IRQ2 (1 << 2) /* IRQ2 PIC2 */ +# define PIC1_OCW1_IRQ3 (1 << 3) /* IRQ3 Serial Port */ +# define PIC1_OCW1_IRQ4 (1 << 4) /* IRQ4 Serial Port */ +# define PIC1_OCW1_IRQ5 (1 << 5) /* IRQ5 Reserved/Sound Card */ +# define PIC1_OCW1_IRQ6 (1 << 6) /* IRQ6 Floppy Disk Controller */ +# define PIC1_OCW1_IRQ7 (1 << 7) /* IRQ7 Parallel Port */ +# define PIC1_OCW1_ALL + +# define PIC2_OCW1_IRQ8 (1 << 0) /* IRQ8 Real Time Clock */ +# define PIC2_OCW1_IRQ9 (1 << 1) /* IRQ9 Redirected IRQ2 */ +# define PIC2_OCW1_IRQ10 (1 << 2) /* IRQ10 Reserved */ +# define PIC2_OCW1_IRQ11 (1 << 3) /* IRQ11 Reserved */ +# define PIC2_OCW1_IRQ12 (1 << 4) /* IRQ12 PS/2 Mouse */ +# define PIC2_OCW1_IRQ13 (1 << 5) /* IRQ13 Maths Co-Processor */ +# define PIC2_OCW1_IRQ14 (1 << 6) /* IRQ14 Hard Disk Drive */ +# define PIC2_OCW1_IRQ15 (1 << 7) /* IRQ15 Reserved */ +# define PIC2_OCW1_ALL + +/* Operation Control Word 2 selects how the End of Interrupt (EOI) procedure + * works. The only thing of interest to us in this register is the non- + * specific EOI command, which we must send at the end of our ISR's. + */ + +#define PIC1_OCW2 0x20 +#define PIC2_OCW2 0xa0 + +# define PIC_OCW2_ACT_SHIFT (0) +# define PIC_OCW2_ACT_MASK (7 << PIC_OCW2_ACT_SHIFT) +# define PIC1_OCW2_ACT_IRQ0 (0 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 0 */ +# define PIC1_OCW2_ACT_IRQ1 (1 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 1 */ +# define PIC1_OCW2_ACT_IRQ2 (2 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 2 */ +# define PIC1_OCW2_ACT_IRQ3 (3 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 3 */ +# define PIC1_OCW2_ACT_IRQ4 (4 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 4 */ +# define PIC1_OCW2_ACT_IRQ5 (5 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 5 */ +# define PIC1_OCW2_ACT_IRQ6 (6 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 6 */ +# define PIC1_OCW2_ACT_IRQ7 (7 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 7 */ + +# define PIC2_OCW2_ACT_IRQ8 (0 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 8 */ +# define PIC2_OCW2_ACT_IRQ9 (1 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 9 */ +# define PIC2_OCW2_ACT_IRQ10 (2 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 10 */ +# define PIC2_OCW2_ACT_IRQ11 (3 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 11 */ +# define PIC2_OCW2_ACT_IRQ12 (4 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 12 */ +# define PIC2_OCW2_ACT_IRQ13 (5 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 13 */ +# define PIC2_OCW2_ACT_IRQ14 (6 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 14 */ +# define PIC2_OCW2_ACT_IRQ15 (7 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 15 */ + +# define PIC_OCW2_EOI_SHIFT (5) +# define PIC_OCW2_EOI_MASK (7 << PIC_OCW2_EOI_SHIFT) +# define PIC_OCW2_EOI_AUTO (0 << PIC_OCW2_EOI_SHIFT) /* Rotate in Auto EOI Mode (Clear) */ +# define PIC_OCW2_EOI_NONSPEC (1 << PIC_OCW2_EOI_SHIFT) /* Non Specific EOI */ +# define PIC_OCW2_EOI_SPEC (3 << PIC_OCW2_EOI_SHIFT) /* Specific EOI */ +# define PIC_OCW2_EOI_RAUTO (4 << PIC_OCW2_EOI_SHIFT) /* Rotate in Auto EOI Mode (Set) */ +# define PIC_OCW2_EOI_RNSPEC (5 << PIC_OCW2_EOI_SHIFT) /* Rotate on Non-Specific EOI */ +# define PIC_OCW2_EOI_PRIO (6 << PIC_OCW2_EOI_SHIFT) /* Set Priority Command (Use Bits 2:0) */ +# define PIC_OCW2_EOI_RSPEC (7 << PIC_OCW2_EOI_SHIFT) /* Rotate on Specific EOI (Use Bits 2:0) */ + +/* Operation Control Word 3. Bits 0 and 1 bitsenable us to read the status + * of the Interrupt Request Register (IRR) and the In-Service Register (ISR). + * This is done by setting the appropriate bits correctly and reading the + * register at the Base Address. + * + * For example if we wanted to read the In-Service Register (ISR), then we + * would set both bits 1 and 0 to 1. The next read to the base register, + * (0x20 for PIC1 or 0xa0 for PIC2) will return the status of the In-Service + * Register. + */ + +#define PIC1_OCW3 0x20 +#define PIC2_OCW3 0xa0 + +# define PIC_OCW3_PCMD_SHIFT (0) /* Poll command */ +# define PIC_OCW3_PCMD_MASK (3 << PIC_OCW3_PCMD_SHIFT) +# define PIC_OCW3_PCMD_IRR (2 << PIC_OCW3_PCMD_SHIFT) /* Next Read Returns Interrupt Request Register */ +# define PIC_OCW3_PCMD_ISR (3 << PIC_OCW3_PCMD_SHIFT) /* Next Read Returns In-Service Register */ +# define PIC_OCW3_POLLCMD (1 << 2) /* Poll command */ +# define PIC_OCW3_ONE (1 << 3) /* Must be set to 1 */ +# define PIC_OCW3_SM_SHIFT (5) +# define PIC_OCW3_SM_MASK (3 << PIC_OCW3_SM_SHIFT) +# define PIC_OCW3_RSM (2 << PIC_OCW3_SM_SHIFT) /* Reset Special Mask */ +# define PIC_OCW3_SSM (3 << PIC_OCW3_SM_SHIFT) /* Set Special Mask */ + +/* If the PIC has been reset, it must be initialized with 2 to 4 Initialization + * Command Words (ICW) before it will accept and process Interrupt Requests. The + * following outlines the four possible Initialization Command Words. + */ + +#define PIC1_ICW1 0x20 +#define PIC2_ICW1 0xa0 + +# define PIC_ICW1_ICW4 (1 << 0) /* Will be Sending ICW4 (no ICW4) */ +# define PIC_ICW1_SINGLE (1 << 1) /* Single PIC (vs. Cascaded pics) */ +# define PIC_ICW1_INTERVAL (1 << 2) /* Call Address Interval of 4 (vs 8) */ +# define PIC_ICW1_LEVEL (1 << 3) /* Level Triggered Interrupts (vs Edge) */ +# define PIC_ICW1_ICW1 (1 << 4) /* Must be set to 1 for ICW1 */ +# define PIC_ICW1_VEC_SHIFT (5) /* Interrupt Vector Addresses for MCS-80/85 Mode */ +# define PIC_ICW1_VEC_MASK (7 << PIC_ICW1_VEC_SHIFT) + +/* Initialization Command Word 2 (ICW2) selects which vector information is + * released onto the bus, during the 2nd INTA Pulse. Using the 8086 mode, + * only bits 7:3 need to be used. This will be 00001000 (0x08) for PIC1 and + * 01110000 (0x70) for PIC2. If you wish to relocate the IRQ Vector Table, + * then you can use this register. + */ + +#define PIC1_ICW2 0x21 +#define PIC2_ICW2 0xa1 + +/* There are two different Initialization Command Word 3's. One is used, if + * the PIC is a master, while the other is used for slaves. + */ + +#define PIC1_ICW3 0x21 +#define PIC2_ICW3 0xa1 + +/* Master ICW3 */ + +# define PIC1_ICW3_IRQ0 (1 << 0) /* IRQ0 is connected to a Slave */ +# define PIC1_ICW3_IRQ1 (1 << 1) /* IRQ1 is connected to a Slave */ +# define PIC1_ICW3_IRQ2 (1 << 2) /* IRQ2 is connected to a Slave */ +# define PIC1_ICW3_IRQ3 (1 << 3) /* IRQ3 is connected to a Slave */ +# define PIC1_ICW3_IRQ4 (1 << 4) /* IRQ4 is connected to a Slave */ +# define PIC1_ICW3_IRQ5 (1 << 5) /* IRQ5 is connected to a Slave */ +# define PIC1_ICW3_IRQ6 (1 << 6) /* IRQ6 is connected to a Slave */ +# define PIC1_ICW3_IRQ7 (1 << 7) /* IRQ7 is connected to a Slave */ + +/* And for the slave device, the ICW3 below is used. */ + +# define PIC_ICW3_SID_MASK (0) /* Slave ID */ +# define PIC_ICW3_SID_SHIFT (7 << PIC_ICW3_SID_MASK) +# define PIC_ICW3_SID0 (0 << PIC_ICW3_SID_MASK) /* Slave 0 */ +# define PIC_ICW3_SID1 (1 << PIC_ICW3_SID_MASK) /* Slave 1 */ +# define PIC_ICW3_SID2 (2 << PIC_ICW3_SID_MASK) /* Slave 2 */ +# define PIC_ICW3_SID3 (3 << PIC_ICW3_SID_MASK) /* Slave 3 */ +# define PIC_ICW3_SID4 (4 << PIC_ICW3_SID_MASK) /* Slave 4 */ +# define PIC_ICW3_SID5 (5 << PIC_ICW3_SID_MASK) /* Slave 5 */ +# define PIC_ICW3_SID6 (6 << PIC_ICW3_SID_MASK) /* Slave 6 */ +# define PIC_ICW3_SID7 (7 << PIC_ICW3_SID_MASK) /* Slave 7 */ + +#define PIC1_ICW4 0x21 +#define PIC2_ICW4 0xa1 + +# define PIC_ICW4_FNM (1 << 4) /* Special Fully Nested Mode */ +# define PIC_ICW4_BMODE_SHIFT (2) /* Bufferd mode */ +# define PIC_ICW4_BMODE_MASK (3 << PIC_ICW4_BMODE_SHIFT) +# define PIC_ICW4_BMODE_NON (0 << PIC_ICW4_BMODE_SHIFT) /* Non - Buffered Mode */ +# define PIC_ICW4_BMODE_SLAVE (2 << PIC_ICW4_BMODE_SHIFT) /* Buffered Mode - Slave */ +# define PIC_ICW4_BMODE_MSTR (3 << PIC_ICW4_BMODE_SHIFT) /* Buffered Mode - Master */ +# define PIC_ICW4_AEOI (1 << 1) /* Auto EOI */ +# define PIC_ICW4_808xMODE (1 << 0) /* 8086/8080 Mode (vs MCS-80/85) */ + +/* Interrupt Mask Register */ + +#define PIC1_IMR 0x21 +#define PIC2_IMR 0xa1 + +# define PIC1_IMR_IRQ0 (1 << 0) /* IRQ0 System Timer */ +# define PIC1_IMR_IRQ1 (1 << 1) /* IRQ1 Keyboard */ +# define PIC1_IMR_IRQ2 (1 << 2) /* IRQ2 PIC2 */ +# define PIC1_IMR_IRQ3 (1 << 3) /* IRQ3 Serial Port */ +# define PIC1_IMR_IRQ4 (1 << 4) /* IRQ4 Serial Port */ +# define PIC1_IMR_IRQ5 (1 << 5) /* IRQ5 Reserved/Sound Card */ +# define PIC1_IMR_IRQ6 (1 << 6) /* IRQ6 Floppy Disk Controller */ +# define PIC1_IMR_IRQ7 (1 << 7) /* IRQ7 Parallel Port */ +# define PIC1_IMR_ALL 0xff + +# define PIC2_IMR_IRQ8 (1 << 0) /* IRQ8 Real Time Clock */ +# define PIC2_IMR_IRQ9 (1 << 1) /* IRQ9 Redirected IRQ2 */ +# define PIC2_IMR_IRQ10 (1 << 2) /* IRQ10 Reserved */ +# define PIC2_IMR_IRQ11 (1 << 3) /* IRQ11 Reserved */ +# define PIC2_IMR_IRQ12 (1 << 4) /* IRQ12 PS/2 Mouse */ +# define PIC2_IMR_IRQ13 (1 << 5) /* IRQ13 Maths Co-Processor */ +# define PIC2_IMR_IRQ14 (1 << 6) /* IRQ14 Hard Disk Drive */ +# define PIC2_IMR_IRQ15 (1 << 7) /* IRQ15 Reserved */ +# define PIC2_IMR_ALL 0xff + +/* Programmable Interrupt Timer Definitions */ + +#define PIT_REG_COUNTER0 0x40 +#define PIT_REG_COUNTER1 0x41 +#define PIT_REG_COUNTER2 0x42 +#define PIT_REG_COMMAND 0x43 + +/* PIT command bit defintions */ + +# define PIT_OCW_BINCOUNT_BCD (1 << 0) /* vs binary */ +# define PIT_OCW_MODE_SHIFT (1) +# define PIT_OCW_MODE_MASK (7 << PIT_OCW_MODE_SHIFT) +# define PIT_OCW_MODE_TMCNT (0 << PIT_OCW_MODE_SHIFT) /* Terminal count */ +# define PIT_OCW_MODE_ONESHOT (1 << PIT_OCW_MODE_SHIFT) /* One shot */ +# define PIT_OCW_MODE_RATEGEN (2 << PIT_OCW_MODE_SHIFT) /* Rate gen */ +# define PIT_OCW_MODE_SQUARE (3 << PIT_OCW_MODE_SHIFT) /* Square wave generation */ +# define PIT_OCW_MODE_SWTRIG (4 << PIT_OCW_MODE_SHIFT) /* Software trigger */ +# define PIT_OCW_MODE_HWTRIG (5 << PIT_OCW_MODE_SHIFT) /* Hardware trigger */ +# define PIT_OCW_RL_SHIFT (4) +# define PIT_OCW_RL_MASK (3 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_LATCH (0 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_LSBONLY (1 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_MSBONLY (2 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_DATA (3 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_COUNTER_SHIFT (6) +# define PIT_OCW_COUNTER_MASK (3 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_0 (0 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_1 (1 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_2 (2 << PIT_OCW_COUNTER_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* GDT data structures ****************************************************** + * + * The Global Descriptor Table or GDT is a data structure used by Intel x86- + * family processors starting with the 80286 in order to define the + * characteristics of the various memory areas used during program execution, + * for example the base address, the size and access privileges like + * executability and writability. These memory areas are called segments in + * Intel terminology. + */ + +/* This structure defines one segment */ + +struct gdt_entry_s +{ + uint16_t lowlimit; /* The lower 16 bits of the limit */ + uint16_t lowbase; /* The lower 16 bits of the base */ + uint8_t midbase; /* The next 8 bits of the base */ + uint8_t access; /* Access flags, determine ring segment can be used in */ + uint8_t granularity; + uint8_t hibase; /* The last 8 bits of the base */ +} packed_struct; + +/* This structure refers to the array of GDT entries, and is in the format + * required by the lgdt instruction. + */ + +struct gdt_ptr_s +{ + uint16_t limit; /* The upper 16 bits of all selector limits */ + uint32_t base; /* The address of the first GDT entry */ +} packed_struct; + +/* IDT data structures ****************************************************** + * + * The Interrupt Descriptor Table (IDT) is a data structure used by the x86 + * architecture to implement an interrupt vector table. The IDT is used by the + * processor to determine the correct response to interrupts and exceptions. + */ + +struct idt_entry_s +{ + uint16_t lobase; /* Lower 16-bits of vector address for interrupt */ + uint16_t sel; /* Kernel segment selector */ + uint8_t zero; /* This must always be zero */ + uint8_t flags; /* (See documentation) */ + uint16_t hibase; /* Upper 16-bits of vector address for interrupt */ +} packed_struct; + +/* A struct describing a pointer to an array of interrupt handlers. This is + * in a format suitable for giving to 'lidt'. + */ + +struct idt_ptr_s +{ + uint16_t limit; + uint32_t base; /* The address of the first GDT entry */ +} packed_struct; + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Return stack pointer */ + +static inline uint32_t up_getsp() +{ + uint32_t regval; + + asm volatile( + "\tmovl %%esp, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +/* Get segment registers */ + +static inline uint32_t up_getds() +{ + uint32_t regval; + + asm volatile( + "\tmov %%ds, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +static inline uint32_t up_getcs() +{ + uint32_t regval; + + asm volatile( + "\tmov %%cs, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +static inline uint32_t up_getss() +{ + uint32_t regval; + + asm volatile( + "\tmov %%ss, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void gdt_flush(uint32_t gdt_addr); +void idt_flush(uint32_t idt_addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_X86_INCLUDE_I486_ARCH_H */ + diff --git a/arch/x86/include/i486/io.h b/arch/x86/include/i486/io.h new file mode 100644 index 0000000000000000000000000000000000000000..56471b5ab5451642fd323eb24e1a3e8ecb1ed7ac --- /dev/null +++ b/arch/x86/include/i486/io.h @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/x86/include/i486/io.h + * arch/chip/io.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through arch/io.h + */ + +#ifndef __ARCH_X86_INCLUDE_I486_IO_H +#define __ARCH_X86_INCLUDE_I486_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/* Standard x86 Port I/O */ + +static inline void outb(uint8_t regval, uint16_t port) +{ + asm volatile( + "\toutb %0,%1\n" + : + : "a" (regval), "dN" (port) + ); +} + +static inline uint8_t inb(uint16_t port) +{ + uint8_t regval; + asm volatile( + "\tinb %1,%0\n" + : "=a" (regval) + : "dN" (port) + ); + return regval; +} + +static inline void outw(uint16_t regval, uint16_t port) +{ + asm volatile( + "\toutw %0,%1\n" + : + : "a" (regval), "dN" (port) + ); +} + +static inline uint16_t inw(uint16_t port) +{ + uint16_t regval; + + asm volatile( + "\tinw %1,%0\n" + : "=a" (regval) + : "dN" (port) + ); + return regval; +} + +static inline void outl(uint32_t regval, uint16_t port) +{ + asm volatile( + "\toutl %0,%1\n" + : + : "a" (regval), "dN" (port) + ); +} + +static inline uint32_t inl(uint16_t port) +{ + uint32_t regval; + asm volatile( + "\tinl %1,%0\n" + : "=a" (regval) + : "dN" (port) + ); + return regval; +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_X86_INCLUDE_I486_IO_H */ diff --git a/arch/x86/include/i486/irq.h b/arch/x86/include/i486/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..53b0f7e14df0d8880b3adc5310f3c584c6abe14f --- /dev/null +++ b/arch/x86/include/i486/irq.h @@ -0,0 +1,297 @@ +/**************************************************************************** + * arch/x86/include/i486/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_X86_INCLUDE_I486_IRQ_H +#define __ARCH_X86_INCLUDE_I486_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ISR and IRQ numbers */ + +#define ISR0 0 /* Division by zero exception */ +#define ISR1 1 /* Debug exception */ +#define ISR2 2 /* Non maskable interrupt */ +#define ISR3 3 /* Breakpoint exception */ +#define ISR4 4 /* 'Into detected overflow' */ +#define ISR5 5 /* Out of bounds exception */ +#define ISR6 6 /* Invalid opcode exception */ +#define ISR7 7 /* No coprocessor exception */ +#define ISR8 8 /* Double fault (pushes an error code) */ +#define ISR9 9 /* Coprocessor segment overrun */ +#define ISR10 10 /* Bad TSS (pushes an error code) */ +#define ISR11 11 /* Segment not present (pushes an error code) */ +#define ISR12 12 /* Stack fault (pushes an error code) */ +#define ISR13 13 /* General protection fault (pushes an error code) */ +#define ISR14 14 /* Page fault (pushes an error code) */ +#define ISR15 15 /* Unknown interrupt exception */ +#define ISR16 16 /* Coprocessor fault */ +#define ISR17 17 /* Alignment check exception */ +#define ISR18 18 /* Machine check exception */ +#define ISR19 19 /* Reserved */ +#define ISR20 20 /* Reserved */ +#define ISR21 21 /* Reserved */ +#define ISR22 22 /* Reserved */ +#define ISR23 23 /* Reserved */ +#define ISR24 24 /* Reserved */ +#define ISR25 25 /* Reserved */ +#define ISR26 26 /* Reserved */ +#define ISR27 27 /* Reserved */ +#define ISR28 28 /* Reserved */ +#define ISR29 29 /* Reserved */ +#define ISR30 30 /* Reserved */ +#define ISR31 31 /* Reserved */ + +#define IRQ0 32 /* System timer (cannot be changed) */ +#define IRQ1 33 /* Keyboard controller (cannot be changed) */ +#define IRQ2 34 /* Cascaded signals from IRQs 8–15 */ +#define IRQ3 35 /* Serial port controller for COM2/4 */ +#define IRQ4 36 /* serial port controller for COM1/3 */ +#define IRQ5 37 /* LPT port 2 or sound card */ +#define IRQ6 38 /* Floppy disk controller */ +#define IRQ7 39 /* LPT port 1 or sound card */ +#define IRQ8 40 /* Real time clock (RTC) */ +#define IRQ9 41 /* Open interrupt/available or SCSI host adapter */ +#define IRQ10 42 /* Open interrupt/available or SCSI or NIC */ +#define IRQ11 43 /* Open interrupt/available or SCSI or NIC */ +#define IRQ12 44 /* Mouse on PS/2 connector */ +#define IRQ13 45 /* Math coprocessor */ +#define IRQ14 46 /* Primary ATA channel */ +#define IRQ15 47 /* Secondary ATA channel */ + +#define NR_IRQS 48 + +/* Common register save structgure created by up_saveusercontext() and by + * ISR/IRQ interrupt processing. + */ + +#define REG_DS (0) /* Data segment selector */ +#define REG_EDI (1) /* Saved by pusha */ +#define REG_ESI (2) /* " " "" " " */ +#define REG_EBP (3) /* " " "" " " */ +#define REG_ESP (4) /* " " "" " " (NOTE 1)*/ +#define REG_EBX (5) /* " " "" " " */ +#define REG_EDX (6) /* " " "" " " */ +#define REG_ECX (7) /* " " "" " " */ +#define REG_EAX (8) /* " " "" " " */ +#define REG_IRQNO (9) /* Interrupt number (NOTE 2) */ +#define REG_ERRCODE (10) /* Error code (NOTE 2) */ +#define REG_EIP (11) /* Pushed by process on interrupt processing */ +#define REG_CS (12) /* " " "" " " "" " " " " */ +#define REG_EFLAGS (13) /* " " "" " " "" " " " " */ +#define REG_SP (14) /* " " "" " " "" " " " " */ +#define REG_SS (15) /* " " "" " " "" " " " " */ + +/* NOTE 1: Two versions of the ESP are saved: One from the interrupt + * processing and one from pusha. Only the interrupt ESP (REG_SP) is used. + * NOTE 2: This is not really state data. Rather, this is just a convenient + * way to pass parameters from the interrupt handler to C cod. + */ + +#define XCPTCONTEXT_REGS (16) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Some special landmarks in the stack frame: + * + * TOP_PUSHA - The offset (in 32-bit words) from the beginning of the + * save area on the stack to the value that should be in REG_ESP. + * BOTTOM_PUSHA - The offset (in 32-bit words) from the stack position before + * the interrupt occurred to the value that should be in REG_ESP. + * save area on the stack to the value that should be in REG_ESP. + * OFFSET_PRIO - The offset from the value of REG_ESP to the value of the + * stack pointer before the interrupt occurred (assuming that a priority + * change occurred. + * OFFSET_PRIO - The offset from the value of REG_ESP to the value of the + * stack pointer before the interrupt occurred (assuming that NO priority + * change occurred. + */ + +#define TOP_PUSHA REG_IRQNO +#define BOTTOM_PRIO (XCPTCONTEXT_REGS-REG_IRQNO) +#define BOTTOM_NOPRIO (REG_SP-REG_IRQNO) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This struct defines the way the registers are stored */ + +#ifndef __ASSEMBLY__ +struct xcptcontext +{ + /* The following function pointer is non-zero if there are pending signals + * to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of instruction pointer and EFLAGS used during + * signal processing. + */ + + uint32_t saved_eip; + uint32_t saved_eflags; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Get the current FLAGS register contents */ + +static inline irqstate_t irqflags() +{ + irqstate_t flags; + + asm volatile( + "\tpushf\n" + "\tpop %0\n" + : "=rm" (flags) + : + : "memory"); + return flags; +} + +/* Get a sample of the FLAGS register, determine if interrupts are disabled. + * If the X86_FLAGS_IF is cleared by cli, then interrupts are disabled. If + * if the X86_FLAGS_IF is set by sti, then interrupts are enable. + */ + +static inline bool up_irq_disabled(irqstate_t flags) +{ + return ((flags & X86_FLAGS_IF) == 0); +} + +static inline bool up_irq_enabled(irqstate_t flags) +{ + return ((flags & X86_FLAGS_IF) != 0); +} + +/* Disable interrupts unconditionally */ + +static inline void up_irq_disable(void) +{ + asm volatile("cli": : :"memory"); +} + +/* Enable interrupts unconditionally */ + +static inline void up_irq_enable(void) +{ + asm volatile("sti": : :"memory"); +} + +/* Disable interrupts, but return previous interrupt state */ + +static inline irqstate_t up_irq_save(void) +{ + irqstate_t flags = irqflags(); + up_irq_disable(); + return flags; +} + +/* Conditionally disable interrupts */ + +static inline void up_irq_restore(irqstate_t flags) +{ + if (up_irq_enabled(flags)) + { + up_irq_enable(); + } +} + +static inline void system_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + /* To be provided */ +} + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_X86_INCLUDE_I486_IRQ_H */ + diff --git a/arch/x86/include/i486/limits.h b/arch/x86/include/i486/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..c66a43da2d50f29104b717fd1f7e8bfeb9a9478c --- /dev/null +++ b/arch/x86/include/i486/limits.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/x86/include/i486/limits.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_INCLUDE_I486_LIMITS_H +#define __ARCH_X86_INCLUDE_I486_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_X86_INCLUDE_I486_LIMITS_H */ diff --git a/arch/x86/include/i486/syscall.h b/arch/x86/include/i486/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..2c84b31e050b22e4d6e398b86477c1b2c41f62a7 --- /dev/null +++ b/arch/x86/include/i486/syscall.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/x86/include/i486/syscall.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_X86_INCLUDE_I486_SYSCALL_H +#define __ARCH_X86_INCLUDE_I486_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x80 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* SWI with SYS_ call number and six parameters */ + +uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, + uintptr_t parm6); + +/* SWI with SYS_ call number and no parameters */ + +static inline uintptr_t sys_call0(unsigned int nbr) +{ + return sys_call6(nbr, 0, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and one parameter */ + +static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) +{ + return sys_call6(nbr, parm1, 0, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and two parameters */ + +static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2) +{ + return sys_call6(nbr, parm1, parm2, 0, 0, 0, 0); +} + +/* SWI with SYS_ call number and three parameters */ + +static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3) +{ + return sys_call6(nbr, parm1, parm2, parm3, 0, 0, 0); +} + +/* SWI with SYS_ call number and four parameters */ + +static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, 0, 0); +} + +/* SWI with SYS_ call number and five parameters */ + +static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3, + uintptr_t parm4, uintptr_t parm5) +{ + return sys_call6(nbr, parm1, parm2, parm3, parm4, parm5, 0); +} + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_X86_INCLUDE_I486_SYSCALL_H */ + diff --git a/arch/x86/include/i486/types.h b/arch/x86/include/i486/types.h new file mode 100644 index 0000000000000000000000000000000000000000..5e1f2ced313cbb8ed13e7a7648f95dffbf7efdb4 --- /dev/null +++ b/arch/x86/include/i486/types.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/x86/include/i486/types.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only + * indirectly through arch/types.h (which is, in turn only accessed + * through sys/types.h or stdint.h). + */ + +#ifndef __ARCH_X86_INCLUDE_I486_TYPES_H +#define __ARCH_X86_INCLUDE_I486_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_X86_INCLUDE_I486_TYPES_H */ diff --git a/arch/x86/include/io.h b/arch/x86/include/io.h new file mode 100644 index 0000000000000000000000000000000000000000..2fe29be37aa254346971f027c01d09b8ffde1fc1 --- /dev/null +++ b/arch/x86/include/io.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/x86/include/io.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_INCLUDE_IO_H +#define __ARCH_X86_INCLUDE_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include architecture-specific IO definitions (These are probably common + * across all architectures, but this gives a little bit of flexibility). + */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_X86_INCLUDE_IO_H */ + diff --git a/arch/x86/include/irq.h b/arch/x86/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..7d80f8a333a83d2e82f5e19ecabcc0ad0ef2abe9 --- /dev/null +++ b/arch/x86/include/irq.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/x86/include/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_X86_INCLUDE_IRQ_H +#define __ARCH_X86_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include NuttX-specific IRQ definitions */ + +#include + +/* Include chip-specific IRQ definitions (including IRQ numbers) */ + +#include + +/* Include architecture-specific IRQ definitions (including register save + * structure and up_irq_save()/up_irq_restore() macros). + */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_X86_INCLUDE_IRQ_H */ + diff --git a/arch/x86/include/limits.h b/arch/x86/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..ab3b1dc905f194e5b4f5306097b9e4041e128f8b --- /dev/null +++ b/arch/x86/include/limits.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * arch/x86/include/limits.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_INCLUDE_LIMITS_H +#define __ARCH_X86_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include architecture-specific limits */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_X86_INCLUDE_LIMITS_H */ diff --git a/arch/x86/include/qemu/arch.h b/arch/x86/include/qemu/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..c64baadb0bd6a2b78e9d80f59ffa4ee0fb317d62 --- /dev/null +++ b/arch/x86/include/qemu/arch.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/x86/include/qemu/arch.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_X86_INCLUDE_QEMU_ARCH_H +#define __ARCH_X86_INCLUDE_QEMU_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_X86_INCLUDE_QEMU_ARCH_H */ + diff --git a/arch/x86/include/qemu/irq.h b/arch/x86/include/qemu/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..601aba73b1b81fc00272802e0d4248f486ff82bc --- /dev/null +++ b/arch/x86/include/qemu/irq.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/x86/include/qemu/irq.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_X86_INCLUDE_QEMU_IRQ_H +#define __ARCH_X86_INCLUDE_QEMU_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_X86_INCLUDE_QEMU_IRQ_H */ + diff --git a/arch/x86/include/syscall.h b/arch/x86/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..88c92d02dc1f6e3230cc40926e4d955c0d59dc6a --- /dev/null +++ b/arch/x86/include/syscall.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/x86/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_X86_INCLUDE_SYSCALL_H +#define __ARCH_X86_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include x86 architecture-specific syscall macros */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_X86_INCLUDE_SYSCALL_H */ + diff --git a/arch/x86/include/types.h b/arch/x86/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..5e7dba28edda06b6d213adcad6c756d527f66a92 --- /dev/null +++ b/arch/x86/include/types.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/x86/include/types.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_X86_INCLUDE_TYPES_H +#define __ARCH_X86_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include architecture-specific limits */ + +#ifdef CONFIG_ARCH_I486 +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_X86_INCLUDE_TYPES_H */ diff --git a/arch/x86/src/.gitignore b/arch/x86/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b47dbaebbb9233a0ff00f1662a42662bcf15c7e2 --- /dev/null +++ b/arch/x86/src/.gitignore @@ -0,0 +1,4 @@ +/chip +/board +/.depend +/Make.dep diff --git a/arch/x86/src/Makefile b/arch/x86/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f38bcee148d0449dd26edb1a35df8acc60ce4da0 --- /dev/null +++ b/arch/x86/src/Makefile @@ -0,0 +1,190 @@ +############################################################################ +# arch/x86/src/Makefile +# +# Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +ifeq ($(CONFIG_ARCH_I486),y) +ARCH_SUBDIR = i486 +endif + +CPPFLAGS += $(EXTRADEFINES) +CFLAGS += $(EXTRADEFINES) +CXXFLAGS += $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = $(TOPDIR)\nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)\chip + CFLAGS += -I$(ARCH_SRCDIR)\common + CFLAGS += -I$(ARCH_SRCDIR)\$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)\sched +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + CFLAGS += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + CFLAGS += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = $(TOPDIR)/nuttx$(EXEEXT) + CFLAGS += -I$(ARCH_SRCDIR)/chip + CFLAGS += -I$(ARCH_SRCDIR)/common + CFLAGS += -I$(ARCH_SRCDIR)/$(ARCH_SUBDIR) + CFLAGS += -I$(TOPDIR)/sched +endif +endif + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +ifeq ($(HOSTOS),FreeBSD) + HOST_ARCH = ${shell uname -m 2>/dev/null || echo "Other"} + ifeq ($(HOST_ARCH),amd64) + LDFLAGS += -melf_i386 + LIBGCC = "/usr/lib32/libgcc.a" + endif +endif + +VPATH = chip:common:$(ARCH_SUBDIR) + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + @echo "LD: nuttx$(EXEEXT)" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_OBJ) $(EXTRA_OBJS) \ + --start-group $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) --end-group +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX)$(EXEEXT) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/x86/src/README.txt b/arch/x86/src/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..96a951e3771dad8f58030e03d9e573f05809c6a9 --- /dev/null +++ b/arch/x86/src/README.txt @@ -0,0 +1,31 @@ +arch/x86/src/README.txt +^^^^^^^^^^^^^^^^^^^^^^^ + +This directory holds x86-specific source files. All x86 source reside in +lower-level common, chip-specific, and architecture-specific directories. + +common/ Directory +^^^^^^^^^^^^^^^^^ + +This directory holds source files common to all x86 architectures. + +Architecture-Specific Directories +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Architecture-specific directories hold common source files shared for by +implementations of specific x86 architectures. + +i486 + This directory holds logic appropriate for any instantiation of the 32-bit + i486 architecture. + +Chip-Specific directories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The same x86 architecture may be realized in different chip implementations. +For SoC chips, in particular, on-chip devices and differing interrupt +structures may require special, chip-specific definitions in these chip- +specific directories. + +qemu + This is the implementation of NuttX on the QEMU x86 simulation. diff --git a/arch/x86/src/common/Kconfig b/arch/x86/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..df2d87a14fa309961e8554ff505104943c619d75 --- /dev/null +++ b/arch/x86/src/common/Kconfig @@ -0,0 +1,9 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_X86 +comment "Common Configuration Options" + +endif diff --git a/arch/x86/src/common/up_allocateheap.c b/arch/x86/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..5fb0a9f288fc17e3b8d85ad4303298dfad5619e1 --- /dev/null +++ b/arch/x86/src/common/up_allocateheap.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/x86/src/common/up_allocateheap.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void*)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} diff --git a/arch/x86/src/common/up_arch.h b/arch/x86/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..b3c316e889afb9142fd061091510ef41f7c383f0 --- /dev/null +++ b/arch/x86/src/common/up_arch.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/x86/src/common/up_arch.h + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef ___ARCH_X86_SRC_COMMON_UP_ARCH_H +#define ___ARCH_X86_SRC_COMMON_UP_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +# define getreg8(p) inb(p) +# define putreg8(v,p) outb(v,p) +# define getreg16(p) inw(p) +# define putreg16(v,p) outw(v,p) +# define getreg32(p) inl(p) +# define putreg32(v,p) outl(v,p) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Atomic modification of registers */ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* ___ARCH_X86_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/x86/src/common/up_assert.c b/arch/x86/src/common/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..32eb751c56d3c2b7c5fde27086101f97e1b10dc8 --- /dev/null +++ b/arch/x86/src/common/up_assert.c @@ -0,0 +1,304 @@ +/**************************************************************************** + * arch/x86/src/common/up_assert.c + * + * Copyright (C) 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/* The following is just intended to keep some ugliness out of the mainline + * code. We are going to print the task name if: + * + * CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name + * (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used) + * defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used + */ + +#undef CONFIG_PRINT_TASKNAME +#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP)) +# define CONFIG_PRINT_TASKNAME 1 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t*)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} +#else +# define up_stackdump() +#endif + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +#ifdef CONFIG_ARCH_STACKDUMP +static void up_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + lldbg("sp: %08x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %08x\n", istackbase); + lldbg(" size: %08x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + lldbg("sp: %08x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %08x\n", ustackbase); + lldbg(" size: %08x\n", ustacksize); +#else + lldbg("sp: %08x\n", sp); + lldbg("stack base: %08x\n", ustackbase); + lldbg("stack size: %08x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + up_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + if (g_current_regs != NULL) + { + up_registerdump((uint32_t*)g_current_regs); + } + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif +} +#else +# define up_dumpstate() +#endif + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || (this_task())->pid == 0) + { + (void)up_irq_save(); + for (;;) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#ifdef CONFIG_PRINT_TASKNAME + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_PRINT_TASKNAME + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + up_dumpstate(); + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/x86/src/common/up_blocktask.c b/arch/x86/src/common/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..e5a4845e2444f80581581da527e5392ee4b2a633 --- /dev/null +++ b/arch/x86/src/common/up_blocktask.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/x86/src/common/up_blocktask.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of the ready to run list must + * be stopped. Save its context and move it to the inactive list specified + * by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally the task at the + * head of the list). It most be stopped, its context saved and moved + * into one of the waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new ready to run task + * must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/x86/src/common/up_copystate.c b/arch/x86/src/common/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..a92a1456bfc231061753cb05889e8c5e75bf7f54 --- /dev/null +++ b/arch/x86/src/common/up_copystate.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/x86/src/common/up_copystate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_undefinedinsn + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void up_copystate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the current ARM model, the state is always copied to and from the + * stack and TCB. + */ + + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/x86/src/common/up_elf.c b/arch/x86/src/common/up_elf.c new file mode 100644 index 0000000000000000000000000000000000000000..894f8657864a6f03033bda7bff7d2ddb46307227 --- /dev/null +++ b/arch/x86/src/common/up_elf.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/x86/src/up_elf.c + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define R_386_32 1 +#define R_386_PC32 2 + +#define ELF_BITS 32 +#define ELF_ARCH EM_386 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the ELF file is appropriate + * for the current, configured architecture. Every architecture that uses + * the ELF loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the ELF file. + * + * Returned Value: + * True if the architecture supports this ELF file. + * + ****************************************************************************/ + +bool up_checkarch(FAR const Elf32_Ehdr *hdr) +{ + return hdr->e_machine == EM_386 || hdr->e_machine == EM_486; +} + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the ELF loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + FAR uint32_t *ptr = (FAR uint32_t *)addr; + + /* All relocations depend upon having valid symbol information. */ + + if (sym == NULL) + { + return -EINVAL; + } + + /* Handle the relocation by relocation type */ + + switch (ELF32_R_TYPE(rel->r_info)) + { + case R_386_32: + *ptr += sym->st_value; + break; + + case R_386_PC32: + *ptr += sym->st_value - (uint32_t)ptr; + break; + + default: + return -EINVAL; + } + + return OK; +} + +int up_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym, + uintptr_t addr) +{ + bdbg("Not supported\n"); + return -ENOSYS; +} + diff --git a/arch/x86/src/common/up_exit.c b/arch/x86/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..12779df0248e0cb320e41a946c8331a32226384e --- /dev/null +++ b/arch/x86/src/common/up_exit.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * common/up_exit.c + * + * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sdbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sdbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sdbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease to exist. + * This is a special case of task_delete() where the task to be deleted is + * the currently executing task. It is more complex because a context + * switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + struct tcb_s* tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", this_task()); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + slldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); +} + diff --git a/arch/x86/src/common/up_initialize.c b/arch/x86/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..07697ea078cb4557d8debe047cd5859445b1ad30 --- /dev/null +++ b/arch/x86/src/common/up_initialize.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * arch/x86/src/common/up_initialize.c + * + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Add any extra memory fragments to the memory manager */ + + up_addregion(); + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the DMA subsystem if the weak function up_dmainitialize has been + * brought into the build + */ + +#ifdef CONFIG_ARCH_DMA +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_dmainitialize) +#endif + { + up_dmainitialize(); + } +#endif + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + /* Initialize USB -- device and/or host */ + + up_usbinitialize(); + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/x86/src/common/up_internal.h b/arch/x86/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..db35e68035a713f77231e41e410b3dd90566ddbb --- /dev/null +++ b/arch/x86/src/common/up_internal.h @@ -0,0 +1,266 @@ +/**************************************************************************** + * arch/x86/src/common/up_internal.h + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_SRC_COMMON_UP_INTERNAL_H +#define __ARCH_X86_SRC_COMMON_UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) because + * these should only be controlled during low level board bring-up and not + * part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* DEFINED: Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* DEFINED: No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* DEFINED: Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + +/* Macros to handle saving and restore interrupt state. In the current + * model, the state is copied from the stack to the TCB, but only a + * referenced is passed to get the state from the TCB. + */ + +#define up_restorestate(regs) (g_current_regs = regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +extern volatile uint32_t *g_current_regs; + +/* This is the beginning of heap as provided from up_head.S. This is the first + * address in DRAM after the loaded program+bss+idle stack. The end of the + * heap is CONFIG_RAM_END + */ + +extern uint32_t g_idle_topstack; + +/* Address of the saved user stack pointer */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +extern uint32_t g_intstackbase; +#endif + +/* These 'addresses' of these values are setup by the linker script. They are + * not actual uint32_t storage locations! They are only used meaningfully in the + * following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declareion extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data (it is + * not!). + * - We can recoved the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +extern uint32_t _stext; /* Start of .text */ +extern uint32_t _etext; /* End_1 of .text + .rodata */ +extern const uint32_t _eronly; /* End+1 of read only section (.text + .rodata) */ +extern uint32_t _sdata; /* Start of .data */ +extern uint32_t _edata; /* End+1 of .data */ +extern uint32_t _sbss; /* Start of .bss */ +extern uint32_t _ebss; /* End+1 of .bss */ +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: x86_boardinitialize + * + * Description: + * This function must be provided by the board-specific logic in the + * directory configs//src/. + * + ****************************************************************************/ + +void x86_boardinitialize(void); + +/* Defined in files with the same name as the function */ + +void up_boot(void); +void up_copystate(uint32_t *dest, uint32_t *src); +void up_savestate(uint32_t *regs); +void up_decodeirq(uint32_t *regs); +void up_irqinitialize(void); +#ifdef CONFIG_ARCH_DMA +void weak_function up_dmainitialize(void); +#endif +int up_saveusercontext(uint32_t *saveregs); +void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; +void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); +void up_sigdeliver(void); +void up_lowputc(char ch); +void up_puts(const char *str); +void up_lowputs(const char *str); + +void up_syscall(uint32_t *regs); +void up_registerdump(uint32_t *regs); + +/* Defined in up_allocateheap.c */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#else +# define up_addregion() +#endif + +/* Defined in up_serial.c */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +void up_earlyserialinit(void); +void up_serialinit(void); +#else +# define up_earlyserialinit() +# define up_serialinit() +#endif + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* Defined in up_watchdog.c */ + +void up_wdtinit(void); + +/* Defined in up_timerisr.c */ + +void up_timer_initialize(void); + +/* Defined in board/up_network.c */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +#ifdef CONFIG_USBDEV +void up_usbinitialize(void); +void up_usbuninitialize(void); +#else +# define up_usbinitialize() +# define up_usbuninitialize() +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_X86_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/x86/src/common/up_interruptcontext.c b/arch/x86/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..7c636e197f49aa45d9a68a38d699ad4c15bbb54c --- /dev/null +++ b/arch/x86/src/common/up_interruptcontext.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * arch/x86/src/common/up_interruptcontext.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: + * Return true is we are currently executing in the interrupt handler + * context. + * + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/x86/src/common/up_lowputs.c b/arch/x86/src/common/up_lowputs.c new file mode 100644 index 0000000000000000000000000000000000000000..7a63135261da61ec8c42b02dc7d170228f5e6cd3 --- /dev/null +++ b/arch/x86/src/common/up_lowputs.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/x86/src/common/up_lowputs.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} diff --git a/arch/x86/src/common/up_mdelay.c b/arch/x86/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..a7f2d693ed8fa93d89eae55d99368ca723d43493 --- /dev/null +++ b/arch/x86/src/common/up_mdelay.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/x86/src/common/up_mdelay.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/x86/src/common/up_modifyreg16.c b/arch/x86/src/common/up_modifyreg16.c new file mode 100644 index 0000000000000000000000000000000000000000..e5239d3a9084be0eafce49c00fe483fd4f0a0760 --- /dev/null +++ b/arch/x86/src/common/up_modifyreg16.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/x86/src/common/up_modifyreg16.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16((uint16_t)addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, (uint16_t)addr); + leave_critical_section(flags); +} diff --git a/arch/x86/src/common/up_modifyreg32.c b/arch/x86/src/common/up_modifyreg32.c new file mode 100644 index 0000000000000000000000000000000000000000..79a3fe2f15021777c43758a21af366f791b9f142 --- /dev/null +++ b/arch/x86/src/common/up_modifyreg32.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/x86/src/common/up_modifyreg32.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32((uint16_t)addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, (uint16_t)addr); + leave_critical_section(flags); +} diff --git a/arch/x86/src/common/up_modifyreg8.c b/arch/x86/src/common/up_modifyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..74ad76d4a7ef1ba9d490ee2944caa05f5fd23610 --- /dev/null +++ b/arch/x86/src/common/up_modifyreg8.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/x86/src/common/up_modifyreg8.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8((uint16_t)addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, (uint16_t)addr); + leave_critical_section(flags); +} diff --git a/arch/x86/src/common/up_puts.c b/arch/x86/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..047802b6acb30d1089420c685d809f1d6ac6764d --- /dev/null +++ b/arch/x86/src/common/up_puts.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/x86/src/common/up_puts.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} diff --git a/arch/x86/src/common/up_releasepending.c b/arch/x86/src/common/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..76137604bb4e0dec729dbb6193b03d4744e276c3 --- /dev/null +++ b/arch/x86/src/common/up_releasepending.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/src/arm/up_releasepending.c + * + * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/x86/src/common/up_reprioritizertr.c b/arch/x86/src/common/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..398199261dea8bbf774ac9f168cd87a7dd996160 --- /dev/null +++ b/arch/x86/src/common/up_reprioritizertr.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/arm/src/arm/up_reprioritizertr.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if up_saveusercontext returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } + } +} diff --git a/arch/x86/src/common/up_udelay.c b/arch/x86/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..486974186063b0f6414cf6949b4ff8f06549f07c --- /dev/null +++ b/arch/x86/src/common/up_udelay.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/x86/src/common/up_udelay.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} diff --git a/arch/x86/src/common/up_unblocktask.c b/arch/x86/src/common/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..706d36808c841d76ae1854a5aabd9a13b5782151 --- /dev/null +++ b/arch/x86/src/common/up_unblocktask.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * arch/x86/src/common/up_unblocktask.c + * + * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list but has been prepped to + * execute. Move the TCB to the ready-to-run list, restore its context, + * and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is in one of the + * waiting tasks lists. It must be moved to the ready-to-run list and, + * if it is the highest priority ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * up_saveusercontext returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!up_saveusercontext(rtcb->xcp.regs)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + up_fullcontextrestore(rtcb->xcp.regs); + } + } +} diff --git a/arch/x86/src/i486/Kconfig b/arch/x86/src/i486/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..dda54330f554df283ff1c3e526b668dadf8e3789 --- /dev/null +++ b/arch/x86/src/i486/Kconfig @@ -0,0 +1,9 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_I486 +comment "i486 Configuration Options" + +endif diff --git a/arch/x86/src/i486/i486_utils.S b/arch/x86/src/i486/i486_utils.S new file mode 100644 index 0000000000000000000000000000000000000000..2f793a460ca9410b6d737aabd82f295201a30690 --- /dev/null +++ b/arch/x86/src/i486/i486_utils.S @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/x86/src/i486/i486_utils.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + + .file "i486_utils.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define KSEG 0x10 + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl gdt_flush + .globl idt_flush + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: gdt_flush + ****************************************************************************/ + + .type gdt_flush, @function +gdt_flush: + movl %eax, 4(%esp) /* Get the pointer to the GDT, passed as a parameter */ + lgdt (%eax) /* Load the new GDT pointer */ + + mov $KSEG, %ax /* KSEG is the offset in the GDT to our data segment */ + mov %ax, %ds /* Load all data segment selectors */ + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + jmp $0x08, $.Lgflush /* 0x08 is the offset to our code segment: Far jump! */ +.Lgflush: + ret + .size gdt_flush, . - gdt_flush + +/**************************************************************************** + * Name: idt_flush + ****************************************************************************/ + + .type idt_flush, @function +idt_flush: + movl %eax, 4(%esp) /* Get the pointer to the IDT, passed as a parameter */ + lidt (%eax) /* Load the IDT pointer */ + ret + .size idt_flush, . - idt_flush + .end diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..1d9b1008d09d1a4c67c3142616d1c5766e3f408a --- /dev/null +++ b/arch/x86/src/i486/up_createstack.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/x86/src/i486/up_createstack.c + * + * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* The i486 uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The i486 stack must be aligned at word (4 byte) boundaries. If + * necessary top_of_stack must be rounded down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/x86/src/i486/up_initialstate.c b/arch/x86/src/i486/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..242545330aa39f76661ef839eb88e34c3eae2702 --- /dev/null +++ b/arch/x86/src/i486/up_initialstate.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/x86/src/i486/up_initialstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB has been created. This + * function is called to initialize the processor specific portions of the + * new TCB. + * + * This function must setup the intial architecture registers and/or stack + * so that execution will begin at tcb->start on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer... the value of the stackpointer before + * the "interrupt occurs." We don't know the value of REG_ESP yet.. + * that depends on if a priority change is required or not. + */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_EIP] = (uint32_t)tcb->start; + + /* Set up the segment registers... assume the same segment as the caller. + * That is not a good assumption in the long run. + */ + + xcp->regs[REG_DS] = up_getds(); + xcp->regs[REG_CS] = up_getcs(); + xcp->regs[REG_SS] = up_getss(); + + /* Set supervisor- or user-mode, depending on how NuttX is configured and + * what kind of thread is being started. Disable FIQs in any event + * + * If the kernel build is not selected, then all threads run in + * supervisor-mode. + */ + +#ifdef CONFIG_BUILD_KERNEL +# error "Missing logic for the CONFIG_BUILD_KERNEL build" +#endif + + /* Enable or disable interrupts, based on user configuration. If the IF + * bit is set, maskable interrupts will be enabled. + */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_EFLAGS] = X86_FLAGS_IF; +#endif +} + diff --git a/arch/x86/src/i486/up_irq.c b/arch/x86/src/i486/up_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..b216a24a719170da4e910c8fb539788c4be1e283 --- /dev/null +++ b/arch/x86/src/i486/up_irq.c @@ -0,0 +1,372 @@ +/**************************************************************************** + * arch/x86/src/i486/up_irq.c + * arch/x86/src/chip/up_irq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "qemu.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) noinline_function; +static void up_remappic(void); +static void up_idtentry(unsigned int index, uint32_t base, uint16_t sel, + uint8_t flags); +static inline void up_idtinit(void); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct idt_entry_s idt_entries[256]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name idt_outb + * + * Description: + * A slightly slower version of outb + * + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) +{ + outb(val, addr); +} + +/**************************************************************************** + * Name up_remappic + * + * Description: + * Remap the PIC. The Programmable Interrupt Controller (PIC) is used to + * combine several sources of interrupt onto one or more CPU lines, while + * allowing priority levels to be assigned to its interrupt outputs. When + * the device has multiple interrupt outputs to assert, it will assert them + * in the order of their relative priority. + * + ****************************************************************************/ + +static void up_remappic(void) +{ + /* Mask interrupts from PIC */ + + idt_outb(PIC1_IMR_ALL, PIC1_IMR); + idt_outb(PIC2_IMR_ALL, PIC2_IMR); + + /* If the PIC has been reset, it must be initialized with 2 to 4 Initialization + * Command Words (ICW) before it will accept and process Interrupt Requests. The + * following outlines the four possible Initialization Command Words. + */ + + /* Remap the irq table for primary: + * + * ICW1 - We will be sending ICW4 + * ICW2 - Address + * ICW3 */ + + idt_outb(PIC_ICW1_ICW4|PIC_ICW1_ICW1, PIC1_ICW1); + idt_outb(0x20, PIC1_ICW2); + idt_outb(PIC1_ICW3_IRQ2, PIC1_ICW3); + idt_outb(PIC_ICW4_808xMODE, PIC1_ICW4); + + /* Remap irq for slave */ + + idt_outb(PIC_ICW1_ICW4|PIC_ICW1_ICW1, PIC2_ICW1); + idt_outb(0x28, PIC2_ICW2); + idt_outb(PIC_ICW3_SID2, PIC2_ICW3); + idt_outb(PIC_ICW4_808xMODE, PIC2_ICW4); + + /* Mask interrupts from PIC */ + + idt_outb(PIC1_IMR_ALL, PIC1_IMR); + idt_outb(PIC2_IMR_ALL, PIC2_IMR); +} + +/**************************************************************************** + * Name up_idtentry + * + * Description: + * Initialize one IDT entry. + * + ****************************************************************************/ + +static void up_idtentry(unsigned int index, uint32_t base, uint16_t sel, + uint8_t flags) +{ + struct idt_entry_s *entry = &idt_entries[index]; + + entry->lobase = base & 0xffff; + entry->hibase = (base >> 16) & 0xffff; + + entry->sel = sel; + entry->zero = 0; + + /* We must uncomment the OR below when we get to using user-mode. It sets the + * interrupt gate's privilege level to 3. + */ + + entry->flags = flags /* | 0x60 */; +} + +/**************************************************************************** + * Name up_idtinit + * + * Description: + * Initialize the IDT. The Interrupt Descriptor Table (IDT) is a data + * structure used by the x86 architecture to implement an interrupt vector + * table. The IDT is used by the processor to determine the correct + * response to interrupts and exceptions. + * + ****************************************************************************/ + +static inline void up_idtinit(void) +{ + struct idt_ptr_s idt_ptr; + + idt_ptr.limit = sizeof(struct idt_entry_s) * 256 - 1; + idt_ptr.base = (uint32_t)&idt_entries; + + memset(&idt_entries, 0, sizeof(struct idt_entry_s)*256); + + /* Re-map the PIC */ + + up_remappic(); + + /* Set each ISR/IRQ to the appropriate vector with selector=8 and with + * 32-bit interrupt gate. Interrupt gate (vs. trap gate) will leave + * interrupts enabled when the IRS/IRQ handler is entered. + */ + + up_idtentry(ISR0, (uint32_t)vector_isr0 , 0x08, 0x8e); + up_idtentry(ISR1, (uint32_t)vector_isr1 , 0x08, 0x8e); + up_idtentry(ISR2, (uint32_t)vector_isr2 , 0x08, 0x8e); + up_idtentry(ISR3, (uint32_t)vector_isr3 , 0x08, 0x8e); + up_idtentry(ISR4, (uint32_t)vector_isr4 , 0x08, 0x8e); + up_idtentry(ISR5, (uint32_t)vector_isr5 , 0x08, 0x8e); + up_idtentry(ISR6, (uint32_t)vector_isr6 , 0x08, 0x8e); + up_idtentry(ISR7, (uint32_t)vector_isr7 , 0x08, 0x8e); + up_idtentry(ISR8, (uint32_t)vector_isr8 , 0x08, 0x8e); + up_idtentry(ISR9, (uint32_t)vector_isr9 , 0x08, 0x8e); + up_idtentry(ISR10, (uint32_t)vector_isr10, 0x08, 0x8e); + up_idtentry(ISR11, (uint32_t)vector_isr11, 0x08, 0x8e); + up_idtentry(ISR12, (uint32_t)vector_isr12, 0x08, 0x8e); + up_idtentry(ISR13, (uint32_t)vector_isr13, 0x08, 0x8e); + up_idtentry(ISR14, (uint32_t)vector_isr14, 0x08, 0x8e); + up_idtentry(ISR15, (uint32_t)vector_isr15, 0x08, 0x8e); + up_idtentry(ISR16, (uint32_t)vector_isr16, 0x08, 0x8e); + up_idtentry(ISR17, (uint32_t)vector_isr17, 0x08, 0x8e); + up_idtentry(ISR18, (uint32_t)vector_isr18, 0x08, 0x8e); + up_idtentry(ISR19, (uint32_t)vector_isr19, 0x08, 0x8e); + up_idtentry(ISR20, (uint32_t)vector_isr20, 0x08, 0x8e); + up_idtentry(ISR21, (uint32_t)vector_isr21, 0x08, 0x8e); + up_idtentry(ISR22, (uint32_t)vector_isr22, 0x08, 0x8e); + up_idtentry(ISR23, (uint32_t)vector_isr23, 0x08, 0x8e); + up_idtentry(ISR24, (uint32_t)vector_isr24, 0x08, 0x8e); + up_idtentry(ISR25, (uint32_t)vector_isr25, 0x08, 0x8e); + up_idtentry(ISR26, (uint32_t)vector_isr26, 0x08, 0x8e); + up_idtentry(ISR27, (uint32_t)vector_isr27, 0x08, 0x8e); + up_idtentry(ISR28, (uint32_t)vector_isr28, 0x08, 0x8e); + up_idtentry(ISR29, (uint32_t)vector_isr29, 0x08, 0x8e); + up_idtentry(ISR30, (uint32_t)vector_isr30, 0x08, 0x8e); + up_idtentry(ISR31, (uint32_t)vector_isr31, 0x08, 0x8e); + + up_idtentry(IRQ0, (uint32_t)vector_irq0, 0x08, 0x8e); + up_idtentry(IRQ1, (uint32_t)vector_irq1, 0x08, 0x8e); + up_idtentry(IRQ2, (uint32_t)vector_irq2, 0x08, 0x8e); + up_idtentry(IRQ3, (uint32_t)vector_irq3, 0x08, 0x8e); + up_idtentry(IRQ4, (uint32_t)vector_irq4, 0x08, 0x8e); + up_idtentry(IRQ5, (uint32_t)vector_irq5, 0x08, 0x8e); + up_idtentry(IRQ6, (uint32_t)vector_irq6, 0x08, 0x8e); + up_idtentry(IRQ7, (uint32_t)vector_irq7, 0x08, 0x8e); + up_idtentry(IRQ8, (uint32_t)vector_irq8, 0x08, 0x8e); + up_idtentry(IRQ9, (uint32_t)vector_irq9, 0x08, 0x8e); + up_idtentry(IRQ10, (uint32_t)vector_irq10, 0x08, 0x8e); + up_idtentry(IRQ11, (uint32_t)vector_irq11, 0x08, 0x8e); + up_idtentry(IRQ12, (uint32_t)vector_irq12, 0x08, 0x8e); + up_idtentry(IRQ13, (uint32_t)vector_irq13, 0x08, 0x8e); + up_idtentry(IRQ14, (uint32_t)vector_irq14, 0x08, 0x8e); + up_idtentry(IRQ15, (uint32_t)vector_irq15, 0x08, 0x8e); + + /* Then program the IDT */ + + idt_flush((uint32_t)&idt_ptr); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Initialize the IDT */ + + up_idtinit(); + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(X86_FLAGS_IF); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + unsigned int regaddr; + uint8_t regbit; + + if (irq >= IRQ0) + { + /* Map the IRQ IMR regiser to a PIC and a bit number */ + + if (irq <= IRQ7) + { + regaddr = PIC1_IMR; + regbit = (1 << (irq - IRQ0)); + } + else if (irq <= IRQ15) + { + regaddr = PIC2_IMR; + regbit = (1 << (irq - IRQ8)); + } + else + { + return; + } + + /* Disable (mask) the interrupt */ + + modifyreg8(regaddr, 0, regbit); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + unsigned int regaddr; + uint8_t regbit; + + if (irq >= IRQ0) + { + /* Map the IRQ IMR regiser to a PIC and a bit number */ + + if (irq <= IRQ7) + { + regaddr = PIC1_IMR; + regbit = (1 << (irq - IRQ0)); + } + else if (irq <= IRQ15) + { + regaddr = PIC2_IMR; + regbit = (1 << (irq - IRQ8)); + } + else + { + return; + } + + /* Enable (unmask) the interrupt */ + + modifyreg8(regaddr, regbit, 0); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ +#warning "Missing Logic" + return OK; +} +#endif diff --git a/arch/x86/src/i486/up_regdump.c b/arch/x86/src/i486/up_regdump.c new file mode 100644 index 0000000000000000000000000000000000000000..4cc2d8cb3657bcebef7297b1a6999938f6846706 --- /dev/null +++ b/arch/x86/src/i486/up_regdump.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/x86/src/i486/up_regdump.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +void up_registerdump(uint32_t *regs) +{ + lldbg(" ds:%08x irq:%08x err:%08x\n", + regs[REG_DS], regs[REG_IRQNO], regs[REG_ERRCODE]); + lldbg("edi:%08x esi:%08x ebp:%08x esp:%08x\n", + regs[REG_EDI], regs[REG_ESI], regs[REG_EBP], regs[REG_ESP]); + lldbg("ebx:%08x edx:%08x ecx:%08x eax:%08x\n", + regs[REG_EBX], regs[REG_EDX], regs[REG_ECX], regs[REG_EAX]); + lldbg("eip:%08x cs:%08x flg:%08x sp:%08x ss:%08x\n", + regs[REG_EIP], regs[REG_CS], regs[REG_EFLAGS], regs[REG_SP], + regs[REG_SS]); +} diff --git a/arch/x86/src/i486/up_releasestack.c b/arch/x86/src/i486/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..0f23cd3fb7541639a3d05e7d2125001ad2bc6f2c --- /dev/null +++ b/arch/x86/src/i486/up_releasestack.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * arch/x86/src/common/up_releasestack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/x86/src/i486/up_savestate.c b/arch/x86/src/i486/up_savestate.c new file mode 100644 index 0000000000000000000000000000000000000000..d3c21709ee77790d453fa561f8afc0f7274f4839 --- /dev/null +++ b/arch/x86/src/i486/up_savestate.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/x86/src/i486/up_savestate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: up_savestate + * + * Description: + * This function saves the interrupt level context information in the + * TCB. This would just be a up_copystate but we have to handle one + * special case. In the case where the privilige level changes, the + * value of sp and ss will not be saved on stack by the interrupt handler. + * So, in that case, we will have to fudge those values here. + * + ****************************************************************************/ + +void up_savestate(uint32_t *regs) +{ + uint8_t cpl; + uint8_t rpl; + + /* First, just copy all of the registers */ + + up_copystate(regs, (uint32_t*)g_current_regs); + + /* The RES_SP and REG_SS values will not be saved by the interrupt handling + * logic if there is no change in privilege level. In that case, we will + * have to "fudge" those values here. For now, just overwrite the REG_SP + * and REG_SS values with what we believe to be correct. Obviously, this + * will have to change in the future to support multi-segment operation. + * + * Check for a change in privilege level. + */ + + rpl = regs[REG_CS] & 3; + cpl = up_getcs() & 3; + DEBUGASSERT(rpl >= cpl); + + if (rpl == cpl) + { + /* No priority change, SP and SS are not present in the stack frame. + * + * The value saved in the REG_ESP will be the stackpointer value prior to + * the execution of the PUSHA. It will point at REG_IRQNO. + */ + + regs[REG_SP] = g_current_regs[REG_ESP] + 4*BOTTOM_NOPRIO; + regs[REG_SS] = up_getss(); + } + else + { + DEBUGASSERT(regs[REG_SP] == g_current_regs[REG_ESP] + 4*BOTTOM_PRIO); + } +} diff --git a/arch/x86/src/i486/up_schedulesigaction.c b/arch/x86/src/i486/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..60604e8827fa4fc733a8f7583d681c48b4d1b0e1 --- /dev/null +++ b/arch/x86/src/i486/up_schedulesigaction.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * arch/x86/src/i486/up_schedulesigaction.c + * + * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more signal handling + * actions have been queued for execution. The architecture specific code + * must configure things so that the 'sigdeliver' callback is executed on + * the thread specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked nor should it + * cause any immediate execution of sigdeliver. Typically, a few cases need + * to be considered: + * + * (1) This function may be called from an interrupt handler. During + * interrupt processing, all xcptcontext structures should be valid for + * all tasks. That structure should be modified to invoke sigdeliver() + * either on return from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT the currently + * executing task, then again just modify the saved xcptcontext + * structure for the recipient task so it will invoke sigdeliver when + * that task is later resumed. + * (3) If not in an interrupt handler and the tcb IS the currently + * executing task -- just call the signal handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + sdbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we will + * have to modify the return state as well as the state in the TCB. + * + * Hmmm... there looks like a latent bug here: The following logic + * would fail in the strange case where we are in an interrupt + * handler, the thread is signalling itself, but a context switch to + * another task has occurred so that g_current_regs does not refer to + * the thread of this_task()! + */ + + else + { + /* Save the return lr and cpsr and one scratch register. These + * will be restored by the signal trampoline after the signals + * have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_eip = g_current_regs[REG_EIP]; + tcb->xcp.saved_eflags = g_current_regs[REG_EFLAGS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + g_current_regs[REG_EIP] = (uint32_t)up_sigdeliver; + g_current_regs[REG_EFLAGS] = 0; + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + up_savestate(tcb->xcp.regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running + * from an interrupt handler or (2) we are not in an + * interrupt handler and the running task is signalling + * some non-running task. + */ + + else + { + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_eip = tcb->xcp.regs[REG_EIP]; + tcb->xcp.saved_eflags = tcb->xcp.regs[REG_EFLAGS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + tcb->xcp.regs[REG_EIP] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_EFLAGS] = 0; + } + } + + leave_critical_section(flags); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ diff --git a/arch/x86/src/i486/up_sigdeliver.c b/arch/x86/src/i486/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..e807c3d6161c7f184248e5df7e8af8303bdf1cff --- /dev/null +++ b/arch/x86/src/i486/up_sigdeliver.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/x86/src/i486/up_sigdeliver.c + * + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" +#include "up_arch.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs[REG_EIP] = rtcb->xcp.saved_eip; + regs[REG_EFLAGS] = rtcb->xcp.saved_eflags; + + /* Get a local copy of the sigdeliver function pointer. we do this so that + * we can nullify the sigdeliver function pointer in the TCB and accept + * more signal deliveries while processing the current pending signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state */ + + up_irq_restore(regs[REG_EFLAGS]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + up_fullcontextrestore(regs); +} + +#endif /* !CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/x86/src/i486/up_stackframe.c b/arch/x86/src/i486/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..fab05bff9c079bbe3e17e4e703f22084a487faf5 --- /dev/null +++ b/arch/x86/src/i486/up_stackframe.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/x86/src/i486/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* The initial stack point is aligned at word (4 byte) boundaries. If + * necessary frame_size must be rounded up to the next boundary to retain + * this alignment. + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/x86/src/i486/up_syscall6.S b/arch/x86/src/i486/up_syscall6.S new file mode 100644 index 0000000000000000000000000000000000000000..437d44d077534300a8207446affa49c971813ef6 --- /dev/null +++ b/arch/x86/src/i486/up_syscall6.S @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/x86/src/i486/up_syscall6.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .file "up_syscall6.S" + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: sys_call6 + * + * C Prototype: + * uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + * uintptr_t parm2, uintptr_t parm3, + * uintptr_t parm4, uintptr_t parm5, + * uintptr_t parm6); + * + ****************************************************************************/ + + .global sys_call6 + .type sys_call6, %function + +sys_call6: + pushl %ebp /* Save ebx, esi, edi, and ebp */ + pushl %edi + pushl %esi + pushl %ebx + + movl 44(%esp),%ebp /* Save parm6 in ebp */ + movl 40(%esp),%edi /* Save parm5 in edi */ + movl 36(%esp),%esi /* Save parm4 in esi */ + movl 32(%esp),%edx /* Save parm3 in edx */ + movl 28(%esp),%ecx /* Save parm2 in ecx */ + movl 24(%esp),%ebx /* Save parm1 in ebx */ + movl 20(%esp),%eax /* Save syscall number in eax */ + int $0x80 /* Execute the trap */ + /* Return value is in %eax */ + popl %ebx /* Restore ebx, esi, edi, and ebp */ + popl %esi + popl %edi + popl %ebp + ret /* And return with result in %eax */ + + .size sys_call6,.-sys_call6 + .end diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..b2005fe2de857a4e3c1f78abba2f10945e2ff677 --- /dev/null +++ b/arch/x86/src/i486/up_usestack.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/x86/src/common/up_usestack.c + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The i486 uses a push-down stack: the stack grows toward loweraddresses in + * memory. The stack pointer register, points to the lowest, valid work + * address (the "top" of the stack). Items on the stack are referenced as + * positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary + * top_of_stack must be rounded down to the next boundary + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} diff --git a/arch/x86/src/qemu/Kconfig b/arch/x86/src/qemu/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d4bd2e071ba9492d2e3c8f5e60f7f693444f9ada --- /dev/null +++ b/arch/x86/src/qemu/Kconfig @@ -0,0 +1,28 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_QEMU +comment "QEMU Configuration Options" + +config QEMU_KEYPAD + bool "QEMU Keypad" + default n + ---help--- + Enable support for the QEMU keypad. See qemu_keypad.h for + interfaces. + +config QEMU_VGA + bool "QEMU VGA" + default n + ---help--- + Enable support for the QEMU VGA. See qemu_vga.h for interfaces. + + NOTE: This VGA driver exports a character driver that can be used + to write into the VGA framebuffer. It does *NOT* support a NuttX + framebuffer interfaces and, hence, cannot be used with the NuttX + graphics subsystem. Such a conversion to the standard NuttX + framebuffer interface would, however, not be a big job. + +endif diff --git a/arch/x86/src/qemu/Make.defs b/arch/x86/src/qemu/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..9d2d78f3bc0783d23e58c78f49fdb5a06044ee8f --- /dev/null +++ b/arch/x86/src/qemu/Make.defs @@ -0,0 +1,71 @@ +############################################################################ +# arch/x86/src/qemu/Make.defs +# +# Copyright (C) 2011, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# The start-up, "head", file + +HEAD_ASRC = qemu_head.S + +# Common x86 and i486 files + +CMN_ASRCS = i486_utils.S up_syscall6.S +CMN_CSRCS += up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_irq.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_regdump.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_savestate.c up_sigdeliver.c +CMN_CSRCS += up_schedulesigaction.c up_stackframe.c up_unblocktask.c +CMN_CSRCS += up_usestack.c + +# Required QEMU files + +CHIP_ASRCS = qemu_saveusercontext.S qemu_fullcontextrestore.S qemu_vectors.S +CHIP_CSRCS = qemu_handlers.c qemu_idle.c qemu_lowputc.c qemu_lowsetup.c +CHIP_CSRCS += qemu_serial.c + +# Configuration-dependent QEMU files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += qemu_timerisr.c +endif + +ifeq ($(CONFIG_QEMU_KEYPAD),y) +CHIP_CSRCS += qemu_keypad.c +endif + +ifeq ($(CONFIG_QEMU_VGA),y) +CHIP_CSRCS += qemu_vga.c +endif + diff --git a/arch/x86/src/qemu/chip.h b/arch/x86/src/qemu/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..63c7529f2f6535e42292dc716bcdd8babdf754bc --- /dev/null +++ b/arch/x86/src/qemu/chip.h @@ -0,0 +1,74 @@ +/************************************************************************************ + * arch/x86/src/qemu/chip.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_X86_SRC_QEMU_QEMU_CHIP_H +#define __ARCH_X86_SRC_QEMU_QEMU_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Get customizations for each supported QEMU emulation */ + +#ifdef CONFIG_ARCH_CHIP_QEMU +#else +# error "Unsupported STM32 chip" +#endif + +/* Include only the memory map. Other chip hardware files should then include this + * file for the proper setup + */ + +#include "qemu_memorymap.h" + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_X86_SRC_QEMU_QEMU_CHIP_H */ diff --git a/arch/x86/src/qemu/qemu.h b/arch/x86/src/qemu/qemu.h new file mode 100644 index 0000000000000000000000000000000000000000..6148180aa9d70f4efb08e21db1c30edf61d21c7f --- /dev/null +++ b/arch/x86/src/qemu/qemu.h @@ -0,0 +1,466 @@ +/************************************************************************************ + * arch/x86/src/qemu/qemu.h + * + * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_X86_SRC_QEMU_QEMU_H +#define __ARCH_X86_SRC_QEMU_QEMU_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: i486_clockconfig + * + * Description: + * Called to initialize the LPC17XX. This does whatever setup is needed to put the + * MCU in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void i486_clockconfig(void); + +/************************************************************************************ + * Name: i486_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void i486_lowsetup(void); + +/************************************************************************************ + * Name: i486_gpioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void i486_gpioirqinitialize(void); +#else +# define i486_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: i486_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int i486_configgpio(uint16_t cfgset); + +/************************************************************************************ + * Name: i486_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void i486_gpiowrite(uint16_t pinset, bool value); + +/************************************************************************************ + * Name: i486_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool i486_gpioread(uint16_t pinset); + +/************************************************************************************ + * Name: i486_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void i486_gpioirqenable(int irq); +#else +# define i486_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: i486_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +void i486_gpioirqdisable(int irq); +#else +# define i486_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: i486_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the base address of the provided pinset. + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +int i486_dumpgpio(uint16_t pinset, const char *msg); +#else +# define i486_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Name: i486_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +FAR struct spi_dev_s *i486_spibus_initialize(int port); + +/************************************************************************************ + * Name: i486_spi/ssp0/ssp1select, i486_spi/ssp0/ssp1status, and + * i486_spi/ssp0/ssp1cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including i486_spibus_initialize()) are provided by common LPC17xx logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in i486_boardinitialize() to configure SPI/SSP chip select + * pins. + * 2. Provide i486_spi/ssp0/ssp1select() and i486_spi/ssp0/ssp1status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * i486_spi/ssp0/ssp1cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to i486_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by i486_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +#ifdef CONFIG_I486_SPI +void i486_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t i486_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int i486_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from ssp0/1select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +struct spi_dev_s; +#ifdef CONFIG_I486_SPI +void spi_flush(FAR struct spi_dev_s *dev); +#endif +#if defined(CONFIG_I486_SSP0) || defined(CONFIG_I486_SSP1) +void ssp_flush(FAR struct spi_dev_s *dev); +#endif + +/**************************************************************************** + * Name: i486_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +void i486_dmainitilaize(void); +#endif + +/**************************************************************************** + * Name: i486_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +DMA_HANDLE i486_dmachannel(void); +#endif + +/**************************************************************************** + * Name: i486_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until i486_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +void i486_dmafree(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: i486_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +int i486_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); +#endif + +/**************************************************************************** + * Name: i486_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +int i486_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); +#endif + +/**************************************************************************** + * Name: i486_dmastop + * + * Description: + * Cancel the DMA. After i486_dmastop() is called, the DMA channel is + * reset and i486_dmasetup() must be called before i486_dmastart() can be + * called again + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +void i486_dmastop(DMA_HANDLE handle); +#endif + +/**************************************************************************** + * Name: i486_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +#ifdef CONFIG_DEBUG_DMA +void i486_dmasample(DMA_HANDLE handle, struct i486_dmaregs_s *regs); +#else +# define i486_dmasample(handle,regs) +#endif +#endif + +/**************************************************************************** + * Name: i486_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_I486_GPDMA +#ifdef CONFIG_DEBUG_DMA +void i486_dmadump(DMA_HANDLE handle, const struct i486_dmaregs_s *regs, + const char *msg); +#else +# define i486_dmadump(handle,regs,msg) +#endif +#endif + +/**************************************************************************** + * Name: vector_* + * + * Description: + * These are the various ISR/IRQ vector address exported from + * qemu_vectors.S. These addresses need to have global scope so that they + * can be known to the interrupt initialization logic in qemu_irq.c. + * + ****************************************************************************/ + +void vector_isr0(void); +void vector_isr1(void); +void vector_isr2(void); +void vector_isr3(void); +void vector_isr4(void); +void vector_isr5(void); +void vector_isr6(void); +void vector_isr7(void); +void vector_isr8(void); +void vector_isr9(void); +void vector_isr10(void); +void vector_isr11(void); +void vector_isr12(void); +void vector_isr13(void); +void vector_isr14(void); +void vector_isr15(void); +void vector_isr16(void); +void vector_isr17(void); +void vector_isr18(void); +void vector_isr19(void); +void vector_isr20(void); +void vector_isr21(void); +void vector_isr22(void); +void vector_isr23(void); +void vector_isr24(void); +void vector_isr25(void); +void vector_isr26(void); +void vector_isr27(void); +void vector_isr28(void); +void vector_isr29(void); +void vector_isr30(void); +void vector_isr31(void); +void vector_irq0(void); +void vector_irq1(void); +void vector_irq2(void); +void vector_irq3(void); +void vector_irq4(void); +void vector_irq5(void); +void vector_irq6(void); +void vector_irq7(void); +void vector_irq8(void); +void vector_irq9(void); +void vector_irq10(void); +void vector_irq11(void); +void vector_irq12(void); +void vector_irq13(void); +void vector_irq14(void); +void vector_irq15(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_X86_SRC_QEMU_QEMU_H */ diff --git a/arch/x86/src/qemu/qemu_fullcontextrestore.S b/arch/x86/src/qemu/qemu_fullcontextrestore.S new file mode 100644 index 0000000000000000000000000000000000000000..97a208ad89332f0b094f36f59c600efa7559c6ec --- /dev/null +++ b/arch/x86/src/qemu/qemu_fullcontextrestore.S @@ -0,0 +1,177 @@ +/************************************************************************** + * arch/x86/src/qemu/qemu_fullcontextrestore.S + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include "up_internal.h" + + .file "qemu_fullcontextrestore.S" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * Public Data + **************************************************************************/ + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Trace macros, use like trace 'i' to print char to serial port. */ + + .macro chout, addr, ch +#ifdef CONFIG_DEBUG + mov $\addr, %dx + mov $\ch, %al + out %al, %dx +#endif + .endm + + .macro trace, ch +#ifdef CONFIG_DEBUG + push %eax + push %edx + chout 0x3f8, \ch + pop %edx + pop %eax +#endif + .endm + +/************************************************************************** + * Public Functions + **************************************************************************/ + + .text + +/************************************************************************** + * Name: up_fullcontextrestore + * + * Full C prototype: + * void up_fullcontextrestore(uint32_t *regs) noreturn_function; + * + **************************************************************************/ + + .globl up_fullcontextrestore + .type up_fullcontextrestore, @function +up_fullcontextrestore: + /* Fetch the pointer to the register save array in EAX. */ + + movl 4(%esp), %eax + + /* Disable interrupts now (the correct EFLAGS will be restored before we + * return + */ + + cli + + /* Get the value of the stack pointer as it was when the pusha was + * executed the interrupt handler. + */ + + movl (4*REG_SP)(%eax), %esp + + /* Create an interrupt stack frame for the final iret. + * + * + * IRET STACK + * PRIO CHANGE No PRIO CHANGE + * --------------- ----------------- + * SP Before -> + * SS EFLAGS + * ESP CS + * EFLAGS -> EIP + * CS ... + * SP After -> EIP + * + * So, first check for a priority change. + */ + + movl (4*REG_CS)(%eax), %edx + andl $3, %edx + mov %cs, %ebx + andl $3, %ebx + cmpb %bl, %dl + je .Lnopriochange + + /* The priority will change... put SS and ESP on the stack */ + + mov (4*REG_SS)(%eax), %ebx + push %ebx + movl (4*REG_SP)(%eax), %ebx + push %ebx + +.Lnopriochange: + movl (4*REG_EFLAGS)(%eax), %ebx + push %ebx + mov (4*REG_CS)(%eax), %ebx + push %ebx + movl (4*REG_EIP)(%eax), %ebx + push %ebx + + /* Save the value of EAX on the stack too */ + + movl (4*REG_EAX)(%eax), %ebx + push %ebx + + /* Now restore the remaining registers */ + + movl (4*REG_ESI)(%eax), %esi + movl (4*REG_EDI)(%eax), %edi + movl (4*REG_EBP)(%eax), %ebp + movl (4*REG_EBX)(%eax), %ebx + movl (4*REG_EDX)(%eax), %edx + movl (4*REG_ECX)(%eax), %ecx + + /* Restore the data segment register. I think there is an issue that will + * need to be address here at some time: If the register save area is in + * one data segment and the stack is in another, then the above would not + * work (and, conversely, if they are in the same data segment, the + * following is unnecessary and redundant). + */ + + mov (4*REG_DS)(%eax), %ds + + /* Restore the correct value of EAX and then return */ + + popl %eax + iret + .size up_fullcontextrestore, . - up_fullcontextrestore + .end diff --git a/arch/x86/src/qemu/qemu_handlers.c b/arch/x86/src/qemu/qemu_handlers.c new file mode 100644 index 0000000000000000000000000000000000000000..0f84efb31354ee3a87fc0eb6e405e081fdb8e7d5 --- /dev/null +++ b/arch/x86/src/qemu/qemu_handlers.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_handlers.c + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) noinline_function; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name idt_outb + * + * Description: + * A slightly slower version of outb + * + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) +{ + outb(val, addr); +} + +/**************************************************************************** + * Name: common_handler + * + * Description: + * Common logic for the ISR/IRQ handlers + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS +static uint32_t *common_handler(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); + + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported. + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t*)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t*)g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + return regs; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: isr_handler + * + * Description: + * This gets called from ISR vector handling logic in qemu_vectors.S + * + ****************************************************************************/ + +uint32_t *isr_handler(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + board_autoled_on(LED_INIRQ); + PANIC(); /* Doesn't return */ + return regs; /* To keep the compiler happy */ +#else + uint32_t *ret; + + /* Dispatch the interrupt */ + + board_autoled_on(LED_INIRQ); + ret = common_handler((int)regs[REG_IRQNO], regs); + board_autoled_off(LED_INIRQ); + return ret; +#endif +} + +/**************************************************************************** + * Name: isr_handler + * + * Description: + * This gets called from IRQ vector handling logic in qemu_vectors.S + * + ****************************************************************************/ + +uint32_t *irq_handler(uint32_t *regs) +{ +#ifdef CONFIG_SUPPRESS_INTERRUPTS + board_autoled_on(LED_INIRQ); + PANIC(); /* Doesn't return */ + return regs; /* To keep the compiler happy */ +#else + uint32_t *ret; + int irq; + + board_autoled_on(LED_INIRQ); + + /* Get the IRQ number */ + + irq = (int)regs[REG_IRQNO]; + + /* Send an EOI (end of interrupt) signal to the PICs if this interrupt + * involved the slave. + */ + + if (irq >= IRQ8) + { + /* Send reset signal to slave */ + + idt_outb(PIC_OCW2_EOI_NONSPEC, PIC2_OCW2); + } + + /* Send reset signal to master */ + + idt_outb(PIC_OCW2_EOI_NONSPEC, PIC1_OCW2); + + /* Dispatch the interrupt */ + + ret = common_handler(irq, regs); + board_autoled_off(LED_INIRQ); + return ret; +#endif +} + diff --git a/arch/x86/src/qemu/qemu_head.S b/arch/x86/src/qemu/qemu_head.S new file mode 100644 index 0000000000000000000000000000000000000000..82b8d37a8d704089cbb4e6b1dbce0b730538938f --- /dev/null +++ b/arch/x86/src/qemu/qemu_head.S @@ -0,0 +1,161 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_head.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + + .file "qemu_head.S" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* Memory Map: _sbss is the start of the BSS region (see ld.script) _ebss is + * the end of the BSS regsion (see ld.script). The idle task stack starts at + * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread + * is the thread that the system boots on and, eventually, becomes the idle, + * do nothing task that runs only when there is nothing else to run. The + * heap continues from there until the end of memory. See g_idle_topstack below. + */ + +#define STACKBASE ((_ebss + 0x1f) & 0xffffffe0) +#define IDLE_STACK (STACKBASE+CONFIG_IDLETHREAD_STACKSIZE) +#define HEAP_BASE (STACKBASE+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Trace macros, use like trace 'i' to print char to serial port. */ + + .macro trace, ch +#ifdef CONFIG_DEBUG + mov $0x3f8, %dx + mov $\ch, %al + out %al, %dx +#endif + .endm + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .global __start /* Making entry point visible to linker */ + .global os_start /* os_start is defined elsewhere */ + .global up_lowsetup /* up_lowsetup is defined elsewhere */ + .global g_idle_topstack /* The start of the heap */ + +/**************************************************************************** + * .text + ****************************************************************************/ +/**************************************************************************** + * Multiboot Header + ****************************************************************************/ + + /* Setting up the Multiboot header - see GRUB docs for details */ + + .set ALIGN, 1<<0 /* Align loaded modules on page boundaries */ + .set MEMINFO, 1<<1 /* Provide memory map */ + .set FLAGS, ALIGN | MEMINFO /* This is the Multiboot 'flag' field */ + .set MAGIC, 0x1badb002 /* 'magic number' lets bootloader find the header */ + .set CHECKSUM, -(MAGIC + FLAGS) /* Checksum required */ + + .text + .align 4 + .long MAGIC + .long FLAGS + .long CHECKSUM + +/**************************************************************************** + * Name: Start + ****************************************************************************/ + + .type __start, @function +__start: + /* Set up the stack */ + + mov $(idle_stack + CONFIG_IDLETHREAD_STACKSIZE), %esp + + /* Multiboot setup */ + + push %eax /* Multiboot magic number */ + push %ebx /* Multiboot data structure */ + + /* Initialize and start NuttX */ + + call up_lowsetup /* Low-level, pre-OS initialization */ + call os_start /* Start NuttX */ + + /* NuttX will not return */ + + cli +hang: + hlt /* Halt machine should NuttX return */ + jmp hang + .size __start, . - __start + +/**************************************************************************** + * .bss + ****************************************************************************/ + +/* The stack for the IDLE task thread is declared in .bss. NuttX boots and + * initializes on the IDLE thread, then at the completion of OS startup, this + * thread becomes the thread that executes when there is nothing else to + * do in the system (see up_idle()). + */ + + .type idle_stack, @object + .comm idle_stack, CONFIG_IDLETHREAD_STACKSIZE, 32 + .size idle_stack, CONFIG_IDLETHREAD_STACKSIZE + +/**************************************************************************** + * .rodata + ****************************************************************************/ + + .section .rodata, "a" + +/* HEAP BASE: _sbss is the start of the BSS region (see ld.script) _ebss is + * the end of the BSS region (see ld.script). The heap continues from there + * until the end of memory. + */ + + .type g_idle_topstack, @object +g_idle_topstack: + .long _ebss + .size g_idle_topstack, . - g_idle_topstack + .end diff --git a/arch/x86/src/qemu/qemu_idle.c b/arch/x86/src/qemu/qemu_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..b3c97948ba110232c1af2b9e18fdecdf9299ba52 --- /dev/null +++ b/arch/x86/src/qemu/qemu_idle.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_idle.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Sleep until an interrupt occurs to save power */ + +#endif +} + diff --git a/arch/x86/src/qemu/qemu_keypad.c b/arch/x86/src/qemu/qemu_keypad.c new file mode 100644 index 0000000000000000000000000000000000000000..5efd1f5b07eccd98de387e4537553a057a18928f --- /dev/null +++ b/arch/x86/src/qemu/qemu_keypad.c @@ -0,0 +1,322 @@ +/**************************************************************************** + * arch/x86/src/qemu_keypad.c + * + * Copyright (C) 2013 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef enum +{ + /* The keyboard syms have been cleverly chosen to map to ASCII */ + + KEY_UNKNOWN = 0, + KEY_NOKEY = 0, + KEY_FIRST = 0, + KEY_BACKSPACE = 8, + KEY_TAB = 9, + KEY_CLEAR = 12, + KEY_RETURN = 13, + KEY_PAUSE = 19, + KEY_ESCAPE = 27, + + KEY_SPACE = 32, + KEY_EXCLAIM = 33, + KEY_QUOTEDBL = 34, + KEY_HASH = 35, + KEY_DOLLAR = 36, + KEY_AMPERSAND = 38, + KEY_QUOTE = 39, + KEY_LEFTPAREN = 40, + KEY_RIGHTPAREN = 41, + KEY_ASTERISK = 42, + KEY_PLUS = 43, + KEY_COMMA = 44, + KEY_MINUS = 45, + KEY_PERIOD = 46, + KEY_SLASH = 47, + KEY_0 = 48, + KEY_1 = 49, + KEY_2 = 50, + KEY_3 = 51, + KEY_4 = 52, + KEY_5 = 53, + KEY_6 = 54, + KEY_7 = 55, + KEY_8 = 56, + KEY_9 = 57, + + KEY_COLON = 58, + KEY_SEMICOLON = 59, + KEY_LESS = 60, + KEY_EQUALS = 61, + KEY_GREATER = 62, + KEY_QUESTION = 63, + KEY_AT = 64, + + KEY_LEFTBRACKET = 91, + KEY_BACKSLASH = 92, + KEY_RIGHTBRACKET = 93, + KEY_CARET = 94, + KEY_UNDERSCORE = 95, + KEY_BACKQUOTE = 96, + KEY_a = 97, + KEY_b = 98, + KEY_c = 99, + KEY_d = 100, + KEY_e = 101, + KEY_f = 102, + KEY_g = 103, + KEY_h = 104, + KEY_i = 105, + KEY_j = 106, + KEY_k = 107, + KEY_l = 108, + KEY_m = 109, + KEY_n = 110, + KEY_o = 111, + KEY_p = 112, + KEY_q = 113, + KEY_r = 114, + KEY_s = 115, + KEY_t = 116, + KEY_u = 117, + KEY_v = 118, + KEY_w = 119, + KEY_x = 120, + KEY_y = 121, + KEY_z = 122, + KEY_DELETE = 127, + KEY_DEBUG = 138, /* 0x80+0x0a */ + + /* Arrows + Home/End pad */ + + KEY_S100 = 173, + KEY_UP = 173, + KEY_DOWN = 174, + KEY_RIGHT = 175, + KEY_LEFT = 176, + KEY_INSERT = 177, + KEY_HOME = 178, + KEY_END = 179, + KEY_PAGEUP = 180, + KEY_PAGEDOWN = 181, + + /* Function keys */ + + KEY_F1 = 182, + KEY_F2 = 183, + KEY_F3 = 184, + KEY_F4 = 185, + KEY_F5 = 186, + KEY_F6 = 187, + KEY_F7 = 188, + KEY_F8 = 189, + KEY_F9 = 190, + KEY_F10 = 191, + KEY_F11 = 192, + KEY_F12 = 193, + KEY_F13 = 194, + KEY_F14 = 195, + KEY_F15 = 196, + + /* Key state modifier keys */ + + KEY_NUMLOCK = 200, + KEY_CAPSLOCK = 201, + KEY_SCROLLOCK = 202, + KEY_RSHIFT = 203, + KEY_LSHIFT = 204, + KEY_RCTRL = 205, + KEY_LCTRL = 206, + KEY_RALT = 207, + KEY_LALT = 208, + KEY_RMETA = 209, + KEY_LMETA = 210, + KEY_LSUPER = 211, /* Left "Windows" key */ + KEY_RSUPER = 212, /* Right "Windows" key */ + KEY_MODE = 213, /* "Alt Gr" key */ + KEY_COMPOSE = 214, /* Multi-key compose key */ + + /* Miscellaneous function keys */ + + KEY_HELP = 215, + KEY_PRINT = 216, + KEY_SYSREQ = 217, + KEY_BREAK = 218, + KEY_QUIT = 250, + + /* Add any other keys here */ + + KEY_LAST +} MDKKey; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int keypad_open(struct file *filep); +static int keypad_close(struct file *filep); +static ssize_t keypad_read(struct file *filep, FAR char *buf, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const unsigned char g_kdbus[128] = +{ + 0, KEY_QUIT, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ + '9', '0', '-', '=', '\b', /* Backspace */ + '\t', /* Tab */ + 'q', 'w', 'e', 'r', /* 19 */ + 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */ + 0, /* 29 - Control */ + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ + '\'', '`', 0, /* Left shift */ + '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ + 'm', ',', '.', '/', 0, /* Right shift */ + '*', + 0, /* Alt */ + ' ', /* Space bar */ + 0, /* Caps lock */ + KEY_F1, /* 59 - F1 key ... > */ + KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, + KEY_F10, /* < ... F10 */ + 0, /* 69 - Num lock*/ + 0, /* Scroll Lock */ + KEY_HOME, /* Home key */ + KEY_UP, /* Up Arrow */ + KEY_PAGEUP, /* Page Up */ + '-', + KEY_LEFT, /* Left Arrow */ + 0, + KEY_RIGHT, /* Right Arrow */ + '+', + KEY_END, /* 79 - End key*/ + KEY_DOWN, /* Down Arrow */ + KEY_PAGEDOWN, /* Page Down */ + KEY_INSERT, /* Insert Key */ + KEY_DELETE, /* Delete Key */ + 0, 0, 0, + 0, /* F11 Key */ + 0, /* F12 Key */ + 0, /* All other keys are undefined */ +}; + +static const struct file_operations g_keypadops = +{ + keypad_open, /* open */ + keypad_close, /* close */ + keypad_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0, /* ioctl */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int keypad_open(struct file *filep) +{ + return OK; +} + +static int keypad_close(struct file *filep) +{ + return OK; +} + +static ssize_t keypad_read(struct file *filep, FAR char *buf, size_t buflen) +{ + uint_fast8_t keycode = 0; + uint_fast8_t scancode = 0; + uint_fast8_t keyflags; + + if (buf == NULL || buflen < 1) + { + /* Well... nothing to do */ + + return -EINVAL; + } + + keyflags = inb(0x64); + if (keyflags & 0x01) + { + scancode = inb(0x60); + if ((scancode & 0x80) == 0) + { + keycode = g_kdbus[scancode]; + //printf("%02x ",scancode); + buf[0] = keycode; + return 1; + } + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: qemu_keypad + * + * Description: + * Registers the QEMU keypad driver + * + ****************************************************************************/ + +void qemu_keypad(void) +{ + (void)register_driver("/dev/keypad", &g_keypadops, 0444, NULL); +} diff --git a/arch/x86/src/qemu/qemu_keypad.h b/arch/x86/src/qemu/qemu_keypad.h new file mode 100644 index 0000000000000000000000000000000000000000..7a676f2924c764cbe91ed3c4bbedc0403730b93e --- /dev/null +++ b/arch/x86/src/qemu/qemu_keypad.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_keypad.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_SRC_QEMU_QEMU_KEYPAD_H +#define __ARCH_X86_SRC_QEMU_QEMU_KEYPAD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: qemu_keypad + * + * Description: + * Registers the QEMU keypad driver + * + ****************************************************************************/ + +void qemu_keypad(void); + +#endif /* __ARCH_X86_SRC_QEMU_QEMU_KEYPAD_H */ diff --git a/arch/x86/src/qemu/qemu_lowputc.c b/arch/x86/src/qemu/qemu_lowputc.c new file mode 100644 index 0000000000000000000000000000000000000000..5f8ad49a070ee1d8aa0978ae283363ddabe46365 --- /dev/null +++ b/arch/x86/src/qemu/qemu_lowputc.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_lowputc.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* COM1 port addresses */ + +#define COM1_PORT 0x3f8 /* COM1: I/O port 0x3f8, IRQ 4 */ +#define COM2_PORT 0x2f8 /* COM2: I/O port 0x2f8, IRQ 3 */ +#define COM3_PORT 0x3e8 /* COM3: I/O port 0x3e8, IRQ 4 */ +#define COM4_PORT 0x2e8 /* COM4: I/O port 0x2e8, IRQ 3 */ + +/* 16650 register offsets */ + +#define COM_RBR 0 /* DLAB=0, Receiver Buffer (read) */ +#define COM_THR 0 /* DLAB=0, Transmitter Holding Register (write) */ +#define COM_DLL 0 /* DLAB=1, Divisor Latch (least significant byte) */ +#define COM_IER 1 /* DLAB=0, Interrupt Enable */ +#define COM_DLM 1 /* DLAB=1, Divisor Latch(most significant byte) */ +#define COM_IIR 2 /* Interrupt Identification (read) */ +#define COM_FCR 2 /* FIFO Control (write) */ +#define COM_LCR 3 /* Line Control */ +#define COM_MCR 4 /* MODEM Control */ +#define COM_LSR 5 /* Line Status */ +#define COM_MSR 6 /* MODEM Status */ +#define COM_SCR 7 /* Scratch */ + +/* 16650 register bit definitions */ + +#define LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ + /* Wait until the Transmitter Holding Register (THR) is empty. */ + + while ((inb(COM1_PORT+COM_LSR) & LSR_THRE) == 0); + + /* Then output the character to the THR*/ + + outb(ch, COM1_PORT+COM_THR); +} + diff --git a/arch/x86/src/qemu/qemu_lowsetup.c b/arch/x86/src/qemu/qemu_lowsetup.c new file mode 100644 index 0000000000000000000000000000000000000000..439f4fcd5fa9f806f264adff9813afe1c6df8f20 --- /dev/null +++ b/arch/x86/src/qemu/qemu_lowsetup.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_lowsetup.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct gdt_entry_s gdt_entries[5]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_gdtentry + * + * Description: + * Set the value of one GDT entry. + * + ****************************************************************************/ + +static void up_gdtentry(struct gdt_entry_s *entry, uint32_t base, + uint32_t limit, uint8_t access, uint8_t gran) +{ + entry->lowbase = (base & 0xffff); + entry->midbase = (base >> 16) & 0xff; + entry->hibase = (base >> 24) & 0xff; + + entry->lowlimit = (limit & 0xffff); + entry->granularity = (limit >> 16) & 0x0f; + + entry->granularity |= gran & 0xf0; + entry->access = access; +} + +/**************************************************************************** + * Name: up_gdtinit + * + * Description: + * Initialize the GDT. The Global Descriptor Table or GDT is a data + * structure used by Intel x86-family processors starting with the 80286 + * in order to define the characteristics of the various memory areas used + * during program execution, for example the base address, the size and + * access privileges like executability and writability. These memory areas + * are called segments in Intel terminology. + * + ****************************************************************************/ + +static void up_gdtinit(void) +{ + struct gdt_ptr_s gdt_ptr; + + up_gdtentry(&gdt_entries[0], 0, 0, 0, 0); /* Null segment */ + up_gdtentry(&gdt_entries[1], 0, 0xffffffff, 0x9a, 0xcf); /* Code segment */ + up_gdtentry(&gdt_entries[2], 0, 0xffffffff, 0x92, 0xcf); /* Data segment */ + up_gdtentry(&gdt_entries[3], 0, 0xffffffff, 0xfa, 0xcf); /* User mode code segment */ + up_gdtentry(&gdt_entries[4], 0, 0xffffffff, 0xf2, 0xcf); /* User mode data segment */ + + gdt_ptr.limit = (sizeof(struct gdt_entry_s) * 5) - 1; + gdt_ptr.base = (uint32_t)gdt_entries; + gdt_flush((uint32_t )&gdt_ptr); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowsetup + * + * Description: + * Called from qemu_head BEFORE starting the operating system in order + * perform any necessary, early initialization. + * + ****************************************************************************/ + +void up_lowsetup(void) +{ + /* Initialize the Global descriptor table */ + + up_gdtinit(); + + /* Early serial driver initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + + /* Now perform board-specific initializations */ + + x86_boardinitialize(); +} + diff --git a/arch/x86/src/qemu/qemu_memorymap.h b/arch/x86/src/qemu/qemu_memorymap.h new file mode 100644 index 0000000000000000000000000000000000000000..1bb8afe68df9969312e9f5898a21eaee5347b8bd --- /dev/null +++ b/arch/x86/src/qemu/qemu_memorymap.h @@ -0,0 +1,67 @@ +/************************************************************************************ + * arch/x86/src/qemu/qemu_memorymap.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_X86_SRC_QEMU_QEMU_MEMORYMAP_H +#define __ARCH_X86_SRC_QEMU_QEMU_MEMORYMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory Map ***********************************************************************/ + +/* Peripheral Base Addresses ********************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_X86_SRC_QEMU_QEMU_MEMORYMAP_H */ diff --git a/arch/x86/src/qemu/qemu_saveusercontext.S b/arch/x86/src/qemu/qemu_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..5b4b78647bc2b2de901b6fa961578be2b12a6e68 --- /dev/null +++ b/arch/x86/src/qemu/qemu_saveusercontext.S @@ -0,0 +1,178 @@ +/************************************************************************** + * arch/x86/src/qemu/up_saveusercontext.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include "up_internal.h" + + .file "qemu_saveusercontext.S" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Trace macros, use like trace 'i' to print char to serial port. */ + + .macro chout, addr, ch +#ifdef CONFIG_DEBUG + mov $\addr, %dx + mov $\ch, %al + out %al, %dx +#endif + .endm + + .macro trace, ch +#ifdef CONFIG_DEBUG + push %eax + push %edx + chout 0x3f8, \ch + pop %edx + pop %eax +#endif + .endm + +/************************************************************************** + * .text + **************************************************************************/ + + .text + +/************************************************************************** + * Name: up_saveusercontext + * + * Full C prototype: + * int up_saveusercontext(uint32_t *regs); + * + * Description: + * Save the "user" context. It is not necessary to save all of the + * registers because it is acceptable for certain registers to be + * modified upon return from a subroutine call. On a context switch + * back to user mode, it will appear as a return from this function. + * + * According to the Intel ABI, the EAX, EDX, and ECX are to be free for + * use within a procedure or function, and need not be preserved. These + * are the so-called caller-saved registers are EAX, ECX, EDX. + * + * On entry, + * sp points to the return address + * sp+4 points to register save array + * + **************************************************************************/ + + .globl up_saveusercontext + .type up_saveusercontext, @function +up_saveusercontext: + /* Fetch the pointer to the register save array. %eax is a available + * because it must be modified later to provide the return value. + */ + + movl 4(%esp), %eax + + /* %ebx, %esi, %edi, and %ebp must be preserved. We can freely used %eax + * because it will be the return value from this function. + */ + + movl %ebx, (4*REG_EBX)(%eax) + movl %esi, (4*REG_ESI)(%eax) + movl %edi, (4*REG_EDI)(%eax) + + /* Save the segment registers */ + + mov %ss, (4*REG_SS)(%eax) + mov %cs, (4*REG_CS)(%eax) + mov %ds, (4*REG_DS)(%eax) + + /* Save the value of SP as will be at the time of the IRET that will + * appear to be the return from this function. + * + * + * CURRENT STACK IRET STACK + * PRIO CHANGE No PRIO CHANGE + * --------------- --------------- ----------------- + * EIP + * CS ... + * EFLAGS EIP + * -> ESP CS + * ESP->Return address SS EFLAGS + * Argument Argument Argument + * + * NOTE: We don't yet know the value for REG_ESP! That depends upon + * if a priority change occurs or not. + */ + + + leal -4(%esp), %ecx + movl %ecx, (4*REG_SP)(%eax) + + /* Fetch the PC from the stack and save it in the save block */ + + movl 0(%esp), %ecx + movl %ecx, (4*REG_EIP)(%eax) + + /* Save the framepointer */ + + movl %ebp, (4*REG_EBP)(%eax) + + /* Save EAX=1. This will be the "apparent" return value from this + * function when context is switch back to this thread. The non-zero + * return value is the indication that we have been resumed. + */ + + movl $1, (4*REG_EAX)(%eax) + + /* Get and save the interrupt state */ + + pushf + pop %ecx + movl %ecx, (4*REG_EFLAGS)(%eax) + + /* And return 0 -- The zero return value is the indication that that + * this is the original, "true" return from the function. + * + * 'ret' will remove the EIP from the top of the stack. + */ + + xorl %eax, %eax + ret + .size up_saveusercontext, . - up_saveusercontext + .end diff --git a/arch/x86/src/qemu/qemu_serial.c b/arch/x86/src/qemu/qemu_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..8419c67d946111198f96b9df4d0cf2c0ec854df0 --- /dev/null +++ b/arch/x86/src/qemu/qemu_serial.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_serial.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "up_internal.h" + +/* This is a "stub" file to suppport up_putc if no real serial driver is + * configured. Normally, drivers/serial/uart_16550.c provides the serial + * driver for this platform. + */ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_getreg(), uart_putreg() + * + * Description: + * These functions must be provided by the processor-specific code in order + * to correctly access 16550 registers + * + ****************************************************************************/ + +uart_datawidth_t uart_getreg(uart_addrwidth_t base, unsigned int offset) +{ + return inb(base + offset); +} + +void uart_putreg(uart_addrwidth_t base, unsigned int offset, uart_datawidth_t value) +{ + outb(value, base + offset); +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/x86/src/qemu/qemu_timerisr.c b/arch/x86/src/qemu/qemu_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..adf844d24ca010c00ce0f8424b8825fb80ea2d96 --- /dev/null +++ b/arch/x86/src/qemu/qemu_timerisr.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "qemu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Programmable interval timer (PIT) + * + * Fpit = Fin / divisor + * divisor = Fin / divisor + * + * Where: + * + * Fpit = The desired interrupt frequency. + * Fin = PIT input frequency (PIT_CLOCK provided in board.h) + * + * The desired timer interrupt frequency is provided by the definition CLK_TCK + * (see include/time.h). CLK_TCK defines the desired number of system clock + * ticks per second. That value is a user configurable setting that defaults + * to 100 (100 ticks per second = 10 MS interval). + */ + +#define PIT_DIVISOR ((uint32_t)PIT_CLOCK/(uint32_t)CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +static int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + /* uint32_t to avoid compile time overflow errors */ + + uint32_t divisor = PIT_DIVISOR; + DEBUGASSERT(divisor <= 0xffff); + + /* Attach to the timer interrupt handler */ + + (void)irq_attach(IRQ0, (xcpt_t)up_timerisr); + + /* Send the command byte to configure counter 0 */ + + outb(PIT_OCW_MODE_SQUARE|PIT_OCW_RL_DATA|PIT_OCW_COUNTER_0, PIT_REG_COMMAND); + + /* Set the PIT input frequency divisor */ + + outb((uint8_t)(divisor & 0xff), PIT_REG_COUNTER0); + outb((uint8_t)((divisor >> 8) & 0xff), PIT_REG_COUNTER0); + + /* And enable IRQ0 */ + + up_enable_irq(IRQ0); +} diff --git a/arch/x86/src/qemu/qemu_vectors.S b/arch/x86/src/qemu/qemu_vectors.S new file mode 100644 index 0000000000000000000000000000000000000000..dbc27a5f8f124ac1a4e00b86a898999552ba7bc9 --- /dev/null +++ b/arch/x86/src/qemu/qemu_vectors.S @@ -0,0 +1,271 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_head.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + + .file "qemu_vectors.S" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define KSEG 0x10 + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl irq_handler + .globl isr_handler + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Trace macros, use like trace 'i' to print char to serial port. */ + + .macro trace, ch + mov $0x3f8, %dx + mov $\ch, %al + out %al, %dx + .endm + +/* This macro creates a stub for an ISR which does NOT pass it's own + * error code (adds a dummy errcode byte). + */ + + .macro ISR_NOERRCODE, intno + .globl vector_isr\intno +vector_isr\intno: + cli /* Disable interrupts firstly. */ + push $0 /* Push a dummy error code. */ + push $\intno /* Push the interrupt number. */ + jmp isr_common /* Go to the common ISR handler code. */ + .endm + +/* This macro creates a stub for an ISR which passes it's own + * error code. + */ + + .macro ISR_ERRCODE, intno + .globl vector_isr\intno +vector_isr\intno: + cli /* Disable interrupts firstly. */ + push $\intno /* Push the interrupt number. */ + jmp isr_common /* Go to the common ISR handler code. */ + .endm + +/* This macro creates a stub for an IRQ - the first parameter is + * the IRQ number, the second is the ISR number it is remapped to. + */ + + .macro IRQ, irqno, intno + .globl vector_irq\irqno +vector_irq\irqno: + cli /* Disable interrupts firstly. */ + push $0 /* Push a dummy error code. */ + push $\intno /* Push the interrupt number. */ + jmp irq_common /* Go to the common IRQ handler code. */ + .endm + +/**************************************************************************** + * IDT Vectors + ****************************************************************************/ +/* The following will be the vector addresses programmed into the IDT */ + + ISR_NOERRCODE ISR0 + ISR_NOERRCODE ISR1 + ISR_NOERRCODE ISR2 + ISR_NOERRCODE ISR3 + ISR_NOERRCODE ISR4 + ISR_NOERRCODE ISR5 + ISR_NOERRCODE ISR6 + ISR_NOERRCODE ISR7 + ISR_ERRCODE ISR8 + ISR_NOERRCODE ISR9 + ISR_ERRCODE ISR10 + ISR_ERRCODE ISR11 + ISR_ERRCODE ISR12 + ISR_ERRCODE ISR13 + ISR_ERRCODE ISR14 + ISR_NOERRCODE ISR15 + ISR_NOERRCODE ISR16 + ISR_NOERRCODE ISR17 + ISR_NOERRCODE ISR18 + ISR_NOERRCODE ISR19 + ISR_NOERRCODE ISR20 + ISR_NOERRCODE ISR21 + ISR_NOERRCODE ISR22 + ISR_NOERRCODE ISR23 + ISR_NOERRCODE ISR24 + ISR_NOERRCODE ISR25 + ISR_NOERRCODE ISR26 + ISR_NOERRCODE ISR27 + ISR_NOERRCODE ISR28 + ISR_NOERRCODE ISR29 + ISR_NOERRCODE ISR30 + ISR_NOERRCODE ISR31 + IRQ 0, IRQ0 + IRQ 1, IRQ1 + IRQ 2, IRQ2 + IRQ 3, IRQ3 + IRQ 4, IRQ4 + IRQ 5, IRQ5 + IRQ 6, IRQ6 + IRQ 7, IRQ7 + IRQ 8, IRQ8 + IRQ 9, IRQ9 + IRQ 10, IRQ10 + IRQ 11, IRQ11 + IRQ 12, IRQ12 + IRQ 13, IRQ13 + IRQ 14, IRQ14 + IRQ 15, IRQ15 + +/**************************************************************************** + * Name: isr_common + * + * Description: + * This is the common ISR logic. It saves the processor state, sets up for + * kernel mode segments, calls the C-level fault handler, and finally + * restores the stack frame. + * + ****************************************************************************/ + + .type isr_common, @function +isr_common: +/* trace 'S' */ + pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */ + + mov %ds, %ax /* Lower 16-bits of eax = ds. */ + pushl %eax /* Save the data segment descriptor */ + + mov $KSEG, %ax /* Load the kernel data segment descriptor */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + /* The current value of the SP points to the beginning of the state save + * structure. Save that on the stack as the input parameter to isr_handler. + */ + + mov %esp, %eax + push %eax + call isr_handler + jmp .Lreturn + .size isr_common, . - isr_common + +/**************************************************************************** + * Name: irq_common + * + * Description: + * This is the common IRQ logic. It saves the processor state, sets up for + * kernel mode segments, calls the C-level fault handler, and finally + * restores the stack frame. + * + ****************************************************************************/ + + .type irq_common, @function +irq_common: +/* trace 'R' */ + pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */ + + mov %ds, %ax /* Lower 16-bits of eax = ds. */ + push %eax /* Save the data segment descriptor */ + + mov $KSEG, %ax /* Load the kernel data segment descriptor */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + /* The current value of the SP points to the beginning of the state save + * structure. Save that on the stack as the input parameter to irq_handler. + */ + + mov %esp, %eax + push %eax + call irq_handler + + /* The common return point for both isr_handler and irq_handler */ + +.Lreturn: + add $4, %esp + + /* EAX may possibly hold a pointer to a different regiser save area on + * return. Are we switching to a new context? + */ + + cmp %eax, %esp + je .Lnoswitch + + /* A context swith will be performed. EAX holds the address of the new + * register save structure. + * + * Jump to up_fullcontextrestore(). We perform a call here, but that function + * never returns. The address of the new register save block is the argument + * to the up_fullcontextrestore(). + */ + + push %eax + call up_fullcontextrestore + +.Lnoswitch: + pop %ebx /* Reload the original data segment descriptor */ + mov %bx, %ds + mov %bx, %es + mov %bx, %fs + mov %bx, %gs + + popa /* Pops edi,esi,ebp... */ + add $8, %esp /* Cleans up the pushed error code and pushed ISR number */ + iret /* Pops 3-5 things at once: CS, EIP, EFLAGS (and maybe SS and ESP) */ + .size irq_common, . - irq_common + .end diff --git a/arch/x86/src/qemu/qemu_vga.c b/arch/x86/src/qemu/qemu_vga.c new file mode 100644 index 0000000000000000000000000000000000000000..78cec8121cec692b2e9f376e7eda359801f04c53 --- /dev/null +++ b/arch/x86/src/qemu/qemu_vga.c @@ -0,0 +1,517 @@ +/**************************************************************************** + * drivers/lcd/vga.c + * + * Copyright (C) 2011 Li Zhuoyi. All rights reserved. + * Author: Li Zhuoyi + * History: 0.1 2012-11-30 initial version + * + * Derived from drivers/lcd/skeleton.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define R_COM 0x63 /* "common" bits */ + +#define R_W256 0x00 +#define R_W320 0x00 +#define R_W360 0x04 +#define R_W376 0x04 +#define R_W400 0x04 + +#define R_H200 0x00 +#define R_H224 0x80 +#define R_H240 0x80 +#define R_H256 0x80 +#define R_H270 0x80 +#define R_H300 0x80 +#define R_H360 0x00 +#define R_H400 0x00 +#define R_H480 0x80 +#define R_H564 0x80 +#define R_H600 0x80 + +#define SZ(x) (sizeof(x)/sizeof(x[0])) + +#define VGA_XRES 320 +#define VGA_YRES 240 +#define VGA_BPP 8 +#define VGA_FBSIZE (VGA_XRES * VGA_YRES * VGA_BPP / 8) +#define VGA_COLORFMT FB_FMT_RGB8 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int init_graph_vga(int width, int height,int chain4); +static int vga_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, + size_t npixels); +static int vga_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, + size_t npixels); +static int vga_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo); +static int vga_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo); +static int vga_getpower(struct lcd_dev_s *dev); +static int vga_setpower(struct lcd_dev_s *dev, int power); +static int vga_getcontrast(struct lcd_dev_s *dev); +static int vga_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); +static int vga_open(struct file *filep); +static int vga_close(struct file *filep); +static ssize_t vga_read(struct file *filep, FAR char *buf, size_t buflen); +static ssize_t vga_write(struct file *filep, FAR const char *buf, size_t buflen); +static off_t vga_seek(FAR struct file *filp, off_t offset, int whence); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_hor_regs[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x13 }; + +static const uint8_t g_width_256[] = { 0x5f, 0x3f, 0x40, 0x82, 0x4a,0x9a, 0x20 }; +static const uint8_t g_width_320[] = { 0x5f, 0x4f, 0x50, 0x82, 0x54,0x80, 0x28 }; +static const uint8_t g_width_360[] = { 0x6b, 0x59, 0x5a, 0x8e, 0x5e,0x8a, 0x2d }; +static const uint8_t g_width_376[] = { 0x6e, 0x5d, 0x5e, 0x91, 0x62,0x8f, 0x2f }; +static const uint8_t g_width_400[] = { 0x70, 0x63, 0x64, 0x92, 0x65,0x82, 0x32 }; + +static const uint8_t g_ver_regs[] = { 0x6, 0x7, 0x9, 0x10, 0x11,0x12, 0x15, 0x16 }; + +static const uint8_t height_200[] = { 0xbf, 0x1f, 0x41, 0x9c, 0x8e,0x8f, 0x96, 0xb9 }; +static const uint8_t height_224[] = { 0x0b, 0x3e, 0x41, 0xda, 0x9c,0xbf, 0xc7, 0x04 }; +static const uint8_t height_240[] = { 0x0d, 0x3e, 0x41, 0xea, 0xac,0xdf, 0xe7, 0x06 }; +static const uint8_t height_256[] = { 0x23, 0xb2, 0x61, 0x0a, 0xac,0xff, 0x07, 0x1a }; +static const uint8_t height_270[] = { 0x30, 0xf0, 0x61, 0x20, 0xa9,0x1b, 0x1f, 0x2f }; +static const uint8_t height_300[] = { 0x70, 0xf0, 0x61, 0x5b, 0x8c,0x57, 0x58, 0x70 }; +static const uint8_t height_360[] = { 0xbf, 0x1f, 0x40, 0x88, 0x85,0x67, 0x6d, 0xba }; +static const uint8_t height_400[] = { 0xbf, 0x1f, 0x40, 0x9c, 0x8e,0x8f, 0x96, 0xb9 }; +static const uint8_t height_480[] = { 0x0d, 0x3e, 0x40, 0xea, 0xac,0xdf, 0xe7, 0x06 }; +static const uint8_t height_564[] = { 0x62, 0xf0, 0x60, 0x37, 0x89,0x33, 0x3c, 0x5c }; +static const uint8_t height_600[] = { 0x70, 0xf0, 0x60, 0x5b, 0x8c,0x57, 0x58, 0x70 }; + +static const uint8_t g_bg_color = 0x0f; +static const uint8_t g_fg_color = 0x01; + +static uint8_t g_runbuffer[VGA_XRES]; +static uint8_t *g_pscreen = (uint8_t*)(0xa0000); + +static off_t g_curpos; + +/* This is the standard, NuttX LCD driver object */ + +static struct lcd_dev_s g_lcddev = +{ + .getvideoinfo = vga_getvideoinfo, + .getplaneinfo = vga_getplaneinfo, + + .getpower = vga_getpower, + .setpower = vga_setpower, + .getcontrast = vga_getcontrast, + .setcontrast = vga_setcontrast, +}; + +static const struct file_operations g_vgaops = +{ + vga_open, /* open */ + vga_close, /* close */ + vga_read, /* read */ + vga_write, /* write */ + vga_seek, /* seek */ + 0, /* ioctl */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* The chain4 parameter should be 1 for normal 13h-type mode, but + * only allows 320x200 256x200, 256x240 and 256x256 because you + * can only access the first 64kb + * + * If chain4 is 0, then plane mode is used (tweaked modes), and + * you'll need to switch planes to access the whole screen but + * that allows you using any resolution, up to 400x600 + * + * Returns 0=ok, -n=fail + */ + +static int init_graph_vga(int width, int height,int chain4) +{ + const uint8_t *w; + const uint8_t *h; + uint8_t val; + int a; + + switch (width) + { + case 256: + w = g_width_256; + val = R_COM + R_W256; + break; + + case 320: + w = g_width_320; + val = R_COM + R_W320; + break; + + case 360: + w = g_width_360; + val = R_COM + R_W360; + break; + + case 376: + w = g_width_376; + val = R_COM + R_W376; + break; + + case 400: + w = g_width_400; + val = R_COM + R_W400; + break; + + default: + return -1; /* fail */ + } + + switch (height) + { + case 200: + h = height_200; + val |= R_H200; + break; + + case 224: + h = height_224; + val |= R_H224; + break; + + case 240: + h = height_240; + val |= R_H240; + break; + + case 256: + h = height_256; + val |= R_H256; + break; + + case 270: + h = height_270; + val |= R_H270; + break; + + case 300: + h = height_300; + val |= R_H300; + break; + + case 360: + h = height_360; + val |= R_H360; + break; + + case 400: + h = height_400; + val |= R_H400; + break; + + case 480: + h = height_480; + val |= R_H480; + break; + + case 564: + h = height_564; + val |= R_H564; + break; + + case 600: + h = height_600; + val |= R_H600; + break; + + default: + return -2; /* fail */ + } + + /* chain4 not available if mode takes over 64k */ + + /* if (chain4 && (long)width*(long)height>65536L) return -3; */ + + /* here goes the actual modeswitch */ + + outb(val, 0x3c2); + outw(0x0e11, 0x3d4); /* enable regs 0-7 */ + + for (a = 0; a < SZ(g_hor_regs); ++a) + { + outw((uint16_t)((w[a] << 8) + g_hor_regs[a]), 0x3d4); + } + + for (a = 0; a < SZ(g_ver_regs); ++a) + { + outw((uint16_t)((h[a] << 8) + g_ver_regs[a]), 0x3d4); + } + + outw(0x0008, 0x3d4); /* vert.panning = 0 */ + + if (chain4) + { + outw(0x4014, 0x3d4); + outw(0xa317, 0x3d4); + outw(0x0e04, 0x3c4); + } + else + { + outw(0x0014, 0x3d4); + outw(0xe317, 0x3d4); + outw(0x0604, 0x3c4); + } + + outw(0x0101, 0x3c4); + outw(0x0f02, 0x3c4); /* Enable writing to all planes */ + outw(0x4005, 0x3ce); /* 256 color mode */ + outw(0x0106, 0x3ce); /* Extend graph mode & a000-bfff */ + + inb(0x3da); + outb(0x30, 0x3c0); + outb(0x41, 0x3c0); + outb(0x33, 0x3c0); + outb(0x00, 0x3c0); + + for (a = 0; a < 16; a++) /* ega pal */ + { + outb((uint8_t)a, 0x3c0); + outb((uint8_t)a, 0x3c0); + } + + outb( 0x20, 0x3c0); /* enable video */ + + return 0; +} + +static int vga_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, + size_t npixels) +{ + memcpy(&g_pscreen[row*VGA_XRES + col],buffer, npixels); + return OK; +} + +static int vga_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, + size_t npixels) +{ + memcpy(buffer,&g_pscreen[row*VGA_XRES + col],npixels); + return OK; +} + +static int vga_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo) +{ + vinfo->fmt = VGA_COLORFMT; + vinfo->xres = VGA_XRES; /* Horizontal resolution in pixel columns */ + vinfo->yres = VGA_YRES; /* Vertical resolution in pixel rows */ + vinfo->nplanes = 1; /* Number of color planes supported */ + return OK; +} + +static int vga_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo) +{ + pinfo->putrun = vga_putrun; /* Put a run into LCD memory */ + pinfo->getrun = vga_getrun; /* Get a run from LCD memory */ + pinfo->buffer = g_runbuffer; /* Run scratch buffer */ + pinfo->bpp = VGA_BPP; /* Bits-per-pixel */ + return OK; +} + +static int vga_getpower(struct lcd_dev_s *dev) +{ + return 0; +} + +static int vga_setpower(struct lcd_dev_s *dev, int power) +{ + return OK; +} + +static int vga_getcontrast(struct lcd_dev_s *dev) +{ + return -ENOSYS; +} + +static int vga_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) +{ + return -ENOSYS; +} + +static int vga_open(struct file * filep) +{ + return OK; +} + +static int vga_close(struct file * filep) +{ + return OK; +} + +static ssize_t vga_read(struct file *filep, FAR char *buf, size_t buflen) +{ + if (buf == NULL || buflen < 1) + { + return -EINVAL; + } + + /* memcpy(&buf,&g_pscreen[y*VGA_XRES + x],buflen); */ + return buflen; +} + +static ssize_t vga_write(struct file *filep, FAR const char *buf, size_t buflen) +{ + int i; + int j; + + if (buf == NULL || buflen < 1) + { + return -EINVAL; + } + + for (j = 0; j < buflen && g_curpos < VGA_FBSIZE; j++) + { + uint8_t dots = buf[j]; + for (i = 0; i < 8 && g_curpos < VGA_FBSIZE; i++) + { + g_pscreen[g_curpos++] = dots & 0x80 ? g_fg_color : g_bg_color; + dots <<= 1; + } + } + + return buflen; +} + +static off_t vga_seek(FAR struct file *filp, off_t offset, int whence) +{ + ssize_t newpos; + + /* Adjust the cursor position as requested */ + + switch (whence) + { + case SEEK_SET: /* From the start of the file */ + newpos = (ssize_t)offset; + break; + + case SEEK_CUR: /* From the current file offset */ + newpos = g_curpos + offset; + break; + + case SEEK_END: /* From the end of the file */ + newpos = (VGA_FBSIZE - 1) - offset; + break; + + default: + return g_curpos; + } + + /* Make sure that the new cursor position lies within the frame buffer */ + + if (newpos < 0) + { + newpos = 0; + } + else if (newpos > VGA_FBSIZE) + { + newpos = VGA_FBSIZE; + } + + /* Set the new cursor position */ + + g_curpos = (off_t)newpos; + return g_curpos; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: qemu_vga_initialize + * + * Description: + * Initialize the QEMU VGA video hardware. + * + ****************************************************************************/ + +FAR struct lcd_dev_s *qemu_vga_initialize(void) +{ + int ret = init_graph_vga(VGA_XRES, VGA_YRES, 1); + if (ret < 0) + { + gdbg("ERROR: init_graph_vga returned %d\n",ret); + } + + memset(g_pscreen, 0, VGA_XRES * VGA_YRES); + return &g_lcddev; +} + +void qemu_vga(void) +{ + int ret = init_graph_vga(VGA_XRES, VGA_YRES, 1); + if (ret < 0) + { + gdbg("ERROR: init_graph_vga returned %d\n",ret); + } + + memset(g_pscreen, g_bg_color, VGA_XRES * VGA_YRES); + (void)register_driver("/dev/lcd", &g_vgaops, 0666, NULL); +} diff --git a/arch/x86/src/qemu/qemu_vga.h b/arch/x86/src/qemu/qemu_vga.h new file mode 100644 index 0000000000000000000000000000000000000000..a617e9a61e7aa5383c0ff3959c2e33e00e4cd50e --- /dev/null +++ b/arch/x86/src/qemu/qemu_vga.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * arch/x86/src/qemu/qemu_vga.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_X86_SRC_QEMU_QEMU_VGA_H +#define __ARCH_X86_SRC_QEMU_QEMU_VGA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: qemu_vga_initialize + * + * Description: + * Initialize the QEMU VGA video hardware. + * + ****************************************************************************/ + +FAR struct lcd_dev_s *qemu_vga_initialize(void); + +void qemu_vga(void); + +#endif /* __ARCH_X86_SRC_QEMU_QEMU_VGA_H */ diff --git a/arch/z16/Kconfig b/arch/z16/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..0b457113ced96340196631dda6ec6992bf698116 --- /dev/null +++ b/arch/z16/Kconfig @@ -0,0 +1,53 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_Z16 +comment "Z16 Configuration Options" + +choice + prompt "ZNEO chip selection" + default ARCH_CHIP_Z16F2811 + +config ARCH_CHIP_Z16F2810 + bool "Z16F2810" + select ARCH_CHIP_Z16F + select ARCH_HAVE_IRQPRIO + ---help--- + ZiLOG Z16F2810 + +config ARCH_CHIP_Z16F2811 + bool "Z16F2811" + select ARCH_CHIP_Z16F + select ARCH_HAVE_IRQPRIO + ---help--- + ZiLOG Z16F2811 + +config ARCH_CHIP_Z16F3211 + bool "Z16F3211" + select ARCH_CHIP_Z16F + select ARCH_HAVE_IRQPRIO + ---help--- + ZiLOG Z16F321 + +config ARCH_CHIP_Z16F6411 + bool "Z16F6411" + select ARCH_CHIP_Z16F + select ARCH_HAVE_IRQPRIO + ---help--- + ZiLOG Z16F6411 + +endchoice + +config ARCH_CHIP_Z16F + bool + +config ARCH_CHIP + string + default "z16f" if ARCH_CHIP_Z16F + +source arch/z16/src/common/Kconfig +source arch/z16/src/z16f/Kconfig + +endif diff --git a/arch/z16/include/arch.h b/arch/z16/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..cb574663df12b708fb79f5f8ef185c5f3af93711 --- /dev/null +++ b/arch/z16/include/arch.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the nameNuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h + */ + +#ifndef __ARCH_ARCH_H +#define __ARCH_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARCH_H */ + diff --git a/arch/z16/include/irq.h b/arch/z16/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..9aab0cc1331ebd4ec8664fb8e5cfab39e01bd04c --- /dev/null +++ b/arch/z16/include/irq.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/irq.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_IRQ_H +#define __ARCH_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_IRQ_H */ + diff --git a/arch/z16/include/limits.h b/arch/z16/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..6c643fe85cf6c236b292e2cd635c2d0e3c6c13a0 --- /dev/null +++ b/arch/z16/include/limits.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/z16/include/limits.h + * + * Copyright (C) 2008, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z16_INCLUDE_LIMITS_H +#define __ARCH_Z16_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 2147483647LL +#define ULLONG_MAX 4294967295ULL + +/* A pointer is 4 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_Z16_INCLUDE_LIMITS_H */ diff --git a/arch/z16/include/serial.h b/arch/z16/include/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..c1ce4aa1f18f4d534fde74c461bb798c07253970 --- /dev/null +++ b/arch/z16/include/serial.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * arch/serial.h + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_SERIAL_H +#define __ARCH_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_SERIAL_H */ diff --git a/arch/z16/include/syscall.h b/arch/z16/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..b686a7cc215afe84ab8a4f754029c376aa37a834 --- /dev/null +++ b/arch/z16/include/syscall.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * arch/z16/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_Z16_INCLUDE_SYSCALL_H +#define __ARCH_Z16_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z16_INCLUDE_SYSCALL_H */ + diff --git a/arch/z16/include/types.h b/arch/z16/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..cafeeb4c28b9f7b7135aa82bbf89883cb81b21a8 --- /dev/null +++ b/arch/z16/include/types.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/z16/include/types.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through sys/types.h + */ + +#ifndef __ARCH_Z16_INCLUDE_TYPES_H +#define __ARCH_Z16_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by + * up_irq_save() + */ + +typedef unsigned short irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z16_INCLUDE_TYPES_H */ diff --git a/arch/z16/include/z16f/arch.h b/arch/z16/include/z16f/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..cc4819c71818ff7d9fc1da1c9ba28988db5ced74 --- /dev/null +++ b/arch/z16/include/z16f/arch.h @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/z16/include/z16f/arch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h (via arch/arch.h) + */ + +#ifndef __ARCH_Z16_INCLUDE_Z16F_IRQ_H +#define __ARCH_Z16_INCLUDE_Z16F_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_Z16_INCLUDE_Z16F_IRQ_H */ + diff --git a/arch/z16/include/z16f/chip.h b/arch/z16/include/z16f/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..e759953dd2fd70bd200483df080a5d4c8952e02c --- /dev/null +++ b/arch/z16/include/z16f/chip.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * arch/z16f/chip.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z16_INCLUDE_Z16F_CHIP_H +#define __ARCH_Z16_INCLUDE_Z16F_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_Z16_INCLUDE_Z16F_CHIP_H */ diff --git a/arch/z16/include/z16f/irq.h b/arch/z16/include/z16f/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..8dac657a63169d460180bdb7faa45c28a2cd4123 --- /dev/null +++ b/arch/z16/include/z16f/irq.h @@ -0,0 +1,255 @@ +/**************************************************************************** + * arch/z16/include/z16f/irq.h + * + * Copyright (C) 2008, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h (via arch/irq.h) + */ + +#ifndef __ARCH_Z16_INCLUDE_Z16F_IRQ_H +#define __ARCH_Z16_INCLUDE_Z16F_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt Vectors (excluding reset and sysexec which are handled differently) */ + +#define Z16F_IRQ_IRQ0 ( 0) /* First of 8 IRQs controlled by IRQ0 registers */ +#define Z16F_IRQ_ADC ( 0) /* Vector: 0x2C IRQ0.0 ADC */ +#define Z16F_IRQ_SPI ( 1) /* Vector: 0x28 IRQ0.1 SPI */ +#define Z16F_IRQ_I2C ( 2) /* Vector: 0x24 IRQ0.2 I2C */ +#define Z16F_IRQ_UART0TX ( 3) /* Vector: 0x20 IRQ0.3 UART0 TX */ +#define Z16F_IRQ_UART0RX ( 4) /* Vector: 0x1C IRQ0.4 UART0 RX */ +#define Z16F_IRQ_TIMER0 ( 5) /* Vector: 0x18 IRQ0.5 Timer 0 */ +#define Z16F_IRQ_TIMER1 ( 6) /* Vector: 0x14 IRQ0.6 Timer 1 */ +#define Z16F_IRQ_TIMER2 ( 7) /* Vector: 0x10 IRQ0.7 Timer 2 */ + +#define Z16F_IRQ_IRQ1 ( 8) /* First of 8 IRQs controlled by IRQ1 registers */ +#define Z16F_IRQ_P0AD ( 8) /* Vector: 0x4C IRQ1.0 Port A/D0, rising/falling edge */ +#define Z16F_IRQ_P1AD ( 9) /* Vector: 0x48 IRQ1.1 Port A/D1, rising/falling edge */ +#define Z16F_IRQ_P2AD (10) /* Vector: 0x44 IRQ1.2 Port A/D2, rising/falling edge */ +#define Z16F_IRQ_P3AD (11) /* Vector: 0x40 IRQ1.3 Port A/D3, rising/falling edge */ +#define Z16F_IRQ_P4AD (12) /* Vector: 0x3C IRQ1.4 Port A/D4, rising/falling edge */ +#define Z16F_IRQ_P5AD (13) /* Vector: 0x38 IRQ1.5 Port A/D5, rising/falling edge */ +#define Z16F_IRQ_P6AD (14) /* Vector: 0x34 IRQ1.6 Port A/D6, rising/falling edge */ +#define Z16F_IRQ_P7AD (15) /* Vector: 0x30 IRQ1.7 Port A/D7, rising/falling edge */ + +#define Z16F_IRQ_IRQ2 (16) /* First of 8 IRQs controlled by IRQ2 registers */ +#define Z16F_IRQ_C0 (16) /* Vector: IRQ2.0 0x6C Port C0, both edges DMA0 */ +#define Z16F_IRQ_C1 (17) /* Vector: IRQ2.1 0x68 Port C1, both edges DMA1 */ +#define Z16F_IRQ_C2 (18) /* Vector: IRQ2.2 0x64 Port C2, both edges DMA2 */ +#define Z16F_IRQ_C3 (19) /* Vector: IRQ2.3 0x60 Port C3, both edges DMA3 */ +#define Z16F_IRQ_PWMFAULT (20) /* Vector: IRQ2.4 0x5C PWM Fault */ +#define Z16F_IRQ_UART1TX (21) /* Vector: IRQ2.5 0x58 UART1 TX */ +#define Z16F_IRQ_UART1RX (22) /* Vector: IRQ2.6 0x54 UART1 RX */ +#define Z16F_IRQ_PWMTIMER (23) /* Vector: IRQ2.7 0x50 PWM Timer */ + +#define Z16F_IRQ_SYSTIMER Z16F_IRQ_TIMER0 +#define NR_IRQS (24) + +/* These macros will map an IRQ to a register bit position */ + +#define Z16F_IRQ0_BIT(i) (1 << ((i)-Z16F_IRQ_IRQ0)) +#define Z16F_IRQ1_BIT(i) (1 << ((i)-Z16F_IRQ_IRQ1)) +#define Z16F_IRQ2_BIT(i) (1 << ((i)-Z16F_IRQ_IRQ2)) + +/* IRQ Stack Frame Format + * + * This stack frame is created on each interrupt. These registers are stored + * in the TCB to many context switches. + * + * The following represent all of the "static" registers r8-r15. These + * are registers that whose value must be retained across function calls. + * These registers must be saved bothby interrupt handling context switch + * switch logic and also by user-initiated context switches. + * + * Registers are saved in the order consistent with pushmho , + * that is with r15 pushed first and r8 push last. Since the z16f has + * a "push-down" stack, the registers will be "in order" in memory. + */ + +#define REG_R8 ( 0) /* 32-bits: R8 */ +#define REG_R9 ( 2) /* 32-bits: R9 */ +#define REG_R10 ( 4) /* 32-bits: R10 */ +#define REG_R11 ( 6) /* 32-bits: R11 */ +#define REG_R12 ( 8) /* 32-bits: R12 */ +#define REG_R13 (10) /* 32-bits: R13 */ + +/* The frame pointer and the SP at the point of task resumption must + * always be saved. + */ + +#define REG_R14 (12) /* 32-bits: R14 = fp */ +#define REG_FP REG_R14 +#define REG_R15 (14) /* 32-bits: R15 = sp */ +#define REG_SP REG_R15 + +/* The following represent all of the "volatile" registers r0-r7. These + * are registers that whose value need not be retained across function + * calls. These registers must be saved by interrupt handling context + * switch logic but not by user-initiated context switches. + * + * Registers are saved in the order consistent with pushmlo , + * that is with r7 pushed first and r0 push last. Since the z16f has + * a "push-down" stack, the registers will be "in order" in memory. + */ + +#define REG_R0 (16) /* 32-bits: R0 */ +#define REG_R1 (18) /* 32-bits: R1 */ +#define REG_R2 (20) /* 32-bits: R2 */ +#define REG_R3 (22) /* 32-bits: R3 */ +#define REG_R4 (24) /* 32-bits: R4 */ +#define REG_R5 (26) /* 32-bits: R5 */ +#define REG_R6 (28) /* 32-bits: R6 */ +#define REG_R7 (30) /* 32-bits: R7 */ + +/* The following two offsets represent the state of the stack on entry + * into the interrupt handler: + * + * TOS[0] = PC[31:24] + * TOS[1] = PC[23:16] + * TOS[2] = PC[15:8] + * TOS[3] = PC[7:0] + * TOS[4] = 0 + * TOS[5] = flags + */ + +#define REG_PC (32) /* 32-bits: Return PC */ +#define REG_FLAGS (34) /* 16-bits: Flags register (with 0x00 padding) */ + +#define XCPTCONTEXT_REGS (35) +#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the type of the register save array */ + +typedef uint16_t chipreg_t; + +/* This struct defines the way the registers are stored. */ + +struct xcptcontext +{ + /* Register save area */ + + uint16_t regs[XCPTCONTEXT_REGS]; + + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* The following retains that state during signal execution */ + + uint32_t saved_pc; /* Saved return address */ + uint16_t saved_i; /* Saved interrupt state */ +#endif +}; +#endif + +/* The ZDS-II provides built-in operations to test & disable and to restore + * the interrupt state. + * + * irqstate_t up_irq_save(void); + * void up_irq_restore(irqstate_t flags); + * + * NOTE: These functions should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +#ifdef __ZILOG__ +# define up_irq_save() TDI() +# define up_irq_restore(f) RI(f) +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* ZDS-II intrinsic functions (normally declared in zneo.h) */ + +intrinsic void EI(void); +intrinsic void DI(void); +intrinsic void RI(unsigned short); +intrinsic void SET_VECTOR(int,void (* func) (void)); +intrinsic unsigned short TDI(void); + +#ifndef __ZILOG__ +irqstate_t up_irq_save(void); +void up_irq_restore(irqstate_t flags); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z16_INCLUDE_Z16F_IRQ_H */ + diff --git a/arch/z16/src/.gitignore b/arch/z16/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5bfbd0044247a58f8b9254233339bce4d8afc41a --- /dev/null +++ b/arch/z16/src/.gitignore @@ -0,0 +1,10 @@ +/Make.dep +/.depend +/board +/chip +/nuttx.linkcmd +/*.asm +/*.obj +/*.lib +/*.map +/*.lst diff --git a/arch/z16/src/Makefile b/arch/z16/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f9bcc15fb8542a94e74e665b6ac6b6e77a782079 --- /dev/null +++ b/arch/z16/src/Makefile @@ -0,0 +1,193 @@ +############################################################################ +# arch/z16/src/Makefile +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +COMPILER = ${shell basename "$(CC)"} +ARCHSRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + USRINCLUDES = -usrinc:'.;$(TOPDIR)/sched;$(ARCHSRCDIR);$(ARCHSRCDIR)/common' +else +ifeq ($(COMPILER),zneocc.exe) + WARCHSRCDIR := ${shell cygpath -w $(ARCHSRCDIR)} + USRINCLUDES = -usrinc:'.;$(WTOPDIR)\sched;$(WARCHSRCDIR);$(WARCHSRCDIR)\common' +else + WARCHSRCDIR = $(ARCHSRCDIR) + USRINCLUDES = -I$(TOPDIR)/sched -I$(ARCHSRCDIR) -I$(ARCHSRCDIR)/common +endif +endif + +INCLUDES = $(ARCHSTDINCLUDES) $(USRINCLUDES) +CFLAGS = $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(INCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +CPPFLAGS += -I$(ARCHSRCDIR) $(EXTRADEFINES) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + LDFLAGS += @"$(ARCHSRCDIR)/nuttx.linkcmd" +else +ifeq ($(COMPILER),zneocc.exe) + LDFLAGS += @"${shell cygpath -w $(ARCHSRCDIR)/nuttx.linkcmd}" +endif +endif + +HEAD_ASRC = $(HEAD_SSRC:.S=$(ASMEXT)) +HEAD_OBJ = $(HEAD_SSRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +SSRCS = $(CHIP_SSRCS) $(CMN_SSRCS) +ASRCS = $(SSRCS:.S=$(ASMEXT)) +AOBJS = $(SSRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +DEPSRCS = $(SSRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +VPATH = chip:common + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +ifeq ($(COMPILER),zneocc.exe) +$(ASRCS) $(HEAD_ASRC): %$(ASMEXT): %.S + $(Q) $(CPP) $(CPPFLAGS) $< -o $@.tmp + $(Q) cat $@.tmp | sed -e "s/^#/;/g" > $@ + $(Q) rm $@.tmp + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %$(ASMEXT) + $(call ASSEMBLE, $<, $@) +else +$(OBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) +endif + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +ifeq ($(COMPILER),zneocc.exe) +nuttx.linkcmd: $(LINKCMDTEMPLATE) + $(Q) cp -f $(LINKCMDTEMPLATE) nuttx.linkcmd +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + @echo "$(TOPDIR)\nuttx"= \>>nuttx.linkcmd + @echo "$(ARCHSRCDIR)\$(HEAD_OBJ)", \>>nuttx.linkcmd + $(Q) for %%G in ($(LINKLIBS)) do ( echo "$(TOPDIR)\lib\%%G", \>>nuttx.linkcmd ) + @echo "$(ARCHSRCDIR)\board\libboard$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\chelpld$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\fpld$(LIBEXT)">>nuttx.linkcmd +else + @echo "\"${shell cygpath -w $(TOPDIR)/nuttx}\"= \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w $(ARCHSRCDIR)/$(HEAD_OBJ)}\", \\" >>nuttx.linkcmd + $(Q) ( for lib in $(LINKLIBS); do \ + echo " \"`cygpath -w $(TOPDIR)/lib/$${lib}`\", \\" >>nuttx.linkcmd; \ + done ; ) + @echo " \"${shell cygpath -w $(ARCHSRCDIR)/board/libboard$(LIBEXT)}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w $(ZDSSTDLIBDIR)/chelpld$(LIBEXT)}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w $(ZDSSTDLIBDIR)/fpld$(LIBEXT)}\"" >>nuttx.linkcmd +endif +else +nuttx.linkcmd: +endif + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) nuttx.linkcmd + @echo "LD: nuttx$(EXEEXT)" + $(Q) $(LD) $(LDFLAGS) + +.depend: Makefile chip/Make.defs $(DEPSRCS) +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ) +else + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ; \ + fi +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(DEPSRCS) >Make.dep + $(Q) touch $@ + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) if exist "$(EXPORT_DIR)$(DELIM)startup" ( copy $(STARTUP_OBJS) "$(EXPORT_DIR)$(DELIM)startup$(DELIM)." /b /y) +else + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi +endif + +# Dependencies + +depend: .depend + +clean: +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ) +else + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ; \ + fi +endif +ifeq ($(COMPILER),zneocc.exe) + $(call DELFILE, nuttx.linkcmd) + $(call DELFILE, *.asm) + $(call DELFILE, *.tmp) + $(call DELFILE, *.map) +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ) +else + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ; \ + fi +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/z16/src/common/Kconfig b/arch/z16/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..cc2a3060a262824dff8fc6437cfdf639ce1ef6ad --- /dev/null +++ b/arch/z16/src/common/Kconfig @@ -0,0 +1,9 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_Z16 +comment "Common Configuration Options" + +endif diff --git a/arch/z16/src/common/up_allocateheap.c b/arch/z16/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..f307a8a73e22461f435b9cc7d126227cbc33ec76 --- /dev/null +++ b/arch/z16/src/common/up_allocateheap.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * common/up_allocateheap.c + * + * Copyright (C) 2008, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Use ZDS-II linker settings to get the unused external RAM and use this + * for the NuttX heap. + */ + +#ifndef CONFIG_HEAP1_BASE + extern _Far unsigned long far_heapbot; + #define CONFIG_HEAP1_BASE ((unsigned long)&far_heapbot) +#endif + +#ifndef CONFIG_HEAP1_END + extern _Far unsigned long far_heaptop; + #define CONFIG_HEAP1_END ((unsigned long)&far_heaptop) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + *heap_start = (FAR void*)CONFIG_HEAP1_BASE; + *heap_size = CONFIG_HEAP1_END - CONFIG_HEAP1_BASE; + board_autoled_on(LED_HEAPALLOCATE); +} + +/**************************************************************************** + * Name: up_addregions + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + kmm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +} +#endif diff --git a/arch/z16/src/common/up_arch.h b/arch/z16/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..be1f77d67de37176113c5105dee3ade5065944d4 --- /dev/null +++ b/arch/z16/src/common/up_arch.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * common/up_arch.h + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z16_SRC_COMMON_UP_ARCH_H +#define __ARCH_Z16_SRC_COMMON_UP_ARCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "chip/chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#endif /* __ARCH_Z16_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/z16/src/common/up_assert.c b/arch/z16/src/common/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..fbd73d2579cef3bf5eeeda8daa3ca1ceb214424d --- /dev/null +++ b/arch/z16/src/common/up_assert.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * common/up_assert.c + * + * Copyright (C) 2008-2009, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "chip/chip.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) /* noreturn_function */ +{ + /* Are we in an interrupt handler or the idle task? */ + + if (up_interrupt_context() || this_task()->pid == 0) + { + (void)up_irq_save(); + for (;;) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +#ifdef CONFIG_HAVE_FILENAME +void up_assert(const uint8_t *filename, int lineno) +#else +void up_assert(void) +#endif +{ +#if CONFIG_TASK_NAME_SIZE > 0 + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_HAVE_FILENAME +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("Assertion failed: task: %s\n", rtcb->name); +#else + lldbg("Assertion failed\n"); +#endif +#endif + + up_stackdump(); + up_registerdump(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/z16/src/common/up_blocktask.c b/arch/z16/src/common/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..e165e74a73097470c544b44ba8c65c4fca135f6a --- /dev/null +++ b/arch/z16/src/common/up_blocktask.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * common/up_blocktask.c + * + * Copyright (C) 2008-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state) +{ + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* dbg("Blocking TCB=%p\n", tcb); */ + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT) + { + /* Yes, then we have to do things differently. + * Just copy the current registers into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z16/src/common/up_copystate.c b/arch/z16/src/common/up_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..f9240c7445082c0f72301bd89d5246b9af58c651 --- /dev/null +++ b/arch/z16/src/common/up_copystate.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * common/up_copystate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_undefinedinsn + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +void up_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/z16/src/common/up_createstack.c b/arch/z16/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..c4d55370408db9a4e2a28eecc525e73f4a868949 --- /dev/null +++ b/arch/z16/src/common/up_createstack.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/z16/common/up_createstack.c + * + * Copyright (C) 2008-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* The ZNeo uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* Align the stack to word (4 byte) boundaries. This is probably + * a greater alignement than is required. + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/z16/src/common/up_doirq.c b/arch/z16/src/common/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..d401f580f6b573ae0cd8bb078c995fa97309b5e7 --- /dev/null +++ b/arch/z16/src/common/up_doirq.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * common/up_doirq.c + * + * Copyright (C) 2008-2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_doirq + * + * Description: + * Interface between low-level IRQ decode logic and the NuttX IRQ dispatch + * logic. + * + ****************************************************************************/ + +FAR chipreg_t *up_doirq(int irq, FAR chipreg_t *regs) +{ + FAR chipreg_t *ret = regs; + + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + if ((unsigned)irq < NR_IRQS) + { + FAR chipreg_t *savestate; + + /* Nested interrupts are not supported in this implementation. If + * you want to implement nested interrupts, you would have to (1) change + * the way that g_current_regs is handled and (2) the design associated + * with CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not + * work for that purpose as implemented here because only the outermost + * nested interrupt can result in a context switch (it can probably be + * deleted). + */ + + /* Current regs non-zero indicates that we are processing + * an interrupt; g_current_regs is also used to manage + * interrupt level context switches. + */ + + savestate = (FAR chipreg_t *)g_current_regs; + g_current_regs = regs; + + /* Acknowledge the interrupt */ + + up_ack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* Restore the previous value of g_current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ + + ret = g_current_regs; + g_current_regs = savestate; + } + + board_autoled_off(LED_INIRQ); +#endif + + return ret; +} diff --git a/arch/z16/src/common/up_exit.c b/arch/z16/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..7c238b249971094274c686f1e5f60e1ea67bef42 --- /dev/null +++ b/arch/z16/src/common/up_exit.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * common/up_exit.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "chip/chip.h" +#include "task/task.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + lldbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + lldbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + lldbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + FAR struct tcb_s* tcb; + + /* Disable interrupts. Interrupts will remain disabled until + * the new task is resumed below. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", tcb); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + lldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + slldbg("New Active Task TCB=%p\n", tcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(tcb); +} + diff --git a/arch/z16/src/common/up_idle.c b/arch/z16/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..01aa0f8d6d893f20ae90c8de3636b3a706a3f689 --- /dev/null +++ b/arch/z16/src/common/up_idle.c @@ -0,0 +1,108 @@ +/**************************************************************************** + * common/up_idle.c + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP) +static uint8_t g_ledtoggle = 0; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their + * is no other ready-to-run task. This is processor idle + * time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be + * performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP) + g_ledtoggle++; + if (g_ledtoggle == 0x80) + { + board_autoled_on(LED_IDLE); + } + else if (g_ledtoggle == 0x00) + { + board_autoled_off(LED_IDLE); + } +#endif + +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, + * then process "fake" timer interrupts. Hopefully, something + * will wake up. + */ + + sched_process_timer(); +#endif +} + diff --git a/arch/z16/src/common/up_initialize.c b/arch/z16/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..50b287d08a69f0d0afd5d32c32b1a2ffa9c2f025 --- /dev/null +++ b/arch/z16/src/common/up_initialize.c @@ -0,0 +1,223 @@ +/**************************************************************************** + * arch/z16/src/common/up_initialize.c + * + * Copyright (C) 2008-2009, 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level + * register storage structure. If is non-NULL only during + * interrupt processing. + */ + +volatile FAR chipreg_t *g_current_regs; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + g_current_regs = NULL; + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Add any extra memory fragments to the memory manager */ + +#if CONFIG_MM_REGIONS > 1 + up_addregion(); +#endif + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + + /* Initialize the system logging device */ + +#ifdef CONFIG_SYSLOG_CHAR + syslog_initialize(); +#endif +#ifdef CONFIG_RAMLOG_SYSLOG + ramlog_sysloginit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/z16/src/common/up_initialstate.c b/arch/z16/src/common/up_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..246dc3dc53b8d61772ded4cfca62c33cd3399ca9 --- /dev/null +++ b/arch/z16/src/common/up_initialstate.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * common/up_initialstate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + uint32_t *reg32 = (uint32_t*)tcb->xcp.regs; + + /* Initialize the initial exception register context structure */ + + memset(&tcb->xcp, 0, sizeof(struct xcptcontext)); +#ifndef CONFIG_SUPPRESS_INTERRUPTS + tcb->xcp.regs[REG_FLAGS] = (uint16_t)Z16F_CNTRL_FLAGS_IRQE; /* IRQE flag will enable interrupts */ +#endif + reg32[REG_SP/2] = (uint32_t)tcb->adj_stack_ptr; + reg32[REG_PC/2] = (uint32_t)tcb->start; +} diff --git a/arch/z16/src/common/up_internal.h b/arch/z16/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..bd6f36ca9f8343c5f869d614a0b669adfb099978 --- /dev/null +++ b/arch/z16/src/common/up_internal.h @@ -0,0 +1,209 @@ +/**************************************************************************** + * common/up_internal.h + * + * Copyright (C) 2008-2009, 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __UP_INTERNAL_H +#define __UP_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip/chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* Dump task state on exit */ +#undef CONFIG_Z16_LOWPUTC /* Support up_lowputc for debug */ +#undef CONFIG_Z16_LOWGETC /* support up_lowgetc for debug */ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if defined(CONFIG_Z16_LOWPUTC) || defined(CONFIG_Z16_LOWGETC) || \ + CONFIG_NFILE_DESCRIPTORS == 0 || defined(CONFIG_DEV_LOWCONSOLE) +# define USE_LOWCONSOLE 1 +# define USE_LOWUARTINIT 1 +#elif !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/* Determine which device to use as the system logging device */ + +#ifndef CONFIG_SYSLOG +# undef CONFIG_SYSLOG_CHAR +# undef CONFIG_RAMLOG_SYSLOG +#endif + +/* Macros for portability */ + +#define IN_INTERRUPT (g_current_regs != NULL) +#define SAVE_IRQCONTEXT(tcb) up_copystate((tcb)->xcp.regs, (FAR chipreg_t*)g_current_regs) +#define SET_IRQCONTEXT(tcb) do { g_current_regs = (tcb)->xcp.regs; } while (0) +#define SAVE_USERCONTEXT(tcb) up_saveusercontext((tcb)->xcp.regs) +#define RESTORE_USERCONTEXT(tcb) up_restoreusercontext((tcb)->xcp.regs) +#define SIGNAL_RETURN(regs) up_restoreusercontext(regs) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*up_vector_t)(void); +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level + * register storage structure. If is non-NULL only during + * interrupt processing. + */ + +extern volatile FAR chipreg_t *g_current_regs; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Defined in files with the same name as the function */ + +void up_copystate(FAR chipreg_t *dest, FAR chipreg_t *src); +FAR chipreg_t *up_doirq(int irq, FAR chipreg_t *regs); +void up_restoreusercontext(FAR chipreg_t *regs); +void up_irqinitialize(void); +int up_saveusercontext(FAR chipreg_t *regs); +void up_sigdeliver(void); +int up_timerisr(int irq, FAR chipreg_t *regs); + +#if defined(CONFIG_Z16_LOWPUTC) || defined(CONFIG_Z16_LOWGETC) +void up_lowputc(char ch); +#else +# define up_lowputc(ch) +#endif + +/* Defined in up_allocateheap.c */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#endif + +/* Defined in up_serial.c */ + +#ifdef USE_SERIALDRIVER +void up_earlyserialinit(void); +void up_serialinit(void); +#endif + +#ifdef USE_LOWCONSOLE +void lowconsole_init(void); +#endif + +/* Defined in up_timerisr.c */ + +void up_timer_initialize(void); + +/* Defined in up_irq.c */ + +void up_ack_irq(int irq); + +/* Defined in board/up_network.c */ + +#ifdef CONFIG_NET +void up_netinitialize(void); +#else +# define up_netinitialize() +#endif + +/* Return the current value of the stack pointer (used in stack dump logic) */ + +chipreg_t up_getsp(void); + +/* Dump stack and registers */ + +#ifdef CONFIG_ARCH_STACKDUMP +void up_stackdump(void); +void up_registerdump(void); +#else +# define up_stackdump() +# define up_registerdump() +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __UP_INTERNAL_H */ diff --git a/arch/z16/src/common/up_interruptcontext.c b/arch/z16/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..c45cf376e5c6ecff37c025865047998296e3059e --- /dev/null +++ b/arch/z16/src/common/up_interruptcontext.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * common/up_interruptcontext.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/z16/src/common/up_mdelay.c b/arch/z16/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..810754dd908646c3ecfc36db0885bcdbc0958bc2 --- /dev/null +++ b/arch/z16/src/common/up_mdelay.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * common/up_mdelay.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_BOARD_LOOPSPERMSEC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} +#endif /* CONFIG_BOARD_LOOPSPERMSEC */ + diff --git a/arch/z16/src/common/up_registerdump.c b/arch/z16/src/common/up_registerdump.c new file mode 100644 index 0000000000000000000000000000000000000000..a4047d56f0171a4109300f4b461bc1d8c6de16a5 --- /dev/null +++ b/arch/z16/src/common/up_registerdump.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * common/up_registerdump.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if + * debug is not selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include + +#include +#include + +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static void up_registerdump(void) +{ + FAR uint32_t *regs32 = (FAR uint32_t*)g_current_regs; + lldbg("R0 :%08x R1 :%08x R2 :%08x R3 :%08x " + "R4 :%08x R5 :%08x R6 :%08x R7 :%08x\n" + regs32[REG_R0/2], regs32[REG_R1/2], regs32[REG_R2/2], regs32[REG_R3/2], + regs32[REG_R4/2], regs32[REG_R5/2], regs32[REG_R6/2], regs32[REG_R7/2]); + lldbg("R8 :%08x R9 :%08x R10:%08x R11:%08x R12:%08x R13:%08x\n" + regs32[REG_R8/2], regs32[REG_R9/2], regs32[REG_R10/2], regs3[REG_R11/2], + regs32[REG_R12/2], regs32[REG_R13/2]); + lldbg("FP :%08x SP :%08x FLG:%04x\n" + regs32[REG_R14/2], regs32[REG_R15/2], g_current_regs[REG_FLAGS]); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z16/src/common/up_releasepending.c b/arch/z16/src/common/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..2d0e09b5ac30f97d6945fa467e66514db74f4dae --- /dev/null +++ b/arch/z16/src/common/up_releasepending.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * common/up_releasepending.c + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + FAR struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (IN_INTERRUPT) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z16/src/common/up_releasestack.c b/arch/z16/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..f1ab953741c28295b9a4868d1da7d405c2545d65 --- /dev/null +++ b/arch/z16/src/common/up_releasestack.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * common/up_releasestack.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { + sched_ufree(dtcb->stack_alloc_ptr); + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/z16/src/common/up_reprioritizertr.c b/arch/z16/src/common/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..4872db37f2634ce6db9a3dcbe10880e9c96a5fbb --- /dev/null +++ b/arch/z16/src/common/up_reprioritizertr.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * common/up_reprioritizertr.c + * + * Copyright (C) 2008-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } + } +} diff --git a/arch/z16/src/common/up_schedulesigaction.c b/arch/z16/src/common/up_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..0592b883352a9a13d4f1bdf45f211175aab48e72 --- /dev/null +++ b/arch/z16/src/common/up_schedulesigaction.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * common/up_schedulesigaction.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + dbg("tcb=0x%p sigdeliver=0x%06x\n", tcb, (uint32_t)sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (!tcb->xcp.sigdeliver) + { + /* First, handle some special cases when the signal is + * being delivered to the currently executing task. + */ + + dbg("rtcb=0x%p g_current_regs=0x%p\n", this_task(), g_current_regs); + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and + * a task is signalling itself for some reason. + */ + + if (!g_current_regs) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted + * task is the same as the one that must receive the signal, then + * we will have to modify the return state as well as the state + * in the TCB. + */ + + else + { + FAR uint32_t *current_pc = (FAR uint32_t*)&g_current_regs[REG_PC]; + + /* Save the return address and interrupt state. These will be + * restored by the signal trampoline after the signals have + * been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = *current_pc; + tcb->xcp.saved_i = g_current_regs[REG_FLAGS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + *current_pc = (uint32_t)up_sigdeliver; + g_current_regs[REG_FLAGS] = 0; + + /* And make sure that the saved context in the TCB is the + * same as the interrupt return context. + */ + + up_copystate(tcb->xcp.regs, g_current_regs); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an + * interrupt handler or (2) we are not in an interrupt handler + * and the running task is signalling some non-running task. + */ + + else + { + FAR uint32_t *saved_pc = (FAR uint32_t*)&tcb->xcp.regs[REG_PC]; + + /* Save the return lr and cpsr and one scratch register + * These will be restored by the signal trampoline after + * the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = *saved_pc; + tcb->xcp.saved_i = tcb->xcp.regs[REG_FLAGS]; + + /* Then set up to vector to the trampoline with interrupts + * disabled + */ + + *saved_pc = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_FLAGS] = 0; + } + } + + leave_critical_section(flags); +} + +#endif /* CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/z16/src/common/up_sigdeliver.c b/arch/z16/src/common/up_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..9861f0096e0208d2775dac3149e231d226dc1071 --- /dev/null +++ b/arch/z16/src/common/up_sigdeliver.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * common/up_sigdeliver.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + FAR struct tcb_s *rtcb = this_task(); + chipreg_t regs[XCPTCONTEXT_REGS]; + FAR uint32_t *regs32 = (FAR uint32_t*)regs; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + up_copystate(regs, rtcb->xcp.regs); + regs32[REG_PC/2] = rtcb->xcp.saved_pc; + regs[REG_FLAGS] = rtcb->xcp.saved_i; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function point in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + if ((regs[REG_FLAGS] & Z16F_CNTRL_FLAGS_IRQE) != 0) + { + EI(); + } + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + SIGNAL_RETURN(regs); +#endif +} + +#endif /* CONFIG_DISABLE_SIGNALS */ diff --git a/arch/z16/src/common/up_stackdump.c b/arch/z16/src/common/up_stackdump.c new file mode 100644 index 0000000000000000000000000000000000000000..f6d9e41236da561befedd4ee55b304605f43200c --- /dev/null +++ b/arch/z16/src/common/up_stackdump.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * common/up_stackdump.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include + +#include "chip/chip.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ +/* To be provided */ + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(void) +{ + struct tcb_s *rtcb = this_task(); + chipreg_t sp = up_getsp(); + chipreg_t stack_base = (chipreg_t)rtcb->adj_stack_ptr; + chipreg_t stack_size = (chipreg_t)rtcb->adj_stack_size; + + lldbg("stack_base: %08x\n", stack_base); + lldbg("stack_size: %08x\n", stack_size); + lldbg("sp: %08x\n", sp); + + if (sp >= stack_base || sp < stack_base - stack_size) + { + lldbg("ERROR: Stack pointer is not within allocated stack\n"); + return; + } + else + { + chipreg_t stack = sp & ~0x0f; + + for (stack = sp & ~0x0f; stack < stack_base; stack += 8*sizeof(chipreg_t)) + { + chipreg_t *ptr = (chipreg_t*)stack; + lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z16/src/common/up_stackframe.c b/arch/z16/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..6a2fe6d3476cdb9cdfad44943c85df7b22107051 --- /dev/null +++ b/arch/z16/src/common/up_stackframe.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/z16/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ +/* Align the stack to word (4 byte) boundaries. This is probablya greater + * alignement than is required. + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP/2] = (uint32_t)tcb->adj_stack_ptr; + + /* And return a pointer to the allocated memory */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/z16/src/common/up_udelay.c b/arch/z16/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..54545ac072c23ba995d189c3d84edab6e9cd37a0 --- /dev/null +++ b/arch/z16/src/common/up_udelay.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * common/up_udelay.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_BOARD_LOOPSPERMSEC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} +#endif /* CONFIG_BOARD_LOOPSPERMSEC */ + diff --git a/arch/z16/src/common/up_unblocktask.c b/arch/z16/src/common/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..96eb7675ac550bcb3a69bbd1cd3d3614ac2b62d0 --- /dev/null +++ b/arch/z16/src/common/up_unblocktask.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * common/up_unblocktask.c + * + * Copyright (C) 2008-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "sched/sched.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(FAR struct tcb_s *tcb) +{ + FAR struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* dbg("Unblocking TCB=%p\n", tcb); */ + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * SAVE_USERCONTEXT returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z16/src/common/up_usestack.c b/arch/z16/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..d65609a67d0cae50da5ce0f309f0b998c26694b3 --- /dev/null +++ b/arch/z16/src/common/up_usestack.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * arch/z16/common/up_usestack.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The ZNEO uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* Align the stack to word (4 byte) boundaries. This is probably + * a greater alignement than is required. + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_size = top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} diff --git a/arch/z16/src/z16f/Kconfig b/arch/z16/src/z16f/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..229a1aa72f176f56cc10a7e4ab1a5b84af3ab3b3 --- /dev/null +++ b/arch/z16/src/z16f/Kconfig @@ -0,0 +1,39 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_Z16F +comment "Z16F Configuration Options" + +menu "Z16F Peripheral Selection" + +config Z16F_ESPI + bool "ESPI" + default n + select SPI + +# UART0/1 always enabled + +config Z16F_UART0 + bool "UART0" + default y + select ARCH_HAVE_UART0 + +config Z16F_UART1 + bool "UART1" + default y + select ARCH_HAVE_UART1 + +endmenu # Z16F Peripheral Selection + +menu "Z16F ESPI Configuration" + depends on Z16F_ESPI + +config Z16F_ESPI_REGDEBUG + bool "ESPI register-level debug" + default n + depends on DEBUG + +endmenu # Z16F ESPI Configuration +endif # ARCH_CHIP_Z16F diff --git a/arch/z16/src/z16f/Make.defs b/arch/z16/src/z16f/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..f14570fb6a8d39eddf70dc52b7fa8d0e9e27ddbd --- /dev/null +++ b/arch/z16/src/z16f/Make.defs @@ -0,0 +1,56 @@ +############################################################################ +# arch/z16/src/z16f/Make.defs +# +# Copyright (C) 2008, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_SSRC = z16f_head.S + +CMN_SSRCS = +CMN_CSRCS = up_allocateheap.c up_initialize.c up_schedulesigaction.c +CMN_CSRCS += up_assert.c up_initialstate.c up_sigdeliver.c up_blocktask.c +CMN_CSRCS += up_interruptcontext.c up_stackdump.c up_copystate.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_createstack.c up_registerdump.c +CMN_CSRCS += up_unblocktask.c up_doirq.c up_releasepending.c up_usestack.c +CMN_CSRCS += up_exit.c up_releasestack.c up_stackframe.c up_idle.c +CMN_CSRCS += up_reprioritizertr.c + +CHIP_SSRCS = z16f_lowuart.S z16f_saveusercontext.S z16f_restoreusercontext.S +CHIP_CSRCS = z16f_clkinit.c z16f_sysexec.c z16f_irq.c z16f_serial.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += z16f_timerisr.c +endif + +ifeq ($(CONFIG_Z16F_ESPI),y) +CHIP_CSRCS += z16f_espi.c +endif diff --git a/arch/z16/src/z16f/chip.h b/arch/z16/src/z16f/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..9d4942f7b943833ec427fdd2f44aa07738d1de85 --- /dev/null +++ b/arch/z16/src/z16f/chip.h @@ -0,0 +1,707 @@ +/************************************************************************************ + * arch/z16/src/z16f/chip.h + * + * Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z16_SRC_Z16F_CHIP_H +#define __ARCH_Z16_SRC_Z16F_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include +#if !defined(__ASSEMBLY__) && defined(CONFIG_Z16F_ESPI) +# include +#endif + +#include "common/up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Hexadecimal Representation *******************************************************/ + +#ifdef __ASSEMBLY__ +# define _HX32(w) %##w +# define _HX8(b) %##b +#else +# define _HX32(w) 0x##w +# define _HX8(b) 0x##b +#endif + +/* Z16F Chip Variants ***************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_Z16F2810) +# define Z16F_INVMEM_SIZE (128*1024) +# define Z16F_IRAM_SIZE (4*1024) +# undef Z16F_HAVE_EXTMEM +# undef Z16F_HAVE_GPIO_PORTJ +# undef Z16F_HAVE_GPIO_PORTK +#elif defined(CONFIG_ARCH_CHIP_Z16F2811) +# define Z16F_INVMEM_SIZE (128*1024) +# define Z16F_IRAM_SIZE (4*1024) +# define Z16F_HAVE_EXTMEM 1 +# define Z16F_HAVE_GPIO_PORTJ 1 +# define Z16F_HAVE_GPIO_PORTK 1 +#elif defined(CONFIG_ARCH_CHIP_Z16F3211) +# define Z16F_INVMEM_SIZE (32*1024) +# define Z16F_IRAM_SIZE (2*1024) +# define Z16F_HAVE_EXTMEM 1 +#elif defined(CONFIG_ARCH_CHIP_Z16F6411) +# define Z16F_INVMEM_SIZE (64*1024) +# define Z16F_IRAM_SIZE (4*1024) +# define Z16F_HAVE_EXTMEM 1 +#else +# error "Z16F chip variant not specified" +#endif + +/* Flash option settings at address 0x00000000 ************************************/ + +#define Z16F_FLOPTION0 rom char _flash_option0 _At 0x0 +#define Z16F_FLOPTION1 rom char _flash_option1 _At 0x1 +#define Z16F_FLOPTION2 rom char _flash_option2 _At 0x2 +#define Z16F_FLOPTION3 rom char _flash_option3 _At 0x3 + +#define Z16F_FLOPTION0_OSCSEL _HX8(c0) /* Bits 6-7: OSC_SEL */ +#define Z16F_FLOPTION0_EXTRNRC _HX8(00) /* 00: On-chip oscillator with ext RC networks */ +#define Z16F_FLOPTION0_LOWFREQ _HX8(40) /* 01: Min. power with very low frequency crystals */ +#define Z16F_FLOPTION0_MEDFREQ _HX8(80) /* 10: Medium power with medium frequency crystals */ +#define Z16F_FLOPTION0_MAXPWR _HX8(c0) /* 11: Maximum power with high frequency crystals */ +#define Z16F_FLOPTION0_WDTRES _HX8(20) /* Bit 5: WDT Reset */ +#define Z16F_FLOPTION0_WDTA0 _HX8(10) /* Bit 4: WDT Always On */ +#define Z16F_FLOPTION0_VBOA0 _HX8(08) /* Bit 3: Voltage Brown-Out Protection Always On */ +#define Z16F_FLOPTION0_DBGUART _HX8(04) /* Bit 2: Debug UART Enable */ +#define Z16F_FLOPTION0_FWP _HX8(02) /* Bit 1: Flash Write Protect */ +#define Z16F_FLOPTION0_RP _HX8(01) /* Bit 0: Read Protect */ + +#define Z16F_FLOPTION1_RESVD _HX8(f8) /* Bits 3-7: Reserved */ +#define Z16F_FLOPTION1_MCEN _HX8(04) /* Bit 2: Motor control pins enable */ +#define Z16F_FLOPTION1_OFFH _HX8(02) /* Bit 1: High side OFF */ +#define Z16F_FLOPTION1_OFFL _HX8(01) /* Bit 0: Low side OFF */ + +#define Z16F_FLOPTION2_RESVD _HX8(ff) /* Bits 0-7: reserved */ + +#define Z16F_FLOPTION3_ROMLESS _HX8(80) /* Bit 7: ROMLESS 16 Select */ +#define Z16F_FLOPTION3_NORMAL _HX8(40) /* Bit 6: 1:Normal 0:Low power mode */ +#define Z16F_FLOPTION3_RESVD _HX8(3f) /* Bits 0-5: Reserved */ + +/* Memory areas ******************************************************************* + * + * Internal non-volatile memory starts at address zero. The size + * of the internal non-volatile memory is chip-dependent. + */ + +#define Z16F_INVMEM_BASE _HX32(00000000) + +/* Most chip variants support external memory */ + +#ifdef Z16F_HAVE_EXTMEM +# define Z16F_EXTMEMCS0_BASE _HX32(00000000) /* External memory at CS0 */ +# define Z16F_EXTMEMCS0_SIZE _HX32(007e0000) /* (actual depends on board) */ +# define Z16F_EXTMEMCS1_BASE _HX32(ff800000) /* External memory at CS1 */ +# define Z16F_EXTMEMCS1_SIZE _HX32(00700000) /* (actual depends on board) */ +# define Z16F_EXTMEMCS2A_BASE _HX32(fff00000) /* External memory at CS2 */ +# define Z16F_EXTMEMCS2A_SIZE _HX32(000f8000) /* (actual depends on board) */ +# define Z16F_EXTMEMCS2B_BASE _HX32(ffffc000) /* External memory at CS2 */ +# define Z16F_EXTMEMCS2B_SIZE _HX32(00000800) /* (actual depends on board) */ +#endif + +/* Internal RAM always ends at 0xffbfff. The IRAM base address depends + * on the size of the IRAM supported by the chip. + */ + +#define Z16F_IRAM_BASE (_HX32(ffffc000) - Z16F_IRAM_SIZE) + +/* External memory mapped peripherals, internal I/O memory and SFRS */ + +#define Z16F_EXTIO_BASE _HX32(ffffc800) /* External peripherals CS3-5 */ +#define Z16F_EXTIO_SIZE _HX32(00001800) +#define Z16F_IIO_BASE _HX32(ffffe000) /* Internal I/O memory and SFRs */ +#define Z16F_IIO_SIZE _HX32(00001fff) + +/* Control Registers ***************************************************************/ + +#define Z16F_CNTRL_PCOV _HX32(ffffe004) /* 32-bits: Program counter overflow */ +#define Z16F_CNTRL_SPOV _HX32(ffffe00c) /* 32-bits: Stack pointer overflow */ +#define Z16F_CNTRL_FLAGS _HX32(ffffe100) /* 8-bits: flags */ +#define Z16F_CNTRL_CPUCTL _HX32(ffffe102) /* 8-bits: CPU control */ + +/* Flag register bits ***************************************************************/ + +#define Z16F_CNTRL_FLAGS_C _HX8(80) /* Bit 7: Carry flag */ +#define Z16F_CNTRL_FLAGS_Z _HX8(40) /* Bit 6: Zero flag */ +#define Z16F_CNTRL_FLAGS_S _HX8(20) /* Bit 5: Sign flag */ +#define Z16F_CNTRL_FLAGS_V _HX8(10) /* Bit 4: Overflow flag */ +#define Z16F_CNTRL_FLAGS_B _HX8(08) /* Bit 3: Blank flag */ +#define Z16F_CNTRL_FLAGS_F1 _HX8(04) /* Bit 2: User flag 1 */ +#define Z16F_CNTRL_FLAGS_CIRQE _HX8(02) /* Bit 1: Chained interrupt enable */ +#define Z16F_CNTRL_FLAGS_IRQE _HX8(01) /* Bit 0: Master interrupt enable */ + +/* CPU control register bits ********************************************************/ + + /* Bits 7-2: Reserved, must be zero */ + /* Bits 1-0: DMA bandwidth control */ +#define Z16F_CNTRL_CPUCTL_BWALL _HX8(00) /* DMA can consume 100% bandwidth */ +#define Z16F_CNTRL_CPUCTL_BW11 _HX8(01) /* DMA can do 1 transaction per 1 cycle */ +#define Z16F_CNTRL_CPUCTL_BW12 _HX8(01) /* DMA can do 1 transaction per 2 cycles */ +#define Z16F_CNTRL_CPUCTL_BW13 _HX8(01) /* DMA can do 1 transaction per 3 cycles */ + +/* Trace registers ******************************************************************/ + +#define Z16F_TRACE_CTL _HX32(ffffe013) /* 8-bit: Trace Control */ +#define Z16F_TRACE_ADDR _HX32(ffffe014) /* 32-bit: Trace Address */ + +/* Interrupt controller registers ***************************************************/ + +#define Z16F_SYSEXCP _HX32(ffffe020) /* 16-bit: System Exception Status */ +# define Z16F_SYSEXCPH _HX32(ffffe020) /* 8-bit: System Exception Status High */ +# define Z16F_SYSEXCPL _HX32(ffffe021) /* 8-bit: System Exception Status Low */ +#define Z16F_LASTIRQ _HX32(ffffe023) /* 8-bit: Last IRQ Register */ +#define Z16F_IRQ0 _HX32(ffffe030) /* 8-bit: Interrupt Request 0 */ +#define Z16F_IRQ0_SET _HX32(ffffe031) /* 8-bit: Interrupt Request 0 Set */ +#define Z16F_IRQ0_EN _HX32(ffffe032) /* 16-bit: IRQ0 Enable */ +# define Z16F_IRQ0_ENH _HX32(ffffe032) /* 8-bit: IRQ0 Enable High Bit */ +# define Z16F_IRQ0_ENL _HX32(ffffe033) /* 8-bit: IRQ0 Enable Low Bit */ +#define Z16F_IRQ1 _HX32(ffffe034) /* 8-bit: Interrupt Request 1 */ +#define Z16F_IRQ1_SET _HX32(ffffe035) /* 8-bit: Interrupt Request 1 Set */ +#define Z16F_IRQ1_EN _HX32(ffffe036) /* 16-bit: IRQ1 Enable */ +# define Z16F_IRQ1_ENH _HX32(ffffe036) /* 8-bit: IRQ1 Enable High Bit */ +# define Z16F_IRQ1_ENL _HX32(ffffe037) /* 8-bit: IRQ1 Enable Low Bit */ +#define Z16F_IRQ2 _HX32(ffffe038) /* 8-bit: Interrupt Request 2 */ +#define Z16F_IRQ2_SET _HX32(ffffe039) /* 8-bit Interrupt Request 2 Set */ +#define Z16F_IRQ2_EN _HX32(ffffe03a) /* 16-bit: IRQ2 Enable */ +# define Z16F_IRQ2_ENH _HX32(ffffe03a) /* 8-bit: IRQ2 Enable High Bit */ +# define Z16F_IRQ2_ENL _HX32(ffffe03c) /* 8-bit: IRQ2 Enable Low Bit */ + +/* System exception status register bit definitions *********************************/ + +#define Z16F_SYSEXCPH_SPOVF _HX8(80) /* Bit 7: Stack pointer overflow */ +#define Z16F_SYSEXCPH_PCOVF _HX8(40) /* Bit 6: Program counter overflow */ +#define Z16F_SYSEXCPH_DIV0 _HX8(20) /* Bit 5: Divide by zero */ +#define Z16F_SYSEXCPH_DIVOVF _HX8(10) /* Bit 4: Divide overflow */ +#define Z16F_SYSEXCPH_ILL _HX8(08) /* Bit 3: Illegal instruction */ + /* Bits 0-2: Reserved */ + /* Bits 3-7: Reserved */ +#define Z16F_SYSEXCPL_WDTOSC _HX8(04) /* Bit 2: WDT oscillator failure */ +#define Z16F_SYSEXCPL_PRIOSC _HX8(02) /* Bit 1: Primary oscillator failure */ +#define Z16F_SYSEXCPL_WDT _HX8(01) /* Bit 0: Watchdog timer interrupt */ + +#define Z16F_SYSEXCP_SPOVF (Z16F_SYSEXCPH_SPOVF << 8) +#define Z16F_SYSEXCP_PCOVF (Z16F_SYSEXCPH_PCOVF << 8) +#define Z16F_SYSEXCP_DIV0 (Z16F_SYSEXCPH_DIV0 << 8) +#define Z16F_SYSEXCP_DIVOVF (Z16F_SYSEXCPH_DIVOVF << 8) +#define Z16F_SYSEXCP_ILL (Z16F_SYSEXCPH_ILL << 8) +#define Z16F_SYSEXCP_WDTOSC Z16F_SYSEXCPL_WDTOSC +#define Z16F_SYSEXCP_PRIOSC Z16F_SYSEXCPL_PRIOSC +#define Z16F_SYSEXCP_WDT Z16F_SYSEXCPL_WDT + +/* External memory interface ********************************************************/ + +#define Z16F_EXTCT _HX32(ffffe070) /* External Interface Control */ +#define Z16F_EXTCS0 _HX32(ffffe072) /* Chip Select 0 Control */ +# define Z16F_EXTCS0H _HX32(ffffe072) /* Chip Select 0 Control High */ +# define Z16F_EXTCS0L _HX32(ffffe073) /* Chip Select 0 Control Low */ +#define Z16F_EXTCS1 _HX32(ffffe074) /* Chip Select 1 Control */ +# define Z16F_EXTCS1H _HX32(ffffe074) /* Chip Select 1 Control High */ +# define Z16F_EXTCS1L _HX32(ffffe075) /* Chip Select 1 Control Low */ +#define Z16F_EXTCS2 _HX32(ffffe076) /* Chip Select 2 Control */ +# define Z16F_EXTCS2H _HX32(ffffe076) /* Chip Select 2 Control High */ +# define Z16F_EXTCS2L _HX32(ffffe077) /* Chip Select 2 Control Low */ +#define Z16F_EXTCS3 _HX32(ffffe078) /* Chip Select 3 Control */ +# define Z16F_EXTCS3H _HX32(ffffe078) /* Chip Select 3 Control High */ +# define Z16F_EXTCS3L _HX32(ffffe079) /* Chip Select 3 Control Low */ +#define Z16F_EXTCS4 _HX32(ffffe07a) /* Chip Select 4 Control */ +# define Z16F_EXTCS4H _HX32(ffffe07a) /* Chip Select 4 Control High */ +# define Z16F_EXTCS4L _HX32(ffffe07b) /* Chip Select 4 Control Low */ +#define Z16F_EXTCS5 _HX32(ffffe07c) /* Chip Select 5 Control */ +# define Z16F_EXTCS5H _HX32(ffffe07c) /* Chip Select 5 Control High */ +# define Z16F_EXTCS5L _HX32(ffffe07d) /* Chip Select 5 Control Low */ + +/* Oscillator control registers *****************************************************/ + +#define Z16F_OSC_CTL _HX32(ffffe0A0) /* 8-bit: Oscillator Control */ +#define Z16F_OSC_DIV _HX32(ffffe0A1) /* 8-bit: Oscillator Divide */ + +/* Oscillator control register bits *************************************************/ + +#define Z16F_OSCCTL_INTEN _HX8(80) /* Bit 7: Internal oscillator enabled */ +#define Z16F_OSCCTL_XTLEN _HX8(40) /* Bit 6: Crystal oscillator enabled */ +#define Z16F_OSCCTL_WDTEN _HX8(20) /* Bit 5: Watchdog timer enabled */ +#define Z16F_OSCCTL_POFEN _HX8(10) /* Bit 4: Failure detection enabled */ +#define Z16F_OSCCTL_WDFEN _HX8(08) /* Bit 3: WD Failure detection enabled*/ +#define Z16F_OSCCTL_FLPEN _HX8(04) /* Bit 2: Flash low power enabled */ +#define Z16F_OSCCTL_INT56 _HX8(00) /* Bits 0-1=0: Internal 5.6 MHz */ +#define Z16F_OSCCTL_EXTCLK _HX8(02) /* Bits 0-1=2: External clock */ +#define Z16F_OSCCTL_WDT10KHZ _HX8(03) /* Bits 0-1=3: WD Timer 10 KHz*/ + +/* GPIO Port A-K ********************************************************************/ + +#define Z16F_GPIOA_IN _HX32(ffffe100) /* 8-bits: Port A Input Data */ +#define Z16F_GPIOA_OUT _HX32(ffffe101) /* 8-bits: Port A Output Data */ +#define Z16F_GPIOA_DD _HX32(ffffe102) /* 8-bits: Port A Data Direction */ +#define Z16F_GPIOA_HDE _HX32(ffffe103) /* 8-bits: Port A High Drive Enable */ +#define Z16F_GPIOA_AF _HX32(ffffe104) /* 16-bits: Port A Alternate Function */ +# define Z16F_GPIOA_AFH _HX32(ffffe104) /* 8-bits: Port A Alternate Function High */ +# define Z16F_GPIOA_AFL _HX32(ffffe105) /* 8-bits: Port A Alternate Function Low */ +#define Z16F_GPIOA_OC _HX32(ffffe106) /* 8-bits: Port A Output Control */ +#define Z16F_GPIOA_PUE _HX32(ffffe107) /* 8-bits: Port A Pull-Up Enable */ +#define Z16F_GPIOA_SMRE _HX32(ffffe108) /* 8-bits: Port A Stop Mode Recovery En */ +#define Z16F_GPIOA_IMUX1 _HX32(ffffe10c) /* 8-bits: Port A IRQ Mux 1 */ +#define Z16F_GPIOA_IMUX _HX32(ffffe10e) /* 8-bits: Port A IRQ Mux */ +#define Z16F_GPIOA_IEDGE _HX32(ffffe10f) /* 8-bits: Port A IRQ Edge */ + +#define Z16F_GPIOB_IN _HX32(ffffe110) /* 8-bits: Port B Input Data */ +#define Z16F_GPIOB_OUT _HX32(ffffe111) /* 8-bits: Port B Output Data */ +#define Z16F_GPIOB_DD _HX32(ffffe112) /* 8-bits: Port B Data Direction */ +#define Z16F_GPIOB_HDE _HX32(ffffe113) /* 8-bits: Port B High Drive Enable */ +#define Z16F_GPIOB_AFL _HX32(ffffe115) /* 8-bits: Port B Alternate Function Low */ +#define Z16F_GPIOB_OC _HX32(ffffe116) /* 8-bits: Port B Output Control */ +#define Z16F_GPIOB_PUE _HX32(ffffe117) /* 8-bits: Port B Pull-Up Enable */ +#define Z16F_GPIOB_SMRE _HX32(ffffe118) /* 8-bits: Port B Stop Mode Recovery En */ + +#define Z16F_GPIOC_IN _HX32(ffffe120) /* 8-bits: Port C Input Data */ +#define Z16F_GPIOC_OUT _HX32(ffffe121) /* 8-bits: Port C Output Data */ +#define Z16F_GPIOC_DD _HX32(ffffe122) /* 8-bits: Port C Data Direction */ +#define Z16F_GPIOC_HDE _HX32(ffffe123) /* 8-bits: Port C High Drive Enable */ +#define Z16F_GPIOC_AF _HX32(ffffe124) /* 16-bits: Port C Alternate Function */ +# define Z16F_GPIOC_AFH _HX32(ffffe124) /* 8-bits: Port C Alternate Function High */ +# define Z16F_GPIOC_AFL _HX32(ffffe125) /* 8-bits: Port C Alternate Function Low */ +#define Z16F_GPIOC_OC _HX32(ffffe126) /* 8-bits: Port C Output Control */ +#define Z16F_GPIOC_PUE _HX32(ffffe127) /* 8-bits: Port C Pull-Up Enable */ +#define Z16F_GPIOC_SMRE _HX32(ffffe128) /* 8-bits: Port C Stop Mode Recovery En */ +#define Z16F_GPIOC_IMUX _HX32(ffffe12e) /* 8-bits: Port C IRQ Mux */ + +#define Z16F_GPIOD_IN _HX32(ffffe130) /* 8-bits: Port D Input Data */ +#define Z16F_GPIOD_OUT _HX32(ffffe131) /* 8-bits: Port D Output Data */ +#define Z16F_GPIOD_DD _HX32(ffffe132) /* 8-bits: Port D Data Direction */ +#define Z16F_GPIOD_HDE _HX32(ffffe133) /* 8-bits: Port D High Drive Enable */ +#define Z16F_GPIOD_AF _HX32(ffffe134) /* 16-bits: Port D Alternate Function */ +# define Z16F_GPIOD_AFH _HX32(ffffe134) /* 8-bits: Port D Alternate Function High */ +# define Z16F_GPIOD_AFL _HX32(ffffe135) /* 8-bits: Port D Alternate Function Low */ +#define Z16F_GPIOD_OC _HX32(ffffe136) /* 8-bits: Port D Output Control */ +#define Z16F_GPIOD_PUE _HX32(ffffe137) /* 8-bits: Port D Pull-Up Enable */ +#define Z16F_GPIOD_SMRE _HX32(ffffe138) /* 8-bits: Port D Stop Mode Recovery En */ + +#define Z16F_GPIOE_IN _HX32(ffffe140) /* 8-bits: Port E Input Data */ +#define Z16F_GPIOE_OUT _HX32(ffffe141) /* 8-bits: Port E Output Data */ +#define Z16F_GPIOE_DD _HX32(ffffe142) /* 8-bits: Port E Data Direction */ +#define Z16F_GPIOE_HDE _HX32(ffffe143) /* 8-bits: Port E High Drive Enable */ +#define Z16F_GPIOE_OC _HX32(ffffe146) /* 8-bits: Port E Output Control */ +#define Z16F_GPIOE_PUE _HX32(ffffe147) /* 8-bits: Port E Pull-Up Enable */ +#define Z16F_GPIOE_SMRE _HX32(ffffe148) /* 8-bits: Port E Stop Mode Recovery En */ + +#define Z16F_GPIOF_IN _HX32(ffffe150) /* 8-bits: Port F Input Data */ +#define Z16F_GPIOF_OUT _HX32(ffffe151) /* 8-bits: Port F Output Data */ +#define Z16F_GPIOF_DD _HX32(ffffe152) /* 8-bits: Port F Data Direction */ +#define Z16F_GPIOF_HDE _HX32(ffffe153) /* 8-bits: Port F High Drive Enable */ +#define Z16F_GPIOF_AFL _HX32(ffffe155) /* 8-bits: Port F Alternate Function Low */ +#define Z16F_GPIOF_OC _HX32(ffffe156) /* 8-bits: Port F Output Control */ +#define Z16F_GPIOF_PUE _HX32(ffffe157) /* 8-bits: Port F Pull-Up Enable */ +#define Z16F_GPIOF_SMRE _HX32(ffffe158) /* 8-bits: Port F Stop Mode Recovery En */ + +#define Z16F_GPIOG_IN _HX32(ffffe160) /* 8-bits: Port G Input Data */ +#define Z16F_GPIOG_OUT _HX32(ffffe161) /* 8-bits: Port G Output Data */ +#define Z16F_GPIOG_DD _HX32(ffffe162) /* 8-bits: Port G Data Direction */ +#define Z16F_GPIOG_HDE _HX32(ffffe163) /* 8-bits: Port G High Drive Enable */ +#define Z16F_GPIOG_AFL _HX32(ffffe165) /* 8-bits: Port G Alternate Function Low */ +#define Z16F_GPIOG_OC _HX32(ffffe166) /* 8-bits: Port G Output Control */ +#define Z16F_GPIOG_PUE _HX32(ffffe167) /* 8-bits: Port G Pull-Up Enable */ +#define Z16F_GPIOG_SMRE _HX32(ffffe168) /* 8-bits: Port G Stop Mode Recovery En */ + +#define Z16F_GPIOH_IN _HX32(ffffe170) /* 8-bits: Port H Input Data */ +#define Z16F_GPIOH_OUT _HX32(ffffe171) /* 8-bits: Port H Output Data */ +#define Z16F_GPIOH_DD _HX32(ffffe172) /* 8-bits: Port H Data Direction */ +#define Z16F_GPIOH_HDE _HX32(ffffe173) /* 8-bits: Port H High Drive Enable */ +#define Z16F_GPIOH_AF _HX32(ffffe174) /* 16-bits: Port H Alternate Function */ +# define Z16F_GPIOH_AFH _HX32(ffffe174) /* 8-bits: Port H Alternate Function High */ +# define Z16F_GPIOH_AFL _HX32(ffffe175) /* 8-bits: Port H Alternate Function LOw */ +#define Z16F_GPIOH_OC _HX32(ffffe176) /* 8-bits: Port H Output Control */ +#define Z16F_GPIOH_PUE _HX32(ffffe177) /* 8-bits: Port H Pull-Up Enable */ +#define Z16F_GPIOH_SMRE _HX32(ffffe178) /* 8-bits: Port H Stop Mode Recovery En */ + +#ifdef Z16F_HAVE_GPIO_PORTJ +# define Z16F_GPIOJ_IN _HX32(ffffe180) /* 8-bits: Port J Input Data */ +# define Z16F_GPIOJ_OUT _HX32(ffffe181) /* 8-bits: Port J Output Data */ +# define Z16F_GPIOJ_DD _HX32(ffffe182) /* 8-bits: Port J Data Direction */ +# define Z16F_GPIOJ_HDE _HX32(ffffe183) /* 8-bits: Port J High Drive Enable */ +# define Z16F_GPIOJ_OC _HX32(ffffe186) /* 8-bits: Port J Output Control */ +# define Z16F_GPIOJ_PUE _HX32(ffffe187) /* 8-bits: Port J Pull-Up Enable */ +# define Z16F_GPIOJ_SMRE _HX32(ffffe188) /* 8-bits: Port J Stop Mode Recovery En */ +#endif + +#ifdef Z16F_HAVE_GPIO_PORTK +# define Z16F_GPIOK_IN _HX32(ffffe190) /* 8-bits: Port K Input Data */ +# define Z16F_GPIOK_OUT _HX32(ffffe191) /* 8-bits: Port K Output Data */ +# define Z16F_GPIOK_DD _HX32(ffffe192) /* 8-bits: Port K Data Direction */ +# define Z16F_GPIOK_HDE _HX32(ffffe193) /* 8-bits: Port K High Drive Enable */ +# define Z16F_GPIOK_AFL _HX32(ffffe195) /* 8-bits: Port K Alternate Function Low */ +# define Z16F_GPIOK_OC _HX32(ffffe196) /* 8-bits: Port K Output Control */ +# define Z16F_GPIOK_PUE _HX32(ffffe197) /* 8-bits: Port K Pull-Up Enable */ +# define Z16F_GPIOK_SMRE _HX32(ffffe198) /* 8-bits: Port K Stop Mode Recovery En */ +#endif + +/* UART Register Offsets *************************************************************/ + +#define Z16F_UART_TXD _HX8(00) /* 8-bits: UART Transmit Data */ +#define Z16F_UART_RXD _HX8(00) /* 8-bits: UART Receive Data */ +#define Z16F_UART_STAT0 _HX8(01) /* 8-bits: UART Status 0 */ +#define Z16F_UART_CTL _HX8(02) /* 16-bits: UART Control */ +# define Z16F_UART_CTL0 _HX8(02) /* 8-bits: UART Control 0 */ +# define Z16F_UART_CTL1 _HX8(03) /* 8-bits: UART COntrol 1 */ +#define Z16F_UART_MDSTAT _HX8(04) /* 8-bits: UART Mode Select & Status */ +#define Z16F_UART_ADDR _HX8(05) /* 8-bits: UART Address Compare */ +#define Z16F_UART_BR _HX8(06) /* 16-bits: UART Baud Rate */ +# define Z16F_UART_BRH _HX8(06) /* 8-bits: UART Baud Rate High Byte */ +# define Z16F_UART_BRL _HX8(07) /* 8-bits: UART Baud Rate Low Byte */ + +#define Z16F_UART0_BASE _HX32(ffffe200) /* UART0 Register Base Address */ +#define Z16F_UART1_BASE _HX32(ffffe210) /* UART1 Register Base Address */ + +/* UART0/1 Registers ****************************************************************/ + +#define Z16F_UART0_TXD _HX32(ffffe200) /* 8-bits: UART0 Transmit Data */ +#define Z16F_UART0_RXD _HX32(ffffe200) /* 8-bits: UART0 Receive Data */ +#define Z16F_UART0_STAT0 _HX32(ffffe201) /* 8-bits: UART0 Status 0 */ +#define Z16F_UART0_CTL _HX32(ffffe202) /* 16-bits: UART0 Control */ +# define Z16F_UART0_CTL0 _HX32(ffffe202) /* 8-bits: UART0 Control 0 */ +# define Z16F_UART0_CTL1 _HX32(ffffe203) /* 8-bits: UART0 COntrol 1 */ +#define Z16F_UART0_MDSTAT _HX32(ffffe204) /* 8-bits: UART0 Mode Select & Status */ +#define Z16F_UART0_ADDR _HX32(ffffe205) /* 8-bits: UART0 Address Compare */ +#define Z16F_UART0_BR _HX32(ffffe206) /* 16-bits: UART0 Baud Rate */ +# define Z16F_UART0_BRH _HX32(ffffe206) /* 8-bits: UART0 Baud Rate High Byte */ +# define Z16F_UART0_BRL _HX32(ffffe207) /* 8-bits: UART0 Baud Rate Low Byte */ + +#define Z16F_UART1_TXD _HX32(ffffe210) /* 8-bits: UART1 Transmit Data */ +#define Z16F_UART1_RXD _HX32(ffffe210) /* 8-bits: UART1 Receive Data */ +#define Z16F_UART1_STAT0 _HX32(ffffe211) /* 8-bits: UART1 Status 0 */ +#define Z16F_UART1_CTL _HX32(ffffe212) /* 16-bits: UART1 Control */ +# define Z16F_UART1_CTL0 _HX32(ffffe212) /* 8-bits: UART1 Control 0 */ +# define Z16F_UART1_CTL1 _HX32(ffffe213) /* 8-bits: UART1 COntrol 1 */ +#define Z16F_UART1_MDSTAT _HX32(ffffe214) /* 8-bits: UART1 Mode Select & Status */ +#define Z16F_UART1_ADDR _HX32(ffffe215) /* 8-bits: UART1 Address Compare */ +#define Z16F_UART1_BR _HX32(ffffe216) /* 16-bits: UART1 Baud Rate */ +# define Z16F_UART1_BRH _HX32(ffffe216) /* 8-bits: UART1 Baud Rate High Byte */ +# define Z16F_UART1_BRL _HX32(ffffe217) /* 8-bits: UART1 Baud Rate Low Byte */ + +/* UART0/1 Status 0 Register Bit Definitions ****************************************/ + +#define Z16F_UARTSTAT0_RDA _HX8(80) /* Bit 7: Receive Data Available */ +#define Z16F_UARTSTAT0_PE _HX8(40) /* Bit 6: Parity Error */ +#define Z16F_UARTSTAT0_OE _HX8(20) /* Bit 5: Overrun Error */ +#define Z16F_UARTSTAT0_FE _HX8(10) /* Bit 4: Framing Error */ +#define Z16F_UARTSTAT0_BRKD _HX8(08) /* Bit 3: Break Detect */ +#define Z16F_UARTSTAT0_TDRE _HX8(04) /* Bit 2: Transmitter Data Register Empty */ +#define Z16F_UARTSTAT0_TXE _HX8(02) /* Bit 1: Transmitter Empty */ +#define Z16F_UARTSTAT0_CTS _HX8(01) /* Bit 0: Clear To Send */ + +/* UART0/1 Control 0/1 Register Bit Definitions *************************************/ + +#define Z16F_UARTCTL0_TEN _HX8(80) /* Bit 7: Transmit Enable */ +#define Z16F_UARTCTL0_REN _HX8(40) /* Bit 6: Receive Enable */ +#define Z16F_UARTCTL0_CTSE _HX8(20) /* Bit 5: CTS Enable */ +#define Z16F_UARTCTL0_PEN _HX8(10) /* Bit 4: Parity Enable */ +#define Z16F_UARTCTL0_PSEL _HX8(08) /* Bit 3: Odd Parity Select */ +#define Z16F_UARTCTL0_SBRK _HX8(04) /* Bit 2: Send Break */ +#define Z16F_UARTCTL0_STOP _HX8(02) /* Bit 1: Stop Bit Select */ +#define Z16F_UARTCTL0_LBEN _HX8(01) /* Bit 0: Loopback Enable */ + +#define Z16F_UARTCTL1_MPMD1 _HX8(80) /* Bit 7: Multiprocessor Mode (bit1) */ +#define Z16F_UARTCTL1_MPEN _HX8(40) /* Bit 6: Multiprocessor Enable */ +#define Z16F_UARTCTL1_MPMD0 _HX8(20) /* Bit 5: Multiprocessor Mode (bit0) */ +#define Z16F_UARTCTL1_MPBT _HX8(10) /* Bit 4: Multiprocessor Bit Transmit */ +#define Z16F_UARTCTL1_DEPOL _HX8(08) /* Bit 3: Driver Enable Polarity */ +#define Z16F_UARTCTL1_BRGCTL _HX8(04) /* Bit 2: Baud Rate Generator Control */ +#define Z16F_UARTCTL1_RDAIRQ _HX8(02) /* Bit 1: Receive Data Interrupt Enable */ +#define Z16F_UARTCTL1_IREN _HX8(01) /* Bit 0: Infrared Encoder/Decoder Enable */ + +/* UART0/1 Mode Status/Select Register Bit Definitions ******************************/ + +#define Z16F_UARTMDSEL_NORMAL _HX8(00) /* Bits 5-7=0: Multiprocessor and Normal Mode */ +#define Z16F_UARTMDSEL_FILTER _HX8(20) /* Bits 5-7=1: Noise Filter Control/Status */ +#define Z16F_UARTMDSEL_LINP _HX8(40) /* Bits 5-7=2: LIN protocol Contol/Status */ +#define Z16F_UARTMDSEL_HWREV _HX8(e0) /* Bits 5-7=7: LIN-UART Hardware Revision */ + /* Bits 0-4: Mode dependent status */ + +/* ESPI registers *******************************************************************/ + +#define Z16F_ESPI_DATA _HX32(ffffe260) /* 8-bit: ESPI Data */ +#define Z16F_ESPI_DCR _HX32(ffffe261) /* 8-bit: ESPI Transmit Data Command */ +#define Z16F_ESPI_CTL _HX32(ffffe262) /* 8-bit: ESPI Control */ +#define Z16F_ESPI_MODE _HX32(ffffe263) /* 8-bit: ESPI Mode */ +#define Z16F_ESPI_STAT _HX32(ffffe264) /* 8-bit: ESPI Status */ +#define Z16F_ESPI_STATE _HX32(ffffe265) /* 8-bit: ESPI State */ +#define Z16F_ESPI_BR _HX32(ffffe266) /* 16-bit: ESPI Baud Rate High Byte */ +# define Z16F_ESPI_BRH _HX32(ffffe266) /* 8-bit: ESPI Baud Rate High Byte */ +# define Z16F_ESPI_BRL _HX32(ffffe267) /* 8-bit: ESPI Baud Rate Low Byte */ + +/* ESPI register bit definitions ****************************************************/ + +#define Z16F_ESPI_DCR_SSV _HX8(01) /* Bit 0: Slave Select Value */ +#define Z16F_ESPI_DCR_TEOF _HX8(02) /* Bit 1: Transmit End of Frame */ + +#define Z16F_ESPI_CTL_ESPIEN0 _HX8(01) /* Bit 0: ESPI Enable and Direction Control */ +#define Z16F_ESPI_CTL_MMEN _HX8(02) /* Bit 1: ESPI Master Mode Enable */ +#define Z16F_ESPI_CTL_WOR _HX8(04) /* Bit 2: Wire-OR (Open-Drain) Mode Enabled */ +#define Z16F_ESPI_CTL_CLKPOL _HX8(08) /* Bit 3: Clock Polarity */ +#define Z16F_ESPI_CTL_PHASE _HX8(10) /* Bit 4: Phase Select */ +#define Z16F_ESPI_CTL_BRGCTL _HX8(20) /* Bit 5: Baud Rate Generator Control */ +#define Z16F_ESPI_CTL_ESPIEN1 _HX8(40) /* Bit 6: ESPI Enable and Direction Control */ +#define Z16F_ESPI_CTL_DIRQE _HX8(80) /* Bit 7: Data Interrupt Request Enable */ + +#define Z16F_ESPI_MODE_SSPO _HX8(01) /* Bit 0: Slave Select Polarity */ +#define Z16F_ESPI_MODE_SSIO _HX8(02) /* Bit 1: Slave Select I/O */ +#define Z16F_ESPI_MODE_NUMBITS_SHIFT (2) /* Bits 2-4: Number of Data Bits Per Character */ +#define Z16F_ESPI_MODE_NUMBITS_MASK (7 << Z16F_ESPI_MODE_NUMBITS_SHIFT) +# define Z16F_ESPI_MODE_NUMBITS_8BITS (0 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 8 bits */ +# define Z16F_ESPI_MODE_NUMBITS_1BIT (1 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 1 bit */ +# define Z16F_ESPI_MODE_NUMBITS_2BITS (2 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 2 bits */ +# define Z16F_ESPI_MODE_NUMBITS_3BITS (3 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 3 bits */ +# define Z16F_ESPI_MODE_NUMBITS_4BITS (4 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 4 bits */ +# define Z16F_ESPI_MODE_NUMBITS_5BITS (5 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 5 bits */ +# define Z16F_ESPI_MODE_NUMBITS_6BITS (6 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 6 bits */ +# define Z16F_ESPI_MODE_NUMBITS_7BITS (7 << Z16F_ESPI_MODE_NUMBITS_SHIFT) /* 7 bits */ +#define Z16F_ESPI_MODE_SSMD_SHIFT (5) /* Bits 5-7: SLAVE SELECT Mode */ +#define Z16F_ESPI_MODE_SSMD_MASK (7 << Z16F_ESPI_MODE_SSMD_SHIFT) +# define Z16F_ESPI_MODE_SSMD_SPI (0 << Z16F_ESPI_MODE_SSMD_SHIFT) /* SPI mode */ +# define Z16F_ESPI_MODE_SSMD_LPBK (1 << Z16F_ESPI_MODE_SSMD_SHIFT) /* LOOPBACK Mode */ +# define Z16F_ESPI_MODE_SSMD_I2S (2 << Z16F_ESPI_MODE_SSMD_SHIFT) /* I2S Mode */ + +#define Z16F_ESPI_STAT_SLAS _HX8(01) /* Bit 0: Slave Select */ +#define Z16F_ESPI_STAT_TFST _HX8(02) /* Bit 1: Transfer Status */ +#define Z16F_ESPI_STAT_RDRF _HX8(04) /* Bit 2: Receive Data Register Full */ +#define Z16F_ESPI_STAT_ROVR _HX8(08) /* Bit 3: Receive Overrun */ +#define Z16F_ESPI_STAT_ABT _HX8(10) /* Bit 4: Slave mode transaction abort */ +#define Z16F_ESPI_STAT_COL _HX8(20) /* Bit 5: Collision */ +#define Z16F_ESPI_STAT_TUND _HX8(40) /* Bit 6: Transmit Underrun */ +#define Z16F_ESPI_STAT_TDRE _HX8(80) /* Bit 7: Transmit Data Register Empty */ + +#define Z16F_ESPI_STATE_SHIFT (0) /* Bits 0-5: ESPI State Machine */ +#define Z16F_ESPI_STATE_MASK (0x3f << Z16F_ESPI_STATE_SHIFT) +# define Z16F_ESPI_STATE_IDLE (0x00 << Z16F_ESPI_STATE_SHIFT) /* Idle */ +# define Z16F_ESPI_STATE_SWAIT (0x01 << Z16F_ESPI_STATE_SHIFT) /* Slave Wait For SCK */ +# define Z16F_ESPI_STATE_I2SSD0 (0x02 << Z16F_ESPI_STATE_SHIFT) /* I2S slave mode start delay */ +# define Z16F_ESPI_STATE_I2SSD1 (0x03 << Z16F_ESPI_STATE_SHIFT) /* I2S slave mode start delay */ +# define Z16F_ESPI_STATE_SPIMD (0x10 << Z16F_ESPI_STATE_SHIFT) /* SPI master mode start delay */ +# define Z16F_ESPI_STATE_I2SMD0 (0x31 << Z16F_ESPI_STATE_SHIFT) /* I2S master mode start delay */ +# define Z16F_ESPI_STATE_I2SMD1 (0x32 << Z16F_ESPI_STATE_SHIFT) /* I2S master mode start delay */ +# define Z16F_ESPI_STATE_B7RCV (0x2e << Z16F_ESPI_STATE_SHIFT) /* Bit 7 Receive */ +# define Z16F_ESPI_STATE_B7XMT (0x2f << Z16F_ESPI_STATE_SHIFT) /* Bit 7 Transmit */ +# define Z16F_ESPI_STATE_B6RCV (0x2c << Z16F_ESPI_STATE_SHIFT) /* Bit 6 Receive */ +# define Z16F_ESPI_STATE_B6XMT (0x2d << Z16F_ESPI_STATE_SHIFT) /* Bit 6 Transmit */ +# define Z16F_ESPI_STATE_B5RCV (0x2a << Z16F_ESPI_STATE_SHIFT) /* Bit 5 Receive */ +# define Z16F_ESPI_STATE_B5XMT (0x2b << Z16F_ESPI_STATE_SHIFT) /* Bit 5 Transmit */ +# define Z16F_ESPI_STATE_B4RCV (0x28 << Z16F_ESPI_STATE_SHIFT) /* Bit 4 Receive */ +# define Z16F_ESPI_STATE_B4XMT (0x29 << Z16F_ESPI_STATE_SHIFT) /* Bit 4 Transmit */ +# define Z16F_ESPI_STATE_B3RCV (0x26 << Z16F_ESPI_STATE_SHIFT) /* Bit 3 Receive */ +# define Z16F_ESPI_STATE_B3XMT (0x27 << Z16F_ESPI_STATE_SHIFT) /* Bit 3 Transmit */ +# define Z16F_ESPI_STATE_B2RCV (0x24 << Z16F_ESPI_STATE_SHIFT) /* Bit 2 Receive */ +# define Z16F_ESPI_STATE_B2XMT (0x25 << Z16F_ESPI_STATE_SHIFT) /* Bit 2 Transmit */ +# define Z16F_ESPI_STATE_B1RCV (0x22 << Z16F_ESPI_STATE_SHIFT) /* Bit 1 Receive */ +# define Z16F_ESPI_STATE_B1XMT (0x23 << Z16F_ESPI_STATE_SHIFT) /* Bit 1 Transmit */ +# define Z16F_ESPI_STATE_B0RCV (0x20 << Z16F_ESPI_STATE_SHIFT) /* Bit 0 Receive */ +# define Z16F_ESPI_STATE_B0XMT (0x21 << Z16F_ESPI_STATE_SHIFT) /* Bit 0 Transmit */ +#define Z16F_ESPI_STATE_SDI _HX8(40) /* Bit 6: Serial Data Input */ +#define Z16F_ESPI_STATE_SCKI _HX8(80) /* Bit 7: Serial Clock Input */ + +/* Timer0/1/2 registers *************************************************************/ + +#define Z16F_TIMER0_HL _HX32(ffffe300) /* 16-bit: Timer 0 */ +# define Z16F_TIMER0_H _HX32(ffffe300) /* 8-bit: Timer 0 High Byte */ +# define Z16F_TIMER0_L _HX32(ffffe301) /* 8-bit: Timer 0 Low Byte */ +#define Z16F_TIMER0_R _HX32(ffffe302) /* 16-bit: Timer 0 Reload */ +# define Z16F_TIMER0_RH _HX32(ffffe302) /* 8-bit: Timer 0 Reload High Byte */ +# define Z16F_TIMER0_RL _HX32(ffffe303) /* 8-bit: Timer 0 Reload Low Byte */ +#define Z16F_TIMER0_PWM _HX32(ffffe304) /* 16-bit: Timer 0 PWM */ +# define Z16F_TIMER0_PWMH _HX32(ffffe304) /* 8-bit: Timer 0 PWM High Byte */ +# define Z16F_TIMER0_PWML _HX32(ffffe305) /* 8-bit: Timer 0 PWM Low Byte */ +#define Z16F_TIMER0_CTL _HX32(ffffe306) /* 16-bit: Timer 0 Control */ +# define Z16F_TIMER0_CTL0 _HX32(ffffe306) /* 8-bit: Timer 0 Control 0 */ +# define Z16F_TIMER0_CTL1 _HX32(ffffe307) /* 8-bit: Timer 0 Control 1 */ + +#define Z16F_TIMER1_HL _HX32(ffffe310) /* 16-bit: Timer 1 */ +# define Z16F_TIMER1_H _HX32(ffffe310) /* 8-bit: Timer 1 High Byte */ +# define Z16F_TIMER1_L _HX32(ffffe311) /* 8-bit: Timer 1 Low Byte */ +#define Z16F_TIMER1_R _HX32(ffffe312) /* 16-bit: Timer 1 Reload */ +# define Z16F_TIMER1_RH _HX32(ffffe312) /* 8-bit: Timer 1 Reload High Byte */ +# define Z16F_TIMER1_RL _HX32(ffffe313) /* 8-bit: Timer 1 Reload Low Byte */ +#define Z16F_TIMER1_PWM _HX32(ffffe314) /* 16-bit: Timer 1 PWM */ +# define Z16F_TIMER1_PWMH _HX32(ffffe314) /* 8-bit: Timer 1 PWM High Byte */ +# define Z16F_TIMER1_PWML _HX32(ffffe315) /* 8-bit: Timer 1 PWM Low Byte */ +#define Z16F_TIMER1_CTL _HX32(ffffe316) /* 16-bit: Timer 1 Control */ +# define Z16F_TIMER1_CTL0 _HX32(ffffe316) /* 8-bit: Timer 1 Control 0 */ +# define Z16F_TIMER1_CTL1 _HX32(ffffe317) /* 8-bit: Timer 1 Control 1 */ + +#define Z16F_TIMER2_HL _HX32(ffffe320) /* 16-bit: Timer 2 */ +# define Z16F_TIMER2_H _HX32(ffffe320) /* 8-bit: Timer 2 High Byte */ +# define Z16F_TIMER2_L _HX32(ffffe321) /* 8-bit: Timer 2 Low Byte */ +#define Z16F_TIMER2_R _HX32(ffffe322) /* 16-bit: Timer 2 Reload */ +# define Z16F_TIMER2_RH _HX32(ffffe322) /* 8-bit: Timer 2 Reload High Byte */ +# define Z16F_TIMER2_RL _HX32(ffffe323) /* 8-bit: Timer 2 Reload Low Byte */ +#define Z16F_TIMER2_PWM _HX32(ffffe324) /* 16-bit: Timer 2 PWM */ +# define Z16F_TIMER2_PWMH _HX32(ffffe324) /* 8-bit: Timer 2 PWM High Byte */ +# define Z16F_TIMER2_PWML _HX32(ffffe325) /* 8-bit: Timer 2 PWM Low Byte */ +#define Z16F_TIMER2_CTL _HX32(ffffe326) /* 16-bit: Timer 2 Control */ +# define Z16F_TIMER2_CTL0 _HX32(ffffe326) /* 8-bit: Timer 2 Control 0 */ +# define Z16F_TIMER2_CTL1 _HX32(ffffe327) /* 8-bit: Timer 2 Control 1 */ + +/* Common timer0/1/2 register bit definitions ***************************************/ + +#define Z16F_TIMERCTL0_TMODE _HX8(80) /* Bit 7: Timer mode */ + /* Bits 5-6: Timer configuration, + * Interpretation depends on timer mode */ +#define Z16F_TIMERCTL0_RELOAD _HX8(00) /* Interrupt occurs on reload or capture */ +#define Z16F_TIMERCTL0_IDISABLED _HX8(40) /* Disabled */ +#define Z16F_TIMERCTL0_IINACTIVE _HX8(40) /* Interrupt occurs on inactive gate edge */ +#define Z16F_TIMERCTL0_ICAPTURE _HX8(40) /* Interrupt occurs on capture */ +#define Z16F_TIMERCTL0_IRELOAD _HX8(60) /* Interrupt occurs on reload */ +#define Z16F_TIMERCTL0_CASCADE _HX8(10) /* Bit 4: Timer is cascaded */ + /* Bits 1-2: PW mode */ +#define Z16F_TIMERCTL0_NODELAY _HZ8(00) /* No delay */ +#define Z16F_TIMERCTL0_DELAY2 _HZ8(01) /* 2 cycle delay */ +#define Z16F_TIMERCTL0_DELAY4 _HZ8(02) /* 4 cycle delay */ +#define Z16F_TIMERCTL0_DELAY8 _HZ8(03) /* 8 cycle delay */ +#define Z16F_TIMERCTL0_DELAY16 _HZ8(04) /* 16 cycle delay */ +#define Z16F_TIMERCTL0_DELAY32 _HZ8(05) /* 32 cycle delay */ +#define Z16F_TIMERCTL0_DELAY64 _HZ8(06) /* 64 cycle delay */ +#define Z16F_TIMERCTL0_DELAY128 _HZ8(07) /* 128 cycle delay */ + +#define Z16F_TIMERCTL1_TEN _HX8(80) /* Bit 7: Timer enable */ +#define Z16F_TIMERCTL1_TPOL _HX8(40) /* Bit 6: Input output polarity */ +#define Z16F_TIMERSCTL1_DIVMASK _HX8(38) /* Bits 3-5: Timer prescale value */ +# define Z16F_TIMERSCTL1_DIV1 _HX8(00) /* Divide by 1 */ +# define Z16F_TIMERSCTL1_DIV2 _HX8(08) /* Divide by 2 */ +# define Z16F_TIMERSCTL1_DIV4 _HX8(10) /* Divide by 4 */ +# define Z16F_TIMERSCTL1_DIV8 _HX8(18) /* Divide by 8 */ +# define Z16F_TIMERSCTL1_DIV16 _HX8(20) /* Divide by 16 */ +# define Z16F_TIMERSCTL1_DIV32 _HX8(28) /* Divide by 32 */ +# define Z16F_TIMERSCTL1_DIV64 _HX8(30) /* Divide by 64 */ +# define Z16F_TIMERSCTL1_DIV128 _HX8(38) /* Divide by 128 */ +#define Z16F_TIMERSCTL1_MODEMASK _HX8(07) /* Bits 0-2: Timer mode + CTL0 TMODE bit*/ +# define Z16F_TIMERSCTL1_ONESHOT _HX8(00) /* One shot mode (CTL0 TMOD = 0) */ +# define Z16F_TIMERSCTL1_PWMDO _HX8(00) /* One shot mode (CTL0 TMOD = 1) */ +# define Z16F_TIMERSCTL1_CONT _HX8(01) /* Continuous mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_CAPRST _HX8(01) /* Capture restart mode (CTL0 TMOD = 1)*/ +# define Z16F_TIMERSCTL1_COUNTER _HX8(02) /* Counter mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_CMPCNTR _HX8(02) /* Comparator counter mode (CTL0 TMOD = 1)*/ +# define Z16F_TIMERSCTL1_PWMSO _HX8(03) /* PWM single output mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_TRIGOS _HX8(03) /* Triggered one shot (CTL0 TMOD = 1)*/ +# define Z16F_TIMERSCTL1_CAPTURE _HX8(04) /* Capture mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_COMPARE _HX8(05) /* Compare mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_GATED _HX8(06) /* Gated mode (CTL0 TMOD = 0)*/ +# define Z16F_TIMERSCTL1_CAPCMP _HX8(07) /* Capture/Compare mode (CTL0 TMOD = 0)*/ + +/* Register access macros ***********************************************************/ + +#ifndef __ASSEMBLY__ +# define getreg8(a) (*(uint8_t volatile _Near*)(a)) +# define putreg8(v,a) (*(uint8_t volatile _Near*)(a) = (v)) +# define getreg16(a) (*(uint16_t volatile _Near*)(a)) +# define putreg16(v,a) (*(uint16_t volatile _Near*)(a) = (v)) +# define getreg32(a) (*(uint32_t volatile _Near*)(a)) +# define putreg32(v,a) (*(uint32_t volatile _Near*)(a) = (v)) +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* The following two routines are called from the low-level reset logic. z16f_lowinit() + * must be provided by the board-specific logic; z16f_lowuartinit() is called only if + * debugging support for up_lowputc (or getc) is enabled. + */ + +void z16f_lowinit(void); +#if defined(CONFIG_Z16_LOWPUTC) || defined(CONFIG_Z16_LOWGETC) +void z16f_lowuartinit(void); +#endif + +/* This function handles Z16F system exceptions */ + +void z16f_sysexec(FAR chipreg_t *regs); + +/* Entry point to reset the processor */ + +void z16f_reset(void); + +/* The following must be provided by board-specific logic that uses the ZNeo + * ESPI + */ + +#ifdef CONFIG_Z16F_ESPI + +struct spi_dev_s; /* Forward reference */ +enum spi_dev_e; /* Forward reference */ + +/* Initialize the selected SPI port */ + +FAR struct spi_dev_s *z16_spibus_initialize(int port); + +/* Select an SPI device (see include/nuttx/spi/spi.h) */ + +void z16f_espi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); + +/* Provide SPI device status (see include/nuttx/spi/spi.h) */ + +uint8_t z16f_espi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); + +/* Select CMD/DATA options (often used with LCD devices) */ + +#ifdef CONFIG_SPI_CMDDATA +int z16f_espi_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_Z16_SRC_Z16F_CHIP_H */ diff --git a/arch/z16/src/z16f/z16f_clkinit.c b/arch/z16/src/z16f/z16f_clkinit.c new file mode 100644 index 0000000000000000000000000000000000000000..15371646bc5e2d9060c0096bf5affef9465e751d --- /dev/null +++ b/arch/z16/src/z16f/z16f_clkinit.c @@ -0,0 +1,265 @@ +/**************************************************************************** + * z16f/z16f_clkinit.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based upon sample code included with the Zilog ZDS-II toolchain. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "chip/chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* System clock source value from ZDS target settings */ + +extern _Erom unsigned long SYS_CLK_SRC; +#define _DEFSRC ((unsigned long)&SYS_CLK_SRC) + +/* System clock frequency value from ZDS target settings */ + +extern _Erom unsigned long SYS_CLK_FREQ; +#define _DEFCLK ((unsigned long)&SYS_CLK_FREQ) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +/**************************************************************************** + * System clock initialization--DEBUG. Code Using Frequency Input from + * ZDS IDE. + * + * The sysclk_init function below uses the flexibility of the ZDS debug + * environment to allow the user to experiment with different clock frequency + * settings to help determine the frequency requirements of his Project. The + * function allows the selection of internal 5.56 MHz, the 10 KHz Watch Dog + * timer or an external clock Source. ZNEO supports clock frequency division + * with the Clock Division Register. The clock division Register will divide + * by (a minimum of) 2 or more. An assumed clock value of 5.5 MHz internal or + * an external clock of 20 MHz was used as the crystal frequency to match the + * Demo Target. The User can enter a new frequency in the OTHER clock dialog + * Target Setting. The clock frequency is passed with the variable _DEFFREQ + * and the clock source is _DEFSRC. + * + * NOTE: The UART output is designed to work with 5.56 MHz internal and 20 MHz + * External clock frequencies at the Default Baud rate of 57.6K Baud. + * Entering different clock frequencies may cause the UART to stop transmitting + * unless the user makes changes to the UART routines. + * + * Function Not Recommended for Release Code. + * + ****************************************************************************/ + +static void z16f_sysclkinit(int clockid, uint32_t frequency) +{ + int count; + int temp_oscdiv; + + /* _DEFSRC (SCKSEL Bits 1,0) is passed to program view the .linkcmd file */ + + if ((getreg8(Z16F_OSC_CTL) & 0x03) != clockid) + { + switch (clockid) + { + /* 0: Internal precision oscillator functions as system clock at 5.6 MHz */ + + case 0: + { + /* Enable 5.6 MHz clock RESET DEFAULT*/ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xa0, Z16F_OSC_CTL); + + /* Wait for oscillator to stabilize */ + + for (count = 0; count < 10000; count++); + + /* Select 5.6 MHz clock (SCKSEL=0) */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xa0, Z16F_OSC_CTL); + } + break; + + /* 1: Crystal oscillator or external clock driver functions as system clock */ + + case 1: + { + /* No divider for the oscillator */ + + putreg8(0x00, Z16F_OSC_DIV); + + /* Enable external oscillator */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xe0, Z16F_OSC_CTL); /* INTEN+XTLEN+WDTEN */ + + /* Wait for oscillator to stabilize */ + + for (count = 0; count < 10000; count++); + + /* select external oscillator (SCKSEL=2) */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xe0 | 1, Z16F_OSC_CTL); + } + break; + + /* 2: Reserved */ + + default: + case 2: + { + /* Reserved */ + } + break; + + /* Watchdog Timer oscillator functions as system clock. */ + + case 3: + { + /* Enable watchdog timer clock */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xb0, Z16F_OSC_CTL); + + /* Wait for oscillator to stabilize */ + + for (count = 0; count < 10000; count++); + + /* Select watch dog timer clock (SKCSEL=3) */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xb0 | 3, Z16F_OSC_CTL); + } + break; + } + } + + /* Check SysClock Frequency. + * divide the clock if the user has selected the OTHER option for frequency. + */ + + if (((clockid == 0) && (frequency < 3000000ul)) || + ((clockid == 1) && (frequency <= 10000000ul))) + { + if ( clockid == 0 ) + { + temp_oscdiv = (5526000ul / (frequency + 1)); + /* Example @ 32 KHz: 0xAC (172 decimal)*/ + } + else + { + temp_oscdiv = ((20000000ul / (frequency +1)) + 1); + } + + /* Unlock and Set the Oscillator Division Register (Z16F_OSC_DIV) */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(temp_oscdiv, Z16F_OSC_DIV); + } + + /* Wait for oscillator to stabilize */ + + for (count = 0; count < 10000; count++); +} + +#else /* CONFIG_DEBUG */ +/**************************************************************************** + * System Clock Initialization Recommended for Release Code + * + * The z16f_sysclkinit function below allows the user to switch from + * Internal to External Clock source and should be used for clock frequency + * switching to the External Clock. Note the delay to allow the clock to + * stabilize. + ****************************************************************************/ + +static void z16f_sysclkinit(int clockid, uint32_t frequency) +{ + int count; + + /* In this configuration, we support only the external oscillator/clock + * the the source of the system clock (__DEFCLK is ignored). + */ + + if ((getreg8(Z16F_OSC_CTL) & 0x03) != 1) + { + /* No divider for the oscillator */ + + putreg8(0x00, Z16F_OSC_DIV); + + /* Enable external oscillator */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xe0, Z16F_OSC_CTL); /* INTEN+XTLEN+WDTEN */ + + /* Wait for oscillator to stabilize */ + + for (count = 0; count < 10000; count++); + + /* Select external oscillator (SCLKSEL=1) */ + + putreg8(0xe7, Z16F_OSC_CTL); /* Unlock the crystal oscillator */ + putreg8(0x18, Z16F_OSC_CTL); + putreg8(0xe0 | 1, Z16F_OSC_CTL); /* Use the external osc/clock as system clock */ + } +} +#endif /* CONFIG_DEBUG */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z16f_clkinit + ****************************************************************************/ + +void z16f_clkinit(void) +{ + /* _DEFSRC (SCKSEL Bits 1,0) is passed to program view the .linkcmd file */ + + z16f_sysclkinit(_DEFSRC, _DEFCLK); +} diff --git a/arch/z16/src/z16f/z16f_espi.c b/arch/z16/src/z16f/z16f_espi.c new file mode 100644 index 0000000000000000000000000000000000000000..869cbb79cbbcf52434b9b0ad54585a4b92e809dd --- /dev/null +++ b/arch/z16/src/z16f/z16f_espi.c @@ -0,0 +1,885 @@ +/**************************************************************************** + * arch/z16/src/z16f/z16f_espi.c + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" + +#ifdef CONFIG_Z16F_ESPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug *******************************************************************/ +/* Check if SPI debug is enabled (non-standard.. no support in + * include/debug.h + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +# undef CONFIG_Z16F_ESPI_REGDEBUG +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg (void) +# endif +#else +# define spidbg (void) +# define spivdbg (void) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The overall state of one SPI controller */ + +struct z16f_spi_s +{ + struct spi_dev_s spi; /* Externally visible part of the SPI interface */ + bool initialized; /* TRUE: Controller has been initialized */ + uint8_t nbits; /* Width of word in bits (1-8) */ + uint8_t mode; /* Mode 0,1,2,3 */ + sem_t exclsem; /* Assures mutually exclusive access to SPI */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + + /* Debug stuff */ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG + bool wr; /* Last was a write */ + uint16_t regval; /* Last value */ + int ntimes; /* Number of times */ + uintptr_t regaddr; /* Last address */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG +static bool spi_checkreg(FAR struct z16f_spi_s *priv, bool wr, + uint16_t regval, uintptr_t regaddr); +static uint8_t spi_getreg8(FAR struct z16f_spi_s *priv, uintptr_t regaddr); +static void spi_putreg8(FAR struct z16f_spi_s *priv, uint8_t regval, + uintptr_t regaddr); +static void spi_putreg16(FAR struct z16f_spi_s *priv, uint16_t regval, + uintptr_t regaddr); +#else +# define spi_getreg8(priv,regaddr) getreg8(regaddr) +# define spi_putreg8(priv,regval,regaddr) putreg8(regval, regaddr) +# define spi_putreg16(priv,regval,regaddr) putreg16(regval, regaddr) +#endif + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(FAR struct z16f_spi_s *priv, const char *msg); +#else +# define spi_dumpregs(priv,msg) +#endif + +static void spi_flush(FAR struct z16f_spi_s *priv); + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* SEPI driver operations */ + +static const struct spi_ops_s g_epsiops = +{ + spi_lock, + z16f_espi_select, + spi_setfrequency, + spi_setmode, + spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + NULL, /* hwfeatures: Not supported */ +#endif + z16f_espi_status, +#ifdef CONFIG_SPI_CMDDATA + z16f_espi_cmddata, +#endif + spi_send, +#ifdef CONFIG_SPI_EXCHANGE + spi_exchange, +#else + spi_sndblock, + spi_recvblock, +#endif + NULL /* registercallback: Not implemented */ +}; + +/* ESPI driver state */ + +static struct z16f_spi_s g_espi; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_checkreg + * + * Description: + * Check if the current register access is a duplicate of the preceding. + * + * Input Parameters: + * wr - true:write false:read + * regval - The value to be written + * regaddr - The address of the register to write to + * + * Returned Value: + * true: This is the first register access of this type. + * flase: This is the same as the preceding register access. + * + ****************************************************************************/ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG +static bool spi_checkreg(FAR struct z16f_spi_s *priv, bool wr, uint16_t regval, + uintptr_t regaddr) +{ + if (wr == priv->wr && /* Same kind of access? */ + regval == priv->regval && /* Same value? */ + regaddr == priv->regaddr) /* Same address? */ + { + /* Yes, then just keep a count of the number of times we did this. */ + + priv->ntimes++; + return false; + } + else + { + /* Did we do the previous operation more than once? */ + + if (priv->ntimes > 0) + { + /* Yes... show how many times we did it */ + + lldbg("...[Repeats %d times]...\n", priv->ntimes); + } + + /* Save information about the new access */ + + priv->wr = wr; + priv->regval = regval; + priv->regaddr = regaddr; + priv->ntimes = 0; + } + + /* Return true if this is the first time that we have done this operation */ + + return true; +} +#endif + +/**************************************************************************** + * Name: spi_getreg8 + * + * Description: + * Read an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG +static uint8_t spi_getreg8(FAR struct z16f_spi_s *priv, uintptr_t regaddr) +{ + uint8_t regval = getreg8(regaddr); + + if (spi_checkreg(priv, false, (uint16_t)regval, regaddr)) + { + lldbg("%06x->%02x\n", regaddr, regval); + } + + return regval; +} +#endif + +/**************************************************************************** + * Name: spi_putreg8 + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG +static void spi_putreg8(FAR struct z16f_spi_s *priv, uint8_t regval, + uintptr_t regaddr) +{ + if (spi_checkreg(priv, true, (uint16_t)regval, regaddr)) + { + lldbg("%06x<-%02x\n", regaddr, regval); + } + + putreg8(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: spi_putreg16 + * + * Description: + * Write a value to an SPI register + * + ****************************************************************************/ + +#ifdef CONFIG_Z16F_ESPI_REGDEBUG +static void spi_putreg16(FAR struct z16f_spi_s *priv, uint16_t regval, + uintptr_t regaddr) +{ + if (spi_checkreg(priv, true, regval, regaddr)) + { + lldbg("%06x<-%04x\n", regaddr, regval); + } + + putreg8(regval, regaddr); +} +#endif + +/**************************************************************************** + * Name: spi_dumpregs + * + * Description: + * Dump the contents of all SPI registers + * + * Input Parameters: + * priv - The SPI controller to dump + * msg - Message to print before the register data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_SPI) && defined(CONFIG_DEBUG_VERBOSE) +static void spi_dumpregs(FAR struct z16f_spi_s *priv, FAR const char *msg) +{ + spivdbg("%s:\n", msg); + spivdbg(" DCR: %02x CTL: %02x MODE: %02x STAT: %02x\n", + getreg8(Z16F_ESPI_DCR), getreg8(Z16F_ESPI_CTL), + getreg8(Z16F_ESPI_MODE), getreg8(Z16F_ESPI_STAT)); + spivdbg(" STATE: %02x BR: %02x %02x\n", + getreg8(Z16F_ESPI_STATE), getreg8(Z16F_ESPI_BRH), + getreg8(Z16F_ESPI_BRL)); +} +#endif + +/**************************************************************************** + * Name: spi_flush + * + * Description: + * Make sure that there are now dangling SPI transfer in progress + * + * Input Parameters: + * priv - SPI controller state + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_flush(FAR struct z16f_spi_s *priv) +{ + /* Make sure the no transfer is in progress... waiting if necessary */ + + while ((spi_getreg8(priv, Z16F_ESPI_STAT) & Z16F_ESPI_STAT_TFST) != 0); + + /* Then make sure that there is no pending RX data .. reading as + * discarding as necessary. + */ + + while ((spi_getreg8(priv, Z16F_ESPI_STAT) & Z16F_ESPI_STAT_RDRF) != 0) + { + (void)spi_getreg8(priv, Z16F_ESPI_DATA); + } +} + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock SPI bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct z16f_spi_s *priv = (FAR struct z16f_spi_s *)dev; + + spivdbg("lock=%d\n", lock); + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct z16f_spi_s *priv = (FAR struct z16f_spi_s *)dev; + uint32_t actual; + uint32_t brg; + + spivdbg("frequency=%d\n", frequency); + + /* Check if the requested frequency is the same as the frequency selection */ + + if (priv->frequency == frequency) + { + /* We are already at this frequency. Return the actual. */ + + return priv->actual; + } + + /* Fbaud = Fsystem / (2 * BRG) + * BRG = Fsystem / (2 * Fbaud) + * + * Example, Fsystem = 18.432MHz, Fbaud = 9600 + * BRG = 960 + */ + + brg = (BOARD_SYSTEM_FREQUENCY >> 1) / frequency; + if (brg > 0xffff) + { + brg = 0xffff; + } + + /* Save the new BRG setting */ + + spi_putreg16(priv, (uint16_t)brg, Z16F_ESPI_BR); + + /* Calculate the new actual frequency */ + + actual = (BOARD_SYSTEM_FREQUENCY >> 1) / brg; + spivdbg("BR=%04x actual=%ld\n", (unsigned int)brg, (long)actual); + + /* Save the frequency setting */ + + priv->frequency = frequency; + priv->actual = actual; + + spidbg("Frequency %d->%d\n", frequency, actual); + return actual; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct z16f_spi_s *priv = (FAR struct z16f_spi_s *)dev; + uint8_t regval; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set the mode appropriately: + * + * SPI CPOL CPHA + * MODE + * 0 0 0 + * 1 0 1 + * 2 1 0 + * 3 1 1 + */ + + regval = spi_getreg8(priv, Z16F_ESPI_CTL); + regval &= ~(Z16F_ESPI_CTL_PHASE | Z16F_ESPI_CTL_CLKPOL); + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; NCPHA=1 */ + break; + + case SPIDEV_MODE1: /* CPOL=0; NCPHA=0 */ + regval |= Z16F_ESPI_CTL_PHASE; + break; + + case SPIDEV_MODE2: /* CPOL=1; NCPHA=1 */ + regval |= Z16F_ESPI_CTL_CLKPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1; NCPHA=0 */ + regval |= (Z16F_ESPI_CTL_PHASE | Z16F_ESPI_CTL_CLKPOL); + break; + + default: + DEBUGASSERT(false); + return; + } + + spi_putreg8(priv, regval, Z16F_ESPI_CTL); + spivdbg("ESPI CTL: %02x\n", regval); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct z16f_spi_s *priv = (FAR struct z16f_spi_s *)dev; + uint8_t regval; + + spivdbg("nbits=%d\n", nbits); + DEBUGASSERT(priv && nbits > 0 && nbits <= 8); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set number of bits appropriately */ + + regval = spi_getreg8(priv, Z16F_ESPI_MODE); + regval &= ~Z16F_ESPI_MODE_NUMBITS_MASK; + + /* The register value of zero is 8-bit */ + + if (nbits < 8) + { + regval |= ((uint8_t)nbits << Z16F_ESPI_MODE_NUMBITS_SHIFT); + } + + spi_putreg8(priv, regval, Z16F_ESPI_MODE); + spivdbg("ESPI MODE: %02x\n", regval); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + uint8_t txbyte; + uint8_t rxbyte; + + /* spi_exchange can do this. Note: right now, this only deals with 8-bit + * words. If the SPI interface were configured for words of other sizes, + * this would fail. + */ + + txbyte = (uint8_t)wd; + rxbyte = (uint8_t)0; + spi_exchange(dev, &txbyte, &rxbyte, 1); + + spivdbg("Sent %02x received %02x\n", txbyte, rxbyte); + return (uint16_t)rxbyte; +} + +/**************************************************************************** + * Name: spi_exchange + * + * Description: + * Exchange a block of data from SPI. + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct z16f_spi_s *priv = (struct z16f_spi_s *)dev; + uint8_t data; + FAR uint8_t *rxptr = rxbuffer; + FAR const uint8_t *txptr = txbuffer; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Make sure that any previous transfer is flushed from the hardware */ + + spi_flush(priv); + + /* Make sure the the TEOF bit is not set (SSV must also be zero) */ + + spi_putreg8(priv, 0, Z16F_ESPI_CTL); + + /* Loop, sending each word in the user-provided data buffer. + * + * Note 2: This loop might be made more efficient. Would logic + * like the following improve the throughput? Or would it + * just add the risk of overruns? + * + * Get byte 1; + * Send byte 1; Now word 1 is "in flight" + * nwords--; + * for ( ; byte > 0; byte--) + * { + * Get byte N. + * Wait for TDRE meaning that byte N-1 has moved to the shift + * register. + * Disable interrupts to keep the following atomic + * Send byte N. Now both work N-1 and N are "in flight" + * Wait for RDRF meaning that byte N-1 is available + * Read byte N-1. + * Re-enable interrupts. + * Save byte N-1. + * } + * Wait for RDRF meaning that the final byte is available + * Read the final byte. + * Save the final byte. + */ + + for ( ; nwords > 0; nwords--) + { + /* Get the data to send (0xff if there is no data source). */ + + if (txptr) + { + data = *txptr++; + } + else + { + data = 0xff; + } + + /* Do we need to set the TEOF bit in the CTL register too? */ + + if (nwords == 1) + { + spi_putreg8(priv, Z16F_ESPI_DCR_TEOF, Z16F_ESPI_CTL); + } + + /* Wait for any transmit data register to be empty. */ + + while ((spi_getreg8(priv, Z16F_ESPI_STAT) & Z16F_ESPI_STAT_TDRE) == 0); + + /* Write the data to transmitted to the Transmit Data Register (TDR) */ + + spi_putreg8(priv, data, Z16F_ESPI_DATA); + + /* Wait for the read data to be available in the data regsiter */ + + while ((spi_getreg8(priv, Z16F_ESPI_STAT) & Z16F_ESPI_STAT_RDRF) == 0); + + /* Read the received data from the SPI Data Register. */ + + data = spi_getreg8(priv, Z16F_ESPI_DATA); + if (rxptr) + { + *rxptr++ = (uint8_t)data; + } + } +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, buffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords) +{ + /* spi_exchange can do this. */ + + spi_exchange(dev, NULL, buffer, nwords); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z16_spibus_initialize + * + * Description: + * Initialize the selected SPI port + * + * Input Parameter: + * port - Identifies the "logical" SPI port. Must be zero in this case. + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *z16_spibus_initialize(int port) +{ + FAR struct z16f_spi_s *priv; + irqstate_t flags; + uint8_t regval; + + spivdbg("port: %d\n", port); + DEBUGASSERT(port == 0); + + /* Check if we have already initialized the ESPI */ + + priv = &g_espi; + if (priv->initialized) + { + /* Initialize the ESPI state structure */ + + flags = enter_critical_section(); + priv->spi.ops = &g_epsiops; + sem_init(&priv->exclsem, 0, 1); + + /* Set up the SPI pin configuration (board-specific logic is required to + * configure and manage all chip selects). + * + * SCK - PC3, Alternate function 1 + * MOSI - PC4, Alternate function 1 + * MISO - PC5, Alternate function 1 + */ + + regval = spi_getreg8(priv, Z16F_GPIOC_AFL); + regval |= 0x38; + spi_putreg8(priv, regval, Z16F_GPIOC_AFL); + + regval = spi_getreg8(priv, Z16F_GPIOC_AFH); + regval &= ~0x38; + spi_putreg8(priv, regval, Z16F_GPIOC_AFH); + + /* Initialize the ESPI peripheral. Master, Mode 0, 8-bits, 400KHz */ + + spi_putreg8(priv, 0x00, Z16F_ESPI_CTL); /* Disabled the ESPI */ + spi_putreg8(priv, 0x00, Z16F_ESPI_DCR); /* Disabled slave select; clear TEOF */ + + regval = Z16F_ESPI_MODE_SSIO | Z16F_ESPI_MODE_NUMBITS_8BITS | Z16F_ESPI_MODE_SSMD_SPI; + spi_putreg8(priv, regval, Z16F_ESPI_MODE); /* SPI mode, 8-bit */ + + regval = Z16F_ESPI_CTL_ESPIEN0 | Z16F_ESPI_CTL_MMEN | Z16F_ESPI_CTL_ESPIEN1; + spi_putreg8(priv, 0x00, Z16F_ESPI_CTL); /* TX/RX mode, Master mode */ + + /* Make sure that we are all in agreement about the configuration and set + * the BRG for 400KHz operation. + */ + + (void)spi_setfrequency(&priv->spi, 400000); + spi_setmode(&priv->spi, SPIDEV_MODE0); + spi_setbits(&priv->spi, 8); + + /* Now we are initialized */ + + priv->initialized = true; + leave_critical_section(flags); + } + + spi_dumpregs(priv, "After initialization"); + return &priv->spi; +} + +#endif /* CONFIG_Z16F_ESPI */ diff --git a/arch/z16/src/z16f/z16f_head.S b/arch/z16/src/z16f/z16f_head.S new file mode 100644 index 0000000000000000000000000000000000000000..1ceccf93330a86f85f18255437ec719cdb4b82bf --- /dev/null +++ b/arch/z16/src/z16f/z16f_head.S @@ -0,0 +1,489 @@ +/************************************************************************** + * arch/z16/src/z16f/z16f_head.S + * Z16F Reset Entry Point + * + * Copyright (C) 2008, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include +#include "common/up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * External References / External Definitions + **************************************************************************/ + + xref _z16f_clkinit:EROM + xref _z16f_lowinit:EROM +#ifdef CONFIG_ARCH_LEDS + xref _board_autoled_initialize:EROM +#endif +#if defined(USE_LOWUARTINIT) + xref _z16f_lowuartinit:EROM +#elif defined(USE_EARLYSERIALINIT) + xref _up_earlyserialinit:EROM +#endif + xref _os_start:EROM + xref _up_doirq:EROM + xref _z16f_sysexec:EROM + xdef _z16f_reset + + xref _low_nearbss:RAM + xref _len_nearbss + xref _low_farbss:ERAM + xref _len_farbss:ERAM + xref _low_neardata:RAM + xref _len_neardata + xref _low_near_romdata:EROM + xref _low_fardata:ERAM + xref _len_fardata:ERAM + xref _low_far_romdata:EROM + xref far_heapbot:ERAM + xref _far_stack:ERAM + xref _near_stack:RAM + +/************************************************************************** + * Flash Option Byte Setup + **************************************************************************/ + + define FOPTIONSEG, SPACE=ROM, ORG=0 + segment FOPTIONSEG + db BOARD_FLOPTION0 + db BOARD_FLOPTION1 + db BOARD_FLOPTION2 + db BOARD_FLOPTION3 + +/************************************************************************** + * vectors + **************************************************************************/ + + vector RESET=_z16f_reset + vector SYSEXC=_sysexc_isr + vector TIMER2=_timer2_isr + vector TIMER1=_timer1_isr + vector TIMER0=_timer0_isr + vector UART0_RX=_uart0rx_isr + vector UART0_TX=_uart0tx_isr + vector I2C=_i2c_isr + vector SPI=_spi_isr + vector ADC=_adc_isr + vector P7AD=_p7ad_isr + vector P6AD=_p6ad_isr + vector P5AD=_p5ad_isr + vector P4AD=_p4ad_isr + vector P3AD=_p3ad_isr + vector P2AD=_p2ad_isr + vector P1AD=_p1ad_isr + vector P0AD=_p0ad_isr + vector PWM_TIMER=_pwmtimer_isr + vector UART1_RX=_uart1rx_isr + vector UART1_TX=_uart1tx_isr + vector PWM_FAULT=_pwmfault_isr + vector C3=_c3_isr + vector C2=_c3_isr + vector C1=_c2_isr + vector C0=_c0_isr + +/************************************************************************** + * Equates + **************************************************************************/ + +/************************************************************************** + * Data Allocation + **************************************************************************/ + +/************************************************************************** + * Code + **************************************************************************/ + + define CODESEG, SPACE=EROM + segment CODESEG + +/************************************************************************** + * Name: _z16f_reset + * + * Description: + * Reset entry point + * + **************************************************************************/ + +_z16f_reset: + /* Initialize the init/idle task stack */ + + ld sp, #(_near_stack+1) /* Set Stack Pointer to the top of internal RAM */ + clr fp + + /* Initialize clocking */ + + call _z16f_clkinit + + /* Initialize onboard LEDs */ + +#ifdef CONFIG_ARCH_LEDS + call _board_autoled_initialize +#endif + /* Perform VERY early UART initialization so that we can use it here */ + +#ifdef USE_LOWUARTINIT + call _z16f_lowuartinit /* Initialize the UART for debugging */ +#endif + /* Initialize the hardware stack overflow register */ + +#ifdef CONFIG_Z16F_INITSPOV + ld r0, #(_near_stack_bot+1) + ld spov, r0 +#endif + /* Clear BSS */ + + lea r0, _low_nearbss + ld r1, #_len_nearbss+1 + jp _z16f_reset2 +_z16f_reset1: + ld.b (r0++), #0 +_z16f_reset2: + djnz r1, _z16f_reset1 + + lea r0, _low_farbss + ld r1, #_len_farbss+1 + jp _z16f_reset4 +_z16f_reset3: + ld.b (r0++), #0 +_z16f_reset4: + djnz r1, _z16f_reset3 + + /* Copy ROM data into RAM */ + + lea r0, _low_near_romdata + lea r1, _low_neardata + ld r2, #_len_neardata+1 + jp _z16f_reset6 +_z16f_reset5: + ld.b r3, (r0++) + ld.b (r1++), r3 +_z16f_reset6: + djnz r2, _z16f_reset5 + + lea r0, _low_far_romdata + lea r1, _low_fardata + ld r2, #_len_fardata+1 + jp _z16f_reset8 +_z16f_reset7: + ld.b r3, (r0++) + ld.b (r1++), r3 +_z16f_reset8: + djnz r2, _z16f_reset7 + + /* Perform low-level hardware initialization */ + + call _z16f_lowinit /* Perform low-level hardware initialization */ + +#ifdef USE_EARLYSERIALINIT + /* Perform early serial initialization */ + + call _up_earlyserialinit +#endif + /* Start NuttX */ + + call _os_start /* Start the operating system */ +_halt1: /* _os_start() should not return */ + halt + jp _halt1 + +/************************************************************************** + * Name: _sysexec_isr + * + * Description: + * System exception interrupt handler. On entry, the stack looks like + * this: + * + * TOS[0] = PC[31:24] + * TOS[1] = PC[23:16] + * TOS[2] = PC[15:8] + * TOS[3] = PC[7:0] + * TOS[4] = 0 + * TOS[5] = flags + * + **************************************************************************/ + +_sysexc_isr: + pushmlo /* Save r0-r7 on the stack */ + + /* Calculate the value of the SP BEFORE the interrupt occurred and + * push that as the saved value of r15=sp + */ + + ld r1, #-6 /* return(4) + flags(1) + padding(1) */ + add r1, sp /* r1 = Value of the SP before the interrupt */ + push r1 /* Push r1 in the spot for the saved SP */ + + /* Save all of the remaining registers */ + + pushmhi + + /* SP now holds the address of the beginning of the save structure + * on the stack. Now handle the system exception with arg1(r1)=address + * of the register save structure. + */ + + ld r1, sp + call _z16f_sysexec /* Handle in C logic */ + +_halt2: /* _z16f_sysexec() should not return */ + halt + jp _halt2 + +/************************************************************************** + * Name: Interrupt handlers + * + * Description: + * All interrupts will be vectored to the following locations. + * On entry, the stack contains the following: + * + * TOS[0] = PC[31:24] + * TOS[1] = PC[23:16] + * TOS[2] = PC[15:8] + * TOS[3] = PC[7:0] + * TOS[4] = 0 + * TOS[5] = flags + * + **************************************************************************/ + +_timer2_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_TIMER2 /* r1 = Timer 2 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_timer1_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_TIMER1 /* r1 = Timer 1 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_timer0_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_TIMER0 /* r1 = Timer 0 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_uart0rx_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_UART0RX /* r1 = UART0 RX IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_uart0tx_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_UART0TX /* r1 = UART0 TX IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_i2c_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_I2C /* r1 = I2C IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_spi_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_SPI /* r1 = SPI IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_adc_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_ADC /* r1 = ADC IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p7ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P7AD /* r1 = Port A/D7, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p6ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P6AD /* r1 = Port A/D6, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p5ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P5AD /* r1 = Port A/D5, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p4ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P4AD /* r1 = Port A/D4, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p3ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P3AD /* r1 = Port A/D3, rising/falling edgeEXEC IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p2ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P2AD /* r1 = Port A/D2, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p1ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P1AD /* r1 = Port A/D1, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_p0ad_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_P0AD /* r1 = Port A/D0, rising/falling edge IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_pwmtimer_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_PWMTIMER /* r1 = PWM Timer IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_uart1rx_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_UART1RX /* r1 = UART1 RX IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_uart1tx_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_UART1TX /* r1 = UART1 TX IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_pwmfault_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_PWMFAULT /* r1 = PWM Fault IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_c3_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_C3 /* r1 = Port C3, both edges DMA3 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_c2_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_C2 /* r1 = Port C2, both edges DMA2 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_c1_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_C1 /* r1 = Port C1, both edges DMA1 IRQ number */ + jp _common_isr /* Join common interrupt handling logic */ + +_c0_isr: + pushmlo /* Save r0-r7 on the stack */ + ld r1, #Z16F_IRQ_C0 /* r1 = Port C0, both edges DMA0 IRQ number */ + /* Join common interrupt handling logic */ + +/************************************************************************** + * Name: _common_isr + * + * Description: + * Common interrupt handling logic. + * + * On entry: + * + * r1 = IRQ number + * + * And the stack contains the following: + * + * TOS[ 0- 3] = r0 + * TOS[ 4- 7] = r1 + * TOS[ 8-11] = r2 + * TOS[12-15] = r3 + * TOS[16-19] = r4 + * TOS[20-23] = r5 + * TOS[24-27] = r6 + * TOS[28-31] = r7 + * TOS[32-35] = return PC + * TOS[36-37] = flags (with padding) + * + **************************************************************************/ + +_common_isr: + /* Calculate the value of the SP BEFORE the interrupt occurred and + * push that as the saved value of r15=sp + */ + + ld r2, #(9*4+2) /* See stack accounting above */ + add r2, sp /* r1 = Value of the SP before the interrupt */ + push r2 /* Push r1 in the spot for the saved SP */ + + /* Save all of the remaining registers */ + + pushmhi + + /* SP now holds the address of the beginning of the save structure + * on the stack. Now handle the interrupt with arg1(r1)=IRQ number and + * arg2(r2)=address of the register save structure. + */ + + ld r2, sp + call _up_doirq + + /* Upon return, _up_doirq will provide that address of the save structure + * to use to return from the interrupt in r0. This may or may not be the + * same value as sp. + */ + + cp r0, sp /* Check if we are performing a context switch */ + jp nz, _common_switch /* Jump if yes, else use faster return */ + popmhi /* Restore r8-r14 */ + add sp, #4 /* Skip over restore of r15=sp */ + popmlo /* Restore r0-r7 */ + iret + + /* We are not returning to the same thread that was interrupted. In this case, + * r0 is not in the stack but, instead, refers to a storage structure in the TCB + */ + +_common_switch: + ld sp, 2*REG_SP(r0) /* sp=Value of SP on return from interrupt */ + ld.w r1, 2*REG_FLAGS(r0) /* r1=padded flags value */ + push.w r1 /* Push padded flags value onto the stack */ + ld r1, 2*REG_PC(r0) /* r1=return address */ + push r1 /* Push the return address onto the stack */ + ld r7, 2*REG_R7(r0) /* Recover saved r7 */ + push r7 /* And save on the stack so that we can use r7 */ + ld r7, sp /* r7=saved sp */ + + ld sp, r0 /* sp=Pointer to register save structure */ + popmhi /* Restore r8-r14 */ + add sp, #4 /* Skip over restore of r15=sp */ + popmlo /* Restore r0-r6 */ + ld sp, r7 /* Switch back to the correct stack */ + pop r7 /* Recover r7 from the stack */ + iret /* Return from interrupt */ + + end diff --git a/arch/z16/src/z16f/z16f_irq.c b/arch/z16/src/z16f/z16f_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..bc2c6ba118ca0368139aee7a52596388e903e1f5 --- /dev/null +++ b/arch/z16/src/z16f/z16f_irq.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/z16/src/z16f/z16f_irq.c + * + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Clear and disable all interrupts. Set all to priority 0. */ + + putreg8(0xff, Z16F_IRQ0); + putreg8(0xff, Z16F_IRQ1); + putreg8(0xff, Z16F_IRQ2); + + putreg16(0x0000, Z16F_IRQ0_EN); + putreg16(0x0000, Z16F_IRQ1_EN); + putreg16(0x0000, Z16F_IRQ2_EN); + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + EI(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* System exceptions cannot be disabled */ + + if (irq >= Z16F_IRQ_IRQ0) + { + /* Disable the interrupt by clearing the corresponding bit in the + * appropriate IRQ enable high register. The enable low + * register is assumed to be zero, resulting interrupt disabled. + */ + + if (irq < Z16F_IRQ_IRQ1) + { + putreg8((getreg8(Z16F_IRQ0_ENH) & ~Z16F_IRQ0_BIT(irq)), Z16F_IRQ0_ENH); + } + else if (irq < Z16F_IRQ_IRQ2) + { + putreg8((getreg8(Z16F_IRQ1_ENH) & ~Z16F_IRQ1_BIT(irq)), Z16F_IRQ1_ENH); + } + else if (irq < NR_IRQS) + { + putreg8((getreg8(Z16F_IRQ2_ENH) & ~Z16F_IRQ2_BIT(irq)), Z16F_IRQ2_ENH); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* System exceptions cannot be disabled */ + + if (irq >= Z16F_IRQ_IRQ0) + { + /* Enable the interrupt by setting the corresponding bit in the + * appropriate IRQ enable register. The enable low + * register is assumed to be zero, resulting in "nomimal" interrupt + * priority. + */ + + if (irq < Z16F_IRQ_IRQ1) + { + putreg8((getreg8(Z16F_IRQ0_ENH) | Z16F_IRQ0_BIT(irq)), Z16F_IRQ0_ENH); + } + else if (irq < Z16F_IRQ_IRQ2) + { + putreg8((getreg8(Z16F_IRQ1_ENH) | Z16F_IRQ1_BIT(irq)), Z16F_IRQ1_ENH); + } + else if (irq < NR_IRQS) + { + putreg8((getreg8(Z16F_IRQ2_ENH) | Z16F_IRQ2_BIT(irq)), Z16F_IRQ2_ENH); + } + } +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + /* System exceptions cannot be disabled or acknowledged */ + + if (irq >= Z16F_IRQ_IRQ0) + { + /* Acknowledge the interrupt by setting the corresponding bit in the + * IRQ status register. + */ + + if (irq < Z16F_IRQ_IRQ1) + { + putreg8(Z16F_IRQ0_BIT(irq), Z16F_IRQ0); + } + else if (irq < Z16F_IRQ_IRQ2) + { + putreg8(Z16F_IRQ1_BIT(irq), Z16F_IRQ2); + } + else if (irq < NR_IRQS) + { + putreg8(Z16F_IRQ2_BIT(irq), Z16F_IRQ2); + } + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set interrupt priority + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + /* To be provided */ + + return -ENOSYS; +} +#endif diff --git a/arch/z16/src/z16f/z16f_lowuart.S b/arch/z16/src/z16f/z16f_lowuart.S new file mode 100644 index 0000000000000000000000000000000000000000..161d5ac9243c50a269ba738ff596bba69bae59cb --- /dev/null +++ b/arch/z16/src/z16f/z16f_lowuart.S @@ -0,0 +1,272 @@ +/************************************************************************* + * arch/z16/src/z16f/z16f_lowuart.asm + * Z16F UART management + * + * Copyright (C) 2008, 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSeqUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +/************************************************************************* + * Included Files + *************************************************************************/ + +#include +#include "chip/chip.h" +#include "common/up_internal.h" + +#ifdef USE_LOWUARTINIT + +/************************************************************************* + * Pre-processor Definitions + *************************************************************************/ + +#ifndef CONFIG_Z16F_UART0 +# undef CONFIG_UART0_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z16F_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +#endif + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE) +# define HAVE_Z16F_SERIAL_CONSOLE +#endif + +/************************************************************************* + * External References / External Definitions + *************************************************************************/ + + xdef _z16f_lowuartinit + xref _SYS_CLK_FREQ:EROM +#ifdef CONFIG_Z16_LOWPUTC + xdef _up_lowputc +#endif +#ifdef CONFIG_Z16_LOWGETC + xdef _up_lowgetc +#endif + +/************************************************************************* + * Data Allocation + *************************************************************************/ + + define CODESEG, SPACE=EROM + segment CODESEG + +/************************************************************************* + * Code + *************************************************************************/ + +/************************************************************************* + * Name: z16f_lowuartinit + * + * Description: + * Initialize UART0 or UART1 + * + * Input Parameters: + * None + * + *************************************************************************/ + +_z16f_lowuartinit: + +#ifdef HAVE_Z16F_SERIAL_CONSOLE + /* Calculate and set the baud rate generation register */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + ld r3, #CONFIG_UART1_BAUD /* r3 = Selected UART1 baud */ +#else + ld r3, #CONFIG_UART0_BAUD /* r3 = Selected UART0 (default) baud */ +#endif + ld r0, r3 /* r0 = baud */ + sll r0, #3 /* r0 = baud * 8 */ + add r0, #_SYS_CLK_FREQ /* r3 = freq + baud * 8 */ + sll r3, #4 /* r3 = baud * 16 */ + udiv r0, r3 /* BRG = (freq + baud * 8)/(baud * 16) */ + + /* Hacks to get a serial console available ASAP */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + ld.w Z16F_UART1_BR, r0 /* Z16F_UART1_BR = BRG */ + + /* Set the GPIO Alternate Function Register Lo (AFL) register */ + + ld r0, #%30 + or.b Z16F_GPIOD_AFL, r0 /* Z16F_GPIOD_AFL |= %30 */ + + /* Enable UART receive (REN) and transmit (TEN) */ + + clr.b Z16F_UART1_CTL1 /* Z16F_UART1_CTL1 = 0 */ + ld r0, #(Z16F_UARTCTL0_TEN|Z16F_UARTCTL0_REN) + ld.b Z16F_UART1_CTL0, r0 /* Z16F_UART1_CTL0 = %c0 */ + +#else + ld.w Z16F_UART0_BR, r0 /* Z16F_UART0_BR = BRG */ + + /* Set the GPIO Alternate Function Register Lo (AFL) register */ + + ld r0, #%30 + or.b Z16F_GPIOA_AFL, r0 /* Z16F_GPIOA_AFL |= %30 */ + + /* Enable UART receive (REN) and transmit (TEN) */ + + clr.b Z16F_UART0_CTL1 /* Z16F_UART0_CTL1 = 0 */ + ld r0, #(Z16F_UARTCTL0_TEN|Z16F_UARTCTL0_REN) + ld.b Z16F_UART0_CTL0, r0 /* Z16F_UART0_CTL0 = %c0 */ + +#endif +#endif /* HAVE_Z16F_SERIAL_CONSOLE */ + + ret /* Return */ + +#endif /* USE_LOWUARTINIT */ + +/************************************************************************* + * Name: _up_lowputc + * + * Description: + * Send one character to the selected serial console + * + * Input Parameters: + * r1 = character + * + * Returned Value: + * None + * + * Modifies r0 (and maybe r1) + * + *************************************************************************/ + +#ifdef CONFIG_Z16_LOWPUTC +_up_lowputc: + +#ifdef HAVE_Z16F_SERIAL_CONSOLE + /* Check if the character to output is a linefeed */ + + ext.ub r0, r1 /* r0=Character masked to 8-bits */ + cp r0, #10 /* Is it a linefeed ('\n') */ + jp ne, _z16f_xmitc /* No? Jump to _z16f_xmitc with character in r1 */ + + /* Output a carriage return before the linefeed */ + + ld r1, #13 /* Output carriage reuturn ('\r') */ + call _z16f_xmitc /* Call _z16f_xmitc with r1='\r' */ + ld r1, #10 /* Restore r1=linefeed to output */ + /* Fall through to _z16f_xmitc with linefeed in r1 */ +#endif /* HAVE_Z16F_SERIAL_CONSOLE */ + +/************************************************************************* + * Name: _z16f_xmitc + * + * Description: + * Send one character on the selected port (really a part of up_lowputc) + * + * Parameters: + * r1 = character + * + * Return: + * None + * + * Modifies r0 + * + *************************************************************************/ + +_z16f_xmitc: +_z16f_xmitc1: + +#ifdef HAVE_Z16F_SERIAL_CONSOLE + ld r0, Z16F_UARTSTAT0_TDRE /* TDRE=Transmitter Data Register Empty */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + tm.b Z16F_UART1_STAT0, r0 /* r0 = Z16F_UART1_STAT0 */ + jp eq, _z16f_xmitc1 /* While (!(Z16F_UART1_STAT0 & TDRE)) */ + ld.b Z16F_UART1_TXD, r1 /* Z16F_UART1_TXD = r1 (character) */ + +#else + tm.b Z16F_UART0_STAT0, r0 /* r0 = Z16F_UART0_STAT1 */ + jp eq, _z16f_xmitc1 /* While (!(Z16F_UART0_STAT0 & TDRE)) */ + ld.b Z16F_UART0_TXD, r1 /* Z16F_UART0_TXD = r1 (character) */ + +#endif +#endif /* HAVE_Z16F_SERIAL_CONSOLE */ + + ret /* Return */ + +#endif /* CONFIG_Z16_LOWPUTC */ + +/************************************************************************* + * Name: _up_lowgetc + * + * Description: + * Get a character from the serial port + * + * Parmeters: + * None + * + * Return + * R0 = Character read + * + *************************************************************************/ + +#ifdef CONFIG_Z16_LOWGETC +_up_lowgetc: +_up_lowgetc1: + +#ifdef HAVE_Z16F_SERIAL_CONSOLE + ld r0, #Z16F_UARTSTAT0_RDA /* RDA=Receive data available */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE + tm.b Z16F_UART1_STAT0, r0 + jp eq, _up_lowgetc1 /* While (!Z16F_UART1_STAT0 & RDA)) */ + ld.ub r0, Z16F_UART1_RXD /* r0 = Z16F_UART1_RXD */ + +#else + tm.b Z16F_UART0_STAT0,r0 /* While (!Z16F_UART0_STAT0 & RDA) */ + jp eq, _up_lowgetc1 + ld.ub r0, Z16F_UART0_RXD /* r0 = Z16F_UART0_RXD */ + +#endif + + cp r0, #%0d /* Test for '\r' */ + jp eq, _up_lowgetc2 + + cp r0, #%0d /* Test \r + high bit */ + jp ne, _up_lowgetc3 + +_up_lowgetc2: + ld r0, #%0a /* Convert '\r' to '\n' */ + +_up_lowgetc3: /* Return value in r0 */ +#endif /* HAVE_Z16F_SERIAL_CONSOLE */ + + ret /* Return */ +#endif + + end diff --git a/arch/z16/src/z16f/z16f_restoreusercontext.S b/arch/z16/src/z16f/z16f_restoreusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..796874fbaa0e5757b89a332db190dcd1859b7780 --- /dev/null +++ b/arch/z16/src/z16f/z16f_restoreusercontext.S @@ -0,0 +1,103 @@ +/************************************************************************* + * arch/z16/src/z16f/z16f_restoreusercontext.asm + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSeqUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +/************************************************************************* + * Included Files + *************************************************************************/ + +#include +#include +#include "chip/chip.h" + +/************************************************************************* + * External References / External Definitions + *************************************************************************/ + + xdef _up_restoreusercontext + +/************************************************************************* + * Data Allocation + *************************************************************************/ + + define CODESEG, SPACE=EROM + segment CODESEG + +/************************************************************************* + * Code + *************************************************************************/ + +/************************************************************************* + * Name: up_restoreusercontext + * + * Description: + * Restore the current user context. + * + * Parameters: + * r1: pointer to the register save array in the XCPT structure + * + *************************************************************************/ + +_up_restoreusercontext: + /* Disable interrupts while we are accessing the TCB's register + * save structure. The correct interrupt state will be retored by + * the iret instruction below + */ + + di + + /* Set up the stack for return from 'interrupt' */ + + ld sp, 2*REG_SP(r1) /* sp=Value of SP on return */ + ld.w r2, 2*REG_FLAGS(r1) /* r1=padded flags value */ + push.w r2 /* Push padded flags value onto the stack */ + ld r2, 2*REG_PC(r1) /* r2=return address */ + push r2 /* Push the return address onto the stack */ + ld r7, 2*REG_R7(r1) /* r7=saved value of r7 */ + push r7 /* Save this so that we can use r7 */ + ld r7, sp /* r7=saved SP value */ + + /* Restore registers and return from interrupt */ + + ld sp, r1 /* sp=Pointer to register save structure */ + popmhi /* Restore r8-r14 */ + add sp, #4 /* Skip over restore of r15=sp */ + popmlo /* Restore r0-r6 */ + ld sp, r7 /* Switch to the correct stack for return */ + pop r7 /* Recover the saved value of r7 from the stack */ + iret2 /* Return from interrupt */ + + end + + diff --git a/arch/z16/src/z16f/z16f_saveusercontext.S b/arch/z16/src/z16f/z16f_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..6b56c2a498dfca5c9e02247791194743c5b4b480 --- /dev/null +++ b/arch/z16/src/z16f/z16f_saveusercontext.S @@ -0,0 +1,119 @@ +/************************************************************************* + * arch/z16/src/z16f/z16f_saveusercontext.asm + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSeqUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +/************************************************************************* + * Included Files + *************************************************************************/ + +#include +#include +#include "chip/chip.h" + +/************************************************************************* + * External References / External Definitions + *************************************************************************/ + + xdef _up_saveusercontext + +/************************************************************************* + * Data Allocation + *************************************************************************/ + + define CODESEG, SPACE=EROM + segment CODESEG + +/************************************************************************* + * Code + *************************************************************************/ + +/************************************************************************* + * Name: up_saveusercontext + * + * Description: + * Save the current user context. + * r0-r7: These are caller saved registers and do not need to be stored + * here + * r8-r13: There callee saved registers must be preserved + * r14: Frame pointer + * r15: Stack pointer (with return address on stack) + * + * Parameters: + * r1: pointer to the register save array in the XCPT structure + * + *************************************************************************/ + +_up_saveusercontext: + /* Save the flags (needed to restore the interrupt state) */ + + ld.ub r3, Z16F_CNTRL_FLAGS /* Fetch the flags register (zero padded) */ + ld.w 2*REG_FLAGS(r1), r3 /* Save 16-bit value */ + + /* Save r8-R13 */ + + ld 2*REG_R8(r1), r8 /* Save r8 */ + ld 2*REG_R9(r1), r9 /* Save r9 */ + ld 2*REG_R10(r1), r10 /* Save r10 */ + ld 2*REG_R11(r1), r11 /* Save r11 */ + ld 2*REG_R12(r1), r12 /* Save r12 */ + ld 2*REG_R13(r1), r13 /* Save r13 */ + + /* Save the stack pointer and the frame pointer */ + + ld 2*REG_FP(r1), fp /* Save the frame pointer */ + ld r0, #4 /* 4 bytes of return address on stack */ + add r0, sp /* Value of stack pointer on return */ + ld 2*REG_SP(r1), r0 /* Save the stack pointer value on return */ + + /* Save the return address at the top of the stack */ + + ld r0, (sp) /* Save the return address */ + ld 2*REG_PC(r1), r0 + + /* Set the return value so that if when the task is restarted + * (via z16f_restoreusercontext() or via interrupt handling return), + * the returned value will be 1 + */ + + ld r0, #1 + ld 2*REG_R0(r1), r0 + + /* But always return 0 when returning from this function. The + * apparent return value tells the higher level logic whether the + * user context was saved or restored (in the spirit of setjmp and longjmp) + */ + + clr r0 /* Always returns 0 */ + ret + end diff --git a/arch/z16/src/z16f/z16f_serial.c b/arch/z16/src/z16f/z16f_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..dcbcff5ceffb955c4ca9f103263c88ef3e9773e7 --- /dev/null +++ b/arch/z16/src/z16f/z16f_serial.c @@ -0,0 +1,920 @@ +/**************************************************************************** + * arch/z16/src/z16f/z16f_serial.c + * + * Copyright (C) 2008-2009, 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* System clock frequency value from ZDS target settings */ + +extern _Erom unsigned long SYS_CLK_FREQ; +#define _DEFCLK ((unsigned long)&SYS_CLK_FREQ) + +#define STATE_DISABLED 0 +#define STATE_RXENABLED 1 +#define STATE_TXENABLED 2 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct z16f_uart_s +{ + uint32_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + bool rxenabled; /* RX interrupt enabled */ + bool txenabled; /* TX interrupt enabled */ + uint8_t rxirq; /* RX IRQ associated with this UART */ + uint8_t txirq; /* RX IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int z16f_setup(struct uart_dev_s *dev); +static void z16f_shutdown(struct uart_dev_s *dev); +static int z16f_attach(struct uart_dev_s *dev); +static void z16f_detach(struct uart_dev_s *dev); +static int z16f_rxinterrupt(int irq, void *context); +static int z16f_txinterrupt(int irq, void *context); +static int z16f_ioctl(struct file *filep, int cmd, unsigned long arg); +static int z16f_receive(struct uart_dev_s *dev, uint32_t *status); +static void z16f_rxint(struct uart_dev_s *dev, bool enable); +static bool z16f_rxavailable(struct uart_dev_s *dev); +static void z16f_send(struct uart_dev_s *dev, int ch); +static void z16f_txint(struct uart_dev_s *dev, bool enable); +static bool z16f_txready(struct uart_dev_s *dev); +static bool z16f_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + z16f_setup, /* setup */ + z16f_shutdown, /* shutdown */ + z16f_attach, /* attach */ + z16f_detach, /* detach */ + z16f_ioctl, /* ioctl */ + z16f_receive, /* receive */ + z16f_rxint, /* rxint */ + z16f_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif + z16f_send, /* send */ + z16f_txint, /* txint */ + z16f_txready, /* txready */ + z16f_txempty /* txempty */ +}; + +/* I/O buffers */ + +#ifdef CONFIG_Z16F_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif + +#ifdef CONFIG_Z16F_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +#ifdef CONFIG_Z16F_UART0 +/* This describes the state of the ZNEO uart0 port. */ + +static struct z16f_uart_s g_uart0priv = +{ + Z16F_UART0_BASE, /* uartbase */ + CONFIG_UART0_BAUD, /* baud */ + false, /* rxenabled */ + false, /* txenabled */ + Z16F_IRQ_UART0RX, /* rxirq */ + Z16F_IRQ_UART0TX, /* txirq */ + CONFIG_UART0_PARITY, /* parity */ + CONFIG_UART0_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart0port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART0_TXBUFSIZE, /* xmit.size */ + g_uart0txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART0_RXBUFSIZE, /* recv.size */ + g_uart0rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart0priv, /* priv */ +}; +#endif + +#ifdef CONFIG_Z16F_UART1 +/* This describes the state of the ZNEO uart1 port. */ + +static struct z16f_uart_s g_uart1priv = +{ + Z16F_UART1_BASE, /* uartbase */ + CONFIG_UART1_BAUD, /* baud */ + false, /* rxenabled */ + false, /* txenabled */ + Z16F_IRQ_UART1RX, /* rxirq */ + Z16F_IRQ_UART1TX, /* txirq */ + CONFIG_UART1_PARITY, /* parity */ + CONFIG_UART1_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart1port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART1_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART1_TXBUFSIZE, /* xmit.size */ + g_uart1txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART1_RXBUFSIZE, /* recv.size */ + g_uart1rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart1priv, /* priv */ +}; +#endif + +/* Now, which one with be tty0/console and which tty1? */ + +#ifndef CONFIG_Z16F_UART0 +# undef CONFIG_UART0_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z16F_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +#endif + +/* First pick the console and ttys0. This could be either of UART0-1 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_Z16F_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_Z16F_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be either of UART0-1 excluding the console UART. */ + +#if defined(CONFIG_Z16F_UART0) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_Z16F_UART1) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z16f_disableuartirq + ****************************************************************************/ + +static uint8_t z16f_disableuartirq(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + uint8_t state = priv->rxenabled ? STATE_RXENABLED : STATE_DISABLED | \ + priv->txenabled ? STATE_TXENABLED : STATE_DISABLED; + + z16f_txint(dev, false); + z16f_rxint(dev, false); + + leave_critical_section(flags); + return state; +} + +/**************************************************************************** + * Name: z16f_restoreuartirq + ****************************************************************************/ + +static void z16f_restoreuartirq(struct uart_dev_s *dev, uint8_t state) +{ + irqstate_t flags = enter_critical_section(); + + z16f_txint(dev, (state & STATE_TXENABLED) ? true : false); + z16f_rxint(dev, (state & STATE_RXENABLED) ? true : false); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z16f_consoleput + ****************************************************************************/ + +#ifdef CONSOLE_DEV +static void z16f_consoleput(uint8_t ch) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)CONSOLE_DEV.priv; + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if (z16f_txready(&CONSOLE_DEV)) + { + break; + } + } + + putreg8(ch, priv->uartbase + Z16F_UART_TXD); +} +#endif + +/**************************************************************************** + * Name: z16f_setup + * + * Description: + * Configure the UART baud, parity, etc. This method is called the first + * time that the serial port is opened. + * + ****************************************************************************/ + +static int z16f_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + uint32_t brg; + uint8_t ctl0; + uint8_t ctl1; + + /* Calculate and set the baud rate generation register. + * BRG = (freq + baud * 8)/(baud * 16) + */ + + brg = (_DEFCLK + (priv->baud << 3)) / (priv->baud << 4); + putreg16((uint16_t)brg, priv->uartbase + Z16F_UART_BR); + + /* Configure STOP bits */ + + ctl0 = 0; + ctl1 = 0; + + if (priv->stopbits2) + { + ctl0 |= Z16F_UARTCTL0_STOP; + } + + /* Configure parity */ + + if (priv->parity == 1) + { + ctl0 |= (Z16F_UARTCTL0_PEN|Z16F_UARTCTL0_PSEL); + } + else if (priv->parity == 2) + { + ctl0 |= Z16F_UARTCTL0_PEN; + } + + putreg8(ctl0, priv->uartbase + Z16F_UART_CTL0); + putreg8(ctl1, priv->uartbase + Z16F_UART_CTL1); + + /* Enable UART receive (REN) and transmit (TEN) */ + + ctl0 |= (Z16F_UARTCTL0_TEN|Z16F_UARTCTL0_REN); + putreg8(ctl0, priv->uartbase + Z16F_UART_CTL0); +#endif + + return OK; +} + +/**************************************************************************** + * Name: z16f_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void z16f_shutdown(struct uart_dev_s *dev) +{ + (void)z16f_disableuartirq(dev); +} + +/**************************************************************************** + * Name: z16f_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int z16f_attach(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + int ret; + + /* Attach the RX IRQ */ + + ret = irq_attach(priv->rxirq, z16f_rxinterrupt); + if (ret == OK) + { + /* Attach the TX IRQ */ + + ret = irq_attach(priv->txirq, z16f_txinterrupt); + if (ret != OK) + { + irq_detach(priv->rxirq); + } + } + + return ret; +} + +/**************************************************************************** + * Name: z16f_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void z16f_detach(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + + up_disable_irq(priv->rxirq); + up_disable_irq(priv->txirq); + + irq_detach(priv->rxirq); + irq_detach(priv->txirq); +} + +/**************************************************************************** + * Name: z16f_rxinterrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an RX + * event occurs at the Z16F's LIN-UART. + * + ****************************************************************************/ + +static int z16f_rxinterrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct z16f_uart_s *priv; + uint8_t status; + +#ifdef CONFIG_Z16F_UART1 + if (g_uart1priv.rxirq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_Z16F_UART0 + if (g_uart0priv.rxirq == irq) + { + dev = &g_uart0port; + } + else +#endif + { + PANIC(); + } + + priv = (struct z16f_uart_s*)dev->priv; + + /* Check the LIN-UART status 0 register to determine whether the source of + * the interrupt is error, break, or received data + */ + + status = getreg8(priv->uartbase + Z16F_UART_STAT0); + + /* REVISIT error and break handling */ + + /* Check if received data is available */ + + if (status & Z16F_UARTSTAT0_RDA) + { + /* Handle an incoming, received byte */ + + uart_recvchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: z16f_txinterrupt + * + * Description: + * This is the UART TX interrupt handler. This interrupt handler will + * be invoked when the X16F LIN UART transmit data register is empty. + * + ****************************************************************************/ + +static int z16f_txinterrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct z16f_uart_s *priv; + uint8_t status; + +#ifdef CONFIG_Z16F_UART1 + if (g_uart1priv.txirq == irq) + { + dev = &g_uart1port; + } + else +#endif +#ifdef CONFIG_Z16F_UART0 + if (g_uart0priv.txirq == irq) + { + dev = &g_uart0port; + } + else +#endif + { + PANIC(); + } + + priv = (struct z16f_uart_s*)dev->priv; + + /* Verify that the transmit data register is empty */ + + status = getreg8(priv->uartbase + Z16F_UART_STAT0); + if (status & Z16F_UARTSTAT0_TDRE) + { + /* Handle outgoing, transmit bytes */ + + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: z16f_ioctl + * + * Description: + * All ioctl that are not handled by the upper half serial driver will be + * routed through this method + * + ****************************************************************************/ + +static int z16f_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: z16f_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * return 'status'. + * + ****************************************************************************/ + +static int z16f_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + uint8_t rxd; + uint8_t stat0; + + rxd = getreg8(priv->uartbase + Z16F_UART_RXD); + stat0 = getreg8(priv->uartbase + Z16F_UART_STAT0); + *status = (uint32_t)rxd | (((uint32_t)stat0) << 8); + + return rxd; +} + +/**************************************************************************** + * Name: z16f_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void z16f_rxint(struct uart_dev_s *dev, bool enable) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->rxirq); +#endif + } + else + { + up_disable_irq(priv->rxirq); + } + + priv->rxenabled = enable; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z16f_rxavailable + * + * Description: + * Return true if the receive FIFO is not empty + * + ****************************************************************************/ + +static bool z16f_rxavailable(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + return ((getreg8(priv->uartbase + Z16F_UART_STAT0) & Z16F_UARTSTAT0_RDA) != 0); +} + +/**************************************************************************** + * Name: z16f_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void z16f_send(struct uart_dev_s *dev, int ch) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + putreg8(ch, priv->uartbase + Z16F_UART_TXD); +} + +/**************************************************************************** + * Name: z16f_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void z16f_txint(struct uart_dev_s *dev, bool enable) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->txirq); +#endif + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + } + else + { + up_disable_irq(priv->txirq); + } + + priv->txenabled = enable; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z16f_txready + * + * Description: + * Return true if the transmit FIFO is not full + * + ****************************************************************************/ + +static bool z16f_txready(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + return ((getreg8(priv->uartbase + Z16F_UART_STAT0) & Z16F_UARTSTAT0_TDRE) != 0); +} + +/**************************************************************************** + * Name: z16f_txempty + * + * Description: + * Return true if the transmit FIFO is empty + * + ****************************************************************************/ + +static bool z16f_txempty(struct uart_dev_s *dev) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv; + return ((getreg8(priv->uartbase + Z16F_UART_STAT0) & Z16F_UARTSTAT0_TXE) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before z16f_serialinit. + * + ****************************************************************************/ + +void up_earlyserialinit(void) +{ + uint8_t regval; + + /* Configure UART alternate pin functions. This may duplicate logic in + * z16f_lowuartinit() or z16f_lowinit(). + */ + +#ifdef CONFIG_Z16F_UART0 + /* UART0 is PA4 and PA5, alternate function 1 */ + + regval = getreg8(Z16F_GPIOA_AFL); + regval |= 0x30; + putreg8(regval, Z16F_GPIOA_AFL); + + regval = getreg8(Z16F_GPIOA_AFH); + regval &= ~0x30; + putreg8(regval, Z16F_GPIOA_AFH); +#endif + +#ifdef CONFIG_Z16F_UART1 + /* UART1 is PD4 and PD5, alternate function 1 */ + + regval = getreg8(Z16F_GPIOD_AFL); + regval |= 0x30; + putreg8(regval, Z16F_GPIOD_AFL); + + regval = getreg8(Z16F_GPIOD_AFH); + regval &= ~0x30; + putreg8(regval, Z16F_GPIOD_AFH); +#endif + + /* Disable UART interrupts */ + +#ifdef TTYS0_DEV + (void)z16f_disableuartirq(&TTYS0_DEV); +#endif + +#ifdef TTYS1_DEV + (void)z16f_disableuartirq(&TTYS1_DEV); +#endif + + /* Configuration any serial console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + z16f_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef CONSOLE_DEV +int up_putc(int ch) +{ + uint8_t state; + + /* Keep interrupts disabled so that we do not interfere with normal + * driver operation. + * + * REVISIT: I can imagine scenarios where the follow logic gets pre-empted + * and the the UART interrupts get left in a bad state. + */ + + state = z16f_disableuartirq(&CONSOLE_DEV); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR before LF */ + + z16f_consoleput('\r'); + } + + /* Output the character */ + + z16f_consoleput((uint8_t)ch); + + /* It is important to restore the TX interrupt while the send is pending. + * otherwise, TRDE interrupts can be lost since they do not pend after the + * TRDE false->true transition. + */ + + z16f_restoreuartirq(&CONSOLE_DEV, state); + return ch; +} +#endif + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE +# define z16f_contrde() \ + ((getreg8(Z16F_UART1_STAT0) & Z16F_UARTSTAT0_TDRE) != 0) +# define z16f_contxd(ch) \ + putreg8((uint8_t)(ch), Z16F_UART1_TXD) +#else +# define z16f_contrde() \ + ((getreg8(Z16F_UART0_STAT0) & Z16F_UARTSTAT0_TDRE) != 0) +# define z16f_contxd(ch) \ + putreg8((uint8_t)(ch), Z16F_UART0_TXD) +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z16f_putc + ****************************************************************************/ + +static void z16f_putc(int ch) +{ + int tmp; + for (tmp = 1000 ; tmp > 0 && !z16f_contrde(); tmp--); + z16f_contxd(ch); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Output CR before LF */ + + z16f_putc('\r'); + } + + /* Output character */ + + z16f_putc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/z16/src/z16f/z16f_sysexec.c b/arch/z16/src/z16f/z16f_sysexec.c new file mode 100644 index 0000000000000000000000000000000000000000..d7ac63175133bea4c3aee1226e409386b80c6f60 --- /dev/null +++ b/arch/z16/src/z16f/z16f_sysexec.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * z16f/z16f_sysexec.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "chip/chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: z16f_sysexec + * + * Description: + * Handle a Z16F system execption + * + ****************************************************************************/ + +void z16f_sysexec(FAR chipreg_t *regs) +{ + uint16_t excp; + + /* Save that register reference so that it can be used for built-in + * diagnostics. + */ + + g_current_regs = regs; + + /* The cause of the system exception is indicated in the SYSEXCPH&L + * registers + */ + + excp = getreg16(Z16F_SYSEXCP); + if ((excp & Z16F_SYSEXCP_SPOVF) != 0) + { + lowsyslog(LOG_ERR, "SP OVERFLOW\n"); + } + + if ((excp & Z16F_SYSEXCP_PCOVF) != 0) + { + lowsyslog(LOG_ERR, "PC OVERFLOW\n"); + } + + if ((excp & Z16F_SYSEXCP_DIV0) != 0) + { + lowsyslog(LOG_ERR, "Divide by zero\n"); + } + + if ((excp & Z16F_SYSEXCP_DIVOVF) != 0) + { + lowsyslog(LOG_ERR, "Divide overflow\n"); + } + + if ((excp & Z16F_SYSEXCP_ILL) != 0) + { + lowsyslog(LOG_ERR, "Illegal instruction\n"); + } + + if ((excp & Z16F_SYSEXCP_WDTOSC) != 0) + { + lowsyslog(LOG_ERR, "WDT oscillator failure\n"); + } + + if ((excp & Z16F_SYSEXCP_PRIOSC) != 0) + { + lowsyslog(LOG_ERR, "Primary Oscillator Failure\n"); + } + + if ((excp & Z16F_SYSEXCP_WDT) != 0) + { + lowsyslog(LOG_ERR, "Watchdog timeout\n"); + z16f_reset(); + } + + PANIC(); +} diff --git a/arch/z16/src/z16f/z16f_timerisr.c b/arch/z16/src/z16f/z16f_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..24b12a46953a2e49283c60c6374c39a7229c2952 --- /dev/null +++ b/arch/z16/src/z16f/z16f_timerisr.c @@ -0,0 +1,233 @@ +/**************************************************************************** + * z16f/z16f_timerisr.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* The desired timer interrupt frequency is provided by the definition + * CLOCKS_PER_SEC (see include/time.h). CLOCKS_PER_SEC defines the desired + * number of system clock ticks per second. That value is a user + * configurable setting that defaults to 100 (100 ticks per second = 10 MS + * interval). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +/* System clock frequency value from ZDS target settings */ + +extern _Erom uint8_t SYS_CLK_FREQ; +#define _DEFCLK ((uint32_t)&SYS_CLK_FREQ) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the system. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t reload; + uint32_t scaledfreq; + uint32_t rawdiv; + uint8_t divider; + uint8_t regval; + int shift; + + up_disable_irq(Z16F_IRQ_SYSTIMER); + + /* Disable the timer and configure for divide by 1 and continuous mode. */ + + regval = Z16F_TIMERSCTL1_DIV1 | Z16F_TIMERSCTL1_CONT; + putreg8(regval, Z16F_TIMER0_CTL1); + + /* Assign an initial timer value */ + + putreg16(0x0001, Z16F_TIMER0_HL); + + /* Calculate timer reload value (continuous mode) + * + * timer_period = reload_value * divisor / system_clock_freqency + * timer_frequency = system_clock_freqency / divisor / reload_value + * or + * reload_value = (system_clock_frequency / timer_frequency / divisor + * + * The prescale value ranges from 1 to 128, the reload value must be less + * then or equal to 0xffff. We would like to select the smallest prescaler + * value and the largest reload value for the greatest accuracy. + * + * Example: system_clock_frequency=20MHz, timer_frequency=100Hz: + * scaledfreq = 20,000,000 / 100 + * = 200,000 + * rawdiv = (200,000 >> 16) + 1 + * = 4 + * divider = Z16F_TIMERSCTL1_DIV4 + * shift = 2 + * reload = 200,000 >> 2 + * = 50,000 + * + * Example: system_clock_frequency=18.432MHz, timer_frequency=100Hz: + * scaledfreq = 20,000,000 / 100 + * = 200,000 + * divisor = ((18,432,000 / 100) >> 16) + 1 + * = 3 -> 4 (need to to up to next power of two) + * reload_value = 20,000,000 / 100 / 4 + * = 56,080 + */ + +#if 0 /* Does not work ??? */ + scaledfreq = _DEFCLK / CLOCKS_PER_SEC; +#else + scaledfreq = (BOARD_SYSTEM_FREQUENCY / CLOCKS_PER_SEC); +#endif + + rawdiv = (scaledfreq >> 16) + 1; + if (rawdiv < 2) + { + divider = Z16F_TIMERSCTL1_DIV1; + shift = 0; + } + else if (rawdiv < 3) + { + divider = Z16F_TIMERSCTL1_DIV2; + shift = 1; + } + else if (rawdiv < 7) + { + divider = Z16F_TIMERSCTL1_DIV4; + shift = 2; + } + else if (rawdiv < 15) + { + divider = Z16F_TIMERSCTL1_DIV8; + shift = 3; + } + else if (rawdiv < 31) + { + divider = Z16F_TIMERSCTL1_DIV16; + shift = 4; + } + else if (rawdiv < 63) + { + divider = Z16F_TIMERSCTL1_DIV32; + shift = 5; + } + else if (rawdiv < 127) + { + divider = Z16F_TIMERSCTL1_DIV64; + shift = 6; + } + else + { + divider = Z16F_TIMERSCTL1_DIV128; + shift = 7; + } + + reload = scaledfreq >> shift; + DEBUGASSERT(reload <= 0xffff); + + /* Set the timer reload value */ + + putreg16((uint16_t)reload, Z16F_TIMER0_R); + + /* Set the prescale value */ + + regval = getreg8(Z16F_TIMER0_CTL1); + regval &= ~Z16F_TIMERSCTL1_DIVMASK; + regval |= divider; + putreg8(regval, Z16F_TIMER0_CTL1); + + /* Enable the timer */ + + regval |= Z16F_TIMERCTL1_TEN; + putreg8(regval, Z16F_TIMER0_CTL1); + + /* Set the timer priority */ + + /* Attach and enable the timer interrupt (leaving at priority 0) */ + + irq_attach(Z16F_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(Z16F_IRQ_SYSTIMER); +} diff --git a/arch/z80/Kconfig b/arch/z80/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2aee96fcf70883ce77db1a87823ef4511dc024f6 --- /dev/null +++ b/arch/z80/Kconfig @@ -0,0 +1,435 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_Z80 +choice + prompt "ZiLOG 8-bit MCU" + default ARCH_CHIP_Z80 + +config ARCH_CHIP_Z80 + bool "Classic z80" + select ARCH_NOINTC + select MM_SMALL + ---help--- + Classic ZiLOG z80 chip + +config ARCH_CHIP_Z8018006VSG + bool "Z8018006VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 68-pin PLCC Z80180 + +config ARCH_CHIP_Z8018010VSG + bool "Z8018010VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 68-pin PLCC Z80180 + +config ARCH_CHIP_Z8018008VSG + bool "Z8018008VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 68-pin PLCC Z80180 + +config ARCH_CHIP_Z8018010FSG + bool "Z8018010FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 80-pin QFP (11 pins N/C) Z80180 + +config ARCH_CHIP_Z8018008VEG + bool "Z8018008VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 68-pin PLCC Z80180 + +config ARCH_CHIP_Z8018006VEG + bool "Z8018006VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 68-pin PLCC Z80180 + +config ARCH_CHIP_Z8018006PSG + bool "Z8018006PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 64-pin DIP 6 MHz 5V Z80180 + +config ARCH_CHIP_Z8018008FSG + bool "Z8018008FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 80-pin QFP (11 pins N/C) 8MHz 5V Z80180 + +config ARCH_CHIP_Z8018010PSG + bool "Z8018010PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 64-pin DIP 10MHz 5V Z80180 + +config ARCH_CHIP_Z8018006PEG + bool "Z8018006PEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 64-pin DIP 6MHz 5V Z80180 + +config ARCH_CHIP_Z8018010VEG + bool "Z8018010VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + 68-pin PLCC 10MHz 5V Z80180 + +config ARCH_CHIP_Z8018010PEG + bool "Z8018010PEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 64-pin DIP 10MHz 5V Z80180 + +config ARCH_CHIP_Z8018008PSG + bool "Z8018008PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 64-pin DIP 8MHz 5V Z80180 + +config ARCH_CHIP_Z8018006FSG + bool "Z8018006FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + ---help--- + Z180: 80-pin QFP (11 pins N/C) 6MHz 5V Z80180 + +config ARCH_CHIP_Z8018000XSO + bool "Z8018000XSO" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + +config ARCH_CHIP_Z8018010FEG + bool "Z8018010FEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + +config ARCH_CHIP_Z8018000WSO + bool "Z8018000WSO" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + +config ARCH_CHIP_Z8018008PEG + bool "Z8018008PEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80180 + +config ARCH_CHIP_Z8018110FEG + bool "Z8018110FEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80181 + ---help--- + Z180: 100-pin QFP Z80181 + +config ARCH_CHIP_Z8018233FSG + bool "Z8018233FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80182 + ---help--- + 100-pin QFP Z80182 + +config ARCH_CHIP_Z8018220AEG + bool "Z8018220AEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80182 + ---help--- + Z180: 100-pin LQFP 20MHz 5V Z80182 + +config ARCH_CHIP_Z8018216FSG + bool "Z8018216FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80182 + ---help--- + Z180: 100-pin QFP 16MHz 5V Z80182 + +config ARCH_CHIP_Z8018216ASG + bool "Z8018216ASG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80182 + ---help--- + Z180: 100-pin LQFP Z80182 + +config ARCH_CHIP_Z8018233ASG + bool "Z8018233ASG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80182 + ---help--- + Z180: 100-pin LQFP 33MHz 5V Z80182 + +config ARCH_CHIP_Z8019520FSG + bool "Z8019520FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80195 + ---help--- + Z180: 100-pin QFP 20MHz 5V Z80195 + +config ARCH_CHIP_Z8019533FSG + bool "Z8019533FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z80195 + ---help--- + Z180: 100-pin QFP 33MHz 5V Z80195 + +config ARCH_CHIP_Z8L18020VSG + bool "Z8L18020VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L180 + ---help--- + Z180: 68-pinn PLCC Z8L180 + +config ARCH_CHIP_Z8L18020FSG + bool "Z8L18020FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L180 + ---help--- + Z180: 80-pin GFP 20MHz 3.3V Z8L180 + +config ARCH_CHIP_Z8L18020PSG + bool "Z8L18020PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L180 + +config ARCH_CHIP_Z8L18220ASG + bool "Z8L18220ASG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L182 + ---help--- + Z180: 100-pin LQFP Z8L182 + +config ARCH_CHIP_Z8L18220FSG + bool "Z8L18220FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L182 + ---help--- + 100-pin QFP 20MHz 3.3V Z8L182 + +config ARCH_CHIP_Z8L18220AEG + bool "Z8L18220AEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8L182 + +config ARCH_CHIP_Z8S18020VSG + bool "Z8S18020VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18020VSG1960 + bool "Z8S18020VSG1960" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18033VSG + bool "Z8S18033VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18010FSG + bool "Z8S18010FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + 80-pin QFP Z8S180 + +config ARCH_CHIP_Z8S18010VEG + bool "Z8S18010VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18020VEG + bool "Z8S18020VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18010VSG + bool "Z8S18010VSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC Z8S180 + +config ARCH_CHIP_Z8S18020PSG + bool "Z8S18020PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + 64-pin DIP 10Mhz 5V Z8S180 + +config ARCH_CHIP_Z8S18033FSG + bool "Z8S18033FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 80-pin QFP 33MHz 5V Z8S180 + +config ARCH_CHIP_Z8S18033FEG + bool "Z8S18033FEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 80-pin QFP 33MHz 5V Z8S180 + +config ARCH_CHIP_Z8S18020FSG + bool "Z8S18020FSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 80-pin QFP 20MHz 5V Z8S180 + +config ARCH_CHIP_Z8S18033VEG + bool "Z8S18033VEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 68-pin PLCC 33MHz 5V Z8S180 + +config ARCH_CHIP_Z8S18010PSG + bool "Z8S18010PSG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + ---help--- + Z180: 64-pin DIP 10MHz 5V Z8S180 + +config ARCH_CHIP_Z8S18020FEG + bool "Z8S18020FEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + +config ARCH_CHIP_Z8S18010PEG + bool "Z8S18010PEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + +config ARCH_CHIP_Z8S18010FEG + bool "Z8S18010FEG" + select ARCH_CHIP_Z180 + select ARCH_CHIP_Z8S180 + +config ARCH_CHIP_Z8F6403 + bool "Z8F6403" + select ARCH_CHIP_Z8 + select ARCH_CHIP_Z8F640X + select ENDIAN_BIG + select HAVE_LOWSERIALINIT + ---help--- + ZiLOG Z8F6403 (z8 Encore) + +config ARCH_CHIP_Z8F6423 + bool "Z8F6423" + select ARCH_CHIP_Z8 + select ARCH_CHIP_Z8F642X + select ENDIAN_BIG + select HAVE_LOWSERIALINIT + ---help--- + ZiLOG Z8F6423 (z8 Encore) + +config ARCH_CHIP_EZ80F91 + bool "EZ80F91" + select ARCH_CHIP_EZ80 + ---help--- + ZiLOG EZ80F91 (ez80 Acclaim) + +config ARCH_CHIP_EZ80F92 + bool "EZ80F92" + select ARCH_CHIP_EZ80 + ---help--- + ZiLOG EZ80F92 (ez80 Acclaim) + +config ARCH_CHIP_EZ80F93 + bool "EZ80F93" + select ARCH_CHIP_EZ80 + ---help--- + ZiLOG EZ80F93 (ez80 Acclaim) + +endchoice + +config ARCH_CHIP_Z8F642X + bool + +config ARCH_CHIP_Z8F640X + bool + +config ARCH_CHIP_Z180 + bool + select MM_SMALL + select ARCH_NOINTC + select ARCH_HAVE_ADDRENV + select ARCH_ADDRENV + select HAVE_LOWSERIALINIT + +config ARCH_CHIP_Z80180 + bool + +config ARCH_CHIP_Z80181 + bool + +config ARCH_CHIP_Z80182 + bool + +config ARCH_CHIP_Z80195 + bool + +config ARCH_CHIP_Z8L180 + bool + +config ARCH_CHIP_Z8L182 + bool + +config ARCH_CHIP_Z8S180 + bool + +config ARCH_CHIP_Z8 + bool + select MM_SMALL + +config ARCH_CHIP_EZ80 + bool + select MM_SMALL if EZ80_Z80MODE + select HAVE_LOWSERIALINIT + select ARCH_HAVE_PHY + +config HAVE_LOWSERIALINIT + bool + +config ARCH_CHIP + string + default "z80" if ARCH_CHIP_Z80 + default "z180" if ARCH_CHIP_Z180 + default "z8" if ARCH_CHIP_Z8 + default "ez80" if ARCH_CHIP_EZ80 + +source "arch/z80/src/common/Kconfig" +source "arch/z80/src/z80/Kconfig" +source "arch/z80/src/z180/Kconfig" +source "arch/z80/src/z8/Kconfig" +source "arch/z80/src/ez80/Kconfig" + +endif diff --git a/arch/z80/include/.gitignore b/arch/z80/include/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6460c4a67846d5801c3600ce961277e3644f647 --- /dev/null +++ b/arch/z80/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/z80/include/arch.h b/arch/z80/include/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..123ea4bada34bc513e90ba5c3cf5b743593879a7 --- /dev/null +++ b/arch/z80/include/arch.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arch.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/arch.h + */ + +#ifndef __ARCH_Z80_INCLUDE_ARCH_H +#define __ARCH_Z80_INCLUDE_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_ARCH_H */ + diff --git a/arch/z80/include/ez80/arch.h b/arch/z80/include/ez80/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..f210332399c31ba1323a3baa77c1b9a24a48c574 --- /dev/null +++ b/arch/z80/include/ez80/arch.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/ez80/arch.h + * arch/chip/arch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h (via arch/arch.h) + */ + +#ifndef __ARCH_EZ80_ARCH_H +#define __ARCH_EZ80_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_EZ80_ARCH_H */ + diff --git a/arch/z80/include/ez80/io.h b/arch/z80/include/ez80/io.h new file mode 100644 index 0000000000000000000000000000000000000000..2ae92c8ba5f62e02bd155fdef90568fefe219c99 --- /dev/null +++ b/arch/z80/include/ez80/io.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/z80/include/ez80/io.h + * arch/chip/io.h + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through arch/io.h + */ + +#ifndef __ARCH_EZ80_IO_H +#define __ARCH_EZ80_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void outp(uint16_t p, uint8_t c); +uint8_t inp(uint16_t p); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_EZ80_IO_H */ diff --git a/arch/z80/include/ez80/irq.h b/arch/z80/include/ez80/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..33b00783effbd7ee0d3ee1b1e93217b76d9243d5 --- /dev/null +++ b/arch/z80/include/ez80/irq.h @@ -0,0 +1,272 @@ +/**************************************************************************** + * arch/ez80/include/ez80/irq.h + * arch/chip/irq.h + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h (via arch/irq.h) + */ + +#ifndef __ARCH_Z80_INCLUDE_EZ80_IRQ_H +#define __ARCH_Z80_INCLUDE_EZ80_IRQ_H + +#ifndef _EZ80F91 +# error "Only the EZ80F91 is currently supported" +#endif + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ez80 Interrupt Numbers ***************************************************/ + +#define EZ80_EMACRX_IRQ (0) /* Vector 0x40 */ +#define EZ80_EMACTX_IRQ (1) /* Vector 0x44 */ +#define EZ80_EMACSYS_IRQ (2) /* Vector 0x48 */ +#define EZ80_PLL_IRQ (3) /* Vector 0x4c */ +#define EZ80_FLASH_IRQ (4) /* Vector 0x50 */ + +#define EZ80_TIMER0_IRQ (5) /* Vector 0x54 */ +#define EZ80_TIMER1_IRQ (6) /* Vector 0x58 */ +#define EZ80_TIMER2_IRQ (7) /* Vector 0x5c */ +#define EZ80_TIMER3_IRQ (8) /* Vector 0x60 */ + +#define EZ80_RTC_IRQ (9) /* Vector 0x6C */ +#define EZ80_UART0_IRQ (10) /* Vector 0x70 */ +#define EZ80_UART1_IRQ (11) /* Vector 0x74 */ + +#define EZ80_I2C_IRQ (12) /* Vector 0x78 */ +#define EZ80_SPI_IRQ (13) /* Vector 0x7c */ + +#define EZ80_PORTA0_IRQ (14) /* Vector 0x80 */ +#define EZ80_PORTA1_IRQ (15) /* Vector 0x84 */ +#define EZ80_PORTA2_IRQ (16) /* Vector 0x88 */ +#define EZ80_PORTA3_IRQ (17) /* Vector 0x8c */ +#define EZ80_PORTA4_IRQ (18) /* Vector 0x90 */ +#define EZ80_PORTA5_IRQ (19) /* Vector 0x94 */ +#define EZ80_PORTA6_IRQ (20) /* Vector 0x98 */ +#define EZ80_PORTA7_IRQ (21) /* Vector 0x9c */ + +#define EZ80_PORTB0_IRQ (22) /* Vector 0xa0 */ +#define EZ80_PORTB1_IRQ (23) /* Vector 0xa4 */ +#define EZ80_PORTB2_IRQ (24) /* Vector 0xa8 */ +#define EZ80_PORTB3_IRQ (25) /* Vector 0xac */ +#define EZ80_PORTB4_IRQ (26) /* Vector 0xb0 */ +#define EZ80_PORTB5_IRQ (27) /* Vector 0xb4 */ +#define EZ80_PORTB6_IRQ (28) /* Vector 0xb8 */ +#define EZ80_PORTB7_IRQ (29) /* Vector 0xbc */ + +#define EZ80_PORTC0_IRQ (30) /* Vector 0xc0 */ +#define EZ80_PORTC1_IRQ (31) /* Vector 0xc4 */ +#define EZ80_PORTC2_IRQ (32) /* Vector 0xc8 */ +#define EZ80_PORTC3_IRQ (33) /* Vector 0xcc */ +#define EZ80_PORTC4_IRQ (34) /* Vector 0xd0 */ +#define EZ80_PORTC5_IRQ (35) /* Vector 0xd4 */ +#define EZ80_PORTC6_IRQ (36) /* Vector 0xd8 */ +#define EZ80_PORTC7_IRQ (37) /* Vector 0xdc */ + +#define EZ80_PORTD0_IRQ (38) /* Vector 0xe0 */ +#define EZ80_PORTD1_IRQ (39) /* Vector 0xe4 */ +#define EZ80_PORTD2_IRQ (40) /* Vector 0xe8 */ +#define EZ80_PORTD3_IRQ (41) /* Vector 0xec */ +#define EZ80_PORTD4_IRQ (42) /* Vector 0xf0 */ +#define EZ80_PORTD5_IRQ (43) /* Vector 0xf4 */ +#define EZ80_PORTD6_IRQ (44) /* Vector 0xf8 */ +#define EZ80_PORTD7_IRQ (45) /* Vector 0xfc */ + +#define NR_IRQS (46) +#define EZ80_IRQ_SYSTIMER EZ80_TIMER0_IRQ + +/* IRQ Management Macros ****************************************************/ + +/* IRQ State Save Format **************************************************** + * + * These indices describe how the ez8 context is save in the state save array + * + * Byte offsets: + */ + +/* IRQ Stack Frame Format + * + * This stack frame is created on each interrupt. These registers are stored + * in the TCB to many context switches. + */ + +/* chipreg_t indices */ + +#define XCPT_I (0) /* Index 0: 16-bit interrupt vector register */ +#define XCPT_BC (1) /* Index 1: Saved 16-bit BC register */ +#define XCPT_DE (2) /* Index 2: Saved 16-bit DE register */ +#define XCPT_IX (3) /* Index 3: Saved 16-bit IX register */ +#define XCPT_IY (4) /* Index 4: Saved 16-bit IY register */ +#define XCPT_SP (5) /* Index 5: Saved 16-bit SP at time of interrupt */ +#define XCPT_HL (6) /* Index 6: Saved 16-bit HL register */ +#define XCPT_AF (7) /* Index 7: Saved 16-bit AF register */ +#define XCPT_PC (8) /* Index 8: Offset to 16-bit PC at time of interrupt */ +#define XCPTCONTEXT_REGS (9) + +#ifdef CONFIG_EZ80_Z80MODE +/* Byte offsets */ + +# define XCPT_I_OFFSET (2*XCPT_I) /* Offset 0: 16-bit interrupt vector register */ +# define XCPT_IF_OFFSET (2*XCPT_I+0) /* Offset 1: Saved flags. P set if interrupts enabled */ +# define XCPT_IA_OFFSET (2*XCPT_I+1) /* Offset 2: Saved lower 8-bits of interrupt vector register */ +# define XCPT_BC_OFFSET (2*XCPT_BC) /* Offset 2: Saved 16-bit BC register */ +# define XCPT_C_OFFSET (2*XCPT_BC+0) /* Offset 2: Saved 8-bit C register */ +# define XCPT_B_OFFSET (2*XCPT_BC+1) /* Offset 3: Saved 8-bit D register */ +# define XCPT_DE_OFFSET (2*XCPT_DE) /* Offset 4: Saved 16-bit DE register */ +# define XCPT_E_OFFSET (2*XCPT_DE+0) /* Offset 4: Saved 8-bit E register */ +# define XCPT_D_OFFSET (2*XCPT_DE+1) /* Offset 5: Saved 8-bit D register */ +# define XCPT_IX_OFFSET (2*XCPT_IX) /* Offset 6: Saved 16-bit IX register */ +# define XCPT_IY_OFFSET (2*XCPT_IY) /* Offset 8: Saved 16-bit IY register */ +# define XCPT_SP_OFFSET (2*XCPT_SP) /* Offset 10: Saved 16-bit SP at time of interrupt */ +# define XCPT_HL_OFFSET (2*XCPT_HL) /* Offset 12: Saved 16-bit HL register */ +# define XCPT_L_OFFSET (2*XCPT_HL+0) /* Offset 12: Saved 8-bit L register */ +# define XCPT_H_OFFSET (2*XCPT_HL+1) /* Offset 13: Saved 8-bit H register */ +# define XCPT_AF_OFFSET (2*XCPT_AF) /* Offset 14: Saved 16-bit AF register */ +# define XCPT_F_OFFSET (2*XCPT_AF+0) /* Offset 14: Saved flags */ +# define XCPT_A_OFFSET (2*XCPT_AF+1) /* Offset 15: Saved 8-bit A register */ +# define XCPT_PC_OFFSET (2*XCPT_PC) /* Offset 16: Offset to 16-bit PC at time of interrupt */ +# define XCPTCONTEXT_SIZE (2*XCPTCONTEXT_REGS) +#else +/* Byte offsets */ + +# define XCPT_I_OFFSET (3*XCPT_I) /* Offset 0: Saved 24-bit interrupt vector register */ +# define XCPT_IF_OFFSET (2*XCPT_I+1) /* Offset 1: Saved flags. P set if interrupts enabled */ +# define XCPT_IA_OFFSET (2*XCPT_I+2) /* Offset 2: Saved lower 8-bits of interrupt vector register */ +# define XCPT_BC_OFFSET (3*XCPT_BC) /* Offset 3: Saved 24-bit BC register */ +# define XCPT_C_OFFSET (3*XCPT_BC+1) /* Offset 4: Saved 8-bit C register */ +# define XCPT_B_OFFSET (3*XCPT_BC+2) /* Offset 5: Saved 8-bit D register */ +# define XCPT_DE_OFFSET (3*XCPT_DE) /* Offset 6: Saved 24-bit DE register */ +# define XCPT_E_OFFSET (3*XCPT_DE+1) /* Offset 7: Saved 8-bit E register */ +# define XCPT_D_OFFSET (3*XCPT_DE+2) /* Offset 8: Saved 8-bit D register */ +# define XCPT_IX_OFFSET (3*XCPT_IX) /* Offset 9: Saved 24-bit IX register */ +# define XCPT_IY_OFFSET (3*XCPT_IY) /* Offset 12: Saved 24-bit IY register */ +# define XCPT_SP_OFFSET (3*XCPT_SP) /* Offset 15: Saved 24-bit SP at time of interrupt */ +# define XCPT_HL_OFFSET (3*XCPT_HL) /* Offset 18: Saved 24-bit HL register */ +# define XCPT_L_OFFSET (3*XCPT_HL+1) /* Offset 19: Saved 8-bit L register */ +# define XCPT_H_OFFSET (3*XCPT_HL+2) /* Offset 20: Saved 8-bit H register */ +# define XCPT_AF_OFFSET (3*XCPT_AF) /* Offset 21: Saved AF register */ +# define XCPT_F_OFFSET (3*XCPT_AF+1) /* Offset 22: Saved AF register */ +# define XCPT_A_OFFSET (3*XCPT_AF+2) /* Offset 23: Saved 8-bit A register */ +# define XCPT_PC_OFFSET (3*XCPT_PC) /* Offset 24: Offset to 24-bit PC at time of interrupt */ +# define XCPTCONTEXT_SIZE (3*XCPTCONTEXT_REGS) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the type of the register save array */ + +#ifdef CONFIG_EZ80_Z80MODE +typedef uint16_t chipreg_t; +#else +typedef uint24_t chipreg_t; +#endif + +/* This struct defines the way the registers are stored. */ + +struct xcptcontext +{ + /* Register save area */ + + chipreg_t regs[XCPTCONTEXT_REGS]; + + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* The following retains that state during signal execution */ + + chipreg_t saved_pc; /* Saved return address */ + chipreg_t saved_i; /* Saved interrupt state */ +#endif +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +irqstate_t up_irq_save(void); +void up_irq_restore(irqstate_t flags); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_INCLUDE_EZ80_IRQ_H */ + diff --git a/arch/z80/include/ez80/limits.h b/arch/z80/include/ez80/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..7b6b99bfa1fbb13c879c4041f311e093817a1b21 --- /dev/null +++ b/arch/z80/include/ez80/limits.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/z80/include/ez80/limits.h + * + * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_EZ80_LIMITS_H +#define __ARCH_Z80_INCLUDE_EZ80_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 32767 +#define UINT_MAX 65535U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +/* A pointer is 2 or 3 bytes, depending upon if the ez80 is in z80 + * compatibility mode or not + * + * Z80 mode - 16 bits + * ADL mode - 24 bits + */ + +#define PTR_MIN (-PTR_MAX - 1) +#ifdef CONFIG_EZ80_Z80MODE +#define PTR_MAX 32767 +#define UPTR_MAX 65535U +#else +#define PTR_MAX 8388607 +#define UPTR_MAX 16777215U +#endif + +#endif /* __ARCH_Z80_INCLUDE_EZ80_LIMITS_H */ diff --git a/arch/z80/include/ez80/types.h b/arch/z80/include/ez80/types.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d46957d263d2ec177c31c5995344eedc263c1 --- /dev/null +++ b/arch/z80/include/ez80/types.h @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/z80/include/ez80/types.h + * include/arch/chip/types.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_Z80_INCLUDE_EZ80_TYPES_H +#define __ARCH_Z80_INCLUDE_EZ80_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + * + * These are the sizes of the types supported by the ZiLOG compiler: + * + * int - 24-bits + * short - 16-bits + * long - 32-bits + * char - 8-bits + * float - 32-bits + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int24_t; +typedef unsigned int _uint24_t; +#define __INT24_DEFINED + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +/* A pointer is 2 or 3 bytes, depending upon if the ez80 is in z80 + * compatibility mode or not + * + * Z80 mode - 16 bits + * ADL mode - 24 bits + */ + +#ifdef CONFIG_EZ80_Z80MODE +typedef signed short _intptr_t; +typedef unsigned short _uintptr_t; +#else +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; +#endif + +/* This is the size of the interrupt state save returned by up_irq_save(). + * It holds the AF regiser pair + a zero pad byte + */ + +typedef _uint24_t irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_EZ80_TYPES_H */ diff --git a/arch/z80/include/io.h b/arch/z80/include/io.h new file mode 100644 index 0000000000000000000000000000000000000000..bd97c3792fa60e30519b8364646ac3078ac551de --- /dev/null +++ b/arch/z80/include/io.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/z80/include/io.h + * arch/chip/io.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_IO_H +#define __ARCH_Z80_INCLUDE_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_IO_H */ diff --git a/arch/z80/include/irq.h b/arch/z80/include/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..da9131cab89c3e7fa70de2b762398bef81aef6f8 --- /dev/null +++ b/arch/z80/include/irq.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/z80/include/irq.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_Z80_INCLUDE_IRQ_H +#define __ARCH_Z80_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_IRQ_H */ + diff --git a/arch/z80/include/limits.h b/arch/z80/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..3013ec8f4b91f1cb9124d67824d727f945c212bd --- /dev/null +++ b/arch/z80/include/limits.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/z80/include/limits.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_LIMITS_H +#define __ARCH_Z80_INCLUDE_LIMITS_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_LIMITS_H */ diff --git a/arch/z80/include/serial.h b/arch/z80/include/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..2997cd4fa935725b194ed6f08e54f55a4e296799 --- /dev/null +++ b/arch/z80/include/serial.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/z80/include/serial.h + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_SERIAL_H +#define __ARCH_Z80_INCLUDE_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_SERIAL_H */ diff --git a/arch/z80/include/syscall.h b/arch/z80/include/syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..20a055f70185b68ce1d7f444ce249bb1c34ce6fa --- /dev/null +++ b/arch/z80/include/syscall.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * arch/z80/include/syscall.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_Z80_INCLUDE_SYSCALL_H +#define __ARCH_Z80_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_SYSCALL_H */ + diff --git a/arch/z80/include/types.h b/arch/z80/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..af06d1fc5650f262a25f2d847e8dc4dd30f13795 --- /dev/null +++ b/arch/z80/include/types.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/z80/include/types.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly +* through sys/types.h + */ + +#ifndef __ARCH_Z80_INCLUDE_TYPES_H +#define __ARCH_Z80_INCLUDE_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_TYPES_H */ diff --git a/arch/z80/include/z180/arch.h b/arch/z80/include/z180/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc90f629ac18810f3aee69baf2b293055dca84f --- /dev/null +++ b/arch/z80/include/z180/arch.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/z80/arch.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/arch.h (via arch/arch.h) + */ + +#ifndef __ARCH_Z80_INCLUDE_Z180_ARCH_H +#define __ARCH_Z80_INCLUDE_Z180_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* The z180 address environment is represented in hardware as the 8-bit + * Common Base Register (CBR). CBR specifies the base address (on 4KB + * boundaries) used to generate a 20-bit physical address for Common Area 1 + * accesses. CBR is the upper 8-bits of the 20-bit address; the lower 14-bits + * of the base address are implicitly zero (hence the 4KB boundary alignment). + */ + +#ifdef CONFIG_ARCH_ADDRENV +typedef uint8_t save_addrenv_t; + +/* At the task-level, the z180 address environment is represented as struct + * z180_cbr_s which is defined in irq.h. + */ + +struct z180_cbr_s; +typedef FAR struct z180_cbr_s *group_addrenv_t; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_Z80_INCLUDE_Z180_ARCH_H */ + diff --git a/arch/z80/include/z180/chip.h b/arch/z80/include/z180/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..88df7a2b4b17d4873a0d0bb1602b3fee75c885fe --- /dev/null +++ b/arch/z80/include/z180/chip.h @@ -0,0 +1,466 @@ +/**************************************************************************** + * arch/z80/include/z180/chip.h + * arch/chip/io.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_Z180_CHIP_H +#define __ARCH_Z80_INCLUDE_Z180_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bits in the Z180 FLAGS register ******************************************/ + +#define Z180_C_FLAG 0x01 /* Bit 0: Carry flag */ +#define Z180_N_FLAG 0x02 /* Bit 1: Add/Subtract flag */ +#define Z180_PV_FLAG 0x04 /* Bit 2: Parity/Overflow flag */ +#define Z180_H_FLAG 0x10 /* Bit 4: Half carry flag */ +#define Z180_Z_FLAG 0x40 /* Bit 5: Zero flag */ +#define Z180_S_FLAG 0x80 /* Bit 7: Sign flag */ + +/* Z180 Chip Definitions ****************************************************/ +/* Z800180 + * + * The 8-bit Z80180 MPU provides the benefits of reduced system costs and + * also provides full backward compatibility with existing ZiLOG Z80 devices. + * Reduced system costs are obtained by incorporating several key system + * functions on-chip with the CPU. These key functions include I/O devices + * such as DMA, UART, and timer channels. Also included on-chip are wait- + * state generators, a clock oscillator, and an interrupt controller. The + * Z80180 MPU is housed in 80-pin QFP, 68-pin PLCC, and 64-pin DIP packages. + * + * Z80180 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMA channels* + * 2 UARTs* (up to 512 Kbps) + * Two 16-Bit Timers + * Clock Serial I/O + * On-Chip Oscillator + * Power-Down Mode* + * Divide-by-One/Divide-by-Two/Multiply-by-Two Clock Options* + * Programmable Driver Strength for EMI Tuning + * + * * Enhanced on the Z8S180 and Z8L180 MPUs + */ + +#if defined(CONFIG_ARCH_CHIP_Z8018006VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8018010VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8018008VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8018010FSG) || /* 80-pin QFP (11 pins N/C) */ \ + defined(CONFIG_ARCH_CHIP_Z8018008VEG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8018006VEG) /* 68-pin PLCC */ + +# undef HAVE_Z8S180 /* Not Z8S180 (5V) or Z8L180 (3.3V) core */ +# define HAVE_Z8X180 1 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +#elif defined(CONFIG_ARCH_CHIP_Z8018006PSG) || /* 64-pin DIP 6 MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018008FSG) || /* 80-pin QFP (11 pins N/C) 8MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018010PSG) || /* 64-pin DIP 10MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018006PEG) || /* 64-pin DIP 6MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018010VEG) || /* 68-pin PLCC 10MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018010PEG) || /* 64-pin DIP 10MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018008PSG) || /* 64-pin DIP 8MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018006FSG) /* 80-pin QFP (11 pins N/C) 6MHz 5V */ + +# undef HAVE_Z8S180 /* Not Z8S180 (5V) or Z8L180 (3.3V) core */ +# define HAVE_Z8X180 1 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# undef HAVE_SERIALIO /* No clocked serial I/O ? */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +#elif defined(CONFIG_ARCH_CHIP_Z8018000XSO) + defined(CONFIG_ARCH_CHIP_Z8018010FEG) + defined(CONFIG_ARCH_CHIP_Z8018000WSO) + defined(CONFIG_ARCH_CHIP_Z8018008PEG) + +# undef HAVE_Z8S180 /* Not Z8S180 (5V) or Z8L180 (3.3V) core */ +# define HAVE_Z8X180 1 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +/* Z80181 + * + * The Z80181 SAC Smart Access Controller is an 8-bit CMOS microprocessor that + * combines a Z180-compatible MPU, one channel of the Z85C30 Serial Communications + * Controller, a Z80 CTC, two 8-bit general-purpose parallel ports, and two Chip + * Select signals, into a single 100-pin Quad Flat Pack package. + * + * Z80181 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMAs + * 2 UARTs + * Two 16-Bit Timers + * Clock Serial I/O + * 1 Channel SCC + * 1 8-Bit Counter/Timer + * 16 I/O Lines + * Emulation Mode + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8018110FEG) /* 100-pin QFP */ + +# undef HAVE_Z8S180 /* Not Z8S180 (5V) or Z8L180 (3.3V) core */ +# undef HAVE_Z8X180 /* Z8x180 registers */ +# define HAVE_Z8X181 1 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 1 /* One (1) 8-bit counter/timer */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 1 /* One (1) Z85C30 serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 16 /* Sixteen (16) I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +/* Z80182 + * + * The Z80182 and Z8L182 MPUs are smart peripheral controller ICs for modems, fax, + * voice messaging, and other communications applications. It uses the Z80180 + * microprocessor linked with two channels of the industry-standard Z85230 ESCC, + * 24 bits of parallel I/O, and a 16550 MIMIC for direct connection to the IBM PC, + * XT, or AT bus + * + * Z80182 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMAs + * 2 UARTs (up to 512 Kbps) + * Two 16-Bit Timers + * Clock Serial I/O + * Power-Down Mode + * Divide-by-One/Divide-by-Two/Multiply-by-Two Clock Options + * Enhanced Serial Communication Controller (ESCC) (2 Channels) with 32-Bit CRC + * 16550 MIMIC + * 24 Parallel I/O + * 3.3 V and 5 V Version + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8018233FSG) || /* 100-pin QFP */ \ + defined(CONFIG_ARCH_CHIP_Z8018220AEG) || /* 100-pin LQFP 20MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018216FSG) || /* 100-pin QFP 16MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8018216ASG) || /* 100-pin LQFP */ \ + defined(CONFIG_ARCH_CHIP_Z8018233ASG) /* 100-pin LQFP 33MHz 5V */ + +# undef HAVE_Z8S180 /* Not Z8S180 (5V) or Z8L180 (3.3V) core */ +# undef HAVE_Z8X180 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# define HAVE_Z8X182 1 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers ? */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No Z85C30 serial communication controller */ +# define HAVE_NESCC 2 /* Two (2) Z85230 Enhanced Serial Communication Controllers */ +# define HAVE_16550 1 /* Have 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 3 /* Three (3) 8-bit parallel ports (24-bit) */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +/* Z80195 + * + * The Z80195 MPU is a smart peripheral controller device designed for general data + * communications applications, and architected specifically to accommodate all + * input and output (I/O) requirements for serial and parallel connectivity. + * Combining a high-performance CPU core with a variety of system and I/O + * resources, the Z80195 is useful in a broad range of applications. + * + * Z80195 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMAs + * 2 UARTs (up to 512 Kbps) + * Two 16-Bit Timers + * 4 Counter/Timers + * Clock Serial I/O + * Power-Down Mode + * 32 K ROM (185) + * 1 Ch ESCC + * IEEE 1284 Bi-Directional Centronics Parallel Port + * 7 or 24 Bits of I/O + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8019520FSG) || /* 100-pin QFP 20MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8019533FSG) /* 100-pin QFP 33MHz 5V */ + +# undef HAVE_Z8S180 /* No Z8S180 (5V) or Z8L180 (3.3V) core */ +# undef HAVE ROM 0 /* No 32KB on-chip ROM (z80185 only) */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# defube HAVE_WDT 1 /* Have Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit counter/timers */ +# define HAVE_NCTCS 4 /* Four (4) Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No Z85C30 serial communication controller */ +# define HAVE_NESCC 1 /* One (1) Enhanced Serial Communication Controllers (EMSCC) */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 2 /* Two (s) 8-bit parallel ports (or 17-bit IEEE 1284) */ +# define HAVE_IEEE1284 1 /* Have bidirectional centronics interface (IEEE 1284) */ + +/* Z8L180 + * + * The enhanced Z8S180/Z8L180 significantly improves on previous Z80180 models, + * while still providing full backward compatibility with existing ZiLOG Z80 + * devices. The Z8S180/Z8L180 now offers faster execution speeds, power-saving + * modes, and EMI noise reduction. + * + * Z8L180 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMAs* + * 2 UARTs* (up to 512 Kbps) + * Two 16-Bit Timers + * Clock Serial I/O + * On-Chip Oscillator + * Power-Down Mode* + * Divide-by-One/Divide-by-Two/Multiply-by-Two Clock Options* + * Programmable Driver Strength for EMI Tuning + * + * * Enhanced on the Z8S180 and Z8L180 MPUs. + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8L18020VSG) || /* 68-pinn PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8L18020FSG) || /* 80-pin GFP 20MHz 3.3V */ \ + defined(CONFIG_ARCH_CHIP_Z8L18020PSG) + +# define HAVE_Z8S180 1 /* Uses Z8S180 (5V) or Z8L180 (3.3V) core */ +# define HAVE_Z8X180 1 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +/* Z8L182 + * + * The Z80182/Z8L182 is a smart peripheral controller IC for modem (in particular + * V. Fast applications), fax, voice messaging and other communications + * applications. It uses the Z80180 microprocessor (Z8S180 MPU core) linked with + * two channels of the industry standard Z85230 ESCC (Enhanced Serial + * Communications Controller), 24 bits of parallel I/O, and a 16550 MIMIC for + * direct connection to the IBM PC, XT, AT bus. + * + * Z8L182 Features + * + * Enhanced Z80 CPU + * 1 MB MMU + * 2 DMAs + * 2 UARTs (up to 512 Kbps) + * Two 16-Bit Timers + * Clock Serial I/O + * Power-Down Mode + * Divide-by-One/Divide-by-Two/Multiply-by-Two Clock Options + * ESCC (2 Channels) with 32-Bit CRC + * 16550 MIMIC + * 24 Parallel I/O + * 3.3 V and 5 V Version + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8L18220ASG) || /* 100-pin LQFP */ \ + defined(CONFIG_ARCH_CHIP_Z8L18220FSG) || /* 100-pin QFP 20MHz 3.3V */ \ + defined(CONFIG_ARCH_CHIP_Z8L18220AEG) + +# define HAVE_Z8S180 1 /* Uses Z8S180 (5V) or Z8L180 (3.3V) core */ +# undef HAVE_Z8X180 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# define HAVE_Z8X182 1 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers ? */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No Z85C30 serial communication controller */ +# define HAVE_NESCC 2 /* Two (2) Z85230 Enhanced Serial Communication Controllers */ +# define HAVE_16550 1 /* Have 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 3 /* Three (3) 8-bit parallel ports (24-bit) */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +/* Z8SL180 + * + * The enhanced Z8S180/Z8L180 significantly improves on previous Z80180 models, + * while still providing full backward compatibility with existing ZiLOG Z80 + * devices. The Z8S180/Z8L180 now offers faster execution speeds, power-saving + * modes, and EMI noise reduction.This enhanced Z180 design also incorporates + * additional feature enhancements to the ASCIs, DMAs, and STANDBY mode power + * consumption. With the addition of ESCC-like Baud Rate Generators (BRGs), the + * two ASCIs offer the flexibility and capability to transfer data + * asynchronously at rates of up to 512 Kbps. + * + * Z8S180 Features + * + * External Memory - 1 + * Voltage Range - 5.0V + * Communications Controller - CSIO, UART + * Other Features - 1MB MMU, 2xDMA’s, 2xUARTs + * Speed (MHz) - 20, 10, 33 + * Core / CPU Used - Z180 + * Pin Count - 64, 68, 80 + * Timers - 2 + * I/O - Clock Serial + * Package - DIP, PLCC, QFP + */ + +#elif defined(CONFIG_ARCH_CHIP_Z8S18020VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18020VSG1960) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18033VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18010FSG) || /* 80-pin QFP */ \ + defined(CONFIG_ARCH_CHIP_Z8S18010VEG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18020VEG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18010VSG) || /* 68-pin PLCC */ \ + defined(CONFIG_ARCH_CHIP_Z8S18020PSG) || /* 64-pin DIP 10Mhz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18033FSG) || /* 80-pin QFP 33MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18033FEG) || /* 80-pin QFP 33MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18020FSG) || /* 80-pin QFP 20MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18033VEG) || /* 68-pin PLCC 33MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18010PSG) || /* 64-pin DIP 10MHz 5V */ \ + defined(CONFIG_ARCH_CHIP_Z8S18020FEG) || \ + defined(CONFIG_ARCH_CHIP_Z8S18010PEG) || \ + defined(CONFIG_ARCH_CHIP_Z8S18010FEG) + +# define HAVE_Z8S180 1 /* Uses Z8S180 (5V) or Z8L180 (3.3V) core */ +# define HAVE_Z8X180 1 /* Z8x180 registers */ +# undef HAVE_Z8X181 /* Z8x181 registers */ +# undef HAVE_Z8X182 /* Z8x182 registers */ +# define HAVE ROM 0 /* No on-chip ROM */ +# define HAVE_SERIALIO 1 /* Have clocked serial I/O */ +# undef HAVE_WDT /* No Watchdog timer */ +# define HAVE_NTIMERS16 2 /* Two (2) 16-bit timers */ +# define HAVE_NCTCS 0 /* No Counter/Timers (CTCs) */ +# define HAVE_NDMA 2 /* Two (2) DMA channels */ +# define HAVE_NUARTS 2 /* Two (2) UARTs (up to 512 Kbps) */ +# define HAVE_NSCC 0 /* No serial communication controller */ +# define HAVE_NESCC 0 /* No Enhanced Serial Communication Controllers */ +# undef HAVE_16550 /* No 16550 MIMIC */ +# define HAVE_NIOLINES 0 /* No I/O lines */ +# define HAVE_NPAR8 0 /* No 8-bit parallel ports */ +# undef HAVE_IEEE1284 /* No bidirectional centronics interface (IEEE 1284) */ + +#else +# error "Unrecognized/undefined Z180 chip" +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_Z180_CHIP_H */ diff --git a/arch/z80/include/z180/io.h b/arch/z80/include/z180/io.h new file mode 100644 index 0000000000000000000000000000000000000000..12bf6219e31b3ea8e87242a0c639b5aa8c8316c7 --- /dev/null +++ b/arch/z80/include/z180/io.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/z80/include/z80/io.h + * arch/chip/io.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through arch/io.h + */ + +#ifndef __ARCH_Z80_INCLUDE_Z180_IO_H +#define __ARCH_Z80_INCLUDE_Z180_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void outp(char p, char c); +char inp(char p); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_INCLUDE_Z180_IO_H */ diff --git a/arch/z80/include/z180/irq.h b/arch/z80/include/z180/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..ec2dbb7b57354d3b538088617a9882d0257794be --- /dev/null +++ b/arch/z80/include/z180/irq.h @@ -0,0 +1,245 @@ +/**************************************************************************** + * arch/z80/include/z180/irq.h + * arch/chip/irq.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h (via arch/irq.h) + */ + +#ifndef __ARCH_Z80_INCLUDE_Z180_IRQ_H +#define __ARCH_Z80_INCLUDE_Z180_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Z180 Interrupts */ +/* Resets */ + /* RST 0 is the power-up interrupt vector */ +#define Z180_RST1 (0) /* RST 1 */ +#define Z180_RST2 (1) /* RST 2 */ +#define Z180_RST3 (2) /* RST 3 */ +#define Z180_RST4 (3) /* RST 4 */ +#define Z180_RST5 (4) /* RST 5 */ +#define Z180_RST6 (5) /* RST 6 */ +#define Z180_RST7 (6) /* RST 7 */ + +/* TRAP Interrupt + * + * The Z8X180 generates a non-maskable TRAP interrupt when an undefined Op + * Code fetch occurs. When a TRAP interrupt occurs the Z8X180 operates as + * follows: + * + * 1. The TRAP bit in the Interrupt TRAP/Control (ITC) register is set to 1. + * 2. The current PC (Program Counter) is saved on the stack. + * 3. The Z8X180 vectors to logical address 0 (which may or may not be the + * same as reset which vectors to physical address 0x00000). + * + * The state of the UFO (Undefined Fetch Object) bit in ITC allows TRAP + * manipulation software to correctly adjust the stacked PC, depending on + * whether the second or third byte of the Op Code generated the TRAP. If + * UFO is 0, the starting address of the invalid instruction is equal to + * the stacked PC-1. If UFO is 1, the starting address of the invalid + * instruction is equal to the stacked PC-2. + */ + +#define Z180_TRAP (7) + +/* INT0 + * + * INT0 (only) has 3 different software programmable interrupt response + * modes—Mode 0, Mode 1 and Mode 2. + * + * - INT0 Mode 0. During the interrupt acknowledge cycle, an instruction + * is fetched from the data bus (DO–D7) at the rising edge of T3. + * + * - INT0 Mode 1. The PC is stacked and instruction execution restarts at + * logical address 0x0038. + * + * - INT0 Mode 2. The restart address is obtained by reading the contents + * of a table residing in memory. The vector table consists of up to + * 128 two-byte restart addresses stored in low byte, high byte order. + * + * This is similar to normal vector mode interrupts (like INT1 and 2): + * The 256-bit table address comes from I, however the lower-order 8 + * bits of the vector is fetched from the data bus. + */ + +#define Z180_INT0 (8) + +/* Vector Interrupts + * + * Normal vector interrupts use a vector table with 16 entries (2 bytes + * per entry). Each entry holds the address of the interrupt handler. + * The vector table address is determined by 11-bits from the I and IL + * registers. The vector table must be aligned on 32-byte address + * boundaries. + */ + +#define Z180_INT1 (9) /* Vector offset 0: External /INT1 */ +#define Z180_INT2 (10) /* Vector offset 2: External /INT2 */ +#define Z180_PRT0 (11) /* Vector offset 4: PRT channel 0 */ +#define Z180_PRT1 (12) /* Vector offset 6: PRT channel 1 */ +#define Z180_DMA0 (13) /* Vector offset 8: DMA channel 0 */ +#define Z180_DMA1 (14) /* Vector offset 10: DMA Channel 1 */ +#define Z180_CSIO (15) /* Vector offset 12: Clocked serial I/O */ +#define Z180_ASCI0 (16) /* Vector offset 14: Async channel 0 */ +#define Z180_ASCI1 (18) /* Vector offset 16: Async channel 1 */ +#define Z180_UNUSED (19) /* Vector offset 18-20: unused */ + +#define Z180_IRQ_SYSTIMER Z180_RST7 +#define NR_IRQS (20) + +/* IRQ Stack Frame Format + * + * This stack frame is created on each interrupt. These registers are stored + * in the TCB to many context switches. + */ + +#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ +#define XCPT_BC (1) /* Offset 1: Saved BC register */ +#define XCPT_DE (2) /* Offset 2: Saved DE register */ +#define XCPT_IX (3) /* Offset 3: Saved IX register */ +#define XCPT_IY (4) /* Offset 4: Saved IY register */ +#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ +#define XCPT_HL (6) /* Offset 6: Saved HL register */ +#define XCPT_AF (7) /* Offset 7: Saved AF register */ +#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ + +#define XCPTCONTEXT_REGS (9) +#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the type of the register save array */ + +typedef uint16_t chipreg_t; + +/* Common Area 1 holds the code and data that is unique to a particular task + * and shared by all pthreads created from that task. Each task will then + * have its own copy of struct z180_cbr_s. This structure is created with + * a reference count of one when the task is created. + * + * When the task creates additional threads, the reference count is + * incremented and the CBR value is shared. When each thread exits, the + * reference count id decremented. When the reference count is decremented, + * the physical memory underlying the CBR is finally released. + */ + +struct z180_cbr_s +{ + uint8_t cbr; /* The CBR value used by the thread */ + uint8_t crefs; /* The number of task groups using this CBR value (0 or 1) */ + uint8_t pages; /* The number of 4KB pages of physical memory in the allocation */ +}; + +/* This struct defines the way the registers and z180-state information are + * stored. + */ + +struct xcptcontext +{ + /* Register save area */ + + chipreg_t regs[XCPTCONTEXT_REGS]; + + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* The following retains that state during signal execution */ + + uint16_t saved_pc; /* Saved return address */ + uint16_t saved_i; /* Saved interrupt state */ +#endif +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +irqstate_t up_irq_save(void) __naked; +void up_irq_restore(irqstate_t flags) __naked; + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_INCLUDE_Z180_IRQ_H */ + diff --git a/arch/z80/include/z180/limits.h b/arch/z80/include/z180/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..283c10e33aa1ea3333595798a886ba2df6bef0a0 --- /dev/null +++ b/arch/z80/include/z180/limits.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/z80/include/z180/limits.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_Z180_LIMITS_H +#define __ARCH_Z80_INCLUDE_Z180_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 32767 +#define UINT_MAX 65535U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_Z80_INCLUDE_Z180_LIMITS_H */ diff --git a/arch/z80/include/z180/types.h b/arch/z80/include/z180/types.h new file mode 100644 index 0000000000000000000000000000000000000000..39498a9002b6583674cd875a3dfa4271f668299e --- /dev/null +++ b/arch/z80/include/z180/types.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/z80/include/z180/types.h + * include/arch/chip/types.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARC_Z80_INCLUDE_Z180_TYPES_H +#define __ARC_Z80_INCLUDE_Z180_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + * + * These are the sizes of the standard SDCC types + * + * For SDCC, sizeof(int) is 16 and sizeof(long) is 32. long long and double + * are not supported. + * + * Generic pointers are 3 bytes in length with the first byte holding data + * space information. + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed int _int16_t; +typedef unsigned int _uint16_t; + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +/* A pointer is 2 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save() */ + +typedef _uint16_t irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARC_Z80_INCLUDE_Z180_TYPES_H */ diff --git a/arch/z80/include/z8/arch.h b/arch/z80/include/z8/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..8d913a73499562f036225cd4bcd86570fbfa5459 --- /dev/null +++ b/arch/z80/include/z8/arch.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/z8/arch.h + * arch/chip/arch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h (via arch/arch.h) + */ + +#ifndef __ARCH_Z8_ARCH_H +#define __ARCH_Z8_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_Z8_ARCH_H */ + diff --git a/arch/z80/include/z8/irq.h b/arch/z80/include/z8/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..7088234f6b5b9ccec3a4d8ec08804e41b11520e8 --- /dev/null +++ b/arch/z80/include/z8/irq.h @@ -0,0 +1,378 @@ +/**************************************************************************** + * arch/z8/include/z8/irq.h + * arch/chip/irq.h + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h (via arch/irq.h) + */ + +#ifndef __ARCH_Z8_IRQ_H +#define __ARCH_Z8_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is similar configuration information that is contained in ez8.h. + * However, this file must be include-able by assembly language files and, + * hence, cannot include ez8.h. The logic is fragmentary at present. + */ + +#ifndef ENCORE_VECTORS +# if defined(_Z8ENCORE_F642X) || defined(_Z8ENCORE_64K_SERIES) +# define ENCORE_VECTORS 1 +# endif + +# if defined(_Z8ENCORE_F640X) || defined(_Z8ENCORE_640_FAMILY) +# define ENCORE_VECTORS 1 +# endif + +# if defined(_Z8ENCORE_F08X) || defined(_Z8ENCORE_8K_SERIES) +# define ENCORE_VECTORS 1 +# endif + +# if defined(_Z8ENCORE_4K_SERIES) +# define ENCORE_VECTORS 1 +# endif +#endif + +/* ez8 Interrupt Numbers ****************************************************/ + +#if defined(ENCORE_VECTORS) + +# define Z8_WDT_IRQ 0 +# define Z8_TRAP_IRQ 1 +# define Z8_TIMER2_IRQ 2 /* Only if EZ8_TIMER3 defined */ +# define Z8_TIMER1_IRQ 3 +# define Z8_TIMER0_IRQ 4 +# define Z8_UART0_RX_IRQ 5 /* Only if EZ8_UART0 defined */ +# define Z8_UART0_TX_IRQ 6 /* Only if EZ8_UART0 defined */ +# define Z8_I2C_IRQ 7 /* Only if EZ8_I2C defined */ +# define Z8_SPI_IRQ 8 /* Only if EZ8_SPI defined */ +# define Z8_ADC_IRQ 9 /* Only if EZ8_ADC defined */ +# define Z8_P7AD_IRQ 10 +# define Z8_P6AD_IRQ 11 +# define Z8_P5AD_IRQ 12 +# define Z8_P4AD_IRQ 13 +# define Z8_P3AD_IRQ 14 +# define Z8_P2AD_IRQ 15 +# define Z8_P1AD_IRQ 16 +# define Z8_P0AD_IRQ 17 +# define Z8_TIMER3_IRQ 18 /* Only if EZ8_TIMER4 defined */ +# define Z8_UART1_RX_IRQ 19 /* Only if EZ8_UART1 defined */ +# define Z8_UART1_TX_IRQ 20 /* Only if EZ8_UART1 defined */ +# define Z8_DMA_IRQ 21 /* Only if EZ8_DMA defined */ +# define Z8_C3_IRQ 22 /* Only if EZ8_PORT1 defined */ +# define Z8_C2_IRQ 23 /* Only if EZ8_PORT1 defined */ +# define Z8_C1_IRQ 24 /* Only if EZ8_PORT1 defined */ +# define Z8_C0_IRQ 25 /* Only if EZ8_PORT1 defined */ + +# define NR_IRQS (26) + +#elif defined(ENCORE_XP_VECTORS) + +# define Z8_WDT_IRQ 0 +# define Z8_TRAP_IRQ 1 +# define Z8_TIMER2_IRQ 2 /* Only if EZ8_TIMER3 defined */ +# define Z8_TIMER1_IRQ 3 +# define Z8_TIMER0_IRQ 4 +# define Z8_UART0_RX_IRQ 5 /* Only if EZ8_UART0 defined */ +# define Z8_UART0_TX_IRQ 6 /* Only if EZ8_UART0 defined */ +# define Z8_I2C_IRQ 7 /* Only if EZ8_I2C defined */ +# define Z8_SPI_IRQ 8 /* Only if EZ8_SPI defined */ +# define Z8_ADC_IRQ 9 /* Only if EZ8_ADC or EZ8_ADC_NEW defined */ +# define Z8_P7AD_IRQ 10 +# define Z8_P6AD_IRQ 11 +# define Z8_P5AD_IRQ 12 +# define Z8_P4AD_IRQ 13 +# define Z8_P3AD_IRQ 14 +# define Z8_P2AD_IRQ 15 +# define Z8_P1AD_IRQ 16 +# define Z8_P0AD_IRQ 17 +# define Z8_TIMER3_IRQ 18 /* Only if EZ8_TIMER4 defined */ +# define Z8_UART1_RX_IRQ 19 /* Only if EZ8_UART1 defined */ +# define Z8_UART1_TX_IRQ 20 /* Only if EZ8_UART1 defined */ +# define Z8_DMA_IRQ 21 /* Only if EZ8_DMA defined */ +# define Z8_C3_IRQ 22 /* Only if EZ8_PORT1 defined */ +# define Z8_C2_IRQ 23 /* Only if EZ8_PORT1 defined */ +# define Z8_C1_IRQ 24 /* Only if EZ8_PORT1 defined */ +# define Z8_C0_IRQ 25 /* Only if EZ8_PORT1 defined */ +# define Z8_POTRAP_IRQ 27 +# define Z8_WOTRAP_IRQ 28 + +# define NR_IRQS (29) + +#elif defined(ENCORE_XP16K_VECTORS) + +# define Z8_WDT_IRQ 0 +# define Z8_TRAP_IRQ 1 +# define Z8_TIMER2_IRQ 2 /* Only if EZ8_TIMER3 defined */ +# define Z8_TIMER1_IRQ 3 +# define Z8_TIMER0_IRQ 4 +# define Z8_UART0_RX_IRQ 5 /* Only if EZ8_UART0 defined */ +# define Z8_UART0_TX_IRQ 6 /* Only if EZ8_UART0 defined */ +# define Z8_I2C_IRQ 7 /* Only if EZ8_I2C defined */ +# define Z8_SPI_IRQ 8 /* Only if EZ8_ESPI defined */ +# define Z8_ADC_IRQ 9 /* Only if EZ8_ADC_NEW defined */ +# define Z8_P7AD_IRQ 10 +# define Z8_P6AD_IRQ 11 +# define Z8_P5AD_IRQ 12 +# define Z8_P4AD_IRQ 13 +# define Z8_P3AD_IRQ 14 +# define Z8_P2AD_IRQ 15 +# define Z8_P1AD_IRQ 16 +# define Z8_P0AD_IRQ 17 +# define Z8_MCT_IRQ 19 /* Only if EZ8_MCT defined */ +# define Z8_UART1_RX_IRQ 20 /* Only if EZ8_UART1 defined */ +# define Z8_UART1_TX_IRQ 21 /* Only if EZ8_UART1 defined */ +# define Z8_C3_IRQ 22 +# define Z8_C2_IRQ 23 +# define Z8_C1_IRQ 24 +# define Z8_C0_IRQ 25 +# define Z8_POTRAP_IRQ 27 +# define Z8_WOTRAP_IRQ 28 + +# define NR_IRQS (29) + +#elif defined(ENCORE_MC_VECTORS) + +# define Z8_WDT_IRQ 0 +# define Z8_TRAP_IRQ 1 +# define Z8_PWMTIMER_IRQ 2 +# define Z8_PWMFAULT_IRQ 3 +# define Z8_ADC_IRQ 4 /* Only if EZ8_ADC_NEW defined */ +# define Z8_CMP_IRQ 5 +# define Z8_TIMER0_IRQ 6 +# define Z8_UART0_RX_IRQ 7 /* Only if EZ8_UART0 defined */ +# define Z8_UART0_TX_IRQ 8 /* Only if EZ8_UART0 defined */ +# define Z8_SPI_IRQ 9 /* Only if EZ8_SPI defined */ +# define Z8_I2C_IRQ 10 /* Only if EZ8_I2C defined */ +# define Z8_C0_IRQ 12 +# define Z8_PB_IRQ 13 +# define Z8_P7AP3A_IRQ 14 +# define Z8_P6AP2A_IRQ 15 +# define Z8_P5AP1A_IRQ 16 +# define Z8_P4AP0A_IRQ 17 +# define Z8_POTRAP_IRQ 27 +# define Z8_WOTRAP_IRQ 28 + +# define NR_IRQS (29) + +#endif + +#define Z8_IRQ_SYSTIMER Z8_TIMER0_IRQ + +/* IRQ Management Macros ****************************************************/ + +/* These macros map IRQ numbers to IRQ registers and bits. + * WARNING: These have only been verified for the Z8F640X family! + */ + +#ifdef ENCORE_VECTORS + +# define Z8_IRQ0_MIN Z8_TIMER2_IRQ +# define Z8_IRQ0_BIT(irq) (1 << (Z8_ADC_IRQ - (irq))) +# define Z8_IRQ0_MAX Z8_ADC_IRQ + +# define Z8_IRQ1_MIN Z8_P7AD_IRQ +# define Z8_IRQ1_BIT(irq) (1 << (Z8_P0AD_IRQ - (irq))) +# define Z8_IRQ1_MAX Z8_P0AD_IRQ + +# define Z8_IRQ2_MIN Z8_TIMER3_IRQ +# define Z8_IRQ2_BIT(irq) (1 << (Z8_C0_IRQ - (irq))) +# define Z8_IRQ2_MAX Z8_C0_IRQ + +#else +# error "Add IRQ support for Z8F family" +#endif + +/* IRQ State Save Format **************************************************** + * + * These indices describe how the ez8 context is save in the state save array + * + * Byte offsets: + */ + +#define XCPT8_R0 (0) /* Offset 0-15: R0-R15 */ +#define XCPT8_R1 (1) +#define XCPT8_R2 (2) +#define XCPT8_R3 (3) +#define XCPT8_R4 (4) +#define XCPT8_R5 (5) +#define XCPT8_R6 (6) +#define XCPT8_R7 (7) +#define XCPT8_R8 (8) +#define XCPT8_R9 (9) +#define XCPT8_R10 (10) +#define XCPT8_R11 (11) +#define XCPT8_R12 (12) +#define XCPT8_R13 (13) +#define XCPT8_R14 (14) +#define XCPT8_R15 (15) +#define XCPT8_SPH (16) /* Offset 16: SP[8:15] */ +#define XCPT8_SPL (17) /* Offset 17: SP[0:7] */ +#define XCPT8_RP (18) /* Offset 18: Register pointer */ +#define XCPT8_FLAGS (19) /* Offset 19: FLAGS */ +#define XCPT8_PCH (20) /* Offset 20: PC[8:15] */ +#define XCPT8_PCL (21) /* Offset 21: PC[0:7] */ + +/* 16-bit "word" offsets */ + +#define XCPT_RR0 (0) /* Indices 0-7: RR0-RR14 */ +#define XCPT_RR2 (1) +#define XCPT_RR4 (2) +#define XCPT_RR6 (3) +#define XCPT_RR8 (4) +#define XCPT_RR10 (5) +#define XCPT_RR12 (6) +#define XCPT_RR14 (7) +#define XCPT_IRQCTL (8) /* Index 8: IRQCTL register */ +#define XCPT_SP (9) /* Index 9: SP[8:15] */ +#define XCPT_RPFLAGS (10) /* Index 10: RP (MS) and FLAGS (LS) */ +#define XCPT_PC (11) /* Index 11: PC[8:15] */ + +#define XCPTCONTEXT_REGS (12) + +/* Byte offsets: */ + +#define XCPT_R0_OFFS (2*XCPT_RR0) /* Offset 0-15: R0-R15 */ +#define XCPT_R1_OFFS (2*XCPT_RR0+1) +#define XCPT_R2_OFFS (2*XCPT_RR2) +#define XCPT_R3_OFFS (2*XCPT_RR2+1) +#define XCPT_R4_OFFS (2*XCPT_RR4) +#define XCPT_R5_OFFS (2*XCPT_RR4+1) +#define XCPT_R6_OFFS (2*XCPT_RR6) +#define XCPT_R7_OFFS (2*XCPT_RR6+1) +#define XCPT_R8_OFFS (2*XCPT_RR8) +#define XCPT_R9_OFFS (2*XCPT_RR8+1) +#define XCPT_R10_OFFS (2*XCPT_RR10) +#define XCPT_R11_OFFS (2*XCPT_RR10+1) +#define XCPT_R12_OFFS (2*XCPT_RR12) +#define XCPT_R13_OFFS (2*XCPT_RR12+1) +#define XCPT_R14_OFFS (2*XCPT_RR14) +#define XCPT_R15_OFFS (2*XCPT_RR14+1) +#define XCPT_UNUSED_OFFS (2*XCPT_IRQCTL) /* Offset 16: Unused (zero) */ +#define XCPT_IRQCTL_OFFS (2*XCPT_IRQCTL+1) /* offset 17: IRQCTL register */ +#define XCPT_SPH_OFFS (2*XCPT_SP) /* Offset 18: SP[8:15] */ +#define XCPT_SPL_OFFS (2*XCPT_SP+1) /* Offset 19: SP[0:7] */ +#define XCPT_RP_OFFS (2*XCPT_RPFLAGS) /* Offset 20: Register pointer */ +#define XCPT_FLAGS_OFFS (2*XCPT_RPFLAGS+1) /* Offset 21: FLAGS */ +#define XCPT_PCH_OFFS (2*XCPT_PC) /* Offset 22: PC[8:15] */ +#define XCPT_PCL_OFFS (2*XCPT_PC+1) /* Offset 23: PC[0:7] */ + +#define XCPTCONTEXT_SIZE (2*XCPTCONTEXT_REGS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the type of the register save array */ + +typedef uint16_t chipreg_t; + +/* This struct defines the way the registers are stored. */ + +struct xcptcontext +{ + /* Register save area */ + + chipreg_t regs[XCPTCONTEXT_REGS]; + + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* The following retains that state during signal execution */ + + uint16_t saved_pc; /* Saved return address */ + uint16_t saved_irqctl; /* Saved interrupt state */ +#endif +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +irqstate_t up_irq_save(void); +void up_irq_restore(irqstate_t flags); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z8_IRQ_H */ + diff --git a/arch/z80/include/z8/limits.h b/arch/z80/include/z8/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..bcf81cb5726bf6aa97cd33b1562fb942ea5306aa --- /dev/null +++ b/arch/z80/include/z8/limits.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/z80/include/z8/limits.h + * + * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_Z8_LIMITS_H +#define __ARCH_Z80_INCLUDE_Z8_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 32767 +#define UINT_MAX 65535U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_Z80_INCLUDE_Z8_LIMITS_H */ diff --git a/arch/z80/include/z8/types.h b/arch/z80/include/z8/types.h new file mode 100644 index 0000000000000000000000000000000000000000..4c66f56871027e858b6f453a2cf3f3a1c6d99622 --- /dev/null +++ b/arch/z80/include/z8/types.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * arch/z80/include/z8/types.h + * include/arch/chip/types.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARCH_Z80_INCLUDE_Z8_IRQ_H +#define __ARCH_Z80_INCLUDE_Z8_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + * + * These are the sizes of the types supported by the ZiLOG Z8Encore! compiler: + * + * int - 16-bits + * short - 16-bits + * long - 32-bits + * char - 8-bits + * float - 32-bits + * double - 32-bits + * + * Pointers: + * + * near pointer - 8-bits + * far pointer - 16-bits + * rom pointer - 16-bits + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed int _int16_t; +typedef unsigned int _uint16_t; + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +/* A pointer is 2 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save() */ + +typedef _uint8_t irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_Z80_INCLUDE_Z8_IRQ_H */ diff --git a/arch/z80/include/z80/arch.h b/arch/z80/include/z80/arch.h new file mode 100644 index 0000000000000000000000000000000000000000..d40c84b4d67977ebb1afb52de5dc4954330358be --- /dev/null +++ b/arch/z80/include/z80/arch.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/z80/arch.h + * arch/chip/arch.h + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/arch.h (via arch/arch.h) + */ + +#ifndef __ARCH_Z80_ARCH_H +#define __ARCH_Z80_ARCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_Z80_ARCH_H */ + diff --git a/arch/z80/include/z80/chip.h b/arch/z80/include/z80/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..ae4ad2891c35835358a9437280ba873ea00aff25 --- /dev/null +++ b/arch/z80/include/z80/chip.h @@ -0,0 +1,80 @@ +/************************************************************************************ + * arch/z80/include/z80/chip.h + * arch/z80/include/chip/chip.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_Z80_CHIP_H +#define __ARCH_Z80_INCLUDE_Z80_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bits in the Z80 FLAGS register ***************************************************/ + +#define Z80_C_FLAG 0x01 /* Bit 0: Carry flag */ +#define Z80_N_FLAG 0x02 /* Bit 1: Add/Subtract flag */ +#define Z80_PV_FLAG 0x04 /* Bit 2: Parity/Overflow flag */ +#define Z80_H_FLAG 0x10 /* Bit 4: Half carry flag */ +#define Z80_Z_FLAG 0x40 /* Bit 5: Zero flag */ +#define Z80_S_FLAG 0x80 /* Bit 7: Sign flag */ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_INCLUDE_Z80_CHIP_H */ diff --git a/arch/z80/include/z80/io.h b/arch/z80/include/z80/io.h new file mode 100644 index 0000000000000000000000000000000000000000..e8545a719cc92b5c86692a675bad16d1cd5a6885 --- /dev/null +++ b/arch/z80/include/z80/io.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/z80/include/z80/io.h + * arch/chip/io.h + * + * Copyright (C) 2008-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through arch/io.h + */ + +#ifndef __ARCH_Z80_IO_H +#define __ARCH_Z80_IO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void outp(char p, char c); +char inp(char p); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_IO_H */ diff --git a/arch/z80/include/z80/irq.h b/arch/z80/include/z80/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..020c777a1c6f0dedc86125195d4516c5343c09e9 --- /dev/null +++ b/arch/z80/include/z80/irq.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/z80/include/z80/irq.h + * arch/chip/irq.h + * + * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h (via arch/irq.h) + */ + +#ifndef __ARCH_Z80_INCLUDE_Z80_IRQ_H +#define __ARCH_Z80_INCLUDE_Z80_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Z80 Interrupts */ + +#define Z80_RST0 (0) +#define Z80_RST1 (1) +#define Z80_RST2 (2) +#define Z80_RST3 (3) +#define Z80_RST4 (4) +#define Z80_RST5 (5) +#define Z80_RST6 (6) +#define Z80_RST7 (7) + +#define Z80_IRQ_SYSTIMER Z80_RST7 +#define NR_IRQS (8) + +/* IRQ Stack Frame Format + * + * This stack frame is created on each interrupt. These registers are stored + * in the TCB to many context switches. + */ + +#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ +#define XCPT_BC (1) /* Offset 1: Saved BC register */ +#define XCPT_DE (2) /* Offset 2: Saved DE register */ +#define XCPT_IX (3) /* Offset 3: Saved IX register */ +#define XCPT_IY (4) /* Offset 4: Saved IY register */ +#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ +#define XCPT_HL (6) /* Offset 6: Saved HL register */ +#define XCPT_AF (7) /* Offset 7: Saved AF register */ +#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ + +#define XCPTCONTEXT_REGS (9) +#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This is the type of the register save array */ + +typedef uint16_t chipreg_t; + +/* This struct defines the way the registers are stored. */ + +struct xcptcontext +{ + /* Register save area */ + + chipreg_t regs[XCPTCONTEXT_REGS]; + + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + +#ifndef CONFIG_DISABLE_SIGNALS + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* The following retains that state during signal execution */ + + uint16_t saved_pc; /* Saved return address */ + uint16_t saved_i; /* Saved interrupt state */ +#endif +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +irqstate_t up_irq_save(void) __naked; +void up_irq_restore(irqstate_t flags) __naked; + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_INCLUDE_Z80_IRQ_H */ + diff --git a/arch/z80/include/z80/limits.h b/arch/z80/include/z80/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..21e06cdb94a870757337502cf215557d07e27e48 --- /dev/null +++ b/arch/z80/include/z80/limits.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/z80/include/z80/limits.h + * + * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_INCLUDE_Z80_LIMITS_H +#define __ARCH_Z80_INCLUDE_Z80_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 32767 +#define UINT_MAX 65535U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +/* A pointer is 2 bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 32767 +#define UPTR_MAX 65535U + +#endif /* __ARCH_Z80_INCLUDE_Z80_LIMITS_H */ diff --git a/arch/z80/include/z80/types.h b/arch/z80/include/z80/types.h new file mode 100644 index 0000000000000000000000000000000000000000..4d6d8ed5b1168bd2ebb2087ba0ec772d5d8a278a --- /dev/null +++ b/arch/z80/include/z80/types.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/z80/include/z80/types.h + * include/arch/chip/types.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through sys/types.h + */ + +#ifndef __ARC_Z80_INCLUDE_Z80_TYPES_H +#define __ARC_Z80_INCLUDE_Z80_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + * + * These are the sizes of the standard SDCC types + * + * For SDCC, sizeof(int) is 16 and sizeof(long) is 32. long long and double + * are not supported. + * + * Generic pointers are 3 bytes in length with the first byte holding data + * space information. + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed int _int16_t; +typedef unsigned int _uint16_t; + +typedef signed long _int32_t; +typedef unsigned long _uint32_t; + +/* A pointer is 2 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save() */ + +typedef _uint16_t irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARC_Z80_INCLUDE_Z80_TYPES_H */ diff --git a/arch/z80/src/.gitignore b/arch/z80/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3db121e5a4dcf2724180b051a786e6fa23e94204 --- /dev/null +++ b/arch/z80/src/.gitignore @@ -0,0 +1,22 @@ +/Make.dep +/.depend +/up_mem.h +/asm_mem.h +/board +/chip +/*.sym +/*.asm +/*.obj +/*.rel +/*.lst +/*.src +/*.adb +/*.rst +/*.lib +/*.lnk +/*.map +/*.mem +/*.ihx +/*.hex +/*.linkcmd +/*.noi diff --git a/arch/z80/src/Makefile b/arch/z80/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c3e2caea7748a6f665478abb532353c337bc4362 --- /dev/null +++ b/arch/z80/src/Makefile @@ -0,0 +1,75 @@ +############################################################################ +# arch/z80/src/Makefile +# +# Copyright (C) 2007, 2008, 2011-2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Makefile fragments + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs +-include board/Make.defs + +# Compiler-Dependent Make: SDCC or ZiLOG ZDS-II + +COMPILER = ${shell basename "$(CC)"} +ifeq ($(COMPILER),sdcc) + + # Check for SDCC native windows build + + ifeq ($(CONFIG_WINDOWS_NATIVE),y) + + # SDCC Windows native build + + include Makefile.sdccw + else + + # SDCC in a POSIX environment (Linux, OSX, or Cygwin/MSYS) + + include Makefile.sdccl + endif +else + + # Check for ZDSII native windows build + + ifeq ($(CONFIG_WINDOWS_NATIVE),y) + + # ZDSII Windows native build + + include Makefile.zdsiiw + else + + # ZDSII in a POSIX environment (Cygwin/MSYS) + + include Makefile.zdsiil + endif +endif diff --git a/arch/z80/src/Makefile.sdccl b/arch/z80/src/Makefile.sdccl new file mode 100644 index 0000000000000000000000000000000000000000..3afd657de4d571b8da74b23d8ec2a6732f3d7c0b --- /dev/null +++ b/arch/z80/src/Makefile.sdccl @@ -0,0 +1,222 @@ +############################################################################ +# arch/z80/src/Makefile.sdccl +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Tools +# CFLAGS, CPPFLAGS, ASFLAGS, LDFLAGS are set in $(TOPDIR)/Make.defs + +CFLAGS += -I$(ARCH_SRCDIR)/chip -I$(ARCH_SRCDIR)/common -I$(TOPDIR)/sched +CPPFLAGS += -D__ASSEMBLY__ + +# Files and directories +# There should be one head source (.asm file) + +HEAD_OBJ = $(HEAD_ASRC:$(ASMEXT)=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +# Assembly sources and objects + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:$(ASMEXT)=$(OBJEXT)) + +# C sources and objects + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +# All sources and objcts + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# Sources that can have dependencies (no .asm files) + +DEPSRCS = $(CSRCS) + +# Directories + +ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +BOARDDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src/board + +VPATH = chip:common:board + +# Libraries + +LIBGCC = ${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name} + +# Targets + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) nuttx.lnk + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %$(ASMEXT) + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +# This is a kludge to work around some conflicting symbols in the SDCC libraries + +$(TOPDIR)/lib/$(SDCCLIB): $(SDCC_LIBDIR)/$(SDCCLIB) + $(Q) cp $(SDCC_LIBDIR)/$(SDCCLIB) $(TOPDIR)/lib/$(SDCCLIB) + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _calloc.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _malloc.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _realloc.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _free.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) printf_large.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) sprintf.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) vprintf.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) strcpy.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) strlen.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strcat.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strchr.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strcmp.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strcspn.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strncat.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strncmp.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strncpy.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strpbrk.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strrchr.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strspn.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strstr.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _strtok.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _memchr.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _memcmp.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _memcpy.rel + $(Q) sdar d $(TOPDIR)/lib/$(SDCCLIB) _memset.rel + +# Create a header file that contains addressing information needed by the +# assemlby language start-up code. Locate the IDLE thread stack at the +# end of RAM. The heap then extends from s__HEAP to the bottom of the +# IDLE thread stack + +asm_mem.h: + @echo " CONFIG_STACK_END == ($(CONFIG_RAM_SIZE) - 1)" >> asm_mem.h + @echo " CONFIG_STACK_BASE == (CONFIG_STACK_END - $(CONFIG_IDLETHREAD_STACKSIZE))" >> asm_mem.h + +# Combine all objects in this directory into a library + +libarch$(LIBEXT): asm_mem.h $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +# This builds the libboard library in the board/ subdirectory + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +# This target builds the final executable + +nuttx.lnk: + @echo "LD: nuttx.lnk" + @echo "--" >nuttx.lnk # Non-interactive + @echo "-k $(BOARDDIR)" >>nuttx.lnk # Path to board library + @echo "-k $(TOPDIR)/lib" >>nuttx.lnk # Path to top-level lib directory + @echo "-l libboard$(LIBEXT)" >>nuttx.lnk # Name of board library + $(Q) for LIB in $(LINKLIBS); do \ + echo "-l $(TOPDIR)/lib/$$LIB" >> nuttx.lnk ;\ + done + @echo "-l $(SDCCLIB)" >>nuttx.lnk # Name of SDCC z80 library +ifneq ($(CONFIG_LINKER_HOME_AREA),) + @echo "-b _HOME=$(CONFIG_LINKER_HOME_AREA)" >>nuttx.lnk # Start of _HOME area +endif +ifneq ($(CONFIG_LINKER_CODE_AREA),) + @echo "-b _CODE=$(CONFIG_LINKER_CODE_AREA)" >>nuttx.lnk # Start of _CODE area +else + @echo "-b _CODE=0x0200" >>nuttx.lnk # Start of _CODE area +endif +ifneq ($(CONFIG_LINKER_DATA_AREA),) + @echo "-b _DATA=$(CONFIG_LINKER_DATA_AREA)" >>nuttx.lnk +else + @echo "-b _DATA=0x8000" >>nuttx.lnk # Start of _DATA area +endif + @echo "-i" >>nuttx.lnk # Intel hex format + @echo "-x" >>nuttx.lnk # Hexadecimal + @echo "-m" >>nuttx.lnk # Generate a map file + @echo "-j" >>nuttx.lnk # Generate a symbol file + @echo "nuttx.ihx" >>nuttx.lnk # Path to head object + @echo "$(HEAD_OBJ)" >>nuttx.lnk # Path to head object + @echo "-e" >>nuttx.lnk # End of script + +nuttx$(EXEEXT): asm_mem.h $(TOPDIR)/lib/$(SDCCLIB) $(HEAD_OBJ) board/libboard$(LIBEXT) nuttx.lnk + @echo "LD: nuttx.ihx" + $(Q) $(LD) -f nuttx.lnk + $(Q) cp -f nuttx.map $(TOPDIR)/. +ifeq ($(EXEEXT),.cmd) + sed s/:00000001FF/:00520001AD/ nuttx.ihx | \ + hex2cmd > $(TOPDIR)/nuttx.cmd +else + $(Q) packihx nuttx.ihx > $(TOPDIR)/nuttx$(EXEEXT) +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Build dependencies + +.depend: Makefile asm_mem.h chip/Make.defs $(DEPSRCS) + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ; \ + fi + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(DEPSRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ; \ + fi + $(call DELFILE, asm_mem.h) + $(call DELFILE, nuttx.*) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + + +distclean: clean + $(Q) if [ -e board/Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ; \ + fi + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep + diff --git a/arch/z80/src/Makefile.sdccw b/arch/z80/src/Makefile.sdccw new file mode 100644 index 0000000000000000000000000000000000000000..ee7948c6711335af1ffa52960643d68178e26518 --- /dev/null +++ b/arch/z80/src/Makefile.sdccw @@ -0,0 +1,208 @@ +############################################################################ +# arch/z80/src/Makefile.sdccw +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Tools +# CFLAGS, CPPFLAGS, ASFLAGS, LDFLAGS are set in $(TOPDIR)\Make.defs + +CFLAGS += -I$(ARCH_SRCDIR)\chip -I$(ARCH_SRCDIR)\common -I$(TOPDIR)\sched +CPPFLAGS += -D__ASSEMBLY__ + +# Files and directories +# There should be one head source (.asm file) + +HEAD_OBJ = $(HEAD_ASRC:$(ASMEXT)=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +# Assembly sources and objects + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:$(ASMEXT)=$(OBJEXT)) + +# C sources and objects + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +# All sources and objcts + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# Sources that can have dependencies (no .asm files) + +DEPSRCS = $(CSRCS) + +# Directories + +ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src +BOARDDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src\board + +VPATH = chip:common:board + +# Libraries + +LIBGCC = ${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name} + +# Targets + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board\libboard$(LIBEXT) nuttx.lnk + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %$(ASMEXT) + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +# This is a kludge to work around some conflicting symbols in the SDCC libraries + +$(TOPDIR)\lib\$(SDCCLIB): $(SDCC_LIBDIR)\$(SDCCLIB) + $(Q) cp $(SDCC_LIBDIR)\$(SDCCLIB) $(TOPDIR)\lib\$(SDCCLIB) + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _calloc.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _malloc.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _realloc.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _free.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) printf_large.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) sprintf.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) vprintf.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) strcpy.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) strlen.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strcat.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strchr.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strcmp.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strcspn.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strncat.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strncmp.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strncpy.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strpbrk.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strrchr.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strspn.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strstr.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _strtok.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _memchr.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _memcmp.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _memcpy.rel + $(Q) sdar d $(TOPDIR)\lib\$(SDCCLIB) _memset.rel + +# Create a header file that contains addressing information needed by the +# assemlby language start-up code. Locate the IDLE thread stack at the +# end of RAM. The heap then extends from s__HEAP to the bottom of the +# IDLE thread stack + +asm_mem.h: + @echo CONFIG_STACK_END == ($(CONFIG_RAM_SIZE) - 1)>>asm_mem.h + @echo CONFIG_STACK_BASE == (CONFIG_STACK_END - $(CONFIG_IDLETHREAD_STACKSIZE))>>asm_mem.h + +# Combine all objects in this directory into a library + +libarch$(LIBEXT): asm_mem.h $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +# This builds the libboard library in the board\ subdirectory + +board\libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +# This target builds the final executable + +nuttx.lnk: + @echo LD: nuttx.lnk + @echo -->nuttx.lnk + @echo -k $(BOARDDIR)>>nuttx.lnk + @echo -k $(TOPDIR)\lib>>nuttx.lnk + @echo -l libboard$(LIBEXT)>>nuttx.lnk + $(Q) for %%G in ($(LINKLIBS)) do ( echo -l $(TOPDIR)\lib\%%G>> nuttx.lnk ) + @echo -l $(SDCCLIB)>>nuttx.lnk +ifneq ($(CONFIG_LINKER_HOME_AREA),) + @echo -b _HOME=$(CONFIG_LINKER_HOME_AREA)>>nuttx.lnk +endif +ifneq ($(CONFIG_LINKER_CODE_AREA),) + @echo -b _CODE=$(CONFIG_LINKER_CODE_AREA)>>nuttx.lnk +else + @echo -b _CODE=0x0200>>nuttx.lnk +endif +ifneq ($(CONFIG_LINKER_DATA_AREA),) + @echo -b _DATA=$(CONFIG_LINKER_DATA_AREA)>>nuttx.lnk +else + @echo -b _DATA=0x8000>>nuttx.lnk +endif + @echo -i>>nuttx.lnk + @echo -x>>nuttx.lnk + @echo -m>>nuttx.lnk + @echo -j>>nuttx.lnk + @echo nuttx.ihx>>nuttx.lnk + @echo $(HEAD_OBJ)>>nuttx.lnk + @echo -e>>nuttx.lnk + +nuttx$(EXEEXT): asm_mem.h $(TOPDIR)\lib\$(SDCCLIB) $(HEAD_OBJ) board\libboard$(LIBEXT) nuttx.lnk + @echo LD: nuttx.ihx + $(Q) $(LD) -f nuttx.lnk + $(Q) cp -f nuttx.map $(TOPDIR)\. +ifeq ($(EXEEXT),.cmd) + sed s/:00000001FF/:00520001AD/ nuttx.ihx | \ + hex2cmd > $(TOPDIR)\nuttx.cmd +else + $(Q) packihx nuttx.ihx > $(TOPDIR)\nuttx$(EXEEXT) +endif + +# This is part of the top-level export target + +export_startup: board\libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if not exist board\Makefile ( echo $(EXPORT_DIR)\startup does not exist ) + $(Q) if exist board\Makefile ( cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)\startup" ) + +# Build dependencies + +.depend: Makefile asm_mem.h chip\Make.defs $(DEPSRCS) + $(Q) if exist board\Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ) + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(DEPSRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(Q) if exist board\Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ) + $(call DELFILE, asm_mem.h) + $(call DELFILE, nuttx.*) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean + $(Q) if exist board\Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ) + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/z80/src/Makefile.zdsiil b/arch/z80/src/Makefile.zdsiil new file mode 100644 index 0000000000000000000000000000000000000000..39c4cbe1eb6299d47359360aa6d28b4fd60ae679 --- /dev/null +++ b/arch/z80/src/Makefile.zdsiil @@ -0,0 +1,176 @@ +############################################################################ +# arch/z80/src/Makefile.zdsiil +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)\Make.defs + +############################################################################ +# Tools +SCHEDSRCDIR = $(TOPDIR)$(DELIM)sched +ARCHSRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src + +WSCHEDSRCDIR = ${shell cygpath -w $(SCHEDSRCDIR)} +WARCHSRCDIR = ${shell cygpath -w $(ARCHSRCDIR)} +USRINCLUDES = -usrinc:'.;$(WSCHEDSRCDIR);$(WARCHSRCDIR);$(WARCHSRCDIR)\common' + +INCLUDES = $(ARCHSTDINCLUDES) $(USRINCLUDES) +CFLAGS = $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(INCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +CPPFLAGS += -I$(ARCHSRCDIR) -I$(ZDSSTDINCDIR) -I$(ZDSZILOGINCDIR) +LDFLAGS += @nuttx.linkcmd + +############################################################################ +# Files and directories + +ifneq ($(HEAD_SSRC),) +HEAD_GENSRC = $(HEAD_SSRC:.S=$(ASMEXT)) +HEAD_OBJ = $(HEAD_SSRC:.S=$(OBJEXT)) +else +HEAD_OBJ = $(HEAD_ASRC:$(ASMEXT)=$(OBJEXT)) +endif + +STARTUP_OBJS ?= $(HEAD_OBJ) + +SSRCS = $(CHIP_SSRCS) $(CMN_SSRCS) +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +GENSRCS = $(SSRCS:.S=$(ASMEXT)) +AOBJS = $(SSRCS:.S=$(OBJEXT)) $(ASRCS:$(ASMEXT)=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +DEPSRCS = $(SSRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +BOARDDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board + +VPATH = chip:common + +############################################################################ +# Targets + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board$(DELIM)libboard$(LIBEXT) + +$(HEAD_GENSRC) $(GENSRCS) : %$(ASMEXT): %.S + $(Q) $(CPP) $(CPPFLAGS) $< -o $@.tmp + $(Q) cat $@.tmp | sed -e "s/^#/;/g" > $@ + $(Q) rm $@.tmp + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %$(ASMEXT) + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board$(DELIM)libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx.linkcmd: $(LINKCMDTEMPLATE) + $(Q) cp -f $(LINKCMDTEMPLATE) nuttx.linkcmd + @echo "\"${shell cygpath -w "$(TOPDIR)/nuttx"}\"= \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ARCHSRCDIR)/$(HEAD_OBJ)"}\", \\" >>nuttx.linkcmd + $(Q) ( for lib in $(LINKLIBS); do \ + echo " \"`cygpath -w "$(TOPDIR)/lib/$${lib}"`\", \\" >>nuttx.linkcmd; \ + done ; ) + @echo " \"${shell cygpath -w "$(ARCHSRCDIR)/board/libboard$(LIBEXT)"}\", \\" >>nuttx.linkcmd +ifeq ($(CONFIG_ARCH_CHIP_Z8F640X),y) + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/chelprevaaD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/crtrevaaLDD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/fprevaaLDD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/csiorevaaLDD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/zsldevinitdummy$(LIBEXT)"}\"" >>nuttx.linkcmd +endif +ifeq ($(CONFIG_ARCH_CHIP_Z8F642X),y) + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/chelpD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/crtLDD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/fpdumyLD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/csioLDD$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/zsldevinitdummy$(LIBEXT)"}\"" >>nuttx.linkcmd +endif +ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y) + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/chelp$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/crt$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSSTDLIBDIR)/fplib$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/gpio$(LIBEXT)"}\", \\" >>nuttx.linkcmd + @echo " \"${shell cygpath -w "$(ZDSZILOGLIBDIR)/uartf91$(LIBEXT)"}\"" >>nuttx.linkcmd +endif + +nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) nuttx.linkcmd + @echo "LD: nuttx$(EXEEXT)" + $(Q) "$(LD)" $(LDFLAGS) + +.depend: Makefile chip$(DELIM)Make.defs $(DEPSRCS) + $(Q) if [ -e board$(DELIM)Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ; \ + fi + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(DEPSRCS) >Make.dep + $(Q) touch $@ + +# This is part of the top-level export target + +export_startup: board$(DELIM)libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)$(DELIM)startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)$(DELIM)startup"; \ + else \ + echo "$(EXPORT_DIR)$(DELIM)startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +depend: .depend + +clean: + $(Q) if [ -e board$(DELIM)Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ; \ + fi + $(call DELFILE, nuttx.linkcmd) + $(call DELFILE, *.asm) + $(call DELFILE, *.tmp) + $(call DELFILE, *.map) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean + $(Q) if [ -e board$(DELIM)Makefile ]; then \ + $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ; \ + fi + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/z80/src/Makefile.zdsiiw b/arch/z80/src/Makefile.zdsiiw new file mode 100644 index 0000000000000000000000000000000000000000..25099e8a60b663697e642f82a58441b050d36989 --- /dev/null +++ b/arch/z80/src/Makefile.zdsiiw @@ -0,0 +1,158 @@ +############################################################################ +# arch/z80/src/Makefile.zdsiiw +# +# Copyright (C) 2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)\Make.defs + +# Tools + +SCHEDSRCDIR = $(TOPDIR)$(DELIM)sched +ARCHSRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src +USRINCLUDES = -usrinc:".;$(SCHEDSRCDIR);$(ARCHSRCDIR);$(ARCHSRCDIR)\common" + +INCLUDES = $(ARCHSTDINCLUDES) $(USRINCLUDES) +CFLAGS = $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(INCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +CPPFLAGS += -I$(ARCHSRCDIR) -I$(ZDSSTDINCDIR) -I$(ZDSZILOGINCDIR) +LDFLAGS += @nuttx.linkcmd + +# Files and directories + +ifneq ($(HEAD_SSRC),) +HEAD_GENSRC = $(HEAD_SSRC:.S=$(ASMEXT)) +HEAD_OBJ = $(HEAD_SSRC:.S=$(OBJEXT)) +else +HEAD_OBJ = $(HEAD_ASRC:$(ASMEXT)=$(OBJEXT)) +endif + +STARTUP_OBJS ?= $(HEAD_OBJ) + +SSRCS = $(CHIP_SSRCS) $(CMN_SSRCS) +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +GENSRCS = $(SSRCS:.S=$(ASMEXT)) +AOBJS = $(SSRCS:.S=$(OBJEXT)) $(ASRCS:$(ASMEXT)=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +DEPSRCS = $(SSRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +BOARDDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board + +VPATH = chip:common + +# Targets + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board$(DELIM)libboard$(LIBEXT) + +$(HEAD_GENSRC) $(GENSRCS) : %$(ASMEXT): %.S + $(Q) $(CPP) $(CPPFLAGS) $< -o $@.tmp + $(Q) cat $@.tmp | sed -e "s/^#/;/g" > $@ + $(Q) rm $@.tmp + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %$(ASMEXT) + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board$(DELIM)libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx.linkcmd: $(LINKCMDTEMPLATE) + $(Q) cp -f $(LINKCMDTEMPLATE) nuttx.linkcmd + @echo "$(TOPDIR)\nuttx"= \>>nuttx.linkcmd + @echo "$(ARCHSRCDIR)\$(HEAD_OBJ)", \>>nuttx.linkcmd + $(Q) for %%G in ($(LINKLIBS)) do ( echo "$(TOPDIR)\lib\%%G", \>>nuttx.linkcmd ) + @echo "$(ARCHSRCDIR)\board\libboard$(LIBEXT)", \>>nuttx.linkcmd +ifeq ($(CONFIG_ARCH_CHIP_Z8F640X),y) + @echo "$(ZDSSTDLIBDIR)\chelprevaaD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\crtrevaaLDD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\fprevaaLDD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\csiorevaaLDD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\zsldevinitdummy$(LIBEXT)">>nuttx.linkcmd +endif +ifeq ($(CONFIG_ARCH_CHIP_Z8F642X),y) + @echo "$(ZDSSTDLIBDIR)\chelpD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\crtLDD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\fpdumyLD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\csioLDD$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\zsldevinitdummy$(LIBEXT)">>nuttx.linkcmd +endif +ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y) + @echo "$(ZDSSTDLIBDIR)\chelp$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\crt$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSSTDLIBDIR)\fplib$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\gpio$(LIBEXT)", \>>nuttx.linkcmd + @echo "$(ZDSZILOGLIBDIR)\uartf91$(LIBEXT)">>nuttx.linkcmd +endif + +nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) nuttx.linkcmd + @echo "LD: nuttx$(EXEEXT)" + $(Q) "$(LD)" $(LDFLAGS) + +.depend: Makefile chip$(DELIM)Make.defs $(DEPSRCS) + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" depend ) + $(Q) $(MKDEP) --dep-path chip --dep-path common "$(CC)" -- $(CFLAGS) -- $(DEPSRCS) >Make.dep + $(Q) touch $@ + +# This is part of the top-level export target + +export_startup: board$(DELIM)libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if exist "$(EXPORT_DIR)$(DELIM)startup" ( copy $(STARTUP_OBJS) "$(EXPORT_DIR)$(DELIM)startup$(DELIM)." /b /y) + +# Dependencies + +depend: .depend + +clean: + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" clean ) + $(call DELFILE, nuttx.linkcmd) + $(call DELFILE, *.asm) + $(call DELFILE, *.tmp) + $(call DELFILE, *.map) + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean + $(Q) if exist board$(DELIM)Makefile ( $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean ) + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/z80/src/common/Kconfig b/arch/z80/src/common/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..a31d4502c4ab01710614feb1f74c5f6ea703c25f --- /dev/null +++ b/arch/z80/src/common/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_Z80 +endif diff --git a/arch/z80/src/common/up_allocateheap.c b/arch/z80/src/common/up_allocateheap.c new file mode 100644 index 0000000000000000000000000000000000000000..7ea677c5f943271732d70ffbefa93c8b3df0c5d2 --- /dev/null +++ b/arch/z80/src/common/up_allocateheap.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * common/up_allocateheap.c + * + * Copyright (C) 2007, 2008, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#ifdef SDCC +/* For the SDCC toolchain, the arch/z80/src/Makefile will parse the map file + * to determine how much memory is available for the heap. This parsed data + * is provided via the auto-generated file up_mem.h + */ + +# include "up_mem.h" + +#else +/* For other toolchains, the architecture must provide a header file in the + * chip subdirectory to provide the heap parameters (if they are not defined + * in the configuration file ) + */ + +# include "chip/up_mem.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + *heap_start = (FAR void*)CONFIG_HEAP1_BASE; + *heap_size = CONFIG_HEAP1_END - CONFIG_HEAP1_BASE; + board_autoled_on(LED_HEAPALLOCATE); +} + +/**************************************************************************** + * Name: up_addregions + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + kmm_addregion((FAR void*)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +} +#endif diff --git a/arch/z80/src/common/up_arch.h b/arch/z80/src/common/up_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..dc7206da744b398bc403ebe0e190aced1ab6bd9b --- /dev/null +++ b/arch/z80/src/common/up_arch.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/z80/src/common/up_arch.h + * + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_COMMON_UP_ARCH_H +#define __ARCH_Z80_SRC_COMMON_UP_ARCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include "chip/chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#endif /* __ARCH_Z80_SRC_COMMON_UP_ARCH_H */ diff --git a/arch/z80/src/common/up_assert.c b/arch/z80/src/common/up_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..78e114d35d9e476ca8bf9cfc488e11c03e357817 --- /dev/null +++ b/arch/z80/src/common/up_assert.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * common/up_assert.c + * + * Copyright (C) 2007-2009, 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG 1 +# define CONFIG_DEBUG_VERBOSE 1 +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) /* noreturn_function */ +{ + /* Are we in an interrupt handler or the idle task? */ + + if (up_interrupt_context() || this_task()->pid == 0) + { + (void)up_irq_save(); + for (;;) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = lowvsyslog(LOG_INFO, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(struct usbtrace_s *trace, void *arg) +{ + usbtrace_trprintf(FAR usbtrace_syslog, trace->event, FAR trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +#ifdef CONFIG_HAVE_FILENAME +void up_assert(const uint8_t *filename, int lineno) +#else +void up_assert(void) +#endif +{ +#if CONFIG_TASK_NAME_SIZE > 0 + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#ifdef CONFIG_HAVE_FILENAME +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + lldbg("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif +#else +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg("Assertion failed: task: %s\n", rtcb->name); +#else + lldbg("Assertion failed\n"); +#endif +#endif + + up_stackdump(); + REGISTER_DUMP(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/z80/src/common/up_blocktask.c b/arch/z80/src/common/up_blocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..831de41317d39ce12bd7e3a29c0c268fc0045397 --- /dev/null +++ b/arch/z80/src/common/up_blocktask.c @@ -0,0 +1,179 @@ +/**************************************************************************** + * arch/z80/src/common/up_blocktask.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state) +{ + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* dbg("Blocking TCB=%p\n", tcb); */ + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT()) + { + /* Yes, then we have to do things differently. + * Just copy the current registers into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the user C context into the TCB at the (old) head of the + * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z80/src/common/up_createstack.c b/arch/z80/src/common/up_createstack.c new file mode 100644 index 0000000000000000000000000000000000000000..60c4733d99e232d2f91f07d594591530975f15ae --- /dev/null +++ b/arch/z80/src/common/up_createstack.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/z80/src/common/up_createstack.c + * + * Copyright (C) 2007-2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * The following TCB fields must be initialized by this function: + * + * - adj_stack_size: Stack size after adjustment for hardware, processor, + * etc. This value is retained only for debug purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* The Z80 family uses a push-down stack: the stack grows + * toward loweraddresses in memory. The stack pointer + * register, points to the lowest, valid work address + * (the "top" of the stack). Items on the stack are + * referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The Z80 stack does not need to be aligned. Here is is aligned at + * word (4 byte) boundary. + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/z80/src/common/up_doirq.c b/arch/z80/src/common/up_doirq.c new file mode 100644 index 0000000000000000000000000000000000000000..30e2caf9fd1489b5fe2f2b82e7192119a8ed5883 --- /dev/null +++ b/arch/z80/src/common/up_doirq.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/z80/src/common/up_doirq.c + * + * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include "up_arch.h" + +#include +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +#include "group/group.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs) +{ + board_autoled_on(LED_INIRQ); + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + + lowsyslog(LOG_ERR, "Unexpected IRQ\n"); + IRQ_ENTER(regs); + PANIC(); + return NULL; /* Won't get here */ + +#else +#ifdef CONFIG_ARCH_ADDRENV + FAR chipreg_t *newregs; +#endif + + if (irq < NR_IRQS) + { + DECL_SAVESTATE(); + + /* Indicate that we have entered IRQ processing logic */ + + IRQ_ENTER(irq, regs); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#ifdef CONFIG_ARCH_ADDRENV + /* If a context switch occurred, 'newregs' will hold the new context */ + + newregs = IRQ_STATE(); + + if (newregs != regs) + { + /* Make sure that the address environment for the previously + * running task is closed down gracefully and set up the + * address environment for the new thread at the head of the + * ready-to-run list. + */ + + (void)group_addrenv(NULL); + } + + regs = newregs; + +#else + /* If a context switch occurred, 'regs' will hold the new context */ + + regs = IRQ_STATE(); +#endif + + /* Indicate that we are no longer in interrupt processing logic */ + + IRQ_LEAVE(irq); + } + + board_autoled_off(LED_INIRQ); + return regs; +#endif +} diff --git a/arch/z80/src/common/up_exit.c b/arch/z80/src/common/up_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..82f647c18c99aaea4edb441214eeb43e328dd805 --- /dev/null +++ b/arch/z80/src/common/up_exit.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * common/up_exit.c + * + * Copyright (C) 2007-2009, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#ifdef CONFIG_DUMP_ON_EXIT +#include +#endif + +#include "chip/chip.h" +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + lldbg(" fd=%d refcount=%d\n", + i, inode->i_crefs); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + lldbg(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + lldbg(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ + FAR struct tcb_s* tcb; + + /* Disable interrupts. Interrupts will remain disabled until + * the new task is resumed below. + */ + + (void)up_irq_save(); + + slldbg("TCB=%p exiting\n", tcb); + +#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) + lldbg("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + slldbg("New Active Task TCB=%p\n", tcb); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(tcb); +} + diff --git a/arch/z80/src/common/up_idle.c b/arch/z80/src/common/up_idle.c new file mode 100644 index 0000000000000000000000000000000000000000..43deca5aa0f7cbfa73008c624126d061038a1e57 --- /dev/null +++ b/arch/z80/src/common/up_idle.c @@ -0,0 +1,108 @@ +/**************************************************************************** + * common/up_idle.c + * + * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP) +static uint8_t g_ledtoggle = 0; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their + * is no other ready-to-run task. This is processor idle + * time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be + * performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP) + g_ledtoggle++; + if (g_ledtoggle == 0x80) + { + board_autoled_on(LED_IDLE); + } + else if (g_ledtoggle == 0x00) + { + board_autoled_off(LED_IDLE); + } +#endif + +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, + * then process "fake" timer interrupts. Hopefully, something + * will wake up. + */ + + sched_process_timer(); +#endif +} + diff --git a/arch/z80/src/common/up_initialize.c b/arch/z80/src/common/up_initialize.c new file mode 100644 index 0000000000000000000000000000000000000000..218a78232663302543378c313a897da7d681c701 --- /dev/null +++ b/arch/z80/src/common/up_initialize.c @@ -0,0 +1,210 @@ +/**************************************************************************** + * arch/z80/src/common/up_initialize.c + * + * Copyright (C) 2007-2009, 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip/switch.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_calibratedelay + * + * Description: + * Delay loops are provided for short timing loops. This function, if + * enabled, will just wait for 100 seconds. Using a stopwatch, you can + * can then determine if the timing loops are properly calibrated. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_CALIBRATION) && defined(CONFIG_DEBUG) +static void up_calibratedelay(void) +{ + int i; + + lldbg("Beginning 100s delay\n"); + for (i = 0; i < 100; i++) + { + up_mdelay(1000); + } + + lldbg("End 100s delay\n"); +} +#else +# define up_calibratedelay() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initialize + * + * Description: + * up_initialize will be called once during OS initialization after the + * basic OS services have been initialized. The architecture specific + * details of initializing the OS will be handled here. Such things as + * setting up interrupt service routines, starting the clock, and + * registering device drivers are some of the things that are different + * for each processor and hardware platform. + * + * up_initialize is called after the OS initialized but before the user + * initialization logic has been started and before the libraries have + * been initialized. OS services and driver services are available. + * + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize global variables */ + + INIT_IRQCONTEXT(); + + /* Calibrate the timing loop */ + + up_calibratedelay(); + + /* Add any extra memory fragments to the memory manager */ + +#if CONFIG_MM_REGIONS > 1 + up_addregion(); +#endif + + /* Initialize the interrupt subsystem */ + + up_irqinitialize(); + + /* Initialize the system timer interrupt */ + +#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) + up_timer_initialize(); +#endif + + /* Initialize the CPU for those that use it (only for the Z180). This + * needs to be done before any tasks are created). + */ + +#ifdef CONFIG_ARCH_ADDRENV + (void)up_mmuinit(); +#endif + + /* Register devices */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#if defined(CONFIG_DEV_NULL) + devnull_register(); /* Standard /dev/null */ +#endif + +#if defined(CONFIG_DEV_ZERO) + devzero_register(); /* Standard /dev/zero */ +#endif + +#if defined(CONFIG_DEV_LOOP) + loop_register(); /* Standard /dev/loop */ +#endif +#endif /* CONFIG_NFILE_DESCRIPTORS */ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + note_register(); /* Non-standard /dev/note */ +#endif + + /* Initialize the serial device driver */ + +#ifdef USE_SERIALDRIVER + up_serialinit(); +#endif + + /* Initialize the console device driver (if it is other than the standard + * serial driver). + */ + +#if defined(CONFIG_DEV_LOWCONSOLE) + lowconsole_init(); +#elif defined(CONFIG_SYSLOG_CONSOLE) + syslog_console_init(); +#elif defined(CONFIG_RAMLOG_CONSOLE) + ramlog_consoleinit(); +#endif + +#ifndef CONFIG_NETDEV_LATEINIT + /* Initialize the network */ + + up_netinitialize(); +#endif + +#ifdef CONFIG_NETDEV_LOOPBACK + /* Initialize the local loopback device */ + + (void)localhost_initialize(); +#endif + +#ifdef CONFIG_NET_TUN + /* Initialize the TUN device */ + + (void)tun_initialize(); +#endif + +#ifdef CONFIG_NETDEV_TELNET + /* Initialize the Telnet session factory */ + + (void)telnet_initialize(); +#endif + + board_autoled_on(LED_IRQSENABLED); +} diff --git a/arch/z80/src/common/up_internal.h b/arch/z80/src/common/up_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..76deaa34b7b7d4b0a993236713b85ca39a3371f1 --- /dev/null +++ b/arch/z80/src/common/up_internal.h @@ -0,0 +1,239 @@ +/**************************************************************************** + * arch/z80/src/common/up_internal.h + * + * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_SRC_COMMON_UP_INTERNAL_H +#define __ARCH_Z80_SRC_COMMON_UP_INTERNAL_H + +/**************************************************************************** + * Conditional Compilation + ****************************************************************************/ + +/* Bring-up debug configurations. These are here (vs defconfig) + * because these should only be controlled during low level + * board bring-up and not part of normal platform configuration. + */ + +#undef CONFIG_SUPPRESS_INTERRUPTS /* Do not enable interrupts */ +#undef CONFIG_SUPPRESS_TIMER_INTS /* No timer */ +#undef CONFIG_SUPPRESS_SERIAL_INTS /* Console will poll */ +#undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */ +#undef CONFIG_DUMP_ON_EXIT /* Dump task state on exit */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include "chip/chip.h" +#include "chip/switch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if CONFIG_NFILE_DESCRIPTORS == 0 || defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# ifdef CONFIG_HAVE_LOWSERIALINIT +# define USE_LOWSERIALINIT 1 +# else +# undef USE_LOWSERIALINIT +# endif +#elif !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_LOWSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# undef USE_LOWSERIALINIT +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_SYSLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# else +# define USE_SERIALDRIVER 1 +# endif +#endif + +/* If some other device is used as the console, then the serial driver may + * still be needed. Let's assume that if the upper half serial driver is + * built, then the lower half will also be needed. There is no need for + * the early serial initialization in this case. + */ + +#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL) +# define USE_SERIALDRIVER 1 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Supplied by chip- or board-specific logic */ + +void up_irqinitialize(void); +int up_timerisr(int irq, FAR chipreg_t *regs); + +#ifdef USE_LOWSERIALINIT +void up_lowserialinit(void); +#endif + +/* Defined in up_doirq.c */ + +FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs); + +/* Define in up_sigdeliver */ + +void up_sigdeliver(void); + +/* Defined in CPU-specific logic (only for Z180) */ + +#ifdef CONFIG_ARCH_ADDRENV +int up_mmuinit(void); +#endif + +/* Defined in up_allocateheap.c */ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void); +#endif + +/* Defined in up_serial.c */ + +#ifdef USE_SERIALDRIVER +void up_serialinit(void); +#else +# define up_serialinit() +#endif + +/* Defined in drivers/lowconsole.c */ + +#ifdef CONFIG_DEV_LOWCONSOLE +void lowconsole_init(void); +#else +# define lowconsole_init() +#endif + +/* Defined in drivers/syslog_console.c */ + +#ifdef CONFIG_SYSLOG_CONSOLE +void syslog_console_init(); +#else +# define syslog_console_init() +#endif + +/* Defined in drivers/ramlog.c */ + +#ifdef CONFIG_RAMLOG_CONSOLE +void ramlog_consoleinit(void); +#else +# define ramlog_consoleinit() +#endif + +/* Low level string output */ + +void up_puts(const char *str); + +/* Defined in up_timerisr.c */ + +void up_timer_initialize(void); + +/* Architecture specific hook into the timer interrupt handler */ + +#ifdef CONFIG_ARCH_TIMERHOOK +void up_timerhook(void); +#endif + +/* Defined in board/up_network.c */ + +#ifdef CONFIG_NET +int up_netinitialize(void); +void up_netuninitialize(void); +# ifdef CONFIG_ARCH_MCFILTER +int up_multicastfilter(FAR struct net_driver_s *dev, FAR uint8_t *mac, bool enable); +# else +# define up_multicastfilter(dev, mac, enable) +# endif +#else +# define up_netinitialize() +# define up_netuninitialize() +# define up_multicastfilter(dev, mac, enable) +#endif + +/* Return the current value of the stack pointer (used in stack dump logic) */ + +uint16_t up_getsp(void); + +/* Dump stack and registers */ + +#ifdef CONFIG_ARCH_STACKDUMP +void up_stackdump(void); +# define REGISTER_DUMP() _REGISTER_DUMP() +#else +# define up_stackdump() +# define REGISTER_DUMP() +#endif + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/z80/src/common/up_interruptcontext.c b/arch/z80/src/common/up_interruptcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..fc9251289489ef694f6fc6c880b0d1dacdc44471 --- /dev/null +++ b/arch/z80/src/common/up_interruptcontext.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * arch/z80/src/common/up_interruptcontext.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return IN_INTERRUPT(); +} diff --git a/arch/z80/src/common/up_mdelay.c b/arch/z80/src/common/up_mdelay.c new file mode 100644 index 0000000000000000000000000000000000000000..607ce484538540521c9c3a8b55cabf9c8a7de0d4 --- /dev/null +++ b/arch/z80/src/common/up_mdelay.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * common/up_mdelay.c + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_BOARD_LOOPSPERMSEC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} +#endif /* CONFIG_BOARD_LOOPSPERMSEC */ + diff --git a/arch/z80/src/common/up_puts.c b/arch/z80/src/common/up_puts.c new file mode 100644 index 0000000000000000000000000000000000000000..bab4a0f9c3840482826b7d731b9213fb69b0b5b6 --- /dev/null +++ b/arch/z80/src/common/up_puts.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/z80/src/common/up_puts.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void up_puts(const char *str) +{ + while (*str) + { + up_putc(*str++); + } +} diff --git a/arch/z80/src/common/up_releasepending.c b/arch/z80/src/common/up_releasepending.c new file mode 100644 index 0000000000000000000000000000000000000000..e4bc07a78fb7d9522f3ed8387d5dcce3324c67ef --- /dev/null +++ b/arch/z80/src/common/up_releasepending.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * arch/z80/src/common/up_releasepending.c + * + * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "chip/switch.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + FAR struct tcb_s *rtcb = this_task(); + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (IN_INTERRUPT()) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the exception context into the TCB of the task that + * was currently active. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task + * restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z80/src/common/up_releasestack.c b/arch/z80/src/common/up_releasestack.c new file mode 100644 index 0000000000000000000000000000000000000000..63b55720306d27ee4adbb0b6dc28f905bfd6cbef --- /dev/null +++ b/arch/z80/src/common/up_releasestack.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * common/up_releasestack.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/z80/src/common/up_reprioritizertr.c b/arch/z80/src/common/up_reprioritizertr.c new file mode 100644 index 0000000000000000000000000000000000000000..d7102775631a35b569c4e6550ec0855a759c981c --- /dev/null +++ b/arch/z80/src/common/up_reprioritizertr.c @@ -0,0 +1,202 @@ +/**************************************************************************** + * arch/z80/src/common/up_reprioritizertr.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "chip/switch.h" +#include "sched/sched.h" +#include "group/group.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + FAR struct tcb_s *rtcb = this_task(); + bool switch_needed; + + slldbg("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT()) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* Copy the exception context into the TCB at the (old) head of the + * ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero + * value, then this is really the previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } + } +} diff --git a/arch/z80/src/common/up_stackdump.c b/arch/z80/src/common/up_stackdump.c new file mode 100644 index 0000000000000000000000000000000000000000..32a3fc68302cad1f05cde59fb9c2ba9bd41f8b9a --- /dev/null +++ b/arch/z80/src/common/up_stackdump.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * common/up_stackdump.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include + +#include "up_arch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ +#warning TO BE PROVIDED + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(void) +{ + struct tcb_s *rtcb = this_task(); + uint16_t sp = up_getsp(); + uint16_t stack_base = (uint16_t)rtcb->adj_stack_ptr; + uint16_t stack_size = (uint16_t)rtcb->adj_stack_size; + + lldbg("stack_base: %04x\n", stack_base); + lldbg("stack_size: %04x\n", stack_size); + lldbg("sp: %04x\n", sp); + + if (sp >= stack_base || sp < stack_base - stack_size) + { + lldbg("ERROR: Stack pointer is not within allocated stack\n"); + return; + } + else + { + uint16_t stack = sp & ~0x0f; + + for (stack = sp & ~0x0f; stack < stack_base; stack += 8*sizeof(uint16_t)) + { + uint16_t *ptr = (uint16_t*)stack; + lldbg("%04x: %04x %04x %04x %04x %04x %04x %04x %04x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z80/src/common/up_stackframe.c b/arch/z80/src/common/up_stackframe.c new file mode 100644 index 0000000000000000000000000000000000000000..9da978a4f7d41b2a4598310012b25233012b849c --- /dev/null +++ b/arch/z80/src/common/up_stackframe.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/z80/src/common/up_stackframe.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ +/* The Z80 stack does not need to be aligned. Here is is aligned at word + * (4 byte) boundary. + */ + +#define STACK_ALIGNMENT 4 + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial state */ + + up_initial_state(tcb); + + /* And return a pointer to the allocated memory */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} + diff --git a/arch/z80/src/common/up_udelay.c b/arch/z80/src/common/up_udelay.c new file mode 100644 index 0000000000000000000000000000000000000000..be5224a20d2690ec96b39cb395f272c268aebed5 --- /dev/null +++ b/arch/z80/src/common/up_udelay.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * common/up_udelay.c + * + * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_BOARD_LOOPSPERMSEC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + microseconds--; + } +} +#endif /* CONFIG_BOARD_LOOPSPERMSEC */ + diff --git a/arch/z80/src/common/up_unblocktask.c b/arch/z80/src/common/up_unblocktask.c new file mode 100644 index 0000000000000000000000000000000000000000..f110172052b5c3043cfd696e7e5749f29864fcde --- /dev/null +++ b/arch/z80/src/common/up_unblocktask.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/z80/src/common/up_unblocktask.c + * + * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "chip/switch.h" +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(FAR struct tcb_s *tcb) +{ + FAR struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* dbg("Unblocking TCB=%p\n", tcb); */ + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (IN_INTERRUPT()) + { + /* Yes, then we have to do things differently. + * Just copy the current context into the OLD rtcb. + */ + + SAVE_IRQCONTEXT(rtcb); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then setup so that the context will be performed on exit + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + SET_IRQCONTEXT(rtcb); + } + + /* We are not in an interrupt handler. Copy the user C context + * into the TCB of the task that was previously active. if + * SAVE_USERCONTEXT returns a non-zero value, then this is really the + * previously running task restarting! + */ + + else if (!SAVE_USERCONTEXT(rtcb)) + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + rtcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(rtcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts */ + + RESTORE_USERCONTEXT(rtcb); + } + } +} diff --git a/arch/z80/src/common/up_usestack.c b/arch/z80/src/common/up_usestack.c new file mode 100644 index 0000000000000000000000000000000000000000..dd82424d33fc22e0b348906a85f89b2d85f0c713 --- /dev/null +++ b/arch/z80/src/common/up_usestack.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/z80/src/common/up_usestack.c + * + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_use_stack + * + * Description: + * Setup up stack-related information in the TCB using pre-allocated stack + * memory. This function is called only from task_init() when a task or + * kernel thread is started (never for pthreads). + * + * The following TCB fields must be initialized: + * + * - adj_stack_size: Stack size after adjustment for hardware, + * processor, etc. This value is retained only for debug + * purposes. + * - stack_alloc_ptr: Pointer to allocated stack + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The + * initial value of the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The allocated stack size. + * + * NOTE: Unlike up_stack_create() and up_stack_release, this function + * does not require the task type (ttype) parameter. The TCB flags will + * always be set to provide the task type to up_use_stack() if it needs + * that information. + * + ****************************************************************************/ + +int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +{ + size_t top_of_stack; + size_t size_of_stack; + + /* Is there already a stack allocated? */ + + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ + + tcb->stack_alloc_ptr = stack; + + /* The Z80 uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register, points to the + * lowest, valid work address (the "top" of the stack). Items on + * the stack are* referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The Z80 stack does not need to be aligned. Here is is aligned at + * word (4 byte) boundary. + */ + + top_of_stack &= ~3; + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_size = top_of_stack; + tcb->adj_stack_size = size_of_stack; + + return OK; +} diff --git a/arch/z80/src/ez80/Kconfig b/arch/z80/src/ez80/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..df8cc5a19784ac40837412e74cf80fc15d21b563 --- /dev/null +++ b/arch/z80/src/ez80/Kconfig @@ -0,0 +1,131 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_EZ80 + +menu "ez80 Peripheral Support" + +config EZ80_UART0 + bool "UART0" + select ARCH_HAVE_UART0 + default n + +config EZ80_UART1 + bool "UART1" + select ARCH_HAVE_UART1 + default n + +config EZ80_UART2 + bool "UART2" + select ARCH_HAVE_UART2 + default n + +config EZ80_EMAC + bool "Ethernet MAC" + default n + select ARCH_HAVE_PHY + select ARCH_HAVE_NETDEV_STATISTICS + ---help--- + Enables support for ez80 EMAC driver. + +endmenu + +# The ZiLOG ZDS-II Windows toolchain is the only toolchain available for +# the ez80. +# + +config EZ80_TOOLCHAIN_ZDSII + bool + default y if ARCH_CHIP_EZ80 + default n if !ARCH_CHIP_EZ80 + +choice + prompt "ZDS-II Toolchain version" + default EZ80_ZDSII_V521 + +config EZ80_ZDSII_V511 + bool "ZDS-II 5.1.1" + +config EZ80_ZDSII_V521 + bool "ZDS-II 5.2.1" + +endchoice # ZDS-II Toolchain version + +if EZ80_EMAC + +config EZ80_FIAD +hex "PHY Address" + range 0x00 0x1f + default 0x1f + ---help--- + Provides the MII address of the PHY device + +# Belongs in net/Kconfig as PHY_AM79C874 +# ETH0_PHY_AM79C874 - Define for Am79c874 PHY + +config EZ80_PHYCONFIG + int "PHY Configuration" + default 0 + ---help--- + 0:Autonegotiate, 1:100FD, 2:100HD, 3:10FD, 4:10HD + +config EZ80_RAMADDR + hex "Address of internal SRAM" + default 0xffc000 + ---help--- + Address of internal SRAM (default is 0xffc000) + +config EZ80_PKTBUFSIZE + int "Packet Buffer Size" + default 64 + ---help--- + The size of one packet buffer. EZ80_PKTBUFSIZE + (EZ80_NTXPKTBUFS+EZ80_NRXPKTBUFS) + must add up to exactly 8192 bytes. + +config EZ80_NTXPKTBUFS + int "Number of Tx Packets" + default 64 + ---help--- + The number of Tx packets. EZ80_PKTBUFSIZE + (EZ80_NTXPKTBUFS+EZ80_NRXPKTBUFS) + must add up to exactly 8192 bytes. + +config EZ80_NRXPKTBUFS + int "Number of Rx Packets" + default 64 + ---help--- + The number of Rx packets. EZ80_PKTBUFSIZE + (EZ80_NTXPKTBUFS+EZ80_NRXPKTBUFS) + must add up to exactly 8192 bytes. + +config EZ80_MDCDIV + int "SCLK Divider" + default 0 + ---help--- + The value to use for the divider to derive the MII MDC clock from SCLK. Options + are 1->4; 2->6; 3->8; 4->10; 5->14; 6->20; and 7->28 + +config EZ80_TXPOLLTIMERMS + int "Tx Poll Milliseconds" + default 10 + ---help--- + Specifies how often the EMAC controller should poll for a Tx packet (milliseconds) + +config ARCH_MCFILTER + bool "Multicast Filtering" + default n + ---help--- + Enables multicast MAC address filtering (not fully implemented) + +endif # EZ80_EMAC + +config ARCH_TIMERHOOK + bool "Timer Hook" + default n + ---help--- + Select this option to enabled a direct call-out from the ez80 timer interrupt + handler. If this is enabled, the ez80 timer interrupt interrupt will call a + user provided function called up_timerhook(). At present, this timer hook is + only used for driving the segment LED on board certain ez80 boards. + +endif # ARCH_CHIP_EZ80 diff --git a/arch/z80/src/ez80/Make.defs b/arch/z80/src/ez80/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..7e79e19d657b2854fe71e1ca3d05e89b24018e0f --- /dev/null +++ b/arch/z80/src/ez80/Make.defs @@ -0,0 +1,66 @@ +############################################################################ +# arch/z80/src/ez80/Make.defs +# +# Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = ez80_vectors.asm +HEAD_SSRC = + +CMN_SSRCS = +CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c +CMN_CSRCS += up_releasestack.c up_interruptcontext.c up_blocktask.c +CMN_CSRCS += up_unblocktask.c up_exit.c up_releasepending.c +CMN_CSRCS += up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c +CMN_CSRCS += up_mdelay.c up_stackframe.c up_udelay.c up_usestack.c +CMN_CSRCS += up_puts.c + +CHIP_ASRCS = ez80_startup.asm ez80_io.asm ez80_up_irq_save.asm +CHIP_ASRCS += ez80_saveusercontext.asm ez80_restorecontext.asm +ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y) +CHIP_ASRCS += ez80f91_init.asm +endif + +CHIP_SSRCS = +CHIP_CSRCS = ez80_clock.c ez80_initialstate.c ez80_irq.c ez80_copystate.c +CHIP_CSRCS += ez80_schedulesigaction.c ez80_sigdeliver.c ez80_lowuart.c +CHIP_CSRCS += ez80_serial.c ez80_spi.c ez80_i2c.c ez80_registerdump.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += ez80_timerisr.c +endif + +ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y) +ifeq ($(CONFIG_EZ80_EMAC),y) +CHIP_CSRCS += ez80_emac.c +endif +endif diff --git a/arch/z80/src/ez80/Toolchain.defs b/arch/z80/src/ez80/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..bc68e4782dd71ea6037bb28004a965849b752495 --- /dev/null +++ b/arch/z80/src/ez80/Toolchain.defs @@ -0,0 +1,47 @@ +############################################################################ +# arch/z80/src/ez80/Toolchain.defs +# +# Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# The ZiLOG ZDS-II Windows toolchain is the only toolchain available for +# the ez80. +# + +CONFIG_EZ80_TOOLCHAIN ?= ZDSII + +ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y +endif diff --git a/arch/z80/src/ez80/chip.h b/arch/z80/src/ez80/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..637a0cd3e0263a90e173e4501e618f4194c21f19 --- /dev/null +++ b/arch/z80/src/ez80/chip.h @@ -0,0 +1,98 @@ +/************************************************************************************ + * arch/z80/src/ez80/chip.h + * arch/z80/src/chip/chip.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_EZ80_CHIP_H +#define __ARCH_Z80_SRC_EZ80_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Bits in the Z80 FLAGS register ***************************************************/ + +#define EZ80_C_FLAG 0x01 /* Bit 0: Carry flag */ +#define EZ80_N_FLAG 0x02 /* Bit 1: Add/Subtract flag */ +#define EZ80_PV_FLAG 0x04 /* Bit 2: Parity/Overflow flag */ +#define EZ80_H_FLAG 0x10 /* Bit 4: Half carry flag */ +#define EZ80_Z_FLAG 0x40 /* Bit 5: Zero flag */ +#define EZ80_S_FLAG 0x80 /* Bit 7: Sign flag */ + +/* Include chip-specific regiser definitions */ + +#if defined(CONFIG_ARCH_CHIP_EZ80F91) +# include "ez80f91.h" +#elif defined(CONFIG_ARCH_CHIP_EZ80F92) +# include "ez80f92.h" +#elif defined(CONFIG_ARCH_CHIP_EZ80F93) +# include "ez80f93.h" +#else +# error "Register definitions not provided for this chip" +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN uint32_t ez80_systemclock; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_SRC_EZ80_CHIP_H */ diff --git a/arch/z80/src/ez80/ez80_clock.c b/arch/z80/src/ez80/ez80_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..1fd3afb591335923467bea87df0b101fff0eb5c6 --- /dev/null +++ b/arch/z80/src/ez80/ez80_clock.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_clock.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arch/board/board.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t ez80_systemclock = EZ80_SYS_CLK_FREQ; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/z80/src/ez80/ez80_copystate.c b/arch/z80/src/ez80/ez80_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..06670bca61ab6caaf8f172debe114f75e1155f52 --- /dev/null +++ b/arch/z80/src/ez80/ez80_copystate.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_copystate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_copystate + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +void ez80_copystate(chipreg_t *dest, const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/z80/src/ez80/ez80_emac.c b/arch/z80/src/ez80/ez80_emac.c new file mode 100644 index 0000000000000000000000000000000000000000..2b1b5834fec8112a72d9b9b5446bed9942921636 --- /dev/null +++ b/arch/z80/src/ez80/ez80_emac.c @@ -0,0 +1,2340 @@ +/**************************************************************************** + * drivers/net/ez80_emac.c + * + * Copyright (C) 2009-2010, 2012, 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * eZ80F91 MCU Product Specification, PS019214-0808, Zilig, Inc., 2008. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_EZ80_EMAC) + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_EZ80_RAMADDR +# define CONFIG_EZ80_RAMADDR EZ80_EMACSRAM +#endif + +#if CONFIG_NET_ETH_MTU > 1518 +# error "MAXF size too big for this device" +#endif + +/* The memory region shared between this driver and the EMAC hardware + * is subdivided into a Transmit buffer and the Receive buffer. + * The Transmit and Receive buffers are subdivided into packet buffers + * of 32, 64, 128, or 256 bytes in size. + */ + +#ifndef CONFIG_EZ80_PKTBUFSIZE +# define CONFIG_EZ80_PKTBUFSIZE 64 +#endif + +#ifndef CONFIG_EZ80_NTXPKTBUFS +# define CONFIG_EZ80_NTXPKTBUFS 64 +#endif + +#ifndef CONFIG_EZ80_NRXPKTBUFS +# define CONFIG_EZ80_NRXPKTBUFS 64 +#endif + +#define EMAC_TXBUFSIZE (CONFIG_EZ80_PKTBUFSIZE * CONFIG_EZ80_NTXPKTBUFS) +#if EMAC_TXBUFSIZE > 8192 +# error "Too many TX buffers" +#endif + +#define EMAC_RXBUFSIZE (CONFIG_EZ80_PKTBUFSIZE * CONFIG_EZ80_NRXPKTBUFS) +#if EMAC_RXBUFSIZE > 8192 +# error "Too many TX buffers" +#endif + +#define EMAC_TOTAL_BUFSIZE (EMAC_TXBUFSIZE + EMAC_RXBUFSIZE) +#if EMAC_TOTAL_BUFSIZE > 8192 +# error "Too many TX+RX buffers" +#elif EMAC_TOTAL_BUFSIZE < 8192 +# error "Unused buffers!" +#endif + +#if CONFIG_EZ80_PKTBUFSIZE == 256 +# define EMAC_BUFSZ EMAC_BUFSZ_256b +# define EMAC_PKTBUF_SHIFT 8 +#elif CONFIG_EZ80_PKTBUFSIZE == 128 +# define EMAC_BUFSZ EMAC_BUFSZ_128b +# define EMAC_PKTBUF_SHIFT 7 +#elif CONFIG_EZ80_PKTBUFSIZE == 64 +# define EMAC_BUFSZ EMAC_BUFSZ_64b +# define EMAC_PKTBUF_SHIFT 6 +#elif CONFIG_EZ80_PKTBUFSIZE == 32 +# define EMAC_BUFSZ EMAC_BUFSZ_32b +# define EMAC_PKTBUF_SHIFT 5 +#else +# error "Unsupported CONFIG_EZ80_PKTBUFSIZE value" +#endif + +#define EMAC_PKTBUF_MASK (CONFIG_EZ80_PKTBUFSIZE - 1) +#define EMAC_PKTBUF_ALIGN(a) (((a) + EMAC_PKTBUF_MASK - 1) & ~EMAC_PKTBUF_MASK) + +/* Am79c874 PHY configuration */ + +#define EZ80_EMAC_AUTONEG 0 +#define EZ80_EMAC_100BFD 1 +#define EZ80_EMAC_100BHD 2 +#define EZ80_EMAC_10BFD 3 +#define EZ80_EMAC_10BHD 4 + +#ifndef CONFIG_EZ80_PHYCONFIG +# define CONFIG_EZ80_PHYCONFIG EZ80_EMAC_10BFD +#endif + +/* Select the fastest MDC clock that does not exceed 25MHz. The MDC + * clock derives from the SCLK divided by 4, 6, 8, 10, 14, 20, or 28. + */ + +#ifndef CONFIG_EZ80_MDCDIV +# ifdef CONFIG_ETH0_PHY_AM79C874 +# define CONFIG_EZ80_MDCDIV EMAC_MDC_DIV20 +# else +# define CONFIG_EZ80_MDCDIV EMAC_MDC_DIV4 +# endif +#endif + +/* Select the Tx poll timer. If not specified, a 10MS timer is set */ + +#ifndef CONFIG_EZ80_TXPOLLTIMERMS +# define CONFIG_EZ80_TXPOLLTIMERMS 10 +#endif + +/* Misc. timing values and settings */ + +#define EMAC_MXPOLLLOOPS 100000 +#define EMAC_CRCPOLY2 0xedb88320; + +/* Default register settings */ + +#define EMAC_TPTV 0x1000 /* TPTV: Default 0x1000 slot time (1slot:512bit) */ +#define EMAC_IPGT 0x12 /* IPGT: Back-to-back IPG default value */ +#define EMAC_IPGR1 0x0c /* IPGR1: Non-back-to-back IPG default value */ +#define EMAC_IPGR2 0x12 /* IPGR2: Non-back-to-back IPG default value */ +#define EMAC_MAXF 0x0600 /* Maximum packet length value (reset value) */ +#define EMAC_LCOL 0x37 /* CFG2: Late collision window default value */ +#define EMAC_RETRY 0x0f /* CFG3: Maximum number of retry default value */ + +/* Poll timer setting. The transmit poll timer is set in increments of + * SYSCLCK / 256. NOTE: The system clock frequency is defined in the board.h file. + */ + +#define EMAC_PTMR ((CONFIG_EZ80_TXPOLLTIMERMS * (ez80_systemclock / 1000) >> 8)) + + /* EMAC system interrupts : + * + * EMAC_ISTAT_TXFSMERR - Bit 7: 1=Transmit state machine error interrupt + * A Transmit State Machine Error should never occur. However, if this + * bit is set, the entire transmitter module must be reset. + * EMAC_ISTAT_MGTDONE - Bit 6: 1=MII Mgmt done interrupt + * This bit is set when communicating to the PHY over the MII during + * a Read or Write operation. + * EMAC_ISTAT_RXOVR - Bit 2: 1=Receive overrun interrupt + * If this bit is set, all incoming packets are ignored until + * this bit is cleared by software. + */ + +#define EMAC_ISTAT_SYSEVENTS (EMAC_ISTAT_TXFSMERR|EMAC_ISTAT_MGTDONE|EMAC_ISTAT_RXOVR) + + /* EMAC Tx interrupts: + * + * EMAC_ISTAT_TXDONE - Bit 0: 1=Transmit done interrupt + * Denotes when packet transmission is complete. + * EMAC_ISTAT_TXCF - Bit 1: 1=Transmit control frame interrupt + * Denotes when control frame transmission is complete. + */ + +#define EMAC_ISTAT_TXEVENTS (EMAC_ISTAT_TXDONE|EMAC_ISTAT_TXCF) + + /* EMAC Rx interrupts: + * + * EMAC_ISTAT_RXDONE - Bit 3: 1=Receive done interrupt + * Denotes when packet reception is complete. + * EMAC_ISTAT_RXPCF - Bit 4: 1=Receive pause control frame interrupt + * Denotes when pause control frame reception is complete. + * EMAC_ISTAT_RXCF - Bit 5: 1=Receive control frame interrupt + * Denotes when control frame reception is complete. + */ + +#define EMAC_ISTAT_RXEVENTS (EMAC_ISTAT_RXDONE|EMAC_ISTAT_RXPCF|EMAC_ISTAT_RXCF) +#define EMAC_EIN_HANDLED (EMAC_ISTAT_RXEVENTS|EMAC_ISTAT_TXEVENTS|EMAC_ISTAT_SYSEVENTS) + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define EMAC_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define EMAC_TXTIMEOUT (60*CLK_TCK) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define ETHBUF ((struct eth_hdr_s *)priv->dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* EMAC statistics (debug only) */ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) +struct ez80mac_statistics_s +{ + uint32_t rx_int; /* Number of Rx interrupts received */ + uint32_t rx_packets; /* Number of packets received (sum of the following): */ +#ifdef CONFIG_NET_IPv4 + uint32_t rx_ip; /* Number of Rx IPv4 packets received */ +#endif +#ifdef CONFIG_NET_IPv6 + uint32_t rx_ipv6; /* Number of Rx IPv6 packets received */ +#endif + uint32_t rx_arp; /* Number of Rx ARP packets received */ + uint32_t rx_dropped; /* Number of dropped, unsupported Rx packets */ + uint32_t rx_nok; /* Number of Rx packets received without OK bit */ + uint32_t rx_errors; /* Number of Rx errors (rx_overerrors + rx_nok) */ + uint32_t rx_ovrerrors; /* Number of FIFO overrun errors */ + uint32_t tx_int; /* Number of Tx interrupts received */ + uint32_t tx_packets; /* Number of Tx descriptors queued */ + uint32_t tx_errors; /* Number of Tx errors (sum of the following) */ + uint32_t tx_abterrors; /* Number of aborted Tx descriptors */ + uint32_t tx_fsmerrors; /* Number of Tx state machine errors */ + uint32_t tx_timeouts; /* Number of Tx timeout errors */ + uint32_t sys_int; /* Number of system interrupts received */ +}; +# define _MKFIELD(a,b,c) a->b##c +# define EMAC_STAT(priv,name) _MKFIELD(priv,stat.,name)++ +#else +# define EMAC_STAT(priv,name) +#endif + +/* Private driver data. The ez80emac_driver_s encapsulates all state information + * for a single hardware interface + */ + +struct ez80emac_driver_s +{ + /* Tx buffer management + * + * txstart: The beginning of the Rx descriptor list (and also the beginning of + * Tx/Rx memory). + * txhead: Points to the oldest Tx descriptor queued for output (but for + * which output has not yet completed. Initialized to NULL; set + * by ez80emac_transmit() when Tx is started and by ez80emac_txinterrupt() + * when Tx processing completes. txhead == NULL is also a sure + * indication that there is no Tx in progress. + * txnext: Points to the next free Tx descriptor. Initialized to txstart; set + * when ez80emac_transmit() adds the descriptor; reset to txstart when the + * last Tx packet is sent. + */ + + FAR struct ez80emac_desc_s *txstart; + FAR struct ez80emac_desc_s *txhead; + FAR struct ez80emac_desc_s *txnext; + + /* Rx buffer management + * + * rxstart: The beginning of the Rx descriptor list (and also the end of + * Tx buffer + 1). + * rxnext: The next of Rx descriptor available for receipt of a packet. + * Initialized to rxstart; rxnext is incremented by rmac_rxinterrupt() + * as part of Rx interrupt processing. rxnext wraps back to rxstart + * when rxnext exceeds rxendp1. + * rxendp1: The end of the Rx descriptor list + 1. + */ + + FAR struct ez80emac_desc_s *rxstart; + FAR struct ez80emac_desc_s *rxnext; + FAR struct ez80emac_desc_s *rxendp1; + + bool bifup; /* true:ifup false:ifdown */ + bool blinkok; /* true:successful MII autonegotiation */ + bool bfullduplex; /* true:full duplex */ + bool b100mbs; /* true:100Mbp */ + + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) + struct ez80mac_statistics_s stat; +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* There is only a single instance of driver private data (because there is + * only one EMAC interface. + */ + +static struct ez80emac_driver_s g_emac; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* MII logic */ + +static void ez80emac_waitmiibusy(void); +static void ez80emac_miiwrite(FAR struct ez80emac_driver_s *priv, uint8_t offset, + uint16_t value); +static uint16_t ez80emac_miiread(FAR struct ez80emac_driver_s *priv, uint32_t offset); +static bool ez80emac_miipoll(FAR struct ez80emac_driver_s *priv, uint32_t offset, + uint16_t bits, bool bclear); +static int ez80emac_miiconfigure(FAR struct ez80emac_driver_s *priv); + +/* Multi-cast filtering */ + +#ifdef CONFIG_EZ80_MCFILTER +static void ez80emac_machash(FAR uint8_t *mac, int *ndx, int *bitno) +#endif + +/* TX/RX logic */ + +static int ez80emac_transmit(struct ez80emac_driver_s *priv); +static int ez80emac_txpoll(struct net_driver_s *dev); + +static inline FAR struct ez80emac_desc_s *ez80emac_rwp(void); +static inline FAR struct ez80emac_desc_s *ez80emac_rrp(void); +static int ez80emac_receive(struct ez80emac_driver_s *priv); + +/* Interrupt handling */ + +static int ez80emac_txinterrupt(int irq, FAR void *context); +static int ez80emac_rxinterrupt(int irq, FAR void *context); +static int ez80emac_sysinterrupt(int irq, FAR void *context); + +/* Watchdog timer expirations */ + +static void ez80emac_polltimer(int argc, uint32_t arg, ...); +static void ez80emac_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int ez80emac_ifup(struct net_driver_s *dev); +static int ez80emac_ifdown(struct net_driver_s *dev); +static int ez80emac_txavail(struct net_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int ez80emac_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int ez80emac_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +#endif + +/* Initialization */ + +static int ez80_emacinitialize(void); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: ez80emac_waitmiibusy + * + * Description: + * Wait for the MII to become available. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80emac_waitmiibusy(void) +{ + /* Wait for any preceding MII management operation to complete */ + + while ((inp(EZ80_EMAC_MIISTAT) & EMAC_MIISTAT_BUSY) != 0); +} + +/**************************************************************************** + * Function: ez80emac_miiwrite + * + * Description: + * Write a signel MII register + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Register offset in PMD + * value - Value to write + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80emac_miiwrite(FAR struct ez80emac_driver_s *priv, uint8_t offset, uint16_t value) +{ + uint8_t regval; + + /* Wait for any preceding MII management operation to complete */ + + ez80emac_waitmiibusy(); + + /* Set up PHY addressing */ + + outp(EZ80_EMAC_FIAD, CONFIG_EZ80_FIAD & EMAC_FIAD_MASK); + outp(EZ80_EMAC_RGAD, offset & EMAC_RGAD_MASK); + + /* Write the control data */ + + outp(EZ80_EMAC_CTLD_H, value >> 8); + outp(EZ80_EMAC_CTLD_L, value & 0xff); + + /* Send control data to PHY */ + + regval = inp(EZ80_EMAC_MIIMGT); + regval |= EMAC_MIIMGMT_LCTLD; + outp(EZ80_EMAC_MIIMGT, regval); +} + +/**************************************************************************** + * Function: ez80emac_miiread + * + * Description: + * Read a single MII register + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Register offset in PMD + * + * Returned Value: + * Value read from the register + * + ****************************************************************************/ + +static uint16_t ez80emac_miiread(FAR struct ez80emac_driver_s *priv, uint32_t offset) +{ + uint8_t regval; + + /* Wait for any preceding MII management operation to complete */ + + ez80emac_waitmiibusy(); + + /* Set up PHY addressing */ + + outp(EZ80_EMAC_FIAD, CONFIG_EZ80_FIAD & EMAC_FIAD_MASK); + outp(EZ80_EMAC_RGAD, offset & EMAC_RGAD_MASK); + + /* Read status from PHY */ + + regval = inp(EZ80_EMAC_MIIMGT); + regval |= EMAC_MIIMGMT_RSTAT; + outp(EZ80_EMAC_MIIMGT, regval); + + /* Wait for MII management operation to complete */ + + ez80emac_waitmiibusy(); + return ((uint16_t)inp(EZ80_EMAC_PRSD_H) << 8 | inp(EZ80_EMAC_PRSD_L)); +} + +/**************************************************************************** + * Function: ez80emac_miipoll + * + * Description: + * Read an MII register until the bit has the specified polarity (or until + * the maximum number of retries occurs + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Register offset in PMD + * bits - Selects set of bits to wait for + * bclear - true:Return true when all bits in 'bits' are 0 + * false:Return true when one or more bits in 'bits' are 1 + * + * Returned Value: + * true:Bit has requested polarity; false: EMAC_MXPOLLLOOPS exceeded + * + ****************************************************************************/ + +static bool ez80emac_miipoll(FAR struct ez80emac_driver_s *priv, uint32_t offset, + uint16_t bits, bool bclear) +{ + uint16_t value; + int i; + + for (i = 0; i < EMAC_MXPOLLLOOPS; i++) + { + value = ez80emac_miiread(priv, offset); + if (bclear) + { + if ((value & bits) == 0) + { + return true; + } + } + else + { + if ((value & bits) != 0) + { + return true; + } + } + } + return false; +} + +/**************************************************************************** + * Function: ez80emac_miiconfigure + * + * Description: + * Dump all MII registers + * + * Parameters: + * priv - Reference to the driver state structure + * offset - Register offset in PMD + * bits - Selects set of bits to wait for + * bclear - true:Return true when all bits in 'bits' are 0 + * false:Return true when one or more bits in 'bits' are 1 + * + * Returned Value: + * true:Bit has requested polarity; false: EMAC_MXPOLLLOOPS exceeded + * + ****************************************************************************/ + +#ifdef CONFIG_ETH0_PHY_AM79C874 +static int ez80emac_miiconfigure(FAR struct ez80emac_driver_s *priv) +{ + uint16_t phyval; + bool bauto; + int ret = OK; + int i; + + /* Verify that the detect PHY is an AMD Am87c874 as expected */ + +#ifdef CONFIG_DEBUG /* Parameter checking only done when DEBUG is enabled */ + phyval = ez80emac_miiread(priv, MII_PHYID1); + if (phyval != MII_PHYID1_AM79C874) + { + ndbg("Not an Am79c874 PHY: PHY1=%04x vs %04x\n", phyval, MII_PHYID1_AM79C874); + ret = -ENODEV; + goto dumpregs; + } + + phyval = ez80emac_miiread(priv, MII_PHYID2); + if (phyval != MII_PHYID2_AM79C874) + { + ndbg("Not an Am79c874 PHY: PHY2=%04x vs %04x\n", phyval, MII_PHYID2_AM79C874); + ret = -ENODEV; + goto dumpregs; + } +#endif + + /* Check if the PHY can do auto-negotiation */ + + phyval = ez80emac_miiread(priv, MII_MSR); + if (phyval & MII_MSR_ANEGABLE) + { + phyval = MII_MCR_ANRESTART | MII_MCR_ANENABLE; + bauto = true; + } + else + { + phyval = 0; + bauto = false; + + /* PADEN - EMAC pads all short frames by adding zeroes to the end of + * the data field. This bit is used in conjunction with ADPADN + * and VLPAD. + * CRCEN - Append CRC to every frame regardless of padding options. + */ + + outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN); + } + + /* Set the configured link capabilities */ + +#if CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_AUTONEG + + ndbg("Configure autonegotiation\n"); + if (bauto) + { + ez80emac_miiwrite(priv, MII_ADVERTISE, + MII_ADVERTISE_100BASETXFULL|MII_ADVERTISE_100BASETXHALF| + MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF| + MII_ADVERTISE_CSMA); + } + else + { + ndbg("Am79c784 is not capable of autonegotiation\n"); + } + +#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_100BFD + + ndbg("100BASETX full duplex\n"); + phyval |= MII_MCR_SPEED100 | MII_MCR_FULLDPLX; + ez80emac_miiwrite(priv, MII_ADVERTISE, + MII_ADVERTISE_100BASETXFULL|MII_ADVERTISE_100BASETXHALF| + MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF| + MII_ADVERTISE_CSMA); + +#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_100BHD + + ndbg("100BASETX half duplex\n"); + phyval |= MII_MCR_SPEED100; + ez80emac_miiwrite(priv, MII_ADVERTISE, + MII_ADVERTISE_100BASETXHALF|MII_ADVERTISE_10BASETXFULL| + MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA); + +#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_10BFD + + ndbg("10BASETX full duplex\n"); + phyval |= MII_MCR_FULLDPLX; + ez80emac_miiwrite(priv, MII_ADVERTISE, + MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA); + +#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_10BHD + + ndbg("10BASETX half duplex\n"); + ez80emac_miiwrite(priv, MII_ADVERTISE, + MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA); + +#else +# error "No recognized value of CONFIG_EZ80_PHYCONFIG" +#endif + + ez80emac_miiwrite(priv, MII_MCR, phyval); + + /* Wait for a link to be established */ + + for (i = 0; i < 50; i++) + { + phyval = ez80emac_miiread(priv, MII_MSR); + if ((phyval & (MII_MSR_ANEGCOMPLETE | MII_MSR_LINKSTATUS)) != 0) + { + break; + } + up_mdelay(10); + } + + if ((phyval & MII_MSR_LINKSTATUS) == 0) + { + ndbg("Failed to establish link\n"); + ret = -ETIMEDOUT; + } + else + { + /* Read the Am79c874 diagnostics register for link settings */ + + phyval = ez80emac_miiread(priv, MII_AM79C874_DIAGNOSTIC); + if (phyval & AM79C874_DIAG_FULLDPLX) + { + outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN|EMAC_CFG1_FULLHD); + } + else + { + outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN); + } + } + +dumpregs: + nvdbg("Am79c874 MII registers (FIAD=%lx)\n", CONFIG_EZ80_FIAD); + nvdbg(" MII_MCR: %04x\n", ez80emac_miiread(priv, MII_MCR)); + nvdbg(" MII_MSR: %04x\n", ez80emac_miiread(priv, MII_MSR)); + nvdbg(" MII_PHYID1: %04x\n", ez80emac_miiread(priv, MII_PHYID1)); + nvdbg(" MII_PHYID2: %04x\n", ez80emac_miiread(priv, MII_PHYID2)); + nvdbg(" MII_ADVERTISE: %04x\n", ez80emac_miiread(priv, MII_ADVERTISE)); + nvdbg(" MII_LPA: %04x\n", ez80emac_miiread(priv, MII_LPA)); + nvdbg(" MII_EXPANSION: %04x\n", ez80emac_miiread(priv, MII_EXPANSION)); + nvdbg(" MII_DIAGNOSTICS: %04x\n", ez80emac_miiread(priv, MII_AM79C874_DIAGNOSTIC)); + nvdbg("EMAC CFG1: %02x\n", inp(EZ80_EMAC_CFG1)); + return ret; +} +#else +static int ez80emac_miiconfigure(FAR struct ez80emac_driver_s *priv) +{ + uint16_t advertise; + uint16_t lpa; + uint16_t mcr; + uint8_t regval; + + /* Start auto-negotiation */ + + ez80emac_miiwrite(priv, MII_MCR, 0); + ez80emac_miiwrite(priv, + MII_MCR, + MII_MCR_ANENABLE | MII_MCR_ANRESTART | MII_MCR_FULLDPLX | MII_MCR_SPEED100); + + /* Wait for auto-negotiation to start */ + + if (!ez80emac_miipoll(priv, MII_MCR, MII_MCR_ANRESTART, false)) + { + ndbg("Autonegotiation didn't start.\n"); + } + + /* Wait for auto-negotiation to complete */ + + if (!ez80emac_miipoll(priv, MII_MSR, MII_MSR_ANEGCOMPLETE, true)) + { + ndbg("Autonegotiation didn't complete.\n"); + } + + /* Wait link */ + + if (!ez80emac_miipoll(priv, MII_MSR, MII_MSR_LINKSTATUS, true)) + { + ndbg("Link is down!\n"); + priv->blinkok = false; + } + else + { + priv->blinkok = true; + } + + /* Read capable media type */ + + up_udelay(500); + advertise = ez80emac_miiread(priv, MII_ADVERTISE); + lpa = ez80emac_miiread(priv, MII_LPA); + + /* Check for 100BASETX full duplex */ + + if ((advertise & MII_ADVERTISE_100BASETXFULL) && (lpa & MII_LPA_100BASETXFULL)) + { + ndbg("100BASETX full duplex\n"); + regval = inp(EZ80_EMAC_CFG1); + regval |= EMAC_CFG1_FULLHD; /* Enable full duplex mode */ + outp(EZ80_EMAC_CFG1, regval); + priv->b100mbs = true; + priv->bfullduplex = true; + } + + /* Check for 100BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_100BASETXHALF) && (lpa & MII_LPA_100BASETXHALF)) + { + ndbg("100BASETX half duplex\n"); + regval = inp(EZ80_EMAC_CFG1); + regval &= ~EMAC_CFG1_FULLHD; /* Disable full duplex mode */ + outp(EZ80_EMAC_CFG1, regval); + priv->b100mbs = true; + priv->bfullduplex = false; + } + + /* Check for 10BASETX full duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXFULL) && (lpa & MII_LPA_10BASETXFULL)) + { + ndbg("10BASETX full duplex\n"); + regval = inp(EZ80_EMAC_CFG1); + regval |= EMAC_CFG1_FULLHD; /* Enable full duplex mode */ + outp(EZ80_EMAC_CFG1, regval); + priv->b100mbs = false; + priv->bfullduplex = true; + } + + /* Check for 10BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXHALF) && (lpa & MII_LPA_10BASETXHALF)) + { + ndbg("10BASETX half duplex\n"); + regval = inp(EZ80_EMAC_CFG1); + regval &= ~EMAC_CFG1_FULLHD; /* Disable full duplex mode */ + outp(EZ80_EMAC_CFG1, regval); + priv->b100mbs = false; + priv->bfullduplex = false; + } + else + { + ndbg("No valid connection; force 10Mbps half-duplex.\n"); + regval = inp(EZ80_EMAC_CFG1); + regval &= ~EMAC_CFG1_FULLHD; /* Disable full duplex mode */ + outp(EZ80_EMAC_CFG1, regval); + priv->b100mbs = false; + priv->bfullduplex = false; + } + + /* Set MII control */ + + mcr = ez80emac_miiread(priv, MII_MCR); + if (priv->bfullduplex) + { + mcr |= MII_MCR_FULLDPLX; + } + else + { + mcr &= ~MII_MCR_FULLDPLX; + } + if (priv->b100mbs) + { + mcr |= MII_MCR_SPEED100; + } + else + { + mcr &= ~MII_MCR_SPEED100; + } + mcr |= MII_MCR_ANENABLE; + ez80emac_miiwrite(priv, MII_MCR, mcr); + + nvdbg("MII registers (FIAD=%lx)\n", CONFIG_EZ80_FIAD); + nvdbg(" MII_MCR: %04x\n", ez80emac_miiread(priv, MII_MCR)); + nvdbg(" MII_MSR: %04x\n", ez80emac_miiread(priv, MII_MSR)); + nvdbg(" MII_PHYID1: %04x\n", ez80emac_miiread(priv, MII_PHYID1)); + nvdbg(" MII_PHYID2: %04x\n", ez80emac_miiread(priv, MII_PHYID2)); + nvdbg(" MII_ADVERTISE: %04x\n", ez80emac_miiread(priv, MII_ADVERTISE)); + nvdbg(" MII_LPA: %04x\n", ez80emac_miiread(priv, MII_LPA)); + nvdbg(" MII_EXPANSION: %04x\n", ez80emac_miiread(priv, MII_EXPANSION)); + nvdbg("EMAC CFG1: %02x\n", inp(EZ80_EMAC_CFG11)); + return OK; +} +#endif + +/**************************************************************************** + * Function: ez80emac_machash + * + * Description: + * Given a MAC address, perform the CRC32 calculation and return the + * index and bit number for the multi-cast hash table. + * + * Parameters: + * priv - Reference to the driver state structure + * mac - The MAC address to add + * enable - true: Enable filtering on this address; false: disable + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_EZ80_MCFILTER +static void ez80emac_machash(FAR uint8_t *mac, int *ndx, int *bitno) +{ + uint32_t hash; + uint32_t crc32; + int i; + int j; + + /* Calculate the CRC32 value on the MAC address */ + + crc32 = 0xffffffff; + for (i = 0; i < 6; i++) + { + crc32 ^= (uint32_t)mac[i] & 0x0f; + for (j = 0; j < 4; j++) + { + if (crc32 & 1) + { + crc32 = (crc32 >> 1) ^ EMAC_CRCPOLY2; + } + else + { + crc32 >>= 1; + } + } + + crc32 ^= (uint32_t)mac[i] >> 4; + for (j = 0; j < 4; j++) + { + if (crc32 & 1) + { + crc32 = (crc32 >> 1) ^ EMAC_CRCPOLY2; + } + else + { + crc32 >>= 1; + } + } + } + + /* The normal CRC result would be the complement of crc32, + * the following calculates the EMAC hash value + * + * This loop changes the bit ordering the for bits [23:28] of + * the CRC32 value to -> [0:5] + */ + + crc32 &= 0x000001f8; + hash = 0; + + for (j = 31; j >= 23; j--) + { + hash = (hash << 1) + (crc32 & 1); + crc32 >>= 1; + } + + *ndx = (hash >> 3) & 7; + *bitno = hash & 7; +} +#endif + +/**************************************************************************** + * Function: ez80emac_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int ez80emac_transmit(struct ez80emac_driver_s *priv) +{ + FAR struct ez80emac_desc_s *txdesc; + FAR struct ez80emac_desc_s *txnext; + uint8_t *psrc; + uint8_t *pdest; + uint24_t len; + irqstate_t flags; + uint8_t regval; + + /* Careful: This function can be called from outside of the interrupt + * handler and, therefore, may be suspended when debug output is generated! + */ + + nllvdbg("txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", + priv->txnext, priv->txnext->np, priv->txnext->pktsize, priv->txnext->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + + /* Increment statistics */ + + flags = enter_critical_section(); + EMAC_STAT(priv, tx_packets); + + /* The current packet to be sent is txnext; Calculate the new txnext and + * set the ownership to host so that the EMAC does not try to transmit + * the next packet. + * + * The new txnext will be the current txnext plus the size of the descriptor + * header plus the size of the data to be transferred, aligned up to the next + * packet buffer size. NOTE: that there is no check to see if we have + * overran the EMAC buffer -- i.e., if the next txnext has not yet been + * tranmitted. + */ + + txdesc = priv->txnext; + + len = EMAC_PKTBUF_ALIGN(priv->dev.d_len + SIZEOF_EMACSDESC); + txnext = (FAR struct ez80emac_desc_s *)((uint8_t*)txdesc + len); + + /* Handle wraparound to the beginning of the TX region */ + + if ((uint8_t*)txnext + SIZEOF_EMACSDESC >= (uint8_t*)priv->rxstart) + { + txnext = (FAR struct ez80emac_desc_s *) + ((uint8_t*)priv->txstart + ((uint8_t*)txnext - (uint8_t*)priv->rxstart)); + } + + priv->txnext = txnext; + txnext->np = 0; + txnext->pktsize = 0; + txnext->stat = 0; /* Bit 15: 0=Host (eZ80 CPU) owns, 1=EMAC owns. */ + + /* Copy the data to the next packet in the Tx buffer (handling wraparound) */ + + psrc = priv->dev.d_buf; + pdest = (uint8_t*)txdesc + SIZEOF_EMACSDESC; + len = (uint8_t*)priv->rxstart - pdest; + if (len >= priv->dev.d_len) + { + /* The entire packet will fit into the EMAC SRAM without wrapping */ + + memcpy(pdest, psrc, priv->dev.d_len); + } + else + { + /* Handle wrap to the beginning of the buffer */ + + memcpy(pdest, psrc, len); + memcpy(priv->txstart, &psrc[len], (priv->dev.d_len - len)); + } + + if (!priv->txhead) + { + /* There are no pending TX actions. This descriptor is the new head */ + + priv->txhead = txdesc; + } + + /* Then, give ownership of the descriptor to the hardware. It should + * perform the transmission on its next polling cycle. + */ + + txdesc->np = (uint24_t)priv->txnext; + txdesc->pktsize = priv->dev.d_len; + txdesc->stat = EMAC_TXDESC_OWNER; + + /* Enable the TX poll timer. The poll timer may alread be running. In that + * case, this will force the hardware to poll again now + */ + + outp(EZ80_EMAC_PTMR, EMAC_PTMR); + leave_critical_section(flags); + + nllvdbg("txdesc=%p {%06x, %u, %04x}\n", + txdesc, txdesc->np, txdesc->pktsize, txdesc->stat); + nllvdbg("txnext=%p {%06x, %u, %04x} trp=%02x%02x\n", + txnext, txnext->np, txnext->pktsize, txnext->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, EMAC_TXTIMEOUT, ez80emac_txtimeout, 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: ez80emac_txpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from devif_poll(). devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int ez80emac_txpoll(struct net_driver_s *dev) +{ + struct ez80emac_driver_s *priv = (struct ez80emac_driver_s *)dev->d_private; + int ret = 0; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + nvdbg("Poll result: d_len=%d\n", priv->dev.d_len); + if (priv->dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet. ez80emac_transmit() will return zero if the + * packet was successfully handled. + */ + + ret = ez80emac_transmit(priv); + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: ez80emac_rwp + * + * Description: + * Get the eZ80 RWP value + * + * Parameters: + * None + * + * Returned Value: + * The current RWP value expressed as a pointer to a descriptor + * + ****************************************************************************/ + +static inline FAR struct ez80emac_desc_s *ez80emac_rwp(void) +{ + return (FAR struct ez80emac_desc_s *) + (CONFIG_EZ80_RAMADDR + ((uint24_t)inp(EZ80_EMAC_RWP_H) << 8) + (uint24_t)inp(EZ80_EMAC_RWP_L)); +} + +/**************************************************************************** + * Function: ez80emac_rrp + * + * Description: + * Get the eZ80 RRP value + * + * Parameters: + * None + * + * Returned Value: + * The current RRP value expressed as a pointer to a descriptor + * + ****************************************************************************/ + +static inline FAR struct ez80emac_desc_s *ez80emac_rrp(void) +{ + return (FAR struct ez80emac_desc_s *) + (CONFIG_EZ80_RAMADDR + ((uint24_t)inp(EZ80_EMAC_RRP_H) << 8) + (uint24_t)inp(EZ80_EMAC_RRP_L)); +} + +/**************************************************************************** + * Function: ez80emac_receive + * + * Description: + * Process received packets pending in the RX buffer + * + * Parameters: + * priv - Driver data instance + * + * Returned Value: + * 0: Success, but nothing received + * >0: Success, number of packets received + * <0: ERROR, negated error number + * + * Returned Value: + * Interrupts are disabled + * + ****************************************************************************/ + +static int ez80emac_receive(struct ez80emac_driver_s *priv) +{ + FAR struct ez80emac_desc_s *rxdesc = priv->rxnext; + FAR struct ez80emac_desc_s *rwp; + uint8_t *psrc; + uint8_t *pdest; + int pktlen; + int npackets; + + /* The RRP register points to where the next Receive packet is read from. + * The read-only EMAC Receive Write Pointer (RWP) register reports the + * current RxDMA Receive Write pointer. The RxDMA block uses the RRP[12:5] + * to compare to RWP[12:5] for determining how many buffers remain. The + * result is the BLKSLFT register. + */ + + rwp = ez80emac_rwp(); + nvdbg("rxnext=%p {%06x, %u, %04x} rrp=%06x rwp=%06x blkslft=%02x\n", + rxdesc, rxdesc->np, rxdesc->pktsize, rxdesc->stat, + ez80emac_rrp(), rwp, + inp(EZ80_EMAC_BLKSLFT_H), inp(EZ80_EMAC_BLKSLFT_L)); + + /* The RxDMA reads the data from the RxFIFO and stores it in the EMAC + * memory Receive buffer. When the end of the packet is detected, the + * RxDMA reads the next two bytes from the RxFIFO and writes them into + * the Rx descriptor status LSB and MSB. The packet length counter is + * stored into the descriptor table packet length field, the descriptor + * table next pointer is written into the Rx descriptor table and finally + * the Rx_DONE_STAT bit in the EMAC Interrupt Status Register register is + * set to 1. + */ + + npackets = 0; + while (rxdesc != rwp) + { + DEBUGASSERT(rxdesc == ez80emac_rrp()); + EMAC_STAT(priv, rx_packets); + + /* Skip over bad packers */ + + if ((rxdesc->stat & EMAC_RXDESC_OK) == 0) + { + nvdbg("Skipping bad RX pkt: %04x\n", rxdesc->stat); + EMAC_STAT(priv, rx_errors); + EMAC_STAT(priv, rx_nok); + continue; + } + + /* We have a good packet. Check if the packet is a valid size + * for the uIP buffer configuration (I routinely see + */ + + if (rxdesc->pktsize > CONFIG_NET_ETH_MTU) + { + nvdbg("Truncated oversize RX pkt: %d->%d\n", rxdesc->pktsize, CONFIG_NET_ETH_MTU); + pktlen = CONFIG_NET_ETH_MTU; + } + else + { + pktlen = rxdesc->pktsize; + } + + /* Copy the data data from the hardware to priv->dev.d_buf */ + + psrc = (FAR uint8_t*)priv->rxnext + SIZEOF_EMACSDESC; + pdest = priv->dev.d_buf; + + /* Check for wraparound */ + + if ((FAR uint8_t*)(psrc + pktlen) > (FAR uint8_t*)priv->rxendp1) + { + int nbytes = (int)((FAR uint8_t*)priv->rxendp1 - (FAR uint8_t*)psrc); + nvdbg("RX wraps after %d bytes\n", nbytes + SIZEOF_EMACSDESC); + + memcpy(pdest, psrc, nbytes); + memcpy(&pdest[nbytes], priv->rxstart, pktlen - nbytes); + } + else + { + memcpy(pdest, psrc, pktlen); + } + + /* Set the amount of data in priv->dev.d_len */ + + priv->dev.d_len = pktlen; + + /* Reclaim the Rx descriptor */ + + priv->rxnext = (FAR struct ez80emac_desc_s *)rxdesc->np; + + rxdesc->np = 0; + rxdesc->pktsize = 0; + rxdesc->stat = 0; + + /* Update pointers */ + + rxdesc = priv->rxnext; + rwp = ez80emac_rwp(); + + /* Update the RRP to match our rxnext pointer: "For the hardware flow control + * to function properly, the software must update the hardare RRP (EmacRrp) + * pointer whenever the software version is upated. The RxDMA uses RWP + * and the RRP to determine how many packets remain in the Rx buffer. + */ + + outp(EZ80_EMAC_RRP_L, (uint8_t)((uint24_t)rxdesc & 0xff)); + outp(EZ80_EMAC_RRP_H, (uint8_t)(((uint24_t)rxdesc >> 8) & 0xff)); + + nvdbg("rxnext=%p {%06x, %u, %04x} rrp=%06x rwp=%06x blkslft=%02x\n", + rxdesc, rxdesc->np, rxdesc->pktsize, rxdesc->stat, + ez80emac_rrp(), rwp, + inp(EZ80_EMAC_BLKSLFT_H), inp(EZ80_EMAC_BLKSLFT_L)); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (ETHBUF->type == HTONS(ETHTYPE_IP)) + { + nllvdbg("IPv4 frame\n"); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + EMAC_STAT(priv, rx_ip); + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + ez80emac_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (ETHBUF->type == HTONS(ETHTYPE_IP6)) + { + nllvdbg("Iv6 frame\n"); + + /* Give the IPv6 packet to the network layer */ + + EMAC_STAT(priv, rx_ip); + ipv6_input(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->dev.d_flags)) + { + arp_out(&priv->dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->dev); + } +#endif + + /* And send the packet */ + + ez80emac_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (ETHBUF->type == htons(ETHTYPE_ARP)) + { + nvdbg("ARP packet received (%02x)\n", ETHBUF->type); + EMAC_STAT(priv, rx_arp); + + arp_arpin(&priv->dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->dev.d_len > 0) + { + ez80emac_transmit(priv); + } + } + else +#endif + { + ndbg("Unsupported packet type dropped (%02x)\n", ETHBUF->type); + EMAC_STAT(priv, rx_dropped); + } + + npackets++; + } + return npackets; +} + +/**************************************************************************** + * Function: ez80emac_txinterrupt + * + * Description: + * Process Rx-related interrupt events + * + * Parameters: + * priv - Driver data instance + * istat - Snapshot of ISTAT register containing Rx events to provess + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ez80emac_txinterrupt(int irq, FAR void *context) +{ + FAR struct ez80emac_driver_s *priv = &g_emac; + FAR struct ez80emac_desc_s *txhead = priv->txhead; + uint8_t regval; + uint8_t istat; + + /* EMAC Tx interrupts: + * + * EMAC_ISTAT_TXDONE - Bit 0: 1=Transmit done interrupt + * Denotes when packet transmission is complete. + * EMAC_ISTAT_TXCF - Bit 1: 1=Transmit control frame interrupt + * Denotes when control frame transmission is complete. + */ + + /* Get and clear Tx interrupt status bits */ + + istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_TXEVENTS; + outp(EZ80_EMAC_ISTAT, istat); + + EMAC_STAT(priv, tx_int); + + /* All events are packet/control frame transmit complete events */ + + nvdbg("txhead=%p {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", + txhead, txhead->np, txhead->pktsize, txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); + + /* Handle all packets in the list that are no longer owned by the hardware */ + + while (txhead && (txhead->stat & EMAC_TXDESC_OWNER) == 0) + { + if ((txhead->stat & EMAC_TXDESC_ABORT) != 0) + { + ndbg("Descriptor %p aborted {%06x, %u, %04x} trp=%02x%02x\n", + txhead, txhead->np, txhead->pktsize, txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + + EMAC_STAT(priv, tx_errors); + EMAC_STAT(priv, tx_abterrors); + } + + /* Get the address of the next Tx descriptor in the list (if any) */ + + txhead = (FAR struct ez80emac_desc_s *)txhead->np; + if (txhead) + { + nvdbg("txhead=%p {%06x, %u, %04x} trp=%02x%02x\n", + txhead, txhead->np, txhead->pktsize, txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + } + } + + /* Save the new head. If it is NULL, then we have read all the way to + * the terminating description with np==NULL. + */ + + priv->txhead = txhead; + if (!priv->txhead) + { + nvdbg("No pending Tx.. Stopping XMIT function.\n"); + + /* Stop the Tx poll timer. (It will get restarted when we have + * something to send + */ + + outp(EZ80_EMAC_PTMR, 0); + + /* Reset the transmit function. That should force the TRP to be + * the same as TDLP which is then set to txstart. + */ + +#if 0 // Seems to reset RWP as well ??? + priv->txnext = priv->txstart; + + regval = inp(EZ80_EMAC_RST); + regval |= EMAC_RST_HRTFN; + outp(EZ80_EMAC_RST, regval); + regval &= ~EMAC_RST_HRTFN; + outp(EZ80_EMAC_RST, regval); +#endif + + /* Cancel any pending the TX timeout */ + + wd_cancel(priv->txtimeout); + } + + return OK; +} + +/**************************************************************************** + * Function: ez80emac_rxinterrupt + * + * Description: + * Process Rx-related interrupt events + * + * Parameters: + * priv - Driver data instance + * istat - Snapshot of ISTAT register containing Rx events to provess + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int ez80emac_rxinterrupt(int irq, FAR void *context) +{ + FAR struct ez80emac_driver_s *priv = &g_emac; + uint8_t istat; + + /* EMAC Rx interrupts: + * + * EMAC_ISTAT_RXDONE - Bit 3: 1=Receive done interrupt + * Denotes when packet reception is complete. + * EMAC_ISTAT_RXPCF - Bit 4: 1=Receive pause control frame interrupt + * Denotes when pause control frame reception is complete. + * EMAC_ISTAT_RXCF - Bit 5: 1=Receive control frame interrupt + * Denotes when control frame reception is complete. + */ + + /* Get and clear Rx interrupt status bits */ + + istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_RXEVENTS; + outp(EZ80_EMAC_ISTAT, istat); + + EMAC_STAT(priv, rx_int); + + /* Process any RX packets pending the RX buffer */ + + (void)ez80emac_receive(priv); + return OK; +} + +/**************************************************************************** + * Function: ez80emac_sysinterrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int ez80emac_sysinterrupt(int irq, FAR void *context) +{ + FAR struct ez80emac_driver_s *priv = &g_emac; + uint8_t events; + uint8_t istat; + + /* EMAC system interrupts : + * + * EMAC_ISTAT_TXFSMERR - Bit 7: 1=Transmit state machine error interrupt + * A Transmit State Machine Error should never occur. However, if this + * bit is set, the entire transmitter module must be reset. + * EMAC_ISTAT_MGTDONE - Bit 6: 1=MII Mgmt done interrupt + * This bit is set when communicating to the PHY over the MII during + * a Read or Write operation. + * EMAC_ISTAT_RXOVR - Bit 2: 1=Receive overrun interrupt + * If this bit is set, all incoming packets are ignored until + * this bit is cleared by software. + */ + + EMAC_STAT(priv, sys_int); + + /* Get and clear system interrupt status bits */ + + istat = inp(EZ80_EMAC_ISTAT) & EMAC_ISTAT_SYSEVENTS; + outp(EZ80_EMAC_ISTAT, istat); + + /* Check for transmit state machine error */ + + if ((istat & EMAC_ISTAT_TXFSMERR) != 0) + { + ndbg("Tx FSMERR txhead=%p {%06x, %u, %04x} trp=%02x%02x istat=%02x\n", + priv->txhead, priv->txhead->np, priv->txhead->pktsize, priv->txhead->stat, + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L), istat); + + /* Increment statistics */ + + EMAC_STAT(priv, tx_errors); + EMAC_STAT(priv, tx_fsmerrors); + + /* Really need to reset the transmitter module here */ + } + + /* Check for Rx overrun error */ + + if ((istat & EMAC_ISTAT_RXOVR) != 0) + { + ndbg("Rx OVR rxnext=%p {%06x, %u, %04x} rrp=%02x%02x rwp=%02x%02x blkslft=%02x istat=%02x\n", + priv->rxnext, priv->rxnext->np, priv->rxnext->pktsize, priv->rxnext->stat, + inp(EZ80_EMAC_RRP_H), inp(EZ80_EMAC_RRP_L), + inp(EZ80_EMAC_RWP_H), inp(EZ80_EMAC_RWP_L), + inp(EZ80_EMAC_BLKSLFT_H), inp(EZ80_EMAC_BLKSLFT_L), + istat); + + /* Increment statistics */ + + EMAC_STAT(priv, rx_errors); + EMAC_STAT(priv, rx_ovrerrors); + } + return OK; +} + +/**************************************************************************** + * Function: ez80emac_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void ez80emac_txtimeout(int argc, uint32_t arg, ...) +{ + FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)arg; + irqstate_t flags; + + /* Increment statistics and dump debug info */ + + EMAC_STAT(priv, tx_errors); + EMAC_STAT(priv, tx_timeouts); + + /* Then reset the hardware */ + + flags = enter_critical_section(); + ez80emac_ifdown(&priv->dev); + ez80emac_ifup(&priv->dev); + leave_critical_section(flags); + + /* Then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->dev, ez80emac_txpoll); +} + +/**************************************************************************** + * Function: ez80emac_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void ez80emac_polltimer(int argc, uint32_t arg, ...) +{ + struct ez80emac_driver_s *priv = (struct ez80emac_driver_s *)arg; + + /* Poll uIP for new XMIT data */ + + (void)devif_timer(&priv->dev, ez80emac_txpoll); + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, EMAC_WDDELAY, ez80emac_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: ez80emac_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int ez80emac_ifup(FAR struct net_driver_s *dev) +{ + FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; + uint8_t regval; + int ret; + + ndbg("Bringing up: MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1], + dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3], + dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]); + ndbg(" IP %d.%d.%d.%d\n", + dev->d_ipaddr >> 24, (dev->d_ipaddr >> 16) & 0xff, + (dev->d_ipaddr >> 8) & 0xff, dev->d_ipaddr & 0xff); + + /* Bring up the interface -- Must be down right now */ + + DEBUGASSERT((inp(EZ80_EMAC_CFG4) & EMAC_CFG4_RXEN) == 0); + + /* Reset hardware */ + + ret = ez80_emacinitialize(); + if (ret == 0) + { + /* EMAC_AFR_BC - Accept broadcast messages + * EMAC_AFR_MC - Accept any multicast message + * EMAC_AFR_QMC - Accept only qualified multicast messages + */ + +#ifdef CONFIG_EZ80_MCFILTER + outp(EZ80_EMAC_AFR, EMAC_AFR_BC|EMAC_AFR_QMC|EMAC_AFR_MC); +#else + outp(EZ80_EMAC_AFR, EMAC_AFR_BC|EMAC_AFR_MC); +#endif + + /* Set the MAC address */ + + outp(EZ80_EMAC_STAD_0, priv->dev.d_mac.ether_addr_octet[0]); + outp(EZ80_EMAC_STAD_1, priv->dev.d_mac.ether_addr_octet[1]); + outp(EZ80_EMAC_STAD_2, priv->dev.d_mac.ether_addr_octet[2]); + outp(EZ80_EMAC_STAD_3, priv->dev.d_mac.ether_addr_octet[3]); + outp(EZ80_EMAC_STAD_4, priv->dev.d_mac.ether_addr_octet[4]); + outp(EZ80_EMAC_STAD_5, priv->dev.d_mac.ether_addr_octet[5]); + + /* Enable/disable promiscuous mode */ + + regval = inp(EZ80_EMAC_AFR); +#if defined(CONFIG_EZ80_EMACPROMISC) + regval |= EMAC_AFR_PROM; +#else + regval &= ~EMAC_AFR_PROM; +#endif + outp(EZ80_EMAC_AFR, regval); + + /* Enable Rx */ + + regval = inp(EZ80_EMAC_CFG4); + regval |= EMAC_CFG4_RXEN; + outp(EZ80_EMAC_CFG4, regval); + + /* Turn on interrupts */ + + outp(EZ80_EMAC_ISTAT, 0xff); /* Clear all pending interrupts */ + outp(EZ80_EMAC_IEN, EMAC_EIN_HANDLED); /* Enable all interrupts */ + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, EMAC_WDDELAY, ez80emac_polltimer, 1, (uint32_t)priv); + + /* Enable the Ethernet interrupts */ + + priv->bifup = true; + up_enable_irq(EZ80_EMACRX_IRQ); + up_enable_irq(EZ80_EMACTX_IRQ); + up_enable_irq(EZ80_EMACSYS_IRQ); + ret = OK; + } + return ret; +} + +/**************************************************************************** + * Function: ez80emac_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int ez80emac_ifdown(struct net_driver_s *dev) +{ + struct ez80emac_driver_s *priv = (struct ez80emac_driver_s *)dev->d_private; + irqstate_t flags; + uint8_t regval; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(EZ80_EMACRX_IRQ); + up_disable_irq(EZ80_EMACTX_IRQ); + up_disable_irq(EZ80_EMACSYS_IRQ); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Disable Rx */ + + regval = inp(EZ80_EMAC_CFG4); + regval &= ~EMAC_CFG4_RXEN; + outp(EZ80_EMAC_CFG4, regval); + + /* Disable the Tx poll timer */ + + outp(EZ80_EMAC_PTMR, 0); + + priv->bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: ez80emac_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int ez80emac_txavail(struct net_driver_s *dev) +{ + struct ez80emac_driver_s *priv = (struct ez80emac_driver_s *)dev->d_private; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->bifup) + { + + /* Check if there is room in the hardware to hold another outgoing packet. */ + + /* If so, then poll uIP for new XMIT data */ + + (void)devif_poll(&priv->dev, ez80emac_txpoll); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Function: ez80emac_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int ez80emac_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + /* MISSING LOGIC!!! */ + + return OK; +} +#endif + +/**************************************************************************** + * Function: ez80emac_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int ez80emac_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + /* MISSING LOGIC!!! */ + + return OK; +} +#endif + +/**************************************************************************** + * Function: ez80emac_initialize + * + * Description: + * Initialize the Ethernet driver + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +static int ez80_emacinitialize(void) +{ + struct ez80emac_driver_s *priv = &g_emac; + uint24_t addr; + uint8_t regval; + int ret; + + /* Reset the EMAC hardware */ + + outp(EZ80_EMAC_IEN, 0); /* Disable all interrupts */ + outp(EZ80_EMAC_RST, 0); /* Reset everything */ + outp(EZ80_EMAC_RST, 0xff); + outp(EZ80_EMAC_RST, 0); + + /* The ez80 has a fixed 8kb of EMAC SRAM memory (+ 8kb of + * general purpose SRAM) located in the high address space. + * Configure the GP and EMAC SRAM + */ + + outp(EZ80_RAM_CTL, (RAMCTL_ERAMEN|RAMCTL_GPRAMEN)); + outp(EZ80_RAM_ADDR_U, (CONFIG_EZ80_RAMADDR >> 16)); + outp(EZ80_EMAC_BP_U, (CONFIG_EZ80_RAMADDR >> 16)); + + /* The EMAC memory is broken into two parts: the Tx buffer and the Rx buffer. + * + * The TX buffer lies at the beginning of the EMAC memory. + * The Transmit Lower Boundary Pointer Register, TLBP, holds the + * least significant 12-bits of the starting address of the Tx buffer. + * The Transmit Write Pointer, TRP, will be set to the TLBP. + */ + + addr = CONFIG_EZ80_RAMADDR; + outp(EZ80_EMAC_TLBP_L, (uint8_t)(addr & 0xff)); + outp(EZ80_EMAC_TLBP_H, (uint8_t)((addr >> 8) & 0xff)); + + priv->txstart = (FAR struct ez80emac_desc_s *)(addr); + priv->txnext = priv->txstart; + priv->txhead = NULL; + + priv->txnext->np = 0; + priv->txnext->pktsize = 0; + priv->txnext->stat = 0; + + nvdbg("txnext=%p {%06x, %u, %04x} tlbp=%02x%02x trp=%02x%02x\n", + priv->txnext, priv->txnext->np, priv->txnext->pktsize, priv->txnext->stat, + inp(EZ80_EMAC_TLBP_H), inp(EZ80_EMAC_TLBP_L), + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + + /* The Boundary Pointer Register, EMAC_BP, points to the start of the Rx + * buffer (end of Tx buffer + 1). Only bits EMAC_BP[12:5] of are + * write-able. + */ + + addr += EMAC_TXBUFSIZE; + outp(EZ80_EMAC_BP_L, (uint8_t)(addr & 0xff)); + outp(EZ80_EMAC_BP_H, (uint8_t)((addr >> 8) & 0xff)); + + priv->rxstart = (FAR struct ez80emac_desc_s *)(addr); + priv->rxnext = priv->rxstart; + + priv->rxnext->np = 0; + priv->rxnext->pktsize = 0; + priv->rxnext->stat = 0; + + nvdbg("rxnext=%p {%06x, %u, %04x} bp=%02x%02x\n", + priv->rxnext, priv->rxnext->np, priv->rxnext->pktsize, priv->rxnext->stat, + inp(EZ80_EMAC_BP_H), inp(EZ80_EMAC_BP_L)); + + /* The EMAC Receive Read Pointer (RRP) register(s) should be initialized + * to the start of the Receive buffer. The RRP register points to where the + * next Receive packet is read from. The EMAC_BP[12:5] is loaded into this + * register whenever the EMAC_RST [(HRRFN) is set to 1. The RxDMA block uses + * the RRP[12:5] to compare to RWP[12:5] for determining how many buffers + * remain. The result equates to the BLKSLFT register. + * + * The read-only EMAC Receive Write Pointer (RWP) registers report the + * current RxDMA Receive Write pointer. This pointer gets initialized to EMAC_BP + * whenever EMAC_RST bits SRST or HRRTN are set. Because the size of the packet + * is limited to a minimum of 32 bytes, the last five bits are always zero. + */ + + outp(EZ80_EMAC_RRP_L, (uint8_t)(addr & 0xff)); + outp(EZ80_EMAC_RRP_H, (uint8_t)((addr >> 8) & 0xff)); + + nvdbg("rrp=%02x%02x rwp=%02x%02x\n", + inp(EZ80_EMAC_RRP_H), inp(EZ80_EMAC_RRP_L), + inp(EZ80_EMAC_RWP_H), inp(EZ80_EMAC_RWP_L)); + + /* The Receive High Boundary Pointer Register, EMAC_RHBP, points to the end + * of the Rx buffer + 1. Only bits EMAC_RHBP[12:5] are write-able. + */ + + addr += EMAC_RXBUFSIZE; + outp(EZ80_EMAC_RHBP_L, (uint8_t)(addr & 0xff)); + outp(EZ80_EMAC_RHBP_H, (uint8_t)((addr >> 8) & 0xff)); + priv->rxendp1 = (FAR struct ez80emac_desc_s *)addr; + + nvdbg("rxendp1=%p rhbp=%02x%02x\n", + priv->rxendp1, + inp(EZ80_EMAC_RHBP_H), inp(EZ80_EMAC_RHBP_L)); + + /* The Tx and Receive buffers are divided into packet buffers of either + * 256, 128, 64, or 32 bytes selected by BufSize register bits 7 and 6. + */ + + outp(EZ80_EMAC_BUFSZ, EMAC_BUFSZ); + nvdbg("bufsz=%02x blksleft=%02x%02x\n", + inp(EZ80_EMAC_BUFSZ), inp(EZ80_EMAC_BLKSLFT_H), inp(EZ80_EMAC_BLKSLFT_L)); + + /* Software reset */ + + outp(EZ80_EMAC_ISTAT, 0xff); /* Clear any pending interrupts */ + regval = inp(EZ80_EMAC_RST); + regval |= EMAC_RST_SRST; + outp(EZ80_EMAC_RST, regval); + regval &= ~EMAC_RST_SRST; + outp(EZ80_EMAC_RST, regval); + + nvdbg("After soft reset: rwp=%02x%02x trp=%02x%02x\n", + inp(EZ80_EMAC_RWP_H), inp(EZ80_EMAC_RWP_L), + inp(EZ80_EMAC_TRP_H), inp(EZ80_EMAC_TRP_L)); + + /* PHY reset */ + + up_udelay(500); + ez80emac_miiwrite(priv, MII_MCR, MII_MCR_RESET); + if (!ez80emac_miipoll(priv, MII_MCR, MII_MCR_RESET, false)) + { + ndbg("PHY reset error.\n"); + } + + /* Initialize MAC */ + + /* Set only the default late collision bytes in CFG2 */ + + outp(EZ80_EMAC_CFG3, EMAC_LCOL); + + /* Set only the retry count in CFG3 */ + + outp(EZ80_EMAC_CFG3, EMAC_RETRY); + + /* EMAC_CFG4_TXFC - Pause control frames are allowed to be transmitted + * EMAC_CFG4_RXFC - Act on received pause control frames + */ + + outp(EZ80_EMAC_CFG4, EMAC_CFG4_TXFC|EMAC_CFG4_RXFC); + + /* EMAC_CFG1_CRCEN + EMAC_CFG1_PADEN + EMAC_CFG1_VLPAD + EMAC_CFG1_ADPADN = + * if VLAN not detected, pad to 60, add CRC + * if VLAN detected, pad to 64, add CRC + */ + + outp(EZ80_EMAC_CFG1, EMAC_CFG1_CRCEN|EMAC_CFG1_PADEN|EMAC_CFG1_ADPADN|EMAC_CFG1_VLPAD); + + outp(EZ80_EMAC_IPGT, EMAC_IPGT); + outp(EZ80_EMAC_IPGR1, EMAC_IPGR1); + outp(EZ80_EMAC_IPGR2, EMAC_IPGR2); + + outp(EZ80_EMAC_MAXF_L, EMAC_MAXF & 0xff); + outp(EZ80_EMAC_MAXF_H, EMAC_MAXF >> 8); + + /* Select the fastest MDC clock divider. The MDC clock derives + * from the SCLK divided by 4, 6, 8, 10, 14, 20, or 28. + */ + + outp(EZ80_EMAC_MIIMGT, CONFIG_EZ80_MDCDIV); + + /* Clear the new hash table */ + + outp(EZ80_EMAC_HTBL_0, 0); + outp(EZ80_EMAC_HTBL_1, 0); + outp(EZ80_EMAC_HTBL_2, 0); + outp(EZ80_EMAC_HTBL_3, 0); + outp(EZ80_EMAC_HTBL_4, 0); + outp(EZ80_EMAC_HTBL_5, 0); + outp(EZ80_EMAC_HTBL_6, 0); + outp(EZ80_EMAC_HTBL_7, 0); + + /* PHY reset */ + + ez80emac_miiwrite(priv, MII_MCR, MII_MCR_RESET); + if (!ez80emac_miipoll(priv, MII_MCR, MII_MCR_RESET, false)) + { + ndbg("PHY reset error.\n"); + ret = -EIO; + goto errout; + } + + /* Configure the PHY */ + + ret = ez80emac_miiconfigure(priv); + + /* Initialize DMA / FIFO */ + + outp(EZ80_EMAC_TPTV_L, EMAC_TPTV & 0xff); + outp(EZ80_EMAC_TPTV_H, EMAC_TPTV >> 8); + return OK; + +errout: + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: ez80emac_initialize + * + * Description: + * Initialize the Ethernet driver + * + * Parameters: + * None + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int up_netinitialize(void) +{ + struct ez80emac_driver_s *priv = &g_emac; + int ret; + + /* Disable all interrupts */ + + outp(EZ80_EMAC_IEN, 0); + + /* Attach IRQs */ + + ret = irq_attach(EZ80_EMACSYS_IRQ, ez80emac_sysinterrupt); + if (ret < 0) + { + nlldbg("Unable to attach IRQ %d\n", EZ80_EMACSYS_IRQ); + ret = -EAGAIN; + goto errout; + } + + ret = irq_attach(EZ80_EMACRX_IRQ, ez80emac_rxinterrupt); + if (ret < 0) + { + nlldbg("Unable to attach IRQ %d\n", EZ80_EMACRX_IRQ); + ret = -EAGAIN; + goto errout; + } + + ret = irq_attach(EZ80_EMACTX_IRQ, ez80emac_txinterrupt); + if (ret < 0) + { + nlldbg("Unable to attach IRQ %d\n", EZ80_EMACTX_IRQ); + ret = -EAGAIN; + goto errout; + } + + /* Initialize the driver structure */ + + memset(&g_emac, 0, sizeof(struct ez80emac_driver_s)); + priv->dev.d_ifup = ez80emac_ifup; /* I/F down callback */ + priv->dev.d_ifdown = ez80emac_ifdown; /* I/F up (new IP address) callback */ + priv->dev.d_txavail = ez80emac_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->dev.d_addmac = ez80emac_addmac; /* Add multicast MAC address */ + priv->dev.d_rmmac = ez80emac_rmmac; /* Remove multicast MAC address */ +#endif + priv->dev.d_private = (FAR void*)&g_emac; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Read the MAC address from the hardware into priv->dev.d_mac.ether_addr_octet */ + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->dev, NET_LL_ETHERNET); + return OK; + +errout: + up_netuninitialize(); + return ret; +} + +/**************************************************************************** + * Function: up_multicastfilter + * + * Description: + * Add one MAC address to the multi-cast hash table + * + * Parameters: + * dev - Reference to the uIP driver state structure + * mac - The MAC address to add + * enable - true: Enable filtering on this address; false: disable + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_MCFILTER +int up_multicastfilter(FAR struct net_driver_s *dev, FAR uint8_t *mac, bool enable) +{ + FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->priv; + uint8_t regval; + int ndx; + int bit; + int i; + + /* The EMAC Hash Table Registers represent an 8x8 hash table matrix. + * This table is used as an option to select between different multi-cast + * addresses. If a multicast address is received, the first 6 bits of the CRC + * decoded and to a table that points to a single bit in the hash table matrix. + * if the selected bit is '1', then multicast packet is accepted. If the bit + * is '0', the multicast packet is rejected. + */ + + /* Apply the hash algorithm to the hash table index and bit number + * corresponding to this MAC + */ + + ez80emac_machash(mclist->dmi_addr, &ndx, &bit); + + /* And set/clear that bit in that array element */ + + regval = inp(EZ80_EMAC_HTBL_0 + ndx); + if (enable) + { + regval |= (1 << bit); + } + else + { + regval &= ~(1 << bit); + } + outp(EZ80_EMAC_HTBL_0 + ndx, regval); + return OK; +} +#endif + +/**************************************************************************** + * Function: up_netuninitialize + * + * Description: + * Un-initialize the Ethernet driver + * + * Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +void up_netuninitialize(void) +{ + FAR struct ez80emac_driver_s *priv = &g_emac; + int i; + + ez80emac_ifdown(&priv->dev); + /* netdev_unregister(priv->dev); No such API yet */ + + priv->txnext = priv->txstart; + priv->txhead = NULL; + + irq_detach(EZ80_EMACRX_IRQ); + irq_detach(EZ80_EMACTX_IRQ); + irq_detach(EZ80_EMACSYS_IRQ); +} + +#endif /* CONFIG_NET && CONFIG_EZ80_EMAC */ + diff --git a/arch/z80/src/ez80/ez80_i2c.c b/arch/z80/src/ez80/ez80_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..f1c8a2bcd1a5f506dbbf2c5d205eb03a2d02f5a4 --- /dev/null +++ b/arch/z80/src/ez80/ez80_i2c.c @@ -0,0 +1,971 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_i2c.c + * + * Copyright(C) 2009, 2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ez80f91.h" +#include "ez80f91_i2c.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EZ80_NOSTOP (1 << 0) /* Bit 0: No STOP on this transfer */ +#define EZ80_NOSTART (1 << 1) /* Bit 1: No address or START on this tranfers */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ez80_i2cdev_s +{ + FAR const struct i2c_ops_s *ops; /* I2C vtable */ + uint32_t frequency; /* Currently selected I2C frequency */ + uint16_t addr; /* 7- or 10-bit address */ + uint8_t addr10 : 1; /* 1=Address is 10-bit */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Misc. Helpers */ + +static void ez80_i2c_setccr(uint16_t ccr); +static uint16_t ez80_i2c_getccr(uint32_t frequency); +static uint8_t ez80_i2c_waitiflg(void); +static void ez80_i2c_clriflg(void); +static void ez80_i2c_start(void); +static void ez80_i2c_stop(void); +static int ez80_i2c_sendaddr(struct ez80_i2cdev_s *priv, + uint8_t readbit); +static int ez80_i2c_read_transfer(FAR struct ez80_i2cdev_s *priv, + FAR uint8_t *buffer, int buflen, uint8_t flags); +static int ez80_i2c_write_transfer(FAR struct ez80_i2cdev_s *priv, + FAR const uint8_t *buffer, int buflen, uint8_t flags); +static void ez80_i2c_setfrequency(FAR struct ez80_i2cdev_s *priv, + uint32_t frequency); + +/* I2C methods */ + +static int ez80_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* This function is normally prototyped int the ZiLOG header file sio.h */ + +extern uint32_t get_freq(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool g_initialized; /* true:I2C has been initialized */ +static sem_t g_i2csem; /* Serialize I2C transfers */ + +const struct i2c_ops_s g_ops = +{ + ez80_i2c_transfer +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: ez80_i2c_semtake/ez80_i2c_semgive + * + * Description: + * Take/Give the I2C semaphore. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_semtake(void) +{ + /* Take the I2C semaphore (perhaps waiting) */ + + while (sem_wait(&g_i2csem) != 0) + { + /* The only case that an error should occr here is if + * the wait was awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +#define ez80_i2c_semgive() sem_post(&g_i2csem) + +/**************************************************************************** + * Name: ez80_i2c_setccr + * + * Description: + * Set the current BRG value for this transaction + * + * Input Parameters: + * ccr - BRG to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_setccr(uint16_t ccr) +{ + outp(EZ80_I2C_CCR, ccr); +} + +/**************************************************************************** + * Name: ez80_i2c_getccr + * + * Description: + * Calculate the BRG value + * + * Input Parameters: + * fscl - The I2C frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint16_t ez80_i2c_getccr(uint32_t fscl) +{ + uint32_t fsamp; + uint32_t ftmp; + uint8_t n; + uint8_t m; + + /* The sampling frequency is given by: + * + * fsamp = sysclock / 2**N + * + * And the I2C clock is determined by: + * + * fscl = sysclock / 10 / (M + 1) / 2**N + * = fsamp / 10 / (M + 1) + * + * The fsmp must be >= 10 * fscl. The best solution is the smallest value of + * N so that the sampling rate is the highest subject to: + * + * The minimum value of the fsamp is given by: + */ + + fsamp = 10 * fscl; + + /* Now, serarch for the smallest value of N that results in the actual + * fsamp >= the ideal fsamp. Fortunately, we only have to check at most + * eight values. + */ + + if (fsamp >= EZ80_SYS_CLK_FREQ) + { + ftmp = EZ80_SYS_CLK_FREQ / 10; + n = 0; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 1)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 1) / 10; + n = 1; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 2)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 2) / 10; + n = 2; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 3)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 3) / 10; + n = 3; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 4)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 4) / 10; + n = 4; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 5)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 5) / 10; + n = 5; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 6)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 6) / 10; + n = 6; + } + else if (fsamp >= (EZ80_SYS_CLK_FREQ >> 7)) + { + ftmp = (EZ80_SYS_CLK_FREQ >> 7) / 10; + n = 7; + } + else + { + ftmp = (EZ80_SYS_CLK_FREQ >> 7) / 10; + fscl = ftmp; + n = 7; + } + + /* Finally, get M: + * + * M = (fsamp / 10) / fscl - 1 = ftmp / fscl - 1 + */ + + m = ftmp / fscl; + if (m > 0) + { + if (--m > 15) + { + m = 15; + } + } + + /* Return the value for CCR */ + + return (n << I2C_CCR_NSHIFT) | (m << I2C_CCR_MSHIFT); +} + +/**************************************************************************** + * Name: ez80_i2c_waitiflg + * + * Description: + * In polled mode, we have to spin until the IFLG bit in the xxx register + * goes to 1, signalling that the last send or receive is complete. This + * could be used to generate an interrupt for a non-polled driver. + * + * Input Parameters: + * priv - Device-specific state data + * readbit - 0 or I2C_READBIT + * + * Returned Value: + * The contents of the I2C_SR register at the time that IFLG became 1. + * + ****************************************************************************/ + +static uint8_t ez80_i2c_waitiflg(void) +{ + while ((inp(EZ80_I2C_CTL) & I2C_CTL_IFLG) != 0); + return inp(EZ80_I2C_SR); +} + +/**************************************************************************** + * Name: ez80_i2c_clriflg + * + * Description: + * Clear the IFLAG bit in the I2C_CTL register, acknowledging the event. + * If interrupts are enabled, this would clear the interrupt status. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_clriflg(void) +{ + uint8_t regval = inp(EZ80_I2C_CTL); + regval &= ~I2C_CTL_IFLG; + outp(EZ80_I2C_CTL, regval); +} + +/**************************************************************************** + * Name: ez80_i2c_start + * + * Description: + * Send the START bit. IFLAG must be zero; it will go to 1 when it is + * time to send the address. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_start(void) +{ + uint8_t regval = inp(EZ80_I2C_CTL); + regval |= I2C_CTL_STA; + outp(EZ80_I2C_CTL, regval); +} + +/**************************************************************************** + * Name: ez80_i2c_stop + * + * Description: + * Send the STOP bit. This terminates the I2C transfer and reverts back + * to IDLE mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_stop(void) +{ + uint8_t regval = inp(EZ80_I2C_CTL); + regval |= I2C_CTL_STP; + outp(EZ80_I2C_CTL, regval); +} + +/**************************************************************************** + * Name: ez80_i2c_sendaddr + * + * Description: + * Send the 8- or 11-bit address for either a read or a write transaction. + * + * Input Parameters: + * priv - Device-specific state data + * readbit - 0 or I2C_READBIT + * + * Returned Value: + * 0: Success, IFLG is set and DATA can be sent or received. + + * Or <0: Negated error value. IFLG is cleared. + * + * -EIO: Irrecoverable (or unexpected) error occured + * -EAGAIN: And + * + ****************************************************************************/ + +static int ez80_i2c_sendaddr(struct ez80_i2cdev_s *priv, uint8_t readbit) +{ + uint8_t sr; + + /* Wait for the IFLG bit to transition to 1. At this point, we should + * have status == 8 meaning that the start bit was sent successfully. + */ + + sr = ez80_i2c_waitiflg(); +#ifdef CONFIG_DEBUG + if (sr != I2C_SR_MSTART) + { + /* This error should never occur */ + + dbg("Bad START status: %02x\n", sr); + ez80_i2c_clriflg(); + return -EIO; + } +#endif + + /* Now send the address */ + + if (!priv->addr10) + { + /* Load the I2C_DR with the 8-bit I2C slave address and clear the + * IFLG. Clearing the IFLAG will cause the address to be transferred. + */ + + outp(EZ80_I2C_DR, (uint8_t)I2C_ADDR8(priv->addr) | readbit); + ez80_i2c_clriflg(); + + /* And wait for the address transfer to complete */ + + sr = ez80_i2c_waitiflg(); + if (sr != I2C_SR_MADDRWRACK && sr != I2C_SR_MADDRWR) + { + dbg("Bad ADDR8 status: %02x\n", sr); + goto failure; + } + } + else + { + /* Load the I2C_DR with upper part of the 10->16-bit I2C slave address + * and clear the IFLG. Clearing the IFLAG will cause the address to + * be transferred. + */ + + outp(EZ80_I2C_DR, (uint8_t)I2C_ADDR10H(priv->addr) | readbit); + ez80_i2c_clriflg(); + + /* And wait for the address transfer to complete */ + + sr = ez80_i2c_waitiflg(); + if (sr != I2C_SR_MADDRWRACK && sr != I2C_SR_MADDRWR) + { + dbg("Bad ADDR10H status: %02x\n", sr); + goto failure; + } + + /* Now send the lower 8 bits of the 10-bit address */ + + outp(EZ80_I2C_DR, (uint8_t)I2C_ADDR10L(priv->addr)); + ez80_i2c_clriflg(); + + /* And wait for the address transfer to complete */ + + sr = ez80_i2c_waitiflg(); + if (sr != I2C_SR_MADDR2WRACK && sr != I2C_SR_MADDR2WR) + { + dbg("Bad ADDR10L status: %02x\n", sr); + goto failure; + } + } + + return OK; + + /* We don't attempt any fancy status-based error recovery */ + +failure: +#ifdef CONFIG_DEBUG + switch (sr) + { + case I2C_SR_ARBLOST1: /* Arbitration lost in address or data byte */ + case I2C_SR_ARBLOST2: /* Arbitration lost in address as master, slave + * address and Write bit received, ACK transmitted */ + case I2C_SR_ARBLOST3: /* Arbitration lost in address as master, General + * Call address received, ACK transmitted */ + case I2C_SR_ARBLOST4: /* Arbitration lost in address as master, slave + * address and Read bit received, ACK transmitted */ + dbg("Arbitration lost: %02x\n", sr); + ez80_i2c_clriflg(); + return -EAGAIN; + + default: + dbg("Unexpected status: %02x\n", sr); + ez80_i2c_clriflg(); + return -EIO; + } +#else + ez80_i2c_clriflg(); + return -EAGAIN; +#endif +} + +/**************************************************************************** + * Name: ez80_i2c_read_transfer + * + * Description: + * Receive a block of data from I2C using the previously selected I2C + * frequency and slave address. Each read operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this read completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to a buffer of data to receive the data from the device + * buflen - The requested number of bytes to be read + * flags - Determines is a START and/or STOP indication is needed. + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +static int ez80_i2c_read_transfer(FAR struct ez80_i2cdev_s *priv, + FAR uint8_t *buffer, int buflen, + uint8_t flags) +{ + FAR uint8_t *ptr; + uint8_t regval; + int retry; + int count; + int ret; + + /* Retry as necessary to receive the whole message */ + + for (retry = 0; retry < 100; retry++) + { + if ((flags & EZ80_NOSTART) == 0) + { + /* Enter MASTER TRANSMIT mode by setting the STA bit in the + * I2C_CTL register to 1. The I2C then tests the I2C bus and + * transmits a START condition when the bus is free. + */ + + ez80_i2c_start(); + + /* When a START condition is transmitted, the IFLG bit is 1. + * Then we may send the I2C slave address. + */ + + ret = ez80_i2c_sendaddr(priv, 0); + if (ret < 0) + { + if (ret == -EAGAIN) + { + continue; + } + else + { + return ret; + } + } + } + + /* Now loop to receive each data byte */ + + ptr = buffer; + for (count = buflen; count; count--) + { + /* Is this the last byte? If so, we must NACK it */ + + regval = inp(EZ80_I2C_CTL); + if (count <= 1) + { + /* If the AAK bit is cleared to 0 during a transfer, the I2C + * transmits a NACK bit after the next byte is received. + */ + + regval &= ~I2C_CTL_AAK; + } + else + { + /* If the AAK bit in the I2C_CTL register is set to 1 then an + * ACK bit is transmitted and the IFLG bit is set after each + * byte is received. + */ + + regval |= I2C_CTL_AAK; + } + + outp(EZ80_I2C_CTL, regval); + + /* Wait for IFLG to be set meaning that incoming data is + * available in the I2C_DR registers. + */ + + regval = ez80_i2c_waitiflg(); + + /* Data byte received in MASTER mode, ACK transmitted */ + + if (regval == I2C_SR_MDATARDACK) + { + /* Since we just ACKed the incoming byte, it must NOT be the last */ + + DEBUGASSERT(count > 1); + + /* Receive the data and clear the IFLGS */ + + *ptr++ = inp(EZ80_I2C_DR); + ez80_i2c_clriflg(); + } + + /* Data byte received in MASTER mode, NACK transmitted */ + + else if (regval == I2C_SR_MDATARDNAK) + { + /* Since we just NACKed the incoming byte, it must be the last */ + + DEBUGASSERT(count <= 1); + + if ((flags & EZ80_NOSTOP) == 0) + { + /* When all bytes are received and the NACK has been sent, + * then the microcontroller must write 1 to the STP bit in + * the I2C_CTL register. The I2C then transmits a STOP + * condition, clears the STP bit and returns to an idle state. + */ + + ez80_i2c_stop(); + } + + ez80_i2c_clriflg(); + return OK; + } + + /* Arbitration lost in address or data byte */ + + else if (regval == I2C_SR_ARBLOST1) + { + /* Clear the IFLG and break out of the inner loop. + * this will cause the whole transfer to start over + */ + + dbg("Arbitration lost: %02x\n", regval); + ez80_i2c_clriflg(); + break; + } + + /* Unexpected status response */ + + else + { + dbg("Unexpected status: %02x\n", regval); + ez80_i2c_clriflg(); + return-EIO; + } + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: ez80_i2c_write_transfer + * + * Description: + * Send a block of data on I2C using the previously selected I2C + * frequency and slave address. Each write operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this write completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the read-only buffer of data to be written to device + * buflen - The number of bytes to send from the buffer + * flags - Determines is a START and/or STOP indication is needed. + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +static int ez80_i2c_write_transfer(FAR struct ez80_i2cdev_s *priv, + FAR const uint8_t *buffer, int buflen, + uint8_t flags) +{ + FAR const uint8_t *ptr; + uint8_t sr; + int retry; + int count; + int ret; + + /* Retry as necessary to send this whole message */ + + for (retry = 0; retry < 100; retry++) + { + if ((flags & EZ80_NOSTART) == 0) + { + /* Enter MASTER TRANSMIT mode by setting the STA bit in the + * I2C_CTL register to 1. The I2C then tests the I2C bus and + * transmits a START condition when the bus is free. + */ + + ez80_i2c_start(); + + /* When a START condition is transmitted, the IFLG bit is 1. Then + * we may send the I2C slave address. + */ + + ret = ez80_i2c_sendaddr(priv, 0); + if (ret < 0) + { + if (ret == -EAGAIN) + { + continue; + } + else + { + return ret; + } + } + } + + /* Then send all of the bytes in the buffer */ + + ptr = buffer; + for (count = buflen; count; count--) + { + /* Load the I2C_DR with next data byte and clear the IFLG. Clearing + * the IFLAG will cause the data to be transferred. + */ + + outp(EZ80_I2C_DR, *ptr++); + ez80_i2c_clriflg(); + + /* And wait for the data transfer to complete */ + + sr = ez80_i2c_waitiflg(); + if (sr != I2C_SR_MDATAWRACK && sr != I2C_SR_MDATAWR) + { + dbg("Bad DATA status: %02x\n", sr); + ez80_i2c_clriflg(); + if (sr == I2C_SR_ARBLOST1) + { + /* Arbitration lost, break out of the inner loop and + * try sending the message again + */ + + break; + } + + /* Otherwise, it is fatal (shouldn't happen) */ + + return -EIO; + } + + /* Data byte was sent successfully. Was that the last byte? */ + + else if (count <= 1) + { + if ((flags & EZ80_NOSTOP) == 0) + { + /* When all bytes are transmitted, the microcontroller + * must write a 1 to the STP bit in the I2C_CTL register. + * The I2C then transmits a STOP condition, clears the + * STP bit and returns to an idle state. + */ + + ez80_i2c_stop(); + } + + return OK; + } + } + } + + /* If we get here, we timed out without successfully sending the message */ + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: ez80_i2c_setfrequency + * + * Description: + * Set the I2C frequency. This frequency will be retained in the struct + * i2c_master_s instance and will be used with all transfers. Required. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The I2C frequency requested + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void ez80_i2c_setfrequency(FAR struct ez80_i2cdev_s *priv, + uint32_t frequency) +{ + uint16_t ccr; + + if (priv->frequency != frequency) + { + /* Calculate and save the BRG and set the CCR */ + + ccr = ez80_i2c_getccr(frequency); + ez80_i2c_setccr(ccr); + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: ez80_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers, each transfer is started with a + * START and the final transfer is completed with a STOP. Each sequence + * will be an 'atomic' operation in the sense that any other I2C actions + * will be serialized and pend until this read completes. Optional. + * + * Input Parameters: + * dev - Device-specific state data + * msgs - A pointer to a set of message descriptors + * msgcount - The number of transfers to perform + * + * Returned Value: + * The number of transfers completed + * + ****************************************************************************/ + +static int ez80_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + FAR struct ez80_i2cdev_s *priv = (FAR struct ez80_i2cdev_s *)dev; + FAR struct i2c_msg_s *msg; + bool nostop; + uint8_t flags; + int ret = OK; + int i; + + /* Perform each segment of the transfer, message at a time */ + + flags = 0; + + /* Get exclusive access to the I2C bus */ + + ez80_i2c_semtake(); + + /* The process each message seqment */ + + for (i = 0; i < count; i++) + { + msg = &msgs[i]; + + /* Set the I2C frequency and address */ + + ez80_i2c_setfrequency(priv, msg->frequency); + + priv->addr = msg->addr; + priv->addr10 = ((msg->flags & I2C_M_TEN) != 0); + + /* Is this the last message in the sequence? */ + + nostop = false; + if (i < (count - 1)) + { + FAR struct i2c_msg_s *next; + + /* No... Check if the next message should have a repeated start or + * not. The conditions for NO repeated start are: + * + * - I2C_M_NORESTART bit set + * - Same direction (I2C_M_READ) + * - Same address (and I2C_M_TEN) + */ + + next = &msgs[i + 1]; + if ((msg->flags & I2C_M_NORESTART) != 0 && + (msg->flags & (I2C_M_READ | I2C_M_TEN)) == (next->flags & (I2C_M_READ | I2C_M_TEN)) && + msg->addr == next->addr) + { + nostop = true; + } + } + + /* Perform the read or write operation */ + + flags |= (nostop) ? EZ80_NOSTOP : 0; + if ((msg->flags & I2C_M_READ) != 0) + { + ret = ez80_i2c_read_transfer(priv, msg->buffer, msg->length, flags); + } + else + { + ret = ez80_i2c_write_transfer(priv, msg->buffer, msg->length, flags); + } + + /* Check for I2C transfer errors */ + + if (ret < 0) + { + break; + } + + /* If there was no STOP bit on this segment, then there should be no + * START on the next segment. + */ + + flags = (nostop) ? EZ80_NOSTART : 0; + } + + ez80_i2c_semgive(); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has mutiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *ez80_i2cbus_initialize(int port) +{ + FAR struct ez80_i2cdev_s *i2c; + uint16_t ccr; + uint8_t regval; + + if (!g_initialized) + { + /* Set up some initial BRG value */ + + ccr = ez80_i2c_getccr(100*1000); + ez80_i2c_setccr(ccr); + + /* No GPIO setup is required -- I2C pints, SCL/SDA are not multiplexed */ + + /* This semaphore enforces serialized access for I2C transfers */ + + sem_init(&g_i2csem, 0, 1); + + /* Enable I2C -- but not interrupts */ + + regval = inp(EZ80_I2C_CTL); + regval |= I2C_CTL_ENAB; + outp(EZ80_I2C_CTL, regval); + } + + /* Now, allocate an I2C instance for this caller */ + + i2c = (FAR struct ez80_i2cdev_s *)kmm_zalloc(sizeof(FAR struct ez80_i2cdev_s)); + if (i2c) + { + /* Initialize the allocated instance */ + + i2c->ops = &g_ops; + } + + return (FAR struct i2c_master_s *)i2c; +} diff --git a/arch/z80/src/ez80/ez80_initialstate.c b/arch/z80/src/ez80/ez80_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..727ba368be7242eeb5dad61b2226c54b2a7940a5 --- /dev/null +++ b/arch/z80/src/ez80/ez80_initialstate.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_initialstate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); +#ifndef CONFIG_SUPPRESS_INTERRUPTS + ((uint8_t*)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG; /* Parity/Overflow flag will enable interrupts */ +#endif + xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; +} diff --git a/arch/z80/src/ez80/ez80_io.asm b/arch/z80/src/ez80/ez80_io.asm new file mode 100644 index 0000000000000000000000000000000000000000..32cd5296c042b32fbab0c4b4609dd6e7e510f40f --- /dev/null +++ b/arch/z80/src/ez80/ez80_io.asm @@ -0,0 +1,154 @@ +;************************************************************************** +; arch/z80/src/ze80/ez80_io.c +; +; Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Global Symbols Imported +;************************************************************************** + +;************************************************************************** +; Global Symbols Expported +;************************************************************************** + + xdef _outp + xdef _inp + +;************************************************************************** +; Global Symbols Expported +;************************************************************************** + + CONFIG_EZ80_Z80MODE equ 0 + +;************************************************************************** +; Code +;************************************************************************** + + segment CODE + .assume ADL=1 + +;************************************************************************** +; Name: void outp(uint16_t p, uint8_t c) +; +; Description: +; Output byte c on port p +; +;************************************************************************** + +_outp: + ; Create a stack frame + + push ix + ld ix, #0 + add ix, sp + + ; Get the arguments from the stack + + .if CONFIG_EZ80_Z80MODE + ; Stack looks like: + ; + ; 7-8 Unused + ; 6 Value + ; 4-5 Port + ; 2-3 Return address + ; SP: 0-1 Caller's fame pointer + + ld bc, (ix + 4) ; Port + ld a, (ix + 6) ; Value + + .else + ; Stack looks like: + ; + ; 10-11 Unused + ; 9 Value + ; 8 Unused + ; 6-7 Port + ; 3-5 Return address + ; SP: 0-2 Caller's frame pointer + + ld bc, (ix + 6) ; Port (upper 8 bits not used) + ld a, (ix + 9) ; Value + + .endif + + ; Output the specified by to the specified 8-bit I/O address + + out (bc), a + pop ix + ret + +;************************************************************************** +; Name: uint8_t inp(uint16_t p) +; +; Description: +; Input byte from port p +; +;************************************************************************** + +_inp: + ; Create a stack frame + + push ix + ld ix, #0 + add ix, sp + + ; Get the arguments from the stack + + .if CONFIG_EZ80_Z80MODE + ; Stack looks like: + ; + ; 4-5 Port + ; 2-3 Return address + ; SP: 0-1 Caller's fame pointer + + ld bc, (ix + 4) ; Port + + .else + ; Stack looks like: + ; + ; 8 Unused + ; 6-7 Port + ; 3-5 Return address + ; SP: 0-2 Caller's frame pointer + + ld bc, (ix + 6) ; Port (upper 8 bits not used) + + .endif + + ; Return port value in A + + in a, (bc) + pop ix + ret + + end diff --git a/arch/z80/src/ez80/ez80_irq.c b/arch/z80/src/ez80/ez80_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..67b37c4eca2393fdbecf12a5a794003f1ccf4e84 --- /dev/null +++ b/arch/z80/src/ez80/ez80_irq.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_irq.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +volatile chipreg_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + g_current_regs = NULL; + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + asm("ei"); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * On many architectures, there are three levels of interrupt enabling: (1) + * at the global level, (2) at the level of the interrupt controller, + * and (3) at the device level. In order to receive interrupts, they + * must be enabled at all three levels. + * + * This function implements disabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* There are no ez80 interrupt controller settings to disable IRQs */ +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * This function implements enabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* There are no ez80 interrupt controller settings to enable IRQs */ +} diff --git a/arch/z80/src/ez80/ez80_irqsave.asm b/arch/z80/src/ez80/ez80_irqsave.asm new file mode 100644 index 0000000000000000000000000000000000000000..de3ad4a6e23bc08f1b55855b3c4fb8adedbde9a4 --- /dev/null +++ b/arch/z80/src/ez80/ez80_irqsave.asm @@ -0,0 +1,88 @@ +;************************************************************************** +; arch/z80/src/ez80/ez80_up_irq_save.asm +; +; Copyright (C) 2008 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Global Symbols Imported +;************************************************************************** + +;************************************************************************** +; Global Symbols Expported +;************************************************************************** + + xdef _up_irq_save + xdef _up_irq_restore + +;************************************************************************** +; Code +;************************************************************************** + + segment CODE + .assume ADL=1 + +;************************************************************************** +;* Name: irqstate_t up_irq_save(void) +;* +;* Description: +;* Disable all interrupts; return previous interrupt state +;* +;************************************************************************** + +_up_irq_save: + ld a, i ; AF = interrupt state + di ; Interrupts are disabled (does not affect F) + push af ; Transfer to HL via the stack + pop hl ; + ret ; And return + +;************************************************************************** +;* Name: void up_irq_restore(irqstate_t flags) +;* +;* Description: +;* Restore previous interrupt state +;* +;************************************************************************** + +_up_irq_restore: + di ; Assume disabled + pop hl ; HL = return address + pop af ; AF Parity bit holds interrupt state + jp po, _disabled ; Skip over re-enable if Parity odd + ei ; Re-enable interrupts +_disabled: + push af ; Restore stack + push hl ; + ret ; and return + + end diff --git a/arch/z80/src/ez80/ez80_lowuart.c b/arch/z80/src/ez80/ez80_lowuart.c new file mode 100644 index 0000000000000000000000000000000000000000..062419b54a98805ee11170e695ab3db7f84f6b10 --- /dev/null +++ b/arch/z80/src/ez80/ez80_lowuart.c @@ -0,0 +1,256 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_loweruart.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/chip.h" +#include "common/up_internal.h" + +#ifdef USE_LOWSERIALINIT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Is there any serial support? This might be the case if the board does + * not have serial ports but supports stdout through, say, an LCD. + */ + +#if defined(CONFIG_EZ80_UART0) || defined(CONFIG_EZ80_UART1) +# define HAVE_SERIAL +#else +# undef HAVE_SERIAL +#endif + +/* Is one of the serial ports a console? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_EZ80_UART0) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART1_SERIAL_CONSOLE +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_EZ80_UART1) +# define HAVE_SERIALCONSOLE 1 +# undef CONFIG_UART0_SERIAL_CONSOLE +#else +# warning "No console is defined" +# if defined(CONFIG_UART0_SERIAL_CONSOLE) || defined(CONFIG_UART1_SERIAL_CONSOLE) +# error "A serial console selected, but corresponding UART not enabled" +# endif +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef HAVE_SERIALCONSOLE +#endif + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define ez80_inp(offs) inp((EZ80_UART0_BASE+(offs))) +# define ez80_outp(offs,val) outp((EZ80_UART0_BASE+(offs)), (val)) +# define CONFIG_UART_BAUD CONFIG_UART0_BAUD +# if CONFIG_UART0_BITS == 7 +# define CONFIG_UART_BITS EZ80_UARTCHAR_7BITS +# else +# define CONFIG_UART_BITS EZ80_UARTCHAR_8BITS +# endif +# if CONFIG_UART0_2STOP != 0 +# define CONFIG_UART_2STOP EZ80_UARTLCTl_2STOP +# else +# define CONFIG_UART_2STOP 0 +# endif +# if CONFIG_UART0_PARITY == 1 /* Odd parity */ +# define CONFIG_UART_PARITY EZ80_UARTLCTL_PEN +# elif CONFIG_UART0_PARITY == 2 /* Even parity */ +# define CONFIG_UART_PARITY (EZ80_UARTLCTL_PEN|EZ80_UARTLCTL_EPS) +# else +# define CONFIG_UART_PARITY 0 +# endif +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define ez80_inp(offs) inp((EZ80_UART1_BASE+(offs))) +# define ez80_outp(offs.val) outp((EZ80_UART1_BASE+(offs)), (val)) +# define CONFIG_UART_BAUD CONFIG_UART1_BAUD +# if CONFIG_UART1_BITS == 7 +# define CONFIG_UART_BITS EZ80_UARTCHAR_7BITS +# else +# define CONFIG_UART_BITS EZ80_UARTCHAR_8BITS +# endif +# if CONFIG_UART1_2STOP != 0 +# define CONFIG_UART_2STOP EZ80_UARTLCTl_2STOP +# else +# define CONFIG_UART_2STOP 0 +# endif +# if CONFIG_UART1_PARITY == 1 /* Odd parity */ +# define CONFIG_UART_PARITY EZ80_UARTLCTL_PEN +# elif CONFIG_UART1_PARITY == 2 /* Even parity */ +# define CONFIG_UART_PARITY (EZ80_UARTLCTL_PEN|EZ80_UARTLCTL_EPS) +# else +# define CONFIG_UART_PARITY 0 +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) +static void ez80_setbaud(void) +{ + uint32_t brg_divisor; + uint8_t lctl; + + /* The resulting BAUD and depends on the system clock frequency and the + * BRG divisor as follows: + * + * BAUD = SYSTEM_CLOCK_FREQUENCY / (16 * BRG_Divisor) + * + * Or + * + * BRG_Divisor = SYSTEM_CLOCK_FREQUENCY / 16 / BAUD + * + * NOTE: The system clock frequency value is defined in the board.h file + */ + + brg_divisor = (ez80_systemclock + (CONFIG_UART_BAUD << 3)) / (CONFIG_UART_BAUD << 4); + + /* Set the DLAB bit to enable access to the BRG registers */ + + lctl = ez80_inp(EZ80_UART_LCTL); + lctl |= EZ80_UARTLCTL_DLAB; + ez80_outp(EZ80_UART_LCTL, lctl); + + ez80_outp(EZ80_UART_BRGL, (uint8_t)(brg_divisor & 0xff)); + ez80_outp(EZ80_UART_BRGH, (uint8_t)(brg_divisor >> 8)); + + lctl &= ~EZ80_UARTLCTL_DLAB; + ez80_outp(EZ80_UART_LCTL, lctl); +} +#endif /* HAVE_SERIALCONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowserialinit + ****************************************************************************/ + +void up_lowserialinit(void) +{ +#ifdef HAVE_SERIAL + uint8_t regval; + + /* Configure pins for usage of UARTs (whether or not we have a console) */ + +#ifdef CONFIG_EZ80_UART0 + /* Set Port D, pins 0 and 1 for their alternate function (Mode 7) to enable UART0 */ + + regval = inp(EZ80_PD_DDR); + regval |= 3; + outp(EZ80_PD_DDR, regval); + + regval = inp(EZ80_PD_ALT1); + regval &= ~3; + outp(EZ80_PD_ALT1, regval); + + regval = inp(EZ80_PD_ALT2); + regval |= 3; + outp(EZ80_PD_ALT2, regval); +#endif + +#ifdef CONFIG_EZ80_UART1 + /* Set Port C, pins 0 and 1 for their alternate function (Mode 7) to enable UART1 */ + + regval = inp(EZ80_PC_DDR); + regval |= 3; + outp(EZ80_PC_DDR, regval); + + regval = inp(EZ80_PC_ALT1); + regval &= ~3; + outp(EZ80_PC_ALT1, regval); + + regval = inp(EZ80_PC_ALT2); + regval |= 3; + outp(EZ80_PC_ALT2, regval); +#endif + +#if defined(HAVE_SERIALCONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Disable interrupts from the UART */ + + regval = ez80_inp(EZ80_UART_IER); + regval &= ~EZ80_UARTEIR_INTMASK; + ez80_outp(EZ80_UART_IER, regval); + + /* Set the baud rate */ + + ez80_setbaud(); + ez80_outp(EZ80_UART_MCTL, 0); + + /* Set the character properties */ + + regval = ez80_inp(EZ80_UART_LCTL); + regval &= ~EZ80_UARTLCTL_MASK; + regval |= (CONFIG_UART_BITS | CONFIG_UART_2STOP | CONFIG_UART_PARITY); + ez80_outp(EZ80_UART_LCTL, regval); + + /* Enable and flush the receive FIFO */ + + regval = EZ80_UARTFCTL_FIFOEN; + ez80_outp(EZ80_UART_FCTL, regval); + regval |= (EZ80_UARTFCTL_CLRTxF|EZ80_UARTFCTL_CLRRxF); + ez80_outp(EZ80_UART_FCTL, regval); + + /* Set the receive trigger level to 1 */ + + regval |= EZ80_UARTTRIG_1; + ez80_outp(EZ80_UART_FCTL, regval); + +#endif /* HAVE_SERIALCONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_SERIAL */ +} + +#endif /* USE_LOWSERIALINIT */ diff --git a/arch/z80/src/ez80/ez80_registerdump.c b/arch/z80/src/ez80/ez80_registerdump.c new file mode 100644 index 0000000000000000000000000000000000000000..0e523b693a7553568ddc4eb8027302830e4ed4d9 --- /dev/null +++ b/arch/z80/src/ez80/ez80_registerdump.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_registerdump.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z80_registerdump + ****************************************************************************/ + +static void ez80_registerdump(void) +{ + if (g_current_regs) + { +#ifdef CONFIG_EZ80_Z80MODE + lldbg("AF: %04x I: %04x\n", + g_current_regs[XCPT_AF], g_current_regs[XCPT_I]); + lldbg("BC: %04x DE: %04x HL: %04x\n", + g_current_regs[XCPT_BC], g_current_regs[XCPT_DE], g_current_regs[XCPT_HL]); + lldbg("IX: %04x IY: %04x\n", + g_current_regs[XCPT_IX], g_current_regs[XCPT_IY]); + lldbg("SP: %04x PC: %04x\n" + g_current_regs[XCPT_SP], g_current_regs[XCPT_PC]); +#else + lldbg("AF: %06x I: %06x\n", + g_current_regs[XCPT_AF], g_current_regs[XCPT_I]); + lldbg("BC: %06x DE: %06x HL: %06x\n", + g_current_regs[XCPT_BC], g_current_regs[XCPT_DE], g_current_regs[XCPT_HL]); + lldbg("IX: %06x IY: %06x\n", + g_current_regs[XCPT_IX], g_current_regs[XCPT_IY]); + lldbg("SP: %06x PC: %06x\n" + g_current_regs[XCPT_SP], g_current_regs[XCPT_PC]); +#endif + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z80/src/ez80/ez80_restorecontext.asm b/arch/z80/src/ez80/ez80_restorecontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..c90ce808fae243db973840507ff882683c7a8c68 --- /dev/null +++ b/arch/z80/src/ez80/ez80_restorecontext.asm @@ -0,0 +1,110 @@ +;************************************************************************** +; arch/z80/src/ez80/ez80_restorcontext.asm +; +; Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Global Symbols Imported +;************************************************************************** + +;************************************************************************** +; Global Symbols Expported +;************************************************************************** + + xdef _ez80_restorecontext + +;************************************************************************** +; Code +;************************************************************************** + + segment CODE + .assume ADL=1 + +;************************************************************************** +; ez80_restorecontext +;************************************************************************** + +_ez80_restorecontext: + ; On entry, stack contains return address (not used), then address + ; of the register save structure + + ; Discard the return address, we won't be returning + + pop hl + + ; Get the address of the beginning of the state save area. Each + ; pop will increment to the next element of the structure + + pop hl ; BC = Address of save structure + ld sp, hl ; SP points to top of storage area + + ; Disable interrupts while we muck with the alternative registers. The + ; Correct interrupt state will be restore below + + di + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in parity + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + pop hl ; Offset 5: HL' = Stack pointer after return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + pop de ; DE' = return address + ld sp, hl ; Set SP = saved stack pointer value before return + push de ; Save return address for ret instruction + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, noinrestore ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes.. Enable interrupts + ret ; and return +noinrestore: + ex af, af' ; Restore AF + ret ; Return with interrupts disabled + end + diff --git a/arch/z80/src/ez80/ez80_saveusercontext.asm b/arch/z80/src/ez80/ez80_saveusercontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..429dc3dd57a686b328853dd5e4b92af85521ebd8 --- /dev/null +++ b/arch/z80/src/ez80/ez80_saveusercontext.asm @@ -0,0 +1,172 @@ +;************************************************************************* +; arch/z80/src/ez80/ez80_saveusercontext.asm +; +; Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************* + +;************************************************************************** +; Global Symbols Imported +;************************************************************************** + +;************************************************************************** +; Global Symbols Expported +;************************************************************************** + + xdef _ez80_saveusercontext + +;************************************************************************* +; Constants +;************************************************************************* + + CONFIG_EZ80_Z80MODE equ 0 + + .if CONFIG_EZ80_Z80MODE + ; Register save area layout + + XCPT_I equ 2*0 ; Offset 0: Saved I w/interrupt state in parity + XCPT_BC equ 2*1 ; Offset 1: Saved BC register + XCPT_DE equ 2*2 ; Offset 2: Saved DE register + XCPT_IX equ 2*3 ; Offset 3: Saved IX register + XCPT_IY equ 2*4 ; Offset 4: Saved IY register + XCPT_SP equ 2*5 ; Offset 5: Offset to SP at time of interrupt + XCPT_HL equ 2*6 ; Offset 6: Saved HL register + XCPT_AF equ 2*7 ; Offset 7: Saved AF register + XCPT_PC equ 2*8 ; Offset 8: Offset to PC at time of interrupt + + ; Stack frame + + FRAME_IY equ 2*0 ; Location of IY on the stack + FRAME_IX equ 2*1 ; Location of IX on the stack + FRAME_RET equ 2*2 ; Location of return address on the stack + FRAME_REGS equ 2*3 ; Location of reg save area on stack + + SP_OFFSET equ 2*3 + .else + ; Register save area layout + + XCPT_I equ 3*0 ; Offset 0: Saved I w/interrupt state in parity + XCPT_BC equ 3*1 ; Offset 1: Saved BC register + XCPT_DE equ 3*2 ; Offset 2: Saved DE register + XCPT_IX equ 3*3 ; Offset 3: Saved IX register + XCPT_IY equ 3*4 ; Offset 4: Saved IY register + XCPT_SP equ 3*5 ; Offset 5: Offset to SP at time of interrupt + XCPT_HL equ 3*6 ; Offset 6: Saved HL register + XCPT_AF equ 3*7 ; Offset 7: Saved AF register + XCPT_PC equ 3*8 ; Offset 8: Offset to PC at time of interrupt .endif + + ; Stack frame + + FRAME_IY equ 3*0 ; Location of IY on the stack + FRAME_IX equ 3*1 ; Location of IX on the stack + FRAME_RET equ 3*2 ; Location of return address on the stack + FRAME_REGS equ 3*3 ; Location of reg save area on stack + + SP_OFFSET equ 3*3 + .endif + +;************************************************************************** +; Code +;************************************************************************** + + segment CODE + .assume ADL=1 + +;************************************************************************* +; Name: z80_saveusercontext +;************************************************************************* + +_ez80_saveusercontext: + ; Set up a stack frame + + push ix ; Save IX and IY + push iy + ld ix, #0 + add ix, sp ; IX = stack frame + + ; Fetch the address of the save area + + ld de, (ix + FRAME_REGS) ; DE = save area address + ld iy, #0 + add iy, de ; IY = save area address + + ; Then save the registers + + ; Save the current interrupt state at offset 0 + + ld a, i ; Get interrupt state in parity bit + push af + pop hl + ld (iy + XCPT_I), hl ; Index 0: I w/interrupt state in parity/overflow + + ; Save BC at offset 1 + + ld (iy + XCPT_BC), bc ; Index 1: BC + + ; DE is not preserved (Index 2) + + ; Save IX at offset 3 + + ld hl, (ix + FRAME_IX) ; HL = Saved alue of IX + ld (iy + XCPT_IX), hl ; Index 3: IX + + ; Save IY at index 4 + + ld hl, (ix + FRAME_IY) ; HL = Saved value of IY + ld (iy + XCPT_IY), hl ; Index 4: IY + + ; Save that stack pointer as it would be upon return in offset 5 + + ld hl, #SP_OFFSET ; Value of stack pointer on return + add hl, sp + ld (iy + XCPT_SP), hl ; Index 5 SP + + ; HL is saved as the value 1 at offset 6 + + ld hl, #1 + ld (iy + XCPT_HL), hl ; Index 2: HL on return (=1) + + ; AF is not preserved (offset 7) + + ; Save the return address at index 8 + + ld hl, (ix + FRAME_RET) ; HL = Saved return address + ld (iy + XCPT_PC), hl ; Index 8: PC + + ; Return the value 0 + + ld hl, #0 + + pop iy + pop ix + ret + end + diff --git a/arch/z80/src/ez80/ez80_schedulesigaction.c b/arch/z80/src/ez80/ez80_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..33d6c11b5f2a0b45ac61e6bb774f5e7eeddc32c9 --- /dev/null +++ b/arch/z80/src/ez80/ez80_schedulesigaction.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_schedulesigaction.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_sigsetup + ****************************************************************************/ + +static void ez80_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs) +{ + /* Save the return address and interrupt state. These will be restored by + * the signal trampoline after the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = regs[XCPT_PC]; + tcb->xcp.saved_i = regs[XCPT_I]; + + /* Then set up to vector to the trampoline with interrupts disabled */ + + regs[XCPT_PC] = (chipreg_t)up_sigdeliver; + regs[XCPT_I] = 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + sdbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!IN_INTERRUPT()) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we + * will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + ez80_sigsetup(tcb, sigdeliver, IRQ_STATE()); + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + SAVE_IRQCONTEXT(tcb); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an interrupt + * handler or (2) we are not in an interrupt handler and the running task + * is signalling some non-running task. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + ez80_sigsetup(tcb, sigdeliver, tcb->xcp.regs); + } + } + + leave_critical_section(flags); +} + +#endif /* CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/z80/src/ez80/ez80_serial.c b/arch/z80/src/ez80/ez80_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..4fbfdda7d57f196a6088a49b135cb41831b066c7 --- /dev/null +++ b/arch/z80/src/ez80/ez80_serial.c @@ -0,0 +1,843 @@ +/**************************************************************************** + * arch/z80/src/ez08/ez80_serial.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ez80_dev_s +{ + uint16_t uartbase; /* Base address of UART registers */ + unsigned int baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 (vs 1) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int ez80_setup(struct uart_dev_s *dev); +static void ez80_shutdown(struct uart_dev_s *dev); +static int ez80_attach(struct uart_dev_s *dev); +static void ez80_detach(struct uart_dev_s *dev); +static int ez80_interrupt(int irq, void *context); +static int ez80_ioctl(struct file *filep, int cmd, unsigned long arg); +static int ez80_receive(struct uart_dev_s *dev, unsigned int *status); +static void ez80_rxint(struct uart_dev_s *dev, bool enable); +static bool ez80_rxavailable(struct uart_dev_s *dev); +static void ez80_send(struct uart_dev_s *dev, int ch); +static void ez80_txint(struct uart_dev_s *dev, bool enable); +static bool ez80_txready(struct uart_dev_s *dev); +static bool ez80_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + ez80_setup, /* setup */ + ez80_shutdown, /* shutdown */ + ez80_attach, /* attach */ + ez80_detach, /* detach */ + ez80_ioctl, /* ioctl */ + ez80_receive, /* receive */ + ez80_rxint, /* rxint */ + ez80_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif + ez80_send, /* send */ + ez80_txint, /* txint */ + ez80_txready, /* txready */ + ez80_txempty /* txempty */ +}; + +/* I/O buffers */ + +#ifdef CONFIG_EZ80_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_EZ80_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +/* This describes the state of the UART0 port. */ + +#ifdef CONFIG_EZ80_UART0 +static struct ez80_dev_s g_uart0priv = +{ + EZ80_UART0_BASE, /* uartbase */ + CONFIG_UART0_BAUD, /* baud */ + EZ80_UART0_IRQ, /* irq */ + CONFIG_UART0_PARITY, /* parity */ + CONFIG_UART0_BITS, /* bits */ + CONFIG_UART0_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart0port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART0_TXBUFSIZE, /* xmit.size */ + g_uart0txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART0_RXBUFSIZE, /* recv.size */ + g_uart0rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart0priv, /* priv */ +}; +#endif + +/* This describes the state of the UART1 port. */ + +#ifdef CONFIG_EZ80_UART1 +static struct ez80_dev_s g_uart1priv = +{ + EZ80_UART1_BASE, /* uartbase */ + CONFIG_UART1_BAUD, /* baud */ + EZ80_UART1_IRQ, /* irq */ + CONFIG_UART1_PARITY, /* parity */ + CONFIG_UART1_BITS, /* bits */ + CONFIG_UART1_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart1port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART1_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART1_TXBUFSIZE, /* xmit.size */ + g_uart1txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART1_RXBUFSIZE, /* recv.size */ + g_uart1rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart1priv, /* priv */ +}; +#endif + +/* Now, which one with be tty0/console and which tty1? */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_EZ80_UART0) +# define CONSOLE_DEV g_uart0port +# define TTYS0_DEV g_uart0port +# if defined(CONFIG_EZ80_UART1) +# define TTYS1_DEV g_uart1port +# endif +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_EZ80_UART1) +# define CONSOLE_DEV g_uart1port +# define TTYS0_DEV g_uart1port +# if defined(CONFIG_EZ80_UART0) +# define TTYS1_DEV g_uart0port +# endif +#elif defined(CONFIG_EZ80_UART0) +# define TTYS0_DEV g_uart0port +# if defined(CONFIG_EZ80_UART1) +# define TTYS1_DEV g_uart1port +# endif +#elif defined(CONFIG_EZ80_UART0) +# define TTYS0_DEV g_uart1port +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_serialin + ****************************************************************************/ + +static inline uint8_t ez80_serialin(struct ez80_dev_s *priv, uint8_t offset) +{ + return inp(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: ez80_serialout + ****************************************************************************/ + +static inline void ez80_serialout(struct ez80_dev_s *priv, uint8_t offset, + uint8_t value) +{ + outp(priv->uartbase + offset, value); +} + +/**************************************************************************** + * Name: ez80_disableuartint + ****************************************************************************/ + +static inline void ez80_disableuartint(struct ez80_dev_s *priv) +{ + uint8_t ier = ez80_serialin(priv, EZ80_UART_IER); + ier &= ~EZ80_UARTEIR_INTMASK; + ez80_serialout(priv, EZ80_UART_IER, ier); +} + +/**************************************************************************** + * Name: ez80_restoreuartint + ****************************************************************************/ + +static inline void ez80_restoreuartint(struct ez80_dev_s *priv, uint8_t bits) +{ + uint8_t ier = ez80_serialin(priv, EZ80_UART_IER); + ier |= bits & (EZ80_UARTEIR_TIE|EZ80_UARTEIR_RIE); + ez80_serialout(priv, EZ80_UART_IER, ier); +} + +/**************************************************************************** + * Name: ez80_waittxready + ****************************************************************************/ + +static inline void ez80_waittxready(struct ez80_dev_s *priv) +{ + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if ((ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0) + { + break; + } + } +} + +/**************************************************************************** + * Name: ez80_setbaud + ****************************************************************************/ + +static inline void ez80_setbaud(struct ez80_dev_s *priv, uint24_t baud) +{ + uint32_t brg_divisor; + uint8_t lctl; + + /* The resulting BAUD and depends on the system clock frequency and the + * BRG divisor as follows: + * + * BAUD = SYSTEM_CLOCK_FREQUENCY / (16 * BRG_Divisor) + * + * Or + * + * BRG_Divisor = SYSTEM_CLOCK_FREQUENCY / 16 / BAUD + */ + + brg_divisor = (ez80_systemclock + (baud << 3)) / (baud << 4); + + /* Set the DLAB bit to enable access to the BRG registers */ + + lctl = ez80_serialin(priv, EZ80_UART_LCTL); + lctl |= EZ80_UARTLCTL_DLAB; + ez80_serialout(priv, EZ80_UART_LCTL, lctl); + + ez80_serialout(priv, EZ80_UART_BRGL, (uint8_t)(brg_divisor & 0xff)); + ez80_serialout(priv, EZ80_UART_BRGH, (uint8_t)(brg_divisor >> 8)); + + lctl &= ~EZ80_UARTLCTL_DLAB; + ez80_serialout(priv, EZ80_UART_LCTL, lctl); +} + +/**************************************************************************** + * Name: ez80_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is called + * the first time that the serial port is opened. + * + ****************************************************************************/ + +static int ez80_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct ez80_dev_s *priv = dev->priv; + uint8_t reg; + uint8_t cval; + + if (priv->bits == 7) + { + cval = EZ80_UARTCHAR_7BITS; + } + else + { + cval = EZ80_UARTCHAR_8BITS; + } + + if (priv->stopbits2) + { + cval |= EZ80_UARTLCTL_2STOP; + } + + if (priv->parity == 1) /* Odd parity */ + { + cval |= (EZ80_UARTLCTL_PEN); + } + else if (priv->parity == 2) /* Even parity */ + { + cval |= (EZ80_UARTLCTL_PEN|EZ80_UARTLCTL_EPS); + } + + /* Set the baud rate */ + + ez80_disableuartint(priv); + ez80_setbaud(priv, priv->baud); + ez80_serialout(priv, EZ80_UART_MCTL, 0); + + /* Set the character properties */ + + reg = (ez80_serialin(priv, EZ80_UART_LCTL) & ~EZ80_UARTLCTL_MASK) | cval; + ez80_serialout(priv, EZ80_UART_LCTL, reg); + + /* Enable and flush the receive FIFO */ + + reg = EZ80_UARTFCTL_FIFOEN; + ez80_serialout(priv, EZ80_UART_FCTL, reg); + reg |= (EZ80_UARTFCTL_CLRTxF|EZ80_UARTFCTL_CLRRxF); + ez80_serialout(priv, EZ80_UART_FCTL, reg); + + /* Set the receive trigger level to 4 */ + + reg |= EZ80_UARTTRIG_4; + ez80_serialout(priv, EZ80_UART_FCTL, reg); +#endif + return OK; +} + +/**************************************************************************** + * Name: ez80_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void ez80_shutdown(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + ez80_disableuartint(priv); +} + +/**************************************************************************** + * Name: ez80_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int ez80_attach(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + + /* Attach the IRQ */ + + return irq_attach(priv->irq, ez80_interrupt); +} + +/**************************************************************************** + * Name: ez80_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void ez80_detach(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + ez80_disableuartint(priv); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: ez80_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int ez80_interrupt(int irq, void *context) +{ + struct uart_dev_s *dev = NULL; + struct ez80_dev_s *priv; + volatile uint32_t cause; + +#ifdef CONFIG_EZ80_UART0 + if (g_uart0priv.irq == irq) + { + dev = &g_uart0port; + } + else +#endif +#ifdef CONFIG_EZ80_UART1 + if (g_uart1priv.irq == irq) + { + dev = &g_uart1port; + } + else +#endif + { + PANIC(); + } + priv = (struct ez80_dev_s*)dev->priv; + + cause = ez80_serialin(priv, EZ80_UART_IIR) & EZ80_UARTIIR_CAUSEMASK; + + /* Check for character timeout (CTO) or Receiver Data Ready (RDR) */ + + if (cause == EZ80_UARTINSTS_CTO || cause == EZ80_UARTINSTS_RDR) + { + /* Receive characters from the RX fifo */ + + uart_recvchars(dev); + } + + /* Check for transmission buffer empty */ + + else if (cause == EZ80_UARTINSTS_TBE) + { + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: ez80_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int ez80_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: ez80_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * the return 'status'. + * + ****************************************************************************/ + +static int ez80_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + uint8_t rbr = ez80_serialin(priv, EZ80_UART_RBR); + uint8_t lsr = ez80_serialin(priv, EZ80_UART_LSR); + + *status = (unsigned int)lsr; + return rbr; +} + +/**************************************************************************** + * Name: ez80_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void ez80_rxint(struct uart_dev_s *dev, bool enable) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + uint8_t ier = ez80_serialin(priv, EZ80_UART_IER); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + ier |= EZ80_UARTEIR_RIE; + ez80_serialout(priv, EZ80_UART_IER, ier); +#endif + } + else + { + ier &= ~EZ80_UARTEIR_RIE; + ez80_serialout(priv, EZ80_UART_IER, ier); + } +} + +/**************************************************************************** + * Name: ez80_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool ez80_rxavailable(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_DR) != 0; +} + +/**************************************************************************** + * Name: ez80_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void ez80_send(struct uart_dev_s *dev, int ch) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + ez80_serialout(priv, EZ80_UART_THR, (uint8_t)ch); +} + +/**************************************************************************** + * Name: ez80_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void ez80_txint(struct uart_dev_s *dev, bool enable) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + uint8_t ier = ez80_serialin(priv, EZ80_UART_IER); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + ier |= EZ80_UARTEIR_TIE; + ez80_serialout(priv, EZ80_UART_IER, ier); +#endif + } + else + { + ier &= ~EZ80_UARTEIR_TIE; + ez80_serialout(priv, EZ80_UART_IER, ier); + } +} + +/**************************************************************************** + * Name: ez80_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool ez80_txready(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0; +} + +/**************************************************************************** + * Name: ez80_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool ez80_txempty(struct uart_dev_s *dev) +{ + struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; + return (ez80_serialin(priv, EZ80_UART_LSR) & EZ80_UARTLSR_TEMT) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + uint8_t regval; + + /* Make sure that all UART interrupts are disabled */ + + ez80_disableuartint(TTYS0_DEV.priv); +#ifdef TTYS1_DEV + ez80_disableuartint(TTYS1_DEV.priv); +#endif + + /* Configure pins for usage of UARTs */ + +#ifdef CONFIG_EZ80_UART0 + /* Set Port D, pins 0 and 1 for their alternate function (Mode 7) to enable UART0 */ + + regval = inp(EZ80_PD_DDR); + regval |= 3; + outp(EZ80_PD_DDR, regval); + + regval = inp(EZ80_PD_ALT1); + regval &= ~3; + outp(EZ80_PD_ALT1, regval); + + regval = inp(EZ80_PD_ALT2); + regval |= 3; + outp(EZ80_PD_ALT2, regval); +#endif + +#ifdef CONFIG_EZ80_UART1 + /* Set Port C, pins 0 and 1 for their alternate function (Mode 7) to enable UART1 */ + + regval = inp(EZ80_PC_DDR); + regval |= 3; + outp(EZ80_PC_DDR, regval); + + regval = inp(EZ80_PC_ALT1); + regval &= ~3; + outp(EZ80_PC_ALT1, regval); + + regval = inp(EZ80_PC_ALT2); + regval |= 3; + outp(EZ80_PC_ALT2, regval); +#endif + + /* If there is a console, then configure the console now */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + ez80_setup(&CONSOLE_DEV); +#endif + + /* Register console and tty devices */ + +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef CONSOLE_DEV + struct ez80_dev_s *priv = (struct ez80_dev_s*)CONSOLE_DEV.priv; + uint8_t ier = ez80_serialin(priv, EZ80_UART_IER); + + ez80_disableuartint(priv); + + /* Check for LF */ + + if (ch == '\n') + { + /* Output CR before LF*/ + + ez80_waittxready(priv); + ez80_serialout(priv, EZ80_UART_THR, '\r'); + } + + /* Output the character */ + + ez80_waittxready(priv); + ez80_serialout(priv, EZ80_UART_THR, (uint8_t)ch); + + /* Wait for the character to be sent before re-enabling interrupts */ + + ez80_waittxready(priv); + ez80_restoreuartint(priv, ier); + return ch; +#endif +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE +# define ez80_inp(offs) inp((EZ80_UART1_BASE+(offs))) +# define ez80_outp(offs,val) outp((EZ80_UART1_BASE+(offs)), (val)) +#else +# define ez80_inp(offs) inp((EZ80_UART0_BASE+(offs))) +# define ez80_outp(offs,val) outp((EZ80_UART0_BASE+(offs)), (val)) +#endif + +#define ez80_txready() ((ez80_inp(EZ80_UART_LSR) & EZ80_UARTLSR_THRE) != 0) +#define ez80_send(ch) ez80_outp(EZ80_UART_THR, ch) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_putc + ****************************************************************************/ + +static void ez80_putc(int ch) +{ + int tmp; + for (tmp = 1000 ; tmp > 0 && !ez80_txready(); tmp--); + ez80_send(ch); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Output CR before LF */ + + ez80_putc('\r'); + } + + /* Output character */ + + ez80_putc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/z80/src/ez80/ez80_sigdeliver.c b/arch/z80/src/ez80/ez80_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..657961ce59eb36a80e96c2329f63db2f8b808246 --- /dev/null +++ b/arch/z80/src/ez80/ez80_sigdeliver.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_sigdeliver.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + FAR struct tcb_s *rtcb = this_task(); + chipreg_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + ez80_copystate(regs, rtcb->xcp.regs); + regs[XCPT_PC] = rtcb->xcp.saved_pc; + regs[XCPT_I] = rtcb->xcp.saved_i; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(regs[XCPT_I]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of + * execution. + */ + + board_autoled_off(LED_SIGNAL); + ez80_restorecontext(regs); +#endif +} + +#endif /* CONFIG_DISABLE_SIGNALS */ diff --git a/arch/z80/src/ez80/ez80_spi.c b/arch/z80/src/ez80/ez80_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..a2f1c4c535dbdb4841a925ba635932db3903e7e9 --- /dev/null +++ b/arch/z80/src/ez80/ez80_spi.c @@ -0,0 +1,501 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_spi.c + * + * Copyright (C) 2009-2010, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "ez80f91_spi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_EZ80F91 +# define GPIOB_SPI_PINSET 0x38 /* MISO+MSOI+SCK. Excludes SS */ +#else +# error "Check GPIO initialization for this chip" +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR uint8_t *buffer, + size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct spi_ops_s g_spiops = +{ + spi_lock, + ez80_spiselect, /* select: Provided externally by board logic */ + spi_setfrequency, + spi_setmode, + NULL, /* setbits: Variable number of bits not implemented */ +#ifdef CONFIG_SPI_HWFEATURES + NULL, /* hwfeatures: Not supported */ +#endif + ez80_spistatus, /* status: Provided externally by board logic */ +#ifdef CONFIG_SPI_CMDDATA + ez80_spicmddata, +#endif + spi_send, + spi_sndblock, + spi_recvblock, + 0 /* registercallback: Not yet implemented */ +}; + +/* This supports is only a single SPI bus/port. If you port this to an + * architecture with multiple SPI busses/ports, then (1) you must create + * a structure, say ez80_spidev_s, containing both struct spi_dev_s and + * the mutual exclusion semaphored, and (2) the following must become an + * array with one 'struct spi_dev_s' instance per bus. + */ + +static struct spi_dev_s g_spidev = {&g_spiops}; +static sem_t g_exclsem = SEM_INITIALIZER(1); /* For mutually exclusive access */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_exclsem) != 0) + { + /* The only case that an error should occur here is if the wait + * was awakened by a signal. + */ + + DEBUGASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&g_exclsem); + } + + return OK; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + /* We want select divisor to provide the highest frequency (SPIR) that does NOT + * exceed the requested frequency.: + * + * SPIR <= System Clock Frequency / (2 * BRG) + * + * So + * + * BRG >= System Clock Frequency / (2 * SPIR) + */ + + uint32_t brg = ((EZ80_SYS_CLK_FREQ+1)/2 + frequency - 1) / frequency; + + /* "When configured as a Master, the 16-bit divisor value must be between + * 0003h and FFFFh, inclusive. When configured as a Slave, the 16-bit + * divisor value must be between 0004h and FFFFh, inclusive." + */ + + if (brg < 3) + { + brg = 3; + } + else if (brg > 0xffff) + { + brg = 0xfff; + } + + outp(EZ80_SPI_BRG_L, brg & 0xff); + outp(EZ80_SPI_BRG_L, (brg >> 8) & 0xff); + + return ((EZ80_SYS_CLK_FREQ+1)/2 + brg - 1) / brg; +} + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. Optional. See enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + uint8_t modebits; + uint8_t regval; + + /* Select the CTL register bits based on the selected mode */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */ + modebits = 0; + break; + + case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */ + modebits = SPI_CTL_CPHA; + break; + + case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */ + modebits = SPI_CTL_CPOL; + break; + + case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */ + modebits = (SPI_CTL_CPOL|SPI_CTL_CPHA); + break; + + default: + return; + } + + /* Then set those bits in the CTL register */ + + regval = inp(EZ80_SPI_CTL); + regval &= ~(SPI_CTL_CPOL|SPI_CTL_CPHA); + regval |= modebits; + outp(EZ80_SPI_CTL, regval); +} + +/**************************************************************************** + * Name: spi_waitspif + * + * Description: + * Wait for the SPIF bit to be set in the status register signifying the + * the data transfer was finished. + * + * Input Parameters: + * None + * + * Returned Value: + * Status register mode bits + * + ****************************************************************************/ + +static uint8_t spi_waitspif(void) +{ + uint8_t status; + + /* Wait for the device to be ready to accept another byte (or for an error + * to be reported + */ + + do + { + status = inp(EZ80_SPI_SR) & (SPI_SR_SPIF|SPI_SR_WCOL|SPI_SR_MODF); + } + while (status == 0); + return status; +} + +/**************************************************************************** + * Name: spi_transfer + * + * Description: + * Send one byte on SPI, return the response + * + * Input Parameters: + * ch - the byte to send + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint8_t spi_transfer(uint8_t ch) +{ + uint8_t status; + + /* Send the byte, repeating if some error occurs */ + + for (;;) + { + outp(EZ80_SPI_TSR, ch); + + /* Wait for the device to be ready to accept another byte */ + + status = spi_waitspif(); + if ((status & SPI_SR_SPIF) != 0) + { + return inp(EZ80_SPI_RBR); + } + } +} + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + return spi_transfer((uint8_t)wd); +} + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer of data to be sent + * buflen - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, + size_t buflen) +{ + FAR const uint8_t *ptr = (FAR const uint8_t*)buffer; + + /* Loop while there are bytes remaining to be sent */ + + while (buflen-- > 0) + { + (void)spi_transfer(*ptr++); + } +} + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Revice a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the buffer in which to recieve data + * buflen - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t buflen) +{ + FAR uint8_t *ptr = (FAR uint8_t*)buffer; + + /* Loop while thre are bytes remaining to be sent */ + + while (buflen-- > 0) + { + *ptr++ = spi_transfer(0xff); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ez80_spibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *ez80_spibus_initialize(int port) +{ + uint8_t regval; + + /* Only the SPI1 interface is supported */ + +#ifdef CONFIG_DEBUG + if (port != 1) + { + return NULL; + } +#endif + + /* Disable SPI */ + + outp(EZ80_SPI_CTL, 0); + + /* Configure GPIOs. For the eZ80F91, the pin mapping for the four SPI pins + * is: + * + * GPIO ALT MASTER SLAVE COMMENT + * ---- ----- ------- ------- --------------------------------- + * PB2 SS INPUT INPUT Managed by board specific logic + * PB3 SCLK OUTPUT INPUT + * PB4 MISO INPUT OUTPUT + * PB5 MOSI OUTPUT INPUT + * + * Select the alternate function for PB2-5: + */ + +#ifdef CONFIG_ARCH_CHIP_EZ80F91 + regval = inp(EZ80_PB_DDR); + regval |= GPIOB_SPI_PINSET; + outp(EZ80_PB_DDR, regval); + + regval = inp(EZ80_PB_ALT1); + regval &= ~GPIOB_SPI_PINSET; + outp(EZ80_PB_ALT1, regval); + + regval = inp(EZ80_PB_ALT2); + regval |= GPIOB_SPI_PINSET; + outp(EZ80_PB_ALT2, regval); +#else +# error "Check GPIO initialization for this chip" +#endif + + /* Set the initial clock frequency for indentification mode < 400kHz */ + + spi_setfrequency(NULL, 400000); + + /* Enable the SPI. + * NOTE 1: Interrupts are not used in this driver version. + * NOTE 2: Initial mode is mode=0. + */ + + outp(EZ80_SPI_CTL, SPI_CTL_SPIEN|SPI_CTL_MASTEREN); + + return &g_spidev; +} diff --git a/arch/z80/src/ez80/ez80_startup.asm b/arch/z80/src/ez80/ez80_startup.asm new file mode 100644 index 0000000000000000000000000000000000000000..af17398132d59bb5d96f86ffb329d8a3814df745 --- /dev/null +++ b/arch/z80/src/ez80/ez80_startup.asm @@ -0,0 +1,155 @@ +;************************************************************************** +; arch/z80/src/ez80/ez80_startup.asm +; +; Copyright (C) 2008 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Included Files +;************************************************************************** + +;************************************************************************** +; Constants +;************************************************************************** + +;************************************************************************** +; Global symbols used +;************************************************************************** + + xref __stack + xref _ez80_init + xref _ez80_initvectors + xref _ez80_initsysclk + xref _ez80_lowinit + xref __low_bss ; Low address of bss segment + xref __len_bss ; Length of bss segment + + xref __low_data ; Address of initialized data section + xref __low_romdata ; Addr of initialized data section in ROM + xref __len_data ; Length of initialized data section + + xref __copy_code_to_ram + xref __len_code + xref __low_code + xref __low_romcode + xref _os_start + xdef _ez80_startup + xdef _ez80_halt + +;************************************************************************** +; Code +;************************************************************************** + + segment CODE + .assume ADL=1 + +;************************************************************************** +; System reset start logic +;************************************************************************** + +_ez80_startup: + ; Set up the stack pointer at the location determined the lincmd + ; file + + ld sp, __stack + + ; Peform chip-specific initialization + + call _ez80_init + + ; initialize the interrupt vector table + + call _ez80_initvectors + + ; Initialize the system clock + + call _ez80_initsysclk + + ; Perform C initializations + ; Clear the uninitialized data section + + ld bc, __len_bss ; Check for non-zero length + ld a, __len_bss >> 16 + or a, c + or a, b + jr z, _ez80_bssdone ; BSS is zero-length ... + xor a, a + ld (__low_bss), a + sbc hl, hl ; hl = 0 + dec bc ; 1st byte's taken care of + sbc hl, bc + jr z, _ez80_bssdone ; Just 1 byte ... + ld hl, __low_bss ; reset hl + ld de, __low_bss + 1 ; [de] = bss + 1 + ldir +_ez80_bssdone: + + ; Copy the initialized data section + ld bc, __len_data ; [bc] = data length + ld a, __len_data >> 16 ; Check for non-zero length + or a, c + or a, b + jr z, _ez80_datadone ; __len_data is zero-length ... + ld hl, __low_romdata ; [hl] = data_copy + ld de, __low_data ; [de] = data + ldir ; Copy the data section +_ez80_datadone: + + ; Copy CODE (which may be in FLASH) to RAM if the + ; copy_code_to_ram symbol is set in the link control file + ld a, __copy_code_to_ram + or a, a + jr z, _ez80_codedone + ld bc, __len_code ; [bc] = code length + ld a, __len_code >> 16 ; Check for non-zero length + or a, c + or a, b + jr z, _ez80_codedone ; __len_code is zero-length + ld hl, __low_romcode ; [hl] = code_copy + ld de, __low_code ; [de] = code + ldir ; Copy the code section +_ez80_codedone: + + ; Perform board-specific initializeation + + call _ez80_lowinit + + ; Then start NuttX + + call _os_start ; jump to the OS entry point + + ; NuttX will never return, but just in case... + +_ez80_halt: + halt ; We should never get here + jp _ez80_halt + diff --git a/arch/z80/src/ez80/ez80_timerisr.c b/arch/z80/src/ez80/ez80_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..26a4fae447a92afcd3bee993afa498d8d0c4658a --- /dev/null +++ b/arch/z80/src/ez80/ez80_timerisr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/z80/src/ez80/ez80_timerisr.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the system. + * + ****************************************************************************/ + +int up_timerisr(int irq, chipreg_t *regs) +{ + /* Read the appropriate timer0 register to clear the interrupt */ + +#ifdef _EZ80F91 + (void)inp(EZ80_TMR0_IIR); +#else + /* _EZ80190, _EZ80L92, _EZ80F92, _EZ80F93 */ + + (void)inp(EZ80_TMR0_CTL); +#endif + + /* Process timer interrupt */ + + sched_process_timer(); + + /* Architecture specific hook into the timer interrupt handler */ + +#ifdef CONFIG_ARCH_TIMERHOOK + up_timerhook(); +#endif + + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint16_t reload; + + /* Disable the timer */ + + outp(EZ80_TMR0_CTL, 0x00); + + /* Attach system timer interrupts */ + + irq_attach(EZ80_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + + /* Set up the timer reload value */ + /* Write to the timer reload register to set the reload value. + * + * In continuous mode: + * + * timer_period = reload_value x clock_divider / system_clock_frequency + * or + * reload_value = (timer_period * system_clock_frequency) / clock_divider + * + * For timer_period=10mS, and clock_divider=16, that would yield: + * + * reload_value = system_clock_frequency / 1600 + * + * For a system timer of 50,000,000 that would result in a reload value of + * 31,250 + * + * NOTE: The system clock frequency value is defined in the board.h file + */ + + reload = (uint16_t)(ez80_systemclock / 1600); + outp(EZ80_TMR0_RRH, (uint8_t)(reload >> 8)); + outp(EZ80_TMR0_RRL, (uint8_t)(reload)); + + /* Clear any pending timer interrupts */ + +#if defined(_EZ80F91) + (void)inp(EZ80_TMR0_IIR); +#elif defined(_EZ80L92) || defined(_EZ80F92) ||defined(_EZ80F93) + (void)inp(EZ80_TMR0_CTL); +#endif + + /* Configure and enable the timer */ + +#if defined(_EZ80190) + outp(EZ80_TMR0_CTL, 0x5f); +#elif defined(_EZ80F91) + outp(EZ80_TMR0_CTL, (EZ80_TMRCLKDIV_16|EZ80_TMRCTL_TIMCONT|EZ80_TMRCTL_RLD|EZ80_TMRCTL_TIMEN)); +#elif defined(_EZ80L92) || defined(_EZ80F92) ||defined(_EZ80F93) + outp(EZ80_TMR0_CTL, 0x57); +#endif + +/* Enable timer end-of-count interrupts */ + +#if defined(_EZ80F91) + outp(EZ80_TMR0_IER, EZ80_TMRIER_EOCEN); +#endif +} diff --git a/arch/z80/src/ez80/ez80_vectors.asm b/arch/z80/src/ez80/ez80_vectors.asm new file mode 100644 index 0000000000000000000000000000000000000000..107b570c4be3dfc5281403010e170e105e163589 --- /dev/null +++ b/arch/z80/src/ez80/ez80_vectors.asm @@ -0,0 +1,340 @@ +;************************************************************************** +; arch/z80/src/ez80/ez80_vectors.asm +; +; Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Constants +;************************************************************************** + +NVECTORS EQU 64 ; max possible interrupt vectors + +;* Bits in the Z80 FLAGS register ***************************************** + +EZ80_C_FLAG EQU 01h ; Bit 0: Carry flag +EZ80_N_FLAG EQU 02h ; Bit 1: Add/Subtract flag +EZ80_PV_FLAG EQU 04h ; Bit 2: Parity/Overflow flag +EZ80_H_FLAG EQU 10h ; Bit 4: Half carry flag +EZ80_Z_FLAG EQU 40h ; Bit 5: Zero flag +EZ80_S_FLAG EQU 80h ; Bit 7: Sign flag + +;* The IRQ number to use for unused vectors + +EZ80_UNUSED EQU 40h + +;************************************************************************** +; Global Symbols Imported +;************************************************************************** + + xref _ez80_startup + xref _up_doirq + +;************************************************************************** +; Global Symbols Exported +;************************************************************************** + + xdef _ez80_reset + xdef _ez80_initvectors + xdef _ez80_handlers + xdef _ez80_rstcommon + xdef _ez80_initvectors + xdef _ez80_vectable + +;************************************************************************** +; Macros +;************************************************************************** + +; Define one reset handler +; 1. Disable interrupts +; 2. Dlear mixed memory mode (MADL) flag +; 3. jump to initialization procedure with jp.lil to set ADL +rstvector: macro + di + rsmix + jp.lil _ez80_startup + endmac rstvector + +; Define one interrupt handler +irqhandler: macro vectno + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #vectno ; A = vector number + jp _ez80_rstcommon ; Remaining RST handling is common + endmac irqhandler + +;************************************************************************** +; Reset entry points +;************************************************************************** + + define .RESET, space = ROM + segment .RESET + +_ez80_reset: +_rst0: + rstvector +_rst8: + rstvector +_rst10: + rstvector +_rst18: + rstvector +_rst20: + rstvector +_rst28: + rstvector +_rst30: + rstvector +_rst38: + rstvector + ds %26 +_nmi: + retn + +;************************************************************************** +; Startup logic +;************************************************************************** + + define .STARTUP, space = ROM + segment .STARTUP + .assume ADL=1 + +;************************************************************************** +; Interrupt Vector Handling +;************************************************************************** + + ; Symbol Val VecNo Addr + ;----------------- --- ----- ----- +_ez80_handlers: + irqhandler 0 ; EZ80_EMACRX_IRQ 0 0 0x040 + handlersize equ $-_ez80handlers + irqhandler 1 ; EZ80_EMACTX_IRQ 1 1 0x044 + irqhandler 2 ; EZ80_EMACSYS_IRQ 2 2 0x048 + irqhandler 3 ; EZ80_PLL_IRQ 3 3 0x04c + irqhandler 4 ; EZ80_FLASH_IRQ 4 4 0x050 + irqhandler 5 ; EZ80_TIMER0_IRQ 5 5 0x054 + irqhandler 6 ; EZ80_TIMER1_IRQ 6 6 0x058 + irqhandler 7 ; EZ80_TIMER2_IRQ 7 7 0x05c + irqhandler 8 ; EZ80_TIMER3_IRQ 8 8 0x060 + irqhandler EZ80_UNUSED ; 9 0x064 + irqhandler EZ80_UNUSED+1 ; 10 0x068 + irqhandler 9 ; EZ80_RTC_IRQ 9 11 0x06C + irqhandler 10 ; EZ80_UART0_IRQ 10 12 0x070 + irqhandler 11 ; EZ80_UART1_IRQ 11 13 0x074 + irqhandler 12 ; EZ80_I2C_IRQ 12 14 0x078 + irqhandler 13 ; EZ80_SPI_IRQ 13 15 0x07c + irqhandler 14 ; EZ80_PORTA0_IRQ 14 16 0x080 + irqhandler 15 ; EZ80_PORTA1_IRQ 15 17 0x084 + irqhandler 16 ; EZ80_PORTA2_IRQ 16 18 0x088 + irqhandler 17 ; EZ80_PORTA3_IRQ 17 19 0x08c + irqhandler 18 ; EZ80_PORTA4_IRQ 18 20 0x090 + irqhandler 19 ; EZ80_PORTA5_IRQ 19 21 0x094 + irqhandler 20 ; EZ80_PORTA6_IRQ 20 22 0x098 + irqhandler 21 ; EZ80_PORTA7_IRQ 21 23 0x09c + irqhandler 22 ; EZ80_PORTB0_IRQ 22 24 0x0a0 + irqhandler 23 ; EZ80_PORTB1_IRQ 23 25 0x0a4 + irqhandler 24 ; EZ80_PORTB2_IRQ 24 26 0x0a8 + irqhandler 25 ; EZ80_PORTB3_IRQ 25 27 0x0ac + irqhandler 26 ; EZ80_PORTB4_IRQ 26 28 0x0b0 + irqhandler 27 ; EZ80_PORTB5_IRQ 27 29 0x0b4 + irqhandler 28 ; EZ80_PORTB6_IRQ 28 20 0x0b8 + irqhandler 29 ; EZ80_PORTB7_IRQ 29 21 0x0bc + irqhandler 30 ; EZ80_PORTC0_IRQ 30 22 0x0c0 + irqhandler 31 ; EZ80_PORTC1_IRQ 31 23 0x0c4 + irqhandler 32 ; EZ80_PORTC2_IRQ 32 24 0x0c8 + irqhandler 33 ; EZ80_PORTC3_IRQ 33 25 0x0cc + irqhandler 34 ; EZ80_PORTC4_IRQ 34 26 0x0d0 + irqhandler 35 ; EZ80_PORTC5_IRQ 35 27 0x0d4 + irqhandler 36 ; EZ80_PORTC6_IRQ 36 28 0x0d8 + irqhandler 37 ; EZ80_PORTC7_IRQ 37 29 0x0dc + irqhandler 38 ; EZ80_PORTD0_IRQ 38 40 0x0e0 + irqhandler 39 ; EZ80_PORTD1_IRQ 39 41 0x0e4 + irqhandler 40 ; EZ80_PORTD2_IRQ 40 42 0x0e8 + irqhandler 41 ; EZ80_PORTD3_IRQ 41 43 0x0ec + irqhandler 42 ; EZ80_PORTD4_IRQ 42 44 0x0f0 + irqhandler 43 ; EZ80_PORTD5_IRQ 43 45 0x0f4 + irqhandler 44 ; EZ80_PORTD6_IRQ 44 46 0x0f8 + irqhandler 45 ; EZ80_PORTD7_IRQ 45 47 0x0fc + irqhandler EZ80_UNUSED+1 ; 48 0x100 + irqhandler EZ80_UNUSED+2 ; 49 0x104 + irqhandler EZ80_UNUSED+3 ; 50 0x108 + irqhandler EZ80_UNUSED+4 ; 51 0x10c + irqhandler EZ80_UNUSED+5 ; 52 0x110 + irqhandler EZ80_UNUSED+6 ; 53 0x114 + irqhandler EZ80_UNUSED+7 ; 54 0x118 + irqhandler EZ80_UNUSED+8 ; 55 0x11c + irqhandler EZ80_UNUSED+9 ; 56 0x120 + irqhandler EZ80_UNUSED+10 ; 57 0x124 + irqhandler EZ80_UNUSED+11 ; 58 0x128 + irqhandler EZ80_UNUSED+12 ; 59 0x12c + irqhandler EZ80_UNUSED+13 ; 60 0x130 + irqhandler EZ80_UNUSED+14 ; 61 0x134 + irqhandler EZ80_UNUSED+15 ; 62 0x138 + irqhandler EZ80_UNUSED+16 ; 63 0x13c + +;************************************************************************** +; Common Interrupt handler +;************************************************************************** + +_ez80_rstcommon: + ; Create a register frame. SP points to top of frame + 4, pushes + ; decrement the stack pointer. Already have + ; + ; Offset 8: Return PC is already on the stack + ; Offset 7: AF (retaining flags) + ; + ; IRQ number is in A + + push hl ; Offset 6: HL + ld hl, #(3*3) ; HL is the value of the stack pointer before + add hl, sp ; the interrupt occurred (3 for PC, AF, HL) + push hl ; Offset 5: Stack pointer + push iy ; Offset 4: IY + push ix ; Offset 3: IX + push de ; Offset 2: DE + push bc ; Offset 1: BC + + ; At this point, we know that interrupts were enabled (or we wouldn't be here + ; so we can save a fake indicationn that will cause interrupts to restored when + ; this context is restored + + ld bc, #EZ80_PV_FLAG ; Parity bit. 1=parity odd, IEF2=1 + push bc ; Offset 0: I with interrupt state in parity + di ; (not necessary) + + ; Call the interrupt decode logic. SP points to the beggining of the reg structure + + ld hl, #0 ; Argument #2 is the beginning of the reg structure + add hl, sp ; + push hl ; Place argument #2 at the top of stack + ld bc, #0 ; BC = reset number + ld c, a ; Save the reset number in C + push bc ; Argument #1 is the Reset number + call _up_doirq ; Decode the IRQ + + ; On return, HL points to the beginning of the reg structure to restore + ; Note that (1) the arguments pushed on the stack are not popped, and (2) the + ; original stack pointer is lost. In the normal case (no context switch), + ; HL will contain the value of the SP before the arguments were pushed. + + ld sp, hl ; Use the new stack pointer + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in parity + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + pop hl ; Offset 5: HL' = Stack pointer after return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + pop de ; Offset 8: Return address + ld sp, hl ; Set SP = saved stack pointer value before return + push de ; Set up for reti + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, nointenable ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes + reti +nointenable: + ex af, af' ; Restore AF + reti + +;************************************************************************** +; Vector Setup Logic +;************************************************************************** + +_ez80_initvectors: + ; Initialize the vector table + + ld iy, _ez80_vectable + ld ix, 4 + ld bc, 4 + ld b, NVECTORS + xor a, a ; Clear carry + ld hl, handlersize + ld de, _ez80_handlers + sbc hl, de ; Length of irq handler in hl + ld d, h + ld e, l + ld hl, _ez80_handlers ; Start of handlers in hl + + ld a, 0 +$1: + ld (iy), hl ; Store IRQ handler + ld (iy+3), a ; Pad to 4 bytes + add hl, de ; Point to next handler + push de + ld de, 4 + add iy, de ; Point to next entry in vector table + pop de + djnz $1 ; Loop until all vectors have been written + + ; Select interrupt mode 2 + + im 2 ; Interrupt mode 2 + + ; Write the address of the vector table into the interrupt vector base + + ld hl, _ez80_vectable >> 8 + ld i, hl + ret + +;************************************************************************** +; Vector Table +;************************************************************************** +; This segment must be aligned on a 512 byte boundary anywhere in RAM +; Each entry will be a 3-byte address in a 4-byte space + + define .IVECTS, space = RAM, align = 200h + segment .IVECTS + + ; The first 64 bytes are not used... the vectors actually start at +0x40 +_ez80_vecreserve: + ds 64 +_ez80_vectable: + ds NVECTORS * 4 diff --git a/arch/z80/src/ez80/ez80f91.h b/arch/z80/src/ez80/ez80f91.h new file mode 100644 index 0000000000000000000000000000000000000000..a1371571b7e2bc3c6bd3ebfe3d6c5bdb633dfcce --- /dev/null +++ b/arch/z80/src/ez80/ez80f91.h @@ -0,0 +1,502 @@ +/************************************************************************************ + * arch/z80/src/ez80/ez80f91.h + * arch/z80/src/chip/ez80f91.h + * + * Copyright (C) 2008, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_EZ80_EZ80F91_H +#define __ARCH_Z80_SRC_EZ80_EZ80F91_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "ez80f91_emac.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Memory map ***********************************************************************/ + +#define EZ80_ONCHIPFLASH 0x000000 /* CS0: 256Kb of on-chip flash */ +#define EZ80_OFFCHIPCS0 0x400000 /* CS0: Off chip use (usually flash) */ +#define EZ80_OFFCHIPCS2 0x800000 /* CS2: Off chip use (e.g. memory mapped I/O) */ +#define EZ80_OFFCHIPCS1 0xc00000 /* CS1: Off chip use (usually SRAM) */ +#define EZ80_EMACSRAM 0xffc000 /* On-chip EMAC SRAM (8Kb) on reset*/ +#define EZ80_ONCHIPSRAM 0xffe000 /* On-chip SRAM (8Kb) on reset */ + +/* Product ID Registers ************************************************************/ + +#define EZ80_ZDI_ID_L 0x00 +#define EZ80_ZDI_ID_H 0x01 +#define EZ80_ZDI_ID_REV 0x02 + +/* Interrupt Registers *************************************************************/ + +#define EZ80_INT_P0 0x10 +#define EZ80_INT_P1 0x11 +#define EZ80_INT_P2 0x12 +#define EZ80_INT_P3 0x13 +#define EZ80_INT_P4 0x14 +#define EZ80_INT_P5 0x15 + +/* EMACC Registers *****************************************************************/ + +#define EZ80_EMAC_TEST 0x20 /* EMAC test register */ +#define EZ80_EMAC_CFG1 0x21 /* EMAC configuration 1 register */ +#define EZ80_EMAC_CFG2 0x22 /* EMAC configuration 2 register */ +#define EZ80_EMAC_CFG3 0x23 /* EMAC configuration 3 register */ +#define EZ80_EMAC_CFG4 0x24 /* EMAC configuration 4 register */ +#define EZ80_EMAC_STAD_0 0x25 /* EMAC station address register 0 */ +#define EZ80_EMAC_STAD_1 0x26 /* EMAC station address register 1 */ +#define EZ80_EMAC_STAD_2 0x27 /* EMAC station address register 2 */ +#define EZ80_EMAC_STAD_3 0x28 /* EMAC station address register 3 */ +#define EZ80_EMAC_STAD_4 0x29 /* EMAC station address register 4 */ +#define EZ80_EMAC_STAD_5 0x2a /* EMAC station address register 5 */ +#define EZ80_EMAC_TPTV_L 0x2b /* Transit pause timer value (low) */ +#define EZ80_EMAC_TPTV_H 0x2c /* Transit pause timer value (high) */ +#define EZ80_EMAC_IPGT 0x2d /* EMAC Interpacket gap register */ +#define EZ80_EMAC_IPGR1 0x2e /* Non-back-to-back IPG register 1 */ +#define EZ80_EMAC_IPGR2 0x2f /* Non-back-to-back IPG register 2 */ +#define EZ80_EMAC_MAXF_L 0x30 /* EMAC maximum frame length register (low) */ +#define EZ80_EMAC_MAXF_H 0x31 /* EMAC maximum frame length register (high) */ +#define EZ80_EMAC_AFR 0x32 /* EMAC address filter register */ +#define EZ80_EMAC_HTBL_0 0x33 /* EMAC hash table register 0 */ +#define EZ80_EMAC_HTBL_1 0x34 /* EMAC hash table register 1 */ +#define EZ80_EMAC_HTBL_2 0x35 /* EMAC hash table register 2 */ +#define EZ80_EMAC_HTBL_3 0x36 /* EMAC hash table register 3 */ +#define EZ80_EMAC_HTBL_4 0x37 /* EMAC hash table register 4 */ +#define EZ80_EMAC_HTBL_5 0x38 /* EMAC hash table register 5 */ +#define EZ80_EMAC_HTBL_6 0x39 /* EMAC hash table register 6 */ +#define EZ80_EMAC_HTBL_7 0x3a /* EMAC hash table register 7 */ +#define EZ80_EMAC_MIIMGT 0x3b /* EMACS MII management register */ +#define EZ80_EMAC_CTLD_L 0x3c /* PHY configuration data register (low) */ +#define EZ80_EMAC_CTLD_H 0x3d /* PHY configuration data register (high) */ +#define EZ80_EMAC_RGAD 0x3e /* PHY address register */ +#define EZ80_EMAC_FIAD 0x3f /* PHY unit select register */ +#define EZ80_EMAC_PTMR 0x40 /* EMAC transmit polling timer register */ +#define EZ80_EMAC_RST 0x41 /* EMAC reset control register */ +#define EZ80_EMAC_TLBP_L 0x42 /* EMAC transmit lower boundary pointer (low) */ +#define EZ80_EMAC_TLBP_H 0x43 /* EMAC transmit lower boundary pointer (high) */ +#define EZ80_EMAC_BP_L 0x44 /* EMAC boundary pointer register (low) */ +#define EZ80_EMAC_BP_H 0x45 /* EMAC boundary pointer register (high) */ +#define EZ80_EMAC_BP_U 0x46 /* EMAC boundary pointer register (upper byte) */ +#define EZ80_EMAC_RHBP_L 0x47 /* EMAC receive high boundary pointer register (low) */ +#define EZ80_EMAC_RHBP_H 0x48 /* EMAC receive high boundary pointer register (high) */ +#define EZ80_EMAC_RRP_L 0x49 /* EMAC receive read pointer (low) */ +#define EZ80_EMAC_RRP_H 0x4a /* EMAC receive read pointer (high) */ +#define EZ80_EMAC_BUFSZ 0x4b /* EMAC buffer size register */ +#define EZ80_EMAC_IEN 0x4c /* EMAC interrupt enable register */ +#define EZ80_EMAC_ISTAT 0x4d /* EMAC interrupt status register */ +#define EZ80_EMAC_PRSD_L 0x4e /* PHY read status data register (low) */ +#define EZ80_EMAC_PRSD_H 0x4f /* PHY read status data register (high) */ +#define EZ80_EMAC_MIISTAT 0x50 /* EMAC MII status register */ +#define EZ80_EMAC_RWP_L 0x51 /* EMAC receive write pointer (low) */ +#define EZ80_EMAC_RWP_H 0x52 /* EMAC receive write pointer (high) */ +#define EZ80_EMAC_TRP_L 0x53 /* EMAC transmit read pointer (low) */ +#define EZ80_EMAC_TRP_H 0x54 /* EMAC transmit read pointer (high) */ +#define EZ80_EMAC_BLKSLFT_L 0x55 /* EMAC receive blocks left register (low) */ +#define EZ80_EMAC_BLKSLFT_H 0x56 /* EMAC receive blocks left register (high) */ +#define EZ80_EMAC_FDATA_L 0x57 /* EMAC FIFO data register (low) */ +#define EZ80_EMAC_FDATA_H 0x58 /* EMAC FIFO data register (high) */ +#define EZ80_EMAC_FFLAGS 0x59 /* EMAC FIFO flags register */ + +/* PLL Registers *******************************************************************/ + +#define EZ80_PLL_DIV_L 0x5c +#define EZ80_PLL_DIV_H 0x5d +#define EZ80_PLL_CTL0 0x5e +#define EZ80_PLL_CTL1 0x5f + +/* Timer Registers *****************************************************************/ + +#define EZ80_TMR0_CTL 0x60 /* RW: Timer 0 control register */ +#define EZ80_TMR0_IER 0x61 /* RW: Timer 0 interrupt enable register */ +#define EZ80_TMR0_IIR 0x62 /* R : Timer 0 interrupt ID register */ +#define EZ80_TMR0_DRL 0x63 /* R : Timer 0 data register (low) */ +#define EZ80_TMR0_DRH 0x64 /* R : Timer 0 data register (high) */ +#define EZ80_TMR0_RRL 0x63 /* W: Timer 0 reload register (low) */ +#define EZ80_TMR0_RRH 0x64 /* W: Timer 0 reload register (high) */ + +#define EZ80_TMR1_CTL 0x65 /* RW: Timer 1 control register */ +#define EZ80_TMR1_IER 0x66 /* RW: Timer 1 interrupt enable register */ +#define EZ80_TMR1_IIR 0x67 /* R : Timer 1 interrupt ID register */ +#define EZ80_TMR1_DRL 0x68 /* R : Timer 1 data register (low) */ +#define EZ80_TMR1_DRH 0x69 /* R : Timer 1 data register (high) */ +#define EZ80_TMR1_RRL 0x68 /* W: Timer 1 reload register (low) */ +#define EZ80_TMR1_RRH 0x69 /* W: Timer 1 reload register (high) */ +#define EZ80_TMR1_CAPCTL 0x6a /* RW: Timer 1 input capture control register */ +#define EZ80_TMR1_CAPAL 0x6b /* R : Timer 1 capture input value A (low) */ +#define EZ80_TMR1_CAPAH 0x6c /* R : Timer 1 capture input value A (high) */ +#define EZ80_TMR1_CAPBL 0x6d /* R : Timer 1 capture input value B (low) */ +#define EZ80_TMR1_CAPBH 0x6e + +#define EZ80_TMR2_CTL 0x6f /* RW: Timer 2 control register */ +#define EZ80_TMR2_IER 0x70 /* RW: Timer 2 interrupt enable register */ +#define EZ80_TMR2_IIR 0x71 /* R : Timer 2 interrupt ID register */ +#define EZ80_TMR2_DRL 0x72 /* R : Timer 2 data register (low) */ +#define EZ80_TMR2_DRH 0x73 /* R : Timer 2 data register (high) */ +#define EZ80_TMR2_RRL 0x72 /* W: Timer 2 reload register (low) */ +#define EZ80_TMR2_RRH 0x73 /* W: Timer 2 reload register (high) */ + +#define EZ80_TMR3_CTL 0x74 /* RW: Timer 3 control register */ +#define EZ80_TMR3_IER 0x75 /* RW: Timer 3 interrupt enable register */ +#define EZ80_TMR3_IIR 0x76 /* R : Timer 3 interrupt ID register */ +#define EZ80_TMR3_DRL 0x77 /* R : Timer 3 data register (low) */ +#define EZ80_TMR3_DRH 0x78 /* R : Timer 3 data register (high) */ +#define EZ80_TMR3_RRL 0x77 /* W: Timer 3 reload register (low) */ +#define EZ80_TMR3_RRH 0x78 /* W: Timer 3 reload register (high) */ +#define EZ80_TMR3_CAPCTL 0x7b /* RW: Timer 3 input capture control register */ +#define EZ80_TMR3_CAPAL 0x7c /* R : Timer 3 capture input value A (low) */ +#define EZ80_TMR3_CAPAH 0x7d /* R : Timer 3 capture input value A (high) */ +#define EZ80_TMR3_CAPBL 0x7e /* R : Timer 3 capture input value B (low) */ +#define EZ80_TMR3_CAPBH 0x7f /* R : Timer 3 capture input value B (high) */ +#define EZ80_TMR3_OCCTL1 0x80 /* RW: Timer 3 output compare control register1 */ +#define EZ80_TMR3_OCCTL2 0x81 /* RW: Timer 3 output compare control register2 */ +#define EZ80_TMR3_OC0L 0x82 /* RW: Timer 3 output compare value 0 (low) */ +#define EZ80_TMR3_OC0H 0x83 /* RW: Timer 3 output compare value 0 (high) */ +#define EZ80_TMR3_OC1L 0x84 /* RW: Timer 3 output compare value 1 (low) */ +#define EZ80_TMR3_OC1H 0x85 /* RW: Timer 3 output compare value 1 (high) */ +#define EZ80_TMR3_OC2L 0x86 /* RW: Timer 3 output compare value 2 (low) */ +#define EZ80_TMR3_OC2H 0x87 /* RW: Timer 3 output compare value 2 (high) */ +#define EZ80_TMR3_OC3L 0x88 /* RW: Timer 3 output compare value 3 (low) */ +#define EZ80_TMR3_OC3H 0x89 /* RW: Timer 3 output compare value 3 (high) */ + +/* TMR0/1/2/3 CTL Register Bit Definitions *******************************************/ + +#define EZ80_TMRCTL_BRKSTOP 0x80 /* Bit 7: Stop timer for debug operation */ +#define EZ80_TMRCTL_CLKSEL 0x60 /* Bits 6-5: Timer source */ +# define EZ80_TMRCLKSEL_SYSCLK 0x00 /* 00: System clock divided by prescaler */ +# define EZ80_TMRCLKSEL_RTC 0x20 /* 01: Real time clock input */ +# define EZ80_TMRCLKSEL_ECF 0x40 /* 10: Event count input, falling edge */ +# define EZ80_TMRCLKSEL_ECR 0x60 /* 11: Event count input, rising edge */ +#define EZ80_TMRCTL_CLKDIV 0x18 /* Bits 3-4: Sysem clock divider */ +# define EZ80_TMRCLKDIV_4 0x00 /* 00: 4 */ +# define EZ80_TMRCLKDIV_16 0x08 /* 01: 16 */ +# define EZ80_TMRCLKDIV_64 0x10 /* 10: 64 */ +# define EZ80_TMRCLKDIV_256 0x18 /* 11: 256 */ +#define EZ80_TMRCTL_TIMCONT 0x04 /* Bit 2: Continuous mode */ +#define EZ80_TMRCTL_RLD 0x02 /* Bit 1: Force reload */ +#define EZ80_TMRCTL_TIMEN 0x01 /* Bit 0: Programmable reload timer enabled */ + +/* TMR0/1/2/3 IER Register Bit Definitions *******************************************/ + /* Bit 7: Reserved */ +#define EZ80_TMRIER_OC3EN 0x40 /* Bit 6: TMR3 OC3 enabled */ +#define EZ80_TMRIER_OC2EN 0x20 /* Bit 5: TMR3 OC2 enabled */ +#define EZ80_TMRIER_OC1EN 0x10 /* Bit 4: TMR3 OC1 enabled */ +#define EZ80_TMRIER_OC0EN 0x08 /* Bit 3: TMR3 OC0 enabled */ +#define EZ80_TMRIER_ICBEN 0x04 /* Bit 2: TMR1/3 capture pin enabled */ +#define EZ80_TMRIER_ICAEN 0x02 /* Bit 1: TMR1/3 capture pin enabled */ +#define EZ80_TMRIER_EOCEN 0x01 /* Bit 0: End of count interrupt enabled */ + +/* TMR0/1/2/3 IER Register Bit Definitions *******************************************/ + /* Bit 7: Reserved */ +#define EZ80_TMRIIR_OC3 0x40 /* Bit 6: TMR3 OC3 */ +#define EZ80_TMRIIR_OC2 0x20 /* Bit 5: TMR3 OC2 */ +#define EZ80_TMRIIR_OC1 0x10 /* Bit 4: TMR3 OC1 */ +#define EZ80_TMRIIR_OC0 0x08 /* Bit 3: TMR3 OC0 */ +#define EZ80_TMRIIR_ICB 0x04 /* Bit 2: TMR1/3 capture pin */ +#define EZ80_TMRIIR_ICA 0x02 /* Bit 1: TMR1/3 capture pin */ +#define EZ80_TMRIIR_EOC 0x01 /* Bit 0: End of count interrupt */ + +/* PWM Registers *********************************************************************/ + +#define EZ80_PWM_CTL1 0x79 +#define EZ80_PWM_CTL2 0x7a +#define EZ80_PWM_CTL3 0x7b +#define EZ80_PWM0R_L 0x7c +#define EZ80_PWM0R_H 0x7d +#define EZ80_PWM1R_L 0x7e +#define EZ80_PWM1R_H 0x7f +#define EZ80_PWM2R_L 0x80 +#define EZ80_PWM2R_H 0x81 +#define EZ80_PWM3R_L 0x82 +#define EZ80_PWM3R_H 0x83 +#define EZ80_PWM0F_L 0x84 +#define EZ80_PWM0F_H 0x85 +#define EZ80_PWM1F_L 0x86 +#define EZ80_PWM1F_H 0x87 +#define EZ80_PWM2F_L 0x88 +#define EZ80_PWM2F_H 0x89 +#define EZ80_PWM3F_L 0x8a +#define EZ80_PWM3F_H 0x8b + +/* WDT Registers *********************************************************************/ + +#define EZ80_WDT_CTL 0x93 +#define EZ80_WDT_RR 0x94 + +/* GPIO Registers ********************************************************************/ + +#define EZ80_PA_DR 0x96 +#define EZ80_PA_DDR 0x97 +#define EZ80_PA_ALT0 0xa6 +#define EZ80_PA_ALT1 0x98 +#define EZ80_PA_ALT2 0x99 +#define EZ80_PB_DR 0x9a +#define EZ80_PB_DDR 0x9b +#define EZ80_PB_ALT0 0xa7 +#define EZ80_PB_ALT1 0x9c +#define EZ80_PB_ALT2 0x9d +#define EZ80_PC_DR 0x9e +#define EZ80_PC_DDR 0x9f +#define EZ80_PC_ALT0 0xce +#define EZ80_PC_ALT1 0xa0 +#define EZ80_PC_ALT2 0xa1 +#define EZ80_PD_DR 0xa2 +#define EZ80_PD_DDR 0xa3 +#define EZ80_PD_ALT0 0xcf +#define EZ80_PD_ALT1 0xa4 +#define EZ80_PD_ALT2 0xa5 + +/* CS Registers **********************************************************************/ + +#define EZ80_CS0_LBR 0xa8 +#define EZ80_CS0_UBR 0xa9 +#define EZ80_CS0_CTL 0xaa +#define EZ80_CS1_LBR 0xab +#define EZ80_CS1_UBR 0xac +#define EZ80_CS1_CTL 0xad +#define EZ80_CS2_LBR 0xae +#define EZ80_CS2_UBR 0xaf +#define EZ80_CS2_CTL 0xb0 +#define EZ80_CS3_LBR 0xb1 +#define EZ80_CS3_UBR 0xb2 +#define EZ80_CS3_CTL 0xb3 + +/* RAMCTL reggisters *****************************************************************/ + +#define EZ80_RAM_CTL 0xb4 +#define EZ80_RAM_CTL0 0xb4 +#define EZ80_RAM_ADDR_U 0xb5 +#define EZ80_MBIST_GPR 0xb6 +#define EZ80_MBIST_EMR 0xb7 + +/* RAMCTL bit definitions ************************************************************/ + +#define RAMCTL_ERAMEN (1 << 6) /* Bit 7: 1=On chip EMAC SRAM is enabled */ +#define RAMCTL_GPRAMEN (1 << 7) /* Bit 7: 1=On chip GP SRAM is enabled */ + +/* SPI Registers *********************************************************************/ + +#define EZ80_SPI_BRG_L 0xb8 +#define EZ80_SPI_BRG_H 0xb9 +#define EZ80_SPI_CTL 0xba +#define EZ80_SPI_SR 0xbb +#define EZ80_SPI_RBR 0xbc +#define EZ80_SPI_TSR 0xbd + +/* UART Register Offsets *************************************************************/ + /* DLAB=0: */ +#define EZ80_UART_THR 0x00 /* W: UART Transmit holding register */ +#define EZ80_UART_RBR 0x00 /* R : UART Receive buffer register */ +#define EZ80_UART_IER 0x01 /* RW: UART Interrupt enable register */ + /* DLAB=1: */ +#define EZ80_UART_BRG 0x00 /* RW: UART Baud rate generator register */ +#define EZ80_UART_BRGL 0x00 /* RW: UART Baud rate generator register (low) */ +#define EZ80_UART_BRGH 0x01 /* RW: UART Baud rate generator register (high) */ + /* DLAB=N/A: */ +#define EZ80_UART_IIR 0x02 /* R : UART Interrupt identification register */ +#define EZ80_UART_FCTL 0x02 /* W: UART FIFO control register */ +#define EZ80_UART_LCTL 0x03 /* RW: UART Line control register */ +#define EZ80_UART_MCTL 0x04 /* RW: UART Modem control register */ +#define EZ80_UART_LSR 0x05 /* R : UART Line status register */ +#define EZ80_UART_MSR 0x06 /* R : UART Modem status register */ +#define EZ80_UART_SPR 0x07 /* RW: UART Scratchpad register */ + +/* UART0/1 Base Register Addresses **************************************************/ + +#define EZ80_UART0_BASE 0xc0 +#define EZ80_UART1_BASE 0xd0 + +/* UART0/1 IER register bits ********************************************************/ + +#define EZ80_UARTEIR_INTMASK 0x1f /* Bits 5-7: Reserved */ +#define EZ80_UARTEIR_TCIE 0x10 /* Bit 4: Transmission complete interrupt */ +#define EZ80_UARTEIR_MIIE 0x08 /* Bit 3: Modem status input interrupt */ +#define EZ80_UARTEIR_LSIE 0x04 /* Bit 2: Line status interrupt */ +#define EZ80_UARTEIR_TIE 0x02 /* Bit 1: Transmit interrupt */ +#define EZ80_UARTEIR_RIE 0x01 /* Bit 0: Receive interrupt */ + +/* UART0/1 IIR register bits ********************************************************/ + +#define EZ80_UARTIIR_FSTS 0x80 /* Bit 7: FIFO enable */ + /* Bits 4-6: Reserved */ +#define EZ80_UARTIIR_INSTS 0x0e /* Bits 1-3: Interrupt status code */ +# define EZ80_UARTINSTS_CTO 0x0c /* 110: Character timeout */ +# define EZ80_UARTINSTS_TC 0x0a /* 101: Transmission complete */ +# define EZ80_UARTINSTS_RLS 0x06 /* 011: Receiver line status */ +# define EZ80_UARTINSTS_RDR 0x04 /* 010: Receive data ready or trigger level */ +# define EZ80_UARTINSTS_TBE 0x02 /* 001: Transmisson buffer empty */ +# define EZ80_UARTINSTS_MS 0x00 /* 000: Modem status */ +#define EZ80_UARTIIR_INTBIT 0x01 /* Bit 0: Active interrupt source */ +#define EZ80_UARTIIR_CAUSEMASK 0x0f + +/* UART0/1 FCTL register bits *******************************************************/ + +#define EZ80_UARTFCTL_TRIG 0xc0 /* Bits 6-7: UART recieve FIFO trigger level */ +# define EZ80_UARTTRIG_1 0x00 /* 00: Receive FIFO trigger level=1 */ +# define EZ80_UARTTRIG_4 0x40 /* 01: Receive FIFO trigger level=4 */ +# define EZ80_UARTTRIG_8 0x80 /* 10: Receive FIFO trigger level=8 */ +# define EZ80_UARTTRIG_14 0xc0 /* 11: Receive FIFO trigger level=14 */ + /* Bit 3-5: Reserved */ +#define EZ80_UARTFCTL_CLRTxF 0x04 /* Bit 2: Transmit enable */ +#define EZ80_UARTFCTL_CLRRxF 0x02 /* Bit 1: Receive enable */ +#define EZ80_UARTFCTL_FIFOEN 0x01 /* Bit 0: Enable receive/transmit FIFOs */ + +/* UART0/1 LCTL register bits *******************************************************/ + +#define EZ80_UARTLCTL_DLAB 0x80 /* Bit 7: Enable access to baud rate generator */ +#define EZ80_UARTLCTL_SB 0x40 /* Bit 6: Send break */ +#define EZ80_UARTLCTL_FPE 0x20 /* Bit 5: Force parity error */ +#define EZ80_UARTLCTL_EPS 0x10 /* Bit 4: Even parity select */ +#define EZ80_UARTLCTL_PEN 0x08 /* Bit 3: Parity enable */ +#define EZ80_UARTLCTL_2STOP 0x04 /* Bit 2: 2 stop bits */ +#define EZ80_UARTLCTL_CHAR 0x03 /* Bits 0-2: Number of data bits */ +# define EZ80_UARTCHAR_5BITS 0x00 /* 00: 5 data bits */ +# define EZ80_UARTCHAR_6BITS 0x01 /* 01: 6 data bits */ +# define EZ80_UARTCHAR_7BITS 0x02 /* 10: 7 data bits */ +# define EZ80_UARTCHAR_8BITS 0x03 /* 11: 8 data bits */ + +#define EZ80_UARTLCTL_MASK 0x3f + +/* UART0/1 MCTL register bits *******************************************************/ + /* Bit 7: Reserved */ +#define EZ80_UARTMCTL_POLARITY 0x40 /* Bit 6: Invert polarity of RxD and TxD */ +#define EZ80_UARTMCTL_MDM 0x20 /* Bit 5: Multi-drop mode enable */ +#define EZ80_UARTMCTL_LOOP 0x10 /* Bit 4: Loopback mode enable */ +#define EZ80_UARTMCTL_OUT2 0x08 /* Bit 3: (loopback mode only) */ +#define EZ80_UARTMCTL_OUT1 0x04 /* Bit 2: (loopback mode only) */ +#define EZ80_UARTMCTL_RTS 0x02 /* Bit 1: Request to send */ +#define EZ80_UARTMCTL_DTR 0x01 /* Bit 0: Data termnal read */ + +/* UART0/1 LSR register bits ********************************************************/ + +#define EZ80_UARTLSR_ERR 0x80 /* Bit 7: Error detected in FIFO */ +#define EZ80_UARTLSR_TEMT 0x40 /* Bit 6: Transmit FIFO empty and idle */ +#define EZ80_UARTLSR_THRE 0x20 /* Bit 5: Transmit FIFO empty */ +#define EZ80_UARTLSR_BI 0x10 /* Bit 4: Break on input */ +#define EZ80_UARTLSR_FE 0x08 /* Bit 3: Framing error */ +#define EZ80_UARTLSR_PE 0x04 /* Bit 2: Parity error */ +#define EZ80_UARTLSR_OE 0x02 /* Bit 1: Overrun error */ +#define EZ80_UARTLSR_DR 0x01 /* Bit 0: Data ready */ + +/* UART0/1 MSR register bits ********************************************************/ + +#define EZ80_UARTMSR_DCD 0x80 /* Bit 7: Data carrier detect */ +#define EZ80_UARTMSR_RI 0x40 /* Bit 6: Ring indicator */ +#define EZ80_UARTMSR_DSR 0x20 /* Bit 5: Data set ready */ +#define EZ80_UARTMSR_CTS 0x10 /* Bit 4: Clear to send */ +#define EZ80_UARTMSR_DDCD 0x08 /* Bit 3: Delta on DCD input */ +#define EZ80_UARTMSR_TERI 0x04 /* Bit 2: Trailing edge change on RI */ +#define EZ80_UARTMSR_DDSR 0x02 /* Bit 1: Delta on DSR input */ +#define EZ80_UARTMSR_DCTS 0x01 /* Bit 0: Delta on CTS input */ + +/* IR Registers ********************************************************************/ + +#define EZ80_IR_CTL 0xbf + +/* I2C Registers *******************************************************************/ + +#define EZ80_I2C_SAR 0xc8 +#define EZ80_I2C_XSAR 0xc9 +#define EZ80_I2C_DR 0xca +#define EZ80_I2C_CTL 0xcb +#define EZ80_I2C_SR 0xcc +#define EZ80_I2C_CCR 0xcd +#define EZ80_I2C_SRR 0xce + +/* CLK Registers *******************************************************************/ + +#define EZ80_CLK_PPD1 0xdb +#define EZ80_CLK_PPD2 0xdc + +/* RTC Registers *******************************************************************/ + +#define EZ80_RTC_SEC 0xe0 +#define EZ80_RTC_MIN 0xe1 +#define EZ80_RTC_HRS 0xe2 +#define EZ80_RTC_DOW 0xe3 +#define EZ80_RTC_DOM 0xe4 +#define EZ80_RTC_MON 0xe5 +#define EZ80_RTC_YR 0xe6 +#define EZ80_RTC_CEN 0xe7 +#define EZ80_RTC_ASEC 0xe8 +#define EZ80_RTC_AMIN 0xe9 +#define EZ80_RTC_AHRS 0xea +#define EZ80_RTC_ADOW 0xeb +#define EZ80_RTC_ACTRL 0xec +#define EZ80_RTC_CTRL 0xed + +/* CSBMC Registers *****************************************************************/ + +#define EZ80_CS0_BMC 0xf0 +#define EZ80_CS1_BMC 0xf1 +#define EZ80_CS2_BMC 0xf2 +#define EZ80_CS3_BMC 0xf3 + +/* FLASH Registers *****************************************************************/ + +#define EZ80_FLASH_KEY 0xf5 +#define EZ80_FLASH_DATA 0xf6 +#define EZ80_FLASH_ADDR_U 0xf7 +#define EZ80_FLASH_CTRL 0xf8 +#define EZ80_FLASH_FDIV 0xf9 +#define EZ80_FLASH_PROT 0xfa +#define EZ80_FLASH_INTC 0xfb +#define EZ80_FLASH_PAGE 0xfc +#define EZ80_FLASH_ROW 0xfd +#define EZ80_FLASH_COL 0xfe +#define EZ80_FLASH_PGCTL 0xff + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_SRC_EZ80_EZ80F91_H */ diff --git a/arch/z80/src/ez80/ez80f91_emac.h b/arch/z80/src/ez80/ez80f91_emac.h new file mode 100644 index 0000000000000000000000000000000000000000..8e32e1ed8352cf9b13c5cc09806205ce4cbe92f3 --- /dev/null +++ b/arch/z80/src/ez80/ez80f91_emac.h @@ -0,0 +1,289 @@ +/************************************************************************************ + * arch/z80/src/ez80/ez80f91_emac.h + * arch/z80/src/chip/ez80f91_emac.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_EZ80_EZ80F91_EMAC_H +#define __ARCH_Z80_SRC_EZ80_EZ80F91_EMAC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* EMACC Registers *****************************************************************/ + +/* Provided in ez80f91.h */ + +/* EMAC configuration 1/2/3 register bit settings ***********************************/ + +#define EMAC_CFG1_DCRCC 0x01 /* Bit 0: 1=4 bytes of proprietary header */ +#define EMAC_CFG1_HUGEN 0x02 /* Bit 1: 1=Allow unlimited size frames to be recieved */ +#define EMAC_CFG1_FLCHK 0x04 /* Bit 2: 1=Frame lengths compared to length/type */ +#define EMAC_CFG1_FULLHD 0x08 /* Bit 3: 1=Enable full duplex mode */ +#define EMAC_CFG1_CRCEN 0x10 /* Bit 4: 1=Append CRC to every frame */ +#define EMAC_CFG1_VLPAD 0x20 /* Bit 5: 1=Pad all short frames to 64 bytes, append CRC */ +#define EMAC_CFG1_ADPADN 0x40 /* Bit 6: 1=Enable frame detection by check VALN protocol ID */ +#define EMAC_CFG1_PADEN 0x80 /* Bit 7: 1=Pad all short frames with zeros. */ + +#define EMAC_CFG2_LCOLMASK 0x3f /* Bits 0-5: Number bytes after start frame for collision */ +#define EMAC_CFG2_NOBO 0x40 /* Bit 6: 1=immediate transmit after collision */ +#define EMAC_CFG2_BPNB 0x80 /* Bit 7: 1=after collision retransmit without back-off */ + +#define EMAC_CFG3_RETRYMASK 0x0f /* Bits 0-3: Number retransmissions before abort */ +#define EMAC_CFG3_BITMD 0x10 /* Bit 4: 1=Enable 10Mbps ENDEC mode */ +#define EMAC_CFG3_XSDFR 0x20 /* Bit 5: 1=Defer to carrier indefinitely */ +#define EMAC_CFG3_PUREP 0x40 /* Bit 6: 1=Verify preamble */ +#define EMAC_CFG3_LONGP 0x80 /* Bit 7: 1=only allow preamble < 12 bytes */ + +#define EMAC_CFG4_RXEN 0x01 /* Bit 0: 1=Receive frames */ +#define EMAC_CFG4_TPAUSE 0x02 /* Bit 1: 1=Force pause condition */ +#define EMAC_CFG4_TXFC 0x04 /* Bit 2: 1=Transmit pause control frames */ +#define EMAC_CFG4_RXFC 0x08 /* Bit 3: 1=Act on receive pause control frames */ +#define EMAC_CFG4_PARF 0x10 /* Bit 4: 1=Receive all frames */ +#define EMAC_CFG4_THDF 0x20 /* Bit 5: 1=Asser back-pressure */ +#define EMAC_CFG4_TPCF 0x40 /* Bit 6: 1=Transmit pause control frame. */ + /* Bit 7: reserved */ + +/* EMAC AFR register bit settings ***************************************************/ + +#define EMAC_AFR_BC 0x01 /* Bit 0: 1=Accept broadcast messages */ +#define EMAC_AFR_QMC 0x02 /* Bit 1: 1=Accept only qualified multicast messages */ +#define EMAC_AFR_MC 0x04 /* Bit 2: 1=Accept any multicast message */ +#define EMAC_AFR_PROM 0x08 /* Bit 3: 1=Enable promiscuous mode */ + /* Bits 4-7: Reserved */ + +/* EMAC MII management register bit settings ****************************************/ + +#define EMAC_MIIMGMT_CLKMASK 0x07 /* Bits 0-2: Divisor that produces MDC from SCLK */ +# define EMAC_MDC_DIV4 0x01 /* MDC = SCLK / 4 */ +# define EMAC_MDC_DIV6 0x02 /* MDC = SCLK / 6 */ +# define EMAC_MDC_DIV8 0x03 /* MDC = SCLK / 8 */ +# define EMAC_MDC_DIV10 0x04 /* MDC = SCLK / 10 */ +# define EMAC_MDC_DIV14 0x05 /* MDC = SCLK / 14 */ +# define EMAC_MDC_DIV20 0x06 /* MDC = SCLK / 20 */ +# define EMAC_MDC_DIV28 0x07 /* MDC = SCLK / 28 */ +#define EMAC_MIIMGMT_SPRE 0x08 /* Bit 3: 1=Suppress MDO preamble */ +#define EMAC_MIIMGMT_SCAN 0x10 /* Bit 4: 1=Perform continus read cycles */ +#define EMAC_MIIMGMT_SCINC 0x20 /* Bit 5: 1=Increment PHY address on scan cycle */ +#define EMAC_MIIMGMT_RSTAT 0x40 /* Bit 6: 1=Read status from PHY (via PRSD) */ +#define EMAC_MIIMGMT_LCTLD 0x80 /* Bit 7: 1=Send CTLD control data to PHY */ + +/* EMAC PHY unit select address register bit settings *******************************/ + +#define EMAC_RGAD_MASK 0x1f /* 5-bit value selects address within PHY */ + +/* EMAC PHY address register bit settings *******************************************/ + +#define EMAC_FIAD_MASK 0x1f /* 5-bit value selects the external PHY */ + +/* EMAC reset control register bit settings *****************************************/ + +#define EMAC_RST_HRMGT 0x01 /* Bit 0: 1=Reset EMAC management function */ +#define EMAC_RST_HRRMC 0x02 /* Bit 1: 1=Reset EMAC receive control function */ +#define EMAC_RST_HRTMC 0x04 /* Bit 2: 1=Reset EMAC transmit control function */ +#define EMAC_RST_HRRFN 0x08 /* Bit 3: 1=Reset receive function */ +#define EMAC_RST_HRTFN 0x10 /* Bit 4: 1=Reset transmit function */ +#define EMAC_RST_SRST 0x20 /* Bit 5: 1=Software reset active */ + /* Bits 6-7: Reserved */ + +/* EMAC bufsize register bit settings ***********************************************/ + +#define EMAC_BUFSZ_BUFSZMASK 0xc0 /* Bits 6-6: Rx/Tx buffer size */ +# define EMAC_BUFSZ_256b 0x00 /* EMAC Rx/Tx buffer size = 256 bytes */ +# define EMAC_BUFSZ_128b 0x40 /* EMAC Rx/Tx buffer size = 128 bytes */ +# define EMAC_BUFSZ_64b 0x80 /* EMAC Rx/Tx buffer size = 64 bytes */ +# define EMAC_BUFSZ_32b 0xc0 /* EMAC Rx/Tx buffer size = 32 bytes */ +#define EMAC_BUFSZ_TPCFLMASK 0x3f /* Bits 0-5: Tranmsit pause frame level */ + +/* EMAC interrupt enable register bit settings **************************************/ + +#define EMAC_EIN_TXDONE 0x01 /* Bit 0: 1=Enable transmit done interrupt */ +#define EMAC_EIN_TXCF 0x02 /* Bit 1: 1=Enable transmit control frame interrupt */ +#define EMAC_EIN_RXOVR 0x04 /* Bit 2: 1=Enable receive overrun interrupt */ +#define EMAC_EIN_RXDONE 0x08 /* Bit 3: 1=Enable receive done interrupt */ +#define EMAC_EIN_RXPCF 0x10 /* Bit 4: 1=Enable receive pause control frame interrupt */ +#define EMAC_EIN_RXCF 0x20 /* Bit 5: 1=Enable receive control frame interrupt */ +#define EMAC_EIN_MGTDONE 0x40 /* Bit 6: 1=Enable MII Mgmt done interrupt */ +#define EMAC_EIN_TXFSMERR 0x80 /* Bit 7: 1=Enable transmit state machine error interrupt */ + +/* EMAC interrupt status register bit settings **************************************/ + +#define EMAC_ISTAT_TXDONE 0x01 /* Bit 0: 1=Transmit done interrupt */ +#define EMAC_ISTAT_TXCF 0x02 /* Bit 1: 1=Transmit control frame interrupt */ +#define EMAC_ISTAT_RXOVR 0x04 /* Bit 2: 1=Receive overrun interrupt */ +#define EMAC_ISTAT_RXDONE 0x08 /* Bit 3: 1=Receive done interrupt */ +#define EMAC_ISTAT_RXPCF 0x10 /* Bit 4: 1=Receive pause control frame interrupt */ +#define EMAC_ISTAT_RXCF 0x20 /* Bit 5: 1=Receive control frame interrupt */ +#define EMAC_ISTAT_MGTDONE 0x40 /* Bit 6: 1=MII Mgmt done interrupt */ +#define EMAC_ISTAT_TXFSMERR 0x80 /* Bit 7: 1=Transmit state machine error interrupt */ + +/* EMAC MII status register bit settings ********************************************/ + +#define EMAC_MIISTAT_RDADRMK 0x1f /* Bits 0-4: PHY addressed in current scan cyle */ +#define EMAC_MIISTAT_NVALID 0x20 /* Bit 5: 1=PRSD is valid */ +#define EMAC_MIISTAT_MIILF 0x40 /* Bit 6: 1=PHY link OK */ +#define EMAC_MIISTAT_BUSY 0x80 /* Bit 7: 1=MII management in progress */ + +/* EMAC FIFO flags register bit settings ********************************************/ + +#define EMAC_FFLAGS_RFE 0x01 /* Bit 0: 1=Receive FIFO empty */ +#define EMAC_FFLAGS_RFAE 0x02 /* Bit 0: 1=Receive FIFO almost empty */ +#define EMAC_FFLAGS_RFAF 0x04 /* Bit 0: 1=Receive FIFO almost full */ +#define EMAC_FFLAGS_RFF 0x08 /* Bit 0: 1=Receive FIFO full */ +#define EMAC_FFLAGS_TFE 0x10 /* Bit 0: 1=Transmit FIFO empty */ +#define EMAC_FFLAGS_TFAE 0x20 /* Bit 0: 1=Transmit FIFO almost empty */ +#define EMAC_FFLAGS_TFF 0x80 /* Bit 0: 1=Trasnmit FIFO full */ + +/* EMAC Transmit Descriptor Status **************************************************/ + +#define EMAC_TXDESC_NCOLL 0x0001 /* Bits 0-3: Bumber of collisions that occurred + * while transmitting the packet. */ +#define EMAC_TXDESC_MXCOLL 0x0010 /* Bit 4: 1=maximum number of collisions. + * number > CFG3[3:0]. packet aborted */ +#define EMAC_TXDESC_LATECOLL 0x0020 /* Bit 5: 1=late collision. Collision is detected + * at a byte count > CFG2[5:0]. Collisions detected + * before the byte count reaches CFG2[5:0] are early + * collisions and retried. */ +#define EMAC_TXDESC_FIFOUNDR 0x0040 /* Bit 6: TxFIFO Underrun. Check the TxAbort + * bit to see if the packet is aborted or retried. */ +#define EMAC_TXDESC_XSDFR 0x0080 /* Bit 7: Packet is excessively deferred. (> 6071 nibble + * times in 100 BaseT or 24,287 bit times in 10 BaseT). */ +#define EMAC_TXDESC_PKTDEFFRD 0x0100 /* Bit 8: Packet is deferred */ +#define EMAC_TXDESC_CRCERROR 0x0200 /* Bit 9: Invalid FCS (CRC). Set CRCEN = 0 and the + * last 4 bytes of the packet are not the valid FCS. */ +#define EMAC_TXDESC_LCERROR 0x0400 /* Bit 10: Type/Length field is not a Type field and + * does not match the actual data byte length of + * the Ethernet packet. The data byte length is + * the number of bytes of data in the Ethernet + * packet between the Type/Length field and the FCS. */ +#define EMAC_TXDESC_LOOR 0x0800 /* Bit 11: Type/Length field is out of range (larger + * than 1518 bytes). */ +#define EMAC_TXDESC_HUGE 0x1000 /* Bit 12: 1=Packet size is very large(Pkt_Size > MAXF). */ +#define EMAC_TXDESC_BPA 0x2000 /* Bit 13: 1=Back pressure applied */ +#define EMAC_TXDESC_ABORT 0x4000 /* Bit 14: 1=Packet aborted (not transmitted). */ +#define EMAC_TXDESC_OWNER 0x8000 /* Bit 15: 0=Host (eZ80 CPU) owns, 1=EMAC owns. */ + +/* Receive Descriptor Status ********************************************************/ + +#define EMAC_RXDESC_OVR 0x0001 /* Bit 0: 1=A Receive Overrun occurs in this packet. An + * overrun occurs when all of the EMAC Receive + * buffers are in use and the Receive FIFO is full. + * The hardware ignores all incoming packets until the + * ISTAT Register [RXOVR] bit is cleared by the software. + * There is no indication as to how many packets are + * ignored. */ +#define EMAC_RXDESC_DVEVENT 0x0002 /* Bit 1: 1=Receive data (RxDV) event is previously seen. + * Indicates that the last Receive event is not long + * enough to be a valid packet. */ +#define EMAC_RXDESC_CEVENT 0x0004 /* Bit 2: 1=Carrier event is previously seen. This event is + * defined as Rx error RxER = 1, receive data valid + * (RxDV) = 0 and receive data (RxD) = Eh */ +#define EMAC_RXDESC_CODEV 0x0008 /* Bit 3: 1=A code violation is detected. The PHY asserts + * Rx error (RxER). */ +#define EMAC_RXDESC_LCERROR 0x0010 /* Bit 4 1=Type/Length field is not a Type field and it does + * not match the actual data byte length of the + * Ethernet packet. The data byte length is the + * number of bytes of data in the Ethernet packet + * between the Type/Length field and the FCS. */ +#define EMAC_RXDESC_LOOR 0x0020 /* Bit 5: 1=Type/Length field is out of range (larger + * than 1518 bytes). */ +#define EMAC_RXDESC_UOPCODE 0x0040 /* Bit 6: 1=Unsupported Op Code is indicated in the Op + * Code field of the Ethernet packet. */ +#define EMAC_RXDESC_VLAN 0x0080 /* Bit 7: 1=The packet is a VLAN packet */ +#define EMAC_RXDESC_BCPKT 0x0100 /* Bit 8: 1=packet contains a broadcast address */ +#define EMAC_RXDESC_MCPKT 0x0200 /* Bit 9: 1=The packet contains a multicast address */ +#define EMAC_RXDESC_CR 0x0400 /* Bit 10: 1=The packet is a control frame */ +#define EMAC_RXDESC_PCF 0x0800 /* Bit 11: 1=The packet is a pause control frame */ +#define EMAC_RXDESC_LONGEVNT 0x1000 /* Bit 12: 1= A Long or Dropped Event occurs. A Long Event is + * when a packet over 50,000 bit times occurs. A + * Dropped Packet can occur if the minimum interpacket + * gap is not met, the preamble is not pure, and + * the CFG3[PUREP] bit is set, or if a preamble over + * 11 bytes in length is detected and the CFG3[LONGP] + * bit is set to 1. */ +#define EMAC_RXDESC_CRCERR 0x2000 /* Bit 13: 1=The CRC (FCS) is in error */ +#define EMAC_RXDESC_ALGNERR 0x4000 /* Bit 14: 1=An odd number of nibbles is received. */ +#define EMAC_RXDESC_OK 0x8000 /* Bit 15: 1=Packet received intact. */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* EMAC descriptor structure (7 bytes) */ + +#ifndef __ASSEMBLY__ +struct ez80emac_desc_s +{ + uint24_t np; /* Pointer to the start of the next packet */ + uint16_t pktsize; /* Number of bytes in the packet, including the 4 CRC + * bytes, but excluding the 7 descriptor table bytes. */ + uint16_t stat; /* Status of the packet. Differs for TX and RX packets + * (see EMAC_RX/TXDESC_* definitions) */ +}; +#endif + +#define SIZEOF_EMACSDESC 7 + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif /* __cplusplus */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_Z80_SRC_EZ80_EZ80F91_EMAC_H */ diff --git a/arch/z80/src/ez80/ez80f91_i2c.h b/arch/z80/src/ez80/ez80f91_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..b59d4ffc7b157d164e43d204dd6440f59461d1ba --- /dev/null +++ b/arch/z80/src/ez80/ez80f91_i2c.h @@ -0,0 +1,186 @@ +/************************************************************************************ + * arch/z80/src/ez80/ez80f91_i2c.h + * arch/z80/src/chip/ez80f91_i2c.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_EZ80_EZ80F91_I2C_H +#define __ARCH_Z80_SRC_EZ80_EZ80F91_I2C_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* I2C Registers ******************************************************************/ + +/* Provided in ez80f91.h */ + +/* I2C Register Bit Definitions ***************************************************/ + +/* Slave Address Register (SAR) Bit Definitions */ + +#define I2C_SAR_GCE (1 << 0) /* Bit 0: 1=I2C enabled to recognize the General Call Address */ +#define I2C_SAR_SLA_SHIFT 1 /* Bits 1-7: 7-bit address or upper 2 bits in 10-bit mode */ +#define I2C_SAR_SLA_MASK (0x7f << 1) + +/* Extended Slave Address Register (XSAR) Bit Definitions */ +/* Bits 0-7: Least significant 8-bits of 10-bit slave address */ + +/* Data Byte Register (DR) Bit Definitions */ +/* Bits 0-7: I2C byte data */ + +/* Control (CTL) Register Bit Definitions */ + +#define I2C_CTL_AAK (1 << 2) /* Bit 2: 1=Acknowledge */ +#define I2C_CTL_IFLG (1 << 3) /* Bit 3: 1=I2C interrupt flag is set */ +#define I2C_CTL_STP (1 << 4) /* Bit 4: 1=Master mode stop-transmit STOP condition on the bus */ +#define I2C_CTL_STA (1 << 5) /* Bit 5: 1=Master mode start-transmit START condition on the bus */ +#define I2C_CTL_ENAB (1 << 6) /* Bit 6: 1=I2C bus (SCL/SDA) is enabled */ +#define I2C_CTL_IEN (1 << 7) /* Bit 7: 1=I2C interrupt is enabled */ + +/* Status Register (SR) Bit Definitions */ + +#define I2C_SR_SHIFT 3 /* Bits 3-7: 5-bit status code */ +#define I2C_SR_MASK (0x1c << I2C_SR_SHIFT) + + +#define I2C_SR_BUSERR 0x00 /* Bus error */ +#define I2C_SR_MSTART 0x08 /* START condition transmitted */ +#define I2C_SR_MREPSTART 0x10 /* Repeated START condition transmitted */ +#define I2C_SR_MADDRWRACK 0x18 /* Address and Write bit transmitted, ACK received */ +#define I2C_SR_MADDRWR 0x20 /* Address and Write bit transmitted, ACK not received */ +#define I2C_SR_MDATAWRACK 0x28 /* Data byte transmitted in MASTER mode, ACK received */ +#define I2C_SR_MDATAWR 0x30 /* Data byte transmitted in MASTER mode, ACK not received */ +#define I2C_SR_ARBLOST1 0x38 /* Arbitration lost in address or data byte */ +#define I2C_SR_MADDRRDACK 0x40 /* Address and Read bit transmitted, ACK received */ +#define I2C_SR_MADDRRD 0x48 /* Address and Read bit transmitted, ACK not received */ +#define I2C_SR_MDATARDACK 0x50 /* Data byte received in MASTER mode, ACK transmitted */ +#define I2C_SR_MDATARDNAK 0x58 /* Data byte received in MASTER mode, NACK transmitted */ +#define I2C_SR_SADDRWRACK 0x60 /* Slave address and Write bit received, ACK transmitted */ +#define I2C_SR_ARBLOST2 0x68 /* Arbitration lost in address as master, slave address and Write bit received, ACK transmitted */ +#define I2C_SR_SGCARDACK 0x70 /* General Call address received, ACK transmitted */ +#define I2C_SR_ARBLOST3 0x78 /* Arbitration lost in address as master, General Call address received, ACK transmitted */ +#define I2C_SR_SDATARDACK 0x80 /* Data byte received after slave address received, ACK transmitted */ +#define I2C_SR_SDATARDNAK 0x88 /* Data byte received after slave address received, NACK transmitted */ +#define I2C_SR_SDATAGCAACK 0x90 /* Data byte received after General Call received, ACK transmitted */ +#define I2C_SR_SDATAGCANAK 0x98 /* Data byte received after General Call received, NACK transmitted */ +#define I2C_SR_SSTOP 0xa0 /* STOP or repeated START condition received in SLAVE mode */ +#define I2C_SR_SSADDRRDACK 0xa8 /* Slave address and Read bit received, ACK transmitted */ +#define I2C_SR_ARBLOST4 0xb0 /* Arbitration lost in address as master, slave address and Read bit received, ACK transmitted */ +#define I2C_SR_SDATAWRACK 0xb8 /* Data byte transmitted in SLAVE mode, ACK received */ +#define I2C_SR_SDATAWR 0xc0 /* Data byte transmitted in SLAVE mode, ACK not received */ +#define I2C_SR_SLDATAWR 0xc8 /* Last byte transmitted in SLAVE mode, ACK received */ +#define I2C_SR_MADDR2WRACK 0xd0 /* Second Address byte and Write bit transmitted, ACK received */ +#define I2C_SR_MADDR2WR 0xd8 /* Second Address byte and Write bit transmitted, ACK not received */ +#define I2C_SR_NONE 0xf8 /* No relevant status information, IFLG = 0 */ + +/* Clock Control Register (CCR) Bit Definitions */ + +#define I2C_CCR_NSHIFT 0 /* Bits 0-2: I2C clock divider exponent */ +#define I2C_CCR_NMASK (0x07 << I2C_CCR_NSHIFT) +#define I2C_CCR_MSHIFT 3 /* Bits 3-6: I2C clock divider scalar value */ +#define I2C_CCR_MMASK (0x0f << I2C_CCR_MSHIFT) + +/* Software Reset Register (SRR) Bit Definitions */ +/* Writing any value to this register performs a software reset of the I2C module */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif /* __cplusplus */ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: ez80_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct i2c_master_s *ez80_i2cbus_initialize(int port); + +/************************************************************************************ + * Name: ez80_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the ez80_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ************************************************************************************/ + +int ez80_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#undef EXTERN +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_Z80_SRC_EZ80_EZ80F91_I2C_H */ diff --git a/arch/z80/src/ez80/ez80f91_init.asm b/arch/z80/src/ez80/ez80f91_init.asm new file mode 100644 index 0000000000000000000000000000000000000000..fbce8502f03f57b157d3322b0f717dcb8fd3596f --- /dev/null +++ b/arch/z80/src/ez80/ez80f91_init.asm @@ -0,0 +1,257 @@ +;************************************************************************** +; arch/z80/src/ez80/ez80f91_init.asm +; +; Copyright (C) 2008 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + +;************************************************************************** +; Included Files +;************************************************************************** + + include "ez80F91.inc" + +;************************************************************************** +; Constants +;************************************************************************** + +;PLL_DIV_L EQU %5C +;PLL_DIV_H EQU %5D +;PLL_CTL0 EQU %5E +;PLL_CTL1 EQU %5F + +OSC EQU 0 +PLL EQU 1 +RTC EQU 2 + +CLK_MUX_OSC EQU %00 +CLK_MUX_PLL EQU %01 +CLK_MUX_RTC EQU %02 + +CHRP_CTL_0 EQU %00 +CHRP_CTL_1 EQU %40 +CHRP_CTL_2 EQU %80 +CHRP_CTL_3 EQU %C0 + +LDS_CTL_0 EQU %00 +LDS_CTL_1 EQU %04 +LDS_CTL_2 EQU %08 +LDS_CTL_3 EQU %0C + +LCK_STATUS EQU %20 +INT_LOCK EQU %10 +INT_UNLOCK EQU %08 +INT_LOCK_EN EQU %04 +INT_UNLOCK_EN EQU %02 +PLL_ENABLE EQU %01 + +;************************************************************************** +; Global symbols used +;************************************************************************** + +; Exported symbols + xdef _ez80_init + xdef _ez80_initsysclk + +; Imported symbols + xref __CS0_LBR_INIT_PARAM + xref __CS0_UBR_INIT_PARAM + xref __CS0_CTL_INIT_PARAM + xref __CS1_LBR_INIT_PARAM + xref __CS1_UBR_INIT_PARAM + xref __CS1_CTL_INIT_PARAM + xref __CS2_LBR_INIT_PARAM + xref __CS2_UBR_INIT_PARAM + xref __CS2_CTL_INIT_PARAM + xref __CS3_LBR_INIT_PARAM + xref __CS3_UBR_INIT_PARAM + xref __CS3_CTL_INIT_PARAM + xref __CS0_BMC_INIT_PARAM + xref __CS1_BMC_INIT_PARAM + xref __CS2_BMC_INIT_PARAM + xref __CS3_BMC_INIT_PARAM + xref __FLASH_CTL_INIT_PARAM + xref __FLASH_ADDR_U_INIT_PARAM + xref __RAM_CTL_INIT_PARAM + xref __RAM_ADDR_U_INIT_PARAM + xref _SYS_CLK_SRC + xref _SYS_CLK_FREQ + xref _OSC_FREQ + xref _OSC_FREQ_MULT + xref __PLL_CTL0_INIT_PARAM + +;************************************************************************** +; Chip-specific initialization logic +;************************************************************************** +; Minimum default initialization for eZ80F91 + + define .STARTUP, space = ROM + segment .STARTUP + .assume ADL = 1 + +_ez80_init: + ; Disable internal peripheral interrupt sources + + ld a, %ff + out0 (PA_DDR), a ; GPIO + out0 (PB_DDR), a + out0 (PC_DDR), a + out0 (PD_DDR), a + ld a, %00 + out0 (PA_ALT1), a + out0 (PB_ALT1), a + out0 (PC_ALT1), a + out0 (PD_ALT1), a + out0 (PA_ALT2), a + out0 (PB_ALT2), a + out0 (PC_ALT2), a + out0 (PD_ALT2), a + out0 (PLL_CTL1), a ; PLL + out0 (TMR0_IER), a ; timers + out0 (TMR1_IER), a + out0 (TMR2_IER), a + out0 (TMR3_IER), a + out0 (UART0_IER), a ; UARTs + out0 (UART1_IER), a + out0 (I2C_CTL), a ; I2C + out0 (EMAC_IEN), a ; EMAC + out0 (FLASH_IRQ), a ; Flash + ld a, %04 + out0 (SPI_CTL), a ; SPI + in0 a, (RTC_CTRL) ; RTC, + and a, %be + out0 (RTC_CTRL), a + + ; Configure external memory/io + + ld a, __CS0_LBR_INIT_PARAM + out0 (CS0_LBR), a + ld a, __CS0_UBR_INIT_PARAM + out0 (CS0_UBR), a + ld a, __CS0_BMC_INIT_PARAM + out0 (CS0_BMC), a + ld a, __CS0_CTL_INIT_PARAM + out0 (CS0_CTL), a + + ld a, __CS1_LBR_INIT_PARAM + out0 (CS1_LBR), a + ld a, __CS1_UBR_INIT_PARAM + out0 (CS1_UBR), a + ld a, __CS1_BMC_INIT_PARAM + out0 (CS1_BMC), a + ld a, __CS1_CTL_INIT_PARAM + out0 (CS1_CTL), a + + ld a, __CS2_LBR_INIT_PARAM + out0 (CS2_LBR), a + ld a, __CS2_UBR_INIT_PARAM + out0 (CS2_UBR), a + ld a, __CS2_BMC_INIT_PARAM + out0 (CS2_BMC), a + ld a, __CS2_CTL_INIT_PARAM + out0 (CS2_CTL), a + + ld a, __CS3_LBR_INIT_PARAM + out0 (CS3_LBR), a + ld a, __CS3_UBR_INIT_PARAM + out0 (CS3_UBR), a + ld a, __CS3_BMC_INIT_PARAM + out0 (CS3_BMC), a + ld a, __CS3_CTL_INIT_PARAM + out0 (CS3_CTL), a + + ; Enable internal memory + + ld a, __FLASH_ADDR_U_INIT_PARAM + out0 (FLASH_ADDR_U), a + ld a, __FLASH_CTL_INIT_PARAM + out0 (FLASH_CTRL), a + + ld a, __RAM_ADDR_U_INIT_PARAM + out0 (RAM_ADDR_U), a + ld a, __RAM_CTL_INIT_PARAM + out0 (RAM_CTL), a + ret + +;***************************************************************************** +; eZ80F91 System Clock Initialization +;***************************************************************************** + +_ez80_initsysclk: + ; check if the PLL should be used + ld a, (_ez80_sysclksrc) + cp a, PLL + jr nz, _ez80_initsysclkdone + + ; Load PLL divider + + ld a, (_ez80_oscfreqmult) ;CR 6202 + out0 (PLL_DIV_L), a + ld a, (_ez80_oscfreqmult+1) + out0 (PLL_DIV_H), a + + ; Set charge pump and lock criteria + + ld a, __PLL_CTL0_INIT_PARAM + and a, %CC ; mask off reserved and clock source bits + out0 (PLL_CTL0), a + + ; Enable PLL + + in0 a, (PLL_CTL1) + set 0, a + out0 (PLL_CTL1), a + + ; Wait for PLL to lock +_ez80_initsysclkwait: + in0 a, (PLL_CTL1) + and a, LCK_STATUS + cp a, LCK_STATUS + jr nz, _ez80_initsysclkwait + + ; Select PLL as system clock source + + ld a, __PLL_CTL0_INIT_PARAM + set 0, a + out0 (PLL_CTL0), a + +_ez80_initsysclkdone: + ret + +;_ez80_oscfreq: +; dl _OSC_FREQ +_ez80_oscfreqmult: + dw _OSC_FREQ_MULT +;_ez80_sysclkfreq: +; dl _SYS_CLK_FREQ +_ez80_sysclksrc: + db _SYS_CLK_SRC + end diff --git a/arch/z80/src/ez80/ez80f91_spi.h b/arch/z80/src/ez80/ez80f91_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..36c0016f485261aef98c93ee44333f2213d45a83 --- /dev/null +++ b/arch/z80/src/ez80/ez80f91_spi.h @@ -0,0 +1,158 @@ +/************************************************************************************ + * arch/z80/src/ez80/ez80f91_spi.h + * arch/z80/src/chip/ez80f91_spi.h + * + * Copyright (C) 2009-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_EZ80_EZ80F91_SPI_H +#define __ARCH_Z80_SRC_EZ80_EZ80F91_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* SPIC Registers *****************************************************************/ + +/* Provided in ez80f91.h */ + +/* SPIC Register Bit Definitions **************************************************/ + +/* Baud Rate Generator (BRG) H/L Register Definitions + * + * No bit definitions -- These two 8-bit registers set the 16-bit BRG divider value + */ + +/* SPI Control (CTL} Register Definitions */ + +#define SPI_CTL_IRQEN (1 << 7) /* Bit 7: 1=SPI system interrupt is enabled */ +#define SPI_CTL_SPIEN (1 << 5) /* Bit 5: 1=SPI is enabled */ +#define SPI_CTL_MASTEREN (1 << 4) /* Bit 4: 1=SPI operates as a master */ +#define SPI_CTL_CPOL (1 << 3) /* Bit 3: 1=Master SCK pin idles in a high (1) state */ +#define SPI_CTL_CPHA (1 << 2) /* Bit 2: 1=SS remains Low to transfer any number of data bytes */ + +/* SR Register Definitions */ + +#define SPI_SR_SPIF (1 << 7) /* Bit x: 1=SPI data transfer is finished */ +#define SPI_SR_WCOL (1 << 6) /* Bit x: 1=SPI write collision is detected*/ +#define SPI_SR_MODF (1 << 4) /* Bit x: 1=Mode fault (multimaster conflict) is detected */ + +/* RBR/TSR Register Definitions */ + +/* No definitions: 8-bit SPI receive/transmit data */ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif /* __cplusplus */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: ez80_spibus_initialize + * + * Description: + * Initialize common parts the selected SPI port. Initialization of + * chip select GPIOs must have been performed by board specific logic + * prior to calling this function. Specifically: GPIOs should have + * been configured for output, and all chip selects disabled. + * + * One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However, + * If multiple devices on on the bus, then multiple chip selects will be + * required. Theregore, all GPIO chip management is deferred to board- + * specific logic. + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *ez80_spibus_initialize(int port); + +/************************************************************************************ + * The external functions, ez80_spiselect, ez80_spistatus, ans ez80_spicmddata must + * be provided by board-specific logic. These are implementations of the select, + * status, and cmddata methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including ez80_spibus_initialize()) are + * provided by common logic. To use this common SPI logic on your board: + * + * 1. Provide ez80_spiselect() and ez80_spistatus() functions in your board-specific + * logic. This function will perform chip selection and status operations using + * GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration, provide the + * ez80_spiscmddata() function in your board-specific logic. This function will + * perform cmd/data selection operations using GPIOs in the way your board is + * configured. + * 3. Add a call to ez80_spibus_initialize() in your low level initialization logic + * 4. The handle returned by ez80_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling mmcsd_spislotinitialize(), + * for example, will bind the SPI driver to the SPI MMC/SD driver). + * + ************************************************************************************/ + +void ez80_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t ez80_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int ez80_spicmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); + +#undef EXTERN +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_Z80_SRC_EZ80_EZ80F91_SPI_H */ diff --git a/arch/z80/src/ez80/switch.h b/arch/z80/src/ez80/switch.h new file mode 100644 index 0000000000000000000000000000000000000000..a6e46204d952b0431f9333bef3ba6802e1f99982 --- /dev/null +++ b/arch/z80/src/ez80/switch.h @@ -0,0 +1,171 @@ +/************************************************************************************ + * arch/z80/src/ez80/switch.h + * arch/z80/src/chip/switch.h + * + * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __EZ80_SWITCH_H +#define __EZ80_SWITCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +#endif +#include "common/up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Macros for portability *********************************************************** + * + * Common logic in arch/z80/src/common is customized for the z8 context switching + * logic via the following macros. + */ + +/* Initialize the IRQ state */ + +#define INIT_IRQCONTEXT() g_current_regs = NULL + +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt + * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). + */ + +#define IN_INTERRUPT() (g_current_regs != NULL) + +/* The following macro is used when the system enters interrupt handling logic + * + * NOTE: Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to change the way that + * g_current_regs is handled. The savestate variable would not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + +#define DECL_SAVESTATE() \ + FAR chipreg_t *savestate + +#define IRQ_ENTER(irq, regs) \ + do { \ + savestate = (FAR chipreg_t *)g_current_regs; \ + g_current_regs = (regs); \ + } while (0) + +/* The following macro is used when the system exits interrupt handling logic */ + +#define IRQ_LEAVE(irq) g_current_regs = savestate + +/* The following macro is used to sample the interrupt state (as a opaque handle) */ + +#define IRQ_STATE() (g_current_regs) + +/* Save the current IRQ context in the specified TCB */ + +#define SAVE_IRQCONTEXT(tcb) ez80_copystate((tcb)->xcp.regs, (FAR chipreg_t*)g_current_regs) + +/* Set the current IRQ context to the state specified in the TCB */ + +#define SET_IRQCONTEXT(tcb) ez80_copystate((FAR chipreg_t*)g_current_regs, (tcb)->xcp.regs) + +/* Save the user context in the specified TCB. User context saves can be simpler + * because only those registers normally saved in a C called need be stored. + */ + +#define SAVE_USERCONTEXT(tcb) ez80_saveusercontext((tcb)->xcp.regs) + +/* Restore the full context -- either a simple user state save or the full, + * IRQ state save. + */ + +#define RESTORE_USERCONTEXT(tcb) ez80_restorecontext((tcb)->xcp.regs) + +/* Dump the current machine registers */ + +#define _REGISTER_DUMP() ez80_registerdump() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage structure. + * If is non-NULL only during interrupt processing. + */ + +extern volatile chipreg_t *g_current_regs; +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Defined in ez80_copystate.c */ + +void ez80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); + +/* Defined in ez80_saveusercontext.asm */ + +int ez80_saveusercontext(FAR chipreg_t *regs); + +/* Defined in ez80_restorecontext.asm */ + +void ez80_restorecontext(FAR chipreg_t *regs); + +/* Defined in ez80_sigsetup.c */ + +void ez80_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, chipreg_t *regs); + +/* Defined in ez80_registerdump.c */ + +void ez80_registerdump(void); + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __EZ80_SWITCH_H */ diff --git a/arch/z80/src/ez80/up_mem.h b/arch/z80/src/ez80/up_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..9f65b5d084203797c6747edc665281b9cc9cf1dd --- /dev/null +++ b/arch/z80/src/ez80/up_mem.h @@ -0,0 +1,89 @@ +/************************************************************************************ + * arch/z80/src/ez80/up_mem.h + * arch/z80/src/chip/up_mem.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __EZ80_UP_MEM_H +#define __EZ80_UP_MEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* For the ZiLOG ZDS-II toolchain(s), the heap will be set using linker- + * defined values: + * + * _heapbot : set to the last used address + 1 in RAM + * _stack : set to the highest address + 1 in RAM + * + * The top of the heap is then determined by the amount of stack setaside + * in the NuttX configuration file + */ + +#ifndef CONFIG_HEAP1_BASE + extern unsigned long _heapbot; +# define CONFIG_HEAP1_BASE ((uint24_t)&_heapbot) +#endif + +#ifndef CONFIG_HEAP1_END + extern unsigned long _stack; +# define CONFIG_HEAP1_END (((uint24_t)&_stack) - CONFIG_IDLETHREAD_STACKSIZE) +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __EZ80_UP_MEM_H */ diff --git a/arch/z80/src/z180/Kconfig b/arch/z80/src/z180/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ce26721f761d2cea412e88f828219868ee76dfcf --- /dev/null +++ b/arch/z80/src/z180/Kconfig @@ -0,0 +1,477 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_Z180 + +choice + prompt "Toolchain Selection" + default Z180_TOOLCHAIN_SDCCW if HOST_WINDOWS + default Z180_TOOLCHAIN_SDCCL if !HOST_WINDOWS + +config Z180_TOOLCHAIN_SDCCL + bool "SDCC for Linux, MAC OSX, or Cygwin" + depends on !WINDOWS_NATIVE + +config Z180_TOOLCHAIN_SDCCW + bool "SDCC for Windows" + depends on HOST_WINDOWS + +endchoice + +config LINKER_HOME_AREA + hex "Physical start of _HOME area" + default 0x0000 + ---help--- + Physical address of the start of the linker HOME area. Default: 0x0000 + +config LINKER_CODE_AREA + hex "Physical start of _CODE area" + default 0x0200 + ---help--- + Physical address of the start of the linker _CODE area. Default: 0x0200 + +config LINKER_DATA_AREA + hex "Physical start of _DATA area" + default 0x8000 + ---help--- + Physical address of the start of the linker _DATA area. Default: 0x8000 + +config LINKER_ROM_AT_0000 + bool "ROM at Physical 0x0000" + default n + ---help--- + Some architectures may have ROM located at physical address zero. In this + case, a special version of the "head" file must be used. + +config Z180_BANKAREA_VIRTBASE + hex "Virtual Start of Bank Area" + default 0x8000 + ---help--- + This setting provides the virtual address of the start of the Bank Area. + NOTE that 0x0000 <= Z180_BANKAREA_BASE <= Z180_COMMONAREA_BASE is required! + Default: 0x8000 + + NuttX Memory Organization: + + Common Area 0: This area holds the common NuttX code that is + directly call-able from all application threads. Common Area + always starts at virtual address 0x0000 and extends to the + Bank Area + + Base Area: This area holds the common NuttX data (including the + share-able heap) that is accessible from all applications and + extends to Common Area 1. + + NOTE: That is execution from RAM, the common NuttX code and + data may be contiguous and lie in the same region (either + Common Area 0 or the Bank Area). The two regions above would + apply in a ROM'ed system, where Common Area 1 is ROM and the + Base Area is RAM. + + Common Area 1: This area holds the code and data that is unique + to a particular task. his area extends to the end of the virtual + address space. All tasks share the same virtual Common Area 2 + virtual address (but each has a unique mapping to different, + underlying physical addresses). + +config Z180_BANKAREA_PHYSBASE + hex "Physical Start of Bank Area" + default 0x08000 + ---help--- + This setting provides the physical address of the start of the Bank Area. + Default: 0x08000 + +config Z180_COMMON1AREA_VIRTBASE + hex "Virtual Start of Common Area 1" + default 0xc000 + ---help--- + This setting provides the virtual address of the start of the Common + Area 1. NOTE that 0x0000 <= Z180_BANKAREA_BASE <= Z180_COMMONAREA_BASE + is required! Default: 0xc000 + + NuttX Memory Organization: + + Common Area 0: This area holds the common NuttX code that is + directly call-able from all application threads. Common Area + always starts at virtual address 0x0000 and extends to the + Bank Area + + Base Area: This area holds the common NuttX data (including the + share-able heap) that is accessible from all applications and + extends to Common Area 1. + + NOTE: That is execution from RAM, the common NuttX code and + data may be contiguous and lie in the same region (either + Common Area 0 or the Bank Area). The two regions above would + apply in a ROM'ed system, where Common Area 1 is ROM and the + Base Area is RAM. + + Common Area 1: This area holds the code and data that is unique + to a particular task. his area extends to the end of the virtual + address space. All tasks share the same virtual Common Area 2 + virtual address (but each has a unique mapping to different, + underlying physical addresses). + +config Z180_PHYSHEAP_START + hex "Physical Start of Free Memory" + default 0x0c000 + ---help--- + This setting provides the physical address of the start of free physical + memory that will be used to allocate memory for tasks (Common Area 1). + Default: 0x0c000 + +config Z180_PHYSHEAP_END + hex "Physical End(+1) of Free Memory" + default 0x100000 + ---help--- + This setting provides the physical address of the end(+1) of free physical + memory that will be used to allocate memory for tasks (Common Area 1). + Default: 0x100000 + +config ARCH_HAVEHEAD + bool "Board-specific Head File" + default n + ---help--- + Use a board-specific version of the "head" file in the + configs//src directory + +menu "Z180 Peripheral Support" + +config Z180_UART0 + bool "UART0" + default n + ---help--- + Select to enable a serial port on UART0. On the Z8x182, bits 0-4 of + port B will not be available if ASCI channel 0 is selected. + +config Z180_UART1 + bool "UART1" + default n + ---help--- + Select to enable a serial port on UART1. On the Z8x182, bits 5-7 of + port B will not be available if ASCI channel 0 is selected. + +config Z180_SCC + bool "SCC" + default n + depends on ARCH_CHIP_Z80181 || ARCH_CHIP_Z8L181 + ---help--- + Select to enable a serial port on the SCC + +config Z180_ESCCA + bool "ESCC Channel A" + default n + depends on ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182 + ---help--- + Select to enable a serial port on ESCC Channel A. Not available + if port C is selected. + +config Z180_ESCCB + bool "ESCC Channel B" + default n + depends on (ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182) && !Z180_MIMIC + ---help--- + Select to enable a serial port on ESCC Channel B + +config Z180_PRT1 + bool "Timer 1" + default n + ---help--- + Select to enable a Programmable Reload Timer 1 (PRT1, PRT0 is used + by NuttX as the system timer) + +# config Z180_DMA0 +# bool "DMA0" +# default n +# ---help--- +# Select to enable support for DMA0 +# +# config Z180_DMA1 +# bool "DMA1" +# default n +# ---help--- +# Select to enable support for DMA1 + +config Z180_PORTA + bool "PORT A" + default n + depends on (ARCH_CHIP_Z80181 || ARCH_CHIP_Z8L181 || ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182) && !Z180_CTC + ---help--- + Select to enable a Port A (called PIA1 on the Z8x181) + +config Z180_PORTB + bool "PORT B" + default n + depends on ARCH_CHIP_Z80181 || ARCH_CHIP_Z8L181 || ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182 + ---help--- + Select to enable a Port B (called PIA2 on the Z8x181). On the Z8x182, + Bits 5-7 will not be available if ASCI channel 1 is used; Bits 0-4 will + not be available if ASCI channel 0 is used. + +config Z180_PORTC + bool "PORT C" + default n + depends on (ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182) && !Z180_ESCCA + ---help--- + Select to enable a Port C. Not available if ESCC channel A is selected. + +config Z180_CTC + bool "CTC" + default n + depends on ARCH_CHIP_Z80181 || ARCH_CHIP_Z8L181 + ---help--- + Select to enable the Counter/Timer (CTC) + +config Z180_MIMIC + bool "16550 MIMIC" + default n + depends on ARCH_CHIP_Z80182 || ARCH_CHIP_Z8L182 + ---help--- + Select to enable the 16550 MIMIC + +endmenu + +choice + prompt "Serial console" + default NO_SERIAL_CONSOLE + depends on DEV_CONSOLE + +config Z180_UART0_SERIAL_CONSOLE + bool "UART0" + depends on Z180_UART0 + +config Z180_UART1_SERIAL_CONSOLE + bool "UART1" + depends on Z180_UART1 + +config Z180_SCC_SERIAL_CONSOLE + bool "SCC" + depends on Z180_SCC + +config Z180_ESCCA_SERIAL_CONSOLE + bool "ESCC Channel A" + depends on Z180_ESCCA + +config Z180_ESCCB_SERIAL_CONSOLE + bool "ESCC Channel B" + depends on Z180_ESCCB + +endchoice + +menu "UART0 Configuration" + depends on Z180_UART0 + +config Z180_UART0_RXBUFSIZE + int "Receive Buffer Size" + default 64 + help + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config Z180_UART0_TXBUFSIZE + int "Transmit Buffer Size" + default 64 + help + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config Z180_UART0_BAUD + int "Baud Rate" + default 9600 + help + The configured BAUD of the SCC. + +config Z180_UART0_BITS + int "Character Size" + default 8 + help + The number of bits in one character. Must be either 5, 6, 7, or 8. + +config Z180_UART0_PARITY + int "Parity Setting" + default 0 + help + 0=no parity, 1=odd parity, 2=even parity + +config Z180_UART0_2STOP + int "use 2 stop bits" + default 0 + help + 1=Two stop bits + +endmenu + +menu "UART1 Configuration" + depends on Z180_UART1 + +config Z180_UART1_RXBUFSIZE + int "Receive Buffer Size" + default 64 + help + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config Z180_UART1_TXBUFSIZE + int "Transmit Buffer Size" + default 64 + help + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config Z180_UART1_BAUD + int "Baud Rate" + default 9600 + help + The configured BAUD of the SCC. + +config Z180_UART1_BITS + int "Character Size" + default 8 + help + The number of bits in one character. Must be either 5, 6, 7, or 8. + +config Z180_UART1_PARITY + int "Parity Setting" + default 0 + help + 0=no parity, 1=odd parity, 2=even parity + +config Z180_UART1_2STOP + int "use 2 stop bits" + default 0 + help + 1=Two stop bits + +endmenu + +menu "SCC Configuration" + depends on Z180_SCC + +config Z180_SCC_RXBUFSIZE + int "Receive Buffer Size" + default 64 + help + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config Z180_SCC_TXBUFSIZE + int "Transmit Buffer Size" + default 64 + help + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config Z180_SCC_BAUD + int "Baud Rate" + default 9600 + help + The configured BAUD of the SCC. + +config Z180_SCC_BITS + int "Character Size" + default 8 + help + The number of bits in one character. Must be either 5, 6, 7, or 8. + +config Z180_SCC_PARITY + int "Parity Setting" + default 0 + help + 0=no parity, 1=odd parity, 2=even parity + +config Z180_SCC_2STOP + int "use 2 stop bits" + default 0 + help + 1=Two stop bits + +endmenu + +menu "ESCC Channel A Configuration" + depends on Z180_ESCCA + +config Z180_ESCCA_RXBUFSIZE + int "Receive Buffer Size" + default 64 + help + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config Z180_ESCCA_TXBUFSIZE + int "Transmit Buffer Size" + default 64 + help + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config Z180_ESCCA_BAUD + int "Baud Rate" + default 9600 + help + The configured BAUD of the SCC. + +config Z180_ESCCA_BITS + int "Character Size" + default 8 + help + The number of bits in one character. Must be either 5, 6, 7, or 8. + +config Z180_ESCCA_PARITY + int "Parity Setting" + default 0 + help + 0=no parity, 1=odd parity, 2=even parity + +config Z180_ESCCA_2STOP + int "use 2 stop bits" + default 0 + help + 1=Two stop bits + +endmenu + +menu "ESCC Channel B Configuration" + depends on Z180_ESCCB + +config Z180_ESCCB_RXBUFSIZE + int "Receive Buffer Size" + default 64 + help + Characters are buffered as they are received. This specifies + the size of the receive buffer. + +config Z180_ESCCB_TXBUFSIZE + int "Transmit Buffer Size" + default 64 + help + Characters are buffered before being sent. This specifies + the size of the transmit buffer. + +config Z180_ESCCB_BAUD + int "Baud Rate" + default 9600 + help + The configured BAUD of the SCC. + +config Z180_ESCCB_BITS + int "Character Size" + default 8 + help + The number of bits in one character. Must be either 5, 6, 7, or 8. + +config Z180_ESCCB_PARITY + int "Parity Setting" + default 0 + help + 0=no parity, 1=odd parity, 2=even parity + +config Z180_ESCCB_2STOP + int "use 2 stop bits" + default 0 + help + 1=Two stop bits + +endmenu +endif diff --git a/arch/z80/src/z180/Make.defs b/arch/z80/src/z180/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..0f71bb9494f3e5103c1d0340caeec0fc3ddf70c5 --- /dev/null +++ b/arch/z80/src/z180/Make.defs @@ -0,0 +1,66 @@ +############################################################################ +# arch/z80/src/z180/Make.defs +# +# Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_ARCH_HAVEHEAD),) +ifeq ($(CONFIG_LINKER_ROM_AT_0000),y) +HEAD_ASRC = z180_rom.asm +else +HEAD_ASRC = z180_head.asm +endif +endif + +CMN_ASRCS = +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_createstack.c +CMN_CSRCS += up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_interruptcontext.c up_mdelay.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_stackframe.c up_reprioritizertr.c +CMN_CSRCS += up_unblocktask.c up_udelay.c up_usestack.c + +CHIP_ASRCS = z180_restoreusercontext.asm z180_saveusercontext.asm +CHIP_ASRCS += z180_vectcommon.asm + +ifeq ($(CONFIG_LINKER_ROM_AT_0000),y) +CHIP_ASRCS += z180_romvectors.asm +else +CHIP_ASRCS += z180_vectors.asm +endif + +CHIP_CSRCS = z180_copystate.c z180_initialstate.c z180_io.c z180_irq.c +CHIP_CSRCS += z180_lowscc.c z180_lowserial.c z180_modifiyreg8.c z180_mmu.c +CHIP_CSRCS += z180_registerdump.c z180_schedulesigaction.c z180_sigdeliver.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += z180_timerisr.c +endif diff --git a/arch/z80/src/z180/README.txt b/arch/z80/src/z180/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..b088470b6adbe4cac654e9262e11c812f0bad721 --- /dev/null +++ b/arch/z80/src/z180/README.txt @@ -0,0 +1,49 @@ +arch/z80/src/z180 +^^^^^^^^^^^^^^^^^ + +The arch/z80 directories contain files to support a variety of 8-bit architectures +from ZiLOG (and spin-architectures such as the Rabbit2000). The arch/z80/src/z180 +sub-directory contains logic unique to the classic Z180 family of chips. + +Files in this directory include: + +z180_head.asm + This is the main entry point into the Z180 program. This includes the + handler for the RESET, power-up interrupt vector and address zero and all + RST interrupts. + +z180_rom.asm + Some architectures may have ROM located at address zero. In this case, a + special version of the "head" logic must be used. This special "head" + file is probably board-specific and, hence, belongs in the board-specific + configs//src directory. This file may, however, be used as + a model for such a board-specific file. + + z180_rom.S is enabled by specifying CONFIG_LINKER_ROM_AT_0000 in the + configuration file. + + A board specific version in the configs//src directory can be + used by: + + 1. Define CONFIG_ARCH_HAVEHEAD + 2. Add the board-specific head file, say .asm, to + configs//src + 3. Add a file called Make.defs in the configs//src directory + containing the line: HEAD_ASRC = .asm + +Make.defs + This is the standard makefile fragment that must be provided in all + chip directories. This fragment identifies the chip-specific file to + be used in building libarch. + +chip.h + This is the standard header file that must be provided in all chip + directories. + +z180_initialstate.c, z180_copystate.c, z180_restoreusercontext.asm, and +z180_saveusercontext.asm, switch + These files implement the Z180 context switching logic + +z180_schedulesigaction.c and z180_sigdeliver.c + These files implement Z180 signal handling. + diff --git a/arch/z80/src/z180/Toolchain.defs b/arch/z80/src/z180/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..cf97558ffca55c069fa65cab349fa4f0786b4449 --- /dev/null +++ b/arch/z80/src/z180/Toolchain.defs @@ -0,0 +1,75 @@ +############################################################################ +# arch/z80/src/z180/Toolchain.defs +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# SDCC is currently the only z180 toolchain supported. See +# http://sdcc.sourceforge.net/. Source and pre-built SDCC binaries can be +# downloaded from the SDCC SourceForge site: +# http://sourceforge.net/projects/sdcc/files/. Pre-built binaries are +# available for Linux, MAC OSX, and for Win32. In addition, SDCC can be +# built to run on Windows as a POSIX toolchain. The various SDCC options are +# selected in the NuttX configuration with: +# +# CONFIG_Z180_TOOLCHAIN_SDCCL=y : SDCC for Linux, MAC OSX or Cygwin +# CONFIG_Z180_TOOLCHAIN_SDCCW=y : SDCC for Win32 +# + +ifeq ($(filter y, \ + $(CONFIG_Z180_TOOLCHAIN_SDCCL) \ + ),y) + CONFIG_Z180_TOOLCHAIN ?= SDCCPOSIX +endif +ifeq ($(filter y, \ + $(CONFIG_Z180_TOOLCHAIN_SDCCW) \ + ),y) + CONFIG_Z180_TOOLCHAIN ?= SDCCWIN32 +endif + +# SDCC toolchain under Linux, MAC OSX or Cygwin + +ifeq ($(CONFIG_Z180_TOOLCHAIN),POSIX) +endif + +# SDCC toolchain under Windows/Cygwin + +ifeq ($(CONFIG_AVR_TOOLCHAIN),SDCCWIN32) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + + diff --git a/arch/z80/src/z180/chip.h b/arch/z80/src/z180/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..b766654f6665a82d39d0e0ed52eb9e8d13ad165e --- /dev/null +++ b/arch/z80/src/z180/chip.h @@ -0,0 +1,54 @@ +/************************************************************************************ + * arch/z80/src/z180/chip.h + * arch/z80/src/chip/chip.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_CHIP_H +#define __ARCH_Z80_SRC_Z180_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_Z80_SRC_Z180_CHIP_H */ diff --git a/arch/z80/src/z180/switch.h b/arch/z80/src/z180/switch.h new file mode 100644 index 0000000000000000000000000000000000000000..4843fa450bdff7e905760e17f1643ebe51a7bf30 --- /dev/null +++ b/arch/z80/src/z180/switch.h @@ -0,0 +1,237 @@ +/************************************************************************************ + * arch/z80/src/z180/switch.h + * arch/z80/src/chip/switch.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_SWITCH_H +#define __ARCH_Z80_SRC_Z180_SWITCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "z180_iomap.h" +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Macros for portability *********************************************************** + * + * Common logic in arch/z80/src/common is customized for the z180 context switching + * logic via the following macros. + */ + +/* Initialize the IRQ state */ + +#define INIT_IRQCONTEXT() \ + g_current_regs = NULL + +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt + * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). + */ + +#define IN_INTERRUPT() \ + (g_current_regs != NULL) + +/* The following macro declares the variables need by IRQ_ENTER and IRQ_LEAVE. + * These variables are used to support nested interrupts. + * + * - savestate holds the previous value of current_state. + * - savecpr holds the previous value of current_cpr. + * + * NOTE: Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to change the way that + * g_current_regs/cbr is handled. The savestate/savecbr variables would not work + * for that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (they can probabaly be deleted). + */ + +#define DECL_SAVESTATE() \ + FAR chipreg_t *savestate; \ + uint8_t savecbr; + +/* The following macro is used when the system enters interrupt handling logic. + * The entry values of g_current_regs and current_cbr and stored in local variables. + * Then g_current_regs and current_cbr are set to the values of the interrupted + * task. + */ + +#define IRQ_ENTER(irq, regs) \ + do \ + { \ + savestate = (FAR chipreg_t *)g_current_regs; \ + savecbr = current_cbr; \ + g_current_regs = (regs); \ + current_cbr = inp(Z180_MMU_CBR); \ + } \ + while (0) + +/* The following macro is used when the system exits interrupt handling logic. + * The value of g_current_regs is restored. If we are not processing a nested + * interrupt (meaning that we going to return to the user task), then also + * set the MMU's CBR register. + */ + +#define IRQ_LEAVE(irq) \ + do \ + { \ + g_current_regs = savestate; \ + if (g_current_regs) \ + { \ + current_cbr = savecbr; \ + } \ + else \ + { \ + outp(Z180_MMU_CBR, savecbr); \ + } \ + } \ + while (0) + +/* The following macro is used to sample the interrupt state (as a opaque handle) */ + +#define IRQ_STATE() \ + (g_current_regs) + +/* Save the current IRQ context in the specified TCB */ + +#define SAVE_IRQCONTEXT(tcb) \ + z180_copystate((tcb)->xcp.regs, (FAR chipreg_t*)g_current_regs) + +/* Set the current IRQ context to the state specified in the TCB */ + +#define SET_IRQCONTEXT(tcb) \ + do \ + { \ + if ((tcb)->xcp.cbr) \ + { \ + current_cbr = (tcb)->xcp.cbr->cbr; \ + } \ + z180_copystate((FAR chipreg_t*)g_current_regs, (tcb)->xcp.regs); \ + } \ + while (0) + +/* Save the user context in the specified TCB. User context saves can be simpler + * because only those registers normally saved in a C called need be stored. + */ + +#define SAVE_USERCONTEXT(tcb) \ + z180_saveusercontext((tcb)->xcp.regs) + +/* Restore the full context -- either a simple user state save or the full, + * IRQ state save. + */ + +#define RESTORE_USERCONTEXT(tcb) \ + do \ + { \ + if ((tcb)->xcp.cbr) \ + { \ + outp(Z180_MMU_CBR, (tcb)->xcp.cbr->cbr); \ + } \ + z180_restoreusercontext((tcb)->xcp.regs); \ + } \ + while (0) + +/* Dump the current machine registers */ + +#define _REGISTER_DUMP() \ + z180_registerdump() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage structure. + * If is non-NULL only during interrupt processing. + */ + +extern volatile chipreg_t *g_current_regs; + +/* This holds the value of the MMU's CBR register. This value is set to the + * interrupted tasks's CBR on interrupt entry, changed to the new task's CBR if + * an interrupt level context switch occurs, and restored on interrupt exit. In + * this way, the CBR is always correct on interrupt exit. + */ + +extern uint8_t current_cbr; +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Defined in z180_copystate.c */ + +void z180_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); + +/* Defined in z180_saveusercontext.asm */ + +int z180_saveusercontext(FAR chipreg_t *regs); + +/* Defined in z180_restoreusercontext.asm */ + +void z180_restoreusercontext(FAR chipreg_t *regs); + +/* Defined in z180_sigsetup.c */ + +void z180_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs); + +/* Defined in z180_registerdump.c */ + +void z180_registerdump(void); + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_Z80_SRC_Z180_SWITCH_H */ diff --git a/arch/z80/src/z180/up_mem.h b/arch/z80/src/z180/up_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..351c1f2205efffaf651fb4b277d2d8f9643e383f --- /dev/null +++ b/arch/z80/src/z180/up_mem.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * common/sdcc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z180_SRC_COMMON_UP_MEM_H +#define __ARCH_Z180_SRC_COMMON_UP_MEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Locate the IDLE thread stack at the end of RAM. */ + +#define CONFIG_STACK_END CONFIG_RAM_SIZE +#define CONFIG_STACK_BASE (CONFIG_STACK_END - CONFIG_IDLETHREAD_STACKSIZE) + +/* The heap then extends from the linker determined beginning of the heap (s__HEAP). + * to the bottom of the IDLE thread stack. NOTE: The symbol s__HEAP is not + * accessible from C because it does not begin with the _ character. g_heapbase + * is defined in z180_head.asm to provide that value to the C code. + */ + +#define CONFIG_HEAP1_END CONFIG_STACK_BASE +#define CONFIG_HEAP1_BASE g_heapbase + +/************************************************************************************ + * Public variables + ************************************************************************************/ + +/* This is the bottom of the heap as provided by the linker symbol s__HEAP. NOTE: + * The symbol s__HEAP is not accessible from C because it does not begin with the _ + * character. g_heapbase is defined in z180_head.asm to provide that value to the C + * code. + */ + +extern const uint16_t g_heapbase; + +#endif /* __ARCH_Z180_SRC_COMMON_UP_MEM_H */ diff --git a/arch/z80/src/z180/z180_config.h b/arch/z80/src/z180/z180_config.h new file mode 100644 index 0000000000000000000000000000000000000000..556973a7531b6a238c51630de13f30600b908dc3 --- /dev/null +++ b/arch/z80/src/z180/z180_config.h @@ -0,0 +1,233 @@ +/************************************************************************************ + * arch/z80/src/z180/z180_config.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_Z180_CONFIG_H +#define __ARCH_Z80_SRC_Z180_Z180_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Verify that selected features match the capability of the selected CPU */ + +#ifndef HAVE_Z8X181 +# undef CONFIG_Z180_SCC +# undef CONFIG_Z180_CTC +#endif + +#ifndef HAVE_Z8X182 +# undef CONFIG_Z180_ESCCA +# undef CONFIG_Z180_ESCCB +# undef CONFIG_Z180_PORTC +# undef CONFIG_Z180_MIMIC +#endif + +#if !defined(HAVE_Z8X181) && !defined(HAVE_Z8X182) +# undef CONFIG_Z180_PORTA +# undef CONFIG_Z180_PORTB +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#undef HAVE_SCC +#undef HAVE_SERIAL + +#if defined(CONFIG_Z180_UART0) || defined(CONFIG_Z180_UART1) +# define HAVE_UART 1 +# define HAVE_SERIAL 1 +#endif + +#if defined(CONFIG_Z180_SCC) || defined(CONFIG_Z180_ESCCA) || \ + defined(CONFIG_Z180_ESCCB) +# define HAVE_SCC 1 +# define HAVE_SERIAL 1 +#endif + +/* Make sure all features are disabled for disabled UARTs/[E]SCC channels. This + * simplifies checking later. + */ + +#ifndef CONFIG_Z180_UART0 +# undef CONFIG_Z180_UART0_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z180_UART1 +# undef CONFIG_Z180_UART1_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z180_SCC +# undef CONFIG_SCC_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z180_ESCCA +# undef CONFIG_Z180_ESCCA_SERIAL_CONSOLE +#endif + +#ifndef CONFIG_Z180_ESCCB +# undef CONFIG_Z180_ESCCB_SERIAL_CONSOLE +#endif + +/* Is there a serial console? There should be at most one defined. */ + +#undef HAVE_UART_CONSOLE +#undef HAVE_SCC_CONSOLE +#undef HAVE_SERIAL_CONSOLE + +#if defined(CONFIG_Z180_UART0_SERIAL_CONSOLE) +# define HAVE_UART_CONSOLE 1 +# define HAVE_SERIAL_CONSOLE 1 + + /* Disable other console selections */ + +# undef CONFIG_Z180_UART1_SERIAL_CONSOLE +# undef CONFIG_Z180_SCC_SERIAL_CONSOLE +# undef CONFIG_Z180_ESCCA_SERIAL_CONSOLE +# undef CONFIG_Z180_ESCCB_SERIAL_CONSOLE + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +# ifndef USE_SERIALDRIVER +# undef CONFIG_Z180_UART1 +# undef CONFIG_Z180_SCC +# undef CONFIG_Z180_ESCCA +# undef CONFIG_Z180_ESCCB +# endif + +#elif defined(CONFIG_Z180_UART1_SERIAL_CONSOLE) +# define HAVE_UART_CONSOLE 1 +# define HAVE_SERIAL_CONSOLE 1 + + /* Disable other console selections */ + +# undef CONFIG_Z180_SCC_SERIAL_CONSOLE +# undef CONFIG_Z180_ESCCA_SERIAL_CONSOLE +# undef CONFIG_Z180_ESCCB_SERIAL_CONSOLE + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +# ifndef USE_SERIALDRIVER +# undef CONFIG_Z180_UART0 +# undef CONFIG_Z180_SCC +# undef CONFIG_Z180_ESCCA +# undef CONFIG_Z180_ESCCB +# endif + +#elif defined(CONFIG_Z180_SCC_SERIAL_CONSOLE) +# define HAVE_SCC_CONSOLE 1 +# define HAVE_SERIAL_CONSOLE 1 + + /* Disable other console selections */ + +# undef CONFIG_Z180_ESCCA_SERIAL_CONSOLE +# undef CONFIG_Z180_ESCCB_SERIAL_CONSOLE + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +# ifndef USE_SERIALDRIVER +# undef CONFIG_Z180_UART0 +# undef CONFIG_Z180_UART1 +# undef CONFIG_Z180_ESCCA +# undef CONFIG_Z180_ESCCB +# endif + +#elif defined(CONFIG_Z180_ESCCA_SERIAL_CONSOLE) +# define HAVE_SCC_CONSOLE 1 +# define HAVE_SERIAL_CONSOLE 1 + + /* Disable other console selections */ + +# undef CONFIG_Z180_ESCCB_SERIAL_CONSOLE + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +# ifndef USE_SERIALDRIVER +# undef CONFIG_Z180_UART0 +# undef CONFIG_Z180_UART1 +# undef CONFIG_Z180_SCC +# undef CONFIG_Z180_ESCCB +# endif + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +#elif defined(CONFIG_Z180_ESCCB_SERIAL_CONSOLE) +# define HAVE_SCC_CONSOLE 1 +# define HAVE_SERIAL_CONSOLE 1 + + /* If we are not using the serial driver, then the serial console is all + * that we will support. + */ + +# ifndef USE_SERIALDRIVER +# undef CONFIG_Z180_UART0 +# undef CONFIG_Z180_UART1 +# undef CONFIG_Z180_SCC +# undef CONFIG_Z180_ESCCA +# endif + +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_Z80_SRC_Z180_Z180_CONFIG_H */ diff --git a/arch/z80/src/z180/z180_copystate.c b/arch/z80/src/z180/z180_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..6824438cabed1149e134c10982b5ac65045bd46c --- /dev/null +++ b/arch/z80/src/z180/z180_copystate.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_copystate.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_copystate + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +void z180_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/z80/src/z180/z180_head.asm b/arch/z80/src/z180/z180_head.asm new file mode 100644 index 0000000000000000000000000000000000000000..2ecbefe2462932a9f37a15336ebcb8da0a068a44 --- /dev/null +++ b/arch/z80/src/z180/z180_head.asm @@ -0,0 +1,212 @@ +;************************************************************************** +; arch/z80/src/z180/z180_head.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z180 + .module z180_head + +;************************************************************************** +; Constants +;************************************************************************** + + ; Default stack base (needs to be fixed) + + .include "asm_mem.h" + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _os_start ; OS entry point + .globl _up_vectcommon ; Common interrupt handling logic + .globl _z180_mmu_lowinit ; MMU initialization logic + .globl s__HEAP ; Start of the heap + +;************************************************************************** +; Reset entry point +;************************************************************************** + + .area _HEADER (ABS) + .org 0x0000 + + di ; Disable interrupts + im 1 ; Set interrupt mode 1 + jr _up_reset ; And boot the system + +;************************************************************************** +; Other reset handlers +;************************************************************************** + + .org 0x0008 ; RST 1 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #0 ; 0 = Z180_RST1 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0010 ; RST 2 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #1 ; 1 = Z180_RST2 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0018 ; RST 3 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #2 ; 2 = Z180_RST3 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0020 ; RST 4 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #3 ; 3 = Z180_RST4 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0028 ; RST 5 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #4 ; 4 = Z180_RST5 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0030 ; RST 6 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #5 ; 5 = Z180_RST6 + jp _up_vectcommon ; Remaining RST handling is common + + .org 0x0038 ; Int mode 1 / RST 7 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #6 ; 6 = Z180_RST7 + jp _up_vectcommon ; Remaining RST handling is common + +;************************************************************************** +; NMI interrupt handler +;************************************************************************** + + .org 0x0066 + retn + +;************************************************************************** +; System start logic +;************************************************************************** + +_up_reset: + ; Set up the stack pointer at the location determined the Makefile + ; and stored in asm_mem.h + + ld SP, #CONFIG_STACK_END ; Set stack pointer + + ; Configure the MMU so that things will lie at the addresses that we + ; expect them to + + call _z180_mmu_lowinit ; Initialize the MMU + + ; Performed initialization unique to the SDCC toolchain + + call gsinit ; Initialize the data section + + ; Then start NuttX + + call _os_start ; jump to the OS entry point + + ; NuttX will never return, but just in case... + +_up_halt:: + halt ; We should never get here + jp _up_halt + +;************************************************************************** +; Ordering of segments for the linker (SDCC only) +;************************************************************************** + + .area _HOME + .area _CODE + .area _INITIALIZER + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _INITIALIZED + .area _BSEG + .area _BSS + .area _HEAP + +;************************************************************************** +; Global data initialization logic (SDCC only) +;************************************************************************** + + .area _GSINIT +gsinit:: + ld bc, #l__INITIALIZER + ld a, b + or a, c + jr Z, gsinit_next + ld de, #s__INITIALIZED + ld hl, #s__INITIALIZER + ldir +gsinit_next: + + .area _GSFINAL + ret + +;************************************************************************** +; The start of the heap (SDCC only). Note that is actually resides in +; the _CODE area (which may be FLASH or ROM) +;************************************************************************** + + .area _CODE +_g_heapbase:: + .dw #s__HEAP + diff --git a/arch/z80/src/z180/z180_initialstate.c b/arch/z80/src/z180/z180_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..f163738c9167449594017e1c1db60a83ca8cd6ff --- /dev/null +++ b/arch/z80/src/z180/z180_initialstate.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_initialstate.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the initial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); +#ifndef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[XCPT_I] = Z180_PV_FLAG; /* Parity flag will enable interrupts */ +#endif + xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; +} diff --git a/arch/z80/src/z180/z180_io.c b/arch/z80/src/z180/z180_io.c new file mode 100644 index 0000000000000000000000000000000000000000..e5b13a7eb7c8d9c6d68ca35f01394b44cf2ea4e6 --- /dev/null +++ b/arch/z80/src/z180/z180_io.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_io.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +/* #include */ + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: outb + * + * Description: + * Output byte c on port p + * + ****************************************************************************/ + +void outp(char p, char c) +{ + __asm + ld c, 4(ix) ; port + ld a, 5(ix) ; value + out (c), a + __endasm; +} + + +/**************************************************************************** + * Name: inpb + * + * Description: + * Input byte from port p + * + ****************************************************************************/ + +char inp(char p) __naked +{ + __asm + ld c, 4(ix) ;port + in l, (c) + __endasm; +} diff --git a/arch/z80/src/z180/z180_iomap.h b/arch/z80/src/z180/z180_iomap.h new file mode 100644 index 0000000000000000000000000000000000000000..f2e9d5915f7b9d8065407462fcda8ce5af813319 --- /dev/null +++ b/arch/z80/src/z180/z180_iomap.h @@ -0,0 +1,890 @@ +/************************************************************************************ + * arch/z80/src/z180/z180_iomap.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_Z180_IOMAP_H +#define __ARCH_Z80_SRC_Z180_Z180_IOMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +/* These registers may be relocated to multiples of 0x40 by setting the IO Control + * Register (ICR). Relocatable to 0x40-0x7f, or 0x80-0xbf. The configuration setting, + * CONFIG_Z180_SFROFFSET, indicates that offset (but is not fully supported yet!) + */ + +#ifdef CONFIG_Z180_SFROFFSET +# define SFR_OFFSET CONFIG_Z180_SFROFFSET +#else +# define SFR_OFFSET 0 +#endif + +/* Z180 Register Bit addresses ******************************************************/ +/* ASCI Registers */ + +#define Z180_ASCI0_CNTLA (SFR_OFFSET+0x00) /* ASCI Control Register A Ch 0 */ +#define Z180_ASCI1_CNTLA (SFR_OFFSET+0x01) /* ASCI Control Register A Ch 1 */ +#define Z180_ASCI0_CNTLB (SFR_OFFSET+0x02) /* ASCI Control Register B Ch 0 */ +#define Z180_ASCI1_CNTLB (SFR_OFFSET+0x03) /* ASCI Control Register B Ch 1 */ +#define Z180_ASCI0_STAT (SFR_OFFSET+0x04) /* ASCI Status Register Ch 0 */ +#define Z180_ASCI1_STAT (SFR_OFFSET+0x05) /* ASCI Status Register Ch 1 */ +#define Z180_ASCI0_TDR (SFR_OFFSET+0x06) /* ASCI Transmit Data Register Ch 0 */ +#define Z180_ASCI1_TDR (SFR_OFFSET+0x07) /* ASCI Transmit Data Register Ch 1 */ +#define Z180_ASCI0_RDR (SFR_OFFSET+0x08) /* ASCI Receive Data Register Ch 0 */ +#define Z180_ASCI1_RDR (SFR_OFFSET+0x09) /* ASCI Receive Data Register Ch 1 */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define Z180_ASCI0_ASEXT (SFR_OFFSET+0x12) /* ASCI Extension Control Register */ +# define Z180_ASCI1_ASEXT (SFR_OFFSET+0x13) /* ASCI Extension Control Register */ +#endif + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define Z180_ASCI0_ASTCL (SFR_OFFSET+0x1a) /* ASCI Time Constant Low */ +# define Z180_ASCI0_ASTCH (SFR_OFFSET+0x1b) /* ASCI Time Constant High */ +# define Z180_ASCI1_ASTCL (SFR_OFFSET+0x1c) /* ASCI Time Constant Low */ +# define Z180_ASCI1_ASTCH (SFR_OFFSET+0x1d) /* ASCI Time Constant High */ +#endif + +/* CSI/O Registers */ + +#define Z180_CSIO_CNTR (SFR_OFFSET+0x0a) /* CSI/O Control Register */ +#define Z180_CSIO_TRD (SFR_OFFSET+0x0b) /* Transmit/Receive Data Register */ + +/* Programmable Reload Timer (PTR) Registers */ + +#define Z180_PRT0_DRL (SFR_OFFSET+0x0c) /* Timer Data Register Ch 0 L */ +#define Z180_PRT0_DRH (SFR_OFFSET+0x0d) /* Data Register Ch 0 H */ +#define Z180_PRT0_RLDRL (SFR_OFFSET+0x0e) /* Reload Register Ch 0 L */ +#define Z180_PRT0_RLDRH (SFR_OFFSET+0x0f) /* Reload Register Ch 0 H */ +#define Z180_PRT_TCR (SFR_OFFSET+0x10) /* Timer Control Register */ + +#define Z180_PRT1_DRL (SFR_OFFSET+0x14) /* Data Register Ch 1 L */ +#define Z180_PRT1_DRH (SFR_OFFSET+0x15) /* Data Register Ch 1 H */ +#define Z180_PRT1_RLDRL (SFR_OFFSET+0x16) /* Reload Register Ch 1 L */ +#define Z180_PRT1_RLDRH (SFR_OFFSET+0x17) /* Reload Register Ch 1 H */ + +#define Z180_FRC (SFR_OFFSET+0x18) /* Free Running Counter */ + +/* DMA Registers */ + +#define Z180_DMA0_SARL (SFR_OFFSET+0x20) /* DMA Source Address Register Ch 0L */ +#define Z180_DMA0_SARH (SFR_OFFSET+0x21) /* DMA Source Address Register Ch 0H */ +#define Z180_DMA0_SARB (SFR_OFFSET+0x22) /* DMA Source Address Register Ch 0B */ +#define Z180_DMA0_DARL (SFR_OFFSET+0x23) /* DMA Destination Address Register Ch 0L */ +#define Z180_DMA0_DARH (SFR_OFFSET+0x24) /* DMA Destination Address Register Ch 0H */ +#define Z180_DMA0_DARB (SFR_OFFSET+0x25) /* DMA Destination Address Register Ch 0B */ +#define Z180_DMA0_BCRL (SFR_OFFSET+0x26) /* DMA Byte Count Register Ch 0L */ +#define Z180_DMA0_BCRH (SFR_OFFSET+0x27) /* DMA Byte Count Register Ch 0H */ + +#define Z180_DMA1_MARL (SFR_OFFSET+0x28) /* DMA Memory Address Register Ch 1L */ +#define Z180_DMA1_MARH (SFR_OFFSET+0x29) /* DMA Memory Address Register Ch 1H */ +#define Z180_DMA1_MARB (SFR_OFFSET+0x2a) /* DMA Memory Address Register Ch 1B */ +#define Z180_DMA1_IARL (SFR_OFFSET+0x2b) /* DMA I/0 Address Register Ch 1L */ +#define Z180_DMA1_IARH (SFR_OFFSET+0x2c) /* DMA I/0 Address Register Ch 1H */ +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define Z180_DMA1_IARB (SFR_OFFSET+0x2d) /* DMA I/O Address Register Ch 1B */ +#endif +#define Z180_DMA1_BCRL (SFR_OFFSET+0x2e) /* DMA Byte Count Register Ch 1L */ +#define Z180_DMA1_BCRH (SFR_OFFSET+0x2f) /* DMA Byte Count Register Ch 1H */ + +#define Z180_DMA_DSTAT (SFR_OFFSET+0x30) /* DMA Status Register */ +#define Z180_DMA_DMODE (SFR_OFFSET+0x31) /* DMA Mode Register */ +#define Z180_DMA_DCNTL (SFR_OFFSET+0x32) /* DMA/WAIT Control Register */ + +/* System Control Registers */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define Z180_CMR (SFR_OFFSET+0x1e) /* Clock Multiplier Register */ +#endif + +#if defined(HAVE_Z8S180) || defined(HAVE_Z8X182) +# define Z180_CCR (SFR_OFFSET+0x1f) /* CPU Control Register */ +#endif + +#define Z180_INT_IL (SFR_OFFSET+0x33) /* IL Register (Interrupt Vector Low Register) */ +#define Z180_INT_ITC (SFR_OFFSET+0x34) /* INT/TRAP Control Register */ + +#define Z180_RCR (SFR_OFFSET+0x36) /* Refresh Control Register */ + +#define Z180_MMU_CBR (SFR_OFFSET+0x38) /* MMU Common Base Register */ +#define Z180_MMU_BBR (SFR_OFFSET+0x39) /* MMU Bank Base Register */ +#define Z180_MMU_CBAR (SFR_OFFSET+0x3a) /* MMU Common/Bank Area Register */ + +#define Z180_OMCR (SFR_OFFSET+0x3e) /* Operation Mode Control Register */ +#define Z180_ICR (SFR_OFFSET+0x3f) /* I/O Control Register */ + +/* The following registers are not relocatable */ +/* Registers unique to Z8x181 class CPUs */ + +#ifdef HAVE_Z8X181 + +/* PIA Registers */ + +# define Z181_PIA1_DDR 0xe0 /* PIA1 Data Direction Register */ +# define Z181_PIA1_DP 0xe1 /* PIA1 Data Port */ +# define Z181_PIA2_DDR 0xe2 /* PIA2 Data Direction Register */ +# define Z181_PIA1_DP 0xe3 /* PIA2 Data Register */ + +/* CTC Registers */ + +# define Z181_CTC0 0xe4 /* CTC Channel 0 Control/Vector Register */ +# define Z181_CTC1 0xe5 /* CTC Channel 1 Control/Vector Register */ +# define Z181_CTC2 0xe6 /* CTC Channel 2 Control/Vector Register */ +# define Z181_CTC3 0xe7 /* CTC Channel 3 Control/Vector Register */ + +/* SCC Registers */ + +# define Z181_SCC_CR 0xe8 /* SCC Control Register */ +# define Z181_SCC_DR 0xe9 /* SCC Data Register */ + +/* System Control Registers */ + +# define Z181_RAM_UBR 0xea /* RAM Upper Boundary Address Register */ +# define Z181_RAM_LBR 0xeb /* RAM Lower Boundary Address Register */ +# define Z181_ROM_BR 0xec /* ROM Address Boundary Register */ +# define Z181_SCR 0xed /* System Configuration Register */ +#endif + +/* Registers unique to Z8x182 class CPUs */ + +#ifdef HAVE_Z8X182 +# define Z182_WSGCS 0xd8 /* WSG Chip Select Register */ +# define Z182_ENH182 0xd9 /* Z80182 Enhancements Register */ +# define Z182_INTEDGE 0xdf /* Interrupt Edge/Pin MUX Control */ + +/* PIA Registers */ + +# define Z182_PA_DDR 0xed /* PA Data Direction Register */ +# define Z182_PA_DR 0xee /* PA Data Register */ +# define Z182_PB_DDR 0xe4 /* PB Data Direction Register */ +# define Z182_PB_DR 0xe5 /* PB Data Register */ +# define Z182_PC_DDR 0xdd /* PC Data Direction Register */ +# define Z182_PC_DR 0xde /* PC Data Register */ + +/* ESCC Registers */ + +# define Z182_ESCCA_CR 0xe0 /* ESCC Chan A Control Register */ +# define Z182_ESCCA_DR 0xe1 /* ESCC Chan A Data Register */ +# define Z182_ESCCB_CR 0xe2 /* ESCC Chan B Control Register */ +# define Z182_ESCCB_DR 0xe3 /* ESCC Chan B Data Register */ + +/* System Control Registers */ + +# define Z182_RAM_UBR 0xe6 /* RAMUBR RAM Upper Boundary Register */ +# define Z182_RAM_LBR 0xe7 /* RAMLBR RAM Lower Boundary Register */ +# define Z182_ROM_BR 0xe8 /* ROM Address Boundary Register */ +# define Z182_SCR 0xef /* System Configuration Register */ + +/* 16550 MIMIC Registers */ + +# define Z182_MIMIC_FCR 0xe9 /* FIFO Control Register */ +# define Z182_MIMIC_MM 0xe9 /* MM register */ +# define Z182_MIMIC_RTTC 0xea /* Receive Timeout Time Constant */ +# define Z182_MIMIC_TTTC 0xeb /* Transmit Timeout Time Constant */ +# define Z182_MIMIC_FSCR 0xec /* FIFO Status and Control */ +# define Z182_MIMIC_RBR 0xf0 /* Receive Buffer Register */ +# define Z182_MIMIC_THR 0xf0 /* Transmit Holding Register */ +# define Z182_MIMIC_IER 0xf1 /* Interrupt Enable Register */ +# define Z182_MIMIC_LCR 0xf3 /* Line Control Register */ +# define Z182_MIMIC_MCR 0xf4 /* Modem Control Register */ +# define Z182_MIMIC_LSR 0xf5 /* Line Status Register */ +# define Z182_MIMIC_MSR 0xf6 /* Modem Status Register */ +# define Z182_MIMIC_SCR 0xf7 /* Scratch Register */ +# define Z182_MIMIC_DLL 0xf8 /* Divisor Latch (LSByte) */ +# define Z182_MIMIC_DLM 0xf9 /* Divisor Latch (MSByte) */ +# define Z182_MIMIC_TTCR 0xfa /* Transmit Time Constant */ +# define Z182_MIMIC_RTCR 0xfb /* Receive Time Constant */ +# define Z182_MIMIC_IVEC 0xfc /* Interrupt Vector */ +# define Z182_MIMIC_IE 0xfd /* Interrupt Enable */ + +# define Z182_MIMIC_IUSIP 0xfe /* Interrupt Under-Service/Interrupt Pending */ +# define Z182_MIMIC_MMC 0xff /* MIMIC Master Control Register */ + +/* Some of the MIMIC registers are accessible to memory-mapped addresses */ + +# define Z182_MIMIC_RBR_ADDR 0x0000 /* Receive Buffer Register */ +# define Z182_MIMIC_DLL_ADDR 0x0000 /* Divisor Latch (LSByte) */ +# define Z182_MIMIC_THR_ADDR 0x0000 /* Transmit Holding Register */ +# define Z182_MIMIC_DLM_ADDR 0x0001 /* Divisor Latch (MSByte) */ +# define Z182_MIMIC_IER_ADDR 0x0001 /* Interrupt Enable Register */ +# define Z182_MIMIC_IIR_ADDR 0x0002 /* Interrupt Identification */ +# define Z182_MIMIC_FCR_ADDR 0x0002 /* FIFO Control Register */ +# define Z182_MIMIC_LCR_ADDR 0x0003 /* Line Control Register */ +# define Z182_MIMIC_MCR_ADDR 0x0004 /* Modem Control Register */ +# define Z182_MIMIC_LSR_ADDR 0x0005 /* Line Status Register */ +# define Z182_MIMIC_MSR_ADDR 0x0006 /* Modem Status Register */ +# define Z182_MIMIC_SCR_ADDR 0x0007 /* Scratch Register */ +#endif + +/* [E]SCC Internal Register Definitions */ +/* Read Registers. The SCC contains eight read registers. To read the contents + * of a register (rather than RR0), the program must first initialize a pointer + * to WR0 in exactly the same manner as a write operation. The next I/O read + * cycle will place the contents of the selected read registers onto the data bus + */ + +#define Z18X_SCC_RR0 0x00 /* Transmit and Receive buffer status and external status */ +#define Z18X_SCC_RR1 0x01 /* Special Receive Condition status */ +#define Z18X_SCC_RR2 0x02 /* Interrupt vector (modified if VIS Bit in WR9 is set) */ +#define Z18X_SCC_RR3 0x03 /* Interrupt pending bits */ +#define Z18X_SCC_RR6 0x06 /* SDLC FIFO byte counter lower byte (only when enabled) */ +#define Z18X_SCC_RR7 0x07 /* SDLC FIFO byte count and status (only when enabled) */ +#define Z18X_SCC_RR8 0x08 /* Receive buffer */ +#define Z18X_SCC_RR10 0x0a /* Miscellaneous status bits */ +#define Z18X_SCC_RR12 0x0c /* Lower byte of baud rate generator time constant */ +#define Z18X_SCC_RR13 0x0d /* Upper byte of baud rate generator time constant */ +#define Z18X_SCC_RR15 0x0f /* External Status interrupt information */ + +/* Write Registers. The SCC contains fifteen write registers that are programmed + * to configure the operating modes of the channel. With the exception of WR0, programming + * the write registers is a two step operation. The first operation is a pointer written to + * WR0 that points to the selected register. The second operation is the actual contro + * word that is written into the register to configure the SCC channel + */ + +#define Z18X_SCC_WR0 0x00 /* Register Pointers, various initialization commands */ +#define Z18X_SCC_WR1 0x01 /* Transmit and Receive interrupt enables, WAIT/DMA commands */ +#define Z18X_SCC_WR2 0x02 /* Interrupt Vector */ +#define Z18X_SCC_WR3 0x03 /* Receive parameters and control modes */ +#define Z18X_SCC_WR4 0x04 /* Transmit and Receive modes and parameters */ +#define Z18X_SCC_WR5 0x05 /* Transmit parameters and control modes */ +#define Z18X_SCC_WR6 0x06 /* Sync Character or SDLC address */ +#define Z18X_SCC_WR7 0x07 /* Sync Character or SDLC flag */ +#define Z18X_SCC_WR8 0x08 /* Transmit buffer */ +#define Z18X_SCC_WR9 0x09 /* Master Interrupt control and reset commands */ +#define Z18X_SCC_WR10 0x0a /* Miscellaneous transmit and receive control bits */ +#define Z18X_SCC_WR11 0x0b /* Clock mode controls for receive and transmit */ +#define Z18X_SCC_WR12 0x0c /* Lower byte of baud rate generator */ +#define Z18X_SCC_WR13 0x0d /* Upper byte of baud rate generator */ +#define Z18X_SCC_WR14 0x0e /* Miscellaneous control bits */ +#define Z18X_SCC_WR15 0x0f /* External status interrupt enable control */ + +/* Z180 Register Bit definitions ****************************************************/ +/* ASCI Registers *******************************************************************/ +/* ASCI Control Register A 0 (CNTLA0: 0x00) */ +/* ASCI Control Register A 1 (CNTLA1: 0x01) */ + +#define ASCI_CNTRLA_MPE (0x80) /* Bit 7: Multi-Processor Mode Enable */ +#define ASCI_CNTRLA_RE (0x40) /* Bit 6: Receiver Enab */ +#define ASCI_CNTRLA_TE (0x20) /* Bit 5: Transmitter Enable */ +#define ASCI_CNTRLA_RTS0 (0x10) /* Bit 4: Request to Send Channel 0 (ASCI0 only) */ +#define ASCI_CNTRLA_CKA1D (0x10) /* Bit 4: CKA1 Clock Disable (ASCI1 only) */ +#define ASCI_CNTRLA_MPBR (0x08) /* Bit 3: Multiprocessor Bit Receive */ +#define ASCI_CNTRLA_EFR (0x08) /* Bit 3: Error Flag Reset */ +#define ASCI_CNTRLA_MOD2 (0x04) /* Bit 2: 8 bit data */ +#define ASCI_CNTRLA_MOD1 (0x02) /* Bit 1: Parity enabled */ +#define ASCI_CNTRLA_MOD0 (0x01) /* Bit 0: Parity enabled */ + +/* ASCI Control Register B 0 (CNTLB0: 0x02) */ +/* ASCI Control Register B 1 (CNTLB1: 0x03) */ + +#define ASCI_CNTRLB_MPBT (0x80) /* Bit 7: Multiprocessor Bit Transmit */ +#define ASCI_CNTRLB_MP (0x40) /* Bit 6: Multiprocessor Mode */ +#define ASCI_CNTRLB_CTS (0x20) /* Bit 5: Clear to Send */ +#define ASCI_CNTRLB_PS (0x20) /* Bit 5: Prescale */ +#define ASCI_CNTRLB_PEO (0x10) /* Bit 4: Parity Even Odd */ +#define ASCI_CNTRLB_DR (0x08) /* Bit 3: Divide Ratio */ + +#define ASCI_CNTRLB_SS_SHIFT (0) /* Bits 0-2: Source/Speed Select */ +#define ASCI_CNTRLB_SS_MASK (7 << ASCI_CNTRLB_SS_SHIFT) +# define ASCI_CNTRLB_SS_DIV1 (0 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 1 */ +# define ASCI_CNTRLB_SS_DIV2 (1 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 2 */ +# define ASCI_CNTRLB_SS_DIV4 (2 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 4 */ +# define ASCI_CNTRLB_SS_DIV8 (3 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 8 */ +# define ASCI_CNTRLB_SS_DIV16 (4 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 16 */ +# define ASCI_CNTRLB_SS_DIV32 (5 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 32 */ +# define ASCI_CNTRLB_SS_DIV64 (6 << ASCI_CNTRLB_SS_SHIFT) /* Divide Ratio: 64 */ +# define ASCI_CNTRLB_SS_EXT (7 << ASCI_CNTRLB_SS_SHIFT) /* External clock */ + +/* ASCI Status Register 0 (STAT0: 0x04) */ +/* ASCI Status Register 1 (STAT1: 0x05) */ + +#define ASCI_STAT_RFRF (0x80) /* Bit 7: Receive Data Register Full */ +#define ASCI_STAT_OVRN (0x40) /* Bit 6: Overrun Error */ +#define ASCI_STAT_PE (0x20) /* Bit 5: Parity Error */ +#define ASCI_STAT_FE (0x10) /* Bit 4: Framing Error */ +#define ASCI_STAT_RIE (0x08) /* Bit 3: Receive Interrupt Enable */ +#define ASCI_STAT_DCD0 (0x04) /* Bit 2: Data Carrier Detect (ASCI0 only) */ +#define ASCI_STAT_CTS1E (0x04) /* Bit 2: Channel 1 CTS Enable (ASCI1 only) */ +#define ASCI_STAT_TDRE (0x02) /* Bit 1: Transmit Data Register Empty */ +#define ASCI_STAT_TIE (0x01) /* Bit 0: Transmit Interrupt Enable */ + +/* ASCI Transmit Data Register Ch. 0 (TDR0: 0x06) - 8-bit data */ +/* ASCI Transmit Data Register Ch. 1 (TDR1: 0x07) - 8-bit data */ +/* ASCI Receive Data Register Ch. 0 (RDR0: 0x08) - 8-bit data */ +/* ASCI Receive Data Register Ch. 1 (RDR0: 0x09) - 8-bit data */ + +/* ASCI0 Extension Control Register (I/O Address: 0x12) (Z8S180/L180-Class Processors Only) */ +/* ASCI1 Extension Control Register (I/O Address: 0x13) (Z8S180/L180-Class Processors Only) */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define ASCI_ASEXT_RDRF (0x80) /* Bit 7: RDRF Interrupt Inhibit */ +# define ASCI0_ASEXT_DCD0 (0x80) /* Bit 6: DCD0 advisory to SW (ASCI0 only) */ +# define ASCI0_ASEXT_CTS0 (0x80) /* Bit 5: CTS0 advisory to SW (ASCI0 only) */ +# define ASCI_ASEXT_X1BC (0x80) /* Bit 4: CKA0 is bit clock */ +# define ASCI_ASEXT_BRG (0x80) /* Bit 3: Enable 16-bit BRG counter */ +# define ASCI_ASEXT_BRKEN (0x80) /* Bit 2: Break Feature Enable */ +# define ASCI_ASEXT_BRKDET (0x80) /* Bit 1: Break Detect */ +# define ASCI_ASEXT_SNDBRK (0x80) /* Bit 0: Send Break */ +#endif + +/* ASCI0 Time Constant Low Register (I/O Address: 0x1a) (Z8S180/L180-Class Processors Only) -- 8-bit data */ +/* ASCI0 Time Constant High Register (I/O Address: 0x1b) (Z8S180/L180-Class Processors Only) -- 8-bit data */ +/* ASCI1 Time Constant Low Register (I/O Address: 0x1c) (Z8S180/L180-Class Processors Only) -- 8-bit data */ +/* ASCI1 Time Constant High Register (I/O Address: 0x1d) (Z8S180/L180-Class Processors Only) -- 8-bit data */ + +/* CSI/O Registers ******************************************************************/ +/* CSI/O Control/Status Register (CNTR: 0x0a) */ + +#define CSIO_CNTR_EF (0x80) /* Bit 7: End Flag */ +#define CSIO_CNTR_EIE (0x40) /* Bit 6: End Interrupt Enable */ +#define CSIO_CNTR_RE (0x20) /* Bit 5: Receive Enable */ +#define CSIO_CNTR_TE (0x10) /* Bit 4: Transmit Enable */ +#define CSIO_CNTR_SS_SHIFT (0) /* Bits 0-2: Speed Select */ +#define CSIO_CNTR_SS_MASK (7 << CSIO_CNTR_SS_SHIFT) +# define CSIO_CNTR_DIV20 (0 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 20 Baud: 200000 */ +# define CSIO_CNTR_DIV40 (1 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 40 Baud: 100000 */ +# define CSIO_CNTR_DIV80 (2 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 80 Baud: 50000 */ +# define CSIO_CNTR_DIV160 (3 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 160 Baud: 25000 */ +# define CSIO_CNTR_DIV320 (4 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 320 Baud: 12500 */ +# define CSIO_CNTR_DIV640 (5 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 640 Baud: 6250 */ +# define CSIO_CNTR_DIV1280 (6 << CSIO_CNTR_SS_SHIFT) /* Divide Ratio: 1280 Baud: 3125 */ +# define CSIO_CNTR_EXT (7 << CSIO_CNTR_SS_SHIFT) /* External Clock input (less than 20) */ + /* Baud at Phi = 4 MHz */ +/* CSI/O Transmit/Receive Register (TRDR: 0x0b) -- 8-bit data */ + +/* Timer Registers ******************************************************************/ +/* Timer Data Register 0L (TMDR0L: 0x0c) -- 8-bit data */ +/* Timer Data Register 0H (TMDR0H: 0x0d) -- 8-bit data */ +/* Timer Reload Register Channel 0L (RLDR0L: 0x0e) -- 8-bit data */ +/* Timer Reload Register Channel 0H (RLDR0H: 0x0f) -- 8-bit data */ + +/* Programmable Reload Timer (PTR) Control Register (TCR: 0x10) */ + +#define PRT_TCR_TIF1 (0x80) /* Bit 7: Timer 1 Interrupt Flag */ +#define PRT_TCR_TIF0 (0x40) /* Bit 6: Timer 0 Interrupt Flag */ +#define PRT_TCR_TIE1 (0x20) /* Bit 5: Timer 1 Interrupt Enable */ +#define PRT_TCR_TIE0 (0x10) /* Bit 4: Timer 0 Interrupt Enable */ +#define PRT_TCR_TOC1 (0x08) /* Bit 3: Timer 1 Output Control */ +#define PRT_TCR_TOC0 (0x04) /* Bit 2: Timer 0 Output Control */ +#define PRT_TCR_TDE1 (0x02) /* Bit 1: Timer 1 Down Count Enable */ +#define PRT_TCR_TDE0 (0x01) /* Bit 0: Timer 0 Down Count Enable */ + +/* Timer Data Register 1L (TMDR1L: 0x14) -- 8-bit data */ +/* Timer Data Register 1H (TMDR1H: 0x15) -- 8-bit data */ +/* Timer Reload Register Channel 1L (RLDR1L: 0x16) -- 8-bit data */ +/* Timer Reload Register Channel 1H (RLDR1H: 0x17) -- 8-bit data */ +/* Free Running counter (FRC: 0x18) -- 8-bit data */ + +/* DMA Registers ********************************************************************/ +/* DMA Destination Address Register Channel 0 (DAR0 I/O Address 0x23 to 0x25) -- 8-bit data */ +/* DMA Byte Count Register Channel 0 (BCR0 I/O Address = 0x26 to 0x27) -- 8-bit data */ +/* DMA Memory Address Register Channel 1 (MAR1: I/O Address = 0x28 to 0x2a) -- 8-bit data */ +/* DMA I/O Address Register Channel 1 (IAR1: I/O Address = 0x2b to 0x2c) -- 8-bit data */ + +/* DMA I/O Address Register Ch. 1 (IAR1B: 0x2d) (Z8S180/L180-Class Processor Only) */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define IAR1B_ALTCH (0x80) /* Bit 7: Alternating Channels */ +# define IAR1B_CURRCH (0x40) /* Bit 6: Currently selected DMA channel */ +# define IAR1B_TOUT (0x08) /* Bit 3: TOUT/DREQ is TOUT Out */ +# define IAR1B_IO_SHIFT (0) /* Bits 0-2: I/O selection*/ +# define IAR1B_IO_MASK (3 << IAR1B_IO_SHIFT) +# define IAR1B_IO_TOUT (0 << IAR1B_IO_SHIFT) /* DMA1 ext TOUT */ +# define IAR1B_IO_DREQ (0 << IAR1B_IO_SHIFT) /* DMA1 ext DREQ */ +# define IAR1B_IO_ASCI0 (1 << IAR1B_IO_SHIFT) /* DMA1 ASCI0 */ +# define IAR1B_IO_ASCI1 (2 << IAR1B_IO_SHIFT) /* DMA1 ASCI1 */ +# define IAR1B_IO_ESCC (3 << IAR1B_IO_SHIFT) /* DMA1 ESCC */ +# define IAR1B_IO_PIA (7 << IAR1B_IO_SHIFT) /* DMA1 PIA27-20 (P1284) */ +#endif + +/* DMA Byte Count Register Channel 1 (BCR1: I/O Address = 0x2e to 0x2f) -- 8-bit data */ + +/* DMA Status Register (DSTAT: 0x30) */ + +#define DSTAT_DE1 (0x80) /* Bit 7: Enable Channel 1 */ +#define DSTAT_DE0 (0x40) /* Bit 6: Enable Channel 0 */ +#define DSTAT_DWE1 (0x20) /* Bit 5: Bit Write Enable 1 */ +#define DSTAT_DWE0 (0x10) /* Bit 4: Bit Write Enable 0 */ +#define DSTAT_DIE1 (0x08) /* Bit 3: DMA Interrupt Enable Channel 1 */ +#define DSTAT_DIE0 (0x04) /* Bit 2: DMA Interrupt Enable Channel 0 */ +#define DSTAT_DME (0x01) /* Bit 0: DMA Main Enable */ + +/* DMA Mode Register (DMODE: 0x31) */ + +#define DMODE_DM_SHIFT (4) /* Bits 4-5: Destination Mode Channel 0 */ +#define DMODE_DM_MASK (3 << DMODE_DM_SHIFT) +# define DMODE_DM_MEMINCR (0 << DMODE_DM_SHIFT) /* Memory with address increment */ +# define DMODE_DM_MEMDECR (1 << DMODE_DM_SHIFT) /* Memory with address decrement */ +# define DMODE_DM_MEM (2 << DMODE_DM_SHIFT) /* Memory with fixed address */ +# define DMODE_DM_IO (3 << DMODE_DM_SHIFT) /* I/O */ +#define DMODE_SM_SHIFT (2) /* Bits 2-3: Source Mode Channel */ +#define DMODE_SM_MASK (3 << DMODE_SM_SHIFT) +# define DMODE_SM_MEMINCR (0 << DMODE_SM_SHIFT) /* Memory with address increment */ +# define DMODE_SM_MEMDECR (1 << DMODE_SM_SHIFT) /* Memory with address decrement */ +# define DMODE_SM_MEM (2 << DMODE_SM_SHIFT) /* Memory with fixed address */ +# define DMODE_SM_IO (3 << DMODE_SM_SHIFT) /* I/O */ +#define DMODE_MMODE (0x01) /* Bit 0: DMA Memory Mode Channel 0 */ + +/* DMA/WAIT Control Register (DCNTL: 0x32) */ + +#define DCNTL_MWI_SHIFT (6) /* Bits 6-7: Memory Wait Insertion */ +#define DCNTL_MWI_MASK (3 << DCNTL_MWI_SHIFT) +#define DCNTL_IWI_SHIFT (4) /* Bits 4-5: Wait Insertion */ +#define DCNTL_IWI_MASK (3 << DCNTL_IWI_SHIFT) +#define DCNTL_DMS_SHIFT (4) /* Bits 2-3: DMA Request Sense */ +#define DCNTL_DMS_MASK (3 << DCNTL_DMS_SHIFT) +# define DCNTL_DMS_DREQ0 (1 << DCNTL_DMS_SHIFT) +# define DCNTL_DMS_DREQ1 (2 << DCNTL_DMS_SHIFT) +#define DCNTL_DIM_SHIFT (0) /* Bits 0-1: DMA Channel 1 I/O and Memory Mode */ +#define DCNTL_DIM_MASK (3 << DCNTL_DIM_SHIFT) +# define DCNTL_DIM_M2IOI (0 << DCNTL_DIM_SHIFT) /* Memory to I/O, increment MARI */ +# define DCNTL_DIM_M2IOD (1 << DCNTL_DIM_SHIFT) /* Memory to I/O, decrement MARI */ +# define DCNTL_DIM_IO2MI (2 << DCNTL_DIM_SHIFT) /* I/O to memory, increment MARI */ +# define DCNTL_DIM_IO2MD (3 << DCNTL_DIM_SHIFT) /* I/O to memory, decrement MARI */ + +/* System Control Registers *********************************************************/ +/* Clock Multiplier Register (CMR: 0x1e) (Z8S180/L180-Class Processors Only) */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define CMR_CMM (0x80) /* Bit 7: X2 Clock Multiplier Mode */ +#endif + +/* CPU Control Register (CCR: 0x1f) (Z8S180/L180-Class Processors Only) */ + +#ifdef HAVE_Z8S180 /* Z8S180/Z8L180 class processors */ +# define CCR_XTAL_DIV (0x80) /* Bit 7: Clock Divide */ +# define CCR_STBYIDLE (0x48) /* Bits 3 & 6: STANDBY/IDLE mode */ +# define CCR_NOSTDBY (0x00) /* No STANDBY */ +# define CCR_IDLE (0x08) /* IDLE after SLEEP */ +# define CCR_STBY (0x40) /* STANDBY after SLEEP */ +# define CCR_STBY64 (0x48) /* STANDBY after SLEEP 64 Cycle Exit */ +# define CCR_BREXT (0x20) /* Bit 5: STANDBY/IDLE exit on BUSREQ */ +# define CCR_LNPHI (0x10) /* Bit 4: 33% Drive on EXTPHI Clock */ +# define CCR_LNIO (0x04) /* Bit 2: 33% Drive on certain external I/O */ +# define CCR_LNCPUCTLR (0x02) /* Bit 1: 33% Drive on CPU control signals */ +# define LNADDATA (0x01) /* Bit 0: 33% drive on A10-A0, D7-D0 */ +#endif + +/* Interrupt Vector Low Register (IL: 0x33) */ + +#define IL_SHIFT (5) /* Bits 5-7: 3-bits of vector interrupt table address */ +#define IL_MASK (7 << IL_SHIFT) + +/* INT/TRAP Control Register (ITC: 0x34) */ + +#define ITC_TRAP (0x80) /* Bit 7: Undefined opcode fetch */ +#define ITC_UFO (0x40) /* Bit 6: Undefined fetch object */ +#define ITC_ITE_SHIFT (0) /* Bits 0-2: Interrupt enable bits */ +#define ITC_ITE_MASK (7 << ITC_ITE_SHIFT) +# define ITC_ITE0 (1 << ITC_ITE_SHIFT) +# define ITC_ITE1 (2 << ITC_ITE_SHIFT) +# define ITC_ITE2 (4 << ITC_ITE_SHIFT) + +/* Refresh Control Register (RCR: 0x36) */ + +#define RCR_REFE (0x80) /* Bit 7: Refresh Enable */ +#define RCR_REFW (0x40) /* Bit 6: Refresh Wait */ +#define RCR_CYC_SHIFT (0) /* Bits 0-1: Cycle Interval */ +#define RCR_CYC_MASK (3 << RCR_CYC_SHIFT) +# define RCR_CYC0 (1 << RCR_CYC_SHIFT) +# define RCR_CYC1 (2 << RCR_CYC_SHIFT) + +/* MMU Common Base Register (CBR: 0x38) - 8-bit base address of Common Area 1 */ +/* MMU Bank Base Register (BBR: 0x39) - 8-bit address of Bank area */ + +/* MMU Common/Bank Area Register (CBAR: 0x3a) */ + +#define CBAR_CA_SHIFT (4) /* Bits 4-7: Low address for Common Area 1 */ +#define CBAR_CA_MASK (15 << CBAR_CA_SHIFT) +#define CBAR_BA_SHIFT (0) /* Bits 0-3: Low address for Bank Area */ +#define CBAR_BA_MASK (15 << CBAR_BA_SHIFT) + +/* Operation Mode Control Register (OMCR: 0x3e) */ + +#define OMCR_M1E (0x80) /* Bit 7: M1 Enable */ +#define OMCR_M1TE (0x40) /* Bit 6: M1 Temporary Enable */ +#define OMCR_IOC (0x20) /* Bit 5: Controls the timing of the IORQ and RD signals */ + +/* I/O Control Register (ICR: 0x3f) */ + +#define ICR_IOA_SHIFT (6) /* Bits 6-7: Internal I/O address bits */ +#define ICR_IOA_MASK (3 << ICR_IOA_SHIFT) +# define ICR_IOA6 (1 << ICR_IOA_SHIFT) +# define ICR_IOA7 (2 << ICR_IOA_SHIFT) +#define ICR_IOSTP (0x20) /* Bit 5: Enable I/O stop mode */ + +/* Registers unique to Z8x181 class CPUs ********************************************/ + +#ifdef HAVE_Z8X181 +/* PIA Registers */ +/* PIAn Data Direction and Data Registers */ + +# define PIA(n) (1 << (n)) + +/* CTC Registers */ +/* CTC Channel Control/Vector Registers */ +/* Control Bit Definitions */ + +# define CTC_IE (0x80) /* Bit 7: Interrupt Enable */ +# define CTC_MODE (0x40) /* Bit 6: Mode bit */ +# define CTC_PF (0x20) /* Bit 5: Pre-scaler factor */ +# define CTC_CTES (0x10) /* Bit 4: Clock/Trigger Edge Selector */ +# define CTC_TT (0x08) /* Bit 3: Timer Trigger */ +# define CTC_TC (0x04) /* Bit 2: Time Constant */ +# define CTC_SR (0x02) /* Bit 1: Software Reset */ + +/* Vector Bit Definitions */ + +# define CTC_CHAN_SHIFT (1) /* Bits 1-2: Channel Identifier */ +# define CTC_CHAN_MASK (3 << CTC_CHAN_SHIFT) +# define CTC_VECT_SHIFT (3) /* Bits 3-7: Vector word */ +# define CTC_VECT_MASK (31 << CTC_VECT_SHIFT) + +# define CTC_CNTRL (0x01) /* Bit 0: 0=Vector 1=Control */ + +/* SCC Registers -- See interface description below */ + +/* System Control Registers */ +/* RAM Upper Boundary Address Register -- 8-bit address (A12-A19) */ +/* RAM Lower Boundary Address Register -- 8-bit address (A12-A19) */ +/* ROM Address Boundary Register -- 8-bit address (A12-A19) */ + +/* System Configuration Register */ + +#define SCR_DCCONFIG (0x40) /* Bit 6: Daisy Chain Configuration */ +#define SCR_ROMCSDIS (0x20) /* Bit 5: Disable /ROMCS */ +#define SCR_REME (0x04) /* Bit 2: ROM Emulator Mode */ +#define SCR_PIA1_CTIO (0x01) /* Bit 0: PIA1 Functions as I/O port or CTC's I/O Pins */ + +#endif + +/* Registers unique to Z8x182 class CPUs ********************************************/ + +#ifdef HAVE_Z8X182 +/* PIA Registers */ +/* Pn Data Direction and Data Register */ + +# define PIA(n) (1 << (n)) + +/* ESCC Registers -- See interface description below */ + +/* System Control Registers */ + +# define SCR_PCSEL (0x80) /* Bit 7: Port C Select */ +# define SCR_PB57SEL (0x40) /* Bit 6: Port PB7-PB5 Selec */ +# define SCR_PB04SEL (0x20) /* Bit 5: Port PB4-PB0 Select */ +# define SCR_DOUT (0x10) /* Bit 4: Data Out */ +# define SCR_ROMDIS (0x08) /* Bit 3: Disable ROMs */ +# define SCR_TRIMUX (0x04) /* Bit 2: Tri-Muxed Pins */ +# define SCR_MIMIC (0x02) /* Bit 1: ESCC/MIMIC */ +# define SCR_DC (0x01) /* Bit 0: Daisy Chain */ + +/* 16550 MIMIC Registers */ +/* To be provided */ + +#endif + +/* [E]SCC Internal Register Definitions *********************************************/ +/* Read Registers */ + +/* RR0: Transmit and Receive buffer status and external status */ + +#define RR0_BA (0x80) /* Bit 7: Break/abort */ +#define RR0_TXUEOM (0x40) /* Bit 6: Tx Underrun/EOM */ +#define RR0_CTS (0x20) /* Bit 5: CTS */ +#define RR0_SH (0x10) /* Bit 4: Sync/Hunt */ +#define RR0_DCD (0x08) /* Bit 3: DCD */ +#define RR0_TXBE (0x04) /* Bit 2: Tx Buffer Empty */ +#define RR0_ZC (0x02) /* Bit 1: Zero Count */ +#define RR0_RXA (0x01) /* Bit 0: Rx Character Available */ + +/* RR1: Special Receive Condition status */ + +#define RR0_EOF (0x80) /* Bit 7: End of Frame (SDLC)*/ +#define RR0_CRCFE (0x40) /* Bit 6: CRC/Framing Error */ +#define RR0_RXOE (0x20) /* Bit 5: Rx Overrun Error */ +#define RR0_PE (0x10) /* Bit 4: Parity Error */ +#define RR0_RES0 (0x08) /* Bit 3: Residue Code 0 */ +#define RR0_RES1 (0x04) /* Bit 2: Residue Code 1 */ +#define RR0_RES2 (0x02) /* Bit 1: Residue Code 2 */ +#define RR0_ALL (0x01) /* Bit 0: All Sent */ + +/* RR2: Interrupt vector (modified if VIS Bit in WR9 is set) -- 8-bit vector value */ + +/* RR3: Interrupt pending bits */ + +#define RR3_RX (0x20) /* Bit 5: Rx IP */ +#define RR3_TX (0x10) /* Bit 4: Tx IP */ +#define RR3_EXT (0x08) /* Bit 3: Ext/Status IP */ + +/* RR6: SDLC FIFO byte counter lower byte (only when enabled) -- 8-bit counter value */ +/* RR7: SDLC FIFO byte count and status (only when enabled) */ + +#define RR7_BC_SHIFT (0) /* Bits 0-5 : Upper 6-bits of counter */ +#define RR7_BC_MASK (0x3f << RR7_BC_SHIFT) +#define RR7_FDA (0x40) /* Bit 6: FIFO Available Status */ +#define RR7_FOS (0x80) /* Bit 7: FIFO Overflow Status */ + +/* RR8: Receive buffer */ +/* RR10: Miscellaneous status bits */ + +#define RR10_1MISS (0x80) /* Bit 7: One Clock Missing */ +#define RR10_2MISS (0x40) /* Bit 6: Two Clocks Mising */ +#define RR10_SEND (0x10) /* Bit 4: Loop Sending */ +#define RR10_ON (0x02) /* Bit 1: On Loop */ + +/* RR12: Lower byte of baud rate generator time constant -- 8-bit time constant value */ +/* RR13: Upper byte of baud rate generator time constant -- 8-bit time constant value */ + +/* RR15: External Status interrupt information */ + +#define RR15_BAIE (0x80) /* Bit 7: Break/Abort IE */ +#define RR15_TXUEOMIE (0x40) /* Bit 6: Tx Underrun/EOM IE */ +#define RR15_CTSIE (0x20) /* Bit 5: CTS IE */ +#define RR15_SHIE (0x10) /* Bit 4: Sync/Hunt IE */ +#define RR15_DCDIE (0x08) /* Bit 3: DCD IE */ +#ifdef HAVE_Z8X182 /* ESCC only */ +# define RR15_SDLCIE (0x04) /* Bit 2: SDLC Status FIFO Enable */ +#endif +#define RR15_ZCIE (0x02) /* Bit 1: Zero Count IE */ + +/* Write Registers */ + +/* WR0: Register Pointers, various initialization commands */ + +#define WR0_CMD1_SHIFT (6) /* Bits 6-7: Command */ +#define WR0_CMD1_MASK (3 << WR0_CMD1_SHIFT); +# define WR0_CMD1_NULL (0 << WR0_CMD1_SHIFT); /* Null Code */ +# define WR0_CMD1_RXCRCRST (1 << WR0_CMD1_SHIFT); /* Reset Rx CRC Checker */ +# define WR0_CMD1_TXCRCRST (2 << WR0_CMD1_SHIFT); /* Reset Tx CRC Generator */ +# define WR0_CMD1_TXURRST (3 << WR0_CMD1_SHIFT); /* Reset Tx Underrun/EOM Latch */ +#define WR0_CMD2_SHIFT (3) /* Bits 3-5: Command */ +#define WR0_CMD2_MASK (3 << WR0_CMD2_SHIFT); +# define WR0_CMD2_NULL (0 << WR0_CMD2_SHIFT); /* Null Code */ +# define WR0_CMD2_HP (1 << WR0_CMD2_SHIFT); /* Point High */ +# define WR0_CMD2_EXTRST (2 << WR0_CMD2_SHIFT); /* Reset Ext/Status Interrupts */ +# define WR0_CMD2_ABORT (3 << WR0_CMD2_SHIFT); /* Send Abort (SDLC) */ +# define WR0_CMD2_ENRX (4 << WR0_CMD2_SHIFT); /* Enable Int on Next Rx Character */ +# define WR0_CMD2_TXPRST (5 << WR0_CMD2_SHIFT); /* Reset Tx Int Pending */ +# define WR0_CMD2_ERRRST (6 << WR0_CMD2_SHIFT); /* Error Reset */ +# define WR0_CMD2_IUSRST (7 << WR0_CMD2_SHIFT); /* Reset Highest IUS */ +#define WR0_REG_SHIFT (0) /* Bits 0-2 : Register address */ +#define WR0_REG_MASK (7 << WR0_REG_SHIFT); + +/* WR1: Transmit and Receive interrupt enables, WAIT/DMA commands */ + +#define WR1_WDMAEN (0x80) /* Bit 7: WAIT/DMA Request Enable */ +#define WR1_WDMAFN (0x40) /* Bit : /WAIT/DMA Request Function */ +#define WR1_WDMAXFR (0x20) /* Bit : WAIT/DMA Request On Receive//Transmit */ +#define WR1_CMD_SHIFT (3) /* Bits 3-4: Command */ +#define WR1_CMD_MASK (3 << WR1_CMD_SHIFT) +# define WR1_CMD_RXDIS (0 << WR1_CMD_SHIFT) /* Rx Int Disable */ +# define WR1_CMD_RXINT1ST (1 << WR1_CMD_SHIFT) /* Rx Int On First Character or Special Condition */ +# define WR1_CMD_RXINTALL (2 << WR1_CMD_SHIFT) /* Int On All Rx Characters or Special Condition */ +# define WR1_CMD_RXINTSPEC (3 << WR1_CMD_SHIFT) /* Rx Int On Special Condition Only */ +#define WR1_PSPEC (0x04) /* Bit 2: Parity is Special Condition */ +#define WR1_TXIE (0x02) /* Bit 1: Tx Int Enable */ +#define WR1_EXTIE (0x01) /* Bit 0: Ext Int Enable */ + +/* WR2: Interrupt Vector -- 8-bit interrupt vector */ + +/* WR3: Receive parameters and control modes */ + +#define WR3_BPC_SHIFT (6) /* Bit 6-7: Bits/character */ +#define WR3_BPC_MASK (3 << WR3_BPC_SHIFT) +# define WR3_BPC_5 (0 << WR3_BPC_SHIFT) /* Rx 5 Bits/Character */ +# define WR3_BPC_7 (1 << WR3_BPC_SHIFT) /* Rx 7 Bits/Character */ +# define WR3_BPC_6 (2 << WR3_BPC_SHIFT) /* Rx 6 Bits/Character */ +# define WR3_BPC_8 (3 << WR3_BPC_SHIFT) /* Rx 8 Bits/Character */ +#define WR3_AE (0x20) /* Bit 5: Auto Enables */ +#define WR3_EHM (0x10) /* Bit 4: Enter Hunt Mode */ +#define WR3_RXCRCEN (0x08) /* Bit 3: Rx CRC Enable */ +#define WR3_ASM (0x04) /* Bit 2: Address Search Mode (SDLC) */ +#define WR3_SCLI (0x02) /* Bit 1: Sync Character Load Inhibit */ +#define WR3_RXEN (0x01) /* Bit 0: Rx Enable */ + +/* WR4: Transmit and Receive modes and parameters */ + +#define WR4_CM_SHIFT (6) /* Bits 6-7: X1 Clock Mode */ +#define WR4_CM_MASK (3 << WR4_CM_SHIFT) +# define WR4_CM_X1 (0 << WR4_CM_SHIFT) /* X1 Clock Mode */ +# define WR4_CM_X16 (1 << WR4_CM_SHIFT) /* X16 Clock Mode */ +# define WR4_CM_X32 (2 << WR4_CM_SHIFT) /* X32 Clock Mode */ +# define WR4_CM_X64 (3 << WR4_CM_SHIFT) /* X64 Clock Mode */ +#define WR4_SM_SHIFT (4) /* Bits 4-5: Sync mode */ +#define WR4_SM_MASK (3 << WR4_SM_SHIFT) +# define WR4_SM_8BIT (0 << WR4_SM_SHIFT) /* 8-Bit Sync Character */ +# define WR4_SM_16BIT (1 << WR4_SM_SHIFT) /* 16-Bit Sync Character */ +# define WR4_SM_SDLC (2 << WR4_SM_SHIFT) /* SDLC Mode (01111110 Flag) */ +# define WR4_SM_EXT (3 << WR4_SM_SHIFT) /* External Sync Mode */ +#define WR4_SB_SHIFT (2) /* Bits 2-3: Sync mode enables */ +#define WR4_SB_MASK (3 << WR4_SB_SHIFT) +# define WR4_SB_SME (0 << WR4_SB_SHIFT) /* Sync Modes Enable */ +# define WR4_SB_STOP1 (1 << WR4_SB_SHIFT) /* 1 Stop Bit/Character */ +# define WR4_SB_STOP1p5 (2 << WR4_SB_SHIFT) /* 1 1/2 Stop Bits/Character */ +# define WR4_SB_STOP2 (3 << WR4_SB_SHIFT) /* 2 Stop Bits/Character */ +#define WR4_PEO (0x02) /* Bit 1: Parity EVEN//ODD */ +#define WR4_PEN (0x01) /* Bit : Parity Enable */ + +/* WR5: Transmit parameters and control modes */ + +#define WR5_DTR (0x80) /* Bit 7: DTR */ +#define WR5_TXBITS_SHIFT (5) /* Bits 5-6: Number of Tx bits */ +#define WR5_TXBITS_MASK (3 << WR5_TXBITS_SHIFT) +# define WR5_TXBITS_5 (0 << WR5_TXBITS_SHIFT) /* Tx 5 Bits(Or Less)/Character */ +# define WR5_TXBITS_7 (1 << WR5_TXBITS_SHIFT) /* Tx 7 Bits/Character */ +# define WR5_TXBITS_6 (2 << WR5_TXBITS_SHIFT) /* Tx 6 Bits/Character */ +# define WR5_TXBITS_8 (3 << WR5_TXBITS_SHIFT) /* Tx 8 Bits/Character */ +#define WR5_SENDBRK (0x10) /* Bit 4: Send Break */ +#define WR5_TXEN (0x08) /* Bit 3: Tx Enable */ +#define WR5_CRC16 (0x04) /* Bit 2: /SDLC/CRC-16 */ +#define WR5_RTS (0x02) /* Bit 1: RTS */ +#define WR5_TXCRCEN (0x01) /* Bit 0: Tx CRC Enable */ + +/* WR6: Sync Character or SDLC address -- 8-bit Monosync, Bisync, or SDLC value */ +/* WR7: Sync Character or SDLC flag -- 8-bit Monosync, Bisync, or SDLC value */ + +#define WR7_SDLC_SYNC (0x7e) + +#ifdef HAVE_Z8X182 /* ESCC only */ +# define WR7P_CRC32EN (0x80) /* Bit 7: 32-bit CRC Enable */ +# define WR7P_EXTRDEN (0x40) /* Bit 6: Extended Read Enable */ +# define WR7P_TXFLVL (0x20) /* Bit 5: Tx FIFO Int Level */ +# define WR7P_TMODE (0x10) /* Bit 4: DTR/REQ Timing Mode */ +# define WR7P_RXFLVL (0x08) /* Bit 3: Rx FIFO Int Level */ +# define WR7P_AUTORTS (0x04) /* Bit 2: Auto RTS Deactivation */ +# define WR7P_AUTOEOM (0x02) /* Bit 1: Auto EOM Reset */ +# define WR7P_AUTOTX (0x01) /* Bit 0: Auto Tx Flag */ +#endif + +/* WR8: Transmit buffer */ + +/* WR9: Master Interrupt control and reset commands */ + +#define WR9_RST_SHIFT (6) /* Bits 6-7: Resets */ +#define WR9_RST_MASK (3 << WR9_RST_SHIFT) +# define WR9_RST_NONE (0 << WR9_RST_SHIFT) /* No Reset */ +# define WR9_RST_CHAN (2 << WR9_RST_SHIFT) /* Channel Reset */ +# define WR9_RST_HWRST (3 << WR9_RST_SHIFT) /* Force Hardware Reset */ +#ifdef HAVE_Z8X182 /* ESCC only */ +# define WR9_INTACKEN (0x20) /* Bit 5: Software INTACK Enable */ +#endif +#define WR9_SHL (0x10) /* Bit 4: Status High//Status Low */ +#define WR9_MIE (0x08) /* Bit 3: MIE */ +#define WR9_DLC (0x04) /* Bit 2: DLC */ +#define WR9_NV (0x02) /* Bit 1: NV */ +#define WR9_VIS (0x01) /* Bit 0: VIS */ + +/* WR10: Miscellaneous transmit and receive control bits */ + +#define WR10_CRCPRE (0x80) /* Bit 7: CRC Preset I/O */ +#define WR10_NRZFM_SHIFT (5) /* Bits 5-6: NRZ/FM */ +#define WR10_NRZFM_MASK (3 << WR10_NRZFM_SHIFT) +# define WR10_NRZ (0 << WR10_NRZFM_SHIFT) /* NRZ */ +# define WR10_NRZI (1 << WR10_NRZFM_SHIFT) /* NRZI */ +# define WR10_FM1 (2 << WR10_NRZFM_SHIFT) /* FM1 (Transition = 1) */ +# define WR10_FM0 (3 << WR10_NRZFM_SHIFT) /* FM0 (Transition = 0) */ +#define WR10_ACTPOLL (0x10) /* Bit 4: Go Active On Poll */ +#define WR10_IDLE (0x08) /* Bit 3: Mark/Flag Idle */ +#define WR10_URABORT (0x04) /* Bit 2: Abort/Flag On Underrun */ +#define WR10_LOOP (0x02) /* Bit 1: Loop Mode */ +#define WR10_68SYNC (0x01) /* Bit 0: 6-Bit//8-Bit Sync */ + +/* WR11: Clock mode controls for receive and transmit */ + +#define WR11_XTAL (0x80) /* Bit 7: /RTxC Xtal//No Xtal */ +#define WR11_RCLK_SHIFT (5) /* Bits 5-6: Receive Clock */ +#define WR11_RCLK_MASK (3 << WR11_RCLK_SHIFT) +# define WR11_RCLK_RTXC (0 << WR11_RCLK_SHIFT) /* Receive Clock = /RTxC Pin */ +# define WR11_RCLK_TRXC (1 << WR11_RCLK_SHIFT) /* Receive Clock = /TRxC Pin */ +# define WR11_RCLK_BRG (2 << WR11_RCLK_SHIFT) /* Receive Clock = BR Generator Output */ +# define WR11_RCLK_DPLL (3 << WR11_RCLK_SHIFT) /* Receive Clock = DPLL Output */ +#define WR11_TCLK_SHIFT (3) /* Bits 3-4: Transmit Clock */ +#define WR11_TCLK_MASK (3 << WR11_TCLK_SHIFT) +# define WR11_TCLK_RTXC (0 << WR11_TCLK_SHIFT) /* Transmit Clock = /RTxC Pin */ +# define WR11_TCLK_TRXC (1 << WR11_TCLK_SHIFT) /* Transmit Clock = /TRxC Pin */ +# define WR11_TCLK_BRG (2 << WR11_TCLK_SHIFT) /* Transmit Clock = BR Generator Output */ +# define WR11_TCLK_DPLL (3 << WR11_TCLK_SHIFT) /* Transmit Clock = DPLL Output */ +#define WR11_TRXCIO (0x04) /* Bit 2: /TRxC O/I */ +#define WR11_TRXCO_SHIFT (0) /* Bits 0-1 : /TRxC Out */ +#define WR11_TRXO_MASK (3 << WR11_TRXCO_SHIFT) +# define WR11_TRXO_XTAL (0 << WR11_TRXCO_SHIFT) /* /TRxC Out = Xtal Output */ +# define WR11_TRXO_TCLK (1 << WR11_TRXCO_SHIFT) /* /TRxC Out = Transmit Clock */ +# define WR11_TRXO_BRG (2 << WR11_TRXCO_SHIFT) /* /TRxC Out = BR Generator Output */ +# define WR11_TRXO_DPLL (3 << WR11_TRXCO_SHIFT) /* /TRxC Out = DPLL Output */ + +/* WR12: Lower byte of baud rate generator -- 8-bit time constant value */ +/* WR13: Upper byte of baud rate generator -- 8-bit time constant value */ + +/* WR14: Miscellaneous control bits */ + +#define WR14_CMD_SHIFT (5) /* Bits 5-7: Command */ +#define WR14_CMD_MASK (7 << WR14_CMD_SHIFT) +# define WR14_CMD_NULL (0 << WR14_CMD_SHIFT) /* Null Command */ +# define WR14_CMD_ESM (1 << WR14_CMD_SHIFT) /* Enter Search Mode */ +# define WR14_CMD_RMCLK (2 << WR14_CMD_SHIFT) /* Reset Missing Clock */ +# define WR14_CMD_DPLLDIS (3 << WR14_CMD_SHIFT) /* Disable DPLL */ +# define WR14_CMD_SRCBRG (4 << WR14_CMD_SHIFT) /* Set Source = BR Generator */ +# define WR14_CMD_SRCRTXC (5 << WR14_CMD_SHIFT) /* Set Source = /RTxC */ +# define WR14_CMD_FM (6 << WR14_CMD_SHIFT) /* Set FM Mode */ +# define WR14_CMD_NRZI (7 << WR14_CMD_SHIFT) /* Set NRZI Mode */ +#define WR14_LPBK (0x10) /* Bit 4: Local Loopback */ +#define WR14_AUTOECHO (0x08) /* Bit 3: Auto Echo */ +#define WR14_DTRREQ (0x04) /* Bit 2: /DTR/Request Function */ +#define WR14_BRGSRC (0x02) /* Bit 1: BR Generator Source */ +#define WR14_BRGEN (0x01) /* Bit 0: BR Generator Enable */ + +/* WR15: External status interrupt enable control */ + +#define WR15_BAIE (0x80) /* Bit 7: Break/Abort IE */ +#define WR15_TXUEOMIE (0x40) /* Bit 6: Tx Underrun/EOM IE */ +#define WR15_CTSIS (0x20) /* Bit 5: CTS IE */ +#define WR15_SHIE (0x10) /* Bit 4: Sync/Hunt IE */ +#define WR15_DCDIE (0x08) /* Bit 3: DCD IE */ +#define WR15_FIFOEN (0x04) /* Bit 2: SDLC FIFO Enable */ +#define WR15_ZCIE (0x02) /* Bit 1: Zero Count IE */ +#ifdef HAVE_Z8X182 /* ESCC only */ +# define WR15_WR7PEN (0x01) /* Bit 0: WR7' SDLC Feature Enable */ +#endif + +#endif /* __ARCH_Z80_SRC_Z180_Z180_IOMAP_H */ diff --git a/arch/z80/src/z180/z180_irq.c b/arch/z80/src/z180/z180_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..cb6b362c9eabe98fb78bd99a8b4a772e7e5f35bc --- /dev/null +++ b/arch/z80/src/z180/z180_irq.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_irq.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "switch.h" +#include "z180_iomap.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +volatile chipreg_t *g_current_regs; + +/* This holds the value of the MMU's CBR register. This value is set to the + * interrupted tasks's CBR on interrupt entry, changed to the new task's CBR if + * an interrupt level context switch occurs, and restored on interrupt exit. In + * this way, the CBR is always correct on interrupt exit. + */ + +uint8_t current_cbr; + +/* The interrupt vector table is exported by z180_vectors.asm or + * z180_romvectors.asm with the name up_vectors: + */ + +extern uintptr_t up_vectors[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_seti + * + * Description: + * Input byte from port p + * + ****************************************************************************/ + +static void z180_seti(uint8_t value) __naked +{ + __asm + ld a, 4(ix) ; value + ld l, a + __endasm; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Disable all interrupts; return previous interrupt state + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) __naked +{ + __asm + ld a, i ; AF Parity bit holds interrupt state + di ; Interrupts are disabled + push af ; Return AF in HL + pop hl ; + ret ; + __endasm; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore previous interrupt state + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t flags) __naked +{ + __asm + di ; Assume disabled + pop hl ; HL = return address + pop af ; AF Parity bit holds interrupt state + jp po, statedisable + ei +statedisable: + push af ; Restore stack + push hl ; + ret ; and return + __endasm; +} + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Initialize and enable interrupts + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint16_t vectaddr = (uint16_t)up_vectors; + uint8_t regval; + + /* Initialize the I and IL registers so that the interrupt vector table + * is used. + */ + + regval = (uint8_t)(vectaddr >> 8); + z180_seti(regval); + + regval = (uint8_t)(vectaddr & IL_MASK); + outp(Z180_INT_IL, regval); + + /* Disable external interrupts */ + + outp(Z180_INT_ITC, 0); + + /* And finally, enable interrupts (including the timer) */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_restore(Z180_C_FLAG); +#endif +} diff --git a/arch/z80/src/z180/z180_lowscc.c b/arch/z80/src/z180/z180_lowscc.c new file mode 100644 index 0000000000000000000000000000000000000000..59caa4c561f46c8f58175573ff48046039fd08f9 --- /dev/null +++ b/arch/z80/src/z180/z180_lowscc.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_lowscc.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/chip.h" +#include "common/up_internal.h" +#include "z180_config.h" + +#if defined(USE_LOWSERIALINIT) && defined(HAVE_SCC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_Z180_SCC_SERIAL_CONSOLE) +# define CONSOLE_CR Z181_SCC_CR +# define CONSOLE_DR Z181_SCC_DR +# define CONSOLE_BAUD CONFIG_Z180_SCC_BAUD +# define CONSOLE_BITS CONFIG_Z180_SCC_BITS +# define CONSOLE_2STOP CONFIG_Z180_SCC_2STOP +# define CONSOLE_PARITY CONFIG_Z180_SCC_PARITY + +#elif defined(CONFIG_Z180_ESCCA_SERIAL_CONSOLE) +# define CONSOLE_CR Z182_ESCCA_CR +# define CONSOLE_DR Z182_ESCCA_DR +# define CONSOLE_BAUD CONFIG_Z180_ESCCA_BAUD +# define CONSOLE_BITS CONFIG_Z180_ESCCA_BITS +# define CONSOLE_2STOP CONFIG_Z180_ESCCA_2STOP +# define CONSOLE_PARITY CONFIG_Z180_ESCCA_PARITY + +#elif defined(CONFIG_Z180_ESCCB_SERIAL_CONSOLE) +# define CONSOLE_CR Z182_ESCCB_CR +# define CONSOLE_DR Z182_ESCCB_DR +# define CONSOLE_BAUD CONFIG_Z180_ESCCB_BAUD +# define CONSOLE_BITS CONFIG_Z180_ESCCB_BITS +# define CONSOLE_PARITY CONFIG_Z180_ESCCB_PARITY +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_scc_lowinit + * + * Description: + * Called early in the boot sequence to initialize the [E]SCC console + * channel (only). + * + ****************************************************************************/ + +#ifdef USE_LOWSERIALINIT +void z180_scc_lowinit(void) +{ +#ifdef HAVE_SCC_CONSOLE +#warning "Missing logic" +#endif +} +#endif + +/**************************************************************************** + * Name: z180_putc + * + * Description: + * Low-level character output + * + ****************************************************************************/ + +#ifdef HAVE_SCC_CONSOLE +void z180_putc(uint8_t ch) __naked +{ + __asm +txbe: + in0 a,(CONSOLE_CR) ; Read RR0 + bit 2, a ; Bit 2, Tx buffer empty? + jr z, txbe ; No, wait until the Tx buffer is empty + + ld a, 4(ix) ; Character to output + out (CONSOLE_DR), a ; Send it + ret + __endasm; +} +#endif + +#endif /* USE_LOWSERIALINIT && HAVE_SCC*/ diff --git a/arch/z80/src/z180/z180_lowserial.c b/arch/z80/src/z180/z180_lowserial.c new file mode 100644 index 0000000000000000000000000000000000000000..6464d8e74a22969e941150bae6798f8c6d91786c --- /dev/null +++ b/arch/z80/src/z180/z180_lowserial.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_lowserial.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "common/up_internal.h" + +#include "z180_config.h" +#include "z180_serial.h" + +#ifdef HAVE_SERIAL + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowserialinit + * + * Description: + * Called early in the boot sequence to initialize the serial ports + * + ****************************************************************************/ + +#ifdef USE_LOWSERIALINIT +void up_lowserialinit(void) +{ + /* Initialize UART and [E]SCC serial devices */ + + z180_uart_lowinit(); + z180_scc_lowinit(); +} +#endif + +/**************************************************************************** + * Name: up_putc/up_lowputc + * + * Description: + * Low-level console output + * + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER +int up_lowputc(int ch) +#else +int up_putc(int ch) +#endif +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Output CR before LF */ + + z180_putc('\r'); + } + + /* Output the character */ + + z180_putc(ch); + return ch; +} + +#endif /* HAVE_SERIAL */ diff --git a/arch/z80/src/z180/z180_lowuart.c b/arch/z80/src/z180/z180_lowuart.c new file mode 100644 index 0000000000000000000000000000000000000000..cd80e3987b53598c30b5f6bb1ce2128c543079cd --- /dev/null +++ b/arch/z80/src/z180/z180_lowuart.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_lowuart.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/chip.h" +#include "common/up_internal.h" +#include "z180_config.h" + +#if defined(USE_LOWSERIALINIT) && defined(HAVE_UART) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_Z180_UART0_SERIAL_CONSOLE) +# define CONSOLE_CR Z181_UART0_CR +# define CONSOLE_DR Z181_UART0_DR +# define CONSOLE_BAUD CONFIG_Z180_UART0_BAUD +# define CONSOLE_BITS CONFIG_Z180_UART0_BITS +# define CONSOLE_2STOP CONFIG_Z180_UART0_2STOP +# define CONSOLE_PARITY CONFIG_Z180_UART0_PARITY + +#elif defined(CONFIG_Z180_UART1_SERIAL_CONSOLE) +# define CONSOLE_CR Z182_UART1_CR +# define CONSOLE_DR Z182_UART1_DR +# define CONSOLE_BAUD CONFIG_Z180_UART1_BAUD +# define CONSOLE_BITS CONFIG_Z180_UART1_BITS +# define CONSOLE_2STOP CONFIG_Z180_UART1_2STOP +# define CONSOLE_PARITY CONFIG_Z180_UART1_PARITY +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_uart_lowinit + * + * Description: + * Called early in the boot sequence to initialize the uart console + * channel (only). + * + ****************************************************************************/ + +#ifdef USE_LOWSERIALINIT +void z180_uart_lowinit(void) +{ +#ifdef HAVE_UART_CONSOLE +#warning "Missing logic" +#endif +} +#endif + +/**************************************************************************** + * Name: z180_putc + * + * Description: + * Low-level character output + * + ****************************************************************************/ + +#ifdef HAVE_UART_CONSOLE +void z180_putc(uint8_t ch) +{ +#warning "Missing logic" +} +#endif + +#endif /* USE_LOWSERIALINIT && HAVE_UART*/ diff --git a/arch/z80/src/z180/z180_mmu.c b/arch/z80/src/z180/z180_mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..e3612dc9f024d9064799e9766e5dbd3e6921b3da --- /dev/null +++ b/arch/z80/src/z180/z180_mmu.c @@ -0,0 +1,605 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_mmu.c + * + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* See arch/z80/src/z180/z180_mmu.txt for additional information */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "z180_mmu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ARCH_ADDRENV +# warning "OS address environment support is required (CONFIG_ARCH_ADDRENV)" +#endif + +#ifndef CONFIG_GRAN +# warning "This file requires the granual allocator (CONFIG_GRAN)" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifndef CONFIG_GRAN_SINGLE +static GRAN_HANDLE g_physhandle; +#endif +static struct z180_cbr_s g_cbrs[CONFIG_MAX_TASKS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_alloccbr + * + * Description: + * Find an unused struture in g_cbrs (i.e., one with reference count == 0). + * If a structure is found, its reference count is set to one and a pointer + * to the structure is returned. + * + ****************************************************************************/ + +static inline FAR struct z180_cbr_s *z180_mmu_alloccbr(void) +{ + int i; + + for (i = 0; i < CONFIG_MAX_TASKS; i++) + { + FAR struct z180_cbr_s *cbr = &g_cbrs[i]; + if (cbr->crefs == 0) + { + cbr->crefs = 1; + return cbr; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: z180_mmu_freecbr + * + * Description: + * Free a struture in g_cbrs by setting its reference count to 0; + * + ****************************************************************************/ + +#define z180_mmu_freecbr(cbr) (cbr)->crefs = 0 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_lowinit + * + * Description: + * Low-level, power-up initialization of the z180 MMU. this must be + * called very early in the boot process to get the basic operating + * memory configuration correct. This function does *not* perform all + * necessray MMU initialization... only the basics needed at power-up. + * up_mmuinit() must be called later to complete the entire MMU + * initialization. + * + ****************************************************************************/ + +void z180_mmu_lowinit(void) __naked +{ + /* Set the CBAR register to set up the virtual address of the Bank Area and + * Common Area 1. Set the BBR register to set up the physical mapping for + * the Bank Area (the physical mapping for Common Area 1 will not be done + * until the first task is started. + */ + + __asm + ld c, #Z180_MMU_CBAR ; port + ld a, #Z180_CBAR_VALUE ; value + out (c), a + + ld c, #Z180_MMU_BBR ; port + ld a, #Z180_BBR_VALUE ; value + out (c), a + __endasm; +} + +/**************************************************************************** + * Name: up_mmuinit + * + * Description: + * Perform higher level initialization of the MMU and physical memory + * memory management logic. + * + ****************************************************************************/ + +int up_mmuinit(void) +{ + /* Here we use the granule allocator as a page allocator. We lie and + * say that 1 page is 1 byte. + */ + +#ifdef CONFIG_GRAN_SINGLE +return gran_initialize((FAR void *)Z180_PHYSHEAP_STARTPAGE, + Z180_PHYSHEAP_NPAGES, 0, 0); +#else +g_physhandle = gran_initialize((FAR void *)Z180_PHYSHEAP_STARTPAGE, + Z180_PHYSHEAP_NPAGES, 0, 0); +return g_physhandle ? OK : -ENOMEM; +#endif +} + +/**************************************************************************** + * Address Environment Interfaces + * + * Low-level interfaces used in binfmt/ to instantiate tasks with address + * environments. These interfaces all operate on type group_addrenv_t which + * is an abstract representation of a task group's address environment and + * must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined. + * + * up_addrenv_create - Create an address environment + * up_addrenv_destroy - Destroy an address environment. + * up_addrenv_vtext - Returns the virtual base address of the .text + * address environment + * up_addrenv_vdata - Returns the virtual base address of the .bss/.data + * address environment + * up_addrenv_heapsize - Returns the size of the initial heap allocation. + * up_addrenv_select - Instantiate an address environment + * up_addrenv_restore - Restore an address environment + * up_addrenv_clone - Copy an address environment from one location to + * another. + * + * Higher-level interfaces used by the tasking logic. These interfaces are + * used by the functions in sched/ and all operate on the thread which whose + * group been assigned an address environment by up_addrenv_clone(). + * + * up_addrenv_attach - Clone the address environment assigned to one TCB + * to another. This operation is done when a pthread + * is created that share's the same address + * environment. + * up_addrenv_detach - Release the threads reference to an address + * environment when a task/thread exits. + * + ****************************************************************************/ +/**************************************************************************** + * Name: up_addrenv_create + * + * Description: + * This function is called when a new task is created in order to + * instantiate an address environment for the new task group. + * up_addrenv_create() is essentially the allocator of the physical + * memory for the new task. + * + * Input Parameters: + * textsize - The size (in bytes) of the .text address environment needed + * by the task. This region may be read/execute only. + * datasize - The size (in bytes) of the .data/.bss address environment + * needed by the task. This region may be read/write only. NOTE: The + * actual size of the data region that is allocated will include a + * OS private reserved region at the beginning. The size of the + * private, reserved region is give by ARCH_DATA_RESERVE_SIZE. + * heapsize - The initial size (in bytes) of the heap address environment + * needed by the task. This region may be read/write only. + * addrenv - The location to return the representation of the task address + * environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize, + FAR group_addrenv_t *addrenv) +{ + FAR struct z180_cbr_s *cbr; + irqstate_t flags; + size_t envsize; + uintptr_t alloc; + unsigned int npages; + int ret; + + /* Convert the size from bytes to numbers of pages */ + +#ifdef CONFIG_BUILD_KERNEL + envsize = textsize + datasize + heapsize; +#else + envsize = textsize + datasize; +#endif + + npages = PHYS_ALIGNUP(envsize); + if (npages < 1) + { + /* No address environment... but I suppose that is not an error */ + + sdbg("ERROR: npages is zero\n"); + return OK; + } + + /* Allocate a structure in the common .bss to hold information about the + * task's address environment. NOTE that this is not a part of the TCB, + * but rather a break-away structure that can be shared by the task as + * well as other threads. That is necessary because the life of the + * address of environment might be longer than the life of the task. + */ + + flags = enter_critical_section(); + cbr = z180_mmu_alloccbr(); + if (!cbr) + { + sdbg("ERROR: No free CBR structures\n"); + ret = -ENOMEM; + goto errout_with_irq; + } + + /* Now allocate the physical memory to back up the address environment */ + +#ifdef CONFIG_GRAN_SINGLE + alloc = (uintptr_t)gran_alloc(npages); +#else + alloc = (uintptr_t)gran_alloc(g_physhandle, npages); +#endif + if (!alloc) + { + sdbg("ERROR: Failed to allocate %d pages\n", npages); + ret = -ENOMEM; + goto errout_with_cbr; + } + + /* Save the information in the CBR structure. Note that alloc is in + * 4KB pages, already in the right form for the CBR. + */ + + DEBUGASSERT(alloc <= 0xff); + + cbr->cbr = (uint8_t)alloc; + cbr->pages = (uint8_t)npages; + *addrenv = (group_addrenv_t)cbr; + + leave_critical_section(flags); + return OK; + +errout_with_cbr: + z180_mmu_freecbr(cbr); + +errout_with_irq: + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: up_addrenv_destroy + * + * Description: + * This function is called when a final thread leaves the task group and + * the task group is destroyed. This function then destroys the defunct + * address environment, releasing the underlying physical memory. + * + * Input Parameters: + * addrenv - The address environment to be destroyed. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_destroy(FAR group_addrenv_t *addrenv) +{ + FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)*addrenv; + + DEBUGASSERT(cbr); + + /* Free the physical address space backing up the mapping */ + +#ifdef CONFIG_GRAN_SINGLE + gran_free((FAR void *)cbr->cbr, cbr->pages); +#else + gran_free(g_physhandle, (FAR void *)cbr->cbr, cbr->pages); +#endif + + /* And make the CBR structure available for re-use */ + + z180_mmu_freecbr(cbr); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_vtext + * + * Description: + * Return the virtual address associated with the newly create .text + * address environment. This function is used by the binary loaders in + * order get an address that can be used to initialize the new task. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * vtext - The location to return the virtual address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_vtext(FAR group_addrenv_t *addrenv, FAR void **vtext) +{ + return CONFIG_Z180_COMMON1AREA_VIRTBASE; +} + +/**************************************************************************** + * Name: up_addrenv_vdata + * + * Description: + * Return the virtual address associated with the newly create .text + * address environment. This function is used by the binary loaders in + * order get an address that can be used to initialize the new task. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * textsize - For some implementations, the text and data will be saved + * in the same memory region (read/write/execute) and, in this case, + * the virtual address of the data just lies at this offset into the + * common region. + * vdata - The location to return the virtual address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize, + FAR void **vdata) +{ + return CONFIG_Z180_COMMON1AREA_VIRTBASE + textsize; +} + +/**************************************************************************** + * Name: up_addrenv_heapsize + * + * Description: + * Return the initial heap allocation size. That is the amount of memory + * allocated by up_addrenv_create() when the heap memory region was first + * created. This may or may not differ from the heapsize parameter that + * was passed to up_addrenv_create() + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * + * Returned Value: + * The initial heap size allocated is returned on success; a negated + * errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv) +{ + /* Not implemented */ + + return (ssize_t)-ENOSYS; +} +#endif + +/**************************************************************************** + * Name: up_addrenv_select + * + * Description: + * After an address environment has been established for a task (via + * up_addrenv_create()), this function may be called to to instantiate + * that address environment in the virtual address space. This might be + * necessary, for example, to load the code for the task from a file or + * to access address environment private data. + * + * Input Parameters: + * addrenv - The representation of the task address environment previously + * returned by up_addrenv_create. + * oldenv + * The address environment that was in place before up_addrenv_select(). + * This may be used with up_addrenv_restore() to restore the original + * address environment that was in place before up_addrenv_select() was + * called. Note that this may be a task agnostic, hardware + * representation that is different from group_addrenv_t. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_select(FAR const group_addrenv_t *addrenv, + FAR save_addrenv_t *oldenv) +{ + FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv; + irqstate_t flags; + + DEBUGASSERT(cbr && oldenv); + + /* Return the current CBR value from the CBR register */ + + flags = enter_critical_section(); + *oldenv = (save_addrenv_t)inp(Z180_MMU_CBR); + + /* Write the new CBR value into CBR register */ + + outp(Z180_MMU_CBR, cbr->cbr); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_restore + * + * Description: + * After an address environment has been temporarilty instantiated by + * up_addrenv_select, this function may be called to to restore the + * original address environment. + * + * Input Parameters: + * oldenv - The hardware representation of the address environment + * previously returned by up_addrenv_select. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_restore(FAR const save_addrenv_t *oldenv) +{ + outp(Z180_MMU_CBR, (uint8_t)*oldenv); + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_coherent + * + * Description: + * Flush D-Cache and invalidate I-Cache in preparation for a change in + * address environments. This should immediately precede a call to + * up_addrenv_select(); + * + * Input Parameters: + * addrenv - Describes the address environment to be made coherent. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_coherent(FAR const group_addrenv_t *addrenv) +{ + /* There are no caches */ + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_clone + * + * Description: + * Duplicate an address environment. This does not copy the underlying + * memory, only the representation that can be used to instantiate that + * memory as an address environment. + * + * Input Parameters: + * src - The address environment to be copied. + * dest - The location to receive the copied address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_clone(FAR const group_addrenv_t *src, + FAR group_addrenv_t *dest); +{ + DEBUGASSERT(src && dest); + + /* Copy the CBR structure. This is an atomic operation so no special + * precautions should be needed. + */ + + *dest = *src; + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_attach + * + * Description: + * This function is called from the core scheduler logic when a thread + * is created that needs to share the address environment of its task + * group. + * + * Input Parameters: + * group - The task group to which the new thread belongs. + * tcb - The tcb of the thread needing the address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb) +{ + /* There is nothing that needs to be done */ + + return OK; +} + +/**************************************************************************** + * Name: up_addrenv_detach + * + * Description: + * This function is called when a task or thread exits in order to release + * its reference to an address environment. The address environment, + * however, should persist until up_addrenv_destroy() is called when the + * task group is itself destroyed. Any resources unique to this thread + * may be destroyed now. + * + * NOTE: In some platforms, nothing will need to be done in this case. + * Simply being a member of the group that has the address environment + * may be sufficient. + * + * Input Parameters: + * group - The group to which the thread belonged. + * tcb - The TCB of the task or thread whose the address environment will + * be released. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb); +{ + /* There is nothing that needs to be done */ + + return OK; +} diff --git a/arch/z80/src/z180/z180_mmu.h b/arch/z80/src/z180/z180_mmu.h new file mode 100644 index 0000000000000000000000000000000000000000..69ee13cc52cb07888ea25b1a157fda96d4610ac9 --- /dev/null +++ b/arch/z80/src/z180/z180_mmu.h @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_mmu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_Z180_MMU_H +#define __ARCH_Z80_SRC_Z180_Z180_MMU_H + +/* See arch/z80/src/z180/z180_mmu.txt for additional information */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "z180_iomap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Virtual addresses */ + +#ifndef CONFIG_Z180_BANKAREA_VIRTBASE +# warning "Assuming Bank Area at virtual address 0x8000" +# define CONFIG_Z180_BANKAREA_VIRTBASE 0x8000 +#endif + +#ifndef CONFIG_Z180_COMMON1AREA_VIRTBASE +# warning "Assuming Common Area 1 at virtual address 0xc000" +# define CONFIG_Z180_COMMON1AREA_VIRTBASE 0xc000 +#endif + +#if CONFIG_Z180_BANKAREA_VIRTBASE > CONFIG_Z180_COMMON1AREA_VIRTBASE +# error "CONFIG_Z180_BANKAREA_VIRTBASE > CONFIG_Z180_COMMON1AREA_VIRTBASE" +#endif + +/* Physical addresses */ + +#ifndef CONFIG_Z180_BANKAREA_PHYSBASE +# warning "Assuming Bank Area 1 at physical address 0x080000" +# define CONFIG_Z180_BANKAREA_PHYSBASE 0x08000 +#endif + +#ifndef CONFIG_Z180_PHYSHEAP_START +# warning "Assuming physical heap starts at physical address 0x0c000" +# define CONFIG_Z180_PHYSHEAP_START 0x0c000 +#endif + +#ifndef CONFIG_Z180_PHYSHEAP_END +# warning "Assuming physical heap ends at physical address 0x100000" +# define CONFIG_Z180_PHYSHEAP_END 0x100000 +#endif + +#if CONFIG_Z180_BANKAREA_PHYSBASE > CONFIG_Z180_PHYSHEAP_START +# error "CONFIG_Z180_BANKAREA_PHYSBASE > CONFIG_Z180_PHYSHEAP_START" +#endif + +#if CONFIG_Z180_PHYSHEAP_START > CONFIG_Z180_PHYSHEAP_END +# error "CONFIG_Z180_PHYSHEAP_START > CONFIG_Z180_PHYSHEAP_END" +#endif + +/* Each page is 4KB */ + +#define Z180_PAGESHIFT (12) +#define Z180_PAGESIZE (1 << Z180_PAGESHIFT) +#define Z180_PAGEMASK (Z180_PAGESIZE - 1) +#define PHYS_ALIGN(phys) ((phys) >> Z180_PAGESHIFT) +#define PHYS_ALIGNUP(phys) (((phys) + Z180_PAGEMASK) >> Z180_PAGESHIFT) + +/* Physical pages */ + +#define Z180_BANKAREA_PHYSPAGE PHYS_ALIGN(CONFIG_Z180_BANKAREA_PHYSBASE) +#define Z180_PHYSHEAP_STARTPAGE PHYS_ALIGN(CONFIG_Z180_PHYSHEAP_START) +#define Z180_PHYSHEAP_ENDPAGE PHYS_ALIGN(CONFIG_Z180_PHYSHEAP_END) +#define Z180_PHYSHEAP_NPAGES (Z180_PHYSHEAP_ENDPAGE - Z180_PHYSHEAP_STARTPAGE + 1) + +/* MMU register values */ + +#define Z180_CBAR_BA_VALUE (((CONFIG_Z180_BANKAREA_VIRTBASE >> 12) & 0x0f) << CBAR_BA_SHIFT) +#define Z180_CBAR_CA_VALUE (((CONFIG_Z180_COMMON1AREA_VIRTBASE >> 12) & 0x0f) << CBAR_CA_SHIFT) +#define Z180_CBAR_VALUE (Z180_CBAR_BA_VALUE | Z180_CBAR_CA_VALUE) +#define Z180_BBR_VALUE ((CONFIG_Z180_BANKAREA_PHYSBASE >> 12) & 0xff) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_lowinit + * + * Description: + * Low-level, power-up initialization of the z180 MMU. this must be + * called very early in the boot process to get the basic operating + * memory configuration correct. This function does *not* perform all + * necessray MMU initialization... only the basics needed at power-up. + * up_mmuinit() must be called later to complete the entire MMU + * initialization. + * + ****************************************************************************/ + +void z180_mmu_lowinit(void) __naked; + +/**************************************************************************** + * Name: up_mmuinit + * + * Description: + * Perform higher level initialization of the MMU and physical memory + * memory management logic. More correctly prototypes in up_internal.h. + * + ****************************************************************************/ + +int up_mmuinit(void); + +#endif /* __ARCH_Z80_SRC_Z180_Z180_MMU_H */ diff --git a/arch/z80/src/z180/z180_mmu.txt b/arch/z80/src/z180/z180_mmu.txt new file mode 100644 index 0000000000000000000000000000000000000000..e12f41e9b76444761d0da225db850c230eaeb827 --- /dev/null +++ b/arch/z80/src/z180/z180_mmu.txt @@ -0,0 +1,114 @@ +The MMU translates every memory address from 16 to 20 bits. The MMU uses +three internal control registers. On reset the MMU gives a straight logical +to physical mapping, simulating the Z80 and, of course, limiting the address +space to 64k. + +Logical Address Spaces +====================== + +The 64KB CPU logical address space is interpreted by the MMU as consisting +of up to three separate logical address areas: + + Common Area 0, + Bank Area, and + Common Area 1. + +Common 0, if it exists, always starts at logical address 0000 and runs up +to the Bank Area. The Bank Area then runs to the start of Common Area 1. + +Registers +========= + +CBAR (Comman/Bank Area Register) + + CBAR is an 8 bit I/O port that can be accessed by the processor's OUT and + IN instructions. The lower 4-bits of CBAR (BA) specify the starting logical + address of the Bank Area, and the upper 4-bits (CA) give the start of + Common Area 1. These bits determine the upper four bits of the 16-bit + address. If CBAR were 0xa8, then the Base Area starts at logical address + 0x8000 and Common Area 1 starts at logical address 0xa000. This gives a + mapping granualarity of 4Kb in the logical address space. + + The CA and BA fields of CBAR may be freely programmed subject only to the + restriction that CA may never be less than BA. + +BBAR (Base Area Bank Register) + + BBR specifies the starting physical address of the base area (the logical + start address is in CBAR). + +CBR (Common Bank Register) + + CBR provides the same information for Common Area 1. + +Both the BBAR and the CBR specify the upper 8-bits of the 20-bit physical +address in the mapping. Hence, mapping is performed with a granularity of +4Kb in the physical address space. + +Physical to Logical Address Mapping +=================================== + +A simple formula gives the translation from logical to physical address for +the Bank Area: + + Physical = Logical + (BBR * 4096) + +The same formula gives Common Area 1: + + Physical = Logical + (CBR * 4096) + +Reset Configuration +=================== + +On reset, the CBAR is set to 0xf0, and CBR and BBR are set to 0x00. This +maps logical to physical with no translation; the Bank Area starts at +logical address 0x0000 and Common 1 at 0xf000. The Bank Area starts at +phsycial address 0x00000 (BBR=0), as does Common Area 1 (CBR=0). If the +logical address is 0x1000, then the MMU allocates this to the Bank Area +and adds the physical base of bank to it (0x00000), giving a translated +address of 0x01000. Similarly, logical 0xf800 is in Common Area 1, and +translates to 0x0f800. + +Configurations +============== + +You can divide the logical address space into one, two, or three areas. + +1) Three areas: + + CBAR:CA > CBAR:BA > 0x0000 + +2a) Two areas (Bank Area and Common Area 1): + + CBAR:CA > CBAR:BA = 0x0000 + +2a) Two areas (Common Area 0 and Common Area 1): + + CBAR:CA = CBAR:BA > 0x0000 + +3) One area (Common Area 1): + + CBAR:CA = CBAR:BA = 0x0000 + +NuttX Memory Organization +========================= + +Common Area 0: This area holds the common NuttX code that is directly +call-able from all application threads. Common Area always starts at +logical address 0x0000 and extends to the Bank Area + +Base Area: This area holds the common NuttX data (including the share- +able heap) that is accessible from all applications and extends to +Common Area 1. + +NOTE: That is execution from RAM, the common NuttX code and data may +be contiguous and lie in the same areas (either Common Area 0 or the +Bank Area). The two areas above would apply in a ROM'ed system, where +Common Area 1 is ROM and the Base Area is RAM. + +Common Area 1: This area holds the code and data that is unique to +a particular task. This area extends to the end of the logical address +space. All tasks share the same logical Common Area 2 logical address +(in the CBAR), but each has a unique mapping to different, underlying +physical addresses. Each task will then have its own, unique CBR value +that must be restored with each context switch to the task. diff --git a/arch/z80/src/z180/z180_modifiyreg8.c b/arch/z80/src/z180/z180_modifiyreg8.c new file mode 100644 index 0000000000000000000000000000000000000000..bfeec463eeb7a5474a2e787235f329c6d899aaa3 --- /dev/null +++ b/arch/z80/src/z180/z180_modifiyreg8.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/common/up_modifyreg8.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a I/O register + * + ****************************************************************************/ + +void modifyreg8(uint16_t addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = inp(addr); + regval &= ~clearbits; + regval |= setbits; + outp(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/z80/src/z180/z180_registerdump.c b/arch/z80/src/z180/z180_registerdump.c new file mode 100644 index 0000000000000000000000000000000000000000..1c3a4c73be35a182838ab6e35ebe423cf492238f --- /dev/null +++ b/arch/z80/src/z180/z180_registerdump.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_registerdump.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_registerdump + ****************************************************************************/ + +static void z180_registerdump(void) +{ + if (g_current_regs) + { + lldbg("AF: %04x I: %04x\n", + g_current_regs[XCPT_AF], g_current_regs[XCPT_I]); + lldbg("BC: %04x DE: %04x HL: %04x\n", + g_current_regs[XCPT_BC], g_current_regs[XCPT_DE], g_current_regs[XCPT_HL]); + lldbg("IX: %04x IY: %04x\n", + g_current_regs[XCPT_IX], g_current_regs[XCPT_IY]); + lldbg("SP: %04x PC: %04x\n" + g_current_regs[XCPT_SP], g_current_regs[XCPT_PC]); + lldbg("CBAR: %02x BBR: %02x CBR: %02x\n" + inp(Z180_MMU_CBAR), inp(Z180_MMU_BBR), inp(Z180_MMU_CBR)); + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z80/src/z180/z180_restoreusercontext.asm b/arch/z80/src/z180/z180_restoreusercontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..fd2a70c1fd4bf02b938c496f8f5a039bae35b54e --- /dev/null +++ b/arch/z80/src/z180/z180_restoreusercontext.asm @@ -0,0 +1,104 @@ +;************************************************************************** +; arch/z80/src/z180/z180_restoreusercontext.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + ; Register save area layout + + .globl XCPT_I ; Offset 0: Saved I w/interrupt state in carry + .globl XCPT_BC ; Offset 1: Saved BC register + .globl XCPT_DE ; Offset 2: Saved DE register + .globl XCPT_IX ; Offset 3: Saved IX register + .globl XCPT_IY ; Offset 4: Saved IY register + .globl XCPT_SP ; Offset 5: Offset to SP at time of interrupt + .globl XCPT_HL ; Offset 6: Saved HL register + .globl XCPT_AF ; Offset 7: Saved AF register + .globl XCPT_PC ; Offset 8: Offset to PC at time of interrupt + +;************************************************************************** +; z180_restoreusercontext +;************************************************************************** + + .area _CODE +_z180_restoreusercontext: + ; On entry, stack contains return address (not used), then address + ; of the register save structure + + ; Discard the return address, we won't be returning + + pop hl + + ; Get the address of the beginning of the state save area. Each + ; pop will increment to the next element of the structure + + pop hl ; BC = Address of save structure + ld sp, hl ; SP points to top of storage area + + ; Disable interrupts while we muck with the alternative registers. The + ; Correct interrupt state will be restore below + + di + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in parity + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + pop hl ; Offset 5: HL' = Stack pointer after return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + pop de ; DE' = return address + ld sp, hl ; Set SP = saved stack pointer value before return + push de ; Save return address for ret instruction + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, noinrestore ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes.. Enable interrupts + ret ; and return +noinrestore: + ex af, af' ; Restore AF + ret ; Return with interrupts disabled diff --git a/arch/z80/src/z180/z180_rom.asm b/arch/z80/src/z180/z180_rom.asm new file mode 100644 index 0000000000000000000000000000000000000000..8a7a62a545232f695ab7fcbf4bf402d9d9002c6f --- /dev/null +++ b/arch/z80/src/z180/z180_rom.asm @@ -0,0 +1,200 @@ +;************************************************************************** +; arch/z80/src/z180/z180_rom.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z180 + .module z180_head + +;************************************************************************** +; Constants +;************************************************************************** + + ; Default stack base (needs to be fixed) + + .include "asm_mem.h" + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _os_start ; OS entry point + .globl _up_vectcommon ; Common interrupt handling logic + .globl _z180_mmu_lowinit ; MMU initialization logic + .globl s__HEAP ; Start of the heap + +;************************************************************************** +; System start logic +;************************************************************************** + +_up_reset: + ; Set up the stack pointer at the location determined the Makefile + ; and stored in asm_mem.h + + ld SP, #CONFIG_STACK_END ; Set stack pointer + + ; Performed initialization unique to the SDCC toolchain + + call gsinit ; Initialize the data section + + ; Copy the reset vectors + + ld hl, #_up_rstvectors ; code for RAM + ld de, #0x4000 ; move it here + ld bc, #3*7 ; 7 vectors / 3 bytes each + ldir + + ; Then start NuttX + + call _os_start ; jump to the OS entry point + + ; NuttX will never return, but just in case... + +_up_halt:: + halt ; We should never get here + jp _up_halt + + ; Data to copy to address 0x4000 + +_up_rstvectors: + jp _up_rst1 ; 0x4000 : RST 1 + jp _up_rst2 ; 0x4003 : RST 2 + jp _up_rst3 ; 0x4006 : RST 3 + jp _up_rst4 ; 0x4009 : RST 4 + jp _up_rst5 ; 0x400c : RST 5 + jp _up_rst6 ; 0x400f : RST 6 + jp _up_rst7 ; 0x4012 : RST 7 + +;************************************************************************** +; Other reset handlers +;************************************************************************** + +_up_rst1: ; RST 1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #0 ; 0 = Z180_RST1 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst2: ; RST 2 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #1 ; 1 = Z180_RST2 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst3: ; RST 3 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #2 ; 2 = Z180_RST3 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst4: ; RST 4 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #3 ; 3 = Z180_RST4 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst5: ; RST 5 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #4 ; 4 = Z180_RST5 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst6: ; RST 6 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #5 ; 5 = Z180_RST6 + jp _up_vectcommon ; Remaining RST handling is common + +_up_rst7: ; RST 7 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #6 ; 6 = Z180_RST7 + jp _up_vectcommon ; Remaining RST handling is common + +;************************************************************************** +; Ordering of segments for the linker (SDCC only) +;************************************************************************** + + .area _HOME + .area _CODE + .area _INITIALIZER + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _INITIALIZED + .area _BSEG + .area _BSS + .area _HEAP + +;************************************************************************** +; Global data initialization logic (SDCC only) +;************************************************************************** + + .area _GSINIT +gsinit:: + ld bc, #l__INITIALIZER + ld a, b + or a, c + jr Z, gsinit_next + ld de, #s__INITIALIZED + ld hl, #s__INITIALIZER + ldir +gsinit_next: + + .area _GSFINAL + ret + +;************************************************************************** +; The start of the heap (SDCC only). Note that is actually resides in +; the _CODE area (which may be FLASH or ROM) +;************************************************************************** + + .area _CODE +_g_heapbase:: + .dw #s__HEAP + diff --git a/arch/z80/src/z180/z180_romvectors.asm b/arch/z80/src/z180/z180_romvectors.asm new file mode 100644 index 0000000000000000000000000000000000000000..b4ca907cbc2b23578a78cb32ee6ee852d6faa7a0 --- /dev/null +++ b/arch/z80/src/z180/z180_romvectors.asm @@ -0,0 +1,83 @@ +;************************************************************************** +; arch/z80/src/z180/z180_romvectors.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z180 + .module z180_romvectors + +;************************************************************************** +; Constants +;************************************************************************** + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _up_int1 ; Vector offset 0: External /INT1 + .globl _up_int2 ; Vector offset 2: External /INT2 + .globl _up_prt0 ; Vector offset 4: PRT channel 0 + .globl _up_prt1 ; Vector offset 6: PRT channel 1 + .globl _up_dma0 ; Vector offset 8: DMA channel 0 + .globl _up_dma1 ; Vector offset 8: DMA channel 1 + .globl _up_csio ; Vector offset 12: Clocked serial I/O + .globl _up_asci0 ; Vector offset 14: Async channel 0 + .globl _up_asci1 ; Vector offset 16: Async channel 1 + .globl _up_unused ; Vector offset 18: Unused + +;************************************************************************** +; Interrupt Vector Table +;************************************************************************** + +; The start of the _VECTORS area must be set by the linker to lie at some +; 32-byte-aligned address + + .area _VECTORS + +_up_vectors:: + .dw _up_int1 ; Vector offset 0: External /INT1 + .dw _up_int2 ; Vector offset 2: External /INT2 + .dw _up_prt0 ; Vector offset 4: PRT channel 0 + .dw _up_prt1 ; Vector offset 6: PRT channel 1 + .dw _up_dma0 ; Vector offset 8: DMA channel 0 + .dw _up_dma1 ; Vector offset 8: DMA channel 1 + .dw _up_csio ; Vector offset 12: Clocked serial I/O + .dw _up_asci0 ; Vector offset 14: Async channel 0 + .dw _up_asci1 ; Vector offset 16: Async channel 1 + .dw _up_unused ; Vector offset 18: Unused + .dw _up_unused ; Vector offset 20: Unused + .dw _up_unused ; Vector offset 22: Unused + .dw _up_unused ; Vector offset 24: Unused + .dw _up_unused ; Vector offset 26: Unused + .dw _up_unused ; Vector offset 28: Unused + .dw _up_unused ; Vector offset 30: Unused diff --git a/arch/z80/src/z180/z180_saveusercontext.asm b/arch/z80/src/z180/z180_saveusercontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..31c9ef8ce48d231a638a0a1bbf44a85d824dc146 --- /dev/null +++ b/arch/z80/src/z180/z180_saveusercontext.asm @@ -0,0 +1,143 @@ +;************************************************************************* +; arch/z80/src/z180/z180_saveusercontext.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************* + +;************************************************************************* +; Constants +;************************************************************************* + + ; Register save area layout + + .globl XCPT_I ; Offset 0: Saved I w/interrupt state in parity + .globl XCPT_BC ; Offset 1: Saved BC register + .globl XCPT_DE ; Offset 2: Saved DE register + .globl XCPT_IX ; Offset 3: Saved IX register + .globl XCPT_IY ; Offset 4: Saved IY register + .globl XCPT_SP ; Offset 5: Offset to SP at time of interrupt + .globl XCPT_HL ; Offset 6: Saved HL register + .globl XCPT_AF ; Offset 7: Saved AF register + .globl XCPT_PC ; Offset 8: Offset to PC at time of interrupt + + ; Stack frame + + FRAME_IY == 0 ; Location of IY on the stack + FRAME_IX == 2 ; Location of IX on the stack + FRAME_RET == 4 ; Location of return address on the stack + FRAME_REGS == 6 ; Location of reg save area on stack + + SP_OFFSET == 6 + +;************************************************************************* +; Name: z180_saveusercontext +;************************************************************************* + + .area _CODE +_z180_saveusercontext: + ; Set up a stack frame + + push ix ; Save IX and IY + push iy + ld ix, #0 + add ix, sp ; IX = stack frame + + ; Fetch the address of the save area + + ld e, FRAME_REGS(ix) ; HL = save area address + ld d, FRAME_REGS+1(ix) ; + ld iy, #0 + add iy, de ; IY = save area address + + ; Then save the registers + + ; Save the current interrupt state at offset 0 + + ld a, i ; Get interrupt state + push af + pop hl + ld XCPT_I(iy), l ; Offset 0: I w/interrupt state in parity + ld XCPT_I+1(iy), h + + ; Save BC at offset 1 + + ld XCPT_BC(iy), c ; Offset 1: BC + ld XCPT_BC+1(iy), b + + ; DE is not preserved (offset 2) + + ; Save IX at offset 3 + + ld l, FRAME_IX(ix) ; HL = Saved alue of IX + ld h, FRAME_IX+1(ix) ; + ld XCPT_IX(iy), l ; Offset 3: IX + ld XCPT_IX+1(iy), h ; + + ; Save IY at offset 4 + + ld l, FRAME_IY(ix) ; HL = Saved value of IY + ld h, FRAME_IY+1(ix) ; + ld XCPT_IY(iy), l ; Offset 4: IY + ld XCPT_IY+1(iy), h + + ; Save that stack pointer as it would be upon return in offset 5 + + ld hl, #SP_OFFSET ; Value of stack pointer on return + add hl, sp + ld XCPT_SP(iy), l ; Offset 5 SP + ld XCPT_SP+1(iy), h + + ; HL is saved as the value 1 at offset 6 + + xor a ; A = 0 + ld XCPT_HL+1(iy), a ; Offset 2: HL on return (=1) + inc a ; A = 1 + ld XCPT_HL(iy), a ; + + ; AF is not preserved (offset 7) + + ; Save the return address in offset 8 + + ld l, FRAME_RET(ix) ; HL = Saved return address + ld h, FRAME_RET+1(ix) ; + ld XCPT_PC(iy), l ; Offset 8: PC + ld XCPT_PC+1(iy), h + + ; Return the value 0 + + xor a ; HL = return value of zero + ld l, a + ld h, a + + pop iy + pop ix + ret diff --git a/arch/z80/src/z180/z180_scc.c b/arch/z80/src/z180/z180_scc.c new file mode 100644 index 0000000000000000000000000000000000000000..5c967a150ec04f3430ba8e391a8a1b409f07de7b --- /dev/null +++ b/arch/z80/src/z180/z180_scc.c @@ -0,0 +1,633 @@ +/**************************************************************************** + * arch/z80/src/ez08/z180_scc.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +#include "z180_config.h" +#include "z180_serial.h" + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct z180_dev_s +{ + uint32_t baud; /* Configured baud */ + uint8_t cr; /* [E]SCC control register */ + uint8_t dr; /* [E]SCC data register */ + uint8_t irq; /* IRQ associated with this [E]SCC */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 (vs 1) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int z180_setup(struct uart_dev_s *dev); +static void z180_shutdown(struct uart_dev_s *dev); +static int z180_attach(struct uart_dev_s *dev); +static void z180_detach(struct uart_dev_s *dev); +static int z180_interrupt(int irq, void *context); +static int z180_ioctl(struct file *filep, int cmd, unsigned long arg); +static int z180_receive(struct uart_dev_s *dev, unsigned int *status); +static void z180_rxint(struct uart_dev_s *dev, bool enable); +static bool z180_rxavailable(struct uart_dev_s *dev); +static void z180_send(struct uart_dev_s *dev, int ch); +static void z180_txint(struct uart_dev_s *dev, bool enable); +static bool z180_txready(struct uart_dev_s *dev); +static bool z180_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + z180_setup, /* setup */ + z180_shutdown, /* shutdown */ + z180_attach, /* attach */ + z180_detach, /* detach */ + z180_ioctl, /* ioctl */ + z180_receive, /* receive */ + z180_rxint, /* rxint */ + z180_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif + z180_send, /* send */ + z180_txint, /* txint */ + z180_txready, /* txready */ + z180_txempty /* txempty */ +}; + +/* I/O buffers */ + +#ifdef CONFIG_Z180_SCC +static char g_scc_rxbuffer[CONFIG_Z180_SCC_RXBUFSIZE]; +static char g_scc_txbuffer[CONFIG_Z180_SCC_TXBUFSIZE]; +#endif +#ifdef CONFIG_Z180_ESCCA +static char g_escca_rxbuffer[CONFIG_Z180_ESCCA_RXBUFSIZE]; +static char g_escca_txbuffer[CONFIG_Z180_ESCCA_TXBUFSIZE]; +#endif +#ifdef CONFIG_Z180_ESCCB +static char g_esccb_rxbuffer[CONFIG_Z180_ESCCB_RXBUFSIZE]; +static char g_esccb_txbuffer[CONFIG_Z180_ESCCB_TXBUFSIZE]; +#endif + +/* This describes the state of the SCC port. */ + +#ifdef CONFIG_Z180_SCC +static const struct z180_dev_s g_scc_priv = +{ + CONFIG_Z180_SCC_BAUD, /* baud */ + Z181_SCC_CR, /* cr */ + Z181_SCC_DR, /* dr */ + Z180_SCC_IRQ, /* irq */ + CONFIG_Z180_SCC_PARITY, /* parity */ + CONFIG_Z180_SCC_BITS, /* bits */ + CONFIG_Z180_SCC_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_scc_port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_Z180_SCC_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_Z180_SCC_TXBUFSIZE, /* xmit.size */ + g_scc_txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_Z180_SCC_RXBUFSIZE, /* recv.size */ + g_scc_rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_scc_priv, /* priv */ +}; +#endif + +/* This describes the state of the ESCC Channel A port. */ + +#ifdef CONFIG_Z180_ESCCA +static const struct z180_dev_s g_escca_priv = +{ + CONFIG_Z180_ESCCA_BAUD, /* baud */ + Z182_ESCCA_CR, /* cr */ + Z182_ESCCA_DR, /* dr */ + Z180_UART1_IRQ, /* irq */ + CONFIG_Z180_ESCCA_PARITY, /* parity */ + CONFIG_Z180_ESCCA_BITS, /* bits */ + CONFIG_Z180_ESCCA_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_escca_port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_Z180_ESCCA_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_Z180_ESCCA_TXBUFSIZE, /* xmit.size */ + g_escca_txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_Z180_ESCCA_RXBUFSIZE, /* recv.size */ + g_escca_rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_escca_priv, /* priv */ +}; +#endif + +/* This describes the state of the ESCC Channel B port. */ + +#ifdef CONFIG_Z180_ESCCB +static const struct z180_dev_s g_esccb_priv = +{ + CONFIG_Z180_ESCCB_BAUD, /* baud */ + Z182_ESCCB_CR, /* cr */ + Z182_ESCCB_DR, /* dr */ + Z180_UART1_IRQ, /* irq */ + CONFIG_Z180_ESCCB_PARITY, /* parity */ + CONFIG_Z180_ESCCB_BITS, /* bits */ + CONFIG_Z180_ESCCB_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_escca_port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_Z180_ESCCA_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_Z180_ESCCA_TXBUFSIZE, /* xmit.size */ + g_escca_txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_Z180_ESCCA_RXBUFSIZE, /* recv.size */ + g_escca_rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_escca_priv, /* priv */ +}; +#endif + +/* Now, which one with be tty0/console and which tty1? NOTE: SCC and ESCCA/B and + * mutually exclusive. + */ + +#undef CONSOLE_DEV +#undef TTYS0_DEV +#undef TTYS1_DEV + +#if defined(CONFIG_Z180_SCC_SERIAL_CONSOLE) +# define CONSOLE_DEV g_scc_port +# define TTYS0_DEV g_scc_port +#elif defined(CONFIG_Z180_SCC) +# define TTYS0_DEV g_scc_port + +#elif defined(CONFIG_Z180_ESCCA_SERIAL_CONSOLE) +# define CONSOLE_DEV g_escca_port +# define TTYS0_DEV g_escca_port +# if defined(CONFIG_Z180_ESCCB) +# define TTYS1_DEV g_esccb_port +# endif + +#elif defined(CONFIG_Z180_ESCCB_SERIAL_CONSOLE) +# define CONSOLE_DEV g_esccb_port +# define TTYS0_DEV g_esccb_port +# if defined(CONFIG_Z180_ESCCA) +# define TTYS1_DEV g_escca_port +# endif + +#elif defined(CONFIG_Z180_ESCCA) +# define TTYS0_DEV g_escca_port +# if defined(CONFIG_Z180_ESCCB) +# define TTYS1_DEV g_esccb_port +# endif + +#elif defined(CONFIG_Z180_ESCCB) +# define TTYS0_DEV g_esccb_port +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_serialin + ****************************************************************************/ + +static inline uint8_t z180_serialin(struct z180_dev_s *priv, uint8_t regaddr) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_serialout + ****************************************************************************/ + +static inline void z180_serialout(struct z180_dev_s *priv, uint8_t regaddr, + uint8_t value) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_disableuartint + ****************************************************************************/ + +static inline void z180_disableuartint(struct z180_dev_s *priv) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_restoreuartint + ****************************************************************************/ + +static inline void z180_restoreuartint(struct z180_dev_s *priv, uint8_t bits) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_waittxready + ****************************************************************************/ + +static inline void z180_waittxready(struct z180_dev_s *priv) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_setbaud + ****************************************************************************/ + +static inline void z180_setbaud(struct z180_dev_s *priv, uint24_t baud) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is called + * the first time that the serial port is opened. + * + ****************************************************************************/ + +static int z180_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG +# warning "Missing logic" +#endif + return OK; +} + +/**************************************************************************** + * Name: z180_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void z180_shutdown(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int z180_attach(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void z180_detach(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked + * when an interrupt received on the 'irq' It should call + * uart_transmitchars or uart_receivechar to perform the + * appropriate data transfers. The interrupt handling logic\ + * must be able to map the 'irq' number into the approprite + * uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int z180_interrupt(int irq, void *context) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int z180_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * the return 'status'. + * + ****************************************************************************/ + +static int z180_receive(struct uart_dev_s *dev, unsigned int *status) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void z180_rxint(struct uart_dev_s *dev, bool enable) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool z180_rxavailable(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void z180_send(struct uart_dev_s *dev, int ch) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void z180_txint(struct uart_dev_s *dev, bool enable) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool z180_txready(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Name: z180_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool z180_txempty(struct uart_dev_s *dev) +{ +#warning "Missing logic" +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Make sure that all UART interrupts are disabled */ +#warning "Missing logic" + + /* Configure for usage of [E]SCC channels */ + +#ifdef CONFIG_Z180_SCC +# warning "Missing logic" +#endif + +#ifdef CONFIG_Z180_ESCCA +# warning "Missing logic" +#endif + +#ifdef CONFIG_Z180_ESCCB +# warning "Missing logic" +#endif + + /* If there is a console, then configure the console now */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + z180_setup(&CONSOLE_DEV); +#endif + + /* Register console and tty devices */ + +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef CONSOLE_DEV + /* Disable [E]SCC interrupts and perform the low-level output */ + + z180_disableuartint(priv); + up_lowputc(ch); + z180_restoreuartint(priv); + return ch; +#endif +} +#endif /* USE_SERIALDRIVER */ diff --git a/arch/z80/src/z180/z180_schedulesigaction.c b/arch/z80/src/z180/z180_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..a29a4b9d8a3935a436768e753501b685ef350b67 --- /dev/null +++ b/arch/z80/src/z180/z180_schedulesigaction.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_schedulesigaction.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_sigsetup + ****************************************************************************/ + +static void z180_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs) +{ + /* Save the return address and interrupt state. These will be restored by + * the signal trampoline after the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = regs[XCPT_PC]; + tcb->xcp.saved_i = regs[XCPT_I]; + + /* Then set up to vector to the trampoline with interrupts disabled */ + + regs[XCPT_PC] = (chipreg_t)up_sigdeliver; + regs[XCPT_I] = 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!IN_INTERRUPT()) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we + * will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z180_sigsetup(tcb, sigdeliver, IRQ_STATE()); + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + SAVE_IRQCONTEXT(tcb); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an interrupt + * handler or (2) we are not in an interrupt handler and the running task + * is signalling some non-running task. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z180_sigsetup(tcb, sigdeliver, tcb->xcp.regs); + } + } + + leave_critical_section(flags); +} + +#endif /* CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/z80/src/z180/z180_serial.h b/arch/z80/src/z180/z180_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..0b0e12d79304b3e65c433e1bc0bd2c2885aabb34 --- /dev/null +++ b/arch/z80/src/z180/z180_serial.h @@ -0,0 +1,111 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_serial.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_Z180_SERIAL_H +#define __ARCH_Z80_SRC_Z180_Z180_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_internal.h" +#include "z180_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + /**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_uart_lowinit + * + * Description: + * Called early in the boot sequence to initialize the uart console + * channel (only). + * + ****************************************************************************/ + +#if defined(HAVE_UART) && defined(USE_LOWSERIALINIT) +void z180_uart_lowinit(void); +#else +# define z180_uart_lowinit() +#endif + +/**************************************************************************** + * Name: z180_scc_lowinit + * + * Description: + * Called early in the boot sequence to initialize the [E]SCC console + * channel (only). + * + ****************************************************************************/ + +#if defined(HAVE_SCC) && defined(USE_LOWSERIALINIT) +void z180_scc_lowinit(void); +#else +# define z180_scc_lowinit() +#endif + +/**************************************************************************** + * Name: z180_putc + * + * Description: + * Low-level character output + * + ****************************************************************************/ + +void z180_putc(uint8_t ch) __naked; + +/**************************************************************************** + * Name: up_putc/up_lowputc + * + * Description: + * Low-level console output + * + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER +int up_lowputc(int ch); +#else +int up_putc(int ch); +# define up_lowputc(ch) up_putc(ch) +#endif + +#endif /* __ARCH_Z80_SRC_Z180_Z180_SERIAL_H */ diff --git a/arch/z80/src/z180/z180_sigdeliver.c b/arch/z80/src/z180/z180_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..e058d5a116d381d52cc8cbf509a0e26ac7c8504d --- /dev/null +++ b/arch/z80/src/z180/z180_sigdeliver.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_sigdeliver.c + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + FAR struct tcb_s *rtcb = this_task(); + chipreg_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + z180_copystate(regs, rtcb->xcp.regs); + regs[XCPT_PC] = rtcb->xcp.saved_pc; + regs[XCPT_I] = rtcb->xcp.saved_i; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(regs[XCPT_I]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + z180_restoreusercontext(regs); +#endif +} + +#endif /* CONFIG_DISABLE_SIGNALS */ diff --git a/arch/z80/src/z180/z180_timerisr.c b/arch/z80/src/z180/z180_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..11f0bc92ce4f34b86525c081186ba993a8bb4dd2 --- /dev/null +++ b/arch/z80/src/z180/z180_timerisr.c @@ -0,0 +1,155 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_timerisr.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "clock/clock.h" +#include "up_internal.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* "The Z180 contains a two channel 16-bit Programmable Reload Timer. Each + * PRT channel contains a 16-bit down counter and a 16-bit reload register." + * Channel 0 is dedicated as the system timer. + */ + +/* "The PRT input clock for both channels is equal to the system clock + * divided by 20." + */ + +#define Z180_PRT_CLOCK (Z180_SYSCLOCK / 20) + +/* The data Register "(TMDR) is decremented once every twenty clocks. When + * TMDR counts down to 0, it is automatically reloaded with the value + * contained in the Reload Register (RLDR)." + */ + +#define A180_PRT0_RELOAD (Z180_PRT_CLOCK / CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, chipreg_t *regs) +{ + /* "When TMDR0 decrements to 0, TIF0 is set to 1. This generates an interrupt + * request if enabled by TIE0 = 1. TIF0 is reset to 0 when TCR is read and + * the higher or lower byte of TMDR0 is read." + */ + + (void)inp(Z180_PRT_TCR); + (void)inp(Z180_PRT0_DRL); + (void)inp(Z180_PRT0_DRH); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint8_t regval; + + /* Configure PRT0 to interrupt at the requested rate */ + /* First stop PRT0 and disable interrupts */ + + regval = inp(Z180_PRT_TCR); + regval &= (PRT_TCR_TIF0|PRT_TCR_TIE0|PRT_TCR_TDE0); + outp(Z180_PRT_TCR, regval); + + /* Set the timer reload value so that the timer will interrupt at the + * desired frequency. "For writing, the TMDR down counting must be + * inhibited using the TDE (Timer Down Count Enable) bits in the TCR + * (Timer Control Register). Then, any or both higher and lower bytes of + * TMDR can be freely written (and read) in any order." + */ + + outp(Z180_PRT0_RLDRL, (A180_PRT0_RELOAD & 0xff)); + outp(Z180_PRT0_RLDRH, (A180_PRT0_RELOAD >> 8)); + + /* Enable down-counting */ + + regval |= PRT_TCR_TDE0; + outp(Z180_PRT_TCR, regval); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(Z180_PRT0, (xcpt_t)up_timerisr); + + /* And enable the timer interrupt */ + + regval |= PRT_TCR_TIE0; + outp(Z180_PRT_TCR, regval); +} diff --git a/arch/z80/src/z180/z180_vectcommon.asm b/arch/z80/src/z180/z180_vectcommon.asm new file mode 100644 index 0000000000000000000000000000000000000000..c7d9a608a112189b0c301cd08c25d636a07c9ad5 --- /dev/null +++ b/arch/z80/src/z180/z180_vectcommon.asm @@ -0,0 +1,222 @@ +;************************************************************************** +; arch/z80/src/z180/z180_vectcommon.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z180 + .module z180_vectcommon + +;************************************************************************** +; Constants +;************************************************************************** + + ; Register save area layout + + XCPT_I == 0 ; Offset 0: Saved I w/interrupt state in carry + XCPT_BC == 2 ; Offset 1: Saved BC register + XCPT_DE == 4 ; Offset 2: Saved DE register + XCPT_IX == 6 ; Offset 3: Saved IX register + XCPT_IY == 8 ; Offset 4: Saved IY register + XCPT_SP == 10 ; Offset 5: Offset to SP at time of interrupt + XCPT_HL == 12 ; Offset 6: Saved HL register + XCPT_AF == 14 ; Offset 7: Saved AF register + XCPT_PC == 16 ; Offset 8: Offset to PC at time of interrupt + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _up_doirq ; Interrupt decoding logic + +;************************************************************************** +; Vector Handlers +;************************************************************************** + + .area _CODE + +_up_int1:: ; Vector offset 0: External /INT1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #9 ; 9 = Z180_INT1 + jr _up_vectcommon ; Remaining RST handling is common + +_up_int2:: ; Vector offset 2: External /INT2 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #10 ; 10 = Z180_INT2 + jr _up_vectcommon ; Remaining RST handling is common + +_up_prt0:: ; Vector offset 4: PRT channel 0 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #11 ; 11 = Z180_PRT0 + jr _up_vectcommon ; Remaining RST handling is common + +_up_prt1:: ; Vector offset 6: PRT channel 1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #12 ; 12 = Z180_PRT1 + jr _up_vectcommon ; Remaining RST handling is common + +_up_dma0:: ; Vector offset 8: DMA channel 0 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #13 ; 13 = Z180_DMA0 + jr _up_vectcommon ; Remaining RST handling is common + +_up_dma1:: ; Vector offset 8: DMA channel 1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #14 ; 14 = Z180_DMA1 + jr _up_vectcommon ; Remaining RST handling is common + +_up_csio:: ; Vector offset 12: Clocked serial I/O + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #15 ; 15 = Z180_CSIO + jr _up_vectcommon ; Remaining RST handling is common + +_up_asci0:: ; Vector offset 14: Async channel 0 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #16 ; 16 = Z180_ASCI0 + jr _up_vectcommon ; Remaining RST handling is common + +_up_asci1:: ; Vector offset 16: Async channel 1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #17 ; 17 = Z180_ASCI1 + jr _up_vectcommon ; Remaining RST handling is common + +_up_unused:: ; Vector offset 18: Unused + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #18 ; 18 = Z180_UNUSED + jr _up_vectcommon ; Remaining RST handling is common + +;************************************************************************** +; Common Interrupt handler +;************************************************************************** + +_up_vectcommon:: + ; Create a register frame. SP points to top of frame + 4, pushes + ; decrement the stack pointer. Already have + ; + ; Offset 8: Return PC is already on the stack + ; Offset 7: AF (retaining flags) + ; + ; IRQ number is in A + + push hl ; Offset 6: HL + ld hl, #(3*2) ; HL is the value of the stack pointer before + add hl, sp ; the interrupt occurred + push hl ; Offset 5: Stack pointer + push iy ; Offset 4: IY + push ix ; Offset 3: IX + push de ; Offset 2: DE + push bc ; Offset 1: BC + + ld b, a ; Save the reset number in B + ld a, i ; Parity bit holds interrupt state + push af ; Offset 0: I with interrupt state in parity + di + + ; Call the interrupt decode logic. SP points to the beginning of the reg structure + + ld hl, #0 ; Argument #2 is the beginning of the reg structure + add hl, sp ; + push hl ; Place argument #2 at the top of stack + push bc ; Argument #1 is the Reset number + inc sp ; (make byte sized) + call _up_doirq ; Decode the IRQ + + ; On return, HL points to the beginning of the reg structure to restore + ; Note that (1) the arguments pushed on the stack are not popped, and (2) the + ; original stack pointer is lost. In the normal case (no context switch), + ; HL will contain the value of the SP before the arguments were pushed. + + ld sp, hl ; Use the new stack pointer + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in carry + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + ld hl, #-2 ; Offset of SP to account for ret addr on stack + pop de ; Offset 5: HL' = Stack pointer after return + add hl, de ; HL = Stack pointer value before return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + ld sp, hl ; Set SP = saved stack pointer value before return + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, nointenable ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes + reti +nointenable:: + ex af, af' ; Restore AF + reti diff --git a/arch/z80/src/z180/z180_vectors.asm b/arch/z80/src/z180/z180_vectors.asm new file mode 100644 index 0000000000000000000000000000000000000000..3bda5c470278bb20c980579af5f50cf9b00d26f6 --- /dev/null +++ b/arch/z80/src/z180/z180_vectors.asm @@ -0,0 +1,84 @@ +;************************************************************************** +; arch/z80/src/z180/z180_vectors.asm +; +; Copyright (C) 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z180 + .module z180_vectors + +;************************************************************************** +; Constants +;************************************************************************** + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _up_int1 ; Vector offset 0: External /INT1 + .globl _up_int2 ; Vector offset 2: External /INT2 + .globl _up_prt0 ; Vector offset 4: PRT channel 0 + .globl _up_prt1 ; Vector offset 6: PRT channel 1 + .globl _up_dma0 ; Vector offset 8: DMA channel 0 + .globl _up_dma1 ; Vector offset 8: DMA channel 1 + .globl _up_csio ; Vector offset 12: Clocked serial I/O + .globl _up_asci0 ; Vector offset 14: Async channel 0 + .globl _up_asci1 ; Vector offset 16: Async channel 1 + .globl _up_unused ; Vector offset 18: Unused + +;************************************************************************** +; Interrupt Vector Table +;************************************************************************** + +; The Vector Table is located at address 0x0040, between the RST vectors +; and the NMI vector + + .area _VECTORS (ABS) + .org 0x0040 + +_up_vectors:: + .dw _up_int1 ; Vector offset 0: External /INT1 + .dw _up_int2 ; Vector offset 2: External /INT2 + .dw _up_prt0 ; Vector offset 4: PRT channel 0 + .dw _up_prt1 ; Vector offset 6: PRT channel 1 + .dw _up_dma0 ; Vector offset 8: DMA channel 0 + .dw _up_dma1 ; Vector offset 8: DMA channel 1 + .dw _up_csio ; Vector offset 12: Clocked serial I/O + .dw _up_asci0 ; Vector offset 14: Async channel 0 + .dw _up_asci1 ; Vector offset 16: Async channel 1 + .dw _up_unused ; Vector offset 18: Unused + .dw _up_unused ; Vector offset 20: Unused + .dw _up_unused ; Vector offset 22: Unused + .dw _up_unused ; Vector offset 24: Unused + .dw _up_unused ; Vector offset 26: Unused + .dw _up_unused ; Vector offset 28: Unused + .dw _up_unused ; Vector offset 30: Unused \ No newline at end of file diff --git a/arch/z80/src/z8/Kconfig b/arch/z80/src/z8/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d7e514031047453e19018cfa04f67cc36d40a19a --- /dev/null +++ b/arch/z80/src/z8/Kconfig @@ -0,0 +1,40 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_Z8 + +# UART0/1 always enabled + +config Z8_UART0 + bool + default y + select ARCH_HAVE_UART0 + +config Z8_UART1 + bool + default y + select ARCH_HAVE_UART1 + +# The ZiLOG ZDS-II Windows toolchain is the only toolchain available for +# the ez80. +# + +config Z8_TOOLCHAIN_ZDSII + bool + default y if ARCH_CHIP_Z8 + default n if !ARCH_CHIP_Z8 + +choice + prompt "ZDS-II Toolchain version" + default EZ80_ZDSII_V521 + +config Z8_ZDSII_V500 + bool "ZDS-II 5.0.0" + +config Z8_ZDSII_V522 + bool "ZDS-II 5.2.2" + +endchoice # ZDS-II Toolchain version +endif # ARCH_CHIP_Z8 diff --git a/arch/z80/src/z8/Make.defs b/arch/z80/src/z8/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..7a7476aa4f0fe56ffa33e9a9a7abe2a5c10cb48a --- /dev/null +++ b/arch/z80/src/z8/Make.defs @@ -0,0 +1,52 @@ +############################################################################ +# arch/z80/src/z8/Make.defs +# +# Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_SSRC = z8_head.S + +CMN_SSRCS = +CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c +CMN_CSRCS += up_releasestack.c up_interruptcontext.c up_blocktask.c +CMN_CSRCS += up_unblocktask.c up_exit.c up_releasepending.c +CMN_CSRCS += up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c +CMN_CSRCS += up_mdelay.c up_stackframe.c up_udelay.c up_usestack.c + +CHIP_SSRCS = z8_vector.S z8_saveusercontext.S z8_restorecontext.S +CHIP_CSRCS = z8_initialstate.c z8_irq.c z8_saveirqcontext.c +CHIP_CSRCS += z8_schedulesigaction.c z8_sigdeliver.c z8_lowuart.c +CHIP_CSRCS += z8_serial.c z8_i2c.c z8_registerdump.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += z8_timerisr.c +endif diff --git a/arch/z80/src/z8/Toolchain.defs b/arch/z80/src/z8/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..9aaf1b89ced10dac10891905eba98f91bd326efb --- /dev/null +++ b/arch/z80/src/z8/Toolchain.defs @@ -0,0 +1,47 @@ +############################################################################ +# arch/z80/src/z8/Toolchain.defs +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# The ZiLOG ZDS-II Windows toolchain is the only toolchain available for +# the z8. +# + +CONFIG_Z8_TOOLCHAIN ?= ZDSII + +ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y +endif diff --git a/arch/z80/src/z8/chip.h b/arch/z80/src/z8/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..b85b478f13829167ee4aff56b21cdd708780c456 --- /dev/null +++ b/arch/z80/src/z8/chip.h @@ -0,0 +1,239 @@ +/************************************************************************************ + * arch/z80/src/z8/chip.h + * arch/z80/src/chip/chip.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __Z8_CHIP_H +#define __Z8_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Hexadecimal Representation *******************************************************/ + +#ifdef __ASSEMBLY__ +# define _HX(h) %##h +#else +# define _HX(h) 0x##h +#endif + +/* Memory Map + * + * 64Kb Program Memory (64K series) + * C:0000 - C:0001 : Flash options + * C:0002 - C:0037 : Vectors + * : ROM data + * : Code + * + * 4Kb Register File (64K series) + * R:020 - R:0ff : 224 byte RDATA + * R:0e0 - R:0ef : 16-byte working register area (RDATA) + * E:100 - E:eff : 3.5 Kbyte EDATA + * f00 - fff : 256 byte control register area + */ + +/* Special Function Registers ******************************************************* + * + * Because of the many different ez80 configurations, we will rely on the + * ZDS-II header file, ez8.h, to provide the correct addresses for each register. + */ + +/* Timer Register Bit Definitions ***************************************************/ + +/* Timer control register */ + +#define Z8_TIMERCTL_TEN _HX(80) /* Bit 7: Timer enabled */ +#define Z8_TIMERCTL_TPOL _HX(40) /* Bit 6: Timer input/output polarity */ +#define Z8_TIMERCTL_DIV1 _HX(00) /* Bits 3-5: Pre-scale divisor */ +#define Z8_TIMERCTL_DIV2 _HX(08) +#define Z8_TIMERCTL_DIV4 _HX(10) +#define Z8_TIMERCTL_DIV8 _HX(18) +#define Z8_TIMERCTL_DIV16 _HX(20) +#define Z8_TIMERCTL_DIV32 _HX(28) +#define Z8_TIMERCTL_DIV64 _HX(30) +#define Z8_TIMERCTL_DIV128 _HX(38) +#define Z8_TIMERCTL_ONESHOT _HX(00) /* Bits 0-2: Timer mode */ +#define Z8_TIMERCTL_CONT _HX(01) +#define Z8_TIMERCTL_COUNTER _HX(02) +#define Z8_TIMERCTL_PWM _HX(03) +#define Z8_TIMERCTL_CAPTURE _HX(04) +#define Z8_TIMERCTL_COMPARE _HX(05) +#define Z8_TIMERCTL_GATED _HX(06) +#define Z8_TIMERCTL_CAPCMP _HX(07) + +/* UART Register Offsets *************************************************************/ + +#define Z8_UART_TXD _HX(00) /* 8-bits: UART Transmit Data */ +#define Z8_UART_RXD _HX(00) /* 8-bits: UART Receive Data */ +#define Z8_UART_STAT0 _HX(01) /* 8-bits: UART Status 0 */ +#define Z8_UART_CTL _HX(02) /* 16-bits: UART Control */ +#define Z8_UART_CTL0 _HX(02) /* 8-bits: UART Control 0 */ +#define Z8_UART_CTL1 _HX(03) /* 8-bits: UART COntrol 1 */ +#if defined(_Z8FMC16) || defined(_Z8F1680) +# define Z8_UART_MDSTAT _HX(04) /* 8-bits: UART Mode Select & Status */ +#else +# define Z8_UART_STAT1 _HX(04) /* 8-bits: UART Status 1 */ +#endif +#define Z8_UART_ADDR _HX(05) /* 8-bits: UART Address Compare */ +#define Z8_UART_BR _HX(06) /* 16-bits: UART Baud Rate */ +#define Z8_UART_BRH _HX(06) /* 8-bits: UART Baud Rate High Byte */ +#define Z8_UART_BRL _HX(07) /* 8-bits: UART Baud Rate Low Byte */ + +/* UART0/1 Base Register Addresses **************************************************/ + +#ifdef EZ8_UART0 +# define Z8_UART0_BASE ((uint8_t volatile far*)0xf40) +#endif + +#ifdef EZ8_UART1 +# define Z8_UART1_BASE ((uint8_t volatile far*)0xf48) +#endif + +/* UART0/1 Status 0 Register Bit Definitions ****************************************/ + +#define Z8_UARTSTAT0_RDA _HX(80) /* Bit 7: Receive Data Available */ +#define Z8_UARTSTAT0_PE _HX(40) /* Bit 6: Parity Error */ +#define Z8_UARTSTAT0_OE _HX(20) /* Bit 5: Overrun Error */ +#define Z8_UARTSTAT0_FE _HX(10) /* Bit 4: Framing Error */ +#define Z8_UARTSTAT0_BRKD _HX(08) /* Bit 3: Break Detect */ +#define Z8_UARTSTAT0_TDRE _HX(04) /* Bit 2: Transmitter Data Register Empty */ +#define Z8_UARTSTAT0_TXE _HX(02) /* Bit 1: Transmitter Empty */ +#define Z8_UARTSTAT0_CTS _HX(01) /* Bit 0: Clear To Send */ + +/* UART0/1 Control 0/1 Register Bit Definitions *************************************/ + +#define Z8_UARTCTL0_TEN _HX(80) /* Bit 7: Transmit Enable */ +#define Z8_UARTCTL0_REN _HX(40) /* Bit 6: Receive Enable */ +#define Z8_UARTCTL0_CTSE _HX(20) /* Bit 5: CTS Enable */ +#define Z8_UARTCTL0_PEN _HX(10) /* Bit 4: Parity Enable */ +#define Z8_UARTCTL0_PSEL _HX(08) /* Bit 3: Odd Parity Select */ +#define Z8_UARTCTL0_SBRK _HX(04) /* Bit 2: Send Break */ +#define Z8_UARTCTL0_STOP _HX(02) /* Bit 1: Stop Bit Select */ +#define Z8_UARTCTL0_LBEN _HX(01) /* Bit 0: Loopback Enable */ + +#define Z8_UARTCTL1_MPMD1 _HX(80) /* Bit 7: Multiprocessor Mode (bit1) */ +#define Z8_UARTCTL1_MPEN _HX(40) /* Bit 6: Multiprocessor Enable */ +#define Z8_UARTCTL1_MPMD0 _HX(20) /* Bit 5: Multiprocessor Mode (bit0) */ +#define Z8_UARTCTL1_MPBT _HX(10) /* Bit 4: Multiprocessor Bit Transmit */ +#define Z8_UARTCTL1_DEPOL _HX(08) /* Bit 3: Driver Enable Polarity */ +#define Z8_UARTCTL1_BRGCTL _HX(04) /* Bit 2: Baud Rate Generator Control */ +#define Z8_UARTCTL1_RDAIRQ _HX(02) /* Bit 1: Receive Data Interrupt Enable */ +#define Z8_UARTCTL1_IREN _HX(01) /* Bit 0: Infrared Encoder/Decoder Eanble */ + +/* UART0/1 Mode Status/Select Register Bit Definitions ******************************/ + +#define Z8_UARTMDSEL_NORMAL _HX(00) /* Bits 5-7=0: Multiprocessor and Normal Mode */ +#define Z8_UARTMDSEL_FILTER HX(20) /* Bits 5-7=1: Noise Filter Control/Status */ +#define Z8_UARTMDSEL_LINP HX(40) /* Bits 5-7=2: LIN protocol Contol/Status */ +#define Z8_UARTMDSEL_HWREV HX(e0) /* Bits 5-7=7: LIN-UART Hardware Revision */ + /* Bits 0-4: Mode dependent status */ + +/* I2C Status Register Bit Definitions **********************************************/ + +#if defined(_Z8FMC16) || defined(_Z8F1680) +# define I2C_ISTAT_NCKI (1 << 0) /* Bit 0: 1=NAK Interrupt */ +# define I2C_ISTAT_SPRS (1 << 1) /* Bit 1: 1=STOP/RESTART condition Interrupt */ +# define I2C_ISTAT_ARBLST (1 << 2) /* Bit 2: 1=Arbitration lost */ +# define I2C_ISTAT_RD (1 << 3) /* Bit 3: 1=Read */ +# define I2C_ISTAT_GCA (1 << 4) /* Bit 4: 1=General Call Address */ +# define I2C_ISTAT_SAM (1 << 5) /* Bit 5: 1=Slave address match */ +# define I2C_ISTAT_RDRF (1 << 6) /* Bit 6: 1=Receive Data Register Full */ +# define I2C_ISTAT_TDRE (1 << 7) /* Bit 7: 1=Transmit Data Register Empty */ +#else +# define I2C_STAT_NCKI (1 << 0) /* Bit 0: 1=NAK Interrupt */ +# define I2C_STAT_DSS (1 << 1) /* Bit 1: 1=Data Shift State */ +# define I2C_STAT_TAS (1 << 2) /* Bit 2: 1=Transmit Address State */ +# define I2C_STAT_RD (1 << 3) /* Bit 3: 1=Read */ +# define I2C_STAT_10B (1 << 4) /* Bit 4: 1=10-Bit Address */ +# define I2C_STAT_ACK (1 << 5) /* Bit 5: 1=Acknowledge */ +# define I2C_STAT_RDRF (1 << 6) /* Bit 6: 1=Receive Data Register Full */ +# define I2C_STAT_TDRE (1 << 7) /* Bit 7: 1=Transmit Data Register Empty */ +#endif + +/* I2C Control Register Bit Definitions *********************************************/ + +#define I2C_CTL_FILTEN (1 << 0) /* Bit 0: 1=I2C Signal Filter Enable */ +#define I2C_CTL_FLUSH (1 << 1) /* Bit 1: 1=Flush Data */ +#define I2C_CTL_NAK (1 << 2) /* Bit 2: 1=Send NAK */ +#define I2C_CTL_TXI (1 << 3) /* Bit 3: 1=Enable TDRE interrupts */ +#define I2C_CTL_BIRQ (1 << 4) /* Bit 4: 1=Baud Rate Generator Interrupt Request */ +#define I2C_CTL_STOP (1 << 5) /* Bit 5: 1=Send Stop Condition */ +#define I2C_CTL_START (1 << 6) /* Bit 6: 1=Send Start Condition */ +#define I2C_CTL_IEN (1 << 7) /* Bit 7: 1=I2C Enable */ + +/* Register access macros *********************************************************** + * + * The register access mechanism provided in ez8.h differs from the useful in other + * NuttX architectures. The following NuttX common macros will at least make the + * access compatible at the source level (however, strict type check is lost). + */ + +#ifndef __ASSEMBLY__ +# define getreg8(a) (a) +# define putreg8(v,a) (a) = (v) +# define getreg16(a) (a) +# define putreg16(v,a) (a) = (v) +# define getreg32(a) (a) +# define putreg32(v,a) (a) = (v) +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __Z8_CHIP_H */ diff --git a/arch/z80/src/z8/switch.h b/arch/z80/src/z8/switch.h new file mode 100644 index 0000000000000000000000000000000000000000..b8e23f597b8fc2049943223bc9d8cdbdd06da12f --- /dev/null +++ b/arch/z80/src/z8/switch.h @@ -0,0 +1,258 @@ +/************************************************************************************ + * arch/z80/src/z8/switch.h + * arch/z80/src/chip/switch.h + * + * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __Z80_SWITCH_H +#define __Z80_SWITCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif +#include "common/up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Z8_IRQSTATE_* definitions ******************************************************** + * These are used in the state field of 'struct z8_irqstate_s' structure to define + * the current state of the interrupt handling. These definition support "lazy" + * interrupt context saving. See comments below associated with s'truct z8_irqstate_s'. + */ + +#define Z8_IRQSTATE_NONE 0 /* Not handling an interrupt */ +#define Z8_IRQSTATE_ENTRY 1 /* In interrupt, context has not been saved */ +#define Z8_IRQSTATE_SAVED 2 /* In interrupt, context has been saved */ + +/* The information saved on interrupt entry can be retained in a array of two + * uint24_t values. These are + * + * value[0] = RP (MS byte) and Flags (LS) byte + * value[1] = PC + * + * The pointer to the save structure is a stack pointer at the time that up_doirq() + * was called: + * + * PC[7:0] + * PC[15:8] + * Flags Register + * SP -> RP + * + * The stack pointer on return from interrupt can be obtained by adding 4 to the + * pointer to the save structure. + */ + +#define Z8_IRQSAVE_RPFLAGS (0) /* Index 10: RP (MS) and FLAGS (LS) */ +#define Z8_IRQSAVE_PC (1) /* Index 2: PC[8:15] */ +#define Z8_IRQSAVE_REGS (2) /* Number 16-bit values saved */ + +/* Byte offsets */ + +#define Z8_IRQSAVE_RP_OFFS (2*Z8_IRQSAVE_RPFLAGS) /* Offset 0: RP */ +#define Z8_IRQSAVE_FLAGS_OFFS (2*Z8_IRQSAVE_RPFLAGS+1) /* Offset 1: FLAGS */ +#define Z8_IRQSAVE_PCH_OFFS (2*Z8_IRQSAVE_PC) /* Offset 2: PC[8:15] */ +#define Z8_IRQSAVE_PCL_OFFS (2*Z8_IRQSAVE_PC+1) /* Offset 3: PC[0:7] */ +#define Z8_IRQSAVE_SIZE (2*Z8_IRQSAVE_REGS) /* Number 8-bit values saved */ + +/* Macros for portability *********************************************************** + * + * Common logic in arch/z80/src/common is customized for the z8 context switching + * logic via the following macros. + */ + +/* Initialize the IRQ state */ + +#define INIT_IRQCONTEXT() \ + do { \ + g_z8irqstate.state = Z8_IRQSTATE_NONE; \ + } while (0) + +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt + * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). + */ + +#define IN_INTERRUPT() \ + (g_z8irqstate.state != Z8_IRQSTATE_NONE) + +/* The following macro is used when the system enters interrupt handling logic + * + * NOTE: Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to change the way that + * g_current_regs is handled. The savestate variable would not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + +#define DECL_SAVESTATE() \ + struct z8_irqstate_s savestate + +#define IRQ_ENTER(irq, regs) \ + do { \ + savestate.state = g_z8irqstate.state; \ + savestate.regs = g_z8irqstate.regs; \ + g_z8irqstate.state = Z8_IRQSTATE_ENTRY; \ + g_z8irqstate.regs = (regs); \ + up_ack_irq(irq); \ + } while (0) + +/* The following macro is used when the system exits interrupt handling logic */ + +#define IRQ_LEAVE(irq) \ + do { \ + g_z8irqstate.state = savestate.state; \ + g_z8irqstate.regs = savestate.regs; \ + } while (0) + +/* The following macro is used to sample the interrupt state (as a opaque handle) */ + +#define IRQ_STATE() \ + (g_z8irqstate.regs) + +/* Save the current IRQ context in the specified TCB */ + +#define SAVE_IRQCONTEXT(tcb) \ + z8_saveirqcontext((tcb)->xcp.regs) + +/* Set the current IRQ context to the state specified in the TCB */ + +#define SET_IRQCONTEXT(tcb) \ + do { \ + g_z8irqstate.state = Z8_IRQSTATE_SAVED; \ + g_z8irqstate.regs = (tcb)->xcp.regs; \ + } while (0) + +/* Save the user context in the specified TCB. User context saves can be simpler + * because only those registers normally saved in a C called need be stored. + */ + +#define SAVE_USERCONTEXT(tcb) \ + z8_saveusercontext((tcb)->xcp.regs) + +/* Restore the full context -- either a simple user state save or the full, + * IRQ state save. + */ + +#define RESTORE_USERCONTEXT(tcb) \ + z8_restorecontext((tcb)->xcp.regs) + +/* Dump the current machine registers */ + +#define _REGISTER_DUMP() \ + z8_registerdump() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* In order to provide faster interrupt handling, the interrupt logic does "lazy" + * context saving as described below: + * + * (1) At the time of the interrupt, minimum information is saved and the register + * pointer is changed so that the interrupt logic does not alter the state of + * the interrupted task's registers. + * (2) If no context switch occurs during the interrupt processing, then the return + * from interrupt is also simple. + * (3) If a context switch occurs during interrupt processing, then + * (a) The full context of the interrupt task is saved, and + * (b) A full context switch is performed when the interrupt exits (see + * z8_vector.S). + * + * The following structure is used to manage this "lazy" context saving. + */ + +#ifndef __ASSEMBLY__ +struct z8_irqstate_s +{ + uint8_t state; /* See Z8_IRQSTATE_* definitions above */ + chipreg_t *regs; /* Saved register information */ +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This structure holds information about the current interrupt processing state */ + +extern struct z8_irqstate_s g_z8irqstate; +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Defined in z8_irq.c */ + +void up_ack_irq(int irq); + +/* Defined in z8_saveusercontext.asm */ + +int z8_saveusercontext(FAR chipreg_t *regs); + +/* Defined in z8_saveirqcontext.c */ + +void z8_saveirqcontext(FAR chipreg_t *regs); + +/* Defined in z8_restorecontext.asm */ + +void z8_restorecontext(FAR chipreg_t *regs); + +/* Defined in z8_sigsetup.c */ + +void z8_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs); + +/* Defined in z8_registerdump.c */ + +void z8_registerdump(void); + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __Z80_SWITCH_H */ diff --git a/arch/z80/src/z8/up_mem.h b/arch/z80/src/z8/up_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..fe6854b4764e51d3c5ff6450646834951810b673 --- /dev/null +++ b/arch/z80/src/z8/up_mem.h @@ -0,0 +1,89 @@ +/************************************************************************************ + * arch/z80/src/z8/up_mem.h + * arch/z80/src/chip/up_mem.h + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __Z8_UP_MEM_H +#define __Z8_UP_MEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* For the ZiLOG ZDS-II toolchain(s), the heap will be set using linker- + * defined values: + * + * far_heapbot : set to the offset to the first unused value in EDATA + * far_stacktop : set to the highest address in EDATA + * + * The top of the heap is then determined by the amount of stack setaside + * in the NuttX configuration file + */ + +#ifndef CONFIG_HEAP1_BASE + extern far unsigned long far_heapbot; +# define CONFIG_HEAP1_BASE ((uint16_t)&far_heapbot) +#endif + +#ifndef CONFIG_HEAP1_END + extern far unsigned long far_stacktop; +# define CONFIG_HEAP1_END (((uint16_t)&far_stacktop) - CONFIG_IDLETHREAD_STACKSIZE + 1) +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __Z8_UP_MEM_H */ diff --git a/arch/z80/src/z8/z8_head.S b/arch/z80/src/z8/z8_head.S new file mode 100644 index 0000000000000000000000000000000000000000..a211e2702126f4f136578338d8f4a7d6fb4595d2 --- /dev/null +++ b/arch/z80/src/z8/z8_head.S @@ -0,0 +1,253 @@ +/************************************************************************** + * arch/z80/src/z8/z8_head.S + * ez8 Reset Entry Point + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER or CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, or CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS or SERVICES; LOSS + * OF USE, DATA, or PROFITS; or BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, or TORT (INCLUDING NEGLIGENCE or OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include +#include + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/* Assume the large model */ + +#if !defined(CONFIG_Z8_MODEL_LARGE) && !defined(CONFIG_Z8_MODEL_SMALL) +# define CONFIG_Z8_MODEL_LARGE 1 +# undef CONFIG_Z8_MODEL_SMALL +#endif + +#ifdef __Z8F1680 +# define CONFIG_Z8_COPYPRAM +#else +# undef CONFIG_Z8_COPYPRAM +#endif + + +/************************************************************************** + * External References / External Definitions + **************************************************************************/ + + xref _z16f_clkinit:ROM + xref _z16f_lowinit:ROM +#ifdef CONFIG_ARCH_LEDS + xref _board_autoled_initialize:ROM +#endif + xref _os_start:ROM + xref _up_doirq:ROM + xref _low_nearbss + xref _len_nearbss + xref _low_farbss + xref _len_farbss + xref _low_neardata + xref _len_neardata + xref _low_near_romdata + xref _low_fardata + xref _len_fardata + xref _low_far_romdata +#ifdef CONFIG_Z8_COPYPRAM + xref _low_pramseg + xref _len_pramseg + xref _low_pram_romdata +#endif + xref _far_stacktop + xdef _z8_reset + xdef __intrp + +/************************************************************************** + * Code + **************************************************************************/ + + segment CODE + +/************************************************************************** + * Interrupt Vectors + **************************************************************************/ + + /* Reset vector */ + + vector RESET = _z8_reset + +/************************************************************************** + * Name: _z16f_reset + * + * Description: + * Reset entry point + * + **************************************************************************/ + + define startup, space=rom + segment startup +_z8_reset: + /* Set the register pointer for working registers e0-ef */ + + srp #%e0 + + /* Initialize the stack pointer */ + + ldx spl, #low(_far_stacktop+1) + ldx sph, #high(_far_stacktop+1) + + /* Clear internal register ram area (c_nearbss) */ + + ld r0, #_low_nearbss + ld r2, #_len_nearbss + cp r2, #0 + jr z, _z8_reset2 + +_z8_reset1: + clr @r0 + inc r0 + djnz r2, _z8_reset1 + + /* Clear extended ram area (c_farbss) */ + +_z8_reset2: + ld r2, #high(_low_farbss) + ld r3, #low(_low_farbss) + ld r0, #high(_len_farbss) + ld r1, #low(_len_farbss) + + ld r4, r0 + or r4, r1 + jr z, _z8_reset4 + clr r4 + +_z8_reset3: + ldx @rr2,r4 + incw rr2 + decw rr0 + jr nz, _z8_reset3 + + /* Copy ROM data into internal RAM */ + +_z8_reset4: +#ifdef CONFIG_Z8_COPYNEARDATA + ld r0, #high(_low_near_romdata) + ld r1, #low(_low_near_romdata) + ld r3, #_len_neardata + ld r4, #_low_neardata + cp r3, #0 + jr z, _z8_reset6 + +_z8_reset5: + ldci @r4, @rr0 + djnz r3, _z8_reset5 + +_z8_reset6: +#endif + /* Copy ROM data into extended RAM */ + + ld r0, #high(_low_fardata) + ld r1, #low(_low_fardata) + ld r2, #high(_low_far_romdata) + ld r3, #low(_low_far_romdata) + ld r4, #high(_len_fardata) + ld r5, #low(_len_fardata) + + ld r6, r4 + or r6, r5 + jr z, _z8_reset8 + +_z8_reset7: + ldc r6, @rr2 + ldx @rr0, r6 + incw rr0 + incw rr2 + decw rr4 + jr nz, _z8_reset7 + + /* Copy ROM copy of code into Program RAM */ + +_z8_reset8: +#ifdef CONFIG_Z8_COPYPRAM + ld r0, #high(_low_pramseg) + ld r1, #low(_low_pramseg) + ld r2, #high(_low_pram_romdata) + ld r3, #low(_low_pram_romdata) + ld r4, #high(_len_pramseg) + ld r5, #low(_len_pramseg) + + ld r6, r4 + or r6, r5 + jr z, _z8_reset10 + +_z8_reset9: + ldc r6, @rr2 + ldc @rr0, r6 + incw rr0 + incw rr2 + decw rr4 + jr nz, _z8_reset9 + +_z8_reset10: +#endif + + /* Start NuttX */ + + ldx __intrp,#0 + xor r15, r15 + xor r14, r14 + call _os_start + + /* We should never get here */ + +_z8_reset_halt: + jr _z8_reset_halt + +/************************************************************************** + * Data + **************************************************************************/ + +#ifdef CONFIG_Z8_MODEL_LARGE + segment FAR_BSS +__intrp ds 1 +#else + segment NEAR_BSS +__intrp ds 1 +#endif + + /* Set aside area for working registers */ + + define workingreg, space=rdata, org=%e0 + segment workingreg + ds %10 + + end _z8_reset diff --git a/arch/z80/src/z8/z8_i2c.c b/arch/z80/src/z8/z8_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..cc3508a564ce7549ddb2fc9ac9cfabf7534bcfdd --- /dev/null +++ b/arch/z80/src/z8/z8_i2c.c @@ -0,0 +1,682 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_i2c.c + * + * Copyright(C) 2009, 2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include /* eZ8 Register definitions */ +#include "chip.h" /* Register bit definitions */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define Z8_NOSTOP (1 << 0) /* Bit 0: No STOP on this transfer */ +#define Z8_NOSTART (1 << 1) /* Bit 1: No address or START on this tranfers */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct z8_i2cdev_s +{ + const struct i2c_ops_s *ops; /* I2C vtable */ + uint32_t frequency; /* Currently selected I2C frequency */ + uint16_t brg; /* Baud rate generator value */ + uint8_t addr; /* 8-bit address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Misc. Helpers */ + +static void z8_i2c_waittxempty(void); +static void z8_i2c_waitrxavail(void); +static void z8_i2c_setbrg(uint16_t brg); +static uint16_t z8_i2c_getbrg(uint32_t frequency); +static int z8_i2c_read_transfer(FAR struct z8_i2cdev_s *priv, + FAR uint8_t *buffer, int buflen, uint8_t flags); +static int z8_i2c_write_transfer(FAR struct z8_i2cdev_s *priv, + FAR const uint8_t *buffer, int buflen, uint8_t flags); +static void z8_i2c_setfrequency(FAR struct z8_i2cdev_s *priv, + uint32_t frequency); + +/* I2C methods */ + +static int z8_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int z8_i2c_reset(FAR struct i2c_master_s *dev); +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* This function is normally prototyped int the ZiLOG header file sio.h */ + +extern uint32_t get_freq(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool g_initialized; /* true:I2C has been initialized */ +static sem_t g_i2csem; /* Serialize I2C transfers */ + +const struct i2c_ops_s g_ops = +{ + z8_i2c_transfer, +#ifdef CONFIG_I2C_RESET + , z8_i2c_reset +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: z8_i2c_semtake/z8_i2c_semgive + * + * Description: + * Take/Give the I2C semaphore. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void z8_i2c_semtake(void) +{ + /* Take the I2C semaphore (perhaps waiting) */ + + while (sem_wait(&g_i2csem) != 0) + { + /* The only case that an error should occr here is if + * the wait was awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +#define z8_i2c_semgive() sem_post(&g_i2csem) + +/**************************************************************************** + * Name: z8_i2c_waittxempty + * + * Description: + * Wait for the transmit data register to become empty. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void z8_i2c_waittxempty(void) +{ + int i; + for (i = 0; i < 10000 && (I2CSTAT & I2C_STAT_TDRE) == 0; i++); +} + +/**************************************************************************** + * Name: z8_i2c_waitrxavail + * + * Description: + * Wait until we have received a full byte of data. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void z8_i2c_waitrxavail(void) +{ + int i; + for (i = 0; i <= 10000 && (I2CSTAT & (I2C_STAT_RDRF | I2C_STAT_NCKI)) == 0; i++); +} + +/**************************************************************************** + * Name: z8_i2c_setbrg + * + * Description: + * Set the current BRG value for this transaction + * + * Input Parameters: + * brg - BRG to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void z8_i2c_setbrg(uint16_t brg) +{ + I2CBRH = (uint8_t)(brg >> 8); + I2CBRL = (uint8_t)(brg & 0xff); +} + +/**************************************************************************** + * Name: z8_i2c_getbrg + * + * Description: + * Calculate the BRG value + * + * Input Parameters: + * frequency - The I2C frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint16_t z8_i2c_getbrg(uint32_t frequency) +{ + uint32_t sysclock = get_freq(); + + /* Max is 400 Kb/sec */ + + if (frequency > 400*1000) + { + dbg("Invalid inputs\n"); + frequency = 400*1000; + } + + /* BRG = sysclock / (4 * frequency) */ + + return ((sysclock >> 2) + (frequency >> 1)) / frequency; +} + +/**************************************************************************** + * Name: z8_i2c_read_transfer + * + * Description: + * Receive a block of data from I2C using the previously selected I2C + * frequency and slave address. Each read operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this read completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to a buffer of data to receive the data from the device + * buflen - The requested number of bytes to be read + * flags - Determines is a START and/or STOP indication is needed. + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +static int z8_i2c_read_transfer(FAR struct z8_i2cdev_s *priv, + FAR uint8_t *buffer, int buflen, + uint8_t flags) +{ + FAR uint8_t *ptr; + int retry; + int count; + + /* Retry as necessary to receive the whole message */ + + for (retry = 0; retry < 100; retry++) + { + if ((flags & Z8_NOSTART) == 0) + { + /* Load the address into the transmit register. It is not sent + * until the START bit is set. + */ + + I2CD = I2C_READADDR8(priv->addr); + + /* If we want only a single byte of data, then set the NACK + * bit now. + */ + + I2CCTL |= I2C_CTL_NAK; + + /* The START bit begins the transaction */ + + I2CCTL |= I2C_CTL_START; + } + + /* Now loop to receive each data byte */ + + ptr = buffer; + for (count = buflen; count; count--) + { + /* Wait for the receive buffer to fill */ + + z8_i2c_waitrxavail(); + + /* Did we get a byte? Or did an error occur? */ + + if (I2CSTAT & I2C_STAT_RDRF) + { + /* Save the data byte */ + + *ptr++ = I2CD; + + /* If the next byte is the last byte, then set NAK now */ + + if (count == 2 && (flags & Z8_NOSTOP) == 0) + { + I2CCTL |= I2C_CTL_NAK; + } + + /* If this was the last byte, then set STOP and return success */ + + else if (count == 1) + { + if ((flags & Z8_NOSTOP) == 0) + { + I2CCTL |= I2C_CTL_STOP; + } + + return OK; + } + } + + /* An error occurred. Clear byte bus and break out of the loop + * to retry now. + */ + + else + { + /* No, flush the buffer and toggle the I2C on and off */ + + I2CCTL |= I2C_CTL_FLUSH; + I2CCTL &= ~I2C_CTL_IEN; + I2CCTL |= I2C_CTL_IEN; + + /* Break out of the loop early and try again */ + + break; + } + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: z8_i2c_write_transfer + * + * Description: + * Send a block of data on I2C using the previously selected I2C + * frequency and slave address. Each write operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this write completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the read-only buffer of data to be written to device + * buflen - The number of bytes to send from the buffer + * flags - Determines is a START and/or STOP indication is needed. + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +static int z8_i2c_write_transfer(FAR struct z8_i2cdev_s *priv, + FAR const uint8_t *buffer, int buflen, + uint8_t flags) +{ + FAR const uint8_t *ptr; + int retry; + int count; + + /* Retry as necessary to send this whole message */ + + for (retry = 0; retry < 100; retry++) + { + if ((flags & Z8_NOSTART) == 0) + { + /* Load the address into the transmit register. It is not sent + * until the START bit is set. + */ + + I2CD = I2C_WRITEADDR8(priv->addr); + I2CCTL |= I2C_CTL_START; + + /* Wait for the xmt buffer to become empty */ + + z8_i2c_waittxempty(); + } + + /* Then send all of the bytes in the buffer */ + + ptr = buffer; + for (count = buflen; count; count--) + { + /* Send a byte of data and wait for it to be sent */ + + I2CD = *ptr++; + z8_i2c_waittxempty(); + + /* If this was the last byte, then send STOP immediately. This + * is because the ACK will not be valid until the STOP clocks out + * the last bit.. Hmmm. If this true then we will never be + * able to send more than one data byte??? + */ + + if (count == 1) + { + if ((flags & Z8_NOSTOP) == 0) + { + I2CCTL |= I2C_CTL_STOP; + } + + /* If this last byte was ACKed, then the whole buffer + * was successfully sent and we can return success. + */ + + if ((I2CSTAT & I2C_STAT_ACK) != 0) + { + return OK; + } + + /* If was was not ACKed, then this inner loop will + * terminated (because count will decrement to zero + * and the whole message will be resent + */ + } + + /* Not the last byte... was this byte ACKed? */ + + else if ((I2CSTAT & I2C_STAT_ACK) == 0) + { + /* No, flush the buffer and toggle the I2C on and off */ + + I2CCTL |= I2C_CTL_FLUSH; + I2CCTL &= ~I2C_CTL_IEN; + I2CCTL |= I2C_CTL_IEN; + + /* Break out of the loop early and try again */ + + break; + } + } + } + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: z8_i2c_setfrequency + * + * Description: + * Set the I2C frequency. This frequency will be retained in the struct + * i2c_master_s instance and will be used with all transfers. Required. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The I2C frequency requested + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void z8_i2c_setfrequency(FAR struct z8_i2cdev_s *priv, + uint32_t frequency) +{ + uint16_t brg; + + /* Has the frequency changed? */ + + if (priv->frequency != frequency) + { + /* Calculate and save the BRG (we won't apply it until the first transfer) */ + + brg = z8_i2c_getbrg(frequency); + z8_i2c_setbrg(brg); + + /* Save the new I2C frequency */ + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: z8_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers, each transfer is started with a + * START and the final transfer is completed with a STOP. Each sequence + * will be an 'atomic' operation in the sense that any other I2C actions + * will be serialized and pend until this read completes. Optional. + * + * Input Parameters: + * dev - Device-specific state data + * msgs - A pointer to a set of message descriptors + * msgcount - The number of transfers to perform + * + * Returned Value: + * The number of transfers completed + * + ****************************************************************************/ + +static int z8_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + FAR struct z8_i2cdev_s *priv = (FAR struct z8_i2cdev_s *)dev; + FAR struct i2c_msg_s *msg; + bool nostop; + uint8_t flags; + int ret = OK; + int i; + + /* Perform each segment of the transfer, message at a time */ + + flags = 0; + + /* Get exclusive access to the I2C bus */ + + z8_i2c_semtake(); + + /* The process each message seqment */ + + for (i = 0; i < count; i++) + { + msg = &msgs[i]; + + /* Set the I2C frequency and address */ + + z8_i2c_setfrequency(priv, msg->frequency); + + priv->addr = msg->addr; + DEBUGASSERT((msg->flags & I2C_M_TEN) == 0); + + /* Is this the last message in the sequence? */ + + nostop = false; + if (i < (count - 1)) + { + FAR struct i2c_msg_s *next; + + /* No... Check if the next message should have a repeated start or + * not. The conditions for NO repeated start are: + * + * - I2C_M_NORESTART bit set + * - Same direction (I2C_M_READ) + * - Same address (and I2C_M_TEN) + */ + + next = &msgs[i + 1]; + if ((msg->flags & I2C_M_NORESTART) != 0 && + (msg->flags & (I2C_M_READ | I2C_M_TEN)) == (next->flags & (I2C_M_READ | I2C_M_TEN)) && + msg->addr == next->addr) + { + nostop = true; + } + } + + /* Perform the read or write operation */ + + flags |= (nostop) ? Z8_NOSTOP : 0; + if ((msg->flags & I2C_M_READ) != 0) + { + ret = z8_i2c_read_transfer(priv, msg->buffer, msg->length, flags); + } + else + { + ret = z8_i2c_write_transfer(priv, msg->buffer, msg->length, flags); + } + + /* Check for I2C transfer errors */ + + if (ret < 0) + { + break; + } + + /* If there was no STOP bit on this segment, then there should be no + * START on the next segment. + */ + + flags = (nostop) ? Z8_NOSTART : 0; + } + + z8_i2c_semgive(); + return ret; +} + +/************************************************************************************ + * Name: z8_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int z8_i2c_reset(FAR struct i2c_master_s * dev) +{ + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has mutiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structre reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *z8_i2cbus_initialize(int port) +{ + FAR struct z8_i2cdev_s *i2c; + + if (!g_initialized) + { + /* Set up some initial BRG value */ + + uint16_t brg = z8_i2c_getbrg(100*1000); + z8_i2c_setbrg(brg); + + /* Make sure that GPIOs are configured for the alternate function (this + * varies with silicon revisions). + */ + + PAADDR = 0x02; + PACTL |= 0xc0; + + /* This semaphore enforces serialized access for I2C transfers */ + + sem_init(&g_i2csem, 0, 1); + + /* Enable I2C -- no interrupts */ + + I2CCTL = I2C_CTL_IEN; + } + + /* Now, allocate an I2C instance for this caller */ + + i2c = (FAR struct z8_i2cdev_s *)kmm_zalloc(sizeof(FAR struct z8_i2cdev_s)); + if (i2c) + { + /* Initialize the allocated instance */ + + i2c->ops = &g_ops; + } + + return (FAR struct i2c_master_s *)i2c; +} diff --git a/arch/z80/src/z8/z8_initialstate.c b/arch/z80/src/z8/z8_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..17299e17a588795a1cdef58d94d0758351acea40 --- /dev/null +++ b/arch/z80/src/z8/z8_initialstate.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_initialstate.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(FAR struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); +#ifndef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */ +#endif + xcp->regs[XCPT_RPFLAGS] = 0xe000; /* RP=%e0 */ + xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; +} diff --git a/arch/z80/src/z8/z8_irq.c b/arch/z80/src/z8/z8_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..17c6881baf3e1eb6870e147450743223c8f0a50a --- /dev/null +++ b/arch/z80/src/z8/z8_irq.c @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_irq.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This structure holds information about the current interrupt processing state */ + +struct z8_irqstate_s g_z8irqstate; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Clear and disable all interrupts. Set all to priority 0. */ + + putreg8(0xff, IRQ0); + putreg8(0xff, IRQ1); + putreg8(0xff, IRQ2); + + putreg16(0x0000, IRQ0EN); + putreg16(0x0000, IRQ1EN); + putreg16(0x0000, IRQ2EN); + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + EI(); +#endif +} + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Disable all interrupts; return previous interrupt state + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) +{ + /* Bit 7 (IRQE) of the IRQCTL register determines if interrupts were + * enabled when this function was called. + */ + + register irqstate_t retval = getreg8(IRQCTL); + + /* Disable interrupts */ + + DI(); + + /* Return the previous interrupt state */ + + return retval; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore previous interrupt state + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t flags) +{ + /* Bit 7 (IRQE) of the IRQCTL register determines if interrupts were + * enabled when up_irq_save() was called. + */ + + if ((flags & 0x80) != 0) + { + /* The IRQE bit was set, re-enable interrupts */ + + EI(); + } +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + /* System exceptions cannot be disabled */ + + if (irq >= Z8_IRQ0_MIN) + { + /* Disable the interrupt by clearing the corresponding bit in the + * appropriate IRQ enable high register. The enable low + * register is assumed to be zero, resulting interrupt disabled. + */ + + if (irq <= Z8_IRQ0_MAX) + { + putreg8((getreg8(IRQ0ENH) & ~Z8_IRQ0_BIT(irq)), IRQ0ENH); + } + else if (irq <= Z8_IRQ1_MAX) + { + putreg8((getreg8(IRQ1ENH) & ~Z8_IRQ1_BIT(irq)), IRQ1ENH); + } + else if (irq < NR_IRQS) + { + putreg8((getreg8(IRQ2ENH) & ~Z8_IRQ2_BIT(irq)), IRQ2ENH); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* System exceptions cannot be disabled */ + + if (irq >= Z8_IRQ0_MIN) + { + /* Enable the interrupt by setting the corresponding bit in the + * appropriate IRQ enable high register. The enable low + * register is assumed to be zero, resulting in "nomimal" interrupt + * priority. + */ + + if (irq <= Z8_IRQ0_MAX) + { + putreg8((getreg8(IRQ0ENH) | Z8_IRQ0_BIT(irq)), IRQ0ENH); + } + else if (irq <= Z8_IRQ1_MAX) + { + putreg8((getreg8(IRQ1ENH) | Z8_IRQ1_BIT(irq)), IRQ1ENH); + } + else if (irq < NR_IRQS) + { + putreg8((getreg8(IRQ2ENH) | Z8_IRQ2_BIT(irq)), IRQ2ENH); + } + } +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the interrupt + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + /* System exceptions cannot be disabled or acknowledged */ + + if (irq >= Z8_IRQ0_MIN) + { + /* Acknowledge the interrupt by setting the* corresponding bit in the + * IRQ status register. + */ + + if (irq <= Z8_IRQ0_MAX) + { + putreg8(Z8_IRQ0_BIT(irq), IRQ0); + } + else if (irq <= Z8_IRQ1_MAX) + { + putreg8(Z8_IRQ1_BIT(irq), IRQ2); + } + else if (irq < NR_IRQS) + { + putreg8(Z8_IRQ2_BIT(irq), IRQ2); + } + } +} diff --git a/arch/z80/src/z8/z8_lowuart.c b/arch/z80/src/z8/z8_lowuart.c new file mode 100644 index 0000000000000000000000000000000000000000..a568a94a9ba884877e67fe0e84690f1fcd3e3dd3 --- /dev/null +++ b/arch/z80/src/z8/z8_lowuart.c @@ -0,0 +1,134 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_loweruart.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/chip.h" +#include "common/up_internal.h" + +#ifdef USE_LOWSERIALINIT + +extern uint32_t get_freq(void); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowserialinit + ****************************************************************************/ + +void up_lowserialinit(void) +{ +#if defined(CONFIG_UART0_SERIAL_CONSOLE) || \ + (defined(EZ8_UART1) && defined(CONFIG_UART1_SERIAL_CONSOLE)) + uint32_t freq = get_freq(); + uint16_t brg; + uint8_t val; +#endif + +#ifdef CONFIG_UART0_SERIAL_CONSOLE + /* Set the baudrate */ + + brg = (freq +(uint32_t)CONFIG_UART0_BAUD * 8) /((uint32_t)CONFIG_UART0_BAUD * 16) ; + + putreg8(brg >> 8, U0BRH); + putreg8(brg & 0xff, U0BRL); + + /* Configure GPIO Port A pins 4 & 5 for alternate function */ + + putreg8(0x02, PAADDR); + val = getreg8(PACTL) | 0x30; /* Set bits in alternate function register */ + putreg8(val, PACTL); + putreg8(0x07, PAADDR); + val = getreg8(PACTL) & 0xcf; /* Reset bits in alternate function set-1 register */ + putreg8(val, PACTL); + putreg8(0x08, PAADDR); + val = getreg8(PACTL) & 0xcf; /* Reset bits in alternate function set-2 register */ + putreg8(val, PACTL); + putreg8(0x00, PAADDR); + + putreg8(0x00, U0CTL1); /* no multi-processor operation mode */ + putreg8(0xc0, U0CTL0); /* Transmit enable, Receive enable, no Parity, 1 Stop bit */ + +#elif defined(EZ8_UART1) && defined(CONFIG_UART1_SERIAL_CONSOLE) + /* Set the baudrate */ + + brg = (freq +(uint32_t)CONFIG_UART1_BAUD * 8) /((uint32_t)CONFIG_UART1_BAUD * 16) ; + + putreg8(brg >> 8, U1BRH); + putreg8(brg & 0xff, U1BRL); + + /* Configure GPIO Port D pins 4 & 5 for alternate function */ + + putreg8(0x02, PAADDR); + val = getreg8(PDCTL) | 0x30; /* Set bits in alternate function register */ + putreg8(val, PDCTL); + putreg8(0x07, PDADDR); + val = getreg8(PDCTL) & 0xcf; /* Reset bits in alternate function set-1 register */ + putreg8(val, PDCTL); + putreg8(0x08, PDADDR); + val = getreg8(PDCTL) & 0xcf; /* Reset bits in alternate function set-2 register */ + putreg8(val, PDCTL); + putreg8(0x00, PDADDR); + + putreg8(0x00, U1CTL1); /* no multi-processor operation mode */ + putreg8(0xc0, U1CTL0); /* Transmit enable, Receive enable, no Parity, 1 Stop bit */ +#endif +} +#endif /* USE_LOWSERIALINIT */ diff --git a/arch/z80/src/z8/z8_registerdump.c b/arch/z80/src/z8/z8_registerdump.c new file mode 100644 index 0000000000000000000000000000000000000000..df6c761a7c942243ad0f02eb9327607c7507376a --- /dev/null +++ b/arch/z80/src/z8/z8_registerdump.c @@ -0,0 +1,137 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_registerdump.c + * + * Copyright (C) 2008-2009,2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void z8_dumpregs(FAR chipret_t *regs) +{ + lldbg("REGS: %04x %04x %04x %04x %04x %04x %04x %04x\n", + regs[XCPT_RR0], regs[XCPT_RR2], regs[XCPT_RR4], regs[XCPT_RR6], + regs[XCPT_RR8], regs[XCPT_RR10], regs[XCPT_RR12], regs[XCPT_RR14]); +} + +static inline void z8_dumpstate(chipreg_t sp, chipreg_t pc, uint8_t irqctl, + chipreg_t rpflags) +{ + lldbg("SP: %04x PC: %04x IRQCTL: %02x RP: %02x FLAGS: %02x\n", + sp, pc, irqctl & 0xff, rpflags >> 8, rpflags & 0xff); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_registerdump + ****************************************************************************/ + +void z8_registerdump(void) +{ + FAR chipret_t *regs; + FAR chipret_t *state; + chipreg_t sp; + uint16_t rp; + + switch (g_z8irqstate.state) + { + case Z8_IRQSTATE_ENTRY: + /* Calculate the source address based on the saved RP value */ + + rp = g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS] >> 8; + regs = (FAR uint16_t*)(rp & 0xf0); + + /* Then dump the register values */ + + z8_dumpregs(regs); + + /* Dump the saved machine state: + * The g_z8irqstate.regs pointer is the value of the stack pointer at + * the time that up_doirq() was called. Therefore, we can calculate + * the correct value for the stack pointer on return from interrupt: + */ + + sp = ((chipreg_t)g_z8irqstate.regs) + Z8_IRQSAVE_SIZE; + z8_dumpstate(sp, g_z8irqstate.regs[Z8_IRQSAVE_PC], 0x80, + g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS]); + break; + + case Z8_IRQSTATE_SAVED: + regs = g_z8irqstate.regs; + z8_dumpregs(regs); + z8_dumpstate(regs[XCPT_SP], regs[XCPT_PC], + regs[XCPT_IRQCTL], regs[XCPT_RPFLAGS]); + break; + + case Z8_IRQSTATE_NONE: + default: + break; + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z80/src/z8/z8_restorecontext.S b/arch/z80/src/z8/z8_restorecontext.S new file mode 100644 index 0000000000000000000000000000000000000000..419961ffe623af5c311b36492b4b537a37d8c61b --- /dev/null +++ b/arch/z80/src/z8/z8_restorecontext.S @@ -0,0 +1,164 @@ +/************************************************************************** + * arch/z80/src/z8/z8_saveusercontext.S + * Save the state of the current user thread + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER or CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, or CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS or SERVICES; LOSS + * OF USE, DATA, or PROFITS; or BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, or TORT (INCLUDING NEGLIGENCE or OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + + xdef _z8_restorecontext + +/************************************************************************** + * Code + **************************************************************************/ + + segment CODE + +/**************************************************************************** + * Name: _z8_restorecontext + * + * Description: + * Restore the task context that was previously saved via + * _z8_saveusercontext() or by interrupt handling. Unlike the + * _z8_saveusercontext() counterpart, we do not know the context of the + * restored task and, hence, we must handle the worst case -- restore + * everythihng. + * + * Parameters: + * On entry, the following stack organization is assumed: + * + * Pointer to the context save structure + * TOS -> Return address (2) + * + * Assumptions: + * Large model, dynamic frames + * + **************************************************************************/ + +_z8_restorecontext: + /* Disable all interrupts because we are going to be using + * the IRQ register set. + */ + + di + + /* Switch to IRQ register set */ + + srp #%f0 + + /* Get the rr0 = the current value of the stack pointer */ + + ldx r0, sph /* rr0 = stack pointer */ + ldx r1, spl + + /* Get rr6 = the pointer to the context save structure */ + + ldx r6, 2(rr0) /* rr6 = pointer to context structure */ + ldx r7, 3(rr0) + + /* Copy all registers into the user register area. NOTE: we + * use the saved RP value to determine the destination adress. + */ + + clr r0 /* rr0 = destination address */ + ldx r1, XCPT_RP_OFFS(rr6) + ld r2, r6 /* rr2 = source address */ + ld r3, r7 + ld r4, #16 /* r4 = number of bytes to copy */ + +_z8_restore: + ldx r5, @rr2 + ldx @rr0, r5 + incw rr0 + incw rr2 + djnz r4, _z8_restore + + /* Set the new stack pointer */ + + ldx r0, XCPT_SPH_OFFS(rr6) + ldx r1, XCPT_SPL_OFFS(rr6) + ldx sph, r0 + ldx spl, r1 + + /* Push the return address onto the stack */ + + ldx r0, XCPT_PCH_OFFS(rr6) + ldx r1, XCPT_PCL_OFFS(rr6) + push r1 + push r0 + + /* Recover the flags and RP settings.. but don't restore them yet */ + + ldx r1, XCPT_FLAGS_OFFS(rr6) + ldx r2, XCPT_RP_OFFS(rr6) + + /* Determine whether interrupts must be enabled on return. This + * would be nicer to do below, but later we will need to preserve + * the condition codes in the flags. + */ + + ldx r0, XCPT_IRQCTL_OFFS(rr6) + tm r0, #%80 + jr nz, _z8_returnenabled + + /* Restore the flag settings */ + + ldx flags, r1 + + /* Restore the user register page and return with interrupts disabled */ + + ldx rp, r2 /* Does not effect flags */ + ret /* Does not effect flags */ + +_z8_returnenabled: + /* Restore the flag settings */ + + ldx flags, r1 + + /* Restore the user register page, re-enable interrupts and return */ + + ldx rp, r2 /* Does not effect flags */ + ei /* Does not effect flags */ + ret /* Does not effect flags */ + + end diff --git a/arch/z80/src/z8/z8_saveirqcontext.c b/arch/z80/src/z8/z8_saveirqcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..4c0ea8f4d54cd1203b05b685c5d4ea2fc4aedee1 --- /dev/null +++ b/arch/z80/src/z8/z8_saveirqcontext.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_saveirqcontext.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_saveirqcontext + * + * Description: + * In order to provide faster interrupt handling, the interrupt logic does + * "lazy" context saving as described below: + * + * (1) At the time of the interrupt, minimum information is saved and the + * register pointer is changed so that the interrupt logic does not + * alter the state of the interrupted task's registers. + * (2) If no context switch occurs during the interrupt processing, then + * the return from interrupt is also simple. + * (3) If a context switch occurs during interrupt processing, then + * (a) The full context of the interrupt task is saved, and + * (b) A full context switch is performed when the interrupt exits + * (see z8_vector.S). + * + * This function implements the full-context switch of bullet 3a. + * + ****************************************************************************/ + +void z8_saveirqcontext(FAR chipreg_t *regs) +{ + /* If we have already saved the interrupted task's registers in the TCB, + * then we do not need to do anything. + */ + + if (g_z8irqstate.state == Z8_IRQSTATE_ENTRY) + { + /* Calculate the source address based on the saved RP value */ + + uint16_t rp = g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS] >> 8; + FAR chipreg_t *src = (FAR uint16_t*)(rp & 0xf0); + FAR chipreg_t *dest = ®s[XCPT_RR0]; + + /* Copy the interrupted tasks register into the TCB register save area. */ + + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + + /* Since the task was interrupted, we know that interrupts were enabled */ + + regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */ + + /* The g_z8irqstate.regs pointer is the value of the stack pointer at + * the time that up_doirq() was called. Therefore, we can calculate + * the correct value for the stack pointer on return from interrupt: + */ + + regs[XCPT_SP] = ((chipreg_t)g_z8irqstate.regs) + Z8_IRQSAVE_SIZE; + + /* Copy the PC, RP, and FLAGS information from the lazy save to the TCB + * register save area. + */ + + regs[XCPT_RPFLAGS] = g_z8irqstate.regs[Z8_IRQSAVE_RPFLAGS]; + regs[XCPT_PC] = g_z8irqstate.regs[Z8_IRQSAVE_PC]; + + /* Now update the IRQ save area so that we will know that we have already + * done this. + */ + + g_z8irqstate.state = Z8_IRQSTATE_SAVED; + g_z8irqstate.regs = regs; + } +} + diff --git a/arch/z80/src/z8/z8_saveusercontext.S b/arch/z80/src/z8/z8_saveusercontext.S new file mode 100644 index 0000000000000000000000000000000000000000..a0b2b1f830b009112aeab422e5983f98c2305d58 --- /dev/null +++ b/arch/z80/src/z8/z8_saveusercontext.S @@ -0,0 +1,165 @@ +/************************************************************************** + * arch/z80/src/z8/z8_saveusercontext.S + * Save the state of the current user thread + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER or CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, or CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS or SERVICES; LOSS + * OF USE, DATA, or PROFITS; or BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, or TORT (INCLUDING NEGLIGENCE or OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include +#include + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + + xdef _z8_saveusercontext + +/************************************************************************** + * Code + **************************************************************************/ + + segment CODE + +/**************************************************************************** + * Name: _z8_saveusercontext + * + * Description: + * Save the current state of the user thread. Since this function is + * called from user code, it is only necessary to save the parts of the + * context that must be preserved between function calls. This includes + * + * - Frame pointer (r14, r15) + * - Register pointer (RP) + * - Interrupt state (flags) + * - Stack pointer (sph, spl) + * - Return address + * + * Parameters: + * On entry, the following stack organization is assumed: + * + * Pointer to the context save structure + * TOS -> Return address (2) + * + * Assumptions: + * Large model, dynamic frames + * + **************************************************************************/ + +_z8_saveusercontext: + /* Get the rr6 = the current value of the stack pointer */ + + ldx r6, sph /* rr6 = stack pointer */ + ldx r7, spl + + /* Get rr2 = the pointer to the context save structure */ + + ldx r2, 2(rr6) /* rr2 = pointer to context structure */ + ldx r3, 3(rr6) + + /* Get the value currently in the interrupt control register. + * Bit 7 (IRQE) determines whether or not interrupts are + * currently enabled (0:disabled, 1:enabled) + */ + + ldx r4, IRQCTL /* r4 = IRQCTL value */ + + /* Disable all interrupts so that there can be no concurrent + * modification of the TCB state save area. + */ + + di + + /* Fetch and save the return address from the stack */ + + ldx r0, @rr6 /* rr0 = return address */ + ldx r1, 1(rr6) + ldx XCPT_PCH_OFFS(rr2), r0 + ldx XCPT_PCL_OFFS(rr2), r1 + + /* Fetch and save the register pointer */ + + ldx r0, rp /* r0 = register pointer */ + ldx XCPT_RP_OFFS(rr2), r0 + + /* Calculate the value of the stack pointer on return + * from this function + */ + + ld r1, #3 /* rr0 = 3 */ + clr r0 + add r1, r7 /* rr0 = SP + 3 */ + adc r0, r6 + ldx XCPT_SPH_OFFS(rr2), r0 + ldx XCPT_SPL_OFFS(rr2), r1 + + /* Save the IRQCTL register value */ + + clr r0 + ldx XCPT_UNUSED_OFFS(rr2), r0 + ldx XCPT_IRQCTL_OFFS(rr2), r4 + + /* Save the frame pointer (rr14) in the context structure */ + + ldx XCPT_R14_OFFS(rr2), r14 + ldx XCPT_R15_OFFS(rr2), r15 + + /* Set the return value of 1 in the context structure. When the + * state is restored (via z8_restorecontext() or an interrupt + * return), the return value of 1 distinguishes the no-context- + * switch case. + */ + + /* clr r0 */ + ld r1, #1 + ldx XCPT_R0_OFFS(rr2), r0 + ldx XCPT_R1_OFFS(rr2), r1 + + /* Setup to return zero for the no-context-switch case */ + + /* clr r0 */ + clr r1 + + /* Now decide if we need to re-enable interrupts or not */ + + tm r4, #%80 + jr z, _z8_noenable + ei +_z8_noenable: + ret + + end + diff --git a/arch/z80/src/z8/z8_schedulesigaction.c b/arch/z80/src/z8/z8_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..2e6de089ec572a16d1af398a9185a737d57493db --- /dev/null +++ b/arch/z80/src/z8/z8_schedulesigaction.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_schedulesigaction.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_sigsetup + ****************************************************************************/ + +static void z8_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs) +{ + /* Save the return address and interrupt state. These will be restored by + * the signal trampoline after the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = regs[XCPT_PC]; + tcb->xcp.saved_irqctl = regs[XCPT_IRQCTL]; + + /* Then set up to vector to the trampoline with interrupts disabled */ + + regs[XCPT_PC] = (chipreg_t)up_sigdeliver; + regs[XCPT_IRQCTL] = 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!IN_INTERRUPT()) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we + * will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z8_sigsetup(tcb, sigdeliver, IRQ_STATE()); + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + SAVE_IRQCONTEXT(tcb); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an interrupt + * handler or (2) we are not in an interrupt handler and the running task + * is signalling some non-running task. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z8_sigsetup(tcb, sigdeliver, tcb->xcp.regs); + } + } + + leave_critical_section(flags); +} + +#endif /* CONFIG_DISABLE_SIGNALS */ + diff --git a/arch/z80/src/z8/z8_serial.c b/arch/z80/src/z8/z8_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..f7fe721ac033a8a6bc0b06e21fb826b7b0214783 --- /dev/null +++ b/arch/z80/src/z8/z8_serial.c @@ -0,0 +1,857 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_serial.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" + +#ifdef USE_SERIALDRIVER + +extern uint32_t get_freq(void); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* System clock frequency value from ZDS target settings */ + +#define STATE_DISABLED 0 +#define STATE_RXENABLED 1 +#define STATE_TXENABLED 2 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct z8_uart_s +{ + uint8_t volatile far* uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + bool rxenabled; /* RX interrupt enabled */ + bool txenabled; /* TX interrupt enabled */ + uint8_t rxirq; /* RX IRQ associated with this UART */ + uint8_t txirq; /* RX IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + bool stopbits2; /* true: Configure with 2 stop bits + * (instead of 1) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int z8_setup(FAR struct uart_dev_s *dev); +static void z8_shutdown(FAR struct uart_dev_s *dev); +static int z8_attach(FAR struct uart_dev_s *dev); +static void z8_detach(FAR struct uart_dev_s *dev); +static int z8_rxinterrupt(int irq, FAR void *context); +static int z8_txinterrupt(int irq, FAR void *context); +static int z8_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int z8_receive(FAR struct uart_dev_s *dev, FAR uint32_t *status); +static void z8_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool z8_rxavailable(FAR struct uart_dev_s *dev); +static void z8_send(FAR struct uart_dev_s *dev, int ch); +static void z8_txint(FAR struct uart_dev_s *dev, bool enable); +static bool z8_txready(FAR struct uart_dev_s *dev); +static bool z8_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + z8_setup, /* setup */ + z8_shutdown, /* shutdown */ + z8_attach, /* attach */ + z8_detach, /* detach */ + z8_ioctl, /* ioctl */ + z8_receive, /* receive */ + z8_rxint, /* rxint */ + z8_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif + z8_send, /* send */ + z8_txint, /* txint */ + z8_txready, /* txready */ + z8_txempty /* txempty */ +}; + +/* I/O buffers */ + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; + +/* This describes the state of the DM320 uart0 port. */ + +static struct z8_uart_s g_uart0priv = +{ + Z8_UART0_BASE, /* uartbase */ + CONFIG_UART0_BAUD, /* baud */ + false, /* rxenabled */ + false, /* txenabled */ + Z8_UART0_RX_IRQ, /* rxirq */ + Z8_UART0_TX_IRQ, /* txirq */ + CONFIG_UART0_PARITY, /* parity */ + CONFIG_UART0_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart0port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART0_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART0_TXBUFSIZE, /* xmit.size */ + g_uart0txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART0_RXBUFSIZE, /* recv.size */ + g_uart0rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart0priv, /* priv */ +}; + +/* This describes the state of the DM320 uart1 port. */ + +static struct z8_uart_s g_uart1priv = +{ + Z8_UART1_BASE, /* uartbase */ + CONFIG_UART1_BAUD, /* baud */ + false, /* rxenabled */ + false, /* txenabled */ + Z8_UART1_RX_IRQ, /* rxirq */ + Z8_UART1_TX_IRQ, /* txirq */ + CONFIG_UART1_PARITY, /* parity */ + CONFIG_UART1_2STOP /* stopbits2 */ +}; + +static uart_dev_t g_uart1port = +{ + 0, /* open_count */ + false, /* xmitwaiting */ + false, /* recvwaiting */ +#ifdef CONFIG_UART1_SERIAL_CONSOLE + true, /* isconsole */ +#else + false, /* isconsole */ +#endif + { 0 }, /* closesem */ + { 0 }, /* xmitsem */ + { 0 }, /* recvsem */ + { + { 0 }, /* xmit.sem */ + 0, /* xmit.head */ + 0, /* xmit.tail */ + CONFIG_UART1_TXBUFSIZE, /* xmit.size */ + g_uart1txbuffer, /* xmit.buffer */ + }, + { + { 0 }, /* recv.sem */ + 0, /* recv.head */ + 0, /* recv.tail */ + CONFIG_UART1_RXBUFSIZE, /* recv.size */ + g_uart0rxbuffer, /* recv.buffer */ + }, + &g_uart_ops, /* ops */ + &g_uart1priv, /* priv */ +}; + +/* Now, which one with be tty0/console and which tty1? */ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE +# define CONSOLE_DEV g_uart1port +# define TTYS0_DEV g_uart1port +# define TTYS1_DEV g_uart0port +#else +# define CONSOLE_DEV g_uart0port +# define TTYS0_DEV g_uart0port +# define TTYS1_DEV g_uart1port +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_putuart + ****************************************************************************/ + +static inline void z8_putuart(FAR struct z8_uart_s *priv, uint8_t value, + uint8_t offset) +{ + putreg8(value, *(priv->uartbase + offset)); +} + +/**************************************************************************** + * Name: z8_getuart + ****************************************************************************/ + +static inline uint8_t z8_getuart(FAR struct z8_uart_s *priv, uint8_t offset) +{ + return getreg8(*(priv->uartbase + offset)); +} + +/**************************************************************************** + * Name: z8_disableuartirq + ****************************************************************************/ + +static uint8_t z8_disableuartirq(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + uint8_t state = priv->rxenabled ? STATE_RXENABLED : STATE_DISABLED | \ + priv->txenabled ? STATE_TXENABLED : STATE_DISABLED; + + z8_txint(dev, false); + z8_rxint(dev, false); + + leave_critical_section(flags); + return state; +} + +/**************************************************************************** + * Name: z8_restoreuartirq + ****************************************************************************/ + +static void z8_restoreuartirq(FAR struct uart_dev_s *dev, uint8_t state) +{ + irqstate_t flags = enter_critical_section(); + + z8_txint(dev, (state & STATE_TXENABLED) ? true : false); + z8_rxint(dev, (state & STATE_RXENABLED) ? true : false); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z8_consoleput + ****************************************************************************/ + +static void z8_consoleput(uint8_t ch) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)CONSOLE_DEV.priv; + int tmp; + + for (tmp = 1000 ; tmp > 0 ; tmp--) + { + if (z8_txready(&CONSOLE_DEV)) + { + break; + } + } + z8_putuart(priv, ch, Z8_UART_TXD); +} + +/**************************************************************************** + * Name: z8_uartconfigure + * + * Description: + * Configure hardware for UART functionality + * + ****************************************************************************/ + +void z8_uartconfigure(void) +{ + uint8_t val; + + /* Configure GPIO Port A pins 4 & 5 for alternate function */ + + putreg8(0x02, PAADDR); + val = getreg8(PACTL) | 0x30; /* Set bits in alternate function register */ + putreg8(val, PACTL); + putreg8(0x07, PAADDR); + val = getreg8(PACTL) & 0xcf; /* Reset bits in alternate function set-1 register */ + putreg8(val, PACTL); + putreg8(0x08, PAADDR); + val = getreg8(PACTL) & 0xcf; /* Reset bits in alternate function set-2 register */ + putreg8(val, PACTL); + putreg8(0x00, PAADDR); + +#ifdef EZ8_UART1 + /* Configure GPIO Port D pins 4 & 5 for alternate function */ + + putreg8(0x02, PAADDR); + val = getreg8(PDCTL) | 0x30; /* Set bits in alternate function register */ + putreg8(val, PDCTL); + putreg8(0x07, PDADDR); + val = getreg8(PDCTL) & 0xcf; /* Reset bits in alternate function set-1 register */ + putreg8(val, PDCTL); + putreg8(0x08, PDADDR); + val = getreg8(PDCTL) & 0xcf; /* Reset bits in alternate function set-2 register */ + putreg8(val, PDCTL); + putreg8(0x00, PDADDR); +#endif +} + +/**************************************************************************** + * Name: z8_setup + * + * Description: + * Configure the UART baud, parity, etc. This method is called the first + * time that the serial port is opened. + * + ****************************************************************************/ + +static int z8_setup(FAR struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + uint32_t freq = get_freq(); + uint16_t brg; + uint8_t ctl0; + uint8_t ctl1; + + /* Calculate and set the baud rate generation register. + * BRG = (freq + baud * 8)/(baud * 16) + */ + + brg = (freq + (priv->baud << 3))/(priv->baud << 4); + z8_putuart(priv, brg >> 8, Z8_UART_BRH); + z8_putuart(priv, brg & 0xff, Z8_UART_BRL); + + /* Configure STOP bits */ + + ctl0 = ctl1 = 0; + if (priv->stopbits2) + { + ctl0 |= Z8_UARTCTL0_STOP; + } + + /* Configure parity */ + + if (priv->parity == 1) + { + ctl0 |= (Z8_UARTCTL0_PEN|Z8_UARTCTL0_PSEL); + } + else if (priv->parity == 2) + { + ctl0 |= Z8_UARTCTL0_PEN; + } + + z8_putuart(priv, ctl0, Z8_UART_CTL0); + z8_putuart(priv, ctl1, Z8_UART_CTL1); + + /* Enable UART receive (REN) and transmit (TEN) */ + + ctl0 |= (Z8_UARTCTL0_TEN|Z8_UARTCTL0_REN); + z8_putuart(priv, ctl0, Z8_UART_CTL0); +#endif + return OK; +} + +/**************************************************************************** + * Name: z8_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void z8_shutdown(FAR struct uart_dev_s *dev) +{ + (void)z8_disableuartirq(dev); +} + +/**************************************************************************** + * Name: z8_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int z8_attach(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + int ret; + + /* Attach the RX IRQ */ + + ret = irq_attach(priv->rxirq, z8_rxinterrupt); + if (ret == OK) + { + /* Attach the TX IRQ */ + + ret = irq_attach(priv->txirq, z8_txinterrupt); + if (ret != OK) + { + irq_detach(priv->rxirq); + } + } + return ret; +} + +/**************************************************************************** + * Name: z8_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception is + * the serial console which is never shutdown. + * + ****************************************************************************/ + +static void z8_detach(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + up_disable_irq(priv->rxirq); + up_disable_irq(priv->txirq); + irq_detach(priv->rxirq); + irq_detach(priv->txirq); +} + +/**************************************************************************** + * Name: z8_rxinterrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an RX + * event occurs at the z8's LIN-UART. + * + ****************************************************************************/ + +static int z8_rxinterrupt(int irq, FAR void *context) +{ + struct uart_dev_s *dev = NULL; + struct z8_uart_s *priv; + uint8_t status; + + if (g_uart1priv.rxirq == irq) + { + dev = &g_uart1port; + } + else if (g_uart0priv.rxirq == irq) + { + dev = &g_uart0port; + } + else + { + PANIC(); + } + + priv = (struct z8_uart_s*)dev->priv; + + /* Check the LIN-UART status 0 register to determine whether the source of + * the interrupt is error, break, or received data + */ + + status = z8_getuart(priv, Z8_UART_STAT0); + + /* REVISIT error and break handling */ + + /* Check if received data is available */ + + if (status & Z8_UARTSTAT0_RDA) + { + /* Handline an incoming, receive byte */ + + uart_recvchars(dev); + } + return OK; +} + +/**************************************************************************** + * Name: z8_txinterrupt + * + * Description: + * This is the UART TX interrupt handler. This interrupt handler will + * be invoked when the X16F LIN UART transmit data register is empty. + * + ****************************************************************************/ + +static int z8_txinterrupt(int irq, FAR void *context) +{ + struct uart_dev_s *dev = NULL; + struct z8_uart_s *priv; + uint8_t status; + + if (g_uart1priv.txirq == irq) + { + dev = &g_uart1port; + } + else if (g_uart0priv.txirq == irq) + { + dev = &g_uart0port; + } + else + { + PANIC(); + } + + priv = (struct z8_uart_s*)dev->priv; + + /* Verify that the transmit data register is empty */ + + status = z8_getuart(priv, Z8_UART_STAT0); + if (status & Z8_UARTSTAT0_TDRE) + { + /* Handle outgoing, transmit bytes */ + + uart_xmitchars(dev); + } + return OK; +} + +/**************************************************************************** + * Name: z8_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int z8_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: z8_receive + * + * Description: + * Called (usually) from the interrupt level to receive one character from + * the UART. Error bits associated with the receipt are provided in the + * return 'status'. + * + ****************************************************************************/ + +static int z8_receive(FAR struct uart_dev_s *dev, FAR uint32_t *status) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + uint8_t rxd; + uint8_t stat0; + + rxd = z8_getuart(priv, Z8_UART_RXD); + stat0 = z8_getuart(priv, Z8_UART_STAT0); + *status = (uint32_t)rxd | (((uint32_t)stat0) << 8); + return rxd; +} + +/**************************************************************************** + * Name: z8_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void z8_rxint(FAR struct uart_dev_s *dev, bool enable) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->rxirq); +#endif + } + else + { + up_disable_irq(priv->rxirq); + } + + priv->rxenabled = enable; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z8_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool z8_rxavailable(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_RDA) != 0); +} + +/**************************************************************************** + * Name: z8_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void z8_send(FAR struct uart_dev_s *dev, int ch) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + z8_putuart(priv, ch, Z8_UART_TXD); +} + +/**************************************************************************** + * Name: z8_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void z8_txint(FAR struct uart_dev_s *dev, bool enable) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + up_enable_irq(priv->txirq); +#endif + } + else + { + up_disable_irq(priv->txirq); + } + + priv->txenabled = enable; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: z8_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool z8_txready(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_TDRE) != 0); +} + +/**************************************************************************** + * Name: z8_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool z8_txempty(FAR struct uart_dev_s *dev) +{ + struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; + return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_TXE) != 0); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. + * + ****************************************************************************/ + +void up_serialinit(void) +{ + /* Disable all UART interrupts */ + + (void)z8_disableuartirq(&TTYS0_DEV); + (void)z8_disableuartirq(&TTYS1_DEV); + + /* Initialize the console for early use */ + CONSOLE_DEV.isconsole = true; + z8_setup(&CONSOLE_DEV); + + /* Reigster console and tty devices */ + + (void)uart_register("/dev/console", &CONSOLE_DEV); + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug + * writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + uint8_t state; + + /* Keep interrupts disabled so that we do not interfere with normal + * driver operation + */ + + state = z8_disableuartirq(&CONSOLE_DEV); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR before LF */ + + z8_consoleput('\r'); + } + + /* Output the character */ + + z8_consoleput((uint8_t)ch); + + /* It is important to restore the TX interrupt while the send is pending. + * otherwise, TRDE interrupts can be lost since they do not pend after the + * TRDE false->true transition. + */ + + z8_restoreuartirq(&CONSOLE_DEV, state); + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_UART1_SERIAL_CONSOLE +# define z8_contrde() \ + ((getreg8(*(Z8_UART1_BASE+Z8_UART_STAT0)) & Z8_UARTSTAT0_TDRE) != 0) +# define z8_contxd(ch) \ + putreg8((uint8_t)(ch), *(Z8_UART1_BASE+Z8_UART_TXD)) +#else +# define z8_contrde() \ + ((getreg8(*(Z8_UART0_BASE+Z8_UART_STAT0)) & Z8_UARTSTAT0_TDRE) != 0) +# define z8_contxd(ch) \ + putreg8((uint8_t)(ch), *(Z8_UART0_BASE+Z8_UART_TXD)) +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_putc + ****************************************************************************/ + +static void z8_putc(int ch) +{ + int tmp; + for (tmp = 1000 ; tmp > 0 && !z8_contrde(); tmp--); + z8_contxd(ch); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + +int up_putc(int ch) +{ + /* Check for LF */ + + if (ch == '\n') + { + /* Output CR before LF */ + + z8_putc('\r'); + } + + /* Output character */ + + z8_putc(ch); + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/z80/src/z8/z8_sigdeliver.c b/arch/z80/src/z8/z8_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..1cbb7e21590a4897113af077dafd6010bd92cee3 --- /dev/null +++ b/arch/z80/src/z8/z8_sigdeliver.c @@ -0,0 +1,155 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_sigdeliver.c + * + * Copyright (C) 2008-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z8_copystate + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +static void z8_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + FAR struct tcb_s *rtcb = this_task(); + chipreg_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + z8_copystate(regs, rtcb->xcp.regs); + regs[XCPT_PC] = rtcb->xcp.saved_pc; + regs[XCPT_IRQCTL] = rtcb->xcp.saved_irqctl; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(regs[XCPT_IRQCTL]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + z8_restorecontext(regs); +#endif +} + +#endif /* CONFIG_DISABLE_SIGNALS */ diff --git a/arch/z80/src/z8/z8_timerisr.c b/arch/z80/src/z8/z8_timerisr.c new file mode 100644 index 0000000000000000000000000000000000000000..d387c770c6e620db973c5e0cf09a1157dbb27f9a --- /dev/null +++ b/arch/z80/src/z8/z8_timerisr.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_timerisr.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip/chip.h" +#include "clock/clock.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* This function is normally prototyped int the ZiLOG header file sio.h */ + +extern uint32_t get_freq(void); + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the system. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t reload; + + up_disable_irq(Z8_IRQ_SYSTIMER); + + /* Write to the timer control register to disable the timer, configure + * the timer for continuous mode, and set up the pre-scale value for + * divide by 4. + */ + + putreg8((Z8_TIMERCTL_DIV4|Z8_TIMERCTL_CONT), T0CTL); + + /* Write to the timer high and low byte registers to set a starting + * count value (this effects only the first pass in continuous mode) + */ + + putreg16(0x0001, T0); + + /* Write to the timer reload register to set the reload value. + * + * In continuous mode: + * + * timer_period = reload_value x prescale / system_clock_frequency + * or + * reload_value = (timer_period * system_clock_frequency) / prescale + * + * For system_clock_frequency=18.432MHz, timer_period=10mS, and prescale=4, + * then reload_value=46,080 - OR: + * + * reload_value = system_clock_frequency / 400 + */ + + reload = get_freq() / 400; + putreg16((uint16_t)reload, T0R); + + /* Write to the timer control register to enable the timer and to + * initiate counting + */ + + putreg8((getreg8(T0CTL)|Z8_TIMERCTL_TEN), T0CTL); + + /* Set the timer priority */ + + /* Attach and enable the timer interrupt (leaving at priority 0 */ + + irq_attach(Z8_IRQ_SYSTIMER, (xcpt_t)up_timerisr); + up_enable_irq(Z8_IRQ_SYSTIMER); +} + diff --git a/arch/z80/src/z8/z8_vector.S b/arch/z80/src/z8/z8_vector.S new file mode 100644 index 0000000000000000000000000000000000000000..bb219d78c4dc770a5b67e748aecf9e67755ca38b --- /dev/null +++ b/arch/z80/src/z8/z8_vector.S @@ -0,0 +1,873 @@ +/************************************************************************** + * arch/z80/src/z8/z8_xdef.S + * Interrupt Handling + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER or CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, or CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS or SERVICES; LOSS + * OF USE, DATA, or PROFITS; or BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, or TORT (INCLUDING NEGLIGENCE or OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include +#include + +#include +#include + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +/************************************************************************** + * External References / External Definitions + **************************************************************************/ + + xref _up_doirq:ROM + +#if defined(ENCORE_VECTORS) + xdef _z8_wdt_handler + xdef _z8_trap_handler +if EZ8_TIMER3=1 + xdef _z8_timer2_handler +endif + xdef _z8_timer1_handler + xdef _z8_timer0_handler +if EZ8_UART0=1 + xdef _z8_uart0rx_handler + xdef _z8_uart0tx_handler +endif +if EZ8_I2C=1 + xdef _z8_i2c_handler +endif +if EZ8_SPI=1 + xdef _z8_spi_handler +endif +if EZ8_ADC=1 + xdef _z8_adc_handler +endif + xdef _z8_p7ad_handler + xdef _z8_p6ad_handler + xdef _z8_p5ad_handler + xdef _z8_p4ad_handler + xdef _z8_p3ad_handler + xdef _z8_p2ad_handler + xdef _z8_p1ad_handler + xdef _z8_p0ad_handler +if EZ8_TIMER4=1 + xdef _z8_timer3_handler +endif +if EZ8_UART1=1 + xdef _z8_uart1rx_handler + xdef _z8_uart1tx_handler +endif +if EZ8_DMA=1 + xdef _z8_dma_handler +endif +if EZ8_PORT1=0 + xdef _z8_c3_handler + xdef _z8_c2_handler + xdef _z8_c1_handler + xdef _z8_c0_handler +endif + +/**************************************************************************/ + +#elif defined(ENCORE_XP_VECTORS) + + xdef _z8_wdt_handler + xdef _z8_trap_handler +if EZ8_TIMER3=1 + xdef _z8_timer2_handler +endif + xdef _z8_timer1_handler + xdef _z8_timer0_handler +if EZ8_UART0=1 + xdef _z8_uart0rx_handler + xdef _z8_uart0tx_handler +endif +if EZ8_I2C=1 + xdef _z8_i2c_handler +endif +if EZ8_SPI=1 + xdef _z8_spi_handler +endif +if (EZ8_ADC=1) || (EZ8_ADC_NEW=1) + xdef _z8_adc_handler +endif + xdef _z8_p7ad_handler + xdef _z8_p6ad_handler + xdef _z8_p5ad_handler + xdef _z8_p4ad_handler + xdef _z8_p3ad_handler + xdef _z8_p2ad_handler + xdef _z8_p1ad_handler + xdef _z8_p0ad_handler +if EZ8_TIMER4=1 + xdef _z8_timer3_handler +endif +if EZ8_UART1=1 + xdef _z8_uart1rx_handler + xdef _z8_uart1tx_handler +endif +if EZ8_DMA=1 + xdef _z8_dma_handler +endif +if (EZ8_PORT1=0) + xdef _z8_c3_handler + xdef _z8_c2_handler + xdef _z8_c1_handler + xdef _z8_c0_handler +endif + xdef _z8_potrap_handler + xdef _z8_wotrap_handler + +/**************************************************************************/ + +#elif defined(ENCORE_XP16K_VECTORS) + + xdef _z8_wdt_handler + xdef _z8_trap_handler +if EZ8_TIMER3=1 + xdef _z8_timer2_handler +endif + xdef _z8_timer1_handler + xdef _z8_timer0_handler +if EZ8_UART0=1 + xdef _z8_uart0rx_handler + xdef _z8_uart0tx_handler +endif +if EZ8_I2C=1 + xdef _z8_i2c_handler +endif +if EZ8_ESPI=1 + xdef _z8_spi_handler +endif +if EZ8_ADC_NEW=1 + xdef _z8_adc_handler +endif + xdef _z8_p7ad_handler + xdef _z8_p6ad_handler + xdef _z8_p5ad_handler + xdef _z8_p4ad_handler + xdef _z8_p3ad_handler + xdef _z8_p2ad_handler + xdef _z8_p1ad_handler + xdef _z8_p0ad_handler +if EZ8_MCT=1 + xdef _z8_mct_handler +endif +if EZ8_UART1=1 + xdef _z8_uart1rx_handler + xdef _z8_uart1tx_handler +endif + xdef _z8_c3_handler + xdef _z8_c2_handler + xdef _z8_c1_handler + xdef _z8_c0_handler + xdef _z8_potrap_handler + xdef _z8_wotrap_handler + +/**************************************************************************/ + +#elif defined(ENCORE_MC_VECTORS) + + xdef _z8_wdt_handler + xdef _z8_trap_handler + xdef _z8_pwmtimer_handler + xdef _z8_pwmfault_handler +if EZ8_ADC_NEW=1 + xdef _z8_adc_handler +endif + xdef _z8_cmp_handler + xdef _z8_timer0_handler +if EZ8_UART0 + xdef _z8_uart0rx_handler + xdef _z8_uart0tx_handler +endif +if EZ8_SPI=1 + xdef _z8_spi_handler +endif +if EZ8_I2C=1 + xdef _z8_i2c_handler +endif + xdef _z8_c0_handler + xdef _z8_pb_handler + xdef _z8_p7ap3a_handler + xdef _z8_p6ap2a_handler + xdef _z8_p5ap1a_handler + xdef _z8_p4ap0a_handler + xdef _z8_potrap_handler + xdef _z8_wotrap_handler +#endif + +/************************************************************************** + * Macros + **************************************************************************/ + +ENTER : MACRO val + pushx rp /* Save the current RP value in the stack */ + srp #%f0 /* Load the interrupt register pointer */ + ld r0, #val /* Pass the new value in r0 */ + jr _z8_common_handler /* The rest of the handling is common */ + ENDMAC ENTER + +LEAVE : MACRO + popx rp /* Restore the user register pointer */ + iret /* And return from interrupt */ + ENDMAC LEAVE + +/************************************************************************** + * Code + **************************************************************************/ + + segment CODE + +/************************************************************************** + * Interrupt Vectors + **************************************************************************/ + +#if defined(ENCORE_VECTORS) + vector WDT = _z8_wdt_handler + vector TRAP = _z8_trap_handler +if EZ8_TIMER3=1 + vector TIMER2 = _z8_timer2_handler +endif + vector TIMER1 = _z8_timer1_handler + vector TIMER0 = _z8_timer0_handler +if EZ8_UART0=1 + vector UART0_RX = _z8_uart0rx_handler + vector UART0_TX = _z8_uart0tx_handler +endif +if EZ8_I2C=1 + vector I2C = _z8_i2c_handler +endif +if EZ8_SPI=1 + vector SPI = _z8_spi_handler +endif +if EZ8_ADC=1 + vector ADC = _z8_adc_handler +endif + vector P7AD = _z8_p7ad_handler + vector P6AD = _z8_p6ad_handler + vector P5AD = _z8_p5ad_handler + vector P4AD = _z8_p4ad_handler + vector P3AD = _z8_p3ad_handler + vector P2AD = _z8_p2ad_handler + vector P1AD = _z8_p1ad_handler + vector P0AD = _z8_p0ad_handler +if EZ8_TIMER4=1 + vector TIMER3 = _z8_timer3_handler +endif +if EZ8_UART1=1 + vector UART1_RX = _z8_uart1rx_handler + vector UART1_TX = _z8_uart1tx_handler +endif +if EZ8_DMA=1 + vector DMA = _z8_dma_handler +endif +if EZ8_PORT1=0 + vector C3 = _z8_c3_handler + vector C2 = _z8_c2_handler + vector C1 = _z8_c1_handler + vector C0 = _z8_c0_handler +endif + +/**************************************************************************/ + +#elif defined(ENCORE_XP_VECTORS) + + vector WDT = _z8_wdt_handler + vector TRAP = _z8_trap_handler +if EZ8_TIMER3=1 + vector TIMER2 = _z8_timer2_handler +endif + vector TIMER1 = _z8_timer1_handler + vector TIMER0 = _z8_timer0_handler +if EZ8_UART0=1 + vector UART0_RX = _z8_uart0rx_handler + vector UART0_TX = _z8_uart0tx_handler +endif +if EZ8_I2C=1 + vector I2C = _z8_i2c_handler +endif +if EZ8_SPI=1 + vector SPI = _z8_spi_handler +endif +if (EZ8_ADC=1) || (EZ8_ADC_NEW=1) + vector ADC = _z8_adc_handler +endif + vector P7AD = _z8_p7ad_handler + vector P6AD = _z8_p6ad_handler + vector P5AD = _z8_p5ad_handler + vector P4AD = _z8_p4ad_handler + vector P3AD = _z8_p3ad_handler + vector P2AD = _z8_p2ad_handler + vector P1AD = _z8_p1ad_handler + vector P0AD = _z8_p0ad_handler +if EZ8_TIMER4=1 + vector TIMER3 = _z8_timer3_handler +endif +if EZ8_UART1=1 + vector UART1_RX = _z8_uart1rx_handler + vector UART1_TX = _z8_uart1tx_handler +endif +if EZ8_DMA=1 + vector DMA = _z8_dma_handler +endif +if EZ8_PORT1=0 + vector C3 = _z8_c3_handler + vector C2 = _z8_c2_handler + vector C1 = _z8_c1_handler + vector C0 = _z8_c0_handler +endif + vector POTRAP = _z8_potrap_handler + vector WOTRAP = _z8_wotrap_handler + +/**************************************************************************/ + +#elif defined(ENCORE_XP16K_VECTORS) + + vector WDT = _z8_wdt_handler + vector TRAP = _z8_trap_handler +if EZ8_TIMER3=1 + vector TIMER2 = _z8_timer2_handler +endif + vector TIMER1 = _z8_timer1_handler + vector TIMER0 = _z8_timer0_handler +if EZ8_UART0=1 + vector UART0_RX = _z8_uart0rx_handler + vector UART0_TX = _z8_uart0tx_handler +endif +if EZ8_I2C=1 + vector I2C = _z8_i2c_handler +endif +if EZ8_ESPI=1 + vector SPI = _z8_spi_handler +endif +if EZ8_ADC_NEW=1 + vector ADC = _z8_adc_handler +endif + vector P7AD = _z8_p7ad_handler + vector P6AD = _z8_p6ad_handler + vector P5AD = _z8_p5ad_handler + vector P4AD = _z8_p4ad_handler + vector P3AD = _z8_p3ad_handler + vector P2AD = _z8_p2ad_handler + vector P1AD = _z8_p1ad_handler + vector P0AD = _z8_p0ad_handler +if EZ8_MCT=1 + vector MCT = _z8_mct_handler +endif +if EZ8_UART1=1 + vector UART1_RX = _z8_uart1rx_handler + vector UART1_TX = _z8_uart1tx_handler +endif + vector C3 = _z8_c3_handler + vector C2 = _z8_c2_handler + vector C1 = _z8_c1_handler + vector C0 = _z8_c0_handler + vector POTRAP = _z8_potrap_handler + vector WOTRAP = _z8_wotrap_handler + +/**************************************************************************/ + +#elif defined(ENCORE_MC_VECTORS) + + vector WDT = _z8_wdt_handler + vector TRAP = _z8_trap_handler + vector PWMTIMER = _z8_pwmtimer_handler + vector PWMFAULT = _z8_pwmfault_handler +if EZ8_ADC_NEW=1 + vector ADC = _z8_adc_handler +endif + vector CMP = _z8_cmp_handler + vector TIMER0 = _z8_timer0_handler +if EZ8_UART0 + vector UART0_RX = _z8_uart0rx_handler + vector UART0_TX = _z8_uart0tx_handler +endif +if EZ8_SPI=1 + vector SPI = _z8_spi_handler +endif +if EZ8_I2C=1 + vector I2C = _z8_i2c_handler +endif + vector C0 = _z8_c0_handler + vector PB = _z8_pb_handler + vector P7A = _z8_p7ap3a_handler + vector P6A = _z8_p6ap2a_handler + vector P5A = _z8_p5ap1a_handler + vector P4A = _z8_p4ap0a_handler + vector POTRAP = _z8_potrap_handler + vector WOTRAP = _z8_wotrap_handler +#endif + +/************************************************************************** + * Name: _z16f_*_handler + * + * Description: + * Map individual interrupts into interrupt number and branch to common + * interrupt handling logic. If higher interrupt handling performance + * for particular interrupts is required, then those interrupts should + * be picked off here and handled outside of the common logic. + * + * On entry to any of these handlers, the stack contains the following: + * + * TOS before interrupt + * PC[7:0] + * PC[15:8] + * SP -> Flags Register + * + **************************************************************************/ + +#if defined(ENCORE_VECTORS) +_z8_wdt_handler: + ENTER(Z8_WDT_IRQ) +_z8_trap_handler: + ENTER(Z8_TRAP_IRQ) +if EZ8_TIMER3=1 +_z8_timer2_handler: + ENTER(Z8_TIMER2_IRQ) +endif +_z8_timer1_handler: + ENTER(Z8_TIMER1_IRQ) +_z8_timer0_handler: + ENTER(Z8_TIMER0_IRQ) +if EZ8_UART0=1 +_z8_uart0rx_handler: + ENTER(Z8_UART0_RX_IRQ) +_z8_uart0tx_handler: + ENTER(Z8_UART0_TX_IRQ) +endif +if EZ8_I2C=1 +_z8_i2c_handler: + ENTER(Z8_I2C_IRQ) +endif +if EZ8_SPI=1 +_z8_spi_handler: + ENTER(Z8_SPI_IRQ) +endif +if EZ8_ADC=1 +_z8_adc_handler: + ENTER(Z8_ADC_IRQ) +endif +_z8_p7ad_handler: + ENTER(Z8_P7AD_IRQ) +_z8_p6ad_handler: + ENTER(Z8_P6AD_IRQ) +_z8_p5ad_handler: + ENTER(Z8_P5AD_IRQ) +_z8_p4ad_handler: + ENTER(Z8_P4AD_IRQ) +_z8_p3ad_handler: + ENTER(Z8_P3AD_IRQ) +_z8_p2ad_handler: + ENTER(Z8_P2AD_IRQ) +_z8_p1ad_handler: + ENTER(Z8_P1AD_IRQ) +_z8_p0ad_handler: + ENTER(Z8_P0AD_IRQ) +if EZ8_TIMER4=1 +_z8_timer3_handler: + ENTER(Z8_TIMER3_IRQ) +endif +if EZ8_UART1=1 +_z8_uart1rx_handler: + ENTER(Z8_UART1_RX_IRQ) +_z8_uart1tx_handler: + ENTER(Z8_UART1_TX_IRQ) +endif +if EZ8_DMA=1 +_z8_dma_handler: + ENTER(Z8_DMA_IRQ) +endif +if EZ8_PORT1=0 +_z8_c3_handler: + ENTER(Z8_C3_IRQ) +_z8_c2_handler: + ENTER(Z8_C2_IRQ) +_z8_c1_handler: + ENTER(Z8_C1_IRQ) +_z8_c0_handler: + ENTER(Z8_C0_IRQ) +endif + +/**************************************************************************/ + +#elif defined(ENCORE_XP_VECTORS) + +_z8_wdt_handler: + ENTER(Z8_WDT_IRQ) +_z8_trap_handler: + ENTER(Z8_TRAP_IRQ) +if EZ8_TIMER3=1 +_z8_timer2_handler: + ENTER(Z8_TIMER2_IRQ) +endif +_z8_timer1_handler: + ENTER(Z8_TIMER1_IRQ) +_z8_timer0_handler: + ENTER(Z8_TIMER0_IRQ) +if EZ8_UART0=1 +_z8_uart0rx_handler: + ENTER(Z8_UART0_RX_IRQ) +_z8_uart0tx_handler: + ENTER(Z8_UART0_TX_IRQ) +endif +if EZ8_I2C=1 +_z8_i2c_handler: + ENTER(Z8_I2C_IRQ) +endif +if EZ8_SPI=1 +_z8_spi_handler: + ENTER(Z8_SPI_IRQ) +endif +if (EZ8_ADC=1) || (EZ8_ADC_NEW=1) +_z8_adc_handler: + ENTER(Z8_ADC_IRQ) +endif +_z8_p7ad_handler: + ENTER(Z8_P7AD_IRQ) +_z8_p6ad_handler: + ENTER(Z8_P6AD_IRQ) +_z8_p5ad_handler: + ENTER(Z8_P5AD_IRQ) +_z8_p4ad_handler: + ENTER(Z8_P4AD_IRQ) +_z8_p3ad_handler: + ENTER(Z8_P3AD_IRQ) +_z8_p2ad_handler: + ENTER(Z8_P2AD_IRQ) +_z8_p1ad_handler: + ENTER(Z8_P1AD_IRQ) +_z8_p0ad_handler: + ENTER(Z8_P0AD_IRQ) +if EZ8_TIMER4=1 +_z8_timer3_handler: + ENTER(Z8_TIMER3_IRQ) +endif +if EZ8_UART1=1 +_z8_uart1rx_handler: + ENTER(Z8_UART1_RX_IRQ) +_z8_uart1tx_handler: + ENTER(Z8_UART1_TX_IRQ) +endif +if EZ8_DMA=1 +_z8_dma_handler: + ENTER(Z8_DMA_IRQ) +endif +if EZ8_PORT1=0 +_z8_c3_handler: + ENTER(Z8_C3_IRQ) +_z8_c2_handler: + ENTER(Z8_C2_IRQ) +_z8_c1_handler: + ENTER(Z8_C1_IRQ) +_z8_c0_handler: + ENTER(Z8_C0_IRQ) +endif +_z8_potrap_handler: + ENTER(Z8_POTRAP_IRQ) +_z8_wotrap_handler: + ENTER(Z8_WOTRAP_IRQ) + +/**************************************************************************/ + +#elif defined(ENCORE_XP16K_VECTORS) + +_z8_wdt_handler: + ENTER(Z8_WDT_IRQ) +_z8_trap_handler: + ENTER(Z8_TRAP_IRQ) +if EZ8_TIMER3=1 +_z8_timer2_handler: + ENTER(Z8_TIMER2_IRQ) +endif +_z8_timer1_handler: + ENTER(Z8_TIMER1_IRQ) +_z8_timer0_handler: + ENTER(Z8_TIMER0_IRQ) +if EZ8_UART0=1 +_z8_uart0rx_handler: + ENTER(Z8_UART0_RX_IRQ) +_z8_uart0tx_handler: + ENTER(Z8_UART0_TX_IRQ) +endif +if EZ8_I2C=1 +_z8_i2c_handler: + ENTER(Z8_I2C_IRQ) +endif +if EZ8_ESPI=1 +_z8_spi_handler: + ENTER(Z8_SPI_IRQ) +endif +if EZ8_ADC_NEW=1 +_z8_adc_handler: + ENTER(Z8_ADC_IRQ) +endif +_z8_p7ad_handler: + ENTER(Z8_P7AD_IRQ) +_z8_p6ad_handler: + ENTER(Z8_P6AD_IRQ) +_z8_p5ad_handler: + ENTER(Z8_P5AD_IRQ) +_z8_p4ad_handler: + ENTER(Z8_P4AD_IRQ) +_z8_p3ad_handler: + ENTER(Z8_P3AD_IRQ) +_z8_p2ad_handler: + ENTER(Z8_P2AD_IRQ) +_z8_p1ad_handler: + ENTER(Z8_P1AD_IRQ) +_z8_p0ad_handler: + ENTER(Z8_P0AD_IRQ) +if EZ8_MCT=1 +_z8_mct_handler: + ENTER(Z8_MCT_IRQ) +endif +if EZ8_UART1=1 +_z8_uart1rx_handler: + ENTER(Z8_UART1_RX_IRQ) +_z8_uart1tx_handler: + ENTER(Z8_UART1_TX_IRQ) +endif +_z8_c3_handler: + ENTER(Z8_C3_IRQ) +_z8_c2_handler: + ENTER(Z8_C2_IRQ) +_z8_c1_handler: + ENTER(Z8_C1_IRQ) +_z8_c0_handler: + ENTER(Z8_C0_IRQ) +_z8_potrap_handler: + ENTER(Z8_POTRAP_IRQ) +_z8_wotrap_handler: + ENTER(Z8_WOTRAP_IRQ) + +/**************************************************************************/ + +#elif defined(ENCORE_MC_VECTORS) + +_z8_wdt_handler: + ENTER(Z8_WDT_IRQ) +_z8_trap_handler: + ENTER(Z8_TRAP_IRQ) +_z8_pwmtimer_handler: + ENTER(Z8_PWMTIMER_IRQ) +_z8_pwmfault_handler: + ENTER(Z8_PWMFAULT_IRQ) +if EZ8_ADC_NEW=1 +_z8_adc_handler: + ENTER(Z8_ADC_IRQ) +endif +_z8_cmp_handler: + ENTER(Z8_CMP_IRQ) +_z8_timer0_handler: + ENTER(Z8_TIMER0_IRQ) +if EZ8_UART0 +_z8_uart0rx_handler: + ENTER(Z8_UART0_RX_IRQ) +_z8_uart0tx_handler: + ENTER(Z8_UART0_TX_IRQ) +endif +if EZ8_SPI=1 +_z8_spi_handler: + ENTER(Z8_SPI_IRQ) +endif +if EZ8_I2C=1 +_z8_i2c_handler: + ENTER(Z8_I2C_IRQ) +endif +_z8_c0_handler: + ENTER(Z8_C0_IRQ) +_z8_pb_handler: + ENTER(Z8_PB_IRQ) +_z8_p7ap3a_handler: + ENTER(Z8_P7A_IRQ) +_z8_p6ap2a_handler: + ENTER(Z8_P6AP2A_IRQ) +_z8_p5ap1a_handler: + ENTER(Z8_P5AP1A_IRQ) +_z8_p4ap0a_handler: + ENTER(Z8_P4AP0A_IRQ) +_z8_potrap_handler: + ENTER(Z8_POTRAP_IRQ) +_z8_wotrap_handler: + ENTER(Z8_WOTRAP_IRQ) +#endif + +/************************************************************************** + * Name: _z16f_common_handler + * + * Description: + * Common IRQ handling logic + * + * On entry, the stack contains the following: + * + * TOS before interrupt + * PC[7:0] + * PC[15:8] + * Flags Register + * SP -> RP + * + * R0 holds the IRQ number and the RP has been reset to %f0 + * + **************************************************************************/ + +_z8_common_handler: + /* Pass the address of the IRQ stack frame */ + + ldx r2, sph /* rr2 = stack pointer */ + ldx r3, spl + push r3 /* Pass as a parameter */ + push r2 + + /* Pass the IRQ number */ + + push r0 + + /* Process the interrupt */ + + call _up_doirq /* Call the IRQ handler */ + + /* Release arguments from the stack */ + + pop r4 /* Discard the IRQ argument */ + pop r2 /* Recover the stack pointer parameter */ + pop r3 + + /* If a interrupt level context switch occurred, then the + * return value will be the same as the input value + */ + + cp r0, r2 /* Same as the return value? */ + jr nz, _z8_switch + cp r1, r3 + jr z, _z8_noswitch + + /* A context switch occurs. Restore the use context. + * rr0 = pointer to context structgure. + */ + +_z8_switch: + + /* Destroy the interrupt return information on the stack */ + + pop r4 /* Destroy saved RP */ + pop r4 /* Destroy saved flags */ + pop r4 /* Destroy saved return address */ + pop r4 + + /* Copy all registers into the user register area. */ + + clr r2 /* rr2 = destination address */ + ldx r3, XCPT_RP_OFFS(rr0) + ld r4, r0 /* rr4 = source address */ + ld r5, r1 + ld r6, #16 /* r6 = number of bytes to copy */ + +_z8_restore: + ldx r7, @rr4 + ldx @rr2, r7 + incw rr2 + incw rr4 + djnz r6, _z8_restore + + /* Set the new stack pointer */ + + ldx r2, XCPT_SPH_OFFS(rr0) + ldx r3, XCPT_SPL_OFFS(rr0) + ldx sph, r2 + ldx spl, r3 + + /* Push the return address onto the stack */ + + ldx r2, XCPT_PCH_OFFS(rr0) + ldx r3, XCPT_PCL_OFFS(rr0) + push r3 + push r2 + + /* Recover the flags and RP settings.. but don't restore them yet */ + + ldx r3, XCPT_FLAGS_OFFS(rr0) + ldx r4, XCPT_RP_OFFS(rr0) + + /* Determine whether interrupts must be enabled on return. This + * would be nicer to do below, but later we will need to preserve + * the condition codes in the flags. + */ + + ldx r2, XCPT_IRQCTL_OFFS(rr0) + tm r2, #%80 + jr nz, _z8_returnenabled + + /* Restore the flag settings */ + + ldx flags, r3 + + /* Restore the user register page and return with interrupts disabled. + * Note that we cannot use the iret instruction because it unconditionally + * re-enabled interrupts + */ + + ldx rp, r4 /* Does not effect flags */ + ret /* Does not effect flags */ + +_z8_returnenabled: + /* Restore the flag settings */ + + ldx flags, r1 + + /* Restore the user register page, re-enable interrupts and return. + * Note that we cannot use the iret instruction because it unconditionally + * re-enabled interrupts + */ + + ldx rp, r4 /* Does not effect flags */ + ei /* Does not effect flags */ + ret /* Does not effect flags */ + +_z8_noswitch: + LEAVE + +/************************************************************************** + * Data + **************************************************************************/ + + /* Set aside area for interrupt registers */ + + define interruptreg, space=rdata, org=%f0 + segment interruptreg + ds %10 + + end _z8_common_handler diff --git a/arch/z80/src/z80/.gitignore b/arch/z80/src/z80/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..33ac7f84357dbaa9e5081adbcac3f47e8cc00738 --- /dev/null +++ b/arch/z80/src/z80/.gitignore @@ -0,0 +1,3 @@ +*.lst +*.sym + diff --git a/arch/z80/src/z80/Kconfig b/arch/z80/src/z80/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..7a05eb08ef75b377d3e5ab3e0467fc1aa4733b05 --- /dev/null +++ b/arch/z80/src/z80/Kconfig @@ -0,0 +1,55 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_Z80 + +choice + prompt "Toolchain Selection" + default Z80_TOOLCHAIN_SDCCW if HOST_WINDOWS + default Z80_TOOLCHAIN_SDCCL if !HOST_WINDOWS + +config Z80_TOOLCHAIN_SDCCL + bool "SDCC for Linux, MAC OSX, or Cygwin" + depends on !WINDOWS_NATIVE + +config Z80_TOOLCHAIN_SDCCW + bool "SDCC for Windows" + depends on HOST_WINDOWS + +endchoice + +config LINKER_HOME_AREA + hex "Start of _HOME area" + default 0x0000 + ---help--- + Start of the linker HOME area. Default: 0x0000 + +config LINKER_CODE_AREA + hex "Start of _CODE area" + default 0x0200 + ---help--- + Start of the linker _CODE area. Default: 0x0200 + +config LINKER_DATA_AREA + hex "Start of _DATA area" + default 0x8000 + ---help--- + Start of the linker _DATA area. Default: 0x8000 + +config LINKER_ROM_AT_0000 + bool "ROM at 0x0000" + default n + ---help--- + Some architectures may have ROM located at address zero. In this + case, a special version of the "head" file must be used. + +config ARCH_HAVEHEAD + bool "Board-specific Head File" + default n + ---help--- + Use a board-specific version of the "head" file in the + configs//src directory + +endif diff --git a/arch/z80/src/z80/Make.defs b/arch/z80/src/z80/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..485dc3bbcde668c380c3e706d8bb01e7ae8e7b84 --- /dev/null +++ b/arch/z80/src/z80/Make.defs @@ -0,0 +1,56 @@ +############################################################################ +# arch/z80/src/z80/Make.defs +# +# Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_ARCH_HAVEHEAD),) +ifeq ($(CONFIG_LINKER_ROM_AT_0000),y) +HEAD_ASRC = z80_rom.asm +else +HEAD_ASRC = z80_head.asm +endif +endif + +CMN_ASRCS = + +CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c +CMN_CSRCS += up_releasestack.c up_interruptcontext.c up_blocktask.c +CMN_CSRCS += up_unblocktask.c up_exit.c up_releasepending.c +CMN_CSRCS += up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c +CMN_CSRCS += up_mdelay.c up_stackframe.c up_udelay.c up_usestack.c + +CHIP_ASRCS = z80_saveusercontext.asm z80_restoreusercontext.asm + +CHIP_CSRCS = z80_initialstate.c z80_io.c z80_irq.c z80_copystate.c +CHIP_CSRCS += z80_schedulesigaction.c z80_sigdeliver.c +CHIP_CSRCS += z80_registerdump.c diff --git a/arch/z80/src/z80/README.txt b/arch/z80/src/z80/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..f5ad20a4c12845ec21010da66e8bd830b697e8ac --- /dev/null +++ b/arch/z80/src/z80/README.txt @@ -0,0 +1,48 @@ +arch/z80/src/z80 +^^^^^^^^^^^^^^^^ + +The arch/z80 directories contain files to support a variety of 8-bit architectures +from ZiLOG (and spin-architectures such as the Rabbit2000). The arch/z80/src/z80 +sub-directory contains logic unique to the classic Z80 chip. + +Files in this directory include: + +z80_head.asm + This is the main entry point into the Z80 program. This includes the + handler for the RESET, power-up interrupt vector and address zero and all + RST interrupts. + +z80_rom.asm + Some architectures may have ROM located at address zero. In this case, a + special version of the "head" logic must be used. This special "head" + file is probably board-specific and, hence, belongs in the board-specific + configs//src directory. This file may, however, be used as + a model for such a board-specific file. + + z80_rom.S is enabled by specifying CONFIG_LINKER_ROM_AT_0000 in the + configuration file. + + A board specific version in the configs//src directory can be + used by: + + 1. Define CONFIG_ARCH_HAVEHEAD + 2. Add the board-specific head file, say .asm, to + configs//src + 3. Add a file called Make.defs in the configs//src directory + containing the line: HEAD_ASRC = .asm + +Make.defs + This is the standard makefile fragment that must be provided in all + chip directories. This fragment identifies the chip-specific file to + be used in building libarch. + +chip.h + This is the standard header file that must be provided in all chip + directories. + +z80_initialstate.c, z80_copystate.c, z80_restoreusercontext.asm, and +z80_saveusercontext.asm, switch + These files implement the Z80 context switching logic + +z80_schedulesigaction.c and z80_sigdeliver.c + These files implement Z80 signal handling. diff --git a/arch/z80/src/z80/Toolchain.defs b/arch/z80/src/z80/Toolchain.defs new file mode 100644 index 0000000000000000000000000000000000000000..90fc9944ad287e3abe8c88670f4b675138928369 --- /dev/null +++ b/arch/z80/src/z80/Toolchain.defs @@ -0,0 +1,75 @@ +############################################################################ +# arch/z80/src/z80/Toolchain.defs +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX 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 THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Setup for the selected toolchain + +# +# SDCC is currently the only z80 toolchain supported. See +# http://sdcc.sourceforge.net/. Source and pre-built SDCC binaries can be +# downloaded from the SDCC SourceForge site: +# http://sourceforge.net/projects/sdcc/files/. Pre-built binaries are +# available for Linux, MAC OSX, and for Win32. In addition, SDCC can be +# built to run on Windows as a POSIX toolchain. The various SDCC options are +# selected in the NuttX configuration with: +# +# CONFIG_Z80_TOOLCHAIN_SDCCL=y : SDCC for Linux, MAC OSX or Cygwin +# CONFIG_Z80_TOOLCHAIN_SDCCW=y : SDCC for Win32 +# + +ifeq ($(filter y, \ + $(CONFIG_Z80_TOOLCHAIN_SDCCL) \ + ),y) + CONFIG_Z80_TOOLCHAIN ?= SDCCPOSIX +endif +ifeq ($(filter y, \ + $(CONFIG_Z80_TOOLCHAIN_SDCCW) \ + ),y) + CONFIG_Z80_TOOLCHAIN ?= SDCCWIN32 +endif + +# SDCC toolchain under Linux, MAC OSX or Cygwin + +ifeq ($(CONFIG_Z80_TOOLCHAIN),POSIX) +endif + +# SDCC toolchain under Windows/Cygwin + +ifeq ($(CONFIG_AVR_TOOLCHAIN),SDCCWIN32) + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif + + diff --git a/arch/z80/src/z80/chip.h b/arch/z80/src/z80/chip.h new file mode 100644 index 0000000000000000000000000000000000000000..a216d71ef7b3eac66b86b08c85d7168a42d6373d --- /dev/null +++ b/arch/z80/src/z80/chip.h @@ -0,0 +1,54 @@ +/************************************************************************************ + * arch/z80/src/z80/chip.h + * arch/z80/src/chip/chip.h + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z80_CHIP_H +#define __ARCH_Z80_SRC_Z80_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#endif /* __ARCH_Z80_SRC_Z80_CHIP_H */ diff --git a/arch/z80/src/z80/switch.h b/arch/z80/src/z80/switch.h new file mode 100644 index 0000000000000000000000000000000000000000..f277893a33d4f8710c63e5f698226e2d7dc154e8 --- /dev/null +++ b/arch/z80/src/z80/switch.h @@ -0,0 +1,170 @@ +/************************************************************************************ + * arch/z80/src/z80/switch.h + * arch/z80/src/chip/switch.h + * + * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __Z80_SWITCH_H +#define __Z80_SWITCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Macros for portability *********************************************************** + * + * Common logic in arch/z80/src/common is customized for the z80 context switching + * logic via the following macros. + */ + +/* Initialize the IRQ state */ + +#define INIT_IRQCONTEXT() g_current_regs = NULL + +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt + * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). + */ + +#define IN_INTERRUPT() (g_current_regs != NULL) + +/* The following macro is used when the system enters interrupt handling logic + * + * NOTE: Nested interrupts are not supported in this implementation. If you want + * to implement nested interrupts, you would have to change the way that + * g_current_regs is handled. The savestate variable would not work for + * that purpose as implemented here because only the outermost nested + * interrupt can result in a context switch (it can probably be deleted). + */ + +#define DECL_SAVESTATE() \ + FAR chipreg_t *savestate + +#define IRQ_ENTER(irq, regs) \ + do { \ + savestate = (FAR chipreg_t *)g_current_regs; \ + g_current_regs = (regs); \ + } while (0) + +/* The following macro is used when the system exits interrupt handling logic */ + +#define IRQ_LEAVE(irq) g_current_regs = savestate + +/* The following macro is used to sample the interrupt state (as a opaque handle) */ + +#define IRQ_STATE() (g_current_regs) + +/* Save the current IRQ context in the specified TCB */ + +#define SAVE_IRQCONTEXT(tcb) z80_copystate((tcb)->xcp.regs, (FAR chipreg_t*)g_current_regs) + +/* Set the current IRQ context to the state specified in the TCB */ + +#define SET_IRQCONTEXT(tcb) z80_copystate((FAR chipreg_t*)g_current_regs, (tcb)->xcp.regs) + +/* Save the user context in the specified TCB. User context saves can be simpler + * because only those registers normally saved in a C called need be stored. + */ + +#define SAVE_USERCONTEXT(tcb) z80_saveusercontext((tcb)->xcp.regs) + +/* Restore the full context -- either a simple user state save or the full, + * IRQ state save. + */ + +#define RESTORE_USERCONTEXT(tcb) z80_restoreusercontext((tcb)->xcp.regs) + +/* Dump the current machine registers */ + +#define _REGISTER_DUMP() z80_registerdump() + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* This holds a references to the current interrupt level register storage structure. + * If is non-NULL only during interrupt processing. + */ + +extern volatile chipreg_t *g_current_regs; +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Defined in z80_copystate.c */ + +void z80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); + +/* Defined in z80_saveusercontext.asm */ + +int z80_saveusercontext(FAR chipreg_t *regs); + +/* Defined in z80_restoreusercontext.asm */ + +void z80_restoreusercontext(FAR chipreg_t *regs); + +/* Defined in z80_sigsetup.c */ + +void z80_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs); + +/* Defined in z80_registerdump.c */ + +void z80_registerdump(void); + +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __Z80_SWITCH_H */ diff --git a/arch/z80/src/z80/up_mem.h b/arch/z80/src/z80/up_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..2b9c356779607b53ac673791b0b3839df0fa1187 --- /dev/null +++ b/arch/z80/src/z80/up_mem.h @@ -0,0 +1,75 @@ +/************************************************************************************ + * common/sdcc.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_Z80_SRC_COMMON_UP_MEM_H +#define __ARCH_Z80_SRC_COMMON_UP_MEM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Locate the IDLE thread stack at the end of RAM. */ + +#define CONFIG_STACK_END CONFIG_RAM_SIZE +#define CONFIG_STACK_BASE (CONFIG_STACK_END - CONFIG_IDLETHREAD_STACKSIZE) + +/* The heap then extends from the linker determined beginning of the heap (s__HEAP). + * to the bottom of the IDLE thread stack. NOTE: The symbol s__HEAP is not + * accessible from C because it does not begin with the _ character. g_heapbase + * is defined in z80_head.asm to provide that value to the C code. + */ + +#define CONFIG_HEAP1_END CONFIG_STACK_BASE +#define CONFIG_HEAP1_BASE g_heapbase + +/************************************************************************************ + * Public variables + ************************************************************************************/ + +/* This is the bottom of the heap as provided by the linker symbol s__HEAP. NOTE: + * The symbol s__HEAP is not accessible from C because it does not begin with the _ + * character. g_heapbase is defined in z80_head.asm to provide that value to the C + * code. + */ + +extern const uint16_t g_heapbase; + +#endif /* __ARCH_Z80_SRC_COMMON_UP_MEM_H */ diff --git a/arch/z80/src/z80/z80_copystate.c b/arch/z80/src/z80/z80_copystate.c new file mode 100644 index 0000000000000000000000000000000000000000..3e22146765ff624788997bf59d0c608ddb4975c3 --- /dev/null +++ b/arch/z80/src/z80/z80_copystate.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_copystate.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z80_copystate + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +void z80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/z80/src/z80/z80_head.asm b/arch/z80/src/z80/z80_head.asm new file mode 100644 index 0000000000000000000000000000000000000000..4dadc5ba40d60bec7b2b334ef7a9125c43d10c23 --- /dev/null +++ b/arch/z80/src/z80/z80_head.asm @@ -0,0 +1,304 @@ +;************************************************************************** +; arch/z80/src/z80/z80_head.asm +; +; Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z80 + .module z80_head + +;************************************************************************** +; Constants +;************************************************************************** + + ; Register save area layout + + XCPT_I == 0 ; Offset 0: Saved I w/interrupt state in carry + XCPT_BC == 2 ; Offset 1: Saved BC register + XCPT_DE == 4 ; Offset 2: Saved DE register + XCPT_IX == 6 ; Offset 3: Saved IX register + XCPT_IY == 8 ; Offset 4: Saved IY register + XCPT_SP == 10 ; Offset 5: Offset to SP at time of interrupt + XCPT_HL == 12 ; Offset 6: Saved HL register + XCPT_AF == 14 ; Offset 7: Saved AF register + XCPT_PC == 16 ; Offset 8: Offset to PC at time of interrupt + + ; Default stack base (needs to be fixed) + + .include "asm_mem.h" + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _os_start ; OS entry point + .globl _up_doirq ; Interrupt decoding logic + +;************************************************************************** +; Reset entry point +;************************************************************************** + + .area _HEADER (ABS) + .org 0x0000 + + di ; Disable interrupts + im 1 ; Set interrupt mode 1 + jr _up_reset ; And boot the system + +;************************************************************************** +; Other reset handlers +; +; Interrupt mode 1 behavior: +; +; 1. M1 cycle: 7 ticks +; Acknowledge interrupt and decrements SP +; 2. M2 cycle: 3 ticks +; Writes the MS byte of the PC onto the stack and decrements SP +; 3. M3 cycle: 3 ticks +; Writes the LS byte of the PC onto the stack and sets the PC to 0x0038. +; +;************************************************************************** + + .org 0x0008 ; RST 1 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #1 ; 1 = Z80_RST1 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0010 ; RST 2 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #2 ; 2 = Z80_RST2 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0018 ; RST 3 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #3 ; 1 = Z80_RST3 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0020 ; RST 4 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #4 ; 1 = Z80_RST4 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0028 ; RST 5 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #5 ; 1 = Z80_RST5 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0030 ; RST 6 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #6 ; 1 = Z80_RST6 + jr _up_rstcommon ; Remaining RST handling is common + + .org 0x0038 ; Int mode 1 / RST 7 + + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #7 ; 7 = Z80_RST7 + jr _up_rstcommon ; Remaining RST handling is common + +;************************************************************************** +; NMI interrupt handler +;************************************************************************** + + .org 0x0066 + retn + +;************************************************************************** +; System start logic +;************************************************************************** + +_up_reset: + ; Set up the stack pointer at the location determined the Makefile + ; and stored in asm_mem.h + + ld SP, #CONFIG_STACK_END ; Set stack pointer + + ; Performed initialization unique to the SDCC toolchain + + call gsinit ; Initialize the data section + + ; Then start NuttX + + call _os_start ; jump to the OS entry point + + ; NuttX will never return, but just in case... + +_up_halt:: + halt ; We should never get here + jp _up_halt + +;************************************************************************** +; Common Interrupt handler +;************************************************************************** + +_up_rstcommon:: + ; Create a register frame. SP points to top of frame + 4, pushes + ; decrement the stack pointer. Already have + ; + ; Offset 8: Return PC is already on the stack + ; Offset 7: AF (retaining flags) + ; + ; IRQ number is in A + + push hl ; Offset 6: HL + ld hl, #(3*2) ; HL is the value of the stack pointer before + add hl, sp ; the interrupt occurred + push hl ; Offset 5: Stack pointer + push iy ; Offset 4: IY + push ix ; Offset 3: IX + push de ; Offset 2: DE + push bc ; Offset 1: BC + + ld b, a ; Save the reset number in B + ld a, i ; Parity bit holds interrupt state + push af ; Offset 0: I with interrupt state in parity + di + + ; Call the interrupt decode logic. SP points to the beginning of the reg structure + + ld hl, #0 ; Argument #2 is the beginning of the reg structure + add hl, sp ; + push hl ; Place argument #2 at the top of stack + push bc ; Argument #1 is the Reset number + inc sp ; (make byte sized) + call _up_doirq ; Decode the IRQ + + ; On return, HL points to the beginning of the reg structure to restore + ; Note that (1) the arguments pushed on the stack are not popped, and (2) the + ; original stack pointer is lost. In the normal case (no context switch), + ; HL will contain the value of the SP before the arguments were pushed. + + ld sp, hl ; Use the new stack pointer + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in carry + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + ld hl, #-2 ; Offset of SP to account for ret addr on stack + pop de ; Offset 5: HL' = Stack pointer after return + add hl, de ; HL = Stack pointer value before return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + ld sp, hl ; Set SP = saved stack pointer value before return + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, nointenable ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes + reti +nointenable:: + ex af, af' ; Restore AF + reti + +;************************************************************************** +; Ordering of segments for the linker (SDCC only) +;************************************************************************** + + .area _HOME + .area _CODE + .area _INITIALIZER + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _INITIALIZED + .area _BSEG + .area _BSS + .area _HEAP + +;************************************************************************** +; Global data initialization logic (SDCC only) +;************************************************************************** + + .area _GSINIT +gsinit:: + ld bc, #l__INITIALIZER + ld a, b + or a, c + jr Z, gsinit_next + ld de, #s__INITIALIZED + ld hl, #s__INITIALIZER + ldir +gsinit_next: + + .area _GSFINAL + ret + +;************************************************************************** +; The start of the heap (SDCC only). Note that is actually resides in +; the _CODE area (which may be FLASH or ROM) +;************************************************************************** + + .area _CODE +_g_heapbase:: + .dw #s__HEAP + diff --git a/arch/z80/src/z80/z80_initialstate.c b/arch/z80/src/z80/z80_initialstate.c new file mode 100644 index 0000000000000000000000000000000000000000..7191f03ebeded52bfe787822fe0d145ed8043342 --- /dev/null +++ b/arch/z80/src/z80/z80_initialstate.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_initialstate.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip/chip.h" +#include "up_internal.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the initial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); +#ifndef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[XCPT_I] = Z80_PV_FLAG; /* Parity flag will enable interrupts */ +#endif + xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; +} diff --git a/arch/z80/src/z80/z80_io.c b/arch/z80/src/z80/z80_io.c new file mode 100644 index 0000000000000000000000000000000000000000..a44be35597eff9cc90965dac787facef153803d2 --- /dev/null +++ b/arch/z80/src/z80/z80_io.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_io.c + * + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +/* #include */ + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: outb + * + * Description: + * Output byte c on port p + * + ****************************************************************************/ + +void outp(char p, char c) +{ + __asm + ld c, 4(ix) ; port + ld a, 5(ix) ; value + out (c), a + __endasm; +} + + +/**************************************************************************** + * Name: inpb + * + * Description: + * Input byte from port p + * + ****************************************************************************/ + +char inp(char p) __naked +{ + __asm + ld c, 4(ix) ;port + in l, (c) + __endasm; +} diff --git a/arch/z80/src/z80/z80_irq.c b/arch/z80/src/z80/z80_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..69a6cc93801b10d06c45cf3fd584d0b5e47fd684 --- /dev/null +++ b/arch/z80/src/z80/z80_irq.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_irq.c + * + * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level register storage + * structure. If is non-NULL only during interrupt processing. + */ + +volatile chipreg_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Disable all interrupts; return previous interrupt state + * + ****************************************************************************/ + +irqstate_t up_irq_save(void) __naked +{ + __asm + ld a, i ; AF Parity bit holds interrupt state + di ; Interrupts are disabled + push af ; Return AF in HL + pop hl ; + ret ; + __endasm; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore previous interrupt state + * + ****************************************************************************/ + +void up_irq_restore(irqstate_t flags) __naked +{ + __asm + di ; Assume disabled + pop hl ; HL = return address + pop af ; AF Parity bit holds interrupt state + jp po, statedisable + ei +statedisable: + push af ; Restore stack + push hl ; + ret ; and return + __endasm; +} diff --git a/arch/z80/src/z80/z80_registerdump.c b/arch/z80/src/z80/z80_registerdump.c new file mode 100644 index 0000000000000000000000000000000000000000..dd83a1eb8c7358f1f6a2da070bd5e095667fc3d1 --- /dev/null +++ b/arch/z80/src/z80/z80_registerdump.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_registerdump.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Output debug info -- even if debug is not selected. */ + +#undef CONFIG_DEBUG +#undef CONFIG_DEBUG_VERBOSE +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_VERBOSE 1 + +#include + +#include +#include + +#include "chip/switch.h" +#include "up_internal.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z80_registerdump + ****************************************************************************/ + +static void z80_registerdump(void) +{ + if (g_current_regs) + { + lldbg("AF: %04x I: %04x\n", + g_current_regs[XCPT_AF], g_current_regs[XCPT_I]); + lldbg("BC: %04x DE: %04x HL: %04x\n", + g_current_regs[XCPT_BC], g_current_regs[XCPT_DE], g_current_regs[XCPT_HL]); + lldbg("IX: %04x IY: %04x\n", + g_current_regs[XCPT_IX], g_current_regs[XCPT_IY]); + lldbg("SP: %04x PC: %04x\n" + g_current_regs[XCPT_SP], g_current_regs[XCPT_PC]); + } +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z80/src/z80/z80_restoreusercontext.asm b/arch/z80/src/z80/z80_restoreusercontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..bab143462564b2bf46ab72422e44dc4447e3901c --- /dev/null +++ b/arch/z80/src/z80/z80_restoreusercontext.asm @@ -0,0 +1,104 @@ +;************************************************************************** +; arch/z80/src/z80/z80_restoreusercontext.asm +; +; Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + ; Register save area layout + + .globl XCPT_I ; Offset 0: Saved I w/interrupt state in carry + .globl XCPT_BC ; Offset 1: Saved BC register + .globl XCPT_DE ; Offset 2: Saved DE register + .globl XCPT_IX ; Offset 3: Saved IX register + .globl XCPT_IY ; Offset 4: Saved IY register + .globl XCPT_SP ; Offset 5: Offset to SP at time of interrupt + .globl XCPT_HL ; Offset 6: Saved HL register + .globl XCPT_AF ; Offset 7: Saved AF register + .globl XCPT_PC ; Offset 8: Offset to PC at time of interrupt + +;************************************************************************** +; z80_restoreusercontext +;************************************************************************** + + .area _CODE +_z80_restoreusercontext: + ; On entry, stack contains return address (not used), then address + ; of the register save structure + + ; Discard the return address, we won't be returning + + pop hl + + ; Get the address of the beginning of the state save area. Each + ; pop will increment to the next element of the structure + + pop hl ; BC = Address of save structure + ld sp, hl ; SP points to top of storage area + + ; Disable interrupts while we muck with the alternative registers. The + ; Correct interrupt state will be restore below + + di + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in parity + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + pop hl ; Offset 5: HL' = Stack pointer after return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + pop de ; DE' = return address + ld sp, hl ; Set SP = saved stack pointer value before return + push de ; Save return address for ret instruction + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, noinrestore ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes.. Enable interrupts + ret ; and return +noinrestore: + ex af, af' ; Restore AF + ret ; Return with interrupts disabled diff --git a/arch/z80/src/z80/z80_rom.asm b/arch/z80/src/z80/z80_rom.asm new file mode 100644 index 0000000000000000000000000000000000000000..abc450bcd87a076e3b23252f2537985bd69f10ad --- /dev/null +++ b/arch/z80/src/z80/z80_rom.asm @@ -0,0 +1,297 @@ +;************************************************************************** +; arch/z80/src/z80/z80_rom.asm +; +; Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************** + + .title NuttX for the Z80 + .module z80_head + +;************************************************************************** +; Constants +;************************************************************************** + + ; Register save area layout + + XCPT_I == 0 ; Offset 0: Saved I w/interrupt state in carry + XCPT_BC == 2 ; Offset 1: Saved BC register + XCPT_DE == 4 ; Offset 2: Saved DE register + XCPT_IX == 6 ; Offset 3: Saved IX register + XCPT_IY == 8 ; Offset 4: Saved IY register + XCPT_SP == 10 ; Offset 5: Offset to SP at time of interrupt + XCPT_HL == 12 ; Offset 6: Saved HL register + XCPT_AF == 14 ; Offset 7: Saved AF register + XCPT_PC == 16 ; Offset 8: Offset to PC at time of interrupt + + ; Default stack base (needs to be fixed) + + .include "asm_mem.h" + +;************************************************************************** +; Global symbols used +;************************************************************************** + + .globl _os_start ; OS entry point + .globl _up_doirq ; Interrupt decoding logic + +;************************************************************************** +; System start logic +;************************************************************************** + +_up_reset: + ; Set up the stack pointer at the location determined the Makefile + ; and stored in asm_mem.h + + ld SP, #CONFIG_STACK_END ; Set stack pointer + + ; Performed initialization unique to the SDCC toolchain + + call gsinit ; Initialize the data section + + ; Copy the reset vectors + + ld hl, #_up_rstvectors ; code for RAM + ld de, #0x4000 ; move it here + ld bc, #3*7 ; 7 vectors / 3 bytes each + ldir + + ; Then start NuttX + + call _os_start ; jump to the OS entry point + + ; NuttX will never return, but just in case... + +_up_halt:: + halt ; We should never get here + jp _up_halt + + ; Data to copy to address 0x4000 + +_up_rstvectors: + jp _up_rst1 ; 0x4000 : RST 1 + jp _up_rst2 ; 0x4003 : RST 2 + jp _up_rst3 ; 0x4006 : RST 3 + jp _up_rst4 ; 0x4009 : RST 4 + jp _up_rst5 ; 0x400c : RST 5 + jp _up_rst6 ; 0x400f : RST 6 + jp _up_rst7 ; 0x4012 : RST 7 + +;************************************************************************** +; Other reset handlers +; +; Interrupt mode 1 behavior: +; +; 1. M1 cycle: 7 ticks +; Acknowledge interrupt and decrements SP +; 2. M2 cycle: 3 ticks +; Writes the MS byte of the PC onto the stack and decrements SP +; 3. M3 cycle: 3 ticks +; Writes the LS byte of the PC onto the stack and sets the PC to 0x0038. +; +;************************************************************************** + +_up_rst1: ; RST 1 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #1 ; 1 = Z80_RST1 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst2: ; RST 2 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #2 ; 2 = Z80_RST2 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst3: ; RST 3 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #3 ; 1 = Z80_RST3 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst4: ; RST 4 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #4 ; 1 = Z80_RST4 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst5: ; RST 5 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #5 ; 1 = Z80_RST5 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst6: ; RST 6 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #6 ; 1 = Z80_RST6 + jr _up_rstcommon ; Remaining RST handling is common + +_up_rst7: ; RST 7 + ; Save AF on the stack, set the interrupt number and jump to the + ; common reset handling logic. + ; Offset 8: Return PC is already on the stack + push af ; Offset 7: AF (retaining flags) + ld a, #7 ; 7 = Z80_RST7 + jr _up_rstcommon ; Remaining RST handling is common + +;************************************************************************** +; Common Interrupt handler +;************************************************************************** + +_up_rstcommon: + ; Create a register frame. SP points to top of frame + 4, pushes + ; decrement the stack pointer. Already have + ; + ; Offset 8: Return PC is already on the stack + ; Offset 7: AF (retaining flags) + ; + ; IRQ number is in A + + push hl ; Offset 6: HL + ld hl, #(3*2) ; HL is the value of the stack pointer before + add hl, sp ; the interrupt occurred + push hl ; Offset 5: Stack pointer + push iy ; Offset 4: IY + push ix ; Offset 3: IX + push de ; Offset 2: DE + push bc ; Offset 1: BC + + ld b, a ; Save the reset number in B + ld a, i ; Parity bit holds interrupt state + push af ; Offset 0: I with interrupt state in parity + di + + ; Call the interrupt decode logic. SP points to the beginning of the reg structure + + ld hl, #0 ; Argument #2 is the beginning of the reg structure + add hl, sp ; + push hl ; Place argument #2 at the top of stack + push bc ; Argument #1 is the Reset number + inc sp ; (make byte sized) + call _up_doirq ; Decode the IRQ + + ; On return, HL points to the beginning of the reg structure to restore + ; Note that (1) the arguments pushed on the stack are not popped, and (2) the + ; original stack pointer is lost. In the normal case (no context switch), + ; HL will contain the value of the SP before the arguments were pushed. + + ld sp, hl ; Use the new stack pointer + + ; Restore registers. HL points to the beginning of the reg structure to restore + + ex af, af' ; Select alternate AF + pop af ; Offset 0: AF' = I with interrupt state in carry + ex af, af' ; Restore original AF + pop bc ; Offset 1: BC + pop de ; Offset 2: DE + pop ix ; Offset 3: IX + pop iy ; Offset 4: IY + exx ; Use alternate BC/DE/HL + ld hl, #-2 ; Offset of SP to account for ret addr on stack + pop de ; Offset 5: HL' = Stack pointer after return + add hl, de ; HL = Stack pointer value before return + exx ; Restore original BC/DE/HL + pop hl ; Offset 6: HL + pop af ; Offset 7: AF + + ; Restore the stack pointer + + exx ; Use alternate BC/DE/HL + ld sp, hl ; Set SP = saved stack pointer value before return + exx ; Restore original BC/DE/HL + + ; Restore interrupt state + + ex af, af' ; Recover interrupt state + jp po, nointenable ; Odd parity, IFF2=0, means disabled + ex af, af' ; Restore AF (before enabling interrupts) + ei ; yes + reti +nointenable:: + ex af, af' ; Restore AF + reti + +;************************************************************************** +; Ordering of segments for the linker (SDCC only) +;************************************************************************** + + .area _HOME + .area _CODE + .area _INITIALIZER + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _INITIALIZED + .area _BSEG + .area _BSS + .area _HEAP + +;************************************************************************** +; Global data initialization logic (SDCC only) +;************************************************************************** + + .area _GSINIT +gsinit:: + ld bc, #l__INITIALIZER + ld a, b + or a, c + jr Z, gsinit_next + ld de, #s__INITIALIZED + ld hl, #s__INITIALIZER + ldir +gsinit_next: + + .area _GSFINAL + ret + +;************************************************************************** +; The start of the heap (SDCC only). Note that is actually resides in +; the _CODE area (which may be FLASH or ROM) +;************************************************************************** + + .area _CODE +_g_heapbase:: + .dw #s__HEAP + diff --git a/arch/z80/src/z80/z80_saveusercontext.asm b/arch/z80/src/z80/z80_saveusercontext.asm new file mode 100644 index 0000000000000000000000000000000000000000..d53c3c5df2e953e459f91c0353f48fda2bb34e69 --- /dev/null +++ b/arch/z80/src/z80/z80_saveusercontext.asm @@ -0,0 +1,143 @@ +;************************************************************************* +; arch/z80/src/z80/z80_saveusercontext.asm +; +; Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. +; Author: Gregory Nutt +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in +; the documentation and/or other materials provided with the +; distribution. +; 3. Neither the name NuttX 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 THE +; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. +; +;************************************************************************* + +;************************************************************************* +; Constants +;************************************************************************* + + ; Register save area layout + + .globl XCPT_I ; Offset 0: Saved I w/interrupt state in parity + .globl XCPT_BC ; Offset 1: Saved BC register + .globl XCPT_DE ; Offset 2: Saved DE register + .globl XCPT_IX ; Offset 3: Saved IX register + .globl XCPT_IY ; Offset 4: Saved IY register + .globl XCPT_SP ; Offset 5: Offset to SP at time of interrupt + .globl XCPT_HL ; Offset 6: Saved HL register + .globl XCPT_AF ; Offset 7: Saved AF register + .globl XCPT_PC ; Offset 8: Offset to PC at time of interrupt + + ; Stack frame + + FRAME_IY == 0 ; Location of IY on the stack + FRAME_IX == 2 ; Location of IX on the stack + FRAME_RET == 4 ; Location of return address on the stack + FRAME_REGS == 6 ; Location of reg save area on stack + + SP_OFFSET == 6 + +;************************************************************************* +; Name: z80_saveusercontext +;************************************************************************* + + .area _CODE +_z80_saveusercontext: + ; Set up a stack frame + + push ix ; Save IX and IY + push iy + ld ix, #0 + add ix, sp ; IX = stack frame + + ; Fetch the address of the save area + + ld e, FRAME_REGS(ix) ; HL = save area address + ld d, FRAME_REGS+1(ix) ; + ld iy, #0 + add iy, de ; IY = save area address + + ; Then save the registers + + ; Save the current interrupt state at offset 0 + + ld a, i ; Get interrupt state + push af + pop hl + ld XCPT_I(iy), l ; Offset 0: I w/interrupt state in parity + ld XCPT_I+1(iy), h + + ; Save BC at offset 1 + + ld XCPT_BC(iy), c ; Offset 1: BC + ld XCPT_BC+1(iy), b + + ; DE is not preserved (offset 2) + + ; Save IX at offset 3 + + ld l, FRAME_IX(ix) ; HL = Saved alue of IX + ld h, FRAME_IX+1(ix) ; + ld XCPT_IX(iy), l ; Offset 3: IX + ld XCPT_IX+1(iy), h ; + + ; Save IY at offset 4 + + ld l, FRAME_IY(ix) ; HL = Saved value of IY + ld h, FRAME_IY+1(ix) ; + ld XCPT_IY(iy), l ; Offset 4: IY + ld XCPT_IY+1(iy), h + + ; Save that stack pointer as it would be upon return in offset 5 + + ld hl, #SP_OFFSET ; Value of stack pointer on return + add hl, sp + ld XCPT_SP(iy), l ; Offset 5 SP + ld XCPT_SP+1(iy), h + + ; HL is saved as the value 1 at offset 6 + + xor a ; A = 0 + ld XCPT_HL+1(iy), a ; Offset 2: HL on return (=1) + inc a ; A = 1 + ld XCPT_HL(iy), a ; + + ; AF is not preserved (offset 7) + + ; Save the return address in offset 8 + + ld l, FRAME_RET(ix) ; HL = Saved return address + ld h, FRAME_RET+1(ix) ; + ld XCPT_PC(iy), l ; Offset 8: PC + ld XCPT_PC+1(iy), h + + ; Return the value 0 + + xor a ; HL = return value of zero + ld l, a + ld h, a + + pop iy + pop ix + ret diff --git a/arch/z80/src/z80/z80_schedulesigaction.c b/arch/z80/src/z80/z80_schedulesigaction.c new file mode 100644 index 0000000000000000000000000000000000000000..eb0c9c5554d818cde70d32e4cafbf446fe1ab61f --- /dev/null +++ b/arch/z80/src/z80/z80_schedulesigaction.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_schedulesigaction.c + * + * Copyright (C) 2007-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z80_sigsetup + ****************************************************************************/ + +static void z80_sigsetup(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs) +{ + /* Save the return address and interrupt state. These will be restored by + * the signal trampoline after the signals have been delivered. + */ + + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = regs[XCPT_PC]; + tcb->xcp.saved_i = regs[XCPT_I]; + + /* Then set up to vector to the trampoline with interrupts disabled */ + + regs[XCPT_PC] = (chipreg_t)up_sigdeliver; + regs[XCPT_I] = 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_schedule_sigaction + * + * Description: + * This function is called by the OS when one or more + * signal handling actions have been queued for execution. + * The architecture specific code must configure things so + * that the 'igdeliver' callback is executed on the thread + * specified by 'tcb' as soon as possible. + * + * This function may be called from interrupt handling logic. + * + * This operation should not cause the task to be unblocked + * nor should it cause any immediate execution of sigdeliver. + * Typically, a few cases need to be considered: + * + * (1) This function may be called from an interrupt handler + * During interrupt processing, all xcptcontext structures + * should be valid for all tasks. That structure should + * be modified to invoke sigdeliver() either on return + * from (this) interrupt or on some subsequent context + * switch to the recipient task. + * (2) If not in an interrupt handler and the tcb is NOT + * the currently executing task, then again just modify + * the saved xcptcontext structure for the recipient + * task so it will invoke sigdeliver when that task is + * later resumed. + * (3) If not in an interrupt handler and the tcb IS the + * currently executing task -- just call the signal + * handler now. + * + ****************************************************************************/ + +void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) +{ + irqstate_t flags; + + dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver); + + /* Make sure that interrupts are disabled */ + + flags = enter_critical_section(); + + /* Refuse to handle nested signal actions */ + + if (tcb->xcp.sigdeliver == NULL) + { + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. + */ + + if (tcb == this_task()) + { + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. + */ + + if (!IN_INTERRUPT()) + { + /* In this case just deliver the signal now. */ + + sigdeliver(tcb); + } + + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we + * will have to modify the return state as well as the state in + * the TCB. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z80_sigsetup(tcb, sigdeliver, IRQ_STATE()); + + /* And make sure that the saved context in the TCB + * is the same as the interrupt return context. + */ + + SAVE_IRQCONTEXT(tcb); + } + } + + /* Otherwise, we are (1) signaling a task is not running from an interrupt + * handler or (2) we are not in an interrupt handler and the running task + * is signalling some non-running task. + */ + + else + { + /* Set up to vector to the trampoline with interrupts disabled. */ + + z80_sigsetup(tcb, sigdeliver, tcb->xcp.regs); + } + } + + leave_critical_section(flags); +} + +#endif /* CONFIG_DISABLE_SIGNALS */ diff --git a/arch/z80/src/z80/z80_sigdeliver.c b/arch/z80/src/z80/z80_sigdeliver.c new file mode 100644 index 0000000000000000000000000000000000000000..b56d1afd32a76fdd3e3a9a32fdeb18858c409f66 --- /dev/null +++ b/arch/z80/src/z80/z80_sigdeliver.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/z80/src/z80/z80_sigdeliver.c + * + * Copyright (C) 2007-2010, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX 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 THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip/switch.h" +#include "sched/sched.h" +#include "up_internal.h" + +#ifndef CONFIG_DISABLE_SIGNALS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sigdeliver + * + * Description: + * This is the a signal handling trampoline. When a signal action was + * posted. The task context was mucked with and forced to branch to this + * location with interrupts disabled. + * + ****************************************************************************/ + +void up_sigdeliver(void) +{ +#ifndef CONFIG_DISABLE_SIGNALS + FAR struct tcb_s *rtcb = this_task(); + chipreg_t regs[XCPTCONTEXT_REGS]; + sig_deliver_t sigdeliver; + + /* Save the errno. This must be preserved throughout the signal handling + * so that the user code final gets the correct errno value (probably + * EINTR). + */ + + int saved_errno = rtcb->pterrno; + + board_autoled_on(LED_SIGNAL); + + sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", + rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); + ASSERT(rtcb->xcp.sigdeliver != NULL); + + /* Save the real return state on the stack. */ + + z80_copystate(regs, rtcb->xcp.regs); + regs[XCPT_PC] = rtcb->xcp.saved_pc; + regs[XCPT_I] = rtcb->xcp.saved_i; + + /* Get a local copy of the sigdeliver function pointer. We do this so + * that we can nullify the sigdeliver function pointer in the TCB and + * accept more signal deliveries while processing the current pending + * signals. + */ + + sigdeliver = rtcb->xcp.sigdeliver; + rtcb->xcp.sigdeliver = NULL; + + /* Then restore the task interrupt state. */ + + up_irq_restore(regs[XCPT_I]); + + /* Deliver the signals */ + + sigdeliver(rtcb); + + /* Output any debug messages BEFORE restoring errno (because they may + * alter errno), then disable interrupts again and restore the original + * errno that is needed by the user logic (it is probably EINTR). + */ + + sdbg("Resuming\n"); + (void)up_irq_save(); + rtcb->pterrno = saved_errno; + + /* Then restore the correct state for this thread of execution. */ + + board_autoled_off(LED_SIGNAL); + z80_restoreusercontext(regs); +#endif +} + +#endif /* CONFIG_DISABLE_SIGNALS */